Version in base suite: 16.02-3 Base version: p7zip-rar_16.02-3 Target version: p7zip-rar_16.02+really25.00+ds-0+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/non-free/p/p7zip-rar/p7zip-rar_16.02-3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/non-free/p/p7zip-rar/p7zip-rar_16.02+really25.00+ds-0+deb12u1.dsc /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zip.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/setup.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/7z.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/apfs.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/arj.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/bz2.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/cab.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/cpio.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/deb.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/dmg.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/fat.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/gz.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/hfs.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/iso.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/lzh.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/lzma.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/ntfs.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/rar.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/rpm.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/split.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/squashfs.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/tar.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/vhd.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/wim.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/xar.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/xz.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/z.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/zip.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/zst.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/7z.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/setup.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/7z.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MenuLogo.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/7zipLogo.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Add.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Add2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Copy.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Copy2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Delete.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Delete2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Extract.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Extract2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Info.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Info2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Move.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Move2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Test.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Test2.bmp |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/FM.ico |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/Contents/Resources/p7zip.icns |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16.icns |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16.png |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16_ok.png |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_32.png |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/MemLat |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma86 |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma_eos |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.xz |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_bzip2.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2_bcj2.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2_crypto.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma_bcj2.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma_crypto.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_ppmd.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_ppmd_bcj2.7z |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_tar.tar |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/check/files.tar |binary /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/debian/tests/data/data.rar |binary p7zip-rar-16.02+really25.00+ds/Asm/arm/7zCrcOpt.asm | 100 p7zip-rar-16.02+really25.00+ds/Asm/arm64/7zAsm.S | 181 p7zip-rar-16.02+really25.00+ds/Asm/arm64/LzmaDecOpt.S | 1487 + p7zip-rar-16.02+really25.00+ds/Asm/x86/7zAsm.asm | 403 p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt.asm | 258 p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt_asm.asm | 171 p7zip-rar-16.02+really25.00+ds/Asm/x86/AesOpt.asm | 1006 p7zip-rar-16.02+really25.00+ds/Asm/x86/LzFindOpt.asm | 540 p7zip-rar-16.02+really25.00+ds/Asm/x86/LzmaDecOpt.asm | 1339 + p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha1Opt.asm | 263 p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha256Opt.asm | 275 p7zip-rar-16.02+really25.00+ds/Asm/x86/Sort.asm | 860 p7zip-rar-16.02+really25.00+ds/Asm/x86/XzCrc64Opt.asm | 523 p7zip-rar-16.02+really25.00+ds/C/7z.h | 204 p7zip-rar-16.02+really25.00+ds/C/7zAlloc.c | 89 p7zip-rar-16.02+really25.00+ds/C/7zAlloc.h | 19 p7zip-rar-16.02+really25.00+ds/C/7zArcIn.c | 1786 + p7zip-rar-16.02+really25.00+ds/C/7zBuf.c | 36 p7zip-rar-16.02+really25.00+ds/C/7zBuf.h | 70 p7zip-rar-16.02+really25.00+ds/C/7zBuf2.c | 103 p7zip-rar-16.02+really25.00+ds/C/7zCrc.c | 548 p7zip-rar-16.02+really25.00+ds/C/7zCrc.h | 53 p7zip-rar-16.02+really25.00+ds/C/7zCrcOpt.c | 314 p7zip-rar-16.02+really25.00+ds/C/7zDec.c | 673 p7zip-rar-16.02+really25.00+ds/C/7zFile.c | 443 p7zip-rar-16.02+really25.00+ds/C/7zFile.h | 92 p7zip-rar-16.02+really25.00+ds/C/7zStream.c | 370 p7zip-rar-16.02+really25.00+ds/C/7zTypes.h | 853 p7zip-rar-16.02+really25.00+ds/C/7zVersion.h | 49 p7zip-rar-16.02+really25.00+ds/C/7zVersion.rc | 55 p7zip-rar-16.02+really25.00+ds/C/7zWindows.h | 101 p7zip-rar-16.02+really25.00+ds/C/7zip_gcc_c.mak | 360 p7zip-rar-16.02+really25.00+ds/C/Aes.c | 726 p7zip-rar-16.02+really25.00+ds/C/Aes.h | 98 p7zip-rar-16.02+really25.00+ds/C/AesOpt.c | 1002 p7zip-rar-16.02+really25.00+ds/C/Alloc.c | 933 p7zip-rar-16.02+really25.00+ds/C/Alloc.h | 102 p7zip-rar-16.02+really25.00+ds/C/Asm_c.mak | 12 p7zip-rar-16.02+really25.00+ds/C/Bcj2.c | 546 p7zip-rar-16.02+really25.00+ds/C/Bcj2.h | 478 p7zip-rar-16.02+really25.00+ds/C/Bcj2Enc.c | 818 p7zip-rar-16.02+really25.00+ds/C/Blake2.h | 153 p7zip-rar-16.02+really25.00+ds/C/Blake2s.c | 2916 ++ p7zip-rar-16.02+really25.00+ds/C/Bra.c | 844 p7zip-rar-16.02+really25.00+ds/C/Bra.h | 169 p7zip-rar-16.02+really25.00+ds/C/Bra86.c | 269 p7zip-rar-16.02+really25.00+ds/C/BraIA64.c | 83 p7zip-rar-16.02+really25.00+ds/C/BwtSort.c | 1143 p7zip-rar-16.02+really25.00+ds/C/BwtSort.h | 53 p7zip-rar-16.02+really25.00+ds/C/Compiler.h | 278 p7zip-rar-16.02+really25.00+ds/C/CpuArch.c | 1181 p7zip-rar-16.02+really25.00+ds/C/CpuArch.h | 912 p7zip-rar-16.02+really25.00+ds/C/Delta.c | 233 p7zip-rar-16.02+really25.00+ds/C/Delta.h | 38 p7zip-rar-16.02+really25.00+ds/C/DllSecur.c | 99 p7zip-rar-16.02+really25.00+ds/C/DllSecur.h | 20 p7zip-rar-16.02+really25.00+ds/C/HuffEnc.c | 508 p7zip-rar-16.02+really25.00+ds/C/HuffEnc.h | 46 p7zip-rar-16.02+really25.00+ds/C/LzFind.c | 2790 +- p7zip-rar-16.02+really25.00+ds/C/LzFind.h | 277 p7zip-rar-16.02+really25.00+ds/C/LzFindMt.c | 2225 + p7zip-rar-16.02+really25.00+ds/C/LzFindMt.h | 215 p7zip-rar-16.02+really25.00+ds/C/LzFindOpt.c | 578 p7zip-rar-16.02+really25.00+ds/C/LzHash.h | 91 p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.c | 871 p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.h | 201 p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.c | 1095 p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.h | 81 p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.c | 1327 - p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.h | 120 p7zip-rar-16.02+really25.00+ds/C/Lzma86.h | 222 p7zip-rar-16.02+really25.00+ds/C/Lzma86Dec.c | 107 p7zip-rar-16.02+really25.00+ds/C/Lzma86Enc.c | 209 p7zip-rar-16.02+really25.00+ds/C/LzmaDec.c | 2463 +- p7zip-rar-16.02+really25.00+ds/C/LzmaDec.h | 464 p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.c | 5501 ++-- p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.h | 163 p7zip-rar-16.02+really25.00+ds/C/LzmaLib.c | 42 p7zip-rar-16.02+really25.00+ds/C/LzmaLib.h | 138 p7zip-rar-16.02+really25.00+ds/C/Md5.c | 206 p7zip-rar-16.02+really25.00+ds/C/Md5.h | 34 p7zip-rar-16.02+really25.00+ds/C/MtCoder.c | 931 p7zip-rar-16.02+really25.00+ds/C/MtCoder.h | 242 p7zip-rar-16.02+really25.00+ds/C/MtDec.c | 1124 p7zip-rar-16.02+really25.00+ds/C/MtDec.h | 202 p7zip-rar-16.02+really25.00+ds/C/Ppmd.h | 254 p7zip-rar-16.02+really25.00+ds/C/Ppmd7.c | 1841 - p7zip-rar-16.02+really25.00+ds/C/Ppmd7.h | 321 p7zip-rar-16.02+really25.00+ds/C/Ppmd7Dec.c | 501 p7zip-rar-16.02+really25.00+ds/C/Ppmd7Enc.c | 524 p7zip-rar-16.02+really25.00+ds/C/Ppmd7aDec.c | 295 p7zip-rar-16.02+really25.00+ds/C/Ppmd8.c | 2697 +- p7zip-rar-16.02+really25.00+ds/C/Ppmd8.h | 318 p7zip-rar-16.02+really25.00+ds/C/Ppmd8Dec.c | 452 p7zip-rar-16.02+really25.00+ds/C/Ppmd8Enc.c | 500 p7zip-rar-16.02+really25.00+ds/C/Precomp.h | 137 p7zip-rar-16.02+really25.00+ds/C/RotateDefs.h | 80 p7zip-rar-16.02+really25.00+ds/C/Sha1.c | 781 p7zip-rar-16.02+really25.00+ds/C/Sha1.h | 124 p7zip-rar-16.02+really25.00+ds/C/Sha1Opt.c | 424 p7zip-rar-16.02+really25.00+ds/C/Sha256.c | 740 p7zip-rar-16.02+really25.00+ds/C/Sha256.h | 112 p7zip-rar-16.02+really25.00+ds/C/Sha256Opt.c | 451 p7zip-rar-16.02+really25.00+ds/C/Sha3.c | 359 p7zip-rar-16.02+really25.00+ds/C/Sha3.h | 36 p7zip-rar-16.02+really25.00+ds/C/Sha512.c | 711 p7zip-rar-16.02+really25.00+ds/C/Sha512.h | 86 p7zip-rar-16.02+really25.00+ds/C/Sha512Opt.c | 395 p7zip-rar-16.02+really25.00+ds/C/Sort.c | 409 p7zip-rar-16.02+really25.00+ds/C/Sort.h | 33 p7zip-rar-16.02+really25.00+ds/C/SwapBytes.c | 835 p7zip-rar-16.02+really25.00+ds/C/SwapBytes.h | 17 p7zip-rar-16.02+really25.00+ds/C/Threads.c | 1394 - p7zip-rar-16.02+really25.00+ds/C/Threads.h | 383 p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsp | 249 p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/7z/7zMain.c | 889 p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.c | 4 p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile | 44 p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile.gcc | 32 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.c | 1699 + p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsp | 248 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.manifest | 18 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.c | 4 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/makefile | 47 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.h | 9 p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.rc | 48 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.c | 1234 + p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsp | 132 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.manifest | 18 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.c | 4 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/makefile | 18 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.h | 9 p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.rc | 48 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.c | 313 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsp | 192 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile | 30 p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile.gcc | 21 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.def | 4 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsp | 206 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLibExports.c | 15 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.c | 4 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/makefile | 59 p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/resource.rc | 3 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.c | 4 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.h | 13 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.c | 657 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsp | 231 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsw | 29 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile | 44 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile_con | 40 p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/resource.rc | 5 p7zip-rar-16.02+really25.00+ds/C/Xxh64.c | 327 p7zip-rar-16.02+really25.00+ds/C/Xxh64.h | 50 p7zip-rar-16.02+really25.00+ds/C/Xz.c | 182 p7zip-rar-16.02+really25.00+ds/C/Xz.h | 817 p7zip-rar-16.02+really25.00+ds/C/XzCrc64.c | 226 p7zip-rar-16.02+really25.00+ds/C/XzCrc64.h | 52 p7zip-rar-16.02+really25.00+ds/C/XzCrc64Opt.c | 330 p7zip-rar-16.02+really25.00+ds/C/XzDec.c | 3789 ++- p7zip-rar-16.02+really25.00+ds/C/XzEnc.c | 1912 + p7zip-rar-16.02+really25.00+ds/C/XzEnc.h | 101 p7zip-rar-16.02+really25.00+ds/C/XzIn.c | 698 p7zip-rar-16.02+really25.00+ds/C/ZstdDec.c | 4067 +++ p7zip-rar-16.02+really25.00+ds/C/ZstdDec.h | 173 p7zip-rar-16.02+really25.00+ds/C/var_clang.mak | 11 p7zip-rar-16.02+really25.00+ds/C/var_clang_arm64.mak | 12 p7zip-rar-16.02+really25.00+ds/C/var_clang_x64.mak | 11 p7zip-rar-16.02+really25.00+ds/C/var_clang_x86.mak | 11 p7zip-rar-16.02+really25.00+ds/C/var_gcc.mak | 12 p7zip-rar-16.02+really25.00+ds/C/var_gcc_arm64.mak | 12 p7zip-rar-16.02+really25.00+ds/C/var_gcc_x64.mak | 10 p7zip-rar-16.02+really25.00+ds/C/var_gcc_x86.mak | 10 p7zip-rar-16.02+really25.00+ds/C/var_mac_arm64.mak | 11 p7zip-rar-16.02+really25.00+ds/C/var_mac_x64.mak | 11 p7zip-rar-16.02+really25.00+ds/C/warn_clang.mak | 1 p7zip-rar-16.02+really25.00+ds/C/warn_clang_mac.mak | 1 p7zip-rar-16.02+really25.00+ds/C/warn_gcc.mak | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip.mak | 240 p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip_gcc.mak | 1370 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Aes.mak | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsp | 638 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.h | 166 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.cpp | 1142 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.h | 141 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.cpp | 1377 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.h | 187 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zExtract.cpp | 852 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.cpp | 400 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.h | 162 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.cpp | 1550 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.h | 351 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandlerOut.cpp | 2075 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.cpp | 38 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.h | 304 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.cpp | 3404 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.h | 885 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zItem.h | 390 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.cpp | 1942 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.h | 667 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.cpp | 356 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zRegister.cpp | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.cpp | 53 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.h | 84 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.cpp | 5600 ++-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.h | 306 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/makefile | 81 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/resource.rc | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApfsHandler.cpp | 4470 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApmHandler.cpp | 742 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArHandler.cpp | 1696 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive.def | 14 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive2.def | 21 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArchiveExports.cpp | 309 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArjHandler.cpp | 1955 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/AvbHandler.cpp | 596 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Base64Handler.cpp | 488 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Bz2Handler.cpp | 925 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.cpp | 222 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.h | 71 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.cpp | 2533 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.cpp | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.h | 82 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.cpp | 981 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.h | 352 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabItem.h | 132 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabRegister.cpp | 38 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.cpp | 1618 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.h | 62 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.cpp | 2081 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.h | 552 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ComHandler.cpp | 1784 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.cpp | 2188 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.h | 884 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.cpp | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.cpp | 152 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.h | 24 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.cpp | 472 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.h | 236 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.cpp | 103 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.h | 131 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.cpp | 228 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.h | 60 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.cpp | 384 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.h | 175 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.h | 72 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp | 47 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.h | 97 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CpioHandler.cpp | 1905 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CramfsHandler.cpp | 1571 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports.cpp | 96 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports2.cpp | 297 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DmgHandler.cpp | 3922 +-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ElfHandler.cpp | 2259 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ExtHandler.cpp | 5725 ++-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FatHandler.cpp | 2380 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FlvHandler.cpp | 1047 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GptHandler.cpp | 878 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GzHandler.cpp | 2246 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.cpp | 609 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.h | 250 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.cpp | 4506 ++- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.h | 87 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IArchive.h | 1352 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IhexHandler.cpp | 990 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.cpp | 909 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.h | 55 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.cpp | 24 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.h | 128 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.cpp | 1408 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.h | 655 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoItem.h | 470 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoRegister.cpp | 42 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LpHandler.cpp | 1170 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LvmHandler.cpp | 1107 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzhHandler.cpp | 1507 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzmaHandler.cpp | 1181 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MachoHandler.cpp | 1404 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MbrHandler.cpp | 1092 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MslzHandler.cpp | 786 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MubHandler.cpp | 504 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.cpp | 546 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.h | 173 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.cpp | 1373 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.cpp |12036 +++++----- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.h | 903 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisRegister.cpp | 40 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/NtfsHandler.cpp | 5649 ++-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PeHandler.cpp | 6477 ++--- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PpmdHandler.cpp | 869 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/QcowHandler.cpp | 1325 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.cpp | 6220 ++--- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.h | 938 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.cpp | 3537 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.h | 231 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHeader.h | 418 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarItem.h | 194 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarVol.h | 265 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/RpmHandler.cpp | 1514 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SparseHandler.cpp | 556 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SplitHandler.cpp | 712 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SquashfsHandler.cpp | 4588 +-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SwfHandler.cpp | 1979 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.cpp | 1771 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.h | 135 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandlerOut.cpp | 506 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.cpp | 122 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.h | 174 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.cpp | 1572 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.h | 177 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarItem.h | 462 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.cpp | 889 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.h | 89 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarRegister.cpp | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.cpp | 829 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.h | 112 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.cpp | 803 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.h | 70 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.cpp | 2882 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.h | 901 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/UefiHandler.cpp | 3502 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VdiHandler.cpp | 800 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdHandler.cpp | 1891 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdxHandler.cpp | 2083 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VmdkHandler.cpp | 3048 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.cpp | 2486 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.h | 198 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandlerOut.cpp | 3873 +-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.cpp | 3717 +-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.h | 1311 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimRegister.cpp | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XarHandler.cpp | 2048 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.cpp | 2408 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.h | 76 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZHandler.cpp | 461 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.cpp | 847 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.h | 138 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipCompressionMode.h | 124 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.cpp | 2768 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.h | 168 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp | 1074 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHeader.h | 377 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.cpp | 5762 ++-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.h | 805 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.cpp | 719 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.h | 666 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.cpp | 732 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.h | 191 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipRegister.cpp | 65 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp | 3407 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.h | 166 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZstdHandler.cpp | 1147 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/makefile | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Asm.mak | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsp | 3344 ++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile | 254 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.gcc | 357 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.list | 897 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/resource.rc | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile | 31 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile.gcc | 111 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/resource.rc | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsp | 2090 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile | 177 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.gcc | 279 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.list | 618 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/resource.rc | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/AloneGCOV/makefile | 286 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsp | 2275 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/makefile | 84 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/resource.rc | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/makefile | 148 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/resource.rc | 5 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/makefile | 116 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/resource.rc | 5 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/makefile | 98 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/resource.rc | 5 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc.mak | 310 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak | 395 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsp | 3426 ++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile | 21 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile.gcc | 57 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/resource.rc | 39 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile.list | 1010 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/makefile | 121 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/resource.rc | 5 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp | 1596 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp | 540 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile | 100 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.gcc | 131 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.list | 185 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/resource.rc | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsp | 1017 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SfxCon.cpp | 987 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile | 147 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.gcc | 215 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.list | 408 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/resource.rc | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp | 246 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h | 83 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp | 135 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp | 872 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp | 371 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/makefile | 121 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.rc | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsp | 1074 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SfxWin.cpp | 268 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/makefile | 159 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.h | 1 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.rc | 55 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/makefile | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zFM/CMakeLists.txt | 175 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zG/CMakeLists.txt | 140 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7z_/CMakeLists.txt | 111 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7za/CMakeLists.txt | 248 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zr/CMakeLists.txt | 178 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/CMakeLists.txt | 47 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt | 278 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate.sh | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate_xcode.sh | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.cpp | 588 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.h | 296 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.cpp | 1009 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.h | 382 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.cpp | 97 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.cpp | 1399 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.h | 376 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.cpp | 995 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.h | 427 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.cpp | 317 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.h | 211 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.cpp | 364 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.h | 93 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.cpp | 760 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.h | 473 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.cpp | 398 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.h | 143 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.cpp | 1223 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.h | 543 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.cpp | 855 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.h | 160 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.cpp | 76 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.cpp | 222 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.h | 196 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.cpp | 300 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.h | 201 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.cpp | 106 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.h | 89 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.cpp | 102 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.h | 68 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/PropId.cpp | 225 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterArc.h | 158 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterCodec.h | 212 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.cpp | 308 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.h | 139 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.cpp | 575 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.h | 303 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.cpp | 157 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.h | 44 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.cpp | 114 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.h | 67 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.cpp | 95 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Const.h | 126 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.cpp | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.h | 62 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.cpp | 2771 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.h | 626 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.cpp | 2011 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.h | 512 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Register.cpp | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.cpp | 1525 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.h | 244 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Register.cpp | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.cpp | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.h | 68 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjRegister.cpp | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.cpp | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.h | 363 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlEncoder.h | 113 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmDecoder.h | 201 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmEncoder.h | 139 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.cpp | 129 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.h | 94 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchRegister.cpp | 99 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ByteSwap.cpp | 183 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Codec.def | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CodecExports.cpp | 722 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.cpp | 268 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.h | 80 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyRegister.cpp | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Deflate64Register.cpp | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateConst.h | 262 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.cpp | 983 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.h | 309 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.cpp | 2048 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.h | 419 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateRegister.cpp | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeltaFilter.cpp | 254 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExports2Compress.cpp | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExportsCompress.cpp | 107 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/HuffmanDecoder.h | 787 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.cpp | 474 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.h | 117 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp | 92 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.h | 40 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.cpp | 28 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.h | 171 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.cpp | 950 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.h | 63 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.cpp | 470 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.h | 142 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LICENSE | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LzhamRegister.cpp | 783 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/README.md | 211 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham.h | 803 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_dynamic_lib.h | 156 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_exports.inc | 31 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_static_lib.h | 59 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/zlib.h | 2 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/CMakeLists.txt | 69 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_comp.h | 38 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp | 244 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.h | 46 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp | 750 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp | 2240 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.h | 503 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp | 1684 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp | 947 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.h | 164 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_null_threading.h | 98 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp | 214 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.h | 535 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_threading.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.cpp | 232 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.h | 387 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzhamcomp.vcxproj | 208 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/CMakeLists.txt | 86 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp | 80 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.h | 58 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp | 73 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.h | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_config.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_core.h | 303 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_decomp.h | 37 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_helpers.h | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp | 286 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.h | 32 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp | 1586 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp | 131 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.h | 89 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_math.h | 142 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp | 463 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.h | 115 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp | 159 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.h | 284 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp | 431 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.h | 157 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp | 1527 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.h | 494 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp | 147 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.h | 99 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_traits.h | 141 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_types.h | 72 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_utils.h | 58 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp | 83 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.h | 628 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzhamdecomp.vcxproj | 224 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp | 179 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzhamlib.vcxproj | 187 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile.list | 129 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.cpp | 533 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.h | 175 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.cpp | 233 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Register.cpp | 44 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.cpp | 618 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.h | 204 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.cpp | 526 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.h | 83 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaRegister.cpp | 44 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.cpp | 1195 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.h | 480 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzx.h | 118 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.cpp | 2046 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.h | 352 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Mtf8.h | 416 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.cpp | 382 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.h | 165 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.cpp | 345 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.h | 107 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdRegister.cpp | 44 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.cpp | 568 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.h | 165 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.cpp | 550 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.h | 235 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile | 49 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile.list | 113 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.cpp | 1011 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.h | 160 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.cpp | 873 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.h | 287 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.cpp | 1857 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.h | 565 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.cpp | 2279 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.h | 390 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.cpp | 3021 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.h | 467 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/RarCodecsRegister.cpp | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.cpp | 404 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.h | 71 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.cpp | 528 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.h | 31 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.cpp | 151 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.h | 86 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.cpp | 243 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.h | 35 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.cpp | 472 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.h | 101 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.cpp | 228 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.h | 157 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.cpp | 122 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.h | 90 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.cpp | 437 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.h | 98 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/makefile | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc.mak | 8 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc64.mak | 8 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.cpp | 595 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.h | 248 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAesRegister.cpp | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Codec.def | 4 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.cpp | 214 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.h | 70 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.cpp | 115 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.h | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.cpp | 391 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.h | 177 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAesReg.cpp | 45 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp | 145 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.h | 41 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.cpp | 363 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.h | 62 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.cpp | 260 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.h | 102 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.cpp | 529 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.h | 181 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.cpp | 335 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.h | 106 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Sha1Cls.h | 88 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.cpp | 466 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.h | 296 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.cpp | 228 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.h | 153 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.cpp | 491 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.h | 131 p7zip-rar-16.02+really25.00+ds/CPP/7zip/GuiCommon.rc | 119 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Guid.txt | 459 p7zip-rar-16.02+really25.00+ds/CPP/7zip/ICoder.h | 851 p7zip-rar-16.02+really25.00+ds/CPP/7zip/IDecl.h | 104 p7zip-rar-16.02+really25.00+ds/CPP/7zip/IPassword.h | 77 p7zip-rar-16.02+really25.00+ds/CPP/7zip/IProgress.h | 39 p7zip-rar-16.02+really25.00+ds/CPP/7zip/IStream.h | 337 p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzFindOpt.mak | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec.mak | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec_gcc.mak | 14 p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersion.h | 4 p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersionInfo.rc | 2 p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/generate.sh | 18 p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/premake4.lua | 253 p7zip-rar-16.02+really25.00+ds/CPP/7zip/PropID.h | 305 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.cpp | 73 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.h | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7Zip.pro | 35 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/main.cpp | 57 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.cpp | 212 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/all.pro | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.cpp | 465 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.pro | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7z_/7z_.pro | 111 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7za/7za.pro | 251 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7zr/7zr.pro | 182 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro | 279 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Lzham/Lzham.pro | 63 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Rar/Rar.pro | 55 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/all.pro | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/test_lib/test_lib.pro | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha1.mak | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha256.mak | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sort.mak | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/SubBuild.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/TestUI.cpp | 565 p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile.list | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.cpp | 3836 +-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.h | 690 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentOut.cpp | 1378 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.cpp | 1469 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.h | 324 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolder.cpp | 101 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp | 373 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 822 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/IFolderArchive.h | 242 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp | 416 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.h | 44 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.cpp | 2118 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsp | 331 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile | 38 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.gcc | 72 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.list | 99 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/resource.rc | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/ClientCodec.cpp | 370 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile | 41 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile.list | 24 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 3169 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.h | 317 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 4470 ++- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.h | 936 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.cpp | 254 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.h | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 554 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.h | 294 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.cpp | 8128 ++++-- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.h | 176 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.cpp | 756 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.h | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall2.cpp | 327 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.cpp | 74 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.h | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DirItem.h | 564 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.cpp | 2537 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.h | 59 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExitCode.h | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.cpp | 1052 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.h | 201 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractMode.h | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.cpp | 535 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.h | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.cpp | 2624 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.h | 429 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/IFileExtractCallback.h | 226 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.cpp | 2419 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.h | 906 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.cpp | 7246 +++--- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.h | 878 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.cpp | 1318 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.h | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Property.h | 28 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.cpp | 168 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.cpp | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.cpp | 39 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.h | 35 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.cpp | 3489 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.h | 419 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.cpp | 128 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.h | 132 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.cpp | 1831 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.h | 344 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.cpp | 536 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.h | 54 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.cpp | 144 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.h | 115 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.cpp | 178 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.cpp | 998 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.h | 337 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.cpp | 82 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.h | 28 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsp | 1052 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.mak | 46 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.manifest | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.cpp | 147 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.h | 65 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp | 1710 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.h | 375 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.cpp | 793 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.h | 106 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.cpp | 2712 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.h | 69 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Main.cpp | 2806 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/MainAr.cpp | 402 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.cpp | 226 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.h | 138 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.cpp | 367 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.h | 128 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 1672 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.h | 272 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.cpp | 223 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.h | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.gcc | 187 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.list | 333 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/resource.rc | 7 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/7-zip.dll.manifest | 1 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.cpp | 1837 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.h | 178 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenuFlags.h | 27 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp | 268 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.def | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsp | 620 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyExplorerCommand.h | 217 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.cpp | 80 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.h | 32 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp | 225 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.h | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/makefile | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.h | 15 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.rc | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource2.rc | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.cpp | 274 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.h | 43 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.cpp | 588 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.def | 35 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsp | 831 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarPlugin.h | 560 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.cpp | 524 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.h | 203 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Messages.h | 136 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.cpp | 145 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.h | 37 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.cpp | 926 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.h | 94 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginCommon.cpp | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginDelete.cpp | 144 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginRead.cpp | 301 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginWrite.cpp | 840 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.cpp | 305 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.h | 85 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.cpp | 327 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.h | 58 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/makefile | 107 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/resource.rc | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/7zFM.exe.manifest | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.cpp | 81 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.h | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.rc | 26 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialogRes.h | 8 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp | 946 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.h | 92 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.cpp | 1971 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.h | 678 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AppState.h | 190 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.cpp | 1132 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.h | 65 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.rc | 25 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.cpp | 1834 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.h | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.rc | 32 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2Res.h | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialogRes.h | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ClassDefs.cpp | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.cpp | 130 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.rc | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialogRes.h | 8 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog_rc.cpp | 60 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.cpp | 219 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.h | 62 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.rc | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialogRes.h | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog_rc.cpp | 77 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/DialogSize.h | 32 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.cpp | 57 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.rc | 15 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialogRes.h | 2 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.cpp | 159 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.h | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.rc | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage2.rc | 14 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPageRes.h | 15 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp | 107 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.h | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.cpp | 2307 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.h | 675 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.cpp | 2347 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsp | 1699 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.mak | 103 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM_rc.cpp | 1170 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.cpp | 1036 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.h | 111 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.cpp | 2307 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.h | 435 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolderCopy.cpp | 1578 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp | 589 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.cpp | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.h | 33 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.cpp | 172 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.h | 32 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.rc | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage2.rc | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPageRes.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.cpp | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.h | 28 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.cpp | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/IFolder.h | 405 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.cpp | 361 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.h | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.rc | 40 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPageRes.h | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.cpp | 621 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.h | 88 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.cpp | 402 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.h | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.rc | 38 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialogRes.h | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.cpp | 466 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.h | 76 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.rc | 14 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialogRes.h | 4 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp | 59 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.cpp | 218 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.rc | 49 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialogRes.h | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.cpp | 440 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.h | 57 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.rc | 24 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage2.rc | 28 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPageRes.h | 15 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.cpp | 154 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.h | 50 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.rc | 14 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialogRes.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp | 83 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyCom2.h | 46 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.cpp | 1691 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.h | 79 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyWindowsNew.h | 195 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.cpp | 276 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.h | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.cpp | 215 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.h | 160 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OptionsDialog.cpp | 89 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.cpp | 409 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.h | 158 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.rc | 93 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialogRes.h | 36 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp | 98 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.cpp | 2334 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.h | 1821 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCopy.cpp | 833 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCrc.cpp | 808 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelDrag.cpp | 3006 ++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelFolderChange.cpp | 1943 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 3067 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItems.cpp | 2617 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelKey.cpp | 357 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelListNotify.cpp | 1594 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelMenu.cpp | 2035 - p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelOperations.cpp | 1080 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSelect.cpp | 646 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSort.cpp | 555 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSplitFile.cpp | 1051 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.cpp | 116 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.rc | 18 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialogRes.h | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginInterface.h | 63 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginLoader.h | 61 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.cpp | 201 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.h | 171 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.rc | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 2840 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.h | 668 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.rc | 40 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2Res.h | 97 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp | 179 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2a.rc | 85 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialogRes.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.cpp | 46 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.rc | 109 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyNameRes.h | 198 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.cpp | 479 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.h | 77 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.cpp | 145 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.h | 61 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.cpp | 361 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.h | 108 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.cpp | 655 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.h | 51 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.cpp | 453 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.h | 37 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.rc | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage2.rc | 37 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPageRes.h | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.cpp | 231 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.rc | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialogRes.h | 16 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog_rc.cpp | 81 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.cpp | 183 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.h | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.h | 67 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.cpp | 109 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.h | 24 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.cpp | 619 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.h | 125 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.cpp | 472 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.h | 126 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.rc | 43 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPageRes.h | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.cpp | 383 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.h | 64 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.cpp | 271 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.h | 101 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/VerCtrl.cpp | 428 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.cpp | 627 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.h | 224 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile | 120 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile.list | 559 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Add2PNG.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/AddPNG.h | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Copy2PNG.h | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/CopyPNG.h | 26 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Delete2PNG.h | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/DeletePNG.h | 26 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Extract2PNG.h | 18 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ExtractPNG.h | 18 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Info2PNG.h | 21 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/InfoPNG.h | 22 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Move2PNG.h | 21 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/MovePNG.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ParentFolder.h | 91 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Test2PNG.h | 21 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/TestPNG.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.h | 374 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.rc | 296 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.h | 40 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.rc | 30 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/wxFM.cpp | 361 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/7zG.exe.manifest | 23 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.cpp | 2773 +- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.h | 202 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.rc | 288 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialogRes.h | 144 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp | 255 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.cpp | 5553 +++- p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.h | 698 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.rc | 233 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialogRes.h | 212 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog_rc.cpp | 328 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressOptionsDialog.rc | 79 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/Extract.rc | 59 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.cpp | 841 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.h | 226 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.rc | 98 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialogRes.h | 48 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog_rc.cpp | 161 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.cpp | 576 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.h | 77 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractRes.h | 102 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.cpp | 954 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsp | 1275 + p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsw | 29 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.cpp | 619 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.h | 43 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.cpp | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.h | 6 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 575 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.h | 65 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp | 189 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h | 88 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.cpp | 1096 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile | 289 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile.list | 417 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource.rc | 26 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.h | 4 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.rc | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.rc | 15 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/wxGUI.cpp | 783 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile.list | 78 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp | 370 p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/makefile | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_arm64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x86.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x86.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_arm64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_x64.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/makefile | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang.mak | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_arm64.mak | 19 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x64.mak | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x86.mak | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc.mak | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm.mak | 34 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm64.mak | 12 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x64.mak | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x86.mak | 10 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_arm64.mak | 13 p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_x64.mak | 11 p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang.mak | 3 p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang_mac.mak | 9 p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_gcc.mak | 55 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Android.mk | 107 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/makefile | 12 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Android.mk | 264 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Application.mk | 5 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/makefile | 35 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Android.mk | 194 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Application.mk | 5 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/makefile | 35 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Android.mk | 272 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/makefile | 10 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Android.mk | 56 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/makefile | 7 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o.d | 63 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o.d | 96 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o.d | 81 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Android.mk | 20 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/makefile | 14 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Android.mk | 20 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/makefile | 16 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile | 30 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile.inc | 33 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/readme.txt | 48 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Android.mk | 36 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Application.mk | 3 p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/makefile | 11 p7zip-rar-16.02+really25.00+ds/CPP/Build.mak | 252 p7zip-rar-16.02+really25.00+ds/CPP/Common/AutoPtr.h | 81 p7zip-rar-16.02+really25.00+ds/CPP/Common/CRC.cpp | 14 p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.cpp | 95 p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.h | 59 p7zip-rar-16.02+really25.00+ds/CPP/Common/CksumReg.cpp | 55 p7zip-rar-16.02+really25.00+ds/CPP/Common/ComTry.h | 39 p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.cpp | 435 p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.h | 126 p7zip-rar-16.02+really25.00+ds/CPP/Common/Common.h | 41 p7zip-rar-16.02+really25.00+ds/CPP/Common/Common0.h | 330 p7zip-rar-16.02+really25.00+ds/CPP/Common/CrcReg.cpp | 175 p7zip-rar-16.02+really25.00+ds/CPP/Common/Defs.h | 31 p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.cpp | 186 p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.h | 81 p7zip-rar-16.02+really25.00+ds/CPP/Common/DynamicBuffer.h | 140 p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.cpp | 361 p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.h | 78 p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.cpp | 336 p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.h | 53 p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.cpp | 267 p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.h | 32 p7zip-rar-16.02+really25.00+ds/CPP/Common/LzFindPrepare.cpp | 7 p7zip-rar-16.02+really25.00+ds/CPP/Common/Md5Reg.cpp | 44 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer.h | 541 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer2.h | 185 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyCom.h | 955 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyException.h | 28 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyGuidDef.h | 117 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyInitGuid.h | 102 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyLinux.h | 117 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.cpp | 280 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.cpp | 3574 +- p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.h | 1871 - p7zip-rar-16.02+really25.00+ds/CPP/Common/MyTypes.h | 76 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyUnknown.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.cpp | 6 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.h | 1350 - p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.cpp | 420 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.h | 551 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.cpp | 609 p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.h | 88 p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.cpp | 379 p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.h | 190 p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.cpp | 28 p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.h | 28 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Prepare.cpp | 7 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Reg.cpp | 107 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Prepare.cpp | 7 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Reg.cpp | 107 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha3Reg.cpp | 76 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Prepare.cpp | 7 p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Reg.cpp | 83 p7zip-rar-16.02+really25.00+ds/CPP/Common/StdAfx.h | 8 p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.cpp | 217 p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.h | 79 p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.cpp | 354 p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.h | 149 p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.cpp | 982 p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.h | 187 p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.cpp | 298 p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.h | 59 p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.cpp | 247 p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.h | 38 p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.cpp | 1151 p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.h | 396 p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.cpp | 1471 - p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.h | 380 p7zip-rar-16.02+really25.00+ds/CPP/Common/Xxh64Reg.cpp | 97 p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Init.cpp | 7 p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Reg.cpp | 81 p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.cpp | 82 p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.h | 156 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.cpp | 290 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.h | 56 p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.cpp | 269 p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.cpp | 10 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.h | 52 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.cpp | 66 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.h | 161 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/CommandBar.h | 52 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Controls.cpp | 533 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.cpp | 1030 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.h | 384 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/DialogImpl.h | 73 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Edit.h | 44 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.cpp | 10 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.h | 87 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.cpp | 162 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.h | 346 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ProgressBar.h | 69 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.cpp | 165 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.h | 50 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ReBar.h | 34 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Static.h | 51 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StatusBar.h | 98 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ToolBar.h | 43 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Trackbar.h | 27 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.cpp | 413 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.h | 126 p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.cpp | 363 p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.h | 153 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Defs.h | 34 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.cpp | 223 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.h | 31 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.cpp | 2239 + p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.h | 298 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.cpp | 2044 + p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.h | 477 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.cpp | 1412 - p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.h | 575 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileLink.cpp | 697 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.cpp | 12 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.h | 66 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.cpp | 1640 - p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.h | 177 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.cpp | 187 p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.h | 31 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Handle.h | 39 p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.cpp | 36 p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.h | 55 p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.cpp | 127 p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.h | 40 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.cpp | 265 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.h | 174 p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.cpp | 37 p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.h | 20 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.cpp | 398 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.h | 87 p7zip-rar-16.02+really25.00+ds/CPP/Windows/NtCheck.h | 104 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.cpp | 22 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.h | 12 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.cpp | 102 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.h | 138 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.cpp | 740 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.h | 285 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.cpp | 383 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.h | 77 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.cpp | 310 p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.h | 67 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.cpp | 787 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.h | 198 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.cpp | 103 p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.h | 33 p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.cpp | 186 p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.h | 150 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.cpp | 839 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.h | 150 p7zip-rar-16.02+really25.00+ds/CPP/Windows/StdAfx.h | 11 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.cpp | 244 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.h | 573 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization2.h | 218 p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp | 592 p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp.back | 168 p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.h | 206 p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.cpp | 1251 + p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.h | 19 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Thread.h | 87 p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.cpp | 670 p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.h | 170 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.cpp | 280 p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.h | 406 p7zip-rar-16.02+really25.00+ds/CPP/include_windows/basetyps.h | 19 p7zip-rar-16.02+really25.00+ds/CPP/include_windows/tchar.h | 89 p7zip-rar-16.02+really25.00+ds/CPP/include_windows/windows.h | 201 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/StdAfx.h | 216 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/config.h | 82 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/initguid.h | 4 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile | 24 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile.list | 36 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myAddExeFlag.cpp | 20 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myPrivate.h | 25 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/mySplitCommandLine.cpp | 217 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/test_lib.cpp | 836 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/wine_GetXXXDefaultLangID.cpp | 741 p7zip-rar-16.02+really25.00+ds/CPP/myWindows/wine_date_and_time.cpp | 468 p7zip-rar-16.02+really25.00+ds/ChangeLog | 1162 p7zip-rar-16.02+really25.00+ds/DOC/7zC.txt | 374 p7zip-rar-16.02+really25.00+ds/DOC/7zFormat.txt | 938 p7zip-rar-16.02+really25.00+ds/DOC/7zip.hhp | 84 p7zip-rar-16.02+really25.00+ds/DOC/7zip.wxs | 403 p7zip-rar-16.02+really25.00+ds/DOC/License.txt | 204 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/add.htm | 93 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/bench.htm | 88 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/delete.htm | 62 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract.htm | 96 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract_full.htm | 73 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/hash.htm | 65 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/index.htm | 36 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/list.htm | 78 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/rename.htm | 51 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/test.htm | 47 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/update.htm | 71 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/exit_codes.htm | 27 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/index.htm | 29 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_exclude.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_include.htm | 80 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_no.htm | 52 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bb.htm | 61 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bs.htm | 67 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/charset.htm | 61 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/exclude.htm | 71 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/include.htm | 89 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/index.htm | 95 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/large_pages.htm | 59 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/list_tech.htm | 36 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/method.htm | 738 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/output_dir.htm | 53 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/overwrite.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/password.htm | 55 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/recurse.htm | 85 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sa.htm | 58 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scc.htm | 42 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scrc.htm | 53 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sdel.htm | 39 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sfx.htm | 153 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/shared.htm | 40 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sni.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sns.htm | 77 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/spf.htm | 80 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ssc.htm | 50 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdin.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdout.htm | 54 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stl.htm | 39 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stop_switch.htm | 31 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stx.htm | 50 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/type.htm | 121 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/update.htm | 177 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/volume.htm | 49 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/working_dir.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/yes.htm | 48 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/syntax.htm | 120 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/about.htm | 21 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/benchmark.htm | 56 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/index.htm | 54 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/menu.htm | 154 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/options.htm | 152 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/add.htm | 311 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/extract.htm | 78 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/index.htm | 63 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/index.htm | 22 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/7z.htm | 117 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/faq.htm | 125 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/formats.htm | 100 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/index.htm | 28 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/license.htm | 30 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/performance.htm | 98 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/thanks.htm | 43 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/start.htm | 38 p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/style.css | 232 p7zip-rar-16.02+really25.00+ds/DOC/Methods.txt | 335 p7zip-rar-16.02+really25.00+ds/DOC/copying.txt | 1004 p7zip-rar-16.02+really25.00+ds/DOC/lzma.txt | 673 p7zip-rar-16.02+really25.00+ds/DOC/readme.txt | 457 p7zip-rar-16.02+really25.00+ds/DOC/src-history.txt | 1358 - p7zip-rar-16.02+really25.00+ds/GUI/Contents/Info.plist | 387 p7zip-rar-16.02+really25.00+ds/GUI/Contents/PkgInfo | 1 p7zip-rar-16.02+really25.00+ds/GUI/Lang/af.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/an.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ar.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ast.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/az.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ba.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/be.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/bg.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/bn.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/br.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ca.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/co.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/cs.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/cy.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/da.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/de.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/el.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/en.ttt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/eo.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/es.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/et.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/eu.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ext.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/fa.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/fi.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/fr.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/fur.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/fy.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ga.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/gl.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/gu.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/he.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/hi.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/hr.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/hu.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/hy.txt | 501 p7zip-rar-16.02+really25.00+ds/GUI/Lang/id.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/io.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/is.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/it.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ja.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ka.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/kaa.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/kk.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ko.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku-ckb.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ky.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/lij.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/lt.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/lv.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/mk.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/mn.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng2.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/mr.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ms.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/nb.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ne.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/nl.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/nn.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/pa-in.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/pl.txt | 477 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ps.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt-br.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ro.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ru.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sa.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/si.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sk.txt | 477 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sl.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sq.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spc.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spl.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/sv.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ta.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/th.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/tr.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/tt.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/ug.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/uk.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/uz.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/va.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/vi.txt | 404 p7zip-rar-16.02+really25.00+ds/GUI/Lang/yo.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-cn.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-tw.txt | 495 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress.desktop | 47 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress2.desktop | 47 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_subdir.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_to.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_test.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde3/readme.txt | 75 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress.desktop | 50 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress2.desktop | 50 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_subdir.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_to.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_test.desktop | 10 p7zip-rar-16.02+really25.00+ds/GUI/kde4/readme.txt | 60 p7zip-rar-16.02+really25.00+ds/GUI/p7zipForFilemanager | 108 p7zip-rar-16.02+really25.00+ds/GUI/p7zip_32.xpm | 38 p7zip-rar-16.02+really25.00+ds/README | 384 p7zip-rar-16.02+really25.00+ds/TODO | 37 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/Benchmark.h | 177 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/MemLat.cpp | 953 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.c | 267 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.h | 107 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk32.asm | 662 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk64.asm | 831 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile | 18 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile.list | 11 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MyVersion.h | 4 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/PipeLen.cpp | 428 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile | 17 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile.list | 8 p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/pl32.asm | 179 p7zip-rar-16.02+really25.00+ds/Utils/bin_to_sources.py | 101 p7zip-rar-16.02+really25.00+ds/Utils/file_7z.py | 83 p7zip-rar-16.02+really25.00+ds/Utils/file_7zCon_sfx.py | 101 p7zip-rar-16.02+really25.00+ds/Utils/file_7zFM.py | 139 p7zip-rar-16.02+really25.00+ds/Utils/file_7zG.py | 104 p7zip-rar-16.02+really25.00+ds/Utils/file_7z_so.py | 252 p7zip-rar-16.02+really25.00+ds/Utils/file_7za.py | 224 p7zip-rar-16.02+really25.00+ds/Utils/file_7zr.py | 154 p7zip-rar-16.02+really25.00+ds/Utils/file_Client7z.py | 25 p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Lzham_so.py | 39 p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Rar_so.py | 28 p7zip-rar-16.02+really25.00+ds/Utils/file_LzmaCon.py | 49 p7zip-rar-16.02+really25.00+ds/Utils/file_P7ZIP.py | 19 p7zip-rar-16.02+really25.00+ds/Utils/file_TestUI.py | 16 p7zip-rar-16.02+really25.00+ds/Utils/generate.py | 801 p7zip-rar-16.02+really25.00+ds/check/check.sh | 168 p7zip-rar-16.02+really25.00+ds/check/check_7zr.sh | 112 p7zip-rar-16.02+really25.00+ds/check/check_Client7z.sh | 95 p7zip-rar-16.02+really25.00+ds/check/check_install.sh | 158 p7zip-rar-16.02+really25.00+ds/check/clean_all.sh | 6 p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/ChangeLog | 41 p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme | 21 p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme.u7z | 30 p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/u7z | 133 p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/README | 21 p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/check/check.sh | 117 p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 | 33 p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/p7zip | 144 p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-shared | 14 p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-static | 10 p7zip-rar-16.02+really25.00+ds/debian/changelog | 23 p7zip-rar-16.02+really25.00+ds/debian/control | 8 p7zip-rar-16.02+really25.00+ds/debian/copyright | 296 p7zip-rar-16.02+really25.00+ds/debian/gbp.conf | 6 p7zip-rar-16.02+really25.00+ds/debian/p7zip-rar.install | 1 p7zip-rar-16.02+really25.00+ds/debian/patches/0001-Accept-Debian-build-flags.patch | 57 p7zip-rar-16.02+really25.00+ds/debian/patches/0002-Add-RAR-plugin-builder.patch | 205 p7zip-rar-16.02+really25.00+ds/debian/patches/0003-Add-missing-CRC-table-constructor-Closes-1118733.patch | 25 p7zip-rar-16.02+really25.00+ds/debian/patches/01-clean-makefile.patch | 255 p7zip-rar-16.02+really25.00+ds/debian/patches/03-include-linux-makefile.patch | 82 p7zip-rar-16.02+really25.00+ds/debian/patches/05-hardening-flags.patch | 33 p7zip-rar-16.02+really25.00+ds/debian/patches/06-CVE-2018-5996.patch | 221 p7zip-rar-16.02+really25.00+ds/debian/patches/CVE-2018-10115.patch | 311 p7zip-rar-16.02+really25.00+ds/debian/patches/series | 8 p7zip-rar-16.02+really25.00+ds/debian/rules | 32 p7zip-rar-16.02+really25.00+ds/debian/salsa-ci.yml | 3 p7zip-rar-16.02+really25.00+ds/debian/source/include-binaries | 1 p7zip-rar-16.02+really25.00+ds/debian/source/options | 2 p7zip-rar-16.02+really25.00+ds/debian/tests/control | 14 p7zip-rar-16.02+really25.00+ds/debian/watch | 3 p7zip-rar-16.02+really25.00+ds/install.sh | 208 p7zip-rar-16.02+really25.00+ds/install_local_context_menu.sh | 18 p7zip-rar-16.02+really25.00+ds/last_error | 1 p7zip-rar-16.02+really25.00+ds/makefile | 85 p7zip-rar-16.02+really25.00+ds/makefile.afl | 23 p7zip-rar-16.02+really25.00+ds/makefile.aix_gcc | 23 p7zip-rar-16.02+really25.00+ds/makefile.android_arm | 49 p7zip-rar-16.02+really25.00+ds/makefile.beos | 19 p7zip-rar-16.02+really25.00+ds/makefile.common | 150 p7zip-rar-16.02+really25.00+ds/makefile.crc32 | 8 p7zip-rar-16.02+really25.00+ds/makefile.cygwin | 21 p7zip-rar-16.02+really25.00+ds/makefile.cygwin64 | 21 p7zip-rar-16.02+really25.00+ds/makefile.cygwin64_asm | 22 p7zip-rar-16.02+really25.00+ds/makefile.cygwin_asm | 23 p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang | 21 p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang_asm | 23 p7zip-rar-16.02+really25.00+ds/makefile.djgpp | 22 p7zip-rar-16.02+really25.00+ds/makefile.djgpp_watt | 49 p7zip-rar-16.02+really25.00+ds/makefile.freebsd5 | 21 p7zip-rar-16.02+really25.00+ds/makefile.freebsd6+ | 21 p7zip-rar-16.02+really25.00+ds/makefile.glb | 48 p7zip-rar-16.02+really25.00+ds/makefile.gprof | 19 p7zip-rar-16.02+really25.00+ds/makefile.haiku | 19 p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc | 18 p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc_64 | 20 p7zip-rar-16.02+really25.00+ds/makefile.hpux-gcc | 22 p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64 | 23 p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm | 28 p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm_icc | 29 p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_sanitizer | 26 p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu | 23 p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu_gcc_4.X | 27 p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm_sanitize | 27 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_aarch64 | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_arm | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_djgpp | 27 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_m68k | 26 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_mipsel | 27 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64 | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64le | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_s390x | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_sparc64 | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc6_sanitize | 23 p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc_2.95_no_need_for_libstdc | 22 p7zip-rar-16.02+really25.00+ds/makefile.linux_other | 24 p7zip-rar-16.02+really25.00+ds/makefile.linux_s390x | 24 p7zip-rar-16.02+really25.00+ds/makefile.linux_scan-build | 23 p7zip-rar-16.02+really25.00+ds/makefile.linux_valgrind | 25 p7zip-rar-16.02+really25.00+ds/makefile.linux_x32 | 23 p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X | 31 p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X_fltk | 30 p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_mudflap_4.X | 28 p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_icc | 27 p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_icc | 25 p7zip-rar-16.02+really25.00+ds/makefile.machine | 23 p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits | 21 p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_asm | 25 p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_ppc | 22 p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_64bits | 21 p7zip-rar-16.02+really25.00+ds/makefile.macosx_llvm_64bits | 27 p7zip-rar-16.02+really25.00+ds/makefile.netbsd | 22 p7zip-rar-16.02+really25.00+ds/makefile.netware_asm_gcc_3.X | 43 p7zip-rar-16.02+really25.00+ds/makefile.oldmake | 85 p7zip-rar-16.02+really25.00+ds/makefile.openbsd | 24 p7zip-rar-16.02+really25.00+ds/makefile.openbsd_no_port | 24 p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.bin | 22 p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.so | 23 p7zip-rar-16.02+really25.00+ds/makefile.qnx_static | 22 p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_32 | 22 p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_64 | 25 p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_gcc | 22 p7zip-rar-16.02+really25.00+ds/makefile.solaris_x86 | 20 p7zip-rar-16.02+really25.00+ds/makefile.tru64 | 23 p7zip-rar-16.02+really25.00+ds/man1/7z.1 | 174 p7zip-rar-16.02+really25.00+ds/man1/7za.1 | 174 p7zip-rar-16.02+really25.00+ds/man1/7zr.1 | 171 1829 files changed, 386379 insertions(+), 310254 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpbfsnkd1s/p7zip-rar_16.02-3.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpbfsnkd1s/p7zip-rar_16.02+really25.00+ds-0+deb12u1.dsc: no acceptable signature found diff -Nru p7zip-rar-16.02/Asm/arm/7zCrcOpt.asm p7zip-rar-16.02+really25.00+ds/Asm/arm/7zCrcOpt.asm --- p7zip-rar-16.02/Asm/arm/7zCrcOpt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/arm/7zCrcOpt.asm 2009-10-08 09:12:00.000000000 +0000 @@ -0,0 +1,100 @@ + CODE32 + + EXPORT |CrcUpdateT4@16| + + AREA |.text|, CODE, ARM + + MACRO + CRC32_STEP_1 + + ldrb r4, [r1], #1 + subs r2, r2, #1 + eor r4, r4, r0 + and r4, r4, #0xFF + ldr r4, [r3, +r4, lsl #2] + eor r0, r4, r0, lsr #8 + + MEND + + + MACRO + CRC32_STEP_4 $STREAM_WORD + + eor r7, r7, r8 + eor r7, r7, r9 + eor r0, r0, r7 + eor r0, r0, $STREAM_WORD + ldr $STREAM_WORD, [r1], #4 + + and r7, r0, #0xFF + and r8, r0, #0xFF00 + and r9, r0, #0xFF0000 + and r0, r0, #0xFF000000 + + ldr r7, [r6, +r7, lsl #2] + ldr r8, [r5, +r8, lsr #6] + ldr r9, [r4, +r9, lsr #14] + ldr r0, [r3, +r0, lsr #22] + + MEND + + +|CrcUpdateT4@16| PROC + + stmdb sp!, {r4-r11, lr} + cmp r2, #0 + beq |$fin| + +|$v1| + tst r1, #7 + beq |$v2| + CRC32_STEP_1 + bne |$v1| + +|$v2| + cmp r2, #16 + blo |$v3| + + ldr r10, [r1], #4 + ldr r11, [r1], #4 + + add r4, r3, #0x400 + add r5, r3, #0x800 + add r6, r3, #0xC00 + + mov r7, #0 + mov r8, #0 + mov r9, #0 + + sub r2, r2, #16 + +|$loop| + ; pld [r1, #0x40] + + CRC32_STEP_4 r10 + CRC32_STEP_4 r11 + + subs r2, r2, #8 + bhs |$loop| + + sub r1, r1, #8 + add r2, r2, #16 + + eor r7, r7, r8 + eor r7, r7, r9 + eor r0, r0, r7 + +|$v3| + cmp r2, #0 + beq |$fin| + +|$v4| + CRC32_STEP_1 + bne |$v4| + +|$fin| + ldmia sp!, {r4-r11, pc} + +|CrcUpdateT4@16| ENDP + + END diff -Nru p7zip-rar-16.02/Asm/arm64/7zAsm.S p7zip-rar-16.02+really25.00+ds/Asm/arm64/7zAsm.S --- p7zip-rar-16.02/Asm/arm64/7zAsm.S 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/arm64/7zAsm.S 2021-04-25 18:00:00.000000000 +0000 @@ -0,0 +1,181 @@ +// 7zAsm.S -- ASM macros for arm64 +// 2021-04-25 : Igor Pavlov : Public domain + +#define r0 x0 +#define r1 x1 +#define r2 x2 +#define r3 x3 +#define r4 x4 +#define r5 x5 +#define r6 x6 +#define r7 x7 +#define r8 x8 +#define r9 x9 +#define r10 x10 +#define r11 x11 +#define r12 x12 +#define r13 x13 +#define r14 x14 +#define r15 x15 +#define r16 x16 +#define r17 x17 +#define r18 x18 +#define r19 x19 +#define r20 x20 +#define r21 x21 +#define r22 x22 +#define r23 x23 +#define r24 x24 +#define r25 x25 +#define r26 x26 +#define r27 x27 +#define r28 x28 +#define r29 x29 +#define r30 x30 + +#define REG_ABI_PARAM_0 r0 +#define REG_ABI_PARAM_1 r1 +#define REG_ABI_PARAM_2 r2 + + +.macro p2_add reg:req, param:req + add \reg, \reg, \param +.endm + +.macro p2_sub reg:req, param:req + sub \reg, \reg, \param +.endm + +.macro p2_sub_s reg:req, param:req + subs \reg, \reg, \param +.endm + +.macro p2_and reg:req, param:req + and \reg, \reg, \param +.endm + +.macro xor reg:req, param:req + eor \reg, \reg, \param +.endm + +.macro or reg:req, param:req + orr \reg, \reg, \param +.endm + +.macro shl reg:req, param:req + lsl \reg, \reg, \param +.endm + +.macro shr reg:req, param:req + lsr \reg, \reg, \param +.endm + +.macro sar reg:req, param:req + asr \reg, \reg, \param +.endm + +.macro p1_neg reg:req + neg \reg, \reg +.endm + +.macro dec reg:req + sub \reg, \reg, 1 +.endm + +.macro dec_s reg:req + subs \reg, \reg, 1 +.endm + +.macro inc reg:req + add \reg, \reg, 1 +.endm + +.macro inc_s reg:req + adds \reg, \reg, 1 +.endm + + +.macro imul reg:req, param:req + mul \reg, \reg, \param +.endm + +/* +arm64 and arm use reverted c flag after subs/cmp instructions: + arm64-arm : x86 + b.lo / b.cc : jb / jc + b.hs / b.cs : jae / jnc +*/ + +.macro jmp lab:req + b \lab +.endm + +.macro je lab:req + b.eq \lab +.endm + +.macro jz lab:req + b.eq \lab +.endm + +.macro jnz lab:req + b.ne \lab +.endm + +.macro jne lab:req + b.ne \lab +.endm + +.macro jb lab:req + b.lo \lab +.endm + +.macro jbe lab:req + b.ls \lab +.endm + +.macro ja lab:req + b.hi \lab +.endm + +.macro jae lab:req + b.hs \lab +.endm + + +.macro cmove dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, eq +.endm + +.macro cmovne dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, ne +.endm + +.macro cmovs dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, mi +.endm + +.macro cmovns dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, pl +.endm + +.macro cmovb dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, lo +.endm + +.macro cmovae dest:req, srcTrue:req + csel \dest, \srcTrue, \dest, hs +.endm + + +.macro MY_ALIGN_16 macro + .p2align 4,, (1 << 4) - 1 +.endm + +.macro MY_ALIGN_32 macro + .p2align 5,, (1 << 5) - 1 +.endm + +.macro MY_ALIGN_64 macro + .p2align 6,, (1 << 6) - 1 +.endm diff -Nru p7zip-rar-16.02/Asm/arm64/LzmaDecOpt.S p7zip-rar-16.02+really25.00+ds/Asm/arm64/LzmaDecOpt.S --- p7zip-rar-16.02/Asm/arm64/LzmaDecOpt.S 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/arm64/LzmaDecOpt.S 2021-04-25 18:00:00.000000000 +0000 @@ -0,0 +1,1487 @@ +// LzmaDecOpt.S -- ARM64-ASM version of LzmaDec_DecodeReal_3() function +// 2021-04-25 : Igor Pavlov : Public domain + +/* +; 3 - is the code compatibility version of LzmaDec_DecodeReal_*() +; function for check at link time. +; That code is tightly coupled with LzmaDec_TryDummy() +; and with another functions in LzmaDec.c file. +; CLzmaDec structure, (probs) array layout, input and output of +; LzmaDec_DecodeReal_*() must be equal in both versions (C / ASM). +*/ + + +#include "7zAsm.S" + + // .arch armv8-a + // .file "LzmaDecOpt.c" + .text + .align 2 + .p2align 4,,15 +#ifdef __APPLE__ + .globl _LzmaDec_DecodeReal_3 +#else + .global LzmaDec_DecodeReal_3 +#endif + // .type LzmaDec_DecodeReal_3, %function + +// #define _LZMA_SIZE_OPT 1 + +#define LZMA_USE_4BYTES_FILL 1 +// #define LZMA_USE_2BYTES_COPY 1 +// #define LZMA_USE_CMOV_LZ_WRAP 1 +// #define _LZMA_PROB32 1 + +#define MY_ALIGN_FOR_ENTRY MY_ALIGN_32 +#define MY_ALIGN_FOR_LOOP MY_ALIGN_32 +#define MY_ALIGN_FOR_LOOP_16 MY_ALIGN_16 + +#ifdef _LZMA_PROB32 + .equ PSHIFT , 2 + .macro PLOAD dest:req, mem:req + ldr \dest, [\mem] + .endm + .macro PLOAD_PREINDEXED dest:req, mem:req, offset:req + ldr \dest, [\mem, \offset]! + .endm + .macro PLOAD_2 dest:req, mem1:req, mem2:req + ldr \dest, [\mem1, \mem2] + .endm + .macro PLOAD_LSL dest:req, mem1:req, mem2:req + ldr \dest, [\mem1, \mem2, lsl #PSHIFT] + .endm + .macro PSTORE src:req, mem:req + str \src, [\mem] + .endm + .macro PSTORE_2 src:req, mem1:req, mem2:req + str \src, [\mem1, \mem2] + .endm + .macro PSTORE_LSL src:req, mem1:req, mem2:req + str \src, [\mem1, \mem2, lsl #PSHIFT] + .endm + .macro PSTORE_LSL_M1 src:req, mem1:req, mem2:req, temp_reg:req + // you must check that temp_reg is free register when macro is used + add \temp_reg, \mem1, \mem2 + str \src, [\temp_reg, \mem2] + .endm +#else + // .equ PSHIFT , 1 + #define PSHIFT 1 + .macro PLOAD dest:req, mem:req + ldrh \dest, [\mem] + .endm + .macro PLOAD_PREINDEXED dest:req, mem:req, offset:req + ldrh \dest, [\mem, \offset]! + .endm + .macro PLOAD_2 dest:req, mem1:req, mem2:req + ldrh \dest, [\mem1, \mem2] + .endm + .macro PLOAD_LSL dest:req, mem1:req, mem2:req + ldrh \dest, [\mem1, \mem2, lsl #PSHIFT] + .endm + .macro PSTORE src:req, mem:req + strh \src, [\mem] + .endm + .macro PSTORE_2 src:req, mem1:req, mem2:req + strh \src, [\mem1, \mem2] + .endm + .macro PSTORE_LSL src:req, mem1:req, mem2:req + strh \src, [\mem1, \mem2, lsl #PSHIFT] + .endm + .macro PSTORE_LSL_M1 src:req, mem1:req, mem2:req, temp_reg:req + strh \src, [\mem1, \mem2] + .endm +#endif + +.equ PMULT , (1 << PSHIFT) +.equ PMULT_2 , (2 << PSHIFT) + +.equ kMatchSpecLen_Error_Data , (1 << 9) + +# x7 t0 : NORM_CALC : prob2 (IF_BIT_1) +# x6 t1 : NORM_CALC : probs_state +# x8 t2 : (LITM) temp : (TREE) temp +# x4 t3 : (LITM) bit : (TREE) temp : UPDATE_0/UPDATE_0 temp +# x10 t4 : (LITM) offs : (TREE) probs_PMULT : numBits +# x9 t5 : (LITM) match : sym2 (ShortDist) +# x1 t6 : (LITM) litm_prob : (TREE) prob_reg : pbPos +# x2 t7 : (LITM) prm : probBranch : cnt +# x3 sym : dist +# x12 len +# x0 range +# x5 cod + + +#define range w0 + +// t6 +#define pbPos w1 +#define pbPos_R r1 +#define prob_reg w1 +#define litm_prob prob_reg + +// t7 +#define probBranch w2 +#define cnt w2 +#define cnt_R r2 +#define prm r2 + +#define sym w3 +#define sym_R r3 +#define dist sym + +#define t3 w4 +#define bit w4 +#define bit_R r4 +#define update_temp_reg r4 + +#define cod w5 + +#define t1 w6 +#define t1_R r6 +#define probs_state t1_R + +#define t0 w7 +#define t0_R r7 +#define prob2 t0 + +#define t2 w8 +#define t2_R r8 + +// t5 +#define match w9 +#define sym2 w9 +#define sym2_R r9 + +#define t4 w10 +#define t4_R r10 + +#define offs w10 +#define offs_R r10 + +#define probs r11 + +#define len w12 +#define len_R x12 + +#define state w13 +#define state_R r13 + +#define dicPos r14 +#define buf r15 +#define bufLimit r16 +#define dicBufSize r17 + +#define limit r19 +#define rep0 w20 +#define rep0_R r20 +#define rep1 w21 +#define rep2 w22 +#define rep3 w23 +#define dic r24 +#define probs_IsMatch r25 +#define probs_Spec r26 +#define checkDicSize w27 +#define processedPos w28 +#define pbMask w29 +#define lc2_lpMask w30 + + +.equ kNumBitModelTotalBits , 11 +.equ kBitModelTotal , (1 << kNumBitModelTotalBits) +.equ kNumMoveBits , 5 +.equ kBitModelOffset , (kBitModelTotal - (1 << kNumMoveBits) + 1) + +.macro NORM_2 macro + ldrb t0, [buf], 1 + shl range, 8 + orr cod, t0, cod, lsl 8 + /* + mov t0, cod + ldrb cod, [buf], 1 + shl range, 8 + bfi cod, t0, #8, #24 + */ +.endm + +.macro TEST_HIGH_BYTE_range macro + tst range, 0xFF000000 +.endm + +.macro NORM macro + TEST_HIGH_BYTE_range + jnz 1f + NORM_2 +1: +.endm + + +# ---------- Branch MACROS ---------- + +.macro UPDATE_0__0 + sub prob2, probBranch, kBitModelOffset +.endm + +.macro UPDATE_0__1 + sub probBranch, probBranch, prob2, asr #(kNumMoveBits) +.endm + +.macro UPDATE_0__2 probsArray:req, probOffset:req, probDisp:req + .if \probDisp == 0 + PSTORE_2 probBranch, \probsArray, \probOffset + .elseif \probOffset == 0 + PSTORE_2 probBranch, \probsArray, \probDisp * PMULT + .else + .error "unsupported" + // add update_temp_reg, \probsArray, \probOffset + PSTORE_2 probBranch, update_temp_reg, \probDisp * PMULT + .endif +.endm + +.macro UPDATE_0 probsArray:req, probOffset:req, probDisp:req + UPDATE_0__0 + UPDATE_0__1 + UPDATE_0__2 \probsArray, \probOffset, \probDisp +.endm + + +.macro UPDATE_1 probsArray:req, probOffset:req, probDisp:req + // sub cod, cod, prob2 + // sub range, range, prob2 + p2_sub cod, range + sub range, prob2, range + sub prob2, probBranch, probBranch, lsr #(kNumMoveBits) + .if \probDisp == 0 + PSTORE_2 prob2, \probsArray, \probOffset + .elseif \probOffset == 0 + PSTORE_2 prob2, \probsArray, \probDisp * PMULT + .else + .error "unsupported" + // add update_temp_reg, \probsArray, \probOffset + PSTORE_2 prob2, update_temp_reg, \probDisp * PMULT + .endif +.endm + + +.macro CMP_COD_BASE + NORM + // lsr prob2, range, kNumBitModelTotalBits + // imul prob2, probBranch + // cmp cod, prob2 + mov prob2, range + shr range, kNumBitModelTotalBits + imul range, probBranch + cmp cod, range +.endm + +.macro CMP_COD_1 probsArray:req + PLOAD probBranch, \probsArray + CMP_COD_BASE +.endm + +.macro CMP_COD_3 probsArray:req, probOffset:req, probDisp:req + .if \probDisp == 0 + PLOAD_2 probBranch, \probsArray, \probOffset + .elseif \probOffset == 0 + PLOAD_2 probBranch, \probsArray, \probDisp * PMULT + .else + .error "unsupported" + add update_temp_reg, \probsArray, \probOffset + PLOAD_2 probBranch, update_temp_reg, \probDisp * PMULT + .endif + CMP_COD_BASE +.endm + + +.macro IF_BIT_1_NOUP probsArray:req, probOffset:req, probDisp:req, toLabel:req + CMP_COD_3 \probsArray, \probOffset, \probDisp + jae \toLabel +.endm + + +.macro IF_BIT_1 probsArray:req, probOffset:req, probDisp:req, toLabel:req + IF_BIT_1_NOUP \probsArray, \probOffset, \probDisp, \toLabel + UPDATE_0 \probsArray, \probOffset, \probDisp +.endm + + +.macro IF_BIT_0_NOUP probsArray:req, probOffset:req, probDisp:req, toLabel:req + CMP_COD_3 \probsArray, \probOffset, \probDisp + jb \toLabel +.endm + +.macro IF_BIT_0_NOUP_1 probsArray:req, toLabel:req + CMP_COD_1 \probsArray + jb \toLabel +.endm + + +# ---------- CMOV MACROS ---------- + +.macro NORM_LSR + NORM + lsr t0, range, #kNumBitModelTotalBits +.endm + +.macro COD_RANGE_SUB + subs t1, cod, t0 + p2_sub range, t0 +.endm + +.macro RANGE_IMUL prob:req + imul t0, \prob +.endm + +.macro NORM_CALC prob:req + NORM_LSR + RANGE_IMUL \prob + COD_RANGE_SUB +.endm + +.macro CMOV_range + cmovb range, t0 +.endm + +.macro CMOV_code + cmovae cod, t1 +.endm + +.macro CMOV_code_Model_Pre prob:req + sub t0, \prob, kBitModelOffset + CMOV_code + cmovae t0, \prob +.endm + + +.macro PUP_BASE_2 prob:req, dest_reg:req + # only sar works for both 16/32 bit prob modes + sub \dest_reg, \prob, \dest_reg, asr #(kNumMoveBits) +.endm + +.macro PUP prob:req, probPtr:req, mem2:req + PUP_BASE_2 \prob, t0 + PSTORE_2 t0, \probPtr, \mem2 +.endm + + + +#define probs_PMULT t4_R + +.macro BIT_01 + add probs_PMULT, probs, PMULT +.endm + + +.macro BIT_0_R prob:req + PLOAD_2 \prob, probs, 1 * PMULT + NORM_LSR + sub t3, \prob, kBitModelOffset + RANGE_IMUL \prob + PLOAD_2 t2, probs, 1 * PMULT_2 + COD_RANGE_SUB + CMOV_range + cmovae t3, \prob + PLOAD_2 t0, probs, 1 * PMULT_2 + PMULT + PUP_BASE_2 \prob, t3 + csel \prob, t2, t0, lo + CMOV_code + mov sym, 2 + PSTORE_2 t3, probs, 1 * PMULT + adc sym, sym, wzr + BIT_01 +.endm + +.macro BIT_1_R prob:req + NORM_LSR + p2_add sym, sym + sub t3, \prob, kBitModelOffset + RANGE_IMUL \prob + PLOAD_LSL t2, probs, sym_R + COD_RANGE_SUB + CMOV_range + cmovae t3, \prob + PLOAD_LSL t0, probs_PMULT, sym_R + PUP_BASE_2 \prob, t3 + csel \prob, t2, t0, lo + CMOV_code + PSTORE_LSL_M1 t3, probs, sym_R, t2_R + adc sym, sym, wzr +.endm + + +.macro BIT_2_R prob:req + NORM_LSR + p2_add sym, sym + sub t3, \prob, kBitModelOffset + RANGE_IMUL \prob + COD_RANGE_SUB + CMOV_range + cmovae t3, \prob + CMOV_code + PUP_BASE_2 \prob, t3 + PSTORE_LSL_M1 t3, probs, sym_R, t2_R + adc sym, sym, wzr +.endm + + +# ---------- MATCHED LITERAL ---------- + +.macro LITM_0 macro + shl match, (PSHIFT + 1) + and bit, match, 256 * PMULT + add prm, probs, 256 * PMULT + 1 * PMULT + p2_add match, match + p2_add prm, bit_R + eor offs, bit, 256 * PMULT + PLOAD litm_prob, prm + + NORM_LSR + sub t2, litm_prob, kBitModelOffset + RANGE_IMUL litm_prob + COD_RANGE_SUB + cmovae offs, bit + CMOV_range + and bit, match, offs + cmovae t2, litm_prob + CMOV_code + mov sym, 2 + PUP_BASE_2 litm_prob, t2 + PSTORE t2, prm + add prm, probs, offs_R + adc sym, sym, wzr +.endm + +.macro LITM macro + p2_add prm, bit_R + xor offs, bit + PLOAD_LSL litm_prob, prm, sym_R + + NORM_LSR + p2_add match, match + sub t2, litm_prob, kBitModelOffset + RANGE_IMUL litm_prob + COD_RANGE_SUB + cmovae offs, bit + CMOV_range + and bit, match, offs + cmovae t2, litm_prob + CMOV_code + PUP_BASE_2 litm_prob, t2 + PSTORE_LSL t2, prm, sym_R + add prm, probs, offs_R + adc sym, sym, sym +.endm + + +.macro LITM_2 macro + p2_add prm, bit_R + PLOAD_LSL litm_prob, prm, sym_R + + NORM_LSR + sub t2, litm_prob, kBitModelOffset + RANGE_IMUL litm_prob + COD_RANGE_SUB + CMOV_range + cmovae t2, litm_prob + CMOV_code + PUP_BASE_2 litm_prob, t2 + PSTORE_LSL t2, prm, sym_R + adc sym, sym, sym +.endm + + +# ---------- REVERSE BITS ---------- + +.macro REV_0 prob:req + NORM_CALC \prob + CMOV_range + PLOAD t2, sym2_R + PLOAD_2 t3, probs, 3 * PMULT + CMOV_code_Model_Pre \prob + add t1_R, probs, 3 * PMULT + cmovae sym2_R, t1_R + PUP \prob, probs, 1 * PMULT + csel \prob, t2, t3, lo +.endm + + +.macro REV_1 prob:req, step:req + NORM_LSR + PLOAD_PREINDEXED t2, sym2_R, (\step * PMULT) + RANGE_IMUL \prob + COD_RANGE_SUB + CMOV_range + PLOAD_2 t3, sym2_R, (\step * PMULT) + sub t0, \prob, kBitModelOffset + CMOV_code + add t1_R, sym2_R, \step * PMULT + cmovae t0, \prob + cmovae sym2_R, t1_R + PUP_BASE_2 \prob, t0 + csel \prob, t2, t3, lo + PSTORE_2 t0, t1_R, 0 - \step * PMULT_2 +.endm + + +.macro REV_2 prob:req, step:req + sub t1_R, sym2_R, probs + NORM_LSR + orr sym, sym, t1, lsr #PSHIFT + RANGE_IMUL \prob + COD_RANGE_SUB + sub t2, sym, \step + CMOV_range + cmovb sym, t2 + CMOV_code_Model_Pre \prob + PUP \prob, sym2_R, 0 +.endm + + +.macro REV_1_VAR prob:req + PLOAD \prob, sym_R + mov probs, sym_R + p2_add sym_R, sym2_R + NORM_LSR + add t2_R, sym_R, sym2_R + RANGE_IMUL \prob + COD_RANGE_SUB + cmovae sym_R, t2_R + CMOV_range + CMOV_code_Model_Pre \prob + p2_add sym2, sym2 + PUP \prob, probs, 0 +.endm + + +.macro add_big dest:req, src:req, param:req + .if (\param) < (1 << 12) + add \dest, \src, \param + .else + #ifndef _LZMA_PROB32 + .error "unexpcted add_big expansion" + #endif + add \dest, \src, (\param) / 2 + add \dest, \dest, (\param) - (\param) / 2 + .endif +.endm + +.macro sub_big dest:req, src:req, param:req + .if (\param) < (1 << 12) + sub \dest, \src, \param + .else + #ifndef _LZMA_PROB32 + .error "unexpcted sub_big expansion" + #endif + sub \dest, \src, (\param) / 2 + sub \dest, \dest, (\param) - (\param) / 2 + .endif +.endm + + +.macro SET_probs offset:req + // add_big probs, probs_Spec, (\offset) * PMULT + add probs, probs_IsMatch, ((\offset) - IsMatch) * PMULT +.endm + + +.macro LIT_PROBS + add sym, sym, processedPos, lsl 8 + inc processedPos + UPDATE_0__0 + shl sym, lc2_lpMask + SET_probs Literal + p2_and sym, lc2_lpMask + // p2_add probs_state, pbPos_R + p2_add probs, sym_R + UPDATE_0__1 + add probs, probs, sym_R, lsl 1 + UPDATE_0__2 probs_state, pbPos_R, 0 +.endm + + + +.equ kNumPosBitsMax , 4 +.equ kNumPosStatesMax , (1 << kNumPosBitsMax) + +.equ kLenNumLowBits , 3 +.equ kLenNumLowSymbols , (1 << kLenNumLowBits) +.equ kLenNumHighBits , 8 +.equ kLenNumHighSymbols , (1 << kLenNumHighBits) +.equ kNumLenProbs , (2 * kLenNumLowSymbols * kNumPosStatesMax + kLenNumHighSymbols) + +.equ LenLow , 0 +.equ LenChoice , LenLow +.equ LenChoice2 , (LenLow + kLenNumLowSymbols) +.equ LenHigh , (LenLow + 2 * kLenNumLowSymbols * kNumPosStatesMax) + +.equ kNumStates , 12 +.equ kNumStates2 , 16 +.equ kNumLitStates , 7 + +.equ kStartPosModelIndex , 4 +.equ kEndPosModelIndex , 14 +.equ kNumFullDistances , (1 << (kEndPosModelIndex >> 1)) + +.equ kNumPosSlotBits , 6 +.equ kNumLenToPosStates , 4 + +.equ kNumAlignBits , 4 +.equ kAlignTableSize , (1 << kNumAlignBits) + +.equ kMatchMinLen , 2 +.equ kMatchSpecLenStart , (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +// .equ kStartOffset , 1408 +.equ kStartOffset , 0 +.equ SpecPos , (-kStartOffset) +.equ IsRep0Long , (SpecPos + kNumFullDistances) +.equ RepLenCoder , (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) +.equ LenCoder , (RepLenCoder + kNumLenProbs) +.equ IsMatch , (LenCoder + kNumLenProbs) +.equ kAlign , (IsMatch + (kNumStates2 << kNumPosBitsMax)) +.equ IsRep , (kAlign + kAlignTableSize) +.equ IsRepG0 , (IsRep + kNumStates) +.equ IsRepG1 , (IsRepG0 + kNumStates) +.equ IsRepG2 , (IsRepG1 + kNumStates) +.equ PosSlot , (IsRepG2 + kNumStates) +.equ Literal , (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +.equ NUM_BASE_PROBS , (Literal + kStartOffset) + +.if kStartOffset != 0 // && IsMatch != 0 + .error "Stop_Compiling_Bad_StartOffset" +.endif + +.if NUM_BASE_PROBS != 1984 + .error "Stop_Compiling_Bad_LZMA_PROBS" +.endif + +.equ offset_lc , 0 +.equ offset_lp , 1 +.equ offset_pb , 2 +.equ offset_dicSize , 4 +.equ offset_probs , 4 + offset_dicSize +.equ offset_probs_1664 , 8 + offset_probs +.equ offset_dic , 8 + offset_probs_1664 +.equ offset_dicBufSize , 8 + offset_dic +.equ offset_dicPos , 8 + offset_dicBufSize +.equ offset_buf , 8 + offset_dicPos +.equ offset_range , 8 + offset_buf +.equ offset_code , 4 + offset_range +.equ offset_processedPos , 4 + offset_code +.equ offset_checkDicSize , 4 + offset_processedPos +.equ offset_rep0 , 4 + offset_checkDicSize +.equ offset_rep1 , 4 + offset_rep0 +.equ offset_rep2 , 4 + offset_rep1 +.equ offset_rep3 , 4 + offset_rep2 +.equ offset_state , 4 + offset_rep3 +.equ offset_remainLen , 4 + offset_state +.equ offset_TOTAL_SIZE , 4 + offset_remainLen + +.if offset_TOTAL_SIZE != 96 + .error "Incorrect offset_TOTAL_SIZE" +.endif + + +.macro IsMatchBranch_Pre + # prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + and pbPos, pbMask, processedPos, lsl #(kLenNumLowBits + 1 + PSHIFT) + add probs_state, probs_IsMatch, state_R +.endm + + +/* +.macro IsMatchBranch + IsMatchBranch_Pre + IF_BIT_1 probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label +.endm +*/ + +.macro CheckLimits + cmp buf, bufLimit + jae fin_OK + cmp dicPos, limit + jae fin_OK +.endm + +#define CheckLimits_lit CheckLimits +/* +.macro CheckLimits_lit + cmp buf, bufLimit + jae fin_OK_lit + cmp dicPos, limit + jae fin_OK_lit +.endm +*/ + + +#define PARAM_lzma REG_ABI_PARAM_0 +#define PARAM_limit REG_ABI_PARAM_1 +#define PARAM_bufLimit REG_ABI_PARAM_2 + + +.macro LOAD_LZMA_VAR reg:req, struct_offs:req + ldr \reg, [PARAM_lzma, \struct_offs] +.endm + +.macro LOAD_LZMA_BYTE reg:req, struct_offs:req + ldrb \reg, [PARAM_lzma, \struct_offs] +.endm + +.macro LOAD_LZMA_PAIR reg0:req, reg1:req, struct_offs:req + ldp \reg0, \reg1, [PARAM_lzma, \struct_offs] +.endm + + +LzmaDec_DecodeReal_3: +_LzmaDec_DecodeReal_3: +/* +.LFB0: + .cfi_startproc +*/ + + stp x19, x20, [sp, -128]! + stp x21, x22, [sp, 16] + stp x23, x24, [sp, 32] + stp x25, x26, [sp, 48] + stp x27, x28, [sp, 64] + stp x29, x30, [sp, 80] + + str PARAM_lzma, [sp, 120] + + mov bufLimit, PARAM_bufLimit + mov limit, PARAM_limit + + LOAD_LZMA_PAIR dic, dicBufSize, offset_dic + LOAD_LZMA_PAIR dicPos, buf, offset_dicPos + LOAD_LZMA_PAIR rep0, rep1, offset_rep0 + LOAD_LZMA_PAIR rep2, rep3, offset_rep2 + + mov t0, 1 << (kLenNumLowBits + 1 + PSHIFT) + LOAD_LZMA_BYTE pbMask, offset_pb + p2_add limit, dic + mov len, wzr // we can set it in all requiread branches instead + lsl pbMask, t0, pbMask + p2_add dicPos, dic + p2_sub pbMask, t0 + + LOAD_LZMA_BYTE lc2_lpMask, offset_lc + mov t0, 256 << PSHIFT + LOAD_LZMA_BYTE t1, offset_lp + p2_add t1, lc2_lpMask + p2_sub lc2_lpMask, (256 << PSHIFT) - PSHIFT + shl t0, t1 + p2_add lc2_lpMask, t0 + + LOAD_LZMA_VAR probs_Spec, offset_probs + LOAD_LZMA_VAR checkDicSize, offset_checkDicSize + LOAD_LZMA_VAR processedPos, offset_processedPos + LOAD_LZMA_VAR state, offset_state + // range is r0 : this load must be last don't move + LOAD_LZMA_PAIR range, cod, offset_range + mov sym, wzr + shl state, PSHIFT + + add_big probs_IsMatch, probs_Spec, ((IsMatch - SpecPos) << PSHIFT) + + // if (processedPos != 0 || checkDicSize != 0) + orr t0, checkDicSize, processedPos + cbz t0, 1f + add t0_R, dicBufSize, dic + cmp dicPos, dic + cmovne t0_R, dicPos + ldrb sym, [t0_R, -1] +1: + IsMatchBranch_Pre + cmp state, 4 * PMULT + jb lit_end + cmp state, kNumLitStates * PMULT + jb lit_matched_end + jmp lz_end + + + +#define BIT_0 BIT_0_R prob_reg +#define BIT_1 BIT_1_R prob_reg +#define BIT_2 BIT_2_R prob_reg + +# ---------- LITERAL ---------- +MY_ALIGN_64 +lit_start: + mov state, wzr +lit_start_2: + LIT_PROBS + + #ifdef _LZMA_SIZE_OPT + + PLOAD_2 prob_reg, probs, 1 * PMULT + mov sym, 1 + BIT_01 +MY_ALIGN_FOR_LOOP +lit_loop: + BIT_1 + tbz sym, 7, lit_loop + + #else + + BIT_0 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + + #endif + + BIT_2 + IsMatchBranch_Pre + strb sym, [dicPos], 1 + p2_and sym, 255 + + CheckLimits_lit +lit_end: + IF_BIT_0_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), lit_start + + # jmp IsMatch_label + + +#define FLAG_STATE_BITS (4 + PSHIFT) + +# ---------- MATCHES ---------- +# MY_ALIGN_FOR_ENTRY +IsMatch_label: + UPDATE_1 probs_state, pbPos_R, (IsMatch - IsMatch) + IF_BIT_1 probs_state, 0, (IsRep - IsMatch), IsRep_label + + SET_probs LenCoder + or state, (1 << FLAG_STATE_BITS) + +# ---------- LEN DECODE ---------- +len_decode: + mov len, 8 - kMatchMinLen + IF_BIT_0_NOUP_1 probs, len_mid_0 + UPDATE_1 probs, 0, 0 + p2_add probs, (1 << (kLenNumLowBits + PSHIFT)) + mov len, 0 - kMatchMinLen + IF_BIT_0_NOUP_1 probs, len_mid_0 + UPDATE_1 probs, 0, 0 + p2_add probs, LenHigh * PMULT - (1 << (kLenNumLowBits + PSHIFT)) + + #if 0 == 1 + BIT_0 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + #else + PLOAD_2 prob_reg, probs, 1 * PMULT + mov sym, 1 + BIT_01 +MY_ALIGN_FOR_LOOP +len8_loop: + BIT_1 + tbz sym, 6, len8_loop + #endif + + mov len, (kLenNumHighSymbols - kLenNumLowSymbols * 2) - kMatchMinLen + jmp len_mid_2 + +MY_ALIGN_FOR_ENTRY +len_mid_0: + UPDATE_0 probs, 0, 0 + p2_add probs, pbPos_R + BIT_0 +len_mid_2: + BIT_1 + BIT_2 + sub len, sym, len + tbz state, FLAG_STATE_BITS, copy_match + +# ---------- DECODE DISTANCE ---------- + // probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + + mov t0, 3 + kMatchMinLen + cmp len, 3 + kMatchMinLen + cmovb t0, len + SET_probs PosSlot - (kMatchMinLen << (kNumPosSlotBits)) + add probs, probs, t0_R, lsl #(kNumPosSlotBits + PSHIFT) + + #ifdef _LZMA_SIZE_OPT + + PLOAD_2 prob_reg, probs, 1 * PMULT + mov sym, 1 + BIT_01 +MY_ALIGN_FOR_LOOP +slot_loop: + BIT_1 + tbz sym, 5, slot_loop + + #else + + BIT_0 + BIT_1 + BIT_1 + BIT_1 + BIT_1 + + #endif + + #define numBits t4 + mov numBits, sym + BIT_2 + // we need only low bits + p2_and sym, 3 + cmp numBits, 32 + kEndPosModelIndex / 2 + jb short_dist + + SET_probs kAlign + + # unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + p2_sub numBits, (32 + 1 + kNumAlignBits) + # distance = (2 | (distance & 1)); + or sym, 2 + PLOAD_2 prob_reg, probs, 1 * PMULT + add sym2_R, probs, 2 * PMULT + +# ---------- DIRECT DISTANCE ---------- + +.macro DIRECT_1 + shr range, 1 + subs t0, cod, range + p2_add sym, sym + // add t1, sym, 1 + csel cod, cod, t0, mi + csinc sym, sym, sym, mi + // csel sym, t1, sym, pl + // adc sym, sym, sym // not 100% compatible for "corruptued-allowed" LZMA streams + dec_s numBits + je direct_end +.endm + + #ifdef _LZMA_SIZE_OPT + + jmp direct_norm +MY_ALIGN_FOR_ENTRY +direct_loop: + DIRECT_1 +direct_norm: + TEST_HIGH_BYTE_range + jnz direct_loop + NORM_2 + jmp direct_loop + + #else + +.macro DIRECT_2 + TEST_HIGH_BYTE_range + jz direct_unroll + DIRECT_1 +.endm + + DIRECT_2 + DIRECT_2 + DIRECT_2 + DIRECT_2 + DIRECT_2 + DIRECT_2 + DIRECT_2 + DIRECT_2 + +direct_unroll: + NORM_2 + DIRECT_1 + DIRECT_1 + DIRECT_1 + DIRECT_1 + DIRECT_1 + DIRECT_1 + DIRECT_1 + DIRECT_1 + jmp direct_unroll + + #endif + +MY_ALIGN_FOR_ENTRY +direct_end: + shl sym, kNumAlignBits + REV_0 prob_reg + REV_1 prob_reg, 2 + REV_1 prob_reg, 4 + REV_2 prob_reg, 8 + +decode_dist_end: + + // if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) + + tst checkDicSize, checkDicSize + csel t0, processedPos, checkDicSize, eq + cmp sym, t0 + jae end_of_payload + // jmp end_of_payload # for debug + + mov rep3, rep2 + mov rep2, rep1 + mov rep1, rep0 + add rep0, sym, 1 + +.macro STATE_UPDATE_FOR_MATCH + // state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + // cmp state, (kNumStates + kNumLitStates) * PMULT + cmp state, kNumLitStates * PMULT + (1 << FLAG_STATE_BITS) + mov state, kNumLitStates * PMULT + mov t0, (kNumLitStates + 3) * PMULT + cmovae state, t0 +.endm + STATE_UPDATE_FOR_MATCH + +# ---------- COPY MATCH ---------- +copy_match: + + // if ((rem = limit - dicPos) == 0) break // return SZ_ERROR_DATA; + subs cnt_R, limit, dicPos + // jz fin_dicPos_LIMIT + jz fin_OK + + // curLen = ((rem < len) ? (unsigned)rem : len); + cmp cnt_R, len_R + cmovae cnt, len + + sub t0_R, dicPos, dic + p2_add dicPos, cnt_R + p2_add processedPos, cnt + p2_sub len, cnt + + // pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + p2_sub_s t0_R, rep0_R + jae 1f + + cmn t0_R, cnt_R + p2_add t0_R, dicBufSize + ja copy_match_cross +1: +# ---------- COPY MATCH FAST ---------- + # t0_R : src_pos + p2_add t0_R, dic + ldrb sym, [t0_R] + p2_add t0_R, cnt_R + p1_neg cnt_R + +copy_common: + dec dicPos + + # dicPos : (ptr_to_last_dest_BYTE) + # t0_R : (src_lim) + # cnt_R : (-curLen) + + IsMatchBranch_Pre + + inc_s cnt_R + jz copy_end + + cmp rep0, 1 + je copy_match_0 + + #ifdef LZMA_USE_2BYTES_COPY + strb sym, [dicPos, cnt_R] + dec dicPos + # dicPos : (ptr_to_last_dest_16bitWORD) + p2_and cnt_R, -2 + ldrh sym, [t0_R, cnt_R] + adds cnt_R, cnt_R, 2 + jz 2f +MY_ALIGN_FOR_LOOP +1: + /* + strh sym, [dicPos, cnt_R] + ldrh sym, [t0_R, cnt_R] + adds cnt_R, cnt_R, 2 + jz 2f + */ + + strh sym, [dicPos, cnt_R] + ldrh sym, [t0_R, cnt_R] + adds cnt_R, cnt_R, 2 + jnz 1b +2: + + /* + // for universal little/big endian code, but slow + strh sym, [dicPos] + inc dicPos + ldrb sym, [t0_R, -1] + */ + + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + // we must improve big-endian detection for another compilers + // for big-endian we need to revert bytes + rev16 sym, sym + #endif + + // (sym) must represent as little-endian here: + strb sym, [dicPos], 1 + shr sym, 8 + + #else + +MY_ALIGN_FOR_LOOP +1: + strb sym, [dicPos, cnt_R] + ldrb sym, [t0_R, cnt_R] + inc_s cnt_R + jz copy_end + + strb sym, [dicPos, cnt_R] + ldrb sym, [t0_R, cnt_R] + inc_s cnt_R + jnz 1b + #endif + +copy_end: +lz_end_match: + strb sym, [dicPos], 1 + + # IsMatchBranch_Pre + CheckLimits +lz_end: + IF_BIT_1_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label + + + +# ---------- LITERAL MATCHED ---------- + + LIT_PROBS + + // matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + + sub t0_R, dicPos, dic + p2_sub_s t0_R, rep0_R + + #ifdef LZMA_USE_CMOV_LZ_WRAP + add t1_R, t0_R, dicBufSize + cmovb t0_R, t1_R + #else + jae 1f + p2_add t0_R, dicBufSize +1: + #endif + + ldrb match, [dic, t0_R] + + // state -= (state < 10) ? 3 : 6; + sub sym, state, 6 * PMULT + cmp state, 10 * PMULT + p2_sub state, 3 * PMULT + cmovae state, sym + + #ifdef _LZMA_SIZE_OPT + + mov offs, 256 * PMULT + shl match, (PSHIFT + 1) + mov sym, 1 + and bit, match, offs + add prm, probs, offs_R + +MY_ALIGN_FOR_LOOP +litm_loop: + LITM + tbz sym, 8, litm_loop + + #else + + LITM_0 + LITM + LITM + LITM + LITM + LITM + LITM + LITM_2 + + #endif + + IsMatchBranch_Pre + strb sym, [dicPos], 1 + p2_and sym, 255 + + // mov len, wzr // LITM uses same regisetr (len / offs). So we clear it + CheckLimits_lit +lit_matched_end: + IF_BIT_1_NOUP probs_state, pbPos_R, (IsMatch - IsMatch), IsMatch_label + # IsMatchBranch + p2_sub state, 3 * PMULT + jmp lit_start_2 + + + +# ---------- REP 0 LITERAL ---------- +MY_ALIGN_FOR_ENTRY +IsRep0Short_label: + UPDATE_0 probs_state, pbPos_R, 0 + + // dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + sub t0_R, dicPos, dic + + // state = state < kNumLitStates ? 9 : 11; + or state, 1 * PMULT + + # the caller doesn't allow (dicPos >= limit) case for REP_SHORT + # so we don't need the following (dicPos == limit) check here: + # cmp dicPos, limit + # jae fin_dicPos_LIMIT_REP_SHORT + # // jmp fin_dicPos_LIMIT_REP_SHORT // for testing/debug puposes + + inc processedPos + + IsMatchBranch_Pre + + p2_sub_s t0_R, rep0_R + #ifdef LZMA_USE_CMOV_LZ_WRAP + add sym_R, t0_R, dicBufSize + cmovb t0_R, sym_R + #else + jae 1f + p2_add t0_R, dicBufSize +1: + #endif + + ldrb sym, [dic, t0_R] + // mov len, wzr + jmp lz_end_match + +MY_ALIGN_FOR_ENTRY +IsRep_label: + UPDATE_1 probs_state, 0, (IsRep - IsMatch) + + # The (checkDicSize == 0 && processedPos == 0) case was checked before in LzmaDec.c with kBadRepCode. + # So we don't check it here. + + # mov t0, processedPos + # or t0, checkDicSize + # jz fin_ERROR_2 + + // state = state < kNumLitStates ? 8 : 11; + cmp state, kNumLitStates * PMULT + mov state, 8 * PMULT + mov probBranch, 11 * PMULT + cmovae state, probBranch + + SET_probs RepLenCoder + + IF_BIT_1 probs_state, 0, (IsRepG0 - IsMatch), IsRepG0_label + sub_big probs_state, probs_state, (IsMatch - IsRep0Long) << PSHIFT + IF_BIT_0_NOUP probs_state, pbPos_R, 0, IsRep0Short_label + UPDATE_1 probs_state, pbPos_R, 0 + jmp len_decode + +MY_ALIGN_FOR_ENTRY +IsRepG0_label: + UPDATE_1 probs_state, 0, (IsRepG0 - IsMatch) + IF_BIT_1 probs_state, 0, (IsRepG1 - IsMatch), IsRepG1_label + mov dist, rep1 + mov rep1, rep0 + mov rep0, dist + jmp len_decode + +# MY_ALIGN_FOR_ENTRY +IsRepG1_label: + UPDATE_1 probs_state, 0, (IsRepG1 - IsMatch) + IF_BIT_1 probs_state, 0, (IsRepG2 - IsMatch), IsRepG2_label + mov dist, rep2 + mov rep2, rep1 + mov rep1, rep0 + mov rep0, dist + jmp len_decode + +# MY_ALIGN_FOR_ENTRY +IsRepG2_label: + UPDATE_1 probs_state, 0, (IsRepG2 - IsMatch) + mov dist, rep3 + mov rep3, rep2 + mov rep2, rep1 + mov rep1, rep0 + mov rep0, dist + jmp len_decode + + + +# ---------- SPEC SHORT DISTANCE ---------- + +MY_ALIGN_FOR_ENTRY +short_dist: + p2_sub_s numBits, 32 + 1 + jbe decode_dist_end + or sym, 2 + shl sym, numBits + add sym_R, probs_Spec, sym_R, lsl #PSHIFT + p2_add sym_R, SpecPos * PMULT + 1 * PMULT + mov sym2, PMULT // # step +MY_ALIGN_FOR_LOOP +spec_loop: + REV_1_VAR prob_reg + dec_s numBits + jnz spec_loop + + p2_add sym2_R, probs_Spec + .if SpecPos != 0 + p2_add sym2_R, SpecPos * PMULT + .endif + p2_sub sym_R, sym2_R + shr sym, PSHIFT + + jmp decode_dist_end + + + +# ---------- COPY MATCH 0 ---------- +MY_ALIGN_FOR_ENTRY +copy_match_0: + #ifdef LZMA_USE_4BYTES_FILL + strb sym, [dicPos, cnt_R] + inc_s cnt_R + jz copy_end + + strb sym, [dicPos, cnt_R] + inc_s cnt_R + jz copy_end + + strb sym, [dicPos, cnt_R] + inc_s cnt_R + jz copy_end + + orr t3, sym, sym, lsl 8 + p2_and cnt_R, -4 + orr t3, t3, t3, lsl 16 +MY_ALIGN_FOR_LOOP_16 +1: + /* + str t3, [dicPos, cnt_R] + adds cnt_R, cnt_R, 4 + jz 2f + */ + + str t3, [dicPos, cnt_R] + adds cnt_R, cnt_R, 4 + jnz 1b +2: + // p2_and sym, 255 + #else + +MY_ALIGN_FOR_LOOP +1: + strb sym, [dicPos, cnt_R] + inc_s cnt_R + jz copy_end + + strb sym, [dicPos, cnt_R] + inc_s cnt_R + jnz 1b + #endif + + jmp copy_end + + +# ---------- COPY MATCH CROSS ---------- +copy_match_cross: + # t0_R - src pos + # cnt_R - total copy len + + p1_neg cnt_R +1: + ldrb sym, [dic, t0_R] + inc t0_R + strb sym, [dicPos, cnt_R] + inc cnt_R + cmp t0_R, dicBufSize + jne 1b + + ldrb sym, [dic] + sub t0_R, dic, cnt_R + jmp copy_common + + + + +/* +fin_dicPos_LIMIT_REP_SHORT: + mov len, 1 + jmp fin_OK +*/ + +/* +fin_dicPos_LIMIT: + jmp fin_OK + # For more strict mode we can stop decoding with error + # mov sym, 1 + # jmp fin +*/ + +fin_ERROR_MATCH_DIST: + # rep0 = distance + 1; + p2_add len, kMatchSpecLen_Error_Data + mov rep3, rep2 + mov rep2, rep1 + mov rep1, rep0 + mov rep0, sym + STATE_UPDATE_FOR_MATCH + # jmp fin_OK + mov sym, 1 + jmp fin + +end_of_payload: + inc_s sym + jnz fin_ERROR_MATCH_DIST + + mov len, kMatchSpecLenStart + xor state, (1 << FLAG_STATE_BITS) + jmp fin_OK + +/* +fin_OK_lit: + mov len, wzr +*/ + +fin_OK: + mov sym, wzr + +fin: + NORM + + #define fin_lzma_reg t0_R + + .macro STORE_LZMA_VAR reg:req, struct_offs:req + str \reg, [fin_lzma_reg, \struct_offs] + .endm + + .macro STORE_LZMA_PAIR reg0:req, reg1:req, struct_offs:req + stp \reg0, \reg1, [fin_lzma_reg, \struct_offs] + .endm + + ldr fin_lzma_reg, [sp, 120] + p2_sub dicPos, dic + shr state, PSHIFT + + STORE_LZMA_PAIR dicPos, buf, offset_dicPos + STORE_LZMA_PAIR range, cod, offset_range + STORE_LZMA_VAR processedPos, offset_processedPos + STORE_LZMA_PAIR rep0, rep1, offset_rep0 + STORE_LZMA_PAIR rep2, rep3, offset_rep2 + STORE_LZMA_PAIR state, len, offset_state + + mov w0, sym + + ldp x29, x30, [sp, 80] + ldp x27, x28, [sp, 64] + ldp x25, x26, [sp, 48] + ldp x23, x24, [sp, 32] + ldp x21, x22, [sp, 16] + ldp x19, x20, [sp], 128 + + ret +/* + .cfi_endproc +.LFE0: + .size LzmaDec_DecodeReal_3, .-LzmaDec_DecodeReal_3 + .ident "TAG_LZMA" + .section .note.GNU-stack,"",@progbits +*/ diff -Nru p7zip-rar-16.02/Asm/x86/7zAsm.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/7zAsm.asm --- p7zip-rar-16.02/Asm/x86/7zAsm.asm 2015-09-26 10:08:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/7zAsm.asm 2023-12-08 11:00:00.000000000 +0000 @@ -1,100 +1,341 @@ ; 7zAsm.asm -- ASM macros -; 2009-12-12 : Igor Pavlov : Public domain -; 2011-10-12 : P7ZIP : Public domain +; 2023-12-08 : Igor Pavlov : Public domain -%define NOT ~ -%macro MY_ASM_START 0 - SECTION .text -%endmacro +; 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 +; @wordsize eq 2 for 32-bit x86 +if @wordsize eq 8 + x64 equ 1 +endif +else +ifdef RAX + x64 equ 1 +endif +endif + + +ifdef x64 + IS_X64 equ 1 +else + IS_X64 equ 0 +endif + +ifdef ABI_LINUX + IS_LINUX equ 1 +else + IS_LINUX equ 0 +endif + +ifndef x64 +; Use ABI_CDECL for x86 (32-bit) only +; if ABI_CDECL is not defined, we use fastcall abi +ifdef ABI_CDECL + IS_CDECL equ 1 +else + IS_CDECL equ 0 +endif +endif + +OPTION PROLOGUE:NONE +OPTION EPILOGUE:NONE + +MY_ASM_START macro + ifdef x64 + .code + else + .386 + .model flat + _TEXT$00 SEGMENT PARA PUBLIC 'CODE' + endif +endm -%macro MY_PROC 2 ; macro name:req, numParams:req +MY_PROC macro name:req, numParams:req align 16 - %define proc_numParams %2 ; numParams - global %1 - global _%1 - %1: - _%1: -%endmacro - -%macro MY_ENDP 0 - %ifdef x64 - ret - ; proc_name ENDP - %else - ret ; (proc_numParams - 2) * 4 - %endif -%endmacro + proc_numParams = numParams + if (IS_X64 gt 0) + proc_name equ name + elseif (IS_LINUX gt 0) + proc_name equ name + elseif (IS_CDECL gt 0) + proc_name equ @CatStr(_,name) + else + proc_name equ @CatStr(@,name,@, %numParams * 4) + endif + proc_name PROC +endm + +MY_ENDP macro + if (IS_X64 gt 0) + ret + elseif (IS_CDECL gt 0) + ret + elseif (proc_numParams LT 3) + ret + else + ret (proc_numParams - 2) * 4 + endif + proc_name ENDP +endm -%ifdef x64 + +ifdef x64 REG_SIZE equ 8 -%else + REG_LOGAR_SIZE equ 3 +else REG_SIZE equ 4 -%endif + REG_LOGAR_SIZE equ 2 +endif + + x0 equ EAX + x1 equ ECX + x2 equ EDX + x3 equ EBX + x4 equ ESP + x5 equ EBP + x6 equ ESI + x7 equ EDI + + x0_W equ AX + x1_W equ CX + x2_W equ DX + x3_W equ BX + + x5_W equ BP + x6_W equ SI + x7_W equ DI + + x0_L equ AL + x1_L equ CL + x2_L equ DL + x3_L equ BL + + x0_H equ AH + x1_H equ CH + x2_H equ DH + x3_H equ BH + +; r0_L equ AL +; r1_L equ CL +; r2_L equ DL +; r3_L equ BL + +; r0_H equ AH +; r1_H equ CH +; r2_H equ DH +; r3_H equ BH + + +ifdef x64 + x5_L equ BPL + x6_L equ SIL + x7_L equ DIL + x8_L equ r8b + x9_L equ r9b + x10_L equ r10b + x11_L equ r11b + x12_L equ r12b + x13_L equ r13b + x14_L equ r14b + x15_L equ r15b + + r0 equ RAX + r1 equ RCX + r2 equ RDX + r3 equ RBX + r4 equ RSP + r5 equ RBP + r6 equ RSI + r7 equ RDI + x8 equ r8d + x9 equ r9d + x10 equ r10d + x11 equ r11d + x12 equ r12d + x13 equ r13d + x14 equ r14d + x15 equ r15d +else + r0 equ x0 + r1 equ x1 + r2 equ x2 + r3 equ x3 + r4 equ x4 + r5 equ x5 + r6 equ x6 + r7 equ x7 +endif + + x0_R equ r0 + x1_R equ r1 + x2_R equ r2 + x3_R equ r3 + x4_R equ r4 + x5_R equ r5 + x6_R equ r6 + x7_R equ r7 + x8_R equ r8 + x9_R equ r9 + x10_R equ r10 + x11_R equ r11 + x12_R equ r12 + x13_R equ r13 + x14_R equ r14 + x15_R equ r15 - %define x0 EAX - %define x1 ECX - %define x2 EDX - %define x3 EBX - %define x4 ESP - %define x5 EBP - %define x6 ESI - %define x7 EDI - - %define x0_L AL - %define x1_L CL - %define x2_L DL - %define x3_L BL - - %define x0_H AH - %define x1_H CH - %define x2_H DH - %define x3_H BH - -%ifdef x64 - %define r0 RAX - %define r1 RCX - %define r2 RDX - %define r3 RBX - %define r4 RSP - %define r5 RBP - %define r6 RSI - %define r7 RDI -%else - %define r0 x0 - %define r1 x1 - %define r2 x2 - %define r3 x3 - %define r4 x4 - %define r5 x5 - %define r6 x6 - %define r7 x7 -%endif +ifdef x64 +ifdef ABI_LINUX -%macro MY_PUSH_4_REGS 0 +MY_PUSH_2_REGS macro + push r3 + push r5 +endm + +MY_POP_2_REGS macro + pop r5 + pop r3 +endm + +endif +endif + + +MY_PUSH_4_REGS macro push r3 push r5 -%ifdef x64 - %ifdef CYGWIN64 - push r6 - push r7 - %endif -%else push r6 push r7 -%endif -%endmacro +endm -%macro MY_POP_4_REGS 0 -%ifdef x64 - %ifdef CYGWIN64 - pop r7 - pop r6 - %endif -%else +MY_POP_4_REGS macro pop r7 pop r6 -%endif pop r5 pop r3 -%endmacro +endm + + +; for fastcall and for WIN-x64 +REG_PARAM_0_x equ x1 +REG_PARAM_0 equ r1 +REG_PARAM_1_x equ x2 +REG_PARAM_1 equ r2 + +ifndef x64 +; for x86-fastcall + +REG_ABI_PARAM_0_x equ REG_PARAM_0_x +REG_ABI_PARAM_0 equ REG_PARAM_0 +REG_ABI_PARAM_1_x equ REG_PARAM_1_x +REG_ABI_PARAM_1 equ REG_PARAM_1 + +MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + MY_PUSH_4_REGS +endm + +MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + MY_POP_4_REGS +endm + +else +; x64 + +if (IS_LINUX eq 0) + +; for WIN-x64: +REG_PARAM_2_x equ x8 +REG_PARAM_2 equ r8 +REG_PARAM_3 equ r9 + +REG_ABI_PARAM_0_x equ REG_PARAM_0_x +REG_ABI_PARAM_0 equ REG_PARAM_0 +REG_ABI_PARAM_1_x equ REG_PARAM_1_x +REG_ABI_PARAM_1 equ REG_PARAM_1 +REG_ABI_PARAM_2_x equ REG_PARAM_2_x +REG_ABI_PARAM_2 equ REG_PARAM_2 +REG_ABI_PARAM_3 equ REG_PARAM_3 + +else +; for LINUX-x64: +REG_LINUX_PARAM_0_x equ x7 +REG_LINUX_PARAM_0 equ r7 +REG_LINUX_PARAM_1_x equ x6 +REG_LINUX_PARAM_1 equ r6 +REG_LINUX_PARAM_2 equ r2 +REG_LINUX_PARAM_3 equ r1 +REG_LINUX_PARAM_4_x equ x8 +REG_LINUX_PARAM_4 equ r8 +REG_LINUX_PARAM_5 equ r9 + +REG_ABI_PARAM_0_x equ REG_LINUX_PARAM_0_x +REG_ABI_PARAM_0 equ REG_LINUX_PARAM_0 +REG_ABI_PARAM_1_x equ REG_LINUX_PARAM_1_x +REG_ABI_PARAM_1 equ REG_LINUX_PARAM_1 +REG_ABI_PARAM_2 equ REG_LINUX_PARAM_2 +REG_ABI_PARAM_3 equ REG_LINUX_PARAM_3 +REG_ABI_PARAM_4_x equ REG_LINUX_PARAM_4_x +REG_ABI_PARAM_4 equ REG_LINUX_PARAM_4 +REG_ABI_PARAM_5 equ REG_LINUX_PARAM_5 + +MY_ABI_LINUX_TO_WIN_2 macro + mov r2, r6 + mov r1, r7 +endm + +MY_ABI_LINUX_TO_WIN_3 macro + mov r8, r2 + mov r2, r6 + mov r1, r7 +endm + +MY_ABI_LINUX_TO_WIN_4 macro + mov r9, r1 + mov r8, r2 + mov r2, r6 + mov r1, r7 +endm + +endif ; IS_LINUX + + +MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + if (IS_LINUX gt 0) + MY_PUSH_2_REGS + else + MY_PUSH_4_REGS + endif +endm + +MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro + if (IS_LINUX gt 0) + MY_POP_2_REGS + else + MY_POP_4_REGS + endif +endm + + +MY_PUSH_PRESERVED_ABI_REGS macro + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + push r12 + push r13 + push r14 + push r15 +endm + + +MY_POP_PRESERVED_ABI_REGS macro + pop r15 + pop r14 + pop r13 + pop r12 + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +endm + +endif ; x64 diff -Nru p7zip-rar-16.02/Asm/x86/7zCrcOpt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt.asm --- p7zip-rar-16.02/Asm/x86/7zCrcOpt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt.asm 2023-12-08 17:00:00.000000000 +0000 @@ -0,0 +1,258 @@ +; 7zCrcOpt.asm -- CRC32 calculation : optimized version +; 2023-12-08 : Igor Pavlov : Public domain + +include 7zAsm.asm + +MY_ASM_START + +NUM_WORDS equ 3 +UNROLL_CNT equ 2 + +if (NUM_WORDS lt 1) or (NUM_WORDS gt 64) +.err +endif +if (UNROLL_CNT lt 1) +.err +endif + +rD equ r2 +rD_x equ x2 +rN equ r7 +rT equ r5 + +ifndef x64 + if (IS_CDECL gt 0) + crc_OFFS equ (REG_SIZE * 5) + data_OFFS equ (REG_SIZE + crc_OFFS) + size_OFFS equ (REG_SIZE + data_OFFS) + else + size_OFFS equ (REG_SIZE * 5) + endif + table_OFFS equ (REG_SIZE + size_OFFS) +endif + +; rN + rD is same speed as rD, but we reduce one instruction in loop +SRCDAT_1 equ rN + rD * 1 + 1 * +SRCDAT_4 equ rN + rD * 1 + 4 * + +CRC macro op:req, dest:req, src:req, t:req + op dest, dword ptr [rT + @CatStr(src, _R) * 4 + 0400h * (t)] +endm + +CRC_XOR macro dest:req, src:req, t:req + CRC xor, dest, src, t +endm + +CRC_MOV macro dest:req, src:req, t:req + CRC mov, dest, src, t +endm + +MOVZXLO macro dest:req, src:req + movzx dest, @CatStr(src, _L) +endm + +MOVZXHI macro dest:req, src:req + movzx dest, @CatStr(src, _H) +endm + +; movzx x0, x0_L - is slow in some cpus (ivb), if same register for src and dest +; movzx x3, x0_L sometimes is 0 cycles latency (not always) +; movzx x3, x0_L sometimes is 0.5 cycles latency +; movzx x3, x0_H is 2 cycles latency in some cpus + +CRC1b macro + movzx x6, byte ptr [rD] + MOVZXLO x3, x0 + inc rD + shr x0, 8 + xor x6, x3 + CRC_XOR x0, x6, 0 + dec rN +endm + +LOAD_1 macro dest:req, t:req, iter:req, index:req + movzx dest, byte ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)] +endm + +LOAD_2 macro dest:req, t:req, iter:req, index:req + movzx dest, word ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)] +endm + +CRC_QUAD macro nn, t:req, iter:req +ifdef x64 + ; paired memory loads give 1-3% speed gain, but it uses more registers + LOAD_2 x3, t, iter, 0 + LOAD_2 x9, t, iter, 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 3 + MOVZXLO x6, x9 + shr x9, 8 + CRC_XOR nn, x3, t * 4 + 2 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x9, t * 4 + 0 +elseif 0 + LOAD_2 x3, t, iter, 0 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 3 + CRC_XOR nn, x3, t * 4 + 2 + LOAD_2 x3, t, iter, 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x3, t * 4 + 0 +elseif 0 + LOAD_1 x3, t, iter, 0 + LOAD_1 x6, t, iter, 1 + CRC_XOR nn, x3, t * 4 + 3 + CRC_XOR nn, x6, t * 4 + 2 + LOAD_1 x3, t, iter, 2 + LOAD_1 x6, t, iter, 3 + CRC_XOR nn, x3, t * 4 + 1 + CRC_XOR nn, x6, t * 4 + 0 +else + ; 32-bit load is better if there is only one read port (core2) + ; but that code can be slower if there are 2 read ports (snb) + mov x3, dword ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + 0)] + MOVZXLO x6, x3 + CRC_XOR nn, x6, t * 4 + 3 + MOVZXHI x6, x3 + shr x3, 16 + CRC_XOR nn, x6, t * 4 + 2 + MOVZXLO x6, x3 + shr x3, 8 + CRC_XOR nn, x6, t * 4 + 1 + CRC_XOR nn, x3, t * 4 + 0 +endif +endm + + +LAST equ (4 * (NUM_WORDS - 1)) + +CRC_ITER macro qq, nn, iter + mov nn, [SRCDAT_4 (NUM_WORDS * (1 + iter))] + + i = 0 + rept NUM_WORDS - 1 + CRC_QUAD nn, i, iter + i = i + 1 + endm + + MOVZXLO x6, qq + mov x3, qq + shr x3, 24 + CRC_XOR nn, x6, LAST + 3 + CRC_XOR nn, x3, LAST + 0 + ror qq, 16 + MOVZXLO x6, qq + shr qq, 24 + CRC_XOR nn, x6, LAST + 1 +if ((UNROLL_CNT and 1) eq 1) and (iter eq (UNROLL_CNT - 1)) + CRC_MOV qq, qq, LAST + 2 + xor qq, nn +else + CRC_XOR nn, qq, LAST + 2 +endif +endm + + +; + 4 for prefetching next 4-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 * UNROLL_CNT + 4) +ALIGN_MASK equ 3 + + +; MY_PROC @CatStr(CrcUpdateT, 12), 4 +MY_PROC @CatStr(CrcUpdateT, %(NUM_WORDS * 4)), 4 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + ifdef x64 + mov x0, REG_ABI_PARAM_0_x ; x0 = x1(win) / x7(linux) + mov rT, REG_ABI_PARAM_3 ; r5 = r9(win) / x1(linux) + mov rN, REG_ABI_PARAM_2 ; r7 = r8(win) / r2(linux) + ; mov rD, REG_ABI_PARAM_1 ; r2 = r2(win) + if (IS_LINUX gt 0) + mov rD, REG_ABI_PARAM_1 ; r2 = r6 + endif + else + if (IS_CDECL gt 0) + mov x0, [r4 + crc_OFFS] + mov rD, [r4 + data_OFFS] + else + mov x0, REG_ABI_PARAM_0_x + endif + mov rN, [r4 + size_OFFS] + mov rT, [r4 + table_OFFS] + endif + + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end +@@: + test rD_x, ALIGN_MASK ; test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, dword ptr [rD] + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + sub rD, rN + +align 16 +@@: +unr_index = 0 +while unr_index lt UNROLL_CNT + if (unr_index and 1) eq 0 + CRC_ITER x0, x1, unr_index + else + CRC_ITER x1, x0, unr_index + endif + unr_index = unr_index + 1 +endm + + add rD, NUM_WORDS * 4 * UNROLL_CNT + jnc @B + +if 0 + ; byte verson + add rD, rN + xor x0, dword ptr [rD] + add rN, NUM_BYTES_LIMIT - 1 +else + ; 4-byte version + add rN, 4 * NUM_WORDS * UNROLL_CNT + sub rD, 4 * NUM_WORDS * UNROLL_CNT +@@: + MOVZXLO x3, x0 + MOVZXHI x1, x0 + shr x0, 16 + MOVZXLO x6, x0 + shr x0, 8 + CRC_MOV x0, x0, 0 + CRC_XOR x0, x3, 3 + CRC_XOR x0, x1, 2 + CRC_XOR x0, x6, 1 + + add rD, 4 +if (NUM_WORDS * UNROLL_CNT) ne 1 + jc @F + xor x0, [SRCDAT_4 0] + jmp @B +@@: +endif + add rD, rN + add rN, 4 - 1 + +endif + + sub rN, rD +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B + +func_end: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +MY_ENDP + +end diff -Nru p7zip-rar-16.02/Asm/x86/7zCrcOpt_asm.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt_asm.asm --- p7zip-rar-16.02/Asm/x86/7zCrcOpt_asm.asm 2015-09-26 10:08:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/7zCrcOpt_asm.asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -; 7zCrcOpt.asm -- CRC32 calculation : optimized version -; 2009-12-12 : Igor Pavlov : Public domain - -%include "7zAsm.asm" - -MY_ASM_START - -%define rD r2 -%define rN r7 - -%ifdef x64 - %define num_VAR r8 - %define table_VAR r9 -%else - data_size equ (REG_SIZE * 7) - crc_table equ (REG_SIZE + data_size) - %define num_VAR [r4 + data_size] - %define table_VAR [r4 + crc_table] -%endif - -%define SRCDAT rN + rD + 4 * - -%macro CRC 4 ;CRC macro op:req, dest:req, src:req, t:req - %1 %2, DWORD [r5 + %3 * 4 + 0400h * %4] ; op dest, DWORD [r5 + src * 4 + 0400h * t] -%endmacro - -%macro CRC_XOR 3 ; CRC_XOR macro dest:req, src:req, t:req - CRC xor, %1, %2, %3 -%endmacro - -%macro CRC_MOV 3 ; CRC_MOV macro dest:req, src:req, t:req - CRC mov, %1, %2, %3 ; CRC mov, dest, src, t -%endmacro - -%macro CRC1b 0 - movzx x6, BYTE [rD] - inc rD - movzx x3, x0_L - xor x6, x3 - shr x0, 8 - CRC xor, x0, r6, 0 - dec rN -%endmacro - -%macro MY_PROLOG 1 ; MY_PROLOG macro crc_end:req - MY_PUSH_4_REGS - - -%ifdef x64 - %ifdef CYGWIN64 - ;ECX=CRC, RDX=buf, R8=size R9=table - ; already in R8 : mov num_VAR,R8 ; LEN - ; already in RDX : mov rD, RDX ; BUF - ; already in R9 : mov table_VAR,R9; table - mov x0, ECX ; CRC - %else - ;EDI=CRC, RSI=buf, RDX=size RCX=table - mov num_VAR,RDX ; LEN - mov rD, RSI ; BUF - mov table_VAR,RCX; table - mov x0, EDI ; CRC - %endif -%else - mov x0, [r4 + 20] ; CRC - mov rD, [r4 + 24] ; buf -%endif - mov rN, num_VAR - mov r5, table_VAR - test rN, rN - jz near %1 ; crc_end - %%sl: - test rD, 7 - jz %%sl_end - CRC1b - jnz %%sl - %%sl_end: - cmp rN, 16 - jb near %1; crc_end - add rN, rD - mov num_VAR, rN - sub rN, 8 - and rN, NOT 7 - sub rD, rN - xor x0, [SRCDAT 0] -%endmacro - -%macro MY_EPILOG 1 ; MY_EPILOG macro crc_end:req - xor x0, [SRCDAT 0] - mov rD, rN - mov rN, num_VAR - sub rN, rD - %1: ; crc_end: - test rN, rN - jz %%end ; @F - CRC1b - jmp %1 ; crc_end - %%end: - MY_POP_4_REGS -%endmacro - -MY_PROC CrcUpdateT8, 4 - MY_PROLOG crc_end_8 - mov x1, [SRCDAT 1] - align 16 - main_loop_8: - mov x6, [SRCDAT 2] - movzx x3, x1_L - CRC_XOR x6, r3, 3 - movzx x3, x1_H - CRC_XOR x6, r3, 2 - shr x1, 16 - movzx x3, x1_L - movzx x1, x1_H - CRC_XOR x6, r3, 1 - movzx x3, x0_L - CRC_XOR x6, r1, 0 - - mov x1, [SRCDAT 3] - CRC_XOR x6, r3, 7 - movzx x3, x0_H - shr x0, 16 - CRC_XOR x6, r3, 6 - movzx x3, x0_L - CRC_XOR x6, r3, 5 - movzx x3, x0_H - CRC_MOV x0, r3, 4 - xor x0, x6 - add rD, 8 - jnz main_loop_8 - - MY_EPILOG crc_end_8 -MY_ENDP - -MY_PROC CrcUpdateT4, 4 - MY_PROLOG crc_end_4 - align 16 - - main_loop_4: - movzx x1, x0_L - movzx x3, x0_H - shr x0, 16 - movzx x6, x0_H - and x0, 0FFh - CRC_MOV x1, r1, 3 - xor x1, [SRCDAT 1] - CRC_XOR x1, r3, 2 - CRC_XOR x1, r6, 0 - CRC_XOR x1, r0, 1 - - movzx x0, x1_L - movzx x3, x1_H - shr x1, 16 - movzx x6, x1_H - and x1, 0FFh - CRC_MOV x0, r0, 3 - xor x0, [SRCDAT 2] - CRC_XOR x0, r3, 2 - CRC_XOR x0, r6, 0 - CRC_XOR x0, r1, 1 - add rD, 8 - jnz main_loop_4 - - MY_EPILOG crc_end_4 -MY_ENDP - -; end - -%ifidn __OUTPUT_FORMAT__,elf -section .note.GNU-stack noalloc noexec nowrite progbits -%endif - diff -Nru p7zip-rar-16.02/Asm/x86/AesOpt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/AesOpt.asm --- p7zip-rar-16.02/Asm/x86/AesOpt.asm 2015-09-26 10:08:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/AesOpt.asm 2021-12-25 15:00:00.000000000 +0000 @@ -1,310 +1,742 @@ -; AesOpt.asm -- Intel's AES. -; 2009-12-12 : Igor Pavlov : Public domain +; AesOpt.asm -- AES optimized code for x86 AES hardware instructions +; 2021-12-25 : Igor Pavlov : Public domain -%include "7zAsm.asm" +include 7zAsm.asm -MY_ASM_START +ifdef __ASMC__ + use_vaes_256 equ 1 +else +ifdef ymm0 + use_vaes_256 equ 1 +endif +endif + + +ifdef use_vaes_256 + ECHO "++ VAES 256" +else + ECHO "-- NO VAES 256" +endif + +ifdef x64 + ECHO "x86-64" +else + ECHO "x86" +if (IS_CDECL gt 0) + ECHO "ABI : CDECL" +else + ECHO "ABI : no CDECL : FASTCALL" +endif +endif + +if (IS_LINUX gt 0) + ECHO "ABI : LINUX" +else + ECHO "ABI : WINDOWS" +endif -%ifndef x64 -; FIXME .xmm -%endif - -%define rD r2 -%define rN r0 - -%macro MY_PROLOG 1 ; MY_PROLOG macro reg:req - %ifdef x64 - %ifdef CYGWIN64 - ; ivAes : %rcx - ; data : %rdx - ; numBlocks : %r8 - %else - mov RCX,RDI - mov R8 ,RDX - mov RDX,RSI - %endif - ; movdqa [r4 + 8], xmm6 - ; movdqa [r4 + 8 + 16], xmm7 - %endif - - push r3 - push r5 - -%ifdef x64 - %ifdef CYGWIN64 - push r6 - %endif - mov rN, r8 -%else - push r6 - mov ecx, [r4 + REG_SIZE * 4] - mov edx, [r4 + REG_SIZE * 5] - mov rN, [r4 + REG_SIZE * 6] -%endif - - mov x6, [r1 + 16] - shl x6, 5 - - movdqa %1, [r1] ; reg - add r1, 32 -%endmacro - -%macro MY_EPILOG 0 -%ifdef x64 - %ifdef CYGWIN64 - pop r6 - %endif -%else - pop r6 -%endif - pop r5 - pop r3 - - %ifdef x64 - ; movdqa xmm6, [r4 + 8] - ; movdqa xmm7, [r4 + 8 + 16] - %endif +MY_ASM_START +ifndef x64 + .686 + .xmm +endif + + +; MY_ALIGN EQU ALIGN(64) +MY_ALIGN EQU + +SEG_ALIGN EQU MY_ALIGN + +MY_SEG_PROC macro name:req, numParams:req + ; seg_name equ @CatStr(_TEXT$, name) + ; seg_name SEGMENT SEG_ALIGN 'CODE' + MY_PROC name, numParams +endm + +MY_SEG_ENDP macro + ; seg_name ENDS +endm + + +NUM_AES_KEYS_MAX equ 15 + +; the number of push operators in function PROLOG +if (IS_LINUX eq 0) or (IS_X64 eq 0) +num_regs_push equ 2 +stack_param_offset equ (REG_SIZE * (1 + num_regs_push)) +endif + +ifdef x64 + num_param equ REG_ABI_PARAM_2 +else + if (IS_CDECL gt 0) + ; size_t size + ; void * data + ; UInt32 * aes + ; ret-ip <- (r4) + aes_OFFS equ (stack_param_offset) + data_OFFS equ (REG_SIZE + aes_OFFS) + size_OFFS equ (REG_SIZE + data_OFFS) + num_param equ [r4 + size_OFFS] + else + num_param equ [r4 + stack_param_offset] + endif +endif + +keys equ REG_PARAM_0 ; r1 +rD equ REG_PARAM_1 ; r2 +rN equ r0 + +koffs_x equ x7 +koffs_r equ r7 + +ksize_x equ x6 +ksize_r equ r6 + +keys2 equ r3 + +state equ xmm0 +key equ xmm0 +key_ymm equ ymm0 +key_ymm_n equ 0 + +ifdef x64 + ways = 11 +else + ways = 4 +endif + +ways_start_reg equ 1 + +iv equ @CatStr(xmm, %(ways_start_reg + ways)) +iv_ymm equ @CatStr(ymm, %(ways_start_reg + ways)) + + +WOP macro op, op2 + i = 0 + rept ways + op @CatStr(xmm, %(ways_start_reg + i)), op2 + i = i + 1 + endm +endm + + +ifndef ABI_LINUX +ifdef x64 + +; we use 32 bytes of home space in stack in WIN64-x64 +NUM_HOME_MM_REGS equ (32 / 16) +; we preserve xmm registers starting from xmm6 in WIN64-x64 +MM_START_SAVE_REG equ 6 + +SAVE_XMM macro num_used_mm_regs:req + num_save_mm_regs = num_used_mm_regs - MM_START_SAVE_REG + if num_save_mm_regs GT 0 + num_save_mm_regs2 = num_save_mm_regs - NUM_HOME_MM_REGS + ; RSP is (16*x + 8) after entering the function in WIN64-x64 + stack_offset = 16 * num_save_mm_regs2 + (stack_param_offset mod 16) + + i = 0 + rept num_save_mm_regs + + if i eq NUM_HOME_MM_REGS + sub r4, stack_offset + endif + + if i lt NUM_HOME_MM_REGS + movdqa [r4 + stack_param_offset + i * 16], @CatStr(xmm, %(MM_START_SAVE_REG + i)) + else + movdqa [r4 + (i - NUM_HOME_MM_REGS) * 16], @CatStr(xmm, %(MM_START_SAVE_REG + i)) + endif + + i = i + 1 + endm + endif +endm + +RESTORE_XMM macro num_used_mm_regs:req + if num_save_mm_regs GT 0 + i = 0 + if num_save_mm_regs2 GT 0 + rept num_save_mm_regs2 + movdqa @CatStr(xmm, %(MM_START_SAVE_REG + NUM_HOME_MM_REGS + i)), [r4 + i * 16] + i = i + 1 + endm + add r4, stack_offset + endif + + num_low_regs = num_save_mm_regs - i + i = 0 + rept num_low_regs + movdqa @CatStr(xmm, %(MM_START_SAVE_REG + i)), [r4 + stack_param_offset + i * 16] + i = i + 1 + endm + endif +endm + +endif ; x64 +endif ; ABI_LINUX + + +MY_PROLOG macro num_used_mm_regs:req + ; num_regs_push: must be equal to the number of push operators + ; push r3 + ; push r5 + if (IS_LINUX eq 0) or (IS_X64 eq 0) + push r6 + push r7 + endif + + mov rN, num_param ; don't move it; num_param can use stack pointer (r4) + + if (IS_X64 eq 0) + if (IS_CDECL gt 0) + mov rD, [r4 + data_OFFS] + mov keys, [r4 + aes_OFFS] + endif + elseif (IS_LINUX gt 0) + MY_ABI_LINUX_TO_WIN_2 + endif + + + ifndef ABI_LINUX + ifdef x64 + SAVE_XMM num_used_mm_regs + endif + endif + + mov ksize_x, [keys + 16] + shl ksize_x, 5 +endm + + +MY_EPILOG macro + ifndef ABI_LINUX + ifdef x64 + RESTORE_XMM num_save_mm_regs + endif + endif + + if (IS_LINUX eq 0) or (IS_X64 eq 0) + pop r7 + pop r6 + endif + ; pop r5 + ; pop r3 MY_ENDP -%endmacro - -ways equ 4 -ways16 equ (ways * 16) +endm -%macro OP_W 2 ; op, op2 -%define i 0 - %1 xmm0,%2 -%define i 1 - %1 xmm1,%2 -%define i 2 - %1 xmm2,%2 -%define i 3 - %1 xmm3,%2 - -%endmacro - -%macro LOAD_OP 2 ; LOAD_OP macro op:req, offs:req - %1 xmm0, [r1 + r3 %2] -%endmacro - -%macro LOAD_OP_W 2 ; LOAD_OP_W macro op:req, offs:req - movdqa xmm7, [r1 + r3 %2] - ; OP_W %1, xmm7 - %1 xmm0,xmm7 - %1 xmm1,xmm7 - %1 xmm2,xmm7 - %1 xmm3,xmm7 -%endmacro +OP_KEY macro op:req, offs:req + op state, [keys + offs] +endm + + +WOP_KEY macro op:req, offs:req + movdqa key, [keys + offs] + WOP op, key +endm ; ---------- AES-CBC Decode ---------- -%macro CBC_DEC_UPDATE 2 ; CBC_DEC_UPDATE macro reg, offs - pxor %1, xmm6 - movdqa xmm6, [rD + %2] - movdqa [rD + %2], %1 -%endmacro - -%macro DECODE 1 ; macro op:req - %1 aesdec, +16 - %%B: - %1 aesdec, +0 - %1 aesdec, -16 - sub x3, 32 - jnz %%B - %1 aesdeclast, +0 -%endmacro - -; void AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks) -MY_PROC AesCbc_Decode_Intel, 3 - MY_PROLOG xmm6 - - sub x6, 32 - - jmp check2 - - align 16 - nextBlocks2: - mov x3, x6 - OP_W movdqa, [rD + i * 16] - - LOAD_OP_W pxor, +32 - - DECODE LOAD_OP_W - - ;OP_W CBC_DEC_UPDATE, i * 16 - CBC_DEC_UPDATE xmm0, 0 * 16 - CBC_DEC_UPDATE xmm1, 1 * 16 - CBC_DEC_UPDATE xmm2, 2 * 16 - CBC_DEC_UPDATE xmm3, 3 * 16 - - - add rD, ways16 - check2: - sub rN, ways - jnc nextBlocks2 - - add rN, ways - jmp check - - nextBlock: - mov x3, x6 - movdqa xmm1, [rD] - LOAD_OP movdqa, +32 - pxor xmm0, xmm1 - - DECODE LOAD_OP - - pxor xmm0, xmm6 - movdqa [rD], xmm0 - movdqa xmm6, xmm1 - add rD, 16 - check: - sub rN, 1 - jnc nextBlock - movdqa [r1 - 32], xmm6 +XOR_WITH_DATA macro reg, _ppp_ + pxor reg, [rD + i * 16] +endm + +WRITE_TO_DATA macro reg, _ppp_ + movdqa [rD + i * 16], reg +endm + + +; state0 equ @CatStr(xmm, %(ways_start_reg)) + +key0 equ @CatStr(xmm, %(ways_start_reg + ways + 1)) +key0_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 1)) + +key_last equ @CatStr(xmm, %(ways_start_reg + ways + 2)) +key_last_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 2)) +key_last_ymm_n equ (ways_start_reg + ways + 2) + +NUM_CBC_REGS equ (ways_start_reg + ways + 3) + + +MY_SEG_PROC AesCbc_Decode_HW, 3 + + AesCbc_Decode_HW_start:: + MY_PROLOG NUM_CBC_REGS + + AesCbc_Decode_HW_start_2:: + movdqa iv, [keys] + add keys, 32 + + movdqa key0, [keys + 1 * ksize_r] + movdqa key_last, [keys] + sub ksize_x, 16 + + jmp check2 + align 16 + nextBlocks2: + WOP movdqa, [rD + i * 16] + mov koffs_x, ksize_x + ; WOP_KEY pxor, ksize_r + 16 + WOP pxor, key0 + ; align 16 + @@: + WOP_KEY aesdec, 1 * koffs_r + sub koffs_r, 16 + jnz @B + ; WOP_KEY aesdeclast, 0 + WOP aesdeclast, key_last + + pxor @CatStr(xmm, %(ways_start_reg)), iv + i = 1 + rept ways - 1 + pxor @CatStr(xmm, %(ways_start_reg + i)), [rD + i * 16 - 16] + i = i + 1 + endm + movdqa iv, [rD + ways * 16 - 16] + WOP WRITE_TO_DATA + + add rD, ways * 16 + AesCbc_Decode_HW_start_3:: + check2: + sub rN, ways + jnc nextBlocks2 + add rN, ways + + sub ksize_x, 16 + + jmp check + nextBlock: + movdqa state, [rD] + mov koffs_x, ksize_x + ; OP_KEY pxor, 1 * ksize_r + 32 + pxor state, key0 + ; movdqa state0, [rD] + ; movdqa state, key0 + ; pxor state, state0 + @@: + OP_KEY aesdec, 1 * koffs_r + 16 + OP_KEY aesdec, 1 * koffs_r + sub koffs_r, 32 + jnz @B + OP_KEY aesdec, 16 + ; OP_KEY aesdeclast, 0 + aesdeclast state, key_last + + pxor state, iv + movdqa iv, [rD] + ; movdqa iv, state0 + movdqa [rD], state + + add rD, 16 + check: + sub rN, 1 + jnc nextBlock + + movdqa [keys - 32], iv +MY_EPILOG + + + + +; ---------- AVX ---------- + + +AVX__WOP_n macro op + i = 0 + rept ways + op (ways_start_reg + i) + i = i + 1 + endm +endm + +AVX__WOP macro op + i = 0 + rept ways + op @CatStr(ymm, %(ways_start_reg + i)) + i = i + 1 + endm +endm + + +AVX__WOP_KEY macro op:req, offs:req + vmovdqa key_ymm, ymmword ptr [keys2 + offs] + AVX__WOP_n op +endm + + +AVX__CBC_START macro reg + ; vpxor reg, key_ymm, ymmword ptr [rD + 32 * i] + vpxor reg, key0_ymm, ymmword ptr [rD + 32 * i] +endm + +AVX__CBC_END macro reg + if i eq 0 + vpxor reg, reg, iv_ymm + else + vpxor reg, reg, ymmword ptr [rD + i * 32 - 16] + endif +endm + + +AVX__WRITE_TO_DATA macro reg + vmovdqu ymmword ptr [rD + 32 * i], reg +endm + +AVX__XOR_WITH_DATA macro reg + vpxor reg, reg, ymmword ptr [rD + 32 * i] +endm + +AVX__CTR_START macro reg + vpaddq iv_ymm, iv_ymm, one_ymm + ; vpxor reg, iv_ymm, key_ymm + vpxor reg, iv_ymm, key0_ymm +endm + + +MY_VAES_INSTR_2 macro cmd, dest, a1, a2 + db 0c4H + db 2 + 040H + 020h * (1 - (a2) / 8) + 080h * (1 - (dest) / 8) + db 5 + 8 * ((not (a1)) and 15) + db cmd + db 0c0H + 8 * ((dest) and 7) + ((a2) and 7) +endm + +MY_VAES_INSTR macro cmd, dest, a + MY_VAES_INSTR_2 cmd, dest, dest, a +endm + +MY_vaesenc macro dest, a + MY_VAES_INSTR 0dcH, dest, a +endm +MY_vaesenclast macro dest, a + MY_VAES_INSTR 0ddH, dest, a +endm +MY_vaesdec macro dest, a + MY_VAES_INSTR 0deH, dest, a +endm +MY_vaesdeclast macro dest, a + MY_VAES_INSTR 0dfH, dest, a +endm + + +AVX__VAES_DEC macro reg + MY_vaesdec reg, key_ymm_n +endm + +AVX__VAES_DEC_LAST_key_last macro reg + ; MY_vaesdeclast reg, key_ymm_n + MY_vaesdeclast reg, key_last_ymm_n +endm + +AVX__VAES_ENC macro reg + MY_vaesenc reg, key_ymm_n +endm + +AVX__VAES_ENC_LAST macro reg + MY_vaesenclast reg, key_ymm_n +endm + +AVX__vinserti128_TO_HIGH macro dest, src + vinserti128 dest, dest, src, 1 +endm + + +MY_PROC AesCbc_Decode_HW_256, 3 + ifdef use_vaes_256 + MY_PROLOG NUM_CBC_REGS + + cmp rN, ways * 2 + jb AesCbc_Decode_HW_start_2 + + vmovdqa iv, xmmword ptr [keys] + add keys, 32 + + vbroadcasti128 key0_ymm, xmmword ptr [keys + 1 * ksize_r] + vbroadcasti128 key_last_ymm, xmmword ptr [keys] + sub ksize_x, 16 + mov koffs_x, ksize_x + add ksize_x, ksize_x + + AVX_STACK_SUB = ((NUM_AES_KEYS_MAX + 1 - 2) * 32) + push keys2 + sub r4, AVX_STACK_SUB + ; sub r4, 32 + ; sub r4, ksize_r + ; lea keys2, [r4 + 32] + mov keys2, r4 + and keys2, -32 + broad: + vbroadcasti128 key_ymm, xmmword ptr [keys + 1 * koffs_r] + vmovdqa ymmword ptr [keys2 + koffs_r * 2], key_ymm + sub koffs_r, 16 + ; jnc broad + jnz broad + + sub rN, ways * 2 + + align 16 + avx_cbcdec_nextBlock2: + mov koffs_x, ksize_x + ; AVX__WOP_KEY AVX__CBC_START, 1 * koffs_r + 32 + AVX__WOP AVX__CBC_START + @@: + AVX__WOP_KEY AVX__VAES_DEC, 1 * koffs_r + sub koffs_r, 32 + jnz @B + ; AVX__WOP_KEY AVX__VAES_DEC_LAST, 0 + AVX__WOP_n AVX__VAES_DEC_LAST_key_last + + AVX__vinserti128_TO_HIGH iv_ymm, xmmword ptr [rD] + AVX__WOP AVX__CBC_END + + vmovdqa iv, xmmword ptr [rD + ways * 32 - 16] + AVX__WOP AVX__WRITE_TO_DATA + + add rD, ways * 32 + sub rN, ways * 2 + jnc avx_cbcdec_nextBlock2 + add rN, ways * 2 + + shr ksize_x, 1 + + ; lea r4, [r4 + 1 * ksize_r + 32] + add r4, AVX_STACK_SUB + pop keys2 + + vzeroupper + jmp AesCbc_Decode_HW_start_3 + else + jmp AesCbc_Decode_HW_start + endif +MY_ENDP +MY_SEG_ENDP - MY_EPILOG + ; ---------- AES-CBC Encode ---------- -%macro ENCODE 1 ; macro op:req - %1 aesenc, -16 - %%B: - %1 aesenc, +0 - %1 aesenc, +16 - add r3, 32 - jnz %%B - %1 aesenclast, +0 -%endmacro - -MY_PROC AesCbc_Encode_Intel, 3 - MY_PROLOG xmm0 - - add r1, r6 - neg r6 - add r6, 32 - - jmp check_e - - align 16 - nextBlock_e: - mov r3, r6 - pxor xmm0, [rD] - pxor xmm0, [r1 + r3 - 32] - - ENCODE LOAD_OP - - movdqa [rD], xmm0 - add rD, 16 - check_e: - sub rN, 1 - jnc nextBlock_e +e0 equ xmm1 - movdqa [r1 + r6 - 64], xmm0 - MY_EPILOG +CENC_START_KEY equ 2 +CENC_NUM_REG_KEYS equ (3 * 2) +; last_key equ @CatStr(xmm, %(CENC_START_KEY + CENC_NUM_REG_KEYS)) + +MY_SEG_PROC AesCbc_Encode_HW, 3 + MY_PROLOG (CENC_START_KEY + CENC_NUM_REG_KEYS + 0) + + movdqa state, [keys] + add keys, 32 + + i = 0 + rept CENC_NUM_REG_KEYS + movdqa @CatStr(xmm, %(CENC_START_KEY + i)), [keys + i * 16] + i = i + 1 + endm + + add keys, ksize_r + neg ksize_r + add ksize_r, (16 * CENC_NUM_REG_KEYS) + ; movdqa last_key, [keys] + jmp check_e + + align 16 + nextBlock_e: + movdqa e0, [rD] + mov koffs_r, ksize_r + pxor e0, @CatStr(xmm, %(CENC_START_KEY)) + pxor state, e0 + + i = 1 + rept (CENC_NUM_REG_KEYS - 1) + aesenc state, @CatStr(xmm, %(CENC_START_KEY + i)) + i = i + 1 + endm + + @@: + OP_KEY aesenc, 1 * koffs_r + OP_KEY aesenc, 1 * koffs_r + 16 + add koffs_r, 32 + jnz @B + OP_KEY aesenclast, 0 + ; aesenclast state, last_key + + movdqa [rD], state + add rD, 16 + check_e: + sub rN, 1 + jnc nextBlock_e + + ; movdqa [keys - 32], state + movdqa [keys + 1 * ksize_r - (16 * CENC_NUM_REG_KEYS) - 32], state +MY_EPILOG +MY_SEG_ENDP + ; ---------- AES-CTR ---------- -%macro XOR_UPD_1 2 ; reg, offs - pxor %1, [rD + %2] -%endmacro - -%macro XOR_UPD_2 2 ; reg, offs - movdqa [rD + %2], %1 -%endmacro - -MY_PROC AesCtr_Code_Intel, 3 - MY_PROLOG xmm6 - - mov r5, r4 - shr r5, 4 - dec r5 - shl r5, 4 - - mov DWORD [r5], 1 - mov DWORD [r5 + 4], 0 - mov DWORD [r5 + 8], 0 - mov DWORD [r5 + 12], 0 - - add r1, r6 - neg r6 - add r6, 32 - - jmp check2_c - - align 16 - nextBlocks2_c: - movdqa xmm7, [r5] - -; i = 0 -; rept ways -; paddq xmm6, xmm7 -; movdqa @CatStr(xmm,%i), xmm6 -; i = i + 1 -; endm - paddq xmm6, xmm7 - movdqa xmm0, xmm6 - - paddq xmm6, xmm7 - movdqa xmm1, xmm6 - - paddq xmm6, xmm7 - movdqa xmm2, xmm6 - - paddq xmm6, xmm7 - movdqa xmm3, xmm6 - - - - mov r3, r6 - LOAD_OP_W pxor, -32 - - ENCODE LOAD_OP_W - - ;OP_W XOR_UPD_1, i * 16 - XOR_UPD_1 xmm0, 0 * 16 - XOR_UPD_1 xmm1, 1 * 16 - XOR_UPD_1 xmm2, 2 * 16 - XOR_UPD_1 xmm3, 3 * 16 - - ;OP_W XOR_UPD_2, i * 16 - XOR_UPD_2 xmm0, 0 * 16 - XOR_UPD_2 xmm1, 1 * 16 - XOR_UPD_2 xmm2, 2 * 16 - XOR_UPD_2 xmm3, 3 * 16 - - add rD, ways16 - check2_c: - sub rN, ways - jnc nextBlocks2_c - - add rN, ways - jmp check_c - - nextBlock_c: - paddq xmm6, [r5] - mov r3, r6 - movdqa xmm0, [r1 + r3 - 32] - pxor xmm0, xmm6 - ENCODE LOAD_OP - XOR_UPD_1 xmm0, 0 - XOR_UPD_2 xmm0, 0 - add rD, 16 - check_c: - sub rN, 1 - jnc nextBlock_c - - movdqa [r1 + r6 - 64], xmm6 - MY_EPILOG - -; end - -%ifidn __OUTPUT_FORMAT__,elf -section .note.GNU-stack noalloc noexec nowrite progbits -%endif +ifdef x64 + ; ways = 11 +endif + + +one equ @CatStr(xmm, %(ways_start_reg + ways + 1)) +one_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 1)) +key0 equ @CatStr(xmm, %(ways_start_reg + ways + 2)) +key0_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 2)) +NUM_CTR_REGS equ (ways_start_reg + ways + 3) + +INIT_CTR macro reg, _ppp_ + paddq iv, one + movdqa reg, iv +endm + + +MY_SEG_PROC AesCtr_Code_HW, 3 + Ctr_start:: + MY_PROLOG NUM_CTR_REGS + + Ctr_start_2:: + movdqa iv, [keys] + add keys, 32 + movdqa key0, [keys] + + add keys, ksize_r + neg ksize_r + add ksize_r, 16 + + Ctr_start_3:: + mov koffs_x, 1 + movd one, koffs_x + jmp check2_c + + align 16 + nextBlocks2_c: + WOP INIT_CTR, 0 + mov koffs_r, ksize_r + ; WOP_KEY pxor, 1 * koffs_r -16 + WOP pxor, key0 + @@: + WOP_KEY aesenc, 1 * koffs_r + add koffs_r, 16 + jnz @B + WOP_KEY aesenclast, 0 + + WOP XOR_WITH_DATA + WOP WRITE_TO_DATA + add rD, ways * 16 + check2_c: + sub rN, ways + jnc nextBlocks2_c + add rN, ways + + sub keys, 16 + add ksize_r, 16 + + jmp check_c + + ; align 16 + nextBlock_c: + paddq iv, one + ; movdqa state, [keys + 1 * koffs_r - 16] + movdqa state, key0 + mov koffs_r, ksize_r + pxor state, iv + + @@: + OP_KEY aesenc, 1 * koffs_r + OP_KEY aesenc, 1 * koffs_r + 16 + add koffs_r, 32 + jnz @B + OP_KEY aesenc, 0 + OP_KEY aesenclast, 16 + + pxor state, [rD] + movdqa [rD], state + add rD, 16 + check_c: + sub rN, 1 + jnc nextBlock_c + + ; movdqa [keys - 32], iv + movdqa [keys + 1 * ksize_r - 16 - 32], iv +MY_EPILOG + + +MY_PROC AesCtr_Code_HW_256, 3 + ifdef use_vaes_256 + MY_PROLOG NUM_CTR_REGS + + cmp rN, ways * 2 + jb Ctr_start_2 + + vbroadcasti128 iv_ymm, xmmword ptr [keys] + add keys, 32 + vbroadcasti128 key0_ymm, xmmword ptr [keys] + mov koffs_x, 1 + vmovd one, koffs_x + vpsubq iv_ymm, iv_ymm, one_ymm + vpaddq one, one, one + AVX__vinserti128_TO_HIGH one_ymm, one + + add keys, ksize_r + sub ksize_x, 16 + neg ksize_r + mov koffs_r, ksize_r + add ksize_r, ksize_r + + AVX_STACK_SUB = ((NUM_AES_KEYS_MAX + 1 - 1) * 32) + push keys2 + lea keys2, [r4 - 32] + sub r4, AVX_STACK_SUB + and keys2, -32 + vbroadcasti128 key_ymm, xmmword ptr [keys] + vmovdqa ymmword ptr [keys2], key_ymm + @@: + vbroadcasti128 key_ymm, xmmword ptr [keys + 1 * koffs_r] + vmovdqa ymmword ptr [keys2 + koffs_r * 2], key_ymm + add koffs_r, 16 + jnz @B + + sub rN, ways * 2 + + align 16 + avx_ctr_nextBlock2: + mov koffs_r, ksize_r + AVX__WOP AVX__CTR_START + ; AVX__WOP_KEY AVX__CTR_START, 1 * koffs_r - 32 + @@: + AVX__WOP_KEY AVX__VAES_ENC, 1 * koffs_r + add koffs_r, 32 + jnz @B + AVX__WOP_KEY AVX__VAES_ENC_LAST, 0 + + AVX__WOP AVX__XOR_WITH_DATA + AVX__WOP AVX__WRITE_TO_DATA + + add rD, ways * 32 + sub rN, ways * 2 + jnc avx_ctr_nextBlock2 + add rN, ways * 2 + + vextracti128 iv, iv_ymm, 1 + sar ksize_r, 1 + + add r4, AVX_STACK_SUB + pop keys2 + + vzeroupper + jmp Ctr_start_3 + else + jmp Ctr_start + endif +MY_ENDP +MY_SEG_ENDP +end diff -Nru p7zip-rar-16.02/Asm/x86/LzFindOpt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/LzFindOpt.asm --- p7zip-rar-16.02/Asm/x86/LzFindOpt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/LzFindOpt.asm 2024-06-18 13:00:00.000000000 +0000 @@ -0,0 +1,540 @@ +; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function +; 2024-06-18: Igor Pavlov : Public domain +; + +ifndef x64 +; x64=1 +; .err +endif + +include 7zAsm.asm + +MY_ASM_START + +ifndef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1 +else + Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1 +endif +endif + +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE' +MY_ALIGN macro num:req + align num + ; align 16 +endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside our function. + align 16 +endm +endif + + +MY_ALIGN_16 macro + MY_ALIGN 16 +endm + +MY_ALIGN_32 macro + MY_ALIGN 32 +endm + +MY_ALIGN_64 macro + MY_ALIGN 64 +endm + + +t0_L equ x0_L +t0_x equ x0 +t0 equ r0 +t1_x equ x3 +t1 equ r3 + +cp_x equ t1_x +cp_r equ t1 +m equ x5 +m_r equ r5 +len_x equ x6 +len equ r6 +diff_x equ x7 +diff equ r7 +len0 equ r10 +len1_x equ x11 +len1 equ r11 +maxLen_x equ x12 +maxLen equ r12 +d equ r13 +ptr0 equ r14 +ptr1 equ r15 + +d_lim equ m_r +cycSize equ len_x +hash_lim equ len0 +delta1_x equ len1_x +delta1_r equ len1 +delta_x equ maxLen_x +delta_r equ maxLen +hash equ ptr0 +src equ ptr1 + + + +if (IS_LINUX gt 0) + +; r1 r2 r8 r9 : win32 +; r7 r6 r2 r1 r8 r9 : linux + +lenLimit equ r8 +lenLimit_x equ x8 +; pos_r equ r2 +pos equ x2 +cur equ r1 +son equ r9 + +else + +lenLimit equ REG_ABI_PARAM_2 +lenLimit_x equ REG_ABI_PARAM_2_x +pos equ REG_ABI_PARAM_1_x +cur equ REG_ABI_PARAM_0 +son equ REG_ABI_PARAM_3 + +endif + + +if (IS_LINUX gt 0) + maxLen_OFFS equ (REG_SIZE * (6 + 1)) +else + cutValue_OFFS equ (REG_SIZE * (8 + 1 + 4)) + d_OFFS equ (REG_SIZE + cutValue_OFFS) + maxLen_OFFS equ (REG_SIZE + d_OFFS) +endif + hash_OFFS equ (REG_SIZE + maxLen_OFFS) + limit_OFFS equ (REG_SIZE + hash_OFFS) + size_OFFS equ (REG_SIZE + limit_OFFS) + cycPos_OFFS equ (REG_SIZE + size_OFFS) + cycSize_OFFS equ (REG_SIZE + cycPos_OFFS) + posRes_OFFS equ (REG_SIZE + cycSize_OFFS) + +if (IS_LINUX gt 0) +else + cutValue_PAR equ [r0 + cutValue_OFFS] + d_PAR equ [r0 + d_OFFS] +endif + maxLen_PAR equ [r0 + maxLen_OFFS] + hash_PAR equ [r0 + hash_OFFS] + limit_PAR equ [r0 + limit_OFFS] + size_PAR equ [r0 + size_OFFS] + cycPos_PAR equ [r0 + cycPos_OFFS] + cycSize_PAR equ [r0 + cycSize_OFFS] + posRes_PAR equ [r0 + posRes_OFFS] + + + cutValue_VAR equ DWORD PTR [r4 + 8 * 0] + cutValueCur_VAR equ DWORD PTR [r4 + 8 * 0 + 4] + cycPos_VAR equ DWORD PTR [r4 + 8 * 1 + 0] + cycSize_VAR equ DWORD PTR [r4 + 8 * 1 + 4] + hash_VAR equ QWORD PTR [r4 + 8 * 2] + limit_VAR equ QWORD PTR [r4 + 8 * 3] + size_VAR equ QWORD PTR [r4 + 8 * 4] + distances equ QWORD PTR [r4 + 8 * 5] + maxLen_VAR equ QWORD PTR [r4 + 8 * 6] + + Old_RSP equ QWORD PTR [r4 + 8 * 7] + LOCAL_SIZE equ 8 * 8 + +COPY_VAR_32 macro dest_var, src_var + mov x3, src_var + mov dest_var, x3 +endm + +COPY_VAR_64 macro dest_var, src_var + mov r3, src_var + mov dest_var, r3 +endm + + +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif +MY_PROC GetMatchesSpecN_2, 13 +MY_PUSH_PRESERVED_ABI_REGS + mov r0, RSP + lea r3, [r0 - LOCAL_SIZE] + and r3, -64 + mov RSP, r3 + mov Old_RSP, r0 + +if (IS_LINUX gt 0) + mov d, REG_ABI_PARAM_5 ; r13 = r9 + mov cutValue_VAR, REG_ABI_PARAM_4_x ; = r8 + mov son, REG_ABI_PARAM_3 ; r9 = r1 + mov r8, REG_ABI_PARAM_2 ; r8 = r2 + mov pos, REG_ABI_PARAM_1_x ; r2 = x6 + mov r1, REG_ABI_PARAM_0 ; r1 = r7 +else + COPY_VAR_32 cutValue_VAR, cutValue_PAR + mov d, d_PAR +endif + + COPY_VAR_64 limit_VAR, limit_PAR + + mov hash_lim, size_PAR + mov size_VAR, hash_lim + + mov cp_x, cycPos_PAR + mov hash, hash_PAR + + mov cycSize, cycSize_PAR + mov cycSize_VAR, cycSize + + ; we want cur in (rcx). So we change the cur and lenLimit variables + sub lenLimit, cur + neg lenLimit_x + inc lenLimit_x + + mov t0_x, maxLen_PAR + sub t0, lenLimit + mov maxLen_VAR, t0 + + jmp main_loop + +MY_ALIGN_64 +fill_empty: + ; ptr0 = *ptr1 = kEmptyHashValue; + mov QWORD PTR [ptr1], 0 + inc pos + inc cp_x + mov DWORD PTR [d - 4], 0 + cmp d, limit_VAR + jae fin + cmp hash, hash_lim + je fin + +; MY_ALIGN_64 +main_loop: + ; UInt32 delta = *hash++; + mov diff_x, [hash] ; delta + add hash, 4 + ; mov cycPos_VAR, cp_x + + inc cur + add d, 4 + mov m, pos + sub m, diff_x; ; matchPos + + ; CLzRef *ptr1 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2; + lea ptr1, [son + 8 * cp_r] + ; mov cycSize, cycSize_VAR + cmp pos, cycSize + jb directMode ; if (pos < cycSize_VAR) + + ; CYC MODE + + cmp diff_x, cycSize + jae fill_empty ; if (delta >= cycSize_VAR) + + xor t0_x, t0_x + mov cycPos_VAR, cp_x + sub cp_x, diff_x + ; jae prepare_for_tree_loop + ; add cp_x, cycSize + cmovb t0_x, cycSize + add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0) + jmp prepare_for_tree_loop + + +directMode: + cmp diff_x, pos + je fill_empty ; if (delta == pos) + jae fin_error ; if (delta >= pos) + + mov cycPos_VAR, cp_x + mov cp_x, m + +prepare_for_tree_loop: + mov len0, lenLimit + mov hash_VAR, hash + ; CLzRef *ptr0 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2 + 1; + lea ptr0, [ptr1 + 4] + ; UInt32 *_distances = ++d; + mov distances, d + + neg len0 + mov len1, len0 + + mov t0_x, cutValue_VAR + mov maxLen, maxLen_VAR + mov cutValueCur_VAR, t0_x + +MY_ALIGN_32 +tree_loop: + neg diff + mov len, len0 + cmp len1, len0 + cmovb len, len1 ; len = (len1 < len0 ? len1 : len0); + add diff, cur + + mov t0_x, [son + cp_r * 8] ; prefetch + movzx t0_x, BYTE PTR [diff + 1 * len] + lea cp_r, [son + cp_r * 8] + cmp [cur + 1 * len], t0_L + je matched_1 + + jb left_0 + + mov [ptr1], m + mov m, [cp_r + 4] + lea ptr1, [cp_r + 4] + sub diff, cur ; FIX32 + jmp next_node + +MY_ALIGN_32 +left_0: + mov [ptr0], m + mov m, [cp_r] + mov ptr0, cp_r + sub diff, cur ; FIX32 + ; jmp next_node + +; ------------ NEXT NODE ------------ +; MY_ALIGN_32 +next_node: + mov cycSize, cycSize_VAR + dec cutValueCur_VAR + je finish_tree + + add diff_x, pos ; prev_match = pos + diff + cmp m, diff_x + jae fin_error ; if (new_match >= prev_match) + + mov diff_x, pos + sub diff_x, m ; delta = pos - new_match + cmp pos, cycSize + jae cyc_mode_2 ; if (pos >= cycSize) + + mov cp_x, m + test m, m + jne tree_loop ; if (m != 0) + +finish_tree: + ; ptr0 = *ptr1 = kEmptyHashValue; + mov DWORD PTR [ptr0], 0 + mov DWORD PTR [ptr1], 0 + + inc pos + + ; _distances[-1] = (UInt32)(d - _distances); + mov t0, distances + mov t1, d + sub t1, t0 + shr t1_x, 2 + mov [t0 - 4], t1_x + + cmp d, limit_VAR + jae fin ; if (d >= limit) + + mov cp_x, cycPos_VAR + mov hash, hash_VAR + mov hash_lim, size_VAR + inc cp_x + cmp hash, hash_lim + jne main_loop ; if (hash != size) + jmp fin + + +MY_ALIGN_32 +cyc_mode_2: + cmp diff_x, cycSize + jae finish_tree ; if (delta >= cycSize) + + mov cp_x, cycPos_VAR + xor t0_x, t0_x + sub cp_x, diff_x ; cp_x = cycPos - delta + cmovb t0_x, cycSize + add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0) + jmp tree_loop + + +MY_ALIGN_32 +matched_1: + + inc len + ; cmp len_x, lenLimit_x + je short lenLimit_reach + movzx t0_x, BYTE PTR [diff + 1 * len] + cmp [cur + 1 * len], t0_L + jne mismatch + + +MY_ALIGN_32 +match_loop: + ; while (++len != lenLimit) (len[diff] != len[0]) ; + + inc len + ; cmp len_x, lenLimit_x + je short lenLimit_reach + movzx t0_x, BYTE PTR [diff + 1 * len] + cmp BYTE PTR [cur + 1 * len], t0_L + je match_loop + +mismatch: + jb left_2 + + mov [ptr1], m + mov m, [cp_r + 4] + lea ptr1, [cp_r + 4] + mov len1, len + + jmp max_update + +MY_ALIGN_32 +left_2: + mov [ptr0], m + mov m, [cp_r] + mov ptr0, cp_r + mov len0, len + +max_update: + sub diff, cur ; restore diff + + cmp maxLen, len + jae next_node + + mov maxLen, len + add len, lenLimit + mov [d], len_x + mov t0_x, diff_x + not t0_x + mov [d + 4], t0_x + add d, 8 + + jmp next_node + + + +MY_ALIGN_32 +lenLimit_reach: + + mov delta_r, cur + sub delta_r, diff + lea delta1_r, [delta_r - 1] + + mov t0_x, [cp_r] + mov [ptr1], t0_x + mov t0_x, [cp_r + 4] + mov [ptr0], t0_x + + mov [d], lenLimit_x + mov [d + 4], delta1_x + add d, 8 + + ; _distances[-1] = (UInt32)(d - _distances); + mov t0, distances + mov t1, d + sub t1, t0 + shr t1_x, 2 + mov [t0 - 4], t1_x + + mov hash, hash_VAR + mov hash_lim, size_VAR + + inc pos + mov cp_x, cycPos_VAR + inc cp_x + + mov d_lim, limit_VAR + mov cycSize, cycSize_VAR + ; if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit) + ; break; + cmp hash, hash_lim + je fin + cmp d, d_lim + jae fin + cmp delta_x, [hash] + jne main_loop + movzx t0_x, BYTE PTR [diff] + cmp [cur], t0_L + jne main_loop + + ; jmp main_loop ; bypass for debug + + mov cycPos_VAR, cp_x + shl len, 3 ; cycSize * 8 + sub diff, cur ; restore diff + xor t0_x, t0_x + cmp cp_x, delta_x ; cmp (cycPos_VAR, delta) + lea cp_r, [son + 8 * cp_r] ; dest + lea src, [cp_r + 8 * diff] + cmovb t0, len ; t0 = (cycPos_VAR < delta ? cycSize * 8 : 0) + add src, t0 + add len, son ; len = son + cycSize * 8 + + +MY_ALIGN_32 +long_loop: + add hash, 4 + + ; *(UInt64 *)(void *)ptr = ((const UInt64 *)(const void *)ptr)[diff]; + + mov t0, [src] + add src, 8 + mov [cp_r], t0 + add cp_r, 8 + cmp src, len + cmove src, son ; if end of (son) buffer is reached, we wrap to begin + + mov DWORD PTR [d], 2 + mov [d + 4], lenLimit_x + mov [d + 8], delta1_x + add d, 12 + + inc cur + + cmp hash, hash_lim + je long_footer + cmp delta_x, [hash] + jne long_footer + movzx t0_x, BYTE PTR [diff + 1 * cur] + cmp [cur], t0_L + jne long_footer + cmp d, d_lim + jb long_loop + +long_footer: + sub cp_r, son + shr cp_r, 3 + add pos, cp_x + sub pos, cycPos_VAR + mov cycSize, cycSize_VAR + + cmp d, d_lim + jae fin + cmp hash, hash_lim + jne main_loop + jmp fin + + + +fin_error: + xor d, d + +fin: + mov RSP, Old_RSP + mov t0, [r4 + posRes_OFFS] + mov [t0], pos + mov r0, d + +MY_POP_PRESERVED_ABI_REGS +MY_ENDP + +ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT +_TEXT$LZFINDOPT ENDS +endif + +end diff -Nru p7zip-rar-16.02/Asm/x86/LzmaDecOpt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/LzmaDecOpt.asm --- p7zip-rar-16.02/Asm/x86/LzmaDecOpt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/LzmaDecOpt.asm 2024-06-18 13:00:00.000000000 +0000 @@ -0,0 +1,1339 @@ +; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function +; 2024-06-18: Igor Pavlov : Public domain +; +; 3 - is the code compatibility version of LzmaDec_DecodeReal_*() +; function for check at link time. +; That code is tightly coupled with LzmaDec_TryDummy() +; and with another functions in LzmaDec.c file. +; CLzmaDec structure, (probs) array layout, input and output of +; LzmaDec_DecodeReal_*() must be equal in both versions (C / ASM). + +ifndef x64 +; x64=1 +; .err +endif + +include 7zAsm.asm + +MY_ASM_START + +; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is defined, we use additional SEGMENT with 64-byte alignment. +; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is not defined, we use default SEGMENT (where default 16-byte alignment of segment is expected). +; The performance is almost identical in our tests. +; But the performance can depend from position of lzmadec code inside instruction cache +; or micro-op cache line (depending from low address bits in 32-byte/64-byte cache lines). +; And 64-byte alignment provides a more consistent speed regardless +; of the code's position in the executable. +; But also it's possible that code without Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT can be +; slightly faster than 64-bytes aligned code in some cases, if offset of lzmadec +; code in 64-byte block after compilation provides better speed by some reason. +; Note that Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT adds an extra section to the ELF file. +; If you don't want to get that extra section, do not define Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT. + +ifndef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1 +else + Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1 +endif +endif + +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE' +MY_ALIGN macro num:req + align num + ; align 16 +endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside out function. + align 16 +endm +endif + + +MY_ALIGN_16 macro + MY_ALIGN 16 +endm + +MY_ALIGN_32 macro + MY_ALIGN 32 +endm + +MY_ALIGN_64 macro + MY_ALIGN 64 +endm + + +; _LZMA_SIZE_OPT equ 1 + +; _LZMA_PROB32 equ 1 + +ifdef _LZMA_PROB32 + PSHIFT equ 2 + PLOAD macro dest, mem + mov dest, dword ptr [mem] + endm + PSTORE macro src, mem + mov dword ptr [mem], src + endm +else + PSHIFT equ 1 + PLOAD macro dest, mem + movzx dest, word ptr [mem] + endm + PSTORE macro src, mem + mov word ptr [mem], @CatStr(src, _W) + endm +endif + +PMULT equ (1 SHL PSHIFT) +PMULT_HALF equ (1 SHL (PSHIFT - 1)) +PMULT_2 equ (1 SHL (PSHIFT + 1)) + +kMatchSpecLen_Error_Data equ (1 SHL 9) + +; x0 range +; x1 pbPos / (prob) TREE +; x2 probBranch / prm (MATCHED) / pbPos / cnt +; x3 sym +;====== r4 === RSP +; x5 cod +; x6 t1 NORM_CALC / probs_state / dist +; x7 t0 NORM_CALC / prob2 IF_BIT_1 +; x8 state +; x9 match (MATCHED) / sym2 / dist2 / lpMask_reg +; x10 kBitModelTotal_reg +; r11 probs +; x12 offs (MATCHED) / dic / len_temp +; x13 processedPos +; x14 bit (MATCHED) / dicPos +; r15 buf + + +cod equ x5 +cod_L equ x5_L +range equ x0 +state equ x8 +state_R equ r8 +buf equ r15 +processedPos equ x13 +kBitModelTotal_reg equ x10 + +probBranch equ x2 +probBranch_R equ r2 +probBranch_W equ x2_W + +pbPos equ x1 +pbPos_R equ r1 + +cnt equ x2 +cnt_R equ r2 + +lpMask_reg equ x9 +dicPos equ r14 + +sym equ x3 +sym_R equ r3 +sym_L equ x3_L + +probs equ r11 +dic equ r12 + +t0 equ x7 +t0_W equ x7_W +t0_R equ r7 + +prob2 equ t0 +prob2_W equ t0_W + +t1 equ x6 +t1_R equ r6 + +probs_state equ t1 +probs_state_R equ t1_R + +prm equ r2 +match equ x9 +match_R equ r9 +offs equ x12 +offs_R equ r12 +bit equ x14 +bit_R equ r14 + +sym2 equ x9 +sym2_R equ r9 + +len_temp equ x12 + +dist equ sym +dist2 equ x9 + + + +kNumBitModelTotalBits equ 11 +kBitModelTotal equ (1 SHL kNumBitModelTotalBits) +kNumMoveBits equ 5 +kBitModelOffset equ ((1 SHL kNumMoveBits) - 1) +kTopValue equ (1 SHL 24) + +NORM_2 macro + ; movzx t0, BYTE PTR [buf] + shl cod, 8 + mov cod_L, BYTE PTR [buf] + shl range, 8 + ; or cod, t0 + inc buf +endm + + +NORM macro + cmp range, kTopValue + jae SHORT @F + NORM_2 +@@: +endm + + +; ---------- Branch MACROS ---------- + +UPDATE_0 macro probsArray:req, probOffset:req, probDisp:req + mov prob2, kBitModelTotal_reg + sub prob2, probBranch + shr prob2, kNumMoveBits + add probBranch, prob2 + PSTORE probBranch, probOffset * 1 + probsArray + probDisp * PMULT +endm + + +UPDATE_1 macro probsArray:req, probOffset:req, probDisp:req + sub prob2, range + sub cod, range + mov range, prob2 + mov prob2, probBranch + shr probBranch, kNumMoveBits + sub prob2, probBranch + PSTORE prob2, probOffset * 1 + probsArray + probDisp * PMULT +endm + + +CMP_COD macro probsArray:req, probOffset:req, probDisp:req + PLOAD probBranch, probOffset * 1 + probsArray + probDisp * PMULT + NORM + mov prob2, range + shr range, kNumBitModelTotalBits + imul range, probBranch + cmp cod, range +endm + + +IF_BIT_1_NOUP macro probsArray:req, probOffset:req, probDisp:req, toLabel:req + CMP_COD probsArray, probOffset, probDisp + jae toLabel +endm + + +IF_BIT_1 macro probsArray:req, probOffset:req, probDisp:req, toLabel:req + IF_BIT_1_NOUP probsArray, probOffset, probDisp, toLabel + UPDATE_0 probsArray, probOffset, probDisp +endm + + +IF_BIT_0_NOUP macro probsArray:req, probOffset:req, probDisp:req, toLabel:req + CMP_COD probsArray, probOffset, probDisp + jb toLabel +endm + + +; ---------- CMOV MACROS ---------- + +NORM_CALC macro prob:req + NORM + mov t0, range + shr range, kNumBitModelTotalBits + imul range, prob + sub t0, range + mov t1, cod + sub cod, range +endm + + +PUP macro prob:req, probPtr:req + sub t0, prob + ; only sar works for both 16/32 bit prob modes + sar t0, kNumMoveBits + add t0, prob + PSTORE t0, probPtr +endm + + +PUP_SUB macro prob:req, probPtr:req, symSub:req + sbb sym, symSub + PUP prob, probPtr +endm + + +PUP_COD macro prob:req, probPtr:req, symSub:req + mov t0, kBitModelOffset + cmovb cod, t1 + mov t1, sym + cmovb t0, kBitModelTotal_reg + PUP_SUB prob, probPtr, symSub +endm + + +BIT_0 macro prob:req, probNext:req + PLOAD prob, probs + 1 * PMULT + PLOAD probNext, probs + 1 * PMULT_2 + + NORM_CALC prob + + cmovae range, t0 + PLOAD t0, probs + 1 * PMULT_2 + PMULT + cmovae probNext, t0 + mov t0, kBitModelOffset + cmovb cod, t1 + cmovb t0, kBitModelTotal_reg + mov sym, 2 + PUP_SUB prob, probs + 1 * PMULT, 0 - 1 +endm + + +BIT_1 macro prob:req, probNext:req + PLOAD probNext, probs + sym_R * PMULT_2 + add sym, sym + + NORM_CALC prob + + cmovae range, t0 + PLOAD t0, probs + sym_R * PMULT + PMULT + cmovae probNext, t0 + PUP_COD prob, probs + t1_R * PMULT_HALF, 0 - 1 +endm + + +BIT_2 macro prob:req, symSub:req + add sym, sym + + NORM_CALC prob + + cmovae range, t0 + PUP_COD prob, probs + t1_R * PMULT_HALF, symSub +endm + + +; ---------- MATCHED LITERAL ---------- + +LITM_0 macro + mov offs, 256 * PMULT + shl match, (PSHIFT + 1) + mov bit, offs + and bit, match + PLOAD x1, probs + 256 * PMULT + bit_R * 1 + 1 * PMULT + lea prm, [probs + 256 * PMULT + bit_R * 1 + 1 * PMULT] + ; lea prm, [probs + 256 * PMULT + 1 * PMULT] + ; add prm, bit_R + xor offs, bit + add match, match + + NORM_CALC x1 + + cmovae offs, bit + mov bit, match + cmovae range, t0 + mov t0, kBitModelOffset + cmovb cod, t1 + cmovb t0, kBitModelTotal_reg + mov sym, 0 + PUP_SUB x1, prm, -2-1 +endm + + +LITM macro + and bit, offs + lea prm, [probs + offs_R * 1] + add prm, bit_R + PLOAD x1, prm + sym_R * PMULT + xor offs, bit + add sym, sym + add match, match + + NORM_CALC x1 + + cmovae offs, bit + mov bit, match + cmovae range, t0 + PUP_COD x1, prm + t1_R * PMULT_HALF, - 1 +endm + + +LITM_2 macro + and bit, offs + lea prm, [probs + offs_R * 1] + add prm, bit_R + PLOAD x1, prm + sym_R * PMULT + add sym, sym + + NORM_CALC x1 + + cmovae range, t0 + PUP_COD x1, prm + t1_R * PMULT_HALF, 256 - 1 +endm + + +; ---------- REVERSE BITS ---------- + +REV_0 macro prob:req, probNext:req + ; PLOAD prob, probs + 1 * PMULT + ; lea sym2_R, [probs + 2 * PMULT] + ; PLOAD probNext, probs + 2 * PMULT + PLOAD probNext, sym2_R + + NORM_CALC prob + + cmovae range, t0 + PLOAD t0, probs + 3 * PMULT + cmovae probNext, t0 + cmovb cod, t1 + mov t0, kBitModelOffset + cmovb t0, kBitModelTotal_reg + lea t1_R, [probs + 3 * PMULT] + cmovae sym2_R, t1_R + PUP prob, probs + 1 * PMULT +endm + + +REV_1 macro prob:req, probNext:req, step:req + add sym2_R, step * PMULT + PLOAD probNext, sym2_R + + NORM_CALC prob + + cmovae range, t0 + PLOAD t0, sym2_R + step * PMULT + cmovae probNext, t0 + cmovb cod, t1 + mov t0, kBitModelOffset + cmovb t0, kBitModelTotal_reg + lea t1_R, [sym2_R + step * PMULT] + cmovae sym2_R, t1_R + PUP prob, t1_R - step * PMULT_2 +endm + + +REV_2 macro prob:req, step:req + sub sym2_R, probs + shr sym2, PSHIFT + or sym, sym2 + + NORM_CALC prob + + cmovae range, t0 + lea t0, [sym - step] + cmovb sym, t0 + cmovb cod, t1 + mov t0, kBitModelOffset + cmovb t0, kBitModelTotal_reg + PUP prob, probs + sym2_R * PMULT +endm + + +REV_1_VAR macro prob:req + PLOAD prob, sym_R + mov probs, sym_R + add sym_R, sym2_R + + NORM_CALC prob + + cmovae range, t0 + lea t0_R, [sym_R + 1 * sym2_R] + cmovae sym_R, t0_R + mov t0, kBitModelOffset + cmovb cod, t1 + ; mov t1, kBitModelTotal + ; cmovb t0, t1 + cmovb t0, kBitModelTotal_reg + add sym2, sym2 + PUP prob, probs +endm + + + + +LIT_PROBS macro lpMaskParam:req + ; prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); + mov t0, processedPos + shl t0, 8 + add sym, t0 + and sym, lpMaskParam + add probs_state_R, pbPos_R + mov x1, LOC lc2 + lea sym, dword ptr[sym_R + 2 * sym_R] + add probs, Literal * PMULT + shl sym, x1_L + add probs, sym_R + UPDATE_0 probs_state_R, 0, IsMatch + inc processedPos +endm + + + +kNumPosBitsMax equ 4 +kNumPosStatesMax equ (1 SHL kNumPosBitsMax) + +kLenNumLowBits equ 3 +kLenNumLowSymbols equ (1 SHL kLenNumLowBits) +kLenNumHighBits equ 8 +kLenNumHighSymbols equ (1 SHL kLenNumHighBits) +kNumLenProbs equ (2 * kLenNumLowSymbols * kNumPosStatesMax + kLenNumHighSymbols) + +LenLow equ 0 +LenChoice equ LenLow +LenChoice2 equ (LenLow + kLenNumLowSymbols) +LenHigh equ (LenLow + 2 * kLenNumLowSymbols * kNumPosStatesMax) + +kNumStates equ 12 +kNumStates2 equ 16 +kNumLitStates equ 7 + +kStartPosModelIndex equ 4 +kEndPosModelIndex equ 14 +kNumFullDistances equ (1 SHL (kEndPosModelIndex SHR 1)) + +kNumPosSlotBits equ 6 +kNumLenToPosStates equ 4 + +kNumAlignBits equ 4 +kAlignTableSize equ (1 SHL kNumAlignBits) + +kMatchMinLen equ 2 +kMatchSpecLenStart equ (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +kStartOffset equ 1664 +SpecPos equ (-kStartOffset) +IsRep0Long equ (SpecPos + kNumFullDistances) +RepLenCoder equ (IsRep0Long + (kNumStates2 SHL kNumPosBitsMax)) +LenCoder equ (RepLenCoder + kNumLenProbs) +IsMatch equ (LenCoder + kNumLenProbs) +kAlign equ (IsMatch + (kNumStates2 SHL kNumPosBitsMax)) +IsRep equ (kAlign + kAlignTableSize) +IsRepG0 equ (IsRep + kNumStates) +IsRepG1 equ (IsRepG0 + kNumStates) +IsRepG2 equ (IsRepG1 + kNumStates) +PosSlot equ (IsRepG2 + kNumStates) +Literal equ (PosSlot + (kNumLenToPosStates SHL kNumPosSlotBits)) +NUM_BASE_PROBS equ (Literal + kStartOffset) + +if kAlign ne 0 + .err +endif + +if NUM_BASE_PROBS ne 1984 + .err +endif + + +PTR_FIELD equ dq ? + +CLzmaDec_Asm struct + lc db ? + lp db ? + pb db ? + _pad_ db ? + dicSize dd ? + + probs_Spec PTR_FIELD + probs_1664 PTR_FIELD + dic_Spec PTR_FIELD + dicBufSize PTR_FIELD + dicPos_Spec PTR_FIELD + buf_Spec PTR_FIELD + + range_Spec dd ? + code_Spec dd ? + processedPos_Spec dd ? + checkDicSize dd ? + rep0 dd ? + rep1 dd ? + rep2 dd ? + rep3 dd ? + state_Spec dd ? + remainLen dd ? +CLzmaDec_Asm ends + + +CLzmaDec_Asm_Loc struct + OLD_RSP PTR_FIELD + lzmaPtr PTR_FIELD + _pad0_ PTR_FIELD + _pad1_ PTR_FIELD + _pad2_ PTR_FIELD + dicBufSize PTR_FIELD + probs_Spec PTR_FIELD + dic_Spec PTR_FIELD + + limit PTR_FIELD + bufLimit PTR_FIELD + lc2 dd ? + lpMask dd ? + pbMask dd ? + checkDicSize dd ? + + _pad_ dd ? + remainLen dd ? + dicPos_Spec PTR_FIELD + rep0 dd ? + rep1 dd ? + rep2 dd ? + rep3 dd ? +CLzmaDec_Asm_Loc ends + + +GLOB_2 equ [sym_R].CLzmaDec_Asm. +GLOB equ [r1].CLzmaDec_Asm. +LOC_0 equ [r0].CLzmaDec_Asm_Loc. +LOC equ [RSP].CLzmaDec_Asm_Loc. + + +COPY_VAR macro name + mov t0, GLOB_2 name + mov LOC_0 name, t0 +endm + + +RESTORE_VAR macro name + mov t0, LOC name + mov GLOB name, t0 +endm + + + +IsMatchBranch_Pre macro reg + ; prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + mov pbPos, LOC pbMask + and pbPos, processedPos + shl pbPos, (kLenNumLowBits + 1 + PSHIFT) + lea probs_state_R, [probs + 1 * state_R] +endm + + +IsMatchBranch macro reg + IsMatchBranch_Pre + IF_BIT_1 probs_state_R, pbPos_R, IsMatch, IsMatch_label +endm + + +CheckLimits macro reg + cmp buf, LOC bufLimit + jae fin_OK + cmp dicPos, LOC limit + jae fin_OK +endm + + + +; RSP is (16x + 8) bytes aligned in WIN64-x64 +; LocalSize equ ((((SIZEOF CLzmaDec_Asm_Loc) + 7) / 16 * 16) + 8) + +PARAM_lzma equ REG_ABI_PARAM_0 +PARAM_limit equ REG_ABI_PARAM_1 +PARAM_bufLimit equ REG_ABI_PARAM_2 + +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif +MY_PROC LzmaDec_DecodeReal_3, 3 +MY_PUSH_PRESERVED_ABI_REGS + + lea r0, [RSP - (SIZEOF CLzmaDec_Asm_Loc)] + and r0, -128 + mov r5, RSP + mov RSP, r0 + mov LOC_0 Old_RSP, r5 + mov LOC_0 lzmaPtr, PARAM_lzma + + mov LOC_0 remainLen, 0 ; remainLen must be ZERO + + mov LOC_0 bufLimit, PARAM_bufLimit + mov sym_R, PARAM_lzma ; CLzmaDec_Asm_Loc pointer for GLOB_2 + mov dic, GLOB_2 dic_Spec + add PARAM_limit, dic + mov LOC_0 limit, PARAM_limit + + COPY_VAR(rep0) + COPY_VAR(rep1) + COPY_VAR(rep2) + COPY_VAR(rep3) + + mov dicPos, GLOB_2 dicPos_Spec + add dicPos, dic + mov LOC_0 dicPos_Spec, dicPos + mov LOC_0 dic_Spec, dic + + mov x1_L, GLOB_2 pb + mov t0, 1 + shl t0, x1_L + dec t0 + mov LOC_0 pbMask, t0 + + ; unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + ; unsigned lc = p->prop.lc; + ; unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); + + mov x1_L, GLOB_2 lc + mov x2, 100h + mov t0, x2 + shr x2, x1_L + ; inc x1 + add x1_L, PSHIFT + mov LOC_0 lc2, x1 + mov x1_L, GLOB_2 lp + shl t0, x1_L + sub t0, x2 + mov LOC_0 lpMask, t0 + mov lpMask_reg, t0 + + ; mov probs, GLOB_2 probs_Spec + ; add probs, kStartOffset SHL PSHIFT + mov probs, GLOB_2 probs_1664 + mov LOC_0 probs_Spec, probs + + mov t0_R, GLOB_2 dicBufSize + mov LOC_0 dicBufSize, t0_R + + mov x1, GLOB_2 checkDicSize + mov LOC_0 checkDicSize, x1 + + mov processedPos, GLOB_2 processedPos_Spec + + mov state, GLOB_2 state_Spec + shl state, PSHIFT + + mov buf, GLOB_2 buf_Spec + mov range, GLOB_2 range_Spec + mov cod, GLOB_2 code_Spec + mov kBitModelTotal_reg, kBitModelTotal + xor sym, sym + + ; if (processedPos != 0 || checkDicSize != 0) + or x1, processedPos + jz @f + + add t0_R, dic + cmp dicPos, dic + cmovnz t0_R, dicPos + movzx sym, byte ptr[t0_R - 1] + +@@: + IsMatchBranch_Pre + cmp state, 4 * PMULT + jb lit_end + cmp state, kNumLitStates * PMULT + jb lit_matched_end + jmp lz_end + + + + +; ---------- LITERAL ---------- +MY_ALIGN_64 +lit_start: + xor state, state +lit_start_2: + LIT_PROBS lpMask_reg + + ifdef _LZMA_SIZE_OPT + + PLOAD x1, probs + 1 * PMULT + mov sym, 1 +MY_ALIGN_16 +lit_loop: + BIT_1 x1, x2 + mov x1, x2 + cmp sym, 127 + jbe lit_loop + + else + + BIT_0 x1, x2 + BIT_1 x2, x1 + BIT_1 x1, x2 + BIT_1 x2, x1 + BIT_1 x1, x2 + BIT_1 x2, x1 + BIT_1 x1, x2 + + endif + + BIT_2 x2, 256 - 1 + + ; mov dic, LOC dic_Spec + mov probs, LOC probs_Spec + IsMatchBranch_Pre + mov byte ptr[dicPos], sym_L + inc dicPos + + CheckLimits +lit_end: + IF_BIT_0_NOUP probs_state_R, pbPos_R, IsMatch, lit_start + + ; jmp IsMatch_label + +; ---------- MATCHES ---------- +; MY_ALIGN_32 +IsMatch_label: + UPDATE_1 probs_state_R, pbPos_R, IsMatch + IF_BIT_1 probs_state_R, 0, IsRep, IsRep_label + + add probs, LenCoder * PMULT + add state, kNumStates * PMULT + +; ---------- LEN DECODE ---------- +len_decode: + mov len_temp, 8 - 1 - kMatchMinLen + IF_BIT_0_NOUP probs, 0, 0, len_mid_0 + UPDATE_1 probs, 0, 0 + add probs, (1 SHL (kLenNumLowBits + PSHIFT)) + mov len_temp, -1 - kMatchMinLen + IF_BIT_0_NOUP probs, 0, 0, len_mid_0 + UPDATE_1 probs, 0, 0 + add probs, LenHigh * PMULT - (1 SHL (kLenNumLowBits + PSHIFT)) + mov sym, 1 + PLOAD x1, probs + 1 * PMULT + +MY_ALIGN_32 +len8_loop: + BIT_1 x1, x2 + mov x1, x2 + cmp sym, 64 + jb len8_loop + + mov len_temp, (kLenNumHighSymbols - kLenNumLowSymbols * 2) - 1 - kMatchMinLen + jmp short len_mid_2 ; we use short here for MASM that doesn't optimize that code as another assembler programs + +MY_ALIGN_32 +len_mid_0: + UPDATE_0 probs, 0, 0 + add probs, pbPos_R + BIT_0 x2, x1 +len_mid_2: + BIT_1 x1, x2 + BIT_2 x2, len_temp + mov probs, LOC probs_Spec + cmp state, kNumStates * PMULT + jb copy_match + + +; ---------- DECODE DISTANCE ---------- + ; probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + + mov t0, 3 + kMatchMinLen + cmp sym, 3 + kMatchMinLen + cmovb t0, sym + add probs, PosSlot * PMULT - (kMatchMinLen SHL (kNumPosSlotBits + PSHIFT)) + shl t0, (kNumPosSlotBits + PSHIFT) + add probs, t0_R + + ; sym = Len + ; mov LOC remainLen, sym + mov len_temp, sym + + ifdef _LZMA_SIZE_OPT + + PLOAD x1, probs + 1 * PMULT + mov sym, 1 +MY_ALIGN_16 +slot_loop: + BIT_1 x1, x2 + mov x1, x2 + cmp sym, 32 + jb slot_loop + + else + + BIT_0 x1, x2 + BIT_1 x2, x1 + BIT_1 x1, x2 + BIT_1 x2, x1 + BIT_1 x1, x2 + + endif + + mov x1, sym + BIT_2 x2, 64-1 + + and sym, 3 + mov probs, LOC probs_Spec + cmp x1, 32 + kEndPosModelIndex / 2 + jb short_dist + + ; unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + sub x1, (32 + 1 + kNumAlignBits) + ; distance = (2 | (distance & 1)); + or sym, 2 + PLOAD x2, probs + 1 * PMULT + shl sym, kNumAlignBits + 1 + lea sym2_R, [probs + 2 * PMULT] + + jmp direct_norm + ; lea t1, [sym_R + (1 SHL kNumAlignBits)] + ; cmp range, kTopValue + ; jb direct_norm + +; ---------- DIRECT DISTANCE ---------- +MY_ALIGN_32 +direct_loop: + shr range, 1 + mov t0, cod + sub cod, range + cmovs cod, t0 + cmovns sym, t1 + + comment ~ + sub cod, range + mov x2, cod + sar x2, 31 + lea sym, dword ptr [r2 + sym_R * 2 + 1] + and x2, range + add cod, x2 + ~ + dec x1 + je direct_end + + add sym, sym +direct_norm: + lea t1, [sym_R + (1 SHL kNumAlignBits)] + cmp range, kTopValue + jae near ptr direct_loop + ; we align for 32 here with "near ptr" command above + NORM_2 + jmp direct_loop + +MY_ALIGN_32 +direct_end: + ; prob = + kAlign; + ; distance <<= kNumAlignBits; + REV_0 x2, x1 + REV_1 x1, x2, 2 + REV_1 x2, x1, 4 + REV_2 x1, 8 + +decode_dist_end: + + ; if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) + + mov t1, LOC rep0 + mov x1, LOC rep1 + mov x2, LOC rep2 + + mov t0, LOC checkDicSize + test t0, t0 + cmove t0, processedPos + cmp sym, t0 + jae end_of_payload + ; jmp end_of_payload ; for debug + + ; rep3 = rep2; + ; rep2 = rep1; + ; rep1 = rep0; + ; rep0 = distance + 1; + + inc sym + mov LOC rep0, sym + ; mov sym, LOC remainLen + mov sym, len_temp + mov LOC rep1, t1 + mov LOC rep2, x1 + mov LOC rep3, x2 + + ; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + cmp state, (kNumStates + kNumLitStates) * PMULT + mov state, kNumLitStates * PMULT + mov t0, (kNumLitStates + 3) * PMULT + cmovae state, t0 + + +; ---------- COPY MATCH ---------- +copy_match: + + ; len += kMatchMinLen; + ; add sym, kMatchMinLen + + ; if ((rem = limit - dicPos) == 0) + ; { + ; p->dicPos = dicPos; + ; return SZ_ERROR_DATA; + ; } + mov cnt_R, LOC limit + sub cnt_R, dicPos + jz fin_dicPos_LIMIT + + ; curLen = ((rem < len) ? (unsigned)rem : len); + cmp cnt_R, sym_R + ; cmovae cnt_R, sym_R ; 64-bit + cmovae cnt, sym ; 32-bit + + mov dic, LOC dic_Spec + mov x1, LOC rep0 + + mov t0_R, dicPos + add dicPos, cnt_R + ; processedPos += curLen; + add processedPos, cnt + ; len -= curLen; + sub sym, cnt + mov LOC remainLen, sym + + sub t0_R, dic + + ; pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + sub t0_R, r1 + jae @f + + mov r1, LOC dicBufSize + add t0_R, r1 + sub r1, t0_R + cmp cnt_R, r1 + ja copy_match_cross +@@: + ; if (curLen <= dicBufSize - pos) + +; ---------- COPY MATCH FAST ---------- + ; Byte *dest = dic + dicPos; + ; mov r1, dic + ; ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + ; sub t0_R, dicPos + ; dicPos += curLen; + + ; const Byte *lim = dest + curLen; + add t0_R, dic + movzx sym, byte ptr[t0_R] + add t0_R, cnt_R + neg cnt_R + ; lea r1, [dicPos - 1] +copy_common: + dec dicPos + ; cmp LOC rep0, 1 + ; je rep0Label + + ; t0_R - src_lim + ; r1 - dest_lim - 1 + ; cnt_R - (-cnt) + + IsMatchBranch_Pre + inc cnt_R + jz copy_end +MY_ALIGN_16 +@@: + mov byte ptr[cnt_R * 1 + dicPos], sym_L + movzx sym, byte ptr[cnt_R * 1 + t0_R] + inc cnt_R + jnz @b + +copy_end: +lz_end_match: + mov byte ptr[dicPos], sym_L + inc dicPos + + ; IsMatchBranch_Pre + CheckLimits +lz_end: + IF_BIT_1_NOUP probs_state_R, pbPos_R, IsMatch, IsMatch_label + + + +; ---------- LITERAL MATCHED ---------- + + LIT_PROBS LOC lpMask + + ; matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + mov x1, LOC rep0 + ; mov dic, LOC dic_Spec + mov LOC dicPos_Spec, dicPos + + ; state -= (state < 10) ? 3 : 6; + lea t0, [state_R - 6 * PMULT] + sub state, 3 * PMULT + cmp state, 7 * PMULT + cmovae state, t0 + + sub dicPos, dic + sub dicPos, r1 + jae @f + add dicPos, LOC dicBufSize +@@: + comment ~ + xor t0, t0 + sub dicPos, r1 + cmovb t0_R, LOC dicBufSize + ~ + + movzx match, byte ptr[dic + dicPos * 1] + + ifdef _LZMA_SIZE_OPT + + mov offs, 256 * PMULT + shl match, (PSHIFT + 1) + mov bit, match + mov sym, 1 +MY_ALIGN_16 +litm_loop: + LITM + cmp sym, 256 + jb litm_loop + sub sym, 256 + + else + + LITM_0 + LITM + LITM + LITM + LITM + LITM + LITM + LITM_2 + + endif + + mov probs, LOC probs_Spec + IsMatchBranch_Pre + ; mov dic, LOC dic_Spec + mov dicPos, LOC dicPos_Spec + mov byte ptr[dicPos], sym_L + inc dicPos + + CheckLimits +lit_matched_end: + IF_BIT_1_NOUP probs_state_R, pbPos_R, IsMatch, IsMatch_label + ; IsMatchBranch + mov lpMask_reg, LOC lpMask + sub state, 3 * PMULT + jmp lit_start_2 + + + +; ---------- REP 0 LITERAL ---------- +MY_ALIGN_32 +IsRep0Short_label: + UPDATE_0 probs_state_R, pbPos_R, IsRep0Long + + ; dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + mov dic, LOC dic_Spec + mov t0_R, dicPos + mov probBranch, LOC rep0 + sub t0_R, dic + + sub probs, RepLenCoder * PMULT + + ; state = state < kNumLitStates ? 9 : 11; + or state, 1 * PMULT + + ; the caller doesn't allow (dicPos >= limit) case for REP_SHORT + ; so we don't need the following (dicPos == limit) check here: + ; cmp dicPos, LOC limit + ; jae fin_dicPos_LIMIT_REP_SHORT + + inc processedPos + + IsMatchBranch_Pre + +; xor sym, sym +; sub t0_R, probBranch_R +; cmovb sym_R, LOC dicBufSize +; add t0_R, sym_R + sub t0_R, probBranch_R + jae @f + add t0_R, LOC dicBufSize +@@: + movzx sym, byte ptr[dic + t0_R * 1] + jmp lz_end_match + + +MY_ALIGN_32 +IsRep_label: + UPDATE_1 probs_state_R, 0, IsRep + + ; The (checkDicSize == 0 && processedPos == 0) case was checked before in LzmaDec.c with kBadRepCode. + ; So we don't check it here. + + ; mov t0, processedPos + ; or t0, LOC checkDicSize + ; jz fin_ERROR_2 + + ; state = state < kNumLitStates ? 8 : 11; + cmp state, kNumLitStates * PMULT + mov state, 8 * PMULT + mov probBranch, 11 * PMULT + cmovae state, probBranch + + ; prob = probs + RepLenCoder; + add probs, RepLenCoder * PMULT + + IF_BIT_1 probs_state_R, 0, IsRepG0, IsRepG0_label + IF_BIT_0_NOUP probs_state_R, pbPos_R, IsRep0Long, IsRep0Short_label + UPDATE_1 probs_state_R, pbPos_R, IsRep0Long + jmp len_decode + +MY_ALIGN_32 +IsRepG0_label: + UPDATE_1 probs_state_R, 0, IsRepG0 + mov dist2, LOC rep0 + mov dist, LOC rep1 + mov LOC rep1, dist2 + + IF_BIT_1 probs_state_R, 0, IsRepG1, IsRepG1_label + mov LOC rep0, dist + jmp len_decode + +; MY_ALIGN_32 +IsRepG1_label: + UPDATE_1 probs_state_R, 0, IsRepG1 + mov dist2, LOC rep2 + mov LOC rep2, dist + + IF_BIT_1 probs_state_R, 0, IsRepG2, IsRepG2_label + mov LOC rep0, dist2 + jmp len_decode + +; MY_ALIGN_32 +IsRepG2_label: + UPDATE_1 probs_state_R, 0, IsRepG2 + mov dist, LOC rep3 + mov LOC rep3, dist2 + mov LOC rep0, dist + jmp len_decode + + + +; ---------- SPEC SHORT DISTANCE ---------- + +MY_ALIGN_32 +short_dist: + sub x1, 32 + 1 + jbe decode_dist_end + or sym, 2 + shl sym, x1_L + lea sym_R, [probs + sym_R * PMULT + SpecPos * PMULT + 1 * PMULT] + mov sym2, PMULT ; step +MY_ALIGN_32 +spec_loop: + REV_1_VAR x2 + dec x1 + jnz spec_loop + + mov probs, LOC probs_Spec + sub sym, sym2 + sub sym, SpecPos * PMULT + sub sym_R, probs + shr sym, PSHIFT + + jmp decode_dist_end + + +; ---------- COPY MATCH CROSS ---------- +copy_match_cross: + ; t0_R - src pos + ; r1 - len to dicBufSize + ; cnt_R - total copy len + + mov t1_R, t0_R ; srcPos + mov t0_R, dic + mov r1, LOC dicBufSize ; + neg cnt_R +@@: + movzx sym, byte ptr[t1_R * 1 + t0_R] + inc t1_R + mov byte ptr[cnt_R * 1 + dicPos], sym_L + inc cnt_R + cmp t1_R, r1 + jne @b + + movzx sym, byte ptr[t0_R] + sub t0_R, cnt_R + jmp copy_common + + + + +; fin_dicPos_LIMIT_REP_SHORT: + ; mov sym, 1 + +fin_dicPos_LIMIT: + mov LOC remainLen, sym + jmp fin_OK + ; For more strict mode we can stop decoding with error + ; mov sym, 1 + ; jmp fin + + +fin_ERROR_MATCH_DIST: + + ; rep3 = rep2; + ; rep2 = rep1; + ; rep1 = rep0; + ; rep0 = distance + 1; + + add len_temp, kMatchSpecLen_Error_Data + mov LOC remainLen, len_temp + + mov LOC rep0, sym + mov LOC rep1, t1 + mov LOC rep2, x1 + mov LOC rep3, x2 + + ; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + cmp state, (kNumStates + kNumLitStates) * PMULT + mov state, kNumLitStates * PMULT + mov t0, (kNumLitStates + 3) * PMULT + cmovae state, t0 + + ; jmp fin_OK + mov sym, 1 + jmp fin + +end_of_payload: + inc sym + jnz fin_ERROR_MATCH_DIST + + mov LOC remainLen, kMatchSpecLenStart + sub state, kNumStates * PMULT + +fin_OK: + xor sym, sym + +fin: + NORM + + mov r1, LOC lzmaPtr + + sub dicPos, LOC dic_Spec + mov GLOB dicPos_Spec, dicPos + mov GLOB buf_Spec, buf + mov GLOB range_Spec, range + mov GLOB code_Spec, cod + shr state, PSHIFT + mov GLOB state_Spec, state + mov GLOB processedPos_Spec, processedPos + + RESTORE_VAR(remainLen) + RESTORE_VAR(rep0) + RESTORE_VAR(rep1) + RESTORE_VAR(rep2) + RESTORE_VAR(rep3) + + mov x0, sym + + mov RSP, LOC Old_RSP + +MY_POP_PRESERVED_ABI_REGS +MY_ENDP + +ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT +_TEXT$LZMADECOPT ENDS +endif + +end diff -Nru p7zip-rar-16.02/Asm/x86/Sha1Opt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha1Opt.asm --- p7zip-rar-16.02/Asm/x86/Sha1Opt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha1Opt.asm 2024-06-16 08:00:00.000000000 +0000 @@ -0,0 +1,263 @@ +; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions +; 2024-06-16 : Igor Pavlov : Public domain + +include 7zAsm.asm + +MY_ASM_START + + + + + + + + + + + + + + + + +CONST SEGMENT READONLY + +align 16 +Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0 + + + + + + + + + + + + + + + + + + + + + + +CONST ENDS + +; _TEXT$SHA1OPT SEGMENT 'CODE' + +ifndef x64 + .686 + .xmm +endif + +ifdef x64 + rNum equ REG_ABI_PARAM_2 + if (IS_LINUX eq 0) + LOCAL_SIZE equ (16 * 2) + endif +else + rNum equ r0 + LOCAL_SIZE equ (16 * 1) +endif + +rState equ REG_ABI_PARAM_0 +rData equ REG_ABI_PARAM_1 + + +MY_sha1rnds4 macro a1, a2, imm + db 0fH, 03aH, 0ccH, (0c0H + a1 * 8 + a2), imm +endm + +MY_SHA_INSTR macro cmd, a1, a2 + db 0fH, 038H, cmd, (0c0H + a1 * 8 + a2) +endm + +cmd_sha1nexte equ 0c8H +cmd_sha1msg1 equ 0c9H +cmd_sha1msg2 equ 0caH + +MY_sha1nexte macro a1, a2 + MY_SHA_INSTR cmd_sha1nexte, a1, a2 +endm + +MY_sha1msg1 macro a1, a2 + MY_SHA_INSTR cmd_sha1msg1, a1, a2 +endm + +MY_sha1msg2 macro a1, a2 + MY_SHA_INSTR cmd_sha1msg2, a1, a2 +endm + +MY_PROLOG macro + ifdef x64 + if (IS_LINUX eq 0) + movdqa [r4 + 8], xmm6 + movdqa [r4 + 8 + 16], xmm7 + sub r4, LOCAL_SIZE + 8 + movdqa [r4 ], xmm8 + movdqa [r4 + 16], xmm9 + endif + else ; x86 + if (IS_CDECL gt 0) + mov rState, [r4 + REG_SIZE * 1] + mov rData, [r4 + REG_SIZE * 2] + mov rNum, [r4 + REG_SIZE * 3] + else ; fastcall + mov rNum, [r4 + REG_SIZE * 1] + endif + push r5 + mov r5, r4 + and r4, -16 + sub r4, LOCAL_SIZE + endif +endm + +MY_EPILOG macro + ifdef x64 + if (IS_LINUX eq 0) + movdqa xmm8, [r4] + movdqa xmm9, [r4 + 16] + add r4, LOCAL_SIZE + 8 + movdqa xmm6, [r4 + 8] + movdqa xmm7, [r4 + 8 + 16] + endif + else ; x86 + mov r4, r5 + pop r5 + endif + MY_ENDP +endm + + +e0_N equ 0 +e1_N equ 1 +abcd_N equ 2 +e0_save_N equ 3 +w_regs equ 4 + +e0 equ @CatStr(xmm, %e0_N) +e1 equ @CatStr(xmm, %e1_N) +abcd equ @CatStr(xmm, %abcd_N) +e0_save equ @CatStr(xmm, %e0_save_N) + + +ifdef x64 + abcd_save equ xmm8 + mask2 equ xmm9 +else + abcd_save equ [r4] + mask2 equ e1 +endif + +LOAD_MASK macro + movdqa mask2, XMMWORD PTR Reverse_Endian_Mask +endm + +LOAD_W macro k:req + movdqu @CatStr(xmm, %(w_regs + k)), [rData + (16 * (k))] + pshufb @CatStr(xmm, %(w_regs + k)), mask2 +endm + + +; pre2 can be 2 or 3 (recommended) +pre2 equ 3 +pre1 equ (pre2 + 1) + +NUM_ROUNDS4 equ 20 + +RND4 macro k + movdqa @CatStr(xmm, %(e0_N + ((k + 1) mod 2))), abcd + MY_sha1rnds4 abcd_N, (e0_N + (k mod 2)), k / 5 + + nextM = (w_regs + ((k + 1) mod 4)) + + if (k EQ NUM_ROUNDS4 - 1) + nextM = e0_save_N + endif + + MY_sha1nexte (e0_N + ((k + 1) mod 2)), nextM + + if (k GE (4 - pre2)) AND (k LT (NUM_ROUNDS4 - pre2)) + pxor @CatStr(xmm, %(w_regs + ((k + pre2) mod 4))), @CatStr(xmm, %(w_regs + ((k + pre2 - 2) mod 4))) + endif + + if (k GE (4 - pre1)) AND (k LT (NUM_ROUNDS4 - pre1)) + MY_sha1msg1 (w_regs + ((k + pre1) mod 4)), (w_regs + ((k + pre1 - 3) mod 4)) + endif + + if (k GE (4 - pre2)) AND (k LT (NUM_ROUNDS4 - pre2)) + MY_sha1msg2 (w_regs + ((k + pre2) mod 4)), (w_regs + ((k + pre2 - 1) mod 4)) + endif +endm + + +REVERSE_STATE macro + ; abcd ; dcba + ; e0 ; 000e + pshufd abcd, abcd, 01bH ; abcd + pshufd e0, e0, 01bH ; e000 +endm + + + + + +MY_PROC Sha1_UpdateBlocks_HW, 3 + MY_PROLOG + + cmp rNum, 0 + je end_c + + movdqu abcd, [rState] ; dcba + movd e0, dword ptr [rState + 16] ; 000e + + REVERSE_STATE + + ifdef x64 + LOAD_MASK + endif + + align 16 + nextBlock: + movdqa abcd_save, abcd + movdqa e0_save, e0 + + ifndef x64 + LOAD_MASK + endif + + LOAD_W 0 + LOAD_W 1 + LOAD_W 2 + LOAD_W 3 + + paddd e0, @CatStr(xmm, %(w_regs)) + k = 0 + rept NUM_ROUNDS4 + RND4 k + k = k + 1 + endm + + paddd abcd, abcd_save + + + add rData, 64 + sub rNum, 1 + jnz nextBlock + + REVERSE_STATE + + movdqu [rState], abcd + movd dword ptr [rState + 16], e0 + + end_c: +MY_EPILOG + +; _TEXT$SHA1OPT ENDS + +end diff -Nru p7zip-rar-16.02/Asm/x86/Sha256Opt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha256Opt.asm --- p7zip-rar-16.02/Asm/x86/Sha256Opt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/Sha256Opt.asm 2024-06-16 08:00:00.000000000 +0000 @@ -0,0 +1,275 @@ +; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions +; 2024-06-16 : Igor Pavlov : Public domain + +include 7zAsm.asm + +MY_ASM_START + +; .data +; public K + +; we can use external SHA256_K_ARRAY defined in Sha256.c +; but we must guarantee that SHA256_K_ARRAY is aligned for 16-bytes + +COMMENT @ +ifdef x64 +K_CONST equ SHA256_K_ARRAY +else +K_CONST equ _SHA256_K_ARRAY +endif +EXTRN K_CONST:xmmword +@ + +CONST SEGMENT READONLY + +align 16 +Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +; COMMENT @ +align 16 +K_CONST \ +DD 0428a2f98H, 071374491H, 0b5c0fbcfH, 0e9b5dba5H +DD 03956c25bH, 059f111f1H, 0923f82a4H, 0ab1c5ed5H +DD 0d807aa98H, 012835b01H, 0243185beH, 0550c7dc3H +DD 072be5d74H, 080deb1feH, 09bdc06a7H, 0c19bf174H +DD 0e49b69c1H, 0efbe4786H, 00fc19dc6H, 0240ca1ccH +DD 02de92c6fH, 04a7484aaH, 05cb0a9dcH, 076f988daH +DD 0983e5152H, 0a831c66dH, 0b00327c8H, 0bf597fc7H +DD 0c6e00bf3H, 0d5a79147H, 006ca6351H, 014292967H +DD 027b70a85H, 02e1b2138H, 04d2c6dfcH, 053380d13H +DD 0650a7354H, 0766a0abbH, 081c2c92eH, 092722c85H +DD 0a2bfe8a1H, 0a81a664bH, 0c24b8b70H, 0c76c51a3H +DD 0d192e819H, 0d6990624H, 0f40e3585H, 0106aa070H +DD 019a4c116H, 01e376c08H, 02748774cH, 034b0bcb5H +DD 0391c0cb3H, 04ed8aa4aH, 05b9cca4fH, 0682e6ff3H +DD 0748f82eeH, 078a5636fH, 084c87814H, 08cc70208H +DD 090befffaH, 0a4506cebH, 0bef9a3f7H, 0c67178f2H +; @ + +CONST ENDS + +; _TEXT$SHA256OPT SEGMENT 'CODE' + +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 r3 + LOCAL_SIZE equ (16 * 1) +endif + +rState equ REG_ABI_PARAM_0 +rData equ REG_ABI_PARAM_1 + + + + + + +MY_SHA_INSTR macro cmd, a1, a2 + db 0fH, 038H, cmd, (0c0H + a1 * 8 + a2) +endm + +cmd_sha256rnds2 equ 0cbH +cmd_sha256msg1 equ 0ccH +cmd_sha256msg2 equ 0cdH + +MY_sha256rnds2 macro a1, a2 + MY_SHA_INSTR cmd_sha256rnds2, a1, a2 +endm + +MY_sha256msg1 macro a1, a2 + MY_SHA_INSTR cmd_sha256msg1, a1, a2 +endm + +MY_sha256msg2 macro a1, a2 + MY_SHA_INSTR cmd_sha256msg2, a1, a2 +endm + +MY_PROLOG macro + ifdef x64 + if (IS_LINUX eq 0) + movdqa [r4 + 8], xmm6 + movdqa [r4 + 8 + 16], xmm7 + sub r4, LOCAL_SIZE + 8 + movdqa [r4 ], xmm8 + 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 + PARAM_OFFSET] + mov rData, [r4 + PARAM_OFFSET + REG_SIZE * 1] + mov rNum, [r4 + PARAM_OFFSET + REG_SIZE * 2] + else ; fastcall + mov rNum, [r4 + PARAM_OFFSET] + endif + and r4, -16 + sub r4, LOCAL_SIZE + endif +endm + +MY_EPILOG macro + ifdef x64 + if (IS_LINUX eq 0) + movdqa xmm8, [r4] + movdqa xmm9, [r4 + 16] + add r4, LOCAL_SIZE + 8 + movdqa xmm6, [r4 + 8] + movdqa xmm7, [r4 + 8 + 16] + endif + else ; x86 + mov r4, r5 + pop r5 + pop r3 + endif + MY_ENDP +endm + + +msg equ xmm0 +tmp equ xmm0 +state0_N equ 2 +state1_N equ 3 +w_regs equ 4 + + +state1_save equ xmm1 +state0 equ @CatStr(xmm, %state0_N) +state1 equ @CatStr(xmm, %state1_N) + + +ifdef x64 + state0_save equ xmm8 + mask2 equ xmm9 +else + state0_save equ [r4] + mask2 equ xmm0 +endif + +LOAD_MASK macro + movdqa mask2, XMMWORD PTR Reverse_Endian_Mask +endm + +LOAD_W macro k:req + movdqu @CatStr(xmm, %(w_regs + k)), [rData + (16 * (k))] + pshufb @CatStr(xmm, %(w_regs + k)), mask2 +endm + + +; pre1 <= 4 && pre2 >= 1 && pre1 > pre2 && (pre1 - pre2) <= 1 +pre1 equ 3 +pre2 equ 2 + + + +RND4 macro k + 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 + + if (k GE (4 - pre1)) AND (k LT (16 - pre1)) + ; w4[0] = msg1(w4[-4], w4[-3]) + MY_sha256msg1 (w_regs + ((k + pre1) mod 4)), (w_regs + ((k + pre1 - 3) mod 4)) + endif + + MY_sha256rnds2 state1_N, state0_N + + if (k GE (4 - pre2)) AND (k LT (16 - pre2)) + movdqa tmp, @CatStr(xmm, %(w_regs + ((k + pre2 - 1) mod 4))) + palignr tmp, @CatStr(xmm, %(w_regs + ((k + pre2 - 2) mod 4))), 4 + paddd @CatStr(xmm, %(w_regs + ((k + pre2) mod 4))), tmp + ; w4[0] = msg2(w4[0], w4[-1]) + MY_sha256msg2 %(w_regs + ((k + pre2) mod 4)), %(w_regs + ((k + pre2 - 1) mod 4)) + endif +endm + + + + + +REVERSE_STATE macro + ; state0 ; dcba + ; state1 ; hgfe + pshufd tmp, state0, 01bH ; abcd + pshufd state0, state1, 01bH ; efgh + movdqa state1, state0 ; efgh + punpcklqdq state0, tmp ; cdgh + punpckhqdq state1, tmp ; abef +endm + + +MY_PROC Sha256_UpdateBlocks_HW, 3 + MY_PROLOG + + lea rTable, [K_CONST] + + cmp rNum, 0 + je end_c + + movdqu state0, [rState] ; dcba + movdqu state1, [rState + 16] ; hgfe + + REVERSE_STATE + + ifdef x64 + LOAD_MASK + endif + + align 16 + nextBlock: + movdqa state0_save, state0 + movdqa state1_save, state1 + + ifndef x64 + LOAD_MASK + endif + + LOAD_W 0 + LOAD_W 1 + LOAD_W 2 + LOAD_W 3 + + + k = 0 + rept 16 + RND4 k + k = k + 1 + endm + + paddd state0, state0_save + paddd state1, state1_save + + add rData, 64 + sub rNum, 1 + jnz nextBlock + + REVERSE_STATE + + movdqu [rState], state0 + movdqu [rState + 16], state1 + + end_c: +MY_EPILOG + +; _TEXT$SHA256OPT ENDS + +end diff -Nru p7zip-rar-16.02/Asm/x86/Sort.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/Sort.asm --- p7zip-rar-16.02/Asm/x86/Sort.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/Sort.asm 2025-01-08 08:00:00.000000000 +0000 @@ -0,0 +1,860 @@ +; SortTest.asm -- ASM version of HeapSort() function +; Igor Pavlov : Public domain + +include ../../../../Asm/x86/7zAsm.asm + +MY_ASM_START + +ifndef Z7_SORT_ASM_USE_SEGMENT +if (IS_LINUX gt 0) + ; Z7_SORT_ASM_USE_SEGMENT equ 1 +else + ; Z7_SORT_ASM_USE_SEGMENT equ 1 +endif +endif + +ifdef Z7_SORT_ASM_USE_SEGMENT +_TEXT$Z7_SORT SEGMENT ALIGN(64) 'CODE' +MY_ALIGN macro num:req + align num +endm +else +MY_ALIGN macro num:req + ; We expect that ".text" is aligned for 16-bytes. + ; So we don't need large alignment inside our function. + align 16 +endm +endif + + +MY_ALIGN_16 macro + MY_ALIGN 16 +endm + +MY_ALIGN_32 macro + MY_ALIGN 32 +endm + +MY_ALIGN_64 macro + MY_ALIGN 64 +endm + +ifdef x64 + +NUM_PREFETCH_LEVELS equ 3 ; to prefetch 1x 64-bytes line (is good for most cases) +; NUM_PREFETCH_LEVELS equ 4 ; to prefetch 2x 64-bytes lines (better for big arrays) + +acc equ x0 +k equ r0 +k_x equ x0 + +p equ r1 + +s equ r2 +s_x equ x2 + +a0 equ x3 +t0 equ a0 + +a3 equ x5 +qq equ a3 + +a1 equ x6 +t1 equ a1 +t1_r equ r6 + +a2 equ x7 +t2 equ a2 + +i equ r8 +e0 equ x8 + +e1 equ x9 + +num_last equ r10 +num_last_x equ x10 + +next4_lim equ r11 +pref_lim equ r12 + + + +SORT_2_WITH_TEMP_REG macro b0, b1, temp_reg + mov temp_reg, b0 + cmp b0, b1 + cmovae b0, b1 ; min + cmovae b1, temp_reg ; max +endm + +SORT macro b0, b1 + SORT_2_WITH_TEMP_REG b0, b1, acc +endm + +LOAD macro dest:req, index:req + mov dest, [p + 4 * index] +endm + +STORE macro reg:req, index:req + mov [p + 4 * index], reg +endm + + +if (NUM_PREFETCH_LEVELS gt 3) + num_prefetches equ (1 SHL (NUM_PREFETCH_LEVELS - 3)) +else + num_prefetches equ 1 +endif + +PREFETCH_OP macro offs + cur_offset = 7 * 4 ; it's average offset in 64-bytes cache line. + ; cur_offset = 0 ; we can use zero offset, if we are sure that array is aligned for 64-bytes. + rept num_prefetches + if 1 + prefetcht0 byte ptr [p + offs + cur_offset] + else + mov pref_x, dword ptr [p + offs + cur_offset] + endif + cur_offset = cur_offset + 64 + endm +endm + +PREFETCH_MY macro +if 1 + if 1 + shl k, NUM_PREFETCH_LEVELS + 3 + else + ; we delay prefetch instruction to improve main loads + shl k, NUM_PREFETCH_LEVELS + shl k, 3 + ; shl k, 0 + endif + PREFETCH_OP k +elseif 1 + shl k, 3 + PREFETCH_OP k * (1 SHL NUM_PREFETCH_LEVELS) ; change it +endif +endm + + +STEP_1 macro exit_label, prefetch_macro +use_cmov_1 equ 1 ; set 1 for cmov, but it's slower in some cases + ; set 0 for LOAD after adc s, 0 + cmp t0, t1 + if use_cmov_1 + cmovb t0, t1 + ; STORE t0, k + endif + adc s, 0 + if use_cmov_1 eq 0 + LOAD t0, s + endif + cmp qq, t0 + jae exit_label + if 1 ; use_cmov_1 eq 0 + STORE t0, k + endif + prefetch_macro + mov t0, [p + s * 8] + mov t1, [p + s * 8 + 4] + mov k, s + add s, s ; slower for some cpus + ; lea s, dword ptr [s + s] ; slower for some cpus + ; shl s, 1 ; faster for some cpus + ; lea s, dword ptr [s * 2] ; faster for some cpus + rept 0 ; 1000 for debug : 0 for normal + ; number of calls in generate_stage : ~0.6 of number of items + shl k, 0 + endm +endm + + +STEP_2 macro exit_label, prefetch_macro +use_cmov_2 equ 0 ; set 1 for cmov, but it's slower in some cases + ; set 0 for LOAD after adc s, 0 + cmp t0, t1 + if use_cmov_2 + mov t2, t0 + cmovb t2, t1 + ; STORE t2, k + endif + mov t0, [p + s * 8] + mov t1, [p + s * 8 + 4] + cmovb t0, [p + s * 8 + 8] + cmovb t1, [p + s * 8 + 12] + adc s, 0 + if use_cmov_2 eq 0 + LOAD t2, s + endif + cmp qq, t2 + jae exit_label + if 1 ; use_cmov_2 eq 0 + STORE t2, k + endif + prefetch_macro + mov k, s + ; add s, s + ; lea s, [s + s] + shl s, 1 + ; lea s, [s * 2] +endm + + +MOVE_SMALLEST_UP macro STEP, use_prefetch, num_unrolls + LOCAL exit_1, exit_2, leaves, opt_loop, last_nodes + + ; s == k * 2 + ; t0 == (p)[s] + ; t1 == (p)[s + 1] + cmp k, next4_lim + jae leaves + + rept num_unrolls + STEP exit_2 + cmp k, next4_lim + jae leaves + endm + + if use_prefetch + prefetch_macro equ PREFETCH_MY + pref_lim_2 equ pref_lim + ; lea pref_lim, dword ptr [num_last + 1] + ; shr pref_lim, NUM_PREFETCH_LEVELS + 1 + cmp k, pref_lim_2 + jae last_nodes + else + prefetch_macro equ + pref_lim_2 equ next4_lim + endif + +MY_ALIGN_16 +opt_loop: + STEP exit_2, prefetch_macro + cmp k, pref_lim_2 + jb opt_loop + +last_nodes: + ; k >= pref_lim_2 + ; 2 cases are possible: + ; case-1: num_after_prefetch_levels == 0 && next4_lim = pref_lim_2 + ; case-2: num_after_prefetch_levels == NUM_PREFETCH_LEVELS - 1 && + ; next4_lim = pref_lim_2 / (NUM_PREFETCH_LEVELS - 1) + if use_prefetch + yyy = NUM_PREFETCH_LEVELS - 1 + while yyy + yyy = yyy - 1 + STEP exit_2 + if yyy + cmp k, next4_lim + jae leaves + endif + endm + endif + +leaves: + ; k >= next4_lim == (num_last + 1) / 4 must be provided by previous code. + ; we have 2 nodes in (s) level : always + ; we can have some nodes in (s * 2) level : low probability case + ; we have no nodes in (s * 4) level + ; s == k * 2 + ; t0 == (p)[s] + ; t1 == (p)[s + 1] + cmp t0, t1 + cmovb t0, t1 + adc s, 0 + STORE t0, k + + ; t0 == (p)[s] + ; s / 2 == k : (s) is index of max item from (p)[k * 2], (p)[k * 2 + 1] + ; we have 3 possible cases here: + ; s * 2 > num_last : (s) node has no childs + ; s * 2 == num_last : (s) node has 1 leaf child that is last item of array + ; s * 2 < num_last : (s) node has 2 leaf childs. We provide (s * 4 > num_last) + ; we check for (s * 2 > num_last) before "cmp qq, t0" check, because + ; we will replace conditional jump with cmov instruction later. + lea t1_r, dword ptr [s + s] + cmp t1_r, num_last + ja exit_1 ; if (s * 2 > num_last), we have no childs : it's high probability branch + + ; it's low probability branch + ; s * 2 <= num_last + cmp qq, t0 + jae exit_2 + + ; qq < t0, so we go to next level + ; we check 1 or 2 childs in next level + mov t0, [p + s * 8] + mov k, s + mov s, t1_r + cmp t1_r, num_last + je @F ; (s == num_last) means that we have single child in tree + + ; (s < num_last) : so we must read both childs and select max of them. + mov t1, [p + k * 8 + 4] + cmp t0, t1 + cmovb t0, t1 + adc s, 0 +@@: + STORE t0, k +exit_1: + ; t0 == (p)[s], s / 2 == k : (s) is index of max item from (p)[k * 2], (p)[k * 2 + 1] + cmp qq, t0 + cmovb k, s +exit_2: + STORE qq, k +endm + + + + +ifdef Z7_SORT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif + +MY_PROC HeapSort, 2 + +if (IS_LINUX gt 0) + mov p, REG_ABI_PARAM_0 ; r1 <- r7 : linux +endif + mov num_last, REG_ABI_PARAM_1 ; r10 <- r6 : linux + ; r10 <- r2 : win64 + cmp num_last, 2 + jb end_1 + + ; MY_PUSH_PRESERVED_ABI_REGS + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + push r12 + + cmp num_last, 4 + ja sort_5 + + LOAD a0, 0 + LOAD a1, 1 + SORT a0, a1 + cmp num_last, 3 + jb end_2 + + LOAD a2, 2 + je sort_3 + + LOAD a3, 3 + SORT a2, a3 + SORT a1, a3 + STORE a3, 3 +sort_3: + SORT a0, a2 + SORT a1, a2 + STORE a2, 2 + jmp end_2 + +sort_5: + ; (num_last > 4) is required here + ; if (num_last >= 6) : we will use optimized loop for leaf nodes loop_down_1 + mov next4_lim, num_last + shr next4_lim, 2 + + dec num_last + mov k, num_last + shr k, 1 + mov i, num_last + shr i, 2 + test num_last, 1 + jnz size_even + + ; ODD number of items. So we compare parent with single child + LOAD t1, num_last + LOAD t0, k + SORT_2_WITH_TEMP_REG t1, t0, t2 + STORE t1, num_last + STORE t0, k + dec k + +size_even: + cmp k, i + jbe loop_down ; jump for num_last == 4 case + +if 0 ; 1 for debug + mov r15, k + mov r14d, 1 ; 100 +loop_benchmark: +endif + ; optimized loop for leaf nodes: + mov t0, [p + k * 8] + mov t1, [p + k * 8 + 4] + +MY_ALIGN_16 +loop_down_1: + ; we compare parent with max of childs: + ; lea s, dword ptr [2 * k] + mov s, k + cmp t0, t1 + cmovb t0, t1 + adc s, s + LOAD t2, k + STORE t0, k + cmp t2, t0 + cmovae s, k + dec k + ; we preload next items before STORE operation for calculated address + mov t0, [p + k * 8] + mov t1, [p + k * 8 + 4] + STORE t2, s + cmp k, i + jne loop_down_1 + +if 0 ; 1 for debug + mov k, r15 + dec r14d + jnz loop_benchmark + ; jmp end_debug +endif + +MY_ALIGN_16 +loop_down: + mov t0, [p + i * 8] + mov t1, [p + i * 8 + 4] + LOAD qq, i + mov k, i + lea s, dword ptr [i + i] + ; jmp end_debug + DOWN_use_prefetch equ 0 + DOWN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_1, DOWN_use_prefetch, DOWN_num_unrolls + sub i, 1 + jnb loop_down + + ; jmp end_debug + LOAD e0, 0 + LOAD e1, 1 + + LEVEL_3_LIMIT equ 8 ; 8 is default, but 7 also can work + + cmp num_last, LEVEL_3_LIMIT + 1 + jb main_loop_sort_5 + +MY_ALIGN_16 +main_loop_sort: + ; num_last > LEVEL_3_LIMIT + ; p[size--] = p[0]; + LOAD qq, num_last + STORE e0, num_last + mov e0, e1 + + mov next4_lim, num_last + shr next4_lim, 2 + mov pref_lim, num_last + shr pref_lim, NUM_PREFETCH_LEVELS + 1 + + dec num_last +if 0 ; 1 for debug + ; that optional optimization can improve the performance, if there are identical items in array + ; 3 times improvement : if all items in array are identical + ; 20% improvement : if items are different for 1 bit only + ; 1-10% improvement : if items are different for (2+) bits + ; no gain : if items are different + cmp qq, e1 + jae next_iter_main +endif + LOAD e1, 2 + LOAD t0, 3 + mov k_x, 2 + cmp e1, t0 + cmovb e1, t0 + mov t0, [p + 4 * (4 + 0)] + mov t1, [p + 4 * (4 + 1)] + cmovb t0, [p + 4 * (4 + 2)] + cmovb t1, [p + 4 * (4 + 3)] + adc k_x, 0 + ; (qq <= e1), because the tree is correctly sorted + ; also here we could check (qq >= e1) or (qq == e1) for faster exit + lea s, dword ptr [k + k] + MAIN_use_prefetch equ 1 + MAIN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_2, MAIN_use_prefetch, MAIN_num_unrolls + +next_iter_main: + cmp num_last, LEVEL_3_LIMIT + jne main_loop_sort + + ; num_last == LEVEL_3_LIMIT +main_loop_sort_5: + ; 4 <= num_last <= LEVEL_3_LIMIT + ; p[size--] = p[0]; + LOAD qq, num_last + STORE e0, num_last + mov e0, e1 + dec num_last_x + + LOAD e1, 2 + LOAD t0, 3 + mov k_x, 2 + cmp e1, t0 + cmovb e1, t0 + adc k_x, 0 + + lea s_x, dword ptr [k * 2] + cmp s_x, num_last_x + ja exit_2 + + mov t0, [p + k * 8] + je exit_1 + + ; s < num_last + mov t1, [p + k * 8 + 4] + cmp t0, t1 + cmovb t0, t1 + adc s_x, 0 +exit_1: + STORE t0, k + cmp qq, t0 + cmovb k_x, s_x +exit_2: + STORE qq, k + cmp num_last_x, 3 + jne main_loop_sort_5 + + ; num_last == 3 (real_size == 4) + LOAD a0, 2 + LOAD a1, 3 + STORE e1, 2 + STORE e0, 3 + SORT a0, a1 +end_2: + STORE a0, 0 + STORE a1, 1 +; end_debug: + ; MY_POP_PRESERVED_ABI_REGS + pop r12 + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +end_1: +MY_ENDP + + + +else +; ------------ x86 32-bit ------------ + +ifdef x64 +IS_CDECL = 0 +endif + +acc equ x0 +k equ r0 +k_x equ acc + +p equ r1 + +num_last equ r2 +num_last_x equ x2 + +a0 equ x3 +t0 equ a0 + +a3 equ x5 +i equ r5 +e0 equ a3 + +a1 equ x6 +qq equ a1 + +a2 equ x7 +s equ r7 +s_x equ a2 + + +SORT macro b0, b1 + cmp b1, b0 + jae @F + if 1 + xchg b0, b1 + else + mov acc, b0 + mov b0, b1 ; min + mov b1, acc ; max + endif +@@: +endm + +LOAD macro dest:req, index:req + mov dest, [p + 4 * index] +endm + +STORE macro reg:req, index:req + mov [p + 4 * index], reg +endm + + +STEP_1 macro exit_label + mov t0, [p + k * 8] + cmp t0, [p + k * 8 + 4] + adc s, 0 + LOAD t0, s + STORE t0, k ; we lookahed stooring for most expected branch + cmp qq, t0 + jae exit_label + ; STORE t0, k ; use if + mov k, s + add s, s + ; lea s, dword ptr [s + s] + ; shl s, 1 + ; lea s, dword ptr [s * 2] +endm + +STEP_BRANCH macro exit_label + mov t0, [p + k * 8] + cmp t0, [p + k * 8 + 4] + jae @F + inc s + mov t0, [p + k * 8 + 4] +@@: + cmp qq, t0 + jae exit_label + STORE t0, k + mov k, s + add s, s +endm + + + +MOVE_SMALLEST_UP macro STEP, num_unrolls, exit_2 + LOCAL leaves, opt_loop, single + + ; s == k * 2 + rept num_unrolls + cmp s, num_last + jae leaves + STEP_1 exit_2 + endm + cmp s, num_last + jb opt_loop + +leaves: + ; (s >= num_last) + jne exit_2 +single: + ; (s == num_last) + mov t0, [p + k * 8] + cmp qq, t0 + jae exit_2 + STORE t0, k + mov k, s + jmp exit_2 + +MY_ALIGN_16 +opt_loop: + STEP exit_2 + cmp s, num_last + jb opt_loop + je single +exit_2: + STORE qq, k +endm + + + + +ifdef Z7_SORT_ASM_USE_SEGMENT +; MY_ALIGN_64 +else + MY_ALIGN_16 +endif + +MY_PROC HeapSort, 2 + ifdef x64 + if (IS_LINUX gt 0) + mov num_last, REG_ABI_PARAM_1 ; r2 <- r6 : linux + mov p, REG_ABI_PARAM_0 ; r1 <- r7 : linux + endif + elseif (IS_CDECL gt 0) + mov num_last, [r4 + REG_SIZE * 2] + mov p, [r4 + REG_SIZE * 1] + endif + cmp num_last, 2 + jb end_1 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + + cmp num_last, 4 + ja sort_5 + + LOAD a0, 0 + LOAD a1, 1 + SORT a0, a1 + cmp num_last, 3 + jb end_2 + + LOAD a2, 2 + je sort_3 + + LOAD a3, 3 + SORT a2, a3 + SORT a1, a3 + STORE a3, 3 +sort_3: + SORT a0, a2 + SORT a1, a2 + STORE a2, 2 + jmp end_2 + +sort_5: + ; num_last > 4 + lea i, dword ptr [num_last - 2] + dec num_last + test i, 1 + jz loop_down + + ; single child + mov t0, [p + num_last * 4] + mov qq, [p + num_last * 2] + dec i + cmp qq, t0 + jae loop_down + + mov [p + num_last * 2], t0 + mov [p + num_last * 4], qq + +MY_ALIGN_16 +loop_down: + mov t0, [p + i * 4] + cmp t0, [p + i * 4 + 4] + mov k, i + mov qq, [p + i * 2] + adc k, 0 + LOAD t0, k + cmp qq, t0 + jae down_next + mov [p + i * 2], t0 + lea s, dword ptr [k + k] + + DOWN_num_unrolls equ 0 + MOVE_SMALLEST_UP STEP_1, DOWN_num_unrolls, down_exit_label +down_next: + sub i, 2 + jnb loop_down + ; jmp end_debug + + LOAD e0, 0 + +MY_ALIGN_16 +main_loop_sort: + ; num_last > 3 + mov t0, [p + 2 * 4] + cmp t0, [p + 3 * 4] + LOAD qq, num_last + STORE e0, num_last + LOAD e0, 1 + mov s_x, 2 + mov k_x, 1 + adc s, 0 + LOAD t0, s + dec num_last + cmp qq, t0 + jae main_exit_label + STORE t0, 1 + mov k, s + add s, s + if 1 + ; for branch data prefetch mode : + ; it's faster for large arrays : larger than (1 << 13) items. + MAIN_num_unrolls equ 10 + STEP_LOOP equ STEP_BRANCH + else + MAIN_num_unrolls equ 0 + STEP_LOOP equ STEP_1 + endif + + MOVE_SMALLEST_UP STEP_LOOP, MAIN_num_unrolls, main_exit_label + + ; jmp end_debug + cmp num_last, 3 + jne main_loop_sort + + ; num_last == 3 (real_size == 4) + LOAD a0, 2 + LOAD a1, 3 + LOAD a2, 1 + STORE e0, 3 ; e0 is alias for a3 + STORE a2, 2 + SORT a0, a1 +end_2: + STORE a0, 0 + STORE a1, 1 +; end_debug: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +end_1: +MY_ENDP + +endif + +ifdef Z7_SORT_ASM_USE_SEGMENT +_TEXT$Z7_SORT ENDS +endif + +if 0 +LEA_IS_D8 (R64) [R2 * 4 + 16] + Lat : TP + 2 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 hsw-rocket + 1 : 2 : p01 snb-ivb + 1 : 1 : p1 conroe-wsm + 1 : 4 : zen3,zen4 + 2 : 4 : zen1,zen2 + +LEA_B_IS (R64) [R2 + R3 * 4] + Lat : TP + 1 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 hsw-rocket + 1 : 2 : p01 snb-ivb + 1 : 1 : p1 nhm-wsm + 1 : 1 : p0 conroe-wsm + 1 : 4 : zen3,zen4 + 2 :2,4 : zen1,zen2 + +LEA_B_IS_D8 (R64) [R2 + R3 * 4 + 16] + Lat : TP + 2 : 1 : adl-e + 2 : 3 p056 adl-p + 1 : 2 : p15 ice-rocket + 3 : 1 : p1/p15 hsw-rocket + 3 : 1 : p01 snb-ivb + 1 : 1 : p1 nhm-wsm + 1 : 1 : p0 conroe-wsm + 2,1 : 2 : zen3,zen4 + 2 : 2 : zen1,zen2 + +CMOVB (R64, R64) + Lat : TP + 1,2 : 2 : adl-e + 1 : 2 p06 adl-p + 1 : 2 : p06 bwd-rocket + 1,2 : 2 : p0156+p06 hsw + 1,2 :1.5 : p015+p05 snb-ivb + 1,2 : 1 : p015+p05 nhm + 1 : 1 : 2*p015 conroe + 1 : 2 : zen3,zen4 + 1 : 4 : zen1,zen2 + +ADC (R64, 0) + Lat : TP + 1,2 : 2 : adl-e + 1 : 2 p06 adl-p + 1 : 2 : p06 bwd-rocket + 1 :1.5 : p0156+p06 hsw + 1 :1.5 : p015+p05 snb-ivb + 2 : 1 : 2*p015 conroe-wstm + 1 : 2 : zen1,zen2,zen3,zen4 + +PREFETCHNTA : fetch data into non-temporal cache close to the processor, minimizing cache pollution. + L1 : Pentium3 + L2 : NetBurst + L1, not L2: Core duo, Core 2, Atom processors + L1, not L2, may fetch into L3 with fast replacement: Nehalem, Westmere, Sandy Bridge, ... + NEHALEM: Fills L1/L3, L1 LRU is not updated + L3 with fast replacement: Xeon Processors based on Nehalem, Westmere, Sandy Bridge, ... +PREFETCHT0 : fetch data into all cache levels. +PREFETCHT1 : fetch data into L2 and L3 +endif + +end diff -Nru p7zip-rar-16.02/Asm/x86/XzCrc64Opt.asm p7zip-rar-16.02+really25.00+ds/Asm/x86/XzCrc64Opt.asm --- p7zip-rar-16.02/Asm/x86/XzCrc64Opt.asm 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Asm/x86/XzCrc64Opt.asm 2023-12-08 17:00:00.000000000 +0000 @@ -0,0 +1,523 @@ +; XzCrc64Opt.asm -- CRC64 calculation : optimized version +; 2023-12-08 : Igor Pavlov : Public domain + +include 7zAsm.asm + +MY_ASM_START + +NUM_WORDS equ 3 + +if (NUM_WORDS lt 1) or (NUM_WORDS gt 64) +.err +endif + +NUM_SKIP_BYTES equ ((NUM_WORDS - 2) * 4) + + +MOVZXLO macro dest:req, src:req + movzx dest, @CatStr(src, _L) +endm + +MOVZXHI macro dest:req, src:req + movzx dest, @CatStr(src, _H) +endm + + +ifdef x64 + +rD equ r11 +rN equ r10 +rT equ r9 + +CRC_OP macro op:req, dest:req, src:req, t:req + op dest, QWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t)] +endm + +CRC_XOR macro dest:req, src:req, t:req + CRC_OP xor, dest, src, t +endm + +CRC_MOV macro dest:req, src:req, t:req + CRC_OP mov, dest, src, t +endm + +CRC1b macro + movzx x6, BYTE PTR [rD] + inc rD + MOVZXLO x3, x0 + xor x6, x3 + shr r0, 8 + CRC_XOR r0, x6, 0 + dec rN +endm + + +; ALIGN_MASK is 3 or 7 bytes alignment: +ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4) + +if NUM_WORDS eq 1 + +src_rN_offset equ 4 +; + 4 for prefetching next 4-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 4) +SRCDAT4 equ DWORD PTR [rN + rD * 1] + +XOR_NEXT macro + mov x1, [rD] + xor r0, r1 +endm + +else ; NUM_WORDS > 1 + +src_rN_offset equ 8 +; + 8 for prefetching next 8-bytes after current iteration +NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 8) + +XOR_NEXT macro + xor r0, QWORD PTR [rD] ; 64-bit read, can be unaligned +endm + +; 32-bit or 64-bit +LOAD_SRC_MULT4 macro dest:req, word_index:req + mov dest, [rN + rD * 1 + 4 * (word_index) - src_rN_offset]; +endm + +endif + + + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 4 + MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 + + mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7 + mov rD, REG_ABI_PARAM_1 ; r11 <- r2 / r6 + mov rN, REG_ABI_PARAM_2 ; r10 <- r8 / r2 +if (IS_LINUX gt 0) + mov rT, REG_ABI_PARAM_3 ; r9 <- r9 / r1 +endif + + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + XOR_NEXT + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + sub rD, rN + add rN, src_rN_offset + +align 16 +@@: + +if NUM_WORDS eq 1 + + mov x1, x0 + shr x1, 8 + MOVZXLO x3, x1 + MOVZXLO x2, x0 + shr x1, 8 + shr r0, 32 + xor x0, SRCDAT4 + CRC_XOR r0, x2, 3 + CRC_XOR r0, x3, 2 + MOVZXLO x2, x1 + shr x1, 8 + CRC_XOR r0, x2, 1 + CRC_XOR r0, x1, 0 + +else ; NUM_WORDS > 1 + +if NUM_WORDS ne 2 + k = 2 + while k lt NUM_WORDS + + LOAD_SRC_MULT4 x1, k + crc_op1 textequ + + if k eq 2 + if (NUM_WORDS and 1) + LOAD_SRC_MULT4 x7, NUM_WORDS ; aligned 32-bit + LOAD_SRC_MULT4 x6, NUM_WORDS + 1 ; aligned 32-bit + shl r6, 32 + else + LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit + crc_op1 textequ + endif + endif + table = 4 * (NUM_WORDS - 1 - k) + MOVZXLO x3, x1 + CRC_OP crc_op1, r7, x3, 3 + table + MOVZXHI x3, x1 + shr x1, 16 + CRC_XOR r6, x3, 2 + table + MOVZXLO x3, x1 + shr x1, 8 + CRC_XOR r7, x3, 1 + table + CRC_XOR r6, x1, 0 + table + k = k + 1 + endm + crc_op2 textequ + +else ; NUM_WORDS == 2 + LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit + crc_op2 textequ +endif ; NUM_WORDS == 2 + + MOVZXHI x3, x0 + MOVZXLO x2, x0 + mov r1, r0 + shr r1, 32 + shr x0, 16 + CRC_XOR r6, x2, NUM_SKIP_BYTES + 7 + CRC_OP crc_op2, r7, x3, NUM_SKIP_BYTES + 6 + MOVZXLO x2, x0 + MOVZXHI x5, x1 + MOVZXLO x3, x1 + shr x0, 8 + shr x1, 16 + CRC_XOR r7, x2, NUM_SKIP_BYTES + 5 + CRC_XOR r6, x3, NUM_SKIP_BYTES + 3 + CRC_XOR r7, x0, NUM_SKIP_BYTES + 4 + CRC_XOR r6, x5, NUM_SKIP_BYTES + 2 + MOVZXLO x2, x1 + shr x1, 8 + CRC_XOR r7, x2, NUM_SKIP_BYTES + 1 + CRC_MOV r0, x1, NUM_SKIP_BYTES + 0 + xor r0, r6 + xor r0, r7 + +endif ; NUM_WORDS > 1 + add rD, NUM_WORDS * 4 + jnc @B + + sub rN, src_rN_offset + add rD, rN + XOR_NEXT + add rN, NUM_BYTES_LIMIT - 1 + sub rN, rD + +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B +func_end: + MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 +MY_ENDP + + + +else +; ================================================================== +; x86 (32-bit) + +rD equ r7 +rN equ r1 +rT equ r5 + +xA equ x6 +xA_R equ r6 + +ifdef x64 + num_VAR equ r8 +else + +crc_OFFS equ (REG_SIZE * 5) + +if (IS_CDECL gt 0) or (IS_LINUX gt 0) + ; cdecl or (GNU fastcall) stack: + ; (UInt32 *) table + ; size_t size + ; void * data + ; (UInt64) crc + ; ret-ip <-(r4) + data_OFFS equ (8 + crc_OFFS) + size_OFFS equ (REG_SIZE + data_OFFS) + table_OFFS equ (REG_SIZE + size_OFFS) + num_VAR equ [r4 + size_OFFS] + table_VAR equ [r4 + table_OFFS] +else + ; Windows fastcall: + ; r1 = data, r2 = size + ; stack: + ; (UInt32 *) table + ; (UInt64) crc + ; ret-ip <-(r4) + table_OFFS equ (8 + crc_OFFS) + table_VAR equ [r4 + table_OFFS] + num_VAR equ table_VAR +endif +endif ; x64 + +SRCDAT4 equ DWORD PTR [rN + rD * 1] + +CRC_1 macro op:req, dest:req, src:req, t:req, word_index:req + op dest, DWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t) + (word_index) * 4] +endm + +CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req + CRC_1 op0, dest0, src, t, 0 + CRC_1 op1, dest1, src, t, 1 +endm + +CRC_XOR macro dest0:req, dest1:req, src:req, t:req + CRC xor, xor, dest0, dest1, src, t +endm + + +CRC1b macro + movzx xA, BYTE PTR [rD] + inc rD + MOVZXLO x3, x0 + xor xA, x3 + shrd x0, x2, 8 + shr x2, 8 + CRC_XOR x0, x2, xA, 0 + dec rN +endm + + +MY_PROLOG_BASE macro + MY_PUSH_4_REGS +ifdef x64 + mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7 + mov rT, REG_ABI_PARAM_3 ; r5 <- r9 / r1 + mov rN, REG_ABI_PARAM_2 ; r1 <- r8 / r2 + mov rD, REG_ABI_PARAM_1 ; r7 <- r2 / r6 + mov r2, r0 + shr r2, 32 + mov x0, x0 +else + if (IS_CDECL gt 0) or (IS_LINUX gt 0) + proc_numParams = proc_numParams + 2 ; for ABI_LINUX + mov rN, [r4 + size_OFFS] + mov rD, [r4 + data_OFFS] + else + mov rD, REG_ABI_PARAM_0 ; r7 <- r1 : (data) + mov rN, REG_ABI_PARAM_1 ; r1 <- r2 : (size) + endif + mov x0, [r4 + crc_OFFS] + mov x2, [r4 + crc_OFFS + 4] + mov rT, table_VAR +endif +endm + + +MY_EPILOG_BASE macro crc_end:req, func_end:req +crc_end: + test rN, rN + jz func_end +@@: + CRC1b + jnz @B +func_end: +ifdef x64 + shl r2, 32 + xor r0, r2 +endif + MY_POP_4_REGS +endm + + +; ALIGN_MASK is 3 or 7 bytes alignment: +ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4) + +if (NUM_WORDS eq 1) + +NUM_BYTES_LIMIT_T4 equ (NUM_WORDS * 4 + 4) + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5 + MY_PROLOG_BASE + + cmp rN, NUM_BYTES_LIMIT_T4 + ALIGN_MASK + jb crc_end_4 +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, [rD] + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT_T4 - 1)] + sub rD, rN + add rN, 4 + + MOVZXLO xA, x0 +align 16 +@@: + mov x3, SRCDAT4 + xor x3, x2 + shr x0, 8 + CRC xor, mov, x3, x2, xA, 3 + MOVZXLO xA, x0 + shr x0, 8 + ; MOVZXHI xA, x0 + ; shr x0, 16 + CRC_XOR x3, x2, xA, 2 + + MOVZXLO xA, x0 + shr x0, 8 + CRC_XOR x3, x2, xA, 1 + CRC_XOR x3, x2, x0, 0 + MOVZXLO xA, x3 + mov x0, x3 + + add rD, 4 + jnc @B + + sub rN, 4 + add rD, rN + xor x0, [rD] + add rN, NUM_BYTES_LIMIT_T4 - 1 + sub rN, rD + MY_EPILOG_BASE crc_end_4, func_end_4 +MY_ENDP + +else ; NUM_WORDS > 1 + +SHR_X macro x, imm + shr x, imm +endm + + +ITER_1 macro v0, v1, a, off + MOVZXLO xA, a + SHR_X a, 8 + CRC_XOR v0, v1, xA, off +endm + + +ITER_4 macro v0, v1, a, off +if 0 eq 0 + ITER_1 v0, v1, a, off + 3 + ITER_1 v0, v1, a, off + 2 + ITER_1 v0, v1, a, off + 1 + CRC_XOR v0, v1, a, off +elseif 0 eq 0 + MOVZXLO xA, a + CRC_XOR v0, v1, xA, off + 3 + mov xA, a + ror a, 16 ; 32-bit ror + shr xA, 24 + CRC_XOR v0, v1, xA, off + MOVZXLO xA, a + SHR_X a, 24 + CRC_XOR v0, v1, xA, off + 1 + CRC_XOR v0, v1, a, off + 2 +else + ; MOVZXHI provides smaller code, but MOVZX_HI_BYTE is not fast instruction + MOVZXLO xA, a + CRC_XOR v0, v1, xA, off + 3 + MOVZXHI xA, a + SHR_X a, 16 + CRC_XOR v0, v1, xA, off + 2 + MOVZXLO xA, a + SHR_X a, 8 + CRC_XOR v0, v1, xA, off + 1 + CRC_XOR v0, v1, a, off +endif +endm + + + +ITER_1_PAIR macro v0, v1, a0, a1, off + ITER_1 v0, v1, a0, off + 4 + ITER_1 v0, v1, a1, off +endm + +src_rD_offset equ 8 +STEP_SIZE equ (NUM_WORDS * 4) + +ITER_12_NEXT macro op, index, v0, v1 + op v0, DWORD PTR [rD + (index + 1) * STEP_SIZE - src_rD_offset] + op v1, DWORD PTR [rD + (index + 1) * STEP_SIZE + 4 - src_rD_offset] +endm + +ITER_12 macro index, a0, a1, v0, v1 + + if NUM_SKIP_BYTES eq 0 + ITER_12_NEXT mov, index, v0, v1 + else + k = 0 + while k lt NUM_SKIP_BYTES + movzx xA, BYTE PTR [rD + (index) * STEP_SIZE + k + 8 - src_rD_offset] + if k eq 0 + CRC mov, mov, v0, v1, xA, NUM_SKIP_BYTES - 1 - k + else + CRC_XOR v0, v1, xA, NUM_SKIP_BYTES - 1 - k + endif + k = k + 1 + endm + ITER_12_NEXT xor, index, v0, v1 + endif + +if 0 eq 0 + ITER_4 v0, v1, a0, NUM_SKIP_BYTES + 4 + ITER_4 v0, v1, a1, NUM_SKIP_BYTES +else ; interleave version is faster/slower for different processors + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 3 + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 2 + ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 1 + CRC_XOR v0, v1, a0, NUM_SKIP_BYTES + 4 + CRC_XOR v0, v1, a1, NUM_SKIP_BYTES +endif +endm + +; we use (UNROLL_CNT > 1) to reduce read ports pressure (num_VAR reads) +UNROLL_CNT equ (2 * 1) +NUM_BYTES_LIMIT equ (STEP_SIZE * UNROLL_CNT + 8) + +MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5 + MY_PROLOG_BASE + + cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK + jb crc_end_12 +@@: + test rD, ALIGN_MASK + jz @F + CRC1b + jmp @B +@@: + xor x0, [rD] + xor x2, [rD + 4] + add rD, src_rD_offset + lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)] + mov num_VAR, rN + +align 16 +@@: + i = 0 + rept UNROLL_CNT + if (i and 1) eq 0 + ITER_12 i, x0, x2, x1, x3 + else + ITER_12 i, x1, x3, x0, x2 + endif + i = i + 1 + endm + + if (UNROLL_CNT and 1) + mov x0, x1 + mov x2, x3 + endif + add rD, STEP_SIZE * UNROLL_CNT + cmp rD, num_VAR + jb @B + + mov rN, num_VAR + add rN, NUM_BYTES_LIMIT - 1 + sub rN, rD + sub rD, src_rD_offset + xor x0, [rD] + xor x2, [rD + 4] + + MY_EPILOG_BASE crc_end_12, func_end_12 +MY_ENDP + +endif ; (NUM_WORDS > 1) +endif ; ! x64 +end diff -Nru p7zip-rar-16.02/C/7z.h p7zip-rar-16.02+really25.00+ds/C/7z.h --- p7zip-rar-16.02/C/7z.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7z.h 2023-04-02 11:00:00.000000000 +0000 @@ -0,0 +1,204 @@ +/* 7z.h -- 7z interface +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_H +#define ZIP7_INC_7Z_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define k7zStartHeaderSize 0x20 +#define k7zSignatureSize 6 + +extern const Byte k7zSignature[k7zSignatureSize]; + +typedef struct +{ + const Byte *Data; + size_t Size; +} CSzData; + +/* CSzCoderInfo & CSzFolder support only default methods */ + +typedef struct +{ + size_t PropsOffset; + UInt32 MethodID; + Byte NumStreams; + Byte PropsSize; +} CSzCoderInfo; + +typedef struct +{ + UInt32 InIndex; + UInt32 OutIndex; +} CSzBond; + +#define SZ_NUM_CODERS_IN_FOLDER_MAX 4 +#define SZ_NUM_BONDS_IN_FOLDER_MAX 3 +#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4 + +typedef struct +{ + UInt32 NumCoders; + UInt32 NumBonds; + UInt32 NumPackStreams; + UInt32 UnpackStream; + UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; + CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX]; + CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; +} CSzFolder; + + +SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd); + +typedef struct +{ + UInt32 Low; + UInt32 High; +} CNtfsFileTime; + +typedef struct +{ + Byte *Defs; /* MSB 0 bit numbering */ + UInt32 *Vals; +} CSzBitUi32s; + +typedef struct +{ + Byte *Defs; /* MSB 0 bit numbering */ + // UInt64 *Vals; + CNtfsFileTime *Vals; +} CSzBitUi64s; + +#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) + +#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) + +typedef struct +{ + UInt32 NumPackStreams; + UInt32 NumFolders; + + UInt64 *PackPositions; // NumPackStreams + 1 + CSzBitUi32s FolderCRCs; // NumFolders + + size_t *FoCodersOffsets; // NumFolders + 1 + UInt32 *FoStartPackStreamIndex; // NumFolders + 1 + UInt32 *FoToCoderUnpackSizes; // NumFolders + 1 + Byte *FoToMainUnpackSizeIndex; // NumFolders + UInt64 *CoderUnpackSizes; // for all coders in all folders + + Byte *CodersData; + + UInt64 RangeLimit; +} CSzAr; + +UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); + +SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, + ILookInStreamPtr stream, UInt64 startPos, + Byte *outBuffer, size_t outSize, + ISzAllocPtr allocMain); + +typedef struct +{ + CSzAr db; + + UInt64 startPosAfterHeader; + UInt64 dataPos; + + UInt32 NumFiles; + + UInt64 *UnpackPositions; // NumFiles + 1 + // Byte *IsEmptyFiles; + Byte *IsDirs; + CSzBitUi32s CRCs; + + CSzBitUi32s Attribs; + // CSzBitUi32s Parents; + CSzBitUi64s MTime; + CSzBitUi64s CTime; + + UInt32 *FolderToFile; // NumFolders + 1 + UInt32 *FileToFolder; // NumFiles + + size_t *FileNameOffsets; /* in 2-byte steps */ + Byte *FileNames; /* UTF-16-LE */ +} CSzArEx; + +#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i)) + +#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc); +UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); + +/* +if dest == NULL, the return value specifies the required size of the buffer, + in 16-bit characters, including the null-terminating character. +if dest != NULL, the return value specifies the number of 16-bit characters that + are written to the dest, including the null-terminating character. */ + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); + +/* +size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex); +UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); +*/ + + + +/* + SzArEx_Extract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +SRes SzArEx_Extract( + const CSzArEx *db, + ILookInStreamPtr inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp); + + +/* +SzArEx_Open Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, + ISzAllocPtr allocMain, ISzAllocPtr allocTemp); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/7zAlloc.c p7zip-rar-16.02+really25.00+ds/C/7zAlloc.c --- p7zip-rar-16.02/C/7zAlloc.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zAlloc.c 2023-03-04 09:00:00.000000000 +0000 @@ -0,0 +1,89 @@ +/* 7zAlloc.c -- Allocation functions for 7z processing +2023-03-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zAlloc.h" + +/* #define SZ_ALLOC_DEBUG */ +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef SZ_ALLOC_DEBUG + +/* +#ifdef _WIN32 +#include "7zWindows.h" +#endif +*/ + +#include +static int g_allocCount = 0; +static int g_allocCountTemp = 0; + +static void Print_Alloc(const char *s, size_t size, int *counter) +{ + const unsigned size2 = (unsigned)size; + fprintf(stderr, "\n%s count = %10d : %10u bytes; ", s, *counter, size2); + (*counter)++; +} +static void Print_Free(const char *s, int *counter) +{ + (*counter)--; + fprintf(stderr, "\n%s count = %10d", s, *counter); +} +#endif + +void *SzAlloc(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p) + if (size == 0) + return 0; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc", size, &g_allocCount); + #endif + return malloc(size); +} + +void SzFree(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free ", &g_allocCount); + #endif + free(address); +} + +void *SzAllocTemp(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p) + if (size == 0) + return 0; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc_temp", size, &g_allocCountTemp); + /* + #ifdef _WIN32 + return HeapAlloc(GetProcessHeap(), 0, size); + #endif + */ + #endif + return malloc(size); +} + +void SzFreeTemp(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free_temp ", &g_allocCountTemp); + /* + #ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, address); + return; + #endif + */ + #endif + free(address); +} diff -Nru p7zip-rar-16.02/C/7zAlloc.h p7zip-rar-16.02+really25.00+ds/C/7zAlloc.h --- p7zip-rar-16.02/C/7zAlloc.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zAlloc.h 2023-03-04 09:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +/* 7zAlloc.h -- Allocation functions +2023-03-04 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_ALLOC_H +#define ZIP7_INC_7Z_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void *SzAlloc(ISzAllocPtr p, size_t size); +void SzFree(ISzAllocPtr p, void *address); + +void *SzAllocTemp(ISzAllocPtr p, size_t size); +void SzFreeTemp(ISzAllocPtr p, void *address); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/7zArcIn.c p7zip-rar-16.02+really25.00+ds/C/7zArcIn.c --- p7zip-rar-16.02/C/7zArcIn.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zArcIn.c 2023-09-07 11:00:00.000000000 +0000 @@ -0,0 +1,1786 @@ +/* 7zArcIn.c -- 7z Input functions +2023-09-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7z.h" +#include "7zBuf.h" +#include "7zCrc.h" +#include "CpuArch.h" + +#define MY_ALLOC(T, p, size, alloc) \ + { if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } + +#define MY_ALLOC_ZE(T, p, size, alloc) \ + { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } + +#define MY_ALLOC_AND_CPY(to, size, from, alloc) \ + { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); } + +#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \ + { if ((size) == 0) to = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } } + +#define k7zMajorVersion 0 + +enum EIdEnum +{ + k7zIdEnd, + k7zIdHeader, + k7zIdArchiveProperties, + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + k7zIdSize, + k7zIdCRC, + k7zIdFolder, + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttrib, + k7zIdComment, + k7zIdEncodedHeader, + k7zIdStartPos, + k7zIdDummy + // k7zNtSecure, + // k7zParent, + // k7zIsReal +}; + +const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + +#define SzBitUi32s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } + +static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) +{ + if (num == 0) + { + p->Defs = NULL; + p->Vals = NULL; + } + else + { + MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc) + MY_ALLOC(UInt32, p->Vals, num, alloc) + } + return SZ_OK; +} + +static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; +} + +#define SzBitUi64s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } + +static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; + ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; +} + + +static void SzAr_Init(CSzAr *p) +{ + p->NumPackStreams = 0; + p->NumFolders = 0; + + p->PackPositions = NULL; + SzBitUi32s_INIT(&p->FolderCRCs) + + p->FoCodersOffsets = NULL; + p->FoStartPackStreamIndex = NULL; + p->FoToCoderUnpackSizes = NULL; + p->FoToMainUnpackSizeIndex = NULL; + p->CoderUnpackSizes = NULL; + + p->CodersData = NULL; + + p->RangeLimit = 0; +} + +static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->PackPositions); + SzBitUi32s_Free(&p->FolderCRCs, alloc); + + ISzAlloc_Free(alloc, p->FoCodersOffsets); + ISzAlloc_Free(alloc, p->FoStartPackStreamIndex); + ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes); + ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); + ISzAlloc_Free(alloc, p->CoderUnpackSizes); + + ISzAlloc_Free(alloc, p->CodersData); + + SzAr_Init(p); +} + + +void SzArEx_Init(CSzArEx *p) +{ + SzAr_Init(&p->db); + + p->NumFiles = 0; + p->dataPos = 0; + + p->UnpackPositions = NULL; + p->IsDirs = NULL; + + p->FolderToFile = NULL; + p->FileToFolder = NULL; + + p->FileNameOffsets = NULL; + p->FileNames = NULL; + + SzBitUi32s_INIT(&p->CRCs) + SzBitUi32s_INIT(&p->Attribs) + // SzBitUi32s_INIT(&p->Parents) + SzBitUi64s_INIT(&p->MTime) + SzBitUi64s_INIT(&p->CTime) +} + +void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->UnpackPositions); + ISzAlloc_Free(alloc, p->IsDirs); + + ISzAlloc_Free(alloc, p->FolderToFile); + ISzAlloc_Free(alloc, p->FileToFolder); + + ISzAlloc_Free(alloc, p->FileNameOffsets); + ISzAlloc_Free(alloc, p->FileNames); + + SzBitUi32s_Free(&p->CRCs, alloc); + SzBitUi32s_Free(&p->Attribs, alloc); + // SzBitUi32s_Free(&p->Parents, alloc); + SzBitUi64s_Free(&p->MTime, alloc); + SzBitUi64s_Free(&p->CTime, alloc); + + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); +} + + +static int TestSignatureCandidate(const Byte *testBytes) +{ + unsigned i; + for (i = 0; i < k7zSignatureSize; i++) + if (testBytes[i] != k7zSignature[i]) + return 0; + return 1; +} + +#define SzData_CLEAR(p) { (p)->Data = NULL; (p)->Size = 0; } + +#define SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) \ + (_sd_)->Size--; dest = *(_sd_)->Data++; + +#define SZ_READ_BYTE_SD(_sd_, dest) \ + if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; \ + SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) + +#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) + +#define SZ_READ_BYTE_2(dest) \ + if (sd.Size == 0) return SZ_ERROR_ARCHIVE; \ + sd.Size--; dest = *sd.Data++; + +#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } +#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } + +#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \ + dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4); + +static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) +{ + Byte firstByte, mask; + unsigned i; + UInt32 v; + + SZ_READ_BYTE(firstByte) + if ((firstByte & 0x80) == 0) + { + *value = firstByte; + return SZ_OK; + } + SZ_READ_BYTE(v) + if ((firstByte & 0x40) == 0) + { + *value = (((UInt32)firstByte & 0x3F) << 8) | v; + return SZ_OK; + } + SZ_READ_BYTE(mask) + *value = v | ((UInt32)mask << 8); + mask = 0x20; + for (i = 2; i < 8; i++) + { + Byte b; + if ((firstByte & mask) == 0) + { + const UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); + *value |= (highPart << (8 * i)); + return SZ_OK; + } + SZ_READ_BYTE(b) + *value |= ((UInt64)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + + +static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) +{ + Byte firstByte; + UInt64 value64; + if (sd->Size == 0) + return SZ_ERROR_ARCHIVE; + firstByte = *sd->Data; + if ((firstByte & 0x80) == 0) + { + *value = firstByte; + sd->Data++; + sd->Size--; + return SZ_OK; + } + RINOK(ReadNumber(sd, &value64)) + if (value64 >= (UInt32)0x80000000 - 1) + return SZ_ERROR_UNSUPPORTED; + if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4))) + return SZ_ERROR_UNSUPPORTED; + *value = (UInt32)value64; + return SZ_OK; +} + +#define ReadID(sd, value) ReadNumber(sd, value) + +static SRes SkipData(CSzData *sd) +{ + UInt64 size; + RINOK(ReadNumber(sd, &size)) + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA(sd, size) + return SZ_OK; +} + +static SRes WaitId(CSzData *sd, UInt32 id) +{ + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)) + if (type == id) + return SZ_OK; + if (type == k7zIdEnd) + return SZ_ERROR_ARCHIVE; + RINOK(SkipData(sd)) + } +} + +static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v) +{ + const UInt32 numBytes = (numItems + 7) >> 3; + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + *v = sd->Data; + SKIP_DATA(sd, numBytes) + return SZ_OK; +} + +static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) +{ + unsigned b = 0; + unsigned m = 0; + UInt32 sum = 0; + for (; numItems != 0; numItems--) + { + if (m == 0) + { + b = *bits++; + m = 8; + } + m--; + sum += (UInt32)((b >> m) & 1); + } + return sum; +} + +static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) +{ + Byte allAreDefined; + Byte *v2; + const UInt32 numBytes = (numItems + 7) >> 3; + *v = NULL; + SZ_READ_BYTE(allAreDefined) + if (numBytes == 0) + return SZ_OK; + if (allAreDefined == 0) + { + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc) + SKIP_DATA(sd, numBytes) + return SZ_OK; + } + MY_ALLOC(Byte, *v, numBytes, alloc) + v2 = *v; + memset(v2, 0xFF, (size_t)numBytes); + { + const unsigned numBits = (unsigned)numItems & 7; + if (numBits != 0) + v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); + } + return SZ_OK; +} + +static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +{ + UInt32 i; + CSzData sd; + UInt32 *vals; + const Byte *defs; + MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc) + sd = *sd2; + defs = crcs->Defs; + vals = crcs->Vals; + for (i = 0; i < numItems; i++) + if (SzBitArray_Check(defs, i)) + { + SZ_READ_32(vals[i]) + } + else + vals[i] = 0; + *sd2 = sd; + return SZ_OK; +} + +static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +{ + SzBitUi32s_Free(crcs, alloc); + RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)) + return ReadUi32s(sd, numItems, crcs, alloc); +} + +static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) +{ + Byte allAreDefined; + UInt32 numDefined = numItems; + SZ_READ_BYTE(allAreDefined) + if (!allAreDefined) + { + const size_t numBytes = (numItems + 7) >> 3; + if (numBytes > sd->Size) + return SZ_ERROR_ARCHIVE; + numDefined = CountDefinedBits(sd->Data, numItems); + SKIP_DATA(sd, numBytes) + } + if (numDefined > (sd->Size >> 2)) + return SZ_ERROR_ARCHIVE; + SKIP_DATA(sd, (size_t)numDefined * 4) + return SZ_OK; +} + +static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) +{ + RINOK(SzReadNumber32(sd, &p->NumPackStreams)) + + RINOK(WaitId(sd, k7zIdSize)) + MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc) + { + UInt64 sum = 0; + UInt32 i; + const UInt32 numPackStreams = p->NumPackStreams; + for (i = 0; i < numPackStreams; i++) + { + UInt64 packSize; + p->PackPositions[i] = sum; + RINOK(ReadNumber(sd, &packSize)) + sum += packSize; + if (sum < packSize) + return SZ_ERROR_ARCHIVE; + } + p->PackPositions[i] = sum; + } + + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)) + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + /* CRC of packed streams is unused now */ + RINOK(SkipBitUi32s(sd, p->NumPackStreams)) + continue; + } + RINOK(SkipData(sd)) + } +} + +/* +static SRes SzReadSwitch(CSzData *sd) +{ + Byte external; + RINOK(SzReadByte(sd, &external)); + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; +} +*/ + +#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) + +SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) +{ + UInt32 numCoders, i; + UInt32 numInStreams = 0; + const Byte *dataStart = sd->Data; + + f->NumCoders = 0; + f->NumBonds = 0; + f->NumPackStreams = 0; + f->UnpackStream = 0; + + RINOK(SzReadNumber32(sd, &numCoders)) + if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (i = 0; i < numCoders; i++) + { + Byte mainByte; + CSzCoderInfo *coder = f->Coders + i; + unsigned idSize, j; + UInt64 id; + + SZ_READ_BYTE(mainByte) + if ((mainByte & 0xC0) != 0) + return SZ_ERROR_UNSUPPORTED; + + idSize = (unsigned)(mainByte & 0xF); + if (idSize > sizeof(id)) + return SZ_ERROR_UNSUPPORTED; + if (idSize > sd->Size) + return SZ_ERROR_ARCHIVE; + id = 0; + for (j = 0; j < idSize; j++) + { + id = ((id << 8) | *sd->Data); + sd->Data++; + sd->Size--; + } + if (id > (UInt32)0xFFFFFFFF) + return SZ_ERROR_UNSUPPORTED; + coder->MethodID = (UInt32)id; + + coder->NumStreams = 1; + coder->PropsOffset = 0; + coder->PropsSize = 0; + + if ((mainByte & 0x10) != 0) + { + UInt32 numStreams; + + RINOK(SzReadNumber32(sd, &numStreams)) + if (numStreams > k_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + coder->NumStreams = (Byte)numStreams; + + RINOK(SzReadNumber32(sd, &numStreams)) + if (numStreams != 1) + return SZ_ERROR_UNSUPPORTED; + } + + numInStreams += coder->NumStreams; + + if (numInStreams > k_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + + if ((mainByte & 0x20) != 0) + { + UInt32 propsSize = 0; + RINOK(SzReadNumber32(sd, &propsSize)) + if (propsSize > sd->Size) + return SZ_ERROR_ARCHIVE; + if (propsSize >= 0x80) + return SZ_ERROR_UNSUPPORTED; + coder->PropsOffset = (size_t)(sd->Data - dataStart); + coder->PropsSize = (Byte)propsSize; + sd->Data += (size_t)propsSize; + sd->Size -= (size_t)propsSize; + } + } + + /* + if (numInStreams == 1 && numCoders == 1) + { + f->NumPackStreams = 1; + f->PackStreams[0] = 0; + } + else + */ + { + Byte streamUsed[k_NumCodersStreams_in_Folder_MAX]; + UInt32 numBonds, numPackStreams; + + numBonds = numCoders - 1; + if (numInStreams < numBonds) + return SZ_ERROR_ARCHIVE; + if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + f->NumBonds = numBonds; + + numPackStreams = numInStreams - numBonds; + if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) + return SZ_ERROR_UNSUPPORTED; + f->NumPackStreams = numPackStreams; + + for (i = 0; i < numInStreams; i++) + streamUsed[i] = False; + + if (numBonds != 0) + { + Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX]; + + for (i = 0; i < numCoders; i++) + coderUsed[i] = False; + + for (i = 0; i < numBonds; i++) + { + CSzBond *bp = f->Bonds + i; + + RINOK(SzReadNumber32(sd, &bp->InIndex)) + if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex]) + return SZ_ERROR_ARCHIVE; + streamUsed[bp->InIndex] = True; + + RINOK(SzReadNumber32(sd, &bp->OutIndex)) + if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex]) + return SZ_ERROR_ARCHIVE; + coderUsed[bp->OutIndex] = True; + } + + for (i = 0; i < numCoders; i++) + if (!coderUsed[i]) + { + f->UnpackStream = i; + break; + } + + if (i == numCoders) + return SZ_ERROR_ARCHIVE; + } + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams; i++) + if (!streamUsed[i]) + break; + if (i == numInStreams) + return SZ_ERROR_ARCHIVE; + f->PackStreams[0] = i; + } + else + for (i = 0; i < numPackStreams; i++) + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)) + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + f->PackStreams[i] = index; + } + } + + f->NumCoders = numCoders; + + return SZ_OK; +} + + +static Z7_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) +{ + CSzData sd; + sd = *sd2; + for (; num != 0; num--) + { + Byte firstByte, mask; + unsigned i; + SZ_READ_BYTE_2(firstByte) + if ((firstByte & 0x80) == 0) + continue; + if ((firstByte & 0x40) == 0) + { + if (sd.Size == 0) + return SZ_ERROR_ARCHIVE; + sd.Size--; + sd.Data++; + continue; + } + mask = 0x20; + for (i = 2; i < 8 && (firstByte & mask) != 0; i++) + mask >>= 1; + if (i > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, i) + } + *sd2 = sd; + return SZ_OK; +} + + +#define k_Scan_NumCoders_MAX 64 +#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + + +static SRes ReadUnpackInfo(CSzAr *p, + CSzData *sd2, + UInt32 numFoldersMax, + const CBuf *tempBufs, UInt32 numTempBufs, + ISzAllocPtr alloc) +{ + CSzData sd; + + UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex; + const Byte *startBufPtr; + Byte external; + + RINOK(WaitId(sd2, k7zIdFolder)) + + RINOK(SzReadNumber32(sd2, &numFolders)) + if (numFolders > numFoldersMax) + return SZ_ERROR_UNSUPPORTED; + p->NumFolders = numFolders; + + SZ_READ_BYTE_SD(sd2, external) + if (external == 0) + sd = *sd2; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd2, &index)) + if (index >= numTempBufs) + return SZ_ERROR_ARCHIVE; + sd.Data = tempBufs[index].data; + sd.Size = tempBufs[index].size; + } + + MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc) + MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc) + + startBufPtr = sd.Data; + + packStreamIndex = 0; + numCodersOutStreams = 0; + + for (fo = 0; fo < numFolders; fo++) + { + UInt32 numCoders, ci, numInStreams = 0; + + p->FoCodersOffsets[fo] = (size_t)(sd.Data - startBufPtr); + + RINOK(SzReadNumber32(&sd, &numCoders)) + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (ci = 0; ci < numCoders; ci++) + { + Byte mainByte; + unsigned idSize; + UInt32 coderInStreams; + + SZ_READ_BYTE_2(mainByte) + if ((mainByte & 0xC0) != 0) + return SZ_ERROR_UNSUPPORTED; + idSize = (mainByte & 0xF); + if (idSize > 8) + return SZ_ERROR_UNSUPPORTED; + if (idSize > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, idSize) + + coderInStreams = 1; + + if ((mainByte & 0x10) != 0) + { + UInt32 coderOutStreams; + RINOK(SzReadNumber32(&sd, &coderInStreams)) + RINOK(SzReadNumber32(&sd, &coderOutStreams)) + if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1) + return SZ_ERROR_UNSUPPORTED; + } + + numInStreams += coderInStreams; + + if ((mainByte & 0x20) != 0) + { + UInt32 propsSize; + RINOK(SzReadNumber32(&sd, &propsSize)) + if (propsSize > sd.Size) + return SZ_ERROR_ARCHIVE; + SKIP_DATA2(sd, propsSize) + } + } + + { + UInt32 indexOfMainStream = 0; + UInt32 numPackStreams = 1; + + if (numCoders != 1 || numInStreams != 1) + { + Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX]; + Byte coderUsed[k_Scan_NumCoders_MAX]; + + UInt32 i; + const UInt32 numBonds = numCoders - 1; + if (numInStreams < numBonds) + return SZ_ERROR_ARCHIVE; + + if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) + return SZ_ERROR_UNSUPPORTED; + + for (i = 0; i < numInStreams; i++) + streamUsed[i] = False; + for (i = 0; i < numCoders; i++) + coderUsed[i] = False; + + for (i = 0; i < numBonds; i++) + { + UInt32 index; + + RINOK(SzReadNumber32(&sd, &index)) + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + + RINOK(SzReadNumber32(&sd, &index)) + if (index >= numCoders || coderUsed[index]) + return SZ_ERROR_ARCHIVE; + coderUsed[index] = True; + } + + numPackStreams = numInStreams - numBonds; + + if (numPackStreams != 1) + for (i = 0; i < numPackStreams; i++) + { + UInt32 index; + RINOK(SzReadNumber32(&sd, &index)) + if (index >= numInStreams || streamUsed[index]) + return SZ_ERROR_ARCHIVE; + streamUsed[index] = True; + } + + for (i = 0; i < numCoders; i++) + if (!coderUsed[i]) + { + indexOfMainStream = i; + break; + } + + if (i == numCoders) + return SZ_ERROR_ARCHIVE; + } + + p->FoStartPackStreamIndex[fo] = packStreamIndex; + p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; + p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; + numCodersOutStreams += numCoders; + if (numCodersOutStreams < numCoders) + return SZ_ERROR_UNSUPPORTED; + if (numPackStreams > p->NumPackStreams - packStreamIndex) + return SZ_ERROR_ARCHIVE; + packStreamIndex += numPackStreams; + } + } + + p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; + + { + const size_t dataSize = (size_t)(sd.Data - startBufPtr); + p->FoStartPackStreamIndex[fo] = packStreamIndex; + p->FoCodersOffsets[fo] = dataSize; + MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc) + } + + if (external != 0) + { + if (sd.Size != 0) + return SZ_ERROR_ARCHIVE; + sd = *sd2; + } + + RINOK(WaitId(&sd, k7zIdCodersUnpackSize)) + + MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc) + { + UInt32 i; + for (i = 0; i < numCodersOutStreams; i++) + { + RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)) + } + } + + for (;;) + { + UInt64 type; + RINOK(ReadID(&sd, &type)) + if (type == k7zIdEnd) + { + *sd2 = sd; + return SZ_OK; + } + if (type == k7zIdCRC) + { + RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)) + continue; + } + RINOK(SkipData(&sd)) + } +} + + +UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex) +{ + return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]]; +} + + +typedef struct +{ + UInt32 NumTotalSubStreams; + UInt32 NumSubDigests; + CSzData sdNumSubStreams; + CSzData sdSizes; + CSzData sdCRCs; +} CSubStreamInfo; + + +static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) +{ + UInt64 type = 0; + UInt32 numSubDigests = 0; + const UInt32 numFolders = p->NumFolders; + UInt32 numUnpackStreams = numFolders; + UInt32 numUnpackSizesInData = 0; + + for (;;) + { + RINOK(ReadID(sd, &type)) + if (type == k7zIdNumUnpackStream) + { + UInt32 i; + ssi->sdNumSubStreams.Data = sd->Data; + numUnpackStreams = 0; + numSubDigests = 0; + for (i = 0; i < numFolders; i++) + { + UInt32 numStreams; + RINOK(SzReadNumber32(sd, &numStreams)) + if (numUnpackStreams > numUnpackStreams + numStreams) + return SZ_ERROR_UNSUPPORTED; + numUnpackStreams += numStreams; + if (numStreams != 0) + numUnpackSizesInData += (numStreams - 1); + if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i)) + numSubDigests += numStreams; + } + ssi->sdNumSubStreams.Size = (size_t)(sd->Data - ssi->sdNumSubStreams.Data); + continue; + } + if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd) + break; + RINOK(SkipData(sd)) + } + + if (!ssi->sdNumSubStreams.Data) + { + numSubDigests = numFolders; + if (p->FolderCRCs.Defs) + numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders); + } + + ssi->NumTotalSubStreams = numUnpackStreams; + ssi->NumSubDigests = numSubDigests; + + if (type == k7zIdSize) + { + ssi->sdSizes.Data = sd->Data; + RINOK(SkipNumbers(sd, numUnpackSizesInData)) + ssi->sdSizes.Size = (size_t)(sd->Data - ssi->sdSizes.Data); + RINOK(ReadID(sd, &type)) + } + + for (;;) + { + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + ssi->sdCRCs.Data = sd->Data; + RINOK(SkipBitUi32s(sd, numSubDigests)) + ssi->sdCRCs.Size = (size_t)(sd->Data - ssi->sdCRCs.Data); + } + else + { + RINOK(SkipData(sd)) + } + RINOK(ReadID(sd, &type)) + } +} + +static SRes SzReadStreamsInfo(CSzAr *p, + CSzData *sd, + UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, + UInt64 *dataOffset, + CSubStreamInfo *ssi, + ISzAllocPtr alloc) +{ + UInt64 type; + + SzData_CLEAR(&ssi->sdSizes) + SzData_CLEAR(&ssi->sdCRCs) + SzData_CLEAR(&ssi->sdNumSubStreams) + + *dataOffset = 0; + RINOK(ReadID(sd, &type)) + if (type == k7zIdPackInfo) + { + RINOK(ReadNumber(sd, dataOffset)) + if (*dataOffset > p->RangeLimit) + return SZ_ERROR_ARCHIVE; + RINOK(ReadPackInfo(p, sd, alloc)) + if (p->PackPositions[p->NumPackStreams] > p->RangeLimit - *dataOffset) + return SZ_ERROR_ARCHIVE; + RINOK(ReadID(sd, &type)) + } + if (type == k7zIdUnpackInfo) + { + RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)) + RINOK(ReadID(sd, &type)) + } + if (type == k7zIdSubStreamsInfo) + { + RINOK(ReadSubStreamsInfo(p, sd, ssi)) + RINOK(ReadID(sd, &type)) + } + else + { + ssi->NumTotalSubStreams = p->NumFolders; + // ssi->NumSubDigests = 0; + } + + return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED); +} + +static SRes SzReadAndDecodePackedStreams( + ILookInStreamPtr inStream, + CSzData *sd, + CBuf *tempBufs, + UInt32 numFoldersMax, + UInt64 baseOffset, + CSzAr *p, + ISzAllocPtr allocTemp) +{ + UInt64 dataStartPos; + UInt32 fo; + CSubStreamInfo ssi; + + RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)) + + dataStartPos += baseOffset; + if (p->NumFolders == 0) + return SZ_ERROR_ARCHIVE; + + for (fo = 0; fo < p->NumFolders; fo++) + Buf_Init(tempBufs + fo); + + for (fo = 0; fo < p->NumFolders; fo++) + { + CBuf *tempBuf = tempBufs + fo; + const UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); + if ((size_t)unpackSize != unpackSize) + return SZ_ERROR_MEM; + if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) + return SZ_ERROR_MEM; + } + + for (fo = 0; fo < p->NumFolders; fo++) + { + const CBuf *tempBuf = tempBufs + fo; + RINOK(LookInStream_SeekTo(inStream, dataStartPos)) + RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)) + } + + return SZ_OK; +} + +static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets) +{ + size_t pos = 0; + *offsets++ = 0; + if (numFiles == 0) + return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE; + if (size < 2) + return SZ_ERROR_ARCHIVE; + if (data[size - 2] != 0 || data[size - 1] != 0) + return SZ_ERROR_ARCHIVE; + do + { + const Byte *p; + if (pos == size) + return SZ_ERROR_ARCHIVE; + for (p = data + pos; + #ifdef _WIN32 + *(const UInt16 *)(const void *)p != 0 + #else + p[0] != 0 || p[1] != 0 + #endif + ; p += 2); + pos = (size_t)(p - data) + 2; + *offsets++ = (pos >> 1); + } + while (--numFiles); + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, + CSzData *sd2, + const CBuf *tempBufs, UInt32 numTempBufs, + ISzAllocPtr alloc) +{ + CSzData sd; + UInt32 i; + CNtfsFileTime *vals; + Byte *defs; + Byte external; + + RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)) + + SZ_READ_BYTE_SD(sd2, external) + if (external == 0) + sd = *sd2; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd2, &index)) + if (index >= numTempBufs) + return SZ_ERROR_ARCHIVE; + sd.Data = tempBufs[index].data; + sd.Size = tempBufs[index].size; + } + + MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc) + vals = p->Vals; + defs = p->Defs; + for (i = 0; i < num; i++) + if (SzBitArray_Check(defs, i)) + { + if (sd.Size < 8) + return SZ_ERROR_ARCHIVE; + vals[i].Low = GetUi32(sd.Data); + vals[i].High = GetUi32(sd.Data + 4); + SKIP_DATA2(sd, 8) + } + else + vals[i].High = vals[i].Low = 0; + + if (external == 0) + *sd2 = sd; + + return SZ_OK; +} + + +#define NUM_ADDITIONAL_STREAMS_MAX 8 + + +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ + CSzData *sd, + ILookInStreamPtr inStream, + CBuf *tempBufs, UInt32 *numTempBufs, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp + ) +{ + CSubStreamInfo ssi; + +{ + UInt64 type; + + SzData_CLEAR(&ssi.sdSizes) + SzData_CLEAR(&ssi.sdCRCs) + SzData_CLEAR(&ssi.sdNumSubStreams) + + ssi.NumSubDigests = 0; + ssi.NumTotalSubStreams = 0; + + RINOK(ReadID(sd, &type)) + + if (type == k7zIdArchiveProperties) + { + for (;;) + { + UInt64 type2; + RINOK(ReadID(sd, &type2)) + if (type2 == k7zIdEnd) + break; + RINOK(SkipData(sd)) + } + RINOK(ReadID(sd, &type)) + } + + if (type == k7zIdAdditionalStreamsInfo) + { + CSzAr tempAr; + SRes res; + + SzAr_Init(&tempAr); + tempAr.RangeLimit = p->db.RangeLimit; + + res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX, + p->startPosAfterHeader, &tempAr, allocTemp); + *numTempBufs = tempAr.NumFolders; + SzAr_Free(&tempAr, allocTemp); + + if (res != SZ_OK) + return res; + RINOK(ReadID(sd, &type)) + } + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, + &p->dataPos, &ssi, allocMain)) + p->dataPos += p->startPosAfterHeader; + RINOK(ReadID(sd, &type)) + } + + if (type == k7zIdEnd) + { + return SZ_OK; + } + + if (type != k7zIdFilesInfo) + return SZ_ERROR_ARCHIVE; +} + +{ + UInt32 numFiles = 0; + UInt32 numEmptyStreams = 0; + const Byte *emptyStreams = NULL; + const Byte *emptyFiles = NULL; + + RINOK(SzReadNumber32(sd, &numFiles)) + p->NumFiles = numFiles; + + for (;;) + { + UInt64 type; + UInt64 size; + RINOK(ReadID(sd, &type)) + if (type == k7zIdEnd) + break; + RINOK(ReadNumber(sd, &size)) + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + + if (type >= ((UInt32)1 << 8)) + { + SKIP_DATA(sd, size) + } + else switch ((unsigned)type) + { + case k7zIdName: + { + size_t namesSize; + const Byte *namesData; + Byte external; + + SZ_READ_BYTE(external) + if (external == 0) + { + namesSize = (size_t)size - 1; + namesData = sd->Data; + } + else + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)) + if (index >= *numTempBufs) + return SZ_ERROR_ARCHIVE; + namesData = (tempBufs)[index].data; + namesSize = (tempBufs)[index].size; + } + + if ((namesSize & 1) != 0) + return SZ_ERROR_ARCHIVE; + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain) + MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain) + RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) + if (external == 0) + { + SKIP_DATA(sd, namesSize) + } + break; + } + case k7zIdEmptyStream: + { + RINOK(RememberBitVector(sd, numFiles, &emptyStreams)) + numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); + emptyFiles = NULL; + break; + } + case k7zIdEmptyFile: + { + RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)) + break; + } + case k7zIdWinAttrib: + { + Byte external; + CSzData sdSwitch; + CSzData *sdPtr; + SzBitUi32s_Free(&p->Attribs, allocMain); + RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)) + + SZ_READ_BYTE(external) + if (external == 0) + sdPtr = sd; + else + { + UInt32 index; + RINOK(SzReadNumber32(sd, &index)) + if (index >= *numTempBufs) + return SZ_ERROR_ARCHIVE; + sdSwitch.Data = (tempBufs)[index].data; + sdSwitch.Size = (tempBufs)[index].size; + sdPtr = &sdSwitch; + } + RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)) + break; + } + /* + case k7zParent: + { + SzBitUi32s_Free(&p->Parents, allocMain); + RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain)); + RINOK(SzReadSwitch(sd)); + RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain)); + break; + } + */ + case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; + case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; + default: + { + SKIP_DATA(sd, size) + } + } + } + + if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams) + return SZ_ERROR_ARCHIVE; + + for (;;) + { + UInt64 type; + RINOK(ReadID(sd, &type)) + if (type == k7zIdEnd) + break; + RINOK(SkipData(sd)) + } + + { + UInt32 i; + UInt32 emptyFileIndex = 0; + UInt32 folderIndex = 0; + UInt32 remSubStreams = 0; + UInt32 numSubStreams = 0; + UInt64 unpackPos = 0; + const Byte *digestsDefs = NULL; + const Byte *digestsVals = NULL; + UInt32 digestIndex = 0; + Byte isDirMask = 0; + Byte crcMask = 0; + Byte mask = 0x80; + + MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain) + MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain) + MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain) + MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain) + + RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)) + + if (ssi.sdCRCs.Size != 0) + { + Byte allDigestsDefined = 0; + SZ_READ_BYTE_SD_NOCHECK(&ssi.sdCRCs, allDigestsDefined) + if (allDigestsDefined) + digestsVals = ssi.sdCRCs.Data; + else + { + const size_t numBytes = (ssi.NumSubDigests + 7) >> 3; + digestsDefs = ssi.sdCRCs.Data; + digestsVals = digestsDefs + numBytes; + } + } + + for (i = 0; i < numFiles; i++, mask >>= 1) + { + if (mask == 0) + { + const UInt32 byteIndex = (i - 1) >> 3; + p->IsDirs[byteIndex] = isDirMask; + p->CRCs.Defs[byteIndex] = crcMask; + isDirMask = 0; + crcMask = 0; + mask = 0x80; + } + + p->UnpackPositions[i] = unpackPos; + p->CRCs.Vals[i] = 0; + + if (emptyStreams && SzBitArray_Check(emptyStreams, i)) + { + if (emptyFiles) + { + if (!SzBitArray_Check(emptyFiles, emptyFileIndex)) + isDirMask |= mask; + emptyFileIndex++; + } + else + isDirMask |= mask; + if (remSubStreams == 0) + { + p->FileToFolder[i] = (UInt32)-1; + continue; + } + } + + if (remSubStreams == 0) + { + for (;;) + { + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderToFile[folderIndex] = i; + numSubStreams = 1; + if (ssi.sdNumSubStreams.Data) + { + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) + } + remSubStreams = numSubStreams; + if (numSubStreams != 0) + break; + { + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + unpackPos += folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + } + folderIndex++; + } + } + + p->FileToFolder[i] = folderIndex; + + if (emptyStreams && SzBitArray_Check(emptyStreams, i)) + continue; + + if (--remSubStreams == 0) + { + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; + if (folderUnpackSize < unpackPos - startFolderUnpackPos) + return SZ_ERROR_ARCHIVE; + unpackPos = startFolderUnpackPos + folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + + if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex)) + { + p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; + crcMask |= mask; + } + folderIndex++; + } + else + { + UInt64 v; + RINOK(ReadNumber(&ssi.sdSizes, &v)) + unpackPos += v; + if (unpackPos < v) + return SZ_ERROR_ARCHIVE; + } + if ((crcMask & mask) == 0 && digestsVals) + { + if (!digestsDefs || SzBitArray_Check(digestsDefs, digestIndex)) + { + p->CRCs.Vals[i] = GetUi32(digestsVals); + digestsVals += 4; + crcMask |= mask; + } + digestIndex++; + } + } + + if (mask != 0x80) + { + const UInt32 byteIndex = (i - 1) >> 3; + p->IsDirs[byteIndex] = isDirMask; + p->CRCs.Defs[byteIndex] = crcMask; + } + + p->UnpackPositions[i] = unpackPos; + + if (remSubStreams != 0) + return SZ_ERROR_ARCHIVE; + + for (;;) + { + p->FolderToFile[folderIndex] = i; + if (folderIndex >= p->db.NumFolders) + break; + if (!ssi.sdNumSubStreams.Data) + return SZ_ERROR_ARCHIVE; + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) + if (numSubStreams != 0) + return SZ_ERROR_ARCHIVE; + /* + { + UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + unpackPos += folderUnpackSize; + if (unpackPos < folderUnpackSize) + return SZ_ERROR_ARCHIVE; + } + */ + folderIndex++; + } + + if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0) + return SZ_ERROR_ARCHIVE; + } +} + return SZ_OK; +} + + +static SRes SzReadHeader( + CSzArEx *p, + CSzData *sd, + ILookInStreamPtr inStream, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + UInt32 i; + UInt32 numTempBufs = 0; + SRes res; + CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX]; + + for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) + Buf_Init(tempBufs + i); + + res = SzReadHeader2(p, sd, inStream, + tempBufs, &numTempBufs, + allocMain, allocTemp); + + for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) + Buf_Free(tempBufs + i, allocTemp); + + RINOK(res) + + if (sd->Size != 0) + return SZ_ERROR_FAIL; + + return res; +} + +static SRes SzArEx_Open2( + CSzArEx *p, + ILookInStreamPtr inStream, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + Byte header[k7zStartHeaderSize]; + Int64 startArcPos; + UInt64 nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; + UInt32 nextHeaderCRC; + CBuf buf; + SRes res; + + startArcPos = 0; + RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)) + + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)) + + if (!TestSignatureCandidate(header)) + return SZ_ERROR_NO_ARCHIVE; + if (header[6] != k7zMajorVersion) + return SZ_ERROR_UNSUPPORTED; + + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); + + p->startPosAfterHeader = (UInt64)startArcPos + k7zStartHeaderSize; + + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) + return SZ_ERROR_CRC; + + p->db.RangeLimit = nextHeaderOffset; + + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) + return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + Int64 pos = 0; + RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)) + if ((UInt64)pos < (UInt64)startArcPos + nextHeaderOffset || + (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset || + (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } + + RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset)) + + if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) + return SZ_ERROR_MEM; + + res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT); + + if (res == SZ_OK) + { + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC) + { + CSzData sd; + UInt64 type; + sd.Data = buf.data; + sd.Size = buf.size; + + res = ReadID(&sd, &type); + + if (res == SZ_OK && type == k7zIdEncodedHeader) + { + CSzAr tempAr; + CBuf tempBuf; + Buf_Init(&tempBuf); + + SzAr_Init(&tempAr); + tempAr.RangeLimit = p->db.RangeLimit; + + res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp); + SzAr_Free(&tempAr, allocTemp); + + if (res != SZ_OK) + { + Buf_Free(&tempBuf, allocTemp); + } + else + { + Buf_Free(&buf, allocTemp); + buf.data = tempBuf.data; + buf.size = tempBuf.size; + sd.Data = buf.data; + sd.Size = buf.size; + res = ReadID(&sd, &type); + } + } + + if (res == SZ_OK) + { + if (type == k7zIdHeader) + { + /* + CSzData sd2; + unsigned ttt; + for (ttt = 0; ttt < 40000; ttt++) + { + SzArEx_Free(p, allocMain); + sd2 = sd; + res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp); + if (res != SZ_OK) + break; + } + */ + res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp); + } + else + res = SZ_ERROR_UNSUPPORTED; + } + } + } + + Buf_Free(&buf, allocTemp); + return res; +} + + +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, + ISzAllocPtr allocMain, ISzAllocPtr allocTemp) +{ + const SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + if (res != SZ_OK) + SzArEx_Free(p, allocMain); + return res; +} + + +SRes SzArEx_Extract( + const CSzArEx *p, + ILookInStreamPtr inStream, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **tempBuf, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAllocPtr allocMain, + ISzAllocPtr allocTemp) +{ + const UInt32 folderIndex = p->FileToFolder[fileIndex]; + SRes res = SZ_OK; + + *offset = 0; + *outSizeProcessed = 0; + + if (folderIndex == (UInt32)-1) + { + ISzAlloc_Free(allocMain, *tempBuf); + *blockIndex = folderIndex; + *tempBuf = NULL; + *outBufferSize = 0; + return SZ_OK; + } + + if (*tempBuf == NULL || *blockIndex != folderIndex) + { + const UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + /* + UInt64 unpackSizeSpec = + p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] - + p->UnpackPositions[p->FolderToFile[folderIndex]]; + */ + const size_t unpackSize = (size_t)unpackSizeSpec; + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + ISzAlloc_Free(allocMain, *tempBuf); + *tempBuf = NULL; + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize); + if (*tempBuf == NULL) + res = SZ_ERROR_MEM; + } + + if (res == SZ_OK) + { + res = SzAr_DecodeFolder(&p->db, folderIndex, + inStream, p->dataPos, *tempBuf, unpackSize, allocTemp); + } + } + } + + if (res == SZ_OK) + { + const UInt64 unpackPos = p->UnpackPositions[fileIndex]; + *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); + *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos); + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + if (SzBitWithVals_Check(&p->CRCs, fileIndex)) + if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex]) + res = SZ_ERROR_CRC; + } + + return res; +} + + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + const size_t offs = p->FileNameOffsets[fileIndex]; + const size_t len = p->FileNameOffsets[fileIndex + 1] - offs; + if (dest != 0) + { + size_t i; + const Byte *src = p->FileNames + offs * 2; + for (i = 0; i < len; i++) + dest[i] = GetUi16(src + i * 2); + } + return len; +} + +/* +size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex) +{ + size_t len; + if (!p->FileNameOffsets) + return 1; + len = 0; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + if SzBitWithVals_Check(&p->Parents, fileIndex) + parent = p->Parents.Vals[fileIndex]; + if (parent == (UInt32)(Int32)-1) + return len; + fileIndex = parent; + } +} + +UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest) +{ + BoolInt needSlash; + if (!p->FileNameOffsets) + { + *(--dest) = 0; + return dest; + } + needSlash = False; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen); + if (needSlash) + *(dest - 1) = '/'; + needSlash = True; + dest -= curLen; + + if SzBitWithVals_Check(&p->Parents, fileIndex) + parent = p->Parents.Vals[fileIndex]; + if (parent == (UInt32)(Int32)-1) + return dest; + fileIndex = parent; + } +} +*/ diff -Nru p7zip-rar-16.02/C/7zBuf.c p7zip-rar-16.02+really25.00+ds/C/7zBuf.c --- p7zip-rar-16.02/C/7zBuf.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zBuf.c 2017-04-03 13:00:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* 7zBuf.c -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zBuf.h" + +void Buf_Init(CBuf *p) +{ + p->data = 0; + p->size = 0; +} + +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc) +{ + p->size = 0; + if (size == 0) + { + p->data = 0; + return 1; + } + p->data = (Byte *)ISzAlloc_Alloc(alloc, size); + if (p->data) + { + p->size = size; + return 1; + } + return 0; +} + +void Buf_Free(CBuf *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->data); + p->data = 0; + p->size = 0; +} diff -Nru p7zip-rar-16.02/C/7zBuf.h p7zip-rar-16.02+really25.00+ds/C/7zBuf.h --- p7zip-rar-16.02/C/7zBuf.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zBuf.h 2023-03-04 11:00:00.000000000 +0000 @@ -1,35 +1,35 @@ -/* 7zBuf.h -- Byte Buffer -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_BUF_H -#define __7Z_BUF_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -typedef struct -{ - Byte *data; - size_t size; -} CBuf; - -void Buf_Init(CBuf *p); -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); -void Buf_Free(CBuf *p, ISzAlloc *alloc); - -typedef struct -{ - Byte *data; - size_t size; - size_t pos; -} CDynBuf; - -void DynBuf_Construct(CDynBuf *p); -void DynBuf_SeekToBeg(CDynBuf *p); -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); - -EXTERN_C_END - -#endif +/* 7zBuf.h -- Byte Buffer +2023-03-04 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_BUF_H +#define ZIP7_INC_7Z_BUF_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef struct +{ + Byte *data; + size_t size; +} CBuf; + +void Buf_Init(CBuf *p); +int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc); +void Buf_Free(CBuf *p, ISzAllocPtr alloc); + +typedef struct +{ + Byte *data; + size_t size; + size_t pos; +} CDynBuf; + +void DynBuf_Construct(CDynBuf *p); +void DynBuf_SeekToBeg(CDynBuf *p); +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc); +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/7zBuf2.c p7zip-rar-16.02+really25.00+ds/C/7zBuf2.c --- p7zip-rar-16.02/C/7zBuf2.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zBuf2.c 2017-04-03 13:00:00.000000000 +0000 @@ -1,51 +1,52 @@ -/* 7zBuf2.c -- Byte Buffer -2014-08-22 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zBuf.h" - -void DynBuf_Construct(CDynBuf *p) -{ - p->data = 0; - p->size = 0; - p->pos = 0; -} - -void DynBuf_SeekToBeg(CDynBuf *p) -{ - p->pos = 0; -} - -int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) -{ - if (size > p->size - p->pos) - { - size_t newSize = p->pos + size; - Byte *data; - newSize += newSize / 4; - data = (Byte *)alloc->Alloc(alloc, newSize); - if (data == 0) - return 0; - p->size = newSize; - memcpy(data, p->data, p->pos); - alloc->Free(alloc, p->data); - p->data = data; - } - if (size != 0) - { - memcpy(p->data + p->pos, buf, size); - p->pos += size; - } - return 1; -} - -void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; - p->pos = 0; -} +/* 7zBuf2.c -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zBuf.h" + +void DynBuf_Construct(CDynBuf *p) +{ + p->data = 0; + p->size = 0; + p->pos = 0; +} + +void DynBuf_SeekToBeg(CDynBuf *p) +{ + p->pos = 0; +} + +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + if (size > p->size - p->pos) + { + size_t newSize = p->pos + size; + Byte *data; + newSize += newSize / 4; + data = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!data) + return 0; + p->size = newSize; + if (p->pos != 0) + memcpy(data, p->data, p->pos); + ISzAlloc_Free(alloc, p->data); + p->data = data; + } + if (size != 0) + { + memcpy(p->data + p->pos, buf, size); + p->pos += size; + } + return 1; +} + +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->data); + p->data = 0; + p->size = 0; + p->pos = 0; +} diff -Nru p7zip-rar-16.02/C/7zCrc.c p7zip-rar-16.02+really25.00+ds/C/7zCrc.c --- p7zip-rar-16.02/C/7zCrc.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zCrc.c 2024-03-01 06:00:00.000000000 +0000 @@ -1,128 +1,420 @@ -/* 7zCrc.c -- CRC32 init -2015-03-10 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zCrc.h" -#include "CpuArch.h" - -#define kCrcPoly 0xEDB88320 - -#ifdef MY_CPU_LE - #define CRC_NUM_TABLES 8 -#else - #define CRC_NUM_TABLES 9 - - #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - - UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); -#endif - -#ifndef MY_CPU_BE - UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); -#endif - -typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); - -CRC_FUNC g_CrcUpdateT4; -CRC_FUNC g_CrcUpdateT8; -CRC_FUNC g_CrcUpdate; - -UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; - -UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) -{ - return g_CrcUpdate(v, data, size, g_CrcTable); -} - -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) -{ - return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; -} - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - const Byte *pEnd = p + size; - for (; p != pEnd; p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -void MY_FAST_CALL CrcGenerateTable() -{ - UInt32 i; - for (i = 0; i < 256; i++) - { - UInt32 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - g_CrcTable[i] = r; - } - for (; i < 256 * CRC_NUM_TABLES; i++) - { - UInt32 r = g_CrcTable[i - 256]; - g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); - } - - #if CRC_NUM_TABLES < 4 - - g_CrcUpdate = CrcUpdateT1; - - #else - - #ifdef MY_CPU_LE - - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT8; - - #ifdef MY_CPU_X86_OR_AMD64 - if (!CPU_Is_InOrder()) - g_CrcUpdate = CrcUpdateT8; - #endif - #endif - - #else - { - #ifndef MY_CPU_BE - UInt32 k = 0x01020304; - const Byte *p = (const Byte *)&k; - if (p[0] == 4 && p[1] == 3) - { - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT8; - // g_CrcUpdate = CrcUpdateT8; - #endif - } - else if (p[0] != 1 || p[1] != 2) - g_CrcUpdate = CrcUpdateT1; - else - #endif - { - for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) - { - UInt32 x = g_CrcTable[i - 256]; - g_CrcTable[i] = CRC_UINT32_SWAP(x); - } - g_CrcUpdateT4 = CrcUpdateT1_BeT4; - g_CrcUpdate = CrcUpdateT1_BeT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT1_BeT8; - // g_CrcUpdate = CrcUpdateT1_BeT8; - #endif - } - } - #endif - - #endif -} +/* 7zCrc.c -- CRC32 calculation and init +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zCrc.h" +#include "CpuArch.h" + +// for debug: +// #define __ARM_FEATURE_CRC32 1 + +#ifdef __ARM_FEATURE_CRC32 +// #pragma message("__ARM_FEATURE_CRC32") +#define Z7_CRC_HW_FORCE +#endif + +// #define Z7_CRC_DEBUG_BE +#ifdef Z7_CRC_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +#ifdef Z7_CRC_HW_FORCE + #define Z7_CRC_NUM_TABLES_USE 1 +#else +#ifdef Z7_CRC_NUM_TABLES + #define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES +#else + #define Z7_CRC_NUM_TABLES_USE 12 +#endif +#endif + +#if Z7_CRC_NUM_TABLES_USE < 1 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif + +#if defined(MY_CPU_LE) || (Z7_CRC_NUM_TABLES_USE == 1) + #define Z7_CRC_NUM_TABLES_TOTAL Z7_CRC_NUM_TABLES_USE +#else + #define Z7_CRC_NUM_TABLES_TOTAL (Z7_CRC_NUM_TABLES_USE + 1) +#endif + +#ifndef Z7_CRC_HW_FORCE + +#if Z7_CRC_NUM_TABLES_USE == 1 \ + || (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#define Z7_CRC_UPDATE_T1_FUNC_NAME CrcUpdateGT1 +static UInt32 Z7_FASTCALL Z7_CRC_UPDATE_T1_FUNC_NAME(UInt32 v, const void *data, size_t size) +{ + const UInt32 *table = g_CrcTable; + const Byte *p = (const Byte *)data; + const Byte *lim = p + size; + for (; p != lim; p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} +#endif + + +#if Z7_CRC_NUM_TABLES_USE != 1 +#ifndef MY_CPU_BE + #define FUNC_NAME_LE_2(s) CrcUpdateT ## s + #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s) + #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC_NUM_TABLES_USE) + UInt32 Z7_FASTCALL FUNC_NAME_LE (UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif +#ifndef MY_CPU_LE + #define FUNC_NAME_BE_2(s) CrcUpdateT1_BeT ## s + #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s) + #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC_NUM_TABLES_USE) + UInt32 Z7_FASTCALL FUNC_NAME_BE (UInt32 v, const void *data, size_t size, const UInt32 *table); +#endif +#endif + +#endif // Z7_CRC_HW_FORCE + +/* ---------- hardware CRC ---------- */ + +#ifdef MY_CPU_LE + +#if defined(MY_CPU_ARM_OR_ARM64) +// #pragma message("ARM*") + + #if (defined(__clang__) && (__clang_major__ >= 3)) \ + || defined(__GNUC__) && (__GNUC__ >= 6) && defined(MY_CPU_ARM64) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #if !defined(__ARM_FEATURE_CRC32) +// #pragma message("!defined(__ARM_FEATURE_CRC32)") +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define __ARM_FEATURE_CRC32 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRC32_WAS_SET + #if defined(__clang__) + #if defined(MY_CPU_ARM64) + #define ATTRIB_CRC __attribute__((__target__("crc"))) + #else + #define ATTRIB_CRC __attribute__((__target__("armv8-a,crc"))) + #endif + #else + #if defined(MY_CPU_ARM64) +#if !defined(Z7_GCC_VERSION) || (Z7_GCC_VERSION >= 60000) + #define ATTRIB_CRC __attribute__((__target__("+crc"))) +#endif + #else +#if !defined(Z7_GCC_VERSION) || (__GNUC__ >= 8) +#if defined(__ARM_FP) && __GNUC__ >= 8 +// for -mfloat-abi=hard: similar to + #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc+simd"))) +#else + #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc"))) +#endif +#endif + #endif + #endif + #endif + #if defined(__ARM_FEATURE_CRC32) + // #pragma message("") +/* +arm_acle.h (GGC): + before Nov 17, 2017: +#ifdef __ARM_FEATURE_CRC32 + + Nov 17, 2017: gcc10.0 (gcc 9.2.0) checked" +#if __ARM_ARCH >= 8 +#pragma GCC target ("arch=armv8-a+crc") + + Aug 22, 2019: GCC 8.4?, 9.2.1, 10.1: +#ifdef __ARM_FEATURE_CRC32 +#ifdef __ARM_FP +#pragma GCC target ("arch=armv8-a+crc+simd") +#else +#pragma GCC target ("arch=armv8-a+crc") +#endif +*/ +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 +#if defined(Z7_GCC_VERSION) && (__GNUC__ == 8) && (Z7_GCC_VERSION < 80400) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 9) && (Z7_GCC_VERSION < 90201) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 10) && (Z7_GCC_VERSION < 100100) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") +#undef __ARM_ARCH +#define __ARM_ARCH 8 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif + #define Z7_CRC_HW_USE + #include + #endif + #elif defined(_MSC_VER) + #if defined(MY_CPU_ARM64) + #if (_MSC_VER >= 1910) + #ifdef __clang__ + // #define Z7_CRC_HW_USE + // #include + #else + #define Z7_CRC_HW_USE + #include + #endif + #endif + #endif + #endif + +#else // non-ARM* + +// #define Z7_CRC_HW_USE // for debug : we can test HW-branch of code +#ifdef Z7_CRC_HW_USE +#include "7zCrcEmu.h" +#endif + +#endif // non-ARM* + + + +#if defined(Z7_CRC_HW_USE) + +// #pragma message("USE ARM HW CRC") + +#ifdef MY_CPU_64BIT + #define CRC_HW_WORD_TYPE UInt64 + #define CRC_HW_WORD_FUNC __crc32d +#else + #define CRC_HW_WORD_TYPE UInt32 + #define CRC_HW_WORD_FUNC __crc32w +#endif + +#define CRC_HW_UNROLL_BYTES (sizeof(CRC_HW_WORD_TYPE) * 4) + +#ifdef ATTRIB_CRC + ATTRIB_CRC +#endif +Z7_NO_INLINE +#ifdef Z7_CRC_HW_FORCE + UInt32 Z7_FASTCALL CrcUpdate +#else + static UInt32 Z7_FASTCALL CrcUpdate_HW +#endif + (UInt32 v, const void *data, size_t size) +{ + const Byte *p = (const Byte *)data; + for (; size != 0 && ((unsigned)(ptrdiff_t)p & (CRC_HW_UNROLL_BYTES - 1)) != 0; size--) + v = __crc32b(v, *p++); + if (size >= CRC_HW_UNROLL_BYTES) + { + const Byte *lim = p + size; + size &= CRC_HW_UNROLL_BYTES - 1; + lim -= size; + do + { + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p)); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE))); + p += 2 * sizeof(CRC_HW_WORD_TYPE); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p)); + v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE))); + p += 2 * sizeof(CRC_HW_WORD_TYPE); + } + while (p != lim); + } + + for (; size != 0; size--) + v = __crc32b(v, *p++); + + return v; +} + +#ifdef Z7_ARM_FEATURE_CRC32_WAS_SET +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#undef __ARM_FEATURE_CRC32 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#undef Z7_ARM_FEATURE_CRC32_WAS_SET +#endif + +#endif // defined(Z7_CRC_HW_USE) +#endif // MY_CPU_LE + + + +#ifndef Z7_CRC_HW_FORCE + +#if defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) +/* +typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_WITH_TABLE_FUNC) + (UInt32 v, const void *data, size_t size, const UInt32 *table); +Z7_CRC_UPDATE_WITH_TABLE_FUNC g_CrcUpdate; +*/ +static unsigned g_Crc_Algo; +#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) +static unsigned g_Crc_Be; +#endif +#endif // defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) + + + +Z7_NO_INLINE +#ifdef Z7_CRC_HW_USE + static UInt32 Z7_FASTCALL CrcUpdate_Base +#else + UInt32 Z7_FASTCALL CrcUpdate +#endif + (UInt32 crc, const void *data, size_t size) +{ +#if Z7_CRC_NUM_TABLES_USE == 1 + return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size); +#else // Z7_CRC_NUM_TABLES_USE != 1 +#ifdef Z7_CRC_UPDATE_T1_FUNC_NAME + if (g_Crc_Algo == 1) + return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size); +#endif + +#ifdef MY_CPU_LE + return FUNC_NAME_LE(crc, data, size, g_CrcTable); +#elif defined(MY_CPU_BE) + return FUNC_NAME_BE(crc, data, size, g_CrcTable); +#else + if (g_Crc_Be) + return FUNC_NAME_BE(crc, data, size, g_CrcTable); + else + return FUNC_NAME_LE(crc, data, size, g_CrcTable); +#endif +#endif // Z7_CRC_NUM_TABLES_USE != 1 +} + + +#ifdef Z7_CRC_HW_USE +Z7_NO_INLINE +UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size) +{ + if (g_Crc_Algo == 0) + return CrcUpdate_HW(crc, data, size); + return CrcUpdate_Base(crc, data, size); +} +#endif + +#endif // !defined(Z7_CRC_HW_FORCE) + + + +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size) +{ + return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL; +} + + +MY_ALIGN(64) +UInt32 g_CrcTable[256 * Z7_CRC_NUM_TABLES_TOTAL]; + + +void Z7_FASTCALL CrcGenerateTable(void) +{ + UInt32 i; + for (i = 0; i < 256; i++) + { +#if defined(Z7_CRC_HW_FORCE) + g_CrcTable[i] = __crc32b(i, 0); +#else + #define kCrcPoly 0xEDB88320 + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + g_CrcTable[i] = r; +#endif + } + for (i = 256; i < 256 * Z7_CRC_NUM_TABLES_USE; i++) + { + const UInt32 r = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); + } + +#if !defined(Z7_CRC_HW_FORCE) && \ + (defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) || defined(MY_CPU_BE)) + +#if Z7_CRC_NUM_TABLES_USE <= 1 + g_Crc_Algo = 1; +#else // Z7_CRC_NUM_TABLES_USE <= 1 + +#if defined(MY_CPU_LE) + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; +#else // !defined(MY_CPU_LE) + { +#ifndef MY_CPU_BE + UInt32 k = 0x01020304; + const Byte *p = (const Byte *)&k; + if (p[0] == 4 && p[1] == 3) + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; + else if (p[0] != 1 || p[1] != 2) + g_Crc_Algo = 1; + else +#endif // MY_CPU_BE + { + for (i = 256 * Z7_CRC_NUM_TABLES_TOTAL - 1; i >= 256; i--) + { + const UInt32 x = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = Z7_BSWAP32(x); + } +#if defined(Z7_CRC_UPDATE_T1_FUNC_NAME) + g_Crc_Algo = Z7_CRC_NUM_TABLES_USE; +#endif +#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) + g_Crc_Be = 1; +#endif + } + } +#endif // !defined(MY_CPU_LE) + +#ifdef MY_CPU_LE +#ifdef Z7_CRC_HW_USE + if (CPU_IsSupported_CRC32()) + g_Crc_Algo = 0; +#endif // Z7_CRC_HW_USE +#endif // MY_CPU_LE + +#endif // Z7_CRC_NUM_TABLES_USE <= 1 +#endif // g_Crc_Algo was declared +} + +Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo) +{ + if (algo == 0) + return &CrcUpdate; + +#if defined(Z7_CRC_HW_USE) + if (algo == sizeof(CRC_HW_WORD_TYPE) * 8) + { +#ifdef Z7_CRC_HW_FORCE + return &CrcUpdate; +#else + if (g_Crc_Algo == 0) + return &CrcUpdate_HW; +#endif + } +#endif + +#ifndef Z7_CRC_HW_FORCE + if (algo == Z7_CRC_NUM_TABLES_USE) + return + #ifdef Z7_CRC_HW_USE + &CrcUpdate_Base; + #else + &CrcUpdate; + #endif +#endif + + return NULL; +} + +#undef kCrcPoly +#undef Z7_CRC_NUM_TABLES_USE +#undef Z7_CRC_NUM_TABLES_TOTAL +#undef CRC_UPDATE_BYTE_2 +#undef FUNC_NAME_LE_2 +#undef FUNC_NAME_LE_1 +#undef FUNC_NAME_LE +#undef FUNC_NAME_BE_2 +#undef FUNC_NAME_BE_1 +#undef FUNC_NAME_BE + +#undef CRC_HW_UNROLL_BYTES +#undef CRC_HW_WORD_FUNC +#undef CRC_HW_WORD_TYPE diff -Nru p7zip-rar-16.02/C/7zCrc.h p7zip-rar-16.02+really25.00+ds/C/7zCrc.h --- p7zip-rar-16.02/C/7zCrc.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zCrc.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,25 +1,28 @@ -/* 7zCrc.h -- CRC32 calculation -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __7Z_CRC_H -#define __7Z_CRC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -extern UInt32 g_CrcTable[]; - -/* Call CrcGenerateTable one time before other CRC functions */ -void MY_FAST_CALL CrcGenerateTable(void); - -#define CRC_INIT_VAL 0xFFFFFFFF -#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) -#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); - -EXTERN_C_END - -#endif +/* 7zCrc.h -- CRC32 calculation +2024-01-22 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_CRC_H +#define ZIP7_INC_7Z_CRC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +extern UInt32 g_CrcTable[]; + +/* Call CrcGenerateTable one time before other CRC functions */ +void Z7_FASTCALL CrcGenerateTable(void); + +#define CRC_INIT_VAL 0xFFFFFFFF +#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size); + +typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_FUNC)(UInt32 v, const void *data, size_t size); +Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/7zCrcOpt.c p7zip-rar-16.02+really25.00+ds/C/7zCrcOpt.c --- p7zip-rar-16.02/C/7zCrcOpt.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zCrcOpt.c 2023-12-07 17:00:00.000000000 +0000 @@ -1,115 +1,199 @@ -/* 7zCrcOpt.c -- CRC32 calculation -2015-03-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#ifndef MY_CPU_BE - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)p; - v = - table[0x300 + ((v ) & 0xFF)] - ^ table[0x200 + ((v >> 8) & 0xFF)] - ^ table[0x100 + ((v >> 16) & 0xFF)] - ^ table[0x000 + ((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 8; size -= 8, p += 8) - { - UInt32 d; - v ^= *(const UInt32 *)p; - v = - table[0x700 + ((v ) & 0xFF)] - ^ table[0x600 + ((v >> 8) & 0xFF)] - ^ table[0x500 + ((v >> 16) & 0xFF)] - ^ table[0x400 + ((v >> 24))]; - d = *((const UInt32 *)p + 1); - v ^= - table[0x300 + ((d ) & 0xFF)] - ^ table[0x200 + ((d >> 8) & 0xFF)] - ^ table[0x100 + ((d >> 16) & 0xFF)] - ^ table[0x000 + ((d >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#endif - - -#ifndef MY_CPU_LE - -#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - -#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8)) - -UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - table += 0x100; - v = CRC_UINT32_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const UInt32 *)p; - v = - table[0x000 + ((v ) & 0xFF)] - ^ table[0x100 + ((v >> 8) & 0xFF)] - ^ table[0x200 + ((v >> 16) & 0xFF)] - ^ table[0x300 + ((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT32_SWAP(v); -} - -UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) -{ - const Byte *p = (const Byte *)data; - table += 0x100; - v = CRC_UINT32_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 8; size -= 8, p += 8) - { - UInt32 d; - v ^= *(const UInt32 *)p; - v = - table[0x400 + ((v ) & 0xFF)] - ^ table[0x500 + ((v >> 8) & 0xFF)] - ^ table[0x600 + ((v >> 16) & 0xFF)] - ^ table[0x700 + ((v >> 24))]; - d = *((const UInt32 *)p + 1); - v ^= - table[0x000 + ((d ) & 0xFF)] - ^ table[0x100 + ((d >> 8) & 0xFF)] - ^ table[0x200 + ((d >> 16) & 0xFF)] - ^ table[0x300 + ((d >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT32_SWAP(v); -} - -#endif +/* 7zCrcOpt.c -- CRC32 calculation (optimized functions) +2023-12-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1 + +// for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC_DEBUG_BE +#ifdef Z7_CRC_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +// the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c +#ifdef Z7_CRC_NUM_TABLES +#define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES +#else +#define Z7_CRC_NUM_TABLES_USE 12 +#endif + +#if Z7_CRC_NUM_TABLES_USE % 4 || \ + Z7_CRC_NUM_TABLES_USE < 4 * 1 || \ + Z7_CRC_NUM_TABLES_USE > 4 * 6 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif + + +#ifndef MY_CPU_BE + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +#define Q(n, d) \ + ( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] ) + +#define R(a) *((const UInt32 *)(const void *)p + (a)) + +#define CRC_FUNC_PRE_LE2(step) \ +UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table) + +#define CRC_FUNC_PRE_LE(step) \ + CRC_FUNC_PRE_LE2(step); \ + CRC_FUNC_PRE_LE2(step) + +CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE) +{ + const Byte *p = (const Byte *)data; + const Byte *lim; + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + lim = p + size; + if (size >= Z7_CRC_NUM_TABLES_USE) + { + lim -= Z7_CRC_NUM_TABLES_USE; + do + { + v ^= R(0); + { +#if Z7_CRC_NUM_TABLES_USE == 1 * 4 + v = Q(0, v); +#else +#define U2(r, op) \ + { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); } + UInt32 d, x; + U2(1, =) +#if Z7_CRC_NUM_TABLES_USE >= 3 * 4 +#define U(r) U2(r, ^=) + U(2) +#if Z7_CRC_NUM_TABLES_USE >= 4 * 4 + U(3) +#if Z7_CRC_NUM_TABLES_USE >= 5 * 4 + U(4) +#if Z7_CRC_NUM_TABLES_USE >= 6 * 4 + U(5) +#if Z7_CRC_NUM_TABLES_USE >= 7 * 4 +#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif +#endif +#endif +#endif +#endif +#undef U +#undef U2 + v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v); +#endif + } + p += Z7_CRC_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC_NUM_TABLES_USE; + } + for (; p < lim; p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#undef CRC_UPDATE_BYTE_2 +#undef R +#undef Q +#undef CRC_FUNC_PRE_LE +#undef CRC_FUNC_PRE_LE2 + +#endif + + + + +#ifndef MY_CPU_LE + +#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8)) + +#define Q(n, d) \ + ( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] ) + +#ifdef Z7_CRC_DEBUG_BE + #define R(a) GetBe32a((const UInt32 *)(const void *)p + (a)) +#else + #define R(a) *((const UInt32 *)(const void *)p + (a)) +#endif + + +#define CRC_FUNC_PRE_BE2(step) \ +UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table) + +#define CRC_FUNC_PRE_BE(step) \ + CRC_FUNC_PRE_BE2(step); \ + CRC_FUNC_PRE_BE2(step) + +CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE) +{ + const Byte *p = (const Byte *)data; + const Byte *lim; + table += 0x100; + v = Z7_BSWAP32(v); + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + lim = p + size; + if (size >= Z7_CRC_NUM_TABLES_USE) + { + lim -= Z7_CRC_NUM_TABLES_USE; + do + { + v ^= R(0); + { +#if Z7_CRC_NUM_TABLES_USE == 1 * 4 + v = Q(0, v); +#else +#define U2(r, op) \ + { d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); } + UInt32 d, x; + U2(1, =) +#if Z7_CRC_NUM_TABLES_USE >= 3 * 4 +#define U(r) U2(r, ^=) + U(2) +#if Z7_CRC_NUM_TABLES_USE >= 4 * 4 + U(3) +#if Z7_CRC_NUM_TABLES_USE >= 5 * 4 + U(4) +#if Z7_CRC_NUM_TABLES_USE >= 6 * 4 + U(5) +#if Z7_CRC_NUM_TABLES_USE >= 7 * 4 +#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif +#endif +#endif +#endif +#endif +#undef U +#undef U2 + v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v); +#endif + } + p += Z7_CRC_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC_NUM_TABLES_USE; + } + for (; p < lim; p++) + v = CRC_UPDATE_BYTE_2_BE(v, *p); + return Z7_BSWAP32(v); +} + +#undef CRC_UPDATE_BYTE_2_BE +#undef R +#undef Q +#undef CRC_FUNC_PRE_BE +#undef CRC_FUNC_PRE_BE2 + +#endif +#undef Z7_CRC_NUM_TABLES_USE +#endif diff -Nru p7zip-rar-16.02/C/7zDec.c p7zip-rar-16.02+really25.00+ds/C/7zDec.c --- p7zip-rar-16.02/C/7zDec.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zDec.c 2024-11-29 10:00:00.000000000 +0000 @@ -0,0 +1,673 @@ +/* 7zDec.c -- Decoding from 7z folder +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define Z7_PPMD_SUPPORT */ + +#include "7z.h" +#include "7zCrc.h" + +#include "Bcj2.h" +#include "Bra.h" +#include "CpuArch.h" +#include "Delta.h" +#include "LzmaDec.h" +#include "Lzma2Dec.h" +#ifdef Z7_PPMD_SUPPORT +#include "Ppmd7.h" +#endif + +#define k_Copy 0 +#ifndef Z7_NO_METHOD_LZMA2 +#define k_LZMA2 0x21 +#endif +#define k_LZMA 0x30101 +#define k_BCJ2 0x303011B + +#if !defined(Z7_NO_METHODS_FILTERS) +#define Z7_USE_BRANCH_FILTER +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64) +#define Z7_USE_FILTER_ARM64 +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARM64 0xa +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT) +#define Z7_USE_FILTER_ARMT +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARMT 0x3030701 +#endif + +#ifndef Z7_NO_METHODS_FILTERS +#define k_Delta 3 +#define k_RISCV 0xb +#define k_BCJ 0x3030103 +#define k_PPC 0x3030205 +#define k_IA64 0x3030401 +#define k_ARM 0x3030501 +#define k_SPARC 0x3030805 +#endif + +#ifdef Z7_PPMD_SUPPORT + +#define k_PPMD 0x30401 + +typedef struct +{ + IByteIn vt; + const Byte *cur; + const Byte *end; + const Byte *begin; + UInt64 processed; + BoolInt extra; + SRes res; + ILookInStreamPtr inStream; +} CByteInToLook; + +static Byte ReadByte(IByteInPtr pp) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook) + if (p->cur != p->end) + return *p->cur++; + if (p->res == SZ_OK) + { + size_t size = (size_t)(p->cur - p->begin); + p->processed += size; + p->res = ILookInStream_Skip(p->inStream, size); + size = (1 << 25); + p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size); + p->cur = p->begin; + p->end = p->begin + size; + if (size != 0) + return *p->cur++; + } + p->extra = True; + return 0; +} + +static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CPpmd7 ppmd; + CByteInToLook s; + SRes res = SZ_OK; + + s.vt.Read = ReadByte; + s.inStream = inStream; + s.begin = s.end = s.cur = NULL; + s.extra = False; + s.res = SZ_OK; + s.processed = 0; + + if (propsSize != 5) + return SZ_ERROR_UNSUPPORTED; + + { + unsigned order = props[0]; + UInt32 memSize = GetUi32(props + 1); + if (order < PPMD7_MIN_ORDER || + order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) + return SZ_ERROR_UNSUPPORTED; + Ppmd7_Construct(&ppmd); + if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) + return SZ_ERROR_MEM; + Ppmd7_Init(&ppmd, order); + } + { + ppmd.rc.dec.Stream = &s.vt; + if (!Ppmd7z_RangeDec_Init(&ppmd.rc.dec)) + res = SZ_ERROR_DATA; + else if (!s.extra) + { + Byte *buf = outBuffer; + const Byte *lim = buf + outSize; + for (; buf != lim; buf++) + { + int sym = Ppmd7z_DecodeSymbol(&ppmd); + if (s.extra || sym < 0) + break; + *buf = (Byte)sym; + } + if (buf != lim) + res = SZ_ERROR_DATA; + else if (!Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) + { + /* if (Ppmd7z_DecodeSymbol(&ppmd) != PPMD7_SYM_END || !Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) */ + res = SZ_ERROR_DATA; + } + } + if (s.extra) + res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); + else if (s.processed + (size_t)(s.cur - s.begin) != inSize) + res = SZ_ERROR_DATA; + } + Ppmd7_Free(&ppmd, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_CONSTRUCT(&state) + RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)) + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + const void *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = ILookInStream_Look(inStream, &inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (outSize != state.dicPos || inSize != 0) + res = SZ_ERROR_DATA; + break; + } + + if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + break; + + if (inProcessed == 0 && dicPos == state.dicPos) + { + res = SZ_ERROR_DATA; + break; + } + + res = ILookInStream_Skip(inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + + +#ifndef Z7_NO_METHOD_LZMA2 + +static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) +{ + CLzma2Dec state; + SRes res = SZ_OK; + + Lzma2Dec_CONSTRUCT(&state) + if (propsSize != 1) + return SZ_ERROR_DATA; + RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)) + state.decoder.dic = outBuffer; + state.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&state); + + for (;;) + { + const void *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = ILookInStream_Look(inStream, &inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; + ELzmaStatus status; + res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (outSize != state.decoder.dicPos || inSize != 0) + res = SZ_ERROR_DATA; + break; + } + + if (inProcessed == 0 && dicPos == state.decoder.dicPos) + { + res = SZ_ERROR_DATA; + break; + } + + res = ILookInStream_Skip(inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + Lzma2Dec_FreeProbs(&state, allocMain); + return res; +} + +#endif + + +static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer) +{ + while (inSize > 0) + { + const void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)) + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(ILookInStream_Skip(inStream, curSize)) + } + return SZ_OK; +} + +static BoolInt IS_MAIN_METHOD(UInt32 m) +{ + switch (m) + { + case k_Copy: + case k_LZMA: + #ifndef Z7_NO_METHOD_LZMA2 + case k_LZMA2: + #endif + #ifdef Z7_PPMD_SUPPORT + case k_PPMD: + #endif + return True; + default: + return False; + } +} + +static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c) +{ + return + c->NumStreams == 1 + /* && c->MethodID <= (UInt32)0xFFFFFFFF */ + && IS_MAIN_METHOD((UInt32)c->MethodID); +} + +#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4) + +static SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (!IS_SUPPORTED_CODER(&f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + + + #if defined(Z7_USE_BRANCH_FILTER) + + if (f->NumCoders == 2) + { + const CSzCoderInfo *c = &f->Coders[1]; + if ( + /* c->MethodID > (UInt32)0xFFFFFFFF || */ + c->NumStreams != 1 + || f->NumPackStreams != 1 + || f->PackStreams[0] != 0 + || f->NumBonds != 1 + || f->Bonds[0].InIndex != 1 + || f->Bonds[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + switch ((UInt32)c->MethodID) + { + #if !defined(Z7_NO_METHODS_FILTERS) + case k_Delta: + case k_BCJ: + case k_PPC: + case k_IA64: + case k_SPARC: + case k_ARM: + case k_RISCV: + #endif + #ifdef Z7_USE_FILTER_ARM64 + case k_ARM64: + #endif + #ifdef Z7_USE_FILTER_ARMT + case k_ARMT: + #endif + break; + default: + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; + } + + #endif + + + if (f->NumCoders == 4) + { + if (!IS_SUPPORTED_CODER(&f->Coders[1]) + || !IS_SUPPORTED_CODER(&f->Coders[2]) + || !IS_BCJ2(&f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 + || f->PackStreams[0] != 2 + || f->PackStreams[1] != 6 + || f->PackStreams[2] != 1 + || f->PackStreams[3] != 0 + || f->NumBonds != 3 + || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0 + || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1 + || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + + return SZ_ERROR_UNSUPPORTED; +} + + + + + + +static SRes SzFolder_Decode2(const CSzFolder *folder, + const Byte *propsData, + const UInt64 *unpackSizes, + const UInt64 *packPositions, + ILookInStreamPtr inStream, UInt64 startPos, + Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, + Byte *tempBuf[]) +{ + UInt32 ci; + SizeT tempSizes[3] = { 0, 0, 0}; + SizeT tempSize3 = 0; + Byte *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)) + + for (ci = 0; ci < folder->NumCoders; ci++) + { + const CSzCoderInfo *coder = &folder->Coders[ci]; + + if (IS_MAIN_METHOD((UInt32)coder->MethodID)) + { + UInt32 si = 0; + UInt64 offset; + UInt64 inSize; + Byte *outBufCur = outBuffer; + SizeT outSizeCur = outSize; + if (folder->NumCoders == 4) + { + const UInt32 indices[] = { 3, 2, 0 }; + const UInt64 unpackSize = unpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + Byte *temp; + outSizeCur = (SizeT)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur); + if (!temp && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (SizeT)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = packPositions[si]; + inSize = packPositions[(size_t)si + 1] - offset; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)) + } + else if (coder->MethodID == k_LZMA) + { + RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) + } + #ifndef Z7_NO_METHOD_LZMA2 + else if (coder->MethodID == k_LZMA2) + { + RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) + } + #endif + #ifdef Z7_PPMD_SUPPORT + else if (coder->MethodID == k_PPMD) + { + RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) + } + #endif + else + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->MethodID == k_BCJ2) + { + const UInt64 offset = packPositions[1]; + const UInt64 s3Size = packPositions[2] - offset; + + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + + tempSizes[2] = (SizeT)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]); + if (!tempBuf[2] && tempSizes[2] != 0) + return SZ_ERROR_MEM; + + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) + RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])) + + if ((tempSizes[0] & 3) != 0 || + (tempSizes[1] & 3) != 0 || + tempSize3 + tempSizes[0] + tempSizes[1] != outSize) + return SZ_ERROR_DATA; + + { + CBcj2Dec p; + + p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3; + p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0]; + p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1]; + p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2]; + + p.dest = outBuffer; + p.destLim = outBuffer + outSize; + + Bcj2Dec_Init(&p); + RINOK(Bcj2Dec_Decode(&p)) + + { + unsigned i; + for (i = 0; i < 4; i++) + if (p.bufs[i] != p.lims[i]) + return SZ_ERROR_DATA; + if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p)) + return SZ_ERROR_DATA; + } + } + } +#if defined(Z7_USE_BRANCH_FILTER) + else if (ci == 1) + { +#if !defined(Z7_NO_METHODS_FILTERS) + if (coder->MethodID == k_Delta) + { + if (coder->PropsSize != 1) + return SZ_ERROR_UNSUPPORTED; + { + Byte state[DELTA_STATE_SIZE]; + Delta_Init(state); + Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); + } + continue; + } +#endif + +#ifdef Z7_USE_FILTER_ARM64 + if (coder->MethodID == k_ARM64) + { + UInt32 pc = 0; + if (coder->PropsSize == 4) + { + pc = GetUi32(propsData + coder->PropsOffset); + if (pc & 3) + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc); + continue; + } +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) + if (coder->MethodID == k_RISCV) + { + UInt32 pc = 0; + if (coder->PropsSize == 4) + { + pc = GetUi32(propsData + coder->PropsOffset); + if (pc & 1) + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + z7_BranchConv_RISCV_Dec(outBuffer, outSize, pc); + continue; + } +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) + { + if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + #define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0; + switch (coder->MethodID) + { + #if !defined(Z7_NO_METHODS_FILTERS) + case k_BCJ: + { + UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0 + break; + } + case k_PPC: Z7_BRANCH_CONV_DEC_2(BranchConv_PPC)(outBuffer, outSize, 0); break; // pc = 0; + // CASE_BRA_CONV(PPC) + CASE_BRA_CONV(IA64) + CASE_BRA_CONV(SPARC) + CASE_BRA_CONV(ARM) + #endif + #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) + CASE_BRA_CONV(ARMT) + #endif + default: + return SZ_ERROR_UNSUPPORTED; + } + continue; + } +#endif + } // (c == 1) +#endif // Z7_USE_BRANCH_FILTER + else + return SZ_ERROR_UNSUPPORTED; + } + + return SZ_OK; +} + + +SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, + ILookInStreamPtr inStream, UInt64 startPos, + Byte *outBuffer, size_t outSize, + ISzAllocPtr allocMain) +{ + SRes res; + CSzFolder folder; + CSzData sd; + + const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; + sd.Data = data; + sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex]; + + res = SzGetNextFolderItem(&folder, &sd); + + if (res != SZ_OK) + return res; + + if (sd.Size != 0 + || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex] + || outSize != SzAr_GetFolderUnpackSize(p, folderIndex)) + return SZ_ERROR_FAIL; + { + unsigned i; + Byte *tempBuf[3] = { 0, 0, 0}; + + res = SzFolder_Decode2(&folder, data, + &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]], + p->PackPositions + p->FoStartPackStreamIndex[folderIndex], + inStream, startPos, + outBuffer, (SizeT)outSize, allocMain, tempBuf); + + for (i = 0; i < 3; i++) + ISzAlloc_Free(allocMain, tempBuf[i]); + + if (res == SZ_OK) + if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex)) + if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex]) + res = SZ_ERROR_CRC; + + return res; + } +} diff -Nru p7zip-rar-16.02/C/7zFile.c p7zip-rar-16.02+really25.00+ds/C/7zFile.c --- p7zip-rar-16.02/C/7zFile.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zFile.c 2023-04-02 11:00:00.000000000 +0000 @@ -0,0 +1,443 @@ +/* 7zFile.c -- File IO +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + + #include + + #ifndef USE_FOPEN + #include + #include + #ifdef _WIN32 + #include + typedef int ssize_t; + typedef int off_t; + #else + #include + #endif + #endif + +#else + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" +*/ + +#endif + +#define kChunkSizeMax (1 << 22) + +void File_Construct(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; + #elif defined(USE_FOPEN) + p->file = NULL; + #else + p->fd = -1; + #endif +} + +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) + +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ + #ifdef USE_WINDOWS_FILE + + p->handle = CreateFileA(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); + + #elif defined(USE_FOPEN) + + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : + #ifdef UNDER_CE + 2; /* ENOENT */ + #else + errno; + #endif + + #else + + int flags = (writeMode ? (O_CREAT | O_EXCL | O_WRONLY) : O_RDONLY); + #ifdef O_BINARY + flags |= O_BINARY; + #endif + p->fd = open(name, flags, 0666); + return (p->fd != -1) ? 0 : errno; + + #endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } + +WRes OutFile_Open(CSzFile *p, const char *name) +{ + #if defined(USE_WINDOWS_FILE) || defined(USE_FOPEN) + return File_Open(p, name, 1); + #else + p->fd = creat(name, 0666); + return (p->fd != -1) ? 0 : errno; + #endif +} + +#endif + + +#ifdef USE_WINDOWS_FILE +static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) +{ + p->handle = CreateFileW(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +} +WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } +#endif + +WRes File_Close(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } + + #elif defined(USE_FOPEN) + + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + { + if (res == EOF) + return errno; + return res; + } + p->file = NULL; + } + + #else + + if (p->fd != -1) + { + if (close(p->fd) != 0) + return errno; + p->fd = -1; + } + + #endif + + return 0; +} + + +WRes File_Read(CSzFile *p, void *data, size_t *size) +{ + size_t originalSize = *size; + *size = 0; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + do + { + const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + const BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + // debug : we can break here for partial reading mode + if (processed == 0) + break; + } + while (originalSize > 0); + + #elif defined(USE_FOPEN) + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const size_t processed = fread(data, 1, curSize, p->file); + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= processed; + *size += processed; + if (processed != curSize) + return ferror(p->file); + // debug : we can break here for partial reading mode + if (processed == 0) + break; + } + while (originalSize > 0); + + #else + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const ssize_t processed = read(p->fd, data, curSize); + if (processed == -1) + return errno; + if (processed == 0) + break; + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= (size_t)processed; + *size += (size_t)processed; + // debug : we can break here for partial reading mode + // break; + } + while (originalSize > 0); + + #endif + + return 0; +} + + +WRes File_Write(CSzFile *p, const void *data, size_t *size) +{ + size_t originalSize = *size; + *size = 0; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + do + { + const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + const BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); + data = (const void *)((const Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + + #elif defined(USE_FOPEN) + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const size_t processed = fwrite(data, 1, curSize, p->file); + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= processed; + *size += processed; + if (processed != curSize) + return ferror(p->file); + if (processed == 0) + break; + } + while (originalSize > 0); + + #else + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const ssize_t processed = write(p->fd, data, curSize); + if (processed == -1) + return errno; + if (processed == 0) + break; + data = (const void *)((const Byte *)data + (size_t)processed); + originalSize -= (size_t)processed; + *size += (size_t)processed; + } + while (originalSize > 0); + + #endif + + return 0; +} + + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) +{ + #ifdef USE_WINDOWS_FILE + + DWORD moveMethod; + UInt32 low = (UInt32)*pos; + LONG high = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ + // (int) to eliminate clang warning + switch ((int)origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + low = SetFilePointer(p->handle, (LONG)low, &high, moveMethod); + if (low == (UInt32)0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((Int64)high << 32) | low; + return 0; + + #else + + int moveMethod; // = origin; + + switch ((int)origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return EINVAL; + } + + #if defined(USE_FOPEN) + { + int res = fseek(p->file, (long)*pos, moveMethod); + if (res == -1) + return errno; + *pos = ftell(p->file); + if (*pos == -1) + return errno; + return 0; + } + #else + { + off_t res = lseek(p->fd, (off_t)*pos, moveMethod); + if (res == -1) + return errno; + *pos = res; + return 0; + } + + #endif // USE_FOPEN + #endif // USE_WINDOWS_FILE +} + + +WRes File_GetLength(CSzFile *p, UInt64 *length) +{ + #ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((UInt64)sizeHigh) << 32) + sizeLow; + return 0; + + #elif defined(USE_FOPEN) + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + + #else + + off_t pos; + *length = 0; + pos = lseek(p->fd, 0, SEEK_CUR); + if (pos != -1) + { + const off_t len2 = lseek(p->fd, 0, SEEK_END); + const off_t res2 = lseek(p->fd, pos, SEEK_SET); + if (len2 != -1) + { + *length = (UInt64)len2; + if (res2 != -1) + return 0; + } + } + return errno; + + #endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(ISeqInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileSeqInStream) + const WRes wres = File_Read(&p->file, buf, size); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->vt.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(ISeekInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Read(&p->file, buf, size); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(ISeekInStreamPtr pp, Int64 *pos, ESzSeek origin) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Seek(&p->file, pos, origin); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->vt.Read = FileInStream_Read; + p->vt.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileOutStream) + const WRes wres = File_Write(&p->file, data, &size); + p->wres = wres; + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->vt.Write = FileOutStream_Write; +} diff -Nru p7zip-rar-16.02/C/7zFile.h p7zip-rar-16.02+really25.00+ds/C/7zFile.h --- p7zip-rar-16.02/C/7zFile.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zFile.h 2023-03-05 09:00:00.000000000 +0000 @@ -0,0 +1,92 @@ +/* 7zFile.h -- File IO +2023-03-05 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_FILE_H +#define ZIP7_INC_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +// #include +#endif + +#ifdef USE_WINDOWS_FILE +#include "7zWindows.h" + +#else +// note: USE_FOPEN mode is limited to 32-bit file size +// #define USE_FOPEN +// #include +#endif + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #elif defined(USE_FOPEN) + FILE *file; + #else + int fd; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +#endif +#ifdef USE_WINDOWS_FILE +WRes InFile_OpenW(CSzFile *p, const WCHAR *name); +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); +#endif +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, UInt64 *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + CSzFile file; + WRes wres; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream vt; + CSzFile file; + WRes wres; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream vt; + CSzFile file; + WRes wres; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/7zStream.c p7zip-rar-16.02+really25.00+ds/C/7zStream.c --- p7zip-rar-16.02/C/7zStream.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zStream.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,171 +1,199 @@ -/* 7zStream.c -- 7z Stream functions -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zTypes.h" - -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((Byte *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) -{ - return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) -{ - size_t processed = 1; - RINOK(stream->Read(stream, buf, &processed)); - return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; -} - -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) -{ - Int64 t = offset; - return stream->Seek(stream, &t, SZ_SEEK_SET); -} - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) -{ - const void *lookBuf; - if (*size == 0) - return SZ_OK; - RINOK(stream->Look(stream, &lookBuf, size)); - memcpy(buf, lookBuf, *size); - return stream->Skip(stream, *size); -} - -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((Byte *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) -{ - return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - size2 = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, &size2); - p->size = size2; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - if (*size > LookToRead_BUF_SIZE) - *size = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, size); - size2 = p->size = *size; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Skip(void *pp, size_t offset) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos += offset; - return SZ_OK; -} - -static SRes LookToRead_Read(void *pp, void *buf, size_t *size) -{ - CLookToRead *p = (CLookToRead *)pp; - size_t rem = p->size - p->pos; - if (rem == 0) - return p->realStream->Read(p->realStream, buf, size); - if (rem > *size) - rem = *size; - memcpy(buf, p->buf + p->pos, rem); - p->pos += rem; - *size = rem; - return SZ_OK; -} - -static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos = p->size = 0; - return p->realStream->Seek(p->realStream, pos, origin); -} - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead) -{ - p->s.Look = lookahead ? - LookToRead_Look_Lookahead : - LookToRead_Look_Exact; - p->s.Skip = LookToRead_Skip; - p->s.Read = LookToRead_Read; - p->s.Seek = LookToRead_Seek; -} - -void LookToRead_Init(CLookToRead *p) -{ - p->pos = p->size = 0; -} - -static SRes SecToLook_Read(void *pp, void *buf, size_t *size) -{ - CSecToLook *p = (CSecToLook *)pp; - return LookInStream_LookRead(p->realStream, buf, size); -} - -void SecToLook_CreateVTable(CSecToLook *p) -{ - p->s.Read = SecToLook_Read; -} - -static SRes SecToRead_Read(void *pp, void *buf, size_t *size) -{ - CSecToRead *p = (CSecToRead *)pp; - return p->realStream->Read(p->realStream, buf, size); -} - -void SecToRead_CreateVTable(CSecToRead *p) -{ - p->s.Read = SecToRead_Read; -} +/* 7zStream.c -- 7z Stream functions +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zTypes.h" + + +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize) +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + size_t cur = size; + const SRes res = ISeqInStream_Read(stream, buf, &cur); + *processedSize += cur; + buf = (void *)((Byte *)buf + cur); + size -= cur; + if (res != SZ_OK) + return res; + if (cur == 0) + return SZ_OK; + } + return SZ_OK; +} + +/* +SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(ISeqInStream_Read(stream, buf, &processed)) + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size) +{ + return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} +*/ + + +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf) +{ + size_t processed = 1; + RINOK(ISeqInStream_Read(stream, buf, &processed)) + return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; +} + + + +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset) +{ + Int64 t = (Int64)offset; + return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); +} + +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size) +{ + const void *lookBuf; + if (*size == 0) + return SZ_OK; + RINOK(ILookInStream_Look(stream, &lookBuf, size)) + memcpy(buf, lookBuf, *size); + return ILookInStream_Skip(stream, *size); +} + +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(ILookInStream_Read(stream, buf, &processed)) + if (processed == 0) + return errorType; + buf = (void *)((Byte *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size) +{ + return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + + + +#define GET_LookToRead2 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLookToRead2) + +static SRes LookToRead2_Look_Lookahead(ILookInStreamPtr pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + GET_LookToRead2 + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size != 0) + { + p->pos = 0; + p->size = 0; + size2 = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, &size2); + p->size = size2; + } + if (*size > size2) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead2_Look_Exact(ILookInStreamPtr pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + GET_LookToRead2 + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size != 0) + { + p->pos = 0; + p->size = 0; + if (*size > p->bufSize) + *size = p->bufSize; + res = ISeekInStream_Read(p->realStream, p->buf, size); + size2 = p->size = *size; + } + if (*size > size2) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead2_Skip(ILookInStreamPtr pp, size_t offset) +{ + GET_LookToRead2 + p->pos += offset; + return SZ_OK; +} + +static SRes LookToRead2_Read(ILookInStreamPtr pp, void *buf, size_t *size) +{ + GET_LookToRead2 + size_t rem = p->size - p->pos; + if (rem == 0) + return ISeekInStream_Read(p->realStream, buf, size); + if (rem > *size) + rem = *size; + memcpy(buf, p->buf + p->pos, rem); + p->pos += rem; + *size = rem; + return SZ_OK; +} + +static SRes LookToRead2_Seek(ILookInStreamPtr pp, Int64 *pos, ESzSeek origin) +{ + GET_LookToRead2 + p->pos = p->size = 0; + return ISeekInStream_Seek(p->realStream, pos, origin); +} + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) +{ + p->vt.Look = lookahead ? + LookToRead2_Look_Lookahead : + LookToRead2_Look_Exact; + p->vt.Skip = LookToRead2_Skip; + p->vt.Read = LookToRead2_Read; + p->vt.Seek = LookToRead2_Seek; +} + + + +static SRes SecToLook_Read(ISeqInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToLook) + return LookInStream_LookRead(p->realStream, buf, size); +} + +void SecToLook_CreateVTable(CSecToLook *p) +{ + p->vt.Read = SecToLook_Read; +} + +static SRes SecToRead_Read(ISeqInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToRead) + return ILookInStream_Read(p->realStream, buf, size); +} + +void SecToRead_CreateVTable(CSecToRead *p) +{ + p->vt.Read = SecToRead_Read; +} diff -Nru p7zip-rar-16.02/C/7zTypes.h p7zip-rar-16.02+really25.00+ds/C/7zTypes.h --- p7zip-rar-16.02/C/7zTypes.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zTypes.h 2024-01-21 11:00:00.000000000 +0000 @@ -1,256 +1,597 @@ -/* 7zTypes.h -- Basic types -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H - -#ifdef _WIN32 -/* #include */ -#endif - -#include - -#ifndef EXTERN_C_BEGIN -#ifdef __cplusplus -#define EXTERN_C_BEGIN extern "C" { -#define EXTERN_C_END } -#else -#define EXTERN_C_BEGIN -#define EXTERN_C_END -#endif -#endif - -EXTERN_C_BEGIN - -#define SZ_OK 0 - -#define SZ_ERROR_DATA 1 -#define SZ_ERROR_MEM 2 -#define SZ_ERROR_CRC 3 -#define SZ_ERROR_UNSUPPORTED 4 -#define SZ_ERROR_PARAM 5 -#define SZ_ERROR_INPUT_EOF 6 -#define SZ_ERROR_OUTPUT_EOF 7 -#define SZ_ERROR_READ 8 -#define SZ_ERROR_WRITE 9 -#define SZ_ERROR_PROGRESS 10 -#define SZ_ERROR_FAIL 11 -#define SZ_ERROR_THREAD 12 - -#define SZ_ERROR_ARCHIVE 16 -#define SZ_ERROR_NO_ARCHIVE 17 - -typedef int SRes; - -#ifdef _WIN32 -/* typedef DWORD WRes; */ -typedef unsigned WRes; -#else -typedef int WRes; -#endif - -#ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -#endif - -typedef unsigned char Byte; -typedef short Int16; -typedef unsigned short UInt16; - -#ifdef _LZMA_UINT32_IS_ULONG -typedef long Int32; -typedef unsigned long UInt32; -#else -typedef int Int32; -typedef unsigned int UInt32; -#endif - -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ - -typedef long Int64; -typedef unsigned long UInt64; - -#else - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n -#else -typedef long long int Int64; -typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL -#endif - -#endif - -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; -#else -typedef size_t SizeT; -#endif - -typedef int Bool; -#define True 1 -#define False 0 - - -#ifdef _WIN32 -#define MY_STD_CALL __stdcall -#else -#define MY_STD_CALL -#endif - -#ifdef _MSC_VER - -#if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) -#else -#define MY_NO_INLINE -#endif - -#define MY_CDECL __cdecl -#define MY_FAST_CALL __fastcall - -#else - -#define MY_NO_INLINE -#define MY_CDECL -#define MY_FAST_CALL - -#endif - - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; - -typedef struct -{ - void (*Write)(void *p, Byte b); -} IByteOut; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) < input(*size)) is allowed */ -} ISeqInStream; - -/* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); - -typedef struct -{ - size_t (*Write)(void *p, const void *buf, size_t size); - /* Returns: result - the number of actually written bytes. - (result < size) means error */ -} ISeqOutStream; - -typedef enum -{ - SZ_SEEK_SET = 0, - SZ_SEEK_CUR = 1, - SZ_SEEK_END = 2 -} ESzSeek; - -typedef struct -{ - SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ISeekInStream; - -typedef struct -{ - SRes (*Look)(void *p, const void **buf, size_t *size); - /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. - (output(*size) > input(*size)) is not allowed - (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(void *p, size_t offset); - /* offset must be <= output(*size) of Look */ - - SRes (*Read)(void *p, void *buf, size_t *size); - /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -} ILookInStream; - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); - -/* reads via ILookInStream::Read */ -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); - -#define LookToRead_BUF_SIZE (1 << 14) - -typedef struct -{ - ILookInStream s; - ISeekInStream *realStream; - size_t pos; - size_t size; - Byte buf[LookToRead_BUF_SIZE]; -} CLookToRead; - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -void LookToRead_Init(CLookToRead *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToLook; - -void SecToLook_CreateVTable(CSecToLook *p); - -typedef struct -{ - ISeqInStream s; - ILookInStream *realStream; -} CSecToRead; - -void SecToRead_CreateVTable(CSecToRead *p); - -typedef struct -{ - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); - /* Returns: result. (result != SZ_OK) means break. - Value (UInt64)(Int64)-1 for size means unknown value. */ -} ICompressProgress; - -typedef struct -{ - void *(*Alloc)(void *p, size_t size); - void (*Free)(void *p, void *address); /* address can be 0 */ -} ISzAlloc; - -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -#define IAlloc_Free(p, a) (p)->Free((p), a) - -#ifdef _WIN32 - -#define CHAR_PATH_SEPARATOR '\\' -#define WCHAR_PATH_SEPARATOR L'\\' -#define STRING_PATH_SEPARATOR "\\" -#define WSTRING_PATH_SEPARATOR L"\\" - -#else - -#define CHAR_PATH_SEPARATOR '/' -#define WCHAR_PATH_SEPARATOR L'/' -#define STRING_PATH_SEPARATOR "/" -#define WSTRING_PATH_SEPARATOR L"/" - -#endif - -EXTERN_C_END - -#endif +/* 7zTypes.h -- Basic types +2024-01-24 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_7Z_TYPES_H +#define ZIP7_7Z_TYPES_H + +#ifdef _WIN32 +/* #include */ +#else +#include +#endif + +#include + +#ifndef EXTERN_C_BEGIN +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif +#endif + +EXTERN_C_BEGIN + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + + +#ifdef _MSC_VER + #if _MSC_VER > 1200 + #define MY_ALIGN(n) __declspec(align(n)) + #else + #define MY_ALIGN(n) + #endif +#else + /* + // C11/C++11: + #include + #define MY_ALIGN(n) alignas(n) + */ + #define MY_ALIGN(n) __attribute__ ((aligned(n))) +#endif + + +#ifdef _WIN32 + +/* typedef DWORD WRes; */ +typedef unsigned WRes; +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) + +// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) + +#else // _WIN32 + +// #define ENV_HAVE_LSTAT +typedef int WRes; + +// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT +#define MY_FACILITY_ERRNO 0x800 +#define MY_FACILITY_WIN32 7 +#define MY_FACILITY_WRes MY_FACILITY_ERRNO + +#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \ + ( (HRESULT)(x) & 0x0000FFFF) \ + | (MY_FACILITY_WRes << 16) \ + | (HRESULT)0x80000000 )) + +#define MY_SRes_HRESULT_FROM_WRes(x) \ + ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x)) + +// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno) +#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x) + +/* +#define ERROR_FILE_NOT_FOUND 2L +#define ERROR_ACCESS_DENIED 5L +#define ERROR_NO_MORE_FILES 18L +#define ERROR_LOCK_VIOLATION 33L +#define ERROR_FILE_EXISTS 80L +#define ERROR_DISK_FULL 112L +#define ERROR_NEGATIVE_SEEK 131L +#define ERROR_ALREADY_EXISTS 183L +#define ERROR_DIRECTORY 267L +#define ERROR_TOO_MANY_POSTS 298L + +#define ERROR_INTERNAL_ERROR 1359L +#define ERROR_INVALID_REPARSE_DATA 4392L +#define ERROR_REPARSE_TAG_INVALID 4393L +#define ERROR_REPARSE_TAG_MISMATCH 4394L +*/ + +// we use errno equivalents for some WIN32 errors: + +#define ERROR_INVALID_PARAMETER EINVAL +#define ERROR_INVALID_FUNCTION EINVAL +#define ERROR_ALREADY_EXISTS EEXIST +#define ERROR_FILE_EXISTS EEXIST +#define ERROR_PATH_NOT_FOUND ENOENT +#define ERROR_FILE_NOT_FOUND ENOENT +#define ERROR_DISK_FULL ENOSPC +// #define ERROR_INVALID_HANDLE EBADF + +// we use FACILITY_WIN32 for errors that has no errno equivalent +// Too many posts were made to a semaphore. +#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL) +#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L) +#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L) + +// if (MY_FACILITY_WRes != FACILITY_WIN32), +// we use FACILITY_WIN32 for COM errors: +#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) +#define E_INVALIDARG ((HRESULT)0x80070057L) +#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) + +/* +// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents: +#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM) +#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +*/ + +#define TEXT(quote) quote + +#define FILE_ATTRIBUTE_READONLY 0x0001 +#define FILE_ATTRIBUTE_HIDDEN 0x0002 +#define FILE_ATTRIBUTE_SYSTEM 0x0004 +#define FILE_ATTRIBUTE_DIRECTORY 0x0010 +#define FILE_ATTRIBUTE_ARCHIVE 0x0020 +#define FILE_ATTRIBUTE_DEVICE 0x0040 +#define FILE_ATTRIBUTE_NORMAL 0x0080 +#define FILE_ATTRIBUTE_TEMPORARY 0x0100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400 +#define FILE_ATTRIBUTE_COMPRESSED 0x0800 +#define FILE_ATTRIBUTE_OFFLINE 0x1000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 + +#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */ + +#endif + + +#ifndef RINOK +#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; } +#endif + +#ifndef RINOK_WRes +#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef Z7_DECL_Int32_AS_long +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + + +#ifndef _WIN32 + +typedef int INT; +typedef Int32 INT32; +typedef unsigned int UINT; +typedef UInt32 UINT32; +typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility +typedef UINT32 ULONG; + +#undef DWORD +typedef UINT32 DWORD; + +#define VOID void + +#define HRESULT LONG + +typedef void *LPVOID; +// typedef void VOID; +// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; +// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits) +typedef long INT_PTR; +typedef unsigned long UINT_PTR; +typedef long LONG_PTR; +typedef unsigned long DWORD_PTR; + +typedef size_t SIZE_T; + +#endif // _WIN32 + + +#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL) + + +#ifdef Z7_DECL_Int64_AS_long + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +#if defined(__clang__) || defined(__GNUC__) +#include +typedef int64_t Int64; +typedef uint64_t UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +// #define UINT64_CONST(n) n ## ULL +#endif +#endif + +#endif + +#define UINT64_CONST(n) n + + +#ifdef Z7_DECL_SizeT_AS_unsigned_int +typedef unsigned int SizeT; +#else +typedef size_t SizeT; +#endif + +/* +#if (defined(_MSC_VER) && _MSC_VER <= 1200) +typedef size_t MY_uintptr_t; +#else +#include +typedef uintptr_t MY_uintptr_t; +#endif +*/ + +typedef int BoolInt; +/* typedef BoolInt Bool; */ +#define True 1 +#define False 0 + + +#ifdef _WIN32 +#define Z7_STDCALL __stdcall +#else +#define Z7_STDCALL +#endif + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define Z7_NO_INLINE __declspec(noinline) +#else +#define Z7_NO_INLINE +#endif + +#define Z7_FORCE_INLINE __forceinline + +#define Z7_CDECL __cdecl +#define Z7_FASTCALL __fastcall + +#else // _MSC_VER + +#if (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4)) \ + || defined(__INTEL_COMPILER) \ + || defined(__xlC__) +#define Z7_NO_INLINE __attribute__((noinline)) +#define Z7_FORCE_INLINE __attribute__((always_inline)) inline +#else +#define Z7_NO_INLINE +#define Z7_FORCE_INLINE +#endif + +#define Z7_CDECL + +#if defined(_M_IX86) \ + || defined(__i386__) +// #define Z7_FASTCALL __attribute__((fastcall)) +// #define Z7_FASTCALL __attribute__((cdecl)) +#define Z7_FASTCALL +#elif defined(MY_CPU_AMD64) +// #define Z7_FASTCALL __attribute__((ms_abi)) +#define Z7_FASTCALL +#else +#define Z7_FASTCALL +#endif + +#endif // _MSC_VER + + +/* The following interfaces use first parameter as pointer to structure */ + +// #define Z7_C_IFACE_CONST_QUAL +#define Z7_C_IFACE_CONST_QUAL const + +#define Z7_C_IFACE_DECL(a) \ + struct a ## _; \ + typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \ + typedef struct a ## _ a; \ + struct a ## _ + + +Z7_C_IFACE_DECL (IByteIn) +{ + Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */ +}; +#define IByteIn_Read(p) (p)->Read(p) + + +Z7_C_IFACE_DECL (IByteOut) +{ + void (*Write)(IByteOutPtr p, Byte b); +}; +#define IByteOut_Write(p, b) (p)->Write(p, b) + + +Z7_C_IFACE_DECL (ISeqInStream) +{ + SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +}; +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) + +/* try to read as much as avail in stream and limited by (*processedSize) */ +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize); +/* it can return SZ_ERROR_INPUT_EOF */ +// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size); +// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf); + + +Z7_C_IFACE_DECL (ISeqOutStream) +{ + size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +}; +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) + +typedef enum +{ + SZ_SEEK_SET = 0, + SZ_SEEK_CUR = 1, + SZ_SEEK_END = 2 +} ESzSeek; + + +Z7_C_IFACE_DECL (ISeekInStream) +{ + SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin); +}; +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +Z7_C_IFACE_DECL (ILookInStream) +{ + SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) > input(*size)) is not allowed + (output(*size) < input(*size)) is allowed */ + SRes (*Skip)(ILookInStreamPtr p, size_t offset); + /* offset must be <= output(*size) of Look */ + SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size); + /* reads directly (without buffer). It's same as ISeqInStream::Read */ + SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin); +}; + +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) + + +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset); + +/* reads via ILookInStream::Read */ +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size); + + +typedef struct +{ + ILookInStream vt; + ISeekInStreamPtr realStream; + + size_t pos; + size_t size; /* it's data size */ + + /* the following variables must be set outside */ + Byte *buf; + size_t bufSize; +} CLookToRead2; + +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); + +#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; } + + +typedef struct +{ + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToLook; + +void SecToLook_CreateVTable(CSecToLook *p); + + + +typedef struct +{ + ISeqInStream vt; + ILookInStreamPtr realStream; +} CSecToRead; + +void SecToRead_CreateVTable(CSecToRead *p); + + +Z7_C_IFACE_DECL (ICompressProgress) +{ + SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +}; + +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) + + + +typedef struct ISzAlloc ISzAlloc; +typedef const ISzAlloc * ISzAllocPtr; + +struct ISzAlloc +{ + void *(*Alloc)(ISzAllocPtr p, size_t size); + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ +}; + +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) +#define ISzAlloc_Free(p, a) (p)->Free(p, a) + +/* deprecated */ +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) + + + + + +#ifndef MY_offsetof + #ifdef offsetof + #define MY_offsetof(type, m) offsetof(type, m) + /* + #define MY_offsetof(type, m) FIELD_OFFSET(type, m) + */ + #else + #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m)) + #endif +#endif + + + +#ifndef Z7_container_of + +/* +#define Z7_container_of(ptr, type, m) container_of(ptr, type, m) +#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +*/ + +/* + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" + GCC 3.4.4 : classes with constructor + GCC 4.8.1 : classes with non-public variable members" +*/ + +#define Z7_container_of(ptr, type, m) \ + ((type *)(void *)((char *)(void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +#define Z7_container_of_CONST(ptr, type, m) \ + ((const type *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +/* +#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \ + ((type *)(void *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) +*/ + +#endif + +#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) + +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +/* +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m) +*/ +#if defined (__clang__) || defined(__GNUC__) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL +#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL +#endif + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \ + Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \ + type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \ + Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p) + + +// #define ZIP7_DECLARE_HANDLE(name) typedef void *name; +#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name; + + +#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) + +#ifndef Z7_ARRAY_SIZE +#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + + +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#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 + +/* +#ifndef Z7_ST +#ifdef _7ZIP_ST +#define Z7_ST +#endif +#endif +*/ diff -Nru p7zip-rar-16.02/C/7zVersion.h p7zip-rar-16.02+really25.00+ds/C/7zVersion.h --- p7zip-rar-16.02/C/7zVersion.h 2016-06-11 08:30:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zVersion.h 2025-07-05 11:00:00.000000000 +0000 @@ -1,22 +1,27 @@ -#define MY_VER_MAJOR 16 -#define MY_VER_MINOR 02 -#define MY_VER_BUILD 0 -#define MY_VERSION_NUMBERS "16.02" -#define MY_VERSION "16.02" -#define MY_DATE "2016-05-21" -#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-2016 Igor Pavlov" - -#ifdef USE_COPYRIGHT_CR - #define MY_COPYRIGHT MY_COPYRIGHT_CR -#else - #define MY_COPYRIGHT MY_COPYRIGHT_PD -#endif - -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE - -#define P7ZIP_VERSION "16.02" - +#define MY_VER_MAJOR 25 +#define MY_VER_MINOR 0 +#define MY_VER_BUILD 0 +#define MY_VERSION_NUMBERS "25.00" +#define MY_VERSION MY_VERSION_NUMBERS + +#ifdef MY_CPU_NAME + #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")" +#else + #define MY_VERSION_CPU MY_VERSION +#endif + +#define MY_DATE "2025-07-05" +#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-2025 Igor Pavlov" + +#ifdef USE_COPYRIGHT_CR + #define MY_COPYRIGHT MY_COPYRIGHT_CR +#else + #define MY_COPYRIGHT MY_COPYRIGHT_PD +#endif + +#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE diff -Nru p7zip-rar-16.02/C/7zVersion.rc p7zip-rar-16.02+really25.00+ds/C/7zVersion.rc --- p7zip-rar-16.02/C/7zVersion.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zVersion.rc 2011-04-18 18:00:00.000000000 +0000 @@ -0,0 +1,55 @@ +#define MY_VS_FFI_FILEFLAGSMASK 0x0000003FL +#define MY_VOS_NT_WINDOWS32 0x00040004L +#define MY_VOS_CE_WINDOWS32 0x00050004L + +#define MY_VFT_APP 0x00000001L +#define MY_VFT_DLL 0x00000002L + +// #include + +#ifndef MY_VERSION +#include "7zVersion.h" +#endif + +#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0 + +#ifdef DEBUG +#define DBG_FL VS_FF_DEBUG +#else +#define DBG_FL 0 +#endif + +#define MY_VERSION_INFO(fileType, descr, intName, origName) \ +LANGUAGE 9, 1 \ +1 VERSIONINFO \ + FILEVERSION MY_VER \ + PRODUCTVERSION MY_VER \ + FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \ + FILEFLAGS DBG_FL \ + FILEOS MY_VOS_NT_WINDOWS32 \ + FILETYPE fileType \ + FILESUBTYPE 0x0L \ +BEGIN \ + BLOCK "StringFileInfo" \ + BEGIN \ + BLOCK "040904b0" \ + BEGIN \ + VALUE "CompanyName", "Igor Pavlov" \ + VALUE "FileDescription", descr \ + VALUE "FileVersion", MY_VERSION \ + VALUE "InternalName", intName \ + VALUE "LegalCopyright", MY_COPYRIGHT \ + VALUE "OriginalFilename", origName \ + VALUE "ProductName", "7-Zip" \ + VALUE "ProductVersion", MY_VERSION \ + END \ + END \ + BLOCK "VarFileInfo" \ + BEGIN \ + VALUE "Translation", 0x409, 1200 \ + END \ +END + +#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe") + +#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll") diff -Nru p7zip-rar-16.02/C/7zWindows.h p7zip-rar-16.02+really25.00+ds/C/7zWindows.h --- p7zip-rar-16.02/C/7zWindows.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zWindows.h 2023-04-02 11:00:00.000000000 +0000 @@ -0,0 +1,101 @@ +/* 7zWindows.h -- StdAfx +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_WINDOWS_H +#define ZIP7_INC_7Z_WINDOWS_H + +#ifdef _WIN32 + +#if defined(__clang__) +# pragma clang diagnostic push +#endif + +#if defined(_MSC_VER) + +#pragma warning(push) +#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + +#if _MSC_VER == 1900 +// for old kit10 versions +// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext': +#endif +// win10 Windows Kit: +#endif // _MSC_VER + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +// for msvc6 without sdk2003 +#define RPC_NO_WINDOWS_H +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +// #if defined(__GNUC__) && !defined(__clang__) +#include +#else +#include +#endif +// #include +// #include + +// but if precompiled with clang-cl then we need +// #include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +#ifndef _W64 + +typedef long LONG_PTR, *PLONG_PTR; +typedef unsigned long ULONG_PTR, *PULONG_PTR; +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + +#define Z7_OLD_WIN_SDK +#endif // _W64 +#endif // _MSC_VER == 1200 + +#ifdef Z7_OLD_WIN_SDK + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif +#ifndef FILE_SPECIAL_ACCESS +#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#endif + +// ShlObj.h: +// #define BIF_NEWDIALOGSTYLE 0x0040 + +#pragma warning(disable : 4201) +// #pragma warning(disable : 4115) + +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + +#endif // Z7_OLD_WIN_SDK + +#ifdef UNDER_CE +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + + +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 && _MSC_VER <= 1600 + // BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed + // string.h + // #pragma warning(disable : 4514) +#endif +#endif + + +/* #include "7zTypes.h" */ + +#endif diff -Nru p7zip-rar-16.02/C/7zip_gcc_c.mak p7zip-rar-16.02+really25.00+ds/C/7zip_gcc_c.mak --- p7zip-rar-16.02/C/7zip_gcc_c.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/7zip_gcc_c.mak 2024-02-28 10:00:00.000000000 +0000 @@ -0,0 +1,360 @@ + +MY_ARCH_2 = $(MY_ARCH) + +MY_ASM = jwasm +MY_ASM = asmc + +ifndef RC +#RC=windres.exe --target=pe-x86-64 +#RC=windres.exe -F pe-i386 +RC=windres.exe +endif + +PROGPATH = $(O)/$(PROG) +PROGPATH_STATIC = $(O)/$(PROG)s + +ifneq ($(CC), xlc) +CFLAGS_WARN_WALL = -Wall -Werror -Wextra +endif + +# for object file +CFLAGS_BASE_LIST = -c +# for ASM file +# CFLAGS_BASE_LIST = -S + +FLAGS_FLTO = -flto +FLAGS_FLTO = + +CFLAGS_BASE = $(MY_ARCH_2) -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ + -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef IS_MINGW +LDFLAGS_STATIC_2 = -static +else +ifndef DEF_FILE +ifndef IS_NOT_STANDALONE +ifndef MY_DYNAMIC_LINK +ifneq ($(CC), clang) +LDFLAGS_STATIC_2 = +# -static +# -static-libstdc++ -static-libgcc +endif +endif +endif +endif +endif + +LDFLAGS_STATIC = -DNDEBUG $(LDFLAGS_STATIC_2) + +ifdef DEF_FILE + + +ifdef IS_MINGW +SHARED_EXT=.dll +LDFLAGS = -shared -DEF $(DEF_FILE) $(LDFLAGS_STATIC) +else +SHARED_EXT=.so +LDFLAGS = -shared -fPIC $(LDFLAGS_STATIC) +CC_SHARED=-fPIC +endif + + +else + +LDFLAGS = $(LDFLAGS_STATIC) +# -s is not required for clang, do we need it for GGC ??? +# -s + +#-static -static-libgcc -static-libstdc++ + +ifdef IS_MINGW +SHARED_EXT=.exe +else +SHARED_EXT= +endif + +endif + + +PROGPATH = $(O)/$(PROG)$(SHARED_EXT) +PROGPATH_STATIC = $(O)/$(PROG)s$(SHARED_EXT) + +ifndef O +O=_o +endif + +ifdef IS_MINGW + +ifdef MSYSTEM +RM = rm -f +MY_MKDIR=mkdir -p +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) +else +RM = del +MY_MKDIR=mkdir +DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll +endif + + +LIB2 = -lOle32 -loleaut32 -luuid -ladvapi32 -lUser32 -lShell32 + +CFLAGS_EXTRA = -DUNICODE -D_UNICODE +# -Wno-delete-non-virtual-dtor + + +else + +RM = rm -f +MY_MKDIR=mkdir -p +# CFLAGS_BASE := $(CFLAGS_BASE) -DZ7_ST +# CFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE + +# LOCAL_LIBS=-lpthread +# LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl +LIB2 = -lpthread -ldl + +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) + +endif + + +ifdef IS_X64 +AFLAGS_ABI = -elf64 -DABI_LINUX +else +AFLAGS_ABI = -elf -DABI_LINUX -DABI_CDECL +# -DABI_CDECL +# -DABI_LINUX +# -DABI_CDECL +endif +AFLAGS = $(AFLAGS_ABI) -Fo$(O)/ + +C_WARN_FLAGS = + +CFLAGS = $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(CFLAGS_EXTRA) $(C_WARN_FLAGS) $(FLAGS_FLTO) $(CC_SHARED) -o $@ + +STATIC_TARGET= +ifdef COMPL_STATIC +STATIC_TARGET=$(PROGPATH_STATIC) +endif + + +all: $(O) $(PROGPATH) $(STATIC_TARGET) + +$(O): + $(MY_MKDIR) $(O) + +ifneq ($(CC), $(CROSS_COMPILE)clang) +LFLAGS_STRIP = -s +endif + +LFLAGS_ALL = $(LFLAGS_STRIP) $(MY_ARCH_2) $(LDFLAGS) $(FLAGS_FLTO) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) +$(PROGPATH): $(OBJS) + $(CC) -o $(PROGPATH) $(LFLAGS_ALL) + +$(PROGPATH_STATIC): $(OBJS) + $(CC) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL) + + +ifndef NO_DEFAULT_RES +# old mingw without -FO +# windres.exe $(RFLAGS) resource.rc $O/resource.o +$O/resource.o: resource.rc + $(RC) $(RFLAGS) resource.rc $(O)/resource.o +endif +# windres.exe $(RFLAGS) resource.rc $(O)\resource.o +# windres.exe $(RFLAGS) resource.rc -FO $(O)/resource.o +# $(RC) $(RFLAGS) resource.rc -FO $(O)/resource.o + + + +$O/7zAlloc.o: ../../../C/7zAlloc.c + $(CC) $(CFLAGS) $< +$O/7zArcIn.o: ../../../C/7zArcIn.c + $(CC) $(CFLAGS) $< +$O/7zBuf.o: ../../../C/7zBuf.c + $(CC) $(CFLAGS) $< +$O/7zBuf2.o: ../../../C/7zBuf2.c + $(CC) $(CFLAGS) $< +$O/7zCrc.o: ../../../C/7zCrc.c + $(CC) $(CFLAGS) $< +$O/7zDec.o: ../../../C/7zDec.c + $(CC) $(CFLAGS) $< +$O/7zFile.o: ../../../C/7zFile.c + $(CC) $(CFLAGS) $< +$O/7zStream.o: ../../../C/7zStream.c + $(CC) $(CFLAGS) $< +$O/Aes.o: ../../../C/Aes.c + $(CC) $(CFLAGS) $< +$O/Alloc.o: ../../../C/Alloc.c + $(CC) $(CFLAGS) $< +$O/Bcj2.o: ../../../C/Bcj2.c + $(CC) $(CFLAGS) $< +$O/Bcj2Enc.o: ../../../C/Bcj2Enc.c + $(CC) $(CFLAGS) $< +$O/Blake2s.o: ../../../C/Blake2s.c + $(CC) $(CFLAGS) $< +$O/Bra.o: ../../../C/Bra.c + $(CC) $(CFLAGS) $< +$O/Bra86.o: ../../../C/Bra86.c + $(CC) $(CFLAGS) $< +$O/BraIA64.o: ../../../C/BraIA64.c + $(CC) $(CFLAGS) $< +$O/BwtSort.o: ../../../C/BwtSort.c + $(CC) $(CFLAGS) $< + +$O/CpuArch.o: ../../../C/CpuArch.c + $(CC) $(CFLAGS) $< +$O/Delta.o: ../../../C/Delta.c + $(CC) $(CFLAGS) $< +$O/DllSecur.o: ../../../C/DllSecur.c + $(CC) $(CFLAGS) $< +$O/HuffEnc.o: ../../../C/HuffEnc.c + $(CC) $(CFLAGS) $< +$O/LzFind.o: ../../../C/LzFind.c + $(CC) $(CFLAGS) $< + +# ifdef MT_FILES +$O/LzFindMt.o: ../../../C/LzFindMt.c + $(CC) $(CFLAGS) $< +$O/LzFindOpt.o: ../../../C/LzFindOpt.c + $(CC) $(CFLAGS) $< + +$O/Threads.o: ../../../C/Threads.c + $(CC) $(CFLAGS) $< +# endif + +$O/LzmaEnc.o: ../../../C/LzmaEnc.c + $(CC) $(CFLAGS) $< +$O/Lzma86Dec.o: ../../../C/Lzma86Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma86Enc.o: ../../../C/Lzma86Enc.c + $(CC) $(CFLAGS) $< +$O/Lzma2Dec.o: ../../../C/Lzma2Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma2DecMt.o: ../../../C/Lzma2DecMt.c + $(CC) $(CFLAGS) $< +$O/Lzma2Enc.o: ../../../C/Lzma2Enc.c + $(CC) $(CFLAGS) $< +$O/LzmaLib.o: ../../../C/LzmaLib.c + $(CC) $(CFLAGS) $< +$O/MtCoder.o: ../../../C/MtCoder.c + $(CC) $(CFLAGS) $< +$O/MtDec.o: ../../../C/MtDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7.o: ../../../C/Ppmd7.c + $(CC) $(CFLAGS) $< +$O/Ppmd7aDec.o: ../../../C/Ppmd7aDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Dec.o: ../../../C/Ppmd7Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Enc.o: ../../../C/Ppmd7Enc.c + $(CC) $(CFLAGS) $< +$O/Ppmd8.o: ../../../C/Ppmd8.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Dec.o: ../../../C/Ppmd8Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Enc.o: ../../../C/Ppmd8Enc.c + $(CC) $(CFLAGS) $< +$O/Sha1.o: ../../../C/Sha1.c + $(CC) $(CFLAGS) $< +$O/Sha256.o: ../../../C/Sha256.c + $(CC) $(CFLAGS) $< +$O/Sort.o: ../../../C/Sort.c + $(CC) $(CFLAGS) $< +$O/SwapBytes.o: ../../../C/SwapBytes.c + $(CC) $(CFLAGS) $< +$O/Xz.o: ../../../C/Xz.c + $(CC) $(CFLAGS) $< +$O/XzCrc64.o: ../../../C/XzCrc64.c + $(CC) $(CFLAGS) $< +$O/XzDec.o: ../../../C/XzDec.c + $(CC) $(CFLAGS) $< +$O/XzEnc.o: ../../../C/XzEnc.c + $(CC) $(CFLAGS) $< +$O/XzIn.o: ../../../C/XzIn.c + $(CC) $(CFLAGS) $< + + +ifdef USE_ASM +ifdef IS_X64 +USE_X86_ASM=1 +else +ifdef IS_X86 +USE_X86_ASM=1 +endif +endif +endif + +ifdef USE_X86_ASM +$O/7zCrcOpt.o: ../../../Asm/x86/7zCrcOpt.asm + $(MY_ASM) $(AFLAGS) $< +$O/XzCrc64Opt.o: ../../../Asm/x86/XzCrc64Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/AesOpt.o: ../../../Asm/x86/AesOpt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha1Opt.o: ../../../Asm/x86/Sha1Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha256Opt.o: ../../../Asm/x86/Sha256Opt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/7zCrcOpt.o: ../../7zCrcOpt.c + $(CC) $(CFLAGS) $< +$O/XzCrc64Opt.o: ../../XzCrc64Opt.c + $(CC) $(CFLAGS) $< +$O/Sha1Opt.o: ../../Sha1Opt.c + $(CC) $(CFLAGS) $< +$O/Sha256Opt.o: ../../Sha256Opt.c + $(CC) $(CFLAGS) $< +$O/AesOpt.o: ../../AesOpt.c + $(CC) $(CFLAGS) $< +endif + + +ifdef USE_LZMA_DEC_ASM + +ifdef IS_X64 +$O/LzmaDecOpt.o: ../../../Asm/x86/LzmaDecOpt.asm + $(MY_ASM) $(AFLAGS) $< +endif + +ifdef IS_ARM64 +$O/LzmaDecOpt.o: ../../../Asm/arm64/LzmaDecOpt.S ../../../Asm/arm64/7zAsm.S + $(CC) $(CFLAGS) $(ASM_FLAGS) $< +endif + +$O/LzmaDec.o: ../../LzmaDec.c + $(CC) $(CFLAGS) -DZ7_LZMA_DEC_OPT $< + +else + +$O/LzmaDec.o: ../../LzmaDec.c + $(CC) $(CFLAGS) $< + +endif + + + +$O/7zMain.o: ../../../C/Util/7z/7zMain.c + $(CC) $(CFLAGS) $< +$O/7zipInstall.o: ../../../C/Util/7zipInstall/7zipInstall.c + $(CC) $(CFLAGS) $< +$O/7zipUninstall.o: ../../../C/Util/7zipUninstall/7zipUninstall.c + $(CC) $(CFLAGS) $< +$O/LzmaUtil.o: ../../../C/Util/Lzma/LzmaUtil.c + $(CC) $(CFLAGS) $< +$O/XzUtil.o: ../../../C/Util/Xz/XzUtil.c + $(CC) $(CFLAGS) $< + + +clean: + -$(DEL_OBJ_EXE) diff -Nru p7zip-rar-16.02/C/Aes.c p7zip-rar-16.02+really25.00+ds/C/Aes.c --- p7zip-rar-16.02/C/Aes.c 2016-06-11 08:30:35.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Aes.c 2024-03-01 11:00:00.000000000 +0000 @@ -1,297 +1,429 @@ -/* Aes.c -- AES encryption / decryption -2016-05-21 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Aes.h" -#include "CpuArch.h" - -static UInt32 T[256 * 4]; -static const Byte Sbox[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; - -void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); - -void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); - -AES_CODE_FUNC g_AesCbc_Encode; -AES_CODE_FUNC g_AesCbc_Decode; -AES_CODE_FUNC g_AesCtr_Code; - -static UInt32 D[256 * 4]; -static Byte InvS[256]; - -static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; - -#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) - -#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) - -#define gb0(x) ( (x) & 0xFF) -#define gb1(x) (((x) >> ( 8)) & 0xFF) -#define gb2(x) (((x) >> (16)) & 0xFF) -#define gb3(x) (((x) >> (24)) & 0xFF) - -void AesGenTables(void) -{ - unsigned i; - for (i = 0; i < 256; i++) - InvS[Sbox[i]] = (Byte)i; - - for (i = 0; i < 256; i++) - { - { - UInt32 a1 = Sbox[i]; - UInt32 a2 = xtime(a1); - UInt32 a3 = a2 ^ a1; - T[ i] = Ui32(a2, a1, a1, a3); - T[0x100 + i] = Ui32(a3, a2, a1, a1); - T[0x200 + i] = Ui32(a1, a3, a2, a1); - T[0x300 + i] = Ui32(a1, a1, a3, a2); - } - { - UInt32 a1 = InvS[i]; - UInt32 a2 = xtime(a1); - UInt32 a4 = xtime(a2); - UInt32 a8 = xtime(a4); - UInt32 a9 = a8 ^ a1; - UInt32 aB = a8 ^ a2 ^ a1; - UInt32 aD = a8 ^ a4 ^ a1; - UInt32 aE = a8 ^ a4 ^ a2; - D[ i] = Ui32(aE, a9, aD, aB); - D[0x100 + i] = Ui32(aB, aE, a9, aD); - D[0x200 + i] = Ui32(aD, aB, aE, a9); - D[0x300 + i] = Ui32(a9, aD, aB, aE); - } - } - - g_AesCbc_Encode = AesCbc_Encode; - g_AesCbc_Decode = AesCbc_Decode; - g_AesCtr_Code = AesCtr_Code; - - #ifdef MY_CPU_X86_OR_AMD64 - #ifdef _7ZIP_ASM - if (CPU_Is_Aes_Supported()) - { - g_AesCbc_Encode = AesCbc_Encode_Intel; - g_AesCbc_Decode = AesCbc_Decode_Intel; - g_AesCtr_Code = AesCtr_Code_Intel; - } - #endif - #endif -} - - -#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])] - -#define HT4(m, i, s, p) m[i] = \ - HT(i, 0, s) ^ \ - HT(i, 1, s) ^ \ - HT(i, 2, s) ^ \ - HT(i, 3, s) ^ w[p + i] - -#define HT16(m, s, p) \ - HT4(m, 0, s, p); \ - HT4(m, 1, s, p); \ - HT4(m, 2, s, p); \ - HT4(m, 3, s, p); \ - -#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] -#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; - - -#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])] - -#define HD4(m, i, s, p) m[i] = \ - HD(i, 0, s) ^ \ - HD(i, 1, s) ^ \ - HD(i, 2, s) ^ \ - HD(i, 3, s) ^ w[p + i]; - -#define HD16(m, s, p) \ - HD4(m, 0, s, p); \ - HD4(m, 1, s, p); \ - HD4(m, 2, s, p); \ - HD4(m, 3, s, p); \ - -#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])] -#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; - -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, wSize; - wSize = keySize + 28; - keySize /= 4; - w[0] = ((UInt32)keySize / 2) + 3; - w += 4; - - for (i = 0; i < keySize; i++, key += 4) - w[i] = GetUi32(key); - - for (; i < wSize; i++) - { - UInt32 t = w[i - 1]; - unsigned rem = i % keySize; - if (rem == 0) - t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); - else if (keySize > 6 && rem == 4) - t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); - w[i] = w[i - keySize] ^ t; - } -} - -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, num; - Aes_SetKey_Enc(w, key, keySize); - num = keySize + 20; - w += 8; - for (i = 0; i < num; i++) - { - UInt32 r = w[i]; - w[i] = - D[ (unsigned)Sbox[gb0(r)]] ^ - D[0x100 + (unsigned)Sbox[gb1(r)]] ^ - D[0x200 + (unsigned)Sbox[gb2(r)]] ^ - D[0x300 + (unsigned)Sbox[gb3(r)]]; - } -} - -/* Aes_Encode and Aes_Decode functions work with little-endian words. - src and dest are pointers to 4 UInt32 words. - src and dest can point to same block */ - -static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - w += 4; - for (;;) - { - HT16(m, s, 0); - if (--numRounds2 == 0) - break; - HT16(s, m, 4); - w += 8; - } - w += 4; - FT4(0); FT4(1); FT4(2); FT4(3); -} - -static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4 + numRounds2 * 8; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - for (;;) - { - w -= 8; - HD16(m, s, 4); - if (--numRounds2 == 0) - break; - HD16(s, m, 0); - } - FD4(0); FD4(1); FD4(2); FD4(3); -} - -void AesCbc_Init(UInt32 *p, const Byte *iv) -{ - unsigned i; - for (i = 0; i < 4; i++) - p[i] = GetUi32(iv + i * 4); -} - -void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - p[0] ^= GetUi32(data); - p[1] ^= GetUi32(data + 4); - p[2] ^= GetUi32(data + 8); - p[3] ^= GetUi32(data + 12); - - Aes_Encode(p + 4, p, p); - - SetUi32(data, p[0]); - SetUi32(data + 4, p[1]); - SetUi32(data + 8, p[2]); - SetUi32(data + 12, p[3]); - } -} - -void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) -{ - UInt32 in[4], out[4]; - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - in[0] = GetUi32(data); - in[1] = GetUi32(data + 4); - in[2] = GetUi32(data + 8); - in[3] = GetUi32(data + 12); - - Aes_Decode(p + 4, out, in); - - SetUi32(data, p[0] ^ out[0]); - SetUi32(data + 4, p[1] ^ out[1]); - SetUi32(data + 8, p[2] ^ out[2]); - SetUi32(data + 12, p[3] ^ out[3]); - - p[0] = in[0]; - p[1] = in[1]; - p[2] = in[2]; - p[3] = in[3]; - } -} - -void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--) - { - UInt32 temp[4]; - Byte buf[16]; - int i; - - if (++p[0] == 0) - p[1]++; - - Aes_Encode(p + 4, temp, p); - - SetUi32(buf, temp[0]); - SetUi32(buf + 4, temp[1]); - SetUi32(buf + 8, temp[2]); - SetUi32(buf + 12, temp[3]); - - for (i = 0; i < 16; i++) - *data++ ^= buf[i]; - } -} +/* Aes.c -- AES encryption / decryption +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "Aes.h" + +AES_CODE_FUNC g_AesCbc_Decode; +#ifndef Z7_SFX +AES_CODE_FUNC g_AesCbc_Encode; +AES_CODE_FUNC g_AesCtr_Code; +UInt32 g_Aes_SupportedFunctions_Flags; +#endif + +MY_ALIGN(64) +static UInt32 T[256 * 4]; +MY_ALIGN(64) +static const Byte Sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + + +MY_ALIGN(64) +static UInt32 D[256 * 4]; +MY_ALIGN(64) +static Byte InvS[256]; + +#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) + +#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) + +#define gb0(x) ( (x) & 0xFF) +#define gb1(x) (((x) >> ( 8)) & 0xFF) +#define gb2(x) (((x) >> (16)) & 0xFF) +#define gb3(x) (((x) >> (24))) + +#define gb(n, x) gb ## n(x) + +#define TT(x) (T + (x << 8)) +#define DD(x) (D + (x << 8)) + + +// #define Z7_SHOW_AES_STATUS + +#ifdef MY_CPU_X86_OR_AMD64 + + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) + #define USE_HW_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_HW_VAES + #endif + #endif + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_HW_AES + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_HW_VAES + #endif + #elif defined(_MSC_VER) + #define USE_HW_AES + #define USE_HW_VAES + #endif + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_AES + #endif + #endif + #endif + #endif +#endif + +#ifdef USE_HW_AES +// #pragma message("=== Aes.c USE_HW_AES === ") +#ifdef Z7_SHOW_AES_STATUS +#include +#define PRF(x) x +#else +#define PRF(x) +#endif +#endif + + +void AesGenTables(void) +{ + unsigned i; + for (i = 0; i < 256; i++) + InvS[Sbox[i]] = (Byte)i; + + for (i = 0; i < 256; i++) + { + { + const UInt32 a1 = Sbox[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a3 = a2 ^ a1; + TT(0)[i] = Ui32(a2, a1, a1, a3); + TT(1)[i] = Ui32(a3, a2, a1, a1); + TT(2)[i] = Ui32(a1, a3, a2, a1); + TT(3)[i] = Ui32(a1, a1, a3, a2); + } + { + const UInt32 a1 = InvS[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a4 = xtime(a2); + const UInt32 a8 = xtime(a4); + const UInt32 a9 = a8 ^ a1; + const UInt32 aB = a8 ^ a2 ^ a1; + const UInt32 aD = a8 ^ a4 ^ a1; + const UInt32 aE = a8 ^ a4 ^ a2; + DD(0)[i] = Ui32(aE, a9, aD, aB); + DD(1)[i] = Ui32(aB, aE, a9, aD); + DD(2)[i] = Ui32(aD, aB, aE, a9); + DD(3)[i] = Ui32(a9, aD, aB, aE); + } + } + + { + AES_CODE_FUNC d = AesCbc_Decode; + #ifndef Z7_SFX + AES_CODE_FUNC e = AesCbc_Encode; + AES_CODE_FUNC c = AesCtr_Code; + UInt32 flags = 0; + #endif + + #ifdef USE_HW_AES + if (CPU_IsSupported_AES()) + { + // #pragma message ("AES HW") + PRF(printf("\n===AES HW\n")); + d = AesCbc_Decode_HW; + + #ifndef Z7_SFX + e = AesCbc_Encode_HW; + c = AesCtr_Code_HW; + flags = k_Aes_SupportedFunctions_HW; + #endif + + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_HW_VAES + if (CPU_IsSupported_VAES_AVX2()) + { + PRF(printf("\n===vaes avx2\n")); + d = AesCbc_Decode_HW_256; + #ifndef Z7_SFX + c = AesCtr_Code_HW_256; + flags |= k_Aes_SupportedFunctions_HW_256; + #endif + } + #endif + #endif + } + #endif + + g_AesCbc_Decode = d; + #ifndef Z7_SFX + g_AesCbc_Encode = e; + g_AesCtr_Code = c; + g_Aes_SupportedFunctions_Flags = flags; + #endif + } +} + + +#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])] + +#define HT4(m, i, s, p) m[i] = \ + HT(i, 0, s) ^ \ + HT(i, 1, s) ^ \ + HT(i, 2, s) ^ \ + HT(i, 3, s) ^ w[p + i] + +#define HT16(m, s, p) \ + HT4(m, 0, s, p); \ + HT4(m, 1, s, p); \ + HT4(m, 2, s, p); \ + HT4(m, 3, s, p); \ + +#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])] +#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; + + +#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])] + +#define HD4(m, i, s, p) m[i] = \ + HD(i, 0, s) ^ \ + HD(i, 1, s) ^ \ + HD(i, 2, s) ^ \ + HD(i, 3, s) ^ w[p + i]; + +#define HD16(m, s, p) \ + HD4(m, 0, s, p); \ + HD4(m, 1, s, p); \ + HD4(m, 2, s, p); \ + HD4(m, 3, s, p); \ + +#define FD(i, x) InvS[gb(x, m[(i - x) & 3])] +#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; + +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, m; + const UInt32 *wLim; + UInt32 t; + UInt32 rcon = 1; + + keySize /= 4; + w[0] = ((UInt32)keySize / 2) + 3; + w += 4; + + for (i = 0; i < keySize; i++, key += 4) + w[i] = GetUi32(key); + + t = w[(size_t)keySize - 1]; + wLim = w + (size_t)keySize * 3 + 28; + m = 0; + do + { + if (m == 0) + { + t = Ui32(Sbox[gb1(t)] ^ rcon, Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); + rcon <<= 1; + if (rcon & 0x100) + rcon = 0x1b; + m = keySize; + } + else if (m == 4 && keySize > 6) + t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); + m--; + t ^= w[0]; + w[keySize] = t; + } + while (++w != wLim); +} + +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, num; + Aes_SetKey_Enc(w, key, keySize); + num = keySize + 20; + w += 8; + for (i = 0; i < num; i++) + { + UInt32 r = w[i]; + w[i] = + DD(0)[Sbox[gb0(r)]] ^ + DD(1)[Sbox[gb1(r)]] ^ + DD(2)[Sbox[gb2(r)]] ^ + DD(3)[Sbox[gb3(r)]]; + } +} + +/* Aes_Encode and Aes_Decode functions work with little-endian words. + src and dest are pointers to 4 UInt32 words. + src and dest can point to same block */ + +// Z7_FORCE_INLINE +static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + w += 4; + for (;;) + { + HT16(m, s, 0) + if (--numRounds2 == 0) + break; + HT16(s, m, 4) + w += 8; + } + w += 4; + FT4(0) + FT4(1) + FT4(2) + FT4(3) +} + +Z7_FORCE_INLINE +static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4 + numRounds2 * 8; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + for (;;) + { + w -= 8; + HD16(m, s, 4) + if (--numRounds2 == 0) + break; + HD16(s, m, 0) + } + FD4(0) + FD4(1) + FD4(2) + FD4(3) +} + +void AesCbc_Init(UInt32 *p, const Byte *iv) +{ + unsigned i; + for (i = 0; i < 4; i++) + p[i] = GetUi32(iv + i * 4); +} + +void Z7_FASTCALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + p[0] ^= GetUi32(data); + p[1] ^= GetUi32(data + 4); + p[2] ^= GetUi32(data + 8); + p[3] ^= GetUi32(data + 12); + + Aes_Encode(p + 4, p, p); + + SetUi32(data, p[0]) + SetUi32(data + 4, p[1]) + SetUi32(data + 8, p[2]) + SetUi32(data + 12, p[3]) + } +} + +void Z7_FASTCALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) +{ + UInt32 in[4], out[4]; + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + in[0] = GetUi32(data); + in[1] = GetUi32(data + 4); + in[2] = GetUi32(data + 8); + in[3] = GetUi32(data + 12); + + Aes_Decode(p + 4, out, in); + + SetUi32(data, p[0] ^ out[0]) + SetUi32(data + 4, p[1] ^ out[1]) + SetUi32(data + 8, p[2] ^ out[2]) + SetUi32(data + 12, p[3] ^ out[3]) + + p[0] = in[0]; + p[1] = in[1]; + p[2] = in[2]; + p[3] = in[3]; + } +} + +void Z7_FASTCALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--) + { + UInt32 temp[4]; + unsigned i; + + if (++p[0] == 0) + p[1]++; + + Aes_Encode(p + 4, temp, p); + + for (i = 0; i < 4; i++, data += 4) + { + const UInt32 t = temp[i]; + + #ifdef MY_CPU_LE_UNALIGN + *((UInt32 *)(void *)data) ^= t; + #else + data[0] = (Byte)(data[0] ^ (t & 0xFF)); + data[1] = (Byte)(data[1] ^ ((t >> 8) & 0xFF)); + data[2] = (Byte)(data[2] ^ ((t >> 16) & 0xFF)); + data[3] = (Byte)(data[3] ^ ((t >> 24))); + #endif + } + } +} + +#undef xtime +#undef Ui32 +#undef gb0 +#undef gb1 +#undef gb2 +#undef gb3 +#undef gb +#undef TT +#undef DD +#undef USE_HW_AES +#undef PRF diff -Nru p7zip-rar-16.02/C/Aes.h p7zip-rar-16.02+really25.00+ds/C/Aes.h --- p7zip-rar-16.02/C/Aes.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Aes.h 2023-04-02 11:00:00.000000000 +0000 @@ -1,38 +1,60 @@ -/* Aes.h -- AES encryption / decryption -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __AES_H -#define __AES_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define AES_BLOCK_SIZE 16 - -/* Call AesGenTables one time before other AES functions */ -void AesGenTables(void); - -/* UInt32 pointers must be 16-byte aligned */ - -/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ -#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) - -/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ -/* keySize = 16 or 24 or 32 (bytes) */ -typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); -void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); - -/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ -void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ -/* data - 16-byte aligned pointer to data */ -/* numBlocks - the number of 16-byte blocks in data array */ -typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); -extern AES_CODE_FUNC g_AesCbc_Encode; -extern AES_CODE_FUNC g_AesCbc_Decode; -extern AES_CODE_FUNC g_AesCtr_Code; - -EXTERN_C_END - -#endif +/* Aes.h -- AES encryption / decryption +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_AES_H +#define ZIP7_INC_AES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define AES_BLOCK_SIZE 16 + +/* Call AesGenTables one time before other AES functions */ +void AesGenTables(void); + +/* UInt32 pointers must be 16-byte aligned */ + +/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ +#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) + +/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ +/* keySize = 16 or 24 or 32 (bytes) */ +typedef void (Z7_FASTCALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); + +/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ +void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ + +/* data - 16-byte aligned pointer to data */ +/* numBlocks - the number of 16-byte blocks in data array */ +typedef void (Z7_FASTCALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); + +extern AES_CODE_FUNC g_AesCbc_Decode; +#ifndef Z7_SFX +extern AES_CODE_FUNC g_AesCbc_Encode; +extern AES_CODE_FUNC g_AesCtr_Code; +#define k_Aes_SupportedFunctions_HW (1 << 2) +#define k_Aes_SupportedFunctions_HW_256 (1 << 3) +extern UInt32 g_Aes_SupportedFunctions_Flags; +#endif + + +#define Z7_DECLARE_AES_CODE_FUNC(funcName) \ + void Z7_FASTCALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks); + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code) + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW) + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW_256) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW_256) + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/AesOpt.c p7zip-rar-16.02+really25.00+ds/C/AesOpt.c --- p7zip-rar-16.02/C/AesOpt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/AesOpt.c 2024-11-24 15:00:00.000000000 +0000 @@ -0,0 +1,1002 @@ +/* AesOpt.c -- AES optimized code for x86 AES hardware instructions +Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Aes.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) + #define USE_INTEL_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_INTEL_VAES + #endif + #endif + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_INTEL_AES + #if !defined(__AES__) + #define ATTRIB_AES __attribute__((__target__("aes"))) + #endif + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_INTEL_VAES + #if !defined(__AES__) || !defined(__VAES__) || !defined(__AVX__) || !defined(__AVX2__) + #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx,avx2"))) + #endif + #endif + #elif defined(_MSC_VER) + #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) + #define USE_INTEL_AES + #if (_MSC_VER >= 1910) + #define USE_INTEL_VAES + #endif + #endif + #ifndef USE_INTEL_AES + #define Z7_USE_AES_HW_STUB + #endif + #ifndef USE_INTEL_VAES + #define Z7_USE_VAES_HW_STUB + #endif + #endif + + #ifndef USE_INTEL_AES + // #define Z7_USE_AES_HW_STUB // for debug + #endif + #ifndef USE_INTEL_VAES + // #define Z7_USE_VAES_HW_STUB // for debug + #endif + + +#ifdef USE_INTEL_AES + +#include + +#if !defined(USE_INTEL_VAES) && defined(Z7_USE_VAES_HW_STUB) +#define AES_TYPE_keys UInt32 +#define AES_TYPE_data Byte +// #define AES_TYPE_keys __m128i +// #define AES_TYPE_data __m128i +#endif + +#ifndef ATTRIB_AES + #define ATTRIB_AES +#endif + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(__m128i *p, __m128i *data, size_t numBlocks) + +#define AES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_AES \ +AES_FUNC_START (name) + +#define MM_OP(op, dest, src) dest = op(dest, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) + +#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src) + +#if 1 +// use aligned SSE load/store for data. +// It is required for our Aes functions, that data is aligned for 16-bytes. +// So we can use this branch of code. +// and compiler can use fused load-op SSE instructions: +// xorps xmm0, XMMWORD PTR [rdx] +#define LOAD_128(pp) (*(__m128i *)(void *)(pp)) +#define STORE_128(pp, _v) *(__m128i *)(void *)(pp) = _v +// use aligned SSE load/store for data. Alternative code with direct access +// #define LOAD_128(pp) _mm_load_si128(pp) +// #define STORE_128(pp, _v) _mm_store_si128(pp, _v) +#else +// use unaligned load/store for data: movdqu XMMWORD PTR [rdx] +#define LOAD_128(pp) _mm_loadu_si128(pp) +#define STORE_128(pp, _v) _mm_storeu_si128(pp, _v) +#endif + +AES_FUNC_START2 (AesCbc_Encode_HW) +{ + if (numBlocks == 0) + return; + { + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i m = *p; + const __m128i k0 = p[2]; + const __m128i k1 = p[3]; + const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; + do + { + UInt32 r = numRounds2; + const __m128i *w = p + 4; + __m128i temp = LOAD_128(data); + MM_XOR (temp, k0) + MM_XOR (m, temp) + MM_OP_m (_mm_aesenc_si128, k1) + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--r); + MM_OP_m (_mm_aesenclast_si128, w[0]) + STORE_128(data, m); + data++; + } + while (--numBlocks); + *p = m; + } +} + + +#define WOP_1(op) +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) +#ifdef MY_CPU_AMD64 +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) +#endif +/* +#define WOP_9(op) WOP_8 (op) op (m8, 8); +#define WOP_10(op) WOP_9 (op) op (m9, 9); +#define WOP_11(op) WOP_10(op) op (m10, 10); +#define WOP_12(op) WOP_11(op) op (m11, 11); +#define WOP_13(op) WOP_12(op) op (m12, 12); +#define WOP_14(op) WOP_13(op) op (m13, 13); +*/ + +#ifdef MY_CPU_AMD64 + #define NUM_WAYS 8 + #define WOP_M1 WOP_8 +#else + #define NUM_WAYS 4 + #define WOP_M1 WOP_4 +#endif + +#define WOP(op) op (m0, 0) WOP_M1(op) + +#define DECLARE_VAR(reg, ii) __m128i reg; +#define LOAD_data_ii(ii) LOAD_128(data + (ii)) +#define LOAD_data( reg, ii) reg = LOAD_data_ii(ii); +#define STORE_data( reg, ii) STORE_128(data + (ii), reg); +#if (NUM_WAYS > 1) +#define XOR_data_M1(reg, ii) MM_XOR (reg, LOAD_128(data + (ii- 1))) +#endif + +#define MM_OP_key(op, reg) MM_OP(op, reg, key); + +#define AES_DEC( reg, ii) MM_OP_key (_mm_aesdec_si128, reg) +#define AES_DEC_LAST( reg, ii) MM_OP_key (_mm_aesdeclast_si128, reg) +#define AES_ENC( reg, ii) MM_OP_key (_mm_aesenc_si128, reg) +#define AES_ENC_LAST( reg, ii) MM_OP_key (_mm_aesenclast_si128, reg) +#define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg) + +#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr; +#define CTR_END( reg, ii) STORE_128(data + (ii), _mm_xor_si128(reg, \ + LOAD_128 (data + (ii)))); +#define WOP_KEY(op, n) { \ + const __m128i key = w[n]; \ + WOP(op) } + +#define WIDE_LOOP_START \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS) \ + { dataEnd -= NUM_WAYS; do { \ + +#define WIDE_LOOP_END \ + data += NUM_WAYS; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS; } \ + +#define SINGLE_LOOP \ + for (; data < dataEnd; data++) + + + +#ifdef USE_INTEL_VAES + +#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src) +#define AVX_DECLARE_VAR(reg, ii) __m256i reg; + +#if 1 +// use unaligned AVX load/store for data. +// It is required for our Aes functions, that data is aligned for 16-bytes. +// But we need 32-bytes reading. +// So we use intrinsics for unaligned AVX load/store. +// notes for _mm256_storeu_si256: +// msvc2022: uses vmovdqu and keeps the order of instruction sequence. +// new gcc11 uses vmovdqu +// old gcc9 could use pair of instructions: +// vmovups %xmm7, -224(%rax) +// vextracti128 $0x1, %ymm7, -208(%rax) +#define AVX_LOAD(p) _mm256_loadu_si256((const __m256i *)(const void *)(p)) +#define AVX_STORE(p, _v) _mm256_storeu_si256((__m256i *)(void *)(p), _v); +#else +// use aligned AVX load/store for data. +// for debug: we can use this branch, if we are sure that data is aligned for 32-bytes. +// msvc2022 uses vmovdqu still +// gcc uses vmovdqa (that requires 32-bytes alignment) +#define AVX_LOAD(p) (*(const __m256i *)(const void *)(p)) +#define AVX_STORE(p, _v) (*(__m256i *)(void *)(p)) = _v; +#endif + +#define AVX_LOAD_data( reg, ii) reg = AVX_LOAD((const __m256i *)(const void *)data + (ii)); +#define AVX_STORE_data( reg, ii) AVX_STORE((__m256i *)(void *)data + (ii), reg) +/* +AVX_XOR_data_M1() needs unaligned memory load, even if (data) +is aligned for 256-bits, because we read 32-bytes chunk that +crosses (data) position: from (data - 16bytes) to (data + 16bytes). +*/ +#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, _mm256_loadu_si256((const __m256i *)(const void *)(data - 1) + (ii))) + +#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg) +#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg) +#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg) +#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg) +#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg) +#define AVX_CTR_START(reg, ii) \ + MM_OP (_mm256_add_epi64, ctr2, two) \ + reg = _mm256_xor_si256(ctr2, key); + +#define AVX_CTR_END(reg, ii) \ + AVX_STORE((__m256i *)(void *)data + (ii), _mm256_xor_si256(reg, \ + AVX_LOAD ((__m256i *)(void *)data + (ii)))); + +#define AVX_WOP_KEY(op, n) { \ + const __m256i key = w[n]; \ + WOP(op) } + +#define NUM_AES_KEYS_MAX 15 + +#define WIDE_LOOP_START_AVX(OP) \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS * 2) \ + { __m256i keys[NUM_AES_KEYS_MAX]; \ + OP \ + { UInt32 ii; for (ii = 0; ii < numRounds; ii++) \ + keys[ii] = _mm256_broadcastsi128_si256(p[ii]); } \ + dataEnd -= NUM_WAYS * 2; \ + do { \ + +#define WIDE_LOOP_END_AVX(OP) \ + data += NUM_WAYS * 2; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS * 2; \ + OP \ + _mm256_zeroupper(); \ + } \ + +/* MSVC for x86: If we don't call _mm256_zeroupper(), and -arch:IA32 is not specified, + MSVC still can insert vzeroupper instruction. */ + +#endif + + + +AES_FUNC_START2 (AesCbc_Decode_HW) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i iv = *p; + const __m128i * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2 + 2 - 1; + const __m128i *dataEnd; + p += 2; + + WIDE_LOOP_START + { + const __m128i *w = wStart; + WOP (DECLARE_VAR) + WOP (LOAD_data) + WOP_KEY (AES_XOR, 1) + do + { + WOP_KEY (AES_DEC, 0) + + w--; + } + while (w != p); + WOP_KEY (AES_DEC_LAST, 0) + + MM_XOR (m0, iv) + WOP_M1 (XOR_data_M1) + LOAD_data(iv, NUM_WAYS - 1) + WOP (STORE_data) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const __m128i *w = wStart - 1; + __m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0)); + + do + { + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) + w -= 2; + } + while (w != p); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) + MM_XOR (m, iv) + LOAD_data(iv, 0) + STORE_data(m, 0) + } + + p[-2] = iv; +} + + +AES_FUNC_START2 (AesCtr_Code_HW) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i ctr = *p; + const UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1; + const __m128i *dataEnd; + const __m128i one = _mm_cvtsi32_si128(1); + + p += 2; + + WIDE_LOOP_START + { + const __m128i *w = p; + UInt32 r = numRoundsMinus2; + WOP (DECLARE_VAR) + WOP (CTR_START) + WOP_KEY (AES_XOR, 0) + w += 1; + do + { + WOP_KEY (AES_ENC, 0) + w += 1; + } + while (--r); + WOP_KEY (AES_ENC_LAST, 0) + WOP (CTR_END) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; + const __m128i *w = p; + __m128i m; + MM_OP (_mm_add_epi64, ctr, one) + m = _mm_xor_si128 (ctr, p[0]); + w += 1; + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--numRounds2); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + CTR_END (m, 0) + } + + p[-2] = ctr; +} + + + +#ifdef USE_INTEL_VAES + +/* +GCC before 2013-Jun: + : + #ifdef __AVX__ + #include + #endif +GCC after 2013-Jun: + : + #include +CLANG 3.8+: +{ + : + #if !defined(_MSC_VER) || defined(__AVX__) + #include + #endif + + if (the compiler is clang for Windows and if global arch is not set for __AVX__) + [ if (defined(_MSC_VER) && !defined(__AVX__)) ] + { + doesn't include + and we have 2 ways to fix it: + 1) we can define required __AVX__ before + or + 2) we can include after + } +} + +If we include manually for GCC/CLANG, it's +required that must be included before . +*/ + +/* +#if defined(__clang__) && defined(_MSC_VER) +#define __AVX__ +#define __AVX2__ +#define __VAES__ +#endif +*/ + +#include +#if defined(__clang__) && defined(_MSC_VER) + #if !defined(__AVX__) + #include + #endif + #if !defined(__AVX2__) + #include + #endif + #if !defined(__VAES__) + #include + #endif +#endif // __clang__ && _MSC_VER + +#ifndef ATTRIB_VAES + #define ATTRIB_VAES +#endif + +#define VAES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_VAES \ +AES_FUNC_START (name) + +VAES_FUNC_START2 (AesCbc_Decode_HW_256) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i iv = *p; + const __m128i *dataEnd; + const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + p += 2; + + WIDE_LOOP_START_AVX(;) + { + const __m256i *w = keys + numRounds - 2; + + WOP (AVX_DECLARE_VAR) + WOP (AVX_LOAD_data) + AVX_WOP_KEY (AVX_AES_XOR, 1) + + do + { + AVX_WOP_KEY (AVX_AES_DEC, 0) + w--; + } + while (w != keys); + AVX_WOP_KEY (AVX_AES_DEC_LAST, 0) + + AVX_XOR (m0, _mm256_setr_m128i(iv, LOAD_data_ii(0))) + WOP_M1 (AVX_XOR_data_M1) + LOAD_data (iv, NUM_WAYS * 2 - 1) + WOP (AVX_STORE_data) + } + WIDE_LOOP_END_AVX(;) + + SINGLE_LOOP + { + const __m128i *w = p - 2 + (size_t)*(const UInt32 *)(p + 1 - 2) * 2; + __m128i m = _mm_xor_si128 (w[2], LOAD_data_ii(0)); + do + { + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) + w -= 2; + } + while (w != p); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) + + MM_XOR (m, iv) + LOAD_data(iv, 0) + STORE_data(m, 0) + } + + p[-2] = iv; +} + + +/* +SSE2: _mm_cvtsi32_si128 : movd +AVX: _mm256_setr_m128i : vinsertf128 +AVX2: _mm256_add_epi64 : vpaddq ymm, ymm, ymm + _mm256_extracti128_si256 : vextracti128 + _mm256_broadcastsi128_si256 : vbroadcasti128 +*/ + +#define AVX_CTR_LOOP_START \ + ctr2 = _mm256_setr_m128i(_mm_sub_epi64(ctr, one), ctr); \ + two = _mm256_setr_m128i(one, one); \ + two = _mm256_add_epi64(two, two); \ + +// two = _mm256_setr_epi64x(2, 0, 2, 0); + +#define AVX_CTR_LOOP_ENC \ + ctr = _mm256_extracti128_si256 (ctr2, 1); \ + +VAES_FUNC_START2 (AesCtr_Code_HW_256) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i ctr = *p; + const UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + const __m128i *dataEnd; + const __m128i one = _mm_cvtsi32_si128(1); + __m256i ctr2, two; + p += 2; + + WIDE_LOOP_START_AVX (AVX_CTR_LOOP_START) + { + const __m256i *w = keys; + UInt32 r = numRounds - 2; + WOP (AVX_DECLARE_VAR) + AVX_WOP_KEY (AVX_CTR_START, 0) + + w += 1; + do + { + AVX_WOP_KEY (AVX_AES_ENC, 0) + w += 1; + } + while (--r); + AVX_WOP_KEY (AVX_AES_ENC_LAST, 0) + + WOP (AVX_CTR_END) + } + WIDE_LOOP_END_AVX (AVX_CTR_LOOP_ENC) + + SINGLE_LOOP + { + UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; + const __m128i *w = p; + __m128i m; + MM_OP (_mm_add_epi64, ctr, one) + m = _mm_xor_si128 (ctr, p[0]); + w += 1; + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--numRounds2); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + CTR_END (m, 0) + } + + p[-2] = ctr; +} + +#endif // USE_INTEL_VAES + +#else // USE_INTEL_AES + +/* no USE_INTEL_AES */ + +#if defined(Z7_USE_AES_HW_STUB) +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. +// #if defined(_MSC_VER) +#pragma message("AES HW_SW stub was used") +// #endif + +#if !defined(USE_INTEL_VAES) && defined(Z7_USE_VAES_HW_STUB) +#define AES_TYPE_keys UInt32 +#define AES_TYPE_data Byte +#endif + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *p, Byte *data, size_t numBlocks) \ + +#define AES_COMPAT_STUB(name) \ + AES_FUNC_START(name); \ + AES_FUNC_START(name ## _HW) \ + { name(p, data, numBlocks); } + +AES_COMPAT_STUB (AesCbc_Encode) +AES_COMPAT_STUB (AesCbc_Decode) +AES_COMPAT_STUB (AesCtr_Code) +#endif // Z7_USE_AES_HW_STUB + +#endif // USE_INTEL_AES + + +#ifndef USE_INTEL_VAES +#if defined(Z7_USE_VAES_HW_STUB) +// #if defined(_MSC_VER) +#pragma message("VAES HW_SW stub was used") +// #endif + +#define VAES_COMPAT_STUB(name) \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks); \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks) \ + { name((AES_TYPE_keys *)(void *)p, (AES_TYPE_data *)(void *)data, numBlocks); } + +VAES_COMPAT_STUB (AesCbc_Decode_HW) +VAES_COMPAT_STUB (AesCtr_Code_HW) +#endif +#endif // ! USE_INTEL_VAES + + + + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_AES + #endif + #endif + #endif + #endif + +#ifdef USE_HW_AES + +// #pragma message("=== AES HW === ") +// __ARM_FEATURE_CRYPTO macro is deprecated in favor of the finer grained feature macro __ARM_FEATURE_AES + +#if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_AES) && \ + !defined(__ARM_FEATURE_CRYPTO) + #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_AES __attribute__((__target__("crypto"))) +#else + #define ATTRIB_AES __attribute__((__target__("+crypto"))) +#endif + #else +#if defined(__clang__) + #define ATTRIB_AES __attribute__((__target__("armv8-a,aes"))) +#else + #define ATTRIB_AES __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif + #endif +#endif +#else + // _MSC_VER + // for arm32 + #define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#ifndef ATTRIB_AES + #define ATTRIB_AES +#endif + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) +#include +#else +/* + clang-17.0.1: error : Cannot select: intrinsic %llvm.arm.neon.aese + clang + 3.8.1 : __ARM_NEON : defined(__ARM_FEATURE_CRYPTO) + 7.0.1 : __ARM_NEON : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO) + 11.?.0 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO) + 13.0.1 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 && defined(__ARM_FEATURE_AES) + 16 : __ARM_NEON && __ARM_FP : __ARM_ARCH >= 8 +*/ +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_AES) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_AES 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + +#include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_AES) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_AES + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") +#endif + +#endif // Z7_MSC_VER_ORIGINAL + +typedef uint8x16_t v128; + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(v128 *p, v128 *data, size_t numBlocks) + +#define AES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_AES \ +AES_FUNC_START (name) + +#define MM_OP(op, dest, src) dest = op(dest, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) +#define MM_OP1_m(op) m = op(m); + +#define MM_XOR( dest, src) MM_OP(veorq_u8, dest, src) +#define MM_XOR_m( src) MM_XOR(m, src) + +#define AES_E_m(k) MM_OP_m (vaeseq_u8, k) +#define AES_E_MC_m(k) AES_E_m (k) MM_OP1_m(vaesmcq_u8) + + +AES_FUNC_START2 (AesCbc_Encode_HW) +{ + if (numBlocks == 0) + return; + { + v128 * const p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; + v128 m = *p; + const UInt32 numRounds2 = *(const UInt32 *)(p + 1); + const v128 *w = p + (size_t)numRounds2 * 2; + const v128 k0 = p[2]; + const v128 k1 = p[3]; + const v128 k2 = p[4]; + const v128 k3 = p[5]; + const v128 k4 = p[6]; + const v128 k5 = p[7]; + const v128 k6 = p[8]; + const v128 k7 = p[9]; + const v128 k8 = p[10]; + const v128 k9 = p[11]; + const v128 k_z4 = w[-2]; + const v128 k_z3 = w[-1]; + const v128 k_z2 = w[0]; + const v128 k_z1 = w[1]; + const v128 k_z0 = w[2]; + // we don't use optimization veorq_u8(*data, k_z0) that can reduce one cycle, + // because gcc/clang compilers are not good for that optimization. + do + { + MM_XOR_m (*data) + AES_E_MC_m (k0) + AES_E_MC_m (k1) + AES_E_MC_m (k2) + AES_E_MC_m (k3) + AES_E_MC_m (k4) + AES_E_MC_m (k5) + if (numRounds2 >= 6) + { + AES_E_MC_m (k6) + AES_E_MC_m (k7) + if (numRounds2 != 6) + { + AES_E_MC_m (k8) + AES_E_MC_m (k9) + } + } + AES_E_MC_m (k_z4) + AES_E_MC_m (k_z3) + AES_E_MC_m (k_z2) + AES_E_m (k_z1) + MM_XOR_m (k_z0) + *data++ = m; + } + while (--numBlocks); + *p = m; + } +} + + +#define WOP_1(op) +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) + + #define NUM_WAYS 8 + #define WOP_M1 WOP_8 + +#define WOP(op) op (m0, 0) WOP_M1(op) + +#define DECLARE_VAR(reg, ii) v128 reg; +#define LOAD_data( reg, ii) reg = data[ii]; +#define STORE_data( reg, ii) data[ii] = reg; +#if (NUM_WAYS > 1) +#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) +#endif + +#define MM_OP_key(op, reg) MM_OP (op, reg, key) + +#define AES_D_m(k) MM_OP_m (vaesdq_u8, k) +#define AES_D_IMC_m(k) AES_D_m (k) MM_OP1_m (vaesimcq_u8) + +#define AES_XOR( reg, ii) MM_OP_key (veorq_u8, reg) +#define AES_D( reg, ii) MM_OP_key (vaesdq_u8, reg) +#define AES_E( reg, ii) MM_OP_key (vaeseq_u8, reg) + +#define AES_D_IMC( reg, ii) AES_D (reg, ii) reg = vaesimcq_u8(reg); +#define AES_E_MC( reg, ii) AES_E (reg, ii) reg = vaesmcq_u8(reg); + +#define CTR_START(reg, ii) MM_OP (vaddq_u64, ctr, one) reg = vreinterpretq_u8_u64(ctr); +#define CTR_END( reg, ii) MM_XOR (data[ii], reg) + +#define WOP_KEY(op, n) { \ + const v128 key = w[n]; \ + WOP(op) } + +#define WIDE_LOOP_START \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS) \ + { dataEnd -= NUM_WAYS; do { \ + +#define WIDE_LOOP_END \ + data += NUM_WAYS; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS; } \ + +#define SINGLE_LOOP \ + for (; data < dataEnd; data++) + + +AES_FUNC_START2 (AesCbc_Decode_HW) +{ + v128 *p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; + v128 iv = *p; + const v128 * const wStart = p + (size_t)*(const UInt32 *)(p + 1) * 2; + const v128 *dataEnd; + p += 2; + + WIDE_LOOP_START + { + const v128 *w = wStart; + WOP (DECLARE_VAR) + WOP (LOAD_data) + WOP_KEY (AES_D_IMC, 2) + do + { + WOP_KEY (AES_D_IMC, 1) + WOP_KEY (AES_D_IMC, 0) + w -= 2; + } + while (w != p); + WOP_KEY (AES_D, 1) + WOP_KEY (AES_XOR, 0) + MM_XOR (m0, iv) + WOP_M1 (XOR_data_M1) + LOAD_data(iv, NUM_WAYS - 1) + WOP (STORE_data) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const v128 *w = wStart; + v128 m; LOAD_data(m, 0) + AES_D_IMC_m (w[2]) + do + { + AES_D_IMC_m (w[1]) + AES_D_IMC_m (w[0]) + w -= 2; + } + while (w != p); + AES_D_m (w[1]) + MM_XOR_m (w[0]) + MM_XOR_m (iv) + LOAD_data(iv, 0) + STORE_data(m, 0) + } + + p[-2] = iv; +} + + +AES_FUNC_START2 (AesCtr_Code_HW) +{ + v128 *p = (v128 *)(void *)ivAes; + v128 *data = (v128 *)(void *)data8; + uint64x2_t ctr = vreinterpretq_u64_u8(*p); + const v128 * const wEnd = p + (size_t)*(const UInt32 *)(p + 1) * 2; + const v128 *dataEnd; +// the bug in clang: +// __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); +#if defined(__clang__) && (__clang_major__ <= 9) +#pragma GCC diagnostic ignored "-Wvector-conversion" +#endif + const uint64x2_t one = vsetq_lane_u64(1, vdupq_n_u64(0), 0); + p += 2; + + WIDE_LOOP_START + { + const v128 *w = p; + WOP (DECLARE_VAR) + WOP (CTR_START) + do + { + WOP_KEY (AES_E_MC, 0) + WOP_KEY (AES_E_MC, 1) + w += 2; + } + while (w != wEnd); + WOP_KEY (AES_E_MC, 0) + WOP_KEY (AES_E, 1) + WOP_KEY (AES_XOR, 2) + WOP (CTR_END) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const v128 *w = p; + v128 m; + CTR_START (m, 0) + do + { + AES_E_MC_m (w[0]) + AES_E_MC_m (w[1]) + w += 2; + } + while (w != wEnd); + AES_E_MC_m (w[0]) + AES_E_m (w[1]) + MM_XOR_m (w[2]) + CTR_END (m, 0) + } + + p[-2] = vreinterpretq_u8_u64(ctr); +} + +#endif // USE_HW_AES + +#endif // MY_CPU_ARM_OR_ARM64 + +#undef NUM_WAYS +#undef WOP_M1 +#undef WOP +#undef DECLARE_VAR +#undef LOAD_data +#undef STORE_data +#undef USE_INTEL_AES +#undef USE_HW_AES diff -Nru p7zip-rar-16.02/C/Alloc.c p7zip-rar-16.02+really25.00+ds/C/Alloc.c --- p7zip-rar-16.02/C/Alloc.c 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Alloc.c 2024-02-18 18:00:00.000000000 +0000 @@ -1,328 +1,605 @@ -/* Alloc.c -- Memory allocation functions -2015-02-21 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#ifdef _WIN32 -#include -#endif -#include -#include - -#ifdef _7ZIP_LARGE_PAGES -#ifdef __linux__ -#ifndef _7ZIP_ST -#include -#endif -#include -#include -#include -#include -#include -#endif -#endif - -#include "Alloc.h" - -/* #define _SZ_ALLOC_DEBUG */ - -/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ -#ifdef _SZ_ALLOC_DEBUG -#include -int g_allocCount = 0; -int g_allocCountMid = 0; -int g_allocCountBig = 0; -#endif - -#ifdef _7ZIP_ASM -// #include -extern int posix_memalign (void **, size_t, size_t); -void *align_alloc(size_t size) -{ - // return _mm_malloc(size,16); - void * ptr = 0; - - if (posix_memalign (&ptr, 16, size) == 0) - return ptr; - else - return NULL; -} - -void align_free(void * ptr) -{ - // _mm_free(ptr); - free(ptr); -} - - -#else -void *align_alloc(size_t size) -{ - return malloc(size); -} - -void align_free(void * ptr) -{ - free(ptr); -} - -#endif - -void *MyAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - { - void *p = align_alloc(size); - fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p); - return p; - } - #else - return align_alloc(size); - #endif -} - -void MyFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address); - #endif - align_free(address); -} - -#ifndef _WIN32 - -#ifdef _7ZIP_LARGE_PAGES - -#ifdef __linux__ -#define _7ZIP_MAX_HUGE_ALLOCS 64 -static void *g_HugePageAddr[_7ZIP_MAX_HUGE_ALLOCS] = { NULL }; -static size_t g_HugePageLen[_7ZIP_MAX_HUGE_ALLOCS]; -static char *g_HugetlbPath; -#endif - -#endif - -#ifdef _7ZIP_LARGE_PAGES -static void *VirtualAlloc(size_t size, int memLargePages) -{ - if (memLargePages) - { - #ifdef __linux__ - /* huge pages support for Linux; added by Joachim Henke */ - #ifndef _7ZIP_ST - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - #endif - int i; - - void * address = NULL; - #ifndef _7ZIP_ST - pthread_mutex_lock(&mutex); - #endif - for (i = 0; i < _7ZIP_MAX_HUGE_ALLOCS; ++i) - { - if (g_HugePageAddr[i] == NULL) - { - int fd, pathlen = strlen(g_HugetlbPath); - char tempname[pathlen+12]; - - memcpy(tempname, g_HugetlbPath, pathlen); - memcpy(tempname + pathlen, "/7z-XXXXXX", 11); - fd = mkstemp(tempname); - unlink(tempname); - if (fd < 0) - { - fprintf(stderr,"cant't open %s (%s)\n",tempname,strerror(errno)); - break; - } - address = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - close(fd); - if (address == MAP_FAILED) - { - address = NULL; - break; - } - g_HugePageLen[i] = size; - g_HugePageAddr[i] = address; -// fprintf(stderr,"HUGE[%d]=%ld %p\n",i,(long)size,address); - break; - } - } - #ifndef _7ZIP_ST - pthread_mutex_unlock(&mutex); - #endif - return address; - #endif - } - return align_alloc(size); -} -#else -static void *VirtualAlloc(size_t size, int memLargePages ) -{ - return align_alloc(size); -} -#endif - -static int VirtualFree(void *address) -{ - #ifdef _7ZIP_LARGE_PAGES - #ifdef __linux__ - int i; - - for (i = 0; i < _7ZIP_MAX_HUGE_ALLOCS; ++i) - { - if (g_HugePageAddr[i] == address) - { - munmap(address, g_HugePageLen[i]); - g_HugePageAddr[i] = NULL; - return 1; - } - } - #endif - #endif - align_free(address); - return 1; -} - -#endif - -void *MidAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++); - #endif - return VirtualAlloc(size, 0); -} - -void MidFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid); - #endif - if (address == 0) - return; - VirtualFree(address); -} - -#ifdef _7ZIP_LARGE_PAGES -size_t g_LargePageSize = 0; -#ifdef _WIN32 -typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); -#elif defined(__linux__) -size_t largePageMinimum() -{ - size_t size; - - g_HugetlbPath = getenv("HUGETLB_PATH"); - - if (g_HugetlbPath == NULL) - { - // not defined => try to find out the directory - static char dir_hugetlbfs[1024]; - const char * filename = "/etc/mtab"; // mounted filesystems - FILE *fp; - struct mntent * info; - - dir_hugetlbfs[0]=0; - - fp = setmntent(filename,"r"); - if (fp) - { - info = getmntent(fp); - while(info) - { -/* - printf("%s:\n",info->mnt_fsname); - printf(" dir='%s'\n",info->mnt_dir); - printf(" type='%s'\n",info->mnt_type); -*/ - - if (strcmp(info->mnt_type,"hugetlbfs") == 0) - { - strcpy(dir_hugetlbfs,info->mnt_dir); - break; - } - - info = getmntent(fp); - } - endmntent(fp); - } - - if (dir_hugetlbfs[0]) - { - g_HugetlbPath = dir_hugetlbfs; - // fprintf(stderr," Found hugetlbfs = '%s'\n",g_HugetlbPath); - } - } - if (g_HugetlbPath == NULL || (size = pathconf(g_HugetlbPath, _PC_REC_MIN_XFER_SIZE)) <= getpagesize()) - return 0; - return size; -} -#else -#define largePageMinimum() 0 -#endif -#endif - -void SetLargePageSize() -{ - #ifdef _7ZIP_LARGE_PAGES - size_t size; - #ifdef _WIN32 - GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) - GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); - if (largePageMinimum == 0) - return; - #endif - size = largePageMinimum(); - if (size == 0 || (size & (size - 1)) != 0) - return; - g_LargePageSize = size; - // fprintf(stderr,"SetLargePageSize : %ld\n",(long)g_LargePageSize); - #endif -} - - -void *BigAlloc(size_t size) -{ - if (size == 0) - return 0; - #ifdef _SZ_ALLOC_DEBUG - fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18)) - { - void *res = VirtualAlloc( (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)), 1); - if (res != 0) - return res; - } - #endif - return VirtualAlloc(size, 0); -} - -void BigFree(void *address) -{ - #ifdef _SZ_ALLOC_DEBUG - if (address != 0) - fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig); - #endif - - if (address == 0) - return; - VirtualFree(address); -} - -static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); } -static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); } -ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); } -static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); } -ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; - +/* Alloc.c -- Memory allocation functions +2024-02-18 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 +#include "7zWindows.h" +#endif +#include + +#include "Alloc.h" + +#if defined(Z7_LARGE_PAGES) && defined(_WIN32) && \ + (!defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502) // < Win2003 (xp-64) + #define Z7_USE_DYN_GetLargePageMinimum +#endif + +// for debug: +#if 0 +#if defined(__CHERI__) && defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// #pragma message("=== Z7_ALLOC_NO_OFFSET_ALLOCATOR === ") +#define Z7_ALLOC_NO_OFFSET_ALLOCATOR +#endif +#endif + +// #define SZ_ALLOC_DEBUG +/* #define SZ_ALLOC_DEBUG */ + +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef SZ_ALLOC_DEBUG + +#include +#include +static int g_allocCount = 0; +#ifdef _WIN32 +static int g_allocCountMid = 0; +static int g_allocCountBig = 0; +#endif + + +#define CONVERT_INT_TO_STR(charType, tempSize) \ + char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = temp[i]; } \ + *s = 0; + +static void ConvertUInt64ToString(UInt64 val, char *s) +{ + CONVERT_INT_TO_STR(char, 24) +} + +#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) + +static void ConvertUInt64ToHex(UInt64 val, char *s) +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; + do + { + unsigned t = (unsigned)(val & 0xF); + val >>= 4; + s[--i] = GET_HEX_CHAR(t); + } + while (i); +} + +#define DEBUG_OUT_STREAM stderr + +static void Print(const char *s) +{ + fputs(s, DEBUG_OUT_STREAM); +} + +static void PrintAligned(const char *s, size_t align) +{ + size_t len = strlen(s); + for(;;) + { + fputc(' ', DEBUG_OUT_STREAM); + if (len >= align) + break; + ++len; + } + Print(s); +} + +static void PrintLn(void) +{ + Print("\n"); +} + +static void PrintHex(UInt64 v, size_t align) +{ + char s[32]; + ConvertUInt64ToHex(v, s); + PrintAligned(s, align); +} + +static void PrintDec(int v, size_t align) +{ + char s[32]; + ConvertUInt64ToString((unsigned)v, s); + PrintAligned(s, align); +} + +static void PrintAddr(void *p) +{ + PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12); +} + + +#define PRINT_REALLOC(name, cnt, size, ptr) { \ + Print(name " "); \ + if (!ptr) PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#define PRINT_ALLOC(name, cnt, size, ptr) { \ + Print(name " "); \ + PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#define PRINT_FREE(name, cnt, ptr) if (ptr) { \ + Print(name " "); \ + PrintDec(--cnt, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#else + +#ifdef _WIN32 +#define PRINT_ALLOC(name, cnt, size, ptr) +#endif +#define PRINT_FREE(name, cnt, ptr) +#define Print(s) +#define PrintLn() +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR +#define PrintHex(v, align) +#endif +#define PrintAddr(p) + +#endif + + +/* +by specification: + malloc(non_NULL, 0) : returns NULL or a unique pointer value that can later be successfully passed to free() + realloc(NULL, size) : the call is equivalent to malloc(size) + realloc(non_NULL, 0) : the call is equivalent to free(ptr) + +in main compilers: + malloc(0) : returns non_NULL + realloc(NULL, 0) : returns non_NULL + realloc(non_NULL, 0) : returns NULL +*/ + + +void *MyAlloc(size_t size) +{ + if (size == 0) + return NULL; + // PRINT_ALLOC("Alloc ", g_allocCount, size, NULL) + #ifdef SZ_ALLOC_DEBUG + { + void *p = malloc(size); + if (p) + { + PRINT_ALLOC("Alloc ", g_allocCount, size, p) + } + return p; + } + #else + return malloc(size); + #endif +} + +void MyFree(void *address) +{ + PRINT_FREE("Free ", g_allocCount, address) + + free(address); +} + +void *MyRealloc(void *address, size_t size) +{ + if (size == 0) + { + MyFree(address); + return NULL; + } + // PRINT_REALLOC("Realloc ", g_allocCount, size, address) + #ifdef SZ_ALLOC_DEBUG + { + void *p = realloc(address, size); + if (p) + { + PRINT_REALLOC("Realloc ", g_allocCount, size, address) + } + return p; + } + #else + return realloc(address, size); + #endif +} + + +#ifdef _WIN32 + +void *MidAlloc(size_t size) +{ + if (size == 0) + return NULL; + #ifdef SZ_ALLOC_DEBUG + { + void *p = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, p) + } + return p; + } + #else + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + #endif +} + +void MidFree(void *address) +{ + PRINT_FREE("Free-Mid", g_allocCountMid, address) + + if (!address) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#ifdef Z7_LARGE_PAGES + +#ifdef MEM_LARGE_PAGES + #define MY_MEM_LARGE_PAGES MEM_LARGE_PAGES +#else + #define MY_MEM_LARGE_PAGES 0x20000000 +#endif + +extern +SIZE_T g_LargePageSize; +SIZE_T g_LargePageSize = 0; +typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID); + +void SetLargePageSize(void) +{ + SIZE_T size; +#ifdef Z7_USE_DYN_GetLargePageMinimum +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + + const + Func_GetLargePageMinimum fn = + (Func_GetLargePageMinimum) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetLargePageMinimum"); + if (!fn) + return; + size = fn(); +#else + size = GetLargePageMinimum(); +#endif + if (size == 0 || (size & (size - 1)) != 0) + return; + g_LargePageSize = size; +} + +#endif // Z7_LARGE_PAGES + +void *BigAlloc(size_t size) +{ + if (size == 0) + return NULL; + + PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL) + + #ifdef Z7_LARGE_PAGES + { + SIZE_T ps = g_LargePageSize; + if (ps != 0 && ps <= (1 << 30) && size > (ps / 2)) + { + size_t size2; + ps--; + size2 = (size + ps) & ~ps; + if (size2 >= size) + { + void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY_MEM_LARGE_PAGES, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-BM ", g_allocCountMid, size2, p) + return p; + } + } + } + } + #endif + + return MidAlloc(size); +} + +void BigFree(void *address) +{ + PRINT_FREE("Free-Big", g_allocCountBig, address) + MidFree(address); +} + +#endif // _WIN32 + + +static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MyAlloc(size); } +static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MyFree(address); } +const ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +#ifdef _WIN32 +static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MidAlloc(size); } +static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MidFree(address); } +static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return BigAlloc(size); } +static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) BigFree(address); } +const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree }; +const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; +#endif + +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR + +#define ADJUST_ALLOC_SIZE 0 +/* +#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1) +*/ +/* + Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if + MyAlloc() can return address that is NOT multiple of sizeof(void *). +*/ + +/* + uintptr_t : C99 (optional) + : unsupported in VS6 +*/ +typedef + #ifdef _WIN32 + UINT_PTR + #elif 1 + uintptr_t + #else + ptrdiff_t + #endif + MY_uintptr_t; + +#if 0 \ + || (defined(__CHERI__) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ > 8)) +// for 128-bit pointers (cheri): +#define MY_ALIGN_PTR_DOWN(p, align) \ + ((void *)((char *)(p) - ((size_t)(MY_uintptr_t)(p) & ((align) - 1)))) +#else +#define MY_ALIGN_PTR_DOWN(p, align) \ + ((void *)((((MY_uintptr_t)(p)) & ~((MY_uintptr_t)(align) - 1)))) +#endif + +#endif + +#if !defined(_WIN32) \ + && (defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) \ + || defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) + #define USE_posix_memalign +#endif + +#ifndef USE_posix_memalign +#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align) +#endif + +/* + This posix_memalign() is for test purposes only. + We also need special Free() function instead of free(), + if this posix_memalign() is used. +*/ + +/* +static int posix_memalign(void **ptr, size_t align, size_t size) +{ + size_t newSize = size + align; + void *p; + void *pAligned; + *ptr = NULL; + if (newSize < size) + return 12; // ENOMEM + p = MyAlloc(newSize); + if (!p) + return 12; // ENOMEM + pAligned = MY_ALIGN_PTR_UP_PLUS(p, align); + ((void **)pAligned)[-1] = p; + *ptr = pAligned; + return 0; +} +*/ + +/* + ALLOC_ALIGN_SIZE >= sizeof(void *) + ALLOC_ALIGN_SIZE >= cache_line_size +*/ + +#define ALLOC_ALIGN_SIZE ((size_t)1 << 7) + +void *z7_AlignedAlloc(size_t size) +{ +#ifndef USE_posix_memalign + + void *p; + void *pAligned; + size_t newSize; + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + + newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + p = MyAlloc(newSize); + + if (!p) + return NULL; + pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE); + + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(p); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + ((void **)pAligned)[-1] = p; + + return pAligned; + +#else + + void *p; + if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size)) + return NULL; + + Print(" posix_memalign="); PrintAddr(p); + PrintLn(); + + return p; + +#endif +} + + +void z7_AlignedFree(void *address) +{ +#ifndef USE_posix_memalign + if (address) + MyFree(((void **)address)[-1]); +#else + free(address); +#endif +} + + +static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) +{ + UNUSED_VAR(pp) + return z7_AlignedAlloc(size); +} + + +static void SzAlignedFree(ISzAllocPtr pp, void *address) +{ + UNUSED_VAR(pp) +#ifndef USE_posix_memalign + if (address) + MyFree(((void **)address)[-1]); +#else + free(address); +#endif +} + + +const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree }; + + + +/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */ +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR +#if 1 + #define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) + #define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] +#else + // we can use this simplified code, + // if (CAlignOffsetAlloc::offset == (k * sizeof(void *)) + #define REAL_BLOCK_PTR_VAR(p) (((void **)(p))[-1]) +#endif +#endif + + +#if 0 +#ifndef Z7_ALLOC_NO_OFFSET_ALLOCATOR +#include +static void PrintPtr(const char *s, const void *p) +{ + const Byte *p2 = (const Byte *)&p; + unsigned i; + printf("%s %p ", s, p); + for (i = sizeof(p); i != 0;) + { + i--; + printf("%02x", p2[i]); + } + printf("\n"); +} +#endif +#endif + + +static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size) +{ +#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) + UNUSED_VAR(pp) + return z7_AlignedAlloc(size); +#else + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); + void *adr; + void *pAligned; + size_t newSize; + size_t extra; + size_t alignSize = (size_t)1 << p->numAlignBits; + + if (alignSize < sizeof(void *)) + alignSize = sizeof(void *); + + if (p->offset >= alignSize) + return NULL; + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + extra = p->offset & (sizeof(void *) - 1); + newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + adr = ISzAlloc_Alloc(p->baseAlloc, newSize); + + if (!adr) + return NULL; + + pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr + + alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset; + +#if 0 + printf("\nalignSize = %6x, offset=%6x, size=%8x \n", (unsigned)alignSize, (unsigned)p->offset, (unsigned)size); + PrintPtr("base", adr); + PrintPtr("alig", pAligned); +#endif + + PrintLn(); + Print("- Aligned: "); + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(adr); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + REAL_BLOCK_PTR_VAR(pAligned) = adr; + + return pAligned; +#endif +} + + +static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address) +{ +#if defined(Z7_ALLOC_NO_OFFSET_ALLOCATOR) + UNUSED_VAR(pp) + z7_AlignedFree(address); +#else + if (address) + { + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); + PrintLn(); + Print("- Aligned Free: "); + PrintLn(); + ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address)); + } +#endif +} + + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p) +{ + p->vt.Alloc = AlignOffsetAlloc_Alloc; + p->vt.Free = AlignOffsetAlloc_Free; +} diff -Nru p7zip-rar-16.02/C/Alloc.h p7zip-rar-16.02+really25.00+ds/C/Alloc.h --- p7zip-rar-16.02/C/Alloc.h 2015-06-19 16:43:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Alloc.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,26 +1,76 @@ -/* Alloc.h -- Memory allocation functions -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __COMMON_ALLOC_H -#define __COMMON_ALLOC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -void *MyAlloc(size_t size); -void MyFree(void *address); - -void SetLargePageSize(); - -void *MidAlloc(size_t size); -void MidFree(void *address); -void *BigAlloc(size_t size); -void BigFree(void *address); - -extern ISzAlloc g_Alloc; -extern ISzAlloc g_BigAlloc; - -EXTERN_C_END - -#endif +/* Alloc.h -- Memory allocation functions +2024-01-22 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ALLOC_H +#define ZIP7_INC_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* + MyFree(NULL) : is allowed, as free(NULL) + MyAlloc(0) : returns NULL : but malloc(0) is allowed to return NULL or non_NULL + MyRealloc(NULL, 0) : returns NULL : but realloc(NULL, 0) is allowed to return NULL or non_NULL +MyRealloc() is similar to realloc() for the following cases: + MyRealloc(non_NULL, 0) : returns NULL and always calls MyFree(ptr) + MyRealloc(NULL, non_ZERO) : returns NULL, if allocation failed + MyRealloc(non_NULL, non_ZERO) : returns NULL, if reallocation failed +*/ + +void *MyAlloc(size_t size); +void MyFree(void *address); +void *MyRealloc(void *address, size_t size); + +void *z7_AlignedAlloc(size_t size); +void z7_AlignedFree(void *p); + +#ifdef _WIN32 + +#ifdef Z7_LARGE_PAGES +void SetLargePageSize(void); +#endif + +void *MidAlloc(size_t size); +void MidFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); + +/* #define Z7_BIG_ALLOC_IS_ZERO_FILLED */ + +#else + +#define MidAlloc(size) z7_AlignedAlloc(size) +#define MidFree(address) z7_AlignedFree(address) +#define BigAlloc(size) z7_AlignedAlloc(size) +#define BigFree(address) z7_AlignedFree(address) + +#endif + +extern const ISzAlloc g_Alloc; + +#ifdef _WIN32 +extern const ISzAlloc g_BigAlloc; +extern const ISzAlloc g_MidAlloc; +#else +#define g_BigAlloc g_AlignedAlloc +#define g_MidAlloc g_AlignedAlloc +#endif + +extern const ISzAlloc g_AlignedAlloc; + + +typedef struct +{ + ISzAlloc vt; + ISzAllocPtr baseAlloc; + unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */ + size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */ +} CAlignOffsetAlloc; + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p); + + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Asm_c.mak p7zip-rar-16.02+really25.00+ds/C/Asm_c.mak --- p7zip-rar-16.02/C/Asm_c.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Asm_c.mak 2024-03-21 08:00:00.000000000 +0000 @@ -0,0 +1,12 @@ +!IFDEF ASM_OBJS +!IF "$(PLATFORM)" == "arm64" +$(ASM_OBJS): ../../../Asm/arm64/$(*B).S + $(COMPL_ASM_CLANG) +!ELSEIF "$(PLATFORM)" == "arm" +$(ASM_OBJS): ../../../Asm/arm/$(*B).asm + $(COMPL_ASM) +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" +$(ASM_OBJS): ../../../Asm/x86/$(*B).asm + $(COMPL_ASM) +!ENDIF +!ENDIF diff -Nru p7zip-rar-16.02/C/Bcj2.c p7zip-rar-16.02+really25.00+ds/C/Bcj2.c --- p7zip-rar-16.02/C/Bcj2.c 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bcj2.c 2023-03-01 12:00:00.000000000 +0000 @@ -1,256 +1,290 @@ -/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) -2015-08-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bcj2.h" -#include "CpuArch.h" - -#define CProb UInt16 - -#define kTopValue ((UInt32)1 << 24) -#define kNumModelBits 11 -#define kBitModelTotal (1 << kNumModelBits) -#define kNumMoveBits 5 - -#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) -#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); - -void Bcj2Dec_Init(CBcj2Dec *p) -{ - unsigned i; - - p->state = BCJ2_DEC_STATE_OK; - p->ip = 0; - p->temp[3] = 0; - p->range = 0; - p->code = 0; - for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) - p->probs[i] = kBitModelTotal >> 1; -} - -SRes Bcj2Dec_Decode(CBcj2Dec *p) -{ - if (p->range <= 5) - { - p->state = BCJ2_DEC_STATE_OK; - for (; p->range != 5; p->range++) - { - if (p->range == 1 && p->code != 0) - return SZ_ERROR_DATA; - - if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) - { - p->state = BCJ2_STREAM_RC; - return SZ_OK; - } - - p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; - } - - if (p->code == 0xFFFFFFFF) - return SZ_ERROR_DATA; - - p->range = 0xFFFFFFFF; - } - else if (p->state >= BCJ2_DEC_STATE_ORIG_0) - { - while (p->state <= BCJ2_DEC_STATE_ORIG_3) - { - Byte *dest = p->dest; - if (dest == p->destLim) - return SZ_OK; - *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; - p->dest = dest + 1; - } - } - - /* - if (BCJ2_IS_32BIT_STREAM(p->state)) - { - const Byte *cur = p->bufs[p->state]; - if (cur == p->lims[p->state]) - return SZ_OK; - p->bufs[p->state] = cur + 4; - - { - UInt32 val; - Byte *dest; - SizeT rem; - - p->ip += 4; - val = GetBe32(cur) - p->ip; - dest = p->dest; - rem = p->destLim - dest; - if (rem < 4) - { - SizeT i; - SetUi32(p->temp, val); - for (i = 0; i < rem; i++) - dest[i] = p->temp[i]; - p->dest = dest + rem; - p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; - return SZ_OK; - } - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); - p->dest = dest + 4; - p->state = BCJ2_DEC_STATE_OK; - } - } - */ - - for (;;) - { - if (BCJ2_IS_32BIT_STREAM(p->state)) - p->state = BCJ2_DEC_STATE_OK; - else - { - if (p->range < kTopValue) - { - if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) - { - p->state = BCJ2_STREAM_RC; - return SZ_OK; - } - p->range <<= 8; - p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; - } - - { - const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; - const Byte *srcLim; - Byte *dest; - SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; - - if (num == 0) - { - p->state = BCJ2_STREAM_MAIN; - return SZ_OK; - } - - dest = p->dest; - if (num > (SizeT)(p->destLim - dest)) - { - num = p->destLim - dest; - if (num == 0) - { - p->state = BCJ2_DEC_STATE_ORIG; - return SZ_OK; - } - } - - srcLim = src + num; - - if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) - *dest = src[0]; - else for (;;) - { - Byte b = *src; - *dest = b; - if (b != 0x0F) - { - if ((b & 0xFE) == 0xE8) - break; - dest++; - if (++src != srcLim) - continue; - break; - } - dest++; - if (++src == srcLim) - break; - if ((*src & 0xF0) != 0x80) - continue; - *dest = *src; - break; - } - - num = src - p->bufs[BCJ2_STREAM_MAIN]; - - if (src == srcLim) - { - p->temp[3] = src[-1]; - p->bufs[BCJ2_STREAM_MAIN] = src; - p->ip += (UInt32)num; - p->dest += num; - p->state = - p->bufs[BCJ2_STREAM_MAIN] == - p->lims[BCJ2_STREAM_MAIN] ? - (unsigned)BCJ2_STREAM_MAIN : - (unsigned)BCJ2_DEC_STATE_ORIG; - return SZ_OK; - } - - { - UInt32 bound, ttt; - CProb *prob; - Byte b = src[0]; - Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); - - p->temp[3] = b; - p->bufs[BCJ2_STREAM_MAIN] = src + 1; - num++; - p->ip += (UInt32)num; - p->dest += num; - - prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); - - _IF_BIT_0 - { - _UPDATE_0 - continue; - } - _UPDATE_1 - - } - } - } - - { - UInt32 val; - unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; - const Byte *cur = p->bufs[cj]; - Byte *dest; - SizeT rem; - - if (cur == p->lims[cj]) - { - p->state = cj; - break; - } - - val = GetBe32(cur); - p->bufs[cj] = cur + 4; - - p->ip += 4; - val -= p->ip; - dest = p->dest; - rem = p->destLim - dest; - - if (rem < 4) - { - SizeT i; - SetUi32(p->temp, val); - for (i = 0; i < rem; i++) - dest[i] = p->temp[i]; - p->dest = dest + rem; - p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; - break; - } - - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); - p->dest = dest + 4; - } - } - - if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) - { - p->range <<= 8; - p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; - } - - return SZ_OK; -} +/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) +2023-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bcj2.h" +#include "CpuArch.h" + +#define kTopValue ((UInt32)1 << 24) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +// UInt32 bcj2_stats[256 + 2][2]; + +void Bcj2Dec_Init(CBcj2Dec *p) +{ + unsigned i; + p->state = BCJ2_STREAM_RC; // BCJ2_DEC_STATE_OK; + p->ip = 0; + p->temp = 0; + p->range = 0; + p->code = 0; + for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) + p->probs[i] = kBitModelTotal >> 1; +} + +SRes Bcj2Dec_Decode(CBcj2Dec *p) +{ + UInt32 v = p->temp; + // const Byte *src; + if (p->range <= 5) + { + UInt32 code = p->code; + p->state = BCJ2_DEC_STATE_ERROR; /* for case if we return SZ_ERROR_DATA; */ + for (; p->range != 5; p->range++) + { + if (p->range == 1 && code != 0) + return SZ_ERROR_DATA; + if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + return SZ_OK; + } + code = (code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + p->code = code; + } + if (code == 0xffffffff) + return SZ_ERROR_DATA; + p->range = 0xffffffff; + } + // else + { + unsigned state = p->state; + // we check BCJ2_IS_32BIT_STREAM() here instead of check in the main loop + if (BCJ2_IS_32BIT_STREAM(state)) + { + const Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) + return SZ_OK; + p->bufs[state] = cur + 4; + { + const UInt32 ip = p->ip + 4; + v = GetBe32a(cur) - ip; + p->ip = ip; + } + state = BCJ2_DEC_STATE_ORIG_0; + } + if ((unsigned)(state - BCJ2_DEC_STATE_ORIG_0) < 4) + { + Byte *dest = p->dest; + for (;;) + { + if (dest == p->destLim) + { + p->state = state; + p->temp = v; + return SZ_OK; + } + *dest++ = (Byte)v; + p->dest = dest; + if (++state == BCJ2_DEC_STATE_ORIG_3 + 1) + break; + v >>= 8; + } + } + } + + // src = p->bufs[BCJ2_STREAM_MAIN]; + for (;;) + { + /* + if (BCJ2_IS_32BIT_STREAM(p->state)) + p->state = BCJ2_DEC_STATE_OK; + else + */ + { + if (p->range < kTopValue) + { + if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + p->temp = v; + return SZ_OK; + } + p->range <<= 8; + p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + } + { + const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; + const Byte *srcLim; + Byte *dest = p->dest; + { + const SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src); + SizeT num = (SizeT)(p->destLim - dest); + if (num >= rem) + num = rem; + #define NUM_ITERS 4 + #if (NUM_ITERS & (NUM_ITERS - 1)) == 0 + num &= ~((SizeT)NUM_ITERS - 1); // if (NUM_ITERS == (1 << x)) + #else + num -= num % NUM_ITERS; // if (NUM_ITERS != (1 << x)) + #endif + srcLim = src + num; + } + + #define NUM_SHIFT_BITS 24 + #define ONE_ITER(indx) { \ + const unsigned b = src[indx]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + /* ++dest */; /* v = b; */ } + + if (src != srcLim) + for (;;) + { + /* The dependency chain of 2-cycle for (v) calculation is not big problem here. + But we can remove dependency chain with v = b in the end of loop. */ + ONE_ITER(0) + #if (NUM_ITERS > 1) + ONE_ITER(1) + #if (NUM_ITERS > 2) + ONE_ITER(2) + #if (NUM_ITERS > 3) + ONE_ITER(3) + #if (NUM_ITERS > 4) + ONE_ITER(4) + #if (NUM_ITERS > 5) + ONE_ITER(5) + #if (NUM_ITERS > 6) + ONE_ITER(6) + #if (NUM_ITERS > 7) + ONE_ITER(7) + #endif + #endif + #endif + #endif + #endif + #endif + #endif + + src += NUM_ITERS; + if (src == srcLim) + break; + } + + if (src == srcLim) + #if (NUM_ITERS > 1) + for (;;) + #endif + { + #if (NUM_ITERS > 1) + if (src == p->lims[BCJ2_STREAM_MAIN] || dest == p->destLim) + #endif + { + const SizeT num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = src; + p->dest = dest; + p->ip += (UInt32)num; + /* state BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ + p->state = + src == p->lims[BCJ2_STREAM_MAIN] ? + (unsigned)BCJ2_STREAM_MAIN : + (unsigned)BCJ2_DEC_STATE_ORIG; + p->temp = v; + return SZ_OK; + } + #if (NUM_ITERS > 1) + ONE_ITER(0) + src++; + #endif + } + + { + const SizeT num = (SizeT)(dest - p->dest); + p->dest = dest; // p->dest += num; + p->bufs[BCJ2_STREAM_MAIN] += num; // = src; + p->ip += (UInt32)num; + } + { + UInt32 bound, ttt; + CBcj2Prob *prob; // unsigned index; + /* + prob = p->probs + (unsigned)((Byte)v == 0xe8 ? + 2 + (Byte)(v >> 8) : + ((v >> 5) & 1)); // ((Byte)v < 0xe8 ? 0 : 1)); + */ + { + const unsigned c = ((v + 0x17) >> 6) & 1; + prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + // (Byte) + // 8x->0 : e9->1 : xxe8->xx+2 + // 8x->0x100 : e9->0x101 : xxe8->xx + // (((0x100 - (e & ~v)) & (0x100 | (v >> 8))) + (e & v)); + // (((0x101 + (~e | v)) & (0x100 | (v >> 8))) + (e & v)); + } + ttt = *prob; + bound = (p->range >> kNumBitModelTotalBits) * ttt; + if (p->code < bound) + { + // bcj2_stats[prob - p->probs][0]++; + p->range = bound; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + continue; + } + { + // bcj2_stats[prob - p->probs][1]++; + p->range -= bound; + p->code -= bound; + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } + } + } + } + { + /* (v == 0xe8 ? 0 : 1) uses setcc instruction with additional zero register usage in x64 MSVC. */ + // const unsigned cj = ((Byte)v == 0xe8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; + const Byte *cur = p->bufs[cj]; + Byte *dest; + SizeT rem; + if (cur == p->lims[cj]) + { + p->state = cj; + break; + } + v = GetBe32a(cur); + p->bufs[cj] = cur + 4; + { + const UInt32 ip = p->ip + 4; + v -= ip; + p->ip = ip; + } + dest = p->dest; + rem = (SizeT)(p->destLim - dest); + if (rem < 4) + { + if ((unsigned)rem > 0) { dest[0] = (Byte)v; v >>= 8; + if ((unsigned)rem > 1) { dest[1] = (Byte)v; v >>= 8; + if ((unsigned)rem > 2) { dest[2] = (Byte)v; v >>= 8; }}} + p->temp = v; + p->dest = dest + rem; + p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; + break; + } + SetUi32(dest, v) + v >>= 24; + p->dest = dest + 4; + } + } + + if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) + { + p->range <<= 8; + p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + } + return SZ_OK; +} + +#undef NUM_ITERS +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff -Nru p7zip-rar-16.02/C/Bcj2.h p7zip-rar-16.02+really25.00+ds/C/Bcj2.h --- p7zip-rar-16.02/C/Bcj2.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bcj2.h 2023-03-02 17:00:00.000000000 +0000 @@ -1,146 +1,332 @@ -/* Bcj2.h -- BCJ2 Converter for x86 code -2014-11-10 : Igor Pavlov : Public domain */ - -#ifndef __BCJ2_H -#define __BCJ2_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define BCJ2_NUM_STREAMS 4 - -enum -{ - BCJ2_STREAM_MAIN, - BCJ2_STREAM_CALL, - BCJ2_STREAM_JUMP, - BCJ2_STREAM_RC -}; - -enum -{ - BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, - BCJ2_DEC_STATE_ORIG_1, - BCJ2_DEC_STATE_ORIG_2, - BCJ2_DEC_STATE_ORIG_3, - - BCJ2_DEC_STATE_ORIG, - BCJ2_DEC_STATE_OK -}; - -enum -{ - BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, - BCJ2_ENC_STATE_OK -}; - - -#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) - -/* -CBcj2Dec / CBcj2Enc -bufs sizes: - BUF_SIZE(n) = lims[n] - bufs[n] -bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: - (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 - (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 -*/ - -/* -CBcj2Dec: -dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: - bufs[BCJ2_STREAM_MAIN] >= dest && - bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + - BUF_SIZE(BCJ2_STREAM_CALL) + - BUF_SIZE(BCJ2_STREAM_JUMP) - tempReserv = 0 : for first call of Bcj2Dec_Decode - tempReserv = 4 : for any other calls of Bcj2Dec_Decode - overlap with offset = 1 is not allowed -*/ - -typedef struct -{ - const Byte *bufs[BCJ2_NUM_STREAMS]; - const Byte *lims[BCJ2_NUM_STREAMS]; - Byte *dest; - const Byte *destLim; - - unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ - - UInt32 ip; - Byte temp[4]; - UInt32 range; - UInt32 code; - UInt16 probs[2 + 256]; -} CBcj2Dec; - -void Bcj2Dec_Init(CBcj2Dec *p); - -/* Returns: SZ_OK or SZ_ERROR_DATA */ -SRes Bcj2Dec_Decode(CBcj2Dec *p); - -#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) - - - -typedef enum -{ - BCJ2_ENC_FINISH_MODE_CONTINUE, - BCJ2_ENC_FINISH_MODE_END_BLOCK, - BCJ2_ENC_FINISH_MODE_END_STREAM -} EBcj2Enc_FinishMode; - -typedef struct -{ - Byte *bufs[BCJ2_NUM_STREAMS]; - const Byte *lims[BCJ2_NUM_STREAMS]; - const Byte *src; - const Byte *srcLim; - - unsigned state; - EBcj2Enc_FinishMode finishMode; - - Byte prevByte; - - Byte cache; - UInt32 range; - UInt64 low; - UInt64 cacheSize; - - UInt32 ip; - - /* 32-bit ralative offset in JUMP/CALL commands is - - (mod 4 GB) in 32-bit mode - - signed Int32 in 64-bit mode - We use (mod 4 GB) check for fileSize. - Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ - UInt32 fileIp; - UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ - UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ - - UInt32 tempTarget; - unsigned tempPos; - Byte temp[4 * 2]; - - unsigned flushPos; - - UInt16 probs[2 + 256]; -} CBcj2Enc; - -void Bcj2Enc_Init(CBcj2Enc *p); -void Bcj2Enc_Encode(CBcj2Enc *p); - -#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) -#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) - - -#define BCJ2_RELAT_LIMIT_NUM_BITS 26 -#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) - -/* limit for CBcj2Enc::fileSize variable */ -#define BCJ2_FileSize_MAX ((UInt32)1 << 31) - -EXTERN_C_END - -#endif +/* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2) +2023-03-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_BCJ2_H +#define ZIP7_INC_BCJ2_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define BCJ2_NUM_STREAMS 4 + +enum +{ + BCJ2_STREAM_MAIN, + BCJ2_STREAM_CALL, + BCJ2_STREAM_JUMP, + BCJ2_STREAM_RC +}; + +enum +{ + BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, + BCJ2_DEC_STATE_ORIG_1, + BCJ2_DEC_STATE_ORIG_2, + BCJ2_DEC_STATE_ORIG_3, + + BCJ2_DEC_STATE_ORIG, + BCJ2_DEC_STATE_ERROR /* after detected data error */ +}; + +enum +{ + BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, + BCJ2_ENC_STATE_FINISHED /* it's state after fully encoded stream */ +}; + + +/* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */ +#define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2) + +/* +CBcj2Dec / CBcj2Enc +bufs sizes: + BUF_SIZE(n) = lims[n] - bufs[n] +bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4: + (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 + (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 +*/ + +// typedef UInt32 CBcj2Prob; +typedef UInt16 CBcj2Prob; + +/* +BCJ2 encoder / decoder internal requirements: + - If last bytes of stream contain marker (e8/e8/0f8x), then + there is also encoded symbol (0 : no conversion) in RC stream. + - One case of overlapped instructions is supported, + if last byte of converted instruction is (0f) and next byte is (8x): + marker [xx xx xx 0f] 8x + then the pair (0f 8x) is treated as marker. +*/ + +/* ---------- BCJ2 Decoder ---------- */ + +/* +CBcj2Dec: +(dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: + bufs[BCJ2_STREAM_MAIN] >= dest && + bufs[BCJ2_STREAM_MAIN] - dest >= + BUF_SIZE(BCJ2_STREAM_CALL) + + BUF_SIZE(BCJ2_STREAM_JUMP) + reserve = bufs[BCJ2_STREAM_MAIN] - dest - + ( BUF_SIZE(BCJ2_STREAM_CALL) + + BUF_SIZE(BCJ2_STREAM_JUMP) ) + and additional conditions: + if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve != 1) : if (ver < v23.00) + } + else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve >= 6) : if (ver < v23.00) + (reserve >= 4) : if (ver >= v23.00) + We need that (reserve) because after first call of Bcj2Dec_Decode(), + CBcj2Dec::temp can contain up to 4 bytes for writing to (dest). + } + (reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode(). + (reserve == 0) also is allowed in case of multi-call, if we use fixed buffers, + and (reserve) is calculated from full (final) sizes of all streams before first call. +*/ + +typedef struct +{ + const Byte *bufs[BCJ2_NUM_STREAMS]; + const Byte *lims[BCJ2_NUM_STREAMS]; + Byte *dest; + const Byte *destLim; + + unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ + + UInt32 ip; /* property of starting base for decoding */ + UInt32 temp; /* Byte temp[4]; */ + UInt32 range; + UInt32 code; + CBcj2Prob probs[2 + 256]; +} CBcj2Dec; + + +/* Note: + Bcj2Dec_Init() sets (CBcj2Dec::ip = 0) + if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init() +*/ +void Bcj2Dec_Init(CBcj2Dec *p); + + +/* Bcj2Dec_Decode(): + returns: + SZ_OK + SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct +*/ +SRes Bcj2Dec_Decode(CBcj2Dec *p); + +/* To check that decoding was finished you can compare + sizes of processed streams with sizes known from another sources. + You must do at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. + additional optional checks: + - the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC) + - the checks Bcj2Dec_IsMaybeFinished*() + also before actual decoding you can check that the + following condition is met for stream sizes: + ( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) ) +*/ + +/* (state == BCJ2_STREAM_MAIN) means that decoder is ready for + additional input data in BCJ2_STREAM_MAIN stream. + Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN) + +/* if the stream decoding was finished correctly, then range decoder + part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0). + Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0) + +/* use Bcj2Dec_IsMaybeFinished() only as additional check + after at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. +*/ +#define Bcj2Dec_IsMaybeFinished(_p_) ( \ + Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \ + Bcj2Dec_IsMaybeFinished_code(_p_)) + + + +/* ---------- BCJ2 Encoder ---------- */ + +typedef enum +{ + BCJ2_ENC_FINISH_MODE_CONTINUE, + BCJ2_ENC_FINISH_MODE_END_BLOCK, + BCJ2_ENC_FINISH_MODE_END_STREAM +} EBcj2Enc_FinishMode; + +/* + BCJ2_ENC_FINISH_MODE_CONTINUE: + process non finished encoding. + It notifies the encoder that additional further calls + can provide more input data (src) than provided by current call. + In that case the CBcj2Enc encoder still can move (src) pointer + up to (srcLim), but CBcj2Enc encoder can store some of the last + processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer. + at return: + (CBcj2Enc::src will point to position that includes + processed data and data copied to (temp[]) buffer) + That data from (temp[]) buffer will be used in further calls. + + BCJ2_ENC_FINISH_MODE_END_BLOCK: + finish encoding of current block (ended at srcLim) without RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) && + CBcj2Enc::src == CBcj2Enc::srcLim) + : it shows that block encoding was finished. And the encoder is + ready for new (src) data or for stream finish operation. + finished block means + { + CBcj2Enc has completed block encoding up to (srcLim). + (1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will + not cross block boundary at (srcLim). + temporary CBcj2Enc buffer for (ORIG) src data is empty. + 3 output uncompressed streams (MAIN, CALL, JUMP) were flushed. + RC stream was not flushed. And RC stream will cross block boundary. + } + Note: some possible implementation of BCJ2 encoder could + write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(), + and it could calculate symbol for RC in another call of Bcj2Enc_Encode(). + BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol. + And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls. + So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK + to ensure that RC symbol is calculated and written in proper block. + + BCJ2_ENC_FINISH_MODE_END_STREAM + finish encoding of stream (ended at srcLim) fully including RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED) + : it shows that stream encoding was finished fully, + and all output streams were flushed fully. + also Bcj2Enc_IsFinished() can be called. +*/ + + +/* + 32-bit relative offset in JUMP/CALL commands is + - (mod 4 GiB) for 32-bit x86 code + - signed Int32 for 64-bit x86-64 code + BCJ2 encoder also does internal relative to absolute address conversions. + And there are 2 possible ways to do it: + before v23: we used 32-bit variables and (mod 4 GiB) conversion + since v23: we use 64-bit variables and (signed Int32 offset) conversion. + The absolute address condition for conversion in v23: + ((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64) + note that if (fileSize64 > 2 GiB). there is difference between + old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23). + And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases. +*/ + +/* +// for old (v22) way for conversion: +typedef UInt32 CBcj2Enc_ip_unsigned; +typedef Int32 CBcj2Enc_ip_signed; +#define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31) +*/ +typedef UInt64 CBcj2Enc_ip_unsigned; +typedef Int64 CBcj2Enc_ip_signed; + +/* maximum size of file that can be used for conversion condition */ +#define BCJ2_ENC_FileSize_MAX ((CBcj2Enc_ip_unsigned)0 - 2) + +/* default value of fileSize64_minus1 variable that means + that absolute address limitation will not be used */ +#define BCJ2_ENC_FileSizeField_UNLIMITED ((CBcj2Enc_ip_unsigned)0 - 1) + +/* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */ +#define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \ + ((CBcj2Enc_ip_unsigned)(fileSize) - 1) + +/* set CBcj2Enc::fileSize64_minus1 variable from size of file */ +#define Bcj2Enc_SET_FileSize(p, fileSize) \ + (p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize); + + +typedef struct +{ + Byte *bufs[BCJ2_NUM_STREAMS]; + const Byte *lims[BCJ2_NUM_STREAMS]; + const Byte *src; + const Byte *srcLim; + + unsigned state; + EBcj2Enc_FinishMode finishMode; + + Byte context; + Byte flushRem; + Byte isFlushState; + + Byte cache; + UInt32 range; + UInt64 low; + UInt64 cacheSize; + + // UInt32 context; // for marker version, it can include marker flag. + + /* (ip64) and (fileIp64) correspond to virtual source stream position + that doesn't include data in temp[] */ + CBcj2Enc_ip_unsigned ip64; /* current (ip) position */ + CBcj2Enc_ip_unsigned fileIp64; /* start (ip) position of current file */ + CBcj2Enc_ip_unsigned fileSize64_minus1; /* size of current file (for conversion limitation) */ + UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */ + // UInt32 relatExcludeBits; + + UInt32 tempTarget; + unsigned tempPos; /* the number of bytes that were copied to temp[] buffer + (tempPos <= 4) outside of Bcj2Enc_Encode() */ + // Byte temp[4]; // for marker version + Byte temp[8]; + CBcj2Prob probs[2 + 256]; +} CBcj2Enc; + +void Bcj2Enc_Init(CBcj2Enc *p); + + +/* +Bcj2Enc_Encode(): at exit: + p->State < BCJ2_NUM_STREAMS : we need more buffer space for output stream + (bufs[p->State] == lims[p->State]) + p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream + (src == srcLim) + p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream +*/ +void Bcj2Enc_Encode(CBcj2Enc *p); + +/* Bcj2Enc encoder can look ahead for up 4 bytes of source stream. + CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer. + (CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after + fully processed data and after data copied to temp buffer. + So if the caller needs to get real number of fully processed input + bytes (without look ahead data in temp buffer), + the caller must subtruct (CBcj2Enc::tempPos) value from processed size + value that is calculated based on current (CBcj2Enc::src): + cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) - + Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); +*/ +/* get the size of input data that was stored in temp[] buffer: */ +#define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos) + +#define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0) + +/* Note : the decoder supports overlapping of marker (0f 80). + But we can eliminate such overlapping cases by setting + the limit for relative offset conversion as + CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB) +*/ +/* default value for CBcj2Enc::relatLimit */ +#define BCJ2_ENC_RELAT_LIMIT_DEFAULT ((UInt32)0x0f << 24) +#define BCJ2_ENC_RELAT_LIMIT_MAX ((UInt32)1 << 31) +// #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5 + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Bcj2Enc.c p7zip-rar-16.02+really25.00+ds/C/Bcj2Enc.c --- p7zip-rar-16.02/C/Bcj2Enc.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bcj2Enc.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,312 +1,506 @@ -/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code) -2014-11-10 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -/* #define SHOW_STAT */ - -#ifdef SHOW_STAT -#include -#define PRF(x) x -#else -#define PRF(x) -#endif - -#include -#include - -#include "Bcj2.h" -#include "CpuArch.h" - -#define CProb UInt16 - -#define kTopValue ((UInt32)1 << 24) -#define kNumModelBits 11 -#define kBitModelTotal (1 << kNumModelBits) -#define kNumMoveBits 5 - -void Bcj2Enc_Init(CBcj2Enc *p) -{ - unsigned i; - - p->state = BCJ2_ENC_STATE_OK; - p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - p->prevByte = 0; - - p->cache = 0; - p->range = 0xFFFFFFFF; - p->low = 0; - p->cacheSize = 1; - - p->ip = 0; - - p->fileIp = 0; - p->fileSize = 0; - p->relatLimit = BCJ2_RELAT_LIMIT; - - p->tempPos = 0; - - p->flushPos = 0; - - for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) - p->probs[i] = kBitModelTotal >> 1; -} - -static Bool MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p) -{ - if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0) - { - Byte *buf = p->bufs[BCJ2_STREAM_RC]; - do - { - if (buf == p->lims[BCJ2_STREAM_RC]) - { - p->state = BCJ2_STREAM_RC; - p->bufs[BCJ2_STREAM_RC] = buf; - return True; - } - *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32)); - p->cache = 0xFF; - } - while (--p->cacheSize); - p->bufs[BCJ2_STREAM_RC] = buf; - p->cache = (Byte)((UInt32)p->low >> 24); - } - p->cacheSize++; - p->low = (UInt32)p->low << 8; - return False; -} - -static void Bcj2Enc_Encode_2(CBcj2Enc *p) -{ - if (BCJ2_IS_32BIT_STREAM(p->state)) - { - Byte *cur = p->bufs[p->state]; - if (cur == p->lims[p->state]) - return; - SetBe32(cur, p->tempTarget); - p->bufs[p->state] = cur + 4; - } - - p->state = BCJ2_ENC_STATE_ORIG; - - for (;;) - { - if (p->range < kTopValue) - { - if (RangeEnc_ShiftLow(p)) - return; - p->range <<= 8; - } - - { - { - const Byte *src = p->src; - const Byte *srcLim; - Byte *dest; - SizeT num = p->srcLim - src; - - if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) - { - if (num <= 4) - return; - num -= 4; - } - else if (num == 0) - break; - - dest = p->bufs[BCJ2_STREAM_MAIN]; - if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest)) - { - num = p->lims[BCJ2_STREAM_MAIN] - dest; - if (num == 0) - { - p->state = BCJ2_STREAM_MAIN; - return; - } - } - - srcLim = src + num; - - if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80) - *dest = src[0]; - else for (;;) - { - Byte b = *src; - *dest = b; - if (b != 0x0F) - { - if ((b & 0xFE) == 0xE8) - break; - dest++; - if (++src != srcLim) - continue; - break; - } - dest++; - if (++src == srcLim) - break; - if ((*src & 0xF0) != 0x80) - continue; - *dest = *src; - break; - } - - num = src - p->src; - - if (src == srcLim) - { - p->prevByte = src[-1]; - p->bufs[BCJ2_STREAM_MAIN] = dest; - p->src = src; - p->ip += (UInt32)num; - continue; - } - - { - Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]); - Bool needConvert; - - p->bufs[BCJ2_STREAM_MAIN] = dest + 1; - p->ip += (UInt32)num + 1; - src++; - - needConvert = False; - - if ((SizeT)(p->srcLim - src) >= 4) - { - UInt32 relatVal = GetUi32(src); - if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize) - && ((relatVal + p->relatLimit) >> 1) < p->relatLimit) - needConvert = True; - } - - { - UInt32 bound; - unsigned ttt; - Byte b = src[-1]; - CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0)); - - ttt = *prob; - bound = (p->range >> kNumModelBits) * ttt; - - if (!needConvert) - { - p->range = bound; - *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); - p->src = src; - p->prevByte = b; - continue; - } - - p->low += bound; - p->range -= bound; - *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); - - { - UInt32 relatVal = GetUi32(src); - UInt32 absVal; - p->ip += 4; - absVal = p->ip + relatVal; - p->prevByte = src[3]; - src += 4; - p->src = src; - { - unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; - Byte *cur = p->bufs[cj]; - if (cur == p->lims[cj]) - { - p->state = cj; - p->tempTarget = absVal; - return; - } - SetBe32(cur, absVal); - p->bufs[cj] = cur + 4; - } - } - } - } - } - } - } - - if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) - return; - - for (; p->flushPos < 5; p->flushPos++) - if (RangeEnc_ShiftLow(p)) - return; - p->state = BCJ2_ENC_STATE_OK; -} - - -void Bcj2Enc_Encode(CBcj2Enc *p) -{ - PRF(printf("\n")); - PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - - if (p->tempPos != 0) - { - unsigned extra = 0; - - for (;;) - { - const Byte *src = p->src; - const Byte *srcLim = p->srcLim; - unsigned finishMode = p->finishMode; - - p->src = p->temp; - p->srcLim = p->temp + p->tempPos; - if (src != srcLim) - p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - - Bcj2Enc_Encode_2(p); - - { - unsigned num = (unsigned)(p->src - p->temp); - unsigned tempPos = p->tempPos - num; - unsigned i; - p->tempPos = tempPos; - for (i = 0; i < tempPos; i++) - p->temp[i] = p->temp[i + num]; - - p->src = src; - p->srcLim = srcLim; - p->finishMode = finishMode; - - if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim) - return; - - if (extra >= tempPos) - { - p->src = src - tempPos; - p->tempPos = 0; - break; - } - - p->temp[tempPos] = src[0]; - p->tempPos = tempPos + 1; - p->src = src + 1; - extra++; - } - } - } - - PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); - - Bcj2Enc_Encode_2(p); - - if (p->state == BCJ2_ENC_STATE_ORIG) - { - const Byte *src = p->src; - unsigned rem = (unsigned)(p->srcLim - src); - unsigned i; - for (i = 0; i < rem; i++) - p->temp[i] = src[i]; - p->tempPos = rem; - p->src = src + rem; - } -} +/* Bcj2Enc.c -- BCJ2 Encoder converter for x86 code (Branch CALL/JUMP variant2) +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +/* #define SHOW_STAT */ +#ifdef SHOW_STAT +#include +#define PRF2(s) printf("%s ip=%8x tempPos=%d src= %8x\n", s, (unsigned)p->ip64, p->tempPos, (unsigned)(p->srcLim - p->src)); +#else +#define PRF2(s) +#endif + +#include "Bcj2.h" +#include "CpuArch.h" + +#define kTopValue ((UInt32)1 << 24) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +void Bcj2Enc_Init(CBcj2Enc *p) +{ + unsigned i; + p->state = BCJ2_ENC_STATE_ORIG; + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + p->context = 0; + p->flushRem = 5; + p->isFlushState = 0; + p->cache = 0; + p->range = 0xffffffff; + p->low = 0; + p->cacheSize = 1; + p->ip64 = 0; + p->fileIp64 = 0; + p->fileSize64_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; + p->relatLimit = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // p->relatExcludeBits = 0; + p->tempPos = 0; + for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) + p->probs[i] = kBitModelTotal >> 1; +} + +// Z7_NO_INLINE +Z7_FORCE_INLINE +static BoolInt Bcj2_RangeEnc_ShiftLow(CBcj2Enc *p) +{ + const UInt32 low = (UInt32)p->low; + const unsigned high = (unsigned) + #if defined(Z7_MSC_VER_ORIGINAL) \ + && defined(MY_CPU_X86) \ + && defined(MY_CPU_LE) \ + && !defined(MY_CPU_64BIT) + // we try to rid of __aullshr() call in MSVS-x86 + (((const UInt32 *)&p->low)[1]); // [1] : for little-endian only + #else + (p->low >> 32); + #endif + if (low < (UInt32)0xff000000 || high != 0) + { + Byte *buf = p->bufs[BCJ2_STREAM_RC]; + do + { + if (buf == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + p->bufs[BCJ2_STREAM_RC] = buf; + return True; + } + *buf++ = (Byte)(p->cache + high); + p->cache = 0xff; + } + while (--p->cacheSize); + p->bufs[BCJ2_STREAM_RC] = buf; + p->cache = (Byte)(low >> 24); + } + p->cacheSize++; + p->low = low << 8; + return False; +} + + +/* +We can use 2 alternative versions of code: +1) non-marker version: + Byte CBcj2Enc::context + Byte temp[8]; + Last byte of marker (e8/e9/[0f]8x) can be written to temp[] buffer. + Encoder writes last byte of marker (e8/e9/[0f]8x) to dest, only in conjunction + with writing branch symbol to range coder in same Bcj2Enc_Encode_2() call. + +2) marker version: + UInt32 CBcj2Enc::context + Byte CBcj2Enc::temp[4]; + MARKER_FLAG in CBcj2Enc::context shows that CBcj2Enc::context contains finded marker. + it's allowed that + one call of Bcj2Enc_Encode_2() writes last byte of marker (e8/e9/[0f]8x) to dest, + and another call of Bcj2Enc_Encode_2() does offset conversion. + So different values of (fileIp) and (fileSize) are possible + in these different Bcj2Enc_Encode_2() calls. + +Also marker version requires additional if((v & MARKER_FLAG) == 0) check in main loop. +So we use non-marker version. +*/ + +/* + Corner cases with overlap in multi-block. + before v23: there was one corner case, where converted instruction + could start in one sub-stream and finish in next sub-stream. + If multi-block (solid) encoding is used, + and BCJ2_ENC_FINISH_MODE_END_BLOCK is used for each sub-stream. + and (0f) is last byte of previous sub-stream + and (8x) is first byte of current sub-stream + then (0f 8x) pair is treated as marker by BCJ2 encoder and decoder. + BCJ2 encoder can converts 32-bit offset for that (0f 8x) cortage, + if that offset meets limit requirements. + If encoder allows 32-bit offset conversion for such overlap case, + then the data in 3 uncompressed BCJ2 streams for some sub-stream + can depend from data of previous sub-stream. + That corner case is not big problem, and it's rare case. + Since v23.00 we do additional check to prevent conversions in such overlap cases. +*/ + +/* + Bcj2Enc_Encode_2() output variables at exit: + { + if (Bcj2Enc_Encode_2() exits with (p->state == BCJ2_ENC_STATE_ORIG)) + { + it means that encoder needs more input data. + if (p->srcLim == p->src) at exit, then + { + (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + all input data were read and processed, and we are ready for + new input data. + } + else + { + (p->srcLim != p->src) + (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + The encoder have found e8/e9/0f_8x marker, + and p->src points to last byte of that marker, + Bcj2Enc_Encode_2() needs more input data to get totally + 5 bytes (last byte of marker and 32-bit branch offset) + as continuous array starting from p->src. + (p->srcLim - p->src < 5) requirement is met after exit. + So non-processed resedue from p->src to p->srcLim is always less than 5 bytes. + } + } + } +*/ + +Z7_NO_INLINE +static void Bcj2Enc_Encode_2(CBcj2Enc *p) +{ + if (!p->isFlushState) + { + const Byte *src; + UInt32 v; + { + const unsigned state = p->state; + if (BCJ2_IS_32BIT_STREAM(state)) + { + Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) + return; + SetBe32a(cur, p->tempTarget) + p->bufs[state] = cur + 4; + } + } + p->state = BCJ2_ENC_STATE_ORIG; // for main reason of exit + src = p->src; + v = p->context; + + // #define WRITE_CONTEXT p->context = v; // for marker version + #define WRITE_CONTEXT p->context = (Byte)v; + #define WRITE_CONTEXT_AND_SRC p->src = src; WRITE_CONTEXT + + for (;;) + { + // const Byte *src; + // UInt32 v; + CBcj2Enc_ip_unsigned ip; + if (p->range < kTopValue) + { + // to reduce register pressure and code size: we save and restore local variables. + WRITE_CONTEXT_AND_SRC + if (Bcj2_RangeEnc_ShiftLow(p)) + return; + p->range <<= 8; + src = p->src; + v = p->context; + } + // src = p->src; + // #define MARKER_FLAG ((UInt32)1 << 17) + // if ((v & MARKER_FLAG) == 0) // for marker version + { + const Byte *srcLim; + Byte *dest = p->bufs[BCJ2_STREAM_MAIN]; + { + const SizeT remSrc = (SizeT)(p->srcLim - src); + SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest); + if (rem >= remSrc) + rem = remSrc; + srcLim = src + rem; + } + /* p->context contains context of previous byte: + bits [0 : 7] : src[-1], if (src) was changed in this call + bits [8 : 31] : are undefined for non-marker version + */ + // v = p->context; + #define NUM_SHIFT_BITS 24 + #define CONV_FLAG ((UInt32)1 << 16) + #define ONE_ITER { \ + b = src[0]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + src++; if (src == srcLim) { break; } } + + if (src != srcLim) + for (;;) + { + /* clang can generate ineffective code with setne instead of two jcc instructions. + we can use 2 iterations and external (unsigned b) to avoid that ineffective code genaration. */ + unsigned b; + ONE_ITER + ONE_ITER + } + + ip = p->ip64 + (CBcj2Enc_ip_unsigned)(SizeT)(dest - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = dest; + p->ip64 = ip; + + if (src == srcLim) + { + WRITE_CONTEXT_AND_SRC + if (src != p->srcLim) + { + p->state = BCJ2_STREAM_MAIN; + return; + } + /* (p->src == p->srcLim) + (p->state == BCJ2_ENC_STATE_ORIG) */ + if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + return; + /* (p->finishMode == BCJ2_ENC_FINISH_MODE_END_STREAM */ + // (p->flushRem == 5); + p->isFlushState = 1; + break; + } + src++; + // p->src = src; + } + // ip = p->ip; // for marker version + /* marker was found */ + /* (v) contains marker that was found: + bits [NUM_SHIFT_BITS : NUM_SHIFT_BITS + 7] + : value of src[-2] : xx/xx/0f + bits [0 : 7] : value of src[-1] : e8/e9/8x + */ + { + { + #if NUM_SHIFT_BITS != 24 + v &= ~(UInt32)CONV_FLAG; + #endif + // UInt32 relat = 0; + if ((SizeT)(p->srcLim - src) >= 4) + { + /* + if (relat != 0 || (Byte)v != 0xe8) + BoolInt isBigOffset = True; + */ + const UInt32 relat = GetUi32(src); + /* + #define EXCLUDE_FLAG ((UInt32)1 << 4) + #define NEED_CONVERT(rel) ((((rel) + EXCLUDE_FLAG) & (0 - EXCLUDE_FLAG * 2)) != 0) + if (p->relatExcludeBits != 0) + { + const UInt32 flag = (UInt32)1 << (p->relatExcludeBits - 1); + isBigOffset = (((relat + flag) & (0 - flag * 2)) != 0); + } + // isBigOffset = False; // for debug + */ + ip -= p->fileIp64; + // Use the following if check, if (ip) is 64-bit: + if (ip > (((v + 0x20) >> 5) & 1)) // 23.00 : we eliminate milti-block overlap for (Of 80) and (e8/e9) + if ((CBcj2Enc_ip_unsigned)((CBcj2Enc_ip_signed)ip + 4 + (Int32)relat) <= p->fileSize64_minus1) + if (((UInt32)(relat + p->relatLimit) >> 1) < p->relatLimit) + v |= CONV_FLAG; + } + else if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + { + // (p->srcLim - src < 4) + // /* + // for non-marker version + p->ip64--; // p->ip = ip - 1; + p->bufs[BCJ2_STREAM_MAIN]--; + src--; + v >>= NUM_SHIFT_BITS; + // (0 < p->srcLim - p->src <= 4) + // */ + // v |= MARKER_FLAG; // for marker version + /* (p->state == BCJ2_ENC_STATE_ORIG) */ + WRITE_CONTEXT_AND_SRC + return; + } + { + const unsigned c = ((v + 0x17) >> 6) & 1; + CBcj2Prob *prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + /* + ((Byte)v == 0xe8 ? 2 + ((Byte)(v >> 8)) : + ((Byte)v < 0xe8 ? 0 : 1)); // ((v >> 5) & 1)); + */ + const unsigned ttt = *prob; + const UInt32 bound = (p->range >> kNumBitModelTotalBits) * ttt; + if ((v & CONV_FLAG) == 0) + { + // static int yyy = 0; yyy++; printf("\n!needConvert = %d\n", yyy); + // v = (Byte)v; // for marker version + p->range = bound; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + // WRITE_CONTEXT_AND_SRC + continue; + } + p->low += bound; + p->range -= bound; + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } + // p->context = src[3]; + { + // const unsigned cj = ((Byte)v == 0xe8 ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP); + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; + ip = p->ip64; + v = GetUi32(src); // relat + ip += 4; + p->ip64 = ip; + src += 4; + // p->src = src; + { + const UInt32 absol = (UInt32)ip + v; + Byte *cur = p->bufs[cj]; + v >>= 24; + // WRITE_CONTEXT + if (cur == p->lims[cj]) + { + p->state = cj; + p->tempTarget = absol; + WRITE_CONTEXT_AND_SRC + return; + } + SetBe32a(cur, absol) + p->bufs[cj] = cur + 4; + } + } + } + } + } // end of loop + } + + for (; p->flushRem != 0; p->flushRem--) + if (Bcj2_RangeEnc_ShiftLow(p)) + return; + p->state = BCJ2_ENC_STATE_FINISHED; +} + + +/* +BCJ2 encoder needs look ahead for up to 4 bytes in (src) buffer. +So base function Bcj2Enc_Encode_2() + in BCJ2_ENC_FINISH_MODE_CONTINUE mode can return with + (p->state == BCJ2_ENC_STATE_ORIG && p->src < p->srcLim) +Bcj2Enc_Encode() solves that look ahead problem by using p->temp[] buffer. + so if (p->state == BCJ2_ENC_STATE_ORIG) after Bcj2Enc_Encode(), + then (p->src == p->srcLim). + And the caller's code is simpler with Bcj2Enc_Encode(). +*/ + +Z7_NO_INLINE +void Bcj2Enc_Encode(CBcj2Enc *p) +{ + PRF2("\n----") + if (p->tempPos != 0) + { + /* extra: number of bytes that were copied from (src) to (temp) buffer in this call */ + unsigned extra = 0; + /* We will touch only minimal required number of bytes in input (src) stream. + So we will add input bytes from (src) stream to temp[] with step of 1 byte. + We don't add new bytes to temp[] before Bcj2Enc_Encode_2() call + in first loop iteration because + - previous call of Bcj2Enc_Encode() could use another (finishMode), + - previous call could finish with (p->state != BCJ2_ENC_STATE_ORIG). + the case with full temp[] buffer (p->tempPos == 4) is possible here. + */ + for (;;) + { + // (0 < p->tempPos <= 5) // in non-marker version + /* p->src : the current src data position including extra bytes + that were copied to temp[] buffer in this call */ + const Byte *src = p->src; + const Byte *srcLim = p->srcLim; + const EBcj2Enc_FinishMode finishMode = p->finishMode; + if (src != srcLim) + { + /* if there are some src data after the data copied to temp[], + then we use MODE_CONTINUE for temp data */ + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + } + p->src = p->temp; + p->srcLim = p->temp + p->tempPos; + PRF2(" ") + Bcj2Enc_Encode_2(p); + { + const unsigned num = (unsigned)(p->src - p->temp); + const unsigned tempPos = p->tempPos - num; + unsigned i; + p->tempPos = tempPos; + for (i = 0; i < tempPos; i++) + p->temp[i] = p->temp[(SizeT)i + num]; + // tempPos : number of bytes in temp buffer + p->src = src; + p->srcLim = srcLim; + p->finishMode = finishMode; + if (p->state != BCJ2_ENC_STATE_ORIG) + { + // (p->tempPos <= 4) // in non-marker version + /* if (the reason of exit from Bcj2Enc_Encode_2() + is not BCJ2_ENC_STATE_ORIG), + then we exit from Bcj2Enc_Encode() with same reason */ + // optional code begin : we rollback (src) and tempPos, if it's possible: + if (extra >= tempPos) + extra = tempPos; + p->src = src - extra; + p->tempPos = tempPos - extra; + // optional code end : rollback of (src) and tempPos + return; + } + /* (p->tempPos <= 4) + (p->state == BCJ2_ENC_STATE_ORIG) + so encoder needs more data than in temp[] */ + if (src == srcLim) + return; // src buffer has no more input data. + /* (src != srcLim) + so we can provide more input data from src for Bcj2Enc_Encode_2() */ + if (extra >= tempPos) + { + /* (extra >= tempPos) means that temp buffer contains + only data from src buffer of this call. + So now we can encode without temp buffer */ + p->src = src - tempPos; // rollback (src) + p->tempPos = 0; + break; + } + // we append one additional extra byte from (src) to temp[] buffer: + p->temp[tempPos] = *src; + p->tempPos = tempPos + 1; + // (0 < p->tempPos <= 5) // in non-marker version + p->src = src + 1; + extra++; + } + } + } + + PRF2("++++") + // (p->tempPos == 0) + Bcj2Enc_Encode_2(p); + PRF2("====") + + if (p->state == BCJ2_ENC_STATE_ORIG) + { + const Byte *src = p->src; + const Byte *srcLim = p->srcLim; + const unsigned rem = (unsigned)(srcLim - src); + /* (rem <= 4) here. + if (p->src != p->srcLim), then + - we copy non-processed bytes from (p->src) to temp[] buffer, + - we set p->src equal to p->srcLim. + */ + if (rem) + { + unsigned i = 0; + p->src = srcLim; + p->tempPos = rem; + // (0 < p->tempPos <= 4) + do + p->temp[i] = src[i]; + while (++i != rem); + } + // (p->tempPos <= 4) + // (p->src == p->srcLim) + } +} + +#undef PRF2 +#undef CONV_FLAG +#undef MARKER_FLAG +#undef WRITE_CONTEXT +#undef WRITE_CONTEXT_AND_SRC +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff -Nru p7zip-rar-16.02/C/Blake2.h p7zip-rar-16.02+really25.00+ds/C/Blake2.h --- p7zip-rar-16.02/C/Blake2.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Blake2.h 2024-01-17 11:00:00.000000000 +0000 @@ -1,48 +1,105 @@ -/* Blake2.h -- BLAKE2 Hash -2015-06-30 : Igor Pavlov : Public domain -2015 : Samuel Neves : Public domain */ - -#ifndef __BLAKE2_H -#define __BLAKE2_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define BLAKE2S_BLOCK_SIZE 64 -#define BLAKE2S_DIGEST_SIZE 32 -#define BLAKE2SP_PARALLEL_DEGREE 8 - -typedef struct -{ - UInt32 h[8]; - UInt32 t[2]; - UInt32 f[2]; - Byte buf[BLAKE2S_BLOCK_SIZE]; - UInt32 bufPos; - UInt32 lastNode_f1; - UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */ -} CBlake2s; - -/* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ -/* -void Blake2s_Init0(CBlake2s *p); -void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size); -void Blake2s_Final(CBlake2s *p, Byte *digest); -*/ - - -typedef struct -{ - CBlake2s S[BLAKE2SP_PARALLEL_DEGREE]; - unsigned bufPos; -} CBlake2sp; - - -void Blake2sp_Init(CBlake2sp *p); -void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size); -void Blake2sp_Final(CBlake2sp *p, Byte *digest); - -EXTERN_C_END - -#endif +/* Blake2.h -- BLAKE2sp Hash +2024-01-17 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_BLAKE2_H +#define ZIP7_INC_BLAKE2_H + +#include "7zTypes.h" + +#if 0 +#include "Compiler.h" +#include "CpuArch.h" +#if defined(MY_CPU_X86_OR_AMD64) +#if defined(__SSE2__) \ + || defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) +#include // SSE2 +#endif + +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) +#include +#if defined(__clang__) +#include +#include +#endif +#endif // avx2 +#endif // MY_CPU_X86_OR_AMD64 +#endif // 0 + +EXTERN_C_BEGIN + +#define Z7_BLAKE2S_BLOCK_SIZE 64 +#define Z7_BLAKE2S_DIGEST_SIZE 32 +#define Z7_BLAKE2SP_PARALLEL_DEGREE 8 +#define Z7_BLAKE2SP_NUM_STRUCT_WORDS 16 + +#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS) +typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_COMPRESS)(UInt32 *states, const Byte *data, const Byte *end); +typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_INIT)(UInt32 *states); +#endif + +// it's required that CBlake2sp is aligned for 32-bytes, +// because the code can use unaligned access with sse and avx256. +// but 64-bytes alignment can be better. +MY_ALIGN(64) +typedef struct +{ + union + { +#if 0 +#if defined(MY_CPU_X86_OR_AMD64) +#if defined(__SSE2__) \ + || defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) + __m128i _pad_align_128bit[4]; +#endif // sse2 +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + __m256i _pad_align_256bit[2]; +#endif // avx2 +#endif // x86 +#endif // 0 + + void * _pad_align_ptr[8]; + UInt32 _pad_align_32bit[16]; + struct + { + unsigned cycPos; + unsigned _pad_unused; +#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS) + Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Fast; + Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Single; + Z7_BLAKE2SP_FUNC_INIT func_Init; + Z7_BLAKE2SP_FUNC_INIT func_Final; +#endif + } header; + } u; + // MY_ALIGN(64) + UInt32 states[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS]; + // MY_ALIGN(64) + UInt32 buf32[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS * 2]; +} CBlake2sp; + +BoolInt Blake2sp_SetFunction(CBlake2sp *p, unsigned algo); +void Blake2sp_Init(CBlake2sp *p); +void Blake2sp_InitState(CBlake2sp *p); +void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size); +void Blake2sp_Final(CBlake2sp *p, Byte *digest); +void z7_Black2sp_Prepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Blake2s.c p7zip-rar-16.02+really25.00+ds/C/Blake2s.c --- p7zip-rar-16.02/C/Blake2s.c 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Blake2s.c 2024-05-18 11:00:00.000000000 +0000 @@ -1,244 +1,2672 @@ -/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash -2015-06-30 : Igor Pavlov : Public domain -2015 : Samuel Neves : Public domain */ - -#include - -#include "Blake2.h" -#include "CpuArch.h" -#include "RotateDefs.h" - -#define rotr32 rotrFixed - -#define BLAKE2S_NUM_ROUNDS 10 -#define BLAKE2S_FINAL_FLAG (~(UInt32)0) - -static const UInt32 k_Blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - - -void Blake2s_Init0(CBlake2s *p) -{ - unsigned i; - for (i = 0; i < 8; i++) - p->h[i] = k_Blake2s_IV[i]; - p->t[0] = 0; - p->t[1] = 0; - p->f[0] = 0; - p->f[1] = 0; - p->bufPos = 0; - p->lastNode_f1 = 0; -} - - -static void Blake2s_Compress(CBlake2s *p) -{ - UInt32 m[16]; - UInt32 v[16]; - - { - unsigned i; - - for (i = 0; i < 16; i++) - m[i] = GetUi32(p->buf + i * sizeof(m[i])); - - for (i = 0; i < 8; i++) - v[i] = p->h[i]; - } - - v[ 8] = k_Blake2s_IV[0]; - v[ 9] = k_Blake2s_IV[1]; - v[10] = k_Blake2s_IV[2]; - v[11] = k_Blake2s_IV[3]; - - v[12] = p->t[0] ^ k_Blake2s_IV[4]; - v[13] = p->t[1] ^ k_Blake2s_IV[5]; - v[14] = p->f[0] ^ k_Blake2s_IV[6]; - v[15] = p->f[1] ^ k_Blake2s_IV[7]; - - #define G(r,i,a,b,c,d) \ - a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \ - a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \ - - #define R(r) \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - - { - unsigned r; - for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++) - { - const Byte *sigma = k_Blake2s_Sigma[r]; - R(r); - } - /* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */ - } - - #undef G - #undef R - - { - unsigned i; - for (i = 0; i < 8; i++) - p->h[i] ^= v[i] ^ v[i + 8]; - } -} - - -#define Blake2s_Increment_Counter(S, inc) \ - { p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); } - -#define Blake2s_Set_LastBlock(p) \ - { p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; } - - -static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size) -{ - while (size != 0) - { - unsigned pos = (unsigned)p->bufPos; - unsigned rem = BLAKE2S_BLOCK_SIZE - pos; - - if (size <= rem) - { - memcpy(p->buf + pos, data, size); - p->bufPos += (UInt32)size; - return; - } - - memcpy(p->buf + pos, data, rem); - Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE); - Blake2s_Compress(p); - p->bufPos = 0; - data += rem; - size -= rem; - } -} - - -static void Blake2s_Final(CBlake2s *p, Byte *digest) -{ - unsigned i; - - Blake2s_Increment_Counter(S, (UInt32)p->bufPos); - Blake2s_Set_LastBlock(p); - memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos); - Blake2s_Compress(p); - - for (i = 0; i < 8; i++) - SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]); -} - - -/* ---------- BLAKE2s ---------- */ - -/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ -/* -typedef struct -{ - Byte digest_length; - Byte key_length; - Byte fanout; - Byte depth; - UInt32 leaf_length; - Byte node_offset[6]; - Byte node_depth; - Byte inner_length; - Byte salt[BLAKE2S_SALTBYTES]; - Byte personal[BLAKE2S_PERSONALBYTES]; -} CBlake2sParam; -*/ - - -static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth) -{ - Blake2s_Init0(p); - - p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24)); - p->h[2] ^= ((UInt32)node_offset); - p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24); - /* - P->digest_length = BLAKE2S_DIGEST_SIZE; - P->key_length = 0; - P->fanout = BLAKE2SP_PARALLEL_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48(P->node_offset, node_offset); - P->node_depth = node_depth; - P->inner_length = BLAKE2S_DIGEST_SIZE; - */ -} - - -void Blake2sp_Init(CBlake2sp *p) -{ - unsigned i; - - p->bufPos = 0; - - for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) - Blake2sp_Init_Spec(&p->S[i], i, 0); - - p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG; -} - - -void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size) -{ - unsigned pos = p->bufPos; - while (size != 0) - { - unsigned index = pos / BLAKE2S_BLOCK_SIZE; - unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1)); - if (rem > size) - rem = (unsigned)size; - Blake2s_Update(&p->S[index], data, rem); - size -= rem; - data += rem; - pos += rem; - pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1); - } - p->bufPos = pos; -} - - -void Blake2sp_Final(CBlake2sp *p, Byte *digest) -{ - CBlake2s R; - unsigned i; - - Blake2sp_Init_Spec(&R, 0, 1); - R.lastNode_f1 = BLAKE2S_FINAL_FLAG; - - for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) - { - Byte hash[BLAKE2S_DIGEST_SIZE]; - Blake2s_Final(&p->S[i], hash); - Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE); - } - - Blake2s_Final(&R, digest); -} +/* Blake2s.c -- BLAKE2sp Hash +2024-05-18 : Igor Pavlov : Public domain +2015-2019 : Samuel Neves : original code : CC0 1.0 Universal (CC0 1.0). */ + +#include "Precomp.h" + +// #include +#include + +#include "Blake2.h" +#include "RotateDefs.h" +#include "Compiler.h" +#include "CpuArch.h" + +/* + if defined(__AVX512F__) && defined(__AVX512VL__) + { + we define Z7_BLAKE2S_USE_AVX512_ALWAYS, + but the compiler can use avx512 for any code. + } + else if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + { we use avx512 only for sse* and avx* branches of code. } +*/ +// #define Z7_BLAKE2S_USE_AVX512_ALWAYS // for debug + +#if defined(__SSE2__) + #define Z7_BLAKE2S_USE_VECTORS +#elif defined(MY_CPU_X86_OR_AMD64) + #if defined(_MSC_VER) && _MSC_VER > 1200 \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \ + || defined(__clang__) \ + || defined(__INTEL_COMPILER) + #define Z7_BLAKE2S_USE_VECTORS + #endif +#endif + +#ifdef Z7_BLAKE2S_USE_VECTORS + +#define Z7_BLAKE2SP_USE_FUNCTIONS + +// define Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED, if CBlake2sp can be non aligned for 32-bytes. +// #define Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + +// SSSE3 : for _mm_shuffle_epi8 (pshufb) that improves the performance for 5-15%. +#if defined(__SSSE3__) + #define Z7_BLAKE2S_USE_SSSE3 +#elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1500) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40300) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40000) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 20300) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1000) + #define Z7_BLAKE2S_USE_SSSE3 +#endif + +#ifdef Z7_BLAKE2S_USE_SSSE3 +/* SSE41 : for _mm_insert_epi32 (pinsrd) + it can slightly reduce code size and improves the performance in some cases. + it's used only for last 512-1024 bytes, if FAST versions (2 or 3) of vector algos are used. + it can be used for all blocks in another algos (4+). +*/ +#if defined(__SSE4_1__) + #define Z7_BLAKE2S_USE_SSE41 +#elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1500) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40300) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40000) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 20300) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1000) + #define Z7_BLAKE2S_USE_SSE41 +#endif +#endif // SSSE3 + +#if defined(__GNUC__) || defined(__clang__) +#if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) && !(defined(__AVX512F__) && defined(__AVX512VL__)) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("avx512vl,avx512f"))) +#else + #if defined(Z7_BLAKE2S_USE_SSE41) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("sse4.1"))) + #elif defined(Z7_BLAKE2S_USE_SSSE3) + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("ssse3"))) + #else + #define BLAKE2S_ATTRIB_128BIT __attribute__((__target__("sse2"))) + #endif +#endif +#endif + + +#if defined(__AVX2__) + #define Z7_BLAKE2S_USE_AVX2 +#else + #if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) + #define Z7_BLAKE2S_USE_AVX2 + #ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) && !(defined(__AVX512F__) && defined(__AVX512VL__)) + #define BLAKE2S_ATTRIB_AVX2 __attribute__((__target__("avx512vl,avx512f"))) +#else + #define BLAKE2S_ATTRIB_AVX2 __attribute__((__target__("avx2"))) +#endif + #endif + #elif defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #if (Z7_MSC_VER_ORIGINAL == 1900) + #pragma warning(disable : 4752) // found Intel(R) Advanced Vector Extensions; consider using /arch:AVX + #endif + #define Z7_BLAKE2S_USE_AVX2 + #endif +#endif + +#ifdef Z7_BLAKE2S_USE_SSE41 +#include // SSE4.1 +#elif defined(Z7_BLAKE2S_USE_SSSE3) +#include // SSSE3 +#else +#include // SSE2 +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2 +#include +#if defined(__clang__) +#include +#include +#endif +#endif // avx2 + + +#if defined(__AVX512F__) && defined(__AVX512VL__) + // && defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL > 1930) + #ifndef Z7_BLAKE2S_USE_AVX512_ALWAYS + #define Z7_BLAKE2S_USE_AVX512_ALWAYS + #endif + // #pragma message ("=== Blake2s AVX512") +#endif + + +#define Z7_BLAKE2S_USE_V128_FAST +// for speed optimization for small messages: +// #define Z7_BLAKE2S_USE_V128_WAY2 + +#ifdef Z7_BLAKE2S_USE_AVX2 + +// for debug: +// gather is slow +// #define Z7_BLAKE2S_USE_GATHER + + #define Z7_BLAKE2S_USE_AVX2_FAST +// for speed optimization for small messages: +// #define Z7_BLAKE2S_USE_AVX2_WAY2 +// #define Z7_BLAKE2S_USE_AVX2_WAY4 +#if defined(Z7_BLAKE2S_USE_AVX2_WAY2) || \ + defined(Z7_BLAKE2S_USE_AVX2_WAY4) + #define Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#endif +#endif + + #define Z7_BLAKE2SP_ALGO_DEFAULT 0 + #define Z7_BLAKE2SP_ALGO_SCALAR 1 +#ifdef Z7_BLAKE2S_USE_V128_FAST + #define Z7_BLAKE2SP_ALGO_V128_FAST 2 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + #define Z7_BLAKE2SP_ALGO_V256_FAST 3 +#endif + #define Z7_BLAKE2SP_ALGO_V128_WAY1 4 +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + #define Z7_BLAKE2SP_ALGO_V128_WAY2 5 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define Z7_BLAKE2SP_ALGO_V256_WAY2 6 +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + #define Z7_BLAKE2SP_ALGO_V256_WAY4 7 +#endif + +#endif // Z7_BLAKE2S_USE_VECTORS + + + + +#define BLAKE2S_FINAL_FLAG (~(UInt32)0) +#define NSW Z7_BLAKE2SP_NUM_STRUCT_WORDS +#define SUPER_BLOCK_SIZE (Z7_BLAKE2S_BLOCK_SIZE * Z7_BLAKE2SP_PARALLEL_DEGREE) +#define SUPER_BLOCK_MASK (SUPER_BLOCK_SIZE - 1) + +#define V_INDEX_0_0 0 +#define V_INDEX_1_0 1 +#define V_INDEX_2_0 2 +#define V_INDEX_3_0 3 +#define V_INDEX_0_1 4 +#define V_INDEX_1_1 5 +#define V_INDEX_2_1 6 +#define V_INDEX_3_1 7 +#define V_INDEX_0_2 8 +#define V_INDEX_1_2 9 +#define V_INDEX_2_2 10 +#define V_INDEX_3_2 11 +#define V_INDEX_0_3 12 +#define V_INDEX_1_3 13 +#define V_INDEX_2_3 14 +#define V_INDEX_3_3 15 +#define V_INDEX_4_0 0 +#define V_INDEX_5_0 1 +#define V_INDEX_6_0 2 +#define V_INDEX_7_0 3 +#define V_INDEX_7_1 4 +#define V_INDEX_4_1 5 +#define V_INDEX_5_1 6 +#define V_INDEX_6_1 7 +#define V_INDEX_6_2 8 +#define V_INDEX_7_2 9 +#define V_INDEX_4_2 10 +#define V_INDEX_5_2 11 +#define V_INDEX_5_3 12 +#define V_INDEX_6_3 13 +#define V_INDEX_7_3 14 +#define V_INDEX_4_3 15 + +#define V(row, col) v[V_INDEX_ ## row ## _ ## col] + +#define k_Blake2s_IV_0 0x6A09E667UL +#define k_Blake2s_IV_1 0xBB67AE85UL +#define k_Blake2s_IV_2 0x3C6EF372UL +#define k_Blake2s_IV_3 0xA54FF53AUL +#define k_Blake2s_IV_4 0x510E527FUL +#define k_Blake2s_IV_5 0x9B05688CUL +#define k_Blake2s_IV_6 0x1F83D9ABUL +#define k_Blake2s_IV_7 0x5BE0CD19UL + +#define KIV(n) (k_Blake2s_IV_## n) + +#ifdef Z7_BLAKE2S_USE_VECTORS +MY_ALIGN(16) +static const UInt32 k_Blake2s_IV[8] = +{ + KIV(0), KIV(1), KIV(2), KIV(3), KIV(4), KIV(5), KIV(6), KIV(7) +}; +#endif + +#define STATE_T(s) ((s) + 8) +#define STATE_F(s) ((s) + 10) + +#ifdef Z7_BLAKE2S_USE_VECTORS + +#define LOAD_128(p) _mm_load_si128 ((const __m128i *)(const void *)(p)) +#define LOADU_128(p) _mm_loadu_si128((const __m128i *)(const void *)(p)) +#ifdef Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + // here we use unaligned load and stores + // use this branch if CBlake2sp can be unaligned for 16 bytes + #define STOREU_128(p, r) _mm_storeu_si128((__m128i *)(void *)(p), r) + #define LOAD_128_FROM_STRUCT(p) LOADU_128(p) + #define STORE_128_TO_STRUCT(p, r) STOREU_128(p, r) +#else + // here we use aligned load and stores + // use this branch if CBlake2sp is aligned for 16 bytes + #define STORE_128(p, r) _mm_store_si128((__m128i *)(void *)(p), r) + #define LOAD_128_FROM_STRUCT(p) LOAD_128(p) + #define STORE_128_TO_STRUCT(p, r) STORE_128(p, r) +#endif + +#endif // Z7_BLAKE2S_USE_VECTORS + + +#if 0 +static void PrintState(const UInt32 *s, unsigned num) +{ + unsigned i; + printf("\n"); + for (i = 0; i < num; i++) + printf(" %08x", (unsigned)s[i]); +} +static void PrintStates2(const UInt32 *s, unsigned x, unsigned y) +{ + unsigned i; + for (i = 0; i < y; i++) + PrintState(s + i * x, x); + printf("\n"); +} +#endif + + +#define REP8_MACRO(m) { m(0) m(1) m(2) m(3) m(4) m(5) m(6) m(7) } + +#define BLAKE2S_NUM_ROUNDS 10 + +#if defined(Z7_BLAKE2S_USE_VECTORS) +#define ROUNDS_LOOP(mac) \ + { unsigned r; for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++) mac(r) } +#endif +/* +#define ROUNDS_LOOP_2(mac) \ + { unsigned r; for (r = 0; r < BLAKE2S_NUM_ROUNDS; r += 2) { mac(r) mac(r + 1) } } +*/ +#if 0 || 1 && !defined(Z7_BLAKE2S_USE_VECTORS) +#define ROUNDS_LOOP_UNROLLED(m) \ + { m(0) m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) } +#endif + +#define SIGMA_TABLE(M) \ + M( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ), \ + M( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ), \ + M( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ), \ + M( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ), \ + M( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ), \ + M( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ), \ + M( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ), \ + M( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ), \ + M( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ), \ + M( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ) + +#define SIGMA_TABLE_MULT(m, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + { a0*m,a1*m,a2*m,a3*m,a4*m,a5*m,a6*m,a7*m,a8*m,a9*m,a10*m,a11*m,a12*m,a13*m,a14*m,a15*m } +#define SIGMA_TABLE_MULT_4( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(4, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) + +// MY_ALIGN(32) +MY_ALIGN(16) +static const Byte k_Blake2s_Sigma_4[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_4) }; + +#define GET_SIGMA_PTR(p, index) \ + ((const void *)((const Byte *)(const void *)(p) + (index))) + +#define GET_STATE_TABLE_PTR_FROM_BYTE_POS(s, pos) \ + ((UInt32 *)(void *)((Byte *)(void *)(s) + (pos))) + + +#ifdef Z7_BLAKE2S_USE_VECTORS + + +#if 0 + // use loading constants from memory + // is faster for some compilers. + #define KK4(n) KIV(n), KIV(n), KIV(n), KIV(n) +MY_ALIGN(64) +static const UInt32 k_Blake2s_IV_WAY4[]= +{ + KK4(0), KK4(1), KK4(2), KK4(3), KK4(4), KK4(5), KK4(6), KK4(7) +}; + #define GET_128_IV_WAY4(i) LOAD_128(k_Blake2s_IV_WAY4 + 4 * (i)) +#else + // use constant generation: + #define GET_128_IV_WAY4(i) _mm_set1_epi32((Int32)KIV(i)) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#define GET_CONST_128_FROM_ARRAY32(k) \ + _mm_set_epi32((Int32)(k)[3], (Int32)(k)[2], (Int32)(k)[1], (Int32)(k)[0]) +#endif + + +#if 0 +#define k_r8 _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1) +#define k_r16 _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2) +#define k_inc _mm_set_epi32(0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE) +#define k_iv0_128 GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 0) +#define k_iv4_128 GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 4) +#else +#if defined(Z7_BLAKE2S_USE_SSSE3) && \ + !defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) +MY_ALIGN(16) static const Byte k_r8_arr [16] = { 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12 }; +MY_ALIGN(16) static const Byte k_r16_arr[16] = { 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 }; +#define k_r8 LOAD_128(k_r8_arr) +#define k_r16 LOAD_128(k_r16_arr) +#endif +MY_ALIGN(16) static const UInt32 k_inc_arr[4] = { Z7_BLAKE2S_BLOCK_SIZE, 0, 0, 0 }; +#define k_inc LOAD_128(k_inc_arr) +#define k_iv0_128 LOAD_128(k_Blake2s_IV + 0) +#define k_iv4_128 LOAD_128(k_Blake2s_IV + 4) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW + +#ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 80000) + #define MY_mm256_set_m128i(hi, lo) _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1) +#else + #define MY_mm256_set_m128i _mm256_set_m128i +#endif + +#define SET_FROM_128(a) MY_mm256_set_m128i(a, a) + +#ifndef Z7_BLAKE2S_USE_AVX512_ALWAYS +MY_ALIGN(32) static const Byte k_r8_arr_256 [32] = +{ + 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12, + 1, 2, 3, 0, 5, 6, 7, 4, 9, 10, 11, 8 ,13, 14, 15, 12 +}; +MY_ALIGN(32) static const Byte k_r16_arr_256[32] = +{ + 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13, + 2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13 +}; +#define k_r8_256 LOAD_256(k_r8_arr_256) +#define k_r16_256 LOAD_256(k_r16_arr_256) +#endif + +// #define k_r8_256 SET_FROM_128(_mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)) +// #define k_r16_256 SET_FROM_128(_mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)) +// #define k_inc_256 SET_FROM_128(_mm_set_epi32(0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE)) +// #define k_iv0_256 SET_FROM_128(GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 0)) +#define k_iv4_256 SET_FROM_128(GET_CONST_128_FROM_ARRAY32(k_Blake2s_IV + 4)) +#endif // Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#endif + + +/* +IPC(TP) ports: +1 p__5 : skl- : SSE : shufps : _mm_shuffle_ps +2 p_15 : icl+ +1 p__5 : nhm-bdw : SSE : xorps : _mm_xor_ps +3 p015 : skl+ + +3 p015 : SSE2 : pxor : _mm_xor_si128 +2 p_15: snb-bdw : SSE2 : padd : _mm_add_epi32 +2 p0_5: mrm-wsm : +3 p015 : skl+ + +2 p_15 : ivb-,icl+ : SSE2 : punpcklqdq, punpckhqdq, punpckldq, punpckhdq +2 p_15 : : SSE2 : pshufd : _mm_shuffle_epi32 +2 p_15 : : SSE2 : pshuflw : _mm_shufflelo_epi16 +2 p_15 : : SSE2 : psrldq : +2 p_15 : : SSE3 : pshufb : _mm_shuffle_epi8 +2 p_15 : : SSE4 : pblendw : _mm_blend_epi16 +1 p__5 : hsw-skl : * + +1 p0 : SSE2 : pslld (i8) : _mm_slli_si128 +2 p01 : skl+ : + +2 p_15 : ivb- : SSE3 : palignr +1 p__5 : hsw+ + +2 p_15 + p23 : ivb-, icl+ : SSE4 : pinsrd : _mm_insert_epi32(xmm, m32, i8) +1 p__5 + p23 : hsw-skl +1 p_15 + p5 : ivb-, ice+ : SSE4 : pinsrd : _mm_insert_epi32(xmm, r32, i8) +0.5 2*p5 : hsw-skl + +2 p23 : SSE2 : movd (m32) +3 p23A : adl : +1 p5: : SSE2 : movd (r32) +*/ + +#if 0 && defined(__XOP__) +// we must debug and test __XOP__ instruction +#include +#include + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) _mm_roti_epi32(r, -(c)) + #define Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED +#elif 1 && defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) _mm_ror_epi32(r, c) + #define Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED +#else + +// MSVC_1937+ uses "orps" instruction for _mm_or_si128(). +// But "orps" has low throughput: TP=1 for bdw-nhm. +// So it can be better to use _mm_add_epi32()/"paddd" (TP=2 for bdw-nhm) instead of "xorps". +// But "orps" is fast for modern cpus (skl+). +// So we are default with "or" version: +#if 0 || 0 && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL > 1937 + // minor optimization for some old cpus, if "xorps" is slow. + #define MM128_EPI32_OR_or_ADD _mm_add_epi32 +#else + #define MM128_EPI32_OR_or_ADD _mm_or_si128 +#endif + + #define MM_ROR_EPI32_VIA_SHIFT(r, c)( \ + MM128_EPI32_OR_or_ADD( \ + _mm_srli_epi32((r), (c)), \ + _mm_slli_epi32((r), 32-(c)))) + #if defined(Z7_BLAKE2S_USE_SSSE3) || defined(Z7_BLAKE2S_USE_SSE41) + #define LOAD_ROTATE_CONSTS \ + const __m128i r8 = k_r8; \ + const __m128i r16 = k_r16; + #define MM_ROR_EPI32(r, c) ( \ + ( 8==(c)) ? _mm_shuffle_epi8(r,r8) \ + : (16==(c)) ? _mm_shuffle_epi8(r,r16) \ + : MM_ROR_EPI32_VIA_SHIFT(r, c)) + #else + #define LOAD_ROTATE_CONSTS + #define MM_ROR_EPI32(r, c) ( \ + (16==(c)) ? _mm_shufflehi_epi16(_mm_shufflelo_epi16(r, 0xb1), 0xb1) \ + : MM_ROR_EPI32_VIA_SHIFT(r, c)) + #endif +#endif + +/* +we have 3 main ways to load 4 32-bit integers to __m128i: + 1) SSE2: _mm_set_epi32() + 2) SSE2: _mm_unpacklo_epi64() / _mm_unpacklo_epi32 / _mm_cvtsi32_si128() + 3) SSE41: _mm_insert_epi32() and _mm_cvtsi32_si128() +good compiler for _mm_set_epi32() generates these instructions: +{ + movd xmm, [m32]; vpunpckldq; vpunpckldq; vpunpcklqdq; +} +good new compiler generates one instruction +{ + for _mm_insert_epi32() : { pinsrd xmm, [m32], i } + for _mm_cvtsi32_si128() : { movd xmm, [m32] } +} +but vc2010 generates slow pair of instructions: +{ + for _mm_insert_epi32() : { mov r32, [m32]; pinsrd xmm, r32, i } + for _mm_cvtsi32_si128() : { mov r32, [m32]; movd xmm, r32 } +} +_mm_insert_epi32() (pinsrd) code reduces xmm register pressure +in comparison with _mm_set_epi32() (movd + vpunpckld) code. +Note that variant with "movd xmm, r32" can be more slow, +but register pressure can be more important. +So we can force to "pinsrd" always. +*/ +// #if !defined(Z7_MSC_VER_ORIGINAL) || Z7_MSC_VER_ORIGINAL > 1600 || defined(MY_CPU_X86) +#ifdef Z7_BLAKE2S_USE_SSE41 + /* _mm_set_epi32() can be more effective for GCC and CLANG + _mm_insert_epi32() is more effective for MSVC */ + #if 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) + #define Z7_BLAKE2S_USE_INSERT_INSTRUCTION + #endif +#endif // USE_SSE41 +// #endif + +#ifdef Z7_BLAKE2S_USE_INSERT_INSTRUCTION + // for SSE4.1 +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_insert_epi32( \ + _mm_insert_epi32( \ + _mm_insert_epi32( \ + _mm_cvtsi32_si128( \ + *(const Int32 *)p0), \ + *(const Int32 *)p1, 1), \ + *(const Int32 *)p2, 2), \ + *(const Int32 *)p3, 3) +#elif 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) +/* MSVC 1400 implements _mm_set_epi32() via slow memory write/read. + Also _mm_unpacklo_epi32 is more effective for another MSVC compilers. + But _mm_set_epi32() is more effective for GCC and CLANG. + So we use _mm_unpacklo_epi32 for MSVC only */ +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_unpacklo_epi64( \ + _mm_unpacklo_epi32( _mm_cvtsi32_si128(*(const Int32 *)p0), \ + _mm_cvtsi32_si128(*(const Int32 *)p1)), \ + _mm_unpacklo_epi32( _mm_cvtsi32_si128(*(const Int32 *)p2), \ + _mm_cvtsi32_si128(*(const Int32 *)p3))) +#else +#define MM_LOAD_EPI32_FROM_4_POINTERS(p0, p1, p2, p3) \ + _mm_set_epi32( \ + *(const Int32 *)p3, \ + *(const Int32 *)p2, \ + *(const Int32 *)p1, \ + *(const Int32 *)p0) +#endif + +#define SET_ROW_FROM_SIGMA_BASE(input, i0, i1, i2, i3) \ + MM_LOAD_EPI32_FROM_4_POINTERS( \ + GET_SIGMA_PTR(input, i0), \ + GET_SIGMA_PTR(input, i1), \ + GET_SIGMA_PTR(input, i2), \ + GET_SIGMA_PTR(input, i3)) + +#define SET_ROW_FROM_SIGMA(input, sigma_index) \ + SET_ROW_FROM_SIGMA_BASE(input, \ + sigma[(sigma_index) ], \ + sigma[(sigma_index) + 2 * 1], \ + sigma[(sigma_index) + 2 * 2], \ + sigma[(sigma_index) + 2 * 3]) \ + + +#define ADD_128(a, b) _mm_add_epi32(a, b) +#define XOR_128(a, b) _mm_xor_si128(a, b) + +#define D_ADD_128(dest, src) dest = ADD_128(dest, src) +#define D_XOR_128(dest, src) dest = XOR_128(dest, src) +#define D_ROR_128(dest, shift) dest = MM_ROR_EPI32(dest, shift) +#define D_ADD_EPI64_128(dest, src) dest = _mm_add_epi64(dest, src) + + +#define AXR(a, b, d, shift) \ + D_ADD_128(a, b); \ + D_XOR_128(d, a); \ + D_ROR_128(d, shift); + +#define AXR2(a, b, c, d, input, sigma_index, shift1, shift2) \ + a = _mm_add_epi32 (a, SET_ROW_FROM_SIGMA(input, sigma_index)); \ + AXR(a, b, d, shift1) \ + AXR(c, d, b, shift2) + +#define ROTATE_WORDS_TO_RIGHT(a, n) \ + a = _mm_shuffle_epi32(a, _MM_SHUFFLE((3+n)&3, (2+n)&3, (1+n)&3, (0+n)&3)); + +#define AXR4(a, b, c, d, input, sigma_index) \ + AXR2(a, b, c, d, input, sigma_index, 16, 12) \ + AXR2(a, b, c, d, input, sigma_index + 1, 8, 7) \ + +#define RR2(a, b, c, d, input) \ + { \ + AXR4(a, b, c, d, input, 0) \ + ROTATE_WORDS_TO_RIGHT(b, 1) \ + ROTATE_WORDS_TO_RIGHT(c, 2) \ + ROTATE_WORDS_TO_RIGHT(d, 3) \ + AXR4(a, b, c, d, input, 8) \ + ROTATE_WORDS_TO_RIGHT(b, 3) \ + ROTATE_WORDS_TO_RIGHT(c, 2) \ + ROTATE_WORDS_TO_RIGHT(d, 1) \ + } + + +/* +Way1: +per 64 bytes block: +10 rounds * 4 iters * (7 + 2) = 360 cycles = if pslld TP=1 + * (7 + 1) = 320 cycles = if pslld TP=2 (skl+) +additional operations per 7_op_iter : +4 movzx byte mem +1 movd mem +3 pinsrd mem +1.5 pshufd +*/ + +static +#if 0 || 0 && (defined(Z7_BLAKE2S_USE_V128_WAY2) || \ + defined(Z7_BLAKE2S_USE_V256_WAY2)) + Z7_NO_INLINE +#else + Z7_FORCE_INLINE +#endif +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2s_Compress_V128_Way1(UInt32 * const s, const Byte * const input) +{ + __m128i a, b, c, d; + __m128i f0, f1; + + LOAD_ROTATE_CONSTS + d = LOAD_128_FROM_STRUCT(STATE_T(s)); + c = k_iv0_128; + a = f0 = LOAD_128_FROM_STRUCT(s); + b = f1 = LOAD_128_FROM_STRUCT(s + 4); + D_ADD_EPI64_128(d, k_inc); + STORE_128_TO_STRUCT (STATE_T(s), d); + D_XOR_128(d, k_iv4_128); + +#define RR(r) { const Byte * const sigma = k_Blake2s_Sigma_4[r]; \ + RR2(a, b, c, d, input) } + + ROUNDS_LOOP(RR) +#undef RR + + STORE_128_TO_STRUCT(s , XOR_128(f0, XOR_128(a, c))); + STORE_128_TO_STRUCT(s + 4, XOR_128(f1, XOR_128(b, d))); +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Way1(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Blake2s_Compress_V128_Way1(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + + +#if defined(Z7_BLAKE2S_USE_V128_WAY2) || \ + defined(Z7_BLAKE2S_USE_AVX2_WAY2) +#if 1 + #define Z7_BLAKE2S_CompressSingleBlock(s, data) \ + Blake2sp_Compress2_V128_Way1(s, data, \ + (const Byte *)(const void *)(data) + Z7_BLAKE2S_BLOCK_SIZE) +#else + #define Z7_BLAKE2S_CompressSingleBlock Blake2s_Compress_V128_Way1 +#endif +#endif + + +#if (defined(Z7_BLAKE2S_USE_AVX2_WAY_SLOW) || \ + defined(Z7_BLAKE2S_USE_V128_WAY2)) && \ + !defined(Z7_BLAKE2S_USE_GATHER) +#define AXR2_LOAD_INDEXES(sigma_index) \ + const unsigned i0 = sigma[(sigma_index)]; \ + const unsigned i1 = sigma[(sigma_index) + 2 * 1]; \ + const unsigned i2 = sigma[(sigma_index) + 2 * 2]; \ + const unsigned i3 = sigma[(sigma_index) + 2 * 3]; \ + +#define SET_ROW_FROM_SIGMA_W(input) \ + SET_ROW_FROM_SIGMA_BASE(input, i0, i1, i2, i3) +#endif + + +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + +#if 1 || !defined(Z7_BLAKE2S_USE_SSE41) +/* we use SET_ROW_FROM_SIGMA_BASE, that uses + (SSE4) _mm_insert_epi32(), if Z7_BLAKE2S_USE_INSERT_INSTRUCTION is defined + (SSE2) _mm_set_epi32() + MSVC can be faster for this branch: +*/ +#define AXR2_W(sigma_index, shift1, shift2) \ + { \ + AXR2_LOAD_INDEXES(sigma_index) \ + a0 = _mm_add_epi32(a0, SET_ROW_FROM_SIGMA_W(data)); \ + a1 = _mm_add_epi32(a1, SET_ROW_FROM_SIGMA_W(data + Z7_BLAKE2S_BLOCK_SIZE)); \ + AXR(a0, b0, d0, shift1) \ + AXR(a1, b1, d1, shift1) \ + AXR(c0, d0, b0, shift2) \ + AXR(c1, d1, b1, shift2) \ + } +#else +/* we use interleaved _mm_insert_epi32(): + GCC can be faster for this branch: +*/ +#define AXR2_W_PRE_INSERT(sigma_index, i) \ + { const unsigned ii = sigma[(sigma_index) + i * 2]; \ + t0 = _mm_insert_epi32(t0, *(const Int32 *)GET_SIGMA_PTR(data, ii), i); \ + t1 = _mm_insert_epi32(t1, *(const Int32 *)GET_SIGMA_PTR(data, Z7_BLAKE2S_BLOCK_SIZE + ii), i); \ + } +#define AXR2_W(sigma_index, shift1, shift2) \ + { __m128i t0, t1; \ + { const unsigned ii = sigma[sigma_index]; \ + t0 = _mm_cvtsi32_si128(*(const Int32 *)GET_SIGMA_PTR(data, ii)); \ + t1 = _mm_cvtsi32_si128(*(const Int32 *)GET_SIGMA_PTR(data, Z7_BLAKE2S_BLOCK_SIZE + ii)); \ + } \ + AXR2_W_PRE_INSERT(sigma_index, 1) \ + AXR2_W_PRE_INSERT(sigma_index, 2) \ + AXR2_W_PRE_INSERT(sigma_index, 3) \ + a0 = _mm_add_epi32(a0, t0); \ + a1 = _mm_add_epi32(a1, t1); \ + AXR(a0, b0, d0, shift1) \ + AXR(a1, b1, d1, shift1) \ + AXR(c0, d0, b0, shift2) \ + AXR(c1, d1, b1, shift2) \ + } +#endif + + +#define AXR4_W(sigma_index) \ + AXR2_W(sigma_index, 16, 12) \ + AXR2_W(sigma_index + 1, 8, 7) \ + +#define WW(r) \ + { const Byte * const sigma = k_Blake2s_Sigma_4[r]; \ + AXR4_W(0) \ + ROTATE_WORDS_TO_RIGHT(b0, 1) \ + ROTATE_WORDS_TO_RIGHT(b1, 1) \ + ROTATE_WORDS_TO_RIGHT(c0, 2) \ + ROTATE_WORDS_TO_RIGHT(c1, 2) \ + ROTATE_WORDS_TO_RIGHT(d0, 3) \ + ROTATE_WORDS_TO_RIGHT(d1, 3) \ + AXR4_W(8) \ + ROTATE_WORDS_TO_RIGHT(b0, 3) \ + ROTATE_WORDS_TO_RIGHT(b1, 3) \ + ROTATE_WORDS_TO_RIGHT(c0, 2) \ + ROTATE_WORDS_TO_RIGHT(c1, 2) \ + ROTATE_WORDS_TO_RIGHT(d0, 1) \ + ROTATE_WORDS_TO_RIGHT(d1, 1) \ + } + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Way2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + end -= Z7_BLAKE2S_BLOCK_SIZE; + + if (data != end) + { + LOAD_ROTATE_CONSTS + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m128i a0, b0, c0, d0; + __m128i a1, b1, c1, d1; + { + const __m128i inc = k_inc; + const __m128i temp = k_iv4_128; + d0 = LOAD_128_FROM_STRUCT (STATE_T(s)); + d1 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + D_ADD_EPI64_128(d0, inc); + D_ADD_EPI64_128(d1, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0); + STORE_128_TO_STRUCT (STATE_T(s + NSW), d1); + D_XOR_128(d0, temp); + D_XOR_128(d1, temp); + } + c1 = c0 = k_iv0_128; + a0 = LOAD_128_FROM_STRUCT(s); + b0 = LOAD_128_FROM_STRUCT(s + 4); + a1 = LOAD_128_FROM_STRUCT(s + NSW); + b1 = LOAD_128_FROM_STRUCT(s + NSW + 4); + + ROUNDS_LOOP (WW) + +#undef WW + + D_XOR_128(a0, c0); + D_XOR_128(b0, d0); + D_XOR_128(a1, c1); + D_XOR_128(b1, d1); + + D_XOR_128(a0, LOAD_128_FROM_STRUCT(s)); + D_XOR_128(b0, LOAD_128_FROM_STRUCT(s + 4)); + D_XOR_128(a1, LOAD_128_FROM_STRUCT(s + NSW)); + D_XOR_128(b1, LOAD_128_FROM_STRUCT(s + NSW + 4)); + + STORE_128_TO_STRUCT(s, a0); + STORE_128_TO_STRUCT(s + 4, b0); + STORE_128_TO_STRUCT(s + NSW, a1); + STORE_128_TO_STRUCT(s + NSW + 4, b1); + + data += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + if (data != end) + return; + } + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); + } +} +#endif // Z7_BLAKE2S_USE_V128_WAY2 + + +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + #define Z7_BLAKE2S_Compress2_V128 Blake2sp_Compress2_V128_Way2 +#else + #define Z7_BLAKE2S_Compress2_V128 Blake2sp_Compress2_V128_Way1 +#endif + + + +#ifdef Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED + #define ROT_128_8(x) MM_ROR_EPI32(x, 8) + #define ROT_128_16(x) MM_ROR_EPI32(x, 16) + #define ROT_128_7(x) MM_ROR_EPI32(x, 7) + #define ROT_128_12(x) MM_ROR_EPI32(x, 12) +#else +#if defined(Z7_BLAKE2S_USE_SSSE3) || defined(Z7_BLAKE2S_USE_SSE41) + #define ROT_128_8(x) _mm_shuffle_epi8(x, r8) // k_r8 + #define ROT_128_16(x) _mm_shuffle_epi8(x, r16) // k_r16 +#else + #define ROT_128_8(x) MM_ROR_EPI32_VIA_SHIFT(x, 8) + #define ROT_128_16(x) MM_ROR_EPI32_VIA_SHIFT(x, 16) +#endif + #define ROT_128_7(x) MM_ROR_EPI32_VIA_SHIFT(x, 7) + #define ROT_128_12(x) MM_ROR_EPI32_VIA_SHIFT(x, 12) +#endif + + +#if 1 +// this branch can provide similar speed on x86* in most cases, +// because [base + index*4] provides same speed as [base + index]. +// but some compilers can generate different code with this branch, that can be faster sometimes. +// this branch uses additional table of 10*16=160 bytes. +#define SIGMA_TABLE_MULT_16( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(16, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) +MY_ALIGN(16) +static const Byte k_Blake2s_Sigma_16[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_16) }; +#define GET_SIGMA_PTR_128(r) const Byte * const sigma = k_Blake2s_Sigma_16[r]; +#define GET_SIGMA_VAL_128(n) (sigma[n]) +#else +#define GET_SIGMA_PTR_128(r) const Byte * const sigma = k_Blake2s_Sigma_4[r]; +#define GET_SIGMA_VAL_128(n) (4 * (size_t)sigma[n]) +#endif + + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST +#if 1 +#define SIGMA_TABLE_MULT_32( a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + SIGMA_TABLE_MULT(32, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) +MY_ALIGN(64) +static const UInt16 k_Blake2s_Sigma_32[BLAKE2S_NUM_ROUNDS][16] = + { SIGMA_TABLE(SIGMA_TABLE_MULT_32) }; +#define GET_SIGMA_PTR_256(r) const UInt16 * const sigma = k_Blake2s_Sigma_32[r]; +#define GET_SIGMA_VAL_256(n) (sigma[n]) +#else +#define GET_SIGMA_PTR_256(r) const Byte * const sigma = k_Blake2s_Sigma_4[r]; +#define GET_SIGMA_VAL_256(n) (8 * (size_t)sigma[n]) +#endif +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + +#define D_ROT_128_7(dest) dest = ROT_128_7(dest) +#define D_ROT_128_8(dest) dest = ROT_128_8(dest) +#define D_ROT_128_12(dest) dest = ROT_128_12(dest) +#define D_ROT_128_16(dest) dest = ROT_128_16(dest) + +#define OP_L(a, i) D_ADD_128 (V(a, 0), \ + LOAD_128((const Byte *)(w) + GET_SIGMA_VAL_128(2*(a)+(i)))); + +#define OP_0(a) OP_L(a, 0) +#define OP_7(a) OP_L(a, 1) + +#define OP_1(a) D_ADD_128 (V(a, 0), V(a, 1)); +#define OP_2(a) D_XOR_128 (V(a, 3), V(a, 0)); +#define OP_4(a) D_ADD_128 (V(a, 2), V(a, 3)); +#define OP_5(a) D_XOR_128 (V(a, 1), V(a, 2)); + +#define OP_3(a) D_ROT_128_16 (V(a, 3)); +#define OP_6(a) D_ROT_128_12 (V(a, 1)); +#define OP_8(a) D_ROT_128_8 (V(a, 3)); +#define OP_9(a) D_ROT_128_7 (V(a, 1)); + + +// for 32-bit x86 : interleave mode works slower, because of register pressure. + +#if 0 || 1 && (defined(MY_CPU_X86) \ + || defined(__GNUC__) && !defined(__clang__)) +// non-inteleaved version: +// is fast for x86 32-bit. +// is fast for GCC x86-64. + +#define V4G(a) \ + OP_0 (a) \ + OP_1 (a) \ + OP_2 (a) \ + OP_3 (a) \ + OP_4 (a) \ + OP_5 (a) \ + OP_6 (a) \ + OP_7 (a) \ + OP_1 (a) \ + OP_2 (a) \ + OP_8 (a) \ + OP_4 (a) \ + OP_5 (a) \ + OP_9 (a) \ + +#define V4R \ +{ \ + V4G (0) \ + V4G (1) \ + V4G (2) \ + V4G (3) \ + V4G (4) \ + V4G (5) \ + V4G (6) \ + V4G (7) \ +} + +#elif 0 || 1 && defined(MY_CPU_X86) + +#define OP_INTER_2(op, a,b) \ + op (a) \ + op (b) \ + +#define V4G(a,b) \ + OP_INTER_2 (OP_0, a,b) \ + OP_INTER_2 (OP_1, a,b) \ + OP_INTER_2 (OP_2, a,b) \ + OP_INTER_2 (OP_3, a,b) \ + OP_INTER_2 (OP_4, a,b) \ + OP_INTER_2 (OP_5, a,b) \ + OP_INTER_2 (OP_6, a,b) \ + OP_INTER_2 (OP_7, a,b) \ + OP_INTER_2 (OP_1, a,b) \ + OP_INTER_2 (OP_2, a,b) \ + OP_INTER_2 (OP_8, a,b) \ + OP_INTER_2 (OP_4, a,b) \ + OP_INTER_2 (OP_5, a,b) \ + OP_INTER_2 (OP_9, a,b) \ + +#define V4R \ +{ \ + V4G (0, 1) \ + V4G (2, 3) \ + V4G (4, 5) \ + V4G (6, 7) \ +} + +#else +// iterleave-4 version is fast for x64 (MSVC/CLANG) + +#define OP_INTER_4(op, a,b,c,d) \ + op (a) \ + op (b) \ + op (c) \ + op (d) \ + +#define V4G(a,b,c,d) \ + OP_INTER_4 (OP_0, a,b,c,d) \ + OP_INTER_4 (OP_1, a,b,c,d) \ + OP_INTER_4 (OP_2, a,b,c,d) \ + OP_INTER_4 (OP_3, a,b,c,d) \ + OP_INTER_4 (OP_4, a,b,c,d) \ + OP_INTER_4 (OP_5, a,b,c,d) \ + OP_INTER_4 (OP_6, a,b,c,d) \ + OP_INTER_4 (OP_7, a,b,c,d) \ + OP_INTER_4 (OP_1, a,b,c,d) \ + OP_INTER_4 (OP_2, a,b,c,d) \ + OP_INTER_4 (OP_8, a,b,c,d) \ + OP_INTER_4 (OP_4, a,b,c,d) \ + OP_INTER_4 (OP_5, a,b,c,d) \ + OP_INTER_4 (OP_9, a,b,c,d) \ + +#define V4R \ +{ \ + V4G (0, 1, 2, 3) \ + V4G (4, 5, 6, 7) \ +} + +#endif + +#define V4_ROUND(r) { GET_SIGMA_PTR_128(r); V4R } + + +#define V4_LOAD_MSG_1(w, m, i) \ +{ \ + __m128i m0, m1, m2, m3; \ + __m128i t0, t1, t2, t3; \ + m0 = LOADU_128((m) + ((i) + 0 * 4) * 16); \ + m1 = LOADU_128((m) + ((i) + 1 * 4) * 16); \ + m2 = LOADU_128((m) + ((i) + 2 * 4) * 16); \ + m3 = LOADU_128((m) + ((i) + 3 * 4) * 16); \ + t0 = _mm_unpacklo_epi32(m0, m1); \ + t1 = _mm_unpackhi_epi32(m0, m1); \ + t2 = _mm_unpacklo_epi32(m2, m3); \ + t3 = _mm_unpackhi_epi32(m2, m3); \ + w[(i) * 4 + 0] = _mm_unpacklo_epi64(t0, t2); \ + w[(i) * 4 + 1] = _mm_unpackhi_epi64(t0, t2); \ + w[(i) * 4 + 2] = _mm_unpacklo_epi64(t1, t3); \ + w[(i) * 4 + 3] = _mm_unpackhi_epi64(t1, t3); \ +} + +#define V4_LOAD_MSG(w, m) \ +{ \ + V4_LOAD_MSG_1 (w, m, 0) \ + V4_LOAD_MSG_1 (w, m, 1) \ + V4_LOAD_MSG_1 (w, m, 2) \ + V4_LOAD_MSG_1 (w, m, 3) \ +} + +#define V4_LOAD_UNPACK_PAIR_128(src32, i, d0, d1) \ +{ \ + const __m128i v0 = LOAD_128_FROM_STRUCT((src32) + (i ) * 4); \ + const __m128i v1 = LOAD_128_FROM_STRUCT((src32) + (i + 1) * 4); \ + d0 = _mm_unpacklo_epi32(v0, v1); \ + d1 = _mm_unpackhi_epi32(v0, v1); \ +} + +#define V4_UNPACK_PAIR_128(dest32, i, s0, s1) \ +{ \ + STORE_128_TO_STRUCT((dest32) + i * 4 , _mm_unpacklo_epi64(s0, s1)); \ + STORE_128_TO_STRUCT((dest32) + i * 4 + 16, _mm_unpackhi_epi64(s0, s1)); \ +} + +#define V4_UNPACK_STATE(dest32, src32) \ +{ \ + __m128i t0, t1, t2, t3, t4, t5, t6, t7; \ + V4_LOAD_UNPACK_PAIR_128(src32, 0, t0, t1) \ + V4_LOAD_UNPACK_PAIR_128(src32, 2, t2, t3) \ + V4_LOAD_UNPACK_PAIR_128(src32, 4, t4, t5) \ + V4_LOAD_UNPACK_PAIR_128(src32, 6, t6, t7) \ + V4_UNPACK_PAIR_128(dest32, 0, t0, t2) \ + V4_UNPACK_PAIR_128(dest32, 8, t1, t3) \ + V4_UNPACK_PAIR_128(dest32, 1, t4, t6) \ + V4_UNPACK_PAIR_128(dest32, 9, t5, t7) \ +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_V128_Fast(UInt32 *s_items, const Byte *data, const Byte *end) +{ + // PrintStates2(s_items, 8, 16); + size_t pos = 0; + pos /= 2; + do + { +#if defined(Z7_BLAKE2S_USE_SSSE3) && \ + !defined(Z7_BLAKE2S_MM_ROR_EPI32_IS_SUPPORTED) + const __m128i r8 = k_r8; + const __m128i r16 = k_r16; +#endif + __m128i w[16]; + __m128i v[16]; + UInt32 *s; + V4_LOAD_MSG(w, data) + s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + { + __m128i ctr = LOAD_128_FROM_STRUCT(s + 64); + D_ADD_EPI64_128 (ctr, k_inc); + STORE_128_TO_STRUCT(s + 64, ctr); + v[12] = XOR_128 (GET_128_IV_WAY4(4), _mm_shuffle_epi32(ctr, _MM_SHUFFLE(0, 0, 0, 0))); + v[13] = XOR_128 (GET_128_IV_WAY4(5), _mm_shuffle_epi32(ctr, _MM_SHUFFLE(1, 1, 1, 1))); + } + v[ 8] = GET_128_IV_WAY4(0); + v[ 9] = GET_128_IV_WAY4(1); + v[10] = GET_128_IV_WAY4(2); + v[11] = GET_128_IV_WAY4(3); + v[14] = GET_128_IV_WAY4(6); + v[15] = GET_128_IV_WAY4(7); + +#define LOAD_STATE_128_FROM_STRUCT(i) \ + v[i] = LOAD_128_FROM_STRUCT(s + (i) * 4); + +#define UPDATE_STATE_128_IN_STRUCT(i) \ + STORE_128_TO_STRUCT(s + (i) * 4, XOR_128( \ + XOR_128(v[i], v[(i) + 8]), \ + LOAD_128_FROM_STRUCT(s + (i) * 4))); + + REP8_MACRO (LOAD_STATE_128_FROM_STRUCT) + ROUNDS_LOOP (V4_ROUND) + REP8_MACRO (UPDATE_STATE_128_IN_STRUCT) + + data += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos += Z7_BLAKE2S_BLOCK_SIZE * 4 / 2; + pos &= SUPER_BLOCK_SIZE / 2 - 1; + } + while (data != end); +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_Final_V128_Fast(UInt32 *states) +{ + const __m128i ctr = LOAD_128_FROM_STRUCT(states + 64); + // printf("\nBlake2sp_Compress2_V128_Fast_Final4\n"); + // PrintStates2(states, 8, 16); + { + ptrdiff_t pos = 8 * 4; + do + { + UInt32 *src32 = states + (size_t)(pos * 1); + UInt32 *dest32 = states + (size_t)(pos * 2); + V4_UNPACK_STATE(dest32, src32) + pos -= 8 * 4; + } + while (pos >= 0); + } + { + unsigned k; + for (k = 0; k < 8; k++) + { + UInt32 *s = states + (size_t)k * 16; + STORE_128_TO_STRUCT (STATE_T(s), ctr); + } + } + // PrintStates2(states, 8, 16); +} + + + +#ifdef Z7_BLAKE2S_USE_AVX2 + +#define ADD_256(a, b) _mm256_add_epi32(a, b) +#define XOR_256(a, b) _mm256_xor_si256(a, b) + +#if 1 && defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #define MM256_ROR_EPI32 _mm256_ror_epi32 + #define Z7_MM256_ROR_EPI32_IS_SUPPORTED +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define LOAD_ROTATE_CONSTS_256 +#endif +#else +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + #define LOAD_ROTATE_CONSTS_256 \ + const __m256i r8 = k_r8_256; \ + const __m256i r16 = k_r16_256; +#endif // AVX2_WAY2 + + #define MM256_ROR_EPI32(r, c) ( \ + ( 8==(c)) ? _mm256_shuffle_epi8(r,r8) \ + : (16==(c)) ? _mm256_shuffle_epi8(r,r16) \ + : _mm256_or_si256( \ + _mm256_srli_epi32((r), (c)), \ + _mm256_slli_epi32((r), 32-(c)))) +#endif // WAY_SLOW +#endif + + +#define D_ADD_256(dest, src) dest = ADD_256(dest, src) +#define D_XOR_256(dest, src) dest = XOR_256(dest, src) + +#define LOADU_256(p) _mm256_loadu_si256((const __m256i *)(const void *)(p)) + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +#ifdef Z7_MM256_ROR_EPI32_IS_SUPPORTED +#define ROT_256_16(x) MM256_ROR_EPI32((x), 16) +#define ROT_256_12(x) MM256_ROR_EPI32((x), 12) +#define ROT_256_8(x) MM256_ROR_EPI32((x), 8) +#define ROT_256_7(x) MM256_ROR_EPI32((x), 7) +#else +#define ROTATE8 _mm256_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, \ + 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1) +#define ROTATE16 _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, \ + 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2) +#define ROT_256_16(x) _mm256_shuffle_epi8((x), ROTATE16) +#define ROT_256_12(x) _mm256_or_si256(_mm256_srli_epi32((x), 12), _mm256_slli_epi32((x), 20)) +#define ROT_256_8(x) _mm256_shuffle_epi8((x), ROTATE8) +#define ROT_256_7(x) _mm256_or_si256(_mm256_srli_epi32((x), 7), _mm256_slli_epi32((x), 25)) +#endif + +#define D_ROT_256_7(dest) dest = ROT_256_7(dest) +#define D_ROT_256_8(dest) dest = ROT_256_8(dest) +#define D_ROT_256_12(dest) dest = ROT_256_12(dest) +#define D_ROT_256_16(dest) dest = ROT_256_16(dest) + +#define LOAD_256(p) _mm256_load_si256((const __m256i *)(const void *)(p)) +#ifdef Z7_BLAKE2SP_STRUCT_IS_NOT_ALIGNED + #define STOREU_256(p, r) _mm256_storeu_si256((__m256i *)(void *)(p), r) + #define LOAD_256_FROM_STRUCT(p) LOADU_256(p) + #define STORE_256_TO_STRUCT(p, r) STOREU_256(p, r) +#else + // if struct is aligned for 32-bytes + #define STORE_256(p, r) _mm256_store_si256((__m256i *)(void *)(p), r) + #define LOAD_256_FROM_STRUCT(p) LOAD_256(p) + #define STORE_256_TO_STRUCT(p, r) STORE_256(p, r) +#endif + +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY_SLOW + +#if 0 + #define DIAG_PERM2(s) \ + { \ + const __m256i a = LOAD_256_FROM_STRUCT((s) ); \ + const __m256i b = LOAD_256_FROM_STRUCT((s) + NSW); \ + STORE_256_TO_STRUCT((s ), _mm256_permute2x128_si256(a, b, 0x20)); \ + STORE_256_TO_STRUCT((s + NSW), _mm256_permute2x128_si256(a, b, 0x31)); \ + } +#else + #define DIAG_PERM2(s) \ + { \ + const __m128i a = LOAD_128_FROM_STRUCT((s) + 4); \ + const __m128i b = LOAD_128_FROM_STRUCT((s) + NSW); \ + STORE_128_TO_STRUCT((s) + NSW, a); \ + STORE_128_TO_STRUCT((s) + 4 , b); \ + } +#endif + #define DIAG_PERM8(s_items) \ + { \ + DIAG_PERM2(s_items) \ + DIAG_PERM2(s_items + NSW * 2) \ + DIAG_PERM2(s_items + NSW * 4) \ + DIAG_PERM2(s_items + NSW * 6) \ + } + + +#define AXR256(a, b, d, shift) \ + D_ADD_256(a, b); \ + D_XOR_256(d, a); \ + d = MM256_ROR_EPI32(d, shift); \ + + + +#ifdef Z7_BLAKE2S_USE_GATHER + + #define TABLE_GATHER_256_4(a0,a1,a2,a3) \ + a0,a1,a2,a3, a0+16,a1+16,a2+16,a3+16 + #define TABLE_GATHER_256( \ + a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \ + { TABLE_GATHER_256_4(a0,a2,a4,a6), \ + TABLE_GATHER_256_4(a1,a3,a5,a7), \ + TABLE_GATHER_256_4(a8,a10,a12,a14), \ + TABLE_GATHER_256_4(a9,a11,a13,a15) } +MY_ALIGN(64) +static const UInt32 k_Blake2s_Sigma_gather256[BLAKE2S_NUM_ROUNDS][16 * 2] = + { SIGMA_TABLE(TABLE_GATHER_256) }; + #define GET_SIGMA(r) \ + const UInt32 * const sigma = k_Blake2s_Sigma_gather256[r]; + #define AXR2_LOAD_INDEXES_AVX(sigma_index) \ + const __m256i i01234567 = LOAD_256(sigma + (sigma_index)); + #define SET_ROW_FROM_SIGMA_AVX(in) \ + _mm256_i32gather_epi32((const void *)(in), i01234567, 4) + #define SIGMA_INTERLEAVE 8 + #define SIGMA_HALF_ROW_SIZE 16 + +#else // !Z7_BLAKE2S_USE_GATHER + + #define GET_SIGMA(r) \ + const Byte * const sigma = k_Blake2s_Sigma_4[r]; + #define AXR2_LOAD_INDEXES_AVX(sigma_index) \ + AXR2_LOAD_INDEXES(sigma_index) + #define SET_ROW_FROM_SIGMA_AVX(in) \ + MY_mm256_set_m128i( \ + SET_ROW_FROM_SIGMA_W((in) + Z7_BLAKE2S_BLOCK_SIZE), \ + SET_ROW_FROM_SIGMA_W(in)) + #define SIGMA_INTERLEAVE 1 + #define SIGMA_HALF_ROW_SIZE 8 +#endif // !Z7_BLAKE2S_USE_GATHER + + +#define ROTATE_WORDS_TO_RIGHT_256(a, n) \ + a = _mm256_shuffle_epi32(a, _MM_SHUFFLE((3+n)&3, (2+n)&3, (1+n)&3, (0+n)&3)); + + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + +#define AXR2_A(sigma_index, shift1, shift2) \ + AXR2_LOAD_INDEXES_AVX(sigma_index) \ + D_ADD_256( a0, SET_ROW_FROM_SIGMA_AVX(data)); \ + AXR256(a0, b0, d0, shift1) \ + AXR256(c0, d0, b0, shift2) \ + +#define AXR4_A(sigma_index) \ + { AXR2_A(sigma_index, 16, 12) } \ + { AXR2_A(sigma_index + SIGMA_INTERLEAVE, 8, 7) } + +#define EE1(r) \ + { GET_SIGMA(r) \ + AXR4_A(0) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 3) \ + AXR4_A(SIGMA_HALF_ROW_SIZE) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 1) \ + } + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Way2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + end -= Z7_BLAKE2S_BLOCK_SIZE; + + if (data != end) + { + LOAD_ROTATE_CONSTS_256 + DIAG_PERM8(s_items) + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m256i a0, b0, c0, d0; + { + const __m128i inc = k_inc; + __m128i d0_128 = LOAD_128_FROM_STRUCT (STATE_T(s)); + __m128i d1_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + D_ADD_EPI64_128(d0_128, inc); + D_ADD_EPI64_128(d1_128, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW), d1_128); + d0 = MY_mm256_set_m128i(d1_128, d0_128); + D_XOR_256(d0, k_iv4_256); + } + c0 = SET_FROM_128(k_iv0_128); + a0 = LOAD_256_FROM_STRUCT(s + NSW * 0); + b0 = LOAD_256_FROM_STRUCT(s + NSW * 1); + + ROUNDS_LOOP (EE1) + + D_XOR_256(a0, c0); + D_XOR_256(b0, d0); + + D_XOR_256(a0, LOAD_256_FROM_STRUCT(s + NSW * 0)); + D_XOR_256(b0, LOAD_256_FROM_STRUCT(s + NSW * 1)); + + STORE_256_TO_STRUCT(s + NSW * 0, a0); + STORE_256_TO_STRUCT(s + NSW * 1, b0); + + data += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos += Z7_BLAKE2S_BLOCK_SIZE * 2; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + DIAG_PERM8(s_items) + if (data != end) + return; + } + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); + } +} + +#endif // Z7_BLAKE2S_USE_AVX2_WAY2 + + + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + +#define AXR2_X(sigma_index, shift1, shift2) \ + AXR2_LOAD_INDEXES_AVX(sigma_index) \ + D_ADD_256( a0, SET_ROW_FROM_SIGMA_AVX(data)); \ + D_ADD_256( a1, SET_ROW_FROM_SIGMA_AVX((data) + Z7_BLAKE2S_BLOCK_SIZE * 2)); \ + AXR256(a0, b0, d0, shift1) \ + AXR256(a1, b1, d1, shift1) \ + AXR256(c0, d0, b0, shift2) \ + AXR256(c1, d1, b1, shift2) \ + +#define AXR4_X(sigma_index) \ + { AXR2_X(sigma_index, 16, 12) } \ + { AXR2_X(sigma_index + SIGMA_INTERLEAVE, 8, 7) } + +#define EE2(r) \ + { GET_SIGMA(r) \ + AXR4_X(0) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(b1, 1) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(c1, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(d1, 3) \ + AXR4_X(SIGMA_HALF_ROW_SIZE) \ + ROTATE_WORDS_TO_RIGHT_256(b0, 3) \ + ROTATE_WORDS_TO_RIGHT_256(b1, 3) \ + ROTATE_WORDS_TO_RIGHT_256(c0, 2) \ + ROTATE_WORDS_TO_RIGHT_256(c1, 2) \ + ROTATE_WORDS_TO_RIGHT_256(d0, 1) \ + ROTATE_WORDS_TO_RIGHT_256(d1, 1) \ + } + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Way4(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + + if ((size_t)(end - data) >= Z7_BLAKE2S_BLOCK_SIZE * 4) + { +#ifndef Z7_MM256_ROR_EPI32_IS_SUPPORTED + const __m256i r8 = k_r8_256; + const __m256i r16 = k_r16_256; +#endif + end -= Z7_BLAKE2S_BLOCK_SIZE * 3; + DIAG_PERM8(s_items) + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + __m256i a0, b0, c0, d0; + __m256i a1, b1, c1, d1; + { + const __m128i inc = k_inc; + __m128i d0_128 = LOAD_128_FROM_STRUCT (STATE_T(s)); + __m128i d1_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW)); + __m128i d2_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW * 2)); + __m128i d3_128 = LOAD_128_FROM_STRUCT (STATE_T(s + NSW * 3)); + D_ADD_EPI64_128(d0_128, inc); + D_ADD_EPI64_128(d1_128, inc); + D_ADD_EPI64_128(d2_128, inc); + D_ADD_EPI64_128(d3_128, inc); + STORE_128_TO_STRUCT (STATE_T(s ), d0_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 1), d1_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 2), d2_128); + STORE_128_TO_STRUCT (STATE_T(s + NSW * 3), d3_128); + d0 = MY_mm256_set_m128i(d1_128, d0_128); + d1 = MY_mm256_set_m128i(d3_128, d2_128); + D_XOR_256(d0, k_iv4_256); + D_XOR_256(d1, k_iv4_256); + } + c1 = c0 = SET_FROM_128(k_iv0_128); + a0 = LOAD_256_FROM_STRUCT(s + NSW * 0); + b0 = LOAD_256_FROM_STRUCT(s + NSW * 1); + a1 = LOAD_256_FROM_STRUCT(s + NSW * 2); + b1 = LOAD_256_FROM_STRUCT(s + NSW * 3); + + ROUNDS_LOOP (EE2) + + D_XOR_256(a0, c0); + D_XOR_256(b0, d0); + D_XOR_256(a1, c1); + D_XOR_256(b1, d1); + + D_XOR_256(a0, LOAD_256_FROM_STRUCT(s + NSW * 0)); + D_XOR_256(b0, LOAD_256_FROM_STRUCT(s + NSW * 1)); + D_XOR_256(a1, LOAD_256_FROM_STRUCT(s + NSW * 2)); + D_XOR_256(b1, LOAD_256_FROM_STRUCT(s + NSW * 3)); + + STORE_256_TO_STRUCT(s + NSW * 0, a0); + STORE_256_TO_STRUCT(s + NSW * 1, b0); + STORE_256_TO_STRUCT(s + NSW * 2, a1); + STORE_256_TO_STRUCT(s + NSW * 3, b1); + + data += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos += Z7_BLAKE2S_BLOCK_SIZE * 4; + pos &= SUPER_BLOCK_MASK; + } + while (data < end); + DIAG_PERM8(s_items) + end += Z7_BLAKE2S_BLOCK_SIZE * 3; + } + if (data == end) + return; + // Z7_BLAKE2S_Compress2_V128(s_items, data, end, pos); + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Z7_BLAKE2S_CompressSingleBlock(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + +#endif // Z7_BLAKE2S_USE_AVX2_WAY4 +#endif // Z7_BLAKE2S_USE_AVX2_WAY_SLOW + + +// --------------------------------------------------------- + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +#define OP256_L(a, i) D_ADD_256 (V(a, 0), \ + LOAD_256((const Byte *)(w) + GET_SIGMA_VAL_256(2*(a)+(i)))); + +#define OP256_0(a) OP256_L(a, 0) +#define OP256_7(a) OP256_L(a, 1) + +#define OP256_1(a) D_ADD_256 (V(a, 0), V(a, 1)); +#define OP256_2(a) D_XOR_256 (V(a, 3), V(a, 0)); +#define OP256_4(a) D_ADD_256 (V(a, 2), V(a, 3)); +#define OP256_5(a) D_XOR_256 (V(a, 1), V(a, 2)); + +#define OP256_3(a) D_ROT_256_16 (V(a, 3)); +#define OP256_6(a) D_ROT_256_12 (V(a, 1)); +#define OP256_8(a) D_ROT_256_8 (V(a, 3)); +#define OP256_9(a) D_ROT_256_7 (V(a, 1)); + + +#if 0 || 1 && defined(MY_CPU_X86) + +#define V8_G(a) \ + OP256_0 (a) \ + OP256_1 (a) \ + OP256_2 (a) \ + OP256_3 (a) \ + OP256_4 (a) \ + OP256_5 (a) \ + OP256_6 (a) \ + OP256_7 (a) \ + OP256_1 (a) \ + OP256_2 (a) \ + OP256_8 (a) \ + OP256_4 (a) \ + OP256_5 (a) \ + OP256_9 (a) \ + +#define V8R { \ + V8_G (0); \ + V8_G (1); \ + V8_G (2); \ + V8_G (3); \ + V8_G (4); \ + V8_G (5); \ + V8_G (6); \ + V8_G (7); \ +} + +#else + +#define OP256_INTER_4(op, a,b,c,d) \ + op (a) \ + op (b) \ + op (c) \ + op (d) \ + +#define V8_G(a,b,c,d) \ + OP256_INTER_4 (OP256_0, a,b,c,d) \ + OP256_INTER_4 (OP256_1, a,b,c,d) \ + OP256_INTER_4 (OP256_2, a,b,c,d) \ + OP256_INTER_4 (OP256_3, a,b,c,d) \ + OP256_INTER_4 (OP256_4, a,b,c,d) \ + OP256_INTER_4 (OP256_5, a,b,c,d) \ + OP256_INTER_4 (OP256_6, a,b,c,d) \ + OP256_INTER_4 (OP256_7, a,b,c,d) \ + OP256_INTER_4 (OP256_1, a,b,c,d) \ + OP256_INTER_4 (OP256_2, a,b,c,d) \ + OP256_INTER_4 (OP256_8, a,b,c,d) \ + OP256_INTER_4 (OP256_4, a,b,c,d) \ + OP256_INTER_4 (OP256_5, a,b,c,d) \ + OP256_INTER_4 (OP256_9, a,b,c,d) \ + +#define V8R { \ + V8_G (0, 1, 2, 3) \ + V8_G (4, 5, 6, 7) \ +} +#endif + +#define V8_ROUND(r) { GET_SIGMA_PTR_256(r); V8R } + + +// for debug: +// #define Z7_BLAKE2S_PERMUTE_WITH_GATHER +#if defined(Z7_BLAKE2S_PERMUTE_WITH_GATHER) +// gather instruction is slow. +#define V8_LOAD_MSG(w, m) \ +{ \ + unsigned i; \ + for (i = 0; i < 16; ++i) { \ + w[i] = _mm256_i32gather_epi32( \ + (const void *)((m) + i * sizeof(UInt32)),\ + _mm256_set_epi32(0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00), \ + sizeof(UInt32)); \ + } \ +} +#else // !Z7_BLAKE2S_PERMUTE_WITH_GATHER + +#define V8_LOAD_MSG_2(w, a0, a1) \ +{ \ + (w)[0] = _mm256_permute2x128_si256(a0, a1, 0x20); \ + (w)[4] = _mm256_permute2x128_si256(a0, a1, 0x31); \ +} + +#define V8_LOAD_MSG_4(w, z0, z1, z2, z3) \ +{ \ + __m256i s0, s1, s2, s3; \ + s0 = _mm256_unpacklo_epi64(z0, z1); \ + s1 = _mm256_unpackhi_epi64(z0, z1); \ + s2 = _mm256_unpacklo_epi64(z2, z3); \ + s3 = _mm256_unpackhi_epi64(z2, z3); \ + V8_LOAD_MSG_2((w) + 0, s0, s2) \ + V8_LOAD_MSG_2((w) + 1, s1, s3) \ +} + +#define V8_LOAD_MSG_0(t0, t1, m) \ +{ \ + __m256i m0, m1; \ + m0 = LOADU_256(m); \ + m1 = LOADU_256((m) + 2 * 32); \ + t0 = _mm256_unpacklo_epi32(m0, m1); \ + t1 = _mm256_unpackhi_epi32(m0, m1); \ +} + +#define V8_LOAD_MSG_8(w, m) \ +{ \ + __m256i t0, t1, t2, t3, t4, t5, t6, t7; \ + V8_LOAD_MSG_0(t0, t4, (m) + 0 * 4 * 32) \ + V8_LOAD_MSG_0(t1, t5, (m) + 1 * 4 * 32) \ + V8_LOAD_MSG_0(t2, t6, (m) + 2 * 4 * 32) \ + V8_LOAD_MSG_0(t3, t7, (m) + 3 * 4 * 32) \ + V8_LOAD_MSG_4((w) , t0, t1, t2, t3) \ + V8_LOAD_MSG_4((w) + 2, t4, t5, t6, t7) \ +} + +#define V8_LOAD_MSG(w, m) \ +{ \ + V8_LOAD_MSG_8(w, m) \ + V8_LOAD_MSG_8((w) + 8, (m) + 32) \ +} + +#endif // !Z7_BLAKE2S_PERMUTE_WITH_GATHER + + +#define V8_PERM_PAIR_STORE(u, a0, a2) \ +{ \ + STORE_256_TO_STRUCT((u), _mm256_permute2x128_si256(a0, a2, 0x20)); \ + STORE_256_TO_STRUCT((u) + 8, _mm256_permute2x128_si256(a0, a2, 0x31)); \ +} + +#define V8_UNPACK_STORE_4(u, z0, z1, z2, z3) \ +{ \ + __m256i s0, s1, s2, s3; \ + s0 = _mm256_unpacklo_epi64(z0, z1); \ + s1 = _mm256_unpackhi_epi64(z0, z1); \ + s2 = _mm256_unpacklo_epi64(z2, z3); \ + s3 = _mm256_unpackhi_epi64(z2, z3); \ + V8_PERM_PAIR_STORE(u + 0, s0, s2) \ + V8_PERM_PAIR_STORE(u + 2, s1, s3) \ +} + +#define V8_UNPACK_STORE_0(src32, d0, d1) \ +{ \ + const __m256i v0 = LOAD_256_FROM_STRUCT ((src32) ); \ + const __m256i v1 = LOAD_256_FROM_STRUCT ((src32) + 8); \ + d0 = _mm256_unpacklo_epi32(v0, v1); \ + d1 = _mm256_unpackhi_epi32(v0, v1); \ +} + +#define V8_UNPACK_STATE(dest32, src32) \ +{ \ + __m256i t0, t1, t2, t3, t4, t5, t6, t7; \ + V8_UNPACK_STORE_0 ((src32) + 16 * 0, t0, t4) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 1, t1, t5) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 2, t2, t6) \ + V8_UNPACK_STORE_0 ((src32) + 16 * 3, t3, t7) \ + V8_UNPACK_STORE_4 ((__m256i *)(void *)(dest32) , t0, t1, t2, t3) \ + V8_UNPACK_STORE_4 ((__m256i *)(void *)(dest32) + 4, t4, t5, t6, t7) \ +} + + + +#define V8_LOAD_STATE_256_FROM_STRUCT(i) \ + v[i] = LOAD_256_FROM_STRUCT(s_items + (i) * 8); + +#if 0 || 0 && defined(MY_CPU_X86) +#define Z7_BLAKE2S_AVX2_FAST_USE_STRUCT +#endif + +#ifdef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT +// this branch doesn't use (iv) array +// so register pressure can be lower. +// it can be faster sometimes +#define V8_LOAD_STATE_256(i) V8_LOAD_STATE_256_FROM_STRUCT(i) +#define V8_UPDATE_STATE_256(i) \ +{ \ + STORE_256_TO_STRUCT(s_items + (i) * 8, XOR_256( \ + XOR_256(v[i], v[(i) + 8]), \ + LOAD_256_FROM_STRUCT(s_items + (i) * 8))); \ +} +#else +// it uses more variables (iv) registers +// it's better for gcc +// maybe that branch is better, if register pressure will be lower (avx512) +#define V8_LOAD_STATE_256(i) { iv[i] = v[i]; } +#define V8_UPDATE_STATE_256(i) { v[i] = XOR_256(XOR_256(v[i], v[i + 8]), iv[i]); } +#define V8_STORE_STATE_256(i) { STORE_256_TO_STRUCT(s_items + (i) * 8, v[i]); } +#endif + + +#if 0 + // use loading constants from memory + #define KK8(n) KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n), KIV(n) +MY_ALIGN(64) +static const UInt32 k_Blake2s_IV_WAY8[]= +{ + KK8(0), KK8(1), KK8(2), KK8(3), KK8(4), KK8(5), KK8(6), KK8(7) +}; + #define GET_256_IV_WAY8(i) LOAD_256(k_Blake2s_IV_WAY8 + 8 * (i)) +#else + // use constant generation: + #define GET_256_IV_WAY8(i) _mm256_set1_epi32((Int32)KIV(i)) +#endif + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Compress2_AVX2_Fast(UInt32 *s_items, const Byte *data, const Byte *end) +{ +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + __m256i v[16]; +#endif + + // PrintStates2(s_items, 8, 16); + +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + REP8_MACRO (V8_LOAD_STATE_256_FROM_STRUCT) +#endif + + do + { + __m256i w[16]; +#ifdef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + __m256i v[16]; +#else + __m256i iv[8]; +#endif + V8_LOAD_MSG(w, data) + { + // we use load/store ctr inside loop to reduce register pressure: +#if 1 || 1 && defined(MY_CPU_X86) + const __m256i ctr = _mm256_add_epi64( + LOAD_256_FROM_STRUCT(s_items + 64), + _mm256_set_epi32( + 0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE, + 0, 0, 0, Z7_BLAKE2S_BLOCK_SIZE)); + STORE_256_TO_STRUCT(s_items + 64, ctr); +#else + const UInt64 ctr64 = *(const UInt64 *)(const void *)(s_items + 64) + + Z7_BLAKE2S_BLOCK_SIZE; + const __m256i ctr = _mm256_set_epi64x(0, (Int64)ctr64, 0, (Int64)ctr64); + *(UInt64 *)(void *)(s_items + 64) = ctr64; +#endif + v[12] = XOR_256 (GET_256_IV_WAY8(4), _mm256_shuffle_epi32(ctr, _MM_SHUFFLE(0, 0, 0, 0))); + v[13] = XOR_256 (GET_256_IV_WAY8(5), _mm256_shuffle_epi32(ctr, _MM_SHUFFLE(1, 1, 1, 1))); + } + v[ 8] = GET_256_IV_WAY8(0); + v[ 9] = GET_256_IV_WAY8(1); + v[10] = GET_256_IV_WAY8(2); + v[11] = GET_256_IV_WAY8(3); + v[14] = GET_256_IV_WAY8(6); + v[15] = GET_256_IV_WAY8(7); + + REP8_MACRO (V8_LOAD_STATE_256) + ROUNDS_LOOP (V8_ROUND) + REP8_MACRO (V8_UPDATE_STATE_256) + data += SUPER_BLOCK_SIZE; + } + while (data != end); + +#ifndef Z7_BLAKE2S_AVX2_FAST_USE_STRUCT + REP8_MACRO (V8_STORE_STATE_256) +#endif +} + + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_Final_AVX2_Fast(UInt32 *states) +{ + const __m128i ctr = LOAD_128_FROM_STRUCT(states + 64); + // PrintStates2(states, 8, 16); + V8_UNPACK_STATE(states, states) + // PrintStates2(states, 8, 16); + { + unsigned k; + for (k = 0; k < 8; k++) + { + UInt32 *s = states + (size_t)k * 16; + STORE_128_TO_STRUCT (STATE_T(s), ctr); + } + } + // PrintStates2(states, 8, 16); + // printf("\nafter V8_UNPACK_STATE \n"); +} + +#endif // Z7_BLAKE2S_USE_AVX2_FAST +#endif // avx2 +#endif // vector + + +/* +#define Blake2s_Increment_Counter(s, inc) \ + { STATE_T(s)[0] += (inc); STATE_T(s)[1] += (STATE_T(s)[0] < (inc)); } +#define Blake2s_Increment_Counter_Small(s, inc) \ + { STATE_T(s)[0] += (inc); } +*/ + +#define Blake2s_Set_LastBlock(s) \ + { STATE_F(s)[0] = BLAKE2S_FINAL_FLAG; /* STATE_F(s)[1] = p->u.header.lastNode_f1; */ } + + +#if 0 || 1 && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL >= 1600 + // good for vs2022 + #define LOOP_8(mac) { unsigned kkk; for (kkk = 0; kkk < 8; kkk++) mac(kkk) } +#else + // good for Z7_BLAKE2S_UNROLL for GCC9 (arm*/x86*) and MSC_VER_1400-x64. + #define LOOP_8(mac) { REP8_MACRO(mac) } +#endif + + +static +Z7_FORCE_INLINE +// Z7_NO_INLINE +void +Z7_FASTCALL +Blake2s_Compress(UInt32 *s, const Byte *input) +{ + UInt32 m[16]; + UInt32 v[16]; + { + unsigned i; + for (i = 0; i < 16; i++) + m[i] = GetUi32(input + i * 4); + } + +#define INIT_v_FROM_s(i) v[i] = s[i]; + + LOOP_8(INIT_v_FROM_s) + + // Blake2s_Increment_Counter(s, Z7_BLAKE2S_BLOCK_SIZE) + { + const UInt32 t0 = STATE_T(s)[0] + Z7_BLAKE2S_BLOCK_SIZE; + const UInt32 t1 = STATE_T(s)[1] + (t0 < Z7_BLAKE2S_BLOCK_SIZE); + STATE_T(s)[0] = t0; + STATE_T(s)[1] = t1; + v[12] = t0 ^ KIV(4); + v[13] = t1 ^ KIV(5); + } + // v[12] = STATE_T(s)[0] ^ KIV(4); + // v[13] = STATE_T(s)[1] ^ KIV(5); + v[14] = STATE_F(s)[0] ^ KIV(6); + v[15] = STATE_F(s)[1] ^ KIV(7); + + v[ 8] = KIV(0); + v[ 9] = KIV(1); + v[10] = KIV(2); + v[11] = KIV(3); + // PrintStates2((const UInt32 *)v, 1, 16); + + #define ADD_SIGMA(a, index) V(a, 0) += *(const UInt32 *)GET_SIGMA_PTR(m, sigma[index]); + #define ADD32M(dest, src, a) V(a, dest) += V(a, src); + #define XOR32M(dest, src, a) V(a, dest) ^= V(a, src); + #define RTR32M(dest, shift, a) V(a, dest) = rotrFixed(V(a, dest), shift); + +// big interleaving can provides big performance gain, if scheduler queues are small. +#if 0 || 1 && defined(MY_CPU_X86) + // interleave-1: for small register number (x86-32bit) + #define G2(index, a, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD32M (0, 1, a) \ + XOR32M (3, 0, a) \ + RTR32M (3, x, a) \ + ADD32M (2, 3, a) \ + XOR32M (1, 2, a) \ + RTR32M (1, y, a) \ + + #define G(a) \ + G2(a * 2 , a, 16, 12) \ + G2(a * 2 + 1, a, 8, 7) \ + + #define R2 \ + G(0) \ + G(1) \ + G(2) \ + G(3) \ + G(4) \ + G(5) \ + G(6) \ + G(7) \ + +#elif 0 || 1 && defined(MY_CPU_X86_OR_AMD64) + // interleave-2: is good if the number of registers is not big (x86-64). + + #define REP2(mac, dest, src, a, b) \ + mac(dest, src, a) \ + mac(dest, src, b) + + #define G2(index, a, b, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD_SIGMA (b, (index) + 2 * 1) \ + REP2 (ADD32M, 0, 1, a, b) \ + REP2 (XOR32M, 3, 0, a, b) \ + REP2 (RTR32M, 3, x, a, b) \ + REP2 (ADD32M, 2, 3, a, b) \ + REP2 (XOR32M, 1, 2, a, b) \ + REP2 (RTR32M, 1, y, a, b) \ + + #define G(a, b) \ + G2(a * 2 , a, b, 16, 12) \ + G2(a * 2 + 1, a, b, 8, 7) \ + + #define R2 \ + G(0, 1) \ + G(2, 3) \ + G(4, 5) \ + G(6, 7) \ + +#else + // interleave-4: + // it has big register pressure for x86/x64. + // and MSVC compilers for x86/x64 are slow for this branch. + // but if we have big number of registers, this branch can be faster. + + #define REP4(mac, dest, src, a, b, c, d) \ + mac(dest, src, a) \ + mac(dest, src, b) \ + mac(dest, src, c) \ + mac(dest, src, d) + + #define G2(index, a, b, c, d, x, y) \ + ADD_SIGMA (a, (index) + 2 * 0) \ + ADD_SIGMA (b, (index) + 2 * 1) \ + ADD_SIGMA (c, (index) + 2 * 2) \ + ADD_SIGMA (d, (index) + 2 * 3) \ + REP4 (ADD32M, 0, 1, a, b, c, d) \ + REP4 (XOR32M, 3, 0, a, b, c, d) \ + REP4 (RTR32M, 3, x, a, b, c, d) \ + REP4 (ADD32M, 2, 3, a, b, c, d) \ + REP4 (XOR32M, 1, 2, a, b, c, d) \ + REP4 (RTR32M, 1, y, a, b, c, d) \ + + #define G(a, b, c, d) \ + G2(a * 2 , a, b, c, d, 16, 12) \ + G2(a * 2 + 1, a, b, c, d, 8, 7) \ + + #define R2 \ + G(0, 1, 2, 3) \ + G(4, 5, 6, 7) \ + +#endif + + #define R(r) { const Byte *sigma = k_Blake2s_Sigma_4[r]; R2 } + + // Z7_BLAKE2S_UNROLL gives 5-6 KB larger code, but faster: + // 20-40% faster for (x86/x64) VC2010+/GCC/CLANG. + // 30-60% faster for (arm64-arm32) GCC. + // 5-11% faster for (arm64) CLANG-MAC. + // so Z7_BLAKE2S_UNROLL is good optimization, if there is no vector branch. + // But if there is vectors branch (for x86*), this scalar code will be unused mostly. + // So we want smaller code (without unrolling) in that case (x86*). +#if 0 || 1 && !defined(Z7_BLAKE2S_USE_VECTORS) + #define Z7_BLAKE2S_UNROLL +#endif + +#ifdef Z7_BLAKE2S_UNROLL + ROUNDS_LOOP_UNROLLED (R) +#else + ROUNDS_LOOP (R) +#endif + + #undef G + #undef G2 + #undef R + #undef R2 + + // printf("\n v after: \n"); + // PrintStates2((const UInt32 *)v, 1, 16); +#define XOR_s_PAIR_v(i) s[i] ^= v[i] ^ v[i + 8]; + + LOOP_8(XOR_s_PAIR_v) + // printf("\n s after:\n"); + // PrintStates2((const UInt32 *)s, 1, 16); +} + + +static +Z7_NO_INLINE +void +Z7_FASTCALL +Blake2sp_Compress2(UInt32 *s_items, const Byte *data, const Byte *end) +{ + size_t pos = 0; + // PrintStates2(s_items, 8, 16); + do + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(s_items, pos); + Blake2s_Compress(s, data); + data += Z7_BLAKE2S_BLOCK_SIZE; + pos += Z7_BLAKE2S_BLOCK_SIZE; + pos &= SUPER_BLOCK_MASK; + } + while (data != end); +} + + +#ifdef Z7_BLAKE2S_USE_VECTORS + +static Z7_BLAKE2SP_FUNC_COMPRESS g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast = Blake2sp_Compress2; +static Z7_BLAKE2SP_FUNC_COMPRESS g_Z7_BLAKE2SP_FUNC_COMPRESS_Single = Blake2sp_Compress2; +static Z7_BLAKE2SP_FUNC_INIT g_Z7_BLAKE2SP_FUNC_INIT_Init; +static Z7_BLAKE2SP_FUNC_INIT g_Z7_BLAKE2SP_FUNC_INIT_Final; +static unsigned g_z7_Blake2sp_SupportedFlags; + + #define Z7_BLAKE2SP_Compress_Fast(p) (p)->u.header.func_Compress_Fast + #define Z7_BLAKE2SP_Compress_Single(p) (p)->u.header.func_Compress_Single +#else + #define Z7_BLAKE2SP_Compress_Fast(p) Blake2sp_Compress2 + #define Z7_BLAKE2SP_Compress_Single(p) Blake2sp_Compress2 +#endif // Z7_BLAKE2S_USE_VECTORS + + +#if 1 && defined(MY_CPU_LE) + #define GET_DIGEST(_s, _digest) \ + { memcpy(_digest, _s, Z7_BLAKE2S_DIGEST_SIZE); } +#else + #define GET_DIGEST(_s, _digest) \ + { unsigned _i; for (_i = 0; _i < 8; _i++) \ + { SetUi32((_digest) + 4 * _i, (_s)[_i]) } \ + } +#endif + + +/* ---------- BLAKE2s ---------- */ +/* +// we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() +typedef struct +{ + Byte digest_length; + Byte key_length; + Byte fanout; // = 1 : in sequential mode + Byte depth; // = 1 : in sequential mode + UInt32 leaf_length; + Byte node_offset[6]; // 0 for the first, leftmost, leaf, or in sequential mode + Byte node_depth; // 0 for the leaves, or in sequential mode + Byte inner_length; // [0, 32], 0 in sequential mode + Byte salt[BLAKE2S_SALTBYTES]; + Byte personal[BLAKE2S_PERSONALBYTES]; +} CBlake2sParam; +*/ + +#define k_Blake2sp_IV_0 \ + (KIV(0) ^ (Z7_BLAKE2S_DIGEST_SIZE | ((UInt32)Z7_BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24))) +#define k_Blake2sp_IV_3_FROM_NODE_DEPTH(node_depth) \ + (KIV(3) ^ ((UInt32)(node_depth) << 16) ^ ((UInt32)Z7_BLAKE2S_DIGEST_SIZE << 24)) + +Z7_FORCE_INLINE +static void Blake2sp_Init_Spec(UInt32 *s, unsigned node_offset, unsigned node_depth) +{ + s[0] = k_Blake2sp_IV_0; + s[1] = KIV(1); + s[2] = KIV(2) ^ (UInt32)node_offset; + s[3] = k_Blake2sp_IV_3_FROM_NODE_DEPTH(node_depth); + s[4] = KIV(4); + s[5] = KIV(5); + s[6] = KIV(6); + s[7] = KIV(7); + + STATE_T(s)[0] = 0; + STATE_T(s)[1] = 0; + STATE_F(s)[0] = 0; + STATE_F(s)[1] = 0; +} + + +#ifdef Z7_BLAKE2S_USE_V128_FAST + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_128BIT + BLAKE2S_ATTRIB_128BIT +#endif +void +Z7_FASTCALL +Blake2sp_InitState_V128_Fast(UInt32 *states) +{ +#define STORE_128_PAIR_INIT_STATES_2(i, t0, t1) \ + { STORE_128_TO_STRUCT(states + 0 + 4 * (i), (t0)); \ + STORE_128_TO_STRUCT(states + 32 + 4 * (i), (t1)); \ + } +#define STORE_128_PAIR_INIT_STATES_1(i, mac) \ + { const __m128i t = mac; \ + STORE_128_PAIR_INIT_STATES_2(i, t, t) \ + } +#define STORE_128_PAIR_INIT_STATES_IV(i) \ + STORE_128_PAIR_INIT_STATES_1(i, GET_128_IV_WAY4(i)) + + STORE_128_PAIR_INIT_STATES_1 (0, _mm_set1_epi32((Int32)k_Blake2sp_IV_0)) + STORE_128_PAIR_INIT_STATES_IV (1) + { + const __m128i t = GET_128_IV_WAY4(2); + STORE_128_PAIR_INIT_STATES_2 (2, + XOR_128(t, _mm_set_epi32(3, 2, 1, 0)), + XOR_128(t, _mm_set_epi32(7, 6, 5, 4))) + } + STORE_128_PAIR_INIT_STATES_1 (3, _mm_set1_epi32((Int32)k_Blake2sp_IV_3_FROM_NODE_DEPTH(0))) + STORE_128_PAIR_INIT_STATES_IV (4) + STORE_128_PAIR_INIT_STATES_IV (5) + STORE_128_PAIR_INIT_STATES_IV (6) + STORE_128_PAIR_INIT_STATES_IV (7) + STORE_128_PAIR_INIT_STATES_1 (16, _mm_set_epi32(0, 0, 0, 0)) + // printf("\n== exit Blake2sp_InitState_V128_Fast ctr=%d\n", states[64]); +} + +#endif // Z7_BLAKE2S_USE_V128_FAST + + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + +static +Z7_NO_INLINE +#ifdef BLAKE2S_ATTRIB_AVX2 + BLAKE2S_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +Blake2sp_InitState_AVX2_Fast(UInt32 *states) +{ +#define STORE_256_INIT_STATES(i, t) \ + STORE_256_TO_STRUCT(states + 8 * (i), t); +#define STORE_256_INIT_STATES_IV(i) \ + STORE_256_INIT_STATES(i, GET_256_IV_WAY8(i)) + + STORE_256_INIT_STATES (0, _mm256_set1_epi32((Int32)k_Blake2sp_IV_0)) + STORE_256_INIT_STATES_IV (1) + STORE_256_INIT_STATES (2, XOR_256( GET_256_IV_WAY8(2), + _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0))) + STORE_256_INIT_STATES (3, _mm256_set1_epi32((Int32)k_Blake2sp_IV_3_FROM_NODE_DEPTH(0))) + STORE_256_INIT_STATES_IV (4) + STORE_256_INIT_STATES_IV (5) + STORE_256_INIT_STATES_IV (6) + STORE_256_INIT_STATES_IV (7) + STORE_256_INIT_STATES (8, _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0)) + // printf("\n== exit Blake2sp_InitState_AVX2_Fast\n"); +} + +#endif // Z7_BLAKE2S_USE_AVX2_FAST + + + +Z7_NO_INLINE +void Blake2sp_InitState(CBlake2sp *p) +{ + size_t i; + // memset(p->states, 0, sizeof(p->states)); // for debug + p->u.header.cycPos = 0; +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + if (p->u.header.func_Init) + { + p->u.header.func_Init(p->states); + return; + } +#endif + for (i = 0; i < Z7_BLAKE2SP_PARALLEL_DEGREE; i++) + Blake2sp_Init_Spec(p->states + i * NSW, (unsigned)i, 0); +} + +void Blake2sp_Init(CBlake2sp *p) +{ +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + p->u.header.func_Compress_Fast = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast; +#else + NULL; +#endif + + p->u.header.func_Compress_Single = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_COMPRESS_Single; +#else + NULL; +#endif + + p->u.header.func_Init = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_INIT_Init; +#else + NULL; +#endif + + p->u.header.func_Final = +#ifdef Z7_BLAKE2S_USE_VECTORS + g_Z7_BLAKE2SP_FUNC_INIT_Final; +#else + NULL; +#endif +#endif + + Blake2sp_InitState(p); +} + + +void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size) +{ + size_t pos; + // printf("\nsize = 0x%6x, cycPos = %5u data = %p\n", (unsigned)size, (unsigned)p->u.header.cycPos, data); + if (size == 0) + return; + pos = p->u.header.cycPos; + // pos < SUPER_BLOCK_SIZE * 2 : is expected + // pos == SUPER_BLOCK_SIZE * 2 : is not expected, but is supported also + { + const size_t pos2 = pos & SUPER_BLOCK_MASK; + if (pos2) + { + const size_t rem = SUPER_BLOCK_SIZE - pos2; + if (rem > size) + { + p->u.header.cycPos = (unsigned)(pos + size); + // cycPos < SUPER_BLOCK_SIZE * 2 + memcpy((Byte *)(void *)p->buf32 + pos, data, size); + /* to simpilify the code here we don't try to process first superblock, + if (cycPos > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) */ + return; + } + // (rem <= size) + memcpy((Byte *)(void *)p->buf32 + pos, data, rem); + pos += rem; + data += rem; + size -= rem; + } + } + + // pos <= SUPER_BLOCK_SIZE * 2 + // pos % SUPER_BLOCK_SIZE == 0 + if (pos) + { + /* pos == SUPER_BLOCK_SIZE || + pos == SUPER_BLOCK_SIZE * 2 */ + size_t end = pos; + if (size > SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE + || (end -= SUPER_BLOCK_SIZE)) + { + Z7_BLAKE2SP_Compress_Fast(p)(p->states, + (const Byte *)(const void *)p->buf32, + (const Byte *)(const void *)p->buf32 + end); + if (pos -= end) + memcpy(p->buf32, (const Byte *)(const void *)p->buf32 + + SUPER_BLOCK_SIZE, SUPER_BLOCK_SIZE); + } + } + + // pos == 0 || (pos == SUPER_BLOCK_SIZE && size <= SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE) + if (size > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) + { + // pos == 0 + const Byte *end; + const size_t size2 = (size - (SUPER_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE + 1)) + & ~(size_t)SUPER_BLOCK_MASK; + size -= size2; + // size < SUPER_BLOCK_SIZE * 2 + end = data + size2; + Z7_BLAKE2SP_Compress_Fast(p)(p->states, data, end); + data = end; + } + + if (size != 0) + { + memcpy((Byte *)(void *)p->buf32 + pos, data, size); + pos += size; + } + p->u.header.cycPos = (unsigned)pos; + // cycPos < SUPER_BLOCK_SIZE * 2 +} + + +void Blake2sp_Final(CBlake2sp *p, Byte *digest) +{ + // UInt32 * const R_states = p->states; + // printf("\nBlake2sp_Final \n"); +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + if (p->u.header.func_Final) + p->u.header.func_Final(p->states); +#endif + // printf("\n=====\nBlake2sp_Final \n"); + // PrintStates(p->states, 32); + + // (p->u.header.cycPos == SUPER_BLOCK_SIZE) can be processed in any branch: + if (p->u.header.cycPos <= SUPER_BLOCK_SIZE) + { + unsigned pos; + memset((Byte *)(void *)p->buf32 + p->u.header.cycPos, + 0, SUPER_BLOCK_SIZE - p->u.header.cycPos); + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + for (pos = 0; pos < SUPER_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos); + Blake2s_Set_LastBlock(s) + if (pos + Z7_BLAKE2S_BLOCK_SIZE > p->u.header.cycPos) + { + UInt32 delta = Z7_BLAKE2S_BLOCK_SIZE; + if (pos < p->u.header.cycPos) + delta -= p->u.header.cycPos & (Z7_BLAKE2S_BLOCK_SIZE - 1); + // 0 < delta <= Z7_BLAKE2S_BLOCK_SIZE + { + const UInt32 v = STATE_T(s)[0]; + STATE_T(s)[1] -= v < delta; // (v < delta) is same condition here as (v == 0) + STATE_T(s)[0] = v - delta; + } + } + } + // PrintStates(p->states, 16); + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE); + // PrintStates(p->states, 16); + } + else + { + // (p->u.header.cycPos > SUPER_BLOCK_SIZE) + unsigned pos; + for (pos = 0; pos < SUPER_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos); + if (pos + SUPER_BLOCK_SIZE >= p->u.header.cycPos) + Blake2s_Set_LastBlock(s) + } + if (p->u.header.cycPos <= SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE) + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE); + + // if (p->u.header.cycPos > SUPER_BLOCK_SIZE * 2 - Z7_BLAKE2S_BLOCK_SIZE; + STATE_F(&p->states[(Z7_BLAKE2SP_PARALLEL_DEGREE - 1) * NSW])[1] = BLAKE2S_FINAL_FLAG; + + // if (p->u.header.cycPos != SUPER_BLOCK_SIZE) + { + pos = SUPER_BLOCK_SIZE; + for (;;) + { + UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, pos & SUPER_BLOCK_MASK); + Blake2s_Set_LastBlock(s) + pos += Z7_BLAKE2S_BLOCK_SIZE; + if (pos >= p->u.header.cycPos) + { + if (pos != p->u.header.cycPos) + { + const UInt32 delta = pos - p->u.header.cycPos; + const UInt32 v = STATE_T(s)[0]; + STATE_T(s)[1] -= v < delta; + STATE_T(s)[0] = v - delta; + memset((Byte *)(void *)p->buf32 + p->u.header.cycPos, 0, delta); + } + break; + } + } + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (Byte *)(void *)p->buf32 + SUPER_BLOCK_SIZE, + (Byte *)(void *)p->buf32 + pos); + } + } + + { + size_t pos; + for (pos = 0; pos < SUPER_BLOCK_SIZE / 2; pos += Z7_BLAKE2S_BLOCK_SIZE / 2) + { + const UInt32 * const s = GET_STATE_TABLE_PTR_FROM_BYTE_POS(p->states, (pos * 2)); + Byte *dest = (Byte *)(void *)p->buf32 + pos; + GET_DIGEST(s, dest) + } + } + Blake2sp_Init_Spec(p->states, 0, 1); + { + size_t pos; + for (pos = 0; pos < (Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2S_DIGEST_SIZE) + - Z7_BLAKE2S_BLOCK_SIZE; pos += Z7_BLAKE2S_BLOCK_SIZE) + { + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (const Byte *)(const void *)p->buf32 + pos, + (const Byte *)(const void *)p->buf32 + pos + Z7_BLAKE2S_BLOCK_SIZE); + } + } + // Blake2s_Final(p->states, 0, digest, p, (Byte *)(void *)p->buf32 + i); + Blake2s_Set_LastBlock(p->states) + STATE_F(p->states)[1] = BLAKE2S_FINAL_FLAG; + { + Z7_BLAKE2SP_Compress_Single(p)(p->states, + (const Byte *)(const void *)p->buf32 + Z7_BLAKE2SP_PARALLEL_DEGREE / 2 * Z7_BLAKE2S_BLOCK_SIZE - Z7_BLAKE2S_BLOCK_SIZE, + (const Byte *)(const void *)p->buf32 + Z7_BLAKE2SP_PARALLEL_DEGREE / 2 * Z7_BLAKE2S_BLOCK_SIZE); + } + GET_DIGEST(p->states, digest) + // printf("\n Blake2sp_Final 555 numDataInBufs = %5u\n", (unsigned)p->u.header.numDataInBufs); +} + + +BoolInt Blake2sp_SetFunction(CBlake2sp *p, unsigned algo) +{ + // printf("\n========== setfunction = %d ======== \n", algo); +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + Z7_BLAKE2SP_FUNC_COMPRESS func = NULL; + Z7_BLAKE2SP_FUNC_COMPRESS func_Single = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Final = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Init = NULL; +#else + UNUSED_VAR(p) +#endif + +#ifdef Z7_BLAKE2S_USE_VECTORS + + func = func_Single = Blake2sp_Compress2; + + if (algo != Z7_BLAKE2SP_ALGO_SCALAR) + { + // printf("\n========== setfunction NON-SCALER ======== \n"); + if (algo == Z7_BLAKE2SP_ALGO_DEFAULT) + { + func = g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast; + func_Single = g_Z7_BLAKE2SP_FUNC_COMPRESS_Single; + func_Init = g_Z7_BLAKE2SP_FUNC_INIT_Init; + func_Final = g_Z7_BLAKE2SP_FUNC_INIT_Final; + } + else + { + if ((g_z7_Blake2sp_SupportedFlags & (1u << algo)) == 0) + return False; + +#ifdef Z7_BLAKE2S_USE_AVX2 + + func_Single = +#if defined(Z7_BLAKE2S_USE_AVX2_WAY2) + Blake2sp_Compress2_AVX2_Way2; +#else + Z7_BLAKE2S_Compress2_V128; +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + if (algo == Z7_BLAKE2SP_ALGO_V256_FAST) + { + func = Blake2sp_Compress2_AVX2_Fast; + func_Final = Blake2sp_Final_AVX2_Fast; + func_Init = Blake2sp_InitState_AVX2_Fast; + } + else +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + if (algo == Z7_BLAKE2SP_ALGO_V256_WAY2) + func = Blake2sp_Compress2_AVX2_Way2; + else +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + if (algo == Z7_BLAKE2SP_ALGO_V256_WAY4) + { + func_Single = func = Blake2sp_Compress2_AVX2_Way4; + } + else +#endif +#endif // avx2 + { + if (algo == Z7_BLAKE2SP_ALGO_V128_FAST) + { + func = Blake2sp_Compress2_V128_Fast; + func_Final = Blake2sp_Final_V128_Fast; + func_Init = Blake2sp_InitState_V128_Fast; + func_Single = Z7_BLAKE2S_Compress2_V128; + } + else +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + if (algo == Z7_BLAKE2SP_ALGO_V128_WAY2) + func = func_Single = Blake2sp_Compress2_V128_Way2; + else +#endif + { + if (algo != Z7_BLAKE2SP_ALGO_V128_WAY1) + return False; + func = func_Single = Blake2sp_Compress2_V128_Way1; + } + } + } + } +#else // !VECTORS + if (algo > 1) // Z7_BLAKE2SP_ALGO_SCALAR + return False; +#endif // !VECTORS + +#ifdef Z7_BLAKE2SP_USE_FUNCTIONS + p->u.header.func_Compress_Fast = func; + p->u.header.func_Compress_Single = func_Single; + p->u.header.func_Final = func_Final; + p->u.header.func_Init = func_Init; +#endif + // printf("\n p->u.header.func_Compress = %p", p->u.header.func_Compress); + return True; +} + + +void z7_Black2sp_Prepare(void) +{ +#ifdef Z7_BLAKE2S_USE_VECTORS + unsigned flags = 0; // (1u << Z7_BLAKE2SP_ALGO_V128_SCALAR); + + Z7_BLAKE2SP_FUNC_COMPRESS func_Fast = Blake2sp_Compress2; + Z7_BLAKE2SP_FUNC_COMPRESS func_Single = Blake2sp_Compress2; + Z7_BLAKE2SP_FUNC_INIT func_Init = NULL; + Z7_BLAKE2SP_FUNC_INIT func_Final = NULL; + +#if defined(MY_CPU_X86_OR_AMD64) + #if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + // optional check + #if 0 || !(defined(__AVX512F__) && defined(__AVX512VL__)) + if (CPU_IsSupported_AVX512F_AVX512VL()) + #endif + #elif defined(Z7_BLAKE2S_USE_SSE41) + if (CPU_IsSupported_SSE41()) + #elif defined(Z7_BLAKE2S_USE_SSSE3) + if (CPU_IsSupported_SSSE3()) + #elif !defined(MY_CPU_AMD64) + if (CPU_IsSupported_SSE2()) + #endif +#endif + { + #if defined(Z7_BLAKE2S_USE_SSE41) + // printf("\n========== Blake2s SSE41 128-bit\n"); + #elif defined(Z7_BLAKE2S_USE_SSSE3) + // printf("\n========== Blake2s SSSE3 128-bit\n"); + #else + // printf("\n========== Blake2s SSE2 128-bit\n"); + #endif + // func_Fast = f_vector = Blake2sp_Compress2_V128_Way2; + // printf("\n========== Blake2sp_Compress2_V128_Way2\n"); + func_Fast = + func_Single = Z7_BLAKE2S_Compress2_V128; + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_WAY1); +#ifdef Z7_BLAKE2S_USE_V128_WAY2 + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_WAY2); +#endif +#ifdef Z7_BLAKE2S_USE_V128_FAST + flags |= (1u << Z7_BLAKE2SP_ALGO_V128_FAST); + func_Fast = Blake2sp_Compress2_V128_Fast; + func_Init = Blake2sp_InitState_V128_Fast; + func_Final = Blake2sp_Final_V128_Fast; +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2 +#if defined(MY_CPU_X86_OR_AMD64) + + #if defined(Z7_BLAKE2S_USE_AVX512_ALWAYS) + #if 0 + if (CPU_IsSupported_AVX512F_AVX512VL()) + #endif + #else + if (CPU_IsSupported_AVX2()) + #endif +#endif + { + // #pragma message ("=== Blake2s AVX2") + // printf("\n========== Blake2s AVX2\n"); + +#ifdef Z7_BLAKE2S_USE_AVX2_WAY2 + func_Single = Blake2sp_Compress2_AVX2_Way2; + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_WAY2); +#endif +#ifdef Z7_BLAKE2S_USE_AVX2_WAY4 + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_WAY4); +#endif + +#ifdef Z7_BLAKE2S_USE_AVX2_FAST + flags |= (1u << Z7_BLAKE2SP_ALGO_V256_FAST); + func_Fast = Blake2sp_Compress2_AVX2_Fast; + func_Init = Blake2sp_InitState_AVX2_Fast; + func_Final = Blake2sp_Final_AVX2_Fast; +#elif defined(Z7_BLAKE2S_USE_AVX2_WAY4) + func_Fast = Blake2sp_Compress2_AVX2_Way4; +#elif defined(Z7_BLAKE2S_USE_AVX2_WAY2) + func_Fast = Blake2sp_Compress2_AVX2_Way2; +#endif + } // avx2 +#endif // avx2 + } // sse* + g_Z7_BLAKE2SP_FUNC_COMPRESS_Fast = func_Fast; + g_Z7_BLAKE2SP_FUNC_COMPRESS_Single = func_Single; + g_Z7_BLAKE2SP_FUNC_INIT_Init = func_Init; + g_Z7_BLAKE2SP_FUNC_INIT_Final = func_Final; + g_z7_Blake2sp_SupportedFlags = flags; + // printf("\nflags=%x\n", flags); +#endif // vectors +} + +/* +#ifdef Z7_BLAKE2S_USE_VECTORS +void align_test2(CBlake2sp *sp); +void align_test2(CBlake2sp *sp) +{ + __m128i a = LOAD_128(sp->states); + D_XOR_128(a, LOAD_128(sp->states + 4)); + STORE_128(sp->states, a); +} +void align_test2(void); +void align_test2(void) +{ + CBlake2sp sp; + Blake2sp_Init(&sp); + Blake2sp_Update(&sp, NULL, 0); +} +#endif +*/ diff -Nru p7zip-rar-16.02/C/Bra.c p7zip-rar-16.02+really25.00+ds/C/Bra.c --- p7zip-rar-16.02/C/Bra.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bra.c 2024-01-20 18:00:00.000000000 +0000 @@ -1,135 +1,709 @@ -/* Bra.c -- Converters for RISC code -2010-04-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 8; - for (i = 0; i <= size; i += 4) - { - if (data[i + 3] == 0xEB) - { - UInt32 dest; - UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]); - src <<= 2; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 2; - data[i + 2] = (Byte)(dest >> 16); - data[i + 1] = (Byte)(dest >> 8); - data[i + 0] = (Byte)dest; - } - } - return i; -} - -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - ip += 4; - for (i = 0; i <= size; i += 2) - { - if ((data[i + 1] & 0xF8) == 0xF0 && - (data[i + 3] & 0xF8) == 0xF8) - { - UInt32 dest; - UInt32 src = - (((UInt32)data[i + 1] & 0x7) << 19) | - ((UInt32)data[i + 0] << 11) | - (((UInt32)data[i + 3] & 0x7) << 8) | - (data[i + 2]); - - src <<= 1; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - dest >>= 1; - - data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); - data[i + 0] = (Byte)(dest >> 11); - data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); - data[i + 2] = (Byte)dest; - i += 2; - } - } - return i; -} - -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) - { - UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3] & (~3)); - - UInt32 dest; - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] &= 0x3; - data[i + 3] |= dest; - } - } - return i; -} - -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - UInt32 i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || - (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) - { - UInt32 src = - ((UInt32)data[i + 0] << 24) | - ((UInt32)data[i + 1] << 16) | - ((UInt32)data[i + 2] << 8) | - ((UInt32)data[i + 3]); - UInt32 dest; - - src <<= 2; - if (encoding) - dest = ip + i + src; - else - dest = src - (ip + i); - dest >>= 2; - - dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; - - data[i + 0] = (Byte)(dest >> 24); - data[i + 1] = (Byte)(dest >> 16); - data[i + 2] = (Byte)(dest >> 8); - data[i + 3] = (Byte)dest; - } - } - return i; -} +/* Bra.c -- Branch converters for RISC code +2024-01-20 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bra.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV(name) z7_ ## name + +#define Z7_BRANCH_FUNC_MAIN(name) \ +static \ +Z7_FORCE_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *Z7_BRANCH_CONV(name)(Byte *p, SizeT size, UInt32 pc, int encoding) + +#define Z7_BRANCH_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc) \ + { return Z7_BRANCH_CONV(name)(data, size, pc, encoding); } \ + +#ifdef Z7_EXTRACT_ONLY +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) +#else +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_ENC_2, 1) +#endif + +#if defined(__clang__) +#define BR_EXTERNAL_FOR +#define BR_NEXT_ITERATION continue; +#else +#define BR_EXTERNAL_FOR for (;;) +#define BR_NEXT_ITERATION break; +#endif + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + // GCC is not good for __builtin_expect() here + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // #define Z7_unlikely [[unlikely]] + // #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_likely [[likely]] +#else + // #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM64) +{ + // Byte *p = data; + const Byte *lim; + const UInt32 flag = (UInt32)1 << (24 - 4); + const UInt32 mask = ((UInt32)1 << 24) - (flag << 1); + size &= ~(SizeT)3; + // if (size == 0) return p; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + BR_EXTERNAL_FOR + { + // Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (;;) + { + UInt32 v; + if Z7_UNLIKELY(p == lim) + return p; + v = GetUi32a(p); + p += 4; + if Z7_UNLIKELY(((v - 0x94000000) & 0xfc000000) == 0) + { + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x03ffffff; + v |= 0x94000000; + SetUi32a(p - 4, v) + BR_NEXT_ITERATION + } + // v = rotlFixed(v, 8); v += (flag << 8) - 0x90; if Z7_UNLIKELY((v & ((mask << 8) + 0x9f)) == 0) + v -= 0x90000000; if Z7_UNLIKELY((v & 0x9f000000) == 0) + { + UInt32 z, c; + // v = rotrFixed(v, 8); + v += flag; if Z7_UNLIKELY(v & mask) continue; + z = (v & 0xffffffe0) | (v >> 26); + c = (BR_PC_GET >> (12 - 3)) & ~(UInt32)7; + BR_CONVERT_VAL(z, c) + v &= 0x1f; + v |= 0x90000000; + v |= z << 26; + v |= 0x00ffffe0 & ((z & (((flag << 1) - 1))) - flag); + SetUi32a(p - 4, v) + } + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM64) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARM) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to next instruction */ + pc += 8 - 4; + + for (;;) + { + for (;;) + { + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + } + { + UInt32 v = GetUi32a(p - 4); + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x00ffffff; + v |= 0xeb000000; + SetUi32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARM) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_PPC) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + for (;;) + { + UInt32 v; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + // v = GetBe32a(p); + v = *(UInt32 *)(void *)p; + p += 4; + // if ((v & 0xfc000003) == 0x48000001) break; + // if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) break; + if Z7_UNLIKELY( + ((v - Z7_CONV_BE_TO_NATIVE_CONST32(0x48000001)) + & Z7_CONV_BE_TO_NATIVE_CONST32(0xfc000003)) == 0) break; + } + { + v = Z7_CONV_NATIVE_TO_BE_32(v); + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= 0x03ffffff; + v |= 0x48000000; + SetBe32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_PPC) + + +#ifdef Z7_CPU_FAST_ROTATE_SUPPORTED +#define BR_SPARC_USE_ROTATE +#endif + +Z7_BRANCH_FUNC_MAIN(BranchConv_SPARC) +{ + // Byte *p = data; + const Byte *lim; + const UInt32 flag = (UInt32)1 << 22; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + for (;;) + { + UInt32 v; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + /* // the code without GetBe32a(): + { const UInt32 v = GetUi16a(p) & 0xc0ff; p += 4; if (v == 0x40 || v == 0xc07f) break; } + */ + v = GetBe32a(p); + p += 4; + #ifdef BR_SPARC_USE_ROTATE + v = rotlFixed(v, 2); + v += (flag << 2) - 1; + if Z7_UNLIKELY((v & (3 - (flag << 3))) == 0) + #else + v += (UInt32)5 << 29; + v ^= (UInt32)7 << 29; + v += flag; + if Z7_UNLIKELY((v & (0 - (flag << 1))) == 0) + #endif + break; + } + { + // UInt32 v = GetBe32a(p - 4); + #ifndef BR_SPARC_USE_ROTATE + v <<= 2; + #endif + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= (flag << 3) - 1; + #ifdef BR_SPARC_USE_ROTATE + v -= (flag << 2) - 1; + v = rotrFixed(v, 2); + #else + v -= (flag << 2); + v >>= 2; + v |= (UInt32)1 << 30; + #endif + SetBe32a(p - 4, v) + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_SPARC) + + +Z7_BRANCH_FUNC_MAIN(BranchConv_ARMT) +{ + // Byte *p = data; + Byte *lim; + size &= ~(SizeT)1; + // if (size == 0) return p; + if (size <= 2) return p; + size -= 2; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to the +2 instructions from current instruction */ + // pc += 4 - 4; + // if (encoding) pc -= 0xf800 << 1; else pc += 0xf800 << 1; + // #define ARMT_TAIL_PROC { goto armt_tail; } + #define ARMT_TAIL_PROC { return p; } + + do + { + /* in MSVC 32-bit x86 compilers: + UInt32 version : it loads value from memory with movzx + Byte version : it loads value to 8-bit register (AL/CL) + movzx version is slightly faster in some cpus + */ + unsigned b1; + // Byte / unsigned + b1 = p[1]; + // optimized version to reduce one (p >= lim) check: + // unsigned a1 = p[1]; b1 = p[3]; p += 2; if Z7_LIKELY((b1 & (a1 ^ 8)) < 0xf8) + for (;;) + { + unsigned b3; // Byte / UInt32 + /* (Byte)(b3) normalization can use low byte computations in MSVC. + It gives smaller code, and no loss of speed in some compilers/cpus. + But new MSVC 32-bit x86 compilers use more slow load + from memory to low byte register in that case. + So we try to use full 32-bit computations for faster code. + */ + // if (p >= lim) { ARMT_TAIL_PROC } b3 = b1 + 8; b1 = p[3]; p += 2; if ((b3 & b1) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b3 = p[3]; p += 2; if Z7_UNLIKELY((b3 & (b1 ^ 8)) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b1 = p[3]; p += 2; if Z7_UNLIKELY((b1 & (b3 ^ 8)) >= 0xf8) break; + } + { + /* we can adjust pc for (0xf800) to rid of (& 0x7FF) operation. + But gcc/clang for arm64 can use bfi instruction for full code here */ + UInt32 v = + ((UInt32)GetUi16a(p - 2) << 11) | + ((UInt32)GetUi16a(p) & 0x7FF); + /* + UInt32 v = + ((UInt32)p[1 - 2] << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + */ + p += 2; + { + UInt32 c = BR_PC_GET >> 1; + BR_CONVERT_VAL(v, c) + } + SetUi16a(p - 4, (UInt16)(((v >> 11) & 0x7ff) | 0xf000)) + SetUi16a(p - 2, (UInt16)(v | 0xf800)) + /* + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xf0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xf8 | (v >> 8)); + */ + } + } + while (p < lim); + return p; + // armt_tail: + // if ((Byte)((lim[1] & 0xf8)) != 0xf0) { lim += 2; } return lim; + // return (Byte *)(lim + ((Byte)((lim[1] ^ 0xf0) & 0xf8) == 0 ? 0 : 2)); + // return (Byte *)(lim + (((lim[1] ^ ~0xfu) & ~7u) == 0 ? 0 : 2)); + // return (Byte *)(lim + 2 - (((((unsigned)lim[1] ^ 8) + 8) >> 7) & 2)); +} +Z7_BRANCH_FUNCS_IMP(BranchConv_ARMT) + + +// #define BR_IA64_NO_INLINE + +Z7_BRANCH_FUNC_MAIN(BranchConv_IA64) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)15; + lim = p + size; + pc -= 1 << 4; + pc >>= 4 - 1; + // pc -= 1 << 1; + + for (;;) + { + unsigned m; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + m = (unsigned)((UInt32)0x334b0000 >> (*p & 0x1e)); + p += 16; + pc += 1 << 1; + if (m &= 3) + break; + } + { + p += (ptrdiff_t)m * 5 - 20; // negative value is expected here. + do + { + const UInt32 t = + #if defined(MY_CPU_X86_OR_AMD64) + // we use 32-bit load here to reduce code size on x86: + GetUi32(p); + #else + GetUi16(p); + #endif + UInt32 z = GetUi32(p + 1) >> m; + p += 5; + if (((t >> m) & (0x70 << 1)) == 0 + && ((z - (0x5000000 << 1)) & (0xf000000 << 1)) == 0) + { + UInt32 v = (UInt32)((0x8fffff << 1) | 1) & z; + z ^= v; + #ifdef BR_IA64_NO_INLINE + v |= (v & ((UInt32)1 << (23 + 1))) >> 3; + { + UInt32 c = pc; + BR_CONVERT_VAL(v, c) + } + v &= (0x1fffff << 1) | 1; + #else + { + if (encoding) + { + // pc &= ~(0xc00000 << 1); // we just need to clear at least 2 bits + pc &= (0x1fffff << 1) | 1; + v += pc; + } + else + { + // pc |= 0xc00000 << 1; // we need to set at least 2 bits + pc |= ~(UInt32)((0x1fffff << 1) | 1); + v -= pc; + } + } + v &= ~(UInt32)(0x600000 << 1); + #endif + v += (0x700000 << 1); + v &= (0x8fffff << 1) | 1; + z |= v; + z <<= m; + SetUi32(p + 1 - 5, z) + } + m++; + } + while (m &= 3); // while (m < 4); + } + } +} +Z7_BRANCH_FUNCS_IMP(BranchConv_IA64) + + +#define BR_CONVERT_VAL_ENC(v) v += BR_PC_GET; +#define BR_CONVERT_VAL_DEC(v) v -= BR_PC_GET; + +#if 1 && defined(MY_CPU_LE_UNALIGN) + #define RISCV_USE_UNALIGNED_LOAD +#endif + +#ifdef RISCV_USE_UNALIGNED_LOAD + #define RISCV_GET_UI32(p) GetUi32(p) + #define RISCV_SET_UI32(p, v) { SetUi32(p, v) } +#else + #define RISCV_GET_UI32(p) \ + ((UInt32)GetUi16a(p) + \ + ((UInt32)GetUi16a((p) + 2) << 16)) + #define RISCV_SET_UI32(p, v) { \ + SetUi16a(p, (UInt16)(v)) \ + SetUi16a((p) + 2, (UInt16)(v >> 16)) } +#endif + +#if 1 && defined(MY_CPU_LE) + #define RISCV_USE_16BIT_LOAD +#endif + +#ifdef RISCV_USE_16BIT_LOAD + #define RISCV_LOAD_VAL(p) GetUi16a(p) +#else + #define RISCV_LOAD_VAL(p) (*(p)) +#endif + +#define RISCV_INSTR_SIZE 2 +#define RISCV_STEP_1 (4 + RISCV_INSTR_SIZE) +#define RISCV_STEP_2 4 +#define RISCV_REG_VAL (2 << 7) +#define RISCV_CMD_VAL 3 +#if 1 + // for code size optimization: + #define RISCV_DELTA_7F 0x7f +#else + #define RISCV_DELTA_7F 0 +#endif + +#define RISCV_CHECK_1(v, b) \ + (((((b) - RISCV_CMD_VAL) ^ ((v) << 8)) & (0xf8000 + RISCV_CMD_VAL)) == 0) + +#if 1 + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL | 8)) \ + << 18) \ + < ((r) & 0x1d)) +#else + // this branch gives larger code, because + // compilers generate larger code for big constants. + #define RISCV_CHECK_2(v, r) \ + ((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + & ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \ + < ((r) & 0x1d)) +#endif + + +#define RISCV_SCAN_LOOP \ + Byte *lim; \ + size &= ~(SizeT)(RISCV_INSTR_SIZE - 1); \ + if (size <= 6) return p; \ + size -= 6; \ + lim = p + size; \ + BR_PC_INIT \ + for (;;) \ + { \ + UInt32 a, v; \ + /* Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE */ \ + for (;;) \ + { \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + a = (RISCV_LOAD_VAL(p) ^ 0x10u) + 1; \ + if ((a & 0x77) == 0) break; \ + a = (RISCV_LOAD_VAL(p + RISCV_INSTR_SIZE) ^ 0x10u) + 1; \ + p += RISCV_INSTR_SIZE * 2; \ + if ((a & 0x77) == 0) \ + { \ + p -= RISCV_INSTR_SIZE; \ + if Z7_UNLIKELY(p >= lim) { return p; } \ + break; \ + } \ + } +// (xx6f ^ 10) + 1 = xx7f + 1 = xx80 : JAL +// (xxef ^ 10) + 1 = xxff + 1 = xx00 + 100 : JAL +// (xx17 ^ 10) + 1 = xx07 + 1 = xx08 : AUIPC +// (xx97 ^ 10) + 1 = xx87 + 1 = xx88 : AUIPC + +Byte * Z7_BRANCH_CONV_ENC(RISCV)(Byte *p, SizeT size, UInt32 pc) +{ + RISCV_SCAN_LOOP + v = a; + a = RISCV_GET_UI32(p); +#ifndef RISCV_USE_16BIT_LOAD + v += (UInt32)p[1] << 8; +#endif + + if ((v & 8) == 0) // JAL + { + if ((v - (0x100 /* - RISCV_DELTA_7F */)) & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + v = ((a & 1u << 31) >> 11) + | ((a & 0x3ff << 21) >> 20) + | ((a & 1 << 20) >> 9) + | (a & 0xff << 12); + BR_CONVERT_VAL_ENC(v) + // ((v & 1) == 0) + // v: bits [1 : 20] contain offset bits +#if 0 && defined(RISCV_USE_UNALIGNED_LOAD) + a &= 0xfff; + a |= ((UInt32)(v << 23)) + | ((UInt32)(v << 7) & ((UInt32)0xff << 16)) + | ((UInt32)(v >> 5) & ((UInt32)0xf0 << 8)); + RISCV_SET_UI32(p, a) +#else // aligned +#if 0 + SetUi16a(p, (UInt16)(((v >> 5) & 0xf000) | (a & 0xfff))) +#else + p[1] = (Byte)(((v >> 13) & 0xf0) | ((a >> 8) & 0xf)); +#endif + +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v <<= 15; + v = Z7_BSWAP32(v); + SetUi16a(p + 2, (UInt16)v) +#else + p[2] = (Byte)(v >> 9); + p[3] = (Byte)(v >> 1); +#endif +#endif // aligned + } + p += 4; + continue; + } // JAL + + { + // AUIPC + if (v & 0xe80) // (not x0) and (not x2) + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (RISCV_CHECK_1(v, b)) + { + { + const UInt32 temp = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, temp) + } + a &= 0xfffff000; + { +#if 1 + const int t = -1 >> 1; + if (t != -1) + a += (b >> 20) - ((b >> 19) & 0x1000); // arithmetic right shift emulation + else +#endif + a += (UInt32)((Int32)b >> 20); // arithmetic right shift (sign-extension). + } + BR_CONVERT_VAL_ENC(a) +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + a = Z7_BSWAP32(a); + RISCV_SET_UI32(p + 4, a) +#else + SetBe32(p + 4, a) +#endif + p += 8; + } + else + p += RISCV_STEP_1; + } + else + { + UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + v = RISCV_GET_UI32(p + 4); + r = (r << 7) + 0x17 + (v & 0xfffff000); + a = (a >> 12) | (v << 20); + RISCV_SET_UI32(p, r) + RISCV_SET_UI32(p + 4, a) + p += 8; + } + else + p += RISCV_STEP_2; + } + } + } // for +} + + +Byte * Z7_BRANCH_CONV_DEC(RISCV)(Byte *p, SizeT size, UInt32 pc) +{ + RISCV_SCAN_LOOP +#ifdef RISCV_USE_16BIT_LOAD + if ((a & 8) == 0) + { +#else + v = a; + a += (UInt32)p[1] << 8; + if ((v & 8) == 0) + { +#endif + // JAL + a -= 0x100 - RISCV_DELTA_7F; + if (a & 0xd80) + { + p += RISCV_INSTR_SIZE; + continue; + } + { + const UInt32 a_old = (a + (0xef - RISCV_DELTA_7F)) & 0xfff; +#if 0 // unaligned + a = GetUi32(p); + v = (UInt32)(a >> 23) & ((UInt32)0xff << 1) + | (UInt32)(a >> 7) & ((UInt32)0xff << 9) +#elif 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + v = GetUi16a(p + 2); + v = Z7_BSWAP32(v) >> 15 +#else + v = (UInt32)p[3] << 1 + | (UInt32)p[2] << 9 +#endif + | (UInt32)((a & 0xf000) << 5); + BR_CONVERT_VAL_DEC(v) + a = a_old + | (v << 11 & 1u << 31) + | (v << 20 & 0x3ff << 21) + | (v << 9 & 1 << 20) + | (v & 0xff << 12); + RISCV_SET_UI32(p, a) + } + p += 4; + continue; + } // JAL + + { + // AUIPC + v = a; +#if 1 && defined(RISCV_USE_UNALIGNED_LOAD) + a = GetUi32(p); +#else + a |= (UInt32)GetUi16a(p + 2) << 16; +#endif + if ((v & 0xe80) == 0) // x0/x2 + { + const UInt32 r = a >> 27; + if (RISCV_CHECK_2(v, r)) + { + UInt32 b; +#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE) + b = RISCV_GET_UI32(p + 4); + b = Z7_BSWAP32(b); +#else + b = GetBe32(p + 4); +#endif + v = a >> 12; + BR_CONVERT_VAL_DEC(b) + a = (r << 7) + 0x17; + a += (b + 0x800) & 0xfffff000; + v |= b << 20; + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + else + p += RISCV_STEP_2; + } + else + { + const UInt32 b = RISCV_GET_UI32(p + 4); + if (!RISCV_CHECK_1(v, b)) + p += RISCV_STEP_1; + else + { + v = (a & 0xfffff000) | (b >> 20); + a = (b << 12) | (0x17 + RISCV_REG_VAL); + RISCV_SET_UI32(p, a) + RISCV_SET_UI32(p + 4, v) + p += 8; + } + } + } + } // for +} diff -Nru p7zip-rar-16.02/C/Bra.h p7zip-rar-16.02+really25.00+ds/C/Bra.h --- p7zip-rar-16.02/C/Bra.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bra.h 2024-01-20 17:00:00.000000000 +0000 @@ -1,64 +1,105 @@ -/* Bra.h -- Branch converters for executables -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __BRA_H -#define __BRA_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -These functions convert relative addresses to absolute addresses -in CALL instructions to increase the compression ratio. - - In: - data - data buffer - size - size of data - ip - current virtual Instruction Pinter (IP) value - state - state variable for x86 converter - encoding - 0 (for decoding), 1 (for encoding) - - Out: - state - state variable for x86 converter - - Returns: - The number of processed bytes. If you call these functions with multiple calls, - you must start next call with first byte after block of processed bytes. - - Type Endian Alignment LookAhead - - x86 little 1 4 - ARMT little 2 2 - ARM little 4 0 - PPC big 4 0 - SPARC big 4 0 - IA64 little 16 0 - - size must be >= Alignment + LookAhead, if it's not last block. - If (size < Alignment + LookAhead), converter returns 0. - - Example: - - UInt32 ip = 0; - for () - { - ; size must be >= Alignment + LookAhead, if it's not last block - SizeT processed = Convert(data, size, ip, 1); - data += processed; - size -= processed; - ip += processed; - } -*/ - -#define x86_Convert_Init(state) { state = 0; } -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); - -EXTERN_C_END - -#endif +/* Bra.h -- Branch converters for executables +2024-01-20 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_BRA_H +#define ZIP7_INC_BRA_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* #define PPC BAD_PPC_11 // for debug */ + +#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec +#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc +#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name) +#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec +#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc + +#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc) +#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state) + +typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv)); +typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt)); + +#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0 +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86)); +Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86)); + +#define Z7_BRANCH_FUNCS_DECL(name) \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \ +Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name)); + +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARM) +Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT) +Z7_BRANCH_FUNCS_DECL (BranchConv_PPC) +Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC) +Z7_BRANCH_FUNCS_DECL (BranchConv_IA64) +Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV) + +/* +These functions convert data that contain CPU instructions. +Each such function converts relative addresses to absolute addresses in some +branch instructions: CALL (in all converters) and JUMP (X86 converter only). +Such conversion allows to increase compression ratio, if we compress that data. + +There are 2 types of converters: + Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc); + Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state); +Each Converter supports 2 versions: one for encoding +and one for decoding (_Enc/_Dec postfixes in function name). + +In params: + data : data buffer + size : size of data + pc : current virtual Program Counter (Instruction Pointer) value +In/Out param: + state : pointer to state variable (for X86 converter only) + +Return: + The pointer to position in (data) buffer after last byte that was processed. + If the caller calls converter again, it must call it starting with that position. + But the caller is allowed to move data in buffer. So pointer to + current processed position also will be changed for next call. + Also the caller must increase internal (pc) value for next call. + +Each converter has some characteristics: Endian, Alignment, LookAhead. + Type Endian Alignment LookAhead + + X86 little 1 4 + ARMT little 2 2 + RISCV little 2 6 + ARM little 4 0 + ARM64 little 4 0 + PPC big 4 0 + SPARC big 4 0 + IA64 little 16 0 + + (data) must be aligned for (Alignment). + processed size can be calculated as: + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0) + it means that converter needs more data for processing. + If (size < Alignment + LookAhead) + then (processed == 0) is allowed. + +Example code for conversion in loop: + UInt32 pc = 0; + size = 0; + for (;;) + { + size += Load_more_input_data(data + size); + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0 && no_more_input_data_after_size) + break; // we stop convert loop + data += processed; + size -= processed; + pc += processed; + } +*/ + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Bra86.c p7zip-rar-16.02+really25.00+ds/C/Bra86.c --- p7zip-rar-16.02/C/Bra86.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Bra86.c 2023-04-02 11:00:00.000000000 +0000 @@ -1,82 +1,187 @@ -/* Bra86.c -- Converter for x86 code (BCJ) -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) - -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) -{ - SizeT pos = 0; - UInt32 mask = *state & 7; - if (size < 5) - return 0; - size -= 4; - ip += 5; - - for (;;) - { - Byte *p = data + pos; - const Byte *limit = data + size; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - - { - SizeT d = (SizeT)(p - data - pos); - pos = (SizeT)(p - data); - if (p >= limit) - { - *state = (d > 2 ? 0 : mask >> (unsigned)d); - return pos; - } - if (d > 2) - mask = 0; - else - { - mask >>= (unsigned)d; - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) - { - mask = (mask >> 1) | 4; - pos++; - continue; - } - } - } - - if (Test86MSByte(p[4])) - { - UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 cur = ip + (UInt32)pos; - pos += 5; - if (encoding) - v += cur; - else - v -= cur; - if (mask != 0) - { - unsigned sh = (mask & 6) << 2; - if (Test86MSByte((Byte)(v >> sh))) - { - v ^= (((UInt32)0x100 << sh) - 1); - if (encoding) - v += cur; - else - v -= cur; - } - mask = 0; - } - p[1] = (Byte)v; - p[2] = (Byte)(v >> 8); - p[3] = (Byte)(v >> 16); - p[4] = (Byte)(0 - ((v >> 24) & 1)); - } - else - { - mask = (mask >> 1) | 4; - pos++; - } - } -} +/* Bra86.c -- Branch converter for X86 code (BCJ) +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Bra.h" +#include "CpuArch.h" + + +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; // (MY_uintptr_t) +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV_ST(name) z7_BranchConvSt_ ## name + +#define BR86_NEED_CONV_FOR_MS_BYTE(b) ((((b) + 1) & 0xfe) == 0) + +#ifdef MY_CPU_LE_UNALIGN + #define BR86_PREPARE_BCJ_SCAN const UInt32 v = GetUi32(p) ^ 0xe8e8e8e8; + #define BR86_IS_BCJ_BYTE(n) ((v & ((UInt32)0xfe << (n) * 8)) == 0) +#else + #define BR86_PREPARE_BCJ_SCAN + // bad for MSVC X86 (partial write to byte reg): + #define BR86_IS_BCJ_BYTE(n) ((p[n - 4] & 0xfe) == 0xe8) + // bad for old MSVC (partial write to byte reg): + // #define BR86_IS_BCJ_BYTE(n) (((*p ^ 0xe8) & 0xfe) == 0) +#endif + +static +Z7_FORCE_INLINE +Z7_ATTRIB_NO_VECTOR +Byte *Z7_BRANCH_CONV_ST(X86)(Byte *p, SizeT size, UInt32 pc, UInt32 *state, int encoding) +{ + if (size < 5) + return p; + { + // Byte *p = data; + const Byte *lim = p + size - 4; + unsigned mask = (unsigned)*state; // & 7; +#ifdef BR_CONV_USE_OPT_PC_PTR + /* if BR_CONV_USE_OPT_PC_PTR is defined: we need to adjust (pc) for (+4), + because call/jump offset is relative to the next instruction. + if BR_CONV_USE_OPT_PC_PTR is not defined : we don't need to adjust (pc) for (+4), + because BR_PC_GET uses (pc - (lim - p)), and lim was adjusted for (-4) before. + */ + pc += 4; +#endif + BR_PC_INIT + goto start; + + for (;; mask |= 4) + { + // cont: mask |= 4; + start: + if (p >= lim) + goto fin; + { + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto m0; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(1)) { goto m1; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(2)) { goto m2; } mask = 0; + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } + } + goto main_loop; + + m0: p--; + m1: p--; + m2: p--; + if (mask == 0) + goto a3; + if (p > lim) + goto fin_p; + + // if (((0x17u >> mask) & 1) == 0) + if (mask > 4 || mask == 3) + { + mask >>= 1; + continue; // goto cont; + } + mask >>= 1; + if (BR86_NEED_CONV_FOR_MS_BYTE(p[mask])) + continue; // goto cont; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + { + mask <<= 3; + if (BR86_NEED_CONV_FOR_MS_BYTE(v >> mask)) + { + v ^= (((UInt32)0x100 << mask) - 1); + #ifdef MY_CPU_X86 + // for X86 : we can recalculate (c) to reduce register pressure + c = BR_PC_GET; + #endif + BR_CONVERT_VAL(v, c) + } + mask = 0; + } + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; + } + + main_loop: + if (p >= lim) + goto fin; + for (;;) + { + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto a0; } + if (BR86_IS_BCJ_BYTE(1)) { goto a1; } + if (BR86_IS_BCJ_BYTE(2)) { goto a2; } + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } + if (p >= lim) + goto fin; + } + + a0: p--; + a1: p--; + a2: p--; + a3: + if (p > lim) + goto fin_p; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; + } + } + +fin_p: + p--; +fin: + // the following processing for tail is optional and can be commented + /* + lim += 4; + for (; p < lim; p++, mask >>= 1) + if ((*p & 0xfe) == 0xe8) + break; + */ + *state = (UInt32)mask; + return p; + } +} + + +#define Z7_BRANCH_CONV_ST_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc, UInt32 *state) \ + { return Z7_BRANCH_CONV_ST(name)(data, size, pc, state, encoding); } + +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_DEC, 0) +#ifndef Z7_EXTRACT_ONLY +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_ENC, 1) +#endif diff -Nru p7zip-rar-16.02/C/BraIA64.c p7zip-rar-16.02+really25.00+ds/C/BraIA64.c --- p7zip-rar-16.02/C/BraIA64.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/BraIA64.c 2023-02-20 10:00:00.000000000 +0000 @@ -1,69 +1,14 @@ -/* BraIA64.c -- Converter for IA-64 code -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Bra.h" - -static const Byte kBranchTable[32] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 -}; - -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 16) - return 0; - size -= 16; - for (i = 0; i <= size; i += 16) - { - UInt32 instrTemplate = data[i] & 0x1F; - UInt32 mask = kBranchTable[instrTemplate]; - UInt32 bitPos = 5; - int slot; - for (slot = 0; slot < 3; slot++, bitPos += 41) - { - UInt32 bytePos, bitRes; - UInt64 instruction, instNorm; - int j; - if (((mask >> slot) & 1) == 0) - continue; - bytePos = (bitPos >> 3); - bitRes = bitPos & 0x7; - instruction = 0; - for (j = 0; j < 6; j++) - instruction += (UInt64)data[i + j + bytePos] << (8 * j); - - instNorm = instruction >> bitRes; - if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0) - { - UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); - UInt32 dest; - src |= ((UInt32)(instNorm >> 36) & 1) << 20; - - src <<= 4; - - if (encoding) - dest = ip + (UInt32)i + src; - else - dest = src - (ip + (UInt32)i); - - dest >>= 4; - - instNorm &= ~((UInt64)(0x8FFFFF) << 13); - instNorm |= ((UInt64)(dest & 0xFFFFF) << 13); - instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20)); - - instruction &= (1 << bitRes) - 1; - instruction |= (instNorm << bitRes); - for (j = 0; j < 6; j++) - data[i + j + bytePos] = (Byte)(instruction >> (8 * j)); - } - } - } - return i; -} +/* BraIA64.c -- Converter for IA-64 code +2023-02-20 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// the code was moved to Bra.c + +#ifdef _MSC_VER +#pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#endif + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wempty-translation-unit" +#endif diff -Nru p7zip-rar-16.02/C/BwtSort.c p7zip-rar-16.02+really25.00+ds/C/BwtSort.c --- p7zip-rar-16.02/C/BwtSort.c 2015-11-20 20:40:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/BwtSort.c 2025-01-13 13:00:00.000000000 +0000 @@ -1,515 +1,628 @@ -/* BwtSort.c -- BWT block sorting -2013-11-12 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "BwtSort.h" -#include "Sort.h" - -/* #define BLOCK_SORT_USE_HEAP_SORT */ - -#define NO_INLINE MY_FAST_CALL - -/* Don't change it !!! */ -#define kNumHashBytes 2 -#define kNumHashValues (1 << (kNumHashBytes * 8)) - -/* kNumRefBitsMax must be < (kNumHashBytes * 8) = 16 */ -#define kNumRefBitsMax 12 - -#define BS_TEMP_SIZE kNumHashValues - -#ifdef BLOCK_SORT_EXTERNAL_FLAGS - -/* 32 Flags in UInt32 word */ -#define kNumFlagsBits 5 -#define kNumFlagsInWord (1 << kNumFlagsBits) -#define kFlagsMask (kNumFlagsInWord - 1) -#define kAllFlags 0xFFFFFFFF - -#else - -#define kNumBitsMax 20 -#define kIndexMask ((1 << kNumBitsMax) - 1) -#define kNumExtraBits (32 - kNumBitsMax) -#define kNumExtra0Bits (kNumExtraBits - 2) -#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) - -#define SetFinishedGroupSize(p, size) \ - { *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ - if ((size) > (1 << kNumExtra0Bits)) { \ - *(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \ - -static void SetGroupSize(UInt32 *p, UInt32 size) -{ - if (--size == 0) - return; - *p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax); - if (size >= (1 << kNumExtra0Bits)) - { - *p |= 0x40000000; - p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax); - } -} - -#endif - -/* -SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks - "range" is not real range. It's only for optimization. -returns: 1 - if there are groups, 0 - no more groups -*/ - -UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices - #ifndef BLOCK_SORT_USE_HEAP_SORT - , UInt32 left, UInt32 range - #endif - ) -{ - UInt32 *ind2 = Indices + groupOffset; - UInt32 *Groups; - if (groupSize <= 1) - { - /* - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetFinishedGroupSize(ind2, 1); - #endif - */ - return 0; - } - Groups = Indices + BlockSize + BS_TEMP_SIZE; - if (groupSize <= ((UInt32)1 << NumRefBits) - #ifndef BLOCK_SORT_USE_HEAP_SORT - && groupSize <= range - #endif - ) - { - UInt32 *temp = Indices + BlockSize; - UInt32 j; - UInt32 mask, thereAreGroups, group, cg; - { - UInt32 gPrev; - UInt32 gRes = 0; - { - UInt32 sp = ind2[0] + NumSortedBytes; - if (sp >= BlockSize) sp -= BlockSize; - gPrev = Groups[sp]; - temp[0] = (gPrev << NumRefBits); - } - - for (j = 1; j < groupSize; j++) - { - UInt32 sp = ind2[j] + NumSortedBytes; - UInt32 g; - if (sp >= BlockSize) sp -= BlockSize; - g = Groups[sp]; - temp[j] = (g << NumRefBits) | j; - gRes |= (gPrev ^ g); - } - if (gRes == 0) - { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetGroupSize(ind2, groupSize); - #endif - return 1; - } - } - - HeapSort(temp, groupSize); - mask = ((1 << NumRefBits) - 1); - thereAreGroups = 0; - - group = groupOffset; - cg = (temp[0] >> NumRefBits); - temp[0] = ind2[temp[0] & mask]; - - { - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 *Flags = Groups + BlockSize; - #else - UInt32 prevGroupStart = 0; - #endif - - for (j = 1; j < groupSize; j++) - { - UInt32 val = temp[j]; - UInt32 cgCur = (val >> NumRefBits); - - if (cgCur != cg) - { - cg = cgCur; - group = groupOffset + j; - - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - { - UInt32 t = group - 1; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); - } - #else - SetGroupSize(temp + prevGroupStart, j - prevGroupStart); - prevGroupStart = j; - #endif - } - else - thereAreGroups = 1; - { - UInt32 ind = ind2[val & mask]; - temp[j] = ind; - Groups[ind] = group; - } - } - - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetGroupSize(temp + prevGroupStart, j - prevGroupStart); - #endif - } - - for (j = 0; j < groupSize; j++) - ind2[j] = temp[j]; - return thereAreGroups; - } - - /* Check that all strings are in one group (cannot sort) */ - { - UInt32 group, j; - UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - group = Groups[sp]; - for (j = 1; j < groupSize; j++) - { - sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - if (Groups[sp] != group) - break; - } - if (j == groupSize) - { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetGroupSize(ind2, groupSize); - #endif - return 1; - } - } - - #ifndef BLOCK_SORT_USE_HEAP_SORT - { - /* ---------- Range Sort ---------- */ - UInt32 i; - UInt32 mid; - for (;;) - { - UInt32 j; - if (range <= 1) - { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetGroupSize(ind2, groupSize); - #endif - return 1; - } - mid = left + ((range + 1) >> 1); - j = groupSize; - i = 0; - do - { - UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - if (Groups[sp] >= mid) - { - for (j--; j > i; j--) - { - sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - if (Groups[sp] < mid) - { - UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp; - break; - } - } - if (i >= j) - break; - } - } - while (++i < j); - if (i == 0) - { - range = range - (mid - left); - left = mid; - } - else if (i == groupSize) - range = (mid - left); - else - break; - } - - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - { - UInt32 t = (groupOffset + i - 1); - UInt32 *Flags = Groups + BlockSize; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); - } - #endif - - { - UInt32 j; - for (j = i; j < groupSize; j++) - Groups[ind2[j]] = groupOffset + i; - } - - { - UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); - return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); - } - - } - - #else - - /* ---------- Heap Sort ---------- */ - - { - UInt32 j; - for (j = 0; j < groupSize; j++) - { - UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; - ind2[j] = sp; - } - - HeapSortRef(ind2, Groups, groupSize); - - /* Write Flags */ - { - UInt32 sp = ind2[0]; - UInt32 group = Groups[sp]; - - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 *Flags = Groups + BlockSize; - #else - UInt32 prevGroupStart = 0; - #endif - - for (j = 1; j < groupSize; j++) - { - sp = ind2[j]; - if (Groups[sp] != group) - { - group = Groups[sp]; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - { - UInt32 t = groupOffset + j - 1; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); - } - #else - SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); - prevGroupStart = j; - #endif - } - } - - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); - #endif - } - { - /* Write new Groups values and Check that there are groups */ - UInt32 thereAreGroups = 0; - for (j = 0; j < groupSize; j++) - { - UInt32 group = groupOffset + j; - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); - if ((ind2[j] & 0x40000000) != 0) - subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits); - subGroupSize++; - for (;;) - { - UInt32 original = ind2[j]; - UInt32 sp = original & kIndexMask; - if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; - ind2[j] = sp | (original & ~kIndexMask); - Groups[sp] = group; - if (--subGroupSize == 0) - break; - j++; - thereAreGroups = 1; - } - #else - UInt32 *Flags = Groups + BlockSize; - for (;;) - { - UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes; - ind2[j] = sp; - Groups[sp] = group; - if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) - break; - j++; - thereAreGroups = 1; - } - #endif - } - return thereAreGroups; - } - } - #endif -} - -/* conditions: blockSize > 0 */ -UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize) -{ - UInt32 *counters = Indices + blockSize; - UInt32 i; - UInt32 *Groups; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 *Flags; - #endif - - /* Radix-Sort for 2 bytes */ - for (i = 0; i < kNumHashValues; i++) - counters[i] = 0; - for (i = 0; i < blockSize - 1; i++) - counters[((UInt32)data[i] << 8) | data[i + 1]]++; - counters[((UInt32)data[i] << 8) | data[0]]++; - - Groups = counters + BS_TEMP_SIZE; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - Flags = Groups + blockSize; - { - UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; - for (i = 0; i < numWords; i++) - Flags[i] = kAllFlags; - } - #endif - - { - UInt32 sum = 0; - for (i = 0; i < kNumHashValues; i++) - { - UInt32 groupSize = counters[i]; - if (groupSize > 0) - { - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 t = sum + groupSize - 1; - Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); - #endif - sum += groupSize; - } - counters[i] = sum - groupSize; - } - - for (i = 0; i < blockSize - 1; i++) - Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; - Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; - - for (i = 0; i < blockSize - 1; i++) - Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; - Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; - - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - { - UInt32 prev = 0; - for (i = 0; i < kNumHashValues; i++) - { - UInt32 prevGroupSize = counters[i] - prev; - if (prevGroupSize == 0) - continue; - SetGroupSize(Indices + prev, prevGroupSize); - prev = counters[i]; - } - } - #endif - } - - { - int NumRefBits; - UInt32 NumSortedBytes; - for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++); - NumRefBits = 32 - NumRefBits; - if (NumRefBits > kNumRefBitsMax) - NumRefBits = kNumRefBitsMax; - - for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) - { - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - UInt32 finishedGroupSize = 0; - #endif - UInt32 newLimit = 0; - for (i = 0; i < blockSize;) - { - UInt32 groupSize; - #ifdef BLOCK_SORT_EXTERNAL_FLAGS - - if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) - { - i++; - continue; - } - for (groupSize = 1; - (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; - groupSize++); - - groupSize++; - - #else - - groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); - { - Bool finishedGroup = ((Indices[i] & 0x80000000) == 0); - if ((Indices[i] & 0x40000000) != 0) - { - groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); - Indices[i + 1] &= kIndexMask; - } - Indices[i] &= kIndexMask; - groupSize++; - if (finishedGroup || groupSize == 1) - { - Indices[i - finishedGroupSize] &= kIndexMask; - if (finishedGroupSize > 1) - Indices[i - finishedGroupSize + 1] &= kIndexMask; - { - UInt32 newGroupSize = groupSize + finishedGroupSize; - SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); - finishedGroupSize = newGroupSize; - } - i += groupSize; - continue; - } - finishedGroupSize = 0; - } - - #endif - - if (NumSortedBytes >= blockSize) - { - UInt32 j; - for (j = 0; j < groupSize; j++) - { - UInt32 t = (i + j); - /* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */ - Groups[Indices[t]] = t; - } - } - else - if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices - #ifndef BLOCK_SORT_USE_HEAP_SORT - , 0, blockSize - #endif - ) != 0) - newLimit = i + groupSize; - i += groupSize; - } - if (newLimit == 0) - break; - } - } - #ifndef BLOCK_SORT_EXTERNAL_FLAGS - for (i = 0; i < blockSize;) - { - UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); - if ((Indices[i] & 0x40000000) != 0) - { - groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); - Indices[i + 1] &= kIndexMask; - } - Indices[i] &= kIndexMask; - groupSize++; - i += groupSize; - } - #endif - return Groups[0]; -} +/* BwtSort.c -- BWT block sorting +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "BwtSort.h" +#include "Sort.h" + +/* #define BLOCK_SORT_USE_HEAP_SORT */ +// #define BLOCK_SORT_USE_HEAP_SORT + +#ifdef BLOCK_SORT_USE_HEAP_SORT + +#define HeapSortRefDown(p, vals, n, size, temp) \ + { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ + size_t s = k << 1; \ + if (s > size) break; \ + if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ + if (val >= vals[p[s]]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + HeapSortRefDown(p, vals, i, size, temp); + } + while (--i != 0); + } + do + { + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortRefDown(p, vals, 1, size, temp); + } + while (size > 1); +} + +#endif // BLOCK_SORT_USE_HEAP_SORT + + +/* Don't change it !!! */ +#define kNumHashBytes 2 +#define kNumHashValues (1 << (kNumHashBytes * 8)) + +/* kNumRefBitsMax must be < (kNumHashBytes * 8) = 16 */ +#define kNumRefBitsMax 12 + +#define BS_TEMP_SIZE kNumHashValues + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + +/* 32 Flags in UInt32 word */ +#define kNumFlagsBits 5 +#define kNumFlagsInWord (1 << kNumFlagsBits) +#define kFlagsMask (kNumFlagsInWord - 1) +#define kAllFlags 0xFFFFFFFF + +#else + +#define kNumBitsMax 20 +#define kIndexMask (((UInt32)1 << kNumBitsMax) - 1) +#define kNumExtraBits (32 - kNumBitsMax) +#define kNumExtra0Bits (kNumExtraBits - 2) +#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1) + +#define SetFinishedGroupSize(p, size) \ + { *(p) |= ((((UInt32)(size) - 1) & kNumExtra0Mask) << kNumBitsMax); \ + if ((size) > (1 << kNumExtra0Bits)) { \ + *(p) |= 0x40000000; \ + *((p) + 1) |= (((UInt32)(size) - 1) >> kNumExtra0Bits) << kNumBitsMax; } } \ + +static void SetGroupSize(UInt32 *p, size_t size) +{ + if (--size == 0) + return; + *p |= 0x80000000 | (((UInt32)size & kNumExtra0Mask) << kNumBitsMax); + if (size >= (1 << kNumExtra0Bits)) + { + *p |= 0x40000000; + p[1] |= (((UInt32)size >> kNumExtra0Bits) << kNumBitsMax); + } +} + +#endif + +/* +SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks + "range" is not real range. It's only for optimization. +returns: 1 - if there are groups, 0 - no more groups +*/ + +static +unsigned +Z7_FASTCALL +SortGroup(size_t BlockSize, size_t NumSortedBytes, + size_t groupOffset, size_t groupSize, + unsigned NumRefBits, UInt32 *Indices +#ifndef BLOCK_SORT_USE_HEAP_SORT + , size_t left, size_t range +#endif + ) +{ + UInt32 *ind2 = Indices + groupOffset; + UInt32 *Groups; + if (groupSize <= 1) + { + /* + #ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetFinishedGroupSize(ind2, 1) + #endif + */ + return 0; + } + Groups = Indices + BlockSize + BS_TEMP_SIZE; + if (groupSize <= ((size_t)1 << NumRefBits) +#ifndef BLOCK_SORT_USE_HEAP_SORT + && groupSize <= range +#endif + ) + { + UInt32 *temp = Indices + BlockSize; + size_t j, group; + UInt32 mask, cg; + unsigned thereAreGroups; + { + UInt32 gPrev; + UInt32 gRes = 0; + { + size_t sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; + gPrev = Groups[sp]; + temp[0] = gPrev << NumRefBits; + } + + for (j = 1; j < groupSize; j++) + { + size_t sp = ind2[j] + NumSortedBytes; + UInt32 g; + if (sp >= BlockSize) + sp -= BlockSize; + g = Groups[sp]; + temp[j] = (g << NumRefBits) | (UInt32)j; + gRes |= (gPrev ^ g); + } + if (gRes == 0) + { +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); +#endif + return 1; + } + } + + HeapSort(temp, groupSize); + mask = ((UInt32)1 << NumRefBits) - 1; + thereAreGroups = 0; + + group = groupOffset; + cg = temp[0] >> NumRefBits; + temp[0] = ind2[temp[0] & mask]; + + { +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; +#else + size_t prevGroupStart = 0; +#endif + + for (j = 1; j < groupSize; j++) + { + const UInt32 val = temp[j]; + const UInt32 cgCur = val >> NumRefBits; + + if (cgCur != cg) + { + cg = cgCur; + group = groupOffset + j; + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + const size_t t = group - 1; + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); + } +#else + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; +#endif + } + else + thereAreGroups = 1; + { + const UInt32 ind = ind2[val & mask]; + temp[j] = ind; + Groups[ind] = (UInt32)group; + } + } + +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(temp + prevGroupStart, j - prevGroupStart); +#endif + } + + for (j = 0; j < groupSize; j++) + ind2[j] = temp[j]; + return thereAreGroups; + } + + /* Check that all strings are in one group (cannot sort) */ + { + UInt32 group; + size_t j; + size_t sp = ind2[0] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; + group = Groups[sp]; + for (j = 1; j < groupSize; j++) + { + sp = ind2[j] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; + if (Groups[sp] != group) + break; + } + if (j == groupSize) + { +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); +#endif + return 1; + } + } + +#ifndef BLOCK_SORT_USE_HEAP_SORT + { + /* ---------- Range Sort ---------- */ + size_t i; + size_t mid; + for (;;) + { + size_t j; + if (range <= 1) + { +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2, groupSize); +#endif + return 1; + } + mid = left + ((range + 1) >> 1); + j = groupSize; + i = 0; + do + { + size_t sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] >= mid) + { + for (j--; j > i; j--) + { + sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize; + if (Groups[sp] < mid) + { + UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp; + break; + } + } + if (i >= j) + break; + } + } + while (++i < j); + if (i == 0) + { + range = range - (mid - left); + left = mid; + } + else if (i == groupSize) + range = (mid - left); + else + break; + } + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + const size_t t = groupOffset + i - 1; + UInt32 *Flags = Groups + BlockSize; + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); + } +#endif + + { + size_t j; + for (j = i; j < groupSize; j++) + Groups[ind2[j]] = (UInt32)(groupOffset + i); + } + + { + unsigned res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left); + return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left)); + } + + } + +#else // BLOCK_SORT_USE_HEAP_SORT + + /* ---------- Heap Sort ---------- */ + + { + size_t j; + for (j = 0; j < groupSize; j++) + { + size_t sp = ind2[j] + NumSortedBytes; + if (sp >= BlockSize) + sp -= BlockSize; + ind2[j] = (UInt32)sp; + } + + HeapSortRef(ind2, Groups, groupSize); + + /* Write Flags */ + { + size_t sp = ind2[0]; + UInt32 group = Groups[sp]; + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags = Groups + BlockSize; +#else + size_t prevGroupStart = 0; +#endif + + for (j = 1; j < groupSize; j++) + { + sp = ind2[j]; + if (Groups[sp] != group) + { + group = Groups[sp]; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + { + const size_t t = groupOffset + j - 1; + Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); + } +#else + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); + prevGroupStart = j; +#endif + } + } + +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart); +#endif + } + { + /* Write new Groups values and Check that there are groups */ + unsigned thereAreGroups = 0; + for (j = 0; j < groupSize; j++) + { + size_t group = groupOffset + j; +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); + if (ind2[j] & 0x40000000) + subGroupSize += ((ind2[(size_t)j + 1] >> kNumBitsMax) << kNumExtra0Bits); + subGroupSize++; + for (;;) + { + const UInt32 original = ind2[j]; + size_t sp = original & kIndexMask; + if (sp < NumSortedBytes) + sp += BlockSize; + sp -= NumSortedBytes; + ind2[j] = (UInt32)sp | (original & ~kIndexMask); + Groups[sp] = (UInt32)group; + if (--subGroupSize == 0) + break; + j++; + thereAreGroups = 1; + } +#else + UInt32 *Flags = Groups + BlockSize; + for (;;) + { + size_t sp = ind2[j]; + if (sp < NumSortedBytes) + sp += BlockSize; + sp -= NumSortedBytes; + ind2[j] = (UInt32)sp; + Groups[sp] = (UInt32)group; + if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0) + break; + j++; + thereAreGroups = 1; + } +#endif + } + return thereAreGroups; + } + } +#endif // BLOCK_SORT_USE_HEAP_SORT +} + + +/* conditions: blockSize > 0 */ +UInt32 BlockSort(UInt32 *Indices, const Byte *data, size_t blockSize) +{ + UInt32 *counters = Indices + blockSize; + size_t i; + UInt32 *Groups; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + UInt32 *Flags; +#endif + +/* Radix-Sort for 2 bytes */ +// { UInt32 yyy; for (yyy = 0; yyy < 100; yyy++) { + for (i = 0; i < kNumHashValues; i++) + counters[i] = 0; + { + const Byte *data2 = data; + size_t a = data[(size_t)blockSize - 1]; + const Byte *data_lim = data + blockSize; + if (blockSize >= 4) + { + data_lim -= 3; + do + { + size_t b; + b = data2[0]; counters[(a << 8) | b]++; + a = data2[1]; counters[(b << 8) | a]++; + b = data2[2]; counters[(a << 8) | b]++; + a = data2[3]; counters[(b << 8) | a]++; + data2 += 4; + } + while (data2 < data_lim); + data_lim += 3; + } + while (data2 != data_lim) + { + size_t b = *data2++; + counters[(a << 8) | b]++; + a = b; + } + } +// }} + + Groups = counters + BS_TEMP_SIZE; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + Flags = Groups + blockSize; + { + const size_t numWords = (blockSize + kFlagsMask) >> kNumFlagsBits; + for (i = 0; i < numWords; i++) + Flags[i] = kAllFlags; + } +#endif + + { + UInt32 sum = 0; + for (i = 0; i < kNumHashValues; i++) + { + const UInt32 groupSize = counters[i]; + counters[i] = sum; + sum += groupSize; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + if (groupSize) + { + const UInt32 t = sum - 1; + Flags[t >> kNumFlagsBits] &= ~((UInt32)1 << (t & kFlagsMask)); + } +#endif + } + } + + for (i = 0; i < blockSize - 1; i++) + Groups[i] = counters[((unsigned)data[i] << 8) | data[(size_t)i + 1]]; + Groups[i] = counters[((unsigned)data[i] << 8) | data[0]]; + + { +#define SET_Indices(a, b, i) \ + { UInt32 c; \ + a = (a << 8) | (b); \ + c = counters[a]; \ + Indices[c] = (UInt32)i++; \ + counters[a] = c + 1; \ + } + + size_t a = data[0]; + const Byte *data_ptr = data + 1; + i = 0; + if (blockSize >= 3) + { + blockSize -= 2; + do + { + size_t b; + b = data_ptr[0]; SET_Indices(a, b, i) + a = data_ptr[1]; SET_Indices(b, a, i) + data_ptr += 2; + } + while (i < blockSize); + blockSize += 2; + } + if (i < blockSize - 1) + { + SET_Indices(a, data[(size_t)i + 1], i) + a = (Byte)a; + } + SET_Indices(a, data[0], i) + } + +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + { + UInt32 prev = 0; + for (i = 0; i < kNumHashValues; i++) + { + const UInt32 prevGroupSize = counters[i] - prev; + if (prevGroupSize == 0) + continue; + SetGroupSize(Indices + prev, prevGroupSize); + prev = counters[i]; + } + } +#endif + + { + unsigned NumRefBits; + size_t NumSortedBytes; + for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++) + {} + NumRefBits = 32 - NumRefBits; + if (NumRefBits > kNumRefBitsMax) + NumRefBits = kNumRefBitsMax; + + for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1) + { +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + size_t finishedGroupSize = 0; +#endif + size_t newLimit = 0; + for (i = 0; i < blockSize;) + { + size_t groupSize; +#ifdef BLOCK_SORT_EXTERNAL_FLAGS + + if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0) + { + i++; + continue; + } + for (groupSize = 1; + (Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0; + groupSize++) + {} + groupSize++; + +#else + + groupSize = (Indices[i] & ~0xC0000000) >> kNumBitsMax; + { + const BoolInt finishedGroup = ((Indices[i] & 0x80000000) == 0); + if (Indices[i] & 0x40000000) + { + groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits); + Indices[(size_t)i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + if (finishedGroup || groupSize == 1) + { + Indices[i - finishedGroupSize] &= kIndexMask; + if (finishedGroupSize > 1) + Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask; + { + const size_t newGroupSize = groupSize + finishedGroupSize; + SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize) + finishedGroupSize = newGroupSize; + } + i += groupSize; + continue; + } + finishedGroupSize = 0; + } + +#endif + + if (NumSortedBytes >= blockSize) + { + size_t j; + for (j = 0; j < groupSize; j++) + { + size_t t = i + j; + /* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */ + Groups[Indices[t]] = (UInt32)t; + } + } + else + if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices + #ifndef BLOCK_SORT_USE_HEAP_SORT + , 0, blockSize + #endif + )) + newLimit = i + groupSize; + i += groupSize; + } + if (newLimit == 0) + break; + } + } +#ifndef BLOCK_SORT_EXTERNAL_FLAGS + for (i = 0; i < blockSize;) + { + size_t groupSize = (Indices[i] & ~0xC0000000) >> kNumBitsMax; + if (Indices[i] & 0x40000000) + { + groupSize += (Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits; + Indices[(size_t)i + 1] &= kIndexMask; + } + Indices[i] &= kIndexMask; + groupSize++; + i += groupSize; + } +#endif + return Groups[0]; +} diff -Nru p7zip-rar-16.02/C/BwtSort.h p7zip-rar-16.02+really25.00+ds/C/BwtSort.h --- p7zip-rar-16.02/C/BwtSort.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/BwtSort.h 2024-12-18 18:00:00.000000000 +0000 @@ -1,26 +1,27 @@ -/* BwtSort.h -- BWT block sorting -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __BWT_SORT_H -#define __BWT_SORT_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ -/* #define BLOCK_SORT_EXTERNAL_FLAGS */ - -#ifdef BLOCK_SORT_EXTERNAL_FLAGS -#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) -#else -#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 -#endif - -#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) - -UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); - -EXTERN_C_END - -#endif +/* BwtSort.h -- BWT block sorting +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_BWT_SORT_H +#define ZIP7_INC_BWT_SORT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ +/* #define BLOCK_SORT_EXTERNAL_FLAGS */ +// #define BLOCK_SORT_EXTERNAL_FLAGS + +#ifdef BLOCK_SORT_EXTERNAL_FLAGS +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) (((blockSize) + 31) >> 5) +#else +#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 +#endif + +#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) + +UInt32 BlockSort(UInt32 *indices, const Byte *data, size_t blockSize); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Compiler.h p7zip-rar-16.02+really25.00+ds/C/Compiler.h --- p7zip-rar-16.02/C/Compiler.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Compiler.h 2025-06-30 17:00:00.000000000 +0000 @@ -1,32 +1,246 @@ -/* Compiler.h -2015-08-02 : Igor Pavlov : Public domain */ - -#ifndef __7Z_COMPILER_H -#define __7Z_COMPILER_H - -#ifdef _MSC_VER - - #ifdef UNDER_CE - #define RPC_NO_WINDOWS_H - /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ - #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union - #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int - #endif - - #if _MSC_VER >= 1300 - #pragma warning(disable : 4996) // This function or variable may be unsafe - #else - #pragma warning(disable : 4511) // copy constructor could not be generated - #pragma warning(disable : 4512) // assignment operator could not be generated - #pragma warning(disable : 4514) // unreferenced inline function has been removed - #pragma warning(disable : 4702) // unreachable code - #pragma warning(disable : 4710) // not inlined - #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information - #endif - -#endif - -#define UNUSED_VAR(x) (void)x; -/* #define UNUSED_VAR(x) x=x; */ - -#endif +/* Compiler.h : Compiler specific defines and pragmas +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_COMPILER_H +#define ZIP7_INC_COMPILER_H + +#if defined(__clang__) +# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif +#if defined(__clang__) && defined(__apple_build_version__) +# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__clang__) +# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__GNUC__) +# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifdef _MSC_VER +#if !defined(__clang__) && !defined(__GNUC__) +#define Z7_MSC_VER_ORIGINAL _MSC_VER +#endif +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define Z7_MINGW +#endif + +#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__)) +#define Z7_MCST_LCC +#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__) +#endif + +/* +#if defined(__AVX2__) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \ + || defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \ + || defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400) + #define Z7_COMPILER_AVX2_SUPPORTED + #endif +#endif +*/ + +// #pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#ifdef __clang__ +// padding size of '' with 4 bytes to alignment boundary +#pragma GCC diagnostic ignored "-Wpadded" + +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \ + && defined(__FreeBSD__) +// freebsd: +#pragma GCC diagnostic ignored "-Wexcess-padding" +#endif + +#if __clang_major__ >= 16 +#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" +#endif + +#if __clang_major__ == 13 +#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) +// cheri +#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast" +#endif +#endif + +#if __clang_major__ == 13 + // for + #pragma GCC diagnostic ignored "-Wreserved-identifier" +#endif + +#endif // __clang__ + +#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16 +// #pragma GCC diagnostic ignored "-Wcast-function-type-strict" +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + +typedef void (*Z7_void_Function)(void); +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC_C (Z7_void_Function) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define Z7_CAST_FUNC_C (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()' +#else +#define Z7_CAST_FUNC_C +#endif +/* +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +*/ +#ifdef __GNUC__ +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif +#endif + + +#ifdef _MSC_VER + + #ifdef UNDER_CE + #define RPC_NO_WINDOWS_H + /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ + #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union + #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int + #endif + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +// == 1200 : -O1 : for __forceinline +// >= 1900 : -O1 : for printf +#pragma warning(disable : 4710) // function not inlined + +#if _MSC_VER < 1900 +// winnt.h: 'Int64ShllMod32' +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + +#if _MSC_VER < 1300 +// #pragma warning(disable : 4702) // unreachable code +// Bra.c : -O1: +#pragma warning(disable : 4714) // function marked as __forceinline not inlined +#endif + +/* +#if _MSC_VER > 1400 && _MSC_VER <= 1900 +// strcat: This function or variable may be unsafe +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif +*/ + +#if _MSC_VER > 1200 +// -Wall warnings + +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4820) // '2' bytes padding added after data member + +#if _MSC_VER >= 1400 && _MSC_VER < 1920 +// 1400: string.h: _DBG_MEMCPY_INLINE_ +// 1600 - 191x : smmintrin.h __cplusplus' +// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable : 4668) + +// 1400 - 1600 : WinDef.h : 'FARPROC' : +// 1900 - 191x : immintrin.h: _readfsbase_u32 +// no function prototype given : converting '()' to '(void)' +#pragma warning(disable : 4255) +#endif + +#if _MSC_VER >= 1914 +// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable : 5045) +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(__clang__) && (__clang_major__ >= 4) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("clang loop unroll(disable)") \ + _Pragma("clang loop vectorize(disable)") + #define Z7_ATTRIB_NO_VECTORIZE +#elif defined(__GNUC__) && (__GNUC__ >= 5) \ + && (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610)) + #define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) + // __attribute__((optimize("no-unroll-loops"))); + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#elif defined(_MSC_VER) && (_MSC_VER >= 1920) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("loop( no_vector )") + #define Z7_ATTRIB_NO_VECTORIZE +#else + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + #define Z7_ATTRIB_NO_VECTORIZE +#endif + +#if defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1920) + #define Z7_PRAGMA_OPTIMIZE_FOR_CODE_SIZE _Pragma("optimize ( \"s\", on )") + #define Z7_PRAGMA_OPTIMIZE_DEFAULT _Pragma("optimize ( \"\", on )") +#else + #define Z7_PRAGMA_OPTIMIZE_FOR_CODE_SIZE + #define Z7_PRAGMA_OPTIMIZE_DEFAULT +#endif + + + +#if defined(MY_CPU_X86_OR_AMD64) && ( \ + defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5)) + #define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse"))) +#else + #define Z7_ATTRIB_NO_SSE +#endif + +#define Z7_ATTRIB_NO_VECTOR \ + Z7_ATTRIB_NO_VECTORIZE \ + Z7_ATTRIB_NO_SSE + + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // GCC is not good for __builtin_expect() + #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_unlikely [[unlikely]] + // #define Z7_likely [[likely]] +#else + #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600)) + +#if (Z7_CLANG_VERSION < 130000) +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"") +#endif + +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#define UNUSED_VAR(x) (void)x; +/* #define UNUSED_VAR(x) x=x; */ + +#endif diff -Nru p7zip-rar-16.02/C/CpuArch.c p7zip-rar-16.02+really25.00+ds/C/CpuArch.c --- p7zip-rar-16.02/C/CpuArch.c 2016-05-18 17:29:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/CpuArch.c 2024-11-24 05:00:00.000000000 +0000 @@ -1,211 +1,970 @@ -/* CpuArch.c -- CPU specific code -2016-02-25: Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#ifdef _7ZIP_ASM -#ifdef MY_CPU_X86_OR_AMD64 - -#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) -#define USE_ASM -#endif - -#if !defined(USE_ASM) && _MSC_VER >= 1500 -#include -#endif - -#if defined(USE_ASM) && !defined(MY_CPU_AMD64) -static UInt32 CheckFlag(UInt32 flag) -{ - #ifdef _MSC_VER - __asm pushfd; - __asm pop EAX; - __asm mov EDX, EAX; - __asm xor EAX, flag; - __asm push EAX; - __asm popfd; - __asm pushfd; - __asm pop EAX; - __asm xor EAX, EDX; - __asm push EDX; - __asm popfd; - __asm and flag, EAX; - #else - __asm__ __volatile__ ( - "pushf\n\t" - "pop %%EAX\n\t" - "movl %%EAX,%%EDX\n\t" - "xorl %0,%%EAX\n\t" - "push %%EAX\n\t" - "popf\n\t" - "pushf\n\t" - "pop %%EAX\n\t" - "xorl %%EDX,%%EAX\n\t" - "push %%EDX\n\t" - "popf\n\t" - "andl %%EAX, %0\n\t": - "=c" (flag) : "c" (flag) : - "%eax", "%edx"); - #endif - return flag; -} -#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; -#else -#define CHECK_CPUID_IS_SUPPORTED -#endif - -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) -{ - #ifdef USE_ASM - - #ifdef _MSC_VER - - UInt32 a2, b2, c2, d2; - __asm xor EBX, EBX; - __asm xor ECX, ECX; - __asm xor EDX, EDX; - __asm mov EAX, function; - __asm cpuid; - __asm mov a2, EAX; - __asm mov b2, EBX; - __asm mov c2, ECX; - __asm mov d2, EDX; - - *a = a2; - *b = b2; - *c = c2; - *d = d2; - - #else - - __asm__ __volatile__ ( - #if defined(MY_CPU_AMD64) && defined(__PIC__) - "mov %%rbx, %%rdi;" - "cpuid;" - "xchg %%rbx, %%rdi;" - : "=a" (*a) , - "=D" (*b) , - #elif defined(MY_CPU_X86) && defined(__PIC__) - "mov %%ebx, %%edi;" - "cpuid;" - "xchgl %%ebx, %%edi;" - : "=a" (*a) , - "=D" (*b) , - #else - "cpuid" - : "=a" (*a) , - "=b" (*b) , - #endif - "=c" (*c) , - "=d" (*d) - : "0" (function)) ; - - #endif - - #else - - int CPUInfo[4]; - __cpuid(CPUInfo, function); - *a = CPUInfo[0]; - *b = CPUInfo[1]; - *c = CPUInfo[2]; - *d = CPUInfo[3]; - - #endif -} - -Bool x86cpuid_CheckAndRead(Cx86cpuid *p) -{ - CHECK_CPUID_IS_SUPPORTED - MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); - MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); - return True; -} - -static const UInt32 kVendors[][3] = -{ - { 0x756E6547, 0x49656E69, 0x6C65746E}, - { 0x68747541, 0x69746E65, 0x444D4163}, - { 0x746E6543, 0x48727561, 0x736C7561} -}; - -int x86cpuid_GetFirm(const Cx86cpuid *p) -{ - unsigned i; - for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) - { - const UInt32 *v = kVendors[i]; - if (v[0] == p->vendor[0] && - v[1] == p->vendor[1] && - v[2] == p->vendor[2]) - return (int)i; - } - return -1; -} - -Bool CPU_Is_InOrder() -{ - Cx86cpuid p; - int firm; - UInt32 family, model; - if (!x86cpuid_CheckAndRead(&p)) - return True; - - family = x86cpuid_GetFamily(p.ver); - model = x86cpuid_GetModel(p.ver); - - firm = x86cpuid_GetFirm(&p); - - switch (firm) - { - case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( - /* In-Order Atom CPU */ - model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ - || model == 0x26 /* 45 nm, Z6xx */ - || model == 0x27 /* 32 nm, Z2460 */ - || model == 0x35 /* 32 nm, Z2760 */ - || model == 0x36 /* 32 nm, N2xxx, D2xxx */ - ))); - case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); - case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); - } - return True; -} - -#if !defined(MY_CPU_AMD64) && defined(_WIN32) -#include -static Bool CPU_Sys_Is_SSE_Supported() -{ - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi)) - return False; - return (vi.dwMajorVersion >= 5); -} -#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; -#else -#define CHECK_SYS_SSE_SUPPORT -#endif - -Bool CPU_Is_Aes_Supported() -{ - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) - return False; - return (p.c >> 25) & 1; -} - -#endif - -#else - -Bool CPU_Is_InOrder() -{ - return True; -} - -#endif // ifdef _7ZIP_ASM - +/* CpuArch.c -- CPU specific code +Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + +#undef NEED_CHECK_FOR_CPUID +#if !defined(MY_CPU_AMD64) +#define NEED_CHECK_FOR_CPUID +#endif + +/* + cpuid instruction supports (subFunction) parameter in ECX, + that is used only with some specific (function) parameter values. + most functions use only (subFunction==0). +*/ +/* + __cpuid(): MSVC and GCC/CLANG use same function/macro name + but parameters are different. + We use MSVC __cpuid() parameters style for our z7_x86_cpuid() function. +*/ + +#if defined(__GNUC__) /* && (__GNUC__ >= 10) */ \ + || defined(__clang__) /* && (__clang_major__ >= 10) */ + +/* there was some CLANG/GCC compilers that have issues with + rbx(ebx) handling in asm blocks in -fPIC mode (__PIC__ is defined). + compiler's contains the macro __cpuid() that is similar to our code. + The history of __cpuid() changes in CLANG/GCC: + GCC: + 2007: it preserved ebx for (__PIC__ && __i386__) + 2013: it preserved rbx and ebx for __PIC__ + 2014: it doesn't preserves rbx and ebx anymore + we suppose that (__GNUC__ >= 5) fixed that __PIC__ ebx/rbx problem. + CLANG: + 2014+: it preserves rbx, but only for 64-bit code. No __PIC__ check. + Why CLANG cares about 64-bit mode only, and doesn't care about ebx (in 32-bit)? + Do we need __PIC__ test for CLANG or we must care about rbx even if + __PIC__ is not defined? +*/ + +#define ASM_LN "\n" + +#if defined(MY_CPU_AMD64) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + + /* "=&r" selects free register. It can select even rbx, if that register is free. + "=&D" for (RDI) also works, but the code can be larger with "=&D" + "2"(subFun) : 2 is (zero-based) index in the output constraint list "=c" (ECX). */ + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%rbx, %q1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%rbx, %q1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#elif defined(MY_CPU_X86) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%ebx, %k1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%ebx, %k1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#else + +#define x86_cpuid_MACRO_2(p, func, subFunc) { \ + __asm__ __volatile__ ( \ + ASM_LN "cpuid" \ + : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(subFunc)); } + +#endif + +#define x86_cpuid_MACRO(p, func) x86_cpuid_MACRO_2(p, func, 0) + +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + x86_cpuid_MACRO(p, func) +} + +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + x86_cpuid_MACRO_2(p, func, subFunc) +} + + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + UInt32 a; + __asm__ __volatile__ ( + ASM_LN "pushf" + ASM_LN "pushf" + ASM_LN "pop %0" + // ASM_LN "movl %0, %1" + // ASM_LN "xorl $0x200000, %0" + ASM_LN "btc %1, %0" + ASM_LN "push %0" + ASM_LN "popf" + ASM_LN "pushf" + ASM_LN "pop %0" + ASM_LN "xorl (%%esp), %0" + + ASM_LN "popf" + ASM_LN + : "=&r" (a) // "=a" + : "i" (EFALGS_CPUID_BIT) + ); + if ((a & (1 << EFALGS_CPUID_BIT)) == 0) + return 0; + #endif + { + UInt32 p[4]; + x86_cpuid_MACRO(p, 0) + return p[0]; + } +} + +#undef ASM_LN + +#elif !defined(_MSC_VER) + +/* +// for gcc/clang and other: we can try to use __cpuid macro: +#include +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + __cpuid(func, p[0], p[1], p[2], p[3]); +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return (UInt32)__get_cpuid_max(0, NULL); +} +*/ +// for unsupported cpuid: +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(func) + p[0] = p[1] = p[2] = p[3] = 0; +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return 0; +} + +#else // _MSC_VER + +#if !defined(MY_CPU_AMD64) + +UInt32 __declspec(naked) Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + __asm pushfd + __asm pushfd + /* + __asm pop eax + // __asm mov edx, eax + __asm btc eax, EFALGS_CPUID_BIT + __asm push eax + */ + __asm btc dword ptr [esp], EFALGS_CPUID_BIT + __asm popfd + __asm pushfd + __asm pop eax + // __asm xor eax, edx + __asm xor eax, [esp] + // __asm push edx + __asm popfd + __asm and eax, (1 shl EFALGS_CPUID_BIT) + __asm jz end_func + #endif + __asm push ebx + __asm xor eax, eax // func + __asm xor ecx, ecx // subFunction (optional) for (func == 0) + __asm cpuid + __asm pop ebx + #if defined(NEED_CHECK_FOR_CPUID) + end_func: + #endif + __asm ret 0 +} + +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm xor ecx, ecx // subfunction (optional) for (func == 0) + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 0 +} + +static +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + UNUSED_VAR(subFunc) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm mov ecx, [esp + 12] // subFunc + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 4 +} + +#else // MY_CPU_AMD64 + + #if _MSC_VER >= 1600 + #include + #define MY_cpuidex __cpuidex + +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + __cpuidex((int *)p, func, subFunc); +} + + #else +/* + __cpuid (func == (0 or 7)) requires subfunction number in ECX. + MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. + __cpuid() in new MSVC clears ECX. + __cpuid() in old MSVC (14.00) x64 doesn't clear ECX + We still can use __cpuid for low (func) values that don't require ECX, + but __cpuid() in old MSVC will be incorrect for some func values: (func == 7). + So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, + where ECX value is first parameter for FASTCALL / NO_INLINE func. + So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and + old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. + +DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!! +*/ +static +Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(Int32 subFunction, Int32 func, Int32 *CPUInfo) +{ + UNUSED_VAR(subFunction) + __cpuid(CPUInfo, func); +} + #define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info) + #pragma message("======== MY_cpuidex_HACK WAS USED ========") +static +void Z7_FASTCALL z7_x86_cpuid_subFunc(UInt32 p[4], UInt32 func, UInt32 subFunc) +{ + MY_cpuidex_HACK(subFunc, func, (Int32 *)p); +} + #endif // _MSC_VER >= 1600 + +#if !defined(MY_CPU_AMD64) +/* inlining for __cpuid() in MSVC x86 (32-bit) produces big ineffective code, + so we disable inlining here */ +Z7_NO_INLINE +#endif +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + MY_cpuidex((Int32 *)p, (Int32)func, 0); +} + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + Int32 a[4]; + MY_cpuidex(a, 0, 0); + return a[0]; +} + +#endif // MY_CPU_AMD64 +#endif // _MSC_VER + +#if defined(NEED_CHECK_FOR_CPUID) +#define CHECK_CPUID_IS_SUPPORTED { if (z7_x86_cpuid_GetMaxFunc() == 0) return 0; } +#else +#define CHECK_CPUID_IS_SUPPORTED +#endif +#undef NEED_CHECK_FOR_CPUID + + +static +BoolInt x86cpuid_Func_1(UInt32 *p) +{ + CHECK_CPUID_IS_SUPPORTED + z7_x86_cpuid(p, 1); + return True; +} + +/* +static const UInt32 kVendors[][1] = +{ + { 0x756E6547 }, // , 0x49656E69, 0x6C65746E }, + { 0x68747541 }, // , 0x69746E65, 0x444D4163 }, + { 0x746E6543 } // , 0x48727561, 0x736C7561 } +}; +*/ + +/* +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; +int x86cpuid_GetFirm(const Cx86cpuid *p); +#define x86cpuid_ver_GetFamily(ver) (((ver >> 16) & 0xff0) | ((ver >> 8) & 0xf)) +#define x86cpuid_ver_GetModel(ver) (((ver >> 12) & 0xf0) | ((ver >> 4) & 0xf)) +#define x86cpuid_ver_GetStepping(ver) (ver & 0xf) + +int x86cpuid_GetFirm(const Cx86cpuid *p) +{ + unsigned i; + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[0]); i++) + { + const UInt32 *v = kVendors[i]; + if (v[0] == p->vendor[0] + // && v[1] == p->vendor[1] + // && v[2] == p->vendor[2] + ) + return (int)i; + } + return -1; +} + +BoolInt CPU_Is_InOrder() +{ + Cx86cpuid p; + UInt32 family, model; + if (!x86cpuid_CheckAndRead(&p)) + return True; + + family = x86cpuid_ver_GetFamily(p.ver); + model = x86cpuid_ver_GetModel(p.ver); + + switch (x86cpuid_GetFirm(&p)) + { + case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( + // In-Order Atom CPU + model == 0x1C // 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 + || model == 0x26 // 45 nm, Z6xx + || model == 0x27 // 32 nm, Z2460 + || model == 0x35 // 32 nm, Z2760 + || model == 0x36 // 32 nm, N2xxx, D2xxx + ))); + case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); + case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); + } + return False; // v23 : unknown processors are not In-Order +} +*/ + +#ifdef _WIN32 +#include "7zWindows.h" +#endif + +#if !defined(MY_CPU_AMD64) && defined(_WIN32) + +/* for legacy SSE ia32: there is no user-space cpu instruction to check + that OS supports SSE register storing/restoring on context switches. + So we need some OS-specific function to check that it's safe to use SSE registers. +*/ + +Z7_FORCE_INLINE +static BoolInt CPU_Sys_Is_SSE_Supported(void) +{ +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4996) // `GetVersion': was declared deprecated +#endif + /* low byte is major version of Windows + We suppose that any Windows version since + Windows2000 (major == 5) supports SSE registers */ + return (Byte)GetVersion() >= 5; +#if defined(_MSC_VER) + #pragma warning(pop) +#endif +} +#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; +#else +#define CHECK_SYS_SSE_SUPPORT +#endif + + +#if !defined(MY_CPU_AMD64) + +BoolInt CPU_IsSupported_CMOV(void) +{ + UInt32 a[4]; + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 15) & 1; +} + +BoolInt CPU_IsSupported_SSE(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSE2(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (BoolInt)(a[3] >> 26) & 1; +} + +#endif + + +static UInt32 x86cpuid_Func_1_ECX(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return a[2]; +} + +BoolInt CPU_IsSupported_AES(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSSE3(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 9) & 1; +} + +BoolInt CPU_IsSupported_SSE41(void) +{ + return (BoolInt)(x86cpuid_Func_1_ECX() >> 19) & 1; +} + +BoolInt CPU_IsSupported_SHA(void) +{ + CHECK_SYS_SSE_SUPPORT + + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + return (BoolInt)(d[1] >> 29) & 1; + } +} + + +BoolInt CPU_IsSupported_SHA512(void) +{ + if (!CPU_IsSupported_AVX2()) return False; // maybe CPU_IsSupported_AVX() is enough here + + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid_subFunc(d, 7, 0); + if (d[0] < 1) // d[0] - is max supported subleaf value + return False; + z7_x86_cpuid_subFunc(d, 7, 1); + return (BoolInt)(d[0]) & 1; + } +} + +/* +MSVC: _xgetbv() intrinsic is available since VS2010SP1. + MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in + that we can use or check. + For any 32-bit x86 we can use asm code in MSVC, + but MSVC asm code is huge after compilation. + So _xgetbv() is better + +ICC: _xgetbv() intrinsic is available (in what version of ICC?) + ICC defines (__GNUC___) and it supports gnu assembler + also ICC supports MASM style code with -use-msasm switch. + but ICC doesn't support __attribute__((__target__)) + +GCC/CLANG 9: + _xgetbv() is macro that works via __builtin_ia32_xgetbv() + and we need __attribute__((__target__("xsave")). + But with __target__("xsave") the function will be not + inlined to function that has no __target__("xsave") attribute. + If we want _xgetbv() call inlining, then we should use asm version + instead of calling _xgetbv(). + Note:intrinsic is broke before GCC 8.2: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684 +*/ + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) \ + || defined(_MSC_VER) && (_MSC_VER >= 1600) && (_MSC_FULL_VER >= 160040219) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + || defined(__clang__) && (__clang_major__ >= 9) +// we define ATTRIB_XGETBV, if we want to use predefined _xgetbv() from compiler +#if defined(__INTEL_COMPILER) +#define ATTRIB_XGETBV +#elif defined(__GNUC__) || defined(__clang__) +// we don't define ATTRIB_XGETBV here, because asm version is better for inlining. +// #define ATTRIB_XGETBV __attribute__((__target__("xsave"))) +#else +#define ATTRIB_XGETBV +#endif +#endif + +#if defined(ATTRIB_XGETBV) +#include +#endif + + +// XFEATURE_ENABLED_MASK/XCR0 +#define MY_XCR_XFEATURE_ENABLED_MASK 0 + +#if defined(ATTRIB_XGETBV) +ATTRIB_XGETBV +#endif +static UInt64 x86_xgetbv_0(UInt32 num) +{ +#if defined(ATTRIB_XGETBV) + { + return + #if (defined(_MSC_VER)) + _xgetbv(num); + #else + __builtin_ia32_xgetbv( + #if !defined(__clang__) + (int) + #endif + num); + #endif + } + +#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC) + + UInt32 a, d; + #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __asm__ + ( + "xgetbv" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #else // is old gcc + __asm__ + ( + ".byte 0x0f, 0x01, 0xd0" "\n\t" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #endif + return ((UInt64)d << 32) | a; + // return a; + +#elif defined(_MSC_VER) && !defined(MY_CPU_AMD64) + + UInt32 a, d; + __asm { + push eax + push edx + push ecx + mov ecx, num; + // xor ecx, ecx // = MY_XCR_XFEATURE_ENABLED_MASK + _emit 0x0f + _emit 0x01 + _emit 0xd0 + mov a, eax + mov d, edx + pop ecx + pop edx + pop eax + } + return ((UInt64)d << 32) | a; + // return a; + +#else // it's unknown compiler + // #error "Need xgetbv function" + UNUSED_VAR(num) + // for MSVC-X64 we could call external function from external file. + /* Actually we had checked OSXSAVE/AVX in cpuid before. + So it's expected that OS supports at least AVX and below. */ + // if (num != MY_XCR_XFEATURE_ENABLED_MASK) return 0; // if not XCR0 + return + // (1 << 0) | // x87 + (1 << 1) // SSE + | (1 << 2); // AVX + +#endif +} + +#ifdef _WIN32 +/* + Windows versions do not know about new ISA extensions that + can be introduced. But we still can use new extensions, + even if Windows doesn't report about supporting them, + But we can use new extensions, only if Windows knows about new ISA extension + that changes the number or size of registers: SSE, AVX/XSAVE, AVX512 + So it's enough to check + MY_PF_AVX_INSTRUCTIONS_AVAILABLE + instead of + MY_PF_AVX2_INSTRUCTIONS_AVAILABLE +*/ +#define MY_PF_XSAVE_ENABLED 17 +// #define MY_PF_SSSE3_INSTRUCTIONS_AVAILABLE 36 +// #define MY_PF_SSE4_1_INSTRUCTIONS_AVAILABLE 37 +// #define MY_PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38 +// #define MY_PF_AVX_INSTRUCTIONS_AVAILABLE 39 +// #define MY_PF_AVX2_INSTRUCTIONS_AVAILABLE 40 +// #define MY_PF_AVX512F_INSTRUCTIONS_AVAILABLE 41 +#endif + +BoolInt CPU_IsSupported_AVX(void) +{ + #ifdef _WIN32 + if (!IsProcessorFeaturePresent(MY_PF_XSAVE_ENABLED)) + return False; + /* PF_AVX_INSTRUCTIONS_AVAILABLE probably is supported starting from + some latest Win10 revisions. But we need AVX in older Windows also. + So we don't use the following check: */ + /* + if (!IsProcessorFeaturePresent(MY_PF_AVX_INSTRUCTIONS_AVAILABLE)) + return False; + */ + #endif + + /* + OS must use new special XSAVE/XRSTOR instructions to save + AVX registers when it required for context switching. + At OS statring: + OS sets CR4.OSXSAVE flag to signal the processor that OS supports the XSAVE extensions. + Also OS sets bitmask in XCR0 register that defines what + registers will be processed by XSAVE instruction: + XCR0.SSE[bit 0] - x87 registers and state + XCR0.SSE[bit 1] - SSE registers and state + XCR0.AVX[bit 2] - AVX registers and state + CR4.OSXSAVE is reflected to CPUID.1:ECX.OSXSAVE[bit 27]. + So we can read that bit in user-space. + XCR0 is available for reading in user-space by new XGETBV instruction. + */ + { + const UInt32 c = x86cpuid_Func_1_ECX(); + if (0 == (1 + & (c >> 28) // AVX instructions are supported by hardware + & (c >> 27))) // OSXSAVE bit: XSAVE and related instructions are enabled by OS. + return False; + } + + /* also we can check + CPUID.1:ECX.XSAVE [bit 26] : that shows that + XSAVE, XRESTOR, XSETBV, XGETBV instructions are supported by hardware. + But that check is redundant, because if OSXSAVE bit is set, then XSAVE is also set */ + + /* If OS have enabled XSAVE extension instructions (OSXSAVE == 1), + in most cases we expect that OS also will support storing/restoring + for AVX and SSE states at least. + But to be ensure for that we call user-space instruction + XGETBV(0) to get XCR0 value that contains bitmask that defines + what exact states(registers) OS have enabled for storing/restoring. + */ + + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 1) // SSE state is supported (set by OS) for storing/restoring + & (BoolInt)(bm >> 2); // AVX state is supported (set by OS) for storing/restoring + } + // since Win7SP1: we can use GetEnabledXStateFeatures(); +} + + +BoolInt CPU_IsSupported_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + return 1 + & (BoolInt)(d[1] >> 5); // avx2 + } +} + +#if 0 +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + BoolInt v; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + v = 1 + & (BoolInt)(d[1] >> 16) // avx512f + & (BoolInt)(d[1] >> 31); // avx512vl + if (!v) + return False; + } + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=0x%x\n", bm); + return 1 + & (BoolInt)(bm >> 5) // OPMASK + & (BoolInt)(bm >> 6) // ZMM upper 256-bit + & (BoolInt)(bm >> 7); // ZMM16 ... ZMM31 + } +} +#endif + +BoolInt CPU_IsSupported_VAES_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) + return False; + if (z7_x86_cpuid_GetMaxFunc() < 7) + return False; + { + UInt32 d[4]; + z7_x86_cpuid(d, 7); + // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); + return 1 + & (BoolInt)(d[1] >> 5) // avx2 + // & (d[1] >> 31) // avx512vl + & (BoolInt)(d[2] >> 9); // vaes // VEX-256/EVEX + } +} + +BoolInt CPU_IsSupported_PageGB(void) +{ + CHECK_CPUID_IS_SUPPORTED + { + UInt32 d[4]; + z7_x86_cpuid(d, 0x80000000); + if (d[0] < 0x80000001) + return False; + z7_x86_cpuid(d, 0x80000001); + return (BoolInt)(d[3] >> 26) & 1; + } +} + + +#elif defined(MY_CPU_ARM_OR_ARM64) + +#ifdef _WIN32 + +#include "7zWindows.h" + +BoolInt CPU_IsSupported_CRC32(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRYPTO(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_NEON(void) { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } + +#else + +#if defined(__APPLE__) + +/* +#include +#include +static void Print_sysctlbyname(const char *name) +{ + size_t bufSize = 256; + char buf[256]; + int res = sysctlbyname(name, &buf, &bufSize, NULL, 0); + { + int i; + printf("\nres = %d : %s : '%s' : bufSize = %d, numeric", res, name, buf, (unsigned)bufSize); + for (i = 0; i < 20; i++) + printf(" %2x", (unsigned)(Byte)buf[i]); + + } +} +*/ +/* + Print_sysctlbyname("hw.pagesize"); + Print_sysctlbyname("machdep.cpu.brand_string"); +*/ + +static BoolInt z7_sysctlbyname_Get_BoolInt(const char *name) +{ + UInt32 val = 0; + if (z7_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) + return 1; + return 0; +} + +BoolInt CPU_IsSupported_CRC32(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); +} + +BoolInt CPU_IsSupported_NEON(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.neon"); +} + +BoolInt CPU_IsSupported_SHA512(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha512"); +} + +/* +BoolInt CPU_IsSupported_SHA3(void) +{ + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_2_sha3"); +} +*/ + +#ifdef MY_CPU_ARM64 +#define APPLE_CRYPTO_SUPPORT_VAL 1 +#else +#define APPLE_CRYPTO_SUPPORT_VAL 0 +#endif + +BoolInt CPU_IsSupported_SHA1(void) { return APPLE_CRYPTO_SUPPORT_VAL; } +BoolInt CPU_IsSupported_SHA2(void) { return APPLE_CRYPTO_SUPPORT_VAL; } +BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; } + + +#else // __APPLE__ + +#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216) + #define Z7_GETAUXV_AVAILABLE +#else +// #pragma message("=== is not NEW GLIBC === ") + #if defined __has_include + #if __has_include () +// #pragma message("=== sys/auxv.h is avail=== ") + #define Z7_GETAUXV_AVAILABLE + #endif + #endif +#endif + +#ifdef Z7_GETAUXV_AVAILABLE +// #pragma message("=== Z7_GETAUXV_AVAILABLE === ") +#include +#define USE_HWCAP +#endif + +#ifdef USE_HWCAP + +#if defined(__FreeBSD__) +static unsigned long MY_getauxval(int aux) +{ + unsigned long val; + if (elf_aux_info(aux, &val, sizeof(val))) + return 0; + return val; +} +#else +#define MY_getauxval getauxval + #if defined __has_include + #if __has_include () +#include + #endif + #endif +#endif + + #define MY_HWCAP_CHECK_FUNC_2(name1, name2) \ + BoolInt CPU_IsSupported_ ## name1(void) { return (MY_getauxval(AT_HWCAP) & (HWCAP_ ## name2)); } + +#ifdef MY_CPU_ARM64 + #define MY_HWCAP_CHECK_FUNC(name) \ + MY_HWCAP_CHECK_FUNC_2(name, name) +#if 1 || defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else + MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD) +#endif +// MY_HWCAP_CHECK_FUNC (ASIMD) +#elif defined(MY_CPU_ARM) + #define MY_HWCAP_CHECK_FUNC(name) \ + BoolInt CPU_IsSupported_ ## name(void) { return (MY_getauxval(AT_HWCAP2) & (HWCAP2_ ## name)); } + MY_HWCAP_CHECK_FUNC_2(NEON, NEON) +#endif + +#else // USE_HWCAP + + #define MY_HWCAP_CHECK_FUNC(name) \ + BoolInt CPU_IsSupported_ ## name(void) { return 0; } +#if defined(__ARM_NEON) + BoolInt CPU_IsSupported_NEON(void) { return True; } +#else + MY_HWCAP_CHECK_FUNC(NEON) +#endif + +#endif // USE_HWCAP + +MY_HWCAP_CHECK_FUNC (CRC32) +MY_HWCAP_CHECK_FUNC (SHA1) +MY_HWCAP_CHECK_FUNC (SHA2) +MY_HWCAP_CHECK_FUNC (AES) +#ifdef MY_CPU_ARM64 +// supports HWCAP_SHA512 and HWCAP_SHA3 since 2017. +// we define them here, if they are not defined +#ifndef HWCAP_SHA3 +// #define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SHA512 +// #pragma message("=== HWCAP_SHA512 define === ") +#define HWCAP_SHA512 (1 << 21) +#endif +MY_HWCAP_CHECK_FUNC (SHA512) +// MY_HWCAP_CHECK_FUNC (SHA3) +#endif + +#endif // __APPLE__ +#endif // _WIN32 + +#endif // MY_CPU_ARM_OR_ARM64 + + + +#ifdef __APPLE__ + +#include + +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) +{ + return sysctlbyname(name, buf, bufSize, NULL, 0); +} + +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) +{ + size_t bufSize = sizeof(*val); + const int res = z7_sysctlbyname_Get(name, val, &bufSize); + if (res == 0 && bufSize != sizeof(*val)) + return EFAULT; + return res; +} + +#endif diff -Nru p7zip-rar-16.02/C/CpuArch.h p7zip-rar-16.02+really25.00+ds/C/CpuArch.h --- p7zip-rar-16.02/C/CpuArch.h 2016-02-17 06:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/CpuArch.h 2025-04-05 08:00:00.000000000 +0000 @@ -1,226 +1,686 @@ -/* CpuArch.h -- CPU specific code -2015-12-01: Igor Pavlov : Public domain */ - -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -MY_CPU_LE means that CPU is LITTLE ENDIAN. -MY_CPU_BE means that CPU is BIG ENDIAN. -If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. - -MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. -*/ - -#if defined(_M_X64) \ - || defined(_M_AMD64) \ - || defined(__x86_64__) \ - || defined(__AMD64__) \ - || defined(__amd64__) - #define MY_CPU_AMD64 -#endif - -#if defined(MY_CPU_AMD64) \ - || defined(_M_IA64) \ - || defined(__AARCH64EL__) \ - || defined(__AARCH64EB__) - #define MY_CPU_64BIT -#endif - -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 -#endif - -#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) -#define MY_CPU_X86_OR_AMD64 -#endif - -#if defined(MY_CPU_X86) \ - || defined(_M_ARM) \ - || defined(__ARMEL__) \ - || defined(__THUMBEL__) \ - || defined(__ARMEB__) \ - || defined(__THUMBEB__) - #define MY_CPU_32BIT -#endif - -#if defined(_WIN32) && defined(_M_ARM) -#define MY_CPU_ARM_LE -#endif - -#if defined(_WIN32) && defined(_M_IA64) -#define MY_CPU_IA64_LE -#endif - -#if defined(MY_CPU_X86_OR_AMD64) \ - || defined(MY_CPU_ARM_LE) \ - || defined(MY_CPU_IA64_LE) \ - || defined(__LITTLE_ENDIAN__) \ - || defined(__ARMEL__) \ - || defined(__THUMBEL__) \ - || defined(__AARCH64EL__) \ - || defined(__MIPSEL__) \ - || defined(__MIPSEL) \ - || defined(_MIPSEL) \ - || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) - #define MY_CPU_LE -#endif - -#if defined(__BIG_ENDIAN__) \ - || defined(__ARMEB__) \ - || defined(__THUMBEB__) \ - || defined(__AARCH64EB__) \ - || defined(__MIPSEB__) \ - || defined(__MIPSEB) \ - || defined(_MIPSEB) \ - || defined(__m68k__) \ - || defined(__s390__) \ - || defined(__s390x__) \ - || defined(__zarch__) \ - || defined(__sparc) \ - || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - #define MY_CPU_BE -#endif - -#if defined(MY_CPU_LE) && defined(MY_CPU_BE) -Stop_Compiling_Bad_Endian -#endif - - -#ifdef MY_CPU_LE - #if defined(MY_CPU_X86_OR_AMD64) \ - /* || defined(__AARCH64EL__) */ - #define MY_CPU_LE_UNALIGN - #endif -#endif - - -#ifdef MY_CPU_LE_UNALIGN - -#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) -#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) -#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) - -#define SetUi16(p, v) { *(UInt16 *)(p) = (v); } -#define SetUi32(p, v) { *(UInt32 *)(p) = (v); } -#define SetUi64(p, v) { *(UInt64 *)(p) = (v); } - -#else - -#define GetUi16(p) ( (UInt16) ( \ - ((const Byte *)(p))[0] | \ - ((UInt16)((const Byte *)(p))[1] << 8) )) - -#define GetUi32(p) ( \ - ((const Byte *)(p))[0] | \ - ((UInt32)((const Byte *)(p))[1] << 8) | \ - ((UInt32)((const Byte *)(p))[2] << 16) | \ - ((UInt32)((const Byte *)(p))[3] << 24)) - -#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) - -#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ - _ppp_[0] = (Byte)_vvv_; \ - _ppp_[1] = (Byte)(_vvv_ >> 8); } - -#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ - _ppp_[0] = (Byte)_vvv_; \ - _ppp_[1] = (Byte)(_vvv_ >> 8); \ - _ppp_[2] = (Byte)(_vvv_ >> 16); \ - _ppp_[3] = (Byte)(_vvv_ >> 24); } - -#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ - SetUi32(_ppp2_ , (UInt32)_vvv2_); \ - SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } - -#endif - - -#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) - -/* Note: we use bswap instruction, that is unsupported in 386 cpu */ - -#include - -#pragma intrinsic(_byteswap_ulong) -#pragma intrinsic(_byteswap_uint64) -#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) -#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) - -#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - -#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) -#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) - -#else - -#define GetBe32(p) ( \ - ((UInt32)((const Byte *)(p))[0] << 24) | \ - ((UInt32)((const Byte *)(p))[1] << 16) | \ - ((UInt32)((const Byte *)(p))[2] << 8) | \ - ((const Byte *)(p))[3] ) - -#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) - -#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ - _ppp_[0] = (Byte)(_vvv_ >> 24); \ - _ppp_[1] = (Byte)(_vvv_ >> 16); \ - _ppp_[2] = (Byte)(_vvv_ >> 8); \ - _ppp_[3] = (Byte)_vvv_; } - -#endif - - -#define GetBe16(p) ( (UInt16) ( \ - ((UInt16)((const Byte *)(p))[0] << 8) | \ - ((const Byte *)(p))[1] )) - - - -#ifdef MY_CPU_X86_OR_AMD64 -#ifdef _7ZIP_ASM - -typedef struct -{ - UInt32 maxFunc; - UInt32 vendor[3]; - UInt32 ver; - UInt32 b; - UInt32 c; - UInt32 d; -} Cx86cpuid; - -enum -{ - CPU_FIRM_INTEL, - CPU_FIRM_AMD, - CPU_FIRM_VIA -}; - -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); - -Bool x86cpuid_CheckAndRead(Cx86cpuid *p); -int x86cpuid_GetFirm(const Cx86cpuid *p); - -#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) -#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF)) -#define x86cpuid_GetStepping(ver) (ver & 0xF) - -#endif - -Bool CPU_Is_InOrder(); -Bool CPU_Is_Aes_Supported(); - -#endif - -EXTERN_C_END - -#endif +/* CpuArch.h -- CPU specific code +Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_CPU_ARCH_H +#define ZIP7_INC_CPU_ARCH_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* +MY_CPU_LE means that CPU is LITTLE ENDIAN. +MY_CPU_BE means that CPU is BIG ENDIAN. +If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. + +MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. + +MY_CPU_64BIT means that processor can work with 64-bit registers. + MY_CPU_64BIT can be used to select fast code branch + MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8) +*/ + +#if !defined(_M_ARM64EC) +#if defined(_M_X64) \ + || defined(_M_AMD64) \ + || defined(__x86_64__) \ + || defined(__AMD64__) \ + || defined(__amd64__) + #define MY_CPU_AMD64 + #ifdef __ILP32__ + #define MY_CPU_NAME "x32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "x64" + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #define MY_CPU_64BIT +#endif +#endif + + +#if defined(_M_IX86) \ + || defined(__i386__) + #define MY_CPU_X86 + #define MY_CPU_NAME "x86" + /* #define MY_CPU_32BIT */ + #define MY_CPU_SIZEOF_POINTER 4 +#endif + +#if defined(__SSE2__) \ + || defined(MY_CPU_AMD64) \ + || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) +#define MY_CPU_SSE2 +#endif + + +#if defined(_M_ARM64) \ + || defined(_M_ARM64EC) \ + || defined(__AARCH64EL__) \ + || defined(__AARCH64EB__) \ + || defined(__aarch64__) + #define MY_CPU_ARM64 +#if defined(__ILP32__) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "arm64-32" + #define MY_CPU_SIZEOF_POINTER 4 +#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16) + #define MY_CPU_NAME "arm64-128" + #define MY_CPU_SIZEOF_POINTER 16 +#else +#if defined(_M_ARM64EC) + #define MY_CPU_NAME "arm64ec" +#else + #define MY_CPU_NAME "arm64" +#endif + #define MY_CPU_SIZEOF_POINTER 8 +#endif + #define MY_CPU_64BIT +#endif + + +#if defined(_M_ARM) \ + || defined(_M_ARM_NT) \ + || defined(_M_ARMT) \ + || defined(__arm__) \ + || defined(__thumb__) \ + || defined(__ARMEL__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEL__) \ + || defined(__THUMBEB__) + #define MY_CPU_ARM + + #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT) + #define MY_CPU_ARMT + #define MY_CPU_NAME "armt" + #else + #define MY_CPU_ARM32 + #define MY_CPU_NAME "arm" + #endif + /* #define MY_CPU_32BIT */ + #define MY_CPU_SIZEOF_POINTER 4 +#endif + + +#if defined(_M_IA64) \ + || defined(__ia64__) + #define MY_CPU_IA64 + #define MY_CPU_NAME "ia64" + #define MY_CPU_64BIT +#endif + + +#if defined(__mips64) \ + || defined(__mips64__) \ + || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) + #define MY_CPU_NAME "mips64" + #define MY_CPU_64BIT +#elif defined(__mips__) + #define MY_CPU_NAME "mips" + /* #define MY_CPU_32BIT */ +#endif + + +#if defined(__ppc64__) \ + || defined(__powerpc64__) \ + || defined(__ppc__) \ + || defined(__powerpc__) \ + || defined(__PPC__) \ + || defined(_POWER) + +#define MY_CPU_PPC_OR_PPC64 + +#if defined(__ppc64__) \ + || defined(__powerpc64__) \ + || defined(_LP64) \ + || defined(__64BIT__) + #ifdef __ILP32__ + #define MY_CPU_NAME "ppc64-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "ppc64" + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #define MY_CPU_64BIT +#else + #define MY_CPU_NAME "ppc" + #define MY_CPU_SIZEOF_POINTER 4 + /* #define MY_CPU_32BIT */ +#endif +#endif + + +#if defined(__sparc__) \ + || defined(__sparc) + #define MY_CPU_SPARC + #if defined(__LP64__) \ + || defined(_LP64) \ + || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_NAME "sparcv9" + #define MY_CPU_SIZEOF_POINTER 8 + #define MY_CPU_64BIT + #elif defined(__sparc_v9__) \ + || defined(__sparcv9) + #define MY_CPU_64BIT + #if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "sparcv9-32" + #else + #define MY_CPU_NAME "sparcv9m" + #endif + #elif defined(__sparc_v8__) \ + || defined(__sparcv8) + #define MY_CPU_NAME "sparcv8" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "sparc" + #endif +#endif + + +#if defined(__riscv) \ + || defined(__riscv__) + #define MY_CPU_RISCV + #if __riscv_xlen == 32 + #define MY_CPU_NAME "riscv32" + #elif __riscv_xlen == 64 + #define MY_CPU_NAME "riscv64" + #else + #define MY_CPU_NAME "riscv" + #endif +#endif + + +#if defined(__loongarch__) + #define MY_CPU_LOONGARCH + #if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64) + #define MY_CPU_64BIT + #endif + #if defined(__loongarch64) + #define MY_CPU_NAME "loongarch64" + #define MY_CPU_LOONGARCH64 + #else + #define MY_CPU_NAME "loongarch" + #endif +#endif + + +// #undef MY_CPU_NAME +// #undef MY_CPU_SIZEOF_POINTER +// #define __e2k__ +// #define __SIZEOF_POINTER__ 4 +#if defined(__e2k__) + #define MY_CPU_E2K + #if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4) + #define MY_CPU_NAME "e2k-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "e2k" + #if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8) + #define MY_CPU_SIZEOF_POINTER 8 + #endif + #endif + #define MY_CPU_64BIT +#endif + + +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) +#define MY_CPU_X86_OR_AMD64 +#endif + +#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64) +#define MY_CPU_ARM_OR_ARM64 +#endif + + +#ifdef _WIN32 + + #ifdef MY_CPU_ARM + #define MY_CPU_ARM_LE + #endif + + #ifdef MY_CPU_ARM64 + #define MY_CPU_ARM64_LE + #endif + + #ifdef _M_IA64 + #define MY_CPU_IA64_LE + #endif + +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_LE) \ + || defined(MY_CPU_ARM64_LE) \ + || defined(MY_CPU_IA64_LE) \ + || defined(_LITTLE_ENDIAN) \ + || defined(__LITTLE_ENDIAN__) \ + || defined(__ARMEL__) \ + || defined(__THUMBEL__) \ + || defined(__AARCH64EL__) \ + || defined(__MIPSEL__) \ + || defined(__MIPSEL) \ + || defined(_MIPSEL) \ + || defined(__BFIN__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + #define MY_CPU_LE +#endif + +#if defined(__BIG_ENDIAN__) \ + || defined(__ARMEB__) \ + || defined(__THUMBEB__) \ + || defined(__AARCH64EB__) \ + || defined(__MIPSEB__) \ + || defined(__MIPSEB) \ + || defined(_MIPSEB) \ + || defined(__m68k__) \ + || defined(__s390__) \ + || defined(__s390x__) \ + || defined(__zarch__) \ + || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + #define MY_CPU_BE +#endif + + +#if defined(MY_CPU_LE) && defined(MY_CPU_BE) + #error Stop_Compiling_Bad_Endian +#endif + +#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE) + #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time +#endif + +#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) + #error Stop_Compiling_Bad_32_64_BIT +#endif + +#ifdef __SIZEOF_POINTER__ + #ifdef MY_CPU_SIZEOF_POINTER + #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__ + #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE + #endif + #else + #define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__ + #endif +#endif + +#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) +#if defined (_LP64) + #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE +#endif +#endif + +#ifdef _MSC_VER + #if _MSC_VER >= 1300 + #define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1)) + #define MY_CPU_pragma_pop __pragma(pack(pop)) + #else + #define MY_CPU_pragma_pack_push_1 + #define MY_CPU_pragma_pop + #endif +#else + #ifdef __xlC__ + #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)") + #define MY_CPU_pragma_pop _Pragma("pack()") + #else + #define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)") + #define MY_CPU_pragma_pop _Pragma("pack(pop)") + #endif +#endif + + +#ifndef MY_CPU_NAME + // #define MY_CPU_IS_UNKNOWN + #ifdef MY_CPU_LE + #define MY_CPU_NAME "LE" + #elif defined(MY_CPU_BE) + #define MY_CPU_NAME "BE" + #else + /* + #define MY_CPU_NAME "" + */ + #endif +#endif + + + + + +#ifdef __has_builtin + #define Z7_has_builtin(x) __has_builtin(x) +#else + #define Z7_has_builtin(x) 0 +#endif + + +#define Z7_BSWAP32_CONST(v) \ + ( (((UInt32)(v) << 24) ) \ + | (((UInt32)(v) << 8) & (UInt32)0xff0000) \ + | (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \ + | (((UInt32)(v) >> 24) )) + + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + +#include + +/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */ + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +#define Z7_BSWAP16(v) _byteswap_ushort(v) +#define Z7_BSWAP32(v) _byteswap_ulong (v) +#define Z7_BSWAP64(v) _byteswap_uint64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +/* GCC can generate slow code that calls function for __builtin_bswap32() for: + - GCC for RISCV, if Zbb/XTHeadBb extension is not used. + - GCC for SPARC. + The code from CLANG for SPARC also is not fastest. + So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases. +*/ +#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \ + && !defined(MY_CPU_SPARC) \ + && ( \ + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \ + ) + +#define Z7_BSWAP16(v) __builtin_bswap16(v) +#define Z7_BSWAP32(v) __builtin_bswap32(v) +#define Z7_BSWAP64(v) __builtin_bswap64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +#else + +#define Z7_BSWAP16(v) ((UInt16) \ + ( ((UInt32)(v) << 8) \ + | ((UInt32)(v) >> 8) \ + )) + +#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v) + +#define Z7_BSWAP64(v) \ + ( ( ( (UInt64)(v) ) << 8 * 7 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \ + | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \ + | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \ + | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \ + | ( ( (UInt64)(v) >> 8 * 7 ) ) \ + ) + +#endif + + + +#ifdef MY_CPU_LE + #if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM64) \ + || defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \ + || defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6) + #define MY_CPU_LE_UNALIGN + #define MY_CPU_LE_UNALIGN_64 + #elif defined(__ARM_FEATURE_UNALIGNED) +/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions. + Description of problems: +problem-1 : 32-bit ARM architecture: + multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM) + require 32-bit (WORD) alignment (by 32-bit ARM architecture). + So there is "Alignment fault exception", if data is not aligned for 32-bit. + +problem-2 : 32-bit kernels and arm64 kernels: + 32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception". + So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux. + + But some arm64 kernels do not handle these faults in 32-bit programs. + So we have unhandled exception for such instructions. + Probably some new arm64 kernels have fixed it, and unaligned + paired-access instructions work in new kernels? + +problem-3 : compiler for 32-bit arm: + Compilers use LDRD/STRD/LDM/STM for UInt64 accesses + and for another cases where two 32-bit accesses are fused + to one multi-access instruction. + So UInt64 variables must be aligned for 32-bit, and each + 32-bit access must be aligned for 32-bit, if we want to + avoid "Alignment fault" exception (handled or unhandled). + +problem-4 : performace: + Even if unaligned access is handled by kernel, it will be slow. + So if we allow unaligned access, we can get fast unaligned + single-access, and slow unaligned paired-access. + + We don't allow unaligned access on 32-bit arm, because compiler + genarates paired-access instructions that require 32-bit alignment, + and some arm64 kernels have no handler for these instructions. + Also unaligned paired-access instructions will be slow, if kernel handles them. +*/ + // it must be disabled: + // #define MY_CPU_LE_UNALIGN + #endif +#endif + + +#ifdef MY_CPU_LE_UNALIGN + +#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) +#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) +#ifdef MY_CPU_LE_UNALIGN_64 +#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) +#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } +#endif + +#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); } +#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); } + +#else + +#define GetUi16(p) ( (UInt16) ( \ + ((const Byte *)(p))[0] | \ + ((UInt16)((const Byte *)(p))[1] << 8) )) + +#define GetUi32(p) ( \ + ((const Byte *)(p))[0] | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((UInt32)((const Byte *)(p))[2] << 16) | \ + ((UInt32)((const Byte *)(p))[3] << 24)) + +#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); } + +#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)_vvv_; \ + _ppp_[1] = (Byte)(_vvv_ >> 8); \ + _ppp_[2] = (Byte)(_vvv_ >> 16); \ + _ppp_[3] = (Byte)(_vvv_ >> 24); } + +#endif + + +#ifndef GetUi64 +#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#endif + +#ifndef SetUi64 +#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ + SetUi32(_ppp2_ , (UInt32)_vvv2_) \ + SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) } +#endif + + +#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) + +#if 0 +// Z7_BSWAP16 can be slow for x86-msvc +#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p))) +#else +#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16) +#endif + +#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p)) +#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); } + +#if defined(MY_CPU_LE_UNALIGN_64) +#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p)) +#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); } +#endif + +#else + +#define GetBe32(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 24) | \ + ((UInt32)((const Byte *)(p))[1] << 16) | \ + ((UInt32)((const Byte *)(p))[2] << 8) | \ + ((const Byte *)(p))[3] ) + +#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 24); \ + _ppp_[1] = (Byte)(_vvv_ >> 16); \ + _ppp_[2] = (Byte)(_vvv_ >> 8); \ + _ppp_[3] = (Byte)_vvv_; } + +#endif + +#ifndef GetBe64 +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) +#endif + +#ifndef SetBe64 +#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \ + _ppp_[0] = (Byte)(_vvv_ >> 56); \ + _ppp_[1] = (Byte)(_vvv_ >> 48); \ + _ppp_[2] = (Byte)(_vvv_ >> 40); \ + _ppp_[3] = (Byte)(_vvv_ >> 32); \ + _ppp_[4] = (Byte)(_vvv_ >> 24); \ + _ppp_[5] = (Byte)(_vvv_ >> 16); \ + _ppp_[6] = (Byte)(_vvv_ >> 8); \ + _ppp_[7] = (Byte)_vvv_; } +#endif + +#ifndef GetBe16 +#ifdef GetBe16_to32 +#define GetBe16(p) ( (UInt16) GetBe16_to32(p)) +#else +#define GetBe16(p) ( (UInt16) ( \ + ((UInt16)((const Byte *)(p))[0] << 8) | \ + ((const Byte *)(p))[1] )) +#endif +#endif + + +#if defined(MY_CPU_BE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_NATIVE_TO_BE_32(v) (v) +// #define Z7_GET_NATIVE16_FROM_2_BYTES(b0, b1) ((b1) | ((b0) << 8)) +#elif defined(MY_CPU_LE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v) +// #define Z7_GET_NATIVE16_FROM_2_BYTES(b0, b1) ((b0) | ((b1) << 8)) +#else +#error Stop_Compiling_Unknown_Endian_CONV +#endif + + +#if defined(MY_CPU_BE) + +#define GetBe64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetBe32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetBe16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetUi64a(p) GetUi64(p) +#define GetUi32a(p) GetUi32(p) +#define GetUi16a(p) GetUi16(p) +#define SetUi32a(p, v) SetUi32(p, v) +#define SetUi16a(p, v) SetUi16(p, v) + +#elif defined(MY_CPU_LE) + +#define GetUi64a(p) (*(const UInt64 *)(const void *)(p)) +#define GetUi32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetBe64a(p) GetBe64(p) +#define GetBe32a(p) GetBe32(p) +#define GetBe16a(p) GetBe16(p) +#define SetBe32a(p, v) SetBe32(p, v) +#define SetBe16a(p, v) SetBe16(p, v) + +#else +#error Stop_Compiling_Unknown_Endian_CPU_a +#endif + + +#ifndef GetBe16_to32 +#define GetBe16_to32(p) GetBe16(p) +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_OR_ARM64) \ + || defined(MY_CPU_PPC_OR_PPC64) + #define Z7_CPU_FAST_ROTATE_SUPPORTED +#endif + + +#ifdef MY_CPU_X86_OR_AMD64 + +void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function); +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void); +#if defined(MY_CPU_AMD64) +#define Z7_IF_X86_CPUID_SUPPORTED +#else +#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc()) +#endif + +BoolInt CPU_IsSupported_AES(void); +BoolInt CPU_IsSupported_AVX(void); +BoolInt CPU_IsSupported_AVX2(void); +BoolInt CPU_IsSupported_AVX512F_AVX512VL(void); +BoolInt CPU_IsSupported_VAES_AVX2(void); +BoolInt CPU_IsSupported_CMOV(void); +BoolInt CPU_IsSupported_SSE(void); +BoolInt CPU_IsSupported_SSE2(void); +BoolInt CPU_IsSupported_SSSE3(void); +BoolInt CPU_IsSupported_SSE41(void); +BoolInt CPU_IsSupported_SHA(void); +BoolInt CPU_IsSupported_SHA512(void); +BoolInt CPU_IsSupported_PageGB(void); + +#elif defined(MY_CPU_ARM_OR_ARM64) + +BoolInt CPU_IsSupported_CRC32(void); +BoolInt CPU_IsSupported_NEON(void); + +#if defined(_WIN32) +BoolInt CPU_IsSupported_CRYPTO(void); +#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO +#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO +#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO +#else +BoolInt CPU_IsSupported_SHA1(void); +BoolInt CPU_IsSupported_SHA2(void); +BoolInt CPU_IsSupported_AES(void); +#endif +BoolInt CPU_IsSupported_SHA512(void); + +#endif + +#if defined(__APPLE__) +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); +#endif + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Delta.c p7zip-rar-16.02+really25.00+ds/C/Delta.c --- p7zip-rar-16.02/C/Delta.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Delta.c 2021-02-09 17:00:00.000000000 +0000 @@ -1,64 +1,169 @@ -/* Delta.c -- Delta converter -2009-05-26 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Delta.h" - -void Delta_Init(Byte *state) -{ - unsigned i; - for (i = 0; i < DELTA_STATE_SIZE; i++) - state[i] = 0; -} - -static void MyMemCpy(Byte *dest, const Byte *src, unsigned size) -{ - unsigned i; - for (i = 0; i < size; i++) - dest[i] = src[i]; -} - -void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) -{ - Byte buf[DELTA_STATE_SIZE]; - unsigned j = 0; - MyMemCpy(buf, state, delta); - { - SizeT i; - for (i = 0; i < size;) - { - for (j = 0; j < delta && i < size; i++, j++) - { - Byte b = data[i]; - data[i] = (Byte)(b - buf[j]); - buf[j] = b; - } - } - } - if (j == delta) - j = 0; - MyMemCpy(state, buf + j, delta - j); - MyMemCpy(state + delta - j, buf, j); -} - -void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) -{ - Byte buf[DELTA_STATE_SIZE]; - unsigned j = 0; - MyMemCpy(buf, state, delta); - { - SizeT i; - for (i = 0; i < size;) - { - for (j = 0; j < delta && i < size; i++, j++) - { - buf[j] = data[i] = (Byte)(buf[j] + data[i]); - } - } - } - if (j == delta) - j = 0; - MyMemCpy(state, buf + j, delta - j); - MyMemCpy(state + delta - j, buf, j); -} +/* Delta.c -- Delta converter +2021-02-09 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Delta.h" + +void Delta_Init(Byte *state) +{ + unsigned i; + for (i = 0; i < DELTA_STATE_SIZE; i++) + state[i] = 0; +} + + +void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) +{ + Byte temp[DELTA_STATE_SIZE]; + + if (size == 0) + return; + + { + unsigned i = 0; + do + temp[i] = state[i]; + while (++i != delta); + } + + if (size <= delta) + { + unsigned i = 0, k; + do + { + Byte b = *data; + *data++ = (Byte)(b - temp[i]); + temp[i] = b; + } + while (++i != size); + + k = 0; + + do + { + if (i == delta) + i = 0; + state[k] = temp[i++]; + } + while (++k != delta); + + return; + } + + { + Byte *p = data + size - delta; + { + unsigned i = 0; + do + state[i] = *p++; + while (++i != delta); + } + { + const Byte *lim = data + delta; + ptrdiff_t dif = -(ptrdiff_t)delta; + + if (((ptrdiff_t)size + dif) & 1) + { + --p; *p = (Byte)(*p - p[dif]); + } + + while (p != lim) + { + --p; *p = (Byte)(*p - p[dif]); + --p; *p = (Byte)(*p - p[dif]); + } + + dif = -dif; + + do + { + --p; *p = (Byte)(*p - temp[--dif]); + } + while (dif != 0); + } + } +} + + +void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) +{ + unsigned i; + const Byte *lim; + + if (size == 0) + return; + + i = 0; + lim = data + size; + + if (size <= delta) + { + do + *data = (Byte)(*data + state[i++]); + while (++data != lim); + + for (; delta != i; state++, delta--) + *state = state[i]; + data -= i; + } + else + { + /* + #define B(n) b ## n + #define I(n) Byte B(n) = state[n]; + #define U(n) { B(n) = (Byte)((B(n)) + *data++); data[-1] = (B(n)); } + #define F(n) if (data != lim) { U(n) } + + if (delta == 1) + { + I(0) + if ((lim - data) & 1) { U(0) } + while (data != lim) { U(0) U(0) } + data -= 1; + } + else if (delta == 2) + { + I(0) I(1) + lim -= 1; while (data < lim) { U(0) U(1) } + lim += 1; F(0) + data -= 2; + } + else if (delta == 3) + { + I(0) I(1) I(2) + lim -= 2; while (data < lim) { U(0) U(1) U(2) } + lim += 2; F(0) F(1) + data -= 3; + } + else if (delta == 4) + { + I(0) I(1) I(2) I(3) + lim -= 3; while (data < lim) { U(0) U(1) U(2) U(3) } + lim += 3; F(0) F(1) F(2) + data -= 4; + } + else + */ + { + do + { + *data = (Byte)(*data + state[i++]); + data++; + } + while (i != delta); + + { + ptrdiff_t dif = -(ptrdiff_t)delta; + do + *data = (Byte)(*data + data[dif]); + while (++data != lim); + data += dif; + } + } + } + + do + *state++ = *data; + while (++data != lim); +} diff -Nru p7zip-rar-16.02/C/Delta.h p7zip-rar-16.02+really25.00+ds/C/Delta.h --- p7zip-rar-16.02/C/Delta.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Delta.h 2023-03-03 10:00:00.000000000 +0000 @@ -1,19 +1,19 @@ -/* Delta.h -- Delta converter -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __DELTA_H -#define __DELTA_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define DELTA_STATE_SIZE 256 - -void Delta_Init(Byte *state); -void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); -void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); - -EXTERN_C_END - -#endif +/* Delta.h -- Delta converter +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_DELTA_H +#define ZIP7_INC_DELTA_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define DELTA_STATE_SIZE 256 + +void Delta_Init(Byte *state); +void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); +void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/DllSecur.c p7zip-rar-16.02+really25.00+ds/C/DllSecur.c --- p7zip-rar-16.02/C/DllSecur.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/DllSecur.c 2023-12-03 18:00:00.000000000 +0000 @@ -0,0 +1,99 @@ +/* DllSecur.c -- DLL loading security +2023-12-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 + +#include "7zWindows.h" + +#include "DllSecur.h" + +#ifndef UNDER_CE + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags); + +#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400 +#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 + +#define DELIM "\0" + +static const char * const g_Dlls = + "userenv" + DELIM "setupapi" + DELIM "apphelp" + DELIM "propsys" + DELIM "dwmapi" + DELIM "cryptbase" + DELIM "oleacc" + DELIM "clbcatq" + DELIM "version" + #ifndef _CONSOLE + DELIM "uxtheme" + #endif + DELIM; + +#endif + +#ifdef __clang__ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#if defined (_MSC_VER) && _MSC_VER >= 1900 +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif + +#define IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN \ + if ((UInt16)GetVersion() != 6) { \ + const \ + Func_SetDefaultDllDirectories setDllDirs = \ + (Func_SetDefaultDllDirectories) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), \ + "SetDefaultDllDirectories"); \ + if (setDllDirs) if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) return; } + +void My_SetDefaultDllDirectories(void) +{ + #ifndef UNDER_CE + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN + #endif +} + + +void LoadSecurityDlls(void) +{ + #ifndef UNDER_CE + // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN + { + wchar_t buf[MAX_PATH + 100]; + const char *dll; + unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2); + if (pos == 0 || pos > MAX_PATH) + return; + if (buf[pos - 1] != '\\') + buf[pos++] = '\\'; + for (dll = g_Dlls; *dll != 0;) + { + wchar_t *dest = &buf[pos]; + for (;;) + { + const char c = *dll++; + if (c == 0) + break; + *dest++ = (Byte)c; + } + dest[0] = '.'; + dest[1] = 'd'; + dest[2] = 'l'; + dest[3] = 'l'; + dest[4] = 0; + // lstrcatW(buf, L".dll"); + LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + } + } + #endif +} + +#endif // _WIN32 diff -Nru p7zip-rar-16.02/C/DllSecur.h p7zip-rar-16.02+really25.00+ds/C/DllSecur.h --- p7zip-rar-16.02/C/DllSecur.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/DllSecur.h 2023-03-03 10:00:00.000000000 +0000 @@ -0,0 +1,20 @@ +/* DllSecur.h -- DLL loading for security +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_DLL_SECUR_H +#define ZIP7_INC_DLL_SECUR_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#ifdef _WIN32 + +void My_SetDefaultDllDirectories(void); +void LoadSecurityDlls(void); + +#endif + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/HuffEnc.c p7zip-rar-16.02+really25.00+ds/C/HuffEnc.c --- p7zip-rar-16.02/C/HuffEnc.c 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/HuffEnc.c 2025-03-20 14:00:00.000000000 +0000 @@ -1,148 +1,360 @@ -/* HuffEnc.c -- functions for Huffman encoding -2016-05-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "HuffEnc.h" -#include "Sort.h" - -#define kMaxLen 16 -#define NUM_BITS 10 -#define MASK ((1 << NUM_BITS) - 1) - -#define NUM_COUNTERS 64 - -#define HUFFMAN_SPEED_OPT - -void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen) -{ - UInt32 num = 0; - /* if (maxLen > 10) maxLen = 10; */ - { - UInt32 i; - - #ifdef HUFFMAN_SPEED_OPT - - UInt32 counters[NUM_COUNTERS]; - for (i = 0; i < NUM_COUNTERS; i++) - counters[i] = 0; - for (i = 0; i < numSymbols; i++) - { - UInt32 freq = freqs[i]; - counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++; - } - - for (i = 1; i < NUM_COUNTERS; i++) - { - UInt32 temp = counters[i]; - counters[i] = num; - num += temp; - } - - for (i = 0; i < numSymbols; i++) - { - UInt32 freq = freqs[i]; - if (freq == 0) - lens[i] = 0; - else - p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS); - } - counters[0] = 0; - HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]); - - #else - - for (i = 0; i < numSymbols; i++) - { - UInt32 freq = freqs[i]; - if (freq == 0) - lens[i] = 0; - else - p[num++] = i | (freq << NUM_BITS); - } - HeapSort(p, num); - - #endif - } - - if (num < 2) - { - unsigned minCode = 0; - unsigned maxCode = 1; - if (num == 1) - { - maxCode = (unsigned)p[0] & MASK; - if (maxCode == 0) - maxCode++; - } - p[minCode] = 0; - p[maxCode] = 1; - lens[minCode] = lens[maxCode] = 1; - return; - } - - { - UInt32 b, e, i; - - i = b = e = 0; - do - { - UInt32 n, m, freq; - n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; - freq = (p[n] & ~MASK); - p[n] = (p[n] & MASK) | (e << NUM_BITS); - m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; - freq += (p[m] & ~MASK); - p[m] = (p[m] & MASK) | (e << NUM_BITS); - p[e] = (p[e] & MASK) | freq; - e++; - } - while (num - e > 1); - - { - UInt32 lenCounters[kMaxLen + 1]; - for (i = 0; i <= kMaxLen; i++) - lenCounters[i] = 0; - - p[--e] &= MASK; - lenCounters[1] = 2; - while (e > 0) - { - UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1; - p[e] = (p[e] & MASK) | (len << NUM_BITS); - if (len >= maxLen) - for (len = maxLen - 1; lenCounters[len] == 0; len--); - lenCounters[len]--; - lenCounters[len + 1] += 2; - } - - { - UInt32 len; - i = 0; - for (len = maxLen; len != 0; len--) - { - UInt32 k; - for (k = lenCounters[len]; k != 0; k--) - lens[p[i++] & MASK] = (Byte)len; - } - } - - { - UInt32 nextCodes[kMaxLen + 1]; - { - UInt32 code = 0; - UInt32 len; - for (len = 1; len <= kMaxLen; len++) - nextCodes[len] = code = (code + lenCounters[len - 1]) << 1; - } - /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ - - { - UInt32 k; - for (k = 0; k < numSymbols; k++) - p[k] = nextCodes[lens[k]]++; - } - } - } - } -} +/* HuffEnc.c -- functions for Huffman encoding +Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "HuffEnc.h" +#include "Sort.h" +#include "CpuArch.h" + +#define kMaxLen Z7_HUFFMAN_LEN_MAX +#define NUM_BITS 10 +#define MASK ((1u << NUM_BITS) - 1) +#define FREQ_MASK (~(UInt32)MASK) +#define NUM_COUNTERS (48 * 2) + +#if 1 && (defined(MY_CPU_LE) || defined(MY_CPU_BE)) +#if defined(MY_CPU_LE) + #define HI_HALF_OFFSET 1 +#else + #define HI_HALF_OFFSET 0 +#endif +#define LOAD_PARENT(p) ((unsigned)*((const UInt16 *)(p) + HI_HALF_OFFSET)) +#define STORE_PARENT(p, fb, val) *((UInt16 *)(p) + HI_HALF_OFFSET) = (UInt16)(val); +#define STORE_PARENT_DIRECT(p, fb, hi) STORE_PARENT(p, fb, hi) +#define UPDATE_E(eHi) eHi++; +#else +#define LOAD_PARENT(p) ((unsigned)(*(p) >> NUM_BITS)) +#define STORE_PARENT_DIRECT(p, fb, hi) *(p) = ((fb) & MASK) | (hi); // set parent field +#define STORE_PARENT(p, fb, val) STORE_PARENT_DIRECT(p, fb, ((UInt32)(val) << NUM_BITS)) +#define UPDATE_E(eHi) eHi += 1 << NUM_BITS; +#endif + +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, unsigned numSymbols, unsigned maxLen) +{ +#if NUM_COUNTERS > 2 + unsigned counters[NUM_COUNTERS]; +#endif +#if 1 && NUM_COUNTERS > (kMaxLen + 4) * 2 + #define lenCounters (counters) + #define codes (counters + kMaxLen + 4) +#else + unsigned lenCounters[kMaxLen + 1]; + UInt32 codes[kMaxLen + 1]; +#endif + + unsigned num; + { + unsigned i; + // UInt32 sum = 0; + +#if NUM_COUNTERS > 2 + +#define CTR_ITEM_FOR_FREQ(freq) \ + counters[(freq) >= NUM_COUNTERS - 1 ? NUM_COUNTERS - 1 : (unsigned)(freq)] + + for (i = 0; i < NUM_COUNTERS; i++) + counters[i] = 0; + memset(lens, 0, numSymbols); + { + const UInt32 *fp = freqs + numSymbols; +#define NUM_UNROLLS 1 +#if NUM_UNROLLS > 1 // use 1 if odd (numSymbols) is possisble + if (numSymbols & 1) + { + UInt32 f; + f = *--fp; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; + } +#endif + do + { + UInt32 f; + fp -= NUM_UNROLLS; + f = fp[0]; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; +#if NUM_UNROLLS > 1 + f = fp[1]; CTR_ITEM_FOR_FREQ(f)++; + // sum += f; +#endif + } + while (fp != freqs); + } +#if 0 + printf("\nsum=%8u numSymbols =%3u ctrs:", sum, numSymbols); + { + unsigned k = 0; + for (k = 0; k < NUM_COUNTERS; k++) + printf(" %u", counters[k]); + } +#endif + + num = counters[1]; + counters[1] = 0; + for (i = 2; i != NUM_COUNTERS; i += 2) + { + unsigned c; + c = (counters )[i]; (counters )[i] = num; num += c; + c = (counters + 1)[i]; (counters + 1)[i] = num; num += c; + } + counters[0] = num; // we want to write (freq==0) symbols to the end of (p) array + { + i = 0; + do + { + const UInt32 f = freqs[i]; +#if 0 + if (f == 0) lens[i] = 0; else +#endif + p[CTR_ITEM_FOR_FREQ(f)++] = i | (f << NUM_BITS); + } + while (++i != numSymbols); + } + HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]); + +#else // NUM_COUNTERS <= 2 + + num = 0; + for (i = 0; i < numSymbols; i++) + { + const UInt32 freq = freqs[i]; + if (freq == 0) + lens[i] = 0; + else + p[num++] = i | (freq << NUM_BITS); + } + HeapSort(p, num); + +#endif + } + + if (num <= 2) + { + unsigned minCode = 0; + unsigned maxCode = 1; + if (num) + { + maxCode = (unsigned)p[(size_t)num - 1] & MASK; + if (num == 2) + { + minCode = (unsigned)p[0] & MASK; + if (minCode > maxCode) + { + const unsigned temp = minCode; + minCode = maxCode; + maxCode = temp; + } + } + else if (maxCode == 0) + maxCode++; + } + p[minCode] = 0; + p[maxCode] = 1; + lens[minCode] = lens[maxCode] = 1; + return; + } + { + unsigned i; + for (i = 0; i <= kMaxLen; i++) + lenCounters[i] = 0; + lenCounters[1] = 2; // by default root node has 2 child leaves at level 1. + } + // if (num != 2) + { + // num > 2 + // the binary tree will contain (num - 1) internal nodes. + // p[num - 2] will be root node of binary tree. + UInt32 *b; + UInt32 *n; + // first node will have two leaf childs: p[0] and p[1]: + // p[0] += p[1] & FREQ_MASK; // set frequency sum of child leafs + // if (pi == n) exit(0); + // if (pi != n) + { + UInt32 fb = (p[1] & FREQ_MASK) + p[0]; + UInt32 f = p[2] & FREQ_MASK; + const UInt32 *pi = p + 2; + UInt32 *e = p; + UInt32 eHi = 0; + n = p + num; + b = p; + // p[0] = fb; + for (;;) + { + // (b <= e) + UInt32 sum; + e++; + UPDATE_E(eHi) + + // (b < e) + + // p range : high bits + // [0, b) : parent : processed nodes that have parent and childs + // [b, e) : FREQ : non-processed nodes that have no parent but have childs + // [e, pi) : FREQ : processed leaves for which parent node was created + // [pi, n) : FREQ : non-processed leaves for which parent node was not created + + // first child + // note : (*b < f) is same result as ((*b & FREQ_MASK) < f) + if (fb < f) + { + // node freq is smaller + sum = fb & FREQ_MASK; + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + fb = *b; + if (b == e) + { + if (++pi == n) + break; + sum += f; + fb &= MASK; + fb |= sum; + *e = fb; + f = *pi & FREQ_MASK; + continue; + } + } + else if (++pi == n) + { + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + break; + } + else + { + sum = f; + f = *pi & FREQ_MASK; + } + + // (b < e) + + // second child + if (fb < f) + { + sum += fb; + sum &= FREQ_MASK; + STORE_PARENT_DIRECT (b, fb, eHi) + b++; + *e = (*e & MASK) | sum; // set frequency sum + // (b <= e) is possible here + fb = *b; + } + else if (++pi == n) + break; + else + { + sum += f; + f = *pi & FREQ_MASK; + *e = (*e & MASK) | sum; // set frequency sum + } + } + } + + // printf("\nnum-e=%3u, numSymbols=%3u, num=%3u, b=%3u", n - e, numSymbols, n - p, b - p); + { + n -= 2; + *n &= MASK; // root node : we clear high bits (zero bits mean level == 0) + if (n != b) + { + // We go here, if we have some number of non-created nodes up to root. + // We process them in simplified code: + // position of parent for each pair of nodes is known. + // n[-2], n[-1] : current pair of child nodes + // (p1) : parent node for current pair. + UInt32 *p1 = n; + do + { + const unsigned len = LOAD_PARENT(p1) + 1; + p1--; + (lenCounters )[len] -= 2; // we remove 2 leaves from level (len) + (lenCounters + 1)[len] += 2 * 2; // we add 4 leaves at level (len + 1) + n -= 2; + STORE_PARENT (n , n[0], len) + STORE_PARENT (n + 1, n[1], len) + } + while (n != b); + } + } + + if (b != p) + { + // we detect level of each node (realtive to root), + // and update lenCounters[]. + // We process only intermediate nodes and we don't process leaves. + do + { + // if (ii < b) : parent_bits_of (p[ii]) == index of parent node : ii < (p[ii]) + // if (ii >= b) : parent_bits_of (p[ii]) == level of this (ii) node in tree + unsigned len; + b--; + len = (unsigned)LOAD_PARENT(p + LOAD_PARENT(b)) + 1; + STORE_PARENT (b, *b, len) + if (len >= maxLen) + { + // We are not allowed to create node at level (maxLen) and higher, + // because all leaves must be placed to level (maxLen) or lower. + // We find nearest allowed leaf and place current node to level of that leaf: + for (len = maxLen - 1; lenCounters[len] == 0; len--) {} + } + lenCounters[len]--; // we remove 1 leaf from level (len) + (lenCounters + 1)[len] += 2; // we add 2 leaves at level (len + 1) + } + while (b != p); + } + } + { + { + unsigned len = maxLen; + const UInt32 *p2 = p; + do + { + unsigned k = lenCounters[len]; + if (k) + do + lens[(unsigned)*p2++ & MASK] = (Byte)len; + while (--k); + } + while (--len); + } + codes[0] = 0; // we don't want garbage values to be written to p[] array. + // codes[1] = 0; + { + UInt32 code = 0; + unsigned len; + for (len = 0; len < kMaxLen; len++) + (codes + 1)[len] = code = (code + lenCounters[len]) << 1; + } + /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ + { + const Byte * const limit = lens + numSymbols; + do + { + unsigned len; + UInt32 c; + len = lens[0]; c = codes[len]; p[0] = c; codes[len] = c + 1; + // len = lens[1]; c = codes[len]; p[1] = c; codes[len] = c + 1; + p += 1; + lens += 1; + } + while (lens != limit); + } + } +} + +#undef kMaxLen +#undef NUM_BITS +#undef MASK +#undef FREQ_MASK +#undef NUM_COUNTERS +#undef CTR_ITEM_FOR_FREQ +#undef LOAD_PARENT +#undef STORE_PARENT +#undef STORE_PARENT_DIRECT +#undef UPDATE_E +#undef HI_HALF_OFFSET +#undef NUM_UNROLLS +#undef lenCounters +#undef codes diff -Nru p7zip-rar-16.02/C/HuffEnc.h p7zip-rar-16.02+really25.00+ds/C/HuffEnc.h --- p7zip-rar-16.02/C/HuffEnc.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/HuffEnc.h 2025-03-20 14:00:00.000000000 +0000 @@ -1,23 +1,23 @@ -/* HuffEnc.h -- Huffman encoding -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __HUFF_ENC_H -#define __HUFF_ENC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* -Conditions: - num <= 1024 = 2 ^ NUM_BITS - Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS) - maxLen <= 16 = kMaxLen - Num_Items(p) >= HUFFMAN_TEMP_SIZE(num) -*/ - -void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); - -EXTERN_C_END - -#endif +/* HuffEnc.h -- Huffman encoding +Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_HUFF_ENC_H +#define ZIP7_INC_HUFF_ENC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define Z7_HUFFMAN_LEN_MAX 16 +/* +Conditions: + 2 <= num <= 1024 = 2 ^ NUM_BITS + Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS) + 1 <= maxLen <= 16 = Z7_HUFFMAN_LEN_MAX + Num_Items(p) >= HUFFMAN_TEMP_SIZE(num) +*/ +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/LzFind.c p7zip-rar-16.02+really25.00+ds/C/LzFind.c --- p7zip-rar-16.02/C/LzFind.c 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzFind.c 2025-05-19 06:00:00.000000000 +0000 @@ -1,1044 +1,1746 @@ -/* LzFind.c -- Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "LzFind.h" -#include "LzHash.h" - -#define kEmptyHashValue 0 -#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1)) -#define kMaxHistorySize ((UInt32)7 << 29) - -#define kStartMaxLen 3 - -static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -{ - if (!p->directInput) - { - alloc->Free(alloc, p->bufferBase); - p->bufferBase = NULL; - } -} - -/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ - -static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -{ - UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; - if (p->directInput) - { - p->blockSize = blockSize; - return 1; - } - if (!p->bufferBase || p->blockSize != blockSize) - { - LzInWindow_Free(p, alloc); - p->blockSize = blockSize; - p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); - } - return (p->bufferBase != NULL); -} - -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } - -UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } - -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -{ - p->posLimit -= subValue; - p->pos -= subValue; - p->streamPos -= subValue; -} - -static void MatchFinder_ReadBlock(CMatchFinder *p) -{ - if (p->streamEndWasReached || p->result != SZ_OK) - return; - - /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */ - - if (p->directInput) - { - UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos); - if (curSize > p->directInputRem) - curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; - p->streamPos += curSize; - if (p->directInputRem == 0) - p->streamEndWasReached = 1; - return; - } - - for (;;) - { - Byte *dest = p->buffer + (p->streamPos - p->pos); - size_t size = (p->bufferBase + p->blockSize - dest); - if (size == 0) - return; - - p->result = p->stream->Read(p->stream, dest, &size); - if (p->result != SZ_OK) - return; - if (size == 0) - { - p->streamEndWasReached = 1; - return; - } - p->streamPos += (UInt32)size; - if (p->streamPos - p->pos > p->keepSizeAfter) - return; - } -} - -void MatchFinder_MoveBlock(CMatchFinder *p) -{ - memmove(p->bufferBase, - p->buffer - p->keepSizeBefore, - (size_t)(p->streamPos - p->pos) + p->keepSizeBefore); - p->buffer = p->bufferBase + p->keepSizeBefore; -} - -int MatchFinder_NeedMove(CMatchFinder *p) -{ - if (p->directInput) - return 0; - /* if (p->streamEndWasReached) return 0; */ - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -} - -void MatchFinder_ReadIfRequired(CMatchFinder *p) -{ - if (p->streamEndWasReached) - return; - if (p->keepSizeAfter >= p->streamPos - p->pos) - MatchFinder_ReadBlock(p); -} - -static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -{ - if (MatchFinder_NeedMove(p)) - MatchFinder_MoveBlock(p); - MatchFinder_ReadBlock(p); -} - -static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -{ - p->cutValue = 32; - p->btMode = 1; - p->numHashBytes = 4; - p->bigHash = 0; -} - -#define kCrcPoly 0xEDB88320 - -void MatchFinder_Construct(CMatchFinder *p) -{ - UInt32 i; - p->bufferBase = NULL; - p->directInput = 0; - p->hash = NULL; - MatchFinder_SetDefaultSettings(p); - - for (i = 0; i < 256; i++) - { - UInt32 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - p->crc[i] = r; - } -} - -static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->hash); - p->hash = NULL; -} - -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -{ - MatchFinder_FreeThisClassMemory(p, alloc); - LzInWindow_Free(p, alloc); -} - -static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) -{ - size_t sizeInBytes = (size_t)num * sizeof(CLzRef); - if (sizeInBytes / sizeof(CLzRef) != num) - return NULL; - return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -} - -int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc) -{ - UInt32 sizeReserv; - - if (historySize > kMaxHistorySize) - { - MatchFinder_Free(p, alloc); - return 0; - } - - sizeReserv = historySize >> 1; - if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3; - else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2; - - sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); - - p->keepSizeBefore = historySize + keepAddBufferBefore + 1; - p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; - - /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ - - if (LzInWindow_Create(p, sizeReserv, alloc)) - { - UInt32 newCyclicBufferSize = historySize + 1; - UInt32 hs; - p->matchMaxLen = matchMaxLen; - { - p->fixedHashSize = 0; - if (p->numHashBytes == 2) - hs = (1 << 16) - 1; - else - { - hs = historySize - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; /* don't change it! It's required for Deflate */ - if (hs > (1 << 24)) - { - if (p->numHashBytes == 3) - hs = (1 << 24) - 1; - else - hs >>= 1; - /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ - } - } - p->hashMask = hs; - hs++; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; - hs += p->fixedHashSize; - } - - { - size_t newSize; - size_t numSons; - p->historySize = historySize; - p->hashSizeSum = hs; - p->cyclicBufferSize = newCyclicBufferSize; - - numSons = newCyclicBufferSize; - if (p->btMode) - numSons <<= 1; - newSize = hs + numSons; - - if (p->hash && p->numRefs == newSize) - return 1; - - MatchFinder_FreeThisClassMemory(p, alloc); - p->numRefs = newSize; - p->hash = AllocRefs(newSize, alloc); - - if (p->hash) - { - p->son = p->hash + p->hashSizeSum; - return 1; - } - } - } - - MatchFinder_Free(p, alloc); - return 0; -} - -static void MatchFinder_SetLimits(CMatchFinder *p) -{ - UInt32 limit = kMaxValForNormalize - p->pos; - UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; - - if (limit2 < limit) - limit = limit2; - limit2 = p->streamPos - p->pos; - - if (limit2 <= p->keepSizeAfter) - { - if (limit2 > 0) - limit2 = 1; - } - else - limit2 -= p->keepSizeAfter; - - if (limit2 < limit) - limit = limit2; - - { - UInt32 lenLimit = p->streamPos - p->pos; - if (lenLimit > p->matchMaxLen) - lenLimit = p->matchMaxLen; - p->lenLimit = lenLimit; - } - p->posLimit = p->pos + limit; -} - -void MatchFinder_Init_2(CMatchFinder *p, int readData) -{ - UInt32 i; - UInt32 *hash = p->hash; - UInt32 num = p->hashSizeSum; - for (i = 0; i < num; i++) - hash[i] = kEmptyHashValue; - - p->cyclicBufferPos = 0; - p->buffer = p->bufferBase; - p->pos = p->streamPos = p->cyclicBufferSize; - p->result = SZ_OK; - p->streamEndWasReached = 0; - - if (readData) - MatchFinder_ReadBlock(p); - - MatchFinder_SetLimits(p); -} - -void MatchFinder_Init(CMatchFinder *p) -{ - MatchFinder_Init_2(p, True); -} - -static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -{ - return (p->pos - p->historySize - 1) & kNormalizeMask; -} - -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) -{ - size_t i; - for (i = 0; i < numItems; i++) - { - UInt32 value = items[i]; - if (value <= subValue) - value = kEmptyHashValue; - else - value -= subValue; - items[i] = value; - } -} - -static void MatchFinder_Normalize(CMatchFinder *p) -{ - UInt32 subValue = MatchFinder_GetSubValue(p); - MatchFinder_Normalize3(subValue, p->hash, p->numRefs); - MatchFinder_ReduceOffsets(p, subValue); -} - -static void MatchFinder_CheckLimits(CMatchFinder *p) -{ - if (p->pos == kMaxValForNormalize) - MatchFinder_Normalize(p); - if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) - MatchFinder_CheckAndMoveAndRead(p); - if (p->cyclicBufferPos == p->cyclicBufferSize) - p->cyclicBufferPos = 0; - MatchFinder_SetLimits(p); -} - -static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) -{ - son[_cyclicBufferPos] = curMatch; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - return distances; - { - const Byte *pb = cur - delta; - curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; - if (pb[maxLen] == cur[maxLen] && *pb == *cur) - { - UInt32 len = 0; - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - return distances; - } - } - } - } -} - -UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, - UInt32 *distances, UInt32 maxLen) -{ - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - return distances; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - if (++len != lenLimit && pb[len] == cur[len]) - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return distances; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } -} - -static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -{ - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - return; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - { - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } -} - -#define MOVE_POS \ - ++p->cyclicBufferPos; \ - p->buffer++; \ - if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); - -#define MOVE_POS_RET MOVE_POS return offset; - -static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } - -#define GET_MATCHES_HEADER2(minLen, ret_op) \ - UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \ - lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ - cur = p->buffer; - -#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) - -#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue - -#define GET_MATCHES_FOOTER(offset, maxLen) \ - offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ - distances + offset, maxLen) - distances); MOVE_POS_RET; - -#define SKIP_FOOTER \ - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; - -#define UPDATE_maxLen { \ - ptrdiff_t diff = (ptrdiff_t)0 - d2; \ - const Byte *c = cur + maxLen; \ - const Byte *lim = cur + lenLimit; \ - for (; c != lim; c++) if (*(c + diff) != *c) break; \ - maxLen = (UInt32)(c - cur); } - -static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 1) -} - -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - offset = 0; - GET_MATCHES_FOOTER(offset, 2) -} - -static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 h2, d2, maxLen, offset, pos; - UInt32 *hash; - GET_MATCHES_HEADER(3) - - HASH3_CALC; - - hash = p->hash; - pos = p->pos; - - d2 = pos - hash[h2]; - - curMatch = hash[kFix3HashSize + hv]; - - hash[h2] = pos; - hash[kFix3HashSize + hv] = pos; - - maxLen = 2; - offset = 0; - - if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) - { - UPDATE_maxLen - distances[0] = maxLen; - distances[1] = d2 - 1; - offset = 2; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } - } - - GET_MATCHES_FOOTER(offset, maxLen) -} - -static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 h2, h3, d2, d3, maxLen, offset, pos; - UInt32 *hash; - GET_MATCHES_HEADER(4) - - HASH4_CALC; - - hash = p->hash; - pos = p->pos; - - d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - - curMatch = hash[kFix4HashSize + hv]; - - hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + hv] = pos; - - maxLen = 0; - offset = 0; - - if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = d2 - 1; - offset = 2; - } - - if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - maxLen = 3; - distances[offset + 1] = d3 - 1; - offset += 2; - d2 = d3; - } - - if (offset != 0) - { - UPDATE_maxLen - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } - } - - if (maxLen < 3) - maxLen = 3; - - GET_MATCHES_FOOTER(offset, maxLen) -} - -/* -static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos; - UInt32 *hash; - GET_MATCHES_HEADER(5) - - HASH5_CALC; - - hash = p->hash; - pos = p->pos; - - d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - d4 = pos - hash[kFix4HashSize + h4]; - - curMatch = hash[kFix5HashSize + hv]; - - hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + h4] = pos; - hash[kFix5HashSize + hv] = pos; - - maxLen = 0; - offset = 0; - - if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = d2 - 1; - offset = 2; - if (*(cur - d2 + 2) == cur[2]) - distances[0] = maxLen = 3; - else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - distances[2] = maxLen = 3; - distances[3] = d3 - 1; - offset = 4; - d2 = d3; - } - } - else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - distances[0] = maxLen = 3; - distances[1] = d3 - 1; - offset = 2; - d2 = d3; - } - - if (d2 != d4 && d4 < p->cyclicBufferSize - && *(cur - d4) == *cur - && *(cur - d4 + 3) == *(cur + 3)) - { - maxLen = 4; - distances[offset + 1] = d4 - 1; - offset += 2; - d2 = d4; - } - - if (offset != 0) - { - UPDATE_maxLen - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); - MOVE_POS_RET; - } - } - - if (maxLen < 4) - maxLen = 4; - - GET_MATCHES_FOOTER(offset, maxLen) -} -*/ - -static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 h2, h3, d2, d3, maxLen, offset, pos; - UInt32 *hash; - GET_MATCHES_HEADER(4) - - HASH4_CALC; - - hash = p->hash; - pos = p->pos; - - d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - - curMatch = hash[kFix4HashSize + hv]; - - hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + hv] = pos; - - maxLen = 0; - offset = 0; - - if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = d2 - 1; - offset = 2; - } - - if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - maxLen = 3; - distances[offset + 1] = d3 - 1; - offset += 2; - d2 = d3; - } - - if (offset != 0) - { - UPDATE_maxLen - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; - } - } - - if (maxLen < 3) - maxLen = 3; - - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances + offset, maxLen) - (distances)); - MOVE_POS_RET -} - -/* -static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos - UInt32 *hash; - GET_MATCHES_HEADER(5) - - HASH5_CALC; - - hash = p->hash; - pos = p->pos; - - d2 = pos - hash[ h2]; - d3 = pos - hash[kFix3HashSize + h3]; - d4 = pos - hash[kFix4HashSize + h4]; - - curMatch = hash[kFix5HashSize + hv]; - - hash[ h2] = pos; - hash[kFix3HashSize + h3] = pos; - hash[kFix4HashSize + h4] = pos; - hash[kFix5HashSize + hv] = pos; - - maxLen = 0; - offset = 0; - - if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) - { - distances[0] = maxLen = 2; - distances[1] = d2 - 1; - offset = 2; - if (*(cur - d2 + 2) == cur[2]) - distances[0] = maxLen = 3; - else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - distances[2] = maxLen = 3; - distances[3] = d3 - 1; - offset = 4; - d2 = d3; - } - } - else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) - { - distances[0] = maxLen = 3; - distances[1] = d3 - 1; - offset = 2; - d2 = d3; - } - - if (d2 != d4 && d4 < p->cyclicBufferSize - && *(cur - d4) == *cur - && *(cur - d4 + 3) == *(cur + 3)) - { - maxLen = 4; - distances[offset + 1] = d4 - 1; - offset += 2; - d2 = d4; - } - - if (offset != 0) - { - UPDATE_maxLen - distances[offset - 2] = maxLen; - if (maxLen == lenLimit) - { - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; - } - } - - if (maxLen < 4) - maxLen = 4; - - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances + offset, maxLen) - (distances)); - MOVE_POS_RET -} -*/ - -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -{ - UInt32 offset; - GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), - distances, 2) - (distances)); - MOVE_POS_RET -} - -static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(2) - HASH2_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 h2; - UInt32 *hash; - SKIP_HEADER(3) - HASH3_CALC; - hash = p->hash; - curMatch = hash[kFix3HashSize + hv]; - hash[h2] = - hash[kFix3HashSize + hv] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 h2, h3; - UInt32 *hash; - SKIP_HEADER(4) - HASH4_CALC; - hash = p->hash; - curMatch = hash[kFix4HashSize + hv]; - hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + hv] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} - -/* -static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 h2, h3, h4; - UInt32 *hash; - SKIP_HEADER(5) - HASH5_CALC; - hash = p->hash; - curMatch = hash[kFix5HashSize + hv]; - hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + h4] = - hash[kFix5HashSize + hv] = p->pos; - SKIP_FOOTER - } - while (--num != 0); -} -*/ - -static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 h2, h3; - UInt32 *hash; - SKIP_HEADER(4) - HASH4_CALC; - hash = p->hash; - curMatch = hash[kFix4HashSize + hv]; - hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + hv] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } - while (--num != 0); -} - -/* -static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - UInt32 h2, h3, h4; - UInt32 *hash; - SKIP_HEADER(5) - HASH5_CALC; - hash = p->hash; - curMatch = p->hash[kFix5HashSize + hv]; - hash[ h2] = - hash[kFix3HashSize + h3] = - hash[kFix4HashSize + h4] = - hash[kFix5HashSize + hv] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } - while (--num != 0); -} -*/ - -void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -{ - do - { - SKIP_HEADER(3) - HASH_ZIP_CALC; - curMatch = p->hash[hv]; - p->hash[hv] = p->pos; - p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS - } - while (--num != 0); -} - -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -{ - vTable->Init = (Mf_Init_Func)MatchFinder_Init; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; - if (!p->btMode) - { - /* if (p->numHashBytes <= 4) */ - { - vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; - } - /* - else - { - vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip; - } - */ - } - else if (p->numHashBytes == 2) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; - } - else if (p->numHashBytes == 3) - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; - } - else /* if (p->numHashBytes == 4) */ - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; - } - /* - else - { - vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches; - vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip; - } - */ -} +/* LzFind.c -- Match finder for LZ algorithms +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +// #include + +#include "CpuArch.h" +#include "LzFind.h" +#include "LzHash.h" + +#define kBlockMoveAlign (1 << 7) // alignment for memmove() +#define kBlockSizeAlign (1 << 16) // alignment for block allocation +#define kBlockSizeReserveMin (1 << 24) // it's 1/256 from 4 GB dictinary + +#define kEmptyHashValue 0 + +#define kMaxValForNormalize ((UInt32)0) +// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xfff) // for debug + +// #define kNormalizeAlign (1 << 7) // alignment for speculated accesses + +#define GET_AVAIL_BYTES(p) \ + Inline_MatchFinder_GetNumAvailableBytes(p) + + +// #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) +#define kFix5HashSize kFix4HashSize + +/* + HASH2_CALC: + if (hv) match, then cur[0] and cur[1] also match +*/ +#define HASH2_CALC hv = GetUi16(cur); + +// (crc[0 ... 255] & 0xFF) provides one-to-one correspondence to [0 ... 255] + +/* + HASH3_CALC: + if (cur[0]) and (h2) match, then cur[1] also match + if (cur[0]) and (hv) match, then cur[1] and cur[2] also match +*/ +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + hv = (temp ^ (p->crc[cur[3]] << kLzHash_CrcShift_1)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + temp ^= (p->crc[cur[3]] << kLzHash_CrcShift_1); \ + /* h4 = temp & p->hash4Mask; */ /* (kHash4Size - 1); */ \ + hv = (temp ^ (p->crc[cur[4]] << kLzHash_CrcShift_2)) & p->hashMask; } + +#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) +{ + // if (!p->directInput) + { + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; + } +} + + +static int LzInWindow_Create2(CMatchFinder *p, UInt32 blockSize, ISzAllocPtr alloc) +{ + if (blockSize == 0) + return 0; + if (!p->bufBase || p->blockSize != blockSize) + { + // size_t blockSizeT; + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + // blockSizeT = blockSize; + + // printf("\nblockSize = 0x%x\n", blockSize); + /* + #if defined _WIN64 + // we can allocate 4GiB, but still use UInt32 for (p->blockSize) + // we use UInt32 type for (p->blockSize), because + // we don't want to wrap over 4 GiB, + // when we use (p->streamPos - p->pos) that is UInt32. + if (blockSize >= (UInt32)0 - (UInt32)kBlockSizeAlign) + { + blockSizeT = ((size_t)1 << 32); + printf("\nchanged to blockSizeT = 4GiB\n"); + } + #endif + */ + + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); + // printf("\nbufferBase = %p\n", p->bufBase); + // return 0; // for debug + } + return (p->bufBase != NULL); +} + +static const Byte *MatchFinder_GetPointerToCurrentPos(void *p) +{ + return ((CMatchFinder *)p)->buffer; +} + +static UInt32 MatchFinder_GetNumAvailableBytes(void *p) +{ + return GET_AVAIL_BYTES((CMatchFinder *)p); +} + + +Z7_NO_INLINE +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + + /* We use (p->streamPos - p->pos) value. + (p->streamPos < p->pos) is allowed. */ + + if (p->directInput) + { + UInt32 curSize = 0xFFFFFFFF - GET_AVAIL_BYTES(p); + if (curSize > p->directInputRem) + curSize = (UInt32)p->directInputRem; + p->streamPos += curSize; + p->directInputRem -= curSize; + if (p->directInputRem == 0) + p->streamEndWasReached = 1; + return; + } + + for (;;) + { + const Byte *dest = p->buffer + GET_AVAIL_BYTES(p); + size_t size = (size_t)(p->bufBase + p->blockSize - dest); + if (size == 0) + { + /* we call ReadBlock() after NeedMove() and MoveBlock(). + NeedMove() and MoveBlock() povide more than (keepSizeAfter) + to the end of (blockSize). + So we don't execute this branch in normal code flow. + We can go here, if we will call ReadBlock() before NeedMove(), MoveBlock(). + */ + // p->result = SZ_ERROR_FAIL; // we can show error here + return; + } + + // #define kRead 3 + // if (size > kRead) size = kRead; // for debug + + /* + // we need cast (Byte *)dest. + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + */ + p->result = ISeqInStream_Read(p->stream, + p->bufBase + (dest - p->bufBase), &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (GET_AVAIL_BYTES(p) > p->keepSizeAfter) + return; + /* here and in another (p->keepSizeAfter) checks we keep on 1 byte more than was requested by Create() function + (GET_AVAIL_BYTES(p) >= p->keepSizeAfter) - minimal required size */ + } + + // on exit: (p->result != SZ_OK || p->streamEndWasReached || GET_AVAIL_BYTES(p) > p->keepSizeAfter) +} + + + +Z7_NO_INLINE +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + const size_t offset = (size_t)(p->buffer - p->bufBase) - p->keepSizeBefore; + const size_t keepBefore = (offset & (kBlockMoveAlign - 1)) + p->keepSizeBefore; + p->buffer = p->bufBase + keepBefore; + memmove(p->bufBase, + p->bufBase + (offset & ~((size_t)kBlockMoveAlign - 1)), + keepBefore + (size_t)GET_AVAIL_BYTES(p)); +} + +/* We call MoveBlock() before ReadBlock(). + So MoveBlock() can be wasteful operation, if the whole input data + can fit in current block even without calling MoveBlock(). + in important case where (dataSize <= historySize) + condition (p->blockSize > dataSize + p->keepSizeAfter) is met + So there is no MoveBlock() in that case case. +*/ + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + if (p->directInput) + return 0; + if (p->streamEndWasReached || p->result != SZ_OK) + return 0; + return ((size_t)(p->bufBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->keepSizeAfter >= GET_AVAIL_BYTES(p)) + MatchFinder_ReadBlock(p); +} + + + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + p->numHashBytes_Min = 2; + p->numHashOutBits = 0; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + unsigned i; + p->buffer = NULL; + p->bufBase = NULL; + p->directInput = 0; + p->stream = NULL; + p->hash = NULL; + p->expectedDataSize = (UInt64)(Int64)-1; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = (UInt32)i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + p->crc[i] = r; + } +} + +#undef kCrcPoly + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->hash); + p->hash = NULL; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) +{ + const size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return NULL; + return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); +} + +#if (kBlockSizeReserveMin < kBlockSizeAlign * 2) + #error Stop_Compiling_Bad_Reserve +#endif + + + +static UInt32 GetBlockSize(CMatchFinder *p, UInt32 historySize) +{ + UInt32 blockSize = (p->keepSizeBefore + p->keepSizeAfter); + /* + if (historySize > kMaxHistorySize) + return 0; + */ + // printf("\nhistorySize == 0x%x\n", historySize); + + if (p->keepSizeBefore < historySize || blockSize < p->keepSizeBefore) // if 32-bit overflow + return 0; + + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)kBlockSizeAlign; + const UInt32 rem = kBlockSizeMax - blockSize; + const UInt32 reserve = (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)) + + (1 << 12) + kBlockMoveAlign + kBlockSizeAlign; // do not overflow 32-bit here + if (blockSize >= kBlockSizeMax + || rem < kBlockSizeReserveMin) // we reject settings that will be slow + return 0; + if (reserve >= rem) + blockSize = kBlockSizeMax; + else + { + blockSize += reserve; + blockSize &= ~(UInt32)(kBlockSizeAlign - 1); + } + } + // printf("\n LzFind_blockSize = %x\n", blockSize); + // printf("\n LzFind_blockSize = %d\n", blockSize >> 20); + return blockSize; +} + + +// input is historySize +static UInt32 MatchFinder_GetHashMask2(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + +// input is historySize +static UInt32 MatchFinder_GetHashMask(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + hs >>= 1; + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAllocPtr alloc) +{ + /* we need one additional byte in (p->keepSizeBefore), + since we use MoveBlock() after (p->pos++) and before dictionary using */ + // keepAddBufferBefore = (UInt32)0xFFFFFFFF - (1 << 22); // for debug + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + + keepAddBufferAfter += matchMaxLen; + /* we need (p->keepSizeAfter >= p->numHashBytes) */ + if (keepAddBufferAfter < p->numHashBytes) + keepAddBufferAfter = p->numHashBytes; + // keepAddBufferAfter -= 2; // for debug + p->keepSizeAfter = keepAddBufferAfter; + + if (p->directInput) + p->blockSize = 0; + if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc)) + { + size_t hashSizeSum; + { + UInt32 hs; + UInt32 hsCur; + + if (p->numHashOutBits != 0) + { + unsigned numBits = p->numHashOutBits; + const unsigned nbMax = + (p->numHashBytes == 2 ? 16 : + (p->numHashBytes == 3 ? 24 : 32)); + if (numBits >= nbMax) + numBits = nbMax; + if (numBits >= 32) + hs = (UInt32)0 - 1; + else + hs = ((UInt32)1 << numBits) - 1; + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize); + if (hs >= hs2) + hs = hs2; + } + hsCur = hs; + if (p->expectedDataSize < historySize) + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize); + if (hsCur >= hs2) + hsCur = hs2; + } + } + else + { + hs = MatchFinder_GetHashMask(p, historySize); + hsCur = hs; + if (p->expectedDataSize < historySize) + { + hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize); + if (hsCur >= hs) // is it possible? + hsCur = hs; + } + } + + p->hashMask = hsCur; + + hashSizeSum = hs; + hashSizeSum++; + if (hashSizeSum < hs) + return 0; + { + UInt32 fixedHashSize = 0; + if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size; + if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size; + // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; + hashSizeSum += fixedHashSize; + p->fixedHashSize = fixedHashSize; + } + } + + p->matchMaxLen = matchMaxLen; + + { + size_t newSize; + size_t numSons; + const UInt32 newCyclicBufferSize = historySize + 1; // do not change it + p->historySize = historySize; + p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1) + + numSons = newCyclicBufferSize; + if (p->btMode) + numSons <<= 1; + newSize = hashSizeSum + numSons; + + if (numSons < newCyclicBufferSize || newSize < numSons) + return 0; + + // aligned size is not required here, but it can be better for some loops + #define NUM_REFS_ALIGN_MASK 0xF + newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK; + + // 22.02: we don't reallocate buffer, if old size is enough + if (p->hash && p->numRefs >= newSize) + return 1; + + MatchFinder_FreeThisClassMemory(p, alloc); + p->numRefs = newSize; + p->hash = AllocRefs(newSize, alloc); + + if (p->hash) + { + p->son = p->hash + hashSizeSum; + return 1; + } + } + } + + MatchFinder_Free(p, alloc); + return 0; +} + + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 k; + UInt32 n = kMaxValForNormalize - p->pos; + if (n == 0) + n = (UInt32)(Int32)-1; // we allow (pos == 0) at start even with (kMaxValForNormalize == 0) + + k = p->cyclicBufferSize - p->cyclicBufferPos; + if (k < n) + n = k; + + k = GET_AVAIL_BYTES(p); + { + const UInt32 ksa = p->keepSizeAfter; + UInt32 mm = p->matchMaxLen; + if (k > ksa) + k -= ksa; // we must limit exactly to keepSizeAfter for ReadBlock + else if (k >= mm) + { + // the limitation for (p->lenLimit) update + k -= mm; // optimization : to reduce the number of checks + k++; + // k = 1; // non-optimized version : for debug + } + else + { + mm = k; + if (k != 0) + k = 1; + } + p->lenLimit = mm; + } + if (k < n) + n = k; + + p->posLimit = p->pos + n; +} + + +void MatchFinder_Init_LowHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash; + const size_t numItems = p->fixedHashSize; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_HighHash(CMatchFinder *p) +{ + size_t i; + CLzRef *items = p->hash + p->fixedHashSize; + const size_t numItems = (size_t)p->hashMask + 1; + for (i = 0; i < numItems; i++) + items[i] = kEmptyHashValue; +} + + +void MatchFinder_Init_4(CMatchFinder *p) +{ + if (!p->directInput) + p->buffer = p->bufBase; + { + /* kEmptyHashValue = 0 (Zero) is used in hash tables as NO-VALUE marker. + the code in CMatchFinderMt expects (pos = 1) */ + p->pos = + p->streamPos = + 1; // it's smallest optimal value. do not change it + // 0; // for debug + } + p->result = SZ_OK; + p->streamEndWasReached = 0; +} + + +// (CYC_TO_POS_OFFSET == 0) is expected by some optimized code +#define CYC_TO_POS_OFFSET 0 +// #define CYC_TO_POS_OFFSET 1 // for debug + +void MatchFinder_Init(void *_p) +{ + CMatchFinder *p = (CMatchFinder *)_p; + MatchFinder_Init_HighHash(p); + MatchFinder_Init_LowHash(p); + MatchFinder_Init_4(p); + // if (readData) + MatchFinder_ReadBlock(p); + + /* if we init (cyclicBufferPos = pos), then we can use one variable + instead of both (cyclicBufferPos) and (pos) : only before (cyclicBufferPos) wrapping */ + p->cyclicBufferPos = (p->pos - CYC_TO_POS_OFFSET); // init with relation to (pos) + // p->cyclicBufferPos = 0; // smallest value + // p->son[0] = p->son[1] = 0; // unused: we can init skipped record for speculated accesses. + MatchFinder_SetLimits(p); +} + + + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + // || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + + #define USE_LZFIND_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_256 + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) + #define LZFIND_ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1600) + #define USE_LZFIND_SATUR_SUB_128 + #endif + #if (_MSC_VER >= 1900) + #define USE_LZFIND_SATUR_SUB_256 + #endif + #endif + +#elif defined(MY_CPU_ARM64) \ + /* || (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) */ + + #if defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) + #define USE_LZFIND_SATUR_SUB_128 + #ifdef MY_CPU_ARM64 + // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__(""))) + #else + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=neon"))) + #endif + + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1910) + #define USE_LZFIND_SATUR_SUB_128 + #endif + #endif + + #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) + #include + #else + #include + #endif + +#endif + + +#ifdef USE_LZFIND_SATUR_SUB_128 + +// #define Z7_SHOW_HW_STATUS + +#ifdef Z7_SHOW_HW_STATUS +#include +#define PRF(x) x +PRF(;) +#else +#define PRF(x) +#endif + + +#ifdef MY_CPU_ARM_OR_ARM64 + +#ifdef MY_CPU_ARM64 +// #define FORCE_LZFIND_SATUR_SUB_128 +#endif +typedef uint32x4_t LzFind_v128; +#define SASUB_128_V(v, s) \ + vsubq_u32(vmaxq_u32(v, s), s) + +#else // MY_CPU_ARM_OR_ARM64 + +#include // sse4.1 + +typedef __m128i LzFind_v128; +// SSE 4.1 +#define SASUB_128_V(v, s) \ + _mm_sub_epi32(_mm_max_epu32(v, s), s) + +#endif // MY_CPU_ARM_OR_ARM64 + + +#define SASUB_128(i) \ + *( LzFind_v128 *)( void *)(items + (i) * 4) = SASUB_128_V( \ + *(const LzFind_v128 *)(const void *)(items + (i) * 4), sub2); + + +Z7_NO_INLINE +static +#ifdef LZFIND_ATTRIB_SSE41 +LZFIND_ATTRIB_SSE41 +#endif +void +Z7_FASTCALL +LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + const LzFind_v128 sub2 = + #ifdef MY_CPU_ARM_OR_ARM64 + vdupq_n_u32(subValue); + #else + _mm_set_epi32((Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + #endif + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_128(0) SASUB_128(1) items += 2 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; + } + while (items != lim); +} + + + +#ifdef USE_LZFIND_SATUR_SUB_256 + +#include // avx +/* +clang :immintrin.h uses +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__AVX2__) +#include +#endif +so we need for clang-cl */ + +#if defined(__clang__) +#include +#include +#endif + +// AVX2: +#define SASUB_256(i) \ + *( __m256i *)( void *)(items + (i) * 8) = \ + _mm256_sub_epi32(_mm256_max_epu32( \ + *(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); + +Z7_NO_INLINE +static +#ifdef LZFIND_ATTRIB_AVX2 +LZFIND_ATTRIB_AVX2 +#endif +void +Z7_FASTCALL +LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + const __m256i sub2 = _mm256_set_epi32( + (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, + (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_256(0) SASUB_256(1) items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; + } + while (items != lim); +} +#endif // USE_LZFIND_SATUR_SUB_256 + +#ifndef FORCE_LZFIND_SATUR_SUB_128 +typedef void (Z7_FASTCALL *LZFIND_SATUR_SUB_CODE_FUNC)( + UInt32 subValue, CLzRef *items, const CLzRef *lim); +static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub; +#endif // FORCE_LZFIND_SATUR_SUB_128 + +#endif // USE_LZFIND_SATUR_SUB_128 + + +// kEmptyHashValue must be zero +// #define SASUB_32(i) { UInt32 v = items[i]; UInt32 m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; } +#define SASUB_32(i) { UInt32 v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; } + +#ifdef FORCE_LZFIND_SATUR_SUB_128 + +#define DEFAULT_SaturSub LzFind_SaturSub_128 + +#else + +#define DEFAULT_SaturSub LzFind_SaturSub_32 + +Z7_NO_INLINE +static +void +Z7_FASTCALL +LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + } + while (items != lim); +} + +#endif + + +Z7_NO_INLINE +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) +{ + #define LZFIND_NORM_ALIGN_BLOCK_SIZE (1 << 7) + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (LZFIND_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) + { + SASUB_32(0) + items++; + } + { + const size_t k_Align_Mask = (LZFIND_NORM_ALIGN_BLOCK_SIZE / 4 - 1); + CLzRef *lim = items + (numItems & ~(size_t)k_Align_Mask); + numItems &= k_Align_Mask; + if (items != lim) + { + #if defined(USE_LZFIND_SATUR_SUB_128) && !defined(FORCE_LZFIND_SATUR_SUB_128) + if (g_LzFind_SaturSub) + g_LzFind_SaturSub(subValue, items, lim); + else + #endif + DEFAULT_SaturSub(subValue, items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SASUB_32(0) + items++; + } +} + + + +// call MatchFinder_CheckLimits() only after (p->pos++) update + +Z7_NO_INLINE +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (// !p->streamEndWasReached && p->result == SZ_OK && + p->keepSizeAfter == GET_AVAIL_BYTES(p)) + { + // we try to read only in exact state (p->keepSizeAfter == GET_AVAIL_BYTES(p)) + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); + } + + if (p->pos == kMaxValForNormalize) + if (GET_AVAIL_BYTES(p) >= p->numHashBytes) // optional optimization for last bytes of data. + /* + if we disable normalization for last bytes of data, and + if (data_size == 4 GiB), we don't call wastfull normalization, + but (pos) will be wrapped over Zero (0) in that case. + And we cannot resume later to normal operation + */ + { + // MatchFinder_Normalize(p); + /* after normalization we need (p->pos >= p->historySize + 1); */ + /* we can reduce subValue to aligned value, if want to keep alignment + of (p->pos) and (p->buffer) for speculated accesses. */ + const UInt32 subValue = (p->pos - p->historySize - 1) /* & ~(UInt32)(kNormalizeAlign - 1) */; + // const UInt32 subValue = (1 << 15); // for debug + // printf("\nMatchFinder_Normalize() subValue == 0x%x\n", subValue); + MatchFinder_REDUCE_OFFSETS(p, subValue) + MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashMask + 1 + p->fixedHashSize); + { + size_t numSonRefs = p->cyclicBufferSize; + if (p->btMode) + numSonRefs <<= 1; + MatchFinder_Normalize3(subValue, p->son, numSonRefs); + } + } + + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + + MatchFinder_SetLimits(p); +} + + +/* + (lenLimit > maxLen) +*/ +Z7_FORCE_INLINE +static UInt32 * Hc_GetMatchesSpec(size_t lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *d, unsigned maxLen) +{ + /* + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return d; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = len; + *d++ = len; + *d++ = delta - 1; + if (len == lenLimit) + return d; + } + } + } + } + */ + + const Byte *lim = cur + lenLimit; + son[_cyclicBufferPos] = curMatch; + + do + { + UInt32 delta; + + if (curMatch == 0) + break; + // if (curMatch2 >= curMatch) return NULL; + delta = pos - curMatch; + if (delta >= _cyclicBufferSize) + break; + { + ptrdiff_t diff; + curMatch = son[_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)]; + diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + if (cur[maxLen] == cur[(ptrdiff_t)maxLen + diff]) + { + const Byte *c = cur; + while (*c == c[diff]) + { + if (++c == lim) + { + d[0] = (UInt32)(lim - cur); + d[1] = delta - 1; + return d + 2; + } + } + { + const unsigned len = (unsigned)(c - cur); + if (maxLen < len) + { + maxLen = len; + d[0] = (UInt32)len; + d[1] = delta - 1; + d += 2; + } + } + } + } + } + while (--cutValue); + + return d; +} + + +Z7_FORCE_INLINE +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *d, UInt32 maxLen) +{ + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + + UInt32 cmCheck; + + // if (curMatch >= pos) { *ptr0 = *ptr1 = kEmptyHashValue; return NULL; } + + cmCheck = (UInt32)(pos - _cyclicBufferSize); + if ((UInt32)pos < _cyclicBufferSize) + cmCheck = 0; + + if (cmCheck < curMatch) + do + { + const UInt32 delta = pos - curMatch; + { + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + const UInt32 pair0 = pair[0]; + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = (UInt32)len; + *d++ = (UInt32)len; + *d++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair0; + *ptr0 = pair[1]; + return d; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + // const UInt32 curMatch2 = pair[1]; + // if (curMatch2 >= curMatch) { *ptr0 = *ptr1 = kEmptyHashValue; return NULL; } + // curMatch = curMatch2; + curMatch = pair[1]; + ptr1 = pair + 1; + len1 = len; + } + else + { + *ptr0 = curMatch; + curMatch = pair[0]; + ptr0 = pair; + len0 = len; + } + } + } + while(--cutValue && cmCheck < curMatch); + + *ptr0 = *ptr1 = kEmptyHashValue; + return d; +} + + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + unsigned len0 = 0, len1 = 0; + + UInt32 cmCheck; + + cmCheck = (UInt32)(pos - _cyclicBufferSize); + if ((UInt32)pos < _cyclicBufferSize) + cmCheck = 0; + + if (// curMatch >= pos || // failure + cmCheck < curMatch) + do + { + const UInt32 delta = pos - curMatch; + { + CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + (_cyclicBufferPos < delta ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + unsigned len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + curMatch = pair[1]; + ptr1 = pair + 1; + len1 = len; + } + else + { + *ptr0 = curMatch; + curMatch = pair[0]; + ptr0 = pair; + len0 = len; + } + } + } + while(--cutValue && cmCheck < curMatch); + + *ptr0 = *ptr1 = kEmptyHashValue; + return; +} + + +#define MOVE_POS \ + p->cyclicBufferPos++; \ + p->buffer++; \ + { const UInt32 pos1 = p->pos + 1; \ + p->pos = pos1; \ + if (pos1 == p->posLimit) MatchFinder_CheckLimits(p); } + +#define MOVE_POS_RET MOVE_POS return distances; + +Z7_NO_INLINE +static void MatchFinder_MovePos(CMatchFinder *p) +{ + /* we go here at the end of stream data, when (avail < num_hash_bytes) + We don't update sons[cyclicBufferPos << btMode]. + So (sons) record will contain junk. And we cannot resume match searching + to normal operation, even if we will provide more input data in buffer. + p->sons[p->cyclicBufferPos << p->btMode] = 0; // kEmptyHashValue + if (p->btMode) + p->sons[(p->cyclicBufferPos << p->btMode) + 1] = 0; // kEmptyHashValue + */ + MOVE_POS +} + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + UInt32 hv; const Byte *cur; UInt32 curMatch; \ + UInt32 lenLimit = p->lenLimit; \ + if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; } \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return distances) +#define SKIP_HEADER(minLen) \ + do { GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, \ + p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define SKIP_FOOTER \ + SkipMatchesSpec(MF_PARAMS(p)); \ + MOVE_POS \ + } while (--num); + +#define GET_MATCHES_FOOTER_BASE(_maxLen_, func) \ + distances = func(MF_PARAMS(p), distances, (UInt32)_maxLen_); \ + MOVE_POS_RET + +#define GET_MATCHES_FOOTER_BT(_maxLen_) \ + GET_MATCHES_FOOTER_BASE(_maxLen_, GetMatchesSpec1) + +#define GET_MATCHES_FOOTER_HC(_maxLen_) \ + GET_MATCHES_FOOTER_BASE(_maxLen_, Hc_GetMatchesSpec) + + + +#define UPDATE_maxLen { \ + const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)d2; \ + const Byte *c = cur + maxLen; \ + const Byte *lim = cur + lenLimit; \ + for (; c != lim; c++) if (*(c + diff) != *c) break; \ + maxLen = (unsigned)(c - cur); } + +static UInt32* Bt2_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + GET_MATCHES_HEADER(2) + HASH2_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_BT(1) +} + +UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_BT(2) +} + + +#define SET_mmm \ + mmm = p->cyclicBufferSize; \ + if (pos < mmm) \ + mmm = pos; + + +static UInt32* Bt3_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, d2, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(3) + + HASH3_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash[h2]; + + curMatch = (hash + kFix3HashSize)[hv]; + + hash[h2] = pos; + (hash + kFix3HashSize)[hv] = pos; + + SET_mmm + + maxLen = 2; + + if (d2 < mmm && *(cur - d2) == *cur) + { + UPDATE_maxLen + distances[0] = (UInt32)maxLen; + distances[1] = d2 - 1; + distances += 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET + } + } + + GET_MATCHES_FOOTER_BT(maxLen) +} + + +static UInt32* Bt4_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(4) + + HASH4_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + curMatch = (hash + kFix4HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + SET_mmm + + maxLen = 3; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) + { + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + // distances[-2] = 3; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_BT(maxLen) +} + + +static UInt32* Bt5_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(5) + + HASH5_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + // d4 = pos - (hash + kFix4HashSize)[h4]; + + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + // (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + SET_mmm + + maxLen = 4; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) + { + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + + distances[-2] = 3; + if (*(cur - d2 + 3) != cur[3]) + break; + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(MF_PARAMS(p)); + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_BT(maxLen) +} + + +static UInt32* Hc4_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(4) + + HASH4_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + curMatch = (hash + kFix4HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + (hash + kFix4HashSize)[hv] = pos; + + SET_mmm + + maxLen = 3; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) + { + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + // distances[-2] = 3; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + d2 = d3; + distances[1] = d3 - 1; + distances += 2; + } + else + break; + + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_HC(maxLen) +} + + +static UInt32 * Hc5_MatchFinder_GetMatches(void *_p, UInt32 *distances) +{ + CMatchFinder *p = (CMatchFinder *)_p; + UInt32 mmm; + UInt32 h2, h3, d2, d3, pos; + unsigned maxLen; + UInt32 *hash; + GET_MATCHES_HEADER(5) + + HASH5_CALC + + hash = p->hash; + pos = p->pos; + + d2 = pos - hash [h2]; + d3 = pos - (hash + kFix3HashSize)[h3]; + // d4 = pos - (hash + kFix4HashSize)[h4]; + + curMatch = (hash + kFix5HashSize)[hv]; + + hash [h2] = pos; + (hash + kFix3HashSize)[h3] = pos; + // (hash + kFix4HashSize)[h4] = pos; + (hash + kFix5HashSize)[hv] = pos; + + SET_mmm + + maxLen = 4; + + for (;;) + { + if (d2 < mmm && *(cur - d2) == *cur) + { + distances[0] = 2; + distances[1] = d2 - 1; + distances += 2; + if (*(cur - d2 + 2) == cur[2]) + { + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + } + else if (d3 < mmm && *(cur - d3) == *cur) + { + distances[1] = d3 - 1; + distances += 2; + d2 = d3; + } + else + break; + + distances[-2] = 3; + if (*(cur - d2 + 3) != cur[3]) + break; + UPDATE_maxLen + distances[-2] = (UInt32)maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET + } + break; + } + + GET_MATCHES_FOOTER_HC(maxLen) +} + + +UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + GET_MATCHES_FOOTER_HC(2) +} + + +static void Bt2_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(2) + { + HASH2_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + } + SKIP_FOOTER +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + SKIP_HEADER(3) + { + HASH_ZIP_CALC + curMatch = p->hash[hv]; + p->hash[hv] = p->pos; + } + SKIP_FOOTER +} + +static void Bt3_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(3) + { + UInt32 h2; + UInt32 *hash; + HASH3_CALC + hash = p->hash; + curMatch = (hash + kFix3HashSize)[hv]; + hash[h2] = + (hash + kFix3HashSize)[hv] = p->pos; + } + SKIP_FOOTER +} + +static void Bt4_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(4) + { + UInt32 h2, h3; + UInt32 *hash; + HASH4_CALC + hash = p->hash; + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = p->pos; + } + SKIP_FOOTER +} + +static void Bt5_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + SKIP_HEADER(5) + { + UInt32 h2, h3; + UInt32 *hash; + HASH5_CALC + hash = p->hash; + curMatch = (hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + // (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = p->pos; + } + SKIP_FOOTER +} + + +#define HC_SKIP_HEADER(minLen) \ + do { if (p->lenLimit < minLen) { MatchFinder_MovePos(p); num--; continue; } { \ + const Byte *cur; \ + UInt32 *hash; \ + UInt32 *son; \ + UInt32 pos = p->pos; \ + UInt32 num2 = num; \ + /* (p->pos == p->posLimit) is not allowed here !!! */ \ + { const UInt32 rem = p->posLimit - pos; if (num2 >= rem) num2 = rem; } \ + num -= num2; \ + { const UInt32 cycPos = p->cyclicBufferPos; \ + son = p->son + cycPos; \ + p->cyclicBufferPos = cycPos + num2; } \ + cur = p->buffer; \ + hash = p->hash; \ + do { \ + UInt32 curMatch; \ + UInt32 hv; + + +#define HC_SKIP_FOOTER \ + cur++; pos++; *son++ = curMatch; \ + } while (--num2); \ + p->buffer = cur; \ + p->pos = pos; \ + if (pos == p->posLimit) MatchFinder_CheckLimits(p); \ + }} while(num); \ + + +static void Hc4_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + HC_SKIP_HEADER(4) + + UInt32 h2, h3; + HASH4_CALC + curMatch = (hash + kFix4HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + (hash + kFix4HashSize)[hv] = pos; + + HC_SKIP_FOOTER +} + + +static void Hc5_MatchFinder_Skip(void *_p, UInt32 num) +{ + CMatchFinder *p = (CMatchFinder *)_p; + HC_SKIP_HEADER(5) + + UInt32 h2, h3; + HASH5_CALC + curMatch = (hash + kFix5HashSize)[hv]; + hash [h2] = + (hash + kFix3HashSize)[h3] = + // (hash + kFix4HashSize)[h4] = + (hash + kFix5HashSize)[hv] = pos; + + HC_SKIP_FOOTER +} + + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + HC_SKIP_HEADER(3) + + HASH_ZIP_CALC + curMatch = hash[hv]; + hash[hv] = pos; + + HC_SKIP_FOOTER +} + + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable) +{ + vTable->Init = MatchFinder_Init; + vTable->GetNumAvailableBytes = MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + if (p->numHashBytes <= 4) + { + vTable->GetMatches = Hc4_MatchFinder_GetMatches; + vTable->Skip = Hc4_MatchFinder_Skip; + } + else + { + vTable->GetMatches = Hc5_MatchFinder_GetMatches; + vTable->Skip = Hc5_MatchFinder_Skip; + } + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = Bt2_MatchFinder_GetMatches; + vTable->Skip = Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = Bt3_MatchFinder_GetMatches; + vTable->Skip = Bt3_MatchFinder_Skip; + } + else if (p->numHashBytes == 4) + { + vTable->GetMatches = Bt4_MatchFinder_GetMatches; + vTable->Skip = Bt4_MatchFinder_Skip; + } + else + { + vTable->GetMatches = Bt5_MatchFinder_GetMatches; + vTable->Skip = Bt5_MatchFinder_Skip; + } +} + + + +void LzFindPrepare(void) +{ + #ifndef FORCE_LZFIND_SATUR_SUB_128 + #ifdef USE_LZFIND_SATUR_SUB_128 + LZFIND_SATUR_SUB_CODE_FUNC f = NULL; + #ifdef MY_CPU_ARM_OR_ARM64 + { + if (CPU_IsSupported_NEON()) + { + // #pragma message ("=== LzFind NEON") + PRF(printf("\n=== LzFind NEON\n")); + f = LzFind_SaturSub_128; + } + // f = 0; // for debug + } + #else // MY_CPU_ARM_OR_ARM64 + if (CPU_IsSupported_SSE41()) + { + // #pragma message ("=== LzFind SSE41") + PRF(printf("\n=== LzFind SSE41\n")); + f = LzFind_SaturSub_128; + + #ifdef USE_LZFIND_SATUR_SUB_256 + if (CPU_IsSupported_AVX2()) + { + // #pragma message ("=== LzFind AVX2") + PRF(printf("\n=== LzFind AVX2\n")); + f = LzFind_SaturSub_256; + } + #endif + } + #endif // MY_CPU_ARM_OR_ARM64 + g_LzFind_SaturSub = f; + #endif // USE_LZFIND_SATUR_SUB_128 + #endif // FORCE_LZFIND_SATUR_SUB_128 +} + + +#undef MOVE_POS +#undef MOVE_POS_RET +#undef PRF diff -Nru p7zip-rar-16.02/C/LzFind.h p7zip-rar-16.02+really25.00+ds/C/LzFind.h --- p7zip-rar-16.02/C/LzFind.h 2015-10-17 14:52:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzFind.h 2024-01-22 13:00:00.000000000 +0000 @@ -1,117 +1,160 @@ -/* LzFind.h -- Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_H -#define __LZ_FIND_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -typedef UInt32 CLzRef; - -typedef struct _CMatchFinder -{ - Byte *buffer; - UInt32 pos; - UInt32 posLimit; - UInt32 streamPos; - UInt32 lenLimit; - - UInt32 cyclicBufferPos; - UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ - - Byte streamEndWasReached; - Byte btMode; - Byte bigHash; - Byte directInput; - - UInt32 matchMaxLen; - CLzRef *hash; - CLzRef *son; - UInt32 hashMask; - UInt32 cutValue; - - Byte *bufferBase; - ISeqInStream *stream; - - UInt32 blockSize; - UInt32 keepSizeBefore; - UInt32 keepSizeAfter; - - UInt32 numHashBytes; - size_t directInputRem; - UInt32 historySize; - UInt32 fixedHashSize; - UInt32 hashSizeSum; - SRes result; - UInt32 crc[256]; - size_t numRefs; -} CMatchFinder; - -#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) - -#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) - -#define Inline_MatchFinder_IsFinishedOK(p) \ - ((p)->streamEndWasReached \ - && (p)->streamPos == (p)->pos \ - && (!(p)->directInput || (p)->directInputRem == 0)) - -int MatchFinder_NeedMove(CMatchFinder *p); -Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -void MatchFinder_MoveBlock(CMatchFinder *p); -void MatchFinder_ReadIfRequired(CMatchFinder *p); - -void MatchFinder_Construct(CMatchFinder *p); - -/* Conditions: - historySize <= 3 GB - keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -*/ -int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, - UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, - ISzAlloc *alloc); -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); -void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); - -UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, - UInt32 *distances, UInt32 maxLen); - -/* -Conditions: - Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. - Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -*/ - -typedef void (*Mf_Init_Func)(void *object); -typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -typedef void (*Mf_Skip_Func)(void *object, UInt32); - -typedef struct _IMatchFinder -{ - Mf_Init_Func Init; - Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; - Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; - Mf_GetMatches_Func GetMatches; - Mf_Skip_Func Skip; -} IMatchFinder; - -void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); - -void MatchFinder_Init_2(CMatchFinder *p, int readData); -void MatchFinder_Init(CMatchFinder *p); - -UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); - -void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); - -EXTERN_C_END - -#endif +/* LzFind.h -- Match finder for LZ algorithms +2024-01-22 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZ_FIND_H +#define ZIP7_INC_LZ_FIND_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef UInt32 CLzRef; + +typedef struct +{ + const Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */ + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + Byte streamEndWasReached; + Byte btMode; + Byte bigHash; + Byte directInput; + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufBase; + ISeqInStreamPtr stream; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + size_t directInputRem; + UInt32 historySize; + UInt32 fixedHashSize; + Byte numHashBytes_Min; + Byte numHashOutBits; + Byte _pad2_[2]; + SRes result; + UInt32 crc[256]; + size_t numRefs; + + UInt64 expectedDataSize; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((const Byte *)(p)->buffer) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((UInt32)((p)->streamPos - (p)->pos)) + +/* +#define Inline_MatchFinder_IsFinishedOK(p) \ + ((p)->streamEndWasReached \ + && (p)->streamPos == (p)->pos \ + && (!(p)->directInput || (p)->directInputRem == 0)) +*/ + +int MatchFinder_NeedMove(CMatchFinder *p); +/* Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); */ +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* (directInput = 0) is default value. + It's required to provide correct (directInput) value + before calling MatchFinder_Create(). + You can set (directInput) by any of the following calls: + - MatchFinder_SET_DIRECT_INPUT_BUF() + - MatchFinder_SET_STREAM() + - MatchFinder_SET_STREAM_MODE() +*/ + +#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \ + (p)->stream = NULL; \ + (p)->directInput = 1; \ + (p)->buffer = (_src_); \ + (p)->directInputRem = (_srcLen_); } + +/* +#define MatchFinder_SET_STREAM_MODE(p) { \ + (p)->directInput = 0; } +*/ + +#define MatchFinder_SET_STREAM(p, _stream_) { \ + (p)->stream = _stream_; \ + (p)->directInput = 0; } + + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAllocPtr alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); + +/* +#define MatchFinder_INIT_POS(p, val) \ + (p)->pos = (val); \ + (p)->streamPos = (val); +*/ + +// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); +#define MatchFinder_REDUCE_OFFSETS(p, subValue) \ + (p)->pos -= (subValue); \ + (p)->streamPos -= (subValue); + + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct +{ + Mf_Init_Func Init; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder2; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable); + +void MatchFinder_Init_LowHash(CMatchFinder *p); +void MatchFinder_Init_HighHash(CMatchFinder *p); +void MatchFinder_Init_4(CMatchFinder *p); +// void MatchFinder_Init(CMatchFinder *p); +void MatchFinder_Init(void *p); + +UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +void LzFindPrepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/LzFindMt.c p7zip-rar-16.02+really25.00+ds/C/LzFindMt.c --- p7zip-rar-16.02/C/LzFindMt.c 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzFindMt.c 2025-06-30 16:00:00.000000000 +0000 @@ -1,803 +1,1422 @@ -/* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2015-10-15 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "LzHash.h" - -#include "LzFindMt.h" - -static void MtSync_Construct(CMtSync *p) -{ - p->wasCreated = False; - p->csWasInitialized = False; - p->csWasEntered = False; - Thread_Construct(&p->thread); - Event_Construct(&p->canStart); - Event_Construct(&p->wasStarted); - Event_Construct(&p->wasStopped); - Semaphore_Construct(&p->freeSemaphore); - Semaphore_Construct(&p->filledSemaphore); -} - -static void MtSync_GetNextBlock(CMtSync *p) -{ - if (p->needStart) - { - p->numProcessedBlocks = 1; - p->needStart = False; - p->stopWriting = False; - p->exit = False; - Event_Reset(&p->wasStarted); - Event_Reset(&p->wasStopped); - - Event_Set(&p->canStart); - Event_Wait(&p->wasStarted); - } - else - { - CriticalSection_Leave(&p->cs); - p->csWasEntered = False; - p->numProcessedBlocks++; - Semaphore_Release1(&p->freeSemaphore); - } - Semaphore_Wait(&p->filledSemaphore); - CriticalSection_Enter(&p->cs); - p->csWasEntered = True; -} - -/* MtSync_StopWriting must be called if Writing was started */ - -static void MtSync_StopWriting(CMtSync *p) -{ - UInt32 myNumBlocks = p->numProcessedBlocks; - if (!Thread_WasCreated(&p->thread) || p->needStart) - return; - p->stopWriting = True; - if (p->csWasEntered) - { - CriticalSection_Leave(&p->cs); - p->csWasEntered = False; - } - Semaphore_Release1(&p->freeSemaphore); - - Event_Wait(&p->wasStopped); - - while (myNumBlocks++ != p->numProcessedBlocks) - { - Semaphore_Wait(&p->filledSemaphore); - Semaphore_Release1(&p->freeSemaphore); - } - p->needStart = True; -} - -static void MtSync_Destruct(CMtSync *p) -{ - if (Thread_WasCreated(&p->thread)) - { - MtSync_StopWriting(p); - p->exit = True; - if (p->needStart) - Event_Set(&p->canStart); - Thread_Wait(&p->thread); - Thread_Close(&p->thread); - } - if (p->csWasInitialized) - { - CriticalSection_Delete(&p->cs); - p->csWasInitialized = False; - } - - Event_Close(&p->canStart); - Event_Close(&p->wasStarted); - Event_Close(&p->wasStopped); - Semaphore_Close(&p->freeSemaphore); - Semaphore_Close(&p->filledSemaphore); - - p->wasCreated = False; -} - -#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } - -static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) -{ - if (p->wasCreated) - return SZ_OK; - - RINOK_THREAD(CriticalSection_Init(&p->cs)); - p->csWasInitialized = True; - - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); - - RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks)); - RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks)); - - p->needStart = True; - - RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj)); - p->wasCreated = True; - return SZ_OK; -} - -static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) -{ - SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); - if (res != SZ_OK) - MtSync_Destruct(p); - return res; -} - -void MtSync_Init(CMtSync *p) { p->needStart = True; } - -#define kMtMaxValForNormalize 0xFFFFFFFF - -#define DEF_GetHeads2(name, v, action) \ - static void GetHeads ## name(const Byte *p, UInt32 pos, \ - UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ - { action; for (; numHeads != 0; numHeads--) { \ - const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } } - -#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) - -DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); ) -DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) -DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) -DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) -/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ - -static void HashThreadFunc(CMatchFinderMt *mt) -{ - CMtSync *p = &mt->hashSync; - for (;;) - { - UInt32 numProcessedBlocks = 0; - Event_Wait(&p->canStart); - Event_Set(&p->wasStarted); - for (;;) - { - if (p->exit) - return; - if (p->stopWriting) - { - p->numProcessedBlocks = numProcessedBlocks; - Event_Set(&p->wasStopped); - break; - } - - { - CMatchFinder *mf = mt->MatchFinder; - if (MatchFinder_NeedMove(mf)) - { - CriticalSection_Enter(&mt->btSync.cs); - CriticalSection_Enter(&mt->hashSync.cs); - { - const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf); - ptrdiff_t offset; - MatchFinder_MoveBlock(mf); - offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf); - mt->pointerToCurPos -= offset; - mt->buffer -= offset; - } - CriticalSection_Leave(&mt->btSync.cs); - CriticalSection_Leave(&mt->hashSync.cs); - continue; - } - - Semaphore_Wait(&p->freeSemaphore); - - MatchFinder_ReadIfRequired(mf); - if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize)) - { - UInt32 subValue = (mf->pos - mf->historySize - 1); - MatchFinder_ReduceOffsets(mf, subValue); - MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1); - } - { - UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize; - UInt32 num = mf->streamPos - mf->pos; - heads[0] = 2; - heads[1] = num; - if (num >= mf->numHashBytes) - { - num = num - mf->numHashBytes + 1; - if (num > kMtHashBlockSize - 2) - num = kMtHashBlockSize - 2; - mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); - heads[0] += num; - } - mf->pos += num; - mf->buffer += num; - } - } - - Semaphore_Release1(&p->filledSemaphore); - } - } -} - -static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) -{ - MtSync_GetNextBlock(&p->hashSync); - p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize; - p->hashBufPosLimit += p->hashBuf[p->hashBufPos++]; - p->hashNumAvail = p->hashBuf[p->hashBufPos++]; -} - -#define kEmptyHashValue 0 - -/* #define MFMT_GM_INLINE */ - -#ifdef MFMT_GM_INLINE - -#define NO_INLINE MY_FAST_CALL - -static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, - UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, - UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) -{ - do - { - UInt32 *distances = _distances + 1; - UInt32 curMatch = pos - *hash++; - - CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; - CLzRef *ptr1 = son + (_cyclicBufferPos << 1); - UInt32 len0 = 0, len1 = 0; - UInt32 cutValue = _cutValue; - UInt32 maxLen = _maxLen; - for (;;) - { - UInt32 delta = pos - curMatch; - if (cutValue-- == 0 || delta >= _cyclicBufferSize) - { - *ptr0 = *ptr1 = kEmptyHashValue; - break; - } - { - CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); - const Byte *pb = cur - delta; - UInt32 len = (len0 < len1 ? len0 : len1); - if (pb[len] == cur[len]) - { - if (++len != lenLimit && pb[len] == cur[len]) - while (++len != lenLimit) - if (pb[len] != cur[len]) - break; - if (maxLen < len) - { - *distances++ = maxLen = len; - *distances++ = delta - 1; - if (len == lenLimit) - { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - break; - } - } - } - if (pb[len] < cur[len]) - { - *ptr1 = curMatch; - ptr1 = pair + 1; - curMatch = *ptr1; - len1 = len; - } - else - { - *ptr0 = curMatch; - ptr0 = pair; - curMatch = *ptr0; - len0 = len; - } - } - } - pos++; - _cyclicBufferPos++; - cur++; - { - UInt32 num = (UInt32)(distances - _distances); - *_distances = num - 1; - _distances += num; - limit -= num; - } - } - while (limit > 0 && --size != 0); - *posRes = pos; - return limit; -} - -#endif - -static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - UInt32 numProcessed = 0; - UInt32 curPos = 2; - UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); - - distances[1] = p->hashNumAvail; - - while (curPos < limit) - { - if (p->hashBufPos == p->hashBufPosLimit) - { - MatchFinderMt_GetNextBlock_Hash(p); - distances[1] = numProcessed + p->hashNumAvail; - if (p->hashNumAvail >= p->numHashBytes) - continue; - distances[0] = curPos + p->hashNumAvail; - distances += curPos; - for (; p->hashNumAvail != 0; p->hashNumAvail--) - *distances++ = 0; - return; - } - { - UInt32 size = p->hashBufPosLimit - p->hashBufPos; - UInt32 lenLimit = p->matchMaxLen; - UInt32 pos = p->pos; - UInt32 cyclicBufferPos = p->cyclicBufferPos; - if (lenLimit >= p->hashNumAvail) - lenLimit = p->hashNumAvail; - { - UInt32 size2 = p->hashNumAvail - lenLimit + 1; - if (size2 < size) - size = size2; - size2 = p->cyclicBufferSize - cyclicBufferPos; - if (size2 < size) - size = size2; - } - - #ifndef MFMT_GM_INLINE - while (curPos < limit && size-- != 0) - { - UInt32 *startDistances = distances + curPos; - UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], - pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, - startDistances + 1, p->numHashBytes - 1) - startDistances); - *startDistances = num - 1; - curPos += num; - cyclicBufferPos++; - pos++; - p->buffer++; - } - #else - { - UInt32 posRes; - curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, - distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes); - p->hashBufPos += posRes - pos; - cyclicBufferPos += posRes - pos; - p->buffer += posRes - pos; - pos = posRes; - } - #endif - - numProcessed += pos - p->pos; - p->hashNumAvail -= pos - p->pos; - p->pos = pos; - if (cyclicBufferPos == p->cyclicBufferSize) - cyclicBufferPos = 0; - p->cyclicBufferPos = cyclicBufferPos; - } - } - - distances[0] = curPos; -} - -static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) -{ - CMtSync *sync = &p->hashSync; - if (!sync->needStart) - { - CriticalSection_Enter(&sync->cs); - sync->csWasEntered = True; - } - - BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize); - - if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) - { - UInt32 subValue = p->pos - p->cyclicBufferSize; - MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2); - p->pos -= subValue; - } - - if (!sync->needStart) - { - CriticalSection_Leave(&sync->cs); - sync->csWasEntered = False; - } -} - -void BtThreadFunc(CMatchFinderMt *mt) -{ - CMtSync *p = &mt->btSync; - for (;;) - { - UInt32 blockIndex = 0; - Event_Wait(&p->canStart); - Event_Set(&p->wasStarted); - for (;;) - { - if (p->exit) - return; - if (p->stopWriting) - { - p->numProcessedBlocks = blockIndex; - MtSync_StopWriting(&mt->hashSync); - Event_Set(&p->wasStopped); - break; - } - Semaphore_Wait(&p->freeSemaphore); - BtFillBlock(mt, blockIndex++); - Semaphore_Release1(&p->filledSemaphore); - } - } -} - -void MatchFinderMt_Construct(CMatchFinderMt *p) -{ - p->hashBuf = NULL; - MtSync_Construct(&p->hashSync); - MtSync_Construct(&p->btSync); -} - -static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->hashBuf); - p->hashBuf = NULL; -} - -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) -{ - MtSync_Destruct(&p->hashSync); - MtSync_Destruct(&p->btSync); - MatchFinderMt_FreeMem(p, alloc); -} - -#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) -#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) -{ - Byte allocaDummy[0x180]; - unsigned i = 0; - for (i = 0; i < 16; i++) - allocaDummy[i] = (Byte)0; - if (allocaDummy[0] == 0) - BtThreadFunc((CMatchFinderMt *)p); - return 0; -} - -SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) -{ - CMatchFinder *mf = p->MatchFinder; - p->historySize = historySize; - if (kMtBtBlockSize <= matchMaxLen * 4) - return SZ_ERROR_PARAM; - if (!p->hashBuf) - { - p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); - if (!p->hashBuf) - return SZ_ERROR_MEM; - p->btBuf = p->hashBuf + kHashBufferSize; - } - keepAddBufferBefore += (kHashBufferSize + kBtBufferSize); - keepAddBufferAfter += kMtHashBlockSize; - if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) - return SZ_ERROR_MEM; - - RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks)); - RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks)); - return SZ_OK; -} - -/* Call it after ReleaseStream / SetStream */ -void MatchFinderMt_Init(CMatchFinderMt *p) -{ - CMatchFinder *mf = p->MatchFinder; - p->btBufPos = p->btBufPosLimit = 0; - p->hashBufPos = p->hashBufPosLimit = 0; - - /* Init without data reading. We don't want to read data in this thread */ - MatchFinder_Init_2(mf, False); - - p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf); - p->btNumAvailBytes = 0; - p->lzPos = p->historySize + 1; - - p->hash = mf->hash; - p->fixedHashSize = mf->fixedHashSize; - p->crc = mf->crc; - - p->son = mf->son; - p->matchMaxLen = mf->matchMaxLen; - p->numHashBytes = mf->numHashBytes; - p->pos = mf->pos; - p->buffer = mf->buffer; - p->cyclicBufferPos = mf->cyclicBufferPos; - p->cyclicBufferSize = mf->cyclicBufferSize; - p->cutValue = mf->cutValue; -} - -/* ReleaseStream is required to finish multithreading */ -void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) -{ - MtSync_StopWriting(&p->btSync); - /* p->MatchFinder->ReleaseStream(); */ -} - -static void MatchFinderMt_Normalize(CMatchFinderMt *p) -{ - MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize); - p->lzPos = p->historySize + 1; -} - -static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) -{ - UInt32 blockIndex; - MtSync_GetNextBlock(&p->btSync); - blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask); - p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize; - p->btBufPosLimit += p->btBuf[p->btBufPos++]; - p->btNumAvailBytes = p->btBuf[p->btBufPos++]; - if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize) - MatchFinderMt_Normalize(p); -} - -static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) -{ - return p->pointerToCurPos; -} - -#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); - -static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) -{ - GET_NEXT_BLOCK_IF_REQUIRED; - return p->btNumAvailBytes; -} - -static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 h2, curMatch2; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH2_CALC - - curMatch2 = hash[h2]; - hash[h2] = lzPos; - - if (curMatch2 >= matchMinPos) - if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - *distances++ = 2; - *distances++ = lzPos - curMatch2 - 1; - } - - return distances; -} - -static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 h2, h3, curMatch2, curMatch3; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH3_CALC - - curMatch2 = hash[ h2]; - curMatch3 = hash[kFix3HashSize + h3]; - - hash[ h2] = lzPos; - hash[kFix3HashSize + h3] = lzPos; - - if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch2 - 1; - if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) - { - distances[0] = 3; - return distances + 2; - } - distances[0] = 2; - distances += 2; - } - - if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) - { - *distances++ = 3; - *distances++ = lzPos - curMatch3 - 1; - } - - return distances; -} - -/* -static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) -{ - UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4; - UInt32 *hash = p->hash; - const Byte *cur = p->pointerToCurPos; - UInt32 lzPos = p->lzPos; - MT_HASH4_CALC - - curMatch2 = hash[ h2]; - curMatch3 = hash[kFix3HashSize + h3]; - curMatch4 = hash[kFix4HashSize + h4]; - - hash[ h2] = lzPos; - hash[kFix3HashSize + h3] = lzPos; - hash[kFix4HashSize + h4] = lzPos; - - if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch2 - 1; - if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) - { - distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; - return distances + 2; - } - distances[0] = 2; - distances += 2; - } - - if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) - { - distances[1] = lzPos - curMatch3 - 1; - if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3]) - { - distances[0] = 4; - return distances + 2; - } - distances[0] = 3; - distances += 2; - } - - if (curMatch4 >= matchMinPos) - if ( - cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] && - cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3] - ) - { - *distances++ = 4; - *distances++ = lzPos - curMatch4 - 1; - } - - return distances; -} -*/ - -#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; - -static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - const UInt32 *btBuf = p->btBuf + p->btBufPos; - UInt32 len = *btBuf++; - p->btBufPos += 1 + len; - p->btNumAvailBytes--; - { - UInt32 i; - for (i = 0; i < len; i += 2) - { - *distances++ = *btBuf++; - *distances++ = *btBuf++; - } - } - INCREASE_LZ_POS - return len; -} - -static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) -{ - const UInt32 *btBuf = p->btBuf + p->btBufPos; - UInt32 len = *btBuf++; - p->btBufPos += 1 + len; - - if (len == 0) - { - /* change for bt5 ! */ - if (p->btNumAvailBytes-- >= 4) - len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances)); - } - else - { - /* Condition: there are matches in btBuf with length < p->numHashBytes */ - UInt32 *distances2; - p->btNumAvailBytes--; - distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); - do - { - *distances2++ = *btBuf++; - *distances2++ = *btBuf++; - } - while ((len -= 2) != 0); - len = (UInt32)(distances2 - (distances)); - } - INCREASE_LZ_POS - return len; -} - -#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED -#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; -#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); - -static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER2_MT { p->btNumAvailBytes--; - SKIP_FOOTER_MT -} - -static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(2) - UInt32 h2; - MT_HASH2_CALC - hash[h2] = p->lzPos; - SKIP_FOOTER_MT -} - -static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(3) - UInt32 h2, h3; - MT_HASH3_CALC - hash[kFix3HashSize + h3] = - hash[ h2] = - p->lzPos; - SKIP_FOOTER_MT -} - -/* -static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) -{ - SKIP_HEADER_MT(4) - UInt32 h2, h3, h4; - MT_HASH4_CALC - hash[kFix4HashSize + h4] = - hash[kFix3HashSize + h3] = - hash[ h2] = - p->lzPos; - SKIP_FOOTER_MT -} -*/ - -void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) -{ - vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; - vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; - vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; - - switch (p->MatchFinder->numHashBytes) - { - case 2: - p->GetHeadsFunc = GetHeads2; - p->MixMatchesFunc = (Mf_Mix_Matches)0; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; - vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; - break; - case 3: - p->GetHeadsFunc = GetHeads3; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip; - break; - default: - /* case 4: */ - p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; - break; - /* - default: - p->GetHeadsFunc = GetHeads5; - p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4; - vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip; - break; - */ - } -} +/* LzFindMt.c -- multithreaded Match finder for LZ algorithms +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +#include "CpuArch.h" + +#include "LzHash.h" +#include "LzFindMt.h" + +// #define LOG_ITERS + +// #define LOG_THREAD + +#ifdef LOG_THREAD +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#ifdef LOG_ITERS +#include +extern UInt64 g_NumIters_Tree; +extern UInt64 g_NumIters_Loop; +extern UInt64 g_NumIters_Bytes; +#define LOG_ITER(x) x +#else +#define LOG_ITER(x) +#endif + +#define kMtHashBlockSize ((UInt32)1 << 17) +#define kMtHashNumBlocks (1 << 1) + +#define GET_HASH_BLOCK_OFFSET(i) (((i) & (kMtHashNumBlocks - 1)) * kMtHashBlockSize) + +#define kMtBtBlockSize ((UInt32)1 << 16) +#define kMtBtNumBlocks (1 << 4) + +#define GET_BT_BLOCK_OFFSET(i) (((i) & (kMtBtNumBlocks - 1)) * (size_t)kMtBtBlockSize) + +/* + HASH functions: + We use raw 8/16 bits from a[1] and a[2], + xored with crc(a[0]) and crc(a[3]). + We check a[0], a[3] only. We don't need to compare a[1] and a[2] in matches. + our crc() function provides one-to-one correspondence for low 8-bit values: + (crc[0...0xFF] & 0xFF) <-> [0...0xFF] +*/ + +#define MF(mt) ((mt)->MatchFinder) +#define MF_CRC (p->crc) + +// #define MF(mt) (&(mt)->MatchFinder) +// #define MF_CRC (p->MatchFinder.crc) + +#define MT_HASH2_CALC \ + h2 = (MF_CRC[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = MF_CRC[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +/* +#define MT_HASH3_CALC__NO_2 { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + h2 = temp & (kHash2Size - 1); \ + temp ^= ((UInt32)cur[2] << 8); \ + h3 = temp & (kHash3Size - 1); \ + h4 = (temp ^ (p->crc[cur[3]] << kLzHash_CrcShift_1)) & p->hash4Mask; } + // (kHash4Size - 1); +*/ + + +Z7_NO_INLINE +static void MtSync_Construct(CMtSync *p) +{ + p->affinityGroup = -1; + p->affinityInGroup = 0; + p->affinity = 0; + p->wasCreated = False; + p->csWasInitialized = False; + p->csWasEntered = False; + Thread_CONSTRUCT(&p->thread) + Event_Construct(&p->canStart); + Event_Construct(&p->wasStopped); + Semaphore_Construct(&p->freeSemaphore); + Semaphore_Construct(&p->filledSemaphore); +} + + +// #define DEBUG_BUFFER_LOCK // define it to debug lock state + +#ifdef DEBUG_BUFFER_LOCK +#include +#define BUFFER_MUST_BE_LOCKED(p) if (!(p)->csWasEntered) exit(1); +#define BUFFER_MUST_BE_UNLOCKED(p) if ( (p)->csWasEntered) exit(1); +#else +#define BUFFER_MUST_BE_LOCKED(p) +#define BUFFER_MUST_BE_UNLOCKED(p) +#endif + +#define LOCK_BUFFER(p) { \ + BUFFER_MUST_BE_UNLOCKED(p); \ + CriticalSection_Enter(&(p)->cs); \ + (p)->csWasEntered = True; } + +#define UNLOCK_BUFFER(p) { \ + BUFFER_MUST_BE_LOCKED(p); \ + CriticalSection_Leave(&(p)->cs); \ + (p)->csWasEntered = False; } + + +Z7_NO_INLINE +static UInt32 MtSync_GetNextBlock(CMtSync *p) +{ + UInt32 numBlocks = 0; + if (p->needStart) + { + BUFFER_MUST_BE_UNLOCKED(p) + p->numProcessedBlocks = 1; + p->needStart = False; + p->stopWriting = False; + p->exit = False; + Event_Reset(&p->wasStopped); + Event_Set(&p->canStart); + } + else + { + UNLOCK_BUFFER(p) + // we free current block + numBlocks = p->numProcessedBlocks++; + Semaphore_Release1(&p->freeSemaphore); + } + + // buffer is UNLOCKED here + Semaphore_Wait(&p->filledSemaphore); + LOCK_BUFFER(p) + return numBlocks; +} + + +/* if Writing (Processing) thread was started, we must call MtSync_StopWriting() */ + +Z7_NO_INLINE +static void MtSync_StopWriting(CMtSync *p) +{ + if (!Thread_WasCreated(&p->thread) || p->needStart) + return; + + PRF(printf("\nMtSync_StopWriting %p\n", p)); + + if (p->csWasEntered) + { + /* we don't use buffer in this thread after StopWriting(). + So we UNLOCK buffer. + And we restore default UNLOCKED state for stopped thread */ + UNLOCK_BUFFER(p) + } + + /* We send (p->stopWriting) message and release freeSemaphore + to free current block. + So the thread will see (p->stopWriting) at some + iteration after Wait(freeSemaphore). + The thread doesn't need to fill all avail free blocks, + so we can get fast thread stop. + */ + + p->stopWriting = True; + Semaphore_Release1(&p->freeSemaphore); // check semaphore count !!! + + PRF(printf("\nMtSync_StopWriting %p : Event_Wait(&p->wasStopped)\n", p)); + Event_Wait(&p->wasStopped); + PRF(printf("\nMtSync_StopWriting %p : Event_Wait() finsihed\n", p)); + + /* 21.03 : we don't restore samaphore counters here. + We will recreate and reinit samaphores in next start */ + + p->needStart = True; +} + + +Z7_NO_INLINE +static void MtSync_Destruct(CMtSync *p) +{ + PRF(printf("\nMtSync_Destruct %p\n", p)); + + if (Thread_WasCreated(&p->thread)) + { + /* we want thread to be in Stopped state before sending EXIT command. + note: stop(btSync) will stop (htSync) also */ + MtSync_StopWriting(p); + /* thread in Stopped state here : (p->needStart == true) */ + p->exit = True; + // if (p->needStart) // it's (true) + Event_Set(&p->canStart); // we send EXIT command to thread + Thread_Wait_Close(&p->thread); // we wait thread finishing + } + + if (p->csWasInitialized) + { + CriticalSection_Delete(&p->cs); + p->csWasInitialized = False; + } + p->csWasEntered = False; + + Event_Close(&p->canStart); + Event_Close(&p->wasStopped); + Semaphore_Close(&p->freeSemaphore); + Semaphore_Close(&p->filledSemaphore); + + p->wasCreated = False; +} + + +// #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } +// we want to get real system error codes here instead of SZ_ERROR_THREAD +#define RINOK_THREAD(x) RINOK_WRes(x) + + +// call it before each new file (when new starting is required): +Z7_NO_INLINE +static SRes MtSync_Init(CMtSync *p, UInt32 numBlocks) +{ + WRes wres; + // BUFFER_MUST_BE_UNLOCKED(p) + if (!p->needStart || p->csWasEntered) + return SZ_ERROR_FAIL; + wres = Semaphore_OptCreateInit(&p->freeSemaphore, numBlocks, numBlocks); + if (wres == 0) + wres = Semaphore_OptCreateInit(&p->filledSemaphore, 0, numBlocks); + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +static WRes MtSync_Create_WRes(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj) +{ + WRes wres; + + if (p->wasCreated) + return SZ_OK; + + RINOK_THREAD(CriticalSection_Init(&p->cs)) + p->csWasInitialized = True; + p->csWasEntered = False; + + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)) + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)) + + p->needStart = True; + p->exit = True; /* p->exit is unused before (canStart) Event. + But in case of some unexpected code failure we will get fast exit from thread */ + + // return ERROR_TOO_MANY_POSTS; // for debug + // return EINVAL; // for debug + +#ifdef _WIN32 + if (p->affinityGroup >= 0) + wres = Thread_Create_With_Group(&p->thread, startAddress, obj, + (unsigned)(UInt32)p->affinityGroup, (CAffinityMask)p->affinityInGroup); + else +#endif + if (p->affinity != 0) + wres = Thread_Create_With_Affinity(&p->thread, startAddress, obj, (CAffinityMask)p->affinity); + else + wres = Thread_Create(&p->thread, startAddress, obj); + + RINOK_THREAD(wres) + p->wasCreated = True; + return SZ_OK; +} + + +Z7_NO_INLINE +static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj) +{ + const WRes wres = MtSync_Create_WRes(p, startAddress, obj); + if (wres == 0) + return 0; + MtSync_Destruct(p); + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +// ---------- HASH THREAD ---------- + +#define kMtMaxValForNormalize 0xFFFFFFFF +// #define kMtMaxValForNormalize ((1 << 21)) // for debug +// #define kNormalizeAlign (1 << 7) // alignment for speculated accesses + +#ifdef MY_CPU_LE_UNALIGN + #define GetUi24hi_from32(p) ((UInt32)GetUi32(p) >> 8) +#else + #define GetUi24hi_from32(p) ((p)[1] ^ ((UInt32)(p)[2] << 8) ^ ((UInt32)(p)[3] << 16)) +#endif + +#define GetHeads_DECL(name) \ + static void GetHeads ## name(const Byte *p, UInt32 pos, \ + UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) + +#define GetHeads_LOOP(v) \ + for (; numHeads != 0; numHeads--) { \ + const UInt32 value = (v); \ + p++; \ + *heads++ = pos - hash[value]; \ + hash[value] = pos++; } + +#define DEF_GetHeads2(name, v, action) \ + GetHeads_DECL(name) { action \ + GetHeads_LOOP(v) } + +#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) + +DEF_GetHeads2(2, GetUi16(p), UNUSED_VAR(hashMask); UNUSED_VAR(crc); ) +DEF_GetHeads(3, (crc[p[0]] ^ GetUi16(p + 1)) & hashMask) +DEF_GetHeads2(3b, GetUi16(p) ^ ((UInt32)(p)[2] << 16), UNUSED_VAR(hashMask); UNUSED_VAR(crc); ) +// BT3 is not good for crc collisions for big hashMask values. + +/* +GetHeads_DECL(3b) +{ + UNUSED_VAR(hashMask); + UNUSED_VAR(crc); + { + const Byte *pLim = p + numHeads; + if (numHeads == 0) + return; + pLim--; + while (p < pLim) + { + UInt32 v1 = GetUi32(p); + UInt32 v0 = v1 & 0xFFFFFF; + UInt32 h0, h1; + p += 2; + v1 >>= 8; + h0 = hash[v0]; hash[v0] = pos; heads[0] = pos - h0; pos++; + h1 = hash[v1]; hash[v1] = pos; heads[1] = pos - h1; pos++; + heads += 2; + } + if (p == pLim) + { + UInt32 v0 = GetUi16(p) ^ ((UInt32)(p)[2] << 16); + *heads = pos - hash[v0]; + hash[v0] = pos; + } + } +} +*/ + +/* +GetHeads_DECL(4) +{ + unsigned sh = 0; + UNUSED_VAR(crc) + while ((hashMask & 0x80000000) == 0) + { + hashMask <<= 1; + sh++; + } + GetHeads_LOOP((GetUi32(p) * 0xa54a1) >> sh) +} +#define GetHeads4b GetHeads4 +*/ + +#define USE_GetHeads_LOCAL_CRC + +#ifdef USE_GetHeads_LOCAL_CRC + +GetHeads_DECL(4) +{ + UInt32 crc0[256]; + UInt32 crc1[256]; + { + unsigned i; + for (i = 0; i < 256; i++) + { + UInt32 v = crc[i]; + crc0[i] = v & hashMask; + crc1[i] = (v << kLzHash_CrcShift_1) & hashMask; + // crc1[i] = rotlFixed(v, 8) & hashMask; + } + } + GetHeads_LOOP(crc0[p[0]] ^ crc1[p[3]] ^ (UInt32)GetUi16(p+1)) +} + +GetHeads_DECL(4b) +{ + UInt32 crc0[256]; + { + unsigned i; + for (i = 0; i < 256; i++) + crc0[i] = crc[i] & hashMask; + } + GetHeads_LOOP(crc0[p[0]] ^ GetUi24hi_from32(p)) +} + +GetHeads_DECL(5) +{ + UInt32 crc0[256]; + UInt32 crc1[256]; + UInt32 crc2[256]; + { + unsigned i; + for (i = 0; i < 256; i++) + { + UInt32 v = crc[i]; + crc0[i] = v & hashMask; + crc1[i] = (v << kLzHash_CrcShift_1) & hashMask; + crc2[i] = (v << kLzHash_CrcShift_2) & hashMask; + } + } + GetHeads_LOOP(crc0[p[0]] ^ crc1[p[3]] ^ crc2[p[4]] ^ (UInt32)GetUi16(p+1)) +} + +GetHeads_DECL(5b) +{ + UInt32 crc0[256]; + UInt32 crc1[256]; + { + unsigned i; + for (i = 0; i < 256; i++) + { + UInt32 v = crc[i]; + crc0[i] = v & hashMask; + crc1[i] = (v << kLzHash_CrcShift_1) & hashMask; + } + } + GetHeads_LOOP(crc0[p[0]] ^ crc1[p[4]] ^ GetUi24hi_from32(p)) +} + +#else + +DEF_GetHeads(4, (crc[p[0]] ^ (crc[p[3]] << kLzHash_CrcShift_1) ^ (UInt32)GetUi16(p+1)) & hashMask) +DEF_GetHeads(4b, (crc[p[0]] ^ GetUi24hi_from32(p)) & hashMask) +DEF_GetHeads(5, (crc[p[0]] ^ (crc[p[3]] << kLzHash_CrcShift_1) ^ (crc[p[4]] << kLzHash_CrcShift_2) ^ (UInt32)GetUi16(p + 1)) & hashMask) +DEF_GetHeads(5b, (crc[p[0]] ^ (crc[p[4]] << kLzHash_CrcShift_1) ^ GetUi24hi_from32(p)) & hashMask) + +#endif + + +static void HashThreadFunc(CMatchFinderMt *mt) +{ + CMtSync *p = &mt->hashSync; + PRF(printf("\nHashThreadFunc\n")); + + for (;;) + { + UInt32 blockIndex = 0; + PRF(printf("\nHashThreadFunc : Event_Wait(&p->canStart)\n")); + Event_Wait(&p->canStart); + PRF(printf("\nHashThreadFunc : Event_Wait(&p->canStart) : after \n")); + if (p->exit) + { + PRF(printf("\nHashThreadFunc : exit \n")); + return; + } + + MatchFinder_Init_HighHash(MF(mt)); + + for (;;) + { + PRF(printf("Hash thread block = %d pos = %d\n", (unsigned)blockIndex, mt->MatchFinder->pos)); + + { + CMatchFinder *mf = MF(mt); + if (MatchFinder_NeedMove(mf)) + { + CriticalSection_Enter(&mt->btSync.cs); + CriticalSection_Enter(&mt->hashSync.cs); + { + const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf); + ptrdiff_t offset; + MatchFinder_MoveBlock(mf); + offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf); + mt->pointerToCurPos -= offset; + mt->buffer -= offset; + } + CriticalSection_Leave(&mt->hashSync.cs); + CriticalSection_Leave(&mt->btSync.cs); + continue; + } + + Semaphore_Wait(&p->freeSemaphore); + + if (p->exit) // exit is unexpected here. But we check it here for some failure case + return; + + // for faster stop : we check (p->stopWriting) after Wait(freeSemaphore) + if (p->stopWriting) + break; + + MatchFinder_ReadIfRequired(mf); + { + UInt32 *heads = mt->hashBuf + GET_HASH_BLOCK_OFFSET(blockIndex++); + UInt32 num = Inline_MatchFinder_GetNumAvailableBytes(mf); + heads[0] = 2; + heads[1] = num; + + /* heads[1] contains the number of avail bytes: + if (avail < mf->numHashBytes) : + { + it means that stream was finished + HASH_THREAD and BT_TREAD must move position for heads[1] (avail) bytes. + HASH_THREAD doesn't stop, + HASH_THREAD fills only the header (2 numbers) for all next blocks: + {2, NumHashBytes - 1}, {2,0}, {2,0}, ... , {2,0} + } + else + { + HASH_THREAD and BT_TREAD must move position for (heads[0] - 2) bytes; + } + */ + + if (num >= mf->numHashBytes) + { + num = num - mf->numHashBytes + 1; + if (num > kMtHashBlockSize - 2) + num = kMtHashBlockSize - 2; + + if (mf->pos > (UInt32)kMtMaxValForNormalize - num) + { + const UInt32 subValue = (mf->pos - mf->historySize - 1); // & ~(UInt32)(kNormalizeAlign - 1); + MatchFinder_REDUCE_OFFSETS(mf, subValue) + MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1); + } + + heads[0] = 2 + num; + mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); + } + + mf->pos += num; // wrap over zero is allowed at the end of stream + mf->buffer += num; + } + } + + Semaphore_Release1(&p->filledSemaphore); + } // for() processing end + + // p->numBlocks_Sent = blockIndex; + Event_Set(&p->wasStopped); + } // for() thread end +} + + + + +// ---------- BT THREAD ---------- + +/* we use one variable instead of two (cyclicBufferPos == pos) before CyclicBuf wrap. + here we define fixed offset of (p->pos) from (p->cyclicBufferPos) */ +#define CYC_TO_POS_OFFSET 0 +// #define CYC_TO_POS_OFFSET 1 // for debug + +#define MFMT_GM_INLINE + +#ifdef MFMT_GM_INLINE + +/* + we use size_t for (pos) instead of UInt32 + to eliminate "movsx" BUG in old MSVC x64 compiler. +*/ + + +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, + UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, + UInt32 *posRes); + +#endif + + +static void BtGetMatches(CMatchFinderMt *p, UInt32 *d) +{ + UInt32 numProcessed = 0; + UInt32 curPos = 2; + + /* GetMatchesSpec() functions don't create (len = 1) + in [len, dist] match pairs, if (p->numHashBytes >= 2) + Also we suppose here that (matchMaxLen >= 2). + So the following code for (reserve) is not required + UInt32 reserve = (p->matchMaxLen * 2); + const UInt32 kNumHashBytes_Max = 5; // BT_HASH_BYTES_MAX + if (reserve < kNumHashBytes_Max - 1) + reserve = kNumHashBytes_Max - 1; + const UInt32 limit = kMtBtBlockSize - (reserve); + */ + + const UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); + + d[1] = p->hashNumAvail; + + if (p->failure_BT) + { + // printf("\n == 1 BtGetMatches() p->failure_BT\n"); + d[0] = 0; + // d[1] = 0; + return; + } + + while (curPos < limit) + { + if (p->hashBufPos == p->hashBufPosLimit) + { + // MatchFinderMt_GetNextBlock_Hash(p); + UInt32 avail; + { + const UInt32 bi = MtSync_GetNextBlock(&p->hashSync); + const UInt32 k = GET_HASH_BLOCK_OFFSET(bi); + const UInt32 *h = p->hashBuf + k; + avail = h[1]; + p->hashBufPosLimit = k + h[0]; + p->hashNumAvail = avail; + p->hashBufPos = k + 2; + } + + { + /* we must prevent UInt32 overflow for avail total value, + if avail was increased with new hash block */ + UInt32 availSum = numProcessed + avail; + if (availSum < numProcessed) + availSum = (UInt32)(Int32)-1; + d[1] = availSum; + } + + if (avail >= p->numHashBytes) + continue; + + // if (p->hashBufPos != p->hashBufPosLimit) exit(1); + + /* (avail < p->numHashBytes) + It means that stream was finished. + And (avail) - is a number of remaining bytes, + we fill (d) for (avail) bytes for LZ_THREAD (receiver). + but we don't update (p->pos) and (p->cyclicBufferPos) here in BT_THREAD */ + + /* here we suppose that we have space enough: + (kMtBtBlockSize - curPos >= p->hashNumAvail) */ + p->hashNumAvail = 0; + d[0] = curPos + avail; + d += curPos; + for (; avail != 0; avail--) + *d++ = 0; + return; + } + { + UInt32 size = p->hashBufPosLimit - p->hashBufPos; + UInt32 pos = p->pos; + UInt32 cyclicBufferPos = p->cyclicBufferPos; + UInt32 lenLimit = p->matchMaxLen; + if (lenLimit >= p->hashNumAvail) + lenLimit = p->hashNumAvail; + { + UInt32 size2 = p->hashNumAvail - lenLimit + 1; + if (size2 < size) + size = size2; + size2 = p->cyclicBufferSize - cyclicBufferPos; + if (size2 < size) + size = size2; + } + + if (pos > (UInt32)kMtMaxValForNormalize - size) + { + const UInt32 subValue = (pos - p->cyclicBufferSize); // & ~(UInt32)(kNormalizeAlign - 1); + pos -= subValue; + p->pos = pos; + MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2); + } + + #ifndef MFMT_GM_INLINE + while (curPos < limit && size-- != 0) + { + UInt32 *startDistances = d + curPos; + UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], + pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, + startDistances + 1, p->numHashBytes - 1) - startDistances); + *startDistances = num - 1; + curPos += num; + cyclicBufferPos++; + pos++; + p->buffer++; + } + #else + { + UInt32 posRes = pos; + const UInt32 *d_end; + { + d_end = GetMatchesSpecN_2( + p->buffer + lenLimit - 1, + pos, p->buffer, p->son, p->cutValue, d + curPos, + p->numHashBytes - 1, p->hashBuf + p->hashBufPos, + d + limit, p->hashBuf + p->hashBufPos + size, + cyclicBufferPos, p->cyclicBufferSize, + &posRes); + } + { + if (!d_end) + { + // printf("\n == 2 BtGetMatches() p->failure_BT\n"); + // internal data failure + p->failure_BT = True; + d[0] = 0; + // d[1] = 0; + return; + } + } + curPos = (UInt32)(d_end - d); + { + const UInt32 processed = posRes - pos; + pos = posRes; + p->hashBufPos += processed; + cyclicBufferPos += processed; + p->buffer += processed; + } + } + #endif + + { + const UInt32 processed = pos - p->pos; + numProcessed += processed; + p->hashNumAvail -= processed; + p->pos = pos; + } + if (cyclicBufferPos == p->cyclicBufferSize) + cyclicBufferPos = 0; + p->cyclicBufferPos = cyclicBufferPos; + } + } + + d[0] = curPos; +} + + +static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) +{ + CMtSync *sync = &p->hashSync; + + BUFFER_MUST_BE_UNLOCKED(sync) + + if (!sync->needStart) + { + LOCK_BUFFER(sync) + } + + BtGetMatches(p, p->btBuf + GET_BT_BLOCK_OFFSET(globalBlockIndex)); + + /* We suppose that we have called GetNextBlock() from start. + So buffer is LOCKED */ + + UNLOCK_BUFFER(sync) +} + + +Z7_NO_INLINE +static void BtThreadFunc(CMatchFinderMt *mt) +{ + CMtSync *p = &mt->btSync; + for (;;) + { + UInt32 blockIndex = 0; + Event_Wait(&p->canStart); + + for (;;) + { + PRF(printf(" BT thread block = %d pos = %d\n", (unsigned)blockIndex, mt->pos)); + /* (p->exit == true) is possible after (p->canStart) at first loop iteration + and is unexpected after more Wait(freeSemaphore) iterations */ + if (p->exit) + return; + + Semaphore_Wait(&p->freeSemaphore); + + // for faster stop : we check (p->stopWriting) after Wait(freeSemaphore) + if (p->stopWriting) + break; + + BtFillBlock(mt, blockIndex++); + + Semaphore_Release1(&p->filledSemaphore); + } + + // we stop HASH_THREAD here + MtSync_StopWriting(&mt->hashSync); + + // p->numBlocks_Sent = blockIndex; + Event_Set(&p->wasStopped); + } +} + + +void MatchFinderMt_Construct(CMatchFinderMt *p) +{ + p->hashBuf = NULL; + MtSync_Construct(&p->hashSync); + MtSync_Construct(&p->btSync); +} + +static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->hashBuf); + p->hashBuf = NULL; +} + +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc) +{ + /* + HASH_THREAD can use CriticalSection(s) btSync.cs and hashSync.cs. + So we must be sure that HASH_THREAD will not use CriticalSection(s) + after deleting CriticalSection here. + + we call ReleaseStream(p) + that calls StopWriting(btSync) + that calls StopWriting(hashSync), if it's required to stop HASH_THREAD. + after StopWriting() it's safe to destruct MtSync(s) in any order */ + + MatchFinderMt_ReleaseStream(p); + + MtSync_Destruct(&p->btSync); + MtSync_Destruct(&p->hashSync); + + LOG_ITER( + printf("\nTree %9d * %7d iter = %9d = sum : bytes = %9d\n", + (UInt32)(g_NumIters_Tree / 1000), + (UInt32)(((UInt64)g_NumIters_Loop * 1000) / (g_NumIters_Tree + 1)), + (UInt32)(g_NumIters_Loop / 1000), + (UInt32)(g_NumIters_Bytes / 1000) + )); + + MatchFinderMt_FreeMem(p, alloc); +} + + +#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) +#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) + + +static THREAD_FUNC_DECL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } +static THREAD_FUNC_DECL BtThreadFunc2(void *p) +{ + Byte allocaDummy[0x180]; + unsigned i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)0; + if (allocaDummy[0] == 0) + BtThreadFunc((CMatchFinderMt *)p); + return 0; +} + + +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc) +{ + CMatchFinder *mf = MF(p); + p->historySize = historySize; + if (kMtBtBlockSize <= matchMaxLen * 4) + return SZ_ERROR_PARAM; + if (!p->hashBuf) + { + p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, ((size_t)kHashBufferSize + (size_t)kBtBufferSize) * sizeof(UInt32)); + if (!p->hashBuf) + return SZ_ERROR_MEM; + p->btBuf = p->hashBuf + kHashBufferSize; + } + keepAddBufferBefore += (kHashBufferSize + kBtBufferSize); + keepAddBufferAfter += kMtHashBlockSize; + if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) + return SZ_ERROR_MEM; + + RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p)) + RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p)) + return SZ_OK; +} + + +SRes MatchFinderMt_InitMt(CMatchFinderMt *p) +{ + RINOK(MtSync_Init(&p->hashSync, kMtHashNumBlocks)) + return MtSync_Init(&p->btSync, kMtBtNumBlocks); +} + + +static void MatchFinderMt_Init(void *_p) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + CMatchFinder *mf = MF(p); + + p->btBufPos = + p->btBufPosLimit = NULL; + p->hashBufPos = + p->hashBufPosLimit = 0; + p->hashNumAvail = 0; // 21.03 + + p->failure_BT = False; + + /* Init without data reading. We don't want to read data in this thread */ + MatchFinder_Init_4(mf); + + MatchFinder_Init_LowHash(mf); + + p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf); + p->btNumAvailBytes = 0; + p->failure_LZ_BT = False; + // p->failure_LZ_LZ = False; + + p->lzPos = + 1; // optimal smallest value + // 0; // for debug: ignores match to start + // kNormalizeAlign; // for debug + + p->hash = mf->hash; + p->fixedHashSize = mf->fixedHashSize; + // p->hash4Mask = mf->hash4Mask; + p->crc = mf->crc; + // memcpy(p->crc, mf->crc, sizeof(mf->crc)); + + p->son = mf->son; + p->matchMaxLen = mf->matchMaxLen; + p->numHashBytes = mf->numHashBytes; + + /* (mf->pos) and (mf->streamPos) were already initialized to 1 in MatchFinder_Init_4() */ + // mf->streamPos = mf->pos = 1; // optimal smallest value + // 0; // for debug: ignores match to start + // kNormalizeAlign; // for debug + + /* we must init (p->pos = mf->pos) for BT, because + BT code needs (p->pos == delta_value_for_empty_hash_record == mf->pos) */ + p->pos = mf->pos; // do not change it + + p->cyclicBufferPos = (p->pos - CYC_TO_POS_OFFSET); + p->cyclicBufferSize = mf->cyclicBufferSize; + p->buffer = mf->buffer; + p->cutValue = mf->cutValue; + // p->son[0] = p->son[1] = 0; // unused: to init skipped record for speculated accesses. +} + + +/* ReleaseStream is required to finish multithreading */ +void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) +{ + // Sleep(1); // for debug + MtSync_StopWriting(&p->btSync); + // Sleep(200); // for debug + /* p->MatchFinder->ReleaseStream(); */ +} + + +Z7_NO_INLINE +static UInt32 MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) +{ + if (p->failure_LZ_BT) + p->btBufPos = p->failureBuf; + else + { + const UInt32 bi = MtSync_GetNextBlock(&p->btSync); + const UInt32 *bt = p->btBuf + GET_BT_BLOCK_OFFSET(bi); + { + const UInt32 numItems = bt[0]; + p->btBufPosLimit = bt + numItems; + p->btNumAvailBytes = bt[1]; + p->btBufPos = bt + 2; + if (numItems < 2 || numItems > kMtBtBlockSize) + { + p->failureBuf[0] = 0; + p->btBufPos = p->failureBuf; + p->btBufPosLimit = p->failureBuf + 1; + p->failure_LZ_BT = True; + // p->btNumAvailBytes = 0; + /* we don't want to decrease AvailBytes, that was load before. + that can be unxepected for the code that have loaded anopther value before */ + } + } + + if (p->lzPos >= (UInt32)kMtMaxValForNormalize - (UInt32)kMtBtBlockSize) + { + /* we don't check (lzPos) over exact avail bytes in (btBuf). + (fixedHashSize) is small, so normalization is fast */ + const UInt32 subValue = (p->lzPos - p->historySize - 1); // & ~(UInt32)(kNormalizeAlign - 1); + p->lzPos -= subValue; + MatchFinder_Normalize3(subValue, p->hash, p->fixedHashSize); + } + } + return p->btNumAvailBytes; +} + + + +static const Byte * MatchFinderMt_GetPointerToCurrentPos(void *_p) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + return p->pointerToCurPos; +} + + +#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); + + +static UInt32 MatchFinderMt_GetNumAvailableBytes(void *_p) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + if (p->btBufPos != p->btBufPosLimit) + return p->btNumAvailBytes; + return MatchFinderMt_GetNextBlock_Bt(p); +} + + +// #define CHECK_FAILURE_LZ(_match_, _pos_) if (_match_ >= _pos_) { p->failure_LZ_LZ = True; return d; } +#define CHECK_FAILURE_LZ(_match_, _pos_) + +static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) +{ + UInt32 h2, c2; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + const UInt32 m = p->lzPos; + MT_HASH2_CALC + + c2 = hash[h2]; + hash[h2] = m; + + if (c2 >= matchMinPos) + { + CHECK_FAILURE_LZ(c2, m) + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) + { + *d++ = 2; + *d++ = m - c2 - 1; + } + } + + return d; +} + +static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) +{ + UInt32 h2, h3, c2, c3; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + const UInt32 m = p->lzPos; + MT_HASH3_CALC + + c2 = hash[h2]; + c3 = (hash + kFix3HashSize)[h3]; + + hash[h2] = m; + (hash + kFix3HashSize)[h3] = m; + + if (c2 >= matchMinPos) + { + CHECK_FAILURE_LZ(c2, m) + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) + { + d[1] = m - c2 - 1; + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m + 2] == cur[2]) + { + d[0] = 3; + return d + 2; + } + d[0] = 2; + d += 2; + } + } + + if (c3 >= matchMinPos) + { + CHECK_FAILURE_LZ(c3, m) + if (cur[(ptrdiff_t)c3 - (ptrdiff_t)m] == cur[0]) + { + *d++ = 3; + *d++ = m - c3 - 1; + } + } + + return d; +} + + +#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; + +/* +static +UInt32* MatchFinderMt_GetMatches_Bt4(CMatchFinderMt *p, UInt32 *d) +{ + const UInt32 *bt = p->btBufPos; + const UInt32 len = *bt++; + const UInt32 *btLim = bt + len; + UInt32 matchMinPos; + UInt32 avail = p->btNumAvailBytes - 1; + p->btBufPos = btLim; + + { + p->btNumAvailBytes = avail; + + #define BT_HASH_BYTES_MAX 5 + + matchMinPos = p->lzPos; + + if (len != 0) + matchMinPos -= bt[1]; + else if (avail < (BT_HASH_BYTES_MAX - 1) - 1) + { + INCREASE_LZ_POS + return d; + } + else + { + const UInt32 hs = p->historySize; + if (matchMinPos > hs) + matchMinPos -= hs; + else + matchMinPos = 1; + } + } + + for (;;) + { + + UInt32 h2, h3, c2, c3; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + UInt32 m = p->lzPos; + MT_HASH3_CALC + + c2 = hash[h2]; + c3 = (hash + kFix3HashSize)[h3]; + + hash[h2] = m; + (hash + kFix3HashSize)[h3] = m; + + if (c2 >= matchMinPos && cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) + { + d[1] = m - c2 - 1; + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m + 2] == cur[2]) + { + d[0] = 3; + d += 2; + break; + } + // else + { + d[0] = 2; + d += 2; + } + } + if (c3 >= matchMinPos && cur[(ptrdiff_t)c3 - (ptrdiff_t)m] == cur[0]) + { + *d++ = 3; + *d++ = m - c3 - 1; + } + break; + } + + if (len != 0) + { + do + { + const UInt32 v0 = bt[0]; + const UInt32 v1 = bt[1]; + bt += 2; + d[0] = v0; + d[1] = v1; + d += 2; + } + while (bt != btLim); + } + INCREASE_LZ_POS + return d; +} +*/ + + +static UInt32 * MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) +{ + UInt32 h2, h3, /* h4, */ c2, c3 /* , c4 */; + UInt32 *hash = p->hash; + const Byte *cur = p->pointerToCurPos; + const UInt32 m = p->lzPos; + MT_HASH3_CALC + // MT_HASH4_CALC + c2 = hash[h2]; + c3 = (hash + kFix3HashSize)[h3]; + // c4 = (hash + kFix4HashSize)[h4]; + + hash[h2] = m; + (hash + kFix3HashSize)[h3] = m; + // (hash + kFix4HashSize)[h4] = m; + + // #define BT5_USE_H2 + // #ifdef BT5_USE_H2 + if (c2 >= matchMinPos && cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) + { + d[1] = m - c2 - 1; + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m + 2] == cur[2]) + { + // d[0] = (cur[(ptrdiff_t)c2 - (ptrdiff_t)m + 3] == cur[3]) ? 4 : 3; + // return d + 2; + + if (cur[(ptrdiff_t)c2 - (ptrdiff_t)m + 3] == cur[3]) + { + d[0] = 4; + return d + 2; + } + d[0] = 3; + d += 2; + + #ifdef BT5_USE_H4 + if (c4 >= matchMinPos) + if ( + cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && + cur[(ptrdiff_t)c4 - (ptrdiff_t)m + 3] == cur[3] + ) + { + *d++ = 4; + *d++ = m - c4 - 1; + } + #endif + return d; + } + d[0] = 2; + d += 2; + } + // #endif + + if (c3 >= matchMinPos && cur[(ptrdiff_t)c3 - (ptrdiff_t)m] == cur[0]) + { + d[1] = m - c3 - 1; + if (cur[(ptrdiff_t)c3 - (ptrdiff_t)m + 3] == cur[3]) + { + d[0] = 4; + return d + 2; + } + d[0] = 3; + d += 2; + } + + #ifdef BT5_USE_H4 + if (c4 >= matchMinPos) + if ( + cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && + cur[(ptrdiff_t)c4 - (ptrdiff_t)m + 3] == cur[3] + ) + { + *d++ = 4; + *d++ = m - c4 - 1; + } + #endif + + return d; +} + + +static UInt32 * MatchFinderMt2_GetMatches(void *_p, UInt32 *d) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + const UInt32 *bt = p->btBufPos; + const UInt32 len = *bt++; + const UInt32 *btLim = bt + len; + p->btBufPos = btLim; + p->btNumAvailBytes--; + INCREASE_LZ_POS + { + while (bt != btLim) + { + const UInt32 v0 = bt[0]; + const UInt32 v1 = bt[1]; + bt += 2; + d[0] = v0; + d[1] = v1; + d += 2; + } + } + return d; +} + + + +static UInt32 * MatchFinderMt_GetMatches(void *_p, UInt32 *d) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + const UInt32 *bt = p->btBufPos; + UInt32 len = *bt++; + const UInt32 avail = p->btNumAvailBytes - 1; + p->btNumAvailBytes = avail; + p->btBufPos = bt + len; + if (len == 0) + { + #define BT_HASH_BYTES_MAX 5 + if (avail >= (BT_HASH_BYTES_MAX - 1) - 1) + { + UInt32 m = p->lzPos; + if (m > p->historySize) + m -= p->historySize; + else + m = 1; + d = p->MixMatchesFunc(p, m, d); + } + } + else + { + /* + first match pair from BinTree: (match_len, match_dist), + (match_len >= numHashBytes). + MixMatchesFunc() inserts only hash matches that are nearer than (match_dist) + */ + d = p->MixMatchesFunc(p, p->lzPos - bt[1], d); + // if (d) // check for failure + do + { + const UInt32 v0 = bt[0]; + const UInt32 v1 = bt[1]; + bt += 2; + d[0] = v0; + d[1] = v1; + d += 2; + } + while (len -= 2); + } + INCREASE_LZ_POS + return d; +} + +#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED +#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; +#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += (size_t)*p->btBufPos + 1; } while (--num != 0); + +static void MatchFinderMt0_Skip(void *_p, UInt32 num) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + SKIP_HEADER2_MT { p->btNumAvailBytes--; + SKIP_FOOTER_MT +} + +static void MatchFinderMt2_Skip(void *_p, UInt32 num) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + SKIP_HEADER_MT(2) + UInt32 h2; + MT_HASH2_CALC + hash[h2] = p->lzPos; + SKIP_FOOTER_MT +} + +static void MatchFinderMt3_Skip(void *_p, UInt32 num) +{ + CMatchFinderMt *p = (CMatchFinderMt *)_p; + SKIP_HEADER_MT(3) + UInt32 h2, h3; + MT_HASH3_CALC + (hash + kFix3HashSize)[h3] = + hash[ h2] = + p->lzPos; + SKIP_FOOTER_MT +} + +/* +// MatchFinderMt4_Skip() is similar to MatchFinderMt3_Skip(). +// The difference is that MatchFinderMt3_Skip() updates hash for last 3 bytes of stream. + +static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) +{ + SKIP_HEADER_MT(4) + UInt32 h2, h3; // h4 + MT_HASH3_CALC + // MT_HASH4_CALC + // (hash + kFix4HashSize)[h4] = + (hash + kFix3HashSize)[h3] = + hash[ h2] = + p->lzPos; + SKIP_FOOTER_MT +} +*/ + +void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable) +{ + vTable->Init = MatchFinderMt_Init; + vTable->GetNumAvailableBytes = MatchFinderMt_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = MatchFinderMt_GetPointerToCurrentPos; + vTable->GetMatches = MatchFinderMt_GetMatches; + + switch (MF(p)->numHashBytes) + { + case 2: + p->GetHeadsFunc = GetHeads2; + p->MixMatchesFunc = NULL; + vTable->Skip = MatchFinderMt0_Skip; + vTable->GetMatches = MatchFinderMt2_GetMatches; + break; + case 3: + p->GetHeadsFunc = MF(p)->bigHash ? GetHeads3b : GetHeads3; + p->MixMatchesFunc = MixMatches2; + vTable->Skip = MatchFinderMt2_Skip; + break; + case 4: + p->GetHeadsFunc = MF(p)->bigHash ? GetHeads4b : GetHeads4; + + // it's fast inline version of GetMatches() + // vTable->GetMatches = MatchFinderMt_GetMatches_Bt4; + + p->MixMatchesFunc = MixMatches3; + vTable->Skip = MatchFinderMt3_Skip; + break; + default: + p->GetHeadsFunc = MF(p)->bigHash ? GetHeads5b : GetHeads5; + p->MixMatchesFunc = MixMatches4; + vTable->Skip = + MatchFinderMt3_Skip; + // MatchFinderMt4_Skip; + break; + } +} + +#undef RINOK_THREAD +#undef PRF +#undef MF +#undef GetUi24hi_from32 +#undef LOCK_BUFFER +#undef UNLOCK_BUFFER diff -Nru p7zip-rar-16.02/C/LzFindMt.h p7zip-rar-16.02+really25.00+ds/C/LzFindMt.h --- p7zip-rar-16.02/C/LzFindMt.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzFindMt.h 2025-05-10 07:00:00.000000000 +0000 @@ -1,101 +1,114 @@ -/* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2015-05-03 : Igor Pavlov : Public domain */ - -#ifndef __LZ_FIND_MT_H -#define __LZ_FIND_MT_H - -#include "LzFind.h" -#include "Threads.h" - -EXTERN_C_BEGIN - -#define kMtHashBlockSize (1 << 13) -#define kMtHashNumBlocks (1 << 3) -#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1) - -#define kMtBtBlockSize (1 << 14) -#define kMtBtNumBlocks (1 << 6) -#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1) - -typedef struct _CMtSync -{ - Bool wasCreated; - Bool needStart; - Bool exit; - Bool stopWriting; - - CThread thread; - CAutoResetEvent canStart; - CAutoResetEvent wasStarted; - CAutoResetEvent wasStopped; - CSemaphore freeSemaphore; - CSemaphore filledSemaphore; - Bool csWasInitialized; - Bool csWasEntered; - CCriticalSection cs; - UInt32 numProcessedBlocks; -} CMtSync; - -typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); - -/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ -#define kMtCacheLineDummy 128 - -typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, - UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); - -typedef struct _CMatchFinderMt -{ - /* LZ */ - const Byte *pointerToCurPos; - UInt32 *btBuf; - UInt32 btBufPos; - UInt32 btBufPosLimit; - UInt32 lzPos; - UInt32 btNumAvailBytes; - - UInt32 *hash; - UInt32 fixedHashSize; - UInt32 historySize; - const UInt32 *crc; - - Mf_Mix_Matches MixMatchesFunc; - - /* LZ + BT */ - CMtSync btSync; - Byte btDummy[kMtCacheLineDummy]; - - /* BT */ - UInt32 *hashBuf; - UInt32 hashBufPos; - UInt32 hashBufPosLimit; - UInt32 hashNumAvail; - - CLzRef *son; - UInt32 matchMaxLen; - UInt32 numHashBytes; - UInt32 pos; - const Byte *buffer; - UInt32 cyclicBufferPos; - UInt32 cyclicBufferSize; /* it must be historySize + 1 */ - UInt32 cutValue; - - /* BT + Hash */ - CMtSync hashSync; - /* Byte hashDummy[kMtCacheLineDummy]; */ - - /* Hash */ - Mf_GetHeads GetHeadsFunc; - CMatchFinder *MatchFinder; -} CMatchFinderMt; - -void MatchFinderMt_Construct(CMatchFinderMt *p); -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); -SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); -void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); -void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); - -EXTERN_C_END - -#endif +/* LzFindMt.h -- multithreaded Match finder for LZ algorithms +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZ_FIND_MT_H +#define ZIP7_INC_LZ_FIND_MT_H + +#include "LzFind.h" +#include "Threads.h" + +EXTERN_C_BEGIN + +typedef struct +{ + UInt32 numProcessedBlocks; + Int32 affinityGroup; + UInt64 affinityInGroup; + UInt64 affinity; + CThread thread; + + BoolInt wasCreated; + BoolInt needStart; + BoolInt csWasInitialized; + BoolInt csWasEntered; + + BoolInt exit; + BoolInt stopWriting; + + CAutoResetEvent canStart; + CAutoResetEvent wasStopped; + CSemaphore freeSemaphore; + CSemaphore filledSemaphore; + CCriticalSection cs; + // UInt32 numBlocks_Sent; +} CMtSync; + + +struct CMatchFinderMt_; + +typedef UInt32 * (*Mf_Mix_Matches)(struct CMatchFinderMt_ *p, UInt32 matchMinPos, UInt32 *distances); + +/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ +#define kMtCacheLineDummy 128 + +typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, + UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); + +typedef struct CMatchFinderMt_ +{ + /* LZ */ + const Byte *pointerToCurPos; + UInt32 *btBuf; + const UInt32 *btBufPos; + const UInt32 *btBufPosLimit; + UInt32 lzPos; + UInt32 btNumAvailBytes; + + UInt32 *hash; + UInt32 fixedHashSize; + // UInt32 hash4Mask; + UInt32 historySize; + const UInt32 *crc; + + Mf_Mix_Matches MixMatchesFunc; + UInt32 failure_LZ_BT; // failure in BT transfered to LZ + // UInt32 failure_LZ_LZ; // failure in LZ tables + UInt32 failureBuf[1]; + // UInt32 crc[256]; + + /* LZ + BT */ + CMtSync btSync; + Byte btDummy[kMtCacheLineDummy]; + + /* BT */ + UInt32 *hashBuf; + UInt32 hashBufPos; + UInt32 hashBufPosLimit; + UInt32 hashNumAvail; + UInt32 failure_BT; + + + CLzRef *son; + UInt32 matchMaxLen; + UInt32 numHashBytes; + UInt32 pos; + const Byte *buffer; + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + UInt32 cutValue; + + /* BT + Hash */ + CMtSync hashSync; + /* Byte hashDummy[kMtCacheLineDummy]; */ + + /* Hash */ + Mf_GetHeads GetHeadsFunc; + CMatchFinder *MatchFinder; + // CMatchFinder MatchFinder; +} CMatchFinderMt; + +// only for Mt part +void MatchFinderMt_Construct(CMatchFinderMt *p); +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc); + +SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc); +void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable); + +/* call MatchFinderMt_InitMt() before IMatchFinder::Init() */ +SRes MatchFinderMt_InitMt(CMatchFinderMt *p); +void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/LzFindOpt.c p7zip-rar-16.02+really25.00+ds/C/LzFindOpt.c --- p7zip-rar-16.02/C/LzFindOpt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzFindOpt.c 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,578 @@ +/* LzFindOpt.c -- multithreaded Match finder for LZ algorithms +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "LzFind.h" + +// #include "LzFindMt.h" + +// #define LOG_ITERS + +// #define LOG_THREAD + +#ifdef LOG_THREAD +#include +#define PRF(x) x +#else +// #define PRF(x) +#endif + +#ifdef LOG_ITERS +#include +UInt64 g_NumIters_Tree; +UInt64 g_NumIters_Loop; +UInt64 g_NumIters_Bytes; +#define LOG_ITER(x) x +#else +#define LOG_ITER(x) +#endif + +// ---------- BT THREAD ---------- + +#define USE_SON_PREFETCH +#define USE_LONG_MATCH_OPT + +#define kEmptyHashValue 0 + +// #define CYC_TO_POS_OFFSET 0 + +// #define CYC_TO_POS_OFFSET 1 // for debug + +/* +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, + UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, UInt32 *posRes) +{ + do + { + UInt32 delta; + if (hash == size) + break; + delta = *hash++; + + if (delta == 0 || delta > (UInt32)pos) + return NULL; + + lenLimit++; + + if (delta == (UInt32)pos) + { + CLzRef *ptr1 = son + ((size_t)pos << 1) - CYC_TO_POS_OFFSET * 2; + *d++ = 0; + ptr1[0] = kEmptyHashValue; + ptr1[1] = kEmptyHashValue; + } +else +{ + UInt32 *_distances = ++d; + + CLzRef *ptr0 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2 + 1; + CLzRef *ptr1 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2; + + const Byte *len0 = cur, *len1 = cur; + UInt32 cutValue = _cutValue; + const Byte *maxLen = cur + _maxLen; + + for (LOG_ITER(g_NumIters_Tree++);;) + { + LOG_ITER(g_NumIters_Loop++); + { + const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + CLzRef *pair = son + ((size_t)(((ptrdiff_t)pos - CYC_TO_POS_OFFSET) + diff) << 1); + const Byte *len = (len0 < len1 ? len0 : len1); + + #ifdef USE_SON_PREFETCH + const UInt32 pair0 = *pair; + #endif + + if (len[diff] == len[0]) + { + if (++len != lenLimit && len[diff] == len[0]) + while (++len != lenLimit) + { + LOG_ITER(g_NumIters_Bytes++); + if (len[diff] != len[0]) + break; + } + if (maxLen < len) + { + maxLen = len; + *d++ = (UInt32)(len - cur); + *d++ = delta - 1; + + if (len == lenLimit) + { + const UInt32 pair1 = pair[1]; + *ptr1 = + #ifdef USE_SON_PREFETCH + pair0; + #else + pair[0]; + #endif + *ptr0 = pair1; + + _distances[-1] = (UInt32)(d - _distances); + + #ifdef USE_LONG_MATCH_OPT + + if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit) + break; + + { + for (;;) + { + hash++; + pos++; + cur++; + lenLimit++; + { + CLzRef *ptr = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2; + #if 0 + *(UInt64 *)(void *)ptr = ((const UInt64 *)(const void *)ptr)[diff]; + #else + const UInt32 p0 = ptr[0 + (diff * 2)]; + const UInt32 p1 = ptr[1 + (diff * 2)]; + ptr[0] = p0; + ptr[1] = p1; + // ptr[0] = ptr[0 + (diff * 2)]; + // ptr[1] = ptr[1 + (diff * 2)]; + #endif + } + // PrintSon(son + 2, pos - 1); + // printf("\npos = %x delta = %x\n", pos, delta); + len++; + *d++ = 2; + *d++ = (UInt32)(len - cur); + *d++ = delta - 1; + if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit) + break; + } + } + #endif + + break; + } + } + } + + { + const UInt32 curMatch = (UInt32)pos - delta; // (UInt32)(pos + diff); + if (len[diff] < len[0]) + { + delta = pair[1]; + if (delta >= curMatch) + return NULL; + *ptr1 = curMatch; + ptr1 = pair + 1; + len1 = len; + } + else + { + delta = *pair; + if (delta >= curMatch) + return NULL; + *ptr0 = curMatch; + ptr0 = pair; + len0 = len; + } + + delta = (UInt32)pos - delta; + + if (--cutValue == 0 || delta >= pos) + { + *ptr0 = *ptr1 = kEmptyHashValue; + _distances[-1] = (UInt32)(d - _distances); + break; + } + } + } + } // for (tree iterations) +} + pos++; + cur++; + } + while (d < limit); + *posRes = (UInt32)pos; + return d; +} +*/ + +/* define cbs if you use 2 functions. + GetMatchesSpecN_1() : (pos < _cyclicBufferSize) + GetMatchesSpecN_2() : (pos >= _cyclicBufferSize) + + do not define cbs if you use 1 function: + GetMatchesSpecN_2() +*/ + +// #define cbs _cyclicBufferSize + +/* + we use size_t for (pos) and (_cyclicBufferPos_ instead of UInt32 + to eliminate "movsx" BUG in old MSVC x64 compiler. +*/ + +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, + UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, + UInt32 *posRes); + +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, + UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, + UInt32 *posRes) +{ + do // while (hash != size) + { + UInt32 delta; + + #ifndef cbs + UInt32 cbs; + #endif + + if (hash == size) + break; + + delta = *hash++; + + if (delta == 0) + return NULL; + + lenLimit++; + + #ifndef cbs + cbs = _cyclicBufferSize; + if ((UInt32)pos < cbs) + { + if (delta > (UInt32)pos) + return NULL; + cbs = (UInt32)pos; + } + #endif + + if (delta >= cbs) + { + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + *d++ = 0; + ptr1[0] = kEmptyHashValue; + ptr1[1] = kEmptyHashValue; + } +else +{ + UInt32 *_distances = ++d; + + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + + UInt32 cutValue = _cutValue; + const Byte *len0 = cur, *len1 = cur; + const Byte *maxLen = cur + _maxLen; + + // if (cutValue == 0) { *ptr0 = *ptr1 = kEmptyHashValue; } else + for (LOG_ITER(g_NumIters_Tree++);;) + { + LOG_ITER(g_NumIters_Loop++); + { + // SPEC code + CLzRef *pair = son + ((size_t)((ptrdiff_t)_cyclicBufferPos - (ptrdiff_t)delta + + (ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0) + ) << 1); + + const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + const Byte *len = (len0 < len1 ? len0 : len1); + + #ifdef USE_SON_PREFETCH + const UInt32 pair0 = *pair; + #endif + + if (len[diff] == len[0]) + { + if (++len != lenLimit && len[diff] == len[0]) + while (++len != lenLimit) + { + LOG_ITER(g_NumIters_Bytes++); + if (len[diff] != len[0]) + break; + } + if (maxLen < len) + { + maxLen = len; + *d++ = (UInt32)(len - cur); + *d++ = delta - 1; + + if (len == lenLimit) + { + const UInt32 pair1 = pair[1]; + *ptr1 = + #ifdef USE_SON_PREFETCH + pair0; + #else + pair[0]; + #endif + *ptr0 = pair1; + + _distances[-1] = (UInt32)(d - _distances); + + #ifdef USE_LONG_MATCH_OPT + + if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit) + break; + + { + for (;;) + { + *d++ = 2; + *d++ = (UInt32)(lenLimit - cur); + *d++ = delta - 1; + cur++; + lenLimit++; + // SPEC + _cyclicBufferPos++; + { + // SPEC code + CLzRef *dest = son + ((size_t)(_cyclicBufferPos) << 1); + const CLzRef *src = dest + ((diff + + (ptrdiff_t)(UInt32)((_cyclicBufferPos < delta) ? cbs : 0)) << 1); + // CLzRef *ptr = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2; + #if 0 + *(UInt64 *)(void *)dest = *((const UInt64 *)(const void *)src); + #else + const UInt32 p0 = src[0]; + const UInt32 p1 = src[1]; + dest[0] = p0; + dest[1] = p1; + #endif + } + pos++; + hash++; + if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit) + break; + } // for() end for long matches + } + #endif + + break; // break from TREE iterations + } + } + } + { + const UInt32 curMatch = (UInt32)pos - delta; // (UInt32)(pos + diff); + if (len[diff] < len[0]) + { + delta = pair[1]; + *ptr1 = curMatch; + ptr1 = pair + 1; + len1 = len; + if (delta >= curMatch) + return NULL; + } + else + { + delta = *pair; + *ptr0 = curMatch; + ptr0 = pair; + len0 = len; + if (delta >= curMatch) + return NULL; + } + delta = (UInt32)pos - delta; + + if (--cutValue == 0 || delta >= cbs) + { + *ptr0 = *ptr1 = kEmptyHashValue; + _distances[-1] = (UInt32)(d - _distances); + break; + } + } + } + } // for (tree iterations) +} + pos++; + _cyclicBufferPos++; + cur++; + } + while (d < limit); + *posRes = (UInt32)pos; + return d; +} + + + +/* +typedef UInt32 uint32plus; // size_t + +UInt32 * Z7_FASTCALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son, + UInt32 _cutValue, UInt32 *d, uint32plus _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, + size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, + UInt32 *posRes) +{ + do // while (hash != size) + { + UInt32 delta; + + #ifndef cbs + UInt32 cbs; + #endif + + if (hash == size) + break; + + delta = *hash++; + + if (delta == 0) + return NULL; + + #ifndef cbs + cbs = _cyclicBufferSize; + if ((UInt32)pos < cbs) + { + if (delta > (UInt32)pos) + return NULL; + cbs = (UInt32)pos; + } + #endif + + if (delta >= cbs) + { + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + *d++ = 0; + ptr1[0] = kEmptyHashValue; + ptr1[1] = kEmptyHashValue; + } +else +{ + CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1); + UInt32 *_distances = ++d; + uint32plus len0 = 0, len1 = 0; + UInt32 cutValue = _cutValue; + uint32plus maxLen = _maxLen; + // lenLimit++; // const Byte *lenLimit = cur + _lenLimit; + + for (LOG_ITER(g_NumIters_Tree++);;) + { + LOG_ITER(g_NumIters_Loop++); + { + // const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + CLzRef *pair = son + ((size_t)((ptrdiff_t)_cyclicBufferPos - delta + + (ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0) + ) << 1); + const Byte *pb = cur - delta; + uint32plus len = (len0 < len1 ? len0 : len1); + + #ifdef USE_SON_PREFETCH + const UInt32 pair0 = *pair; + #endif + + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while (++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + maxLen = len; + *d++ = (UInt32)len; + *d++ = delta - 1; + if (len == lenLimit) + { + { + const UInt32 pair1 = pair[1]; + *ptr0 = pair1; + *ptr1 = + #ifdef USE_SON_PREFETCH + pair0; + #else + pair[0]; + #endif + } + + _distances[-1] = (UInt32)(d - _distances); + + #ifdef USE_LONG_MATCH_OPT + + if (hash == size || *hash != delta || pb[lenLimit] != cur[lenLimit] || d >= limit) + break; + + { + const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta; + for (;;) + { + *d++ = 2; + *d++ = (UInt32)lenLimit; + *d++ = delta - 1; + _cyclicBufferPos++; + { + CLzRef *dest = son + ((size_t)_cyclicBufferPos << 1); + const CLzRef *src = dest + ((diff + + (ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0)) << 1); + #if 0 + *(UInt64 *)(void *)dest = *((const UInt64 *)(const void *)src); + #else + const UInt32 p0 = src[0]; + const UInt32 p1 = src[1]; + dest[0] = p0; + dest[1] = p1; + #endif + } + hash++; + pos++; + cur++; + pb++; + if (hash == size || *hash != delta || pb[lenLimit] != cur[lenLimit] || d >= limit) + break; + } + } + #endif + + break; + } + } + } + { + const UInt32 curMatch = (UInt32)pos - delta; + if (pb[len] < cur[len]) + { + delta = pair[1]; + *ptr1 = curMatch; + ptr1 = pair + 1; + len1 = len; + } + else + { + delta = *pair; + *ptr0 = curMatch; + ptr0 = pair; + len0 = len; + } + + { + if (delta >= curMatch) + return NULL; + delta = (UInt32)pos - delta; + if (delta >= cbs + // delta >= _cyclicBufferSize || delta >= pos + || --cutValue == 0) + { + *ptr0 = *ptr1 = kEmptyHashValue; + _distances[-1] = (UInt32)(d - _distances); + break; + } + } + } + } + } // for (tree iterations) +} + pos++; + _cyclicBufferPos++; + cur++; + } + while (d < limit); + *posRes = (UInt32)pos; + return d; +} +*/ diff -Nru p7zip-rar-16.02/C/LzHash.h p7zip-rar-16.02+really25.00+ds/C/LzHash.h --- p7zip-rar-16.02/C/LzHash.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzHash.h 2023-03-05 17:00:00.000000000 +0000 @@ -1,57 +1,34 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2015-04-12 : Igor Pavlov : Public domain */ - -#ifndef __LZ_HASH_H -#define __LZ_HASH_H - -#define kHash2Size (1 << 10) -#define kHash3Size (1 << 16) -#define kHash4Size (1 << 20) - -#define kFix3HashSize (kHash2Size) -#define kFix4HashSize (kHash2Size + kHash3Size) -#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) - -#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8); - -#define HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - h2 = temp & (kHash2Size - 1); \ - hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } - -#define HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - h2 = temp & (kHash2Size - 1); \ - temp ^= ((UInt32)cur[2] << 8); \ - h3 = temp & (kHash3Size - 1); \ - hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; } - -#define HASH5_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - h2 = temp & (kHash2Size - 1); \ - temp ^= ((UInt32)cur[2] << 8); \ - h3 = temp & (kHash3Size - 1); \ - temp ^= (p->crc[cur[3]] << 5); \ - h4 = temp & (kHash4Size - 1); \ - hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; } - -/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; - - -#define MT_HASH2_CALC \ - h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); - -#define MT_HASH3_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - h2 = temp & (kHash2Size - 1); \ - h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } - -#define MT_HASH4_CALC { \ - UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ - h2 = temp & (kHash2Size - 1); \ - temp ^= ((UInt32)cur[2] << 8); \ - h3 = temp & (kHash3Size - 1); \ - h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } - -#endif +/* LzHash.h -- HASH constants for LZ algorithms +2023-03-05 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZ_HASH_H +#define ZIP7_INC_LZ_HASH_H + +/* + (kHash2Size >= (1 << 8)) : Required + (kHash3Size >= (1 << 16)) : Required +*/ + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +// #define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +// #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +/* + We use up to 3 crc values for hash: + crc0 + crc1 << Shift_1 + crc2 << Shift_2 + (Shift_1 = 5) and (Shift_2 = 10) is good tradeoff. + Small values for Shift are not good for collision rate. + Big value for Shift_2 increases the minimum size + of hash table, that will be slow for small files. +*/ + +#define kLzHash_CrcShift_1 5 +#define kLzHash_CrcShift_2 10 + +#endif diff -Nru p7zip-rar-16.02/C/Lzma2Dec.c p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.c --- p7zip-rar-16.02/C/Lzma2Dec.c 2015-11-20 20:40:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.c 2024-03-01 07:00:00.000000000 +0000 @@ -1,378 +1,493 @@ -/* Lzma2Dec.c -- LZMA2 Decoder -2015-11-09 : Igor Pavlov : Public domain */ - -/* #define SHOW_DEBUG_INFO */ - -#include "Precomp.h" - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include - -#include "Lzma2Dec.h" - -/* -00000000 - EOS -00000001 U U - Uncompressed Reset Dic -00000010 U U - Uncompressed No Reset -100uuuuu U U P P - LZMA no reset -101uuuuu U U P P - LZMA reset state -110uuuuu U U P P S - LZMA reset state + new prop -111uuuuu U U P P S - LZMA reset state + new prop + reset dic - - u, U - Unpack Size - P - Pack Size - S - Props -*/ - -#define LZMA2_CONTROL_LZMA (1 << 7) -#define LZMA2_CONTROL_COPY_NO_RESET 2 -#define LZMA2_CONTROL_COPY_RESET_DIC 1 -#define LZMA2_CONTROL_EOF 0 - -#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) - -#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) -#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) - -#define LZMA2_LCLP_MAX 4 -#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -typedef enum -{ - LZMA2_STATE_CONTROL, - LZMA2_STATE_UNPACK0, - LZMA2_STATE_UNPACK1, - LZMA2_STATE_PACK0, - LZMA2_STATE_PACK1, - LZMA2_STATE_PROP, - LZMA2_STATE_DATA, - LZMA2_STATE_DATA_CONT, - LZMA2_STATE_FINISHED, - LZMA2_STATE_ERROR -} ELzma2State; - -static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) -{ - UInt32 dicSize; - if (prop > 40) - return SZ_ERROR_UNSUPPORTED; - dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); - props[0] = (Byte)LZMA2_LCLP_MAX; - props[1] = (Byte)(dicSize); - props[2] = (Byte)(dicSize >> 8); - props[3] = (Byte)(dicSize >> 16); - props[4] = (Byte)(dicSize >> 24); - return SZ_OK; -} - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) -{ - Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) -{ - Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -void Lzma2Dec_Init(CLzma2Dec *p) -{ - p->state = LZMA2_STATE_CONTROL; - p->needInitDic = True; - p->needInitState = True; - p->needInitProp = True; - LzmaDec_Init(&p->decoder); -} - -static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) -{ - switch (p->state) - { - case LZMA2_STATE_CONTROL: - p->control = b; - PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos)); - PRF(printf(" %2X", (unsigned)b)); - if (p->control == 0) - return LZMA2_STATE_FINISHED; - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if ((p->control & 0x7F) > 2) - return LZMA2_STATE_ERROR; - p->unpackSize = 0; - } - else - p->unpackSize = (UInt32)(p->control & 0x1F) << 16; - return LZMA2_STATE_UNPACK0; - - case LZMA2_STATE_UNPACK0: - p->unpackSize |= (UInt32)b << 8; - return LZMA2_STATE_UNPACK1; - - case LZMA2_STATE_UNPACK1: - p->unpackSize |= (UInt32)b; - p->unpackSize++; - PRF(printf(" %8u", (unsigned)p->unpackSize)); - return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; - - case LZMA2_STATE_PACK0: - p->packSize = (UInt32)b << 8; - return LZMA2_STATE_PACK1; - - case LZMA2_STATE_PACK1: - p->packSize |= (UInt32)b; - p->packSize++; - PRF(printf(" %8u", (unsigned)p->packSize)); - return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: - (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); - - case LZMA2_STATE_PROP: - { - unsigned lc, lp; - if (b >= (9 * 5 * 5)) - return LZMA2_STATE_ERROR; - lc = b % 9; - b /= 9; - p->decoder.prop.pb = b / 5; - lp = b % 5; - if (lc + lp > LZMA2_LCLP_MAX) - return LZMA2_STATE_ERROR; - p->decoder.prop.lc = lc; - p->decoder.prop.lp = lp; - p->needInitProp = False; - return LZMA2_STATE_DATA; - } - } - return LZMA2_STATE_ERROR; -} - -static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) -{ - memcpy(p->dic + p->dicPos, src, size); - p->dicPos += size; - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) - p->checkDicSize = p->prop.dicSize; - p->processedPos += (UInt32)size; -} - -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT inSize = *srcLen; - *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->state != LZMA2_STATE_FINISHED) - { - SizeT dicPos = p->decoder.dicPos; - - if (p->state == LZMA2_STATE_ERROR) - return SZ_ERROR_DATA; - - if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - - if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - (*srcLen)++; - p->state = Lzma2Dec_UpdateState(p, *src++); - - if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - continue; - } - - { - SizeT destSizeCur = dicLimit - dicPos; - SizeT srcSizeCur = inSize - *srcLen; - ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; - - if (p->unpackSize <= destSizeCur) - { - destSizeCur = (SizeT)p->unpackSize; - curFinishMode = LZMA_FINISH_END; - } - - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - - if (p->state == LZMA2_STATE_DATA) - { - Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); - if (initDic) - p->needInitProp = p->needInitState = True; - else if (p->needInitDic) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - p->needInitDic = False; - LzmaDec_InitDicAndState(&p->decoder, initDic, False); - } - - if (srcSizeCur > destSizeCur) - srcSizeCur = destSizeCur; - - if (srcSizeCur == 0) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - - LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->unpackSize -= (UInt32)srcSizeCur; - p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; - } - else - { - SizeT outSizeProcessed; - SRes res; - - if (p->state == LZMA2_STATE_DATA) - { - unsigned mode = LZMA2_GET_LZMA_MODE(p); - Bool initDic = (mode == 3); - Bool initState = (mode != 0); - if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - - LzmaDec_InitDicAndState(&p->decoder, initDic, initState); - p->needInitDic = False; - p->needInitState = False; - p->state = LZMA2_STATE_DATA_CONT; - } - - if (srcSizeCur > p->packSize) - srcSizeCur = (SizeT)p->packSize; - - res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->packSize -= (UInt32)srcSizeCur; - - outSizeProcessed = p->decoder.dicPos - dicPos; - p->unpackSize -= (UInt32)outSizeProcessed; - - RINOK(res); - if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) - return res; - - if (srcSizeCur == 0 && outSizeProcessed == 0) - { - if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - || p->unpackSize != 0 - || p->packSize != 0) - { - p->state = LZMA2_STATE_ERROR; - return SZ_ERROR_DATA; - } - p->state = LZMA2_STATE_CONTROL; - } - - if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - *status = LZMA_STATUS_NOT_FINISHED; - } - } - } - - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return SZ_OK; -} - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT outSize = *destLen, inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - SizeT srcSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->decoder.dicPos == p->decoder.dicBufSize) - p->decoder.dicPos = 0; - dicPos = p->decoder.dicPos; - if (outSize > p->decoder.dicBufSize - dicPos) - { - outSizeCur = p->decoder.dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); - src += srcSizeCur; - inSize -= srcSizeCur; - *srcLen += srcSizeCur; - outSizeCur = p->decoder.dicPos - dicPos; - memcpy(dest, p->decoder.dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzma2Dec p; - SRes res; - SizeT outSize = *destLen, inSize = *srcLen; - *destLen = *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - Lzma2Dec_Construct(&p); - RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); - p.decoder.dic = dest; - p.decoder.dicBufSize = outSize; - Lzma2Dec_Init(&p); - *srcLen = inSize; - res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - *destLen = p.decoder.dicPos; - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - Lzma2Dec_FreeProbs(&p, alloc); - return res; -} +/* Lzma2Dec.c -- LZMA2 Decoder +2024-03-01 : Igor Pavlov : Public domain */ + +/* #define SHOW_DEBUG_INFO */ + +#include "Precomp.h" + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include + +#include "Lzma2Dec.h" + +/* +00000000 - End of data +00000001 U U - Uncompressed, reset dic, need reset state and set new prop +00000010 U U - Uncompressed, no reset +100uuuuu U U P P - LZMA, no reset +101uuuuu U U P P - LZMA, reset state +110uuuuu U U P P S - LZMA, reset state + set new prop +111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic + + u, U - Unpack Size + P - Pack Size + S - Props +*/ + +#define LZMA2_CONTROL_COPY_RESET_DIC 1 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +typedef enum +{ + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) +{ + UInt32 dicSize; + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (Byte)LZMA2_LCLP_MAX; + props[1] = (Byte)(dicSize); + props[2] = (Byte)(dicSize >> 8); + props[3] = (Byte)(dicSize >> 16); + props[4] = (Byte)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)) + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) +{ + Byte props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)) + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitLevel = 0xE0; + p->isExtraMode = False; + p->unpackSize = 0; + + // p->decoder.dicPos = 0; // we can use it instead of full init + LzmaDec_Init(&p->decoder); +} + +// ELzma2State +static unsigned Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) +{ + switch (p->state) + { + case LZMA2_STATE_CONTROL: + p->isExtraMode = False; + p->control = b; + PRF(printf("\n %8X", (unsigned)p->decoder.dicPos)); + PRF(printf(" %02X", (unsigned)b)); + if (b == 0) + return LZMA2_STATE_FINISHED; + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (b == LZMA2_CONTROL_COPY_RESET_DIC) + p->needInitLevel = 0xC0; + else if (b > 2 || p->needInitLevel == 0xE0) + return LZMA2_STATE_ERROR; + } + else + { + if (b < p->needInitLevel) + return LZMA2_STATE_ERROR; + p->needInitLevel = 0; + p->unpackSize = (UInt32)(b & 0x1F) << 16; + } + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (UInt32)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (UInt32)b; + p->unpackSize++; + PRF(printf(" %7u", (unsigned)p->unpackSize)); + return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (UInt32)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (UInt32)b; + p->packSize++; + // if (p->packSize < 5) return LZMA2_STATE_ERROR; + PRF(printf(" %5u", (unsigned)p->packSize)); + return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA; + + case LZMA2_STATE_PROP: + { + unsigned lc, lp; + if (b >= (9 * 5 * 5)) + return LZMA2_STATE_ERROR; + lc = b % 9; + b /= 9; + p->decoder.prop.pb = (Byte)(b / 5); + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) + return LZMA2_STATE_ERROR; + p->decoder.prop.lc = (Byte)lc; + p->decoder.prop.lp = (Byte)lp; + return LZMA2_STATE_DATA; + } + + default: + return LZMA2_STATE_ERROR; + } +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) + p->checkDicSize = p->prop.dicSize; + p->processedPos += (UInt32)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); + + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_ERROR) + { + SizeT dicPos; + + if (p->state == LZMA2_STATE_FINISHED) + { + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + + dicPos = p->decoder.dicPos; + + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) + break; + continue; + } + + { + SizeT inCur = inSize - *srcLen; + SizeT outCur = dicLimit - dicPos; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (outCur >= p->unpackSize) + { + outCur = (SizeT)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (inCur == 0) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) + { + BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + LzmaDec_InitDicAndState(&p->decoder, initDic, False); + } + + if (inCur > outCur) + inCur = outCur; + if (inCur == 0) + break; + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); + + src += inCur; + *srcLen += inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + SRes res; + + if (p->state == LZMA2_STATE_DATA) + { + BoolInt initDic = (p->control >= 0xE0); + BoolInt initState = (p->control >= 0xA0); + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->state = LZMA2_STATE_DATA_CONT; + } + + if (inCur > p->packSize) + inCur = (SizeT)p->packSize; + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + outCur = p->decoder.dicPos - dicPos; + p->unpackSize -= (UInt32)outCur; + + if (res != 0) + break; + + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (p->packSize == 0) + break; + return SZ_OK; + } + + if (inCur == 0 && outCur == 0) + { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + || p->unpackSize != 0 + || p->packSize != 0) + break; + p->state = LZMA2_STATE_CONTROL; + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + } + } + } + + *status = LZMA_STATUS_NOT_SPECIFIED; + p->state = LZMA2_STATE_ERROR; + return SZ_ERROR_DATA; +} + + + + +ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, + SizeT outSize, + const Byte *src, SizeT *srcLen, + int checkFinishBlock) +{ + SizeT inSize = *srcLen; + *srcLen = 0; + + while (p->state != LZMA2_STATE_ERROR) + { + if (p->state == LZMA2_STATE_FINISHED) + return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK; + + if (outSize == 0 && !checkFinishBlock) + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + (*srcLen)++; + + p->state = Lzma2Dec_UpdateState(p, *src++); + + if (p->state == LZMA2_STATE_UNPACK0) + { + // if (p->decoder.dicPos != 0) + if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0) + return LZMA2_PARSE_STATUS_NEW_BLOCK; + // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; + } + + // The following code can be commented. + // It's not big problem, if we read additional input bytes. + // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state. + + if (outSize == 0 && p->state != LZMA2_STATE_FINISHED) + { + // checkFinishBlock is true. So we expect that block must be finished, + // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here + // break; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + } + + if (p->state == LZMA2_STATE_DATA) + return LZMA2_PARSE_STATUS_NEW_CHUNK; + + continue; + } + + if (outSize == 0) + return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; + + { + SizeT inCur = inSize - *srcLen; + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (inCur == 0) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + if (inCur > p->unpackSize) + inCur = p->unpackSize; + if (inCur > outSize) + inCur = outSize; + p->decoder.dicPos += inCur; + src += inCur; + *srcLen += inCur; + outSize -= inCur; + p->unpackSize -= (UInt32)inCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + p->isExtraMode = True; + + if (inCur == 0) + { + if (p->packSize != 0) + return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; + } + else if (p->state == LZMA2_STATE_DATA) + { + p->state = LZMA2_STATE_DATA_CONT; + if (*src != 0) + { + // first byte of lzma chunk must be Zero + *srcLen += 1; + p->packSize--; + break; + } + } + + if (inCur > p->packSize) + inCur = (SizeT)p->packSize; + + src += inCur; + *srcLen += inCur; + p->packSize -= (UInt32)inCur; + + if (p->packSize == 0) + { + SizeT rem = outSize; + if (rem > p->unpackSize) + rem = p->unpackSize; + p->decoder.dicPos += rem; + p->unpackSize -= (UInt32)rem; + outSize -= rem; + if (p->unpackSize == 0) + p->state = LZMA2_STATE_CONTROL; + } + } + } + } + + p->state = LZMA2_STATE_ERROR; + return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; +} + + + + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + + for (;;) + { + SizeT inCur = inSize, outCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + + if (p->decoder.dicPos == p->decoder.dicBufSize) + p->decoder.dicPos = 0; + dicPos = p->decoder.dicPos; + curFinishMode = LZMA_FINISH_ANY; + outCur = p->decoder.dicBufSize - dicPos; + + if (outCur >= outSize) + { + outCur = outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); + + src += inCur; + inSize -= inCur; + *srcLen += inCur; + outCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outCur); + dest += outCur; + outSize -= outCur; + *destLen += outCur; + if (res != 0) + return res; + if (outCur == 0 || outSize == 0) + return SZ_OK; + } +} + + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) +{ + CLzma2Dec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + Lzma2Dec_CONSTRUCT(&p) + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)) + p.decoder.dic = dest; + p.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&p); + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + Lzma2Dec_FreeProbs(&p, alloc); + return res; +} + +#undef PRF diff -Nru p7zip-rar-16.02/C/Lzma2Dec.h p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.h --- p7zip-rar-16.02/C/Lzma2Dec.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2Dec.h 2023-03-03 12:00:00.000000000 +0000 @@ -1,80 +1,121 @@ -/* Lzma2Dec.h -- LZMA2 Decoder -2015-05-13 : Igor Pavlov : Public domain */ - -#ifndef __LZMA2_DEC_H -#define __LZMA2_DEC_H - -#include "LzmaDec.h" - -EXTERN_C_BEGIN - -/* ---------- State Interface ---------- */ - -typedef struct -{ - CLzmaDec decoder; - UInt32 packSize; - UInt32 unpackSize; - unsigned state; - Byte control; - Bool needInitDic; - Bool needInitState; - Bool needInitProp; -} CLzma2Dec; - -#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) -#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); -#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); -SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); -void Lzma2Dec_Init(CLzma2Dec *p); - - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen or dicLimit). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - SZ_ERROR_DATA - Data error -*/ - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); - -EXTERN_C_END - -#endif +/* Lzma2Dec.h -- LZMA2 Decoder +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_DEC_H +#define ZIP7_INC_LZMA2_DEC_H + +#include "LzmaDec.h" + +EXTERN_C_BEGIN + +/* ---------- State Interface ---------- */ + +typedef struct +{ + unsigned state; + Byte control; + Byte needInitLevel; + Byte isExtraMode; + Byte _pad_; + UInt32 packSize; + UInt32 unpackSize; + CLzmaDec decoder; +} CLzma2Dec; + +#define Lzma2Dec_CONSTRUCT(p) LzmaDec_CONSTRUCT(&(p)->decoder) +#define Lzma2Dec_Construct(p) Lzma2Dec_CONSTRUCT(p) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- LZMA2 block and chunk parsing ---------- */ + +/* +Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data. +It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code: + - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input. + - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read. + CLzma2Dec::unpackSize contains unpack size of that chunk +*/ + +typedef enum +{ +/* + LZMA_STATUS_NOT_SPECIFIED // data error + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED // + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused +*/ + LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1, + LZMA2_PARSE_STATUS_NEW_CHUNK +} ELzma2ParseStatus; + +ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, + SizeT outSize, // output size + const Byte *src, SizeT *srcLen, + int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position. + ); + +/* +LZMA2 parser doesn't decode LZMA chunks, so we must read + full input LZMA chunk to decode some part of LZMA chunk. + +Lzma2Dec_GetUnpackExtra() returns the value that shows + max possible number of output bytes that can be output by decoder + at current input positon. +*/ + +#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0) + + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Lzma2DecMt.c p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.c --- p7zip-rar-16.02/C/Lzma2DecMt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.c 2023-04-13 08:00:00.000000000 +0000 @@ -0,0 +1,1095 @@ +/* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #define SHOW_DEBUG_INFO +// #define Z7_ST + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "Alloc.h" + +#include "Lzma2Dec.h" +#include "Lzma2DecMt.h" + +#ifndef Z7_ST +#include "MtDec.h" + +#define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28) +#endif + + +#ifndef Z7_ST +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif +#define PRF_STR(s) PRF(printf("\n" s "\n");) +#define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2);) +#endif + + +void Lzma2DecMtProps_Init(CLzma2DecMtProps *p) +{ + p->inBufSize_ST = 1 << 20; + p->outStep_ST = 1 << 20; + + #ifndef Z7_ST + p->numThreads = 1; + p->inBufSize_MT = 1 << 18; + p->outBlockMax = LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT; + p->inBlockMax = p->outBlockMax + p->outBlockMax / 16; + #endif +} + + + +#ifndef Z7_ST + +/* ---------- CLzma2DecMtThread ---------- */ + +typedef struct +{ + CLzma2Dec dec; + Byte dec_created; + Byte needInit; + + Byte *outBuf; + size_t outBufSize; + + EMtDecParseState state; + ELzma2ParseStatus parseStatus; + + size_t inPreSize; + size_t outPreSize; + + size_t inCodeSize; + size_t outCodeSize; + SRes codeRes; + + CAlignOffsetAlloc alloc; + + Byte mtPad[1 << 7]; +} CLzma2DecMtThread; + +#endif + + +/* ---------- CLzma2DecMt ---------- */ + +struct CLzma2DecMt +{ + // ISzAllocPtr alloc; + ISzAllocPtr allocMid; + + CAlignOffsetAlloc alignOffsetAlloc; + CLzma2DecMtProps props; + Byte prop; + + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; + + BoolInt finishMode; + BoolInt outSize_Defined; + UInt64 outSize; + + UInt64 outProcessed; + UInt64 inProcessed; + BoolInt readWasFinished; + SRes readRes; + + Byte *inBuf; + size_t inBufSize; + Byte dec_created; + CLzma2Dec dec; + + size_t inPos; + size_t inLim; + + #ifndef Z7_ST + UInt64 outProcessed_Parse; + BoolInt mtc_WasConstructed; + CMtDec mtc; + CLzma2DecMtThread coders[MTDEC_THREADS_MAX]; + #endif +}; + + + +CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) +{ + CLzma2DecMt *p = (CLzma2DecMt *)ISzAlloc_Alloc(alloc, sizeof(CLzma2DecMt)); + if (!p) + return NULL; + + // p->alloc = alloc; + p->allocMid = allocMid; + + AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); + p->alignOffsetAlloc.numAlignBits = 7; + p->alignOffsetAlloc.offset = 0; + p->alignOffsetAlloc.baseAlloc = alloc; + + p->inBuf = NULL; + p->inBufSize = 0; + p->dec_created = False; + + // Lzma2DecMtProps_Init(&p->props); + + #ifndef Z7_ST + p->mtc_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + t->dec_created = False; + t->outBuf = NULL; + t->outBufSize = 0; + } + } + #endif + + return (CLzma2DecMtHandle)(void *)p; +} + + +#ifndef Z7_ST + +static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + if (t->outBuf) + { + ISzAlloc_Free(p->allocMid, t->outBuf); + t->outBuf = NULL; + t->outBufSize = 0; + } + } +} + +#endif + + +static void Lzma2DecMt_FreeSt(CLzma2DecMt *p) +{ + if (p->dec_created) + { + Lzma2Dec_Free(&p->dec, &p->alignOffsetAlloc.vt); + p->dec_created = False; + } + if (p->inBuf) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBuf = NULL; + } + p->inBufSize = 0; +} + + +// #define GET_CLzma2DecMt_p CLzma2DecMt *p = (CLzma2DecMt *)(void *)pp; + +void Lzma2DecMt_Destroy(CLzma2DecMtHandle p) +{ + // GET_CLzma2DecMt_p + + Lzma2DecMt_FreeSt(p); + + #ifndef Z7_ST + + if (p->mtc_WasConstructed) + { + MtDec_Destruct(&p->mtc); + p->mtc_WasConstructed = False; + } + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + if (t->dec_created) + { + // we don't need to free dict here + Lzma2Dec_FreeProbs(&t->dec, &t->alloc.vt); // p->alloc !!! + t->dec_created = False; + } + } + } + Lzma2DecMt_FreeOutBufs(p); + + #endif + + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); +} + + + +#ifndef Z7_ST + +static void Lzma2DecMt_MtCallback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) +{ + CLzma2DecMt *me = (CLzma2DecMt *)obj; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + + PRF_STR_INT_2("Parse", coderIndex, cc->srcSize) + + cc->state = MTDEC_PARSE_CONTINUE; + + if (cc->startCall) + { + if (!t->dec_created) + { + Lzma2Dec_CONSTRUCT(&t->dec) + t->dec_created = True; + AlignOffsetAlloc_CreateVTable(&t->alloc); + { + /* (1 << 12) is expected size of one way in data cache. + We optimize alignment for cache line size of 128 bytes and smaller */ + const unsigned kNumAlignBits = 12; + const unsigned kNumCacheLineBits = 7; /* <= kNumAlignBits */ + t->alloc.numAlignBits = kNumAlignBits; + t->alloc.offset = ((UInt32)coderIndex * (((unsigned)1 << 11) + (1 << 8) + (1 << 6))) & (((unsigned)1 << kNumAlignBits) - ((unsigned)1 << kNumCacheLineBits)); + t->alloc.baseAlloc = me->alignOffsetAlloc.baseAlloc; + } + } + Lzma2Dec_Init(&t->dec); + + t->inPreSize = 0; + t->outPreSize = 0; + // t->blockWasFinished = False; + // t->finishedWithMark = False; + t->parseStatus = (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; + t->state = MTDEC_PARSE_CONTINUE; + + t->inCodeSize = 0; + t->outCodeSize = 0; + t->codeRes = SZ_OK; + + // (cc->srcSize == 0) is allowed + } + + { + ELzma2ParseStatus status; + BoolInt overflow; + UInt32 unpackRem = 0; + + int checkFinishBlock = True; + size_t limit = me->props.outBlockMax; + if (me->outSize_Defined) + { + UInt64 rem = me->outSize - me->outProcessed_Parse; + if (limit >= rem) + { + limit = (size_t)rem; + if (!me->finishMode) + checkFinishBlock = False; + } + } + + // checkFinishBlock = False, if we want to decode partial data + // that must be finished at position <= outBlockMax. + + { + const size_t srcOrig = cc->srcSize; + SizeT srcSize_Point = 0; + SizeT dicPos_Point = 0; + + cc->srcSize = 0; + overflow = False; + + for (;;) + { + SizeT srcCur = (SizeT)(srcOrig - cc->srcSize); + + status = Lzma2Dec_Parse(&t->dec, + (SizeT)limit - t->dec.decoder.dicPos, + cc->src + cc->srcSize, &srcCur, + checkFinishBlock); + + cc->srcSize += srcCur; + + if (status == LZMA2_PARSE_STATUS_NEW_CHUNK) + { + if (t->dec.unpackSize > me->props.outBlockMax - t->dec.decoder.dicPos) + { + overflow = True; + break; + } + continue; + } + + if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) + { + if (t->dec.decoder.dicPos == 0) + continue; + // we decode small blocks in one thread + if (t->dec.decoder.dicPos >= (1 << 14)) + break; + dicPos_Point = t->dec.decoder.dicPos; + srcSize_Point = (SizeT)cc->srcSize; + continue; + } + + if ((int)status == LZMA_STATUS_NOT_FINISHED && checkFinishBlock + // && limit == t->dec.decoder.dicPos + // && limit == me->props.outBlockMax + ) + { + overflow = True; + break; + } + + unpackRem = Lzma2Dec_GetUnpackExtra(&t->dec); + break; + } + + if (dicPos_Point != 0 + && (int)status != LZMA2_PARSE_STATUS_NEW_BLOCK + && (int)status != LZMA_STATUS_FINISHED_WITH_MARK + && (int)status != LZMA_STATUS_NOT_SPECIFIED) + { + // we revert to latest newBlock state + status = LZMA2_PARSE_STATUS_NEW_BLOCK; + unpackRem = 0; + t->dec.decoder.dicPos = dicPos_Point; + cc->srcSize = srcSize_Point; + overflow = False; + } + } + + t->inPreSize += cc->srcSize; + t->parseStatus = status; + + if (overflow) + cc->state = MTDEC_PARSE_OVERFLOW; + else + { + size_t dicPos = t->dec.decoder.dicPos; + + if ((int)status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) + { + cc->state = MTDEC_PARSE_NEW; + cc->srcSize--; // we don't need control byte of next block + t->inPreSize--; + } + else + { + cc->state = MTDEC_PARSE_END; + if ((int)status != LZMA_STATUS_FINISHED_WITH_MARK) + { + // (status == LZMA_STATUS_NOT_SPECIFIED) + // (status == LZMA_STATUS_NOT_FINISHED) + if (unpackRem != 0) + { + /* we also reserve space for max possible number of output bytes of current LZMA chunk */ + size_t rem = limit - dicPos; + if (rem > unpackRem) + rem = unpackRem; + dicPos += rem; + } + } + } + + me->outProcessed_Parse += dicPos; + } + + cc->outPos = dicPos; + t->outPreSize = (size_t)dicPos; + } + + t->state = cc->state; + return; + } +} + + +static SRes Lzma2DecMt_MtCallback_PreCode(void *pp, unsigned coderIndex) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + Byte *dest = t->outBuf; + + if (t->inPreSize == 0) + { + t->codeRes = SZ_ERROR_DATA; + return t->codeRes; + } + + if (!dest || t->outBufSize < t->outPreSize) + { + if (dest) + { + ISzAlloc_Free(me->allocMid, dest); + t->outBuf = NULL; + t->outBufSize = 0; + } + + dest = (Byte *)ISzAlloc_Alloc(me->allocMid, t->outPreSize + // + (1 << 28) + ); + // Sleep(200); + if (!dest) + return SZ_ERROR_MEM; + t->outBuf = dest; + t->outBufSize = t->outPreSize; + } + + t->dec.decoder.dic = dest; + t->dec.decoder.dicBufSize = (SizeT)t->outPreSize; + + t->needInit = True; + + return Lzma2Dec_AllocateProbs(&t->dec, me->prop, &t->alloc.vt); // alloc.vt +} + + +static SRes Lzma2DecMt_MtCallback_Code(void *pp, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + // int finished, int blockFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + + UNUSED_VAR(srcFinished) + + PRF_STR_INT_2("Code", coderIndex, srcSize) + + *inCodePos = t->inCodeSize; + *outCodePos = 0; + *stop = True; + + if (t->needInit) + { + Lzma2Dec_Init(&t->dec); + t->needInit = False; + } + + { + ELzmaStatus status; + SizeT srcProcessed = (SizeT)srcSize; + BoolInt blockWasFinished = + ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK); + + SRes res = Lzma2Dec_DecodeToDic(&t->dec, + (SizeT)t->outPreSize, + src, &srcProcessed, + blockWasFinished ? LZMA_FINISH_END : LZMA_FINISH_ANY, + &status); + + t->codeRes = res; + + t->inCodeSize += srcProcessed; + *inCodePos = t->inCodeSize; + t->outCodeSize = t->dec.decoder.dicPos; + *outCodePos = t->dec.decoder.dicPos; + + if (res != SZ_OK) + return res; + + if (srcProcessed == srcSize) + *stop = False; + + if (blockWasFinished) + { + if (srcSize != srcProcessed) + return SZ_ERROR_FAIL; + + if (t->inPreSize == t->inCodeSize) + { + if (t->outPreSize != t->outCodeSize) + return SZ_ERROR_FAIL; + *stop = True; + } + } + else + { + if (t->outPreSize == t->outCodeSize) + *stop = True; + } + + return SZ_OK; + } +} + + +#define LZMA2DECMT_STREAM_WRITE_STEP (1 << 24) + +static SRes Lzma2DecMt_MtCallback_Write(void *pp, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + BoolInt *needContinue, BoolInt *canRecode) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + const CLzma2DecMtThread *t = &me->coders[coderIndex]; + size_t size = t->outCodeSize; + const Byte *data = t->outBuf; + BoolInt needContinue2 = True; + + UNUSED_VAR(src) + UNUSED_VAR(srcSize) + UNUSED_VAR(isCross) + + PRF_STR_INT_2("Write", coderIndex, srcSize) + + *needContinue = False; + *canRecode = True; + + if ( + // t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + t->state == MTDEC_PARSE_OVERFLOW + || t->state == MTDEC_PARSE_END) + needContinue2 = False; + + + if (!needWriteToStream) + return SZ_OK; + + me->mtc.inProcessed += t->inCodeSize; + + if (t->codeRes == SZ_OK) + if ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK) + if (t->outPreSize != t->outCodeSize + || t->inPreSize != t->inCodeSize) + return SZ_ERROR_FAIL; + + *canRecode = False; + + if (me->outStream) + { + for (;;) + { + size_t cur = size; + size_t written; + if (cur > LZMA2DECMT_STREAM_WRITE_STEP) + cur = LZMA2DECMT_STREAM_WRITE_STEP; + + written = ISeqOutStream_Write(me->outStream, data, cur); + + me->outProcessed += written; + // me->mtc.writtenTotal += written; + if (written != cur) + return SZ_ERROR_WRITE; + data += cur; + size -= cur; + if (size == 0) + { + *needContinue = needContinue2; + return SZ_OK; + } + RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0)) + } + } + + return SZ_ERROR_FAIL; + /* + if (size > me->outBufSize) + return SZ_ERROR_OUTPUT_EOF; + memcpy(me->outBuf, data, size); + me->outBufSize -= size; + me->outBuf += size; + *needContinue = needContinue2; + return SZ_OK; + */ +} + +#endif + + +static SRes Lzma2Dec_Prepare_ST(CLzma2DecMt *p) +{ + if (!p->dec_created) + { + Lzma2Dec_CONSTRUCT(&p->dec) + p->dec_created = True; + } + + RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt)) + + if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBufSize = 0; + p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); + if (!p->inBuf) + return SZ_ERROR_MEM; + p->inBufSize = p->props.inBufSize_ST; + } + + Lzma2Dec_Init(&p->dec); + + return SZ_OK; +} + + +static SRes Lzma2Dec_Decode_ST(CLzma2DecMt *p + #ifndef Z7_ST + , BoolInt tMode + #endif + ) +{ + SizeT wrPos; + size_t inPos, inLim; + const Byte *inData; + UInt64 inPrev, outPrev; + + CLzma2Dec *dec; + + #ifndef Z7_ST + if (tMode) + { + Lzma2DecMt_FreeOutBufs(p); + tMode = MtDec_PrepareRead(&p->mtc); + } + #endif + + RINOK(Lzma2Dec_Prepare_ST(p)) + + dec = &p->dec; + + inPrev = p->inProcessed; + outPrev = p->outProcessed; + + inPos = 0; + inLim = 0; + inData = NULL; + wrPos = dec->decoder.dicPos; + + for (;;) + { + SizeT dicPos; + SizeT size; + ELzmaFinishMode finishMode; + SizeT inProcessed; + ELzmaStatus status; + SRes res; + + SizeT outProcessed; + BoolInt outFinished; + BoolInt needStop; + + if (inPos == inLim) + { + #ifndef Z7_ST + if (tMode) + { + inData = MtDec_Read(&p->mtc, &inLim); + inPos = 0; + if (inData) + continue; + tMode = False; + inLim = 0; + } + #endif + + if (!p->readWasFinished) + { + inPos = 0; + inLim = p->inBufSize; + inData = p->inBuf; + p->readRes = ISeqInStream_Read(p->inStream, (void *)(p->inBuf), &inLim); + // p->readProcessed += inLim; + // inLim -= 5; p->readWasFinished = True; // for test + if (inLim == 0 || p->readRes != SZ_OK) + p->readWasFinished = True; + } + } + + dicPos = dec->decoder.dicPos; + { + SizeT next = dec->decoder.dicBufSize; + if (next - wrPos > p->props.outStep_ST) + next = wrPos + (SizeT)p->props.outStep_ST; + size = next - dicPos; + } + + finishMode = LZMA_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (size >= rem) + { + size = (SizeT)rem; + if (p->finishMode) + finishMode = LZMA_FINISH_END; + } + } + + inProcessed = (SizeT)(inLim - inPos); + + res = Lzma2Dec_DecodeToDic(dec, dicPos + size, inData + inPos, &inProcessed, finishMode, &status); + + inPos += inProcessed; + p->inProcessed += inProcessed; + outProcessed = dec->decoder.dicPos - dicPos; + p->outProcessed += outProcessed; + + outFinished = (p->outSize_Defined && p->outSize <= p->outProcessed); + + needStop = (res != SZ_OK + || (inProcessed == 0 && outProcessed == 0) + || status == LZMA_STATUS_FINISHED_WITH_MARK + || (!p->finishMode && outFinished)); + + if (needStop || outProcessed >= size) + { + SRes res2; + { + size_t writeSize = dec->decoder.dicPos - wrPos; + size_t written = ISeqOutStream_Write(p->outStream, dec->decoder.dic + wrPos, writeSize); + res2 = (written == writeSize) ? SZ_OK : SZ_ERROR_WRITE; + } + + if (dec->decoder.dicPos == dec->decoder.dicBufSize) + dec->decoder.dicPos = 0; + wrPos = dec->decoder.dicPos; + + RINOK(res2) + + if (needStop) + { + if (res != SZ_OK) + return res; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (p->finishMode) + { + if (p->outSize_Defined && p->outSize != p->outProcessed) + return SZ_ERROR_DATA; + } + return SZ_OK; + } + + if (!p->finishMode && outFinished) + return SZ_OK; + + if (status == LZMA_STATUS_NEEDS_MORE_INPUT) + return SZ_ERROR_INPUT_EOF; + + return SZ_ERROR_DATA; + } + } + + if (p->progress) + { + UInt64 inDelta = p->inProcessed - inPrev; + UInt64 outDelta = p->outProcessed - outPrev; + if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) + { + RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed)) + inPrev = p->inProcessed; + outPrev = p->outProcessed; + } + } + } +} + + + +SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + ISeqOutStreamPtr outStream, const UInt64 *outDataSize, int finishMode, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + UInt64 *inProcessed, + // UInt64 *outProcessed, + int *isMT, + ICompressProgressPtr progress) +{ + // GET_CLzma2DecMt_p + #ifndef Z7_ST + BoolInt tMode; + #endif + + *inProcessed = 0; + + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + + p->prop = prop; + p->props = *props; + + p->inStream = inStream; + p->outStream = outStream; + p->progress = progress; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + p->finishMode = finishMode; + + p->outProcessed = 0; + p->inProcessed = 0; + + p->readWasFinished = False; + p->readRes = SZ_OK; + + *isMT = False; + + + #ifndef Z7_ST + + tMode = False; + + // p->mtc.parseRes = SZ_OK; + + // p->mtc.numFilledThreads = 0; + // p->mtc.crossStart = 0; + // p->mtc.crossEnd = 0; + // p->mtc.allocError_for_Read_BlockIndex = 0; + // p->mtc.isAllocError = False; + + if (p->props.numThreads > 1) + { + IMtDecCallback2 vt; + + Lzma2DecMt_FreeSt(p); + + p->outProcessed_Parse = 0; + + if (!p->mtc_WasConstructed) + { + p->mtc_WasConstructed = True; + MtDec_Construct(&p->mtc); + } + + p->mtc.progress = progress; + p->mtc.inStream = inStream; + + // p->outBuf = NULL; + // p->outBufSize = 0; + /* + if (!outStream) + { + // p->outBuf = outBuf; + // p->outBufSize = *outBufSize; + // *outBufSize = 0; + return SZ_ERROR_PARAM; + } + */ + + // p->mtc.inBlockMax = p->props.inBlockMax; + p->mtc.alloc = &p->alignOffsetAlloc.vt; + // p->alignOffsetAlloc.baseAlloc; + // p->mtc.inData = inData; + // p->mtc.inDataSize = inDataSize; + p->mtc.mtCallback = &vt; + p->mtc.mtCallbackObject = p; + + p->mtc.inBufSize = p->props.inBufSize_MT; + + p->mtc.numThreadsMax = p->props.numThreads; + + *isMT = True; + + vt.Parse = Lzma2DecMt_MtCallback_Parse; + vt.PreCode = Lzma2DecMt_MtCallback_PreCode; + vt.Code = Lzma2DecMt_MtCallback_Code; + vt.Write = Lzma2DecMt_MtCallback_Write; + + { + BoolInt needContinue = False; + + SRes res = MtDec_Code(&p->mtc); + + /* + if (!outStream) + *outBufSize = p->outBuf - outBuf; + */ + + *inProcessed = p->mtc.inProcessed; + + needContinue = False; + + if (res == SZ_OK) + { + if (p->mtc.mtProgress.res != SZ_OK) + res = p->mtc.mtProgress.res; + else + needContinue = p->mtc.needContinue; + } + + if (!needContinue) + { + if (res == SZ_OK) + return p->mtc.readRes; + return res; + } + + tMode = True; + p->readRes = p->mtc.readRes; + p->readWasFinished = p->mtc.readWasFinished; + p->inProcessed = p->mtc.inProcessed; + + PRF_STR("----- decoding ST -----") + } + } + + #endif + + + *isMT = False; + + { + SRes res = Lzma2Dec_Decode_ST(p + #ifndef Z7_ST + , tMode + #endif + ); + + *inProcessed = p->inProcessed; + + // res = SZ_OK; // for test + if (res == SZ_ERROR_INPUT_EOF) + { + if (p->readRes != SZ_OK) + res = p->readRes; + } + else if (res == SZ_OK && p->readRes != SZ_OK) + res = p->readRes; + + /* + #ifndef Z7_ST + if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK) + res = p->mtc.parseRes; + #endif + */ + + return res; + } +} + + +/* ---------- Read from CLzma2DecMtHandle Interface ---------- */ + +SRes Lzma2DecMt_Init(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqInStreamPtr inStream) +{ + // GET_CLzma2DecMt_p + + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + + p->prop = prop; + p->props = *props; + + p->inStream = inStream; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + p->finishMode = finishMode; + + p->outProcessed = 0; + p->inProcessed = 0; + + p->inPos = 0; + p->inLim = 0; + + return Lzma2Dec_Prepare_ST(p); +} + + +SRes Lzma2DecMt_Read(CLzma2DecMtHandle p, + Byte *data, size_t *outSize, + UInt64 *inStreamProcessed) +{ + // GET_CLzma2DecMt_p + ELzmaFinishMode finishMode; + SRes readRes; + size_t size = *outSize; + + *outSize = 0; + *inStreamProcessed = 0; + + finishMode = LZMA_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (size >= rem) + { + size = (size_t)rem; + if (p->finishMode) + finishMode = LZMA_FINISH_END; + } + } + + readRes = SZ_OK; + + for (;;) + { + SizeT inCur; + SizeT outCur; + ELzmaStatus status; + SRes res; + + if (p->inPos == p->inLim && readRes == SZ_OK) + { + p->inPos = 0; + p->inLim = p->props.inBufSize_ST; + readRes = ISeqInStream_Read(p->inStream, p->inBuf, &p->inLim); + } + + inCur = (SizeT)(p->inLim - p->inPos); + outCur = (SizeT)size; + + res = Lzma2Dec_DecodeToBuf(&p->dec, data, &outCur, + p->inBuf + p->inPos, &inCur, finishMode, &status); + + p->inPos += inCur; + p->inProcessed += inCur; + *inStreamProcessed += inCur; + p->outProcessed += outCur; + *outSize += outCur; + size -= outCur; + data += outCur; + + if (res != 0) + return res; + + /* + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return readRes; + + if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (p->finishMode && p->outSize_Defined && p->outProcessed >= p->outSize) + return SZ_ERROR_DATA; + return readRes; + } + */ + + if (inCur == 0 && outCur == 0) + return readRes; + } +} + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff -Nru p7zip-rar-16.02/C/Lzma2DecMt.h p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.h --- p7zip-rar-16.02/C/Lzma2DecMt.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2DecMt.h 2023-04-13 08:00:00.000000000 +0000 @@ -0,0 +1,81 @@ +/* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_DEC_MT_H +#define ZIP7_INC_LZMA2_DEC_MT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef struct +{ + size_t inBufSize_ST; + size_t outStep_ST; + + #ifndef Z7_ST + unsigned numThreads; + size_t inBufSize_MT; + size_t outBlockMax; + size_t inBlockMax; + #endif +} CLzma2DecMtProps; + +/* init to single-thread mode */ +void Lzma2DecMtProps_Init(CLzma2DecMtProps *p); + + +/* ---------- CLzma2DecMtHandle Interface ---------- */ + +/* Lzma2DecMt_ * functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + // SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef struct CLzma2DecMt CLzma2DecMt; +typedef CLzma2DecMt * CLzma2DecMtHandle; +// Z7_DECLARE_HANDLE(CLzma2DecMtHandle) + +CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); +void Lzma2DecMt_Destroy(CLzma2DecMtHandle p); + +SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + ISeqOutStreamPtr outStream, + const UInt64 *outDataSize, // NULL means undefined + int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + + // out variables: + UInt64 *inProcessed, + int *isMT, /* out: (*isMT == 0), if single thread decoding was used */ + + // UInt64 *outProcessed, + ICompressProgressPtr progress); + + +/* ---------- Read from CLzma2DecMtHandle Interface ---------- */ + +SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp, + Byte prop, + const CLzma2DecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqInStreamPtr inStream); + +SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, + Byte *data, size_t *outSize, + UInt64 *inStreamProcessed); + + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Lzma2Enc.c p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.c --- p7zip-rar-16.02/C/Lzma2Enc.c 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.c 2025-06-30 17:00:00.000000000 +0000 @@ -1,520 +1,807 @@ -/* Lzma2Enc.c -- LZMA2 Encoder -2015-10-04 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -/* #include */ -#include - -/* #define _7ZIP_ST */ - -#include "Lzma2Enc.h" - -#ifndef _7ZIP_ST -#include "MtCoder.h" -#else -#define NUM_MT_CODER_THREADS_MAX 1 -#endif - -#define LZMA2_CONTROL_LZMA (1 << 7) -#define LZMA2_CONTROL_COPY_NO_RESET 2 -#define LZMA2_CONTROL_COPY_RESET_DIC 1 -#define LZMA2_CONTROL_EOF 0 - -#define LZMA2_LCLP_MAX 4 - -#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) - -#define LZMA2_PACK_SIZE_MAX (1 << 16) -#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX -#define LZMA2_UNPACK_SIZE_MAX (1 << 21) -#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX - -#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16) - - -#define PRF(x) /* x */ - -/* ---------- CLzma2EncInt ---------- */ - -typedef struct -{ - CLzmaEncHandle enc; - UInt64 srcPos; - Byte props; - Bool needInitState; - Bool needInitProp; -} CLzma2EncInt; - -static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props) -{ - Byte propsEncoded[LZMA_PROPS_SIZE]; - SizeT propsSize = LZMA_PROPS_SIZE; - RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)); - RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)); - p->srcPos = 0; - p->props = propsEncoded[0]; - p->needInitState = True; - p->needInitProp = True; - return SZ_OK; -} - -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, - Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); -void LzmaEnc_Finish(CLzmaEncHandle pp); -void LzmaEnc_SaveState(CLzmaEncHandle pp); -void LzmaEnc_RestoreState(CLzmaEncHandle pp); - - -static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, - size_t *packSizeRes, ISeqOutStream *outStream) -{ - size_t packSizeLimit = *packSizeRes; - size_t packSize = packSizeLimit; - UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; - unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); - Bool useCopyBlock; - SRes res; - - *packSizeRes = 0; - if (packSize < lzHeaderSize) - return SZ_ERROR_OUTPUT_EOF; - packSize -= lzHeaderSize; - - LzmaEnc_SaveState(p->enc); - res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, - outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); - - PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); - - if (unpackSize == 0) - return res; - - if (res == SZ_OK) - useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16)); - else - { - if (res != SZ_ERROR_OUTPUT_EOF) - return res; - res = SZ_OK; - useCopyBlock = True; - } - - if (useCopyBlock) - { - size_t destPos = 0; - PRF(printf("################# COPY ")); - - while (unpackSize > 0) - { - UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; - if (packSizeLimit - destPos < u + 3) - return SZ_ERROR_OUTPUT_EOF; - outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); - outBuf[destPos++] = (Byte)((u - 1) >> 8); - outBuf[destPos++] = (Byte)(u - 1); - memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u); - unpackSize -= u; - destPos += u; - p->srcPos += u; - - if (outStream) - { - *packSizeRes += destPos; - if (outStream->Write(outStream, outBuf, destPos) != destPos) - return SZ_ERROR_WRITE; - destPos = 0; - } - else - *packSizeRes = destPos; - /* needInitState = True; */ - } - - LzmaEnc_RestoreState(p->enc); - return SZ_OK; - } - - { - size_t destPos = 0; - UInt32 u = unpackSize - 1; - UInt32 pm = (UInt32)(packSize - 1); - unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); - - PRF(printf(" ")); - - outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F)); - outBuf[destPos++] = (Byte)(u >> 8); - outBuf[destPos++] = (Byte)u; - outBuf[destPos++] = (Byte)(pm >> 8); - outBuf[destPos++] = (Byte)pm; - - if (p->needInitProp) - outBuf[destPos++] = p->props; - - p->needInitProp = False; - p->needInitState = False; - destPos += packSize; - p->srcPos += unpackSize; - - if (outStream) - if (outStream->Write(outStream, outBuf, destPos) != destPos) - return SZ_ERROR_WRITE; - - *packSizeRes = destPos; - return SZ_OK; - } -} - - -/* ---------- Lzma2 Props ---------- */ - -void Lzma2EncProps_Init(CLzma2EncProps *p) -{ - LzmaEncProps_Init(&p->lzmaProps); - p->numTotalThreads = -1; - p->numBlockThreads = -1; - p->blockSize = 0; -} - -void Lzma2EncProps_Normalize(CLzma2EncProps *p) -{ - int t1, t1n, t2, t3; - { - CLzmaEncProps lzmaProps = p->lzmaProps; - LzmaEncProps_Normalize(&lzmaProps); - t1n = lzmaProps.numThreads; - } - - t1 = p->lzmaProps.numThreads; - t2 = p->numBlockThreads; - t3 = p->numTotalThreads; - - if (t2 > NUM_MT_CODER_THREADS_MAX) - t2 = NUM_MT_CODER_THREADS_MAX; - - if (t3 <= 0) - { - if (t2 <= 0) - t2 = 1; - t3 = t1n * t2; - } - else if (t2 <= 0) - { - t2 = t3 / t1n; - if (t2 == 0) - { - t1 = 1; - t2 = t3; - } - if (t2 > NUM_MT_CODER_THREADS_MAX) - t2 = NUM_MT_CODER_THREADS_MAX; - } - else if (t1 <= 0) - { - t1 = t3 / t2; - if (t1 == 0) - t1 = 1; - } - else - t3 = t1n * t2; - - p->lzmaProps.numThreads = t1; - - LzmaEncProps_Normalize(&p->lzmaProps); - - t1 = p->lzmaProps.numThreads; - - if (p->blockSize == 0) - { - UInt32 dictSize = p->lzmaProps.dictSize; - UInt64 blockSize = (UInt64)dictSize << 2; - const UInt32 kMinSize = (UInt32)1 << 20; - const UInt32 kMaxSize = (UInt32)1 << 28; - if (blockSize < kMinSize) blockSize = kMinSize; - if (blockSize > kMaxSize) blockSize = kMaxSize; - if (blockSize < dictSize) blockSize = dictSize; - p->blockSize = (size_t)blockSize; - } - - if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1) - { - UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1; - if (temp > p->lzmaProps.reduceSize) - { - UInt64 numBlocks = temp / p->blockSize; - if (numBlocks < (unsigned)t2) - { - t2 = (unsigned)numBlocks; - if (t2 == 0) - t2 = 1; - t3 = t1 * t2; - } - } - } - - p->numBlockThreads = t2; - p->numTotalThreads = t3; -} - - -static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) -{ - return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; -} - - -/* ---------- Lzma2 ---------- */ - -typedef struct -{ - Byte propEncoded; - CLzma2EncProps props; - - Byte *outBuf; - - ISzAlloc *alloc; - ISzAlloc *allocBig; - - CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX]; - - #ifndef _7ZIP_ST - CMtCoder mtCoder; - #endif - -} CLzma2Enc; - - -/* ---------- Lzma2EncThread ---------- */ - -static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) -{ - UInt64 packTotal = 0; - SRes res = SZ_OK; - - if (!mainEncoder->outBuf) - { - mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); - if (!mainEncoder->outBuf) - return SZ_ERROR_MEM; - } - - RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); - RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE, - mainEncoder->alloc, mainEncoder->allocBig)); - - for (;;) - { - size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; - res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream); - if (res != SZ_OK) - break; - packTotal += packSize; - res = Progress(progress, p->srcPos, packTotal); - if (res != SZ_OK) - break; - if (packSize == 0) - break; - } - - LzmaEnc_Finish(p->enc); - - if (res == SZ_OK) - { - Byte b = 0; - if (outStream->Write(outStream, &b, 1) != 1) - return SZ_ERROR_WRITE; - } - - return res; -} - - -#ifndef _7ZIP_ST - -typedef struct -{ - IMtCoderCallback funcTable; - CLzma2Enc *lzma2Enc; -} CMtCallbackImp; - -static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize, - const Byte *src, size_t srcSize, int finished) -{ - CMtCallbackImp *imp = (CMtCallbackImp *)pp; - CLzma2Enc *mainEncoder = imp->lzma2Enc; - CLzma2EncInt *p = &mainEncoder->coders[index]; - - SRes res = SZ_OK; - { - size_t destLim = *destSize; - *destSize = 0; - - if (srcSize != 0) - { - RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); - - RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE, - mainEncoder->alloc, mainEncoder->allocBig)); - - while (p->srcPos < srcSize) - { - size_t packSize = destLim - *destSize; - res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL); - if (res != SZ_OK) - break; - *destSize += packSize; - - if (packSize == 0) - { - res = SZ_ERROR_FAIL; - break; - } - - if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK) - { - res = SZ_ERROR_PROGRESS; - break; - } - } - - LzmaEnc_Finish(p->enc); - if (res != SZ_OK) - return res; - } - - if (finished) - { - if (*destSize == destLim) - return SZ_ERROR_OUTPUT_EOF; - dest[(*destSize)++] = 0; - } - } - return res; -} - -#endif - - -/* ---------- Lzma2Enc ---------- */ - -CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc)); - if (!p) - return NULL; - Lzma2EncProps_Init(&p->props); - Lzma2EncProps_Normalize(&p->props); - p->outBuf = 0; - p->alloc = alloc; - p->allocBig = allocBig; - { - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - p->coders[i].enc = 0; - } - - #ifndef _7ZIP_ST - MtCoder_Construct(&p->mtCoder); - #endif - - return p; -} - -void Lzma2Enc_Destroy(CLzma2EncHandle pp) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - { - CLzma2EncInt *t = &p->coders[i]; - if (t->enc) - { - LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); - t->enc = 0; - } - } - - #ifndef _7ZIP_ST - MtCoder_Destruct(&p->mtCoder); - #endif - - IAlloc_Free(p->alloc, p->outBuf); - IAlloc_Free(p->alloc, pp); -} - -SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - CLzmaEncProps lzmaProps = props->lzmaProps; - LzmaEncProps_Normalize(&lzmaProps); - if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) - return SZ_ERROR_PARAM; - p->props = *props; - Lzma2EncProps_Normalize(&p->props); - return SZ_OK; -} - -Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - unsigned i; - UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); - for (i = 0; i < 40; i++) - if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i)) - break; - return (Byte)i; -} - -SRes Lzma2Enc_Encode(CLzma2EncHandle pp, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress) -{ - CLzma2Enc *p = (CLzma2Enc *)pp; - int i; - - for (i = 0; i < p->props.numBlockThreads; i++) - { - CLzma2EncInt *t = &p->coders[(unsigned)i]; - if (!t->enc) - { - t->enc = LzmaEnc_Create(p->alloc); - if (!t->enc) - return SZ_ERROR_MEM; - } - } - - #ifndef _7ZIP_ST - if (p->props.numBlockThreads > 1) - { - CMtCallbackImp mtCallback; - - mtCallback.funcTable.Code = MtCallbackImp_Code; - mtCallback.lzma2Enc = p; - - p->mtCoder.progress = progress; - p->mtCoder.inStream = inStream; - p->mtCoder.outStream = outStream; - p->mtCoder.alloc = p->alloc; - p->mtCoder.mtCallback = &mtCallback.funcTable; - - p->mtCoder.blockSize = p->props.blockSize; - p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; - if (p->mtCoder.destBlockSize < p->props.blockSize) - { - p->mtCoder.destBlockSize = (size_t)0 - 1; - if (p->mtCoder.destBlockSize < p->props.blockSize) - return SZ_ERROR_FAIL; - } - p->mtCoder.numThreads = p->props.numBlockThreads; - - return MtCoder_Code(&p->mtCoder); - } - #endif - - return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress); -} +/* Lzma2Enc.c -- LZMA2 Encoder +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define Z7_ST */ + +#include "Lzma2Enc.h" + +#ifndef Z7_ST +#include "MtCoder.h" +#else +#define MTCODER_THREADS_MAX 1 +#endif + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_LCLP_MAX 4 + +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#define LZMA2_PACK_SIZE_MAX (1 << 16) +#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX +#define LZMA2_UNPACK_SIZE_MAX (1 << 21) +#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX + +#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16) + + +#define PRF(x) /* x */ + + +/* ---------- CLimitedSeqInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + UInt64 limit; + UInt64 processed; + int finished; +} CLimitedSeqInStream; + +static void LimitedSeqInStream_Init(CLimitedSeqInStream *p) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->finished = 0; +} + +static SRes LimitedSeqInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLimitedSeqInStream) + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + const UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->finished = (size2 == 0 ? 1 : 0); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CLzma2EncInt ---------- */ + +typedef struct +{ + CLzmaEncHandle enc; + Byte propsAreSet; + Byte propsByte; + Byte needInitState; + Byte needInitProp; + UInt64 srcPos; +} CLzma2EncInt; + + +static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props) +{ + if (!p->propsAreSet) + { + SizeT propsSize = LZMA_PROPS_SIZE; + Byte propsEncoded[LZMA_PROPS_SIZE]; + RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)) + RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)) + p->propsByte = propsEncoded[0]; + p->propsAreSet = True; + } + return SZ_OK; +} + +static void Lzma2EncInt_InitBlock(CLzma2EncInt *p) +{ + p->srcPos = 0; + p->needInitState = True; + p->needInitProp = True; +} + + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); + +/* +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p); +*/ + +static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, + size_t *packSizeRes, ISeqOutStreamPtr outStream) +{ + size_t packSizeLimit = *packSizeRes; + size_t packSize = packSizeLimit; + UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; + unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); + BoolInt useCopyBlock; + SRes res; + + *packSizeRes = 0; + if (packSize < lzHeaderSize) + return SZ_ERROR_OUTPUT_EOF; + packSize -= lzHeaderSize; + + LzmaEnc_SaveState(p->enc); + res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, + outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); + + PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); + + if (unpackSize == 0) + return res; + + if (res == SZ_OK) + useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16)); + else + { + if (res != SZ_ERROR_OUTPUT_EOF) + return res; + res = SZ_OK; + useCopyBlock = True; + } + + if (useCopyBlock) + { + size_t destPos = 0; + PRF(printf("################# COPY ")); + + while (unpackSize > 0) + { + const UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; + if (packSizeLimit - destPos < u + 3) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); + outBuf[destPos++] = (Byte)((u - 1) >> 8); + outBuf[destPos++] = (Byte)(u - 1); + memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u); + unpackSize -= u; + destPos += u; + p->srcPos += u; + + if (outStream) + { + *packSizeRes += destPos; + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + destPos = 0; + } + else + *packSizeRes = destPos; + /* needInitState = True; */ + } + + LzmaEnc_RestoreState(p->enc); + return SZ_OK; + } + + { + size_t destPos = 0; + const UInt32 u = unpackSize - 1; + const UInt32 pm = (UInt32)(packSize - 1); + const unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); + + PRF(printf(" ")); + + outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F)); + outBuf[destPos++] = (Byte)(u >> 8); + outBuf[destPos++] = (Byte)u; + outBuf[destPos++] = (Byte)(pm >> 8); + outBuf[destPos++] = (Byte)pm; + + if (p->needInitProp) + outBuf[destPos++] = p->propsByte; + + p->needInitProp = False; + p->needInitState = False; + destPos += packSize; + p->srcPos += unpackSize; + + if (outStream) + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + + *packSizeRes = destPos; + return SZ_OK; + } +} + + +/* ---------- Lzma2 Props ---------- */ + +void Lzma2EncProps_Init(CLzma2EncProps *p) +{ + LzmaEncProps_Init(&p->lzmaProps); + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; + p->numThreadGroups = 0; +} + +void Lzma2EncProps_Normalize(CLzma2EncProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzmaEncProps lzmaProps = p->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + t1n = lzmaProps.numThreads; + } + + t1 = p->lzmaProps.numThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzmaProps.numThreads = t1; + + t2r = t2; + + fileSize = p->lzmaProps.reduceSize; + + if ( p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO + && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzmaProps.reduceSize = p->blockSize; + + LzmaEncProps_Normalize(&p->lzmaProps); + + p->lzmaProps.reduceSize = fileSize; + + t1 = p->lzmaProps.numThreads; + + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + { + t2r = t2 = 1; + t3 = t1; + } + else if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO && t2 <= 1) + { + /* if there is no block multi-threading, we use SOLID block */ + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + } + else + { + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + { + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt32 dictSize = p->lzmaProps.dictSize; + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + p->blockSize = blockSize; + } + + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (int)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static SRes Progress(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize) +{ + return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; +} + + +/* ---------- Lzma2 ---------- */ + +struct CLzma2Enc +{ + Byte propEncoded; + CLzma2EncProps props; + UInt64 expectedDataSize; + + Byte *tempBufLzma; + + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CLzma2EncInt coders[MTCODER_THREADS_MAX]; + + #ifndef Z7_ST + + ISeqOutStreamPtr outStream; + Byte *outBuf; + size_t outBuf_Rem; /* remainder in outBuf */ + + size_t outBufSize; /* size of allocated outBufs[i] */ + size_t outBufsDataSizes[MTCODER_BLOCKS_MAX]; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + Byte *outBufs[MTCODER_BLOCKS_MAX]; + + #endif +}; + + + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc)); + if (!p) + return NULL; + Lzma2EncProps_Init(&p->props); + Lzma2EncProps_Normalize(&p->props); + p->expectedDataSize = (UInt64)(Int64)-1; + p->tempBufLzma = NULL; + p->alloc = alloc; + p->allocBig = allocBig; + { + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + p->coders[i].enc = NULL; + } + + #ifndef Z7_ST + p->mtCoder_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif + + return (CLzma2EncHandle)p; +} + + +#ifndef Z7_ST + +static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p) +{ + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + +#endif + +// #define GET_CLzma2Enc_p CLzma2Enc *p = (CLzma2Enc *)(void *)p; + +void Lzma2Enc_Destroy(CLzma2EncHandle p) +{ + // GET_CLzma2Enc_p + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CLzma2EncInt *t = &p->coders[i]; + if (t->enc) + { + LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); + t->enc = NULL; + } + } + + + #ifndef Z7_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + Lzma2Enc_FreeOutBufs(p); + #endif + + ISzAlloc_Free(p->alloc, p->tempBufLzma); + p->tempBufLzma = NULL; + + ISzAlloc_Free(p->alloc, p); +} + + +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props) +{ + // GET_CLzma2Enc_p + CLzmaEncProps lzmaProps = props->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) + return SZ_ERROR_PARAM; + p->props = *props; + Lzma2EncProps_Normalize(&p->props); + return SZ_OK; +} + + +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize) +{ + // GET_CLzma2Enc_p + p->expectedDataSize = expectedDataSiize; +} + + +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p) +{ + // GET_CLzma2Enc_p + unsigned i; + UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); + for (i = 0; i < 40; i++) + if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i)) + break; + return (Byte)i; +} + + +static SRes Lzma2Enc_EncodeMt1( + CLzma2Enc *me, + CLzma2EncInt *p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + int finished, + ICompressProgressPtr progress) +{ + UInt64 unpackTotal = 0; + UInt64 packTotal = 0; + size_t outLim = 0; + CLimitedSeqInStream limitedInStream; + + if (outBuf) + { + outLim = *outBufSize; + *outBufSize = 0; + } + + if (!p->enc) + { + p->propsAreSet = False; + p->enc = LzmaEnc_Create(me->alloc); + if (!p->enc) + return SZ_ERROR_MEM; + } + + limitedInStream.realStream = inStream; + if (inStream) + { + limitedInStream.vt.Read = LimitedSeqInStream_Read; + } + + if (!outBuf) + { + // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma + if (!me->tempBufLzma) + { + me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); + if (!me->tempBufLzma) + return SZ_ERROR_MEM; + } + } + + RINOK(Lzma2EncInt_InitStream(p, &me->props)) + + for (;;) + { + SRes res = SZ_OK; + SizeT inSizeCur = 0; + + Lzma2EncInt_InitBlock(p); + + LimitedSeqInStream_Init(&limitedInStream); + limitedInStream.limit = me->props.blockSize; + + if (inStream) + { + UInt64 expected = (UInt64)(Int64)-1; + // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize + if (me->expectedDataSize != (UInt64)(Int64)-1 + && me->expectedDataSize >= unpackTotal) + expected = me->expectedDataSize - unpackTotal; + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && expected > me->props.blockSize) + expected = (size_t)me->props.blockSize; + + LzmaEnc_SetDataSize(p->enc, expected); + + RINOK(LzmaEnc_PrepareForLzma2(p->enc, + &limitedInStream.vt, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)) + } + else + { + inSizeCur = (SizeT)(inDataSize - (size_t)unpackTotal); + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && inSizeCur > me->props.blockSize) + inSizeCur = (SizeT)(size_t)me->props.blockSize; + + // LzmaEnc_SetDataSize(p->enc, inSizeCur); + + RINOK(LzmaEnc_MemPrepare(p->enc, + inData + (size_t)unpackTotal, inSizeCur, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)) + } + + for (;;) + { + size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; + if (outBuf) + packSize = outLim - (size_t)packTotal; + + res = Lzma2EncInt_EncodeSubblock(p, + outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize, + outBuf ? NULL : outStream); + + if (res != SZ_OK) + break; + + packTotal += packSize; + if (outBuf) + *outBufSize = (size_t)packTotal; + + res = Progress(progress, unpackTotal + p->srcPos, packTotal); + if (res != SZ_OK) + break; + + /* + if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0) + break; + */ + + if (packSize == 0) + break; + } + + LzmaEnc_Finish(p->enc); + + unpackTotal += p->srcPos; + + RINOK(res) + + if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur)) + return SZ_ERROR_FAIL; + + if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize)) + { + if (finished) + { + if (outBuf) + { + const size_t destPos = *outBufSize; + if (destPos >= outLim) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos] = LZMA2_CONTROL_EOF; // 0 + *outBufSize = destPos + 1; + } + else + { + const Byte b = LZMA2_CONTROL_EOF; // 0; + if (ISeqOutStream_Write(outStream, &b, 1) != 1) + return SZ_ERROR_WRITE; + } + } + return SZ_OK; + } + } +} + + + +#ifndef Z7_ST + +static SRes Lzma2Enc_MtCallback_Code(void *p, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CLzma2Enc *me = (CLzma2Enc *)p; + size_t destSize = me->outBufSize; + SRes res; + CMtProgressThunk progressThunk; + + Byte *dest = me->outBufs[outBufIndex]; + + me->outBufsDataSizes[outBufIndex] = 0; + + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + progressThunk.inSize = 0; + progressThunk.outSize = 0; + + res = Lzma2Enc_EncodeMt1(me, + &me->coders[coderIndex], + NULL, dest, &destSize, + NULL, src, srcSize, + finished, + &progressThunk.vt); + + me->outBufsDataSizes[outBufIndex] = destSize; + + return res; +} + + +static SRes Lzma2Enc_MtCallback_Write(void *p, unsigned outBufIndex) +{ + CLzma2Enc *me = (CLzma2Enc *)p; + size_t size = me->outBufsDataSizes[outBufIndex]; + const Byte *data = me->outBufs[outBufIndex]; + + if (me->outStream) + return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE; + + if (size > me->outBuf_Rem) + return SZ_ERROR_OUTPUT_EOF; + memcpy(me->outBuf, data, size); + me->outBuf_Rem -= size; + me->outBuf += size; + return SZ_OK; +} + +#endif + + + +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + ICompressProgressPtr progress) +{ + // GET_CLzma2Enc_p + + if (inStream && inData) + return SZ_ERROR_PARAM; + + if (outStream && outBuf) + return SZ_ERROR_PARAM; + + { + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + p->coders[i].propsAreSet = False; + } + + #ifndef Z7_ST + + if (p->props.numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = Lzma2Enc_MtCallback_Code; + vt.Write = Lzma2Enc_MtCallback_Write; + + p->outStream = outStream; + p->outBuf = NULL; + p->outBuf_Rem = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBuf_Rem = *outBufSize; + *outBufSize = 0; + } + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = inData; + p->mtCoder.inDataSize = inDataSize; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + p->mtCoder.blockSize = (size_t)p->props.blockSize; + if (p->mtCoder.blockSize != p->props.blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + const size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16; + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + Lzma2Enc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = (unsigned)p->props.numBlockThreads_Max; + p->mtCoder.numThreadGroups = p->props.numThreadGroups; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + { + const SRes res = MtCoder_Code(&p->mtCoder); + if (!outStream) + *outBufSize = (size_t)(p->outBuf - outBuf); + return res; + } + } + + #endif + + + return Lzma2Enc_EncodeMt1(p, + &p->coders[0], + outStream, outBuf, outBufSize, + inStream, inData, inDataSize, + True, /* finished */ + progress); +} + +#undef PRF diff -Nru p7zip-rar-16.02/C/Lzma2Enc.h p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.h --- p7zip-rar-16.02/C/Lzma2Enc.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma2Enc.h 2025-06-28 12:00:00.000000000 +0000 @@ -1,62 +1,58 @@ -/* Lzma2Enc.h -- LZMA2 Encoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA2_ENC_H -#define __LZMA2_ENC_H - -#include "LzmaEnc.h" - -EXTERN_C_BEGIN - -typedef struct -{ - CLzmaEncProps lzmaProps; - size_t blockSize; - int numBlockThreads; - int numTotalThreads; -} CLzma2EncProps; - -void Lzma2EncProps_Init(CLzma2EncProps *p); -void Lzma2EncProps_Normalize(CLzma2EncProps *p); - -/* ---------- CLzmaEnc2Handle Interface ---------- */ - -/* Lzma2Enc_* functions can return the following exit codes: -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error - SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -typedef void * CLzma2EncHandle; - -CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig); -void Lzma2Enc_Destroy(CLzma2EncHandle p); -SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); -Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); -SRes Lzma2Enc_Encode(CLzma2EncHandle p, - ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress); - -/* ---------- One Call Interface ---------- */ - -/* Lzma2Encode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -/* -SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -*/ - -EXTERN_C_END - -#endif +/* Lzma2Enc.h -- LZMA2 Encoder +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_ENC_H +#define ZIP7_INC_LZMA2_ENC_H + +#include "LzmaEnc.h" + +EXTERN_C_BEGIN + +#define LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO 0 +#define LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID ((UInt64)(Int64)-1) + +typedef struct +{ + CLzmaEncProps lzmaProps; + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; + unsigned numThreadGroups; // 0 : no groups +} CLzma2EncProps; + +void Lzma2EncProps_Init(CLzma2EncProps *p); +void Lzma2EncProps_Normalize(CLzma2EncProps *p); + +/* ---------- CLzmaEnc2Handle Interface ---------- */ + +/* Lzma2Enc_* functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef struct CLzma2Enc CLzma2Enc; +typedef CLzma2Enc * CLzma2EncHandle; +// Z7_DECLARE_HANDLE(CLzma2EncHandle) + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void Lzma2Enc_Destroy(CLzma2EncHandle p); +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize); +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + ICompressProgressPtr progress); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Lzma86.h p7zip-rar-16.02+really25.00+ds/C/Lzma86.h --- p7zip-rar-16.02/C/Lzma86.h 2014-12-28 12:49:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma86.h 2023-03-03 13:00:00.000000000 +0000 @@ -1,111 +1,111 @@ -/* Lzma86.h -- LZMA + x86 (BCJ) Filter -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA86_H -#define __LZMA86_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define LZMA86_SIZE_OFFSET (1 + 5) -#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) - -/* -It's an example for LZMA + x86 Filter use. -You can use .lzma86 extension, if you write that stream to file. -.lzma86 header adds one additional byte to standard .lzma header. -.lzma86 header (14 bytes): - Offset Size Description - 0 1 = 0 - no filter, pure LZMA - = 1 - x86 filter + LZMA - 1 1 lc, lp and pb in encoded form - 2 4 dictSize (little endian) - 6 8 uncompressed size (little endian) - - -Lzma86_Encode -------------- -level - compression level: 0 <= level <= 9, the default value for "level" is 5. - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes, for level = 5. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - For better compression ratio dictSize must be >= inSize. - -filterMode: - SZ_FILTER_NO - no Filter - SZ_FILTER_YES - x86 Filter - SZ_FILTER_AUTO - it tries both alternatives to select best. - Encoder will use 2 or 3 passes: - 2 passes when FILTER_NO provides better compression. - 3 passes when FILTER_YES provides better compression. - -Lzma86Encode allocates Data with MyAlloc functions. -RAM Requirements for compressing: - RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize - filterMode FilterBlockSize - SZ_FILTER_NO 0 - SZ_FILTER_YES inSize - SZ_FILTER_AUTO inSize - - -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -enum ESzFilterMode -{ - SZ_FILTER_NO, - SZ_FILTER_YES, - SZ_FILTER_AUTO -}; - -SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode); - - -/* -Lzma86_GetUnpackSize: - In: - src - input data - srcLen - input data size - Out: - unpackSize - size of uncompressed stream - Return code: - SZ_OK - OK - SZ_ERROR_INPUT_EOF - Error in headers -*/ - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); - -/* -Lzma86_Decode: - In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size - Out: - destLen - processed output size - srcLen - processed input size - Return code: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - unsupported file - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer -*/ - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); - -EXTERN_C_END - -#endif +/* Lzma86.h -- LZMA + x86 (BCJ) Filter +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA86_H +#define ZIP7_INC_LZMA86_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define LZMA86_SIZE_OFFSET (1 + 5) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +/* +It's an example for LZMA + x86 Filter use. +You can use .lzma86 extension, if you write that stream to file. +.lzma86 header adds one additional byte to standard .lzma header. +.lzma86 header (14 bytes): + Offset Size Description + 0 1 = 0 - no filter, pure LZMA + = 1 - x86 filter + LZMA + 1 1 lc, lp and pb in encoded form + 2 4 dictSize (little endian) + 6 8 uncompressed size (little endian) + + +Lzma86_Encode +------------- +level - compression level: 0 <= level <= 9, the default value for "level" is 5. + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes, for level = 5. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + For better compression ratio dictSize must be >= inSize. + +filterMode: + SZ_FILTER_NO - no Filter + SZ_FILTER_YES - x86 Filter + SZ_FILTER_AUTO - it tries both alternatives to select best. + Encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. + +Lzma86Encode allocates Data with MyAlloc functions. +RAM Requirements for compressing: + RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize + filterMode FilterBlockSize + SZ_FILTER_NO 0 + SZ_FILTER_YES inSize + SZ_FILTER_AUTO inSize + + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode); + + +/* +Lzma86_GetUnpackSize: + In: + src - input data + srcLen - input data size + Out: + unpackSize - size of uncompressed stream + Return code: + SZ_OK - OK + SZ_ERROR_INPUT_EOF - Error in headers +*/ + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); + +/* +Lzma86_Decode: + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + Out: + destLen - processed output size + srcLen - processed input size + Return code: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - unsupported file + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer +*/ + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Lzma86Dec.c p7zip-rar-16.02+really25.00+ds/C/Lzma86Dec.c --- p7zip-rar-16.02/C/Lzma86Dec.c 2016-05-20 08:20:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma86Dec.c 2023-03-03 13:00:00.000000000 +0000 @@ -1,54 +1,53 @@ -/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2016-05-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaDec.h" - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) -{ - unsigned i; - if (srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - *unpackSize = 0; - for (i = 0; i < sizeof(UInt64); i++) - *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); - return SZ_OK; -} - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) -{ - SRes res; - int useFilter; - SizeT inSizePure; - ELzmaStatus status; - - if (*srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - - useFilter = src[0]; - - if (useFilter > 1) - { - *destLen = 0; - return SZ_ERROR_UNSUPPORTED; - } - - inSizePure = *srcLen - LZMA86_HEADER_SIZE; - res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, - src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); - *srcLen = inSizePure + LZMA86_HEADER_SIZE; - if (res != SZ_OK) - return res; - if (useFilter == 1) - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(dest, *destLen, 0, &x86State, 0); - } - return SZ_OK; -} +/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder +2023-03-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaDec.h" + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) +{ + unsigned i; + if (srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + *unpackSize = 0; + for (i = 0; i < sizeof(UInt64); i++) + *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); + return SZ_OK; +} + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SRes res; + int useFilter; + SizeT inSizePure; + ELzmaStatus status; + + if (*srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + + useFilter = src[0]; + + if (useFilter > 1) + { + *destLen = 0; + return SZ_ERROR_UNSUPPORTED; + } + + inSizePure = *srcLen - LZMA86_HEADER_SIZE; + res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, + src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); + *srcLen = inSizePure + LZMA86_HEADER_SIZE; + if (res != SZ_OK) + return res; + if (useFilter == 1) + { + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(dest, *destLen, 0, &x86State); + } + return SZ_OK; +} diff -Nru p7zip-rar-16.02/C/Lzma86Enc.c p7zip-rar-16.02+really25.00+ds/C/Lzma86Enc.c --- p7zip-rar-16.02/C/Lzma86Enc.c 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Lzma86Enc.c 2023-03-03 13:00:00.000000000 +0000 @@ -1,106 +1,103 @@ -/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2016-05-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaEnc.h" - -#define SZE_OUT_OVERFLOW SZE_DATA_ERROR - -int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode) -{ - size_t outSize2 = *destLen; - Byte *filteredStream; - Bool useFilter; - int mainResult = SZ_ERROR_OUTPUT_EOF; - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - - *destLen = 0; - if (outSize2 < LZMA86_HEADER_SIZE) - return SZ_ERROR_OUTPUT_EOF; - - { - int i; - UInt64 t = srcLen; - for (i = 0; i < 8; i++, t >>= 8) - dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; - } - - filteredStream = 0; - useFilter = (filterMode != SZ_FILTER_NO); - if (useFilter) - { - if (srcLen != 0) - { - filteredStream = (Byte *)MyAlloc(srcLen); - if (filteredStream == 0) - return SZ_ERROR_MEM; - memcpy(filteredStream, src, srcLen); - } - { - UInt32 x86State; - x86_Convert_Init(x86State); - x86_Convert(filteredStream, srcLen, 0, &x86State, 1); - } - } - - { - size_t minSize = 0; - Bool bestIsFiltered = False; - - /* passes for SZ_FILTER_AUTO: - 0 - BCJ + LZMA - 1 - LZMA - 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. - */ - int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; - - int i; - for (i = 0; i < numPasses; i++) - { - size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; - size_t outPropsSize = 5; - SRes curRes; - Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); - if (curModeIsFiltered && !bestIsFiltered) - break; - if (useFilter && i == 0) - curModeIsFiltered = True; - - curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, - curModeIsFiltered ? filteredStream : src, srcLen, - &props, dest + 1, &outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); - - if (curRes != SZ_ERROR_OUTPUT_EOF) - { - if (curRes != SZ_OK) - { - mainResult = curRes; - break; - } - if (outSizeProcessed <= minSize || mainResult != SZ_OK) - { - minSize = outSizeProcessed; - bestIsFiltered = curModeIsFiltered; - mainResult = SZ_OK; - } - } - } - dest[0] = (Byte)(bestIsFiltered ? 1 : 0); - *destLen = LZMA86_HEADER_SIZE + minSize; - } - if (useFilter) - MyFree(filteredStream); - return mainResult; -} +/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder +2023-03-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaEnc.h" + +int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode) +{ + size_t outSize2 = *destLen; + Byte *filteredStream; + BoolInt useFilter; + int mainResult = SZ_ERROR_OUTPUT_EOF; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + + *destLen = 0; + if (outSize2 < LZMA86_HEADER_SIZE) + return SZ_ERROR_OUTPUT_EOF; + + { + int i; + UInt64 t = srcLen; + for (i = 0; i < 8; i++, t >>= 8) + dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; + } + + filteredStream = 0; + useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (srcLen != 0) + { + filteredStream = (Byte *)MyAlloc(srcLen); + if (filteredStream == 0) + return SZ_ERROR_MEM; + memcpy(filteredStream, src, srcLen); + } + { + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State); + } + } + + { + size_t minSize = 0; + BoolInt bestIsFiltered = False; + + /* passes for SZ_FILTER_AUTO: + 0 - BCJ + LZMA + 1 - LZMA + 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. + */ + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + + int i; + for (i = 0; i < numPasses; i++) + { + size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; + size_t outPropsSize = 5; + SRes curRes; + BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); + if (curModeIsFiltered && !bestIsFiltered) + break; + if (useFilter && i == 0) + curModeIsFiltered = True; + + curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, + curModeIsFiltered ? filteredStream : src, srcLen, + &props, dest + 1, &outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); + + if (curRes != SZ_ERROR_OUTPUT_EOF) + { + if (curRes != SZ_OK) + { + mainResult = curRes; + break; + } + if (outSizeProcessed <= minSize || mainResult != SZ_OK) + { + minSize = outSizeProcessed; + bestIsFiltered = curModeIsFiltered; + mainResult = SZ_OK; + } + } + } + dest[0] = (Byte)(bestIsFiltered ? 1 : 0); + *destLen = LZMA86_HEADER_SIZE + minSize; + } + if (useFilter) + MyFree(filteredStream); + return mainResult; +} diff -Nru p7zip-rar-16.02/C/LzmaDec.c p7zip-rar-16.02+really25.00+ds/C/LzmaDec.c --- p7zip-rar-16.02/C/LzmaDec.c 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaDec.c 2023-04-07 18:00:00.000000000 +0000 @@ -1,1100 +1,1363 @@ -/* LzmaDec.c -- LZMA Decoder -2016-05-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "LzmaDec.h" - -#include - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_INIT_SIZE 5 - -#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) - -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -#define TREE_DECODE(probs, limit, i) \ - { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } - -/* #define _LZMA_SIZE_OPT */ - -#ifdef _LZMA_SIZE_OPT -#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -#else -#define TREE_6_DECODE(probs, i) \ - { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - i -= 0x40; } -#endif - -#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) -#define MATCHED_LITER_DEC \ - matchByte <<= 1; \ - bit = (matchByte & offs); \ - probLit = prob + offs + bit + symbol; \ - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) - -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } - -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -#define UPDATE_0_CHECK range = bound; -#define UPDATE_1_CHECK range -= bound; code -= bound; -#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -#define TREE_DECODE_CHECK(probs, limit, i) \ - { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 0x300 - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) - -#define LZMA_DIC_MIN (1 << 12) - -/* First LZMA-symbol is always decoded. -And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -Out: - Result: - SZ_OK - OK - SZ_ERROR_DATA - Error - p->remainLen: - < kMatchSpecLenStart : normal remain - = kMatchSpecLenStart : finished - = kMatchSpecLenStart + 1 : Flush marker (unused now) - = kMatchSpecLenStart + 2 : State Init Marker (unused now) -*/ - -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - CLzmaProb *probs = p->probs; - - unsigned state = p->state; - UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; - unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; - unsigned lc = p->prop.lc; - - Byte *dic = p->dic; - SizeT dicBufSize = p->dicBufSize; - SizeT dicPos = p->dicPos; - - UInt32 processedPos = p->processedPos; - UInt32 checkDicSize = p->checkDicSize; - unsigned len = 0; - - const Byte *buf = p->buf; - UInt32 range = p->range; - UInt32 code = p->code; - - do - { - CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = processedPos & pbMask; - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - unsigned symbol; - UPDATE_0(prob); - prob = probs + Literal; - if (processedPos != 0 || checkDicSize != 0) - prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); - processedPos++; - - if (state < kNumLitStates) - { - state -= (state < 4) ? state : 3; - symbol = 1; - #ifdef _LZMA_SIZE_OPT - do { NORMAL_LITER_DEC } while (symbol < 0x100); - #else - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - NORMAL_LITER_DEC - #endif - } - else - { - unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; - unsigned offs = 0x100; - state -= (state < 10) ? 3 : 6; - symbol = 1; - #ifdef _LZMA_SIZE_OPT - do - { - unsigned bit; - CLzmaProb *probLit; - MATCHED_LITER_DEC - } - while (symbol < 0x100); - #else - { - unsigned bit; - CLzmaProb *probLit; - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - MATCHED_LITER_DEC - } - #endif - } - - dic[dicPos++] = (Byte)symbol; - continue; - } - - { - UPDATE_1(prob); - prob = probs + IsRep + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - state += kNumStates; - prob = probs + LenCoder; - } - else - { - UPDATE_1(prob); - if (checkDicSize == 0 && processedPos == 0) - return SZ_ERROR_DATA; - prob = probs + IsRepG0 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0(prob) - { - UPDATE_0(prob); - dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; - dicPos++; - processedPos++; - state = state < kNumLitStates ? 9 : 11; - continue; - } - UPDATE_1(prob); - } - else - { - UInt32 distance; - UPDATE_1(prob); - prob = probs + IsRepG1 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep1; - } - else - { - UPDATE_1(prob); - prob = probs + IsRepG2 + state; - IF_BIT_0(prob) - { - UPDATE_0(prob); - distance = rep2; - } - else - { - UPDATE_1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = probs + RepLenCoder; - } - - #ifdef _LZMA_SIZE_OPT - { - unsigned lim, offset; - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - lim = (1 << kLenNumLowBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenChoice2; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - lim = (1 << kLenNumMidBits); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - lim = (1 << kLenNumHighBits); - } - } - TREE_DECODE(probLen, lim, len); - len += offset; - } - #else - { - CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - len -= 8; - } - else - { - UPDATE_1(probLen); - probLen = prob + LenChoice2; - IF_BIT_0(probLen) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - } - else - { - UPDATE_1(probLen); - probLen = prob + LenHigh; - TREE_DECODE(probLen, (1 << kLenNumHighBits), len); - len += kLenNumLowSymbols + kLenNumMidSymbols; - } - } - } - #endif - - if (state >= kNumStates) - { - UInt32 distance; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); - if (distance >= kStartPosModelIndex) - { - unsigned posSlot = (unsigned)distance; - unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); - distance = (2 | (distance & 1)); - if (posSlot < kEndPosModelIndex) - { - distance <<= numDirectBits; - prob = probs + SpecPos + distance - posSlot - 1; - { - UInt32 mask = 1; - unsigned i = 1; - do - { - GET_BIT2(prob + i, i, ; , distance |= mask); - mask <<= 1; - } - while (--numDirectBits != 0); - } - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE - range >>= 1; - - { - UInt32 t; - code -= range; - t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ - distance = (distance << 1) + (t + 1); - code += range & t; - } - /* - distance <<= 1; - if (code >= range) - { - code -= range; - distance |= 1; - } - */ - } - while (--numDirectBits != 0); - prob = probs + Align; - distance <<= kNumAlignBits; - { - unsigned i = 1; - GET_BIT2(prob + i, i, ; , distance |= 1); - GET_BIT2(prob + i, i, ; , distance |= 2); - GET_BIT2(prob + i, i, ; , distance |= 4); - GET_BIT2(prob + i, i, ; , distance |= 8); - } - if (distance == (UInt32)0xFFFFFFFF) - { - len += kMatchSpecLenStart; - state -= kNumStates; - break; - } - } - } - - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (checkDicSize == 0) - { - if (distance >= processedPos) - { - p->dicPos = dicPos; - return SZ_ERROR_DATA; - } - } - else if (distance >= checkDicSize) - { - p->dicPos = dicPos; - return SZ_ERROR_DATA; - } - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - } - - len += kMatchMinLen; - - { - SizeT rem; - unsigned curLen; - SizeT pos; - - if ((rem = limit - dicPos) == 0) - { - p->dicPos = dicPos; - return SZ_ERROR_DATA; - } - - curLen = ((rem < len) ? (unsigned)rem : len); - pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); - - processedPos += curLen; - - len -= curLen; - if (curLen <= dicBufSize - pos) - { - Byte *dest = dic + dicPos; - ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; - const Byte *lim = dest + curLen; - dicPos += curLen; - do - *(dest) = (Byte)*(dest + src); - while (++dest != lim); - } - else - { - do - { - dic[dicPos++] = dic[pos]; - if (++pos == dicBufSize) - pos = 0; - } - while (--curLen != 0); - } - } - } - } - while (dicPos < limit && buf < bufLimit); - - NORMALIZE; - - p->buf = buf; - p->range = range; - p->code = code; - p->remainLen = len; - p->dicPos = dicPos; - p->processedPos = processedPos; - p->reps[0] = rep0; - p->reps[1] = rep1; - p->reps[2] = rep2; - p->reps[3] = rep3; - p->state = state; - - return SZ_OK; -} - -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -{ - if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) - { - Byte *dic = p->dic; - SizeT dicPos = p->dicPos; - SizeT dicBufSize = p->dicBufSize; - unsigned len = p->remainLen; - SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ - SizeT rem = limit - dicPos; - if (rem < len) - len = (unsigned)(rem); - - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) - p->checkDicSize = p->prop.dicSize; - - p->processedPos += len; - p->remainLen -= len; - while (len != 0) - { - len--; - dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; - dicPos++; - } - p->dicPos = dicPos; - } -} - -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -{ - do - { - SizeT limit2 = limit; - if (p->checkDicSize == 0) - { - UInt32 rem = p->prop.dicSize - p->processedPos; - if (limit - p->dicPos > rem) - limit2 = p->dicPos + rem; - } - - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); - - if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) - p->checkDicSize = p->prop.dicSize; - - LzmaDec_WriteRem(p, limit); - } - while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); - - if (p->remainLen > kMatchSpecLenStart) - p->remainLen = kMatchSpecLenStart; - - return 0; -} - -typedef enum -{ - DUMMY_ERROR, /* unexpected end of input stream */ - DUMMY_LIT, - DUMMY_MATCH, - DUMMY_REP -} ELzmaDummy; - -static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -{ - UInt32 range = p->range; - UInt32 code = p->code; - const Byte *bufLimit = buf + inSize; - const CLzmaProb *probs = p->probs; - unsigned state = p->state; - ELzmaDummy res; - - { - const CLzmaProb *prob; - UInt32 bound; - unsigned ttt; - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK - - /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ - - prob = probs + Literal; - if (p->checkDicSize != 0 || p->processedPos != 0) - prob += ((UInt32)LZMA_LIT_SIZE * - ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + - (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); - - if (state < kNumLitStates) - { - unsigned symbol = 1; - do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchByte = p->dic[p->dicPos - p->reps[0] + - (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; - unsigned offs = 0x100; - unsigned symbol = 1; - do - { - unsigned bit; - const CLzmaProb *probLit; - matchByte <<= 1; - bit = (matchByte & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - res = DUMMY_LIT; - } - else - { - unsigned len; - UPDATE_1_CHECK; - - prob = probs + IsRep + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - state = 0; - prob = probs + LenCoder; - res = DUMMY_MATCH; - } - else - { - UPDATE_1_CHECK; - res = DUMMY_REP; - prob = probs + IsRepG0 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - NORMALIZE_CHECK; - return DUMMY_REP; - } - else - { - UPDATE_1_CHECK; - } - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG1 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG2 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - } - } - } - state = kNumStates; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - const CLzmaProb *probLen = prob + LenChoice; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = 1 << kLenNumLowBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenChoice2; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = 1 << kLenNumMidBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = 1 << kLenNumHighBits; - } - } - TREE_DECODE_CHECK(probLen, limit, len); - len += offset; - } - - if (state < 4) - { - unsigned posSlot; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - unsigned numDirectBits = ((posSlot >> 1) - 1); - - /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ - - if (posSlot < kEndPosModelIndex) - { - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE_CHECK - range >>= 1; - code -= range & (((code - range) >> 31) - 1); - /* if (code >= range) code -= range; */ - } - while (--numDirectBits != 0); - prob = probs + Align; - numDirectBits = kNumAlignBits; - } - { - unsigned i = 1; - do - { - GET_BIT_CHECK(prob + i, i); - } - while (--numDirectBits != 0); - } - } - } - } - } - NORMALIZE_CHECK; - return res; -} - - -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -{ - p->needFlush = 1; - p->remainLen = 0; - p->tempBufSize = 0; - - if (initDic) - { - p->processedPos = 0; - p->checkDicSize = 0; - p->needInitState = 1; - } - if (initState) - p->needInitState = 1; -} - -void LzmaDec_Init(CLzmaDec *p) -{ - p->dicPos = 0; - LzmaDec_InitDicAndState(p, True, True); -} - -static void LzmaDec_InitStateReal(CLzmaDec *p) -{ - SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); - SizeT i; - CLzmaProb *probs = p->probs; - for (i = 0; i < numProbs; i++) - probs[i] = kBitModelTotal >> 1; - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; - p->state = 0; - p->needInitState = 0; -} - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT inSize = *srcLen; - (*srcLen) = 0; - LzmaDec_WriteRem(p, dicLimit); - - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->remainLen != kMatchSpecLenStart) - { - int checkEndMarkNow; - - if (p->needFlush) - { - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) - p->tempBuf[p->tempBufSize++] = *src++; - if (p->tempBufSize < RC_INIT_SIZE) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (p->tempBuf[0] != 0) - return SZ_ERROR_DATA; - p->code = - ((UInt32)p->tempBuf[1] << 24) - | ((UInt32)p->tempBuf[2] << 16) - | ((UInt32)p->tempBuf[3] << 8) - | ((UInt32)p->tempBuf[4]); - p->range = 0xFFFFFFFF; - p->needFlush = 0; - p->tempBufSize = 0; - } - - checkEndMarkNow = 0; - if (p->dicPos >= dicLimit) - { - if (p->remainLen == 0 && p->code == 0) - { - *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; - return SZ_OK; - } - if (finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->remainLen != 0) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - checkEndMarkNow = 1; - } - - if (p->needInitState) - LzmaDec_InitStateReal(p); - - if (p->tempBufSize == 0) - { - SizeT processed; - const Byte *bufLimit; - if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, src, inSize); - if (dummyRes == DUMMY_ERROR) - { - memcpy(p->tempBuf, src, inSize); - p->tempBufSize = (unsigned)inSize; - (*srcLen) += inSize; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - bufLimit = src; - } - else - bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; - p->buf = src; - if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) - return SZ_ERROR_DATA; - processed = (SizeT)(p->buf - src); - (*srcLen) += processed; - src += processed; - inSize -= processed; - } - else - { - unsigned rem = p->tempBufSize, lookAhead = 0; - while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) - p->tempBuf[rem++] = src[lookAhead++]; - p->tempBufSize = rem; - if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); - if (dummyRes == DUMMY_ERROR) - { - (*srcLen) += lookAhead; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - } - p->buf = p->tempBuf; - if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) - return SZ_ERROR_DATA; - - { - unsigned kkk = (unsigned)(p->buf - p->tempBuf); - if (rem < kkk) - return SZ_ERROR_FAIL; /* some internal error */ - rem -= kkk; - if (lookAhead < rem) - return SZ_ERROR_FAIL; /* some internal error */ - lookAhead -= rem; - } - (*srcLen) += lookAhead; - src += lookAhead; - inSize -= lookAhead; - p->tempBufSize = 0; - } - } - if (p->code == 0) - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -} - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - SizeT outSize = *destLen; - SizeT inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - SizeT inSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->dicPos == p->dicBufSize) - p->dicPos = 0; - dicPos = p->dicPos; - if (outSize > p->dicBufSize - dicPos) - { - outSizeCur = p->dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); - src += inSizeCur; - inSize -= inSizeCur; - *srcLen += inSizeCur; - outSizeCur = p->dicPos - dicPos; - memcpy(dest, p->dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->probs); - p->probs = NULL; -} - -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->dic); - p->dic = NULL; -} - -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -{ - LzmaDec_FreeProbs(p, alloc); - LzmaDec_FreeDict(p, alloc); -} - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -{ - UInt32 dicSize; - Byte d; - - if (size < LZMA_PROPS_SIZE) - return SZ_ERROR_UNSUPPORTED; - else - dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); - - if (dicSize < LZMA_DIC_MIN) - dicSize = LZMA_DIC_MIN; - p->dicSize = dicSize; - - d = data[0]; - if (d >= (9 * 5 * 5)) - return SZ_ERROR_UNSUPPORTED; - - p->lc = d % 9; - d /= 9; - p->pb = d / 5; - p->lp = d % 5; - - return SZ_OK; -} - -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -{ - UInt32 numProbs = LzmaProps_GetNumProbs(propNew); - if (!p->probs || numProbs != p->numProbs) - { - LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); - p->numProbs = numProbs; - if (!p->probs) - return SZ_ERROR_MEM; - } - return SZ_OK; -} - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - - { - UInt32 dictSize = propNew.dicSize; - SizeT mask = ((UInt32)1 << 12) - 1; - if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; - else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; - dicBufSize = ((SizeT)dictSize + mask) & ~mask; - if (dicBufSize < dictSize) - dicBufSize = dictSize; - } - - if (!p->dic || dicBufSize != p->dicBufSize) - { - LzmaDec_FreeDict(p, alloc); - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); - if (!p->dic) - { - LzmaDec_FreeProbs(p, alloc); - return SZ_ERROR_MEM; - } - } - p->dicBufSize = dicBufSize; - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzmaDec p; - SRes res; - SizeT outSize = *destLen, inSize = *srcLen; - *destLen = *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - if (inSize < RC_INIT_SIZE) - return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); - p.dic = dest; - p.dicBufSize = outSize; - LzmaDec_Init(&p); - *srcLen = inSize; - res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - *destLen = p.dicPos; - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - LzmaDec_FreeProbs(&p, alloc); - return res; -} +/* LzmaDec.c -- LZMA Decoder +2023-04-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #include "CpuArch.h" */ +#include "LzmaDec.h" + +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) + +#define RC_INIT_SIZE 5 + +#ifndef Z7_LZMA_DEC_OPT + +#define kNumMoveBits 5 +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p) i = (i + i); A0; } else \ + { UPDATE_1(p) i = (i + i) + 1; A1; } + +#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } + +#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ + { UPDATE_0(p + i) A0; } else \ + { UPDATE_1(p + i) A1; } +#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) +#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) +#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) + +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define Z7_LZMA_SIZE_OPT */ + +#ifdef Z7_LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + i -= 0x40; } +#endif + +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol) +#define MATCHED_LITER_DEC \ + matchByte += matchByte; \ + bit = offs; \ + offs &= matchByte; \ + probLit = prob + (offs + bit + symbol); \ + GET_BIT2(probLit, symbol, offs ^= bit; , ;) + +#endif // Z7_LZMA_DEC_OPT + + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK i = (i + i); A0; } else \ + { UPDATE_1_CHECK i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ + { UPDATE_0_CHECK i += m; m += m; } else \ + { UPDATE_1_CHECK m += m; i += m; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenLow 0 +#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +#define LenChoice LenLow +#define LenChoice2 (LenLow + (1 << kLenNumLowBits)) + +#define kNumStates 12 +#define kNumStates2 16 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +#define kMatchSpecLen_Error_Data (1 << 9) +#define kMatchSpecLen_Error_Fail (kMatchSpecLen_Error_Data - 1) + +/* External ASM code needs same CLzmaProb array layout. So don't change it. */ + +/* (probs_1664) is faster and better for code size at some platforms */ +/* +#ifdef MY_CPU_X86_OR_AMD64 +*/ +#define kStartOffset 1664 +#define GET_PROBS p->probs_1664 +/* +#define GET_PROBS p->probs + kStartOffset +#else +#define kStartOffset 0 +#define GET_PROBS p->probs +#endif +*/ + +#define SpecPos (-kStartOffset) +#define IsRep0Long (SpecPos + kNumFullDistances) +#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax)) +#define LenCoder (RepLenCoder + kNumLenProbs) +#define IsMatch (LenCoder + kNumLenProbs) +#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax)) +#define IsRep (Align + kAlignTableSize) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define PosSlot (IsRepG2 + kNumStates) +#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define NUM_BASE_PROBS (Literal + kStartOffset) + +#if Align != 0 && kStartOffset != 0 + #error Stop_Compiling_Bad_LZMA_kAlign +#endif + +#if NUM_BASE_PROBS != 1984 + #error Stop_Compiling_Bad_LZMA_PROBS +#endif + + +#define LZMA_LIT_SIZE 0x300 + +#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + + +#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4) +#define COMBINED_PS_STATE (posState + state) +#define GET_LEN_STATE (posState) + +#define LZMA_DIC_MIN (1 << 12) + +/* +p->remainLen : shows status of LZMA decoder: + < kMatchSpecLenStart : the number of bytes to be copied with (p->rep0) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + = kMatchSpecLenStart + 1 : need init range coder + = kMatchSpecLenStart + 2 : need init range coder and state + = kMatchSpecLen_Error_Fail : Internal Code Failure + = kMatchSpecLen_Error_Data + [0 ... 273] : LZMA Data Error +*/ + +/* ---------- LZMA_DECODE_REAL ---------- */ +/* +LzmaDec_DecodeReal_3() can be implemented in external ASM file. +3 - is the code compatibility version of that function for check at link time. +*/ + +#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3 + +/* +LZMA_DECODE_REAL() +In: + RangeCoder is normalized + if (p->dicPos == limit) + { + LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases. + So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol + is not END_OF_PAYALOAD_MARKER, then the function doesn't write any byte to dictionary, + the function returns SZ_OK, and the caller can use (p->remainLen) and (p->reps[0]) later. + } + +Processing: + The first LZMA symbol will be decoded in any case. + All main checks for limits are at the end of main loop, + It decodes additional LZMA-symbols while (p->buf < bufLimit && dicPos < limit), + RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked. + But if (p->buf < bufLimit), the caller provided at least (LZMA_REQUIRED_INPUT_MAX + 1) bytes for + next iteration before limit (bufLimit + LZMA_REQUIRED_INPUT_MAX), + that is enough for worst case LZMA symbol with one additional RangeCoder normalization for one bit. + So that function never reads bufLimit [LZMA_REQUIRED_INPUT_MAX] byte. + +Out: + RangeCoder is normalized + Result: + SZ_OK - OK + p->remainLen: + < kMatchSpecLenStart : the number of bytes to be copied with (p->reps[0]) offset + = kMatchSpecLenStart : the LZMA stream was finished with end mark + + SZ_ERROR_DATA - error, when the MATCH-Symbol refers out of dictionary + p->remainLen : undefined + p->reps[*] : undefined +*/ + + +#ifdef Z7_LZMA_DEC_OPT + +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); + +#else + +static +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lc = p->prop.lc; + unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc); + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(processedPos, pbMask); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob) + prob = probs + Literal; + if (processedPos != 0 || checkDicSize != 0) + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); + processedPos++; + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + #ifdef Z7_LZMA_SIZE_OPT + do { NORMAL_LITER_DEC } while (symbol < 0x100); + #else + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + NORMAL_LITER_DEC + #endif + } + else + { + unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + #ifdef Z7_LZMA_SIZE_OPT + do + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + } + while (symbol < 0x100); + #else + { + unsigned bit; + CLzmaProb *probLit; + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + MATCHED_LITER_DEC + } + #endif + } + + dic[dicPos++] = (Byte)symbol; + continue; + } + + { + UPDATE_1(prob) + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob) + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0(prob) + { + UPDATE_0(prob) + + // that case was checked before with kBadRepCode + // if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; } + // The caller doesn't allow (dicPos == limit) case here + // so we don't need the following check: + // if (dicPos == limit) { state = state < kNumLitStates ? 9 : 11; len = 1; break; } + + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob) + } + else + { + UInt32 distance; + UPDATE_1(prob) + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + distance = rep1; + } + else + { + UPDATE_1(prob) + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob) + distance = rep2; + } + else + { + UPDATE_1(prob) + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + + #ifdef Z7_LZMA_SIZE_OPT + { + unsigned lim, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen) + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + lim = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen) + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + lim = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, lim, len) + len += offset; + } + #else + { + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE; + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + len -= 8; + } + else + { + UPDATE_1(probLen) + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen) + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + len = 1; + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + } + else + { + UPDATE_1(probLen) + probLen = prob + LenHigh; + TREE_DECODE(probLen, (1 << kLenNumHighBits), len) + len += kLenNumLowSymbols * 2; + } + } + } + #endif + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance) + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos; + { + UInt32 m = 1; + distance++; + do + { + REV_BIT_VAR(prob, distance, m) + } + while (--numDirectBits); + distance -= m; + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + REV_BIT_CONST(prob, i, 1) + REV_BIT_CONST(prob, i, 2) + REV_BIT_CONST(prob, i, 4) + REV_BIT_LAST (prob, i, 8) + distance |= i; + } + if (distance == (UInt32)0xFFFFFFFF) + { + len = kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize)) + { + len += kMatchSpecLen_Error_Data + kMatchMinLen; + // len = kMatchSpecLen_Error_Data; + // len += kMatchMinLen; + break; + } + } + + len += kMatchMinLen; + + { + SizeT rem; + unsigned curLen; + SizeT pos; + + if ((rem = limit - dicPos) == 0) + { + /* + We stop decoding and return SZ_OK, and we can resume decoding later. + Any error conditions can be tested later in caller code. + For more strict mode we can stop decoding with error + // len += kMatchSpecLen_Error_Data; + */ + break; + } + + curLen = ((rem < len) ? (unsigned)rem : len); + pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); + + processedPos += (UInt32)curLen; + + len -= curLen; + if (curLen <= dicBufSize - pos) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += (SizeT)curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + + NORMALIZE + + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = (UInt32)len; // & (kMatchSpecLen_Error_Data - 1); // we can write real length for error matches too. + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = (UInt32)state; + if (len >= kMatchSpecLen_Error_Data) + return SZ_ERROR_DATA; + return SZ_OK; +} +#endif + + + +static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + unsigned len = (unsigned)p->remainLen; + if (len == 0 /* || len >= kMatchSpecLenStart */) + return; + { + SizeT dicPos = p->dicPos; + Byte *dic; + SizeT dicBufSize; + SizeT rep0; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ + { + SizeT rem = limit - dicPos; + if (rem < len) + { + len = (unsigned)(rem); + if (len == 0) + return; + } + } + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += (UInt32)len; + p->remainLen -= (UInt32)len; + dic = p->dic; + rep0 = p->reps[0]; + dicBufSize = p->dicBufSize; + do + { + dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; + dicPos++; + } + while (--len); + p->dicPos = dicPos; + } +} + + +/* +At staring of new stream we have one of the following symbols: + - Literal - is allowed + - Non-Rep-Match - is allowed only if it's end marker symbol + - Rep-Match - is not allowed +We use early check of (RangeCoder:Code) over kBadRepCode to simplify main decoding code +*/ + +#define kRange0 0xFFFFFFFF +#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)) +#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))) +#if kBadRepCode != (0xC0000000 - 0x400) + #error Stop_Compiling_Bad_LZMA_Check +#endif + + +/* +LzmaDec_DecodeReal2(): + It calls LZMA_DECODE_REAL() and it adjusts limit according (p->checkDicSize). + +We correct (p->checkDicSize) after LZMA_DECODE_REAL() and in LzmaDec_WriteRem(), +and we support the following state of (p->checkDicSize): + if (total_processed < p->prop.dicSize) then + { + (total_processed == p->processedPos) + (p->checkDicSize == 0) + } + else + (p->checkDicSize == p->prop.dicSize) +*/ + +static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit = p->dicPos + rem; + } + { + int res = LZMA_DECODE_REAL(p, limit, bufLimit); + if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + return res; + } +} + + + +typedef enum +{ + DUMMY_INPUT_EOF, /* need more input data */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + + +#define IS_DUMMY_END_MARKER_POSSIBLE(dummyRes) ((dummyRes) == DUMMY_MATCH) + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byte **bufOut) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = *bufOut; + const CLzmaProb *probs = GET_PROBS; + unsigned state = (unsigned)p->state; + ELzmaDummy res; + + for (;;) + { + const CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = CALC_POS_STATE(p->processedPos, ((unsigned)1 << p->prop.pb) - 1); + + prob = probs + IsMatch + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += ((UInt32)LZMA_LIT_SIZE * + ((((p->processedPos) & (((unsigned)1 << (p->prop.lp)) - 1)) << p->prop.lc) + + ((unsigned)p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + const CLzmaProb *probLit; + matchByte += matchByte; + bit = offs; + offs &= matchByte; + probLit = prob + (offs + bit + symbol); + GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; ) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + prob = probs + IsRep0Long + COMBINED_PS_STATE; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + break; + } + else + { + UPDATE_1_CHECK + } + } + else + { + UPDATE_1_CHECK + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } + else + { + UPDATE_1_CHECK + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + } + else + { + UPDATE_1_CHECK + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + const CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE; + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK + probLen = prob + LenHigh; + offset = kLenNumLowSymbols * 2; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len) + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot) + if (posSlot >= kStartPosModelIndex) + { + unsigned numDirectBits = ((posSlot >> 1) - 1); + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits); + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + unsigned m = 1; + do + { + REV_BIT_CHECK(prob, i, m) + } + while (--numDirectBits); + } + } + } + } + break; + } + NORMALIZE_CHECK + + *bufOut = buf; + return res; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); +void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState) +{ + p->remainLen = kMatchSpecLenStart + 1; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->remainLen = kMatchSpecLenStart + 2; + } + if (initState) + p->remainLen = kMatchSpecLenStart + 2; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + + +/* +LZMA supports optional end_marker. +So the decoder can lookahead for one additional LZMA-Symbol to check end_marker. +That additional LZMA-Symbol can require up to LZMA_REQUIRED_INPUT_MAX bytes in input stream. +When the decoder reaches dicLimit, it looks (finishMode) parameter: + if (finishMode == LZMA_FINISH_ANY), the decoder doesn't lookahead + if (finishMode != LZMA_FINISH_ANY), the decoder lookahead, if end_marker is possible for current position + +When the decoder lookahead, and the lookahead symbol is not end_marker, we have two ways: + 1) Strict mode (default) : the decoder returns SZ_ERROR_DATA. + 2) The relaxed mode (alternative mode) : we could return SZ_OK, and the caller + must check (status) value. The caller can show the error, + if the end of stream is expected, and the (status) is noit + LZMA_STATUS_FINISHED_WITH_MARK or LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK. +*/ + + +#define RETURN_NOT_FINISHED_FOR_FINISH \ + *status = LZMA_STATUS_NOT_FINISHED; \ + return SZ_ERROR_DATA; // for strict mode + // return SZ_OK; // for relaxed mode + + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + if (p->remainLen > kMatchSpecLenStart) + { + if (p->remainLen > kMatchSpecLenStart + 2) + return p->remainLen == kMatchSpecLen_Error_Fail ? SZ_ERROR_FAIL : SZ_ERROR_DATA; + + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize != 0 && p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + p->code = + ((UInt32)p->tempBuf[1] << 24) + | ((UInt32)p->tempBuf[2] << 16) + | ((UInt32)p->tempBuf[3] << 8) + | ((UInt32)p->tempBuf[4]); + + if (p->checkDicSize == 0 + && p->processedPos == 0 + && p->code >= kBadRepCode) + return SZ_ERROR_DATA; + + p->range = 0xFFFFFFFF; + p->tempBufSize = 0; + + if (p->remainLen > kMatchSpecLenStart + 1) + { + SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); + SizeT i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + } + + p->remainLen = 0; + } + + for (;;) + { + if (p->remainLen == kMatchSpecLenStart) + { + if (p->code != 0) + return SZ_ERROR_DATA; + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + + LzmaDec_WriteRem(p, dicLimit); + + { + // (p->remainLen == 0 || p->dicPos == dicLimit) + + int checkEndMarkNow = 0; + + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + RETURN_NOT_FINISHED_FOR_FINISH + } + checkEndMarkNow = 1; + } + + // (p->remainLen == 0) + + if (p->tempBufSize == 0) + { + const Byte *bufLimit; + int dummyProcessed = -1; + + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + const Byte *bufOut = src + inSize; + + ELzmaDummy dummyRes = LzmaDec_TryDummy(p, src, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) + { + size_t i; + if (inSize >= LZMA_REQUIRED_INPUT_MAX) + break; + (*srcLen) += inSize; + p->tempBufSize = (unsigned)inSize; + for (i = 0; i < inSize; i++) + p->tempBuf[i] = src[i]; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - src); + if ((unsigned)dummyProcessed > LZMA_REQUIRED_INPUT_MAX) + break; + + if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) + { + unsigned i; + (*srcLen) += (unsigned)dummyProcessed; + p->tempBufSize = (unsigned)dummyProcessed; + for (i = 0; i < (unsigned)dummyProcessed; i++) + p->tempBuf[i] = src[i]; + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + + bufLimit = src; + // we will decode only one iteration + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + + p->buf = src; + + { + int res = LzmaDec_DecodeReal2(p, dicLimit, bufLimit); + + SizeT processed = (SizeT)(p->buf - src); + + if (dummyProcessed < 0) + { + if (processed > inSize) + break; + } + else if ((unsigned)dummyProcessed != processed) + break; + + src += processed; + inSize -= processed; + (*srcLen) += processed; + + if (res != SZ_OK) + { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } + } + continue; + } + + { + // we have some data in (p->tempBuf) + // in strict mode: tempBufSize is not enough for one Symbol decoding. + // in relaxed mode: tempBufSize not larger than required for one Symbol decoding. + + unsigned rem = p->tempBufSize; + unsigned ahead = 0; + int dummyProcessed = -1; + + while (rem < LZMA_REQUIRED_INPUT_MAX && ahead < inSize) + p->tempBuf[rem++] = src[ahead++]; + + // ahead - the size of new data copied from (src) to (p->tempBuf) + // rem - the size of temp buffer including new data from (src) + + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + const Byte *bufOut = p->tempBuf + rem; + + ELzmaDummy dummyRes = LzmaDec_TryDummy(p, p->tempBuf, &bufOut); + + if (dummyRes == DUMMY_INPUT_EOF) + { + if (rem >= LZMA_REQUIRED_INPUT_MAX) + break; + p->tempBufSize = rem; + (*srcLen) += (SizeT)ahead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + dummyProcessed = (int)(bufOut - p->tempBuf); + + if ((unsigned)dummyProcessed < p->tempBufSize) + break; + + if (checkEndMarkNow && !IS_DUMMY_END_MARKER_POSSIBLE(dummyRes)) + { + (*srcLen) += (unsigned)dummyProcessed - p->tempBufSize; + p->tempBufSize = (unsigned)dummyProcessed; + // p->remainLen = kMatchSpecLen_Error_Data; + RETURN_NOT_FINISHED_FOR_FINISH + } + } + + p->buf = p->tempBuf; + + { + // we decode one symbol from (p->tempBuf) here, so the (bufLimit) is equal to (p->buf) + int res = LzmaDec_DecodeReal2(p, dicLimit, p->buf); + + SizeT processed = (SizeT)(p->buf - p->tempBuf); + rem = p->tempBufSize; + + if (dummyProcessed < 0) + { + if (processed > LZMA_REQUIRED_INPUT_MAX) + break; + if (processed < rem) + break; + } + else if ((unsigned)dummyProcessed != processed) + break; + + processed -= rem; + + src += processed; + inSize -= processed; + (*srcLen) += processed; + p->tempBufSize = 0; + + if (res != SZ_OK) + { + p->remainLen = kMatchSpecLen_Error_Data; + return SZ_ERROR_DATA; + } + } + } + } + } + + /* Some unexpected error: internal error of code, memory corruption or hardware failure */ + p->remainLen = kMatchSpecLen_Error_Fail; + return SZ_ERROR_FAIL; +} + + + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->probs); + p->probs = NULL; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->dic); + p->dic = NULL; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = (Byte)(d % 9); + d /= 9; + p->pb = (Byte)(d / 5); + p->lp = (Byte)(d % 5); + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (!p->probs || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb)); + if (!p->probs) + return SZ_ERROR_MEM; + p->probs_1664 = p->probs + 1664; + p->numProbs = numProbs; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) + + { + UInt32 dictSize = propNew.dicSize; + SizeT mask = ((UInt32)1 << 12) - 1; + if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1; + dicBufSize = ((SizeT)dictSize + mask) & ~mask; + if (dicBufSize < dictSize) + dicBufSize = dictSize; + } + + if (!p->dic || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize); + if (!p->dic) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAllocPtr alloc) +{ + CLzmaDec p; + SRes res; + SizeT outSize = *destLen, inSize = *srcLen; + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + LzmaDec_CONSTRUCT(&p) + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)) + p.dic = dest; + p.dicBufSize = outSize; + LzmaDec_Init(&p); + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + *destLen = p.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff -Nru p7zip-rar-16.02/C/LzmaDec.h p7zip-rar-16.02+really25.00+ds/C/LzmaDec.h --- p7zip-rar-16.02/C/LzmaDec.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaDec.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,227 +1,237 @@ -/* LzmaDec.h -- LZMA Decoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, - but memory usage for CLzmaDec::probs will be doubled in that case */ - -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 -#else -#define CLzmaProb UInt16 -#endif - - -/* ---------- LZMA Properties ---------- */ - -#define LZMA_PROPS_SIZE 5 - -typedef struct _CLzmaProps -{ - unsigned lc, lp, pb; - UInt32 dicSize; -} CLzmaProps; - -/* LzmaProps_Decode - decodes properties -Returns: - SZ_OK - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); - - -/* ---------- LZMA Decoder state ---------- */ - -/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. - Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ - -#define LZMA_REQUIRED_INPUT_MAX 20 - -typedef struct -{ - CLzmaProps prop; - CLzmaProb *probs; - Byte *dic; - const Byte *buf; - UInt32 range, code; - SizeT dicPos; - SizeT dicBufSize; - UInt32 processedPos; - UInt32 checkDicSize; - unsigned state; - UInt32 reps[4]; - unsigned remainLen; - int needFlush; - int needInitState; - UInt32 numProbs; - unsigned tempBufSize; - Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -} CLzmaDec; - -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - -void LzmaDec_Init(CLzmaDec *p); - -/* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - -typedef enum -{ - LZMA_FINISH_ANY, /* finish at any point */ - LZMA_FINISH_END /* block must be finished at the end */ -} ELzmaFinishMode; - -/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! - - You must use LZMA_FINISH_END, when you know that current output buffer - covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. - - If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, - and output value of destLen will be less than output buffer size limit. - You can check status result also. - - You can use multiple checks to test data integrity after full decompression: - 1) Check Result and "status" variable. - 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. - 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. - You must use correct finish mode in that case. */ - -typedef enum -{ - LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ - LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ - LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -} ELzmaStatus; - -/* ELzmaStatus is used only as output value for function call */ - - -/* ---------- Interfaces ---------- */ - -/* There are 3 levels of interfaces: - 1) Dictionary Interface - 2) Buffer Interface - 3) One Call Interface - You can select any of these interfaces, but don't mix functions from different - groups for same object. */ - - -/* There are two variants to allocate state for Dictionary Interface: - 1) LzmaDec_Allocate / LzmaDec_Free - 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs - You can use variant 2, if you set dictionary buffer manually. - For Buffer Interface you must always use variant 1. - -LzmaDec_Allocate* can return: - SZ_OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); - -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); - -/* ---------- Dictionary Interface ---------- */ - -/* You can use it, if you want to eliminate the overhead for data copying from - dictionary to some other external buffer. - You must work with CLzmaDec variables directly in this interface. - - STEPS: - LzmaDec_Constr() - LzmaDec_Allocate() - for (each new stream) - { - LzmaDec_Init() - while (it needs more decompression) - { - LzmaDec_DecodeToDic() - use data from CLzmaDec::dic and update CLzmaDec::dicPos - } - } - LzmaDec_Free() -*/ - -/* LzmaDec_DecodeToDic - - The decoding to internal dictionary buffer (CLzmaDec::dic). - You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! - -finishMode: - It has meaning only if the decoding reaches output limit (dicLimit). - LZMA_FINISH_ANY - Decode just dicLimit bytes. - LZMA_FINISH_END - Stream must be finished after dicLimit. - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error -*/ - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- Buffer Interface ---------- */ - -/* It's zlib-like interface. - See LzmaDec_DecodeToDic description for information about STEPS and return results, - but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need - to work with CLzmaDec variables manually. - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). -*/ - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* LzmaDecode - -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); - -EXTERN_C_END - -#endif +/* LzmaDec.h -- LZMA Decoder +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA_DEC_H +#define ZIP7_INC_LZMA_DEC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* #define Z7_LZMA_PROB32 */ +/* Z7_LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +typedef +#ifdef Z7_LZMA_PROB32 + UInt32 +#else + UInt16 +#endif + CLzmaProb; + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct +{ + Byte lc; + Byte lp; + Byte pb; + Byte _pad_; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + /* Don't change this structure. ASM code can use it. */ + CLzmaProps prop; + CLzmaProb *probs; + CLzmaProb *probs_1664; + Byte *dic; + SizeT dicBufSize; + SizeT dicPos; + const Byte *buf; + UInt32 range; + UInt32 code; + UInt32 processedPos; + UInt32 checkDicSize; + UInt32 reps[4]; + UInt32 state; + UInt32 remainLen; + + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p) + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + - Stream with end mark. That end mark adds about 6 bytes to compressed size. + - Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Construct() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAllocPtr alloc); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/LzmaEnc.c p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.c --- p7zip-rar-16.02/C/LzmaEnc.c 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.c 2025-05-11 14:00:00.000000000 +0000 @@ -1,2351 +1,3150 @@ -/* LzmaEnc.c -- LZMA Encoder -2016-05-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -/* #define SHOW_STAT */ -/* #define SHOW_STAT2 */ - -#if defined(SHOW_STAT) || defined(SHOW_STAT2) -#include -#endif - -#include "LzmaEnc.h" - -#include "LzFind.h" -#ifndef _7ZIP_ST -#include "LzFindMt.h" -#endif - -#ifdef SHOW_STAT -static unsigned g_STAT_OFFSET = 0; -#endif - -#define kMaxHistorySize ((UInt32)3 << 29) -/* #define kMaxHistorySize ((UInt32)7 << 29) */ - -#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) - -#define kBlockSize (9 << 10) -#define kUnpackBlockSize (1 << 18) -#define kMatchArraySize (1 << 21) -#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) - -#define kNumMaxDirectBits (31) - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 -#define kProbInitValue (kBitModelTotal >> 1) - -#define kNumMoveReducingBits 4 -#define kNumBitPriceShiftBits 4 -#define kBitPrice (1 << kNumBitPriceShiftBits) - -void LzmaEncProps_Init(CLzmaEncProps *p) -{ - p->level = 5; - p->dictSize = p->mc = 0; - p->reduceSize = (UInt64)(Int64)-1; - p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; - p->writeEndMark = 0; -} - -void LzmaEncProps_Normalize(CLzmaEncProps *p) -{ - int level = p->level; - if (level < 0) level = 5; - p->level = level; - - if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); - if (p->dictSize > p->reduceSize) - { - unsigned i; - for (i = 11; i <= 30; i++) - { - if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } - if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } - } - } - - if (p->lc < 0) p->lc = 3; - if (p->lp < 0) p->lp = 0; - if (p->pb < 0) p->pb = 2; - - if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); - if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); - if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); - if (p->numHashBytes < 0) p->numHashBytes = 4; - if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); - - if (p->numThreads < 0) - p->numThreads = - #ifndef _7ZIP_ST - ((p->btMode && p->algo) ? 2 : 1); - #else - 1; - #endif -} - -UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -{ - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); - return props.dictSize; -} - -#if (_MSC_VER >= 1400) -/* BSR code is fast for some new CPUs */ -/* #define LZMA_LOG_BSR */ -#endif - -#ifdef LZMA_LOG_BSR - -#define kDicLogSizeMaxCompress 32 - -#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); } - -static UInt32 GetPosSlot1(UInt32 pos) -{ - UInt32 res; - BSR2_RET(pos, res); - return res; -} -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } - -#else - -#define kNumLogBits (9 + sizeof(size_t) / 2) -/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */ - -#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) - -static void LzmaEnc_FastPosInit(Byte *g_FastPos) -{ - unsigned slot; - g_FastPos[0] = 0; - g_FastPos[1] = 1; - g_FastPos += 2; - - for (slot = 2; slot < kNumLogBits * 2; slot++) - { - size_t k = ((size_t)1 << ((slot >> 1) - 1)); - size_t j; - for (j = 0; j < k; j++) - g_FastPos[j] = (Byte)slot; - g_FastPos += k; - } -} - -/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ -/* -#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ - (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ - res = p->g_FastPos[pos >> zz] + (zz * 2); } -*/ - -/* -#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ - (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ - res = p->g_FastPos[pos >> zz] + (zz * 2); } -*/ - -#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ - res = p->g_FastPos[pos >> zz] + (zz * 2); } - -/* -#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ - p->g_FastPos[pos >> 6] + 12 : \ - p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -*/ - -#define GetPosSlot1(pos) p->g_FastPos[pos] -#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } - -#endif - - -#define LZMA_NUM_REPS 4 - -typedef unsigned CState; - -typedef struct -{ - UInt32 price; - - CState state; - int prev1IsChar; - int prev2; - - UInt32 posPrev2; - UInt32 backPrev2; - - UInt32 posPrev; - UInt32 backPrev; - UInt32 backs[LZMA_NUM_REPS]; -} COptimal; - -#define kNumOpts (1 << 12) - -#define kNumLenToPosStates 4 -#define kNumPosSlotBits 6 -#define kDicLogSizeMin 0 -#define kDicLogSizeMax 32 -#define kDistTableSizeMax (kDicLogSizeMax * 2) - - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) -#define kAlignMask (kAlignTableSize - 1) - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) - -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#ifdef _LZMA_PROB32 -#define CLzmaProb UInt32 -#else -#define CLzmaProb UInt16 -#endif - -#define LZMA_PB_MAX 4 -#define LZMA_LC_MAX 8 -#define LZMA_LP_MAX 4 - -#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) - - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define LZMA_MATCH_LEN_MIN 2 -#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) - -#define kNumStates 12 - - -typedef struct -{ - CLzmaProb choice; - CLzmaProb choice2; - CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; - CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; - CLzmaProb high[kLenNumHighSymbols]; -} CLenEnc; - - -typedef struct -{ - CLenEnc p; - UInt32 tableSize; - UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; - UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -} CLenPriceEnc; - - -typedef struct -{ - UInt32 range; - Byte cache; - UInt64 low; - UInt64 cacheSize; - Byte *buf; - Byte *bufLim; - Byte *bufBase; - ISeqOutStream *outStream; - UInt64 processed; - SRes res; -} CRangeEnc; - - -typedef struct -{ - CLzmaProb *litProbs; - - UInt32 state; - UInt32 reps[LZMA_NUM_REPS]; - - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; -} CSaveState; - - -typedef struct -{ - void *matchFinderObj; - IMatchFinder matchFinder; - - UInt32 optimumEndIndex; - UInt32 optimumCurrentIndex; - - UInt32 longestMatchLength; - UInt32 numPairs; - UInt32 numAvail; - - UInt32 numFastBytes; - UInt32 additionalOffset; - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; - - unsigned lc, lp, pb; - unsigned lpMask, pbMask; - unsigned lclp; - - CLzmaProb *litProbs; - - Bool fastMode; - Bool writeEndMark; - Bool finished; - Bool multiThread; - Bool needInit; - - UInt64 nowPos64; - - UInt32 matchPriceCount; - UInt32 alignPriceCount; - - UInt32 distTableSize; - - UInt32 dictSize; - SRes result; - - CRangeEnc rc; - - #ifndef _7ZIP_ST - Bool mtMode; - CMatchFinderMt matchFinderMt; - #endif - - CMatchFinder matchFinderBase; - - #ifndef _7ZIP_ST - Byte pad[128]; - #endif - - COptimal opt[kNumOpts]; - - #ifndef LZMA_LOG_BSR - Byte g_FastPos[1 << kNumLogBits]; - #endif - - UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; - UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; - - UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; - UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; - UInt32 alignPrices[kAlignTableSize]; - - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; - CLzmaProb isRep[kNumStates]; - CLzmaProb isRepG0[kNumStates]; - CLzmaProb isRepG1[kNumStates]; - CLzmaProb isRepG2[kNumStates]; - CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; - - CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; - CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - - CLenPriceEnc lenEnc; - CLenPriceEnc repLenEnc; - - CSaveState saveState; - - #ifndef _7ZIP_ST - Byte pad2[128]; - #endif -} CLzmaEnc; - - -void LzmaEnc_SaveState(CLzmaEncHandle pp) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - CSaveState *dest = &p->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb)); -} - -void LzmaEnc_RestoreState(CLzmaEncHandle pp) -{ - CLzmaEnc *dest = (CLzmaEnc *)pp; - const CSaveState *p = &dest->saveState; - int i; - dest->lenEnc = p->lenEnc; - dest->repLenEnc = p->repLenEnc; - dest->state = p->state; - - for (i = 0; i < kNumStates; i++) - { - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); - } - for (i = 0; i < kNumLenToPosStates; i++) - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); - memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); - memcpy(dest->reps, p->reps, sizeof(p->reps)); - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb)); -} - -SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - CLzmaEncProps props = *props2; - LzmaEncProps_Normalize(&props); - - if (props.lc > LZMA_LC_MAX - || props.lp > LZMA_LP_MAX - || props.pb > LZMA_PB_MAX - || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress) - || props.dictSize > kMaxHistorySize) - return SZ_ERROR_PARAM; - - p->dictSize = props.dictSize; - { - unsigned fb = props.fb; - if (fb < 5) - fb = 5; - if (fb > LZMA_MATCH_LEN_MAX) - fb = LZMA_MATCH_LEN_MAX; - p->numFastBytes = fb; - } - p->lc = props.lc; - p->lp = props.lp; - p->pb = props.pb; - p->fastMode = (props.algo == 0); - p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0); - { - UInt32 numHashBytes = 4; - if (props.btMode) - { - if (props.numHashBytes < 2) - numHashBytes = 2; - else if (props.numHashBytes < 4) - numHashBytes = props.numHashBytes; - } - p->matchFinderBase.numHashBytes = numHashBytes; - } - - p->matchFinderBase.cutValue = props.mc; - - p->writeEndMark = props.writeEndMark; - - #ifndef _7ZIP_ST - /* - if (newMultiThread != _multiThread) - { - ReleaseMatchFinder(); - _multiThread = newMultiThread; - } - */ - p->multiThread = (props.numThreads > 1); - #endif - - return SZ_OK; -} - -static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; - -#define IsCharState(s) ((s) < 7) - -#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) - -#define kInfinityPrice (1 << 30) - -static void RangeEnc_Construct(CRangeEnc *p) -{ - p->outStream = NULL; - p->bufBase = NULL; -} - -#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) - -#define RC_BUF_SIZE (1 << 16) -static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -{ - if (!p->bufBase) - { - p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); - if (!p->bufBase) - return 0; - p->bufLim = p->bufBase + RC_BUF_SIZE; - } - return 1; -} - -static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->bufBase); - p->bufBase = 0; -} - -static void RangeEnc_Init(CRangeEnc *p) -{ - /* Stream.Init(); */ - p->low = 0; - p->range = 0xFFFFFFFF; - p->cacheSize = 1; - p->cache = 0; - - p->buf = p->bufBase; - - p->processed = 0; - p->res = SZ_OK; -} - -static void RangeEnc_FlushStream(CRangeEnc *p) -{ - size_t num; - if (p->res != SZ_OK) - return; - num = p->buf - p->bufBase; - if (num != p->outStream->Write(p->outStream, p->bufBase, num)) - p->res = SZ_ERROR_WRITE; - p->processed += num; - p->buf = p->bufBase; -} - -static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -{ - if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0) - { - Byte temp = p->cache; - do - { - Byte *buf = p->buf; - *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); - p->buf = buf; - if (buf == p->bufLim) - RangeEnc_FlushStream(p); - temp = 0xFF; - } - while (--p->cacheSize != 0); - p->cache = (Byte)((UInt32)p->low >> 24); - } - p->cacheSize++; - p->low = (UInt32)p->low << 8; -} - -static void RangeEnc_FlushData(CRangeEnc *p) -{ - int i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); -} - -static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits) -{ - do - { - p->range >>= 1; - p->low += p->range & (0 - ((value >> --numBits) & 1)); - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); - } - } - while (numBits != 0); -} - -static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -{ - UInt32 ttt = *prob; - UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; - if (symbol == 0) - { - p->range = newBound; - ttt += (kBitModelTotal - ttt) >> kNumMoveBits; - } - else - { - p->low += newBound; - p->range -= newBound; - ttt -= ttt >> kNumMoveBits; - } - *prob = (CLzmaProb)ttt; - if (p->range < kTopValue) - { - p->range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -{ - symbol |= 0x100; - do - { - RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); - symbol <<= 1; - } - while (symbol < 0x10000); -} - -static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -{ - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } - while (symbol < 0x10000); -} - -static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -{ - UInt32 i; - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) - { - const int kCyclesBits = kNumBitPriceShiftBits; - UInt32 w = i; - UInt32 bitCount = 0; - int j; - for (j = 0; j < kCyclesBits; j++) - { - w = w * w; - bitCount <<= 1; - while (w >= ((UInt32)1 << 16)) - { - w >>= 1; - bitCount++; - } - } - ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); - } -} - - -#define GET_PRICE(prob, symbol) \ - p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; - -#define GET_PRICEa(prob, symbol) \ - ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; - -#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] - -#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] - -static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices) -{ - UInt32 price = 0; - symbol |= 0x100; - do - { - price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); - symbol <<= 1; - } - while (symbol < 0x10000); - return price; -} - -static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices) -{ - UInt32 price = 0; - UInt32 offs = 0x100; - symbol |= 0x100; - do - { - matchByte <<= 1; - price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); - symbol <<= 1; - offs &= ~(matchByte ^ symbol); - } - while (symbol < 0x10000); - return price; -} - - -static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -{ - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0;) - { - UInt32 bit; - i--; - bit = (symbol >> i) & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - } -} - -static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -{ - UInt32 m = 1; - int i; - for (i = 0; i < numBitLevels; i++) - { - UInt32 bit = symbol & 1; - RangeEnc_EncodeBit(rc, probs + m, bit); - m = (m << 1) | bit; - symbol >>= 1; - } -} - -static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices) -{ - UInt32 price = 0; - symbol |= (1 << numBitLevels); - while (symbol != 1) - { - price += GET_PRICEa(probs[symbol >> 1], symbol & 1); - symbol >>= 1; - } - return price; -} - -static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices) -{ - UInt32 price = 0; - UInt32 m = 1; - int i; - for (i = numBitLevels; i != 0; i--) - { - UInt32 bit = symbol & 1; - symbol >>= 1; - price += GET_PRICEa(probs[m], bit); - m = (m << 1) | bit; - } - return price; -} - - -static void LenEnc_Init(CLenEnc *p) -{ - unsigned i; - p->choice = p->choice2 = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) - p->low[i] = kProbInitValue; - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) - p->mid[i] = kProbInitValue; - for (i = 0; i < kLenNumHighSymbols; i++) - p->high[i] = kProbInitValue; -} - -static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -{ - if (symbol < kLenNumLowSymbols) - { - RangeEnc_EncodeBit(rc, &p->choice, 0); - RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice, 1); - if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) - { - RangeEnc_EncodeBit(rc, &p->choice2, 0); - RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); - } - else - { - RangeEnc_EncodeBit(rc, &p->choice2, 1); - RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); - } - } -} - -static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices) -{ - UInt32 a0 = GET_PRICE_0a(p->choice); - UInt32 a1 = GET_PRICE_1a(p->choice); - UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); - UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); - UInt32 i = 0; - for (i = 0; i < kLenNumLowSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); - } - for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) - { - if (i >= numSymbols) - return; - prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); - } - for (; i < numSymbols; i++) - prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -} - -static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices) -{ - LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); - p->counters[posState] = p->tableSize; -} - -static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices) -{ - UInt32 posState; - for (posState = 0; posState < numPosStates; posState++) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - -static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices) -{ - LenEnc_Encode(&p->p, rc, symbol, posState); - if (updatePrice) - if (--p->counters[posState] == 0) - LenPriceEnc_UpdateTable(p, posState, ProbPrices); -} - - - - -static void MovePos(CLzmaEnc *p, UInt32 num) -{ - #ifdef SHOW_STAT - g_STAT_OFFSET += num; - printf("\n MovePos %u", num); - #endif - - if (num != 0) - { - p->additionalOffset += num; - p->matchFinder.Skip(p->matchFinderObj, num); - } -} - -static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -{ - UInt32 lenRes = 0, numPairs; - p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); - numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); - - #ifdef SHOW_STAT - printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2); - g_STAT_OFFSET++; - { - UInt32 i; - for (i = 0; i < numPairs; i += 2) - printf("%2u %6u | ", p->matches[i], p->matches[i + 1]); - } - #endif - - if (numPairs > 0) - { - lenRes = p->matches[numPairs - 2]; - if (lenRes == p->numFastBytes) - { - UInt32 numAvail = p->numAvail; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - { - const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - const Byte *pby = pbyCur + lenRes; - ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1]; - const Byte *pbyLim = pbyCur + numAvail; - for (; pby != pbyLim && *pby == pby[dif]; pby++); - lenRes = (UInt32)(pby - pbyCur); - } - } - } - p->additionalOffset++; - *numDistancePairsRes = numPairs; - return lenRes; -} - - -#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -#define IsShortRep(p) ((p)->backPrev == 0) - -static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -{ - return - GET_PRICE_0(p->isRepG0[state]) + - GET_PRICE_0(p->isRep0Long[state][posState]); -} - -static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -{ - UInt32 price; - if (repIndex == 0) - { - price = GET_PRICE_0(p->isRepG0[state]); - price += GET_PRICE_1(p->isRep0Long[state][posState]); - } - else - { - price = GET_PRICE_1(p->isRepG0[state]); - if (repIndex == 1) - price += GET_PRICE_0(p->isRepG1[state]); - else - { - price += GET_PRICE_1(p->isRepG1[state]); - price += GET_PRICE(p->isRepG2[state], repIndex - 2); - } - } - return price; -} - -static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -{ - return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + - GetPureRepPrice(p, repIndex, state, posState); -} - -static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -{ - UInt32 posMem = p->opt[cur].posPrev; - UInt32 backMem = p->opt[cur].backPrev; - p->optimumEndIndex = cur; - do - { - if (p->opt[cur].prev1IsChar) - { - MakeAsChar(&p->opt[posMem]) - p->opt[posMem].posPrev = posMem - 1; - if (p->opt[cur].prev2) - { - p->opt[posMem - 1].prev1IsChar = False; - p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; - p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; - } - } - { - UInt32 posPrev = posMem; - UInt32 backCur = backMem; - - backMem = p->opt[posPrev].backPrev; - posMem = p->opt[posPrev].posPrev; - - p->opt[posPrev].backPrev = backCur; - p->opt[posPrev].posPrev = cur; - cur = posPrev; - } - } - while (cur != 0); - *backRes = p->opt[0].backPrev; - p->optimumCurrentIndex = p->opt[0].posPrev; - return p->optimumCurrentIndex; -} - -#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300) - -static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -{ - UInt32 lenEnd, cur; - UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; - UInt32 *matches; - - { - - UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len; - UInt32 matchPrice, repMatchPrice, normalMatchPrice; - const Byte *data; - Byte curByte, matchByte; - - if (p->optimumEndIndex != p->optimumCurrentIndex) - { - const COptimal *opt = &p->opt[p->optimumCurrentIndex]; - UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; - *backRes = opt->backPrev; - p->optimumCurrentIndex = opt->posPrev; - return lenRes; - } - p->optimumCurrentIndex = p->optimumEndIndex = 0; - - if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); - else - { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; - } - - numAvail = p->numAvail; - if (numAvail < 2) - { - *backRes = (UInt32)(-1); - return 1; - } - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - repMaxIndex = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 lenTest; - const Byte *data2; - reps[i] = p->reps[i]; - data2 = data - reps[i] - 1; - if (data[0] != data2[0] || data[1] != data2[1]) - { - repLens[i] = 0; - continue; - } - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - repLens[i] = lenTest; - if (lenTest > repLens[repMaxIndex]) - repMaxIndex = i; - } - if (repLens[repMaxIndex] >= p->numFastBytes) - { - UInt32 lenRes; - *backRes = repMaxIndex; - lenRes = repLens[repMaxIndex]; - MovePos(p, lenRes - 1); - return lenRes; - } - - matches = p->matches; - if (mainLen >= p->numFastBytes) - { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; - } - curByte = *data; - matchByte = *(data - (reps[0] + 1)); - - if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) - { - *backRes = (UInt32)-1; - return 1; - } - - p->opt[0].state = (CState)p->state; - - posState = (position & p->pbMask); - - { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + - (!IsCharState(p->state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); - } - - MakeAsChar(&p->opt[1]); - - matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); - - if (matchByte == curByte) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); - if (shortRepPrice < p->opt[1].price) - { - p->opt[1].price = shortRepPrice; - MakeAsShortRep(&p->opt[1]); - } - } - lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); - - if (lenEnd < 2) - { - *backRes = p->opt[1].backPrev; - return 1; - } - - p->opt[1].posPrev = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - p->opt[0].backs[i] = reps[i]; - - len = lenEnd; - do - p->opt[len--].price = kInfinityPrice; - while (len >= 2); - - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 repLen = repLens[i]; - UInt32 price; - if (repLen < 2) - continue; - price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); - do - { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; - COptimal *opt = &p->opt[repLen]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = i; - opt->prev1IsChar = False; - } - } - while (--repLen >= 2); - } - - normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); - - len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); - if (len <= mainLen) - { - UInt32 offs = 0; - while (len > matches[offs]) - offs += 2; - for (; ; len++) - { - COptimal *opt; - UInt32 distance = matches[offs + 1]; - - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; - UInt32 lenToPosState = GetLenToPosState(len); - if (distance < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][distance]; - else - { - UInt32 slot; - GetPosSlot2(distance, slot); - curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; - } - opt = &p->opt[len]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = 0; - opt->backPrev = distance + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - if (len == matches[offs]) - { - offs += 2; - if (offs == numPairs) - break; - } - } - } - - cur = 0; - - #ifdef SHOW_STAT2 - /* if (position >= 0) */ - { - unsigned i; - printf("\n pos = %4X", position); - for (i = cur; i <= lenEnd; i++) - printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); - } - #endif - - } - - for (;;) - { - UInt32 numAvail; - UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; - UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; - Bool nextIsChar; - Byte curByte, matchByte; - const Byte *data; - COptimal *curOpt; - COptimal *nextOpt; - - cur++; - if (cur == lenEnd) - return Backward(p, backRes, cur); - - newLen = ReadMatchDistances(p, &numPairs); - if (newLen >= p->numFastBytes) - { - p->numPairs = numPairs; - p->longestMatchLength = newLen; - return Backward(p, backRes, cur); - } - position++; - curOpt = &p->opt[cur]; - posPrev = curOpt->posPrev; - if (curOpt->prev1IsChar) - { - posPrev--; - if (curOpt->prev2) - { - state = p->opt[curOpt->posPrev2].state; - if (curOpt->backPrev2 < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; - } - else - state = p->opt[posPrev].state; - state = kLiteralNextStates[state]; - } - else - state = p->opt[posPrev].state; - if (posPrev == cur - 1) - { - if (IsShortRep(curOpt)) - state = kShortRepNextStates[state]; - else - state = kLiteralNextStates[state]; - } - else - { - UInt32 pos; - const COptimal *prevOpt; - if (curOpt->prev1IsChar && curOpt->prev2) - { - posPrev = curOpt->posPrev2; - pos = curOpt->backPrev2; - state = kRepNextStates[state]; - } - else - { - pos = curOpt->backPrev; - if (pos < LZMA_NUM_REPS) - state = kRepNextStates[state]; - else - state = kMatchNextStates[state]; - } - prevOpt = &p->opt[posPrev]; - if (pos < LZMA_NUM_REPS) - { - UInt32 i; - reps[0] = prevOpt->backs[pos]; - for (i = 1; i <= pos; i++) - reps[i] = prevOpt->backs[i - 1]; - for (; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i]; - } - else - { - UInt32 i; - reps[0] = (pos - LZMA_NUM_REPS); - for (i = 1; i < LZMA_NUM_REPS; i++) - reps[i] = prevOpt->backs[i - 1]; - } - } - curOpt->state = (CState)state; - - curOpt->backs[0] = reps[0]; - curOpt->backs[1] = reps[1]; - curOpt->backs[2] = reps[2]; - curOpt->backs[3] = reps[3]; - - curPrice = curOpt->price; - nextIsChar = False; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - curByte = *data; - matchByte = *(data - (reps[0] + 1)); - - posState = (position & p->pbMask); - - curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); - { - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); - curAnd1Price += - (!IsCharState(state) ? - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : - LitEnc_GetPrice(probs, curByte, p->ProbPrices)); - } - - nextOpt = &p->opt[cur + 1]; - - if (curAnd1Price < nextOpt->price) - { - nextOpt->price = curAnd1Price; - nextOpt->posPrev = cur; - MakeAsChar(nextOpt); - nextIsChar = True; - } - - matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); - - if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); - if (shortRepPrice <= nextOpt->price) - { - nextOpt->price = shortRepPrice; - nextOpt->posPrev = cur; - MakeAsShortRep(nextOpt); - nextIsChar = True; - } - } - numAvailFull = p->numAvail; - { - UInt32 temp = kNumOpts - 1 - cur; - if (temp < numAvailFull) - numAvailFull = temp; - } - - if (numAvailFull < 2) - continue; - numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); - - if (!nextIsChar && matchByte != curByte) /* speed optimization */ - { - /* try Literal + rep0 */ - UInt32 temp; - UInt32 lenTest2; - const Byte *data2 = data - reps[0] - 1; - UInt32 limit = p->numFastBytes + 1; - if (limit > numAvailFull) - limit = numAvailFull; - - for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); - lenTest2 = temp - 1; - if (lenTest2 >= 2) - { - UInt32 state2 = kLiteralNextStates[state]; - UInt32 posStateNext = (position + 1) & p->pbMask; - UInt32 nextRepMatchPrice = curAnd1Price + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = False; - } - } - } - } - - startLen = 2; /* speed optimization */ - { - UInt32 repIndex; - for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) - { - UInt32 lenTest; - UInt32 lenTestTemp; - UInt32 price; - const Byte *data2 = data - reps[repIndex] - 1; - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); - while (lenEnd < cur + lenTest) - p->opt[++lenEnd].price = kInfinityPrice; - lenTestTemp = lenTest; - price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); - do - { - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; - COptimal *opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = repIndex; - opt->prev1IsChar = False; - } - } - while (--lenTest >= 2); - lenTest = lenTestTemp; - - if (repIndex == 0) - startLen = lenTest + 1; - - /* if (_maxMode) */ - { - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 nextRepMatchPrice; - UInt32 state2 = kRepNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = - price + p->repLenEnc.prices[posState][lenTest - 2] + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (position + lenTest + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 curAndLenPrice; - COptimal *opt; - UInt32 offset = cur + lenTest + 1 + lenTest2; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = repIndex; - } - } - } - } - } - } - /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ - if (newLen > numAvail) - { - newLen = numAvail; - for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); - matches[numPairs] = newLen; - numPairs += 2; - } - if (newLen >= startLen) - { - UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); - UInt32 offs, curBack, posSlot; - UInt32 lenTest; - while (lenEnd < cur + newLen) - p->opt[++lenEnd].price = kInfinityPrice; - - offs = 0; - while (startLen > matches[offs]) - offs += 2; - curBack = matches[offs + 1]; - GetPosSlot2(curBack, posSlot); - for (lenTest = /*2*/ startLen; ; lenTest++) - { - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; - { - UInt32 lenToPosState = GetLenToPosState(lenTest); - COptimal *opt; - if (curBack < kNumFullDistances) - curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; - else - curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; - - opt = &p->opt[cur + lenTest]; - if (curAndLenPrice < opt->price) - { - opt->price = curAndLenPrice; - opt->posPrev = cur; - opt->backPrev = curBack + LZMA_NUM_REPS; - opt->prev1IsChar = False; - } - } - - if (/*_maxMode && */lenTest == matches[offs]) - { - /* Try Match + Literal + Rep0 */ - const Byte *data2 = data - curBack - 1; - UInt32 lenTest2 = lenTest + 1; - UInt32 limit = lenTest2 + p->numFastBytes; - if (limit > numAvailFull) - limit = numAvailFull; - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); - lenTest2 -= lenTest + 1; - if (lenTest2 >= 2) - { - UInt32 nextRepMatchPrice; - UInt32 state2 = kMatchNextStates[state]; - UInt32 posStateNext = (position + lenTest) & p->pbMask; - UInt32 curAndLenCharPrice = curAndLenPrice + - GET_PRICE_0(p->isMatch[state2][posStateNext]) + - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), - data[lenTest], data2[lenTest], p->ProbPrices); - state2 = kLiteralNextStates[state2]; - posStateNext = (posStateNext + 1) & p->pbMask; - nextRepMatchPrice = curAndLenCharPrice + - GET_PRICE_1(p->isMatch[state2][posStateNext]) + - GET_PRICE_1(p->isRep[state2]); - - /* for (; lenTest2 >= 2; lenTest2--) */ - { - UInt32 offset = cur + lenTest + 1 + lenTest2; - UInt32 curAndLenPrice2; - COptimal *opt; - while (lenEnd < offset) - p->opt[++lenEnd].price = kInfinityPrice; - curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); - opt = &p->opt[offset]; - if (curAndLenPrice2 < opt->price) - { - opt->price = curAndLenPrice2; - opt->posPrev = cur + lenTest + 1; - opt->backPrev = 0; - opt->prev1IsChar = True; - opt->prev2 = True; - opt->posPrev2 = cur; - opt->backPrev2 = curBack + LZMA_NUM_REPS; - } - } - } - offs += 2; - if (offs == numPairs) - break; - curBack = matches[offs + 1]; - if (curBack >= kNumFullDistances) - GetPosSlot2(curBack, posSlot); - } - } - } - } -} - -#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) - -static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -{ - UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; - const Byte *data; - const UInt32 *matches; - - if (p->additionalOffset == 0) - mainLen = ReadMatchDistances(p, &numPairs); - else - { - mainLen = p->longestMatchLength; - numPairs = p->numPairs; - } - - numAvail = p->numAvail; - *backRes = (UInt32)-1; - if (numAvail < 2) - return 1; - if (numAvail > LZMA_MATCH_LEN_MAX) - numAvail = LZMA_MATCH_LEN_MAX; - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - - repLen = repIndex = 0; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 len; - const Byte *data2 = data - p->reps[i] - 1; - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - for (len = 2; len < numAvail && data[len] == data2[len]; len++); - if (len >= p->numFastBytes) - { - *backRes = i; - MovePos(p, len - 1); - return len; - } - if (len > repLen) - { - repIndex = i; - repLen = len; - } - } - - matches = p->matches; - if (mainLen >= p->numFastBytes) - { - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; - MovePos(p, mainLen - 1); - return mainLen; - } - - mainDist = 0; /* for GCC */ - if (mainLen >= 2) - { - mainDist = matches[numPairs - 1]; - while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) - { - if (!ChangePair(matches[numPairs - 3], mainDist)) - break; - numPairs -= 2; - mainLen = matches[numPairs - 2]; - mainDist = matches[numPairs - 1]; - } - if (mainLen == 2 && mainDist >= 0x80) - mainLen = 1; - } - - if (repLen >= 2 && ( - (repLen + 1 >= mainLen) || - (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || - (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) - { - *backRes = repIndex; - MovePos(p, repLen - 1); - return repLen; - } - - if (mainLen < 2 || numAvail <= 2) - return 1; - - p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); - if (p->longestMatchLength >= 2) - { - UInt32 newDistance = matches[p->numPairs - 1]; - if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || - (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || - (p->longestMatchLength > mainLen + 1) || - (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) - return 1; - } - - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; - for (i = 0; i < LZMA_NUM_REPS; i++) - { - UInt32 len, limit; - const Byte *data2 = data - p->reps[i] - 1; - if (data[0] != data2[0] || data[1] != data2[1]) - continue; - limit = mainLen - 1; - for (len = 2; len < limit && data[len] == data2[len]; len++); - if (len >= limit) - return 1; - } - *backRes = mainDist + LZMA_NUM_REPS; - MovePos(p, mainLen - 2); - return mainLen; -} - -static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -{ - UInt32 len; - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - len = LZMA_MATCH_LEN_MIN; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); - RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -} - -static SRes CheckErrors(CLzmaEnc *p) -{ - if (p->result != SZ_OK) - return p->result; - if (p->rc.res != SZ_OK) - p->result = SZ_ERROR_WRITE; - if (p->matchFinderBase.result != SZ_OK) - p->result = SZ_ERROR_READ; - if (p->result != SZ_OK) - p->finished = True; - return p->result; -} - -static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -{ - /* ReleaseMFStream(); */ - p->finished = True; - if (p->writeEndMark) - WriteEndMarker(p, nowPos & p->pbMask); - RangeEnc_FlushData(&p->rc); - RangeEnc_FlushStream(&p->rc); - return CheckErrors(p); -} - -static void FillAlignPrices(CLzmaEnc *p) -{ - UInt32 i; - for (i = 0; i < kAlignTableSize; i++) - p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); - p->alignPriceCount = 0; -} - -static void FillDistancesPrices(CLzmaEnc *p) -{ - UInt32 tempPrices[kNumFullDistances]; - UInt32 i, lenToPosState; - for (i = kStartPosModelIndex; i < kNumFullDistances; i++) - { - UInt32 posSlot = GetPosSlot1(i); - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); - } - - for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) - { - UInt32 posSlot; - const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; - UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; - for (posSlot = 0; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); - for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) - posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); - - { - UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; - for (i = 0; i < kStartPosModelIndex; i++) - distancesPrices[i] = posSlotPrices[i]; - for (; i < kNumFullDistances; i++) - distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; - } - } - p->matchPriceCount = 0; -} - -void LzmaEnc_Construct(CLzmaEnc *p) -{ - RangeEnc_Construct(&p->rc); - MatchFinder_Construct(&p->matchFinderBase); - - #ifndef _7ZIP_ST - MatchFinderMt_Construct(&p->matchFinderMt); - p->matchFinderMt.MatchFinder = &p->matchFinderBase; - #endif - - { - CLzmaEncProps props; - LzmaEncProps_Init(&props); - LzmaEnc_SetProps(p, &props); - } - - #ifndef LZMA_LOG_BSR - LzmaEnc_FastPosInit(p->g_FastPos); - #endif - - LzmaEnc_InitPriceTables(p->ProbPrices); - p->litProbs = NULL; - p->saveState.litProbs = NULL; -} - -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -{ - void *p; - p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); - if (p) - LzmaEnc_Construct((CLzmaEnc *)p); - return p; -} - -void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->litProbs); - alloc->Free(alloc, p->saveState.litProbs); - p->litProbs = NULL; - p->saveState.litProbs = NULL; -} - -void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - #ifndef _7ZIP_ST - MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); - #endif - - MatchFinder_Free(&p->matchFinderBase, allocBig); - LzmaEnc_FreeLits(p, alloc); - RangeEnc_Free(&p->rc, alloc); -} - -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); - alloc->Free(alloc, p); -} - -static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -{ - UInt32 nowPos32, startPos32; - if (p->needInit) - { - p->matchFinder.Init(p->matchFinderObj); - p->needInit = 0; - } - - if (p->finished) - return p->result; - RINOK(CheckErrors(p)); - - nowPos32 = (UInt32)p->nowPos64; - startPos32 = nowPos32; - - if (p->nowPos64 == 0) - { - UInt32 numPairs; - Byte curByte; - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - return Flush(p, nowPos32); - ReadMatchDistances(p, &numPairs); - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); - p->state = kLiteralNextStates[p->state]; - curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset); - LitEnc_Encode(&p->rc, p->litProbs, curByte); - p->additionalOffset--; - nowPos32++; - } - - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) - for (;;) - { - UInt32 pos, len, posState; - - if (p->fastMode) - len = GetOptimumFast(p, &pos); - else - len = GetOptimum(p, nowPos32, &pos); - - #ifdef SHOW_STAT2 - printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos); - #endif - - posState = nowPos32 & p->pbMask; - if (len == 1 && pos == (UInt32)-1) - { - Byte curByte; - CLzmaProb *probs; - const Byte *data; - - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; - curByte = *data; - probs = LIT_PROBS(nowPos32, *(data - 1)); - if (IsCharState(p->state)) - LitEnc_Encode(&p->rc, probs, curByte); - else - LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); - p->state = kLiteralNextStates[p->state]; - } - else - { - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); - if (pos < LZMA_NUM_REPS) - { - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); - if (pos == 0) - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); - RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); - } - else - { - UInt32 distance = p->reps[pos]; - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); - if (pos == 1) - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); - else - { - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); - RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); - if (pos == 3) - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - } - p->reps[1] = p->reps[0]; - p->reps[0] = distance; - } - if (len == 1) - p->state = kShortRepNextStates[p->state]; - else - { - LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - p->state = kRepNextStates[p->state]; - } - } - else - { - UInt32 posSlot; - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); - p->state = kMatchNextStates[p->state]; - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); - pos -= LZMA_NUM_REPS; - GetPosSlot(pos, posSlot); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); - - if (posSlot >= kStartPosModelIndex) - { - UInt32 footerBits = ((posSlot >> 1) - 1); - UInt32 base = ((2 | (posSlot & 1)) << footerBits); - UInt32 posReduced = pos - base; - - if (posSlot < kEndPosModelIndex) - RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); - else - { - RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); - p->alignPriceCount++; - } - } - p->reps[3] = p->reps[2]; - p->reps[2] = p->reps[1]; - p->reps[1] = p->reps[0]; - p->reps[0] = pos; - p->matchPriceCount++; - } - } - p->additionalOffset -= len; - nowPos32 += len; - if (p->additionalOffset == 0) - { - UInt32 processed; - if (!p->fastMode) - { - if (p->matchPriceCount >= (1 << 7)) - FillDistancesPrices(p); - if (p->alignPriceCount >= kAlignTableSize) - FillAlignPrices(p); - } - if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) - break; - processed = nowPos32 - startPos32; - if (useLimits) - { - if (processed + kNumOpts + 300 >= maxUnpackSize || - RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) - break; - } - else if (processed >= (1 << 17)) - { - p->nowPos64 += nowPos32 - startPos32; - return CheckErrors(p); - } - } - } - p->nowPos64 += nowPos32 - startPos32; - return Flush(p, nowPos32); -} - -#define kBigHashDicLimit ((UInt32)1 << 24) - -static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - UInt32 beforeSize = kNumOpts; - if (!RangeEnc_Alloc(&p->rc, alloc)) - return SZ_ERROR_MEM; - - #ifndef _7ZIP_ST - p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); - #endif - - { - unsigned lclp = p->lc + p->lp; - if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) - { - LzmaEnc_FreeLits(p, alloc); - p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); - p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); - if (!p->litProbs || !p->saveState.litProbs) - { - LzmaEnc_FreeLits(p, alloc); - return SZ_ERROR_MEM; - } - p->lclp = lclp; - } - } - - p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); - - if (beforeSize + p->dictSize < keepWindowSize) - beforeSize = keepWindowSize - p->dictSize; - - #ifndef _7ZIP_ST - if (p->mtMode) - { - RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); - p->matchFinderObj = &p->matchFinderMt; - MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); - } - else - #endif - { - if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) - return SZ_ERROR_MEM; - p->matchFinderObj = &p->matchFinderBase; - MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); - } - - return SZ_OK; -} - -void LzmaEnc_Init(CLzmaEnc *p) -{ - UInt32 i; - p->state = 0; - for (i = 0 ; i < LZMA_NUM_REPS; i++) - p->reps[i] = 0; - - RangeEnc_Init(&p->rc); - - - for (i = 0; i < kNumStates; i++) - { - UInt32 j; - for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) - { - p->isMatch[i][j] = kProbInitValue; - p->isRep0Long[i][j] = kProbInitValue; - } - p->isRep[i] = kProbInitValue; - p->isRepG0[i] = kProbInitValue; - p->isRepG1[i] = kProbInitValue; - p->isRepG2[i] = kProbInitValue; - } - - { - UInt32 num = (UInt32)0x300 << (p->lp + p->lc); - CLzmaProb *probs = p->litProbs; - for (i = 0; i < num; i++) - probs[i] = kProbInitValue; - } - - { - for (i = 0; i < kNumLenToPosStates; i++) - { - CLzmaProb *probs = p->posSlotEncoder[i]; - UInt32 j; - for (j = 0; j < (1 << kNumPosSlotBits); j++) - probs[j] = kProbInitValue; - } - } - { - for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) - p->posEncoders[i] = kProbInitValue; - } - - LenEnc_Init(&p->lenEnc.p); - LenEnc_Init(&p->repLenEnc.p); - - for (i = 0; i < (1 << kNumAlignBits); i++) - p->posAlignEncoder[i] = kProbInitValue; - - p->optimumEndIndex = 0; - p->optimumCurrentIndex = 0; - p->additionalOffset = 0; - - p->pbMask = (1 << p->pb) - 1; - p->lpMask = (1 << p->lp) - 1; -} - -void LzmaEnc_InitPrices(CLzmaEnc *p) -{ - if (!p->fastMode) - { - FillDistancesPrices(p); - FillAlignPrices(p); - } - - p->lenEnc.tableSize = - p->repLenEnc.tableSize = - p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; - LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); - LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -} - -static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - UInt32 i; - for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) - if (p->dictSize <= ((UInt32)1 << i)) - break; - p->distTableSize = i * 2; - - p->finished = False; - p->result = SZ_OK; - RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - p->nowPos64 = 0; - return SZ_OK; -} - -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - p->rc.outStream = outStream; - return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -} - -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, - ISeqInStream *inStream, UInt32 keepWindowSize, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - p->matchFinderBase.stream = inStream; - p->needInit = 1; - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -{ - p->matchFinderBase.directInput = 1; - p->matchFinderBase.bufferBase = (Byte *)src; - p->matchFinderBase.directInputRem = srcLen; -} - -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - LzmaEnc_SetInputBuf(p, src, srcLen); - p->needInit = 1; - - return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -} - -void LzmaEnc_Finish(CLzmaEncHandle pp) -{ - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; - if (p->mtMode) - MatchFinderMt_ReleaseStream(&p->matchFinderMt); - #else - UNUSED_VAR(pp); - #endif -} - - -typedef struct -{ - ISeqOutStream funcTable; - Byte *data; - SizeT rem; - Bool overflow; -} CSeqOutStreamBuf; - -static size_t MyWrite(void *pp, const void *data, size_t size) -{ - CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; - if (p->rem < size) - { - size = p->rem; - p->overflow = True; - } - memcpy(p->data, data, size); - p->rem -= size; - p->data += size; - return size; -} - - -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -{ - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -} - - -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -{ - const CLzmaEnc *p = (CLzmaEnc *)pp; - return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -} - - -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, - Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - UInt64 nowPos64; - SRes res; - CSeqOutStreamBuf outStream; - - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; - - p->writeEndMark = False; - p->finished = False; - p->result = SZ_OK; - - if (reInit) - LzmaEnc_Init(p); - LzmaEnc_InitPrices(p); - nowPos64 = p->nowPos64; - RangeEnc_Init(&p->rc); - p->rc.outStream = &outStream.funcTable; - - res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); - - *unpackSize = (UInt32)(p->nowPos64 - nowPos64); - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - - return res; -} - - -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -{ - SRes res = SZ_OK; - - #ifndef _7ZIP_ST - Byte allocaDummy[0x300]; - allocaDummy[0] = 0; - allocaDummy[1] = allocaDummy[0]; - #endif - - for (;;) - { - res = LzmaEnc_CodeOneBlock(p, False, 0, 0); - if (res != SZ_OK || p->finished) - break; - if (progress) - { - res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); - if (res != SZ_OK) - { - res = SZ_ERROR_PROGRESS; - break; - } - } - } - - LzmaEnc_Finish(p); - - /* - if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) - res = SZ_ERROR_FAIL; - } - */ - - return res; -} - - -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, - ISzAlloc *alloc, ISzAlloc *allocBig) -{ - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -} - - -SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - unsigned i; - UInt32 dictSize = p->dictSize; - if (*size < LZMA_PROPS_SIZE) - return SZ_ERROR_PARAM; - *size = LZMA_PROPS_SIZE; - props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); - - if (dictSize >= ((UInt32)1 << 22)) - { - UInt32 kDictMask = ((UInt32)1 << 20) - 1; - if (dictSize < (UInt32)0xFFFFFFFF - kDictMask) - dictSize = (dictSize + kDictMask) & ~kDictMask; - } - else for (i = 11; i <= 30; i++) - { - if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; } - if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; } - } - - for (i = 0; i < 4; i++) - props[1 + i] = (Byte)(dictSize >> (8 * i)); - return SZ_OK; -} - - -SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - SRes res; - CLzmaEnc *p = (CLzmaEnc *)pp; - - CSeqOutStreamBuf outStream; - - outStream.funcTable.Write = MyWrite; - outStream.data = dest; - outStream.rem = *destLen; - outStream.overflow = False; - - p->writeEndMark = writeEndMark; - p->rc.outStream = &outStream.funcTable; - - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); - - if (res == SZ_OK) - { - res = LzmaEnc_Encode2(p, progress); - if (res == SZ_OK && p->nowPos64 != srcLen) - res = SZ_ERROR_FAIL; - } - - *destLen -= outStream.rem; - if (outStream.overflow) - return SZ_ERROR_OUTPUT_EOF; - return res; -} - - -SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); - SRes res; - if (!p) - return SZ_ERROR_MEM; - - res = LzmaEnc_SetProps(p, props); - if (res == SZ_OK) - { - res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); - if (res == SZ_OK) - res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, - writeEndMark, progress, alloc, allocBig); - } - - LzmaEnc_Destroy(p, alloc, allocBig); - return res; -} +/* LzmaEnc.c -- LZMA Encoder +Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#if defined(SHOW_STAT) || defined(SHOW_STAT2) +#include +#endif + +#include "CpuArch.h" +#include "LzmaEnc.h" + +#include "LzFind.h" +#ifndef Z7_ST +#include "LzFindMt.h" +#endif + +/* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */ + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); + +#ifdef SHOW_STAT +static unsigned g_STAT_OFFSET = 0; +#endif + +/* for good normalization speed we still reserve 256 MB before 4 GB range */ +#define kLzmaMaxHistorySize ((UInt32)15 << 28) + +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +// #define kBitPrice (1 << kNumBitPriceShiftBits) + +#define REP_LEN_COUNT 64 + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->reduceSize = (UInt64)(Int64)-1; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->numHashOutBits = 0; + p->writeEndMark = 0; + p->affinityGroup = -1; + p->affinity = 0; + p->affinityInGroup = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + + if (p->dictSize == 0) + p->dictSize = (unsigned)level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + (unsigned)level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); + + if (p->dictSize > p->reduceSize) + { + UInt32 v = (UInt32)p->reduceSize; + const UInt32 kReduceMin = ((UInt32)1 << 12); + if (v < kReduceMin) + v = kReduceMin; + if (p->dictSize > v) + p->dictSize = v; + } + + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + + if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1; + if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64; + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5); + if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1); + + if (p->numThreads < 0) + p->numThreads = + #ifndef Z7_ST + ((p->btMode && p->algo) ? 2 : 1); + #else + 1; + #endif +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + + +/* +x86/x64: + +BSR: + IF (SRC == 0) ZF = 1, DEST is undefined; + AMD : DEST is unchanged; + IF (SRC != 0) ZF = 0; DEST is index of top non-zero bit + BSR is slow in some processors + +LZCNT: + IF (SRC == 0) CF = 1, DEST is size_in_bits_of_register(src) (32 or 64) + IF (SRC != 0) CF = 0, DEST = num_lead_zero_bits + IF (DEST == 0) ZF = 1; + +LZCNT works only in new processors starting from Haswell. +if LZCNT is not supported by processor, then it's executed as BSR. +LZCNT can be faster than BSR, if supported. +*/ + +// #define LZMA_LOG_BSR + +#if defined(MY_CPU_ARM_OR_ARM64) /* || defined(MY_CPU_X86_OR_AMD64) */ + + #if (defined(__clang__) && (__clang_major__ >= 6)) \ + || (defined(__GNUC__) && (__GNUC__ >= 6)) + #define LZMA_LOG_BSR + #elif defined(_MSC_VER) && (_MSC_VER >= 1300) + // #if defined(MY_CPU_ARM_OR_ARM64) + #define LZMA_LOG_BSR + // #endif + #endif +#endif + +// #include + +#ifdef LZMA_LOG_BSR + +#if defined(__clang__) \ + || defined(__GNUC__) + +/* + C code: : (30 - __builtin_clz(x)) + gcc9/gcc10 for x64 /x86 : 30 - (bsr(x) xor 31) + clang10 for x64 : 31 + (bsr(x) xor -32) +*/ + + #define MY_clz(x) ((unsigned)__builtin_clz(x)) + // __lzcnt32 + // __builtin_ia32_lzcnt_u32 + +#else // #if defined(_MSC_VER) + + #ifdef MY_CPU_ARM_OR_ARM64 + + #define MY_clz _CountLeadingZeros + + #else // if defined(MY_CPU_X86_OR_AMD64) + + // #define MY_clz __lzcnt // we can use lzcnt (unsupported by old CPU) + // _BitScanReverse code is not optimal for some MSVC compilers + #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); zz--; \ + res = (zz + zz) + (pos >> zz); } + + #endif // MY_CPU_X86_OR_AMD64 + +#endif // _MSC_VER + + +#ifndef BSR2_RET + + #define BSR2_RET(pos, res) { unsigned zz = 30 - MY_clz(pos); \ + res = (zz + zz) + (pos >> zz); } + +#endif + + +unsigned GetPosSlot1(UInt32 pos); +unsigned GetPosSlot1(UInt32 pos) +{ + unsigned res; + BSR2_RET(pos, res) + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res) } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) } + + +#else // ! LZMA_LOG_BSR + +#define kNumLogBits (11 + sizeof(size_t) / 8 * 3) + +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +static void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + unsigned slot; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + g_FastPos += 2; + + for (slot = 2; slot < kNumLogBits * 2; slot++) + { + size_t k = ((size_t)1 << ((slot >> 1) - 1)); + size_t j; + for (j = 0; j < k; j++) + g_FastPos[j] = (Byte)slot; + g_FastPos += k; + } +} + +/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +/* +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } +*/ + +#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ + res = p->g_FastPos[pos >> zz] + (zz * 2); } + +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); } + +#endif // LZMA_LOG_BSR + + +#define LZMA_NUM_REPS 4 + +typedef UInt16 CState; +typedef UInt16 CExtra; + +typedef struct +{ + UInt32 price; + CState state; + CExtra extra; + // 0 : normal + // 1 : LIT : MATCH + // > 1 : MATCH (extra-1) : LIT : REP0 (len) + UInt32 len; + UInt32 dist; + UInt32 reps[LZMA_NUM_REPS]; +} COptimal; + + +// 18.06 +#define kNumOpts (1 << 11) +#define kPackReserve (kNumOpts * 8) +// #define kNumOpts (1 << 12) +// #define kPackReserve (1 + kNumOpts * 2) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +// #define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +typedef +#ifdef Z7_LZMA_PROB32 + UInt32 +#else + UInt16 +#endif + CLzmaProb; + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) +#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + + +typedef struct +{ + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + + +typedef struct +{ + unsigned tableSize; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2]; + // UInt32 prices2[kLenNumSymbolsTotal]; +} CLenPriceEnc; + +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN]) + +/* +#define GET_PRICE_LEN(p, posState, len) \ + ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9))) +*/ + +typedef struct +{ + UInt32 range; + unsigned cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStreamPtr outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + + +typedef struct +{ + CLzmaProb *litProbs; + + unsigned state; + UInt32 reps[LZMA_NUM_REPS]; + + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; + +} CSaveState; + + +typedef UInt32 CProbPrice; + + +struct CLzmaEnc +{ + void *matchFinderObj; + IMatchFinder2 matchFinder; + + unsigned optCur; + unsigned optEnd; + + unsigned longestMatchLen; + unsigned numPairs; + UInt32 numAvail; + + unsigned state; + unsigned numFastBytes; + unsigned additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + unsigned lpMask, pbMask; + CLzmaProb *litProbs; + CRangeEnc rc; + + UInt32 backRes; + + unsigned lc, lp, pb; + unsigned lclp; + + BoolInt fastMode; + BoolInt writeEndMark; + BoolInt finished; + BoolInt multiThread; + BoolInt needInit; + // BoolInt _maxMode; + + UInt64 nowPos64; + + unsigned matchPriceCount; + // unsigned alignPriceCount; + int repLenEncCounter; + + unsigned distTableSize; + + UInt32 dictSize; + SRes result; + + #ifndef Z7_ST + BoolInt mtMode; + // begin of CMatchFinderMt is used in LZ thread + CMatchFinderMt matchFinderMt; + // end of CMatchFinderMt is used in BT and HASH threads + // #else + // CMatchFinder matchFinderBase; + #endif + CMatchFinder matchFinderBase; + + + // we suppose that we have 8-bytes alignment after CMatchFinder + + #ifndef Z7_ST + Byte pad[128]; + #endif + + // LZ thread + CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + + // we want {len , dist} pairs to be 8-bytes aligned in matches array + UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2]; + + // we want 8-bytes alignment here + UInt32 alignPrices[kAlignTableSize]; + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances]; + + CLenEnc lenProbs; + CLenEnc repLenProbs; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + COptimal opt[kNumOpts]; + + CSaveState saveState; + + // BoolInt mf_Failure; + #ifndef Z7_ST + Byte pad2[128]; + #endif +}; + + +#define MFB (p->matchFinderBase) +/* +#ifndef Z7_ST +#define MFB (p->matchFinderMt.MatchFinder) +#endif +*/ + +// #define GET_CLzmaEnc_p CLzmaEnc *p = (CLzmaEnc*)(void *)p; +// #define GET_const_CLzmaEnc_p const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p; + +#define COPY_ARR(dest, src, arr) memcpy((dest)->arr, (src)->arr, sizeof((src)->arr)); + +#define COPY_LZMA_ENC_STATE(d, s, p) \ + (d)->state = (s)->state; \ + COPY_ARR(d, s, reps) \ + COPY_ARR(d, s, posAlignEncoder) \ + COPY_ARR(d, s, isRep) \ + COPY_ARR(d, s, isRepG0) \ + COPY_ARR(d, s, isRepG1) \ + COPY_ARR(d, s, isRepG2) \ + COPY_ARR(d, s, isMatch) \ + COPY_ARR(d, s, isRep0Long) \ + COPY_ARR(d, s, posSlotEncoder) \ + COPY_ARR(d, s, posEncoders) \ + (d)->lenProbs = (s)->lenProbs; \ + (d)->repLenProbs = (s)->repLenProbs; \ + memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp); + +void LzmaEnc_SaveState(CLzmaEncHandle p) +{ + // GET_CLzmaEnc_p + CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(v, p, p) +} + +void LzmaEnc_RestoreState(CLzmaEncHandle p) +{ + // GET_CLzmaEnc_p + const CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(p, v, p) +} + + +Z7_NO_INLINE +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2) +{ + // GET_CLzmaEnc_p + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX + || props.lp > LZMA_LP_MAX + || props.pb > LZMA_PB_MAX) + return SZ_ERROR_PARAM; + + + if (props.dictSize > kLzmaMaxHistorySize) + props.dictSize = kLzmaMaxHistorySize; + + #ifndef LZMA_LOG_BSR + { + const UInt64 dict64 = props.dictSize; + if (dict64 > ((UInt64)1 << kDicLogSizeMaxCompress)) + return SZ_ERROR_PARAM; + } + #endif + + p->dictSize = props.dictSize; + { + unsigned fb = (unsigned)props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = (unsigned)props.lc; + p->lp = (unsigned)props.lp; + p->pb = (unsigned)props.pb; + p->fastMode = (props.algo == 0); + // p->_maxMode = True; + MFB.btMode = (Byte)(props.btMode ? 1 : 0); + // MFB.btMode = (Byte)(props.btMode); + { + unsigned numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) numHashBytes = 2; + else if (props.numHashBytes < 4) numHashBytes = (unsigned)props.numHashBytes; + } + if (props.numHashBytes >= 5) numHashBytes = 5; + + MFB.numHashBytes = numHashBytes; + // MFB.numHashBytes_Min = 2; + MFB.numHashOutBits = (Byte)props.numHashOutBits; + } + + MFB.cutValue = props.mc; + + p->writeEndMark = (BoolInt)props.writeEndMark; + + #ifndef Z7_ST + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + p->matchFinderMt.btSync.affinity = + p->matchFinderMt.hashSync.affinity = props.affinity; + p->matchFinderMt.btSync.affinityGroup = + p->matchFinderMt.hashSync.affinityGroup = props.affinityGroup; + p->matchFinderMt.btSync.affinityInGroup = + p->matchFinderMt.hashSync.affinityInGroup = props.affinityInGroup; + #endif + + return SZ_OK; +} + + +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize) +{ + // GET_CLzmaEnc_p + MFB.expectedDataSize = expectedDataSiize; +} + + +#define kState_Start 0 +#define kState_LitAfterMatch 4 +#define kState_LitAfterRep 5 +#define kState_MatchAfterLit 7 +#define kState_RepAfterLit 8 + +static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +#define IsLitState(s) ((s) < 7) +#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1) +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = NULL; + p->bufBase = NULL; +} + +#define RangeEnc_GetProcessed(p) ( (p)->processed + (size_t)((p)->buf - (p)->bufBase) + (p)->cacheSize) +#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + (size_t)((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) + +static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc) +{ + if (!p->bufBase) + { + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE); + if (!p->bufBase) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + p->range = 0xFFFFFFFF; + p->cache = 0; + p->low = 0; + p->cacheSize = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) +{ + const size_t num = (size_t)(p->buf - p->bufBase); + if (p->res == SZ_OK) + { + if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + } + p->processed += num; + p->buf = p->bufBase; +} + +Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + UInt32 low = (UInt32)p->low; + unsigned high = (unsigned)(p->low >> 32); + p->low = (UInt32)(low << 8); + if (low < (UInt32)0xFF000000 || high != 0) + { + { + Byte *buf = p->buf; + *buf++ = (Byte)(p->cache + high); + p->cache = (unsigned)(low >> 24); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (p->cacheSize == 0) + return; + } + high += 0xFF; + for (;;) + { + Byte *buf = p->buf; + *buf++ = (Byte)(high); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + if (--p->cacheSize == 0) + return; + } + } + p->cacheSize++; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); } + +#define RC_BIT_PRE(p, prob) \ + ttt = *(prob); \ + newBound = (range >> kNumBitModelTotalBits) * ttt; + +// #define Z7_LZMA_ENC_USE_BRANCH + +#ifdef Z7_LZMA_ENC_USE_BRANCH + +#define RC_BIT(p, prob, bit) { \ + RC_BIT_PRE(p, prob) \ + if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \ + else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#else + +#define RC_BIT(p, prob, bit) { \ + UInt32 mask; \ + RC_BIT_PRE(p, prob) \ + mask = 0 - (UInt32)bit; \ + range &= mask; \ + mask &= newBound; \ + range -= mask; \ + (p)->low += mask; \ + mask = (UInt32)bit - 1; \ + range += newBound & mask; \ + mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \ + mask += ((1 << kNumMoveBits) - 1); \ + ttt += (UInt32)((Int32)(mask - ttt) >> kNumMoveBits); \ + *(prob) = (CLzmaProb)ttt; \ + RC_NORM(p) \ + } + +#endif + + + + +#define RC_BIT_0_BASE(p, prob) \ + range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + +#define RC_BIT_1_BASE(p, prob) \ + range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \ + +#define RC_BIT_0(p, prob) \ + RC_BIT_0_BASE(p, prob) \ + RC_NORM(p) + +#define RC_BIT_1(p, prob) \ + RC_BIT_1_BASE(p, prob) \ + RC_NORM(p) + +static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob) +{ + UInt32 range, ttt, newBound; + range = p->range; + RC_BIT_PRE(p, prob) + RC_BIT_0(p, prob) + p->range = range; +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym) +{ + UInt32 range = p->range; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1); + CLzmaProb *prob = probs + (sym >> 8); + UInt32 bit = (sym >> 7) & 1; + sym <<= 1; + RC_BIT(p, prob, bit) + } + while (sym < 0x10000); + p->range = range; +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte) +{ + UInt32 range = p->range; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + UInt32 ttt, newBound; + CLzmaProb *prob; + UInt32 bit; + matchByte <<= 1; + // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1); + prob = probs + (offs + (matchByte & offs) + (sym >> 8)); + bit = (sym >> 7) & 1; + sym <<= 1; + offs &= ~(matchByte ^ sym); + RC_BIT(p, prob, bit) + } + while (sym < 0x10000); + p->range = range; +} + + + +static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices) +{ + UInt32 i; + for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++) + { + const unsigned kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1)); + unsigned bitCount = 0; + unsigned j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i] = (CProbPrice)(((unsigned)kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + // printf("\n%3d: %5d", i, ProbPrices[i]); + } +} + + +#define GET_PRICE(prob, bit) \ + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] + +#define GET_PRICEa(prob, bit) \ + ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices) +{ + UInt32 price = 0; + sym |= 0x100; + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); + } + while (sym >= 2); + return price; +} + + +static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + sym |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1); + sym <<= 1; + offs &= ~(matchByte ^ sym); + } + while (sym < 0x10000); + return price; +} + + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym) +{ + UInt32 range = rc->range; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + unsigned bit = sym & 1; + // RangeEnc_EncodeBit(rc, probs + m, bit); + sym >>= 1; + RC_BIT(rc, probs + m, bit) + m = (m << 1) | bit; + } + while (--numBits); + rc->range = range; +} + + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState) +{ + UInt32 range, ttt, newBound; + CLzmaProb *probs = p->low; + range = rc->range; + RC_BIT_PRE(rc, probs) + if (sym >= kLenNumLowSymbols) + { + RC_BIT_1(rc, probs) + probs += kLenNumLowSymbols; + RC_BIT_PRE(rc, probs) + if (sym >= kLenNumLowSymbols * 2) + { + RC_BIT_1(rc, probs) + rc->range = range; + // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2); + LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2); + return; + } + sym -= kLenNumLowSymbols; + } + + // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym); + { + unsigned m; + unsigned bit; + RC_BIT_0(rc, probs) + probs += (posState << (1 + kLenNumLowBits)); + bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit) m = (1 << 1) + bit; + bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit) m = (m << 1) + bit; + bit = sym & 1; RC_BIT(rc, probs + m, bit) + rc->range = range; + } +} + +static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices) +{ + unsigned i; + for (i = 0; i < 8; i += 2) + { + UInt32 price = startPrice; + UInt32 prob; + price += GET_PRICEa(probs[1 ], (i >> 2)); + price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1); + prob = probs[4 + (i >> 1)]; + prices[i ] = price + GET_PRICEa_0(prob); + prices[i + 1] = price + GET_PRICEa_1(prob); + } +} + + +Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables( + CLenPriceEnc *p, + unsigned numPosStates, + const CLenEnc *enc, + const CProbPrice *ProbPrices) +{ + UInt32 b; + + { + unsigned prob = enc->low[0]; + UInt32 a, c; + unsigned posState; + b = GET_PRICEa_1(prob); + a = GET_PRICEa_0(prob); + c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); + for (posState = 0; posState < numPosStates; posState++) + { + UInt32 *prices = p->prices[posState]; + const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits)); + SetPrices_3(probs, a, prices, ProbPrices); + SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices); + } + } + + /* + { + unsigned i; + UInt32 b; + a = GET_PRICEa_0(enc->low[0]); + for (i = 0; i < kLenNumLowSymbols; i++) + p->prices2[i] = a; + a = GET_PRICEa_1(enc->low[0]); + b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]); + for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++) + p->prices2[i] = b; + a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + } + */ + + // p->counter = numSymbols; + // p->counter = 64; + + { + unsigned i = p->tableSize; + + if (i > kLenNumLowSymbols * 2) + { + const CLzmaProb *probs = enc->high; + UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2; + i -= kLenNumLowSymbols * 2 - 1; + i >>= 1; + b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]); + do + { + /* + p->prices2[i] = a + + // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices); + LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices); + */ + // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices); + unsigned sym = --i + (1 << (kLenNumHighBits - 1)); + UInt32 price = b; + do + { + const unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[sym], bit); + } + while (sym >= 2); + + { + const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))]; + prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob); + prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob); + } + } + while (i); + + { + unsigned posState; + const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]); + for (posState = 1; posState < numPosStates; posState++) + memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num); + } + } + } +} + +/* + #ifdef SHOW_STAT + g_STAT_OFFSET += num; + printf("\n MovePos %u", num); + #endif +*/ + +#define MOVE_POS(p, num) { \ + p->additionalOffset += (num); \ + p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); } + + +static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes) +{ + unsigned numPairs; + + p->additionalOffset++; + p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + { + const UInt32 *d = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); + // if (!d) { p->mf_Failure = True; *numPairsRes = 0; return 0; } + numPairs = (unsigned)(d - p->matches); + } + *numPairsRes = numPairs; + + #ifdef SHOW_STAT + printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2); + g_STAT_OFFSET++; + { + unsigned i; + for (i = 0; i < numPairs; i += 2) + printf("%2u %6u | ", p->matches[i], p->matches[i + 1]); + } + #endif + + if (numPairs == 0) + return 0; + { + const unsigned len = p->matches[(size_t)numPairs - 2]; + if (len != p->numFastBytes) + return len; + { + UInt32 numAvail = p->numAvail; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + { + const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + const Byte *p2 = p1 + len; + const ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1]; + const Byte *lim = p1 + numAvail; + for (; p2 != lim && *p2 == p2[dif]; p2++) + {} + return (unsigned)(p2 - p1); + } + } + } +} + +#define MARK_LIT ((UInt32)(Int32)-1) + +#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; } +#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; } +#define IsShortRep(p) ((p)->dist == 0) + + +#define GetPrice_ShortRep(p, state, posState) \ + ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState])) + +#define GetPrice_Rep_0(p, state, posState) ( \ + GET_PRICE_1(p->isMatch[state][posState]) \ + + GET_PRICE_1(p->isRep0Long[state][posState])) \ + + GET_PRICE_1(p->isRep[state]) \ + + GET_PRICE_0(p->isRepG0[state]) + +Z7_FORCE_INLINE +static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState) +{ + UInt32 price; + UInt32 prob = p->isRepG0[state]; + if (repIndex == 0) + { + price = GET_PRICE_0(prob); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(prob); + prob = p->isRepG1[state]; + if (repIndex == 1) + price += GET_PRICE_0(prob); + else + { + price += GET_PRICE_1(prob); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + + +static unsigned Backward(CLzmaEnc *p, unsigned cur) +{ + unsigned wr = cur + 1; + p->optEnd = wr; + + for (;;) + { + UInt32 dist = p->opt[cur].dist; + unsigned len = (unsigned)p->opt[cur].len; + unsigned extra = (unsigned)p->opt[cur].extra; + cur -= len; + + if (extra) + { + wr--; + p->opt[wr].len = (UInt32)len; + cur -= extra; + len = extra; + if (extra == 1) + { + p->opt[wr].dist = dist; + dist = MARK_LIT; + } + else + { + p->opt[wr].dist = 0; + len--; + wr--; + p->opt[wr].dist = MARK_LIT; + p->opt[wr].len = 1; + } + } + + if (cur == 0) + { + p->backRes = dist; + p->optCur = wr; + return len; + } + + wr--; + p->opt[wr].dist = dist; + p->opt[wr].len = (UInt32)len; + } +} + + + +#define LIT_PROBS(pos, prevByte) \ + (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc)) + + +static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) +{ + unsigned last, cur; + UInt32 reps[LZMA_NUM_REPS]; + unsigned repLens[LZMA_NUM_REPS]; + UInt32 *matches; + + { + UInt32 numAvail; + unsigned numPairs, mainLen, repMaxIndex, i, posState; + UInt32 matchPrice, repMatchPrice; + const Byte *data; + Byte curByte, matchByte; + + p->optCur = p->optEnd = 0; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLen; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + if (numAvail < 2) + { + p->backRes = MARK_LIT; + return 1; + } + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repMaxIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization + break; + } + + if (repLens[repMaxIndex] >= p->numFastBytes) + { + unsigned len; + p->backRes = (UInt32)repMaxIndex; + len = repLens[repMaxIndex]; + MOVE_POS(p, len - 1) + return len; + } + + matches = p->matches; + #define MATCHES matches + // #define MATCHES p->matches + + if (mainLen >= p->numFastBytes) + { + p->backRes = MATCHES[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) + return mainLen; + } + + curByte = *data; + matchByte = *(data - reps[0]); + + last = repLens[repMaxIndex]; + if (last <= mainLen) + last = mainLen; + + if (last < 2 && curByte != matchByte) + { + p->backRes = MARK_LIT; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsLitState(p->state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + } + + MakeAs_Lit(&p->opt[1]) + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + // 18.06 + if (matchByte == curByte && repLens[0] == 0) + { + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAs_ShortRep(&p->opt[1]) + } + if (last < 2) + { + p->backRes = p->opt[1].dist; + return 1; + } + } + + p->opt[1].len = 1; + + p->opt[0].reps[0] = reps[0]; + p->opt[0].reps[1] = reps[1]; + p->opt[0].reps[2] = reps[2]; + p->opt[0].reps[3] = reps[3]; + + // ---------- REP ---------- + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen); + COptimal *opt = &p->opt[repLen]; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)repLen; + opt->dist = (UInt32)i; + opt->extra = 0; + } + } + while (--repLen >= 2); + } + + + // ---------- MATCH ---------- + { + unsigned len = repLens[0] + 1; + if (len <= mainLen) + { + unsigned offs = 0; + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + if (len < 2) + len = 2; + else + while (len > MATCHES[offs]) + offs += 2; + + for (; ; len++) + { + COptimal *opt; + UInt32 dist = MATCHES[(size_t)offs + 1]; + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + unsigned lenToPosState = GetLenToPosState(len); + + if (dist < kNumFullDistances) + price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)]; + else + { + unsigned slot; + GetPosSlot2(dist, slot) + price += p->alignPrices[dist & kAlignMask]; + price += p->posSlotPrices[lenToPosState][slot]; + } + + opt = &p->opt[len]; + + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + + if (len == MATCHES[offs]) + { + offs += 2; + if (offs == numPairs) + break; + } + } + } + } + + + cur = 0; + + #ifdef SHOW_STAT2 + /* if (position >= 0) */ + { + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= last; i++) + printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); + } + #endif + } + + + + // ---------- Optimal Parsing ---------- + + for (;;) + { + unsigned numAvail; + UInt32 numAvailFull; + unsigned newLen, numPairs, prev, state, posState, startLen; + UInt32 litPrice, matchPrice, repMatchPrice; + BoolInt nextIsLit; + Byte curByte, matchByte; + const Byte *data; + COptimal *curOpt, *nextOpt; + + if (++cur == last) + break; + + // 18.06 + if (cur >= kNumOpts - 64) + { + unsigned j, best; + UInt32 price = p->opt[cur].price; + best = cur; + for (j = cur + 1; j <= last; j++) + { + UInt32 price2 = p->opt[j].price; + if (price >= price2) + { + price = price2; + best = j; + } + } + { + unsigned delta = best - cur; + if (delta != 0) + { + MOVE_POS(p, delta) + } + } + cur = best; + break; + } + + newLen = ReadMatchDistances(p, &numPairs); + + if (newLen >= p->numFastBytes) + { + p->numPairs = numPairs; + p->longestMatchLen = newLen; + break; + } + + curOpt = &p->opt[cur]; + + position++; + + // we need that check here, if skip_items in p->opt are possible + /* + if (curOpt->price >= kInfinityPrice) + continue; + */ + + prev = cur - curOpt->len; + + if (curOpt->len == 1) + { + state = (unsigned)p->opt[prev].state; + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + const COptimal *prevOpt; + UInt32 b0; + UInt32 dist = curOpt->dist; + + if (curOpt->extra) + { + prev -= (unsigned)curOpt->extra; + state = kState_RepAfterLit; + if (curOpt->extra == 1) + state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit); + } + else + { + state = (unsigned)p->opt[prev].state; + if (dist < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + + prevOpt = &p->opt[prev]; + b0 = prevOpt->reps[0]; + + if (dist < LZMA_NUM_REPS) + { + if (dist == 0) + { + reps[0] = b0; + reps[1] = prevOpt->reps[1]; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; + } + else + { + reps[1] = b0; + b0 = prevOpt->reps[1]; + if (dist == 1) + { + reps[0] = b0; + reps[2] = prevOpt->reps[2]; + reps[3] = prevOpt->reps[3]; + } + else + { + reps[2] = b0; + reps[0] = prevOpt->reps[dist]; + reps[3] = prevOpt->reps[dist ^ 1]; + } + } + } + else + { + reps[0] = (dist - LZMA_NUM_REPS + 1); + reps[1] = b0; + reps[2] = prevOpt->reps[1]; + reps[3] = prevOpt->reps[2]; + } + } + + curOpt->state = (CState)state; + curOpt->reps[0] = reps[0]; + curOpt->reps[1] = reps[1]; + curOpt->reps[2] = reps[2]; + curOpt->reps[3] = reps[3]; + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + curByte = *data; + matchByte = *(data - reps[0]); + + posState = (position & p->pbMask); + + /* + The order of Price checks: + < LIT + <= SHORT_REP + < LIT : REP_0 + < REP [ : LIT : REP_0 ] + < MATCH [ : LIT : REP_0 ] + */ + + { + UInt32 curPrice = curOpt->price; + unsigned prob = p->isMatch[state][posState]; + matchPrice = curPrice + GET_PRICE_1(prob); + litPrice = curPrice + GET_PRICE_0(prob); + } + + nextOpt = &p->opt[(size_t)cur + 1]; + nextIsLit = False; + + // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice) + // 18.new.06 + if ((nextOpt->price < kInfinityPrice + // && !IsLitState(state) + && matchByte == curByte) + || litPrice > nextOpt->price + ) + litPrice = 0; + else + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + litPrice += (!IsLitState(state) ? + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, curByte, p->ProbPrices)); + + if (litPrice < nextOpt->price) + { + nextOpt->price = litPrice; + nextOpt->len = 1; + MakeAs_Lit(nextOpt) + nextIsLit = True; + } + } + + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + numAvailFull = p->numAvail; + { + unsigned temp = kNumOpts - 1 - cur; + if (numAvailFull > temp) + numAvailFull = (UInt32)temp; + } + + // 18.06 + // ---------- SHORT_REP ---------- + if (IsLitState(state)) // 18.new + if (matchByte == curByte) + if (repMatchPrice < nextOpt->price) // 18.new + // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1)) + if ( + // nextOpt->price >= kInfinityPrice || + nextOpt->len < 2 // we can check nextOpt->len, if skip items are not allowed in p->opt + || (nextOpt->dist != 0 + // && nextOpt->extra <= 1 // 17.old + ) + ) + { + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState); + // if (shortRepPrice <= nextOpt->price) // 17.old + if (shortRepPrice < nextOpt->price) // 18.new + { + nextOpt->price = shortRepPrice; + nextOpt->len = 1; + MakeAs_ShortRep(nextOpt) + nextIsLit = False; + } + } + + if (numAvailFull < 2) + continue; + numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); + + // numAvail <= p->numFastBytes + + // ---------- LIT : REP_0 ---------- + + if (!nextIsLit + && litPrice != 0 // 18.new + && matchByte != curByte + && numAvailFull > 2) + { + const Byte *data2 = data - reps[0]; + if (data[1] == data2[1] && data[2] == data2[2]) + { + unsigned len; + unsigned limit = p->numFastBytes + 1; + if (limit > numAvailFull) + limit = numAvailFull; + for (len = 3; len < limit && data[len] == data2[len]; len++) + {} + + { + unsigned state2 = kLiteralNextStates[state]; + unsigned posState2 = (position + 1) & p->pbMask; + UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2); + { + unsigned offset = cur + len; + + if (last < offset) + last = offset; + + // do + { + UInt32 price2; + COptimal *opt; + len--; + // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len); + + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len; + opt->dist = 0; + opt->extra = 1; + } + } + // while (len >= 3); + } + } + } + } + + startLen = 2; /* speed optimization */ + + { + // ---------- REP ---------- + unsigned repIndex = 0; // 17.old + // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused + for (; repIndex < LZMA_NUM_REPS; repIndex++) + { + unsigned len; + UInt32 price; + const Byte *data2 = data - reps[repIndex]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + + // if (len < startLen) continue; // 18.new: speed optimization + + { + unsigned offset = cur + len; + if (last < offset) + last = offset; + } + { + unsigned len2 = len; + price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState); + do + { + UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2); + COptimal *opt = &p->opt[cur + len2]; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->dist = (UInt32)repIndex; + opt->extra = 0; + } + } + while (--len2 >= 2); + } + + if (repIndex == 0) startLen = len + 1; // 17.old + // startLen = len + 1; // 18.new + + /* if (_maxMode) */ + { + // ---------- REP : LIT : REP_0 ---------- + // numFastBytes + 1 + numFastBytes + + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + unsigned state2 = kRepNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + price += GET_PRICE_LEN(&p->repLenEnc, posState, len) + + GET_PRICE_0(p->isMatch[state2][posState2]) + + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterRep; + posState2 = (posState2 + 1) & p->pbMask; + + + price += GetPrice_Rep_0(p, state2, posState2); + + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + // if (len2 >= 3) + { + { + unsigned offset = cur + len + len2; + + if (last < offset) + last = offset; + // do + { + UInt32 price2; + COptimal *opt; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); + + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = (UInt32)repIndex; + } + } + // while (len2 >= 3); + } + } + } + } + } + } + + + // ---------- MATCH ---------- + /* for (unsigned len = 2; len <= newLen; len++) */ + if (newLen > numAvail) + { + newLen = numAvail; + for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2); + MATCHES[numPairs] = (UInt32)newLen; + numPairs += 2; + } + + // startLen = 2; /* speed optimization */ + + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 dist; + unsigned offs, posSlot, len; + + { + unsigned offset = cur + newLen; + if (last < offset) + last = offset; + } + + offs = 0; + while (startLen > MATCHES[offs]) + offs += 2; + dist = MATCHES[(size_t)offs + 1]; + + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot) + + for (len = /*2*/ startLen; ; len++) + { + UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); + { + COptimal *opt; + unsigned lenNorm = len - 2; + lenNorm = GetLenToPosState2(lenNorm); + if (dist < kNumFullDistances) + price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)]; + else + price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask]; + + opt = &p->opt[cur + len]; + if (price < opt->price) + { + opt->price = price; + opt->len = (UInt32)len; + opt->dist = dist + LZMA_NUM_REPS; + opt->extra = 0; + } + } + + if (len == MATCHES[offs]) + { + // if (p->_maxMode) { + // MATCH : LIT : REP_0 + + const Byte *data2 = data - dist - 1; + unsigned len2 = len + 1; + unsigned limit = len2 + p->numFastBytes; + if (limit > numAvailFull) + limit = numAvailFull; + + len2 += 2; + if (len2 <= limit) + if (data[len2 - 2] == data2[len2 - 2]) + if (data[len2 - 1] == data2[len2 - 1]) + { + for (; len2 < limit && data[len2] == data2[len2]; len2++) + {} + + len2 -= len; + + // if (len2 >= 3) + { + unsigned state2 = kMatchNextStates[state]; + unsigned posState2 = (position + len) & p->pbMask; + unsigned offset; + price += GET_PRICE_0(p->isMatch[state2][posState2]); + price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]), + data[len], data2[len], p->ProbPrices); + + // state2 = kLiteralNextStates[state2]; + state2 = kState_LitAfterMatch; + + posState2 = (posState2 + 1) & p->pbMask; + price += GetPrice_Rep_0(p, state2, posState2); + + offset = cur + len + len2; + + if (last < offset) + last = offset; + // do + { + UInt32 price2; + COptimal *opt; + len2--; + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2); + price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2); + opt = &p->opt[offset]; + // offset--; + if (price2 < opt->price) + { + opt->price = price2; + opt->len = (UInt32)len2; + opt->extra = (CExtra)(len + 1); + opt->dist = dist + LZMA_NUM_REPS; + } + } + // while (len2 >= 3); + } + + } + + offs += 2; + if (offs == numPairs) + break; + dist = MATCHES[(size_t)offs + 1]; + // if (dist >= kNumFullDistances) + GetPosSlot2(dist, posSlot) + } + } + } + } + + do + p->opt[last].price = kInfinityPrice; + while (--last); + + return Backward(p, cur); +} + + + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + + + +static unsigned GetOptimumFast(CLzmaEnc *p) +{ + UInt32 numAvail, mainDist; + unsigned mainLen, numPairs, repIndex, repLen, i; + const Byte *data; + + if (p->additionalOffset == 0) + mainLen = ReadMatchDistances(p, &numPairs); + else + { + mainLen = p->longestMatchLen; + numPairs = p->numPairs; + } + + numAvail = p->numAvail; + p->backRes = MARK_LIT; + if (numAvail < 2) + return 1; + // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + repLen = repIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (len = 2; len < numAvail && data[len] == data2[len]; len++) + {} + if (len >= p->numFastBytes) + { + p->backRes = (UInt32)i; + MOVE_POS(p, len - 1) + return len; + } + if (len > repLen) + { + repIndex = i; + repLen = len; + } + } + + if (mainLen >= p->numFastBytes) + { + p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; + MOVE_POS(p, mainLen - 1) + return mainLen; + } + + mainDist = 0; /* for GCC */ + + if (mainLen >= 2) + { + mainDist = p->matches[(size_t)numPairs - 1]; + while (numPairs > 2) + { + UInt32 dist2; + if (mainLen != p->matches[(size_t)numPairs - 4] + 1) + break; + dist2 = p->matches[(size_t)numPairs - 3]; + if (!ChangePair(dist2, mainDist)) + break; + numPairs -= 2; + mainLen--; + mainDist = dist2; + } + if (mainLen == 2 && mainDist >= 0x80) + mainLen = 1; + } + + if (repLen >= 2) + if ( repLen + 1 >= mainLen + || (repLen + 2 >= mainLen && mainDist >= (1 << 9)) + || (repLen + 3 >= mainLen && mainDist >= (1 << 15))) + { + p->backRes = (UInt32)repIndex; + MOVE_POS(p, repLen - 1) + return repLen; + } + + if (mainLen < 2 || numAvail <= 2) + return 1; + + { + unsigned len1 = ReadMatchDistances(p, &p->numPairs); + p->longestMatchLen = len1; + + if (len1 >= 2) + { + UInt32 newDist = p->matches[(size_t)p->numPairs - 1]; + if ( (len1 >= mainLen && newDist < mainDist) + || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist)) + || (len1 > mainLen + 1) + || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist))) + return 1; + } + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + unsigned len, limit; + const Byte *data2 = data - p->reps[i]; + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + limit = mainLen - 1; + for (len = 2;; len++) + { + if (len >= limit) + return 1; + if (data[len] != data2[len]) + break; + } + } + + p->backRes = mainDist + LZMA_NUM_REPS; + if (mainLen != 2) + { + MOVE_POS(p, mainLen - 2) + } + return mainLen; +} + + + + +static void WriteEndMarker(CLzmaEnc *p, unsigned posState) +{ + UInt32 range; + range = p->rc.range; + { + UInt32 ttt, newBound; + CLzmaProb *prob = &p->isMatch[p->state][posState]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_1(&p->rc, prob) + prob = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, prob) + RC_BIT_0(&p->rc, prob) + } + p->state = kMatchNextStates[p->state]; + + p->rc.range = range; + LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState); + range = p->rc.range; + + { + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1); + CLzmaProb *probs = p->posSlotEncoder[0]; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m) + m = (m << 1) + 1; + } + while (m < (1 << kNumPosSlotBits)); + } + { + // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range; + unsigned numBits = 30 - kNumAlignBits; + do + { + range >>= 1; + p->rc.low += range; + RC_NORM(&p->rc) + } + while (--numBits); + } + + { + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); + CLzmaProb *probs = p->posAlignEncoder; + unsigned m = 1; + do + { + UInt32 ttt, newBound; + RC_BIT_PRE(p, probs + m) + RC_BIT_1(&p->rc, probs + m) + m = (m << 1) + 1; + } + while (m < kAlignTableSize); + } + p->rc.range = range; +} + + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + + #ifndef Z7_ST + if ( + // p->mf_Failure || + (p->mtMode && + ( // p->matchFinderMt.failure_LZ_LZ || + p->matchFinderMt.failure_LZ_BT)) + ) + { + p->result = MY_HRES_ERROR_INTERNAL_ERROR; + // printf("\nCheckErrors p->matchFinderMt.failureLZ\n"); + } + #endif + + if (MFB.result != SZ_OK) + p->result = SZ_ERROR_READ; + + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + + +Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + + +Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) +{ + unsigned i; + const CProbPrice *ProbPrices = p->ProbPrices; + const CLzmaProb *probs = p->posAlignEncoder; + // p->alignPriceCount = 0; + for (i = 0; i < kAlignTableSize / 2; i++) + { + UInt32 price = 0; + unsigned sym = i; + unsigned m = 1; + unsigned bit; + UInt32 prob; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit; + prob = probs[m]; + p->alignPrices[i ] = price + GET_PRICEa_0(prob); + p->alignPrices[i + 8] = price + GET_PRICEa_1(prob); + // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + } +} + + +Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) +{ + // int y; for (y = 0; y < 100; y++) { + + UInt32 tempPrices[kNumFullDistances]; + unsigned i, lps; + + const CProbPrice *ProbPrices = p->ProbPrices; + p->matchPriceCount = 0; + + for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++) + { + unsigned posSlot = GetPosSlot1(i); + unsigned footerBits = (posSlot >> 1) - 1; + unsigned base = ((2 | (posSlot & 1)) << footerBits); + const CLzmaProb *probs = p->posEncoders + (size_t)base * 2; + // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices); + UInt32 price = 0; + unsigned m = 1; + unsigned sym = i; + unsigned offset = (unsigned)1 << footerBits; + base += i; + + if (footerBits) + do + { + unsigned bit = sym & 1; + sym >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) + bit; + } + while (--footerBits); + + { + unsigned prob = probs[m]; + tempPrices[base ] = price + GET_PRICEa_0(prob); + tempPrices[base + offset] = price + GET_PRICEa_1(prob); + } + } + + for (lps = 0; lps < kNumLenToPosStates; lps++) + { + unsigned slot; + unsigned distTableSize2 = (p->distTableSize + 1) >> 1; + UInt32 *posSlotPrices = p->posSlotPrices[lps]; + const CLzmaProb *probs = p->posSlotEncoder[lps]; + + for (slot = 0; slot < distTableSize2; slot++) + { + // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); + UInt32 price; + unsigned bit; + unsigned sym = slot + (1 << (kNumPosSlotBits - 1)); + unsigned prob; + bit = sym & 1; sym >>= 1; price = GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit); + prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))]; + posSlotPrices[(size_t)slot * 2 ] = price + GET_PRICEa_0(prob); + posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob); + } + + { + UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++) + { + posSlotPrices[(size_t)slot * 2 ] += delta; + posSlotPrices[(size_t)slot * 2 + 1] += delta; + delta += ((UInt32)1 << kNumBitPriceShiftBits); + } + } + + { + UInt32 *dp = p->distancesPrices[lps]; + + dp[0] = posSlotPrices[0]; + dp[1] = posSlotPrices[1]; + dp[2] = posSlotPrices[2]; + dp[3] = posSlotPrices[3]; + + for (i = 4; i < kNumFullDistances; i += 2) + { + UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)]; + dp[i ] = slotPrice + tempPrices[i]; + dp[i + 1] = slotPrice + tempPrices[i + 1]; + } + } + } + // } +} + + + +static void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&MFB); + + #ifndef Z7_ST + p->matchFinderMt.MatchFinder = &MFB; + MatchFinderMt_Construct(&p->matchFinderMt); + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = NULL; + p->saveState.litProbs = NULL; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc) +{ + void *p; + p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc)); + if (p) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->litProbs); + ISzAlloc_Free(alloc, p->saveState.litProbs); + p->litProbs = NULL; + p->saveState.litProbs = NULL; +} + +static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + #ifndef Z7_ST + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + + MatchFinder_Free(&MFB, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + LzmaEnc_Destruct(p, alloc, allocBig); + ISzAlloc_Free(alloc, p); +} + + +Z7_NO_INLINE +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->needInit) + { + #ifndef Z7_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)) + } + #endif + p->matchFinder.Init(p->matchFinderObj); + p->needInit = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)) + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + unsigned numPairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numPairs); + RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]); + // p->state = kLiteralNextStates[p->state]; + curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + + for (;;) + { + UInt32 dist; + unsigned len, posState; + UInt32 range, ttt, newBound; + CLzmaProb *probs; + + if (p->fastMode) + len = GetOptimumFast(p); + else + { + unsigned oci = p->optCur; + if (p->optEnd == oci) + len = GetOptimum(p, nowPos32); + else + { + const COptimal *opt = &p->opt[oci]; + len = opt->len; + p->backRes = opt->dist; + p->optCur = oci + 1; + } + } + + posState = (unsigned)nowPos32 & p->pbMask; + range = p->rc.range; + probs = &p->isMatch[p->state][posState]; + + RC_BIT_PRE(&p->rc, probs) + + dist = p->backRes; + + #ifdef SHOW_STAT2 + printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist); + #endif + + if (dist == MARK_LIT) + { + Byte curByte; + const Byte *data; + unsigned state; + + RC_BIT_0(&p->rc, probs) + p->rc.range = range; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + probs = LIT_PROBS(nowPos32, *(data - 1)); + curByte = *data; + state = p->state; + p->state = kLiteralNextStates[state]; + if (IsLitState(state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0])); + } + else + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRep[p->state]; + RC_BIT_PRE(&p->rc, probs) + + if (dist < LZMA_NUM_REPS) + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG0[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 0) + { + RC_BIT_0(&p->rc, probs) + probs = &p->isRep0Long[p->state][posState]; + RC_BIT_PRE(&p->rc, probs) + if (len != 1) + { + RC_BIT_1_BASE(&p->rc, probs) + } + else + { + RC_BIT_0_BASE(&p->rc, probs) + p->state = kShortRepNextStates[p->state]; + } + } + else + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG1[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 1) + { + RC_BIT_0_BASE(&p->rc, probs) + dist = p->reps[1]; + } + else + { + RC_BIT_1(&p->rc, probs) + probs = &p->isRepG2[p->state]; + RC_BIT_PRE(&p->rc, probs) + if (dist == 2) + { + RC_BIT_0_BASE(&p->rc, probs) + dist = p->reps[2]; + } + else + { + RC_BIT_1_BASE(&p->rc, probs) + dist = p->reps[3]; + p->reps[3] = p->reps[2]; + } + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = dist; + } + + RC_NORM(&p->rc) + + p->rc.range = range; + + if (len != 1) + { + LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + --p->repLenEncCounter; + p->state = kRepNextStates[p->state]; + } + } + else + { + unsigned posSlot; + RC_BIT_0(&p->rc, probs) + p->rc.range = range; + p->state = kMatchNextStates[p->state]; + + LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState); + // --p->lenEnc.counter; + + dist -= LZMA_NUM_REPS; + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = dist + 1; + + p->matchPriceCount++; + GetPosSlot(dist, posSlot) + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot); + { + UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits); + range = p->rc.range; + probs = p->posSlotEncoder[GetLenToPosState(len)]; + do + { + CLzmaProb *prob = probs + (sym >> kNumPosSlotBits); + UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1; + sym <<= 1; + RC_BIT(&p->rc, prob, bit) + } + while (sym < (1 << kNumPosSlotBits * 2)); + p->rc.range = range; + } + + if (dist >= kStartPosModelIndex) + { + unsigned footerBits = ((posSlot >> 1) - 1); + + if (dist < kNumFullDistances) + { + unsigned base = ((2 | (posSlot & 1)) << footerBits); + RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */)); + } + else + { + UInt32 pos2 = (dist | 0xF) << (32 - footerBits); + range = p->rc.range; + // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + /* + do + { + range >>= 1; + p->rc.low += range & (0 - ((dist >> --footerBits) & 1)); + RC_NORM(&p->rc) + } + while (footerBits > kNumAlignBits); + */ + do + { + range >>= 1; + p->rc.low += range & (0 - (pos2 >> 31)); + pos2 += pos2; + RC_NORM(&p->rc) + } + while (pos2 != 0xF0000000); + + + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + + { + unsigned m = 1; + unsigned bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) + p->rc.range = range; + // p->alignPriceCount++; + } + } + } + } + } + + nowPos32 += (UInt32)len; + p->additionalOffset -= len; + + if (p->additionalOffset == 0) + { + UInt32 processed; + + if (!p->fastMode) + { + /* + if (p->alignPriceCount >= 16) // kAlignTableSize + FillAlignPrices(p); + if (p->matchPriceCount >= 128) + FillDistancesPrices(p); + if (p->lenEnc.counter <= 0) + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices); + */ + if (p->matchPriceCount >= 64) + { + FillAlignPrices(p); + // { int y; for (y = 0; y < 100; y++) { + FillDistancesPrices(p); + // }} + LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices); + } + if (p->repLenEncCounter <= 0) + { + p->repLenEncCounter = REP_LEN_COUNT; + LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices); + } + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + + if (maxPackSize) + { + if (processed + kNumOpts + 300 >= maxUnpackSize + || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize) + break; + } + else if (processed >= (1 << 17)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + + + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + UInt32 beforeSize = kNumOpts; + UInt32 dictSize; + + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + + #ifndef Z7_ST + p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0)); + #endif + + { + const unsigned lclp = p->lc + p->lp; + if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp); + if (!p->litProbs || !p->saveState.litProbs) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + MFB.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); + + + dictSize = p->dictSize; + if (dictSize == ((UInt32)2 << 30) || + dictSize == ((UInt32)3 << 30)) + { + /* 21.03 : here we reduce the dictionary for 2 reasons: + 1) we don't want 32-bit back_distance matches in decoder for 2 GB dictionary. + 2) we want to elimate useless last MatchFinder_Normalize3() for corner cases, + where data size is aligned for 1 GB: 5/6/8 GB. + That reducing must be >= 1 for such corner cases. */ + dictSize -= 1; + } + + if (beforeSize + dictSize < keepWindowSize) + beforeSize = keepWindowSize - dictSize; + + /* in worst case we can look ahead for + max(LZMA_MATCH_LEN_MAX, numFastBytes + 1 + numFastBytes) bytes. + we send larger value for (keepAfter) to MantchFinder_Create(): + (numFastBytes + LZMA_MATCH_LEN_MAX + 1) + */ + + #ifndef Z7_ST + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize, + p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */ + , allocBig)) + p->matchFinderObj = &p->matchFinderMt; + MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0); + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&MFB, dictSize, beforeSize, + p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 21.03 */ + , allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &MFB; + MatchFinder_CreateVTable(&MFB, &p->matchFinder); + } + + return SZ_OK; +} + +static void LzmaEnc_Init(CLzmaEnc *p) +{ + unsigned i; + p->state = 0; + p->reps[0] = + p->reps[1] = + p->reps[2] = + p->reps[3] = 1; + + RangeEnc_Init(&p->rc); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + for (i = 0; i < kNumStates; i++) + { + unsigned j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + unsigned j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for (i = 0; i < kNumFullDistances; i++) + p->posEncoders[i] = kProbInitValue; + } + + { + const size_t num = (size_t)0x300 << (p->lp + p->lc); + size_t k; + CLzmaProb *probs = p->litProbs; + for (k = 0; k < num; k++) + probs[k] = kProbInitValue; + } + + + LenEnc_Init(&p->lenProbs); + LenEnc_Init(&p->repLenProbs); + + p->optEnd = 0; + p->optCur = 0; + + { + for (i = 0; i < kNumOpts; i++) + p->opt[i].price = kInfinityPrice; + } + + p->additionalOffset = 0; + + p->pbMask = ((unsigned)1 << p->pb) - 1; + p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc); + + // p->mf_Failure = False; +} + + +static void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + + p->repLenEncCounter = REP_LEN_COUNT; + + LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + unsigned i; + for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + p->nowPos64 = 0; + p->needInit = 1; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle p, + ISeqOutStreamPtr outStream, + ISeqInStreamPtr inStream, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, + ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, + const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen) + LzmaEnc_SetDataSize(p, srcLen); + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle p) +{ + #ifndef Z7_ST + // GET_CLzmaEnc_p + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + UNUSED_VAR(p) + #endif +} + + +typedef struct +{ + ISeqOutStream vt; + Byte *data; + size_t rem; + BoolInt overflow; +} CLzmaEnc_SeqOutStreamBuf; + +static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf) + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + if (size != 0) + { + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + } + return size; +} + + +/* +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p) +{ + GET_const_CLzmaEnc_p + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} +*/ + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p) +{ + // GET_const_CLzmaEnc_p + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + + +// (desiredPackSize == 0) is not allowed +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + // GET_CLzmaEnc_p + UInt64 nowPos64; + SRes res; + CLzmaEnc_SeqOutStreamBuf outStream; + + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.vt; + nowPos64 = p->nowPos64; + + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + + +Z7_NO_INLINE +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress) +{ + SRes res = SZ_OK; + + #ifndef Z7_ST + Byte allocaDummy[0x300]; + allocaDummy[0] = 0; + allocaDummy[1] = allocaDummy[0]; + #endif + + for (;;) + { + res = LzmaEnc_CodeOneBlock(p, 0, 0); + if (res != SZ_OK || p->finished) + break; + if (progress) + { + res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + + LzmaEnc_Finish((CLzmaEncHandle)(void *)p); + + /* + if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB)) + res = SZ_ERROR_FAIL; + } + */ + + return res; +} + + +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress, + ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + // GET_CLzmaEnc_p + RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig)) + return LzmaEnc_Encode2(p, progress); +} + + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size) +{ + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + { + // GET_CLzmaEnc_p + const UInt32 dictSize = p->dictSize; + UInt32 v; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + // we write aligned dictionary value to properties for lzma decoder + if (dictSize >= ((UInt32)1 << 21)) + { + const UInt32 kDictMask = ((UInt32)1 << 20) - 1; + v = (dictSize + kDictMask) & ~kDictMask; + if (v < dictSize) + v = dictSize; + } + else + { + unsigned i = 11 * 2; + do + { + v = (UInt32)(2 + (i & 1)) << (i >> 1); + i++; + } + while (v < dictSize); + } + + SetUi32(props + 1, v) + return SZ_OK; + } +} + + +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p) +{ + // GET_CLzmaEnc_p + return (unsigned)p->writeEndMark; +} + + +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + SRes res; + // GET_CLzmaEnc_p + + CLzmaEnc_SeqOutStreamBuf outStream; + + outStream.vt.Write = SeqOutStreamBuf_Write; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + p->rc.outStream = &outStream.vt; + + res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig); + + if (res == SZ_OK) + { + res = LzmaEnc_Encode2(p, progress); + if (res == SZ_OK && p->nowPos64 != srcLen) + res = SZ_ERROR_FAIL; + } + + *destLen -= (SizeT)outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzmaEncHandle p = LzmaEnc_Create(alloc); + SRes res; + if (!p) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} + + +/* +#ifndef Z7_ST +void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2]) +{ + GET_const_CLzmaEnc_p + lz_threads[0] = p->matchFinderMt.hashSync.thread; + lz_threads[1] = p->matchFinderMt.btSync.thread; +} +#endif +*/ diff -Nru p7zip-rar-16.02/C/LzmaEnc.h p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.h --- p7zip-rar-16.02/C/LzmaEnc.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaEnc.h 2025-05-10 07:00:00.000000000 +0000 @@ -1,78 +1,85 @@ -/* LzmaEnc.h -- LZMA Encoder -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define LZMA_PROPS_SIZE 5 - -typedef struct _CLzmaEncProps -{ - int level; /* 0 <= level <= 9 */ - UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version - (1 << 12) <= dictSize <= (1 << 30) for 64-bit version - default = (1 << 24) */ - UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. - Encoder uses this value to reduce dictionary size */ - int lc; /* 0 <= lc <= 8, default = 3 */ - int lp; /* 0 <= lp <= 4, default = 0 */ - int pb; /* 0 <= pb <= 4, default = 2 */ - int algo; /* 0 - fast, 1 - normal, default = 1 */ - int fb; /* 5 <= fb <= 273, default = 32 */ - int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ - int numHashBytes; /* 2, 3 or 4, default = 4 */ - UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ - unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ - int numThreads; /* 1 or 2, default = 2 */ -} CLzmaEncProps; - -void LzmaEncProps_Init(CLzmaEncProps *p); -void LzmaEncProps_Normalize(CLzmaEncProps *p); -UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); - - -/* ---------- CLzmaEncHandle Interface ---------- */ - -/* LzmaEnc_* functions can return the following exit codes: -Returns: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater in props - SZ_ERROR_WRITE - Write callback error. - SZ_ERROR_PROGRESS - some break from progress callback - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -typedef void * CLzmaEncHandle; - -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - -/* ---------- One Call Interface ---------- */ - -/* LzmaEncode -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - -EXTERN_C_END - -#endif +/* LzmaEnc.h -- LZMA Encoder +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA_ENC_H +#define ZIP7_INC_LZMA_ENC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define LZMA_PROPS_SIZE 5 + +typedef struct +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (3 << 29) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + unsigned numHashOutBits; /* default = ? */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ + + // int _pad; + Int32 affinityGroup; + + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. + Encoder uses this value to reduce dictionary size */ + + UInt64 affinity; + UInt64 affinityInGroup; +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc* functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef struct CLzmaEnc CLzmaEnc; +typedef CLzmaEnc * CLzmaEncHandle; +// Z7_DECLARE_HANDLE(CLzmaEncHandle) + +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); + +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); + +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + + +/* ---------- One Call Interface ---------- */ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/LzmaLib.c p7zip-rar-16.02+really25.00+ds/C/LzmaLib.c --- p7zip-rar-16.02/C/LzmaLib.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaLib.c 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,42 @@ +/* LzmaLib.c -- LZMA library wrapper +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Alloc.h" +#include "LzmaDec.h" +#include "LzmaEnc.h" +#include "LzmaLib.h" + +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ +) +{ + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + props.lc = lc; + props.lp = lp; + props.pb = pb; + props.fb = fb; + props.numThreads = numThreads; + + return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); +} + + +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, + const unsigned char *props, size_t propsSize) +{ + ELzmaStatus status; + return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); +} diff -Nru p7zip-rar-16.02/C/LzmaLib.h p7zip-rar-16.02+really25.00+ds/C/LzmaLib.h --- p7zip-rar-16.02/C/LzmaLib.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/LzmaLib.h 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,138 @@ +/* LzmaLib.h -- LZMA library interface +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA_LIB_H +#define ZIP7_INC_LZMA_LIB_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define Z7_STDAPI int Z7_STDCALL + +#define LZMA_PROPS_SIZE 5 + +/* +RAM requirements for LZMA: + for compression: (dictSize * 11.5 + 6 MB) + state_size + for decompression: dictSize + state_size + state_size = (4 + (1.5 << (lc + lp))) KB + by default (lc=3, lp=0), state_size = 16 KB. + +LZMA properties (5 bytes) format + Offset Size Description + 0 1 lc, lp and pb in encoded form. + 1 4 dictSize (little endian). +*/ + +/* +LzmaCompress +------------ + +outPropsSize - + In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + + LZMA Encoder will use defult values for any parameter, if it is + -1 for any from: level, loc, lp, pb, fb, numThreads + 0 for dictSize + +level - compression level: 0 <= level <= 9; + + level dictSize algo fb + 0: 64 KB 0 32 + 1: 256 KB 0 32 + 2: 1 MB 0 32 + 3: 4 MB 0 32 + 4: 16 MB 0 32 + 5: 16 MB 1 32 + 6: 32 MB 1 32 + 7: 32 MB 1 64 + 8: 64 MB 1 64 + 9: 64 MB 1 64 + + The default value for "level" is 5. + + algo = 0 means fast method + algo = 1 means normal method + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + +lc - The number of literal context bits (high bits of previous literal). + It can be in the range from 0 to 8. The default value is 3. + Sometimes lc=4 gives the gain for big files. + +lp - The number of literal pos bits (low bits of current position for literals). + It can be in the range from 0 to 4. The default value is 0. + The lp switch is intended for periodical data when the period is equal to 2^lp. + For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's + better to set lc=0, if you change lp switch. + +pb - The number of pos bits (low bits of current position). + It can be in the range from 0 to 4. The default value is 2. + The pb switch is intended for periodical data when the period is equal 2^pb. + +fb - Word size (the number of fast bytes). + It can be in the range from 5 to 273. The default value is 32. + Usually, a big number gives a little bit better compression ratio and + slower compression process. + +numThreads - The number of thereads. 1 or 2. The default value is 2. + Fast mode (algo = 0) can use only 1 thread. + +In: + dest - output data buffer + destLen - output data buffer size + src - input data + srcLen - input data size +Out: + destLen - processed output size +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* default = (1 << 24) */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ + ); + +/* +LzmaUncompress +-------------- +In: + dest - output data buffer + destLen - output data buffer size + src - input data + srcLen - input data size +Out: + destLen - processed output size + srcLen - processed input size +Returns: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation arror + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) +*/ + +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, + const unsigned char *props, size_t propsSize); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Md5.c p7zip-rar-16.02+really25.00+ds/C/Md5.c --- p7zip-rar-16.02/C/Md5.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Md5.c 2024-11-26 09:00:00.000000000 +0000 @@ -0,0 +1,206 @@ +/* Md5.c -- MD5 Hash +: Igor Pavlov : Public domain +This code is based on Colin Plumb's public domain md5.c code */ + +#include "Precomp.h" + +#include + +#include "Md5.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#define MD5_UPDATE_BLOCKS(p) Md5_UpdateBlocks + +Z7_NO_INLINE +void Md5_Init(CMd5 *p) +{ + p->count = 0; + p->state[0] = 0x67452301; + p->state[1] = 0xefcdab89; + p->state[2] = 0x98badcfe; + p->state[3] = 0x10325476; +} + +#if 0 && !defined(MY_CPU_LE_UNALIGN) +// optional optimization for Big-endian processors or processors without unaligned access: +// it is intended to reduce the number of complex LE32 memory reading from 64 to 16. +// But some compilers (sparc, armt) are better without this optimization. +#define Z7_MD5_USE_DATA32_ARRAY +#endif + +#define LOAD_DATA(i) GetUi32((const UInt32 *)(const void *)data + (i)) + +#ifdef Z7_MD5_USE_DATA32_ARRAY +#define D(i) data32[i] +#else +#define D(i) LOAD_DATA(i) +#endif + +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define R1(i, f, start, step, w, x, y, z, s, k) \ + w += D((start + step * (i)) % 16) + k; \ + w += f(x, y, z); \ + w = rotlFixed(w, s) + x; \ + +#define R4(i4, f, start, step, s0,s1,s2,s3, k0,k1,k2,k3) \ + R1 (i4*4+0, f, start, step, a,b,c,d, s0, k0) \ + R1 (i4*4+1, f, start, step, d,a,b,c, s1, k1) \ + R1 (i4*4+2, f, start, step, c,d,a,b, s2, k2) \ + R1 (i4*4+3, f, start, step, b,c,d,a, s3, k3) \ + +#define R16(f, start, step, s0,s1,s2,s3, k00,k01,k02,k03, k10,k11,k12,k13, k20,k21,k22,k23, k30,k31,k32,k33) \ + R4 (0, f, start, step, s0,s1,s2,s3, k00,k01,k02,k03) \ + R4 (1, f, start, step, s0,s1,s2,s3, k10,k11,k12,k13) \ + R4 (2, f, start, step, s0,s1,s2,s3, k20,k21,k22,k23) \ + R4 (3, f, start, step, s0,s1,s2,s3, k30,k31,k32,k33) \ + +static +Z7_NO_INLINE +void Z7_FASTCALL Md5_UpdateBlocks(UInt32 state[4], const Byte *data, size_t numBlocks) +{ + UInt32 a, b, c, d; + // if (numBlocks == 0) return; + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + do + { +#ifdef Z7_MD5_USE_DATA32_ARRAY + UInt32 data32[MD5_NUM_BLOCK_WORDS]; + { +#define LOAD_data32_x4(i) { \ + data32[i ] = LOAD_DATA(i ); \ + data32[i + 1] = LOAD_DATA(i + 1); \ + data32[i + 2] = LOAD_DATA(i + 2); \ + data32[i + 3] = LOAD_DATA(i + 3); } +#if 1 + LOAD_data32_x4 (0 * 4) + LOAD_data32_x4 (1 * 4) + LOAD_data32_x4 (2 * 4) + LOAD_data32_x4 (3 * 4) +#else + unsigned i; + for (i = 0; i < MD5_NUM_BLOCK_WORDS; i += 4) + { + LOAD_data32_x4(i) + } +#endif + } +#endif + + R16 (F1, 0, 1, 7,12,17,22, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821) + R16 (F2, 1, 5, 5, 9,14,20, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a) + R16 (F3, 5, 3, 4,11,16,23, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665) + R16 (F4, 0, 7, 6,10,15,21, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391) + + a += state[0]; + b += state[1]; + c += state[2]; + d += state[3]; + + state[0] = a; + state[1] = b; + state[2] = c; + state[3] = d; + + data += MD5_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Md5_UpdateBlock(p) MD5_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Md5_Update(CMd5 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1); + const unsigned num = MD5_BLOCK_SIZE - pos; + p->count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Md5_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 6; + if (numBlocks) + MD5_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= MD5_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 6); + memcpy(p->buffer, data, size); + } +} + + +void Md5_Final(CMd5 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->count & (MD5_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (MD5_BLOCK_SIZE - 4 * 2)) + { + while (pos != MD5_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, MD5_BLOCK_SIZE - pos); + Md5_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (MD5_BLOCK_SIZE - 4 * 2) - pos); + { + const UInt64 numBits = p->count << 3; +#if defined(MY_CPU_LE_UNALIGN) + SetUi64 (p->buffer + MD5_BLOCK_SIZE - 4 * 2, numBits) +#else + SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 2, (UInt32)(numBits)) + SetUi32a(p->buffer + MD5_BLOCK_SIZE - 4 * 1, (UInt32)(numBits >> 32)) +#endif + } + Md5_UpdateBlock(p); + + SetUi32(digest, p->state[0]) + SetUi32(digest + 4, p->state[1]) + SetUi32(digest + 8, p->state[2]) + SetUi32(digest + 12, p->state[3]) + + Md5_Init(p); +} + +#undef R1 +#undef R4 +#undef R16 +#undef D +#undef LOAD_DATA +#undef LOAD_data32_x4 +#undef F1 +#undef F2 +#undef F3 +#undef F4 diff -Nru p7zip-rar-16.02/C/Md5.h p7zip-rar-16.02+really25.00+ds/C/Md5.h --- p7zip-rar-16.02/C/Md5.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Md5.h 2024-11-26 09:00:00.000000000 +0000 @@ -0,0 +1,34 @@ +/* Md5.h -- MD5 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MD5_H +#define ZIP7_INC_MD5_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define MD5_NUM_BLOCK_WORDS 16 +#define MD5_NUM_DIGEST_WORDS 4 + +#define MD5_BLOCK_SIZE (MD5_NUM_BLOCK_WORDS * 4) +#define MD5_DIGEST_SIZE (MD5_NUM_DIGEST_WORDS * 4) + +typedef struct +{ + UInt64 count; + UInt64 _pad_1; + // we want 16-bytes alignment here + UInt32 state[MD5_NUM_DIGEST_WORDS]; + UInt64 _pad_2[4]; + // we want 64-bytes alignment here + Byte buffer[MD5_BLOCK_SIZE]; +} CMd5; + +void Md5_Init(CMd5 *p); +void Md5_Update(CMd5 *p, const Byte *data, size_t size); +void Md5_Final(CMd5 *p, Byte *digest); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/MtCoder.c p7zip-rar-16.02+really25.00+ds/C/MtCoder.c --- p7zip-rar-16.02/C/MtCoder.c 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/MtCoder.c 2025-07-04 06:00:00.000000000 +0000 @@ -1,327 +1,604 @@ -/* MtCoder.c -- Multi-thread Coder -2015-10-13 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "MtCoder.h" - -void LoopThread_Construct(CLoopThread *p) -{ - Thread_Construct(&p->thread); - Event_Construct(&p->startEvent); - Event_Construct(&p->finishedEvent); -} - -void LoopThread_Close(CLoopThread *p) -{ - Thread_Close(&p->thread); - Event_Close(&p->startEvent); - Event_Close(&p->finishedEvent); -} - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp) -{ - CLoopThread *p = (CLoopThread *)pp; - for (;;) - { - if (Event_Wait(&p->startEvent) != 0) - return SZ_ERROR_THREAD; - if (p->stop) - return 0; - p->res = p->func(p->param); - if (Event_Set(&p->finishedEvent) != 0) - return SZ_ERROR_THREAD; - } -} - -WRes LoopThread_Create(CLoopThread *p) -{ - p->stop = 0; - RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent)); - RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent)); - return Thread_Create(&p->thread, LoopThreadFunc, p); -} - -WRes LoopThread_StopAndWait(CLoopThread *p) -{ - p->stop = 1; - if (Event_Set(&p->startEvent) != 0) - return SZ_ERROR_THREAD; - return Thread_Wait(&p->thread); -} - -WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); } -WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); } - -static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) -{ - return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; -} - -static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress) -{ - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - p->inSizes[i] = p->outSizes[i] = 0; - p->totalInSize = p->totalOutSize = 0; - p->progress = progress; - p->res = SZ_OK; -} - -static void MtProgress_Reinit(CMtProgress *p, unsigned index) -{ - p->inSizes[index] = 0; - p->outSizes[index] = 0; -} - -#define UPDATE_PROGRESS(size, prev, total) \ - if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; } - -SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize) -{ - SRes res; - CriticalSection_Enter(&p->cs); - UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize) - UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize) - if (p->res == SZ_OK) - p->res = Progress(p->progress, p->totalInSize, p->totalOutSize); - res = p->res; - CriticalSection_Leave(&p->cs); - return res; -} - -static void MtProgress_SetError(CMtProgress *p, SRes res) -{ - CriticalSection_Enter(&p->cs); - if (p->res == SZ_OK) - p->res = res; - CriticalSection_Leave(&p->cs); -} - -static void MtCoder_SetError(CMtCoder* p, SRes res) -{ - CriticalSection_Enter(&p->cs); - if (p->res == SZ_OK) - p->res = res; - CriticalSection_Leave(&p->cs); -} - -/* ---------- MtThread ---------- */ - -void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder) -{ - p->mtCoder = mtCoder; - p->outBuf = 0; - p->inBuf = 0; - Event_Construct(&p->canRead); - Event_Construct(&p->canWrite); - LoopThread_Construct(&p->thread); -} - -#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } - -static void CMtThread_CloseEvents(CMtThread *p) -{ - Event_Close(&p->canRead); - Event_Close(&p->canWrite); -} - -static void CMtThread_Destruct(CMtThread *p) -{ - CMtThread_CloseEvents(p); - - if (Thread_WasCreated(&p->thread.thread)) - { - LoopThread_StopAndWait(&p->thread); - LoopThread_Close(&p->thread); - } - - if (p->mtCoder->alloc) - IAlloc_Free(p->mtCoder->alloc, p->outBuf); - p->outBuf = 0; - - if (p->mtCoder->alloc) - IAlloc_Free(p->mtCoder->alloc, p->inBuf); - p->inBuf = 0; -} - -#define MY_BUF_ALLOC(buf, size, newSize) \ - if (buf == 0 || size != newSize) \ - { IAlloc_Free(p->mtCoder->alloc, buf); \ - size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \ - if (buf == 0) return SZ_ERROR_MEM; } - -static SRes CMtThread_Prepare(CMtThread *p) -{ - MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize) - MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize) - - p->stopReading = False; - p->stopWriting = False; - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite)); - - return SZ_OK; -} - -static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize) -{ - size_t size = *processedSize; - *processedSize = 0; - while (size != 0) - { - size_t curSize = size; - SRes res = stream->Read(stream, data, &curSize); - *processedSize += curSize; - data += curSize; - size -= curSize; - RINOK(res); - if (curSize == 0) - return SZ_OK; - } - return SZ_OK; -} - -#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads - 1 ? 0 : p->index + 1] - -static SRes MtThread_Process(CMtThread *p, Bool *stop) -{ - CMtThread *next; - *stop = True; - if (Event_Wait(&p->canRead) != 0) - return SZ_ERROR_THREAD; - - next = GET_NEXT_THREAD(p); - - if (p->stopReading) - { - next->stopReading = True; - return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD; - } - - { - size_t size = p->mtCoder->blockSize; - size_t destSize = p->outBufSize; - - RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size)); - next->stopReading = *stop = (size != p->mtCoder->blockSize); - if (Event_Set(&next->canRead) != 0) - return SZ_ERROR_THREAD; - - RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index, - p->outBuf, &destSize, p->inBuf, size, *stop)); - - MtProgress_Reinit(&p->mtCoder->mtProgress, p->index); - - if (Event_Wait(&p->canWrite) != 0) - return SZ_ERROR_THREAD; - if (p->stopWriting) - return SZ_ERROR_FAIL; - if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize) - return SZ_ERROR_WRITE; - return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD; - } -} - -static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp) -{ - CMtThread *p = (CMtThread *)pp; - for (;;) - { - Bool stop; - CMtThread *next = GET_NEXT_THREAD(p); - SRes res = MtThread_Process(p, &stop); - if (res != SZ_OK) - { - MtCoder_SetError(p->mtCoder, res); - MtProgress_SetError(&p->mtCoder->mtProgress, res); - next->stopReading = True; - next->stopWriting = True; - Event_Set(&next->canRead); - Event_Set(&next->canWrite); - return res; - } - if (stop) - return 0; - } -} - -void MtCoder_Construct(CMtCoder* p) -{ - unsigned i; - p->alloc = 0; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - { - CMtThread *t = &p->threads[i]; - t->index = i; - CMtThread_Construct(t, p); - } - CriticalSection_Init(&p->cs); - CriticalSection_Init(&p->mtProgress.cs); -} - -void MtCoder_Destruct(CMtCoder* p) -{ - unsigned i; - for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) - CMtThread_Destruct(&p->threads[i]); - CriticalSection_Delete(&p->cs); - CriticalSection_Delete(&p->mtProgress.cs); -} - -SRes MtCoder_Code(CMtCoder *p) -{ - unsigned i, numThreads = p->numThreads; - SRes res = SZ_OK; - p->res = SZ_OK; - - MtProgress_Init(&p->mtProgress, p->progress); - - for (i = 0; i < numThreads; i++) - { - RINOK(CMtThread_Prepare(&p->threads[i])); - } - - for (i = 0; i < numThreads; i++) - { - CMtThread *t = &p->threads[i]; - CLoopThread *lt = &t->thread; - - if (!Thread_WasCreated(<->thread)) - { - lt->func = ThreadFunc; - lt->param = t; - - if (LoopThread_Create(lt) != SZ_OK) - { - res = SZ_ERROR_THREAD; - break; - } - } - } - - if (res == SZ_OK) - { - unsigned j; - for (i = 0; i < numThreads; i++) - { - CMtThread *t = &p->threads[i]; - if (LoopThread_StartSubThread(&t->thread) != SZ_OK) - { - res = SZ_ERROR_THREAD; - p->threads[0].stopReading = True; - break; - } - } - - Event_Set(&p->threads[0].canWrite); - Event_Set(&p->threads[0].canRead); - - for (j = 0; j < i; j++) - LoopThread_WaitSubThread(&p->threads[j].thread); - } - - for (i = 0; i < numThreads; i++) - CMtThread_CloseEvents(&p->threads[i]); - return (res == SZ_OK) ? p->res : res; -} +/* MtCoder.c -- Multi-thread Coder +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "MtCoder.h" + +#ifndef Z7_ST + +static SRes MtProgressThunk_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CMtProgressThunk) + UInt64 inSize2 = 0; + UInt64 outSize2 = 0; + if (inSize != (UInt64)(Int64)-1) + { + inSize2 = inSize - p->inSize; + p->inSize = inSize; + } + if (outSize != (UInt64)(Int64)-1) + { + outSize2 = outSize - p->outSize; + p->outSize = outSize; + } + return MtProgress_ProgressAdd(p->mtProgress, inSize2, outSize2); +} + + +void MtProgressThunk_CreateVTable(CMtProgressThunk *p) +{ + p->vt.Progress = MtProgressThunk_Progress; +} + + + +#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } + + +static THREAD_FUNC_DECL ThreadFunc(void *pp); + + +static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t +#ifdef _WIN32 + , CMtCoder * const mtc +#endif + ) +{ + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->startEvent); + // printf("\n====== MtCoderThread_CreateAndStart : \n"); + if (wres == 0) + { + t->stop = False; + if (!Thread_WasCreated(&t->thread)) + { +#ifdef _WIN32 + if (mtc->numThreadGroups) + wres = Thread_Create_With_Group(&t->thread, ThreadFunc, t, + ThreadNextGroup_GetNext(&mtc->nextGroup), // group + 0); // affinityMask + else +#endif + wres = Thread_Create(&t->thread, ThreadFunc, t); + } + if (wres == 0) + wres = Event_Set(&t->startEvent); + } + if (wres == 0) + return SZ_OK; + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +Z7_FORCE_INLINE +static void MtCoderThread_Destruct(CMtCoderThread *t) +{ + if (Thread_WasCreated(&t->thread)) + { + t->stop = 1; + Event_Set(&t->startEvent); + Thread_Wait_Close(&t->thread); + } + + Event_Close(&t->startEvent); + + if (t->inBuf) + { + ISzAlloc_Free(t->mtCoder->allocBig, t->inBuf); + t->inBuf = NULL; + } +} + + + + +/* + ThreadFunc2() returns: + SZ_OK - in all normal cases (even for stream error or memory allocation error) + SZ_ERROR_THREAD - in case of failure in system synch function +*/ + +static SRes ThreadFunc2(CMtCoderThread *t) +{ + CMtCoder * const mtc = t->mtCoder; + + for (;;) + { + unsigned bi; + SRes res; + SRes res2; + BoolInt finished; + unsigned bufIndex; + size_t size; + const Byte *inData; + UInt64 readProcessed = 0; + + RINOK_THREAD(Event_Wait(&mtc->readEvent)) + + /* after Event_Wait(&mtc->readEvent) we must call Event_Set(&mtc->readEvent) in any case to unlock another threads */ + + if (mtc->stopReading) + { + return Event_Set(&mtc->readEvent) == 0 ? SZ_OK : SZ_ERROR_THREAD; + } + + res = MtProgress_GetError(&mtc->mtProgress); + + size = 0; + inData = NULL; + finished = True; + + if (res == SZ_OK) + { + size = mtc->blockSize; + if (mtc->inStream) + { + if (!t->inBuf) + { + t->inBuf = (Byte *)ISzAlloc_Alloc(mtc->allocBig, mtc->blockSize); + if (!t->inBuf) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SeqInStream_ReadMax(mtc->inStream, t->inBuf, &size); + readProcessed = mtc->readProcessed + size; + mtc->readProcessed = readProcessed; + } + if (res != SZ_OK) + { + mtc->readRes = res; + /* after reading error - we can stop encoding of previous blocks */ + MtProgress_SetError(&mtc->mtProgress, res); + } + else + finished = (size != mtc->blockSize); + } + else + { + size_t rem; + readProcessed = mtc->readProcessed; + rem = mtc->inDataSize - (size_t)readProcessed; + if (size > rem) + size = rem; + inData = mtc->inData + (size_t)readProcessed; + readProcessed += size; + mtc->readProcessed = readProcessed; + finished = (mtc->inDataSize == (size_t)readProcessed); + } + } + + /* we must get some block from blocksSemaphore before Event_Set(&mtc->readEvent) */ + + res2 = SZ_OK; + + if (Semaphore_Wait(&mtc->blocksSemaphore) != 0) + { + res2 = SZ_ERROR_THREAD; + if (res == SZ_OK) + { + res = res2; + // MtProgress_SetError(&mtc->mtProgress, res); + } + } + + bi = mtc->blockIndex; + + if (++mtc->blockIndex >= mtc->numBlocksMax) + mtc->blockIndex = 0; + + bufIndex = (unsigned)(int)-1; + + if (res == SZ_OK) + res = MtProgress_GetError(&mtc->mtProgress); + + if (res != SZ_OK) + finished = True; + + if (!finished) + { + if (mtc->numStartedThreads < mtc->numStartedThreadsLimit + && mtc->expectedDataSize != readProcessed) + { + res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads] +#ifdef _WIN32 + , mtc +#endif + ); + if (res == SZ_OK) + mtc->numStartedThreads++; + else + { + MtProgress_SetError(&mtc->mtProgress, res); + finished = True; + } + } + } + + if (finished) + mtc->stopReading = True; + + RINOK_THREAD(Event_Set(&mtc->readEvent)) + + if (res2 != SZ_OK) + return res2; + + if (res == SZ_OK) + { + CriticalSection_Enter(&mtc->cs); + bufIndex = mtc->freeBlockHead; + mtc->freeBlockHead = mtc->freeBlockList[bufIndex]; + CriticalSection_Leave(&mtc->cs); + + res = mtc->mtCallback->Code(mtc->mtCallbackObject, t->index, bufIndex, + mtc->inStream ? t->inBuf : inData, size, finished); + + // MtProgress_Reinit(&mtc->mtProgress, t->index); + + if (res != SZ_OK) + MtProgress_SetError(&mtc->mtProgress, res); + } + + { + CMtCoderBlock * const block = &mtc->blocks[bi]; + block->res = res; + block->bufIndex = bufIndex; + block->finished = finished; + } + + #ifdef MTCODER_USE_WRITE_THREAD + RINOK_THREAD(Event_Set(&mtc->writeEvents[bi])) + #else + { + unsigned wi; + { + CriticalSection_Enter(&mtc->cs); + wi = mtc->writeIndex; + if (wi == bi) + mtc->writeIndex = (unsigned)(int)-1; + else + mtc->ReadyBlocks[bi] = True; + CriticalSection_Leave(&mtc->cs); + } + + if (wi != bi) + { + if (res != SZ_OK || finished) + return 0; + continue; + } + + if (mtc->writeRes != SZ_OK) + res = mtc->writeRes; + + for (;;) + { + if (res == SZ_OK && bufIndex != (unsigned)(int)-1) + { + res = mtc->mtCallback->Write(mtc->mtCallbackObject, bufIndex); + if (res != SZ_OK) + { + mtc->writeRes = res; + MtProgress_SetError(&mtc->mtProgress, res); + } + } + + if (++wi >= mtc->numBlocksMax) + wi = 0; + { + BoolInt isReady; + + CriticalSection_Enter(&mtc->cs); + + if (bufIndex != (unsigned)(int)-1) + { + mtc->freeBlockList[bufIndex] = mtc->freeBlockHead; + mtc->freeBlockHead = bufIndex; + } + + isReady = mtc->ReadyBlocks[wi]; + + if (isReady) + mtc->ReadyBlocks[wi] = False; + else + mtc->writeIndex = wi; + + CriticalSection_Leave(&mtc->cs); + + RINOK_THREAD(Semaphore_Release1(&mtc->blocksSemaphore)) + + if (!isReady) + break; + } + + { + CMtCoderBlock *block = &mtc->blocks[wi]; + if (res == SZ_OK && block->res != SZ_OK) + res = block->res; + bufIndex = block->bufIndex; + finished = block->finished; + } + } + } + #endif + + if (finished || res != SZ_OK) + return 0; + } +} + + +static THREAD_FUNC_DECL ThreadFunc(void *pp) +{ + CMtCoderThread * const t = (CMtCoderThread *)pp; + for (;;) + { + if (Event_Wait(&t->startEvent) != 0) + return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; + if (t->stop) + return 0; + { + const SRes res = ThreadFunc2(t); + CMtCoder *mtc = t->mtCoder; + if (res != SZ_OK) + { + MtProgress_SetError(&mtc->mtProgress, res); + } + + #ifndef MTCODER_USE_WRITE_THREAD + { + const unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); + if (numFinished == mtc->numStartedThreads) + if (Event_Set(&mtc->finishedEvent) != 0) + return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; + } + #endif + } + } +} + + + +void MtCoder_Construct(CMtCoder *p) +{ + unsigned i; + + p->blockSize = 0; + p->numThreadsMax = 0; + p->numThreadGroups = 0; + p->expectedDataSize = (UInt64)(Int64)-1; + + p->inStream = NULL; + p->inData = NULL; + p->inDataSize = 0; + + p->progress = NULL; + p->allocBig = NULL; + + p->mtCallback = NULL; + p->mtCallbackObject = NULL; + + p->allocatedBufsSize = 0; + + Event_Construct(&p->readEvent); + Semaphore_Construct(&p->blocksSemaphore); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CMtCoderThread *t = &p->threads[i]; + t->mtCoder = p; + t->index = i; + t->inBuf = NULL; + t->stop = False; + Event_Construct(&t->startEvent); + Thread_CONSTRUCT(&t->thread) + } + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + Event_Construct(&p->writeEvents[i]); + #else + Event_Construct(&p->finishedEvent); + #endif + + CriticalSection_Init(&p->cs); + CriticalSection_Init(&p->mtProgress.cs); +} + + + + +static void MtCoder_Free(CMtCoder *p) +{ + unsigned i; + + /* + p->stopReading = True; + if (Event_IsCreated(&p->readEvent)) + Event_Set(&p->readEvent); + */ + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + MtCoderThread_Destruct(&p->threads[i]); + + Event_Close(&p->readEvent); + Semaphore_Close(&p->blocksSemaphore); + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + Event_Close(&p->writeEvents[i]); + #else + Event_Close(&p->finishedEvent); + #endif +} + + +void MtCoder_Destruct(CMtCoder *p) +{ + MtCoder_Free(p); + + CriticalSection_Delete(&p->cs); + CriticalSection_Delete(&p->mtProgress.cs); +} + + +SRes MtCoder_Code(CMtCoder *p) +{ + unsigned numThreads = p->numThreadsMax; + unsigned numBlocksMax; + unsigned i; + SRes res = SZ_OK; + + // printf("\n====== MtCoder_Code : \n"); + + if (numThreads > MTCODER_THREADS_MAX) + numThreads = MTCODER_THREADS_MAX; + numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads); + + if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++; + if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++; + if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++; + + if (numBlocksMax > MTCODER_BLOCKS_MAX) + numBlocksMax = MTCODER_BLOCKS_MAX; + + if (p->blockSize != p->allocatedBufsSize) + { + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CMtCoderThread *t = &p->threads[i]; + if (t->inBuf) + { + ISzAlloc_Free(p->allocBig, t->inBuf); + t->inBuf = NULL; + } + } + p->allocatedBufsSize = p->blockSize; + } + + p->readRes = SZ_OK; + + MtProgress_Init(&p->mtProgress, p->progress); + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < numBlocksMax; i++) + { + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->writeEvents[i])) + } + #else + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) + #endif + + { + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->readEvent)) + RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, (UInt32)numBlocksMax, (UInt32)numBlocksMax)) + } + + for (i = 0; i < MTCODER_BLOCKS_MAX - 1; i++) + p->freeBlockList[i] = i + 1; + p->freeBlockList[MTCODER_BLOCKS_MAX - 1] = (unsigned)(int)-1; + p->freeBlockHead = 0; + + p->readProcessed = 0; + p->blockIndex = 0; + p->numBlocksMax = numBlocksMax; + p->stopReading = False; + + #ifndef MTCODER_USE_WRITE_THREAD + p->writeIndex = 0; + p->writeRes = SZ_OK; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->ReadyBlocks[i] = False; + p->numFinishedThreads = 0; + #endif + + p->numStartedThreadsLimit = numThreads; + p->numStartedThreads = 0; + ThreadNextGroup_Init(&p->nextGroup, p->numThreadGroups, 0); // startGroup + + // for (i = 0; i < numThreads; i++) + { + // here we create new thread for first block. + // And each new thread will create another new thread after block reading + // until numStartedThreadsLimit is reached. + CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++]; + { + const SRes res2 = MtCoderThread_CreateAndStart(nextThread +#ifdef _WIN32 + , p +#endif + ); + RINOK(res2) + } + } + + RINOK_THREAD(Event_Set(&p->readEvent)) + + #ifdef MTCODER_USE_WRITE_THREAD + { + unsigned bi = 0; + + for (;; bi++) + { + if (bi >= numBlocksMax) + bi = 0; + + RINOK_THREAD(Event_Wait(&p->writeEvents[bi])) + + { + const CMtCoderBlock * const block = &p->blocks[bi]; + const unsigned bufIndex = block->bufIndex; + const BoolInt finished = block->finished; + if (res == SZ_OK && block->res != SZ_OK) + res = block->res; + + if (bufIndex != (unsigned)(int)-1) + { + if (res == SZ_OK) + { + res = p->mtCallback->Write(p->mtCallbackObject, bufIndex); + if (res != SZ_OK) + MtProgress_SetError(&p->mtProgress, res); + } + + CriticalSection_Enter(&p->cs); + { + p->freeBlockList[bufIndex] = p->freeBlockHead; + p->freeBlockHead = bufIndex; + } + CriticalSection_Leave(&p->cs); + } + + RINOK_THREAD(Semaphore_Release1(&p->blocksSemaphore)) + + if (finished) + break; + } + } + } + #else + { + const WRes wres = Event_Wait(&p->finishedEvent); + res = MY_SRes_HRESULT_FROM_WRes(wres); + } + #endif + + if (res == SZ_OK) + res = p->readRes; + + if (res == SZ_OK) + res = p->mtProgress.res; + + #ifndef MTCODER_USE_WRITE_THREAD + if (res == SZ_OK) + res = p->writeRes; + #endif + + if (res != SZ_OK) + MtCoder_Free(p); + return res; +} + +#endif + +#undef RINOK_THREAD diff -Nru p7zip-rar-16.02/C/MtCoder.h p7zip-rar-16.02+really25.00+ds/C/MtCoder.h --- p7zip-rar-16.02/C/MtCoder.h 2009-12-21 11:46:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/MtCoder.h 2025-05-15 06:00:00.000000000 +0000 @@ -1,98 +1,144 @@ -/* MtCoder.h -- Multi-thread Coder -2009-11-19 : Igor Pavlov : Public domain */ - -#ifndef __MT_CODER_H -#define __MT_CODER_H - -#include "Threads.h" - -EXTERN_C_BEGIN - -typedef struct -{ - CThread thread; - CAutoResetEvent startEvent; - CAutoResetEvent finishedEvent; - int stop; - - THREAD_FUNC_TYPE func; - LPVOID param; - THREAD_FUNC_RET_TYPE res; -} CLoopThread; - -void LoopThread_Construct(CLoopThread *p); -void LoopThread_Close(CLoopThread *p); -WRes LoopThread_Create(CLoopThread *p); -WRes LoopThread_StopAndWait(CLoopThread *p); -WRes LoopThread_StartSubThread(CLoopThread *p); -WRes LoopThread_WaitSubThread(CLoopThread *p); - -#ifndef _7ZIP_ST -#define NUM_MT_CODER_THREADS_MAX 32 -#else -#define NUM_MT_CODER_THREADS_MAX 1 -#endif - -typedef struct -{ - UInt64 totalInSize; - UInt64 totalOutSize; - ICompressProgress *progress; - SRes res; - CCriticalSection cs; - UInt64 inSizes[NUM_MT_CODER_THREADS_MAX]; - UInt64 outSizes[NUM_MT_CODER_THREADS_MAX]; -} CMtProgress; - -SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize); - -struct _CMtCoder; - -typedef struct -{ - struct _CMtCoder *mtCoder; - Byte *outBuf; - size_t outBufSize; - Byte *inBuf; - size_t inBufSize; - unsigned index; - CLoopThread thread; - - Bool stopReading; - Bool stopWriting; - CAutoResetEvent canRead; - CAutoResetEvent canWrite; -} CMtThread; - -typedef struct -{ - SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize, - const Byte *src, size_t srcSize, int finished); -} IMtCoderCallback; - -typedef struct _CMtCoder -{ - size_t blockSize; - size_t destBlockSize; - unsigned numThreads; - - ISeqInStream *inStream; - ISeqOutStream *outStream; - ICompressProgress *progress; - ISzAlloc *alloc; - - IMtCoderCallback *mtCallback; - CCriticalSection cs; - SRes res; - - CMtProgress mtProgress; - CMtThread threads[NUM_MT_CODER_THREADS_MAX]; -} CMtCoder; - -void MtCoder_Construct(CMtCoder* p); -void MtCoder_Destruct(CMtCoder* p); -SRes MtCoder_Code(CMtCoder *p); - -EXTERN_C_END - -#endif +/* MtCoder.h -- Multi-thread Coder +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MT_CODER_H +#define ZIP7_INC_MT_CODER_H + +#include "MtDec.h" + +EXTERN_C_BEGIN + +/* + if ( defined MTCODER_USE_WRITE_THREAD) : main thread writes all data blocks to output stream + if (not defined MTCODER_USE_WRITE_THREAD) : any coder thread can write data blocks to output stream +*/ +/* #define MTCODER_USE_WRITE_THREAD */ + +#ifndef Z7_ST + #define MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) + #define MTCODER_THREADS_MAX 256 + #define MTCODER_BLOCKS_MAX (MTCODER_GET_NUM_BLOCKS_FROM_THREADS(MTCODER_THREADS_MAX) + 3) +#else + #define MTCODER_THREADS_MAX 1 + #define MTCODER_BLOCKS_MAX 1 +#endif + + +#ifndef Z7_ST + + +typedef struct +{ + ICompressProgress vt; + CMtProgress *mtProgress; + UInt64 inSize; + UInt64 outSize; +} CMtProgressThunk; + +void MtProgressThunk_CreateVTable(CMtProgressThunk *p); + +#define MtProgressThunk_INIT(p) { (p)->inSize = 0; (p)->outSize = 0; } + + +struct CMtCoder_; + + +typedef struct +{ + struct CMtCoder_ *mtCoder; + unsigned index; + int stop; + Byte *inBuf; + + CAutoResetEvent startEvent; + CThread thread; +} CMtCoderThread; + + +typedef struct +{ + SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished); + SRes (*Write)(void *p, unsigned outBufIndex); +} IMtCoderCallback2; + + +typedef struct +{ + SRes res; + unsigned bufIndex; + BoolInt finished; +} CMtCoderBlock; + + +typedef struct CMtCoder_ +{ + /* input variables */ + + size_t blockSize; /* size of input block */ + unsigned numThreadsMax; + unsigned numThreadGroups; + UInt64 expectedDataSize; + + ISeqInStreamPtr inStream; + const Byte *inData; + size_t inDataSize; + + ICompressProgressPtr progress; + ISzAllocPtr allocBig; + + IMtCoderCallback2 *mtCallback; + void *mtCallbackObject; + + + /* internal variables */ + + size_t allocatedBufsSize; + + CAutoResetEvent readEvent; + CSemaphore blocksSemaphore; + + BoolInt stopReading; + SRes readRes; + + #ifdef MTCODER_USE_WRITE_THREAD + CAutoResetEvent writeEvents[MTCODER_BLOCKS_MAX]; + #else + CAutoResetEvent finishedEvent; + SRes writeRes; + unsigned writeIndex; + Byte ReadyBlocks[MTCODER_BLOCKS_MAX]; + LONG numFinishedThreads; + #endif + + unsigned numStartedThreadsLimit; + unsigned numStartedThreads; + + unsigned numBlocksMax; + unsigned blockIndex; + UInt64 readProcessed; + + CCriticalSection cs; + + unsigned freeBlockHead; + unsigned freeBlockList[MTCODER_BLOCKS_MAX]; + + CMtProgress mtProgress; + CMtCoderBlock blocks[MTCODER_BLOCKS_MAX]; + CMtCoderThread threads[MTCODER_THREADS_MAX]; + + CThreadNextGroup nextGroup; +} CMtCoder; + + +void MtCoder_Construct(CMtCoder *p); +void MtCoder_Destruct(CMtCoder *p); +SRes MtCoder_Code(CMtCoder *p); + + +#endif + + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/MtDec.c p7zip-rar-16.02+really25.00+ds/C/MtDec.c --- p7zip-rar-16.02/C/MtDec.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/MtDec.c 2024-02-20 10:00:00.000000000 +0000 @@ -0,0 +1,1124 @@ +/* MtDec.c -- Multi-thread Decoder +2024-02-20 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #define SHOW_DEBUG_INFO + +// #include +#include + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "MtDec.h" + +#ifndef Z7_ST + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) + +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress) +{ + p->progress = progress; + p->res = SZ_OK; + p->totalInSize = 0; + p->totalOutSize = 0; +} + + +SRes MtProgress_Progress_ST(CMtProgress *p) +{ + if (p->res == SZ_OK && p->progress) + if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK) + p->res = SZ_ERROR_PROGRESS; + return p->res; +} + + +SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize) +{ + SRes res; + CriticalSection_Enter(&p->cs); + + p->totalInSize += inSize; + p->totalOutSize += outSize; + if (p->res == SZ_OK && p->progress) + if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK) + p->res = SZ_ERROR_PROGRESS; + res = p->res; + + CriticalSection_Leave(&p->cs); + return res; +} + + +SRes MtProgress_GetError(CMtProgress *p) +{ + SRes res; + CriticalSection_Enter(&p->cs); + res = p->res; + CriticalSection_Leave(&p->cs); + return res; +} + + +void MtProgress_SetError(CMtProgress *p, SRes res) +{ + CriticalSection_Enter(&p->cs); + if (p->res == SZ_OK) + p->res = res; + CriticalSection_Leave(&p->cs); +} + + +#define RINOK_THREAD(x) RINOK_WRes(x) + + +struct CMtDecBufLink_ +{ + struct CMtDecBufLink_ *next; + void *pad[3]; +}; + +typedef struct CMtDecBufLink_ CMtDecBufLink; + +#define MTDEC__LINK_DATA_OFFSET sizeof(CMtDecBufLink) +#define MTDEC__DATA_PTR_FROM_LINK(link) ((Byte *)(link) + MTDEC__LINK_DATA_OFFSET) + + + +static THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp); + + +static WRes MtDecThread_CreateEvents(CMtDecThread *t) +{ + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->canWrite); + if (wres == 0) + { + wres = AutoResetEvent_OptCreate_And_Reset(&t->canRead); + if (wres == 0) + return SZ_OK; + } + return wres; +} + + +static SRes MtDecThread_CreateAndStart(CMtDecThread *t) +{ + WRes wres = MtDecThread_CreateEvents(t); + // wres = 17; // for test + if (wres == 0) + { + if (Thread_WasCreated(&t->thread)) + return SZ_OK; + wres = Thread_Create(&t->thread, MtDec_ThreadFunc, t); + if (wres == 0) + return SZ_OK; + } + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +void MtDecThread_FreeInBufs(CMtDecThread *t) +{ + if (t->inBuf) + { + void *link = t->inBuf; + t->inBuf = NULL; + do + { + void *next = ((CMtDecBufLink *)link)->next; + ISzAlloc_Free(t->mtDec->alloc, link); + link = next; + } + while (link); + } +} + + +static void MtDecThread_CloseThread(CMtDecThread *t) +{ + if (Thread_WasCreated(&t->thread)) + { + Event_Set(&t->canWrite); /* we can disable it. There are no threads waiting canWrite in normal cases */ + Event_Set(&t->canRead); + Thread_Wait_Close(&t->thread); + } + + Event_Close(&t->canRead); + Event_Close(&t->canWrite); +} + +static void MtDec_CloseThreads(CMtDec *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + MtDecThread_CloseThread(&p->threads[i]); +} + +static void MtDecThread_Destruct(CMtDecThread *t) +{ + MtDecThread_CloseThread(t); + MtDecThread_FreeInBufs(t); +} + + + +static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted) +{ + SRes res; + CriticalSection_Enter(&p->mtProgress.cs); + *wasInterrupted = (p->needInterrupt && interruptIndex > p->interruptIndex); + res = p->mtProgress.res; + CriticalSection_Leave(&p->mtProgress.cs); + return res; +} + +static SRes MtDec_Progress_GetError_Spec(CMtDec *p, UInt64 inSize, UInt64 outSize, UInt64 interruptIndex, BoolInt *wasInterrupted) +{ + SRes res; + CriticalSection_Enter(&p->mtProgress.cs); + + p->mtProgress.totalInSize += inSize; + p->mtProgress.totalOutSize += outSize; + if (p->mtProgress.res == SZ_OK && p->mtProgress.progress) + if (ICompressProgress_Progress(p->mtProgress.progress, p->mtProgress.totalInSize, p->mtProgress.totalOutSize) != SZ_OK) + p->mtProgress.res = SZ_ERROR_PROGRESS; + + *wasInterrupted = (p->needInterrupt && interruptIndex > p->interruptIndex); + res = p->mtProgress.res; + + CriticalSection_Leave(&p->mtProgress.cs); + + return res; +} + +static void MtDec_Interrupt(CMtDec *p, UInt64 interruptIndex) +{ + CriticalSection_Enter(&p->mtProgress.cs); + if (!p->needInterrupt || interruptIndex < p->interruptIndex) + { + p->interruptIndex = interruptIndex; + p->needInterrupt = True; + } + CriticalSection_Leave(&p->mtProgress.cs); +} + +Byte *MtDec_GetCrossBuff(CMtDec *p) +{ + Byte *cr = p->crossBlock; + if (!cr) + { + cr = (Byte *)ISzAlloc_Alloc(p->alloc, MTDEC__LINK_DATA_OFFSET + p->inBufSize); + if (!cr) + return NULL; + p->crossBlock = cr; + } + return MTDEC__DATA_PTR_FROM_LINK(cr); +} + + +/* + MtDec_ThreadFunc2() returns: + 0 - in all normal cases (even for stream error or memory allocation error) + (!= 0) - WRes error return by system threading function +*/ + +// #define MTDEC_ProgessStep (1 << 22) +#define MTDEC_ProgessStep (1 << 0) + +static WRes MtDec_ThreadFunc2(CMtDecThread *t) +{ + CMtDec *p = t->mtDec; + + PRF_STR_INT("MtDec_ThreadFunc2", t->index) + + // SetThreadAffinityMask(GetCurrentThread(), 1 << t->index); + + for (;;) + { + SRes res, codeRes; + BoolInt wasInterrupted, isAllocError, overflow, finish; + SRes threadingErrorSRes; + BoolInt needCode, needWrite, needContinue; + + size_t inDataSize_Start; + UInt64 inDataSize; + // UInt64 inDataSize_Full; + + UInt64 blockIndex; + + UInt64 inPrev = 0; + UInt64 outPrev = 0; + UInt64 inCodePos; + UInt64 outCodePos; + + Byte *afterEndData = NULL; + size_t afterEndData_Size = 0; + BoolInt afterEndData_IsCross = False; + + BoolInt canCreateNewThread = False; + // CMtDecCallbackInfo parse; + CMtDecThread *nextThread; + + PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index) + + RINOK_THREAD(Event_Wait(&t->canRead)) + if (p->exitThread) + return 0; + + PRF_STR_INT("after Event_Wait(&t->canRead)", t->index) + + // if (t->index == 3) return 19; // for test + + blockIndex = p->blockIndex++; + + // PRF(printf("\ncanRead\n")) + + res = MtDec_Progress_GetError_Spec(p, 0, 0, blockIndex, &wasInterrupted); + + finish = p->readWasFinished; + needCode = False; + needWrite = False; + isAllocError = False; + overflow = False; + + inDataSize_Start = 0; + inDataSize = 0; + // inDataSize_Full = 0; + + if (res == SZ_OK && !wasInterrupted) + { + // if (p->inStream) + { + CMtDecBufLink *prev = NULL; + CMtDecBufLink *link = (CMtDecBufLink *)t->inBuf; + size_t crossSize = p->crossEnd - p->crossStart; + + PRF(printf("\ncrossSize = %d\n", crossSize)); + + for (;;) + { + if (!link) + { + link = (CMtDecBufLink *)ISzAlloc_Alloc(p->alloc, MTDEC__LINK_DATA_OFFSET + p->inBufSize); + if (!link) + { + finish = True; + // p->allocError_for_Read_BlockIndex = blockIndex; + isAllocError = True; + break; + } + link->next = NULL; + if (prev) + { + // static unsigned g_num = 0; + // printf("\n%6d : %x", ++g_num, (unsigned)(size_t)((Byte *)link - (Byte *)prev)); + prev->next = link; + } + else + t->inBuf = (void *)link; + } + + { + Byte *data = MTDEC__DATA_PTR_FROM_LINK(link); + Byte *parseData = data; + size_t size; + + if (crossSize != 0) + { + inDataSize = crossSize; + // inDataSize_Full = inDataSize; + inDataSize_Start = crossSize; + size = crossSize; + parseData = MTDEC__DATA_PTR_FROM_LINK(p->crossBlock) + p->crossStart; + PRF(printf("\ncross : crossStart = %7d crossEnd = %7d finish = %1d", + (int)p->crossStart, (int)p->crossEnd, (int)finish)); + } + else + { + size = p->inBufSize; + + res = SeqInStream_ReadMax(p->inStream, data, &size); + + // size = 10; // test + + inDataSize += size; + // inDataSize_Full = inDataSize; + if (!prev) + inDataSize_Start = size; + + p->readProcessed += size; + finish = (size != p->inBufSize); + if (finish) + p->readWasFinished = True; + + // res = E_INVALIDARG; // test + + if (res != SZ_OK) + { + // PRF(printf("\nRead error = %d\n", res)) + // we want to decode all data before error + p->readRes = res; + // p->readError_BlockIndex = blockIndex; + p->readWasFinished = True; + finish = True; + res = SZ_OK; + // break; + } + + if (inDataSize - inPrev >= MTDEC_ProgessStep) + { + res = MtDec_Progress_GetError_Spec(p, 0, 0, blockIndex, &wasInterrupted); + if (res != SZ_OK || wasInterrupted) + break; + inPrev = inDataSize; + } + } + + { + CMtDecCallbackInfo parse; + + parse.startCall = (prev == NULL); + parse.src = parseData; + parse.srcSize = size; + parse.srcFinished = finish; + parse.canCreateNewThread = True; + + PRF(printf("\nParse size = %d\n", (unsigned)size)); + + p->mtCallback->Parse(p->mtCallbackObject, t->index, &parse); + + PRF(printf(" Parse processed = %d, state = %d \n", (unsigned)parse.srcSize, (unsigned)parse.state)); + + needWrite = True; + canCreateNewThread = parse.canCreateNewThread; + + // printf("\n\n%12I64u %12I64u", (UInt64)p->mtProgress.totalInSize, (UInt64)p->mtProgress.totalOutSize); + + if ( + // parseRes != SZ_OK || + // inDataSize - (size - parse.srcSize) > p->inBlockMax + // || + parse.state == MTDEC_PARSE_OVERFLOW + // || wasInterrupted + ) + { + // Overflow or Parse error - switch from MT decoding to ST decoding + finish = True; + overflow = True; + + { + PRF(printf("\n Overflow")); + // PRF(printf("\nisBlockFinished = %d", (unsigned)parse.blockWasFinished)); + PRF(printf("\n inDataSize = %d", (unsigned)inDataSize)); + } + + if (crossSize != 0) + memcpy(data, parseData, size); + p->crossStart = 0; + p->crossEnd = 0; + break; + } + + if (crossSize != 0) + { + memcpy(data, parseData, parse.srcSize); + p->crossStart += parse.srcSize; + } + + if (parse.state != MTDEC_PARSE_CONTINUE || finish) + { + // we don't need to parse in current thread anymore + + if (parse.state == MTDEC_PARSE_END) + finish = True; + + needCode = True; + // p->crossFinished = finish; + + if (parse.srcSize == size) + { + // full parsed - no cross transfer + p->crossStart = 0; + p->crossEnd = 0; + break; + } + + if (parse.state == MTDEC_PARSE_END) + { + afterEndData = parseData + parse.srcSize; + afterEndData_Size = size - parse.srcSize; + if (crossSize != 0) + afterEndData_IsCross = True; + // we reduce data size to required bytes (parsed only) + inDataSize -= afterEndData_Size; + if (!prev) + inDataSize_Start = parse.srcSize; + break; + } + + { + // partial parsed - need cross transfer + if (crossSize != 0) + inDataSize = parse.srcSize; // it's only parsed now + else + { + // partial parsed - is not in initial cross block - we need to copy new data to cross block + Byte *cr = MtDec_GetCrossBuff(p); + if (!cr) + { + { + PRF(printf("\ncross alloc error error\n")); + // res = SZ_ERROR_MEM; + finish = True; + // p->allocError_for_Read_BlockIndex = blockIndex; + isAllocError = True; + break; + } + } + + { + size_t crSize = size - parse.srcSize; + inDataSize -= crSize; + p->crossEnd = crSize; + p->crossStart = 0; + memcpy(cr, parseData + parse.srcSize, crSize); + } + } + + // inDataSize_Full = inDataSize; + if (!prev) + inDataSize_Start = parse.srcSize; // it's partial size (parsed only) + + finish = False; + break; + } + } + + if (parse.srcSize != size) + { + res = SZ_ERROR_FAIL; + PRF(printf("\nfinished error SZ_ERROR_FAIL = %d\n", res)); + break; + } + } + } + + prev = link; + link = link->next; + + if (crossSize != 0) + { + crossSize = 0; + p->crossStart = 0; + p->crossEnd = 0; + } + } + } + + if (res == SZ_OK) + res = MtDec_GetError_Spec(p, blockIndex, &wasInterrupted); + } + + codeRes = SZ_OK; + + if (res == SZ_OK && needCode && !wasInterrupted) + { + codeRes = p->mtCallback->PreCode(p->mtCallbackObject, t->index); + if (codeRes != SZ_OK) + { + needCode = False; + finish = True; + // SZ_ERROR_MEM is expected error here. + // if (codeRes == SZ_ERROR_MEM) - we will try single-thread decoding later. + // if (codeRes != SZ_ERROR_MEM) - we can stop decoding or try single-thread decoding. + } + } + + if (res != SZ_OK || wasInterrupted) + finish = True; + + nextThread = NULL; + threadingErrorSRes = SZ_OK; + + if (!finish) + { + if (p->numStartedThreads < p->numStartedThreads_Limit && canCreateNewThread) + { + SRes res2 = MtDecThread_CreateAndStart(&p->threads[p->numStartedThreads]); + if (res2 == SZ_OK) + { + // if (p->numStartedThreads % 1000 == 0) PRF(printf("\n numStartedThreads=%d\n", p->numStartedThreads)); + p->numStartedThreads++; + } + else + { + PRF(printf("\nERROR: numStartedThreads=%d\n", p->numStartedThreads)); + if (p->numStartedThreads == 1) + { + // if only one thread is possible, we leave muti-threading code + finish = True; + needCode = False; + threadingErrorSRes = res2; + } + else + p->numStartedThreads_Limit = p->numStartedThreads; + } + } + + if (!finish) + { + unsigned nextIndex = t->index + 1; + nextThread = &p->threads[nextIndex >= p->numStartedThreads ? 0 : nextIndex]; + RINOK_THREAD(Event_Set(&nextThread->canRead)) + // We have started executing for new iteration (with next thread) + // And that next thread now is responsible for possible exit from decoding (threading_code) + } + } + + // each call of Event_Set(&nextThread->canRead) must be followed by call of Event_Set(&nextThread->canWrite) + // if ( !finish ) we must call Event_Set(&nextThread->canWrite) in any case + // if ( finish ) we switch to single-thread mode and there are 2 ways at the end of current iteration (current block): + // - if (needContinue) after Write(&needContinue), we restore decoding with new iteration + // - otherwise we stop decoding and exit from MtDec_ThreadFunc2() + + // Don't change (finish) variable in the further code + + + // ---------- CODE ---------- + + inPrev = 0; + outPrev = 0; + inCodePos = 0; + outCodePos = 0; + + if (res == SZ_OK && needCode && codeRes == SZ_OK) + { + BoolInt isStartBlock = True; + CMtDecBufLink *link = (CMtDecBufLink *)t->inBuf; + + for (;;) + { + size_t inSize; + int stop; + + if (isStartBlock) + inSize = inDataSize_Start; + else + { + UInt64 rem = inDataSize - inCodePos; + inSize = p->inBufSize; + if (inSize > rem) + inSize = (size_t)rem; + } + + inCodePos += inSize; + stop = True; + + codeRes = p->mtCallback->Code(p->mtCallbackObject, t->index, + (const Byte *)MTDEC__DATA_PTR_FROM_LINK(link), inSize, + (inCodePos == inDataSize), // srcFinished + &inCodePos, &outCodePos, &stop); + + if (codeRes != SZ_OK) + { + PRF(printf("\nCode Interrupt error = %x\n", codeRes)); + // we interrupt only later blocks + MtDec_Interrupt(p, blockIndex); + break; + } + + if (stop || inCodePos == inDataSize) + break; + + { + const UInt64 inDelta = inCodePos - inPrev; + const UInt64 outDelta = outCodePos - outPrev; + if (inDelta >= MTDEC_ProgessStep || outDelta >= MTDEC_ProgessStep) + { + // Sleep(1); + res = MtDec_Progress_GetError_Spec(p, inDelta, outDelta, blockIndex, &wasInterrupted); + if (res != SZ_OK || wasInterrupted) + break; + inPrev = inCodePos; + outPrev = outCodePos; + } + } + + link = link->next; + isStartBlock = False; + } + } + + + // ---------- WRITE ---------- + + RINOK_THREAD(Event_Wait(&t->canWrite)) + + { + BoolInt isErrorMode = False; + BoolInt canRecode = True; + BoolInt needWriteToStream = needWrite; + + if (p->exitThread) return 0; // it's never executed in normal cases + + if (p->wasInterrupted) + wasInterrupted = True; + else + { + if (codeRes != SZ_OK) // || !needCode // check it !!! + { + p->wasInterrupted = True; + p->codeRes = codeRes; + if (codeRes == SZ_ERROR_MEM) + isAllocError = True; + } + + if (threadingErrorSRes) + { + p->wasInterrupted = True; + p->threadingErrorSRes = threadingErrorSRes; + needWriteToStream = False; + } + if (isAllocError) + { + p->wasInterrupted = True; + p->isAllocError = True; + needWriteToStream = False; + } + if (overflow) + { + p->wasInterrupted = True; + p->overflow = True; + needWriteToStream = False; + } + } + + if (needCode) + { + if (wasInterrupted) + { + inCodePos = 0; + outCodePos = 0; + } + { + const UInt64 inDelta = inCodePos - inPrev; + const UInt64 outDelta = outCodePos - outPrev; + // if (inDelta != 0 || outDelta != 0) + res = MtProgress_ProgressAdd(&p->mtProgress, inDelta, outDelta); + } + } + + needContinue = (!finish); + + // if (res == SZ_OK && needWrite && !wasInterrupted) + if (needWrite) + { + // p->inProcessed += inCodePos; + + PRF(printf("\n--Write afterSize = %d\n", (unsigned)afterEndData_Size)); + + res = p->mtCallback->Write(p->mtCallbackObject, t->index, + res == SZ_OK && needWriteToStream && !wasInterrupted, // needWrite + afterEndData, afterEndData_Size, afterEndData_IsCross, + &needContinue, + &canRecode); + + // res = SZ_ERROR_FAIL; // for test + + PRF(printf("\nAfter Write needContinue = %d\n", (unsigned)needContinue)); + PRF(printf("\nprocessed = %d\n", (unsigned)p->inProcessed)); + + if (res != SZ_OK) + { + PRF(printf("\nWrite error = %d\n", res)); + isErrorMode = True; + p->wasInterrupted = True; + } + if (res != SZ_OK + || (!needContinue && !finish)) + { + PRF(printf("\nWrite Interrupt error = %x\n", res)); + MtDec_Interrupt(p, blockIndex); + } + } + + if (canRecode) + if (!needCode + || res != SZ_OK + || p->wasInterrupted + || codeRes != SZ_OK + || wasInterrupted + || p->numFilledThreads != 0 + || isErrorMode) + { + if (p->numFilledThreads == 0) + p->filledThreadStart = t->index; + if (inDataSize != 0 || !finish) + { + t->inDataSize_Start = inDataSize_Start; + t->inDataSize = inDataSize; + p->numFilledThreads++; + } + PRF(printf("\np->numFilledThreads = %d\n", p->numFilledThreads)); + PRF(printf("p->filledThreadStart = %d\n", p->filledThreadStart)); + } + + if (!finish) + { + RINOK_THREAD(Event_Set(&nextThread->canWrite)) + } + else + { + if (needContinue) + { + // we restore decoding with new iteration + RINOK_THREAD(Event_Set(&p->threads[0].canWrite)) + } + else + { + // we exit from decoding + if (t->index == 0) + return SZ_OK; + p->exitThread = True; + } + RINOK_THREAD(Event_Set(&p->threads[0].canRead)) + } + } + } +} + +#ifdef _WIN32 +#define USE_ALLOCA +#endif + +#ifdef USE_ALLOCA +#ifdef _WIN32 +#include +#else +#include +#endif +#endif + + +typedef + #ifdef _WIN32 + UINT_PTR + #elif 1 + uintptr_t + #else + ptrdiff_t + #endif + MY_uintptr_t; + +static THREAD_FUNC_DECL MtDec_ThreadFunc1(void *pp) +{ + WRes res; + + CMtDecThread *t = (CMtDecThread *)pp; + CMtDec *p; + + // fprintf(stdout, "\n%d = %p\n", t->index, &t); + + res = MtDec_ThreadFunc2(t); + p = t->mtDec; + if (res == 0) + return (THREAD_FUNC_RET_TYPE)(MY_uintptr_t)p->exitThreadWRes; + { + // it's unexpected situation for some threading function error + if (p->exitThreadWRes == 0) + p->exitThreadWRes = res; + PRF(printf("\nthread exit error = %d\n", res)); + p->exitThread = True; + Event_Set(&p->threads[0].canRead); + Event_Set(&p->threads[0].canWrite); + MtProgress_SetError(&p->mtProgress, MY_SRes_HRESULT_FROM_WRes(res)); + } + return (THREAD_FUNC_RET_TYPE)(MY_uintptr_t)res; +} + +static Z7_NO_INLINE THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp) +{ + #ifdef USE_ALLOCA + CMtDecThread *t = (CMtDecThread *)pp; + // fprintf(stderr, "\n%d = %p - before", t->index, &t); + t->allocaPtr = alloca(t->index * 128); + #endif + return MtDec_ThreadFunc1(pp); +} + + +int MtDec_PrepareRead(CMtDec *p) +{ + if (p->crossBlock && p->crossStart == p->crossEnd) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + if (i > p->numStartedThreads + || p->numFilledThreads <= + (i >= p->filledThreadStart ? + i - p->filledThreadStart : + i + p->numStartedThreads - p->filledThreadStart)) + MtDecThread_FreeInBufs(&p->threads[i]); + } + + return (p->numFilledThreads != 0) || (p->crossStart != p->crossEnd); +} + + +const Byte *MtDec_Read(CMtDec *p, size_t *inLim) +{ + while (p->numFilledThreads != 0) + { + CMtDecThread *t = &p->threads[p->filledThreadStart]; + + if (*inLim != 0) + { + { + void *link = t->inBuf; + void *next = ((CMtDecBufLink *)link)->next; + ISzAlloc_Free(p->alloc, link); + t->inBuf = next; + } + + if (t->inDataSize == 0) + { + MtDecThread_FreeInBufs(t); + if (--p->numFilledThreads == 0) + break; + if (++p->filledThreadStart == p->numStartedThreads) + p->filledThreadStart = 0; + t = &p->threads[p->filledThreadStart]; + } + } + + { + size_t lim = t->inDataSize_Start; + if (lim != 0) + t->inDataSize_Start = 0; + else + { + UInt64 rem = t->inDataSize; + lim = p->inBufSize; + if (lim > rem) + lim = (size_t)rem; + } + t->inDataSize -= lim; + *inLim = lim; + return (const Byte *)MTDEC__DATA_PTR_FROM_LINK(t->inBuf); + } + } + + { + size_t crossSize = p->crossEnd - p->crossStart; + if (crossSize != 0) + { + const Byte *data = MTDEC__DATA_PTR_FROM_LINK(p->crossBlock) + p->crossStart; + *inLim = crossSize; + p->crossStart = 0; + p->crossEnd = 0; + return data; + } + *inLim = 0; + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + return NULL; + } +} + + +void MtDec_Construct(CMtDec *p) +{ + unsigned i; + + p->inBufSize = (size_t)1 << 18; + + p->numThreadsMax = 0; + + p->inStream = NULL; + + // p->inData = NULL; + // p->inDataSize = 0; + + p->crossBlock = NULL; + p->crossStart = 0; + p->crossEnd = 0; + + p->numFilledThreads = 0; + + p->progress = NULL; + p->alloc = NULL; + + p->mtCallback = NULL; + p->mtCallbackObject = NULL; + + p->allocatedBufsSize = 0; + + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CMtDecThread *t = &p->threads[i]; + t->mtDec = p; + t->index = i; + t->inBuf = NULL; + Event_Construct(&t->canRead); + Event_Construct(&t->canWrite); + Thread_CONSTRUCT(&t->thread) + } + + // Event_Construct(&p->finishedEvent); + + CriticalSection_Init(&p->mtProgress.cs); +} + + +static void MtDec_Free(CMtDec *p) +{ + unsigned i; + + p->exitThread = True; + + for (i = 0; i < MTDEC_THREADS_MAX; i++) + MtDecThread_Destruct(&p->threads[i]); + + // Event_Close(&p->finishedEvent); + + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } +} + + +void MtDec_Destruct(CMtDec *p) +{ + MtDec_Free(p); + + CriticalSection_Delete(&p->mtProgress.cs); +} + + +SRes MtDec_Code(CMtDec *p) +{ + unsigned i; + + p->inProcessed = 0; + + p->blockIndex = 1; // it must be larger than not_defined index (0) + p->isAllocError = False; + p->overflow = False; + p->threadingErrorSRes = SZ_OK; + + p->needContinue = True; + + p->readWasFinished = False; + p->needInterrupt = False; + p->interruptIndex = (UInt64)(Int64)-1; + + p->readProcessed = 0; + p->readRes = SZ_OK; + p->codeRes = SZ_OK; + p->wasInterrupted = False; + + p->crossStart = 0; + p->crossEnd = 0; + + p->filledThreadStart = 0; + p->numFilledThreads = 0; + + { + unsigned numThreads = p->numThreadsMax; + if (numThreads > MTDEC_THREADS_MAX) + numThreads = MTDEC_THREADS_MAX; + p->numStartedThreads_Limit = numThreads; + p->numStartedThreads = 0; + } + + if (p->inBufSize != p->allocatedBufsSize) + { + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CMtDecThread *t = &p->threads[i]; + if (t->inBuf) + MtDecThread_FreeInBufs(t); + } + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + + p->allocatedBufsSize = p->inBufSize; + } + + MtProgress_Init(&p->mtProgress, p->progress); + + // RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) + p->exitThread = False; + p->exitThreadWRes = 0; + + { + WRes wres; + SRes sres; + CMtDecThread *nextThread = &p->threads[p->numStartedThreads++]; + // wres = MtDecThread_CreateAndStart(nextThread); + wres = MtDecThread_CreateEvents(nextThread); + if (wres == 0) { wres = Event_Set(&nextThread->canWrite); + if (wres == 0) { wres = Event_Set(&nextThread->canRead); + if (wres == 0) { THREAD_FUNC_RET_TYPE res = MtDec_ThreadFunc(nextThread); + wres = (WRes)(MY_uintptr_t)res; + if (wres != 0) + { + p->needContinue = False; + MtDec_CloseThreads(p); + }}}} + + // wres = 17; // for test + // wres = Event_Wait(&p->finishedEvent); + + sres = MY_SRes_HRESULT_FROM_WRes(wres); + + if (sres != 0) + p->threadingErrorSRes = sres; + + if ( + // wres == 0 + // wres != 0 + // || p->mtc.codeRes == SZ_ERROR_MEM + p->isAllocError + || p->threadingErrorSRes != SZ_OK + || p->overflow) + { + // p->needContinue = True; + } + else + p->needContinue = False; + + if (p->needContinue) + return SZ_OK; + + // if (sres != SZ_OK) + return sres; + // return SZ_ERROR_FAIL; + } +} + +#endif + +#undef PRF diff -Nru p7zip-rar-16.02/C/MtDec.h p7zip-rar-16.02+really25.00+ds/C/MtDec.h --- p7zip-rar-16.02/C/MtDec.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/MtDec.h 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,202 @@ +/* MtDec.h -- Multi-thread Decoder +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MT_DEC_H +#define ZIP7_INC_MT_DEC_H + +#include "7zTypes.h" + +#ifndef Z7_ST +#include "Threads.h" +#endif + +EXTERN_C_BEGIN + +#ifndef Z7_ST + +#ifndef Z7_ST + #define MTDEC_THREADS_MAX 32 +#else + #define MTDEC_THREADS_MAX 1 +#endif + + +typedef struct +{ + ICompressProgressPtr progress; + SRes res; + UInt64 totalInSize; + UInt64 totalOutSize; + CCriticalSection cs; +} CMtProgress; + +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress); +SRes MtProgress_Progress_ST(CMtProgress *p); +SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize); +SRes MtProgress_GetError(CMtProgress *p); +void MtProgress_SetError(CMtProgress *p, SRes res); + +struct CMtDec; + +typedef struct +{ + struct CMtDec_ *mtDec; + unsigned index; + void *inBuf; + + size_t inDataSize_Start; // size of input data in start block + UInt64 inDataSize; // total size of input data in all blocks + + CThread thread; + CAutoResetEvent canRead; + CAutoResetEvent canWrite; + void *allocaPtr; +} CMtDecThread; + +void MtDecThread_FreeInBufs(CMtDecThread *t); + + +typedef enum +{ + MTDEC_PARSE_CONTINUE, // continue this block with more input data + MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread + MTDEC_PARSE_NEW, // new block + MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue) +} EMtDecParseState; + +typedef struct +{ + // in + int startCall; + const Byte *src; + size_t srcSize; + // in : (srcSize == 0) is allowed + // out : it's allowed to return less that actually was used ? + int srcFinished; + + // out + EMtDecParseState state; + BoolInt canCreateNewThread; + UInt64 outPos; // check it (size_t) +} CMtDecCallbackInfo; + + +typedef struct +{ + void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci); + + // PreCode() and Code(): + // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks + SRes (*PreCode)(void *p, unsigned coderIndex); + SRes (*Code)(void *p, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop); + // stop - means stop another Code calls + + + /* Write() must be called, if Parse() was called + set (needWrite) if + { + && (was not interrupted by progress) + && (was not interrupted in previous block) + } + + out: + if (*needContinue), decoder still need to continue decoding with new iteration, + even after MTDEC_PARSE_END + if (*canRecode), we didn't flush current block data, so we still can decode current block later. + */ + SRes (*Write)(void *p, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + // int srcFinished, + BoolInt *needContinue, + BoolInt *canRecode); + +} IMtDecCallback2; + + + +typedef struct CMtDec_ +{ + /* input variables */ + + size_t inBufSize; /* size of input block */ + unsigned numThreadsMax; + // size_t inBlockMax; + unsigned numThreadsMax_2; + + ISeqInStreamPtr inStream; + // const Byte *inData; + // size_t inDataSize; + + ICompressProgressPtr progress; + ISzAllocPtr alloc; + + IMtDecCallback2 *mtCallback; + void *mtCallbackObject; + + + /* internal variables */ + + size_t allocatedBufsSize; + + BoolInt exitThread; + WRes exitThreadWRes; + + UInt64 blockIndex; + BoolInt isAllocError; + BoolInt overflow; + SRes threadingErrorSRes; + + BoolInt needContinue; + + // CAutoResetEvent finishedEvent; + + SRes readRes; + SRes codeRes; + + BoolInt wasInterrupted; + + unsigned numStartedThreads_Limit; + unsigned numStartedThreads; + + Byte *crossBlock; + size_t crossStart; + size_t crossEnd; + UInt64 readProcessed; + BoolInt readWasFinished; + UInt64 inProcessed; + + unsigned filledThreadStart; + unsigned numFilledThreads; + + #ifndef Z7_ST + BoolInt needInterrupt; + UInt64 interruptIndex; + CMtProgress mtProgress; + CMtDecThread threads[MTDEC_THREADS_MAX]; + #endif +} CMtDec; + + +void MtDec_Construct(CMtDec *p); +void MtDec_Destruct(CMtDec *p); + +/* +MtDec_Code() returns: + SZ_OK - in most cases + MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function +*/ + +SRes MtDec_Code(CMtDec *p); +Byte *MtDec_GetCrossBuff(CMtDec *p); + +int MtDec_PrepareRead(CMtDec *p); +const Byte *MtDec_Read(CMtDec *p, size_t *inLim); + +#endif + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Ppmd.h p7zip-rar-16.02+really25.00+ds/C/Ppmd.h --- p7zip-rar-16.02/C/Ppmd.h 2016-05-20 08:20:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd.h 2023-03-05 15:00:00.000000000 +0000 @@ -1,85 +1,169 @@ -/* Ppmd.h -- PPMD codec common code -2016-05-16 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#ifndef __PPMD_H -#define __PPMD_H - -#include "CpuArch.h" - -EXTERN_C_BEGIN - -#ifdef MY_CPU_32BIT - #define PPMD_32BIT -#endif - -#define PPMD_INT_BITS 7 -#define PPMD_PERIOD_BITS 7 -#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) - -#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) -#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) -#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) -#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) - -#define PPMD_N1 4 -#define PPMD_N2 4 -#define PPMD_N3 4 -#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) -#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) - -#pragma pack(push, 1) -/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */ - -/* SEE-contexts for PPM-contexts with masked symbols */ -typedef struct -{ - UInt16 Summ; /* Freq */ - Byte Shift; /* Speed of Freq change; low Shift is for fast change */ - Byte Count; /* Count to next change of Shift */ -} CPpmd_See; - -#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ - { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } - -typedef struct -{ - Byte Symbol; - Byte Freq; - UInt16 SuccessorLow; - UInt16 SuccessorHigh; -} CPpmd_State; - -#pragma pack(pop) - -typedef - #ifdef PPMD_32BIT - CPpmd_State * - #else - UInt32 - #endif - CPpmd_State_Ref; - -typedef - #ifdef PPMD_32BIT - void * - #else - UInt32 - #endif - CPpmd_Void_Ref; - -typedef - #ifdef PPMD_32BIT - Byte * - #else - UInt32 - #endif - CPpmd_Byte_Ref; - -#define PPMD_SetAllBitsIn256Bytes(p) \ - { unsigned z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \ - p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }} - -EXTERN_C_END - -#endif +/* Ppmd.h -- PPMD codec common code +2023-03-05 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#ifndef ZIP7_INC_PPMD_H +#define ZIP7_INC_PPMD_H + +#include "CpuArch.h" + +EXTERN_C_BEGIN + +#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) +/* + PPMD code always uses 32-bit internal fields in PPMD structures to store internal references in main block. + if (PPMD_32BIT is defined), the PPMD code stores internal pointers to 32-bit reference fields. + if (PPMD_32BIT is NOT defined), the PPMD code stores internal UInt32 offsets to reference fields. + if (pointer size is 64-bit), then (PPMD_32BIT) mode is not allowed, + if (pointer size is 32-bit), then (PPMD_32BIT) mode is optional, + and it's allowed to disable PPMD_32BIT mode even if pointer is 32-bit. + PPMD code works slightly faster in (PPMD_32BIT) mode. +*/ + #define PPMD_32BIT +#endif + +#define PPMD_INT_BITS 7 +#define PPMD_PERIOD_BITS 7 +#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) + +#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) +#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) +#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) +#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) + +#define PPMD_N1 4 +#define PPMD_N2 4 +#define PPMD_N3 4 +#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) +#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) + +MY_CPU_pragma_pack_push_1 +/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */ + +/* SEE-contexts for PPM-contexts with masked symbols */ +typedef struct +{ + UInt16 Summ; /* Freq */ + Byte Shift; /* Speed of Freq change; low Shift is for fast change */ + Byte Count; /* Count to next change of Shift */ +} CPpmd_See; + +#define Ppmd_See_UPDATE(p) \ + { if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ + { (p)->Summ = (UInt16)((p)->Summ << 1); \ + (p)->Count = (Byte)(3 << (p)->Shift++); }} + + +typedef struct +{ + Byte Symbol; + Byte Freq; + UInt16 Successor_0; + UInt16 Successor_1; +} CPpmd_State; + +typedef struct CPpmd_State2_ +{ + Byte Symbol; + Byte Freq; +} CPpmd_State2; + +typedef struct CPpmd_State4_ +{ + UInt16 Successor_0; + UInt16 Successor_1; +} CPpmd_State4; + +MY_CPU_pragma_pop + +/* + PPMD code can write full CPpmd_State structure data to CPpmd*_Context + at (byte offset = 2) instead of some fields of original CPpmd*_Context structure. + + If we use pointers to different types, but that point to shared + memory space, we can have aliasing problem (strict aliasing). + + XLC compiler in -O2 mode can change the order of memory write instructions + in relation to read instructions, if we have use pointers to different types. + + To solve that aliasing problem we use combined CPpmd*_Context structure + with unions that contain the fields from both structures: + the original CPpmd*_Context and CPpmd_State. + So we can access the fields from both structures via one pointer, + and the compiler doesn't change the order of write instructions + in relation to read instructions. + + If we don't use memory write instructions to shared memory in + some local code, and we use only reading instructions (read only), + then probably it's safe to use pointers to different types for reading. +*/ + + + +#ifdef PPMD_32BIT + + #define Ppmd_Ref_Type(type) type * + #define Ppmd_GetRef(p, ptr) (ptr) + #define Ppmd_GetPtr(p, ptr) (ptr) + #define Ppmd_GetPtr_Type(p, ptr, note_type) (ptr) + +#else + + #define Ppmd_Ref_Type(type) UInt32 + #define Ppmd_GetRef(p, ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) + #define Ppmd_GetPtr(p, offs) ((void *)((p)->Base + (offs))) + #define Ppmd_GetPtr_Type(p, offs, type) ((type *)Ppmd_GetPtr(p, offs)) + +#endif // PPMD_32BIT + + +typedef Ppmd_Ref_Type(CPpmd_State) CPpmd_State_Ref; +typedef Ppmd_Ref_Type(void) CPpmd_Void_Ref; +typedef Ppmd_Ref_Type(Byte) CPpmd_Byte_Ref; + + +/* +#ifdef MY_CPU_LE_UNALIGN +// the unaligned 32-bit access latency can be too large, if the data is not in L1 cache. +#define Ppmd_GET_SUCCESSOR(p) ((CPpmd_Void_Ref)*(const UInt32 *)(const void *)&(p)->Successor_0) +#define Ppmd_SET_SUCCESSOR(p, v) *(UInt32 *)(void *)(void *)&(p)->Successor_0 = (UInt32)(v) + +#else +*/ + +/* + We can write 16-bit halves to 32-bit (Successor) field in any selected order. + But the native order is more consistent way. + So we use the native order, if LE/BE order can be detected here at compile time. +*/ + +#ifdef MY_CPU_BE + + #define Ppmd_GET_SUCCESSOR(p) \ + ( (CPpmd_Void_Ref) (((UInt32)(p)->Successor_0 << 16) | (p)->Successor_1) ) + + #define Ppmd_SET_SUCCESSOR(p, v) { \ + (p)->Successor_0 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); \ + (p)->Successor_1 = (UInt16)((UInt32)(v) /* & 0xFFFF */); } + +#else + + #define Ppmd_GET_SUCCESSOR(p) \ + ( (CPpmd_Void_Ref) ((p)->Successor_0 | ((UInt32)(p)->Successor_1 << 16)) ) + + #define Ppmd_SET_SUCCESSOR(p, v) { \ + (p)->Successor_0 = (UInt16)((UInt32)(v) /* & 0xFFFF */); \ + (p)->Successor_1 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); } + +#endif + +// #endif + + +#define PPMD_SetAllBitsIn256Bytes(p) \ + { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \ + p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }} + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Ppmd7.c p7zip-rar-16.02+really25.00+ds/C/Ppmd7.c --- p7zip-rar-16.02/C/Ppmd7.c 2016-06-11 08:08:05.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd7.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,710 +1,1131 @@ -/* Ppmd7.c -- PPMdH codec -2016-05-21 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include - -#include "Ppmd7.h" - -const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; - -#define MAX_FREQ 124 -#define UNIT_SIZE 12 - -#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) -#define I2U(indx) (p->Indx2Units[indx]) - -#ifdef PPMD_32BIT - #define REF(ptr) (ptr) -#else - #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) -#endif - -#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) - -#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) -#define STATS(ctx) Ppmd7_GetStats(p, ctx) -#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) -#define SUFFIX(ctx) CTX((ctx)->Suffix) - -typedef CPpmd7_Context * CTX_PTR; - -struct CPpmd7_Node_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Node_ * - #else - UInt32 - #endif - CPpmd7_Node_Ref; - -typedef struct CPpmd7_Node_ -{ - UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ - UInt16 NU; - CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ - CPpmd7_Node_Ref Prev; -} CPpmd7_Node; - -#ifdef PPMD_32BIT - #define NODE(ptr) (ptr) -#else - #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) -#endif - -void Ppmd7_Construct(CPpmd7 *p) -{ - unsigned i, k, m; - - p->Base = 0; - - for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) - { - unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while (--step); - p->Indx2Units[i] = (Byte)k; - } - - p->NS2BSIndx[0] = (0 << 1); - p->NS2BSIndx[1] = (1 << 1); - memset(p->NS2BSIndx + 2, (2 << 1), 9); - memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); - - for (i = 0; i < 3; i++) - p->NS2Indx[i] = (Byte)i; - for (m = i, k = 1; i < 256; i++) - { - p->NS2Indx[i] = (Byte)m; - if (--k == 0) - k = (++m) - 2; - } - - memset(p->HB2Flag, 0, 0x40); - memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); -} - -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->Base); - p->Size = 0; - p->Base = 0; -} - -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) -{ - if (p->Base == 0 || p->Size != size) - { - Ppmd7_Free(p, alloc); - p->AlignOffset = - #ifdef PPMD_32BIT - (4 - size) & 3; - #else - 4 - (size & 3); - #endif - if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size - #ifndef PPMD_32BIT - + UNIT_SIZE - #endif - )) == 0) - return False; - p->Size = size; - } - return True; -} - -static void InsertNode(CPpmd7 *p, void *node, unsigned indx) -{ - *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; - p->FreeList[indx] = REF(node); -} - -static void *RemoveNode(CPpmd7 *p, unsigned indx) -{ - CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); - p->FreeList[indx] = *node; - return node; -} - -static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) -{ - unsigned i, nu = I2U(oldIndx) - I2U(newIndx); - ptr = (Byte *)ptr + U2B(I2U(newIndx)); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); - } - InsertNode(p, ptr, i); -} - -static void GlueFreeBlocks(CPpmd7 *p) -{ - #ifdef PPMD_32BIT - CPpmd7_Node headItem; - CPpmd7_Node_Ref head = &headItem; - #else - CPpmd7_Node_Ref head = p->AlignOffset + p->Size; - #endif - - CPpmd7_Node_Ref n = head; - unsigned i; - - p->GlueCount = 255; - - /* create doubly-linked list of free blocks */ - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - UInt16 nu = I2U(i); - CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; - p->FreeList[i] = 0; - while (next != 0) - { - CPpmd7_Node *node = NODE(next); - node->Next = n; - n = NODE(n)->Prev = next; - next = *(const CPpmd7_Node_Ref *)node; - node->Stamp = 0; - node->NU = (UInt16)nu; - } - } - NODE(head)->Stamp = 1; - NODE(head)->Next = n; - NODE(n)->Prev = head; - if (p->LoUnit != p->HiUnit) - ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; - - /* Glue free blocks */ - while (n != head) - { - CPpmd7_Node *node = NODE(n); - UInt32 nu = (UInt32)node->NU; - for (;;) - { - CPpmd7_Node *node2 = NODE(n) + nu; - nu += node2->NU; - if (node2->Stamp != 0 || nu >= 0x10000) - break; - NODE(node2->Prev)->Next = node2->Next; - NODE(node2->Next)->Prev = node2->Prev; - node->NU = (UInt16)nu; - } - n = node->Next; - } - - /* Fill lists of free blocks */ - for (n = NODE(head)->Next; n != head;) - { - CPpmd7_Node *node = NODE(n); - unsigned nu; - CPpmd7_Node_Ref next = node->Next; - for (nu = node->NU; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, node + k, nu - k - 1); - } - InsertNode(p, node, i); - n = next; - } -} - -static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) -{ - unsigned i; - void *retVal; - if (p->GlueCount == 0) - { - GlueFreeBlocks(p); - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - } - i = indx; - do - { - if (++i == PPMD_NUM_INDEXES) - { - UInt32 numBytes = U2B(I2U(indx)); - p->GlueCount--; - return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); - } - } - while (p->FreeList[i] == 0); - retVal = RemoveNode(p, i); - SplitBlock(p, retVal, i, indx); - return retVal; -} - -static void *AllocUnits(CPpmd7 *p, unsigned indx) -{ - UInt32 numBytes; - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - numBytes = U2B(I2U(indx)); - if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) - { - void *retVal = p->LoUnit; - p->LoUnit += numBytes; - return retVal; - } - return AllocUnitsRare(p, indx); -} - -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); } - -static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) -{ - unsigned i0 = U2I(oldNU); - unsigned i1 = U2I(newNU); - if (i0 == i1) - return oldPtr; - if (p->FreeList[i1] != 0) - { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); - return ptr; - } - SplitBlock(p, oldPtr, i0, i1); - return oldPtr; -} - -#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) - -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) -{ - (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); -} - -static void RestartModel(CPpmd7 *p) -{ - unsigned i, k, m; - - memset(p->FreeList, 0, sizeof(p->FreeList)); - p->Text = p->Base + p->AlignOffset; - p->HiUnit = p->Text + p->Size; - p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; - p->GlueCount = 0; - - p->OrderFall = p->MaxOrder; - p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; - p->PrevSuccess = 0; - - p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - p->MinContext->Suffix = 0; - p->MinContext->NumStats = 256; - p->MinContext->SummFreq = 256 + 1; - p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ - p->LoUnit += U2B(256 / 2); - p->MinContext->Stats = REF(p->FoundState); - for (i = 0; i < 256; i++) - { - CPpmd_State *s = &p->FoundState[i]; - s->Symbol = (Byte)i; - s->Freq = 1; - SetSuccessor(s, 0); - } - - for (i = 0; i < 128; i++) - for (k = 0; k < 8; k++) - { - UInt16 *dest = p->BinSumm[i] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); - for (m = 0; m < 64; m += 8) - dest[m] = val; - } - - for (i = 0; i < 25; i++) - for (k = 0; k < 16; k++) - { - CPpmd_See *s = &p->See[i][k]; - s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); - s->Count = 4; - } -} - -void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) -{ - p->MaxOrder = maxOrder; - RestartModel(p); - p->DummySee.Shift = PPMD_PERIOD_BITS; - p->DummySee.Summ = 0; /* unused */ - p->DummySee.Count = 64; /* unused */ -} - -static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) -{ - CPpmd_State upState; - CTX_PTR c = p->MinContext; - CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); - CPpmd_State *ps[PPMD7_MAX_ORDER]; - unsigned numPs = 0; - - if (!skip) - ps[numPs++] = p->FoundState; - - while (c->Suffix) - { - CPpmd_Void_Ref successor; - CPpmd_State *s; - c = SUFFIX(c); - if (c->NumStats != 1) - { - for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); - } - else - s = ONE_STATE(c); - successor = SUCCESSOR(s); - if (successor != upBranch) - { - c = CTX(successor); - if (numPs == 0) - return c; - break; - } - ps[numPs++] = s; - } - - upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); - SetSuccessor(&upState, upBranch + 1); - - if (c->NumStats == 1) - upState.Freq = ONE_STATE(c)->Freq; - else - { - UInt32 cf, s0; - CPpmd_State *s; - for (s = STATS(c); s->Symbol != upState.Symbol; s++); - cf = s->Freq - 1; - s0 = c->SummFreq - c->NumStats - cf; - upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); - } - - do - { - /* Create Child */ - CTX_PTR c1; /* = AllocContext(p); */ - if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); - else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); - else - { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); - if (!c1) - return NULL; - } - c1->NumStats = 1; - *ONE_STATE(c1) = upState; - c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); - c = c1; - } - while (numPs != 0); - - return c; -} - -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) -{ - CPpmd_State tmp = *t1; - *t1 = *t2; - *t2 = tmp; -} - -static void UpdateModel(CPpmd7 *p) -{ - CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; - unsigned s0, ns; - - if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) - { - c = SUFFIX(p->MinContext); - - if (c->NumStats == 1) - { - CPpmd_State *s = ONE_STATE(c); - if (s->Freq < 32) - s->Freq++; - } - else - { - CPpmd_State *s = STATS(c); - if (s->Symbol != p->FoundState->Symbol) - { - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s[0].Freq >= s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - s--; - } - } - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - } - - if (p->OrderFall == 0) - { - p->MinContext = p->MaxContext = CreateSuccessors(p, True); - if (p->MinContext == 0) - { - RestartModel(p); - return; - } - SetSuccessor(p->FoundState, REF(p->MinContext)); - return; - } - - *p->Text++ = p->FoundState->Symbol; - successor = REF(p->Text); - if (p->Text >= p->UnitsStart) - { - RestartModel(p); - return; - } - - if (fSuccessor) - { - if (fSuccessor <= successor) - { - CTX_PTR cs = CreateSuccessors(p, False); - if (cs == NULL) - { - RestartModel(p); - return; - } - fSuccessor = REF(cs); - } - if (--p->OrderFall == 0) - { - successor = fSuccessor; - p->Text -= (p->MaxContext != p->MinContext); - } - } - else - { - SetSuccessor(p->FoundState, successor); - fSuccessor = REF(p->MinContext); - } - - s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); - - for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) - { - unsigned ns1; - UInt32 cf, sf; - if ((ns1 = c->NumStats) != 1) - { - if ((ns1 & 1) == 0) - { - /* Expand for one UNIT */ - unsigned oldNU = ns1 >> 1; - unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) - { - void *ptr = AllocUnits(p, i + 1); - void *oldPtr; - if (!ptr) - { - RestartModel(p); - return; - } - oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); - c->Stats = STATS_REF(ptr); - } - } - c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); - } - else - { - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); - if (!s) - { - RestartModel(p); - return; - } - *s = *ONE_STATE(c); - c->Stats = REF(s); - if (s->Freq < MAX_FREQ / 4 - 1) - s->Freq <<= 1; - else - s->Freq = MAX_FREQ - 4; - c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); - } - cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); - sf = (UInt32)s0 + c->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf) + (cf >= 4 * sf); - c->SummFreq += 3; - } - else - { - cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); - c->SummFreq = (UInt16)(c->SummFreq + cf); - } - { - CPpmd_State *s = STATS(c) + ns1; - SetSuccessor(s, successor); - s->Symbol = p->FoundState->Symbol; - s->Freq = (Byte)cf; - c->NumStats = (UInt16)(ns1 + 1); - } - } - p->MaxContext = p->MinContext = CTX(fSuccessor); -} - -static void Rescale(CPpmd7 *p) -{ - unsigned i, adder, sumFreq, escFreq; - CPpmd_State *stats = STATS(p->MinContext); - CPpmd_State *s = p->FoundState; - { - CPpmd_State tmp = *s; - for (; s != stats; s--) - s[0] = s[-1]; - *s = tmp; - } - escFreq = p->MinContext->SummFreq - s->Freq; - s->Freq += 4; - adder = (p->OrderFall != 0); - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq = s->Freq; - - i = p->MinContext->NumStats - 1; - do - { - escFreq -= (++s)->Freq; - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq += s->Freq; - if (s[0].Freq > s[-1].Freq) - { - CPpmd_State *s1 = s; - CPpmd_State tmp = *s1; - do - s1[0] = s1[-1]; - while (--s1 != stats && tmp.Freq > s1[-1].Freq); - *s1 = tmp; - } - } - while (--i); - - if (s->Freq == 0) - { - unsigned numStats = p->MinContext->NumStats; - unsigned n0, n1; - do { i++; } while ((--s)->Freq == 0); - escFreq += i; - p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); - if (p->MinContext->NumStats == 1) - { - CPpmd_State tmp = *stats; - do - { - tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); - escFreq >>= 1; - } - while (escFreq > 1); - InsertNode(p, stats, U2I(((numStats + 1) >> 1))); - *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; - return; - } - n0 = (numStats + 1) >> 1; - n1 = (p->MinContext->NumStats + 1) >> 1; - if (n0 != n1) - p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); - } - p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); - p->FoundState = STATS(p->MinContext); -} - -CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) -{ - CPpmd_See *see; - unsigned nonMasked = p->MinContext->NumStats - numMasked; - if (p->MinContext->NumStats != 256) - { - see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] + - (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + - 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + - 4 * (unsigned)(numMasked > nonMasked) + - p->HiBitsFlag; - { - unsigned r = (see->Summ >> see->Shift); - see->Summ = (UInt16)(see->Summ - r); - *escFreq = r + (r == 0); - } - } - else - { - see = &p->DummySee; - *escFreq = 1; - } - return see; -} - -static void NextContext(CPpmd7 *p) -{ - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); - if (p->OrderFall == 0 && (Byte *)c > p->Text) - p->MinContext = p->MaxContext = c; - else - UpdateModel(p); -} - -void Ppmd7_Update1(CPpmd7 *p) -{ - CPpmd_State *s = p->FoundState; - s->Freq += 4; - p->MinContext->SummFreq += 4; - if (s[0].Freq > s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - p->FoundState = --s; - if (s->Freq > MAX_FREQ) - Rescale(p); - } - NextContext(p); -} - -void Ppmd7_Update1_0(CPpmd7 *p) -{ - p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); - p->RunLength += p->PrevSuccess; - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - NextContext(p); -} - -void Ppmd7_UpdateBin(CPpmd7 *p) -{ - p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); - p->PrevSuccess = 1; - p->RunLength++; - NextContext(p); -} - -void Ppmd7_Update2(CPpmd7 *p) -{ - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - p->RunLength = p->InitRL; - UpdateModel(p); -} +/* Ppmd7.c -- PPMdH codec +2023-09-07 : Igor Pavlov : Public domain +This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ + +#include "Precomp.h" + +#include + +#include "Ppmd7.h" + +/* define PPMD7_ORDER_0_SUPPPORT to suport order-0 mode, unsupported by orignal PPMd var.H. code */ +// #define PPMD7_ORDER_0_SUPPPORT + +MY_ALIGN(16) +static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +MY_ALIGN(16) +static const UInt16 PPMD7_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +#define MAX_FREQ 124 +#define UNIT_SIZE 12 + +#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) +#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1]) +#define I2U(indx) ((unsigned)p->Indx2Units[indx]) +#define I2U_UInt16(indx) ((UInt16)p->Indx2Units[indx]) + +#define REF(ptr) Ppmd_GetRef(p, ptr) + +#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +#define STATS(ctx) Ppmd7_GetStats(p, ctx) +#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) +#define SUFFIX(ctx) CTX((ctx)->Suffix) + +typedef CPpmd7_Context * PPMD7_CTX_PTR; + +struct CPpmd7_Node_; + +typedef Ppmd_Ref_Type(struct CPpmd7_Node_) CPpmd7_Node_Ref; + +typedef struct CPpmd7_Node_ +{ + UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ + UInt16 NU; + CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ + CPpmd7_Node_Ref Prev; +} CPpmd7_Node; + +#define NODE(r) Ppmd_GetPtr_Type(p, r, CPpmd7_Node) + +void Ppmd7_Construct(CPpmd7 *p) +{ + unsigned i, k, m; + + p->Base = NULL; + + for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) + { + unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); + do { p->Units2Indx[k++] = (Byte)i; } while (--step); + p->Indx2Units[i] = (Byte)k; + } + + p->NS2BSIndx[0] = (0 << 1); + p->NS2BSIndx[1] = (1 << 1); + memset(p->NS2BSIndx + 2, (2 << 1), 9); + memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); + + for (i = 0; i < 3; i++) + p->NS2Indx[i] = (Byte)i; + + for (m = i, k = 1; i < 256; i++) + { + p->NS2Indx[i] = (Byte)m; + if (--k == 0) + k = (++m) - 2; + } + + memcpy(p->ExpEscape, PPMD7_kExpEscape, 16); +} + + +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Base); + p->Size = 0; + p->Base = NULL; +} + + +BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc) +{ + if (!p->Base || p->Size != size) + { + Ppmd7_Free(p, alloc); + p->AlignOffset = (4 - size) & 3; + if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == NULL) + return False; + p->Size = size; + } + return True; +} + + + +// ---------- Internal Memory Allocator ---------- + +/* We can use CPpmd7_Node in list of free units (as in Ppmd8) + But we still need one additional list walk pass in Ppmd7_GlueFreeBlocks(). + So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in Ppmd7_InsertNode() / Ppmd7_RemoveNode() +*/ + +#define EMPTY_NODE 0 + + +static void Ppmd7_InsertNode(CPpmd7 *p, void *node, unsigned indx) +{ + *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; + // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx]; + + p->FreeList[indx] = REF(node); + +} + + +static void *Ppmd7_RemoveNode(CPpmd7 *p, unsigned indx) +{ + CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); + p->FreeList[indx] = *node; + // CPpmd7_Node *node = NODE((CPpmd7_Node_Ref)p->FreeList[indx]); + // p->FreeList[indx] = node->Next; + return node; +} + + +static void Ppmd7_SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +{ + unsigned i, nu = I2U(oldIndx) - I2U(newIndx); + ptr = (Byte *)ptr + U2B(I2U(newIndx)); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + Ppmd7_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + } + Ppmd7_InsertNode(p, ptr, i); +} + + +/* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */ + +typedef union +{ + CPpmd7_Node Node; + CPpmd7_Node_Ref NextRef; +} CPpmd7_Node_Union; + +/* Original PPmdH (Ppmd7) code uses doubly linked list in Ppmd7_GlueFreeBlocks() + we use single linked list similar to Ppmd8 code */ + + +static void Ppmd7_GlueFreeBlocks(CPpmd7 *p) +{ + /* + we use first UInt16 field of 12-bytes UNITs as record type stamp + CPpmd_State { Byte Symbol; Byte Freq; : Freq != 0 + CPpmd7_Context { UInt16 NumStats; : NumStats != 0 + CPpmd7_Node { UInt16 Stamp : Stamp == 0 for free record + : Stamp == 1 for head record and guard + Last 12-bytes UNIT in array is always contains 12-bytes order-0 CPpmd7_Context record. + */ + CPpmd7_Node_Ref head, n = 0; + + p->GlueCount = 255; + + + /* we set guard NODE at LoUnit */ + if (p->LoUnit != p->HiUnit) + ((CPpmd7_Node *)(void *)p->LoUnit)->Stamp = 1; + + { + /* Create list of free blocks. + We still need one additional list walk pass before Glue. */ + unsigned i; + for (i = 0; i < PPMD_NUM_INDEXES; i++) + { + const UInt16 nu = I2U_UInt16(i); + CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; + p->FreeList[i] = 0; + while (next != 0) + { + /* Don't change the order of the following commands: */ + CPpmd7_Node_Union *un = (CPpmd7_Node_Union *)NODE(next); + const CPpmd7_Node_Ref tmp = next; + next = un->NextRef; + un->Node.Stamp = EMPTY_NODE; + un->Node.NU = nu; + un->Node.Next = n; + n = tmp; + } + } + } + + head = n; + /* Glue and Fill must walk the list in same direction */ + { + /* Glue free blocks */ + CPpmd7_Node_Ref *prev = &head; + while (n) + { + CPpmd7_Node *node = NODE(n); + UInt32 nu = node->NU; + n = node->Next; + if (nu == 0) + { + *prev = n; + continue; + } + prev = &node->Next; + for (;;) + { + CPpmd7_Node *node2 = node + nu; + nu += node2->NU; + if (node2->Stamp != EMPTY_NODE || nu >= 0x10000) + break; + node->NU = (UInt16)nu; + node2->NU = 0; + } + } + } + + /* Fill lists of free blocks */ + for (n = head; n != 0;) + { + CPpmd7_Node *node = NODE(n); + UInt32 nu = node->NU; + unsigned i; + n = node->Next; + if (nu == 0) + continue; + for (; nu > 128; nu -= 128, node += 128) + Ppmd7_InsertNode(p, node, PPMD_NUM_INDEXES - 1); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + Ppmd7_InsertNode(p, node + k, (unsigned)nu - k - 1); + } + Ppmd7_InsertNode(p, node, i); + } +} + + +Z7_NO_INLINE +static void *Ppmd7_AllocUnitsRare(CPpmd7 *p, unsigned indx) +{ + unsigned i; + + if (p->GlueCount == 0) + { + Ppmd7_GlueFreeBlocks(p); + if (p->FreeList[indx] != 0) + return Ppmd7_RemoveNode(p, indx); + } + + i = indx; + + do + { + if (++i == PPMD_NUM_INDEXES) + { + UInt32 numBytes = U2B(I2U(indx)); + Byte *us = p->UnitsStart; + p->GlueCount--; + return ((UInt32)(us - p->Text) > numBytes) ? (p->UnitsStart = us - numBytes) : NULL; + } + } + while (p->FreeList[i] == 0); + + { + void *block = Ppmd7_RemoveNode(p, i); + Ppmd7_SplitBlock(p, block, i, indx); + return block; + } +} + + +static void *Ppmd7_AllocUnits(CPpmd7 *p, unsigned indx) +{ + if (p->FreeList[indx] != 0) + return Ppmd7_RemoveNode(p, indx); + { + UInt32 numBytes = U2B(I2U(indx)); + Byte *lo = p->LoUnit; + if ((UInt32)(p->HiUnit - lo) >= numBytes) + { + p->LoUnit = lo + numBytes; + return lo; + } + } + return Ppmd7_AllocUnitsRare(p, indx); +} + + +#define MEM_12_CPY(dest, src, num) \ + { UInt32 *d = (UInt32 *)(dest); \ + const UInt32 *z = (const UInt32 *)(src); \ + unsigned n = (num); \ + do { \ + d[0] = z[0]; \ + d[1] = z[1]; \ + d[2] = z[2]; \ + z += 3; \ + d += 3; \ + } while (--n); \ + } + + +/* +static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) +{ + unsigned i0 = U2I(oldNU); + unsigned i1 = U2I(newNU); + if (i0 == i1) + return oldPtr; + if (p->FreeList[i1] != 0) + { + void *ptr = Ppmd7_RemoveNode(p, i1); + MEM_12_CPY(ptr, oldPtr, newNU) + Ppmd7_InsertNode(p, oldPtr, i0); + return ptr; + } + Ppmd7_SplitBlock(p, oldPtr, i0, i1); + return oldPtr; +} +*/ + + +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) +static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) +{ + Ppmd_SET_SUCCESSOR(p, v) +} + + + +Z7_NO_INLINE +static +void Ppmd7_RestartModel(CPpmd7 *p) +{ + unsigned i, k; + + memset(p->FreeList, 0, sizeof(p->FreeList)); + + p->Text = p->Base + p->AlignOffset; + p->HiUnit = p->Text + p->Size; + p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; + p->GlueCount = 0; + + p->OrderFall = p->MaxOrder; + p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; + p->PrevSuccess = 0; + + { + CPpmd7_Context *mc = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd7_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + + p->LoUnit += U2B(256 / 2); + p->MaxContext = p->MinContext = mc; + p->FoundState = s; + + mc->NumStats = 256; + mc->Union2.SummFreq = 256 + 1; + mc->Union4.Stats = REF(s); + mc->Suffix = 0; + + for (i = 0; i < 256; i++, s++) + { + s->Symbol = (Byte)i; + s->Freq = 1; + SetSuccessor(s, 0); + } + + #ifdef PPMD7_ORDER_0_SUPPPORT + if (p->MaxOrder == 0) + { + CPpmd_Void_Ref r = REF(mc); + s = p->FoundState; + for (i = 0; i < 256; i++, s++) + SetSuccessor(s, r); + return; + } + #endif + } + + for (i = 0; i < 128; i++) + + + + for (k = 0; k < 8; k++) + { + unsigned m; + UInt16 *dest = p->BinSumm[i] + k; + const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD7_kInitBinEsc[k] / (i + 2)); + for (m = 0; m < 64; m += 8) + dest[m] = val; + } + + + for (i = 0; i < 25; i++) + { + + CPpmd_See *s = p->See[i]; + + + + unsigned summ = ((5 * i + 10) << (PPMD_PERIOD_BITS - 4)); + for (k = 0; k < 16; k++, s++) + { + s->Summ = (UInt16)summ; + s->Shift = (PPMD_PERIOD_BITS - 4); + s->Count = 4; + } + } + + p->DummySee.Summ = 0; /* unused */ + p->DummySee.Shift = PPMD_PERIOD_BITS; + p->DummySee.Count = 64; /* unused */ +} + + +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) +{ + p->MaxOrder = maxOrder; + + Ppmd7_RestartModel(p); +} + + + +/* + Ppmd7_CreateSuccessors() + It's called when (FoundState->Successor) is RAW-Successor, + that is the link to position in Raw text. + So we create Context records and write the links to + FoundState->Successor and to identical RAW-Successors in suffix + contexts of MinContex. + + The function returns: + if (OrderFall == 0) then MinContext is already at MAX order, + { return pointer to new or existing context of same MAX order } + else + { return pointer to new real context that will be (Order+1) in comparison with MinContext + + also it can return pointer to real context of same order, +*/ + +Z7_NO_INLINE +static PPMD7_CTX_PTR Ppmd7_CreateSuccessors(CPpmd7 *p) +{ + PPMD7_CTX_PTR c = p->MinContext; + CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); + Byte newSym, newFreq; + unsigned numPs = 0; + CPpmd_State *ps[PPMD7_MAX_ORDER]; + + if (p->OrderFall != 0) + ps[numPs++] = p->FoundState; + + while (c->Suffix) + { + CPpmd_Void_Ref successor; + CPpmd_State *s; + c = SUFFIX(c); + + + if (c->NumStats != 1) + { + Byte sym = p->FoundState->Symbol; + for (s = STATS(c); s->Symbol != sym; s++); + + } + else + { + s = ONE_STATE(c); + + } + successor = SUCCESSOR(s); + if (successor != upBranch) + { + // (c) is real record Context here, + c = CTX(successor); + if (numPs == 0) + { + // (c) is real record MAX Order Context here, + // So we don't need to create any new contexts. + return c; + } + break; + } + ps[numPs++] = s; + } + + // All created contexts will have single-symbol with new RAW-Successor + // All new RAW-Successors will point to next position in RAW text + // after FoundState->Successor + + newSym = *(const Byte *)Ppmd7_GetPtr(p, upBranch); + upBranch++; + + + if (c->NumStats == 1) + newFreq = ONE_STATE(c)->Freq; + else + { + UInt32 cf, s0; + CPpmd_State *s; + for (s = STATS(c); s->Symbol != newSym; s++); + cf = (UInt32)s->Freq - 1; + s0 = (UInt32)c->Union2.SummFreq - c->NumStats - cf; + /* + cf - is frequency of symbol that will be Successor in new context records. + s0 - is commulative frequency sum of another symbols from parent context. + max(newFreq)= (s->Freq + 1), when (s0 == 1) + we have requirement (Ppmd7Context_OneState()->Freq <= 128) in BinSumm[] + so (s->Freq < 128) - is requirement for multi-symbol contexts + */ + newFreq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : (2 * cf + s0 - 1) / (2 * s0) + 1)); + } + + // Create new single-symbol contexts from low order to high order in loop + + do + { + PPMD7_CTX_PTR c1; + /* = AllocContext(p); */ + if (p->HiUnit != p->LoUnit) + c1 = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); + else if (p->FreeList[0] != 0) + c1 = (PPMD7_CTX_PTR)Ppmd7_RemoveNode(p, 0); + else + { + c1 = (PPMD7_CTX_PTR)Ppmd7_AllocUnitsRare(p, 0); + if (!c1) + return NULL; + } + + c1->NumStats = 1; + ONE_STATE(c1)->Symbol = newSym; + ONE_STATE(c1)->Freq = newFreq; + SetSuccessor(ONE_STATE(c1), upBranch); + c1->Suffix = REF(c); + SetSuccessor(ps[--numPs], REF(c1)); + c = c1; + } + while (numPs != 0); + + return c; +} + + + +#define SWAP_STATES(s) \ + { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; } + + +void Ppmd7_UpdateModel(CPpmd7 *p); +Z7_NO_INLINE +void Ppmd7_UpdateModel(CPpmd7 *p) +{ + CPpmd_Void_Ref maxSuccessor, minSuccessor; + PPMD7_CTX_PTR c, mc; + unsigned s0, ns; + + + + if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) + { + /* Update Freqs in Suffix Context */ + + c = SUFFIX(p->MinContext); + + if (c->NumStats == 1) + { + CPpmd_State *s = ONE_STATE(c); + if (s->Freq < 32) + s->Freq++; + } + else + { + CPpmd_State *s = STATS(c); + Byte sym = p->FoundState->Symbol; + + if (s->Symbol != sym) + { + do + { + // s++; if (s->Symbol == sym) break; + s++; + } + while (s->Symbol != sym); + + if (s[0].Freq >= s[-1].Freq) + { + SWAP_STATES(s) + s--; + } + } + + if (s->Freq < MAX_FREQ - 9) + { + s->Freq = (Byte)(s->Freq + 2); + c->Union2.SummFreq = (UInt16)(c->Union2.SummFreq + 2); + } + } + } + + + if (p->OrderFall == 0) + { + /* MAX ORDER context */ + /* (FoundState->Successor) is RAW-Successor. */ + p->MaxContext = p->MinContext = Ppmd7_CreateSuccessors(p); + if (!p->MinContext) + { + Ppmd7_RestartModel(p); + return; + } + SetSuccessor(p->FoundState, REF(p->MinContext)); + return; + } + + + /* NON-MAX ORDER context */ + + { + Byte *text = p->Text; + *text++ = p->FoundState->Symbol; + p->Text = text; + if (text >= p->UnitsStart) + { + Ppmd7_RestartModel(p); + return; + } + maxSuccessor = REF(text); + } + + minSuccessor = SUCCESSOR(p->FoundState); + + if (minSuccessor) + { + // there is Successor for FoundState in MinContext. + // So the next context will be one order higher than MinContext. + + if (minSuccessor <= maxSuccessor) + { + // minSuccessor is RAW-Successor. So we will create real contexts records: + PPMD7_CTX_PTR cs = Ppmd7_CreateSuccessors(p); + if (!cs) + { + Ppmd7_RestartModel(p); + return; + } + minSuccessor = REF(cs); + } + + // minSuccessor now is real Context pointer that points to existing (Order+1) context + + if (--p->OrderFall == 0) + { + /* + if we move to MaxOrder context, then minSuccessor will be common Succesor for both: + MinContext that is (MaxOrder - 1) + MaxContext that is (MaxOrder) + so we don't need new RAW-Successor, and we can use real minSuccessor + as succssors for both MinContext and MaxContext. + */ + maxSuccessor = minSuccessor; + + /* + if (MaxContext != MinContext) + { + there was order fall from MaxOrder and we don't need current symbol + to transfer some RAW-Succesors to real contexts. + So we roll back pointer in raw data for one position. + } + */ + p->Text -= (p->MaxContext != p->MinContext); + } + } + else + { + /* + FoundState has NULL-Successor here. + And only root 0-order context can contain NULL-Successors. + We change Successor in FoundState to RAW-Successor, + And next context will be same 0-order root Context. + */ + SetSuccessor(p->FoundState, maxSuccessor); + minSuccessor = REF(p->MinContext); + } + + mc = p->MinContext; + c = p->MaxContext; + + p->MaxContext = p->MinContext = CTX(minSuccessor); + + if (c == mc) + return; + + // s0 : is pure Escape Freq + s0 = mc->Union2.SummFreq - (ns = mc->NumStats) - ((unsigned)p->FoundState->Freq - 1); + + do + { + unsigned ns1; + UInt32 sum; + + if ((ns1 = c->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + /* Expand for one UNIT */ + const unsigned oldNU = ns1 >> 1; + const unsigned i = U2I(oldNU); + if (i != U2I((size_t)oldNU + 1)) + { + void *ptr = Ppmd7_AllocUnits(p, i + 1); + void *oldPtr; + if (!ptr) + { + Ppmd7_RestartModel(p); + return; + } + oldPtr = STATS(c); + MEM_12_CPY(ptr, oldPtr, oldNU) + Ppmd7_InsertNode(p, oldPtr, i); + c->Union4.Stats = STATS_REF(ptr); + } + } + sum = c->Union2.SummFreq; + /* max increase of Escape_Freq is 3 here. + total increase of Union2.SummFreq for all symbols is less than 256 here */ + sum += (UInt32)(unsigned)((2 * ns1 < ns) + 2 * ((unsigned)(4 * ns1 <= ns) & (sum <= 8 * ns1))); + /* original PPMdH uses 16-bit variable for (sum) here. + But (sum < 0x9000). So we don't truncate (sum) to 16-bit */ + // sum = (UInt16)sum; + } + else + { + // instead of One-symbol context we create 2-symbol context + CPpmd_State *s = (CPpmd_State*)Ppmd7_AllocUnits(p, 0); + if (!s) + { + Ppmd7_RestartModel(p); + return; + } + { + unsigned freq = c->Union2.State2.Freq; + // s = *ONE_STATE(c); + s->Symbol = c->Union2.State2.Symbol; + s->Successor_0 = c->Union4.State4.Successor_0; + s->Successor_1 = c->Union4.State4.Successor_1; + // SetSuccessor(s, c->Union4.Stats); // call it only for debug purposes to check the order of + // (Successor_0 and Successor_1) in LE/BE. + c->Union4.Stats = REF(s); + if (freq < MAX_FREQ / 4 - 1) + freq <<= 1; + else + freq = MAX_FREQ - 4; + // (max(s->freq) == 120), when we convert from 1-symbol into 2-symbol context + s->Freq = (Byte)freq; + // max(InitEsc = PPMD7_kExpEscape[*]) is 25. So the max(escapeFreq) is 26 here + sum = (UInt32)(freq + p->InitEsc + (ns > 3)); + } + } + + { + CPpmd_State *s = STATS(c) + ns1; + UInt32 cf = 2 * (sum + 6) * (UInt32)p->FoundState->Freq; + UInt32 sf = (UInt32)s0 + sum; + s->Symbol = p->FoundState->Symbol; + c->NumStats = (UInt16)(ns1 + 1); + SetSuccessor(s, maxSuccessor); + + if (cf < 6 * sf) + { + cf = (UInt32)1 + (cf > sf) + (cf >= 4 * sf); + sum += 3; + /* It can add (0, 1, 2) to Escape_Freq */ + } + else + { + cf = (UInt32)4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); + sum += cf; + } + + c->Union2.SummFreq = (UInt16)sum; + s->Freq = (Byte)cf; + } + c = SUFFIX(c); + } + while (c != mc); +} + + + +Z7_NO_INLINE +static void Ppmd7_Rescale(CPpmd7 *p) +{ + unsigned i, adder, sumFreq, escFreq; + CPpmd_State *stats = STATS(p->MinContext); + CPpmd_State *s = p->FoundState; + + /* Sort the list by Freq */ + if (s != stats) + { + CPpmd_State tmp = *s; + do + s[0] = s[-1]; + while (--s != stats); + *s = tmp; + } + + sumFreq = s->Freq; + escFreq = p->MinContext->Union2.SummFreq - sumFreq; + + /* + if (p->OrderFall == 0), adder = 0 : it's allowed to remove symbol from MAX Order context + if (p->OrderFall != 0), adder = 1 : it's NOT allowed to remove symbol from NON-MAX Order context + */ + + adder = (p->OrderFall != 0); + + #ifdef PPMD7_ORDER_0_SUPPPORT + adder |= (p->MaxOrder == 0); // we don't remove symbols from order-0 context + #endif + + sumFreq = (sumFreq + 4 + adder) >> 1; + i = (unsigned)p->MinContext->NumStats - 1; + s->Freq = (Byte)sumFreq; + + do + { + unsigned freq = (++s)->Freq; + escFreq -= freq; + freq = (freq + adder) >> 1; + sumFreq += freq; + s->Freq = (Byte)freq; + if (freq > s[-1].Freq) + { + CPpmd_State tmp = *s; + CPpmd_State *s1 = s; + do + { + s1[0] = s1[-1]; + } + while (--s1 != stats && freq > s1[-1].Freq); + *s1 = tmp; + } + } + while (--i); + + if (s->Freq == 0) + { + /* Remove all items with Freq == 0 */ + CPpmd7_Context *mc; + unsigned numStats, numStatsNew, n0, n1; + + i = 0; do { i++; } while ((--s)->Freq == 0); + + /* We increase (escFreq) for the number of removed symbols. + So we will have (0.5) increase for Escape_Freq in avarage per + removed symbol after Escape_Freq halving */ + escFreq += i; + mc = p->MinContext; + numStats = mc->NumStats; + numStatsNew = numStats - i; + mc->NumStats = (UInt16)(numStatsNew); + n0 = (numStats + 1) >> 1; + + if (numStatsNew == 1) + { + /* Create Single-Symbol context */ + unsigned freq = stats->Freq; + + do + { + escFreq >>= 1; + freq = (freq + 1) >> 1; + } + while (escFreq > 1); + + s = ONE_STATE(mc); + *s = *stats; + s->Freq = (Byte)freq; // (freq <= 260 / 4) + p->FoundState = s; + Ppmd7_InsertNode(p, stats, U2I(n0)); + return; + } + + n1 = (numStatsNew + 1) >> 1; + if (n0 != n1) + { + // p->MinContext->Union4.Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); + unsigned i0 = U2I(n0); + unsigned i1 = U2I(n1); + if (i0 != i1) + { + if (p->FreeList[i1] != 0) + { + void *ptr = Ppmd7_RemoveNode(p, i1); + p->MinContext->Union4.Stats = STATS_REF(ptr); + MEM_12_CPY(ptr, (const void *)stats, n1) + Ppmd7_InsertNode(p, stats, i0); + } + else + Ppmd7_SplitBlock(p, stats, i0, i1); + } + } + } + { + CPpmd7_Context *mc = p->MinContext; + mc->Union2.SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); + // Escape_Freq halving here + p->FoundState = STATS(mc); + } +} + + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) +{ + CPpmd_See *see; + const CPpmd7_Context *mc = p->MinContext; + unsigned numStats = mc->NumStats; + if (numStats != 256) + { + unsigned nonMasked = numStats - numMasked; + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] + + (nonMasked < (unsigned)SUFFIX(mc)->NumStats - numStats) + + 2 * (unsigned)(mc->Union2.SummFreq < 11 * numStats) + + 4 * (unsigned)(numMasked > nonMasked) + + p->HiBitsFlag; + { + // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ + const unsigned summ = (UInt16)see->Summ; // & 0xFFFF + const unsigned r = (summ >> see->Shift); + see->Summ = (UInt16)(summ - r); + *escFreq = (UInt32)(r + (r == 0)); + } + } + else + { + see = &p->DummySee; + *escFreq = 1; + } + return see; +} + + +static void Ppmd7_NextContext(CPpmd7 *p) +{ + PPMD7_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + if (p->OrderFall == 0 && (const Byte *)c > p->Text) + p->MaxContext = p->MinContext = c; + else + Ppmd7_UpdateModel(p); +} + + +void Ppmd7_Update1(CPpmd7 *p) +{ + CPpmd_State *s = p->FoundState; + unsigned freq = s->Freq; + freq += 4; + p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); + s->Freq = (Byte)freq; + if (freq > s[-1].Freq) + { + SWAP_STATES(s) + p->FoundState = --s; + if (freq > MAX_FREQ) + Ppmd7_Rescale(p); + } + Ppmd7_NextContext(p); +} + + +void Ppmd7_Update1_0(CPpmd7 *p) +{ + CPpmd_State *s = p->FoundState; + CPpmd7_Context *mc = p->MinContext; + unsigned freq = s->Freq; + const unsigned summFreq = mc->Union2.SummFreq; + p->PrevSuccess = (2 * freq > summFreq); + p->RunLength += (Int32)p->PrevSuccess; + mc->Union2.SummFreq = (UInt16)(summFreq + 4); + freq += 4; + s->Freq = (Byte)freq; + if (freq > MAX_FREQ) + Ppmd7_Rescale(p); + Ppmd7_NextContext(p); +} + + +/* +void Ppmd7_UpdateBin(CPpmd7 *p) +{ + unsigned freq = p->FoundState->Freq; + p->FoundState->Freq = (Byte)(freq + (freq < 128)); + p->PrevSuccess = 1; + p->RunLength++; + Ppmd7_NextContext(p); +} +*/ + +void Ppmd7_Update2(CPpmd7 *p) +{ + CPpmd_State *s = p->FoundState; + unsigned freq = s->Freq; + freq += 4; + p->RunLength = p->InitRL; + p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); + s->Freq = (Byte)freq; + if (freq > MAX_FREQ) + Ppmd7_Rescale(p); + Ppmd7_UpdateModel(p); +} + + + +/* +PPMd Memory Map: +{ + [ 0 ] contains subset of original raw text, that is required to create context + records, Some symbols are not written, when max order context was reached + [ Text ] free area + [ UnitsStart ] CPpmd_State vectors and CPpmd7_Context records + [ LoUnit ] free area for CPpmd_State and CPpmd7_Context items +[ HiUnit ] CPpmd7_Context records + [ Size ] end of array +} + +These addresses don't cross at any time. +And the following condtions is true for addresses: + (0 <= Text < UnitsStart <= LoUnit <= HiUnit <= Size) + +Raw text is BYTE--aligned. +the data in block [ UnitsStart ... Size ] contains 12-bytes aligned UNITs. + +Last UNIT of array at offset (Size - 12) is root order-0 CPpmd7_Context record. +The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors. +The code doesn't free UNITs allocated for CPpmd7_Context records. + +The code calls Ppmd7_RestartModel(), when there is no free memory for allocation. +And Ppmd7_RestartModel() changes the state to orignal start state, with full free block. + + +The code allocates UNITs with the following order: + +Allocation of 1 UNIT for Context record + - from free space (HiUnit) down to (LoUnit) + - from FreeList[0] + - Ppmd7_AllocUnitsRare() + +Ppmd7_AllocUnits() for CPpmd_State vectors: + - from FreeList[i] + - from free space (LoUnit) up to (HiUnit) + - Ppmd7_AllocUnitsRare() + +Ppmd7_AllocUnitsRare() + - if (GlueCount == 0) + { Glue lists, GlueCount = 255, allocate from FreeList[i]] } + - loop for all higher sized FreeList[...] lists + - from (UnitsStart - Text), GlueCount-- + - ERROR + + +Each Record with Context contains the CPpmd_State vector, where each +CPpmd_State contains the link to Successor. +There are 3 types of Successor: + 1) NULL-Successor - NULL pointer. NULL-Successor links can be stored + only in 0-order Root Context Record. + We use 0 value as NULL-Successor + 2) RAW-Successor - the link to position in raw text, + that "RAW-Successor" is being created after first + occurrence of new symbol for some existing context record. + (RAW-Successor > 0). + 3) RECORD-Successor - the link to CPpmd7_Context record of (Order+1), + that record is being created when we go via RAW-Successor again. + +For any successors at any time: the following condtions are true for Successor links: +(NULL-Successor < RAW-Successor < UnitsStart <= RECORD-Successor) + + +---------- Symbol Frequency, SummFreq and Range in Range_Coder ---------- + +CPpmd7_Context::SummFreq = Sum(Stats[].Freq) + Escape_Freq + +The PPMd code tries to fulfill the condition: + (SummFreq <= (256 * 128 = RC::kBot)) + +We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124) +So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol. +If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7. +SummFreq and Escape_Freq can be changed in Ppmd7_Rescale() and *Update*() functions. +Ppmd7_Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Ppmd7_Rescale() for +max-order context. + +When the PPMd code still break (Total <= RC::Range) condition in range coder, +we have two ways to resolve that problem: + 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases. + 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value. +*/ + +#undef MAX_FREQ +#undef UNIT_SIZE +#undef U2B +#undef U2I +#undef I2U +#undef I2U_UInt16 +#undef REF +#undef STATS_REF +#undef CTX +#undef STATS +#undef ONE_STATE +#undef SUFFIX +#undef NODE +#undef EMPTY_NODE +#undef MEM_12_CPY +#undef SUCCESSOR +#undef SWAP_STATES diff -Nru p7zip-rar-16.02/C/Ppmd7.h p7zip-rar-16.02+really25.00+ds/C/Ppmd7.h --- p7zip-rar-16.02/C/Ppmd7.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd7.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,140 +1,181 @@ -/* Ppmd7.h -- PPMdH compression codec -2016-05-21 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -/* This code supports virtual RangeDecoder and includes the implementation -of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. -If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ - -#ifndef __PPMD7_H -#define __PPMD7_H - -#include "Ppmd.h" - -EXTERN_C_BEGIN - -#define PPMD7_MIN_ORDER 2 -#define PPMD7_MAX_ORDER 64 - -#define PPMD7_MIN_MEM_SIZE (1 << 11) -#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) - -struct CPpmd7_Context_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Context_ * - #else - UInt32 - #endif - CPpmd7_Context_Ref; - -typedef struct CPpmd7_Context_ -{ - UInt16 NumStats; - UInt16 SummFreq; - CPpmd_State_Ref Stats; - CPpmd7_Context_Ref Suffix; -} CPpmd7_Context; - -#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) - -typedef struct -{ - CPpmd7_Context *MinContext, *MaxContext; - CPpmd_State *FoundState; - unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; - Int32 RunLength, InitRL; /* must be 32-bit at least */ - - UInt32 Size; - UInt32 GlueCount; - Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; - UInt32 AlignOffset; - - Byte Indx2Units[PPMD_NUM_INDEXES]; - Byte Units2Indx[128]; - CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; - Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; - CPpmd_See DummySee, See[25][16]; - UInt16 BinSumm[128][64]; -} CPpmd7; - -void Ppmd7_Construct(CPpmd7 *p); -Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); -void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); -void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); -#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) - - -/* ---------- Internal Functions ---------- */ - -extern const Byte PPMD7_kExpEscape[16]; - -#ifdef PPMD_32BIT - #define Ppmd7_GetPtr(p, ptr) (ptr) - #define Ppmd7_GetContext(p, ptr) (ptr) - #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) -#else - #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) - #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) - #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) -#endif - -void Ppmd7_Update1(CPpmd7 *p); -void Ppmd7_Update1_0(CPpmd7 *p); -void Ppmd7_Update2(CPpmd7 *p); -void Ppmd7_UpdateBin(CPpmd7 *p); - -#define Ppmd7_GetBinSumm(p) \ - &p->BinSumm[(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ - p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ - (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ - 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \ - ((p->RunLength >> 26) & 0x20)] - -CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); - - -/* ---------- Decode ---------- */ - -typedef struct -{ - UInt32 (*GetThreshold)(void *p, UInt32 total); - void (*Decode)(void *p, UInt32 start, UInt32 size); - UInt32 (*DecodeBit)(void *p, UInt32 size0); -} IPpmd7_RangeDec; - -typedef struct -{ - IPpmd7_RangeDec p; - UInt32 Range; - UInt32 Code; - IByteIn *Stream; -} CPpmd7z_RangeDec; - -void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); -Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); -#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) - -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); - - -/* ---------- Encode ---------- */ - -typedef struct -{ - UInt64 Low; - UInt32 Range; - Byte Cache; - UInt64 CacheSize; - IByteOut *Stream; -} CPpmd7z_RangeEnc; - -void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); -void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); - -void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); - -EXTERN_C_END - -#endif +/* Ppmd7.h -- Ppmd7 (PPMdH) compression codec +2023-04-02 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001): Dmitry Shkarin : Public domain */ + + +#ifndef ZIP7_INC_PPMD7_H +#define ZIP7_INC_PPMD7_H + +#include "Ppmd.h" + +EXTERN_C_BEGIN + +#define PPMD7_MIN_ORDER 2 +#define PPMD7_MAX_ORDER 64 + +#define PPMD7_MIN_MEM_SIZE (1 << 11) +#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) + +struct CPpmd7_Context_; + +typedef Ppmd_Ref_Type(struct CPpmd7_Context_) CPpmd7_Context_Ref; + +// MY_CPU_pragma_pack_push_1 + +typedef struct CPpmd7_Context_ +{ + UInt16 NumStats; + + + union + { + UInt16 SummFreq; + CPpmd_State2 State2; + } Union2; + + union + { + CPpmd_State_Ref Stats; + CPpmd_State4 State4; + } Union4; + + CPpmd7_Context_Ref Suffix; +} CPpmd7_Context; + +// MY_CPU_pragma_pop + +#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->Union2) + + + + +typedef struct +{ + UInt32 Range; + UInt32 Code; + UInt32 Low; + IByteInPtr Stream; +} CPpmd7_RangeDec; + + +typedef struct +{ + UInt32 Range; + Byte Cache; + // Byte _dummy_[3]; + UInt64 Low; + UInt64 CacheSize; + IByteOutPtr Stream; +} CPpmd7z_RangeEnc; + + +typedef struct +{ + CPpmd7_Context *MinContext, *MaxContext; + CPpmd_State *FoundState; + unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; + Int32 RunLength, InitRL; /* must be 32-bit at least */ + + UInt32 Size; + UInt32 GlueCount; + UInt32 AlignOffset; + Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; + + + + + union + { + CPpmd7_RangeDec dec; + CPpmd7z_RangeEnc enc; + } rc; + + Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment + Byte Units2Indx[128]; + CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; + + Byte NS2BSIndx[256], NS2Indx[256]; + Byte ExpEscape[16]; + CPpmd_See DummySee, See[25][16]; + UInt16 BinSumm[128][64]; + // int LastSymbol; +} CPpmd7; + + +void Ppmd7_Construct(CPpmd7 *p); +BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc); +void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc); +void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); +#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) + + +/* ---------- Internal Functions ---------- */ + +#define Ppmd7_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr) +#define Ppmd7_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd7_Context) +#define Ppmd7_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State) + +void Ppmd7_Update1(CPpmd7 *p); +void Ppmd7_Update1_0(CPpmd7 *p); +void Ppmd7_Update2(CPpmd7 *p); + +#define PPMD7_HiBitsFlag_3(sym) ((((unsigned)sym + 0xC0) >> (8 - 3)) & (1 << 3)) +#define PPMD7_HiBitsFlag_4(sym) ((((unsigned)sym + 0xC0) >> (8 - 4)) & (1 << 4)) +// #define PPMD7_HiBitsFlag_3(sym) ((sym) < 0x40 ? 0 : (1 << 3)) +// #define PPMD7_HiBitsFlag_4(sym) ((sym) < 0x40 ? 0 : (1 << 4)) + +#define Ppmd7_GetBinSumm(p) \ + &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1] \ + [ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \ + + p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] \ + + PPMD7_HiBitsFlag_4(Ppmd7Context_OneState(p->MinContext)->Symbol) \ + + (p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol)) ] + +CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); + + +/* +We support two versions of Ppmd7 (PPMdH) methods that use same CPpmd7 structure: + 1) Ppmd7a_*: original PPMdH + 2) Ppmd7z_*: modified PPMdH with 7z Range Coder +Ppmd7_*: the structures and functions that are common for both versions of PPMd7 (PPMdH) +*/ + +/* ---------- Decode ---------- */ + +#define PPMD7_SYM_END (-1) +#define PPMD7_SYM_ERROR (-2) + +/* +You must set (CPpmd7::rc.dec.Stream) before Ppmd7*_RangeDec_Init() + +Ppmd7*_DecodeSymbol() +out: + >= 0 : decoded byte + -1 : PPMD7_SYM_END : End of payload marker + -2 : PPMD7_SYM_ERROR : Data error +*/ + +/* Ppmd7a_* : original PPMdH */ +BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p); +#define Ppmd7a_RangeDec_IsFinishedOK(p) ((p)->Code == 0) +int Ppmd7a_DecodeSymbol(CPpmd7 *p); + +/* Ppmd7z_* : modified PPMdH with 7z Range Coder */ +BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p); +#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) +int Ppmd7z_DecodeSymbol(CPpmd7 *p); +// Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim); + + +/* ---------- Encode ---------- */ + +void Ppmd7z_Init_RangeEnc(CPpmd7 *p); +void Ppmd7z_Flush_RangeEnc(CPpmd7 *p); +// void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol); +void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Ppmd7Dec.c p7zip-rar-16.02+really25.00+ds/C/Ppmd7Dec.c --- p7zip-rar-16.02/C/Ppmd7Dec.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd7Dec.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,189 +1,312 @@ -/* Ppmd7Dec.c -- PPMdH Decoder -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd7.h" - -#define kTopValue (1 << 24) - -Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) -{ - unsigned i; - p->Code = 0; - p->Range = 0xFFFFFFFF; - if (p->Stream->Read((void *)p->Stream) != 0) - return False; - for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - return (p->Code < 0xFFFFFFFF); -} - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - return (p->Code) / (p->Range /= total); -} - -static void Range_Normalize(CPpmd7z_RangeDec *p) -{ - if (p->Range < kTopValue) - { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - p->Range <<= 8; - if (p->Range < kTopValue) - { - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - p->Range <<= 8; - } - } -} - -static void Range_Decode(void *pp, UInt32 start, UInt32 size) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - p->Code -= start * p->Range; - p->Range *= size; - Range_Normalize(p); -} - -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - UInt32 newBound = (p->Range >> 14) * size0; - UInt32 symbol; - if (p->Code < newBound) - { - symbol = 0; - p->Range = newBound; - } - else - { - symbol = 1; - p->Code -= newBound; - p->Range -= newBound; - } - Range_Normalize(p); - return symbol; -} - -void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) -{ - p->p.GetThreshold = Range_GetThreshold; - p->p.Decode = Range_Decode; - p->p.DecodeBit = Range_DecodeBit; -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - unsigned i; - UInt32 count, hiCnt; - if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) - { - Byte symbol; - rc->Decode(rc, 0, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1_0(p); - return symbol; - } - p->PrevSuccess = 0; - i = p->MinContext->NumStats - 1; - do - { - if ((hiCnt += (++s)->Freq) > count) - { - Byte symbol; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1(p); - return symbol; - } - } - while (--i); - if (count >= p->MinContext->SummFreq) - return -2; - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - if (rc->DecodeBit(rc, *prob) == 0) - { - Byte symbol; - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; - Ppmd7_UpdateBin(p); - return symbol; - } - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; - p->PrevSuccess = 0; - } - for (;;) - { - CPpmd_State *ps[256], *s; - UInt32 freqSum, count, hiCnt; - CPpmd_See *see; - unsigned i, num, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return -1; - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - hiCnt = 0; - s = Ppmd7_GetStats(p, p->MinContext); - i = 0; - num = p->MinContext->NumStats - numMasked; - do - { - int k = (int)(MASK(s->Symbol)); - hiCnt += (s->Freq & k); - ps[i] = s++; - i -= k; - } - while (i != num); - - see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); - freqSum += hiCnt; - count = rc->GetThreshold(rc, freqSum); - - if (count < hiCnt) - { - Byte symbol; - CPpmd_State **pps = ps; - for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); - s = *pps; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - Ppmd_See_Update(see); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update2(p); - return symbol; - } - if (count >= freqSum) - return -2; - rc->Decode(rc, hiCnt, freqSum - hiCnt); - see->Summ = (UInt16)(see->Summ + freqSum); - do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); - } -} +/* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder +2023-09-07 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001): Dmitry Shkarin : Public domain */ + + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTopValue ((UInt32)1 << 24) + + +#define READ_BYTE(p) IByteIn_Read((p)->Stream) + +BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p) +{ + unsigned i; + p->Code = 0; + p->Range = 0xFFFFFFFF; + if (READ_BYTE(p) != 0) + return False; + for (i = 0; i < 4; i++) + p->Code = (p->Code << 8) | READ_BYTE(p); + return (p->Code < 0xFFFFFFFF); +} + +#define RC_NORM_BASE(p) if ((p)->Range < kTopValue) \ + { (p)->Code = ((p)->Code << 8) | READ_BYTE(p); (p)->Range <<= 8; + +#define RC_NORM_1(p) RC_NORM_BASE(p) } +#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +#define R (&p->rc.dec) + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) +{ + + + R->Code -= start * R->Range; + R->Range *= size; + RC_NORM_LOCAL(R) +} + +#define RC_Decode(start, size) Ppmd7z_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) + + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +// typedef CPpmd7_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) +void Ppmd7_UpdateModel(CPpmd7 *p); + +#define MASK(sym) ((Byte *)charMask)[sym] +// Z7_FORCE_INLINE +// static +int Ppmd7z_DecodeSymbol(CPpmd7 *p) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + unsigned i; + UInt32 count, hiCnt; + const UInt32 summFreq = p->MinContext->Union2.SummFreq; + + + + + count = RC_GetThreshold(summFreq); + hiCnt = count; + + if ((Int32)(count -= s->Freq) < 0) + { + Byte sym; + RC_DecodeFinal(0, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update1_0(p); + return sym; + } + + p->PrevSuccess = 0; + i = (unsigned)p->MinContext->NumStats - 1; + + do + { + if ((Int32)(count -= (++s)->Freq) < 0) + { + Byte sym; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update1(p); + return sym; + } + } + while (--i); + + if (hiCnt >= summFreq) + return PPMD7_SYM_ERROR; + + hiCnt -= count; + RC_Decode(hiCnt, summFreq - hiCnt) + + p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); + PPMD_SetAllBitsIn256Bytes(charMask) + // i = p->MinContext->NumStats - 1; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); + UInt16 *prob = Ppmd7_GetBinSumm(p); + UInt32 pr = *prob; + UInt32 size0 = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + + if (R->Code < size0) + { + Byte sym; + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + + // RangeDec_DecodeBit0(size0); + R->Range = size0; + RC_NORM_1(R) + /* we can use single byte normalization here because of + (min(BinSumm[][]) = 95) > (1 << (14 - 8)) */ + + // sym = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; + // Ppmd7_UpdateBin(p); + { + unsigned freq = s->Freq; + CPpmd7_Context *c = CTX(SUCCESSOR(s)); + sym = s->Symbol; + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 128)); + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c > p->Text) + p->MaxContext = p->MinContext = c; + else + Ppmd7_UpdateModel(p); + } + return sym; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + + // RangeDec_DecodeBit1(size0); + + R->Code -= size0; + R->Range -= size0; + RC_NORM_LOCAL(R) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_State *s, *s2; + UInt32 freqSum, count, hiCnt; + + CPpmd_See *see; + CPpmd7_Context *mc; + unsigned numMasked; + RC_NORM_REMOTE(R) + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return PPMD7_SYM_END; + mc = Ppmd7_GetContext(p, mc->Suffix); + } + while (mc->NumStats == numMasked); + + s = Ppmd7_GetStats(p, mc); + + { + unsigned num = mc->NumStats; + unsigned num2 = num / 2; + + num &= 1; + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); + s += num; + p->MinContext = mc; + + do + { + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; + s += 2; + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); + } + while (--num2); + } + + see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); + freqSum += hiCnt; + + + + + count = RC_GetThreshold(freqSum); + + if (count < hiCnt) + { + Byte sym; + + s = Ppmd7_GetStats(p, p->MinContext); + hiCnt = count; + // count -= s->Freq & (UInt32)(MASK(s->Symbol)); + // if ((Int32)count >= 0) + { + for (;;) + { + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + } + } + s--; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + + // new (see->Summ) value can overflow over 16-bits in some rare cases + Ppmd_See_UPDATE(see) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update2(p); + return sym; + } + + if (count >= freqSum) + return PPMD7_SYM_ERROR; + + RC_Decode(hiCnt, freqSum - hiCnt) + + // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. + // new (see->Summ) value can overflow over 16-bits in some rare cases + see->Summ = (UInt16)(see->Summ + freqSum); + + s = Ppmd7_GetStats(p, p->MinContext); + s2 = s + p->MinContext->NumStats; + do + { + MASK(s->Symbol) = 0; + s++; + } + while (s != s2); + } +} + +/* +Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim) +{ + int sym = 0; + if (buf != lim) + do + { + sym = Ppmd7z_DecodeSymbol(p); + if (sym < 0) + break; + *buf = (Byte)sym; + } + while (++buf < lim); + p->LastSymbol = sym; + return buf; +} +*/ + +#undef kTopValue +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru p7zip-rar-16.02/C/Ppmd7Enc.c p7zip-rar-16.02+really25.00+ds/C/Ppmd7Enc.c --- p7zip-rar-16.02/C/Ppmd7Enc.c 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd7Enc.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,187 +1,337 @@ -/* Ppmd7Enc.c -- PPMdH Encoder -2015-09-28 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd7.h" - -#define kTopValue (1 << 24) - -void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p) -{ - p->Low = 0; - p->Range = 0xFFFFFFFF; - p->Cache = 0; - p->CacheSize = 1; -} - -static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) -{ - if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0) - { - Byte temp = p->Cache; - do - { - p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); - temp = 0xFF; - } - while (--p->CacheSize != 0); - p->Cache = (Byte)((UInt32)p->Low >> 24); - } - p->CacheSize++; - p->Low = (UInt32)p->Low << 8; -} - -static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) -{ - p->Low += start * (p->Range /= total); - p->Range *= size; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - p->Range = (p->Range >> 14) * size0; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - UInt32 newBound = (p->Range >> 14) * size0; - p->Low += newBound; - p->Range -= newBound; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p) -{ - unsigned i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - UInt32 sum; - unsigned i; - if (s->Symbol == symbol) - { - RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1_0(p); - return; - } - p->PrevSuccess = 0; - sum = s->Freq; - i = p->MinContext->NumStats - 1; - do - { - if ((++s)->Symbol == symbol) - { - RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1(p); - return; - } - sum += s->Freq; - } - while (--i); - - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); - if (s->Symbol == symbol) - { - RangeEnc_EncodeBit_0(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - p->FoundState = s; - Ppmd7_UpdateBin(p); - return; - } - else - { - RangeEnc_EncodeBit_1(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - p->PrevSuccess = 0; - } - } - for (;;) - { - UInt32 escFreq; - CPpmd_See *see; - CPpmd_State *s; - UInt32 sum; - unsigned i, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return; /* EndMarker (symbol = -1) */ - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - - see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); - s = Ppmd7_GetStats(p, p->MinContext); - sum = 0; - i = p->MinContext->NumStats; - do - { - int cur = s->Symbol; - if (cur == symbol) - { - UInt32 low = sum; - CPpmd_State *s1 = s; - do - { - sum += (s->Freq & (int)(MASK(s->Symbol))); - s++; - } - while (--i); - RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq); - Ppmd_See_Update(see); - p->FoundState = s1; - Ppmd7_Update2(p); - return; - } - sum += (s->Freq & (int)(MASK(cur))); - MASK(cur) = 0; - s++; - } - while (--i); - - RangeEnc_Encode(rc, sum, escFreq, sum + escFreq); - see->Summ = (UInt16)(see->Summ + sum + escFreq); - } -} +/* Ppmd7Enc.c -- Ppmd7z (PPMdH with 7z Range Coder) Encoder +2023-09-07 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001): Dmitry Shkarin : Public domain */ + + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTopValue ((UInt32)1 << 24) + +#define R (&p->rc.enc) + +void Ppmd7z_Init_RangeEnc(CPpmd7 *p) +{ + R->Low = 0; + R->Range = 0xFFFFFFFF; + R->Cache = 0; + R->CacheSize = 1; +} + +Z7_NO_INLINE +static void Ppmd7z_RangeEnc_ShiftLow(CPpmd7 *p) +{ + if ((UInt32)R->Low < (UInt32)0xFF000000 || (unsigned)(R->Low >> 32) != 0) + { + Byte temp = R->Cache; + do + { + IByteOut_Write(R->Stream, (Byte)(temp + (Byte)(R->Low >> 32))); + temp = 0xFF; + } + while (--R->CacheSize != 0); + R->Cache = (Byte)((UInt32)R->Low >> 24); + } + R->CacheSize++; + R->Low = (UInt32)((UInt32)R->Low << 8); +} + +#define RC_NORM_BASE(p) if (R->Range < kTopValue) { R->Range <<= 8; Ppmd7z_RangeEnc_ShiftLow(p); +#define RC_NORM_1(p) RC_NORM_BASE(p) } +#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +/* +#define Ppmd7z_RangeEnc_Encode(p, start, _size_) \ + { UInt32 size = _size_; \ + R->Low += start * R->Range; \ + R->Range *= size; \ + RC_NORM_LOCAL(p); } +*/ + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RangeEnc_Encode(CPpmd7 *p, UInt32 start, UInt32 size) +{ + R->Low += start * R->Range; + R->Range *= size; + RC_NORM_LOCAL(p) +} + +void Ppmd7z_Flush_RangeEnc(CPpmd7 *p) +{ + unsigned i; + for (i = 0; i < 5; i++) + Ppmd7z_RangeEnc_ShiftLow(p); +} + + + +#define RC_Encode(start, size) Ppmd7z_RangeEnc_Encode(p, start, size); +#define RC_EncodeFinal(start, size) RC_Encode(start, size) RC_NORM_REMOTE(p) + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +#define SUFFIX(ctx) CTX((ctx)->Suffix) +// typedef CPpmd7_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) + +void Ppmd7_UpdateModel(CPpmd7 *p); + +#define MASK(sym) ((Byte *)charMask)[sym] + +Z7_FORCE_INLINE +static +void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + UInt32 sum; + unsigned i; + + + + + R->Range /= p->MinContext->Union2.SummFreq; + + if (s->Symbol == symbol) + { + // R->Range /= p->MinContext->Union2.SummFreq; + RC_EncodeFinal(0, s->Freq) + p->FoundState = s; + Ppmd7_Update1_0(p); + return; + } + p->PrevSuccess = 0; + sum = s->Freq; + i = (unsigned)p->MinContext->NumStats - 1; + do + { + if ((++s)->Symbol == symbol) + { + // R->Range /= p->MinContext->Union2.SummFreq; + RC_EncodeFinal(sum, s->Freq) + p->FoundState = s; + Ppmd7_Update1(p); + return; + } + sum += s->Freq; + } + while (--i); + + // R->Range /= p->MinContext->Union2.SummFreq; + RC_Encode(sum, p->MinContext->Union2.SummFreq - sum) + + p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); + PPMD_SetAllBitsIn256Bytes(charMask) + // MASK(s->Symbol) = 0; + // i = p->MinContext->NumStats - 1; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + UInt16 *prob = Ppmd7_GetBinSumm(p); + CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); + UInt32 pr = *prob; + const UInt32 bound = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + if (s->Symbol == symbol) + { + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + // RangeEnc_EncodeBit_0(p, bound); + R->Range = bound; + RC_NORM_1(p) + + // p->FoundState = s; + // Ppmd7_UpdateBin(p); + { + const unsigned freq = s->Freq; + CPpmd7_Context *c = CTX(SUCCESSOR(s)); + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 128)); + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c > p->Text) + p->MaxContext = p->MinContext = c; + else + Ppmd7_UpdateModel(p); + } + return; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + // RangeEnc_EncodeBit_1(p, bound); + R->Low += bound; + R->Range -= bound; + RC_NORM_LOCAL(p) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(s->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_See *see; + CPpmd_State *s; + UInt32 sum, escFreq; + CPpmd7_Context *mc; + unsigned i, numMasked; + + RC_NORM_REMOTE(p) + + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return; /* EndMarker (symbol = -1) */ + mc = Ppmd7_GetContext(p, mc->Suffix); + i = mc->NumStats; + } + while (i == numMasked); + + p->MinContext = mc; + + // see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); + { + if (i != 256) + { + unsigned nonMasked = i - numMasked; + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] + + p->HiBitsFlag + + (nonMasked < (unsigned)SUFFIX(mc)->NumStats - i) + + 2 * (unsigned)(mc->Union2.SummFreq < 11 * i) + + 4 * (unsigned)(numMasked > nonMasked); + { + // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ + unsigned summ = (UInt16)see->Summ; // & 0xFFFF + unsigned r = (summ >> see->Shift); + see->Summ = (UInt16)(summ - r); + escFreq = r + (r == 0); + } + } + else + { + see = &p->DummySee; + escFreq = 1; + } + } + + s = Ppmd7_GetStats(p, mc); + sum = 0; + // i = mc->NumStats; + + do + { + const unsigned cur = s->Symbol; + if ((int)cur == symbol) + { + const UInt32 low = sum; + const UInt32 freq = s->Freq; + unsigned num2; + + Ppmd_See_UPDATE(see) + p->FoundState = s; + sum += escFreq; + + num2 = i / 2; + i &= 1; + sum += freq & (0 - (UInt32)i); + if (num2 != 0) + { + s += i; + do + { + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; + s += 2; + sum += (s[-2].Freq & (unsigned)(MASK(sym0))); + sum += (s[-1].Freq & (unsigned)(MASK(sym1))); + } + while (--num2); + } + + + R->Range /= sum; + RC_EncodeFinal(low, freq) + Ppmd7_Update2(p); + return; + } + sum += (s->Freq & (unsigned)(MASK(cur))); + s++; + } + while (--i); + + { + const UInt32 total = sum + escFreq; + see->Summ = (UInt16)(see->Summ + total); + + R->Range /= total; + RC_Encode(sum, escFreq) + } + + { + const CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + s--; + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } +} + + +void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim) +{ + for (; buf < lim; buf++) + { + Ppmd7z_EncodeSymbol(p, *buf); + } +} + +#undef kTopValue +#undef WRITE_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Encode +#undef RC_EncodeFinal +#undef SUFFIX +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru p7zip-rar-16.02/C/Ppmd7aDec.c p7zip-rar-16.02+really25.00+ds/C/Ppmd7aDec.c --- p7zip-rar-16.02/C/Ppmd7aDec.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd7aDec.c 2023-09-07 11:00:00.000000000 +0000 @@ -0,0 +1,295 @@ +/* Ppmd7aDec.c -- PPMd7a (PPMdH) Decoder +2023-09-07 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001): Dmitry Shkarin : Public domain + Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) + +#define READ_BYTE(p) IByteIn_Read((p)->Stream) + +BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p) +{ + unsigned i; + p->Code = 0; + p->Range = 0xFFFFFFFF; + p->Low = 0; + + for (i = 0; i < 4; i++) + p->Code = (p->Code << 8) | READ_BYTE(p); + return (p->Code < 0xFFFFFFFF); +} + +#define RC_NORM(p) \ + while ((p->Low ^ (p->Low + p->Range)) < kTop \ + || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) { \ + p->Code = (p->Code << 8) | READ_BYTE(p); \ + p->Range <<= 8; p->Low <<= 8; } + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +#define R (&p->rc.dec) + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7a_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) +{ + start *= R->Range; + R->Low += start; + R->Code -= start; + R->Range *= size; + RC_NORM_LOCAL(R) +} + +#define RC_Decode(start, size) Ppmd7a_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) + + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +typedef CPpmd7_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) +void Ppmd7_UpdateModel(CPpmd7 *p); + +#define MASK(sym) ((Byte *)charMask)[sym] + + +int Ppmd7a_DecodeSymbol(CPpmd7 *p) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + unsigned i; + UInt32 count, hiCnt; + const UInt32 summFreq = p->MinContext->Union2.SummFreq; + + if (summFreq > R->Range) + return PPMD7_SYM_ERROR; + + count = RC_GetThreshold(summFreq); + hiCnt = count; + + if ((Int32)(count -= s->Freq) < 0) + { + Byte sym; + RC_DecodeFinal(0, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update1_0(p); + return sym; + } + + p->PrevSuccess = 0; + i = (unsigned)p->MinContext->NumStats - 1; + + do + { + if ((Int32)(count -= (++s)->Freq) < 0) + { + Byte sym; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update1(p); + return sym; + } + } + while (--i); + + if (hiCnt >= summFreq) + return PPMD7_SYM_ERROR; + + hiCnt -= count; + RC_Decode(hiCnt, summFreq - hiCnt) + + p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); + PPMD_SetAllBitsIn256Bytes(charMask) + // i = p->MinContext->NumStats - 1; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); + UInt16 *prob = Ppmd7_GetBinSumm(p); + UInt32 pr = *prob; + UInt32 size0 = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + + if (R->Code < size0) + { + Byte sym; + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + + // RangeDec_DecodeBit0(size0); + R->Range = size0; + RC_NORM(R) + + + + // sym = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; + // Ppmd7_UpdateBin(p); + { + unsigned freq = s->Freq; + CTX_PTR c = CTX(SUCCESSOR(s)); + sym = s->Symbol; + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 128)); + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c > p->Text) + p->MaxContext = p->MinContext = c; + else + Ppmd7_UpdateModel(p); + } + return sym; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + + // RangeDec_DecodeBit1(size0); + R->Low += size0; + R->Code -= size0; + R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0; + RC_NORM_LOCAL(R) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_State *s, *s2; + UInt32 freqSum, count, hiCnt; + + CPpmd_See *see; + CPpmd7_Context *mc; + unsigned numMasked; + RC_NORM_REMOTE(R) + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return PPMD7_SYM_END; + mc = Ppmd7_GetContext(p, mc->Suffix); + } + while (mc->NumStats == numMasked); + + s = Ppmd7_GetStats(p, mc); + + { + unsigned num = mc->NumStats; + unsigned num2 = num / 2; + + num &= 1; + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); + s += num; + p->MinContext = mc; + + do + { + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; + s += 2; + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); + } + while (--num2); + } + + see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); + freqSum += hiCnt; + + if (freqSum > R->Range) + return PPMD7_SYM_ERROR; + + count = RC_GetThreshold(freqSum); + + if (count < hiCnt) + { + Byte sym; + + s = Ppmd7_GetStats(p, p->MinContext); + hiCnt = count; + // count -= s->Freq & (UInt32)(MASK(s->Symbol)); + // if ((Int32)count >= 0) + { + for (;;) + { + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + } + } + s--; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + + // new (see->Summ) value can overflow over 16-bits in some rare cases + Ppmd_See_UPDATE(see) + p->FoundState = s; + sym = s->Symbol; + Ppmd7_Update2(p); + return sym; + } + + if (count >= freqSum) + return PPMD7_SYM_ERROR; + + RC_Decode(hiCnt, freqSum - hiCnt) + + // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. + // new (see->Summ) value can overflow over 16-bits in some rare cases + see->Summ = (UInt16)(see->Summ + freqSum); + + s = Ppmd7_GetStats(p, p->MinContext); + s2 = s + p->MinContext->NumStats; + do + { + MASK(s->Symbol) = 0; + s++; + } + while (s != s2); + } +} + +#undef kTop +#undef kBot +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru p7zip-rar-16.02/C/Ppmd8.c p7zip-rar-16.02+really25.00+ds/C/Ppmd8.c --- p7zip-rar-16.02/C/Ppmd8.c 2016-06-11 08:08:05.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd8.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,1123 +1,1574 @@ -/* Ppmd8.c -- PPMdI codec -2016-05-21 : Igor Pavlov : Public domain -This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ - -#include "Precomp.h" - -#include - -#include "Ppmd8.h" - -const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; - -#define MAX_FREQ 124 -#define UNIT_SIZE 12 - -#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) -#define I2U(indx) (p->Indx2Units[indx]) - -#ifdef PPMD_32BIT - #define REF(ptr) (ptr) -#else - #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) -#endif - -#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) - -#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) -#define STATS(ctx) Ppmd8_GetStats(p, ctx) -#define ONE_STATE(ctx) Ppmd8Context_OneState(ctx) -#define SUFFIX(ctx) CTX((ctx)->Suffix) - -typedef CPpmd8_Context * CTX_PTR; - -struct CPpmd8_Node_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd8_Node_ * - #else - UInt32 - #endif - CPpmd8_Node_Ref; - -typedef struct CPpmd8_Node_ -{ - UInt32 Stamp; - CPpmd8_Node_Ref Next; - UInt32 NU; -} CPpmd8_Node; - -#ifdef PPMD_32BIT - #define NODE(ptr) (ptr) -#else - #define NODE(offs) ((CPpmd8_Node *)(p->Base + (offs))) -#endif - -#define EMPTY_NODE 0xFFFFFFFF - -void Ppmd8_Construct(CPpmd8 *p) -{ - unsigned i, k, m; - - p->Base = 0; - - for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) - { - unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while (--step); - p->Indx2Units[i] = (Byte)k; - } - - p->NS2BSIndx[0] = (0 << 1); - p->NS2BSIndx[1] = (1 << 1); - memset(p->NS2BSIndx + 2, (2 << 1), 9); - memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); - - for (i = 0; i < 5; i++) - p->NS2Indx[i] = (Byte)i; - for (m = i, k = 1; i < 260; i++) - { - p->NS2Indx[i] = (Byte)m; - if (--k == 0) - k = (++m) - 4; - } -} - -void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->Base); - p->Size = 0; - p->Base = 0; -} - -Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc) -{ - if (p->Base == 0 || p->Size != size) - { - Ppmd8_Free(p, alloc); - p->AlignOffset = - #ifdef PPMD_32BIT - (4 - size) & 3; - #else - 4 - (size & 3); - #endif - if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size)) == 0) - return False; - p->Size = size; - } - return True; -} - -static void InsertNode(CPpmd8 *p, void *node, unsigned indx) -{ - ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE; - ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx]; - ((CPpmd8_Node *)node)->NU = I2U(indx); - p->FreeList[indx] = REF(node); - p->Stamps[indx]++; -} - -static void *RemoveNode(CPpmd8 *p, unsigned indx) -{ - CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]); - p->FreeList[indx] = node->Next; - p->Stamps[indx]--; - return node; -} - -static void SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx) -{ - unsigned i, nu = I2U(oldIndx) - I2U(newIndx); - ptr = (Byte *)ptr + U2B(I2U(newIndx)); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); - } - InsertNode(p, ptr, i); -} - -static void GlueFreeBlocks(CPpmd8 *p) -{ - CPpmd8_Node_Ref head = 0; - CPpmd8_Node_Ref *prev = &head; - unsigned i; - - p->GlueCount = 1 << 13; - memset(p->Stamps, 0, sizeof(p->Stamps)); - - /* Order-0 context is always at top UNIT, so we don't need guard NODE at the end. - All blocks up to p->LoUnit can be free, so we need guard NODE at LoUnit. */ - if (p->LoUnit != p->HiUnit) - ((CPpmd8_Node *)p->LoUnit)->Stamp = 0; - - /* Glue free blocks */ - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - CPpmd8_Node_Ref next = (CPpmd8_Node_Ref)p->FreeList[i]; - p->FreeList[i] = 0; - while (next != 0) - { - CPpmd8_Node *node = NODE(next); - if (node->NU != 0) - { - CPpmd8_Node *node2; - *prev = next; - prev = &(node->Next); - while ((node2 = node + node->NU)->Stamp == EMPTY_NODE) - { - node->NU += node2->NU; - node2->NU = 0; - } - } - next = node->Next; - } - } - *prev = 0; - - /* Fill lists of free blocks */ - while (head != 0) - { - CPpmd8_Node *node = NODE(head); - unsigned nu; - head = node->Next; - nu = node->NU; - if (nu == 0) - continue; - for (; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, node + k, nu - k - 1); - } - InsertNode(p, node, i); - } -} - -static void *AllocUnitsRare(CPpmd8 *p, unsigned indx) -{ - unsigned i; - void *retVal; - if (p->GlueCount == 0) - { - GlueFreeBlocks(p); - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - } - i = indx; - do - { - if (++i == PPMD_NUM_INDEXES) - { - UInt32 numBytes = U2B(I2U(indx)); - p->GlueCount--; - return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); - } - } - while (p->FreeList[i] == 0); - retVal = RemoveNode(p, i); - SplitBlock(p, retVal, i, indx); - return retVal; -} - -static void *AllocUnits(CPpmd8 *p, unsigned indx) -{ - UInt32 numBytes; - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - numBytes = U2B(I2U(indx)); - if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) - { - void *retVal = p->LoUnit; - p->LoUnit += numBytes; - return retVal; - } - return AllocUnitsRare(p, indx); -} - -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } - -static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) -{ - unsigned i0 = U2I(oldNU); - unsigned i1 = U2I(newNU); - if (i0 == i1) - return oldPtr; - if (p->FreeList[i1] != 0) - { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); - return ptr; - } - SplitBlock(p, oldPtr, i0, i1); - return oldPtr; -} - -static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu) -{ - InsertNode(p, ptr, U2I(nu)); -} - -static void SpecialFreeUnit(CPpmd8 *p, void *ptr) -{ - if ((Byte *)ptr != p->UnitsStart) - InsertNode(p, ptr, 0); - else - { - #ifdef PPMD8_FREEZE_SUPPORT - *(UInt32 *)ptr = EMPTY_NODE; /* it's used for (Flags == 0xFF) check in RemoveBinContexts */ - #endif - p->UnitsStart += UNIT_SIZE; - } -} - -static void *MoveUnitsUp(CPpmd8 *p, void *oldPtr, unsigned nu) -{ - unsigned indx = U2I(nu); - void *ptr; - if ((Byte *)oldPtr > p->UnitsStart + 16 * 1024 || REF(oldPtr) > p->FreeList[indx]) - return oldPtr; - ptr = RemoveNode(p, indx); - MyMem12Cpy(ptr, oldPtr, nu); - if ((Byte*)oldPtr != p->UnitsStart) - InsertNode(p, oldPtr, indx); - else - p->UnitsStart += U2B(I2U(indx)); - return ptr; -} - -static void ExpandTextArea(CPpmd8 *p) -{ - UInt32 count[PPMD_NUM_INDEXES]; - unsigned i; - memset(count, 0, sizeof(count)); - if (p->LoUnit != p->HiUnit) - ((CPpmd8_Node *)p->LoUnit)->Stamp = 0; - - { - CPpmd8_Node *node = (CPpmd8_Node *)p->UnitsStart; - for (; node->Stamp == EMPTY_NODE; node += node->NU) - { - node->Stamp = 0; - count[U2I(node->NU)]++; - } - p->UnitsStart = (Byte *)node; - } - - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - CPpmd8_Node_Ref *next = (CPpmd8_Node_Ref *)&p->FreeList[i]; - while (count[i] != 0) - { - CPpmd8_Node *node = NODE(*next); - while (node->Stamp == 0) - { - *next = node->Next; - node = NODE(*next); - p->Stamps[i]--; - if (--count[i] == 0) - break; - } - next = &node->Next; - } - } -} - -#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) - -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) -{ - (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); -} - -#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); } - -static void RestartModel(CPpmd8 *p) -{ - unsigned i, k, m, r; - - memset(p->FreeList, 0, sizeof(p->FreeList)); - memset(p->Stamps, 0, sizeof(p->Stamps)); - RESET_TEXT(0); - p->HiUnit = p->Text + p->Size; - p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; - p->GlueCount = 0; - - p->OrderFall = p->MaxOrder; - p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; - p->PrevSuccess = 0; - - p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - p->MinContext->Suffix = 0; - p->MinContext->NumStats = 255; - p->MinContext->Flags = 0; - p->MinContext->SummFreq = 256 + 1; - p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ - p->LoUnit += U2B(256 / 2); - p->MinContext->Stats = REF(p->FoundState); - for (i = 0; i < 256; i++) - { - CPpmd_State *s = &p->FoundState[i]; - s->Symbol = (Byte)i; - s->Freq = 1; - SetSuccessor(s, 0); - } - - for (i = m = 0; m < 25; m++) - { - while (p->NS2Indx[i] == m) - i++; - for (k = 0; k < 8; k++) - { - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 1)); - UInt16 *dest = p->BinSumm[m] + k; - for (r = 0; r < 64; r += 8) - dest[r] = val; - } - } - - for (i = m = 0; m < 24; m++) - { - while (p->NS2Indx[i + 3] == m + 3) - i++; - for (k = 0; k < 32; k++) - { - CPpmd_See *s = &p->See[m][k]; - s->Summ = (UInt16)((2 * i + 5) << (s->Shift = PPMD_PERIOD_BITS - 4)); - s->Count = 7; - } - } -} - -void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod) -{ - p->MaxOrder = maxOrder; - p->RestoreMethod = restoreMethod; - RestartModel(p); - p->DummySee.Shift = PPMD_PERIOD_BITS; - p->DummySee.Summ = 0; /* unused */ - p->DummySee.Count = 64; /* unused */ -} - -static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale) -{ - unsigned i = ctx->NumStats, escFreq, sumFreq, flags; - CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1); - ctx->Stats = REF(s); - #ifdef PPMD8_FREEZE_SUPPORT - /* fixed over Shkarin's code. Fixed code is not compatible with original code for some files in FREEZE mode. */ - scale |= (ctx->SummFreq >= ((UInt32)1 << 15)); - #endif - flags = (ctx->Flags & (0x10 + 0x04 * scale)) + 0x08 * (s->Symbol >= 0x40); - escFreq = ctx->SummFreq - s->Freq; - sumFreq = (s->Freq = (Byte)((s->Freq + scale) >> scale)); - do - { - escFreq -= (++s)->Freq; - sumFreq += (s->Freq = (Byte)((s->Freq + scale) >> scale)); - flags |= 0x08 * (s->Symbol >= 0x40); - } - while (--i); - ctx->SummFreq = (UInt16)(sumFreq + ((escFreq + scale) >> scale)); - ctx->Flags = (Byte)flags; -} - -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) -{ - CPpmd_State tmp = *t1; - *t1 = *t2; - *t2 = tmp; -} - -static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order) -{ - int i; - unsigned tmp; - CPpmd_State *s; - - if (!ctx->NumStats) - { - s = ONE_STATE(ctx); - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart) - { - if (order < p->MaxOrder) - SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - if (SUCCESSOR(s) || order <= 9) /* O_BOUND */ - return REF(ctx); - } - SpecialFreeUnit(p, ctx); - return 0; - } - - ctx->Stats = STATS_REF(MoveUnitsUp(p, STATS(ctx), tmp = ((unsigned)ctx->NumStats + 2) >> 1)); - - for (s = STATS(ctx) + (i = ctx->NumStats); s >= STATS(ctx); s--) - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) < p->UnitsStart) - { - CPpmd_State *s2 = STATS(ctx) + (i--); - SetSuccessor(s, 0); - SwapStates(s, s2); - } - else if (order < p->MaxOrder) - SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - - if (i != ctx->NumStats && order) - { - ctx->NumStats = (Byte)i; - s = STATS(ctx); - if (i < 0) - { - FreeUnits(p, s, tmp); - SpecialFreeUnit(p, ctx); - return 0; - } - if (i == 0) - { - ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40)); - *ONE_STATE(ctx) = *s; - FreeUnits(p, s, tmp); - /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */ - ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3); - } - else - Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i); - } - return REF(ctx); -} - -#ifdef PPMD8_FREEZE_SUPPORT -static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, CTX_PTR ctx, unsigned order) -{ - CPpmd_State *s; - if (!ctx->NumStats) - { - s = ONE_STATE(ctx); - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder) - SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - /* Suffix context can be removed already, since different (high-order) - Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */ - if (!SUCCESSOR(s) && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF)) - { - FreeUnits(p, ctx, 1); - return 0; - } - else - return REF(ctx); - } - - for (s = STATS(ctx) + ctx->NumStats; s >= STATS(ctx); s--) - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder) - SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - - return REF(ctx); -} -#endif - -static UInt32 GetUsedMemory(const CPpmd8 *p) -{ - UInt32 v = 0; - unsigned i; - for (i = 0; i < PPMD_NUM_INDEXES; i++) - v += p->Stamps[i] * I2U(i); - return p->Size - (UInt32)(p->HiUnit - p->LoUnit) - (UInt32)(p->UnitsStart - p->Text) - U2B(v); -} - -#ifdef PPMD8_FREEZE_SUPPORT - #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1, fSuccessor) -#else - #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1) -#endif - -static void RestoreModel(CPpmd8 *p, CTX_PTR c1 - #ifdef PPMD8_FREEZE_SUPPORT - , CTX_PTR fSuccessor - #endif - ) -{ - CTX_PTR c; - CPpmd_State *s; - RESET_TEXT(0); - for (c = p->MaxContext; c != c1; c = SUFFIX(c)) - if (--(c->NumStats) == 0) - { - s = STATS(c); - c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40)); - *ONE_STATE(c) = *s; - SpecialFreeUnit(p, s); - ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3); - } - else - Refresh(p, c, (c->NumStats+3) >> 1, 0); - - for (; c != p->MinContext; c = SUFFIX(c)) - if (!c->NumStats) - ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1)); - else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats) - Refresh(p, c, (c->NumStats + 2) >> 1, 1); - - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - p->MaxContext = fSuccessor; - p->GlueCount += !(p->Stamps[1] & 1); - } - else if (p->RestoreMethod == PPMD8_RESTORE_METHOD_FREEZE) - { - while (p->MaxContext->Suffix) - p->MaxContext = SUFFIX(p->MaxContext); - RemoveBinContexts(p, p->MaxContext, 0); - p->RestoreMethod++; - p->GlueCount = 0; - p->OrderFall = p->MaxOrder; - } - else - #endif - if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1)) - RestartModel(p); - else - { - while (p->MaxContext->Suffix) - p->MaxContext = SUFFIX(p->MaxContext); - do - { - CutOff(p, p->MaxContext, 0); - ExpandTextArea(p); - } - while (GetUsedMemory(p) > 3 * (p->Size >> 2)); - p->GlueCount = 0; - p->OrderFall = p->MaxOrder; - } -} - -static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c) -{ - CPpmd_State upState; - Byte flags; - CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); - /* fixed over Shkarin's code. Maybe it could work without + 1 too. */ - CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; - unsigned numPs = 0; - - if (!skip) - ps[numPs++] = p->FoundState; - - while (c->Suffix) - { - CPpmd_Void_Ref successor; - CPpmd_State *s; - c = SUFFIX(c); - if (s1) - { - s = s1; - s1 = NULL; - } - else if (c->NumStats != 0) - { - for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); - if (s->Freq < MAX_FREQ - 9) - { - s->Freq++; - c->SummFreq++; - } - } - else - { - s = ONE_STATE(c); - s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24))); - } - successor = SUCCESSOR(s); - if (successor != upBranch) - { - c = CTX(successor); - if (numPs == 0) - return c; - break; - } - ps[numPs++] = s; - } - - upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch); - SetSuccessor(&upState, upBranch + 1); - flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40)); - - if (c->NumStats == 0) - upState.Freq = ONE_STATE(c)->Freq; - else - { - UInt32 cf, s0; - CPpmd_State *s; - for (s = STATS(c); s->Symbol != upState.Symbol; s++); - cf = s->Freq - 1; - s0 = c->SummFreq - c->NumStats - cf; - upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0))); - } - - do - { - /* Create Child */ - CTX_PTR c1; /* = AllocContext(p); */ - if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); - else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); - else - { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); - if (!c1) - return NULL; - } - c1->NumStats = 0; - c1->Flags = flags; - *ONE_STATE(c1) = upState; - c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); - c = c1; - } - while (numPs != 0); - - return c; -} - -static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c) -{ - CPpmd_State *s = NULL; - CTX_PTR c1 = c; - CPpmd_Void_Ref upBranch = REF(p->Text); - - #ifdef PPMD8_FREEZE_SUPPORT - /* The BUG in Shkarin's code was fixed: ps could overflow in CUT_OFF mode. */ - CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; - unsigned numPs = 0; - ps[numPs++] = p->FoundState; - #endif - - SetSuccessor(p->FoundState, upBranch); - p->OrderFall++; - - for (;;) - { - if (s1) - { - c = SUFFIX(c); - s = s1; - s1 = NULL; - } - else - { - if (!c->Suffix) - { - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); - p->OrderFall = 1; - } - #endif - return c; - } - c = SUFFIX(c); - if (c->NumStats) - { - if ((s = STATS(c))->Symbol != p->FoundState->Symbol) - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - else - { - s = ONE_STATE(c); - s->Freq = (Byte)(s->Freq + (s->Freq < 32)); - } - } - if (SUCCESSOR(s)) - break; - #ifdef PPMD8_FREEZE_SUPPORT - ps[numPs++] = s; - #endif - SetSuccessor(s, upBranch); - p->OrderFall++; - } - - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - c = CTX(SUCCESSOR(s)); - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); - p->OrderFall = 1; - return c; - } - else - #endif - if (SUCCESSOR(s) <= upBranch) - { - CTX_PTR successor; - CPpmd_State *s2 = p->FoundState; - p->FoundState = s; - - successor = CreateSuccessors(p, False, NULL, c); - if (successor == NULL) - SetSuccessor(s, 0); - else - SetSuccessor(s, REF(successor)); - p->FoundState = s2; - } - - if (p->OrderFall == 1 && c1 == p->MaxContext) - { - SetSuccessor(p->FoundState, SUCCESSOR(s)); - p->Text--; - } - if (SUCCESSOR(s) == 0) - return NULL; - return CTX(SUCCESSOR(s)); -} - -static void UpdateModel(CPpmd8 *p) -{ - CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; - unsigned s0, ns, fFreq = p->FoundState->Freq; - Byte flag, fSymbol = p->FoundState->Symbol; - CPpmd_State *s = NULL; - - if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) - { - c = SUFFIX(p->MinContext); - - if (c->NumStats == 0) - { - s = ONE_STATE(c); - if (s->Freq < 32) - s->Freq++; - } - else - { - s = STATS(c); - if (s->Symbol != p->FoundState->Symbol) - { - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s[0].Freq >= s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - s--; - } - } - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - } - - c = p->MaxContext; - if (p->OrderFall == 0 && fSuccessor) - { - CTX_PTR cs = CreateSuccessors(p, True, s, p->MinContext); - if (cs == 0) - { - SetSuccessor(p->FoundState, 0); - RESTORE_MODEL(c, CTX(fSuccessor)); - } - else - { - SetSuccessor(p->FoundState, REF(cs)); - p->MaxContext = cs; - } - return; - } - - *p->Text++ = p->FoundState->Symbol; - successor = REF(p->Text); - if (p->Text >= p->UnitsStart) - { - RESTORE_MODEL(c, CTX(fSuccessor)); /* check it */ - return; - } - - if (!fSuccessor) - { - CTX_PTR cs = ReduceOrder(p, s, p->MinContext); - if (cs == NULL) - { - RESTORE_MODEL(c, 0); - return; - } - fSuccessor = REF(cs); - } - else if ((Byte *)Ppmd8_GetPtr(p, fSuccessor) < p->UnitsStart) - { - CTX_PTR cs = CreateSuccessors(p, False, s, p->MinContext); - if (cs == NULL) - { - RESTORE_MODEL(c, 0); - return; - } - fSuccessor = REF(cs); - } - - if (--p->OrderFall == 0) - { - successor = fSuccessor; - p->Text -= (p->MaxContext != p->MinContext); - } - #ifdef PPMD8_FREEZE_SUPPORT - else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - successor = fSuccessor; - RESET_TEXT(0); - p->OrderFall = 0; - } - #endif - - s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq; - flag = (Byte)(0x08 * (fSymbol >= 0x40)); - - for (; c != p->MinContext; c = SUFFIX(c)) - { - unsigned ns1; - UInt32 cf, sf; - if ((ns1 = c->NumStats) != 0) - { - if ((ns1 & 1) != 0) - { - /* Expand for one UNIT */ - unsigned oldNU = (ns1 + 1) >> 1; - unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) - { - void *ptr = AllocUnits(p, i + 1); - void *oldPtr; - if (!ptr) - { - RESTORE_MODEL(c, CTX(fSuccessor)); - return; - } - oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); - c->Stats = STATS_REF(ptr); - } - } - c->SummFreq = (UInt16)(c->SummFreq + (3 * ns1 + 1 < ns)); - } - else - { - CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0); - if (!s2) - { - RESTORE_MODEL(c, CTX(fSuccessor)); - return; - } - *s2 = *ONE_STATE(c); - c->Stats = REF(s2); - if (s2->Freq < MAX_FREQ / 4 - 1) - s2->Freq <<= 1; - else - s2->Freq = MAX_FREQ - 4; - c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2)); - } - cf = 2 * fFreq * (c->SummFreq + 6); - sf = (UInt32)s0 + c->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf) + (cf >= 4 * sf); - c->SummFreq += 4; - } - else - { - cf = 4 + (cf > 9 * sf) + (cf > 12 * sf) + (cf > 15 * sf); - c->SummFreq = (UInt16)(c->SummFreq + cf); - } - { - CPpmd_State *s2 = STATS(c) + ns1 + 1; - SetSuccessor(s2, successor); - s2->Symbol = fSymbol; - s2->Freq = (Byte)cf; - c->Flags |= flag; - c->NumStats = (Byte)(ns1 + 1); - } - } - p->MaxContext = p->MinContext = CTX(fSuccessor); -} - -static void Rescale(CPpmd8 *p) -{ - unsigned i, adder, sumFreq, escFreq; - CPpmd_State *stats = STATS(p->MinContext); - CPpmd_State *s = p->FoundState; - { - CPpmd_State tmp = *s; - for (; s != stats; s--) - s[0] = s[-1]; - *s = tmp; - } - escFreq = p->MinContext->SummFreq - s->Freq; - s->Freq += 4; - adder = (p->OrderFall != 0 - #ifdef PPMD8_FREEZE_SUPPORT - || p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE - #endif - ); - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq = s->Freq; - - i = p->MinContext->NumStats; - do - { - escFreq -= (++s)->Freq; - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq += s->Freq; - if (s[0].Freq > s[-1].Freq) - { - CPpmd_State *s1 = s; - CPpmd_State tmp = *s1; - do - s1[0] = s1[-1]; - while (--s1 != stats && tmp.Freq > s1[-1].Freq); - *s1 = tmp; - } - } - while (--i); - - if (s->Freq == 0) - { - unsigned numStats = p->MinContext->NumStats; - unsigned n0, n1; - do { i++; } while ((--s)->Freq == 0); - escFreq += i; - p->MinContext->NumStats = (Byte)(p->MinContext->NumStats - i); - if (p->MinContext->NumStats == 0) - { - CPpmd_State tmp = *stats; - tmp.Freq = (Byte)((2 * tmp.Freq + escFreq - 1) / escFreq); - if (tmp.Freq > MAX_FREQ / 3) - tmp.Freq = MAX_FREQ / 3; - InsertNode(p, stats, U2I((numStats + 2) >> 1)); - p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40)); - *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; - return; - } - n0 = (numStats + 2) >> 1; - n1 = (p->MinContext->NumStats + 2) >> 1; - if (n0 != n1) - p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); - p->MinContext->Flags &= ~0x08; - p->MinContext->Flags |= 0x08 * ((s = STATS(p->MinContext))->Symbol >= 0x40); - i = p->MinContext->NumStats; - do { p->MinContext->Flags |= 0x08*((++s)->Symbol >= 0x40); } while (--i); - } - p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); - p->MinContext->Flags |= 0x4; - p->FoundState = STATS(p->MinContext); -} - -CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq) -{ - CPpmd_See *see; - if (p->MinContext->NumStats != 0xFF) - { - see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] + - (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) + - 2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats < - ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) + - p->MinContext->Flags; - { - unsigned r = (see->Summ >> see->Shift); - see->Summ = (UInt16)(see->Summ - r); - *escFreq = r + (r == 0); - } - } - else - { - see = &p->DummySee; - *escFreq = 1; - } - return see; -} - -static void NextContext(CPpmd8 *p) -{ - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); - if (p->OrderFall == 0 && (Byte *)c >= p->UnitsStart) - p->MinContext = p->MaxContext = c; - else - { - UpdateModel(p); - p->MinContext = p->MaxContext; - } -} - -void Ppmd8_Update1(CPpmd8 *p) -{ - CPpmd_State *s = p->FoundState; - s->Freq += 4; - p->MinContext->SummFreq += 4; - if (s[0].Freq > s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - p->FoundState = --s; - if (s->Freq > MAX_FREQ) - Rescale(p); - } - NextContext(p); -} - -void Ppmd8_Update1_0(CPpmd8 *p) -{ - p->PrevSuccess = (2 * p->FoundState->Freq >= p->MinContext->SummFreq); - p->RunLength += p->PrevSuccess; - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - NextContext(p); -} - -void Ppmd8_UpdateBin(CPpmd8 *p) -{ - p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 196)); - p->PrevSuccess = 1; - p->RunLength++; - NextContext(p); -} - -void Ppmd8_Update2(CPpmd8 *p) -{ - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - p->RunLength = p->InitRL; - UpdateModel(p); - p->MinContext = p->MaxContext; -} - -/* H->I changes: - NS2Indx - GlewCount, and Glue method - BinSum - See / EscFreq - CreateSuccessors updates more suffix contexts - UpdateModel consts. - PrevSuccess Update -*/ +/* Ppmd8.c -- PPMdI codec +2023-09-07 : Igor Pavlov : Public domain +This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ + +#include "Precomp.h" + +#include + +#include "Ppmd8.h" + + + + +MY_ALIGN(16) +static const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +MY_ALIGN(16) +static const UInt16 PPMD8_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; + +#define MAX_FREQ 124 +#define UNIT_SIZE 12 + +#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) +#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1]) +#define I2U(indx) ((unsigned)p->Indx2Units[indx]) + + +#define REF(ptr) Ppmd_GetRef(p, ptr) + +#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) + +#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) +#define STATS(ctx) Ppmd8_GetStats(p, ctx) +#define ONE_STATE(ctx) Ppmd8Context_OneState(ctx) +#define SUFFIX(ctx) CTX((ctx)->Suffix) + +typedef CPpmd8_Context * PPMD8_CTX_PTR; + +struct CPpmd8_Node_; + +typedef Ppmd_Ref_Type(struct CPpmd8_Node_) CPpmd8_Node_Ref; + +typedef struct CPpmd8_Node_ +{ + UInt32 Stamp; + + CPpmd8_Node_Ref Next; + UInt32 NU; +} CPpmd8_Node; + +#define NODE(r) Ppmd_GetPtr_Type(p, r, CPpmd8_Node) + +void Ppmd8_Construct(CPpmd8 *p) +{ + unsigned i, k, m; + + p->Base = NULL; + + for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) + { + unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); + do { p->Units2Indx[k++] = (Byte)i; } while (--step); + p->Indx2Units[i] = (Byte)k; + } + + p->NS2BSIndx[0] = (0 << 1); + p->NS2BSIndx[1] = (1 << 1); + memset(p->NS2BSIndx + 2, (2 << 1), 9); + memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); + + for (i = 0; i < 5; i++) + p->NS2Indx[i] = (Byte)i; + + for (m = i, k = 1; i < 260; i++) + { + p->NS2Indx[i] = (Byte)m; + if (--k == 0) + k = (++m) - 4; + } + + memcpy(p->ExpEscape, PPMD8_kExpEscape, 16); +} + + +void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->Base); + p->Size = 0; + p->Base = NULL; +} + + +BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc) +{ + if (!p->Base || p->Size != size) + { + Ppmd8_Free(p, alloc); + p->AlignOffset = (4 - size) & 3; + if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == NULL) + return False; + p->Size = size; + } + return True; +} + + + +// ---------- Internal Memory Allocator ---------- + + + + + + +#define EMPTY_NODE 0xFFFFFFFF + + +static void Ppmd8_InsertNode(CPpmd8 *p, void *node, unsigned indx) +{ + ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE; + ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx]; + ((CPpmd8_Node *)node)->NU = I2U(indx); + p->FreeList[indx] = REF(node); + p->Stamps[indx]++; +} + + +static void *Ppmd8_RemoveNode(CPpmd8 *p, unsigned indx) +{ + CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]); + p->FreeList[indx] = node->Next; + p->Stamps[indx]--; + + return node; +} + + +static void Ppmd8_SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +{ + unsigned i, nu = I2U(oldIndx) - I2U(newIndx); + ptr = (Byte *)ptr + U2B(I2U(newIndx)); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + Ppmd8_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + } + Ppmd8_InsertNode(p, ptr, i); +} + + + + + + + + + + + + + + +static void Ppmd8_GlueFreeBlocks(CPpmd8 *p) +{ + /* + we use first UInt32 field of 12-bytes UNITs as record type stamp + CPpmd_State { Byte Symbol; Byte Freq; : Freq != 0xFF + CPpmd8_Context { Byte NumStats; Byte Flags; UInt16 SummFreq; : Flags != 0xFF ??? + CPpmd8_Node { UInt32 Stamp : Stamp == 0xFFFFFFFF for free record + : Stamp == 0 for guard + Last 12-bytes UNIT in array is always contains 12-bytes order-0 CPpmd8_Context record + */ + CPpmd8_Node_Ref n; + + p->GlueCount = 1 << 13; + memset(p->Stamps, 0, sizeof(p->Stamps)); + + /* we set guard NODE at LoUnit */ + if (p->LoUnit != p->HiUnit) + ((CPpmd8_Node *)(void *)p->LoUnit)->Stamp = 0; + + { + /* Glue free blocks */ + CPpmd8_Node_Ref *prev = &n; + unsigned i; + for (i = 0; i < PPMD_NUM_INDEXES; i++) + { + + CPpmd8_Node_Ref next = (CPpmd8_Node_Ref)p->FreeList[i]; + p->FreeList[i] = 0; + while (next != 0) + { + CPpmd8_Node *node = NODE(next); + UInt32 nu = node->NU; + *prev = next; + next = node->Next; + if (nu != 0) + { + CPpmd8_Node *node2; + prev = &(node->Next); + while ((node2 = node + nu)->Stamp == EMPTY_NODE) + { + nu += node2->NU; + node2->NU = 0; + node->NU = nu; + } + } + } + } + + *prev = 0; + } + + + + + + + + + + + + + + + + + + + + + /* Fill lists of free blocks */ + while (n != 0) + { + CPpmd8_Node *node = NODE(n); + UInt32 nu = node->NU; + unsigned i; + n = node->Next; + if (nu == 0) + continue; + for (; nu > 128; nu -= 128, node += 128) + Ppmd8_InsertNode(p, node, PPMD_NUM_INDEXES - 1); + if (I2U(i = U2I(nu)) != nu) + { + unsigned k = I2U(--i); + Ppmd8_InsertNode(p, node + k, (unsigned)nu - k - 1); + } + Ppmd8_InsertNode(p, node, i); + } +} + + +Z7_NO_INLINE +static void *Ppmd8_AllocUnitsRare(CPpmd8 *p, unsigned indx) +{ + unsigned i; + + if (p->GlueCount == 0) + { + Ppmd8_GlueFreeBlocks(p); + if (p->FreeList[indx] != 0) + return Ppmd8_RemoveNode(p, indx); + } + + i = indx; + + do + { + if (++i == PPMD_NUM_INDEXES) + { + UInt32 numBytes = U2B(I2U(indx)); + Byte *us = p->UnitsStart; + p->GlueCount--; + return ((UInt32)(us - p->Text) > numBytes) ? (p->UnitsStart = us - numBytes) : (NULL); + } + } + while (p->FreeList[i] == 0); + + { + void *block = Ppmd8_RemoveNode(p, i); + Ppmd8_SplitBlock(p, block, i, indx); + return block; + } +} + + +static void *Ppmd8_AllocUnits(CPpmd8 *p, unsigned indx) +{ + if (p->FreeList[indx] != 0) + return Ppmd8_RemoveNode(p, indx); + { + UInt32 numBytes = U2B(I2U(indx)); + Byte *lo = p->LoUnit; + if ((UInt32)(p->HiUnit - lo) >= numBytes) + { + p->LoUnit = lo + numBytes; + return lo; + } + } + return Ppmd8_AllocUnitsRare(p, indx); +} + + +#define MEM_12_CPY(dest, src, num) \ + { UInt32 *d = (UInt32 *)(dest); \ + const UInt32 *z = (const UInt32 *)(src); \ + unsigned n = (num); \ + do { \ + d[0] = z[0]; \ + d[1] = z[1]; \ + d[2] = z[2]; \ + z += 3; \ + d += 3; \ + } while (--n); \ + } + + + +static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) +{ + unsigned i0 = U2I(oldNU); + unsigned i1 = U2I(newNU); + if (i0 == i1) + return oldPtr; + if (p->FreeList[i1] != 0) + { + void *ptr = Ppmd8_RemoveNode(p, i1); + MEM_12_CPY(ptr, oldPtr, newNU) + Ppmd8_InsertNode(p, oldPtr, i0); + return ptr; + } + Ppmd8_SplitBlock(p, oldPtr, i0, i1); + return oldPtr; +} + + +static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu) +{ + Ppmd8_InsertNode(p, ptr, U2I(nu)); +} + + +static void SpecialFreeUnit(CPpmd8 *p, void *ptr) +{ + if ((Byte *)ptr != p->UnitsStart) + Ppmd8_InsertNode(p, ptr, 0); + else + { + #ifdef PPMD8_FREEZE_SUPPORT + *(UInt32 *)ptr = EMPTY_NODE; /* it's used for (Flags == 0xFF) check in RemoveBinContexts() */ + #endif + p->UnitsStart += UNIT_SIZE; + } +} + + +/* +static void *MoveUnitsUp(CPpmd8 *p, void *oldPtr, unsigned nu) +{ + unsigned indx = U2I(nu); + void *ptr; + if ((Byte *)oldPtr > p->UnitsStart + (1 << 14) || REF(oldPtr) > p->FreeList[indx]) + return oldPtr; + ptr = Ppmd8_RemoveNode(p, indx); + MEM_12_CPY(ptr, oldPtr, nu) + if ((Byte *)oldPtr != p->UnitsStart) + Ppmd8_InsertNode(p, oldPtr, indx); + else + p->UnitsStart += U2B(I2U(indx)); + return ptr; +} +*/ + +static void ExpandTextArea(CPpmd8 *p) +{ + UInt32 count[PPMD_NUM_INDEXES]; + unsigned i; + + memset(count, 0, sizeof(count)); + if (p->LoUnit != p->HiUnit) + ((CPpmd8_Node *)(void *)p->LoUnit)->Stamp = 0; + + { + CPpmd8_Node *node = (CPpmd8_Node *)(void *)p->UnitsStart; + while (node->Stamp == EMPTY_NODE) + { + UInt32 nu = node->NU; + node->Stamp = 0; + count[U2I(nu)]++; + node += nu; + } + p->UnitsStart = (Byte *)node; + } + + for (i = 0; i < PPMD_NUM_INDEXES; i++) + { + UInt32 cnt = count[i]; + if (cnt == 0) + continue; + { + CPpmd8_Node_Ref *prev = (CPpmd8_Node_Ref *)&p->FreeList[i]; + CPpmd8_Node_Ref n = *prev; + p->Stamps[i] -= cnt; + for (;;) + { + CPpmd8_Node *node = NODE(n); + n = node->Next; + if (node->Stamp != 0) + { + prev = &node->Next; + continue; + } + *prev = n; + if (--cnt == 0) + break; + } + } + } +} + + +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) +static void Ppmd8State_SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) +{ + Ppmd_SET_SUCCESSOR(p, v) +} + +#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); } + +Z7_NO_INLINE +static +void Ppmd8_RestartModel(CPpmd8 *p) +{ + unsigned i, k, m; + + memset(p->FreeList, 0, sizeof(p->FreeList)); + memset(p->Stamps, 0, sizeof(p->Stamps)); + RESET_TEXT(0) + p->HiUnit = p->Text + p->Size; + p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; + p->GlueCount = 0; + + p->OrderFall = p->MaxOrder; + p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; + p->PrevSuccess = 0; + + { + CPpmd8_Context *mc = (PPMD8_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd8_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + + p->LoUnit += U2B(256 / 2); + p->MaxContext = p->MinContext = mc; + p->FoundState = s; + mc->Flags = 0; + mc->NumStats = 256 - 1; + mc->Union2.SummFreq = 256 + 1; + mc->Union4.Stats = REF(s); + mc->Suffix = 0; + + for (i = 0; i < 256; i++, s++) + { + s->Symbol = (Byte)i; + s->Freq = 1; + Ppmd8State_SetSuccessor(s, 0); + } + } + + + + + + + + + + + + + for (i = m = 0; m < 25; m++) + { + while (p->NS2Indx[i] == m) + i++; + for (k = 0; k < 8; k++) + { + unsigned r; + UInt16 *dest = p->BinSumm[m] + k; + const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD8_kInitBinEsc[k] / (i + 1)); + for (r = 0; r < 64; r += 8) + dest[r] = val; + } + } + + for (i = m = 0; m < 24; m++) + { + unsigned summ; + CPpmd_See *s; + while (p->NS2Indx[(size_t)i + 3] == m + 3) + i++; + s = p->See[m]; + summ = ((2 * i + 5) << (PPMD_PERIOD_BITS - 4)); + for (k = 0; k < 32; k++, s++) + { + s->Summ = (UInt16)summ; + s->Shift = (PPMD_PERIOD_BITS - 4); + s->Count = 7; + } + } + + p->DummySee.Summ = 0; /* unused */ + p->DummySee.Shift = PPMD_PERIOD_BITS; + p->DummySee.Count = 64; /* unused */ +} + + +void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod) +{ + p->MaxOrder = maxOrder; + p->RestoreMethod = restoreMethod; + Ppmd8_RestartModel(p); +} + + +#define FLAG_RESCALED (1 << 2) +// #define FLAG_SYM_HIGH (1 << 3) +#define FLAG_PREV_HIGH (1 << 4) + +#define HiBits_Prepare(sym) ((unsigned)(sym) + 0xC0) + +#define HiBits_Convert_3(flags) (((flags) >> (8 - 3)) & (1 << 3)) +#define HiBits_Convert_4(flags) (((flags) >> (8 - 4)) & (1 << 4)) + +#define PPMD8_HiBitsFlag_3(sym) HiBits_Convert_3(HiBits_Prepare(sym)) +#define PPMD8_HiBitsFlag_4(sym) HiBits_Convert_4(HiBits_Prepare(sym)) + +// #define PPMD8_HiBitsFlag_3(sym) (0x08 * ((sym) >= 0x40)) +// #define PPMD8_HiBitsFlag_4(sym) (0x10 * ((sym) >= 0x40)) + +/* +Refresh() is called when we remove some symbols (successors) in context. +It increases Escape_Freq for sum of all removed symbols. +*/ + +static void Refresh(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned oldNU, unsigned scale) +{ + unsigned i = ctx->NumStats, escFreq, sumFreq, flags; + CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1); + ctx->Union4.Stats = REF(s); + + // #ifdef PPMD8_FREEZE_SUPPORT + /* + (ctx->Union2.SummFreq >= ((UInt32)1 << 15)) can be in FREEZE mode for some files. + It's not good for range coder. So new versions of support fix: + - original PPMdI code rev.1 + + original PPMdI code rev.2 + - 7-Zip default ((PPMD8_FREEZE_SUPPORT is not defined) + + 7-Zip (p->RestoreMethod >= PPMD8_RESTORE_METHOD_FREEZE) + if we use that fixed line, we can lose compatibility with some files created before fix + if we don't use that fixed line, the program can work incorrectly in FREEZE mode in rare case. + */ + // if (p->RestoreMethod >= PPMD8_RESTORE_METHOD_FREEZE) + { + scale |= (ctx->Union2.SummFreq >= ((UInt32)1 << 15)); + } + // #endif + + + + flags = HiBits_Prepare(s->Symbol); + { + unsigned freq = s->Freq; + escFreq = ctx->Union2.SummFreq - freq; + freq = (freq + scale) >> scale; + sumFreq = freq; + s->Freq = (Byte)freq; + } + + do + { + unsigned freq = (++s)->Freq; + escFreq -= freq; + freq = (freq + scale) >> scale; + sumFreq += freq; + s->Freq = (Byte)freq; + flags |= HiBits_Prepare(s->Symbol); + } + while (--i); + + ctx->Union2.SummFreq = (UInt16)(sumFreq + ((escFreq + scale) >> scale)); + ctx->Flags = (Byte)((ctx->Flags & (FLAG_PREV_HIGH + FLAG_RESCALED * scale)) + HiBits_Convert_3(flags)); +} + + +static void SWAP_STATES(CPpmd_State *t1, CPpmd_State *t2) +{ + CPpmd_State tmp = *t1; + *t1 = *t2; + *t2 = tmp; +} + + +/* +CutOff() reduces contexts: + It conversts Successors at MaxOrder to another Contexts to NULL-Successors + It removes RAW-Successors and NULL-Successors that are not Order-0 + and it removes contexts when it has no Successors. + if the (Union4.Stats) is close to (UnitsStart), it moves it up. +*/ + +static CPpmd_Void_Ref CutOff(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned order) +{ + int ns = ctx->NumStats; + unsigned nu; + CPpmd_State *stats; + + if (ns == 0) + { + CPpmd_State *s = ONE_STATE(ctx); + CPpmd_Void_Ref successor = SUCCESSOR(s); + if ((Byte *)Ppmd8_GetPtr(p, successor) >= p->UnitsStart) + { + if (order < p->MaxOrder) + successor = CutOff(p, CTX(successor), order + 1); + else + successor = 0; + Ppmd8State_SetSuccessor(s, successor); + if (successor || order <= 9) /* O_BOUND */ + return REF(ctx); + } + SpecialFreeUnit(p, ctx); + return 0; + } + + nu = ((unsigned)ns + 2) >> 1; + // ctx->Union4.Stats = STATS_REF(MoveUnitsUp(p, STATS(ctx), nu)); + { + unsigned indx = U2I(nu); + stats = STATS(ctx); + + if ((UInt32)((Byte *)stats - p->UnitsStart) <= (1 << 14) + && (CPpmd_Void_Ref)ctx->Union4.Stats <= p->FreeList[indx]) + { + void *ptr = Ppmd8_RemoveNode(p, indx); + ctx->Union4.Stats = STATS_REF(ptr); + MEM_12_CPY(ptr, (const void *)stats, nu) + if ((Byte *)stats != p->UnitsStart) + Ppmd8_InsertNode(p, stats, indx); + else + p->UnitsStart += U2B(I2U(indx)); + stats = ptr; + } + } + + { + CPpmd_State *s = stats + (unsigned)ns; + do + { + CPpmd_Void_Ref successor = SUCCESSOR(s); + if ((Byte *)Ppmd8_GetPtr(p, successor) < p->UnitsStart) + { + CPpmd_State *s2 = stats + (unsigned)(ns--); + if (order) + { + if (s != s2) + *s = *s2; + } + else + { + SWAP_STATES(s, s2); + Ppmd8State_SetSuccessor(s2, 0); + } + } + else + { + if (order < p->MaxOrder) + Ppmd8State_SetSuccessor(s, CutOff(p, CTX(successor), order + 1)); + else + Ppmd8State_SetSuccessor(s, 0); + } + } + while (--s >= stats); + } + + if (ns != ctx->NumStats && order) + { + if (ns < 0) + { + FreeUnits(p, stats, nu); + SpecialFreeUnit(p, ctx); + return 0; + } + ctx->NumStats = (Byte)ns; + if (ns == 0) + { + const Byte sym = stats->Symbol; + ctx->Flags = (Byte)((ctx->Flags & FLAG_PREV_HIGH) + PPMD8_HiBitsFlag_3(sym)); + // *ONE_STATE(ctx) = *stats; + ctx->Union2.State2.Symbol = sym; + ctx->Union2.State2.Freq = (Byte)(((unsigned)stats->Freq + 11) >> 3); + ctx->Union4.State4.Successor_0 = stats->Successor_0; + ctx->Union4.State4.Successor_1 = stats->Successor_1; + FreeUnits(p, stats, nu); + } + else + { + Refresh(p, ctx, nu, ctx->Union2.SummFreq > 16 * (unsigned)ns); + } + } + + return REF(ctx); +} + + + +#ifdef PPMD8_FREEZE_SUPPORT + +/* +RemoveBinContexts() + It conversts Successors at MaxOrder to another Contexts to NULL-Successors + It changes RAW-Successors to NULL-Successors + removes Bin Context without Successor, if suffix of that context is also binary. +*/ + +static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, PPMD8_CTX_PTR ctx, unsigned order) +{ + if (!ctx->NumStats) + { + CPpmd_State *s = ONE_STATE(ctx); + CPpmd_Void_Ref successor = SUCCESSOR(s); + if ((Byte *)Ppmd8_GetPtr(p, successor) >= p->UnitsStart && order < p->MaxOrder) + successor = RemoveBinContexts(p, CTX(successor), order + 1); + else + successor = 0; + Ppmd8State_SetSuccessor(s, successor); + /* Suffix context can be removed already, since different (high-order) + Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */ + if (!successor && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF)) + { + FreeUnits(p, ctx, 1); + return 0; + } + } + else + { + CPpmd_State *s = STATS(ctx) + ctx->NumStats; + do + { + CPpmd_Void_Ref successor = SUCCESSOR(s); + if ((Byte *)Ppmd8_GetPtr(p, successor) >= p->UnitsStart && order < p->MaxOrder) + Ppmd8State_SetSuccessor(s, RemoveBinContexts(p, CTX(successor), order + 1)); + else + Ppmd8State_SetSuccessor(s, 0); + } + while (--s >= STATS(ctx)); + } + + return REF(ctx); +} + +#endif + + + +static UInt32 GetUsedMemory(const CPpmd8 *p) +{ + UInt32 v = 0; + unsigned i; + for (i = 0; i < PPMD_NUM_INDEXES; i++) + v += p->Stamps[i] * I2U(i); + return p->Size - (UInt32)(p->HiUnit - p->LoUnit) - (UInt32)(p->UnitsStart - p->Text) - U2B(v); +} + +#ifdef PPMD8_FREEZE_SUPPORT + #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1, fSuccessor) +#else + #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1) +#endif + + +static void RestoreModel(CPpmd8 *p, PPMD8_CTX_PTR ctxError + #ifdef PPMD8_FREEZE_SUPPORT + , PPMD8_CTX_PTR fSuccessor + #endif + ) +{ + PPMD8_CTX_PTR c; + CPpmd_State *s; + RESET_TEXT(0) + + // we go here in cases of error of allocation for context (c1) + // Order(MinContext) < Order(ctxError) <= Order(MaxContext) + + // We remove last symbol from each of contexts [p->MaxContext ... ctxError) contexts + // So we rollback all created (symbols) before error. + for (c = p->MaxContext; c != ctxError; c = SUFFIX(c)) + if (--(c->NumStats) == 0) + { + s = STATS(c); + c->Flags = (Byte)((c->Flags & FLAG_PREV_HIGH) + PPMD8_HiBitsFlag_3(s->Symbol)); + // *ONE_STATE(c) = *s; + c->Union2.State2.Symbol = s->Symbol; + c->Union2.State2.Freq = (Byte)(((unsigned)s->Freq + 11) >> 3); + c->Union4.State4.Successor_0 = s->Successor_0; + c->Union4.State4.Successor_1 = s->Successor_1; + + SpecialFreeUnit(p, s); + } + else + { + /* Refresh() can increase Escape_Freq on value of Freq of last symbol, that was added before error. + so the largest possible increase for Escape_Freq is (8) from value before ModelUpoadet() */ + Refresh(p, c, ((unsigned)c->NumStats + 3) >> 1, 0); + } + + // increase Escape Freq for context [ctxError ... p->MinContext) + for (; c != p->MinContext; c = SUFFIX(c)) + if (c->NumStats == 0) + { + // ONE_STATE(c) + c->Union2.State2.Freq = (Byte)(((unsigned)c->Union2.State2.Freq + 1) >> 1); + } + else if ((c->Union2.SummFreq = (UInt16)(c->Union2.SummFreq + 4)) > 128 + 4 * c->NumStats) + Refresh(p, c, ((unsigned)c->NumStats + 2) >> 1, 1); + + #ifdef PPMD8_FREEZE_SUPPORT + if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) + { + p->MaxContext = fSuccessor; + p->GlueCount += !(p->Stamps[1] & 1); // why? + } + else if (p->RestoreMethod == PPMD8_RESTORE_METHOD_FREEZE) + { + while (p->MaxContext->Suffix) + p->MaxContext = SUFFIX(p->MaxContext); + RemoveBinContexts(p, p->MaxContext, 0); + // we change the current mode to (PPMD8_RESTORE_METHOD_FREEZE + 1) + p->RestoreMethod = PPMD8_RESTORE_METHOD_FREEZE + 1; + p->GlueCount = 0; + p->OrderFall = p->MaxOrder; + } + else + #endif + if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1)) + Ppmd8_RestartModel(p); + else + { + while (p->MaxContext->Suffix) + p->MaxContext = SUFFIX(p->MaxContext); + do + { + CutOff(p, p->MaxContext, 0); + ExpandTextArea(p); + } + while (GetUsedMemory(p) > 3 * (p->Size >> 2)); + p->GlueCount = 0; + p->OrderFall = p->MaxOrder; + } + p->MinContext = p->MaxContext; +} + + + +Z7_NO_INLINE +static PPMD8_CTX_PTR Ppmd8_CreateSuccessors(CPpmd8 *p, BoolInt skip, CPpmd_State *s1, PPMD8_CTX_PTR c) +{ + + CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); + Byte newSym, newFreq, flags; + unsigned numPs = 0; + CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; /* fixed over Shkarin's code. Maybe it could work without + 1 too. */ + + if (!skip) + ps[numPs++] = p->FoundState; + + while (c->Suffix) + { + CPpmd_Void_Ref successor; + CPpmd_State *s; + c = SUFFIX(c); + + if (s1) { s = s1; s1 = NULL; } + else if (c->NumStats != 0) + { + Byte sym = p->FoundState->Symbol; + for (s = STATS(c); s->Symbol != sym; s++); + if (s->Freq < MAX_FREQ - 9) { s->Freq++; c->Union2.SummFreq++; } + } + else + { + s = ONE_STATE(c); + s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24))); + } + successor = SUCCESSOR(s); + if (successor != upBranch) + { + + c = CTX(successor); + if (numPs == 0) + { + + + return c; + } + break; + } + ps[numPs++] = s; + } + + + + + + newSym = *(const Byte *)Ppmd8_GetPtr(p, upBranch); + upBranch++; + flags = (Byte)(PPMD8_HiBitsFlag_4(p->FoundState->Symbol) + PPMD8_HiBitsFlag_3(newSym)); + + if (c->NumStats == 0) + newFreq = c->Union2.State2.Freq; + else + { + UInt32 cf, s0; + CPpmd_State *s; + for (s = STATS(c); s->Symbol != newSym; s++); + cf = (UInt32)s->Freq - 1; + s0 = (UInt32)c->Union2.SummFreq - c->NumStats - cf; + /* + + + max(newFreq)= (s->Freq - 1), when (s0 == 1) + + + */ + newFreq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0))); + } + + + + do + { + PPMD8_CTX_PTR c1; + /* = AllocContext(p); */ + if (p->HiUnit != p->LoUnit) + c1 = (PPMD8_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); + else if (p->FreeList[0] != 0) + c1 = (PPMD8_CTX_PTR)Ppmd8_RemoveNode(p, 0); + else + { + c1 = (PPMD8_CTX_PTR)Ppmd8_AllocUnitsRare(p, 0); + if (!c1) + return NULL; + } + c1->Flags = flags; + c1->NumStats = 0; + c1->Union2.State2.Symbol = newSym; + c1->Union2.State2.Freq = newFreq; + Ppmd8State_SetSuccessor(ONE_STATE(c1), upBranch); + c1->Suffix = REF(c); + Ppmd8State_SetSuccessor(ps[--numPs], REF(c1)); + c = c1; + } + while (numPs != 0); + + return c; +} + + +static PPMD8_CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, PPMD8_CTX_PTR c) +{ + CPpmd_State *s = NULL; + PPMD8_CTX_PTR c1 = c; + CPpmd_Void_Ref upBranch = REF(p->Text); + + #ifdef PPMD8_FREEZE_SUPPORT + /* The BUG in Shkarin's code was fixed: ps could overflow in CUT_OFF mode. */ + CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; + unsigned numPs = 0; + ps[numPs++] = p->FoundState; + #endif + + Ppmd8State_SetSuccessor(p->FoundState, upBranch); + p->OrderFall++; + + for (;;) + { + if (s1) + { + c = SUFFIX(c); + s = s1; + s1 = NULL; + } + else + { + if (!c->Suffix) + { + #ifdef PPMD8_FREEZE_SUPPORT + if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) + { + do { Ppmd8State_SetSuccessor(ps[--numPs], REF(c)); } while (numPs); + RESET_TEXT(1) + p->OrderFall = 1; + } + #endif + return c; + } + c = SUFFIX(c); + if (c->NumStats) + { + if ((s = STATS(c))->Symbol != p->FoundState->Symbol) + do { s++; } while (s->Symbol != p->FoundState->Symbol); + if (s->Freq < MAX_FREQ - 9) + { + s->Freq = (Byte)(s->Freq + 2); + c->Union2.SummFreq = (UInt16)(c->Union2.SummFreq + 2); + } + } + else + { + s = ONE_STATE(c); + s->Freq = (Byte)(s->Freq + (s->Freq < 32)); + } + } + if (SUCCESSOR(s)) + break; + #ifdef PPMD8_FREEZE_SUPPORT + ps[numPs++] = s; + #endif + Ppmd8State_SetSuccessor(s, upBranch); + p->OrderFall++; + } + + #ifdef PPMD8_FREEZE_SUPPORT + if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) + { + c = CTX(SUCCESSOR(s)); + do { Ppmd8State_SetSuccessor(ps[--numPs], REF(c)); } while (numPs); + RESET_TEXT(1) + p->OrderFall = 1; + return c; + } + else + #endif + if (SUCCESSOR(s) <= upBranch) + { + PPMD8_CTX_PTR successor; + CPpmd_State *s2 = p->FoundState; + p->FoundState = s; + + successor = Ppmd8_CreateSuccessors(p, False, NULL, c); + if (!successor) + Ppmd8State_SetSuccessor(s, 0); + else + Ppmd8State_SetSuccessor(s, REF(successor)); + p->FoundState = s2; + } + + { + CPpmd_Void_Ref successor = SUCCESSOR(s); + if (p->OrderFall == 1 && c1 == p->MaxContext) + { + Ppmd8State_SetSuccessor(p->FoundState, successor); + p->Text--; + } + if (successor == 0) + return NULL; + return CTX(successor); + } +} + + + +void Ppmd8_UpdateModel(CPpmd8 *p); +Z7_NO_INLINE +void Ppmd8_UpdateModel(CPpmd8 *p) +{ + CPpmd_Void_Ref maxSuccessor, minSuccessor = SUCCESSOR(p->FoundState); + PPMD8_CTX_PTR c; + unsigned s0, ns, fFreq = p->FoundState->Freq; + Byte flag, fSymbol = p->FoundState->Symbol; + { + CPpmd_State *s = NULL; + if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) + { + /* Update Freqs in Suffix Context */ + + c = SUFFIX(p->MinContext); + + if (c->NumStats == 0) + { + s = ONE_STATE(c); + if (s->Freq < 32) + s->Freq++; + } + else + { + Byte sym = p->FoundState->Symbol; + s = STATS(c); + + if (s->Symbol != sym) + { + do + { + + s++; + } + while (s->Symbol != sym); + + if (s[0].Freq >= s[-1].Freq) + { + SWAP_STATES(&s[0], &s[-1]); + s--; + } + } + + if (s->Freq < MAX_FREQ - 9) + { + s->Freq = (Byte)(s->Freq + 2); + c->Union2.SummFreq = (UInt16)(c->Union2.SummFreq + 2); + } + } + } + + c = p->MaxContext; + if (p->OrderFall == 0 && minSuccessor) + { + PPMD8_CTX_PTR cs = Ppmd8_CreateSuccessors(p, True, s, p->MinContext); + if (!cs) + { + Ppmd8State_SetSuccessor(p->FoundState, 0); + RESTORE_MODEL(c, CTX(minSuccessor)); + return; + } + Ppmd8State_SetSuccessor(p->FoundState, REF(cs)); + p->MinContext = p->MaxContext = cs; + return; + } + + + + + { + Byte *text = p->Text; + *text++ = p->FoundState->Symbol; + p->Text = text; + if (text >= p->UnitsStart) + { + RESTORE_MODEL(c, CTX(minSuccessor)); /* check it */ + return; + } + maxSuccessor = REF(text); + } + + if (!minSuccessor) + { + PPMD8_CTX_PTR cs = ReduceOrder(p, s, p->MinContext); + if (!cs) + { + RESTORE_MODEL(c, NULL); + return; + } + minSuccessor = REF(cs); + } + else if ((Byte *)Ppmd8_GetPtr(p, minSuccessor) < p->UnitsStart) + { + PPMD8_CTX_PTR cs = Ppmd8_CreateSuccessors(p, False, s, p->MinContext); + if (!cs) + { + RESTORE_MODEL(c, NULL); + return; + } + minSuccessor = REF(cs); + } + + if (--p->OrderFall == 0) + { + maxSuccessor = minSuccessor; + p->Text -= (p->MaxContext != p->MinContext); + } + #ifdef PPMD8_FREEZE_SUPPORT + else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) + { + maxSuccessor = minSuccessor; + RESET_TEXT(0) + p->OrderFall = 0; + } + #endif + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + flag = (Byte)(PPMD8_HiBitsFlag_3(fSymbol)); + s0 = p->MinContext->Union2.SummFreq - (ns = p->MinContext->NumStats) - fFreq; + + for (; c != p->MinContext; c = SUFFIX(c)) + { + unsigned ns1; + UInt32 sum; + + if ((ns1 = c->NumStats) != 0) + { + if ((ns1 & 1) != 0) + { + /* Expand for one UNIT */ + const unsigned oldNU = (ns1 + 1) >> 1; + const unsigned i = U2I(oldNU); + if (i != U2I((size_t)oldNU + 1)) + { + void *ptr = Ppmd8_AllocUnits(p, i + 1); + void *oldPtr; + if (!ptr) + { + RESTORE_MODEL(c, CTX(minSuccessor)); + return; + } + oldPtr = STATS(c); + MEM_12_CPY(ptr, oldPtr, oldNU) + Ppmd8_InsertNode(p, oldPtr, i); + c->Union4.Stats = STATS_REF(ptr); + } + } + sum = c->Union2.SummFreq; + /* max increase of Escape_Freq is 1 here. + an average increase is 1/3 per symbol */ + sum += (UInt32)(unsigned)(3 * ns1 + 1 < ns); + /* original PPMdH uses 16-bit variable for (sum) here. + But (sum < ???). Do we need to truncate (sum) to 16-bit */ + // sum = (UInt16)sum; + } + else + { + + CPpmd_State *s = (CPpmd_State*)Ppmd8_AllocUnits(p, 0); + if (!s) + { + RESTORE_MODEL(c, CTX(minSuccessor)); + return; + } + { + unsigned freq = c->Union2.State2.Freq; + // s = *ONE_STATE(c); + s->Symbol = c->Union2.State2.Symbol; + s->Successor_0 = c->Union4.State4.Successor_0; + s->Successor_1 = c->Union4.State4.Successor_1; + // Ppmd8State_SetSuccessor(s, c->Union4.Stats); // call it only for debug purposes to check the order of + // (Successor_0 and Successor_1) in LE/BE. + c->Union4.Stats = REF(s); + if (freq < MAX_FREQ / 4 - 1) + freq <<= 1; + else + freq = MAX_FREQ - 4; + + s->Freq = (Byte)freq; + + sum = (UInt32)(freq + p->InitEsc + (ns > 2)); // Ppmd8 (> 2) + } + } + + { + CPpmd_State *s = STATS(c) + ns1 + 1; + UInt32 cf = 2 * (sum + 6) * (UInt32)fFreq; + UInt32 sf = (UInt32)s0 + sum; + s->Symbol = fSymbol; + c->NumStats = (Byte)(ns1 + 1); + Ppmd8State_SetSuccessor(s, maxSuccessor); + c->Flags |= flag; + if (cf < 6 * sf) + { + cf = (unsigned)1 + (cf > sf) + (cf >= 4 * sf); + sum += 4; + /* It can add (1, 2, 3) to Escape_Freq */ + } + else + { + cf = (unsigned)4 + (cf > 9 * sf) + (cf > 12 * sf) + (cf > 15 * sf); + sum += cf; + } + + c->Union2.SummFreq = (UInt16)sum; + s->Freq = (Byte)cf; + } + + } + p->MaxContext = p->MinContext = CTX(minSuccessor); +} + + + +Z7_NO_INLINE +static void Ppmd8_Rescale(CPpmd8 *p) +{ + unsigned i, adder, sumFreq, escFreq; + CPpmd_State *stats = STATS(p->MinContext); + CPpmd_State *s = p->FoundState; + + /* Sort the list by Freq */ + if (s != stats) + { + CPpmd_State tmp = *s; + do + s[0] = s[-1]; + while (--s != stats); + *s = tmp; + } + + sumFreq = s->Freq; + escFreq = p->MinContext->Union2.SummFreq - sumFreq; + + + + + + + adder = (p->OrderFall != 0); + + #ifdef PPMD8_FREEZE_SUPPORT + adder |= (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE); + #endif + + sumFreq = (sumFreq + 4 + adder) >> 1; + i = p->MinContext->NumStats; + s->Freq = (Byte)sumFreq; + + do + { + unsigned freq = (++s)->Freq; + escFreq -= freq; + freq = (freq + adder) >> 1; + sumFreq += freq; + s->Freq = (Byte)freq; + if (freq > s[-1].Freq) + { + CPpmd_State tmp = *s; + CPpmd_State *s1 = s; + do + { + s1[0] = s1[-1]; + } + while (--s1 != stats && freq > s1[-1].Freq); + *s1 = tmp; + } + } + while (--i); + + if (s->Freq == 0) + { + /* Remove all items with Freq == 0 */ + CPpmd8_Context *mc; + unsigned numStats, numStatsNew, n0, n1; + + i = 0; do { i++; } while ((--s)->Freq == 0); + + + + + escFreq += i; + mc = p->MinContext; + numStats = mc->NumStats; + numStatsNew = numStats - i; + mc->NumStats = (Byte)(numStatsNew); + n0 = (numStats + 2) >> 1; + + if (numStatsNew == 0) + { + + unsigned freq = (2 * (unsigned)stats->Freq + escFreq - 1) / escFreq; + if (freq > MAX_FREQ / 3) + freq = MAX_FREQ / 3; + mc->Flags = (Byte)((mc->Flags & FLAG_PREV_HIGH) + PPMD8_HiBitsFlag_3(stats->Symbol)); + + + + + + s = ONE_STATE(mc); + *s = *stats; + s->Freq = (Byte)freq; + p->FoundState = s; + Ppmd8_InsertNode(p, stats, U2I(n0)); + return; + } + + n1 = (numStatsNew + 2) >> 1; + if (n0 != n1) + mc->Union4.Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); + { + // here we are for max order only. So Ppmd8_MakeEscFreq() doesn't use mc->Flags + // but we still need current (Flags & FLAG_PREV_HIGH), if we will convert context to 1-symbol context later. + /* + unsigned flags = HiBits_Prepare((s = STATS(mc))->Symbol); + i = mc->NumStats; + do { flags |= HiBits_Prepare((++s)->Symbol); } while (--i); + mc->Flags = (Byte)((mc->Flags & ~FLAG_SYM_HIGH) + HiBits_Convert_3(flags)); + */ + } + } + + + + + + + { + CPpmd8_Context *mc = p->MinContext; + mc->Union2.SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); + mc->Flags |= FLAG_RESCALED; + p->FoundState = STATS(mc); + } +} + + +CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq) +{ + CPpmd_See *see; + const CPpmd8_Context *mc = p->MinContext; + unsigned numStats = mc->NumStats; + if (numStats != 0xFF) + { + // (3 <= numStats + 2 <= 256) (3 <= NS2Indx[3] and NS2Indx[256] === 26) + see = p->See[(size_t)(unsigned)p->NS2Indx[(size_t)numStats + 2] - 3] + + (mc->Union2.SummFreq > 11 * (numStats + 1)) + + 2 * (unsigned)(2 * numStats < ((unsigned)SUFFIX(mc)->NumStats + numMasked1)) + + mc->Flags; + + { + // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ + const unsigned summ = (UInt16)see->Summ; // & 0xFFFF + const unsigned r = (summ >> see->Shift); + see->Summ = (UInt16)(summ - r); + *escFreq = (UInt32)(r + (r == 0)); + } + } + else + { + see = &p->DummySee; + *escFreq = 1; + } + return see; +} + + +static void Ppmd8_NextContext(CPpmd8 *p) +{ + PPMD8_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart) + p->MaxContext = p->MinContext = c; + else + Ppmd8_UpdateModel(p); +} + + +void Ppmd8_Update1(CPpmd8 *p) +{ + CPpmd_State *s = p->FoundState; + unsigned freq = s->Freq; + freq += 4; + p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); + s->Freq = (Byte)freq; + if (freq > s[-1].Freq) + { + SWAP_STATES(s, &s[-1]); + p->FoundState = --s; + if (freq > MAX_FREQ) + Ppmd8_Rescale(p); + } + Ppmd8_NextContext(p); +} + + +void Ppmd8_Update1_0(CPpmd8 *p) +{ + CPpmd_State *s = p->FoundState; + CPpmd8_Context *mc = p->MinContext; + unsigned freq = s->Freq; + const unsigned summFreq = mc->Union2.SummFreq; + p->PrevSuccess = (2 * freq >= summFreq); // Ppmd8 (>=) + p->RunLength += (Int32)p->PrevSuccess; + mc->Union2.SummFreq = (UInt16)(summFreq + 4); + freq += 4; + s->Freq = (Byte)freq; + if (freq > MAX_FREQ) + Ppmd8_Rescale(p); + Ppmd8_NextContext(p); +} + + +/* +void Ppmd8_UpdateBin(CPpmd8 *p) +{ + unsigned freq = p->FoundState->Freq; + p->FoundState->Freq = (Byte)(freq + (freq < 196)); // Ppmd8 (196) + p->PrevSuccess = 1; + p->RunLength++; + Ppmd8_NextContext(p); +} +*/ + +void Ppmd8_Update2(CPpmd8 *p) +{ + CPpmd_State *s = p->FoundState; + unsigned freq = s->Freq; + freq += 4; + p->RunLength = p->InitRL; + p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); + s->Freq = (Byte)freq; + if (freq > MAX_FREQ) + Ppmd8_Rescale(p); + Ppmd8_UpdateModel(p); +} + +/* H->I changes: + NS2Indx + GlueCount, and Glue method + BinSum + See / EscFreq + Ppmd8_CreateSuccessors updates more suffix contexts + Ppmd8_UpdateModel consts. + PrevSuccess Update + +Flags: + (1 << 2) - the Context was Rescaled + (1 << 3) - there is symbol in Stats with (sym >= 0x40) in + (1 << 4) - main symbol of context is (sym >= 0x40) +*/ + +#undef RESET_TEXT +#undef FLAG_RESCALED +#undef FLAG_PREV_HIGH +#undef HiBits_Prepare +#undef HiBits_Convert_3 +#undef HiBits_Convert_4 +#undef PPMD8_HiBitsFlag_3 +#undef PPMD8_HiBitsFlag_4 +#undef RESTORE_MODEL + +#undef MAX_FREQ +#undef UNIT_SIZE +#undef U2B +#undef U2I +#undef I2U + +#undef REF +#undef STATS_REF +#undef CTX +#undef STATS +#undef ONE_STATE +#undef SUFFIX +#undef NODE +#undef EMPTY_NODE +#undef MEM_12_CPY +#undef SUCCESSOR +#undef SWAP_STATES diff -Nru p7zip-rar-16.02/C/Ppmd8.h p7zip-rar-16.02+really25.00+ds/C/Ppmd8.h --- p7zip-rar-16.02/C/Ppmd8.h 2011-05-08 18:29:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd8.h 2023-04-02 12:00:00.000000000 +0000 @@ -1,137 +1,181 @@ -/* Ppmd8.h -- PPMdI codec -2011-01-27 : Igor Pavlov : Public domain -This code is based on: - PPMd var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#ifndef __PPMD8_H -#define __PPMD8_H - -#include "Ppmd.h" - -EXTERN_C_BEGIN - -#define PPMD8_MIN_ORDER 2 -#define PPMD8_MAX_ORDER 16 - -struct CPpmd8_Context_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd8_Context_ * - #else - UInt32 - #endif - CPpmd8_Context_Ref; - -#pragma pack(push, 1) - -typedef struct CPpmd8_Context_ -{ - Byte NumStats; - Byte Flags; - UInt16 SummFreq; - CPpmd_State_Ref Stats; - CPpmd8_Context_Ref Suffix; -} CPpmd8_Context; - -#pragma pack(pop) - -#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) - -/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed - code is not compatible with original code for some files compressed - in FREEZE mode. So we disable FREEZE mode support. */ - -enum -{ - PPMD8_RESTORE_METHOD_RESTART, - PPMD8_RESTORE_METHOD_CUT_OFF - #ifdef PPMD8_FREEZE_SUPPORT - , PPMD8_RESTORE_METHOD_FREEZE - #endif -}; - -typedef struct -{ - CPpmd8_Context *MinContext, *MaxContext; - CPpmd_State *FoundState; - unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder; - Int32 RunLength, InitRL; /* must be 32-bit at least */ - - UInt32 Size; - UInt32 GlueCount; - Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; - UInt32 AlignOffset; - unsigned RestoreMethod; - - /* Range Coder */ - UInt32 Range; - UInt32 Code; - UInt32 Low; - union - { - IByteIn *In; - IByteOut *Out; - } Stream; - - Byte Indx2Units[PPMD_NUM_INDEXES]; - Byte Units2Indx[128]; - CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; - UInt32 Stamps[PPMD_NUM_INDEXES]; - - Byte NS2BSIndx[256], NS2Indx[260]; - CPpmd_See DummySee, See[24][32]; - UInt16 BinSumm[25][64]; -} CPpmd8; - -void Ppmd8_Construct(CPpmd8 *p); -Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc); -void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc); -void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); -#define Ppmd8_WasAllocated(p) ((p)->Base != NULL) - - -/* ---------- Internal Functions ---------- */ - -extern const Byte PPMD8_kExpEscape[16]; - -#ifdef PPMD_32BIT - #define Ppmd8_GetPtr(p, ptr) (ptr) - #define Ppmd8_GetContext(p, ptr) (ptr) - #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats) -#else - #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs))) - #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs))) - #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats))) -#endif - -void Ppmd8_Update1(CPpmd8 *p); -void Ppmd8_Update1_0(CPpmd8 *p); -void Ppmd8_Update2(CPpmd8 *p); -void Ppmd8_UpdateBin(CPpmd8 *p); - -#define Ppmd8_GetBinSumm(p) \ - &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ - p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ - p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] - -CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); - - -/* ---------- Decode ---------- */ - -Bool Ppmd8_RangeDec_Init(CPpmd8 *p); -#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) -int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ - - -/* ---------- Encode ---------- */ - -#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } -void Ppmd8_RangeEnc_FlushData(CPpmd8 *p); -void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */ - -EXTERN_C_END - -#endif +/* Ppmd8.h -- Ppmd8 (PPMdI) compression codec +2023-04-02 : Igor Pavlov : Public domain +This code is based on: + PPMd var.I (2002): Dmitry Shkarin : Public domain + Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#ifndef ZIP7_INC_PPMD8_H +#define ZIP7_INC_PPMD8_H + +#include "Ppmd.h" + +EXTERN_C_BEGIN + +#define PPMD8_MIN_ORDER 2 +#define PPMD8_MAX_ORDER 16 + + + + +struct CPpmd8_Context_; + +typedef Ppmd_Ref_Type(struct CPpmd8_Context_) CPpmd8_Context_Ref; + +// MY_CPU_pragma_pack_push_1 + +typedef struct CPpmd8_Context_ +{ + Byte NumStats; + Byte Flags; + + union + { + UInt16 SummFreq; + CPpmd_State2 State2; + } Union2; + + union + { + CPpmd_State_Ref Stats; + CPpmd_State4 State4; + } Union4; + + CPpmd8_Context_Ref Suffix; +} CPpmd8_Context; + +// MY_CPU_pragma_pop + +#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->Union2) + +/* PPMdI code rev.2 contains the fix over PPMdI code rev.1. + But the code PPMdI.2 is not compatible with PPMdI.1 for some files compressed + in FREEZE mode. So we disable FREEZE mode support. */ + +// #define PPMD8_FREEZE_SUPPORT + +enum +{ + PPMD8_RESTORE_METHOD_RESTART, + PPMD8_RESTORE_METHOD_CUT_OFF + #ifdef PPMD8_FREEZE_SUPPORT + , PPMD8_RESTORE_METHOD_FREEZE + #endif + , PPMD8_RESTORE_METHOD_UNSUPPPORTED +}; + + + + + + + + +typedef struct +{ + CPpmd8_Context *MinContext, *MaxContext; + CPpmd_State *FoundState; + unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, RestoreMethod; + Int32 RunLength, InitRL; /* must be 32-bit at least */ + + UInt32 Size; + UInt32 GlueCount; + UInt32 AlignOffset; + Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; + + UInt32 Range; + UInt32 Code; + UInt32 Low; + union + { + IByteInPtr In; + IByteOutPtr Out; + } Stream; + + Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment + Byte Units2Indx[128]; + CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; + UInt32 Stamps[PPMD_NUM_INDEXES]; + Byte NS2BSIndx[256], NS2Indx[260]; + Byte ExpEscape[16]; + CPpmd_See DummySee, See[24][32]; + UInt16 BinSumm[25][64]; + +} CPpmd8; + + +void Ppmd8_Construct(CPpmd8 *p); +BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc); +void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc); +void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); +#define Ppmd8_WasAllocated(p) ((p)->Base != NULL) + + +/* ---------- Internal Functions ---------- */ + +#define Ppmd8_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr) +#define Ppmd8_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd8_Context) +#define Ppmd8_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State) + +void Ppmd8_Update1(CPpmd8 *p); +void Ppmd8_Update1_0(CPpmd8 *p); +void Ppmd8_Update2(CPpmd8 *p); + + + + + + +#define Ppmd8_GetBinSumm(p) \ + &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]] \ + [ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \ + + p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ + + p->MinContext->Flags ] + + +CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); + + +/* 20.01: the original PPMdI encoder and decoder probably could work incorrectly in some rare cases, + where the original PPMdI code can give "Divide by Zero" operation. + We use the following fix to allow correct working of encoder and decoder in any cases. + We correct (Escape_Freq) and (_sum_), if (_sum_) is larger than p->Range) */ +#define PPMD8_CORRECT_SUM_RANGE(p, _sum_) if (_sum_ > p->Range /* /1 */) _sum_ = p->Range; + + +/* ---------- Decode ---------- */ + +#define PPMD8_SYM_END (-1) +#define PPMD8_SYM_ERROR (-2) + +/* +You must set (CPpmd8::Stream.In) before Ppmd8_RangeDec_Init() + +Ppmd8_DecodeSymbol() +out: + >= 0 : decoded byte + -1 : PPMD8_SYM_END : End of payload marker + -2 : PPMD8_SYM_ERROR : Data error +*/ + + +BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p); +#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) +int Ppmd8_DecodeSymbol(CPpmd8 *p); + + + + + + + + +/* ---------- Encode ---------- */ + +#define Ppmd8_Init_RangeEnc(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } +void Ppmd8_Flush_RangeEnc(CPpmd8 *p); +void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); + + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Ppmd8Dec.c p7zip-rar-16.02+really25.00+ds/C/Ppmd8Dec.c --- p7zip-rar-16.02/C/Ppmd8Dec.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd8Dec.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,157 +1,295 @@ -/* Ppmd8Dec.c -- PPMdI Decoder -2010-04-16 : Igor Pavlov : Public domain -This code is based on: - PPMd var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd8.h" - -#define kTop (1 << 24) -#define kBot (1 << 15) - -Bool Ppmd8_RangeDec_Init(CPpmd8 *p) -{ - unsigned i; - p->Low = 0; - p->Range = 0xFFFFFFFF; - p->Code = 0; - for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); - return (p->Code < 0xFFFFFFFF); -} - -static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total) -{ - return p->Code / (p->Range /= total); -} - -static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size) -{ - start *= p->Range; - p->Low += start; - p->Code -= start; - p->Range *= size; - - while ((p->Low ^ (p->Low + p->Range)) < kTop || - (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) - { - p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); - p->Range <<= 8; - p->Low <<= 8; - } -} - -#define MASK(sym) ((signed char *)charMask)[sym] - -int Ppmd8_DecodeSymbol(CPpmd8 *p) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 0) - { - CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); - unsigned i; - UInt32 count, hiCnt; - if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) - { - Byte symbol; - RangeDec_Decode(p, 0, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update1_0(p); - return symbol; - } - p->PrevSuccess = 0; - i = p->MinContext->NumStats; - do - { - if ((hiCnt += (++s)->Freq) > count) - { - Byte symbol; - RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update1(p); - return symbol; - } - } - while (--i); - if (count >= p->MinContext->SummFreq) - return -2; - RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt); - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats; - do { MASK((--s)->Symbol) = 0; } while (--i); - } - else - { - UInt16 *prob = Ppmd8_GetBinSumm(p); - if (((p->Code / (p->Range >>= 14)) < *prob)) - { - Byte symbol; - RangeDec_Decode(p, 0, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol; - Ppmd8_UpdateBin(p); - return symbol; - } - RangeDec_Decode(p, *prob, (1 << 14) - *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD8_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; - p->PrevSuccess = 0; - } - for (;;) - { - CPpmd_State *ps[256], *s; - UInt32 freqSum, count, hiCnt; - CPpmd_See *see; - unsigned i, num, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return -1; - p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - hiCnt = 0; - s = Ppmd8_GetStats(p, p->MinContext); - i = 0; - num = p->MinContext->NumStats - numMasked; - do - { - int k = (int)(MASK(s->Symbol)); - hiCnt += (s->Freq & k); - ps[i] = s++; - i -= k; - } - while (i != num); - - see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); - freqSum += hiCnt; - count = RangeDec_GetThreshold(p, freqSum); - - if (count < hiCnt) - { - Byte symbol; - CPpmd_State **pps = ps; - for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); - s = *pps; - RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); - Ppmd_See_Update(see); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update2(p); - return symbol; - } - if (count >= freqSum) - return -2; - RangeDec_Decode(p, hiCnt, freqSum - hiCnt); - see->Summ = (UInt16)(see->Summ + freqSum); - do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); - } -} +/* Ppmd8Dec.c -- Ppmd8 (PPMdI) Decoder +2023-09-07 : Igor Pavlov : Public domain +This code is based on: + PPMd var.I (2002): Dmitry Shkarin : Public domain + Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#include "Precomp.h" + +#include "Ppmd8.h" + +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) + +#define READ_BYTE(p) IByteIn_Read((p)->Stream.In) + +BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p) +{ + unsigned i; + p->Code = 0; + p->Range = 0xFFFFFFFF; + p->Low = 0; + + for (i = 0; i < 4; i++) + p->Code = (p->Code << 8) | READ_BYTE(p); + return (p->Code < 0xFFFFFFFF); +} + +#define RC_NORM(p) \ + while ((p->Low ^ (p->Low + p->Range)) < kTop \ + || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) { \ + p->Code = (p->Code << 8) | READ_BYTE(p); \ + p->Range <<= 8; p->Low <<= 8; } + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +#define R p + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd8_RD_Decode(CPpmd8 *p, UInt32 start, UInt32 size) +{ + start *= R->Range; + R->Low += start; + R->Code -= start; + R->Range *= size; + RC_NORM_LOCAL(R) +} + +#define RC_Decode(start, size) Ppmd8_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) + + +#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) +// typedef CPpmd8_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) +void Ppmd8_UpdateModel(CPpmd8 *p); + +#define MASK(sym) ((Byte *)charMask)[sym] + + +int Ppmd8_DecodeSymbol(CPpmd8 *p) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 0) + { + CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); + unsigned i; + UInt32 count, hiCnt; + UInt32 summFreq = p->MinContext->Union2.SummFreq; + + PPMD8_CORRECT_SUM_RANGE(p, summFreq) + + + count = RC_GetThreshold(summFreq); + hiCnt = count; + + if ((Int32)(count -= s->Freq) < 0) + { + Byte sym; + RC_DecodeFinal(0, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd8_Update1_0(p); + return sym; + } + + p->PrevSuccess = 0; + i = p->MinContext->NumStats; + + do + { + if ((Int32)(count -= (++s)->Freq) < 0) + { + Byte sym; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + p->FoundState = s; + sym = s->Symbol; + Ppmd8_Update1(p); + return sym; + } + } + while (--i); + + if (hiCnt >= summFreq) + return PPMD8_SYM_ERROR; + + hiCnt -= count; + RC_Decode(hiCnt, summFreq - hiCnt) + + + PPMD_SetAllBitsIn256Bytes(charMask) + // i = p->MinContext->NumStats - 1; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); + UInt16 *prob = Ppmd8_GetBinSumm(p); + UInt32 pr = *prob; + UInt32 size0 = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + + if (R->Code < size0) + { + Byte sym; + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + + // RangeDec_DecodeBit0(size0); + R->Range = size0; + RC_NORM(R) + + + + // sym = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol; + // Ppmd8_UpdateBin(p); + { + unsigned freq = s->Freq; + CPpmd8_Context *c = CTX(SUCCESSOR(s)); + sym = s->Symbol; + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 196)); + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart) + p->MaxContext = p->MinContext = c; + else + Ppmd8_UpdateModel(p); + } + return sym; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + + // RangeDec_DecodeBit1(rc2, size0); + R->Low += size0; + R->Code -= size0; + R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - size0; + RC_NORM_LOCAL(R) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_State *s, *s2; + UInt32 freqSum, count, hiCnt; + UInt32 freqSum2; + CPpmd_See *see; + CPpmd8_Context *mc; + unsigned numMasked; + RC_NORM_REMOTE(R) + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return PPMD8_SYM_END; + mc = Ppmd8_GetContext(p, mc->Suffix); + } + while (mc->NumStats == numMasked); + + s = Ppmd8_GetStats(p, mc); + + { + unsigned num = (unsigned)mc->NumStats + 1; + unsigned num2 = num / 2; + + num &= 1; + hiCnt = (s->Freq & (UInt32)(MASK(s->Symbol))) & (0 - (UInt32)num); + s += num; + p->MinContext = mc; + + do + { + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; + s += 2; + hiCnt += (s[-2].Freq & (UInt32)(MASK(sym0))); + hiCnt += (s[-1].Freq & (UInt32)(MASK(sym1))); + } + while (--num2); + } + + see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); + freqSum += hiCnt; + freqSum2 = freqSum; + PPMD8_CORRECT_SUM_RANGE(R, freqSum2) + + + count = RC_GetThreshold(freqSum2); + + if (count < hiCnt) + { + Byte sym; + // Ppmd_See_UPDATE(see) // new (see->Summ) value can overflow over 16-bits in some rare cases + s = Ppmd8_GetStats(p, p->MinContext); + hiCnt = count; + + + { + for (;;) + { + count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + // count -= s->Freq & (UInt32)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; + } + } + s--; + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) + + // new (see->Summ) value can overflow over 16-bits in some rare cases + Ppmd_See_UPDATE(see) + p->FoundState = s; + sym = s->Symbol; + Ppmd8_Update2(p); + return sym; + } + + if (count >= freqSum2) + return PPMD8_SYM_ERROR; + + RC_Decode(hiCnt, freqSum2 - hiCnt) + + // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. + // new (see->Summ) value can overflow over 16-bits in some rare cases + see->Summ = (UInt16)(see->Summ + freqSum); + + s = Ppmd8_GetStats(p, p->MinContext); + s2 = s + p->MinContext->NumStats + 1; + do + { + MASK(s->Symbol) = 0; + s++; + } + while (s != s2); + } +} + +#undef kTop +#undef kBot +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru p7zip-rar-16.02/C/Ppmd8Enc.c p7zip-rar-16.02+really25.00+ds/C/Ppmd8Enc.c --- p7zip-rar-16.02/C/Ppmd8Enc.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Ppmd8Enc.c 2023-09-07 11:00:00.000000000 +0000 @@ -1,163 +1,337 @@ -/* Ppmd8Enc.c -- PPMdI Encoder -2010-04-16 : Igor Pavlov : Public domain -This code is based on: - PPMd var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#include "Precomp.h" - -#include "Ppmd8.h" - -#define kTop (1 << 24) -#define kBot (1 << 15) - -void Ppmd8_RangeEnc_FlushData(CPpmd8 *p) -{ - unsigned i; - for (i = 0; i < 4; i++, p->Low <<= 8 ) - p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24)); -} - -static void RangeEnc_Normalize(CPpmd8 *p) -{ - while ((p->Low ^ (p->Low + p->Range)) < kTop || - (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) - { - p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24)); - p->Range <<= 8; - p->Low <<= 8; - } -} - -static void RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total) -{ - p->Low += start * (p->Range /= total); - p->Range *= size; - RangeEnc_Normalize(p); -} - -static void RangeEnc_EncodeBit_0(CPpmd8 *p, UInt32 size0) -{ - p->Range >>= 14; - p->Range *= size0; - RangeEnc_Normalize(p); -} - -static void RangeEnc_EncodeBit_1(CPpmd8 *p, UInt32 size0) -{ - p->Low += size0 * (p->Range >>= 14); - p->Range *= ((1 << 14) - size0); - RangeEnc_Normalize(p); -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 0) - { - CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); - UInt32 sum; - unsigned i; - if (s->Symbol == symbol) - { - RangeEnc_Encode(p, 0, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd8_Update1_0(p); - return; - } - p->PrevSuccess = 0; - sum = s->Freq; - i = p->MinContext->NumStats; - do - { - if ((++s)->Symbol == symbol) - { - RangeEnc_Encode(p, sum, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd8_Update1(p); - return; - } - sum += s->Freq; - } - while (--i); - - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats; - do { MASK((--s)->Symbol) = 0; } while (--i); - RangeEnc_Encode(p, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); - } - else - { - UInt16 *prob = Ppmd8_GetBinSumm(p); - CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); - if (s->Symbol == symbol) - { - RangeEnc_EncodeBit_0(p, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - p->FoundState = s; - Ppmd8_UpdateBin(p); - return; - } - else - { - RangeEnc_EncodeBit_1(p, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD8_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - p->PrevSuccess = 0; - } - } - for (;;) - { - UInt32 escFreq; - CPpmd_See *see; - CPpmd_State *s; - UInt32 sum; - unsigned i, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return; /* EndMarker (symbol = -1) */ - p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - - see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq); - s = Ppmd8_GetStats(p, p->MinContext); - sum = 0; - i = p->MinContext->NumStats + 1; - do - { - int cur = s->Symbol; - if (cur == symbol) - { - UInt32 low = sum; - CPpmd_State *s1 = s; - do - { - sum += (s->Freq & (int)(MASK(s->Symbol))); - s++; - } - while (--i); - RangeEnc_Encode(p, low, s1->Freq, sum + escFreq); - Ppmd_See_Update(see); - p->FoundState = s1; - Ppmd8_Update2(p); - return; - } - sum += (s->Freq & (int)(MASK(cur))); - MASK(cur) = 0; - s++; - } - while (--i); - - RangeEnc_Encode(p, sum, escFreq, sum + escFreq); - see->Summ = (UInt16)(see->Summ + sum + escFreq); - } -} +/* Ppmd8Enc.c -- Ppmd8 (PPMdI) Encoder +2023-09-07 : Igor Pavlov : Public domain +This code is based on: + PPMd var.I (2002): Dmitry Shkarin : Public domain + Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#include "Precomp.h" + +#include "Ppmd8.h" + +#define kTop ((UInt32)1 << 24) +#define kBot ((UInt32)1 << 15) + +#define WRITE_BYTE(p) IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24)) + +void Ppmd8_Flush_RangeEnc(CPpmd8 *p) +{ + unsigned i; + for (i = 0; i < 4; i++, p->Low <<= 8 ) + WRITE_BYTE(p); +} + + + + + + +#define RC_NORM(p) \ + while ((p->Low ^ (p->Low + p->Range)) < kTop \ + || (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) \ + { WRITE_BYTE(p); p->Range <<= 8; p->Low <<= 8; } + + + + + + + + + + + + + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +// #define RC_PRE(total) p->Range /= total; +// #define RC_PRE(total) + +#define R p + + + + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd8_RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total) +{ + R->Low += start * (R->Range /= total); + R->Range *= size; + RC_NORM_LOCAL(R) +} + + + + + + + + + + +#define RC_Encode(start, size, total) Ppmd8_RangeEnc_Encode(p, start, size, total); +#define RC_EncodeFinal(start, size, total) RC_Encode(start, size, total) RC_NORM_REMOTE(p) + +#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) + +// typedef CPpmd8_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) + +void Ppmd8_UpdateModel(CPpmd8 *p); + +#define MASK(sym) ((Byte *)charMask)[sym] + +// Z7_FORCE_INLINE +// static +void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 0) + { + CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); + UInt32 sum; + unsigned i; + UInt32 summFreq = p->MinContext->Union2.SummFreq; + + PPMD8_CORRECT_SUM_RANGE(p, summFreq) + + // RC_PRE(summFreq); + + if (s->Symbol == symbol) + { + + RC_EncodeFinal(0, s->Freq, summFreq) + p->FoundState = s; + Ppmd8_Update1_0(p); + return; + } + p->PrevSuccess = 0; + sum = s->Freq; + i = p->MinContext->NumStats; + do + { + if ((++s)->Symbol == symbol) + { + + RC_EncodeFinal(sum, s->Freq, summFreq) + p->FoundState = s; + Ppmd8_Update1(p); + return; + } + sum += s->Freq; + } + while (--i); + + + RC_Encode(sum, summFreq - sum, summFreq) + + + PPMD_SetAllBitsIn256Bytes(charMask) + // MASK(s->Symbol) = 0; + // i = p->MinContext->NumStats; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + UInt16 *prob = Ppmd8_GetBinSumm(p); + CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); + UInt32 pr = *prob; + const UInt32 bound = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + if (s->Symbol == symbol) + { + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + // RangeEnc_EncodeBit_0(p, bound); + R->Range = bound; + RC_NORM(R) + + // p->FoundState = s; + // Ppmd8_UpdateBin(p); + { + const unsigned freq = s->Freq; + CPpmd8_Context *c = CTX(SUCCESSOR(s)); + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 196)); // Ppmd8 (196) + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c >= p->UnitsStart) + p->MaxContext = p->MinContext = c; + else + Ppmd8_UpdateModel(p); + } + return; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + // RangeEnc_EncodeBit_1(p, bound); + R->Low += bound; + R->Range = (R->Range & ~((UInt32)PPMD_BIN_SCALE - 1)) - bound; + RC_NORM_LOCAL(R) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(s->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_See *see; + CPpmd_State *s; + UInt32 sum, escFreq; + CPpmd8_Context *mc; + unsigned i, numMasked; + + RC_NORM_REMOTE(p) + + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return; /* EndMarker (symbol = -1) */ + mc = Ppmd8_GetContext(p, mc->Suffix); + + } + while (mc->NumStats == numMasked); + + p->MinContext = mc; + + see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq); + + + + + + + + + + + + + + + + + + + + + + + + + s = Ppmd8_GetStats(p, p->MinContext); + sum = 0; + i = (unsigned)p->MinContext->NumStats + 1; + + do + { + const unsigned cur = s->Symbol; + if ((int)cur == symbol) + { + const UInt32 low = sum; + const UInt32 freq = s->Freq; + unsigned num2; + + Ppmd_See_UPDATE(see) + p->FoundState = s; + sum += escFreq; + + num2 = i / 2; + i &= 1; + sum += freq & (0 - (UInt32)i); + if (num2 != 0) + { + s += i; + do + { + const unsigned sym0 = s[0].Symbol; + const unsigned sym1 = s[1].Symbol; + s += 2; + sum += (s[-2].Freq & (unsigned)(MASK(sym0))); + sum += (s[-1].Freq & (unsigned)(MASK(sym1))); + } + while (--num2); + } + + PPMD8_CORRECT_SUM_RANGE(p, sum) + + RC_EncodeFinal(low, freq, sum) + Ppmd8_Update2(p); + return; + } + sum += (s->Freq & (unsigned)(MASK(cur))); + s++; + } + while (--i); + + { + UInt32 total = sum + escFreq; + see->Summ = (UInt16)(see->Summ + total); + PPMD8_CORRECT_SUM_RANGE(p, total) + + RC_Encode(sum, total - sum, total) + } + + { + const CPpmd_State *s2 = Ppmd8_GetStats(p, p->MinContext); + s--; + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } +} + + + + + + + + + +#undef kTop +#undef kBot +#undef WRITE_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Encode +#undef RC_EncodeFinal + +#undef CTX +#undef SUCCESSOR +#undef MASK diff -Nru p7zip-rar-16.02/C/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Precomp.h --- p7zip-rar-16.02/C/Precomp.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Precomp.h 2024-01-26 11:00:00.000000000 +0000 @@ -1,10 +1,127 @@ -/* Precomp.h -- StdAfx -2013-11-12 : Igor Pavlov : Public domain */ - -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H - -#include "Compiler.h" -/* #include "7zTypes.h" */ - -#endif +/* Precomp.h -- precompilation file +2024-01-25 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_PRECOMP_H +#define ZIP7_INC_PRECOMP_H + +/* + this file must be included before another *.h files and before . + this file is included from the following files: + C\*.c + C\Util\*\Precomp.h <- C\Util\*\*.c + CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp + + this file can set the following macros: + Z7_LARGE_PAGES 1 + Z7_LONG_PATH 1 + Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip + _WIN32_WINNT 0x0500 (or higher) + WINVER _WIN32_WINNT + UNICODE 1 + _UNICODE 1 +*/ + +#include "Compiler.h" + +#ifdef _MSC_VER +// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#if _MSC_VER >= 1912 +// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception. +#endif +#endif + +/* +// for debug: +#define UNICODE 1 +#define _UNICODE 1 +#define _WIN32_WINNT 0x0500 // win2000 +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +*/ + +#ifdef _WIN32 +/* + this "Precomp.h" file must be included before , + if we want to define _WIN32_WINNT before . +*/ + +#ifndef Z7_LARGE_PAGES +#ifndef Z7_NO_LARGE_PAGES +#define Z7_LARGE_PAGES 1 +#endif +#endif + +#ifndef Z7_LONG_PATH +#ifndef Z7_NO_LONG_PATH +#define Z7_LONG_PATH 1 +#endif +#endif + +#ifndef Z7_DEVICE_FILE +#ifndef Z7_NO_DEVICE_FILE +// #define Z7_DEVICE_FILE 1 +#endif +#endif + +// we don't change macros if included after +#ifndef _WINDOWS_ + +#ifndef Z7_WIN32_WINNT_MIN + #if defined(_M_ARM64) || defined(__aarch64__) + // #define Z7_WIN32_WINNT_MIN 0x0a00 // win10 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT) + // #define Z7_WIN32_WINNT_MIN 0x0602 // win8 + #define Z7_WIN32_WINNT_MIN 0x0600 // vista + #elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64) + #define Z7_WIN32_WINNT_MIN 0x0503 // win2003 + // #elif defined(_M_IX86) || defined(__i386__) + // #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + #else // x86 and another(old) systems + #define Z7_WIN32_WINNT_MIN 0x0500 // win2000 + // #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug + #endif +#endif // Z7_WIN32_WINNT_MIN + + +#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT +#ifdef _WIN32_WINNT + // #error Stop_Compiling_Bad_WIN32_WINNT +#else + #ifndef Z7_NO_DEFINE_WIN32_WINNT +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define _WIN32_WINNT Z7_WIN32_WINNT_MIN +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER + #endif +#endif // _WIN32_WINNT + +#ifndef WINVER + #define WINVER _WIN32_WINNT +#endif +#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT + + +#ifndef _MBCS +#ifndef Z7_NO_UNICODE +// UNICODE and _UNICODE are used by and by 7-zip code. + +#ifndef UNICODE +#define UNICODE 1 +#endif + +#ifndef _UNICODE +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _UNICODE 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // Z7_NO_UNICODE +#endif // _MBCS +#endif // _WINDOWS_ + +// #include "7zWindows.h" + +#endif // _WIN32 + +#endif diff -Nru p7zip-rar-16.02/C/RotateDefs.h p7zip-rar-16.02+really25.00+ds/C/RotateDefs.h --- p7zip-rar-16.02/C/RotateDefs.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/RotateDefs.h 2023-06-18 11:00:00.000000000 +0000 @@ -1,30 +1,50 @@ -/* RotateDefs.h -- Rotate functions -2015-03-25 : Igor Pavlov : Public domain */ - -#ifndef __ROTATE_DEFS_H -#define __ROTATE_DEFS_H - -#ifdef _MSC_VER - -#include - -/* don't use _rotl with MINGW. It can insert slow call to function. */ - -/* #if (_MSC_VER >= 1200) */ -#pragma intrinsic(_rotl) -#pragma intrinsic(_rotr) -/* #endif */ - -#define rotlFixed(x, n) _rotl((x), (n)) -#define rotrFixed(x, n) _rotr((x), (n)) - -#else - -/* new compilers can translate these macros to fast commands. */ - -#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) -#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) - -#endif - -#endif +/* RotateDefs.h -- Rotate functions +2023-06-18 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ROTATE_DEFS_H +#define ZIP7_INC_ROTATE_DEFS_H + +#ifdef _MSC_VER + +#include + +/* don't use _rotl with old MINGW. It can insert slow call to function. */ + +/* #if (_MSC_VER >= 1200) */ +#pragma intrinsic(_rotl) +#pragma intrinsic(_rotr) +/* #endif */ + +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#if (_MSC_VER >= 1300) +#define Z7_ROTL64(x, n) _rotl64((x), (n)) +#define Z7_ROTR64(x, n) _rotr64((x), (n)) +#else +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#else + +/* new compilers can translate these macros to fast commands. */ + +#if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5) +/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63))) +#else +/* for old GCC / clang: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#endif + +#endif diff -Nru p7zip-rar-16.02/C/Sha1.c p7zip-rar-16.02+really25.00+ds/C/Sha1.c --- p7zip-rar-16.02/C/Sha1.c 2016-06-11 08:08:05.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha1.c 2024-10-29 18:00:00.000000000 +0000 @@ -1,340 +1,441 @@ -/* Sha1.c -- SHA-1 Hash -2016-05-20 : Igor Pavlov : Public domain -This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ - -#include "Precomp.h" - -#include - -#include "CpuArch.h" -#include "RotateDefs.h" -#include "Sha1.h" - -// define it for speed optimization -// #define _SHA1_UNROLL - -#ifdef _SHA1_UNROLL - #define kNumW 16 - #define WW(i) W[(i)&15] -#else - #define kNumW 80 - #define WW(i) W[i] -#endif - -#define w0(i) (W[i] = data[i]) - -#define w1(i) (WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1)) - -#define f1(x,y,z) (z^(x&(y^z))) -#define f2(x,y,z) (x^y^z) -#define f3(x,y,z) ((x&y)|(z&(x|y))) -#define f4(x,y,z) (x^y^z) - -#define RK(a,b,c,d,e, fx, w, k) e += fx(b,c,d) + w + k + rotlFixed(a,5); b = rotlFixed(b,30); - -#define R0(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w0(i), 0x5A827999) -#define R1(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w1(i), 0x5A827999) -#define R2(a,b,c,d,e, i) RK(a,b,c,d,e, f2, w1(i), 0x6ED9EBA1) -#define R3(a,b,c,d,e, i) RK(a,b,c,d,e, f3, w1(i), 0x8F1BBCDC) -#define R4(a,b,c,d,e, i) RK(a,b,c,d,e, f4, w1(i), 0xCA62C1D6) - -#define RX_1_4(rx1, rx4, i) \ - rx1(a,b,c,d,e, i); \ - rx4(e,a,b,c,d, i+1); \ - rx4(d,e,a,b,c, i+2); \ - rx4(c,d,e,a,b, i+3); \ - rx4(b,c,d,e,a, i+4); \ - -#define RX_5(rx, i) RX_1_4(rx, rx, i); - -#ifdef _SHA1_UNROLL - - #define RX_15 \ - RX_5(R0, 0); \ - RX_5(R0, 5); \ - RX_5(R0, 10); - - #define RX_20(rx, i) \ - RX_5(rx, i); \ - RX_5(rx, i + 5); \ - RX_5(rx, i + 10); \ - RX_5(rx, i + 15); - -#else - -#define RX_15 { unsigned i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } } -#define RX_20(rx, ii) { unsigned i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } } - -#endif - - -void Sha1_Init(CSha1 *p) -{ - p->state[0] = 0x67452301; - p->state[1] = 0xEFCDAB89; - p->state[2] = 0x98BADCFE; - p->state[3] = 0x10325476; - p->state[4] = 0xC3D2E1F0; - p->count = 0; -} - -void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest) -{ - UInt32 a, b, c, d, e; - UInt32 W[kNumW]; - - a = p->state[0]; - b = p->state[1]; - c = p->state[2]; - d = p->state[3]; - e = p->state[4]; - - RX_15 - - RX_1_4(R0, R1, 15); - - RX_20(R2, 20); - RX_20(R3, 40); - RX_20(R4, 60); - - destDigest[0] = p->state[0] + a; - destDigest[1] = p->state[1] + b; - destDigest[2] = p->state[2] + c; - destDigest[3] = p->state[3] + d; - destDigest[4] = p->state[4] + e; -} - -void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes) -{ - UInt32 a, b, c, d, e; - UInt32 W[kNumW]; - - a = p->state[0]; - b = p->state[1]; - c = p->state[2]; - d = p->state[3]; - e = p->state[4]; - - RX_15 - - RX_1_4(R0, R1, 15); - - RX_20(R2, 20); - RX_20(R3, 40); - RX_20(R4, 60); - - p->state[0] += a; - p->state[1] += b; - p->state[2] += c; - p->state[3] += d; - p->state[4] += e; - - if (returnRes) - { - unsigned i; - for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++) - data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i]; - } -} - -#define Sha1_UpdateBlock(p) Sha1_GetBlockDigest(p, p->buffer, p->state) - -void Sha1_Update(CSha1 *p, const Byte *data, size_t size) -{ - unsigned pos, pos2; - if (size == 0) - return; - pos = (unsigned)p->count & 0x3F; - p->count += size; - pos2 = pos & 3; - pos >>= 2; - - if (pos2 != 0) - { - UInt32 w; - pos2 = (3 - pos2) * 8; - w = ((UInt32)*data++) << pos2; - if (--size && pos2) - { - pos2 -= 8; - w |= ((UInt32)*data++) << pos2; - if (--size && pos2) - { - pos2 -= 8; - w |= ((UInt32)*data++) << pos2; - size--; - } - } - p->buffer[pos] |= w; - if (pos2 == 0) - pos++; - } - - for (;;) - { - if (pos == SHA1_NUM_BLOCK_WORDS) - { - for (;;) - { - unsigned i; - Sha1_UpdateBlock(p); - if (size < SHA1_BLOCK_SIZE) - break; - size -= SHA1_BLOCK_SIZE; - for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i += 2) - { - p->buffer[i ] = GetBe32(data); - p->buffer[i + 1] = GetBe32(data + 4); - data += 8; - } - } - pos = 0; - } - if (size < 4) - break; - - p->buffer[pos] = GetBe32(data); - data += 4; - size -= 4; - pos++; - } - - if (size != 0) - { - UInt32 w = ((UInt32)data[0]) << 24; - if (size > 1) - { - w |= ((UInt32)data[1]) << 16; - if (size > 2) - w |= ((UInt32)data[2]) << 8; - } - p->buffer[pos] = w; - } -} - -void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */) -{ - int returnRes = False; - - unsigned pos = (unsigned)p->count & 0x3F; - p->count += size; - - while (size--) - { - unsigned pos2 = (pos & 3); - UInt32 v = ((UInt32)*data++) << (8 * (3 - pos2)); - UInt32 *ref = &(p->buffer[pos >> 2]); - pos++; - if (pos2 == 0) - { - *ref = v; - continue; - } - *ref |= v; - - if (pos == SHA1_BLOCK_SIZE) - { - pos = 0; - Sha1_UpdateBlock_Rar(p, p->buffer, returnRes); - if (returnRes) - { - unsigned i; - for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) - { - UInt32 d = p->buffer[i]; - Byte *prev = data + i * 4 - SHA1_BLOCK_SIZE; - SetUi32(prev, d); - } - } - // returnRes = rar350Mode; - returnRes = True; - } - } -} - -void Sha1_Final(CSha1 *p, Byte *digest) -{ - unsigned pos = (unsigned)p->count & 0x3F; - unsigned pos2 = (pos & 3); - UInt64 numBits; - UInt32 w; - unsigned i; - - pos >>= 2; - - w = 0; - if (pos2 != 0) - w = p->buffer[pos]; - p->buffer[pos++] = w | (((UInt32)0x80000000) >> (8 * pos2)); - - while (pos != (SHA1_NUM_BLOCK_WORDS - 2)) - { - pos &= 0xF; - if (pos == 0) - Sha1_UpdateBlock(p); - p->buffer[pos++] = 0; - } - - numBits = (p->count << 3); - p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); - p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); - Sha1_UpdateBlock(p); - - for (i = 0; i < SHA1_NUM_DIGEST_WORDS; i++) - { - UInt32 v = p->state[i]; - SetBe32(digest, v); - digest += 4; - } - - Sha1_Init(p); -} - - -void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size) -{ - const UInt64 numBits = (p->count + size) << 5; - block[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); - block[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); - block[size++] = 0x80000000; - while (size != (SHA1_NUM_BLOCK_WORDS - 2)) - block[size++] = 0; -} - -void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size) -{ - unsigned pos = (unsigned)p->count & 0xF; - p->count += size; - while (size--) - { - p->buffer[pos++] = *data++; - if (pos == SHA1_NUM_BLOCK_WORDS) - { - pos = 0; - Sha1_UpdateBlock(p); - } - } -} - -void Sha1_32_Final(CSha1 *p, UInt32 *digest) -{ - UInt64 numBits; - unsigned pos = (unsigned)p->count & 0xF; - p->buffer[pos++] = 0x80000000; - - while (pos != (SHA1_NUM_BLOCK_WORDS - 2)) - { - pos &= 0xF; - if (pos == 0) - Sha1_UpdateBlock(p); - p->buffer[pos++] = 0; - } - - numBits = (p->count << 5); - p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); - p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); - - Sha1_GetBlockDigest(p, p->buffer, digest); - - Sha1_Init(p); -} +/* Sha1.c -- SHA-1 Hash +: Igor Pavlov : Public domain +This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha1.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) \ + || defined(_MSC_VER) && (_MSC_VER >= 1200) + #define Z7_COMPILER_SHA1_SUPPORTED + #endif +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \ + && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037)) + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define Z7_COMPILER_SHA1_SUPPORTED + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define Z7_COMPILER_SHA1_SUPPORTED + #endif + #endif + #endif + #endif +#endif + +void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); + +#ifdef Z7_COMPILER_SHA1_SUPPORTED + void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); + + static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS = Sha1_UpdateBlocks; + static SHA1_FUNC_UPDATE_BLOCKS g_SHA1_FUNC_UPDATE_BLOCKS_HW; + + #define SHA1_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks +#else + #define SHA1_UPDATE_BLOCKS(p) Sha1_UpdateBlocks +#endif + + +BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo) +{ + SHA1_FUNC_UPDATE_BLOCKS func = Sha1_UpdateBlocks; + + #ifdef Z7_COMPILER_SHA1_SUPPORTED + if (algo != SHA1_ALGO_SW) + { + if (algo == SHA1_ALGO_DEFAULT) + func = g_SHA1_FUNC_UPDATE_BLOCKS; + else + { + if (algo != SHA1_ALGO_HW) + return False; + func = g_SHA1_FUNC_UPDATE_BLOCKS_HW; + if (!func) + return False; + } + } + #else + if (algo > 1) + return False; + #endif + + p->v.vars.func_UpdateBlocks = func; + return True; +} + + +/* define it for speed optimization */ +// #define Z7_SHA1_UNROLL + +// allowed unroll steps: (1, 2, 4, 5, 20) + +#undef Z7_SHA1_BIG_W +#ifdef Z7_SHA1_UNROLL + #define STEP_PRE 20 + #define STEP_MAIN 20 +#else + #define Z7_SHA1_BIG_W + #define STEP_PRE 5 + #define STEP_MAIN 5 +#endif + + +#ifdef Z7_SHA1_BIG_W + #define kNumW 80 + #define w(i) W[i] +#else + #define kNumW 16 + #define w(i) W[(i)&15] +#endif + +#define w0(i) (W[i] = GetBe32(data + (size_t)(i) * 4)) +#define w1(i) (w(i) = rotlFixed(w((size_t)(i)-3) ^ w((size_t)(i)-8) ^ w((size_t)(i)-14) ^ w((size_t)(i)-16), 1)) + +#define f0(x,y,z) ( 0x5a827999 + (z^(x&(y^z))) ) +#define f1(x,y,z) ( 0x6ed9eba1 + (x^y^z) ) +#define f2(x,y,z) ( 0x8f1bbcdc + ((x&y)|(z&(x|y))) ) +#define f3(x,y,z) ( 0xca62c1d6 + (x^y^z) ) + +/* +#define T1(fx, ww) \ + tmp = e + fx(b,c,d) + ww + rotlFixed(a, 5); \ + e = d; \ + d = c; \ + c = rotlFixed(b, 30); \ + b = a; \ + a = tmp; \ +*/ + +#define T5(a,b,c,d,e, fx, ww) \ + e += fx(b,c,d) + ww + rotlFixed(a, 5); \ + b = rotlFixed(b, 30); \ + + +/* +#define R1(i, fx, wx) \ + T1 ( fx, wx(i)); \ + +#define R2(i, fx, wx) \ + R1 ( (i) , fx, wx); \ + R1 ( (i) + 1, fx, wx); \ + +#define R4(i, fx, wx) \ + R2 ( (i) , fx, wx); \ + R2 ( (i) + 2, fx, wx); \ +*/ + +#define M5(i, fx, wx0, wx1) \ + T5 ( a,b,c,d,e, fx, wx0((i) ) ) \ + T5 ( e,a,b,c,d, fx, wx1((i)+1) ) \ + T5 ( d,e,a,b,c, fx, wx1((i)+2) ) \ + T5 ( c,d,e,a,b, fx, wx1((i)+3) ) \ + T5 ( b,c,d,e,a, fx, wx1((i)+4) ) \ + +#define R5(i, fx, wx) \ + M5 ( i, fx, wx, wx) \ + + +#if STEP_PRE > 5 + + #define R20_START \ + R5 ( 0, f0, w0) \ + R5 ( 5, f0, w0) \ + R5 ( 10, f0, w0) \ + M5 ( 15, f0, w0, w1) \ + + #elif STEP_PRE == 5 + + #define R20_START \ + { size_t i; for (i = 0; i < 15; i += STEP_PRE) \ + { R5(i, f0, w0) } } \ + M5 ( 15, f0, w0, w1) \ + +#else + + #if STEP_PRE == 1 + #define R_PRE R1 + #elif STEP_PRE == 2 + #define R_PRE R2 + #elif STEP_PRE == 4 + #define R_PRE R4 + #endif + + #define R20_START \ + { size_t i; for (i = 0; i < 16; i += STEP_PRE) \ + { R_PRE(i, f0, w0) } } \ + R4 ( 16, f0, w1) \ + +#endif + + + +#if STEP_MAIN > 5 + + #define R20(ii, fx) \ + R5 ( (ii) , fx, w1) \ + R5 ( (ii) + 5 , fx, w1) \ + R5 ( (ii) + 10, fx, w1) \ + R5 ( (ii) + 15, fx, w1) \ + +#else + + #if STEP_MAIN == 1 + #define R_MAIN R1 + #elif STEP_MAIN == 2 + #define R_MAIN R2 + #elif STEP_MAIN == 4 + #define R_MAIN R4 + #elif STEP_MAIN == 5 + #define R_MAIN R5 + #endif + + #define R20(ii, fx) \ + { size_t i; for (i = (ii); i < (ii) + 20; i += STEP_MAIN) \ + { R_MAIN(i, fx, w1) } } \ + +#endif + + + +void Sha1_InitState(CSha1 *p) +{ + p->v.vars.count = 0; + p->state[0] = 0x67452301; + p->state[1] = 0xEFCDAB89; + p->state[2] = 0x98BADCFE; + p->state[3] = 0x10325476; + p->state[4] = 0xC3D2E1F0; +} + +void Sha1_Init(CSha1 *p) +{ + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA1_SUPPORTED + g_SHA1_FUNC_UPDATE_BLOCKS; + #else + NULL; + #endif + Sha1_InitState(p); +} + + +Z7_NO_INLINE +void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks) +{ + UInt32 a, b, c, d, e; + UInt32 W[kNumW]; + + if (numBlocks == 0) + return; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + do + { + #if STEP_PRE < 5 || STEP_MAIN < 5 + UInt32 tmp; + #endif + + R20_START + R20(20, f1) + R20(40, f2) + R20(60, f3) + + a += state[0]; + b += state[1]; + c += state[2]; + d += state[3]; + e += state[4]; + + state[0] = a; + state[1] = b; + state[2] = c; + state[3] = d; + state[4] = e; + + data += SHA1_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Sha1_UpdateBlock(p) SHA1_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Sha1_Update(CSha1 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1); + const unsigned num = SHA1_BLOCK_SIZE - pos; + p->v.vars.count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha1_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 6; + // if (numBlocks) + SHA1_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA1_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 6); + memcpy(p->buffer, data, size); + } +} + + +void Sha1_Final(CSha1 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->v.vars.count & (SHA1_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (SHA1_BLOCK_SIZE - 4 * 2)) + { + while (pos != SHA1_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA1_BLOCK_SIZE - pos); + Sha1_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (SHA1_BLOCK_SIZE - 4 * 2) - pos); + { + const UInt64 numBits = p->v.vars.count << 3; + SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32)) + SetBe32(p->buffer + SHA1_BLOCK_SIZE - 4 * 1, (UInt32)(numBits)) + } + Sha1_UpdateBlock(p); + + SetBe32(digest, p->state[0]) + SetBe32(digest + 4, p->state[1]) + SetBe32(digest + 8, p->state[2]) + SetBe32(digest + 12, p->state[3]) + SetBe32(digest + 16, p->state[4]) + + Sha1_InitState(p); +} + + +void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size) +{ + const UInt64 numBits = (p->v.vars.count + size) << 3; + SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 2], (UInt32)(numBits >> 32)) + SetBe32(&((UInt32 *)(void *)block)[SHA1_NUM_BLOCK_WORDS - 1], (UInt32)(numBits)) + // SetBe32((UInt32 *)(block + size), 0x80000000); + SetUi32((UInt32 *)(void *)(block + size), 0x80) + size += 4; + while (size != (SHA1_NUM_BLOCK_WORDS - 2) * 4) + { + *((UInt32 *)(void *)(block + size)) = 0; + size += 4; + } +} + +void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest) +{ + MY_ALIGN (16) + UInt32 st[SHA1_NUM_DIGEST_WORDS]; + + st[0] = p->state[0]; + st[1] = p->state[1]; + st[2] = p->state[2]; + st[3] = p->state[3]; + st[4] = p->state[4]; + + SHA1_UPDATE_BLOCKS(p)(st, data, 1); + + SetBe32(destDigest + 0 , st[0]) + SetBe32(destDigest + 1 * 4, st[1]) + SetBe32(destDigest + 2 * 4, st[2]) + SetBe32(destDigest + 3 * 4, st[3]) + SetBe32(destDigest + 4 * 4, st[4]) +} + + +void Sha1Prepare(void) +{ +#ifdef Z7_COMPILER_SHA1_SUPPORTED + SHA1_FUNC_UPDATE_BLOCKS f, f_hw; + f = Sha1_UpdateBlocks; + f_hw = NULL; +#ifdef MY_CPU_X86_OR_AMD64 + if (CPU_IsSupported_SHA() + && CPU_IsSupported_SSSE3() + ) +#else + if (CPU_IsSupported_SHA1()) +#endif + { + // printf("\n========== HW SHA1 ======== \n"); +#if 1 && defined(MY_CPU_ARM_OR_ARM64) && defined(Z7_MSC_VER_ORIGINAL) && (_MSC_FULL_VER < 192930037) + /* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037). + It generated incorrect SHA-1 code. */ + #pragma message("== SHA1 code can work incorrectly with this compiler") + #error Stop_Compiling_MSC_Compiler_BUG_SHA1 +#endif + { + f = f_hw = Sha1_UpdateBlocks_HW; + } + } + g_SHA1_FUNC_UPDATE_BLOCKS = f; + g_SHA1_FUNC_UPDATE_BLOCKS_HW = f_hw; +#endif +} + +#undef kNumW +#undef w +#undef w0 +#undef w1 +#undef f0 +#undef f1 +#undef f2 +#undef f3 +#undef T1 +#undef T5 +#undef M5 +#undef R1 +#undef R2 +#undef R4 +#undef R5 +#undef R20_START +#undef R_PRE +#undef R_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA1_BIG_W +#undef Z7_SHA1_UNROLL +#undef Z7_COMPILER_SHA1_SUPPORTED diff -Nru p7zip-rar-16.02/C/Sha1.h p7zip-rar-16.02+really25.00+ds/C/Sha1.h --- p7zip-rar-16.02/C/Sha1.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha1.h 2024-10-28 10:00:00.000000000 +0000 @@ -1,38 +1,86 @@ -/* Sha1.h -- SHA-1 Hash -2016-05-20 : Igor Pavlov : Public domain */ - -#ifndef __7Z_SHA1_H -#define __7Z_SHA1_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define SHA1_NUM_BLOCK_WORDS 16 -#define SHA1_NUM_DIGEST_WORDS 5 - -#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4) -#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4) - -typedef struct -{ - UInt32 state[SHA1_NUM_DIGEST_WORDS]; - UInt64 count; - UInt32 buffer[SHA1_NUM_BLOCK_WORDS]; -} CSha1; - -void Sha1_Init(CSha1 *p); - -void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest); -void Sha1_Update(CSha1 *p, const Byte *data, size_t size); -void Sha1_Final(CSha1 *p, Byte *digest); - -void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */); - -void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size); -void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size); -void Sha1_32_Final(CSha1 *p, UInt32 *digest); - -EXTERN_C_END - -#endif +/* Sha1.h -- SHA-1 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SHA1_H +#define ZIP7_INC_SHA1_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA1_NUM_BLOCK_WORDS 16 +#define SHA1_NUM_DIGEST_WORDS 5 + +#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4) +#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4) + + + + +typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks); + +/* + if (the system supports different SHA1 code implementations) + { + (CSha1::func_UpdateBlocks) will be used + (CSha1::func_UpdateBlocks) can be set by + Sha1_Init() - to default (fastest) + Sha1_SetFunction() - to any algo + } + else + { + (CSha1::func_UpdateBlocks) is ignored. + } +*/ + +typedef struct +{ + union + { + struct + { + SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[4]; + void *_pad_align_ptr[2]; + } v; + UInt32 state[SHA1_NUM_DIGEST_WORDS]; + UInt32 _pad_3[3]; + Byte buffer[SHA1_BLOCK_SIZE]; +} CSha1; + + +#define SHA1_ALGO_DEFAULT 0 +#define SHA1_ALGO_SW 1 +#define SHA1_ALGO_HW 2 + +/* +Sha1_SetFunction() +return: + 0 - (algo) value is not supported, and func_UpdateBlocks was not changed + 1 - func_UpdateBlocks was set according (algo) value. +*/ + +BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo); + +void Sha1_InitState(CSha1 *p); +void Sha1_Init(CSha1 *p); +void Sha1_Update(CSha1 *p, const Byte *data, size_t size); +void Sha1_Final(CSha1 *p, Byte *digest); + +void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size); +void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest); + +// void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks); + +/* +call Sha1Prepare() once at program start. +It prepares all supported implementations, and detects the fastest implementation. +*/ + +void Sha1Prepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Sha1Opt.c p7zip-rar-16.02+really25.00+ds/C/Sha1Opt.c --- p7zip-rar-16.02/C/Sha1Opt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha1Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -0,0 +1,424 @@ +/* Sha1Opt.c -- SHA-1 optimized code for SHA-1 hardware instructions +: Igor Pavlov : Public domain */ + +#include "Precomp.h" +#include "Compiler.h" +#include "CpuArch.h" + +// #define Z7_USE_HW_SHA_STUB // for debug +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check + #define USE_HW_SHA + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) + #define USE_HW_SHA + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA__) || !defined(__SSSE3__) + #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) + #endif + #endif + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1900) + #define USE_HW_SHA + #else + #define Z7_USE_HW_SHA_STUB + #endif + #endif +// #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif + +#ifdef USE_HW_SHA + +// #pragma message("Sha1 HW") + + + + +// sse/sse2/ssse3: +#include +// sha*: +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__SHA__) + #include + #endif +#else + +#endif + +/* +SHA1 uses: +SSE2: + _mm_loadu_si128 + _mm_storeu_si128 + _mm_set_epi32 + _mm_add_epi32 + _mm_shuffle_epi32 / pshufd + _mm_xor_si128 + _mm_cvtsi128_si32 + _mm_cvtsi32_si128 +SSSE3: + _mm_shuffle_epi8 / pshufb + +SHA: + _mm_sha1* +*/ + +#define XOR_SI128(dest, src) dest = _mm_xor_si128(dest, src); +#define SHUFFLE_EPI8(dest, mask) dest = _mm_shuffle_epi8(dest, mask); +#define SHUFFLE_EPI32(dest, mask) dest = _mm_shuffle_epi32(dest, mask); +#ifdef __clang__ +#define SHA1_RNDS4_RET_TYPE_CAST (__m128i) +#else +#define SHA1_RNDS4_RET_TYPE_CAST +#endif +#define SHA1_RND4(abcd, e0, f) abcd = SHA1_RNDS4_RET_TYPE_CAST _mm_sha1rnds4_epu32(abcd, e0, f); +#define SHA1_NEXTE(e, m) e = _mm_sha1nexte_epu32(e, m); +#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); +#define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src); +#define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src); + +#define LOAD_SHUFFLE(m, k) \ + m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \ + SHUFFLE_EPI8(m, mask) \ + +#define NNN(m0, m1, m2, m3) + +#define SM1(m0, m1, m2, m3) \ + SHA1_MSG1(m0, m1) \ + +#define SM2(m0, m1, m2, m3) \ + XOR_SI128(m3, m1) \ + SHA1_MSG2(m3, m2) \ + +#define SM3(m0, m1, m2, m3) \ + XOR_SI128(m3, m1) \ + SM1(m0, m1, m2, m3) \ + SHA1_MSG2(m3, m2) \ + +#define R4(k, m0, m1, m2, m3, e0, e1, OP) \ + e1 = abcd; \ + SHA1_RND4(abcd, e0, (k) / 5) \ + SHA1_NEXTE(e1, m1) \ + OP(m0, m1, m2, m3) \ + + + +#define R16(k, mx, OP0, OP1, OP2, OP3) \ + R4 ( (k)*4+0, m0,m1,m2,m3, e0,e1, OP0 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, e1,e0, OP1 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, e0,e1, OP2 ) \ + R4 ( (k)*4+3, m3,mx,m1,m2, e1,e0, OP3 ) \ + +#define PREPARE_STATE \ + SHUFFLE_EPI32 (abcd, 0x1B) \ + SHUFFLE_EPI32 (e0, 0x1B) \ + + + + + +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) +{ + const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f); + + + __m128i abcd, e0; + + if (numBlocks == 0) + return; + + abcd = _mm_loadu_si128((const __m128i *) (const void *) &state[0]); // dbca + e0 = _mm_cvtsi32_si128((int)state[4]); // 000e + + PREPARE_STATE + + do + { + __m128i abcd_save, e2; + __m128i m0, m1, m2, m3; + __m128i e1; + + + abcd_save = abcd; + e2 = e0; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + ADD_EPI32(e0, m0) + + R16 ( 0, m0, SM1, SM3, SM3, SM3 ) + R16 ( 1, m0, SM3, SM3, SM3, SM3 ) + R16 ( 2, m0, SM3, SM3, SM3, SM3 ) + R16 ( 3, m0, SM3, SM3, SM3, SM3 ) + R16 ( 4, e2, SM2, NNN, NNN, NNN ) + + ADD_EPI32(abcd, abcd_save) + + data += 64; + } + while (--numBlocks); + + PREPARE_STATE + + _mm_storeu_si128((__m128i *) (void *) state, abcd); + *(state + 4) = (UInt32)_mm_cvtsi128_si32(e0); +} + +#endif // USE_HW_SHA + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \ + && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037)) + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_SHA + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_SHA + #endif + #endif + #endif + #endif + +#ifdef USE_HW_SHA + +// #pragma message("=== Sha1 HW === ") +// __ARM_FEATURE_CRYPTO macro is deprecated in favor of the finer grained feature macro __ARM_FEATURE_SHA2 + +#if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) + #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_SHA __attribute__((__target__("crypto"))) +#else + #define ATTRIB_SHA __attribute__((__target__("+crypto"))) +#endif + #else +#if defined(__clang__) && (__clang_major__ >= 1) + #define ATTRIB_SHA __attribute__((__target__("armv8-a,sha2"))) +#else + #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif + #endif +#endif +#else + // _MSC_VER + // for arm32 + #define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) +#include +#else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_SHA2 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + +#include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_SHA2) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_SHA2 + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") +#endif + +#endif // Z7_MSC_VER_ORIGINAL + +typedef uint32x4_t v128; +// typedef __n128 v128; // MSVC +// the bug in clang 3.8.1: +// __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); +#if defined(__clang__) && (__clang_major__ <= 9) +#pragma GCC diagnostic ignored "-Wvector-conversion" +#endif + +#ifdef MY_CPU_BE + #define MY_rev32_for_LE(x) x +#else + #define MY_rev32_for_LE(x) vrev32q_u8(x) +#endif + +#define LOAD_128_32(_p) vld1q_u32(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_32(_p, _v) vst1q_u32(_p, _v) + +#define LOAD_SHUFFLE(m, k) \ + m = vreinterpretq_u32_u8( \ + MY_rev32_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ + +#define N0(dest, src2, src3) +#define N1(dest, src) +#define U0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3); +#define U1(dest, src) dest = vsha1su1q_u32(dest, src); +#define C(e) abcd = vsha1cq_u32(abcd, e, t) +#define P(e) abcd = vsha1pq_u32(abcd, e, t) +#define M(e) abcd = vsha1mq_u32(abcd, e, t) +#define H(e) e = vsha1h_u32(vgetq_lane_u32(abcd, 0)) +#define T(m, c) t = vaddq_u32(m, c) + +#define R16(d0,d1,d2,d3, f0,z0, f1,z1, f2,z2, f3,z3, w0,w1,w2,w3) \ + T(m0, d0); f0(m3, m0, m1) z0(m2, m1) H(e1); w0(e0); \ + T(m1, d1); f1(m0, m1, m2) z1(m3, m2) H(e0); w1(e1); \ + T(m2, d2); f2(m1, m2, m3) z2(m0, m3) H(e1); w2(e0); \ + T(m3, d3); f3(m2, m3, m0) z3(m1, m0) H(e0); w3(e1); \ + + +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + v128 abcd; + v128 c0, c1, c2, c3; + uint32_t e0; + + if (numBlocks == 0) + return; + + c0 = vdupq_n_u32(0x5a827999); + c1 = vdupq_n_u32(0x6ed9eba1); + c2 = vdupq_n_u32(0x8f1bbcdc); + c3 = vdupq_n_u32(0xca62c1d6); + + abcd = LOAD_128_32(&state[0]); + e0 = state[4]; + + do + { + v128 abcd_save; + v128 m0, m1, m2, m3; + v128 t; + uint32_t e0_save, e1; + + abcd_save = abcd; + e0_save = e0; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + R16 ( c0,c0,c0,c0, N0,N1, U0,N1, U0,U1, U0,U1, C,C,C,C ) + R16 ( c0,c1,c1,c1, U0,U1, U0,U1, U0,U1, U0,U1, C,P,P,P ) + R16 ( c1,c1,c2,c2, U0,U1, U0,U1, U0,U1, U0,U1, P,P,M,M ) + R16 ( c2,c2,c2,c3, U0,U1, U0,U1, U0,U1, U0,U1, M,M,M,P ) + R16 ( c3,c3,c3,c3, U0,U1, N0,U1, N0,N1, N0,N1, P,P,P,P ) + + abcd = vaddq_u32(abcd, abcd_save); + e0 += e0_save; + + data += 64; + } + while (--numBlocks); + + STORE_128_32(&state[0], abcd); + state[4] = e0; +} + +#endif // USE_HW_SHA + +#endif // MY_CPU_ARM_OR_ARM64 + +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) +// #error Stop_Compiling_UNSUPPORTED_SHA +// #include +// #include "Sha1.h" +// #if defined(_MSC_VER) +#pragma message("Sha1 HW-SW stub was used") +// #endif +void Z7_FASTCALL Sha1_UpdateBlocks (UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks) +{ + Sha1_UpdateBlocks(state, data, numBlocks); + /* + UNUSED_VAR(state); + UNUSED_VAR(data); + UNUSED_VAR(numBlocks); + exit(1); + return; + */ +} +#endif + +#undef U0 +#undef U1 +#undef N0 +#undef N1 +#undef C +#undef P +#undef M +#undef H +#undef T +#undef MY_rev32_for_LE +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 +#undef SM3 +#undef NNN +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru p7zip-rar-16.02/C/Sha256.c p7zip-rar-16.02+really25.00+ds/C/Sha256.c --- p7zip-rar-16.02/C/Sha256.c 2015-11-20 20:40:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha256.c 2024-10-29 11:00:00.000000000 +0000 @@ -1,248 +1,492 @@ -/* Crypto/Sha256.c -- SHA-256 Hash -2015-11-14 : Igor Pavlov : Public domain -This code is based on public domain code from Wei Dai's Crypto++ library. */ - -#include "Precomp.h" - -#include - -#include "CpuArch.h" -#include "RotateDefs.h" -#include "Sha256.h" - -/* define it for speed optimization */ -#ifndef _SFX -#define _SHA256_UNROLL -#define _SHA256_UNROLL2 -#endif - -/* #define _SHA256_UNROLL2 */ - -void Sha256_Init(CSha256 *p) -{ - p->state[0] = 0x6a09e667; - p->state[1] = 0xbb67ae85; - p->state[2] = 0x3c6ef372; - p->state[3] = 0xa54ff53a; - p->state[4] = 0x510e527f; - p->state[5] = 0x9b05688c; - p->state[6] = 0x1f83d9ab; - p->state[7] = 0x5be0cd19; - p->count = 0; -} - -#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) -#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) -#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) -#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) - -#define blk0(i) (W[i]) -#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15])) - -#define Ch(x,y,z) (z^(x&(y^z))) -#define Maj(x,y,z) ((x&y)|(z&(x|y))) - -#ifdef _SHA256_UNROLL2 - -#define R(a,b,c,d,e,f,g,h, i) \ - h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \ - d += h; \ - h += S0(a) + Maj(a, b, c) - -#define RX_8(i) \ - R(a,b,c,d,e,f,g,h, i); \ - R(h,a,b,c,d,e,f,g, i+1); \ - R(g,h,a,b,c,d,e,f, i+2); \ - R(f,g,h,a,b,c,d,e, i+3); \ - R(e,f,g,h,a,b,c,d, i+4); \ - R(d,e,f,g,h,a,b,c, i+5); \ - R(c,d,e,f,g,h,a,b, i+6); \ - R(b,c,d,e,f,g,h,a, i+7) - -#define RX_16 RX_8(0); RX_8(8); - -#else - -#define a(i) T[(0-(i))&7] -#define b(i) T[(1-(i))&7] -#define c(i) T[(2-(i))&7] -#define d(i) T[(3-(i))&7] -#define e(i) T[(4-(i))&7] -#define f(i) T[(5-(i))&7] -#define g(i) T[(6-(i))&7] -#define h(i) T[(7-(i))&7] - -#define R(i) \ - h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \ - d(i) += h(i); \ - h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \ - -#ifdef _SHA256_UNROLL - -#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); -#define RX_16 RX_8(0); RX_8(8); - -#else - -#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); } - -#endif - -#endif - -static const UInt32 K[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -static void Sha256_WriteByteBlock(CSha256 *p) -{ - UInt32 W[16]; - unsigned j; - UInt32 *state; - - #ifdef _SHA256_UNROLL2 - UInt32 a,b,c,d,e,f,g,h; - #else - UInt32 T[8]; - #endif - - for (j = 0; j < 16; j += 4) - { - const Byte *ccc = p->buffer + j * 4; - W[j ] = GetBe32(ccc); - W[j + 1] = GetBe32(ccc + 4); - W[j + 2] = GetBe32(ccc + 8); - W[j + 3] = GetBe32(ccc + 12); - } - - state = p->state; - - #ifdef _SHA256_UNROLL2 - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - f = state[5]; - g = state[6]; - h = state[7]; - #else - for (j = 0; j < 8; j++) - T[j] = state[j]; - #endif - - for (j = 0; j < 64; j += 16) - { - RX_16 - } - - #ifdef _SHA256_UNROLL2 - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - state[5] += f; - state[6] += g; - state[7] += h; - #else - for (j = 0; j < 8; j++) - state[j] += T[j]; - #endif - - /* Wipe variables */ - /* memset(W, 0, sizeof(W)); */ - /* memset(T, 0, sizeof(T)); */ -} - -#undef S0 -#undef S1 -#undef s0 -#undef s1 - -void Sha256_Update(CSha256 *p, const Byte *data, size_t size) -{ - if (size == 0) - return; - - { - unsigned pos = (unsigned)p->count & 0x3F; - unsigned num; - - p->count += size; - - num = 64 - pos; - if (num > size) - { - memcpy(p->buffer + pos, data, size); - return; - } - - size -= num; - memcpy(p->buffer + pos, data, num); - data += num; - } - - for (;;) - { - Sha256_WriteByteBlock(p); - if (size < 64) - break; - size -= 64; - memcpy(p->buffer, data, 64); - data += 64; - } - - if (size != 0) - memcpy(p->buffer, data, size); -} - -void Sha256_Final(CSha256 *p, Byte *digest) -{ - unsigned pos = (unsigned)p->count & 0x3F; - unsigned i; - - p->buffer[pos++] = 0x80; - - while (pos != (64 - 8)) - { - pos &= 0x3F; - if (pos == 0) - Sha256_WriteByteBlock(p); - p->buffer[pos++] = 0; - } - - { - UInt64 numBits = (p->count << 3); - SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); - SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); - } - - Sha256_WriteByteBlock(p); - - for (i = 0; i < 8; i += 2) - { - UInt32 v0 = p->state[i]; - UInt32 v1 = p->state[i + 1]; - SetBe32(digest , v0); - SetBe32(digest + 4, v1); - digest += 8; - } - - Sha256_Init(p); -} +/* Sha256.c -- SHA-256 Hash +: Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha256.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) \ + || defined(_MSC_VER) && (_MSC_VER >= 1200) + #define Z7_COMPILER_SHA256_SUPPORTED + #endif +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define Z7_COMPILER_SHA256_SUPPORTED + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #endif + #endif + #endif +#endif + +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); + +#ifdef Z7_COMPILER_SHA256_SUPPORTED + void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); + + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW; + + #define SHA256_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks +#else + #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks +#endif + + +BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo) +{ + SHA256_FUNC_UPDATE_BLOCKS func = Sha256_UpdateBlocks; + + #ifdef Z7_COMPILER_SHA256_SUPPORTED + if (algo != SHA256_ALGO_SW) + { + if (algo == SHA256_ALGO_DEFAULT) + func = g_SHA256_FUNC_UPDATE_BLOCKS; + else + { + if (algo != SHA256_ALGO_HW) + return False; + func = g_SHA256_FUNC_UPDATE_BLOCKS_HW; + if (!func) + return False; + } + } + #else + if (algo > 1) + return False; + #endif + + p->v.vars.func_UpdateBlocks = func; + return True; +} + + +/* define it for speed optimization */ + +#ifdef Z7_SFX + #define STEP_PRE 1 + #define STEP_MAIN 1 +#else + #define STEP_PRE 2 + #define STEP_MAIN 4 + // #define Z7_SHA256_UNROLL +#endif + +#undef Z7_SHA256_BIG_W +#if STEP_MAIN != 16 + #define Z7_SHA256_BIG_W +#endif + + + + +void Sha256_InitState(CSha256 *p) +{ + p->v.vars.count = 0; + p->state[0] = 0x6a09e667; + p->state[1] = 0xbb67ae85; + p->state[2] = 0x3c6ef372; + p->state[3] = 0xa54ff53a; + p->state[4] = 0x510e527f; + p->state[5] = 0x9b05688c; + p->state[6] = 0x1f83d9ab; + p->state[7] = 0x5be0cd19; +} + + + + + + + + +void Sha256_Init(CSha256 *p) +{ + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA256_SUPPORTED + g_SHA256_FUNC_UPDATE_BLOCKS; + #else + NULL; + #endif + Sha256_InitState(p); +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x,22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x,25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >>10)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + + +#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe32(data + ((size_t)(j) + i) * 4)) + +#define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15)) + +#ifdef Z7_SHA256_BIG_W + // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned. + #define w(j, i) W[(size_t)(j) + i] + #define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i)) +#else + #if STEP_MAIN == 16 + #define w(j, i) W[(i) & 15] + #else + #define w(j, i) W[((size_t)(j) + (i)) & 15] + #endif + #define blk2(j, i) (w(j, i) += blk2_main(j, i)) +#endif + +#define W_MAIN(i) blk2(j, i) + + +#define T1(wx, i) \ + tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + h = g; \ + g = f; \ + f = e; \ + e = d + tmp; \ + tmp += S0(a) + Maj(a, b, c); \ + d = c; \ + c = b; \ + b = a; \ + a = tmp; \ + +#define R1_PRE(i) T1( W_PRE, i) +#define R1_MAIN(i) T1( W_MAIN, i) + +#if (!defined(Z7_SHA256_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) +#define R2_MAIN(i) \ + R1_MAIN(i) \ + R1_MAIN(i + 1) \ + +#endif + + + +#if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 + +#define T4( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + tmp = h; \ + h += d; \ + d = tmp + S0(a) + Maj(a, b, c); \ + +#define R4( wx, i) \ + T4 ( a,b,c,d,e,f,g,h, wx, (i )); \ + T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \ + T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \ + T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \ + +#define R4_PRE(i) R4( W_PRE, i) +#define R4_MAIN(i) R4( W_MAIN, i) + + +#define T8( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + d += h; \ + h += S0(a) + Maj(a, b, c); \ + +#define R8( wx, i) \ + T8 ( a,b,c,d,e,f,g,h, wx, i ); \ + T8 ( h,a,b,c,d,e,f,g, wx, i+1); \ + T8 ( g,h,a,b,c,d,e,f, wx, i+2); \ + T8 ( f,g,h,a,b,c,d,e, wx, i+3); \ + T8 ( e,f,g,h,a,b,c,d, wx, i+4); \ + T8 ( d,e,f,g,h,a,b,c, wx, i+5); \ + T8 ( c,d,e,f,g,h,a,b, wx, i+6); \ + T8 ( b,c,d,e,f,g,h,a, wx, i+7); \ + +#define R8_PRE(i) R8( W_PRE, i) +#define R8_MAIN(i) R8( W_MAIN, i) + +#endif + + +extern +MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64]; +MY_ALIGN(64) const UInt32 SHA256_K_ARRAY[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + + + + + +#define K SHA256_K_ARRAY + +Z7_NO_INLINE +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + UInt32 W +#ifdef Z7_SHA256_BIG_W + [64]; +#else + [16]; +#endif + unsigned j; + UInt32 a,b,c,d,e,f,g,h; +#if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) + UInt32 tmp; +#endif + + if (numBlocks == 0) return; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + do + { + + for (j = 0; j < 16; j += STEP_PRE) + { + #if STEP_PRE > 4 + + #if STEP_PRE < 8 + R4_PRE(0); + #else + R8_PRE(0); + #if STEP_PRE == 16 + R8_PRE(8); + #endif + #endif + + #else + + R1_PRE(0) + #if STEP_PRE >= 2 + R1_PRE(1) + #if STEP_PRE >= 4 + R1_PRE(2) + R1_PRE(3) + #endif + #endif + + #endif + } + + for (j = 16; j < 64; j += STEP_MAIN) + { + #if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 + + #if STEP_MAIN < 8 + R4_MAIN(0) + #else + R8_MAIN(0) + #if STEP_MAIN == 16 + R8_MAIN(8) + #endif + #endif + + #else + + R1_MAIN(0) + #if STEP_MAIN >= 2 + R1_MAIN(1) + #if STEP_MAIN >= 4 + R2_MAIN(2) + #if STEP_MAIN >= 8 + R2_MAIN(4) + R2_MAIN(6) + #if STEP_MAIN >= 16 + R2_MAIN(8) + R2_MAIN(10) + R2_MAIN(12) + R2_MAIN(14) + #endif + #endif + #endif + #endif + #endif + } + + a += state[0]; state[0] = a; + b += state[1]; state[1] = b; + c += state[2]; state[2] = c; + d += state[3]; state[3] = d; + e += state[4]; state[4] = e; + f += state[5]; state[5] = f; + g += state[6]; state[6] = g; + h += state[7]; state[7] = h; + + data += SHA256_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); + const unsigned num = SHA256_BLOCK_SIZE - pos; + p->v.vars.count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha256_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 6; + // if (numBlocks) + SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA256_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 6); + memcpy(p->buffer, data, size); + } +} + + +void Sha256_Final(CSha256 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->v.vars.count & (SHA256_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (SHA256_BLOCK_SIZE - 4 * 2)) + { + while (pos != SHA256_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA256_BLOCK_SIZE - pos); + Sha256_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (SHA256_BLOCK_SIZE - 4 * 2) - pos); + { + const UInt64 numBits = p->v.vars.count << 3; + SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 2, (UInt32)(numBits >> 32)) + SetBe32(p->buffer + SHA256_BLOCK_SIZE - 4 * 1, (UInt32)(numBits)) + } + Sha256_UpdateBlock(p); +#if 1 && defined(MY_CPU_BE) + memcpy(digest, p->state, SHA256_DIGEST_SIZE); +#else + { + unsigned i; + for (i = 0; i < 8; i += 2) + { + const UInt32 v0 = p->state[i]; + const UInt32 v1 = p->state[(size_t)i + 1]; + SetBe32(digest , v0) + SetBe32(digest + 4, v1) + digest += 4 * 2; + } + } + + + + +#endif + Sha256_InitState(p); +} + + +void Sha256Prepare(void) +{ +#ifdef Z7_COMPILER_SHA256_SUPPORTED + SHA256_FUNC_UPDATE_BLOCKS f, f_hw; + f = Sha256_UpdateBlocks; + f_hw = NULL; +#ifdef MY_CPU_X86_OR_AMD64 + if (CPU_IsSupported_SHA() + && CPU_IsSupported_SSSE3() + ) +#else + if (CPU_IsSupported_SHA2()) +#endif + { + // printf("\n========== HW SHA256 ======== \n"); + f = f_hw = Sha256_UpdateBlocks_HW; + } + g_SHA256_FUNC_UPDATE_BLOCKS = f; + g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw; +#endif +} + +#undef U64C +#undef K +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef Ch +#undef Maj +#undef W_MAIN +#undef W_PRE +#undef w +#undef blk2_main +#undef blk2 +#undef T1 +#undef T4 +#undef T8 +#undef R1_PRE +#undef R1_MAIN +#undef R2_MAIN +#undef R4 +#undef R4_PRE +#undef R4_MAIN +#undef R8 +#undef R8_PRE +#undef R8_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA256_BIG_W +#undef Z7_SHA256_UNROLL +#undef Z7_COMPILER_SHA256_SUPPORTED diff -Nru p7zip-rar-16.02/C/Sha256.h p7zip-rar-16.02+really25.00+ds/C/Sha256.h --- p7zip-rar-16.02/C/Sha256.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha256.h 2024-10-29 18:00:00.000000000 +0000 @@ -1,26 +1,86 @@ -/* Sha256.h -- SHA-256 Hash -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __CRYPTO_SHA256_H -#define __CRYPTO_SHA256_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define SHA256_DIGEST_SIZE 32 - -typedef struct -{ - UInt32 state[8]; - UInt64 count; - Byte buffer[64]; -} CSha256; - -void Sha256_Init(CSha256 *p); -void Sha256_Update(CSha256 *p, const Byte *data, size_t size); -void Sha256_Final(CSha256 *p, Byte *digest); - -EXTERN_C_END - -#endif +/* Sha256.h -- SHA-256 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SHA256_H +#define ZIP7_INC_SHA256_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA256_NUM_BLOCK_WORDS 16 +#define SHA256_NUM_DIGEST_WORDS 8 + +#define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4) +#define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4) + + + + +typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks); + +/* + if (the system supports different SHA256 code implementations) + { + (CSha256::func_UpdateBlocks) will be used + (CSha256::func_UpdateBlocks) can be set by + Sha256_Init() - to default (fastest) + Sha256_SetFunction() - to any algo + } + else + { + (CSha256::func_UpdateBlocks) is ignored. + } +*/ + +typedef struct +{ + union + { + struct + { + SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[4]; + void *_pad_align_ptr[2]; + } v; + UInt32 state[SHA256_NUM_DIGEST_WORDS]; + + Byte buffer[SHA256_BLOCK_SIZE]; +} CSha256; + + +#define SHA256_ALGO_DEFAULT 0 +#define SHA256_ALGO_SW 1 +#define SHA256_ALGO_HW 2 + +/* +Sha256_SetFunction() +return: + 0 - (algo) value is not supported, and func_UpdateBlocks was not changed + 1 - func_UpdateBlocks was set according (algo) value. +*/ + +BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo); + +void Sha256_InitState(CSha256 *p); +void Sha256_Init(CSha256 *p); +void Sha256_Update(CSha256 *p, const Byte *data, size_t size); +void Sha256_Final(CSha256 *p, Byte *digest); + + + + +// void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); + +/* +call Sha256Prepare() once at program start. +It prepares all supported implementations, and detects the fastest implementation. +*/ + +void Sha256Prepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Sha256Opt.c p7zip-rar-16.02+really25.00+ds/C/Sha256Opt.c --- p7zip-rar-16.02/C/Sha256Opt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha256Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -0,0 +1,451 @@ +/* Sha256Opt.c -- SHA-256 optimized code for SHA-256 hardware instructions +: Igor Pavlov : Public domain */ + +#include "Precomp.h" +#include "Compiler.h" +#include "CpuArch.h" + +// #define Z7_USE_HW_SHA_STUB // for debug +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check + #define USE_HW_SHA + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) + #define USE_HW_SHA + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA__) || !defined(__SSSE3__) + #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) + #endif + #endif + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1900) + #define USE_HW_SHA + #else + #define Z7_USE_HW_SHA_STUB + #endif + #endif +// #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif + +#ifdef USE_HW_SHA + +// #pragma message("Sha256 HW") + + + + +// sse/sse2/ssse3: +#include +// sha*: +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__SHA__) + #include + #endif +#else + +#endif + +/* +SHA256 uses: +SSE2: + _mm_loadu_si128 + _mm_storeu_si128 + _mm_set_epi32 + _mm_add_epi32 + _mm_shuffle_epi32 / pshufd + + + +SSSE3: + _mm_shuffle_epi8 / pshufb + _mm_alignr_epi8 +SHA: + _mm_sha256* +*/ + +// K array must be aligned for 16-bytes at least. +// The compiler can look align attribute and selects +// movdqu - for code without align attribute +// movdqa - for code with align attribute +extern +MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64]; +#define K SHA256_K_ARRAY + + +#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); +#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src); +#define SHA256_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src); + +#define LOAD_SHUFFLE(m, k) \ + m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \ + m = _mm_shuffle_epi8(m, mask); \ + +#define NNN(m0, m1, m2, m3) + +#define SM1(m1, m2, m3, m0) \ + SHA256_MSG1(m0, m1); \ + +#define SM2(m2, m3, m0, m1) \ + ADD_EPI32(m0, _mm_alignr_epi8(m3, m2, 4)) \ + SHA256_MSG2(m0, m3); \ + +#define RND2(t0, t1) \ + t0 = _mm_sha256rnds2_epu32(t0, t1, msg); + + + +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = _mm_add_epi32(m0, *(const __m128i *) (const void *) &K[(k) * 4]); \ + RND2(state0, state1); \ + msg = _mm_shuffle_epi32(msg, 0x0E); \ + OP0(m0, m1, m2, m3) \ + RND2(state1, state0); \ + OP1(m0, m1, m2, m3) \ + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \ + +#define PREPARE_STATE \ + tmp = _mm_shuffle_epi32(state0, 0x1B); /* abcd */ \ + state0 = _mm_shuffle_epi32(state1, 0x1B); /* efgh */ \ + state1 = state0; \ + state0 = _mm_unpacklo_epi64(state0, tmp); /* cdgh */ \ + state1 = _mm_unpackhi_epi64(state1, tmp); /* abef */ \ + + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + const __m128i mask = _mm_set_epi32(0x0c0d0e0f, 0x08090a0b, 0x04050607, 0x00010203); + + + __m128i tmp, state0, state1; + + if (numBlocks == 0) + return; + + state0 = _mm_loadu_si128((const __m128i *) (const void *) &state[0]); + state1 = _mm_loadu_si128((const __m128i *) (const void *) &state[4]); + + PREPARE_STATE + + do + { + __m128i state0_save, state1_save; + __m128i m0, m1, m2, m3; + __m128i msg; + // #define msg tmp + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) + + ADD_EPI32(state0, state0_save) + ADD_EPI32(state1, state1_save) + + data += 64; + } + while (--numBlocks); + + PREPARE_STATE + + _mm_storeu_si128((__m128i *) (void *) &state[0], state0); + _mm_storeu_si128((__m128i *) (void *) &state[4], state1); +} + +#endif // USE_HW_SHA + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA2) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_SHA + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_SHA + #endif + #endif + #endif + #endif + +#ifdef USE_HW_SHA + +// #pragma message("=== Sha256 HW === ") + + +#if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) + #ifdef MY_CPU_ARM64 +#if defined(__clang__) + #define ATTRIB_SHA __attribute__((__target__("crypto"))) +#else + #define ATTRIB_SHA __attribute__((__target__("+crypto"))) +#endif + #else +#if defined(__clang__) && (__clang_major__ >= 1) + #define ATTRIB_SHA __attribute__((__target__("armv8-a,sha2"))) +#else + #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) +#endif + #endif +#endif +#else + // _MSC_VER + // for arm32 + #define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) +#include +#else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA2) && \ + !defined(__ARM_FEATURE_CRYPTO) +// #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1 +// #if defined(__clang__) && __clang_major__ < 13 + #define __ARM_FEATURE_CRYPTO 1 +// #else + #define __ARM_FEATURE_SHA2 1 +// #endif + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#if defined(__clang__) + +#if defined(__ARM_ARCH) && __ARM_ARCH < 8 + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #pragma message("#define __ARM_ARCH 8") + #undef __ARM_ARCH + #define __ARM_ARCH 8 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif + +#endif // clang + +#include + +#if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \ + defined(__ARM_FEATURE_CRYPTO) && \ + defined(__ARM_FEATURE_SHA2) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_CRYPTO + #undef __ARM_FEATURE_SHA2 + #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") +#endif + +#endif // Z7_MSC_VER_ORIGINAL + +typedef uint32x4_t v128; +// typedef __n128 v128; // MSVC + +#ifdef MY_CPU_BE + #define MY_rev32_for_LE(x) x +#else + #define MY_rev32_for_LE(x) vrev32q_u8(x) +#endif + +#if 1 // 0 for debug +// for arm32: it works slower by some reason than direct code +/* +for arm32 it generates: +MSVC-2022, GCC-9: + vld1.32 {d18,d19}, [r10] + vst1.32 {d4,d5}, [r3] + vld1.8 {d20-d21}, [r4] +there is no align hint (like [r10:128]). So instruction allows unaligned access +*/ +#define LOAD_128_32(_p) vld1q_u32(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_32(_p, _v) vst1q_u32(_p, _v) +#else +/* +for arm32: +MSVC-2022: + vldm r10,{d18,d19} + vstm r3,{d4,d5} + does it require strict alignment? +GCC-9: + vld1.64 {d30-d31}, [r0:64] + vldr d28, [r0, #16] + vldr d29, [r0, #24] + vst1.64 {d30-d31}, [r0:64] + vstr d28, [r0, #16] + vstr d29, [r0, #24] +there is hint [r0:64], so does it requires 64-bit alignment. +*/ +#define LOAD_128_32(_p) (*(const v128 *)(const void *)(_p)) +#define LOAD_128_8(_p) vreinterpretq_u8_u32(*(const v128 *)(const void *)(_p)) +#define STORE_128_32(_p, _v) *(v128 *)(void *)(_p) = (_v) +#endif + +#define LOAD_SHUFFLE(m, k) \ + m = vreinterpretq_u32_u8( \ + MY_rev32_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ + +// K array must be aligned for 16-bytes at least. +extern +MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64]; +#define K SHA256_K_ARRAY + +#define SHA256_SU0(dest, src) dest = vsha256su0q_u32(dest, src); +#define SHA256_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3); + +#define SM1(m0, m1, m2, m3) SHA256_SU0(m3, m0) +#define SM2(m0, m1, m2, m3) SHA256_SU1(m2, m0, m1) +#define NNN(m0, m1, m2, m3) + +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = vaddq_u32(m0, *(const v128 *) (const void *) &K[(k) * 4]); \ + tmp = state0; \ + state0 = vsha256hq_u32( state0, state1, msg ); \ + state1 = vsha256h2q_u32( state1, tmp, msg ); \ + OP0(m0, m1, m2, m3); \ + OP1(m0, m1, m2, m3); \ + + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0, m1, m2, m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1, m2, m3, m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2, m3, m0, m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3, m0, m1, m2, OP6, OP7 ) \ + + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + v128 state0, state1; + + if (numBlocks == 0) + return; + + state0 = LOAD_128_32(&state[0]); + state1 = LOAD_128_32(&state[4]); + + do + { + v128 state0_save, state1_save; + v128 m0, m1, m2, m3; + v128 msg, tmp; + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) + + state0 = vaddq_u32(state0, state0_save); + state1 = vaddq_u32(state1, state1_save); + + data += 64; + } + while (--numBlocks); + + STORE_128_32(&state[0], state0); + STORE_128_32(&state[4], state1); +} + +#endif // USE_HW_SHA + +#endif // MY_CPU_ARM_OR_ARM64 + + +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) +// #error Stop_Compiling_UNSUPPORTED_SHA +// #include +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. +// #include "Sha256.h" +// #if defined(_MSC_VER) +#pragma message("Sha256 HW-SW stub was used") +// #endif +void Z7_FASTCALL Sha256_UpdateBlocks (UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + Sha256_UpdateBlocks(state, data, numBlocks); + /* + UNUSED_VAR(state); + UNUSED_VAR(data); + UNUSED_VAR(numBlocks); + exit(1); + return; + */ +} +#endif + + +#undef K +#undef RND2 +#undef MY_rev32_for_LE + +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 + + +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru p7zip-rar-16.02/C/Sha3.c p7zip-rar-16.02+really25.00+ds/C/Sha3.c --- p7zip-rar-16.02/C/Sha3.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha3.c 2024-11-26 10:00:00.000000000 +0000 @@ -0,0 +1,359 @@ +/* Sha3.c -- SHA-3 Hash +: Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha3.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#define U64C(x) UINT64_CONST(x) + +static +MY_ALIGN(64) +const UInt64 SHA3_K_ARRAY[24] = +{ + U64C(0x0000000000000001), U64C(0x0000000000008082), + U64C(0x800000000000808a), U64C(0x8000000080008000), + U64C(0x000000000000808b), U64C(0x0000000080000001), + U64C(0x8000000080008081), U64C(0x8000000000008009), + U64C(0x000000000000008a), U64C(0x0000000000000088), + U64C(0x0000000080008009), U64C(0x000000008000000a), + U64C(0x000000008000808b), U64C(0x800000000000008b), + U64C(0x8000000000008089), U64C(0x8000000000008003), + U64C(0x8000000000008002), U64C(0x8000000000000080), + U64C(0x000000000000800a), U64C(0x800000008000000a), + U64C(0x8000000080008081), U64C(0x8000000000008080), + U64C(0x0000000080000001), U64C(0x8000000080008008) +}; + +void Sha3_Init(CSha3 *p) +{ + p->count = 0; + memset(p->state, 0, sizeof(p->state)); +} + +#define GET_state(i, a) UInt64 a = state[i]; +#define SET_state(i, a) state[i] = a; + +#define LS_5(M, i, a0,a1,a2,a3,a4) \ + M ((i) * 5 , a0) \ + M ((i) * 5 + 1, a1) \ + M ((i) * 5 + 2, a2) \ + M ((i) * 5 + 3, a3) \ + M ((i) * 5 + 4, a4) \ + +#define LS_25(M) \ + LS_5 (M, 0, a50, a51, a52, a53, a54) \ + LS_5 (M, 1, a60, a61, a62, a63, a64) \ + LS_5 (M, 2, a70, a71, a72, a73, a74) \ + LS_5 (M, 3, a80, a81, a82, a83, a84) \ + LS_5 (M, 4, a90, a91, a92, a93, a94) \ + + +#define XOR_1(i, a0) \ + a0 ^= GetUi64(data + (i) * 8); \ + +#define XOR_4(i, a0,a1,a2,a3) \ + XOR_1 ((i) , a0); \ + XOR_1 ((i) + 1, a1); \ + XOR_1 ((i) + 2, a2); \ + XOR_1 ((i) + 3, a3); \ + +#define D(d,b1,b2) \ + d = b1 ^ Z7_ROTL64(b2, 1); + +#define D5 \ + D (d0, c4, c1) \ + D (d1, c0, c2) \ + D (d2, c1, c3) \ + D (d3, c2, c4) \ + D (d4, c3, c0) \ + +#define C0(c,a,d) \ + c = a ^ d; \ + +#define C(c,a,d,k) \ + c = a ^ d; \ + c = Z7_ROTL64(c, k); \ + +#define E4(e1,e2,e3,e4) \ + e1 = c1 ^ (~c2 & c3); \ + e2 = c2 ^ (~c3 & c4); \ + e3 = c3 ^ (~c4 & c0); \ + e4 = c4 ^ (~c0 & c1); \ + +#define CK( v0,w0, \ + v1,w1,k1, \ + v2,w2,k2, \ + v3,w3,k3, \ + v4,w4,k4, e0,e1,e2,e3,e4, keccak_c) \ + C0(c0,v0,w0) \ + C (c1,v1,w1,k1) \ + C (c2,v2,w2,k2) \ + C (c3,v3,w3,k3) \ + C (c4,v4,w4,k4) \ + e0 = c0 ^ (~c1 & c2) ^ keccak_c; \ + E4(e1,e2,e3,e4) \ + +#define CE( v0,w0,k0, \ + v1,w1,k1, \ + v2,w2,k2, \ + v3,w3,k3, \ + v4,w4,k4, e0,e1,e2,e3,e4) \ + C (c0,v0,w0,k0) \ + C (c1,v1,w1,k1) \ + C (c2,v2,w2,k2) \ + C (c3,v3,w3,k3) \ + C (c4,v4,w4,k4) \ + e0 = c0 ^ (~c1 & c2); \ + E4(e1,e2,e3,e4) \ + +// numBlocks != 0 +static +Z7_NO_INLINE +void Z7_FASTCALL Sha3_UpdateBlocks(UInt64 state[SHA3_NUM_STATE_WORDS], + const Byte *data, size_t numBlocks, size_t blockSize) +{ + LS_25 (GET_state) + + do + { + unsigned round; + XOR_4 ( 0, a50, a51, a52, a53) + XOR_4 ( 4, a54, a60, a61, a62) + XOR_1 ( 8, a63) + if (blockSize > 8 * 9) { XOR_4 ( 9, a64, a70, a71, a72) // sha3-384 + if (blockSize > 8 * 13) { XOR_4 (13, a73, a74, a80, a81) // sha3-256 + if (blockSize > 8 * 17) { XOR_1 (17, a82) // sha3-224 + if (blockSize > 8 * 18) { XOR_1 (18, a83) // shake128 + XOR_1 (19, a84) + XOR_1 (20, a90) }}}} + data += blockSize; + + for (round = 0; round < 24; round += 2) + { + UInt64 c0, c1, c2, c3, c4; + UInt64 d0, d1, d2, d3, d4; + UInt64 e50, e51, e52, e53, e54; + UInt64 e60, e61, e62, e63, e64; + UInt64 e70, e71, e72, e73, e74; + UInt64 e80, e81, e82, e83, e84; + UInt64 e90, e91, e92, e93, e94; + + c0 = a50^a60^a70^a80^a90; + c1 = a51^a61^a71^a81^a91; + c2 = a52^a62^a72^a82^a92; + c3 = a53^a63^a73^a83^a93; + c4 = a54^a64^a74^a84^a94; + D5 + CK( a50, d0, + a61, d1, 44, + a72, d2, 43, + a83, d3, 21, + a94, d4, 14, e50, e51, e52, e53, e54, SHA3_K_ARRAY[round]) + CE( a53, d3, 28, + a64, d4, 20, + a70, d0, 3, + a81, d1, 45, + a92, d2, 61, e60, e61, e62, e63, e64) + CE( a51, d1, 1, + a62, d2, 6, + a73, d3, 25, + a84, d4, 8, + a90, d0, 18, e70, e71, e72, e73, e74) + CE( a54, d4, 27, + a60, d0, 36, + a71, d1, 10, + a82, d2, 15, + a93, d3, 56, e80, e81, e82, e83, e84) + CE( a52, d2, 62, + a63, d3, 55, + a74, d4, 39, + a80, d0, 41, + a91, d1, 2, e90, e91, e92, e93, e94) + + // ---------- ROUND + 1 ---------- + + c0 = e50^e60^e70^e80^e90; + c1 = e51^e61^e71^e81^e91; + c2 = e52^e62^e72^e82^e92; + c3 = e53^e63^e73^e83^e93; + c4 = e54^e64^e74^e84^e94; + D5 + CK( e50, d0, + e61, d1, 44, + e72, d2, 43, + e83, d3, 21, + e94, d4, 14, a50, a51, a52, a53, a54, SHA3_K_ARRAY[(size_t)round + 1]) + CE( e53, d3, 28, + e64, d4, 20, + e70, d0, 3, + e81, d1, 45, + e92, d2, 61, a60, a61, a62, a63, a64) + CE( e51, d1, 1, + e62, d2, 6, + e73, d3, 25, + e84, d4, 8, + e90, d0, 18, a70, a71, a72, a73, a74) + CE (e54, d4, 27, + e60, d0, 36, + e71, d1, 10, + e82, d2, 15, + e93, d3, 56, a80, a81, a82, a83, a84) + CE (e52, d2, 62, + e63, d3, 55, + e74, d4, 39, + e80, d0, 41, + e91, d1, 2, a90, a91, a92, a93, a94) + } + } + while (--numBlocks); + + LS_25 (SET_state) +} + + +#define Sha3_UpdateBlock(p) \ + Sha3_UpdateBlocks(p->state, p->buffer, 1, p->blockSize) + +void Sha3_Update(CSha3 *p, const Byte *data, size_t size) +{ +/* + for (;;) + { + if (size == 0) + return; + unsigned cur = p->blockSize - p->count; + if (cur > size) + cur = (unsigned)size; + size -= cur; + unsigned pos = p->count; + p->count = pos + cur; + while (pos & 7) + { + if (cur == 0) + return; + Byte *pb = &(((Byte *)p->state)[pos]); + *pb = (Byte)(*pb ^ *data++); + cur--; + pos++; + } + if (cur >= 8) + { + do + { + *(UInt64 *)(void *)&(((Byte *)p->state)[pos]) ^= GetUi64(data); + data += 8; + pos += 8; + cur -= 8; + } + while (cur >= 8); + } + if (pos != p->blockSize) + { + if (cur) + { + Byte *pb = &(((Byte *)p->state)[pos]); + do + { + *pb = (Byte)(*pb ^ *data++); + pb++; + } + while (--cur); + } + return; + } + Sha3_UpdateBlock(p->state); + p->count = 0; + } +*/ + if (size == 0) + return; + { + const unsigned pos = p->count; + const unsigned num = p->blockSize - pos; + if (num > size) + { + p->count = pos + (unsigned)size; + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha3_UpdateBlock(p); + } + } + if (size >= p->blockSize) + { + const size_t numBlocks = size / p->blockSize; + const Byte *dataOld = data; + data += numBlocks * p->blockSize; + size = (size_t)(dataOld + size - data); + Sha3_UpdateBlocks(p->state, dataOld, numBlocks, p->blockSize); + } + p->count = (unsigned)size; + if (size) + memcpy(p->buffer, data, size); +} + + +// we support only (digestSize % 4 == 0) cases +void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake) +{ + memset(p->buffer + p->count, 0, p->blockSize - p->count); + // we write bits markers from low to higher in current byte: + // - if sha-3 : 2 bits : 0,1 + // - if shake : 4 bits : 1111 + // then we write bit 1 to same byte. + // And we write bit 1 to highest bit of last byte of block. + p->buffer[p->count] = (Byte)(shake ? 0x1f : 0x06); + // we need xor operation (^= 0x80) here because we must write 0x80 bit + // to same byte as (0x1f : 0x06), if (p->count == p->blockSize - 1) !!! + p->buffer[p->blockSize - 1] ^= 0x80; +/* + ((Byte *)p->state)[p->count] ^= (Byte)(shake ? 0x1f : 0x06); + ((Byte *)p->state)[p->blockSize - 1] ^= 0x80; +*/ + Sha3_UpdateBlock(p); +#if 1 && defined(MY_CPU_LE) + memcpy(digest, p->state, digestSize); +#else + { + const unsigned numWords = digestSize >> 3; + unsigned i; + for (i = 0; i < numWords; i++) + { + const UInt64 v = p->state[i]; + SetUi64(digest, v) + digest += 8; + } + if (digestSize & 4) // for SHA3-224 + { + const UInt32 v = (UInt32)p->state[numWords]; + SetUi32(digest, v) + } + } +#endif + Sha3_Init(p); +} + +#undef GET_state +#undef SET_state +#undef LS_5 +#undef LS_25 +#undef XOR_1 +#undef XOR_4 +#undef D +#undef D5 +#undef C0 +#undef C +#undef E4 +#undef CK +#undef CE diff -Nru p7zip-rar-16.02/C/Sha3.h p7zip-rar-16.02+really25.00+ds/C/Sha3.h --- p7zip-rar-16.02/C/Sha3.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha3.h 2024-11-26 10:00:00.000000000 +0000 @@ -0,0 +1,36 @@ +/* Sha3.h -- SHA-3 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MD5_H +#define ZIP7_INC_MD5_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA3_NUM_STATE_WORDS 25 + +#define SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize) \ + (SHA3_NUM_STATE_WORDS * 8 - (digestSize) * 2) + +typedef struct +{ + UInt32 count; // < blockSize + UInt32 blockSize; // <= SHA3_NUM_STATE_WORDS * 8 + UInt64 _pad1[3]; + // we want 32-bytes alignment here + UInt64 state[SHA3_NUM_STATE_WORDS]; + UInt64 _pad2[3]; + // we want 64-bytes alignment here + Byte buffer[SHA3_NUM_STATE_WORDS * 8]; // last bytes will be unused with predefined blockSize values +} CSha3; + +#define Sha3_SET_blockSize(p, blockSize) { (p)->blockSize = (blockSize); } + +void Sha3_Init(CSha3 *p); +void Sha3_Update(CSha3 *p, const Byte *data, size_t size); +void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Sha512.c p7zip-rar-16.02+really25.00+ds/C/Sha512.c --- p7zip-rar-16.02/C/Sha512.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha512.c 2024-12-03 11:00:00.000000000 +0000 @@ -0,0 +1,711 @@ +/* Sha512.c -- SHA-512 Hash +: Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "Sha512.h" +#include "RotateDefs.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000) \ + || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) \ + || defined(_MSC_VER) && (_MSC_VER >= 1940) + #define Z7_COMPILER_SHA512_SUPPORTED + #endif +#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE) + #if defined(__ARM_FEATURE_SHA512) + #define Z7_COMPILER_SHA512_SUPPORTED + #else + #if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it + #define Z7_COMPILER_SHA512_SUPPORTED + #endif + #endif +#endif + + + + + + + + + + + + + + +void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks); + +#ifdef Z7_COMPILER_SHA512_SUPPORTED + void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); + + static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS = Sha512_UpdateBlocks; + static SHA512_FUNC_UPDATE_BLOCKS g_SHA512_FUNC_UPDATE_BLOCKS_HW; + + #define SHA512_UPDATE_BLOCKS(p) p->v.vars.func_UpdateBlocks +#else + #define SHA512_UPDATE_BLOCKS(p) Sha512_UpdateBlocks +#endif + + +BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo) +{ + SHA512_FUNC_UPDATE_BLOCKS func = Sha512_UpdateBlocks; + + #ifdef Z7_COMPILER_SHA512_SUPPORTED + if (algo != SHA512_ALGO_SW) + { + if (algo == SHA512_ALGO_DEFAULT) + func = g_SHA512_FUNC_UPDATE_BLOCKS; + else + { + if (algo != SHA512_ALGO_HW) + return False; + func = g_SHA512_FUNC_UPDATE_BLOCKS_HW; + if (!func) + return False; + } + } + #else + if (algo > 1) + return False; + #endif + + p->v.vars.func_UpdateBlocks = func; + return True; +} + + +/* define it for speed optimization */ + +#if 0 // 1 for size optimization + #define STEP_PRE 1 + #define STEP_MAIN 1 +#else + #define STEP_PRE 2 + #define STEP_MAIN 4 + // #define Z7_SHA512_UNROLL +#endif + +#undef Z7_SHA512_BIG_W +#if STEP_MAIN != 16 + #define Z7_SHA512_BIG_W +#endif + + +#define U64C(x) UINT64_CONST(x) + +static MY_ALIGN(64) const UInt64 SHA512_INIT_ARRAYS[4][8] = { +{ U64C(0x8c3d37c819544da2), U64C(0x73e1996689dcd4d6), U64C(0x1dfab7ae32ff9c82), U64C(0x679dd514582f9fcf), + U64C(0x0f6d2b697bd44da8), U64C(0x77e36f7304c48942), U64C(0x3f9d85a86a1d36c8), U64C(0x1112e6ad91d692a1) +}, +{ U64C(0x22312194fc2bf72c), U64C(0x9f555fa3c84c64c2), U64C(0x2393b86b6f53b151), U64C(0x963877195940eabd), + U64C(0x96283ee2a88effe3), U64C(0xbe5e1e2553863992), U64C(0x2b0199fc2c85b8aa), U64C(0x0eb72ddc81c52ca2) +}, +{ U64C(0xcbbb9d5dc1059ed8), U64C(0x629a292a367cd507), U64C(0x9159015a3070dd17), U64C(0x152fecd8f70e5939), + U64C(0x67332667ffc00b31), U64C(0x8eb44a8768581511), U64C(0xdb0c2e0d64f98fa7), U64C(0x47b5481dbefa4fa4) +}, +{ U64C(0x6a09e667f3bcc908), U64C(0xbb67ae8584caa73b), U64C(0x3c6ef372fe94f82b), U64C(0xa54ff53a5f1d36f1), + U64C(0x510e527fade682d1), U64C(0x9b05688c2b3e6c1f), U64C(0x1f83d9abfb41bd6b), U64C(0x5be0cd19137e2179) +}}; + +void Sha512_InitState(CSha512 *p, unsigned digestSize) +{ + p->v.vars.count = 0; + memcpy(p->state, SHA512_INIT_ARRAYS[(size_t)(digestSize >> 4) - 1], sizeof(p->state)); +} + +void Sha512_Init(CSha512 *p, unsigned digestSize) +{ + p->v.vars.func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA512_SUPPORTED + g_SHA512_FUNC_UPDATE_BLOCKS; + #else + NULL; + #endif + Sha512_InitState(p, digestSize); +} + +#define S0(x) (Z7_ROTR64(x,28) ^ Z7_ROTR64(x,34) ^ Z7_ROTR64(x,39)) +#define S1(x) (Z7_ROTR64(x,14) ^ Z7_ROTR64(x,18) ^ Z7_ROTR64(x,41)) +#define s0(x) (Z7_ROTR64(x, 1) ^ Z7_ROTR64(x, 8) ^ (x >> 7)) +#define s1(x) (Z7_ROTR64(x,19) ^ Z7_ROTR64(x,61) ^ (x >> 6)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + + +#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe64(data + ((size_t)(j) + i) * 8)) + +#define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15)) + +#ifdef Z7_SHA512_BIG_W + // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned. + #define w(j, i) W[(size_t)(j) + i] + #define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i)) +#else + #if STEP_MAIN == 16 + #define w(j, i) W[(i) & 15] + #else + #define w(j, i) W[((size_t)(j) + (i)) & 15] + #endif + #define blk2(j, i) (w(j, i) += blk2_main(j, i)) +#endif + +#define W_MAIN(i) blk2(j, i) + + +#define T1(wx, i) \ + tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + h = g; \ + g = f; \ + f = e; \ + e = d + tmp; \ + tmp += S0(a) + Maj(a, b, c); \ + d = c; \ + c = b; \ + b = a; \ + a = tmp; \ + +#define R1_PRE(i) T1( W_PRE, i) +#define R1_MAIN(i) T1( W_MAIN, i) + +#if (!defined(Z7_SHA512_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) +#define R2_MAIN(i) \ + R1_MAIN(i) \ + R1_MAIN(i + 1) \ + +#endif + + + +#if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8 + +#define T4( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + tmp = h; \ + h += d; \ + d = tmp + S0(a) + Maj(a, b, c); \ + +#define R4( wx, i) \ + T4 ( a,b,c,d,e,f,g,h, wx, (i )); \ + T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \ + T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \ + T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \ + +#define R4_PRE(i) R4( W_PRE, i) +#define R4_MAIN(i) R4( W_MAIN, i) + + +#define T8( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + d += h; \ + h += S0(a) + Maj(a, b, c); \ + +#define R8( wx, i) \ + T8 ( a,b,c,d,e,f,g,h, wx, i ); \ + T8 ( h,a,b,c,d,e,f,g, wx, i+1); \ + T8 ( g,h,a,b,c,d,e,f, wx, i+2); \ + T8 ( f,g,h,a,b,c,d,e, wx, i+3); \ + T8 ( e,f,g,h,a,b,c,d, wx, i+4); \ + T8 ( d,e,f,g,h,a,b,c, wx, i+5); \ + T8 ( c,d,e,f,g,h,a,b, wx, i+6); \ + T8 ( b,c,d,e,f,g,h,a, wx, i+7); \ + +#define R8_PRE(i) R8( W_PRE, i) +#define R8_MAIN(i) R8( W_MAIN, i) + +#endif + + +extern +MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80]; +MY_ALIGN(64) const UInt64 SHA512_K_ARRAY[80] = { + U64C(0x428a2f98d728ae22), U64C(0x7137449123ef65cd), U64C(0xb5c0fbcfec4d3b2f), U64C(0xe9b5dba58189dbbc), + U64C(0x3956c25bf348b538), U64C(0x59f111f1b605d019), U64C(0x923f82a4af194f9b), U64C(0xab1c5ed5da6d8118), + U64C(0xd807aa98a3030242), U64C(0x12835b0145706fbe), U64C(0x243185be4ee4b28c), U64C(0x550c7dc3d5ffb4e2), + U64C(0x72be5d74f27b896f), U64C(0x80deb1fe3b1696b1), U64C(0x9bdc06a725c71235), U64C(0xc19bf174cf692694), + U64C(0xe49b69c19ef14ad2), U64C(0xefbe4786384f25e3), U64C(0x0fc19dc68b8cd5b5), U64C(0x240ca1cc77ac9c65), + U64C(0x2de92c6f592b0275), U64C(0x4a7484aa6ea6e483), U64C(0x5cb0a9dcbd41fbd4), U64C(0x76f988da831153b5), + U64C(0x983e5152ee66dfab), U64C(0xa831c66d2db43210), U64C(0xb00327c898fb213f), U64C(0xbf597fc7beef0ee4), + U64C(0xc6e00bf33da88fc2), U64C(0xd5a79147930aa725), U64C(0x06ca6351e003826f), U64C(0x142929670a0e6e70), + U64C(0x27b70a8546d22ffc), U64C(0x2e1b21385c26c926), U64C(0x4d2c6dfc5ac42aed), U64C(0x53380d139d95b3df), + U64C(0x650a73548baf63de), U64C(0x766a0abb3c77b2a8), U64C(0x81c2c92e47edaee6), U64C(0x92722c851482353b), + U64C(0xa2bfe8a14cf10364), U64C(0xa81a664bbc423001), U64C(0xc24b8b70d0f89791), U64C(0xc76c51a30654be30), + U64C(0xd192e819d6ef5218), U64C(0xd69906245565a910), U64C(0xf40e35855771202a), U64C(0x106aa07032bbd1b8), + U64C(0x19a4c116b8d2d0c8), U64C(0x1e376c085141ab53), U64C(0x2748774cdf8eeb99), U64C(0x34b0bcb5e19b48a8), + U64C(0x391c0cb3c5c95a63), U64C(0x4ed8aa4ae3418acb), U64C(0x5b9cca4f7763e373), U64C(0x682e6ff3d6b2b8a3), + U64C(0x748f82ee5defb2fc), U64C(0x78a5636f43172f60), U64C(0x84c87814a1f0ab72), U64C(0x8cc702081a6439ec), + U64C(0x90befffa23631e28), U64C(0xa4506cebde82bde9), U64C(0xbef9a3f7b2c67915), U64C(0xc67178f2e372532b), + U64C(0xca273eceea26619c), U64C(0xd186b8c721c0c207), U64C(0xeada7dd6cde0eb1e), U64C(0xf57d4f7fee6ed178), + U64C(0x06f067aa72176fba), U64C(0x0a637dc5a2c898a6), U64C(0x113f9804bef90dae), U64C(0x1b710b35131c471b), + U64C(0x28db77f523047d84), U64C(0x32caab7b40c72493), U64C(0x3c9ebe0a15c9bebc), U64C(0x431d67c49c100d4c), + U64C(0x4cc5d4becb3e42b6), U64C(0x597f299cfc657e2a), U64C(0x5fcb6fab3ad6faec), U64C(0x6c44198c4a475817) +}; + +#define K SHA512_K_ARRAY + +Z7_NO_INLINE +void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + UInt64 W +#ifdef Z7_SHA512_BIG_W + [80]; +#else + [16]; +#endif + unsigned j; + UInt64 a,b,c,d,e,f,g,h; +#if !defined(Z7_SHA512_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) + UInt64 tmp; +#endif + + if (numBlocks == 0) return; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + do + { + + for (j = 0; j < 16; j += STEP_PRE) + { + #if STEP_PRE > 4 + + #if STEP_PRE < 8 + R4_PRE(0); + #else + R8_PRE(0); + #if STEP_PRE == 16 + R8_PRE(8); + #endif + #endif + + #else + + R1_PRE(0) + #if STEP_PRE >= 2 + R1_PRE(1) + #if STEP_PRE >= 4 + R1_PRE(2) + R1_PRE(3) + #endif + #endif + + #endif + } + + for (j = 16; j < 80; j += STEP_MAIN) + { + #if defined(Z7_SHA512_UNROLL) && STEP_MAIN >= 8 + + #if STEP_MAIN < 8 + R4_MAIN(0) + #else + R8_MAIN(0) + #if STEP_MAIN == 16 + R8_MAIN(8) + #endif + #endif + + #else + + R1_MAIN(0) + #if STEP_MAIN >= 2 + R1_MAIN(1) + #if STEP_MAIN >= 4 + R2_MAIN(2) + #if STEP_MAIN >= 8 + R2_MAIN(4) + R2_MAIN(6) + #if STEP_MAIN >= 16 + R2_MAIN(8) + R2_MAIN(10) + R2_MAIN(12) + R2_MAIN(14) + #endif + #endif + #endif + #endif + #endif + } + + a += state[0]; state[0] = a; + b += state[1]; state[1] = b; + c += state[2]; state[2] = c; + d += state[3]; state[3] = d; + e += state[4]; state[4] = e; + f += state[5]; state[5] = f; + g += state[6]; state[6] = g; + h += state[7]; state[7] = h; + + data += SHA512_BLOCK_SIZE; + } + while (--numBlocks); +} + + +#define Sha512_UpdateBlock(p) SHA512_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Sha512_Update(CSha512 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + { + const unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1); + const unsigned num = SHA512_BLOCK_SIZE - pos; + p->v.vars.count += size; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha512_UpdateBlock(p); + } + } + { + const size_t numBlocks = size >> 7; + // if (numBlocks) + SHA512_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= SHA512_BLOCK_SIZE - 1; + if (size == 0) + return; + data += (numBlocks << 7); + memcpy(p->buffer, data, size); + } +} + + +void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize) +{ + unsigned pos = (unsigned)p->v.vars.count & (SHA512_BLOCK_SIZE - 1); + p->buffer[pos++] = 0x80; + if (pos > (SHA512_BLOCK_SIZE - 8 * 2)) + { + while (pos != SHA512_BLOCK_SIZE) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, SHA512_BLOCK_SIZE - pos); + Sha512_UpdateBlock(p); + pos = 0; + } + memset(&p->buffer[pos], 0, (SHA512_BLOCK_SIZE - 8 * 2) - pos); + { + const UInt64 numBits = p->v.vars.count << 3; + SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 2, 0) // = (p->v.vars.count >> (64 - 3)); (high 64-bits) + SetBe64(p->buffer + SHA512_BLOCK_SIZE - 8 * 1, numBits) + } + Sha512_UpdateBlock(p); +#if 1 && defined(MY_CPU_BE) + memcpy(digest, p->state, digestSize); +#else + { + const unsigned numWords = digestSize >> 3; + unsigned i; + for (i = 0; i < numWords; i++) + { + const UInt64 v = p->state[i]; + SetBe64(digest, v) + digest += 8; + } + if (digestSize & 4) // digestSize == SHA512_224_DIGEST_SIZE + { + const UInt32 v = (UInt32)((p->state[numWords]) >> 32); + SetBe32(digest, v) + } + } +#endif + Sha512_InitState(p, digestSize); +} + + + +// #define Z7_SHA512_PROBE_DEBUG // for debug + +#if defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED) + +#if defined(Z7_SHA512_PROBE_DEBUG) \ + || defined(_WIN32) && defined(MY_CPU_ARM64) +#ifndef Z7_SHA512_USE_PROBE +#define Z7_SHA512_USE_PROBE +#endif +#endif + +#ifdef Z7_SHA512_USE_PROBE + +#ifdef Z7_SHA512_PROBE_DEBUG +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#if 0 || !defined(_MSC_VER) // 1 || : for debug LONGJMP mode +// MINGW doesn't support __try. So we use signal() / longjmp(). +// Note: signal() / longjmp() probably is not thread-safe. +// So we must call Sha512Prepare() from main thread at program start. +#ifndef Z7_SHA512_USE_LONGJMP +#define Z7_SHA512_USE_LONGJMP +#endif +#endif + +#ifdef Z7_SHA512_USE_LONGJMP +#include +#include +static jmp_buf g_Sha512_jmp_buf; +// static int g_Sha512_Unsupported; + +#if defined(__GNUC__) && (__GNUC__ >= 8) \ + || defined(__clang__) && (__clang_major__ >= 3) + __attribute__((noreturn)) +#endif +static void Z7_CDECL Sha512_signal_Handler(int v) +{ + PRF(printf("======== Sha512_signal_Handler = %x\n", (unsigned)v);) + // g_Sha512_Unsupported = 1; + longjmp(g_Sha512_jmp_buf, 1); +} +#endif // Z7_SHA512_USE_LONGJMP + + +#if defined(_WIN32) +#include "7zWindows.h" +#endif + +#if defined(MY_CPU_ARM64) +// #define Z7_SHA512_USE_SIMPLIFIED_PROBE // for debug +#endif + +#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE +#include +#if defined(__clang__) + __attribute__((__target__("sha3"))) +#elif !defined(_MSC_VER) + __attribute__((__target__("arch=armv8.2-a+sha3"))) +#endif +#endif +static BoolInt CPU_IsSupported_SHA512_Probe(void) +{ + PRF(printf("\n== CPU_IsSupported_SHA512_Probe\n");) +#if defined(_WIN32) && defined(MY_CPU_ARM64) + // we have no SHA512 flag for IsProcessorFeaturePresent() still. + if (!CPU_IsSupported_CRYPTO()) + return False; + PRF(printf("==== Registry check\n");) + { + // we can't read ID_AA64ISAR0_EL1 register from application. + // but ID_AA64ISAR0_EL1 register is mapped to "CP 4030" registry value. + HKEY key = NULL; + LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), + 0, KEY_READ, &key); + if (res != ERROR_SUCCESS) + return False; + { + DWORD type = 0; + DWORD count = sizeof(UInt64); + UInt64 val = 0; + res = RegQueryValueEx(key, TEXT("CP 4030"), NULL, + &type, (LPBYTE)&val, &count); + RegCloseKey(key); + if (res != ERROR_SUCCESS + || type != REG_QWORD + || count != sizeof(UInt64) + || ((unsigned)(val >> 12) & 0xf) != 2) + return False; + // we parse SHA2 field of ID_AA64ISAR0_EL1 register: + // 0 : No SHA2 instructions implemented + // 1 : SHA256 implemented + // 2 : SHA256 and SHA512 implemented + } + } +#endif // defined(_WIN32) && defined(MY_CPU_ARM64) + + +#if 1 // 0 for debug to disable SHA512 PROBE code + +/* +----- SHA512 PROBE ----- + +We suppose that "CP 4030" registry reading is enough. +But we use additional SHA512 PROBE code, because +we can catch exception here, and we don't catch exceptions, +if we call Sha512 functions from main code. + +NOTE: arm64 PROBE code doesn't work, if we call it via Wine in linux-arm64. +The program just stops. +Also x64 version of PROBE code doesn't work, if we run it via Intel SDE emulator +without SHA512 support (-skl switch), +The program stops, and we have message from SDE: + TID 0 SDE-ERROR: Executed instruction not valid for specified chip (SKYLAKE): vsha512msg1 +But we still want to catch that exception instead of process stopping. +Does this PROBE code work in native Windows-arm64 (with/without sha512 hw instructions)? +Are there any ways to fix the problems with arm64-wine and x64-SDE cases? +*/ + + PRF(printf("==== CPU_IsSupported_SHA512 PROBE\n");) + { + BoolInt isSupported = False; +#ifdef Z7_SHA512_USE_LONGJMP + void (Z7_CDECL *signal_prev)(int); + /* + if (g_Sha512_Unsupported) + { + PRF(printf("==== g_Sha512_Unsupported\n");) + return False; + } + */ + printf("====== signal(SIGILL)\n"); + signal_prev = signal(SIGILL, Sha512_signal_Handler); + if (signal_prev == SIG_ERR) + { + PRF(printf("====== signal fail\n");) + return False; + } + // PRF(printf("==== signal_prev = %p\n", (void *)signal_prev);) + // docs: Before the specified function is executed, + // the value of func is set to SIG_DFL. + // So we can exit if (setjmp(g_Sha512_jmp_buf) != 0). + PRF(printf("====== setjmp\n");) + if (!setjmp(g_Sha512_jmp_buf)) +#else // Z7_SHA512_USE_LONGJMP + +#ifdef _MSC_VER +#ifdef __clang_major__ + #pragma GCC diagnostic ignored "-Wlanguage-extension-token" +#endif + __try +#endif +#endif // Z7_SHA512_USE_LONGJMP + + { +#if defined(Z7_COMPILER_SHA512_SUPPORTED) +#ifdef Z7_SHA512_USE_SIMPLIFIED_PROBE + // simplified sha512 check for arm64: + const uint64x2_t a = vdupq_n_u64(1); + const uint64x2_t b = vsha512hq_u64(a, a, a); + PRF(printf("======== vsha512hq_u64 probe\n");) + if ((UInt32)vgetq_lane_u64(b, 0) == 0x11800002) +#else + MY_ALIGN(16) + UInt64 temp[SHA512_NUM_DIGEST_WORDS + SHA512_NUM_BLOCK_WORDS]; + memset(temp, 0x5a, sizeof(temp)); + PRF(printf("======== Sha512_UpdateBlocks_HW\n");) + Sha512_UpdateBlocks_HW(temp, + (const Byte *)(const void *)(temp + SHA512_NUM_DIGEST_WORDS), 1); + // PRF(printf("======== t = %x\n", (UInt32)temp[0]);) + if ((UInt32)temp[0] == 0xa33cfdf7) +#endif + { + PRF(printf("======== PROBE SHA512: SHA512 is supported\n");) + isSupported = True; + } +#else // Z7_COMPILER_SHA512_SUPPORTED + // for debug : we generate bad instrction or raise exception. + // __except() doesn't catch raise() calls. +#ifdef Z7_SHA512_USE_LONGJMP + PRF(printf("====== raise(SIGILL)\n");) + raise(SIGILL); +#else +#if defined(_MSC_VER) && defined(MY_CPU_X86) + __asm ud2 +#endif +#endif // Z7_SHA512_USE_LONGJMP +#endif // Z7_COMPILER_SHA512_SUPPORTED + } + +#ifdef Z7_SHA512_USE_LONGJMP + PRF(printf("====== restore signal SIGILL\n");) + signal(SIGILL, signal_prev); +#elif _MSC_VER + __except (EXCEPTION_EXECUTE_HANDLER) + { + PRF(printf("==== CPU_IsSupported_SHA512 __except(EXCEPTION_EXECUTE_HANDLER)\n");) + } +#endif + PRF(printf("== return (sha512 supported) = %d\n", isSupported);) + return isSupported; + } +#else + // without SHA512 PROBE code + return True; +#endif +} + +#endif // Z7_SHA512_USE_PROBE +#endif // defined(Z7_SHA512_PROBE_DEBUG) || defined(Z7_COMPILER_SHA512_SUPPORTED) + + +void Sha512Prepare(void) +{ +#ifdef Z7_COMPILER_SHA512_SUPPORTED + SHA512_FUNC_UPDATE_BLOCKS f, f_hw; + f = Sha512_UpdateBlocks; + f_hw = NULL; +#ifdef Z7_SHA512_USE_PROBE + if (CPU_IsSupported_SHA512_Probe()) +#elif defined(MY_CPU_X86_OR_AMD64) + if (CPU_IsSupported_SHA512() && CPU_IsSupported_AVX2()) +#else + if (CPU_IsSupported_SHA512()) +#endif + { + // printf("\n========== HW SHA512 ======== \n"); + f = f_hw = Sha512_UpdateBlocks_HW; + } + g_SHA512_FUNC_UPDATE_BLOCKS = f; + g_SHA512_FUNC_UPDATE_BLOCKS_HW = f_hw; +#elif defined(Z7_SHA512_PROBE_DEBUG) + CPU_IsSupported_SHA512_Probe(); // for debug +#endif +} + + +#undef K +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef Ch +#undef Maj +#undef W_MAIN +#undef W_PRE +#undef w +#undef blk2_main +#undef blk2 +#undef T1 +#undef T4 +#undef T8 +#undef R1_PRE +#undef R1_MAIN +#undef R2_MAIN +#undef R4 +#undef R4_PRE +#undef R4_MAIN +#undef R8 +#undef R8_PRE +#undef R8_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA512_BIG_W +#undef Z7_SHA512_UNROLL +#undef Z7_COMPILER_SHA512_SUPPORTED diff -Nru p7zip-rar-16.02/C/Sha512.h p7zip-rar-16.02+really25.00+ds/C/Sha512.h --- p7zip-rar-16.02/C/Sha512.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha512.h 2024-10-29 18:00:00.000000000 +0000 @@ -0,0 +1,86 @@ +/* Sha512.h -- SHA-512 Hash +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SHA512_H +#define ZIP7_INC_SHA512_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA512_NUM_BLOCK_WORDS 16 +#define SHA512_NUM_DIGEST_WORDS 8 + +#define SHA512_BLOCK_SIZE (SHA512_NUM_BLOCK_WORDS * 8) +#define SHA512_DIGEST_SIZE (SHA512_NUM_DIGEST_WORDS * 8) +#define SHA512_224_DIGEST_SIZE (224 / 8) +#define SHA512_256_DIGEST_SIZE (256 / 8) +#define SHA512_384_DIGEST_SIZE (384 / 8) + +typedef void (Z7_FASTCALL *SHA512_FUNC_UPDATE_BLOCKS)(UInt64 state[8], const Byte *data, size_t numBlocks); + +/* + if (the system supports different SHA512 code implementations) + { + (CSha512::func_UpdateBlocks) will be used + (CSha512::func_UpdateBlocks) can be set by + Sha512_Init() - to default (fastest) + Sha512_SetFunction() - to any algo + } + else + { + (CSha512::func_UpdateBlocks) is ignored. + } +*/ + +typedef struct +{ + union + { + struct + { + SHA512_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + } vars; + UInt64 _pad_64bit[8]; + void *_pad_align_ptr[2]; + } v; + UInt64 state[SHA512_NUM_DIGEST_WORDS]; + + Byte buffer[SHA512_BLOCK_SIZE]; +} CSha512; + + +#define SHA512_ALGO_DEFAULT 0 +#define SHA512_ALGO_SW 1 +#define SHA512_ALGO_HW 2 + +/* +Sha512_SetFunction() +return: + 0 - (algo) value is not supported, and func_UpdateBlocks was not changed + 1 - func_UpdateBlocks was set according (algo) value. +*/ + +BoolInt Sha512_SetFunction(CSha512 *p, unsigned algo); +// we support only these (digestSize) values: 224/8, 256/8, 384/8, 512/8 +void Sha512_InitState(CSha512 *p, unsigned digestSize); +void Sha512_Init(CSha512 *p, unsigned digestSize); +void Sha512_Update(CSha512 *p, const Byte *data, size_t size); +void Sha512_Final(CSha512 *p, Byte *digest, unsigned digestSize); + + + + +// void Z7_FASTCALL Sha512_UpdateBlocks(UInt64 state[8], const Byte *data, size_t numBlocks); + +/* +call Sha512Prepare() once at program start. +It prepares all supported implementations, and detects the fastest implementation. +*/ + +void Sha512Prepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Sha512Opt.c p7zip-rar-16.02+really25.00+ds/C/Sha512Opt.c --- p7zip-rar-16.02/C/Sha512Opt.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sha512Opt.c 2024-11-24 16:00:00.000000000 +0000 @@ -0,0 +1,395 @@ +/* Sha512Opt.c -- SHA-512 optimized code for SHA-512 hardware instructions +: Igor Pavlov : Public domain */ + +#include "Precomp.h" +#include "Compiler.h" +#include "CpuArch.h" + +// #define Z7_USE_HW_SHA_STUB // for debug +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 2400) && (__INTEL_COMPILER <= 9900) // fix it + #define USE_HW_SHA + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 170001) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 170001) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 140000) + #define USE_HW_SHA + #if !defined(__INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA512__) || !defined(__AVX2__) + #define ATTRIB_SHA512 __attribute__((__target__("sha512,avx2"))) + #endif + #endif + #elif defined(Z7_MSC_VER_ORIGINAL) + #if (_MSC_VER >= 1940) + #define USE_HW_SHA + #else + // #define Z7_USE_HW_SHA_STUB + #endif + #endif +// #endif // MY_CPU_X86_OR_AMD64 +#ifndef USE_HW_SHA + // #define Z7_USE_HW_SHA_STUB // for debug +#endif + +#ifdef USE_HW_SHA + +// #pragma message("Sha512 HW") + +#include + +#if defined (__clang__) && defined(_MSC_VER) + #if !defined(__AVX__) + #include + #endif + #if !defined(__AVX2__) + #include + #endif + #if !defined(__SHA512__) + #include + #endif +#else + +#endif + +/* +SHA512 uses: +AVX: + _mm256_loadu_si256 (vmovdqu) + _mm256_storeu_si256 + _mm256_set_epi32 (unused) +AVX2: + _mm256_add_epi64 : vpaddq + _mm256_shuffle_epi8 : vpshufb + _mm256_shuffle_epi32 : pshufd + _mm256_blend_epi32 : vpblendd + _mm256_permute4x64_epi64 : vpermq : 3c + _mm256_permute2x128_si256: vperm2i128 : 3c + _mm256_extracti128_si256 : vextracti128 : 3c +SHA512: + _mm256_sha512* +*/ + +// K array must be aligned for 32-bytes at least. +// The compiler can look align attribute and selects +// vmovdqu - for code without align attribute +// vmovdqa - for code with align attribute +extern +MY_ALIGN(64) +const UInt64 SHA512_K_ARRAY[80]; +#define K SHA512_K_ARRAY + + +#define ADD_EPI64(dest, src) dest = _mm256_add_epi64(dest, src); +#define SHA512_MSG1(dest, src) dest = _mm256_sha512msg1_epi64(dest, _mm256_extracti128_si256(src, 0)); +#define SHA512_MSG2(dest, src) dest = _mm256_sha512msg2_epi64(dest, src); + +#define LOAD_SHUFFLE(m, k) \ + m = _mm256_loadu_si256((const __m256i *)(const void *)(data + (k) * 32)); \ + m = _mm256_shuffle_epi8(m, mask); \ + +#define NNN(m0, m1, m2, m3) + +#define SM1(m1, m2, m3, m0) \ + SHA512_MSG1(m0, m1); \ + +#define SM2(m2, m3, m0, m1) \ + ADD_EPI64(m0, _mm256_permute4x64_epi64(_mm256_blend_epi32(m2, m3, 3), 0x39)); \ + SHA512_MSG2(m0, m3); \ + +#define RND2(t0, t1, lane) \ + t0 = _mm256_sha512rnds2_epi64(t0, t1, _mm256_extracti128_si256(msg, lane)); + + + +#define R4(k, m0, m1, m2, m3, OP0, OP1) \ + msg = _mm256_add_epi64(m0, *(const __m256i *) (const void *) &K[(k) * 4]); \ + RND2(state0, state1, 0); OP0(m0, m1, m2, m3) \ + RND2(state1, state0, 1); OP1(m0, m1, m2, m3) \ + + + + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \ + +#define PREPARE_STATE \ + state0 = _mm256_shuffle_epi32(state0, 0x4e); /* cdab */ \ + state1 = _mm256_shuffle_epi32(state1, 0x4e); /* ghef */ \ + tmp = state0; \ + state0 = _mm256_permute2x128_si256(state0, state1, 0x13); /* cdgh */ \ + state1 = _mm256_permute2x128_si256(tmp, state1, 2); /* abef */ \ + + +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA512 +ATTRIB_SHA512 +#endif +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + const __m256i mask = _mm256_set_epi32( + 0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607, + 0x08090a0b,0x0c0d0e0f, 0x00010203,0x04050607); + __m256i tmp, state0, state1; + + if (numBlocks == 0) + return; + + state0 = _mm256_loadu_si256((const __m256i *) (const void *) &state[0]); + state1 = _mm256_loadu_si256((const __m256i *) (const void *) &state[4]); + + PREPARE_STATE + + do + { + __m256i state0_save, state1_save; + __m256i m0, m1, m2, m3; + __m256i msg; + // #define msg tmp + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 4, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) + ADD_EPI64(state0, state0_save) + ADD_EPI64(state1, state1_save) + + data += 128; + } + while (--numBlocks); + + PREPARE_STATE + + _mm256_storeu_si256((__m256i *) (void *) &state[0], state0); + _mm256_storeu_si256((__m256i *) (void *) &state[4], state1); +} + +#endif // USE_HW_SHA + +// gcc 8.5 also supports sha512, but we need also support in assembler that is called by gcc +#elif defined(MY_CPU_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_SHA512) + #define USE_HW_SHA + #else + #if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 130000) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1940) // fix it + #define USE_HW_SHA + #endif + #endif + +#ifdef USE_HW_SHA + +// #pragma message("=== Sha512 HW === ") + + +#if defined(__clang__) || defined(__GNUC__) +#if !defined(__ARM_FEATURE_SHA512) +// #pragma message("=== we define SHA3 ATTRIB_SHA512 === ") +#if defined(__clang__) + #define ATTRIB_SHA512 __attribute__((__target__("sha3"))) // "armv8.2-a,sha3" +#else + #define ATTRIB_SHA512 __attribute__((__target__("arch=armv8.2-a+sha3"))) +#endif +#endif +#endif + + +#if defined(Z7_MSC_VER_ORIGINAL) +#include +#else + +#if defined(__clang__) && __clang_major__ < 16 +#if !defined(__ARM_FEATURE_SHA512) +// #pragma message("=== we set __ARM_FEATURE_SHA512 1 === ") + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #define Z7_ARM_FEATURE_SHA512_WAS_SET 1 + #define __ARM_FEATURE_SHA512 1 + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif // clang + +#include + +#if defined(Z7_ARM_FEATURE_SHA512_WAS_SET) && \ + defined(__ARM_FEATURE_SHA512) + Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER + #undef __ARM_FEATURE_SHA512 + #undef Z7_ARM_FEATURE_SHA512_WAS_SET + Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +// #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ") +#endif + +#endif // Z7_MSC_VER_ORIGINAL + +typedef uint64x2_t v128_64; +// typedef __n128 v128_64; // MSVC + +#ifdef MY_CPU_BE + #define MY_rev64_for_LE(x) x +#else + #define MY_rev64_for_LE(x) vrev64q_u8(x) +#endif + +#define LOAD_128_64(_p) vld1q_u64(_p) +#define LOAD_128_8(_p) vld1q_u8 (_p) +#define STORE_128_64(_p, _v) vst1q_u64(_p, _v) + +#define LOAD_SHUFFLE(m, k) \ + m = vreinterpretq_u64_u8( \ + MY_rev64_for_LE( \ + LOAD_128_8(data + (k) * 16))); \ + +// K array must be aligned for 16-bytes at least. +extern +MY_ALIGN(64) +const UInt64 SHA512_K_ARRAY[80]; +#define K SHA512_K_ARRAY + +#define NN(m0, m1, m4, m5, m7) +#define SM(m0, m1, m4, m5, m7) \ + m0 = vsha512su1q_u64(vsha512su0q_u64(m0, m1), m7, vextq_u64(m4, m5, 1)); + +#define R2(k, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP) \ + OP(m0, m1, m4, m5, m7) \ + t = vaddq_u64(m0, vld1q_u64(k)); \ + t = vaddq_u64(vextq_u64(t, t, 1), a3); \ + t = vsha512hq_u64(t, vextq_u64(a2, a3, 1), vextq_u64(a1, a2, 1)); \ + a3 = vsha512h2q_u64(t, a1, a0); \ + a1 = vaddq_u64(a1, t); \ + +#define R8(k, m0,m1,m2,m3,m4,m5,m6,m7, OP) \ + R2 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, a0,a1,a2,a3, OP ) \ + R2 ( (k)+1*2, m1,m2,m3,m4,m5,m6,m7,m0, a3,a0,a1,a2, OP ) \ + R2 ( (k)+2*2, m2,m3,m4,m5,m6,m7,m0,m1, a2,a3,a0,a1, OP ) \ + R2 ( (k)+3*2, m3,m4,m5,m6,m7,m0,m1,m2, a1,a2,a3,a0, OP ) \ + +#define R16(k, OP) \ + R8 ( (k)+0*2, m0,m1,m2,m3,m4,m5,m6,m7, OP ) \ + R8 ( (k)+4*2, m4,m5,m6,m7,m0,m1,m2,m3, OP ) \ + + +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA512 +ATTRIB_SHA512 +#endif +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + v128_64 a0, a1, a2, a3; + + if (numBlocks == 0) + return; + a0 = LOAD_128_64(&state[0]); + a1 = LOAD_128_64(&state[2]); + a2 = LOAD_128_64(&state[4]); + a3 = LOAD_128_64(&state[6]); + do + { + v128_64 a0_save, a1_save, a2_save, a3_save; + v128_64 m0, m1, m2, m3, m4, m5, m6, m7; + v128_64 t; + unsigned i; + const UInt64 *k_ptr; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + LOAD_SHUFFLE (m4, 4) + LOAD_SHUFFLE (m5, 5) + LOAD_SHUFFLE (m6, 6) + LOAD_SHUFFLE (m7, 7) + + a0_save = a0; + a1_save = a1; + a2_save = a2; + a3_save = a3; + + R16 ( K, NN ) + k_ptr = K + 16; + for (i = 0; i < 4; i++) + { + R16 ( k_ptr, SM ) + k_ptr += 16; + } + + a0 = vaddq_u64(a0, a0_save); + a1 = vaddq_u64(a1, a1_save); + a2 = vaddq_u64(a2, a2_save); + a3 = vaddq_u64(a3, a3_save); + + data += 128; + } + while (--numBlocks); + + STORE_128_64(&state[0], a0); + STORE_128_64(&state[2], a1); + STORE_128_64(&state[4], a2); + STORE_128_64(&state[6], a3); +} + +#endif // USE_HW_SHA + +#endif // MY_CPU_ARM_OR_ARM64 + + +#if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB) +// #error Stop_Compiling_UNSUPPORTED_SHA +// #include +// We can compile this file with another C compiler, +// or we can compile asm version. +// So we can generate real code instead of this stub function. +// #include "Sha512.h" +// #if defined(_MSC_VER) +#pragma message("Sha512 HW-SW stub was used") +// #endif +void Z7_FASTCALL Sha512_UpdateBlocks (UInt64 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha512_UpdateBlocks_HW(UInt64 state[8], const Byte *data, size_t numBlocks) +{ + Sha512_UpdateBlocks(state, data, numBlocks); + /* + UNUSED_VAR(state); + UNUSED_VAR(data); + UNUSED_VAR(numBlocks); + exit(1); + return; + */ +} +#endif + + +#undef K +#undef RND2 +#undef MY_rev64_for_LE +#undef NN +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 +#undef SM +#undef R2 +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA512 +#undef USE_VER_MIN +#undef Z7_USE_HW_SHA_STUB diff -Nru p7zip-rar-16.02/C/Sort.c p7zip-rar-16.02+really25.00+ds/C/Sort.c --- p7zip-rar-16.02/C/Sort.c 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sort.c 2025-01-08 09:00:00.000000000 +0000 @@ -1,141 +1,268 @@ -/* Sort.c -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Sort.h" - -#define HeapSortDown(p, k, size, temp) \ - { for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && p[s + 1] > p[s]) s++; \ - if (temp >= p[s]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } - -void HeapSort(UInt32 *p, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt32 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt32 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) - } - { - UInt32 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) - { - p[1] = p[2]; - p[2] = temp; - } - else - p[1] = temp; - } -} - -void HeapSort64(UInt64 *p, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt64 temp = p[i]; - size_t k = i; - HeapSortDown(p, k, size, temp) - } - while (--i != 0); - } - /* - do - { - size_t k = 1; - UInt64 temp = p[size]; - p[size--] = p[1]; - HeapSortDown(p, k, size, temp) - } - while (size > 1); - */ - while (size > 3) - { - UInt64 temp = p[size]; - size_t k = (p[3] > p[2]) ? 3 : 2; - p[size--] = p[1]; - p[1] = p[k]; - HeapSortDown(p, k, size, temp) - } - { - UInt64 temp = p[size]; - p[size] = p[1]; - if (size > 2 && p[2] < temp) - { - p[1] = p[2]; - p[2] = temp; - } - else - p[1] = temp; - } -} - -/* -#define HeapSortRefDown(p, vals, n, size, temp) \ - { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ - size_t s = (k << 1); \ - if (s > size) break; \ - if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ - if (val >= vals[p[s]]) break; \ - p[k] = p[s]; k = s; \ - } p[k] = temp; } - -void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) -{ - if (size <= 1) - return; - p--; - { - size_t i = size / 2; - do - { - UInt32 temp = p[i]; - HeapSortRefDown(p, vals, i, size, temp); - } - while (--i != 0); - } - do - { - UInt32 temp = p[size]; - p[size--] = p[1]; - HeapSortRefDown(p, vals, 1, size, temp); - } - while (size > 1); -} -*/ +/* Sort.c -- Sort functions +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Sort.h" +#include "CpuArch.h" + +#if ( (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_prefetch)) \ + ) +// the code with prefetch is slow for small arrays on x86. +// So we disable prefetch for x86. +#ifndef MY_CPU_X86 + // #pragma message("Z7_PREFETCH : __builtin_prefetch") + #define Z7_PREFETCH(a) __builtin_prefetch((a)) +#endif + +#elif defined(_WIN32) // || defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "7zWindows.h" + +// NOTE: CLANG/GCC/MSVC can define different values for _MM_HINT_T0 / PF_TEMPORAL_LEVEL_1. +// For example, clang-cl can generate "prefetcht2" instruction for +// PreFetchCacheLine(PF_TEMPORAL_LEVEL_1) call. +// But we want to generate "prefetcht0" instruction. +// So for CLANG/GCC we must use __builtin_prefetch() in code branch above +// instead of PreFetchCacheLine() / _mm_prefetch(). + +// New msvc-x86 compiler generates "prefetcht0" instruction for PreFetchCacheLine() call. +// But old x86 cpus don't support "prefetcht0". +// So we will use PreFetchCacheLine(), only if we are sure that +// generated instruction is supported by all cpus of that isa. +#if defined(MY_CPU_AMD64) \ + || defined(MY_CPU_ARM64) \ + || defined(MY_CPU_IA64) +// we need to use additional braces for (a) in PreFetchCacheLine call, because +// PreFetchCacheLine macro doesn't use braces: +// #define PreFetchCacheLine(l, a) _mm_prefetch((CHAR CONST *) a, l) + // #pragma message("Z7_PREFETCH : PreFetchCacheLine") + #define Z7_PREFETCH(a) PreFetchCacheLine(PF_TEMPORAL_LEVEL_1, (a)) +#endif + +#endif // _WIN32 + + +#define PREFETCH_NO(p,k,s,size) + +#ifndef Z7_PREFETCH + #define SORT_PREFETCH(p,k,s,size) +#else + +// #define PREFETCH_LEVEL 2 // use it if cache line is 32-bytes +#define PREFETCH_LEVEL 3 // it is fast for most cases (64-bytes cache line prefetch) +// #define PREFETCH_LEVEL 4 // it can be faster for big array (128-bytes prefetch) + +#if PREFETCH_LEVEL == 0 + + #define SORT_PREFETCH(p,k,s,size) + +#else // PREFETCH_LEVEL != 0 + +/* +if defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + we prefetch one value per cache line. + Use it if array is aligned for cache line size (64 bytes) + or if array is small (less than L1 cache size). + +if !defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + we perfetch all cache lines that can be required. + it can be faster for big unaligned arrays. +*/ + #define USE_PREFETCH_FOR_ALIGNED_ARRAY + +// s == k * 2 +#if 0 && PREFETCH_LEVEL <= 3 && defined(MY_CPU_X86_OR_AMD64) + // x86 supports (lea r1*8+offset) + #define PREFETCH_OFFSET(k,s) ((s) << PREFETCH_LEVEL) +#else + #define PREFETCH_OFFSET(k,s) ((k) << (PREFETCH_LEVEL + 1)) +#endif + +#if 1 && PREFETCH_LEVEL <= 3 && defined(USE_PREFETCH_FOR_ALIGNED_ARRAY) + #define PREFETCH_ADD_OFFSET 0 +#else + // last offset that can be reqiured in PREFETCH_LEVEL step: + #define PREFETCH_RANGE ((2 << PREFETCH_LEVEL) - 1) + #define PREFETCH_ADD_OFFSET PREFETCH_RANGE / 2 +#endif + +#if PREFETCH_LEVEL <= 3 + +#ifdef USE_PREFETCH_FOR_ALIGNED_ARRAY + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_ADD_OFFSET; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2)); \ + }} +#else /* for unaligned array */ + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE)); \ + Z7_PREFETCH((p + s2)); \ + }} +#endif + +#else // PREFETCH_LEVEL > 3 + +#ifdef USE_PREFETCH_FOR_ALIGNED_ARRAY + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE - 16 / 2; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - 16)); \ + Z7_PREFETCH((p + s2)); \ + }} +#else /* for unaligned array */ + #define SORT_PREFETCH(p,k,s,size) \ + { const size_t s2 = PREFETCH_OFFSET(k,s) + PREFETCH_RANGE; \ + if (s2 <= size) { \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE)); \ + Z7_PREFETCH((p + s2 - PREFETCH_RANGE / 2)); \ + Z7_PREFETCH((p + s2)); \ + }} +#endif + +#endif // PREFETCH_LEVEL > 3 +#endif // PREFETCH_LEVEL != 0 +#endif // Z7_PREFETCH + + +#if defined(MY_CPU_ARM64) \ + /* || defined(MY_CPU_AMD64) */ \ + /* || defined(MY_CPU_ARM) && !defined(_MSC_VER) */ + // we want to use cmov, if cmov is very fast: + // - this cmov version is slower for clang-x64. + // - this cmov version is faster for gcc-arm64 for some fast arm64 cpus. + #define Z7_FAST_CMOV_SUPPORTED +#endif + +#ifdef Z7_FAST_CMOV_SUPPORTED + // we want to use cmov here, if cmov is fast: new arm64 cpus. + // we want the compiler to use conditional move for this branch + #define GET_MAX_VAL(n0, n1, max_val_slow) if (n0 < n1) n0 = n1; +#else + // use this branch, if cpu doesn't support fast conditional move. + // it uses slow array access reading: + #define GET_MAX_VAL(n0, n1, max_val_slow) n0 = max_val_slow; +#endif + +#define HeapSortDown(p, k, size, temp, macro_prefetch) \ +{ \ + for (;;) { \ + UInt32 n0, n1; \ + size_t s = k * 2; \ + if (s >= size) { \ + if (s == size) { \ + n0 = p[s]; \ + p[k] = n0; \ + if (temp < n0) k = s; \ + } \ + break; \ + } \ + n0 = p[k * 2]; \ + n1 = p[k * 2 + 1]; \ + s += n0 < n1; \ + GET_MAX_VAL(n0, n1, p[s]) \ + if (temp >= n0) break; \ + macro_prefetch(p, k, s, size) \ + p[k] = n0; \ + k = s; \ + } \ + p[k] = temp; \ +} + + +/* +stage-1 : O(n) : + we generate intermediate partially sorted binary tree: + p[0] : it's additional item for better alignment of tree structure in memory. + p[1] + p[2] p[3] + p[4] p[5] p[6] p[7] + ... + p[x] >= p[x * 2] + p[x] >= p[x * 2 + 1] + +stage-2 : O(n)*log2(N): + we move largest item p[0] from head of tree to the end of array + and insert last item to sorted binary tree. +*/ + +// (p) must be aligned for cache line size (64-bytes) for best performance + +void Z7_FASTCALL HeapSort(UInt32 *p, size_t size) +{ + if (size < 2) + return; + if (size == 2) + { + const UInt32 a0 = p[0]; + const UInt32 a1 = p[1]; + const unsigned k = a1 < a0; + p[k] = a0; + p[k ^ 1] = a1; + return; + } + { + // stage-1 : O(n) + // we transform array to partially sorted binary tree. + size_t i = --size / 2; + // (size) now is the index of the last item in tree, + // if (i) + { + do + { + const UInt32 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp, PREFETCH_NO) + } + while (--i); + } + { + const UInt32 temp = p[0]; + const UInt32 a1 = p[1]; + if (temp < a1) + { + size_t k = 1; + p[0] = a1; + HeapSortDown(p, k, size, temp, PREFETCH_NO) + } + } + } + + if (size < 3) + { + // size == 2 + const UInt32 a0 = p[0]; + p[0] = p[2]; + p[2] = a0; + return; + } + if (size != 3) + { + // stage-2 : O(size) * log2(size): + // we move largest item p[0] from head to the end of array, + // and insert last item to sorted binary tree. + do + { + const UInt32 temp = p[size]; + size_t k = p[2] < p[3] ? 3 : 2; + p[size--] = p[0]; + p[0] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp, SORT_PREFETCH) // PREFETCH_NO + } + while (size != 3); + } + { + const UInt32 a2 = p[2]; + const UInt32 a3 = p[3]; + const size_t k = a2 < a3; + p[2] = p[1]; + p[3] = p[0]; + p[k] = a3; + p[k ^ 1] = a2; + } +} diff -Nru p7zip-rar-16.02/C/Sort.h p7zip-rar-16.02+really25.00+ds/C/Sort.h --- p7zip-rar-16.02/C/Sort.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Sort.h 2025-01-06 09:00:00.000000000 +0000 @@ -1,18 +1,15 @@ -/* Sort.h -- Sort functions -2014-04-05 : Igor Pavlov : Public domain */ - -#ifndef __7Z_SORT_H -#define __7Z_SORT_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -void HeapSort(UInt32 *p, size_t size); -void HeapSort64(UInt64 *p, size_t size); - -/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ - -EXTERN_C_END - -#endif +/* Sort.h -- Sort functions +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SORT_H +#define ZIP7_INC_SORT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void Z7_FASTCALL HeapSort(UInt32 *p, size_t size); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/SwapBytes.c p7zip-rar-16.02+really25.00+ds/C/SwapBytes.c --- p7zip-rar-16.02/C/SwapBytes.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/SwapBytes.c 2024-03-01 11:00:00.000000000 +0000 @@ -0,0 +1,835 @@ +/* SwapBytes.c -- Byte Swap conversion filter +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Compiler.h" +#include "CpuArch.h" +#include "RotateDefs.h" +#include "SwapBytes.h" + +typedef UInt16 CSwapUInt16; +typedef UInt32 CSwapUInt32; + +// #define k_SwapBytes_Mode_BASE 0 + +#ifdef MY_CPU_X86_OR_AMD64 + +#define k_SwapBytes_Mode_SSE2 1 +#define k_SwapBytes_Mode_SSSE3 2 +#define k_SwapBytes_Mode_AVX2 3 + + // #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #define SWAP_ATTRIB_SSE2 __attribute__((__target__("sse2"))) + #define SWAP_ATTRIB_SSSE3 __attribute__((__target__("ssse3"))) + #define SWAP_ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #elif defined(_MSC_VER) + #if (_MSC_VER == 1900) + #pragma warning(disable : 4752) // found Intel(R) Advanced Vector Extensions; consider using /arch:AVX + #endif + #if (_MSC_VER >= 1900) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #elif (_MSC_VER >= 1500) // (VS2008) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSSE3 + #elif (_MSC_VER >= 1310) // (VS2003) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSE2 + #endif + #endif // _MSC_VER + +/* +// for debug +#ifdef k_SwapBytes_Mode_MAX +#undef k_SwapBytes_Mode_MAX +#endif +*/ + +#ifndef k_SwapBytes_Mode_MAX +#define k_SwapBytes_Mode_MAX 0 +#endif + +#if (k_SwapBytes_Mode_MAX != 0) && defined(MY_CPU_AMD64) + #define k_SwapBytes_Mode_MIN k_SwapBytes_Mode_SSE2 +#else + #define k_SwapBytes_Mode_MIN 0 +#endif + +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_AVX2) + #define USE_SWAP_AVX2 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSSE3) + #define USE_SWAP_SSSE3 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSE2) + #define USE_SWAP_128 +#endif + +#if k_SwapBytes_Mode_MAX <= k_SwapBytes_Mode_MIN || !defined(USE_SWAP_128) +#define FORCE_SWAP_MODE +#endif + + +#ifdef USE_SWAP_128 +/* + MMX + SSE + SSE2 + SSE3 + SSSE3 + SSE4.1 + SSE4.2 + SSE4A + AES + AVX, AVX2, FMA +*/ + +#include // sse2 +// typedef __m128i v128; + +#define SWAP2_128(i) { \ + const __m128i v = *(const __m128i *)(const void *)(items + (i) * 8); \ + *( __m128i *)( void *)(items + (i) * 8) = \ + _mm_or_si128( \ + _mm_slli_epi16(v, 8), \ + _mm_srli_epi16(v, 8)); } +// _mm_or_si128() has more ports to execute than _mm_add_epi16(). + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +/* +// sse2 +#define SWAP4_128_pack(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v0 = _mm_unpacklo_epi8(v, mask); \ + __m128i v1 = _mm_unpackhi_epi8(v, mask); \ + v0 = _mm_shufflelo_epi16(v0, 0x1b); \ + v1 = _mm_shufflelo_epi16(v1, 0x1b); \ + v0 = _mm_shufflehi_epi16(v0, 0x1b); \ + v1 = _mm_shufflehi_epi16(v1, 0x1b); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_packus_epi16(v0, v1); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_pack(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + const __m128i mask = _mm_setzero_si128(); + // const __m128i mask = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, 0); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128_pack(0); items += 1 * 4; + // SWAP4_128_pack(0); SWAP4_128_pack(1); items += 2 * 4; + } + while (items != lim); +} + +// sse2 +#define SWAP4_128_shift(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v2; \ + v2 = _mm_or_si128( \ + _mm_slli_si128(_mm_and_si128(v, mask), 1), \ + _mm_and_si128(_mm_srli_si128(v, 1), mask)); \ + v = _mm_or_si128( \ + _mm_slli_epi32(v, 24), \ + _mm_srli_epi32(v, 24)); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_or_si128(v2, v); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_shift(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + #define M1 0xff00 + const __m128i mask = _mm_set_epi32(M1, M1, M1, M1); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + SWAP4_128_shift(0); items += 1 * 4; + } + while (items != lim); +} +*/ + + +#if defined(USE_SWAP_SSSE3) || defined(USE_SWAP_AVX2) + +#define SWAP_SHUF_REV_SEQ_2_VALS(v) (v)+1, (v) +#define SWAP_SHUF_REV_SEQ_4_VALS(v) (v)+3, (v)+2, (v)+1, (v) + +#define SWAP2_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_2_VALS (0 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (1 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (2 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (3 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (4 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (5 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (6 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (7 * 2) + +#define SWAP4_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_4_VALS (0 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (1 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (2 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (3 * 4) + +#if defined(USE_SWAP_AVX2) +/* if we use 256_BIT_INIT_MASK, each static array mask will be larger for 16 bytes */ +// #define SWAP_USE_256_BIT_INIT_MASK +#endif + +#if defined(SWAP_USE_256_BIT_INIT_MASK) && defined(USE_SWAP_AVX2) +#define SWAP_MASK_INIT_SIZE 32 +#else +#define SWAP_MASK_INIT_SIZE 16 +#endif + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap2[] = +{ + SWAP2_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP2_SHUF_MASK_16_BYTES + #endif +}; + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap4[] = +{ + SWAP4_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP4_SHUF_MASK_16_BYTES + #endif +}; + + +#ifdef USE_SWAP_SSSE3 + +#include // ssse3 + +#define SHUF_128(i) *(items + (i)) = \ + _mm_shuffle_epi8(*(items + (i)), mask); // SSSE3 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_SSSE3 +SWAP_ATTRIB_SSSE3 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_128(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m128i *items = (__m128i *)items8; + const __m128i *lim = (const __m128i *)lim8; + // const __m128i mask = _mm_set_epi8(SHUF_SWAP2_MASK_16_VALS); + // const __m128i mask = _mm_set_epi8(SHUF_SWAP4_MASK_16_VALS); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = *(const __m128i *)(const void *)&(k_ShufMask_Swap4[0]); + const __m128i mask = *(const __m128i *)mask128_ptr; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_128(0) SHUF_128(1) items += 2; + SHUF_128(0) SHUF_128(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_SSSE3 + + + +#ifdef USE_SWAP_AVX2 + +#include // avx, avx2 +#if defined(__clang__) +#include +#include +#endif + +#define SHUF_256(i) *(items + (i)) = \ + _mm256_shuffle_epi8(*(items + (i)), mask); // AVX2 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_AVX2 +SWAP_ATTRIB_AVX2 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_256(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m256i *items = (__m256i *)items8; + const __m256i *lim = (const __m256i *)lim8; + /* + UNUSED_VAR(mask128_ptr) + __m256i mask = + for Swap4: _mm256_setr_epi8(SWAP4_SHUF_MASK_16_BYTES, SWAP4_SHUF_MASK_16_BYTES); + for Swap2: _mm256_setr_epi8(SWAP2_SHUF_MASK_16_BYTES, SWAP2_SHUF_MASK_16_BYTES); + */ + const __m256i mask = + #if SWAP_MASK_INIT_SIZE > 16 + *(const __m256i *)(const void *)mask128_ptr; + #else + /* msvc: broadcastsi128() version reserves the stack for no reason + msvc 19.29-: _mm256_insertf128_si256() / _mm256_set_m128i)) versions use non-avx movdqu xmm0,XMMWORD PTR [r8] + msvc 19.30+ (VS2022): replaces _mm256_set_m128i(m,m) to vbroadcastf128(m) as we want + */ + // _mm256_broadcastsi128_si256(*mask128_ptr); +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 80000) + #define MY_mm256_set_m128i(hi, lo) _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1) +#else + #define MY_mm256_set_m128i _mm256_set_m128i +#endif + MY_mm256_set_m128i( + *(const __m128i *)mask128_ptr, + *(const __m128i *)mask128_ptr); + #endif + + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_256(0) SHUF_256(1) items += 2; + SHUF_256(0) SHUF_256(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_AVX2 +#endif // USE_SWAP_SSSE3 || USE_SWAP_AVX2 +#endif // USE_SWAP_128 + + + +// compile message "NEON intrinsics not available with the soft-float ABI" +#elif defined(MY_CPU_ARM_OR_ARM64) \ + && defined(MY_CPU_LE) \ + && !defined(Z7_DISABLE_ARM_NEON) + + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 6) + #if defined(__ARM_FP) + #if (defined(__ARM_ARCH) && (__ARM_ARCH >= 4)) \ + || defined(MY_CPU_ARM64) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) + #define USE_SWAP_128 + #ifdef MY_CPU_ARM64 + // #define SWAP_ATTRIB_NEON __attribute__((__target__(""))) + #else +#if defined(Z7_CLANG_VERSION) + // #define SWAP_ATTRIB_NEON __attribute__((__target__("neon"))) +#else + // #pragma message("SWAP_ATTRIB_NEON __attribute__((__target__(fpu=neon))") + #define SWAP_ATTRIB_NEON __attribute__((__target__("fpu=neon"))) +#endif + #endif // MY_CPU_ARM64 + #endif // __ARM_NEON + #endif // __ARM_ARCH + #endif // __ARM_FP + + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1910) + #define USE_SWAP_128 + #endif + #endif + + #ifdef USE_SWAP_128 + #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64) + #include + #else + +/* +#if !defined(__ARM_NEON) +#if defined(Z7_GCC_VERSION) && (__GNUC__ < 5) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 5) && (Z7_GCC_VERSION < 90201) \ + || defined(Z7_GCC_VERSION) && (__GNUC__ == 5) && (Z7_GCC_VERSION < 100100) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#pragma message("#define __ARM_NEON 1") +// #define __ARM_NEON 1 +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif +*/ + #include + #endif + #endif + +#ifndef USE_SWAP_128 + #define FORCE_SWAP_MODE +#else + +#ifdef MY_CPU_ARM64 + // for debug : comment it + #define FORCE_SWAP_MODE +#else + #define k_SwapBytes_Mode_NEON 1 +#endif +// typedef uint8x16_t v128; +#define SWAP2_128(i) *(uint8x16_t *) (void *)(items + (i) * 8) = \ + vrev16q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 8)); +#define SWAP4_128(i) *(uint8x16_t *) (void *)(items + (i) * 4) = \ + vrev32q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 4)); + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes4_128(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + } + while (items != lim); +} + +#endif // USE_SWAP_128 + +#else // MY_CPU_ARM_OR_ARM64 +#define FORCE_SWAP_MODE +#endif // MY_CPU_ARM_OR_ARM64 + + + + + + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_X86) + /* _byteswap_ushort() in MSVC x86 32-bit works via slow { mov dh, al; mov dl, ah } + So we use own versions of byteswap function */ + #if (_MSC_VER < 1400 ) // old MSVC-X86 without _rotr16() support + #define SWAP2_16(i) { UInt32 v = items[i]; v += (v << 16); v >>= 8; items[i] = (CSwapUInt16)v; } + #else // is new MSVC-X86 with fast _rotr16() + #include + #define SWAP2_16(i) { items[i] = _rotr16(items[i], 8); } + #endif +#else // is not MSVC-X86 + #define SWAP2_16(i) { CSwapUInt16 v = items[i]; items[i] = Z7_BSWAP16(v); } +#endif // MSVC-X86 + +#if defined(Z7_CPU_FAST_BSWAP_SUPPORTED) + #define SWAP4_32(i) { CSwapUInt32 v = items[i]; items[i] = Z7_BSWAP32(v); } +#else + #define SWAP4_32(i) \ + { UInt32 v = items[i]; \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); \ + v = rotlFixed(v, 16); \ + items[i] = v; } +#endif + + + + +#if defined(FORCE_SWAP_MODE) && defined(USE_SWAP_128) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(MY_CPU_X86_OR_AMD64) + #define DEFAULT_Swap4 SwapBytes4_128 + #endif +#endif + +#if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + +#define SWAP_BASE_FUNCS_PREFIXES \ +Z7_FORCE_INLINE \ +static \ +Z7_ATTRIB_NO_VECTOR \ +void Z7_FASTCALL + + +#if defined(MY_CPU_ARM_OR_ARM64) +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wlanguage-extension-token" +#endif +#endif + + +#ifdef MY_CPU_64BIT + +#if defined(MY_CPU_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 8) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + + #define SWAP2_64_VAR(v) asm ("rev16 %x0,%x0" : "+r" (v)); + #define SWAP4_64_VAR(v) asm ("rev32 %x0,%x0" : "+r" (v)); + +#else // is not ARM64-GNU + +#if !defined(MY_CPU_X86_OR_AMD64) || (k_SwapBytes_Mode_MIN == 0) || !defined(USE_SWAP_128) + #define SWAP2_64_VAR(v) \ + v = ( 0x00ff00ff00ff00ff & (v >> 8)) \ + + ((0x00ff00ff00ff00ff & v) << 8); + /* plus gives faster code in MSVC */ +#endif + +#ifdef Z7_CPU_FAST_BSWAP_SUPPORTED + #define SWAP4_64_VAR(v) \ + v = Z7_BSWAP64(v); \ + v = Z7_ROTL64(v, 32); +#else + #define SWAP4_64_VAR(v) \ + v = ( 0x000000ff000000ff & (v >> 24)) \ + + ((0x000000ff000000ff & v) << 24 ) \ + + ( 0x0000ff000000ff00 & (v >> 8)) \ + + ((0x0000ff000000ff00 & v) << 8 ) \ + ; +#endif + +#endif // ARM64-GNU + + +#ifdef SWAP2_64_VAR + +#define SWAP2_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 4); \ + SWAP2_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 4) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_64(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + } + while (items != lim); +} + + #define DEFAULT_Swap2 SwapBytes2_64 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 + #endif +#else // !defined(SWAP2_64_VAR) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 1 + #endif +#endif // SWAP2_64_VAR + + +#define SWAP4_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 2); \ + SWAP4_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 2) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_64(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + } + while (items != lim); +} + +#define DEFAULT_Swap4 SwapBytes4_64 + +#else // is not 64BIT + + +#if defined(MY_CPU_ARM_OR_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 6) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + +#ifdef MY_CPU_64BIT + #define SWAP2_32_VAR(v) asm ("rev16 %w0,%w0" : "+r" (v)); +#else + #define SWAP2_32_VAR(v) asm ("rev16 %0,%0" : "+r" (v)); // for clang/gcc + // asm ("rev16 %r0,%r0" : "+r" (a)); // for gcc +#endif + +#elif defined(_MSC_VER) && (_MSC_VER < 1300) && defined(MY_CPU_X86) \ + || !defined(Z7_CPU_FAST_BSWAP_SUPPORTED) \ + || !defined(Z7_CPU_FAST_ROTATE_SUPPORTED) + // old msvc doesn't support _byteswap_ulong() + #define SWAP2_32_VAR(v) \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); + +#else // is not ARM and is not old-MSVC-X86 and fast BSWAP/ROTATE are supported + #define SWAP2_32_VAR(v) \ + v = Z7_BSWAP32(v); \ + v = rotlFixed(v, 16); + +#endif // GNU-ARM* + +#define SWAP2_32(i) { \ + UInt32 v = *(const UInt32 *)(const void *)(items + (i) * 2); \ + SWAP2_32_VAR(v); \ + *(UInt32 *)(void *)(items + (i) * 2) = v; } + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_32(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + } + while (items != lim); +} + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_32(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_32(0) SWAP4_32(1) items += 2; + SWAP4_32(0) SWAP4_32(1) items += 2; + } + while (items != lim); +} + +#define DEFAULT_Swap2 SwapBytes2_32 +#define DEFAULT_Swap4 SwapBytes4_32 +#if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 +#endif + +#endif // MY_CPU_64BIT +#endif // if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + + + +#if !defined(FORCE_SWAP_MODE) +static unsigned g_SwapBytes_Mode; +#endif + +/* size of largest unrolled loop iteration: 128 bytes = 4 * 32 bytes (AVX). */ +#define SWAP_ITERATION_BLOCK_SIZE_MAX (1 << 7) + +// 32 bytes for (AVX) or 2 * 16-bytes for NEON. +#define SWAP_VECTOR_ALIGN_SIZE (1 << 5) + +Z7_NO_INLINE +void z7_SwapBytes2(CSwapUInt16 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP2_16(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt16) - 1; + size_t numItems2 = numItems; + CSwapUInt16 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #endif // MY_CPU_X86_OR_AMD64 + #if SWAP2_DEFAULT_MODE == 0 + if (g_SwapBytes_Mode != 0) + SwapBytes2_128(items, lim); + else + #endif + #endif // FORCE_SWAP_MODE + DEFAULT_Swap2(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP2_16(0) + items++; + } +} + + +Z7_NO_INLINE +void z7_SwapBytes4(CSwapUInt32 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP4_32(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt32) - 1; + size_t numItems2 = numItems; + CSwapUInt32 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #else // MY_CPU_X86_OR_AMD64 + + if (g_SwapBytes_Mode != 0) + SwapBytes4_128(items, lim); + else + #endif // MY_CPU_X86_OR_AMD64 + #endif // FORCE_SWAP_MODE + DEFAULT_Swap4(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP4_32(0) + items++; + } +} + + +// #define SHOW_HW_STATUS + +#ifdef SHOW_HW_STATUS +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +void z7_SwapBytesPrepare(void) +{ +#ifndef FORCE_SWAP_MODE + unsigned mode = 0; // k_SwapBytes_Mode_BASE; + +#ifdef MY_CPU_ARM_OR_ARM64 + { + if (CPU_IsSupported_NEON()) + { + // #pragma message ("=== SwapBytes NEON") + PRF(printf("\n=== SwapBytes NEON\n");) + mode = k_SwapBytes_Mode_NEON; + } + } +#else // MY_CPU_ARM_OR_ARM64 + { + #ifdef USE_SWAP_AVX2 + if (CPU_IsSupported_AVX2()) + { + // #pragma message ("=== SwapBytes AVX2") + PRF(printf("\n=== SwapBytes AVX2\n");) + mode = k_SwapBytes_Mode_AVX2; + } + else + #endif + #ifdef USE_SWAP_SSSE3 + if (CPU_IsSupported_SSSE3()) + { + // #pragma message ("=== SwapBytes SSSE3") + PRF(printf("\n=== SwapBytes SSSE3\n");) + mode = k_SwapBytes_Mode_SSSE3; + } + else + #endif + #if !defined(MY_CPU_AMD64) + if (CPU_IsSupported_SSE2()) + #endif + { + // #pragma message ("=== SwapBytes SSE2") + PRF(printf("\n=== SwapBytes SSE2\n");) + mode = k_SwapBytes_Mode_SSE2; + } + } +#endif // MY_CPU_ARM_OR_ARM64 + g_SwapBytes_Mode = mode; + // g_SwapBytes_Mode = 0; // for debug +#endif // FORCE_SWAP_MODE + PRF(printf("\n=== SwapBytesPrepare\n");) +} + +#undef PRF diff -Nru p7zip-rar-16.02/C/SwapBytes.h p7zip-rar-16.02+really25.00+ds/C/SwapBytes.h --- p7zip-rar-16.02/C/SwapBytes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/SwapBytes.h 2023-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,17 @@ +/* SwapBytes.h -- Byte Swap conversion filter +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SWAP_BYTES_H +#define ZIP7_INC_SWAP_BYTES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void z7_SwapBytes2(UInt16 *data, size_t numItems); +void z7_SwapBytes4(UInt32 *data, size_t numItems); +void z7_SwapBytesPrepare(void); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Threads.c p7zip-rar-16.02+really25.00+ds/C/Threads.c --- p7zip-rar-16.02/C/Threads.c 2009-06-06 09:00:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Threads.c 2025-07-05 09:00:00.000000000 +0000 @@ -1,582 +1,812 @@ -/* Threads.c */ - -#include "Threads.h" - -#ifdef ENV_BEOS -#include -#else -#include -#include -#endif - -#include - -#if defined(__linux__) -#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP -#endif - -#ifdef ENV_BEOS - -/* TODO : optimize the code and verify the returned values */ - -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) -{ - thread->_tid = spawn_thread((int32 (*)(void *))startAddress, "CThread", B_LOW_PRIORITY, parameter); - if (thread->_tid >= B_OK) { - resume_thread(thread->_tid); - } else { - thread->_tid = B_BAD_THREAD_ID; - } - thread->_created = 1; - return 0; // SZ_OK; -} - -WRes Thread_Wait(CThread *thread) -{ - int ret; - - if (thread->_created == 0) - return EINVAL; - - if (thread->_tid >= B_OK) - { - status_t exit_value; - wait_for_thread(thread->_tid, &exit_value); - thread->_tid = B_BAD_THREAD_ID; - } else { - return EINVAL; - } - - thread->_created = 0; - - return 0; -} - -WRes Thread_Close(CThread *thread) -{ - if (!thread->_created) return SZ_OK; - - thread->_tid = B_BAD_THREAD_ID; - thread->_created = 0; - return SZ_OK; -} - - -WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) -{ - p->_index_waiting = 0; - p->_manual_reset = manualReset; - p->_state = (initialSignaled ? TRUE : FALSE); - p->_created = 1; - p->_sem = create_sem(1,"event"); - return 0; -} - -WRes Event_Set(CEvent *p) { - int index; - acquire_sem(p->_sem); - p->_state = TRUE; - for(index = 0 ; index < p->_index_waiting ; index++) - { - send_data(p->_waiting[index], '7zCN', NULL, 0); - } - p->_index_waiting = 0; - release_sem(p->_sem); - return 0; -} - -WRes Event_Reset(CEvent *p) { - acquire_sem(p->_sem); - p->_state = FALSE; - release_sem(p->_sem); - return 0; -} - -WRes Event_Wait(CEvent *p) { - acquire_sem(p->_sem); - while (p->_state == FALSE) - { - thread_id sender; - p->_waiting[p->_index_waiting++] = find_thread(NULL); - release_sem(p->_sem); - /* int msg = */ receive_data(&sender, NULL, 0); - acquire_sem(p->_sem); - } - if (p->_manual_reset == FALSE) - { - p->_state = FALSE; - } - release_sem(p->_sem); - return 0; -} - -WRes Event_Close(CEvent *p) { - if (p->_created) - { - p->_created = 0; - delete_sem(p->_sem); - } - return 0; -} - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) -{ - p->_index_waiting = 0; - p->_count = initiallyCount; - p->_maxCount = maxCount; - p->_created = 1; - p->_sem = create_sem(1,"sem"); - return 0; -} - -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) -{ - UInt32 newCount; - int index; - - if (releaseCount < 1) return EINVAL; - - acquire_sem(p->_sem); - newCount = p->_count + releaseCount; - if (newCount > p->_maxCount) - { - release_sem(p->_sem); - return EINVAL; - } - p->_count = newCount; - for(index = 0 ; index < p->_index_waiting ; index++) - { - send_data(p->_waiting[index], '7zCN', NULL, 0); - } - p->_index_waiting = 0; - release_sem(p->_sem); - return 0; -} - -WRes Semaphore_Wait(CSemaphore *p) { - acquire_sem(p->_sem); - while (p->_count < 1) - { - thread_id sender; - p->_waiting[p->_index_waiting++] = find_thread(NULL); - release_sem(p->_sem); - /* int msg = */ receive_data(&sender, NULL, 0); - acquire_sem(p->_sem); - } - p->_count--; - release_sem(p->_sem); - return 0; -} - -WRes Semaphore_Close(CSemaphore *p) { - if (p->_created) - { - p->_created = 0; - delete_sem(p->_sem); - } - return 0; -} - -WRes CriticalSection_Init(CCriticalSection * lpCriticalSection) -{ - lpCriticalSection->_sem = create_sem(1,"cc"); - return 0; -} - -#else /* !ENV_BEOS */ - -WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) -{ - pthread_attr_t attr; - int ret; - - thread->_created = 0; - - ret = pthread_attr_init(&attr); - if (ret) return ret; - - ret = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); - if (ret) return ret; - - ret = pthread_create(&thread->_tid, &attr, (void * (*)(void *))startAddress, parameter); - - /* ret2 = */ pthread_attr_destroy(&attr); - - if (ret) return ret; - - thread->_created = 1; - - return 0; // SZ_OK; -} - -WRes Thread_Wait(CThread *thread) -{ - void *thread_return; - int ret; - - if (thread->_created == 0) - return EINVAL; - - ret = pthread_join(thread->_tid,&thread_return); - thread->_created = 0; - - return ret; -} - -WRes Thread_Close(CThread *thread) -{ - if (!thread->_created) return SZ_OK; - - pthread_detach(thread->_tid); - thread->_tid = 0; - thread->_created = 0; - return SZ_OK; -} - -#ifdef DEBUG_SYNCHRO - -#include - -static void dump_error(int ligne,int ret,const char *text,void *param) -{ - printf("\n##T%d#ERROR2 (l=%d) %s : param=%p ret = %d (%s)##\n",(int)pthread_self(),ligne,text,param,ret,strerror(ret)); - // abort(); -} - -WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) -{ - int ret; - pthread_mutexattr_t mutexattr; - memset(&mutexattr,0,sizeof(mutexattr)); - ret = pthread_mutexattr_init(&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"Event_Create::pthread_mutexattr_init",&mutexattr); - ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) dump_error(__LINE__,ret,"Event_Create::pthread_mutexattr_settype",&mutexattr); - ret = pthread_mutex_init(&p->_mutex,&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"Event_Create::pthread_mutexattr_init",&p->_mutex); - if (ret == 0) - { - ret = pthread_cond_init(&p->_cond,0); - if (ret != 0) dump_error(__LINE__,ret,"Event_Create::pthread_cond_init",&p->_cond); - p->_manual_reset = manualReset; - p->_state = (initialSignaled ? TRUE : FALSE); - p->_created = 1; - } - return ret; -} - -WRes Event_Set(CEvent *p) { - int ret = pthread_mutex_lock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"ES::pthread_mutex_lock",&p->_mutex); - if (ret == 0) - { - p->_state = TRUE; - ret = pthread_cond_broadcast(&p->_cond); - if (ret != 0) dump_error(__LINE__,ret,"ES::pthread_cond_broadcast",&p->_cond); - if (ret == 0) - { - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"ES::pthread_mutex_unlock",&p->_mutex); - } - } - return ret; -} - -WRes Event_Reset(CEvent *p) { - int ret = pthread_mutex_lock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"ER::pthread_mutex_lock",&p->_mutex); - if (ret == 0) - { - p->_state = FALSE; - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"ER::pthread_mutex_unlock",&p->_mutex); - } - return ret; -} - -WRes Event_Wait(CEvent *p) { - int ret = pthread_mutex_lock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"EW::pthread_mutex_lock",&p->_mutex); - if (ret == 0) - { - while ((p->_state == FALSE) && (ret == 0)) - { - ret = pthread_cond_wait(&p->_cond, &p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"EW::pthread_cond_wait",&p->_mutex); - } - if (ret == 0) - { - if (p->_manual_reset == FALSE) - { - p->_state = FALSE; - } - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"EW::pthread_mutex_unlock",&p->_mutex); - } - } - return ret; -} - -WRes Event_Close(CEvent *p) { - if (p->_created) - { - int ret; - p->_created = 0; - ret = pthread_mutex_destroy(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"EC::pthread_mutex_destroy",&p->_mutex); - ret = pthread_cond_destroy(&p->_cond); - if (ret != 0) dump_error(__LINE__,ret,"EC::pthread_cond_destroy",&p->_cond); - } - return 0; -} - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) -{ - int ret; - pthread_mutexattr_t mutexattr; - memset(&mutexattr,0,sizeof(mutexattr)); - ret = pthread_mutexattr_init(&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"SemC::pthread_mutexattr_init",&mutexattr); - ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) dump_error(__LINE__,ret,"SemC::pthread_mutexattr_settype",&mutexattr); - ret = pthread_mutex_init(&p->_mutex,&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"SemC::pthread_mutexattr_init",&p->_mutex); - if (ret == 0) - { - ret = pthread_cond_init(&p->_cond,0); - if (ret != 0) dump_error(__LINE__,ret,"SemC::pthread_cond_init",&p->_mutex); - p->_count = initiallyCount; - p->_maxCount = maxCount; - p->_created = 1; - } - return ret; -} - -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) -{ - int ret; - if (releaseCount < 1) return EINVAL; - - ret = pthread_mutex_lock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemR::pthread_mutex_lock",&p->_mutex); - if (ret == 0) - { - UInt32 newCount = p->_count + releaseCount; - if (newCount > p->_maxCount) - { - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemR::pthread_mutex_unlock",&p->_mutex); - return EINVAL; - } - p->_count = newCount; - ret = pthread_cond_broadcast(&p->_cond); - if (ret != 0) dump_error(__LINE__,ret,"SemR::pthread_cond_broadcast",&p->_cond); - if (ret == 0) - { - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemR::pthread_mutex_unlock",&p->_mutex); - } - } - return ret; -} - -WRes Semaphore_Wait(CSemaphore *p) { - int ret = pthread_mutex_lock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemW::pthread_mutex_lock",&p->_mutex); - if (ret == 0) - { - while ((p->_count < 1) && (ret == 0)) - { - ret = pthread_cond_wait(&p->_cond, &p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemW::pthread_cond_wait",&p->_mutex); - } - if (ret == 0) - { - p->_count--; - ret = pthread_mutex_unlock(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"SemW::pthread_mutex_unlock",&p->_mutex); - } - } - return ret; -} - -WRes Semaphore_Close(CSemaphore *p) { - if (p->_created) - { - int ret; - p->_created = 0; - ret = pthread_mutex_destroy(&p->_mutex); - if (ret != 0) dump_error(__LINE__,ret,"Semc::pthread_mutex_destroy",&p->_mutex); - ret = pthread_cond_destroy(&p->_cond); - if (ret != 0) dump_error(__LINE__,ret,"Semc::pthread_cond_destroy",&p->_cond); - } - return 0; -} - -WRes CriticalSection_Init(CCriticalSection * lpCriticalSection) -{ - if (lpCriticalSection) - { - int ret; - pthread_mutexattr_t mutexattr; - memset(&mutexattr,0,sizeof(mutexattr)); - ret = pthread_mutexattr_init(&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"CS I::pthread_mutexattr_init",&mutexattr); - ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) dump_error(__LINE__,ret,"CS I::pthread_mutexattr_settype",&mutexattr); - ret = pthread_mutex_init(&lpCriticalSection->_mutex,&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"CS I::pthread_mutexattr_init",&lpCriticalSection->_mutex); - return ret; - } - return EINTR; -} - -void CriticalSection_Enter(CCriticalSection * lpCriticalSection) -{ - if (lpCriticalSection) - { - int ret = pthread_mutex_lock(&(lpCriticalSection->_mutex)); - if (ret != 0) dump_error(__LINE__,ret,"CS::pthread_mutex_lock",&(lpCriticalSection->_mutex)); - } -} - -void CriticalSection_Leave(CCriticalSection * lpCriticalSection) -{ - if (lpCriticalSection) - { - int ret = pthread_mutex_unlock(&(lpCriticalSection->_mutex)); - if (ret != 0) dump_error(__LINE__,ret,"CS::pthread_mutex_unlock",&(lpCriticalSection->_mutex)); - } -} - -void CriticalSection_Delete(CCriticalSection * lpCriticalSection) -{ - if (lpCriticalSection) - { - int ret = pthread_mutex_destroy(&(lpCriticalSection->_mutex)); - if (ret != 0) dump_error(__LINE__,ret,"CS::pthread_mutex_destroy",&(lpCriticalSection->_mutex)); - } -} - -#else - -WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) -{ - pthread_mutex_init(&p->_mutex,0); - pthread_cond_init(&p->_cond,0); - p->_manual_reset = manualReset; - p->_state = (initialSignaled ? TRUE : FALSE); - p->_created = 1; - return 0; -} - -WRes Event_Set(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - p->_state = TRUE; - pthread_cond_broadcast(&p->_cond); - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Reset(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - p->_state = FALSE; - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Wait(CEvent *p) { - pthread_mutex_lock(&p->_mutex); - while (p->_state == FALSE) - { - pthread_cond_wait(&p->_cond, &p->_mutex); - } - if (p->_manual_reset == FALSE) - { - p->_state = FALSE; - } - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Event_Close(CEvent *p) { - if (p->_created) - { - p->_created = 0; - pthread_mutex_destroy(&p->_mutex); - pthread_cond_destroy(&p->_cond); - } - return 0; -} - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) -{ - pthread_mutex_init(&p->_mutex,0); - pthread_cond_init(&p->_cond,0); - p->_count = initiallyCount; - p->_maxCount = maxCount; - p->_created = 1; - return 0; -} - -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) -{ - UInt32 newCount; - - if (releaseCount < 1) return EINVAL; - - pthread_mutex_lock(&p->_mutex); - - newCount = p->_count + releaseCount; - if (newCount > p->_maxCount) - { - pthread_mutex_unlock(&p->_mutex); - return EINVAL; - } - p->_count = newCount; - pthread_cond_broadcast(&p->_cond); - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Semaphore_Wait(CSemaphore *p) { - pthread_mutex_lock(&p->_mutex); - while (p->_count < 1) - { - pthread_cond_wait(&p->_cond, &p->_mutex); - } - p->_count--; - pthread_mutex_unlock(&p->_mutex); - return 0; -} - -WRes Semaphore_Close(CSemaphore *p) { - if (p->_created) - { - p->_created = 0; - pthread_mutex_destroy(&p->_mutex); - pthread_cond_destroy(&p->_cond); - } - return 0; -} - -WRes CriticalSection_Init(CCriticalSection * lpCriticalSection) -{ - return pthread_mutex_init(&(lpCriticalSection->_mutex),0); -} - -#endif /* DEBUG_SYNCHRO */ - -#endif /* ENV_BEOS */ - -WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) - { return Event_Create(p, TRUE, initialSignaled); } - -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) - { return ManualResetEvent_Create(p, 0); } - -WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) - { return Event_Create(p, FALSE, initialSignaled); } -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) - { return AutoResetEvent_Create(p, 0); } - +/* Threads.c -- multithreading library +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 + +#ifndef USE_THREADS_CreateThread +#include +#endif + +#include "Threads.h" + +static WRes GetError(void) +{ + const DWORD res = GetLastError(); + return res ? (WRes)res : 1; +} + +static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); } +static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } + +WRes HandlePtr_Close(HANDLE *p) +{ + if (*p != NULL) + { + if (!CloseHandle(*p)) + return GetError(); + *p = NULL; + } + return 0; +} + +WRes Handle_WaitObject(HANDLE h) +{ + DWORD dw = WaitForSingleObject(h, INFINITE); + /* + (dw) result: + WAIT_OBJECT_0 // 0 + WAIT_ABANDONED // 0x00000080 : is not compatible with Win32 Error space + WAIT_TIMEOUT // 0x00000102 : is compatible with Win32 Error space + WAIT_FAILED // 0xFFFFFFFF + */ + if (dw == WAIT_FAILED) + { + dw = GetLastError(); + if (dw == 0) + return WAIT_FAILED; + } + return (WRes)dw; +} + +#define Thread_Wait(p) Handle_WaitObject(*(p)) + +WRes Thread_Wait_Close(CThread *p) +{ + WRes res = Thread_Wait(p); + WRes res2 = Thread_Close(p); + return (res != 0 ? res : res2); +} + +typedef struct MY_PROCESSOR_NUMBER { + WORD Group; + BYTE Number; + BYTE Reserved; +} MY_PROCESSOR_NUMBER, *MY_PPROCESSOR_NUMBER; + +typedef struct MY_GROUP_AFFINITY { +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION < 100000) + // KAFFINITY is not defined in old mingw + ULONG_PTR +#else + KAFFINITY +#endif + Mask; + WORD Group; + WORD Reserved[3]; +} MY_GROUP_AFFINITY, *MY_PGROUP_AFFINITY; + +typedef BOOL (WINAPI *Func_SetThreadGroupAffinity)( + HANDLE hThread, + CONST MY_GROUP_AFFINITY *GroupAffinity, + MY_PGROUP_AFFINITY PreviousGroupAffinity); + +typedef BOOL (WINAPI *Func_GetThreadGroupAffinity)( + HANDLE hThread, + MY_PGROUP_AFFINITY GroupAffinity); + +typedef BOOL (WINAPI *Func_GetProcessGroupAffinity)( + HANDLE hProcess, + PUSHORT GroupCount, + PUSHORT GroupArray); + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +#if 0 +#include +#define PRF(x) x +/* +-- + before call of SetThreadGroupAffinity() + GetProcessGroupAffinity return one group. + after call of SetThreadGroupAffinity(): + GetProcessGroupAffinity return more than group, + if SetThreadGroupAffinity() was to another group. +-- + GetProcessAffinityMask MS DOCs: + { + If the calling process contains threads in multiple groups, + the function returns zero for both affinity masks. + } + but tests in win10 with 2 groups (less than 64 cores total): + GetProcessAffinityMask() still returns non-zero affinity masks + even after SetThreadGroupAffinity() calls. +*/ +static void PrintProcess_Info() +{ + { + const + Func_GetProcessGroupAffinity fn_GetProcessGroupAffinity = + (Func_GetProcessGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetProcessGroupAffinity"); + if (fn_GetProcessGroupAffinity) + { + unsigned i; + USHORT GroupCounts[64]; + USHORT GroupCount = Z7_ARRAY_SIZE(GroupCounts); + BOOL boolRes = fn_GetProcessGroupAffinity(GetCurrentProcess(), + &GroupCount, GroupCounts); + printf("\n====== GetProcessGroupAffinity : " + "boolRes=%u GroupCounts = %u :", + boolRes, (unsigned)GroupCount); + for (i = 0; i < GroupCount; i++) + printf(" %u", GroupCounts[i]); + printf("\n"); + } + } + { + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask)) + { + PRF(printf("\n====== GetProcessAffinityMask : " + ": processAffinityMask=%x, systemAffinityMask=%x\n", + (UInt32)processAffinityMask, (UInt32)systemAffinityMask);) + } + else + printf("\n==GetProcessAffinityMask FAIL"); + } +} +#else +#ifndef USE_THREADS_CreateThread +// #define PRF(x) +#endif +#endif + +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) +{ + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + + #ifdef USE_THREADS_CreateThread + + DWORD threadId; + *p = CreateThread(NULL, 0, func, param, 0, &threadId); + + #else + + unsigned threadId; + *p = (HANDLE)(_beginthreadex(NULL, 0, func, param, 0, &threadId)); + +#if 0 // 1 : for debug + { + DWORD_PTR prevMask; + DWORD_PTR affinity = 1 << 0; + prevMask = SetThreadAffinityMask(*p, (DWORD_PTR)affinity); + prevMask = prevMask; + } +#endif +#if 0 // 1 : for debug + { + /* win10: new thread will be created in same group that is assigned to parent thread + but affinity mask will contain all allowed threads of that group, + even if affinity mask of parent group is not full + win11: what group it will be created, if we have set + affinity of parent thread with ThreadGroupAffinity? + */ + const + Func_GetThreadGroupAffinity fn = + (Func_GetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetThreadGroupAffinity"); + if (fn) + { + // BOOL wres2; + MY_GROUP_AFFINITY groupAffinity; + memset(&groupAffinity, 0, sizeof(groupAffinity)); + /* wres2 = */ fn(*p, &groupAffinity); + PRF(printf("\n==Thread_Create cur = %6u GetThreadGroupAffinity(): " + "wres2_BOOL = %u, group=%u mask=%x\n", + GetCurrentThreadId(), + wres2, + groupAffinity.Group, + (UInt32)groupAffinity.Mask);) + } + } +#endif + + #endif + + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return HandleToWRes(*p); +} + + +WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity) +{ + #ifdef USE_THREADS_CreateThread + + UNUSED_VAR(affinity) + return Thread_Create(p, func, param); + + #else + + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + HANDLE h; + WRes wres; + unsigned threadId; + h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId)); + *p = h; + wres = HandleToWRes(h); + if (h) + { + { + // DWORD_PTR prevMask = + SetThreadAffinityMask(h, (DWORD_PTR)affinity); + /* + if (prevMask == 0) + { + // affinity change is non-critical error, so we can ignore it + // wres = GetError(); + } + */ + } + { + const DWORD prevSuspendCount = ResumeThread(h); + /* ResumeThread() returns: + 0 : was_not_suspended + 1 : was_resumed + -1 : error + */ + if (prevSuspendCount == (DWORD)-1) + wres = GetError(); + } + } + + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return wres; + + #endif +} + + +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask) +{ +#ifdef USE_THREADS_CreateThread + + UNUSED_VAR(group) + UNUSED_VAR(affinityMask) + return Thread_Create(p, func, param); + +#else + + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ + HANDLE h; + WRes wres; + unsigned threadId; + h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId)); + *p = h; + wres = HandleToWRes(h); + if (h) + { + // PrintProcess_Info(); + { + const + Func_SetThreadGroupAffinity fn = + (Func_SetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "SetThreadGroupAffinity"); + if (fn) + { + // WRes wres2; + MY_GROUP_AFFINITY groupAffinity, prev_groupAffinity; + memset(&groupAffinity, 0, sizeof(groupAffinity)); + // groupAffinity.Mask must use only bits that supported by current group + // (groupAffinity.Mask = 0) means all allowed bits + groupAffinity.Mask = affinityMask; + groupAffinity.Group = (WORD)group; + // wres2 = + fn(h, &groupAffinity, &prev_groupAffinity); + /* + if (groupAffinity.Group == prev_groupAffinity.Group) + wres2 = wres2; + else + wres2 = wres2; + if (wres2 == 0) + { + wres2 = GetError(); + PRF(printf("\n==SetThreadGroupAffinity error: %u\n", wres2);) + } + else + { + PRF(printf("\n==Thread_Create_With_Group::SetThreadGroupAffinity()" + " threadId = %6u" + " group=%u mask=%x\n", + threadId, + prev_groupAffinity.Group, + (UInt32)prev_groupAffinity.Mask);) + } + */ + } + } + { + const DWORD prevSuspendCount = ResumeThread(h); + /* ResumeThread() returns: + 0 : was_not_suspended + 1 : was_resumed + -1 : error + */ + if (prevSuspendCount == (DWORD)-1) + wres = GetError(); + } + } + + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return wres; + + #endif +} + + +static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) +{ + *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); + return HandleToWRes(*p); +} + +WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } +WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } + +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } + + +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) +{ + // negative ((LONG)maxCount) is not supported in WIN32::CreateSemaphore() + *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); + return HandleToWRes(*p); +} + +WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount) +{ + // if (Semaphore_IsCreated(p)) + { + WRes wres = Semaphore_Close(p); + if (wres != 0) + return wres; + } + return Semaphore_Create(p, initCount, maxCount); +} + +static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) + { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) + { return Semaphore_Release(p, (LONG)num, NULL); } +WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } + +WRes CriticalSection_Init(CCriticalSection *p) +{ + /* InitializeCriticalSection() can raise exception: + Windows XP, 2003 : can raise a STATUS_NO_MEMORY exception + Windows Vista+ : no exceptions */ + #ifdef _MSC_VER + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wlanguage-extension-token" + #endif + __try + #endif + { + InitializeCriticalSection(p); + /* InitializeCriticalSectionAndSpinCount(p, 0); */ + } + #ifdef _MSC_VER + __except (EXCEPTION_EXECUTE_HANDLER) { return ERROR_NOT_ENOUGH_MEMORY; } + #endif + return 0; +} + + + + +#else // _WIN32 + +// ---------- POSIX ---------- + +#if defined(__linux__) && !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) +#ifndef Z7_AFFINITY_DISABLE +// _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET +// clang < 3.6 : unknown warning group '-Wreserved-id-macro' +// clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier" +// clang >= 13 : do not give warning +#if !defined(_GNU_SOURCE) +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +// #define _GNU_SOURCE +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif // !defined(_GNU_SOURCE) +#endif // Z7_AFFINITY_DISABLE +#endif // __linux__ + +#include "Threads.h" + +#include +#include +#include +#ifdef Z7_AFFINITY_SUPPORTED +// #include +#endif + + +// #include +// #define PRF(p) p +#define PRF(p) +#define Print(s) PRF(printf("\n%s\n", s);) + +WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet) +{ + // new thread in Posix probably inherits affinity from parrent thread + Print("Thread_Create_With_CpuSet") + + pthread_attr_t attr; + int ret; + // int ret2; + + p->_created = 0; + + RINOK(pthread_attr_init(&attr)) + + ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + if (!ret) + { + if (cpuSet) + { + // pthread_attr_setaffinity_np() is not supported for MUSL compile. + // so we check for __GLIBC__ here +#if defined(Z7_AFFINITY_SUPPORTED) && defined( __GLIBC__) + /* + printf("\n affinity :"); + unsigned i; + for (i = 0; i < sizeof(*cpuSet) && i < 8; i++) + { + Byte b = *((const Byte *)cpuSet + i); + char temp[32]; + #define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) + temp[0] = GET_HEX_CHAR((b & 0xF)); + temp[1] = GET_HEX_CHAR((b >> 4)); + // temp[0] = GET_HEX_CHAR((b >> 4)); // big-endian + // temp[1] = GET_HEX_CHAR((b & 0xF)); // big-endian + temp[2] = 0; + printf("%s", temp); + } + printf("\n"); + */ + + // ret2 = + pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet); + // if (ret2) ret = ret2; +#endif + } + + ret = pthread_create(&p->_tid, &attr, func, param); + + if (!ret) + { + p->_created = 1; + /* + if (cpuSet) + { + // ret2 = + pthread_setaffinity_np(p->_tid, sizeof(*cpuSet), cpuSet); + // if (ret2) ret = ret2; + } + */ + } + } + // ret2 = + pthread_attr_destroy(&attr); + // if (ret2 != 0) ret = ret2; + return ret; +} + + +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) +{ + return Thread_Create_With_CpuSet(p, func, param, NULL); +} + +/* +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinity) +{ + UNUSED_VAR(group) + return Thread_Create_With_Affinity(p, func, param, affinity); +} +*/ + +WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity) +{ + Print("Thread_Create_WithAffinity") + CCpuSet cs; + unsigned i; + CpuSet_Zero(&cs); + for (i = 0; i < sizeof(affinity) * 8; i++) + { + if (affinity == 0) + break; + if (affinity & 1) + { + CpuSet_Set(&cs, i); + } + affinity >>= 1; + } + return Thread_Create_With_CpuSet(p, func, param, &cs); +} + + +WRes Thread_Close(CThread *p) +{ + // Print("Thread_Close") + int ret; + if (!p->_created) + return 0; + + ret = pthread_detach(p->_tid); + p->_tid = 0; + p->_created = 0; + return ret; +} + + +WRes Thread_Wait_Close(CThread *p) +{ + // Print("Thread_Wait_Close") + void *thread_return; + int ret; + if (!p->_created) + return EINVAL; + + ret = pthread_join(p->_tid, &thread_return); + // probably we can't use that (_tid) after pthread_join(), so we close thread here + p->_created = 0; + p->_tid = 0; + return ret; +} + + + +static WRes Event_Create(CEvent *p, int manualReset, int signaled) +{ + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) + p->_manual_reset = manualReset; + p->_state = (signaled ? True : False); + p->_created = 1; + return 0; +} + +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) + { return Event_Create(p, True, signaled); } +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) + { return ManualResetEvent_Create(p, 0); } +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) + { return Event_Create(p, False, signaled); } +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) + { return AutoResetEvent_Create(p, 0); } + + +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) +// freebsd: +#pragma GCC diagnostic ignored "-Wthread-safety-analysis" +#endif + +WRes Event_Set(CEvent *p) +{ + RINOK(pthread_mutex_lock(&p->_mutex)) + p->_state = True; + { + const int res1 = pthread_cond_broadcast(&p->_cond); + const int res2 = pthread_mutex_unlock(&p->_mutex); + return (res2 ? res2 : res1); + } +} + +WRes Event_Reset(CEvent *p) +{ + RINOK(pthread_mutex_lock(&p->_mutex)) + p->_state = False; + return pthread_mutex_unlock(&p->_mutex); +} + +WRes Event_Wait(CEvent *p) +{ + RINOK(pthread_mutex_lock(&p->_mutex)) + while (p->_state == False) + { + // ETIMEDOUT + // ret = + pthread_cond_wait(&p->_cond, &p->_mutex); + // if (ret != 0) break; + } + if (p->_manual_reset == False) + { + p->_state = False; + } + return pthread_mutex_unlock(&p->_mutex); +} + +WRes Event_Close(CEvent *p) +{ + if (!p->_created) + return 0; + p->_created = 0; + { + const int res1 = pthread_mutex_destroy(&p->_mutex); + const int res2 = pthread_cond_destroy(&p->_cond); + return (res1 ? res1 : res2); + } +} + + +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) +{ + if (initCount > maxCount || maxCount < 1) + return EINVAL; + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) + p->_count = initCount; + p->_maxCount = maxCount; + p->_created = 1; + return 0; +} + + +WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount) +{ + if (Semaphore_IsCreated(p)) + { + /* + WRes wres = Semaphore_Close(p); + if (wres != 0) + return wres; + */ + if (initCount > maxCount || maxCount < 1) + return EINVAL; + // return EINVAL; // for debug + p->_count = initCount; + p->_maxCount = maxCount; + return 0; + } + return Semaphore_Create(p, initCount, maxCount); +} + + +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) +{ + UInt32 newCount; + int ret; + + if (releaseCount < 1) + return EINVAL; + + RINOK(pthread_mutex_lock(&p->_mutex)) + + newCount = p->_count + releaseCount; + if (newCount > p->_maxCount) + ret = ERROR_TOO_MANY_POSTS; // EINVAL; + else + { + p->_count = newCount; + ret = pthread_cond_broadcast(&p->_cond); + } + RINOK(pthread_mutex_unlock(&p->_mutex)) + return ret; +} + +WRes Semaphore_Wait(CSemaphore *p) +{ + RINOK(pthread_mutex_lock(&p->_mutex)) + while (p->_count < 1) + { + pthread_cond_wait(&p->_cond, &p->_mutex); + } + p->_count--; + return pthread_mutex_unlock(&p->_mutex); +} + +WRes Semaphore_Close(CSemaphore *p) +{ + if (!p->_created) + return 0; + p->_created = 0; + { + const int res1 = pthread_mutex_destroy(&p->_mutex); + const int res2 = pthread_cond_destroy(&p->_cond); + return (res1 ? res1 : res2); + } +} + + + +WRes CriticalSection_Init(CCriticalSection *p) +{ + // Print("CriticalSection_Init") + if (!p) + return EINTR; + return pthread_mutex_init(&p->_mutex, NULL); +} + +void CriticalSection_Enter(CCriticalSection *p) +{ + // Print("CriticalSection_Enter") + if (p) + { + // int ret = + pthread_mutex_lock(&p->_mutex); + } +} + +void CriticalSection_Leave(CCriticalSection *p) +{ + // Print("CriticalSection_Leave") + if (p) + { + // int ret = + pthread_mutex_unlock(&p->_mutex); + } +} + +void CriticalSection_Delete(CCriticalSection *p) +{ + // Print("CriticalSection_Delete") + if (p) + { + // int ret = + pthread_mutex_destroy(&p->_mutex); + } +} + +LONG InterlockedIncrement(LONG volatile *addend) +{ + // Print("InterlockedIncrement") + #ifdef USE_HACK_UNSAFE_ATOMIC + LONG val = *addend + 1; + *addend = val; + return val; + #else + + #if defined(__clang__) && (__clang_major__ >= 8) + #pragma GCC diagnostic ignored "-Watomic-implicit-seq-cst" + #endif + return __sync_add_and_fetch(addend, 1); + #endif +} + +LONG InterlockedDecrement(LONG volatile *addend) +{ + // Print("InterlockedDecrement") + #ifdef USE_HACK_UNSAFE_ATOMIC + LONG val = *addend - 1; + *addend = val; + return val; + #else + return __sync_sub_and_fetch(addend, 1); + #endif +} + +#endif // _WIN32 + +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p) +{ + if (Event_IsCreated(p)) + return Event_Reset(p); + return AutoResetEvent_CreateNotSignaled(p); +} + +void ThreadNextGroup_Init(CThreadNextGroup *p, UInt32 numGroups, UInt32 startGroup) +{ + // printf("\n====== ThreadNextGroup_Init numGroups = %x: startGroup=%x\n", numGroups, startGroup); + if (numGroups == 0) + numGroups = 1; + p->NumGroups = numGroups; + p->NextGroup = startGroup % numGroups; +} + + +UInt32 ThreadNextGroup_GetNext(CThreadNextGroup *p) +{ + const UInt32 next = p->NextGroup; + p->NextGroup = (next + 1) % p->NumGroups; + return next; +} + +#undef PRF +#undef Print diff -Nru p7zip-rar-16.02/C/Threads.h p7zip-rar-16.02+really25.00+ds/C/Threads.h --- p7zip-rar-16.02/C/Threads.h 2014-12-21 13:23:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Threads.h 2025-06-30 14:00:00.000000000 +0000 @@ -1,123 +1,260 @@ -/* Threads.h -- multithreading library -2008-11-22 : Igor Pavlov : Public domain */ - -#ifndef __7Z_THRESDS_H -#define __7Z_THRESDS_H - -#include "7zTypes.h" -#include "windows.h" - -#ifdef ENV_BEOS -#include -#define MAX_THREAD 256 -#else -#include -#endif - -/* #define DEBUG_SYNCHRO 1 */ - -typedef struct _CThread -{ -#ifdef ENV_BEOS - thread_id _tid; -#else - pthread_t _tid; -#endif - int _created; - -} CThread; - -#define Thread_Construct(thread) (thread)->_created = 0 -#define Thread_WasCreated(thread) ((thread)->_created != 0) - -typedef unsigned THREAD_FUNC_RET_TYPE; -#define THREAD_FUNC_CALL_TYPE MY_STD_CALL -#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE - -typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); - -WRes Thread_Create(CThread *thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter); -WRes Thread_Wait(CThread *thread); -WRes Thread_Close(CThread *thread); - -typedef struct _CEvent -{ - int _created; - int _manual_reset; - int _state; -#ifdef ENV_BEOS - thread_id _waiting[MAX_THREAD]; - int _index_waiting; - sem_id _sem; -#else - pthread_mutex_t _mutex; - pthread_cond_t _cond; -#endif -} CEvent; - -typedef CEvent CAutoResetEvent; -typedef CEvent CManualResetEvent; - -#define Event_Construct(event) (event)->_created = 0 -#define Event_IsCreated(event) ((event)->_created) - -WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); -WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); -WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); -WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); -WRes Event_Set(CEvent *event); -WRes Event_Reset(CEvent *event); -WRes Event_Wait(CEvent *event); -WRes Event_Close(CEvent *event); - - -typedef struct _CSemaphore -{ - int _created; - UInt32 _count; - UInt32 _maxCount; -#ifdef ENV_BEOS - thread_id _waiting[MAX_THREAD]; - int _index_waiting; - sem_id _sem; -#else - pthread_mutex_t _mutex; - pthread_cond_t _cond; -#endif -} CSemaphore; - -#define Semaphore_Construct(p) (p)->_created = 0 - -WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); -WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); -#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1) -WRes Semaphore_Wait(CSemaphore *p); -WRes Semaphore_Close(CSemaphore *p); - -typedef struct { -#ifdef ENV_BEOS - sem_id _sem; -#else - pthread_mutex_t _mutex; -#endif -} CCriticalSection; - -WRes CriticalSection_Init(CCriticalSection *p); -#ifdef ENV_BEOS -#define CriticalSection_Delete(p) delete_sem((p)->_sem) -#define CriticalSection_Enter(p) acquire_sem((p)->_sem) -#define CriticalSection_Leave(p) release_sem((p)->_sem) -#else -#ifdef DEBUG_SYNCHRO -void CriticalSection_Delete(CCriticalSection *); -void CriticalSection_Enter(CCriticalSection *); -void CriticalSection_Leave(CCriticalSection *); -#else -#define CriticalSection_Delete(p) pthread_mutex_destroy(&((p)->_mutex)) -#define CriticalSection_Enter(p) pthread_mutex_lock(&((p)->_mutex)) -#define CriticalSection_Leave(p) pthread_mutex_unlock(&((p)->_mutex)) -#endif -#endif - -#endif - +/* Threads.h -- multithreading library +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_THREADS_H +#define ZIP7_INC_THREADS_H + +#ifdef _WIN32 +#include "7zWindows.h" + +#else + +#include "Compiler.h" + +// #define Z7_AFFINITY_DISABLE +#if defined(__linux__) +#if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) +#ifndef Z7_AFFINITY_DISABLE +#define Z7_AFFINITY_SUPPORTED +// #pragma message(" ==== Z7_AFFINITY_SUPPORTED") +#if !defined(_GNU_SOURCE) +// #pragma message(" ==== _GNU_SOURCE set") +// we need _GNU_SOURCE for cpu_set_t, if we compile for MUSL +Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define _GNU_SOURCE +Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER +#endif +#endif +#endif +#endif + +#include + +#endif + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#ifdef _WIN32 + +WRes HandlePtr_Close(HANDLE *h); +WRes Handle_WaitObject(HANDLE h); + +typedef HANDLE CThread; + +#define Thread_CONSTRUCT(p) { *(p) = NULL; } +#define Thread_WasCreated(p) (*(p) != NULL) +#define Thread_Close(p) HandlePtr_Close(p) +// #define Thread_Wait(p) Handle_WaitObject(*(p)) + +#ifdef UNDER_CE + // if (USE_THREADS_CreateThread is defined), we use _beginthreadex() + // if (USE_THREADS_CreateThread is not definned), we use CreateThread() + #define USE_THREADS_CreateThread +#endif + +typedef + #ifdef USE_THREADS_CreateThread + DWORD + #else + unsigned + #endif + THREAD_FUNC_RET_TYPE; + +#define THREAD_FUNC_RET_ZERO 0 + +typedef DWORD_PTR CAffinityMask; +typedef DWORD_PTR CCpuSet; + +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((DWORD_PTR)1 << (cpu)) + +#else // _WIN32 + +typedef struct +{ + pthread_t _tid; + int _created; +} CThread; + +#define Thread_CONSTRUCT(p) { (p)->_tid = 0; (p)->_created = 0; } +#define Thread_WasCreated(p) ((p)->_created != 0) +WRes Thread_Close(CThread *p); +// #define Thread_Wait Thread_Wait_Close + +typedef void * THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_RET_ZERO NULL + + +typedef UInt64 CAffinityMask; + +#ifdef Z7_AFFINITY_SUPPORTED + +typedef cpu_set_t CCpuSet; +#define CpuSet_Zero(p) CPU_ZERO(p) +#define CpuSet_Set(p, cpu) CPU_SET(cpu, p) +#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p) + +#else + +typedef UInt64 CCpuSet; +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((UInt64)1 << (cpu)) +#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0) + +#endif + + +#endif // _WIN32 + + +#define THREAD_FUNC_CALL_TYPE Z7_STDCALL + +#if defined(_WIN32) && defined(__GNUC__) +/* GCC compiler for x86 32-bit uses the rule: + the stack is 16-byte aligned before CALL instruction for function calling. + But only root function main() contains instructions that + set 16-byte alignment for stack pointer. And another functions + just keep alignment, if it was set in some parent function. + + The problem: + if we create new thread in MinGW (GCC) 32-bit x86 via _beginthreadex() or CreateThread(), + the root function of thread doesn't set 16-byte alignment. + And stack frames in all child functions also will be unaligned in that case. + + Here we set (force_align_arg_pointer) attribute for root function of new thread. + Do we need (force_align_arg_pointer) also for another systems? */ + + #define THREAD_FUNC_ATTRIB_ALIGN_ARG __attribute__((force_align_arg_pointer)) + // #define THREAD_FUNC_ATTRIB_ALIGN_ARG // for debug : bad alignment in SSE functions +#else + #define THREAD_FUNC_ATTRIB_ALIGN_ARG +#endif + +#define THREAD_FUNC_DECL THREAD_FUNC_ATTRIB_ALIGN_ARG THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE + +typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); +WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); +WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity); +WRes Thread_Wait_Close(CThread *p); + +#ifdef _WIN32 +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask); +#define Thread_Create_With_CpuSet(p, func, param, cs) \ + Thread_Create_With_Affinity(p, func, param, *cs) +#else +WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet); +#endif + +typedef struct +{ + unsigned NumGroups; + unsigned NextGroup; +} CThreadNextGroup; + +void ThreadNextGroup_Init(CThreadNextGroup *p, unsigned numGroups, unsigned startGroup); +unsigned ThreadNextGroup_GetNext(CThreadNextGroup *p); + + +#ifdef _WIN32 + +typedef HANDLE CEvent; +typedef CEvent CAutoResetEvent; +typedef CEvent CManualResetEvent; +#define Event_Construct(p) *(p) = NULL +#define Event_IsCreated(p) (*(p) != NULL) +#define Event_Close(p) HandlePtr_Close(p) +#define Event_Wait(p) Handle_WaitObject(*(p)) +WRes Event_Set(CEvent *p); +WRes Event_Reset(CEvent *p); +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); + +typedef HANDLE CSemaphore; +#define Semaphore_Construct(p) *(p) = NULL +#define Semaphore_IsCreated(p) (*(p) != NULL) +#define Semaphore_Close(p) HandlePtr_Close(p) +#define Semaphore_Wait(p) Handle_WaitObject(*(p)) +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); +WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount); +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); +WRes Semaphore_Release1(CSemaphore *p); + +typedef CRITICAL_SECTION CCriticalSection; +WRes CriticalSection_Init(CCriticalSection *p); +#define CriticalSection_Delete(p) DeleteCriticalSection(p) +#define CriticalSection_Enter(p) EnterCriticalSection(p) +#define CriticalSection_Leave(p) LeaveCriticalSection(p) + + +#else // _WIN32 + +typedef struct +{ + int _created; + int _manual_reset; + int _state; + pthread_mutex_t _mutex; + pthread_cond_t _cond; +} CEvent; + +typedef CEvent CAutoResetEvent; +typedef CEvent CManualResetEvent; + +#define Event_Construct(p) (p)->_created = 0 +#define Event_IsCreated(p) ((p)->_created) + +WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); +WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); +WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); +WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); + +WRes Event_Set(CEvent *p); +WRes Event_Reset(CEvent *p); +WRes Event_Wait(CEvent *p); +WRes Event_Close(CEvent *p); + + +typedef struct +{ + int _created; + UInt32 _count; + UInt32 _maxCount; + pthread_mutex_t _mutex; + pthread_cond_t _cond; +} CSemaphore; + +#define Semaphore_Construct(p) (p)->_created = 0 +#define Semaphore_IsCreated(p) ((p)->_created) + +WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); +WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount); +WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); +#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1) +WRes Semaphore_Wait(CSemaphore *p); +WRes Semaphore_Close(CSemaphore *p); + + +typedef struct +{ + pthread_mutex_t _mutex; +} CCriticalSection; + +WRes CriticalSection_Init(CCriticalSection *p); +void CriticalSection_Delete(CCriticalSection *cs); +void CriticalSection_Enter(CCriticalSection *cs); +void CriticalSection_Leave(CCriticalSection *cs); + +LONG InterlockedIncrement(LONG volatile *addend); +LONG InterlockedDecrement(LONG volatile *addend); + +#endif // _WIN32 + +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Util/7z/7z.dsp p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsp --- p7zip-rar-16.02/C/Util/7z/7z.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsp 2024-01-26 14:00:00.000000000 +0000 @@ -0,0 +1,249 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "Z7_PPMD_SUPPORT" /D "Z7_EXTRACT_ONLY" /FAcs /Yu"Precomp.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7zDec.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /D "Z7_PPMD_SUPPORT" /D "Z7_EXTRACT_ONLY" /Yu"Precomp.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7zDec.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\7z.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zArcIn.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrcOpt.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zDec.c +# ADD CPP /D "_7ZIP_PPMD_SUPPPORT" +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zStream.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra86.c +# End Source File +# Begin Source File + +SOURCE=..\..\BraIA64.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.c +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=..\..\Ppmd7.c +# End Source File +# Begin Source File + +SOURCE=..\..\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\Ppmd7Dec.c +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.c +# ADD CPP /Yc"Precomp.h" +# End Source File +# Begin Source File + +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zMain.c +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/7z/7z.dsw p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsw --- p7zip-rar-16.02/C/Util/7z/7z.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/7z.dsw 2008-03-17 08:00:00.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=.\7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/C/Util/7z/7zMain.c p7zip-rar-16.02+really25.00+ds/C/Util/7z/7zMain.c --- p7zip-rar-16.02/C/Util/7z/7zMain.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/7zMain.c 2024-02-28 16:00:00.000000000 +0000 @@ -0,0 +1,889 @@ +/* 7zMain.c - Test application for 7z Decoder +2024-02-28 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +#include + +#ifndef USE_WINDOWS_FILE +/* for mkdir */ +#ifdef _WIN32 +#include +#else +#include +#include +#ifdef __GNUC__ +#include +#endif +#include +// #include +#include +#include +#endif +#endif + +#include "../../7zFile.h" +#include "../../7z.h" +#include "../../7zAlloc.h" +#include "../../7zBuf.h" +#include "../../7zCrc.h" +#include "../../7zVersion.h" + +#include "../../CpuArch.h" + +#define kInputBufSize ((size_t)1 << 18) + +static const ISzAlloc g_Alloc = { SzAlloc, SzFree }; +// static const ISzAlloc g_Alloc_temp = { SzAllocTemp, SzFreeTemp }; + + +static void Print(const char *s) +{ + fputs(s, stdout); +} + + +static int Buf_EnsureSize(CBuf *dest, size_t size) +{ + if (dest->size >= size) + return 1; + Buf_Free(dest, &g_Alloc); + return Buf_Create(dest, size, &g_Alloc); +} + +#ifndef _WIN32 +#define MY_USE_UTF8 +#endif + +/* #define MY_USE_UTF8 */ + +#ifdef MY_USE_UTF8 + +#define MY_UTF8_START(n) (0x100 - (1 << (7 - (n)))) + +#define MY_UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) + +#define MY_UTF8_HEAD(n, val) ((Byte)(MY_UTF8_START(n) + (val >> (6 * (n))))) +#define MY_UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F))) + +static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim) +{ + size_t size = 0; + for (;;) + { + UInt32 val; + if (src == srcLim) + return size; + + size++; + val = *src++; + + if (val < 0x80) + continue; + + if (val < MY_UTF8_RANGE(1)) + { + size++; + continue; + } + + if (val >= 0xD800 && val < 0xDC00 && src != srcLim) + { + const UInt32 c2 = *src; + if (c2 >= 0xDC00 && c2 < 0xE000) + { + src++; + size += 3; + continue; + } + } + + size += 2; + } +} + +static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim) +{ + for (;;) + { + UInt32 val; + if (src == srcLim) + return dest; + + val = *src++; + + if (val < 0x80) + { + *dest++ = (Byte)val; + continue; + } + + if (val < MY_UTF8_RANGE(1)) + { + dest[0] = MY_UTF8_HEAD(1, val); + dest[1] = MY_UTF8_CHAR(0, val); + dest += 2; + continue; + } + + if (val >= 0xD800 && val < 0xDC00 && src != srcLim) + { + const UInt32 c2 = *src; + if (c2 >= 0xDC00 && c2 < 0xE000) + { + src++; + val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; + dest[0] = MY_UTF8_HEAD(3, val); + dest[1] = MY_UTF8_CHAR(2, val); + dest[2] = MY_UTF8_CHAR(1, val); + dest[3] = MY_UTF8_CHAR(0, val); + dest += 4; + continue; + } + } + + dest[0] = MY_UTF8_HEAD(2, val); + dest[1] = MY_UTF8_CHAR(1, val); + dest[2] = MY_UTF8_CHAR(0, val); + dest += 3; + } +} + +static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen) +{ + size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen); + destLen += 1; + if (!Buf_EnsureSize(dest, destLen)) + return SZ_ERROR_MEM; + *Utf16_To_Utf8(dest->data, src, src + srcLen) = 0; + return SZ_OK; +} + +#endif + +static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s + #ifndef MY_USE_UTF8 + , UINT codePage + #endif + ) +{ + size_t len = 0; + for (len = 0; s[len] != 0; len++) {} + + #ifndef MY_USE_UTF8 + { + const size_t size = len * 3 + 100; + if (!Buf_EnsureSize(buf, size)) + return SZ_ERROR_MEM; + { + buf->data[0] = 0; + if (len != 0) + { + const char defaultChar = '_'; + BOOL defUsed; + const unsigned numChars = (unsigned)WideCharToMultiByte( + codePage, 0, (LPCWSTR)s, (int)len, (char *)buf->data, (int)size, &defaultChar, &defUsed); + if (numChars == 0 || numChars >= size) + return SZ_ERROR_FAIL; + buf->data[numChars] = 0; + } + return SZ_OK; + } + } + #else + return Utf16_To_Utf8Buf(buf, s, len); + #endif +} + +#ifdef _WIN32 + #ifndef USE_WINDOWS_FILE + static UINT g_FileCodePage = CP_ACP; + #define MY_FILE_CODE_PAGE_PARAM ,g_FileCodePage + #endif +#else + #define MY_FILE_CODE_PAGE_PARAM +#endif + +static WRes MyCreateDir(const UInt16 *name) +{ + #ifdef USE_WINDOWS_FILE + + return CreateDirectoryW((LPCWSTR)name, NULL) ? 0 : GetLastError(); + + #else + + CBuf buf; + WRes res; + Buf_Init(&buf); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) + + res = + #ifdef _WIN32 + _mkdir((const char *)buf.data) + #else + mkdir((const char *)buf.data, 0777) + #endif + == 0 ? 0 : errno; + Buf_Free(&buf, &g_Alloc); + return res; + + #endif +} + +static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name) +{ + #ifdef USE_WINDOWS_FILE + return OutFile_OpenW(p, (LPCWSTR)name); + #else + CBuf buf; + WRes res; + Buf_Init(&buf); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) + res = OutFile_Open(p, (const char *)buf.data); + Buf_Free(&buf, &g_Alloc); + return res; + #endif +} + + +static SRes PrintString(const UInt16 *s) +{ + CBuf buf; + SRes res; + Buf_Init(&buf); + res = Utf16_To_Char(&buf, s + #ifndef MY_USE_UTF8 + , CP_OEMCP + #endif + ); + if (res == SZ_OK) + Print((const char *)buf.data); + Buf_Free(&buf, &g_Alloc); + return res; +} + +static void UInt64ToStr(UInt64 value, char *s, int numDigits) +{ + char temp[32]; + int pos = 0; + do + { + temp[pos++] = (char)('0' + (unsigned)(value % 10)); + value /= 10; + } + while (value != 0); + + for (numDigits -= pos; numDigits > 0; numDigits--) + *s++ = ' '; + + do + *s++ = temp[--pos]; + while (pos); + *s = '\0'; +} + +static char *UIntToStr(char *s, unsigned value, int numDigits) +{ + char temp[16]; + int pos = 0; + do + temp[pos++] = (char)('0' + (value % 10)); + while (value /= 10); + + for (numDigits -= pos; numDigits > 0; numDigits--) + *s++ = '0'; + + do + *s++ = temp[--pos]; + while (pos); + *s = '\0'; + return s; +} + +static void UIntToStr_2(char *s, unsigned value) +{ + s[0] = (char)('0' + (value / 10)); + s[1] = (char)('0' + (value % 10)); +} + + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + + + +#ifndef _WIN32 + +// MS uses long for BOOL, but long is 32-bit in MS. So we use int. +// typedef long BOOL; +typedef int BOOL; + +typedef struct +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME; + +static LONG TIME_GetBias(void) +{ + const time_t utc = time(NULL); + struct tm *ptm = localtime(&utc); + const int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ + ptm = gmtime(&utc); + ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ + return (int)(mktime(ptm) - utc); +} + +#define TICKS_PER_SEC 10000000 + +#define GET_TIME_64(pft) ((pft)->dwLowDateTime | ((UInt64)(pft)->dwHighDateTime << 32)) + +#define SET_FILETIME(ft, v64) \ + (ft)->dwLowDateTime = (DWORD)v64; \ + (ft)->dwHighDateTime = (DWORD)(v64 >> 32); + +#define WINAPI +#define TRUE 1 + +static BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime) +{ + UInt64 v = GET_TIME_64(fileTime); + v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC); + SET_FILETIME(localFileTime, v) + return TRUE; +} + +static const UInt32 kNumTimeQuantumsInSecond = 10000000; +static const UInt32 kFileTimeStartYear = 1601; +static const UInt32 kUnixTimeStartYear = 1970; + +static Int64 Time_FileTimeToUnixTime64(const FILETIME *ft) +{ + const UInt64 kUnixTimeOffset = + (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear)); + const UInt64 winTime = GET_TIME_64(ft); + return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset; +} + +#if defined(_AIX) + #define MY_ST_TIMESPEC st_timespec +#else + #define MY_ST_TIMESPEC timespec +#endif + +static void FILETIME_To_timespec(const FILETIME *ft, struct MY_ST_TIMESPEC *ts) +{ + if (ft) + { + const Int64 sec = Time_FileTimeToUnixTime64(ft); + // time_t is long + const time_t sec2 = (time_t)sec; + if (sec2 == sec) + { + ts->tv_sec = sec2; + { + const UInt64 winTime = GET_TIME_64(ft); + ts->tv_nsec = (long)((winTime % 10000000) * 100); + } + return; + } + } + // else + { + ts->tv_sec = 0; + // ts.tv_nsec = UTIME_NOW; // set to the current time + ts->tv_nsec = UTIME_OMIT; // keep old timesptamp + } +} + +static WRes Set_File_FILETIME(const UInt16 *name, const FILETIME *mTime) +{ + struct timespec times[2]; + + const int flags = 0; // follow link + // = AT_SYMLINK_NOFOLLOW; // don't follow link + + CBuf buf; + int res; + Buf_Init(&buf); + RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM)) + FILETIME_To_timespec(NULL, ×[0]); + FILETIME_To_timespec(mTime, ×[1]); + res = utimensat(AT_FDCWD, (const char *)buf.data, times, flags); + Buf_Free(&buf, &g_Alloc); + if (res == 0) + return 0; + return errno; +} + +#endif + +static void NtfsFileTime_to_FILETIME(const CNtfsFileTime *t, FILETIME *ft) +{ + ft->dwLowDateTime = (DWORD)(t->Low); + ft->dwHighDateTime = (DWORD)(t->High); +} + +static void ConvertFileTimeToString(const CNtfsFileTime *nTime, char *s) +{ + unsigned year, mon, hour, min, sec; + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + UInt32 t; + UInt32 v; + // UInt64 v64 = nt->Low | ((UInt64)nt->High << 32); + UInt64 v64; + { + FILETIME fileTime, locTime; + NtfsFileTime_to_FILETIME(nTime, &fileTime); + if (!FileTimeToLocalFileTime(&fileTime, &locTime)) + { + locTime.dwHighDateTime = + locTime.dwLowDateTime = 0; + } + v64 = locTime.dwLowDateTime | ((UInt64)locTime.dwHighDateTime << 32); + } + v64 /= 10000000; + sec = (unsigned)(v64 % 60); v64 /= 60; + min = (unsigned)(v64 % 60); v64 /= 60; + hour = (unsigned)(v64 % 24); v64 /= 24; + + v = (UInt32)v64; + + year = (unsigned)(1601 + v / PERIOD_400 * 400); + v %= PERIOD_400; + + t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; + t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; + t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 0;; mon++) + { + const UInt32 d = ms[mon]; + if (v < d) + break; + v -= d; + } + s = UIntToStr(s, year, 4); *s++ = '-'; + UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3; + UIntToStr_2(s, (unsigned)v + 1); s[2] = ' '; s += 3; + UIntToStr_2(s, hour); s[2] = ':'; s += 3; + UIntToStr_2(s, min); s[2] = ':'; s += 3; + UIntToStr_2(s, sec); s[2] = 0; +} + +static void PrintLF(void) +{ + Print("\n"); +} + +static void PrintError(char *s) +{ + Print("\nERROR: "); + Print(s); + PrintLF(); +} + +static void PrintError_WRes(const char *message, WRes wres) +{ + Print("\nERROR: "); + Print(message); + PrintLF(); + { + char s[32]; + UIntToStr(s, (unsigned)wres, 1); + Print("System error code: "); + Print(s); + } + // sprintf(buffer + strlen(buffer), "\nSystem error code: %d", (unsigned)wres); + #ifdef _WIN32 + { + char *s = NULL; + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, wres, 0, (LPSTR) &s, 0, NULL) != 0 && s) + { + Print(" : "); + Print(s); + LocalFree(s); + } + } + #else + { + const char *s = strerror(wres); + if (s) + { + Print(" : "); + Print(s); + } + } + #endif + PrintLF(); +} + +static void GetAttribString(UInt32 wa, BoolInt isDir, char *s) +{ + #ifdef USE_WINDOWS_FILE + s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.'); + s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.'); + s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.'); + s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.'); + s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.'); + s[5] = 0; + #else + s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.'); + s[1] = 0; + #endif +} + + +// #define NUM_PARENTS_MAX 128 + +int Z7_CDECL main(int numargs, char *args[]) +{ + ISzAlloc allocImp; + ISzAlloc allocTempImp; + + CFileInStream archiveStream; + CLookToRead2 lookStream; + CSzArEx db; + SRes res; + UInt16 *temp = NULL; + size_t tempSize = 0; + // UInt32 parents[NUM_PARENTS_MAX]; + + Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"); + + if (numargs == 1) + { + Print( + "Usage: 7zDec \n\n" + "\n" + " e: Extract files from archive (without using directory names)\n" + " l: List contents of archive\n" + " t: Test integrity of archive\n" + " x: eXtract files with full paths\n"); + return 0; + } + + if (numargs < 3) + { + PrintError("incorrect command"); + return 1; + } + + #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE) + g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + #endif + + + allocImp = g_Alloc; + allocTempImp = g_Alloc; + // allocTempImp = g_Alloc_temp; + + { + WRes wres = + #ifdef UNDER_CE + InFile_OpenW(&archiveStream.file, L"\test.7z"); // change it + #else + InFile_Open(&archiveStream.file, args[2]); + #endif + if (wres != 0) + { + PrintError_WRes("cannot open input file", wres); + return 1; + } + } + + FileInStream_CreateVTable(&archiveStream); + archiveStream.wres = 0; + LookToRead2_CreateVTable(&lookStream, False); + lookStream.buf = NULL; + + res = SZ_OK; + + { + lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize); + if (!lookStream.buf) + res = SZ_ERROR_MEM; + else + { + lookStream.bufSize = kInputBufSize; + lookStream.realStream = &archiveStream.vt; + LookToRead2_INIT(&lookStream) + } + } + + CrcGenerateTable(); + + SzArEx_Init(&db); + + if (res == SZ_OK) + { + res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp); + } + + if (res == SZ_OK) + { + char *command = args[1]; + int listCommand = 0, testCommand = 0, fullPaths = 0; + + if (strcmp(command, "l") == 0) listCommand = 1; + else if (strcmp(command, "t") == 0) testCommand = 1; + else if (strcmp(command, "e") == 0) { } + else if (strcmp(command, "x") == 0) { fullPaths = 1; } + else + { + PrintError("incorrect command"); + res = SZ_ERROR_FAIL; + } + + if (res == SZ_OK) + { + UInt32 i; + + /* + if you need cache, use these 3 variables. + if you use external function, you can make these variable as static. + */ + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ + Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ + size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ + + for (i = 0; i < db.NumFiles; i++) + { + size_t offset = 0; + size_t outSizeProcessed = 0; + // const CSzFileItem *f = db.Files + i; + size_t len; + const BoolInt isDir = SzArEx_IsDir(&db, i); + if (listCommand == 0 && isDir && !fullPaths) + continue; + len = SzArEx_GetFileNameUtf16(&db, i, NULL); + // len = SzArEx_GetFullNameLen(&db, i); + + if (len > tempSize) + { + SzFree(NULL, temp); + tempSize = len; + temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); + if (!temp) + { + res = SZ_ERROR_MEM; + break; + } + } + + SzArEx_GetFileNameUtf16(&db, i, temp); + /* + if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp) + { + res = SZ_ERROR_FAIL; + break; + } + */ + + if (listCommand) + { + char attr[8], s[32], t[32]; + UInt64 fileSize; + + GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); + + fileSize = SzArEx_GetFileSize(&db, i); + UInt64ToStr(fileSize, s, 10); + + if (SzBitWithVals_Check(&db.MTime, i)) + ConvertFileTimeToString(&db.MTime.Vals[i], t); + else + { + size_t j; + for (j = 0; j < 19; j++) + t[j] = ' '; + t[j] = '\0'; + } + + Print(t); + Print(" "); + Print(attr); + Print(" "); + Print(s); + Print(" "); + res = PrintString(temp); + if (res != SZ_OK) + break; + if (isDir) + Print("/"); + PrintLF(); + continue; + } + + Print(testCommand ? + "T ": + "- "); + res = PrintString(temp); + if (res != SZ_OK) + break; + + if (isDir) + Print("/"); + else + { + res = SzArEx_Extract(&db, &lookStream.vt, i, + &blockIndex, &outBuffer, &outBufferSize, + &offset, &outSizeProcessed, + &allocImp, &allocTempImp); + if (res != SZ_OK) + break; + } + + if (!testCommand) + { + CSzFile outFile; + size_t processedSize; + size_t j; + UInt16 *name = (UInt16 *)temp; + const UInt16 *destPath = (const UInt16 *)name; + + for (j = 0; name[j] != 0; j++) + if (name[j] == '/') + { + if (fullPaths) + { + name[j] = 0; + MyCreateDir(name); + name[j] = CHAR_PATH_SEPARATOR; + } + else + destPath = name + j + 1; + } + + if (isDir) + { + MyCreateDir(destPath); + PrintLF(); + continue; + } + else + { + const WRes wres = OutFile_OpenUtf16(&outFile, destPath); + if (wres != 0) + { + PrintError_WRes("cannot open output file", wres); + res = SZ_ERROR_FAIL; + break; + } + } + + processedSize = outSizeProcessed; + + { + const WRes wres = File_Write(&outFile, outBuffer + offset, &processedSize); + if (wres != 0 || processedSize != outSizeProcessed) + { + PrintError_WRes("cannot write output file", wres); + res = SZ_ERROR_FAIL; + break; + } + } + + { + FILETIME mtime; + FILETIME *mtimePtr = NULL; + + #ifdef USE_WINDOWS_FILE + FILETIME ctime; + FILETIME *ctimePtr = NULL; + #endif + + if (SzBitWithVals_Check(&db.MTime, i)) + { + const CNtfsFileTime *t = &db.MTime.Vals[i]; + mtime.dwLowDateTime = (DWORD)(t->Low); + mtime.dwHighDateTime = (DWORD)(t->High); + mtimePtr = &mtime; + } + + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.CTime, i)) + { + const CNtfsFileTime *t = &db.CTime.Vals[i]; + ctime.dwLowDateTime = (DWORD)(t->Low); + ctime.dwHighDateTime = (DWORD)(t->High); + ctimePtr = &ctime; + } + + if (mtimePtr || ctimePtr) + SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr); + #endif + + { + const WRes wres = File_Close(&outFile); + if (wres != 0) + { + PrintError_WRes("cannot close output file", wres); + res = SZ_ERROR_FAIL; + break; + } + } + + #ifndef USE_WINDOWS_FILE + #ifdef _WIN32 + mtimePtr = mtimePtr; + #else + if (mtimePtr) + Set_File_FILETIME(destPath, mtimePtr); + #endif + #endif + } + + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.Attribs, i)) + { + UInt32 attrib = db.Attribs.Vals[i]; + /* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker. + We remove posix bits, if we detect posix mode field */ + if ((attrib & 0xF0000000) != 0) + attrib &= 0x7FFF; + SetFileAttributesW((LPCWSTR)destPath, attrib); + } + #endif + } + PrintLF(); + } + ISzAlloc_Free(&allocImp, outBuffer); + } + } + + SzFree(NULL, temp); + SzArEx_Free(&db, &allocImp); + ISzAlloc_Free(&allocImp, lookStream.buf); + + File_Close(&archiveStream.file); + + if (res == SZ_OK) + { + Print("\nEverything is Ok\n"); + return 0; + } + + if (res == SZ_ERROR_UNSUPPORTED) + PrintError("decoder doesn't support this archive"); + else if (res == SZ_ERROR_MEM) + PrintError("cannot allocate memory"); + else if (res == SZ_ERROR_CRC) + PrintError("CRC error"); + else if (res == SZ_ERROR_READ /* || archiveStream.Res != 0 */) + PrintError_WRes("Read Error", archiveStream.wres); + else + { + char s[32]; + UInt64ToStr((unsigned)res, s, 0); + PrintError(s); + } + + return 1; +} diff -Nru p7zip-rar-16.02/C/Util/7z/Precomp.c p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.c --- p7zip-rar-16.02/C/Util/7z/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.c 2013-01-23 18:00:00.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru p7zip-rar-16.02/C/Util/7z/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.h --- p7zip-rar-16.02/C/Util/7z/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/7z/makefile p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile --- p7zip-rar-16.02/C/Util/7z/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile 2024-03-21 09:00:00.000000000 +0000 @@ -0,0 +1,44 @@ +CFLAGS = $(CFLAGS) -DZ7_PPMD_SUPPORT -DZ7_EXTRACT_ONLY + +PROG = 7zDec.exe + +C_OBJS = \ + $O\7zAlloc.obj \ + $O\7zBuf.obj \ + $O\7zFile.obj \ + $O\7zDec.obj \ + $O\7zArcIn.obj \ + $O\7zStream.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\Lzma2Dec.obj \ + $O\LzmaDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + +7Z_OBJS = \ + $O\7zMain.obj \ + +!include "../../../CPP/7zip/Crc.mak" +!include "../../../CPP/7zip/LzmaDec.mak" + +OBJS = \ + $O\Precomp.obj \ + $(7Z_OBJS) \ + $(C_OBJS) \ + $(ASM_OBJS) \ + +!include "../../../CPP/Build.mak" + +$(7Z_OBJS): $(*B).c + $(CCOMPL_USE) +$(C_OBJS): ../../$(*B).c + $(CCOMPL_USE) +$O\Precomp.obj: Precomp.c + $(CCOMPL_PCH) + +!include "../../Asm_c.mak" diff -Nru p7zip-rar-16.02/C/Util/7z/makefile.gcc p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile.gcc --- p7zip-rar-16.02/C/Util/7z/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7z/makefile.gcc 2023-03-02 16:00:00.000000000 +0000 @@ -0,0 +1,32 @@ +PROG = 7zdec + +LOCAL_FLAGS = -DZ7_PPMD_SUPPORT -DZ7_EXTRACT_ONLY + +include ../../../CPP/7zip/LzmaDec_gcc.mak + + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $O/Bcj2.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/Lzma2Dec.o \ + $O/LzmaDec.o \ + $O/Ppmd7.o \ + $O/Ppmd7Dec.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/7zAlloc.o \ + $O/7zArcIn.o \ + $O/7zBuf.o \ + $O/7zBuf2.o \ + $O/7zDec.o \ + $O/7zMain.o \ + $O/7zFile.o \ + $O/7zStream.o \ + + +include ../../7zip_gcc_c.mak Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/C/Util/7zipInstall/7zip.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zip.ico differ diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.c p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.c --- p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.c 2024-04-05 03:00:00.000000000 +0000 @@ -0,0 +1,1699 @@ +/* 7zipInstall.c - 7-Zip Installer +2024-04-05 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#define SZ_ERROR_ABORT 100 + +#include "../../7zWindows.h" + +#if defined(_MSC_VER) && _MSC_VER < 1600 +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#endif + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +#ifdef Z7_OLD_WIN_SDK +struct IShellView; +#define SHFOLDERAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE +SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +typedef enum { + SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists + SHGFP_TYPE_DEFAULT = 1, // default value, may not exist +} SHGFP_TYPE; +#endif +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../7z.h" +#include "../../7zAlloc.h" +#include "../../7zCrc.h" +#include "../../7zFile.h" +#include "../../7zVersion.h" +#include "../../CpuArch.h" +#include "../../DllSecur.h" + +#include "resource.h" + +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +#define LLL_(quote) L##quote +#define LLL(quote) LLL_(quote) + +#define wcscat lstrcatW +#define wcslen (size_t)lstrlenW +#define wcscpy lstrcpyW +// wcsncpy() and lstrcpynW() work differently. We don't use them. + +#define kInputBufSize ((size_t)1 << 18) + +#define Z7_7ZIP_CUR_VER ((MY_VER_MAJOR << 16) | MY_VER_MINOR) +#define Z7_7ZIP_DLL_VER_COMPAT ((16 << 16) | 3) + +static LPCSTR const k_7zip = "7-Zip"; + +static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip"; + +// #define Z7_64BIT_INSTALLER 1 + +#ifdef _WIN64 + #define Z7_64BIT_INSTALLER 1 +#endif + +#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION) + +#ifdef Z7_64BIT_INSTALLER + + // #define USE_7ZIP_32_DLL + + #if defined(_M_ARM64) || defined(_M_ARM) + #define k_Postfix L" (arm64)" + #else + #define k_Postfix L" (x64)" + #define USE_7ZIP_32_DLL + #endif +#else + #if defined(_M_ARM64) || defined(_M_ARM) + #define k_Postfix L" (arm)" + #else + // #define k_Postfix L" (x86)" + #define k_Postfix + #endif +#endif + +#define k_7zip_with_Ver k_7zip_with_Ver_base k_Postfix + + +static LPCWSTR const k_7zip_with_Ver_str = k_7zip_with_Ver; + +static LPCWSTR const k_7zip_Setup = k_7zip_with_Ver L" Setup"; + +static LPCWSTR const k_Reg_Path = L"Path"; + +static LPCWSTR const k_Reg_Path32 = L"Path" + #ifdef Z7_64BIT_INSTALLER + L"64" + #else + L"32" + #endif + ; + +#if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) + #define k_Reg_WOW_Flag KEY_WOW64_64KEY +#else + #define k_Reg_WOW_Flag 0 +#endif + +#ifdef USE_7ZIP_32_DLL +#ifdef _WIN64 + #define k_Reg_WOW_Flag_32 KEY_WOW64_32KEY +#else + #define k_Reg_WOW_Flag_32 0 +#endif +#endif + +#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}" + +static LPCWSTR const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID; +static LPCWSTR const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32"; + +#define g_AllUsers True + +static BoolInt g_Install_was_Pressed; +static BoolInt g_Finished; +static BoolInt g_SilentMode; + +static HWND g_HWND; +static HWND g_Path_HWND; +static HWND g_InfoLine_HWND; +static HWND g_Progress_HWND; + +static DWORD g_TotalSize; + +static WCHAR cmd[MAX_PATH + 4]; +static WCHAR cmdError[MAX_PATH + 4]; +static WCHAR path[MAX_PATH * 2 + 40]; + + + +static void CpyAscii(wchar_t *dest, const char *s) +{ + for (;;) + { + Byte b = (Byte)*s++; + *dest++ = b; + if (b == 0) + return; + } +} + +static void CatAscii(wchar_t *dest, const char *s) +{ + dest += wcslen(dest); + CpyAscii(dest, s); +} + +static void PrintErrorMessage(const char *s1, const wchar_t *s2) +{ + WCHAR m[MAX_PATH + 512]; + m[0] = 0; + CatAscii(m, "ERROR:"); + if (s1) + { + CatAscii(m, "\n"); + CatAscii(m, s1); + } + if (s2) + { + CatAscii(m, "\n"); + wcscat(m, s2); + } + MessageBoxW(g_HWND, m, k_7zip_with_Ver_str, MB_ICONERROR | MB_OK); +} + + +typedef DWORD (WINAPI * Func_GetFileVersionInfoSizeW)(LPCWSTR lptstrFilename, LPDWORD lpdwHandle); +typedef BOOL (WINAPI * Func_GetFileVersionInfoW)(LPCWSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData); +typedef BOOL (WINAPI * Func_VerQueryValueW)(const LPVOID pBlock, LPWSTR lpSubBlock, LPVOID * lplpBuffer, PUINT puLen); + +static HMODULE g_version_dll_hModule; + +static DWORD GetFileVersion(LPCWSTR s) +{ + DWORD size = 0; + void *vi = NULL; + DWORD version = 0; + + Func_GetFileVersionInfoSizeW my_GetFileVersionInfoSizeW; + Func_GetFileVersionInfoW my_GetFileVersionInfoW; + Func_VerQueryValueW my_VerQueryValueW; + + if (!g_version_dll_hModule) + { + wchar_t buf[MAX_PATH + 100]; + { + unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2); + if (len == 0 || len > MAX_PATH) + return 0; + } + { + unsigned pos = (unsigned)lstrlenW(buf); + if (buf[pos - 1] != '\\') + buf[pos++] = '\\'; + lstrcpyW(buf + pos, L"version.dll"); + } + g_version_dll_hModule = LoadLibraryW(buf); + if (!g_version_dll_hModule) + return 0; + } + + my_GetFileVersionInfoSizeW = (Func_GetFileVersionInfoSizeW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "GetFileVersionInfoSizeW"); + my_GetFileVersionInfoW = (Func_GetFileVersionInfoW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "GetFileVersionInfoW"); + my_VerQueryValueW = (Func_VerQueryValueW) Z7_CAST_FUNC_C GetProcAddress(g_version_dll_hModule, + "VerQueryValueW"); + + if (!my_GetFileVersionInfoSizeW + || !my_GetFileVersionInfoW + || !my_VerQueryValueW) + return 0; + + size = my_GetFileVersionInfoSizeW(s, NULL); + if (size == 0) + return 0; + + vi = malloc(size); + if (!vi) + return 0; + + if (my_GetFileVersionInfoW(s, 0, size, vi)) + { + VS_FIXEDFILEINFO *fi = NULL; + UINT fiLen = 0; + if (my_VerQueryValueW(vi, L"\\", (LPVOID *)&fi, &fiLen)) + version = fi->dwFileVersionMS; + } + + free(vi); + return version; +} + + +static WRes MyCreateDir(LPCWSTR name) +{ + return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); +} + +#define IS_SEPAR(c) (c == WCHAR_PATH_SEPARATOR) +#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) +#define IS_DRIVE_PATH(s) (IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2])) + +static int ReverseFind_PathSepar(const wchar_t *s) +{ + int separ = -1; + int i; + for (i = 0;; i++) + { + wchar_t c = s[i]; + if (c == 0) + return separ; + if (IS_SEPAR(c)) + separ = i; + } +} + +static WRes CreateComplexDir(void) +{ + WCHAR s[MAX_PATH + 10]; + + unsigned prefixSize = 0; + WRes wres; + + { + size_t len = wcslen(path); + if (len > MAX_PATH) + return ERROR_INVALID_NAME; + wcscpy(s, path); + } + + if (IS_DRIVE_PATH(s)) + prefixSize = 3; + else if (IS_SEPAR(s[0]) && IS_SEPAR(s[1])) + prefixSize = 2; + else + return ERROR_INVALID_NAME; + + { + DWORD attrib = GetFileAttributesW(s); + if (attrib != INVALID_FILE_ATTRIBUTES) + return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ? 0 : ERROR_ALREADY_EXISTS; + } + + wres = MyCreateDir(s); + if (wres == 0 || wres == ERROR_ALREADY_EXISTS) + return 0; + + { + size_t len = wcslen(s); + { + const int pos = ReverseFind_PathSepar(s); + if (pos < 0) + return wres; + if ((unsigned)pos < prefixSize) + return wres; + if ((unsigned)pos == len - 1) + { + if (len == 1) + return 0; + s[pos] = 0; + len = (unsigned)pos; + } + } + + for (;;) + { + int pos; + wres = MyCreateDir(s); + if (wres == 0) + break; + if (wres == ERROR_ALREADY_EXISTS) + { + const DWORD attrib = GetFileAttributesW(s); + if (attrib != INVALID_FILE_ATTRIBUTES) + if ((attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) + return ERROR_ALREADY_EXISTS; + break; + } + pos = ReverseFind_PathSepar(s); + if (pos < 0 || pos == 0 || (unsigned)pos < prefixSize) + return wres; + s[pos] = 0; + } + + for (;;) + { + const size_t pos = wcslen(s); + if (pos >= len) + return 0; + s[pos] = CHAR_PATH_SEPARATOR; + wres = MyCreateDir(s); + if (wres != 0) + return wres; + } + } +} + + +static int MyRegistry_QueryString(HKEY hKey, LPCWSTR name, LPWSTR dest) +{ + DWORD cnt = MAX_PATH * sizeof(name[0]); + DWORD type = 0; + const LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, &cnt); + if (type != REG_SZ) + return False; + return res == ERROR_SUCCESS; +} + +static int MyRegistry_QueryString2(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) +{ + HKEY key = 0; + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); + if (res != ERROR_SUCCESS) + return False; + { + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + RegCloseKey(key); + return res2; + } +} + +static LONG MyRegistry_SetString(HKEY hKey, LPCWSTR name, LPCWSTR val) +{ + return RegSetValueExW(hKey, name, 0, REG_SZ, + (const BYTE *)val, (DWORD)(wcslen(val) + 1) * sizeof(val[0])); +} + +static LONG MyRegistry_SetDWORD(HKEY hKey, LPCWSTR name, DWORD val) +{ + return RegSetValueExW(hKey, name, 0, REG_DWORD, (const BYTE *)&val, sizeof(DWORD)); +} + + +static LONG MyRegistry_CreateKey(HKEY parentKey, LPCWSTR name, HKEY *destKey) +{ + return RegCreateKeyExW(parentKey, name, 0, NULL, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS | k_Reg_WOW_Flag, + NULL, destKey, NULL); +} + +static LONG MyRegistry_CreateKeyAndVal(HKEY parentKey, LPCWSTR keyName, LPCWSTR valName, LPCWSTR val) +{ + HKEY destKey = 0; + LONG res = MyRegistry_CreateKey(parentKey, keyName, &destKey); + if (res == ERROR_SUCCESS) + { + res = MyRegistry_SetString(destKey, valName, val); + /* res = */ RegCloseKey(destKey); + } + return res; +} + + +#ifdef USE_7ZIP_32_DLL + +static LONG MyRegistry_CreateKey_32(HKEY parentKey, LPCWSTR name, HKEY *destKey) +{ + return RegCreateKeyExW(parentKey, name, 0, NULL, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS | k_Reg_WOW_Flag_32, + NULL, destKey, NULL); +} + +static LONG MyRegistry_CreateKeyAndVal_32(HKEY parentKey, LPCWSTR keyName, LPCWSTR valName, LPCWSTR val) +{ + HKEY destKey = 0; + LONG res = MyRegistry_CreateKey_32(parentKey, keyName, &destKey); + if (res == ERROR_SUCCESS) + { + res = MyRegistry_SetString(destKey, valName, val); + /* res = */ RegCloseKey(destKey); + } + return res; +} + +#endif + + + +#ifdef UNDER_CE + #define kBufSize (1 << 13) +#else + #define kBufSize (1 << 15) +#endif + +#define kSignatureSearchLimit (1 << 22) + +static BoolInt FindSignature(CSzFile *stream, UInt64 *resPos) +{ + Byte buf[kBufSize]; + size_t numPrevBytes = 0; + *resPos = 0; + + for (;;) + { + size_t processed, pos; + if (*resPos > kSignatureSearchLimit) + return False; + processed = kBufSize - numPrevBytes; + if (File_Read(stream, buf + numPrevBytes, &processed) != 0) + return False; + processed += numPrevBytes; + if (processed < k7zStartHeaderSize || + (processed == k7zStartHeaderSize && numPrevBytes != 0)) + return False; + processed -= k7zStartHeaderSize; + for (pos = 0; pos <= processed; pos++) + { + for (; pos <= processed && buf[pos] != '7'; pos++); + if (pos > processed) + break; + if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) + if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8)) + { + *resPos += pos; + return True; + } + } + *resPos += processed; + numPrevBytes = k7zStartHeaderSize; + memmove(buf, buf + processed, k7zStartHeaderSize); + } +} + +static void HexToString(UInt32 val, WCHAR *s) +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; + do + { + unsigned t = (unsigned)((val & 0xF)); + val >>= 4; + s[--i] = (WCHAR)(unsigned)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + while (i); +} + + +#ifndef UNDER_CE + +static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM data) +{ + UNUSED_VAR(lp) + UNUSED_VAR(data) + UNUSED_VAR(hwnd) + + switch (uMsg) + { + case BFFM_INITIALIZED: + { + SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, data); + break; + } + case BFFM_SELCHANGED: + { + // show selected path for BIF_STATUSTEXT + WCHAR dir[MAX_PATH]; + if (!SHGetPathFromIDListW((LPITEMIDLIST)lp, dir)) + dir[0] = 0; + SendMessage(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir); + break; + } + default: + break; + } + return 0; +} + +static BoolInt MyBrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags, + LPCWSTR initialFolder, LPWSTR resultPath) +{ + WCHAR displayName[MAX_PATH]; + BROWSEINFOW browseInfo; + + displayName[0] = 0; + browseInfo.hwndOwner = owner; + browseInfo.pidlRoot = NULL; + + // there are Unicode/Astring problems in some WinCE SDK ? + browseInfo.pszDisplayName = displayName; + browseInfo.lpszTitle = title; + browseInfo.ulFlags = ulFlags; + browseInfo.lpfn = (initialFolder != NULL) ? BrowseCallbackProc : NULL; + browseInfo.lParam = (LPARAM)initialFolder; + { + LPITEMIDLIST idlist = SHBrowseForFolderW(&browseInfo); + if (idlist) + { + SHGetPathFromIDListW(idlist, resultPath); + // free idlist + // CoTaskMemFree(idlist); + return True; + } + return False; + } +} + +#endif + +static void NormalizePrefix(WCHAR *s) +{ + size_t i = 0; + + for (;; i++) + { + const wchar_t c = s[i]; + if (c == 0) + break; + if (c == '/') + s[i] = WCHAR_PATH_SEPARATOR; + } + + if (i != 0 && s[i - 1] != WCHAR_PATH_SEPARATOR) + { + s[i] = WCHAR_PATH_SEPARATOR; + s[i + 1] = 0; + } +} + +static char MyCharLower_Ascii(char c) +{ + if (c >= 'A' && c <= 'Z') + return (char)((unsigned char)c + 0x20); + return c; +} + +static wchar_t MyWCharLower_Ascii(wchar_t c) +{ + if (c >= 'A' && c <= 'Z') + return (wchar_t)(c + 0x20); + return c; +} + +static LPCWSTR FindSubString(LPCWSTR s1, const char *s2) +{ + for (;;) + { + unsigned i; + if (*s1 == 0) + return NULL; + for (i = 0;; i++) + { + const char b = s2[i]; + if (b == 0) + return s1; + if (MyWCharLower_Ascii(s1[i]) != (Byte)MyCharLower_Ascii(b)) + { + s1++; + break; + } + } + } +} + +static void Set7zipPostfix(WCHAR *s) +{ + NormalizePrefix(s); + if (FindSubString(s, "7-Zip")) + return; + CatAscii(s, "7-Zip\\"); +} + + +static int Install(void); + +static void OnClose(void) +{ + if (g_Install_was_Pressed && !g_Finished) + { + if (MessageBoxW(g_HWND, + L"Do you want to cancel " k_7zip_with_Ver L" installation?", + k_7zip_with_Ver, + MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES) + return; + } + DestroyWindow(g_HWND); + g_HWND = NULL; +} + +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + // UNUSED_VAR(hwnd) + UNUSED_VAR(lParam) + + switch (message) + { + case WM_INITDIALOG: + g_Path_HWND = GetDlgItem(hwnd, IDE_EXTRACT_PATH); + g_InfoLine_HWND = GetDlgItem(hwnd, IDT_CUR_FILE); + g_Progress_HWND = GetDlgItem(hwnd, IDC_PROGRESS); + + SetWindowTextW(hwnd, k_7zip_Setup); + SetDlgItemTextW(hwnd, IDE_EXTRACT_PATH, path); + + ShowWindow(g_Progress_HWND, SW_HIDE); + ShowWindow(g_InfoLine_HWND, SW_HIDE); + + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + if (g_Finished) + { + OnClose(); + break; + } + if (!g_Install_was_Pressed) + { + SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)(void *)GetDlgItem(hwnd, IDCANCEL), TRUE); + + EnableWindow(g_Path_HWND, FALSE); + EnableWindow(GetDlgItem(hwnd, IDB_EXTRACT_SET_PATH), FALSE); + EnableWindow(GetDlgItem(hwnd, IDOK), FALSE); + + g_Install_was_Pressed = True; + return TRUE; + } + break; + } + + case IDCANCEL: + { + OnClose(); + break; + } + + case IDB_EXTRACT_SET_PATH: + { + #ifndef UNDER_CE + + WCHAR s[MAX_PATH]; + WCHAR s2[MAX_PATH]; + GetDlgItemTextW(hwnd, IDE_EXTRACT_PATH, s, MAX_PATH); + if (MyBrowseForFolder(hwnd, L"Select the folder for installation:" , + 0 + | BIF_NEWDIALOGSTYLE // 5.0 of ?.dll ? + | BIF_RETURNONLYFSDIRS + // | BIF_STATUSTEXT // doesn't work for BIF_NEWDIALOGSTYLE + , s, s2)) + { + Set7zipPostfix(s2); + SetDlgItemTextW(hwnd, IDE_EXTRACT_PATH, s2); + } + + #endif + break; + } + + default: return FALSE; + } + break; + + case WM_CLOSE: + OnClose(); + break; + /* + case WM_DESTROY: + PostQuitMessage(0); + return TRUE; + */ + default: + return FALSE; + } + + return TRUE; +} + + + +static LONG SetRegKey_Path2(HKEY parentKey) +{ + HKEY destKey = 0; + LONG res = MyRegistry_CreateKey(parentKey, k_Reg_Software_7zip, &destKey); + if (res == ERROR_SUCCESS) + { + res = MyRegistry_SetString(destKey, k_Reg_Path32, path); + /* res = */ MyRegistry_SetString(destKey, k_Reg_Path, path); + /* res = */ RegCloseKey(destKey); + } + return res; +} + +static void SetRegKey_Path(void) +{ + SetRegKey_Path2(HKEY_CURRENT_USER); + SetRegKey_Path2(HKEY_LOCAL_MACHINE); +} + + +static HRESULT CreateShellLink(LPCWSTR srcPath, LPCWSTR targetPath) +{ + IShellLinkW* sl; + + // CoInitialize has already been called. + HRESULT hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&sl); + + if (SUCCEEDED(hres)) + { + IPersistFile* pf; + + sl->lpVtbl->SetPath(sl, targetPath); + // sl->lpVtbl->SetDescription(sl, description); + hres = sl->lpVtbl->QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf); + + if (SUCCEEDED(hres)) + { + hres = pf->lpVtbl->Save(pf, srcPath, TRUE); + pf->lpVtbl->Release(pf); + } + sl->lpVtbl->Release(sl); + } + + return hres; +} + +static void SetShellProgramsGroup(HWND hwndOwner) +{ + #ifdef UNDER_CE + + // CpyAscii(link, "\\Program Files\\"); + UNUSED_VAR(hwndOwner) + + #else + + unsigned i = (g_AllUsers ? 0 : 2); + + for (; i < 3; i++) + { + BoolInt isOK = True; + WCHAR link[MAX_PATH + 40]; + WCHAR destPath[MAX_PATH + 40]; + + link[0] = 0; + + if (SHGetFolderPathW(hwndOwner, + i == 1 ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, + NULL, SHGFP_TYPE_CURRENT, link) != S_OK) + continue; + + NormalizePrefix(link); + CatAscii(link, k_7zip); + // CatAscii(link, "2"); + + if (i != 0) + MyCreateDir(link); + + NormalizePrefix(link); + + { + unsigned baseLen = (unsigned)wcslen(link); + unsigned k; + + for (k = 0; k < 2; k++) + { + CpyAscii(link + baseLen, k == 0 ? + "7-Zip File Manager.lnk" : + "7-Zip Help.lnk" + ); + wcscpy(destPath, path); + CatAscii(destPath, k == 0 ? + "7zFM.exe" : + "7-zip.chm"); + + if (i == 0) + DeleteFileW(link); + else if (CreateShellLink(link, destPath) != S_OK) + isOK = False; + } + } + + if (i != 0 && isOK) + break; + } + + #endif +} + +static LPCWSTR const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; +static LPCWSTR const k_7zip_ShellExtension = L"7-Zip Shell Extension"; + +static void WriteCLSID(void) +{ + HKEY destKey; + LONG res; + + #ifdef USE_7ZIP_32_DLL + + MyRegistry_CreateKeyAndVal_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip, NULL, k_7zip_ShellExtension); + + res = MyRegistry_CreateKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc, &destKey); + + if (res == ERROR_SUCCESS) + { + WCHAR destPath[MAX_PATH + 40]; + wcscpy(destPath, path); + CatAscii(destPath, "7-zip32.dll"); + /* res = */ MyRegistry_SetString(destKey, NULL, destPath); + /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); + // DeleteRegValue(destKey, L"InprocServer32"); + /* res = */ RegCloseKey(destKey); + } + + #endif + + + MyRegistry_CreateKeyAndVal(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip, NULL, k_7zip_ShellExtension); + + destKey = 0; + res = MyRegistry_CreateKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc, &destKey); + + if (res == ERROR_SUCCESS) + { + WCHAR destPath[MAX_PATH + 40]; + wcscpy(destPath, path); + CatAscii(destPath, "7-zip.dll"); + /* res = */ MyRegistry_SetString(destKey, NULL, destPath); + /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); + // DeleteRegValue(destKey, L"InprocServer32"); + /* res = */ RegCloseKey(destKey); + } +} + +static LPCSTR const k_ShellEx_Items[] = +{ + "*\\shellex\\ContextMenuHandlers" + , "Directory\\shellex\\ContextMenuHandlers" + , "Folder\\shellex\\ContextMenuHandlers" + , "Directory\\shellex\\DragDropHandlers" + , "Drive\\shellex\\DragDropHandlers" +}; + +static void WriteShellEx(void) +{ + unsigned i; + WCHAR destPath[MAX_PATH + 40]; + + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) + { + CpyAscii(destPath, k_ShellEx_Items[i]); + CatAscii(destPath, "\\7-Zip"); + + #ifdef USE_7ZIP_32_DLL + MyRegistry_CreateKeyAndVal_32(HKEY_CLASSES_ROOT, destPath, NULL, k_7zip_CLSID); + #endif + MyRegistry_CreateKeyAndVal (HKEY_CLASSES_ROOT, destPath, NULL, k_7zip_CLSID); + } + + #ifdef USE_7ZIP_32_DLL + MyRegistry_CreateKeyAndVal_32(HKEY_LOCAL_MACHINE, k_Shell_Approved, k_7zip_CLSID, k_7zip_ShellExtension); + #endif + MyRegistry_CreateKeyAndVal (HKEY_LOCAL_MACHINE, k_Shell_Approved, k_7zip_CLSID, k_7zip_ShellExtension); + + + wcscpy(destPath, path); + CatAscii(destPath, "7zFM.exe"); + + { + HKEY destKey = 0; + LONG res = MyRegistry_CreateKey(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe", &destKey); + if (res == ERROR_SUCCESS) + { + MyRegistry_SetString(destKey, NULL, destPath); + MyRegistry_SetString(destKey, L"Path", path); + RegCloseKey(destKey); + } + + } + + { + HKEY destKey = 0; + LONG res = MyRegistry_CreateKey(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\7-Zip", &destKey); + if (res == ERROR_SUCCESS) + { + MyRegistry_SetString(destKey, L"DisplayName", k_7zip_with_Ver_str); + MyRegistry_SetString(destKey, L"DisplayVersion", LLL(MY_VERSION_NUMBERS)); + MyRegistry_SetString(destKey, L"DisplayIcon", destPath); + MyRegistry_SetString(destKey, L"InstallLocation", path); + + destPath[0] = '\"'; + wcscpy(destPath + 1, path); + CatAscii(destPath, "Uninstall.exe\""); + MyRegistry_SetString(destKey, L"UninstallString", destPath); + + CatAscii(destPath, " /S"); + MyRegistry_SetString(destKey, L"QuietUninstallString", destPath); + + MyRegistry_SetDWORD(destKey, L"NoModify", 1); + MyRegistry_SetDWORD(destKey, L"NoRepair", 1); + + MyRegistry_SetDWORD(destKey, L"EstimatedSize", g_TotalSize >> 10); + + MyRegistry_SetDWORD(destKey, L"VersionMajor", MY_VER_MAJOR); + MyRegistry_SetDWORD(destKey, L"VersionMinor", MY_VER_MINOR); + + MyRegistry_SetString(destKey, L"Publisher", LLL(MY_AUTHOR_NAME)); + + // MyRegistry_SetString(destKey, L"HelpLink", L"http://www.7-zip.org/support.html"); + // MyRegistry_SetString(destKey, L"URLInfoAbout", L"http://www.7-zip.org/"); + // MyRegistry_SetString(destKey, L"URLUpdateInfo", L"http://www.7-zip.org/"); + + RegCloseKey(destKey); + } + } +} + + +static const wchar_t *GetCmdParam(const wchar_t *s) +{ + unsigned pos = 0; + BoolInt quoteMode = False; + for (;; s++) + { + wchar_t c = *s; + if (c == 0 || (c == L' ' && !quoteMode)) + break; + if (c == L'\"') + { + quoteMode = !quoteMode; + continue; + } + if (pos >= Z7_ARRAY_SIZE(cmd) - 1) + exit(1); + cmd[pos++] = c; + } + cmd[pos] = 0; + return s; +} + + +static void RemoveQuotes(wchar_t *s) +{ + const wchar_t *src = s; + for (;;) + { + wchar_t c = *src++; + if (c == '\"') + continue; + *s++ = c; + if (c == 0) + return; + } +} + +// #define IS_LIMIT_CHAR(c) (c == 0 || c == ' ') + + +typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL); + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + lpCmdLine, int nCmdShow) +{ + + UNUSED_VAR(hPrevInstance) + UNUSED_VAR(lpCmdLine) + UNUSED_VAR(nCmdShow) + + #ifndef UNDER_CE + LoadSecurityDlls(); + CoInitialize(NULL); + #endif + + CrcGenerateTable(); + + { + const wchar_t *s = GetCommandLineW(); + + #ifndef UNDER_CE + s = GetCmdParam(s); + #endif + + for (;;) + { + { + const wchar_t c = *s; + if (c == 0) + break; + if (c == ' ') + { + s++; + continue; + } + } + + { + const wchar_t *s2 = GetCmdParam(s); + BoolInt error = True; + if (cmd[0] == '/') + { + if (cmd[1] == 'S') + { + if (cmd[2] == 0) + { + g_SilentMode = True; + error = False; + } + } + else if (cmd[1] == 'D' && cmd[2] == '=') + { + wcscpy(path, cmd + 3); + // RemoveQuotes(path); + error = False; + } + } + s = s2; + if (error && cmdError[0] == 0) + wcscpy(cmdError, cmd); + } + } + + if (cmdError[0] != 0) + { + if (!g_SilentMode) + PrintErrorMessage("Unsupported command:", cmdError); + return 1; + } + } + + #if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) + { + BOOL isWow64 = FALSE; + const Func_IsWow64Process func_IsWow64Process = (Func_IsWow64Process) + Z7_CAST_FUNC_C GetProcAddress(GetModuleHandleW(L"kernel32.dll"), + "IsWow64Process"); + + if (func_IsWow64Process) + func_IsWow64Process(GetCurrentProcess(), &isWow64); + + if (!isWow64) + { + if (!g_SilentMode) + PrintErrorMessage("This installation requires Windows " + #ifdef MY_CPU_X86_OR_AMD64 + "x64" + #else + "64-bit" + #endif + , NULL); + return 1; + } + } + #endif + + + if (path[0] == 0) + { + HKEY key = 0; + BoolInt ok = False; + const LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, k_Reg_Software_7zip, 0, KEY_READ | k_Reg_WOW_Flag, &key); + if (res == ERROR_SUCCESS) + { + ok = MyRegistry_QueryString(key, k_Reg_Path32, path); + // ok = MyRegistry_QueryString(key, k_Reg_Path, path); + RegCloseKey(key); + } + + // ok = False; + if (!ok) + { + /* + #ifdef UNDER_CE + CpyAscii(path, "\\Program Files\\"); + #else + + #ifdef Z7_64BIT_INSTALLER + { + DWORD ttt = GetEnvironmentVariableW(L"ProgramW6432", path, MAX_PATH); + if (ttt == 0 || ttt > MAX_PATH) + CpyAscii(path, "C:\\"); + } + #else + if (!SHGetSpecialFolderPathW(0, path, CSIDL_PROGRAM_FILES, FALSE)) + CpyAscii(path, "C:\\"); + #endif + #endif + */ + if (!MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", L"ProgramFilesDir", path)) + CpyAscii(path, + #ifdef UNDER_CE + "\\Program Files\\" + #else + "C:\\" + #endif + ); + + Set7zipPostfix(path); + } + } + + NormalizePrefix(path); + + if (g_SilentMode) + return Install(); + + { + int retCode = 1; + // INT_PTR res = DialogBox( + g_HWND = CreateDialog( + hInstance, + // GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_INSTALL), NULL, MyDlgProc); + if (!g_HWND) + return 1; + + { + const HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); + // SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); + SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); + } + + + { + BOOL bRet; + MSG msg; + + // we need messages for all thread windows (including EDITTEXT window in dialog) + while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) + { + if (bRet == -1) + return retCode; + if (!g_HWND) + return retCode; + + if (!IsDialogMessage(g_HWND, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (!g_HWND) + return retCode; + + if (g_Install_was_Pressed && !g_Finished) + { + retCode = Install(); + g_Finished = True; + if (retCode != 0) + break; + if (!g_HWND) + break; + { + SetDlgItemTextW(g_HWND, IDOK, L"Close"); + EnableWindow(GetDlgItem(g_HWND, IDOK), TRUE); + EnableWindow(GetDlgItem(g_HWND, IDCANCEL), FALSE); + SendMessage(g_HWND, WM_NEXTDLGCTL, (WPARAM)(void *)GetDlgItem(g_HWND, IDOK), TRUE); + } + } + } + + if (g_HWND) + { + DestroyWindow(g_HWND); + g_HWND = NULL; + } + } + + return retCode; + } +} + + +static BoolInt GetErrorMessage(DWORD errorCode, WCHAR *message) +{ + LPWSTR msgBuf; + if (FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) + return False; + wcscpy(message, msgBuf); + LocalFree(msgBuf); + return True; +} + + + +static int Install(void) +{ + CFileInStream archiveStream; + CLookToRead2 lookStream; + CSzArEx db; + + SRes res = SZ_OK; + WRes winRes = 0; + const char *errorMessage = NULL; + + ISzAlloc allocImp; + ISzAlloc allocTempImp; + WCHAR sfxPath[MAX_PATH + 2]; + + int needRebootLevel = 0; + + allocImp.Alloc = SzAlloc; + allocImp.Free = SzFree; + + allocTempImp.Alloc = SzAllocTemp; + allocTempImp.Free = SzFreeTemp; + + { + const DWORD len = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); + if (len == 0 || len > MAX_PATH) + return 1; + } + + winRes = InFile_OpenW(&archiveStream.file, sfxPath); + + if (winRes == 0) + { + UInt64 pos = 0; + if (!FindSignature(&archiveStream.file, &pos)) + errorMessage = "Can't find 7z archive"; + else + winRes = File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET); + } + + if (winRes != 0) + res = SZ_ERROR_FAIL; + + if (errorMessage) + res = SZ_ERROR_FAIL; + +if (res == SZ_OK) +{ + size_t pathLen; + if (!g_SilentMode) + { + GetDlgItemTextW(g_HWND, IDE_EXTRACT_PATH, path, MAX_PATH); + } + + FileInStream_CreateVTable(&archiveStream); + LookToRead2_CreateVTable(&lookStream, False); + lookStream.buf = NULL; + + RemoveQuotes(path); + { + // Remove post spaces + unsigned endPos = 0; + unsigned i = 0; + + for (;;) + { + const wchar_t c = path[i++]; + if (c == 0) + break; + if (c != ' ') + endPos = i; + } + + path[endPos] = 0; + if (path[0] == 0) + { + PrintErrorMessage("Incorrect path", NULL); + return 1; + } + } + + NormalizePrefix(path); + winRes = CreateComplexDir(); + + if (winRes != 0) + res = SZ_ERROR_FAIL; + + pathLen = wcslen(path); + + if (res == SZ_OK) + { + lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize); + if (!lookStream.buf) + res = SZ_ERROR_MEM; + else + { + lookStream.bufSize = kInputBufSize; + lookStream.realStream = &archiveStream.vt; + LookToRead2_INIT(&lookStream) + } + } + + SzArEx_Init(&db); + + if (res == SZ_OK) + { + res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp); + } + + if (res == SZ_OK) + { + UInt32 i; + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if (!outBuf) */ + Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */ + size_t outBufSize = 0; /* it can have any value before first call, if (!outBuf) */ + + g_TotalSize = 0; + + if (!g_SilentMode) + { + ShowWindow(g_Progress_HWND, SW_SHOW); + ShowWindow(g_InfoLine_HWND, SW_SHOW); + SendMessage(g_Progress_HWND, PBM_SETRANGE32, 0, db.NumFiles); + } + + for (i = 0; i < db.NumFiles; i++) + { + size_t offset = 0; + size_t outSizeProcessed = 0; + WCHAR *temp; + + if (!g_SilentMode) + { + MSG msg; + + // g_HWND + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (!IsDialogMessage(g_HWND, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (!g_HWND) + return 1; + } + + // Sleep(10); + SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0); + } + + { + const size_t len = SzArEx_GetFileNameUtf16(&db, i, NULL); + if (len >= MAX_PATH) + { + res = SZ_ERROR_FAIL; + break; + } + } + + temp = path + pathLen; + + SzArEx_GetFileNameUtf16(&db, i, (UInt16 *)temp); + + if (!g_SilentMode) + SetWindowTextW(g_InfoLine_HWND, temp); + + { + res = SzArEx_Extract(&db, &lookStream.vt, i, + &blockIndex, &outBuf, &outBufSize, + &offset, &outSizeProcessed, + &allocImp, &allocTempImp); + if (res != SZ_OK) + break; + } + + { + CSzFile outFile; + size_t processedSize; + size_t j; + // size_t nameStartPos = 0; + UInt32 tempIndex = 0; + int fileLevel = 1 << 2; + WCHAR origPath[MAX_PATH * 2 + 10]; + + for (j = 0; temp[j] != 0; j++) + { + if (temp[j] == '/') + { + temp[j] = 0; + MyCreateDir(path); + temp[j] = CHAR_PATH_SEPARATOR; + // nameStartPos = j + 1; + } + } + + if (SzArEx_IsDir(&db, i)) + { + MyCreateDir(path); + continue; + } + + { + // BoolInt skipFile = False; + + wcscpy(origPath, path); + + for (;;) + { + WRes openRes; + + if (tempIndex != 0) + { + if (tempIndex > 100) + { + res = SZ_ERROR_FAIL; + break; + } + wcscpy(path, origPath); + CatAscii(path, ".tmp"); + if (tempIndex > 1) + HexToString(tempIndex, path + wcslen(path)); + if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) + { + tempIndex++; + continue; + } + } + + { + SetFileAttributesW(path, 0); + openRes = OutFile_OpenW(&outFile, path); + if (openRes == 0) + break; + } + + if (tempIndex != 0) + { + tempIndex++; + continue; + } + + if (FindSubString(temp, "7-zip.dll") + #ifdef USE_7ZIP_32_DLL + || FindSubString(temp, "7-zip32.dll") + #endif + ) + { + const DWORD ver = GetFileVersion(path); + fileLevel = ((ver < Z7_7ZIP_DLL_VER_COMPAT || ver > Z7_7ZIP_CUR_VER) ? 2 : 1); + tempIndex++; + continue; + } + + if (g_SilentMode) + { + tempIndex++; + continue; + } + { + WCHAR message[MAX_PATH * 3 + 100]; + int mbRes; + + CpyAscii(message, "Can't open file\n"); + wcscat(message, path); + CatAscii(message, "\n"); + + GetErrorMessage(openRes, message + wcslen(message)); + + mbRes = MessageBoxW(g_HWND, message, L"Error", MB_ICONERROR | MB_ABORTRETRYIGNORE | MB_DEFBUTTON3); + if (mbRes == IDABORT) + { + res = SZ_ERROR_ABORT; + tempIndex = 0; + break; + } + if (mbRes == IDIGNORE) + { + // skipFile = True; + tempIndex++; + } + } + } + + if (res != SZ_OK) + break; + + /* + if (skipFile) + continue; + */ + } + + // if (res == SZ_OK) + { + processedSize = outSizeProcessed; + winRes = File_Write(&outFile, outBuf + offset, &processedSize); + if (winRes != 0 || processedSize != outSizeProcessed) + { + errorMessage = "Can't write output file"; + res = SZ_ERROR_FAIL; + } + + g_TotalSize += (DWORD)outSizeProcessed; + + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.MTime, i)) + { + const CNtfsFileTime *t = db.MTime.Vals + i; + FILETIME mTime; + mTime.dwLowDateTime = t->Low; + mTime.dwHighDateTime = t->High; + SetFileTime(outFile.handle, NULL, NULL, &mTime); + } + #endif + + { + const WRes winRes2 = File_Close(&outFile); + if (res != SZ_OK) + break; + if (winRes2 != 0) + { + winRes = winRes2; + break; + } + } + + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.Attribs, i)) + SetFileAttributesW(path, db.Attribs.Vals[i]); + #endif + } + + if (tempIndex != 0) + { + // is it supported at win2000 ? + #ifndef UNDER_CE + if (!MoveFileExW(path, origPath, MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING)) + { + winRes = GetLastError(); + break; + } + needRebootLevel |= fileLevel; + #endif + } + + } + } + + ISzAlloc_Free(&allocImp, outBuf); + + if (!g_SilentMode) + SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0); + + path[pathLen] = 0; + + if (i == db.NumFiles) + { + SetRegKey_Path(); + WriteCLSID(); + WriteShellEx(); + + SetShellProgramsGroup(g_HWND); + if (!g_SilentMode) + SetWindowTextW(g_InfoLine_HWND, k_7zip_with_Ver L" is installed"); + } + } + + SzArEx_Free(&db, &allocImp); + + ISzAlloc_Free(&allocImp, lookStream.buf); + + File_Close(&archiveStream.file); + +} + + if (winRes != 0) + res = SZ_ERROR_FAIL; + + if (res == SZ_OK) + { + if (!g_SilentMode && needRebootLevel > 1) + { + if (MessageBoxW(g_HWND, L"You must restart your system to complete the installation.\nRestart now?", + k_7zip_Setup, MB_YESNO | MB_DEFBUTTON2) == IDYES) + { + #ifndef UNDER_CE + + // Get a token for this process. + HANDLE hToken; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + { + TOKEN_PRIVILEGES tkp; + // Get the LUID for the shutdown privilege. + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + // Get the shutdown privilege for this process. + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); + + if (GetLastError() == ERROR_SUCCESS) + { + if (!ExitWindowsEx(EWX_REBOOT, 0)) + { + } + } + } + + #endif + } + } + + if (res == SZ_OK) + return 0; + } + + if (!g_SilentMode) + { + if (winRes != 0) + { + WCHAR m[MAX_PATH + 100]; + m[0] = 0; + GetErrorMessage(winRes, m); + PrintErrorMessage(NULL, m); + } + else + { + if (res == SZ_ERROR_ABORT) + return 2; + + if (res == SZ_ERROR_UNSUPPORTED) + errorMessage = "Decoder doesn't support this archive"; + else if (res == SZ_ERROR_MEM) + errorMessage = "Can't allocate required memory"; + else if (res == SZ_ERROR_CRC) + errorMessage = "CRC error"; + else if (res == SZ_ERROR_DATA) + errorMessage = "Data error"; + + if (!errorMessage) + errorMessage = "ERROR"; + PrintErrorMessage(errorMessage, NULL); + } + } + + return 1; +} diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.dsp p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsp --- p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsp 2023-04-04 10:00:00.000000000 +0000 @@ -0,0 +1,248 @@ +# Microsoft Developer Studio Project File - Name="7zipInstall" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=7zipInstall - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7zipInstall.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7zipInstall.mak" CFG="7zipInstall - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7zipInstall - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "7zipInstall - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7zipInstall - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7zipInstall - Win32 Release" +# Name "7zipInstall - Win32 Debug" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\7z.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zArcIn.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrcOpt.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zStream.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra86.c +# End Source File +# Begin Source File + +SOURCE=..\..\BraIA64.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\DllSecur.c +# End Source File +# Begin Source File + +SOURCE=..\..\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.c +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.c +# ADD CPP /Yc"Precomp.h" +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zipInstall.c +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.dsw p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsw --- p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.dsw 2015-05-31 12:00:00.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7zipInstall"=.\7zipInstall.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.manifest p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.manifest --- p7zip-rar-16.02/C/Util/7zipInstall/7zipInstall.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/7zipInstall.manifest 2015-06-14 13:00:00.000000000 +0000 @@ -0,0 +1,18 @@ + + + +7-Zip Installer + + + + + + + + + + + + +true + diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/Precomp.c p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.c --- p7zip-rar-16.02/C/Util/7zipInstall/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.c 2013-01-23 18:00:00.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.h --- p7zip-rar-16.02/C/Util/7zipInstall/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/makefile p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/makefile --- p7zip-rar-16.02/C/Util/7zipInstall/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/makefile 2024-04-29 15:00:00.000000000 +0000 @@ -0,0 +1,47 @@ +PROG = 7zipInstall.exe +MY_FIXED = 1 + +!IFDEF Z7_64BIT_INSTALLER +CFLAGS = $(CFLAGS) -DZ7_64BIT_INSTALLER +!ENDIF + +CFLAGS = $(CFLAGS) \ + -DZ7_LZMA_SIZE_OPT \ + -DZ7_NO_METHOD_LZMA2 \ + -DZ7_NO_METHODS_FILTERS \ + -DZ7_USE_NATIVE_BRANCH_FILTER \ + -DZ7_EXTRACT_ONLY \ + +MAIN_OBJS = \ + $O\7zipInstall.obj \ + +C_OBJS = \ + $O\7zAlloc.obj \ + $O\7zArcIn.obj \ + $O\7zBuf.obj \ + $O\7zFile.obj \ + $O\7zDec.obj \ + $O\7zStream.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\CpuArch.obj \ + $O\DllSecur.obj \ + $O\LzmaDec.obj \ + +OBJS = \ + $(MAIN_OBJS) \ + $(C_OBJS) \ + $(ASM_OBJS) \ + $O\resource.res + +!include "../../../CPP/7zip/Crc.mak" +# !include "../../../CPP/7zip/LzmaDec.mak" + +!include "../../../CPP/Build.mak" + +$(MAIN_OBJS): $(*B).c + $(COMPL_O1) +$(C_OBJS): ../../$(*B).c + $(COMPL_O1) + +!include "../../Asm_c.mak" diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/resource.h p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.h --- p7zip-rar-16.02/C/Util/7zipInstall/resource.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.h 2015-08-25 12:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_INSTALL 100 + +#define IDT_EXTRACT_EXTRACT_TO 110 +#define IDE_EXTRACT_PATH 111 +#define IDB_EXTRACT_SET_PATH 112 +#define IDT_CUR_FILE 113 +#define IDC_PROGRESS 114 + +#define IDI_ICON 1 diff -Nru p7zip-rar-16.02/C/Util/7zipInstall/resource.rc p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.rc --- p7zip-rar-16.02/C/Util/7zipInstall/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipInstall/resource.rc 2024-03-21 07:00:00.000000000 +0000 @@ -0,0 +1,48 @@ +#include +// #include +// #include +#include + +#define USE_COPYRIGHT_CR +#include "../../7zVersion.rc" +#include "resource.h" + +MY_VERSION_INFO(MY_VFT_APP, "7-Zip Installer", "7zipInstall", "7zipInstall.exe") + +1 ICON "7zip.ico" + +#define xc 184 +#define yc 96 + +#define m 8 +#define bxs 64 +#define bys 16 +#define bxsDots 20 + +#define xs (xc + m + m) +#define ys (yc + m + m) + +#define bx1 (xs - m - bxs) +#define bx2 (bx1 - m - bxs) + +#define by (ys - m - bys) + +IDD_INSTALL DIALOG 0, 0, xs, ys +STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE +CAPTION "Install 7-Zip" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Destination folder:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 + EDITTEXT IDE_EXTRACT_PATH, m, 21, xc - bxsDots - 12, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, 20, bxsDots, bys, WS_GROUP + + LTEXT "", IDT_CUR_FILE, m, 50, xc, 8 + CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10 + + DEFPUSHBUTTON "&Install", IDOK, bx2, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +END + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "7zipInstall.manifest" +#endif diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.c p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.c --- p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.c 2024-03-21 10:00:00.000000000 +0000 @@ -0,0 +1,1234 @@ +/* 7zipUninstall.c - 7-Zip Uninstaller +2024-03-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #define SZ_ERROR_ABORT 100 + +#include "../../7zTypes.h" +#include "../../7zWindows.h" + +#if defined(_MSC_VER) && _MSC_VER < 1600 +#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union +#endif + +#ifdef Z7_OLD_WIN_SDK +struct IShellView; +#define SHFOLDERAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE +SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +typedef enum { + SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists + SHGFP_TYPE_DEFAULT = 1, // default value, may not exist +} SHGFP_TYPE; +#endif +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../7zVersion.h" + +#include "resource.h" + + + + +#define LLL_(quote) L##quote +#define LLL(quote) LLL_(quote) + +#define wcscat lstrcatW +#define wcslen (size_t)lstrlenW +#define wcscpy lstrcpyW + +// static LPCWSTR const k_7zip = L"7-Zip"; + +// #define Z7_64BIT_INSTALLER 1 + +#ifdef _WIN64 + #define Z7_64BIT_INSTALLER 1 +#endif + +#define k_7zip_with_Ver_base L"7-Zip " LLL(MY_VERSION) + +#ifdef Z7_64BIT_INSTALLER + + // #define USE_7ZIP_32_DLL + + #if defined(_M_ARM64) || defined(_M_ARM) + #define k_Postfix L" (arm64)" + #else + #define k_Postfix L" (x64)" + #define USE_7ZIP_32_DLL + #endif +#else + #if defined(_M_ARM64) || defined(_M_ARM) + #define k_Postfix L" (arm)" + #else + // #define k_Postfix L" (x86)" + #define k_Postfix + #endif +#endif + +#define k_7zip_with_Ver k_7zip_with_Ver_base k_Postfix + +static LPCWSTR const k_7zip_with_Ver_Uninstall = k_7zip_with_Ver L" Uninstall"; + +static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip"; + +static LPCWSTR const k_Reg_Path = L"Path"; + +static LPCWSTR const k_Reg_Path32 = L"Path" + #ifdef Z7_64BIT_INSTALLER + L"64" + #else + L"32" + #endif + ; + +#if defined(Z7_64BIT_INSTALLER) && !defined(_WIN64) + #define k_Reg_WOW_Flag KEY_WOW64_64KEY +#else + #define k_Reg_WOW_Flag 0 +#endif + +#ifdef USE_7ZIP_32_DLL +#ifdef _WIN64 + #define k_Reg_WOW_Flag_32 KEY_WOW64_32KEY +#else + #define k_Reg_WOW_Flag_32 0 +#endif +#endif + +#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}" + +static LPCWSTR const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID; +static LPCWSTR const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32"; + + +#define g_AllUsers True + +static BoolInt g_Install_was_Pressed; +static BoolInt g_Finished; +static BoolInt g_SilentMode; + +static HWND g_HWND; +static HWND g_Path_HWND; +static HWND g_InfoLine_HWND; +static HWND g_Progress_HWND; + +// RegDeleteKeyExW is supported starting from win2003sp1/xp-pro-x64 +// Z7_WIN32_WINNT_MIN < 0x0600 // Vista +#if !defined(Z7_WIN32_WINNT_MIN) \ + || Z7_WIN32_WINNT_MIN < 0x0502 /* < win2003 */ \ + || Z7_WIN32_WINNT_MIN == 0x0502 && !defined(_M_AMD64) +#define Z7_USE_DYN_RegDeleteKeyExW +#endif + +#ifdef Z7_USE_DYN_RegDeleteKeyExW +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +typedef LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved); +static Func_RegDeleteKeyExW func_RegDeleteKeyExW; +#endif + +static WCHAR cmd[MAX_PATH + 4]; +static WCHAR cmdError[MAX_PATH + 4]; +static WCHAR path[MAX_PATH * 2 + 40]; +static WCHAR workDir[MAX_PATH + 10]; +static WCHAR modulePath[MAX_PATH + 10]; +static WCHAR modulePrefix[MAX_PATH + 10]; +static WCHAR tempPath[MAX_PATH * 2 + 40]; +static WCHAR cmdLine[MAX_PATH * 3 + 40]; +static WCHAR copyPath[MAX_PATH * 2 + 40]; + +static LPCWSTR const kUninstallExe = L"Uninstall.exe"; + +#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) + + +static void CpyAscii(wchar_t *dest, const char *s) +{ + for (;;) + { + const Byte b = (Byte)*s++; + *dest++ = b; + if (b == 0) + return; + } +} + +static void CatAscii(wchar_t *dest, const char *s) +{ + dest += wcslen(dest); + CpyAscii(dest, s); +} + +static void PrintErrorMessage(const char *s1, const wchar_t *s2) +{ + WCHAR m[MAX_PATH + 512]; + m[0] = 0; + CatAscii(m, "ERROR:"); + if (s1) + { + CatAscii(m, "\n"); + CatAscii(m, s1); + } + if (s2) + { + CatAscii(m, "\n"); + wcscat(m, s2); + } + MessageBoxW(g_HWND, m, k_7zip_with_Ver_Uninstall, MB_ICONERROR | MB_OK); +} + + +static BoolInt AreStringsEqual_NoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2 && MAKE_CHAR_UPPER(c1) != MAKE_CHAR_UPPER(c2)) + return False; + if (c2 == 0) + return True; + } +} + +static BoolInt IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1; + const wchar_t c2 = *s2++; + if (c2 == 0) + return True; + c1 = *s1++; + if (c1 != c2 && MAKE_CHAR_UPPER(c1) != MAKE_CHAR_UPPER(c2)) + return False; + } +} + +static void NormalizePrefix(WCHAR *s) +{ + const size_t len = wcslen(s); + if (len != 0) + if (s[len - 1] != WCHAR_PATH_SEPARATOR) + { + s[len] = WCHAR_PATH_SEPARATOR; + s[len + 1] = 0; + } +} + +static int MyRegistry_QueryString(HKEY hKey, LPCWSTR name, LPWSTR dest) +{ + DWORD cnt = MAX_PATH * sizeof(name[0]); + DWORD type = 0; + const LONG res = RegQueryValueExW(hKey, name, NULL, &type, (LPBYTE)dest, &cnt); + if (type != REG_SZ) + return False; + return res == ERROR_SUCCESS; +} + +static int MyRegistry_QueryString2(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) +{ + HKEY key = 0; + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag, &key); + if (res != ERROR_SUCCESS) + return False; + { + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + RegCloseKey(key); + return res2; + } +} + +static LONG MyRegistry_OpenKey_ReadWrite(HKEY parentKey, LPCWSTR name, HKEY *destKey) +{ + return RegOpenKeyExW(parentKey, name, 0, KEY_READ | KEY_WRITE | k_Reg_WOW_Flag, destKey); +} + +static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCWSTR name) +{ +#if k_Reg_WOW_Flag != 0 +#ifdef Z7_USE_DYN_RegDeleteKeyExW + if (!func_RegDeleteKeyExW) + return E_FAIL; + return func_RegDeleteKeyExW +#else + return RegDeleteKeyExW +#endif + (parentKey, name, k_Reg_WOW_Flag, 0); +#else + return RegDeleteKeyW(parentKey, name); +#endif +} + +#ifdef USE_7ZIP_32_DLL + +static int MyRegistry_QueryString2_32(HKEY hKey, LPCWSTR keyName, LPCWSTR valName, LPWSTR dest) +{ + HKEY key = 0; + const LONG res = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | k_Reg_WOW_Flag_32, &key); + if (res != ERROR_SUCCESS) + return False; + { + const BoolInt res2 = MyRegistry_QueryString(key, valName, dest); + RegCloseKey(key); + return res2; + } +} + +static LONG MyRegistry_OpenKey_ReadWrite_32(HKEY parentKey, LPCWSTR name, HKEY *destKey) +{ + return RegOpenKeyExW(parentKey, name, 0, KEY_READ | KEY_WRITE | k_Reg_WOW_Flag_32, destKey); +} + +static LONG MyRegistry_DeleteKey_32(HKEY parentKey, LPCWSTR name) +{ +#if k_Reg_WOW_Flag_32 != 0 +#ifdef Z7_USE_DYN_RegDeleteKeyExW + if (!func_RegDeleteKeyExW) + return E_FAIL; + return func_RegDeleteKeyExW +#else + return RegDeleteKeyExW +#endif + (parentKey, name, k_Reg_WOW_Flag_32, 0); +#else + return RegDeleteKeyW(parentKey, name); +#endif +} + +#endif + + + + +static void MyReg_DeleteVal_Path_if_Equal(HKEY hKey, LPCWSTR name) +{ + WCHAR s[MAX_PATH + 10]; + if (MyRegistry_QueryString(hKey, name, s)) + { + NormalizePrefix(s); + if (AreStringsEqual_NoCase(s, path)) + RegDeleteValueW(hKey, name); + } +} + +static void SetRegKey_Path2(HKEY parentKey) +{ + HKEY key = 0; + const LONG res = MyRegistry_OpenKey_ReadWrite(parentKey, k_Reg_Software_7zip, &key); + if (res == ERROR_SUCCESS) + { + MyReg_DeleteVal_Path_if_Equal(key, k_Reg_Path32); + MyReg_DeleteVal_Path_if_Equal(key, k_Reg_Path); + + RegCloseKey(key); + // MyRegistry_DeleteKey(parentKey, k_Reg_Software_7zip); + } +} + +static void SetRegKey_Path(void) +{ + SetRegKey_Path2(HKEY_CURRENT_USER); + SetRegKey_Path2(HKEY_LOCAL_MACHINE); +} + +static HRESULT CreateShellLink(LPCWSTR srcPath, LPCWSTR targetPath) +{ + IShellLinkW *sl; + + // CoInitialize has already been called. + HRESULT hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&sl); + + if (SUCCEEDED(hres)) + { + IPersistFile *pf; + + hres = sl->lpVtbl->QueryInterface(sl, &IID_IPersistFile, (LPVOID *)&pf); + + if (SUCCEEDED(hres)) + { + WCHAR s[MAX_PATH + 10]; + hres = pf->lpVtbl->Load(pf, srcPath, TRUE); + pf->lpVtbl->Release(pf); + + if (SUCCEEDED(hres)) + { + hres = sl->lpVtbl->GetPath(sl, s, MAX_PATH, NULL, 0); // SLGP_RAWPATH + if (!AreStringsEqual_NoCase(s, targetPath)) + hres = S_FALSE; + } + } + + sl->lpVtbl->Release(sl); + } + + return hres; +} + +static void SetShellProgramsGroup(HWND hwndOwner) +{ + #ifdef UNDER_CE + + UNUSED_VAR(hwndOwner) + + #else + + unsigned i = (g_AllUsers ? 1 : 2); + + for (; i < 3; i++) + { + // BoolInt isOK = True; + WCHAR link[MAX_PATH + 40]; + WCHAR destPath[MAX_PATH + 40]; + + link[0] = 0; + + if (SHGetFolderPathW(hwndOwner, + i == 1 ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, + NULL, SHGFP_TYPE_CURRENT, link) != S_OK) + continue; + + NormalizePrefix(link); + CatAscii(link, "7-Zip\\"); + + { + const size_t baseLen = wcslen(link); + unsigned k; + BoolInt needDelete = False; + + for (k = 0; k < 2; k++) + { + CpyAscii(link + baseLen, k == 0 ? + "7-Zip File Manager.lnk" : + "7-Zip Help.lnk"); + wcscpy(destPath, path); + CatAscii(destPath, k == 0 ? + "7zFM.exe" : + "7-zip.chm"); + + if (CreateShellLink(link, destPath) == S_OK) + { + needDelete = True; + DeleteFileW(link); + } + } + + if (needDelete) + { + link[baseLen] = 0; + RemoveDirectoryW(link); + } + } + } + + #endif +} + + +static LPCSTR const k_ShellEx_Items[] = +{ + "*\\shellex\\ContextMenuHandlers" + , "Directory\\shellex\\ContextMenuHandlers" + , "Folder\\shellex\\ContextMenuHandlers" + , "Directory\\shellex\\DragDropHandlers" + , "Drive\\shellex\\DragDropHandlers" +}; + +static LPCWSTR const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"; + +static LPCWSTR const k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe"; +#define k_REG_Uninstall L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" +static LPCWSTR const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip"; + + +static void RemoveQuotes(wchar_t *s) +{ + const size_t len = wcslen(s); + size_t i; + if (len == 0 || s[0] != '\"' || s[len - 1] != '\"') + return; + for (i = 0; i < len; i++) + s[i] = s[i + 1]; + s[len - 2] = 0; +} + +static BoolInt AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name) +{ + if (!IsString1PrefixedByString2_NoCase(s, prefix)) + return False; + return AreStringsEqual_NoCase(s + wcslen(prefix), name); +} + +static void WriteCLSID(void) +{ + WCHAR s[MAX_PATH + 30]; + + if (MyRegistry_QueryString2(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc, NULL, s)) + { + if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll")) + { + { + const LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); + if (res == ERROR_SUCCESS) + MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip); + } + + { + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) + { + WCHAR destPath[MAX_PATH]; + CpyAscii(destPath, k_ShellEx_Items[i]); + CatAscii(destPath, "\\7-Zip"); + + MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, destPath); + } + } + + { + HKEY destKey = 0; + const LONG res = MyRegistry_OpenKey_ReadWrite(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); + if (res == ERROR_SUCCESS) + { + RegDeleteValueW(destKey, k_7zip_CLSID); + /* res = */ RegCloseKey(destKey); + } + } + } + } + + + #ifdef USE_7ZIP_32_DLL + + if (MyRegistry_QueryString2_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc, NULL, s)) + { + if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll")) + { + { + const LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc); + if (res == ERROR_SUCCESS) + MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip); + } + + { + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(k_ShellEx_Items); i++) + { + WCHAR destPath[MAX_PATH]; + CpyAscii(destPath, k_ShellEx_Items[i]); + CatAscii(destPath, "\\7-Zip"); + + MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, destPath); + } + } + + { + HKEY destKey = 0; + const LONG res = MyRegistry_OpenKey_ReadWrite_32(HKEY_LOCAL_MACHINE, k_Shell_Approved, &destKey); + if (res == ERROR_SUCCESS) + { + RegDeleteValueW(destKey, k_7zip_CLSID); + /* res = */ RegCloseKey(destKey); + } + } + } + } + + #endif + + + if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm, NULL, s)) + { + // RemoveQuotes(s); + if (AreEqual_Path_PrefixName(s, path, L"7zFM.exe")) + MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm); + } + + if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_Uninstall_7zip, L"UninstallString", s)) + { + RemoveQuotes(s); + if (AreEqual_Path_PrefixName(s, path, kUninstallExe)) + MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_Uninstall_7zip); + } +} + + +static const wchar_t *GetCmdParam(const wchar_t *s) +{ + unsigned pos = 0; + BoolInt quoteMode = False; + for (;; s++) + { + const wchar_t c = *s; + if (c == 0 || (c == L' ' && !quoteMode)) + break; + if (c == L'\"') + { + quoteMode = !quoteMode; + continue; + } + if (pos >= Z7_ARRAY_SIZE(cmd) - 1) + exit(1); + cmd[pos++] = c; + } + cmd[pos] = 0; + return s; +} + +/* +static void RemoveQuotes(wchar_t *s) +{ + const wchar_t *src = s; + for (;;) + { + wchar_t c = *src++; + if (c == '\"') + continue; + *s++ = c; + if (c == 0) + return; + } +} +*/ + +static BoolInt DoesFileOrDirExist(void) +{ + return (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES); +} + +static BOOL RemoveFileAfterReboot2(const WCHAR *s) +{ + #ifndef UNDER_CE + return MoveFileExW(s, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + #else + UNUSED_VAR(s) + return TRUE; + #endif +} + +static BOOL RemoveFileAfterReboot(void) +{ + return RemoveFileAfterReboot2(path); +} + +// #define IS_LIMIT_CHAR(c) (c == 0 || c == ' ') + +static BoolInt IsThereSpace(const wchar_t *s) +{ + for (;;) + { + const wchar_t c = *s++; + if (c == 0) + return False; + if (c == ' ') + return True; + } +} + +static void AddPathParam(wchar_t *dest, const wchar_t *src) +{ + const BoolInt needQuote = IsThereSpace(src); + if (needQuote) + CatAscii(dest, "\""); + wcscat(dest, src); + if (needQuote) + CatAscii(dest, "\""); +} + + + +static BoolInt GetErrorMessage(DWORD errorCode, WCHAR *message) +{ + LPWSTR msgBuf; + if (FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) + return False; + wcscpy(message, msgBuf); + LocalFree(msgBuf); + return True; +} + +static BOOL RemoveDir(void) +{ + const DWORD attrib = GetFileAttributesW(path); + if (attrib == INVALID_FILE_ATTRIBUTES) + return TRUE; + if (RemoveDirectoryW(path)) + return TRUE; + return RemoveFileAfterReboot(); +} + + + + + +#define k_Lang "Lang" + +// NUM_LANG_TXT_FILES files are placed before en.ttt +#define NUM_LANG_TXT_FILES 92 + +#ifdef USE_7ZIP_32_DLL + #define NUM_EXTRA_FILES_64BIT 1 +#else + #define NUM_EXTRA_FILES_64BIT 0 +#endif + +#define NUM_FILES (NUM_LANG_TXT_FILES + 1 + 13 + NUM_EXTRA_FILES_64BIT) + +static const char * const k_Names = + "af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext" + " fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kab kk ko ku ku-ckb ky" + " lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru" + " sa si sk sl sq sr-spc sr-spl sv sw ta tg th tk tr tt ug uk uz uz-cyrl va vi yo zh-cn zh-tw" + " en.ttt" + " descript.ion" + " History.txt" + " License.txt" + " readme.txt" + " 7-zip.chm" + " 7z.sfx" + " 7zCon.sfx" + " 7z.exe" + " 7zG.exe" + " 7z.dll" + " 7zFM.exe" + #ifdef USE_7ZIP_32_DLL + " 7-zip32.dll" + #endif + " 7-zip.dll" + " Uninstall.exe"; + + + +static int Install(void) +{ + SRes res = SZ_OK; + WRes winRes = 0; + + // BoolInt needReboot = False; + const size_t pathLen = wcslen(path); + + if (!g_SilentMode) + { + ShowWindow(g_Progress_HWND, SW_SHOW); + ShowWindow(g_InfoLine_HWND, SW_SHOW); + SendMessage(g_Progress_HWND, PBM_SETRANGE32, 0, NUM_FILES); + } + + { + unsigned i; + const char *curName = k_Names; + + for (i = 0; *curName != 0; i++) + { + WCHAR *temp; + + if (!g_SilentMode) + { + MSG msg; + + // g_HWND + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (!IsDialogMessage(g_HWND, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (!g_HWND) + return 1; + } + + // Sleep(1); + SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0); + } + + path[pathLen] = 0; + temp = path + pathLen; + + if (i <= NUM_LANG_TXT_FILES) + CpyAscii(temp, k_Lang "\\"); + + { + WCHAR *dest = temp + wcslen(temp); + + for (;;) + { + const char c = *curName; + if (c == 0) + break; + curName++; + if (c == ' ') + break; + *dest++ = (Byte)c; + } + + *dest = 0; + } + + if (i < NUM_LANG_TXT_FILES) + CatAscii(temp, ".txt"); + + if (!g_SilentMode) + SetWindowTextW(g_InfoLine_HWND, temp); + + { + const DWORD attrib = GetFileAttributesW(path); + if (attrib == INVALID_FILE_ATTRIBUTES) + continue; + if (attrib & FILE_ATTRIBUTE_READONLY) + SetFileAttributesW(path, 0); + if (!DeleteFileW(path)) + { + if (!RemoveFileAfterReboot()) + { + winRes = GetLastError(); + } + /* + else + needReboot = True; + */ + } + } + } + + CpyAscii(path + pathLen, k_Lang); + RemoveDir(); + + path[pathLen] = 0; + RemoveDir(); + + if (!g_SilentMode) + SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0); + + if (*curName == 0) + { + SetRegKey_Path(); + WriteCLSID(); + SetShellProgramsGroup(g_HWND); + if (!g_SilentMode) + SetWindowTextW(g_InfoLine_HWND, k_7zip_with_Ver L" is uninstalled"); + } + } + + if (winRes != 0) + res = SZ_ERROR_FAIL; + + if (res == SZ_OK) + { + // if (!g_SilentMode && needReboot); + return 0; + } + + if (!g_SilentMode) + { + WCHAR m[MAX_PATH + 100]; + m[0] = 0; + if (winRes == 0 || !GetErrorMessage(winRes, m)) + CpyAscii(m, "ERROR"); + PrintErrorMessage("System ERROR:", m); + } + + return 1; +} + + +static void OnClose(void) +{ + if (g_Install_was_Pressed && !g_Finished) + { + if (MessageBoxW(g_HWND, + L"Do you want to cancel uninstallation?", + k_7zip_with_Ver_Uninstall, + MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES) + return; + } + DestroyWindow(g_HWND); + g_HWND = NULL; +} + +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + UNUSED_VAR(lParam) + + switch (message) + { + case WM_INITDIALOG: + g_Path_HWND = GetDlgItem(hwnd, IDE_EXTRACT_PATH); + g_InfoLine_HWND = GetDlgItem(hwnd, IDT_CUR_FILE); + g_Progress_HWND = GetDlgItem(hwnd, IDC_PROGRESS); + + SetWindowTextW(hwnd, k_7zip_with_Ver_Uninstall); + SetDlgItemTextW(hwnd, IDE_EXTRACT_PATH, path); + + ShowWindow(g_Progress_HWND, SW_HIDE); + ShowWindow(g_InfoLine_HWND, SW_HIDE); + + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + if (g_Finished) + { + OnClose(); + break; + } + if (!g_Install_was_Pressed) + { + SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)(void *)GetDlgItem(hwnd, IDCANCEL), TRUE); + + EnableWindow(g_Path_HWND, FALSE); + EnableWindow(GetDlgItem(hwnd, IDOK), FALSE); + + g_Install_was_Pressed = True; + return TRUE; + } + break; + } + + case IDCANCEL: + { + OnClose(); + break; + } + + default: return FALSE; + } + break; + + case WM_CLOSE: + OnClose(); + break; + /* + case WM_DESTROY: + PostQuitMessage(0); + return TRUE; + */ + default: + return FALSE; + } + + return TRUE; +} + + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + lpCmdLine, int nCmdShow) +{ + const wchar_t *cmdParams; + BoolInt useTemp = True; + + UNUSED_VAR(hPrevInstance) + UNUSED_VAR(lpCmdLine) + UNUSED_VAR(nCmdShow) + +#ifndef UNDER_CE + CoInitialize(NULL); +#endif + +#ifndef UNDER_CE +#ifdef Z7_USE_DYN_RegDeleteKeyExW + func_RegDeleteKeyExW = + (Func_RegDeleteKeyExW) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandleW(L"advapi32.dll"), + "RegDeleteKeyExW"); +#endif +#endif + + { + const wchar_t *s = GetCommandLineW(); + + #ifndef UNDER_CE + s = GetCmdParam(s); + #endif + + cmdParams = s; + + for (;;) + { + { + wchar_t c = *s; + if (c == 0) + break; + if (c == ' ') + { + s++; + continue; + } + } + + { + const wchar_t *s2 = GetCmdParam(s); + BoolInt error = True; + if (cmd[0] == '/') + { + if (cmd[1] == 'S') + { + if (cmd[2] == 0) + { + g_SilentMode = True; + error = False; + } + } + else if (cmd[1] == 'N') + { + if (cmd[2] == 0) + { + useTemp = False; + error = False; + } + } + else if (cmd[1] == 'D' && cmd[2] == '=') + { + wcscpy(workDir, cmd + 3); + // RemoveQuotes(workDir); + useTemp = False; + error = False; + } + } + s = s2; + if (error && cmdError[0] == 0) + wcscpy(cmdError, cmd); + } + } + + if (cmdError[0] != 0) + { + if (!g_SilentMode) + PrintErrorMessage("Unsupported command:", cmdError); + return 1; + } + } + + { + wchar_t *name; + const DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH); + if (len == 0 || len > MAX_PATH) + return 1; + + name = NULL; + wcscpy(modulePrefix, modulePath); + + { + wchar_t *s = modulePrefix; + for (;;) + { + const wchar_t c = *s++; + if (c == 0) + break; + if (c == WCHAR_PATH_SEPARATOR) + name = s; + } + } + + if (!name) + return 1; + + if (!AreStringsEqual_NoCase(name, kUninstallExe)) + useTemp = False; + + *name = 0; // keep only prefix for modulePrefix + } + + + if (useTemp) + { + DWORD winRes = GetTempPathW(MAX_PATH, path); + + // GetTempPath: the returned string ends with a backslash + /* + { + WCHAR s[MAX_PATH + 1]; + wcscpy(s, path); + GetLongPathNameW(s, path, MAX_PATH); + } + */ + + if (winRes != 0 && winRes <= MAX_PATH + 1 + && !IsString1PrefixedByString2_NoCase(modulePrefix, path)) + { + unsigned i; + DWORD d; + + const size_t pathLen = wcslen(path); + d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); + + for (i = 0; i < 100; i++, d += GetTickCount()) + { + CpyAscii(path + pathLen, "7z"); + + { + wchar_t *s = path + wcslen(path); + UInt32 value = d; + unsigned k; + for (k = 0; k < 8; k++) + { + const unsigned t = value & 0xF; + value >>= 4; + s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[k] = 0; + } + + if (DoesFileOrDirExist()) + continue; + if (CreateDirectoryW(path, NULL)) + { + CatAscii(path, STRING_PATH_SEPARATOR); + wcscpy(tempPath, path); + break; + } + if (GetLastError() != ERROR_ALREADY_EXISTS) + break; + } + + if (tempPath[0] != 0) + { + wcscpy(copyPath, tempPath); + CatAscii(copyPath, "Uninst.exe"); // we need not "Uninstall.exe" here + + if (CopyFileW(modulePath, copyPath, TRUE)) + { + RemoveFileAfterReboot2(copyPath); + RemoveFileAfterReboot2(tempPath); + + { + STARTUPINFOW si; + PROCESS_INFORMATION pi; + cmdLine[0] = 0; + + // maybe CreateProcess supports path with spaces even without quotes. + AddPathParam(cmdLine, copyPath); + CatAscii(cmdLine, " /N /D="); + AddPathParam(cmdLine, modulePrefix); + + if (cmdParams[0] != 0 && wcslen(cmdParams) < MAX_PATH * 2 + 10) + wcscat(cmdLine, cmdParams); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + + if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, tempPath, &si, &pi)) + { + CloseHandle(pi.hThread); + if (pi.hProcess) + { + CloseHandle(pi.hProcess); + return 0; + } + } + } + } + } + } + } + + wcscpy(path, modulePrefix); + + if (workDir[0] != 0) + { + wcscpy(path, workDir); + NormalizePrefix(path); + } + + /* + if (path[0] == 0) + { + HKEY key = 0; + BoolInt ok = False; + LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, k_Reg_Software_7zip, 0, KEY_READ | k_Reg_WOW_Flag, &key); + if (res == ERROR_SUCCESS) + { + ok = MyRegistry_QueryString(key, k_Reg_Path32, path); + // ok = MyRegistry_QueryString(key, k_Reg_Path, path); + RegCloseKey(key); + } + } + */ + + + if (g_SilentMode) + return Install(); + + { + int retCode = 1; + g_HWND = CreateDialog( + hInstance, + // GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_INSTALL), NULL, MyDlgProc); + if (!g_HWND) + return 1; + + { + const HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); + // SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); + SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); + } + + { + BOOL bRet; + MSG msg; + + while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) + { + if (bRet == -1) + return retCode; + if (!g_HWND) + return retCode; + + if (!IsDialogMessage(g_HWND, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (!g_HWND) + return retCode; + + if (g_Install_was_Pressed && !g_Finished) + { + retCode = Install(); + g_Finished = True; + if (retCode != 0) + break; + if (!g_HWND) + break; + { + SetDlgItemTextW(g_HWND, IDOK, L"Close"); + EnableWindow(GetDlgItem(g_HWND, IDOK), TRUE); + EnableWindow(GetDlgItem(g_HWND, IDCANCEL), FALSE); + SendMessage(g_HWND, WM_NEXTDLGCTL, (WPARAM)(void *)GetDlgItem(g_HWND, IDOK), TRUE); + } + } + } + + if (g_HWND) + { + DestroyWindow(g_HWND); + g_HWND = NULL; + } + } + + return retCode; + } +} diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.dsp p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsp --- p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsp 2023-04-04 11:00:00.000000000 +0000 @@ -0,0 +1,132 @@ +# Microsoft Developer Studio Project File - Name="7zipUninstall" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=7zipUninstall - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7zipUninstall.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7zipUninstall.mak" CFG="7zipUninstall - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7zipUninstall - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "7zipUninstall - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7zipUninstall - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /FAcs /Yu"Precomp.h" /FD /GF /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/Uninstall.exe" + +!ELSEIF "$(CFG)" == "7zipUninstall - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/Uninstall.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7zipUninstall - Win32 Release" +# Name "7zipUninstall - Win32 Debug" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zVersion.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.c +# ADD CPP /Yc"Precomp.h" +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zipUninstall.c +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.dsw p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsw --- p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.dsw 2015-05-31 12:00:00.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7zipUninstall"=.\7zipUninstall.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.ico differ diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.manifest p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.manifest --- p7zip-rar-16.02/C/Util/7zipUninstall/7zipUninstall.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/7zipUninstall.manifest 2015-06-14 13:00:00.000000000 +0000 @@ -0,0 +1,18 @@ + + + +7-Zip Uninstaller + + + + + + + + + + + + +true + diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/Precomp.c p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.c --- p7zip-rar-16.02/C/Util/7zipUninstall/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.c 2013-01-23 18:00:00.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.h --- p7zip-rar-16.02/C/Util/7zipUninstall/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/makefile p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/makefile --- p7zip-rar-16.02/C/Util/7zipUninstall/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/makefile 2023-04-04 13:00:00.000000000 +0000 @@ -0,0 +1,18 @@ +PROG = 7zipUninstall.exe +MY_FIXED = 1 + +!IFDEF Z7_64BIT_INSTALLER +CFLAGS = $(CFLAGS) -DZ7_64BIT_INSTALLER +!ENDIF + +MAIN_OBJS = \ + $O\7zipUninstall.obj \ + +OBJS = \ + $(MAIN_OBJS) \ + $O\resource.res + +!include "../../../CPP/Build.mak" + +$(MAIN_OBJS): $(*B).c + $(COMPL_O1) diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/resource.h p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.h --- p7zip-rar-16.02/C/Util/7zipUninstall/resource.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.h 2015-08-25 12:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_INSTALL 100 + +#define IDT_EXTRACT_EXTRACT_TO 110 +#define IDE_EXTRACT_PATH 111 + +#define IDT_CUR_FILE 113 +#define IDC_PROGRESS 114 + +#define IDI_ICON 1 diff -Nru p7zip-rar-16.02/C/Util/7zipUninstall/resource.rc p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.rc --- p7zip-rar-16.02/C/Util/7zipUninstall/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/7zipUninstall/resource.rc 2024-03-21 10:00:00.000000000 +0000 @@ -0,0 +1,48 @@ +#include +// #include +// #include +#include + +#define USE_COPYRIGHT_CR +#include "../../7zVersion.rc" +#include "resource.h" + +MY_VERSION_INFO(MY_VFT_APP, "7-Zip Uninstaller", "Uninstall", "Uninstall.exe") + +1 ICON "7zipUninstall.ico" + +#define xc 184 +#define yc 96 + +#define m 8 +#define bxs 64 +#define bys 16 + + +#define xs (xc + m + m) +#define ys (yc + m + m) + +#define bx1 (xs - m - bxs) +#define bx2 (bx1 - m - bxs) + +#define by (ys - m - bys) + +IDD_INSTALL DIALOG 0, 0, xs, ys +STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE +CAPTION "Uninstall 7-Zip" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Uninstall from:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 + EDITTEXT IDE_EXTRACT_PATH, m, 21, xc, 14, ES_AUTOHSCROLL | WS_DISABLED + + + LTEXT "", IDT_CUR_FILE, m, 50, xc, 8 + CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10 + + DEFPUSHBUTTON "&Uninstall", IDOK, bx2, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +END + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "7zipUninstall.manifest" +#endif diff -Nru p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.c p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.c --- p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.c 2023-04-04 19:00:00.000000000 +0000 @@ -0,0 +1,313 @@ +/* LzmaUtil.c -- Test application for LZMA compression +2023-03-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +#include +#include + +#include "../../CpuArch.h" + +#include "../../Alloc.h" +#include "../../7zFile.h" +#include "../../7zVersion.h" +#include "../../LzFind.h" +#include "../../LzmaDec.h" +#include "../../LzmaEnc.h" + +static const char * const kCantReadMessage = "Cannot read input file"; +static const char * const kCantWriteMessage = "Cannot write output file"; +static const char * const kCantAllocateMessage = "Cannot allocate memory"; +static const char * const kDataErrorMessage = "Data error"; + +static void Print(const char *s) +{ + fputs(s, stdout); +} + +static void PrintHelp(void) +{ + Print( + "\n" "LZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE + "\n" + "\n" "Usage: lzma inputFile outputFile" + "\n" " e: encode file" + "\n" " d: decode file" + "\n"); +} + +static int PrintError(const char *message) +{ + Print("\nError: "); + Print(message); + Print("\n"); + return 1; +} + +#define CONVERT_INT_TO_STR(charType, tempSize) \ + unsigned char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = (charType)temp[i]; } \ + *s = 0; \ + return s; + +static char * Convert_unsigned_To_str(unsigned val, char *s) +{ + CONVERT_INT_TO_STR(char, 32) +} + +static void Print_unsigned(unsigned code) +{ + char str[32]; + Convert_unsigned_To_str(code, str); + Print(str); +} + +static int PrintError_WRes(const char *message, WRes wres) +{ + PrintError(message); + Print("\nSystem error code: "); + Print_unsigned((unsigned)wres); + #ifndef _WIN32 + { + const char *s = strerror(wres); + if (s) + { + Print(" : "); + Print(s); + } + } + #endif + Print("\n"); + return 1; +} + +static int PrintErrorNumber(SRes val) +{ + Print("\n7-Zip error code: "); + Print_unsigned((unsigned)val); + Print("\n"); + return 1; +} + +static int PrintUserError(void) +{ + return PrintError("Incorrect command"); +} + + +#define IN_BUF_SIZE (1 << 16) +#define OUT_BUF_SIZE (1 << 16) + + +static SRes Decode2(CLzmaDec *state, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + UInt64 unpackSize) +{ + const int thereIsSize = (unpackSize != (UInt64)(Int64)-1); + Byte inBuf[IN_BUF_SIZE]; + Byte outBuf[OUT_BUF_SIZE]; + size_t inPos = 0, inSize = 0, outPos = 0; + LzmaDec_Init(state); + for (;;) + { + if (inPos == inSize) + { + inSize = IN_BUF_SIZE; + RINOK(inStream->Read(inStream, inBuf, &inSize)) + inPos = 0; + } + { + SRes res; + SizeT inProcessed = inSize - inPos; + SizeT outProcessed = OUT_BUF_SIZE - outPos; + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + ELzmaStatus status; + if (thereIsSize && outProcessed > unpackSize) + { + outProcessed = (SizeT)unpackSize; + finishMode = LZMA_FINISH_END; + } + + res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, + inBuf + inPos, &inProcessed, finishMode, &status); + inPos += inProcessed; + outPos += outProcessed; + unpackSize -= outProcessed; + + if (outStream) + if (outStream->Write(outStream, outBuf, outPos) != outPos) + return SZ_ERROR_WRITE; + + outPos = 0; + + if (res != SZ_OK || (thereIsSize && unpackSize == 0)) + return res; + + if (inProcessed == 0 && outProcessed == 0) + { + if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) + return SZ_ERROR_DATA; + return res; + } + } + } +} + + +static SRes Decode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream) +{ + UInt64 unpackSize; + int i; + SRes res = 0; + + CLzmaDec state; + + /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ + unsigned char header[LZMA_PROPS_SIZE + 8]; + + /* Read and parse header */ + + { + size_t size = sizeof(header); + RINOK(SeqInStream_ReadMax(inStream, header, &size)) + if (size != sizeof(header)) + return SZ_ERROR_INPUT_EOF; + } + unpackSize = 0; + for (i = 0; i < 8; i++) + unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8); + + LzmaDec_CONSTRUCT(&state) + RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)) + res = Decode2(&state, outStream, inStream, unpackSize); + LzmaDec_Free(&state, &g_Alloc); + return res; +} + +static SRes Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, UInt64 fileSize) +{ + CLzmaEncHandle enc; + SRes res; + CLzmaEncProps props; + + enc = LzmaEnc_Create(&g_Alloc); + if (enc == 0) + return SZ_ERROR_MEM; + + LzmaEncProps_Init(&props); + res = LzmaEnc_SetProps(enc, &props); + + if (res == SZ_OK) + { + Byte header[LZMA_PROPS_SIZE + 8]; + size_t headerSize = LZMA_PROPS_SIZE; + int i; + + res = LzmaEnc_WriteProperties(enc, header, &headerSize); + for (i = 0; i < 8; i++) + header[headerSize++] = (Byte)(fileSize >> (8 * i)); + if (outStream->Write(outStream, header, headerSize) != headerSize) + res = SZ_ERROR_WRITE; + else + { + if (res == SZ_OK) + res = LzmaEnc_Encode(enc, outStream, inStream, NULL, &g_Alloc, &g_Alloc); + } + } + LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); + return res; +} + + +int Z7_CDECL main(int numArgs, const char *args[]) +{ + CFileSeqInStream inStream; + CFileOutStream outStream; + char c; + int res; + int encodeMode; + BoolInt useOutFile = False; + + LzFindPrepare(); + + FileSeqInStream_CreateVTable(&inStream); + File_Construct(&inStream.file); + inStream.wres = 0; + + FileOutStream_CreateVTable(&outStream); + File_Construct(&outStream.file); + outStream.wres = 0; + + if (numArgs == 1) + { + PrintHelp(); + return 0; + } + + if (numArgs < 3 || numArgs > 4 || strlen(args[1]) != 1) + return PrintUserError(); + + c = args[1][0]; + encodeMode = (c == 'e' || c == 'E'); + if (!encodeMode && c != 'd' && c != 'D') + return PrintUserError(); + + /* + { + size_t t4 = sizeof(UInt32); + size_t t8 = sizeof(UInt64); + if (t4 != 4 || t8 != 8) + return PrintError("Incorrect UInt32 or UInt64"); + } + */ + + { + const WRes wres = InFile_Open(&inStream.file, args[2]); + if (wres != 0) + return PrintError_WRes("Cannot open input file", wres); + } + + if (numArgs > 3) + { + WRes wres; + useOutFile = True; + wres = OutFile_Open(&outStream.file, args[3]); + if (wres != 0) + return PrintError_WRes("Cannot open output file", wres); + } + else if (encodeMode) + PrintUserError(); + + if (encodeMode) + { + UInt64 fileSize; + const WRes wres = File_GetLength(&inStream.file, &fileSize); + if (wres != 0) + return PrintError_WRes("Cannot get file length", wres); + res = Encode(&outStream.vt, &inStream.vt, fileSize); + } + else + { + res = Decode(&outStream.vt, useOutFile ? &inStream.vt : NULL); + } + + if (useOutFile) + File_Close(&outStream.file); + File_Close(&inStream.file); + + if (res != SZ_OK) + { + if (res == SZ_ERROR_MEM) + return PrintError(kCantAllocateMessage); + else if (res == SZ_ERROR_DATA) + return PrintError(kDataErrorMessage); + else if (res == SZ_ERROR_WRITE) + return PrintError_WRes(kCantWriteMessage, outStream.wres); + else if (res == SZ_ERROR_READ) + return PrintError_WRes(kCantReadMessage, inStream.wres); + return PrintErrorNumber(res); + } + return 0; +} diff -Nru p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.dsp p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsp --- p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsp 2025-02-05 06:00:00.000000000 +0000 @@ -0,0 +1,192 @@ +# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=LzmaUtil - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LzmaUtil.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LzmaUtil - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W4 /WX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7lzma.exe" + +!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7lzma.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LzmaUtil - Win32 Release" +# Name "LzmaUtil - Win32 Debug" +# Begin Source File + +SOURCE=..\..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zStream.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Alloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFind.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindMt.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindOpt.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaEnc.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=.\LzmaUtil.c +# End Source File +# Begin Source File + +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\Threads.c +# End Source File +# Begin Source File + +SOURCE=..\..\Threads.h +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.dsw p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsw --- p7zip-rar-16.02/C/Util/Lzma/LzmaUtil.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/LzmaUtil.dsw 2008-03-10 08:59:46.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LzmaUtil"=.\LzmaUtil.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/C/Util/Lzma/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/Precomp.h --- p7zip-rar-16.02/C/Util/Lzma/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/Lzma/makefile p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile --- p7zip-rar-16.02/C/Util/Lzma/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile 2021-11-01 11:00:38.000000000 +0000 @@ -0,0 +1,30 @@ +# MY_STATIC_LINK=1 +PROG = LZMAc.exe + +CFLAGS = $(CFLAGS) \ + +LIB_OBJS = \ + $O\LzmaUtil.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\LzFindOpt.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\7zFile.obj \ + $O\7zStream.obj \ + $O\Threads.obj \ + +OBJS = \ + $(LIB_OBJS) \ + $(C_OBJS) \ + +!include "../../../CPP/Build.mak" + +$(LIB_OBJS): $(*B).c + $(COMPL_O2) +$(C_OBJS): ../../$(*B).c + $(COMPL_O2) diff -Nru p7zip-rar-16.02/C/Util/Lzma/makefile.gcc p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile.gcc --- p7zip-rar-16.02/C/Util/Lzma/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/Lzma/makefile.gcc 2021-11-01 11:01:17.000000000 +0000 @@ -0,0 +1,21 @@ +PROG = 7lzma + +include ../../../CPP/7zip/LzmaDec_gcc.mak + + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $O/7zFile.o \ + $O/7zStream.o \ + $O/Alloc.o \ + $O/CpuArch.o \ + $O/LzFind.o \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/LzmaUtil.o \ + $O/Threads.o \ + + +include ../../7zip_gcc_c.mak diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.def p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.def --- p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.def 2008-03-09 09:56:31.000000000 +0000 @@ -0,0 +1,4 @@ +EXPORTS + LzmaCompress + LzmaUncompress + diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.dsp p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsp --- p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsp 2025-02-05 06:00:00.000000000 +0000 @@ -0,0 +1,206 @@ +# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=LzmaLib - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LzmaLib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LzmaLib.mak" CFG="LzmaLib - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LzmaLib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "LzmaLib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LzmaLib - Win32 Release" +# Name "LzmaLib - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\LzmaLib.def +# End Source File +# Begin Source File + +SOURCE=.\LzmaLibExports.c +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\Alloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFind.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindMt.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzFindOpt.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaEnc.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaLib.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaLib.h +# End Source File +# Begin Source File + +SOURCE=..\..\Precomp.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=..\..\Threads.c +# End Source File +# Begin Source File + +SOURCE=..\..\Threads.h +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.dsw p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsw --- p7zip-rar-16.02/C/Util/LzmaLib/LzmaLib.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLib.dsw 2008-03-09 11:06:56.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LzmaLib"=.\LzmaLib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/LzmaLibExports.c p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLibExports.c --- p7zip-rar-16.02/C/Util/LzmaLib/LzmaLibExports.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/LzmaLibExports.c 2023-03-05 17:00:00.000000000 +0000 @@ -0,0 +1,15 @@ +/* LzmaLibExports.c -- LZMA library DLL Entry point +2023-03-05 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "../../7zWindows.h" + +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved); +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) +{ + UNUSED_VAR(hInstance) + UNUSED_VAR(dwReason) + UNUSED_VAR(lpReserved) + return TRUE; +} diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/Precomp.c p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.c --- p7zip-rar-16.02/C/Util/LzmaLib/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.c 2013-01-23 18:00:00.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.h --- p7zip-rar-16.02/C/Util/LzmaLib/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/makefile p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/makefile --- p7zip-rar-16.02/C/Util/LzmaLib/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/makefile 2024-03-21 10:00:00.000000000 +0000 @@ -0,0 +1,59 @@ +MY_STATIC_LINK=1 +SLIB = sLZMA.lib +PROG = LZMA.dll +SLIBPATH = $O\$(SLIB) + +DEF_FILE = LzmaLib.def +CFLAGS = $(CFLAGS) \ + +LIB_OBJS = \ + $O\LzmaLibExports.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\LzmaLib.obj \ + $O\Threads.obj \ + +!include "../../../CPP/7zip/LzFindOpt.mak" +!include "../../../CPP/7zip/LzmaDec.mak" + +OBJS = \ + $O\Precomp.obj \ + $(LIB_OBJS) \ + $(C_OBJS) \ + $(ASM_OBJS) \ + $O\resource.res + +!include "../../../CPP/Build.mak" + +$(SLIBPATH): $O $(OBJS) + lib -out:$(SLIBPATH) $(OBJS) $(LIBS) + + +MAK_SINGLE_FILE = 1 + +$O\Precomp.obj: Precomp.c + $(CCOMPL_PCH) + +!IFDEF MAK_SINGLE_FILE + +$(LIB_OBJS): $(*B).c + $(CCOMPL_USE) +$(C_OBJS): ../../$(*B).c + $(CCOMPL_USE) + +!ELSE + +{.}.c{$O}.obj:: + $(CCOMPLB_USE) +{../../../C}.c{$O}.obj:: + $(CCOMPLB_USE) + +!ENDIF + +!include "../../Asm_c.mak" diff -Nru p7zip-rar-16.02/C/Util/LzmaLib/resource.rc p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/resource.rc --- p7zip-rar-16.02/C/Util/LzmaLib/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/LzmaLib/resource.rc 2011-04-18 17:32:26.000000000 +0000 @@ -0,0 +1,3 @@ +#include "../../7zVersion.rc" + +MY_VERSION_INFO_DLL("LZMA library", "LZMA") diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/Precomp.c p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.c --- p7zip-rar-16.02/C/Util/SfxSetup/Precomp.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.c 2013-01-23 17:42:30.000000000 +0000 @@ -0,0 +1,4 @@ +/* Precomp.c -- StdAfx +2013-01-21 : Igor Pavlov : Public domain */ + +#include "Precomp.h" diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/Precomp.h p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.h --- p7zip-rar-16.02/C/Util/SfxSetup/Precomp.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/Precomp.h 2024-01-23 08:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +/* Precomp.h -- Precomp +2024-01-23 : Igor Pavlov : Public domain */ + +// #ifndef ZIP7_INC_PRECOMP_LOC_H +// #define ZIP7_INC_PRECOMP_LOC_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../Precomp.h" + +// #endif diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.c p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.c --- p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.c 2024-01-24 17:00:00.000000000 +0000 @@ -0,0 +1,657 @@ +/* SfxSetup.c - 7z SFX Setup +2024-01-24 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifndef UNICODE +#define UNICODE +#endif + +#ifndef _UNICODE +#define _UNICODE +#endif + +#ifdef _CONSOLE +#include +#endif + +#include "../../7z.h" +#include "../../7zAlloc.h" +#include "../../7zCrc.h" +#include "../../7zFile.h" +#include "../../CpuArch.h" +#include "../../DllSecur.h" + +#define k_EXE_ExtIndex 2 + +#define kInputBufSize ((size_t)1 << 18) + + +#define wcscat lstrcatW +#define wcslen (size_t)lstrlenW +#define wcscpy lstrcpyW +// wcsncpy() and lstrcpynW() work differently. We don't use them. + +static const char * const kExts[] = +{ + "bat" + , "cmd" + , "exe" + , "inf" + , "msi" + #ifdef UNDER_CE + , "cab" + #endif + , "html" + , "htm" +}; + +static const char * const kNames[] = +{ + "setup" + , "install" + , "run" + , "start" +}; + +static unsigned FindExt(const wchar_t *s, unsigned *extLen) +{ + unsigned len = (unsigned)wcslen(s); + unsigned i; + for (i = len; i > 0; i--) + { + if (s[i - 1] == '.') + { + *extLen = len - i; + return i - 1; + } + } + *extLen = 0; + return len; +} + +#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) + +static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len) +{ + unsigned i; + for (i = 0; i < num; i++) + { + const char *item = items[i]; + const unsigned itemLen = (unsigned)strlen(item); + unsigned j; + if (len != itemLen) + continue; + for (j = 0; j < len; j++) + { + const unsigned c = (Byte)item[j]; + if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j]) + break; + } + if (j == len) + return i; + } + return i; +} + +#ifdef _CONSOLE +static BOOL WINAPI HandlerRoutine(DWORD ctrlType) +{ + UNUSED_VAR(ctrlType); + return TRUE; +} +#endif + + +#ifdef _CONSOLE +static void PrintStr(const char *s) +{ + fputs(s, stdout); +} +#endif + +static void PrintErrorMessage(const char *message) +{ + #ifdef _CONSOLE + PrintStr("\n7-Zip Error: "); + PrintStr(message); + PrintStr("\n"); + #else + #ifdef UNDER_CE + WCHAR messageW[256 + 4]; + unsigned i; + for (i = 0; i < 256 && message[i] != 0; i++) + messageW[i] = message[i]; + messageW[i] = 0; + MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR); + #else + MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR); + #endif + #endif +} + +static WRes MyCreateDir(const WCHAR *name) +{ + return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); +} + +#ifdef UNDER_CE +#define kBufferSize (1 << 13) +#else +#define kBufferSize (1 << 15) +#endif + +#define kSignatureSearchLimit (1 << 22) + +static BoolInt FindSignature(CSzFile *stream, UInt64 *resPos) +{ + Byte buf[kBufferSize]; + size_t numPrevBytes = 0; + *resPos = 0; + for (;;) + { + size_t processed, pos; + if (*resPos > kSignatureSearchLimit) + return False; + processed = kBufferSize - numPrevBytes; + if (File_Read(stream, buf + numPrevBytes, &processed) != 0) + return False; + processed += numPrevBytes; + if (processed < k7zStartHeaderSize || + (processed == k7zStartHeaderSize && numPrevBytes != 0)) + return False; + processed -= k7zStartHeaderSize; + for (pos = 0; pos <= processed; pos++) + { + for (; pos <= processed && buf[pos] != '7'; pos++); + if (pos > processed) + break; + if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) + if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8)) + { + *resPos += pos; + return True; + } + } + *resPos += processed; + numPrevBytes = k7zStartHeaderSize; + memmove(buf, buf + processed, k7zStartHeaderSize); + } +} + +static BoolInt DoesFileOrDirExist(const WCHAR *path) +{ + WIN32_FIND_DATAW fd; + HANDLE handle; + handle = FindFirstFileW(path, &fd); + if (handle == INVALID_HANDLE_VALUE) + return False; + FindClose(handle); + return True; +} + +static WRes RemoveDirWithSubItems(WCHAR *path) +{ + WIN32_FIND_DATAW fd; + HANDLE handle; + WRes res = 0; + const size_t len = wcslen(path); + wcscpy(path + len, L"*"); + handle = FindFirstFileW(path, &fd); + path[len] = L'\0'; + if (handle == INVALID_HANDLE_VALUE) + return GetLastError(); + + for (;;) + { + if (wcscmp(fd.cFileName, L".") != 0 && + wcscmp(fd.cFileName, L"..") != 0) + { + wcscpy(path + len, fd.cFileName); + if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + wcscat(path, WSTRING_PATH_SEPARATOR); + res = RemoveDirWithSubItems(path); + } + else + { + SetFileAttributesW(path, 0); + if (DeleteFileW(path) == 0) + res = GetLastError(); + } + + if (res != 0) + break; + } + + if (!FindNextFileW(handle, &fd)) + { + res = GetLastError(); + if (res == ERROR_NO_MORE_FILES) + res = 0; + break; + } + } + + path[len] = L'\0'; + FindClose(handle); + if (res == 0) + { + if (!RemoveDirectoryW(path)) + res = GetLastError(); + } + return res; +} + +#ifdef _CONSOLE +int Z7_CDECL main(void) +#else +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + lpCmdLine, int nCmdShow) +#endif +{ + CFileInStream archiveStream; + CLookToRead2 lookStream; + CSzArEx db; + SRes res = SZ_OK; + ISzAlloc allocImp; + ISzAlloc allocTempImp; + WCHAR sfxPath[MAX_PATH + 2]; + WCHAR path[MAX_PATH * 3 + 2]; + #ifndef UNDER_CE + WCHAR workCurDir[MAX_PATH + 32]; + #endif + size_t pathLen; + DWORD winRes; + const wchar_t *cmdLineParams; + const char *errorMessage = NULL; + BoolInt useShellExecute = True; + DWORD exitCode = 0; + + LoadSecurityDlls(); + + #ifdef _CONSOLE + SetConsoleCtrlHandler(HandlerRoutine, TRUE); + #else + UNUSED_VAR(hInstance) + UNUSED_VAR(hPrevInstance) + UNUSED_VAR(lpCmdLine) + UNUSED_VAR(nCmdShow) + #endif + + CrcGenerateTable(); + + allocImp.Alloc = SzAlloc; + allocImp.Free = SzFree; + + allocTempImp.Alloc = SzAllocTemp; + allocTempImp.Free = SzFreeTemp; + + FileInStream_CreateVTable(&archiveStream); + LookToRead2_CreateVTable(&lookStream, False); + lookStream.buf = NULL; + + winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH); + if (winRes == 0 || winRes > MAX_PATH) + return 1; + { + cmdLineParams = GetCommandLineW(); + #ifndef UNDER_CE + { + BoolInt quoteMode = False; + for (;; cmdLineParams++) + { + const wchar_t c = *cmdLineParams; + if (c == L'\"') + quoteMode = !quoteMode; + else if (c == 0 || (c == L' ' && !quoteMode)) + break; + } + } + #endif + } + + { + unsigned i; + DWORD d; + winRes = GetTempPathW(MAX_PATH, path); + if (winRes == 0 || winRes > MAX_PATH) + return 1; + pathLen = wcslen(path); + d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); + + for (i = 0;; i++, d += GetTickCount()) + { + if (i >= 100) + { + res = SZ_ERROR_FAIL; + break; + } + wcscpy(path + pathLen, L"7z"); + + { + wchar_t *s = path + wcslen(path); + UInt32 value = d; + unsigned k; + for (k = 0; k < 8; k++) + { + const unsigned t = value & 0xF; + value >>= 4; + s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[k] = '\0'; + } + + if (DoesFileOrDirExist(path)) + continue; + if (CreateDirectoryW(path, NULL)) + { + wcscat(path, WSTRING_PATH_SEPARATOR); + pathLen = wcslen(path); + break; + } + if (GetLastError() != ERROR_ALREADY_EXISTS) + { + res = SZ_ERROR_FAIL; + break; + } + } + + #ifndef UNDER_CE + wcscpy(workCurDir, path); + #endif + if (res != SZ_OK) + errorMessage = "Can't create temp folder"; + } + + if (res != SZ_OK) + { + if (!errorMessage) + errorMessage = "Error"; + PrintErrorMessage(errorMessage); + return 1; + } + + if (InFile_OpenW(&archiveStream.file, sfxPath) != 0) + { + errorMessage = "can not open input file"; + res = SZ_ERROR_FAIL; + } + else + { + UInt64 pos = 0; + if (!FindSignature(&archiveStream.file, &pos)) + res = SZ_ERROR_FAIL; + else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0) + res = SZ_ERROR_FAIL; + if (res != 0) + errorMessage = "Can't find 7z archive"; + } + + if (res == SZ_OK) + { + lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize); + if (!lookStream.buf) + res = SZ_ERROR_MEM; + else + { + lookStream.bufSize = kInputBufSize; + lookStream.realStream = &archiveStream.vt; + LookToRead2_INIT(&lookStream) + } + } + + SzArEx_Init(&db); + + if (res == SZ_OK) + { + res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp); + } + + if (res == SZ_OK) + { + UInt32 executeFileIndex = (UInt32)(Int32)-1; + UInt32 minPrice = 1 << 30; + UInt32 i; + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ + Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ + size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ + + for (i = 0; i < db.NumFiles; i++) + { + size_t offset = 0; + size_t outSizeProcessed = 0; + WCHAR *temp; + + if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH) + { + res = SZ_ERROR_FAIL; + break; + } + + temp = path + pathLen; + + SzArEx_GetFileNameUtf16(&db, i, (UInt16 *)temp); + { + res = SzArEx_Extract(&db, &lookStream.vt, i, + &blockIndex, &outBuffer, &outBufferSize, + &offset, &outSizeProcessed, + &allocImp, &allocTempImp); + if (res != SZ_OK) + break; + } + { + CSzFile outFile; + size_t processedSize; + size_t j; + size_t nameStartPos = 0; + for (j = 0; temp[j] != 0; j++) + { + if (temp[j] == '/') + { + temp[j] = 0; + MyCreateDir(path); + temp[j] = CHAR_PATH_SEPARATOR; + nameStartPos = j + 1; + } + } + + if (SzArEx_IsDir(&db, i)) + { + MyCreateDir(path); + continue; + } + else + { + unsigned extLen; + const WCHAR *name = temp + nameStartPos; + unsigned len = (unsigned)wcslen(name); + const unsigned nameLen = FindExt(temp + nameStartPos, &extLen); + const unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen); + const unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen); + + const unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12)); + if (minPrice > price) + { + minPrice = price; + executeFileIndex = i; + useShellExecute = (extPrice != k_EXE_ExtIndex); + } + + if (DoesFileOrDirExist(path)) + { + errorMessage = "Duplicate file"; + res = SZ_ERROR_FAIL; + break; + } + if (OutFile_OpenW(&outFile, path)) + { + errorMessage = "Can't open output file"; + res = SZ_ERROR_FAIL; + break; + } + } + + processedSize = outSizeProcessed; + if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) + { + errorMessage = "Can't write output file"; + res = SZ_ERROR_FAIL; + } + + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.MTime, i)) + { + const CNtfsFileTime *t = db.MTime.Vals + i; + FILETIME mTime; + mTime.dwLowDateTime = t->Low; + mTime.dwHighDateTime = t->High; + SetFileTime(outFile.handle, NULL, NULL, &mTime); + } + #endif + + { + const WRes res2 = File_Close(&outFile); + if (res != SZ_OK) + break; + if (res2 != 0) + { + errorMessage = "Can't close output file"; + res = SZ_ERROR_FAIL; + break; + } + } + #ifdef USE_WINDOWS_FILE + if (SzBitWithVals_Check(&db.Attribs, i)) + SetFileAttributesW(path, db.Attribs.Vals[i]); + #endif + } + } + + if (res == SZ_OK) + { + if (executeFileIndex == (UInt32)(Int32)-1) + { + errorMessage = "There is no file to execute"; + res = SZ_ERROR_FAIL; + } + else + { + WCHAR *temp = path + pathLen; + UInt32 j; + SzArEx_GetFileNameUtf16(&db, executeFileIndex, (UInt16 *)temp); + for (j = 0; temp[j] != 0; j++) + if (temp[j] == '/') + temp[j] = CHAR_PATH_SEPARATOR; + } + } + ISzAlloc_Free(&allocImp, outBuffer); + } + + SzArEx_Free(&db, &allocImp); + + ISzAlloc_Free(&allocImp, lookStream.buf); + + File_Close(&archiveStream.file); + + if (res == SZ_OK) + { + HANDLE hProcess = 0; + + #ifndef UNDER_CE + WCHAR oldCurDir[MAX_PATH + 2]; + oldCurDir[0] = 0; + { + const DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir); + if (needLen == 0 || needLen > MAX_PATH) + oldCurDir[0] = 0; + SetCurrentDirectory(workCurDir); + } + #endif + + if (useShellExecute) + { + SHELLEXECUTEINFO ei; + UINT32 executeRes; + BOOL success; + + memset(&ei, 0, sizeof(ei)); + ei.cbSize = sizeof(ei); + ei.lpFile = path; + ei.fMask = SEE_MASK_NOCLOSEPROCESS + #ifndef UNDER_CE + | SEE_MASK_FLAG_DDEWAIT + #endif + /* | SEE_MASK_NO_CONSOLE */ + ; + if (wcslen(cmdLineParams) != 0) + ei.lpParameters = cmdLineParams; + ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */ + success = ShellExecuteEx(&ei); + executeRes = (UINT32)(UINT_PTR)ei.hInstApp; + if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */ + res = SZ_ERROR_FAIL; + else + hProcess = ei.hProcess; + } + else + { + STARTUPINFOW si; + PROCESS_INFORMATION pi; + WCHAR cmdLine[MAX_PATH * 3]; + + wcscpy(cmdLine, path); + wcscat(cmdLine, cmdLineParams); + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) + res = SZ_ERROR_FAIL; + else + { + CloseHandle(pi.hThread); + hProcess = pi.hProcess; + } + } + + if (hProcess != 0) + { + WaitForSingleObject(hProcess, INFINITE); + if (!GetExitCodeProcess(hProcess, &exitCode)) + exitCode = 1; + CloseHandle(hProcess); + } + + #ifndef UNDER_CE + SetCurrentDirectory(oldCurDir); + #endif + } + + path[pathLen] = L'\0'; + RemoveDirWithSubItems(path); + + if (res == SZ_OK) + return (int)exitCode; + + { + if (res == SZ_ERROR_UNSUPPORTED) + errorMessage = "Decoder doesn't support this archive"; + else if (res == SZ_ERROR_MEM) + errorMessage = "Can't allocate required memory"; + else if (res == SZ_ERROR_CRC) + errorMessage = "CRC error"; + else + { + if (!errorMessage) + errorMessage = "ERROR"; + } + + if (errorMessage) + PrintErrorMessage(errorMessage); + } + return 1; +} diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.dsp p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsp --- p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsp 2016-06-03 10:47:49.000000000 +0000 @@ -0,0 +1,231 @@ +# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=SfxSetup - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SfxSetup.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SfxSetup.mak" CFG="SfxSetup - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SfxSetup - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "SfxSetup - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "SfxSetup - Win32 Release" +# Name "SfxSetup - Win32 Debug" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\7z.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zAlloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zArcIn.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zCrcOpt.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zFile.h +# End Source File +# Begin Source File + +SOURCE=..\..\7zStream.c +# End Source File +# Begin Source File + +SOURCE=..\..\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.c +# End Source File +# Begin Source File + +SOURCE=..\..\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\Bra86.c +# End Source File +# Begin Source File + +SOURCE=..\..\BraIA64.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.c +# End Source File +# Begin Source File + +SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\DllSecur.c +# End Source File +# Begin Source File + +SOURCE=..\..\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.c +# End Source File +# Begin Source File + +SOURCE=..\..\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.c +# End Source File +# Begin Source File + +SOURCE=..\..\LzmaDec.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Precomp.c +# ADD CPP /Yc"Precomp.h" +# End Source File +# Begin Source File + +SOURCE=.\Precomp.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\SfxSetup.c +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.dsw p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsw --- p7zip-rar-16.02/C/Util/SfxSetup/SfxSetup.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/SfxSetup.dsw 2010-10-08 05:19:13.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SfxSetup"=.\SfxSetup.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/makefile p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile --- p7zip-rar-16.02/C/Util/SfxSetup/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile 2024-03-21 10:00:00.000000000 +0000 @@ -0,0 +1,44 @@ +PROG = 7zS2.sfx +MY_FIXED = 1 + +CFLAGS = $(CFLAGS) \ + -DZ7_EXTRACT_ONLY \ + +C_OBJS = \ + $O\7zAlloc.obj \ + $O\7zArcIn.obj \ + $O\7zBuf.obj \ + $O\7zBuf2.obj \ + $O\7zFile.obj \ + $O\7zDec.obj \ + $O\7zStream.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\DllSecur.obj \ + $O\Lzma2Dec.obj \ + $O\LzmaDec.obj \ + +7Z_OBJS = \ + $O\SfxSetup.obj \ + +!include "../../../CPP/7zip/Crc.mak" +# !include "../../../CPP/7zip/LzmaDec.mak" + +OBJS = \ + $(7Z_OBJS) \ + $(C_OBJS) \ + $(ASM_OBJS) \ + $O\resource.res + +!include "../../../CPP/Build.mak" + +$(7Z_OBJS): $(*B).c + $(COMPL_O1) +$(C_OBJS): ../../$(*B).c + $(COMPL_O1) + +!include "../../Asm_c.mak" diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/makefile_con p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile_con --- p7zip-rar-16.02/C/Util/SfxSetup/makefile_con 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/makefile_con 2023-04-04 13:00:00.000000000 +0000 @@ -0,0 +1,40 @@ +PROG = 7zS2con.sfx +MY_FIXED = 1 + +CFLAGS = $(CFLAGS) -D_CONSOLE \ + -DZ7_EXTRACT_ONLY \ + +C_OBJS = \ + $O\7zAlloc.obj \ + $O\7zArcIn.obj \ + $O\7zBuf.obj \ + $O\7zBuf2.obj \ + $O\7zCrc.obj \ + $O\7zCrcOpt.obj \ + $O\7zFile.obj \ + $O\7zDec.obj \ + $O\7zStream.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\DllSecur.obj \ + $O\Lzma2Dec.obj \ + $O\LzmaDec.obj \ + +7Z_OBJS = \ + $O\SfxSetup.obj \ + +OBJS = \ + $(7Z_OBJS) \ + $(C_OBJS) \ + $O\resource.res + +!include "../../../CPP/Build.mak" + +$(7Z_OBJS): $(*B).c + $(COMPL_O1) +$(C_OBJS): ../../$(*B).c + $(COMPL_O1) diff -Nru p7zip-rar-16.02/C/Util/SfxSetup/resource.rc p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/resource.rc --- p7zip-rar-16.02/C/Util/SfxSetup/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/resource.rc 2011-04-18 17:31:56.000000000 +0000 @@ -0,0 +1,5 @@ +#include "../../7zVersion.rc" + +MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx") + +1 ICON "setup.ico" Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/C/Util/SfxSetup/setup.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/C/Util/SfxSetup/setup.ico differ diff -Nru p7zip-rar-16.02/C/Xxh64.c p7zip-rar-16.02+really25.00+ds/C/Xxh64.c --- p7zip-rar-16.02/C/Xxh64.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Xxh64.c 2023-08-18 08:00:00.000000000 +0000 @@ -0,0 +1,327 @@ +/* Xxh64.c -- XXH64 hash calculation +original code: Copyright (c) Yann Collet. +2023-08-18 : modified by Igor Pavlov. +This source code is licensed under BSD 2-Clause License. +*/ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "RotateDefs.h" +#include "Xxh64.h" + +#define Z7_XXH_PRIME64_1 UINT64_CONST(0x9E3779B185EBCA87) +#define Z7_XXH_PRIME64_2 UINT64_CONST(0xC2B2AE3D27D4EB4F) +#define Z7_XXH_PRIME64_3 UINT64_CONST(0x165667B19E3779F9) +#define Z7_XXH_PRIME64_4 UINT64_CONST(0x85EBCA77C2B2AE63) +#define Z7_XXH_PRIME64_5 UINT64_CONST(0x27D4EB2F165667C5) + +void Xxh64State_Init(CXxh64State *p) +{ + const UInt64 seed = 0; + p->v[0] = seed + Z7_XXH_PRIME64_1 + Z7_XXH_PRIME64_2; + p->v[1] = seed + Z7_XXH_PRIME64_2; + p->v[2] = seed; + p->v[3] = seed - Z7_XXH_PRIME64_1; +} + +#if !defined(MY_CPU_64BIT) && defined(MY_CPU_X86) && defined(_MSC_VER) + #define Z7_XXH64_USE_ASM +#endif + +#if !defined(MY_CPU_64BIT) && defined(MY_CPU_X86) \ + && defined(Z7_MSC_VER_ORIGINAL) && Z7_MSC_VER_ORIGINAL > 1200 +/* we try to avoid __allmul calls in MSVC for 64-bit multiply. + But MSVC6 still uses __allmul for our code. + So for MSVC6 we use default 64-bit multiply without our optimization. +*/ +#define LOW32(b) ((UInt32)(b & 0xffffffff)) +/* MSVC compiler (MSVC > 1200) can use "mul" instruction + without __allmul for our MY_emulu MACRO. + MY_emulu is similar to __emulu(a, b) MACRO */ +#define MY_emulu(a, b) ((UInt64)(a) * (b)) +#define MY_SET_HIGH32(a) ((UInt64)(a) << 32) +#define MY_MUL32_SET_HIGH32(a, b) MY_SET_HIGH32((UInt32)(a) * (UInt32)(b)) +// /* +#define MY_MUL64(a, b) \ + ( MY_emulu((UInt32)(a), LOW32(b)) + \ + MY_SET_HIGH32( \ + (UInt32)((a) >> 32) * LOW32(b) + \ + (UInt32)(a) * (UInt32)((b) >> 32) \ + )) +// */ +/* +#define MY_MUL64(a, b) \ + ( MY_emulu((UInt32)(a), LOW32(b)) \ + + MY_MUL32_SET_HIGH32((a) >> 32, LOW32(b)) + \ + + MY_MUL32_SET_HIGH32(a, (b) >> 32) \ + ) +*/ + +#define MY_MUL_32_64(a32, b) \ + ( MY_emulu((UInt32)(a32), LOW32(b)) \ + + MY_MUL32_SET_HIGH32(a32, (b) >> 32) \ + ) + +#else +#define MY_MUL64(a, b) ((a) * (b)) +#define MY_MUL_32_64(a32, b) ((a32) * (UInt64)(b)) +#endif + + +static +Z7_FORCE_INLINE +UInt64 Xxh64_Round(UInt64 acc, UInt64 input) +{ + acc += MY_MUL64(input, Z7_XXH_PRIME64_2); + acc = Z7_ROTL64(acc, 31); + return MY_MUL64(acc, Z7_XXH_PRIME64_1); +} + +static UInt64 Xxh64_Merge(UInt64 acc, UInt64 val) +{ + acc ^= Xxh64_Round(0, val); + return MY_MUL64(acc, Z7_XXH_PRIME64_1) + Z7_XXH_PRIME64_4; +} + + +#ifdef Z7_XXH64_USE_ASM + +#define Z7_XXH_PRIME64_1_HIGH 0x9E3779B1 +#define Z7_XXH_PRIME64_1_LOW 0x85EBCA87 +#define Z7_XXH_PRIME64_2_HIGH 0xC2B2AE3D +#define Z7_XXH_PRIME64_2_LOW 0x27D4EB4F + +void +Z7_NO_INLINE +__declspec(naked) +Z7_FASTCALL +Xxh64State_UpdateBlocks(CXxh64State *p, const void *data, const void *end) +{ + #if !defined(__clang__) + UNUSED_VAR(p) + UNUSED_VAR(data) + UNUSED_VAR(end) + #endif + __asm push ebx + __asm push ebp + __asm push esi + __asm push edi + + #define STACK_OFFSET 4 * 8 + __asm sub esp, STACK_OFFSET + +#define COPY_1(n) \ + __asm mov eax, [ecx + n * 4] \ + __asm mov [esp + n * 4], eax \ + +#define COPY_2(n) \ + __asm mov eax, [esp + n * 4] \ + __asm mov [ecx + n * 4], eax \ + + COPY_1(0) + __asm mov edi, [ecx + 1 * 4] \ + COPY_1(2) + COPY_1(3) + COPY_1(4) + COPY_1(5) + COPY_1(6) + COPY_1(7) + + __asm mov esi, edx \ + __asm mov [esp + 0 * 8 + 4], ecx + __asm mov ecx, Z7_XXH_PRIME64_2_LOW \ + __asm mov ebp, Z7_XXH_PRIME64_1_LOW \ + +#define R(n, state1, state1_reg) \ + __asm mov eax, [esi + n * 8] \ + __asm imul ebx, eax, Z7_XXH_PRIME64_2_HIGH \ + __asm add ebx, state1 \ + __asm mul ecx \ + __asm add edx, ebx \ + __asm mov ebx, [esi + n * 8 + 4] \ + __asm imul ebx, ecx \ + __asm add eax, [esp + n * 8] \ + __asm adc edx, ebx \ + __asm mov ebx, eax \ + __asm shld eax, edx, 31 \ + __asm shld edx, ebx, 31 \ + __asm imul state1_reg, eax, Z7_XXH_PRIME64_1_HIGH \ + __asm imul edx, ebp \ + __asm add state1_reg, edx \ + __asm mul ebp \ + __asm add state1_reg, edx \ + __asm mov [esp + n * 8], eax \ + +#define R2(n) \ + R(n, [esp + n * 8 + 4], ebx) \ + __asm mov [esp + n * 8 + 4], ebx \ + + __asm align 16 + __asm main_loop: + R(0, edi, edi) + R2(1) + R2(2) + R2(3) + __asm add esi, 32 + __asm cmp esi, [esp + STACK_OFFSET + 4 * 4 + 4] + __asm jne main_loop + + __asm mov ecx, [esp + 0 * 8 + 4] + + COPY_2(0) + __asm mov [ecx + 1 * 4], edi + COPY_2(2) + COPY_2(3) + COPY_2(4) + COPY_2(5) + COPY_2(6) + COPY_2(7) + + __asm add esp, STACK_OFFSET + __asm pop edi + __asm pop esi + __asm pop ebp + __asm pop ebx + __asm ret 4 +} + +#else + +void +Z7_NO_INLINE +Z7_FASTCALL +Xxh64State_UpdateBlocks(CXxh64State *p, const void *_data, const void *end) +{ + const Byte *data = (const Byte *)_data; + UInt64 v[4]; + v[0] = p->v[0]; + v[1] = p->v[1]; + v[2] = p->v[2]; + v[3] = p->v[3]; + do + { + v[0] = Xxh64_Round(v[0], GetUi64(data)); data += 8; + v[1] = Xxh64_Round(v[1], GetUi64(data)); data += 8; + v[2] = Xxh64_Round(v[2], GetUi64(data)); data += 8; + v[3] = Xxh64_Round(v[3], GetUi64(data)); data += 8; + } + while (data != end); + p->v[0] = v[0]; + p->v[1] = v[1]; + p->v[2] = v[2]; + p->v[3] = v[3]; +} + +#endif + +UInt64 Xxh64State_Digest(const CXxh64State *p, const void *_data, UInt64 count) +{ + UInt64 h = p->v[2]; + + if (count >= 32) + { + h = Z7_ROTL64(p->v[0], 1) + + Z7_ROTL64(p->v[1], 7) + + Z7_ROTL64(h, 12) + + Z7_ROTL64(p->v[3], 18); + h = Xxh64_Merge(h, p->v[0]); + h = Xxh64_Merge(h, p->v[1]); + h = Xxh64_Merge(h, p->v[2]); + h = Xxh64_Merge(h, p->v[3]); + } + else + h += Z7_XXH_PRIME64_5; + + h += count; + + // XXH64_finalize(): + { + unsigned cnt = (unsigned)count & 31; + const Byte *data = (const Byte *)_data; + while (cnt >= 8) + { + h ^= Xxh64_Round(0, GetUi64(data)); + data += 8; + h = Z7_ROTL64(h, 27); + h = MY_MUL64(h, Z7_XXH_PRIME64_1) + Z7_XXH_PRIME64_4; + cnt -= 8; + } + if (cnt >= 4) + { + const UInt32 v = GetUi32(data); + data += 4; + h ^= MY_MUL_32_64(v, Z7_XXH_PRIME64_1); + h = Z7_ROTL64(h, 23); + h = MY_MUL64(h, Z7_XXH_PRIME64_2) + Z7_XXH_PRIME64_3; + cnt -= 4; + } + while (cnt) + { + const UInt32 v = *data++; + h ^= MY_MUL_32_64(v, Z7_XXH_PRIME64_5); + h = Z7_ROTL64(h, 11); + h = MY_MUL64(h, Z7_XXH_PRIME64_1); + cnt--; + } + // XXH64_avalanche(h): + h ^= h >> 33; h = MY_MUL64(h, Z7_XXH_PRIME64_2); + h ^= h >> 29; h = MY_MUL64(h, Z7_XXH_PRIME64_3); + h ^= h >> 32; + return h; + } +} + + +void Xxh64_Init(CXxh64 *p) +{ + Xxh64State_Init(&p->state); + p->count = 0; + p->buf64[0] = 0; + p->buf64[1] = 0; + p->buf64[2] = 0; + p->buf64[3] = 0; +} + +void Xxh64_Update(CXxh64 *p, const void *_data, size_t size) +{ + const Byte *data = (const Byte *)_data; + unsigned cnt; + if (size == 0) + return; + cnt = (unsigned)p->count; + p->count += size; + + if (cnt &= 31) + { + unsigned rem = 32 - cnt; + Byte *dest = (Byte *)p->buf64 + cnt; + if (rem > size) + rem = (unsigned)size; + size -= rem; + cnt += rem; + // memcpy((Byte *)p->buf64 + cnt, data, rem); + do + *dest++ = *data++; + while (--rem); + if (cnt != 32) + return; + Xxh64State_UpdateBlocks(&p->state, p->buf64, &p->buf64[4]); + } + + if (size &= ~(size_t)31) + { + Xxh64State_UpdateBlocks(&p->state, data, data + size); + data += size; + } + + cnt = (unsigned)p->count & 31; + if (cnt) + { + // memcpy(p->buf64, data, cnt); + Byte *dest = (Byte *)p->buf64; + do + *dest++ = *data++; + while (--cnt); + } +} diff -Nru p7zip-rar-16.02/C/Xxh64.h p7zip-rar-16.02+really25.00+ds/C/Xxh64.h --- p7zip-rar-16.02/C/Xxh64.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Xxh64.h 2023-08-18 08:00:00.000000000 +0000 @@ -0,0 +1,50 @@ +/* Xxh64.h -- XXH64 hash calculation interfaces +2023-08-18 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XXH64_H +#define ZIP7_INC_XXH64_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define Z7_XXH64_BLOCK_SIZE (4 * 8) + +typedef struct +{ + UInt64 v[4]; +} CXxh64State; + +void Xxh64State_Init(CXxh64State *p); + +// end != data && end == data + Z7_XXH64_BLOCK_SIZE * numBlocks +void Z7_FASTCALL Xxh64State_UpdateBlocks(CXxh64State *p, const void *data, const void *end); + +/* +Xxh64State_Digest(): +data: + the function processes only + (totalCount & (Z7_XXH64_BLOCK_SIZE - 1)) bytes in (data): (smaller than 32 bytes). +totalCount: total size of hashed stream: + it includes total size of data processed by previous Xxh64State_UpdateBlocks() calls, + and it also includes current processed size in (data). +*/ +UInt64 Xxh64State_Digest(const CXxh64State *p, const void *data, UInt64 totalCount); + + +typedef struct +{ + CXxh64State state; + UInt64 count; + UInt64 buf64[4]; +} CXxh64; + +void Xxh64_Init(CXxh64 *p); +void Xxh64_Update(CXxh64 *p, const void *data, size_t size); + +#define Xxh64_Digest(p) \ + Xxh64State_Digest(&(p)->state, (p)->buf64, (p)->count) + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/Xz.c p7zip-rar-16.02+really25.00+ds/C/Xz.c --- p7zip-rar-16.02/C/Xz.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Xz.c 2024-03-01 07:00:00.000000000 +0000 @@ -1,90 +1,92 @@ -/* Xz.c - Xz -2015-05-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "7zCrc.h" -#include "CpuArch.h" -#include "Xz.h" -#include "XzCrc64.h" - -const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 }; -const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; - -unsigned Xz_WriteVarInt(Byte *buf, UInt64 v) -{ - unsigned i = 0; - do - { - buf[i++] = (Byte)((v & 0x7F) | 0x80); - v >>= 7; - } - while (v != 0); - buf[i - 1] &= 0x7F; - return i; -} - -void Xz_Construct(CXzStream *p) -{ - p->numBlocks = p->numBlocksAllocated = 0; - p->blocks = 0; - p->flags = 0; -} - -void Xz_Free(CXzStream *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->blocks); - p->numBlocks = p->numBlocksAllocated = 0; - p->blocks = 0; -} - -unsigned XzFlags_GetCheckSize(CXzStreamFlags f) -{ - unsigned t = XzFlags_GetCheckType(f); - return (t == 0) ? 0 : (4 << ((t - 1) / 3)); -} - -void XzCheck_Init(CXzCheck *p, unsigned mode) -{ - p->mode = mode; - switch (mode) - { - case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; - case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; - case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; - } -} - -void XzCheck_Update(CXzCheck *p, const void *data, size_t size) -{ - switch (p->mode) - { - case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; - case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; - case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; - } -} - -int XzCheck_Final(CXzCheck *p, Byte *digest) -{ - switch (p->mode) - { - case XZ_CHECK_CRC32: - SetUi32(digest, CRC_GET_DIGEST(p->crc)); - break; - case XZ_CHECK_CRC64: - { - int i; - UInt64 v = CRC64_GET_DIGEST(p->crc64); - for (i = 0; i < 8; i++, v >>= 8) - digest[i] = (Byte)(v & 0xFF); - break; - } - case XZ_CHECK_SHA256: - Sha256_Final(&p->sha, digest); - break; - default: - return 0; - } - return 1; -} +/* Xz.c - Xz +2024-03-01 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zCrc.h" +#include "CpuArch.h" +#include "Xz.h" +#include "XzCrc64.h" + +const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 }; +/* const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; */ + +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v) +{ + unsigned i = 0; + do + { + buf[i++] = (Byte)((v & 0x7F) | 0x80); + v >>= 7; + } + while (v != 0); + buf[(size_t)i - 1] &= 0x7F; + return i; +} + +void Xz_Construct(CXzStream *p) +{ + p->numBlocks = 0; + p->blocks = NULL; + p->flags = 0; +} + +void Xz_Free(CXzStream *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->blocks); + p->numBlocks = 0; + p->blocks = NULL; +} + +unsigned XzFlags_GetCheckSize(CXzStreamFlags f) +{ + unsigned t = XzFlags_GetCheckType(f); + return (t == 0) ? 0 : ((unsigned)4 << ((t - 1) / 3)); +} + +void XzCheck_Init(CXzCheck *p, unsigned mode) +{ + p->mode = mode; + switch (mode) + { + case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; + case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; + case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; + default: break; + } +} + +void XzCheck_Update(CXzCheck *p, const void *data, size_t size) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; + case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; + case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; + default: break; + } +} + +int XzCheck_Final(CXzCheck *p, Byte *digest) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: + SetUi32(digest, CRC_GET_DIGEST(p->crc)) + break; + case XZ_CHECK_CRC64: + { + int i; + UInt64 v = CRC64_GET_DIGEST(p->crc64); + for (i = 0; i < 8; i++, v >>= 8) + digest[i] = (Byte)(v & 0xFF); + break; + } + case XZ_CHECK_SHA256: + Sha256_Final(&p->sha, digest); + break; + default: + return 0; + } + return 1; +} diff -Nru p7zip-rar-16.02/C/Xz.h p7zip-rar-16.02+really25.00+ds/C/Xz.h --- p7zip-rar-16.02/C/Xz.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/Xz.h 2025-05-03 11:00:00.000000000 +0000 @@ -1,275 +1,542 @@ -/* Xz.h - Xz interface -2015-05-01 : Igor Pavlov : Public domain */ - -#ifndef __XZ_H -#define __XZ_H - -#include "Sha256.h" - -EXTERN_C_BEGIN - -#define XZ_ID_Subblock 1 -#define XZ_ID_Delta 3 -#define XZ_ID_X86 4 -#define XZ_ID_PPC 5 -#define XZ_ID_IA64 6 -#define XZ_ID_ARM 7 -#define XZ_ID_ARMT 8 -#define XZ_ID_SPARC 9 -#define XZ_ID_LZMA2 0x21 - -unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); -unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); - -/* ---------- xz block ---------- */ - -#define XZ_BLOCK_HEADER_SIZE_MAX 1024 - -#define XZ_NUM_FILTERS_MAX 4 -#define XZ_BF_NUM_FILTERS_MASK 3 -#define XZ_BF_PACK_SIZE (1 << 6) -#define XZ_BF_UNPACK_SIZE (1 << 7) - -#define XZ_FILTER_PROPS_SIZE_MAX 20 - -typedef struct -{ - UInt64 id; - UInt32 propsSize; - Byte props[XZ_FILTER_PROPS_SIZE_MAX]; -} CXzFilter; - -typedef struct -{ - UInt64 packSize; - UInt64 unpackSize; - Byte flags; - CXzFilter filters[XZ_NUM_FILTERS_MAX]; -} CXzBlock; - -#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) -#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) -#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) - -SRes XzBlock_Parse(CXzBlock *p, const Byte *header); -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes); - -/* ---------- xz stream ---------- */ - -#define XZ_SIG_SIZE 6 -#define XZ_FOOTER_SIG_SIZE 2 - -extern const Byte XZ_SIG[XZ_SIG_SIZE]; -extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; - -#define XZ_STREAM_FLAGS_SIZE 2 -#define XZ_STREAM_CRC_SIZE 4 - -#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) -#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) - -#define XZ_CHECK_MASK 0xF -#define XZ_CHECK_NO 0 -#define XZ_CHECK_CRC32 1 -#define XZ_CHECK_CRC64 4 -#define XZ_CHECK_SHA256 10 - -typedef struct -{ - unsigned mode; - UInt32 crc; - UInt64 crc64; - CSha256 sha; -} CXzCheck; - -void XzCheck_Init(CXzCheck *p, unsigned mode); -void XzCheck_Update(CXzCheck *p, const void *data, size_t size); -int XzCheck_Final(CXzCheck *p, Byte *digest); - -typedef UInt16 CXzStreamFlags; - -#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) -#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) -#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) -unsigned XzFlags_GetCheckSize(CXzStreamFlags f); - -SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream); - -typedef struct -{ - UInt64 unpackSize; - UInt64 totalSize; -} CXzBlockSizes; - -typedef struct -{ - CXzStreamFlags flags; - size_t numBlocks; - size_t numBlocksAllocated; - CXzBlockSizes *blocks; - UInt64 startOffset; -} CXzStream; - -void Xz_Construct(CXzStream *p); -void Xz_Free(CXzStream *p, ISzAlloc *alloc); - -#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) - -UInt64 Xz_GetUnpackSize(const CXzStream *p); -UInt64 Xz_GetPackSize(const CXzStream *p); - -typedef struct -{ - size_t num; - size_t numAllocated; - CXzStream *streams; -} CXzs; - -void Xzs_Construct(CXzs *p); -void Xzs_Free(CXzs *p, ISzAlloc *alloc); -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc); - -UInt64 Xzs_GetNumBlocks(const CXzs *p); -UInt64 Xzs_GetUnpackSize(const CXzs *p); - -typedef enum -{ - CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ - CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - CODER_STATUS_NOT_FINISHED, /* stream was not finished */ - CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ -} ECoderStatus; - -typedef enum -{ - CODER_FINISH_ANY, /* finish at any point */ - CODER_FINISH_END /* block must be finished at the end */ -} ECoderFinishMode; - -typedef struct _IStateCoder -{ - void *p; - void (*Free)(void *p, ISzAlloc *alloc); - SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc); - void (*Init)(void *p); - SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished); -} IStateCoder; - -#define MIXCODER_NUM_FILTERS_MAX 4 - -typedef struct -{ - ISzAlloc *alloc; - Byte *buf; - unsigned numCoders; - int finished[MIXCODER_NUM_FILTERS_MAX - 1]; - size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; - size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; - UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; - IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; -} CMixCoder; - -void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc); -void MixCoder_Free(CMixCoder *p); -void MixCoder_Init(CMixCoder *p); -SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId); -SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int srcWasFinished, - ECoderFinishMode finishMode, ECoderStatus *status); - -typedef enum -{ - XZ_STATE_STREAM_HEADER, - XZ_STATE_STREAM_INDEX, - XZ_STATE_STREAM_INDEX_CRC, - XZ_STATE_STREAM_FOOTER, - XZ_STATE_STREAM_PADDING, - XZ_STATE_BLOCK_HEADER, - XZ_STATE_BLOCK, - XZ_STATE_BLOCK_FOOTER -} EXzState; - -typedef struct -{ - EXzState state; - UInt32 pos; - unsigned alignPos; - unsigned indexPreSize; - - CXzStreamFlags streamFlags; - - UInt32 blockHeaderSize; - UInt64 packSize; - UInt64 unpackSize; - - UInt64 numBlocks; - UInt64 indexSize; - UInt64 indexPos; - UInt64 padSize; - - UInt64 numStartedStreams; - UInt64 numFinishedStreams; - UInt64 numTotalBlocks; - - UInt32 crc; - CMixCoder decoder; - CXzBlock block; - CXzCheck check; - CSha256 sha; - Byte shaDigest[SHA256_DIGEST_SIZE]; - Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; -} CXzUnpacker; - -void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc); -void XzUnpacker_Init(CXzUnpacker *p); -void XzUnpacker_Free(CXzUnpacker *p); - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - CODER_FINISH_ANY - use smallest number of input bytes - CODER_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - CODER_STATUS_NOT_FINISHED, - CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams, - call XzUnpacker_IsStreamWasFinished to check that current stream was finished - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_DATA - Data error - SZ_ERROR_UNSUPPORTED - Unsupported method or method properties - SZ_ERROR_CRC - CRC error - // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). - - SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: - - xz Stream Signature failure - - CRC32 of xz Stream Header is failed - - The size of Stream padding is not multiple of four bytes. - It's possible to get that error, if xz stream was finished and the stream - contains some another data. In that case you can call XzUnpacker_GetExtraSize() - function to get real size of xz stream. -*/ - - -SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, - ECoderStatus *status); - -Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p); - -/* -Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of -xz stream in two cases: -XzUnpacker_Code() returns: - res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT - res == SZ_ERROR_NO_ARCHIVE -*/ - -UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p); - -EXTERN_C_END - -#endif +/* Xz.h - Xz interface +Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_H +#define ZIP7_INC_XZ_H + +#include "Sha256.h" +#include "Delta.h" + +EXTERN_C_BEGIN + +#define XZ_ID_Subblock 1 +#define XZ_ID_Delta 3 +#define XZ_ID_X86 4 +#define XZ_ID_PPC 5 +#define XZ_ID_IA64 6 +#define XZ_ID_ARM 7 +#define XZ_ID_ARMT 8 +#define XZ_ID_SPARC 9 +#define XZ_ID_ARM64 0xa +#define XZ_ID_RISCV 0xb +#define XZ_ID_LZMA2 0x21 + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); + +/* ---------- xz block ---------- */ + +#define XZ_BLOCK_HEADER_SIZE_MAX 1024 + +#define XZ_NUM_FILTERS_MAX 4 +#define XZ_BF_NUM_FILTERS_MASK 3 +#define XZ_BF_PACK_SIZE (1 << 6) +#define XZ_BF_UNPACK_SIZE (1 << 7) + +#define XZ_FILTER_PROPS_SIZE_MAX 20 + +typedef struct +{ + UInt64 id; + UInt32 propsSize; + Byte props[XZ_FILTER_PROPS_SIZE_MAX]; +} CXzFilter; + +typedef struct +{ + UInt64 packSize; + UInt64 unpackSize; + Byte flags; + CXzFilter filters[XZ_NUM_FILTERS_MAX]; +} CXzBlock; + +#define XzBlock_GetNumFilters(p) (((unsigned)(p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) +#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) +#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) +#define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0) + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header); +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes); + +/* ---------- xz stream ---------- */ + +#define XZ_SIG_SIZE 6 +#define XZ_FOOTER_SIG_SIZE 2 + +extern const Byte XZ_SIG[XZ_SIG_SIZE]; + +/* +extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; +*/ + +#define XZ_FOOTER_SIG_0 'Y' +#define XZ_FOOTER_SIG_1 'Z' + +#define XZ_STREAM_FLAGS_SIZE 2 +#define XZ_STREAM_CRC_SIZE 4 + +#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) +#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) + +#define XZ_CHECK_MASK 0xF +#define XZ_CHECK_NO 0 +#define XZ_CHECK_CRC32 1 +#define XZ_CHECK_CRC64 4 +#define XZ_CHECK_SHA256 10 + +typedef struct +{ + unsigned mode; + UInt32 crc; + UInt64 crc64; + CSha256 sha; +} CXzCheck; + +void XzCheck_Init(CXzCheck *p, unsigned mode); +void XzCheck_Update(CXzCheck *p, const void *data, size_t size); +int XzCheck_Final(CXzCheck *p, Byte *digest); + +typedef UInt16 CXzStreamFlags; + +#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) +#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) +#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) +unsigned XzFlags_GetCheckSize(CXzStreamFlags f); + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream); + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; +} CXzBlockSizes; + +typedef struct +{ + CXzStreamFlags flags; + // Byte _pad[6]; + size_t numBlocks; + CXzBlockSizes *blocks; + UInt64 startOffset; +} CXzStream; + +#define Xz_CONSTRUCT(p) { (p)->numBlocks = 0; (p)->blocks = NULL; (p)->flags = 0; } +void Xz_Construct(CXzStream *p); +void Xz_Free(CXzStream *p, ISzAllocPtr alloc); + +#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) + +UInt64 Xz_GetUnpackSize(const CXzStream *p); +UInt64 Xz_GetPackSize(const CXzStream *p); + +typedef struct +{ + size_t num; + size_t numAllocated; + CXzStream *streams; +} CXzs; + +#define Xzs_CONSTRUCT(p) { (p)->num = 0; (p)->numAllocated = 0; (p)->streams = NULL; } +void Xzs_Construct(CXzs *p); +void Xzs_Free(CXzs *p, ISzAllocPtr alloc); +/* +Xzs_ReadBackward() must be called for empty CXzs object. +Xzs_ReadBackward() can return non empty object with (p->num != 0) even in case of error. +*/ +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr inStream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc); + +UInt64 Xzs_GetNumBlocks(const CXzs *p); +UInt64 Xzs_GetUnpackSize(const CXzs *p); + + +// ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + +typedef enum +{ + CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ + CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + CODER_STATUS_NOT_FINISHED, /* stream was not finished */ + CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ +} ECoderStatus; + + +// ECoderFinishMode values are identical to ELzmaFinishMode + +typedef enum +{ + CODER_FINISH_ANY, /* finish at any point */ + CODER_FINISH_END /* block must be finished at the end */ +} ECoderFinishMode; + + +typedef struct +{ + void *p; // state object; + void (*Free)(void *p, ISzAllocPtr alloc); + SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); + void (*Init)(void *p); + SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status); + SizeT (*Filter)(void *p, Byte *data, SizeT size); +} IStateCoder; + + +typedef struct +{ + UInt32 methodId; + UInt32 delta; + UInt32 ip; + UInt32 X86_State; + Byte delta_State[DELTA_STATE_SIZE]; +} CXzBcFilterStateBase; + +typedef SizeT (*Xz_Func_BcFilterStateBase_Filter)(CXzBcFilterStateBase *p, Byte *data, SizeT size); + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc); + + +#define MIXCODER_NUM_FILTERS_MAX 4 + +typedef struct +{ + ISzAllocPtr alloc; + Byte *buf; + unsigned numCoders; + + Byte *outBuf; + size_t outBufSize; + size_t outWritten; // is equal to lzmaDecoder.dicPos (in outBuf mode) + BoolInt wasFinished; + SRes res; + ECoderStatus status; + // BoolInt SingleBufMode; + + int finished[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; + UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; + SRes results[MIXCODER_NUM_FILTERS_MAX]; + IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; +} CMixCoder; + + +typedef enum +{ + XZ_STATE_STREAM_HEADER, + XZ_STATE_STREAM_INDEX, + XZ_STATE_STREAM_INDEX_CRC, + XZ_STATE_STREAM_FOOTER, + XZ_STATE_STREAM_PADDING, + XZ_STATE_BLOCK_HEADER, + XZ_STATE_BLOCK, + XZ_STATE_BLOCK_FOOTER +} EXzState; + + +typedef struct +{ + EXzState state; + unsigned pos; + unsigned alignPos; + unsigned indexPreSize; + + CXzStreamFlags streamFlags; + + unsigned blockHeaderSize; + UInt64 packSize; + UInt64 unpackSize; + + UInt64 numBlocks; // number of finished blocks in current stream + UInt64 indexSize; + UInt64 indexPos; + UInt64 padSize; + + UInt64 numStartedStreams; + UInt64 numFinishedStreams; + UInt64 numTotalBlocks; + + UInt32 crc; + CMixCoder decoder; + CXzBlock block; + CXzCheck check; + CSha256 sha; + + BoolInt parseMode; + BoolInt headerParsedOk; + BoolInt decodeToStreamSignature; + unsigned decodeOnlyOneBlock; + + Byte *outBuf; + size_t outBufSize; + size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked + + UInt32 shaDigest32[SHA256_DIGEST_SIZE / 4]; + Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; // it must be aligned for 4-bytes +} CXzUnpacker; + +/* alloc : aligned for cache line allocation is better */ +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc); +void XzUnpacker_Init(CXzUnpacker *p); +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize); +void XzUnpacker_Free(CXzUnpacker *p); + +/* + XzUnpacker + The sequence for decoding functions: + { + XzUnpacker_Construct() + [Decoding_Calls] + XzUnpacker_Free() + } + + [Decoding_Calls] + + There are 3 types of interfaces for [Decoding_Calls] calls: + + Interface-1 : Partial output buffers: + { + XzUnpacker_Init() + for() + { + XzUnpacker_Code(); + } + XzUnpacker_IsStreamWasFinished() + } + + Interface-2 : Direct output buffer: + Use it, if you know exact size of decoded data, and you need + whole xz unpacked data in one output buffer. + xz unpacker doesn't allocate additional buffer for lzma2 dictionary in that mode. + { + XzUnpacker_Init() + XzUnpacker_SetOutBufMode(); // to set output buffer and size + for() + { + XzUnpacker_Code(); // (dest = NULL) in XzUnpacker_Code() + } + XzUnpacker_IsStreamWasFinished() + } + + Interface-3 : Direct output buffer : One call full decoding + It unpacks whole input buffer to output buffer in one call. + It uses Interface-2 internally. + { + XzUnpacker_CodeFull() + XzUnpacker_IsStreamWasFinished() + } +*/ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + CODER_FINISH_ANY - use smallest number of input bytes + CODER_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + CODER_STATUS_NOT_FINISHED, + CODER_STATUS_NEEDS_MORE_INPUT - the decoder can return it in two cases: + 1) it needs more input data to finish current xz stream + 2) xz stream was finished successfully. But the decoder supports multiple + concatented xz streams. So it expects more input data for new xz streams. + Call XzUnpacker_IsStreamWasFinished() to check that latest xz stream was finished successfully. + + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_DATA - Data error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC error + // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + + SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: + - xz Stream Signature failure + - CRC32 of xz Stream Header is failed + - The size of Stream padding is not multiple of four bytes. + It's possible to get that error, if xz stream was finished and the stream + contains some another data. In that case you can call XzUnpacker_GetExtraSize() + function to get real size of xz stream. +*/ + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status); + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status); + +/* +If you decode full xz stream(s), then you can call XzUnpacker_IsStreamWasFinished() +after successful XzUnpacker_CodeFull() or after last call of XzUnpacker_Code(). +*/ + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p); + +/* +XzUnpacker_GetExtraSize() returns then number of unconfirmed bytes, + if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state. +These bytes can be some data after xz archive, or +it can be start of new xz stream. + +Call XzUnpacker_GetExtraSize() after XzUnpacker_Code() function to detect real size of +xz stream in two cases, if XzUnpacker_Code() returns: + res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT + res == SZ_ERROR_NO_ARCHIVE +*/ + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p); + + +/* + for random block decoding: + XzUnpacker_Init(); + set CXzUnpacker::streamFlags + XzUnpacker_PrepareToRandomBlockDecoding() + loop + { + XzUnpacker_Code() + XzUnpacker_IsBlockFinished() + } +*/ + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p); +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p); + +#define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags)) + + + + + + +/* ---- Single-Thread and Multi-Thread xz Decoding with Input/Output Streams ---- */ + +/* + if (CXzDecMtProps::numThreads > 1), the decoder can try to use + Multi-Threading. The decoder analyses xz block header, and if + there are pack size and unpack size values stored in xz block header, + the decoder reads compressed data of block to internal buffers, + and then it can start parallel decoding, if there are another blocks. + The decoder can switch back to Single-Thread decoding after some conditions. + + The sequence of calls for xz decoding with in/out Streams: + { + XzDecMt_Create() + XzDecMtProps_Init(XzDecMtProps) to set default values of properties + // then you can change some XzDecMtProps parameters with required values + // here you can set the number of threads and (memUseMax) - the maximum + Memory usage for multithreading decoding. + for() + { + XzDecMt_Decode() // one call per one file + } + XzDecMt_Destroy() + } +*/ + + +typedef struct +{ + size_t inBufSize_ST; // size of input buffer for Single-Thread decoding + size_t outStep_ST; // size of output buffer for Single-Thread decoding + BoolInt ignoreErrors; // if set to 1, the decoder can ignore some errors and it skips broken parts of data. + + #ifndef Z7_ST + unsigned numThreads; // the number of threads for Multi-Thread decoding. if (umThreads == 1) it will use Single-thread decoding + size_t inBufSize_MT; // size of small input data buffers for Multi-Thread decoding. Big number of such small buffers can be created + size_t memUseMax; // the limit of total memory usage for Multi-Thread decoding. + // it's recommended to set (memUseMax) manually to value that is smaller of total size of RAM in computer. + #endif +} CXzDecMtProps; + +void XzDecMtProps_Init(CXzDecMtProps *p); + +typedef struct CXzDecMt CXzDecMt; +typedef CXzDecMt * CXzDecMtHandle; +// Z7_DECLARE_HANDLE(CXzDecMtHandle) + +/* + alloc : XzDecMt uses CAlignOffsetAlloc internally for addresses allocated by (alloc). + allocMid : for big allocations, aligned allocation is better +*/ + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); +void XzDecMt_Destroy(CXzDecMtHandle p); + + +typedef struct +{ + Byte UnpackSize_Defined; + Byte NumStreams_Defined; + Byte NumBlocks_Defined; + + Byte DataAfterEnd; // there are some additional data after good xz streams, and that data is not new xz stream. + Byte DecodingTruncated; // Decoding was Truncated, we need only partial output data + + UInt64 InSize; // pack size processed. That value doesn't include the data after + // end of xz stream, if that data was not correct + UInt64 OutSize; + + UInt64 NumStreams; + UInt64 NumBlocks; + + SRes DecodeRes; // the error code of xz streams data decoding + SRes ReadRes; // error code from ISeqInStream:Read() + SRes ProgressRes; // error code from ICompressProgress:Progress() + + SRes CombinedRes; // Combined result error code that shows main rusult + // = S_OK, if there is no error. + // but check also (DataAfterEnd) that can show additional minor errors. + + SRes CombinedRes_Type; // = SZ_ERROR_READ, if error from ISeqInStream + // = SZ_ERROR_PROGRESS, if error from ICompressProgress + // = SZ_ERROR_WRITE, if error from ISeqOutStream + // = SZ_ERROR_* codes for decoding +} CXzStatInfo; + +void XzStatInfo_Clear(CXzStatInfo *p); + +/* + +XzDecMt_Decode() +SRes: it's combined decoding result. It also is equal to stat->CombinedRes. + + SZ_OK - no error + check also output value in (stat->DataAfterEnd) + that can show additional possible error + + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_NO_ARCHIVE - is not xz archive + SZ_ERROR_ARCHIVE - Headers error + SZ_ERROR_DATA - Data Error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC Error + SZ_ERROR_INPUT_EOF - it needs more input data + SZ_ERROR_WRITE - ISeqOutStream error + (SZ_ERROR_READ) - ISeqInStream errors + (SZ_ERROR_PROGRESS) - ICompressProgress errors + // SZ_ERROR_THREAD - error in multi-threading functions + MY_SRes_HRESULT_FROM_WRes(WRes_error) - error in multi-threading function +*/ + +SRes XzDecMt_Decode(CXzDecMtHandle p, + const CXzDecMtProps *props, + const UInt64 *outDataSize, // NULL means undefined + int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished + ISeqOutStreamPtr outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, // out: decoding results and statistics + int *isMT, // out: 0 means that ST (Single-Thread) version was used + // 1 means that MT (Multi-Thread) version was used + ICompressProgressPtr progress); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/XzCrc64.c p7zip-rar-16.02+really25.00+ds/C/XzCrc64.c --- p7zip-rar-16.02/C/XzCrc64.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzCrc64.c 2023-12-08 10:00:00.000000000 +0000 @@ -1,86 +1,140 @@ -/* XzCrc64.c -- CRC64 calculation -2015-03-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "XzCrc64.h" -#include "CpuArch.h" - -#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) - -#ifdef MY_CPU_LE - #define CRC_NUM_TABLES 4 -#else - #define CRC_NUM_TABLES 5 - #define CRC_UINT64_SWAP(v) \ - ((v >> 56) \ - | ((v >> 40) & ((UInt64)0xFF << 8)) \ - | ((v >> 24) & ((UInt64)0xFF << 16)) \ - | ((v >> 8) & ((UInt64)0xFF << 24)) \ - | ((v << 8) & ((UInt64)0xFF << 32)) \ - | ((v << 24) & ((UInt64)0xFF << 40)) \ - | ((v << 40) & ((UInt64)0xFF << 48)) \ - | ((v << 56))) - - UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -#endif - -#ifndef MY_CPU_BE - UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); -#endif - -typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); - -static CRC_FUNC g_Crc64Update; -UInt64 g_Crc64Table[256 * CRC_NUM_TABLES]; - -UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) -{ - return g_Crc64Update(v, data, size, g_Crc64Table); -} - -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) -{ - return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; -} - -void MY_FAST_CALL Crc64GenerateTable() -{ - UInt32 i; - for (i = 0; i < 256; i++) - { - UInt64 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1)); - g_Crc64Table[i] = r; - } - for (; i < 256 * CRC_NUM_TABLES; i++) - { - UInt64 r = g_Crc64Table[i - 256]; - g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); - } - - #ifdef MY_CPU_LE - - g_Crc64Update = XzCrc64UpdateT4; - - #else - { - #ifndef MY_CPU_BE - UInt32 k = 1; - if (*(const Byte *)&k == 1) - g_Crc64Update = XzCrc64UpdateT4; - else - #endif - { - for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) - { - UInt64 x = g_Crc64Table[i - 256]; - g_Crc64Table[i] = CRC_UINT64_SWAP(x); - } - g_Crc64Update = XzCrc64UpdateT1_BeT4; - } - } - #endif -} +/* XzCrc64.c -- CRC64 calculation +2023-12-08 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "XzCrc64.h" +#include "CpuArch.h" + +#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) + +// for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC64_DEBUG_BE +#ifdef Z7_CRC64_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +#ifdef Z7_CRC64_NUM_TABLES + #define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES +#else + #define Z7_CRC64_NUM_TABLES_USE 12 +#endif + +#if Z7_CRC64_NUM_TABLES_USE < 1 + #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES +#endif + + +#if Z7_CRC64_NUM_TABLES_USE != 1 + +#ifndef MY_CPU_BE + #define FUNC_NAME_LE_2(s) XzCrc64UpdateT ## s + #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s) + #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC64_NUM_TABLES_USE) + UInt64 Z7_FASTCALL FUNC_NAME_LE (UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif +#ifndef MY_CPU_LE + #define FUNC_NAME_BE_2(s) XzCrc64UpdateBeT ## s + #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s) + #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC64_NUM_TABLES_USE) + UInt64 Z7_FASTCALL FUNC_NAME_BE (UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#if defined(MY_CPU_LE) + #define FUNC_REF FUNC_NAME_LE +#elif defined(MY_CPU_BE) + #define FUNC_REF FUNC_NAME_BE +#else + #define FUNC_REF g_Crc64Update + static UInt64 (Z7_FASTCALL *FUNC_REF)(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#endif + + +MY_ALIGN(64) +static UInt64 g_Crc64Table[256 * Z7_CRC64_NUM_TABLES_USE]; + + +UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size) +{ +#if Z7_CRC64_NUM_TABLES_USE == 1 + #define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + const UInt64 *table = g_Crc64Table; + const Byte *p = (const Byte *)data; + const Byte *lim = p + size; + for (; p != lim; p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + return v; + #undef CRC64_UPDATE_BYTE_2 +#else + return FUNC_REF (v, data, size, g_Crc64Table); +#endif +} + + +Z7_NO_INLINE +void Z7_FASTCALL Crc64GenerateTable(void) +{ + unsigned i; + for (i = 0; i < 256; i++) + { + UInt64 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); + g_Crc64Table[i] = r; + } + +#if Z7_CRC64_NUM_TABLES_USE != 1 +#if 1 || 1 && defined(MY_CPU_X86) // low register count + for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i++) + { + const UInt64 r0 = g_Crc64Table[(size_t)i]; + g_Crc64Table[(size_t)i + 256] = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); + } +#else + for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i += 2) + { + UInt64 r0 = g_Crc64Table[(size_t)(i) ]; + UInt64 r1 = g_Crc64Table[(size_t)(i) + 1]; + r0 = g_Crc64Table[(Byte)r0] ^ (r0 >> 8); + r1 = g_Crc64Table[(Byte)r1] ^ (r1 >> 8); + g_Crc64Table[(size_t)i + 256 ] = r0; + g_Crc64Table[(size_t)i + 256 + 1] = r1; + } +#endif + +#ifndef MY_CPU_LE + { +#ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + FUNC_REF = FUNC_NAME_LE; + else +#endif + { +#ifndef MY_CPU_BE + FUNC_REF = FUNC_NAME_BE; +#endif + for (i = 0; i < 256 * Z7_CRC64_NUM_TABLES_USE; i++) + { + const UInt64 x = g_Crc64Table[i]; + g_Crc64Table[i] = Z7_BSWAP64(x); + } + } + } +#endif // ndef MY_CPU_LE +#endif // Z7_CRC64_NUM_TABLES_USE != 1 +} + +#undef kCrc64Poly +#undef Z7_CRC64_NUM_TABLES_USE +#undef FUNC_REF +#undef FUNC_NAME_LE_2 +#undef FUNC_NAME_LE_1 +#undef FUNC_NAME_LE +#undef FUNC_NAME_BE_2 +#undef FUNC_NAME_BE_1 +#undef FUNC_NAME_BE diff -Nru p7zip-rar-16.02/C/XzCrc64.h p7zip-rar-16.02+really25.00+ds/C/XzCrc64.h --- p7zip-rar-16.02/C/XzCrc64.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzCrc64.h 2023-12-08 10:00:00.000000000 +0000 @@ -1,26 +1,26 @@ -/* XzCrc64.h -- CRC64 calculation -2013-01-18 : Igor Pavlov : Public domain */ - -#ifndef __XZ_CRC64_H -#define __XZ_CRC64_H - -#include - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -extern UInt64 g_Crc64Table[]; - -void MY_FAST_CALL Crc64GenerateTable(void); - -#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) -#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) -#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size); -UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size); - -EXTERN_C_END - -#endif +/* XzCrc64.h -- CRC64 calculation +2023-12-08 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_CRC64_H +#define ZIP7_INC_XZ_CRC64_H + +#include + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +// extern UInt64 g_Crc64Table[]; + +void Z7_FASTCALL Crc64GenerateTable(void); + +#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) +#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) +// #define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt64 Z7_FASTCALL Crc64Update(UInt64 crc, const void *data, size_t size); +// UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/XzCrc64Opt.c p7zip-rar-16.02+really25.00+ds/C/XzCrc64Opt.c --- p7zip-rar-16.02/C/XzCrc64Opt.c 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzCrc64Opt.c 2025-01-03 20:00:00.000000000 +0000 @@ -1,69 +1,261 @@ -/* XzCrc64Opt.c -- CRC64 calculation -2015-03-01 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" - -#ifndef MY_CPU_BE - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - UInt32 d = (UInt32)v ^ *(const UInt32 *)p; - v = (v >> 32) - ^ table[0x300 + ((d ) & 0xFF)] - ^ table[0x200 + ((d >> 8) & 0xFF)] - ^ table[0x100 + ((d >> 16) & 0xFF)] - ^ table[0x000 + ((d >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#endif - - -#ifndef MY_CPU_LE - -#define CRC_UINT64_SWAP(v) \ - ((v >> 56) \ - | ((v >> 40) & ((UInt64)0xFF << 8)) \ - | ((v >> 24) & ((UInt64)0xFF << 16)) \ - | ((v >> 8) & ((UInt64)0xFF << 24)) \ - | ((v << 8) & ((UInt64)0xFF << 32)) \ - | ((v << 24) & ((UInt64)0xFF << 40)) \ - | ((v << 40) & ((UInt64)0xFF << 48)) \ - | ((v << 56))) - -#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8)) - -UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) -{ - const Byte *p = (const Byte *)data; - table += 0x100; - v = CRC_UINT64_SWAP(v); - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p; - v = (v << 32) - ^ table[0x000 + ((d ) & 0xFF)] - ^ table[0x100 + ((d >> 8) & 0xFF)] - ^ table[0x200 + ((d >> 16) & 0xFF)] - ^ table[0x300 + ((d >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2_BE(v, *p); - return CRC_UINT64_SWAP(v); -} - -#endif +/* XzCrc64Opt.c -- CRC64 calculation (optimized functions) +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#if !defined(Z7_CRC64_NUM_TABLES) || Z7_CRC64_NUM_TABLES > 1 + +// for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu +// #define Z7_CRC64_DEBUG_BE +#ifdef Z7_CRC64_DEBUG_BE +#undef MY_CPU_LE +#define MY_CPU_BE +#endif + +#if defined(MY_CPU_64BIT) +#define Z7_CRC64_USE_64BIT +#endif + +// the value Z7_CRC64_NUM_TABLES_USE must be defined to same value as in XzCrc64.c +#ifdef Z7_CRC64_NUM_TABLES +#define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES +#else +#define Z7_CRC64_NUM_TABLES_USE 12 +#endif + +#if Z7_CRC64_NUM_TABLES_USE % 4 || \ + Z7_CRC64_NUM_TABLES_USE < 4 || \ + Z7_CRC64_NUM_TABLES_USE > 4 * 4 + #error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + + +#ifndef MY_CPU_BE + +#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +#if defined(Z7_CRC64_USE_64BIT) && (Z7_CRC64_NUM_TABLES_USE % 8 == 0) + +#define Q64LE(n, d) \ + ( (table + ((n) * 8 + 7) * 0x100)[((d) ) & 0xFF] \ + ^ (table + ((n) * 8 + 6) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 5) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 4) * 0x100)[((d) >> 3 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 3) * 0x100)[((d) >> 4 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 2) * 0x100)[((d) >> 5 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 1) * 0x100)[((d) >> 6 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 0) * 0x100)[((d) >> 7 * 8)] ) + +#define R64(a) *((const UInt64 *)(const void *)p + (a)) + +#else + +#define Q32LE(n, d) \ + ( (table + ((n) * 4 + 3) * 0x100)[((d) ) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] ) + +#define R32(a) *((const UInt32 *)(const void *)p + (a)) + +#endif + + +#define CRC64_FUNC_PRE_LE2(step) \ +UInt64 Z7_FASTCALL XzCrc64UpdateT ## step (UInt64 v, const void *data, size_t size, const UInt64 *table) + +#define CRC64_FUNC_PRE_LE(step) \ + CRC64_FUNC_PRE_LE2(step); \ + CRC64_FUNC_PRE_LE2(step) + +CRC64_FUNC_PRE_LE(Z7_CRC64_NUM_TABLES_USE) +{ + const Byte *p = (const Byte *)data; + const Byte *lim; + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC64_NUM_TABLES_USE & 4))) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + lim = p + size; + if (size >= Z7_CRC64_NUM_TABLES_USE) + { + lim -= Z7_CRC64_NUM_TABLES_USE; + do + { +#if Z7_CRC64_NUM_TABLES_USE == 4 + const UInt32 d = (UInt32)v ^ R32(0); + v = (v >> 32) ^ Q32LE(0, d); +#elif Z7_CRC64_NUM_TABLES_USE == 8 +#ifdef Z7_CRC64_USE_64BIT + v ^= R64(0); + v = Q64LE(0, v); +#else + UInt32 v0, v1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + v = Q32LE(1, v0) ^ Q32LE(0, v1); +#endif +#elif Z7_CRC64_NUM_TABLES_USE == 12 + UInt32 w; + UInt32 v0, v1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + w = R32(2); + v = Q32LE(0, w); + v ^= Q32LE(2, v0) ^ Q32LE(1, v1); +#elif Z7_CRC64_NUM_TABLES_USE == 16 +#ifdef Z7_CRC64_USE_64BIT + UInt64 w; + UInt64 x; + w = R64(1); x = Q64LE(0, w); + v ^= R64(0); v = x ^ Q64LE(1, v); +#else + UInt32 v0, v1; + UInt32 r0, r1; + v0 = (UInt32)v ^ R32(0); + v1 = (UInt32)(v >> 32) ^ R32(1); + r0 = R32(2); + r1 = R32(3); + v = Q32LE(1, r0) ^ Q32LE(0, r1); + v ^= Q32LE(3, v0) ^ Q32LE(2, v1); +#endif +#else +#error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + p += Z7_CRC64_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC64_NUM_TABLES_USE; + } + for (; p < lim; p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + return v; +} + +#undef CRC64_UPDATE_BYTE_2 +#undef R32 +#undef R64 +#undef Q32LE +#undef Q64LE +#undef CRC64_FUNC_PRE_LE +#undef CRC64_FUNC_PRE_LE2 + +#endif + + + + +#ifndef MY_CPU_LE + +#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 56) ^ (b)] ^ ((crc) << 8)) + +#if defined(Z7_CRC64_USE_64BIT) && (Z7_CRC64_NUM_TABLES_USE % 8 == 0) + +#define Q64BE(n, d) \ + ( (table + ((n) * 8 + 0) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 8 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 3) * 0x100)[((d) >> 3 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 4) * 0x100)[((d) >> 4 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 5) * 0x100)[((d) >> 5 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 6) * 0x100)[((d) >> 6 * 8) & 0xFF] \ + ^ (table + ((n) * 8 + 7) * 0x100)[((d) >> 7 * 8)] ) + +#ifdef Z7_CRC64_DEBUG_BE + #define R64BE(a) GetBe64a((const UInt64 *)(const void *)p + (a)) +#else + #define R64BE(a) *((const UInt64 *)(const void *)p + (a)) +#endif + +#else + +#define Q32BE(n, d) \ + ( (table + ((n) * 4 + 0) * 0x100)[(Byte)(d)] \ + ^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \ + ^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] ) + +#ifdef Z7_CRC64_DEBUG_BE + #define R32BE(a) GetBe32a((const UInt32 *)(const void *)p + (a)) +#else + #define R32BE(a) *((const UInt32 *)(const void *)p + (a)) +#endif + +#endif + +#define CRC64_FUNC_PRE_BE2(step) \ +UInt64 Z7_FASTCALL XzCrc64UpdateBeT ## step (UInt64 v, const void *data, size_t size, const UInt64 *table) + +#define CRC64_FUNC_PRE_BE(step) \ + CRC64_FUNC_PRE_BE2(step); \ + CRC64_FUNC_PRE_BE2(step) + +CRC64_FUNC_PRE_BE(Z7_CRC64_NUM_TABLES_USE) +{ + const Byte *p = (const Byte *)data; + const Byte *lim; + v = Z7_BSWAP64(v); + for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC64_NUM_TABLES_USE & 4))) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + lim = p + size; + if (size >= Z7_CRC64_NUM_TABLES_USE) + { + lim -= Z7_CRC64_NUM_TABLES_USE; + do + { +#if Z7_CRC64_NUM_TABLES_USE == 4 + const UInt32 d = (UInt32)(v >> 32) ^ R32BE(0); + v = (v << 32) ^ Q32BE(0, d); +#elif Z7_CRC64_NUM_TABLES_USE == 12 + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + const UInt32 w = R32BE(2); + v = Q32BE(0, w); + v ^= Q32BE(2, d1) ^ Q32BE(1, d0); + +#elif Z7_CRC64_NUM_TABLES_USE == 8 + #ifdef Z7_CRC64_USE_64BIT + v ^= R64BE(0); + v = Q64BE(0, v); + #else + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + v = Q32BE(1, d1) ^ Q32BE(0, d0); + #endif +#elif Z7_CRC64_NUM_TABLES_USE == 16 + #ifdef Z7_CRC64_USE_64BIT + const UInt64 w = R64BE(1); + v ^= R64BE(0); + v = Q64BE(0, w) ^ Q64BE(1, v); + #else + const UInt32 d1 = (UInt32)(v >> 32) ^ R32BE(0); + const UInt32 d0 = (UInt32)(v ) ^ R32BE(1); + const UInt32 w1 = R32BE(2); + const UInt32 w0 = R32BE(3); + v = Q32BE(1, w1) ^ Q32BE(0, w0); + v ^= Q32BE(3, d1) ^ Q32BE(2, d0); + #endif +#else +#error Stop_Compiling_Bad_CRC64_NUM_TABLES +#endif + p += Z7_CRC64_NUM_TABLES_USE; + } + while (p <= lim); + lim += Z7_CRC64_NUM_TABLES_USE; + } + for (; p < lim; p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + return Z7_BSWAP64(v); +} + +#undef CRC64_UPDATE_BYTE_2_BE +#undef R32BE +#undef R64BE +#undef Q32BE +#undef Q64BE +#undef CRC64_FUNC_PRE_BE +#undef CRC64_FUNC_PRE_BE2 + +#endif +#undef Z7_CRC64_NUM_TABLES_USE +#endif diff -Nru p7zip-rar-16.02/C/XzDec.c p7zip-rar-16.02+really25.00+ds/C/XzDec.c --- p7zip-rar-16.02/C/XzDec.c 2015-11-20 20:40:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzDec.c 2025-04-30 13:00:00.000000000 +0000 @@ -1,913 +1,2876 @@ -/* XzDec.c -- Xz Decode -2015-11-09 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -/* #define XZ_DUMP */ - -#ifdef XZ_DUMP -#include -#endif - -#include -#include - -#include "7zCrc.h" -#include "Alloc.h" -#include "Bra.h" -#include "CpuArch.h" -#include "Delta.h" -#include "Lzma2Dec.h" - -#ifdef USE_SUBBLOCK -#include "Bcj3Dec.c" -#include "SbDec.c" -#endif - -#include "Xz.h" - -#define XZ_CHECK_SIZE_MAX 64 - -#define CODER_BUF_SIZE (1 << 17) - -unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) -{ - unsigned i, limit; - *value = 0; - limit = (maxSize > 9) ? 9 : (unsigned)maxSize; - - for (i = 0; i < limit;) - { - Byte b = p[i]; - *value |= (UInt64)(b & 0x7F) << (7 * i++); - if ((b & 0x80) == 0) - return (b == 0 && i != 1) ? 0 : i; - } - return 0; -} - -/* ---------- BraState ---------- */ - -#define BRA_BUF_SIZE (1 << 14) - -typedef struct -{ - size_t bufPos; - size_t bufConv; - size_t bufTotal; - - UInt32 methodId; - int encodeMode; - UInt32 delta; - UInt32 ip; - UInt32 x86State; - Byte deltaState[DELTA_STATE_SIZE]; - - Byte buf[BRA_BUF_SIZE]; -} CBraState; - -static void BraState_Free(void *pp, ISzAlloc *alloc) -{ - alloc->Free(alloc, pp); -} - -static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - CBraState *p = ((CBraState *)pp); - UNUSED_VAR(alloc); - p->ip = 0; - if (p->methodId == XZ_ID_Delta) - { - if (propSize != 1) - return SZ_ERROR_UNSUPPORTED; - p->delta = (unsigned)props[0] + 1; - } - else - { - if (propSize == 4) - { - UInt32 v = GetUi32(props); - switch (p->methodId) - { - case XZ_ID_PPC: - case XZ_ID_ARM: - case XZ_ID_SPARC: - if ((v & 3) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - case XZ_ID_ARMT: - if ((v & 1) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - case XZ_ID_IA64: - if ((v & 0xF) != 0) - return SZ_ERROR_UNSUPPORTED; - break; - } - p->ip = v; - } - else if (propSize != 0) - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; -} - -static void BraState_Init(void *pp) -{ - CBraState *p = ((CBraState *)pp); - p->bufPos = p->bufConv = p->bufTotal = 0; - x86_Convert_Init(p->x86State); - if (p->methodId == XZ_ID_Delta) - Delta_Init(p->deltaState); -} - -#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break; - -static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - CBraState *p = ((CBraState *)pp); - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - UNUSED_VAR(finishMode); - *destLen = 0; - *srcLen = 0; - *wasFinished = 0; - while (destLenOrig > 0) - { - if (p->bufPos != p->bufConv) - { - size_t curSize = p->bufConv - p->bufPos; - if (curSize > destLenOrig) - curSize = destLenOrig; - memcpy(dest, p->buf + p->bufPos, curSize); - p->bufPos += curSize; - *destLen += curSize; - dest += curSize; - destLenOrig -= curSize; - continue; - } - p->bufTotal -= p->bufPos; - memmove(p->buf, p->buf + p->bufPos, p->bufTotal); - p->bufPos = 0; - p->bufConv = 0; - { - size_t curSize = BRA_BUF_SIZE - p->bufTotal; - if (curSize > srcLenOrig) - curSize = srcLenOrig; - memcpy(p->buf + p->bufTotal, src, curSize); - *srcLen += curSize; - src += curSize; - srcLenOrig -= curSize; - p->bufTotal += curSize; - } - if (p->bufTotal == 0) - break; - switch (p->methodId) - { - case XZ_ID_Delta: - if (p->encodeMode) - Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal); - else - Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal); - p->bufConv = p->bufTotal; - break; - case XZ_ID_X86: - p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode); - break; - CASE_BRA_CONV(PPC) - CASE_BRA_CONV(IA64) - CASE_BRA_CONV(ARM) - CASE_BRA_CONV(ARMT) - CASE_BRA_CONV(SPARC) - default: - return SZ_ERROR_UNSUPPORTED; - } - p->ip += (UInt32)p->bufConv; - - if (p->bufConv == 0) - { - if (!srcWasFinished) - break; - p->bufConv = p->bufTotal; - } - } - if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished) - *wasFinished = 1; - return SZ_OK; -} - -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc) -{ - CBraState *decoder; - if (id != XZ_ID_Delta && - id != XZ_ID_X86 && - id != XZ_ID_PPC && - id != XZ_ID_IA64 && - id != XZ_ID_ARM && - id != XZ_ID_ARMT && - id != XZ_ID_SPARC) - return SZ_ERROR_UNSUPPORTED; - p->p = 0; - decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState)); - if (decoder == 0) - return SZ_ERROR_MEM; - decoder->methodId = (UInt32)id; - decoder->encodeMode = encodeMode; - p->p = decoder; - p->Free = BraState_Free; - p->SetProps = BraState_SetProps; - p->Init = BraState_Init; - p->Code = BraState_Code; - return SZ_OK; -} - -/* ---------- SbState ---------- */ - -#ifdef USE_SUBBLOCK - -static void SbState_Free(void *pp, ISzAlloc *alloc) -{ - CSbDec *p = (CSbDec *)pp; - SbDec_Free(p); - alloc->Free(alloc, pp); -} - -static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - UNUSED_VAR(pp); - UNUSED_VAR(props); - UNUSED_VAR(alloc); - return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; -} - -static void SbState_Init(void *pp) -{ - SbDec_Init((CSbDec *)pp); -} - -static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - CSbDec *p = (CSbDec *)pp; - SRes res; - UNUSED_VAR(srcWasFinished); - p->dest = dest; - p->destLen = *destLen; - p->src = src; - p->srcLen = *srcLen; - p->finish = finishMode; /* change it */ - res = SbDec_Decode((CSbDec *)pp); - *destLen -= p->destLen; - *srcLen -= p->srcLen; - *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ - return res; -} - -SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) -{ - CSbDec *decoder; - p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CSbDec)); - if (decoder == 0) - return SZ_ERROR_MEM; - p->p = decoder; - p->Free = SbState_Free; - p->SetProps = SbState_SetProps; - p->Init = SbState_Init; - p->Code = SbState_Code; - SbDec_Construct(decoder); - SbDec_SetAlloc(decoder, alloc); - return SZ_OK; -} -#endif - -/* ---------- Lzma2State ---------- */ - -static void Lzma2State_Free(void *pp, ISzAlloc *alloc) -{ - Lzma2Dec_Free((CLzma2Dec *)pp, alloc); - alloc->Free(alloc, pp); -} - -static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) -{ - if (propSize != 1) - return SZ_ERROR_UNSUPPORTED; - return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc); -} - -static void Lzma2State_Init(void *pp) -{ - Lzma2Dec_Init((CLzma2Dec *)pp); -} - -static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) -{ - ELzmaStatus status; - /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ - SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); - UNUSED_VAR(srcWasFinished); - *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); - return res; -} - -static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) -{ - CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec)); - p->p = decoder; - if (decoder == 0) - return SZ_ERROR_MEM; - p->Free = Lzma2State_Free; - p->SetProps = Lzma2State_SetProps; - p->Init = Lzma2State_Init; - p->Code = Lzma2State_Code; - Lzma2Dec_Construct(decoder); - return SZ_OK; -} - - -void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc) -{ - unsigned i; - p->alloc = alloc; - p->buf = NULL; - p->numCoders = 0; - for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) - p->coders[i].p = NULL; -} - -void MixCoder_Free(CMixCoder *p) -{ - unsigned i; - for (i = 0; i < p->numCoders; i++) - { - IStateCoder *sc = &p->coders[i]; - if (p->alloc && sc->p) - sc->Free(sc->p, p->alloc); - } - p->numCoders = 0; - if (p->buf) - { - p->alloc->Free(p->alloc, p->buf); - p->buf = NULL; /* 9.31: the BUG was fixed */ - } -} - -void MixCoder_Init(CMixCoder *p) -{ - unsigned i; - for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++) - { - p->size[i] = 0; - p->pos[i] = 0; - p->finished[i] = 0; - } - for (i = 0; i < p->numCoders; i++) - { - IStateCoder *coder = &p->coders[i]; - coder->Init(coder->p); - } -} - -SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId) -{ - IStateCoder *sc = &p->coders[coderIndex]; - p->ids[coderIndex] = methodId; - switch (methodId) - { - case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc); - #ifdef USE_SUBBLOCK - case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); - #endif - } - if (coderIndex == 0) - return SZ_ERROR_UNSUPPORTED; - return BraState_SetFromMethod(sc, methodId, 0, p->alloc); -} - -SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int srcWasFinished, - ECoderFinishMode finishMode, ECoderStatus *status) -{ - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - Bool allFinished = True; - *destLen = 0; - *srcLen = 0; - *status = CODER_STATUS_NOT_FINISHED; - - if (!p->buf) - { - p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); - if (!p->buf) - return SZ_ERROR_MEM; - } - - if (p->numCoders != 1) - finishMode = CODER_FINISH_ANY; - - for (;;) - { - Bool processed = False; - unsigned i; - /* - if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) - break; - */ - - for (i = 0; i < p->numCoders; i++) - { - SRes res; - IStateCoder *coder = &p->coders[i]; - Byte *destCur; - SizeT destLenCur, srcLenCur; - const Byte *srcCur; - int srcFinishedCur; - int encodingWasFinished; - - if (i == 0) - { - srcCur = src; - srcLenCur = srcLenOrig - *srcLen; - srcFinishedCur = srcWasFinished; - } - else - { - srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1]; - srcLenCur = p->size[i - 1] - p->pos[i - 1]; - srcFinishedCur = p->finished[i - 1]; - } - - if (i == p->numCoders - 1) - { - destCur = dest; - destLenCur = destLenOrig - *destLen; - } - else - { - if (p->pos[i] != p->size[i]) - continue; - destCur = p->buf + (CODER_BUF_SIZE * i); - destLenCur = CODER_BUF_SIZE; - } - - res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished); - - if (!encodingWasFinished) - allFinished = False; - - if (i == 0) - { - *srcLen += srcLenCur; - src += srcLenCur; - } - else - { - p->pos[i - 1] += srcLenCur; - } - - if (i == p->numCoders - 1) - { - *destLen += destLenCur; - dest += destLenCur; - } - else - { - p->size[i] = destLenCur; - p->pos[i] = 0; - p->finished[i] = encodingWasFinished; - } - - if (res != SZ_OK) - return res; - - if (destLenCur != 0 || srcLenCur != 0) - processed = True; - } - if (!processed) - break; - } - if (allFinished) - *status = CODER_STATUS_FINISHED_WITH_MARK; - return SZ_OK; -} - -SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) -{ - *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); - if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != - GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) - return SZ_ERROR_NO_ARCHIVE; - return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; -} - -static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) -{ - return - indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) && - (GetUi32(buf) == CrcCalc(buf + 4, 6) && - flags == GetBe16(buf + 8) && - memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0); -} - -#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ - if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } - - -SRes XzBlock_Parse(CXzBlock *p, const Byte *header) -{ - unsigned pos; - unsigned numFilters, i; - unsigned headerSize = (unsigned)header[0] << 2; - - if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) - return SZ_ERROR_ARCHIVE; - - pos = 1; - if (pos == headerSize) - return SZ_ERROR_ARCHIVE; - p->flags = header[pos++]; - - if (XzBlock_HasPackSize(p)) - { - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize); - if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) - return SZ_ERROR_ARCHIVE; - } - - if (XzBlock_HasUnpackSize(p)) - READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize); - - numFilters = XzBlock_GetNumFilters(p); - for (i = 0; i < numFilters; i++) - { - CXzFilter *filter = p->filters + i; - UInt64 size; - READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id); - READ_VARINT_AND_CHECK(header, pos, headerSize, &size); - if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) - return SZ_ERROR_ARCHIVE; - filter->propsSize = (UInt32)size; - memcpy(filter->props, header + pos, (size_t)size); - pos += (unsigned)size; - - #ifdef XZ_DUMP - printf("\nf[%u] = %2X: ", i, (unsigned)filter->id); - { - unsigned i; - for (i = 0; i < size; i++) - printf(" %2X", filter->props[i]); - } - #endif - } - - while (pos < headerSize) - if (header[pos++] != 0) - return SZ_ERROR_ARCHIVE; - return SZ_OK; -} - -SRes XzDec_Init(CMixCoder *p, const CXzBlock *block) -{ - unsigned i; - Bool needReInit = True; - unsigned numFilters = XzBlock_GetNumFilters(block); - - if (numFilters == p->numCoders) - { - for (i = 0; i < numFilters; i++) - if (p->ids[i] != block->filters[numFilters - 1 - i].id) - break; - needReInit = (i != numFilters); - } - - if (needReInit) - { - MixCoder_Free(p); - p->numCoders = numFilters; - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &block->filters[numFilters - 1 - i]; - RINOK(MixCoder_SetFromMethod(p, i, f->id)); - } - } - - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &block->filters[numFilters - 1 - i]; - IStateCoder *sc = &p->coders[i]; - RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)); - } - - MixCoder_Init(p); - return SZ_OK; -} - -void XzUnpacker_Init(CXzUnpacker *p) -{ - p->state = XZ_STATE_STREAM_HEADER; - p->pos = 0; - p->numStartedStreams = 0; - p->numFinishedStreams = 0; - p->numTotalBlocks = 0; - p->padSize = 0; -} - -void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc) -{ - MixCoder_Construct(&p->decoder, alloc); - XzUnpacker_Init(p); -} - -void XzUnpacker_Free(CXzUnpacker *p) -{ - MixCoder_Free(&p->decoder); -} - -SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status) -{ - SizeT destLenOrig = *destLen; - SizeT srcLenOrig = *srcLen; - *destLen = 0; - *srcLen = 0; - *status = CODER_STATUS_NOT_SPECIFIED; - for (;;) - { - SizeT srcRem = srcLenOrig - *srcLen; - - if (p->state == XZ_STATE_BLOCK) - { - SizeT destLen2 = destLenOrig - *destLen; - SizeT srcLen2 = srcLenOrig - *srcLen; - SRes res; - if (srcLen2 == 0 && destLen2 == 0) - { - *status = CODER_STATUS_NOT_FINISHED; - return SZ_OK; - } - - res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status); - XzCheck_Update(&p->check, dest, destLen2); - - (*srcLen) += srcLen2; - src += srcLen2; - p->packSize += srcLen2; - - (*destLen) += destLen2; - dest += destLen2; - p->unpackSize += destLen2; - - RINOK(res); - - if (*status == CODER_STATUS_FINISHED_WITH_MARK) - { - Byte temp[32]; - unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags)); - num += Xz_WriteVarInt(temp + num, p->unpackSize); - Sha256_Update(&p->sha, temp, num); - p->indexSize += num; - p->numBlocks++; - - p->state = XZ_STATE_BLOCK_FOOTER; - p->pos = 0; - p->alignPos = 0; - } - else if (srcLen2 == 0 && destLen2 == 0) - return SZ_OK; - - continue; - } - - if (srcRem == 0) - { - *status = CODER_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - - switch (p->state) - { - case XZ_STATE_STREAM_HEADER: - { - if (p->pos < XZ_STREAM_HEADER_SIZE) - { - if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) - return SZ_ERROR_NO_ARCHIVE; - p->buf[p->pos++] = *src++; - (*srcLen)++; - } - else - { - RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); - p->numStartedStreams++; - p->state = XZ_STATE_BLOCK_HEADER; - Sha256_Init(&p->sha); - p->indexSize = 0; - p->numBlocks = 0; - p->pos = 0; - } - break; - } - - case XZ_STATE_BLOCK_HEADER: - { - if (p->pos == 0) - { - p->buf[p->pos++] = *src++; - (*srcLen)++; - if (p->buf[0] == 0) - { - p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); - p->indexPos = p->indexPreSize; - p->indexSize += p->indexPreSize; - Sha256_Final(&p->sha, p->shaDigest); - Sha256_Init(&p->sha); - p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); - p->state = XZ_STATE_STREAM_INDEX; - } - p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; - } - else if (p->pos != p->blockHeaderSize) - { - UInt32 cur = p->blockHeaderSize - p->pos; - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - } - else - { - RINOK(XzBlock_Parse(&p->block, p->buf)); - p->numTotalBlocks++; - p->state = XZ_STATE_BLOCK; - p->packSize = 0; - p->unpackSize = 0; - XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); - RINOK(XzDec_Init(&p->decoder, &p->block)); - } - break; - } - - case XZ_STATE_BLOCK_FOOTER: - { - if (((p->packSize + p->alignPos) & 3) != 0) - { - (*srcLen)++; - p->alignPos++; - if (*src++ != 0) - return SZ_ERROR_CRC; - } - else - { - UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); - UInt32 cur = checkSize - p->pos; - if (cur != 0) - { - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - } - else - { - Byte digest[XZ_CHECK_SIZE_MAX]; - p->state = XZ_STATE_BLOCK_HEADER; - p->pos = 0; - if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) - return SZ_ERROR_CRC; - } - } - break; - } - - case XZ_STATE_STREAM_INDEX: - { - if (p->pos < p->indexPreSize) - { - (*srcLen)++; - if (*src++ != p->buf[p->pos++]) - return SZ_ERROR_CRC; - } - else - { - if (p->indexPos < p->indexSize) - { - UInt64 cur = p->indexSize - p->indexPos; - if (srcRem > cur) - srcRem = (SizeT)cur; - p->crc = CrcUpdate(p->crc, src, srcRem); - Sha256_Update(&p->sha, src, srcRem); - (*srcLen) += srcRem; - src += srcRem; - p->indexPos += srcRem; - } - else if ((p->indexPos & 3) != 0) - { - Byte b = *src++; - p->crc = CRC_UPDATE_BYTE(p->crc, b); - (*srcLen)++; - p->indexPos++; - p->indexSize++; - if (b != 0) - return SZ_ERROR_CRC; - } - else - { - Byte digest[SHA256_DIGEST_SIZE]; - p->state = XZ_STATE_STREAM_INDEX_CRC; - p->indexSize += 4; - p->pos = 0; - Sha256_Final(&p->sha, digest); - if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) - return SZ_ERROR_CRC; - } - } - break; - } - - case XZ_STATE_STREAM_INDEX_CRC: - { - if (p->pos < 4) - { - (*srcLen)++; - p->buf[p->pos++] = *src++; - } - else - { - p->state = XZ_STATE_STREAM_FOOTER; - p->pos = 0; - if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf)) - return SZ_ERROR_CRC; - } - break; - } - - case XZ_STATE_STREAM_FOOTER: - { - UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; - if (cur > srcRem) - cur = (UInt32)srcRem; - memcpy(p->buf + p->pos, src, cur); - p->pos += cur; - (*srcLen) += cur; - src += cur; - if (p->pos == XZ_STREAM_FOOTER_SIZE) - { - p->state = XZ_STATE_STREAM_PADDING; - p->numFinishedStreams++; - p->padSize = 0; - if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) - return SZ_ERROR_CRC; - } - break; - } - - case XZ_STATE_STREAM_PADDING: - { - if (*src != 0) - { - if (((UInt32)p->padSize & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - p->pos = 0; - p->state = XZ_STATE_STREAM_HEADER; - } - else - { - (*srcLen)++; - src++; - p->padSize++; - } - break; - } - - case XZ_STATE_BLOCK: break; /* to disable GCC warning */ - } - } - /* - if (p->state == XZ_STATE_FINISHED) - *status = CODER_STATUS_FINISHED_WITH_MARK; - return SZ_OK; - */ -} - -Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p) -{ - return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); -} - -UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p) -{ - UInt64 num = 0; - if (p->state == XZ_STATE_STREAM_PADDING) - num += p->padSize; - else if (p->state == XZ_STATE_STREAM_HEADER) - num += p->padSize + p->pos; - return num; -} +/* XzDec.c -- Xz Decode +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +// #define XZ_DUMP + +/* #define XZ_DUMP */ + +#ifdef XZ_DUMP +#include +#endif + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define PRF_STR(s) PRF(printf("\n" s "\n")) +#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) + +#include +#include + +#include "7zCrc.h" +#include "Alloc.h" +#include "Bra.h" +#include "CpuArch.h" +#include "Delta.h" +#include "Lzma2Dec.h" + +// #define USE_SUBBLOCK + +#ifdef USE_SUBBLOCK +#include "Bcj3Dec.c" +#include "SbDec.h" +#endif + +#include "Xz.h" + +#define XZ_CHECK_SIZE_MAX 64 + +#define CODER_BUF_SIZE ((size_t)1 << 17) + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) +{ + unsigned i, limit; + *value = 0; + limit = (maxSize > 9) ? 9 : (unsigned)maxSize; + + for (i = 0; i < limit;) + { + const unsigned b = p[i]; + *value |= (UInt64)(b & 0x7F) << (7 * i++); + if ((b & 0x80) == 0) + return (b == 0 && i != 1) ? 0 : i; + } + return 0; +} + + +/* ---------- XzBcFilterState ---------- */ + +#define BRA_BUF_SIZE (1 << 14) + +typedef struct +{ + size_t bufPos; + size_t bufConv; + size_t bufTotal; + Byte *buf; // must be aligned for 4 bytes + Xz_Func_BcFilterStateBase_Filter filter_func; + // int encodeMode; + CXzBcFilterStateBase base; + // Byte buf[BRA_BUF_SIZE]; +} CXzBcFilterState; + + +static void XzBcFilterState_Free(void *pp, ISzAllocPtr alloc) +{ + if (pp) + { + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + ISzAlloc_Free(alloc, p->buf); + ISzAlloc_Free(alloc, pp); + } +} + + +static SRes XzBcFilterState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + CXzBcFilterStateBase *p = &((CXzBcFilterState *)pp)->base; + UNUSED_VAR(alloc) + p->ip = 0; + if (p->methodId == XZ_ID_Delta) + { + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + p->delta = (UInt32)props[0] + 1; + } + else + { + if (propSize == 4) + { + const UInt32 v = GetUi32(props); + switch (p->methodId) + { + case XZ_ID_PPC: + case XZ_ID_ARM: + case XZ_ID_SPARC: + case XZ_ID_ARM64: + if (v & 3) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_ARMT: + case XZ_ID_RISCV: + if (v & 1) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_IA64: + if (v & 0xf) + return SZ_ERROR_UNSUPPORTED; + break; + default: break; + } + p->ip = v; + } + else if (propSize != 0) + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; +} + + +static void XzBcFilterState_Init(void *pp) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + p->bufPos = p->bufConv = p->bufTotal = 0; + p->base.X86_State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + if (p->base.methodId == XZ_ID_Delta) + Delta_Init(p->base.delta_State); +} + + +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Dec[] = +{ + Z7_BRANCH_CONV_DEC_2 (BranchConv_PPC), + Z7_BRANCH_CONV_DEC_2 (BranchConv_IA64), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARMT), + Z7_BRANCH_CONV_DEC_2 (BranchConv_SPARC), + Z7_BRANCH_CONV_DEC_2 (BranchConv_ARM64), + Z7_BRANCH_CONV_DEC_2 (BranchConv_RISCV) +}; + +static SizeT XzBcFilterStateBase_Filter_Dec(CXzBcFilterStateBase *p, Byte *data, SizeT size) +{ + switch (p->methodId) + { + case XZ_ID_Delta: + Delta_Decode(p->delta_State, p->delta, data, size); + break; + case XZ_ID_X86: + size = (SizeT)(z7_BranchConvSt_X86_Dec(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Dec)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Dec[i](data, size, p->ip) - data); + } + break; + } + p->ip += (UInt32)size; + return size; +} + + +static SizeT XzBcFilterState_Filter(void *pp, Byte *data, SizeT size) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + return p->filter_func(&p->base, data, size); +} + + +static SRes XzBcFilterState_Code2(void *pp, + Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + SizeT destRem = *destLen; + SizeT srcRem = *srcLen; + UNUSED_VAR(finishMode) + + *destLen = 0; + *srcLen = 0; + // *wasFinished = False; + *status = CODER_STATUS_NOT_FINISHED; + + while (destRem != 0) + { + { + size_t size = p->bufConv - p->bufPos; + if (size) + { + if (size > destRem) + size = destRem; + memcpy(dest, p->buf + p->bufPos, size); + p->bufPos += size; + *destLen += size; + dest += size; + destRem -= size; + continue; + } + } + + p->bufTotal -= p->bufPos; + memmove(p->buf, p->buf + p->bufPos, p->bufTotal); + p->bufPos = 0; + p->bufConv = 0; + { + size_t size = BRA_BUF_SIZE - p->bufTotal; + if (size > srcRem) + size = srcRem; + memcpy(p->buf + p->bufTotal, src, size); + *srcLen += size; + src += size; + srcRem -= size; + p->bufTotal += size; + } + if (p->bufTotal == 0) + break; + + p->bufConv = p->filter_func(&p->base, p->buf, p->bufTotal); + + if (p->bufConv == 0) + { + if (!srcWasFinished) + break; + p->bufConv = p->bufTotal; + } + } + + if (p->bufTotal == p->bufPos && srcRem == 0 && srcWasFinished) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + // *wasFinished = 1; + } + + return SZ_OK; +} + + +#define XZ_IS_SUPPORTED_FILTER_ID(id) \ + ((id) >= XZ_ID_Delta && (id) <= XZ_ID_RISCV) + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc) +{ + CXzBcFilterState *decoder; + if (!XZ_IS_SUPPORTED_FILTER_ID(id)) + return SZ_ERROR_UNSUPPORTED; + decoder = (CXzBcFilterState *)p->p; + if (!decoder) + { + decoder = (CXzBcFilterState *)ISzAlloc_Alloc(alloc, sizeof(CXzBcFilterState)); + if (!decoder) + return SZ_ERROR_MEM; + decoder->buf = ISzAlloc_Alloc(alloc, BRA_BUF_SIZE); + if (!decoder->buf) + { + ISzAlloc_Free(alloc, decoder); + return SZ_ERROR_MEM; + } + p->p = decoder; + p->Free = XzBcFilterState_Free; + p->SetProps = XzBcFilterState_SetProps; + p->Init = XzBcFilterState_Init; + p->Code2 = XzBcFilterState_Code2; + p->Filter = XzBcFilterState_Filter; + decoder->filter_func = func; + } + decoder->base.methodId = (UInt32)id; + // decoder->encodeMode = encodeMode; + return SZ_OK; +} + + + +/* ---------- SbState ---------- */ + +#ifdef USE_SUBBLOCK + +static void SbState_Free(void *pp, ISzAllocPtr alloc) +{ + CSbDec *p = (CSbDec *)pp; + SbDec_Free(p); + ISzAlloc_Free(alloc, pp); +} + +static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + UNUSED_VAR(pp) + UNUSED_VAR(props) + UNUSED_VAR(alloc) + return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static void SbState_Init(void *pp) +{ + SbDec_Init((CSbDec *)pp); +} + +static SRes SbState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CSbDec *p = (CSbDec *)pp; + SRes res; + UNUSED_VAR(srcWasFinished) + p->dest = dest; + p->destLen = *destLen; + p->src = src; + p->srcLen = *srcLen; + p->finish = finishMode; /* change it */ + res = SbDec_Decode((CSbDec *)pp); + *destLen -= p->destLen; + *srcLen -= p->srcLen; + // *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ + *status = (*destLen == 0 && *srcLen == 0) ? + CODER_STATUS_FINISHED_WITH_MARK : + CODER_STATUS_NOT_FINISHED; + return res; +} + +static SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc) +{ + CSbDec *decoder = (CSbDec *)p->p; + if (!decoder) + { + decoder = (CSbDec *)ISzAlloc_Alloc(alloc, sizeof(CSbDec)); + if (!decoder) + return SZ_ERROR_MEM; + p->p = decoder; + p->Free = SbState_Free; + p->SetProps = SbState_SetProps; + p->Init = SbState_Init; + p->Code2 = SbState_Code2; + p->Filter = NULL; + } + SbDec_Construct(decoder); + SbDec_SetAlloc(decoder, alloc); + return SZ_OK; +} + +#endif + + + +/* ---------- Lzma2 ---------- */ + +typedef struct +{ + CLzma2Dec decoder; + BoolInt outBufMode; +} CLzma2Dec_Spec; + + +static void Lzma2State_Free(void *pp, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + Lzma2Dec_FreeProbs(&p->decoder, alloc); + else + Lzma2Dec_Free(&p->decoder, alloc); + ISzAlloc_Free(alloc, pp); +} + +static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + { + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + return Lzma2Dec_AllocateProbs(&p->decoder, props[0], alloc); + else + return Lzma2Dec_Allocate(&p->decoder, props[0], alloc); + } +} + +static void Lzma2State_Init(void *pp) +{ + Lzma2Dec_Init(&((CLzma2Dec_Spec *)pp)->decoder); +} + + +/* + if (outBufMode), then (dest) is not used. Use NULL. + Data is unpacked to (spec->decoder.decoder.dic) output buffer. +*/ + +static SRes Lzma2State_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)pp; + ELzmaStatus status2; + /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ + SRes res; + UNUSED_VAR(srcWasFinished) + if (spec->outBufMode) + { + SizeT dicPos = spec->decoder.decoder.dicPos; + SizeT dicLimit = dicPos + *destLen; + res = Lzma2Dec_DecodeToDic(&spec->decoder, dicLimit, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + *destLen = spec->decoder.decoder.dicPos - dicPos; + } + else + res = Lzma2Dec_DecodeToBuf(&spec->decoder, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + // *wasFinished = (status2 == LZMA_STATUS_FINISHED_WITH_MARK); + // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + *status = (ECoderStatus)status2; + return res; +} + + +static SRes Lzma2State_SetFromMethod(IStateCoder *p, Byte *outBuf, size_t outBufSize, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if (!spec) + { + spec = (CLzma2Dec_Spec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec_Spec)); + if (!spec) + return SZ_ERROR_MEM; + p->p = spec; + p->Free = Lzma2State_Free; + p->SetProps = Lzma2State_SetProps; + p->Init = Lzma2State_Init; + p->Code2 = Lzma2State_Code2; + p->Filter = NULL; + Lzma2Dec_CONSTRUCT(&spec->decoder) + } + spec->outBufMode = False; + if (outBuf) + { + spec->outBufMode = True; + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + +static SRes Lzma2State_ResetOutBuf(IStateCoder *p, Byte *outBuf, size_t outBufSize) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if ((spec->outBufMode && !outBuf) || (!spec->outBufMode && outBuf)) + return SZ_ERROR_FAIL; + if (outBuf) + { + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + + +static void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc) +{ + unsigned i; + p->alloc = alloc; + p->buf = NULL; + p->numCoders = 0; + + p->outBufSize = 0; + p->outBuf = NULL; + // p->SingleBufMode = False; + + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + p->coders[i].p = NULL; +} + + +static void MixCoder_Free(CMixCoder *p) +{ + unsigned i; + p->numCoders = 0; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + { + IStateCoder *sc = &p->coders[i]; + if (sc->p) + { + sc->Free(sc->p, p->alloc); + sc->p = NULL; + } + } + if (p->buf) + { + ISzAlloc_Free(p->alloc, p->buf); + p->buf = NULL; /* 9.31: the BUG was fixed */ + } +} + +static void MixCoder_Init(CMixCoder *p) +{ + unsigned i; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++) + { + p->size[i] = 0; + p->pos[i] = 0; + p->finished[i] = 0; + } + for (i = 0; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + coder->Init(coder->p); + p->results[i] = SZ_OK; + } + p->outWritten = 0; + p->wasFinished = False; + p->res = SZ_OK; + p->status = CODER_STATUS_NOT_SPECIFIED; +} + + +static SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + p->ids[coderIndex] = methodId; + if (methodId == XZ_ID_LZMA2) + return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); +#ifdef USE_SUBBLOCK + if (methodId == XZ_ID_Subblock) + return SbState_SetFromMethod(sc, p->alloc); +#endif + if (coderIndex == 0) + return SZ_ERROR_UNSUPPORTED; + return Xz_StateCoder_Bc_SetFromMethod_Func(sc, methodId, + XzBcFilterStateBase_Filter_Dec, p->alloc); +} + + +static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + if (methodId == XZ_ID_LZMA2) + return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); + return SZ_ERROR_UNSUPPORTED; +} + + + +/* + if (destFinish) - then unpack data block is finished at (*destLen) position, + and we can return data that were not processed by filter + +output (status) can be : + CODER_STATUS_NOT_FINISHED + CODER_STATUS_FINISHED_WITH_MARK + CODER_STATUS_NEEDS_MORE_INPUT - not implemented still +*/ + +static SRes MixCoder_Code(CMixCoder *p, + Byte *dest, SizeT *destLen, int destFinish, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + + *destLen = 0; + *srcLen = 0; + + if (p->wasFinished) + return p->res; + + p->status = CODER_STATUS_NOT_FINISHED; + + // if (p->SingleBufMode) + if (p->outBuf) + { + SRes res; + SizeT destLen2, srcLen2; + int wasFinished; + + PRF_STR("------- MixCoder Single ----------") + + srcLen2 = srcLenOrig; + destLen2 = destLenOrig; + + { + IStateCoder *coder = &p->coders[0]; + res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode, + // &wasFinished, + &p->status); + wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK); + } + + p->res = res; + + /* + if (wasFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + else + { + if (res == SZ_OK) + if (destLen2 != destLenOrig) + p->status = CODER_STATUS_NEEDS_MORE_INPUT; + } + */ + + + *srcLen = srcLen2; + src += srcLen2; + p->outWritten += destLen2; + + if (res != SZ_OK || srcWasFinished || wasFinished) + p->wasFinished = True; + + if (p->numCoders == 1) + *destLen = destLen2; + else if (p->wasFinished) + { + unsigned i; + size_t processed = p->outWritten; + + for (i = 1; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + processed = coder->Filter(coder->p, p->outBuf, processed); + if (wasFinished || (destFinish && p->outWritten == destLenOrig)) + processed = p->outWritten; + PRF_STR_INT("filter", i) + } + *destLen = processed; + } + return res; + } + + PRF_STR("standard mix") + + if (p->numCoders != 1) + { + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); + if (!p->buf) + return SZ_ERROR_MEM; + } + + finishMode = CODER_FINISH_ANY; + } + + for (;;) + { + BoolInt processed = False; + BoolInt allFinished = True; + SRes resMain = SZ_OK; + unsigned i; + + p->status = CODER_STATUS_NOT_FINISHED; + /* + if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) + break; + */ + + for (i = 0; i < p->numCoders; i++) + { + SRes res; + IStateCoder *coder = &p->coders[i]; + Byte *dest2; + SizeT destLen2, srcLen2; // destLen2_Orig; + const Byte *src2; + int srcFinished2; + int encodingWasFinished; + ECoderStatus status2; + + if (i == 0) + { + src2 = src; + srcLen2 = srcLenOrig - *srcLen; + srcFinished2 = srcWasFinished; + } + else + { + size_t k = i - 1; + src2 = p->buf + (CODER_BUF_SIZE * k) + p->pos[k]; + srcLen2 = p->size[k] - p->pos[k]; + srcFinished2 = p->finished[k]; + } + + if (i == p->numCoders - 1) + { + dest2 = dest; + destLen2 = destLenOrig - *destLen; + } + else + { + if (p->pos[i] != p->size[i]) + continue; + dest2 = p->buf + (CODER_BUF_SIZE * i); + destLen2 = CODER_BUF_SIZE; + } + + // destLen2_Orig = destLen2; + + if (p->results[i] != SZ_OK) + { + if (resMain == SZ_OK) + resMain = p->results[i]; + continue; + } + + res = coder->Code2(coder->p, + dest2, &destLen2, + src2, &srcLen2, srcFinished2, + finishMode, + // &encodingWasFinished, + &status2); + + if (res != SZ_OK) + { + p->results[i] = res; + if (resMain == SZ_OK) + resMain = res; + } + + encodingWasFinished = (status2 == CODER_STATUS_FINISHED_WITH_MARK); + + if (!encodingWasFinished) + { + allFinished = False; + if (p->numCoders == 1 && res == SZ_OK) + p->status = status2; + } + + if (i == 0) + { + *srcLen += srcLen2; + src += srcLen2; + } + else + p->pos[(size_t)i - 1] += srcLen2; + + if (i == p->numCoders - 1) + { + *destLen += destLen2; + dest += destLen2; + } + else + { + p->size[i] = destLen2; + p->pos[i] = 0; + p->finished[i] = encodingWasFinished; + } + + if (destLen2 != 0 || srcLen2 != 0) + processed = True; + } + + if (!processed) + { + if (allFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + return resMain; + } + } +} + + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) +{ + *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); + if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != + GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) + return SZ_ERROR_NO_ARCHIVE; + return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) +{ + return indexSize == (((UInt64)GetUi32a(buf + 4) + 1) << 2) + && GetUi32a(buf) == CrcCalc(buf + 4, 6) + && flags == GetBe16a(buf + 8) + && GetUi16a(buf + 10) == (XZ_FOOTER_SIG_0 | (XZ_FOOTER_SIG_1 << 8)); +} + +#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ + { const unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; \ + pos += s; } + + +static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p) +{ + const unsigned numFilters = XzBlock_GetNumFilters(p) - 1; + unsigned i; + { + const CXzFilter *f = &p->filters[numFilters]; + if (f->id != XZ_ID_LZMA2 || f->propsSize != 1 || f->props[0] > 40) + return False; + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + if (f->id == XZ_ID_Delta) + { + if (f->propsSize != 1) + return False; + } + else if (!XZ_IS_SUPPORTED_FILTER_ID(f->id) + || (f->propsSize != 0 && f->propsSize != 4)) + return False; + } + return True; +} + + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header) +{ + unsigned pos; + unsigned numFilters, i; + unsigned headerSize = (unsigned)header[0] << 2; + + /* (headerSize != 0) : another code checks */ + + if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) + return SZ_ERROR_ARCHIVE; + + pos = 1; + p->flags = header[pos++]; + + p->packSize = (UInt64)(Int64)-1; + if (XzBlock_HasPackSize(p)) + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize) + if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) + return SZ_ERROR_ARCHIVE; + } + + p->unpackSize = (UInt64)(Int64)-1; + if (XzBlock_HasUnpackSize(p)) + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize) + } + + numFilters = XzBlock_GetNumFilters(p); + for (i = 0; i < numFilters; i++) + { + CXzFilter *filter = p->filters + i; + UInt64 size; + READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id) + READ_VARINT_AND_CHECK(header, pos, headerSize, &size) + if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) + return SZ_ERROR_ARCHIVE; + filter->propsSize = (UInt32)size; + memcpy(filter->props, header + pos, (size_t)size); + pos += (unsigned)size; + + #ifdef XZ_DUMP + printf("\nf[%u] = %2X: ", i, (unsigned)filter->id); + { + unsigned i; + for (i = 0; i < size; i++) + printf(" %2X", filter->props[i]); + } + #endif + } + + if (XzBlock_HasUnsupportedFlags(p)) + return SZ_ERROR_UNSUPPORTED; + + while (pos < headerSize) + if (header[pos++] != 0) + return SZ_ERROR_ARCHIVE; + return SZ_OK; +} + + + + +static SRes XzDecMix_Init(CMixCoder *p, const CXzBlock *block, Byte *outBuf, size_t outBufSize) +{ + unsigned i; + BoolInt needReInit = True; + unsigned numFilters = XzBlock_GetNumFilters(block); + + if (numFilters == p->numCoders && ((p->outBuf && outBuf) || (!p->outBuf && !outBuf))) + { + needReInit = False; + for (i = 0; i < numFilters; i++) + if (p->ids[i] != block->filters[numFilters - 1 - i].id) + { + needReInit = True; + break; + } + } + + // p->SingleBufMode = (outBuf != NULL); + p->outBuf = outBuf; + p->outBufSize = outBufSize; + + // p->SingleBufMode = False; + // outBuf = NULL; + + if (needReInit) + { + MixCoder_Free(p); + for (i = 0; i < numFilters; i++) + { + RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)) + } + p->numCoders = numFilters; + } + else + { + RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)) + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &block->filters[numFilters - 1 - i]; + IStateCoder *sc = &p->coders[i]; + RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)) + } + + MixCoder_Init(p); + return SZ_OK; +} + + + +void XzUnpacker_Init(CXzUnpacker *p) +{ + p->state = XZ_STATE_STREAM_HEADER; + p->pos = 0; + p->numStartedStreams = 0; + p->numFinishedStreams = 0; + p->numTotalBlocks = 0; + p->padSize = 0; + p->decodeOnlyOneBlock = 0; + + p->parseMode = False; + p->decodeToStreamSignature = False; + + // p->outBuf = NULL; + // p->outBufSize = 0; + p->outDataWritten = 0; +} + + +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize) +{ + p->outBuf = outBuf; + p->outBufSize = outBufSize; +} + + +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc) +{ + MixCoder_Construct(&p->decoder, alloc); + p->outBuf = NULL; + p->outBufSize = 0; + XzUnpacker_Init(p); +} + + +void XzUnpacker_Free(CXzUnpacker *p) +{ + MixCoder_Free(&p->decoder); +} + + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p) +{ + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + p->decodeOnlyOneBlock = 1; +} + + +static void XzUnpacker_UpdateIndex(CXzUnpacker *p, UInt64 packSize, UInt64 unpackSize) +{ + Byte temp[32]; + unsigned num = Xz_WriteVarInt(temp, packSize); + num += Xz_WriteVarInt(temp + num, unpackSize); + Sha256_Update(&p->sha, temp, num); + p->indexSize += num; + p->numBlocks++; +} + + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + *destLen = 0; + *srcLen = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + for (;;) + { + SizeT srcRem; + + if (p->state == XZ_STATE_BLOCK) + { + SizeT destLen2 = destLenOrig - *destLen; + SizeT srcLen2 = srcLenOrig - *srcLen; + SRes res; + + ECoderFinishMode finishMode2 = finishMode; + BoolInt srcFinished2 = (BoolInt)srcFinished; + BoolInt destFinish = False; + + if (p->block.packSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.packSize - p->packSize; + if (srcLen2 >= rem) + { + srcFinished2 = True; + srcLen2 = (SizeT)rem; + } + if (rem == 0 && p->block.unpackSize == p->unpackSize) + return SZ_ERROR_DATA; + } + + if (p->block.unpackSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.unpackSize - p->unpackSize; + if (destLen2 >= rem) + { + destFinish = True; + finishMode2 = CODER_FINISH_END; + destLen2 = (SizeT)rem; + } + } + + /* + if (srcLen2 == 0 && destLen2 == 0) + { + *status = CODER_STATUS_NOT_FINISHED; + return SZ_OK; + } + */ + + { + res = MixCoder_Code(&p->decoder, + (p->outBuf ? NULL : dest), &destLen2, destFinish, + src, &srcLen2, srcFinished2, + finishMode2); + + *status = p->decoder.status; + XzCheck_Update(&p->check, (p->outBuf ? p->outBuf + p->outDataWritten : dest), destLen2); + if (!p->outBuf) + dest += destLen2; + p->outDataWritten += destLen2; + } + + (*srcLen) += srcLen2; + src += srcLen2; + p->packSize += srcLen2; + (*destLen) += destLen2; + p->unpackSize += destLen2; + + RINOK(res) + + if (*status != CODER_STATUS_FINISHED_WITH_MARK) + { + if (p->block.packSize == p->packSize + && *status == CODER_STATUS_NEEDS_MORE_INPUT) + { + PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT") + *status = CODER_STATUS_NOT_SPECIFIED; + return SZ_ERROR_DATA; + } + + return SZ_OK; + } + { + XzUnpacker_UpdateIndex(p, XzUnpacker_GetPackSizeForIndex(p), p->unpackSize); + p->state = XZ_STATE_BLOCK_FOOTER; + p->pos = 0; + p->alignPos = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize) + || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize)) + { + PRF_STR("ERROR: block.size mismatch") + return SZ_ERROR_DATA; + } + } + // continue; + } + + srcRem = srcLenOrig - *srcLen; + + // XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes + if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + switch ((int)p->state) + { + case XZ_STATE_STREAM_HEADER: + { + if (p->pos < XZ_STREAM_HEADER_SIZE) + { + if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) + return SZ_ERROR_NO_ARCHIVE; + if (p->decodeToStreamSignature) + return SZ_OK; + p->buf[p->pos++] = *src++; + (*srcLen)++; + } + else + { + RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)) + p->numStartedStreams++; + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + } + break; + } + + case XZ_STATE_BLOCK_HEADER: + { + if (p->pos == 0) + { + p->buf[p->pos++] = *src++; + (*srcLen)++; + if (p->buf[0] == 0) + { + if (p->decodeOnlyOneBlock) + return SZ_ERROR_DATA; + p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); + p->indexPos = p->indexPreSize; + p->indexSize += p->indexPreSize; + Sha256_Final(&p->sha, (Byte *)(void *)p->shaDigest32); + Sha256_Init(&p->sha); + p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); + p->state = XZ_STATE_STREAM_INDEX; + break; + } + p->blockHeaderSize = ((unsigned)p->buf[0] << 2) + 4; + break; + } + + if (p->pos != p->blockHeaderSize) + { + unsigned cur = p->blockHeaderSize - p->pos; + if (cur > srcRem) + cur = (unsigned)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + } + else + { + RINOK(XzBlock_Parse(&p->block, p->buf)) + if (!XzBlock_AreSupportedFilters(&p->block)) + return SZ_ERROR_UNSUPPORTED; + p->numTotalBlocks++; + p->state = XZ_STATE_BLOCK; + p->packSize = 0; + p->unpackSize = 0; + XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); + if (p->parseMode) + { + p->headerParsedOk = True; + return SZ_OK; + } + RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)) + } + break; + } + + case XZ_STATE_BLOCK_FOOTER: + { + if ((((unsigned)p->packSize + p->alignPos) & 3) != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->alignPos++; + if (*src++ != 0) + return SZ_ERROR_CRC; + } + else + { + const unsigned checkSize = XzFlags_GetCheckSize(p->streamFlags); + unsigned cur = checkSize - p->pos; + if (cur != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (cur > srcRem) + cur = (unsigned)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (checkSize != p->pos) + break; + } + { + UInt32 digest32[XZ_CHECK_SIZE_MAX / 4]; + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + if (XzCheck_Final(&p->check, (void *)digest32) && memcmp(digest32, p->buf, checkSize) != 0) + return SZ_ERROR_CRC; + if (p->decodeOnlyOneBlock) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + } + } + break; + } + + case XZ_STATE_STREAM_INDEX: + { + if (p->pos < p->indexPreSize) + { + (*srcLen)++; + if (*src++ != p->buf[p->pos++]) + return SZ_ERROR_CRC; + } + else + { + if (p->indexPos < p->indexSize) + { + UInt64 cur = p->indexSize - p->indexPos; + if (srcRem > cur) + srcRem = (SizeT)cur; + p->crc = CrcUpdate(p->crc, src, srcRem); + Sha256_Update(&p->sha, src, srcRem); + (*srcLen) += srcRem; + src += srcRem; + p->indexPos += srcRem; + } + else if ((p->indexPos & 3) != 0) + { + Byte b = *src++; + p->crc = CRC_UPDATE_BYTE(p->crc, b); + (*srcLen)++; + p->indexPos++; + p->indexSize++; + if (b != 0) + return SZ_ERROR_CRC; + } + else + { + UInt32 digest32[SHA256_DIGEST_SIZE / 4]; + p->state = XZ_STATE_STREAM_INDEX_CRC; + p->indexSize += 4; + p->pos = 0; + Sha256_Final(&p->sha, (void *)digest32); + if (memcmp(digest32, p->shaDigest32, SHA256_DIGEST_SIZE) != 0) + return SZ_ERROR_CRC; + } + } + break; + } + + case XZ_STATE_STREAM_INDEX_CRC: + { + if (p->pos < 4) + { + (*srcLen)++; + p->buf[p->pos++] = *src++; + } + else + { + const Byte *ptr = p->buf; + p->state = XZ_STATE_STREAM_FOOTER; + p->pos = 0; + if (CRC_GET_DIGEST(p->crc) != GetUi32a(ptr)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_FOOTER: + { + unsigned cur = XZ_STREAM_FOOTER_SIZE - p->pos; + if (cur > srcRem) + cur = (unsigned)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (p->pos == XZ_STREAM_FOOTER_SIZE) + { + p->state = XZ_STATE_STREAM_PADDING; + p->numFinishedStreams++; + p->padSize = 0; + if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_PADDING: + { + if (*src != 0) + { + if ((unsigned)p->padSize & 3) + return SZ_ERROR_NO_ARCHIVE; + p->pos = 0; + p->state = XZ_STATE_STREAM_HEADER; + } + else + { + (*srcLen)++; + src++; + p->padSize++; + } + break; + } + + case XZ_STATE_BLOCK: break; /* to disable GCC warning */ + + default: return SZ_ERROR_FAIL; + } + } + /* + if (p->state == XZ_STATE_FINISHED) + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + */ +} + + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + XzUnpacker_Init(p); + XzUnpacker_SetOutBuf(p, dest, *destLen); + + return XzUnpacker_Code(p, + NULL, destLen, + src, srcLen, True, + finishMode, status); +} + + +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0); +} + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); +} + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p) +{ + UInt64 num = 0; + if (p->state == XZ_STATE_STREAM_PADDING) + num = p->padSize; + else if (p->state == XZ_STATE_STREAM_HEADER) + num = p->padSize + p->pos; + return num; +} + + + + + + + + + + + + + + + + + + + + + +#ifndef Z7_ST +#include "MtDec.h" +#endif + + +void XzDecMtProps_Init(CXzDecMtProps *p) +{ + p->inBufSize_ST = 1 << 18; + p->outStep_ST = 1 << 20; + p->ignoreErrors = False; + + #ifndef Z7_ST + p->numThreads = 1; + p->inBufSize_MT = 1 << 18; + p->memUseMax = sizeof(size_t) << 28; + #endif +} + + + +#ifndef Z7_ST + +/* ---------- CXzDecMtThread ---------- */ + +typedef struct +{ + Byte *outBuf; + size_t outBufSize; + size_t outPreSize; + size_t inPreSize; + size_t inPreHeaderSize; + size_t blockPackSize_for_Index; // including block header and checksum. + size_t blockPackTotal; // including stream header, block header and checksum. + size_t inCodeSize; + size_t outCodeSize; + ECoderStatus status; + SRes codeRes; + BoolInt skipMode; + // BoolInt finishedWithMark; + EMtDecParseState parseState; + BoolInt parsing_Truncated; + BoolInt atBlockHeader; + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + BoolInt dec_created; + CXzUnpacker dec; + + Byte mtPad[1 << 7]; +} CXzDecMtThread; + +#endif + + +/* ---------- CXzDecMt ---------- */ + +struct CXzDecMt +{ + CAlignOffsetAlloc alignOffsetAlloc; + ISzAllocPtr allocMid; + + CXzDecMtProps props; + size_t unpackBlockMaxSize; + + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; + + BoolInt finishMode; + BoolInt outSize_Defined; + UInt64 outSize; + + UInt64 outProcessed; + UInt64 inProcessed; + UInt64 readProcessed; + BoolInt readWasFinished; + SRes readRes; + SRes writeRes; + + Byte *outBuf; + size_t outBufSize; + Byte *inBuf; + size_t inBufSize; + + CXzUnpacker dec; + + ECoderStatus status; + SRes codeRes; + + #ifndef Z7_ST + BoolInt mainDecoderWasCalled; + // int statErrorDefined; + int finishedDecoderIndex; + + // global values that are used in Parse stage + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + // UInt64 numBadBlocks; + SRes mainErrorCode; // it's set to error code, if the size Code() output doesn't patch the size from Parsing stage + // it can be = SZ_ERROR_INPUT_EOF + // it can be = SZ_ERROR_DATA, in some another cases + BoolInt isBlockHeaderState_Parse; + BoolInt isBlockHeaderState_Write; + UInt64 outProcessed_Parse; + BoolInt parsing_Truncated; + + BoolInt mtc_WasConstructed; + CMtDec mtc; + CXzDecMtThread coders[MTDEC_THREADS_MAX]; + #endif +}; + + + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) +{ + CXzDecMt *p = (CXzDecMt *)ISzAlloc_Alloc(alloc, sizeof(CXzDecMt)); + if (!p) + return NULL; + + AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); + p->alignOffsetAlloc.baseAlloc = alloc; + p->alignOffsetAlloc.numAlignBits = 7; + p->alignOffsetAlloc.offset = 0; + + p->allocMid = allocMid; + + p->outBuf = NULL; + p->outBufSize = 0; + p->inBuf = NULL; + p->inBufSize = 0; + + XzUnpacker_Construct(&p->dec, &p->alignOffsetAlloc.vt); + + p->unpackBlockMaxSize = 0; + + XzDecMtProps_Init(&p->props); + + #ifndef Z7_ST + p->mtc_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + coder->dec_created = False; + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + #endif + + return (CXzDecMtHandle)p; +} + + +#ifndef Z7_ST + +static void XzDecMt_FreeOutBufs(CXzDecMt *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + if (coder->outBuf) + { + ISzAlloc_Free(p->allocMid, coder->outBuf); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + p->unpackBlockMaxSize = 0; +} + +#endif + + + +static void XzDecMt_FreeSt(CXzDecMt *p) +{ + XzUnpacker_Free(&p->dec); + + if (p->outBuf) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBuf = NULL; + } + p->outBufSize = 0; + + if (p->inBuf) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBuf = NULL; + } + p->inBufSize = 0; +} + + +// #define GET_CXzDecMt_p CXzDecMt *p = pp; + +void XzDecMt_Destroy(CXzDecMtHandle p) +{ + // GET_CXzDecMt_p + + XzDecMt_FreeSt(p); + + #ifndef Z7_ST + + if (p->mtc_WasConstructed) + { + MtDec_Destruct(&p->mtc); + p->mtc_WasConstructed = False; + } + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *t = &p->coders[i]; + if (t->dec_created) + { + // we don't need to free dict here + XzUnpacker_Free(&t->dec); + t->dec_created = False; + } + } + } + XzDecMt_FreeOutBufs(p); + + #endif + + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); +} + + + +#ifndef Z7_ST + +static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) +{ + CXzDecMt *me = (CXzDecMt *)obj; + CXzDecMtThread *coder = &me->coders[coderIndex]; + size_t srcSize = cc->srcSize; + + cc->srcSize = 0; + cc->outPos = 0; + cc->state = MTDEC_PARSE_CONTINUE; + + cc->canCreateNewThread = True; + + if (cc->startCall) + { + coder->outPreSize = 0; + coder->inPreSize = 0; + coder->inPreHeaderSize = 0; + coder->parseState = MTDEC_PARSE_CONTINUE; + coder->parsing_Truncated = False; + coder->skipMode = False; + coder->codeRes = SZ_OK; + coder->status = CODER_STATUS_NOT_SPECIFIED; + coder->inCodeSize = 0; + coder->outCodeSize = 0; + + coder->numStreams = me->numStreams; + coder->numTotalBlocks = me->numTotalBlocks; + coder->numBlocks = me->numBlocks; + + if (!coder->dec_created) + { + XzUnpacker_Construct(&coder->dec, &me->alignOffsetAlloc.vt); + coder->dec_created = True; + } + + XzUnpacker_Init(&coder->dec); + + if (me->isBlockHeaderState_Parse) + { + coder->dec.streamFlags = me->streamFlags; + coder->atBlockHeader = True; + XzUnpacker_PrepareToRandomBlockDecoding(&coder->dec); + } + else + { + coder->atBlockHeader = False; + me->isBlockHeaderState_Parse = True; + } + + coder->dec.numStartedStreams = me->numStreams; + coder->dec.numTotalBlocks = me->numTotalBlocks; + coder->dec.numBlocks = me->numBlocks; + } + + while (!coder->skipMode) + { + ECoderStatus status; + SRes res; + size_t srcSize2 = srcSize; + size_t destSize = (size_t)0 - 1; + + coder->dec.parseMode = True; + coder->dec.headerParsedOk = False; + + PRF_STR_INT("Parse", srcSize2) + + res = XzUnpacker_Code(&coder->dec, + NULL, &destSize, + cc->src, &srcSize2, cc->srcFinished, + CODER_FINISH_END, &status); + + // PRF(printf(" res = %d, srcSize2 = %d", res, (unsigned)srcSize2)); + + coder->codeRes = res; + coder->status = status; + cc->srcSize += srcSize2; + srcSize -= srcSize2; + coder->inPreHeaderSize += srcSize2; + coder->inPreSize = coder->inPreHeaderSize; + + if (res != SZ_OK) + { + cc->state = + coder->parseState = MTDEC_PARSE_END; + /* + if (res == SZ_ERROR_MEM) + return res; + return SZ_OK; + */ + return; // res; + } + + if (coder->dec.headerParsedOk) + { + const CXzBlock *block = &coder->dec.block; + if (XzBlock_HasUnpackSize(block) + // && block->unpackSize <= me->props.outBlockMax + && XzBlock_HasPackSize(block)) + { + { + if (block->unpackSize * 2 * me->mtc.numStartedThreads > me->props.memUseMax) + { + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + } + { + const UInt64 packSize = block->packSize; + const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + const unsigned checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); + const UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; + // if (blockPackSum <= me->props.inBlockMax) + // unpackBlockMaxSize + { + coder->blockPackSize_for_Index = (size_t)(coder->dec.blockHeaderSize + packSize + checkSize); + coder->blockPackTotal = (size_t)blockPackSum; + coder->outPreSize = (size_t)block->unpackSize; + coder->streamFlags = coder->dec.streamFlags; + me->streamFlags = coder->dec.streamFlags; + coder->skipMode = True; + break; + } + } + } + } + else + // if (coder->inPreSize <= me->props.inBlockMax) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = + coder->parseState = MTDEC_PARSE_END; + return; // SZ_OK; + } + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + + // ---------- skipMode ---------- + { + UInt64 rem = coder->blockPackTotal - coder->inPreSize; + size_t cur = srcSize; + if (cur > rem) + cur = (size_t)rem; + cc->srcSize += cur; + coder->inPreSize += cur; + srcSize -= cur; + + if (coder->inPreSize == coder->blockPackTotal) + { + if (srcSize == 0) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = MTDEC_PARSE_END; + } + else if ((cc->src)[cc->srcSize] == 0) // we check control byte of next block + cc->state = MTDEC_PARSE_END; + else + { + cc->state = MTDEC_PARSE_NEW; + + { + size_t blockMax = me->unpackBlockMaxSize; + if (blockMax < coder->outPreSize) + blockMax = coder->outPreSize; + { + UInt64 required = (UInt64)blockMax * (me->mtc.numStartedThreads + 1) * 2; + if (me->props.memUseMax < required) + cc->canCreateNewThread = False; + } + } + + if (me->outSize_Defined) + { + // next block can be zero size + const UInt64 rem2 = me->outSize - me->outProcessed_Parse; + if (rem2 < coder->outPreSize) + { + coder->parsing_Truncated = True; + cc->state = MTDEC_PARSE_END; + } + me->outProcessed_Parse += coder->outPreSize; + } + } + } + else if (cc->srcFinished) + cc->state = MTDEC_PARSE_END; + else + return; // SZ_OK; + + coder->parseState = cc->state; + cc->outPos = coder->outPreSize; + + me->numStreams = coder->dec.numStartedStreams; + me->numTotalBlocks = coder->dec.numTotalBlocks; + me->numBlocks = coder->dec.numBlocks + 1; + return; // SZ_OK; + } +} + + +static SRes XzDecMt_Callback_PreCode(void *pp, unsigned coderIndex) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + Byte *dest; + + if (!coder->dec.headerParsedOk) + return SZ_OK; + + dest = coder->outBuf; + + if (!dest || coder->outBufSize < coder->outPreSize) + { + if (dest) + { + ISzAlloc_Free(me->allocMid, dest); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + { + size_t outPreSize = coder->outPreSize; + if (outPreSize == 0) + outPreSize = 1; + dest = (Byte *)ISzAlloc_Alloc(me->allocMid, outPreSize); + } + if (!dest) + return SZ_ERROR_MEM; + coder->outBuf = dest; + coder->outBufSize = coder->outPreSize; + + if (coder->outBufSize > me->unpackBlockMaxSize) + me->unpackBlockMaxSize = coder->outBufSize; + } + + // return SZ_ERROR_MEM; + + XzUnpacker_SetOutBuf(&coder->dec, coder->outBuf, coder->outBufSize); + + { + SRes res = XzDecMix_Init(&coder->dec.decoder, &coder->dec.block, coder->outBuf, coder->outBufSize); + // res = SZ_ERROR_UNSUPPORTED; // to test + coder->codeRes = res; + if (res != SZ_OK) + { + // if (res == SZ_ERROR_MEM) return res; + if (me->props.ignoreErrors && res != SZ_ERROR_MEM) + return SZ_OK; + return res; + } + } + + return SZ_OK; +} + + +static SRes XzDecMt_Callback_Code(void *pp, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + // int finished, int blockFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + *stop = True; + + if (srcSize > coder->inPreSize - coder->inCodeSize) + return SZ_ERROR_FAIL; + + if (coder->inCodeSize < coder->inPreHeaderSize) + { + size_t step = coder->inPreHeaderSize - coder->inCodeSize; + if (step > srcSize) + step = srcSize; + src += step; + srcSize -= step; + coder->inCodeSize += step; + *inCodePos = coder->inCodeSize; + if (coder->inCodeSize < coder->inPreHeaderSize) + { + *stop = False; + return SZ_OK; + } + } + + if (!coder->dec.headerParsedOk) + return SZ_OK; + if (!coder->outBuf) + return SZ_OK; + + if (coder->codeRes == SZ_OK) + { + ECoderStatus status; + SRes res; + size_t srcProcessed = srcSize; + size_t outSizeCur = coder->outPreSize - coder->dec.outDataWritten; + + // PRF(printf("\nCallback_Code: Code %d %d\n", (unsigned)srcSize, (unsigned)outSizeCur)); + + res = XzUnpacker_Code(&coder->dec, + NULL, &outSizeCur, + src, &srcProcessed, srcFinished, + // coder->finishedWithMark ? CODER_FINISH_END : CODER_FINISH_ANY, + CODER_FINISH_END, + &status); + + // PRF(printf(" res = %d, srcSize2 = %d, outSizeCur = %d", res, (unsigned)srcProcessed, (unsigned)outSizeCur)); + + coder->codeRes = res; + coder->status = status; + coder->inCodeSize += srcProcessed; + coder->outCodeSize = coder->dec.outDataWritten; + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + + if (res == SZ_OK) + { + if (srcProcessed == srcSize) + *stop = False; + return SZ_OK; + } + } + + if (me->props.ignoreErrors && coder->codeRes != SZ_ERROR_MEM) + { + *inCodePos = coder->inPreSize; + *outCodePos = coder->outPreSize; + return SZ_OK; + } + return coder->codeRes; +} + + +#define XZDECMT_STREAM_WRITE_STEP (1 << 24) + +static SRes XzDecMt_Callback_Write(void *pp, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + // int srcFinished, + BoolInt *needContinue, + BoolInt *canRecode) +{ + CXzDecMt *me = (CXzDecMt *)pp; + const CXzDecMtThread *coder = &me->coders[coderIndex]; + + // PRF(printf("\nWrite processed = %d srcSize = %d\n", (unsigned)me->mtc.inProcessed, (unsigned)srcSize)); + + *needContinue = False; + *canRecode = True; + + if (!needWriteToStream) + return SZ_OK; + + if (!coder->dec.headerParsedOk || !coder->outBuf) + { + if (me->finishedDecoderIndex < 0) + me->finishedDecoderIndex = (int)coderIndex; + return SZ_OK; + } + + if (me->finishedDecoderIndex >= 0) + return SZ_OK; + + me->mtc.inProcessed += coder->inCodeSize; + + *canRecode = False; + + { + SRes res; + size_t size = coder->outCodeSize; + Byte *data = coder->outBuf; + + // we use in me->dec: sha, numBlocks, indexSize + + if (!me->isBlockHeaderState_Write) + { + XzUnpacker_PrepareToRandomBlockDecoding(&me->dec); + me->dec.decodeOnlyOneBlock = False; + me->dec.numStartedStreams = coder->dec.numStartedStreams; + me->dec.streamFlags = coder->streamFlags; + + me->isBlockHeaderState_Write = True; + } + + me->dec.numTotalBlocks = coder->dec.numTotalBlocks; + XzUnpacker_UpdateIndex(&me->dec, coder->blockPackSize_for_Index, coder->outPreSize); + + if (coder->outPreSize != size) + { + if (me->props.ignoreErrors) + { + memset(data + size, 0, coder->outPreSize - size); + size = coder->outPreSize; + } + // me->numBadBlocks++; + if (me->mainErrorCode == SZ_OK) + { + if ((int)coder->status == LZMA_STATUS_NEEDS_MORE_INPUT) + me->mainErrorCode = SZ_ERROR_INPUT_EOF; + else + me->mainErrorCode = SZ_ERROR_DATA; + } + } + + if (me->writeRes != SZ_OK) + return me->writeRes; + + res = SZ_OK; + { + if (me->outSize_Defined) + { + const UInt64 rem = me->outSize - me->outProcessed; + if (size > rem) + size = (SizeT)rem; + } + + for (;;) + { + size_t cur = size; + size_t written; + if (cur > XZDECMT_STREAM_WRITE_STEP) + cur = XZDECMT_STREAM_WRITE_STEP; + + written = ISeqOutStream_Write(me->outStream, data, cur); + + // PRF(printf("\nWritten ask = %d written = %d\n", (unsigned)cur, (unsigned)written)); + + me->outProcessed += written; + if (written != cur) + { + me->writeRes = SZ_ERROR_WRITE; + res = me->writeRes; + break; + } + data += cur; + size -= cur; + // PRF_STR_INT("Written size =", size) + if (size == 0) + break; + res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0); + if (res != SZ_OK) + break; + } + } + + if (coder->codeRes != SZ_OK) + if (!me->props.ignoreErrors) + { + me->finishedDecoderIndex = (int)coderIndex; + return res; + } + + RINOK(res) + + if (coder->inPreSize != coder->inCodeSize + || coder->blockPackTotal != coder->inCodeSize) + { + me->finishedDecoderIndex = (int)coderIndex; + return SZ_OK; + } + + if (coder->parseState != MTDEC_PARSE_END) + { + *needContinue = True; + return SZ_OK; + } + } + + // (coder->state == MTDEC_PARSE_END) means that there are no other working threads + // so we can use mtc variables without lock + + PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed) + + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + { + CXzUnpacker *dec = &me->dec; + + PRF_STR_INT("PostSingle", srcSize) + + { + size_t srcProcessed = srcSize; + ECoderStatus status; + size_t outSizeCur = 0; + SRes res; + + // dec->decodeOnlyOneBlock = False; + dec->decodeToStreamSignature = True; + + me->mainDecoderWasCalled = True; + + if (coder->parsing_Truncated) + { + me->parsing_Truncated = True; + return SZ_OK; + } + + /* + We have processed all xz-blocks of stream, + And xz unpacker is at XZ_STATE_BLOCK_HEADER state, where + (src) is a pointer to xz-Index structure. + We finish reading of current xz-Stream, including Zero padding after xz-Stream. + We exit, if we reach extra byte (first byte of new-Stream or another data). + But we don't update input stream pointer for that new extra byte. + If extra byte is not correct first byte of xz-signature, + we have SZ_ERROR_NO_ARCHIVE error here. + */ + + res = XzUnpacker_Code(dec, + NULL, &outSizeCur, + src, &srcProcessed, + me->mtc.readWasFinished, // srcFinished + CODER_FINISH_END, // CODER_FINISH_ANY, + &status); + + // res = SZ_ERROR_ARCHIVE; // for failure test + + me->status = status; + me->codeRes = res; + + if (isCross) + me->mtc.crossStart += srcProcessed; + + me->mtc.inProcessed += srcProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + srcSize -= srcProcessed; + src += srcProcessed; + + if (res != SZ_OK) + { + return SZ_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + + if (!isCross) + { + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + if (srcSize != 0) + memcpy(crossBuf, src, srcSize); + me->mtc.crossStart = 0; + me->mtc.crossEnd = srcSize; + } + + PRF_STR_INT("XZ_STATE_STREAM_HEADER crossEnd = ", (unsigned)me->mtc.crossEnd) + + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT || srcSize != 0) + { + return SZ_ERROR_FAIL; + } + + if (me->mtc.readWasFinished) + { + return SZ_OK; + } + } + + { + size_t inPos; + size_t inLim; + // const Byte *inData; + UInt64 inProgressPrev = me->mtc.inProcessed; + + // XzDecMt_Prepare_InBuf_ST(p); + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + + inPos = 0; + inLim = 0; + + // inData = crossBuf; + + for (;;) + { + SizeT inProcessed; + SizeT outProcessed; + ECoderStatus status; + SRes res; + + if (inPos == inLim) + { + if (!me->mtc.readWasFinished) + { + inPos = 0; + inLim = me->mtc.inBufSize; + me->mtc.readRes = ISeqInStream_Read(me->inStream, (void *)crossBuf, &inLim); + me->mtc.readProcessed += inLim; + if (inLim == 0 || me->mtc.readRes != SZ_OK) + me->mtc.readWasFinished = True; + } + } + + inProcessed = inLim - inPos; + outProcessed = 0; + + res = XzUnpacker_Code(dec, + NULL, &outProcessed, + crossBuf + inPos, &inProcessed, + (inProcessed == 0), // srcFinished + CODER_FINISH_END, &status); + + me->codeRes = res; + me->status = status; + inPos += inProcessed; + me->mtc.inProcessed += inProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + if (res != SZ_OK) + { + return SZ_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->mtc.crossStart = inPos; + me->mtc.crossEnd = inLim; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT) + return SZ_ERROR_FAIL; + + if (me->mtc.progress) + { + UInt64 inDelta = me->mtc.inProcessed - inProgressPrev; + if (inDelta >= (1 << 22)) + { + RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)) + inProgressPrev = me->mtc.inProcessed; + } + } + if (me->mtc.readWasFinished) + return SZ_OK; + } + } + } +} + + +#endif + + + +void XzStatInfo_Clear(CXzStatInfo *p) +{ + p->InSize = 0; + p->OutSize = 0; + + p->NumStreams = 0; + p->NumBlocks = 0; + + p->UnpackSize_Defined = False; + + p->NumStreams_Defined = False; + p->NumBlocks_Defined = False; + + p->DataAfterEnd = False; + p->DecodingTruncated = False; + + p->DecodeRes = SZ_OK; + p->ReadRes = SZ_OK; + p->ProgressRes = SZ_OK; + + p->CombinedRes = SZ_OK; + p->CombinedRes_Type = SZ_OK; +} + + + +/* + XzDecMt_Decode_ST() can return SZ_OK or the following errors + - SZ_ERROR_MEM for memory allocation error + - error from XzUnpacker_Code() function + - SZ_ERROR_WRITE for ISeqOutStream::Write(). stat->CombinedRes_Type = SZ_ERROR_WRITE in that case + - ICompressProgress::Progress() error, stat->CombinedRes_Type = SZ_ERROR_PROGRESS. + But XzDecMt_Decode_ST() doesn't return ISeqInStream::Read() errors. + ISeqInStream::Read() result is set to p->readRes. + also it can set stat->CombinedRes_Type to SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. +*/ + +static SRes XzDecMt_Decode_ST(CXzDecMt *p + #ifndef Z7_ST + , BoolInt tMode + #endif + , CXzStatInfo *stat) +{ + size_t outPos; + size_t inPos, inLim; + const Byte *inData; + UInt64 inPrev, outPrev; + + CXzUnpacker *dec; + + #ifndef Z7_ST + if (tMode) + { + XzDecMt_FreeOutBufs(p); + tMode = (BoolInt)MtDec_PrepareRead(&p->mtc); + } + #endif + + if (!p->outBuf || p->outBufSize != p->props.outStep_ST) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBufSize = 0; + p->outBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.outStep_ST); + if (!p->outBuf) + return SZ_ERROR_MEM; + p->outBufSize = p->props.outStep_ST; + } + + if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBufSize = 0; + p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); + if (!p->inBuf) + return SZ_ERROR_MEM; + p->inBufSize = p->props.inBufSize_ST; + } + + dec = &p->dec; + dec->decodeToStreamSignature = False; + // dec->decodeOnlyOneBlock = False; + + XzUnpacker_SetOutBuf(dec, NULL, 0); + + inPrev = p->inProcessed; + outPrev = p->outProcessed; + + inPos = 0; + inLim = 0; + inData = NULL; + outPos = 0; + + for (;;) + { + SizeT outSize; + BoolInt finished; + ECoderFinishMode finishMode; + SizeT inProcessed; + ECoderStatus status; + SRes res; + + SizeT outProcessed; + + + + if (inPos == inLim) + { + #ifndef Z7_ST + if (tMode) + { + inData = MtDec_Read(&p->mtc, &inLim); + inPos = 0; + if (inData) + continue; + tMode = False; + inLim = 0; + } + #endif + + if (!p->readWasFinished) + { + inPos = 0; + inLim = p->inBufSize; + inData = p->inBuf; + p->readRes = ISeqInStream_Read(p->inStream, (void *)p->inBuf, &inLim); + p->readProcessed += inLim; + if (inLim == 0 || p->readRes != SZ_OK) + p->readWasFinished = True; + } + } + + outSize = p->props.outStep_ST - outPos; + + finishMode = CODER_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (outSize >= rem) + { + outSize = (SizeT)rem; + if (p->finishMode) + finishMode = CODER_FINISH_END; + } + } + + inProcessed = inLim - inPos; + outProcessed = outSize; + + res = XzUnpacker_Code(dec, p->outBuf + outPos, &outProcessed, + inData + inPos, &inProcessed, + (inPos == inLim), // srcFinished + finishMode, &status); + + p->codeRes = res; + p->status = status; + + inPos += inProcessed; + outPos += outProcessed; + p->inProcessed += inProcessed; + p->outProcessed += outProcessed; + + finished = ((inProcessed == 0 && outProcessed == 0) || res != SZ_OK); + + if (finished || outProcessed >= outSize) + if (outPos != 0) + { + const size_t written = ISeqOutStream_Write(p->outStream, p->outBuf, outPos); + // p->outProcessed += written; // 21.01: BUG fixed + if (written != outPos) + { + stat->CombinedRes_Type = SZ_ERROR_WRITE; + return SZ_ERROR_WRITE; + } + outPos = 0; + } + + if (p->progress && res == SZ_OK) + { + if (p->inProcessed - inPrev >= (1 << 22) || + p->outProcessed - outPrev >= (1 << 22)) + { + res = ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed); + if (res != SZ_OK) + { + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + stat->ProgressRes = res; + return res; + } + inPrev = p->inProcessed; + outPrev = p->outProcessed; + } + } + + if (finished) + { + // p->codeRes is preliminary error from XzUnpacker_Code. + // and it can be corrected later as final result + // so we return SZ_OK here instead of (res); + return SZ_OK; + // return res; + } + } +} + + + +/* +XzStatInfo_SetStat() transforms + CXzUnpacker return code and status to combined CXzStatInfo results. + it can convert SZ_OK to SZ_ERROR_INPUT_EOF + it can convert SZ_ERROR_NO_ARCHIVE to SZ_OK and (DataAfterEnd = 1) +*/ + +static void XzStatInfo_SetStat(const CXzUnpacker *dec, + int finishMode, + // UInt64 readProcessed, + UInt64 inProcessed, + SRes res, // it's result from CXzUnpacker unpacker + ECoderStatus status, + BoolInt decodingTruncated, + CXzStatInfo *stat) +{ + UInt64 extraSize; + + stat->DecodingTruncated = (Byte)(decodingTruncated ? 1 : 0); + stat->InSize = inProcessed; + stat->NumStreams = dec->numStartedStreams; + stat->NumBlocks = dec->numTotalBlocks; + + stat->UnpackSize_Defined = True; + stat->NumStreams_Defined = True; + stat->NumBlocks_Defined = True; + + extraSize = XzUnpacker_GetExtraSize(dec); + + if (res == SZ_OK) + { + if (status == CODER_STATUS_NEEDS_MORE_INPUT) + { + // CODER_STATUS_NEEDS_MORE_INPUT is expected status for correct xz streams + // any extra data is part of correct data + extraSize = 0; + // if xz stream was not finished, then we need more data + if (!XzUnpacker_IsStreamWasFinished(dec)) + res = SZ_ERROR_INPUT_EOF; + } + else + { + // CODER_STATUS_FINISHED_WITH_MARK is not possible for multi stream xz decoding + // so he we have (status == CODER_STATUS_NOT_FINISHED) + // if (status != CODER_STATUS_FINISHED_WITH_MARK) + if (!decodingTruncated || finishMode) + res = SZ_ERROR_DATA; + } + } + else if (res == SZ_ERROR_NO_ARCHIVE) + { + /* + SZ_ERROR_NO_ARCHIVE is possible for 2 states: + XZ_STATE_STREAM_HEADER - if bad signature or bad CRC + XZ_STATE_STREAM_PADDING - if non-zero padding data + extraSize and inProcessed don't include "bad" byte + */ + // if (inProcessed == extraSize), there was no any good xz stream header, and we keep error + if (inProcessed != extraSize) // if there were good xz streams before error + { + // if (extraSize != 0 || readProcessed != inProcessed) + { + // he we suppose that all xz streams were finsihed OK, and we have + // some extra data after all streams + stat->DataAfterEnd = True; + res = SZ_OK; + } + } + } + + if (stat->DecodeRes == SZ_OK) + stat->DecodeRes = res; + + stat->InSize -= extraSize; +} + + + +SRes XzDecMt_Decode(CXzDecMtHandle p, + const CXzDecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqOutStreamPtr outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, + int *isMT, + ICompressProgressPtr progress) +{ + // GET_CXzDecMt_p + #ifndef Z7_ST + BoolInt tMode; + #endif + + XzStatInfo_Clear(stat); + + p->props = *props; + + p->inStream = inStream; + p->outStream = outStream; + p->progress = progress; + // p->stat = stat; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + + p->finishMode = (BoolInt)finishMode; + + // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test + + p->writeRes = SZ_OK; + p->outProcessed = 0; + p->inProcessed = 0; + p->readProcessed = 0; + p->readWasFinished = False; + p->readRes = SZ_OK; + + p->codeRes = SZ_OK; + p->status = CODER_STATUS_NOT_SPECIFIED; + + XzUnpacker_Init(&p->dec); + + *isMT = False; + + /* + p->outBuf = NULL; + p->outBufSize = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBufSize = *outBufSize; + *outBufSize = 0; + } + */ + + + #ifndef Z7_ST + + p->isBlockHeaderState_Parse = False; + p->isBlockHeaderState_Write = False; + // p->numBadBlocks = 0; + p->mainErrorCode = SZ_OK; + p->mainDecoderWasCalled = False; + + tMode = False; + + if (p->props.numThreads > 1) + { + IMtDecCallback2 vt; + BoolInt needContinue; + SRes res; + // we just free ST buffers here + // but we still keep state variables, that was set in XzUnpacker_Init() + XzDecMt_FreeSt(p); + + p->outProcessed_Parse = 0; + p->parsing_Truncated = False; + + p->numStreams = 0; + p->numTotalBlocks = 0; + p->numBlocks = 0; + p->finishedDecoderIndex = -1; + + if (!p->mtc_WasConstructed) + { + p->mtc_WasConstructed = True; + MtDec_Construct(&p->mtc); + } + + p->mtc.mtCallback = &vt; + p->mtc.mtCallbackObject = p; + + p->mtc.progress = progress; + p->mtc.inStream = inStream; + p->mtc.alloc = &p->alignOffsetAlloc.vt; + // p->mtc.inData = inData; + // p->mtc.inDataSize = inDataSize; + p->mtc.inBufSize = p->props.inBufSize_MT; + // p->mtc.inBlockMax = p->props.inBlockMax; + p->mtc.numThreadsMax = p->props.numThreads; + + *isMT = True; + + vt.Parse = XzDecMt_Callback_Parse; + vt.PreCode = XzDecMt_Callback_PreCode; + vt.Code = XzDecMt_Callback_Code; + vt.Write = XzDecMt_Callback_Write; + + + res = MtDec_Code(&p->mtc); + + + stat->InSize = p->mtc.inProcessed; + + p->inProcessed = p->mtc.inProcessed; + p->readRes = p->mtc.readRes; + p->readWasFinished = p->mtc.readWasFinished; + p->readProcessed = p->mtc.readProcessed; + + tMode = True; + needContinue = False; + + if (res == SZ_OK) + { + if (p->mtc.mtProgress.res != SZ_OK) + { + res = p->mtc.mtProgress.res; + stat->ProgressRes = res; + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + } + else + needContinue = p->mtc.needContinue; + } + + if (!needContinue) + { + { + SRes codeRes; + BoolInt truncated = False; + ECoderStatus status; + const CXzUnpacker *dec; + + stat->OutSize = p->outProcessed; + + if (p->finishedDecoderIndex >= 0) + { + const CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex]; + codeRes = coder->codeRes; + dec = &coder->dec; + status = coder->status; + } + else if (p->mainDecoderWasCalled) + { + codeRes = p->codeRes; + dec = &p->dec; + status = p->status; + truncated = p->parsing_Truncated; + } + else + return SZ_ERROR_FAIL; + + if (p->mainErrorCode != SZ_OK) + stat->DecodeRes = p->mainErrorCode; + + XzStatInfo_SetStat(dec, p->finishMode, + // p->mtc.readProcessed, + p->mtc.inProcessed, + codeRes, status, + truncated, + stat); + } + + if (res == SZ_OK) + { + stat->ReadRes = p->mtc.readRes; + + if (p->writeRes != SZ_OK) + { + res = p->writeRes; + stat->CombinedRes_Type = SZ_ERROR_WRITE; + } + else if (p->mtc.readRes != SZ_OK + // && p->mtc.inProcessed == p->mtc.readProcessed + && stat->DecodeRes == SZ_ERROR_INPUT_EOF) + { + res = p->mtc.readRes; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + else if (stat->DecodeRes != SZ_OK) + res = stat->DecodeRes; + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } + + PRF_STR("----- decoding ST -----") + } + + #endif + + + *isMT = False; + + { + SRes res = XzDecMt_Decode_ST(p + #ifndef Z7_ST + , tMode + #endif + , stat + ); + + #ifndef Z7_ST + // we must set error code from MT decoding at first + if (p->mainErrorCode != SZ_OK) + stat->DecodeRes = p->mainErrorCode; + #endif + + XzStatInfo_SetStat(&p->dec, + p->finishMode, + // p->readProcessed, + p->inProcessed, + p->codeRes, p->status, + False, // truncated + stat); + + stat->ReadRes = p->readRes; + + if (res == SZ_OK) + { + if (p->readRes != SZ_OK + // && p->inProcessed == p->readProcessed + && stat->DecodeRes == SZ_ERROR_INPUT_EOF) + { + // we set read error as combined error, only if that error was the reason + // of decoding problem + res = p->readRes; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + else if (stat->DecodeRes != SZ_OK) + res = stat->DecodeRes; + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } +} + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff -Nru p7zip-rar-16.02/C/XzEnc.c p7zip-rar-16.02+really25.00+ds/C/XzEnc.c --- p7zip-rar-16.02/C/XzEnc.c 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzEnc.c 2025-07-04 06:00:00.000000000 +0000 @@ -1,538 +1,1374 @@ -/* XzEnc.c -- Xz Encode -2015-09-16 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include -#include - -#include "7zCrc.h" -#include "Alloc.h" -#include "Bra.h" -#include "CpuArch.h" - -#ifdef USE_SUBBLOCK -#include "Bcj3Enc.c" -#include "SbFind.c" -#include "SbEnc.c" -#endif - -#include "XzEnc.h" - -#define XzBlock_ClearFlags(p) (p)->flags = 0; -#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1); -#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; -#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; - -static SRes WriteBytes(ISeqOutStream *s, const void *buf, UInt32 size) -{ - return (s->Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; -} - -static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UInt32 *crc) -{ - *crc = CrcUpdate(*crc, buf, size); - return WriteBytes(s, buf, size); -} - -static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s) -{ - UInt32 crc; - Byte header[XZ_STREAM_HEADER_SIZE]; - memcpy(header, XZ_SIG, XZ_SIG_SIZE); - header[XZ_SIG_SIZE] = (Byte)(f >> 8); - header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); - crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); - SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc); - return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); -} - - -static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s) -{ - Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; - - unsigned pos = 1; - unsigned numFilters, i; - header[pos++] = p->flags; - - if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); - if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); - numFilters = XzBlock_GetNumFilters(p); - - for (i = 0; i < numFilters; i++) - { - const CXzFilter *f = &p->filters[i]; - pos += Xz_WriteVarInt(header + pos, f->id); - pos += Xz_WriteVarInt(header + pos, f->propsSize); - memcpy(header + pos, f->props, f->propsSize); - pos += f->propsSize; - } - - while ((pos & 3) != 0) - header[pos++] = 0; - - header[0] = (Byte)(pos >> 2); - SetUi32(header + pos, CrcCalc(header, pos)); - return WriteBytes(s, header, pos + 4); -} - - -static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s) -{ - Byte buf[32]; - UInt64 globalPos; - { - UInt32 crc = CRC_INIT_VAL; - unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); - size_t i; - - globalPos = pos; - buf[0] = 0; - RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); - - for (i = 0; i < p->numBlocks; i++) - { - const CXzBlockSizes *block = &p->blocks[i]; - pos = Xz_WriteVarInt(buf, block->totalSize); - pos += Xz_WriteVarInt(buf + pos, block->unpackSize); - globalPos += pos; - RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); - } - - pos = ((unsigned)globalPos & 3); - - if (pos != 0) - { - buf[0] = buf[1] = buf[2] = 0; - RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc)); - globalPos += 4 - pos; - } - { - SetUi32(buf, CRC_GET_DIGEST(crc)); - RINOK(WriteBytes(s, buf, 4)); - globalPos += 4; - } - } - - { - UInt32 indexSize = (UInt32)((globalPos >> 2) - 1); - SetUi32(buf + 4, indexSize); - buf[8] = (Byte)(p->flags >> 8); - buf[9] = (Byte)(p->flags & 0xFF); - SetUi32(buf, CrcCalc(buf + 4, 6)); - memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE); - return WriteBytes(s, buf, 12); - } -} - - -static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc) -{ - if (!p->blocks || p->numBlocksAllocated == p->numBlocks) - { - size_t num = p->numBlocks * 2 + 1; - size_t newSize = sizeof(CXzBlockSizes) * num; - CXzBlockSizes *blocks; - if (newSize / sizeof(CXzBlockSizes) != num) - return SZ_ERROR_MEM; - blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize); - if (!blocks) - return SZ_ERROR_MEM; - if (p->numBlocks != 0) - { - memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes)); - alloc->Free(alloc, p->blocks); - } - p->blocks = blocks; - p->numBlocksAllocated = num; - } - { - CXzBlockSizes *block = &p->blocks[p->numBlocks++]; - block->unpackSize = unpackSize; - block->totalSize = totalSize; - } - return SZ_OK; -} - - -/* ---------- CSeqCheckInStream ---------- */ - -typedef struct -{ - ISeqInStream p; - ISeqInStream *realStream; - UInt64 processed; - CXzCheck check; -} CSeqCheckInStream; - -static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned mode) -{ - p->processed = 0; - XzCheck_Init(&p->check, mode); -} - -static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest) -{ - XzCheck_Final(&p->check, digest); -} - -static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size) -{ - CSeqCheckInStream *p = (CSeqCheckInStream *)pp; - SRes res = p->realStream->Read(p->realStream, data, size); - XzCheck_Update(&p->check, data, *size); - p->processed += *size; - return res; -} - - -/* ---------- CSeqSizeOutStream ---------- */ - -typedef struct -{ - ISeqOutStream p; - ISeqOutStream *realStream; - UInt64 processed; -} CSeqSizeOutStream; - -static size_t MyWrite(void *pp, const void *data, size_t size) -{ - CSeqSizeOutStream *p = (CSeqSizeOutStream *)pp; - size = p->realStream->Write(p->realStream, data, size); - p->processed += size; - return size; -} - - -/* ---------- CSeqInFilter ---------- */ - -#define FILTER_BUF_SIZE (1 << 20) - -typedef struct -{ - ISeqInStream p; - ISeqInStream *realStream; - IStateCoder StateCoder; - Byte *buf; - size_t curPos; - size_t endPos; - int srcWasFinished; -} CSeqInFilter; - -static SRes SeqInFilter_Read(void *pp, void *data, size_t *size) -{ - CSeqInFilter *p = (CSeqInFilter *)pp; - size_t sizeOriginal = *size; - if (sizeOriginal == 0) - return SZ_OK; - *size = 0; - - for (;;) - { - if (!p->srcWasFinished && p->curPos == p->endPos) - { - p->curPos = 0; - p->endPos = FILTER_BUF_SIZE; - RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos)); - if (p->endPos == 0) - p->srcWasFinished = 1; - } - { - SizeT srcLen = p->endPos - p->curPos; - int wasFinished; - SRes res; - *size = sizeOriginal; - res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen, - p->srcWasFinished, CODER_FINISH_ANY, &wasFinished); - p->curPos += srcLen; - if (*size != 0 || srcLen == 0 || res != 0) - return res; - } - } -} - -static void SeqInFilter_Construct(CSeqInFilter *p) -{ - p->buf = NULL; - p->p.Read = SeqInFilter_Read; -} - -static void SeqInFilter_Free(CSeqInFilter *p) -{ - if (p->buf) - { - g_Alloc.Free(&g_Alloc, p->buf); - p->buf = NULL; - } -} - -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc); - -static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props) -{ - if (!p->buf) - { - p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE); - if (!p->buf) - return SZ_ERROR_MEM; - } - p->curPos = p->endPos = 0; - p->srcWasFinished = 0; - RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc)); - RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc)); - p->StateCoder.Init(p->StateCoder.p); - return SZ_OK; -} - - -/* ---------- CSbEncInStream ---------- */ - -#ifdef USE_SUBBLOCK - -typedef struct -{ - ISeqInStream p; - ISeqInStream *inStream; - CSbEnc enc; -} CSbEncInStream; - -static SRes SbEncInStream_Read(void *pp, void *data, size_t *size) -{ - CSbEncInStream *p = (CSbEncInStream *)pp; - size_t sizeOriginal = *size; - if (sizeOriginal == 0) - return S_OK; - - for (;;) - { - if (p->enc.needRead && !p->enc.readWasFinished) - { - size_t processed = p->enc.needReadSizeMax; - RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)); - p->enc.readPos += processed; - if (processed == 0) - { - p->enc.readWasFinished = True; - p->enc.isFinalFinished = True; - } - p->enc.needRead = False; - } - - *size = sizeOriginal; - RINOK(SbEnc_Read(&p->enc, data, size)); - if (*size != 0 || !p->enc.needRead) - return S_OK; - } -} - -void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc) -{ - SbEnc_Construct(&p->enc, alloc); - p->p.Read = SbEncInStream_Read; -} - -SRes SbEncInStream_Init(CSbEncInStream *p) -{ - return SbEnc_Init(&p->enc); -} - -void SbEncInStream_Free(CSbEncInStream *p) -{ - SbEnc_Free(&p->enc); -} - -#endif - - -typedef struct -{ - CLzma2EncHandle lzma2; - #ifdef USE_SUBBLOCK - CSbEncInStream sb; - #endif - CSeqInFilter filter; - ISzAlloc *alloc; - ISzAlloc *bigAlloc; -} CLzma2WithFilters; - - -static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, ISzAlloc *bigAlloc) -{ - p->alloc = alloc; - p->bigAlloc = bigAlloc; - p->lzma2 = NULL; - #ifdef USE_SUBBLOCK - SbEncInStream_Construct(&p->sb, alloc); - #endif - SeqInFilter_Construct(&p->filter); -} - -static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p) -{ - p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc); - if (!p->lzma2) - return SZ_ERROR_MEM; - return SZ_OK; -} - -static void Lzma2WithFilters_Free(CLzma2WithFilters *p) -{ - SeqInFilter_Free(&p->filter); - #ifdef USE_SUBBLOCK - SbEncInStream_Free(&p->sb); - #endif - if (p->lzma2) - { - Lzma2Enc_Destroy(p->lzma2); - p->lzma2 = NULL; - } -} - - -void XzProps_Init(CXzProps *p) -{ - p->lzma2Props = NULL; - p->filterProps = NULL; - p->checkId = XZ_CHECK_CRC32; -} - -void XzFilterProps_Init(CXzFilterProps *p) -{ - p->id = 0; - p->delta = 0; - p->ip = 0; - p->ipDefined = False; -} - - -static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, - ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress) -{ - xz->flags = (Byte)props->checkId; - - RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props)); - RINOK(Xz_WriteHeader(xz->flags, outStream)); - - { - CSeqCheckInStream checkInStream; - CSeqSizeOutStream seqSizeOutStream; - CXzBlock block; - unsigned filterIndex = 0; - CXzFilter *filter = NULL; - const CXzFilterProps *fp = props->filterProps; - - XzBlock_ClearFlags(&block); - XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); - - if (fp) - { - filter = &block.filters[filterIndex++]; - filter->id = fp->id; - filter->propsSize = 0; - - if (fp->id == XZ_ID_Delta) - { - filter->props[0] = (Byte)(fp->delta - 1); - filter->propsSize = 1; - } - else if (fp->ipDefined) - { - SetUi32(filter->props, fp->ip); - filter->propsSize = 4; - } - } - - { - CXzFilter *f = &block.filters[filterIndex++]; - f->id = XZ_ID_LZMA2; - f->propsSize = 1; - f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); - } - - seqSizeOutStream.p.Write = MyWrite; - seqSizeOutStream.realStream = outStream; - seqSizeOutStream.processed = 0; - - RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); - - checkInStream.p.Read = SeqCheckInStream_Read; - checkInStream.realStream = inStream; - SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); - - if (fp) - { - #ifdef USE_SUBBLOCK - if (fp->id == XZ_ID_Subblock) - { - lzmaf->sb.inStream = &checkInStream.p; - RINOK(SbEncInStream_Init(&lzmaf->sb)); - } - else - #endif - { - lzmaf->filter.realStream = &checkInStream.p; - RINOK(SeqInFilter_Init(&lzmaf->filter, filter)); - } - } - - { - UInt64 packPos = seqSizeOutStream.processed; - - SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, - fp ? - #ifdef USE_SUBBLOCK - (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p: - #endif - &lzmaf->filter.p: - &checkInStream.p, - progress); - - RINOK(res); - block.unpackSize = checkInStream.processed; - block.packSize = seqSizeOutStream.processed - packPos; - } - - { - unsigned padSize = 0; - Byte buf[128]; - while ((((unsigned)block.packSize + padSize) & 3) != 0) - buf[padSize++] = 0; - SeqCheckInStream_GetDigest(&checkInStream, buf + padSize); - RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags))); - RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc)); - } - } - return Xz_WriteFooter(xz, outStream); -} - - -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress) -{ - SRes res; - CXzStream xz; - CLzma2WithFilters lzmaf; - Xz_Construct(&xz); - Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc); - res = Lzma2WithFilters_Create(&lzmaf); - if (res == SZ_OK) - res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress); - Lzma2WithFilters_Free(&lzmaf); - Xz_Free(&xz, &g_Alloc); - return res; -} - - -SRes Xz_EncodeEmpty(ISeqOutStream *outStream) -{ - SRes res; - CXzStream xz; - Xz_Construct(&xz); - res = Xz_WriteHeader(xz.flags, outStream); - if (res == SZ_OK) - res = Xz_WriteFooter(&xz, outStream); - Xz_Free(&xz, &g_Alloc); - return res; -} +/* XzEnc.c -- Xz Encode +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +#include + +#include "7zCrc.h" +#include "Bra.h" +#include "CpuArch.h" + +#ifdef USE_SUBBLOCK +#include "Bcj3Enc.c" +#include "SbFind.c" +#include "SbEnc.c" +#endif + +#include "XzEnc.h" + +// #define Z7_ST + +#ifndef Z7_ST +#include "MtCoder.h" +#else +#define MTCODER_THREADS_MAX 1 +#define MTCODER_BLOCKS_MAX 1 +#endif + +#define XZ_GET_PAD_SIZE(dataSize) ((4 - ((unsigned)(dataSize) & 3)) & 3) + +#define XZ_CHECK_SIZE_MAX 64 +/* max pack size for LZMA2 block + pad4 + check_size: */ +#define XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize) ((unpackSize) + ((unpackSize) >> 10) + 16 + XZ_CHECK_SIZE_MAX) + +#define XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(unpackSize) (XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize)) + + +// #define XzBlock_ClearFlags(p) (p)->flags = 0; +#define XzBlock_ClearFlags_SetNumFilters(p, n) (p)->flags = (Byte)((n) - 1); +#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; +#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; + + +static SRes WriteBytes(ISeqOutStreamPtr s, const void *buf, size_t size) +{ + return (ISeqOutStream_Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; +} + +static SRes WriteBytes_UpdateCrc(ISeqOutStreamPtr s, const void *buf, size_t size, UInt32 *crc) +{ + *crc = CrcUpdate(*crc, buf, size); + return WriteBytes(s, buf, size); +} + + +static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStreamPtr s) +{ + UInt32 crc; + Byte header[XZ_STREAM_HEADER_SIZE]; + memcpy(header, XZ_SIG, XZ_SIG_SIZE); + header[XZ_SIG_SIZE] = (Byte)(f >> 8); + header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); + crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); + SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc) + return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); +} + + +static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStreamPtr s) +{ + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + + unsigned pos = 1; + unsigned numFilters, i; + header[pos++] = p->flags; + + if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); + if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); + numFilters = XzBlock_GetNumFilters(p); + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + pos += Xz_WriteVarInt(header + pos, f->id); + pos += Xz_WriteVarInt(header + pos, f->propsSize); + memcpy(header + pos, f->props, f->propsSize); + pos += f->propsSize; + } + + while ((pos & 3) != 0) + header[pos++] = 0; + + header[0] = (Byte)(pos >> 2); + SetUi32(header + pos, CrcCalc(header, pos)) + return WriteBytes(s, header, pos + 4); +} + + + + +typedef struct +{ + size_t numBlocks; + size_t size; + size_t allocated; + Byte *blocks; +} CXzEncIndex; + + +static void XzEncIndex_Construct(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; + p->blocks = NULL; +} + +static void XzEncIndex_Init(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; +} + +static void XzEncIndex_Free(CXzEncIndex *p, ISzAllocPtr alloc) +{ + if (p->blocks) + { + ISzAlloc_Free(alloc, p->blocks); + p->blocks = NULL; + } + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; +} + + +static SRes XzEncIndex_ReAlloc(CXzEncIndex *p, size_t newSize, ISzAllocPtr alloc) +{ + Byte *blocks = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!blocks) + return SZ_ERROR_MEM; + if (p->size != 0) + memcpy(blocks, p->blocks, p->size); + if (p->blocks) + ISzAlloc_Free(alloc, p->blocks); + p->blocks = blocks; + p->allocated = newSize; + return SZ_OK; +} + + +static SRes XzEncIndex_PreAlloc(CXzEncIndex *p, UInt64 numBlocks, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + UInt64 pos; + { + Byte buf[32]; + unsigned pos2 = Xz_WriteVarInt(buf, totalSize); + pos2 += Xz_WriteVarInt(buf + pos2, unpackSize); + pos = numBlocks * pos2; + } + + if (pos <= p->allocated - p->size) + return SZ_OK; + { + UInt64 newSize64 = p->size + pos; + size_t newSize = (size_t)newSize64; + if (newSize != newSize64) + return SZ_ERROR_MEM; + return XzEncIndex_ReAlloc(p, newSize, alloc); + } +} + + +static SRes XzEncIndex_AddIndexRecord(CXzEncIndex *p, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + Byte buf[32]; + unsigned pos = Xz_WriteVarInt(buf, totalSize); + pos += Xz_WriteVarInt(buf + pos, unpackSize); + + if (pos > p->allocated - p->size) + { + size_t newSize = p->allocated * 2 + 16 * 2; + if (newSize < p->size + pos) + return SZ_ERROR_MEM; + RINOK(XzEncIndex_ReAlloc(p, newSize, alloc)) + } + memcpy(p->blocks + p->size, buf, pos); + p->size += pos; + p->numBlocks++; + return SZ_OK; +} + + +static SRes XzEncIndex_WriteFooter(const CXzEncIndex *p, CXzStreamFlags flags, ISeqOutStreamPtr s) +{ + Byte buf[32]; + UInt64 globalPos; + UInt32 crc = CRC_INIT_VAL; + unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); + + globalPos = pos; + buf[0] = 0; + RINOK(WriteBytes_UpdateCrc(s, buf, pos, &crc)) + RINOK(WriteBytes_UpdateCrc(s, p->blocks, p->size, &crc)) + globalPos += p->size; + + pos = XZ_GET_PAD_SIZE(globalPos); + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + globalPos += pos; + + crc = CrcUpdate(crc, buf + 4 - pos, pos); + SetUi32(buf + 4, CRC_GET_DIGEST(crc)) + + SetUi32(buf + 8 + 4, (UInt32)(globalPos >> 2)) + buf[8 + 8] = (Byte)(flags >> 8); + buf[8 + 9] = (Byte)(flags & 0xFF); + SetUi32(buf + 8, CrcCalc(buf + 8 + 4, 6)) + buf[8 + 10] = XZ_FOOTER_SIG_0; + buf[8 + 11] = XZ_FOOTER_SIG_1; + + return WriteBytes(s, buf + 4 - pos, pos + 4 + 12); +} + + + +/* ---------- CSeqCheckInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + const Byte *data; + UInt64 limit; + UInt64 processed; + int realStreamFinished; + CXzCheck check; +} CSeqCheckInStream; + +static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned checkMode) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->realStreamFinished = 0; + XzCheck_Init(&p->check, checkMode); +} + +static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest) +{ + XzCheck_Final(&p->check, digest); +} + +static SRes SeqCheckInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqCheckInStream) + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + if (p->realStream) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->realStreamFinished = (size2 == 0) ? 1 : 0; + } + else + memcpy(data, p->data + (size_t)p->processed, size2); + XzCheck_Update(&p->check, data, size2); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CSeqSizeOutStream ---------- */ + +typedef struct +{ + ISeqOutStream vt; + ISeqOutStreamPtr realStream; + Byte *outBuf; + size_t outBufLimit; + UInt64 processed; +} CSeqSizeOutStream; + +static size_t SeqSizeOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqSizeOutStream) + if (p->realStream) + size = ISeqOutStream_Write(p->realStream, data, size); + else + { + if (size > p->outBufLimit - (size_t)p->processed) + return 0; + memcpy(p->outBuf + (size_t)p->processed, data, size); + } + p->processed += size; + return size; +} + + +/* ---------- CSeqInFilter ---------- */ + +#define FILTER_BUF_SIZE (1 << 20) + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + IStateCoder StateCoder; + Byte *buf; + size_t curPos; + size_t endPos; + int srcWasFinished; +} CSeqInFilter; + + +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Enc[] = +{ + Z7_BRANCH_CONV_ENC_2 (BranchConv_PPC), + Z7_BRANCH_CONV_ENC_2 (BranchConv_IA64), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARM), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARMT), + Z7_BRANCH_CONV_ENC_2 (BranchConv_SPARC), + Z7_BRANCH_CONV_ENC_2 (BranchConv_ARM64), + Z7_BRANCH_CONV_ENC_2 (BranchConv_RISCV) +}; + +static SizeT XzBcFilterStateBase_Filter_Enc(CXzBcFilterStateBase *p, Byte *data, SizeT size) +{ + switch (p->methodId) + { + case XZ_ID_Delta: + Delta_Encode(p->delta_State, p->delta, data, size); + break; + case XZ_ID_X86: + size = (SizeT)(z7_BranchConvSt_X86_Enc(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Enc)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Enc[i](data, size, p->ip) - data); + } + break; + } + p->ip += (UInt32)size; + return size; +} + + +static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props, ISzAllocPtr alloc) +{ + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(alloc, FILTER_BUF_SIZE); + if (!p->buf) + return SZ_ERROR_MEM; + } + p->curPos = p->endPos = 0; + p->srcWasFinished = 0; + RINOK(Xz_StateCoder_Bc_SetFromMethod_Func(&p->StateCoder, props->id, XzBcFilterStateBase_Filter_Enc, alloc)) + RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, alloc)) + p->StateCoder.Init(p->StateCoder.p); + return SZ_OK; +} + + +static SRes SeqInFilter_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInFilter) + const size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + *size = 0; + + for (;;) + { + if (!p->srcWasFinished && p->curPos == p->endPos) + { + p->curPos = 0; + p->endPos = FILTER_BUF_SIZE; + RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos)) + if (p->endPos == 0) + p->srcWasFinished = 1; + } + { + SizeT srcLen = p->endPos - p->curPos; + ECoderStatus status; + SRes res; + *size = sizeOriginal; + res = p->StateCoder.Code2(p->StateCoder.p, + (Byte *)data, size, + p->buf + p->curPos, &srcLen, + p->srcWasFinished, CODER_FINISH_ANY, + &status); + p->curPos += srcLen; + if (*size != 0 || srcLen == 0 || res != SZ_OK) + return res; + } + } +} + +Z7_FORCE_INLINE +static void SeqInFilter_Construct(CSeqInFilter *p) +{ + p->buf = NULL; + p->StateCoder.p = NULL; + p->vt.Read = SeqInFilter_Read; +} + +Z7_FORCE_INLINE +static void SeqInFilter_Free(CSeqInFilter *p, ISzAllocPtr alloc) +{ + if (p->StateCoder.p) + { + p->StateCoder.Free(p->StateCoder.p, alloc); + p->StateCoder.p = NULL; + } + if (p->buf) + { + ISzAlloc_Free(alloc, p->buf); + p->buf = NULL; + } +} + + +/* ---------- CSbEncInStream ---------- */ + +#ifdef USE_SUBBLOCK + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr inStream; + CSbEnc enc; +} CSbEncInStream; + +static SRes SbEncInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + CSbEncInStream *p = Z7_CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt); + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + + for (;;) + { + if (p->enc.needRead && !p->enc.readWasFinished) + { + size_t processed = p->enc.needReadSizeMax; + RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)) + p->enc.readPos += processed; + if (processed == 0) + { + p->enc.readWasFinished = True; + p->enc.isFinalFinished = True; + } + p->enc.needRead = False; + } + + *size = sizeOriginal; + RINOK(SbEnc_Read(&p->enc, data, size)) + if (*size != 0 || !p->enc.needRead) + return SZ_OK; + } +} + +void SbEncInStream_Construct(CSbEncInStream *p, ISzAllocPtr alloc) +{ + SbEnc_Construct(&p->enc, alloc); + p->vt.Read = SbEncInStream_Read; +} + +SRes SbEncInStream_Init(CSbEncInStream *p) +{ + return SbEnc_Init(&p->enc); +} + +void SbEncInStream_Free(CSbEncInStream *p) +{ + SbEnc_Free(&p->enc); +} + +#endif + + + +/* ---------- CXzProps ---------- */ + + +void XzFilterProps_Init(CXzFilterProps *p) +{ + p->id = 0; + p->delta = 0; + p->ip = 0; + p->ipDefined = False; +} + +void XzProps_Init(CXzProps *p) +{ + p->checkId = XZ_CHECK_CRC32; + p->numThreadGroups = 0; + p->blockSize = XZ_PROPS_BLOCK_SIZE_AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; + p->reduceSize = (UInt64)(Int64)-1; + p->forceWriteSizesInHeader = 0; + // p->forceWriteSizesInHeader = 1; + + XzFilterProps_Init(&p->filterProps); + Lzma2EncProps_Init(&p->lzma2Props); +} + + +static void XzEncProps_Normalize_Fixed(CXzProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + Lzma2EncProps_Normalize(&tp); + t1n = tp.numTotalThreads; + } + + t1 = p->lzma2Props.numTotalThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzma2Props.numTotalThreads = t1; + + t2r = t2; + + fileSize = p->reduceSize; + + if ((p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzma2Props.lzmaProps.reduceSize = p->blockSize; + + Lzma2EncProps_Normalize(&p->lzma2Props); + + t1 = p->lzma2Props.numTotalThreads; + + { + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (int)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static void XzProps_Normalize(CXzProps *p) +{ + /* we normalize xzProps properties, but we normalize only some of CXzProps::lzma2Props properties. + Lzma2Enc_SetProps() will normalize lzma2Props later. */ + + if (p->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID) + { + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + return; + } + else + { + CLzma2EncProps *lzma2 = &p->lzma2Props; + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + { + // xz-auto + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + { + // if (xz-auto && lzma2-solid) - we use solid for both + p->blockSize = XZ_PROPS_BLOCK_SIZE_SOLID; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + } + else + { + // if (xz-auto && (lzma2-auto || lzma2-fixed_) + // we calculate block size for lzma2 and use that block size for xz, lzma2 uses single-chunk per block + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + + Lzma2EncProps_Normalize(&tp); + + p->blockSize = tp.blockSize; // fixed or solid + p->numBlockThreads_Reduced = tp.numBlockThreads_Reduced; + p->numBlockThreads_Max = tp.numBlockThreads_Max; + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = tp.blockSize; // fixed or solid, LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + if (lzma2->lzmaProps.reduceSize > tp.blockSize && tp.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + lzma2->lzmaProps.reduceSize = tp.blockSize; + lzma2->numBlockThreads_Reduced = 1; + lzma2->numBlockThreads_Max = 1; + return; + } + } + else + { + // xz-fixed + // we can use xz::reduceSize or xz::blockSize as base for lzmaProps::reduceSize + + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + { + UInt64 r = p->reduceSize; + if (r > p->blockSize || r == (UInt64)(Int64)-1) + r = p->blockSize; + lzma2->lzmaProps.reduceSize = r; + } + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + else if (lzma2->blockSize > p->blockSize && lzma2->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + lzma2->blockSize = p->blockSize; + + XzEncProps_Normalize_Fixed(p); + } + } +} + + +/* ---------- CLzma2WithFilters ---------- */ + +typedef struct +{ + CLzma2EncHandle lzma2; + CSeqInFilter filter; + + #ifdef USE_SUBBLOCK + CSbEncInStream sb; + #endif +} CLzma2WithFilters; + + +Z7_FORCE_INLINE +static void Lzma2WithFilters_Construct(CLzma2WithFilters *p) +{ + p->lzma2 = NULL; + SeqInFilter_Construct(&p->filter); + + #ifdef USE_SUBBLOCK + SbEncInStream_Construct(&p->sb, alloc); + #endif +} + + +static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p, ISzAllocPtr alloc, ISzAllocPtr bigAlloc) +{ + if (!p->lzma2) + { + p->lzma2 = Lzma2Enc_Create(alloc, bigAlloc); + if (!p->lzma2) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + + +Z7_FORCE_INLINE +static void Lzma2WithFilters_Free(CLzma2WithFilters *p, ISzAllocPtr alloc) +{ + #ifdef USE_SUBBLOCK + SbEncInStream_Free(&p->sb); + #endif + + SeqInFilter_Free(&p->filter, alloc); + if (p->lzma2) + { + Lzma2Enc_Destroy(p->lzma2); + p->lzma2 = NULL; + } +} + + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; + size_t headerSize; +} CXzEncBlockInfo; + + +static SRes Xz_CompressBlock( + CLzma2WithFilters *lzmaf, + + ISeqOutStreamPtr outStream, + Byte *outBufHeader, + Byte *outBufData, size_t outBufDataLimit, + + ISeqInStreamPtr inStream, + // UInt64 expectedSize, + const Byte *inBuf, // used if (!inStream) + size_t inBufSize, // used if (!inStream), it's block size, props->blockSize is ignored + + const CXzProps *props, + ICompressProgressPtr progress, + int *inStreamFinished, /* only for inStream version */ + CXzEncBlockInfo *blockSizes, + ISzAllocPtr alloc, + ISzAllocPtr allocBig) +{ + CSeqCheckInStream checkInStream; + CSeqSizeOutStream seqSizeOutStream; + CXzBlock block; + unsigned filterIndex = 0; + CXzFilter *filter = NULL; + const CXzFilterProps *fp = &props->filterProps; + if (fp->id == 0) + fp = NULL; + + *inStreamFinished = False; + + RINOK(Lzma2WithFilters_Create(lzmaf, alloc, allocBig)) + + RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, &props->lzma2Props)) + + // XzBlock_ClearFlags(&block) + XzBlock_ClearFlags_SetNumFilters(&block, 1 + (fp ? 1 : 0)) + + if (fp) + { + filter = &block.filters[filterIndex++]; + filter->id = fp->id; + filter->propsSize = 0; + + if (fp->id == XZ_ID_Delta) + { + filter->props[0] = (Byte)(fp->delta - 1); + filter->propsSize = 1; + } + else if (fp->ipDefined) + { + Byte *ptr = filter->props; + SetUi32(ptr, fp->ip) + filter->propsSize = 4; + } + } + + { + CXzFilter *f = &block.filters[filterIndex++]; + f->id = XZ_ID_LZMA2; + f->propsSize = 1; + f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); + } + + seqSizeOutStream.vt.Write = SeqSizeOutStream_Write; + seqSizeOutStream.realStream = outStream; + seqSizeOutStream.outBuf = outBufData; + seqSizeOutStream.outBufLimit = outBufDataLimit; + seqSizeOutStream.processed = 0; + + /* + if (expectedSize != (UInt64)(Int64)-1) + { + block.unpackSize = expectedSize; + if (props->blockSize != (UInt64)(Int64)-1) + if (expectedSize > props->blockSize) + block.unpackSize = props->blockSize; + XzBlock_SetHasUnpackSize(&block) + } + */ + + if (outStream) + { + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) + } + + checkInStream.vt.Read = SeqCheckInStream_Read; + SeqCheckInStream_Init(&checkInStream, props->checkId); + + checkInStream.realStream = inStream; + checkInStream.data = inBuf; + checkInStream.limit = props->blockSize; + if (!inStream) + checkInStream.limit = inBufSize; + + if (fp) + { + #ifdef USE_SUBBLOCK + if (fp->id == XZ_ID_Subblock) + { + lzmaf->sb.inStream = &checkInStream.vt; + RINOK(SbEncInStream_Init(&lzmaf->sb)) + } + else + #endif + { + lzmaf->filter.realStream = &checkInStream.vt; + RINOK(SeqInFilter_Init(&lzmaf->filter, filter, alloc)) + } + } + + { + SRes res; + Byte *outBuf = NULL; + size_t outSize = 0; + BoolInt useStream = (fp || inStream); + // useStream = True; + + if (!useStream) + { + XzCheck_Update(&checkInStream.check, inBuf, inBufSize); + checkInStream.processed = inBufSize; + } + + if (!outStream) + { + outBuf = seqSizeOutStream.outBuf; // + (size_t)seqSizeOutStream.processed; + outSize = seqSizeOutStream.outBufLimit; // - (size_t)seqSizeOutStream.processed; + } + + res = Lzma2Enc_Encode2(lzmaf->lzma2, + outBuf ? NULL : &seqSizeOutStream.vt, + outBuf, + outBuf ? &outSize : NULL, + + useStream ? + (fp ? + ( + #ifdef USE_SUBBLOCK + (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.vt: + #endif + &lzmaf->filter.vt) : + &checkInStream.vt) : NULL, + + useStream ? NULL : inBuf, + useStream ? 0 : inBufSize, + + progress); + + if (outBuf) + seqSizeOutStream.processed += outSize; + + RINOK(res) + blockSizes->unpackSize = checkInStream.processed; + } + { + Byte buf[4 + XZ_CHECK_SIZE_MAX]; + const unsigned padSize = XZ_GET_PAD_SIZE(seqSizeOutStream.processed); + const UInt64 packSize = seqSizeOutStream.processed; + + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + + SeqCheckInStream_GetDigest(&checkInStream, buf + 4); + RINOK(WriteBytes(&seqSizeOutStream.vt, buf + (4 - padSize), + padSize + XzFlags_GetCheckSize((CXzStreamFlags)props->checkId))) + + blockSizes->totalSize = seqSizeOutStream.processed - padSize; + + if (!outStream) + { + seqSizeOutStream.outBuf = outBufHeader; + seqSizeOutStream.outBufLimit = XZ_BLOCK_HEADER_SIZE_MAX; + seqSizeOutStream.processed = 0; + + block.unpackSize = blockSizes->unpackSize; + XzBlock_SetHasUnpackSize(&block) + + block.packSize = packSize; + XzBlock_SetHasPackSize(&block) + + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) + + blockSizes->headerSize = (size_t)seqSizeOutStream.processed; + blockSizes->totalSize += seqSizeOutStream.processed; + } + } + + if (inStream) + *inStreamFinished = checkInStream.realStreamFinished; + else + { + *inStreamFinished = False; + if (checkInStream.processed != inBufSize) + return SZ_ERROR_FAIL; + } + + return SZ_OK; +} + + + +typedef struct +{ + ICompressProgress vt; + ICompressProgressPtr progress; + UInt64 inOffset; + UInt64 outOffset; +} CCompressProgress_XzEncOffset; + + +static SRes CompressProgress_XzEncOffset_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) +{ + const CCompressProgress_XzEncOffset *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CCompressProgress_XzEncOffset, vt); + inSize += p->inOffset; + outSize += p->outOffset; + return ICompressProgress_Progress(p->progress, inSize, outSize); +} + + + + +struct CXzEnc +{ + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CXzProps xzProps; + UInt64 expectedDataSize; + + CXzEncIndex xzIndex; + + CLzma2WithFilters lzmaf_Items[MTCODER_THREADS_MAX]; + + size_t outBufSize; /* size of allocated outBufs[i] */ + Byte *outBufs[MTCODER_BLOCKS_MAX]; + + #ifndef Z7_ST + unsigned checkType; + ISeqOutStreamPtr outStream; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + CXzEncBlockInfo EncBlocks[MTCODER_BLOCKS_MAX]; + #endif +}; + + +static void XzEnc_Construct(CXzEnc *p) +{ + unsigned i; + + XzEncIndex_Construct(&p->xzIndex); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + Lzma2WithFilters_Construct(&p->lzmaf_Items[i]); + + #ifndef Z7_ST + p->mtCoder_WasConstructed = False; + { + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif +} + + +static void XzEnc_FreeOutBufs(CXzEnc *p) +{ + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + + +static void XzEnc_Free(CXzEnc *p, ISzAllocPtr alloc) +{ + unsigned i; + + XzEncIndex_Free(&p->xzIndex, alloc); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + Lzma2WithFilters_Free(&p->lzmaf_Items[i], alloc); + + #ifndef Z7_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + XzEnc_FreeOutBufs(p); + #endif +} + + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CXzEnc *p = (CXzEnc *)ISzAlloc_Alloc(alloc, sizeof(CXzEnc)); + if (!p) + return NULL; + XzEnc_Construct(p); + XzProps_Init(&p->xzProps); + XzProps_Normalize(&p->xzProps); + p->expectedDataSize = (UInt64)(Int64)-1; + p->alloc = alloc; + p->allocBig = allocBig; + return (CXzEncHandle)p; +} + +// #define GET_CXzEnc_p CXzEnc *p = (CXzEnc *)(void *)pp; + +void XzEnc_Destroy(CXzEncHandle p) +{ + // GET_CXzEnc_p + XzEnc_Free(p, p->alloc); + ISzAlloc_Free(p->alloc, p); +} + + +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props) +{ + // GET_CXzEnc_p + p->xzProps = *props; + XzProps_Normalize(&p->xzProps); + return SZ_OK; +} + + +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize) +{ + // GET_CXzEnc_p + p->expectedDataSize = expectedDataSiize; +} + + + + +#ifndef Z7_ST + +static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CXzEnc *me = (CXzEnc *)pp; + SRes res; + CMtProgressThunk progressThunk; + Byte *dest; + UNUSED_VAR(finished) + { + CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + bInfo->totalSize = 0; + bInfo->unpackSize = 0; + bInfo->headerSize = 0; + // v23.02: we don't compress empty blocks + // also we must ignore that empty block in XzEnc_MtCallback_Write() + if (srcSize == 0) + return SZ_OK; + } + dest = me->outBufs[outBufIndex]; + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + MtProgressThunk_INIT(&progressThunk) + + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + res = Xz_CompressBlock( + &me->lzmaf_Items[coderIndex], + + NULL, + dest, + dest + XZ_BLOCK_HEADER_SIZE_MAX, me->outBufSize - XZ_BLOCK_HEADER_SIZE_MAX, + + NULL, + // srcSize, // expectedSize + src, srcSize, + + &me->xzProps, + &progressThunk.vt, + &inStreamFinished, + &blockSizes, + me->alloc, + me->allocBig); + + if (res == SZ_OK) + me->EncBlocks[outBufIndex] = blockSizes; + + return res; + } +} + + +static SRes XzEnc_MtCallback_Write(void *pp, unsigned outBufIndex) +{ + CXzEnc *me = (CXzEnc *)pp; + const CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + // v23.02: we don't write empty blocks + // note: if (bInfo->unpackSize == 0) then there is no compressed data of block + if (bInfo->unpackSize == 0) + return SZ_OK; + { + const Byte *data = me->outBufs[outBufIndex]; + RINOK(WriteBytes(me->outStream, data, bInfo->headerSize)) + { + const UInt64 totalPackFull = bInfo->totalSize + XZ_GET_PAD_SIZE(bInfo->totalSize); + RINOK(WriteBytes(me->outStream, data + XZ_BLOCK_HEADER_SIZE_MAX, (size_t)totalPackFull - bInfo->headerSize)) + } + return XzEncIndex_AddIndexRecord(&me->xzIndex, bInfo->unpackSize, bInfo->totalSize, me->alloc); + } +} + +#endif + + + +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress) +{ + // GET_CXzEnc_p + + const CXzProps *props = &p->xzProps; + + XzEncIndex_Init(&p->xzIndex); + { + UInt64 numBlocks = 1; + UInt64 blockSize = props->blockSize; + + if (blockSize != XZ_PROPS_BLOCK_SIZE_SOLID + && props->reduceSize != (UInt64)(Int64)-1) + { + numBlocks = props->reduceSize / blockSize; + if (numBlocks * blockSize != props->reduceSize) + numBlocks++; + } + else + blockSize = (UInt64)1 << 62; + + RINOK(XzEncIndex_PreAlloc(&p->xzIndex, numBlocks, blockSize, XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(blockSize), p->alloc)) + } + + RINOK(Xz_WriteHeader((CXzStreamFlags)props->checkId, outStream)) + + + #ifndef Z7_ST + if (props->numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = XzEnc_MtCallback_Code; + vt.Write = XzEnc_MtCallback_Write; + + p->checkType = props->checkId; + p->xzProps = *props; + + p->outStream = outStream; + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = NULL; + p->mtCoder.inDataSize = 0; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + if ( props->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID + || props->blockSize == XZ_PROPS_BLOCK_SIZE_AUTO) + return SZ_ERROR_FAIL; + + p->mtCoder.blockSize = (size_t)props->blockSize; + if (p->mtCoder.blockSize != props->blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + size_t destBlockSize = XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(p->mtCoder.blockSize); + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + XzEnc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = (unsigned)props->numBlockThreads_Max; + p->mtCoder.numThreadGroups = props->numThreadGroups; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + RINOK(MtCoder_Code(&p->mtCoder)) + } + else + #endif + { + int writeStartSizes; + CCompressProgress_XzEncOffset progress2; + Byte *bufData = NULL; + size_t bufSize = 0; + + progress2.vt.Progress = CompressProgress_XzEncOffset_Progress; + progress2.inOffset = 0; + progress2.outOffset = 0; + progress2.progress = progress; + + writeStartSizes = 0; + + if (props->blockSize != XZ_PROPS_BLOCK_SIZE_SOLID) + { + writeStartSizes = (props->forceWriteSizesInHeader > 0); + + if (writeStartSizes) + { + size_t t2; + size_t t = (size_t)props->blockSize; + if (t != props->blockSize) + return SZ_ERROR_PARAM; + t = XZ_GET_MAX_BLOCK_PACK_SIZE(t); + if (t < props->blockSize) + return SZ_ERROR_PARAM; + t2 = XZ_BLOCK_HEADER_SIZE_MAX + t; + if (!p->outBufs[0] || t2 != p->outBufSize) + { + XzEnc_FreeOutBufs(p); + p->outBufs[0] = (Byte *)ISzAlloc_Alloc(p->alloc, t2); + if (!p->outBufs[0]) + return SZ_ERROR_MEM; + p->outBufSize = t2; + } + bufData = p->outBufs[0] + XZ_BLOCK_HEADER_SIZE_MAX; + bufSize = t; + } + } + + for (;;) + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + /* + UInt64 rem = (UInt64)(Int64)-1; + if (props->reduceSize != (UInt64)(Int64)-1 + && props->reduceSize >= progress2.inOffset) + rem = props->reduceSize - progress2.inOffset; + */ + + blockSizes.headerSize = 0; // for GCC + + RINOK(Xz_CompressBlock( + &p->lzmaf_Items[0], + + writeStartSizes ? NULL : outStream, + writeStartSizes ? p->outBufs[0] : NULL, + bufData, bufSize, + + inStream, + // rem, + NULL, 0, + + props, + progress ? &progress2.vt : NULL, + &inStreamFinished, + &blockSizes, + p->alloc, + p->allocBig)) + + { + UInt64 totalPackFull = blockSizes.totalSize + XZ_GET_PAD_SIZE(blockSizes.totalSize); + + if (writeStartSizes) + { + RINOK(WriteBytes(outStream, p->outBufs[0], blockSizes.headerSize)) + RINOK(WriteBytes(outStream, bufData, (size_t)totalPackFull - blockSizes.headerSize)) + } + + RINOK(XzEncIndex_AddIndexRecord(&p->xzIndex, blockSizes.unpackSize, blockSizes.totalSize, p->alloc)) + + progress2.inOffset += blockSizes.unpackSize; + progress2.outOffset += totalPackFull; + } + + if (inStreamFinished) + break; + } + } + + return XzEncIndex_WriteFooter(&p->xzIndex, (CXzStreamFlags)props->checkId, outStream); +} + + +#include "Alloc.h" + +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress) +{ + SRes res; + CXzEncHandle xz = XzEnc_Create(&g_Alloc, &g_BigAlloc); + if (!xz) + return SZ_ERROR_MEM; + res = XzEnc_SetProps(xz, props); + if (res == SZ_OK) + res = XzEnc_Encode(xz, outStream, inStream, progress); + XzEnc_Destroy(xz); + return res; +} + + +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream) +{ + SRes res; + CXzEncIndex xzIndex; + XzEncIndex_Construct(&xzIndex); + res = Xz_WriteHeader((CXzStreamFlags)0, outStream); + if (res == SZ_OK) + res = XzEncIndex_WriteFooter(&xzIndex, (CXzStreamFlags)0, outStream); + XzEncIndex_Free(&xzIndex, NULL); // g_Alloc + return res; +} diff -Nru p7zip-rar-16.02/C/XzEnc.h p7zip-rar-16.02+really25.00+ds/C/XzEnc.h --- p7zip-rar-16.02/C/XzEnc.h 2011-05-08 18:29:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzEnc.h 2025-07-02 12:00:00.000000000 +0000 @@ -1,39 +1,62 @@ -/* XzEnc.h -- Xz Encode -2011-02-07 : Igor Pavlov : Public domain */ - -#ifndef __XZ_ENC_H -#define __XZ_ENC_H - -#include "Lzma2Enc.h" - -#include "Xz.h" - -EXTERN_C_BEGIN - -typedef struct -{ - UInt32 id; - UInt32 delta; - UInt32 ip; - int ipDefined; -} CXzFilterProps; - -void XzFilterProps_Init(CXzFilterProps *p); - -typedef struct -{ - const CLzma2EncProps *lzma2Props; - const CXzFilterProps *filterProps; - unsigned checkId; -} CXzProps; - -void XzProps_Init(CXzProps *p); - -SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, - const CXzProps *props, ICompressProgress *progress); - -SRes Xz_EncodeEmpty(ISeqOutStream *outStream); - -EXTERN_C_END - -#endif +/* XzEnc.h -- Xz Encode +: Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_ENC_H +#define ZIP7_INC_XZ_ENC_H + +#include "Lzma2Enc.h" + +#include "Xz.h" + +EXTERN_C_BEGIN + + +#define XZ_PROPS_BLOCK_SIZE_AUTO LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO +#define XZ_PROPS_BLOCK_SIZE_SOLID LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + + +typedef struct +{ + UInt32 id; + UInt32 delta; + UInt32 ip; + int ipDefined; +} CXzFilterProps; + +void XzFilterProps_Init(CXzFilterProps *p); + + +typedef struct +{ + CLzma2EncProps lzma2Props; + CXzFilterProps filterProps; + unsigned checkId; + unsigned numThreadGroups; // 0 : no groups + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; + int forceWriteSizesInHeader; + UInt64 reduceSize; +} CXzProps; + +void XzProps_Init(CXzProps *p); + +typedef struct CXzEnc CXzEnc; +typedef CXzEnc * CXzEncHandle; +// Z7_DECLARE_HANDLE(CXzEncHandle) + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void XzEnc_Destroy(CXzEncHandle p); +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props); +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize); +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress); + +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress); + +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/XzIn.c p7zip-rar-16.02+really25.00+ds/C/XzIn.c --- p7zip-rar-16.02/C/XzIn.c 2015-11-20 20:40:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/XzIn.c 2025-05-04 10:00:00.000000000 +0000 @@ -1,313 +1,385 @@ -/* XzIn.c - Xz input -2015-11-08 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "7zCrc.h" -#include "CpuArch.h" -#include "Xz.h" - -SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) -{ - Byte sig[XZ_STREAM_HEADER_SIZE]; - RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) - return SZ_ERROR_NO_ARCHIVE; - return Xz_ParseHeader(p, sig); -} - -#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ - { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ - if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } - -SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes) -{ - Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; - unsigned headerSize; - *headerSizeRes = 0; - RINOK(SeqInStream_ReadByte(inStream, &header[0])); - headerSize = ((unsigned)header[0] << 2) + 4; - if (headerSize == 0) - { - *headerSizeRes = 1; - *isIndex = True; - return SZ_OK; - } - - *isIndex = False; - *headerSizeRes = headerSize; - RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1)); - return XzBlock_Parse(p, header); -} - -#define ADD_SIZE_CHECH(size, val) \ - { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; } - -UInt64 Xz_GetUnpackSize(const CXzStream *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECH(size, p->blocks[i].unpackSize); - return size; -} - -UInt64 Xz_GetPackSize(const CXzStream *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->numBlocks; i++) - ADD_SIZE_CHECH(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3); - return size; -} - -/* -SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) -{ - return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); -} -*/ - -static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) -{ - size_t numBlocks, pos = 1; - UInt32 crc; - - if (size < 5 || buf[0] != 0) - return SZ_ERROR_ARCHIVE; - - size -= 4; - crc = CrcCalc(buf, size); - if (crc != GetUi32(buf + size)) - return SZ_ERROR_ARCHIVE; - - { - UInt64 numBlocks64; - READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64); - numBlocks = (size_t)numBlocks64; - if (numBlocks != numBlocks64 || numBlocks * 2 > size) - return SZ_ERROR_ARCHIVE; - } - - Xz_Free(p, alloc); - if (numBlocks != 0) - { - size_t i; - p->numBlocks = numBlocks; - p->numBlocksAllocated = numBlocks; - p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); - if (p->blocks == 0) - return SZ_ERROR_MEM; - for (i = 0; i < numBlocks; i++) - { - CXzBlockSizes *block = &p->blocks[i]; - READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize); - READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize); - if (block->totalSize == 0) - return SZ_ERROR_ARCHIVE; - } - } - while ((pos & 3) != 0) - if (buf[pos++] != 0) - return SZ_ERROR_ARCHIVE; - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; -} - -static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc) -{ - SRes res; - size_t size; - Byte *buf; - if (indexSize > ((UInt32)1 << 31)) - return SZ_ERROR_UNSUPPORTED; - size = (size_t)indexSize; - if (size != indexSize) - return SZ_ERROR_UNSUPPORTED; - buf = alloc->Alloc(alloc, size); - if (buf == 0) - return SZ_ERROR_MEM; - res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); - if (res == SZ_OK) - res = Xz_ReadIndex2(p, buf, size, alloc); - alloc->Free(alloc, buf); - return res; -} - -static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size) -{ - RINOK(LookInStream_SeekTo(stream, offset)); - return LookInStream_Read(stream, buf, size); - /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ -} - -static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc) -{ - UInt64 indexSize; - Byte buf[XZ_STREAM_FOOTER_SIZE]; - UInt64 pos = *startOffset; - - if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - - pos -= XZ_STREAM_FOOTER_SIZE; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); - - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) - { - UInt32 total = 0; - pos += XZ_STREAM_FOOTER_SIZE; - - for (;;) - { - size_t i; - #define TEMP_BUF_SIZE (1 << 10) - Byte temp[TEMP_BUF_SIZE]; - - i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; - pos -= i; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)); - total += (UInt32)i; - for (; i != 0; i--) - if (temp[i - 1] != 0) - break; - if (i != 0) - { - if ((i & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - pos += i; - break; - } - if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) - return SZ_ERROR_NO_ARCHIVE; - } - - if (pos < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - pos -= XZ_STREAM_FOOTER_SIZE; - RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) - return SZ_ERROR_NO_ARCHIVE; - } - - p->flags = (CXzStreamFlags)GetBe16(buf + 8); - - if (!XzFlags_IsSupported(p->flags)) - return SZ_ERROR_UNSUPPORTED; - - if (GetUi32(buf) != CrcCalc(buf + 4, 6)) - return SZ_ERROR_ARCHIVE; - - indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; - - if (pos < indexSize) - return SZ_ERROR_ARCHIVE; - - pos -= indexSize; - RINOK(LookInStream_SeekTo(stream, pos)); - RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)); - - { - UInt64 totalSize = Xz_GetPackSize(p); - if (totalSize == XZ_SIZE_OVERFLOW - || totalSize >= ((UInt64)1 << 63) - || pos < totalSize + XZ_STREAM_HEADER_SIZE) - return SZ_ERROR_ARCHIVE; - pos -= (totalSize + XZ_STREAM_HEADER_SIZE); - RINOK(LookInStream_SeekTo(stream, pos)); - *startOffset = pos; - } - { - CXzStreamFlags headerFlags; - CSecToRead secToRead; - SecToRead_CreateVTable(&secToRead); - secToRead.realStream = stream; - - RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s)); - return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; - } -} - - -/* ---------- Xz Streams ---------- */ - -void Xzs_Construct(CXzs *p) -{ - p->num = p->numAllocated = 0; - p->streams = 0; -} - -void Xzs_Free(CXzs *p, ISzAlloc *alloc) -{ - size_t i; - for (i = 0; i < p->num; i++) - Xz_Free(&p->streams[i], alloc); - alloc->Free(alloc, p->streams); - p->num = p->numAllocated = 0; - p->streams = 0; -} - -UInt64 Xzs_GetNumBlocks(const CXzs *p) -{ - UInt64 num = 0; - size_t i; - for (i = 0; i < p->num; i++) - num += p->streams[i].numBlocks; - return num; -} - -UInt64 Xzs_GetUnpackSize(const CXzs *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->num; i++) - ADD_SIZE_CHECH(size, Xz_GetUnpackSize(&p->streams[i])); - return size; -} - -/* -UInt64 Xzs_GetPackSize(const CXzs *p) -{ - UInt64 size = 0; - size_t i; - for (i = 0; i < p->num; i++) - ADD_SIZE_CHECH(size, Xz_GetTotalSize(&p->streams[i])); - return size; -} -*/ - -SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc) -{ - Int64 endOffset = 0; - RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END)); - *startOffset = endOffset; - for (;;) - { - CXzStream st; - SRes res; - Xz_Construct(&st); - res = Xz_ReadBackward(&st, stream, startOffset, alloc); - st.startOffset = *startOffset; - RINOK(res); - if (p->num == p->numAllocated) - { - size_t newNum = p->num + p->num / 4 + 1; - Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream)); - if (data == 0) - return SZ_ERROR_MEM; - p->numAllocated = newNum; - if (p->num != 0) - memcpy(data, p->streams, p->num * sizeof(CXzStream)); - alloc->Free(alloc, p->streams); - p->streams = (CXzStream *)data; - } - p->streams[p->num++] = st; - if (*startOffset == 0) - break; - RINOK(LookInStream_SeekTo(stream, *startOffset)); - if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK) - return SZ_ERROR_PROGRESS; - } - return SZ_OK; -} +/* XzIn.c - Xz input +: Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zCrc.h" +#include "Xz.h" +#include "CpuArch.h" + +#define XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(p) \ + (GetUi16a((const Byte *)(const void *)(p) + 10) == \ + (XZ_FOOTER_SIG_0 | (XZ_FOOTER_SIG_1 << 8))) + +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream) +{ + UInt32 data32[XZ_STREAM_HEADER_SIZE / 4]; + size_t processedSize = XZ_STREAM_HEADER_SIZE; + RINOK(SeqInStream_ReadMax(inStream, data32, &processedSize)) + if (processedSize != XZ_STREAM_HEADER_SIZE + || memcmp(data32, XZ_SIG, XZ_SIG_SIZE) != 0) + return SZ_ERROR_NO_ARCHIVE; + return Xz_ParseHeader(p, (const Byte *)(const void *)data32); +} + +#define READ_VARINT_AND_CHECK(buf, size, res) \ +{ const unsigned s = Xz_ReadVarInt(buf, size, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; \ + size -= s; \ + buf += s; \ +} + +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes) +{ + MY_ALIGN(4) + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + unsigned headerSize; + *headerSizeRes = 0; + RINOK(SeqInStream_ReadByte(inStream, &header[0])) + headerSize = header[0]; + if (headerSize == 0) + { + *headerSizeRes = 1; + *isIndex = True; + return SZ_OK; + } + + *isIndex = False; + headerSize = (headerSize << 2) + 4; + *headerSizeRes = (UInt32)headerSize; + { + size_t processedSize = headerSize - 1; + RINOK(SeqInStream_ReadMax(inStream, header + 1, &processedSize)) + if (processedSize != headerSize - 1) + return SZ_ERROR_INPUT_EOF; + } + return XzBlock_Parse(p, header); +} + + +#define ADD_SIZE_CHECK(size, val) \ +{ const UInt64 newSize = size + (val); \ + if (newSize < size) return XZ_SIZE_OVERFLOW; \ + size = newSize; \ +} + +UInt64 Xz_GetUnpackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + { + ADD_SIZE_CHECK(size, p->blocks[i].unpackSize) + } + return size; +} + +UInt64 Xz_GetPackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + { + ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3) + } + return size; +} + + +// input; +// CXzStream (p) is empty object. +// size != 0 +// (size & 3) == 0 +// (buf) is aligned for at least 4 bytes. +// output: +// p->numBlocks is number of allocated items in p->blocks +// p->blocks[*] values must be ignored, if function returns error. +static SRes Xz_ParseIndex(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + size_t numBlocks; + if (size < 5 || buf[0] != 0) + return SZ_ERROR_ARCHIVE; + size -= 4; + { + const UInt32 crc = CrcCalc(buf, size); + if (crc != GetUi32a(buf + size)) + return SZ_ERROR_ARCHIVE; + } + buf++; + size--; + { + UInt64 numBlocks64; + READ_VARINT_AND_CHECK(buf, size, &numBlocks64) + // (numBlocks64) is 63-bit value, so we can calculate (numBlocks64 * 2): + if (numBlocks64 * 2 > size) + return SZ_ERROR_ARCHIVE; + if (numBlocks64 >= ((size_t)1 << (sizeof(size_t) * 8 - 1)) / sizeof(CXzBlockSizes)) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE + numBlocks = (size_t)numBlocks64; + } + // Xz_Free(p, alloc); // it's optional, because (p) is empty already + if (numBlocks) + { + CXzBlockSizes *blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); + if (!blocks) + return SZ_ERROR_MEM; + p->blocks = blocks; + p->numBlocks = numBlocks; + // the caller will call Xz_Free() in case of error + do + { + READ_VARINT_AND_CHECK(buf, size, &blocks->totalSize) + READ_VARINT_AND_CHECK(buf, size, &blocks->unpackSize) + if (blocks->totalSize == 0) + return SZ_ERROR_ARCHIVE; + blocks++; + } + while (--numBlocks); + } + if (size >= 4) + return SZ_ERROR_ARCHIVE; + while (size) + if (buf[--size]) + return SZ_ERROR_ARCHIVE; + return SZ_OK; +} + + +/* +static SRes Xz_ReadIndex(CXzStream *p, ILookInStreamPtr stream, UInt64 indexSize, ISzAllocPtr alloc) +{ + SRes res; + size_t size; + Byte *buf; + if (indexSize >= ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE + size = (size_t)indexSize; + buf = (Byte *)ISzAlloc_Alloc(alloc, size); + if (!buf) + return SZ_ERROR_MEM; + res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); + if (res == SZ_OK) + res = Xz_ParseIndex(p, buf, size, alloc); + ISzAlloc_Free(alloc, buf); + return res; +} +*/ + +static SRes LookInStream_SeekRead_ForArc(ILookInStreamPtr stream, UInt64 offset, void *buf, size_t size) +{ + RINOK(LookInStream_SeekTo(stream, offset)) + return LookInStream_Read(stream, buf, size); + /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ +} + + +/* +in: + (*startOffset) is position in (stream) where xz_stream must be finished. +out: + if returns SZ_OK, then (*startOffset) is position in stream that shows start of xz_stream. +*/ +static SRes Xz_ReadBackward(CXzStream *p, ILookInStreamPtr stream, Int64 *startOffset, ISzAllocPtr alloc) +{ + #define TEMP_BUF_SIZE (1 << 10) + UInt32 buf32[TEMP_BUF_SIZE / 4]; + UInt64 pos = (UInt64)*startOffset; + + if ((pos & 3) || pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, XZ_STREAM_FOOTER_SIZE)) + + if (!XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(buf32)) + { + pos += XZ_STREAM_FOOTER_SIZE; + for (;;) + { + // pos != 0 + // (pos & 3) == 0 + size_t i = pos >= TEMP_BUF_SIZE ? TEMP_BUF_SIZE : (size_t)pos; + pos -= i; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, i)) + i /= 4; + do + if (buf32[i - 1] != 0) + break; + while (--i); + + pos += i * 4; + #define XZ_STREAM_BACKWARD_READING_PAD_MAX (1 << 16) + // here we don't support rare case with big padding for xz stream. + // so we have padding limit for backward reading. + if ((UInt64)*startOffset - pos > XZ_STREAM_BACKWARD_READING_PAD_MAX) + return SZ_ERROR_NO_ARCHIVE; + if (i) + break; + } + // we try to open xz stream after skipping zero padding. + // ((UInt64)*startOffset == pos) is possible here! + if (pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf32, XZ_STREAM_FOOTER_SIZE)) + if (!XZ_FOOTER_12B_ALIGNED16_SIG_CHECK(buf32)) + return SZ_ERROR_NO_ARCHIVE; + } + + p->flags = (CXzStreamFlags)GetBe16a(buf32 + 2); + if (!XzFlags_IsSupported(p->flags)) + return SZ_ERROR_UNSUPPORTED; + { + /* to eliminate GCC 6.3 warning: + dereferencing type-punned pointer will break strict-aliasing rules */ + const UInt32 *buf_ptr = buf32; + if (GetUi32a(buf_ptr) != CrcCalc(buf32 + 1, 6)) + return SZ_ERROR_ARCHIVE; + } + { + const UInt64 indexSize = ((UInt64)GetUi32a(buf32 + 1) + 1) << 2; + if (pos < indexSize) + return SZ_ERROR_ARCHIVE; + pos -= indexSize; + // v25.00: relaxed indexSize check. We allow big index table. + // if (indexSize > ((UInt32)1 << 31)) + if (indexSize >= ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return SZ_ERROR_MEM; // SZ_ERROR_ARCHIVE + RINOK(LookInStream_SeekTo(stream, pos)) + // RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)) + { + SRes res; + const size_t size = (size_t)indexSize; + // if (size != indexSize) return SZ_ERROR_UNSUPPORTED; + Byte *buf = (Byte *)ISzAlloc_Alloc(alloc, size); + if (!buf) + return SZ_ERROR_MEM; + res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); + if (res == SZ_OK) + res = Xz_ParseIndex(p, buf, size, alloc); + ISzAlloc_Free(alloc, buf); + RINOK(res) + } + } + { + UInt64 total = Xz_GetPackSize(p); + if (total == XZ_SIZE_OVERFLOW || total >= ((UInt64)1 << 63)) + return SZ_ERROR_ARCHIVE; + total += XZ_STREAM_HEADER_SIZE; + if (pos < total) + return SZ_ERROR_ARCHIVE; + pos -= total; + RINOK(LookInStream_SeekTo(stream, pos)) + *startOffset = (Int64)pos; + } + { + CXzStreamFlags headerFlags; + CSecToRead secToRead; + SecToRead_CreateVTable(&secToRead); + secToRead.realStream = stream; + RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)) + return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; + } +} + + +/* ---------- Xz Streams ---------- */ + +void Xzs_Construct(CXzs *p) +{ + Xzs_CONSTRUCT(p) +} + +void Xzs_Free(CXzs *p, ISzAllocPtr alloc) +{ + size_t i; + for (i = 0; i < p->num; i++) + Xz_Free(&p->streams[i], alloc); + ISzAlloc_Free(alloc, p->streams); + p->num = p->numAllocated = 0; + p->streams = NULL; +} + +UInt64 Xzs_GetNumBlocks(const CXzs *p) +{ + UInt64 num = 0; + size_t i; + for (i = 0; i < p->num; i++) + num += p->streams[i].numBlocks; + return num; +} + +UInt64 Xzs_GetUnpackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + { + ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])) + } + return size; +} + +/* +UInt64 Xzs_GetPackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + { + ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])) + } + return size; +} +*/ + +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr stream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc) +{ + Int64 endOffset = 0; + // it's supposed that CXzs object is empty here. + // if CXzs object is not empty, it will add new streams to that non-empty object. + // Xzs_Free(p, alloc); // it's optional call to empty CXzs object. + RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)) + *startOffset = endOffset; + for (;;) + { + CXzStream st; + SRes res; + Xz_CONSTRUCT(&st) + res = Xz_ReadBackward(&st, stream, startOffset, alloc); + // if (res == SZ_OK), then (*startOffset) is start offset of new stream if + // if (res != SZ_OK), then (*startOffset) is unchend or it's expected start offset of stream with error + st.startOffset = (UInt64)*startOffset; + // we must store (st) object to array, or we must free (st) local object. + if (res != SZ_OK) + { + Xz_Free(&st, alloc); + return res; + } + if (p->num == p->numAllocated) + { + const size_t newNum = p->num + p->num / 4 + 1; + void *data = ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream)); + if (!data) + { + Xz_Free(&st, alloc); + return SZ_ERROR_MEM; + } + p->numAllocated = newNum; + if (p->num != 0) + memcpy(data, p->streams, p->num * sizeof(CXzStream)); + ISzAlloc_Free(alloc, p->streams); + p->streams = (CXzStream *)data; + } + // we use direct copying of raw data from local variable (st) to object in array. + // so we don't need to call Xz_Free(&st, alloc) after copying and after p->num++ + p->streams[p->num++] = st; + if (*startOffset == 0) + return SZ_OK; + // seek operation is optional: + // RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)) + if (progress && ICompressProgress_Progress(progress, (UInt64)(endOffset - *startOffset), (UInt64)(Int64)-1) != SZ_OK) + return SZ_ERROR_PROGRESS; + } +} diff -Nru p7zip-rar-16.02/C/ZstdDec.c p7zip-rar-16.02+really25.00+ds/C/ZstdDec.c --- p7zip-rar-16.02/C/ZstdDec.c 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/ZstdDec.c 2024-06-18 06:00:00.000000000 +0000 @@ -0,0 +1,4067 @@ +/* ZstdDec.c -- Zstd Decoder +2024-06-18 : the code was developed by Igor Pavlov, using Zstandard format + specification and original zstd decoder code as reference code. +original zstd decoder code: Copyright (c) Facebook, Inc. All rights reserved. +This source code is licensed under BSD 3-Clause License. +*/ + +#include "Precomp.h" + +#include +#include +// #include + +#include "Alloc.h" +#include "Xxh64.h" +#include "ZstdDec.h" +#include "CpuArch.h" + +#if defined(MY_CPU_ARM64) +#include +#endif + +/* original-zstd still doesn't support window larger than 2 GiB. + So we also limit our decoder for 2 GiB window: */ +#if defined(MY_CPU_64BIT) && 0 == 1 + #define MAX_WINDOW_SIZE_LOG 41 +#else + #define MAX_WINDOW_SIZE_LOG 31 +#endif + +typedef + #if MAX_WINDOW_SIZE_LOG < 32 + UInt32 + #else + size_t + #endif + CZstdDecOffset; + +// for debug: simpler and smaller code but slow: +// #define Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + +// #define SHOW_STAT +#ifdef SHOW_STAT +#include +static unsigned g_Num_Blocks_Compressed = 0; +static unsigned g_Num_Blocks_memcpy = 0; +static unsigned g_Num_Wrap_memmove_Num = 0; +static unsigned g_Num_Wrap_memmove_Bytes = 0; +static unsigned g_NumSeqs_total = 0; +// static unsigned g_NumCopy = 0; +static unsigned g_NumOver = 0; +static unsigned g_NumOver2 = 0; +static unsigned g_Num_Match = 0; +static unsigned g_Num_Lits = 0; +static unsigned g_Num_LitsBig = 0; +static unsigned g_Num_Lit0 = 0; +static unsigned g_Num_Rep0 = 0; +static unsigned g_Num_Rep1 = 0; +static unsigned g_Num_Rep2 = 0; +static unsigned g_Num_Rep3 = 0; +static unsigned g_Num_Threshold_0 = 0; +static unsigned g_Num_Threshold_1 = 0; +static unsigned g_Num_Threshold_0sum = 0; +static unsigned g_Num_Threshold_1sum = 0; +#define STAT_UPDATE(v) v +#else +#define STAT_UPDATE(v) +#endif +#define STAT_INC(v) STAT_UPDATE(v++;) + + +typedef struct +{ + const Byte *ptr; + size_t len; +} +CInBufPair; + + +#if defined(MY_CPU_ARM_OR_ARM64) || defined(MY_CPU_X86_OR_AMD64) + #if (defined(__clang__) && (__clang_major__ >= 6)) \ + || (defined(__GNUC__) && (__GNUC__ >= 6)) + // disable for debug: + #define Z7_ZSTD_DEC_USE_BSR + #elif defined(_MSC_VER) && (_MSC_VER >= 1300) + // #if defined(MY_CPU_ARM_OR_ARM64) + #if (_MSC_VER >= 1600) + #include + #endif + // disable for debug: + #define Z7_ZSTD_DEC_USE_BSR + #endif +#endif + +#ifdef Z7_ZSTD_DEC_USE_BSR + #if defined(__clang__) || defined(__GNUC__) + #define MY_clz(x) ((unsigned)__builtin_clz((UInt32)x)) + #else // #if defined(_MSC_VER) + #ifdef MY_CPU_ARM_OR_ARM64 + #define MY_clz _CountLeadingZeros + #endif // MY_CPU_X86_OR_AMD64 + #endif // _MSC_VER +#elif !defined(Z7_ZSTD_DEC_USE_LOG_TABLE) + #define Z7_ZSTD_DEC_USE_LOG_TABLE +#endif + + +static +Z7_FORCE_INLINE +unsigned GetHighestSetBit_32_nonzero_big(UInt32 num) +{ + // (num != 0) + #ifdef MY_clz + return 31 - MY_clz(num); + #elif defined(Z7_ZSTD_DEC_USE_BSR) + { + unsigned long zz; + _BitScanReverse(&zz, num); + return zz; + } + #else + { + int i = -1; + for (;;) + { + i++; + num >>= 1; + if (num == 0) + return (unsigned)i; + } + } + #endif +} + +#ifdef Z7_ZSTD_DEC_USE_LOG_TABLE + +#define R1(a) a, a +#define R2(a) R1(a), R1(a) +#define R3(a) R2(a), R2(a) +#define R4(a) R3(a), R3(a) +#define R5(a) R4(a), R4(a) +#define R6(a) R5(a), R5(a) +#define R7(a) R6(a), R6(a) +#define R8(a) R7(a), R7(a) +#define R9(a) R8(a), R8(a) + +#define Z7_ZSTD_FSE_MAX_ACCURACY 9 +// states[] values in FSE_Generate() can use (Z7_ZSTD_FSE_MAX_ACCURACY + 1) bits. +static const Byte k_zstd_LogTable[2 << Z7_ZSTD_FSE_MAX_ACCURACY] = +{ + R1(0), R1(1), R2(2), R3(3), R4(4), R5(5), R6(6), R7(7), R8(8), R9(9) +}; + +#define GetHighestSetBit_32_nonzero_small(num) (k_zstd_LogTable[num]) +#else +#define GetHighestSetBit_32_nonzero_small GetHighestSetBit_32_nonzero_big +#endif + + +#ifdef MY_clz + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + bitOffset -= (CBitCtr)(MY_clz(b) - 23); +#elif defined(Z7_ZSTD_DEC_USE_BSR) + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + { unsigned long zz; _BitScanReverse(&zz, b); bitOffset -= 8; bitOffset += zz; } +#else + #define UPDATE_BIT_OFFSET_FOR_PADDING(b, bitOffset) \ + for (;;) { bitOffset--; if (b & 0x80) { break; } b <<= 1; } +#endif + +#define SET_bitOffset_TO_PAD(bitOffset, src, srcLen) \ +{ \ + unsigned lastByte = (src)[(size_t)(srcLen) - 1]; \ + if (lastByte == 0) return SZ_ERROR_DATA; \ + bitOffset = (CBitCtr)((srcLen) * 8); \ + UPDATE_BIT_OFFSET_FOR_PADDING(lastByte, bitOffset) \ +} + +#ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + +#define SET_bitOffset_TO_PAD_and_SET_BIT_SIZE(bitOffset, src, srcLen_res) \ +{ \ + unsigned lastByte = (src)[(size_t)(srcLen_res) - 1]; \ + if (lastByte == 0) return SZ_ERROR_DATA; \ + srcLen_res *= 8; \ + bitOffset = (CBitCtr)srcLen_res; \ + UPDATE_BIT_OFFSET_FOR_PADDING(lastByte, bitOffset) \ +} + +#endif + +/* +typedef Int32 CBitCtr_signed; +typedef Int32 CBitCtr; +*/ +// /* +typedef ptrdiff_t CBitCtr_signed; +typedef ptrdiff_t CBitCtr; +// */ + + +#define MATCH_LEN_MIN 3 +#define kBlockSizeMax (1u << 17) + +// #define Z7_ZSTD_DEC_PRINT_TABLE + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE +#define NUM_OFFSET_SYMBOLS_PREDEF 29 +#endif +#define NUM_OFFSET_SYMBOLS_MAX (MAX_WINDOW_SIZE_LOG + 1) // 32 +#define NUM_LL_SYMBOLS 36 +#define NUM_ML_SYMBOLS 53 +#define FSE_NUM_SYMBOLS_MAX 53 // NUM_ML_SYMBOLS + +// /* +#if !defined(MY_CPU_X86) || defined(__PIC__) || defined(MY_CPU_64BIT) +#define Z7_ZSTD_DEC_USE_BASES_IN_OBJECT +#endif +// */ +// for debug: +// #define Z7_ZSTD_DEC_USE_BASES_LOCAL +// #define Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + +#define GLOBAL_TABLE(n) k_ ## n + +#if defined(Z7_ZSTD_DEC_USE_BASES_LOCAL) + #define BASES_TABLE(n) a_ ## n +#elif defined(Z7_ZSTD_DEC_USE_BASES_IN_OBJECT) + #define BASES_TABLE(n) p->m_ ## n +#else + #define BASES_TABLE(n) GLOBAL_TABLE(n) +#endif + +#define Z7_ZSTD_DEC_USE_ML_PLUS3 + +#if defined(Z7_ZSTD_DEC_USE_BASES_LOCAL) || \ + defined(Z7_ZSTD_DEC_USE_BASES_IN_OBJECT) + +#define SEQ_EXTRA_TABLES(n) \ + Byte n ## SEQ_LL_EXTRA [NUM_LL_SYMBOLS]; \ + Byte n ## SEQ_ML_EXTRA [NUM_ML_SYMBOLS]; \ + UInt32 n ## SEQ_LL_BASES [NUM_LL_SYMBOLS]; \ + UInt32 n ## SEQ_ML_BASES [NUM_ML_SYMBOLS]; \ + +#define Z7_ZSTD_DEC_USE_BASES_CALC + +#ifdef Z7_ZSTD_DEC_USE_BASES_CALC + + #define FILL_LOC_BASES(n, startSum) \ + { unsigned i; UInt32 sum = startSum; \ + for (i = 0; i != Z7_ARRAY_SIZE(GLOBAL_TABLE(n ## _EXTRA)); i++) \ + { const unsigned a = GLOBAL_TABLE(n ## _EXTRA)[i]; \ + BASES_TABLE(n ## _BASES)[i] = sum; \ + /* if (sum != GLOBAL_TABLE(n ## _BASES)[i]) exit(1); */ \ + sum += (UInt32)1 << a; \ + BASES_TABLE(n ## _EXTRA)[i] = (Byte)a; }} + + #define FILL_LOC_BASES_ALL \ + FILL_LOC_BASES (SEQ_LL, 0) \ + FILL_LOC_BASES (SEQ_ML, MATCH_LEN_MIN) \ + +#else + #define COPY_GLOBAL_ARR(n) \ + memcpy(BASES_TABLE(n), GLOBAL_TABLE(n), sizeof(GLOBAL_TABLE(n))); + #define FILL_LOC_BASES_ALL \ + COPY_GLOBAL_ARR (SEQ_LL_EXTRA) \ + COPY_GLOBAL_ARR (SEQ_ML_EXTRA) \ + COPY_GLOBAL_ARR (SEQ_LL_BASES) \ + COPY_GLOBAL_ARR (SEQ_ML_BASES) \ + +#endif + +#endif + + + +/// The sequence decoding baseline and number of additional bits to read/add +#if !defined(Z7_ZSTD_DEC_USE_BASES_CALC) +static const UInt32 GLOBAL_TABLE(SEQ_LL_BASES) [NUM_LL_SYMBOLS] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 +}; +#endif + +static const Byte GLOBAL_TABLE(SEQ_LL_EXTRA) [NUM_LL_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16 +}; + +#if !defined(Z7_ZSTD_DEC_USE_BASES_CALC) +static const UInt32 GLOBAL_TABLE(SEQ_ML_BASES) [NUM_ML_SYMBOLS] = +{ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 +}; +#endif + +static const Byte GLOBAL_TABLE(SEQ_ML_EXTRA) [NUM_ML_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16 +}; + + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE + +static const Int16 SEQ_LL_PREDEF_DIST [NUM_LL_SYMBOLS] = +{ + 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 +}; +static const Int16 SEQ_OFFSET_PREDEF_DIST [NUM_OFFSET_SYMBOLS_PREDEF] = +{ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 +}; +static const Int16 SEQ_ML_PREDEF_DIST [NUM_ML_SYMBOLS] = +{ + 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 +}; + +#endif + +// typedef int FastInt; +// typedef Int32 FastInt32; +typedef unsigned FastInt; +typedef UInt32 FastInt32; +typedef FastInt32 CFseRecord; + + +#define FSE_REC_LEN_OFFSET 8 +#define FSE_REC_STATE_OFFSET 16 +#define GET_FSE_REC_SYM(st) ((Byte)(st)) +#define GET_FSE_REC_LEN(st) ((Byte)((st) >> FSE_REC_LEN_OFFSET)) +#define GET_FSE_REC_STATE(st) ((st) >> FSE_REC_STATE_OFFSET) + +// #define FSE_REC_SYM_MASK (0xff) +// #define GET_FSE_REC_SYM(st) (st & FSE_REC_SYM_MASK) + +#define W_BASE(state, len, sym) \ + (((UInt32)state << (4 + FSE_REC_STATE_OFFSET)) + \ + (len << FSE_REC_LEN_OFFSET) + (sym)) +#define W(state, len, sym) W_BASE(state, len, sym) +static const CFseRecord k_PredefRecords_LL[1 << 6] = { +W(0,4, 0),W(1,4, 0),W(2,5, 1),W(0,5, 3),W(0,5, 4),W(0,5, 6),W(0,5, 7),W(0,5, 9), +W(0,5,10),W(0,5,12),W(0,6,14),W(0,5,16),W(0,5,18),W(0,5,19),W(0,5,21),W(0,5,22), +W(0,5,24),W(2,5,25),W(0,5,26),W(0,6,27),W(0,6,29),W(0,6,31),W(2,4, 0),W(0,4, 1), +W(0,5, 2),W(2,5, 4),W(0,5, 5),W(2,5, 7),W(0,5, 8),W(2,5,10),W(0,5,11),W(0,6,13), +W(2,5,16),W(0,5,17),W(2,5,19),W(0,5,20),W(2,5,22),W(0,5,23),W(0,4,25),W(1,4,25), +W(2,5,26),W(0,6,28),W(0,6,30),W(3,4, 0),W(1,4, 1),W(2,5, 2),W(2,5, 3),W(2,5, 5), +W(2,5, 6),W(2,5, 8),W(2,5, 9),W(2,5,11),W(2,5,12),W(0,6,15),W(2,5,17),W(2,5,18), +W(2,5,20),W(2,5,21),W(2,5,23),W(2,5,24),W(0,6,35),W(0,6,34),W(0,6,33),W(0,6,32) +}; +static const CFseRecord k_PredefRecords_OF[1 << 5] = { +W(0,5, 0),W(0,4, 6),W(0,5, 9),W(0,5,15),W(0,5,21),W(0,5, 3),W(0,4, 7),W(0,5,12), +W(0,5,18),W(0,5,23),W(0,5, 5),W(0,4, 8),W(0,5,14),W(0,5,20),W(0,5, 2),W(1,4, 7), +W(0,5,11),W(0,5,17),W(0,5,22),W(0,5, 4),W(1,4, 8),W(0,5,13),W(0,5,19),W(0,5, 1), +W(1,4, 6),W(0,5,10),W(0,5,16),W(0,5,28),W(0,5,27),W(0,5,26),W(0,5,25),W(0,5,24) +}; +#if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) +#undef W +#define W(state, len, sym) W_BASE(state, len, (sym + MATCH_LEN_MIN)) +#endif +static const CFseRecord k_PredefRecords_ML[1 << 6] = { +W(0,6, 0),W(0,4, 1),W(2,5, 2),W(0,5, 3),W(0,5, 5),W(0,5, 6),W(0,5, 8),W(0,6,10), +W(0,6,13),W(0,6,16),W(0,6,19),W(0,6,22),W(0,6,25),W(0,6,28),W(0,6,31),W(0,6,33), +W(0,6,35),W(0,6,37),W(0,6,39),W(0,6,41),W(0,6,43),W(0,6,45),W(1,4, 1),W(0,4, 2), +W(2,5, 3),W(0,5, 4),W(2,5, 6),W(0,5, 7),W(0,6, 9),W(0,6,12),W(0,6,15),W(0,6,18), +W(0,6,21),W(0,6,24),W(0,6,27),W(0,6,30),W(0,6,32),W(0,6,34),W(0,6,36),W(0,6,38), +W(0,6,40),W(0,6,42),W(0,6,44),W(2,4, 1),W(3,4, 1),W(1,4, 2),W(2,5, 4),W(2,5, 5), +W(2,5, 7),W(2,5, 8),W(0,6,11),W(0,6,14),W(0,6,17),W(0,6,20),W(0,6,23),W(0,6,26), +W(0,6,29),W(0,6,52),W(0,6,51),W(0,6,50),W(0,6,49),W(0,6,48),W(0,6,47),W(0,6,46) +}; + + +// sum of freqs[] must be correct +// (numSyms != 0) +// (accuracy >= 5) +static +Z7_NO_INLINE +// Z7_FORCE_INLINE +void FSE_Generate(CFseRecord *table, + const Int16 *const freqs, const size_t numSyms, + const unsigned accuracy, UInt32 delta) +{ + size_t size = (size_t)1 << accuracy; + // max value in states[x] is ((1 << accuracy) * 2) + UInt16 states[FSE_NUM_SYMBOLS_MAX]; + { + /* Symbols with "less than 1" probability get a single cell, + starting from the end of the table. + These symbols define a full state reset, reading (accuracy) bits. */ + size_t threshold = size; + { + size_t s = 0; + do + if (freqs[s] == -1) + { + table[--threshold] = (CFseRecord)s; + states[s] = 1; + } + while (++s != numSyms); + } + + #ifdef SHOW_STAT + if (threshold == size) + { + STAT_INC(g_Num_Threshold_0) + STAT_UPDATE(g_Num_Threshold_0sum += (unsigned)size;) + } + else + { + STAT_INC(g_Num_Threshold_1) + STAT_UPDATE(g_Num_Threshold_1sum += (unsigned)size;) + } + #endif + + // { unsigned uuu; for (uuu = 0; uuu < 400; uuu++) + { + // Each (symbol) gets freqs[symbol] cells. + // Cell allocation is spread, not linear. + const size_t step = (size >> 1) + (size >> 3) + 3; + size_t pos = 0; + // const unsigned mask = size - 1; + /* + if (threshold == size) + { + size_t s = 0; + size--; + do + { + int freq = freqs[s]; + if (freq <= 0) + continue; + states[s] = (UInt16)freq; + do + { + table[pos] (CFseRecord)s; + pos = (pos + step) & size; // & mask; + } + while (--freq); + } + while (++s != numSyms); + } + else + */ + { + size_t s = 0; + size--; + do + { + int freq = freqs[s]; + if (freq <= 0) + continue; + states[s] = (UInt16)freq; + do + { + table[pos] = (CFseRecord)s; + // we skip position, if it's already occupied by a "less than 1" probability symbol. + // (step) is coprime to table size, so the cycle will visit each position exactly once + do + pos = (pos + step) & size; // & mask; + while (pos >= threshold); + } + while (--freq); + } + while (++s != numSyms); + } + size++; + // (pos != 0) is unexpected case that means that freqs[] are not correct. + // so it's some failure in code (for example, incorrect predefined freq[] table) + // if (pos != 0) return SZ_ERROR_FAIL; + } + // } + } + { + const CFseRecord * const limit = table + size; + delta = ((UInt32)size << FSE_REC_STATE_OFFSET) - delta; + /* State increases by symbol over time, decreasing number of bits. + Baseline increases until the bit threshold is passed, at which point it resets to 0 */ + do + { + #define TABLE_ITER(a) \ + { \ + const FastInt sym = (FastInt)table[a]; \ + const unsigned nextState = states[sym]; \ + unsigned nb; \ + states[sym] = (UInt16)(nextState + 1); \ + nb = accuracy - GetHighestSetBit_32_nonzero_small(nextState); \ + table[a] = (CFseRecord)(sym - delta \ + + ((UInt32)nb << FSE_REC_LEN_OFFSET) \ + + ((UInt32)nextState << FSE_REC_STATE_OFFSET << nb)); \ + } + TABLE_ITER(0) + TABLE_ITER(1) + table += 2; + } + while (table != limit); + } +} + + +#ifdef Z7_ZSTD_DEC_PRINT_TABLE + +static void Print_Predef(unsigned predefAccuracy, + const unsigned numSymsPredef, + const Int16 * const predefFreqs, + const CFseRecord *checkTable) +{ + CFseRecord table[1 << 6]; + unsigned i; + FSE_Generate(table, predefFreqs, numSymsPredef, predefAccuracy, + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + numSymsPredef == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : + #endif + 0 + ); + if (memcmp(table, checkTable, sizeof(UInt32) << predefAccuracy) != 0) + exit(1); + for (i = 0; i < (1u << predefAccuracy); i++) + { + const UInt32 v = table[i]; + const unsigned state = (unsigned)(GET_FSE_REC_STATE(v)); + if (state & 0xf) + exit(1); + if (i != 0) + { + printf(","); + if (i % 8 == 0) + printf("\n"); + } + printf("W(%d,%d,%2d)", + (unsigned)(state >> 4), + (unsigned)((v >> FSE_REC_LEN_OFFSET) & 0xff), + (unsigned)GET_FSE_REC_SYM(v)); + } + printf("\n\n"); +} + +#endif + + +#define GET16(dest, p) { const Byte *ptr = p; dest = GetUi16(ptr); } +#define GET32(dest, p) { const Byte *ptr = p; dest = GetUi32(ptr); } + +// (1 <= numBits <= 9) +#define FORWARD_READ_BITS(destVal, numBits, mask) \ + { const CBitCtr_signed bos3 = (bitOffset) >> 3; \ + if (bos3 >= 0) return SZ_ERROR_DATA; \ + GET16(destVal, src + bos3) \ + destVal >>= (bitOffset) & 7; \ + bitOffset += (CBitCtr_signed)(numBits); \ + mask = (1u << (numBits)) - 1; \ + destVal &= mask; \ + } + +#define FORWARD_READ_1BIT(destVal) \ + { const CBitCtr_signed bos3 = (bitOffset) >> 3; \ + if (bos3 >= 0) return SZ_ERROR_DATA; \ + destVal = *(src + bos3); \ + destVal >>= (bitOffset) & 7; \ + (bitOffset)++; \ + destVal &= 1; \ + } + + +// in: (accuracyMax <= 9) +// at least 2 bytes will be processed from (in) stream. +// at return: (in->len > 0) +static +Z7_NO_INLINE +SRes FSE_DecodeHeader(CFseRecord *const table, + CInBufPair *const in, + const unsigned accuracyMax, + Byte *const accuracyRes, + unsigned numSymbolsMax) +{ + unsigned accuracy; + unsigned remain1; + unsigned syms; + Int16 freqs[FSE_NUM_SYMBOLS_MAX + 3]; // +3 for overwrite (repeat) + const Byte *src = in->ptr; + CBitCtr_signed bitOffset = (CBitCtr_signed)in->len - 1; + if (bitOffset <= 0) + return SZ_ERROR_DATA; + accuracy = *src & 0xf; + accuracy += 5; + if (accuracy > accuracyMax) + return SZ_ERROR_DATA; + *accuracyRes = (Byte)accuracy; + remain1 = (1u << accuracy) + 1; // (it's remain_freqs_sum + 1) + syms = 0; + src += bitOffset; // src points to last byte + bitOffset = 4 - (bitOffset << 3); + + for (;;) + { + // (2 <= remain1) + const unsigned bits = GetHighestSetBit_32_nonzero_small((unsigned)remain1); + // (1 <= bits <= accuracy) + unsigned val; // it must be unsigned or int + unsigned mask; + FORWARD_READ_BITS(val, bits, mask) + { + const unsigned val2 = remain1 + val - mask; + if (val2 > mask) + { + unsigned bit; + FORWARD_READ_1BIT(bit) + if (bit) + val = val2; + } + } + { + // (remain1 >= 2) + // (0 <= (int)val <= remain1) + val = (unsigned)((int)val - 1); + // val now is "probability" of symbol + // (probability == -1) means "less than 1" frequency. + // (-1 <= (int)val <= remain1 - 1) + freqs[syms++] = (Int16)(int)val; + if (val != 0) + { + remain1 -= (int)val < 0 ? 1u : (unsigned)val; + // remain1 -= val; + // val >>= (sizeof(val) * 8 - 2); + // remain1 -= val & 2; + // freqs[syms++] = (Int16)(int)val; + // syms++; + if (remain1 == 1) + break; + if (syms >= FSE_NUM_SYMBOLS_MAX) + return SZ_ERROR_DATA; + } + else // if (val == 0) + { + // freqs[syms++] = 0; + // syms++; + for (;;) + { + unsigned repeat; + FORWARD_READ_BITS(repeat, 2, mask) + freqs[syms ] = 0; + freqs[syms + 1] = 0; + freqs[syms + 2] = 0; + syms += repeat; + if (syms >= FSE_NUM_SYMBOLS_MAX) + return SZ_ERROR_DATA; + if (repeat != 3) + break; + } + } + } + } + + if (syms > numSymbolsMax) + return SZ_ERROR_DATA; + bitOffset += 7; + bitOffset >>= 3; + if (bitOffset > 0) + return SZ_ERROR_DATA; + in->ptr = src + bitOffset; + in->len = (size_t)(1 - bitOffset); + { + // unsigned uuu; for (uuu = 0; uuu < 50; uuu++) + FSE_Generate(table, freqs, syms, accuracy, + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : + #endif + 0 + ); + } + return SZ_OK; +} + + +// ---------- HUFFMAN ---------- + +#define HUF_MAX_BITS 12 +#define HUF_MAX_SYMBS 256 +#define HUF_DUMMY_SIZE (128 + 8 * 2) // it must multiple of 8 +// #define HUF_DUMMY_SIZE 0 +#define HUF_TABLE_SIZE ((2 << HUF_MAX_BITS) + HUF_DUMMY_SIZE) +#define HUF_GET_SYMBOLS(table) ((table) + (1 << HUF_MAX_BITS) + HUF_DUMMY_SIZE) +// #define HUF_GET_LENS(table) (table) + +typedef struct +{ + // Byte table[HUF_TABLE_SIZE]; + UInt64 table64[HUF_TABLE_SIZE / sizeof(UInt64)]; +} +CZstdDecHufTable; + +/* +Input: + numSyms != 0 + (bits) array size must be aligned for 2 + if (numSyms & 1), then bits[numSyms] == 0, + Huffman tree must be correct before Huf_Build() call: + (sum (1/2^bits[i]) == 1). + && (bits[i] <= HUF_MAX_BITS) +*/ +static +Z7_FORCE_INLINE +void Huf_Build(Byte * const table, + const Byte *bits, const unsigned numSyms) +{ + unsigned counts0[HUF_MAX_BITS + 1]; + unsigned counts1[HUF_MAX_BITS + 1]; + const Byte * const bitsEnd = bits + numSyms; + // /* + { + unsigned t; + for (t = 0; t < Z7_ARRAY_SIZE(counts0); t++) counts0[t] = 0; + for (t = 0; t < Z7_ARRAY_SIZE(counts1); t++) counts1[t] = 0; + } + // */ + // memset(counts0, 0, sizeof(counts0)); + // memset(counts1, 0, sizeof(counts1)); + { + const Byte *bits2 = bits; + // we access additional bits[symbol] if (numSyms & 1) + do + { + counts0[bits2[0]]++; + counts1[bits2[1]]++; + } + while ((bits2 += 2) < bitsEnd); + } + { + unsigned r = 0; + unsigned i = HUF_MAX_BITS; + // Byte *lens = HUF_GET_LENS(symbols); + do + { + const unsigned num = (counts0[i] + counts1[i]) << (HUF_MAX_BITS - i); + counts0[i] = r; + if (num) + { + Byte *lens = &table[r]; + r += num; + memset(lens, (int)i, num); + } + } + while (--i); + counts0[0] = 0; // for speculated loads + // no need for check: + // if (r != (UInt32)1 << HUF_MAX_BITS) exit(0); + } + { + #ifdef MY_CPU_64BIT + UInt64 + #else + UInt32 + #endif + v = 0; + Byte *symbols = HUF_GET_SYMBOLS(table); + do + { + const unsigned nb = *bits++; + if (nb) + { + const unsigned code = counts0[nb]; + const unsigned num = (1u << HUF_MAX_BITS) >> nb; + counts0[nb] = code + num; + // memset(&symbols[code], i, num); + // /* + { + Byte *s2 = &symbols[code]; + if (num <= 2) + { + s2[0] = (Byte)v; + s2[(size_t)num - 1] = (Byte)v; + } + else if (num <= 8) + { + *(UInt32 *)(void *)s2 = (UInt32)v; + *(UInt32 *)(void *)(s2 + (size_t)num - 4) = (UInt32)v; + } + else + { + #ifdef MY_CPU_64BIT + UInt64 *s = (UInt64 *)(void *)s2; + const UInt64 *lim = (UInt64 *)(void *)(s2 + num); + do + { + s[0] = v; s[1] = v; s += 2; + } + while (s != lim); + #else + UInt32 *s = (UInt32 *)(void *)s2; + const UInt32 *lim = (const UInt32 *)(const void *)(s2 + num); + do + { + s[0] = v; s[1] = v; s += 2; + s[0] = v; s[1] = v; s += 2; + } + while (s != lim); + #endif + } + } + // */ + } + v += + #ifdef MY_CPU_64BIT + 0x0101010101010101; + #else + 0x01010101; + #endif + } + while (bits != bitsEnd); + } +} + + + +// how many bytes (src) was moved back from original value. +// we need (HUF_SRC_OFFSET == 3) for optimized 32-bit memory access +#define HUF_SRC_OFFSET 3 + +// v <<= 8 - (bitOffset & 7) + numBits; +// v >>= 32 - HUF_MAX_BITS; +#define HUF_GET_STATE(v, bitOffset, numBits) \ + GET32(v, src + (HUF_SRC_OFFSET - 3) + ((CBitCtr_signed)bitOffset >> 3)) \ + v >>= 32 - HUF_MAX_BITS - 8 + ((unsigned)bitOffset & 7) - numBits; \ + v &= (1u << HUF_MAX_BITS) - 1; \ + + +#ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS +#if defined(MY_CPU_AMD64) && defined(_MSC_VER) && _MSC_VER == 1400 \ + || !defined(MY_CPU_X86_OR_AMD64) \ + // || 1 == 1 /* for debug : to force STREAM4_PRELOAD mode */ + // we need big number (>=16) of registers for PRELOAD4 + #define Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4 + // #define Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2 // for debug +#endif +#endif + +// for debug: simpler and smaller code but slow: +// #define Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE + +#if defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE) || \ + !defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS) + +#define HUF_DECODE(bitOffset, dest) \ +{ \ + UInt32 v; \ + HUF_GET_STATE(v, bitOffset, 0) \ + bitOffset -= table[v]; \ + *(dest) = symbols[v]; \ + if ((CBitCtr_signed)bitOffset < 0) return SZ_ERROR_DATA; \ +} + +#endif + +#if !defined(Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE) || \ + defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4) || \ + defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2) \ + +#define HUF_DECODE_2_INIT(v, bitOffset) \ + HUF_GET_STATE(v, bitOffset, 0) + +#define HUF_DECODE_2(v, bitOffset, dest) \ +{ \ + unsigned numBits; \ + numBits = table[v]; \ + *(dest) = symbols[v]; \ + HUF_GET_STATE(v, bitOffset, numBits) \ + bitOffset -= (CBitCtr)numBits; \ + if ((CBitCtr_signed)bitOffset < 0) return SZ_ERROR_DATA; \ +} + +#endif + + +// src == ptr - HUF_SRC_OFFSET +// we are allowed to access 3 bytes before start of input buffer +static +Z7_NO_INLINE +SRes Huf_Decompress_1stream(const Byte * const table, + const Byte *src, const size_t srcLen, + Byte *dest, const size_t destLen) +{ + CBitCtr bitOffset; + if (srcLen == 0) + return SZ_ERROR_DATA; + SET_bitOffset_TO_PAD (bitOffset, src + HUF_SRC_OFFSET, srcLen) + if (destLen) + { + const Byte *symbols = HUF_GET_SYMBOLS(table); + const Byte *destLim = dest + destLen; + #ifdef Z7_ZSTD_DEC_USE_HUF_STREAM1_SIMPLE + { + do + { + HUF_DECODE (bitOffset, dest) + } + while (++dest != destLim); + } + #else + { + UInt32 v; + HUF_DECODE_2_INIT (v, bitOffset) + do + { + HUF_DECODE_2 (v, bitOffset, dest) + } + while (++dest != destLim); + } + #endif + } + return bitOffset == 0 ? SZ_OK : SZ_ERROR_DATA; +} + + +// for debug : it reduces register pressure : by array copy can be slow : +// #define Z7_ZSTD_DEC_USE_HUF_LOCAL + +// src == ptr + (6 - HUF_SRC_OFFSET) +// srcLen >= 10 +// we are allowed to access 3 bytes before start of input buffer +static +Z7_NO_INLINE +SRes Huf_Decompress_4stream(const Byte * const + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + table2, + #else + table, + #endif + const Byte *src, size_t srcLen, + Byte *dest, size_t destLen) +{ + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + Byte table[HUF_TABLE_SIZE]; + #endif + UInt32 sizes[3]; + const size_t delta = (destLen + 3) / 4; + if ((sizes[0] = GetUi16(src + (0 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + if ((sizes[1] = GetUi16(src + (2 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + sizes[1] += sizes[0]; + if ((sizes[2] = GetUi16(src + (4 + HUF_SRC_OFFSET - 6))) == 0) return SZ_ERROR_DATA; + sizes[2] += sizes[1]; + srcLen -= 6; + if (srcLen <= sizes[2]) + return SZ_ERROR_DATA; + + #ifdef Z7_ZSTD_DEC_USE_HUF_LOCAL + { + // unsigned i = 0; for(; i < 1000; i++) + memcpy(table, table2, HUF_TABLE_SIZE); + } + #endif + + #ifndef Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + { + CBitCtr bitOffset_0, + bitOffset_1, + bitOffset_2, + bitOffset_3; + { + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_0, src + HUF_SRC_OFFSET, sizes[0]) + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_1, src + HUF_SRC_OFFSET, sizes[1]) + SET_bitOffset_TO_PAD_and_SET_BIT_SIZE (bitOffset_2, src + HUF_SRC_OFFSET, sizes[2]) + SET_bitOffset_TO_PAD (bitOffset_3, src + HUF_SRC_OFFSET, srcLen) + } + { + const Byte * const symbols = HUF_GET_SYMBOLS(table); + Byte *destLim = dest + destLen - delta * 3; + + if (dest != destLim) + #ifdef Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD4 + { + UInt32 v_0, v_1, v_2, v_3; + HUF_DECODE_2_INIT (v_0, bitOffset_0) + HUF_DECODE_2_INIT (v_1, bitOffset_1) + HUF_DECODE_2_INIT (v_2, bitOffset_2) + HUF_DECODE_2_INIT (v_3, bitOffset_3) + // #define HUF_DELTA (1 << 17) / 4 + do + { + HUF_DECODE_2 (v_3, bitOffset_3, dest + delta * 3) + HUF_DECODE_2 (v_2, bitOffset_2, dest + delta * 2) + HUF_DECODE_2 (v_1, bitOffset_1, dest + delta) + HUF_DECODE_2 (v_0, bitOffset_0, dest) + } + while (++dest != destLim); + /* + {// unsigned y = 0; for (;y < 1; y++) + { + const size_t num = destLen - delta * 3; + Byte *orig = dest - num; + memmove (orig + delta , orig + HUF_DELTA, num); + memmove (orig + delta * 2, orig + HUF_DELTA * 2, num); + memmove (orig + delta * 3, orig + HUF_DELTA * 3, num); + }} + */ + } + #elif defined(Z7_ZSTD_DEC_USE_HUF_STREAM4_PRELOAD2) + { + UInt32 v_0, v_1, v_2, v_3; + HUF_DECODE_2_INIT (v_0, bitOffset_0) + HUF_DECODE_2_INIT (v_1, bitOffset_1) + do + { + HUF_DECODE_2 (v_0, bitOffset_0, dest) + HUF_DECODE_2 (v_1, bitOffset_1, dest + delta) + } + while (++dest != destLim); + dest = destLim - (destLen - delta * 3); + dest += delta * 2; + destLim += delta * 2; + HUF_DECODE_2_INIT (v_2, bitOffset_2) + HUF_DECODE_2_INIT (v_3, bitOffset_3) + do + { + HUF_DECODE_2 (v_2, bitOffset_2, dest) + HUF_DECODE_2 (v_3, bitOffset_3, dest + delta) + } + while (++dest != destLim); + dest -= delta * 2; + destLim -= delta * 2; + } + #else + { + do + { + HUF_DECODE (bitOffset_3, dest + delta * 3) + HUF_DECODE (bitOffset_2, dest + delta * 2) + HUF_DECODE (bitOffset_1, dest + delta) + HUF_DECODE (bitOffset_0, dest) + } + while (++dest != destLim); + } + #endif + + if (bitOffset_3 != (CBitCtr)sizes[2]) + return SZ_ERROR_DATA; + if (destLen &= 3) + { + destLim = dest + 4 - destLen; + do + { + HUF_DECODE (bitOffset_2, dest + delta * 2) + HUF_DECODE (bitOffset_1, dest + delta) + HUF_DECODE (bitOffset_0, dest) + } + while (++dest != destLim); + } + if ( bitOffset_0 != 0 + || bitOffset_1 != (CBitCtr)sizes[0] + || bitOffset_2 != (CBitCtr)sizes[1]) + return SZ_ERROR_DATA; + } + } + #else // Z7_ZSTD_DEC_USE_HUF_STREAM1_ALWAYS + { + unsigned i; + for (i = 0; i < 4; i++) + { + size_t d = destLen; + size_t size = srcLen; + if (i != 3) + { + d = delta; + size = sizes[i]; + } + if (i != 0) + size -= sizes[i - 1]; + destLen -= d; + RINOK(Huf_Decompress_1stream(table, src, size, dest, d)) + dest += d; + src += size; + } + } + #endif + + return SZ_OK; +} + + + +// (in->len != 0) +// we are allowed to access in->ptr[-3] +// at least 2 bytes in (in->ptr) will be processed +static SRes Huf_DecodeTable(CZstdDecHufTable *const p, CInBufPair *const in) +{ + Byte weights[HUF_MAX_SYMBS + 1]; // +1 for extra write for loop unroll + unsigned numSyms; + const unsigned header = *(in->ptr)++; + in->len--; + // memset(weights, 0, sizeof(weights)); + if (header >= 128) + { + // direct representation: 4 bits field (0-15) per weight + numSyms = header - 127; + // numSyms != 0 + { + const size_t numBytes = (numSyms + 1) / 2; + const Byte *const ws = in->ptr; + size_t i = 0; + if (in->len < numBytes) + return SZ_ERROR_DATA; + in->ptr += numBytes; + in->len -= numBytes; + do + { + const unsigned b = ws[i]; + weights[i * 2 ] = (Byte)(b >> 4); + weights[i * 2 + 1] = (Byte)(b & 0xf); + } + while (++i != numBytes); + /* 7ZIP: we can restore correct zero value for weights[numSyms], + if we want to use zero values starting from numSyms in code below. */ + // weights[numSyms] = 0; + } + } + else + { + #define MAX_ACCURACY_LOG_FOR_WEIGHTS 6 + CFseRecord table[1 << MAX_ACCURACY_LOG_FOR_WEIGHTS]; + + Byte accuracy; + const Byte *src; + size_t srcLen; + if (in->len < header) + return SZ_ERROR_DATA; + { + CInBufPair fse_stream; + fse_stream.len = header; + fse_stream.ptr = in->ptr; + in->ptr += header; + in->len -= header; + RINOK(FSE_DecodeHeader(table, &fse_stream, + MAX_ACCURACY_LOG_FOR_WEIGHTS, + &accuracy, + 16 // num weight symbols max (max-symbol is 15) + )) + // at least 2 bytes were processed in fse_stream. + // (srcLen > 0) after FSE_DecodeHeader() + // if (srcLen == 0) return SZ_ERROR_DATA; + src = fse_stream.ptr; + srcLen = fse_stream.len; + } + // we are allowed to access src[-5] + { + // unsigned yyy = 200; do { + CBitCtr bitOffset; + FastInt32 state1, state2; + SET_bitOffset_TO_PAD (bitOffset, src, srcLen) + state1 = accuracy; + src -= state1 >> 2; // src -= 1; // for GET16() optimization + state1 <<= FSE_REC_LEN_OFFSET; + state2 = state1; + numSyms = 0; + for (;;) + { + #define FSE_WEIGHT_DECODE(st) \ + { \ + const unsigned bits = GET_FSE_REC_LEN(st); \ + FastInt r; \ + GET16(r, src + (bitOffset >> 3)) \ + r >>= (unsigned)bitOffset & 7; \ + if ((CBitCtr_signed)(bitOffset -= (CBitCtr)bits) < 0) \ + { if (bitOffset + (CBitCtr)bits != 0) \ + return SZ_ERROR_DATA; \ + break; } \ + r &= 0xff; \ + r >>= 8 - bits; \ + st = table[GET_FSE_REC_STATE(st) + r]; \ + weights[numSyms++] = (Byte)GET_FSE_REC_SYM(st); \ + } + FSE_WEIGHT_DECODE (state1) + FSE_WEIGHT_DECODE (state2) + if (numSyms == HUF_MAX_SYMBS) + return SZ_ERROR_DATA; + } + // src += (unsigned)accuracy >> 2; } while (--yyy); + } + } + + // Build using weights: + { + UInt32 sum = 0; + { + // numSyms >= 1 + unsigned i = 0; + weights[numSyms] = 0; + do + { + sum += ((UInt32)1 << weights[i ]) & ~(UInt32)1; + sum += ((UInt32)1 << weights[i + 1]) & ~(UInt32)1; + i += 2; + } + while (i < numSyms); + if (sum == 0) + return SZ_ERROR_DATA; + } + { + const unsigned maxBits = GetHighestSetBit_32_nonzero_big(sum) + 1; + { + const UInt32 left = ((UInt32)1 << maxBits) - sum; + // (left != 0) + // (left) must be power of 2 in correct stream + if (left & (left - 1)) + return SZ_ERROR_DATA; + weights[numSyms++] = (Byte)GetHighestSetBit_32_nonzero_big(left); + } + // if (numSyms & 1) + weights[numSyms] = 0; // for loop unroll + // numSyms >= 2 + { + unsigned i = 0; + do + { + /* + #define WEIGHT_ITER(a) \ + { unsigned w = weights[i + (a)]; \ + const unsigned t = maxBits - w; \ + w = w ? t: w; \ + if (w > HUF_MAX_BITS) return SZ_ERROR_DATA; \ + weights[i + (a)] = (Byte)w; } + */ + // /* + #define WEIGHT_ITER(a) \ + { unsigned w = weights[i + (a)]; \ + if (w) { \ + w = maxBits - w; \ + if (w > HUF_MAX_BITS) return SZ_ERROR_DATA; \ + weights[i + (a)] = (Byte)w; }} + // */ + WEIGHT_ITER(0) + // WEIGHT_ITER(1) + // i += 2; + } + while (++i != numSyms); + } + } + } + { + // unsigned yyy; for (yyy = 0; yyy < 100; yyy++) + Huf_Build((Byte *)(void *)p->table64, weights, numSyms); + } + return SZ_OK; +} + + +typedef enum +{ + k_SeqMode_Predef = 0, + k_SeqMode_RLE = 1, + k_SeqMode_FSE = 2, + k_SeqMode_Repeat = 3 +} +z7_zstd_enum_SeqMode; + +// predefAccuracy == 5 for OFFSET symbols +// predefAccuracy == 6 for MATCH/LIT LEN symbols +static +SRes +Z7_NO_INLINE +// Z7_FORCE_INLINE +FSE_Decode_SeqTable(CFseRecord * const table, + CInBufPair * const in, + unsigned predefAccuracy, + Byte * const accuracyRes, + unsigned numSymbolsMax, + const CFseRecord * const predefs, + const unsigned seqMode) +{ + // UNUSED_VAR(numSymsPredef) + // UNUSED_VAR(predefFreqs) + if (seqMode == k_SeqMode_FSE) + { + // unsigned y = 50; CInBufPair in2 = *in; do { *in = in2; RINOK( + return + FSE_DecodeHeader(table, in, + predefAccuracy + 3, // accuracyMax + accuracyRes, + numSymbolsMax) + ; + // )} while (--y); return SZ_OK; + } + // numSymsMax = numSymsPredef + ((predefAccuracy & 1) * (32 - 29))); // numSymsMax + // numSymsMax == 32 for offsets + + if (seqMode == k_SeqMode_Predef) + { + *accuracyRes = (Byte)predefAccuracy; + memcpy(table, predefs, sizeof(UInt32) << predefAccuracy); + return SZ_OK; + } + + // (seqMode == k_SeqMode_RLE) + if (in->len == 0) + return SZ_ERROR_DATA; + in->len--; + { + const Byte *ptr = in->ptr; + const unsigned sym = ptr[0]; + in->ptr = ptr + 1; + if (sym >= numSymbolsMax) + return SZ_ERROR_DATA; + table[0] = (FastInt32)sym + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + + (numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : 0) + #endif + ; + *accuracyRes = 0; + } + return SZ_OK; +} + + +typedef struct +{ + CFseRecord of[1 << 8]; + CFseRecord ll[1 << 9]; + CFseRecord ml[1 << 9]; +} +CZstdDecFseTables; + + +typedef struct +{ + Byte *win; + SizeT cycSize; + /* + if (outBuf_fromCaller) : cycSize = outBufSize_fromCaller + else { + if ( isCyclicMode) : cycSize = cyclic_buffer_size = (winSize + extra_space) + if (!isCyclicMode) : cycSize = ContentSize, + (isCyclicMode == true) if (ContetSize >= winSize) or ContetSize is unknown + } + */ + SizeT winPos; + + CZstdDecOffset reps[3]; + + Byte ll_accuracy; + Byte of_accuracy; + Byte ml_accuracy; + // Byte seqTables_wereSet; + Byte litHuf_wasSet; + + Byte *literalsBase; + + size_t winSize; // from header + size_t totalOutCheck; // totalOutCheck <= winSize + + #ifdef Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + SEQ_EXTRA_TABLES(m_) + #endif + // UInt64 _pad_Alignment; // is not required now + CZstdDecFseTables fse; + CZstdDecHufTable huf; +} +CZstdDec1; + +#define ZstdDec1_GET_BLOCK_SIZE_LIMIT(p) \ + ((p)->winSize < kBlockSizeMax ? (UInt32)(p)->winSize : kBlockSizeMax) + +#define SEQ_TABLES_WERE_NOT_SET_ml_accuracy 1 // accuracy=1 is not used by zstd +#define IS_SEQ_TABLES_WERE_SET(p) (((p)->ml_accuracy != SEQ_TABLES_WERE_NOT_SET_ml_accuracy)) +// #define IS_SEQ_TABLES_WERE_SET(p) ((p)->seqTables_wereSet) + + +static void ZstdDec1_Construct(CZstdDec1 *p) +{ + #ifdef Z7_ZSTD_DEC_PRINT_TABLE + Print_Predef(6, NUM_LL_SYMBOLS, SEQ_LL_PREDEF_DIST, k_PredefRecords_LL); + Print_Predef(5, NUM_OFFSET_SYMBOLS_PREDEF, SEQ_OFFSET_PREDEF_DIST, k_PredefRecords_OF); + Print_Predef(6, NUM_ML_SYMBOLS, SEQ_ML_PREDEF_DIST, k_PredefRecords_ML); + #endif + + p->win = NULL; + p->cycSize = 0; + p->literalsBase = NULL; + #ifdef Z7_ZSTD_DEC_USE_BASES_IN_OBJECT + FILL_LOC_BASES_ALL + #endif +} + + +static void ZstdDec1_Init(CZstdDec1 *p) +{ + p->reps[0] = 1; + p->reps[1] = 4; + p->reps[2] = 8; + // p->seqTables_wereSet = False; + p->ml_accuracy = SEQ_TABLES_WERE_NOT_SET_ml_accuracy; + p->litHuf_wasSet = False; + p->totalOutCheck = 0; +} + + + +#ifdef MY_CPU_LE_UNALIGN + #define Z7_ZSTD_DEC_USE_UNALIGNED_COPY +#endif + +#ifdef Z7_ZSTD_DEC_USE_UNALIGNED_COPY + + #define COPY_CHUNK_SIZE 16 + + #define COPY_CHUNK_4_2(dest, src) \ + { \ + ((UInt32 *)(void *)dest)[0] = ((const UInt32 *)(const void *)src)[0]; \ + ((UInt32 *)(void *)dest)[1] = ((const UInt32 *)(const void *)src)[1]; \ + src += 4 * 2; \ + dest += 4 * 2; \ + } + + /* sse2 doesn't help here in GCC and CLANG. + so we disabled sse2 here */ + /* + #if defined(MY_CPU_AMD64) + #define Z7_ZSTD_DEC_USE_SSE2 + #elif defined(MY_CPU_X86) + #if defined(_MSC_VER) && _MSC_VER >= 1300 && defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || defined(__SSE2__) \ + // || 1 == 1 // for debug only + #define Z7_ZSTD_DEC_USE_SSE2 + #endif + #endif + */ + + #if defined(MY_CPU_ARM64) + #define COPY_OFFSET_MIN 16 + #define COPY_CHUNK1(dest, src) \ + { \ + vst1q_u8((uint8_t *)(void *)dest, \ + vld1q_u8((const uint8_t *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if ((len -= COPY_CHUNK_SIZE) == 0) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(Z7_ZSTD_DEC_USE_SSE2) + #include // sse2 + #define COPY_OFFSET_MIN 16 + + #define COPY_CHUNK1(dest, src) \ + { \ + _mm_storeu_si128((__m128i *)(void *)dest, \ + _mm_loadu_si128((const __m128i *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if ((len -= COPY_CHUNK_SIZE) == 0) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(MY_CPU_64BIT) + #define COPY_OFFSET_MIN 8 + + #define COPY_CHUNK(dest, src) \ + { \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + ((UInt64 *)(void *)dest)[1] = ((const UInt64 *)(const void *)src)[1]; \ + src += 8 * 2; \ + dest += 8 * 2; \ + } + + #else + #define COPY_OFFSET_MIN 4 + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_4_2(dest, src); \ + COPY_CHUNK_4_2(dest, src); \ + } + + #endif +#endif + + +#ifndef COPY_CHUNK_SIZE + #define COPY_OFFSET_MIN 4 + #define COPY_CHUNK_SIZE 8 + #define COPY_CHUNK_2(dest, src) \ + { \ + const Byte a0 = src[0]; \ + const Byte a1 = src[1]; \ + dest[0] = a0; \ + dest[1] = a1; \ + src += 2; \ + dest += 2; \ + } + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + } +#endif + + +#define COPY_PREPARE \ + len += (COPY_CHUNK_SIZE - 1); \ + len &= ~(size_t)(COPY_CHUNK_SIZE - 1); \ + { if (len > rem) \ + { len = rem; \ + rem &= (COPY_CHUNK_SIZE - 1); \ + if (rem) { \ + len -= rem; \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do *dest++ = *src++; while (--rem); \ + if (len == 0) return; }}} + +#define COPY_CHUNKS \ +{ \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do { COPY_CHUNK(dest, src) } \ + while (len -= COPY_CHUNK_SIZE); \ +} + +// (len != 0) +// (len <= rem) +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyLiterals(Byte *dest, Byte const *src, size_t len, size_t rem) +{ + COPY_PREPARE + COPY_CHUNKS +} + + +/* we can define Z7_STD_DEC_USE_AFTER_CYC_BUF, if we want to use additional + space after cycSize that can be used to reduce the code in CopyMatch(): */ +// for debug: +// #define Z7_STD_DEC_USE_AFTER_CYC_BUF + +/* +CopyMatch() +if wrap (offset > winPos) +{ + then we have at least (COPY_CHUNK_SIZE) avail in (dest) before we will overwrite (src): + (cycSize >= offset + COPY_CHUNK_SIZE) + if defined(Z7_STD_DEC_USE_AFTER_CYC_BUF) + we are allowed to read win[cycSize + COPY_CHUNK_SIZE - 1], +} +(len != 0) +*/ +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch(size_t offset, size_t len, + Byte *win, size_t winPos, size_t rem, const size_t cycSize) +{ + Byte *dest = win + winPos; + const Byte *src; + // STAT_INC(g_NumCopy) + + if (offset > winPos) + { + size_t back = offset - winPos; + // src = win + cycSize - back; + // cycSize -= offset; + STAT_INC(g_NumOver) + src = dest + (cycSize - offset); + // (src >= dest) here + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + if (back < len) + { + #else + if (back < len + (COPY_CHUNK_SIZE - 1)) + { + if (back >= len) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + *dest++ = *src++; + while (--len); + return; + } + #endif + // back < len + STAT_INC(g_NumOver2) + len -= back; + rem -= back; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + *dest++ = *src++; + while (--back); + src = dest - offset; + // src = win; + // we go to MAIN-COPY + } + } + else + src = dest - offset; + + // len != 0 + // do *dest++ = *src++; while (--len); return; + + // --- MAIN COPY --- + // if (src >= dest), then ((size_t)(src - dest) >= COPY_CHUNK_SIZE) + // so we have at least COPY_CHUNK_SIZE space before overlap for writing. + COPY_PREPARE + + /* now (len == COPY_CHUNK_SIZE * x) + so we can unroll for aligned copy */ + { + // const unsigned b0 = src[0]; + // (COPY_OFFSET_MIN >= 4) + + if (offset >= COPY_OFFSET_MIN) + { + COPY_CHUNKS + // return; + } + else + #if (COPY_OFFSET_MIN > 4) + #if COPY_CHUNK_SIZE < 8 + #error Stop_Compiling_Bad_COPY_CHUNK_SIZE + #endif + if (offset >= 4) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + COPY_CHUNK_4_2(dest, src) + #if COPY_CHUNK_SIZE != 16 + if (len == 8) break; + #endif + COPY_CHUNK_4_2(dest, src) + } + while (len -= 16); + // return; + } + else + #endif + { + // (offset < 4) + const unsigned b0 = src[0]; + if (offset < 2) + { + #if defined(Z7_ZSTD_DEC_USE_UNALIGNED_COPY) && (COPY_CHUNK_SIZE == 16) + #if defined(MY_CPU_64BIT) + { + const UInt64 v64 = (UInt64)b0 * 0x0101010101010101; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + ((UInt64 *)(void *)dest)[0] = v64; + ((UInt64 *)(void *)dest)[1] = v64; + dest += 16; + } + while (len -= 16); + } + #else + { + UInt32 v = b0; + v |= v << 8; + v |= v << 16; + do + { + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + } + while (len -= 16); + } + #endif + #else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + } + while (len -= 4); + #endif + } + else if (offset == 2) + { + const Byte b1 = src[1]; + { + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest += 2; + } + while (len -= 2); + } + } + else // (offset == 3) + { + const Byte *lim = dest + len - 2; + const Byte b1 = src[1]; + const Byte b2 = src[2]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest[2] = b2; + dest += 3; + } + while (dest < lim); + lim++; // points to last byte that must be written + if (dest <= lim) + { + *dest = (Byte)b0; + if (dest != lim) + dest[1] = b1; + } + } + } + } +} + + + +#define UPDATE_TOTAL_OUT(p, size) \ +{ \ + size_t _toc = (p)->totalOutCheck + (size); \ + const size_t _ws = (p)->winSize; \ + if (_toc >= _ws) _toc = _ws; \ + (p)->totalOutCheck = _toc; \ +} + + +#if defined(MY_CPU_64BIT) && defined(MY_CPU_LE_UNALIGN) +// we can disable it for debug: +#define Z7_ZSTD_DEC_USE_64BIT_LOADS +#endif +// #define Z7_ZSTD_DEC_USE_64BIT_LOADS // for debug : slow in 32-bit + +// SEQ_SRC_OFFSET: how many bytes (src) (seqSrc) was moved back from original value. +// we need (SEQ_SRC_OFFSET != 0) for optimized memory access +#ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define SEQ_SRC_OFFSET 7 +#else + #define SEQ_SRC_OFFSET 3 +#endif +#define SRC_PLUS_FOR_4BYTES(bitOffset) (SEQ_SRC_OFFSET - 3) + ((CBitCtr_signed)(bitOffset) >> 3) +#define BIT_OFFSET_7BITS(bitOffset) ((unsigned)(bitOffset) & 7) +/* + if (BIT_OFFSET_DELTA_BITS == 0) : bitOffset == number_of_unprocessed_bits + if (BIT_OFFSET_DELTA_BITS == 1) : bitOffset == number_of_unprocessed_bits - 1 + and we can read 1 bit more in that mode : (8 * n + 1). +*/ +// #define BIT_OFFSET_DELTA_BITS 0 +#define BIT_OFFSET_DELTA_BITS 1 +#if BIT_OFFSET_DELTA_BITS == 1 + #define GET_SHIFT_FROM_BOFFS7(boff7) (7 ^ (boff7)) +#else + #define GET_SHIFT_FROM_BOFFS7(boff7) (8 - BIT_OFFSET_DELTA_BITS - (boff7)) +#endif + +#define UPDATE_BIT_OFFSET(bitOffset, numBits) \ + (bitOffset) -= (CBitCtr)(numBits); + +#define GET_SHIFT(bitOffset) GET_SHIFT_FROM_BOFFS7(BIT_OFFSET_7BITS(bitOffset)) + + +#if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) + #if (NUM_OFFSET_SYMBOLS_MAX - BIT_OFFSET_DELTA_BITS < 32) + /* if (NUM_OFFSET_SYMBOLS_MAX == 32 && BIT_OFFSET_DELTA_BITS == 1), + we have depth 31 + 9 + 9 + 8 = 57 bits that can b read with single read. */ + #define Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + #endif + #ifndef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + #if (BIT_OFFSET_DELTA_BITS == 1) + /* if (winLimit - winPos <= (kBlockSizeMax = (1 << 17))) + { + the case (16 bits literal extra + 16 match extra) is not possible + in correct stream. So error will be detected for (16 + 16) case. + And longest correct sequence after offset reading is (31 + 9 + 9 + 8 = 57 bits). + So we can use just one 64-bit load here in that case. + } + */ + #define Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML + #endif + #endif +#endif + + +#if !defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) || \ + (!defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML)) +// in : (0 < bits <= (24 or 25)): +#define STREAM_READ_BITS(dest, bits) \ +{ \ + GET32(dest, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + dest <<= GET_SHIFT(bitOffset); \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + dest >>= 32 - bits; \ +} +#endif + + +#define FSE_Peek_1(table, state) table[state] + +#define STATE_VAR(name) state_ ## name + +// in : (0 <= accuracy <= (24 or 25)) +#define FSE_INIT_STATE(name, cond) \ +{ \ + UInt32 r; \ + const unsigned bits = p->name ## _accuracy; \ + GET32(r, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + r <<= GET_SHIFT(bitOffset); \ + r >>= 1; \ + r >>= 31 ^ bits; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + STATE_VAR(name) = FSE_Peek_1(FSE_TABLE(name), r); \ + /* STATE_VAR(name) = dest << 16; */ \ +} + + +#define FSE_Peek_Plus(name, r) \ + STATE_VAR(name) = FSE_Peek_1(FSE_TABLE(name), \ + GET_FSE_REC_STATE(STATE_VAR(name)) + r); + +#define LZ_LOOP_ERROR_EXIT { return SZ_ERROR_DATA; } + +#define BO_OVERFLOW_CHECK \ + { if ((CBitCtr_signed)bitOffset < 0) LZ_LOOP_ERROR_EXIT } + + +#ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + +#define GET64(dest, p) { const Byte *ptr = p; dest = GetUi64(ptr); } + +#define FSE_PRELOAD \ +{ \ + GET64(v, src - 4 + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + v <<= GET_SHIFT(bitOffset); \ +} + +#define FSE_UPDATE_STATE_2(name, cond) \ +{ \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + UInt64 r = v; \ + v <<= bits; \ + r >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + r >>= 63 ^ bits; \ + FSE_Peek_Plus(name, r); \ +} + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_2 (ll, {} ) \ + FSE_UPDATE_STATE_2 (ml, {} ) \ + FSE_UPDATE_STATE_2 (of, BO_OVERFLOW_CHECK) \ + +#else // Z7_ZSTD_DEC_USE_64BIT_LOADS + +// it supports 8 bits accuracy for any code +// it supports 9 bits accuracy, if (BIT_OFFSET_DELTA_BITS == 1) +#define FSE_UPDATE_STATE_0(name, cond) \ +{ \ + UInt32 r; \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + GET16(r, src + 2 + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + r >>= (bitOffset & 7); \ + r &= (1 << (8 + BIT_OFFSET_DELTA_BITS)) - 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + cond \ + r >>= (8 + BIT_OFFSET_DELTA_BITS) - bits; \ + FSE_Peek_Plus(name, r); \ +} + +// for debug (slow): +// #define Z7_ZSTD_DEC_USE_FSE_FUSION_FORCE +#if BIT_OFFSET_DELTA_BITS == 0 || defined(Z7_ZSTD_DEC_USE_FSE_FUSION_FORCE) + #define Z7_ZSTD_DEC_USE_FSE_FUSION +#endif + +#ifdef Z7_ZSTD_DEC_USE_FSE_FUSION +#define FSE_UPDATE_STATE_1(name) \ +{ UInt32 rest2; \ +{ \ + UInt32 r; \ + unsigned bits; \ + GET32(r, src + SRC_PLUS_FOR_4BYTES(bitOffset)) \ + bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + r <<= GET_SHIFT(bitOffset); \ + rest2 = r << bits; \ + r >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + r >>= 31 ^ bits; \ + FSE_Peek_Plus(name, r); \ +} + +#define FSE_UPDATE_STATE_3(name) \ +{ \ + const unsigned bits = GET_FSE_REC_LEN(STATE_VAR(name)); \ + rest2 >>= 1; \ + UPDATE_BIT_OFFSET(bitOffset, bits) \ + rest2 >>= 31 ^ bits; \ + FSE_Peek_Plus(name, rest2); \ +}} + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_1 (ll) \ + FSE_UPDATE_STATE_3 (ml) \ + FSE_UPDATE_STATE_0 (of, BO_OVERFLOW_CHECK) \ + +#else // Z7_ZSTD_DEC_USE_64BIT_LOADS + +#define FSE_UPDATE_STATES \ + FSE_UPDATE_STATE_0 (ll, {} ) \ + FSE_UPDATE_STATE_0 (ml, {} ) \ + FSE_UPDATE_STATE_0 (of, BO_OVERFLOW_CHECK) \ + +#endif // Z7_ZSTD_DEC_USE_FSE_FUSION +#endif // Z7_ZSTD_DEC_USE_64BIT_LOADS + + + +typedef struct +{ + UInt32 numSeqs; + UInt32 literalsLen; + const Byte *literals; +} +CZstdDec1_Vars; + + +// if (BIT_OFFSET_DELTA_BITS != 0), we need (BIT_OFFSET_DELTA_BYTES > 0) +#define BIT_OFFSET_DELTA_BYTES BIT_OFFSET_DELTA_BITS + +/* if (NUM_OFFSET_SYMBOLS_MAX == 32) + max_seq_bit_length = (31) + 16 + 16 + 9 + 8 + 9 = 89 bits + if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) we have longest backward + lookahead offset, and we read UInt64 after literal_len reading. + if (BIT_OFFSET_DELTA_BITS == 1 && NUM_OFFSET_SYMBOLS_MAX == 32) + MAX_BACKWARD_DEPTH = 16 bytes +*/ +#define MAX_BACKWARD_DEPTH \ + ((NUM_OFFSET_SYMBOLS_MAX - 1 + 16 + 16 + 7) / 8 + 7 + BIT_OFFSET_DELTA_BYTES) + +/* srcLen != 0 + src == real_data_ptr - SEQ_SRC_OFFSET - BIT_OFFSET_DELTA_BYTES + if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) then + (winLimit - p->winPos <= (1 << 17)) is required +*/ +static +Z7_NO_INLINE +// Z7_ATTRIB_NO_VECTOR +SRes Decompress_Sequences(CZstdDec1 * const p, + const Byte *src, const size_t srcLen, + const size_t winLimit, + const CZstdDec1_Vars * const vars) +{ +#ifdef Z7_ZSTD_DEC_USE_BASES_LOCAL + SEQ_EXTRA_TABLES(a_) +#endif + + // for debug: + // #define Z7_ZSTD_DEC_USE_LOCAL_FSE_TABLES +#ifdef Z7_ZSTD_DEC_USE_LOCAL_FSE_TABLES + #define FSE_TABLE(n) fse. n + const CZstdDecFseTables fse = p->fse; + /* + CZstdDecFseTables fse; + #define COPY_FSE_TABLE(n) \ + memcpy(fse. n, p->fse. n, (size_t)4 << p-> n ## _accuracy); + COPY_FSE_TABLE(of) + COPY_FSE_TABLE(ll) + COPY_FSE_TABLE(ml) + */ +#else + #define FSE_TABLE(n) (p->fse. n) +#endif + +#ifdef Z7_ZSTD_DEC_USE_BASES_LOCAL + FILL_LOC_BASES_ALL +#endif + + { + unsigned numSeqs = vars->numSeqs; + const Byte *literals = vars->literals; + ptrdiff_t literalsLen = (ptrdiff_t)vars->literalsLen; + Byte * const win = p->win; + size_t winPos = p->winPos; + const size_t cycSize = p->cycSize; + size_t totalOutCheck = p->totalOutCheck; + const size_t winSize = p->winSize; + size_t reps_0 = p->reps[0]; + size_t reps_1 = p->reps[1]; + size_t reps_2 = p->reps[2]; + UInt32 STATE_VAR(ll), STATE_VAR(of), STATE_VAR(ml); + CBitCtr bitOffset; + + SET_bitOffset_TO_PAD (bitOffset, src + SEQ_SRC_OFFSET, srcLen + BIT_OFFSET_DELTA_BYTES) + + bitOffset -= BIT_OFFSET_DELTA_BITS; + + FSE_INIT_STATE(ll, {} ) + FSE_INIT_STATE(of, {} ) + FSE_INIT_STATE(ml, BO_OVERFLOW_CHECK) + + for (;;) + { + size_t matchLen; + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + UInt64 v; + #endif + + #ifdef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF + FSE_PRELOAD + #endif + + // if (of_code == 0) + if ((Byte)STATE_VAR(of) == 0) + { + if (GET_FSE_REC_SYM(STATE_VAR(ll)) == 0) + { + const size_t offset = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep1) + } + STAT_UPDATE(else g_Num_Rep0++;) + } + else + { + const unsigned of_code = (Byte)STATE_VAR(of); + + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #if !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #endif + #else + UInt32 v; + { + const Byte *src4 = src + SRC_PLUS_FOR_4BYTES(bitOffset); + const unsigned skip = GET_SHIFT(bitOffset); + GET32(v, src4) + v <<= skip; + v |= (UInt32)src4[-1] >> (8 - skip); + } + #endif + + UPDATE_BIT_OFFSET(bitOffset, of_code) + + if (of_code == 1) + { + // read 1 bit + #if defined(Z7_MSC_VER_ORIGINAL) || defined(MY_CPU_X86_OR_AMD64) + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define CHECK_HIGH_BIT_64(a) ((Int64)(UInt64)(a) < 0) + #else + #define CHECK_HIGH_BIT_32(a) ((Int32)(UInt32)(a) < 0) + #endif + #else + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + #define CHECK_HIGH_BIT_64(a) ((UInt64)(a) & ((UInt64)1 << 63)) + #else + #define CHECK_HIGH_BIT_32(a) ((UInt32)(a) & ((UInt32)1 << 31)) + #endif + #endif + + if + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + CHECK_HIGH_BIT_64 (((UInt64)GET_FSE_REC_SYM(STATE_VAR(ll)) - 1) ^ v) + #else + CHECK_HIGH_BIT_32 (((UInt32)GET_FSE_REC_SYM(STATE_VAR(ll)) - 1) ^ v) + #endif + { + v <<= 1; + { + const size_t offset = reps_2; + reps_2 = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep2) + } + } + else + { + if (GET_FSE_REC_SYM(STATE_VAR(ll)) == 0) + { + // litLen == 0 && bit == 1 + STAT_INC(g_Num_Rep3) + v <<= 1; + reps_2 = reps_1; + reps_1 = reps_0; + if (--reps_0 == 0) + { + // LZ_LOOP_ERROR_EXIT + // original-zstd decoder : input is corrupted; force offset to 1 + // reps_0 = 1; + reps_0++; + } + } + else + { + // litLen != 0 && bit == 0 + v <<= 1; + { + const size_t offset = reps_1; + reps_1 = reps_0; + reps_0 = offset; + STAT_INC(g_Num_Rep1) + } + } + } + } + else + { + // (2 <= of_code) + // if (of_code >= 32) LZ_LOOP_ERROR_EXIT // optional check + // we don't allow (of_code >= 32) cases in another code + reps_2 = reps_1; + reps_1 = reps_0; + reps_0 = ((size_t)1 << of_code) - 3 + (size_t) + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + (v >> (64 - of_code)); + v <<= of_code; + #else + (v >> (32 - of_code)); + #endif + } + } + + #ifdef Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML + FSE_PRELOAD + #endif + + matchLen = (size_t)GET_FSE_REC_SYM(STATE_VAR(ml)) + #ifndef Z7_ZSTD_DEC_USE_ML_PLUS3 + + MATCH_LEN_MIN + #endif + ; + { + { + if (matchLen >= 32 + MATCH_LEN_MIN) // if (state_ml & 0x20) + { + const unsigned extra = BASES_TABLE(SEQ_ML_EXTRA) [(size_t)matchLen - MATCH_LEN_MIN]; + matchLen = BASES_TABLE(SEQ_ML_BASES) [(size_t)matchLen - MATCH_LEN_MIN]; + #if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) && \ + (defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) || \ + defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF)) + { + UPDATE_BIT_OFFSET(bitOffset, extra) + matchLen += (size_t)(v >> (64 - extra)); + #if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #else + v <<= extra; + #endif + } + #else + { + UInt32 v32; + STREAM_READ_BITS(v32, extra) + matchLen += v32; + } + #endif + STAT_INC(g_Num_Match) + } + } + } + + #if defined(Z7_ZSTD_DEC_USE_64BIT_LOADS) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) && \ + !defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_ML) + FSE_PRELOAD + #endif + + { + size_t litLen = GET_FSE_REC_SYM(STATE_VAR(ll)); + if (litLen) + { + // if (STATE_VAR(ll) & 0x70) + if (litLen >= 16) + { + const unsigned extra = BASES_TABLE(SEQ_LL_EXTRA) [litLen]; + litLen = BASES_TABLE(SEQ_LL_BASES) [litLen]; + #ifdef Z7_ZSTD_DEC_USE_64BIT_LOADS + { + UPDATE_BIT_OFFSET(bitOffset, extra) + litLen += (size_t)(v >> (64 - extra)); + #if defined(Z7_ZSTD_DEC_USE_64BIT_PRELOAD_OF) + FSE_PRELOAD + #else + v <<= extra; + #endif + } + #else + { + UInt32 v32; + STREAM_READ_BITS(v32, extra) + litLen += v32; + } + #endif + STAT_INC(g_Num_LitsBig) + } + + if ((literalsLen -= (ptrdiff_t)litLen) < 0) + LZ_LOOP_ERROR_EXIT + totalOutCheck += litLen; + { + const size_t rem = winLimit - winPos; + if (litLen > rem) + LZ_LOOP_ERROR_EXIT + { + const Byte *literals_temp = literals; + Byte *d = win + winPos; + literals += litLen; + winPos += litLen; + CopyLiterals(d, literals_temp, litLen, rem); + } + } + } + STAT_UPDATE(else g_Num_Lit0++;) + } + + #define COPY_MATCH \ + { if (reps_0 > winSize || reps_0 > totalOutCheck) LZ_LOOP_ERROR_EXIT \ + totalOutCheck += matchLen; \ + { const size_t rem = winLimit - winPos; \ + if (matchLen > rem) LZ_LOOP_ERROR_EXIT \ + { const size_t winPos_temp = winPos; \ + winPos += matchLen; \ + CopyMatch(reps_0, matchLen, win, winPos_temp, rem, cycSize); }}} + + if (--numSeqs == 0) + { + COPY_MATCH + break; + } + FSE_UPDATE_STATES + COPY_MATCH + } // for + + if ((CBitCtr_signed)bitOffset != BIT_OFFSET_DELTA_BYTES * 8 - BIT_OFFSET_DELTA_BITS) + return SZ_ERROR_DATA; + + if (literalsLen) + { + const size_t rem = winLimit - winPos; + if ((size_t)literalsLen > rem) + return SZ_ERROR_DATA; + { + Byte *d = win + winPos; + winPos += (size_t)literalsLen; + totalOutCheck += (size_t)literalsLen; + CopyLiterals + // memcpy + (d, literals, (size_t)literalsLen, rem); + } + } + if (totalOutCheck >= winSize) + totalOutCheck = winSize; + p->totalOutCheck = totalOutCheck; + p->winPos = winPos; + p->reps[0] = (CZstdDecOffset)reps_0; + p->reps[1] = (CZstdDecOffset)reps_1; + p->reps[2] = (CZstdDecOffset)reps_2; + } + return SZ_OK; +} + + +// for debug: define to check that ZstdDec1_NeedTempBufferForInput() works correctly: +// #define Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP // define it for debug only +#ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP +static unsigned g_numSeqs; +#endif + + +#define k_LitBlockType_Flag_RLE_or_Treeless 1 +#define k_LitBlockType_Flag_Compressed 2 + +// outLimit : is strong limit +// outLimit <= ZstdDec1_GET_BLOCK_SIZE_LIMIT(p) +// inSize != 0 +static +Z7_NO_INLINE +SRes ZstdDec1_DecodeBlock(CZstdDec1 *p, + const Byte *src, SizeT inSize, SizeT afterAvail, + const size_t outLimit) +{ + CZstdDec1_Vars vars; + vars.literals = p->literalsBase; + { + const unsigned b0 = *src++; + UInt32 numLits, compressedSize; + const Byte *litStream; + Byte *literalsDest; + inSize--; + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + // we need at least one additional byte for (numSeqs). + // so we check for that additional byte in conditions. + numLits = b0 >> 3; + if (b0 & 4) + { + UInt32 v; + if (inSize < 1 + 1) // we need at least 1 byte here and 1 byte for (numSeqs). + return SZ_ERROR_DATA; + numLits >>= 1; + v = GetUi16(src); + src += 2; + inSize -= 2; + if ((b0 & 8) == 0) + { + src--; + inSize++; + v = (Byte)v; + } + numLits += v << 4; + } + compressedSize = 1; + if ((b0 & k_LitBlockType_Flag_RLE_or_Treeless) == 0) + compressedSize = numLits; + } + else if (inSize < 4) + return SZ_ERROR_DATA; + else + { + const unsigned mode4Streams = b0 & 0xc; + const unsigned numBytes = (3 * mode4Streams + 32) >> 4; + const unsigned numBits = 4 * numBytes - 2; + const UInt32 mask = ((UInt32)16 << numBits) - 1; + compressedSize = GetUi32(src); + numLits = (( + #ifdef MY_CPU_LE_UNALIGN + GetUi32(src - 1) + #else + ((compressedSize << 8) + b0) + #endif + ) >> 4) & mask; + src += numBytes; + inSize -= numBytes; + compressedSize >>= numBits; + compressedSize &= mask; + /* + if (numLits != 0) printf("inSize = %7u num_lits=%7u compressed=%7u ratio = %u ratio2 = %u\n", + i1, numLits, (unsigned)compressedSize * 1, (unsigned)compressedSize * 100 / numLits, + (unsigned)numLits * 100 / (unsigned)inSize); + } + */ + if (compressedSize == 0) + return SZ_ERROR_DATA; // (compressedSize == 0) is not allowed + } + + STAT_UPDATE(g_Num_Lits += numLits;) + + vars.literalsLen = numLits; + + if (compressedSize >= inSize) + return SZ_ERROR_DATA; + litStream = src; + src += compressedSize; + inSize -= compressedSize; + // inSize != 0 + { + UInt32 numSeqs = *src++; + inSize--; + if (numSeqs > 127) + { + UInt32 b1; + if (inSize == 0) + return SZ_ERROR_DATA; + numSeqs -= 128; + b1 = *src++; + inSize--; + if (numSeqs == 127) + { + if (inSize == 0) + return SZ_ERROR_DATA; + numSeqs = (UInt32)(*src++) + 127; + inSize--; + } + numSeqs = (numSeqs << 8) + b1; + } + if (numSeqs * MATCH_LEN_MIN + numLits > outLimit) + return SZ_ERROR_DATA; + vars.numSeqs = numSeqs; + + STAT_UPDATE(g_NumSeqs_total += numSeqs;) + /* + #ifdef SHOW_STAT + printf("\n %5u : %8u, %8u : %5u", (int)g_Num_Blocks_Compressed, (int)numSeqs, (int)g_NumSeqs_total, + (int)g_NumSeqs_total / g_Num_Blocks_Compressed); + #endif + // printf("\nnumSeqs2 = %d", numSeqs); + */ + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + if (numSeqs != g_numSeqs) return SZ_ERROR_DATA; // for debug + #endif + if (numSeqs == 0) + { + if (inSize != 0) + return SZ_ERROR_DATA; + literalsDest = p->win + p->winPos; + } + else + literalsDest = p->literalsBase; + } + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + if (b0 & k_LitBlockType_Flag_RLE_or_Treeless) + { + memset(literalsDest, litStream[0], numLits); + if (vars.numSeqs) + { + // literalsDest == p->literalsBase == vars.literals + #if COPY_CHUNK_SIZE > 1 + memset(p->literalsBase + numLits, 0, COPY_CHUNK_SIZE); + #endif + } + } + else + { + // unsigned y; + // for (y = 0; y < 10000; y++) + memcpy(literalsDest, litStream, numLits); + if (vars.numSeqs) + { + /* we need up to (15 == COPY_CHUNK_SIZE - 1) space for optimized CopyLiterals(). + If we have additional space in input stream after literals stream, + we use direct copy of rar literals in input stream */ + if ((size_t)(src + inSize - litStream) - numLits + afterAvail >= (COPY_CHUNK_SIZE - 1)) + vars.literals = litStream; + else + { + // literalsDest == p->literalsBase == vars.literals + #if COPY_CHUNK_SIZE > 1 + /* CopyLiterals(): + 1) we don't want reading non-initialized data + 2) we will copy only zero byte after literals buffer */ + memset(p->literalsBase + numLits, 0, COPY_CHUNK_SIZE); + #endif + } + } + } + } + else + { + CInBufPair hufStream; + hufStream.ptr = litStream; + hufStream.len = compressedSize; + + if ((b0 & k_LitBlockType_Flag_RLE_or_Treeless) == 0) + { + // unsigned y = 100; CInBufPair hs2 = hufStream; do { hufStream = hs2; + RINOK(Huf_DecodeTable(&p->huf, &hufStream)) + p->litHuf_wasSet = True; + // } while (--y); + } + else if (!p->litHuf_wasSet) + return SZ_ERROR_DATA; + + { + // int yyy; for (yyy = 0; yyy < 34; yyy++) { + SRes sres; + if ((b0 & 0xc) == 0) // mode4Streams + sres = Huf_Decompress_1stream((const Byte *)(const void *)p->huf.table64, + hufStream.ptr - HUF_SRC_OFFSET, hufStream.len, literalsDest, numLits); + else + { + // 6 bytes for the jump table + 4x1 bytes of end-padding Bytes) + if (hufStream.len < 6 + 4) + return SZ_ERROR_DATA; + // the condition from original-zstd decoder: + #define Z7_ZSTD_MIN_LITERALS_FOR_4_STREAMS 6 + if (numLits < Z7_ZSTD_MIN_LITERALS_FOR_4_STREAMS) + return SZ_ERROR_DATA; + sres = Huf_Decompress_4stream((const Byte *)(const void *)p->huf.table64, + hufStream.ptr + (6 - HUF_SRC_OFFSET), hufStream.len, literalsDest, numLits); + } + RINOK(sres) + // } + } + } + + if (vars.numSeqs == 0) + { + p->winPos += numLits; + UPDATE_TOTAL_OUT(p, numLits) + return SZ_OK; + } + } + { + CInBufPair in; + unsigned mode; + unsigned seqMode; + + in.ptr = src; + in.len = inSize; + if (in.len == 0) + return SZ_ERROR_DATA; + in.len--; + mode = *in.ptr++; + if (mode & 3) // Reserved bits + return SZ_ERROR_DATA; + + seqMode = (mode >> 6); + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else RINOK(FSE_Decode_SeqTable( + p->fse.ll, + &in, + 6, // predefAccuracy + &p->ll_accuracy, + NUM_LL_SYMBOLS, + k_PredefRecords_LL, + seqMode)) + + seqMode = (mode >> 4) & 3; + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else RINOK(FSE_Decode_SeqTable( + p->fse.of, + &in, + 5, // predefAccuracy + &p->of_accuracy, + NUM_OFFSET_SYMBOLS_MAX, + k_PredefRecords_OF, + seqMode)) + + seqMode = (mode >> 2) & 3; + if (seqMode == k_SeqMode_Repeat) + { if (!IS_SEQ_TABLES_WERE_SET(p)) return SZ_ERROR_DATA; } + else + { + RINOK(FSE_Decode_SeqTable( + p->fse.ml, + &in, + 6, // predefAccuracy + &p->ml_accuracy, + NUM_ML_SYMBOLS, + k_PredefRecords_ML, + seqMode)) + /* + #if defined(Z7_ZSTD_DEC_USE_ML_PLUS3) + // { unsigned y = 1 << 10; do + { + const unsigned accuracy = p->ml_accuracy; + if (accuracy == 0) + p->fse.ml[0] += 3; + else + #ifdef MY_CPU_64BIT + { + // alignemt (UInt64 _pad_Alignment) in fse.ml is required for that code + UInt64 *table = (UInt64 *)(void *)p->fse.ml; + const UInt64 *end = (const UInt64 *)(const void *) + ((const Byte *)(const void *)table + ((size_t)sizeof(CFseRecord) << accuracy)); + do + { + table[0] += ((UInt64)MATCH_LEN_MIN << 32) + MATCH_LEN_MIN; + table[1] += ((UInt64)MATCH_LEN_MIN << 32) + MATCH_LEN_MIN; + table += 2; + } + while (table != end); + } + #else + { + UInt32 *table = p->fse.ml; + const UInt32 *end = (const UInt32 *)(const void *) + ((const Byte *)(const void *)table + ((size_t)sizeof(CFseRecord) << accuracy)); + do + { + table[0] += MATCH_LEN_MIN; + table[1] += MATCH_LEN_MIN; + table += 2; + table[0] += MATCH_LEN_MIN; + table[1] += MATCH_LEN_MIN; + table += 2; + } + while (table != end); + } + #endif + } + // while (--y); } + #endif + */ + } + + // p->seqTables_wereSet = True; + if (in.len == 0) + return SZ_ERROR_DATA; + return Decompress_Sequences(p, + in.ptr - SEQ_SRC_OFFSET - BIT_OFFSET_DELTA_BYTES, in.len, + p->winPos + outLimit, &vars); + } +} + + + + +// inSize != 0 +// it must do similar to ZstdDec1_DecodeBlock() +static size_t ZstdDec1_NeedTempBufferForInput( + const SizeT beforeSize, const Byte * const src, const SizeT inSize) +{ + unsigned b0; + UInt32 pos; + + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + g_numSeqs = 1 << 24; + #else + // we have at least 3 bytes before seq data: litBlockType, numSeqs, seqMode + #define MIN_BLOCK_LZ_HEADERS_SIZE 3 + if (beforeSize >= MAX_BACKWARD_DEPTH - MIN_BLOCK_LZ_HEADERS_SIZE) + return 0; + #endif + + b0 = src[0]; + + if ((b0 & k_LitBlockType_Flag_Compressed) == 0) + { + UInt32 numLits = b0 >> 3; + pos = 1; + if (b0 & 4) + { + UInt32 v; + if (inSize < 3) + return 0; + numLits >>= 1; + v = GetUi16(src + 1); + pos = 3; + if ((b0 & 8) == 0) + { + pos = 2; + v = (Byte)v; + } + numLits += v << 4; + } + if (b0 & k_LitBlockType_Flag_RLE_or_Treeless) + numLits = 1; + pos += numLits; + } + else if (inSize < 5) + return 0; + else + { + const unsigned mode4Streams = b0 & 0xc; + const unsigned numBytes = (3 * mode4Streams + 48) >> 4; + const unsigned numBits = 4 * numBytes - 6; + UInt32 cs = GetUi32(src + 1); + cs >>= numBits; + cs &= ((UInt32)16 << numBits) - 1; + if (cs == 0) + return 0; + pos = numBytes + cs; + } + + if (pos >= inSize) + return 0; + { + UInt32 numSeqs = src[pos++]; + if (numSeqs > 127) + { + UInt32 b1; + if (pos >= inSize) + return 0; + numSeqs -= 128; + b1 = src[pos++]; + if (numSeqs == 127) + { + if (pos >= inSize) + return 0; + numSeqs = (UInt32)(src[pos++]) + 127; + } + numSeqs = (numSeqs << 8) + b1; + } + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + g_numSeqs = numSeqs; // for debug + #endif + if (numSeqs == 0) + return 0; + } + /* + if (pos >= inSize) + return 0; + pos++; + */ + // we will have one additional byte for seqMode: + if (beforeSize + pos >= MAX_BACKWARD_DEPTH - 1) + return 0; + return 1; +} + + + +// ---------- ZSTD FRAME ---------- + +#define kBlockType_Raw 0 +#define kBlockType_RLE 1 +#define kBlockType_Compressed 2 +#define kBlockType_Reserved 3 + +typedef enum +{ + // begin: states that require 4 bytes: + ZSTD2_STATE_SIGNATURE, + ZSTD2_STATE_HASH, + ZSTD2_STATE_SKIP_HEADER, + // end of states that require 4 bytes + + ZSTD2_STATE_SKIP_DATA, + ZSTD2_STATE_FRAME_HEADER, + ZSTD2_STATE_AFTER_HEADER, + ZSTD2_STATE_BLOCK, + ZSTD2_STATE_DATA, + ZSTD2_STATE_FINISHED +} EZstd2State; + + +struct CZstdDec +{ + EZstd2State frameState; + unsigned tempSize; + + Byte temp[14]; // 14 is required + + Byte descriptor; + Byte windowDescriptor; + Byte isLastBlock; + Byte blockType; + Byte isErrorState; + Byte hashError; + Byte disableHash; + Byte isCyclicMode; + + UInt32 blockSize; + UInt32 dictionaryId; + UInt32 curBlockUnpackRem; // for compressed blocks only + UInt32 inTempPos; + + UInt64 contentSize; + UInt64 contentProcessed; + CXxh64State xxh64; + + Byte *inTemp; + SizeT winBufSize_Allocated; + Byte *win_Base; + + ISzAllocPtr alloc_Small; + ISzAllocPtr alloc_Big; + + CZstdDec1 decoder; +}; + +#define ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p) \ + ((unsigned)(p)->contentProcessed & (Z7_XXH64_BLOCK_SIZE - 1)) + +#define ZSTD_DEC_IS_LAST_BLOCK(p) ((p)->isLastBlock) + + +static void ZstdDec_FreeWindow(CZstdDec * const p) +{ + if (p->win_Base) + { + ISzAlloc_Free(p->alloc_Big, p->win_Base); + p->win_Base = NULL; + // p->decoder.win = NULL; + p->winBufSize_Allocated = 0; + } +} + + +CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big) +{ + CZstdDec *p = (CZstdDec *)ISzAlloc_Alloc(alloc_Small, sizeof(CZstdDec)); + if (!p) + return NULL; + p->alloc_Small = alloc_Small; + p->alloc_Big = alloc_Big; + // ZstdDec_CONSTRUCT(p) + p->inTemp = NULL; + p->win_Base = NULL; + p->winBufSize_Allocated = 0; + p->disableHash = False; + ZstdDec1_Construct(&p->decoder); + return p; +} + +void ZstdDec_Destroy(CZstdDecHandle p) +{ + #ifdef SHOW_STAT + #define PRINT_STAT1(name, v) \ + printf("\n%25s = %9u", name, v); + PRINT_STAT1("g_Num_Blocks_Compressed", g_Num_Blocks_Compressed) + PRINT_STAT1("g_Num_Blocks_memcpy", g_Num_Blocks_memcpy) + PRINT_STAT1("g_Num_Wrap_memmove_Num", g_Num_Wrap_memmove_Num) + PRINT_STAT1("g_Num_Wrap_memmove_Bytes", g_Num_Wrap_memmove_Bytes) + if (g_Num_Blocks_Compressed) + { + #define PRINT_STAT(name, v) \ + printf("\n%17s = %9u, per_block = %8u", name, v, v / g_Num_Blocks_Compressed); + PRINT_STAT("g_NumSeqs", g_NumSeqs_total) + // PRINT_STAT("g_NumCopy", g_NumCopy) + PRINT_STAT("g_NumOver", g_NumOver) + PRINT_STAT("g_NumOver2", g_NumOver2) + PRINT_STAT("g_Num_Match", g_Num_Match) + PRINT_STAT("g_Num_Lits", g_Num_Lits) + PRINT_STAT("g_Num_LitsBig", g_Num_LitsBig) + PRINT_STAT("g_Num_Lit0", g_Num_Lit0) + PRINT_STAT("g_Num_Rep_0", g_Num_Rep0) + PRINT_STAT("g_Num_Rep_1", g_Num_Rep1) + PRINT_STAT("g_Num_Rep_2", g_Num_Rep2) + PRINT_STAT("g_Num_Rep_3", g_Num_Rep3) + PRINT_STAT("g_Num_Threshold_0", g_Num_Threshold_0) + PRINT_STAT("g_Num_Threshold_1", g_Num_Threshold_1) + PRINT_STAT("g_Num_Threshold_0sum", g_Num_Threshold_0sum) + PRINT_STAT("g_Num_Threshold_1sum", g_Num_Threshold_1sum) + } + printf("\n"); + #endif + + ISzAlloc_Free(p->alloc_Small, p->decoder.literalsBase); + // p->->decoder.literalsBase = NULL; + ISzAlloc_Free(p->alloc_Small, p->inTemp); + // p->inTemp = NULL; + ZstdDec_FreeWindow(p); + ISzAlloc_Free(p->alloc_Small, p); +} + + + +#define kTempBuffer_PreSize (1u << 6) +#if kTempBuffer_PreSize < MAX_BACKWARD_DEPTH + #error Stop_Compiling_Bad_kTempBuffer_PreSize +#endif + +static SRes ZstdDec_AllocateMisc(CZstdDec *p) +{ + #define k_Lit_AfterAvail (1u << 6) + #if k_Lit_AfterAvail < (COPY_CHUNK_SIZE - 1) + #error Stop_Compiling_Bad_k_Lit_AfterAvail + #endif + // return ZstdDec1_Allocate(&p->decoder, p->alloc_Small); + if (!p->decoder.literalsBase) + { + p->decoder.literalsBase = (Byte *)ISzAlloc_Alloc(p->alloc_Small, + kBlockSizeMax + k_Lit_AfterAvail); + if (!p->decoder.literalsBase) + return SZ_ERROR_MEM; + } + if (!p->inTemp) + { + // we need k_Lit_AfterAvail here for owerread from raw literals stream + p->inTemp = (Byte *)ISzAlloc_Alloc(p->alloc_Small, + kBlockSizeMax + kTempBuffer_PreSize + k_Lit_AfterAvail); + if (!p->inTemp) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + + +static void ZstdDec_Init_ForNewFrame(CZstdDec *p) +{ + p->frameState = ZSTD2_STATE_SIGNATURE; + p->tempSize = 0; + + p->isErrorState = False; + p->hashError = False; + p->isCyclicMode = False; + p->contentProcessed = 0; + Xxh64State_Init(&p->xxh64); + ZstdDec1_Init(&p->decoder); +} + + +void ZstdDec_Init(CZstdDec *p) +{ + ZstdDec_Init_ForNewFrame(p); + p->decoder.winPos = 0; + memset(p->temp, 0, sizeof(p->temp)); +} + + +#define DESCRIPTOR_Get_DictionaryId_Flag(d) ((d) & 3) +#define DESCRIPTOR_FLAG_CHECKSUM (1 << 2) +#define DESCRIPTOR_FLAG_RESERVED (1 << 3) +// #define DESCRIPTOR_FLAG_UNUSED (1 << 4) +#define DESCRIPTOR_FLAG_SINGLE (1 << 5) +#define DESCRIPTOR_Get_ContentSize_Flag3(d) ((d) >> 5) +#define DESCRIPTOR_Is_ContentSize_Defined(d) (((d) & 0xe0) != 0) + + +static EZstd2State ZstdDec_UpdateState(CZstdDec * const p, const Byte b, CZstdDecInfo * const info) +{ + unsigned tempSize = p->tempSize; + p->temp[tempSize++] = b; + p->tempSize = tempSize; + + if (p->frameState == ZSTD2_STATE_BLOCK) + { + if (tempSize < 3) + return ZSTD2_STATE_BLOCK; + { + UInt32 b0 = GetUi32(p->temp); + const unsigned type = ((unsigned)b0 >> 1) & 3; + if (type == kBlockType_RLE && tempSize == 3) + return ZSTD2_STATE_BLOCK; + // info->num_Blocks_forType[type]++; + info->num_Blocks++; + if (type == kBlockType_Reserved) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED + return ZSTD2_STATE_BLOCK; + } + p->blockType = (Byte)type; + p->isLastBlock = (Byte)(b0 & 1); + p->inTempPos = 0; + p->tempSize = 0; + b0 >>= 3; + b0 &= 0x1fffff; + // info->num_BlockBytes_forType[type] += b0; + if (b0 == 0) + { + // empty RAW/RLE blocks are allowed in original-zstd decoder + if (type == kBlockType_Compressed) + { + p->isErrorState = True; + return ZSTD2_STATE_BLOCK; + } + if (!ZSTD_DEC_IS_LAST_BLOCK(p)) + return ZSTD2_STATE_BLOCK; + if (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) + return ZSTD2_STATE_HASH; + return ZSTD2_STATE_FINISHED; + } + p->blockSize = b0; + { + UInt32 blockLim = ZstdDec1_GET_BLOCK_SIZE_LIMIT(&p->decoder); + // compressed and uncompressed block sizes cannot be larger than min(kBlockSizeMax, window_size) + if (b0 > blockLim) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED; + return ZSTD2_STATE_BLOCK; + } + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor)) + { + const UInt64 rem = p->contentSize - p->contentProcessed; + if (blockLim > rem) + blockLim = (UInt32)rem; + } + p->curBlockUnpackRem = blockLim; + // uncompressed block size cannot be larger than remain data size: + if (type != kBlockType_Compressed) + { + if (b0 > blockLim) + { + p->isErrorState = True; // SZ_ERROR_UNSUPPORTED; + return ZSTD2_STATE_BLOCK; + } + } + } + } + return ZSTD2_STATE_DATA; + } + + if ((unsigned)p->frameState < ZSTD2_STATE_SKIP_DATA) + { + UInt32 v; + if (tempSize != 4) + return p->frameState; + v = GetUi32(p->temp); + if ((unsigned)p->frameState < ZSTD2_STATE_HASH) // == ZSTD2_STATE_SIGNATURE + { + if (v == 0xfd2fb528) + { + p->tempSize = 0; + info->num_DataFrames++; + return ZSTD2_STATE_FRAME_HEADER; + } + if ((v & 0xfffffff0) == 0x184d2a50) + { + p->tempSize = 0; + info->num_SkipFrames++; + return ZSTD2_STATE_SKIP_HEADER; + } + p->isErrorState = True; + return ZSTD2_STATE_SIGNATURE; + // return ZSTD2_STATE_ERROR; // is not ZSTD stream + } + if (p->frameState == ZSTD2_STATE_HASH) + { + info->checksum_Defined = True; + info->checksum = v; + // #ifndef DISABLE_XXH_CHECK + if (!p->disableHash) + { + if (p->decoder.winPos < ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p)) + { + // unexpected code failure + p->isErrorState = True; + // SZ_ERROR_FAIL; + } + else + if ((UInt32)Xxh64State_Digest(&p->xxh64, + p->decoder.win + (p->decoder.winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p)), + p->contentProcessed) != v) + { + p->hashError = True; + // return ZSTD2_STATE_ERROR; // hash error + } + } + // #endif + return ZSTD2_STATE_FINISHED; + } + // (p->frameState == ZSTD2_STATE_SKIP_HEADER) + { + p->blockSize = v; + info->skipFrames_Size += v; + p->tempSize = 0; + /* we want the caller could know that there was finished frame + finished frame. So we allow the case where + we have ZSTD2_STATE_SKIP_DATA state with (blockSize == 0). + */ + // if (v == 0) return ZSTD2_STATE_SIGNATURE; + return ZSTD2_STATE_SKIP_DATA; + } + } + + // if (p->frameState == ZSTD2_STATE_FRAME_HEADER) + { + unsigned descriptor; + const Byte *h; + descriptor = p->temp[0]; + p->descriptor = (Byte)descriptor; + if (descriptor & DESCRIPTOR_FLAG_RESERVED) // reserved bit + { + p->isErrorState = True; + return ZSTD2_STATE_FRAME_HEADER; + // return ZSTD2_STATE_ERROR; + } + { + const unsigned n = DESCRIPTOR_Get_ContentSize_Flag3(descriptor); + // tempSize -= 1 + ((1u << (n >> 1)) | ((n + 1) & 1)); + tempSize -= (0x9a563422u >> (n * 4)) & 0xf; + } + if (tempSize != (4u >> (3 - DESCRIPTOR_Get_DictionaryId_Flag(descriptor)))) + return ZSTD2_STATE_FRAME_HEADER; + + info->descriptor_OR = (Byte)(info->descriptor_OR | descriptor); + info->descriptor_NOT_OR = (Byte)(info->descriptor_NOT_OR | ~descriptor); + + h = &p->temp[1]; + { + Byte w = 0; + if ((descriptor & DESCRIPTOR_FLAG_SINGLE) == 0) + { + w = *h++; + if (info->windowDescriptor_MAX < w) + info->windowDescriptor_MAX = w; + // info->are_WindowDescriptors = True; + // info->num_WindowDescriptors++; + } + else + { + // info->are_SingleSegments = True; + // info->num_SingleSegments++; + } + p->windowDescriptor = w; + } + { + unsigned n = DESCRIPTOR_Get_DictionaryId_Flag(descriptor); + UInt32 d = 0; + if (n) + { + n = 1u << (n - 1); + d = GetUi32(h) & ((UInt32)(Int32)-1 >> (32 - 8u * n)); + h += n; + } + p->dictionaryId = d; + // info->dictionaryId_Cur = d; + if (d != 0) + { + if (info->dictionaryId == 0) + info->dictionaryId = d; + else if (info->dictionaryId != d) + info->are_DictionaryId_Different = True; + } + } + { + unsigned n = DESCRIPTOR_Get_ContentSize_Flag3(descriptor); + UInt64 v = 0; + if (n) + { + n >>= 1; + if (n == 1) + v = 256; + v += GetUi64(h) & ((UInt64)(Int64)-1 >> (64 - (8u << n))); + // info->are_ContentSize_Known = True; + // info->num_Frames_with_ContentSize++; + if (info->contentSize_MAX < v) + info->contentSize_MAX = v; + info->contentSize_Total += v; + } + else + { + info->are_ContentSize_Unknown = True; + // info->num_Frames_without_ContentSize++; + } + p->contentSize = v; + } + // if ((size_t)(h - p->temp) != headerSize) return ZSTD2_STATE_ERROR; // it's unexpected internal code failure + p->tempSize = 0; + + info->checksum_Defined = False; + /* + if (descriptor & DESCRIPTOR_FLAG_CHECKSUM) + info->are_Checksums = True; + else + info->are_Non_Checksums = True; + */ + + return ZSTD2_STATE_AFTER_HEADER; // ZSTD2_STATE_BLOCK; + } +} + + +static void ZstdDec_Update_XXH(CZstdDec * const p, size_t xxh64_winPos) +{ + /* + #ifdef DISABLE_XXH_CHECK + UNUSED_VAR(data) + #else + */ + if (!p->disableHash && (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM)) + { + // const size_t pos = p->xxh64_winPos; + const size_t size = (p->decoder.winPos - xxh64_winPos) & ~(size_t)31; + if (size) + { + // p->xxh64_winPos = pos + size; + Xxh64State_UpdateBlocks(&p->xxh64, + p->decoder.win + xxh64_winPos, + p->decoder.win + xxh64_winPos + size); + } + } +} + + +/* +in: + (winLimit) : is relaxed limit, where this function is allowed to stop writing of decoded data (if possible). + - this function uses (winLimit) for RAW/RLE blocks only, + because this function can decode single RAW/RLE block in several different calls. + - this function DOESN'T use (winLimit) for Compressed blocks, + because this function decodes full compressed block in single call. + (CZstdDec1::winPos <= winLimit) + (winLimit <= CZstdDec1::cycSize). + Note: if (ds->outBuf_fromCaller) mode is used, then + { + (strong_limit) is stored in CZstdDec1::cycSize. + So (winLimit) is more strong than (strong_limit). + } + +exit: + Note: (CZstdDecState::winPos) will be set by caller after exit of this function. + + This function can exit for any of these conditions: + - (frameState == ZSTD2_STATE_AFTER_HEADER) + - (frameState == ZSTD2_STATE_FINISHED) : frame was finished : (status == ZSTD_STATUS_FINISHED_FRAME) is set + - finished non-empty non-last block. So (CZstdDec1::winPos_atExit != winPos_atFuncStart). + - ZSTD_STATUS_NEEDS_MORE_INPUT in src + - (CZstdDec1::winPos) have reached (winLimit) in non-finished RAW/RLE block + + This function decodes no more than one non-empty block. + So it fulfills the condition at exit: + (CZstdDec1::winPos_atExit - winPos_atFuncStart <= block_size_max) + Note: (winPos_atExit > winLimit) is possible in some cases after compressed block decoding. + + if (ds->outBuf_fromCaller) mode (useAdditionalWinLimit medo) + { + then this function uses additional strong limit from (CZstdDec1::cycSize). + So this function will not write any data after (CZstdDec1::cycSize) + And it fulfills the condition at exit: + (CZstdDec1::winPos_atExit <= CZstdDec1::cycSize) + } +*/ +static SRes ZstdDec_DecodeBlock(CZstdDec * const p, CZstdDecState * const ds, + SizeT winLimitAdd) +{ + const Byte *src = ds->inBuf; + SizeT * const srcLen = &ds->inPos; + const SizeT inSize = ds->inLim; + // const int useAdditionalWinLimit = ds->outBuf_fromCaller ? 1 : 0; + enum_ZstdStatus * const status = &ds->status; + CZstdDecInfo * const info = &ds->info; + SizeT winLimit; + + const SizeT winPos_atFuncStart = p->decoder.winPos; + src += *srcLen; + *status = ZSTD_STATUS_NOT_SPECIFIED; + + // finishMode = ZSTD_FINISH_ANY; + if (ds->outSize_Defined) + { + if (ds->outSize < ds->outProcessed) + { + // p->isAfterSizeMode = 2; // we have extra bytes already + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + // size = 0; + } + else + { + // p->outSize >= p->outProcessed + const UInt64 rem = ds->outSize - ds->outProcessed; + /* + if (rem == 0) + p->isAfterSizeMode = 1; // we have reached exact required size + */ + if (winLimitAdd >= rem) + { + winLimitAdd = (SizeT)rem; + // if (p->finishMode) finishMode = ZSTD_FINISH_END; + } + } + } + + winLimit = p->decoder.winPos + winLimitAdd; + // (p->decoder.winPos <= winLimit) + + // while (p->frameState != ZSTD2_STATE_ERROR) + while (!p->isErrorState) + { + SizeT inCur = inSize - *srcLen; + + if (p->frameState == ZSTD2_STATE_DATA) + { + /* (p->decoder.winPos == winPos_atFuncStart) is expected, + because this function doesn't start new block. + if it have finished some non-empty block in this call. */ + if (p->decoder.winPos != winPos_atFuncStart) + return SZ_ERROR_FAIL; // it's unexpected + + /* + if (p->decoder.winPos > winLimit) + { + // we can be here, if in this function call + // - we have extracted non-empty compressed block, and (winPos > winLimit) after that. + // - we have started new block decoding after that. + // It's unexpected case, because we exit after non-empty non-last block. + *status = (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED; + return SZ_OK; + } + */ + // p->decoder.winPos <= winLimit + + if (p->blockType != kBlockType_Compressed) + { + // it's RLE or RAW block. + // p->BlockSize != 0_ + // winLimit <= p->decoder.cycSize + /* So here we use more strong (winLimit), even for + (ds->outBuf_fromCaller) mode. */ + SizeT outCur = winLimit - p->decoder.winPos; + { + const UInt32 rem = p->blockSize; + if (outCur > rem) + outCur = rem; + } + if (p->blockType == kBlockType_Raw) + { + if (outCur > inCur) + outCur = inCur; + /* output buffer is better aligned for XXH code. + So we use hash for output buffer data */ + // ZstdDec_Update_XXH(p, src, outCur); // for debug: + memcpy(p->decoder.win + p->decoder.winPos, src, outCur); + src += outCur; + *srcLen += outCur; + } + else // kBlockType_RLE + { + #define RLE_BYTE_INDEX_IN_temp 3 + memset(p->decoder.win + p->decoder.winPos, + p->temp[RLE_BYTE_INDEX_IN_temp], outCur); + } + { + const SizeT xxh64_winPos = p->decoder.winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p); + p->decoder.winPos += outCur; + UPDATE_TOTAL_OUT(&p->decoder, outCur) + p->contentProcessed += outCur; + ZstdDec_Update_XXH(p, xxh64_winPos); + } + // ds->winPos = p->decoder.winPos; // the caller does it instead. for debug: + ds->outProcessed += outCur; + if (p->blockSize -= (UInt32)outCur) + { + /* + if (ds->outSize_Defined) + { + if (ds->outSize <= ds->outProcessed) ds->isAfterSizeMode = (enum_ZstdStatus) + (ds->outSize == ds->outProcessed ? 1u: 2u); + } + */ + *status = (enum_ZstdStatus) + (ds->outSize_Defined && ds->outSize <= ds->outProcessed ? + ZSTD_STATUS_OUT_REACHED : (p->blockType == kBlockType_Raw && inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED); + return SZ_OK; + } + } + else // kBlockType_Compressed + { + // p->blockSize != 0 + // (uncompressed_size_of_block == 0) is allowed + // (p->curBlockUnpackRem == 0) is allowed + /* + if (p->decoder.winPos >= winLimit) + { + if (p->decoder.winPos != winPos_atFuncStart) + { + // it's unexpected case + // We already have some data in finished blocks in this function call. + // So we don't decompress new block after (>=winLimit), + // even if it's empty block. + *status = (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED; + return SZ_OK; + } + // (p->decoder.winPos == winLimit == winPos_atFuncStart) + // we will decode current block, because that current + // block can be empty block and we want to make some visible + // change of (src) stream after function start. + } + */ + /* + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + // we don't want to start new block, if we have more extra decoded bytes already + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + } + */ + { + const Byte *comprStream; + size_t afterAvail; + UInt32 inTempPos = p->inTempPos; + const UInt32 rem = p->blockSize - inTempPos; + // rem != 0 + if (inTempPos != 0 // (inTemp) buffer already contains some input data + || inCur < rem // available input data size is smaller than compressed block size + || ZstdDec1_NeedTempBufferForInput(*srcLen, src, rem)) + { + if (inCur > rem) + inCur = rem; + if (inCur) + { + STAT_INC(g_Num_Blocks_memcpy) + // we clear data for backward lookahead reading + if (inTempPos == 0) + memset(p->inTemp + kTempBuffer_PreSize - MAX_BACKWARD_DEPTH, 0, MAX_BACKWARD_DEPTH); + // { unsigned y = 0; for(;y < 1000; y++) + memcpy(p->inTemp + inTempPos + kTempBuffer_PreSize, src, inCur); + // } + src += inCur; + *srcLen += inCur; + inTempPos += (UInt32)inCur; + p->inTempPos = inTempPos; + } + if (inTempPos != p->blockSize) + { + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + #if COPY_CHUNK_SIZE > 1 + memset(p->inTemp + kTempBuffer_PreSize + inTempPos, 0, COPY_CHUNK_SIZE); + #endif + comprStream = p->inTemp + kTempBuffer_PreSize; + afterAvail = k_Lit_AfterAvail; + // we don't want to read non-initialized data or junk in CopyMatch(): + } + else + { + // inCur >= rem + // we use direct decoding from (src) buffer: + afterAvail = inCur - rem; + comprStream = src; + src += rem; + *srcLen += rem; + } + + #ifdef Z7_ZSTD_DEC_USE_CHECK_OF_NEED_TEMP + ZstdDec1_NeedTempBufferForInput(*srcLen, comprStream, p->blockSize); + #endif + // printf("\nblockSize=%u", p->blockSize); + // printf("%x\n", (unsigned)p->contentProcessed); + STAT_INC(g_Num_Blocks_Compressed) + { + SRes sres; + const size_t winPos = p->decoder.winPos; + /* + if ( useAdditionalWinLimit), we use strong unpack limit: smallest from + - limit from stream : (curBlockUnpackRem) + - limit from caller : (cycSize - winPos) + if (!useAdditionalWinLimit), we use only relaxed limit: + - limit from stream : (curBlockUnpackRem) + */ + SizeT outLimit = p->curBlockUnpackRem; + if (ds->outBuf_fromCaller) + // if (useAdditionalWinLimit) + { + const size_t limit = p->decoder.cycSize - winPos; + if (outLimit > limit) + outLimit = limit; + } + sres = ZstdDec1_DecodeBlock(&p->decoder, + comprStream, p->blockSize, afterAvail, outLimit); + // ds->winPos = p->decoder.winPos; // the caller does it instead. for debug: + if (sres) + { + p->isErrorState = True; + return sres; + } + { + const SizeT xxh64_winPos = winPos - ZstdDec_GET_UNPROCESSED_XXH64_SIZE(p); + const size_t num = p->decoder.winPos - winPos; + ds->outProcessed += num; + p->contentProcessed += num; + ZstdDec_Update_XXH(p, xxh64_winPos); + } + } + // printf("\nwinPos=%x", (int)(unsigned)p->decoder.winPos); + } + } + + /* + if (ds->outSize_Defined) + { + if (ds->outSize <= ds->outProcessed) ds->isAfterSizeMode = (enum_ZstdStatus) + (ds->outSize == ds->outProcessed ? 1u: 2u); + } + */ + + if (!ZSTD_DEC_IS_LAST_BLOCK(p)) + { + p->frameState = ZSTD2_STATE_BLOCK; + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; + } + // we exit only if (winPos) was changed in this function call: + if (p->decoder.winPos != winPos_atFuncStart) + { + // decoded block was not empty. So we exit: + *status = (enum_ZstdStatus)( + (inSize == *srcLen) ? + ZSTD_STATUS_NEEDS_MORE_INPUT : + ZSTD_STATUS_NOT_FINISHED); + return SZ_OK; + } + // (p->decoder.winPos == winPos_atFuncStart) + // so current decoded block was empty. + // we will try to decode more blocks in this function. + continue; + } + + // decoded block was last in frame + if (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) + { + p->frameState = ZSTD2_STATE_HASH; + if (ds->outSize_Defined && ds->outSize < ds->outProcessed) + { + *status = ZSTD_STATUS_OUT_REACHED; + return SZ_OK; // disable if want to + /* We want to get same return codes for any input buffer sizes. + We want to get faster ZSTD_STATUS_OUT_REACHED status. + So we exit with ZSTD_STATUS_OUT_REACHED here, + instead of ZSTD2_STATE_HASH and ZSTD2_STATE_FINISHED processing. + that depends from input buffer size and that can set + ZSTD_STATUS_NEEDS_MORE_INPUT or return SZ_ERROR_DATA or SZ_ERROR_CRC. + */ + } + } + else + { + /* ZSTD2_STATE_FINISHED proccesing doesn't depend from input buffer */ + p->frameState = ZSTD2_STATE_FINISHED; + } + /* + p->frameState = (p->descriptor & DESCRIPTOR_FLAG_CHECKSUM) ? + ZSTD2_STATE_HASH : + ZSTD2_STATE_FINISHED; + */ + /* it's required to process ZSTD2_STATE_FINISHED state in this function call, + because we must check contentSize and hashError in ZSTD2_STATE_FINISHED code, + while the caller can reinit full state for ZSTD2_STATE_FINISHED + So we can't exit from function here. */ + continue; + } + + if (p->frameState == ZSTD2_STATE_FINISHED) + { + *status = ZSTD_STATUS_FINISHED_FRAME; + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor) + && p->contentSize != p->contentProcessed) + return SZ_ERROR_DATA; + if (p->hashError) // for debug + return SZ_ERROR_CRC; + return SZ_OK; + // p->frameState = ZSTD2_STATE_SIGNATURE; + // continue; + } + + if (p->frameState == ZSTD2_STATE_AFTER_HEADER) + return SZ_OK; // we need memory allocation for that state + + if (p->frameState == ZSTD2_STATE_SKIP_DATA) + { + UInt32 blockSize = p->blockSize; + // (blockSize == 0) is possible + if (inCur > blockSize) + inCur = blockSize; + src += inCur; + *srcLen += inCur; + blockSize -= (UInt32)inCur; + p->blockSize = blockSize; + if (blockSize == 0) + { + p->frameState = ZSTD2_STATE_SIGNATURE; + // continue; // for debug: we can continue without return to caller. + // we notify the caller that skip frame was finished: + *status = ZSTD_STATUS_FINISHED_FRAME; + return SZ_OK; + } + // blockSize != 0 + // (inCur) was smaller than previous value of p->blockSize. + // (inSize == *srcLen) now + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (inCur == 0) + { + *status = ZSTD_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + { + (*srcLen)++; + p->frameState = ZstdDec_UpdateState(p, *src++, info); + } + } + + *status = ZSTD_STATUS_NOT_SPECIFIED; + p->isErrorState = True; + // p->frameState = ZSTD2_STATE_ERROR; + // if (p->frameState = ZSTD2_STATE_SIGNATURE) return SZ_ERROR_NO_ARCHIVE + return SZ_ERROR_DATA; +} + + + + +SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p) +{ + p->needWrite_Size = 0; + p->status = ZSTD_STATUS_NOT_SPECIFIED; + dec->disableHash = p->disableHash; + + if (p->outBuf_fromCaller) + { + dec->decoder.win = p->outBuf_fromCaller; + dec->decoder.cycSize = p->outBufSize_fromCaller; + } + + // p->winPos = dec->decoder.winPos; + + for (;;) + { + SizeT winPos, size; + // SizeT outProcessed; + SRes res; + + if (p->wrPos > dec->decoder.winPos) + return SZ_ERROR_FAIL; + + if (dec->frameState == ZSTD2_STATE_FINISHED) + { + if (!p->outBuf_fromCaller) + { + // we need to set positions to zero for new frame. + if (p->wrPos != dec->decoder.winPos) + { + /* We have already asked the caller to flush all data + with (p->needWrite_Size) and (ZSTD_STATUS_FINISHED_FRAME) status. + So it's unexpected case */ + // p->winPos = dec->decoder.winPos; + // p->needWrite_Size = dec->decoder.winPos - p->wrPos; // flush size asking + // return SZ_OK; // ask to flush again + return SZ_ERROR_FAIL; + } + // (p->wrPos == dec->decoder.winPos), and we wrap to zero: + dec->decoder.winPos = 0; + p->winPos = 0; + p->wrPos = 0; + } + ZstdDec_Init_ForNewFrame(dec); + // continue; + } + + winPos = dec->decoder.winPos; + { + SizeT next = dec->decoder.cycSize; + /* cycSize == 0, if no buffer was allocated still, + or, if (outBuf_fromCaller) mode and (outBufSize_fromCaller == 0) */ + if (!p->outBuf_fromCaller + && next + && next <= winPos + && dec->isCyclicMode) + { + // (0 < decoder.cycSize <= winPos) in isCyclicMode. + // so we need to wrap (winPos) and (wrPos) over (cycSize). + const size_t delta = next; + // (delta) is how many bytes we remove from buffer. + /* + // we don't need data older than last (cycSize) bytes. + size_t delta = winPos - next; // num bytes after (cycSize) + if (delta <= next) // it's expected case + delta = next; + // delta == Max(cycSize, winPos - cycSize) + */ + if (p->wrPos < delta) + { + // (wrPos < decoder.cycSize) + // We have asked already the caller to flush required data + // p->status = ZSTD_STATUS_NOT_SPECIFIED; + // p->winPos = winPos; + // p->needWrite_Size = delta - p->wrPos; // flush size asking + // return SZ_OK; // ask to flush again + return SZ_ERROR_FAIL; + } + // p->wrPos >= decoder.cycSize + // we move extra data after (decoder.cycSize) to start of cyclic buffer: + winPos -= delta; + if (winPos) + { + if (winPos >= delta) + return SZ_ERROR_FAIL; + memmove(dec->decoder.win, dec->decoder.win + delta, winPos); + // printf("\nmemmove processed=%8x winPos=%8x\n", (unsigned)p->outProcessed, (unsigned)dec->decoder.winPos); + STAT_INC(g_Num_Wrap_memmove_Num) + STAT_UPDATE(g_Num_Wrap_memmove_Bytes += (unsigned)winPos;) + } + dec->decoder.winPos = winPos; + p->winPos = winPos; + p->wrPos -= delta; + // dec->xxh64_winPos -= delta; + + // (winPos < delta) + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + /* we set the data after cycSize, because + we don't want to read non-initialized data or junk in CopyMatch(). */ + memset(dec->decoder.win + next, 0, COPY_CHUNK_SIZE); + #endif + + /* + if (winPos == next) + { + if (winPos != p->wrPos) + { + // we already requested before to flush full data for that case. + // but we give the caller a second chance to flush data: + p->needWrite_Size = winPos - p->wrPos; + return SZ_OK; + } + // (decoder.cycSize == winPos == p->wrPos) + // so we do second wrapping to zero: + winPos = 0; + dec->decoder.winPos = 0; + p->winPos = 0; + p->wrPos = 0; + } + */ + // (winPos < next) + } + + if (winPos > next) + return SZ_ERROR_FAIL; // it's unexpected case + /* + if (!outBuf_fromCaller && isCyclicMode && cycSize != 0) + then (winPos < cycSize) + else (winPos <= cycSize) + */ + if (!p->outBuf_fromCaller) + { + // that code is optional. We try to optimize write chunk sizes. + /* (next2) is expected next write position in the caller, + if the caller writes by kBlockSizeMax chunks. + */ + /* + const size_t next2 = (winPos + kBlockSizeMax) & (kBlockSizeMax - 1); + if (winPos < next2 && next2 < next) + next = next2; + */ + } + size = next - winPos; + } + + // note: ZstdDec_DecodeBlock() uses (winLimit = winPos + size) only for RLE and RAW blocks + res = ZstdDec_DecodeBlock(dec, p, size); + /* + after one block decoding: + if (!outBuf_fromCaller && isCyclicMode && cycSize != 0) + then (winPos < cycSize + max_block_size) + else (winPos <= cycSize) + */ + + if (!p->outBuf_fromCaller) + p->win = dec->decoder.win; + p->winPos = dec->decoder.winPos; + + // outProcessed = dec->decoder.winPos - winPos; + // p->outProcessed += outProcessed; + + if (res != SZ_OK) + return res; + + if (dec->frameState != ZSTD2_STATE_AFTER_HEADER) + { + if (p->outBuf_fromCaller) + return SZ_OK; + { + // !p->outBuf_fromCaller + /* + if (ZSTD_STATUS_FINISHED_FRAME), we request full flushing here because + 1) it's simpler to work with allocation and extracting of next frame, + 2) it's better to start writing to next new frame with aligned memory + for faster xxh 64-bit reads. + */ + size_t end = dec->decoder.winPos; // end pos for all data flushing + if (p->status != ZSTD_STATUS_FINISHED_FRAME) + { + // we will request flush here only for cases when wrap in cyclic buffer can be required in next call. + if (!dec->isCyclicMode) + return SZ_OK; + // isCyclicMode + { + const size_t delta = dec->decoder.cycSize; + if (end < delta) + return SZ_OK; // (winPos < cycSize). no need for flush + // cycSize <= winPos + // So we ask the caller to flush of (cycSize - wrPos) bytes, + // and then we will wrap cylicBuffer in next call + end = delta; + } + } + p->needWrite_Size = end - p->wrPos; + } + return SZ_OK; + } + + // ZSTD2_STATE_AFTER_HEADER + { + BoolInt useCyclic = False; + size_t cycSize; + + // p->status = ZSTD_STATUS_NOT_FINISHED; + if (dec->dictionaryId != 0) + { + /* actually we can try to decode some data, + because it's possible that some data doesn't use dictionary */ + // p->status = ZSTD_STATUS_NOT_SPECIFIED; + return SZ_ERROR_UNSUPPORTED; + } + + { + UInt64 winSize = dec->contentSize; + UInt64 winSize_Allocate = winSize; + const unsigned descriptor = dec->descriptor; + + if ((descriptor & DESCRIPTOR_FLAG_SINGLE) == 0) + { + const Byte wd = dec->windowDescriptor; + winSize = (UInt64)(8 + (wd & 7)) << ((wd >> 3) + 10 - 3); + if (!DESCRIPTOR_Is_ContentSize_Defined(descriptor) + || winSize_Allocate > winSize) + { + winSize_Allocate = winSize; + useCyclic = True; + } + } + /* + else + { + if (p->info.singleSegment_ContentSize_MAX < winSize) + p->info.singleSegment_ContentSize_MAX = winSize; + // p->info.num_SingleSegments++; + } + */ + if (p->info.windowSize_MAX < winSize) + p->info.windowSize_MAX = winSize; + if (p->info.windowSize_Allocate_MAX < winSize_Allocate) + p->info.windowSize_Allocate_MAX = winSize_Allocate; + /* + winSize_Allocate is MIN(content_size, window_size_from_descriptor). + Wven if (content_size < (window_size_from_descriptor)) + original-zstd still uses (window_size_from_descriptor) to check that decoding is allowed. + We try to follow original-zstd, and here we check (winSize) instead of (winSize_Allocate)) + */ + if ( + // winSize_Allocate // it's relaxed check + winSize // it's more strict check to be compatible with original-zstd + > ((UInt64)1 << MAX_WINDOW_SIZE_LOG)) + return SZ_ERROR_UNSUPPORTED; // SZ_ERROR_MEM + cycSize = (size_t)winSize_Allocate; + if (cycSize != winSize_Allocate) + return SZ_ERROR_MEM; + // cycSize <= winSize + /* later we will use (CZstdDec1::winSize) to check match offsets and check block sizes. + if (there is window descriptor) + { + We will check block size with (window_size_from_descriptor) instead of (winSize_Allocate). + Does original-zstd do it that way also? + } + Here we must reduce full real 64-bit (winSize) to size_t for (CZstdDec1::winSize). + Also we don't want too big values for (CZstdDec1::winSize). + our (CZstdDec1::winSize) will meet the condition: + (CZstdDec1::winSize < kBlockSizeMax || CZstdDec1::winSize <= cycSize). + */ + dec->decoder.winSize = (winSize < kBlockSizeMax) ? (size_t)winSize: cycSize; + // note: (CZstdDec1::winSize > cycSize) is possible, if (!useCyclic) + } + + RINOK(ZstdDec_AllocateMisc(dec)) + + if (p->outBuf_fromCaller) + dec->isCyclicMode = False; + else + { + size_t d = cycSize; + + if (dec->decoder.winPos != p->wrPos) + return SZ_ERROR_FAIL; + + dec->decoder.winPos = 0; + p->wrPos = 0; + p->winPos = dec->decoder.winPos; + + /* + const size_t needWrite = dec->decoder.winPos - p->wrPos; + if (!needWrite) + { + dec->decoder.winPos = 0; + p->wrPos = 0; + p->winPos = dec->decoder.winPos; + } + */ + /* if (!useCyclic) we allocate only cycSize = ContentSize. + But if we want to support the case where new frame starts with winPos != 0, + then we will wrap over zero, and we still need + to set (useCyclic) and allocate additional buffer spaces. + Now we don't allow new frame starting with (winPos != 0). + so (dec->decoder->winPos == 0) + can use (!useCyclic) with reduced buffer sizes. + */ + /* + if (dec->decoder->winPos != 0) + useCyclic = True; + */ + + if (useCyclic) + { + /* cyclyc buffer size must be at least (COPY_CHUNK_SIZE - 1) bytes + larger than window size, because CopyMatch() can write additional + (COPY_CHUNK_SIZE - 1) bytes and overwrite oldests data in cyclyc buffer. + But for performance reasons we align (cycSize) for (kBlockSizeMax). + also we must provide (cycSize >= max_decoded_data_after_cycSize), + because after data move wrapping over zero we must provide (winPos < cycSize). + */ + const size_t alignSize = kBlockSizeMax; + /* here we add (1 << 7) instead of (COPY_CHUNK_SIZE - 1), because + we want to get same (cycSize) for different COPY_CHUNK_SIZE values. */ + // cycSize += (COPY_CHUNK_SIZE - 1) + (alignSize - 1); // for debug : we can get smallest (cycSize) + cycSize += (1 << 7) + alignSize; + cycSize &= ~(size_t)(alignSize - 1); + // cycSize must be aligned for 32, because xxh requires 32-bytes blocks. + // cycSize += 12345; // for debug + // cycSize += 1 << 10; // for debug + // cycSize += 32; // for debug + // cycSize += kBlockSizeMax; // for debug + if (cycSize < d) + return SZ_ERROR_MEM; + /* + in cyclic buffer mode we allow to decode one additional block + that exceeds (cycSize). + So we must allocate additional (kBlockSizeMax) bytes after (cycSize). + if defined(Z7_STD_DEC_USE_AFTER_CYC_BUF) + { + we can read (COPY_CHUNK_SIZE - 1) bytes after (cycSize) + but we aready allocate additional kBlockSizeMax that + is larger than COPY_CHUNK_SIZE. + So we don't need additional space of COPY_CHUNK_SIZE after (cycSize). + } + */ + /* + #ifdef Z7_STD_DEC_USE_AFTER_CYC_BUF + d = cycSize + (1 << 7); // we must add at least (COPY_CHUNK_SIZE - 1) + #endif + */ + d = cycSize + kBlockSizeMax; + if (d < cycSize) + return SZ_ERROR_MEM; + } + + { + const size_t kMinWinAllocSize = 1 << 12; + if (d < kMinWinAllocSize) + d = kMinWinAllocSize; + } + + if (d > dec->winBufSize_Allocated) + { + /* + if (needWrite) + { + p->needWrite_Size = needWrite; + return SZ_OK; + // return SZ_ERROR_FAIL; + } + */ + + if (dec->winBufSize_Allocated != 0) + { + const size_t k_extra = (useCyclic || d >= (1u << 20)) ? + 2 * kBlockSizeMax : 0; + unsigned i = useCyclic ? 17 : 12; + for (; i < sizeof(size_t) * 8; i++) + { + const size_t d2 = ((size_t)1 << i) + k_extra; + if (d2 >= d) + { + d = d2; + break; + } + } + } + // RINOK(ZstdDec_AllocateWindow(dec, d)) + ZstdDec_FreeWindow(dec); + dec->win_Base = (Byte *)ISzAlloc_Alloc(dec->alloc_Big, d); + if (!dec->win_Base) + return SZ_ERROR_MEM; + dec->decoder.win = dec->win_Base; + dec->winBufSize_Allocated = d; + } + /* + else + { + // for non-cyclycMode we want flush data, and set winPos = 0 + if (needWrite) + { + if (!useCyclic || dec->decoder.winPos >= cycSize) + { + p->needWrite_Size = needWrite; + return SZ_OK; + // return SZ_ERROR_FAIL; + } + } + } + */ + + dec->decoder.cycSize = cycSize; + p->win = dec->decoder.win; + // p->cycSize = dec->decoder.cycSize; + dec->isCyclicMode = (Byte)useCyclic; + } // (!p->outBuf_fromCaller) end + + // p->winPos = dec->decoder.winPos; + dec->frameState = ZSTD2_STATE_BLOCK; + // continue; + } // ZSTD2_STATE_AFTER_HEADER end + } +} + + +void ZstdDec_GetResInfo(const CZstdDec *dec, + const CZstdDecState *p, + SRes res, + CZstdDecResInfo *stat) +{ + // ZstdDecInfo_CLEAR(stat); + stat->extraSize = 0; + stat->is_NonFinishedFrame = False; + if (dec->frameState != ZSTD2_STATE_FINISHED) + { + if (dec->frameState == ZSTD2_STATE_SIGNATURE) + { + stat->extraSize = (Byte)dec->tempSize; + if (ZstdDecInfo_GET_NUM_FRAMES(&p->info) == 0) + res = SZ_ERROR_NO_ARCHIVE; + } + else + { + stat->is_NonFinishedFrame = True; + if (res == SZ_OK && p->status == ZSTD_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + } + } + stat->decode_SRes = res; +} + + +size_t ZstdDec_ReadUnusedFromInBuf( + CZstdDecHandle dec, + size_t afterDecoding_tempPos, + void *data, size_t size) +{ + size_t processed = 0; + if (dec->frameState == ZSTD2_STATE_SIGNATURE) + { + Byte *dest = (Byte *)data; + const size_t tempSize = dec->tempSize; + while (afterDecoding_tempPos < tempSize) + { + if (size == 0) + break; + size--; + *dest++ = dec->temp[afterDecoding_tempPos++]; + processed++; + } + } + return processed; +} + + +void ZstdDecState_Clear(CZstdDecState *p) +{ + memset(p, 0 , sizeof(*p)); +} diff -Nru p7zip-rar-16.02/C/ZstdDec.h p7zip-rar-16.02+really25.00+ds/C/ZstdDec.h --- p7zip-rar-16.02/C/ZstdDec.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/ZstdDec.h 2024-01-21 11:00:00.000000000 +0000 @@ -0,0 +1,173 @@ +/* ZstdDec.h -- Zstd Decoder interfaces +2024-01-21 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ZSTD_DEC_H +#define ZIP7_INC_ZSTD_DEC_H + +EXTERN_C_BEGIN + +typedef struct CZstdDec CZstdDec; +typedef CZstdDec * CZstdDecHandle; + +CZstdDecHandle ZstdDec_Create(ISzAllocPtr alloc_Small, ISzAllocPtr alloc_Big); +void ZstdDec_Destroy(CZstdDecHandle p); + +typedef enum +{ + ZSTD_STATUS_NOT_SPECIFIED, /* use main error code instead */ + ZSTD_STATUS_FINISHED_FRAME, /* data frame or skip frame was finished */ + ZSTD_STATUS_NOT_FINISHED, /* just finished non-empty block or unfinished RAW/RLE block */ + ZSTD_STATUS_NEEDS_MORE_INPUT, /* the callee needs more input bytes. It has more priority over ZSTD_STATUS_NOT_FINISHED */ + ZSTD_STATUS_OUT_REACHED /* is not finihed frame and ((outProcessed > outSize) || (outProcessed == outSize && unfinished RAW/RLE block) */ +} enum_ZstdStatus_Dummy; + +#define ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(p) \ + ((p)->status & ZSTD_STATUS_FINISHED_FRAME) +/* + ((p)->status == ZSTD_STATUS_NEEDS_MORE_INPUT || \ + (p)->status == ZSTD_STATUS_FINISHED_FRAME) +*/ + +typedef Byte enum_ZstdStatus; + + +void ZstdDec_Init(CZstdDecHandle p); + +typedef struct +{ + UInt64 num_Blocks; + Byte descriptor_OR; + Byte descriptor_NOT_OR; + Byte are_ContentSize_Unknown; + Byte windowDescriptor_MAX; + + // Byte are_ContentSize_Known; + // Byte are_SingleSegments; + // Byte are_WindowDescriptors; + Byte checksum_Defined; + // Byte are_Checksums; + // Byte are_Non_Checksums; + + // Byte are_DictionaryId; + Byte are_DictionaryId_Different; + + // Byte reserved[3]; + + UInt32 checksum; // checksum of last data frame + /// UInt32 dictionaryId_Cur; + UInt32 dictionaryId; // if there are non-zero dictionary IDs, then it's first dictionaryId + + UInt64 num_DataFrames; + UInt64 num_SkipFrames; + UInt64 skipFrames_Size; + UInt64 contentSize_Total; + UInt64 contentSize_MAX; + // UInt64 num_Checksums; + // UInt64 num_Non_Checksums; // frames without checksum + // UInt64 num_WindowDescriptors; + // UInt64 num_SingleSegments; + // UInt64 num_Frames_with_ContentSize; + // UInt64 num_Frames_without_ContentSize; + UInt64 windowSize_MAX; + UInt64 windowSize_Allocate_MAX; + // UInt64 num_DictionaryIds; + // UInt64 num_Blocks_forType[4]; + // UInt64 num_BlockBytes_forType[4]; + // UInt64 num_SingleSegments; + // UInt64 singleSegment_ContentSize_MAX; +} CZstdDecInfo; + +#define ZstdDecInfo_CLEAR(p) { memset(p, 0, sizeof(*(p))); } + +#define ZstdDecInfo_GET_NUM_FRAMES(p) ((p)->num_DataFrames + (p)->num_SkipFrames) + + +typedef struct CZstdDecState +{ + enum_ZstdStatus status; // out + Byte disableHash; + // Byte mustBeFinished; + Byte outSize_Defined; + // Byte isAfterSizeMode; + // UInt64 inProcessed; + // SRes codeRes; + // Byte needWrite_IsStrong; + + const Byte *inBuf; + size_t inPos; // in/out + size_t inLim; + + const Byte *win; // out + size_t winPos; // out + size_t wrPos; // in/out + // size_t cycSize; // out : if (!outBuf_fromCaller) + size_t needWrite_Size; // out + + Byte *outBuf_fromCaller; + size_t outBufSize_fromCaller; + /* (outBufSize_fromCaller >= full_uncompressed_size_of_all_frames) is required + for success decoding. + If outBufSize_fromCaller < full_uncompressed_size_of_all_frames), + decoding can give error message, because we decode per block basis. + */ + + // size_t outStep; + UInt64 outSize; // total in all frames + UInt64 outProcessed; // out decoded in all frames (it can be >= outSize) + + CZstdDecInfo info; +} CZstdDecState; + +void ZstdDecState_Clear(CZstdDecState *p); + +/* +ZstdDec_Decode() +return: + SZ_OK - no error + SZ_ERROR_DATA - Data Error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - XXH hash Error + // SZ_ERROR_ARCHIVE - Headers error (not used now) +*/ +SRes ZstdDec_Decode(CZstdDecHandle dec, CZstdDecState *p); + +/* +ZstdDec_ReadUnusedFromInBuf(): +returns: the number of bytes that were read from InBuf +(*afterDecoding_tempPos) must be set to zero before first call of ZstdDec_ReadUnusedFromInBuf() +*/ +size_t ZstdDec_ReadUnusedFromInBuf( + CZstdDecHandle dec, + size_t afterDecoding_tempPos, // in/out + void *data, size_t size); + +typedef struct +{ + SRes decode_SRes; // error code of data decoding + Byte is_NonFinishedFrame; // there is unfinished decoding for data frame or skip frame + Byte extraSize; +} CZstdDecResInfo; + +/* +#define ZstdDecResInfo_CLEAR(p) \ +{ (p)->decode_SRes = 0; \ + (p)->is_NonFinishedFrame; \ + (p)->extraSize = 0; \ +} +// memset(p, 0, sizeof(*p)); +*/ + +/* +additional error codes for CZstdDecResInfo::decode_SRes: + SZ_ERROR_NO_ARCHIVE - is not zstd stream (no frames) + SZ_ERROR_INPUT_EOF - need more data in input stream +*/ +void ZstdDec_GetResInfo(const CZstdDec *dec, + const CZstdDecState *p, + SRes res, // it's result from ZstdDec_Decode() + CZstdDecResInfo *info); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/C/var_clang.mak p7zip-rar-16.02+really25.00+ds/C/var_clang.mak --- p7zip-rar-16.02/C/var_clang.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_clang.mak 2021-04-28 11:31:13.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM= +O=b/c +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/var_clang_arm64.mak p7zip-rar-16.02+really25.00+ds/C/var_clang_arm64.mak --- p7zip-rar-16.02/C/var_clang_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_clang_arm64.mak 2024-02-28 10:00:00.000000000 +0000 @@ -0,0 +1,12 @@ +PLATFORM=arm64 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +ASM_FLAGS=-Wno-unused-macros +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/var_clang_x64.mak p7zip-rar-16.02+really25.00+ds/C/var_clang_x64.mak --- p7zip-rar-16.02/C/var_clang_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_clang_x64.mak 2021-05-31 17:50:54.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/c_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/var_clang_x86.mak p7zip-rar-16.02+really25.00+ds/C/var_clang_x86.mak --- p7zip-rar-16.02/C/var_clang_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_clang_x86.mak 2021-05-31 17:50:54.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x86 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/var_gcc.mak p7zip-rar-16.02+really25.00+ds/C/var_gcc.mak --- p7zip-rar-16.02/C/var_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_gcc.mak 2021-04-28 11:30:57.000000000 +0000 @@ -0,0 +1,12 @@ +PLATFORM= +O=b/g +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff -Nru p7zip-rar-16.02/C/var_gcc_arm64.mak p7zip-rar-16.02+really25.00+ds/C/var_gcc_arm64.mak --- p7zip-rar-16.02/C/var_gcc_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_gcc_arm64.mak 2021-04-28 11:24:49.000000000 +0000 @@ -0,0 +1,12 @@ +PLATFORM=arm64 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH=-mtune=cortex-a53 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff -Nru p7zip-rar-16.02/C/var_gcc_x64.mak p7zip-rar-16.02+really25.00+ds/C/var_gcc_x64.mak --- p7zip-rar-16.02/C/var_gcc_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_gcc_x64.mak 2021-04-28 11:25:04.000000000 +0000 @@ -0,0 +1,10 @@ +PLATFORM=x64 +O=b/g_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ diff -Nru p7zip-rar-16.02/C/var_gcc_x86.mak p7zip-rar-16.02+really25.00+ds/C/var_gcc_x86.mak --- p7zip-rar-16.02/C/var_gcc_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_gcc_x86.mak 2021-05-31 17:50:54.000000000 +0000 @@ -0,0 +1,10 @@ +PLATFORM=x86 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ diff -Nru p7zip-rar-16.02/C/var_mac_arm64.mak p7zip-rar-16.02+really25.00+ds/C/var_mac_arm64.mak --- p7zip-rar-16.02/C/var_mac_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_mac_arm64.mak 2021-04-28 11:25:46.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=arm64 +O=b/m_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH=-arch arm64 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/var_mac_x64.mak p7zip-rar-16.02+really25.00+ds/C/var_mac_x64.mak --- p7zip-rar-16.02/C/var_mac_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/var_mac_x64.mak 2021-04-28 11:26:18.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/m_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-arch x86_64 +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/C/warn_clang.mak p7zip-rar-16.02+really25.00+ds/C/warn_clang.mak --- p7zip-rar-16.02/C/warn_clang.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/warn_clang.mak 2023-05-06 05:00:00.000000000 +0000 @@ -0,0 +1 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors diff -Nru p7zip-rar-16.02/C/warn_clang_mac.mak p7zip-rar-16.02+really25.00+ds/C/warn_clang_mac.mak --- p7zip-rar-16.02/C/warn_clang_mac.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/warn_clang_mac.mak 2023-05-03 13:00:00.000000000 +0000 @@ -0,0 +1 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors -Wno-poison-system-directories diff -Nru p7zip-rar-16.02/C/warn_gcc.mak p7zip-rar-16.02+really25.00+ds/C/warn_gcc.mak --- p7zip-rar-16.02/C/warn_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/C/warn_gcc.mak 2021-05-31 17:50:54.000000000 +0000 @@ -0,0 +1,51 @@ +CFLAGS_WARN_GCC_4_5 = \ + +CFLAGS_WARN_GCC_6 = \ + -Waddress \ + -Waggressive-loop-optimizations \ + -Wattributes \ + -Wbool-compare \ + -Wcast-align \ + -Wcomment \ + -Wdiv-by-zero \ + -Wduplicated-cond \ + -Wformat-contains-nul \ + -Winit-self \ + -Wint-to-pointer-cast \ + -Wunused \ + -Wunused-macros \ + +# -Wno-strict-aliasing + +CFLAGS_WARN_GCC_9 = \ + -Waddress \ + -Waddress-of-packed-member \ + -Waggressive-loop-optimizations \ + -Wattributes \ + -Wbool-compare \ + -Wbool-operation \ + -Wcast-align \ + -Wcast-align=strict \ + -Wcomment \ + -Wdangling-else \ + -Wdiv-by-zero \ + -Wduplicated-branches \ + -Wduplicated-cond \ + -Wformat-contains-nul \ + -Wimplicit-fallthrough=5 \ + -Winit-self \ + -Wint-in-bool-context \ + -Wint-to-pointer-cast \ + -Wunused \ + -Wunused-macros \ + -Wconversion \ + +# -Wno-sign-conversion \ + +CFLAGS_WARN_GCC_PPMD_UNALIGNED = \ + -Wno-strict-aliasing \ + + +CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) \ + +# $(CFLAGS_WARN_GCC_PPMD_UNALIGNED) diff -Nru p7zip-rar-16.02/CPP/7zip/7zip.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip.mak --- p7zip-rar-16.02/CPP/7zip/7zip.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip.mak 2024-01-29 08:00:00.000000000 +0000 @@ -0,0 +1,240 @@ +OBJS = \ + $O\StdAfx.obj \ + $(CURRENT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $(CONSOLE_OBJS) \ + $(EXPLORER_OBJS) \ + $(FM_OBJS) \ + $(GUI_OBJS) \ + $(AR_COMMON_OBJS) \ + $(AR_OBJS) \ + $(7Z_OBJS) \ + $(CAB_OBJS) \ + $(CHM_OBJS) \ + $(COM_OBJS) \ + $(ISO_OBJS) \ + $(NSIS_OBJS) \ + $(RAR_OBJS) \ + $(TAR_OBJS) \ + $(UDF_OBJS) \ + $(WIM_OBJS) \ + $(ZIP_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(C_OBJS) \ + $(ASM_OBJS) \ + $O\resource.res \ + +!include "../../../Build.mak" + +# MAK_SINGLE_FILE = 1 + +!IFDEF MAK_SINGLE_FILE + +!IFDEF CURRENT_OBJS +$(CURRENT_OBJS): ./$(*B).cpp + $(COMPL) +!ENDIF + + +!IFDEF COMMON_OBJS +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF WIN_OBJS +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF WIN_CTRL_OBJS +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF 7ZIP_COMMON_OBJS +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF AR_OBJS +$(AR_OBJS): ../../Archive/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF AR_COMMON_OBJS +$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF 7Z_OBJS +$(7Z_OBJS): ../../Archive/7z/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF CAB_OBJS +$(CAB_OBJS): ../../Archive/Cab/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF CHM_OBJS +$(CHM_OBJS): ../../Archive/Chm/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF COM_OBJS +$(COM_OBJS): ../../Archive/Com/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF ISO_OBJS +$(ISO_OBJS): ../../Archive/Iso/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF NSIS_OBJS +$(NSIS_OBJS): ../../Archive/Nsis/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF RAR_OBJS +$(RAR_OBJS): ../../Archive/Rar/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF TAR_OBJS +$(TAR_OBJS): ../../Archive/Tar/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF UDF_OBJS +$(UDF_OBJS): ../../Archive/Udf/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF WIM_OBJS +$(WIM_OBJS): ../../Archive/Wim/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF ZIP_OBJS +$(ZIP_OBJS): ../../Archive/Zip/$(*B).cpp + $(COMPL) $(ZIP_FLAGS) +!ENDIF + +!IFDEF COMPRESS_OBJS +$(COMPRESS_OBJS): ../../Compress/$(*B).cpp + $(COMPL_O2) +!ENDIF + +!IFDEF CRYPTO_OBJS +$(CRYPTO_OBJS): ../../Crypto/$(*B).cpp + $(COMPL_O2) +!ENDIF + +!IFDEF UI_COMMON_OBJS +$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF AGENT_OBJS +$(AGENT_OBJS): ../../UI/Agent/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF CONSOLE_OBJS +$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp + $(COMPL) $(CONSOLE_VARIANT_FLAGS) +!ENDIF + +!IFDEF EXPLORER_OBJS +$(EXPLORER_OBJS): ../../UI/Explorer/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF FM_OBJS +$(FM_OBJS): ../../UI/FileManager/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF GUI_OBJS +$(GUI_OBJS): ../../UI/GUI/$(*B).cpp + $(COMPL) +!ENDIF + +!IFDEF C_OBJS +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) +!ENDIF + + +!ELSE + +{.}.cpp{$O}.obj:: + $(COMPLB) +{../../../Common}.cpp{$O}.obj:: + $(COMPLB) +{../../../Windows}.cpp{$O}.obj:: + $(COMPLB) +{../../../Windows/Control}.cpp{$O}.obj:: + $(COMPLB) +{../../Common}.cpp{$O}.obj:: + $(COMPLB) + +{../../UI/Common}.cpp{$O}.obj:: + $(COMPLB) +{../../UI/Agent}.cpp{$O}.obj:: + $(COMPLB) +{../../UI/Console}.cpp{$O}.obj:: + $(COMPLB) $(CONSOLE_VARIANT_FLAGS) +{../../UI/Explorer}.cpp{$O}.obj:: + $(COMPLB) +{../../UI/FileManager}.cpp{$O}.obj:: + $(COMPLB) +{../../UI/GUI}.cpp{$O}.obj:: + $(COMPLB) + + +{../../Archive}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Common}.cpp{$O}.obj:: + $(COMPLB) + +{../../Archive/7z}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Cab}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Chm}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Com}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Iso}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Nsis}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Rar}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Tar}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Udf}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Wim}.cpp{$O}.obj:: + $(COMPLB) +{../../Archive/Zip}.cpp{$O}.obj:: + $(COMPLB) $(ZIP_FLAGS) + +{../../Compress}.cpp{$O}.obj:: + $(COMPLB_O2) +{../../Crypto}.cpp{$O}.obj:: + $(COMPLB_O2) +{../../../../C}.c{$O}.obj:: + $(CCOMPLB) + +!ENDIF + +!include "Asm.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/7zip_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip_gcc.mak --- p7zip-rar-16.02/CPP/7zip/7zip_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/7zip_gcc.mak 2025-07-02 05:00:00.000000000 +0000 @@ -0,0 +1,1370 @@ +# USE_CLANG=1 +# USE_ASM = 1 +# IS_X64 = 1 +# MY_ARCH = +# USE_ASM= +# USE_JWASM=1 + +MY_ARCH_2 = $(MY_ARCH) + +MY_ASM = asmc +ifdef USE_JWASM +MY_ASM = jwasm +endif + +ifndef RC +RC=windres.exe --target=pe-x86-64 +RC=windres.exe -F pe-i386 +RC=windres.exe +endif + + +PROGPATH = $(O)/$(PROG) +PROGPATH_STATIC = $(O)/$(PROG)s + + +ifneq ($(CC), xlc) +CFLAGS_WARN_WALL = -Werror -Wall -Wextra +endif + +# for object file +# -Wa,-aln=test.s +# -save-temps +FLAGS_BASE = -mbranch-protection=standard -march=armv8.5-a +FLAGS_BASE = -mbranch-protection=standard +FLAGS_BASE = +# FLAGS_BASE = -DZ7_NO_UNICODE + +CFLAGS_BASE_LIST = -c + + +#DEBUG_BUILD=1 + +ifdef DEBUG_BUILD +CFLAGS_DEBUG = -g +else +CFLAGS_DEBUG = -DNDEBUG +ifneq ($(CC), $(CROSS_COMPILE)clang) +LFLAGS_STRIP = -s +endif +endif + +# CFLAGS_BASE_LIST = -S +CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \ + $(CFLAGS_DEBUG) -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ + -fPIC + +FLAGS_FLTO = -ffunction-sections +FLAGS_FLTO = -flto +FLAGS_FLTO = $(FLAGS_BASE) +# -DZ7_AFFINITY_DISABLE + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef IS_MINGW +LDFLAGS_STATIC_2 = -static +else +ifndef DEF_FILE +ifndef IS_NOT_STANDALONE +ifndef MY_DYNAMIC_LINK +ifneq ($(CC), clang) +LDFLAGS_STATIC_2 = +# -static +# -static-libstdc++ -static-libgcc +endif +endif +endif +endif +endif + +LDFLAGS_STATIC = $(CFLAGS_DEBUG) $(LDFLAGS_STATIC_2) $(LDFLAGS_STATIC_3) + +ifndef O + ifdef IS_MINGW + O=_o + else + O=_o + endif +endif + + +ifdef DEF_FILE + + +ifdef IS_MINGW +SHARED_EXT=.dll +LDFLAGS = -shared -DEF $(DEF_FILE) $(LDFLAGS_STATIC) +else +SHARED_EXT=.so +LDFLAGS = -shared -fPIC $(LDFLAGS_STATIC) +CC_SHARED=-fPIC +endif + + +else + +LDFLAGS = $(LDFLAGS_STATIC) +# -z force-bti +# -s is not required for clang, do we need it for GCC ??? + +#-static -static-libgcc -static-libstdc++ + +ifdef IS_MINGW +SHARED_EXT=.exe +else +SHARED_EXT= +endif + +endif + + +PROGPATH = $(O)/$(PROG)$(SHARED_EXT) +PROGPATH_STATIC = $(O)/$(PROG)s$(SHARED_EXT) + +ifdef IS_MINGW + +ifdef MSYSTEM +RM = rm -f +MY_MKDIR=mkdir -p +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) +LIB_HTMLHELP=-lhtmlhelp +else +RM = del +MY_MKDIR=mkdir +DEL_OBJ_EXE = -$(RM) $(O)\*.o $(O)\$(PROG).exe $(O)\$(PROG).dll +endif + +LIB2_GUI = -lOle32 -lGdi32 -lComctl32 -lComdlg32 -lShell32 $(LIB_HTMLHELP) +LIB2 = -loleaut32 -luuid -ladvapi32 -lUser32 $(LIB2_GUI) + +# v24.00: -DUNICODE and -D_UNICODE are defined in precompilation header files +# CXXFLAGS_EXTRA = -DUNICODE -D_UNICODE +# -Wno-delete-non-virtual-dtor + + +else + +RM = rm -f +MY_MKDIR=mkdir -p +DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS) + +# CFLAGS_BASE := $(CFLAGS_BASE) -DZ7_ST +# CXXFLAGS_EXTRA = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE + +# LOCAL_LIBS=-lpthread +# LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl +LIB2 = -lpthread +LIB2 = -lpthread -ldl + + +endif + + + +CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CC_SHARED) -o $@ + + +ifdef IS_MINGW + +ifdef IS_X64 +AFLAGS_ABI = -win64 +else +AFLAGS_ABI = -coff -DABI_CDECL +# -DABI_CDECL +# -DABI_LINUX +# -DABI_CDECL +endif +AFLAGS = -nologo $(AFLAGS_ABI) -Fo$(O)/$(basename $(/dev/null && echo -z noexecstack || echo) +endif + +endif + + +LFLAGS_ALL = $(LFLAGS_STRIP) $(MY_ARCH_2) $(LDFLAGS) $(FLAGS_FLTO) $(LD_arch) $(LFLAGS_NOEXECSTACK) $(OBJS) $(MY_LIBS) $(LIB2) + +# -s : GCC : Remove all symbol table and relocation information from the executable. +# -s : CLANG : unsupported +# -s + +$(PROGPATH): $(OBJS) + $(CXX) -o $(PROGPATH) $(LFLAGS_ALL) + +$(PROGPATH_STATIC): $(OBJS) + $(CXX) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL) + +# -s strips debug sections from executable in GCC + + + + +ifndef NO_DEFAULT_RES +$O/resource.o: resource.rc + $(RC) $(RFLAGS) resource.rc $@ + +# windres.exe : in old version mingw: +# $(RFLAGS) resource.rc $O/resource.o +# windres.exe : in new version mingw: +# $(RC) $(RFLAGS) resource.rc -FO $@ + + +endif + +$O/LzmaAlone.o: LzmaAlone.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CommandLineParser.o: ../../../Common/CommandLineParser.cpp + $(CXX) $(CXXFLAGS) $< +$O/CRC.o: ../../../Common/CRC.cpp + $(CXX) $(CXXFLAGS) $< + +$O/CrcReg.o: ../../../Common/CrcReg.cpp + $(CXX) $(CXXFLAGS) $< + +$O/DynLimBuf.o: ../../../Common/DynLimBuf.cpp + $(CXX) $(CXXFLAGS) $< +$O/IntToString.o: ../../../Common/IntToString.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lang.o: ../../../Common/Lang.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Md5Reg.o: ../../../Common/Md5Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyMap.o: ../../../Common/MyMap.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyString.o: ../../../Common/MyString.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyVector.o: ../../../Common/MyVector.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyWindows.o: ../../../Common/MyWindows.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyWindows2.o: ../../../Common/MyWindows2.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyXml.o: ../../../Common/MyXml.cpp + $(CXX) $(CXXFLAGS) $< +$O/NewHandler.o: ../../../Common/NewHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Random.o: ../../../Common/Random.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha1Prepare.o: ../../../Common/Sha1Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha1Reg.o: ../../../Common/Sha1Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha256Prepare.o: ../../../Common/Sha256Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha3Reg.o: ../../../Common/Sha3Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Prepare.o: ../../../Common/Sha512Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Reg.o: ../../../Common/Sha512Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/StdInStream.o: ../../../Common/StdInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/StdOutStream.o: ../../../Common/StdOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringConvert.o: ../../../Common/StringConvert.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringToInt.o: ../../../Common/StringToInt.cpp + $(CXX) $(CXXFLAGS) $< +$O/TextConfig.o: ../../../Common/TextConfig.cpp + $(CXX) $(CXXFLAGS) $< +$O/UTFConvert.o: ../../../Common/UTFConvert.cpp + $(CXX) $(CXXFLAGS) $< +$O/Wildcard.o: ../../../Common/Wildcard.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzCrc64Init.o: ../../../Common/XzCrc64Init.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzCrc64Reg.o: ../../../Common/XzCrc64Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Xxh64Reg.o: ../../../Common/Xxh64Reg.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/Clipboard.o: ../../../Windows/Clipboard.cpp + $(CXX) $(CXXFLAGS) $< +$O/COM.o: ../../../Windows/COM.cpp + $(CXX) $(CXXFLAGS) $< +$O/CommonDialog.o: ../../../Windows/CommonDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/Console.o: ../../../Windows/Console.cpp + $(CXX) $(CXXFLAGS) $< +$O/DLL.o: ../../../Windows/DLL.cpp + $(CXX) $(CXXFLAGS) $< +$O/ErrorMsg.o: ../../../Windows/ErrorMsg.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileDir.o: ../../../Windows/FileDir.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileFind.o: ../../../Windows/FileFind.cpp + $(CXX) $(CXXFLAGS) $< + +$O/FileIO.o: ../../../Windows/FileIO.cpp + $(CXX) $(CXXFLAGS) $< + +$O/FileLink.o: ../../../Windows/FileLink.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileMapping.o: ../../../Windows/FileMapping.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileName.o: ../../../Windows/FileName.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileSystem.o: ../../../Windows/FileSystem.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemoryGlobal.o: ../../../Windows/MemoryGlobal.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemoryLock.o: ../../../Windows/MemoryLock.cpp + $(CXX) $(CXXFLAGS) $< +$O/Menu.o: ../../../Windows/Menu.cpp + $(CXX) $(CXXFLAGS) $< +$O/NationalTime.o: ../../../Windows/NationalTime.cpp + $(CXX) $(CXXFLAGS) $< +$O/Net.o: ../../../Windows/Net.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProcessMessages.o: ../../../Windows/ProcessMessages.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProcessUtils.o: ../../../Windows/ProcessUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariant.o: ../../../Windows/PropVariant.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariantConv.o: ../../../Windows/PropVariantConv.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropVariantUtils.o: ../../../Windows/PropVariantUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Registry.o: ../../../Windows/Registry.cpp + $(CXX) $(CXXFLAGS) $< +$O/ResourceString.o: ../../../Windows/ResourceString.cpp + $(CXX) $(CXXFLAGS) $< +$O/SecurityUtils.o: ../../../Windows/SecurityUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Shell.o: ../../../Windows/Shell.cpp + $(CXX) $(CXXFLAGS) $< +$O/Synchronization.o: ../../../Windows/Synchronization.cpp + $(CXX) $(CXXFLAGS) $< +$O/System.o: ../../../Windows/System.cpp + $(CXX) $(CXXFLAGS) $< +$O/SystemInfo.o: ../../../Windows/SystemInfo.cpp + $(CXX) $(CXXFLAGS) $< +$O/TimeUtils.o: ../../../Windows/TimeUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/Window.o: ../../../Windows/Window.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/ComboBox.o: ../../../Windows/Control/ComboBox.cpp + $(CXX) $(CXXFLAGS) $< +$O/Dialog.o: ../../../Windows/Control/Dialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImageList.o: ../../../Windows/Control/ImageList.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListView.o: ../../../Windows/Control/ListView.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropertyPage.o: ../../../Windows/Control/PropertyPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/Window2.o: ../../../Windows/Control/Window2.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CreateCoder.o: ../../Common/CreateCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/CWrappers.o: ../../Common/CWrappers.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilePathAutoRename.o: ../../Common/FilePathAutoRename.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileStreams.o: ../../Common/FileStreams.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilterCoder.o: ../../Common/FilterCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/InBuffer.o: ../../Common/InBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/InOutTempBuffer.o: ../../Common/InOutTempBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/LimitedStreams.o: ../../Common/LimitedStreams.cpp + $(CXX) $(CXXFLAGS) $< +$O/LockedStream.o: ../../Common/LockedStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemBlocks.o: ../../Common/MemBlocks.cpp + $(CXX) $(CXXFLAGS) $< +$O/MethodId.o: ../../Common/MethodId.cpp + $(CXX) $(CXXFLAGS) $< +$O/MethodProps.o: ../../Common/MethodProps.cpp + $(CXX) $(CXXFLAGS) $< +$O/MultiOutStream.o: ../../Common/MultiOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OffsetStream.o: ../../Common/OffsetStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutBuffer.o: ../../Common/OutBuffer.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutMemStream.o: ../../Common/OutMemStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressMt.o: ../../Common/ProgressMt.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressUtils.o: ../../Common/ProgressUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropId.o: ../../Common/PropId.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamBinder.o: ../../Common/StreamBinder.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamObjects.o: ../../Common/StreamObjects.cpp + $(CXX) $(CXXFLAGS) $< +$O/StreamUtils.o: ../../Common/StreamUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/UniqBlocks.o: ../../Common/UniqBlocks.cpp + $(CXX) $(CXXFLAGS) $< +$O/VirtThread.o: ../../Common/VirtThread.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ApfsHandler.o: ../../Archive/ApfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ApmHandler.o: ../../Archive/ApmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveExports.o: ../../Archive/ArchiveExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArHandler.o: ../../Archive/ArHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArjHandler.o: ../../Archive/ArjHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/AvbHandler.o: ../../Archive/AvbHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Base64Handler.o: ../../Archive/Base64Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bz2Handler.o: ../../Archive/Bz2Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ComHandler.o: ../../Archive/ComHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CpioHandler.o: ../../Archive/CpioHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CramfsHandler.o: ../../Archive/CramfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateProps.o: ../../Archive/DeflateProps.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports.o: ../../Archive/DllExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports2.o: ../../Archive/DllExports2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DmgHandler.o: ../../Archive/DmgHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ElfHandler.o: ../../Archive/ElfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtHandler.o: ../../Archive/ExtHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/FatHandler.o: ../../Archive/FatHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/FlvHandler.o: ../../Archive/FlvHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/GptHandler.o: ../../Archive/GptHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/GzHandler.o: ../../Archive/GzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/HandlerCont.o: ../../Archive/HandlerCont.cpp + $(CXX) $(CXXFLAGS) $< +$O/HfsHandler.o: ../../Archive/HfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/IhexHandler.o: ../../Archive/IhexHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LpHandler.o: ../../Archive/LpHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LvmHandler.o: ../../Archive/LvmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzhHandler.o: ../../Archive/LzhHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaHandler.o: ../../Archive/LzmaHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MachoHandler.o: ../../Archive/MachoHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MbrHandler.o: ../../Archive/MbrHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MslzHandler.o: ../../Archive/MslzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/MubHandler.o: ../../Archive/MubHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/NtfsHandler.o: ../../Archive/NtfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/PeHandler.o: ../../Archive/PeHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdHandler.o: ../../Archive/PpmdHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/QcowHandler.o: ../../Archive/QcowHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/RpmHandler.o: ../../Archive/RpmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SparseHandler.o: ../../Archive/SparseHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitHandler.o: ../../Archive/SplitHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SquashfsHandler.o: ../../Archive/SquashfsHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/SwfHandler.o: ../../Archive/SwfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/UefiHandler.o: ../../Archive/UefiHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VdiHandler.o: ../../Archive/VdiHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VhdHandler.o: ../../Archive/VhdHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VhdxHandler.o: ../../Archive/VhdxHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/VmdkHandler.o: ../../Archive/VmdkHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/XarHandler.o: ../../Archive/XarHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzHandler.o: ../../Archive/XzHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZHandler.o: ../../Archive/ZHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZstdHandler.o: ../../Archive/ZstdHandler.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/7zCompressionMode.o: ../../Archive/7z/7zCompressionMode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zDecode.o: ../../Archive/7z/7zDecode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zEncode.o: ../../Archive/7z/7zEncode.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zExtract.o: ../../Archive/7z/7zExtract.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zFolderInStream.o: ../../Archive/7z/7zFolderInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHandler.o: ../../Archive/7z/7zHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHandlerOut.o: ../../Archive/7z/7zHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zHeader.o: ../../Archive/7z/7zHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zIn.o: ../../Archive/7z/7zIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zOut.o: ../../Archive/7z/7zOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zProperties.o: ../../Archive/7z/7zProperties.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zRegister.o: ../../Archive/7z/7zRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zSpecStream.o: ../../Archive/7z/7zSpecStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zUpdate.o: ../../Archive/7z/7zUpdate.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/CabBlockInStream.o: ../../Archive/Cab/CabBlockInStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabHandler.o: ../../Archive/Cab/CabHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabHeader.o: ../../Archive/Cab/CabHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabIn.o: ../../Archive/Cab/CabIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/CabRegister.o: ../../Archive/Cab/CabRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ChmHandler.o: ../../Archive/Chm/ChmHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/ChmIn.o: ../../Archive/Chm/ChmIn.cpp + $(CXX) $(CXXFLAGS) $< + +$O/IsoHandler.o: ../../Archive/Iso/IsoHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoHeader.o: ../../Archive/Iso/IsoHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoIn.o: ../../Archive/Iso/IsoIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/IsoRegister.o: ../../Archive/Iso/IsoRegister.cpp + $(CXX) $(CXXFLAGS) $< + +$O/NsisDecode.o: ../../Archive/Nsis/NsisDecode.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisHandler.o: ../../Archive/Nsis/NsisHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisIn.o: ../../Archive/Nsis/NsisIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/NsisRegister.o: ../../Archive/Nsis/NsisRegister.cpp + $(CXX) $(CXXFLAGS) $< + +$O/Rar5Handler.o: ../../Archive/Rar/Rar5Handler.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarHandler.o: ../../Archive/Rar/RarHandler.cpp + $(CXX) $(CXXFLAGS) $< + +$O/TarHandler.o: ../../Archive/Tar/TarHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarHandlerOut.o: ../../Archive/Tar/TarHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarHeader.o: ../../Archive/Tar/TarHeader.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarIn.o: ../../Archive/Tar/TarIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarOut.o: ../../Archive/Tar/TarOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarRegister.o: ../../Archive/Tar/TarRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/TarUpdate.o: ../../Archive/Tar/TarUpdate.cpp + $(CXX) $(CXXFLAGS) $< + +$O/UdfHandler.o: ../../Archive/Udf/UdfHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/UdfIn.o: ../../Archive/Udf/UdfIn.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/WimHandler.o: ../../Archive/Wim/WimHandler.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimHandlerOut.o: ../../Archive/Wim/WimHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimIn.o: ../../Archive/Wim/WimIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/WimRegister.o: ../../Archive/Wim/WimRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/ZipAddCommon.o: ../../Archive/Zip/ZipAddCommon.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipHandler.o: ../../Archive/Zip/ZipHandler.cpp + $(CXX) $(CXXFLAGS) $(ZIP_FLAGS) $< +$O/ZipHandlerOut.o: ../../Archive/Zip/ZipHandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipIn.o: ../../Archive/Zip/ZipIn.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipItem.o: ../../Archive/Zip/ZipItem.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipOut.o: ../../Archive/Zip/ZipOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipUpdate.o: ../../Archive/Zip/ZipUpdate.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipRegister.o: ../../Archive/Zip/ZipRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Bcj2Coder.o: ../../Compress/Bcj2Coder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bcj2Register.o: ../../Compress/Bcj2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/BcjCoder.o: ../../Compress/BcjCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BcjRegister.o: ../../Compress/BcjRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/BitlDecoder.o: ../../Compress/BitlDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BranchMisc.o: ../../Compress/BranchMisc.cpp + $(CXX) $(CXXFLAGS) $< +$O/BranchRegister.o: ../../Compress/BranchRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/ByteSwap.o: ../../Compress/ByteSwap.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Crc.o: ../../Compress/BZip2Crc.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Decoder.o: ../../Compress/BZip2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Encoder.o: ../../Compress/BZip2Encoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/BZip2Register.o: ../../Compress/BZip2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/CodecExports.o: ../../Compress/CodecExports.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyCoder.o: ../../Compress/CopyCoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyRegister.o: ../../Compress/CopyRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/Deflate64Register.o: ../../Compress/Deflate64Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateDecoder.o: ../../Compress/DeflateDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateEncoder.o: ../../Compress/DeflateEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeflateRegister.o: ../../Compress/DeflateRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/DeltaFilter.o: ../../Compress/DeltaFilter.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExports2Compress.o: ../../Compress/DllExports2Compress.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExportsCompress.o: ../../Compress/DllExportsCompress.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImplodeDecoder.o: ../../Compress/ImplodeDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ImplodeHuffmanDecoder.o: ../../Compress/ImplodeHuffmanDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzfseDecoder.o: ../../Compress/LzfseDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzhDecoder.o: ../../Compress/LzhDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Decoder.o: ../../Compress/Lzma2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Encoder.o: ../../Compress/Lzma2Encoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Lzma2Register.o: ../../Compress/Lzma2Register.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaDecoder.o: ../../Compress/LzmaDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaEncoder.o: ../../Compress/LzmaEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmaRegister.o: ../../Compress/LzmaRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzmsDecoder.o: ../../Compress/LzmsDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzOutWindow.o: ../../Compress/LzOutWindow.cpp + $(CXX) $(CXXFLAGS) $< +$O/LzxDecoder.o: ../../Compress/LzxDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdDecoder.o: ../../Compress/PpmdDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdEncoder.o: ../../Compress/PpmdEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdRegister.o: ../../Compress/PpmdRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/PpmdZip.o: ../../Compress/PpmdZip.cpp + $(CXX) $(CXXFLAGS) $< +$O/QuantumDecoder.o: ../../Compress/QuantumDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar1Decoder.o: ../../Compress/Rar1Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar2Decoder.o: ../../Compress/Rar2Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar3Decoder.o: ../../Compress/Rar3Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar3Vm.o: ../../Compress/Rar3Vm.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar5Decoder.o: ../../Compress/Rar5Decoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarCodecsRegister.o: ../../Compress/RarCodecsRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/ShrinkDecoder.o: ../../Compress/ShrinkDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XpressDecoder.o: ../../Compress/XpressDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzDecoder.o: ../../Compress/XzDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/XzEncoder.o: ../../Compress/XzEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZDecoder.o: ../../Compress/ZDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZlibDecoder.o: ../../Compress/ZlibDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZlibEncoder.o: ../../Compress/ZlibEncoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZstdDecoder.o: ../../Compress/ZstdDecoder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZstdRegister.o: ../../Compress/ZstdRegister.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/7zAes.o: ../../Crypto/7zAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/7zAesRegister.o: ../../Crypto/7zAesRegister.cpp + $(CXX) $(CXXFLAGS) $< +$O/HmacSha1.o: ../../Crypto/HmacSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/HmacSha256.o: ../../Crypto/HmacSha256.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyAes.o: ../../Crypto/MyAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyAesReg.o: ../../Crypto/MyAesReg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Pbkdf2HmacSha1.o: ../../Crypto/Pbkdf2HmacSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/RandGen.o: ../../Crypto/RandGen.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar20Crypto.o: ../../Crypto/Rar20Crypto.cpp + $(CXX) $(CXXFLAGS) $< +$O/Rar5Aes.o: ../../Crypto/Rar5Aes.cpp + $(CXX) $(CXXFLAGS) $< +$O/RarAes.o: ../../Crypto/RarAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/WzAes.o: ../../Crypto/WzAes.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipCrypto.o: ../../Crypto/ZipCrypto.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipStrong.o: ../../Crypto/ZipStrong.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/CoderMixer2.o: ../../Archive/Common/CoderMixer2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DummyOutStream.o: ../../Archive/Common/DummyOutStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/FindSignature.o: ../../Archive/Common/FindSignature.cpp + $(CXX) $(CXXFLAGS) $< +$O/HandlerOut.o: ../../Archive/Common/HandlerOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/InStreamWithCRC.o: ../../Archive/Common/InStreamWithCRC.cpp + $(CXX) $(CXXFLAGS) $< +$O/ItemNameUtils.o: ../../Archive/Common/ItemNameUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/MultiStream.o: ../../Archive/Common/MultiStream.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutStreamWithCRC.o: ../../Archive/Common/OutStreamWithCRC.cpp + $(CXX) $(CXXFLAGS) $< +$O/OutStreamWithSha1.o: ../../Archive/Common/OutStreamWithSha1.cpp + $(CXX) $(CXXFLAGS) $< +$O/ParseProperties.o: ../../Archive/Common/ParseProperties.cpp + $(CXX) $(CXXFLAGS) $< + + + + +$O/ArchiveCommandLine.o: ../../UI/Common/ArchiveCommandLine.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveExtractCallback.o: ../../UI/Common/ArchiveExtractCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveName.o: ../../UI/Common/ArchiveName.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveOpenCallback.o: ../../UI/Common/ArchiveOpenCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/Bench.o: ../../UI/Common/Bench.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressCall.o: ../../UI/Common/CompressCall.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressCall2.o: ../../UI/Common/CompressCall2.cpp + $(CXX) $(CXXFLAGS) $< +$O/DefaultName.o: ../../UI/Common/DefaultName.cpp + $(CXX) $(CXXFLAGS) $< +$O/EnumDirItems.o: ../../UI/Common/EnumDirItems.cpp + $(CXX) $(CXXFLAGS) $< +$O/Extract.o: ../../UI/Common/Extract.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractingFilePath.o: ../../UI/Common/ExtractingFilePath.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashCalc.o: ../../UI/Common/HashCalc.cpp + $(CXX) $(CXXFLAGS) $< +$O/LoadCodecs.o: ../../UI/Common/LoadCodecs.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenArchive.o: ../../UI/Common/OpenArchive.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropIDUtils.o: ../../UI/Common/PropIDUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SetProperties.o: ../../UI/Common/SetProperties.cpp + $(CXX) $(CXXFLAGS) $< +$O/SortUtils.o: ../../UI/Common/SortUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/TempFiles.o: ../../UI/Common/TempFiles.cpp + $(CXX) $(CXXFLAGS) $< +$O/Update.o: ../../UI/Common/Update.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateAction.o: ../../UI/Common/UpdateAction.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallback.o: ../../UI/Common/UpdateCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdatePair.o: ../../UI/Common/UpdatePair.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateProduce.o: ../../UI/Common/UpdateProduce.cpp + $(CXX) $(CXXFLAGS) $< +$O/WorkDir.o: ../../UI/Common/WorkDir.cpp + $(CXX) $(CXXFLAGS) $< +$O/ZipRegistry.o: ../../UI/Common/ZipRegistry.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Agent.o: ../../UI/Agent/Agent.cpp + $(CXX) $(CXXFLAGS) $< +$O/AgentOut.o: ../../UI/Agent/AgentOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/AgentProxy.o: ../../UI/Agent/AgentProxy.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolder.o: ../../UI/Agent/ArchiveFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolderOpen.o: ../../UI/Agent/ArchiveFolderOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/ArchiveFolderOut.o: ../../UI/Agent/ArchiveFolderOut.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackAgent.o: ../../UI/Agent/UpdateCallbackAgent.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/Client7z.o: ../../UI/Client7z/Client7z.cpp + $(CXX) $(CXXFLAGS) $< + + +$O/BenchCon.o: ../../UI/Console/BenchCon.cpp + $(CXX) $(CXXFLAGS) $< +$O/ConsoleClose.o: ../../UI/Console/ConsoleClose.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractCallbackConsole.o: ../../UI/Console/ExtractCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashCon.o: ../../UI/Console/HashCon.cpp + $(CXX) $(CXXFLAGS) $< +$O/List.o: ../../UI/Console/List.cpp + $(CXX) $(CXXFLAGS) $< +$O/Main.o: ../../UI/Console/Main.cpp ../../../../C/7zVersion.h + $(CXX) $(CXXFLAGS) $(CONSOLE_VARIANT_FLAGS) $(CONSOLE_ASM_FLAGS) $< +$O/MainAr.o: ../../UI/Console/MainAr.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenCallbackConsole.o: ../../UI/Console/OpenCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/PercentPrinter.o: ../../UI/Console/PercentPrinter.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackConsole.o: ../../UI/Console/UpdateCallbackConsole.cpp + $(CXX) $(CXXFLAGS) $< +$O/UserInputUtils.o: ../../UI/Console/UserInputUtils.cpp + $(CXX) $(CXXFLAGS) $< + +$O/BenchmarkDialog.o: ../../UI/GUI/BenchmarkDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/CompressDialog.o: ../../UI/GUI/CompressDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractDialog.o: ../../UI/GUI/ExtractDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractGUI.o: ../../UI/GUI/ExtractGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/GUI.o: ../../UI/GUI/GUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/HashGUI.o: ../../UI/GUI/HashGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackGUI.o: ../../UI/GUI/UpdateCallbackGUI.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallbackGUI2.o: ../../UI/GUI/UpdateCallbackGUI2.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateGUI.o: ../../UI/GUI/UpdateGUI.cpp + $(CXX) $(CXXFLAGS) $< + +$O/MyMessages.o: ../../UI/Explorer/MyMessages.cpp + $(CXX) $(CXXFLAGS) $< +$O/ContextMenu.o: ../../UI/Explorer/ContextMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/DllExportsExplorer.o: ../../UI/Explorer/DllExportsExplorer.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryContextMenu.o: ../../UI/Explorer/RegistryContextMenu.cpp + $(CXX) $(CXXFLAGS) $< + + + +$O/AboutDialog.o: ../../UI/FileManager/AboutDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/AltStreamsFolder.o: ../../UI/FileManager/AltStreamsFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/App.o: ../../UI/FileManager/App.cpp + $(CXX) $(CXXFLAGS) $< +$O/BrowseDialog.o: ../../UI/FileManager/BrowseDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/BrowseDialog2.o: ../../UI/FileManager/BrowseDialog2.cpp + $(CXX) $(CXXFLAGS) $< +$O/ClassDefs.o: ../../UI/FileManager/ClassDefs.cpp + $(CXX) $(CXXFLAGS) $< +$O/ComboDialog.o: ../../UI/FileManager/ComboDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/CopyDialog.o: ../../UI/FileManager/CopyDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/EditDialog.o: ../../UI/FileManager/EditDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/EditPage.o: ../../UI/FileManager/EditPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/EnumFormatEtc.o: ../../UI/FileManager/EnumFormatEtc.cpp + $(CXX) $(CXXFLAGS) $< +$O/ExtractCallback.o: ../../UI/FileManager/ExtractCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/FileFolderPluginOpen.o: ../../UI/FileManager/FileFolderPluginOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/FilePlugins.o: ../../UI/FileManager/FilePlugins.cpp + $(CXX) $(CXXFLAGS) $< +$O/FM.o: ../../UI/FileManager/FM.cpp + $(CXX) $(CXXFLAGS) $< +$O/FoldersPage.o: ../../UI/FileManager/FoldersPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/FormatUtils.o: ../../UI/FileManager/FormatUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSDrives.o: ../../UI/FileManager/FSDrives.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSFolder.o: ../../UI/FileManager/FSFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/FSFolderCopy.o: ../../UI/FileManager/FSFolderCopy.cpp + $(CXX) $(CXXFLAGS) $< +$O/HelpUtils.o: ../../UI/FileManager/HelpUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LangPage.o: ../../UI/FileManager/LangPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/LangUtils.o: ../../UI/FileManager/LangUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/LinkDialog.o: ../../UI/FileManager/LinkDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ListViewDialog.o: ../../UI/FileManager/ListViewDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/MemDialog.o: ../../UI/FileManager/MemDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/MenuPage.o: ../../UI/FileManager/MenuPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/MessagesDialog.o: ../../UI/FileManager/MessagesDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/MyLoadMenu.o: ../../UI/FileManager/MyLoadMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/NetFolder.o: ../../UI/FileManager/NetFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/OpenCallback.o: ../../UI/FileManager/OpenCallback.cpp + $(CXX) $(CXXFLAGS) $< +$O/OptionsDialog.o: ../../UI/FileManager/OptionsDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/OverwriteDialog.o: ../../UI/FileManager/OverwriteDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/Panel.o: ../../UI/FileManager/Panel.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelCopy.o: ../../UI/FileManager/PanelCopy.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelCrc.o: ../../UI/FileManager/PanelCrc.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelDrag.o: ../../UI/FileManager/PanelDrag.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelFolderChange.o: ../../UI/FileManager/PanelFolderChange.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelItemOpen.o: ../../UI/FileManager/PanelItemOpen.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelItems.o: ../../UI/FileManager/PanelItems.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelKey.o: ../../UI/FileManager/PanelKey.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelListNotify.o: ../../UI/FileManager/PanelListNotify.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelMenu.o: ../../UI/FileManager/PanelMenu.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelOperations.o: ../../UI/FileManager/PanelOperations.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSelect.o: ../../UI/FileManager/PanelSelect.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSort.o: ../../UI/FileManager/PanelSort.cpp + $(CXX) $(CXXFLAGS) $< +$O/PanelSplitFile.o: ../../UI/FileManager/PanelSplitFile.cpp + $(CXX) $(CXXFLAGS) $< +$O/PasswordDialog.o: ../../UI/FileManager/PasswordDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgramLocation.o: ../../UI/FileManager/ProgramLocation.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressDialog.o: ../../UI/FileManager/ProgressDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/ProgressDialog2.o: ../../UI/FileManager/ProgressDialog2.cpp + $(CXX) $(CXXFLAGS) $< +$O/PropertyName.o: ../../UI/FileManager/PropertyName.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryAssociations.o: ../../UI/FileManager/RegistryAssociations.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryPlugins.o: ../../UI/FileManager/RegistryPlugins.cpp + $(CXX) $(CXXFLAGS) $< +$O/RegistryUtils.o: ../../UI/FileManager/RegistryUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/RootFolder.o: ../../UI/FileManager/RootFolder.cpp + $(CXX) $(CXXFLAGS) $< +$O/SettingsPage.o: ../../UI/FileManager/SettingsPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitDialog.o: ../../UI/FileManager/SplitDialog.cpp + $(CXX) $(CXXFLAGS) $< +$O/SplitUtils.o: ../../UI/FileManager/SplitUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/StringUtils.o: ../../UI/FileManager/StringUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SysIconUtils.o: ../../UI/FileManager/SysIconUtils.cpp + $(CXX) $(CXXFLAGS) $< +$O/SystemPage.o: ../../UI/FileManager/SystemPage.cpp + $(CXX) $(CXXFLAGS) $< +$O/TextPairs.o: ../../UI/FileManager/TextPairs.cpp + $(CXX) $(CXXFLAGS) $< +$O/UpdateCallback100.o: ../../UI/FileManager/UpdateCallback100.cpp + $(CXX) $(CXXFLAGS) $< +$O/VerCtrl.o: ../../UI/FileManager/VerCtrl.cpp + $(CXX) $(CXXFLAGS) $< +$O/ViewSettings.o: ../../UI/FileManager/ViewSettings.cpp + $(CXX) $(CXXFLAGS) $< + +$O/SfxCon.o: ../../Bundles/SFXCon/SfxCon.cpp + $(CXX) $(CXXFLAGS) $< + +$O/$(FILE_IO).o: ../../../$(FILE_IO_2).cpp + $(CXX) $(CXXFLAGS) $< + + + + + + +$O/7zAlloc.o: ../../../../C/7zAlloc.c + $(CC) $(CFLAGS) $< +$O/7zArcIn.o: ../../../../C/7zArcIn.c + $(CC) $(CFLAGS) $< +$O/7zBuf.o: ../../../../C/7zBuf.c + $(CC) $(CFLAGS) $< +$O/7zBuf2.o: ../../../../C/7zBuf2.c + $(CC) $(CFLAGS) $< +$O/7zCrc.o: ../../../../C/7zCrc.c + $(CC) $(CFLAGS) $< +$O/7zDec.o: ../../../../C/7zDec.c + $(CC) $(CFLAGS) $< +$O/7zFile.o: ../../../../C/7zFile.c + $(CC) $(CFLAGS) $< +$O/7zStream.o: ../../../../C/7zStream.c + $(CC) $(CFLAGS) $< +$O/Aes.o: ../../../../C/Aes.c + $(CC) $(CFLAGS) $< +$O/Alloc.o: ../../../../C/Alloc.c + $(CC) $(CFLAGS) $< +$O/Bcj2.o: ../../../../C/Bcj2.c + $(CC) $(CFLAGS) $< +$O/Bcj2Enc.o: ../../../../C/Bcj2Enc.c + $(CC) $(CFLAGS) $< +$O/Blake2s.o: ../../../../C/Blake2s.c + $(CC) $(CFLAGS) $< +$O/Bra.o: ../../../../C/Bra.c + $(CC) $(CFLAGS) $< +$O/Bra86.o: ../../../../C/Bra86.c + $(CC) $(CFLAGS) $< +$O/BraIA64.o: ../../../../C/BraIA64.c + $(CC) $(CFLAGS) $< +$O/BwtSort.o: ../../../../C/BwtSort.c + $(CC) $(CFLAGS) $< + +$O/CpuArch.o: ../../../../C/CpuArch.c + $(CC) $(CFLAGS) $< +$O/Delta.o: ../../../../C/Delta.c + $(CC) $(CFLAGS) $< +$O/DllSecur.o: ../../../../C/DllSecur.c + $(CC) $(CFLAGS) $< +$O/HuffEnc.o: ../../../../C/HuffEnc.c + $(CC) $(CFLAGS) $< +$O/LzFind.o: ../../../../C/LzFind.c + $(CC) $(CFLAGS) $< + +# ifdef MT_FILES +$O/LzFindMt.o: ../../../../C/LzFindMt.c + $(CC) $(CFLAGS) $< + +$O/Threads.o: ../../../../C/Threads.c + $(CC) $(CFLAGS) $< +# endif + +$O/LzmaEnc.o: ../../../../C/LzmaEnc.c + $(CC) $(CFLAGS) $< +$O/Lzma86Dec.o: ../../../../C/Lzma86Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma86Enc.o: ../../../../C/Lzma86Enc.c + $(CC) $(CFLAGS) $< +$O/Lzma2Dec.o: ../../../../C/Lzma2Dec.c + $(CC) $(CFLAGS) $< +$O/Lzma2DecMt.o: ../../../../C/Lzma2DecMt.c + $(CC) $(CFLAGS) $< +$O/Lzma2Enc.o: ../../../../C/Lzma2Enc.c + $(CC) $(CFLAGS) $< +$O/LzmaLib.o: ../../../../C/LzmaLib.c + $(CC) $(CFLAGS) $< +$O/Md5.o: ../../../../C/Md5.c + $(CC) $(CFLAGS) $< +$O/MtCoder.o: ../../../../C/MtCoder.c + $(CC) $(CFLAGS) $< +$O/MtDec.o: ../../../../C/MtDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7.o: ../../../../C/Ppmd7.c + $(CC) $(CFLAGS) $< +$O/Ppmd7aDec.o: ../../../../C/Ppmd7aDec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Dec.o: ../../../../C/Ppmd7Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd7Enc.o: ../../../../C/Ppmd7Enc.c + $(CC) $(CFLAGS) $< +$O/Ppmd8.o: ../../../../C/Ppmd8.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Dec.o: ../../../../C/Ppmd8Dec.c + $(CC) $(CFLAGS) $< +$O/Ppmd8Enc.o: ../../../../C/Ppmd8Enc.c + $(CC) $(CFLAGS) $< +$O/Sha1.o: ../../../../C/Sha1.c + $(CC) $(CFLAGS) $< +$O/Sha256.o: ../../../../C/Sha256.c + $(CC) $(CFLAGS) $< +$O/Sha3.o: ../../../../C/Sha3.c + $(CC) $(CFLAGS) $< +$O/Sha512.o: ../../../../C/Sha512.c + $(CC) $(CFLAGS) $< +$O/Sha512Opt.o: ../../../../C/Sha512Opt.c + $(CC) $(CFLAGS) $< +$O/SwapBytes.o: ../../../../C/SwapBytes.c + $(CC) $(CFLAGS) $< +$O/Xxh64.o: ../../../../C/Xxh64.c + $(CC) $(CFLAGS) $< +$O/Xz.o: ../../../../C/Xz.c + $(CC) $(CFLAGS) $< +$O/XzCrc64.o: ../../../../C/XzCrc64.c + $(CC) $(CFLAGS) $< +$O/XzDec.o: ../../../../C/XzDec.c + $(CC) $(CFLAGS) $< +$O/XzEnc.o: ../../../../C/XzEnc.c + $(CC) $(CFLAGS) $< +$O/XzIn.o: ../../../../C/XzIn.c + $(CC) $(CFLAGS) $< +$O/ZstdDec.o: ../../../../C/ZstdDec.c + $(CC) $(CFLAGS) $< + + +ifdef USE_ASM +ifdef IS_X64 +USE_X86_ASM=1 +USE_X64_ASM=1 +else +ifdef IS_X86 +USE_X86_ASM=1 +endif +endif +endif + +ifdef USE_X86_ASM +$O/7zCrcOpt.o: ../../../../Asm/x86/7zCrcOpt.asm + $(MY_ASM) $(AFLAGS) $< +$O/XzCrc64Opt.o: ../../../../Asm/x86/XzCrc64Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha1Opt.o: ../../../../Asm/x86/Sha1Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sha256Opt.o: ../../../../Asm/x86/Sha256Opt.asm + $(MY_ASM) $(AFLAGS) $< +$O/Sort.o: ../../../../Asm/x86/Sort.asm + $(MY_ASM) $(AFLAGS) $< + +ifndef USE_JWASM +USE_X86_ASM_AES=1 +endif + +else +$O/7zCrcOpt.o: ../../../../C/7zCrcOpt.c + $(CC) $(CFLAGS) $< +$O/XzCrc64Opt.o: ../../../../C/XzCrc64Opt.c + $(CC) $(CFLAGS) $< +$O/Sha1Opt.o: ../../../../C/Sha1Opt.c + $(CC) $(CFLAGS) $< +$O/Sha256Opt.o: ../../../../C/Sha256Opt.c + $(CC) $(CFLAGS) $< +$O/Sort.o: ../../../../C/Sort.c + $(CC) $(CFLAGS) $< +endif + + +ifdef USE_X86_ASM_AES +$O/AesOpt.o: ../../../../Asm/x86/AesOpt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/AesOpt.o: ../../../../C/AesOpt.c + $(CC) $(CFLAGS) $< +endif + + +ifdef USE_X64_ASM +$O/LzFindOpt.o: ../../../../Asm/x86/LzFindOpt.asm + $(MY_ASM) $(AFLAGS) $< +else +$O/LzFindOpt.o: ../../../../C/LzFindOpt.c + $(CC) $(CFLAGS) $< +endif + +ifdef USE_LZMA_DEC_ASM + +ifdef IS_X64 +$O/LzmaDecOpt.o: ../../../../Asm/x86/LzmaDecOpt.asm + $(MY_ASM) $(AFLAGS) $< +endif + +ifdef IS_ARM64 +$O/LzmaDecOpt.o: ../../../../Asm/arm64/LzmaDecOpt.S ../../../../Asm/arm64/7zAsm.S + $(CC) $(CFLAGS) $(ASM_FLAGS) $< +endif + +$O/LzmaDec.o: ../../../../C/LzmaDec.c + $(CC) $(CFLAGS) -DZ7_LZMA_DEC_OPT $< + +else + +$O/LzmaDec.o: ../../../../C/LzmaDec.c + $(CC) $(CFLAGS) $< + +endif + + + + +$O/7zMain.o: ../../../../C/Util/7z/7zMain.c + $(CC) $(CFLAGS) $< +$O/LzmaUtil.o: ../../../../C/Util/Lzma/LzmaUtil.c + $(CC) $(CFLAGS) $< + +ifneq ($(CC), xlc) +SHOW_PREDEF=-dM +else +SHOW_PREDEF= -qshowmacros=pre +endif + +predef_cc: + $(CC) $(CFLAGS) -E $(SHOW_PREDEF) ../../../../C/CpuArch.c > predef_cc_log +# $(CC) $(CFLAGS) -E -dM - < /dev/null +predef_cxx: + $(CXX) $(CFLAGS) -E $(SHOW_PREDEF) ../../../Common/CrcReg.cpp > predef_cxx_log + +predef: predef_cc predef_cxx + + +clean: + -$(DEL_OBJ_EXE) diff -Nru p7zip-rar-16.02/CPP/7zip/Aes.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Aes.mak --- p7zip-rar-16.02/CPP/7zip/Aes.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Aes.mak 2021-03-09 07:53:46.000000000 +0000 @@ -0,0 +1,10 @@ +C_OBJS = $(C_OBJS) \ + $O\Aes.obj + +!IF defined(USE_C_AES) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ + $O\AesOpt.obj +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +ASM_OBJS = $(ASM_OBJS) \ + $O\AesOpt.obj +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7z.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7z.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsp 2023-04-04 20:00:00.000000000 +0000 @@ -0,0 +1,638 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\Formats\7z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\Formats\7z.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=..\ArchiveExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CodecExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\DllExports2.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=.\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=.\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=.\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zIn.h +# End Source File +# Begin Source File + +SOURCE=.\7zItem.h +# End Source File +# Begin Source File + +SOURCE=.\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zOut.h +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=.\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=.\7zUpdate.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7z.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsw --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7z.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7z.dsw 2003-06-24 21:47:38.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=".\7z.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zCompressionMode.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zCompressionMode.cpp 2008-08-05 09:48:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.cpp 2003-06-19 23:14:40.000000000 +0000 @@ -1,3 +1,3 @@ -// CompressionMethod.cpp - -#include "StdAfx.h" +// CompressionMethod.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zCompressionMode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zCompressionMode.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zCompressionMode.h 2024-12-14 09:00:00.000000000 +0000 @@ -1,74 +1,92 @@ -// 7zCompressionMode.h - -#ifndef __7Z_COMPRESSION_MODE_H -#define __7Z_COMPRESSION_MODE_H - -#include "../../Common/MethodId.h" -#include "../../Common/MethodProps.h" - -namespace NArchive { -namespace N7z { - -struct CMethodFull: public CMethodProps -{ - CMethodId Id; - UInt32 NumStreams; - - bool IsSimpleCoder() const { return NumStreams == 1; } -}; - -struct CBond2 -{ - UInt32 OutCoder; - UInt32 OutStream; - UInt32 InCoder; -}; - -struct CCompressionMethodMode -{ - /* - if (Bonds.Empty()), then default bonds must be created - if (Filter_was_Inserted) - { - Methods[0] is filter method - Bonds don't contain bonds for filter (these bonds must be created) - } - */ - - CObjectVector Methods; - CRecordVector Bonds; - - bool IsThereBond_to_Coder(unsigned coderIndex) const - { - FOR_VECTOR(i, Bonds) - if (Bonds[i].InCoder == coderIndex) - return true; - return false; - } - - bool DefaultMethod_was_Inserted; - bool Filter_was_Inserted; - - #ifndef _7ZIP_ST - UInt32 NumThreads; - bool MultiThreadMixer; - #endif - - bool PasswordIsDefined; - UString Password; - - bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } - CCompressionMethodMode(): - DefaultMethod_was_Inserted(false), - Filter_was_Inserted(false), - PasswordIsDefined(false) - #ifndef _7ZIP_ST - , NumThreads(1) - , MultiThreadMixer(true) - #endif - {} -}; - -}} - -#endif +// 7zCompressionMode.h + +#ifndef ZIP7_INC_7Z_COMPRESSION_MODE_H +#define ZIP7_INC_7Z_COMPRESSION_MODE_H + +#include "../../Common/MethodId.h" +#include "../../Common/MethodProps.h" + +namespace NArchive { +namespace N7z { + +struct CMethodFull: public CMethodProps +{ + CMethodId Id; + UInt32 NumStreams; + int CodecIndex; + UInt32 NumThreads; + bool Set_NumThreads; + + CMethodFull(): CodecIndex(-1), NumThreads(1), Set_NumThreads(false) {} + bool IsSimpleCoder() const { return NumStreams == 1; } +}; + +struct CBond2 +{ + UInt32 OutCoder; + UInt32 OutStream; + UInt32 InCoder; +}; + +struct CCompressionMethodMode +{ + /* + if (Bonds.Empty()), then default bonds must be created + if (Filter_was_Inserted) + { + Methods[0] is filter method + Bonds don't contain bonds for filter (these bonds must be created) + } + */ + + CObjectVector Methods; + CRecordVector Bonds; + + bool IsThereBond_to_Coder(unsigned coderIndex) const + { + FOR_VECTOR(i, Bonds) + if (Bonds[i].InCoder == coderIndex) + return true; + return false; + } + + bool DefaultMethod_was_Inserted; + bool Filter_was_Inserted; + bool PasswordIsDefined; + bool MemoryUsageLimit_WasSet; + + #ifndef Z7_ST + bool NumThreads_WasForced; + bool MultiThreadMixer; + UInt32 NumThreads; + UInt32 NumThreadGroups; + #endif + + UString Password; // _Wipe + UInt64 MemoryUsageLimit; + + bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); } + CCompressionMethodMode(): + DefaultMethod_was_Inserted(false) + , Filter_was_Inserted(false) + , PasswordIsDefined(false) + , MemoryUsageLimit_WasSet(false) + #ifndef Z7_ST + , NumThreads_WasForced(false) + , MultiThreadMixer(true) + , NumThreads(1) + , NumThreadGroups(0) + #endif + , MemoryUsageLimit((UInt64)1 << 30) + {} + +#ifdef Z7_CPP_IS_SUPPORTED_default + CCompressionMethodMode(const CCompressionMethodMode &) = default; + CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default; +#endif + ~CCompressionMethodMode() { Password.Wipe_and_Empty(); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zDecode.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zDecode.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.cpp 2024-02-17 09:00:00.000000000 +0000 @@ -1,543 +1,599 @@ -// 7zDecode.cpp - -#include "StdAfx.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamObjects.h" - -#include "7zDecode.h" - -namespace NArchive { -namespace N7z { - -class CDecProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr _progress; -public: - CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize) -{ - return _progress->SetRatioInfo(NULL, outSize); -} - -static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi) -{ - bi.Clear(); - - bi.Bonds.ClearAndSetSize(folder.Bonds.Size()); - unsigned i; - for (i = 0; i < folder.Bonds.Size(); i++) - { - NCoderMixer2::CBond &bond = bi.Bonds[i]; - const N7z::CBond &folderBond = folder.Bonds[i]; - bond.PackIndex = folderBond.PackIndex; - bond.UnpackIndex = folderBond.UnpackIndex; - } - - bi.Coders.ClearAndSetSize(folder.Coders.Size()); - bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); - for (i = 0; i < folder.Coders.Size(); i++) - { - const CCoderInfo &coderInfo = folder.Coders[i]; - bi.Coders[i].NumStreams = coderInfo.NumStreams; - bi.CoderMethodIDs[i] = coderInfo.MethodID; - } - - /* - if (!bi.SetUnpackCoder()) - throw 1112; - */ - bi.UnpackCoder = folder.UnpackCoder; - bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size()); - for (i = 0; i < folder.PackStreams.Size(); i++) - bi.PackStreams[i] = folder.PackStreams[i]; -} - -static inline bool AreCodersEqual( - const NCoderMixer2::CCoderStreamsInfo &a1, - const NCoderMixer2::CCoderStreamsInfo &a2) -{ - return (a1.NumStreams == a2.NumStreams); -} - -static inline bool AreBondsEqual( - const NCoderMixer2::CBond &a1, - const NCoderMixer2::CBond &a2) -{ - return - (a1.PackIndex == a2.PackIndex) && - (a1.UnpackIndex == a2.UnpackIndex); -} - -static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) -{ - if (a1.Coders.Size() != a2.Coders.Size()) - return false; - unsigned i; - for (i = 0; i < a1.Coders.Size(); i++) - if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) - return false; - - if (a1.Bonds.Size() != a2.Bonds.Size()) - return false; - for (i = 0; i < a1.Bonds.Size(); i++) - if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i])) - return false; - - for (i = 0; i < a1.CoderMethodIDs.Size(); i++) - if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) - return false; - - if (a1.PackStreams.Size() != a2.PackStreams.Size()) - return false; - for (i = 0; i < a1.PackStreams.Size(); i++) - if (a1.PackStreams[i] != a2.PackStreams[i]) - return false; - - /* - if (a1.UnpackCoder != a2.UnpackCoder) - return false; - */ - return true; -} - -CDecoder::CDecoder(bool useMixerMT): - _bindInfoPrev_Defined(false), - _useMixerMT(useMixerMT) -{} - - -struct CLockedInStream: - public IUnknown, - public CMyUnknownImp -{ - CMyComPtr Stream; - UInt64 Pos; - - MY_UNKNOWN_IMP - - #ifdef USE_MIXER_MT - NWindows::NSynchronization::CCriticalSection CriticalSection; - #endif -}; - - -#ifdef USE_MIXER_MT - -class CLockedSequentialInStreamMT: - public ISequentialInStream, - public CMyUnknownImp -{ - CLockedInStream *_glob; - UInt64 _pos; - CMyComPtr _globRef; -public: - void Init(CLockedInStream *lockedInStream, UInt64 startPos) - { - _globRef = lockedInStream; - _glob = lockedInStream; - _pos = startPos; - } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); - - if (_pos != _glob->Pos) - { - RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); - _glob->Pos = _pos; - } - - UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); - _pos += realProcessedSize; - _glob->Pos = _pos; - if (processedSize) - *processedSize = realProcessedSize; - return res; -} - -#endif - - -#ifdef USE_MIXER_ST - -class CLockedSequentialInStreamST: - public ISequentialInStream, - public CMyUnknownImp -{ - CLockedInStream *_glob; - UInt64 _pos; - CMyComPtr _globRef; -public: - void Init(CLockedInStream *lockedInStream, UInt64 startPos) - { - _globRef = lockedInStream; - _glob = lockedInStream; - _pos = startPos; - } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (_pos != _glob->Pos) - { - RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL)); - _glob->Pos = _pos; - } - - UInt32 realProcessedSize = 0; - HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); - _pos += realProcessedSize; - _glob->Pos = _pos; - if (processedSize) - *processedSize = realProcessedSize; - return res; -} - -#endif - - - -HRESULT CDecoder::Decode( - DECL_EXTERNAL_CODECS_LOC_VARS - IInStream *inStream, - UInt64 startPos, - const CFolders &folders, unsigned folderIndex, - const UInt64 *unpackSize - - , ISequentialOutStream *outStream - , ICompressProgressInfo *compressProgress - , ISequentialInStream ** - - #ifdef USE_MIXER_ST - inStreamMainRes - #endif - - _7Z_DECODER_CRYPRO_VARS_DECL - - #if !defined(_7ZIP_ST) && !defined(_SFX) - , bool mtMode, UInt32 numThreads - #endif - ) -{ - const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; - CFolderEx folderInfo; - folders.ParseFolderEx(folderIndex, folderInfo); - - if (!folderInfo.IsDecodingSupported()) - return E_NOTIMPL; - - CBindInfoEx bindInfo; - Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo); - if (!bindInfo.CalcMapsAndCheck()) - return E_NOTIMPL; - - UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex); - bool fullUnpack = true; - if (unpackSize) - { - if (*unpackSize > folderUnpackSize) - return E_FAIL; - fullUnpack = (*unpackSize == folderUnpackSize); - } - - /* - We don't need to init isEncrypted and passwordIsDefined - We must upgrade them only - - #ifndef _NO_CRYPTO - isEncrypted = false; - passwordIsDefined = false; - #endif - */ - - if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev)) - { - _mixerRef.Release(); - - #ifdef USE_MIXER_MT - #ifdef USE_MIXER_ST - if (_useMixerMT) - #endif - { - _mixerMT = new NCoderMixer2::CMixerMT(false); - _mixerRef = _mixerMT; - _mixer = _mixerMT; - } - #ifdef USE_MIXER_ST - else - #endif - #endif - { - #ifdef USE_MIXER_ST - _mixerST = new NCoderMixer2::CMixerST(false); - _mixerRef = _mixerST; - _mixer = _mixerST; - #endif - } - - RINOK(_mixer->SetBindInfo(bindInfo)); - - FOR_VECTOR(i, folderInfo.Coders) - { - const CCoderInfo &coderInfo = folderInfo.Coders[i]; - - #ifndef _SFX - // we don't support RAR codecs here - if ((coderInfo.MethodID >> 8) == 0x403) - return E_NOTIMPL; - #endif - - CCreatedCoder cod; - RINOK(CreateCoder( - EXTERNAL_CODECS_LOC_VARS - coderInfo.MethodID, false, cod)); - - if (coderInfo.IsSimpleCoder()) - { - if (!cod.Coder) - return E_NOTIMPL; - // CMethodId m = coderInfo.MethodID; - // isFilter = (IsFilterMethod(m) || m == k_AES); - } - else - { - if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams) - return E_NOTIMPL; - } - _mixer->AddCoder(cod); - - // now there is no codec that uses another external codec - /* - #ifdef EXTERNAL_CODECS - CMyComPtr setCompressCodecsInfo; - decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); - } - #endif - */ - } - - _bindInfoPrev = bindInfo; - _bindInfoPrev_Defined = true; - } - - _mixer->ReInit(); - - UInt32 packStreamIndex = 0; - UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; - - unsigned i; - - for (i = 0; i < folderInfo.Coders.Size(); i++) - { - const CCoderInfo &coderInfo = folderInfo.Coders[i]; - IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); - - { - CMyComPtr setDecoderProperties; - decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); - if (setDecoderProperties) - { - const CByteBuffer &props = coderInfo.Props; - size_t size = props.Size(); - if (size > 0xFFFFFFFF) - return E_NOTIMPL; - HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size); - if (res == E_INVALIDARG) - res = E_NOTIMPL; - RINOK(res); - } - } - - #if !defined(_7ZIP_ST) && !defined(_SFX) - if (mtMode) - { - CMyComPtr setCoderMt; - decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); - if (setCoderMt) - { - RINOK(setCoderMt->SetNumberOfThreads(numThreads)); - } - } - #endif - - #ifndef _NO_CRYPTO - { - CMyComPtr cryptoSetPassword; - decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword); - if (cryptoSetPassword) - { - isEncrypted = true; - if (!getTextPassword) - return E_NOTIMPL; - CMyComBSTR passwordBSTR; - RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); - passwordIsDefined = true; - password.Empty(); - size_t len = 0; - if (passwordBSTR) - { - password = passwordBSTR; - len = password.Len(); - } - CByteBuffer buffer(len * 2); - for (size_t k = 0; k < len; k++) - { - wchar_t c = passwordBSTR[k]; - ((Byte *)buffer)[k * 2] = (Byte)c; - ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); - } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); - } - } - #endif - - { - CMyComPtr setFinishMode; - decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); - if (setFinishMode) - { - RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack))); - } - } - - UInt32 numStreams = (UInt32)coderInfo.NumStreams; - - CObjArray packSizes(numStreams); - CObjArray packSizesPointers(numStreams); - - for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++) - { - int bond = folderInfo.FindBond_for_PackStream(packStreamIndex); - - if (bond >= 0) - packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex]; - else - { - int index = folderInfo.Find_in_PackStreams(packStreamIndex); - if (index < 0) - return E_NOTIMPL; - packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index]; - packSizesPointers[j] = &packSizes[j]; - } - } - - const UInt64 *unpackSizesPointer = - (unpackSize && i == bindInfo.UnpackCoder) ? - unpackSize : - &folders.CoderUnpackSizes[unpackStreamIndexStart + i]; - - _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers); - } - - if (outStream) - { - _mixer->SelectMainCoder(!fullUnpack); - } - - CObjectVector< CMyComPtr > inStreams; - - CLockedInStream *lockedInStreamSpec = new CLockedInStream; - CMyComPtr lockedInStream = lockedInStreamSpec; - - bool needMtLock = false; - - if (folderInfo.PackStreams.Size() > 1) - { - // lockedInStream.Pos = (UInt64)(Int64)-1; - // RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos)); - RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos)); - lockedInStreamSpec->Stream = inStream; - - #ifdef USE_MIXER_ST - if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) - #endif - needMtLock = true; - } - - for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) - { - CMyComPtr packStream; - UInt64 packPos = startPos + packPositions[j]; - - if (folderInfo.PackStreams.Size() == 1) - { - RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL)); - packStream = inStream; - } - else - { - #ifdef USE_MIXER_MT - #ifdef USE_MIXER_ST - if (_useMixerMT || needMtLock) - #endif - { - CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; - packStream = lockedStreamImpSpec; - lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); - } - #ifdef USE_MIXER_ST - else - #endif - #endif - { - #ifdef USE_MIXER_ST - CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST; - packStream = lockedStreamImpSpec; - lockedStreamImpSpec->Init(lockedInStreamSpec, packPos); - #endif - } - } - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - inStreams.AddNew() = streamSpec; - streamSpec->SetStream(packStream); - streamSpec->Init(packPositions[j + 1] - packPositions[j]); - } - - unsigned num = inStreams.Size(); - CObjArray inStreamPointers(num); - for (i = 0; i < num; i++) - inStreamPointers[i] = inStreams[i]; - - if (outStream) - { - CMyComPtr progress2; - if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex)) - progress2 = new CDecProgress(compressProgress); - - ISequentialOutStream *outStreamPointer = outStream; - return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress); - } - - #ifdef USE_MIXER_ST - return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes); - #else - return E_FAIL; - #endif -} - -}} +// 7zDecode.cpp + +#include "StdAfx.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "7zDecode.h" + +namespace NArchive { +namespace N7z { + +Z7_CLASS_IMP_COM_1( + CDecProgress + , ICompressProgressInfo +) + CMyComPtr _progress; +public: + CDecProgress(ICompressProgressInfo *progress): _progress(progress) {} +}; + +Z7_COM7F_IMF(CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)) +{ + return _progress->SetRatioInfo(NULL, outSize); +} + +static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi) +{ + bi.Clear(); + + bi.Bonds.ClearAndSetSize(folder.Bonds.Size()); + unsigned i; + for (i = 0; i < folder.Bonds.Size(); i++) + { + NCoderMixer2::CBond &bond = bi.Bonds[i]; + const N7z::CBond &folderBond = folder.Bonds[i]; + bond.PackIndex = folderBond.PackIndex; + bond.UnpackIndex = folderBond.UnpackIndex; + } + + bi.Coders.ClearAndSetSize(folder.Coders.Size()); + bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); + for (i = 0; i < folder.Coders.Size(); i++) + { + const CCoderInfo &coderInfo = folder.Coders[i]; + bi.Coders[i].NumStreams = coderInfo.NumStreams; + bi.CoderMethodIDs[i] = coderInfo.MethodID; + } + + /* + if (!bi.SetUnpackCoder()) + throw 1112; + */ + bi.UnpackCoder = folder.UnpackCoder; + bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size()); + for (i = 0; i < folder.PackStreams.Size(); i++) + bi.PackStreams[i] = folder.PackStreams[i]; +} + +static inline bool AreCodersEqual( + const NCoderMixer2::CCoderStreamsInfo &a1, + const NCoderMixer2::CCoderStreamsInfo &a2) +{ + return (a1.NumStreams == a2.NumStreams); +} + +static inline bool AreBondsEqual( + const NCoderMixer2::CBond &a1, + const NCoderMixer2::CBond &a2) +{ + return + (a1.PackIndex == a2.PackIndex) && + (a1.UnpackIndex == a2.UnpackIndex); +} + +static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) +{ + if (a1.Coders.Size() != a2.Coders.Size()) + return false; + unsigned i; + for (i = 0; i < a1.Coders.Size(); i++) + if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) + return false; + + if (a1.Bonds.Size() != a2.Bonds.Size()) + return false; + for (i = 0; i < a1.Bonds.Size(); i++) + if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i])) + return false; + + for (i = 0; i < a1.CoderMethodIDs.Size(); i++) + if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) + return false; + + if (a1.PackStreams.Size() != a2.PackStreams.Size()) + return false; + for (i = 0; i < a1.PackStreams.Size(); i++) + if (a1.PackStreams[i] != a2.PackStreams[i]) + return false; + + /* + if (a1.UnpackCoder != a2.UnpackCoder) + return false; + */ + return true; +} + +CDecoder::CDecoder(bool useMixerMT): + _bindInfoPrev_Defined(false) +{ + #if defined(USE_MIXER_ST) && defined(USE_MIXER_MT) + _useMixerMT = useMixerMT; + #else + UNUSED_VAR(useMixerMT) + #endif +} + + +Z7_CLASS_IMP_COM_0( + CLockedInStream +) +public: + CMyComPtr Stream; + UInt64 Pos; + + #ifdef USE_MIXER_MT + NWindows::NSynchronization::CCriticalSection CriticalSection; + #endif +}; + + +#ifdef USE_MIXER_MT + +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamMT + , ISequentialInStream +) + CLockedInStream *_glob; + UInt64 _pos; + CMyComPtr _globRef; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _globRef = lockedInStream; + _glob = lockedInStream; + _pos = startPos; + } +}; + +Z7_COM7F_IMF(CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection); + + if (_pos != _glob->Pos) + { + RINOK(InStream_SeekSet(_glob->Stream, _pos)) + _glob->Pos = _pos; + } + + UInt32 realProcessedSize = 0; + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + _pos += realProcessedSize; + _glob->Pos = _pos; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + +#endif + + +#ifdef USE_MIXER_ST + +Z7_CLASS_IMP_COM_1( + CLockedSequentialInStreamST + , ISequentialInStream +) + CLockedInStream *_glob; + UInt64 _pos; + CMyComPtr _globRef; +public: + void Init(CLockedInStream *lockedInStream, UInt64 startPos) + { + _globRef = lockedInStream; + _glob = lockedInStream; + _pos = startPos; + } +}; + +Z7_COM7F_IMF(CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (_pos != _glob->Pos) + { + RINOK(InStream_SeekSet(_glob->Stream, _pos)) + _glob->Pos = _pos; + } + + UInt32 realProcessedSize = 0; + const HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize); + _pos += realProcessedSize; + _glob->Pos = _pos; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + +#endif + + + +HRESULT CDecoder::Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + UInt64 startPos, + const CFolders &folders, unsigned folderIndex, + const UInt64 *unpackSize + + , ISequentialOutStream *outStream + , ICompressProgressInfo *compressProgress + + , ISequentialInStream ** + #ifdef USE_MIXER_ST + inStreamMainRes + #endif + + , bool &dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS_DECL + + #if !defined(Z7_ST) + , bool mtMode, UInt32 numThreads, UInt64 memUsage + #endif + ) +{ + dataAfterEnd_Error = false; + + const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; + CFolderEx folderInfo; + folders.ParseFolderEx(folderIndex, folderInfo); + + if (!folderInfo.IsDecodingSupported()) + return E_NOTIMPL; + + CBindInfoEx bindInfo; + Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo); + if (!bindInfo.CalcMapsAndCheck()) + return E_NOTIMPL; + + UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex); + bool fullUnpack = true; + if (unpackSize) + { + if (*unpackSize > folderUnpackSize) + return E_FAIL; + fullUnpack = (*unpackSize == folderUnpackSize); + } + + /* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only + + #ifndef Z7_NO_CRYPTO + isEncrypted = false; + passwordIsDefined = false; + #endif + */ + + if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev)) + { + _bindInfoPrev_Defined = false; + _mixerRef.Release(); + + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + if (_useMixerMT) + #endif + { + _mixerMT = new NCoderMixer2::CMixerMT(false); + _mixerRef = _mixerMT; + _mixer = _mixerMT; + } + #ifdef USE_MIXER_ST + else + #endif + #endif + { + #ifdef USE_MIXER_ST + _mixerST = new NCoderMixer2::CMixerST(false); + _mixerRef = _mixerST; + _mixer = _mixerST; + #endif + } + + RINOK(_mixer->SetBindInfo(bindInfo)) + + FOR_VECTOR(i, folderInfo.Coders) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + + #ifndef Z7_SFX + // we don't support RAR codecs here + if ((coderInfo.MethodID >> 8) == 0x403) + return E_NOTIMPL; + #endif + + CCreatedCoder cod; + RINOK(CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + coderInfo.MethodID, false, cod)) + + if (coderInfo.IsSimpleCoder()) + { + if (!cod.Coder) + return E_NOTIMPL; + // CMethodId m = coderInfo.MethodID; + // isFilter = (IsFilterMethod(m) || m == k_AES); + } + else + { + if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams) + return E_NOTIMPL; + } + _mixer->AddCoder(cod); + + // now there is no codec that uses another external codec + /* + #ifdef Z7_EXTERNAL_CODECS + CMyComPtr setCompressCodecsInfo; + decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); + } + #endif + */ + } + + _bindInfoPrev = bindInfo; + _bindInfoPrev_Defined = true; + } + + RINOK(_mixer->ReInit2()) + + UInt32 packStreamIndex = 0; + UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; + + unsigned i; + + #if !defined(Z7_ST) + bool mt_wasUsed = false; + #endif + + for (i = 0; i < folderInfo.Coders.Size(); i++) + { + const CCoderInfo &coderInfo = folderInfo.Coders[i]; + IUnknown *decoder = _mixer->GetCoder(i).GetUnknown(); + + // now there is no codec that uses another external codec + /* + #ifdef Z7_EXTERNAL_CODECS + { + Z7_DECL_CMyComPtr_QI_FROM(ISetCompressCodecsInfo, + setCompressCodecsInfo, decoder) + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) + } + } + #endif + */ + + #if !defined(Z7_ST) + if (!mt_wasUsed) + { + if (mtMode) + { + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetCoderMt, + setCoderMt, decoder) + if (setCoderMt) + { + mt_wasUsed = true; + RINOK(setCoderMt->SetNumberOfThreads(numThreads)) + } + } + // if (memUsage != 0) + { + Z7_DECL_CMyComPtr_QI_FROM(ICompressSetMemLimit, + setMemLimit, decoder) + if (setMemLimit) + { + mt_wasUsed = true; + RINOK(setMemLimit->SetMemLimit(memUsage)) + } + } + } + #endif + + { + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetDecoderProperties2, + setDecoderProperties, decoder) + const CByteBuffer &props = coderInfo.Props; + const UInt32 size32 = (UInt32)props.Size(); + if (props.Size() != size32) + return E_NOTIMPL; + if (setDecoderProperties) + { + HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32); + if (res == E_INVALIDARG) + res = E_NOTIMPL; + RINOK(res) + } + else if (size32 != 0) + { + // v23: we fail, if decoder doesn't support properties + return E_NOTIMPL; + } + } + + #ifndef Z7_NO_CRYPTO + { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoSetPassword, + cryptoSetPassword, decoder) + if (cryptoSetPassword) + { + isEncrypted = true; + if (!getTextPassword) + return E_NOTIMPL; + CMyComBSTR_Wipe passwordBSTR; + RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)) + passwordIsDefined = true; + password.Wipe_and_Empty(); + size_t len = 0; + if (passwordBSTR) + { + password = passwordBSTR; + len = password.Len(); + } + CByteBuffer_Wipe buffer(len * 2); + const LPCOLESTR psw = passwordBSTR; + for (size_t k = 0; k < len; k++) + { + const wchar_t c = psw[k]; + ((Byte *)buffer)[k * 2] = (Byte)c; + ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())) + } + } + #endif + + bool finishMode = false; + { + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetFinishMode, + setFinishMode, decoder) + if (setFinishMode) + { + finishMode = fullUnpack; + RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode))) + } + } + + UInt32 numStreams = (UInt32)coderInfo.NumStreams; + + CObjArray packSizes(numStreams); + CObjArray packSizesPointers(numStreams); + + for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++) + { + int bond = folderInfo.FindBond_for_PackStream(packStreamIndex); + + if (bond >= 0) + packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex]; + else + { + int index = folderInfo.Find_in_PackStreams(packStreamIndex); + if (index < 0) + return E_NOTIMPL; + packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index]; + packSizesPointers[j] = &packSizes[j]; + } + } + + const UInt64 *unpackSizesPointer = + (unpackSize && i == bindInfo.UnpackCoder) ? + unpackSize : + &folders.CoderUnpackSizes[unpackStreamIndexStart + i]; + + _mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode); + } + + if (outStream) + { + _mixer->SelectMainCoder(!fullUnpack); + } + + CObjectVector< CMyComPtr > inStreams; + + CMyComPtr2_Create lockedInStream; + + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + bool needMtLock = _useMixerMT; + #endif + #endif + + if (folderInfo.PackStreams.Size() > 1) + { + // lockedInStream.Pos = (UInt64)(Int64)-1; + // RINOK(InStream_GetPos(inStream, lockedInStream.Pos)) + RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStream->Pos)) + lockedInStream->Stream = inStream; + + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + /* + For ST-mixer mode: + If parallel input stream reading from pack streams is possible, + we must use MT-lock for packed streams. + Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode. + So we force to needMtLock mode only if there is unknown (external) decoder. + */ + if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex)) + needMtLock = true; + #endif + #endif + } + + for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) + { + CMyComPtr packStream; + const UInt64 packPos = startPos + packPositions[j]; + + if (folderInfo.PackStreams.Size() == 1) + { + RINOK(InStream_SeekSet(inStream, packPos)) + packStream = inStream; + } + else + { + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + if (needMtLock) + #endif + { + CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT; + packStream = lockedStreamImpSpec; + lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); + } + #ifdef USE_MIXER_ST + else + #endif + #endif + { + #ifdef USE_MIXER_ST + CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST; + packStream = lockedStreamImpSpec; + lockedStreamImpSpec->Init(lockedInStream.ClsPtr(), packPos); + #endif + } + } + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + inStreams.AddNew() = streamSpec; + streamSpec->SetStream(packStream); + streamSpec->Init(packPositions[j + 1] - packPositions[j]); + } + + const unsigned num = inStreams.Size(); + CObjArray inStreamPointers(num); + for (i = 0; i < num; i++) + inStreamPointers[i] = inStreams[i]; + + if (outStream) + { + CMyComPtr progress2; + if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex)) + progress2 = new CDecProgress(compressProgress); + + ISequentialOutStream *outStreamPointer = outStream; + return _mixer->Code(inStreamPointers, &outStreamPointer, + progress2 ? (ICompressProgressInfo *)progress2 : compressProgress, + dataAfterEnd_Error); + } + + #ifdef USE_MIXER_ST + return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes); + #else + return E_FAIL; + #endif +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zDecode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zDecode.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zDecode.h 2023-03-04 09:00:00.000000000 +0000 @@ -1,68 +1,73 @@ -// 7zDecode.h - -#ifndef __7Z_DECODE_H -#define __7Z_DECODE_H - -#include "../Common/CoderMixer2.h" - -#include "7zIn.h" - -namespace NArchive { -namespace N7z { - -struct CBindInfoEx: public NCoderMixer2::CBindInfo -{ - CRecordVector CoderMethodIDs; - - void Clear() - { - CBindInfo::Clear(); - CoderMethodIDs.Clear(); - } -}; - -class CDecoder -{ - bool _bindInfoPrev_Defined; - CBindInfoEx _bindInfoPrev; - - bool _useMixerMT; - - #ifdef USE_MIXER_ST - NCoderMixer2::CMixerST *_mixerST; - #endif - - #ifdef USE_MIXER_MT - NCoderMixer2::CMixerMT *_mixerMT; - #endif - - NCoderMixer2::CMixer *_mixer; - CMyComPtr _mixerRef; - -public: - - CDecoder(bool useMixerMT); - - HRESULT Decode( - DECL_EXTERNAL_CODECS_LOC_VARS - IInStream *inStream, - UInt64 startPos, - const CFolders &folders, unsigned folderIndex, - const UInt64 *unpackSize // if (!unpackSize), then full folder is required - // if (unpackSize), then only *unpackSize bytes from folder are required - - , ISequentialOutStream *outStream - , ICompressProgressInfo *compressProgress - , ISequentialInStream **inStreamMainRes - - _7Z_DECODER_CRYPRO_VARS_DECL - - #if !defined(_7ZIP_ST) && !defined(_SFX) - , bool mtMode, UInt32 numThreads - #endif - ); -}; - -}} - -#endif +// 7zDecode.h + +#ifndef ZIP7_INC_7Z_DECODE_H +#define ZIP7_INC_7Z_DECODE_H + +#include "../Common/CoderMixer2.h" + +#include "7zIn.h" + +namespace NArchive { +namespace N7z { + +struct CBindInfoEx: public NCoderMixer2::CBindInfo +{ + CRecordVector CoderMethodIDs; + + void Clear() + { + CBindInfo::Clear(); + CoderMethodIDs.Clear(); + } +}; + +class CDecoder +{ + bool _bindInfoPrev_Defined; + #ifdef USE_MIXER_ST + #ifdef USE_MIXER_MT + bool _useMixerMT; + #endif + #endif + CBindInfoEx _bindInfoPrev; + + #ifdef USE_MIXER_ST + NCoderMixer2::CMixerST *_mixerST; + #endif + + #ifdef USE_MIXER_MT + NCoderMixer2::CMixerMT *_mixerMT; + #endif + + NCoderMixer2::CMixer *_mixer; + CMyComPtr _mixerRef; + +public: + + CDecoder(bool useMixerMT); + + HRESULT Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + UInt64 startPos, + const CFolders &folders, unsigned folderIndex, + const UInt64 *unpackSize // if (!unpackSize), then full folder is required + // if (unpackSize), then only *unpackSize bytes from folder are required + + , ISequentialOutStream *outStream + , ICompressProgressInfo *compressProgress + + , ISequentialInStream **inStreamMainRes + , bool &dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS_DECL + + #if !defined(Z7_ST) + , bool mtMode, UInt32 numThreads, UInt64 memUsage + #endif + ); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zEncode.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zEncode.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.cpp 2023-12-20 09:00:00.000000000 +0000 @@ -1,656 +1,721 @@ -// 7zEncode.cpp - -#include "StdAfx.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/FilterCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/InOutTempBuffer.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamObjects.h" - -#include "7zEncode.h" -#include "7zSpecStream.h" - -namespace NArchive { -namespace N7z { - -void CEncoder::InitBindConv() -{ - unsigned numIn = _bindInfo.Coders.Size(); - - _SrcIn_to_DestOut.ClearAndSetSize(numIn); - _DestOut_to_SrcIn.ClearAndSetSize(numIn); - - unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams(); - _SrcOut_to_DestIn.ClearAndSetSize(numOut); - // _DestIn_to_SrcOut.ClearAndSetSize(numOut); - - UInt32 destIn = 0; - UInt32 destOut = 0; - - for (unsigned i = _bindInfo.Coders.Size(); i != 0;) - { - i--; - - const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i]; - - numIn--; - numOut -= coder.NumStreams; - - _SrcIn_to_DestOut[numIn] = destOut; - _DestOut_to_SrcIn[destOut] = numIn; - - destOut++; - - for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++) - { - UInt32 index = numOut + j; - _SrcOut_to_DestIn[index] = destIn; - // _DestIn_to_SrcOut[destIn] = index; - } - } -} - -void CEncoder::SetFolder(CFolder &folder) -{ - folder.Bonds.SetSize(_bindInfo.Bonds.Size()); - - unsigned i; - - for (i = 0; i < _bindInfo.Bonds.Size(); i++) - { - CBond &fb = folder.Bonds[i]; - const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i]; - fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex]; - fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex]; - } - - folder.Coders.SetSize(_bindInfo.Coders.Size()); - - for (i = 0; i < _bindInfo.Coders.Size(); i++) - { - CCoderInfo &coderInfo = folder.Coders[i]; - const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i]; - - coderInfo.NumStreams = coderStreamsInfo.NumStreams; - coderInfo.MethodID = _decompressionMethods[i]; - // we don't free coderInfo.Props here. So coderInfo.Props can be non-empty. - } - - folder.PackStreams.SetSize(_bindInfo.PackStreams.Size()); - - for (i = 0; i < _bindInfo.PackStreams.Size(); i++) - folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; -} - - - -static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) -{ - CMyComPtr setCoderProperties; - coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); - if (setCoderProperties) - return props.SetCoderProps(setCoderProperties, dataSizeReduce); - return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; -} - - - -void CMtEncMultiProgress::Init(ICompressProgressInfo *progress) -{ - _progress = progress; - OutSize = 0; -} - -STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) -{ - UInt64 outSize2; - { - #ifndef _7ZIP_ST - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - #endif - outSize2 = OutSize; - } - - if (_progress) - return _progress->SetRatioInfo(inSize, &outSize2); - - return S_OK; -} - - - -HRESULT CEncoder::CreateMixerCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - const UInt64 *inSizeForReduce) -{ - #ifdef USE_MIXER_MT - #ifdef USE_MIXER_ST - if (_options.MultiThreadMixer) - #endif - { - _mixerMT = new NCoderMixer2::CMixerMT(true); - _mixerRef = _mixerMT; - _mixer = _mixerMT; - } - #ifdef USE_MIXER_ST - else - #endif - #endif - { - #ifdef USE_MIXER_ST - _mixerST = new NCoderMixer2::CMixerST(true); - _mixerRef = _mixerST; - _mixer = _mixerST; - #endif - } - - RINOK(_mixer->SetBindInfo(_bindInfo)); - - FOR_VECTOR (m, _options.Methods) - { - const CMethodFull &methodFull = _options.Methods[m]; - - CCreatedCoder cod; - - RINOK(CreateCoder( - EXTERNAL_CODECS_LOC_VARS - methodFull.Id, true, cod)); - - if (cod.NumStreams != methodFull.NumStreams) - return E_FAIL; - if (!cod.Coder && !cod.Coder2) - return E_FAIL; - - CMyComPtr encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; - - #ifndef _7ZIP_ST - { - CMyComPtr setCoderMt; - encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); - if (setCoderMt) - { - RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads)); - } - } - #endif - - RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)); - - /* - CMyComPtr resetSalt; - encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt); - if (resetSalt) - { - resetSalt->ResetSalt(); - } - */ - - // now there is no codec that uses another external codec - /* - #ifdef EXTERNAL_CODECS - CMyComPtr setCompressCodecsInfo; - encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - // we must use g_ExternalCodecs also - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); - } - #endif - */ - - CMyComPtr cryptoSetPassword; - encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); - - if (cryptoSetPassword) - { - const unsigned sizeInBytes = _options.Password.Len() * 2; - CByteBuffer buffer(sizeInBytes); - for (unsigned i = 0; i < _options.Password.Len(); i++) - { - wchar_t c = _options.Password[i]; - ((Byte *)buffer)[i * 2] = (Byte)c; - ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); - } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)); - } - - _mixer->AddCoder(cod); - } - return S_OK; -} - - - -class CSequentialOutTempBufferImp2: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; -public: - CMtEncMultiProgress *_mtProgresSpec; - - CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {} - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed) -{ - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; - return E_FAIL; - } - if (processed) - *processed = size; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); - return S_OK; -} - - -class CSequentialOutMtNotify: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - CMyComPtr _stream; - CMtEncMultiProgress *_mtProgresSpec; - - CSequentialOutMtNotify(): _mtProgresSpec(NULL) {} - MY_UNKNOWN_IMP1(ISequentialOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed) -{ - UInt32 realProcessed = 0; - HRESULT res = _stream->Write(data, size, &realProcessed); - if (processed) - *processed = realProcessed; - if (_mtProgresSpec) - _mtProgresSpec->AddOutSize(size); - return res; -} - - - -HRESULT CEncoder::Encode( - DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, - // const UInt64 *inStreamSize, - const UInt64 *inSizeForReduce, - CFolder &folderItem, - CRecordVector &coderUnpackSizes, - UInt64 &unpackSize, - ISequentialOutStream *outStream, - CRecordVector &packSizes, - ICompressProgressInfo *compressProgress) -{ - RINOK(EncoderConstr()); - - if (!_mixerRef) - { - RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)); - } - - _mixer->ReInit(); - - CMtEncMultiProgress *mtProgressSpec = NULL; - CMyComPtr mtProgress; - - CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL; - CMyComPtr mtOutStreamNotify; - - CObjectVector inOutTempBuffers; - CObjectVector tempBufferSpecs; - CObjectVector > tempBuffers; - - unsigned numMethods = _bindInfo.Coders.Size(); - - unsigned i; - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - { - CInOutTempBuffer &iotb = inOutTempBuffers.AddNew(); - iotb.Create(); - iotb.InitWriting(); - } - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - { - CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2; - CMyComPtr tempBuffer = tempBufferSpec; - tempBufferSpec->Init(&inOutTempBuffers[i - 1]); - tempBuffers.Add(tempBuffer); - tempBufferSpecs.Add(tempBufferSpec); - } - - for (i = 0; i < numMethods; i++) - _mixer->SetCoderInfo(i, NULL, NULL); - - - /* inStreamSize can be used by BCJ2 to set optimal range of conversion. - But current BCJ2 encoder uses also another way to check exact size of current file. - So inStreamSize is not required. */ - - /* - if (inStreamSize) - _mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL); - */ - - - CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; - CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; - - CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; - CMyComPtr outStreamSizeCount; - - inStreamSizeCountSpec->Init(inStream); - - ISequentialInStream *inStreamPointer = inStreamSizeCount; - CRecordVector outStreamPointers; - - SetFolder(folderItem); - - for (i = 0; i < numMethods; i++) - { - IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); - - CMyComPtr resetInitVector; - coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector); - if (resetInitVector) - { - resetInitVector->ResetInitVector(); - } - - CMyComPtr writeCoderProperties; - coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); - - CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props; - - if (writeCoderProperties) - { - CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; - CMyComPtr dynOutStream(outStreamSpec); - outStreamSpec->Init(); - writeCoderProperties->WriteCoderProperties(dynOutStream); - outStreamSpec->CopyToBuffer(props); - } - else - props.Free(); - } - - _mixer->SelectMainCoder(false); - UInt32 mainCoder = _mixer->MainCoderIndex; - - bool useMtProgress = false; - if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder)) - { - #ifdef _7ZIP_ST - if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder)) - #endif - useMtProgress = true; - } - - if (useMtProgress) - { - mtProgressSpec = new CMtEncMultiProgress; - mtProgress = mtProgressSpec; - mtProgressSpec->Init(compressProgress); - - mtOutStreamNotifySpec = new CSequentialOutMtNotify; - mtOutStreamNotify = mtOutStreamNotifySpec; - mtOutStreamNotifySpec->_stream = outStream; - mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec; - - FOR_VECTOR(t, tempBufferSpecs) - { - tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec; - } - } - - - if (_bindInfo.PackStreams.Size() != 0) - { - outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; - outStreamSizeCount = outStreamSizeCountSpec; - outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream); - outStreamSizeCountSpec->Init(); - outStreamPointers.Add(outStreamSizeCount); - } - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - outStreamPointers.Add(tempBuffers[i - 1]); - - RINOK(_mixer->Code( - &inStreamPointer, - &outStreamPointers.Front(), - mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress)); - - if (_bindInfo.PackStreams.Size() != 0) - packSizes.Add(outStreamSizeCountSpec->GetSize()); - - for (i = 1; i < _bindInfo.PackStreams.Size(); i++) - { - CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1]; - RINOK(inOutTempBuffer.WriteToStream(outStream)); - packSizes.Add(inOutTempBuffer.GetDataSize()); - } - - unpackSize = 0; - - for (i = 0; i < _bindInfo.Coders.Size(); i++) - { - int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]); - UInt64 streamSize; - if (bond < 0) - { - streamSize = inStreamSizeCountSpec->GetSize(); - unpackSize = streamSize; - } - else - streamSize = _mixer->GetBondStreamSize(bond); - coderUnpackSizes.Add(streamSize); - } - - return S_OK; -} - - -CEncoder::CEncoder(const CCompressionMethodMode &options): - _constructed(false) -{ - if (options.IsEmpty()) - throw 1; - - _options = options; - - #ifdef USE_MIXER_ST - _mixerST = NULL; - #endif - - #ifdef USE_MIXER_MT - _mixerMT = NULL; - #endif - - _mixer = NULL; -} - - -HRESULT CEncoder::EncoderConstr() -{ - if (_constructed) - return S_OK; - if (_options.Methods.IsEmpty()) - { - // it has only password method; - if (!_options.PasswordIsDefined) - throw 1; - if (!_options.Bonds.IsEmpty()) - throw 1; - - CMethodFull method; - method.Id = k_AES; - method.NumStreams = 1; - _options.Methods.Add(method); - - NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; - coderStreamsInfo.NumStreams = 1; - _bindInfo.Coders.Add(coderStreamsInfo); - - _bindInfo.PackStreams.Add(0); - _bindInfo.UnpackCoder = 0; - } - else - { - - UInt32 numOutStreams = 0; - unsigned i; - - for (i = 0; i < _options.Methods.Size(); i++) - { - const CMethodFull &methodFull = _options.Methods[i]; - NCoderMixer2::CCoderStreamsInfo cod; - - cod.NumStreams = methodFull.NumStreams; - - if (_options.Bonds.IsEmpty()) - { - // if there are no bonds in options, we create bonds via first streams of coders - if (i != _options.Methods.Size() - 1) - { - NCoderMixer2::CBond bond; - bond.PackIndex = numOutStreams; - bond.UnpackIndex = i + 1; // it's next coder - _bindInfo.Bonds.Add(bond); - } - else if (cod.NumStreams != 0) - _bindInfo.PackStreams.Insert(0, numOutStreams); - - for (UInt32 j = 1; j < cod.NumStreams; j++) - _bindInfo.PackStreams.Add(numOutStreams + j); - } - - numOutStreams += cod.NumStreams; - - _bindInfo.Coders.Add(cod); - } - - if (!_options.Bonds.IsEmpty()) - { - for (i = 0; i < _options.Bonds.Size(); i++) - { - NCoderMixer2::CBond mixerBond; - const CBond2 &bond = _options.Bonds[i]; - if (bond.InCoder >= _bindInfo.Coders.Size() - || bond.OutCoder >= _bindInfo.Coders.Size() - || bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams) - return E_INVALIDARG; - mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream; - mixerBond.UnpackIndex = bond.InCoder; - _bindInfo.Bonds.Add(mixerBond); - } - - for (i = 0; i < numOutStreams; i++) - if (_bindInfo.FindBond_for_PackStream(i) == -1) - _bindInfo.PackStreams.Add(i); - } - - if (!_bindInfo.SetUnpackCoder()) - return E_INVALIDARG; - - if (!_bindInfo.CalcMapsAndCheck()) - return E_INVALIDARG; - - if (_bindInfo.PackStreams.Size() != 1) - { - /* main_PackStream is pack stream of main path of coders tree. - We find main_PackStream, and place to start of list of out streams. - It allows to use more optimal memory usage for temp buffers, - if main_PackStream is largest stream. */ - - UInt32 ci = _bindInfo.UnpackCoder; - - for (;;) - { - if (_bindInfo.Coders[ci].NumStreams == 0) - break; - - UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; - int bond = _bindInfo.FindBond_for_PackStream(outIndex); - if (bond >= 0) - { - ci = _bindInfo.Bonds[bond].UnpackIndex; - continue; - } - - int si = _bindInfo.FindStream_in_PackStreams(outIndex); - if (si >= 0) - _bindInfo.PackStreams.MoveToFront(si); - break; - } - } - - if (_options.PasswordIsDefined) - { - unsigned numCryptoStreams = _bindInfo.PackStreams.Size(); - - unsigned numInStreams = _bindInfo.Coders.Size(); - - for (i = 0; i < numCryptoStreams; i++) - { - NCoderMixer2::CBond bond; - bond.UnpackIndex = numInStreams + i; - bond.PackIndex = _bindInfo.PackStreams[i]; - _bindInfo.Bonds.Add(bond); - } - _bindInfo.PackStreams.Clear(); - - /* - if (numCryptoStreams == 0) - numCryptoStreams = 1; - */ - - for (i = 0; i < numCryptoStreams; i++) - { - CMethodFull method; - method.NumStreams = 1; - method.Id = k_AES; - _options.Methods.Add(method); - - NCoderMixer2::CCoderStreamsInfo cod; - cod.NumStreams = 1; - _bindInfo.Coders.Add(cod); - - _bindInfo.PackStreams.Add(numOutStreams++); - } - } - - } - - for (unsigned i = _options.Methods.Size(); i != 0;) - _decompressionMethods.Add(_options.Methods[--i].Id); - - if (_bindInfo.Coders.Size() > 16) - return E_INVALIDARG; - if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16) - return E_INVALIDARG; - - if (!_bindInfo.CalcMapsAndCheck()) - return E_INVALIDARG; - - InitBindConv(); - _constructed = true; - return S_OK; -} - -CEncoder::~CEncoder() {} - -}} +// 7zEncode.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/FilterCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/InOutTempBuffer.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" + +#include "7zEncode.h" +#include "7zSpecStream.h" + +namespace NArchive { +namespace N7z { + +void CEncoder::InitBindConv() +{ + unsigned numIn = _bindInfo.Coders.Size(); + + SrcIn_to_DestOut.ClearAndSetSize(numIn); + DestOut_to_SrcIn.ClearAndSetSize(numIn); + + unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams(); + SrcOut_to_DestIn.ClearAndSetSize(numOut); + // _DestIn_to_SrcOut.ClearAndSetSize(numOut); + + UInt32 destIn = 0; + UInt32 destOut = 0; + + for (unsigned i = _bindInfo.Coders.Size(); i != 0;) + { + i--; + + const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i]; + + numIn--; + numOut -= coder.NumStreams; + + SrcIn_to_DestOut[numIn] = destOut; + DestOut_to_SrcIn[destOut] = numIn; + + destOut++; + + for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++) + { + UInt32 index = numOut + j; + SrcOut_to_DestIn[index] = destIn; + // _DestIn_to_SrcOut[destIn] = index; + } + } +} + +void CEncoder::SetFolder(CFolder &folder) +{ + folder.Bonds.SetSize(_bindInfo.Bonds.Size()); + + unsigned i; + + for (i = 0; i < _bindInfo.Bonds.Size(); i++) + { + CBond &fb = folder.Bonds[i]; + const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i]; + fb.PackIndex = SrcOut_to_DestIn[mixerBond.PackIndex]; + fb.UnpackIndex = SrcIn_to_DestOut[mixerBond.UnpackIndex]; + } + + folder.Coders.SetSize(_bindInfo.Coders.Size()); + + for (i = 0; i < _bindInfo.Coders.Size(); i++) + { + CCoderInfo &coderInfo = folder.Coders[i]; + const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i]; + + coderInfo.NumStreams = coderStreamsInfo.NumStreams; + coderInfo.MethodID = _decompressionMethods[i]; + // we don't free coderInfo.Props here. So coderInfo.Props can be non-empty. + } + + folder.PackStreams.SetSize(_bindInfo.PackStreams.Size()); + + for (i = 0; i < _bindInfo.PackStreams.Size(); i++) + folder.PackStreams[i] = SrcOut_to_DestIn[_bindInfo.PackStreams[i]]; +} + + + +static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder) +{ + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderProperties, + setCoderProperties, coder) + if (setCoderProperties) + return props.SetCoderProps(setCoderProperties, dataSizeReduce); + return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK; +} + + + +void CMtEncMultiProgress::Init(ICompressProgressInfo *progress) +{ + _progress = progress; + OutSize = 0; +} + +Z7_COM7F_IMF(CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) +{ + UInt64 outSize2; + { + #ifndef Z7_ST + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + #endif + outSize2 = OutSize; + } + + if (_progress) + return _progress->SetRatioInfo(inSize, &outSize2); + + return S_OK; +} + + + +HRESULT CEncoder::CreateMixerCoder( + DECL_EXTERNAL_CODECS_LOC_VARS + const UInt64 *inSizeForReduce) +{ + #ifdef USE_MIXER_MT + #ifdef USE_MIXER_ST + if (_options.MultiThreadMixer) + #endif + { + _mixerMT = new NCoderMixer2::CMixerMT(true); + _mixerRef = _mixerMT; + _mixer = _mixerMT; + } + #ifdef USE_MIXER_ST + else + #endif + #endif + { + #ifdef USE_MIXER_ST + _mixerST = new NCoderMixer2::CMixerST(true); + _mixerRef = _mixerST; + _mixer = _mixerST; + #endif + } + + RINOK(_mixer->SetBindInfo(_bindInfo)) + + FOR_VECTOR (m, _options.Methods) + { + const CMethodFull &methodFull = _options.Methods[m]; + + CCreatedCoder cod; + + if (methodFull.CodecIndex >= 0) + { + RINOK(CreateCoder_Index( + EXTERNAL_CODECS_LOC_VARS + (unsigned)methodFull.CodecIndex, true, cod)) + } + else + { + RINOK(CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + methodFull.Id, true, cod)) + } + + if (!cod.Coder && !cod.Coder2) + { + return E_NOTIMPL; // unsupported method, if encoder + // return E_FAIL; + } + + if (cod.NumStreams != methodFull.NumStreams) + return E_FAIL; + + CMyComPtr encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; + + #ifndef Z7_ST + if (methodFull.Set_NumThreads) + { + CMyComPtr setCoderMt; + encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads( + /* _options.NumThreads */ + methodFull.NumThreads + )) + } + } + #endif + + RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon)) + + /* + CMyComPtr resetSalt; + encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt); + if (resetSalt) + { + resetSalt->ResetSalt(); + } + */ + + // now there is no codec that uses another external codec + /* + #ifdef Z7_EXTERNAL_CODECS + CMyComPtr setCompressCodecsInfo; + encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)); + } + #endif + */ + + CMyComPtr cryptoSetPassword; + encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); + + if (cryptoSetPassword) + { + const unsigned sizeInBytes = _options.Password.Len() * 2; + CByteBuffer_Wipe buffer(sizeInBytes); + for (unsigned i = 0; i < _options.Password.Len(); i++) + { + wchar_t c = _options.Password[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes)) + } + + _mixer->AddCoder(cod); + } + return S_OK; +} + + + +Z7_CLASS_IMP_COM_1( + CSequentialOutTempBufferImp2 + , ISequentialOutStream +) +public: + CInOutTempBuffer TempBuffer; + CMtEncMultiProgress *_mtProgressSpec; + + CSequentialOutTempBufferImp2(): _mtProgressSpec(NULL) {} +}; + +Z7_COM7F_IMF(CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)) +{ + COM_TRY_BEGIN + if (processed) + *processed = 0; + RINOK(TempBuffer.Write_HRESULT(data, size)) + if (processed) + *processed = size; + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); + return S_OK; + COM_TRY_END +} + + +Z7_CLASS_IMP_COM_1( + CSequentialOutMtNotify + , ISequentialOutStream +) +public: + CMyComPtr _stream; + CMtEncMultiProgress *_mtProgressSpec; + + CSequentialOutMtNotify(): _mtProgressSpec(NULL) {} +}; + +Z7_COM7F_IMF(CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)) +{ + UInt32 realProcessed = 0; + HRESULT res = _stream->Write(data, size, &realProcessed); + if (processed) + *processed = realProcessed; + if (_mtProgressSpec) + _mtProgressSpec->AddOutSize(size); + return res; +} + + +static HRESULT FillProps_from_Coder(IUnknown *coder, CByteBuffer &props) +{ + Z7_DECL_CMyComPtr_QI_FROM( + ICompressWriteCoderProperties, + writeCoderProperties, coder) + if (writeCoderProperties) + { + CMyComPtr2_Create outStreamSpec; + outStreamSpec->Init(); + RINOK(writeCoderProperties->WriteCoderProperties(outStreamSpec)) + outStreamSpec->CopyToBuffer(props); + } + else + props.Free(); + return S_OK; +} + +HRESULT CEncoder::Encode1( + DECL_EXTERNAL_CODECS_LOC_VARS + ISequentialInStream *inStream, + // const UInt64 *inStreamSize, + const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, + CFolder &folderItem, + // CRecordVector &coderUnpackSizes, + // UInt64 &unpackSize, + ISequentialOutStream *outStream, + CRecordVector &packSizes, + ICompressProgressInfo *compressProgress) +{ + RINOK(EncoderConstr()) + + if (!_mixerRef) + { + RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce)) + } + + RINOK(_mixer->ReInit2()) + + CMyComPtr2 mtProgress; + CMyComPtr2 mtOutStreamNotify; + + CRecordVector tempBufferSpecs; + CObjectVector > tempBuffers; + + unsigned i; + + for (i = 1; i < _bindInfo.PackStreams.Size(); i++) + { + CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2(); + CMyComPtr tempBuffer = tempBufferSpec; + tempBufferSpecs.Add(tempBufferSpec); + tempBuffers.Add(tempBuffer); + } + + const unsigned numMethods = _bindInfo.Coders.Size(); + + for (i = 0; i < numMethods; i++) + _mixer->SetCoderInfo(i, NULL, NULL, false); + + + /* inStreamSize can be used by BCJ2 to set optimal range of conversion. + But current BCJ2 encoder uses also another way to check exact size of current file. + So inStreamSize is not required. */ + + /* + if (inStreamSize) + _mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL); + */ + + + /* + CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2; + CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; + */ + + CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL; + CMyComPtr outStreamSizeCount; + + // inStreamSizeCountSpec->Init(inStream); + + // ISequentialInStream *inStreamPointer = inStreamSizeCount; + ISequentialInStream *inStreamPointer = inStream; + + CRecordVector outStreamPointers; + + SetFolder(folderItem); + + for (i = 0; i < numMethods; i++) + { + IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + /* + { + CEncoder *sfEncoder = NULL; + Z7_DECL_CMyComPtr_QI_FROM( + IGetSfEncoderInternal, + sf, coder) + if (sf) + { + RINOK(sf->GetSfEncoder(&sfEncoder)); + if (!sfEncoder) + return E_FAIL; + + } + } + */ + /* + #ifdef Z7_EXTERNAL_CODECS + { + Z7_DECL_CMyComPtr_QI_FROM( + ISetCompressCodecsInfo, + setCompressCodecsInfo, coder) + if (setCompressCodecsInfo) + { + // we must use g_ExternalCodecs also + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(_externalCodecs->GetCodecs)) + } + } + #endif + */ + { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoResetInitVector, + resetInitVector, coder) + if (resetInitVector) + { + RINOK(resetInitVector->ResetInitVector()) + } + } + { + Z7_DECL_CMyComPtr_QI_FROM( + ICompressSetCoderPropertiesOpt, + optProps, coder) + if (optProps) + { + const PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; + RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + } + } + // we must write properties from coder after ResetInitVector() + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) + } + + _mixer->SelectMainCoder(false); + const UInt32 mainCoder = _mixer->MainCoderIndex; + + bool useMtProgress = false; + if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder)) + { + #ifdef Z7_ST + if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder)) + #endif + useMtProgress = true; + } + + if (useMtProgress) + { + mtProgress.SetFromCls(new CMtEncMultiProgress); + mtProgress->Init(compressProgress); + + mtOutStreamNotify.SetFromCls(new CSequentialOutMtNotify); + mtOutStreamNotify->_stream = outStream; + mtOutStreamNotify->_mtProgressSpec = mtProgress.ClsPtr(); + + FOR_VECTOR (t, tempBufferSpecs) + { + tempBufferSpecs[t]->_mtProgressSpec = mtProgress.ClsPtr(); + } + } + + + if (_bindInfo.PackStreams.Size() != 0) + { + outStreamSizeCountSpec = new CSequentialOutStreamSizeCount; + outStreamSizeCount = outStreamSizeCountSpec; + outStreamSizeCountSpec->SetStream(mtOutStreamNotify.IsDefined() ? + mtOutStreamNotify.Interface() : outStream); + outStreamSizeCountSpec->Init(); + outStreamPointers.Add(outStreamSizeCount); + } + + for (i = 1; i < _bindInfo.PackStreams.Size(); i++) + outStreamPointers.Add(tempBuffers[i - 1]); + + bool dataAfterEnd_Error; + + RINOK(_mixer->Code( + &inStreamPointer, + outStreamPointers.ConstData(), + mtProgress.IsDefined() ? mtProgress.Interface() : + compressProgress, dataAfterEnd_Error)) + + if (_bindInfo.PackStreams.Size() != 0) + packSizes.Add(outStreamSizeCountSpec->GetSize()); + + for (i = 1; i < _bindInfo.PackStreams.Size(); i++) + { + CInOutTempBuffer &iotb = tempBufferSpecs[i - 1]->TempBuffer; + RINOK(iotb.WriteToStream(outStream)) + packSizes.Add(iotb.GetDataSize()); + } + + /* Code() in some future codec can change properties. + v23: so we fill properties again after Code() */ + for (i = 0; i < numMethods; i++) + { + IUnknown *coder = _mixer->GetCoder(i).GetUnknown(); + RINOK(FillProps_from_Coder(coder, folderItem.Coders[numMethods - 1 - i].Props)) + } + + return S_OK; +} + + +void CEncoder::Encode_Post( + UInt64 unpackSize, + CRecordVector &coderUnpackSizes) +{ + // unpackSize = 0; + for (unsigned i = 0; i < _bindInfo.Coders.Size(); i++) + { + const int bond = _bindInfo.FindBond_for_UnpackStream(DestOut_to_SrcIn[i]); + UInt64 streamSize; + if (bond < 0) + { + // streamSize = inStreamSizeCountSpec->GetSize(); + // unpackSize = streamSize; + streamSize = unpackSize; + } + else + streamSize = _mixer->GetBondStreamSize((unsigned)bond); + coderUnpackSizes.Add(streamSize); + } +} + + +CEncoder::CEncoder(const CCompressionMethodMode &options): + _constructed(false) +{ + if (options.IsEmpty()) + throw 1; + + _options = options; + + #ifdef USE_MIXER_ST + _mixerST = NULL; + #endif + + #ifdef USE_MIXER_MT + _mixerMT = NULL; + #endif + + _mixer = NULL; +} + + +HRESULT CEncoder::EncoderConstr() +{ + if (_constructed) + return S_OK; + if (_options.Methods.IsEmpty()) + { + // it has only password method; + if (!_options.PasswordIsDefined) + throw 1; + if (!_options.Bonds.IsEmpty()) + throw 1; + + CMethodFull method; + method.Id = k_AES; + method.NumStreams = 1; + _options.Methods.Add(method); + + NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; + coderStreamsInfo.NumStreams = 1; + _bindInfo.Coders.Add(coderStreamsInfo); + + _bindInfo.PackStreams.Add(0); + _bindInfo.UnpackCoder = 0; + } + else + { + + UInt32 numOutStreams = 0; + unsigned i; + + for (i = 0; i < _options.Methods.Size(); i++) + { + const CMethodFull &methodFull = _options.Methods[i]; + NCoderMixer2::CCoderStreamsInfo cod; + + cod.NumStreams = methodFull.NumStreams; + + if (_options.Bonds.IsEmpty()) + { + // if there are no bonds in options, we create bonds via first streams of coders + if (i != _options.Methods.Size() - 1) + { + NCoderMixer2::CBond bond; + bond.PackIndex = numOutStreams; + bond.UnpackIndex = i + 1; // it's next coder + _bindInfo.Bonds.Add(bond); + } + else if (cod.NumStreams != 0) + _bindInfo.PackStreams.Insert(0, numOutStreams); + + for (UInt32 j = 1; j < cod.NumStreams; j++) + _bindInfo.PackStreams.Add(numOutStreams + j); + } + + numOutStreams += cod.NumStreams; + + _bindInfo.Coders.Add(cod); + } + + if (!_options.Bonds.IsEmpty()) + { + for (i = 0; i < _options.Bonds.Size(); i++) + { + NCoderMixer2::CBond mixerBond; + const CBond2 &bond = _options.Bonds[i]; + if (bond.InCoder >= _bindInfo.Coders.Size() + || bond.OutCoder >= _bindInfo.Coders.Size() + || bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams) + return E_INVALIDARG; + mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream; + mixerBond.UnpackIndex = bond.InCoder; + _bindInfo.Bonds.Add(mixerBond); + } + + for (i = 0; i < numOutStreams; i++) + if (_bindInfo.FindBond_for_PackStream(i) == -1) + _bindInfo.PackStreams.Add(i); + } + + if (!_bindInfo.SetUnpackCoder()) + return E_INVALIDARG; + + if (!_bindInfo.CalcMapsAndCheck()) + return E_INVALIDARG; + + if (_bindInfo.PackStreams.Size() != 1) + { + /* main_PackStream is pack stream of main path of coders tree. + We find main_PackStream, and place to start of list of out streams. + It allows to use more optimal memory usage for temp buffers, + if main_PackStream is largest stream. */ + + UInt32 ci = _bindInfo.UnpackCoder; + + for (;;) + { + if (_bindInfo.Coders[ci].NumStreams == 0) + break; + + const UInt32 outIndex = _bindInfo.Coder_to_Stream[ci]; + const int bond = _bindInfo.FindBond_for_PackStream(outIndex); + if (bond >= 0) + { + ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex; + continue; + } + + const int si = _bindInfo.FindStream_in_PackStreams(outIndex); + if (si >= 0) + _bindInfo.PackStreams.MoveToFront((unsigned)si); + break; + } + } + + if (_options.PasswordIsDefined) + { + unsigned numCryptoStreams = _bindInfo.PackStreams.Size(); + + unsigned numInStreams = _bindInfo.Coders.Size(); + + for (i = 0; i < numCryptoStreams; i++) + { + NCoderMixer2::CBond bond; + bond.UnpackIndex = numInStreams + i; + bond.PackIndex = _bindInfo.PackStreams[i]; + _bindInfo.Bonds.Add(bond); + } + _bindInfo.PackStreams.Clear(); + + /* + if (numCryptoStreams == 0) + numCryptoStreams = 1; + */ + + for (i = 0; i < numCryptoStreams; i++) + { + CMethodFull method; + method.NumStreams = 1; + method.Id = k_AES; + _options.Methods.Add(method); + + NCoderMixer2::CCoderStreamsInfo cod; + cod.NumStreams = 1; + _bindInfo.Coders.Add(cod); + + _bindInfo.PackStreams.Add(numOutStreams++); + } + } + + } + + for (unsigned i = _options.Methods.Size(); i != 0;) + _decompressionMethods.Add(_options.Methods[--i].Id); + + if (_bindInfo.Coders.Size() > 16) + return E_INVALIDARG; + if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16) + return E_INVALIDARG; + + if (!_bindInfo.CalcMapsAndCheck()) + return E_INVALIDARG; + + InitBindConv(); + _constructed = true; + return S_OK; +} + +CEncoder::~CEncoder() {} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zEncode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zEncode.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zEncode.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,92 +1,95 @@ -// 7zEncode.h - -#ifndef __7Z_ENCODE_H -#define __7Z_ENCODE_H - -#include "7zCompressionMode.h" - -#include "../Common/CoderMixer2.h" - -#include "7zItem.h" - -namespace NArchive { -namespace N7z { - -class CMtEncMultiProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr _progress; - #ifndef _7ZIP_ST - NWindows::NSynchronization::CCriticalSection CriticalSection; - #endif - -public: - UInt64 OutSize; - - CMtEncMultiProgress(): OutSize(0) {} - - void Init(ICompressProgressInfo *progress); - - void AddOutSize(UInt64 addOutSize) - { - #ifndef _7ZIP_ST - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - #endif - OutSize += addOutSize; - } - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -class CEncoder -{ - #ifdef USE_MIXER_ST - NCoderMixer2::CMixerST *_mixerST; - #endif - #ifdef USE_MIXER_MT - NCoderMixer2::CMixerMT *_mixerMT; - #endif - - NCoderMixer2::CMixer *_mixer; - CMyComPtr _mixerRef; - - CCompressionMethodMode _options; - NCoderMixer2::CBindInfo _bindInfo; - CRecordVector _decompressionMethods; - - CRecordVector _SrcIn_to_DestOut; - CRecordVector _SrcOut_to_DestIn; - // CRecordVector _DestIn_to_SrcOut; - CRecordVector _DestOut_to_SrcIn; - - void InitBindConv(); - void SetFolder(CFolder &folder); - - HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS - const UInt64 *inSizeForReduce); - - bool _constructed; -public: - - CEncoder(const CCompressionMethodMode &options); - ~CEncoder(); - HRESULT EncoderConstr(); - HRESULT Encode( - DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, - // const UInt64 *inStreamSize, - const UInt64 *inSizeForReduce, - CFolder &folderItem, - CRecordVector &coderUnpackSizes, - UInt64 &unpackSize, - ISequentialOutStream *outStream, - CRecordVector &packSizes, - ICompressProgressInfo *compressProgress); -}; - -}} - -#endif +// 7zEncode.h + +#ifndef ZIP7_INC_7Z_ENCODE_H +#define ZIP7_INC_7Z_ENCODE_H + +#include "7zCompressionMode.h" + +#include "../Common/CoderMixer2.h" + +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +Z7_CLASS_IMP_COM_1( + CMtEncMultiProgress, + ICompressProgressInfo +) + CMyComPtr _progress; + #ifndef Z7_ST + NWindows::NSynchronization::CCriticalSection CriticalSection; + #endif + +public: + UInt64 OutSize; + + CMtEncMultiProgress(): OutSize(0) {} + + void Init(ICompressProgressInfo *progress); + + void AddOutSize(UInt64 addOutSize) + { + #ifndef Z7_ST + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + #endif + OutSize += addOutSize; + } +}; + + +class CEncoder Z7_final MY_UNCOPYABLE +{ + #ifdef USE_MIXER_ST + NCoderMixer2::CMixerST *_mixerST; + #endif + #ifdef USE_MIXER_MT + NCoderMixer2::CMixerMT *_mixerMT; + #endif + + NCoderMixer2::CMixer *_mixer; + CMyComPtr _mixerRef; + + CCompressionMethodMode _options; + NCoderMixer2::CBindInfo _bindInfo; + CRecordVector _decompressionMethods; + + CRecordVector SrcIn_to_DestOut; + CRecordVector SrcOut_to_DestIn; + // CRecordVector DestIn_to_SrcOut; + CRecordVector DestOut_to_SrcIn; + + void InitBindConv(); + void SetFolder(CFolder &folder); + + HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS + const UInt64 *inSizeForReduce); + + bool _constructed; +public: + + CEncoder(const CCompressionMethodMode &options); + ~CEncoder(); + HRESULT EncoderConstr(); + HRESULT Encode1( + DECL_EXTERNAL_CODECS_LOC_VARS + ISequentialInStream *inStream, + // const UInt64 *inStreamSize, + const UInt64 *inSizeForReduce, + UInt64 expectedDataSize, + CFolder &folderItem, + // CRecordVector &coderUnpackSizes, + // UInt64 &unpackSize, + ISequentialOutStream *outStream, + CRecordVector &packSizes, + ICompressProgressInfo *compressProgress); + + void Encode_Post( + UInt64 unpackSize, + CRecordVector &coderUnpackSizes); + +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zExtract.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zExtract.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zExtract.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zExtract.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -1,408 +1,444 @@ -// 7zExtract.cpp - -#include "StdAfx.h" - -#include "../../../../C/7zCrc.h" - -#include "../../../Common/ComTry.h" - -#include "../../Common/ProgressUtils.h" - -#include "7zDecode.h" -#include "7zHandler.h" - -// EXTERN_g_ExternalCodecs - -namespace NArchive { -namespace N7z { - -class CFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; -public: - bool TestMode; - bool CheckCrc; -private: - bool _fileIsOpen; - bool _calcCrc; - UInt32 _crc; - UInt64 _rem; - - const UInt32 *_indexes; - unsigned _numFiles; - unsigned _fileIndex; - - HRESULT OpenFile(bool isCorrupted = false); - HRESULT CloseFile_and_SetResult(Int32 res); - HRESULT CloseFile(); - HRESULT ProcessEmptyFiles(); - -public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - - const CDbEx *_db; - CMyComPtr ExtractCallback; - - bool ExtraWriteWasCut; - - CFolderOutStream(): - TestMode(false), - CheckCrc(true) - {} - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - - HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles); - HRESULT FlushCorrupted(Int32 callbackOperationResult); - - bool WasWritingFinished() const { return _numFiles == 0; } -}; - - -HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles) -{ - _fileIndex = startIndex; - _indexes = indexes; - _numFiles = numFiles; - - _fileIsOpen = false; - ExtraWriteWasCut = false; - - return ProcessEmptyFiles(); -} - -HRESULT CFolderOutStream::OpenFile(bool isCorrupted) -{ - const CFileItem &fi = _db->Files[_fileIndex]; - UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); - Int32 askMode = (_fileIndex == nextFileIndex) ? - (TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : - NExtract::NAskMode::kSkip; - - if (isCorrupted - && askMode == NExtract::NAskMode::kExtract - && !_db->IsItemAnti(_fileIndex) - && !fi.IsDir) - askMode = NExtract::NAskMode::kTest; - - CMyComPtr realOutStream; - RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)); - - _stream = realOutStream; - _crc = CRC_INIT_VAL; - _calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir); - - _fileIsOpen = true; - _rem = fi.Size; - - if (askMode == NExtract::NAskMode::kExtract - && !realOutStream - && !_db->IsItemAnti(_fileIndex) - && !fi.IsDir) - askMode = NExtract::NAskMode::kSkip; - return ExtractCallback->PrepareOperation(askMode); -} - -HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res) -{ - _stream.Release(); - _fileIsOpen = false; - - if (!_indexes) - _numFiles--; - else if (*_indexes == _fileIndex) - { - _indexes++; - _numFiles--; - } - - _fileIndex++; - return ExtractCallback->SetOperationResult(res); -} - -HRESULT CFolderOutStream::CloseFile() -{ - const CFileItem &fi = _db->Files[_fileIndex]; - return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ? - NExtract::NOperationResult::kOK : - NExtract::NOperationResult::kCRCError); -} - -HRESULT CFolderOutStream::ProcessEmptyFiles() -{ - while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0) - { - RINOK(OpenFile()); - RINOK(CloseFile()); - } - return S_OK; -} - -STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (_fileIsOpen) - { - UInt32 cur = (size < _rem ? size : (UInt32)_rem); - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, cur, &cur); - if (_calcCrc) - _crc = CrcUpdate(_crc, data, cur); - if (processedSize) - *processedSize += cur; - data = (const Byte *)data + cur; - size -= cur; - _rem -= cur; - if (_rem == 0) - { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); - } - RINOK(result); - if (cur == 0) - break; - continue; - } - - RINOK(ProcessEmptyFiles()); - if (_numFiles == 0) - { - // we support partial extracting - /* - if (processedSize) - *processedSize += size; - break; - */ - ExtraWriteWasCut = true; - // return S_FALSE; - return k_My_HRESULT_WritingWasCut; - } - RINOK(OpenFile()); - } - - return S_OK; -} - -HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult) -{ - while (_numFiles != 0) - { - if (_fileIsOpen) - { - RINOK(CloseFile_and_SetResult(callbackOperationResult)); - } - else - { - RINOK(OpenFile(true)); - } - } - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec) -{ - COM_TRY_BEGIN - - CMyComPtr extractCallback = extractCallbackSpec; - - UInt64 importantTotalUnpacked = 0; - - // numItems = (UInt32)(Int32)-1; - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _db.Files.Size(); - - if (numItems == 0) - return S_OK; - - { - CNum prevFolder = kNumNoIndex; - UInt32 nextFile = 0; - - UInt32 i; - - for (i = 0; i < numItems; i++) - { - UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex == kNumNoIndex) - continue; - if (folderIndex != prevFolder || fileIndex < nextFile) - nextFile = _db.FolderStartFileIndex[folderIndex]; - for (CNum index = nextFile; index <= fileIndex; index++) - importantTotalUnpacked += _db.Files[index].Size; - nextFile = fileIndex + 1; - prevFolder = folderIndex; - } - } - - RINOK(extractCallback->SetTotal(importantTotalUnpacked)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CDecoder decoder( - #if !defined(USE_MIXER_MT) - false - #elif !defined(USE_MIXER_ST) - true - #elif !defined(__7Z_SET_PROPERTIES) - #ifdef _7ZIP_ST - false - #else - true - #endif - #else - _useMultiThreadMixer - #endif - ); - - UInt64 curPacked, curUnpacked; - - CMyComPtr callbackMessage; - extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); - - CFolderOutStream *folderOutStream = new CFolderOutStream; - CMyComPtr outStream(folderOutStream); - - folderOutStream->_db = &_db; - folderOutStream->ExtractCallback = extractCallback; - folderOutStream->TestMode = (testModeSpec != 0); - folderOutStream->CheckCrc = (_crcSize != 0); - - for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked) - { - RINOK(lps->SetCur()); - - if (i >= numItems) - break; - - curUnpacked = 0; - curPacked = 0; - - UInt32 fileIndex = allFilesMode ? i : indices[i]; - CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; - - UInt32 numSolidFiles = 1; - - if (folderIndex != kNumNoIndex) - { - curPacked = _db.GetFolderFullPackSize(folderIndex); - UInt32 nextFile = fileIndex + 1; - fileIndex = _db.FolderStartFileIndex[folderIndex]; - UInt32 k; - - for (k = i + 1; k < numItems; k++) - { - UInt32 fileIndex2 = allFilesMode ? k : indices[k]; - if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex - || fileIndex2 < nextFile) - break; - nextFile = fileIndex2 + 1; - } - - numSolidFiles = k - i; - - for (k = fileIndex; k < nextFile; k++) - curUnpacked += _db.Files[k].Size; - } - - { - HRESULT result = folderOutStream->Init(fileIndex, - allFilesMode ? NULL : indices + i, - numSolidFiles); - - i += numSolidFiles; - - RINOK(result); - } - - // to test solid block with zero unpacked size we disable that code - if (folderOutStream->WasWritingFinished()) - continue; - - #ifndef _NO_CRYPTO - CMyComPtr getTextPassword; - if (extractCallback) - extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); - #endif - - try - { - #ifndef _NO_CRYPTO - bool isEncrypted = false; - bool passwordIsDefined = false; - UString password; - #endif - - - HRESULT result = decoder.Decode( - EXTERNAL_CODECS_VARS - _inStream, - _db.ArcInfo.DataStartPosition, - _db, folderIndex, - &curUnpacked, - - outStream, - progress, - NULL // *inStreamMainRes - - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) && !defined(_SFX) - , true, _numThreads - #endif - ); - - if (result == S_FALSE || result == E_NOTIMPL) - { - bool wasFinished = folderOutStream->WasWritingFinished(); - - int resOp = (result == S_FALSE ? - NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kUnsupportedMethod); - - RINOK(folderOutStream->FlushCorrupted(resOp)); - - if (wasFinished) - { - // we don't show error, if it's after required files - if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage) - { - RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)); - } - } - continue; - } - - if (result != S_OK) - return result; - - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); - continue; - } - catch(...) - { - RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)); - // continue; - return E_FAIL; - } - } - - return S_OK; - - COM_TRY_END -} - -}} +// 7zExtract.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" + +#include "../../../Common/ComTry.h" + +#include "../../Common/ProgressUtils.h" + +#include "7zDecode.h" +#include "7zHandler.h" + +// EXTERN_g_ExternalCodecs + +namespace NArchive { +namespace N7z { + +Z7_CLASS_IMP_COM_1( + CFolderOutStream + , ISequentialOutStream + /* , ICompressGetSubStreamSize */ +) + CMyComPtr _stream; +public: + bool TestMode; + bool CheckCrc; +private: + bool _fileIsOpen; + bool _calcCrc; + UInt32 _crc; + UInt64 _rem; + + const UInt32 *_indexes; + // unsigned _startIndex; + unsigned _numFiles; + unsigned _fileIndex; + + HRESULT OpenFile(bool isCorrupted = false); + HRESULT CloseFile_and_SetResult(Int32 res); + HRESULT CloseFile(); + HRESULT ProcessEmptyFiles(); + +public: + const CDbEx *_db; + CMyComPtr ExtractCallback; + + bool ExtraWriteWasCut; + + CFolderOutStream(): + TestMode(false), + CheckCrc(true) + {} + + HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles); + HRESULT FlushCorrupted(Int32 callbackOperationResult); + + bool WasWritingFinished() const { return _numFiles == 0; } +}; + + +HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles) +{ + // _startIndex = startIndex; + _fileIndex = startIndex; + _indexes = indexes; + _numFiles = numFiles; + + _fileIsOpen = false; + ExtraWriteWasCut = false; + + return ProcessEmptyFiles(); +} + +HRESULT CFolderOutStream::OpenFile(bool isCorrupted) +{ + const CFileItem &fi = _db->Files[_fileIndex]; + const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex); + Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract : + NExtract::NAskMode::kSkip; + + if (isCorrupted + && askMode == NExtract::NAskMode::kExtract + && !_db->IsItemAnti(_fileIndex) + && !fi.IsDir) + askMode = NExtract::NAskMode::kTest; + + CMyComPtr realOutStream; + RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode)) + + _stream = realOutStream; + _crc = CRC_INIT_VAL; + _calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir); + + _fileIsOpen = true; + _rem = fi.Size; + + if (askMode == NExtract::NAskMode::kExtract + && !realOutStream + && !_db->IsItemAnti(_fileIndex) + && !fi.IsDir) + askMode = NExtract::NAskMode::kSkip; + return ExtractCallback->PrepareOperation(askMode); +} + +HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res) +{ + _stream.Release(); + _fileIsOpen = false; + + if (!_indexes) + _numFiles--; + else if (*_indexes == _fileIndex) + { + _indexes++; + _numFiles--; + } + + _fileIndex++; + return ExtractCallback->SetOperationResult(res); +} + +HRESULT CFolderOutStream::CloseFile() +{ + const CFileItem &fi = _db->Files[_fileIndex]; + return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ? + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kCRCError); +} + +HRESULT CFolderOutStream::ProcessEmptyFiles() +{ + while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0) + { + RINOK(OpenFile()) + RINOK(CloseFile()) + } + return S_OK; +} + +Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (_fileIsOpen) + { + UInt32 cur = (size < _rem ? size : (UInt32)_rem); + if (_calcCrc) + { + const UInt32 k_Step = (UInt32)1 << 20; + if (cur > k_Step) + cur = k_Step; + } + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, cur, &cur); + if (_calcCrc) + _crc = CrcUpdate(_crc, data, cur); + if (processedSize) + *processedSize += cur; + data = (const Byte *)data + cur; + size -= cur; + _rem -= cur; + if (_rem == 0) + { + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) + } + RINOK(result) + if (cur == 0) + break; + continue; + } + + RINOK(ProcessEmptyFiles()) + if (_numFiles == 0) + { + // we support partial extracting + /* + if (processedSize) + *processedSize += size; + break; + */ + ExtraWriteWasCut = true; + // return S_FALSE; + return k_My_HRESULT_WritingWasCut; + } + RINOK(OpenFile()) + } + + return S_OK; +} + +HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult) +{ + while (_numFiles != 0) + { + if (_fileIsOpen) + { + RINOK(CloseFile_and_SetResult(callbackOperationResult)) + } + else + { + RINOK(OpenFile(true)) + } + } + return S_OK; +} + +/* +Z7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + *value = 0; + // const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex; + const unsigned numFiles_Original = _numFiles; + if (subStream >= numFiles_Original) + return S_FALSE; // E_FAIL; + *value = _db->Files[_startIndex + (unsigned)subStream].Size; + return S_OK; +} +*/ + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)) +{ + // for GCC + // CFolderOutStream *folderOutStream = new CFolderOutStream; + // CMyComPtr outStream(folderOutStream); + + COM_TRY_BEGIN + + CMyComPtr extractCallback = extractCallbackSpec; + + UInt64 importantTotalUnpacked = 0; + + // numItems = (UInt32)(Int32)-1; + + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _db.Files.Size(); + + if (numItems == 0) + return S_OK; + + { + CNum prevFolder = kNumNoIndex; + UInt32 nextFile = 0; + + UInt32 i; + + for (i = 0; i < numItems; i++) + { + const UInt32 fileIndex = allFilesMode ? i : indices[i]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex == kNumNoIndex) + continue; + if (folderIndex != prevFolder || fileIndex < nextFile) + nextFile = _db.FolderStartFileIndex[folderIndex]; + for (CNum index = nextFile; index <= fileIndex; index++) + importantTotalUnpacked += _db.Files[index].Size; + nextFile = fileIndex + 1; + prevFolder = folderIndex; + } + } + + RINOK(extractCallback->SetTotal(importantTotalUnpacked)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + CDecoder decoder( + #if !defined(USE_MIXER_MT) + false + #elif !defined(USE_MIXER_ST) + true + #elif !defined(Z7_7Z_SET_PROPERTIES) + #ifdef Z7_ST + false + #else + true + #endif + #else + _useMultiThreadMixer + #endif + ); + + UInt64 curPacked, curUnpacked; + + CMyComPtr callbackMessage; + extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); + + CFolderOutStream *folderOutStream = new CFolderOutStream; + CMyComPtr outStream(folderOutStream); + + folderOutStream->_db = &_db; + folderOutStream->ExtractCallback = extractCallback; + folderOutStream->TestMode = (testModeSpec != 0); + folderOutStream->CheckCrc = (_crcSize != 0); + + for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked) + { + RINOK(lps->SetCur()) + + if (i >= numItems) + break; + + curUnpacked = 0; + curPacked = 0; + + UInt32 fileIndex = allFilesMode ? i : indices[i]; + const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex]; + + UInt32 numSolidFiles = 1; + + if (folderIndex != kNumNoIndex) + { + curPacked = _db.GetFolderFullPackSize(folderIndex); + UInt32 nextFile = fileIndex + 1; + fileIndex = _db.FolderStartFileIndex[folderIndex]; + UInt32 k; + + for (k = i + 1; k < numItems; k++) + { + const UInt32 fileIndex2 = allFilesMode ? k : indices[k]; + if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex + || fileIndex2 < nextFile) + break; + nextFile = fileIndex2 + 1; + } + + numSolidFiles = k - i; + + for (k = fileIndex; k < nextFile; k++) + curUnpacked += _db.Files[k].Size; + } + + { + const HRESULT result = folderOutStream->Init(fileIndex, + allFilesMode ? NULL : indices + i, + numSolidFiles); + + i += numSolidFiles; + + RINOK(result) + } + + if (folderOutStream->WasWritingFinished()) + { + // for debug: to test zero size stream unpacking + // if (folderIndex == kNumNoIndex) // enable this check for debug + continue; + } + + if (folderIndex == kNumNoIndex) + return E_FAIL; + + #ifndef Z7_NO_CRYPTO + CMyComPtr getTextPassword; + if (extractCallback) + extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + #endif + + try + { + #ifndef Z7_NO_CRYPTO + bool isEncrypted = false; + bool passwordIsDefined = false; + UString_Wipe password; + #endif + + bool dataAfterEnd_Error = false; + + const HRESULT result = decoder.Decode( + EXTERNAL_CODECS_VARS + _inStream, + _db.ArcInfo.DataStartPosition, + _db, folderIndex, + &curUnpacked, + + outStream, + lps, + NULL // *inStreamMainRes + , dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) + , true, _numThreads, _memUsage_Decompress + #endif + ); + + if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error) + { + const bool wasFinished = folderOutStream->WasWritingFinished(); + + int resOp = NExtract::NOperationResult::kDataError; + + if (result != S_FALSE) + { + if (result == E_NOTIMPL) + resOp = NExtract::NOperationResult::kUnsupportedMethod; + else if (wasFinished && dataAfterEnd_Error) + resOp = NExtract::NOperationResult::kDataAfterEnd; + } + + RINOK(folderOutStream->FlushCorrupted(resOp)) + + if (wasFinished) + { + // we don't show error, if it's after required files + if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage) + { + RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp)) + } + } + continue; + } + + if (result != S_OK) + return result; + + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) + continue; + } + catch(...) + { + RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError)) + // continue; + // return E_FAIL; + throw; + } + } + + return S_OK; + + COM_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zFolderInStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zFolderInStream.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.cpp 2023-05-11 16:00:00.000000000 +0000 @@ -1,136 +1,264 @@ -// 7zFolderInStream.cpp - -#include "StdAfx.h" - -#include "7zFolderInStream.h" - -namespace NArchive { -namespace N7z { - -void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, - const UInt32 *indexes, unsigned numFiles) -{ - _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; - - _stream.Release(); -} - -HRESULT CFolderInStream::OpenStream() -{ - _pos = 0; - _crc = CRC_INIT_VAL; - _size_Defined = false; - _size = 0; - - while (_index < _numFiles) - { - CMyComPtr stream; - HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream); - if (result != S_OK) - { - if (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; - } - return S_OK; - } - - _index++; - RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - AddFileInfo(result == S_OK); - } - return S_OK; -} - -void CFolderInStream::AddFileInfo(bool isProcessed) -{ - Processed.Add(isProcessed); - Sizes.Add(_pos); - CRCs.Add(CRC_GET_DIGEST(_crc)); -} - -STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - while (size != 0) - { - if (_stream) - { - UInt32 processed2; - RINOK(_stream->Read(data, size, &processed2)); - if (processed2 != 0) - { - _crc = CrcUpdate(_crc, data, processed2); - _pos += processed2; - if (processedSize) - *processedSize = processed2; - return S_OK; - } - - _stream.Release(); - _index++; - AddFileInfo(true); - - _pos = 0; - _crc = CRC_INIT_VAL; - _size_Defined = false; - _size = 0; - - RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - } - - if (_index >= _numFiles) - break; - RINOK(OpenStream()); - } - return S_OK; -} - -STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) -{ - *value = 0; - if (subStream > Sizes.Size()) - return S_FALSE; // E_FAIL; - - unsigned index = (unsigned)subStream; - if (index < Sizes.Size()) - { - *value = Sizes[index]; - return S_OK; - } - - if (!_size_Defined) - { - *value = _pos; - return S_FALSE; - } - - *value = (_pos > _size ? _pos : _size); - return S_OK; -} - -}} +// 7zFolderInStream.cpp + +#include "StdAfx.h" + +#include "../../../Windows/TimeUtils.h" + +#include "7zFolderInStream.h" + +namespace NArchive { +namespace N7z { + +void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, + const UInt32 *indexes, unsigned numFiles) +{ + _updateCallback = updateCallback; + _indexes = indexes; + _numFiles = numFiles; + + _totalSize_for_Coder = 0; + ClearFileInfo(); + + Processed.ClearAndReserve(numFiles); + Sizes.ClearAndReserve(numFiles); + CRCs.ClearAndReserve(numFiles); + TimesDefined.ClearAndReserve(numFiles); + MTimes.ClearAndReserve(Need_MTime ? numFiles : (unsigned)0); + CTimes.ClearAndReserve(Need_CTime ? numFiles : (unsigned)0); + ATimes.ClearAndReserve(Need_ATime ? numFiles : (unsigned)0); + Attribs.ClearAndReserve(Need_Attrib ? numFiles : (unsigned)0); + + // FolderCrc = CRC_INIT_VAL; + _stream.Release(); +} + +void CFolderInStream::ClearFileInfo() +{ + _pos = 0; + _crc = CRC_INIT_VAL; + _size_Defined = false; + _times_Defined = false; + _size = 0; + FILETIME_Clear(_mTime); + FILETIME_Clear(_cTime); + FILETIME_Clear(_aTime); + _attrib = 0; +} + +HRESULT CFolderInStream::OpenStream() +{ + while (Processed.Size() < _numFiles) + { + CMyComPtr stream; + const HRESULT result = _updateCallback->GetStream(_indexes[Processed.Size()], &stream); + if (result != S_OK && result != S_FALSE) + return result; + + _stream = stream; + + if (stream) + { + { + 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; + } + } + + RINOK(AddFileInfo(result == S_OK)) + } + return S_OK; +} + +static void AddFt(CRecordVector &vec, const FILETIME &ft) +{ + 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); + CRCs.AddInReserved(CRC_GET_DIGEST(_crc)); + if (Need_Attrib) Attribs.AddInReserved(_attrib); + TimesDefined.AddInReserved(_times_Defined); + if (Need_MTime) AddFt(MTimes, _mTime); + if (Need_CTime) AddFt(CTimes, _cTime); + if (Need_ATime) AddFt(ATimes, _aTime); + ClearFileInfo(); + /* + if (isProcessed && _reportArcProp) + RINOK(ReportItemProps(_reportArcProp, index, _pos, &crc)) + */ + return _updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +Z7_COM7F_IMF(CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + while (size != 0) + { + if (_stream) + { + /* + if (_pos == 0) + { + const UInt32 align = (UInt32)1 << AlignLog; + const UInt32 offset = (UInt32)_totalSize_for_Coder & (align - 1); + if (offset != 0) + { + UInt32 cur = align - offset; + if (cur > size) + cur = size; + memset(data, 0, cur); + data = (Byte *)data + cur; + size -= cur; + // _pos += cur; // for debug + _totalSize_for_Coder += cur; + if (processedSize) + *processedSize += cur; + continue; + } + } + */ + UInt32 cur = size; + const UInt32 kMax = (UInt32)1 << 20; + if (cur > kMax) + cur = kMax; + RINOK(_stream->Read(data, cur, &cur)) + if (cur != 0) + { + // if (Need_Crc) + _crc = CrcUpdate(_crc, data, cur); + /* + if (FolderCrc) + FolderCrc = CrcUpdate(FolderCrc, data, cur); + */ + _pos += cur; + _totalSize_for_Coder += cur; + if (processedSize) + *processedSize = cur; // use +=cur, if continue is possible in loop + return S_OK; + } + + _stream.Release(); + RINOK(AddFileInfo(true)) + } + + if (Processed.Size() >= _numFiles) + break; + RINOK(OpenStream()) + } + return S_OK; +} + +Z7_COM7F_IMF(CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + *value = 0; + if (subStream > Sizes.Size()) + return S_FALSE; // E_FAIL; + + const unsigned index = (unsigned)subStream; + if (index < Sizes.Size()) + { + *value = Sizes[index]; + return S_OK; + } + + if (!_size_Defined) + { + *value = _pos; + return S_FALSE; + } + + *value = (_pos > _size ? _pos : _size); + return S_OK; +} + + +/* +HRESULT CFolderInStream::CloseCrcStream() +{ + if (!_crcStream) + return S_OK; + if (!_crcStream_Spec->WasFinished()) + return E_FAIL; + _crc = _crcStream_Spec->GetCRC() ^ CRC_INIT_VAL; // change it + const UInt64 size = _crcStream_Spec->GetSize(); + _pos = size; + _totalSize_for_Coder += size; + _crcStream.Release(); + // _crcStream->ReleaseStream(); + _stream.Release(); + return AddFileInfo(true); +} + +Z7_COM7F_IMF(CFolderInStream::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream) +{ + RINOK(CloseCrcStream()) + *stream = NULL; + *streamIndexRes = Processed.Size(); + if (Processed.Size() >= _numFiles) + return S_OK; + RINOK(OpenStream()); + if (!_stream) + return S_OK; + if (!_crcStream) + { + _crcStream_Spec = new CSequentialInStreamWithCRC; + _crcStream = _crcStream_Spec; + } + _crcStream_Spec->Init(); + _crcStream_Spec->SetStream(_stream); + *stream = _crcStream; + _crcStream->AddRef(); + return S_OK; +} +*/ + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zFolderInStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zFolderInStream.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zFolderInStream.h 2023-05-11 16:00:00.000000000 +0000 @@ -1,61 +1,101 @@ -// 7zFolderInStream.h - -#ifndef __7Z_FOLDER_IN_STREAM_H -#define __7Z_FOLDER_IN_STREAM_H - -#include "../../../../C/7zCrc.h" - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyVector.h" - -#include "../../ICoder.h" -#include "../IArchive.h" - -namespace NArchive { -namespace N7z { - -class CFolderInStream: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _pos; - UInt32 _crc; - bool _size_Defined; - UInt64 _size; - - const UInt32 *_indexes; - unsigned _numFiles; - unsigned _index; - - CMyComPtr _updateCallback; - - HRESULT OpenStream(); - void AddFileInfo(bool isProcessed); - -public: - CRecordVector Processed; - CRecordVector CRCs; - CRecordVector Sizes; - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); - - void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles); - - bool WasFinished() const { return _index == _numFiles; } - - UInt64 GetFullSize() const - { - UInt64 size = 0; - FOR_VECTOR (i, Sizes) - size += Sizes[i]; - return size; - } -}; - -}} - -#endif +// 7zFolderInStream.h + +#ifndef ZIP7_INC_7Z_FOLDER_IN_STREAM_H +#define ZIP7_INC_7Z_FOLDER_IN_STREAM_H + +#include "../../../../C/7zCrc.h" + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" +// #include "../Common/InStreamWithCRC.h" + +#include "../../ICoder.h" +#include "../IArchive.h" + +namespace NArchive { +namespace N7z { + +Z7_CLASS_IMP_COM_2( + CFolderInStream + , ISequentialInStream + , ICompressGetSubStreamSize +) + /* + Z7_COM7F_IMP(GetNextStream(UInt64 *streamIndex)) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + */ + + CMyComPtr _stream; + UInt64 _totalSize_for_Coder; + UInt64 _pos; + UInt32 _crc; + bool _size_Defined; + bool _times_Defined; + UInt64 _size; + FILETIME _mTime; + FILETIME _cTime; + FILETIME _aTime; + UInt32 _attrib; + + unsigned _numFiles; + const UInt32 *_indexes; + + CMyComPtr _updateCallback; + + void ClearFileInfo(); + HRESULT OpenStream(); + HRESULT AddFileInfo(bool isProcessed); + // HRESULT CloseCrcStream(); +public: + bool Need_MTime; + bool Need_CTime; + bool Need_ATime; + bool Need_Attrib; + // bool Need_Crc; + // bool Need_FolderCrc; + // unsigned AlignLog; + + CRecordVector Processed; + CRecordVector Sizes; + CRecordVector CRCs; + CRecordVector Attribs; + CRecordVector TimesDefined; + CRecordVector MTimes; + CRecordVector CTimes; + CRecordVector ATimes; + // UInt32 FolderCrc; + + // UInt32 GetFolderCrc() const { return CRC_GET_DIGEST(FolderCrc); } + // CSequentialInStreamWithCRC *_crcStream_Spec; + // CMyComPtr _crcStream; + // CMyComPtr _reportArcProp; + + void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles); + + bool WasFinished() const { return Processed.Size() == _numFiles; } + + UInt64 Get_TotalSize_for_Coder() const { return _totalSize_for_Coder; } + /* + UInt64 GetFullSize() const + { + UInt64 size = 0; + FOR_VECTOR (i, Sizes) + size += Sizes[i]; + return size; + } + */ + + CFolderInStream(): + Need_MTime(false), + Need_CTime(false), + Need_ATime(false), + Need_Attrib(false) + // , Need_Crc(true) + // , Need_FolderCrc(false) + // , AlignLog(0) + {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,755 +1,795 @@ -// 7zHandler.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" - -#ifndef __7Z_SET_PROPERTIES -#include "../../../Windows/System.h" -#endif - -#include "../Common/ItemNameUtils.h" - -#include "7zHandler.h" -#include "7zProperties.h" - -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY -#include "../Common/ParseProperties.h" -#endif -#endif - -using namespace NWindows; -using namespace NCOM; - -namespace NArchive { -namespace N7z { - -CHandler::CHandler() -{ - #ifndef _NO_CRYPTO - _isEncrypted = false; - _passwordIsDefined = false; - #endif - - #ifdef EXTRACT_ONLY - - _crcSize = 4; - - #ifdef __7Z_SET_PROPERTIES - _numThreads = NSystem::GetNumberOfProcessors(); - _useMultiThreadMixer = true; - #endif - - #endif -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _db.Files.Size(); - return S_OK; -} - -#ifdef _SFX - -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) -{ - *numProps = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) -{ - return E_NOTIMPL; -} - -#else - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - kpidMethod, - kpidSolid, - kpidNumBlocks - // , kpidIsTree -}; - -IMP_IInArchive_ArcProps - -static inline char GetHex(unsigned value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} - -static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id) -{ - int len = 0; - do - { - s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; - s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; - } - while (id != 0); - return (unsigned)-len; -} - -static void ConvertMethodIdToString(AString &res, UInt64 id) -{ - const unsigned kLen = 32; - char s[kLen]; - unsigned len = kLen - 1; - s[len] = 0; - res += s + len - ConvertMethodIdToString_Back(s + len, id); -} - -static unsigned GetStringForSizeValue(char *s, UInt32 val) -{ - unsigned i; - for (i = 0; i <= 31; i++) - if (((UInt32)1 << i) == val) - { - if (i < 10) - { - s[0] = (char)('0' + i); - s[1] = 0; - return 1; - } - if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); } - else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); } - else { s[0] = '3'; s[1] = (char)('0' + i - 30); } - s[2] = 0; - return 2; - } - char c = 'b'; - if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } - else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } - ::ConvertUInt32ToString(val, s); - unsigned pos = MyStringLen(s); - s[pos++] = c; - s[pos] = 0; - return pos; -} - -/* -static inline void AddHexToString(UString &res, Byte value) -{ - res += GetHex((Byte)(value >> 4)); - res += GetHex((Byte)(value & 0xF)); -} -*/ - -static char *AddProp32(char *s, const char *name, UInt32 v) -{ - *s++ = ':'; - s = MyStpCpy(s, name); - ::ConvertUInt32ToString(v, s); - return s + MyStringLen(s); -} - -void CHandler::AddMethodName(AString &s, UInt64 id) -{ - AString name; - FindMethod(EXTERNAL_CODECS_VARS id, name); - if (name.IsEmpty()) - ConvertMethodIdToString(s, id); - else - s += name; -} - -#endif - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - #ifndef _SFX - COM_TRY_BEGIN - #endif - NCOM::CPropVariant prop; - switch (propID) - { - #ifndef _SFX - case kpidMethod: - { - AString s; - const CParsedMethods &pm = _db.ParsedMethods; - FOR_VECTOR (i, pm.IDs) - { - UInt64 id = pm.IDs[i]; - s.Add_Space_if_NotEmpty(); - char temp[16]; - if (id == k_LZMA2) - { - s += "LZMA2:"; - if ((pm.Lzma2Prop & 1) == 0) - ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp); - else - GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11)); - s += temp; - } - else if (id == k_LZMA) - { - s += "LZMA:"; - GetStringForSizeValue(temp, pm.LzmaDic); - s += temp; - } - else - AddMethodName(s, id); - } - prop = s; - break; - } - case kpidSolid: prop = _db.IsSolid(); break; - case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break; - case kpidHeadersSize: prop = _db.HeadersSize; break; - case kpidPhySize: prop = _db.PhySize; break; - case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break; - /* - case kpidIsTree: if (_db.IsTree) prop = true; break; - case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break; - case kpidIsAux: if (_db.IsTree) prop = true; break; - */ - // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break; - #endif - - case kpidWarningFlags: - { - UInt32 v = 0; - if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError; - if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature; - if (v != 0) - prop = v; - break; - } - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc; - if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError; - if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported; - if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature; - prop = v; - break; - } - } - prop.Detach(value); - return S_OK; - #ifndef _SFX - COM_TRY_END - #endif -} - -static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index) -{ - UInt64 value; - if (v.GetItem(index, value)) - PropVarEm_Set_FileTime64(prop, value); -} - -bool CHandler::IsFolderEncrypted(CNum folderIndex) const -{ - if (folderIndex == kNumNoIndex) - return false; - size_t startPos = _db.FoCodersDataOffset[folderIndex]; - const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; - CInByte2 inByte; - inByte.Init(p, size); - - CNum numCoders = inByte.ReadNum(); - for (; numCoders != 0; numCoders--) - { - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); - const Byte *longID = inByte.GetPtr(); - UInt64 id64 = 0; - for (unsigned j = 0; j < idSize; j++) - id64 = ((id64 << 8) | longID[j]); - inByte.SkipDataNoCheck(idSize); - if (id64 == k_AES) - return true; - if ((mainByte & 0x20) != 0) - inByte.SkipDataNoCheck(inByte.ReadNum()); - } - return false; -} - -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) -{ - *numProps = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) -{ - *name = NULL; - *propID = kpidNtSecure; - return S_OK; -} - -STDMETHODIMP CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) -{ - /* - const CFileItem &file = _db.Files[index]; - *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir); - *parent = (UInt32)(Int32)file.Parent; - */ - *parentType = NParentType::kDir; - *parent = (UInt32)(Int32)-1; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - if (/* _db.IsTree && propID == kpidName || - !_db.IsTree && */ propID == kpidPath) - { - if (_db.NameOffsets && _db.NamesBuf) - { - size_t offset = _db.NameOffsets[index]; - size_t size = (_db.NameOffsets[index + 1] - offset) * 2; - if (size < ((UInt32)1 << 31)) - { - *data = (const void *)(_db.NamesBuf + offset * 2); - *dataSize = (UInt32)size; - *propType = NPropDataType::kUtf16z; - } - } - return S_OK; - } - /* - if (propID == kpidNtSecure) - { - if (index < (UInt32)_db.SecureIDs.Size()) - { - int id = _db.SecureIDs[index]; - size_t offs = _db.SecureOffsets[id]; - size_t size = _db.SecureOffsets[id + 1] - offs; - if (size >= 0) - { - *data = _db.SecureBuf + offs; - *dataSize = (UInt32)size; - *propType = NPropDataType::kRaw; - } - } - } - */ - return S_OK; -} - -#ifndef _SFX - -HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const -{ - PropVariant_Clear(prop); - if (folderIndex == kNumNoIndex) - return S_OK; - // for (int ttt = 0; ttt < 1; ttt++) { - const unsigned kTempSize = 256; - char temp[kTempSize]; - unsigned pos = kTempSize; - temp[--pos] = 0; - - size_t startPos = _db.FoCodersDataOffset[folderIndex]; - const Byte *p = _db.CodersData + startPos; - size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; - CInByte2 inByte; - inByte.Init(p, size); - - // numCoders == 0 ??? - CNum numCoders = inByte.ReadNum(); - bool needSpace = false; - - for (; numCoders != 0; numCoders--, needSpace = true) - { - if (pos < 32) // max size of property - break; - Byte mainByte = inByte.ReadByte(); - unsigned idSize = (mainByte & 0xF); - const Byte *longID = inByte.GetPtr(); - UInt64 id64 = 0; - for (unsigned j = 0; j < idSize; j++) - id64 = ((id64 << 8) | longID[j]); - inByte.SkipDataNoCheck(idSize); - - if ((mainByte & 0x10) != 0) - { - inByte.ReadNum(); // NumInStreams - inByte.ReadNum(); // NumOutStreams - } - - CNum propsSize = 0; - const Byte *props = NULL; - if ((mainByte & 0x20) != 0) - { - propsSize = inByte.ReadNum(); - props = inByte.GetPtr(); - inByte.SkipDataNoCheck(propsSize); - } - - const char *name = NULL; - char s[32]; - s[0] = 0; - - if (id64 <= (UInt32)0xFFFFFFFF) - { - UInt32 id = (UInt32)id64; - if (id == k_LZMA) - { - name = "LZMA"; - if (propsSize == 5) - { - UInt32 dicSize = GetUi32((const Byte *)props + 1); - char *dest = s + GetStringForSizeValue(s, dicSize); - UInt32 d = props[0]; - if (d != 0x5D) - { - UInt32 lc = d % 9; - d /= 9; - UInt32 pb = d / 5; - UInt32 lp = d % 5; - if (lc != 3) dest = AddProp32(dest, "lc", lc); - if (lp != 0) dest = AddProp32(dest, "lp", lp); - if (pb != 2) dest = AddProp32(dest, "pb", pb); - } - } - } - else if (id == k_LZMA2) - { - name = "LZMA2"; - if (propsSize == 1) - { - Byte d = props[0]; - if ((d & 1) == 0) - ConvertUInt32ToString((UInt32)((d >> 1) + 12), s); - else - GetStringForSizeValue(s, 3 << ((d >> 1) + 11)); - } - } - else if (id == k_PPMD) - { - name = "PPMD"; - if (propsSize == 5) - { - Byte order = *props; - char *dest = s; - *dest++ = 'o'; - ConvertUInt32ToString(order, dest); - dest += MyStringLen(dest); - dest = MyStpCpy(dest, ":mem"); - GetStringForSizeValue(dest, GetUi32(props + 1)); - } - } - else if (id == k_Delta) - { - name = "Delta"; - if (propsSize == 1) - ConvertUInt32ToString((UInt32)props[0] + 1, s); - } - else if (id == k_BCJ2) name = "BCJ2"; - else if (id == k_BCJ) name = "BCJ"; - else if (id == k_AES) - { - name = "7zAES"; - if (propsSize >= 1) - { - Byte firstByte = props[0]; - UInt32 numCyclesPower = firstByte & 0x3F; - ConvertUInt32ToString(numCyclesPower, s); - } - } - } - - if (name) - { - unsigned nameLen = MyStringLen(name); - unsigned propsLen = MyStringLen(s); - unsigned totalLen = nameLen + propsLen; - if (propsLen != 0) - totalLen++; - if (needSpace) - totalLen++; - if (totalLen + 5 >= pos) - break; - pos -= totalLen; - MyStringCopy(temp + pos, name); - if (propsLen != 0) - { - char *dest = temp + pos + nameLen; - *dest++ = ':'; - MyStringCopy(dest, s); - } - if (needSpace) - temp[pos + totalLen - 1] = ' '; - } - else - { - AString methodName; - FindMethod(EXTERNAL_CODECS_VARS id64, methodName); - if (needSpace) - temp[--pos] = ' '; - if (methodName.IsEmpty()) - pos -= ConvertMethodIdToString_Back(temp + pos, id64); - else - { - unsigned len = methodName.Len(); - if (len + 5 > pos) - break; - pos -= len; - for (unsigned i = 0; i < len; i++) - temp[pos + i] = methodName[i]; - } - } - } - - if (numCoders != 0 && pos >= 4) - { - temp[--pos] = ' '; - temp[--pos] = '.'; - temp[--pos] = '.'; - temp[--pos] = '.'; - } - - return PropVarEm_Set_Str(prop, temp + pos); - // } -} - -#endif - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - PropVariant_Clear(value); - // COM_TRY_BEGIN - // NCOM::CPropVariant prop; - - /* - const CRef2 &ref2 = _refs[index]; - if (ref2.Refs.IsEmpty()) - return E_FAIL; - const CRef &ref = ref2.Refs.Front(); - */ - - const CFileItem &item = _db.Files[index]; - UInt32 index2 = index; - - switch (propID) - { - case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break; - case kpidSize: - { - PropVarEm_Set_UInt64(value, item.Size); - // prop = ref2.Size; - break; - } - case kpidPackSize: - { - // prop = ref2.PackSize; - { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; - if (folderIndex != kNumNoIndex) - { - if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) - PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex)); - /* - else - PropVarEm_Set_UInt64(value, 0); - */ - } - else - PropVarEm_Set_UInt64(value, 0); - } - break; - } - // case kpidIsAux: prop = _db.IsItemAux(index2); break; - case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; } - case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break; - case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break; - case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break; - case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break; - case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break; - case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break; - case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break; - /* - case kpidIsAltStream: prop = item.IsAltStream; break; - case kpidNtSecure: - { - int id = _db.SecureIDs[index]; - size_t offs = _db.SecureOffsets[id]; - size_t size = _db.SecureOffsets[id + 1] - offs; - if (size >= 0) - { - prop.SetBlob(_db.SecureBuf + offs, (ULONG)size); - } - break; - } - */ - - case kpidPath: return _db.GetPath_Prop(index, value); - - #ifndef _SFX - - case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); - case kpidBlock: - { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; - if (folderIndex != kNumNoIndex) - PropVarEm_Set_UInt32(value, (UInt32)folderIndex); - } - break; - /* - case kpidPackedSize0: - case kpidPackedSize1: - case kpidPackedSize2: - case kpidPackedSize3: - case kpidPackedSize4: - { - CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; - if (folderIndex != kNumNoIndex) - { - if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && - _db.FoStartPackStreamIndex[folderIndex + 1] - - _db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0)) - { - PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0)); - } - } - else - PropVarEm_Set_UInt64(value, 0); - } - break; - */ - - #endif - } - // prop.Detach(value); - return S_OK; - // COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - Close(); - #ifndef _SFX - _fileInfoPopIDs.Clear(); - #endif - - try - { - CMyComPtr openArchiveCallbackTemp = openArchiveCallback; - - #ifndef _NO_CRYPTO - CMyComPtr getTextPassword; - if (openArchiveCallback) - openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); - #endif - - CInArchive archive( - #ifdef __7Z_SET_PROPERTIES - _useMultiThreadMixer - #else - true - #endif - ); - _db.IsArc = false; - RINOK(archive.Open(stream, maxCheckStartPosition)); - _db.IsArc = true; - - HRESULT result = archive.ReadDatabase( - EXTERNAL_CODECS_VARS - _db - #ifndef _NO_CRYPTO - , getTextPassword, _isEncrypted, _passwordIsDefined, _password - #endif - ); - RINOK(result); - - _inStream = stream; - } - catch(...) - { - Close(); - // return E_INVALIDARG; - // return S_FALSE; - // we must return out_of_memory here - return E_OUTOFMEMORY; - } - // _inStream = stream; - #ifndef _SFX - FillPopIDs(); - #endif - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - COM_TRY_BEGIN - _inStream.Release(); - _db.Clear(); - #ifndef _NO_CRYPTO - _isEncrypted = false; - _passwordIsDefined = false; - _password.Empty(); - #endif - return S_OK; - COM_TRY_END -} - -#ifdef __7Z_SET_PROPERTIES -#ifdef EXTRACT_ONLY - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - COM_TRY_BEGIN - const UInt32 numProcessors = NSystem::GetNumberOfProcessors(); - _numThreads = numProcessors; - _useMultiThreadMixer = true; - - 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]; - UInt32 number; - unsigned index = ParseStringToUInt32(name, number); - if (index == 0) - { - if (name.IsEqualTo("mtf")) - { - RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)); - continue; - } - if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads)); - continue; - } - else - return E_INVALIDARG; - } - } - return S_OK; - COM_TRY_END -} - -#endif -#endif - -IMPL_ISetCompressCodecsInfo - -}} +// 7zHandler.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" + +#ifndef Z7_7Z_SET_PROPERTIES +#include "../../../Windows/System.h" +#endif + +#include "../Common/ItemNameUtils.h" + +#include "7zHandler.h" +#include "7zProperties.h" + +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY +#include "../Common/ParseProperties.h" +#endif +#endif + +using namespace NWindows; +using namespace NCOM; + +namespace NArchive { +namespace N7z { + +CHandler::CHandler() +{ + #ifndef Z7_NO_CRYPTO + _isEncrypted = false; + _passwordIsDefined = false; + #endif + + #ifdef Z7_EXTRACT_ONLY + + _crcSize = 4; + + #ifdef Z7_7Z_SET_PROPERTIES + _useMultiThreadMixer = true; + #endif + + #endif +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _db.Files.Size(); + return S_OK; +} + +#ifdef Z7_SFX + +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */, + BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)) +{ + return E_NOTIMPL; +} + +#else + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidMethod, + kpidSolid, + kpidNumBlocks + // , kpidIsTree +}; + +IMP_IInArchive_ArcProps + +static inline char GetHex(unsigned value) +{ + return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); +} + +static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id) +{ + int len = 0; + do + { + s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; + s[--len] = GetHex((unsigned)id & 0xF); id >>= 4; + } + while (id != 0); + return (unsigned)-len; +} + +static void ConvertMethodIdToString(AString &res, UInt64 id) +{ + const unsigned kLen = 32; + char s[kLen]; + unsigned len = kLen - 1; + s[len] = 0; + res += s + len - ConvertMethodIdToString_Back(s + len, id); +} + + +static char *GetStringForSizeValue(char *s, UInt32 val) +{ + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == val) + { + if (i >= 10) + { + *s++= (char)('0' + i / 10); + i %= 10; + } + *s++ = (char)('0' + i); + *s = 0; + return s; + } + + char c = 'b'; + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + s = ConvertUInt32ToString(val, s); + *s++ = c; + *s = 0; + return s; +} + + +static void GetLzma2String(char *s, unsigned d) +{ + if (d > 40) + { + *s = 0; + return; + // s = MyStpCpy(s, "unsup"); + } + else if ((d & 1) == 0) + d = (d >> 1) + 12; + else + { + // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11)); + d = (d >> 1) + 1; + char c = 'k'; + if (d >= 10) + { + c = 'm'; + d -= 10; + } + s = ConvertUInt32ToString((UInt32)3 << d, s); + *s++ = c; + *s = 0; + return; + } + ConvertUInt32ToString(d, s); +} + + +/* +static inline void AddHexToString(UString &res, Byte value) +{ + res += GetHex((Byte)(value >> 4)); + res += GetHex((Byte)(value & 0xF)); +} +*/ + +static char *AddProp32(char *s, const char *name, UInt32 v) +{ + *s++ = ':'; + s = MyStpCpy(s, name); + return ConvertUInt32ToString(v, s); +} + +void CHandler::AddMethodName(AString &s, UInt64 id) +{ + AString name; + FindMethod(EXTERNAL_CODECS_VARS id, name); + if (name.IsEmpty()) + ConvertMethodIdToString(s, id); + else + s += name; +} + +#endif + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + #ifndef Z7_SFX + COM_TRY_BEGIN + #endif + NCOM::CPropVariant prop; + switch (propID) + { + #ifndef Z7_SFX + case kpidMethod: + { + AString s; + const CParsedMethods &pm = _db.ParsedMethods; + FOR_VECTOR (i, pm.IDs) + { + UInt64 id = pm.IDs[i]; + s.Add_Space_if_NotEmpty(); + char temp[16]; + if (id == k_LZMA2) + { + s += "LZMA2:"; + GetLzma2String(temp, pm.Lzma2Prop); + s += temp; + } + else if (id == k_LZMA) + { + s += "LZMA:"; + GetStringForSizeValue(temp, pm.LzmaDic); + s += temp; + } + /* + else if (id == k_ZSTD) + { + s += "ZSTD"; + } + */ + else + AddMethodName(s, id); + } + prop = s; + break; + } + case kpidSolid: prop = _db.IsSolid(); break; + case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break; + case kpidHeadersSize: prop = _db.HeadersSize; break; + case kpidPhySize: prop = _db.PhySize; break; + case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break; + /* + case kpidIsTree: if (_db.IsTree) prop = true; break; + case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break; + case kpidIsAux: if (_db.IsTree) prop = true; break; + */ + // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break; + #endif + + case kpidWarningFlags: + { + UInt32 v = 0; + if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError; + if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature; + if (v != 0) + prop = v; + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError; + if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported; + if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature; + prop = v; + break; + } + + case kpidReadOnly: + { + if (!_db.CanUpdate()) + prop = true; + break; + } + default: break; + } + return prop.Detach(value); + #ifndef Z7_SFX + COM_TRY_END + #endif +} + +static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index) +{ + UInt64 value; + if (v.GetItem(index, value)) + PropVarEm_Set_FileTime64_Prec(prop, value, k_PropVar_TimePrec_100ns); +} + +bool CHandler::IsFolderEncrypted(CNum folderIndex) const +{ + if (folderIndex == kNumNoIndex) + return false; + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData.ConstData() + startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + CInByte2 inByte; + inByte.Init(p, size); + + CNum numCoders = inByte.ReadNum(); + for (; numCoders != 0; numCoders--) + { + const Byte mainByte = inByte.ReadByte(); + const unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); + UInt64 id64 = 0; + for (unsigned j = 0; j < idSize; j++) + id64 = ((id64 << 8) | longID[j]); + inByte.SkipDataNoCheck(idSize); + if (id64 == k_AES) + return true; + if ((mainByte & 0x20) != 0) + inByte.SkipDataNoCheck(inByte.ReadNum()); + } + return false; +} + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = kpidNtSecure; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) +{ + /* + const CFileItem &file = _db.Files[index]; + *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir); + *parent = (UInt32)(Int32)file.Parent; + */ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (/* _db.IsTree && propID == kpidName || + !_db.IsTree && */ propID == kpidPath) + { + if (_db.NameOffsets && _db.NamesBuf) + { + const size_t offset = _db.NameOffsets[index]; + const size_t size = (_db.NameOffsets[index + 1] - offset) * 2; + if (size < ((UInt32)1 << 31)) + { + *data = (const void *)(_db.NamesBuf.ConstData() + offset * 2); + *dataSize = (UInt32)size; + *propType = NPropDataType::kUtf16z; + } + } + return S_OK; + } + /* + if (propID == kpidNtSecure) + { + if (index < (UInt32)_db.SecureIDs.Size()) + { + int id = _db.SecureIDs[index]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + if (size >= 0) + { + *data = _db.SecureBuf + offs; + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + } + } + } + */ + return S_OK; +} + +#ifndef Z7_SFX + +HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const +{ + PropVariant_Clear(prop); + if (folderIndex == kNumNoIndex) + return S_OK; + // for (int ttt = 0; ttt < 1; ttt++) { + const unsigned kTempSize = 256; + char temp[kTempSize]; + unsigned pos = kTempSize; + temp[--pos] = 0; + + const size_t startPos = _db.FoCodersDataOffset[folderIndex]; + const Byte *p = _db.CodersData.ConstData() + startPos; + const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos; + CInByte2 inByte; + inByte.Init(p, size); + + // numCoders == 0 ??? + CNum numCoders = inByte.ReadNum(); + bool needSpace = false; + + for (; numCoders != 0; numCoders--, needSpace = true) + { + if (pos < 32) // max size of property + break; + const Byte mainByte = inByte.ReadByte(); + UInt64 id64 = 0; + const unsigned idSize = (mainByte & 0xF); + const Byte *longID = inByte.GetPtr(); + for (unsigned j = 0; j < idSize; j++) + id64 = ((id64 << 8) | longID[j]); + inByte.SkipDataNoCheck(idSize); + + if ((mainByte & 0x10) != 0) + { + inByte.ReadNum(); // NumInStreams + inByte.ReadNum(); // NumOutStreams + } + + CNum propsSize = 0; + const Byte *props = NULL; + if ((mainByte & 0x20) != 0) + { + propsSize = inByte.ReadNum(); + props = inByte.GetPtr(); + inByte.SkipDataNoCheck(propsSize); + } + + const char *name = NULL; + char s[32]; + s[0] = 0; + + if (id64 <= (UInt32)0xFFFFFFFF) + { + const UInt32 id = (UInt32)id64; + if (id == k_LZMA) + { + name = "LZMA"; + if (propsSize == 5) + { + const UInt32 dicSize = GetUi32((const Byte *)props + 1); + char *dest = GetStringForSizeValue(s, dicSize); + UInt32 d = props[0]; + if (d != 0x5D) + { + const UInt32 lc = d % 9; + d /= 9; + const UInt32 pb = d / 5; + const UInt32 lp = d % 5; + if (lc != 3) dest = AddProp32(dest, "lc", lc); + if (lp != 0) dest = AddProp32(dest, "lp", lp); + if (pb != 2) dest = AddProp32(dest, "pb", pb); + } + } + } + else if (id == k_LZMA2) + { + name = "LZMA2"; + if (propsSize == 1) + GetLzma2String(s, props[0]); + } + else if (id == k_PPMD) + { + name = "PPMD"; + if (propsSize == 5) + { + char *dest = s; + *dest++ = 'o'; + dest = ConvertUInt32ToString(*props, dest); + dest = MyStpCpy(dest, ":mem"); + GetStringForSizeValue(dest, GetUi32(props + 1)); + } + } + else if (id == k_Delta) + { + name = "Delta"; + if (propsSize == 1) + ConvertUInt32ToString((UInt32)props[0] + 1, s); + } + else if (id == k_ARM64 || id == k_RISCV) + { + name = id == k_ARM64 ? "ARM64" : "RISCV"; + if (propsSize == 4) + ConvertUInt32ToString(GetUi32(props), s); + /* + else if (propsSize != 0) + MyStringCopy(s, "unsupported"); + */ + } + else if (id == k_BCJ2) name = "BCJ2"; + else if (id == k_BCJ) name = "BCJ"; + else if (id == k_AES) + { + name = "7zAES"; + if (propsSize >= 1) + { + const Byte firstByte = props[0]; + const UInt32 numCyclesPower = firstByte & 0x3F; + ConvertUInt32ToString(numCyclesPower, s); + } + } + } + + if (name) + { + const unsigned nameLen = MyStringLen(name); + const unsigned propsLen = MyStringLen(s); + unsigned totalLen = nameLen + propsLen; + if (propsLen != 0) + totalLen++; + if (needSpace) + totalLen++; + if (totalLen + 5 >= pos) + break; + pos -= totalLen; + MyStringCopy(temp + pos, name); + if (propsLen != 0) + { + char *dest = temp + pos + nameLen; + *dest++ = ':'; + MyStringCopy(dest, s); + } + if (needSpace) + temp[pos + totalLen - 1] = ' '; + } + else + { + AString methodName; + FindMethod(EXTERNAL_CODECS_VARS id64, methodName); + if (needSpace) + temp[--pos] = ' '; + if (methodName.IsEmpty()) + pos -= ConvertMethodIdToString_Back(temp + pos, id64); + else + { + const unsigned len = methodName.Len(); + if (len + 5 > pos) + break; + pos -= len; + for (unsigned i = 0; i < len; i++) + temp[pos + i] = methodName[i]; + } + } + } + + if (numCoders != 0 && pos >= 4) + { + temp[--pos] = ' '; + temp[--pos] = '.'; + temp[--pos] = '.'; + temp[--pos] = '.'; + } + + return PropVarEm_Set_Str(prop, temp + pos); + // } +} + +#endif + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + RINOK(PropVariant_Clear(value)) + // COM_TRY_BEGIN + // NCOM::CPropVariant prop; + + /* + const CRef2 &ref2 = _refs[index]; + if (ref2.Refs.IsEmpty()) + return E_FAIL; + const CRef &ref = ref2.Refs.Front(); + */ + + const CFileItem &item = _db.Files[index]; + const UInt32 index2 = index; + + switch (propID) + { + case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break; + case kpidSize: + { + PropVarEm_Set_UInt64(value, item.Size); + // prop = ref2.Size; + break; + } + case kpidPackSize: + { + // prop = ref2.PackSize; + { + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2) + PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex)); + /* + else + PropVarEm_Set_UInt64(value, 0); + */ + } + else + PropVarEm_Set_UInt64(value, 0); + } + break; + } + // case kpidIsAux: prop = _db.IsItemAux(index2); break; + case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; } + case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break; + case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break; + case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break; + case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break; + case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break; + case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break; + case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break; + /* + case kpidIsAltStream: prop = item.IsAltStream; break; + case kpidNtSecure: + { + int id = _db.SecureIDs[index]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + if (size >= 0) + { + prop.SetBlob(_db.SecureBuf + offs, (ULONG)size); + } + break; + } + */ + + case kpidPath: return _db.GetPath_Prop(index, value); + + #ifndef Z7_SFX + + case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value); + case kpidBlock: + { + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + PropVarEm_Set_UInt32(value, (UInt32)folderIndex); + } + break; + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES + case kpidPackedSize0: + case kpidPackedSize1: + case kpidPackedSize2: + case kpidPackedSize3: + case kpidPackedSize4: + { + const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2]; + if (folderIndex != kNumNoIndex) + { + if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 && + _db.FoStartPackStreamIndex[folderIndex + 1] - + _db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0)) + { + PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0)); + } + } + else + PropVarEm_Set_UInt64(value, 0); + } + break; + #endif + + #endif + default: break; + } + // return prop.Detach(value); + return S_OK; + // COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback)) +{ + COM_TRY_BEGIN + Close(); + #ifndef Z7_SFX + _fileInfoPopIDs.Clear(); + #endif + + try + { + CMyComPtr openArchiveCallbackTemp = openArchiveCallback; + + #ifndef Z7_NO_CRYPTO + CMyComPtr getTextPassword; + if (openArchiveCallback) + openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + #endif + + CInArchive archive( + #ifdef Z7_7Z_SET_PROPERTIES + _useMultiThreadMixer + #else + true + #endif + ); + _db.IsArc = false; + RINOK(archive.Open(stream, maxCheckStartPosition)) + _db.IsArc = true; + + HRESULT result = archive.ReadDatabase( + EXTERNAL_CODECS_VARS + _db + #ifndef Z7_NO_CRYPTO + , getTextPassword, _isEncrypted, _passwordIsDefined, _password + #endif + ); + RINOK(result) + + _inStream = stream; + } + catch(...) + { + Close(); + // return E_INVALIDARG; + // return S_FALSE; + // we must return out_of_memory here + return E_OUTOFMEMORY; + } + // _inStream = stream; + #ifndef Z7_SFX + FillPopIDs(); + #endif + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + COM_TRY_BEGIN + _inStream.Release(); + _db.Clear(); + #ifndef Z7_NO_CRYPTO + _isEncrypted = false; + _passwordIsDefined = false; + _password.Wipe_and_Empty(); + #endif + return S_OK; + COM_TRY_END +} + +#ifdef Z7_7Z_SET_PROPERTIES +#ifdef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + COM_TRY_BEGIN + + InitCommon(); + _useMultiThreadMixer = true; + + 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]; + UInt32 number; + const unsigned index = ParseStringToUInt32(name, number); + if (index == 0) + { + if (name.IsEqualTo("mtf")) + { + RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer)) + continue; + } + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + { + RINOK(hres) + continue; + } + } + return E_INVALIDARG; + } + } + return S_OK; + COM_TRY_END +} + +#endif +#endif + +IMPL_ISetCompressCodecsInfo + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandler.h 2015-11-06 12:02:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandler.h 2024-05-12 11:00:00.000000000 +0000 @@ -1,173 +1,178 @@ -// 7z/Handler.h - -#ifndef __7Z_HANDLER_H -#define __7Z_HANDLER_H - -#include "../../ICoder.h" -#include "../IArchive.h" - -#include "../../Common/CreateCoder.h" - -#ifndef EXTRACT_ONLY -#include "../Common/HandlerOut.h" -#endif - -#include "7zCompressionMode.h" -#include "7zIn.h" - -namespace NArchive { -namespace N7z { - -#ifndef __7Z_SET_PROPERTIES - -#ifdef EXTRACT_ONLY - #if !defined(_7ZIP_ST) && !defined(_SFX) - #define __7Z_SET_PROPERTIES - #endif -#else - #define __7Z_SET_PROPERTIES -#endif - -#endif - - -#ifndef EXTRACT_ONLY - -class COutHandler: public CMultiMethodProps -{ - HRESULT SetSolidFromString(const UString &s); - HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value); -public: - bool _removeSfxBlock; - - UInt64 _numSolidFiles; - UInt64 _numSolidBytes; - bool _numSolidBytesDefined; - bool _solidExtension; - bool _useTypeSorting; - - bool _compressHeaders; - bool _encryptHeadersSpecified; - bool _encryptHeaders; - // bool _useParents; 9.26 - - CBoolPair Write_CTime; - CBoolPair Write_ATime; - CBoolPair Write_MTime; - - bool _useMultiThreadMixer; - - // bool _volumeMode; - - void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } - void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } - void InitSolid() - { - InitSolidFiles(); - InitSolidSize(); - _solidExtension = false; - _numSolidBytesDefined = false; - } - - void InitProps(); - - COutHandler() { InitProps(); } - - HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); -}; - -#endif - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - #ifdef __7Z_SET_PROPERTIES - public ISetProperties, - #endif - #ifndef EXTRACT_ONLY - public IOutArchive, - #endif - PUBLIC_ISetCompressCodecsInfo - public CMyUnknownImp - #ifndef EXTRACT_ONLY - , public COutHandler - #endif -{ -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - #ifdef __7Z_SET_PROPERTIES - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - #endif - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - - #ifdef __7Z_SET_PROPERTIES - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif - - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) - #endif - - DECL_ISetCompressCodecsInfo - - CHandler(); - -private: - CMyComPtr _inStream; - NArchive::N7z::CDbEx _db; - - #ifndef _NO_CRYPTO - bool _isEncrypted; - bool _passwordIsDefined; - UString _password; - #endif - - #ifdef EXTRACT_ONLY - - #ifdef __7Z_SET_PROPERTIES - UInt32 _numThreads; - bool _useMultiThreadMixer; - #endif - - UInt32 _crcSize; - - #else - - CRecordVector _bonds; - - HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m); - HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod); - HRESULT SetMainMethod(CCompressionMethodMode &method - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ); - - - #endif - - bool IsFolderEncrypted(CNum folderIndex) const; - #ifndef _SFX - - CRecordVector _fileInfoPopIDs; - void FillPopIDs(); - void AddMethodName(AString &s, UInt64 id); - HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const; - - #endif - - DECL_EXTERNAL_CODECS_VARS -}; - -}} - -#endif +// 7z/Handler.h + +#ifndef ZIP7_7Z_HANDLER_H +#define ZIP7_7Z_HANDLER_H + +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#ifndef Z7_7Z_SET_PROPERTIES + +#ifdef Z7_EXTRACT_ONLY + #if !defined(Z7_ST) && !defined(Z7_SFX) + #define Z7_7Z_SET_PROPERTIES + #endif +#else + #define Z7_7Z_SET_PROPERTIES +#endif + +#endif + +// #ifdef Z7_7Z_SET_PROPERTIES +#include "../Common/HandlerOut.h" +// #endif + +#include "7zCompressionMode.h" +#include "7zIn.h" + +namespace NArchive { +namespace N7z { + + +#ifndef Z7_EXTRACT_ONLY + +class COutHandler: public CMultiMethodProps +{ + HRESULT SetSolidFromString(const UString &s); + HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value); +public: + UInt64 _numSolidFiles; + UInt64 _numSolidBytes; + bool _numSolidBytesDefined; + bool _solidExtension; + bool _useTypeSorting; + + bool _compressHeaders; + bool _encryptHeadersSpecified; + bool _encryptHeaders; + // bool _useParents; 9.26 + + CHandlerTimeOptions TimeOptions; + + CBoolPair Write_Attrib; + + bool _useMultiThreadMixer; + bool _removeSfxBlock; + // bool _volumeMode; + + UInt32 _decoderCompatibilityVersion; + CUIntVector _enabledFilters; + CUIntVector _disabledFilters; + + void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); } + void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); } + void InitSolid() + { + InitSolidFiles(); + InitSolidSize(); + _solidExtension = false; + _numSolidBytesDefined = false; + } + + void InitProps7z(); + void InitProps(); + + COutHandler() { InitProps7z(); } + + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); +}; + +#endif + +class CHandler Z7_final: + public IInArchive, + public IArchiveGetRawProps, + + #ifdef Z7_7Z_SET_PROPERTIES + public ISetProperties, + #endif + + #ifndef Z7_EXTRACT_ONLY + public IOutArchive, + #endif + + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC + + public CMyUnknownImp, + + #ifndef Z7_EXTRACT_ONLY + public COutHandler + #else + public CCommonMethodProps + #endif +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_COM_QI_ENTRY(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + #ifdef Z7_7Z_SET_PROPERTIES + Z7_IFACE_COM7_IMP(ISetProperties) + #endif + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif + DECL_ISetCompressCodecsInfo + +private: + CMyComPtr _inStream; + NArchive::N7z::CDbEx _db; + + #ifndef Z7_NO_CRYPTO + bool _isEncrypted; + bool _passwordIsDefined; + UString _password; // _Wipe + #endif + + #ifdef Z7_EXTRACT_ONLY + + #ifdef Z7_7Z_SET_PROPERTIES + bool _useMultiThreadMixer; + #endif + + UInt32 _crcSize; + + #else + + CRecordVector _bonds; + + HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m); + HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod); + HRESULT SetMainMethod(CCompressionMethodMode &method); + + #endif + + bool IsFolderEncrypted(CNum folderIndex) const; + #ifndef Z7_SFX + + CRecordVector _fileInfoPopIDs; + void FillPopIDs(); + void AddMethodName(AString &s, UInt64 id); + HRESULT SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const; + + #endif + + DECL_EXTERNAL_CODECS_VARS + +public: + CHandler(); + ~CHandler() + { + Close(); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandlerOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandlerOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHandlerOut.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHandlerOut.cpp 2025-07-03 07:00:00.000000000 +0000 @@ -1,913 +1,1162 @@ -// 7zHandlerOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/Wildcard.h" - -#include "../Common/ItemNameUtils.h" -#include "../Common/ParseProperties.h" - -#include "7zHandler.h" -#include "7zOut.h" -#include "7zUpdate.h" - -using namespace NWindows; - -namespace NArchive { -namespace N7z { - -static const char *k_LZMA_Name = "LZMA"; -static const char *kDefaultMethodName = "LZMA2"; -static const char *k_Copy_Name = "Copy"; - -static const char *k_MatchFinder_ForHeaders = "BT2"; -static const UInt32 k_NumFastBytes_ForHeaders = 273; -static const UInt32 k_Level_ForHeaders = 5; -static const UInt32 k_Dictionary_ForHeaders = - #ifdef UNDER_CE - 1 << 18; - #else - 1 << 20; - #endif - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kWindows; - return S_OK; -} - -HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) -{ - if (!FindMethod( - EXTERNAL_CODECS_VARS - m.MethodName, dest.Id, dest.NumStreams)) - return E_INVALIDARG; - (CProps &)dest = (CProps &)m; - return S_OK; -} - -HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod) -{ - if (!_compressHeaders) - return S_OK; - COneMethodInfo m; - m.MethodName = k_LZMA_Name; - m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders); - m.AddProp_Level(k_Level_ForHeaders); - m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders); - m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders); - m.AddProp_NumThreads(1); - - CMethodFull &methodFull = headerMethod.Methods.AddNew(); - return PropsMethod_To_FullMethod(methodFull, m); -} - -HRESULT CHandler::SetMainMethod( - CCompressionMethodMode &methodMode - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ) -{ - methodMode.Bonds = _bonds; - - CObjectVector methods = _methods; - - { - FOR_VECTOR (i, methods) - { - AString &methodName = methods[i].MethodName; - if (methodName.IsEmpty()) - methodName = kDefaultMethodName; - } - if (methods.IsEmpty()) - { - COneMethodInfo &m = methods.AddNew(); - m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName); - methodMode.DefaultMethod_was_Inserted = true; - } - } - - if (!_filterMethod.MethodName.IsEmpty()) - { - // if (methodMode.Bonds.IsEmpty()) - { - FOR_VECTOR (k, methodMode.Bonds) - { - CBond2 &bond = methodMode.Bonds[k]; - bond.InCoder++; - bond.OutCoder++; - } - methods.Insert(0, _filterMethod); - methodMode.Filter_was_Inserted = true; - } - } - - const UInt64 kSolidBytes_Min = (1 << 24); - const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1; - - bool needSolid = false; - - FOR_VECTOR (i, methods) - { - COneMethodInfo &oneMethodInfo = methods[i]; - SetGlobalLevelAndThreads(oneMethodInfo - #ifndef _7ZIP_ST - , numThreads - #endif - ); - - CMethodFull &methodFull = methodMode.Methods.AddNew(); - RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)); - - if (methodFull.Id != k_Copy) - needSolid = true; - - if (_numSolidBytesDefined) - continue; - - UInt32 dicSize; - switch (methodFull.Id) - { - case k_LZMA: - case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break; - case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break; - case k_Deflate: dicSize = (UInt32)1 << 15; break; - case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break; - default: continue; - } - - _numSolidBytes = (UInt64)dicSize << 7; - if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min; - if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max; - _numSolidBytesDefined = true; - } - - if (!_numSolidBytesDefined) - if (needSolid) - _numSolidBytes = kSolidBytes_Max; - else - _numSolidBytes = 0; - _numSolidBytesDefined = true; - return S_OK; -} - -static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined) -{ - // ft = 0; - // ftDefined = false; - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(index, propID, &prop)); - if (prop.vt == VT_FILETIME) - { - ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); - ftDefined = true; - } - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - else - { - ft = 0; - ftDefined = false; - } - return S_OK; -} - -/* - -#ifdef _WIN32 -static const wchar_t kDirDelimiter1 = L'\\'; -#endif -static const wchar_t kDirDelimiter2 = L'/'; - -static inline bool IsCharDirLimiter(wchar_t c) -{ - return ( - #ifdef _WIN32 - c == kDirDelimiter1 || - #endif - c == kDirDelimiter2); -} - -static int FillSortIndex(CObjectVector &treeFolders, int cur, int curSortIndex) -{ - CTreeFolder &tf = treeFolders[cur]; - tf.SortIndex = curSortIndex++; - for (int i = 0; i < tf.SubFolders.Size(); i++) - curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex); - tf.SortIndexEnd = curSortIndex; - return curSortIndex; -} - -static int FindSubFolder(const CObjectVector &treeFolders, int cur, const UString &name, int &insertPos) -{ - const CIntVector &subFolders = treeFolders[cur].SubFolders; - int left = 0, right = subFolders.Size(); - insertPos = -1; - for (;;) - { - if (left == right) - { - insertPos = left; - return -1; - } - int mid = (left + right) / 2; - int midFolder = subFolders[mid]; - int compare = CompareFileNames(name, treeFolders[midFolder].Name); - if (compare == 0) - return midFolder; - if (compare < 0) - right = mid; - else - left = mid + 1; - } -} - -static int AddFolder(CObjectVector &treeFolders, int cur, const UString &name) -{ - int insertPos; - int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos); - if (folderIndex < 0) - { - folderIndex = treeFolders.Size(); - CTreeFolder &newFolder = treeFolders.AddNew(); - newFolder.Parent = cur; - newFolder.Name = name; - treeFolders[cur].SubFolders.Insert(insertPos, folderIndex); - } - // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234; - return folderIndex; -} -*/ - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - - const CDbEx *db = 0; - #ifdef _7Z_VOL - if (_volumes.Size() > 1) - return E_FAIL; - const CVolume *volume = 0; - if (_volumes.Size() == 1) - { - volume = &_volumes.Front(); - db = &volume->Database; - } - #else - if (_inStream != 0) - db = &_db; - #endif - - /* - CMyComPtr getRawProps; - updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); - - CUniqBlocks secureBlocks; - secureBlocks.AddUniq(NULL, 0); - - CObjectVector treeFolders; - { - CTreeFolder folder; - folder.Parent = -1; - treeFolders.Add(folder); - } - */ - - 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 || !Write_MTime.Def); - - 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(); - } - - UString s; - - for (UInt32 i = 0; i < numItems; i++) - { - Int32 newData, newProps; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); - CUpdateItem ui; - ui.NewProps = IntToBool(newProps); - ui.NewData = IntToBool(newData); - ui.IndexInArchive = indexInArchive; - ui.IndexInClient = i; - ui.IsAnti = false; - ui.Size = 0; - - UString name; - // bool isAltStream = false; - if (ui.IndexInArchive != -1) - { - if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size()) - return E_INVALIDARG; - const CFileItem &fi = db->Files[ui.IndexInArchive]; - if (!ui.NewProps) - { - _db.GetPath(ui.IndexInArchive, name); - } - ui.IsDir = fi.IsDir; - ui.Size = fi.Size; - // isAltStream = fi.IsAltStream; - ui.IsAnti = db->IsItemAnti(ui.IndexInArchive); - - if (!ui.NewProps) - { - ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); - ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); - ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); - } - } - - if (ui.NewProps) - { - bool folderStatusIsDefined; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)); - if (prop.vt == VT_EMPTY) - ui.AttribDefined = false; - else if (prop.vt != VT_UI4) - return E_INVALIDARG; - else - { - ui.Attrib = prop.ulVal; - ui.AttribDefined = true; - } - } - - // we need MTime to sort files. - if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)); - if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)); - if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)); - - /* - if (getRawProps) - { - const void *data; - UInt32 dataSize; - UInt32 propType; - - getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType); - if (dataSize != 0 && propType != NPropDataType::kRaw) - return E_FAIL; - ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize); - } - */ - - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); - if (prop.vt == VT_EMPTY) - { - } - else if (prop.vt != VT_BSTR) - return E_INVALIDARG; - else - { - name = NItemName::MakeLegalName(prop.bstrVal); - } - } - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)); - if (prop.vt == VT_EMPTY) - folderStatusIsDefined = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - { - ui.IsDir = (prop.boolVal != VARIANT_FALSE); - folderStatusIsDefined = true; - } - } - - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)); - if (prop.vt == VT_EMPTY) - ui.IsAnti = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - ui.IsAnti = (prop.boolVal != VARIANT_FALSE); - } - - /* - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop)); - if (prop.vt == VT_EMPTY) - isAltStream = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - isAltStream = (prop.boolVal != VARIANT_FALSE); - } - */ - - if (ui.IsAnti) - { - ui.AttribDefined = false; - - ui.CTimeDefined = false; - ui.ATimeDefined = false; - ui.MTimeDefined = false; - - ui.Size = 0; - } - - if (!folderStatusIsDefined && ui.AttribDefined) - ui.SetDirStatusFromAttrib(); - } - else - { - /* - if (_db.SecureIDs.IsEmpty()) - ui.SecureIndex = secureBlocks.AddUniq(NULL, 0); - else - { - int id = _db.SecureIDs[ui.IndexInArchive]; - size_t offs = _db.SecureOffsets[id]; - size_t size = _db.SecureOffsets[id + 1] - offs; - ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size); - } - */ - } - - /* - { - int folderIndex = 0; - if (_useParents) - { - int j; - s.Empty(); - for (j = 0; j < name.Len(); j++) - { - wchar_t c = name[j]; - if (IsCharDirLimiter(c)) - { - folderIndex = AddFolder(treeFolders, folderIndex, s); - s.Empty(); - continue; - } - s += c; - } - if (isAltStream) - { - int colonPos = s.Find(':'); - if (colonPos < 0) - { - // isAltStream = false; - return E_INVALIDARG; - } - UString mainName = s.Left(colonPos); - int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName); - if (treeFolders[newFolderIndex].UpdateItemIndex < 0) - { - for (int j = updateItems.Size() - 1; j >= 0; j--) - { - CUpdateItem &ui2 = updateItems[j]; - if (ui2.ParentFolderIndex == folderIndex - && ui2.Name == mainName) - { - ui2.TreeFolderIndex = newFolderIndex; - treeFolders[newFolderIndex].UpdateItemIndex = j; - } - } - } - folderIndex = newFolderIndex; - s.Delete(0, colonPos + 1); - } - ui.Name = s; - } - else - ui.Name = name; - ui.IsAltStream = isAltStream; - ui.ParentFolderIndex = folderIndex; - ui.TreeFolderIndex = -1; - if (ui.IsDir && !s.IsEmpty()) - { - ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s); - treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size(); - } - } - */ - ui.Name = name; - - if (ui.NewData) - { - ui.Size = 0; - if (!ui.IsDir) - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - ui.Size = (UInt64)prop.uhVal.QuadPart; - if (ui.Size != 0 && ui.IsAnti) - return E_INVALIDARG; - } - } - - updateItems.Add(ui); - } - - /* - FillSortIndex(treeFolders, 0, 0); - for (i = 0; i < (UInt32)updateItems.Size(); i++) - { - CUpdateItem &ui = updateItems[i]; - ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex; - ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd; - } - */ - - CCompressionMethodMode methodMode, headerMethod; - - HRESULT res = SetMainMethod(methodMode - #ifndef _7ZIP_ST - , _numThreads - #endif - ); - RINOK(res); - - RINOK(SetHeaderMethod(headerMethod)); - - #ifndef _7ZIP_ST - methodMode.NumThreads = _numThreads; - methodMode.MultiThreadMixer = _useMultiThreadMixer; - headerMethod.NumThreads = 1; - headerMethod.MultiThreadMixer = _useMultiThreadMixer; - #endif - - CMyComPtr getPassword2; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); - - methodMode.PasswordIsDefined = false; - methodMode.Password.Empty(); - if (getPassword2) - { - CMyComBSTR password; - Int32 passwordIsDefined; - RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)); - methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); - if (methodMode.PasswordIsDefined && password) - methodMode.Password = password; - } - - bool compressMainHeader = _compressHeaders; // check it - - bool encryptHeaders = false; - - #ifndef _NO_CRYPTO - if (!methodMode.PasswordIsDefined && _passwordIsDefined) - { - // if header is compressed, we use that password for updated archive - methodMode.PasswordIsDefined = true; - methodMode.Password = _password; - } - #endif - - if (methodMode.PasswordIsDefined) - { - if (_encryptHeadersSpecified) - encryptHeaders = _encryptHeaders; - #ifndef _NO_CRYPTO - else - encryptHeaders = _passwordIsDefined; - #endif - compressMainHeader = true; - if (encryptHeaders) - { - headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined; - headerMethod.Password = methodMode.Password; - } - } - - if (numItems < 2) - compressMainHeader = false; - - int level = GetLevel(); - - CUpdateOptions options; - options.Method = &methodMode; - options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL; - options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted); - options.MaxFilter = (level >= 8); - options.AnalysisLevel = GetAnalysisLevel(); - - options.HeaderOptions.CompressMainHeader = compressMainHeader; - /* - options.HeaderOptions.WriteCTime = Write_CTime; - options.HeaderOptions.WriteATime = Write_ATime; - options.HeaderOptions.WriteMTime = Write_MTime; - */ - - options.NumSolidFiles = _numSolidFiles; - options.NumSolidBytes = _numSolidBytes; - options.SolidExtension = _solidExtension; - options.UseTypeSorting = _useTypeSorting; - - options.RemoveSfxBlock = _removeSfxBlock; - // options.VolumeMode = _volumeMode; - - options.MultiThreadMixer = _useMultiThreadMixer; - - COutArchive archive; - CArchiveDatabaseOut newDatabase; - - CMyComPtr getPassword; - updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword); - - /* - if (secureBlocks.Sorted.Size() > 1) - { - secureBlocks.GetReverseMap(); - for (int i = 0; i < updateItems.Size(); i++) - { - int &secureIndex = updateItems[i].SecureIndex; - secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex]; - } - } - */ - - res = Update( - EXTERNAL_CODECS_VARS - #ifdef _7Z_VOL - volume ? volume->Stream: 0, - volume ? db : 0, - #else - _inStream, - db, - #endif - updateItems, - // treeFolders, - // secureBlocks, - archive, newDatabase, outStream, updateCallback, options - #ifndef _NO_CRYPTO - , getPassword - #endif - ); - - RINOK(res); - - updateItems.ClearAndFree(); - - return archive.WriteDatabase(EXTERNAL_CODECS_VARS - newDatabase, options.HeaderMethod, options.HeaderOptions); - - COM_TRY_END -} - -static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream) -{ - stream = 0; - { - unsigned index = ParseStringToUInt32(srcString, coder); - if (index == 0) - return E_INVALIDARG; - srcString.DeleteFrontal(index); - } - if (srcString[0] == 's') - { - srcString.Delete(0); - unsigned index = ParseStringToUInt32(srcString, stream); - if (index == 0) - return E_INVALIDARG; - srcString.DeleteFrontal(index); - } - return S_OK; -} - -void COutHandler::InitProps() -{ - CMultiMethodProps::Init(); - - _removeSfxBlock = false; - _compressHeaders = true; - _encryptHeadersSpecified = false; - _encryptHeaders = false; - // _useParents = false; - - Write_CTime.Init(); - Write_ATime.Init(); - Write_MTime.Init(); - - _useMultiThreadMixer = true; - - // _volumeMode = false; - - InitSolid(); - _useTypeSorting = false; -} - -HRESULT COutHandler::SetSolidFromString(const UString &s) -{ - UString s2 = s; - s2.MakeLower_Ascii(); - for (unsigned i = 0; i < s2.Len();) - { - const wchar_t *start = ((const wchar_t *)s2) + i; - const wchar_t *end; - UInt64 v = ConvertStringToUInt64(start, &end); - if (start == end) - { - if (s2[i++] != 'e') - return E_INVALIDARG; - _solidExtension = true; - continue; - } - i += (int)(end - start); - if (i == s2.Len()) - return E_INVALIDARG; - wchar_t c = s2[i++]; - if (c == 'f') - { - if (v < 1) - v = 1; - _numSolidFiles = v; - } - else - { - unsigned numBits; - switch (c) - { - case 'b': numBits = 0; break; - case 'k': numBits = 10; break; - case 'm': numBits = 20; break; - case 'g': numBits = 30; break; - case 't': numBits = 40; break; - default: return E_INVALIDARG; - } - _numSolidBytes = (v << numBits); - _numSolidBytesDefined = true; - } - } - return S_OK; -} - -HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value) -{ - bool isSolid; - switch (value.vt) - { - case VT_EMPTY: isSolid = true; break; - case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break; - case VT_BSTR: - if (StringToBool(value.bstrVal, isSolid)) - break; - return SetSolidFromString(value.bstrVal); - default: return E_INVALIDARG; - } - if (isSolid) - InitSolid(); - else - _numSolidFiles = 1; - return S_OK; -} - -static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) -{ - RINOK(PROPVARIANT_to_bool(prop, dest.Val)); - dest.Def = true; - return S_OK; -} - -HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) -{ - UString name = nameSpec; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - - if (name[0] == L's') - { - name.Delete(0); - if (name.IsEmpty()) - return SetSolidFromPROPVARIANT(value); - if (value.vt != VT_EMPTY) - return E_INVALIDARG; - return SetSolidFromString(name); - } - - UInt32 number; - int index = ParseStringToUInt32(name, number); - // UString realName = name.Ptr(index); - if (index == 0) - { - if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock); - if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders); - // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents); - - if (name.IsEqualTo("hcf")) - { - bool compressHeadersFull = true; - RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)); - return compressHeadersFull ? S_OK: E_INVALIDARG; - } - - if (name.IsEqualTo("he")) - { - RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)); - _encryptHeadersSpecified = true; - return S_OK; - } - - if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime); - if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime); - if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime); - - if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer); - - if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting); - - // if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode); - } - return CMultiMethodProps::SetProperty(name, value); -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - COM_TRY_BEGIN - _bonds.Clear(); - InitProps(); - - 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] == 'b') - { - if (value.vt != VT_EMPTY) - return E_INVALIDARG; - name.Delete(0); - - CBond2 bond; - RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)); - if (name[0] != ':') - return E_INVALIDARG; - name.Delete(0); - UInt32 inStream = 0; - RINOK(ParseBond(name, bond.InCoder, inStream)); - if (inStream != 0) - return E_INVALIDARG; - if (!name.IsEmpty()) - return E_INVALIDARG; - _bonds.Add(bond); - continue; - } - - RINOK(SetProperty(name, value)); - } - - unsigned numEmptyMethods = GetNumEmptyMethods(); - if (numEmptyMethods > 0) - { - unsigned k; - for (k = 0; k < _bonds.Size(); k++) - { - const CBond2 &bond = _bonds[k]; - if (bond.InCoder < (UInt32)numEmptyMethods || - bond.OutCoder < (UInt32)numEmptyMethods) - return E_INVALIDARG; - } - for (k = 0; k < _bonds.Size(); k++) - { - CBond2 &bond = _bonds[k]; - bond.InCoder -= (UInt32)numEmptyMethods; - bond.OutCoder -= (UInt32)numEmptyMethods; - } - _methods.DeleteFrontal(numEmptyMethods); - } - - FOR_VECTOR (k, _bonds) - { - const CBond2 &bond = _bonds[k]; - if (bond.InCoder >= (UInt32)_methods.Size() || - bond.OutCoder >= (UInt32)_methods.Size()) - return E_INVALIDARG; - } - - return S_OK; - COM_TRY_END -} - -}} +// 7zHandlerOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/Wildcard.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/ParseProperties.h" + +#include "7zHandler.h" +#include "7zOut.h" +#include "7zUpdate.h" + +#ifndef Z7_EXTRACT_ONLY + +using namespace NWindows; + +namespace NArchive { +namespace N7z { + +static const UInt32 k_decoderCompatibilityVersion = 2301; +// 7-Zip version 2301 supports ARM64 filter + +#define k_LZMA_Name "LZMA" +#define kDefaultMethodName "LZMA2" +#define k_Copy_Name "Copy" + +#define k_MatchFinder_ForHeaders "BT2" + +static const UInt32 k_NumFastBytes_ForHeaders = 273; +static const UInt32 k_Level_ForHeaders = 5; +static const UInt32 k_Dictionary_ForHeaders = + #ifdef UNDER_CE + 1 << 18; + #else + 1 << 20; + #endif + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) +{ + *type = NFileTimeType::kWindows; + return S_OK; +} + +HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m) +{ + bool isFilter; + dest.CodecIndex = FindMethod_Index( + EXTERNAL_CODECS_VARS + m.MethodName, true, + dest.Id, dest.NumStreams, isFilter); + if (dest.CodecIndex < 0) + return E_INVALIDARG; + (CProps &)dest = (CProps &)m; + return S_OK; +} + +HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod) +{ + if (!_compressHeaders) + return S_OK; + COneMethodInfo m; + m.MethodName = k_LZMA_Name; + m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders); + m.AddProp_Level(k_Level_ForHeaders); + m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders); + m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders); + m.AddProp_NumThreads(1); + + CMethodFull &methodFull = headerMethod.Methods.AddNew(); + return PropsMethod_To_FullMethod(methodFull, m); +} + + +HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode) +{ + methodMode.Bonds = _bonds; + + // we create local copy of _methods. So we can modify it. + CObjectVector methods = _methods; + + { + FOR_VECTOR (i, methods) + { + AString &methodName = methods[i].MethodName; + if (methodName.IsEmpty()) + methodName = kDefaultMethodName; + } + if (methods.IsEmpty()) + { + COneMethodInfo &m = methods.AddNew(); + m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName); + methodMode.DefaultMethod_was_Inserted = true; + } + } + + if (!_filterMethod.MethodName.IsEmpty()) + { + // if (methodMode.Bonds.IsEmpty()) + { + FOR_VECTOR (k, methodMode.Bonds) + { + CBond2 &bond = methodMode.Bonds[k]; + bond.InCoder++; + bond.OutCoder++; + } + methods.Insert(0, _filterMethod); + methodMode.Filter_was_Inserted = true; + } + } + + const UInt64 kSolidBytes_Min = 1 << 24; + const UInt64 kSolidBytes_Max = (UInt64)1 << 32; // for non-LZMA2 methods + + bool needSolid = false; + + FOR_VECTOR (i, methods) + { + COneMethodInfo &oneMethodInfo = methods[i]; + + SetGlobalLevelTo(oneMethodInfo); + +#ifndef Z7_ST + const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0); + if (!numThreads_WasSpecifiedInMethod) + { + // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already + CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads); + } + if (methodMode.NumThreadGroups > 1) + CMultiMethodProps::Set_Method_NumThreadGroups_IfNotFinded(oneMethodInfo, methodMode.NumThreadGroups); +#endif + + CMethodFull &methodFull = methodMode.Methods.AddNew(); + RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)) + +#ifndef Z7_ST + methodFull.Set_NumThreads = true; + methodFull.NumThreads = methodMode.NumThreads; +#endif + + if (methodFull.Id != k_Copy) + needSolid = true; + + UInt64 dicSize; + switch (methodFull.Id) + { + case k_LZMA: + case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break; + case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break; + case k_Deflate: dicSize = (UInt32)1 << 15; break; + case k_Deflate64: dicSize = (UInt32)1 << 16; break; + case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break; + // case k_ZSTD: dicSize = 1 << 23; break; + default: continue; + } + + UInt64 numSolidBytes; + + /* + if (methodFull.Id == k_ZSTD) + { + // continue; + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(oneMethodInfo.Set_PropsTo_zstd(encoderProps)); + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + UInt64 cs = (UInt64)(zstdProps.jobSize); + UInt32 winSize = (UInt32)(1 << zstdProps.windowLog); + if (cs < winSize) + cs = winSize; + numSolidBytes = cs << 6; + const UInt64 kSolidBytes_Zstd_Max = ((UInt64)1 << 34); + if (numSolidBytes > kSolidBytes_Zstd_Max) + numSolidBytes = kSolidBytes_Zstd_Max; + + methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder + + #ifndef Z7_ST + if (!numThreads_WasSpecifiedInMethod + && !methodMode.NumThreads_WasForced + && methodMode.MemoryUsageLimit_WasSet + ) + { + const UInt32 numThreads_Original = methodMode.NumThreads; + const UInt32 numThreads_New = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps, + methodMode.MemoryUsageLimit, + numThreads_Original); + if (numThreads_Original != numThreads_New) + { + CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New); + } + } + #endif + } + else + */ + if (methodFull.Id == k_LZMA2) + { + // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code + /* lzma2 code use dictionary up to fake 4 GiB to calculate ChunkSize. + So we do same */ + UInt64 cs = (UInt64)dicSize << 2; + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + if (cs < kMinSize) cs = kMinSize; + if (cs > kMaxSize) cs = kMaxSize; + if (cs < dicSize) cs = dicSize; + cs += (kMinSize - 1); + cs &= ~(UInt64)(kMinSize - 1); + // we want to use at least 64 chunks (threads) per one solid block. + + // here we don't use chunkSize property + numSolidBytes = cs << 6; + + // here we get real chunkSize + cs = oneMethodInfo.Get_Xz_BlockSize(); + if (dicSize > cs) + dicSize = cs; + + const UInt64 kSolidBytes_Lzma2_Max = (UInt64)1 << 34; + if (numSolidBytes > kSolidBytes_Lzma2_Max) + numSolidBytes = kSolidBytes_Lzma2_Max; + + methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder + + #ifndef Z7_ST + if (!numThreads_WasSpecifiedInMethod + && !methodMode.NumThreads_WasForced + && methodMode.MemoryUsageLimit_WasSet) + { + const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); + const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads; + + if (numBlockThreads_Original > 1) + { + /* + const UInt32 kNumThreads_Max = 1024; + if (numBlockThreads > kNumMaxThreads) + numBlockThreads = kNumMaxThreads; + */ + + UInt32 numBlockThreads = numBlockThreads_Original; + const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid + + for (; numBlockThreads > 1; numBlockThreads--) + { + UInt64 size = numBlockThreads * (lzmaMemUsage + cs); + UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; + if (cs < ((UInt32)1 << 26)) numPackChunks++; + if (cs < ((UInt32)1 << 24)) numPackChunks++; + if (cs < ((UInt32)1 << 22)) numPackChunks++; + size += numPackChunks * cs; + // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20)); + if (size <= methodMode.MemoryUsageLimit) + break; + } + + if (numBlockThreads == 0) + numBlockThreads = 1; + if (numBlockThreads != numBlockThreads_Original) + { + const UInt32 numThreads_New = numBlockThreads * lzmaThreads; + CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New); + } + } + } + #endif + } + else + { + numSolidBytes = (UInt64)dicSize << 7; + if (numSolidBytes > kSolidBytes_Max) + numSolidBytes = kSolidBytes_Max; + } + + if (_numSolidBytesDefined) + continue; + + if (numSolidBytes < kSolidBytes_Min) + numSolidBytes = kSolidBytes_Min; + _numSolidBytes = numSolidBytes; + _numSolidBytesDefined = true; + } + + if (!_numSolidBytesDefined) + { + if (needSolid) + _numSolidBytes = kSolidBytes_Max; + else + _numSolidBytes = 0; + } + _numSolidBytesDefined = true; + + + return S_OK; +} + + + +static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined) +{ + // ft = 0; + // ftDefined = false; + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(index, propID, &prop)) + if (prop.vt == VT_FILETIME) + { + ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); + ftDefined = true; + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + else + { + ft = 0; + ftDefined = false; + } + return S_OK; +} + +/* + +#ifdef _WIN32 +static const wchar_t kDirDelimiter1 = L'\\'; +#endif +static const wchar_t kDirDelimiter2 = L'/'; + +static inline bool IsCharDirLimiter(wchar_t c) +{ + return ( + #ifdef _WIN32 + c == kDirDelimiter1 || + #endif + c == kDirDelimiter2); +} + +static int FillSortIndex(CObjectVector &treeFolders, int cur, int curSortIndex) +{ + CTreeFolder &tf = treeFolders[cur]; + tf.SortIndex = curSortIndex++; + for (int i = 0; i < tf.SubFolders.Size(); i++) + curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex); + tf.SortIndexEnd = curSortIndex; + return curSortIndex; +} + +static int FindSubFolder(const CObjectVector &treeFolders, int cur, const UString &name, int &insertPos) +{ + const CIntVector &subFolders = treeFolders[cur].SubFolders; + int left = 0, right = subFolders.Size(); + insertPos = -1; + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + int mid = (left + right) / 2; + int midFolder = subFolders[mid]; + int compare = CompareFileNames(name, treeFolders[midFolder].Name); + if (compare == 0) + return midFolder; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +static int AddFolder(CObjectVector &treeFolders, int cur, const UString &name) +{ + int insertPos; + int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos); + if (folderIndex < 0) + { + folderIndex = treeFolders.Size(); + CTreeFolder &newFolder = treeFolders.AddNew(); + newFolder.Parent = cur; + newFolder.Name = name; + treeFolders[cur].SubFolders.Insert(insertPos, folderIndex); + } + // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234; + return folderIndex; +} +*/ + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + const CDbEx *db = NULL; + #ifdef Z7_7Z_VOL + if (_volumes.Size() > 1) + return E_FAIL; + const CVolume *volume = 0; + if (_volumes.Size() == 1) + { + volume = &_volumes.Front(); + db = &volume->Database; + } + #else + if (_inStream) + db = &_db; + #endif + + if (db && !db->CanUpdate()) + return E_NOTIMPL; + + /* + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRawProps, + getRawProps, updateCallback) + + CUniqBlocks secureBlocks; + secureBlocks.AddUniq(NULL, 0); + + CObjectVector treeFolders; + { + CTreeFolder folder; + folder.Parent = -1; + treeFolders.Add(folder); + } + */ + + CObjectVector updateItems; + + 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 (!TimeOptions.Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty(); + if (!TimeOptions.Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty(); + if (!TimeOptions.Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty(); + if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty(); + } + + // UString s; + UString name; + + for (UInt32 i = 0; i < numItems; i++) + { + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) + CUpdateItem ui; + ui.NewProps = IntToBool(newProps); + ui.NewData = IntToBool(newData); + ui.IndexInArchive = (int)indexInArchive; + ui.IndexInClient = i; + ui.IsAnti = false; + ui.Size = 0; + + name.Empty(); + // bool isAltStream = false; + if (ui.IndexInArchive != -1) + { + if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size()) + return E_INVALIDARG; + const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive]; + if (!ui.NewProps) + { + _db.GetPath((unsigned)ui.IndexInArchive, name); + } + ui.IsDir = fi.IsDir; + ui.Size = fi.Size; + // isAltStream = fi.IsAltStream; + ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive); + + if (!ui.NewProps) + { + ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime); + ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime); + ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime); + } + } + + if (ui.NewProps) + { + bool folderStatusIsDefined; + if (need_Attrib) + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)) + if (prop.vt == VT_EMPTY) + ui.AttribDefined = false; + else if (prop.vt != VT_UI4) + return E_INVALIDARG; + else + { + ui.Attrib = prop.ulVal; + ui.AttribDefined = true; + } + } + + // we need MTime to sort files. + if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined)) + if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined)) + if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined)) + + /* + if (getRawProps) + { + const void *data; + UInt32 dataSize; + UInt32 propType; + + getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType); + if (dataSize != 0 && propType != NPropDataType::kRaw) + return E_FAIL; + ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize); + } + */ + + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidPath, &prop)) + if (prop.vt == VT_EMPTY) + { + } + else if (prop.vt != VT_BSTR) + return E_INVALIDARG; + else + { + name = prop.bstrVal; + NItemName::ReplaceSlashes_OsToUnix(name); + } + } + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)) + if (prop.vt == VT_EMPTY) + folderStatusIsDefined = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + { + ui.IsDir = (prop.boolVal != VARIANT_FALSE); + folderStatusIsDefined = true; + } + } + + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)) + if (prop.vt == VT_EMPTY) + ui.IsAnti = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + ui.IsAnti = (prop.boolVal != VARIANT_FALSE); + } + + /* + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop)); + if (prop.vt == VT_EMPTY) + isAltStream = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + isAltStream = (prop.boolVal != VARIANT_FALSE); + } + */ + + if (ui.IsAnti) + { + ui.AttribDefined = false; + + ui.CTimeDefined = false; + ui.ATimeDefined = false; + ui.MTimeDefined = false; + + ui.Size = 0; + } + + if (!folderStatusIsDefined && ui.AttribDefined) + ui.SetDirStatusFromAttrib(); + } + else + { + /* + if (_db.SecureIDs.IsEmpty()) + ui.SecureIndex = secureBlocks.AddUniq(NULL, 0); + else + { + int id = _db.SecureIDs[ui.IndexInArchive]; + size_t offs = _db.SecureOffsets[id]; + size_t size = _db.SecureOffsets[id + 1] - offs; + ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size); + } + */ + } + + /* + { + int folderIndex = 0; + if (_useParents) + { + int j; + s.Empty(); + for (j = 0; j < name.Len(); j++) + { + wchar_t c = name[j]; + if (IsCharDirLimiter(c)) + { + folderIndex = AddFolder(treeFolders, folderIndex, s); + s.Empty(); + continue; + } + s += c; + } + if (isAltStream) + { + int colonPos = s.Find(':'); + if (colonPos < 0) + { + // isAltStream = false; + return E_INVALIDARG; + } + UString mainName = s.Left(colonPos); + int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName); + if (treeFolders[newFolderIndex].UpdateItemIndex < 0) + { + for (int j = updateItems.Size() - 1; j >= 0; j--) + { + CUpdateItem &ui2 = updateItems[j]; + if (ui2.ParentFolderIndex == folderIndex + && ui2.Name == mainName) + { + ui2.TreeFolderIndex = newFolderIndex; + treeFolders[newFolderIndex].UpdateItemIndex = j; + } + } + } + folderIndex = newFolderIndex; + s.Delete(0, colonPos + 1); + } + ui.Name = s; + } + else + ui.Name = name; + ui.IsAltStream = isAltStream; + ui.ParentFolderIndex = folderIndex; + ui.TreeFolderIndex = -1; + if (ui.IsDir && !s.IsEmpty()) + { + ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s); + treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size(); + } + } + */ + ui.Name = name; + + if (ui.NewData) + { + ui.Size = 0; + if (!ui.IsDir) + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(i, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + ui.Size = (UInt64)prop.uhVal.QuadPart; + if (ui.Size != 0 && ui.IsAnti) + return E_INVALIDARG; + } + } + + updateItems.Add(ui); + } + + /* + FillSortIndex(treeFolders, 0, 0); + for (i = 0; i < (UInt32)updateItems.Size(); i++) + { + CUpdateItem &ui = updateItems[i]; + ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex; + ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd; + } + */ + + CCompressionMethodMode methodMode, headerMethod; + + methodMode.MemoryUsageLimit = _memUsage_Compress; + methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet; + + #ifndef Z7_ST + { + UInt32 numThreads = _numThreads; + const UInt32 kNumThreads_Max = 1024; + if (numThreads > kNumThreads_Max) + numThreads = kNumThreads_Max; + methodMode.NumThreads = numThreads; + methodMode.NumThreads_WasForced = _numThreads_WasForced; + methodMode.MultiThreadMixer = _useMultiThreadMixer; +#ifdef _WIN32 + methodMode.NumThreadGroups = _numThreadGroups; // _change it +#endif + // headerMethod.NumThreads = 1; + headerMethod.MultiThreadMixer = _useMultiThreadMixer; + } + #endif + + const HRESULT res = SetMainMethod(methodMode); + RINOK(res) + + RINOK(SetHeaderMethod(headerMethod)) + + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword2, + getPassword2, updateCallback) + + methodMode.PasswordIsDefined = false; + methodMode.Password.Wipe_and_Empty(); + if (getPassword2) + { + CMyComBSTR_Wipe password; + Int32 passwordIsDefined; + RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)) + methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); + if (methodMode.PasswordIsDefined && password) + methodMode.Password = password; + } + + bool compressMainHeader = _compressHeaders; // check it + + bool encryptHeaders = false; + + #ifndef Z7_NO_CRYPTO + if (!methodMode.PasswordIsDefined && _passwordIsDefined) + { + // if header is compressed, we use that password for updated archive + methodMode.PasswordIsDefined = true; + methodMode.Password = _password; + } + #endif + + if (methodMode.PasswordIsDefined) + { + if (_encryptHeadersSpecified) + encryptHeaders = _encryptHeaders; + #ifndef Z7_NO_CRYPTO + else + encryptHeaders = _passwordIsDefined; + #endif + compressMainHeader = true; + if (encryptHeaders) + { + headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined; + headerMethod.Password = methodMode.Password; + } + } + + if (numItems < 2) + compressMainHeader = false; + + const int level = GetLevel(); + + CUpdateOptions options; + options.Need_CTime = need_CTime; + options.Need_ATime = need_ATime; + options.Need_MTime = need_MTime; + options.Need_Attrib = need_Attrib; + // options.Need_Crc = (_crcSize != 0); // for debug + + options.Method = &methodMode; + options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL; + options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted); + options.MaxFilter = (level >= 8); + options.AnalysisLevel = GetAnalysisLevel(); + + options.SetFilterSupporting_ver_enabled_disabled( + _decoderCompatibilityVersion, + _enabledFilters, + _disabledFilters); + + options.HeaderOptions.CompressMainHeader = compressMainHeader; + /* + options.HeaderOptions.WriteCTime = Write_CTime; + options.HeaderOptions.WriteATime = Write_ATime; + options.HeaderOptions.WriteMTime = Write_MTime; + options.HeaderOptions.WriteAttrib = Write_Attrib; + */ + + options.NumSolidFiles = _numSolidFiles; + options.NumSolidBytes = _numSolidBytes; + options.SolidExtension = _solidExtension; + options.UseTypeSorting = _useTypeSorting; + + options.RemoveSfxBlock = _removeSfxBlock; + // options.VolumeMode = _volumeMode; + + options.MultiThreadMixer = _useMultiThreadMixer; + + /* + if (secureBlocks.Sorted.Size() > 1) + { + secureBlocks.GetReverseMap(); + for (int i = 0; i < updateItems.Size(); i++) + { + int &secureIndex = updateItems[i].SecureIndex; + secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex]; + } + } + */ + + return Update( + EXTERNAL_CODECS_VARS + #ifdef Z7_7Z_VOL + volume ? volume->Stream: 0, + volume ? db : 0, + #else + _inStream, + db, + #endif + updateItems, + // treeFolders, + // secureBlocks, + outStream, updateCallback, options); + + COM_TRY_END +} + +static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream) +{ + stream = 0; + { + const unsigned index = ParseStringToUInt32(srcString, coder); + if (index == 0) + return E_INVALIDARG; + srcString.DeleteFrontal(index); + } + if (srcString[0] == 's') + { + srcString.Delete(0); + const unsigned index = ParseStringToUInt32(srcString, stream); + if (index == 0) + return E_INVALIDARG; + srcString.DeleteFrontal(index); + } + return S_OK; +} + +void COutHandler::InitProps7z() +{ + _removeSfxBlock = false; + _compressHeaders = true; + _encryptHeadersSpecified = false; + _encryptHeaders = false; + // _useParents = false; + + TimeOptions.Init(); + Write_Attrib.Init(); + + _useMultiThreadMixer = true; + + // _volumeMode = false; + + InitSolid(); + _useTypeSorting = false; + + _decoderCompatibilityVersion = k_decoderCompatibilityVersion; + _enabledFilters.Clear(); + _disabledFilters.Clear(); +} + +void COutHandler::InitProps() +{ + CMultiMethodProps::Init(); + InitProps7z(); +} + + + +HRESULT COutHandler::SetSolidFromString(const UString &s) +{ + UString s2 = s; + s2.MakeLower_Ascii(); + for (unsigned i = 0; i < s2.Len();) + { + const wchar_t *start = ((const wchar_t *)s2) + i; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (start == end) + { + if (s2[i++] != 'e') + return E_INVALIDARG; + _solidExtension = true; + continue; + } + i += (unsigned)(end - start); + if (i == s2.Len()) + return E_INVALIDARG; + const wchar_t c = s2[i++]; + if (c == 'f') + { + if (v < 1) + v = 1; + _numSolidFiles = v; + } + else + { + unsigned numBits; + switch (c) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return E_INVALIDARG; + } + _numSolidBytes = (v << numBits); + _numSolidBytesDefined = true; + /* + if (_numSolidBytes == 0) + _numSolidFiles = 1; + */ + } + } + return S_OK; +} + +HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value) +{ + bool isSolid; + switch (value.vt) + { + case VT_EMPTY: isSolid = true; break; + case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break; + case VT_BSTR: + if (StringToBool(value.bstrVal, isSolid)) + break; + return SetSolidFromString(value.bstrVal); + default: return E_INVALIDARG; + } + if (isSolid) + InitSolid(); + else + _numSolidFiles = 1; + return S_OK; +} + +static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) +{ + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) + dest.Def = true; + return S_OK; +} + +struct C_Id_Name_pair +{ + UInt32 Id; + const char *Name; +}; + +static const C_Id_Name_pair g_filter_pairs[] = +{ + { k_Delta, "Delta" }, + { k_ARM64, "ARM64" }, + { k_RISCV, "RISCV" }, + { k_SWAP2, "SWAP2" }, + { k_SWAP4, "SWAP4" }, + { k_BCJ, "BCJ" }, + { k_BCJ2 , "BCJ2" }, + { k_PPC, "PPC" }, + { k_IA64, "IA64" }, + { k_ARM, "ARM" }, + { k_ARMT, "ARMT" }, + { k_SPARC, "SPARC" } +}; + + +HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name[0] == L's') + { + name.Delete(0); + if (name.IsEmpty()) + return SetSolidFromPROPVARIANT(value); + if (value.vt != VT_EMPTY) + return E_INVALIDARG; + return SetSolidFromString(name); + } + + UInt32 number; + const unsigned index = ParseStringToUInt32(name, number); + // UString realName = name.Ptr(index); + if (index == 0) + { + if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock); + if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders); + // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents); + + if (name.IsEqualTo("hcf")) + { + bool compressHeadersFull = true; + RINOK(PROPVARIANT_to_bool(value, compressHeadersFull)) + return compressHeadersFull ? S_OK: E_INVALIDARG; + } + + if (name.IsEqualTo("he")) + { + RINOK(PROPVARIANT_to_bool(value, _encryptHeaders)) + _encryptHeadersSpecified = true; + return S_OK; + } + + { + 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); + + if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting); + + if (name.IsPrefixedBy_Ascii_NoCase("yv")) + { + name.Delete(0, 2); + UInt32 v = 1 << 16; // if no number is noit specified, we use big value + RINOK(ParsePropToUInt32(name, value, v)) + _decoderCompatibilityVersion = v; + // if (v == 0) _decoderCompatibilityVersion = k_decoderCompatibilityVersion; + return S_OK; + } + + if (name.IsPrefixedBy_Ascii_NoCase("yf")) + { + name.Delete(0, 2); + CUIntVector *vec; + if (name.IsEqualTo_Ascii_NoCase("a")) vec = &_enabledFilters; + else if (name.IsEqualTo_Ascii_NoCase("d")) vec = &_disabledFilters; + else return E_INVALIDARG; + + if (value.vt != VT_BSTR) + return E_INVALIDARG; + for (unsigned k = 0;; k++) + { + if (k == Z7_ARRAY_SIZE(g_filter_pairs)) + { + // maybe we can ignore unsupported filter names here? + return E_INVALIDARG; + } + const C_Id_Name_pair &pair = g_filter_pairs[k]; + if (StringsAreEqualNoCase_Ascii(value.bstrVal, pair.Name)) + { + vec->AddToUniqueSorted(pair.Id); + break; + } + } + return S_OK; + } + + // if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode); + } + return CMultiMethodProps::SetProperty(name, value); +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + COM_TRY_BEGIN + _bonds.Clear(); + InitProps(); + + 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.Find(L':') >= 0) // 'b' was used as NCoderPropID::kBlockSize2 before v23 + if (name[0] == 'b') + { + if (value.vt != VT_EMPTY) + return E_INVALIDARG; + name.Delete(0); + + CBond2 bond; + RINOK(ParseBond(name, bond.OutCoder, bond.OutStream)) + if (name[0] != ':') + return E_INVALIDARG; + name.Delete(0); + UInt32 inStream = 0; + RINOK(ParseBond(name, bond.InCoder, inStream)) + if (inStream != 0) + return E_INVALIDARG; + if (!name.IsEmpty()) + return E_INVALIDARG; + _bonds.Add(bond); + continue; + } + + RINOK(SetProperty(name, value)) + } + + unsigned numEmptyMethods = GetNumEmptyMethods(); + if (numEmptyMethods > 0) + { + unsigned k; + for (k = 0; k < _bonds.Size(); k++) + { + const CBond2 &bond = _bonds[k]; + if (bond.InCoder < (UInt32)numEmptyMethods || + bond.OutCoder < (UInt32)numEmptyMethods) + return E_INVALIDARG; + } + for (k = 0; k < _bonds.Size(); k++) + { + CBond2 &bond = _bonds[k]; + bond.InCoder -= (UInt32)numEmptyMethods; + bond.OutCoder -= (UInt32)numEmptyMethods; + } + _methods.DeleteFrontal(numEmptyMethods); + } + + FOR_VECTOR (k, _bonds) + { + const CBond2 &bond = _bonds[k]; + if (bond.InCoder >= (UInt32)_methods.Size() || + bond.OutCoder >= (UInt32)_methods.Size()) + return E_INVALIDARG; + } + + return S_OK; + COM_TRY_END +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHeader.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHeader.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.cpp 2023-03-04 09:00:00.000000000 +0000 @@ -1,19 +1,19 @@ -// 7zHeader.cpp - -#include "StdAfx.h" - -#include "7zHeader.h" - -namespace NArchive { -namespace N7z { - -Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; -#ifdef _7Z_VOL -Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; -#endif - -// We can change signature. So file doesn't contain correct signature. -// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } }; -// static SignatureInitializer g_SignatureInitializer; - -}} +// 7zHeader.cpp + +#include "StdAfx.h" + +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +Byte kSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; +#ifdef Z7_7Z_VOL +Byte kFinishSignature[kSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C + 1}; +#endif + +// We can change signature. So file doesn't contain correct signature. +// struct SignatureInitializer { SignatureInitializer() { kSignature[0]--; } }; +// static SignatureInitializer g_SignatureInitializer; + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zHeader.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zHeader.h 2024-03-03 09:00:00.000000000 +0000 @@ -1,148 +1,156 @@ -// 7z/7zHeader.h - -#ifndef __7Z_HEADER_H -#define __7Z_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace N7z { - -const unsigned kSignatureSize = 6; -extern Byte kSignature[kSignatureSize]; - -// #define _7Z_VOL -// 7z-MultiVolume is not finished yet. -// It can work already, but I still do not like some -// things of that new multivolume format. -// So please keep it commented. - -#ifdef _7Z_VOL -extern Byte kFinishSignature[kSignatureSize]; -#endif - -struct CArchiveVersion -{ - Byte Major; - Byte Minor; -}; - -const Byte kMajorVersion = 0; - -struct CStartHeader -{ - UInt64 NextHeaderOffset; - UInt64 NextHeaderSize; - UInt32 NextHeaderCRC; -}; - -const UInt32 kStartHeaderSize = 20; - -#ifdef _7Z_VOL -struct CFinishHeader: public CStartHeader -{ - UInt64 ArchiveStartOffset; // data offset from end if that struct - UInt64 AdditionalStartBlockSize; // start signature & start header size -}; - -const UInt32 kFinishHeaderSize = kStartHeaderSize + 16; -#endif - -namespace NID -{ - enum EEnum - { - kEnd, - - kHeader, - - kArchiveProperties, - - kAdditionalStreamsInfo, - kMainStreamsInfo, - kFilesInfo, - - kPackInfo, - kUnpackInfo, - kSubStreamsInfo, - - kSize, - kCRC, - - kFolder, - - kCodersUnpackSize, - kNumUnpackStream, - - kEmptyStream, - kEmptyFile, - kAnti, - - kName, - kCTime, - kATime, - kMTime, - kWinAttrib, - kComment, - - kEncodedHeader, - - kStartPos, - kDummy - - // kNtSecure, - // kParent, - // kIsAux - }; -} - - -const UInt32 k_Copy = 0; -const UInt32 k_Delta = 3; - -const UInt32 k_LZMA2 = 0x21; - -const UInt32 k_SWAP2 = 0x20302; -const UInt32 k_SWAP4 = 0x20304; - -const UInt32 k_LZMA = 0x30101; -const UInt32 k_PPMD = 0x30401; - -const UInt32 k_Deflate = 0x40108; -const UInt32 k_BZip2 = 0x40202; - -const UInt32 k_BCJ = 0x3030103; -const UInt32 k_BCJ2 = 0x303011B; -const UInt32 k_PPC = 0x3030205; -const UInt32 k_IA64 = 0x3030401; -const UInt32 k_ARM = 0x3030501; -const UInt32 k_ARMT = 0x3030701; -const UInt32 k_SPARC = 0x3030805; - -const UInt32 k_AES = 0x6F10701; - - -static inline bool IsFilterMethod(UInt64 m) -{ - if (m > (UInt64)0xFFFFFFFF) - return false; - switch ((UInt32)m) - { - case k_Delta: - case k_BCJ: - case k_BCJ2: - case k_PPC: - case k_IA64: - case k_ARM: - case k_ARMT: - case k_SPARC: - case k_SWAP2: - case k_SWAP4: - return true; - } - return false; -} - -}} - -#endif +// 7z/7zHeader.h + +#ifndef ZIP7_INC_7Z_HEADER_H +#define ZIP7_INC_7Z_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace N7z { + +const unsigned kSignatureSize = 6; +extern Byte kSignature[kSignatureSize]; + +// #define Z7_7Z_VOL +// 7z-MultiVolume is not finished yet. +// It can work already, but I still do not like some +// things of that new multivolume format. +// So please keep it commented. + +#ifdef Z7_7Z_VOL +extern Byte kFinishSignature[kSignatureSize]; +#endif + +struct CArchiveVersion +{ + Byte Major; + Byte Minor; +}; + +const Byte kMajorVersion = 0; + +struct CStartHeader +{ + UInt64 NextHeaderOffset; + UInt64 NextHeaderSize; + UInt32 NextHeaderCRC; +}; + +const UInt32 kStartHeaderSize = 20; + +#ifdef Z7_7Z_VOL +struct CFinishHeader: public CStartHeader +{ + UInt64 ArchiveStartOffset; // data offset from end if that struct + UInt64 AdditionalStartBlockSize; // start signature & start header size +}; + +const UInt32 kFinishHeaderSize = kStartHeaderSize + 16; +#endif + +namespace NID +{ + enum EEnum + { + kEnd, + + kHeader, + + kArchiveProperties, + + kAdditionalStreamsInfo, + kMainStreamsInfo, + kFilesInfo, + + kPackInfo, + kUnpackInfo, + kSubStreamsInfo, + + kSize, + kCRC, + + kFolder, + + kCodersUnpackSize, + kNumUnpackStream, + + kEmptyStream, + kEmptyFile, + kAnti, + + kName, + kCTime, + kATime, + kMTime, + kWinAttrib, + kComment, + + kEncodedHeader, + + kStartPos, + kDummy + + // kNtSecure, + // kParent, + // kIsAux + }; +} + + +const UInt32 k_Copy = 0; +const UInt32 k_Delta = 3; +const UInt32 k_ARM64 = 0xa; +const UInt32 k_RISCV = 0xb; + +const UInt32 k_LZMA2 = 0x21; + +const UInt32 k_SWAP2 = 0x20302; +const UInt32 k_SWAP4 = 0x20304; + +const UInt32 k_LZMA = 0x30101; +const UInt32 k_PPMD = 0x30401; + +const UInt32 k_Deflate = 0x40108; +const UInt32 k_Deflate64 = 0x40109; +const UInt32 k_BZip2 = 0x40202; + +const UInt32 k_BCJ = 0x3030103; +const UInt32 k_BCJ2 = 0x303011B; +const UInt32 k_PPC = 0x3030205; +const UInt32 k_IA64 = 0x3030401; +const UInt32 k_ARM = 0x3030501; +const UInt32 k_ARMT = 0x3030701; +const UInt32 k_SPARC = 0x3030805; + +const UInt32 k_AES = 0x6F10701; + +// const UInt32 k_ZSTD = 0x4015D; // winzip zstd +// 0x4F71101, 7z-zstd + +inline bool IsFilterMethod(UInt64 m) +{ + if (m > (UInt32)0xFFFFFFFF) + return false; + switch ((UInt32)m) + { + case k_Delta: + case k_ARM64: + case k_RISCV: + case k_BCJ: + case k_BCJ2: + case k_PPC: + case k_IA64: + case k_ARM: + case k_ARMT: + case k_SPARC: + case k_SWAP2: + case k_SWAP4: + return true; + default: break; + } + return false; +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zIn.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.cpp 2024-02-17 09:00:00.000000000 +0000 @@ -1,1640 +1,1764 @@ -// 7zIn.cpp - -#include "StdAfx.h" - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "../../../../C/7zCrc.h" -#include "../../../../C/CpuArch.h" - -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "7zDecode.h" -#include "7zIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader -#ifndef _SFX -#define FORMAT_7Z_RECOVERY -#endif - -using namespace NWindows; -using namespace NCOM; - -namespace NArchive { -namespace N7z { - -static void BoolVector_Fill_False(CBoolVector &v, unsigned size) -{ - v.ClearAndSetSize(size); - bool *p = &v[0]; - for (unsigned i = 0; i < size; i++) - p[i] = false; -} - -class CInArchiveException {}; -class CUnsupportedFeatureException: public CInArchiveException {}; - -static void ThrowException() { throw CInArchiveException(); } -static inline void ThrowEndOfData() { ThrowException(); } -static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } -static inline void ThrowIncorrect() { ThrowException(); } - -class CStreamSwitch -{ - CInArchive *_archive; - bool _needRemove; - bool _needUpdatePos; -public: - CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {} - ~CStreamSwitch() { Remove(); } - void Remove(); - void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos); - void Set(CInArchive *archive, const CByteBuffer &byteBuffer); - void Set(CInArchive *archive, const CObjectVector *dataVector); -}; - -void CStreamSwitch::Remove() -{ - if (_needRemove) - { - if (_archive->_inByteBack->GetRem() != 0) - _archive->ThereIsHeaderError = true; - _archive->DeleteByteStream(_needUpdatePos); - _needRemove = false; - } -} - -void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos) -{ - Remove(); - _archive = archive; - _archive->AddByteStream(data, size); - _needRemove = true; - _needUpdatePos = needUpdatePos; -} - -void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) -{ - Set(archive, byteBuffer, byteBuffer.Size(), false); -} - -void CStreamSwitch::Set(CInArchive *archive, const CObjectVector *dataVector) -{ - Remove(); - Byte external = archive->ReadByte(); - if (external != 0) - { - if (!dataVector) - ThrowIncorrect(); - CNum dataIndex = archive->ReadNum(); - if (dataIndex >= dataVector->Size()) - ThrowIncorrect(); - Set(archive, (*dataVector)[dataIndex]); - } -} - -void CInArchive::AddByteStream(const Byte *buf, size_t size) -{ - if (_numInByteBufs == kNumBufLevelsMax) - ThrowIncorrect(); - _inByteBack = &_inByteVector[_numInByteBufs++]; - _inByteBack->Init(buf, size); -} - - -Byte CInByte2::ReadByte() -{ - if (_pos >= _size) - ThrowEndOfData(); - return _buffer[_pos++]; -} - -void CInByte2::ReadBytes(Byte *data, size_t size) -{ - if (size == 0) - return; - if (size > _size - _pos) - ThrowEndOfData(); - memcpy(data, _buffer + _pos, size); - _pos += size; -} - -void CInByte2::SkipData(UInt64 size) -{ - if (size > _size - _pos) - ThrowEndOfData(); - _pos += (size_t)size; -} - -void CInByte2::SkipData() -{ - SkipData(ReadNumber()); -} - -static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) -{ - if (size == 0) - { - processed = 0; - return 0; - } - - unsigned b = *p++; - size--; - - if ((b & 0x80) == 0) - { - processed = 1; - return b; - } - - if (size == 0) - { - processed = 0; - return 0; - } - - UInt64 value = (UInt64)*p; - p++; - size--; - - for (unsigned i = 1; i < 8; i++) - { - unsigned mask = (unsigned)0x80 >> i; - if ((b & mask) == 0) - { - UInt64 high = b & (mask - 1); - value |= (high << (i * 8)); - processed = i + 1; - return value; - } - - if (size == 0) - { - processed = 0; - return 0; - } - - value |= ((UInt64)*p << (i * 8)); - p++; - size--; - } - - processed = 9; - return value; -} - -UInt64 CInByte2::ReadNumber() -{ - size_t processed; - UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); - if (processed == 0) - ThrowEndOfData(); - _pos += processed; - return res; -} - -CNum CInByte2::ReadNum() -{ - /* - if (_pos < _size) - { - Byte val = _buffer[_pos]; - if ((unsigned)val < 0x80) - { - _pos++; - return (unsigned)val; - } - } - */ - UInt64 value = ReadNumber(); - if (value > kNumMax) - ThrowUnsupported(); - return (CNum)value; -} - -UInt32 CInByte2::ReadUInt32() -{ - if (_pos + 4 > _size) - ThrowEndOfData(); - UInt32 res = Get32(_buffer + _pos); - _pos += 4; - return res; -} - -UInt64 CInByte2::ReadUInt64() -{ - if (_pos + 8 > _size) - ThrowEndOfData(); - UInt64 res = Get64(_buffer + _pos); - _pos += 8; - return res; -} - -#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false; - -static inline bool TestSignature(const Byte *p) -{ - CHECK_SIGNATURE - return CrcCalc(p + 12, 20) == Get32(p + 8); -} - -#ifdef FORMAT_7Z_RECOVERY -static inline bool TestSignature2(const Byte *p) -{ - CHECK_SIGNATURE; - if (CrcCalc(p + 12, 20) == Get32(p + 8)) - return true; - for (unsigned i = 8; i < kHeaderSize; i++) - if (p[i] != 0) - return false; - return (p[6] != 0 || p[7] != 0); -} -#else -#define TestSignature2(p) TestSignature(p) -#endif - -HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) -{ - RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); - - if (TestSignature2(_header)) - return S_OK; - if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) - return S_FALSE; - - const UInt32 kBufSize = 1 << 15; - CByteArr buf(kBufSize); - memcpy(buf, _header, kHeaderSize); - UInt64 offset = 0; - - for (;;) - { - UInt32 readSize = kBufSize - kHeaderSize; - if (searchHeaderSizeLimit) - { - UInt64 rem = *searchHeaderSizeLimit - offset; - if (readSize > rem) - readSize = (UInt32)rem; - if (readSize == 0) - return S_FALSE; - } - - UInt32 processed = 0; - RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)); - if (processed == 0) - return S_FALSE; - - for (UInt32 pos = 0;;) - { - const Byte *p = buf + pos + 1; - const Byte *lim = buf + processed; - for (; p <= lim; p += 4) - { - if (p[0] == '7') break; - if (p[1] == '7') { p += 1; break; } - if (p[2] == '7') { p += 2; break; } - if (p[3] == '7') { p += 3; break; } - }; - if (p > lim) - break; - pos = (UInt32)(p - buf); - if (TestSignature(p)) - { - memcpy(_header, p, kHeaderSize); - _arhiveBeginStreamPosition += offset + pos; - return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL); - } - } - - offset += processed; - memmove(buf, buf + processed, kHeaderSize); - } -} - -// S_FALSE means that file is not archive -HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) -{ - HeadersSize = 0; - Close(); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) - RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition)) - RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)) - RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); - _stream = stream; - return S_OK; -} - -void CInArchive::Close() -{ - _numInByteBufs = 0; - _stream.Release(); - ThereIsHeaderError = false; -} - -void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) -{ - for (;;) - { - if (ReadID() == NID::kEnd) - break; - SkipData(); - } -} - -// CFolder &folder can be non empty. So we must set all fields - -void CInByte2::ParseFolder(CFolder &folder) -{ - UInt32 numCoders = ReadNum(); - - if (numCoders == 0) - ThrowUnsupported(); - - folder.Coders.SetSize(numCoders); - - UInt32 numInStreams = 0; - UInt32 i; - for (i = 0; i < numCoders; i++) - { - CCoderInfo &coder = folder.Coders[i]; - { - Byte mainByte = ReadByte(); - if ((mainByte & 0xC0) != 0) - ThrowUnsupported(); - unsigned idSize = (mainByte & 0xF); - if (idSize > 8 || idSize > GetRem()) - ThrowUnsupported(); - const Byte *longID = GetPtr(); - UInt64 id = 0; - for (unsigned j = 0; j < idSize; j++) - id = ((id << 8) | longID[j]); - SkipDataNoCheck(idSize); - coder.MethodID = id; - - if ((mainByte & 0x10) != 0) - { - coder.NumStreams = ReadNum(); - /* numOutStreams = */ ReadNum(); - } - else - { - coder.NumStreams = 1; - } - - if ((mainByte & 0x20) != 0) - { - CNum propsSize = ReadNum(); - coder.Props.Alloc((size_t)propsSize); - ReadBytes((Byte *)coder.Props, (size_t)propsSize); - } - else - coder.Props.Free(); - } - numInStreams += coder.NumStreams; - } - - UInt32 numBonds = numCoders - 1; - folder.Bonds.SetSize(numBonds); - for (i = 0; i < numBonds; i++) - { - CBond &bp = folder.Bonds[i]; - bp.PackIndex = ReadNum(); - bp.UnpackIndex = ReadNum(); - } - - if (numInStreams < numBonds) - ThrowUnsupported(); - UInt32 numPackStreams = numInStreams - numBonds; - folder.PackStreams.SetSize(numPackStreams); - - if (numPackStreams == 1) - { - for (i = 0; i < numInStreams; i++) - if (folder.FindBond_for_PackStream(i) < 0) - { - folder.PackStreams[0] = i; - break; - } - if (i == numInStreams) - ThrowUnsupported(); - } - else - for (i = 0; i < numPackStreams; i++) - folder.PackStreams[i] = ReadNum(); -} - -void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const -{ - size_t startPos = FoCodersDataOffset[folderIndex]; - CInByte2 inByte; - inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); - inByte.ParseFolder(folder); - if (inByte.GetRem() != 0) - throw 20120424; -} - - -void CDatabase::GetPath(unsigned index, UString &path) const -{ - path.Empty(); - if (!NameOffsets || !NamesBuf) - return; - - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; - - if (size >= (1 << 28)) - return; - - wchar_t *s = path.GetBuf((unsigned)size - 1); - - const Byte *p = ((const Byte *)NamesBuf + offset * 2); - - #if defined(_WIN32) && defined(MY_CPU_LE) - - wmemcpy(s, (const wchar_t *)p, size); - - #else - - for (size_t i = 0; i < size; i++) - { - *s = Get16(p); - p += 2; - s++; - } - - #endif - - path.ReleaseBuf_SetLen((unsigned)size - 1); -} - -HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() -{ - PropVariant_Clear(path); - if (!NameOffsets || !NamesBuf) - return S_OK; - - size_t offset = NameOffsets[index]; - size_t size = NameOffsets[index + 1] - offset; - - if (size >= (1 << 14)) - return S_OK; - - RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)); - wchar_t *s = path->bstrVal; - - const Byte *p = ((const Byte *)NamesBuf + offset * 2); - - for (size_t i = 0; i < size; i++) - { - wchar_t c = Get16(p); - p += 2; - #if WCHAR_PATH_SEPARATOR != L'/' - if (c == L'/') - c = WCHAR_PATH_SEPARATOR; - #endif - *s++ = c; - } - - return S_OK; - - /* - unsigned cur = index; - unsigned size = 0; - - for (int i = 0;; i++) - { - size_t len = NameOffsets[cur + 1] - NameOffsets[cur]; - size += (unsigned)len; - if (i > 256 || len > (1 << 14) || size > (1 << 14)) - return PropVarEm_Set_Str(path, "[TOO-LONG]"); - cur = Files[cur].Parent; - if (cur < 0) - break; - } - size--; - - RINOK(PropVarEm_Alloc_Bstr(path, size)); - wchar_t *s = path->bstrVal; - s += size; - *s = 0; - cur = index; - - for (;;) - { - unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1); - const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2; - for (; len != 0; len--) - { - p -= 2; - --s; - wchar_t c = Get16(p); - if (c == '/') - c = WCHAR_PATH_SEPARATOR; - *s = c; - } - - const CFileItem &file = Files[cur]; - cur = file.Parent; - if (cur < 0) - return S_OK; - *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR); - } - */ -} - -void CInArchive::WaitId(UInt64 id) -{ - for (;;) - { - UInt64 type = ReadID(); - if (type == id) - return; - if (type == NID::kEnd) - ThrowIncorrect(); - SkipData(); - } -} - -void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) -{ - ReadBoolVector2(numItems, crcs.Defs); - crcs.Vals.ClearAndSetSize(numItems); - UInt32 *p = &crcs.Vals[0]; - const bool *defs = &crcs.Defs[0]; - for (unsigned i = 0; i < numItems; i++) - { - UInt32 crc = 0; - if (defs[i]) - crc = ReadUInt32(); - p[i] = crc; - } -} - -#define k_Scan_NumCoders_MAX 64 -#define k_Scan_NumCodersStreams_in_Folder_MAX 64 - -void CInArchive::ReadPackInfo(CFolders &f) -{ - CNum numPackStreams = ReadNum(); - - WaitId(NID::kSize); - f.PackPositions.Alloc(numPackStreams + 1); - f.NumPackStreams = numPackStreams; - UInt64 sum = 0; - for (CNum i = 0; i < numPackStreams; i++) - { - f.PackPositions[i] = sum; - UInt64 packSize = ReadNumber(); - sum += packSize; - if (sum < packSize) - ThrowIncorrect(); - } - f.PackPositions[numPackStreams] = sum; - - UInt64 type; - for (;;) - { - type = ReadID(); - if (type == NID::kEnd) - return; - if (type == NID::kCRC) - { - CUInt32DefVector PackCRCs; - ReadHashDigests(numPackStreams, PackCRCs); - continue; - } - SkipData(); - } -} - -void CInArchive::ReadUnpackInfo( - const CObjectVector *dataVector, - CFolders &folders) -{ - WaitId(NID::kFolder); - CNum numFolders = ReadNum(); - - CNum numCodersOutStreams = 0; - { - CStreamSwitch streamSwitch; - streamSwitch.Set(this, dataVector); - const Byte *startBufPtr = _inByteBack->GetPtr(); - folders.NumFolders = numFolders; - - folders.FoStartPackStreamIndex.Alloc(numFolders + 1); - folders.FoToMainUnpackSizeIndex.Alloc(numFolders); - folders.FoCodersDataOffset.Alloc(numFolders + 1); - folders.FoToCoderUnpackSizes.Alloc(numFolders + 1); - - CBoolVector StreamUsed; - CBoolVector CoderUsed; - - CNum packStreamIndex = 0; - CNum fo; - CInByte2 *inByte = _inByteBack; - - for (fo = 0; fo < numFolders; fo++) - { - UInt32 indexOfMainStream = 0; - UInt32 numPackStreams = 0; - folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; - - CNum numInStreams = 0; - CNum numCoders = inByte->ReadNum(); - - if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) - ThrowUnsupported(); - - for (CNum ci = 0; ci < numCoders; ci++) - { - Byte mainByte = inByte->ReadByte(); - if ((mainByte & 0xC0) != 0) - ThrowUnsupported(); - - unsigned idSize = (mainByte & 0xF); - if (idSize > 8) - ThrowUnsupported(); - if (idSize > inByte->GetRem()) - ThrowEndOfData(); - const Byte *longID = inByte->GetPtr(); - UInt64 id = 0; - for (unsigned j = 0; j < idSize; j++) - id = ((id << 8) | longID[j]); - inByte->SkipDataNoCheck(idSize); - if (folders.ParsedMethods.IDs.Size() < 128) - folders.ParsedMethods.IDs.AddToUniqueSorted(id); - - CNum coderInStreams = 1; - if ((mainByte & 0x10) != 0) - { - coderInStreams = inByte->ReadNum(); - if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) - ThrowUnsupported(); - if (inByte->ReadNum() != 1) - ThrowUnsupported(); - } - - numInStreams += coderInStreams; - if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) - ThrowUnsupported(); - - if ((mainByte & 0x20) != 0) - { - CNum propsSize = inByte->ReadNum(); - if (propsSize > inByte->GetRem()) - ThrowEndOfData(); - if (id == k_LZMA2 && propsSize == 1) - { - Byte v = *_inByteBack->GetPtr(); - if (folders.ParsedMethods.Lzma2Prop < v) - folders.ParsedMethods.Lzma2Prop = v; - } - else if (id == k_LZMA && propsSize == 5) - { - UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); - if (folders.ParsedMethods.LzmaDic < dicSize) - folders.ParsedMethods.LzmaDic = dicSize; - } - inByte->SkipDataNoCheck((size_t)propsSize); - } - } - - if (numCoders == 1 && numInStreams == 1) - { - indexOfMainStream = 0; - numPackStreams = 1; - } - else - { - UInt32 i; - CNum numBonds = numCoders - 1; - if (numInStreams < numBonds) - ThrowUnsupported(); - - BoolVector_Fill_False(StreamUsed, numInStreams); - BoolVector_Fill_False(CoderUsed, numCoders); - - for (i = 0; i < numBonds; i++) - { - CNum index = ReadNum(); - if (index >= numInStreams || StreamUsed[index]) - ThrowUnsupported(); - StreamUsed[index] = true; - - index = ReadNum(); - if (index >= numCoders || CoderUsed[index]) - ThrowUnsupported(); - CoderUsed[index] = true; - } - - numPackStreams = numInStreams - numBonds; - - if (numPackStreams != 1) - for (i = 0; i < numPackStreams; i++) - { - CNum index = inByte->ReadNum(); // PackStreams - if (index >= numInStreams || StreamUsed[index]) - ThrowUnsupported(); - StreamUsed[index] = true; - } - - for (i = 0; i < numCoders; i++) - if (!CoderUsed[i]) - { - indexOfMainStream = i; - break; - } - - if (i == numCoders) - ThrowUnsupported(); - } - - folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; - numCodersOutStreams += numCoders; - folders.FoStartPackStreamIndex[fo] = packStreamIndex; - if (numPackStreams > folders.NumPackStreams - packStreamIndex) - ThrowIncorrect(); - packStreamIndex += numPackStreams; - folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; - } - - size_t dataSize = _inByteBack->GetPtr() - startBufPtr; - folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; - folders.FoStartPackStreamIndex[fo] = packStreamIndex; - folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; - folders.CodersData.CopyFrom(startBufPtr, dataSize); - - // if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported(); - } - - WaitId(NID::kCodersUnpackSize); - folders.CoderUnpackSizes.Alloc(numCodersOutStreams); - for (CNum i = 0; i < numCodersOutStreams; i++) - folders.CoderUnpackSizes[i] = ReadNumber(); - - for (;;) - { - UInt64 type = ReadID(); - if (type == NID::kEnd) - return; - if (type == NID::kCRC) - { - ReadHashDigests(numFolders, folders.FolderCRCs); - continue; - } - SkipData(); - } -} - -void CInArchive::ReadSubStreamsInfo( - CFolders &folders, - CRecordVector &unpackSizes, - CUInt32DefVector &digests) -{ - folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); - CNum i; - for (i = 0; i < folders.NumFolders; i++) - folders.NumUnpackStreamsVector[i] = 1; - - UInt64 type; - - for (;;) - { - type = ReadID(); - if (type == NID::kNumUnpackStream) - { - for (i = 0; i < folders.NumFolders; i++) - folders.NumUnpackStreamsVector[i] = ReadNum(); - continue; - } - if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd) - break; - SkipData(); - } - - if (type == NID::kSize) - { - for (i = 0; i < folders.NumFolders; i++) - { - // v3.13 incorrectly worked with empty folders - // v4.07: we check that folder is empty - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; - if (numSubstreams == 0) - continue; - UInt64 sum = 0; - for (CNum j = 1; j < numSubstreams; j++) - { - UInt64 size = ReadNumber(); - unpackSizes.Add(size); - sum += size; - if (sum < size) - ThrowIncorrect(); - } - UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); - if (folderUnpackSize < sum) - ThrowIncorrect(); - unpackSizes.Add(folderUnpackSize - sum); - } - type = ReadID(); - } - else - { - for (i = 0; i < folders.NumFolders; i++) - { - /* v9.26 - v9.29 incorrectly worked: - if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ - CNum val = folders.NumUnpackStreamsVector[i]; - if (val > 1) - ThrowIncorrect(); - if (val == 1) - unpackSizes.Add(folders.GetFolderUnpackSize(i)); - } - } - - unsigned numDigests = 0; - for (i = 0; i < folders.NumFolders; i++) - { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; - if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) - numDigests += numSubstreams; - } - - for (;;) - { - if (type == NID::kEnd) - break; - if (type == NID::kCRC) - { - // CUInt32DefVector digests2; - // ReadHashDigests(numDigests, digests2); - CBoolVector digests2; - ReadBoolVector2(numDigests, digests2); - - digests.ClearAndSetSize(unpackSizes.Size()); - - unsigned k = 0; - unsigned k2 = 0; - - for (i = 0; i < folders.NumFolders; i++) - { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; - if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) - { - digests.Defs[k] = true; - digests.Vals[k] = folders.FolderCRCs.Vals[i]; - k++; - } - else for (CNum j = 0; j < numSubstreams; j++) - { - bool defined = digests2[k2++]; - digests.Defs[k] = defined; - UInt32 crc = 0; - if (defined) - crc = ReadUInt32(); - digests.Vals[k] = crc; - k++; - } - } - // if (k != unpackSizes.Size()) throw 1234567; - } - else - SkipData(); - - type = ReadID(); - } - - if (digests.Defs.Size() != unpackSizes.Size()) - { - digests.ClearAndSetSize(unpackSizes.Size()); - unsigned k = 0; - for (i = 0; i < folders.NumFolders; i++) - { - CNum numSubstreams = folders.NumUnpackStreamsVector[i]; - if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) - { - digests.Defs[k] = true; - digests.Vals[k] = folders.FolderCRCs.Vals[i]; - k++; - } - else for (CNum j = 0; j < numSubstreams; j++) - { - digests.Defs[k] = false; - digests.Vals[k] = 0; - k++; - } - } - } -} - -void CInArchive::ReadStreamsInfo( - const CObjectVector *dataVector, - UInt64 &dataOffset, - CFolders &folders, - CRecordVector &unpackSizes, - CUInt32DefVector &digests) -{ - UInt64 type = ReadID(); - - if (type == NID::kPackInfo) - { - dataOffset = ReadNumber(); - ReadPackInfo(folders); - type = ReadID(); - } - - if (type == NID::kUnpackInfo) - { - ReadUnpackInfo(dataVector, folders); - type = ReadID(); - } - - if (folders.NumFolders != 0 && !folders.PackPositions) - { - // if there are folders, we need PackPositions also - folders.PackPositions.Alloc(1); - folders.PackPositions[0] = 0; - } - - if (type == NID::kSubStreamsInfo) - { - ReadSubStreamsInfo(folders, unpackSizes, digests); - type = ReadID(); - } - else - { - folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); - /* If digests.Defs.Size() == 0, it means that there are no crcs. - So we don't need to fill digests with values. */ - // digests.Vals.ClearAndSetSize(folders.NumFolders); - // BoolVector_Fill_False(digests.Defs, folders.NumFolders); - for (CNum i = 0; i < folders.NumFolders; i++) - { - folders.NumUnpackStreamsVector[i] = 1; - unpackSizes.Add(folders.GetFolderUnpackSize(i)); - // digests.Vals[i] = 0; - } - } - - if (type != NID::kEnd) - ThrowIncorrect(); -} - -void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v) -{ - v.ClearAndSetSize(numItems); - Byte b = 0; - Byte mask = 0; - bool *p = &v[0]; - for (unsigned i = 0; i < numItems; i++) - { - if (mask == 0) - { - b = ReadByte(); - mask = 0x80; - } - p[i] = ((b & mask) != 0); - mask >>= 1; - } -} - -void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) -{ - Byte allAreDefined = ReadByte(); - if (allAreDefined == 0) - { - ReadBoolVector(numItems, v); - return; - } - v.ClearAndSetSize(numItems); - bool *p = &v[0]; - for (unsigned i = 0; i < numItems; i++) - p[i] = true; -} - -void CInArchive::ReadUInt64DefVector(const CObjectVector &dataVector, - CUInt64DefVector &v, unsigned numItems) -{ - ReadBoolVector2(numItems, v.Defs); - - CStreamSwitch streamSwitch; - streamSwitch.Set(this, &dataVector); - - v.Vals.ClearAndSetSize(numItems); - UInt64 *p = &v.Vals[0]; - const bool *defs = &v.Defs[0]; - - for (unsigned i = 0; i < numItems; i++) - { - UInt64 t = 0; - if (defs[i]) - t = ReadUInt64(); - p[i] = t; - } -} - -HRESULT CInArchive::ReadAndDecodePackedStreams( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 baseOffset, - UInt64 &dataOffset, CObjectVector &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL - ) -{ - CFolders folders; - CRecordVector unpackSizes; - CUInt32DefVector digests; - - ReadStreamsInfo(NULL, - dataOffset, - folders, - unpackSizes, - digests); - - CDecoder decoder(_useMixerMT); - - for (CNum i = 0; i < folders.NumFolders; i++) - { - CByteBuffer &data = dataVector.AddNew(); - UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); - size_t unpackSize = (size_t)unpackSize64; - if (unpackSize != unpackSize64) - ThrowUnsupported(); - data.Alloc(unpackSize); - - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream = outStreamSpec; - outStreamSpec->Init(data, unpackSize); - - HRESULT result = decoder.Decode( - EXTERNAL_CODECS_LOC_VARS - _stream, baseOffset + dataOffset, - folders, i, - NULL, // *unpackSize - - outStream, - NULL, // *compressProgress - NULL // **inStreamMainRes - - _7Z_DECODER_CRYPRO_VARS - #if !defined(_7ZIP_ST) && !defined(_SFX) - , false // mtMode - , 1 // numThreads - #endif - ); - RINOK(result); - - if (folders.FolderCRCs.ValidAndDefined(i)) - if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) - ThrowIncorrect(); - } - HeadersSize += folders.PackPositions[folders.NumPackStreams]; - return S_OK; -} - -HRESULT CInArchive::ReadHeader( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ) -{ - UInt64 type = ReadID(); - - if (type == NID::kArchiveProperties) - { - ReadArchiveProperties(db.ArcInfo); - type = ReadID(); - } - - CObjectVector dataVector; - - if (type == NID::kAdditionalStreamsInfo) - { - HRESULT result = ReadAndDecodePackedStreams( - EXTERNAL_CODECS_LOC_VARS - db.ArcInfo.StartPositionAfterHeader, - db.ArcInfo.DataStartPosition2, - dataVector - _7Z_DECODER_CRYPRO_VARS - ); - RINOK(result); - db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; - type = ReadID(); - } - - CRecordVector unpackSizes; - CUInt32DefVector digests; - - if (type == NID::kMainStreamsInfo) - { - ReadStreamsInfo(&dataVector, - db.ArcInfo.DataStartPosition, - (CFolders &)db, - unpackSizes, - digests); - db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader; - type = ReadID(); - } - - db.Files.Clear(); - - if (type == NID::kFilesInfo) - { - - const CNum numFiles = ReadNum(); - db.Files.ClearAndSetSize(numFiles); - /* - db.Files.Reserve(numFiles); - CNum i; - for (i = 0; i < numFiles; i++) - db.Files.Add(CFileItem()); - */ - - db.ArcInfo.FileInfoPopIDs.Add(NID::kSize); - // if (!db.PackSizes.IsEmpty()) - db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo); - if (numFiles > 0 && !digests.Defs.IsEmpty()) - db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC); - - CBoolVector emptyStreamVector; - BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles); - CBoolVector emptyFileVector; - CBoolVector antiFileVector; - CNum numEmptyStreams = 0; - - for (;;) - { - const UInt64 type2 = ReadID(); - if (type2 == NID::kEnd) - break; - UInt64 size = ReadNumber(); - if (size > _inByteBack->GetRem()) - ThrowIncorrect(); - CStreamSwitch switchProp; - switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true); - bool addPropIdToList = true; - bool isKnownType = true; - if (type2 > ((UInt32)1 << 30)) - isKnownType = false; - else switch ((UInt32)type2) - { - case NID::kName: - { - CStreamSwitch streamSwitch; - streamSwitch.Set(this, &dataVector); - size_t rem = _inByteBack->GetRem(); - db.NamesBuf.Alloc(rem); - ReadBytes(db.NamesBuf, rem); - db.NameOffsets.Alloc(db.Files.Size() + 1); - size_t pos = 0; - unsigned i; - for (i = 0; i < db.Files.Size(); i++) - { - size_t curRem = (rem - pos) / 2; - const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos); - size_t j; - for (j = 0; j < curRem && buf[j] != 0; j++); - if (j == curRem) - ThrowEndOfData(); - db.NameOffsets[i] = pos / 2; - pos += j * 2 + 2; - } - db.NameOffsets[i] = pos / 2; - if (pos != rem) - ThereIsHeaderError = true; - break; - } - case NID::kWinAttrib: - { - CBoolVector boolVector; - ReadBoolVector2(db.Files.Size(), boolVector); - CStreamSwitch streamSwitch; - streamSwitch.Set(this, &dataVector); - for (CNum i = 0; i < numFiles; i++) - { - CFileItem &file = db.Files[i]; - file.AttribDefined = boolVector[i]; - if (file.AttribDefined) - file.Attrib = ReadUInt32(); - } - break; - } - /* - case NID::kIsAux: - { - ReadBoolVector(db.Files.Size(), db.IsAux); - break; - } - case NID::kParent: - { - db.IsTree = true; - // CBoolVector boolVector; - // ReadBoolVector2(db.Files.Size(), boolVector); - // CStreamSwitch streamSwitch; - // streamSwitch.Set(this, &dataVector); - CBoolVector boolVector; - ReadBoolVector2(db.Files.Size(), boolVector); - - db.ThereAreAltStreams = false; - for (i = 0; i < numFiles; i++) - { - CFileItem &file = db.Files[i]; - // file.Parent = -1; - // if (boolVector[i]) - file.Parent = (int)ReadUInt32(); - file.IsAltStream = !boolVector[i]; - if (file.IsAltStream) - db.ThereAreAltStreams = true; - } - break; - } - */ - case NID::kEmptyStream: - { - ReadBoolVector(numFiles, emptyStreamVector); - numEmptyStreams = 0; - for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++) - if (emptyStreamVector[i]) - numEmptyStreams++; - - BoolVector_Fill_False(emptyFileVector, numEmptyStreams); - BoolVector_Fill_False(antiFileVector, numEmptyStreams); - - break; - } - case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; - case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; - case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break; - case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break; - case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break; - case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break; - case NID::kDummy: - { - for (UInt64 j = 0; j < size; j++) - if (ReadByte() != 0) - ThereIsHeaderError = true; - addPropIdToList = false; - break; - } - /* - case NID::kNtSecure: - { - try - { - { - CStreamSwitch streamSwitch; - streamSwitch.Set(this, &dataVector); - UInt32 numDescriptors = ReadUInt32(); - size_t offset = 0; - db.SecureOffsets.Clear(); - for (i = 0; i < numDescriptors; i++) - { - UInt32 size = ReadUInt32(); - db.SecureOffsets.Add(offset); - offset += size; - } - // ThrowIncorrect();; - db.SecureOffsets.Add(offset); - db.SecureBuf.SetCapacity(offset); - for (i = 0; i < numDescriptors; i++) - { - offset = db.SecureOffsets[i]; - ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset); - } - db.SecureIDs.Clear(); - for (unsigned i = 0; i < db.Files.Size(); i++) - { - db.SecureIDs.Add(ReadNum()); - // db.SecureIDs.Add(ReadUInt32()); - } - // ReadUInt32(); - if (_inByteBack->GetRem() != 0) - ThrowIncorrect();; - } - } - catch(CInArchiveException &) - { - ThereIsHeaderError = true; - addPropIdToList = isKnownType = false; - db.ClearSecure(); - } - break; - } - */ - default: - addPropIdToList = isKnownType = false; - } - if (isKnownType) - { - if (addPropIdToList) - db.ArcInfo.FileInfoPopIDs.Add(type2); - } - else - { - db.UnsupportedFeatureWarning = true; - _inByteBack->SkipRem(); - } - // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02) - if (_inByteBack->GetRem() != 0) - ThrowIncorrect(); - } - - type = ReadID(); // Read (NID::kEnd) end of headers - - if (numFiles - numEmptyStreams != unpackSizes.Size()) - ThrowUnsupported(); - - CNum emptyFileIndex = 0; - CNum sizeIndex = 0; - - CNum numAntiItems = 0; - - CNum i; - - for (i = 0; i < numEmptyStreams; i++) - if (antiFileVector[i]) - numAntiItems++; - - for (i = 0; i < numFiles; i++) - { - CFileItem &file = db.Files[i]; - bool isAnti; - file.HasStream = !emptyStreamVector[i]; - file.Crc = 0; - if (file.HasStream) - { - file.IsDir = false; - isAnti = false; - file.Size = unpackSizes[sizeIndex]; - file.CrcDefined = digests.ValidAndDefined(sizeIndex); - if (file.CrcDefined) - file.Crc = digests.Vals[sizeIndex]; - sizeIndex++; - } - else - { - file.IsDir = !emptyFileVector[emptyFileIndex]; - isAnti = antiFileVector[emptyFileIndex]; - emptyFileIndex++; - file.Size = 0; - file.CrcDefined = false; - } - if (numAntiItems != 0) - db.IsAnti.Add(isAnti); - } - } - db.FillLinks(); - /* - if (type != NID::kEnd) - ThrowIncorrect(); - if (_inByteBack->GetRem() != 0) - ThrowIncorrect(); - */ - return S_OK; -} - -void CDbEx::FillLinks() -{ - FolderStartFileIndex.Alloc(NumFolders); - FileIndexToFolderIndexMap.Alloc(Files.Size()); - - CNum folderIndex = 0; - CNum indexInFolder = 0; - unsigned i; - - for (i = 0; i < Files.Size(); i++) - { - bool emptyStream = !Files[i].HasStream; - if (indexInFolder == 0) - { - if (emptyStream) - { - FileIndexToFolderIndexMap[i] = kNumNoIndex; - continue; - } - // v3.13 incorrectly worked with empty folders - // v4.07: we skip empty folders - for (;;) - { - if (folderIndex >= NumFolders) - ThrowIncorrect(); - FolderStartFileIndex[folderIndex] = i; - if (NumUnpackStreamsVector[folderIndex] != 0) - break; - folderIndex++; - } - } - FileIndexToFolderIndexMap[i] = folderIndex; - if (emptyStream) - continue; - if (++indexInFolder >= NumUnpackStreamsVector[folderIndex]) - { - folderIndex++; - indexInFolder = 0; - } - } - - if (indexInFolder != 0) - folderIndex++; - /* - if (indexInFolder != 0) - ThrowIncorrect(); - */ - - for (;;) - { - if (folderIndex >= NumFolders) - return; - FolderStartFileIndex[folderIndex] = i; - /* - if (NumUnpackStreamsVector[folderIndex] != 0) - ThrowIncorrect();; - */ - folderIndex++; - } -} - -HRESULT CInArchive::ReadDatabase2( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ) -{ - db.Clear(); - db.ArcInfo.StartPosition = _arhiveBeginStreamPosition; - - db.ArcInfo.Version.Major = _header[6]; - db.ArcInfo.Version.Minor = _header[7]; - - if (db.ArcInfo.Version.Major != kMajorVersion) - { - // db.UnsupportedVersion = true; - return S_FALSE; - } - - UInt64 nextHeaderOffset = Get64(_header + 12); - UInt64 nextHeaderSize = Get64(_header + 20); - UInt32 nextHeaderCRC = Get32(_header + 28); - - #ifdef FORMAT_7Z_RECOVERY - UInt32 crcFromArc = Get32(_header + 8); - if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) - { - UInt64 cur, fileSize; - RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); - const unsigned kCheckSize = 512; - Byte buf[kCheckSize]; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); - UInt64 rem = fileSize - cur; - unsigned checkSize = kCheckSize; - if (rem < kCheckSize) - checkSize = (unsigned)(rem); - if (checkSize < 3) - return S_FALSE; - RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); - - if (buf[checkSize - 1] != 0) - return S_FALSE; - - unsigned i; - for (i = checkSize - 2;; i--) - { - if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo || - buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo) - break; - if (i == 0) - return S_FALSE; - } - nextHeaderSize = checkSize - i; - nextHeaderOffset = rem - nextHeaderSize; - nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); - RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); - db.StartHeaderWasRecovered = true; - } - else - #endif - { - // Crc was tested already at signature check - // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect(); - } - - db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; - db.PhySize = kHeaderSize; - - db.IsArc = false; - if ((Int64)nextHeaderOffset < 0 || - nextHeaderSize > ((UInt64)1 << 62)) - return S_FALSE; - if (nextHeaderSize == 0) - { - if (nextHeaderOffset != 0) - return S_FALSE; - db.IsArc = true; - return S_OK; - } - - if (!db.StartHeaderWasRecovered) - db.IsArc = true; - - HeadersSize += kHeaderSize + nextHeaderSize; - db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; - if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize) - { - db.UnexpectedEnd = true; - return S_FALSE; - } - RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); - - size_t nextHeaderSize_t = (size_t)nextHeaderSize; - if (nextHeaderSize_t != nextHeaderSize) - return E_OUTOFMEMORY; - CByteBuffer buffer2(nextHeaderSize_t); - - RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)); - - if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) - ThrowIncorrect(); - - if (!db.StartHeaderWasRecovered) - db.PhySizeWasConfirmed = true; - - CStreamSwitch streamSwitch; - streamSwitch.Set(this, buffer2); - - CObjectVector dataVector; - - UInt64 type = ReadID(); - if (type != NID::kHeader) - { - if (type != NID::kEncodedHeader) - ThrowIncorrect(); - HRESULT result = ReadAndDecodePackedStreams( - EXTERNAL_CODECS_LOC_VARS - db.ArcInfo.StartPositionAfterHeader, - db.ArcInfo.DataStartPosition2, - dataVector - _7Z_DECODER_CRYPRO_VARS - ); - RINOK(result); - if (dataVector.Size() == 0) - return S_OK; - if (dataVector.Size() > 1) - ThrowIncorrect(); - streamSwitch.Remove(); - streamSwitch.Set(this, dataVector.Front()); - if (ReadID() != NID::kHeader) - ThrowIncorrect(); - } - - db.IsArc = true; - - db.HeadersSize = HeadersSize; - - return ReadHeader( - EXTERNAL_CODECS_LOC_VARS - db - _7Z_DECODER_CRYPRO_VARS - ); -} - -HRESULT CInArchive::ReadDatabase( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ) -{ - try - { - HRESULT res = ReadDatabase2( - EXTERNAL_CODECS_LOC_VARS db - _7Z_DECODER_CRYPRO_VARS - ); - if (ThereIsHeaderError) - db.ThereIsHeaderError = true; - if (res == E_NOTIMPL) - ThrowUnsupported(); - return res; - } - catch(CUnsupportedFeatureException &) - { - db.UnsupportedFeatureError = true; - return S_FALSE; - } - catch(CInArchiveException &) - { - db.ThereIsHeaderError = true; - return S_FALSE; - } -} - -}} +// 7zIn.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyBuffer2.h" +// #include "../../../Common/UTFConvert.h" + +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "7zDecode.h" +#include "7zIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader +#ifndef Z7_SFX +#define FORMAT_7Z_RECOVERY +#endif + +using namespace NWindows; +using namespace NCOM; + +unsigned BoolVector_CountSum(const CBoolVector &v); +Z7_NO_INLINE +unsigned BoolVector_CountSum(const CBoolVector &v) +{ + unsigned sum = 0; + const unsigned size = v.Size(); + if (size) + { + const bool *p = v.ConstData(); + const bool * const lim = p + size; + do + if (*p) + sum++; + while (++p != lim); + } + return sum; +} + +static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i) +{ + return i < v.Size() ? v[i] : false; +} + +Z7_NO_INLINE +static void BoolVector_Fill_False(CBoolVector &v, unsigned size) +{ + v.ClearAndSetSize(size); + bool *p = v.NonConstData(); + for (unsigned i = 0; i < size; i++) + p[i] = false; +} + + +namespace NArchive { +namespace N7z { + +#define k_Scan_NumCoders_MAX 64 +#define k_Scan_NumCodersStreams_in_Folder_MAX 64 + +class CInArchiveException {}; +class CUnsupportedFeatureException: public CInArchiveException {}; + +Z7_ATTR_NORETURN +static void ThrowException() { throw CInArchiveException(); } +Z7_ATTR_NORETURN +static inline void ThrowEndOfData() { ThrowException(); } +Z7_ATTR_NORETURN +static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } +Z7_ATTR_NORETURN +static inline void ThrowIncorrect() { ThrowException(); } + +class CStreamSwitch +{ + CInArchive *_archive; + bool _needRemove; + bool _needUpdatePos; +public: + CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {} + ~CStreamSwitch() { Remove(); } + void Remove(); + void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos); + void Set(CInArchive *archive, const CByteBuffer &byteBuffer); + void Set(CInArchive *archive, const CObjectVector *dataVector); +}; + +void CStreamSwitch::Remove() +{ + if (_needRemove) + { + if (_archive->_inByteBack->GetRem() != 0) + _archive->ThereIsHeaderError = true; + _archive->DeleteByteStream(_needUpdatePos); + _needRemove = false; + } +} + +void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos) +{ + Remove(); + _archive = archive; + _archive->AddByteStream(data, size); + _needRemove = true; + _needUpdatePos = needUpdatePos; +} + +void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) +{ + Set(archive, byteBuffer, byteBuffer.Size(), false); +} + +void CStreamSwitch::Set(CInArchive *archive, const CObjectVector *dataVector) +{ + Remove(); + const Byte external = archive->ReadByte(); + if (external != 0) + { + if (!dataVector) + ThrowIncorrect(); + const CNum dataIndex = archive->ReadNum(); + if (dataIndex >= dataVector->Size()) + ThrowIncorrect(); + Set(archive, (*dataVector)[dataIndex]); + } +} + +void CInArchive::AddByteStream(const Byte *buf, size_t size) +{ + if (_numInByteBufs == kNumBufLevelsMax) + ThrowIncorrect(); + _inByteBack = &_inByteVector[_numInByteBufs++]; + _inByteBack->Init(buf, size); +} + + +Byte CInByte2::ReadByte() +{ + if (_pos >= _size) + ThrowEndOfData(); + return _buffer[_pos++]; +} + +void CInByte2::ReadBytes(Byte *data, size_t size) +{ + if (size == 0) + return; + if (size > _size - _pos) + ThrowEndOfData(); + memcpy(data, _buffer + _pos, size); + _pos += size; +} + +void CInByte2::SkipData(UInt64 size) +{ + if (size > _size - _pos) + ThrowEndOfData(); + _pos += (size_t)size; +} + +void CInByte2::SkipData() +{ + SkipData(ReadNumber()); +} + +static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) +{ + if (size == 0) + { + processed = 0; + return 0; + } + + const unsigned b = *p++; + size--; + + if ((b & 0x80) == 0) + { + processed = 1; + return b; + } + + if (size == 0) + { + processed = 0; + return 0; + } + + UInt64 value = (UInt64)*p; + p++; + size--; + + for (unsigned i = 1; i < 8; i++) + { + const unsigned mask = (unsigned)0x80 >> i; + if ((b & mask) == 0) + { + const UInt64 high = b & (mask - 1); + value |= (high << (i * 8)); + processed = i + 1; + return value; + } + + if (size == 0) + { + processed = 0; + return 0; + } + + value |= ((UInt64)*p << (i * 8)); + p++; + size--; + } + + processed = 9; + return value; +} + +UInt64 CInByte2::ReadNumber() +{ + size_t processed; + const UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); + if (processed == 0) + ThrowEndOfData(); + _pos += processed; + return res; +} + +CNum CInByte2::ReadNum() +{ + /* + if (_pos < _size) + { + Byte val = _buffer[_pos]; + if ((unsigned)val < 0x80) + { + _pos++; + return (unsigned)val; + } + } + */ + const UInt64 value = ReadNumber(); + if (value > kNumMax) + ThrowUnsupported(); + return (CNum)value; +} + +UInt32 CInByte2::ReadUInt32() +{ + if (_pos + 4 > _size) + ThrowEndOfData(); + const UInt32 res = Get32(_buffer + _pos); + _pos += 4; + return res; +} + +UInt64 CInByte2::ReadUInt64() +{ + if (_pos + 8 > _size) + ThrowEndOfData(); + const UInt64 res = Get64(_buffer + _pos); + _pos += 8; + return res; +} + +#define Y0 '7' +#define Y1 'z' +#define Y2 0xBC +#define Y3 0xAF +#define Y4 0x27 +#define Y5 0x1C + +#define IS_SIGNATURE(p)( \ + (p)[2] == Y2 && \ + (p)[3] == Y3 && \ + (p)[5] == Y5 && \ + (p)[4] == Y4 && \ + (p)[1] == Y1 && \ + (p)[0] == Y0) + +/* FindSignature_10() is allowed to access data up to and including &limit[9]. + limit[10] access is not allowed. + return: + (return_ptr < limit) : signature was found at (return_ptr) + (return_ptr >= limit) : limit was reached or crossed. So no signature found before limit +*/ +Z7_NO_INLINE +static const Byte *FindSignature_10(const Byte *p, const Byte *limit) +{ + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + const Byte b = p[5]; + p += 6; + if (b == Y0) { break; } + if (b == Y1) { p -= 1; break; } + if (b == Y2) { p -= 2; break; } + if (b == Y3) { p -= 3; break; } + if (b == Y4) { p -= 4; break; } + if (b == Y5) { p -= 5; break; } + } + if (IS_SIGNATURE(p - 1)) + return p - 1; + } +} + + +static inline bool TestStartCrc(const Byte *p) +{ + return CrcCalc(p + 12, 20) == Get32(p + 8); +} + +static inline bool TestSignature2(const Byte *p) +{ + if (!IS_SIGNATURE(p)) + return false; + #ifdef FORMAT_7Z_RECOVERY + if (TestStartCrc(p)) + return true; + for (unsigned i = 8; i < kHeaderSize; i++) + if (p[i] != 0) + return false; + return (p[6] != 0 || p[7] != 0); + #else + return TestStartCrc(p); + #endif +} + + +HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)) + + if (TestSignature2(_header)) + return S_OK; + if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) + return S_FALSE; + + const UInt32 kBufSize = (1 << 15) + kHeaderSize; // must be > (kHeaderSize * 2) + CAlignedBuffer1 buf(kBufSize); + memcpy(buf, _header, kHeaderSize); + UInt64 offset = 0; + + for (;;) + { + UInt32 readSize = + (offset == 0) ? + kBufSize - kHeaderSize - kHeaderSize : + kBufSize - kHeaderSize; + if (searchHeaderSizeLimit) + { + const UInt64 rem = *searchHeaderSizeLimit - offset; + if (readSize > rem) + readSize = (UInt32)rem; + if (readSize == 0) + return S_FALSE; + } + + UInt32 processed = 0; + RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)) + if (processed == 0) + return S_FALSE; + + /* &buf[0] was already tested for signature before. + So first search here will be for &buf[1] */ + + for (UInt32 pos = 0;;) + { + const Byte *p = buf + pos + 1; + const Byte *lim = buf + processed + 1; + /* we have (kHeaderSize - 1 = 31) filled bytes starting from (lim), + and it's safe to access just 10 bytes in that reserved area */ + p = FindSignature_10(p, lim); + if (p >= lim) + break; + pos = (UInt32)(p - buf); + if (TestStartCrc(p)) + { + memcpy(_header, p, kHeaderSize); + _arhiveBeginStreamPosition += offset + pos; + return InStream_SeekSet(stream, _arhiveBeginStreamPosition + kHeaderSize); + } + } + + offset += processed; + memmove(buf, buf + processed, kHeaderSize); + } +} + +// S_FALSE means that file is not archive +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + HeadersSize = 0; + Close(); + RINOK(InStream_GetPos_GetSize(stream, _arhiveBeginStreamPosition, _fileEndPosition)) + RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)) + _stream = stream; + return S_OK; +} + +void CInArchive::Close() +{ + _numInByteBufs = 0; + _stream.Release(); + ThereIsHeaderError = false; +} + +void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) +{ + for (;;) + { + if (ReadID() == NID::kEnd) + break; + SkipData(); + } +} + +// CFolder &folder can be non empty. So we must set all fields + +void CInByte2::ParseFolder(CFolder &folder) +{ + const UInt32 numCoders = ReadNum(); + + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) + ThrowUnsupported(); + + folder.Coders.SetSize(numCoders); + + UInt32 numInStreams = 0; + UInt32 i; + for (i = 0; i < numCoders; i++) + { + CCoderInfo &coder = folder.Coders[i]; + { + const Byte mainByte = ReadByte(); + if ((mainByte & 0xC0) != 0) + ThrowUnsupported(); + const unsigned idSize = (mainByte & 0xF); + if (idSize > 8 || idSize > GetRem()) + ThrowUnsupported(); + const Byte *longID = GetPtr(); + UInt64 id = 0; + for (unsigned j = 0; j < idSize; j++) + id = ((id << 8) | longID[j]); + SkipDataNoCheck(idSize); + coder.MethodID = id; + + if ((mainByte & 0x10) != 0) + { + coder.NumStreams = ReadNum(); + // if (coder.NumStreams > k_Scan_NumCodersStreams_in_Folder_MAX) ThrowUnsupported(); + /* numOutStreams = */ ReadNum(); + // if (ReadNum() != 1) // numOutStreams ThrowUnsupported(); + } + else + { + coder.NumStreams = 1; + } + + if ((mainByte & 0x20) != 0) + { + const CNum propsSize = ReadNum(); + coder.Props.Alloc((size_t)propsSize); + ReadBytes((Byte *)coder.Props, (size_t)propsSize); + } + else + coder.Props.Free(); + } + numInStreams += coder.NumStreams; + } + + const UInt32 numBonds = numCoders - 1; + folder.Bonds.SetSize(numBonds); + for (i = 0; i < numBonds; i++) + { + CBond &bp = folder.Bonds[i]; + bp.PackIndex = ReadNum(); + bp.UnpackIndex = ReadNum(); + } + + if (numInStreams < numBonds) + ThrowUnsupported(); + const UInt32 numPackStreams = numInStreams - numBonds; + folder.PackStreams.SetSize(numPackStreams); + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams; i++) + if (folder.FindBond_for_PackStream(i) < 0) + { + folder.PackStreams[0] = i; + break; + } + if (i == numInStreams) + ThrowUnsupported(); + } + else + for (i = 0; i < numPackStreams; i++) + folder.PackStreams[i] = ReadNum(); +} + +void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const +{ + const size_t startPos = FoCodersDataOffset[folderIndex]; + CInByte2 inByte; + inByte.Init(CodersData.ConstData() + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); + inByte.ParseFolder(folder); + if (inByte.GetRem() != 0) + throw 20120424; +} + + +void CDatabase::GetPath(unsigned index, UString &path) const +{ + path.Empty(); + if (!NameOffsets || !NamesBuf) + return; + + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; + + if (size >= (1 << 28)) + return; + + wchar_t *s = path.GetBuf((unsigned)size - 1); + + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + + #if defined(_WIN32) && defined(MY_CPU_LE) + + wmemcpy(s, (const wchar_t *)(const void *)p, size); + + #else + + for (size_t i = 0; i < size; i++) + { + *s = Get16(p); + p += 2; + s++; + } + + #endif + + path.ReleaseBuf_SetLen((unsigned)size - 1); +} + +HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() +{ + PropVariant_Clear(path); + if (!NameOffsets || !NamesBuf) + return S_OK; + + const size_t offset = NameOffsets[index]; + const size_t size = NameOffsets[index + 1] - offset; + + if (size >= (1 << 14)) + return S_OK; + + // (size) includes null terminator + + /* + #if WCHAR_MAX > 0xffff + + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + size = Utf16LE__Get_Num_WCHARs(p, size - 1); + // (size) doesn't include null terminator + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size)); + wchar_t *s = path->bstrVal; + wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, size, s); + *sEnd = 0; + if (s + size != sEnd) return E_FAIL; + + #else + */ + + RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)) + wchar_t *s = path->bstrVal; + const Byte *p = ((const Byte *)NamesBuf + offset * 2); + // Utf16LE__To_WCHARs_Sep(p, size, s); + + for (size_t i = 0; i < size; i++) + { + wchar_t c = Get16(p); + p += 2; + #if WCHAR_PATH_SEPARATOR != L'/' + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + #endif + *s++ = c; + } + + // #endif + + return S_OK; + + /* + unsigned cur = index; + unsigned size = 0; + + for (int i = 0;; i++) + { + size_t len = NameOffsets[cur + 1] - NameOffsets[cur]; + size += (unsigned)len; + if (i > 256 || len > (1 << 14) || size > (1 << 14)) + return PropVarEm_Set_Str(path, "[TOO-LONG]"); + cur = Files[cur].Parent; + if (cur < 0) + break; + } + size--; + + RINOK(PropVarEm_Alloc_Bstr(path, size)); + wchar_t *s = path->bstrVal; + s += size; + *s = 0; + cur = index; + + for (;;) + { + unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1); + const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2; + for (; len != 0; len--) + { + p -= 2; + --s; + wchar_t c = Get16(p); + if (c == '/') + c = WCHAR_PATH_SEPARATOR; + *s = c; + } + + const CFileItem &file = Files[cur]; + cur = file.Parent; + if (cur < 0) + return S_OK; + *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR); + } + */ +} + +void CInArchive::WaitId(UInt64 id) +{ + for (;;) + { + const UInt64 type = ReadID(); + if (type == id) + return; + if (type == NID::kEnd) + ThrowIncorrect(); + SkipData(); + } +} + + +void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v) +{ + const unsigned numItems = v.Defs.Size(); + v.Vals.ClearAndSetSize(numItems); + UInt32 *p = &v.Vals[0]; + const bool *defs = &v.Defs[0]; + for (unsigned i = 0; i < numItems; i++) + { + UInt32 a = 0; + if (defs[i]) + a = ReadUInt32(); + p[i] = a; + } +} + + +void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) +{ + ReadBoolVector2(numItems, crcs.Defs); + Read_UInt32_Vector(crcs); +} + + +void CInArchive::ReadPackInfo(CFolders &f) +{ + const CNum numPackStreams = ReadNum(); + + WaitId(NID::kSize); + f.PackPositions.Alloc(numPackStreams + 1); + f.NumPackStreams = numPackStreams; + UInt64 sum = 0; + for (CNum i = 0; i < numPackStreams; i++) + { + f.PackPositions[i] = sum; + const UInt64 packSize = ReadNumber(); + sum += packSize; + if (sum < packSize) + ThrowIncorrect(); + } + f.PackPositions[numPackStreams] = sum; + + UInt64 type; + for (;;) + { + type = ReadID(); + if (type == NID::kEnd) + return; + if (type == NID::kCRC) + { + CUInt32DefVector PackCRCs; + ReadHashDigests(numPackStreams, PackCRCs); + continue; + } + SkipData(); + } +} + +void CInArchive::ReadUnpackInfo( + const CObjectVector *dataVector, + CFolders &folders) +{ + WaitId(NID::kFolder); + const CNum numFolders = ReadNum(); + + CNum numCodersOutStreams = 0; + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, dataVector); + const Byte *startBufPtr = _inByteBack->GetPtr(); + folders.NumFolders = numFolders; + + folders.FoStartPackStreamIndex.Alloc(numFolders + 1); + folders.FoToMainUnpackSizeIndex.Alloc(numFolders); + folders.FoCodersDataOffset.Alloc(numFolders + 1); + folders.FoToCoderUnpackSizes.Alloc(numFolders + 1); + + CBoolVector StreamUsed; + CBoolVector CoderUsed; + + CNum packStreamIndex = 0; + CNum fo; + CInByte2 *inByte = _inByteBack; + + for (fo = 0; fo < numFolders; fo++) + { + UInt32 indexOfMainStream = 0; + UInt32 numPackStreams = 0; + folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr); + + CNum numInStreams = 0; + const CNum numCoders = inByte->ReadNum(); + + if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) + ThrowUnsupported(); + + for (CNum ci = 0; ci < numCoders; ci++) + { + const Byte mainByte = inByte->ReadByte(); + if ((mainByte & 0xC0) != 0) + ThrowUnsupported(); + + const unsigned idSize = (mainByte & 0xF); + if (idSize > 8) + ThrowUnsupported(); + if (idSize > inByte->GetRem()) + ThrowEndOfData(); + const Byte *longID = inByte->GetPtr(); + UInt64 id = 0; + for (unsigned j = 0; j < idSize; j++) + id = ((id << 8) | longID[j]); + inByte->SkipDataNoCheck(idSize); + if (folders.ParsedMethods.IDs.Size() < 128) + folders.ParsedMethods.IDs.AddToUniqueSorted(id); + + CNum coderInStreams = 1; + if ((mainByte & 0x10) != 0) + { + coderInStreams = inByte->ReadNum(); + if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) + ThrowUnsupported(); + if (inByte->ReadNum() != 1) + ThrowUnsupported(); + } + + numInStreams += coderInStreams; + if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) + ThrowUnsupported(); + + if ((mainByte & 0x20) != 0) + { + const CNum propsSize = inByte->ReadNum(); + if (propsSize > inByte->GetRem()) + ThrowEndOfData(); + if (id == k_LZMA2 && propsSize == 1) + { + const Byte v = *_inByteBack->GetPtr(); + if (folders.ParsedMethods.Lzma2Prop < v) + folders.ParsedMethods.Lzma2Prop = v; + } + else if (id == k_LZMA && propsSize == 5) + { + const UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); + if (folders.ParsedMethods.LzmaDic < dicSize) + folders.ParsedMethods.LzmaDic = dicSize; + } + inByte->SkipDataNoCheck((size_t)propsSize); + } + } + + if (numCoders == 1 && numInStreams == 1) + { + indexOfMainStream = 0; + numPackStreams = 1; + } + else + { + UInt32 i; + const CNum numBonds = numCoders - 1; + if (numInStreams < numBonds) + ThrowUnsupported(); + + BoolVector_Fill_False(StreamUsed, numInStreams); + BoolVector_Fill_False(CoderUsed, numCoders); + + for (i = 0; i < numBonds; i++) + { + CNum index = ReadNum(); + if (index >= numInStreams || StreamUsed[index]) + ThrowUnsupported(); + StreamUsed[index] = true; + + index = ReadNum(); + if (index >= numCoders || CoderUsed[index]) + ThrowUnsupported(); + CoderUsed[index] = true; + } + + numPackStreams = numInStreams - numBonds; + + if (numPackStreams != 1) + for (i = 0; i < numPackStreams; i++) + { + const CNum index = inByte->ReadNum(); // PackStreams + if (index >= numInStreams || StreamUsed[index]) + ThrowUnsupported(); + StreamUsed[index] = true; + } + + for (i = 0; i < numCoders; i++) + if (!CoderUsed[i]) + { + indexOfMainStream = i; + break; + } + + if (i == numCoders) + ThrowUnsupported(); + } + + folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; + numCodersOutStreams += numCoders; + folders.FoStartPackStreamIndex[fo] = packStreamIndex; + if (numPackStreams > folders.NumPackStreams - packStreamIndex) + ThrowIncorrect(); + packStreamIndex += numPackStreams; + folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; + } + + const size_t dataSize = (size_t)(_inByteBack->GetPtr() - startBufPtr); + folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; + folders.FoStartPackStreamIndex[fo] = packStreamIndex; + folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr); + folders.CodersData.CopyFrom(startBufPtr, dataSize); + + // if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported(); + } + + WaitId(NID::kCodersUnpackSize); + folders.CoderUnpackSizes.Alloc(numCodersOutStreams); + for (CNum i = 0; i < numCodersOutStreams; i++) + folders.CoderUnpackSizes[i] = ReadNumber(); + + for (;;) + { + const UInt64 type = ReadID(); + if (type == NID::kEnd) + return; + if (type == NID::kCRC) + { + ReadHashDigests(numFolders, folders.FolderCRCs); + continue; + } + SkipData(); + } +} + +void CInArchive::ReadSubStreamsInfo( + CFolders &folders, + CRecordVector &unpackSizes, + CUInt32DefVector &digests) +{ + folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); + CNum i; + for (i = 0; i < folders.NumFolders; i++) + folders.NumUnpackStreamsVector[i] = 1; + + UInt64 type; + + for (;;) + { + type = ReadID(); + if (type == NID::kNumUnpackStream) + { + for (i = 0; i < folders.NumFolders; i++) + folders.NumUnpackStreamsVector[i] = ReadNum(); + continue; + } + if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd) + break; + SkipData(); + } + + if (type == NID::kSize) + { + for (i = 0; i < folders.NumFolders; i++) + { + // v3.13 incorrectly worked with empty folders + // v4.07: we check that folder is empty + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 0) + continue; + UInt64 sum = 0; + for (CNum j = 1; j < numSubstreams; j++) + { + const UInt64 size = ReadNumber(); + unpackSizes.Add(size); + sum += size; + if (sum < size) + ThrowIncorrect(); + } + const UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); + if (folderUnpackSize < sum) + ThrowIncorrect(); + unpackSizes.Add(folderUnpackSize - sum); + } + type = ReadID(); + } + else + { + for (i = 0; i < folders.NumFolders; i++) + { + /* v9.26 - v9.29 incorrectly worked: + if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ + const CNum val = folders.NumUnpackStreamsVector[i]; + if (val > 1) + ThrowIncorrect(); + if (val == 1) + unpackSizes.Add(folders.GetFolderUnpackSize(i)); + } + } + + unsigned numDigests = 0; + for (i = 0; i < folders.NumFolders; i++) + { + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) + numDigests += numSubstreams; + } + + for (;;) + { + if (type == NID::kEnd) + break; + if (type == NID::kCRC) + { + // CUInt32DefVector digests2; + // ReadHashDigests(numDigests, digests2); + CBoolVector digests2; + ReadBoolVector2(numDigests, digests2); + + digests.ClearAndSetSize(unpackSizes.Size()); + + unsigned k = 0; + unsigned k2 = 0; + + for (i = 0; i < folders.NumFolders; i++) + { + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) + { + digests.Defs[k] = true; + digests.Vals[k] = folders.FolderCRCs.Vals[i]; + k++; + } + else for (CNum j = 0; j < numSubstreams; j++) + { + bool defined = digests2[k2++]; + digests.Defs[k] = defined; + UInt32 crc = 0; + if (defined) + crc = ReadUInt32(); + digests.Vals[k] = crc; + k++; + } + } + // if (k != unpackSizes.Size()) throw 1234567; + } + else + SkipData(); + + type = ReadID(); + } + + if (digests.Defs.Size() != unpackSizes.Size()) + { + digests.ClearAndSetSize(unpackSizes.Size()); + unsigned k = 0; + for (i = 0; i < folders.NumFolders; i++) + { + const CNum numSubstreams = folders.NumUnpackStreamsVector[i]; + if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) + { + digests.Defs[k] = true; + digests.Vals[k] = folders.FolderCRCs.Vals[i]; + k++; + } + else for (CNum j = 0; j < numSubstreams; j++) + { + digests.Defs[k] = false; + digests.Vals[k] = 0; + k++; + } + } + } +} + + + +void CInArchive::ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CFolders &folders, + CRecordVector &unpackSizes, + CUInt32DefVector &digests) +{ + UInt64 type = ReadID(); + + if (type == NID::kPackInfo) + { + dataOffset = ReadNumber(); + if (dataOffset > _rangeLimit) + ThrowIncorrect(); + ReadPackInfo(folders); + if (folders.PackPositions[folders.NumPackStreams] > _rangeLimit - dataOffset) + ThrowIncorrect(); + type = ReadID(); + } + + if (type == NID::kUnpackInfo) + { + ReadUnpackInfo(dataVector, folders); + type = ReadID(); + } + + if (folders.NumFolders != 0 && !folders.PackPositions) + { + // if there are folders, we need PackPositions also + folders.PackPositions.Alloc(1); + folders.PackPositions[0] = 0; + } + + if (type == NID::kSubStreamsInfo) + { + ReadSubStreamsInfo(folders, unpackSizes, digests); + type = ReadID(); + } + else + { + folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); + /* If digests.Defs.Size() == 0, it means that there are no crcs. + So we don't need to fill digests with values. */ + // digests.Vals.ClearAndSetSize(folders.NumFolders); + // BoolVector_Fill_False(digests.Defs, folders.NumFolders); + for (CNum i = 0; i < folders.NumFolders; i++) + { + folders.NumUnpackStreamsVector[i] = 1; + unpackSizes.Add(folders.GetFolderUnpackSize(i)); + // digests.Vals[i] = 0; + } + } + + if (type != NID::kEnd) + ThrowIncorrect(); +} + +void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v) +{ + v.ClearAndSetSize(numItems); + Byte b = 0; + Byte mask = 0; + bool *p = &v[0]; + for (unsigned i = 0; i < numItems; i++) + { + if (mask == 0) + { + b = ReadByte(); + mask = 0x80; + } + p[i] = ((b & mask) != 0); + mask = (Byte)(mask >> 1); + } +} + +void CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) +{ + const Byte allAreDefined = ReadByte(); + if (allAreDefined == 0) + { + ReadBoolVector(numItems, v); + return; + } + v.ClearAndSetSize(numItems); + bool *p = &v[0]; + for (unsigned i = 0; i < numItems; i++) + p[i] = true; +} + +void CInArchive::ReadUInt64DefVector(const CObjectVector &dataVector, + CUInt64DefVector &v, unsigned numItems) +{ + ReadBoolVector2(numItems, v.Defs); + + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + + v.Vals.ClearAndSetSize(numItems); + UInt64 *p = &v.Vals[0]; + const bool *defs = &v.Defs[0]; + + for (unsigned i = 0; i < numItems; i++) + { + UInt64 t = 0; + if (defs[i]) + t = ReadUInt64(); + p[i] = t; + } +} + +HRESULT CInArchive::ReadAndDecodePackedStreams( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 baseOffset, + UInt64 &dataOffset, CObjectVector &dataVector + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ) +{ + CFolders folders; + CRecordVector unpackSizes; + CUInt32DefVector digests; + + ReadStreamsInfo(NULL, + dataOffset, + folders, + unpackSizes, + digests); + + CDecoder decoder(_useMixerMT); + + for (CNum i = 0; i < folders.NumFolders; i++) + { + CByteBuffer &data = dataVector.AddNew(); + const UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); + const size_t unpackSize = (size_t)unpackSize64; + if (unpackSize != unpackSize64) + ThrowUnsupported(); + data.Alloc(unpackSize); + + CMyComPtr2_Create outStreamSpec; + outStreamSpec->Init(data, unpackSize); + + bool dataAfterEnd_Error = false; + + HRESULT result = decoder.Decode( + EXTERNAL_CODECS_LOC_VARS + _stream, baseOffset + dataOffset, + folders, i, + NULL, // &unpackSize64 + + outStreamSpec, + NULL, // *compressProgress + + NULL // **inStreamMainRes + , dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS + #if !defined(Z7_ST) + , false // mtMode + , 1 // numThreads + , 0 // memUsage + #endif + ); + + RINOK(result) + + if (dataAfterEnd_Error) + ThereIsHeaderError = true; + + if (unpackSize != outStreamSpec->GetPos()) + ThrowIncorrect(); + + if (folders.FolderCRCs.ValidAndDefined(i)) + if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) + ThrowIncorrect(); + } + + if (folders.PackPositions) + HeadersSize += folders.PackPositions[folders.NumPackStreams]; + + return S_OK; +} + +HRESULT CInArchive::ReadHeader( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ) +{ + UInt64 type = ReadID(); + + if (type == NID::kArchiveProperties) + { + ReadArchiveProperties(db.ArcInfo); + type = ReadID(); + } + + CObjectVector dataVector; + + if (type == NID::kAdditionalStreamsInfo) + { + const HRESULT result = ReadAndDecodePackedStreams( + EXTERNAL_CODECS_LOC_VARS + db.ArcInfo.StartPositionAfterHeader, + db.ArcInfo.DataStartPosition2, + dataVector + Z7_7Z_DECODER_CRYPRO_VARS + ); + RINOK(result) + db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; + type = ReadID(); + } + + CRecordVector unpackSizes; + CUInt32DefVector digests; + + if (type == NID::kMainStreamsInfo) + { + ReadStreamsInfo(&dataVector, + db.ArcInfo.DataStartPosition, + (CFolders &)db, + unpackSizes, + digests); + db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader; + type = ReadID(); + } + + if (type == NID::kFilesInfo) + { + + const CNum numFiles = ReadNum(); + + db.ArcInfo.FileInfoPopIDs.Add(NID::kSize); + // if (!db.PackSizes.IsEmpty()) + db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo); + if (numFiles > 0 && !digests.Defs.IsEmpty()) + db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC); + + CBoolVector emptyStreamVector; + CBoolVector emptyFileVector; + CBoolVector antiFileVector; + unsigned numEmptyStreams = 0; + + for (;;) + { + const UInt64 type2 = ReadID(); + if (type2 == NID::kEnd) + break; + const UInt64 size = ReadNumber(); + if (size > _inByteBack->GetRem()) + ThrowIncorrect(); + CStreamSwitch switchProp; + switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true); + bool addPropIdToList = true; + bool isKnownType = true; + if (type2 > ((UInt32)1 << 30)) + isKnownType = false; + else switch ((UInt32)type2) + { + case NID::kName: + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + const size_t rem = _inByteBack->GetRem(); + db.NamesBuf.Alloc(rem); + ReadBytes(db.NamesBuf, rem); + db.NameOffsets.Alloc(numFiles + 1); + size_t pos = 0; + unsigned i; + for (i = 0; i < numFiles; i++) + { + const size_t curRem = (rem - pos) / 2; + const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf.ConstData() + pos); + size_t j; + for (j = 0; j < curRem && buf[j] != 0; j++); + if (j == curRem) + ThrowEndOfData(); + db.NameOffsets[i] = pos / 2; + pos += j * 2 + 2; + } + db.NameOffsets[i] = pos / 2; + if (pos != rem) + ThereIsHeaderError = true; + break; + } + + case NID::kWinAttrib: + { + ReadBoolVector2(numFiles, db.Attrib.Defs); + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + Read_UInt32_Vector(db.Attrib); + break; + } + + /* + case NID::kIsAux: + { + ReadBoolVector(numFiles, db.IsAux); + break; + } + case NID::kParent: + { + db.IsTree = true; + // CBoolVector boolVector; + // ReadBoolVector2(numFiles, boolVector); + // CStreamSwitch streamSwitch; + // streamSwitch.Set(this, &dataVector); + CBoolVector boolVector; + ReadBoolVector2(numFiles, boolVector); + + db.ThereAreAltStreams = false; + for (i = 0; i < numFiles; i++) + { + CFileItem &file = db.Files[i]; + // file.Parent = -1; + // if (boolVector[i]) + file.Parent = (int)ReadUInt32(); + file.IsAltStream = !boolVector[i]; + if (file.IsAltStream) + db.ThereAreAltStreams = true; + } + break; + } + */ + case NID::kEmptyStream: + { + ReadBoolVector(numFiles, emptyStreamVector); + numEmptyStreams = BoolVector_CountSum(emptyStreamVector); + emptyFileVector.Clear(); + antiFileVector.Clear(); + break; + } + case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; + case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; + case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break; + case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break; + case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break; + case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break; + case NID::kDummy: + { + for (UInt64 j = 0; j < size; j++) + if (ReadByte() != 0) + ThereIsHeaderError = true; + addPropIdToList = false; + break; + } + /* + case NID::kNtSecure: + { + try + { + { + CStreamSwitch streamSwitch; + streamSwitch.Set(this, &dataVector); + UInt32 numDescriptors = ReadUInt32(); + size_t offset = 0; + db.SecureOffsets.Clear(); + for (i = 0; i < numDescriptors; i++) + { + UInt32 size = ReadUInt32(); + db.SecureOffsets.Add(offset); + offset += size; + } + // ThrowIncorrect();; + db.SecureOffsets.Add(offset); + db.SecureBuf.SetCapacity(offset); + for (i = 0; i < numDescriptors; i++) + { + offset = db.SecureOffsets[i]; + ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset); + } + db.SecureIDs.Clear(); + for (unsigned i = 0; i < numFiles; i++) + { + db.SecureIDs.Add(ReadNum()); + // db.SecureIDs.Add(ReadUInt32()); + } + // ReadUInt32(); + if (_inByteBack->GetRem() != 0) + ThrowIncorrect();; + } + } + catch(CInArchiveException &) + { + ThereIsHeaderError = true; + addPropIdToList = isKnownType = false; + db.ClearSecure(); + } + break; + } + */ + default: + addPropIdToList = isKnownType = false; + } + if (isKnownType) + { + if (addPropIdToList) + db.ArcInfo.FileInfoPopIDs.Add(type2); + } + else + { + db.UnsupportedFeatureWarning = true; + _inByteBack->SkipRem(); + } + // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02) + if (_inByteBack->GetRem() != 0) + ThrowIncorrect(); + } + + type = ReadID(); // Read (NID::kEnd) end of headers + + if (numFiles - numEmptyStreams != unpackSizes.Size()) + ThrowUnsupported(); + + CNum emptyFileIndex = 0; + CNum sizeIndex = 0; + + const unsigned numAntiItems = BoolVector_CountSum(antiFileVector); + + if (numAntiItems != 0) + db.IsAnti.ClearAndSetSize(numFiles); + + db.Files.ClearAndSetSize(numFiles); + + for (CNum i = 0; i < numFiles; i++) + { + CFileItem &file = db.Files[i]; + bool isAnti; + file.Crc = 0; + if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i)) + { + file.HasStream = true; + file.IsDir = false; + isAnti = false; + file.Size = unpackSizes[sizeIndex]; + file.CrcDefined = digests.ValidAndDefined(sizeIndex); + if (file.CrcDefined) + file.Crc = digests.Vals[sizeIndex]; + sizeIndex++; + } + else + { + file.HasStream = false; + file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex); + isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex); + emptyFileIndex++; + file.Size = 0; + file.CrcDefined = false; + } + if (numAntiItems != 0) + db.IsAnti[i] = isAnti; + } + + } + + db.FillLinks(); + + if (type != NID::kEnd || _inByteBack->GetRem() != 0) + { + db.UnsupportedFeatureWarning = true; + // ThrowIncorrect(); + } + + return S_OK; +} + + +void CDbEx::FillLinks() +{ + FolderStartFileIndex.Alloc(NumFolders); + FileIndexToFolderIndexMap.Alloc(Files.Size()); + + CNum folderIndex = 0; + CNum indexInFolder = 0; + unsigned i; + + for (i = 0; i < Files.Size(); i++) + { + const bool emptyStream = !Files[i].HasStream; + if (indexInFolder == 0) + { + if (emptyStream) + { + FileIndexToFolderIndexMap[i] = kNumNoIndex; + continue; + } + // v3.13 incorrectly worked with empty folders + // v4.07: we skip empty folders + for (;;) + { + if (folderIndex >= NumFolders) + ThrowIncorrect(); + FolderStartFileIndex[folderIndex] = i; + if (NumUnpackStreamsVector[folderIndex] != 0) + break; + folderIndex++; + } + } + FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + if (++indexInFolder >= NumUnpackStreamsVector[folderIndex]) + { + folderIndex++; + indexInFolder = 0; + } + } + + if (indexInFolder != 0) + { + folderIndex++; + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } + + for (;;) + { + if (folderIndex >= NumFolders) + return; + FolderStartFileIndex[folderIndex] = i; + if (NumUnpackStreamsVector[folderIndex] != 0) + { + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } + folderIndex++; + } +} + + +HRESULT CInArchive::ReadDatabase2( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ) +{ + db.Clear(); + db.ArcInfo.StartPosition = _arhiveBeginStreamPosition; + + db.ArcInfo.Version.Major = _header[6]; + db.ArcInfo.Version.Minor = _header[7]; + + if (db.ArcInfo.Version.Major != kMajorVersion) + { + // db.UnsupportedVersion = true; + return S_FALSE; + } + + UInt64 nextHeaderOffset = Get64(_header + 12); + UInt64 nextHeaderSize = Get64(_header + 20); + UInt32 nextHeaderCRC = Get32(_header + 28); + + #ifdef FORMAT_7Z_RECOVERY + const UInt32 crcFromArc = Get32(_header + 8); + if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) + { + UInt64 cur, fileSize; + RINOK(InStream_GetPos(_stream, cur)) + const unsigned kCheckSize = 512; + Byte buf[kCheckSize]; + RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize)) + const UInt64 rem = fileSize - cur; + unsigned checkSize = kCheckSize; + if (rem < kCheckSize) + checkSize = (unsigned)(rem); + if (checkSize < 3) + return S_FALSE; + RINOK(InStream_SeekSet(_stream, fileSize - checkSize)) + RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)) + + if (buf[checkSize - 1] != 0) + return S_FALSE; + + unsigned i; + for (i = checkSize - 2;; i--) + { + if ((buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo) || + (buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)) + break; + if (i == 0) + return S_FALSE; + } + nextHeaderSize = checkSize - i; + nextHeaderOffset = rem - nextHeaderSize; + nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); + RINOK(InStream_SeekSet(_stream, cur)) + db.StartHeaderWasRecovered = true; + } + else + #endif + { + // Crc was tested already at signature check + // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect(); + } + + db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; + db.PhySize = kHeaderSize; + + db.IsArc = false; + if ((Int64)nextHeaderOffset < 0 || + nextHeaderSize > ((UInt64)1 << 62)) + return S_FALSE; + + HeadersSize = kHeaderSize; + + if (nextHeaderSize == 0) + { + if (nextHeaderOffset != 0 || nextHeaderCRC != 0) + return S_FALSE; + db.IsArc = true; + db.HeadersSize = HeadersSize; + return S_OK; + } + + if (!db.StartHeaderWasRecovered) + db.IsArc = true; + + HeadersSize += nextHeaderSize; + // db.EndHeaderOffset = nextHeaderOffset; + _rangeLimit = nextHeaderOffset; + + db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; + if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize) + { + db.UnexpectedEnd = true; + return S_FALSE; + } + RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL)) + + const size_t nextHeaderSize_t = (size_t)nextHeaderSize; + if (nextHeaderSize_t != nextHeaderSize) + return E_OUTOFMEMORY; + CByteBuffer buffer2(nextHeaderSize_t); + + RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)) + + if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) + ThrowIncorrect(); + + if (!db.StartHeaderWasRecovered) + db.PhySizeWasConfirmed = true; + + CStreamSwitch streamSwitch; + streamSwitch.Set(this, buffer2); + + CObjectVector dataVector; + + const UInt64 type = ReadID(); + if (type != NID::kHeader) + { + if (type != NID::kEncodedHeader) + ThrowIncorrect(); + const HRESULT result = ReadAndDecodePackedStreams( + EXTERNAL_CODECS_LOC_VARS + db.ArcInfo.StartPositionAfterHeader, + db.ArcInfo.DataStartPosition2, + dataVector + Z7_7Z_DECODER_CRYPRO_VARS + ); + RINOK(result) + if (dataVector.Size() == 0) + return S_OK; + if (dataVector.Size() > 1) + ThrowIncorrect(); + streamSwitch.Remove(); + streamSwitch.Set(this, dataVector.Front()); + if (ReadID() != NID::kHeader) + ThrowIncorrect(); + } + + db.IsArc = true; + + db.HeadersSize = HeadersSize; + + return ReadHeader( + EXTERNAL_CODECS_LOC_VARS + db + Z7_7Z_DECODER_CRYPRO_VARS + ); +} + + +HRESULT CInArchive::ReadDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ) +{ + try + { + const HRESULT res = ReadDatabase2( + EXTERNAL_CODECS_LOC_VARS db + Z7_7Z_DECODER_CRYPRO_VARS + ); + if (ThereIsHeaderError) + db.ThereIsHeaderError = true; + if (res == E_NOTIMPL) + ThrowUnsupported(); + return res; + } + catch(CUnsupportedFeatureException &) + { + db.UnsupportedFeatureError = true; + return S_FALSE; + } + catch(CInArchiveException &) + { + db.ThereIsHeaderError = true; + return S_FALSE; + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zIn.h 2015-11-20 20:39:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zIn.h 2024-02-17 09:00:00.000000000 +0000 @@ -1,431 +1,454 @@ -// 7zIn.h - -#ifndef __7Z_IN_H -#define __7Z_IN_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../IPassword.h" -#include "../../IStream.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/InBuffer.h" - -#include "7zItem.h" - -namespace NArchive { -namespace N7z { - -/* - We don't need to init isEncrypted and passwordIsDefined - We must upgrade them only */ - -#ifdef _NO_CRYPTO -#define _7Z_DECODER_CRYPRO_VARS_DECL -#define _7Z_DECODER_CRYPRO_VARS -#else -#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password -#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password -#endif - -struct CParsedMethods -{ - Byte Lzma2Prop; - UInt32 LzmaDic; - CRecordVector IDs; - - CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {} -}; - -struct CFolderEx: public CFolder -{ - unsigned UnpackCoder; -}; - -struct CFolders -{ - CNum NumPackStreams; - CNum NumFolders; - - CObjArray PackPositions; // NumPackStreams + 1 - // CUInt32DefVector PackCRCs; // we don't use PackCRCs now - - CUInt32DefVector FolderCRCs; // NumFolders - CObjArray NumUnpackStreamsVector; // NumFolders - - CObjArray CoderUnpackSizes; // including unpack sizes of bond coders - CObjArray FoToCoderUnpackSizes; // NumFolders + 1 - CObjArray FoStartPackStreamIndex; // NumFolders + 1 - CObjArray FoToMainUnpackSizeIndex; // NumFolders - - CObjArray FoCodersDataOffset; // NumFolders + 1 - CByteBuffer CodersData; - - CParsedMethods ParsedMethods; - - void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; - void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const - { - ParseFolderInfo(folderIndex, folder); - folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex]; - } - - unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const - { - return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]); - } - - UInt64 GetFolderUnpackSize(unsigned folderIndex) const - { - return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; - } - - UInt64 GetStreamPackSize(unsigned index) const - { - return PackPositions[index + 1] - PackPositions[index]; - } - - CFolders(): NumPackStreams(0), NumFolders(0) {} - - void Clear() - { - NumPackStreams = 0; - PackPositions.Free(); - // PackCRCs.Clear(); - - NumFolders = 0; - FolderCRCs.Clear(); - NumUnpackStreamsVector.Free(); - CoderUnpackSizes.Free(); - FoToCoderUnpackSizes.Free(); - FoStartPackStreamIndex.Free(); - FoToMainUnpackSizeIndex.Free(); - FoCodersDataOffset.Free(); - CodersData.Free(); - } -}; - -struct CDatabase: public CFolders -{ - CRecordVector Files; - - CUInt64DefVector CTime; - CUInt64DefVector ATime; - CUInt64DefVector MTime; - CUInt64DefVector StartPos; - CBoolVector IsAnti; - /* - CBoolVector IsAux; - CByteBuffer SecureBuf; - CRecordVector SecureIDs; - */ - - CByteBuffer NamesBuf; - CObjArray NameOffsets; // numFiles + 1, offsets of utf-16 symbols - - /* - void ClearSecure() - { - SecureBuf.Free(); - SecureIDs.Clear(); - } - */ - - void Clear() - { - CFolders::Clear(); - // ClearSecure(); - - NamesBuf.Free(); - NameOffsets.Free(); - - Files.Clear(); - CTime.Clear(); - ATime.Clear(); - MTime.Clear(); - StartPos.Clear(); - IsAnti.Clear(); - // IsAux.Clear(); - } - - bool IsSolid() const - { - for (CNum i = 0; i < NumFolders; i++) - if (NumUnpackStreamsVector[i] > 1) - return true; - return false; - } - bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } - // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } - - /* - const void* GetName(unsigned index) const - { - if (!NameOffsets || !NamesBuf) - return NULL; - return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); - }; - */ - void GetPath(unsigned index, UString &path) const; - HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); -}; - -struct CInArchiveInfo -{ - CArchiveVersion Version; - UInt64 StartPosition; - UInt64 StartPositionAfterHeader; - UInt64 DataStartPosition; - UInt64 DataStartPosition2; - CRecordVector FileInfoPopIDs; - - void Clear() - { - StartPosition = 0; - StartPositionAfterHeader = 0; - DataStartPosition = 0; - DataStartPosition2 = 0; - FileInfoPopIDs.Clear(); - } -}; - -struct CDbEx: public CDatabase -{ - CInArchiveInfo ArcInfo; - - CObjArray FolderStartFileIndex; - CObjArray FileIndexToFolderIndexMap; - - UInt64 HeadersSize; - UInt64 PhySize; - - /* - CRecordVector SecureOffsets; - bool IsTree; - bool ThereAreAltStreams; - */ - - bool IsArc; - bool PhySizeWasConfirmed; - - bool ThereIsHeaderError; - bool UnexpectedEnd; - // bool UnsupportedVersion; - - bool StartHeaderWasRecovered; - bool UnsupportedFeatureWarning; - bool UnsupportedFeatureError; - - /* - void ClearSecureEx() - { - ClearSecure(); - SecureOffsets.Clear(); - } - */ - - void Clear() - { - IsArc = false; - PhySizeWasConfirmed = false; - - ThereIsHeaderError = false; - UnexpectedEnd = false; - // UnsupportedVersion = false; - - StartHeaderWasRecovered = false; - UnsupportedFeatureError = false; - UnsupportedFeatureWarning = false; - - /* - IsTree = false; - ThereAreAltStreams = false; - */ - - CDatabase::Clear(); - - // SecureOffsets.Clear(); - ArcInfo.Clear(); - FolderStartFileIndex.Free(); - FileIndexToFolderIndexMap.Free(); - - HeadersSize = 0; - PhySize = 0; - } - - void FillLinks(); - - UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const - { - return ArcInfo.DataStartPosition + - PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; - } - - UInt64 GetFolderFullPackSize(CNum folderIndex) const - { - return - PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - - PackPositions[FoStartPackStreamIndex[folderIndex]]; - } - - UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const - { - size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex; - return PackPositions[i + 1] - PackPositions[i]; - } - - UInt64 GetFilePackSize(CNum fileIndex) const - { - CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex != kNumNoIndex) - if (FolderStartFileIndex[folderIndex] == fileIndex) - return GetFolderFullPackSize(folderIndex); - return 0; - } -}; - -const unsigned kNumBufLevelsMax = 4; - -struct CInByte2 -{ - const Byte *_buffer; -public: - size_t _size; - size_t _pos; - - size_t GetRem() const { return _size - _pos; } - const Byte *GetPtr() const { return _buffer + _pos; } - void Init(const Byte *buffer, size_t size) - { - _buffer = buffer; - _size = size; - _pos = 0; - } - Byte ReadByte(); - void ReadBytes(Byte *data, size_t size); - void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } - void SkipData(UInt64 size); - - void SkipData(); - void SkipRem() { _pos = _size; } - UInt64 ReadNumber(); - CNum ReadNum(); - UInt32 ReadUInt32(); - UInt64 ReadUInt64(); - - void ParseFolder(CFolder &folder); -}; - -class CStreamSwitch; - -const UInt32 kHeaderSize = 32; - -class CInArchive -{ - friend class CStreamSwitch; - - CMyComPtr _stream; - - unsigned _numInByteBufs; - CInByte2 _inByteVector[kNumBufLevelsMax]; - - CInByte2 *_inByteBack; - bool ThereIsHeaderError; - - UInt64 _arhiveBeginStreamPosition; - UInt64 _fileEndPosition; - - Byte _header[kHeaderSize]; - - UInt64 HeadersSize; - - bool _useMixerMT; - - void AddByteStream(const Byte *buffer, size_t size); - - void DeleteByteStream(bool needUpdatePos) - { - _numInByteBufs--; - if (_numInByteBufs > 0) - { - _inByteBack = &_inByteVector[_numInByteBufs - 1]; - if (needUpdatePos) - _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; - } - } - - HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); - - void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } - Byte ReadByte() { return _inByteBack->ReadByte(); } - UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } - CNum ReadNum() { return _inByteBack->ReadNum(); } - UInt64 ReadID() { return _inByteBack->ReadNumber(); } - UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } - UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } - void SkipData(UInt64 size) { _inByteBack->SkipData(size); } - void SkipData() { _inByteBack->SkipData(); } - void WaitId(UInt64 id); - - void ReadArchiveProperties(CInArchiveInfo &archiveInfo); - void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); - - void ReadPackInfo(CFolders &f); - - void ReadUnpackInfo( - const CObjectVector *dataVector, - CFolders &folders); - - void ReadSubStreamsInfo( - CFolders &folders, - CRecordVector &unpackSizes, - CUInt32DefVector &digests); - - void ReadStreamsInfo( - const CObjectVector *dataVector, - UInt64 &dataOffset, - CFolders &folders, - CRecordVector &unpackSizes, - CUInt32DefVector &digests); - - void ReadBoolVector(unsigned numItems, CBoolVector &v); - void ReadBoolVector2(unsigned numItems, CBoolVector &v); - void ReadUInt64DefVector(const CObjectVector &dataVector, - CUInt64DefVector &v, unsigned numItems); - HRESULT ReadAndDecodePackedStreams( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 baseOffset, UInt64 &dataOffset, - CObjectVector &dataVector - _7Z_DECODER_CRYPRO_VARS_DECL - ); - HRESULT ReadHeader( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ); - HRESULT ReadDatabase2( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ); -public: - CInArchive(bool useMixerMT): - _numInByteBufs(0), - _useMixerMT(useMixerMT) - {} - - HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive - void Close(); - - HRESULT ReadDatabase( - DECL_EXTERNAL_CODECS_LOC_VARS - CDbEx &db - _7Z_DECODER_CRYPRO_VARS_DECL - ); -}; - -}} - -#endif +// 7zIn.h + +#ifndef ZIP7_INC_7Z_IN_H +#define ZIP7_INC_7Z_IN_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../IPassword.h" +#include "../../IStream.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/InBuffer.h" + +#include "7zItem.h" + +namespace NArchive { +namespace N7z { + +/* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only */ + +#ifdef Z7_NO_CRYPTO +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL +#define Z7_7Z_DECODER_CRYPRO_VARS +#else +#define Z7_7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password +#define Z7_7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password +#endif + +struct CParsedMethods +{ + Byte Lzma2Prop; + UInt32 LzmaDic; + CRecordVector IDs; + + CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {} +}; + +struct CFolderEx: public CFolder +{ + unsigned UnpackCoder; +}; + +struct CFolders +{ + CNum NumPackStreams; + CNum NumFolders; + + CObjArray PackPositions; // NumPackStreams + 1 + // CUInt32DefVector PackCRCs; // we don't use PackCRCs now + + CUInt32DefVector FolderCRCs; // NumFolders + CObjArray NumUnpackStreamsVector; // NumFolders + + CObjArray CoderUnpackSizes; // including unpack sizes of bond coders + CObjArray FoToCoderUnpackSizes; // NumFolders + 1 + CObjArray FoStartPackStreamIndex; // NumFolders + 1 + CObjArray FoToMainUnpackSizeIndex; // NumFolders + + CObjArray FoCodersDataOffset; // NumFolders + 1 + CByteBuffer CodersData; + + CParsedMethods ParsedMethods; + + void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; + void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const + { + ParseFolderInfo(folderIndex, folder); + folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex]; + } + + unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const + { + return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]); + } + + UInt64 GetFolderUnpackSize(unsigned folderIndex) const + { + return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; + } + + UInt64 GetStreamPackSize(unsigned index) const + { + return PackPositions[index + 1] - PackPositions[index]; + } + + CFolders(): NumPackStreams(0), NumFolders(0) {} + + void Clear() + { + NumPackStreams = 0; + PackPositions.Free(); + // PackCRCs.Clear(); + + NumFolders = 0; + FolderCRCs.Clear(); + NumUnpackStreamsVector.Free(); + CoderUnpackSizes.Free(); + FoToCoderUnpackSizes.Free(); + FoStartPackStreamIndex.Free(); + FoToMainUnpackSizeIndex.Free(); + FoCodersDataOffset.Free(); + CodersData.Free(); + } +}; + +struct CDatabase: public CFolders +{ + CRecordVector Files; + + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CUInt32DefVector Attrib; + CBoolVector IsAnti; + /* + CBoolVector IsAux; + CByteBuffer SecureBuf; + CRecordVector SecureIDs; + */ + + CByteBuffer NamesBuf; + CObjArray NameOffsets; // numFiles + 1, offsets of utf-16 symbols + + /* + void ClearSecure() + { + SecureBuf.Free(); + SecureIDs.Clear(); + } + */ + + void Clear() + { + CFolders::Clear(); + // ClearSecure(); + + NamesBuf.Free(); + NameOffsets.Free(); + + Files.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + Attrib.Clear(); + IsAnti.Clear(); + // IsAux.Clear(); + } + + bool IsSolid() const + { + for (CNum i = 0; i < NumFolders; i++) + if (NumUnpackStreamsVector[i] > 1) + return true; + return false; + } + bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } + // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } + + /* + const void* GetName(unsigned index) const + { + if (!NameOffsets || !NamesBuf) + return NULL; + return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); + }; + */ + void GetPath(unsigned index, UString &path) const; + HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); +}; + + +struct CInArchiveInfo +{ + CArchiveVersion Version; + UInt64 StartPosition; // in stream + UInt64 StartPositionAfterHeader; // in stream + UInt64 DataStartPosition; // in stream + UInt64 DataStartPosition2; // in stream. it's for headers + CRecordVector FileInfoPopIDs; + + void Clear() + { + StartPosition = 0; + StartPositionAfterHeader = 0; + DataStartPosition = 0; + DataStartPosition2 = 0; + FileInfoPopIDs.Clear(); + } +}; + + +struct CDbEx: public CDatabase +{ + CInArchiveInfo ArcInfo; + + CObjArray FolderStartFileIndex; + CObjArray FileIndexToFolderIndexMap; + + UInt64 HeadersSize; + UInt64 PhySize; + // UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes) + + /* + CRecordVector SecureOffsets; + bool IsTree; + bool ThereAreAltStreams; + */ + + bool IsArc; + bool PhySizeWasConfirmed; + + bool ThereIsHeaderError; + bool UnexpectedEnd; + // bool UnsupportedVersion; + + bool StartHeaderWasRecovered; + bool UnsupportedFeatureWarning; + bool UnsupportedFeatureError; + + /* + void ClearSecureEx() + { + ClearSecure(); + SecureOffsets.Clear(); + } + */ + + void Clear() + { + IsArc = false; + PhySizeWasConfirmed = false; + + ThereIsHeaderError = false; + UnexpectedEnd = false; + // UnsupportedVersion = false; + + StartHeaderWasRecovered = false; + UnsupportedFeatureError = false; + UnsupportedFeatureWarning = false; + + /* + IsTree = false; + ThereAreAltStreams = false; + */ + + CDatabase::Clear(); + + // SecureOffsets.Clear(); + ArcInfo.Clear(); + FolderStartFileIndex.Free(); + FileIndexToFolderIndexMap.Free(); + + HeadersSize = 0; + PhySize = 0; + // EndHeaderOffset = 0; + } + + bool CanUpdate() const + { + if (ThereIsHeaderError + || UnexpectedEnd + || StartHeaderWasRecovered + || UnsupportedFeatureError) + return false; + return true; + } + + void FillLinks(); + + UInt64 GetFolderStreamPos(size_t folderIndex, size_t indexInFolder) const + { + return ArcInfo.DataStartPosition + PackPositions.ConstData() + [FoStartPackStreamIndex.ConstData()[folderIndex] + indexInFolder]; + } + + UInt64 GetFolderFullPackSize(size_t folderIndex) const + { + return + PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex + 1]] - + PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex]]; + } + + UInt64 GetFolderPackStreamSize(size_t folderIndex, size_t streamIndex) const + { + const size_t i = FoStartPackStreamIndex.ConstData()[folderIndex] + streamIndex; + return PackPositions.ConstData()[i + 1] - + PackPositions.ConstData()[i]; + } + + /* + UInt64 GetFilePackSize(size_t fileIndex) const + { + const CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex != kNumNoIndex) + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + return 0; + } + */ +}; + +const unsigned kNumBufLevelsMax = 4; + +struct CInByte2 +{ + const Byte *_buffer; +public: + size_t _size; + size_t _pos; + + size_t GetRem() const { return _size - _pos; } + const Byte *GetPtr() const { return _buffer + _pos; } + void Init(const Byte *buffer, size_t size) + { + _buffer = buffer; + _size = size; + _pos = 0; + } + Byte ReadByte(); + void ReadBytes(Byte *data, size_t size); + void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } + void SkipData(UInt64 size); + + void SkipData(); + void SkipRem() { _pos = _size; } + UInt64 ReadNumber(); + CNum ReadNum(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + + void ParseFolder(CFolder &folder); +}; + +class CStreamSwitch; + +const UInt32 kHeaderSize = 32; + +class CInArchive +{ + friend class CStreamSwitch; + + CMyComPtr _stream; + + unsigned _numInByteBufs; + CInByte2 _inByteVector[kNumBufLevelsMax]; + + CInByte2 *_inByteBack; + bool ThereIsHeaderError; + + UInt64 _arhiveBeginStreamPosition; + UInt64 _fileEndPosition; + + UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes) + + Byte _header[kHeaderSize]; + + UInt64 HeadersSize; + + bool _useMixerMT; + + void AddByteStream(const Byte *buffer, size_t size); + + void DeleteByteStream(bool needUpdatePos) + { + _numInByteBufs--; + if (_numInByteBufs > 0) + { + _inByteBack = &_inByteVector[_numInByteBufs - 1]; + if (needUpdatePos) + _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; + } + } + + HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + + void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } + Byte ReadByte() { return _inByteBack->ReadByte(); } + UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } + CNum ReadNum() { return _inByteBack->ReadNum(); } + UInt64 ReadID() { return _inByteBack->ReadNumber(); } + UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } + UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } + void SkipData(UInt64 size) { _inByteBack->SkipData(size); } + void SkipData() { _inByteBack->SkipData(); } + void WaitId(UInt64 id); + + void Read_UInt32_Vector(CUInt32DefVector &v); + + void ReadArchiveProperties(CInArchiveInfo &archiveInfo); + void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); + + void ReadPackInfo(CFolders &f); + + void ReadUnpackInfo( + const CObjectVector *dataVector, + CFolders &folders); + + void ReadSubStreamsInfo( + CFolders &folders, + CRecordVector &unpackSizes, + CUInt32DefVector &digests); + + void ReadStreamsInfo( + const CObjectVector *dataVector, + UInt64 &dataOffset, + CFolders &folders, + CRecordVector &unpackSizes, + CUInt32DefVector &digests); + + void ReadBoolVector(unsigned numItems, CBoolVector &v); + void ReadBoolVector2(unsigned numItems, CBoolVector &v); + void ReadUInt64DefVector(const CObjectVector &dataVector, + CUInt64DefVector &v, unsigned numItems); + HRESULT ReadAndDecodePackedStreams( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 baseOffset, UInt64 &dataOffset, + CObjectVector &dataVector + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ); + HRESULT ReadHeader( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ); + HRESULT ReadDatabase2( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ); +public: + CInArchive(bool useMixerMT): + _numInByteBufs(0), + _useMixerMT(useMixerMT) + {} + + HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive + void Close(); + + HRESULT ReadDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + CDbEx &db + Z7_7Z_DECODER_CRYPRO_VARS_DECL + ); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zItem.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zItem.h 2023-09-12 11:00:00.000000000 +0000 @@ -1,183 +1,207 @@ -// 7zItem.h - -#ifndef __7Z_ITEM_H -#define __7Z_ITEM_H - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyString.h" - -#include "../../Common/MethodId.h" - -#include "7zHeader.h" - -namespace NArchive { -namespace N7z { - -typedef UInt32 CNum; -const CNum kNumMax = 0x7FFFFFFF; -const CNum kNumNoIndex = 0xFFFFFFFF; - -struct CCoderInfo -{ - CMethodId MethodID; - CByteBuffer Props; - UInt32 NumStreams; - - bool IsSimpleCoder() const { return NumStreams == 1; } -}; - -struct CBond -{ - UInt32 PackIndex; - UInt32 UnpackIndex; -}; - -struct CFolder -{ - CLASS_NO_COPY(CFolder) -public: - CObjArray2 Coders; - CObjArray2 Bonds; - CObjArray2 PackStreams; - - CFolder() {} - - bool IsDecodingSupported() const { return Coders.Size() <= 32; } - - int Find_in_PackStreams(UInt32 packStream) const - { - FOR_VECTOR(i, PackStreams) - if (PackStreams[i] == packStream) - return i; - return -1; - } - - int FindBond_for_PackStream(UInt32 packStream) const - { - FOR_VECTOR(i, Bonds) - if (Bonds[i].PackIndex == packStream) - return i; - return -1; - } - - /* - int FindBond_for_UnpackStream(UInt32 unpackStream) const - { - FOR_VECTOR(i, Bonds) - if (Bonds[i].UnpackIndex == unpackStream) - return i; - return -1; - } - - int FindOutCoder() const - { - for (int i = (int)Coders.Size() - 1; i >= 0; i--) - if (FindBond_for_UnpackStream(i) < 0) - return i; - return -1; - } - */ - - bool IsEncrypted() const - { - FOR_VECTOR(i, Coders) - if (Coders[i].MethodID == k_AES) - return true; - return false; - } -}; - -struct CUInt32DefVector -{ - CBoolVector Defs; - CRecordVector Vals; - - void ClearAndSetSize(unsigned newSize) - { - Defs.ClearAndSetSize(newSize); - Vals.ClearAndSetSize(newSize); - } - - void Clear() - { - Defs.Clear(); - Vals.Clear(); - } - - void ReserveDown() - { - Defs.ReserveDown(); - Vals.ReserveDown(); - } - - bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; } -}; - -struct CUInt64DefVector -{ - CBoolVector Defs; - CRecordVector Vals; - - void Clear() - { - Defs.Clear(); - Vals.Clear(); - } - - void ReserveDown() - { - Defs.ReserveDown(); - Vals.ReserveDown(); - } - - bool GetItem(unsigned index, UInt64 &value) const - { - if (index < Defs.Size() && Defs[index]) - { - value = Vals[index]; - return true; - } - value = 0; - return false; - } - - void SetItem(unsigned index, bool defined, UInt64 value); - - bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } -}; - -struct CFileItem -{ - UInt64 Size; - UInt32 Attrib; - UInt32 Crc; - /* - int Parent; - bool IsAltStream; - */ - bool HasStream; // Test it !!! it means that there is - // stream in some folder. It can be empty stream - bool IsDir; - bool CrcDefined; - bool AttribDefined; - - CFileItem(): - /* - Parent(-1), - IsAltStream(false), - */ - HasStream(true), - IsDir(false), - CrcDefined(false), - AttribDefined(false) - {} - void SetAttrib(UInt32 attrib) - { - AttribDefined = true; - Attrib = attrib; - } -}; - -}} - -#endif +// 7zItem.h + +#ifndef ZIP7_INC_7Z_ITEM_H +#define ZIP7_INC_7Z_ITEM_H + +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyString.h" + +#include "../../Common/MethodId.h" + +#include "7zHeader.h" + +namespace NArchive { +namespace N7z { + +typedef UInt32 CNum; +const CNum kNumMax = 0x7FFFFFFF; +const CNum kNumNoIndex = 0xFFFFFFFF; + +struct CCoderInfo +{ + CMethodId MethodID; + CByteBuffer Props; + UInt32 NumStreams; + + bool IsSimpleCoder() const { return NumStreams == 1; } +}; + + +struct CBond +{ + UInt32 PackIndex; + UInt32 UnpackIndex; +}; + + +struct CFolder +{ + Z7_CLASS_NO_COPY(CFolder) +public: + CObjArray2 Coders; + CObjArray2 Bonds; + CObjArray2 PackStreams; + + CFolder() {} + + bool IsDecodingSupported() const { return Coders.Size() <= 32; } + + int Find_in_PackStreams(UInt32 packStream) const + { + FOR_VECTOR(i, PackStreams) + if (PackStreams[i] == packStream) + return (int)i; + return -1; + } + + int FindBond_for_PackStream(UInt32 packStream) const + { + FOR_VECTOR(i, Bonds) + if (Bonds[i].PackIndex == packStream) + return (int)i; + return -1; + } + + /* + int FindBond_for_UnpackStream(UInt32 unpackStream) const + { + FOR_VECTOR(i, Bonds) + if (Bonds[i].UnpackIndex == unpackStream) + return i; + return -1; + } + + int FindOutCoder() const + { + for (int i = (int)Coders.Size() - 1; i >= 0; i--) + if (FindBond_for_UnpackStream(i) < 0) + return i; + return -1; + } + */ + + bool IsEncrypted() const + { + FOR_VECTOR(i, Coders) + if (Coders[i].MethodID == k_AES) + return true; + return false; + } +}; + + +struct CUInt32DefVector +{ + CBoolVector Defs; + CRecordVector Vals; + + void ClearAndSetSize(unsigned newSize) + { + Defs.ClearAndSetSize(newSize); + Vals.ClearAndSetSize(newSize); + } + + void Clear() + { + Defs.Clear(); + Vals.Clear(); + } + + void ReserveDown() + { + Defs.ReserveDown(); + Vals.ReserveDown(); + } + + bool GetItem(unsigned index, UInt32 &value) const + { + if (index < Defs.Size() && Defs[index]) + { + value = Vals[index]; + return true; + } + value = 0; + return false; + } + + bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; } + + bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } + + void SetItem(unsigned index, bool defined, UInt32 value); + void if_NonEmpty_FillResidue_with_false(unsigned numItems) + { + if (Defs.Size() != 0 && Defs.Size() < numItems) + SetItem(numItems - 1, false, 0); + } +}; + + +struct CUInt64DefVector +{ + CBoolVector Defs; + CRecordVector Vals; + + void Clear() + { + Defs.Clear(); + Vals.Clear(); + } + + void ReserveDown() + { + Defs.ReserveDown(); + Vals.ReserveDown(); + } + + bool GetItem(unsigned index, UInt64 &value) const + { + if (index < Defs.Size() && Defs[index]) + { + value = Vals[index]; + return true; + } + value = 0; + return false; + } + + bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; } + + void SetItem(unsigned index, bool defined, UInt64 value); +}; + + +struct CFileItem +{ + UInt64 Size; + UInt32 Crc; + /* + int Parent; + bool IsAltStream; + */ + bool HasStream; // Test it !!! it means that there is + // stream in some folder. It can be empty stream + bool IsDir; + bool CrcDefined; + + /* + void Clear() + { + HasStream = true; + IsDir = false; + CrcDefined = false; + } + + CFileItem(): + // Parent(-1), + // IsAltStream(false), + HasStream(true), + IsDir(false), + CrcDefined(false), + {} + */ +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zOut.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -1,916 +1,1026 @@ -// 7zOut.cpp - -#include "StdAfx.h" - -#include "../../../../C/7zCrc.h" - -#include "../../../Common/AutoPtr.h" - -#include "../../Common/StreamObjects.h" - -#include "7zOut.h" - -namespace NArchive { -namespace N7z { - -HRESULT COutArchive::WriteSignature() -{ - Byte buf[8]; - memcpy(buf, kSignature, kSignatureSize); - buf[kSignatureSize] = kMajorVersion; - buf[kSignatureSize + 1] = 4; - return WriteDirect(buf, 8); -} - -#ifdef _7Z_VOL -HRESULT COutArchive::WriteFinishSignature() -{ - RINOK(WriteDirect(kFinishSignature, kSignatureSize)); - CArchiveVersion av; - av.Major = kMajorVersion; - av.Minor = 2; - RINOK(WriteDirectByte(av.Major)); - return WriteDirectByte(av.Minor); -} -#endif - -static void SetUInt32(Byte *p, UInt32 d) -{ - for (int i = 0; i < 4; i++, d >>= 8) - p[i] = (Byte)d; -} - -static void SetUInt64(Byte *p, UInt64 d) -{ - for (int i = 0; i < 8; i++, d >>= 8) - p[i] = (Byte)d; -} - -HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) -{ - Byte buf[24]; - SetUInt64(buf + 4, h.NextHeaderOffset); - SetUInt64(buf + 12, h.NextHeaderSize); - SetUInt32(buf + 20, h.NextHeaderCRC); - SetUInt32(buf, CrcCalc(buf + 4, 20)); - return WriteDirect(buf, 24); -} - -#ifdef _7Z_VOL -HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) -{ - CCRC crc; - crc.UpdateUInt64(h.NextHeaderOffset); - crc.UpdateUInt64(h.NextHeaderSize); - crc.UpdateUInt32(h.NextHeaderCRC); - crc.UpdateUInt64(h.ArchiveStartOffset); - crc.UpdateUInt64(h.AdditionalStartBlockSize); - RINOK(WriteDirectUInt32(crc.GetDigest())); - RINOK(WriteDirectUInt64(h.NextHeaderOffset)); - RINOK(WriteDirectUInt64(h.NextHeaderSize)); - RINOK(WriteDirectUInt32(h.NextHeaderCRC)); - RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); - return WriteDirectUInt64(h.AdditionalStartBlockSize); -} -#endif - -HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) -{ - Close(); - #ifdef _7Z_VOL - // endMarker = false; - _endMarker = endMarker; - #endif - SeqStream = stream; - if (!endMarker) - { - SeqStream.QueryInterface(IID_IOutStream, &Stream); - if (!Stream) - { - return E_NOTIMPL; - // endMarker = true; - } - } - #ifdef _7Z_VOL - if (endMarker) - { - /* - CStartHeader sh; - sh.NextHeaderOffset = (UInt32)(Int32)-1; - sh.NextHeaderSize = (UInt32)(Int32)-1; - sh.NextHeaderCRC = 0; - WriteStartHeader(sh); - */ - } - else - #endif - { - if (!Stream) - return E_FAIL; - RINOK(WriteSignature()); - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos)); - } - return S_OK; -} - -void COutArchive::Close() -{ - SeqStream.Release(); - Stream.Release(); -} - -HRESULT COutArchive::SkipPrefixArchiveHeader() -{ - #ifdef _7Z_VOL - if (_endMarker) - return S_OK; - #endif - Byte buf[24]; - memset(buf, 0, 24); - return WriteDirect(buf, 24); -} - -UInt64 COutArchive::GetPos() const -{ - if (_countMode) - return _countSize; - if (_writeToStream) - return _outByte.GetProcessedSize(); - return _outByte2.GetPos(); -} - -void COutArchive::WriteBytes(const void *data, size_t size) -{ - if (_countMode) - _countSize += size; - else if (_writeToStream) - { - _outByte.WriteBytes(data, size); - _crc = CrcUpdate(_crc, data, size); - } - else - _outByte2.WriteBytes(data, size); -} - -void COutArchive::WriteByte(Byte b) -{ - if (_countMode) - _countSize++; - else if (_writeToStream) - { - _outByte.WriteByte(b); - _crc = CRC_UPDATE_BYTE(_crc, b); - } - else - _outByte2.WriteByte(b); -} - -void COutArchive::WriteUInt32(UInt32 value) -{ - for (int i = 0; i < 4; i++) - { - WriteByte((Byte)value); - value >>= 8; - } -} - -void COutArchive::WriteUInt64(UInt64 value) -{ - for (int i = 0; i < 8; i++) - { - WriteByte((Byte)value); - value >>= 8; - } -} - -void COutArchive::WriteNumber(UInt64 value) -{ - Byte firstByte = 0; - Byte mask = 0x80; - int i; - for (i = 0; i < 8; i++) - { - if (value < ((UInt64(1) << ( 7 * (i + 1))))) - { - firstByte |= Byte(value >> (8 * i)); - break; - } - firstByte |= mask; - mask >>= 1; - } - WriteByte(firstByte); - for (; i > 0; i--) - { - WriteByte((Byte)value); - value >>= 8; - } -} - -static UInt32 GetBigNumberSize(UInt64 value) -{ - int i; - for (i = 1; i < 9; i++) - if (value < (((UInt64)1 << (i * 7)))) - break; - return i; -} - -#ifdef _7Z_VOL -UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) -{ - UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; - if (nameLength != 0) - { - nameLength = (nameLength + 1) * 2; - result += nameLength + GetBigNumberSize(nameLength) + 2; - } - if (props) - { - result += 20; - } - if (result >= 128) - result++; - result += kSignatureSize + 2 + kFinishHeaderSize; - return result; -} - -UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) -{ - UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); - int testSize; - if (volSize > headersSizeBase) - testSize = volSize - headersSizeBase; - else - testSize = 1; - UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); - UInt64 pureSize = 1; - if (volSize > headersSize) - pureSize = volSize - headersSize; - return pureSize; -} -#endif - -void COutArchive::WriteFolder(const CFolder &folder) -{ - WriteNumber(folder.Coders.Size()); - unsigned i; - - for (i = 0; i < folder.Coders.Size(); i++) - { - const CCoderInfo &coder = folder.Coders[i]; - { - UInt64 id = coder.MethodID; - unsigned idSize; - for (idSize = 1; idSize < sizeof(id); idSize++) - if ((id >> (8 * idSize)) == 0) - break; - idSize &= 0xF; - Byte temp[16]; - for (unsigned t = idSize; t != 0; t--, id >>= 8) - temp[t] = (Byte)(id & 0xFF); - - Byte b = (Byte)(idSize); - bool isComplex = !coder.IsSimpleCoder(); - b |= (isComplex ? 0x10 : 0); - - size_t propsSize = coder.Props.Size(); - b |= ((propsSize != 0) ? 0x20 : 0); - temp[0] = b; - WriteBytes(temp, idSize + 1); - if (isComplex) - { - WriteNumber(coder.NumStreams); - WriteNumber(1); // NumOutStreams; - } - if (propsSize == 0) - continue; - WriteNumber(propsSize); - WriteBytes(coder.Props, propsSize); - } - } - - for (i = 0; i < folder.Bonds.Size(); i++) - { - const CBond &bond = folder.Bonds[i]; - WriteNumber(bond.PackIndex); - WriteNumber(bond.UnpackIndex); - } - - if (folder.PackStreams.Size() > 1) - for (i = 0; i < folder.PackStreams.Size(); i++) - WriteNumber(folder.PackStreams[i]); -} - -void COutArchive::WriteBoolVector(const CBoolVector &boolVector) -{ - Byte b = 0; - Byte mask = 0x80; - FOR_VECTOR (i, boolVector) - { - if (boolVector[i]) - b |= mask; - mask >>= 1; - if (mask == 0) - { - WriteByte(b); - mask = 0x80; - b = 0; - } - } - if (mask != 0x80) - WriteByte(b); -} - -static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } - -void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) -{ - WriteByte(id); - WriteNumber(Bv_GetSizeInBytes(boolVector)); - WriteBoolVector(boolVector); -} - -void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) -{ - unsigned numDefined = 0; - unsigned i; - for (i = 0; i < digests.Defs.Size(); i++) - if (digests.Defs[i]) - numDefined++; - if (numDefined == 0) - return; - - WriteByte(NID::kCRC); - if (numDefined == digests.Defs.Size()) - WriteByte(1); - else - { - WriteByte(0); - WriteBoolVector(digests.Defs); - } - for (i = 0; i < digests.Defs.Size(); i++) - if (digests.Defs[i]) - WriteUInt32(digests.Vals[i]); -} - -void COutArchive::WritePackInfo( - UInt64 dataOffset, - const CRecordVector &packSizes, - const CUInt32DefVector &packCRCs) -{ - if (packSizes.IsEmpty()) - return; - WriteByte(NID::kPackInfo); - WriteNumber(dataOffset); - WriteNumber(packSizes.Size()); - WriteByte(NID::kSize); - FOR_VECTOR (i, packSizes) - WriteNumber(packSizes[i]); - - WriteHashDigests(packCRCs); - - WriteByte(NID::kEnd); -} - -void COutArchive::WriteUnpackInfo(const CObjectVector &folders, const COutFolders &outFolders) -{ - if (folders.IsEmpty()) - return; - - WriteByte(NID::kUnpackInfo); - - WriteByte(NID::kFolder); - WriteNumber(folders.Size()); - { - WriteByte(0); - FOR_VECTOR (i, folders) - WriteFolder(folders[i]); - } - - WriteByte(NID::kCodersUnpackSize); - FOR_VECTOR (i, outFolders.CoderUnpackSizes) - WriteNumber(outFolders.CoderUnpackSizes[i]); - - WriteHashDigests(outFolders.FolderUnpackCRCs); - - WriteByte(NID::kEnd); -} - -void COutArchive::WriteSubStreamsInfo(const CObjectVector &folders, - const COutFolders &outFolders, - const CRecordVector &unpackSizes, - const CUInt32DefVector &digests) -{ - const CRecordVector &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector; - WriteByte(NID::kSubStreamsInfo); - - unsigned i; - for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - if (numUnpackStreamsInFolders[i] != 1) - { - WriteByte(NID::kNumUnpackStream); - for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - WriteNumber(numUnpackStreamsInFolders[i]); - break; - } - - for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - if (numUnpackStreamsInFolders[i] > 1) - { - WriteByte(NID::kSize); - CNum index = 0; - for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) - { - CNum num = numUnpackStreamsInFolders[i]; - for (CNum j = 0; j < num; j++) - { - if (j + 1 != num) - WriteNumber(unpackSizes[index]); - index++; - } - } - break; - } - - CUInt32DefVector digests2; - - unsigned digestIndex = 0; - for (i = 0; i < folders.Size(); i++) - { - unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i]; - if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i)) - digestIndex++; - else - for (unsigned j = 0; j < numSubStreams; j++, digestIndex++) - { - digests2.Defs.Add(digests.Defs[digestIndex]); - digests2.Vals.Add(digests.Vals[digestIndex]); - } - } - WriteHashDigests(digests2); - WriteByte(NID::kEnd); -} - -// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. - -void COutArchive::SkipAlign(unsigned pos, unsigned alignSize) -{ - if (!_useAlign) - return; - pos += (unsigned)GetPos(); - pos &= (alignSize - 1); - if (pos == 0) - return; - unsigned skip = alignSize - pos; - if (skip < 2) - skip += alignSize; - skip -= 2; - WriteByte(NID::kDummy); - WriteByte((Byte)skip); - for (unsigned i = 0; i < skip; i++) - WriteByte(0); -} - -void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize) -{ - const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); - const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2; - SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize); - - WriteByte(type); - WriteNumber(dataSize); - if (numDefined == v.Size()) - WriteByte(1); - else - { - WriteByte(0); - WriteBoolVector(v); - } - WriteByte(0); -} - -void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) -{ - unsigned numDefined = 0; - - unsigned i; - for (i = 0; i < v.Defs.Size(); i++) - if (v.Defs[i]) - numDefined++; - - if (numDefined == 0) - return; - - WriteAlignedBoolHeader(v.Defs, numDefined, type, 8); - - for (i = 0; i < v.Defs.Size(); i++) - if (v.Defs[i]) - WriteUInt64(v.Vals[i]); -} - -HRESULT COutArchive::EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, - CRecordVector &packSizes, CObjectVector &folders, COutFolders &outFolders) -{ - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr stream = streamSpec; - streamSpec->Init(data, data.Size()); - outFolders.FolderUnpackCRCs.Defs.Add(true); - outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); - // outFolders.NumUnpackStreamsVector.Add(1); - UInt64 dataSize64 = data.Size(); - UInt64 unpackSize; - RINOK(encoder.Encode( - EXTERNAL_CODECS_LOC_VARS - stream, - // NULL, - &dataSize64, - folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL)) - return S_OK; -} - -void COutArchive::WriteHeader( - const CArchiveDatabaseOut &db, - // const CHeaderOptions &headerOptions, - UInt64 &headerOffset) -{ - /* - bool thereIsSecure = (db.SecureBuf.Size() != 0); - */ - _useAlign = true; - - { - UInt64 packSize = 0; - FOR_VECTOR (i, db.PackSizes) - packSize += db.PackSizes[i]; - headerOffset = packSize; - } - - - WriteByte(NID::kHeader); - - // Archive Properties - - if (db.Folders.Size() > 0) - { - WriteByte(NID::kMainStreamsInfo); - WritePackInfo(0, db.PackSizes, db.PackCRCs); - WriteUnpackInfo(db.Folders, (const COutFolders &)db); - - CRecordVector unpackSizes; - CUInt32DefVector digests; - FOR_VECTOR (i, db.Files) - { - const CFileItem &file = db.Files[i]; - if (!file.HasStream) - continue; - unpackSizes.Add(file.Size); - digests.Defs.Add(file.CrcDefined); - digests.Vals.Add(file.Crc); - } - - WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests); - WriteByte(NID::kEnd); - } - - if (db.Files.IsEmpty()) - { - WriteByte(NID::kEnd); - return; - } - - WriteByte(NID::kFilesInfo); - WriteNumber(db.Files.Size()); - - { - /* ---------- Empty Streams ---------- */ - CBoolVector emptyStreamVector; - emptyStreamVector.ClearAndSetSize(db.Files.Size()); - unsigned numEmptyStreams = 0; - { - FOR_VECTOR (i, db.Files) - if (db.Files[i].HasStream) - emptyStreamVector[i] = false; - else - { - emptyStreamVector[i] = true; - numEmptyStreams++; - } - } - - if (numEmptyStreams != 0) - { - WritePropBoolVector(NID::kEmptyStream, emptyStreamVector); - - CBoolVector emptyFileVector, antiVector; - emptyFileVector.ClearAndSetSize(numEmptyStreams); - antiVector.ClearAndSetSize(numEmptyStreams); - bool thereAreEmptyFiles = false, thereAreAntiItems = false; - unsigned cur = 0; - - FOR_VECTOR (i, db.Files) - { - const CFileItem &file = db.Files[i]; - if (file.HasStream) - continue; - emptyFileVector[cur] = !file.IsDir; - if (!file.IsDir) - thereAreEmptyFiles = true; - bool isAnti = db.IsItemAnti(i); - antiVector[cur] = isAnti; - if (isAnti) - thereAreAntiItems = true; - cur++; - } - - if (thereAreEmptyFiles) - WritePropBoolVector(NID::kEmptyFile, emptyFileVector); - if (thereAreAntiItems) - WritePropBoolVector(NID::kAnti, antiVector); - } - } - - - { - /* ---------- Names ---------- */ - - unsigned numDefined = 0; - size_t namesDataSize = 0; - FOR_VECTOR (i, db.Files) - { - const UString &name = db.Names[i]; - if (!name.IsEmpty()) - numDefined++; - namesDataSize += (name.Len() + 1) * 2; - } - - if (numDefined > 0) - { - namesDataSize++; - SkipAlign(2 + GetBigNumberSize(namesDataSize), 16); - - WriteByte(NID::kName); - WriteNumber(namesDataSize); - WriteByte(0); - FOR_VECTOR (i, db.Files) - { - const UString &name = db.Names[i]; - for (unsigned t = 0; t <= name.Len(); t++) - { - wchar_t c = name[t]; - WriteByte((Byte)c); - WriteByte((Byte)(c >> 8)); - } - } - } - } - - /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime); - /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime); - /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime); - WriteUInt64DefVector(db.StartPos, NID::kStartPos); - - { - /* ---------- Write Attrib ---------- */ - CBoolVector boolVector; - boolVector.ClearAndSetSize(db.Files.Size()); - unsigned numDefined = 0; - - { - FOR_VECTOR (i, db.Files) - { - bool defined = db.Files[i].AttribDefined; - boolVector[i] = defined; - if (defined) - numDefined++; - } - } - - if (numDefined != 0) - { - WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4); - FOR_VECTOR (i, db.Files) - { - const CFileItem &file = db.Files[i]; - if (file.AttribDefined) - WriteUInt32(file.Attrib); - } - } - } - - /* - { - // ---------- Write IsAux ---------- - unsigned numAux = 0; - const CBoolVector &isAux = db.IsAux; - for (i = 0; i < isAux.Size(); i++) - if (isAux[i]) - numAux++; - if (numAux > 0) - { - const unsigned bvSize = Bv_GetSizeInBytes(isAux); - WriteByte(NID::kIsAux); - WriteNumber(bvSize); - WriteBoolVector(isAux); - } - } - - { - // ---------- Write Parent ---------- - CBoolVector boolVector; - boolVector.Reserve(db.Files.Size()); - unsigned numIsDir = 0; - unsigned numParentLinks = 0; - for (i = 0; i < db.Files.Size(); i++) - { - const CFileItem &file = db.Files[i]; - bool defined = !file.IsAltStream; - boolVector.Add(defined); - if (defined) - numIsDir++; - if (file.Parent >= 0) - numParentLinks++; - } - if (numParentLinks > 0) - { - // WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4); - const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector); - const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1; - SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4); - - WriteByte(NID::kParent); - WriteNumber(dataSize); - if (numIsDir == boolVector.Size()) - WriteByte(1); - else - { - WriteByte(0); - WriteBoolVector(boolVector); - } - for (i = 0; i < db.Files.Size(); i++) - { - const CFileItem &file = db.Files[i]; - // if (file.Parent >= 0) - WriteUInt32(file.Parent); - } - } - } - - if (thereIsSecure) - { - UInt64 secureDataSize = 1 + 4 + - db.SecureBuf.Size() + - db.SecureSizes.Size() * 4; - // secureDataSize += db.SecureIDs.Size() * 4; - for (i = 0; i < db.SecureIDs.Size(); i++) - secureDataSize += GetBigNumberSize(db.SecureIDs[i]); - SkipAlign(2 + GetBigNumberSize(secureDataSize), 4); - WriteByte(NID::kNtSecure); - WriteNumber(secureDataSize); - WriteByte(0); - WriteUInt32(db.SecureSizes.Size()); - for (i = 0; i < db.SecureSizes.Size(); i++) - WriteUInt32(db.SecureSizes[i]); - WriteBytes(db.SecureBuf, db.SecureBuf.Size()); - for (i = 0; i < db.SecureIDs.Size(); i++) - { - WriteNumber(db.SecureIDs[i]); - // WriteUInt32(db.SecureIDs[i]); - } - } - */ - - WriteByte(NID::kEnd); // for files - WriteByte(NID::kEnd); // for headers -} - -HRESULT COutArchive::WriteDatabase( - DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabaseOut &db, - const CCompressionMethodMode *options, - const CHeaderOptions &headerOptions) -{ - if (!db.CheckNumFiles()) - return E_FAIL; - - UInt64 headerOffset; - UInt32 headerCRC; - UInt64 headerSize; - if (db.IsEmpty()) - { - headerSize = 0; - headerOffset = 0; - headerCRC = CrcCalc(0, 0); - } - else - { - bool encodeHeaders = false; - if (options != 0) - if (options->IsEmpty()) - options = 0; - if (options != 0) - if (options->PasswordIsDefined || headerOptions.CompressMainHeader) - encodeHeaders = true; - - _outByte.SetStream(SeqStream); - _outByte.Init(); - _crc = CRC_INIT_VAL; - _countMode = encodeHeaders; - _writeToStream = true; - _countSize = 0; - WriteHeader(db, /* headerOptions, */ headerOffset); - - if (encodeHeaders) - { - CByteBuffer buf(_countSize); - _outByte2.Init((Byte *)buf, _countSize); - - _countMode = false; - _writeToStream = false; - WriteHeader(db, /* headerOptions, */ headerOffset); - - if (_countSize != _outByte2.GetPos()) - return E_FAIL; - - CCompressionMethodMode encryptOptions; - encryptOptions.PasswordIsDefined = options->PasswordIsDefined; - encryptOptions.Password = options->Password; - CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); - CRecordVector packSizes; - CObjectVector folders; - COutFolders outFolders; - - RINOK(EncodeStream( - EXTERNAL_CODECS_LOC_VARS - encoder, buf, - packSizes, folders, outFolders)); - - _writeToStream = true; - - if (folders.Size() == 0) - throw 1; - - WriteID(NID::kEncodedHeader); - WritePackInfo(headerOffset, packSizes, CUInt32DefVector()); - WriteUnpackInfo(folders, outFolders); - WriteByte(NID::kEnd); - FOR_VECTOR (i, packSizes) - headerOffset += packSizes[i]; - } - RINOK(_outByte.Flush()); - headerCRC = CRC_GET_DIGEST(_crc); - headerSize = _outByte.GetProcessedSize(); - } - #ifdef _7Z_VOL - if (_endMarker) - { - CFinishHeader h; - h.NextHeaderSize = headerSize; - h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = - UInt64(0) - (headerSize + - 4 + kFinishHeaderSize); - h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; - h.AdditionalStartBlockSize = 0; - RINOK(WriteFinishHeader(h)); - return WriteFinishSignature(); - } - else - #endif - { - CStartHeader h; - h.NextHeaderSize = headerSize; - h.NextHeaderCRC = headerCRC; - h.NextHeaderOffset = headerOffset; - RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL)); - return WriteStartHeader(h); - } -} - -void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value) -{ - while (index >= Defs.Size()) - Defs.Add(false); - Defs[index] = defined; - if (!defined) - return; - while (index >= Vals.Size()) - Vals.Add(0); - Vals[index] = value; -} - -void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name) -{ - unsigned index = Files.Size(); - CTime.SetItem(index, file2.CTimeDefined, file2.CTime); - ATime.SetItem(index, file2.ATimeDefined, file2.ATime); - MTime.SetItem(index, file2.MTimeDefined, file2.MTime); - StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); - SetItem_Anti(index, file2.IsAnti); - // SetItem_Aux(index, file2.IsAux); - Names.Add(name); - Files.Add(file); -} - -}} +// 7zOut.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/AutoPtr.h" +// #include "../../../Common/UTFConvert.h" + +#include "../../Common/StreamObjects.h" +#include "../Common/OutStreamWithCRC.h" + +#include "7zOut.h" + +unsigned BoolVector_CountSum(const CBoolVector &v); + +static UInt64 UInt64Vector_CountSum(const CRecordVector &v) +{ + UInt64 sum = 0; + const unsigned size = v.Size(); + if (size) + { + const UInt64 *p = v.ConstData(); + const UInt64 * const lim = p + size; + do + sum += *p++; + while (p != lim); + } + return sum; +} + + +namespace NArchive { +namespace N7z { + +static void FillSignature(Byte *buf) +{ + memcpy(buf, kSignature, kSignatureSize); + buf[kSignatureSize] = kMajorVersion; + buf[kSignatureSize + 1] = 4; +} + +#ifdef Z7_7Z_VOL +HRESULT COutArchive::WriteFinishSignature() +{ + RINOK(WriteDirect(kFinishSignature, kSignatureSize)); + CArchiveVersion av; + av.Major = kMajorVersion; + av.Minor = 2; + RINOK(WriteDirectByte(av.Major)); + return WriteDirectByte(av.Minor); +} +#endif + +static void SetUInt32(Byte *p, UInt32 d) +{ + for (int i = 0; i < 4; i++, d >>= 8) + p[i] = (Byte)d; +} + +static void SetUInt64(Byte *p, UInt64 d) +{ + for (int i = 0; i < 8; i++, d >>= 8) + p[i] = (Byte)d; +} + +HRESULT COutArchive::WriteStartHeader(const CStartHeader &h) +{ + Byte buf[32]; + FillSignature(buf); + SetUInt64(buf + 8 + 4, h.NextHeaderOffset); + SetUInt64(buf + 8 + 12, h.NextHeaderSize); + SetUInt32(buf + 8 + 20, h.NextHeaderCRC); + SetUInt32(buf + 8, CrcCalc(buf + 8 + 4, 20)); + return WriteDirect(buf, sizeof(buf)); +} + +#ifdef Z7_7Z_VOL +HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h) +{ + CCRC crc; + crc.UpdateUInt64(h.NextHeaderOffset); + crc.UpdateUInt64(h.NextHeaderSize); + crc.UpdateUInt32(h.NextHeaderCRC); + crc.UpdateUInt64(h.ArchiveStartOffset); + crc.UpdateUInt64(h.AdditionalStartBlockSize); + RINOK(WriteDirectUInt32(crc.GetDigest())); + RINOK(WriteDirectUInt64(h.NextHeaderOffset)); + RINOK(WriteDirectUInt64(h.NextHeaderSize)); + RINOK(WriteDirectUInt32(h.NextHeaderCRC)); + RINOK(WriteDirectUInt64(h.ArchiveStartOffset)); + return WriteDirectUInt64(h.AdditionalStartBlockSize); +} +#endif + +HRESULT COutArchive::Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */) +{ + Close(); + #ifdef Z7_7Z_VOL + // endMarker = false; + _endMarker = endMarker; + #endif + SeqStream = stream; + // if (!endMarker) + { + SeqStream.QueryInterface(IID_IOutStream, &Stream); + if (!Stream) + { + return E_NOTIMPL; + // endMarker = true; + } + RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_signatureHeaderPos)) + Byte buf[32]; + FillSignature(buf); + memset(&buf[8], 0, 32 - 8); + return WriteDirect(buf, sizeof(buf)); + } + #ifdef Z7_7Z_VOL + if (endMarker) + { + /* + CStartHeader sh; + sh.NextHeaderOffset = (UInt32)(Int32)-1; + sh.NextHeaderSize = (UInt32)(Int32)-1; + sh.NextHeaderCRC = 0; + WriteStartHeader(sh); + return S_OK; + */ + } + #endif +} + +void COutArchive::Close() +{ + SeqStream.Release(); + Stream.Release(); +} + +UInt64 COutArchive::GetPos() const +{ + if (_countMode) + return _countSize; + if (_writeToStream) + return _outByte.GetProcessedSize(); + return _outByte2.GetPos(); +} + +void COutArchive::WriteBytes(const void *data, size_t size) +{ + if (_countMode) + _countSize += size; + else if (_writeToStream) + { + _outByte.WriteBytes(data, size); + // _crc = CrcUpdate(_crc, data, size); + } + else + _outByte2.WriteBytes(data, size); +} + +void COutArchive::WriteByte(Byte b) +{ + if (_countMode) + _countSize++; + else if (_writeToStream) + WriteByte_ToStream(b); + else + _outByte2.WriteByte(b); +} + +/* +void COutArchive::WriteUInt32(UInt32 value) +{ + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +void COutArchive::WriteUInt64(UInt64 value) +{ + for (int i = 0; i < 8; i++) + { + WriteByte((Byte)value); + value >>= 8; + } +} +*/ + +void COutArchive::WriteNumber(UInt64 value) +{ + Byte firstByte = 0; + Byte mask = 0x80; + int i; + for (i = 0; i < 8; i++) + { + if (value < ((UInt64(1) << ( 7 * (i + 1))))) + { + firstByte |= Byte(value >> (8 * i)); + break; + } + firstByte |= mask; + mask = (Byte)(mask >> 1); + } + WriteByte(firstByte); + for (; i > 0; i--) + { + WriteByte((Byte)value); + value >>= 8; + } +} + +static unsigned GetBigNumberSize(UInt64 value) +{ + unsigned i; + for (i = 1; i < 9; i++) + if (value < (((UInt64)1 << (i * 7)))) + break; + return i; +} + +#ifdef Z7_7Z_VOL +UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props) +{ + UInt32 result = GetBigNumberSize(dataSize) * 2 + 41; + if (nameLength != 0) + { + nameLength = (nameLength + 1) * 2; + result += nameLength + GetBigNumberSize(nameLength) + 2; + } + if (props) + { + result += 20; + } + if (result >= 128) + result++; + result += kSignatureSize + 2 + kFinishHeaderSize; + return result; +} + +UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props) +{ + UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props); + int testSize; + if (volSize > headersSizeBase) + testSize = volSize - headersSizeBase; + else + testSize = 1; + UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props); + UInt64 pureSize = 1; + if (volSize > headersSize) + pureSize = volSize - headersSize; + return pureSize; +} +#endif + +void COutArchive::WriteFolder(const CFolder &folder) +{ + WriteNumber(folder.Coders.Size()); + unsigned i; + + for (i = 0; i < folder.Coders.Size(); i++) + { + const CCoderInfo &coder = folder.Coders[i]; + { + UInt64 id = coder.MethodID; + unsigned idSize; + for (idSize = 1; idSize < sizeof(id); idSize++) + if ((id >> (8 * idSize)) == 0) + break; + // idSize &= 0xF; // idSize is smaller than 16 already + Byte temp[16]; + for (unsigned t = idSize; t != 0; t--, id >>= 8) + temp[t] = (Byte)(id & 0xFF); + + unsigned b = idSize; + const bool isComplex = !coder.IsSimpleCoder(); + b |= (isComplex ? 0x10 : 0); + + const size_t propsSize = coder.Props.Size(); + b |= ((propsSize != 0) ? 0x20 : 0); + temp[0] = (Byte)b; + WriteBytes(temp, idSize + 1); + if (isComplex) + { + WriteNumber(coder.NumStreams); + WriteNumber(1); // NumOutStreams; + } + if (propsSize == 0) + continue; + WriteNumber(propsSize); + WriteBytes(coder.Props, propsSize); + } + } + + for (i = 0; i < folder.Bonds.Size(); i++) + { + const CBond &bond = folder.Bonds[i]; + WriteNumber(bond.PackIndex); + WriteNumber(bond.UnpackIndex); + } + + if (folder.PackStreams.Size() > 1) + for (i = 0; i < folder.PackStreams.Size(); i++) + WriteNumber(folder.PackStreams[i]); +} + +void COutArchive::Write_BoolVector(const CBoolVector &boolVector) +{ + Byte b = 0; + Byte mask = 0x80; + FOR_VECTOR (i, boolVector) + { + if (boolVector[i]) + b |= mask; + mask = (Byte)(mask >> 1); + if (mask == 0) + { + WriteByte(b); + mask = 0x80; + b = 0; + } + } + if (mask != 0x80) + WriteByte(b); +} + +static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; } + +void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) +{ + WriteByte(id); + WriteNumber(Bv_GetSizeInBytes(boolVector)); + Write_BoolVector(boolVector); +} + +void COutArchive::Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined) +{ + if (numDefined == boolVector.Size()) + WriteByte(1); + else + { + WriteByte(0); + Write_BoolVector(boolVector); + } +} + + +void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) +{ + const unsigned numDefined = BoolVector_CountSum(digests.Defs); + if (numDefined == 0) + return; + WriteByte(NID::kCRC); + Write_BoolVector_numDefined(digests.Defs, numDefined); + Write_UInt32DefVector_numDefined(digests, numDefined); +} + + +void COutArchive::WritePackInfo( + UInt64 dataOffset, + const CRecordVector &packSizes, + const CUInt32DefVector &packCRCs) +{ + if (packSizes.IsEmpty()) + return; + WriteByte(NID::kPackInfo); + WriteNumber(dataOffset); + WriteNumber(packSizes.Size()); + WriteByte(NID::kSize); + FOR_VECTOR (i, packSizes) + WriteNumber(packSizes[i]); + + WriteHashDigests(packCRCs); + + WriteByte(NID::kEnd); +} + +void COutArchive::WriteUnpackInfo(const CObjectVector &folders, const COutFolders &outFolders) +{ + if (folders.IsEmpty()) + return; + + WriteByte(NID::kUnpackInfo); + + WriteByte(NID::kFolder); + WriteNumber(folders.Size()); + { + WriteByte(0); + FOR_VECTOR (i, folders) + WriteFolder(folders[i]); + } + + WriteByte(NID::kCodersUnpackSize); + FOR_VECTOR (i, outFolders.CoderUnpackSizes) + WriteNumber(outFolders.CoderUnpackSizes[i]); + + WriteHashDigests(outFolders.FolderUnpackCRCs); + + WriteByte(NID::kEnd); +} + +void COutArchive::WriteSubStreamsInfo(const CObjectVector &folders, + const COutFolders &outFolders, + const CRecordVector &unpackSizes, + const CUInt32DefVector &digests) +{ + const CRecordVector &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector; + WriteByte(NID::kSubStreamsInfo); + + unsigned i; + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + if (numUnpackStreamsInFolders[i] != 1) + { + WriteByte(NID::kNumUnpackStream); + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + WriteNumber(numUnpackStreamsInFolders[i]); + break; + } + + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + if (numUnpackStreamsInFolders[i] > 1) + { + WriteByte(NID::kSize); + CNum index = 0; + for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) + { + CNum num = numUnpackStreamsInFolders[i]; + for (CNum j = 0; j < num; j++) + { + if (j + 1 != num) + WriteNumber(unpackSizes[index]); + index++; + } + } + break; + } + + CUInt32DefVector digests2; + + unsigned digestIndex = 0; + for (i = 0; i < folders.Size(); i++) + { + unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i]; + if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i)) + digestIndex++; + else + for (unsigned j = 0; j < numSubStreams; j++, digestIndex++) + { + digests2.Defs.Add(digests.Defs[digestIndex]); + digests2.Vals.Add(digests.Vals[digestIndex]); + } + } + WriteHashDigests(digests2); + WriteByte(NID::kEnd); +} + +// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field. + +void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts) +{ + if (!_useAlign) + return; + + const unsigned alignSize = (unsigned)1 << alignShifts; + pos += (unsigned)GetPos(); + pos &= (alignSize - 1); + if (pos == 0) + return; + unsigned skip = alignSize - pos; + if (skip < 2) + skip += alignSize; + skip -= 2; + WriteByte(NID::kDummy); + WriteByte((Byte)skip); + for (unsigned i = 0; i < skip; i++) + WriteByte(0); +} + +void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts) +{ + const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v); + const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2; + SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts); + + WriteByte(type); + WriteNumber(dataSize); + Write_BoolVector_numDefined(v, numDefined); + WriteByte(0); // 0 means no switching to external stream +} + + +void COutArchive::Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined) +{ + if (_countMode) + { + _countSize += (size_t)numDefined * 4; + return; + } + + const bool * const defs = v.Defs.ConstData(); + const UInt32 * const vals = v.Vals.ConstData(); + const size_t num = v.Defs.Size(); + + for (size_t i = 0; i < num; i++) + if (defs[i]) + { + UInt32 value = vals[i]; + for (int k = 0; k < 4; k++) + { + if (_writeToStream) + WriteByte_ToStream((Byte)value); + else + _outByte2.WriteByte((Byte)value); + // WriteByte((Byte)value); + value >>= 8; + } + // WriteUInt32(v.Vals[i]); + } +} + + +void COutArchive::Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type) +{ + const unsigned numDefined = BoolVector_CountSum(v.Defs); + if (numDefined == 0) + return; + + WriteAlignedBools(v.Defs, numDefined, type, 3); + + if (_countMode) + { + _countSize += (size_t)numDefined * 8; + return; + } + + const bool * const defs = v.Defs.ConstData(); + const UInt64 * const vals = v.Vals.ConstData(); + const size_t num = v.Defs.Size(); + + for (size_t i = 0; i < num; i++) + if (defs[i]) + { + UInt64 value = vals[i]; + for (int k = 0; k < 8; k++) + { + if (_writeToStream) + WriteByte_ToStream((Byte)value); + else + _outByte2.WriteByte((Byte)value); + // WriteByte((Byte)value); + value >>= 8; + } + // WriteUInt64(v.Vals[i]); + } +} + + +HRESULT COutArchive::EncodeStream( + DECL_EXTERNAL_CODECS_LOC_VARS + CEncoder &encoder, const CByteBuffer &data, + CRecordVector &packSizes, CObjectVector &folders, COutFolders &outFolders) +{ + CMyComPtr2_Create streamSpec; + streamSpec->Init(data, data.Size()); + outFolders.FolderUnpackCRCs.Defs.Add(true); + outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); + // outFolders.NumUnpackStreamsVector.Add(1); + const UInt64 dataSize64 = data.Size(); + const UInt64 expectSize = data.Size(); + RINOK(encoder.Encode1( + EXTERNAL_CODECS_LOC_VARS + streamSpec, + // NULL, + &dataSize64, // inSizeForReduce + expectSize, + folders.AddNew(), + // outFolders.CoderUnpackSizes, unpackSize, + SeqStream, packSizes, NULL)) + if (!streamSpec->WasFinished()) + return E_FAIL; + encoder.Encode_Post(dataSize64, outFolders.CoderUnpackSizes); + return S_OK; +} + +void COutArchive::WriteHeader( + const CArchiveDatabaseOut &db, + // const CHeaderOptions &headerOptions, + UInt64 &headerOffset) +{ + /* + bool thereIsSecure = (db.SecureBuf.Size() != 0); + */ + _useAlign = true; + + headerOffset = UInt64Vector_CountSum(db.PackSizes); + + WriteByte(NID::kHeader); + + /* + { + // It's example for per archive properies writing + + WriteByte(NID::kArchiveProperties); + + // you must use random 40-bit number that will identify you + // then you can use same kDeveloperID for any properties and methods + const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number + + #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID) + + { + const UInt64 kSubID = 0x1; // you can use small number for subID + const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); + WriteNumber(kID); + const unsigned kPropsSize = 3; // it's example size + WriteNumber(kPropsSize); + for (unsigned i = 0; i < kPropsSize; i++) + WriteByte((Byte)(i & 0xFF)); + } + { + const UInt64 kSubID = 0x2; // you can use small number for subID + const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID); + WriteNumber(kID); + const unsigned kPropsSize = 5; // it's example size + WriteNumber(kPropsSize); + for (unsigned i = 0; i < kPropsSize; i++) + WriteByte((Byte)(i + 16)); + } + WriteByte(NID::kEnd); + } + */ + + if (db.Folders.Size() > 0) + { + WriteByte(NID::kMainStreamsInfo); + WritePackInfo(0, db.PackSizes, db.PackCRCs); + WriteUnpackInfo(db.Folders, (const COutFolders &)db); + + CRecordVector unpackSizes; + CUInt32DefVector digests; + FOR_VECTOR (i, db.Files) + { + const CFileItem &file = db.Files[i]; + if (!file.HasStream) + continue; + unpackSizes.Add(file.Size); + digests.Defs.Add(file.CrcDefined); + digests.Vals.Add(file.Crc); + } + + WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests); + WriteByte(NID::kEnd); + } + + if (db.Files.IsEmpty()) + { + WriteByte(NID::kEnd); + return; + } + + WriteByte(NID::kFilesInfo); + WriteNumber(db.Files.Size()); + + { + /* ---------- Empty Streams ---------- */ + CBoolVector emptyStreamVector; + emptyStreamVector.ClearAndSetSize(db.Files.Size()); + unsigned numEmptyStreams = 0; + { + FOR_VECTOR (i, db.Files) + if (db.Files[i].HasStream) + emptyStreamVector[i] = false; + else + { + emptyStreamVector[i] = true; + numEmptyStreams++; + } + } + + if (numEmptyStreams != 0) + { + WritePropBoolVector(NID::kEmptyStream, emptyStreamVector); + + CBoolVector emptyFileVector, antiVector; + emptyFileVector.ClearAndSetSize(numEmptyStreams); + antiVector.ClearAndSetSize(numEmptyStreams); + bool thereAreEmptyFiles = false, thereAreAntiItems = false; + unsigned cur = 0; + + FOR_VECTOR (i, db.Files) + { + const CFileItem &file = db.Files[i]; + if (file.HasStream) + continue; + emptyFileVector[cur] = !file.IsDir; + if (!file.IsDir) + thereAreEmptyFiles = true; + bool isAnti = db.IsItemAnti(i); + antiVector[cur] = isAnti; + if (isAnti) + thereAreAntiItems = true; + cur++; + } + + if (thereAreEmptyFiles) + WritePropBoolVector(NID::kEmptyFile, emptyFileVector); + if (thereAreAntiItems) + WritePropBoolVector(NID::kAnti, antiVector); + } + } + + + { + /* ---------- Names ---------- */ + + size_t namesDataSize = 0; + { + FOR_VECTOR (i, db.Files) + { + const UString &name = db.Names[i]; + const size_t numUtfChars = + /* + #if WCHAR_MAX > 0xffff + Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); + #else + */ + name.Len(); + // #endif + namesDataSize += numUtfChars; + } + } + if (namesDataSize) + { + namesDataSize += db.Files.Size(); // we will write tail zero wchar for each name + namesDataSize *= 2; // 2 bytes per wchar for UTF16 encoding + namesDataSize++; // for additional switch byte (zero value) + SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); + WriteByte(NID::kName); + WriteNumber(namesDataSize); + + if (_countMode) + _countSize += namesDataSize; + else + { + WriteByte(0); + FOR_VECTOR (i, db.Files) + { + const UString &name = db.Names[i]; + const wchar_t *p = name.Ptr(); + const size_t len = (size_t)name.Len() + 1; + const wchar_t * const lim = p + len; + if (_writeToStream) + { + do + { + const wchar_t c = *p++; + WriteByte_ToStream((Byte)c); + WriteByte_ToStream((Byte)(c >> 8)); + } + while (p != lim); + } + else + { + Byte *dest = _outByte2.GetDest_and_Update(len * 2); + do + { + /* + #if WCHAR_MAX > 0xffff + if (c >= 0x10000) + { + c -= 0x10000; + if (c < (1 << 20)) + { + unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); + WriteByte((Byte)c0); + WriteByte((Byte)(c0 >> 8)); + c = 0xdc00 + (c & 0x3FF); + } + else + c = '_'; // we change character unsupported by UTF16 + } + #endif + */ + const wchar_t c = *p++; + SetUi16(dest, (UInt16)c) + dest += 2; + } + while (p != lim); + } + } + } + } + } + + /* if (headerOptions.WriteCTime) */ Write_UInt64DefVector_type(db.CTime, NID::kCTime); + /* if (headerOptions.WriteATime) */ Write_UInt64DefVector_type(db.ATime, NID::kATime); + /* if (headerOptions.WriteMTime) */ Write_UInt64DefVector_type(db.MTime, NID::kMTime); + Write_UInt64DefVector_type(db.StartPos, NID::kStartPos); + + { + /* ---------- Write Attrib ---------- */ + const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); + if (numDefined != 0) + { + WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); + Write_UInt32DefVector_numDefined(db.Attrib, numDefined); + } + } + + /* + { + // ---------- Write IsAux ---------- + if (BoolVector_CountSum(db.IsAux) != 0) + WritePropBoolVector(NID::kIsAux, db.IsAux); + } + + { + // ---------- Write Parent ---------- + CBoolVector boolVector; + boolVector.Reserve(db.Files.Size()); + unsigned numIsDir = 0; + unsigned numParentLinks = 0; + for (i = 0; i < db.Files.Size(); i++) + { + const CFileItem &file = db.Files[i]; + bool defined = !file.IsAltStream; + boolVector.Add(defined); + if (defined) + numIsDir++; + if (file.Parent >= 0) + numParentLinks++; + } + if (numParentLinks > 0) + { + // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2); + const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector); + const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1; + SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2); + + WriteByte(NID::kParent); + WriteNumber(dataSize); + Write_BoolVector_numDefined(boolVector, numIsDir); + for (i = 0; i < db.Files.Size(); i++) + { + const CFileItem &file = db.Files[i]; + // if (file.Parent >= 0) + WriteUInt32(file.Parent); + } + } + } + + if (thereIsSecure) + { + UInt64 secureDataSize = 1 + 4 + + db.SecureBuf.Size() + + db.SecureSizes.Size() * 4; + // secureDataSize += db.SecureIDs.Size() * 4; + for (i = 0; i < db.SecureIDs.Size(); i++) + secureDataSize += GetBigNumberSize(db.SecureIDs[i]); + SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2); + WriteByte(NID::kNtSecure); + WriteNumber(secureDataSize); + WriteByte(0); + WriteUInt32(db.SecureSizes.Size()); + for (i = 0; i < db.SecureSizes.Size(); i++) + WriteUInt32(db.SecureSizes[i]); + WriteBytes(db.SecureBuf, db.SecureBuf.Size()); + for (i = 0; i < db.SecureIDs.Size(); i++) + { + WriteNumber(db.SecureIDs[i]); + // WriteUInt32(db.SecureIDs[i]); + } + } + */ + + WriteByte(NID::kEnd); // for files + WriteByte(NID::kEnd); // for headers +} + +HRESULT COutArchive::WriteDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + const CArchiveDatabaseOut &db, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions) +{ + if (!db.CheckNumFiles()) + return E_FAIL; + + CStartHeader sh; + sh.NextHeaderOffset = 0; + sh.NextHeaderSize = 0; + sh.NextHeaderCRC = 0; // CrcCalc(NULL, 0); + + if (!db.IsEmpty()) + { + CMyComPtr2_Create crcStream; + crcStream->SetStream(SeqStream); + crcStream->Init(); + + bool encodeHeaders = false; + if (options) + if (options->IsEmpty()) + options = NULL; + if (options) + if (options->PasswordIsDefined || headerOptions.CompressMainHeader) + encodeHeaders = true; + + if (!_outByte.Create(1 << 16)) + return E_OUTOFMEMORY; + _outByte.SetStream(crcStream.Interface()); + _outByte.Init(); + // _crc = CRC_INIT_VAL; + _countMode = encodeHeaders; + _writeToStream = true; + _countSize = 0; + WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); + + if (encodeHeaders) + { + CByteBuffer buf(_countSize); + _outByte2.Init((Byte *)buf, _countSize); + + _countMode = false; + _writeToStream = false; + WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); + + if (_countSize != _outByte2.GetPos()) + return E_FAIL; + + CCompressionMethodMode encryptOptions; + encryptOptions.PasswordIsDefined = options->PasswordIsDefined; + encryptOptions.Password = options->Password; + CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions); + CRecordVector packSizes; + CObjectVector folders; + COutFolders outFolders; + + RINOK(EncodeStream( + EXTERNAL_CODECS_LOC_VARS + encoder, buf, + packSizes, folders, outFolders)) + + _writeToStream = true; + + if (folders.Size() == 0) + throw 1; + + WriteID(NID::kEncodedHeader); + WritePackInfo(sh.NextHeaderOffset, packSizes, CUInt32DefVector()); + WriteUnpackInfo(folders, outFolders); + WriteByte(NID::kEnd); + + sh.NextHeaderOffset += UInt64Vector_CountSum(packSizes); + } + RINOK(_outByte.Flush()) + sh.NextHeaderCRC = crcStream->GetCRC(); + // sh.NextHeaderCRC = CRC_GET_DIGEST(_crc); + // if (CRC_GET_DIGEST(_crc) != sh.NextHeaderCRC) throw 1; + sh.NextHeaderSize = _outByte.GetProcessedSize(); + } + #ifdef Z7_7Z_VOL + if (_endMarker) + { + CFinishHeader h; + h.NextHeaderSize = headerSize; + h.NextHeaderCRC = headerCRC; + h.NextHeaderOffset = + UInt64(0) - (headerSize + + 4 + kFinishHeaderSize); + h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset; + h.AdditionalStartBlockSize = 0; + RINOK(WriteFinishHeader(h)); + return WriteFinishSignature(); + } + else + #endif + if (Stream) + { + RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) + return WriteStartHeader(sh); + } + return S_OK; +} + +void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value) +{ + while (index >= Defs.Size()) + Defs.Add(false); + Defs[index] = defined; + if (!defined) + return; + while (index >= Vals.Size()) + Vals.Add(0); + Vals[index] = value; +} + +void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value) +{ + while (index >= Defs.Size()) + Defs.Add(false); + Defs[index] = defined; + if (!defined) + return; + while (index >= Vals.Size()) + Vals.Add(0); + Vals[index] = value; +} + +void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name) +{ + unsigned index = Files.Size(); + CTime.SetItem(index, file2.CTimeDefined, file2.CTime); + ATime.SetItem(index, file2.ATimeDefined, file2.ATime); + MTime.SetItem(index, file2.MTimeDefined, file2.MTime); + StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos); + Attrib.SetItem(index, file2.AttribDefined, file2.Attrib); + SetItem_Anti(index, file2.IsAnti); + // SetItem_Aux(index, file2.IsAux); + Names.Add(name); + Files.Add(file); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zOut.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zOut.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zOut.h 2023-11-25 15:00:00.000000000 +0000 @@ -1,321 +1,346 @@ -// 7zOut.h - -#ifndef __7Z_OUT_H -#define __7Z_OUT_H - -#include "7zCompressionMode.h" -#include "7zEncode.h" -#include "7zHeader.h" -#include "7zItem.h" - -#include "../../Common/OutBuffer.h" -#include "../../Common/StreamUtils.h" - -namespace NArchive { -namespace N7z { - -class CWriteBufferLoc -{ - Byte *_data; - size_t _size; - size_t _pos; -public: - CWriteBufferLoc(): _size(0), _pos(0) {} - void Init(Byte *data, size_t size) - { - _data = data; - _size = size; - _pos = 0; - } - void WriteBytes(const void *data, size_t size) - { - if (size == 0) - return; - if (size > _size - _pos) - throw 1; - memcpy(_data + _pos, data, size); - _pos += size; - } - void WriteByte(Byte b) - { - if (_size == _pos) - throw 1; - _data[_pos++] = b; - } - size_t GetPos() const { return _pos; } -}; - -struct CHeaderOptions -{ - bool CompressMainHeader; - /* - bool WriteCTime; - bool WriteATime; - bool WriteMTime; - */ - - CHeaderOptions(): - CompressMainHeader(true) - /* - , WriteCTime(false) - , WriteATime(false) - , WriteMTime(true) - */ - {} -}; - - -struct CFileItem2 -{ - UInt64 CTime; - UInt64 ATime; - UInt64 MTime; - UInt64 StartPos; - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool StartPosDefined; - bool IsAnti; - // bool IsAux; - - void Init() - { - CTimeDefined = false; - ATimeDefined = false; - MTimeDefined = false; - StartPosDefined = false; - IsAnti = false; - // IsAux = false; - } -}; - -struct COutFolders -{ - CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. - - CRecordVector NumUnpackStreamsVector; - CRecordVector CoderUnpackSizes; // including unpack sizes of bond coders - - void OutFoldersClear() - { - FolderUnpackCRCs.Clear(); - NumUnpackStreamsVector.Clear(); - CoderUnpackSizes.Clear(); - } - - void OutFoldersReserveDown() - { - FolderUnpackCRCs.ReserveDown(); - NumUnpackStreamsVector.ReserveDown(); - CoderUnpackSizes.ReserveDown(); - } -}; - -struct CArchiveDatabaseOut: public COutFolders -{ - CRecordVector PackSizes; - CUInt32DefVector PackCRCs; - CObjectVector Folders; - - CRecordVector Files; - UStringVector Names; - CUInt64DefVector CTime; - CUInt64DefVector ATime; - CUInt64DefVector MTime; - CUInt64DefVector StartPos; - CRecordVector IsAnti; - - /* - CRecordVector IsAux; - - CByteBuffer SecureBuf; - CRecordVector SecureSizes; - CRecordVector SecureIDs; - - void ClearSecure() - { - SecureBuf.Free(); - SecureSizes.Clear(); - SecureIDs.Clear(); - } - */ - - void Clear() - { - OutFoldersClear(); - - PackSizes.Clear(); - PackCRCs.Clear(); - Folders.Clear(); - - Files.Clear(); - Names.Clear(); - CTime.Clear(); - ATime.Clear(); - MTime.Clear(); - StartPos.Clear(); - IsAnti.Clear(); - - /* - IsAux.Clear(); - ClearSecure(); - */ - } - - void ReserveDown() - { - OutFoldersReserveDown(); - - PackSizes.ReserveDown(); - PackCRCs.ReserveDown(); - Folders.ReserveDown(); - - Files.ReserveDown(); - Names.ReserveDown(); - CTime.ReserveDown(); - ATime.ReserveDown(); - MTime.ReserveDown(); - StartPos.ReserveDown(); - IsAnti.ReserveDown(); - - /* - IsAux.ReserveDown(); - */ - } - - bool IsEmpty() const - { - return ( - PackSizes.IsEmpty() && - NumUnpackStreamsVector.IsEmpty() && - Folders.IsEmpty() && - Files.IsEmpty()); - } - - bool CheckNumFiles() const - { - unsigned size = Files.Size(); - return ( - CTime.CheckSize(size) && - ATime.CheckSize(size) && - MTime.CheckSize(size) && - StartPos.CheckSize(size) && - (size == IsAnti.Size() || IsAnti.Size() == 0)); - } - - bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } - // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } - - void SetItem_Anti(unsigned index, bool isAnti) - { - while (index >= IsAnti.Size()) - IsAnti.Add(false); - IsAnti[index] = isAnti; - } - /* - void SetItem_Aux(unsigned index, bool isAux) - { - while (index >= IsAux.Size()) - IsAux.Add(false); - IsAux[index] = isAux; - } - */ - - void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); -}; - -class COutArchive -{ - UInt64 _prefixHeaderPos; - - HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } - - UInt64 GetPos() const; - void WriteBytes(const void *data, size_t size); - void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } - void WriteByte(Byte b); - void WriteUInt32(UInt32 value); - void WriteUInt64(UInt64 value); - void WriteNumber(UInt64 value); - void WriteID(UInt64 value) { WriteNumber(value); } - - void WriteFolder(const CFolder &folder); - HRESULT WriteFileHeader(const CFileItem &itemInfo); - void WriteBoolVector(const CBoolVector &boolVector); - void WritePropBoolVector(Byte id, const CBoolVector &boolVector); - - void WriteHashDigests(const CUInt32DefVector &digests); - - void WritePackInfo( - UInt64 dataOffset, - const CRecordVector &packSizes, - const CUInt32DefVector &packCRCs); - - void WriteUnpackInfo( - const CObjectVector &folders, - const COutFolders &outFolders); - - void WriteSubStreamsInfo( - const CObjectVector &folders, - const COutFolders &outFolders, - const CRecordVector &unpackSizes, - const CUInt32DefVector &digests); - - void SkipAlign(unsigned pos, unsigned alignSize); - void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize); - void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); - - HRESULT EncodeStream( - DECL_EXTERNAL_CODECS_LOC_VARS - CEncoder &encoder, const CByteBuffer &data, - CRecordVector &packSizes, CObjectVector &folders, COutFolders &outFolders); - void WriteHeader( - const CArchiveDatabaseOut &db, - // const CHeaderOptions &headerOptions, - UInt64 &headerOffset); - - bool _countMode; - bool _writeToStream; - size_t _countSize; - UInt32 _crc; - COutBuffer _outByte; - CWriteBufferLoc _outByte2; - - #ifdef _7Z_VOL - bool _endMarker; - #endif - - bool _useAlign; - - HRESULT WriteSignature(); - #ifdef _7Z_VOL - HRESULT WriteFinishSignature(); - #endif - HRESULT WriteStartHeader(const CStartHeader &h); - #ifdef _7Z_VOL - HRESULT WriteFinishHeader(const CFinishHeader &h); - #endif - CMyComPtr Stream; -public: - - COutArchive() { _outByte.Create(1 << 16); } - CMyComPtr SeqStream; - HRESULT Create(ISequentialOutStream *stream, bool endMarker); - void Close(); - HRESULT SkipPrefixArchiveHeader(); - HRESULT WriteDatabase( - DECL_EXTERNAL_CODECS_LOC_VARS - const CArchiveDatabaseOut &db, - const CCompressionMethodMode *options, - const CHeaderOptions &headerOptions); - - #ifdef _7Z_VOL - static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); - static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); - #endif - -}; - -}} - -#endif +// 7zOut.h + +#ifndef ZIP7_INC_7Z_OUT_H +#define ZIP7_INC_7Z_OUT_H + +#include "7zCompressionMode.h" +#include "7zEncode.h" +#include "7zHeader.h" +#include "7zItem.h" + +#include "../../Common/OutBuffer.h" +#include "../../Common/StreamUtils.h" + +namespace NArchive { +namespace N7z { + +const unsigned k_StartHeadersRewriteSize = 32; + +class CWriteBufferLoc +{ + Byte *_data; + Byte *_dataLim; + Byte *_dataBase; +public: + // CWriteBufferLoc(): _data(NULL), _dataLim(NULL), _dataBase(NULL) {} + void Init(Byte *data, size_t size) + { + _data = data; + _dataBase = data; + _dataLim = data + size; + } + + Byte *GetDest_and_Update(size_t size) + { + Byte *dest = _data; + if (size > (size_t)(_dataLim - dest)) + throw 1; + _data = dest + size; + return dest; + } + void WriteBytes(const void *data, size_t size) + { + if (size == 0) + return; + Byte *dest = GetDest_and_Update(size); + memcpy(dest, data, size); + } + void WriteByte(Byte b) + { + Byte *dest = _data; + if (dest == _dataLim) + throw 1; + *dest++ = b; + _data = dest; + } + size_t GetPos() const { return (size_t)(_data - _dataBase); } +}; + + +struct CHeaderOptions +{ + bool CompressMainHeader; + /* + bool WriteCTime; + bool WriteATime; + bool WriteMTime; + */ + + CHeaderOptions(): + CompressMainHeader(true) + /* + , WriteCTime(false) + , WriteATime(false) + , WriteMTime(true) + */ + {} +}; + + +struct CFileItem2 +{ + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; + UInt64 StartPos; + UInt32 Attrib; + + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool StartPosDefined; + bool AttribDefined; + bool IsAnti; + // bool IsAux; + + /* + void Init() + { + CTimeDefined = false; + ATimeDefined = false; + MTimeDefined = false; + StartPosDefined = false; + AttribDefined = false; + IsAnti = false; + // IsAux = false; + } + */ +}; + + +struct COutFolders +{ + CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. + + CRecordVector NumUnpackStreamsVector; + CRecordVector CoderUnpackSizes; // including unpack sizes of bond coders + + void OutFoldersClear() + { + FolderUnpackCRCs.Clear(); + NumUnpackStreamsVector.Clear(); + CoderUnpackSizes.Clear(); + } + + void OutFoldersReserveDown() + { + FolderUnpackCRCs.ReserveDown(); + NumUnpackStreamsVector.ReserveDown(); + CoderUnpackSizes.ReserveDown(); + } +}; + + +struct CArchiveDatabaseOut: public COutFolders +{ + CRecordVector PackSizes; + CUInt32DefVector PackCRCs; + CObjectVector Folders; + + CRecordVector Files; + UStringVector Names; + CUInt64DefVector CTime; + CUInt64DefVector ATime; + CUInt64DefVector MTime; + CUInt64DefVector StartPos; + CUInt32DefVector Attrib; + CBoolVector IsAnti; + + /* + CBoolVector IsAux; + + CByteBuffer SecureBuf; + CRecordVector SecureSizes; + CRecordVector SecureIDs; + + void ClearSecure() + { + SecureBuf.Free(); + SecureSizes.Clear(); + SecureIDs.Clear(); + } + */ + + void Clear() + { + OutFoldersClear(); + + PackSizes.Clear(); + PackCRCs.Clear(); + Folders.Clear(); + + Files.Clear(); + Names.Clear(); + CTime.Clear(); + ATime.Clear(); + MTime.Clear(); + StartPos.Clear(); + Attrib.Clear(); + IsAnti.Clear(); + + /* + IsAux.Clear(); + ClearSecure(); + */ + } + + void ReserveDown() + { + OutFoldersReserveDown(); + + PackSizes.ReserveDown(); + PackCRCs.ReserveDown(); + Folders.ReserveDown(); + + Files.ReserveDown(); + Names.ReserveDown(); + CTime.ReserveDown(); + ATime.ReserveDown(); + MTime.ReserveDown(); + StartPos.ReserveDown(); + Attrib.ReserveDown(); + IsAnti.ReserveDown(); + + /* + IsAux.ReserveDown(); + */ + } + + bool IsEmpty() const + { + return ( + PackSizes.IsEmpty() && + NumUnpackStreamsVector.IsEmpty() && + Folders.IsEmpty() && + Files.IsEmpty()); + } + + bool CheckNumFiles() const + { + unsigned size = Files.Size(); + return ( + CTime.CheckSize(size) + && ATime.CheckSize(size) + && MTime.CheckSize(size) + && StartPos.CheckSize(size) + && Attrib.CheckSize(size) + && (size == IsAnti.Size() || IsAnti.Size() == 0)); + } + + bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } + // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } + + void SetItem_Anti(unsigned index, bool isAnti) + { + while (index >= IsAnti.Size()) + IsAnti.Add(false); + IsAnti[index] = isAnti; + } + /* + void SetItem_Aux(unsigned index, bool isAux) + { + while (index >= IsAux.Size()) + IsAux.Add(false); + IsAux[index] = isAux; + } + */ + + void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); +}; + + +class COutArchive +{ + HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } + + UInt64 GetPos() const; + void WriteBytes(const void *data, size_t size); + void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } + void WriteByte(Byte b); + void WriteByte_ToStream(Byte b) + { + _outByte.WriteByte(b); + // _crc = CRC_UPDATE_BYTE(_crc, b); + } + // void WriteUInt32(UInt32 value); + // void WriteUInt64(UInt64 value); + void WriteNumber(UInt64 value); + void WriteID(UInt64 value) { WriteNumber(value); } + + void WriteFolder(const CFolder &folder); + HRESULT WriteFileHeader(const CFileItem &itemInfo); + void Write_BoolVector(const CBoolVector &boolVector); + void Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined); + void WritePropBoolVector(Byte id, const CBoolVector &boolVector); + + void WriteHashDigests(const CUInt32DefVector &digests); + + void WritePackInfo( + UInt64 dataOffset, + const CRecordVector &packSizes, + const CUInt32DefVector &packCRCs); + + void WriteUnpackInfo( + const CObjectVector &folders, + const COutFolders &outFolders); + + void WriteSubStreamsInfo( + const CObjectVector &folders, + const COutFolders &outFolders, + const CRecordVector &unpackSizes, + const CUInt32DefVector &digests); + + void SkipToAligned(unsigned pos, unsigned alignShifts); + void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts); + void Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined); + void Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type); + + HRESULT EncodeStream( + DECL_EXTERNAL_CODECS_LOC_VARS + CEncoder &encoder, const CByteBuffer &data, + CRecordVector &packSizes, CObjectVector &folders, COutFolders &outFolders); + void WriteHeader( + const CArchiveDatabaseOut &db, + // const CHeaderOptions &headerOptions, + UInt64 &headerOffset); + + bool _countMode; + bool _writeToStream; + bool _useAlign; + #ifdef Z7_7Z_VOL + bool _endMarker; + #endif + // UInt32 _crc; + size_t _countSize; + CWriteBufferLoc _outByte2; + COutBuffer _outByte; + UInt64 _signatureHeaderPos; + CMyComPtr Stream; + + #ifdef Z7_7Z_VOL + HRESULT WriteFinishSignature(); + HRESULT WriteFinishHeader(const CFinishHeader &h); + #endif + HRESULT WriteStartHeader(const CStartHeader &h); + +public: + CMyComPtr SeqStream; + + // COutArchive(); + HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */); + void Close(); + HRESULT WriteDatabase( + DECL_EXTERNAL_CODECS_LOC_VARS + const CArchiveDatabaseOut &db, + const CCompressionMethodMode *options, + const CHeaderOptions &headerOptions); + + #ifdef Z7_7Z_VOL + static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); + static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); + #endif +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zProperties.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zProperties.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.cpp 2023-03-29 09:00:00.000000000 +0000 @@ -1,174 +1,182 @@ -// 7zProperties.cpp - -#include "StdAfx.h" - -#include "7zProperties.h" -#include "7zHeader.h" -#include "7zHandler.h" - -// #define _MULTI_PACK - -namespace NArchive { -namespace N7z { - -struct CPropMap -{ - UInt32 FilePropID; - CStatProp StatProp; -}; - -static const CPropMap kPropMap[] = -{ - { NID::kName, { NULL, kpidPath, VT_BSTR } }, - { NID::kSize, { NULL, kpidSize, VT_UI8 } }, - { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, - - #ifdef _MULTI_PACK - { 100, { "Pack0", kpidPackedSize0, VT_UI8 } }, - { 101, { "Pack1", kpidPackedSize1, VT_UI8 } }, - { 102, { "Pack2", kpidPackedSize2, VT_UI8 } }, - { 103, { "Pack3", kpidPackedSize3, VT_UI8 } }, - { 104, { "Pack4", kpidPackedSize4, VT_UI8 } }, - #endif - - { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, - { NID::kMTime, { NULL, kpidMTime, VT_FILETIME } }, - { NID::kATime, { NULL, kpidATime, VT_FILETIME } }, - { NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } }, - { NID::kStartPos, { NULL, kpidPosition, VT_UI8 } }, - - { NID::kCRC, { NULL, kpidCRC, VT_UI4 } }, - -// { NID::kIsAux, { NULL, kpidIsAux, VT_BOOL } }, - { NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } } - - #ifndef _SFX - , - { 97, { NULL, kpidEncrypted, VT_BOOL } }, - { 98, { NULL, kpidMethod, VT_BSTR } }, - { 99, { NULL, kpidBlock, VT_UI4 } } - #endif -}; - -static void CopyOneItem(CRecordVector &src, - CRecordVector &dest, UInt32 item) -{ - FOR_VECTOR (i, src) - if (src[i] == item) - { - dest.Add(item); - src.Delete(i); - return; - } -} - -static void RemoveOneItem(CRecordVector &src, UInt32 item) -{ - FOR_VECTOR (i, src) - if (src[i] == item) - { - src.Delete(i); - return; - } -} - -static void InsertToHead(CRecordVector &dest, UInt32 item) -{ - FOR_VECTOR (i, dest) - if (dest[i] == item) - { - dest.Delete(i); - break; - } - dest.Insert(0, item); -} - -#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id); - -void CHandler::FillPopIDs() -{ - _fileInfoPopIDs.Clear(); - - #ifdef _7Z_VOL - if (_volumes.Size() < 1) - return; - const CVolume &volume = _volumes.Front(); - const CArchiveDatabaseEx &_db = volume.Database; - #endif - - CRecordVector fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs; - - RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); - RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); - /* - RemoveOneItem(fileInfoPopIDs, NID::kParent); - RemoveOneItem(fileInfoPopIDs, NID::kNtSecure); - */ - - COPY_ONE_ITEM(kName); - COPY_ONE_ITEM(kAnti); - COPY_ONE_ITEM(kSize); - COPY_ONE_ITEM(kPackInfo); - COPY_ONE_ITEM(kCTime); - COPY_ONE_ITEM(kMTime); - COPY_ONE_ITEM(kATime); - COPY_ONE_ITEM(kWinAttrib); - COPY_ONE_ITEM(kCRC); - COPY_ONE_ITEM(kComment); - - _fileInfoPopIDs += fileInfoPopIDs; - - #ifndef _SFX - _fileInfoPopIDs.Add(97); - _fileInfoPopIDs.Add(98); - _fileInfoPopIDs.Add(99); - #endif - - #ifdef _MULTI_PACK - _fileInfoPopIDs.Add(100); - _fileInfoPopIDs.Add(101); - _fileInfoPopIDs.Add(102); - _fileInfoPopIDs.Add(103); - _fileInfoPopIDs.Add(104); - #endif - - #ifndef _SFX - InsertToHead(_fileInfoPopIDs, NID::kMTime); - InsertToHead(_fileInfoPopIDs, NID::kPackInfo); - InsertToHead(_fileInfoPopIDs, NID::kSize); - InsertToHead(_fileInfoPopIDs, NID::kName); - #endif -} - -STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) -{ - *numProps = _fileInfoPopIDs.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) -{ - if (index >= _fileInfoPopIDs.Size()) - return E_INVALIDARG; - UInt64 id = _fileInfoPopIDs[index]; - for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++) - { - const CPropMap &pr = kPropMap[i]; - if (pr.FilePropID == id) - { - const CStatProp &st = pr.StatProp; - *propID = st.PropID; - *varType = st.vt; - /* - if (st.lpwstrName) - *name = ::SysAllocString(st.lpwstrName); - else - */ - *name = NULL; - return S_OK; - } - } - return E_INVALIDARG; -} - -}} +// 7zProperties.cpp + +#include "StdAfx.h" + +#include "7zHandler.h" +#include "7zProperties.h" + +namespace NArchive { +namespace N7z { + +struct CPropMap +{ + Byte FilePropID; + // CStatProp StatProp; + VARTYPE vt; + UInt32 StatPropID; +}; + +// #define STAT_PROP(name, id, vt) { name, id, vt } +#define STAT_PROP(name, id, vt) vt, id + +#define STAT_PROP2(id, vt) STAT_PROP(NULL, id, vt) + +#define k_7z_id_Encrypted 97 +#define k_7z_id_Method 98 +#define k_7z_id_Block 99 + +static const CPropMap kPropMap[] = +{ + { NID::kName, STAT_PROP2(kpidPath, VT_BSTR) }, + { NID::kSize, STAT_PROP2(kpidSize, VT_UI8) }, + { NID::kPackInfo, STAT_PROP2(kpidPackSize, VT_UI8) }, + + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES +#define k_7z_id_PackedSize0 100 + { k_7z_id_PackedSize0 + 0, STAT_PROP("Pack0", kpidPackedSize0, VT_UI8) }, + { k_7z_id_PackedSize0 + 1, STAT_PROP("Pack1", kpidPackedSize1, VT_UI8) }, + { k_7z_id_PackedSize0 + 2, STAT_PROP("Pack2", kpidPackedSize2, VT_UI8) }, + { k_7z_id_PackedSize0 + 3, STAT_PROP("Pack3", kpidPackedSize3, VT_UI8) }, + { k_7z_id_PackedSize0 + 4, STAT_PROP("Pack4", kpidPackedSize4, VT_UI8) }, + #endif + + { NID::kCTime, STAT_PROP2(kpidCTime, VT_FILETIME) }, + { NID::kMTime, STAT_PROP2(kpidMTime, VT_FILETIME) }, + { NID::kATime, STAT_PROP2(kpidATime, VT_FILETIME) }, + { NID::kWinAttrib, STAT_PROP2(kpidAttrib, VT_UI4) }, + { NID::kStartPos, STAT_PROP2(kpidPosition, VT_UI8) }, + + { NID::kCRC, STAT_PROP2(kpidCRC, VT_UI4) }, + // { NID::kIsAux, STAT_PROP2(kpidIsAux, VT_BOOL) }, + { NID::kAnti, STAT_PROP2(kpidIsAnti, VT_BOOL) } + + #ifndef Z7_SFX + , { k_7z_id_Encrypted, STAT_PROP2(kpidEncrypted, VT_BOOL) } + , { k_7z_id_Method, STAT_PROP2(kpidMethod, VT_BSTR) } + , { k_7z_id_Block, STAT_PROP2(kpidBlock, VT_UI4) } + #endif +}; + +static void CopyOneItem(CRecordVector &src, + CRecordVector &dest, const UInt32 item) +{ + FOR_VECTOR (i, src) + if (src[i] == item) + { + dest.Add(item); + src.Delete(i); + return; + } +} + +static void RemoveOneItem(CRecordVector &src, const UInt32 item) +{ + FOR_VECTOR (i, src) + if (src[i] == item) + { + src.Delete(i); + return; + } +} + +static void InsertToHead(CRecordVector &dest, const UInt32 item) +{ + FOR_VECTOR (i, dest) + if (dest[i] == item) + { + dest.Delete(i); + break; + } + dest.Insert(0, item); +} + +#define COPY_ONE_ITEM(id) CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::id); + +void CHandler::FillPopIDs() +{ + _fileInfoPopIDs.Clear(); + + #ifdef Z7_7Z_VOL + if (_volumes.Size() < 1) + return; + const CVolume &volume = _volumes.Front(); + const CArchiveDatabaseEx &_db = volume.Database; + #endif + + CRecordVector fileInfoPopIDs = _db.ArcInfo.FileInfoPopIDs; + + RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream); + RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile); + /* + RemoveOneItem(fileInfoPopIDs, NID::kParent); + RemoveOneItem(fileInfoPopIDs, NID::kNtSecure); + */ + + COPY_ONE_ITEM(kName) + COPY_ONE_ITEM(kAnti) + COPY_ONE_ITEM(kSize) + COPY_ONE_ITEM(kPackInfo) + COPY_ONE_ITEM(kCTime) + COPY_ONE_ITEM(kMTime) + COPY_ONE_ITEM(kATime) + COPY_ONE_ITEM(kWinAttrib) + COPY_ONE_ITEM(kCRC) + COPY_ONE_ITEM(kComment) + + _fileInfoPopIDs += fileInfoPopIDs; + + #ifndef Z7_SFX + _fileInfoPopIDs.Add(k_7z_id_Encrypted); + _fileInfoPopIDs.Add(k_7z_id_Method); + _fileInfoPopIDs.Add(k_7z_id_Block); + #endif + + #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES + for (unsigned i = 0; i < 5; i++) + _fileInfoPopIDs.Add(k_7z_id_PackedSize0 + i); + #endif + + #ifndef Z7_SFX + InsertToHead(_fileInfoPopIDs, NID::kMTime); + InsertToHead(_fileInfoPopIDs, NID::kPackInfo); + InsertToHead(_fileInfoPopIDs, NID::kSize); + InsertToHead(_fileInfoPopIDs, NID::kName); + #endif +} + +Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps)) +{ + *numProps = _fileInfoPopIDs.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) +{ + if (index >= _fileInfoPopIDs.Size()) + return E_INVALIDARG; + const UInt64 id = _fileInfoPopIDs[index]; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPropMap); i++) + { + const CPropMap &pr = kPropMap[i]; + if (pr.FilePropID == id) + { + *propID = pr.StatPropID; + *varType = pr.vt; + /* + const CStatProp &st = pr.StatProp; + *propID = st.PropID; + *varType = st.vt; + */ + /* + if (st.lpwstrName) + *name = ::SysAllocString(st.lpwstrName); + else + */ + *name = NULL; + return S_OK; + } + } + return E_INVALIDARG; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zProperties.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zProperties.h 2008-08-14 09:11:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zProperties.h 2023-03-29 09:00:00.000000000 +0000 @@ -1,22 +1,26 @@ -// 7zProperties.h - -#ifndef __7Z_PROPERTIES_H -#define __7Z_PROPERTIES_H - -#include "../../PropID.h" - -namespace NArchive { -namespace N7z { - -enum -{ - kpidPackedSize0 = kpidUserDefined, - kpidPackedSize1, - kpidPackedSize2, - kpidPackedSize3, - kpidPackedSize4 -}; - -}} - -#endif +// 7zProperties.h + +#ifndef ZIP7_INC_7Z_PROPERTIES_H +#define ZIP7_INC_7Z_PROPERTIES_H + +#include "../../PropID.h" + +namespace NArchive { +namespace N7z { + +// #define Z7_7Z_SHOW_PACK_STREAMS_SIZES // for debug + +#ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES +enum +{ + kpidPackedSize0 = kpidUserDefined, + kpidPackedSize1, + kpidPackedSize2, + kpidPackedSize3, + kpidPackedSize4 +}; +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zRegister.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zRegister.cpp 2022-08-17 05:00:00.000000000 +0000 @@ -1,21 +1,27 @@ -// 7zRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "7zHandler.h" - -namespace NArchive { -namespace N7z { - -static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; - -REGISTER_ARC_IO_DECREMENT_SIG( - "7z", "7z", NULL, 7, - k_Signature_Dec, - 0, - NArcInfoFlags::kFindSignature, - NULL); - -}} +// 7zRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "7zHandler.h" + +namespace NArchive { +namespace N7z { + +static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C}; + +REGISTER_ARC_IO_DECREMENT_SIG( + "7z", "7z", NULL, 7, + k_Signature_Dec, + 0, + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zSpecStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zSpecStream.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.cpp 2023-03-29 06:00:00.000000000 +0000 @@ -1,22 +1,31 @@ -// 7zSpecStream.cpp - -#include "StdAfx.h" - -#include "7zSpecStream.h" - -STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return result; -} - -STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value) -{ - if (!_getSubStreamSize) - return E_NOTIMPL; - return _getSubStreamSize->GetSubStreamSize(subStream, value); -} +// 7zSpecStream.cpp + +#include "StdAfx.h" + +#include "7zSpecStream.h" + +/* +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + if (!_getSubStreamSize) + return E_NOTIMPL; + return _getSubStreamSize->GetSubStreamSize(subStream, value); +} + +Z7_COM7F_IMF(CSequentialInStreamSizeCount2::GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +{ + if (!_compressGetSubStreamSize) + return E_NOTIMPL; + return _compressGetSubStreamSize->GetNextInSubStream(streamIndexRes, stream); +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zSpecStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zSpecStream.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zSpecStream.h 2023-03-29 06:00:00.000000000 +0000 @@ -1,35 +1,49 @@ -// 7zSpecStream.h - -#ifndef __7Z_SPEC_STREAM_H -#define __7Z_SPEC_STREAM_H - -#include "../../../Common/MyCom.h" - -#include "../../ICoder.h" - -class CSequentialInStreamSizeCount2: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ - CMyComPtr _stream; - CMyComPtr _getSubStreamSize; - UInt64 _size; -public: - void Init(ISequentialInStream *stream) - { - _size = 0; - _getSubStreamSize.Release(); - _stream = stream; - _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); - } - UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); -}; - -#endif +// 7zSpecStream.h + +#ifndef ZIP7_INC_7Z_SPEC_STREAM_H +#define ZIP7_INC_7Z_SPEC_STREAM_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" + +/* +#define Z7_COM_QI_ENTRY_AG_2(i, sub0, sub) else if (iid == IID_ ## i) \ + { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ + { i *ti = this; *outObject = ti; } } + +class CSequentialInStreamSizeCount2 Z7_final: + public ISequentialInStream, + public ICompressGetSubStreamSize, + public ICompressInSubStreams, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ISequentialInStream) + Z7_COM_QI_ENTRY(ICompressGetSubStreamSize) + Z7_COM_QI_ENTRY_AG_2(ISequentialInStream, _stream, _compressGetSubStreamSize) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressGetSubStreamSize) + Z7_IFACE_COM7_IMP(ICompressInSubStreams) + + CMyComPtr _stream; + CMyComPtr _getSubStreamSize; + CMyComPtr _compressGetSubStreamSize; + UInt64 _size; +public: + void Init(ISequentialInStream *stream) + { + _size = 0; + _getSubStreamSize.Release(); + _compressGetSubStreamSize.Release(); + _stream = stream; + _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize); + _stream.QueryInterface(IID_ICompressInSubStreams, &_compressGetSubStreamSize); + } + UInt64 GetSize() const { return _size; } +}; +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zUpdate.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zUpdate.cpp 2016-05-20 08:31:41.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.cpp 2024-06-19 05:00:00.000000000 +0000 @@ -1,2512 +1,3088 @@ -// 7zUpdate.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/Wildcard.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "../Common/ItemNameUtils.h" - -#include "7zDecode.h" -#include "7zEncode.h" -#include "7zFolderInStream.h" -#include "7zHandler.h" -#include "7zOut.h" -#include "7zUpdate.h" - -#ifndef WIN32 -#include "Windows/FileIO.h" -#endif - -namespace NArchive { -namespace N7z { - - -#define k_X86 k_BCJ - -struct CFilterMode -{ - UInt32 Id; - UInt32 Delta; - - CFilterMode(): Id(0), Delta(0) {} - - void SetDelta() - { - if (Id == k_IA64) - Delta = 16; - else if (Id == k_ARM || Id == k_PPC || Id == k_PPC) - Delta = 4; - else if (Id == k_ARMT) - Delta = 2; - else - Delta = 0; - } -}; - - -/* ---------- PE ---------- */ - -#define MZ_SIG 0x5A4D - -#define PE_SIG 0x00004550 -#define PE_OptHeader_Magic_32 0x10B -#define PE_OptHeader_Magic_64 0x20B -#define PE_SectHeaderSize 40 -#define PE_SECT_EXECUTE 0x20000000 - -static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) -{ - if (size < 512 || GetUi16(buf) != MZ_SIG) - return 0; - - const Byte *p; - UInt32 peOffset, optHeaderSize, filterId; - - peOffset = GetUi32(buf + 0x3C); - if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0) - return 0; - p = buf + peOffset; - if (GetUi32(p) != PE_SIG) - return 0; - p += 4; - - switch (GetUi16(p)) - { - case 0x014C: - case 0x8664: filterId = k_X86; break; - - /* - IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE - IMAGE_FILE_MACHINE_THUMB 0x01C2 // ARM Thumb / Thumb-2 LE - IMAGE_FILE_MACHINE_ARMNT 0x01C4 // ARM Thumb-2, LE - Note: We use ARM filter for 0x01C2. (WinCE 5 - 0x01C2) files mostly contain ARM code (not Thumb/Thumb-2). - */ - - case 0x01C0: // WinCE old - case 0x01C2: filterId = k_ARM; break; // WinCE new - case 0x01C4: filterId = k_ARMT; break; // WinRT - - case 0x0200: filterId = k_IA64; break; - default: return 0; - } - - optHeaderSize = GetUi16(p + 16); - if (optHeaderSize > (1 << 10)) - return 0; - - p += 20; /* headerSize */ - - switch (GetUi16(p)) - { - case PE_OptHeader_Magic_32: - case PE_OptHeader_Magic_64: - break; - default: - return 0; - } - - filterMode->Id = filterId; - return 1; -} - - -/* ---------- ELF ---------- */ - -#define ELF_SIG 0x464C457F - -#define ELF_CLASS_32 1 -#define ELF_CLASS_64 2 - -#define ELF_DATA_2LSB 1 -#define ELF_DATA_2MSB 2 - -static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } -static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); } -// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); } - -static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) -{ - Bool /* is32, */ be; - UInt32 filterId; - - if (size < 512 || buf[6] != 1) /* ver */ - return 0; - - if (GetUi32(buf) != ELF_SIG) - return 0; - - switch (buf[4]) - { - case ELF_CLASS_32: /* is32 = True; */ break; - case ELF_CLASS_64: /* is32 = False; */ break; - default: return 0; - } - - switch (buf[5]) - { - case ELF_DATA_2LSB: be = False; break; - case ELF_DATA_2MSB: be = True; break; - default: return 0; - } - - switch (Get16(buf + 0x12, be)) - { - case 3: - case 6: - case 62: filterId = k_X86; break; - case 2: - case 18: - case 43: filterId = k_SPARC; break; - case 20: - case 21: if (!be) return 0; filterId = k_PPC; break; - case 40: if ( be) return 0; filterId = k_ARM; break; - - /* Some IA-64 ELF exacutable have size that is not aligned for 16 bytes. - So we don't use IA-64 filter for IA-64 ELF */ - // case 50: if ( be) return 0; filterId = k_IA64; break; - - default: return 0; - } - - filterMode->Id = filterId; - return 1; -} - - - -/* ---------- Mach-O ---------- */ - -#define MACH_SIG_BE_32 0xCEFAEDFE -#define MACH_SIG_BE_64 0xCFFAEDFE -#define MACH_SIG_LE_32 0xFEEDFACE -#define MACH_SIG_LE_64 0xFEEDFACF - -#define MACH_ARCH_ABI64 (1 << 24) -#define MACH_MACHINE_386 7 -#define MACH_MACHINE_ARM 12 -#define MACH_MACHINE_SPARC 14 -#define MACH_MACHINE_PPC 18 -#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) -#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) - -static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode) -{ - UInt32 filterId, numCommands, commandsSize; - - if (size < 512) - return 0; - - Bool /* mode64, */ be; - switch (GetUi32(buf)) - { - case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break; - case MACH_SIG_BE_64: /* mode64 = True; */ be = True; break; - case MACH_SIG_LE_32: /* mode64 = False; */ be = False; break; - case MACH_SIG_LE_64: /* mode64 = True; */ be = False; break; - default: return 0; - } - - switch (Get32(buf + 4, be)) - { - case MACH_MACHINE_386: - case MACH_MACHINE_AMD64: filterId = k_X86; break; - case MACH_MACHINE_ARM: if ( be) return 0; filterId = k_ARM; break; - case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break; - case MACH_MACHINE_PPC: - case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break; - default: return 0; - } - - numCommands = Get32(buf + 0x10, be); - commandsSize = Get32(buf + 0x14, be); - - if (commandsSize > (1 << 24) || numCommands > (1 << 18)) - return 0; - - filterMode->Id = filterId; - return 1; -} - - -/* ---------- WAV ---------- */ - -#define WAV_SUBCHUNK_fmt 0x20746D66 -#define WAV_SUBCHUNK_data 0x61746164 - -#define RIFF_SIG 0x46464952 - -static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) -{ - UInt32 subChunkSize, pos; - if (size < 0x2C) - return False; - - if (GetUi32(buf + 0) != RIFF_SIG || - GetUi32(buf + 8) != 0x45564157 || // WAVE - GetUi32(buf + 0xC) != WAV_SUBCHUNK_fmt) - return False; - subChunkSize = GetUi32(buf + 0x10); - /* [0x14 = format] = 1 (PCM) */ - if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1) - return False; - - unsigned numChannels = GetUi16(buf + 0x16); - unsigned bitsPerSample = GetUi16(buf + 0x22); - - if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256) - return False; - - pos = 0x14 + subChunkSize; - - const int kNumSubChunksTests = 10; - // Do we need to scan more than 3 sub-chunks? - for (int i = 0; i < kNumSubChunksTests; i++) - { - if (pos + 8 > size) - return False; - subChunkSize = GetUi32(buf + pos + 4); - if (GetUi32(buf + pos) == WAV_SUBCHUNK_data) - { - unsigned delta = numChannels * (bitsPerSample >> 3); - if (delta >= 256) - return False; - filterMode->Id = k_Delta; - filterMode->Delta = delta; - return True; - } - if (subChunkSize > (1 << 16)) - return False; - pos += subChunkSize + 8; - } - return False; -} - -static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) -{ - filterMode->Id = 0; - filterMode->Delta = 0; - - if (Parse_EXE(buf, size, filterMode)) return True; - if (Parse_ELF(buf, size, filterMode)) return True; - if (Parse_MACH(buf, size, filterMode)) return True; - return Parse_WAV(buf, size, filterMode); -} - - - - -struct CFilterMode2: public CFilterMode -{ - bool Encrypted; - unsigned GroupIndex; - - CFilterMode2(): Encrypted(false) {} - - int Compare(const CFilterMode2 &m) const - { - if (!Encrypted) - { - if (m.Encrypted) - return -1; - } - else if (!m.Encrypted) - return 1; - - if (Id < m.Id) return -1; - if (Id > m.Id) return 1; - - if (Delta < m.Delta) return -1; - if (Delta > m.Delta) return 1; - - return 0; - } - - bool operator ==(const CFilterMode2 &m) const - { - return Id == m.Id && Delta == m.Delta && Encrypted == m.Encrypted; - } -}; - -static unsigned GetGroup(CRecordVector &filters, const CFilterMode2 &m) -{ - unsigned i; - for (i = 0; i < filters.Size(); i++) - { - const CFilterMode2 &m2 = filters[i]; - if (m == m2) - return i; - /* - if (m.Encrypted != m2.Encrypted) - { - if (!m.Encrypted) - break; - continue; - } - - if (m.Id < m2.Id) break; - if (m.Id != m2.Id) continue; - - if (m.Delta < m2.Delta) break; - if (m.Delta != m2.Delta) continue; - */ - } - // filters.Insert(i, m); - // return i; - return filters.Add(m); -} - -static inline bool Is86Filter(CMethodId m) -{ - return (m == k_BCJ || m == k_BCJ2); -} - -static inline bool IsExeFilter(CMethodId m) -{ - switch (m) - { - case k_BCJ: - case k_BCJ2: - case k_ARM: - case k_ARMT: - case k_PPC: - case k_SPARC: - case k_IA64: - return true; - } - return false; -} - -static unsigned Get_FilterGroup_for_Folder( - CRecordVector &filters, const CFolderEx &f, bool extractFilter) -{ - CFilterMode2 m; - m.Id = 0; - m.Delta = 0; - m.Encrypted = f.IsEncrypted(); - - if (extractFilter) - { - const CCoderInfo &coder = f.Coders[f.UnpackCoder]; - - if (coder.MethodID == k_Delta) - { - if (coder.Props.Size() == 1) - { - m.Delta = (unsigned)coder.Props[0] + 1; - m.Id = k_Delta; - } - } - else if (IsExeFilter(coder.MethodID)) - { - m.Id = (UInt32)coder.MethodID; - if (m.Id == k_BCJ2) - m.Id = k_BCJ; - m.SetDelta(); - } - } - - return GetGroup(filters, m); -} - - - - -static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, - UInt64 position, UInt64 size, ICompressProgressInfo *progress) -{ - RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLimited(streamSpec); - streamSpec->SetStream(inStream); - streamSpec->Init(size); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL); -} - -/* -unsigned CUpdateItem::GetExtensionPos() const -{ - int slashPos = Name.ReverseFind_PathSepar(); - int dotPos = Name.ReverseFind_Dot(); - if (dotPos <= slashPos) - return Name.Len(); - return dotPos + 1; -} - -UString CUpdateItem::GetExtension() const -{ - return Name.Ptr(GetExtensionPos()); -} -*/ - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b)) - -/* -static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) -{ - size_t c1 = a1.GetCapacity(); - size_t c2 = a2.GetCapacity(); - RINOZ_COMP(c1, c2); - for (size_t i = 0; i < c1; i++) - RINOZ_COMP(a1[i], a2[i]); - return 0; -} - -static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2) -{ - RINOZ_COMP(c1.NumInStreams, c2.NumInStreams); - RINOZ_COMP(c1.NumOutStreams, c2.NumOutStreams); - RINOZ_COMP(c1.MethodID, c2.MethodID); - return CompareBuffers(c1.Props, c2.Props); -} - -static int CompareBonds(const CBond &b1, const CBond &b2) -{ - RINOZ_COMP(b1.InIndex, b2.InIndex); - return MyCompare(b1.OutIndex, b2.OutIndex); -} - -static int CompareFolders(const CFolder &f1, const CFolder &f2) -{ - int s1 = f1.Coders.Size(); - int s2 = f2.Coders.Size(); - RINOZ_COMP(s1, s2); - int i; - for (i = 0; i < s1; i++) - RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i])); - s1 = f1.Bonds.Size(); - s2 = f2.Bonds.Size(); - RINOZ_COMP(s1, s2); - for (i = 0; i < s1; i++) - RINOZ(CompareBonds(f1.Bonds[i], f2.Bonds[i])); - return 0; -} -*/ - -/* -static int CompareFiles(const CFileItem &f1, const CFileItem &f2) -{ - return CompareFileNames(f1.Name, f2.Name); -} -*/ - -struct CFolderRepack -{ - unsigned FolderIndex; - CNum NumCopyFiles; -}; - -/* -static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *) -{ - int i1 = p1->FolderIndex; - int i2 = p2->FolderIndex; - // In that version we don't want to parse folders here, so we don't compare folders - // probably it must be improved in future - // const CDbEx &db = *(const CDbEx *)param; - // RINOZ(CompareFolders( - // db.Folders[i1], - // db.Folders[i2])); - - return MyCompare(i1, i2); - - // RINOZ_COMP( - // db.NumUnpackStreamsVector[i1], - // db.NumUnpackStreamsVector[i2]); - // if (db.NumUnpackStreamsVector[i1] == 0) - // return 0; - // return CompareFiles( - // db.Files[db.FolderStartFileIndex[i1]], - // db.Files[db.FolderStartFileIndex[i2]]); -} -*/ - -/* - we sort empty files and dirs in such order: - - Dir.NonAnti (name sorted) - - File.NonAnti (name sorted) - - File.Anti (name sorted) - - Dir.Anti (reverse name sorted) -*/ - -static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param) -{ - const CObjectVector &updateItems = *(const CObjectVector *)param; - const CUpdateItem &u1 = updateItems[*p1]; - const CUpdateItem &u2 = updateItems[*p2]; - // NonAnti < Anti - if (u1.IsAnti != u2.IsAnti) - return (u1.IsAnti ? 1 : -1); - if (u1.IsDir != u2.IsDir) - { - // Dir.NonAnti < File < Dir.Anti - if (u1.IsDir) - return (u1.IsAnti ? 1 : -1); - return (u2.IsAnti ? -1 : 1); - } - int n = CompareFileNames(u1.Name, u2.Name); - return (u1.IsDir && u1.IsAnti) ? -n : n; -} - -static const char *g_Exts = - " 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo" - " zip jar ear war msi" - " 3gp avi mov mpeg mpg mpe wmv" - " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav" - " swf" - " chm hxi hxs" - " gif jpeg jpg jp2 png tiff bmp ico psd psp" - " awg ps eps cgm dxf svg vrml wmf emf ai md" - " cad dwg pps key sxi" - " max 3ds" - " iso bin nrg mdf img pdi tar cpio xpi" - " vfd vhd vud vmc vsv" - " vmdk dsk nvram vmem vmsd vmsn vmss vmtm" - " inl inc idl acf asa" - " h hpp hxx c cpp cxx m mm go swift" - " rc java cs rs pas bas vb cls ctl frm dlg def" - " f77 f f90 f95" - " asm s" - " sql manifest dep" - " mak clw csproj vcproj sln dsp dsw" - " class" - " bat cmd bash sh" - " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" - " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs" - " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf" - " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf" - " abw afp cwk lwp wpd wps wpt wrf wri" - " abf afm bdf fon mgf otf pcf pfa snf ttf" - " dbf mdb nsf ntf wdb db fdb gdb" - " exe dll ocx vbx sfx sys tlb awx com obj lib out o so" - " pdb pch idb ncb opt"; - -static unsigned GetExtIndex(const char *ext) -{ - unsigned extIndex = 1; - const char *p = g_Exts; - for (;;) - { - char c = *p++; - if (c == 0) - return extIndex; - if (c == ' ') - continue; - unsigned pos = 0; - for (;;) - { - char c2 = ext[pos++]; - if (c2 == 0 && (c == 0 || c == ' ')) - return extIndex; - if (c != c2) - break; - c = *p++; - } - extIndex++; - for (;;) - { - if (c == 0) - return extIndex; - if (c == ' ') - break; - c = *p++; - } - } -} - -struct CRefItem -{ - const CUpdateItem *UpdateItem; - UInt32 Index; - unsigned ExtensionPos; - unsigned NamePos; - unsigned ExtensionIndex; - - CRefItem() {}; - CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): - UpdateItem(&ui), - Index(index), - ExtensionPos(0), - NamePos(0), - ExtensionIndex(0) - { - if (sortByType) - { - int slashPos = ui.Name.ReverseFind_PathSepar(); - NamePos = slashPos + 1; - int dotPos = ui.Name.ReverseFind_Dot(); - if (dotPos <= slashPos) - ExtensionPos = ui.Name.Len(); - else - { - ExtensionPos = dotPos + 1; - if (ExtensionPos != ui.Name.Len()) - { - AString s; - for (unsigned pos = ExtensionPos;; pos++) - { - wchar_t c = ui.Name[pos]; - if (c >= 0x80) - break; - if (c == 0) - { - ExtensionIndex = GetExtIndex(s); - break; - } - s += (char)MyCharLower_Ascii((char)c); - } - } - } - } - } -}; - -struct CSortParam -{ - // const CObjectVector *TreeFolders; - bool SortByType; -}; - -/* - we sort files in such order: - - Dir.NonAnti (name sorted) - - alt streams - - Dirs - - Dir.Anti (reverse name sorted) -*/ - - -static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param) -{ - const CRefItem &a1 = *p1; - const CRefItem &a2 = *p2; - const CUpdateItem &u1 = *a1.UpdateItem; - const CUpdateItem &u2 = *a2.UpdateItem; - - /* - if (u1.IsAltStream != u2.IsAltStream) - return u1.IsAltStream ? 1 : -1; - */ - - // Actually there are no dirs that time. They were stored in other steps - // So that code is unused? - if (u1.IsDir != u2.IsDir) - return u1.IsDir ? 1 : -1; - if (u1.IsDir) - { - if (u1.IsAnti != u2.IsAnti) - return (u1.IsAnti ? 1 : -1); - int n = CompareFileNames(u1.Name, u2.Name); - return -n; - } - - // bool sortByType = *(bool *)param; - const CSortParam *sortParam = (const CSortParam *)param; - bool sortByType = sortParam->SortByType; - if (sortByType) - { - RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))); - RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))); - if (!u1.MTimeDefined && u2.MTimeDefined) return 1; - if (u1.MTimeDefined && !u2.MTimeDefined) return -1; - if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime); - RINOZ_COMP(u1.Size, u2.Size); - } - /* - int par1 = a1.UpdateItem->ParentFolderIndex; - int par2 = a2.UpdateItem->ParentFolderIndex; - const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1]; - const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2]; - - int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd; - int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd; - if (b1 < b2) - { - if (e1 <= b2) - return -1; - // p2 in p1 - int par = par2; - for (;;) - { - const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; - par = tf.Parent; - if (par == par1) - { - RINOZ(CompareFileNames(u1.Name, tf.Name)); - break; - } - } - } - else if (b2 < b1) - { - if (e2 <= b1) - return 1; - // p1 in p2 - int par = par1; - for (;;) - { - const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; - par = tf.Parent; - if (par == par2) - { - RINOZ(CompareFileNames(tf.Name, u2.Name)); - break; - } - } - } - */ - // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex); - RINOK(CompareFileNames(u1.Name, u2.Name)); - RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient); - RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive); - return 0; -} - -struct CSolidGroup -{ - CRecordVector Indices; - - CRecordVector folderRefs; -}; - -static const char *g_ExeExts[] = -{ - "dll" - , "exe" - , "ocx" - , "sfx" - , "sys" -}; - -static bool IsExeExt(const wchar_t *ext) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_ExeExts); i++) - if (StringsAreEqualNoCase_Ascii(ext, g_ExeExts[i])) - return true; - return false; -} - -#ifndef _WIN32 -static bool IsExeFile(const CUpdateItem &ui) -{ - int dotPos = ui.Name.ReverseFind(L'.'); - if (dotPos >= 0) - if (IsExeExt(ui.Name.Ptr(dotPos + 1)) ) return true; - - if (ui.Attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) { - unsigned short st_mode = ui.Attrib >> 16; - if ((st_mode & 00111) && (ui.Size >= 2048)) - { - // file has the execution flag and it's big enought - // try to find if the file is a script - NWindows::NFile::NIO::CInFile file; - if (file.Open(ui.Name)) - { - char buffer[2048]; - UINT32 processedSize; - if (file.Read(buffer,sizeof(buffer),processedSize)) - { - for(UInt32 i = 0; i < processedSize ; i++) - { - if (buffer[i] == 0) - { - return true; // this file is not a text (ascii, utf8, ...) ! - } - } - } - } - } - } - return false; -} -#endif - -struct CAnalysis -{ - CMyComPtr Callback; - CByteBuffer Buffer; - - bool ParseWav; - bool ParseExe; - bool ParseAll; - - CAnalysis(): - ParseWav(true), - ParseExe(false), - ParseAll(false) - {} - - HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode); -}; - -static const size_t kAnalysisBufSize = 1 << 14; - -HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode) -{ - filterMode.Id = 0; - filterMode.Delta = 0; - - CFilterMode filterModeTemp = filterMode; - - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); - - // if (dotPos > slashPos) - { - bool needReadFile = ParseAll; - - bool probablyIsSameIsa = false; - - if (!needReadFile || !Callback) - { - const wchar_t *ext; - if (dotPos > slashPos) - ext = ui.Name.Ptr(dotPos + 1); - else - ext = ui.Name.RightPtr(0); - - // p7zip uses the trick to store posix attributes in high 16 bits - if (ui.Attrib & 0x8000) - { - unsigned st_mode = ui.Attrib >> 16; - // st_mode = 00111; - if ((st_mode & 00111) && (ui.Size >= 2048)) - { - #ifndef _WIN32 - probablyIsSameIsa = true; - #endif - needReadFile = true; - } - } - -#ifdef _WIN32 - if (IsExeExt(ext)) -#else - if (IsExeFile(ui)) -#endif - { - needReadFile = true; - #ifdef _WIN32 - probablyIsSameIsa = true; - needReadFile = ParseExe; - #endif - } - else if (StringsAreEqualNoCase_Ascii(ext, "wav")) - { - needReadFile = ParseWav; - } - /* - else if (!needReadFile && ParseUnixExt) - { - if (StringsAreEqualNoCase_Ascii(ext, "so") - || StringsAreEqualNoCase_Ascii(ext, "")) - - needReadFile = true; - } - */ - } - - if (needReadFile && Callback) - { - if (Buffer.Size() != kAnalysisBufSize) - { - Buffer.Alloc(kAnalysisBufSize); - } - { - CMyComPtr stream; - HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze); - if (result == S_OK && stream) - { - size_t size = kAnalysisBufSize; - result = ReadStream(stream, Buffer, &size); - stream.Release(); - // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK)); - if (result == S_OK) - { - Bool parseRes = ParseFile(Buffer, size, &filterModeTemp); - if (parseRes && filterModeTemp.Delta == 0) - { - filterModeTemp.SetDelta(); - if (filterModeTemp.Delta != 0 && filterModeTemp.Id != k_Delta) - { - if (ui.Size % filterModeTemp.Delta != 0) - { - parseRes = false; - } - } - } - if (!parseRes) - { - filterModeTemp.Id = 0; - filterModeTemp.Delta = 0; - } - } - } - } - } - else if ((needReadFile && !Callback) || probablyIsSameIsa) - { - #ifdef MY_CPU_X86_OR_AMD64 - if (probablyIsSameIsa) - filterModeTemp.Id = k_X86; - #endif - } - } - - filterMode = filterModeTemp; - return S_OK; -} - -static inline void GetMethodFull(UInt64 methodID, UInt32 numStreams, CMethodFull &m) -{ - m.Id = methodID; - m.NumStreams = numStreams; -} - -static HRESULT AddBondForFilter(CCompressionMethodMode &mode) -{ - for (unsigned c = 1; c < mode.Methods.Size(); c++) - { - if (!mode.IsThereBond_to_Coder(c)) - { - CBond2 bond; - bond.OutCoder = 0; - bond.OutStream = 0; - bond.InCoder = c; - mode.Bonds.Add(bond); - return S_OK; - } - } - return E_INVALIDARG; -} - -static HRESULT AddFilterBond(CCompressionMethodMode &mode) -{ - if (!mode.Bonds.IsEmpty()) - return AddBondForFilter(mode); - return S_OK; -} - -static HRESULT AddBcj2Methods(CCompressionMethodMode &mode) -{ - // mode.Methods[0] must be k_BCJ2 method ! - - CMethodFull m; - GetMethodFull(k_LZMA, 1, m); - - m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20); - m.AddProp32(NCoderPropID::kNumFastBytes, 128); - m.AddProp32(NCoderPropID::kNumThreads, 1); - m.AddProp32(NCoderPropID::kLitPosBits, 2); - m.AddProp32(NCoderPropID::kLitContextBits, 0); - // m.AddProp_Ascii(NCoderPropID::kMatchFinder, "BT2"); - - unsigned methodIndex = mode.Methods.Size(); - - if (mode.Bonds.IsEmpty()) - { - for (unsigned i = 1; i + 1 < mode.Methods.Size(); i++) - { - CBond2 bond; - bond.OutCoder = i; - bond.OutStream = 0; - bond.InCoder = i + 1; - mode.Bonds.Add(bond); - } - } - - mode.Methods.Add(m); - mode.Methods.Add(m); - - RINOK(AddBondForFilter(mode)); - CBond2 bond; - bond.OutCoder = 0; - bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond); - bond.InCoder = methodIndex + 1; bond.OutStream = 2; mode.Bonds.Add(bond); - return S_OK; -} - -static HRESULT MakeExeMethod(CCompressionMethodMode &mode, - const CFilterMode &filterMode, /* bool addFilter, */ bool bcj2Filter) -{ - if (mode.Filter_was_Inserted) - { - const CMethodFull &m = mode.Methods[0]; - CMethodId id = m.Id; - if (id == k_BCJ2) - return AddBcj2Methods(mode); - if (!m.IsSimpleCoder()) - return E_NOTIMPL; - // if (Bonds.IsEmpty()) we can create bonds later - return AddFilterBond(mode); - } - - if (filterMode.Id == 0) - return S_OK; - - CMethodFull &m = mode.Methods.InsertNew(0); - - { - FOR_VECTOR(k, mode.Bonds) - { - CBond2 &bond = mode.Bonds[k]; - bond.InCoder++; - bond.OutCoder++; - } - } - - HRESULT res; - - if (bcj2Filter && Is86Filter(filterMode.Id)) - { - GetMethodFull(k_BCJ2, 4, m); - res = AddBcj2Methods(mode); - } - else - { - GetMethodFull(filterMode.Id, 1, m); - if (filterMode.Id == k_Delta) - m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta); - res = AddFilterBond(mode); - - int alignBits = -1; - if (filterMode.Id == k_Delta || filterMode.Delta != 0) - { - if (filterMode.Delta == 1) alignBits = 0; - else if (filterMode.Delta == 2) alignBits = 1; - else if (filterMode.Delta == 4) alignBits = 2; - else if (filterMode.Delta == 8) alignBits = 3; - else if (filterMode.Delta == 16) alignBits = 4; - } - else - { - // alignBits = GetAlignForFilterMethod(filterMode.Id); - } - - if (res == S_OK && alignBits >= 0) - { - unsigned nextCoder = 1; - if (!mode.Bonds.IsEmpty()) - { - nextCoder = mode.Bonds.Back().InCoder; - } - if (nextCoder < mode.Methods.Size()) - { - CMethodFull &nextMethod = mode.Methods[nextCoder]; - if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2) - { - if (!nextMethod.Are_Lzma_Model_Props_Defined()) - { - if (alignBits != 0) - { - if (alignBits > 2 || filterMode.Id == k_Delta) - nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits); - unsigned lc = 0; - if (alignBits < 3) - lc = 3 - alignBits; - nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc); - nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits); - } - } - } - } - } - } - - return res; -} - - -static void FromUpdateItemToFileItem(const CUpdateItem &ui, - CFileItem &file, CFileItem2 &file2) -{ - if (ui.AttribDefined) - file.SetAttrib(ui.Attrib); - - file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined; - file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined; - file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined; - file2.IsAnti = ui.IsAnti; - // file2.IsAux = false; - file2.StartPosDefined = false; - - file.Size = ui.Size; - file.IsDir = ui.IsDir; - file.HasStream = ui.HasStream(); - // file.IsAltStream = ui.IsAltStream; -} - -class CRepackInStreamWithSizes: - public ISequentialInStream, - public ICompressGetSubStreamSize, - public CMyUnknownImp -{ - CMyComPtr _stream; - // UInt64 _size; - const CBoolVector *_extractStatuses; - UInt32 _startIndex; -public: - const CDbEx *_db; - - void Init(ISequentialInStream *stream, UInt32 startIndex, const CBoolVector *extractStatuses) - { - _startIndex = startIndex; - _extractStatuses = extractStatuses; - // _size = 0; - _stream = stream; - } - // UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); -}; - -STDMETHODIMP CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - return _stream->Read(data, size, processedSize); - /* - UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return result; - */ -} - -STDMETHODIMP CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value) -{ - *value = 0; - if (subStream >= _extractStatuses->Size()) - return S_FALSE; // E_FAIL; - unsigned index = (unsigned)subStream; - if ((*_extractStatuses)[index]) - { - const CFileItem &fi = _db->Files[_startIndex + index]; - if (fi.HasStream) - *value = fi.Size; - } - return S_OK; -} - - -class CRepackStreamBase -{ -protected: - bool _needWrite; - bool _fileIsOpen; - bool _calcCrc; - UInt32 _crc; - UInt64 _rem; - - const CBoolVector *_extractStatuses; - UInt32 _startIndex; - unsigned _currentIndex; - - HRESULT OpenFile(); - HRESULT CloseFile(); - HRESULT ProcessEmptyFiles(); - -public: - const CDbEx *_db; - CMyComPtr _opCallback; - CMyComPtr _extractCallback; - - HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses); - HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; } -}; - -HRESULT CRepackStreamBase::Init(UInt32 startIndex, const CBoolVector *extractStatuses) -{ - _startIndex = startIndex; - _extractStatuses = extractStatuses; - - _currentIndex = 0; - _fileIsOpen = false; - - return ProcessEmptyFiles(); -} - -HRESULT CRepackStreamBase::OpenFile() -{ - UInt32 arcIndex = _startIndex + _currentIndex; - const CFileItem &fi = _db->Files[arcIndex]; - - _needWrite = (*_extractStatuses)[_currentIndex]; - if (_opCallback) - { - RINOK(_opCallback->ReportOperation( - NEventIndexType::kInArcIndex, arcIndex, - _needWrite ? - NUpdateNotifyOp::kRepack : - NUpdateNotifyOp::kSkip)); - } - - _crc = CRC_INIT_VAL; - _calcCrc = (fi.CrcDefined && !fi.IsDir); - - _fileIsOpen = true; - _rem = fi.Size; - return S_OK; -} - -const HRESULT k_My_HRESULT_CRC_ERROR = 0x20000002; - -HRESULT CRepackStreamBase::CloseFile() -{ - UInt32 arcIndex = _startIndex + _currentIndex; - const CFileItem &fi = _db->Files[arcIndex]; - _fileIsOpen = false; - _currentIndex++; - if (!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) - return S_OK; - - if (_extractCallback) - { - RINOK(_extractCallback->ReportExtractResult( - NEventIndexType::kInArcIndex, arcIndex, - NExtract::NOperationResult::kCRCError)); - } - // return S_FALSE; - return k_My_HRESULT_CRC_ERROR; -} - -HRESULT CRepackStreamBase::ProcessEmptyFiles() -{ - while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0) - { - RINOK(OpenFile()); - RINOK(CloseFile()); - } - return S_OK; -} - - - -#ifndef _7ZIP_ST - -class CFolderOutStream2: - public CRepackStreamBase, - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - CMyComPtr _stream; - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (_fileIsOpen) - { - UInt32 cur = (size < _rem ? size : (UInt32)_rem); - HRESULT result = S_OK; - if (_needWrite) - result = _stream->Write(data, cur, &cur); - if (_calcCrc) - _crc = CrcUpdate(_crc, data, cur); - if (processedSize) - *processedSize += cur; - data = (const Byte *)data + cur; - size -= cur; - _rem -= cur; - if (_rem == 0) - { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); - } - RINOK(result); - if (cur == 0) - break; - continue; - } - - RINOK(ProcessEmptyFiles()); - if (_currentIndex == _extractStatuses->Size()) - { - // we don't support write cut here - return E_FAIL; - } - RINOK(OpenFile()); - } - - return S_OK; -} - -#endif - - - -static const UInt32 kTempBufSize = 1 << 16; - -class CFolderInStream2: - public CRepackStreamBase, - public ISequentialInStream, - public CMyUnknownImp -{ - Byte *_buf; -public: - CMyComPtr _inStream; - HRESULT Result; - - MY_UNKNOWN_IMP - - CFolderInStream2(): - Result(S_OK) - { - _buf = new Byte[kTempBufSize]; - } - - ~CFolderInStream2() - { - delete []_buf; - } - - void Init() { Result = S_OK; } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (_fileIsOpen) - { - UInt32 cur = (size < _rem ? size : (UInt32)_rem); - - void *buf; - if (_needWrite) - buf = data; - else - { - buf = _buf; - if (cur > kTempBufSize) - cur = kTempBufSize; - } - - HRESULT result = _inStream->Read(buf, cur, &cur); - _crc = CrcUpdate(_crc, buf, cur); - _rem -= cur; - - if (_needWrite) - { - data = (Byte *)data + cur; - size -= cur; - if (processedSize) - *processedSize += cur; - } - - if (result != S_OK) - Result = result; - - if (_rem == 0) - { - RINOK(CloseFile()); - RINOK(ProcessEmptyFiles()); - } - - RINOK(result); - - if (cur == 0) - return E_FAIL; - - continue; - } - - RINOK(ProcessEmptyFiles()); - if (_currentIndex == _extractStatuses->Size()) - { - return S_OK; - } - RINOK(OpenFile()); - } - - return S_OK; -} - - -class CThreadDecoder - #ifndef _7ZIP_ST - : public CVirtThread - #endif -{ -public: - CDecoder Decoder; - - CThreadDecoder(bool multiThreadMixer): - Decoder(multiThreadMixer) - { - #ifndef _7ZIP_ST - if (multiThreadMixer) - { - MtMode = false; - NumThreads = 1; - FosSpec = new CFolderOutStream2; - Fos = FosSpec; - Result = E_FAIL; - } - #endif - // UnpackSize = 0; - // send_UnpackSize = false; - } - - #ifndef _7ZIP_ST - - HRESULT Result; - CMyComPtr InStream; - - CFolderOutStream2 *FosSpec; - CMyComPtr Fos; - - UInt64 StartPos; - const CFolders *Folders; - int FolderIndex; - - // bool send_UnpackSize; - // UInt64 UnpackSize; - - #ifndef _NO_CRYPTO - CMyComPtr getTextPassword; - #endif - - DECL_EXTERNAL_CODECS_LOC_VARS2; - - #ifndef _7ZIP_ST - bool MtMode; - UInt32 NumThreads; - #endif - - - ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); } - virtual void Execute(); - - #endif -}; - -#ifndef _7ZIP_ST - -void CThreadDecoder::Execute() -{ - try - { - #ifndef _NO_CRYPTO - bool isEncrypted = false; - bool passwordIsDefined = false; - UString password; - #endif - - Result = Decoder.Decode( - EXTERNAL_CODECS_LOC_VARS - InStream, - StartPos, - *Folders, FolderIndex, - - // send_UnpackSize ? &UnpackSize : NULL, - NULL, // unpackSize : FULL unpack - - Fos, - NULL, // compressProgress - NULL // *inStreamMainRes - - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST - , MtMode, NumThreads - #endif - ); - } - catch(...) - { - Result = E_FAIL; - } - - /* - if (Result == S_OK) - Result = FosSpec->CheckFinishedState(); - */ - FosSpec->_stream.Release(); -} - -#endif - -#ifndef _NO_CRYPTO - -class CCryptoGetTextPassword: - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - UString Password; - - MY_UNKNOWN_IMP - STDMETHOD(CryptoGetTextPassword)(BSTR *password); -}; - -STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password) -{ - return StringToBstr(Password, password); -} - -#endif - - -static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFileItem2 &file2) -{ - file = inDb.Files[index]; - file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime); - file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime); - file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime); - file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos); - file2.IsAnti = inDb.IsItemAnti(index); - // file2.IsAux = inDb.IsItemAux(index); -} - -HRESULT Update( - DECL_EXTERNAL_CODECS_LOC_VARS - IInStream *inStream, - const CDbEx *db, - const CObjectVector &updateItems, - // const CObjectVector &treeFolders, - // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, - ISequentialOutStream *seqOutStream, - IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ) -{ - UInt64 numSolidFiles = options.NumSolidFiles; - if (numSolidFiles == 0) - numSolidFiles = 1; - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - - CMyComPtr extractCallback; - updateCallback->QueryInterface(IID_IArchiveExtractCallbackMessage, (void **)&extractCallback); - - // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); - - /* - CMyComPtr outStream; - RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); - if (!outStream) - return E_NOTIMPL; - */ - - UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0; - if (startBlockSize > 0 && !options.RemoveSfxBlock) - { - RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); - } - - CIntArr fileIndexToUpdateIndexMap; - UInt64 complexity = 0; - UInt64 inSizeForReduce2 = 0; - bool needEncryptedRepack = false; - - CRecordVector filters; - CObjectVector groups; - bool thereAreRepacks = false; - - bool useFilters = options.UseFilters; - if (useFilters) - { - const CCompressionMethodMode &method = *options.Method; - - FOR_VECTOR (i, method.Methods) - if (IsFilterMethod(method.Methods[i].Id)) - { - useFilters = false; - break; - } - } - - if (db) - { - fileIndexToUpdateIndexMap.Alloc(db->Files.Size()); - unsigned i; - - for (i = 0; i < db->Files.Size(); i++) - fileIndexToUpdateIndexMap[i] = -1; - - for (i = 0; i < updateItems.Size(); i++) - { - int index = updateItems[i].IndexInArchive; - if (index != -1) - fileIndexToUpdateIndexMap[(unsigned)index] = i; - } - - for (i = 0; i < db->NumFolders; i++) - { - CNum indexInFolder = 0; - CNum numCopyItems = 0; - CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; - UInt64 repackSize = 0; - - for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++) - { - const CFileItem &file = db->Files[fi]; - if (file.HasStream) - { - indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; - if (updateIndex >= 0 && !updateItems[updateIndex].NewData) - { - numCopyItems++; - repackSize += file.Size; - } - } - } - - if (numCopyItems == 0) - continue; - - CFolderRepack rep; - rep.FolderIndex = i; - rep.NumCopyFiles = numCopyItems; - CFolderEx f; - db->ParseFolderEx(i, f); - - const bool isEncrypted = f.IsEncrypted(); - const bool needCopy = (numCopyItems == numUnpackStreams); - const bool extractFilter = (useFilters || needCopy); - - unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); - - while (groupIndex >= groups.Size()) - groups.AddNew(); - - groups[groupIndex].folderRefs.Add(rep); - - if (needCopy) - complexity += db->GetFolderFullPackSize(i); - else - { - thereAreRepacks = true; - complexity += repackSize; - if (inSizeForReduce2 < repackSize) - inSizeForReduce2 = repackSize; - if (isEncrypted) - needEncryptedRepack = true; - } - } - } - - UInt64 inSizeForReduce = 0; - { - FOR_VECTOR (i, updateItems) - { - const CUpdateItem &ui = updateItems[i]; - if (ui.NewData) - { - complexity += ui.Size; - if (numSolidFiles != 1) - inSizeForReduce += ui.Size; - else if (inSizeForReduce < ui.Size) - inSizeForReduce = ui.Size; - } - } - } - - if (inSizeForReduce < inSizeForReduce2) - inSizeForReduce = inSizeForReduce2; - - RINOK(updateCallback->SetTotal(complexity)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - #ifndef _7ZIP_ST - - CStreamBinder sb; - if (options.MultiThreadMixer) - { - RINOK(sb.CreateEvents()); - } - - #endif - - CThreadDecoder threadDecoder(options.MultiThreadMixer); - - #ifndef _7ZIP_ST - if (options.MultiThreadMixer && thereAreRepacks) - { - #ifdef EXTERNAL_CODECS - threadDecoder.__externalCodecs = __externalCodecs; - #endif - RINOK(threadDecoder.Create()); - } - #endif - - { - CAnalysis analysis; - if (options.AnalysisLevel == 0) - { - analysis.ParseWav = false; - analysis.ParseExe = false; - analysis.ParseAll = false; - } - else - { - analysis.Callback = opCallback; - if (options.AnalysisLevel > 0) - { - analysis.ParseWav = true; - if (options.AnalysisLevel >= 7) - { - analysis.ParseExe = true; - if (options.AnalysisLevel >= 9) - analysis.ParseAll = true; - } - } - } - - // ---------- Split files to groups ---------- - - const CCompressionMethodMode &method = *options.Method; - - FOR_VECTOR (i, updateItems) - { - const CUpdateItem &ui = updateItems[i]; - if (!ui.NewData || !ui.HasStream()) - continue; - - CFilterMode2 fm; - if (useFilters) - { - RINOK(analysis.GetFilterGroup(i, ui, fm)); - } - fm.Encrypted = method.PasswordIsDefined; - - unsigned groupIndex = GetGroup(filters, fm); - while (groupIndex >= groups.Size()) - groups.AddNew(); - groups[groupIndex].Indices.Add(i); - } - } - - - #ifndef _NO_CRYPTO - - CCryptoGetTextPassword *getPasswordSpec = NULL; - CMyComPtr getTextPassword; - if (needEncryptedRepack) - { - getPasswordSpec = new CCryptoGetTextPassword; - getTextPassword = getPasswordSpec; - - #ifndef _7ZIP_ST - threadDecoder.getTextPassword = getPasswordSpec; - #endif - - if (options.Method->PasswordIsDefined) - getPasswordSpec->Password = options.Method->Password; - else - { - if (!getDecoderPassword) - return E_NOTIMPL; - CMyComBSTR password; - RINOK(getDecoderPassword->CryptoGetTextPassword(&password)); - if (password) - getPasswordSpec->Password = password; - } - } - - #endif - - - // ---------- Compress ---------- - - RINOK(archive.Create(seqOutStream, false)); - RINOK(archive.SkipPrefixArchiveHeader()); - - /* - CIntVector treeFolderToArcIndex; - treeFolderToArcIndex.Reserve(treeFolders.Size()); - for (i = 0; i < treeFolders.Size(); i++) - treeFolderToArcIndex.Add(-1); - // ---------- Write Tree (only AUX dirs) ---------- - for (i = 1; i < treeFolders.Size(); i++) - { - const CTreeFolder &treeFolder = treeFolders[i]; - CFileItem file; - CFileItem2 file2; - file2.Init(); - int secureID = 0; - if (treeFolder.UpdateItemIndex < 0) - { - // we can store virtual dir item wuthout attrib, but we want all items have attrib. - file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY); - file2.IsAux = true; - } - else - { - const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex]; - // if item is not dir, then it's parent for alt streams. - // we will write such items later - if (!ui.IsDir) - continue; - secureID = ui.SecureIndex; - if (ui.NewProps) - FromUpdateItemToFileItem(ui, file, file2); - else - GetFile(*db, ui.IndexInArchive, file, file2); - } - file.Size = 0; - file.HasStream = false; - file.IsDir = true; - file.Parent = treeFolder.Parent; - - treeFolderToArcIndex[i] = newDatabase.Files.Size(); - newDatabase.AddFile(file, file2, treeFolder.Name); - - if (totalSecureDataSize != 0) - newDatabase.SecureIDs.Add(secureID); - } - */ - - { - /* ---------- Write non-AUX dirs and Empty files ---------- */ - CUIntVector emptyRefs; - - unsigned i; - - for (i = 0; i < updateItems.Size(); i++) - { - const CUpdateItem &ui = updateItems[i]; - if (ui.NewData) - { - if (ui.HasStream()) - continue; - } - else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream) - continue; - /* - if (ui.TreeFolderIndex >= 0) - continue; - */ - emptyRefs.Add(i); - } - - emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); - - for (i = 0; i < emptyRefs.Size(); i++) - { - const CUpdateItem &ui = updateItems[emptyRefs[i]]; - CFileItem file; - CFileItem2 file2; - UString name; - if (ui.NewProps) - { - FromUpdateItemToFileItem(ui, file, file2); - name = ui.Name; - } - else - { - GetFile(*db, ui.IndexInArchive, file, file2); - db->GetPath(ui.IndexInArchive, name); - } - - /* - if (totalSecureDataSize != 0) - newDatabase.SecureIDs.Add(ui.SecureIndex); - file.Parent = ui.ParentFolderIndex; - */ - newDatabase.AddFile(file, file2, name); - } - } - - lps->ProgressOffset = 0; - - { - // ---------- Sort Filters ---------- - - FOR_VECTOR (i, filters) - { - filters[i].GroupIndex = i; - } - filters.Sort2(); - } - - for (unsigned groupIndex = 0; groupIndex < filters.Size(); groupIndex++) - { - const CFilterMode2 &filterMode = filters[groupIndex]; - - CCompressionMethodMode method = *options.Method; - { - HRESULT res = MakeExeMethod(method, filterMode, - #ifdef _7ZIP_ST - false - #else - options.MaxFilter && options.MultiThreadMixer - #endif - ); - - RINOK(res); - } - - if (filterMode.Encrypted) - { - if (!method.PasswordIsDefined) - { - #ifndef _NO_CRYPTO - if (getPasswordSpec) - method.Password = getPasswordSpec->Password; - #endif - method.PasswordIsDefined = true; - } - } - else - { - method.PasswordIsDefined = false; - method.Password.Empty(); - } - - CEncoder encoder(method); - - // ---------- Repack and copy old solid blocks ---------- - - const CSolidGroup &group = groups[filterMode.GroupIndex]; - - FOR_VECTOR(folderRefIndex, group.folderRefs) - { - const CFolderRepack &rep = group.folderRefs[folderRefIndex]; - - unsigned folderIndex = rep.FolderIndex; - - CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; - - if (rep.NumCopyFiles == numUnpackStreams) - { - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NUpdateNotifyOp::kReplicate)); - - // ---------- Copy old solid block ---------- - { - CNum indexInFolder = 0; - for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) - { - if (db->Files[fi].HasStream) - { - indexInFolder++; - RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, (UInt32)fi, - NUpdateNotifyOp::kReplicate)); - } - } - } - } - - UInt64 packSize = db->GetFolderFullPackSize(folderIndex); - RINOK(WriteRange(inStream, archive.SeqStream, - db->GetFolderStreamPos(folderIndex, 0), packSize, progress)); - lps->ProgressOffset += packSize; - - CFolder &folder = newDatabase.Folders.AddNew(); - db->ParseFolderInfo(folderIndex, folder); - CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; - FOR_VECTOR(j, folder.PackStreams) - { - newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j)); - // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); - // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]); - } - - size_t indexStart = db->FoToCoderUnpackSizes[folderIndex]; - size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; - for (; indexStart < indexEnd; indexStart++) - newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes[indexStart]); - } - else - { - // ---------- Repack old solid block ---------- - - CBoolVector extractStatuses; - - CNum indexInFolder = 0; - - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NUpdateNotifyOp::kRepack)) - } - - /* We could reduce data size of decoded folder, if we don't need to repack - last files in folder. But the gain in speed is small in most cases. - So we unpack full folder. */ - - UInt64 sizeToEncode = 0; - - /* - UInt64 importantUnpackSize = 0; - unsigned numImportantFiles = 0; - UInt64 decodeSize = 0; - */ - - for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) - { - bool needExtract = false; - const CFileItem &file = db->Files[fi]; - - if (file.HasStream) - { - indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; - if (updateIndex >= 0 && !updateItems[updateIndex].NewData) - needExtract = true; - // decodeSize += file.Size; - } - - extractStatuses.Add(needExtract); - if (needExtract) - { - sizeToEncode += file.Size; - /* - numImportantFiles = extractStatuses.Size(); - importantUnpackSize = decodeSize; - */ - } - } - - // extractStatuses.DeleteFrom(numImportantFiles); - - unsigned startPackIndex = newDatabase.PackSizes.Size(); - UInt64 curUnpackSize; - { - - CMyComPtr sbInStream; - CRepackStreamBase *repackBase; - CFolderInStream2 *FosSpec2 = NULL; - - CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes; - CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; - { - #ifndef _7ZIP_ST - if (options.MultiThreadMixer) - { - repackBase = threadDecoder.FosSpec; - CMyComPtr sbOutStream; - sb.CreateStreams(&sbInStream, &sbOutStream); - sb.ReInit(); - - threadDecoder.FosSpec->_stream = sbOutStream; - - threadDecoder.InStream = inStream; - threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0); - threadDecoder.Folders = (const CFolders *)db; - threadDecoder.FolderIndex = folderIndex; - - // threadDecoder.UnpackSize = importantUnpackSize; - // threadDecoder.send_UnpackSize = true; - } - else - #endif - { - FosSpec2 = new CFolderInStream2; - FosSpec2->Init(); - sbInStream = FosSpec2; - repackBase = FosSpec2; - - #ifndef _NO_CRYPTO - bool isEncrypted = false; - bool passwordIsDefined = false; - UString password; - #endif - - CMyComPtr decodedStream; - HRESULT res = threadDecoder.Decoder.Decode( - EXTERNAL_CODECS_LOC_VARS - inStream, - db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);, - *db, folderIndex, - // &importantUnpackSize, // *unpackSize - NULL, // *unpackSize : FULL unpack - - NULL, // *outStream - NULL, // *compressProgress - &decodedStream - - _7Z_DECODER_CRYPRO_VARS - #ifndef _7ZIP_ST - , false // mtMode - , 1 // numThreads - #endif - ); - - RINOK(res); - if (!decodedStream) - return E_FAIL; - - FosSpec2->_inStream = decodedStream; - } - - repackBase->_db = db; - repackBase->_opCallback = opCallback; - repackBase->_extractCallback = extractCallback; - - UInt32 startIndex = db->FolderStartFileIndex[folderIndex]; - RINOK(repackBase->Init(startIndex, &extractStatuses)); - - inStreamSizeCountSpec->_db = db; - inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses); - - #ifndef _7ZIP_ST - if (options.MultiThreadMixer) - { - threadDecoder.Start(); - } - #endif - } - - - HRESULT encodeRes = encoder.Encode( - EXTERNAL_CODECS_LOC_VARS - inStreamSizeCount, - // NULL, - &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curUnpackSize, - archive.SeqStream, newDatabase.PackSizes, progress); - - if (encodeRes == k_My_HRESULT_CRC_ERROR) - return E_FAIL; - - #ifndef _7ZIP_ST - if (options.MultiThreadMixer) - { - // 16.00: hang was fixed : for case if decoding was not finished. - // We close CBinderInStream and it calls CStreamBinder::CloseRead() - inStreamSizeCount.Release(); - sbInStream.Release(); - - threadDecoder.WaitExecuteFinish(); - - HRESULT decodeRes = threadDecoder.Result; - // if (res == k_My_HRESULT_CRC_ERROR) - if (decodeRes == S_FALSE) - { - if (extractCallback) - { - RINOK(extractCallback->ReportExtractResult( - NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex], - // NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NExtract::NOperationResult::kDataError)); - } - return E_FAIL; - } - RINOK(decodeRes); - if (encodeRes == S_OK) - if (sb.ProcessedSize != sizeToEncode) - encodeRes = E_FAIL; - } - else - #endif - { - if (FosSpec2->Result == S_FALSE) - { - if (extractCallback) - { - RINOK(extractCallback->ReportExtractResult( - NEventIndexType::kBlockIndex, (UInt32)folderIndex, - NExtract::NOperationResult::kDataError)); - } - return E_FAIL; - } - RINOK(FosSpec2->Result); - } - - RINOK(encodeRes); - RINOK(repackBase->CheckFinishedState()); - - if (curUnpackSize != sizeToEncode) - return E_FAIL; - } - - for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) - lps->OutSize += newDatabase.PackSizes[startPackIndex]; - lps->InSize += curUnpackSize; - } - - newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles); - - CNum indexInFolder = 0; - for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) - { - CFileItem file; - CFileItem2 file2; - GetFile(*db, fi, file, file2); - UString name; - db->GetPath(fi, name); - if (file.HasStream) - { - indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fi]; - if (updateIndex >= 0) - { - const CUpdateItem &ui = updateItems[updateIndex]; - if (ui.NewData) - continue; - if (ui.NewProps) - { - CFileItem uf; - FromUpdateItemToFileItem(ui, uf, file2); - uf.Size = file.Size; - uf.Crc = file.Crc; - uf.CrcDefined = file.CrcDefined; - uf.HasStream = file.HasStream; - file = uf; - name = ui.Name; - } - /* - file.Parent = ui.ParentFolderIndex; - if (ui.TreeFolderIndex >= 0) - treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); - if (totalSecureDataSize != 0) - newDatabase.SecureIDs.Add(ui.SecureIndex); - */ - newDatabase.AddFile(file, file2, name); - } - } - } - } - - - // ---------- Compress files to new solid blocks ---------- - - unsigned numFiles = group.Indices.Size(); - if (numFiles == 0) - continue; - CRecordVector refItems; - refItems.ClearAndSetSize(numFiles); - bool sortByType = (options.UseTypeSorting && numSolidFiles > 1); - - unsigned i; - - for (i = 0; i < numFiles; i++) - refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType); - - CSortParam sortParam; - // sortParam.TreeFolders = &treeFolders; - sortParam.SortByType = sortByType; - refItems.Sort(CompareUpdateItems, (void *)&sortParam); - - CObjArray indices(numFiles); - - for (i = 0; i < numFiles; i++) - { - UInt32 index = refItems[i].Index; - indices[i] = index; - /* - const CUpdateItem &ui = updateItems[index]; - CFileItem file; - if (ui.NewProps) - FromUpdateItemToFileItem(ui, file); - else - file = db.Files[ui.IndexInArchive]; - if (file.IsAnti || file.IsDir) - return E_FAIL; - newDatabase.Files.Add(file); - */ - } - - for (i = 0; i < numFiles;) - { - UInt64 totalSize = 0; - unsigned numSubFiles; - - const wchar_t *prevExtension = NULL; - - for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++) - { - const CUpdateItem &ui = updateItems[indices[i + numSubFiles]]; - totalSize += ui.Size; - if (totalSize > options.NumSolidBytes) - break; - if (options.SolidExtension) - { - int slashPos = ui.Name.ReverseFind_PathSepar(); - int dotPos = ui.Name.ReverseFind_Dot(); - const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1); - if (numSubFiles == 0) - prevExtension = ext; - else if (!StringsAreEqualNoCase(ext, prevExtension)) - break; - } - } - - if (numSubFiles < 1) - numSubFiles = 1; - - RINOK(lps->SetCur()); - - CFolderInStream *inStreamSpec = new CFolderInStream; - CMyComPtr solidInStream(inStreamSpec); - inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); - - unsigned startPackIndex = newDatabase.PackSizes.Size(); - UInt64 curFolderUnpackSize; - RINOK(encoder.Encode( - EXTERNAL_CODECS_LOC_VARS - solidInStream, - // NULL, - &inSizeForReduce, - newDatabase.Folders.AddNew(), newDatabase.CoderUnpackSizes, curFolderUnpackSize, - archive.SeqStream, newDatabase.PackSizes, progress)); - - if (!inStreamSpec->WasFinished()) - return E_FAIL; - - for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) - lps->OutSize += newDatabase.PackSizes[startPackIndex]; - - lps->InSize += curFolderUnpackSize; - // for () - // newDatabase.PackCRCsDefined.Add(false); - // newDatabase.PackCRCs.Add(0); - - CNum numUnpackStreams = 0; - UInt64 skippedSize = 0; - - for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++) - { - const CUpdateItem &ui = updateItems[indices[i + subIndex]]; - CFileItem file; - CFileItem2 file2; - UString name; - if (ui.NewProps) - { - FromUpdateItemToFileItem(ui, file, file2); - name = ui.Name; - } - else - { - GetFile(*db, ui.IndexInArchive, file, file2); - db->GetPath(ui.IndexInArchive, name); - } - if (file2.IsAnti || file.IsDir) - return E_FAIL; - - /* - CFileItem &file = newDatabase.Files[ - startFileIndexInDatabase + i + subIndex]; - */ - if (!inStreamSpec->Processed[subIndex]) - { - skippedSize += ui.Size; - continue; - // file.Name.AddAscii(".locked"); - } - - file.Crc = inStreamSpec->CRCs[subIndex]; - file.Size = inStreamSpec->Sizes[subIndex]; - - // if (file.Size >= 0) // test purposes - if (file.Size != 0) - { - file.CrcDefined = true; - file.HasStream = true; - numUnpackStreams++; - } - else - { - file.CrcDefined = false; - file.HasStream = false; - } - - /* - file.Parent = ui.ParentFolderIndex; - if (ui.TreeFolderIndex >= 0) - treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); - if (totalSecureDataSize != 0) - newDatabase.SecureIDs.Add(ui.SecureIndex); - */ - newDatabase.AddFile(file, file2, name); - } - - // numUnpackStreams = 0 is very bad case for locked files - // v3.13 doesn't understand it. - newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams); - i += numSubFiles; - - if (skippedSize != 0 && complexity >= skippedSize) - { - complexity -= skippedSize; - RINOK(updateCallback->SetTotal(complexity)); - } - } - } - - RINOK(lps->SetCur()); - - /* - fileIndexToUpdateIndexMap.ClearAndFree(); - groups.ClearAndFree(); - */ - - /* - for (i = 0; i < newDatabase.Files.Size(); i++) - { - CFileItem &file = newDatabase.Files[i]; - file.Parent = treeFolderToArcIndex[file.Parent]; - } - - if (totalSecureDataSize != 0) - { - newDatabase.SecureBuf.SetCapacity(totalSecureDataSize); - size_t pos = 0; - newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size()); - for (i = 0; i < secureBlocks.Sorted.Size(); i++) - { - const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]]; - size_t size = buf.GetCapacity(); - if (size != 0) - memcpy(newDatabase.SecureBuf + pos, buf, size); - newDatabase.SecureSizes.Add((UInt32)size); - pos += size; - } - } - */ - newDatabase.ReserveDown(); - - if (opCallback) - RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)); - - return S_OK; -} - -}} +// 7zUpdate.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/Wildcard.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "7zDecode.h" +#include "7zEncode.h" +#include "7zFolderInStream.h" +#include "7zHandler.h" +#include "7zOut.h" +#include "7zUpdate.h" + +namespace NArchive { +namespace N7z { + +#define k_X86 k_BCJ + +struct CFilterMode +{ + UInt32 Id; + UInt32 Delta; // required File Size alignment, if Id is not k_Delta. + // (Delta == 0) means unknown alignment + UInt32 Offset; // for k_ARM64 / k_RISCV + // UInt32 AlignSizeOpt; // for k_ARM64 + + CFilterMode(): + Id(0), + Delta(0), + Offset(0) + // , AlignSizeOpt(0) + {} + + void ClearFilterMode() + { + Id = 0; + Delta = 0; + Offset = 0; + // AlignSizeOpt = 0; + } + + // it sets Delta as Align value, if Id is exe filter + // in another cases it sets Delta = 0, that + void SetDelta() + { + if (Id == k_IA64) + Delta = 16; + else if (Id == k_ARM64 || Id == k_ARM || Id == k_PPC || Id == k_SPARC) + Delta = 4; + else if (Id == k_ARMT || Id == k_RISCV) + Delta = 2; + else if (Id == k_BCJ || Id == k_BCJ2) + Delta = 1; // do we need it? + else + Delta = 0; + } +}; + + +/* ---------- PE ---------- */ + +#define MZ_SIG 0x5A4D + +#define PE_SIG 0x00004550 +#define PE_OptHeader_Magic_32 0x10B +#define PE_OptHeader_Magic_64 0x20B +// #define PE_SectHeaderSize 40 +// #define PE_SECT_EXECUTE 0x20000000 + +static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) +{ + if (size < 512 || GetUi16(buf) != MZ_SIG) + return 0; + + const Byte *p; + UInt32 peOffset, optHeaderSize, filterId; + + peOffset = GetUi32(buf + 0x3C); + if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0) + return 0; + p = buf + peOffset; + if (GetUi32(p) != PE_SIG) + return 0; + p += 4; + + const unsigned machine = GetUi16(p); + + switch (machine) + { + case 0x014C: + case 0x8664: filterId = k_X86; break; + case 0xAA64: filterId = k_ARM64; break; + + /* + IMAGE_FILE_MACHINE_ARM 0x01C0 // ARM LE + IMAGE_FILE_MACHINE_THUMB 0x01C2 // ARM Thumb / Thumb-2 LE + IMAGE_FILE_MACHINE_ARMNT 0x01C4 // ARM Thumb-2, LE + Note: We use ARM filter for 0x01C2. (WinCE 5 - 0x01C2) files mostly contain ARM code (not Thumb/Thumb-2). + */ + + case 0x01C0: // WinCE old + case 0x01C2: filterId = k_ARM; break; // WinCE new + case 0x01C4: filterId = k_ARMT; break; // WinRT + + case 0x5032: // RISCV32 + case 0x5064: // RISCV64 + // case 0x5128: // RISCV128 + filterId = k_RISCV; break; + + case 0x0200: filterId = k_IA64; break; + default: return 0; + } + + const UInt32 numSections = GetUi16(p + 2); + optHeaderSize = GetUi16(p + 16); + if (optHeaderSize > (1 << 10)) + return 0; + + p += 20; /* headerSize */ + + switch (GetUi16(p)) + { + case PE_OptHeader_Magic_32: + case PE_OptHeader_Magic_64: + break; + default: + return 0; + } + + // Windows exe file sizes are not aligned for 4 KiB. + // So we can't use (CFilterMode::Offset != 0) in solid archives. + // So we just don't set Offset here. +#define NUM_SCAN_SECTIONS_MAX (1 << 6) +// #define EXE_SECTION_OFFSET_MAX (1 << 27) +// #define EXE_SECTION_SIZE_MIN (1 << 8) +// #define EXE_SECTION_SIZE_MAX (1 << 27) +#define PE_SectHeaderSize 40 +// #define PE_SECT_EXECUTE 0x20000000 + +/* + if (numSections > NUM_SCAN_SECTIONS_MAX) + return 0; +*/ + + if ((size_t)(p - buf) + optHeaderSize <= size) + { + p += optHeaderSize; +/* + // UInt32 numExeSections = 0; + // bool execute_finded = false; + // UInt32 sect_va = 0; + // UInt32 sect_size = 0; + // UInt32 sect_offset = 0; +*/ + if (numSections <= NUM_SCAN_SECTIONS_MAX) + if (machine == 0x8664) + for (UInt32 i = 0; i < numSections + ; i++, p += PE_SectHeaderSize) + { + // UInt32 characts, rawSize, offset; + if ((UInt32)(p - buf) + PE_SectHeaderSize > size) + { + // return 0; + break; + } + if (memcmp(p, ".a64xrm", 8) == 0) + { + // ARM64EC + filterId = k_ARM64; + break; + } +/* + rawSize = GetUi32(p + 16); + offset = GetUi32(p + 20); + characts = GetUi32(p + 36); + if (rawSize >= EXE_SECTION_SIZE_MIN && + rawSize <= EXE_SECTION_SIZE_MAX && + offset <= EXE_SECTION_OFFSET_MAX && + // offset < limit && + offset > 0) + { + if ((characts & PE_SECT_EXECUTE) != 0) + { + // execute_finded = true; + // sect_va = GetUi32(p + 12); + // sect_size = rawSize; + // sect_offset = offset; + break; + } + } +*/ + } + } + + /* + filterMode->Offset = 0; + if (filterId == k_ARM64) + { + // filterMode->AlignSizeOpt = (1 << 12); + // const UInt32 offs = (sect_va - sect_offset) & 0xFFF; + // if (offs != 0) + // filterMode->Offset = offs; // change it + } + */ + filterMode->Id = filterId; + return 1; +} + + +/* + Filters don't improve the compression ratio for relocatable object files (".o"). + But we can get compression ratio gain, if we compress object + files and executables in same solid block. + So we use filters for relocatable object files (".o"): +*/ +// #define Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ + +/* ---------- ELF ---------- */ + +#define ELF_SIG 0x464C457F + +#define ELF_CLASS_32 1 +#define ELF_CLASS_64 2 + +#define ELF_DATA_2LSB 1 +#define ELF_DATA_2MSB 2 + +static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } +static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); } +// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); } + +static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) +{ + BoolInt /* is32, */ be; + UInt32 filterId; + + if (size < 512 || buf[6] != 1) /* ver */ + return 0; + + if (GetUi32(buf) != ELF_SIG) + return 0; + + switch (buf[4]) + { + case ELF_CLASS_32: /* is32 = True; */ break; + case ELF_CLASS_64: /* is32 = False; */ break; + default: return 0; + } + + switch (buf[5]) + { + case ELF_DATA_2LSB: be = False; break; + case ELF_DATA_2MSB: be = True; break; + default: return 0; + } + +#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ +#define ELF_ET_REL 1 + if (Get16(buf + 0x10, be) == ELF_ET_REL) + return 0; +#endif + + switch (Get16(buf + 0x12, be)) + { + case 3: + case 6: + case 62: filterId = k_X86; break; + case 2: + case 18: + case 43: filterId = k_SPARC; break; + case 20: + case 21: if (!be) return 0; filterId = k_PPC; break; + case 40: if (be) return 0; filterId = k_ARM; break; + case 183: if (be) return 0; filterId = k_ARM64; break; + case 243: if (be) return 0; filterId = k_RISCV; break; + + /* Some IA-64 ELF executables have size that is not aligned for 16 bytes. + So we don't use IA-64 filter for IA-64 ELF */ + // case 50: if ( be) return 0; filterId = k_IA64; break; + + default: return 0; + } + + filterMode->Id = filterId; + return 1; +} + + + +/* ---------- Mach-O ---------- */ + +#define MACH_SIG_BE_32 0xCEFAEDFE +#define MACH_SIG_BE_64 0xCFFAEDFE +#define MACH_SIG_LE_32 0xFEEDFACE +#define MACH_SIG_LE_64 0xFEEDFACF + +#define MACH_ARCH_ABI64 (1 << 24) +#define MACH_MACHINE_386 7 +#define MACH_MACHINE_ARM 12 +#define MACH_MACHINE_SPARC 14 +#define MACH_MACHINE_PPC 18 +#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) +#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) +#define MACH_MACHINE_ARM64 (MACH_ARCH_ABI64 | MACH_MACHINE_ARM) + +static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode) +{ + UInt32 filterId, numCommands, commandsSize; + + if (size < 512) + return 0; + + BoolInt /* mode64, */ be; + switch (GetUi32(buf)) + { + case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break; + case MACH_SIG_BE_64: /* mode64 = True; */ be = True; break; + case MACH_SIG_LE_32: /* mode64 = False; */ be = False; break; + case MACH_SIG_LE_64: /* mode64 = True; */ be = False; break; + default: return 0; + } + +#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ +#define MACH_TYPE_OBJECT 1 + if (Get32(buf + 0xC, be) == MACH_TYPE_OBJECT) + return 0; +#endif + + switch (Get32(buf + 4, be)) + { + case MACH_MACHINE_386: + case MACH_MACHINE_AMD64: filterId = k_X86; break; + case MACH_MACHINE_ARM: if ( be) return 0; filterId = k_ARM; break; + case MACH_MACHINE_SPARC: if (!be) return 0; filterId = k_SPARC; break; + case MACH_MACHINE_PPC: + case MACH_MACHINE_PPC64: if (!be) return 0; filterId = k_PPC; break; + case MACH_MACHINE_ARM64: if ( be) return 0; filterId = k_ARM64; break; + default: return 0; + } + + numCommands = Get32(buf + 0x10, be); + commandsSize = Get32(buf + 0x14, be); + + if (commandsSize > (1 << 24) || numCommands > (1 << 18)) + return 0; + + filterMode->Id = filterId; + return 1; +} + + +/* ---------- WAV ---------- */ + +#define WAV_SUBCHUNK_fmt 0x20746D66 +#define WAV_SUBCHUNK_data 0x61746164 + +#define RIFF_SIG 0x46464952 + +static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) +{ + UInt32 subChunkSize, pos; + if (size < 0x2C) + return False; + + if (GetUi32(buf + 0) != RIFF_SIG || + GetUi32(buf + 8) != 0x45564157 || // WAVE + GetUi32(buf + 0xC) != WAV_SUBCHUNK_fmt) + return False; + subChunkSize = GetUi32(buf + 0x10); + /* [0x14 = format] = 1 (PCM) */ + if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1) + return False; + + const unsigned numChannels = GetUi16(buf + 0x16); + const unsigned bitsPerSample = GetUi16(buf + 0x22); + if ((bitsPerSample & 0x7) != 0) + return False; + const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3); + if (delta == 0 || delta > 256) + return False; + + pos = 0x14 + subChunkSize; + + const int kNumSubChunksTests = 10; + // Do we need to scan more than 3 sub-chunks? + for (int i = 0; i < kNumSubChunksTests; i++) + { + if (pos + 8 > size) + return False; + subChunkSize = GetUi32(buf + pos + 4); + if (GetUi32(buf + pos) == WAV_SUBCHUNK_data) + { + filterMode->Id = k_Delta; + filterMode->Delta = delta; + return True; + } + if (subChunkSize > (1 << 16)) + return False; + pos += subChunkSize + 8; + } + return False; +} + + +/* + filterMode->Delta will be set as: + = delta value : [1, 256] : for k_Delta + = 0 for another filters (branch filters) +*/ +static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) +{ + filterMode->ClearFilterMode(); + + if (Parse_EXE(buf, size, filterMode)) return True; + if (Parse_ELF(buf, size, filterMode)) return True; + if (Parse_MACH(buf, size, filterMode)) return True; + return Parse_WAV(buf, size, filterMode); +} + + + + +struct CFilterMode2: public CFilterMode +{ + bool Encrypted; + unsigned GroupIndex; + + CFilterMode2(): Encrypted(false) {} + + int Compare(const CFilterMode2 &m) const + { + if (!Encrypted) + { + if (m.Encrypted) + return -1; + } + else if (!m.Encrypted) + return 1; + + const UInt32 id1 = Id; + const UInt32 id2 = m.Id; + /* + // we can change the order to place k_ARM64 files close to another exe files + if (id1 <= k_SPARC && + id2 <= k_SPARC) + { + #define k_ARM64_FOR_SORT 0x3030901 + if (id1 == k_ARM64) id1 = k_ARM64_FOR_SORT; + if (id2 == k_ARM64) id2 = k_ARM64_FOR_SORT; + } + */ + if (id1 < id2) return -1; + if (id1 > id2) return 1; + + if (Delta < m.Delta) return -1; + if (Delta > m.Delta) return 1; + + if (Offset < m.Offset) return -1; + if (Offset > m.Offset) return 1; + + /* we don't go here, because GetGroup() + and operator ==(const CFilterMode2 &m) + add only unique CFilterMode2:: { Id, Delta, Offset, Encrypted } items. + */ + /* + if (GroupIndex < m.GroupIndex) return -1; + if (GroupIndex > m.GroupIndex) return 1; + */ + return 0; + } + + bool operator ==(const CFilterMode2 &m) const + { + return Id == m.Id + && Delta == m.Delta + && Offset == m.Offset + && Encrypted == m.Encrypted; + } +}; + +static unsigned GetGroup(CRecordVector &filters, const CFilterMode2 &m) +{ + unsigned i; + for (i = 0; i < filters.Size(); i++) + { + const CFilterMode2 &m2 = filters[i]; + if (m == m2) + return i; + /* + if (m.Encrypted != m2.Encrypted) + { + if (!m.Encrypted) + break; + continue; + } + + if (m.Id < m2.Id) break; + if (m.Id != m2.Id) continue; + + if (m.Delta < m2.Delta) break; + if (m.Delta != m2.Delta) continue; + */ + } + // filters.Insert(i, m); + // return i; + return filters.Add(m); +} + +static inline bool Is86Filter(CMethodId m) +{ + return (m == k_BCJ || m == k_BCJ2); +} + +static inline bool IsExeFilter(CMethodId m) +{ + switch (m) + { + case k_ARM64: + case k_RISCV: + case k_BCJ: + case k_BCJ2: + case k_ARM: + case k_ARMT: + case k_PPC: + case k_SPARC: + case k_IA64: + return true; + default: break; + } + return false; +} + +static unsigned Get_FilterGroup_for_Folder( + CRecordVector &filters, const CFolderEx &f, bool extractFilter) +{ + CFilterMode2 m; + // m.Id = 0; + // m.Delta = 0; + // m.Offset = 0; + m.Encrypted = f.IsEncrypted(); + + if (extractFilter) + { + const CCoderInfo &coder = f.Coders[f.UnpackCoder]; + + if (coder.MethodID == k_Delta) + { + if (coder.Props.Size() == 1) + { + m.Delta = (unsigned)coder.Props[0] + 1; + m.Id = k_Delta; + } + } + else if (IsExeFilter(coder.MethodID)) + { + m.Id = (UInt32)coder.MethodID; + if (m.Id == k_BCJ2) + m.Id = k_BCJ; + m.SetDelta(); + if (m.Id == k_ARM64 || + m.Id == k_RISCV) + if (coder.Props.Size() == 4) + m.Offset = GetUi32(coder.Props); + } + } + + return GetGroup(filters, m); +} + + + + +static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, + UInt64 position, UInt64 size, ICompressProgressInfo *progress) +{ + RINOK(InStream_SeekSet(inStream, position)) + CMyComPtr2_Create streamSpec; + streamSpec->SetStream(inStream); + streamSpec->Init(size); + CMyComPtr2_Create copyCoder; + RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, progress)) + return (copyCoder->TotalSize == size ? S_OK : E_FAIL); +} + +/* +unsigned CUpdateItem::GetExtensionPos() const +{ + int slashPos = Name.ReverseFind_PathSepar(); + int dotPos = Name.ReverseFind_Dot(); + if (dotPos <= slashPos) + return Name.Len(); + return dotPos + 1; +} + +UString CUpdateItem::GetExtension() const +{ + return Name.Ptr(GetExtensionPos()); +} +*/ + +#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; } + +#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b)) + +/* +static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) +{ + size_t c1 = a1.GetCapacity(); + size_t c2 = a2.GetCapacity(); + RINOZ_COMP(c1, c2); + for (size_t i = 0; i < c1; i++) + RINOZ_COMP(a1[i], a2[i]); + return 0; +} + +static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2) +{ + RINOZ_COMP(c1.NumInStreams, c2.NumInStreams); + RINOZ_COMP(c1.NumOutStreams, c2.NumOutStreams); + RINOZ_COMP(c1.MethodID, c2.MethodID); + return CompareBuffers(c1.Props, c2.Props); +} + +static int CompareBonds(const CBond &b1, const CBond &b2) +{ + RINOZ_COMP(b1.InIndex, b2.InIndex); + return MyCompare(b1.OutIndex, b2.OutIndex); +} + +static int CompareFolders(const CFolder &f1, const CFolder &f2) +{ + int s1 = f1.Coders.Size(); + int s2 = f2.Coders.Size(); + RINOZ_COMP(s1, s2); + int i; + for (i = 0; i < s1; i++) + RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i])); + s1 = f1.Bonds.Size(); + s2 = f2.Bonds.Size(); + RINOZ_COMP(s1, s2); + for (i = 0; i < s1; i++) + RINOZ(CompareBonds(f1.Bonds[i], f2.Bonds[i])); + return 0; +} +*/ + +/* +static int CompareFiles(const CFileItem &f1, const CFileItem &f2) +{ + return CompareFileNames(f1.Name, f2.Name); +} +*/ + +struct CFolderRepack +{ + unsigned FolderIndex; + CNum NumCopyFiles; +}; + +/* +static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *) +{ + int i1 = p1->FolderIndex; + int i2 = p2->FolderIndex; + // In that version we don't want to parse folders here, so we don't compare folders + // probably it must be improved in future + // const CDbEx &db = *(const CDbEx *)param; + // RINOZ(CompareFolders( + // db.Folders[i1], + // db.Folders[i2])); + + return MyCompare(i1, i2); + + // RINOZ_COMP( + // db.NumUnpackStreamsVector[i1], + // db.NumUnpackStreamsVector[i2]); + // if (db.NumUnpackStreamsVector[i1] == 0) + // return 0; + // return CompareFiles( + // db.Files[db.FolderStartFileIndex[i1]], + // db.Files[db.FolderStartFileIndex[i2]]); +} +*/ + +/* + we sort empty files and dirs in such order: + - Dir.NonAnti (name sorted) + - File.NonAnti (name sorted) + - File.Anti (name sorted) + - Dir.Anti (reverse name sorted) +*/ + +static int CompareEmptyItems(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &updateItems = *(const CObjectVector *)param; + const CUpdateItem &u1 = updateItems[*p1]; + const CUpdateItem &u2 = updateItems[*p2]; + // NonAnti < Anti + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); + if (u1.IsDir != u2.IsDir) + { + // Dir.NonAnti < File < Dir.Anti + if (u1.IsDir) + return (u1.IsAnti ? 1 : -1); + return (u2.IsAnti ? -1 : 1); + } + int n = CompareFileNames(u1.Name, u2.Name); + return (u1.IsDir && u1.IsAnti) ? -n : n; +} + +static const char *g_Exts = + " 7z xz lzma ace arc arj bz tbz bz2 tbz2 cab deb gz tgz ha lha lzh lzo lzx pak rar rpm sit zoo" + " zip jar ear war msi" + " 3gp avi mov mpeg mpg mpe wmv" + " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav" + " swf" + " chm hxi hxs" + " gif jpeg jpg jp2 png tiff bmp ico psd psp" + " awg ps eps cgm dxf svg vrml wmf emf ai md" + " cad dwg pps key sxi" + " max 3ds" + " iso bin nrg mdf img pdi tar cpio xpi" + " vfd vhd vud vmc vsv" + " vmdk dsk nvram vmem vmsd vmsn vmss vmtm" + " inl inc idl acf asa" + " h hpp hxx c cpp cxx m mm go swift" + " rc java cs rs pas bas vb cls ctl frm dlg def" + " f77 f f90 f95" + " asm s" + " sql manifest dep" + " mak clw csproj vcproj sln dsp dsw" + " class" + " bat cmd bash sh" + " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" + " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs" + " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf" + " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf" + " abw afp cwk lwp wpd wps wpt wrf wri" + " abf afm bdf fon mgf otf pcf pfa snf ttf" + " dbf mdb nsf ntf wdb db fdb gdb" + " exe dll ocx vbx sfx sys tlb awx com obj lib out o so" + " pdb pch idb ncb opt"; + +static unsigned GetExtIndex(const char *ext) +{ + unsigned extIndex = 1; + const char *p = g_Exts; + for (;;) + { + char c = *p++; + if (c == 0) + return extIndex; + if (c == ' ') + continue; + unsigned pos = 0; + for (;;) + { + char c2 = ext[pos++]; + if (c2 == 0 && (c == 0 || c == ' ')) + return extIndex; + if (c != c2) + break; + c = *p++; + } + extIndex++; + for (;;) + { + if (c == 0) + return extIndex; + if (c == ' ') + break; + c = *p++; + } + } +} + +struct CRefItem +{ + const CUpdateItem *UpdateItem; + UInt32 Index; + unsigned ExtensionPos; + unsigned NamePos; + unsigned ExtensionIndex; + + CRefItem() {} + CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType): + UpdateItem(&ui), + Index(index), + ExtensionPos(0), + NamePos(0), + ExtensionIndex(0) + { + if (sortByType) + { + const int slashPos = ui.Name.ReverseFind_PathSepar(); + NamePos = (unsigned)(slashPos + 1); + const int dotPos = ui.Name.ReverseFind_Dot(); + if (dotPos <= slashPos) + ExtensionPos = ui.Name.Len(); + else + { + ExtensionPos = (unsigned)(dotPos + 1); + if (ExtensionPos != ui.Name.Len()) + { + AString s; + for (unsigned pos = ExtensionPos;; pos++) + { + const wchar_t c = ui.Name[pos]; + if (c >= 0x80) + break; + if (c == 0) + { + ExtensionIndex = GetExtIndex(s); + break; + } + s.Add_Char((char)MyCharLower_Ascii((char)c)); + } + } + } + } + } +}; + +struct CSortParam +{ + // const CObjectVector *TreeFolders; + bool SortByType; +}; + +/* + we sort files in such order: + - Dir.NonAnti (name sorted) + - alt streams + - Dirs + - Dir.Anti (reverse name sorted) +*/ + + +static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param) +{ + const CRefItem &a1 = *p1; + const CRefItem &a2 = *p2; + const CUpdateItem &u1 = *a1.UpdateItem; + const CUpdateItem &u2 = *a2.UpdateItem; + + /* + if (u1.IsAltStream != u2.IsAltStream) + return u1.IsAltStream ? 1 : -1; + */ + + // Actually there are no dirs that time. They were stored in other steps + // So that code is unused? + if (u1.IsDir != u2.IsDir) + return u1.IsDir ? 1 : -1; + if (u1.IsDir) + { + if (u1.IsAnti != u2.IsAnti) + return (u1.IsAnti ? 1 : -1); + int n = CompareFileNames(u1.Name, u2.Name); + return -n; + } + + // bool sortByType = *(bool *)param; + const CSortParam *sortParam = (const CSortParam *)param; + const bool sortByType = sortParam->SortByType; + if (sortByType) + { + RINOZ_COMP(a1.ExtensionIndex, a2.ExtensionIndex) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.ExtensionPos), u2.Name.Ptr(a2.ExtensionPos))) + RINOZ(CompareFileNames(u1.Name.Ptr(a1.NamePos), u2.Name.Ptr(a2.NamePos))) + if (!u1.MTimeDefined && u2.MTimeDefined) return 1; + if (u1.MTimeDefined && !u2.MTimeDefined) return -1; + if (u1.MTimeDefined && u2.MTimeDefined) RINOZ_COMP(u1.MTime, u2.MTime) + RINOZ_COMP(u1.Size, u2.Size) + } + /* + int par1 = a1.UpdateItem->ParentFolderIndex; + int par2 = a2.UpdateItem->ParentFolderIndex; + const CTreeFolder &tf1 = (*sortParam->TreeFolders)[par1]; + const CTreeFolder &tf2 = (*sortParam->TreeFolders)[par2]; + + int b1 = tf1.SortIndex, e1 = tf1.SortIndexEnd; + int b2 = tf2.SortIndex, e2 = tf2.SortIndexEnd; + if (b1 < b2) + { + if (e1 <= b2) + return -1; + // p2 in p1 + int par = par2; + for (;;) + { + const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; + par = tf.Parent; + if (par == par1) + { + RINOZ(CompareFileNames(u1.Name, tf.Name)); + break; + } + } + } + else if (b2 < b1) + { + if (e2 <= b1) + return 1; + // p1 in p2 + int par = par1; + for (;;) + { + const CTreeFolder &tf = (*sortParam->TreeFolders)[par]; + par = tf.Parent; + if (par == par2) + { + RINOZ(CompareFileNames(tf.Name, u2.Name)); + break; + } + } + } + */ + // RINOZ_COMP(a1.UpdateItem->ParentSortIndex, a2.UpdateItem->ParentSortIndex); + RINOK(CompareFileNames(u1.Name, u2.Name)) + RINOZ_COMP(a1.UpdateItem->IndexInClient, a2.UpdateItem->IndexInClient) + RINOZ_COMP(a1.UpdateItem->IndexInArchive, a2.UpdateItem->IndexInArchive) + return 0; +} + +struct CSolidGroup +{ + CRecordVector Indices; + + CRecordVector folderRefs; +}; + +static const char * const g_Exe_Exts[] = +{ + "dll" + , "exe" + , "ocx" + , "sfx" + , "sys" +}; + +static const char * const g_ExeUnix_Exts[] = +{ + "so" + , "dylib" +}; + +static bool IsExt_Exe(const wchar_t *ext) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exe_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_Exe_Exts[i])) + return true; + return false; +} + +/* +static bool IsExt_ExeUnix(const wchar_t *ext) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + if (StringsAreEqualNoCase_Ascii(ext, g_ExeUnix_Exts[i])) + return true; + return false; +} +*/ + +// we try to find "so" extension in such name: libstdc++.so.6.0.29 +static bool IsExt_ExeUnix_NumericAllowed(const UString &path) +{ + unsigned pos = path.Len(); + unsigned dotPos = pos; + for (;;) + { + if (pos == 0) + return false; + const wchar_t c = path[--pos]; + if (IS_PATH_SEPAR(c)) + return false; + if (c == '.') + { + const unsigned num = (dotPos - pos) - 1; + if (num < 1) + return false; + const wchar_t *cur = path.Ptr(pos + 1); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExeUnix_Exts); i++) + { + const char *ext = g_ExeUnix_Exts[i]; + if (num == MyStringLen(ext)) + if (IsString1PrefixedByString2_NoCase_Ascii(cur, ext)) + return true; + } + const wchar_t *end; + ConvertStringToUInt32(cur, &end); + if ((size_t)(end - cur) != num) + return false; + dotPos = pos; + } + } +} + + +struct CAnalysis +{ + CMyComPtr Callback; + CByteBuffer Buffer; + + bool ParseWav; + bool ParseExe; + bool ParseExeUnix; + bool ParseNoExt; + bool ParseAll; + + /* + bool Need_ATime; + bool ATime_Defined; + FILETIME ATime; + */ + + CAnalysis(): + ParseWav(false), + ParseExe(false), + ParseExeUnix(false), + ParseNoExt(false), + ParseAll(false) + /* + , Need_ATime(false) + , ATime_Defined(false) + */ + {} + + HRESULT GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode); +}; + +static const size_t kAnalysisBufSize = 1 << 14; + +HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMode &filterMode) +{ + filterMode.Id = 0; + filterMode.Delta = 0; + filterMode.Offset = 0; + + CFilterMode filterModeTemp = filterMode; + + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); + + // if (dotPos > slashPos) + { + bool needReadFile = ParseAll; + /* if (Callback) is not supported by client, + we still try to use file name extension to detect executable file */ + bool probablyIsSameIsa = false; + + if (!needReadFile || !Callback) + { + const wchar_t *ext = NULL; + if (dotPos > slashPos) + ext = ui.Name.Ptr((unsigned)(dotPos + 1)); + // 7-zip stores posix attributes in high 16 bits and sets (0x8000) flag + if (ui.Attrib & 0x8000) + { + const unsigned st_mode = ui.Attrib >> 16; + /* note: executable ".so" can be without execute permission, + and symbolic link to such ".so" file is possible */ + // st_mode = 00111; // for debug + /* in Linux we expect such permissions: + 0755 : for most executables + 0644 : for some ".so" files + 0777 : in WSL for all files. + We can try to exclude some such 0777 cases from analysis, + if there is non-executable extension. + */ + + if ((st_mode & ( + MY_LIN_S_IXUSR | + MY_LIN_S_IXGRP | + MY_LIN_S_IXOTH)) != 0 + && MY_LIN_S_ISREG(st_mode) + && (ui.Size >= (1u << 11))) + { + #ifndef _WIN32 + probablyIsSameIsa = true; + #endif + needReadFile = true; + } + } + + if (!needReadFile) + { + if (!ext) + needReadFile = ParseNoExt; + else + { + bool isUnixExt = false; + if (ParseExeUnix) + isUnixExt = IsExt_ExeUnix_NumericAllowed(ui.Name); + if (isUnixExt) + { + needReadFile = true; + #ifndef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (IsExt_Exe(ext)) + { + needReadFile = ParseExe; + #ifdef _WIN32 + probablyIsSameIsa = true; + #endif + } + else if (StringsAreEqualNoCase_Ascii(ext, "wav")) + { + if (!needReadFile) + needReadFile = ParseWav; + } + } + } + } + + if (needReadFile) + { + BoolInt parseRes = false; + if (Callback) + { + if (Buffer.Size() != kAnalysisBufSize) + Buffer.Alloc(kAnalysisBufSize); + CMyComPtr stream; + HRESULT result = Callback->GetStream2(index, &stream, NUpdateNotifyOp::kAnalyze); + if (result == S_OK && stream) + { + /* + if (Need_ATime) + { + // access time could be changed in analysis pass + CMyComPtr getProps; + stream.QueryInterface(IID_IStreamGetProps, (void **)&getProps); + if (getProps) + if (getProps->GetProps(NULL, NULL, &ATime, NULL, NULL) == S_OK) + ATime_Defined = true; + } + */ + size_t size = kAnalysisBufSize; + result = ReadStream(stream, Buffer, &size); + stream.Release(); + // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK)); + if (result == S_OK) + { + parseRes = ParseFile(Buffer, size, &filterModeTemp); + } + } + } // Callback + else if (probablyIsSameIsa) + { + #ifdef MY_CPU_X86_OR_AMD64 + filterModeTemp.Id = k_X86; + #endif + #ifdef MY_CPU_ARM64 + filterModeTemp.Id = k_ARM64; + #endif + #ifdef MY_CPU_RISCV + filterModeTemp.Id = k_RISCV; + #endif + #ifdef MY_CPU_SPARC + filterModeTemp.Id = k_SPARC; + #endif + parseRes = true; + } + + if (parseRes + && filterModeTemp.Id != k_Delta + && filterModeTemp.Delta == 0) + { + /* ParseFile() sets (filterModeTemp.Delta == 0) for all + methods except of k_Delta. */ + // it's not k_Delta + // So we call SetDelta() to set Delta + filterModeTemp.SetDelta(); + if (filterModeTemp.Delta > 1) + { + /* If file Size is not aligned, then branch filter + will not work for next file in solid block. + Maybe we should allow filter for non-aligned-size file in non-solid archives ? + */ + if (ui.Size % filterModeTemp.Delta != 0) + parseRes = false; + // windows exe files are not aligned for 4 KiB. + /* + else if (filterModeTemp.Id == k_ARM64 && filterModeTemp.Offset != 0) + { + if (ui.Size % (1 << 12) != 0) + { + // If Size is not aligned for 4 KiB, then Offset will not work for next file in solid block. + // so we place such file in group with (Offset==0). + filterModeTemp.Offset = 0; + } + } + */ + } + } + if (!parseRes) + filterModeTemp.ClearFilterMode(); + } + } + + filterMode = filterModeTemp; + return S_OK; +} + +static inline void GetMethodFull(UInt64 methodID, UInt32 numStreams, CMethodFull &m) +{ + m.Id = methodID; + m.NumStreams = numStreams; +} + + +// we add bond for mode.Methods[0] that is filter +static HRESULT AddBondForFilter(CCompressionMethodMode &mode) +{ + for (unsigned c = 1; c < mode.Methods.Size(); c++) + { + if (!mode.IsThereBond_to_Coder(c)) + { + CBond2 bond; + bond.OutCoder = 0; + bond.OutStream = 0; + bond.InCoder = c; + mode.Bonds.Add(bond); + return S_OK; + } + } + return E_INVALIDARG; +} + +/* +static HRESULT AddBondForFilter_if_ThereAreBonds(CCompressionMethodMode &mode) +{ + if (!mode.Bonds.IsEmpty()) + return AddBondForFilter(mode); + return S_OK; +} +*/ + +static HRESULT AddBcj2Methods(CCompressionMethodMode &mode) +{ + // mode.Methods[0] must be k_BCJ2 method ! + // mode.Methods[1] : we expect that there is at least one method after BCJ2 + + CMethodFull m; + GetMethodFull(k_LZMA, 1, m); + + m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20); + m.AddProp32(NCoderPropID::kNumFastBytes, 128); + m.AddProp32(NCoderPropID::kNumThreads, 1); + m.AddProp32(NCoderPropID::kLitPosBits, 2); + m.AddProp32(NCoderPropID::kLitContextBits, 0); + // m.AddProp_Ascii(NCoderPropID::kMatchFinder, "BT2"); + + const unsigned methodIndex = mode.Methods.Size(); + + if (mode.Bonds.IsEmpty()) + { + for (unsigned i = 1; i + 1 < mode.Methods.Size(); i++) + { + CBond2 bond; + bond.OutCoder = i; + bond.OutStream = 0; + bond.InCoder = i + 1; + mode.Bonds.Add(bond); + } + } + + mode.Methods.Add(m); + mode.Methods.Add(m); + + RINOK(AddBondForFilter(mode)) + CBond2 bond; + bond.OutCoder = 0; // index of BCJ2 coder + bond.InCoder = methodIndex; bond.OutStream = 1; mode.Bonds.Add(bond); + bond.InCoder = methodIndex + 1; bond.OutStream = 2; mode.Bonds.Add(bond); + return S_OK; +} + + +static HRESULT MakeExeMethod(CCompressionMethodMode &mode, + const CFilterMode &filterMode, + const bool bcj2_IsAllowed, + const CUIntVector &disabledFilterIDs) +{ + if (mode.Filter_was_Inserted) + { + // filter was inserted, but bond for that filter was not added still. + const CMethodFull &m = mode.Methods[0]; + if (m.Id == k_BCJ2) + return AddBcj2Methods(mode); + if (!m.IsSimpleCoder()) + return E_NOTIMPL; + if (mode.Bonds.IsEmpty()) + return S_OK; + return AddBondForFilter(mode); + } + + if (filterMode.Id == 0) + return S_OK; + + unsigned nextCoder; + + const bool useBcj2 = bcj2_IsAllowed + && Is86Filter(filterMode.Id) + && disabledFilterIDs.FindInSorted(k_BCJ2) < 0; + + if (!useBcj2 && disabledFilterIDs.FindInSorted(filterMode.Id) >= 0) + { + // required filter is disabled, + // but we still can use information about data alignment. +#if 0 // 1 for debug + // we can return here, if we want default lzma properties + return S_OK; +#else + // we will try to change lzma/lzma2 properties + nextCoder = 0; + if (!mode.Bonds.IsEmpty()) + for (unsigned c = 0;; c++) + { + if (c == mode.Methods.Size()) + return S_OK; + if (!mode.IsThereBond_to_Coder(c)) + { + nextCoder = c; + break; + } + } +#endif + } + else + { + // we insert new filter method: + CMethodFull &m = mode.Methods.InsertNew(0); // 0 == index of new inserted item + { + // we move all coder indexes in bonds up for 1 position: + FOR_VECTOR (k, mode.Bonds) + { + CBond2 &bond = mode.Bonds[k]; + bond.InCoder++; + bond.OutCoder++; + } + } + if (useBcj2) + { + GetMethodFull(k_BCJ2, 4, m); + return AddBcj2Methods(mode); + } + + GetMethodFull(filterMode.Id, 1, m); + + if (filterMode.Id == k_Delta) + m.AddProp32(NCoderPropID::kDefaultProp, filterMode.Delta); + else if (filterMode.Id == k_ARM64 + || filterMode.Id == k_RISCV) + { + // if (filterMode.Offset != 0) + m.AddProp32( + NCoderPropID::kDefaultProp, + // NCoderPropID::kBranchOffset, + filterMode.Offset); + } + + nextCoder = 1; + if (!mode.Bonds.IsEmpty()) + { + RINOK(AddBondForFilter(mode)) + nextCoder = mode.Bonds.Back().InCoder; + } + } + + if (nextCoder >= mode.Methods.Size()) + { + // we don't expect that case, if there was non-filter method. + // but we return S_OK to support filter-only case. + return S_OK; + } + + int alignBits = -1; + { + const UInt32 delta = filterMode.Delta; + if (delta == 0 || delta > 16) + { + // if (delta == 0) alignBits = GetAlignForFilterMethod(filterMode.Id); + } + else if ((delta & ((1 << 4) - 1)) == 0) alignBits = 4; + else if ((delta & ((1 << 3) - 1)) == 0) alignBits = 3; + else if ((delta & ((1 << 2) - 1)) == 0) alignBits = 2; + else if ((delta & ((1 << 1) - 1)) == 0) alignBits = 1; + // else alignBits = 0; + /* alignBits=0 is default mode for lzma/lzma2. + So we don't set alignBits=0 here. */ + } + if (alignBits <= 0) + return S_OK; + // (alignBits > 0) + CMethodFull &nextMethod = mode.Methods[nextCoder]; + if (nextMethod.Id == k_LZMA || nextMethod.Id == k_LZMA2) + if (!nextMethod.Are_Lzma_Model_Props_Defined()) + { + if (alignBits > 2 || filterMode.Id == k_Delta) + nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits); + const unsigned lc = (alignBits < 3) ? (unsigned)(3 - alignBits) : 0u; + nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc); + nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits); + } + return S_OK; +} + + +static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2) +{ + file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined; + file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined; + file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined; + file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined; + file2.IsAnti = ui.IsAnti; + // file2.IsAux = false; + file2.StartPosDefined = false; + // file2.StartPos = 0; +} + + +static void UpdateItem_To_FileItem(const CUpdateItem &ui, + CFileItem &file, CFileItem2 &file2) +{ + UpdateItem_To_FileItem2(ui, file2); + + file.Size = ui.Size; + file.IsDir = ui.IsDir; + file.HasStream = ui.HasStream(); + // file.IsAltStream = ui.IsAltStream; +} + + + +Z7_CLASS_IMP_COM_2( + CRepackInStreamWithSizes + , ISequentialInStream + , ICompressGetSubStreamSize +) + CMyComPtr _stream; + UInt64 _size; + const CBoolVector *_extractStatuses; + UInt32 _startIndex; +public: + const CDbEx *_db; + + void Init(ISequentialInStream *stream, UInt32 startIndex, const CBoolVector *extractStatuses) + { + _startIndex = startIndex; + _extractStatuses = extractStatuses; + _size = 0; + _stream = stream; + } + UInt64 GetSize() const { return _size; } +}; + +Z7_COM7F_IMF(CRepackInStreamWithSizes::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +Z7_COM7F_IMF(CRepackInStreamWithSizes::GetSubStreamSize(UInt64 subStream, UInt64 *value)) +{ + *value = 0; + if (subStream >= _extractStatuses->Size()) + return S_FALSE; // E_FAIL; + const unsigned index = (unsigned)subStream; + if ((*_extractStatuses)[index]) + { + const CFileItem &fi = _db->Files[_startIndex + index]; + if (fi.HasStream) + *value = fi.Size; + } + return S_OK; +} + + +class CRepackStreamBase +{ +protected: + bool _needWrite; + bool _fileIsOpen; + bool _calcCrc; + UInt32 _crc; + UInt64 _rem; + + const CBoolVector *_extractStatuses; + UInt32 _startIndex; + unsigned _currentIndex; + + HRESULT OpenFile(); + HRESULT CloseFile(); + HRESULT ProcessEmptyFiles(); + +public: + const CDbEx *_db; + CMyComPtr _opCallback; + CMyComPtr _extractCallback; + + HRESULT Init(UInt32 startIndex, const CBoolVector *extractStatuses); + HRESULT CheckFinishedState() const { return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; } +}; + +HRESULT CRepackStreamBase::Init(UInt32 startIndex, const CBoolVector *extractStatuses) +{ + _startIndex = startIndex; + _extractStatuses = extractStatuses; + + _currentIndex = 0; + _fileIsOpen = false; + + return ProcessEmptyFiles(); +} + +HRESULT CRepackStreamBase::OpenFile() +{ + UInt32 arcIndex = _startIndex + _currentIndex; + const CFileItem &fi = _db->Files[arcIndex]; + + _needWrite = (*_extractStatuses)[_currentIndex]; + if (_opCallback) + { + RINOK(_opCallback->ReportOperation( + NEventIndexType::kInArcIndex, arcIndex, + _needWrite ? + NUpdateNotifyOp::kRepack : + NUpdateNotifyOp::kSkip)) + } + + _crc = CRC_INIT_VAL; + _calcCrc = (fi.CrcDefined && !fi.IsDir); + + _fileIsOpen = true; + _rem = fi.Size; + return S_OK; +} + +const HRESULT k_My_HRESULT_CRC_ERROR = 0x20000002; + +HRESULT CRepackStreamBase::CloseFile() +{ + UInt32 arcIndex = _startIndex + _currentIndex; + const CFileItem &fi = _db->Files[arcIndex]; + _fileIsOpen = false; + _currentIndex++; + if (!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) + return S_OK; + + if (_extractCallback) + { + RINOK(_extractCallback->ReportExtractResult( + NEventIndexType::kInArcIndex, arcIndex, + NExtract::NOperationResult::kCRCError)) + } + // return S_FALSE; + return k_My_HRESULT_CRC_ERROR; +} + +HRESULT CRepackStreamBase::ProcessEmptyFiles() +{ + while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0) + { + RINOK(OpenFile()) + RINOK(CloseFile()) + } + return S_OK; +} + + + +#ifndef Z7_ST + +class CFolderOutStream2 Z7_final: + public CRepackStreamBase, + public ISequentialOutStream, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + CMyComPtr _stream; +}; + +Z7_COM7F_IMF(CFolderOutStream2::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (_fileIsOpen) + { + UInt32 cur = (size < _rem ? size : (UInt32)_rem); + HRESULT result = S_OK; + if (_needWrite) + result = _stream->Write(data, cur, &cur); + if (_calcCrc) + _crc = CrcUpdate(_crc, data, cur); + if (processedSize) + *processedSize += cur; + data = (const Byte *)data + cur; + size -= cur; + _rem -= cur; + if (_rem == 0) + { + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) + } + RINOK(result) + if (cur == 0) + break; + continue; + } + + RINOK(ProcessEmptyFiles()) + if (_currentIndex == _extractStatuses->Size()) + { + // we don't support write cut here + return E_FAIL; + } + RINOK(OpenFile()) + } + + return S_OK; +} + +#endif + + + +static const UInt32 kTempBufSize = 1 << 16; + +class CFolderInStream2 Z7_final: + public CRepackStreamBase, + public ISequentialInStream, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialInStream) + + Byte *_buf; +public: + CMyComPtr _inStream; + HRESULT Result; + + CFolderInStream2(): + Result(S_OK) + { + _buf = new Byte[kTempBufSize]; + } + + ~CFolderInStream2() + { + delete []_buf; + } + + void Init() { Result = S_OK; } +}; + +Z7_COM7F_IMF(CFolderInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (_fileIsOpen) + { + UInt32 cur = (size < _rem ? size : (UInt32)_rem); + + void *buf; + if (_needWrite) + buf = data; + else + { + buf = _buf; + if (cur > kTempBufSize) + cur = kTempBufSize; + } + + const HRESULT result = _inStream->Read(buf, cur, &cur); + _crc = CrcUpdate(_crc, buf, cur); + _rem -= cur; + + if (_needWrite) + { + data = (Byte *)data + cur; + size -= cur; + if (processedSize) + *processedSize += cur; + } + + if (result != S_OK) + Result = result; + + if (_rem == 0) + { + RINOK(CloseFile()) + RINOK(ProcessEmptyFiles()) + } + + RINOK(result) + + if (cur == 0) + return E_FAIL; + + continue; + } + + RINOK(ProcessEmptyFiles()) + if (_currentIndex == _extractStatuses->Size()) + { + return S_OK; + } + RINOK(OpenFile()) + } + + return S_OK; +} + + +class CThreadDecoder Z7_final + #ifndef Z7_ST + : public CVirtThread + #endif +{ +public: + CDecoder Decoder; + + CThreadDecoder(bool multiThreadMixer): + Decoder(multiThreadMixer) + { + #ifndef Z7_ST + if (multiThreadMixer) + { + MtMode = false; + NumThreads = 1; + FosSpec = new CFolderOutStream2; + Fos = FosSpec; + Result = E_FAIL; + } + #endif + // UnpackSize = 0; + // send_UnpackSize = false; + } + + #ifndef Z7_ST + + bool dataAfterEnd_Error; + HRESULT Result; + CMyComPtr InStream; + + CFolderOutStream2 *FosSpec; + CMyComPtr Fos; + + UInt64 StartPos; + const CFolders *Folders; + unsigned FolderIndex; + + // bool send_UnpackSize; + // UInt64 UnpackSize; + + #ifndef Z7_NO_CRYPTO + CMyComPtr getTextPassword; + #endif + + DECL_EXTERNAL_CODECS_LOC_VARS_DECL + + #ifndef Z7_ST + bool MtMode; + UInt32 NumThreads; + #endif + + + ~CThreadDecoder() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before + destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } +private: + virtual void Execute() Z7_override; + + #endif +}; + +#ifndef Z7_ST + +void CThreadDecoder::Execute() +{ + try + { + #ifndef Z7_NO_CRYPTO + bool isEncrypted = false; + bool passwordIsDefined = false; + UString password; + #endif + + dataAfterEnd_Error = false; + + Result = Decoder.Decode( + EXTERNAL_CODECS_LOC_VARS + InStream, + StartPos, + *Folders, FolderIndex, + + // send_UnpackSize ? &UnpackSize : NULL, + NULL, // unpackSize : FULL unpack + + Fos, + NULL, // compressProgress + + NULL // *inStreamMainRes + , dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST + , MtMode, NumThreads, + 0 // MemUsage + #endif + + ); + } + catch(...) + { + Result = E_FAIL; + } + + /* + if (Result == S_OK) + Result = FosSpec->CheckFinishedState(); + */ + FosSpec->_stream.Release(); +} + +#endif + +#ifndef Z7_NO_CRYPTO + +Z7_CLASS_IMP_NOQIB_1( + CCryptoGetTextPassword + , ICryptoGetTextPassword +) +public: + UString Password; +}; + +Z7_COM7F_IMF(CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)) +{ + return StringToBstr(Password, password); +} + +#endif + + +static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFileItem2 &file2) +{ + file = inDb.Files[index]; + file2.CTimeDefined = inDb.CTime.GetItem(index, file2.CTime); + file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime); + file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime); + file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos); + file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib); + file2.IsAnti = inDb.IsItemAnti(index); + // file2.IsAux = inDb.IsItemAux(index); +} + +HRESULT Update( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + const CDbEx *db, + CObjectVector &updateItems, + // const CObjectVector &treeFolders, + // const CUniqBlocks &secureBlocks, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options) +{ + UInt64 numSolidFiles = options.NumSolidFiles; + if (numSolidFiles == 0) + numSolidFiles = 1; + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveExtractCallbackMessage2, + extractCallback, updateCallback) + + /* + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackArcProp, + reportArcProp, updateCallback) + */ + + // size_t totalSecureDataSize = (size_t)secureBlocks.GetTotalSizeInBytes(); + + CMyComPtr v_StreamSetRestriction; + { + Z7_DECL_CMyComPtr_QI_FROM( + IOutStream, + outStream, seqOutStream) + if (!outStream) + return E_NOTIMPL; + const UInt64 sfxBlockSize = (db && !options.RemoveSfxBlock) ? + db->ArcInfo.StartPosition: 0; + seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&v_StreamSetRestriction); + if (v_StreamSetRestriction) + { + UInt64 offset = 0; + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &offset)) + RINOK(v_StreamSetRestriction->SetRestriction( + outStream ? offset + sfxBlockSize : 0, + outStream ? offset + sfxBlockSize + k_StartHeadersRewriteSize : 0)) + } + outStream.Release(); + if (sfxBlockSize != 0) + { + RINOK(WriteRange(inStream, seqOutStream, 0, sfxBlockSize, NULL)) + } + } + + CIntArr fileIndexToUpdateIndexMap; + UInt64 complexity = 0; + bool isThere_UnknownSize = false; + UInt64 inSizeForReduce2 = 0; + + #ifndef Z7_NO_CRYPTO + bool needEncryptedRepack = false; + #endif + + CRecordVector filters; + CObjectVector groups; + + #ifndef Z7_ST + bool thereAreRepacks = false; + #endif + + bool useFilters = options.UseFilters; + if (useFilters) + { + const CCompressionMethodMode &method = *options.Method; + + FOR_VECTOR (i, method.Methods) + { + /* IsFilterMethod() knows only built-in codecs + FIXME: we should check IsFilter status for external filters too */ + if (IsFilterMethod(method.Methods[i].Id)) + { + useFilters = false; + break; + } + } + } + + if (db) + { + fileIndexToUpdateIndexMap.Alloc(db->Files.Size()); + unsigned i; + + for (i = 0; i < db->Files.Size(); i++) + fileIndexToUpdateIndexMap[i] = -1; + + for (i = 0; i < updateItems.Size(); i++) + { + int index = updateItems[i].IndexInArchive; + if (index != -1) + fileIndexToUpdateIndexMap[(unsigned)index] = (int)i; + } + + for (i = 0; i < db->NumFolders; i++) + { + CNum indexInFolder = 0; + CNum numCopyItems = 0; + const CNum numUnpackStreams = db->NumUnpackStreamsVector[i]; + UInt64 repackSize = 0; + + for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++) + { + if (fi >= db->Files.Size()) + return E_FAIL; + + const CFileItem &file = db->Files[fi]; + if (file.HasStream) + { + indexInFolder++; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) + { + numCopyItems++; + repackSize += file.Size; + } + } + } + + if (numCopyItems == 0) + continue; + + CFolderRepack rep; + rep.FolderIndex = i; + rep.NumCopyFiles = numCopyItems; + CFolderEx f; + db->ParseFolderEx(i, f); + + #ifndef Z7_NO_CRYPTO + const bool isEncrypted = f.IsEncrypted(); + #endif + const bool needCopy = (numCopyItems == numUnpackStreams); + const bool extractFilter = (useFilters || needCopy); + + const unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter); + + while (groupIndex >= groups.Size()) + groups.AddNew(); + + groups[groupIndex].folderRefs.Add(rep); + + if (needCopy) + complexity += db->GetFolderFullPackSize(i); + else + { + #ifndef Z7_ST + thereAreRepacks = true; + #endif + complexity += repackSize; + if (inSizeForReduce2 < repackSize) + inSizeForReduce2 = repackSize; + #ifndef Z7_NO_CRYPTO + if (isEncrypted) + needEncryptedRepack = true; + #endif + } + } + } + + UInt64 inSizeForReduce = 0; + { + const bool isSolid = (numSolidFiles > 1 && options.NumSolidBytes != 0); + FOR_VECTOR (i, updateItems) + { + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + { + if (ui.Size == (UInt64)(Int64)-1) + isThere_UnknownSize = true; + else + { + complexity += ui.Size; + if (isSolid) + inSizeForReduce += ui.Size; + else if (inSizeForReduce < ui.Size) + inSizeForReduce = ui.Size; + } + } + } + } + + if (isThere_UnknownSize) + inSizeForReduce = (UInt64)(Int64)-1; + else + RINOK(updateCallback->SetTotal(complexity)) + + if (inSizeForReduce < inSizeForReduce2) + inSizeForReduce = inSizeForReduce2; + + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + #ifndef Z7_ST + + CStreamBinder sb; + /* + if (options.MultiThreadMixer) + { + RINOK(sb.CreateEvents()); + } + */ + + #endif + + CThreadDecoder threadDecoder(options.MultiThreadMixer); + + #ifndef Z7_ST + if (options.MultiThreadMixer && thereAreRepacks) + { + #ifdef Z7_EXTERNAL_CODECS + threadDecoder._externalCodecs = _externalCodecs; + #endif + const WRes wres = threadDecoder.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + #endif + + { + CAnalysis analysis; + // analysis.Need_ATime = options.Need_ATime; + int analysisLevel = options.AnalysisLevel; + // (analysisLevel < 0) means default level (5) + if (analysisLevel < 0) + analysisLevel = 5; + if (analysisLevel != 0) + { + analysis.Callback = opCallback; + analysis.ParseWav = true; + if (analysisLevel >= 5) + { + analysis.ParseExe = true; + analysis.ParseExeUnix = true; + // analysis.ParseNoExt = true; + if (analysisLevel >= 7) + { + analysis.ParseNoExt = true; + if (analysisLevel >= 9) + analysis.ParseAll = true; + } + } + } + + // ---------- Split files to groups ---------- + + const CCompressionMethodMode &method = *options.Method; + + FOR_VECTOR (i, updateItems) + { + const CUpdateItem &ui = updateItems[i]; + if (!ui.NewData || !ui.HasStream()) + continue; + + 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; + + const unsigned groupIndex = GetGroup(filters, fm); + while (groupIndex >= groups.Size()) + groups.AddNew(); + groups[groupIndex].Indices.Add(i); + } + } + + + #ifndef Z7_NO_CRYPTO + + CCryptoGetTextPassword *getPasswordSpec = NULL; + CMyComPtr getTextPassword; + if (needEncryptedRepack) + { + getPasswordSpec = new CCryptoGetTextPassword; + getTextPassword = getPasswordSpec; + + #ifndef Z7_ST + threadDecoder.getTextPassword = getPasswordSpec; + #endif + + if (options.Method->PasswordIsDefined) + getPasswordSpec->Password = options.Method->Password; + else + { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getDecoderPassword, updateCallback) + if (!getDecoderPassword) + return E_NOTIMPL; + CMyComBSTR password; + RINOK(getDecoderPassword->CryptoGetTextPassword(&password)) + if (password) + getPasswordSpec->Password = password; + } + } + + #endif + + // ---------- Compress ---------- + + COutArchive archive; + CArchiveDatabaseOut newDatabase; + + RINOK(archive.Create_and_WriteStartPrefix(seqOutStream)) + + /* + CIntVector treeFolderToArcIndex; + treeFolderToArcIndex.Reserve(treeFolders.Size()); + for (i = 0; i < treeFolders.Size(); i++) + treeFolderToArcIndex.Add(-1); + // ---------- Write Tree (only AUX dirs) ---------- + for (i = 1; i < treeFolders.Size(); i++) + { + const CTreeFolder &treeFolder = treeFolders[i]; + CFileItem file; + CFileItem2 file2; + file2.Init(); + int secureID = 0; + if (treeFolder.UpdateItemIndex < 0) + { + // we can store virtual dir item wuthout attrib, but we want all items have attrib. + file.SetAttrib(FILE_ATTRIBUTE_DIRECTORY); + file2.IsAux = true; + } + else + { + const CUpdateItem &ui = updateItems[treeFolder.UpdateItemIndex]; + // if item is not dir, then it's parent for alt streams. + // we will write such items later + if (!ui.IsDir) + continue; + secureID = ui.SecureIndex; + if (ui.NewProps) + UpdateItem_To_FileItem(ui, file, file2); + else + GetFile(*db, ui.IndexInArchive, file, file2); + } + file.Size = 0; + file.HasStream = false; + file.IsDir = true; + file.Parent = treeFolder.Parent; + + treeFolderToArcIndex[i] = newDatabase.Files.Size(); + newDatabase.AddFile(file, file2, treeFolder.Name); + + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(secureID); + } + */ + + { + /* ---------- Write non-AUX dirs and Empty files ---------- */ + CUIntVector emptyRefs; + + unsigned i; + + for (i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + { + if (ui.HasStream()) + continue; + } + else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream) + continue; + /* + if (ui.TreeFolderIndex >= 0) + continue; + */ + emptyRefs.Add(i); + } + + emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); + + for (i = 0; i < emptyRefs.Size(); i++) + { + const CUpdateItem &ui = updateItems[emptyRefs[i]]; + CFileItem file; + CFileItem2 file2; + UString name; + if (ui.NewProps) + { + UpdateItem_To_FileItem(ui, file, file2); + file.CrcDefined = false; + name = ui.Name; + } + else + { + GetFile(*db, (unsigned)ui.IndexInArchive, file, file2); + db->GetPath((unsigned)ui.IndexInArchive, name); + } + + /* + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + file.Parent = ui.ParentFolderIndex; + */ + newDatabase.AddFile(file, file2, name); + } + } + + lps->ProgressOffset = 0; + + { + // ---------- Sort Filters ---------- + FOR_VECTOR (i, filters) + { + filters[i].GroupIndex = i; + } + filters.Sort2(); + } + + for (unsigned groupIndex = 0; groupIndex < filters.Size(); groupIndex++) + { + const CFilterMode2 &filterMode = filters[groupIndex]; + + CCompressionMethodMode method = *options.Method; + { + const HRESULT res = MakeExeMethod(method, filterMode, + // bcj2_IsAllowed: + #ifdef Z7_ST + false + #else + options.MaxFilter && options.MultiThreadMixer + #endif + , options.DisabledFilterIDs); + + RINOK(res) + } + + if (filterMode.Encrypted) + { + if (!method.PasswordIsDefined) + { + #ifndef Z7_NO_CRYPTO + if (getPasswordSpec) + method.Password = getPasswordSpec->Password; + #endif + method.PasswordIsDefined = true; + } + } + else + { + method.PasswordIsDefined = false; + method.Password.Empty(); + } + + CEncoder encoder(method); + + // ---------- Repack and copy old solid blocks ---------- + + const CSolidGroup &group = groups[filterMode.GroupIndex]; + + FOR_VECTOR (folderRefIndex, group.folderRefs) + { + const CFolderRepack &rep = group.folderRefs[folderRefIndex]; + + const unsigned folderIndex = rep.FolderIndex; + + const CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex]; + + if (rep.NumCopyFiles == numUnpackStreams) + { + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NUpdateNotifyOp::kReplicate)) + + // ---------- Copy old solid block ---------- + { + CNum indexInFolder = 0; + for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) + { + if (db->Files[fi].HasStream) + { + indexInFolder++; + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, (UInt32)fi, + NUpdateNotifyOp::kReplicate)) + } + } + } + } + + const UInt64 packSize = db->GetFolderFullPackSize(folderIndex); + RINOK(WriteRange(inStream, archive.SeqStream, + db->GetFolderStreamPos(folderIndex, 0), packSize, lps)) + lps->ProgressOffset += packSize; + + const unsigned folderIndex_New = newDatabase.Folders.Size(); + CFolder &folder = newDatabase.Folders.AddNew(); + // v23.01: we copy FolderCrc, if FolderCrc was used + if (db->FolderCRCs.ValidAndDefined(folderIndex)) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, db->FolderCRCs.Vals[folderIndex]); + + db->ParseFolderInfo(folderIndex, folder); + const CNum startIndex = db->FoStartPackStreamIndex[folderIndex]; + FOR_VECTOR (j, folder.PackStreams) + { + newDatabase.PackSizes.Add(db->GetStreamPackSize(startIndex + j)); + // newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]); + // newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]); + } + + size_t indexStart = db->FoToCoderUnpackSizes[folderIndex]; + const size_t indexEnd = db->FoToCoderUnpackSizes[folderIndex + 1]; + for (; indexStart < indexEnd; indexStart++) + newDatabase.CoderUnpackSizes.Add(db->CoderUnpackSizes.ConstData()[indexStart]); + } + else + { + // ---------- Repack old solid block ---------- + + CBoolVector extractStatuses; + + CNum indexInFolder = 0; + + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NUpdateNotifyOp::kRepack)) + } + + /* We could reduce data size of decoded folder, if we don't need to repack + last files in folder. But the gain in speed is small in most cases. + So we unpack full folder. */ + + UInt64 sizeToEncode = 0; + + /* + UInt64 importantUnpackSize = 0; + unsigned numImportantFiles = 0; + UInt64 decodeSize = 0; + */ + + for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) + { + bool needExtract = false; + const CFileItem &file = db->Files[fi]; + + if (file.HasStream) + { + indexInFolder++; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData) + needExtract = true; + // decodeSize += file.Size; + } + + extractStatuses.Add(needExtract); + if (needExtract) + { + sizeToEncode += file.Size; + /* + numImportantFiles = extractStatuses.Size(); + importantUnpackSize = decodeSize; + */ + } + } + + // extractStatuses.DeleteFrom(numImportantFiles); + + unsigned startPackIndex = newDatabase.PackSizes.Size(); + UInt64 curUnpackSize; + { + CMyComPtr sbInStream; + CRepackStreamBase *repackBase; + CFolderInStream2 *FosSpec2 = NULL; + + CRepackInStreamWithSizes *inStreamSizeCountSpec = new CRepackInStreamWithSizes; + CMyComPtr inStreamSizeCount = inStreamSizeCountSpec; + { + #ifndef Z7_ST + if (options.MultiThreadMixer) + { + repackBase = threadDecoder.FosSpec; + CMyComPtr sbOutStream; + sb.CreateStreams2(sbInStream, sbOutStream); + RINOK(sb.Create_ReInit()) + + threadDecoder.FosSpec->_stream = sbOutStream; + + threadDecoder.InStream = inStream; + threadDecoder.StartPos = db->ArcInfo.DataStartPosition; // db->GetFolderStreamPos(folderIndex, 0); + threadDecoder.Folders = (const CFolders *)db; + threadDecoder.FolderIndex = folderIndex; + + // threadDecoder.UnpackSize = importantUnpackSize; + // threadDecoder.send_UnpackSize = true; + } + else + #endif + { + FosSpec2 = new CFolderInStream2; + FosSpec2->Init(); + sbInStream = FosSpec2; + repackBase = FosSpec2; + + #ifndef Z7_NO_CRYPTO + bool isEncrypted = false; + bool passwordIsDefined = false; + UString password; + #endif + + CMyComPtr decodedStream; + bool dataAfterEnd_Error = false; + + const HRESULT res = threadDecoder.Decoder.Decode( + EXTERNAL_CODECS_LOC_VARS + inStream, + db->ArcInfo.DataStartPosition, // db->GetFolderStreamPos(folderIndex, 0);, + *db, folderIndex, + // &importantUnpackSize, // *unpackSize + NULL, // *unpackSize : FULL unpack + + NULL, // *outStream + NULL, // *compressProgress + + &decodedStream + , dataAfterEnd_Error + + Z7_7Z_DECODER_CRYPRO_VARS + #ifndef Z7_ST + , false // mtMode + , 1 // numThreads + , 0 // memUsage + #endif + ); + + RINOK(res) + if (!decodedStream) + return E_FAIL; + + FosSpec2->_inStream = decodedStream; + } + + repackBase->_db = db; + repackBase->_opCallback = opCallback; + repackBase->_extractCallback = extractCallback; + + UInt32 startIndex = db->FolderStartFileIndex[folderIndex]; + RINOK(repackBase->Init(startIndex, &extractStatuses)) + + inStreamSizeCountSpec->_db = db; + inStreamSizeCountSpec->Init(sbInStream, startIndex, &extractStatuses); + + #ifndef Z7_ST + if (options.MultiThreadMixer) + { + WRes wres = threadDecoder.Start(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + #endif + } + + // curUnpackSize = sizeToEncode; + + HRESULT encodeRes = encoder.Encode1( + EXTERNAL_CODECS_LOC_VARS + inStreamSizeCount, + // NULL, + &inSizeForReduce, + sizeToEncode, // expectedDataSize + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curUnpackSize, + archive.SeqStream, newDatabase.PackSizes, lps); + + if (encodeRes == k_My_HRESULT_CRC_ERROR) + return E_FAIL; + + curUnpackSize = inStreamSizeCountSpec->GetSize(); + + if (encodeRes == S_OK) + { + encoder.Encode_Post(curUnpackSize, newDatabase.CoderUnpackSizes); + } + + #ifndef Z7_ST + if (options.MultiThreadMixer) + { + // 16.00: hang was fixed : for case if decoding was not finished. + // We close CBinderInStream and it calls CStreamBinder::CloseRead() + inStreamSizeCount.Release(); + sbInStream.Release(); + + { + const WRes wres = threadDecoder.WaitExecuteFinish(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + + const HRESULT decodeRes = threadDecoder.Result; + // if (res == k_My_HRESULT_CRC_ERROR) + if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error) + { + if (extractCallback) + { + RINOK(extractCallback->ReportExtractResult( + NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex], + // NEventIndexType::kBlockIndex, (UInt32)folderIndex, + (decodeRes != S_OK ? + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kDataAfterEnd))) + } + if (decodeRes != S_OK) + return E_FAIL; + } + RINOK(decodeRes) + if (encodeRes == S_OK) + if (sb.ProcessedSize != sizeToEncode) + encodeRes = E_FAIL; + } + else + #endif + { + if (FosSpec2->Result == S_FALSE) + { + if (extractCallback) + { + RINOK(extractCallback->ReportExtractResult( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NExtract::NOperationResult::kDataError)) + } + return E_FAIL; + } + RINOK(FosSpec2->Result) + } + + RINOK(encodeRes) + RINOK(repackBase->CheckFinishedState()) + + if (curUnpackSize != sizeToEncode) + return E_FAIL; + } + + for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) + lps->OutSize += newDatabase.PackSizes[startPackIndex]; + lps->InSize += curUnpackSize; + } + + newDatabase.NumUnpackStreamsVector.Add(rep.NumCopyFiles); + + CNum indexInFolder = 0; + for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++) + { + if (db->Files[fi].HasStream) + { + indexInFolder++; + const int updateIndex = fileIndexToUpdateIndexMap[fi]; + if (updateIndex >= 0) + { + const CUpdateItem &ui = updateItems[(unsigned)updateIndex]; + if (ui.NewData) + continue; + + UString name; + CFileItem file; + CFileItem2 file2; + GetFile(*db, fi, file, file2); + + if (ui.NewProps) + { + UpdateItem_To_FileItem2(ui, file2); + file.IsDir = ui.IsDir; + name = ui.Name; + } + else + db->GetPath(fi, name); + + /* + file.Parent = ui.ParentFolderIndex; + if (ui.TreeFolderIndex >= 0) + treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + */ + newDatabase.AddFile(file, file2, name); + } + } + } + } + + + // ---------- Compress files to new solid blocks ---------- + + const unsigned numFiles = group.Indices.Size(); + if (numFiles == 0) + continue; + CRecordVector refItems; + refItems.ClearAndSetSize(numFiles); + // bool sortByType = (options.UseTypeSorting && isSoid); // numSolidFiles > 1 + const bool sortByType = options.UseTypeSorting; + + unsigned i; + + for (i = 0; i < numFiles; i++) + refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType); + + CSortParam sortParam; + // sortParam.TreeFolders = &treeFolders; + sortParam.SortByType = sortByType; + refItems.Sort(CompareUpdateItems, (void *)&sortParam); + + CObjArray indices(numFiles); + + for (i = 0; i < numFiles; i++) + { + const UInt32 index = refItems[i].Index; + indices[i] = index; + /* + const CUpdateItem &ui = updateItems[index]; + CFileItem file; + if (ui.NewProps) + UpdateItem_To_FileItem(ui, file); + else + file = db.Files[ui.IndexInArchive]; + if (file.IsAnti || file.IsDir) + return E_FAIL; + newDatabase.Files.Add(file); + */ + } + + for (i = 0; i < numFiles;) + { + UInt64 totalSize = 0; + unsigned numSubFiles; + + const wchar_t *prevExtension = NULL; + + for (numSubFiles = 0; i + numSubFiles < numFiles && numSubFiles < numSolidFiles; numSubFiles++) + { + const CUpdateItem &ui = updateItems[indices[i + numSubFiles]]; + totalSize += ui.Size; + if (totalSize > options.NumSolidBytes) + break; + if (options.SolidExtension) + { + const int slashPos = ui.Name.ReverseFind_PathSepar(); + const int dotPos = ui.Name.ReverseFind_Dot(); + const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1)); + if (numSubFiles == 0) + prevExtension = ext; + else if (!StringsAreEqualNoCase(ext, prevExtension)) + break; + } + } + + if (numSubFiles < 1) + numSubFiles = 1; + + RINOK(lps->SetCur()) + + /* + const unsigned folderIndex = newDatabase.NumUnpackStreamsVector.Size(); + + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kBlockIndex, (UInt32)folderIndex, + NUpdateNotifyOp::kAdd)); + } + */ + + + CMyComPtr2_Create inStreamSpec; // solidInStream; + + // inStreamSpec->_reportArcProp = reportArcProp; + + inStreamSpec->Need_CTime = options.Need_CTime; + inStreamSpec->Need_ATime = options.Need_ATime; + inStreamSpec->Need_MTime = options.Need_MTime; + inStreamSpec->Need_Attrib = options.Need_Attrib; + // inStreamSpec->Need_Crc = options.Need_Crc; + + inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); + + unsigned startPackIndex = newDatabase.PackSizes.Size(); + // UInt64 curFolderUnpackSize = totalSize; + // curFolderUnpackSize = (UInt64)(Int64)-1; // for debug + const UInt64 expectedDataSize = totalSize; + + // const unsigned folderIndex_New = newDatabase.Folders.Size(); + + RINOK(encoder.Encode1( + EXTERNAL_CODECS_LOC_VARS + inStreamSpec, + // NULL, + &inSizeForReduce, + expectedDataSize, // expected size + newDatabase.Folders.AddNew(), + // newDatabase.CoderUnpackSizes, curFolderUnpackSize, + archive.SeqStream, newDatabase.PackSizes, lps)) + + if (!inStreamSpec->WasFinished()) + return E_FAIL; + + /* + if (inStreamSpec->Need_FolderCrc) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, + true, inStreamSpec->GetFolderCrc()); + */ + + const UInt64 curFolderUnpackSize = inStreamSpec->Get_TotalSize_for_Coder(); + encoder.Encode_Post(curFolderUnpackSize, newDatabase.CoderUnpackSizes); + + UInt64 packSize = 0; + // const UInt32 numStreams = newDatabase.PackSizes.Size() - startPackIndex; + for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++) + packSize += newDatabase.PackSizes[startPackIndex]; + lps->OutSize += packSize; + + // for () + // newDatabase.PackCRCsDefined.Add(false); + // newDatabase.PackCRCs.Add(0); + + CNum numUnpackStreams = 0; + UInt64 skippedSize = 0; + UInt64 procSize = 0; + // unsigned numProcessedFiles = 0; + + for (unsigned subIndex = 0; subIndex < numSubFiles; subIndex++) + { + const CUpdateItem &ui = updateItems[indices[i + subIndex]]; + CFileItem file; + CFileItem2 file2; + UString name; + if (ui.NewProps) + { + UpdateItem_To_FileItem(ui, file, file2); + name = ui.Name; + } + else + { + GetFile(*db, (unsigned)ui.IndexInArchive, file, file2); + db->GetPath((unsigned)ui.IndexInArchive, name); + } + if (file2.IsAnti || file.IsDir) + return E_FAIL; + + /* + CFileItem &file = newDatabase.Files[ + startFileIndexInDatabase + i + subIndex]; + */ + if (!inStreamSpec->Processed[subIndex]) + { + // we don't add file here + skippedSize += ui.Size; + continue; // comment it for debug + // name += ".locked"; // for debug + } + + // if (inStreamSpec->Need_Crc) + file.Crc = inStreamSpec->CRCs[subIndex]; + file.Size = inStreamSpec->Sizes[subIndex]; + + procSize += file.Size; + // if (file.Size >= 0) // for debug: test purposes + if (file.Size != 0) + { + file.CrcDefined = true; // inStreamSpec->Need_Crc; + file.HasStream = true; + numUnpackStreams++; + } + else + { + file.CrcDefined = false; + 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) + treeFolderToArcIndex[ui.TreeFolderIndex] = newDatabase.Files.Size(); + if (totalSecureDataSize != 0) + newDatabase.SecureIDs.Add(ui.SecureIndex); + */ + /* + if (reportArcProp) + { + RINOK(ReportItemProps(reportArcProp, ui.IndexInClient, file.Size, + file.CrcDefined ? &file.Crc : NULL)) + } + */ + + // numProcessedFiles++; + newDatabase.AddFile(file, file2, name); + } + + /* + // for debug: + // we can write crc to folders area, if folder contains only one file + if (numUnpackStreams == 1 && numSubFiles == 1) + { + const CFileItem &file = newDatabase.Files.Back(); + if (file.CrcDefined) + newDatabase.FolderUnpackCRCs.SetItem(folderIndex_New, true, file.Crc); + } + */ + + /* + // it's optional check to ensure that sizes are correct + if (inStreamSpec->TotalSize_for_Coder != curFolderUnpackSize) + return E_FAIL; + */ + // if (inStreamSpec->AlignLog == 0) + { + if (procSize != curFolderUnpackSize) + return E_FAIL; + } + // else + { + /* + { + const CFolder &old = newDatabase.Folders.Back(); + CFolder &folder = newDatabase.Folders.AddNew(); + { + const unsigned numBonds = old.Bonds.Size(); + folder.Bonds.SetSize(numBonds + 1); + for (unsigned k = 0; k < numBonds; k++) + folder.Bonds[k] = old.Bonds[k]; + CBond &bond = folder.Bonds[numBonds]; + bond.PackIndex = 0; + bond.UnpackIndex = 0; + } + { + const unsigned numCoders = old.Coders.Size(); + folder.Coders.SetSize(numCoders + 1); + for (unsigned k = 0; k < numCoders; k++) + folder.Coders[k] = old.Coders[k]; + CCoderInfo &cod = folder.Coders[numCoders]; + cod.Props.Alloc(1); + cod.Props[0] = (Byte)inStreamSpec->AlignLog; + cod.NumStreams = 1; + } + { + const unsigned numPackStreams = old.Coders.Size(); + folder.Coders.SetSize(numPackStreams); + for (unsigned k = 0; k < numPackStreams; k++) + folder.PackStreams[k] = old.PackStreams[k]; + } + } + newDatabase.Folders.Delete(newDatabase.Folders.Size() - 2); + */ + } + + + lps->InSize += procSize; + // lps->InSize += curFolderUnpackSize; + + // numUnpackStreams = 0 is very bad case for locked files + // v3.13 doesn't understand it. + newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams); + i += numSubFiles; + + if (skippedSize != 0 && complexity >= skippedSize) + { + 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)); + } + */ + } + } + + RINOK(lps->SetCur()) + + /* + fileIndexToUpdateIndexMap.ClearAndFree(); + groups.ClearAndFree(); + */ + + /* + for (i = 0; i < newDatabase.Files.Size(); i++) + { + CFileItem &file = newDatabase.Files[i]; + file.Parent = treeFolderToArcIndex[file.Parent]; + } + + if (totalSecureDataSize != 0) + { + newDatabase.SecureBuf.SetCapacity(totalSecureDataSize); + size_t pos = 0; + newDatabase.SecureSizes.Reserve(secureBlocks.Sorted.Size()); + for (i = 0; i < secureBlocks.Sorted.Size(); i++) + { + const CByteBuffer &buf = secureBlocks.Bufs[secureBlocks.Sorted[i]]; + size_t size = buf.GetCapacity(); + if (size != 0) + memcpy(newDatabase.SecureBuf + pos, buf, size); + newDatabase.SecureSizes.Add((UInt32)size); + pos += size; + } + } + */ + + { + const unsigned numFolders = newDatabase.Folders.Size(); + if (newDatabase.NumUnpackStreamsVector.Size() != numFolders + || newDatabase.FolderUnpackCRCs.Defs.Size() > numFolders) + return E_FAIL; + newDatabase.FolderUnpackCRCs.if_NonEmpty_FillResidue_with_false(numFolders); + } + + updateItems.ClearAndFree(); + newDatabase.ReserveDown(); + + if (opCallback) + RINOK(opCallback->ReportOperation(NEventIndexType::kNoIndex, (UInt32)(Int32)-1, NUpdateNotifyOp::kHeader)) + + RINOK(archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS + newDatabase, options.HeaderMethod, options.HeaderOptions)) + + if (v_StreamSetRestriction) + RINOK(v_StreamSetRestriction->SetRestriction(0, 0)) + + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/7zUpdate.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/7zUpdate.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/7zUpdate.h 2024-05-12 11:00:00.000000000 +0000 @@ -1,139 +1,167 @@ -// 7zUpdate.h - -#ifndef __7Z_UPDATE_H -#define __7Z_UPDATE_H - -#include "../IArchive.h" - -// #include "../../Common/UniqBlocks.h" - -#include "7zCompressionMode.h" -#include "7zIn.h" -#include "7zOut.h" - -namespace NArchive { -namespace N7z { - -/* -struct CTreeFolder -{ - UString Name; - int Parent; - CIntVector SubFolders; - int UpdateItemIndex; - int SortIndex; - int SortIndexEnd; - - CTreeFolder(): UpdateItemIndex(-1) {} -}; -*/ - -struct CUpdateItem -{ - int IndexInArchive; - int IndexInClient; - - UInt64 CTime; - UInt64 ATime; - UInt64 MTime; - - UInt64 Size; - UString Name; - /* - bool IsAltStream; - int ParentFolderIndex; - int TreeFolderIndex; - */ - - // that code is not used in 9.26 - // int ParentSortIndex; - // int ParentSortIndexEnd; - - UInt32 Attrib; - - bool NewData; - bool NewProps; - - bool IsAnti; - bool IsDir; - - bool AttribDefined; - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - - // int SecureIndex; // 0 means (no_security) - - bool HasStream() const { return !IsDir && !IsAnti && Size != 0; } - // bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes - - CUpdateItem(): - // ParentSortIndex(-1), - // IsAltStream(false), - IsAnti(false), - IsDir(false), - AttribDefined(false), - CTimeDefined(false), - ATimeDefined(false), - MTimeDefined(false) - // SecureIndex(0) - {} - void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); } - - // unsigned GetExtensionPos() const; - // UString GetExtension() const; -}; - -struct CUpdateOptions -{ - const CCompressionMethodMode *Method; - const CCompressionMethodMode *HeaderMethod; - bool UseFilters; // use additional filters for some files - bool MaxFilter; // use BCJ2 filter instead of BCJ - int AnalysisLevel; - - CHeaderOptions HeaderOptions; - - UInt64 NumSolidFiles; - UInt64 NumSolidBytes; - bool SolidExtension; - - bool UseTypeSorting; - - bool RemoveSfxBlock; - bool MultiThreadMixer; - - CUpdateOptions(): - Method(NULL), - HeaderMethod(NULL), - UseFilters(false), - MaxFilter(false), - AnalysisLevel(-1), - NumSolidFiles((UInt64)(Int64)(-1)), - NumSolidBytes((UInt64)(Int64)(-1)), - SolidExtension(false), - UseTypeSorting(true), - RemoveSfxBlock(false), - MultiThreadMixer(true) - {} -}; - -HRESULT Update( - DECL_EXTERNAL_CODECS_LOC_VARS - IInStream *inStream, - const CDbEx *db, - const CObjectVector &updateItems, - // const CObjectVector &treeFolders, // treeFolders[0] is root - // const CUniqBlocks &secureBlocks, - COutArchive &archive, - CArchiveDatabaseOut &newDatabase, - ISequentialOutStream *seqOutStream, - IArchiveUpdateCallback *updateCallback, - const CUpdateOptions &options - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getDecoderPassword - #endif - ); -}} - -#endif +// 7zUpdate.h + +#ifndef ZIP7_INC_7Z_UPDATE_H +#define ZIP7_INC_7Z_UPDATE_H + +#include "../IArchive.h" + +// #include "../../Common/UniqBlocks.h" + +#include "7zCompressionMode.h" +#include "7zIn.h" + +namespace NArchive { +namespace N7z { + +/* +struct CTreeFolder +{ + UString Name; + int Parent; + CIntVector SubFolders; + int UpdateItemIndex; + int SortIndex; + int SortIndexEnd; + + CTreeFolder(): UpdateItemIndex(-1) {} +}; +*/ + +struct CUpdateItem +{ + int IndexInArchive; + unsigned IndexInClient; + + UInt64 CTime; + UInt64 ATime; + UInt64 MTime; + + UInt64 Size; + UString Name; + /* + bool IsAltStream; + int ParentFolderIndex; + int TreeFolderIndex; + */ + + // that code is not used in 9.26 + // int ParentSortIndex; + // int ParentSortIndexEnd; + + UInt32 Attrib; + + bool NewData; + bool NewProps; + + bool IsAnti; + bool IsDir; + + bool AttribDefined; + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + + // bool ATime_WasReadByAnalysis; + + // int SecureIndex; // 0 means (no_security) + + bool HasStream() const { return !IsDir && !IsAnti && Size != 0; } + // bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes + + CUpdateItem(): + // ParentSortIndex(-1), + // IsAltStream(false), + IsAnti(false), + IsDir(false), + AttribDefined(false), + CTimeDefined(false), + ATimeDefined(false), + MTimeDefined(false) + // , ATime_WasReadByAnalysis(false) + // SecureIndex(0) + {} + void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); } + + // unsigned GetExtensionPos() const; + // UString GetExtension() const; +}; + +struct CUpdateOptions +{ + const CCompressionMethodMode *Method; + const CCompressionMethodMode *HeaderMethod; + bool UseFilters; // use additional filters for some files + bool MaxFilter; // use BCJ2 filter instead of BCJ + int AnalysisLevel; + + UInt64 NumSolidFiles; + UInt64 NumSolidBytes; + bool SolidExtension; + + bool UseTypeSorting; + + bool RemoveSfxBlock; + bool MultiThreadMixer; + + bool Need_CTime; + bool Need_ATime; + bool Need_MTime; + bool Need_Attrib; + // bool Need_Crc; + + CHeaderOptions HeaderOptions; + + CUIntVector DisabledFilterIDs; + + void Add_DisabledFilter_for_id(UInt32 id, + const CUIntVector &enabledFilters) + { + if (enabledFilters.FindInSorted(id) < 0) + DisabledFilterIDs.AddToUniqueSorted(id); + } + + void SetFilterSupporting_ver_enabled_disabled( + UInt32 compatVer, + const CUIntVector &enabledFilters, + const CUIntVector &disabledFilters) + { + DisabledFilterIDs = disabledFilters; + if (compatVer < 2300) Add_DisabledFilter_for_id(k_ARM64, enabledFilters); + if (compatVer < 2402) Add_DisabledFilter_for_id(k_RISCV, enabledFilters); + } + + CUpdateOptions(): + Method(NULL), + HeaderMethod(NULL), + UseFilters(false), + MaxFilter(false), + AnalysisLevel(-1), + NumSolidFiles((UInt64)(Int64)(-1)), + NumSolidBytes((UInt64)(Int64)(-1)), + SolidExtension(false), + UseTypeSorting(true), + RemoveSfxBlock(false), + MultiThreadMixer(true), + Need_CTime(false), + Need_ATime(false), + Need_MTime(false), + Need_Attrib(false) + // , Need_Crc(true) + { + DisabledFilterIDs.Add(k_RISCV); + } +}; + +HRESULT Update( + DECL_EXTERNAL_CODECS_LOC_VARS + IInStream *inStream, + const CDbEx *db, + CObjectVector &updateItems, + // const CObjectVector &treeFolders, // treeFolders[0] is root + // const CUniqBlocks &secureBlocks, + ISequentialOutStream *seqOutStream, + IArchiveUpdateCallback *updateCallback, + const CUpdateOptions &options); +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/7z/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/7z/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/makefile --- p7zip-rar-16.02/CPP/7zip/Archive/7z/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/makefile 2023-04-04 20:00:00.000000000 +0000 @@ -0,0 +1,81 @@ +PROG = 7z.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) \ + -DZ7_EXTERNAL_CODECS \ + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + $O\CodecExports.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/7z/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/resource.rc --- p7zip-rar-16.02/CPP/7zip/Archive/7z/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/7z/resource.rc 2008-08-06 11:35:53.000000000 +0000 @@ -0,0 +1,11 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Plugin", "7z") + +0 ICON "../Icons/7z.ico" + +STRINGTABLE +BEGIN + 100 "7z:0" +END + diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ApfsHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApfsHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ApfsHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApfsHandler.cpp 2023-12-11 16:00:00.000000000 +0000 @@ -0,0 +1,4470 @@ +// 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 "../../../C/Sha256.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer2.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" + +#include "HfsHandler.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 { + +struct CUuid +{ + Byte Data[16]; + + void SetHex_To_str(char *s) const + { + ConvertDataToHex_Lower(s, Data, sizeof(Data)); + } + + void AddHexToString(UString &dest) const + { + char temp[sizeof(Data) * 2 + 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; +typedef UInt64 paddr_t_unsigned; + +#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 + +static const unsigned k_obj_phys_Size = 0x20; + +// 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) + { + const unsigned logSize = GetLogSize(block_size); + // don't change it. Some code requires (block_size <= 16) + if (logSize < 12 || logSize > 16) + return false; + block_size_Log = logSize; + } + + G64 (0x28, block_count) + + 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; +} + + +enum apfs_hash_type_t +{ + APFS_HASH_INVALID = 0, + APFS_HASH_SHA256 = 1, + APFS_HASH_SHA512_256 = 2, + APFS_HASH_SHA384 = 3, + APFS_HASH_SHA512 = 4, + + APFS_HASH_MIN = APFS_HASH_SHA256, + APFS_HASH_MAX = APFS_HASH_SHA512, + + APFS_HASH_DEFAULT = APFS_HASH_SHA256 +}; + +static unsigned GetHashSize(unsigned hashType) +{ + if (hashType > APFS_HASH_MAX) return 0; + if (hashType < APFS_HASH_MIN) return 0; + if (hashType == APFS_HASH_SHA256) return 32; + return hashType * 16; +} + +#define APFS_HASH_MAX_SIZE 64 + +static const char * const g_hash_types[] = +{ + NULL + , "SHA256" + , "SHA512_256" + , "SHA384" + , "SHA512" +}; + + +struct C_integrity_meta_phys +{ + // CPhys im_o; + // UInt32 im_version; + UInt32 im_flags; + // apfs_hash_type_t + UInt32 im_hash_type; + // UInt32 im_root_hash_offset; + // xid_t im_broken_xid; + // UInt64 im_reserved[9]; + + unsigned HashSize; + Byte Hash[APFS_HASH_MAX_SIZE]; + + bool Is_SHA256() const { return im_hash_type == APFS_HASH_SHA256; } + + C_integrity_meta_phys() + { + memset(this, 0, sizeof(*this)); + } + bool Parse(const Byte *p, size_t size, oid_t oid); +}; + +bool C_integrity_meta_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_INTEGRITY_META) + return false; + if (o.oid != oid) + return false; + // G32 (0x20, im_version); + G32 (0x24, im_flags) + G32 (0x28, im_hash_type) + UInt32 im_root_hash_offset; + G32 (0x2C, im_root_hash_offset) + // G64x (0x30, im_broken_xid); + const unsigned hashSize = GetHashSize(im_hash_type); + HashSize = hashSize; + if (im_root_hash_offset >= size || size - im_root_hash_offset < hashSize) + return false; + memcpy(Hash, p + im_root_hash_offset, hashSize); + 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 ophys; + 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 Is_NOHEADER() const { return (flags & BTNODE_NOHEADER) != 0; } + bool Is_HASHED() const { return (flags & BTNODE_HASHED) != 0; } + + bool Parse(const Byte *p, size_t size, bool noHeader = false) + { + 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); + */ + memset(&ophys, 0, sizeof(ophys)); + if (noHeader) + { + for (unsigned i = 0; i < k_obj_phys_Size; i++) + if (p[i] != 0) + return false; + } + else + { + if (!CheckFletcher64(p, size)) + return false; + ophys.Parse(p); + } + if (Is_NOHEADER() != noHeader) + return false; + 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) +*/ +#define BTREE_NOHEADER (1 << 8) + +/* + 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; } + bool Is_NOHEADER() const { return (fixed.flags & BTREE_NOHEADER) != 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; // 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; // virtual object identifier of the integrity metadata object + oid_t fext_tree_oid; // virtual object identifier of the file extent tree. + UInt32 fext_tree_type; // The type of the file extent tree. + /* + 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; + + void Clear() + { + Name.Empty(); + ParentItemIndex = VI_MINUS1; + RefIndex = 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, +*/ +#define 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 + + UInt64 GetEndOffset() const { return logical_offset + EXTENT_GET_LEN(len_and_flags); } +}; + + +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; + bool dstream_defined; + bool NeedShow; + CByteBuffer Data; + + j_dstream dstream; + UInt64 Id; + + bool Is_dstream_OK_for_SymLink() const + { + return dstream_defined && dstream.size <= (1 << 12) && dstream.size != 0; + } + + UInt64 GetSize() const + { + if (dstream_defined) // dstream has more priority + return dstream.size; + return Data.Size(); + } + + void Clear() + { + dstream_defined = false; + NeedShow = true; + Data.Free(); + Name.Empty(); + } + + 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 + unsigned DecmpfsIndex; // index in Attrs + unsigned ResourceIndex; // index in Attrs + + NHfs::CCompressHeader CompressHeader; + + CNode(): + ItemIndex(VI_MINUS1), + NumCalcedLinks(0), + // NumItems(0), + dstream_defined(false), + refcnt_defined(false), + SymLinkIndex(VI_MINUS1), + DecmpfsIndex(VI_MINUS1), + ResourceIndex(VI_MINUS1) + {} + + bool IsDir() const { return MY_LIN_S_ISDIR(mode); } + bool IsSymLink() const { return MY_LIN_S_ISLNK(mode); } + + bool Has_UNCOMPRESSED_SIZE() const { return (internal_flags & INODE_HAS_UNCOMPRESSED_SIZE) != 0; } + + 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; + } + size = 0; + if (Has_UNCOMPRESSED_SIZE()) + { + size = uncompressed_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; + } + size = 0; + + if (IsSymLink()) + attrIndex = SymLinkIndex; + else + { + if (!CompressHeader.IsCorrect || + !CompressHeader.IsSupported) + return false; + const CAttr &attr = Attrs[DecmpfsIndex]; + if (!CompressHeader.IsMethod_Resource()) + { + size = attr.Data.Size() - CompressHeader.DataPos; + return true; + } + attrIndex = ResourceIndex; + } + 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 + // bool IsAltStream() const { return false; } + unsigned GetAttrIndex() const { return VI_MINUS1; } + #endif +}; + + +struct CRef2 +{ + unsigned VolIndex; + unsigned RefIndex; +}; + + +struct CHashChunk +{ + UInt64 lba; + UInt32 hashed_len; // the value is UInt16 + Byte hash[APFS_HASH_MAX_SIZE]; +}; + +typedef CRecordVector CStreamHashes; + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _hashError; + CAlignedBuffer1 _sha; + CMyComPtr _stream; + const CStreamHashes *_hashes; + unsigned _blockSizeLog; + unsigned _chunkIndex; + UInt32 _offsetInChunk; + // UInt64 _size; + + CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } +public: + COutStreamWithHash(): _sha(sizeof(CSha256)) {} + + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + // void ReleaseStream() { _stream.Release(); } + void Init(const CStreamHashes *hashes, unsigned blockSizeLog) + { + _hashes = hashes; + _blockSizeLog = blockSizeLog; + _chunkIndex = 0; + _offsetInChunk = 0; + _hashError = false; + // _size = 0; + } + // UInt64 GetSize() const { return _size; } + bool FinalCheck(); +}; + + +static bool Sha256_Final_and_CheckDigest(CSha256 *sha256, const Byte *digest) +{ + MY_ALIGN (16) + UInt32 temp[SHA256_NUM_DIGEST_WORDS]; + Sha256_Final(sha256, (Byte *)temp); + return memcmp(temp, digest, SHA256_DIGEST_SIZE) == 0; +} + + +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (processedSize) + *processedSize = size; + while (size != 0) + { + if (_hashError) + break; + if (_chunkIndex >= _hashes->Size()) + { + _hashError = true; + break; + } + if (_offsetInChunk == 0) + Sha256_Init(Sha()); + const CHashChunk &chunk = (*_hashes)[_chunkIndex]; + /* (_blockSizeLog <= 16) && chunk.hashed_len is 16-bit. + so we can use 32-bit chunkSize here */ + const UInt32 chunkSize = ((UInt32)chunk.hashed_len << _blockSizeLog); + const UInt32 rem = chunkSize - _offsetInChunk; + UInt32 cur = size; + if (cur > rem) + cur = (UInt32)rem; + Sha256_Update(Sha(), (const Byte *)data, cur); + data = (const void *)((const Byte *)data + cur); + size -= cur; + // _size += cur; + _offsetInChunk += cur; + if (chunkSize == _offsetInChunk) + { + if (!Sha256_Final_and_CheckDigest(Sha(), chunk.hash)) + _hashError = true; + _offsetInChunk = 0; + _chunkIndex++; + } + } + return result; +} + + +bool COutStreamWithHash::FinalCheck() +{ + if (_hashError) + return false; + + if (_offsetInChunk != 0) + { + const CHashChunk &chunk = (*_hashes)[_chunkIndex]; + { + const UInt32 chunkSize = ((UInt32)chunk.hashed_len << _blockSizeLog); + const UInt32 rem = chunkSize - _offsetInChunk; + Byte b = 0; + for (UInt32 i = 0; i < rem; i++) + Sha256_Update(Sha(), &b, 1); + } + if (!Sha256_Final_and_CheckDigest(Sha(), chunk.hash)) + _hashError = true; + _offsetInChunk = 0; + _chunkIndex++; + } + if (_chunkIndex != _hashes->Size()) + _hashError = true; + return !_hashError; +} + + + +struct CVol +{ + CObjectVector Nodes; + CRecordVector NodeIDs; + CObjectVector Items; + CRecordVector Refs; + + CObjectVector SmallNodes; + CRecordVector SmallNodeIDs; + + CObjectVector FEXT_Nodes; + CRecordVector FEXT_NodeIDs; + + CObjectVector Hash_Vectors; + CRecordVector Hash_IDs; + + unsigned StartRef2Index; // ref2_Index for Refs[0] item + unsigned RootRef2Index; // ref2_Index of virtual root folder (Volume1) + CApfs apfs; + C_integrity_meta_phys integrity; + + bool NodeNotFound; + bool ThereAreUnlinkedNodes; + bool WrongInodeLink; + bool UnsupportedFeature; + bool UnsupportedMethod; + + 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), + UnsupportedMethod(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((Int64)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, + Z7_ARRAY_SIZE(g_APFS_INCOMPAT_Flags), + (UInt32)apfs.incompatible_features); + s.Add_LF(); + + + if (apfs.integrity_meta_oid != 0) + { + /* + AddComment_Name(s, "im_version"); + s.Add_UInt32(integrity.im_version); + s.Add_LF(); + */ + AddComment_Name(s, "im_flags"); + s.Add_UInt32(integrity.im_flags); + s.Add_LF(); + AddComment_Name(s, "im_hash_type"); + const char *p = NULL; + if (integrity.im_hash_type < Z7_ARRAY_SIZE(g_hash_types)) + p = g_hash_types[integrity.im_hash_type]; + if (p) + s += p; + else + s.Add_UInt32(integrity.im_hash_type); + 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 < Z7_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; + paddr_t_unsigned paddr; + + bool IsFlag_NoHeader() const { return (flags & OMAP_VAL_NOHEADER) != 0; } + + 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; + bool UnsupportedMethod; + + CSuperBlock sb; + + IInStream *OpenInStream; + IArchiveOpenCallback *OpenCallback; + UInt64 ProgressVal_Cur; + UInt64 ProgressVal_Prev; + UInt64 ProgressVal_NumFilesTotal; + CObjectVector Buffers; + + UInt32 MethodsMask; + UInt64 GetSize(const UInt32 index) const; + + void Clear() + { + HeadersError = false; + ThereAreAltStreams = false; + UnsupportedFeature = false; + UnsupportedMethod = false; + + ProgressVal_Cur = 0; + ProgressVal_Prev = 0; + ProgressVal_NumFilesTotal = 0; + + MethodsMask = 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, bool noHeader, CVol *vol, const Byte *hash, + CMap &map, unsigned recurseLevel); + HRESULT ReadObjectMap(UInt64 oid, CVol *vol, CObjectMap &map); + HRESULT OpenVolume(const CObjectMap &omap, const oid_t fs_oid); + HRESULT Open2(); + + HRESULT GetAttrStream(IInStream *apfsInStream, const CVol &vol, + const CAttr &attr, ISequentialInStream **stream); + + HRESULT GetAttrStream_dstream(IInStream *apfsInStream, const CVol &vol, + const CAttr &attr, ISequentialInStream **stream); + + 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(InStream_SeekSet(OpenInStream, oid << sb.block_size_Log)) + 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; +} +} + + +static bool CheckHash(unsigned hashAlgo, const Byte *data, size_t size, const Byte *digest) +{ + if (hashAlgo == APFS_HASH_SHA256) + { + MY_ALIGN (16) + CSha256 sha; + Sha256_Init(&sha); + Sha256_Update(&sha, data, size); + return Sha256_Final_and_CheckDigest(&sha, digest); + } + return true; +} + + +HRESULT CDatabase::ReadMap(UInt64 oid, bool noHeader, + CVol *vol, const Byte *hash, + 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; + } + + if (hash && vol) + if (!CheckHash(vol->integrity.im_hash_type, buf, blockSize, hash)) + return S_FALSE; + + CBTreeNodePhys bt; + if (!bt.Parse(buf, blockSize, noHeader)) + 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 (!noHeader) + if (bt.ophys.subtype != map.Subtype) + return S_FALSE; + + unsigned endLimit = blockSize; + + if (recurseLevel == 0) + { + if (!noHeader) + if (bt.ophys.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; + if (bti.Is_NOHEADER() != noHeader) + return S_FALSE; + // we don't allow volumes with big number of Keys + const unsigned kNumItemsMax = k_VectorSizeMax; + if (map.bti.node_count > kNumItemsMax) + return S_FALSE; + if (map.bti.key_count > kNumItemsMax) + return S_FALSE; + } + else + { + if (!noHeader) + if (bt.ophys.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, noHeader, vol, + NULL, /* hash */ + 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.len < 8) + return S_FALSE; + + const Byte *hashNew = NULL; + oid_t oidNext = Get64(p2); + + if (bt.Is_HASHED()) + { + if (!vol) + return S_FALSE; + /* + struct btn_index_node_val { + oid_t binv_child_oid; + uint8_t binv_child_hash[BTREE_NODE_HASH_SIZE_MAX]; + }; + */ + /* (a.v.len == 40) is possible if Is_HASHED() + so there is hash (for example, 256-bit) after 64-bit id) */ + if (a.v.len != 8 + vol->integrity.HashSize) + return S_FALSE; + hashNew = p2 + 8; + /* we need to add root_tree_oid here, + but where it's defined in apfs specification ? */ + oidNext += vol->apfs.root_tree_oid; + } + else + { + if (a.v.len != 8) + return S_FALSE; + } + + // value is only 64-bit for non leaf. + + if (map.bti.Is_PHYSICAL()) + { + return S_FALSE; + // the code was not tested: + // RINOK(ReadMap(oidNext, map, recurseLevel + 1)); + // continue; + } + /* + else if (map.bti.Is_EPHEMERAL()) + { + // Ephemeral objects are stored in memory while the container is mounted and in a checkpoint when the container isn't mounted + // the code was not tested: + return S_FALSE; + } + */ + else + { + /* nodes in the B-tree use virtual object identifiers to link to their child nodes. */ + 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, ov.IsFlag_NoHeader(), vol, hashNew, + map, recurseLevel + 1)) + continue; + } + } + } + } + } + + if (recurseLevel == 0) + if (!map.CheckAtFinish()) + return S_FALSE; + return S_OK; +} + + + +HRESULT CDatabase::ReadObjectMap(UInt64 oid, CVol *vol, 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, + false /* noHeader */, + vol, + NULL, /* hash */ + 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, + NULL, /* CVol */ + 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; + + if (apfs.fext_tree_oid != 0) + { + if ((apfs.incompatible_features & APFS_INCOMPAT_SEALED_VOLUME) == 0) + return S_FALSE; + if ((apfs.fext_tree_type & OBJ_PHYSICAL) == 0) + return S_FALSE; + if ((apfs.fext_tree_type & OBJECT_TYPE_MASK) != OBJECT_TYPE_BTREE) + return S_FALSE; + + CMap map2; + map2.Subtype = OBJECT_TYPE_FEXT_TREE; + map2.IsPhysical = true; + + RINOK(ReadMap(apfs.fext_tree_oid, + false /* noHeader */, + &vol, + NULL, /* hash */ + map2, 0)) + + UInt64 prevId = 1; + + FOR_VECTOR (i, map2.Pairs) + { + if (OpenCallback && (i & 0xffff) == 1) + { + const UInt64 numFiles = ProgressVal_NumFilesTotal + + (vol.Items.Size() + vol.Nodes.Size()) / 2; + RINOK(OpenCallback->SetCompleted(&numFiles, &ProgressVal_Cur)) + } + // The key half of a record from a file extent tree. + // struct fext_tree_key + const CKeyValPair &pair = map2.Pairs[i]; + if (pair.Key.Size() != 16) + return S_FALSE; + const Byte *p = pair.Key; + const UInt64 id = GetUi64(p); + if (id < prevId) + return S_FALSE; // IDs must be sorted + prevId = id; + + CExtent ext; + ext.logical_offset = GetUi64(p + 8); + { + if (pair.Val.Size() != 16) + return S_FALSE; + const Byte *p2 = pair.Val; + ext.len_and_flags = GetUi64(p2); + ext.phys_block_num = GetUi64(p2 + 8); + } + + PRF(printf("\n%6d: id=%6d logical_addr = %2d len_and_flags=%5x phys_block_num = %5d", + i, (unsigned)id, + (unsigned)ext.logical_offset, + (unsigned)ext.len_and_flags, + (unsigned)ext.phys_block_num)); + + if (vol.FEXT_NodeIDs.IsEmpty() || + vol.FEXT_NodeIDs.Back() != id) + { + vol.FEXT_NodeIDs.Add(id); + vol.FEXT_Nodes.AddNew(); + } + CRecordVector &extents = vol.FEXT_Nodes.Back().Extents; + if (!extents.IsEmpty()) + if (ext.logical_offset != extents.Back().GetEndOffset()) + return S_FALSE; + extents.Add(ext); + continue; + } + + PRF(printf("\n\n")); + } + + /* 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, &vol, map.Omap); + + const Byte *hash_for_root = NULL; + + if (apfs.integrity_meta_oid != 0) + { + if ((apfs.incompatible_features & APFS_INCOMPAT_SEALED_VOLUME) == 0) + return S_FALSE; + const int index = map.Omap.FindKey(apfs.integrity_meta_oid); + if (index == -1) + return S_FALSE; + const omap_val &ov = map.Omap.Vals[(unsigned)index]; + if (ov.size != blockSize) + return S_FALSE; + RINOK(SeekReadBlock_FALSE(ov.paddr, buf)) + if (!vol.integrity.Parse(buf, blockSize, apfs.integrity_meta_oid)) + return S_FALSE; + if (vol.integrity.im_hash_type != 0) + hash_for_root = vol.integrity.Hash; + } + + { + 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, ov.IsFlag_NoHeader(), + &vol, hash_for_root, + map, 0)) + } + + bool needParseAttr = 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)) + } + } + + CAttr attr; + CItem item; + + 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; + + PRF(printf(" parent_id = %d", (unsigned)inode.parent_id)); + + 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; + + attr.Clear(); + 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 streamSize=%d", (unsigned)attr.Id, (unsigned)attr.dstream.size)); + } + 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()) + needParseAttr = true; + } + else if (attr.Name.IsEqualTo("com.apple.decmpfs")) + { + inode.DecmpfsIndex = inode.Attrs.Size(); + // if (attr.dstream_defined) + needParseAttr = true; + } + else if (attr.Name.IsEqualTo("com.apple.ResourceFork")) + { + inode.ResourceIndex = inode.Attrs.Size(); + } + 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 = %d", (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) + { + PRF(printf(" refcnt != 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.Clear(); + + 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(" DIR_REC next=%6d flags=%2x %s", + (unsigned)item.Val.file_id, + (unsigned)item.Val.flags, + item.Name.Ptr())); + continue; + } + + if (type == APFS_TYPE_FILE_INFO) + { + if (pair.Key.Size() != 16) + return S_FALSE; + // j_file_info_key + const UInt64 info_and_lba = Get64(p + 8); + + #define J_FILE_INFO_LBA_MASK 0x00ffffffffffffffUL + // #define J_FILE_INFO_TYPE_MASK 0xff00000000000000UL + #define J_FILE_INFO_TYPE_SHIFT 56 + #define APFS_FILE_INFO_DATA_HASH 1 + + const unsigned infoType = (unsigned)(info_and_lba >> J_FILE_INFO_TYPE_SHIFT); + // address is a paddr_t + const UInt64 lba = info_and_lba & J_FILE_INFO_LBA_MASK; + // j_file_data_hash_val_t + /* Use this field of the union if the type stored in the info_and_lba field of j_file_info_val_t is + APFS_FILE_INFO_DATA_HASH */ + if (infoType != APFS_FILE_INFO_DATA_HASH) + return S_FALSE; + if (pair.Val.Size() != 3 + vol.integrity.HashSize) + return S_FALSE; + /* + struct j_file_data_hash_val + { + UInt16 hashed_len; // The length, in blocks, of the data segment that was hashed. + UInt8 hash_size; // must be consistent with integrity_meta_phys_t::im_hash_type + UInt8 hash[0]; + } + */ + + const unsigned hash_size = pair.Val[2]; + if (hash_size != vol.integrity.HashSize) + return S_FALSE; + + CHashChunk hr; + hr.hashed_len = GetUi16(pair.Val); + if (hr.hashed_len == 0) + return S_FALSE; + memcpy(hr.hash, (const Byte *)pair.Val + 3, vol.integrity.HashSize); + // (hashed_len <= 4) : we have seen + hr.lba = lba; + + PRF(printf(" FILE_INFO lba = %6x, hashed_len=%6d", + (unsigned)lba, + (unsigned)hr.hashed_len)); + + if (vol.Hash_IDs.IsEmpty() || vol.Hash_IDs.Back() != id) + { + vol.Hash_Vectors.AddNew(); + vol.Hash_IDs.Add(id); + } + CStreamHashes &hashes = vol.Hash_Vectors.Back(); + if (hashes.Size() != 0) + { + const CHashChunk &hr_Back = hashes.Back(); + if (lba != hr_Back.lba + ((UInt64)hr_Back.hashed_len << sb.block_size_Log)) + return S_FALSE; + } + hashes.Add(hr); + continue; + } + + if (type == APFS_TYPE_SNAP_METADATA) + { + if (pair.Key.Size() != 8) + return S_FALSE; + PRF(printf(" SNAP_METADATA")); + // continue; + } + + /* SIBLING items are used, if there are more than one hard link to some inode + key : value + parent_id_1 DIR_REC : inode_id, name_1 + parent_id_2 DIR_REC : inode_id, name_2 + inode_id INODE : parent_id_1, name_1 + inode_id SIBLING_LINK sibling_id_1 : parent_id_1, name_1 + inode_id SIBLING_LINK sibling_id_2 : parent_id_2, name_2 + sibling_id_1 SIBLING_MAP : inode_id + sibling_id_2 SIBLING_MAP : inode_id + */ + + if (type == APFS_TYPE_SIBLING_LINK) + { + if (pair.Key.Size() != 16) + return S_FALSE; + if (pair.Val.Size() < 10 + 1) + return S_FALSE; + /* + // struct j_sibling_key + // The sibling's unique identifier. + // This value matches the object identifier for the sibling map record + const UInt64 sibling_id = Get64(p + 8); + // struct j_sibling_val + const Byte *v = pair.Val; + const UInt64 parent_id = Get64(v); // The object identifier for the inode that's the parent directory. + const unsigned name_len = Get16(v + 8); // len including the final null character + if (10 + name_len != pair.Val.Size()) + return S_FALSE; + if (v[10 + name_len - 1] != 0) + return S_FALSE; + AString name ((const char *)(v + 10)); + if (name.Len() != name_len - 1) + return S_FALSE; + PRF(printf(" SIBLING_LINK sibling_id = %6d : parent_id=%6d %s", + (unsigned)sibling_id, (unsigned)parent_id, name.Ptr())); + */ + continue; + } + + if (type == APFS_TYPE_SIBLING_MAP) + { + // struct j_sibling_map_key + // The object identifier in the header is the sibling's unique identifier + if (pair.Key.Size() != 8 || pair.Val.Size() != 8) + return S_FALSE; + /* + // j_sibling_map_val + // The inode number of the underlying file + const UInt64 file_id = Get64(pair.Val); + PRF(printf(" SIBLING_MAP : file_id = %d", (unsigned)file_id)); + */ + continue; + } + + UnsupportedFeature = true; + // return S_FALSE; + } + ProgressVal_NumFilesTotal += vol.Items.Size(); + } + + + if (needParseAttr) + { + /* we read external streams for attributes + So we can get SymLink for GetProperty(kpidSymLink) later */ + FOR_VECTOR (i, vol.Nodes) + { + CNode &node = vol.Nodes[i]; + + FOR_VECTOR (a, node.Attrs) + { + CAttr &attr = node.Attrs[a]; + if (attr.Data.Size() != 0 || !attr.dstream_defined) + continue; + if (a == node.SymLinkIndex) + { + if (!attr.Is_dstream_OK_for_SymLink()) + continue; + } + else + { + if (a != node.DecmpfsIndex + // && a != node.ResourceIndex + ) + continue; + } + // we don't expect big streams here + // largest dstream for Decmpfs attribute is (2Kib+17) + if (attr.dstream.size > ((UInt32)1 << 16)) + continue; + CMyComPtr inStream; + const HRESULT res = GetAttrStream_dstream(OpenInStream, vol, attr, &inStream); + if (res == S_OK && inStream) + { + CByteBuffer buf2; + const size_t size = (size_t)attr.dstream.size; + buf2.Alloc(size); + if (ReadStream_FAIL(inStream, buf2, size) == S_OK) + attr.Data = buf2; + + ProgressVal_Cur += size; + if (OpenCallback) + if (ProgressVal_Cur - ProgressVal_Prev >= (1 << 22)) + { + + RINOK(OpenCallback->SetCompleted( + &ProgressVal_NumFilesTotal, + &ProgressVal_Cur)) + ProgressVal_Prev = ProgressVal_Cur; + } + } + } + + if (node.Has_UNCOMPRESSED_SIZE()) + if (IsViDef(node.DecmpfsIndex)) + { + CAttr &attr = node.Attrs[node.DecmpfsIndex]; + node.CompressHeader.Parse(attr.Data, attr.Data.Size()); + + if (node.CompressHeader.IsCorrect) + if (node.CompressHeader.Method < sizeof(MethodsMask) * 8) + MethodsMask |= ((UInt32)1 << node.CompressHeader.Method); + + if (node.CompressHeader.IsCorrect + && node.CompressHeader.IsSupported + && node.CompressHeader.UnpackSize == node.uncompressed_size) + { + attr.NeedShow = false; + if (node.CompressHeader.IsMethod_Resource() + && IsViDef(node.ResourceIndex)) + node.Attrs[node.ResourceIndex].NeedShow = false; + } + else + { + vol.UnsupportedMethod = true; + } + } + } + } + + const HRESULT res = vol.FillRefs(); + + if (vol.ThereAreErrors()) + HeadersError = true; + if (vol.UnsupportedFeature) + UnsupportedFeature = true; + if (vol.UnsupportedMethod) + UnsupportedMethod = true; + if (vol.NumAltStreams != 0) + ThereAreAltStreams = true; + + return res; +} + + + +HRESULT CVol::FillRefs() +{ + { + Refs.Reserve(Items.Size()); + // we fill Refs[*] + // we + // and set Nodes[*].ItemIndex for Nodes that are directories; + 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++) + { + // comment it for debug + const CAttr &attr = inode.Attrs[k]; + if (!attr.NeedShow) + continue; + + if (k == inode.SymLinkIndex) + continue; + ref.AttrIndex = k; + NumAltStreams++; + Refs.Add(ref); + /* + 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; +} + + + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveGetRawProps, + public IInArchiveGetStream, + public CMyUnknownImp, + public CDatabase +{ + Z7_IFACES_IMP_UNK_3( + IInArchive, + IArchiveGetRawProps, + IInArchiveGetStream) + + CMyComPtr _stream; + int FindHashIndex_for_Item(UInt32 index); +}; + + +Z7_COM7F_IMF(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 +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _stream.Release(); + Clear(); + return S_OK; +} + + +enum +{ + kpidBytesWritten = kpidUserDefined, + kpidBytesRead, + kpidPrimeName, + kpidParentINode, + kpidAddTime, + kpidGeneration, + kpidBsdFlags + // kpidUncompressedSize +}; + +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, kpidMethod, VT_BSTR }, + { NULL, kpidINode, VT_UI8 }, + { NULL, kpidLinks, VT_UI4 }, + { NULL, kpidSymLink, VT_BSTR }, + { NULL, kpidUserId, VT_UI4 }, + { NULL, kpidGroupId, VT_UI4 }, + { NULL, kpidCharacts, VT_BSTR }, + #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 } + // , { "Uncompressed Size", kpidUncompressedSize, VT_UI8 } +}; + + +static const Byte kArcProps[] = +{ + kpidName, + kpidCharacts, + 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); +} + + +Z7_COM7F_IMF(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 kpidCharacts: NHfs::MethodsMaskToProp(MethodsMask, prop); 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 (UnsupportedMethod) flags |= kpv_ErrorFlags_UnsupportedMethod; + 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 +} + + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = 0; + return S_OK; +} + + +Z7_COM7F_IMF(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; + + 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; +} + + +Z7_COM7F_IMF(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.Add_Dot(); + 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; + UString s2; + 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]; + 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 such 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.Add_Colon(); + 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; +} + + + +Z7_COM7F_IMF(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: + { + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + if (inode && !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: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + 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 = 0; + if (inode->GetSize(ref.GetAttrIndex(), size) || + !inode->IsDir()) + prop = size; + } + break; + + case kpidPackSize: + if (inode) + { + UInt64 size; + if (inode->GetPackSize(ref.GetAttrIndex(), size) || + !inode->IsDir()) + prop = size; + } + break; + + case kpidMethod: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + if (inode) + { + if (inode->CompressHeader.IsCorrect) + inode->CompressHeader.MethodToProp(prop); + else if (IsViDef(inode->DecmpfsIndex)) + prop = "decmpfs"; + else if (!inode->IsDir() && !inode->dstream_defined) + { + if (inode->IsSymLink()) + { + if (IsViDef(inode->SymLinkIndex)) + prop = "symlink"; + } + // else prop = "no_dstream"; + } + } + break; + + /* + case kpidUncompressedSize: + if (inode && inode->Has_UNCOMPRESSED_SIZE()) + prop = inode->uncompressed_size; + break; + */ + + case kpidIsDir: + { + bool isDir = false; + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + { + 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: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + if (inode) + { + FLAGS_TO_PROP(g_INODE_Flags, (UInt32)inode->internal_flags, prop); + } + break; + + case kpidBsdFlags: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + if (inode) + { + FLAGS_TO_PROP(g_INODE_BSD_Flags, inode->bsd_flags, prop); + } + break; + + case kpidGeneration: + #ifdef APFS_SHOW_ALT_STREAMS + // if (!ref.IsAltStream()) + #endif + 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: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + 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: + #ifdef APFS_SHOW_ALT_STREAMS + if (!ref.IsAltStream()) + #endif + 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; +} + + +Z7_COM7F_IMF(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; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + CMyComPtr2_Create copyCoder; + + // We don't know if zlib without Adler is allowed in APFS. + // But zlib without Adler is allowed in HFS. + // So here we allow apfs/zlib without Adler: + NHfs::CDecoder decoder(true); // IsAdlerOptional + + for (i = 0;; i++, currentTotalSize += currentItemSize) + { + lps->InSize = currentTotalSize; + lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + + if (i >= numItems) + break; + + const UInt32 index = allFilesMode ? i : indices[i]; + const CRef2 &ref2 = Refs2[index]; + const CVol &vol = Vols[ref2.VolIndex]; + + currentItemSize = GetSize(index); + + int opRes; + { + 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)) + opRes = NExtract::NOperationResult::kDataError; + + if (IsViDef(ref.NodeIndex)) + { + const CNode &inode = vol.Nodes[ref.NodeIndex]; + if ( + #ifdef APFS_SHOW_ALT_STREAMS + !ref.IsAltStream() && + #endif + !inode.dstream_defined + && inode.Extents.IsEmpty() + && inode.Has_UNCOMPRESSED_SIZE() + && inode.uncompressed_size == inode.CompressHeader.UnpackSize) + { + if (inode.CompressHeader.IsSupported) + { + CMyComPtr inStreamFork; + UInt64 forkSize = 0; + const CByteBuffer *decmpfs_Data = NULL; + + if (inode.CompressHeader.IsMethod_Resource()) + { + if (IsViDef(inode.ResourceIndex)) + { + const CAttr &attr = inode.Attrs[inode.ResourceIndex]; + forkSize = attr.GetSize(); + GetAttrStream(_stream, vol, attr, &inStreamFork); + } + } + else + { + const CAttr &attr = inode.Attrs[inode.DecmpfsIndex]; + decmpfs_Data = &attr.Data; + } + + if (inStreamFork || decmpfs_Data) + { + const HRESULT hres = decoder.Extract( + inStreamFork, realOutStream, + forkSize, + inode.CompressHeader, + decmpfs_Data, + currentTotalSize, extractCallback, + opRes); + if (hres != S_FALSE && hres != S_OK) + return hres; + } + } + else + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else + { + CMyComPtr inStream; + if (GetStream(index, &inStream) == S_OK && inStream) + { + CMyComPtr2 hashStream; + + if (vol.integrity.Is_SHA256()) + { + const int hashIndex = FindHashIndex_for_Item(index); + if (hashIndex != -1) + { + hashStream.Create_if_Empty(); + hashStream->SetStream(realOutStream); + hashStream->Init(&(vol.Hash_Vectors[(unsigned)hashIndex]), sb.block_size_Log); + } + } + + RINOK(copyCoder.Interface()->Code(inStream, + hashStream.IsDefined() ? + hashStream.Interface() : + realOutStream.Interface(), + NULL, NULL, lps)) + opRes = NExtract::NOperationResult::kDataError; + if (copyCoder->TotalSize == currentItemSize) + { + opRes = NExtract::NOperationResult::kOK; + if (hashStream.IsDefined()) + if (!hashStream->FinalCheck()) + opRes = NExtract::NOperationResult::kCRCError; + } + else if (copyCoder->TotalSize < currentItemSize) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + } + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Refs2.Size(); + return S_OK; +} + + +int CHandler::FindHashIndex_for_Item(UInt32 index) +{ + const CRef2 &ref2 = Refs2[index]; + const CVol &vol = Vols[ref2.VolIndex]; + if (IsViNotDef(ref2.RefIndex)) + return -1; + + const CRef &ref = vol.Refs[ref2.RefIndex]; + if (IsViNotDef(ref.NodeIndex)) + return -1; + const CNode &inode = vol.Nodes[ref.NodeIndex]; + + unsigned attrIndex = ref.GetAttrIndex(); + + if (IsViNotDef(attrIndex) + && !inode.dstream_defined + && inode.IsSymLink()) + { + attrIndex = inode.SymLinkIndex; + if (IsViNotDef(attrIndex)) + return -1; + } + + if (IsViDef(attrIndex)) + { + /* we have seen examples, where hash available for "com.apple.ResourceFork" stream. + these hashes for "com.apple.ResourceFork" stream are for unpacked data. + but the caller here needs packed data of stream. So we don't use hashes */ + return -1; + } + else + { + if (!inode.dstream_defined) + return -1; + const UInt64 id = vol.NodeIDs[ref.NodeIndex]; + return vol.Hash_IDs.FindInSorted(id); + } +} + + +Z7_COM7F_IMF(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) + { + CMyComPtr2 streamTemp; + streamTemp.Create_if_Empty(); + streamTemp->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) + extents = &vol.SmallNodes[(unsigned)idIndex].Extents; + else + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(attr.Id); + if (fext_Index == -1) + return S_FALSE; + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].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; + extents = &inode.Extents; + if (inode.dstream_defined) + { + rem = inode.dstream.size; + if (inode.Extents.Size() == 0) + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(vol.NodeIDs[ref.NodeIndex]); + if (fext_Index != -1) + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].Extents; + } + } + else + { + // return S_FALSE; // check it !!! How zero size files are stored with dstream_defined? + } + } + return GetStream2(_stream, extents, rem, stream); +} + + + +HRESULT CDatabase::GetAttrStream(IInStream *apfsInStream, const CVol &vol, + const CAttr &attr, ISequentialInStream **stream) +{ + *stream = NULL; + if (!attr.dstream_defined) + { + CMyComPtr2 streamTemp; + streamTemp.Create_if_Empty(); + streamTemp->Init(attr.Data, attr.Data.Size(), (IInArchive *)this); + *stream = streamTemp.Detach(); + return S_OK; + } + return GetAttrStream_dstream(apfsInStream, vol, attr, stream); +} + + +HRESULT CDatabase::GetAttrStream_dstream( IInStream *apfsInStream, const CVol &vol, + const CAttr &attr, ISequentialInStream **stream) +{ + const CRecordVector *extents; + { + const int idIndex = vol.SmallNodeIDs.FindInSorted(attr.Id); + if (idIndex != -1) + extents = &vol.SmallNodes[(unsigned)idIndex].Extents; + else + { + const int fext_Index = vol.FEXT_NodeIDs.FindInSorted(attr.Id); + if (fext_Index == -1) + return S_FALSE; + extents = &vol.FEXT_Nodes[(unsigned)fext_Index].Extents; + } + } + return GetStream2(apfsInStream, extents, attr.dstream.size, stream); +} + + +HRESULT CDatabase::GetStream2( + IInStream *apfsInStream, + const CRecordVector *extents, UInt64 rem, + ISequentialInStream **stream) +{ + CMyComPtr2 extentStream; + extentStream.Create_if_Empty(); + + 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; + extentStream->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; + extentStream->Extents.Add(se); + extentStream->Stream = apfsInStream; + extentStream->Init(); + *stream = extentStream.Detach(); + return S_OK; +} + + +REGISTER_ARC_I( + "APFS", "apfs img", NULL, 0xc3, + k_Signature, + k_SignatureOffset, + 0, + IsArc_APFS) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ApmHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApmHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ApmHandler.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ApmHandler.cpp 2024-11-22 10:00:00.000000000 +0000 @@ -1,320 +1,422 @@ -// ApmHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/Defs.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) - -using namespace NWindows; - -namespace NArchive { -namespace NApm { - -static const Byte kSig0 = 'E'; -static const Byte kSig1 = 'R'; - -struct CItem -{ - UInt32 StartBlock; - UInt32 NumBlocks; - char Name[32]; - char Type[32]; - /* - UInt32 DataStartBlock; - UInt32 NumDataBlocks; - UInt32 Status; - UInt32 BootStartBlock; - UInt32 BootSize; - UInt32 BootAddr; - UInt32 BootEntry; - UInt32 BootChecksum; - char Processor[16]; - */ - - bool Parse(const Byte *p, UInt32 &numBlocksInMap) - { - numBlocksInMap = Get32(p + 4); - StartBlock = Get32(p + 8); - NumBlocks = Get32(p + 0xC); - memcpy(Name, p + 0x10, 32); - memcpy(Type, p + 0x30, 32); - if (p[0] != 0x50 || p[1] != 0x4D || p[2] != 0 || p[3] != 0) - return false; - /* - DataStartBlock = Get32(p + 0x50); - NumDataBlocks = Get32(p + 0x54); - Status = Get32(p + 0x58); - BootStartBlock = Get32(p + 0x5C); - BootSize = Get32(p + 0x60); - BootAddr = Get32(p + 0x64); - if (Get32(p + 0x68) != 0) - return false; - BootEntry = Get32(p + 0x6C); - if (Get32(p + 0x70) != 0) - return false; - BootChecksum = Get32(p + 0x74); - memcpy(Processor, p + 0x78, 16); - */ - return true; - } -}; - -class CHandler: public CHandlerCont -{ - CRecordVector _items; - unsigned _blockSizeLog; - UInt32 _numBlocks; - UInt64 _phySize; - bool _isArc; - - HRESULT ReadTables(IInStream *stream); - UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } - - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const - { - const CItem &item = _items[index]; - pos = BlocksToBytes(item.StartBlock); - size = BlocksToBytes(item.NumBlocks); - return NExtract::NOperationResult::kOK; - } - -public: - INTERFACE_IInArchive_Cont(;) -}; - -static const UInt32 kSectorSize = 512; - -API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size) -{ - if (size < kSectorSize) - return k_IsArc_Res_NEED_MORE; - if (p[0] != kSig0 || p[1] != kSig1) - return k_IsArc_Res_NO; - unsigned i; - for (i = 8; i < 16; i++) - if (p[i] != 0) - return k_IsArc_Res_NO; - UInt32 blockSize = Get16(p + 2); - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i >= 12) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -HRESULT CHandler::ReadTables(IInStream *stream) -{ - Byte buf[kSectorSize]; - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - if (buf[0] != kSig0 || buf[1] != kSig1) - return S_FALSE; - UInt32 blockSize = Get16(buf + 2); - unsigned i; - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i >= 12) - return S_FALSE; - _blockSizeLog = i; - _numBlocks = Get32(buf + 4); - for (i = 8; i < 16; i++) - if (buf[i] != 0) - return S_FALSE; - } - - unsigned numSkips = (unsigned)1 << (_blockSizeLog - 9); - for (unsigned j = 1; j < numSkips; j++) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - } - - UInt32 numBlocksInMap = 0; - - for (unsigned i = 0;;) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - - CItem item; - - UInt32 numBlocksInMap2 = 0; - if (!item.Parse(buf, numBlocksInMap2)) - return S_FALSE; - if (i == 0) - { - numBlocksInMap = numBlocksInMap2; - if (numBlocksInMap > (1 << 8)) - return S_FALSE; - } - else if (numBlocksInMap2 != numBlocksInMap) - return S_FALSE; - - UInt32 finish = item.StartBlock + item.NumBlocks; - if (finish < item.StartBlock) - return S_FALSE; - _numBlocks = MyMax(_numBlocks, finish); - - _items.Add(item); - for (unsigned j = 1; j < numSkips; j++) - { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - } - if (++i == numBlocksInMap) - break; - } - - _phySize = BlocksToBytes(_numBlocks); - _isArc = true; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(ReadTables(stream)); - _stream = stream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _phySize = 0; - _items.Clear(); - _stream.Release(); - return S_OK; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidOffset -}; - -static const Byte kArcProps[] = -{ - kpidClusterSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static AString GetString(const char *s) -{ - AString res; - for (unsigned i = 0; i < 32 && s[i] != 0; i++) - res += s[i]; - return res; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: - { - int mainIndex = -1; - FOR_VECTOR (i, _items) - { - AString s = GetString(_items[i].Type); - if (s != "Apple_Free" && - s != "Apple_partition_map") - { - if (mainIndex >= 0) - { - mainIndex = -1; - break; - } - mainIndex = i; - } - } - if (mainIndex >= 0) - prop = (UInt32)mainIndex; - break; - } - case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; - case kpidPhySize: prop = _phySize; break; - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; - 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 CItem &item = _items[index]; - switch (propID) - { - case kpidPath: - { - AString s = GetString(item.Name); - if (s.IsEmpty()) - { - char s2[32]; - ConvertUInt32ToString(index, s2); - s = s2; - } - AString type = GetString(item.Type); - if (type == "Apple_HFS") - type = "hfs"; - if (!type.IsEmpty()) - { - s += '.'; - s += type; - } - prop = s; - break; - } - case kpidSize: - case kpidPackSize: - prop = BlocksToBytes(item.NumBlocks); - break; - case kpidOffset: prop = BlocksToBytes(item.StartBlock); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static const Byte k_Signature[] = { kSig0, kSig1 }; - -REGISTER_ARC_I( - "APM", "apm", 0, 0xD4, - k_Signature, - 0, - 0, - IsArc_Apm) - -}} +// ApmHandler.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 Get32(p) GetBe32a(p) + +using namespace NWindows; + +namespace NArchive { + +namespace NDmg { + const char *Find_Apple_FS_Ext(const AString &name); + bool Is_Apple_FS_Or_Unknown(const AString &name); +} + +namespace NApm { + +static const Byte kSig0 = 'E'; +static const Byte kSig1 = 'R'; + +static const CUInt32PCharPair k_Flags[] = +{ + { 0, "VALID" }, + { 1, "ALLOCATED" }, + { 2, "IN_USE" }, + { 3, "BOOTABLE" }, + { 4, "READABLE" }, + { 5, "WRITABLE" }, + { 6, "OS_PIC_CODE" }, + // { 7, "OS_SPECIFIC_2" }, // "Unused" + { 8, "ChainCompatible" }, // "OS_SPECIFIC_1" + { 9, "RealDeviceDriver" }, + // { 10, "CanChainToNext" }, + { 30, "MOUNTED_AT_STARTUP" }, + { 31, "STARTUP" } +}; + +#define DPME_FLAGS_VALID (1u << 0) +#define DPME_FLAGS_ALLOCATED (1u << 1) + +static const unsigned k_Str_Size = 32; + +struct CItem +{ + UInt32 StartBlock; + UInt32 NumBlocks; + UInt32 Flags; // pmPartStatus + char Name[k_Str_Size]; + char Type[k_Str_Size]; + /* + UInt32 DataStartBlock; + UInt32 NumDataBlocks; + UInt32 BootStartBlock; + UInt32 BootSize; + UInt32 BootAddr; + UInt32 BootEntry; + UInt32 BootChecksum; + char Processor[16]; + */ + + bool Is_Valid_and_Allocated() const + { return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; } + + bool Parse(const UInt32 *p32, UInt32 &numBlocksInMap) + { + if (GetUi32a(p32) != 0x4d50) // "PM" + return false; + numBlocksInMap = Get32(p32 + 4 / 4); + StartBlock = Get32(p32 + 8 / 4); + NumBlocks = Get32(p32 + 0xc / 4); + Flags = Get32(p32 + 0x58 / 4); + memcpy(Name, p32 + 0x10 / 4, k_Str_Size); + memcpy(Type, p32 + 0x30 / 4, k_Str_Size); + /* + DataStartBlock = Get32(p + 0x50); + NumDataBlocks = Get32(p + 0x54); + BootStartBlock = Get32(p + 0x5c); + BootSize = Get32(p + 0x60); + BootAddr = Get32(p + 0x64); + if (Get32(p + 0x68) != 0) + return false; + BootEntry = Get32(p + 0x6c); + if (Get32(p + 0x70) != 0) + return false; + BootChecksum = Get32(p + 0x74); + memcpy(Processor, p32 + 0x78 / 4, 16); + */ + return true; + } +}; + + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + CRecordVector _items; + unsigned _blockSizeLog; + bool _isArc; + // UInt32 _numBlocks; + UInt64 _phySize; + + UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + const CItem &item = _items[index]; + pos = BlocksToBytes(item.StartBlock); + size = BlocksToBytes(item.NumBlocks); + return NExtract::NOperationResult::kOK; + } +}; + +static const UInt32 kSectorSize = 512; + +// we support only 4 cluster sizes: 512, 1024, 2048, 4096 */ + +API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size) +{ + if (size < kSectorSize) + return k_IsArc_Res_NEED_MORE; + if (GetUi32(p + 12) != 0) + return k_IsArc_Res_NO; + UInt32 v = GetUi32(p); // we read as little-endian + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) + return k_IsArc_Res_NO; + if ((0x116u >> (v >> 17)) & 1) + return k_IsArc_Res_YES; + return k_IsArc_Res_NO; +} +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)) +{ + COM_TRY_BEGIN + Close(); + + UInt32 buf32[kSectorSize / 4]; + unsigned numPadSectors, blockSizeLog_from_Header; + { + // Driver Descriptor Map (DDM) + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + // 8: UInt16 sbDevType : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 10: UInt16 sbDevId : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 12: UInt32 sbData : =0 + if (buf32[3] != 0) + return S_FALSE; + UInt32 v = GetUi32a(buf32); // we read as little-endian + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) + return S_FALSE; + v >>= 16; + if (v == 0) + return S_FALSE; + if (v & (v - 1)) + return S_FALSE; + // v == { 16,8,4,2 } : block size (x256 bytes) + const unsigned a = +#if 1 + (0x30210u >> v) & 3; +#else + 0; // for debug : hardcoded switch to 512-bytes mode +#endif + numPadSectors = (1u << a) - 1; + _blockSizeLog = blockSizeLog_from_Header = 9 + a; + } + +/* + some APMs (that are ".iso" macOS installation files) contain + (blockSizeLog == 11) in DDM header, + and contain 2 overlapping maps: + 1) map for 512-bytes-step + 2) map for 2048-bytes-step + 512-bytes-step map is correct. + 2048-bytes-step map can be incorrect in some cases. + + macos 8 / OSX DP2 iso: + There is shared "hfs" item in both maps. + And correct (offset/size) values for "hfs" partition + can be calculated only in 512-bytes mode (ignoring blockSizeLog == 11). + But some records (Macintosh.Apple_Driver*_) + can be correct on both modes: 512-bytes mode / 2048-bytes-step. + + macos 921 ppc / Apple Mac OS X 10.3.0 iso: + Both maps are correct. + If we use 512-bytes-step, each 4th item is (Apple_Void) with zero size. + And these zero size (Apple_Void) items will be first items in 2048-bytes-step map. +*/ + +// we define Z7_APM_SWITCH_TO_512_BYTES, because +// we want to support old MACOS APMs that contain correct value only +// for 512-bytes-step mode +#define Z7_APM_SWITCH_TO_512_BYTES + + const UInt32 numBlocks_from_Header = Get32(buf32 + 1); + UInt32 numBlocks = 0; + { + for (unsigned k = 0; k < numPadSectors; k++) + { + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (k == 0) + { + if (GetUi32a(buf32) == 0x4d50 // "PM" + // && (Get32(buf32 + 0x58 / 4) & 1) // Flags::VALID + // some old APMs don't use VALID flag for Apple_partition_map item + && Get32(buf32 + 8 / 4) == 1) // StartBlock + { + // we switch the mode to 512-bytes-step map reading: + numPadSectors = 0; + _blockSizeLog = 9; + break; + } + } +#endif + } + } + + for (unsigned i = 0;;) + { +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (i != 0 || _blockSizeLog == blockSizeLog_from_Header) +#endif + { + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + } + + CItem item; + UInt32 numBlocksInMap = 0; + if (!item.Parse(buf32, numBlocksInMap)) + return S_FALSE; + // v24.09: we don't check that all entries have same (numBlocksInMap) values, + // because some APMs have different (numBlocksInMap) values, if (Apple_Void) is used. + if (numBlocksInMap > (1 << 8) || numBlocksInMap <= i) + return S_FALSE; + + const UInt32 finish = item.StartBlock + item.NumBlocks; + if (finish < item.StartBlock) + return S_FALSE; + if (numBlocks < finish) + numBlocks = finish; + + _items.Add(item); + if (numPadSectors != 0) + { + RINOK(stream->Seek(numPadSectors << 9, STREAM_SEEK_CUR, NULL)) + } + if (++i == numBlocksInMap) + break; + } + + _phySize = BlocksToBytes(numBlocks); + // _numBlocks = numBlocks; + const UInt64 physSize = (UInt64)numBlocks_from_Header << blockSizeLog_from_Header; + if (_phySize < physSize) + _phySize = physSize; + _isArc = true; + _stream = stream; + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _phySize = 0; + _items.Clear(); + _stream.Release(); + return S_OK; +} + + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidOffset, + kpidCharacts + // , kpidCpu +}; + +static const Byte kArcProps[] = +{ + kpidClusterSize + // , kpidNumBlocks +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void GetString(AString &dest, const char *src) +{ + dest.SetFrom_CalcLen(src, k_Str_Size); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: + { + int mainIndex = -1; + FOR_VECTOR (i, _items) + { + const CItem &item = _items[i]; + if (!item.Is_Valid_and_Allocated()) + continue; + AString s; + GetString(s, item.Type); + if (NDmg::Is_Apple_FS_Or_Unknown(s)) + { + if (mainIndex != -1) + { + mainIndex = -1; + break; + } + mainIndex = (int)i; + } + } + if (mainIndex != -1) + prop = (UInt32)(Int32)mainIndex; + break; + } + case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; + case kpidPhySize: prop = _phySize; break; + // case kpidNumBlocks: prop = _numBlocks; break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CItem &item = _items[index]; + switch (propID) + { + case kpidPath: + { + AString s; + GetString(s, item.Name); + if (s.IsEmpty()) + s.Add_UInt32(index); + AString type; + GetString(type, item.Type); + { + const char *ext = NDmg::Find_Apple_FS_Ext(type); + if (ext) + type = ext; + } + if (!type.IsEmpty()) + { + s.Add_Dot(); + s += type; + } + prop = s; + break; + } +/* + case kpidCpu: + { + AString s; + s.SetFrom_CalcLen(item.Processor, sizeof(item.Processor)); + if (!s.IsEmpty()) + prop = s; + break; + } +*/ + case kpidSize: + case kpidPackSize: + prop = BlocksToBytes(item.NumBlocks); + break; + case kpidOffset: prop = BlocksToBytes(item.StartBlock); break; + case kpidCharacts: FLAGS_TO_PROP(k_Flags, item.Flags, prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static const Byte k_Signature[] = { kSig0, kSig1 }; + +REGISTER_ARC_I( + "APM", "apm", NULL, 0xD4, + k_Signature, + 0, + 0, + IsArc_Apm) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ArHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ArHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArHandler.cpp 2025-06-16 10:00:00.000000000 +0000 @@ -1,854 +1,842 @@ -// ArHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" -#include "../../Common/StringToInt.h" - -#include "../../Windows/PropVariant.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" - -using namespace NWindows; -using namespace NTime; - -namespace NArchive { -namespace NAr { - -/* -The end of each file member (including last file in archive) is 2-bytes aligned. -It uses 0xA padding if required. - -File Names: - -GNU/SVR4 variant (.a static library): - / - archive symbol table - // - the list of the long filenames, separated by one or more LF characters. - /N - the reference to name string in long filenames list - name/ - the name - -Microsoft variant (.lib static library): - / - First linker file (archive symbol table) - / - Second linker file - // - the list of the long filenames, null-terminated. Each string begins - immediately after the null byte in the previous string. - /N - the reference to name string in long filenames list - name/ - the name - -BSD (Mac OS X) variant: - "__.SYMDEF" - archive symbol table - or - "__.SYMDEF SORTED" - archive symbol table - #1/N - the real filename of length N is appended to the file header. -*/ - -static const unsigned kSignatureLen = 8; - -#define SIGNATURE { '!', '<', 'a', 'r', 'c', 'h', '>', 0x0A } - -static const Byte kSignature[kSignatureLen] = SIGNATURE; - -static const unsigned kNameSize = 16; -static const unsigned kTimeSize = 12; -static const unsigned kUserSize = 6; -static const unsigned kModeSize = 8; -static const unsigned kSizeSize = 10; - -static const unsigned kHeaderSize = kNameSize + kTimeSize + kUserSize * 2 + kModeSize + kSizeSize + 1 + 1; - -enum EType -{ - kType_Ar, - kType_ALib, - kType_Deb, - kType_Lib -}; - -static const char * const k_TypeExtionsions[] = -{ - "ar" - , "a" - , "deb" - , "lib" -}; - -enum ESubType -{ - kSubType_None, - kSubType_BSD -}; - -/* -struct CHeader -{ - char Name[kNameSize]; - char MTime[kTimeSize]; - char User[kUserSize]; - char Group[kUserSize]; - char Mode[kModeSize]; - char Size[kSizeSize]; - char Quote; - char NewLine; -}; -*/ - -struct CItem -{ - AString Name; - UInt64 Size; - UInt32 MTime; - UInt32 User; - UInt32 Group; - UInt32 Mode; - - UInt64 HeaderPos; - UInt64 HeaderSize; - - int TextFileIndex; - int SameNameIndex; - - CItem(): TextFileIndex(-1), SameNameIndex(-1) {} - UInt64 GetDataPos() const { return HeaderPos + HeaderSize; } -}; - -class CInArchive -{ - CMyComPtr m_Stream; - -public: - UInt64 Position; - ESubType SubType; - - HRESULT GetNextItem(CItem &itemInfo, bool &filled); - HRESULT Open(IInStream *inStream); - HRESULT SkipData(UInt64 dataSize) - { - return m_Stream->Seek(dataSize + (dataSize & 1), STREAM_SEEK_CUR, &Position); - } -}; - -HRESULT CInArchive::Open(IInStream *inStream) -{ - SubType = kSubType_None; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &Position)); - char signature[kSignatureLen]; - RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)); - Position += kSignatureLen; - if (memcmp(signature, kSignature, kSignatureLen) != 0) - return S_FALSE; - m_Stream = inStream; - return S_OK; -} - -static unsigned RemoveTailSpaces(char *dest, const char *s, unsigned size) -{ - memcpy(dest, s, size); - for (; size != 0; size--) - { - if (dest[size - 1] != ' ') - break; - } - dest[size] = 0; - return size; -} - -static bool OctalToNumber32(const char *s, unsigned size, UInt32 &res) -{ - res = 0; - char sz[32]; - size = RemoveTailSpaces(sz, s, size); - if (size == 0) - return true; // some items doesn't contaion any numbers - const char *end; - UInt64 res64 = ConvertOctStringToUInt64(sz, &end); - if ((unsigned)(end - sz) != size) - return false; - res = (UInt32)res64; - return (res64 <= 0xFFFFFFFF); -} - -static bool DecimalToNumber(const char *s, unsigned size, UInt64 &res) -{ - res = 0; - char sz[32]; - size = RemoveTailSpaces(sz, s, size); - if (size == 0) - return true; // some items doesn't contaion any numbers - const char *end; - res = ConvertStringToUInt64(sz, &end); - return ((unsigned)(end - sz) == size); -} - -static bool DecimalToNumber32(const char *s, unsigned size, UInt32 &res) -{ - UInt64 res64; - if (!DecimalToNumber(s, size, res64)) - return false; - res = (UInt32)res64; - return (res64 <= 0xFFFFFFFF); -} - -#define RIF(x) { if (!(x)) return S_FALSE; } - - -HRESULT CInArchive::GetNextItem(CItem &item, bool &filled) -{ - filled = false; - - char header[kHeaderSize]; - const char *cur = header; - - { - size_t processedSize = sizeof(header); - item.HeaderPos = Position; - item.HeaderSize = kHeaderSize; - RINOK(ReadStream(m_Stream, header, &processedSize)); - if (processedSize != sizeof(header)) - return S_OK; - if (header[kHeaderSize - 2] != 0x60 || - header[kHeaderSize - 1] != 0x0A) - return S_OK; - for (unsigned i = 0; i < kHeaderSize - 2; i++) - // if (header[i] < 0x20) - if (header[i] == 0) - return S_OK; - Position += processedSize; - } - - UInt32 longNameLen = 0; - if (cur[0] == '#' && - cur[1] == '1' && - cur[2] == '/' && - cur[3] != 0) - { - // BSD variant - RIF(DecimalToNumber32(cur + 3, kNameSize - 3 , longNameLen)); - if (longNameLen >= (1 << 12)) - longNameLen = 0; - } - else - { - char tempString[kNameSize + 1]; - RemoveTailSpaces(tempString, cur, kNameSize); - item.Name = tempString; - } - cur += kNameSize; - - RIF(DecimalToNumber32(cur, kTimeSize, item.MTime)); cur += kTimeSize; - RIF(DecimalToNumber32(cur, kUserSize, item.User)); cur += kUserSize; - RIF(DecimalToNumber32(cur, kUserSize, item.Group)); cur += kUserSize; - RIF(OctalToNumber32(cur, kModeSize, item.Mode)); cur += kModeSize; - RIF(DecimalToNumber(cur, kSizeSize, item.Size)); cur += kSizeSize; - - if (longNameLen != 0 && longNameLen <= item.Size) - { - SubType = kSubType_BSD; - size_t processedSize = longNameLen; - char *s = item.Name.GetBuf(longNameLen); - HRESULT res = ReadStream(m_Stream, s, &processedSize); - item.Name.ReleaseBuf_CalcLen(longNameLen); - RINOK(res); - if (processedSize != longNameLen) - return S_OK; - item.Size -= longNameLen; - item.HeaderSize += longNameLen; - Position += processedSize; - } - - filled = true; - return S_OK; -} - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CObjectVector _items; - CMyComPtr _stream; - Int32 _mainSubfile; - UInt64 _phySize; - - EType _type; - ESubType _subType; - int _longNames_FileIndex; - AString _libFiles[2]; - unsigned _numLibFiles; - AString _errorMessage; - bool _isArc; - - - void UpdateErrorMessage(const char *s); - - HRESULT ParseLongNames(IInStream *stream); - void ChangeDuplicateNames(); - int FindItem(UInt32 offset) const; - HRESULT AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos); - HRESULT ParseLibSymbols(IInStream *stream, unsigned fileIndex); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -void CHandler::UpdateErrorMessage(const char *s) -{ - if (!_errorMessage.IsEmpty()) - _errorMessage += '\n'; - _errorMessage += s; -} - -static const Byte kArcProps[] = -{ - kpidSubType -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidMTime, - kpidPosixAttrib, - kpidUser, - kpidGroup -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -HRESULT CHandler::ParseLongNames(IInStream *stream) -{ - unsigned i; - for (i = 0; i < _items.Size(); i++) - if (_items[i].Name == "//") - break; - if (i == _items.Size()) - return S_OK; - - unsigned fileIndex = i; - const CItem &item = _items[fileIndex]; - if (item.Size > ((UInt32)1 << 30)) - return S_FALSE; - RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); - const size_t size = (size_t)item.Size; - - CByteArr p(size); - RINOK(ReadStream_FALSE(stream, p, size)); - - for (i = 0; i < _items.Size(); i++) - { - CItem &item2 = _items[i]; - if (item2.Name[0] != '/') - continue; - const char *ptr = item2.Name.Ptr(1); - const char *end; - UInt32 pos = ConvertStringToUInt32(ptr, &end); - if (*end != 0 || end == ptr) - continue; - if (pos >= size) - continue; - UInt32 start = pos; - for (;;) - { - if (pos >= size) - return S_FALSE; - char c = p[pos]; - if (c == 0 || c == 0x0A) - break; - pos++; - } - item2.Name.SetFrom((const char *)(p + start), pos - start); - } - - _longNames_FileIndex = fileIndex; - return S_OK; -} - -void CHandler::ChangeDuplicateNames() -{ - unsigned i; - for (i = 1; i < _items.Size(); i++) - { - CItem &item = _items[i]; - if (item.Name[0] == '/') - continue; - CItem &prev = _items[i - 1]; - if (item.Name == prev.Name) - { - if (prev.SameNameIndex < 0) - prev.SameNameIndex = 0; - item.SameNameIndex = prev.SameNameIndex + 1; - } - } - for (i = 0; i < _items.Size(); i++) - { - CItem &item = _items[i]; - if (item.SameNameIndex < 0) - continue; - char sz[32]; - ConvertUInt32ToString(item.SameNameIndex + 1, sz); - unsigned len = MyStringLen(sz); - sz[len++] = '.'; - sz[len] = 0; - item.Name.Insert(0, sz); - } -} - -int CHandler::FindItem(UInt32 offset) const -{ - unsigned left = 0, right = _items.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - UInt64 midVal = _items[mid].HeaderPos; - if (offset == midVal) - return mid; - if (offset < midVal) - right = mid; - else - left = mid + 1; - } - return -1; -} - -HRESULT CHandler::AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos) -{ - int fileIndex = FindItem(offset); - if (fileIndex < (int)0) - return S_FALSE; - - size_t i = pos; - do - { - if (i >= size) - return S_FALSE; - } - while (data[i++] != 0); - - AString &s = _libFiles[_numLibFiles]; - const AString &name = _items[fileIndex].Name; - s += name; - if (!name.IsEmpty() && name.Back() == '/') - s.DeleteBack(); - s += " "; - s += (const char *)(data + pos); - s += (char)0xD; - s += (char)0xA; - pos = i; - return S_OK; -} - -static UInt32 Get32(const Byte *p, unsigned be) { if (be) return GetBe32(p); return GetUi32(p); } - -HRESULT CHandler::ParseLibSymbols(IInStream *stream, unsigned fileIndex) -{ - CItem &item = _items[fileIndex]; - if (item.Name != "/" && - item.Name != "__.SYMDEF" && - item.Name != "__.SYMDEF SORTED") - return S_OK; - if (item.Size > ((UInt32)1 << 30) || - item.Size < 4) - return S_OK; - RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); - size_t size = (size_t)item.Size; - CByteArr p(size); - RINOK(ReadStream_FALSE(stream, p, size)); - - size_t pos = 0; - - if (item.Name != "/") - { - // __.SYMDEF parsing (BSD) - unsigned be; - for (be = 0; be < 2; be++) - { - UInt32 tableSize = Get32(p, be); - pos = 4; - if (size - pos < tableSize || (tableSize & 7) != 0) - continue; - size_t namesStart = pos + tableSize; - UInt32 namesSize = Get32(p + namesStart, be); - namesStart += 4; - if (namesStart > size || namesStart + namesSize != size) - continue; - - UInt32 numSymbols = tableSize >> 3; - UInt32 i; - for (i = 0; i < numSymbols; i++, pos += 8) - { - size_t namePos = Get32(p + pos, be); - UInt32 offset = Get32(p + pos + 4, be); - if (AddFunc(offset, p + namesStart, namesSize, namePos) != S_OK) - break; - } - if (i == numSymbols) - { - pos = size; - _type = kType_ALib; - _subType = kSubType_BSD; - break; - } - } - if (be == 2) - return S_FALSE; - } - else if (_numLibFiles == 0) - { - // archive symbol table (GNU) - UInt32 numSymbols = GetBe32(p); - pos = 4; - if (numSymbols > (size - pos) / 4) - return S_FALSE; - pos += 4 * numSymbols; - - for (UInt32 i = 0; i < numSymbols; i++) - { - UInt32 offset = GetBe32(p + 4 + i * 4); - RINOK(AddFunc(offset, p, size, pos)); - } - _type = kType_ALib; - } - else - { - // Second linker file (Microsoft .lib) - UInt32 numMembers = GetUi32(p); - pos = 4; - if (numMembers > (size - pos) / 4) - return S_FALSE; - pos += 4 * numMembers; - - if (size - pos < 4) - return S_FALSE; - UInt32 numSymbols = GetUi32(p + pos); - pos += 4; - if (numSymbols > (size - pos) / 2) - return S_FALSE; - size_t indexStart = pos; - pos += 2 * numSymbols; - - for (UInt32 i = 0; i < numSymbols; i++) - { - // index is 1-based. So 32-bit numSymbols field works as item[0] - UInt32 index = GetUi16(p + indexStart + i * 2); - if (index == 0 || index > numMembers) - return S_FALSE; - UInt32 offset = GetUi32(p + index * 4); - RINOK(AddFunc(offset, p, size, pos)); - } - _type = kType_Lib; - } - // size can be 2-byte aligned in linux files - if (pos != size && pos + (pos & 1) != size) - return S_FALSE; - item.TextFileIndex = _numLibFiles++; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - - UInt64 fileSize = 0; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - - CInArchive arc; - RINOK(arc.Open(stream)); - - if (callback) - { - RINOK(callback->SetTotal(NULL, &fileSize)); - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &arc.Position)); - } - - CItem item; - for (;;) - { - bool filled; - RINOK(arc.GetNextItem(item, filled)); - if (!filled) - break; - _items.Add(item); - arc.SkipData(item.Size); - if (callback && (_items.Size() & 0xFF) == 0) - { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &arc.Position)); - } - } - - if (_items.IsEmpty()) - { - // we don't need false empty archives (8-bytes signature only) - if (arc.Position != fileSize) - return S_FALSE; - } - - _isArc = true; - - _subType = arc.SubType; - - if (ParseLongNames(stream) != S_OK) - UpdateErrorMessage("Long file names parsing error"); - if (_longNames_FileIndex >= 0) - _items.Delete(_longNames_FileIndex); - - if (!_items.IsEmpty() && _items[0].Name == "debian-binary") - { - _type = kType_Deb; - _items.DeleteFrontal(1); - for (unsigned i = 0; i < _items.Size(); i++) - if (_items[i].Name.IsPrefixedBy("data.tar.")) - if (_mainSubfile < 0) - _mainSubfile = i; - else - { - _mainSubfile = -1; - break; - } - } - else - { - ChangeDuplicateNames(); - bool error = false; - for (unsigned li = 0; li < 2 && li < _items.Size(); li++) - if (ParseLibSymbols(stream, li) != S_OK) - error = true; - if (error) - UpdateErrorMessage("Library symbols information error"); - } - - _stream = stream; - _phySize = arc.Position; - - /* - if (fileSize < _phySize) - UpdateErrorMessage("Unexpected end of archive"); - */ - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _phySize = 0; - - _errorMessage.Empty(); - _stream.Release(); - _items.Clear(); - - _type = kType_Ar; - _subType = kSubType_None; - _mainSubfile = -1; - _longNames_FileIndex = -1; - - _numLibFiles = 0; - _libFiles[0].Empty(); - _libFiles[1].Empty(); - - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _phySize; break; - case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; - case kpidExtension: prop = k_TypeExtionsions[(unsigned)_type]; break; - case kpidShortComment: - case kpidSubType: - { - AString s = k_TypeExtionsions[(unsigned)_type]; - if (_subType == kSubType_BSD) - s += ":BSD"; - prop = s; - break; - } - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; - prop = v; - break; - } - case kpidWarning: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; - case kpidIsNotArcType: if (_type != kType_Deb) prop = true; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItem &item = _items[index]; - switch (propID) - { - case kpidPath: - if (item.TextFileIndex >= 0) - prop = (item.TextFileIndex == 0) ? "1.txt" : "2.txt"; - else - prop = (const wchar_t *)NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP)); - break; - case kpidSize: - case kpidPackSize: - if (item.TextFileIndex >= 0) - prop = (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len(); - else - prop = item.Size; - break; - case kpidMTime: - { - if (item.MTime != 0) - { - FILETIME fileTime; - NTime::UnixTimeToFileTime(item.MTime, fileTime); - prop = fileTime; - } - break; - } - case kpidUser: if (item.User != 0) prop = item.User; break; - case kpidGroup: if (item.Group != 0) prop = item.Group; break; - case kpidPosixAttrib: - if (item.TextFileIndex < 0) - prop = item.Mode; - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - 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 CItem &item = _items[allFilesMode ? i : indices[i]]; - totalSize += - (item.TextFileIndex >= 0) ? - (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size; - } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentTotalSize += (item.TextFileIndex >= 0) ? - (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - bool isOk = true; - if (item.TextFileIndex >= 0) - { - const AString &f = _libFiles[(unsigned)item.TextFileIndex]; - if (realOutStream) - RINOK(WriteStream(realOutStream, f, f.Len())); - } - else - { - RINOK(_stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - isOk = (copyCoderSpec->TotalSize == item.Size); - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(isOk ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CItem &item = _items[index]; - if (item.TextFileIndex >= 0) - { - const AString &f = _libFiles[(unsigned)item.TextFileIndex]; - Create_BufInStream_WithNewBuffer((const void *)(const char *)f, f.Len(), stream); - return S_OK; - } - else - return CreateLimitedInStream(_stream, item.GetDataPos(), item.Size, stream); - COM_TRY_END -} - -REGISTER_ARC_I( - "Ar", "ar a deb lib", 0, 0xEC, - kSignature, - 0, - 0, - NULL) - -}} +// ArHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringConvert.h" +#include "../../Common/StringToInt.h" + +#include "../../Windows/PropVariant.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" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NAr { + +/* +The end of each file member (including last file in archive) is 2-bytes aligned. +It uses 0xA padding if required. + +File Names: + +GNU/SVR4 variant (.a static library): + / - archive symbol table + // - the list of the long filenames, separated by one or more LF characters. + /N - the reference to name string in long filenames list + name/ - the name + +Microsoft variant (.lib static library): + / - First linker file (archive symbol table) + / - Second linker file + // - the list of the long filenames, null-terminated. Each string begins + immediately after the null byte in the previous string. + /N - the reference to name string in long filenames list + name/ - the name + +BSD (Mac OS X) variant: + "__.SYMDEF" - archive symbol table + or + "__.SYMDEF SORTED" - archive symbol table + #1/N - the real filename of length N is appended to the file header. +*/ + +static const unsigned kSignatureLen = 8; +static const Byte kSignature[kSignatureLen] = + { '!', '<', 'a', 'r', 'c', 'h', '>', 0x0A }; + +static const unsigned kNameSize = 16; +static const unsigned kTimeSize = 12; +static const unsigned kUserSize = 6; +static const unsigned kModeSize = 8; +static const unsigned kSizeSize = 10; + +static const unsigned kHeaderSize = kNameSize + kTimeSize + kUserSize * 2 + kModeSize + kSizeSize + 1 + 1; + +enum EType +{ + kType_Ar, + kType_ALib, + kType_Deb, + kType_Lib +}; + +static const char * const k_TypeExtionsions[] = +{ + "ar" + , "a" + , "deb" + , "lib" +}; + +enum ESubType +{ + kSubType_None, + kSubType_BSD +}; + +/* +struct CHeader +{ + char Name[kNameSize]; + char MTime[kTimeSize]; + char User[kUserSize]; + char Group[kUserSize]; + char Mode[kModeSize]; + char Size[kSizeSize]; + char Quote; + char NewLine; +}; +*/ + +struct CItem +{ + AString Name; + UInt64 Size; + UInt32 MTime; + UInt32 User; + UInt32 Group; + UInt32 Mode; + + UInt64 HeaderPos; + UInt64 HeaderSize; + + int TextFileIndex; + int SameNameIndex; + + CItem(): TextFileIndex(-1), SameNameIndex(-1) {} + UInt64 GetDataPos() const { return HeaderPos + HeaderSize; } +}; + +class CInArchive +{ + CMyComPtr m_Stream; + +public: + UInt64 Position; + ESubType SubType; + + HRESULT GetNextItem(CItem &itemInfo, bool &filled); + HRESULT Open(IInStream *inStream); + HRESULT SkipData(UInt64 dataSize) + { + return m_Stream->Seek((Int64)(dataSize + (dataSize & 1)), STREAM_SEEK_CUR, &Position); + } +}; + +HRESULT CInArchive::Open(IInStream *inStream) +{ + SubType = kSubType_None; + RINOK(InStream_GetPos(inStream, Position)) + char signature[kSignatureLen]; + RINOK(ReadStream_FALSE(inStream, signature, kSignatureLen)) + Position += kSignatureLen; + if (memcmp(signature, kSignature, kSignatureLen) != 0) + return S_FALSE; + m_Stream = inStream; + return S_OK; +} + +static unsigned RemoveTailSpaces(char *dest, const char *s, unsigned size) +{ + memcpy(dest, s, size); + for (; size != 0; size--) + { + if (dest[size - 1] != ' ') + break; + } + dest[size] = 0; + return size; +} + +static bool OctalToNumber32(const char *s, unsigned size, UInt32 &res) +{ + res = 0; + char sz[32]; + size = RemoveTailSpaces(sz, s, size); + if (size == 0 || strcmp(sz, "-1") == 0) + return true; // some items don't contain any numbers + const char *end; + UInt64 res64 = ConvertOctStringToUInt64(sz, &end); + if ((unsigned)(end - sz) != size) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +static bool DecimalToNumber(const char *s, unsigned size, UInt64 &res) +{ + res = 0; + char sz[32]; + size = RemoveTailSpaces(sz, s, size); + if (size == 0 || strcmp(sz, "-1") == 0) + return true; // some items don't contain any numbers + const char *end; + res = ConvertStringToUInt64(sz, &end); + return ((unsigned)(end - sz) == size); +} + +static bool DecimalToNumber32(const char *s, unsigned size, UInt32 &res) +{ + UInt64 res64; + if (!DecimalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + + +HRESULT CInArchive::GetNextItem(CItem &item, bool &filled) +{ + filled = false; + + char header[kHeaderSize]; + const char *cur = header; + + { + size_t processedSize = sizeof(header); + item.HeaderPos = Position; + item.HeaderSize = kHeaderSize; + RINOK(ReadStream(m_Stream, header, &processedSize)) + if (processedSize != sizeof(header)) + return S_OK; + if (header[kHeaderSize - 2] != 0x60 || + header[kHeaderSize - 1] != 0x0A) + return S_OK; + for (unsigned i = 0; i < kHeaderSize - 2; i++) + // if (header[i] < 0x20) + if (header[i] == 0) + return S_OK; + Position += processedSize; + } + + UInt32 longNameLen = 0; + if (cur[0] == '#' && + cur[1] == '1' && + cur[2] == '/' && + cur[3] != 0) + { + // BSD variant + RIF(DecimalToNumber32(cur + 3, kNameSize - 3 , longNameLen)) + if (longNameLen >= (1 << 12)) + longNameLen = 0; + } + else + { + char tempString[kNameSize + 1]; + RemoveTailSpaces(tempString, cur, kNameSize); + item.Name = tempString; + } + cur += kNameSize; + + RIF(DecimalToNumber32(cur, kTimeSize, item.MTime)) cur += kTimeSize; + RIF(DecimalToNumber32(cur, kUserSize, item.User)) cur += kUserSize; + RIF(DecimalToNumber32(cur, kUserSize, item.Group)) cur += kUserSize; + RIF(OctalToNumber32(cur, kModeSize, item.Mode)) cur += kModeSize; + RIF(DecimalToNumber(cur, kSizeSize, item.Size)) cur += kSizeSize; + + if (longNameLen != 0 && longNameLen <= item.Size) + { + SubType = kSubType_BSD; + size_t processedSize = longNameLen; + char *s = item.Name.GetBuf(longNameLen); + HRESULT res = ReadStream(m_Stream, s, &processedSize); + item.Name.ReleaseBuf_CalcLen(longNameLen); + RINOK(res) + if (processedSize != longNameLen) + return S_OK; + item.Size -= longNameLen; + item.HeaderSize += longNameLen; + Position += processedSize; + } + + filled = true; + return S_OK; +} + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + bool _isArc; + CObjectVector _items; + CMyComPtr _stream; + UInt64 _phySize; + Int32 _mainSubfile; + + EType _type; + ESubType _subType; + int _longNames_FileIndex; + unsigned _numLibFiles; + AString _errorMessage; + AString _libFiles[2]; + + void UpdateErrorMessage(const char *s); + + HRESULT ParseLongNames(IInStream *stream); + void ChangeDuplicateNames(); + int FindItem(UInt32 offset) const; + HRESULT AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos); + HRESULT ParseLibSymbols(IInStream *stream, unsigned fileIndex); +}; + +void CHandler::UpdateErrorMessage(const char *s) +{ + if (!_errorMessage.IsEmpty()) + _errorMessage.Add_LF(); + _errorMessage += s; +} + +static const Byte kArcProps[] = +{ + kpidSubType +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidMTime, + kpidPosixAttrib, + kpidUserId, + kpidGroupId +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +HRESULT CHandler::ParseLongNames(IInStream *stream) +{ + unsigned i; + for (i = 0; i < _items.Size(); i++) + if (_items[i].Name.IsEqualTo("//")) + break; + if (i == _items.Size()) + return S_OK; + + unsigned fileIndex = i; + const CItem &item = _items[fileIndex]; + if (item.Size > ((UInt32)1 << 30)) + return S_FALSE; + RINOK(InStream_SeekSet(stream, item.GetDataPos())) + const size_t size = (size_t)item.Size; + + CByteArr p(size); + RINOK(ReadStream_FALSE(stream, p, size)) + + for (i = 0; i < _items.Size(); i++) + { + CItem &item2 = _items[i]; + if (item2.Name[0] != '/') + continue; + const char *ptr = item2.Name.Ptr(1); + const char *end; + UInt32 pos = ConvertStringToUInt32(ptr, &end); + if (*end != 0 || end == ptr) + continue; + if (pos >= size) + continue; + UInt32 start = pos; + for (;;) + { + if (pos >= size) + return S_FALSE; + const Byte c = p[pos]; + if (c == 0 || c == 0x0A) + break; + pos++; + } + item2.Name.SetFrom((const char *)(p + start), (unsigned)(pos - start)); + } + + _longNames_FileIndex = (int)fileIndex; + return S_OK; +} + +void CHandler::ChangeDuplicateNames() +{ + unsigned i; + for (i = 1; i < _items.Size(); i++) + { + CItem &item = _items[i]; + if (item.Name[0] == '/') + continue; + CItem &prev = _items[i - 1]; + if (item.Name.IsEqualTo(prev.Name)) + { + if (prev.SameNameIndex < 0) + prev.SameNameIndex = 0; + item.SameNameIndex = prev.SameNameIndex + 1; + } + } + for (i = 0; i < _items.Size(); i++) + { + CItem &item = _items[i]; + if (item.SameNameIndex < 0) + continue; + char sz[32]; + ConvertUInt32ToString((unsigned)item.SameNameIndex + 1, sz); + unsigned len = MyStringLen(sz); + sz[len++] = '.'; + sz[len] = 0; + item.Name.Insert(0, sz); + } +} + +int CHandler::FindItem(UInt32 offset) const +{ + unsigned left = 0, right = _items.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const UInt64 midVal = _items[mid].HeaderPos; + if (offset == midVal) + return (int)mid; + if (offset < midVal) + right = mid; + else + left = mid + 1; + } + return -1; +} + +HRESULT CHandler::AddFunc(UInt32 offset, const Byte *data, size_t size, size_t &pos) +{ + const int fileIndex = FindItem(offset); + if (fileIndex < (int)0) + return S_FALSE; + + size_t i = pos; + do + { + if (i >= size) + return S_FALSE; + } + while (data[i++] != 0); + + AString &s = _libFiles[_numLibFiles]; + const AString &name = _items[(unsigned)fileIndex].Name; + s += name; + if (!name.IsEmpty() && name.Back() == '/') + s.DeleteBack(); + s += " "; + s += (const char *)(data + pos); + // s.Add_Char((char)0xD); + s.Add_LF(); + pos = i; + return S_OK; +} + +static UInt32 Get32(const Byte *p, unsigned be) { if (be) return GetBe32(p); return GetUi32(p); } + +HRESULT CHandler::ParseLibSymbols(IInStream *stream, unsigned fileIndex) +{ + CItem &item = _items[fileIndex]; + if (!item.Name.IsEqualTo("/") && + !item.Name.IsEqualTo("__.SYMDEF") && + !item.Name.IsEqualTo("__.SYMDEF SORTED")) + return S_OK; + if (item.Size > ((UInt32)1 << 30) || + item.Size < 4) + return S_OK; + RINOK(InStream_SeekSet(stream, item.GetDataPos())) + size_t size = (size_t)item.Size; + CByteArr p(size); + RINOK(ReadStream_FALSE(stream, p, size)) + + size_t pos = 0; + + if (!item.Name.IsEqualTo("/")) + { + // "__.SYMDEF" parsing (BSD) + unsigned be; + for (be = 0; be < 2; be++) + { + const UInt32 tableSize = Get32(p, be); + pos = 4; + if (size - pos < tableSize || (tableSize & 7) != 0) + continue; + size_t namesStart = pos + tableSize; + const UInt32 namesSize = Get32(p.ConstData() + namesStart, be); + namesStart += 4; + if (namesStart > size || namesStart + namesSize != size) + continue; + + const UInt32 numSymbols = tableSize >> 3; + UInt32 i; + for (i = 0; i < numSymbols; i++, pos += 8) + { + size_t namePos = Get32(p + pos, be); + const UInt32 offset = Get32(p + pos + 4, be); + if (AddFunc(offset, p + namesStart, namesSize, namePos) != S_OK) + break; + } + if (i == numSymbols) + { + pos = size; + _type = kType_ALib; + _subType = kSubType_BSD; + break; + } + } + if (be == 2) + return S_FALSE; + } + else if (_numLibFiles == 0) + { + // archive symbol table (GNU) + const UInt32 numSymbols = GetBe32(p); + pos = 4; + if (numSymbols > (size - pos) / 4) + return S_FALSE; + pos += 4 * numSymbols; + + for (UInt32 i = 0; i < numSymbols; i++) + { + const UInt32 offset = GetBe32(p + 4 + i * 4); + RINOK(AddFunc(offset, p, size, pos)) + } + _type = kType_ALib; + } + else + { + // Second linker file (Microsoft .lib) + const UInt32 numMembers = GetUi32(p); + pos = 4; + if (numMembers > (size - pos) / 4) + return S_FALSE; + pos += 4 * numMembers; + + if (size - pos < 4) + return S_FALSE; + const UInt32 numSymbols = GetUi32(p + pos); + pos += 4; + if (numSymbols > (size - pos) / 2) + return S_FALSE; + size_t indexStart = pos; + pos += 2 * numSymbols; + + for (UInt32 i = 0; i < numSymbols; i++) + { + // index is 1-based. So 32-bit numSymbols field works as item[0] + const UInt32 index = GetUi16(p + indexStart + i * 2); + if (index == 0 || index > numMembers) + return S_FALSE; + const UInt32 offset = GetUi32(p + index * 4); + RINOK(AddFunc(offset, p, size, pos)) + } + _type = kType_Lib; + } + // size can be 2-byte aligned in linux files + if (pos != size && pos + (pos & 1) != size) + return S_FALSE; + item.TextFileIndex = (int)(_numLibFiles++); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + + UInt64 fileSize; + RINOK(InStream_AtBegin_GetSize(stream, fileSize)) + + CInArchive arc; + RINOK(arc.Open(stream)) + + if (callback) + { + RINOK(callback->SetTotal(NULL, &fileSize)) + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &arc.Position)) + } + + CItem item; + for (;;) + { + bool filled; + RINOK(arc.GetNextItem(item, filled)) + if (!filled) + break; + _items.Add(item); + arc.SkipData(item.Size); + if (callback && (_items.Size() & 0xFF) == 0) + { + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &arc.Position)) + } + } + + if (_items.IsEmpty()) + { + // we don't need false empty archives (8-bytes signature only) + if (arc.Position != fileSize) + return S_FALSE; + } + + _isArc = true; + + _subType = arc.SubType; + + if (ParseLongNames(stream) != S_OK) + UpdateErrorMessage("Long file names parsing error"); + if (_longNames_FileIndex >= 0) + _items.Delete((unsigned)_longNames_FileIndex); + + if (!_items.IsEmpty() && _items[0].Name.IsEqualTo("debian-binary")) + { + _type = kType_Deb; + _items.DeleteFrontal(1); + for (unsigned i = 0; i < _items.Size(); i++) + if (_items[i].Name.IsPrefixedBy("data.tar.")) + { + if (_mainSubfile < 0) + _mainSubfile = (int)i; + else + { + _mainSubfile = -1; + break; + } + } + } + else + { + ChangeDuplicateNames(); + bool error = false; + for (unsigned li = 0; li < 2 && li < _items.Size(); li++) + if (ParseLibSymbols(stream, li) != S_OK) + error = true; + if (error) + UpdateErrorMessage("Library symbols information error"); + } + + _stream = stream; + _phySize = arc.Position; + + /* + if (fileSize < _phySize) + UpdateErrorMessage("Unexpected end of archive"); + */ + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _phySize = 0; + + _errorMessage.Empty(); + _stream.Release(); + _items.Clear(); + + _type = kType_Ar; + _subType = kSubType_None; + _mainSubfile = -1; + _longNames_FileIndex = -1; + + _numLibFiles = 0; + _libFiles[0].Empty(); + _libFiles[1].Empty(); + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _phySize; break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; + case kpidExtension: prop = k_TypeExtionsions[(unsigned)_type]; break; + case kpidShortComment: + case kpidSubType: + { + AString s (k_TypeExtionsions[(unsigned)_type]); + if (_subType == kSubType_BSD) + s += ":BSD"; + prop = s; + break; + } + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + prop = v; + break; + } + case kpidWarning: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; + case kpidIsNotArcType: if (_type != kType_Deb) prop = true; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = _items[index]; + switch (propID) + { + case kpidPath: + if (item.TextFileIndex >= 0) + prop = (item.TextFileIndex == 0) ? "1.txt" : "2.txt"; + else + prop = (const wchar_t *)NItemName::GetOsPath_Remove_TailSlash(MultiByteToUnicodeString(item.Name, CP_OEMCP)); + break; + case kpidSize: + case kpidPackSize: + if (item.TextFileIndex >= 0) + prop = (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len(); + else + prop = item.Size; + break; + case kpidMTime: + { + if (item.MTime != 0) + PropVariant_SetFrom_UnixTime(prop, item.MTime); + 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; + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(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 CItem &item = _items[allFilesMode ? i : indices[i]]; + totalSize += + (item.TextFileIndex >= 0) ? + (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size; + } + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + currentTotalSize += (item.TextFileIndex >= 0) ? + (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + opRes = NExtract::NOperationResult::kOK; + if (item.TextFileIndex >= 0) + { + const AString &f = _libFiles[(unsigned)item.TextFileIndex]; + if (realOutStream) + RINOK(WriteStream(realOutStream, f, f.Len())) + } + else + { + RINOK(InStream_SeekSet(_stream, item.GetDataPos())) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item.Size) + opRes = NExtract::NOperationResult::kDataError; + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + const CItem &item = _items[index]; + if (item.TextFileIndex >= 0) + { + const AString &f = _libFiles[(unsigned)item.TextFileIndex]; + Create_BufInStream_WithNewBuffer((const void *)(const char *)f, f.Len(), stream); + return S_OK; + } + else + return CreateLimitedInStream(_stream, item.GetDataPos(), item.Size, stream); + COM_TRY_END +} + +REGISTER_ARC_I( + "Ar", "ar a deb udeb lib", NULL, 0xEC, + kSignature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Archive.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive.def --- p7zip-rar-16.02/CPP/7zip/Archive/Archive.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive.def 2023-04-03 11:00:00.000000000 +0000 @@ -0,0 +1,14 @@ +EXPORTS + CreateObject PRIVATE + + GetHandlerProperty PRIVATE + GetNumberOfFormats PRIVATE + GetHandlerProperty2 PRIVATE + GetIsArc PRIVATE + + SetCodecs PRIVATE + + SetLargePageMode PRIVATE + SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Archive2.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive2.def --- p7zip-rar-16.02/CPP/7zip/Archive/Archive2.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Archive2.def 2023-04-03 10:00:00.000000000 +0000 @@ -0,0 +1,21 @@ +EXPORTS + CreateObject PRIVATE + + GetHandlerProperty PRIVATE + GetNumberOfFormats PRIVATE + GetHandlerProperty2 PRIVATE + GetIsArc PRIVATE + + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE + CreateDecoder PRIVATE + CreateEncoder PRIVATE + + GetHashers PRIVATE + + SetCodecs PRIVATE + + SetLargePageMode PRIVATE + SetCaseSensitive PRIVATE + + GetModuleProp PRIVATE diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ArchiveExports.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArchiveExports.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ArchiveExports.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArchiveExports.cpp 2023-03-23 11:00:00.000000000 +0000 @@ -1,151 +1,158 @@ -// ArchiveExports.cpp - -#include "StdAfx.h" - -#include "../../../C/7zVersion.h" - -#include "../../Common/ComTry.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" - -static const unsigned kNumArcsMax = 64; -static unsigned g_NumArcs = 0; -static unsigned g_DefaultArcIndex = 0; -static const CArcInfo *g_Arcs[kNumArcsMax]; - -void RegisterArc(const CArcInfo *arcInfo) throw() -{ - if (g_NumArcs < kNumArcsMax) - { - const char *p = arcInfo->Name; - if (p[0] == '7' && p[1] == 'z' && p[2] == 0) - g_DefaultArcIndex = g_NumArcs; - g_Arcs[g_NumArcs++] = arcInfo; - } -} - -DEFINE_GUID(CLSID_CArchiveHandler, - k_7zip_GUID_Data1, - k_7zip_GUID_Data2, - k_7zip_GUID_Data3_Common, - 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); - -#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) - -static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value) -{ - if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) - value->vt = VT_BSTR; - return S_OK; -} - -static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) -{ - return SetPropStrFromBin((const char *)&guid, sizeof(guid), value); -} - -int FindFormatCalssId(const GUID *clsid) -{ - GUID cls = *clsid; - CLS_ARC_ID_ITEM(cls) = 0; - if (cls != CLSID_CArchiveHandler) - return -1; - Byte id = CLS_ARC_ID_ITEM(*clsid); - for (unsigned i = 0; i < g_NumArcs; i++) - if (g_Arcs[i]->Id == id) - return (int)i; - return -1; -} - -STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) -{ - COM_TRY_BEGIN - { - int needIn = (*iid == IID_IInArchive); - int needOut = (*iid == IID_IOutArchive); - if (!needIn && !needOut) - return E_NOINTERFACE; - int formatIndex = FindFormatCalssId(clsid); - if (formatIndex < 0) - return CLASS_E_CLASSNOTAVAILABLE; - - const CArcInfo &arc = *g_Arcs[formatIndex]; - if (needIn) - { - *outObject = arc.CreateInArchive(); - ((IInArchive *)*outObject)->AddRef(); - } - else - { - if (!arc.CreateOutArchive) - return CLASS_E_CLASSNOTAVAILABLE; - *outObject = arc.CreateOutArchive(); - ((IOutArchive *)*outObject)->AddRef(); - } - } - COM_TRY_END - return S_OK; -} - -STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::PropVariant_Clear(value); - if (formatIndex >= g_NumArcs) - return E_INVALIDARG; - const CArcInfo &arc = *g_Arcs[formatIndex]; - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case NArchive::NHandlerPropID::kName: prop = arc.Name; break; - case NArchive::NHandlerPropID::kClassID: - { - GUID clsId = CLSID_CArchiveHandler; - CLS_ARC_ID_ITEM(clsId) = arc.Id; - return SetPropGUID(clsId, value); - } - case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break; - case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break; - case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break; - case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break; - 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::kSignatureOffset: prop = (UInt32)arc.SignatureOffset; break; - // case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break; - - case NArchive::NHandlerPropID::kSignature: - if (arc.SignatureSize != 0 && !arc.IsMultiSignature()) - return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); - break; - case NArchive::NHandlerPropID::kMultiSignature: - if (arc.SignatureSize != 0 && arc.IsMultiSignature()) - return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) -{ - return GetHandlerProperty2(g_DefaultArcIndex, propID, value); -} - -STDAPI GetNumberOfFormats(UINT32 *numFormats) -{ - *numFormats = g_NumArcs; - return S_OK; -} - -STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc) -{ - *isArc = NULL; - if (formatIndex >= g_NumArcs) - return E_INVALIDARG; - *isArc = g_Arcs[formatIndex]->IsArc; - return S_OK; -} +// ArchiveExports.cpp + +#include "StdAfx.h" + +#include "../../../C/7zVersion.h" + +#include "../../Common/ComTry.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" + +static const unsigned kNumArcsMax = 72; +static unsigned g_NumArcs = 0; +static unsigned g_DefaultArcIndex = 0; +static const CArcInfo *g_Arcs[kNumArcsMax]; + +void RegisterArc(const CArcInfo *arcInfo) throw() +{ + if (g_NumArcs < kNumArcsMax) + { + const char *p = arcInfo->Name; + if (p[0] == '7' && p[1] == 'z' && p[2] == 0) + g_DefaultArcIndex = g_NumArcs; + g_Arcs[g_NumArcs++] = arcInfo; + } + // else throw 1; +} + +Z7_DEFINE_GUID(CLSID_CArchiveHandler, + k_7zip_GUID_Data1, + k_7zip_GUID_Data2, + k_7zip_GUID_Data3_Common, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); + +#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5]) + +static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value) +{ + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != NULL) + value->vt = VT_BSTR; + return S_OK; +} + +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) +{ + return SetPropStrFromBin((const char *)&guid, sizeof(guid), value); +} + +static int FindFormatCalssId(const GUID *clsid) +{ + GUID cls = *clsid; + CLS_ARC_ID_ITEM(cls) = 0; + if (cls != CLSID_CArchiveHandler) + return -1; + const Byte id = CLS_ARC_ID_ITEM(*clsid); + for (unsigned i = 0; i < g_NumArcs; i++) + if (g_Arcs[i]->Id == id) + return (int)i; + return -1; +} + +STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + { + const int needIn = (*iid == IID_IInArchive); + const int needOut = (*iid == IID_IOutArchive); + if (!needIn && !needOut) + return E_NOINTERFACE; + const int formatIndex = FindFormatCalssId(clsid); + if (formatIndex < 0) + return CLASS_E_CLASSNOTAVAILABLE; + + const CArcInfo &arc = *g_Arcs[formatIndex]; + if (needIn) + { + *outObject = arc.CreateInArchive(); + ((IInArchive *)*outObject)->AddRef(); + } + else + { + if (!arc.CreateOutArchive) + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = arc.CreateOutArchive(); + ((IOutArchive *)*outObject)->AddRef(); + } + } + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value); +STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::PropVariant_Clear(value); + if (formatIndex >= g_NumArcs) + return E_INVALIDARG; + const CArcInfo &arc = *g_Arcs[formatIndex]; + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case NArchive::NHandlerPropID::kName: prop = arc.Name; break; + case NArchive::NHandlerPropID::kClassID: + { + GUID clsId = CLSID_CArchiveHandler; + CLS_ARC_ID_ITEM(clsId) = arc.Id; + return SetPropGUID(clsId, value); + } + case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break; + case NArchive::NHandlerPropID::kAddExtension: if (arc.AddExt) prop = arc.AddExt; break; + case NArchive::NHandlerPropID::kUpdate: prop = (bool)(arc.CreateOutArchive != NULL); break; + case NArchive::NHandlerPropID::kKeepName: prop = ((arc.Flags & NArcInfoFlags::kKeepName) != 0); break; + 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; + + case NArchive::NHandlerPropID::kSignature: + if (arc.SignatureSize != 0 && !arc.IsMultiSignature()) + return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); + break; + case NArchive::NHandlerPropID::kMultiSignature: + if (arc.SignatureSize != 0 && arc.IsMultiSignature()) + return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value); + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value); +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + return GetHandlerProperty2(g_DefaultArcIndex, propID, value); +} + +STDAPI GetNumberOfFormats(UINT32 *numFormats); +STDAPI GetNumberOfFormats(UINT32 *numFormats) +{ + *numFormats = g_NumArcs; + return S_OK; +} + +STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc); +STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc) +{ + *isArc = NULL; + if (formatIndex >= g_NumArcs) + return E_INVALIDARG; + *isArc = g_Arcs[formatIndex]->IsArc; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ArjHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArjHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ArjHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ArjHandler.cpp 2023-12-21 10:00:00.000000000 +0000 @@ -1,977 +1,978 @@ -// ArjHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariant.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 "../Compress/LzhDecoder.h" - -#include "Common/ItemNameUtils.h" -#include "Common/OutStreamWithCRC.h" - -namespace NCompress { -namespace NArj { -namespace NDecoder { - -static const unsigned kMatchMinLen = 3; - -static const UInt32 kWindowSize = 1 << 15; // must be >= (1 << 14) - -class CCoder: - public ICompressCoder, - public CMyUnknownImp -{ - CLzOutWindow _outWindow; - NBitm::CDecoder _inBitStream; - - class CCoderReleaser - { - CCoder *_coder; - public: - CCoderReleaser(CCoder *coder): _coder(coder) {} - void Disable() { _coder = NULL; } - ~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); } - }; - friend class CCoderReleaser; - - HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress); -public: - MY_UNKNOWN_IMP - - bool FinishMode; - CCoder(): FinishMode(false) {} - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } -}; - -HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress) -{ - const UInt32 kStep = 1 << 20; - UInt64 next = 0; - if (rem > kStep && progress) - next = rem - kStep; - - while (rem != 0) - { - if (rem <= next) - { - if (_inBitStream.ExtraBitsWereRead()) - return S_FALSE; - - UInt64 packSize = _inBitStream.GetProcessedSize(); - UInt64 pos = _outWindow.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - next = 0; - if (rem > kStep) - next = rem - kStep; - } - - UInt32 len; - - { - const unsigned kNumBits = 7 + 7; - UInt32 val = _inBitStream.GetValue(kNumBits); - - if ((val & (1 << (kNumBits - 1))) == 0) - { - _outWindow.PutByte((Byte)(val >> 5)); - _inBitStream.MovePos(1 + 8); - rem--; - continue; - } - - UInt32 mask = 1 << (kNumBits - 2); - unsigned w; - - for (w = 1; w < 7; w++, mask >>= 1) - if ((val & mask) == 0) - break; - - unsigned readBits = (w != 7 ? 1 : 0); - readBits += w + w; - len = (1 << w) - 1 + kMatchMinLen - 1 + - (((val >> (kNumBits - readBits)) & ((1 << w) - 1))); - _inBitStream.MovePos(readBits); - } - - { - const unsigned kNumBits = 4 + 13; - UInt32 val = _inBitStream.GetValue(kNumBits); - - unsigned readBits = 1; - unsigned w; - - if ((val & ((UInt32)1 << 16)) == 0) w = 9; - else if ((val & ((UInt32)1 << 15)) == 0) w = 10; - else if ((val & ((UInt32)1 << 14)) == 0) w = 11; - else if ((val & ((UInt32)1 << 13)) == 0) w = 12; - else { w = 13; readBits = 0; } - - readBits += w + w - 9; - - UInt32 dist = ((UInt32)1 << w) - (1 << 9) + - (((val >> (kNumBits - readBits)) & ((1 << w) - 1))); - _inBitStream.MovePos(readBits); - - if (len > rem) - len = (UInt32)rem; - - if (!_outWindow.CopyBlock(dist, len)) - return S_FALSE; - rem -= len; - } - } - - if (FinishMode) - { - if (_inBitStream.ReadAlignBits() != 0) - return S_FALSE; - } - - if (_inBitStream.ExtraBitsWereRead()) - return S_FALSE; - - return S_OK; -} - - - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try - { - if (!outSize) - return E_INVALIDARG; - - if (!_outWindow.Create(kWindowSize)) - return E_OUTOFMEMORY; - if (!_inBitStream.Create(1 << 17)) - return E_OUTOFMEMORY; - - _outWindow.SetStream(outStream); - _outWindow.Init(false); - _inBitStream.SetStream(inStream); - _inBitStream.Init(); - - CCoderReleaser coderReleaser(this); - HRESULT res; - { - res = CodeReal(*outSize, progress); - if (res != S_OK) - return res; - } - - coderReleaser.Disable(); - return _outWindow.Flush(); - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}}} - - - - -using namespace NWindows; - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NArj { - -static const unsigned kBlockSizeMin = 30; -static const unsigned kBlockSizeMax = 2600; - -static const Byte kSig0 = 0x60; -static const Byte kSig1 = 0xEA; - -namespace NCompressionMethod -{ - enum - { - kStored = 0, - kCompressed1a = 1, - kCompressed1b = 2, - kCompressed1c = 3, - kCompressed2 = 4, - kNoDataNoCRC = 8, - kNoData = 9 - }; -} - -namespace NFileType -{ - enum - { - kBinary = 0, - k7BitText, - kArchiveHeader, - kDirectory, - kVolumeLablel, - kChapterLabel - }; -} - -namespace NFlags -{ - const Byte kGarbled = 1 << 0; - const Byte kAnsiPage = 1 << 1; // or (OLD_SECURED_FLAG) obsolete - const Byte kVolume = 1 << 2; - const Byte kExtFile = 1 << 3; - const Byte kPathSym = 1 << 4; - const Byte kBackup = 1 << 5; // obsolete - const Byte kSecured = 1 << 6; - const Byte kDualName = 1 << 7; -} - -namespace NHostOS -{ - enum EEnum - { - kMSDOS = 0, // MS-DOS, OS/2, Win32, pkarj 2.50 (FAT / VFAT / FAT32) - kPRIMOS, - kUnix, - kAMIGA, - kMac, - kOS_2, - kAPPLE_GS, - kAtari_ST, - kNext, - kVAX_VMS, - kWIN95 - }; -} - -static const char * const kHostOS[] = -{ - "MSDOS" - , "PRIMOS" - , "UNIX" - , "AMIGA" - , "MAC" - , "OS/2" - , "APPLE GS" - , "ATARI ST" - , "NEXT" - , "VAX VMS" - , "WIN95" -}; - -struct CArcHeader -{ - // Byte ArchiverVersion; - // Byte ExtractVersion; - Byte HostOS; - // Byte Flags; - // Byte SecuryVersion; - // Byte FileType; - // Byte Reserved; - UInt32 CTime; - UInt32 MTime; - UInt32 ArchiveSize; - // UInt32 SecurPos; - // UInt16 FilespecPosInFilename; - UInt16 SecurSize; - // Byte EncryptionVersion; - // Byte LastChapter; - AString Name; - AString Comment; - - HRESULT Parse(const Byte *p, unsigned size); -}; - -API_FUNC_static_IsArc IsArc_Arj(const Byte *p, size_t size) -{ - if (size < kBlockSizeMin + 4) - return k_IsArc_Res_NEED_MORE; - if (p[0] != kSig0 || p[1] != kSig1) - return k_IsArc_Res_NO; - UInt32 blockSize = Get16(p + 2); - if (blockSize < kBlockSizeMin || - blockSize > kBlockSizeMax) - return k_IsArc_Res_NO; - - p += 4; - size -= 4; - - Byte headerSize = p[0]; - if (headerSize < kBlockSizeMin || - headerSize > blockSize || - p[6] != NFileType::kArchiveHeader || - p[28] > 8) // EncryptionVersion - return k_IsArc_Res_NO; - - if (blockSize + 4 <= size) - if (Get32(p + blockSize) != CrcCalc(p, blockSize)) - return k_IsArc_Res_NO; - - return k_IsArc_Res_YES; -} -} - -static HRESULT ReadString(const Byte *p, unsigned &size, AString &res) -{ - unsigned num = size; - for (unsigned i = 0; i < num;) - { - if (p[i++] == 0) - { - size = i; - res = (const char *)p; - return S_OK; - } - } - return S_FALSE; -} - -HRESULT CArcHeader::Parse(const Byte *p, unsigned size) -{ - Byte headerSize = p[0]; - if (headerSize < kBlockSizeMin || headerSize > size) - return S_FALSE; - // ArchiverVersion = p[1]; - // ExtractVersion = p[2]; - HostOS = p[3]; - // Flags = p[4]; - // SecuryVersion = p[5]; - if (p[6] != NFileType::kArchiveHeader) - return S_FALSE; - // Reserved = p[7]; - CTime = Get32(p + 8); - MTime = Get32(p + 12); - ArchiveSize = Get32(p + 16); // it can be zero. (currently used only for secured archives) - // SecurPos = Get32(p + 20); - // UInt16 filespecPositionInFilename = Get16(p + 24); - SecurSize = Get16(p + 26); - // EncryptionVersion = p[28]; - // LastChapter = p[29]; - unsigned pos = headerSize; - unsigned size1 = size - pos; - RINOK(ReadString(p + pos, size1, Name)); - pos += size1; - size1 = size - pos; - RINOK(ReadString(p + pos, size1, Comment)); - pos += size1; - return S_OK; -} - -struct CItem -{ - AString Name; - AString Comment; - - UInt32 MTime; - UInt32 PackSize; - UInt32 Size; - UInt32 FileCRC; - UInt32 SplitPos; - - Byte Version; - Byte ExtractVersion; - Byte HostOS; - Byte Flags; - Byte Method; - Byte FileType; - - // UInt16 FilespecPosInFilename; - UInt16 FileAccessMode; - // Byte FirstChapter; - // Byte LastChapter; - - UInt64 DataPosition; - - bool IsEncrypted() const { return (Flags & NFlags::kGarbled) != 0; } - bool IsDir() const { return (FileType == NFileType::kDirectory); } - bool IsSplitAfter() const { return (Flags & NFlags::kVolume) != 0; } - bool IsSplitBefore() const { return (Flags & NFlags::kExtFile) != 0; } - UInt32 GetWinAttrib() const - { - UInt32 atrrib = 0; - switch (HostOS) - { - case NHostOS::kMSDOS: - case NHostOS::kWIN95: - atrrib = FileAccessMode; - break; - } - if (IsDir()) - atrrib |= FILE_ATTRIBUTE_DIRECTORY; - return atrrib; - } - - HRESULT Parse(const Byte *p, unsigned size); -}; - -HRESULT CItem::Parse(const Byte *p, unsigned size) -{ - Byte headerSize = p[0]; - if (headerSize < kBlockSizeMin || headerSize > size) - return S_FALSE; - Version = p[1]; - ExtractVersion = p[2]; - HostOS = p[3]; - Flags = p[4]; - Method = p[5]; - FileType = p[6]; - // Reserved = p[7]; - MTime = Get32(p + 8); - PackSize = Get32(p + 12); - Size = Get32(p + 16); - FileCRC = Get32(p + 20); - // FilespecPosInFilename = Get16(p + 24); - FileAccessMode = Get16(p + 26); - // FirstChapter = p[28]; - // FirstChapter = p[29]; - - SplitPos = 0; - if (IsSplitBefore() && headerSize >= 34) - SplitPos = Get32(p + 30); - - unsigned pos = headerSize; - unsigned size1 = size - pos; - RINOK(ReadString(p + pos, size1, Name)); - pos += size1; - size1 = size - pos; - RINOK(ReadString(p + pos, size1, Comment)); - pos += size1; - - return S_OK; -} - -enum EErrorType -{ - k_ErrorType_OK, - k_ErrorType_Corrupted, - k_ErrorType_UnexpectedEnd, -}; - -class CArc -{ -public: - UInt64 Processed; - EErrorType Error; - bool IsArc; - IInStream *Stream; - IArchiveOpenCallback *Callback; - UInt64 NumFiles; - CArcHeader Header; - - HRESULT Open(); - HRESULT GetNextItem(CItem &item, bool &filled); - void Close() - { - IsArc = false; - Error = k_ErrorType_OK; - } -private: - UInt32 _blockSize; - Byte _block[kBlockSizeMax + 4]; - - HRESULT ReadBlock(bool &filled, bool readSignature); - HRESULT SkipExtendedHeaders(); - HRESULT Read(void *data, size_t *size); -}; - -HRESULT CArc::Read(void *data, size_t *size) -{ - HRESULT res = ReadStream(Stream, data, size); - Processed += *size; - return res; -} - -#define READ_STREAM(_dest_, _size_) \ - { size_t _processed_ = (_size_); RINOK(Read(_dest_, &_processed_)); \ - if (_processed_ != (_size_)) { Error = k_ErrorType_UnexpectedEnd; return S_OK; } } - -HRESULT CArc::ReadBlock(bool &filled, bool readSignature) -{ - Error = k_ErrorType_OK; - filled = false; - Byte buf[4]; - unsigned signSize = readSignature ? 2 : 0; - READ_STREAM(buf, signSize + 2) - if (readSignature) - if (buf[0] != kSig0 || buf[1] != kSig1) - { - Error = k_ErrorType_Corrupted; - return S_OK; - } - _blockSize = Get16(buf + signSize); - if (_blockSize == 0) // end of archive - return S_OK; - if (_blockSize < kBlockSizeMin || - _blockSize > kBlockSizeMax) - { - Error = k_ErrorType_Corrupted; - return S_OK; - } - READ_STREAM(_block, _blockSize + 4); - if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize)) - { - Error = k_ErrorType_Corrupted; - return S_OK; - } - filled = true; - return S_OK; -} - -HRESULT CArc::SkipExtendedHeaders() -{ - for (UInt32 i = 0;; i++) - { - bool filled; - RINOK(ReadBlock(filled, false)); - if (!filled) - return S_OK; - if (Callback && (i & 0xFF) == 0) - RINOK(Callback->SetCompleted(&NumFiles, &Processed)); - } -} - -HRESULT CArc::Open() -{ - bool filled; - RINOK(ReadBlock(filled, true)); - if (!filled) - return S_FALSE; - RINOK(Header.Parse(_block, _blockSize)); - IsArc = true; - return SkipExtendedHeaders(); -} - -HRESULT CArc::GetNextItem(CItem &item, bool &filled) -{ - RINOK(ReadBlock(filled, true)); - if (!filled) - return S_OK; - filled = false; - if (item.Parse(_block, _blockSize) != S_OK) - { - Error = k_ErrorType_Corrupted; - return S_OK; - } - /* - UInt32 extraData; - if ((header.Flags & NFlags::kExtFile) != 0) - extraData = GetUi32(_block + pos); - */ - - RINOK(SkipExtendedHeaders()); - filled = true; - return S_OK; -} - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CObjectVector _items; - CMyComPtr _stream; - UInt64 _phySize; - CArc _arc; -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - - HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback); -}; - -static const Byte kArcProps[] = -{ - kpidName, - kpidCTime, - kpidMTime, - kpidHostOS, - kpidComment -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPosition, - kpidPackSize, - kpidMTime, - kpidAttrib, - kpidEncrypted, - kpidCRC, - kpidMethod, - kpidHostOS, - kpidComment -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -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; -} - -static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop) -{ - char temp[16]; - const char *s = NULL; - if (hostOS < ARRAY_SIZE(kHostOS)) - s = kHostOS[hostOS]; - else - { - ConvertUInt32ToString(hostOS, temp); - s = temp; - } - prop = s; -} - -static void SetUnicodeString(const AString &s, NCOM::CPropVariant &prop) -{ - if (!s.IsEmpty()) - prop = MultiByteToUnicodeString(s, CP_OEMCP); -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _phySize; break; - case kpidName: SetUnicodeString(_arc.Header.Name, prop); break; - case kpidCTime: SetTime(_arc.Header.CTime, prop); break; - case kpidMTime: SetTime(_arc.Header.MTime, prop); break; - case kpidHostOS: SetHostOS(_arc.Header.HostOS, prop); break; - case kpidComment: SetUnicodeString(_arc.Header.Comment, prop); break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_arc.IsArc) v |= kpv_ErrorFlags_IsNotArc; - switch (_arc.Error) - { - case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; - case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; - } - 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 CItem &item = _items[index]; - switch (propID) - { - case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidPackSize: prop = item.PackSize; break; - case kpidPosition: if (item.IsSplitBefore() || item.IsSplitAfter()) prop = (UInt64)item.SplitPos; break; - case kpidAttrib: prop = item.GetWinAttrib(); break; - case kpidEncrypted: prop = item.IsEncrypted(); break; - case kpidCRC: prop = item.FileCRC; break; - case kpidMethod: prop = item.Method; break; - case kpidHostOS: SetHostOS(item.HostOS, prop); break; - case kpidMTime: SetTime(item.MTime, prop); break; - case kpidComment: SetUnicodeString(item.Comment, prop); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback) -{ - Close(); - - UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - - _arc.Stream = inStream; - _arc.Callback = callback; - _arc.NumFiles = 0; - _arc.Processed = 0; - - RINOK(_arc.Open()); - - _phySize = _arc.Processed; - if (_arc.Header.ArchiveSize != 0) - _phySize = (UInt64)_arc.Header.ArchiveSize + _arc.Header.SecurSize; - - for (;;) - { - CItem item; - bool filled; - - _arc.Error = k_ErrorType_OK; - RINOK(_arc.GetNextItem(item, filled)); - - if (_arc.Error != k_ErrorType_OK) - break; - - if (!filled) - { - if (_arc.Error == k_ErrorType_OK) - if (_arc.Header.ArchiveSize == 0) - _phySize = _arc.Processed; - break; - } - item.DataPosition = _arc.Processed; - _items.Add(item); - - UInt64 pos = item.DataPosition + item.PackSize; - if (_arc.Header.ArchiveSize == 0) - _phySize = pos; - if (pos > endPos) - { - _arc.Error = k_ErrorType_UnexpectedEnd; - break; - } - - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); - _arc.NumFiles = _items.Size(); - _arc.Processed = pos; - - if (callback && (_items.Size() & 0xFF) == 0) - { - RINOK(callback->SetCompleted(&_arc.NumFiles, &_arc.Processed)); - } - } - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - HRESULT res; - { - res = Open2(inStream, callback); - if (res == S_OK) - { - _stream = inStream; - return S_OK; - } - } - return res; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _arc.Close(); - _phySize = 0; - _items.Clear(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - UInt64 totalUnpacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const CItem &item = _items[allFilesMode ? i : indices[i]]; - totalUnpacked += item.Size; - // totalPacked += item.PackSize; - } - extractCallback->SetTotal(totalUnpacked); - - totalUnpacked = totalPacked = 0; - UInt64 curUnpacked, curPacked; - - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL; - CMyComPtr lzhDecoder; - - NCompress::NArj::NDecoder::CCoder *arjDecoderSpec = NULL; - CMyComPtr arjDecoder; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(inStreamSpec); - inStreamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked) - { - lps->InSize = totalPacked; - lps->OutSize = totalUnpacked; - RINOK(lps->SetCur()); - - curUnpacked = curPacked = 0; - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) - { - // if (!testMode) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - continue; - } - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - curUnpacked = item.Size; - curPacked = item.PackSize; - - { - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(); - - inStreamSpec->Init(item.PackSize); - - UInt64 pos; - _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); - - HRESULT result = S_OK; - Int32 opRes = NExtract::NOperationResult::kOK; - - if (item.IsEncrypted()) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else - { - switch (item.Method) - { - case NCompressionMethod::kStored: - { - result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) - result = S_FALSE; - break; - } - case NCompressionMethod::kCompressed1a: - case NCompressionMethod::kCompressed1b: - case NCompressionMethod::kCompressed1c: - { - if (!lzhDecoder) - { - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - } - lzhDecoderSpec->FinishMode = true; - const UInt32 kHistorySize = 26624; - lzhDecoderSpec->SetDictSize(kHistorySize); - result = lzhDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress); - if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize) - result = S_FALSE; - break; - } - case NCompressionMethod::kCompressed2: - { - if (!arjDecoder) - { - arjDecoderSpec = new NCompress::NArj::NDecoder::CCoder; - arjDecoder = arjDecoderSpec; - } - arjDecoderSpec->FinishMode = true; - result = arjDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress); - if (result == S_OK && arjDecoderSpec->GetInputProcessedSize() != item.PackSize) - result = S_FALSE; - break; - } - default: - opRes = NExtract::NOperationResult::kUnsupportedMethod; - } - } - - if (opRes == NExtract::NOperationResult::kOK) - { - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else - { - RINOK(result); - opRes = (outStreamSpec->GetCRC() == item.FileCRC) ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kCRCError; - } - } - - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - } - - return S_OK; - COM_TRY_END -} - -static const Byte k_Signature[] = { kSig0, kSig1 }; - -REGISTER_ARC_I( - "Arj", "arj", 0, 4, - k_Signature, - 0, - 0, - IsArc_Arj) - -}} +// ArjHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/AutoPtr.h" +#include "../../Common/ComTry.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariant.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 "../Compress/LzhDecoder.h" + +#include "Common/ItemNameUtils.h" +#include "Common/OutStreamWithCRC.h" + +namespace NCompress { +namespace NArj { +namespace NDecoder { + +static const unsigned kMatchMinLen = 3; +static const UInt32 kWindowSize = 1 << 15; // must be >= (1 << 14) + +class CCoder +{ + CLzOutWindow _outWindow; + NBitm::CDecoder _inBitStream; + // bool FinishMode; + + class CCoderReleaser + { + CCoder *_coder; + public: + CCoderReleaser(CCoder *coder): _coder(coder) {} + void Disable() { _coder = NULL; } + ~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); } + }; + friend class CCoderReleaser; + + HRESULT CodeReal(UInt32 outSize, ICompressProgressInfo *progress); +public: + + // CCoder(): FinishMode(true) {} + UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress); +}; + + +HRESULT CCoder::CodeReal(UInt32 rem, ICompressProgressInfo *progress) +{ + const UInt32 kStep = 1 << 20; + UInt32 next = 0; + if (rem > kStep && progress) + next = rem - kStep; + + while (rem != 0) + { + if (rem <= next) + { + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + const UInt64 packSize = _inBitStream.GetProcessedSize(); + const UInt64 pos = _outWindow.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) + next = 0; + if (rem > kStep) + next = rem - kStep; + } + + UInt32 len; + { + const unsigned kNumBits = 7 + 7; + const UInt32 val = _inBitStream.GetValue(kNumBits); + + if ((val & (1u << (kNumBits - 1))) == 0) + { + _outWindow.PutByte((Byte)(val >> 5)); + _inBitStream.MovePos(1 + 8); + rem--; + continue; + } + + unsigned w; + { + UInt32 flag = (UInt32)1 << (kNumBits - 2); + for (w = 1; w < 7; w++, flag >>= 1) + if ((val & flag) == 0) + break; + } + const unsigned readBits = (w != 7 ? 1 : 0) + w * 2; + const UInt32 mask = ((UInt32)1 << w) - 1; + len = mask + kMatchMinLen - 1 + + ((val >> (kNumBits - readBits)) & mask); + _inBitStream.MovePos(readBits); + } + { + const unsigned kNumBits = 4 + 13; + const UInt32 val = _inBitStream.GetValue(kNumBits); + unsigned readBits = 1; + unsigned w; + if ((val & ((UInt32)1 << 16)) == 0) w = 9; + else if ((val & ((UInt32)1 << 15)) == 0) w = 10; + else if ((val & ((UInt32)1 << 14)) == 0) w = 11; + else if ((val & ((UInt32)1 << 13)) == 0) w = 12; + else { w = 13; readBits = 0; } + + readBits += w + w - 9; + const UInt32 dist = ((UInt32)1 << w) - (1 << 9) + + (((val >> (kNumBits - readBits)) & ((1 << w) - 1))); + _inBitStream.MovePos(readBits); + if (len > rem) + { + // if (FinishMode) + return S_FALSE; + // else len = (UInt32)rem; + } + if (!_outWindow.CopyBlock(dist, len)) + return S_FALSE; + rem -= len; + } + } + + // if (FinishMode) + { + if (_inBitStream.ReadAlignBits() != 0) + return S_FALSE; + } + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + return S_OK; +} + + +HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress) +{ + try + { + if (!_outWindow.Create(kWindowSize)) + return E_OUTOFMEMORY; + if (!_inBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + _outWindow.SetStream(outStream); + _outWindow.Init(false); + _inBitStream.SetStream(inStream); + _inBitStream.Init(); + { + CCoderReleaser coderReleaser(this); + RINOK(CodeReal(outSize, progress)) + coderReleaser.Disable(); + } + return _outWindow.Flush(); + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} + + + + +using namespace NWindows; + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NArj { + +static const unsigned kBlockSizeMin = 30; +static const unsigned kBlockSizeMax = 2600; + +static const Byte kSig0 = 0x60; +static const Byte kSig1 = 0xEA; + +namespace NCompressionMethod +{ + enum + { + kStored = 0, + kCompressed1a = 1, + kCompressed1b = 2, + kCompressed1c = 3, + kCompressed2 = 4, + kNoDataNoCRC = 8, + kNoData = 9 + }; +} + +namespace NFileType +{ + enum + { + kBinary = 0, + k7BitText, + kArchiveHeader, + kDirectory, + kVolumeLablel, + kChapterLabel + }; +} + +namespace NFlags +{ + const Byte kGarbled = 1 << 0; + // const Byte kAnsiPage = 1 << 1; // or (OLD_SECURED_FLAG) obsolete + const Byte kVolume = 1 << 2; + const Byte kExtFile = 1 << 3; + // const Byte kPathSym = 1 << 4; + // const Byte kBackup = 1 << 5; // obsolete + // const Byte kSecured = 1 << 6; + // const Byte kDualName = 1 << 7; +} + +namespace NHostOS +{ + enum EEnum + { + kMSDOS = 0, // MS-DOS, OS/2, Win32, pkarj 2.50 (FAT / VFAT / FAT32) + kPRIMOS, + kUnix, + kAMIGA, + kMac, + kOS_2, + kAPPLE_GS, + kAtari_ST, + kNext, + kVAX_VMS, + kWIN95 + }; +} + +static const char * const kHostOS[] = +{ + "MSDOS" + , "PRIMOS" + , "UNIX" + , "AMIGA" + , "MAC" + , "OS/2" + , "APPLE GS" + , "ATARI ST" + , "NEXT" + , "VAX VMS" + , "WIN95" +}; + +struct CArcHeader +{ + // Byte ArchiverVersion; + // Byte ExtractVersion; + Byte HostOS; + // Byte Flags; + // Byte SecuryVersion; + // Byte FileType; + // Byte Reserved; + UInt32 CTime; + UInt32 MTime; + UInt32 ArchiveSize; + // UInt32 SecurPos; + // UInt16 FilespecPosInFilename; + UInt16 SecurSize; + // Byte EncryptionVersion; + // Byte LastChapter; + AString Name; + AString Comment; + + HRESULT Parse(const Byte *p, unsigned size); +}; + +API_FUNC_static_IsArc IsArc_Arj(const Byte *p, size_t size) +{ + if (size < kBlockSizeMin + 4) + return k_IsArc_Res_NEED_MORE; + if (p[0] != kSig0 || p[1] != kSig1) + return k_IsArc_Res_NO; + UInt32 blockSize = Get16(p + 2); + if (blockSize < kBlockSizeMin || + blockSize > kBlockSizeMax) + return k_IsArc_Res_NO; + + p += 4; + size -= 4; + + Byte headerSize = p[0]; + if (headerSize < kBlockSizeMin || + headerSize > blockSize || + p[6] != NFileType::kArchiveHeader || + p[28] > 8) // EncryptionVersion + return k_IsArc_Res_NO; + + if (blockSize + 4 <= size) + if (Get32(p + blockSize) != CrcCalc(p, blockSize)) + return k_IsArc_Res_NO; + + return k_IsArc_Res_YES; +} +} + +static HRESULT ReadString(const Byte *p, unsigned &size, AString &res) +{ + unsigned num = size; + for (unsigned i = 0; i < num;) + { + if (p[i++] == 0) + { + size = i; + res = (const char *)p; + return S_OK; + } + } + return S_FALSE; +} + +HRESULT CArcHeader::Parse(const Byte *p, unsigned size) +{ + Byte headerSize = p[0]; + if (headerSize < kBlockSizeMin || headerSize > size) + return S_FALSE; + // ArchiverVersion = p[1]; + // ExtractVersion = p[2]; + HostOS = p[3]; + // Flags = p[4]; + // SecuryVersion = p[5]; + if (p[6] != NFileType::kArchiveHeader) + return S_FALSE; + // Reserved = p[7]; + CTime = Get32(p + 8); + MTime = Get32(p + 12); + ArchiveSize = Get32(p + 16); // it can be zero. (currently used only for secured archives) + // SecurPos = Get32(p + 20); + // UInt16 filespecPositionInFilename = Get16(p + 24); + SecurSize = Get16(p + 26); + // EncryptionVersion = p[28]; + // LastChapter = p[29]; + unsigned pos = headerSize; + unsigned size1 = size - pos; + RINOK(ReadString(p + pos, size1, Name)) + pos += size1; + size1 = size - pos; + RINOK(ReadString(p + pos, size1, Comment)) + pos += size1; + return S_OK; +} + + +struct CExtendedInfo +{ + UInt64 Size; + bool CrcError; + + void Clear() + { + Size = 0; + CrcError = false; + } + void ParseToPropVar(NCOM::CPropVariant &prop) const + { + if (Size != 0) + { + AString s; + s += "Extended:"; + s.Add_UInt32((UInt32)Size); + if (CrcError) + s += ":CRC_ERROR"; + prop = s; + } + } +}; + + +struct CItem +{ + AString Name; + AString Comment; + + UInt32 MTime; + UInt32 PackSize; + UInt32 Size; + UInt32 FileCRC; + UInt32 SplitPos; + + Byte Version; + Byte ExtractVersion; + Byte HostOS; + Byte Flags; + Byte Method; + Byte FileType; + + // UInt16 FilespecPosInFilename; + UInt16 FileAccessMode; + // Byte FirstChapter; + // Byte LastChapter; + + UInt64 DataPosition; + + CExtendedInfo ExtendedInfo; + + bool IsEncrypted() const { return (Flags & NFlags::kGarbled) != 0; } + bool IsDir() const { return (FileType == NFileType::kDirectory); } + bool IsSplitAfter() const { return (Flags & NFlags::kVolume) != 0; } + bool IsSplitBefore() const { return (Flags & NFlags::kExtFile) != 0; } + UInt32 GetWinAttrib() const + { + UInt32 atrrib = 0; + switch (HostOS) + { + case NHostOS::kMSDOS: + case NHostOS::kWIN95: + atrrib = FileAccessMode; + break; + } + if (IsDir()) + atrrib |= FILE_ATTRIBUTE_DIRECTORY; + return atrrib; + } + + HRESULT Parse(const Byte *p, unsigned size); +}; + +HRESULT CItem::Parse(const Byte *p, unsigned size) +{ + Byte headerSize = p[0]; + if (headerSize < kBlockSizeMin || headerSize > size) + return S_FALSE; + Version = p[1]; + ExtractVersion = p[2]; + HostOS = p[3]; + Flags = p[4]; + Method = p[5]; + FileType = p[6]; + // Reserved = p[7]; + MTime = Get32(p + 8); + PackSize = Get32(p + 12); + Size = Get32(p + 16); + FileCRC = Get32(p + 20); + // FilespecPosInFilename = Get16(p + 24); + FileAccessMode = Get16(p + 26); + // FirstChapter = p[28]; + // FirstChapter = p[29]; + + SplitPos = 0; + if (IsSplitBefore() && headerSize >= 34) + SplitPos = Get32(p + 30); + + unsigned pos = headerSize; + unsigned size1 = size - pos; + RINOK(ReadString(p + pos, size1, Name)) + pos += size1; + size1 = size - pos; + RINOK(ReadString(p + pos, size1, Comment)) + pos += size1; + + return S_OK; +} + +enum EErrorType +{ + k_ErrorType_OK, + k_ErrorType_Corrupted, + k_ErrorType_UnexpectedEnd +}; + +class CArc +{ +public: + UInt64 Processed; + EErrorType Error; + bool IsArc; + IInStream *Stream; + IArchiveOpenCallback *Callback; + UInt64 NumFiles; + CArcHeader Header; + + CExtendedInfo ExtendedInfo; + + HRESULT Open(); + HRESULT GetNextItem(CItem &item, bool &filled); + void Close() + { + IsArc = false; + Error = k_ErrorType_OK; + ExtendedInfo.Clear(); + } +private: + unsigned _blockSize; + CByteBuffer _block; + + HRESULT ReadBlock(bool &filled, CExtendedInfo *extendedInfo); + HRESULT SkipExtendedHeaders(CExtendedInfo &extendedInfo); + HRESULT Read(void *data, size_t *size); +}; + +HRESULT CArc::Read(void *data, size_t *size) +{ + HRESULT res = ReadStream(Stream, data, size); + Processed += *size; + return res; +} + +#define READ_STREAM(_dest_, _size_) \ + { size_t _processed_ = (_size_); RINOK(Read(_dest_, &_processed_)); \ + if (_processed_ != (_size_)) { Error = k_ErrorType_UnexpectedEnd; return S_OK; } } + +HRESULT CArc::ReadBlock(bool &filled, CExtendedInfo *extendedInfo) +{ + Error = k_ErrorType_OK; + filled = false; + Byte buf[4]; + const unsigned signSize = extendedInfo ? 0 : 2; + READ_STREAM(buf, signSize + 2) + if (!extendedInfo) + if (buf[0] != kSig0 || buf[1] != kSig1) + { + Error = k_ErrorType_Corrupted; + return S_OK; + } + _blockSize = Get16(buf + signSize); + if (_blockSize == 0) // end of archive + return S_OK; + + if (!extendedInfo) + if (_blockSize < kBlockSizeMin || _blockSize > kBlockSizeMax) + { + Error = k_ErrorType_Corrupted; + return S_OK; + } + + const size_t readSize = _blockSize + 4; + if (readSize > _block.Size()) + { + // extended data size is limited by (64 KB) + // _blockSize is less than 64 KB + const size_t upSize = (_blockSize > kBlockSizeMax ? (1 << 16) : kBlockSizeMax); + _block.Alloc(upSize + 4); + } + + if (extendedInfo) + extendedInfo->Size += _blockSize; + + READ_STREAM(_block, readSize) + if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize)) + { + if (extendedInfo) + extendedInfo->CrcError = true; + else + { + Error = k_ErrorType_Corrupted; + return S_OK; + } + } + filled = true; + return S_OK; +} + +HRESULT CArc::SkipExtendedHeaders(CExtendedInfo &extendedInfo) +{ + extendedInfo.Clear(); + for (UInt32 i = 0;; i++) + { + bool filled; + RINOK(ReadBlock(filled, &extendedInfo)) + if (!filled) + return S_OK; + if (Callback && (i & 0xFF) == 0) + RINOK(Callback->SetCompleted(&NumFiles, &Processed)) + } +} + +HRESULT CArc::Open() +{ + bool filled; + RINOK(ReadBlock(filled, NULL)) // (extendedInfo = NULL) + if (!filled) + return S_FALSE; + RINOK(Header.Parse(_block, _blockSize)) + IsArc = true; + return SkipExtendedHeaders(ExtendedInfo); +} + +HRESULT CArc::GetNextItem(CItem &item, bool &filled) +{ + RINOK(ReadBlock(filled, NULL)) // (extendedInfo = NULL) + if (!filled) + return S_OK; + filled = false; + if (item.Parse(_block, _blockSize) != S_OK) + { + Error = k_ErrorType_Corrupted; + return S_OK; + } + /* + UInt32 extraData; + if ((header.Flags & NFlags::kExtFile) != 0) + extraData = GetUi32(_block + pos); + */ + + RINOK(SkipExtendedHeaders(item.ExtendedInfo)) + filled = true; + return S_OK; +} + + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CObjectVector _items; + CMyComPtr _stream; + UInt64 _phySize; + CArc _arc; + + HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback); +}; + +static const Byte kArcProps[] = +{ + kpidName, + kpidCTime, + kpidMTime, + kpidHostOS, + kpidComment, + kpidCharacts +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPosition, + kpidPackSize, + kpidMTime, + kpidAttrib, + kpidEncrypted, + kpidCRC, + kpidMethod, + kpidHostOS, + kpidComment, + kpidCharacts +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void SetTime(UInt32 dosTime, NCOM::CPropVariant &prop) +{ + if (dosTime == 0) + return; + PropVariant_SetFrom_DosTime(prop, dosTime); +} + +static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop) +{ + TYPE_TO_PROP(kHostOS, hostOS, prop); +} + +static void SetUnicodeString(const AString &s, NCOM::CPropVariant &prop) +{ + if (!s.IsEmpty()) + prop = MultiByteToUnicodeString(s, CP_OEMCP); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _phySize; break; + case kpidName: SetUnicodeString(_arc.Header.Name, prop); break; + case kpidCTime: SetTime(_arc.Header.CTime, prop); break; + case kpidMTime: SetTime(_arc.Header.MTime, prop); break; + case kpidHostOS: SetHostOS(_arc.Header.HostOS, prop); break; + case kpidComment: SetUnicodeString(_arc.Header.Comment, prop); break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_arc.IsArc) v |= kpv_ErrorFlags_IsNotArc; + switch (_arc.Error) + { + case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; + case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; + case k_ErrorType_OK: + // default: + break; + } + prop = v; + break; + } + case kpidCharacts: _arc.ExtendedInfo.ParseToPropVar(prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CItem &item = _items[index]; + switch (propID) + { + case kpidPath: prop = NItemName::GetOsPath(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidPosition: if (item.IsSplitBefore() || item.IsSplitAfter()) prop = (UInt64)item.SplitPos; break; + case kpidAttrib: prop = item.GetWinAttrib(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidCRC: prop = item.FileCRC; break; + case kpidMethod: prop = item.Method; break; + case kpidHostOS: SetHostOS(item.HostOS, prop); break; + case kpidMTime: SetTime(item.MTime, prop); break; + case kpidComment: SetUnicodeString(item.Comment, prop); break; + case kpidCharacts: item.ExtendedInfo.ParseToPropVar(prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *inStream, IArchiveOpenCallback *callback) +{ + Close(); + + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(inStream, endPos)) + + _arc.Stream = inStream; + _arc.Callback = callback; + _arc.NumFiles = 0; + _arc.Processed = 0; + + RINOK(_arc.Open()) + + _phySize = _arc.Processed; + if (_arc.Header.ArchiveSize != 0) + _phySize = (UInt64)_arc.Header.ArchiveSize + _arc.Header.SecurSize; + + for (;;) + { + CItem item; + bool filled; + + _arc.Error = k_ErrorType_OK; + RINOK(_arc.GetNextItem(item, filled)) + + if (_arc.Error != k_ErrorType_OK) + break; + + if (!filled) + { + if (_arc.Error == k_ErrorType_OK) + if (_arc.Header.ArchiveSize == 0) + _phySize = _arc.Processed; + break; + } + item.DataPosition = _arc.Processed; + _items.Add(item); + + UInt64 pos = item.DataPosition + item.PackSize; + if (_arc.Header.ArchiveSize == 0) + _phySize = pos; + if (pos > endPos) + { + _arc.Error = k_ErrorType_UnexpectedEnd; + break; + } + + RINOK(InStream_SeekSet(inStream, pos)) + _arc.NumFiles = _items.Size(); + _arc.Processed = pos; + + if (callback && (_items.Size() & 0xFF) == 0) + { + RINOK(callback->SetCompleted(&_arc.NumFiles, &_arc.Processed)) + } + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + HRESULT res; + { + res = Open2(inStream, callback); + if (res == S_OK) + { + _stream = inStream; + return S_OK; + } + } + return res; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _arc.Close(); + _phySize = 0; + _items.Clear(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + UInt64 totalUnpacked = 0, totalPacked = 0; + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _items.Size(); + if (numItems == 0) + return S_OK; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CItem &item = _items[allFilesMode ? i : indices[i]]; + totalUnpacked += item.Size; + // totalPacked += item.PackSize; + } + RINOK(extractCallback->SetTotal(totalUnpacked)) + + totalUnpacked = totalPacked = 0; + UInt32 curUnpacked, curPacked; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyUniquePtr lzhDecoder; + CMyUniquePtr arjDecoder; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++, + totalUnpacked += curUnpacked, + totalPacked += curPacked) + { + lps->InSize = totalPacked; + lps->OutSize = totalUnpacked; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + curUnpacked = curPacked = 0; + + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + // realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + continue; + } + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + curUnpacked = item.Size; + curPacked = item.PackSize; + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + // realOutStream.Release(); + outStream->Init(); + + inStream->Init(item.PackSize); + + RINOK(InStream_SeekSet(_stream, item.DataPosition)) + + HRESULT result = S_OK; + opRes = NExtract::NOperationResult::kOK; + + if (item.IsEncrypted()) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + { + switch (item.Method) + { + case NCompressionMethod::kStored: + { + result = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + if (result == S_OK && copyCoder->TotalSize != item.PackSize) + result = S_FALSE; + break; + } + case NCompressionMethod::kCompressed1a: + case NCompressionMethod::kCompressed1b: + case NCompressionMethod::kCompressed1c: + { + lzhDecoder.Create_if_Empty(); + // lzhDecoder->FinishMode = true; + const UInt32 kHistorySize = 26624; + lzhDecoder->SetDictSize(kHistorySize); + result = lzhDecoder->Code(inStream, outStream, curUnpacked, lps); + if (result == S_OK && lzhDecoder->GetInputProcessedSize() != item.PackSize) + result = S_FALSE; + break; + } + case NCompressionMethod::kCompressed2: + { + arjDecoder.Create_if_Empty(); + // arjDecoderSpec->FinishMode = true; + result = arjDecoder->Code(inStream, outStream, curUnpacked, lps); + if (result == S_OK && arjDecoder->GetInputProcessedSize() != item.PackSize) + result = S_FALSE; + break; + } + default: + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + } + + if (opRes == NExtract::NOperationResult::kOK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(result) + opRes = (outStream->GetCRC() == item.FileCRC) ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError; + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + +static const Byte k_Signature[] = { kSig0, kSig1 }; + +REGISTER_ARC_I( + "Arj", "arj", NULL, 4, + k_Signature, + 0, + 0, + IsArc_Arj) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/AvbHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/AvbHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/AvbHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/AvbHandler.cpp 2023-03-27 17:00:00.000000000 +0000 @@ -0,0 +1,596 @@ +// AvbHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +#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 NAvb { + +static void AddNameToString(AString &s, const Byte *name, unsigned size, bool strictConvert) +{ + for (unsigned i = 0; i < size; i++) + { + Byte c = name[i]; + if (c == 0) + return; + if (strictConvert && c < 32) + c = '_'; + s += (char)c; + } +} + +/* Maximum size of a vbmeta image - 64 KiB. */ +#define VBMETA_MAX_SIZE (64 * 1024) + +#define SIGNATURE { 'A', 'V', 'B', 'f', 0, 0, 0, 1 } + +static const unsigned k_SignatureSize = 8; +static const Byte k_Signature[k_SignatureSize] = SIGNATURE; + +// #define AVB_FOOTER_MAGIC "AVBf" +// #define AVB_FOOTER_MAGIC_LEN 4 +/* The current footer version used - keep in sync with avbtool. */ +#define AVB_FOOTER_VERSION_MAJOR 1 + +/* The struct used as a footer used on partitions, used to find the + * AvbVBMetaImageHeader struct. This struct is always stored at the + * end of a partition. + */ +// #define AVB_FOOTER_SIZE 64 +static const unsigned kFooterSize = 64; + +struct CFooter +{ + /* 0: Four bytes equal to "AVBf" (AVB_FOOTER_MAGIC). */ + // Byte magic[AVB_FOOTER_MAGIC_LEN]; + /* 4: The major version of the footer struct. */ + UInt32 version_major; + /* 8: The minor version of the footer struct. */ + UInt32 version_minor; + + /* 12: The original size of the image on the partition. */ + UInt64 original_image_size; + + /* 20: The offset of the |AvbVBMetaImageHeader| struct. */ + UInt64 vbmeta_offset; + + /* 28: The size of the vbmeta block (header + auth + aux blocks). */ + UInt64 vbmeta_size; + + /* 36: Padding to ensure struct is size AVB_FOOTER_SIZE bytes. This + * must be set to zeroes. + */ + Byte reserved[28]; + + void Parse(const Byte *p) + { + G32 (4, version_major); + G32 (8, version_minor); + G64 (12, original_image_size); + G64 (20, vbmeta_offset); + G64 (28, vbmeta_size); + } +}; + + +/* Size of the vbmeta image header. */ +#define AVB_VBMETA_IMAGE_HEADER_SIZE 256 + +/* Magic for the vbmeta image header. */ +// #define AVB_MAGIC "AVB0" +// #define AVB_MAGIC_LEN 4 +/* Maximum size of the release string including the terminating NUL byte. */ +#define AVB_RELEASE_STRING_SIZE 48 + +struct AvbVBMetaImageHeader +{ + /* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */ + // Byte magic[AVB_MAGIC_LEN]; + + /* 4: The major version of libavb required for this header. */ + UInt32 required_libavb_version_major; + /* 8: The minor version of libavb required for this header. */ + UInt32 required_libavb_version_minor; + + /* 12: The size of the signature block. */ + UInt64 authentication_data_block_size; + /* 20: The size of the auxiliary data block. */ + UInt64 auxiliary_data_block_size; + + /* 28: The verification algorithm used, see |AvbAlgorithmType| enum. */ + UInt32 algorithm_type; + + /* 32: Offset into the "Authentication data" block of hash data. */ + UInt64 hash_offset; + /* 40: Length of the hash data. */ + UInt64 hash_size; + + /* 48: Offset into the "Authentication data" block of signature data. */ + UInt64 signature_offset; + /* 56: Length of the signature data. */ + UInt64 signature_size; + + /* 64: Offset into the "Auxiliary data" block of public key data. */ + UInt64 public_key_offset; + /* 72: Length of the public key data. */ + UInt64 public_key_size; + + /* 80: Offset into the "Auxiliary data" block of public key metadata. */ + UInt64 public_key_metadata_offset; + /* 88: Length of the public key metadata. Must be set to zero if there + * is no public key metadata. + */ + UInt64 public_key_metadata_size; + + /* 96: Offset into the "Auxiliary data" block of descriptor data. */ + UInt64 descriptors_offset; + /* 104: Length of descriptor data. */ + UInt64 descriptors_size; + + /* 112: The rollback index which can be used to prevent rollback to + * older versions. + */ + UInt64 rollback_index; + + /* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be + * set to zero if the vbmeta image is not a top-level image. + */ + UInt32 flags; + + /* 124: The location of the rollback index defined in this header. + * Only valid for the main vbmeta. For chained partitions, the rollback + * index location must be specified in the AvbChainPartitionDescriptor + * and this value must be set to 0. + */ + UInt32 rollback_index_location; + + /* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or + * "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL + * terminated. Applications must not make assumptions about how this + * string is formatted. + */ + Byte release_string[AVB_RELEASE_STRING_SIZE]; + + /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE + * bytes. This must be set to zeroes. + */ + // Byte reserved[80]; + bool Parse(const Byte *p); +}; + +bool AvbVBMetaImageHeader::Parse(const Byte *p) +{ + // Byte magic[AVB_MAGIC_LEN]; + if (Get32(p) != 0x41564230) // "AVB0" + return false; + G32 (4, required_libavb_version_major); + if (required_libavb_version_major != AVB_FOOTER_VERSION_MAJOR) // "AVB0" + return false; + G32 (8, required_libavb_version_minor); + G64 (12, authentication_data_block_size); + G64 (20, auxiliary_data_block_size); + G32 (28, algorithm_type); + G64 (32, hash_offset); + G64 (40, hash_size); + G64 (48, signature_offset); + G64 (56, signature_size); + G64 (64, public_key_offset); + G64 (72, public_key_size); + G64 (80, public_key_metadata_offset); + G64 (88, public_key_metadata_size); + G64 (96, descriptors_offset); + G64 (104, descriptors_size); + G64 (112, rollback_index); + G32 (120, flags); + G32 (124, rollback_index_location); + memcpy(release_string, p + 128, AVB_RELEASE_STRING_SIZE); + + /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE + * bytes. This must be set to zeroes. + */ + // Byte reserved[80]; + return true; +} + + +static const unsigned k_Descriptor_Size = 16; + +enum AvbDescriptorTag +{ + AVB_DESCRIPTOR_TAG_PROPERTY, + AVB_DESCRIPTOR_TAG_HASHTREE, + AVB_DESCRIPTOR_TAG_HASH, + AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE, + AVB_DESCRIPTOR_TAG_CHAIN_PARTITION +}; + +struct AvbDescriptor +{ + UInt64 Tag; + UInt64 Size; + + void Parse(const Byte *p) + { + G64 (0, Tag); + G64 (8, Size); + } +}; + + +enum AvbHashtreeDescriptorFlags +{ + AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB = (1 << 0), + AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE = (1 << 1) +}; + +/* A descriptor containing information about a dm-verity hashtree. + * + * Hash-trees are used to verify large partitions typically containing + * file systems. See + * https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity for more + * information about dm-verity. + * + * Following this struct are |partition_name_len| bytes of the + * partition name (UTF-8 encoded), |salt_len| bytes of salt, and then + * |root_digest_len| bytes of the root digest. + * + * The |reserved| field is for future expansion and must be set to NUL + * bytes. + * + * Changes in v1.1: + * - flags field is added which supports AVB_HASHTREE_DESCRIPTOR_FLAGS_USE_AB + * - digest_len may be zero, which indicates the use of a persistent digest + */ + +static const unsigned k_Hashtree_Size_Min = 164; + +struct AvbHashtreeDescriptor +{ + UInt32 dm_verity_version; + UInt64 image_size; + UInt64 tree_offset; + UInt64 tree_size; + UInt32 data_block_size; + UInt32 hash_block_size; + UInt32 fec_num_roots; + UInt64 fec_offset; + UInt64 fec_size; + Byte hash_algorithm[32]; + UInt32 partition_name_len; + UInt32 salt_len; + UInt32 root_digest_len; + UInt32 flags; + Byte reserved[60]; + void Parse(const Byte *p) + { + G32 (0, dm_verity_version); + G64 (4, image_size); + G64 (12, tree_offset); + G64 (20, tree_size); + G32 (28, data_block_size); + G32 (32, hash_block_size); + G32 (36, fec_num_roots); + G64 (40, fec_offset); + G64 (48, fec_size); + memcpy(hash_algorithm, p + 56, 32); + G32 (88, partition_name_len); + G32 (92, salt_len); + G32 (96, root_digest_len); + G32 (100, flags); + } +}; + +static const unsigned k_PropertyDescriptor_Size_Min = 16; + +struct AvbPropertyDescriptor +{ + UInt64 key_num_bytes; + UInt64 value_num_bytes; + + void Parse(const Byte *p) + { + G64 (0, key_num_bytes); + G64 (8, value_num_bytes); + } +}; + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + // UInt64 _startOffset; + UInt64 _phySize; + + CFooter Footer; + AString Name; + const char *Ext; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + if (index != 0) + return NExtract::NOperationResult::kUnavailable; + // pos = _startOffset; + pos = 0; + size = Footer.original_image_size; + return NExtract::NOperationResult::kOK; + } +}; + + +HRESULT CHandler::Open2(IInStream *stream) +{ + UInt64 fileSize; + { + Byte buf[kFooterSize]; + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) + if (fileSize < kFooterSize) + return S_FALSE; + RINOK(InStream_SeekSet(stream, fileSize - kFooterSize)) + RINOK(ReadStream_FALSE(stream, buf, kFooterSize)) + if (memcmp(buf, k_Signature, k_SignatureSize) != 0) + return S_FALSE; + Footer.Parse(buf); + if (Footer.vbmeta_size > VBMETA_MAX_SIZE || + Footer.vbmeta_size < AVB_VBMETA_IMAGE_HEADER_SIZE) + return S_FALSE; + for (unsigned i = 36; i < kFooterSize; i++) + if (buf[i] != 0) + return S_FALSE; + } + { + CByteBuffer buf; + buf.Alloc((size_t)Footer.vbmeta_size); + RINOK(InStream_SeekSet(stream, Footer.vbmeta_offset)) + RINOK(ReadStream_FALSE(stream, buf, (size_t)Footer.vbmeta_size)) + + AvbVBMetaImageHeader meta; + if (!meta.Parse(buf)) + return S_FALSE; + + unsigned offset = (unsigned)AVB_VBMETA_IMAGE_HEADER_SIZE; + unsigned rem = (unsigned)(Footer.vbmeta_size - offset); + + if (meta.authentication_data_block_size != 0) + { + if (rem < meta.authentication_data_block_size) + return S_FALSE; + const unsigned u = (unsigned)meta.authentication_data_block_size; + offset += u; + rem -= u; + } + + if (rem < meta.descriptors_offset || + rem - meta.descriptors_offset < meta.descriptors_size) + return S_FALSE; + rem = (unsigned)meta.descriptors_size; + while (rem != 0) + { + if (rem < k_Descriptor_Size) + return S_FALSE; + AvbDescriptor desc; + desc.Parse(buf + offset); + offset += k_Descriptor_Size; + rem -= k_Descriptor_Size; + if (desc.Size > rem) + return S_FALSE; + const unsigned descSize = (unsigned)desc.Size; + if (desc.Tag == AVB_DESCRIPTOR_TAG_HASHTREE) + { + if (descSize < k_Hashtree_Size_Min) + return S_FALSE; + AvbHashtreeDescriptor ht; + ht.Parse(buf + offset); + unsigned pos = k_Hashtree_Size_Min; + + if (pos + ht.partition_name_len > descSize) + return S_FALSE; + Name.Empty(); // UTF-8 + AddNameToString(Name, buf + offset + pos, ht.partition_name_len, false); + pos += ht.partition_name_len; + + if (pos + ht.salt_len > descSize) + return S_FALSE; + CByteBuffer salt; + salt.CopyFrom(buf + offset + pos, ht.salt_len); + pos += ht.salt_len; + + if (pos + ht.root_digest_len > descSize) + return S_FALSE; + CByteBuffer digest; + digest.CopyFrom(buf + offset + pos, ht.root_digest_len); + pos += ht.root_digest_len; + // what is that digest? + } + else if (desc.Tag == AVB_DESCRIPTOR_TAG_PROPERTY) + { + if (descSize < k_PropertyDescriptor_Size_Min + 2) + return S_FALSE; + AvbPropertyDescriptor pt; + pt.Parse(buf + offset); + unsigned pos = k_PropertyDescriptor_Size_Min; + + if (pt.key_num_bytes > descSize - pos - 1) + return S_FALSE; + AString key; // UTF-8 + AddNameToString(key, buf + offset + pos, (unsigned)pt.key_num_bytes, false); + pos += (unsigned)pt.key_num_bytes + 1; + + if (descSize < pos) + return S_FALSE; + if (pt.value_num_bytes > descSize - pos - 1) + return S_FALSE; + AString value; // UTF-8 + AddNameToString(value, buf + offset + pos, (unsigned)pt.value_num_bytes, false); + pos += (unsigned)pt.value_num_bytes + 1; + } + offset += descSize; + rem -= descSize; + } + + _phySize = fileSize; + + // _startOffset = 0; + return S_OK; + } +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + try + { + if (Open2(stream) != S_OK) + return S_FALSE; + _stream = stream; + + { + CMyComPtr parseStream; + if (GetStream(0, &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 == Footer.original_image_size) + Ext = "ext"; + } + } + } + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _stream.Release(); + // _startOffset = 0; + _phySize = 0; + Ext = NULL; + Name.Empty(); + return S_OK; +} + + +static const Byte kArcProps[] = +{ + kpidName +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidPhySize: prop = _phySize; break; + case kpidName: + { + if (!Name.IsEmpty()) + { + AString s (Name); + s += ".avb"; + prop = s; + } + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidPath: + { + if (!Name.IsEmpty()) + { + AString s (Name); + s += '.'; + s += Ext ? Ext : "img"; + prop = s; + } + break; + } + case kpidPackSize: + case kpidSize: + prop = Footer.original_image_size; + break; + case kpidExtension: prop = (Ext ? Ext : "img"); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + + +REGISTER_ARC_I_NO_SIG( + "AVB", "avb img", NULL, 0xc0, + /* k_Signature, */ + 0, + /* NArcInfoFlags::kUseGlobalOffset | */ + NArcInfoFlags::kBackwardOpen + , + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Base64Handler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Base64Handler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Base64Handler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Base64Handler.cpp 2023-12-11 09:00:00.000000000 +0000 @@ -0,0 +1,488 @@ +// Base64Handler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyVector.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" +#include "../Common/InBuffer.h" + +/* +spaces: + 9(TAB),10(LF),13(CR),32(SPACE) + Non-breaking space: + 0xa0 : Unicode, Windows code pages 1250-1258 + 0xff (unused): DOS code pages + +end of stream markers: '=' (0x3d): + "=" , if numBytes (% 3 == 2) + "==" , if numBytes (% 3 == 1) +*/ + + +static const Byte k_Base64Table[256] = +{ + 66,77,77,77,77,77,77,77,77,65,65,77,77,65,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63, + 52,53,54,55,56,57,58,59,60,61,77,77,77,64,77,77, + 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77, + 77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 65,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, + 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77 +}; + +static const unsigned k_Code_Equals = 64; +static const unsigned k_Code_Space = 65; +static const unsigned k_Code_Zero = 66; + +API_FUNC_static_IsArc IsArc_Base64(const Byte *p, size_t size) +{ + size_t num = 0; + size_t firstSpace = 0; + + for (;;) + { + if (size == 0) + return k_IsArc_Res_NEED_MORE; + UInt32 c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c < 64) + { + num++; + continue; + } + + if (c == k_Code_Space) + { + if (p[-1] == ' ' && firstSpace == 0) + firstSpace = num; + continue; + } + + if (c != k_Code_Equals) + return k_IsArc_Res_NO; + break; + } + + { + // we try to redece false positive detection here. + // we don't expect space character in starting base64 line + const unsigned kNumExpectedNonSpaceSyms = 20; + if (firstSpace != 0 && firstSpace < num && firstSpace < kNumExpectedNonSpaceSyms) + return k_IsArc_Res_NO; + } + + num &= 3; + + if (num <= 1) + return k_IsArc_Res_NO; + if (num != 3) + { + if (size == 0) + return k_IsArc_Res_NEED_MORE; + UInt32 c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c != k_Code_Equals) + return k_IsArc_Res_NO; + } + + for (;;) + { + if (size == 0) + return k_IsArc_Res_YES; + UInt32 c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c == k_Code_Space) + continue; + return k_IsArc_Res_NO; + } +} +} + + +enum EBase64Res +{ + k_Base64_RES_MaybeFinished, + k_Base64_RES_Finished, + k_Base64_RES_NeedMoreInput, + k_Base64_RES_UnexpectedChar +}; + + +static EBase64Res Base64ToBin(Byte *p, size_t size, const Byte **srcEnd, Byte **destEnd) +{ + Byte *dest = p; + UInt32 val = 1; + EBase64Res res = k_Base64_RES_NeedMoreInput; + + for (;;) + { + if (size == 0) + { + if (val == 1) + res = k_Base64_RES_MaybeFinished; + break; + } + UInt32 c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c < 64) + { + val = (val << 6) | c; + if ((val & ((UInt32)1 << 24)) == 0) + continue; + dest[0] = (Byte)(val >> 16); + dest[1] = (Byte)(val >> 8); + dest[2] = (Byte)(val); + dest += 3; + val = 1; + continue; + } + + if (c == k_Code_Space) + continue; + + if (c == k_Code_Equals) + { + if (val >= (1 << 12)) + { + if (val & (1 << 18)) + { + res = k_Base64_RES_Finished; + break; + } + if (size == 0) + break; + c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c == k_Code_Equals) + { + res = k_Base64_RES_Finished; + break; + } + } + } + + p--; + res = k_Base64_RES_UnexpectedChar; + break; + } + + if (val >= ((UInt32)1 << 12)) + { + if (val & (1 << 18)) + { + *dest++ = (Byte)(val >> 10); + val <<= 2; + } + *dest++ = (Byte)(val >> 4); + } + + *srcEnd = p; + *destEnd = dest; + return res; +} + + +static const Byte *Base64_SkipSpaces(const Byte *p, size_t size) +{ + for (;;) + { + if (size == 0) + return p; + const UInt32 c = k_Base64Table[(Byte)(*p++)]; + size--; + if (c == k_Code_Space) + continue; + return p - 1; + } +} + + +// the following function is used by DmgHandler.cpp + +Byte *Base64ToBin(Byte *dest, const char *src); +Byte *Base64ToBin(Byte *dest, const char *src) +{ + UInt32 val = 1; + + for (;;) + { + const UInt32 c = k_Base64Table[(Byte)(*src++)]; + + if (c < 64) + { + val = (val << 6) | c; + if ((val & ((UInt32)1 << 24)) == 0) + continue; + dest[0] = (Byte)(val >> 16); + dest[1] = (Byte)(val >> 8); + dest[2] = (Byte)(val); + dest += 3; + val = 1; + continue; + } + + if (c == k_Code_Space) + continue; + + if (c == k_Code_Equals) + break; + + if (c == k_Code_Zero && val == 1) // end of string + return dest; + + return NULL; + } + + if (val < (1 << 12)) + return NULL; + + if (val & (1 << 18)) + { + *dest++ = (Byte)(val >> 10); + val <<= 2; + } + else if (k_Base64Table[(Byte)(*src++)] != k_Code_Equals) + return NULL; + *dest++ = (Byte)(val >> 4); + + for (;;) + { + const Byte c = k_Base64Table[(Byte)(*src++)]; + if (c == k_Code_Space) + continue; + if (c == k_Code_Zero) + return dest; + return NULL; + } +} + + +namespace NArchive { +namespace NBase64 { + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + bool _isArc; + UInt64 _phySize; + size_t _size; + EBase64Res _sres; + CByteBuffer _data; +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_sres == k_Base64_RES_NeedMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (v != 0) + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidSize: prop = (UInt64)_size; break; + case kpidPackSize: prop = _phySize; break; + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + + +static HRESULT ReadStream_OpenProgress(ISequentialInStream *stream, void *data, size_t size, IArchiveOpenCallback *openCallback) throw() +{ + UInt64 bytes = 0; + while (size != 0) + { + const UInt32 kBlockSize = ((UInt32)1 << 24); + const UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + RINOK(stream->Read(data, curSize, &processedSizeLoc)) + if (processedSizeLoc == 0) + return E_FAIL; + data = (void *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + bytes += processedSizeLoc; + const UInt64 files = 1; + RINOK(openCallback->SetCompleted(&files, &bytes)) + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + { + Close(); + { + const unsigned kStartSize = 1 << 12; + _data.Alloc(kStartSize); + size_t size = kStartSize; + RINOK(ReadStream(stream, _data, &size)) + if (IsArc_Base64(_data, size) == k_IsArc_Res_NO) + return S_FALSE; + } + _isArc = true; + + UInt64 packSize64; + RINOK(InStream_GetSize_SeekToEnd(stream, packSize64)) + if (packSize64 == 0) + return S_FALSE; + size_t curSize = 1 << 16; + if (curSize > packSize64) + curSize = (size_t)packSize64; + const unsigned kLogStep = 4; + + for (;;) + { + RINOK(InStream_SeekSet(stream, 0)) + + _data.Alloc(curSize); + RINOK(ReadStream_OpenProgress(stream, _data, curSize, openCallback)) + + const Byte *srcEnd; + Byte *dest; + _sres = Base64ToBin(_data, curSize, &srcEnd, &dest); + _size = (size_t)(dest - _data); + const size_t mainSize = (size_t)(srcEnd - _data); + _phySize = mainSize; + if (_sres == k_Base64_RES_UnexpectedChar) + break; + if (curSize != mainSize) + { + const Byte *end2 = Base64_SkipSpaces(srcEnd, curSize - mainSize); + if ((size_t)(end2 - _data) != curSize) + break; + _phySize = curSize; + } + + if (curSize == packSize64) + break; + + UInt64 curSize64 = packSize64; + if (curSize < (packSize64 >> kLogStep)) + curSize64 = (UInt64)curSize << kLogStep; + curSize = (size_t)curSize64; + if (curSize != curSize64) + return E_OUTOFMEMORY; + } + if (_size == 0) + return S_FALSE; + return S_OK; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + _size = 0; + _isArc = false; + _sres = k_Base64_RES_MaybeFinished; + _data.Free(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + RINOK(extractCallback->SetTotal(_size)) + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + // RINOK(lps->SetCur()) + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + RINOK(extractCallback->PrepareOperation(askMode)) + if (realOutStream) + { + RINOK(WriteStream(realOutStream, (const Byte *)_data, _size)) + } + opRes = NExtract::NOperationResult::kOK; + if (_sres != k_Base64_RES_Finished) + { + if (_sres == k_Base64_RES_NeedMoreInput) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else if (_sres == k_Base64_RES_UnexpectedChar) + opRes = NExtract::NOperationResult::kDataError; + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + lps->InSize = _phySize; + lps->OutSize = _size; + return lps->SetCur(); + COM_TRY_END +} + +REGISTER_ARC_I_NO_SIG( + "Base64", "b64", NULL, 0xC5, + 0, + NArcInfoFlags::kKeepName + | NArcInfoFlags::kStartOpen + | NArcInfoFlags::kByExtOnlyOpen, + IsArc_Base64) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Bz2Handler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Bz2Handler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Bz2Handler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Bz2Handler.cpp 2025-07-02 12:00:00.000000000 +0000 @@ -1,443 +1,482 @@ -// Bz2Handler.cpp - -#include "StdAfx.h" - -#include "../../Common/ComTry.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/BZip2Decoder.h" -#include "../Compress/BZip2Encoder.h" -#include "../Compress/CopyCoder.h" - -#include "Common/DummyOutStream.h" -#include "Common/HandlerOut.h" - -using namespace NWindows; - -namespace NArchive { -namespace NBz2 { - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ - CMyComPtr _stream; - CMyComPtr _seqStream; - - bool _isArc; - bool _needSeekToStart; - bool _dataAfterEnd; - bool _needMoreInput; - - bool _packSize_Defined; - bool _unpackSize_Defined; - bool _numStreams_Defined; - bool _numBlocks_Defined; - - UInt64 _packSize; - UInt64 _unpackSize; - UInt64 _numStreams; - UInt64 _numBlocks; - - CSingleMethodProps _props; - -public: - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveOpenSeq, - IOutArchive, - ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - CHandler() { } -}; - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize -}; - -static const Byte kArcProps[] = -{ - kpidNumStreams, - kpidNumBlocks -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; - case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; - case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; - case kpidNumBlocks: if (_numBlocks_Defined) prop = _numBlocks; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - prop = v; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; - case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break; - } - prop.Detach(value); - return S_OK; -} - -static const unsigned kSignatureCheckSize = 10; - -API_FUNC_static_IsArc IsArc_BZip2(const Byte *p, size_t size) -{ - if (size < kSignatureCheckSize) - return k_IsArc_Res_NEED_MORE; - if (p[0] != 'B' || p[1] != 'Z' || p[2] != 'h' || p[3] < '1' || p[3] > '9') - return k_IsArc_Res_NO; - p += 4; - if (NCompress::NBZip2::IsBlockSig(p)) - return k_IsArc_Res_YES; - if (NCompress::NBZip2::IsEndSig(p)) - return k_IsArc_Res_YES; - return k_IsArc_Res_NO; -} -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - COM_TRY_BEGIN - Close(); - { - Byte buf[kSignatureCheckSize]; - RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize)); - if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO) - return S_FALSE; - _isArc = true; - _stream = stream; - _seqStream = stream; - _needSeekToStart = true; - } - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - Close(); - _isArc = true; - _seqStream = stream; - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _needSeekToStart = false; - _dataAfterEnd = false; - _needMoreInput = false; - - _packSize_Defined = false; - _unpackSize_Defined = false; - _numStreams_Defined = false; - _numBlocks_Defined = false; - - _packSize = 0; - - _seqStream.Release(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - if (_packSize_Defined) - extractCallback->SetTotal(_packSize); - - // RINOK(extractCallback->SetCompleted(&packSize)); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - - if (_needSeekToStart) - { - if (!_stream) - return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - else - _needSeekToStart = true; - - Int32 opRes; - - try - { - - NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder; - CMyComPtr decoder = decoderSpec; - decoderSpec->SetInStream(_seqStream); - - #ifndef _7ZIP_ST - RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads)); - #endif - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, true); - - UInt64 packSize = 0; - UInt64 unpackedSize = 0; - UInt64 numStreams = 0; - - decoderSpec->InitNumBlocks(); - - HRESULT result = S_OK; - - for (;;) - { - lps->InSize = packSize; - lps->OutSize = unpackedSize; - - RINOK(lps->SetCur()); - - result = decoderSpec->CodeResume(outStream, progress); - - if (result != S_FALSE && result != S_OK) - return result; - - if (decoderSpec->IsBz) - numStreams++; - else if (numStreams == 0) - { - _isArc = false; - result = S_FALSE; - break; - } - - unpackedSize = outStreamSpec->GetSize(); - UInt64 streamSize = decoderSpec->GetStreamSize(); - - if (streamSize == packSize) - { - // no new bytes in input stream, So it's good end of archive. - result = S_OK; - break; - } - - if (!decoderSpec->IsBz) - { - _dataAfterEnd = true; - result = S_FALSE; - break; - } - - if (decoderSpec->Base.BitDecoder.ExtraBitsWereRead()) - { - _needMoreInput = true; - packSize = streamSize; - result = S_FALSE; - break; - } - - packSize = decoderSpec->GetInputProcessedSize(); - - if (packSize > streamSize) - return E_FAIL; - - if (result != S_OK) - break; - } - - if (numStreams != 0) - { - _packSize = packSize; - _unpackSize = unpackedSize; - _numStreams = numStreams; - _numBlocks = decoderSpec->GetNumBlocks(); - - _packSize_Defined = true; - _unpackSize_Defined = true; - _numStreams_Defined = true; - _numBlocks_Defined = true; - } - - decoderSpec->ReleaseInStream(); - outStream.Release(); - - if (!_isArc) - opRes = NExtract::NOperationResult::kIsNotArc; - else if (_needMoreInput) - opRes = NExtract::NOperationResult::kUnexpectedEnd; - else if (decoderSpec->CrcError) - opRes = NExtract::NOperationResult::kCRCError; - else if (_dataAfterEnd) - opRes = NExtract::NOperationResult::kDataAfterEnd; - else if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else if (result == S_OK) - opRes = NExtract::NOperationResult::kOK; - else - return result; - - } - catch(const CInBufferException &e) { return e.ErrorCode; } - - return extractCallback->SetOperationResult(opRes); - - COM_TRY_END -} - -static HRESULT UpdateArchive( - UInt64 unpackSize, - ISequentialOutStream *outStream, - const CProps &props, - IArchiveUpdateCallback *updateCallback) -{ - 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)); - return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); -} - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kUnix; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - - if (numItems != 1) - return E_INVALIDARG; - - Int32 newData, newProps; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); - - if (IntToBool(newProps)) - { - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); - if (prop.vt != VT_EMPTY) - if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) - return E_INVALIDARG; - } - } - - if (IntToBool(newData)) - { - UInt64 size; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - } - return UpdateArchive(size, outStream, _props, updateCallback); - } - - if (indexInArchive != 0) - return E_INVALIDARG; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, 0, - NUpdateNotifyOp::kReplicate)) - } - - if (_stream) - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - - return NCompress::CopyStream(_stream, outStream, progress); - - COM_TRY_END -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - return _props.SetProperties(names, values, numProps); -} - -static const Byte k_Signature[] = { 'B', 'Z', 'h' }; - -REGISTER_ARC_IO( - "bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2, - k_Signature, - 0, - NArcInfoFlags::kKeepName, - IsArc_BZip2) - -}} +// Bz2Handler.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/BZip2Decoder.h" +#include "../Compress/BZip2Encoder.h" +#include "../Compress/CopyCoder.h" + +#include "Common/DummyOutStream.h" +#include "Common/HandlerOut.h" + +using namespace NWindows; + +namespace NArchive { +namespace NBz2 { + +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveOpenSeq, + IOutArchive, + ISetProperties +) + CMyComPtr _stream; + CMyComPtr _seqStream; + + bool _isArc; + bool _needSeekToStart; + bool _dataAfterEnd; + bool _needMoreInput; + + bool _packSize_Defined; + bool _unpackSize_Defined; + bool _numStreams_Defined; + bool _numBlocks_Defined; + + UInt64 _packSize; + UInt64 _unpackSize; + UInt64 _numStreams; + UInt64 _numBlocks; + + CSingleMethodProps _props; +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidNumStreams, + kpidNumBlocks +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; + case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; + case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; + case kpidNumBlocks: if (_numBlocks_Defined) prop = _numBlocks; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + prop = v; + break; + } + default: break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; + case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break; + default: break; + } + prop.Detach(value); + return S_OK; +} + +static const unsigned kSignatureCheckSize = 10; + +API_FUNC_static_IsArc IsArc_BZip2(const Byte *p, size_t size) +{ + if (size < kSignatureCheckSize) + return k_IsArc_Res_NEED_MORE; + if (p[0] != 'B' || p[1] != 'Z' || p[2] != 'h' || p[3] < '1' || p[3] > '9') + return k_IsArc_Res_NO; + p += 4; + if (NCompress::NBZip2::IsBlockSig(p)) + return k_IsArc_Res_YES; + if (NCompress::NBZip2::IsEndSig(p)) + return k_IsArc_Res_YES; + return k_IsArc_Res_NO; +} +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) +{ + COM_TRY_BEGIN + Close(); + { + Byte buf[kSignatureCheckSize]; + RINOK(ReadStream_FALSE(stream, buf, kSignatureCheckSize)) + if (IsArc_BZip2(buf, kSignatureCheckSize) == k_IsArc_Res_NO) + return S_FALSE; + _isArc = true; + _stream = stream; + _seqStream = stream; + _needSeekToStart = true; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _isArc = true; + _seqStream = stream; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _needSeekToStart = false; + _dataAfterEnd = false; + _needMoreInput = false; + + _packSize_Defined = false; + _unpackSize_Defined = false; + _numStreams_Defined = false; + _numBlocks_Defined = false; + + _packSize = 0; + + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + if (_packSize_Defined) + { + RINOK(extractCallback->SetTotal(_packSize)) + } + + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(InStream_SeekToBegin(_stream)) + } + else + _needSeekToStart = true; + + // try { + + CMyComPtr2_Create decoder; + + #ifndef Z7_ST + RINOK(decoder->SetNumberOfThreads(_props._numThreads)) + #endif + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + decoder->FinishMode = true; + decoder->Base.DecodeAllStreams = true; + + _dataAfterEnd = false; + _needMoreInput = false; + + HRESULT result = decoder.Interface()->Code(_seqStream, outStream, NULL, NULL, lps); + + if (result != S_FALSE && result != S_OK) + return result; + + if (decoder->Base.NumStreams == 0) + { + _isArc = false; + result = S_FALSE; + } + else + { + const UInt64 inProcessedSize = decoder->GetInputProcessedSize(); + UInt64 packSize = inProcessedSize; + + if (decoder->Base.NeedMoreInput) + _needMoreInput = true; + + if (!decoder->Base.IsBz) + { + packSize = decoder->Base.FinishedPackSize; + if (packSize != inProcessedSize) + _dataAfterEnd = true; + } + + _packSize = packSize; + _unpackSize = decoder->GetOutProcessedSize(); + _numStreams = decoder->Base.NumStreams; + _numBlocks = decoder->GetNumBlocks(); + + _packSize_Defined = true; + _unpackSize_Defined = true; + _numStreams_Defined = true; + _numBlocks_Defined = true; + + // RINOK( + lps.Interface()->SetRatioInfo(&packSize, &_unpackSize); + } + + // outStream.Release(); + + if (!_isArc) + opRes = NExtract::NOperationResult::kIsNotArc; + else if (_needMoreInput) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else if (decoder->GetCrcError()) + opRes = NExtract::NOperationResult::kCRCError; + else if (_dataAfterEnd) + opRes = NExtract::NOperationResult::kDataAfterEnd; + else if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else if (decoder->Base.MinorError) + opRes = NExtract::NOperationResult::kDataError; + else if (result == S_OK) + opRes = NExtract::NOperationResult::kOK; + else + return result; + + } + return extractCallback->SetOperationResult(opRes); + + // } catch(...) { return E_FAIL; } + + COM_TRY_END +} + + +/* +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 + // , ArchiveUpdateCallbackArcProp *reportArcProp + ) +{ + { + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)) + if (!fileInStream) + return S_FALSE; + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, fileInStream) + if (streamGetSize) + { + UInt64 size; + if (streamGetSize->GetSize(&size) == S_OK) + unpackSize = size; + } + } + RINOK(updateCallback->SetTotal(unpackSize)) + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + { + CMyComPtr2_Create encoder; + RINOK(props.SetCoderProps(encoder.ClsPtr(), NULL)) + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + /* + if (reportArcProp) + { + unpackSize = encoderSpec->GetInProcessedSize(); + RINOK(ReportArcProps(reportArcProp, &unpackSize, &encoderSpec->NumBlocks)); + } + */ + } + } + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; + // *timeType = NFileTimeType::kUnix; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + if (numItems != 1) + return E_INVALIDARG; + + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + // Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, reportArcProp, updateCallback) + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt != VT_EMPTY) + if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + + CMethodProps props2 = _props; +#ifndef Z7_ST + props2.AddProp_NumThreads(_props._numThreads); +#ifdef _WIN32 + if (_props._numThreadGroups > 1) + props2.AddProp32(NCoderPropID::kNumThreadGroups, _props._numThreadGroups); +#endif +#endif + + return UpdateArchive(size, outStream, props2, updateCallback); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, 0, + NUpdateNotifyOp::kReplicate)) + } + + if (_stream) + RINOK(InStream_SeekToBegin(_stream)) + + return NCompress::CopyStream(_stream, outStream, lps); + + // return ReportArcProps(reportArcProp, NULL, NULL); + + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + return _props.SetProperties(names, values, numProps); +} + +static const Byte k_Signature[] = { 'B', 'Z', 'h' }; + +REGISTER_ARC_IO( + "bzip2", "bz2 bzip2 tbz2 tbz", "* * .tar .tar", 2, + k_Signature, + 0, + NArcInfoFlags::kKeepName + , 0 + , IsArc_BZip2) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabBlockInStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabBlockInStream.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.cpp 2024-01-01 07:00:00.000000000 +0000 @@ -1,100 +1,122 @@ -// CabBlockInStream.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" -#include "../../../../C/CpuArch.h" - -#include "../../Common/StreamUtils.h" - -#include "CabBlockInStream.h" - -namespace NArchive { -namespace NCab { - -static const UInt32 kBlockSize = (1 << 16); - -bool CCabBlockInStream::Create() -{ - if (!_buf) - _buf = (Byte *)::MyAlloc(kBlockSize); - return _buf != 0; -} - -CCabBlockInStream::~CCabBlockInStream() -{ - ::MyFree(_buf); -} - -static UInt32 CheckSum(const Byte *p, UInt32 size) -{ - UInt32 sum = 0; - - for (; size >= 8; size -= 8) - { - sum ^= GetUi32(p) ^ GetUi32(p + 4); - p += 8; - } - - if (size >= 4) - { - sum ^= GetUi32(p); - p += 4; - } - - size &= 3; - if (size > 2) sum ^= (UInt32)(*p++) << 16; - if (size > 1) sum ^= (UInt32)(*p++) << 8; - if (size > 0) sum ^= (UInt32)(*p++); - - return sum; -} - -HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize) -{ - const UInt32 kHeaderSize = 8; - const UInt32 kReservedMax = 256; - Byte header[kHeaderSize + kReservedMax]; - RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize)) - packSize = GetUi16(header + 4); - unpackSize = GetUi16(header + 6); - if (packSize > kBlockSize - _size) - return S_FALSE; - RINOK(ReadStream_FALSE(stream, _buf + _size, packSize)); - - if (MsZip) - { - if (_size == 0) - { - if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B) - return S_FALSE; - _pos = 2; - } - if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */ - return S_FALSE; - } - - if (GetUi32(header) != 0) // checkSum - if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize)) - return S_FALSE; - - _size += packSize; - return S_OK; -} - -STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (size != 0) - { - UInt32 rem = _size - _pos; - if (size > rem) - size = rem; - memcpy(data, _buf + _pos, size); - _pos += size; - } - if (processedSize) - *processedSize = size; - return S_OK; -} - -}} +// CabBlockInStream.cpp + +#include "StdAfx.h" + +#include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" + +#include "../../Common/StreamUtils.h" + +#include "CabBlockInStream.h" + +namespace NArchive { +namespace NCab { + +static const UInt32 kBlockSize = 1 << 16; +static const unsigned k_OverReadPadZone_Size = 32; +static const unsigned kHeaderSize = 8; +static const unsigned kReservedMax = 256; +static const unsigned kHeaderOffset = kBlockSize + k_OverReadPadZone_Size; + +bool CBlockPackData::Create() throw() +{ + if (!_buf) + _buf = (Byte *)z7_AlignedAlloc(kBlockSize + k_OverReadPadZone_Size + kHeaderSize + kReservedMax); + return _buf != NULL; +} + +CBlockPackData::~CBlockPackData() throw() +{ + z7_AlignedFree(_buf); +} + +static UInt32 CheckSum(const Byte *p, UInt32 size) throw() +{ +#ifdef MY_CPU_64BIT + + UInt64 sum64 = 0; + if (size >= 16) + { + const Byte *lim = p + (size_t)size - 16; + do + { + sum64 ^= GetUi64(p) ^ GetUi64(p + 8); + p += 16; + } + while (p <= lim); + size = (UInt32)(lim + 16 - p); + } + if (size >= 8) + { + sum64 ^= GetUi64(p); + p += 8; + size -= 8; + } + + UInt32 sum = (UInt32)(sum64 >> 32) ^ (UInt32)sum64; + +#else + + UInt32 sum = 0; + if (size >= 16) + { + const Byte *lim = p + (size_t)size - 16; + do + { + sum ^= GetUi32(p) + ^ GetUi32(p + 4) + ^ GetUi32(p + 8) + ^ GetUi32(p + 12); + p += 16; + } + while (p <= lim); + size = (UInt32)(lim + 16 - p); + } + if (size >= 8) + { + sum ^= GetUi32(p + 0) ^ GetUi32(p + 4); + p += 8; + size -= 8; + } + +#endif + + if (size >= 4) + { + sum ^= GetUi32(p); + p += 4; + } + if (size &= 3) + { + if (size >= 2) + { + if (size > 2) + sum ^= (UInt32)(*p++) << 16; + sum ^= (UInt32)(*p++) << 8; + } + sum ^= (UInt32)(*p++); + } + return sum; +} + + +HRESULT CBlockPackData::Read(ISequentialInStream *stream, Byte ReservedSize, UInt32 &packSizeRes, UInt32 &unpackSize) throw() +{ + const UInt32 reserved8 = kHeaderSize + ReservedSize; + const Byte *header = _buf + kHeaderOffset; + RINOK(ReadStream_FALSE(stream, (void *)header, reserved8)) + unpackSize = GetUi16a(header + 6); + const UInt32 packSize = GetUi16a(header + 4); + packSizeRes = packSize; + if (packSize > kBlockSize - _size) + return S_FALSE; + RINOK(ReadStream_FALSE(stream, _buf + _size, packSize)) + memset(_buf + _size + packSize, 0xff, k_OverReadPadZone_Size); + if (*(const UInt32 *)(const void *)header != 0) // checkSum + if (CheckSum(header, reserved8) != CheckSum(_buf + _size, packSize)) + return S_FALSE; + _size += packSize; + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabBlockInStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabBlockInStream.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabBlockInStream.h 2024-01-01 07:00:00.000000000 +0000 @@ -1,43 +1,28 @@ -// CabBlockInStream.h - -#ifndef __CAB_BLOCK_IN_STREAM_H -#define __CAB_BLOCK_IN_STREAM_H - -#include "../../../Common/MyCom.h" -#include "../../IStream.h" - -namespace NArchive { -namespace NCab { - -class CCabBlockInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - Byte *_buf; - UInt32 _size; - UInt32 _pos; - -public: - UInt32 ReservedSize; // < 256 - bool MsZip; - - MY_UNKNOWN_IMP - - CCabBlockInStream(): _buf(0), ReservedSize(0), MsZip(false) {} - ~CCabBlockInStream(); - - bool Create(); - - void InitForNewBlock() { _size = 0; _pos = 0; } - - HRESULT PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize); - - UInt32 GetPackSizeAvail() const { return _size - _pos; } - const Byte *GetData() const { return _buf + _pos; } - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -}} - -#endif +// CabBlockInStream.h + +#ifndef ZIP7_INC_CAB_BLOCK_IN_STREAM_H +#define ZIP7_INC_CAB_BLOCK_IN_STREAM_H + +#include "../../IStream.h" + +namespace NArchive { +namespace NCab { + +class CBlockPackData +{ + Byte *_buf; + UInt32 _size; +public: + CBlockPackData(): _buf(NULL), _size(0) {} + ~CBlockPackData() throw(); + bool Create() throw(); + void InitForNewBlock() { _size = 0; } + HRESULT Read(ISequentialInStream *stream, Byte ReservedSize, UInt32 &packSize, UInt32 &unpackSize) throw(); + UInt32 GetPackSize() const { return _size; } + // 32 bytes of overread zone is available after PackSize: + const Byte *GetData() const { return _buf; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.cpp 2024-03-02 10:00:00.000000000 +0000 @@ -1,1261 +1,1272 @@ -// CabHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../../C/Alloc.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/DeflateDecoder.h" -#include "../../Compress/LzxDecoder.h" -#include "../../Compress/QuantumDecoder.h" - -#include "../Common/ItemNameUtils.h" - -#include "CabBlockInStream.h" -#include "CabHandler.h" - -using namespace NWindows; - -namespace NArchive { -namespace NCab { - -// #define _CAB_DETAILS - -#ifdef _CAB_DETAILS -enum -{ - kpidBlockReal = kpidUserDefined -}; -#endif - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidMTime, - kpidAttrib, - kpidMethod, - kpidBlock - #ifdef _CAB_DETAILS - , - // kpidBlockReal, // L"BlockReal", - kpidOffset, - kpidVolume - #endif -}; - -static const Byte kArcProps[] = -{ - kpidTotalPhySize, - kpidMethod, - // kpidSolid, - kpidNumBlocks, - kpidNumVolumes, - kpidVolumeIndex, - kpidId -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static const char * const kMethods[] = -{ - "None" - , "MSZip" - , "Quantum" - , "LZX" -}; - -static const unsigned kMethodNameBufSize = 32; // "Quantum:255" - -static void SetMethodName(char *s, unsigned method, unsigned param) -{ - if (method < ARRAY_SIZE(kMethods)) - { - s = MyStpCpy(s, kMethods[method]); - if (method != NHeader::NMethod::kLZX && - method != NHeader::NMethod::kQuantum) - return; - *s++ = ':'; - method = param; - } - ConvertUInt32ToString(method, s); -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMethod: - { - UInt32 mask = 0; - UInt32 params[2] = { 0, 0 }; - { - FOR_VECTOR (v, m_Database.Volumes) - { - const CRecordVector &folders = m_Database.Volumes[v].Folders; - FOR_VECTOR (i, folders) - { - const CFolder &folder = folders[i]; - unsigned method = folder.GetMethod(); - mask |= ((UInt32)1 << method); - if (method == NHeader::NMethod::kLZX || - method == NHeader::NMethod::kQuantum) - { - unsigned di = (method == NHeader::NMethod::kQuantum) ? 0 : 1; - if (params[di] < folder.MethodMinor) - params[di] = folder.MethodMinor; - } - } - } - } - - AString s; - - for (unsigned i = 0; i < kNumMethodsMax; i++) - { - if ((mask & (1 << i)) == 0) - continue; - s.Add_Space_if_NotEmpty(); - char temp[kMethodNameBufSize]; - SetMethodName(temp, i, params[i == NHeader::NMethod::kQuantum ? 0 : 1]); - s += temp; - } - - prop = s; - break; - } - // case kpidSolid: prop = _database.IsSolid(); break; - case kpidNumBlocks: - { - UInt32 numFolders = 0; - FOR_VECTOR (v, m_Database.Volumes) - numFolders += m_Database.Volumes[v].Folders.Size(); - prop = numFolders; - break; - } - - case kpidTotalPhySize: - { - if (m_Database.Volumes.Size() > 1) - { - UInt64 sum = 0; - FOR_VECTOR (v, m_Database.Volumes) - sum += m_Database.Volumes[v].ArcInfo.Size; - prop = sum; - } - break; - } - - case kpidNumVolumes: - prop = (UInt32)m_Database.Volumes.Size(); - break; - - case kpidVolumeIndex: - { - if (m_Database.Volumes.Size() == 1) - { - const CDatabaseEx &db = m_Database.Volumes[0]; - const CInArcInfo &ai = db.ArcInfo; - prop = (UInt32)ai.CabinetNumber; - } - break; - } - - case kpidId: - { - if (m_Database.Volumes.Size() != 0) - { - prop = (UInt32)m_Database.Volumes[0].ArcInfo.SetID; - } - break; - } - - case kpidOffset: - /* - if (m_Database.Volumes.Size() == 1) - prop = m_Database.Volumes[0].StartPosition; - */ - prop = _offset; - break; - - case kpidPhySize: - /* - if (m_Database.Volumes.Size() == 1) - prop = (UInt64)m_Database.Volumes[0].ArcInfo.Size; - */ - prop = (UInt64)_phySize; - break; - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; - if (_errorInHeaders) v |= kpv_ErrorFlags_HeadersError; - if (_unexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - prop = v; - break; - } - - case kpidError: - if (!_errorMessage.IsEmpty()) - prop = _errorMessage; - break; - - case kpidName: - { - if (m_Database.Volumes.Size() == 1) - { - const CDatabaseEx &db = m_Database.Volumes[0]; - const CInArcInfo &ai = db.ArcInfo; - if (ai.SetID != 0) - { - AString s; - char temp[32]; - ConvertUInt32ToString(ai.SetID, temp); - s += temp; - ConvertUInt32ToString(ai.CabinetNumber + 1, temp); - s += '_'; - s += temp; - s += ".cab"; - prop = s; - } - /* - // that code is incomplete. It gcan give accurate name of volume - char s[32]; - ConvertUInt32ToString(ai.CabinetNumber + 2, s); - unsigned len = MyStringLen(s); - if (ai.IsThereNext()) - { - AString fn = ai.NextArc.FileName; - if (fn.Len() > 4 && StringsAreEqualNoCase_Ascii(fn.RightPtr(4), ".cab")) - fn.DeleteFrom(fn.Len() - 4); - if (len < fn.Len()) - { - if (strcmp(s, fn.RightPtr(len)) == 0) - { - AString s2 = fn; - s2.DeleteFrom(fn.Len() - len); - ConvertUInt32ToString(ai.CabinetNumber + 1, s); - s2 += s; - s2 += ".cab"; - prop = GetUnicodeString(s2); - } - } - } - */ - } - break; - } - - // case kpidShortComment: - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - const CMvItem &mvItem = m_Database.Items[index]; - const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; - unsigned itemIndex = mvItem.ItemIndex; - const CItem &item = db.Items[itemIndex]; - switch (propID) - { - case kpidPath: - { - UString unicodeName; - if (item.IsNameUTF()) - ConvertUTF8ToUnicode(item.Name, unicodeName); - else - unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP); - prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); - break; - } - - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidAttrib: prop = item.GetWinAttrib(); break; - - 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; - break; - } - - case kpidMethod: - { - UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size()); - const CFolder &folder = db.Folders[realFolderIndex]; - char s[kMethodNameBufSize];; - SetMethodName(s, folder.GetMethod(), folder.MethodMinor); - prop = s; - break; - } - - case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break; - - #ifdef _CAB_DETAILS - - // case kpidBlockReal: prop = (UInt32)item.FolderIndex; break; - case kpidOffset: prop = (UInt32)item.Offset; break; - case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break; - - #endif - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - - CInArchive archive; - CMyComPtr openVolumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - - CMyComPtr nextStream = inStream; - bool prevChecked = false; - UString startVolName; - bool startVolName_was_Requested = false; - UInt64 numItems = 0; - unsigned numTempVolumes = 0; - // try - { - while (nextStream) - { - CDatabaseEx db; - db.Stream = nextStream; - - HRESULT res = archive.Open(db, maxCheckStartPosition); - - _errorInHeaders |= archive.HeaderError; - _errorInHeaders |= archive.ErrorInNames; - _unexpectedEnd |= archive.UnexpectedEnd; - - if (res == S_OK && !m_Database.Volumes.IsEmpty()) - { - const CArchInfo &lastArc = m_Database.Volumes.Back().ArcInfo; - unsigned cabNumber = db.ArcInfo.CabinetNumber; - if (lastArc.SetID != db.ArcInfo.SetID) - res = S_FALSE; - else if (prevChecked) - { - if (cabNumber != lastArc.CabinetNumber + 1) - res = S_FALSE; - } - else if (cabNumber >= lastArc.CabinetNumber) - res = S_FALSE; - else if (numTempVolumes != 0) - { - const CArchInfo &prevArc = m_Database.Volumes[numTempVolumes - 1].ArcInfo; - if (cabNumber != prevArc.CabinetNumber + 1) - res = S_FALSE; - } - } - - if (archive.IsArc || res == S_OK) - { - _isArc = true; - if (m_Database.Volumes.IsEmpty()) - { - _offset = db.StartPosition; - _phySize = db.ArcInfo.Size; - } - } - - if (res == S_OK) - { - numItems += db.Items.Size(); - m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : numTempVolumes, db); - if (!prevChecked && m_Database.Volumes.Size() > 1) - { - numTempVolumes++; - if (db.ArcInfo.CabinetNumber + 1 == m_Database.Volumes[numTempVolumes].ArcInfo.CabinetNumber) - numTempVolumes = 0; - } - } - else - { - if (res != S_FALSE) - return res; - if (m_Database.Volumes.IsEmpty()) - return S_FALSE; - if (prevChecked) - break; - prevChecked = true; - if (numTempVolumes != 0) - { - m_Database.Volumes.DeleteFrontal(numTempVolumes); - numTempVolumes = 0; - } - } - - RINOK(callback->SetCompleted(&numItems, NULL)); - - nextStream = NULL; - - for (;;) - { - const COtherArc *otherArc = NULL; - - if (!prevChecked) - { - if (numTempVolumes == 0) - { - const CInArcInfo &ai = m_Database.Volumes[0].ArcInfo; - if (ai.IsTherePrev()) - otherArc = &ai.PrevArc; - else - prevChecked = true; - } - else - { - const CInArcInfo &ai = m_Database.Volumes[numTempVolumes - 1].ArcInfo; - if (ai.IsThereNext()) - otherArc = &ai.NextArc; - else - { - prevChecked = true; - m_Database.Volumes.DeleteFrontal(numTempVolumes); - numTempVolumes = 0; - } - } - } - - if (!otherArc) - { - const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo; - if (ai.IsThereNext()) - otherArc = &ai.NextArc; - } - - if (!otherArc) - break; - if (!openVolumeCallback) - break; - // printf("\n%s", otherArc->FileName); - const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP); - - if (!startVolName_was_Requested) - { - // some "bad" cab example can contain the link to itself. - startVolName_was_Requested = true; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt == VT_BSTR) - startVolName = prop.bstrVal; - } - if (fullName == startVolName) - break; - } - - HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); - if (result == S_OK) - break; - if (result != S_FALSE) - return result; - - if (!_errorMessage.IsEmpty()) - _errorMessage.Add_LF(); - _errorMessage.AddAscii("Can't open volume: "); - _errorMessage += fullName; - - if (prevChecked) - break; - prevChecked = true; - if (numTempVolumes != 0) - { - m_Database.Volumes.DeleteFrontal(numTempVolumes); - numTempVolumes = 0; - } - } - - } // read nextStream iteration - - if (numTempVolumes != 0) - { - m_Database.Volumes.DeleteFrontal(numTempVolumes); - numTempVolumes = 0; - } - if (m_Database.Volumes.IsEmpty()) - return S_FALSE; - else - { - m_Database.FillSortAndShrink(); - if (!m_Database.Check()) - return S_FALSE; - } - } - COM_TRY_END - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _errorMessage.Empty(); - _isArc = false; - _errorInHeaders = false; - _unexpectedEnd = false; - // _mainVolIndex = -1; - _phySize = 0; - _offset = 0; - - m_Database.Clear(); - return S_OK; -} - -class CFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -private: - const CMvDatabaseEx *m_Database; - const CRecordVector *m_ExtractStatuses; - - Byte *TempBuf; - UInt32 TempBufSize; - unsigned NumIdenticalFiles; - bool TempBufMode; - UInt32 m_BufStartFolderOffset; - - unsigned m_StartIndex; - unsigned m_CurrentIndex; - CMyComPtr m_ExtractCallback; - bool m_TestMode; - - CMyComPtr m_RealOutStream; - - bool m_IsOk; - bool m_FileIsOpen; - UInt32 m_RemainFileSize; - UInt64 m_FolderSize; - UInt64 m_PosInFolder; - - void FreeTempBuf() - { - ::MyFree(TempBuf); - TempBuf = NULL; - } - - HRESULT OpenFile(); - HRESULT CloseFileWithResOp(Int32 resOp); - HRESULT CloseFile(); - HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); -public: - HRESULT WriteEmptyFiles(); - - CFolderOutStream(): TempBuf(NULL) {} - ~CFolderOutStream() { FreeTempBuf(); } - void Init( - const CMvDatabaseEx *database, - const CRecordVector *extractStatuses, - unsigned startIndex, - UInt64 folderSize, - IArchiveExtractCallback *extractCallback, - bool testMode); - HRESULT FlushCorrupted(unsigned folderIndex); - HRESULT Unsupported(); - - bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); } - UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } - UInt64 GetPosInFolder() const { return m_PosInFolder; } -}; - - -void CFolderOutStream::Init( - const CMvDatabaseEx *database, - const CRecordVector *extractStatuses, - unsigned startIndex, - UInt64 folderSize, - IArchiveExtractCallback *extractCallback, - bool testMode) -{ - m_Database = database; - m_ExtractStatuses = extractStatuses; - m_StartIndex = startIndex; - m_FolderSize = folderSize; - - m_ExtractCallback = extractCallback; - m_TestMode = testMode; - - m_CurrentIndex = 0; - m_PosInFolder = 0; - m_FileIsOpen = false; - m_IsOk = true; - TempBufMode = false; - NumIdenticalFiles = 0; -} - - -HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp) -{ - m_RealOutStream.Release(); - m_FileIsOpen = false; - NumIdenticalFiles--; - return m_ExtractCallback->SetOperationResult(resOp); -} - - -HRESULT CFolderOutStream::CloseFile() -{ - return CloseFileWithResOp(m_IsOk ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError); -} - - -HRESULT CFolderOutStream::OpenFile() -{ - if (NumIdenticalFiles == 0) - { - const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; - const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - unsigned numExtractItems = 0; - unsigned curIndex; - - for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); curIndex++) - { - const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex]; - const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; - if (item.Offset != item2.Offset || - item.Size != item2.Size || - item.Size == 0) - break; - if (!m_TestMode && (*m_ExtractStatuses)[curIndex]) - numExtractItems++; - } - - NumIdenticalFiles = (curIndex - m_CurrentIndex); - if (NumIdenticalFiles == 0) - NumIdenticalFiles = 1; - TempBufMode = false; - - if (numExtractItems > 1) - { - if (!TempBuf || item.Size > TempBufSize) - { - FreeTempBuf(); - TempBuf = (Byte *)MyAlloc(item.Size); - TempBufSize = item.Size; - if (TempBuf == NULL) - return E_OUTOFMEMORY; - } - TempBufMode = true; - m_BufStartFolderOffset = item.Offset; - } - else if (numExtractItems == 1) - { - while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex]) - { - CMyComPtr stream; - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip)); - if (stream) - return E_FAIL; - RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip)); - m_CurrentIndex++; - m_FileIsOpen = true; - CloseFile(); - } - } - } - - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : - NExtract::NAskMode::kSkip; - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); - if (!m_RealOutStream && !m_TestMode) - askMode = NExtract::NAskMode::kSkip; - return m_ExtractCallback->PrepareOperation(askMode); -} - - -HRESULT CFolderOutStream::WriteEmptyFiles() -{ - if (m_FileIsOpen) - return S_OK; - for (; m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) - { - const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; - const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - UInt64 fileSize = item.Size; - if (fileSize != 0) - return S_OK; - HRESULT result = OpenFile(); - m_RealOutStream.Release(); - RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - return S_OK; -} - - -HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) -{ - COM_TRY_BEGIN - - UInt32 realProcessed = 0; - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (m_FileIsOpen) - { - UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size); - HRESULT res = S_OK; - if (numBytesToWrite != 0) - { - if (!isOK) - m_IsOk = false; - if (m_RealOutStream) - { - UInt32 processedSizeLocal = 0; - res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); - numBytesToWrite = processedSizeLocal; - } - if (TempBufMode && TempBuf) - memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite); - } - realProcessed += numBytesToWrite; - if (processedSize) - *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); - size -= numBytesToWrite; - m_RemainFileSize -= numBytesToWrite; - m_PosInFolder += numBytesToWrite; - - if (res != S_OK) - return res; - - if (m_RemainFileSize == 0) - { - RINOK(CloseFile()); - - while (NumIdenticalFiles) - { - HRESULT result = OpenFile(); - m_FileIsOpen = true; - m_CurrentIndex++; - if (result == S_OK && m_RealOutStream && TempBuf) - result = WriteStream(m_RealOutStream, TempBuf, (size_t)(m_PosInFolder - m_BufStartFolderOffset)); - - if (!TempBuf && TempBufMode && m_RealOutStream) - { - RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnsupportedMethod)); - } - else - { - RINOK(CloseFile()); - } - - RINOK(result); - } - - TempBufMode = false; - } - - if (realProcessed > 0) - break; // with this break this function works as Write-Part - } - else - { - if (m_CurrentIndex >= m_ExtractStatuses->Size()) - { - // we ignore extra data; - realProcessed += size; - if (processedSize) - *processedSize = realProcessed; - m_PosInFolder += size; - return S_OK; - // return E_FAIL; - } - - const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; - const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - - m_RemainFileSize = item.Size; - - UInt32 fileOffset = item.Offset; - - if (fileOffset < m_PosInFolder) - return E_FAIL; - - if (fileOffset > m_PosInFolder) - { - UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size); - realProcessed += numBytesToWrite; - if (processedSize) - *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); - size -= numBytesToWrite; - m_PosInFolder += numBytesToWrite; - } - - if (fileOffset == m_PosInFolder) - { - RINOK(OpenFile()); - m_FileIsOpen = true; - m_CurrentIndex++; - m_IsOk = true; - } - } - } - - return WriteEmptyFiles(); - - COM_TRY_END -} - - -STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write2(data, size, processedSize, true); -} - - -HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) -{ - if (!NeedMoreWrite()) - { - CMyComPtr callbackMessage; - m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); - if (callbackMessage) - { - RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, NExtract::NOperationResult::kDataError)); - } - return S_OK; - } - - const unsigned kBufSize = (1 << 12); - Byte buf[kBufSize]; - for (unsigned i = 0; i < kBufSize; i++) - buf[i] = 0; - - for (;;) - { - if (!NeedMoreWrite()) - return S_OK; - UInt64 remain = GetRemain(); - UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize); - UInt32 processedSizeLocal = 0; - RINOK(Write2(buf, size, &processedSizeLocal, false)); - } -} - - -HRESULT CFolderOutStream::Unsupported() -{ - while (m_CurrentIndex < m_ExtractStatuses->Size()) - { - HRESULT result = OpenFile(); - if (result != S_FALSE && result != S_OK) - return result; - m_RealOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - m_CurrentIndex++; - } - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = m_Database.Items.Size(); - if (numItems == 0) - return S_OK; - bool testMode = (testModeSpec != 0); - UInt64 totalUnPacked = 0; - - UInt32 i; - int lastFolder = -2; - UInt64 lastFolderSize = 0; - - for (i = 0; i < numItems; i++) - { - unsigned index = allFilesMode ? i : indices[i]; - const CMvItem &mvItem = m_Database.Items[index]; - const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - if (item.IsDir()) - continue; - int folderIndex = m_Database.GetFolderIndex(&mvItem); - if (folderIndex != lastFolder) - totalUnPacked += lastFolderSize; - lastFolder = folderIndex; - lastFolderSize = item.GetEndOffset(); - } - - totalUnPacked += lastFolderSize; - - extractCallback->SetTotal(totalUnPacked); - - totalUnPacked = 0; - - UInt64 totalPacked = 0; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL; - CMyComPtr deflateDecoder; - - NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; - CMyComPtr lzxDecoder; - - NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL; - CMyComPtr quantumDecoder; - - CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream(); - CMyComPtr cabBlockInStream = cabBlockInStreamSpec; - if (!cabBlockInStreamSpec->Create()) - return E_OUTOFMEMORY; - - CRecordVector extractStatuses; - - for (i = 0;;) - { - lps->OutSize = totalUnPacked; - lps->InSize = totalPacked; - RINOK(lps->SetCur()); - - if (i >= numItems) - break; - - unsigned index = allFilesMode ? i : indices[i]; - - const CMvItem &mvItem = m_Database.Items[index]; - const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; - unsigned itemIndex = mvItem.ItemIndex; - const CItem &item = db.Items[itemIndex]; - - i++; - if (item.IsDir()) - { - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - int folderIndex = m_Database.GetFolderIndex(&mvItem); - - if (folderIndex < 0) - { - // If we need previous archive - Int32 askMode= testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)); - continue; - } - - unsigned startIndex2 = m_Database.FolderStartFileIndex[folderIndex]; - unsigned startIndex = startIndex2; - extractStatuses.Clear(); - for (; startIndex < index; startIndex++) - extractStatuses.Add(false); - extractStatuses.Add(true); - startIndex++; - UInt64 curUnpack = item.GetEndOffset(); - - for (; i < numItems; i++) - { - unsigned indexNext = allFilesMode ? i : indices[i]; - const CMvItem &mvItem2 = m_Database.Items[indexNext]; - const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; - if (item2.IsDir()) - continue; - int newFolderIndex = m_Database.GetFolderIndex(&mvItem2); - - if (newFolderIndex != folderIndex) - break; - for (; startIndex < indexNext; startIndex++) - extractStatuses.Add(false); - extractStatuses.Add(true); - startIndex++; - curUnpack = item2.GetEndOffset(); - } - - CFolderOutStream *cabFolderOutStream = new CFolderOutStream; - CMyComPtr outStream(cabFolderOutStream); - - unsigned folderIndex2 = item.GetFolderIndex(db.Folders.Size()); - const CFolder &folder = db.Folders[folderIndex2]; - - cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, - curUnpack, extractCallback, testMode); - - cabBlockInStreamSpec->MsZip = false; - HRESULT res = S_OK; - - switch (folder.GetMethod()) - { - case NHeader::NMethod::kNone: - break; - - case NHeader::NMethod::kMSZip: - if (!deflateDecoder) - { - deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; - deflateDecoder = deflateDecoderSpec; - } - cabBlockInStreamSpec->MsZip = true; - break; - - case NHeader::NMethod::kLZX: - if (!lzxDecoder) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder; - lzxDecoder = lzxDecoderSpec; - } - res = lzxDecoderSpec->SetParams_and_Alloc(folder.MethodMinor); - break; - - case NHeader::NMethod::kQuantum: - if (!quantumDecoder) - { - quantumDecoderSpec = new NCompress::NQuantum::CDecoder; - quantumDecoder = quantumDecoderSpec; - } - res = quantumDecoderSpec->SetParams(folder.MethodMinor); - break; - - default: - res = E_INVALIDARG; - break; - } - - if (res == E_INVALIDARG) - { - RINOK(cabFolderOutStream->Unsupported()); - totalUnPacked += curUnpack; - continue; - } - RINOK(res); - - { - unsigned volIndex = mvItem.VolumeIndex; - int locFolderIndex = item.GetFolderIndex(db.Folders.Size()); - bool keepHistory = false; - bool keepInputBuffer = false; - bool thereWasNotAlignedChunk = false; - - for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();) - { - if (volIndex >= m_Database.Volumes.Size()) - { - res = S_FALSE; - break; - } - - const CDatabaseEx &db2 = m_Database.Volumes[volIndex]; - const CFolder &folder2 = db2.Folders[locFolderIndex]; - - if (bl == 0) - { - cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSize(); - RINOK(db2.Stream->Seek(db2.StartPosition + folder2.DataStart, STREAM_SEEK_SET, NULL)); - } - - if (bl == folder2.NumDataBlocks) - { - /* - CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit. - But there are some big CAB archives from MS that contain more - than (0xFFFF) CFDATA blocks in folder. - Old cab extracting software can show error (or ask next volume) - but cab extracting library in new Windows ignores this error. - 15.00 : We also try to ignore such error, if archive is not multi-volume. - */ - if (m_Database.Volumes.Size() > 1) - { - volIndex++; - locFolderIndex = 0; - bl = 0; - continue; - } - } - - bl++; - - if (!keepInputBuffer) - cabBlockInStreamSpec->InitForNewBlock(); - - UInt32 packSize, unpackSize; - res = cabBlockInStreamSpec->PreRead(db2.Stream, packSize, unpackSize); - if (res == S_FALSE) - break; - RINOK(res); - keepInputBuffer = (unpackSize == 0); - if (keepInputBuffer) - continue; - - UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); - totalPacked += packSize; - - lps->OutSize = totalUnPacked2; - lps->InSize = totalPacked; - RINOK(lps->SetCur()); - - const UInt32 kBlockSizeMax = (1 << 15); - - /* We don't try to reduce last block. - Note that LZX converts data with x86 filter. - and filter needs larger input data than reduced size. - It's simpler to decompress full chunk here. - also we need full block for quantum for more integrity checks */ - - if (unpackSize > kBlockSizeMax) - { - res = S_FALSE; - break; - } - - if (unpackSize != kBlockSizeMax) - { - if (thereWasNotAlignedChunk) - { - res = S_FALSE; - break; - } - thereWasNotAlignedChunk = true; - } - - UInt64 unpackSize64 = unpackSize; - UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail(); - - switch (folder2.GetMethod()) - { - case NHeader::NMethod::kNone: - res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL); - break; - - case NHeader::NMethod::kMSZip: - deflateDecoderSpec->Set_KeepHistory(keepHistory); - /* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block. - But PyCabArc can create CAB archives that doesn't have finish marker at the end of block. - Cabarc probably ignores such errors in cab archives. - Maybe we also should ignore that error? - Or we should extract full file and show the warning? */ - deflateDecoderSpec->Set_NeedFinishInput(true); - res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL); - if (res == S_OK) - { - if (!deflateDecoderSpec->IsFinished()) - res = S_FALSE; - if (!deflateDecoderSpec->IsFinalBlock()) - res = S_FALSE; - } - break; - - case NHeader::NMethod::kLZX: - lzxDecoderSpec->SetKeepHistory(keepHistory); - lzxDecoderSpec->KeepHistoryForNext = true; - - res = lzxDecoderSpec->Code(cabBlockInStreamSpec->GetData(), packSizeChunk, unpackSize); - - if (res == S_OK) - res = WriteStream(outStream, - lzxDecoderSpec->GetUnpackData(), - lzxDecoderSpec->GetUnpackSize()); - break; - - case NHeader::NMethod::kQuantum: - res = quantumDecoderSpec->Code(cabBlockInStreamSpec->GetData(), - packSizeChunk, outStream, unpackSize, keepHistory); - break; - } - - if (res != S_OK) - { - if (res != S_FALSE) - RINOK(res); - break; - } - - keepHistory = true; - } - - if (res == S_OK) - { - RINOK(cabFolderOutStream->WriteEmptyFiles()); - } - } - - if (res != S_OK || cabFolderOutStream->NeedMoreWrite()) - { - RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2)); - } - - totalUnPacked += curUnpack; - } - - return S_OK; - - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = m_Database.Items.Size(); - return S_OK; -} - -}} +// CabHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/AutoPtr.h" +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/DeflateDecoder.h" +#include "../../Compress/LzxDecoder.h" +#include "../../Compress/QuantumDecoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "CabBlockInStream.h" +#include "CabHandler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NCab { + +// #define CAB_DETAILS + +#ifdef CAB_DETAILS +enum +{ + kpidBlockReal = kpidUserDefined +}; +#endif + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidMTime, + kpidAttrib, + kpidMethod, + kpidBlock + #ifdef CAB_DETAILS + , + // kpidBlockReal, // L"BlockReal", + kpidOffset, + kpidVolume + #endif +}; + +static const Byte kArcProps[] = +{ + kpidTotalPhySize, + kpidMethod, + // kpidSolid, + kpidNumBlocks, + kpidNumVolumes, + kpidVolumeIndex, + kpidId +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static const char * const kMethods[] = +{ + "None" + , "MSZip" + , "Quantum" + , "LZX" +}; + +static const unsigned kMethodNameBufSize = 32; // "Quantum:255" + +static void SetMethodName(char *s, unsigned method, unsigned param) +{ + if (method < Z7_ARRAY_SIZE(kMethods)) + { + s = MyStpCpy(s, kMethods[method]); + if (method != NHeader::NMethod::kLZX && + method != NHeader::NMethod::kQuantum) + return; + *s++ = ':'; + method = param; + } + ConvertUInt32ToString(method, s); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMethod: + { + UInt32 mask = 0; + UInt32 params[2] = { 0, 0 }; + { + FOR_VECTOR (v, m_Database.Volumes) + { + const CRecordVector &folders = m_Database.Volumes[v].Folders; + FOR_VECTOR (i, folders) + { + const CFolder &folder = folders[i]; + const unsigned method = folder.GetMethod(); + mask |= ((UInt32)1 << method); + if (method == NHeader::NMethod::kLZX || + method == NHeader::NMethod::kQuantum) + { + const unsigned di = (method == NHeader::NMethod::kQuantum) ? 0 : 1; + if (params[di] < folder.MethodMinor) + params[di] = folder.MethodMinor; + } + } + } + } + + AString s; + + for (unsigned i = 0; i < kNumMethodsMax; i++) + { + if ((mask & (1 << i)) == 0) + continue; + s.Add_Space_if_NotEmpty(); + char temp[kMethodNameBufSize]; + SetMethodName(temp, i, params[i == NHeader::NMethod::kQuantum ? 0 : 1]); + s += temp; + } + + prop = s; + break; + } + // case kpidSolid: prop = _database.IsSolid(); break; + case kpidNumBlocks: + { + UInt32 numFolders = 0; + FOR_VECTOR (v, m_Database.Volumes) + numFolders += m_Database.Volumes[v].Folders.Size(); + prop = numFolders; + break; + } + + case kpidTotalPhySize: + { + if (m_Database.Volumes.Size() > 1) + { + UInt64 sum = 0; + FOR_VECTOR (v, m_Database.Volumes) + sum += m_Database.Volumes[v].ArcInfo.Size; + prop = sum; + } + break; + } + + case kpidNumVolumes: + prop = (UInt32)m_Database.Volumes.Size(); + break; + + case kpidVolumeIndex: + { + if (!m_Database.Volumes.IsEmpty()) + { + const CDatabaseEx &db = m_Database.Volumes[0]; + const CInArcInfo &ai = db.ArcInfo; + prop = (UInt32)ai.CabinetNumber; + } + break; + } + + case kpidId: + { + if (m_Database.Volumes.Size() != 0) + { + prop = (UInt32)m_Database.Volumes[0].ArcInfo.SetID; + } + break; + } + + case kpidOffset: + /* + if (m_Database.Volumes.Size() == 1) + prop = m_Database.Volumes[0].StartPosition; + */ + prop = _offset; + break; + + case kpidPhySize: + /* + if (m_Database.Volumes.Size() == 1) + prop = (UInt64)m_Database.Volumes[0].ArcInfo.Size; + */ + prop = (UInt64)_phySize; + break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_errorInHeaders) v |= kpv_ErrorFlags_HeadersError; + if (_unexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + prop = v; + break; + } + + case kpidError: + if (!_errorMessage.IsEmpty()) + prop = _errorMessage; + break; + + case kpidName: + { + if (m_Database.Volumes.Size() == 1) + { + const CDatabaseEx &db = m_Database.Volumes[0]; + const CInArcInfo &ai = db.ArcInfo; + if (ai.SetID != 0) + { + AString s; + s.Add_UInt32(ai.SetID); + s.Add_Char('_'); + s.Add_UInt32(ai.CabinetNumber + 1); + s += ".cab"; + prop = s; + } + /* + // that code is incomplete. It gcan give accurate name of volume + char s[32]; + ConvertUInt32ToString(ai.CabinetNumber + 2, s); + unsigned len = MyStringLen(s); + if (ai.IsThereNext()) + { + AString fn = ai.NextArc.FileName; + if (fn.Len() > 4 && StringsAreEqualNoCase_Ascii(fn.RightPtr(4), ".cab")) + fn.DeleteFrom(fn.Len() - 4); + if (len < fn.Len()) + { + if (strcmp(s, fn.RightPtr(len)) == 0) + { + AString s2 = fn; + s2.DeleteFrom(fn.Len() - len); + ConvertUInt32ToString(ai.CabinetNumber + 1, s); + s2 += s; + s2 += ".cab"; + prop = GetUnicodeString(s2); + } + } + } + */ + } + break; + } + + // case kpidShortComment: + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + const unsigned itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; + switch (propID) + { + case kpidPath: + { + UString unicodeName; + if (item.IsNameUTF()) + ConvertUTF8ToUnicode(item.Name, unicodeName); + else + unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP); + prop = (const wchar_t *)NItemName::WinPathToOsPath(unicodeName); + break; + } + + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidAttrib: prop = item.GetWinAttrib(); break; + + case kpidMTime: + { + PropVariant_SetFrom_DosTime(prop, item.Time); + break; + } + + case kpidMethod: + { + const int realFolderIndex = item.GetFolderIndex(db.Folders.Size()); + if (realFolderIndex >= 0) + { + const CFolder &folder = db.Folders[(unsigned)realFolderIndex]; + char s[kMethodNameBufSize]; + SetMethodName(s, folder.GetMethod(), folder.MethodMinor); + prop = s; + } + break; + } + + case kpidBlock: prop.Set_Int32((Int32)m_Database.GetFolderIndex(&mvItem)); break; + + #ifdef CAB_DETAILS + + // case kpidBlockReal: prop = (UInt32)item.FolderIndex; break; + case kpidOffset: prop = (UInt32)item.Offset; break; + case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break; + + #endif + + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + + CInArchive archive; + CMyComPtr openVolumeCallback; + if (callback) + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + + CMyComPtr nextStream = inStream; + bool prevChecked = false; + UString startVolName; + bool startVolName_was_Requested = false; + UInt64 numItems = 0; + unsigned numTempVolumes = 0; + // try + { + while (nextStream) + { + CDatabaseEx db; + db.Stream = nextStream; + + HRESULT res = archive.Open(db, maxCheckStartPosition); + + _errorInHeaders |= archive.HeaderError; + _errorInHeaders |= archive.ErrorInNames; + _unexpectedEnd |= archive.UnexpectedEnd; + + if (res == S_OK && !m_Database.Volumes.IsEmpty()) + { + const CArchInfo &lastArc = m_Database.Volumes.Back().ArcInfo; + const unsigned cabNumber = db.ArcInfo.CabinetNumber; + if (lastArc.SetID != db.ArcInfo.SetID) + res = S_FALSE; + else if (prevChecked) + { + if (cabNumber != lastArc.CabinetNumber + 1) + res = S_FALSE; + } + else if (cabNumber >= lastArc.CabinetNumber) + res = S_FALSE; + else if (numTempVolumes != 0) + { + const CArchInfo &prevArc = m_Database.Volumes[numTempVolumes - 1].ArcInfo; + if (cabNumber != prevArc.CabinetNumber + 1) + res = S_FALSE; + } + } + + if (archive.IsArc || res == S_OK) + { + _isArc = true; + if (m_Database.Volumes.IsEmpty()) + { + _offset = db.StartPosition; + _phySize = db.ArcInfo.Size; + } + } + + if (res == S_OK) + { + numItems += db.Items.Size(); + m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : numTempVolumes, db); + if (!prevChecked && m_Database.Volumes.Size() > 1) + { + numTempVolumes++; + if (db.ArcInfo.CabinetNumber + 1 == m_Database.Volumes[numTempVolumes].ArcInfo.CabinetNumber) + numTempVolumes = 0; + } + } + else + { + if (res != S_FALSE) + return res; + if (m_Database.Volumes.IsEmpty()) + return S_FALSE; + if (prevChecked) + break; + prevChecked = true; + if (numTempVolumes != 0) + { + m_Database.Volumes.DeleteFrontal(numTempVolumes); + numTempVolumes = 0; + } + } + + if (callback) + { + RINOK(callback->SetCompleted(&numItems, NULL)) + } + + nextStream = NULL; + + for (;;) + { + const COtherArc *otherArc = NULL; + + if (!prevChecked) + { + if (numTempVolumes == 0) + { + const CInArcInfo &ai = m_Database.Volumes[0].ArcInfo; + if (ai.IsTherePrev()) + otherArc = &ai.PrevArc; + else + prevChecked = true; + } + else + { + const CInArcInfo &ai = m_Database.Volumes[numTempVolumes - 1].ArcInfo; + if (ai.IsThereNext()) + otherArc = &ai.NextArc; + else + { + prevChecked = true; + m_Database.Volumes.DeleteFrontal(numTempVolumes); + numTempVolumes = 0; + } + } + } + + if (!otherArc) + { + const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo; + if (ai.IsThereNext()) + otherArc = &ai.NextArc; + } + + if (!otherArc) + break; + if (!openVolumeCallback) + break; + // printf("\n%s", otherArc->FileName); + const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP); + + if (!startVolName_was_Requested) + { + // some "bad" cab example can contain the link to itself. + startVolName_was_Requested = true; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt == VT_BSTR) + startVolName = prop.bstrVal; + } + if (fullName == startVolName) + break; + } + + const HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + if (result == S_OK) + break; + if (result != S_FALSE) + return result; + + if (!_errorMessage.IsEmpty()) + _errorMessage.Add_LF(); + _errorMessage += "Can't open volume: "; + _errorMessage += fullName; + + if (prevChecked) + break; + prevChecked = true; + if (numTempVolumes != 0) + { + m_Database.Volumes.DeleteFrontal(numTempVolumes); + numTempVolumes = 0; + } + } + + } // read nextStream iteration + + if (numTempVolumes != 0) + { + m_Database.Volumes.DeleteFrontal(numTempVolumes); + numTempVolumes = 0; + } + if (m_Database.Volumes.IsEmpty()) + return S_FALSE; + else + { + m_Database.FillSortAndShrink(); + if (!m_Database.Check()) + return S_FALSE; + } + } + COM_TRY_END + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _errorMessage.Empty(); + _isArc = false; + _errorInHeaders = false; + _unexpectedEnd = false; + // _mainVolIndex = -1; + _phySize = 0; + _offset = 0; + + m_Database.Clear(); + return S_OK; +} + + +Z7_CLASS_IMP_NOQIB_1( + CFolderOutStream + , ISequentialOutStream +) + bool m_TestMode; + bool TempBufMode; + bool m_IsOk; + bool m_FileIsOpen; + + const CMvDatabaseEx *m_Database; + const CRecordVector *m_ExtractStatuses; + + Byte *TempBuf; + UInt32 TempBufSize; + UInt32 TempBufWritten; + unsigned NumIdenticalFiles; + + unsigned m_StartIndex; + unsigned m_CurrentIndex; + + UInt32 m_RemainFileSize; + + UInt64 m_FolderSize; + UInt64 m_PosInFolder; + + CMyComPtr m_ExtractCallback; + CMyComPtr m_RealOutStream; + + void FreeTempBuf() + { + ::MyFree(TempBuf); + TempBuf = NULL; + } + + HRESULT OpenFile(); + HRESULT CloseFileWithResOp(Int32 resOp); + HRESULT CloseFile(); +public: + HRESULT WriteEmptyFiles(); + + CFolderOutStream(): TempBuf(NULL) {} + ~CFolderOutStream() { FreeTempBuf(); } + void Init( + const CMvDatabaseEx *database, + const CRecordVector *extractStatuses, + unsigned startIndex, + UInt64 folderSize, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(unsigned folderIndex); + HRESULT Unsupported(); + + bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); } + UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } + UInt64 GetPosInFolder() const { return m_PosInFolder; } +}; + + +void CFolderOutStream::Init( + const CMvDatabaseEx *database, + const CRecordVector *extractStatuses, + unsigned startIndex, + UInt64 folderSize, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + m_Database = database; + m_ExtractStatuses = extractStatuses; + m_StartIndex = startIndex; + m_FolderSize = folderSize; + + m_ExtractCallback = extractCallback; + m_TestMode = testMode; + + m_CurrentIndex = 0; + m_PosInFolder = 0; + m_FileIsOpen = false; + m_IsOk = true; + TempBufMode = false; + NumIdenticalFiles = 0; +} + + +HRESULT CFolderOutStream::CloseFileWithResOp(Int32 resOp) +{ + m_RealOutStream.Release(); + m_FileIsOpen = false; + NumIdenticalFiles--; + return m_ExtractCallback->SetOperationResult(resOp); +} + + +HRESULT CFolderOutStream::CloseFile() +{ + return CloseFileWithResOp(m_IsOk ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError); +} + + +HRESULT CFolderOutStream::OpenFile() +{ + if (NumIdenticalFiles == 0) + { + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + unsigned numExtractItems = 0; + unsigned curIndex; + + for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); curIndex++) + { + const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex]; + const CItem &item2 = m_Database->Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; + if (item.Offset != item2.Offset || + item.Size != item2.Size || + item.Size == 0) + break; + if (!m_TestMode && (*m_ExtractStatuses)[curIndex]) + numExtractItems++; + } + + NumIdenticalFiles = (curIndex - m_CurrentIndex); + if (NumIdenticalFiles == 0) + NumIdenticalFiles = 1; + TempBufMode = false; + + if (numExtractItems > 1) + { + if (!TempBuf || item.Size > TempBufSize) + { + FreeTempBuf(); + TempBuf = (Byte *)MyAlloc(item.Size); + TempBufSize = item.Size; + if (!TempBuf) + return E_OUTOFMEMORY; + } + TempBufMode = true; + TempBufWritten = 0; + } + else if (numExtractItems == 1) + { + while (NumIdenticalFiles && !(*m_ExtractStatuses)[m_CurrentIndex]) + { + CMyComPtr stream; + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &stream, NExtract::NAskMode::kSkip)) + if (stream) + return E_FAIL; + RINOK(m_ExtractCallback->PrepareOperation(NExtract::NAskMode::kSkip)) + m_CurrentIndex++; + m_FileIsOpen = true; + CloseFile(); + } + } + } + + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract : + NExtract::NAskMode::kSkip; + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)) + if (!m_RealOutStream && !m_TestMode) + askMode = NExtract::NAskMode::kSkip; + return m_ExtractCallback->PrepareOperation(askMode); +} + + +HRESULT CFolderOutStream::WriteEmptyFiles() +{ + if (m_FileIsOpen) + return S_OK; + for (; m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) + { + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + const UInt64 fileSize = item.Size; + if (fileSize != 0) + return S_OK; + const HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result) + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + return S_OK; +} + + +Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + // (data == NULL) means Error_Data for solid folder flushing + COM_TRY_BEGIN + + UInt32 realProcessed = 0; + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (m_FileIsOpen) + { + UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size); + HRESULT res = S_OK; + if (numBytesToWrite != 0) + { + if (!data) + m_IsOk = false; + + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + // 18.01 : we don't want ZEROs instead of missing data + if (data) + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + else + processedSizeLocal = numBytesToWrite; + numBytesToWrite = processedSizeLocal; + } + + if (TempBufMode && TempBuf) + { + if (data) + { + memcpy(TempBuf + TempBufWritten, data, numBytesToWrite); + TempBufWritten += numBytesToWrite; + } + } + } + realProcessed += numBytesToWrite; + if (processedSize) + *processedSize = realProcessed; + if (data) + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + + if (res != S_OK) + return res; + + if (m_RemainFileSize == 0) + { + RINOK(CloseFile()) + + while (NumIdenticalFiles) + { + HRESULT result = OpenFile(); + m_FileIsOpen = true; + m_CurrentIndex++; + if (result == S_OK && m_RealOutStream && TempBuf) + result = WriteStream(m_RealOutStream, TempBuf, TempBufWritten); + + if (!TempBuf && TempBufMode && m_RealOutStream) + { + RINOK(CloseFileWithResOp(NExtract::NOperationResult::kUnsupportedMethod)) + } + else + { + RINOK(CloseFile()) + } + + RINOK(result) + } + + TempBufMode = false; + } + + if (realProcessed > 0) + break; // with this break this function works as Write-Part + } + else + { + if (m_CurrentIndex >= m_ExtractStatuses->Size()) + { + // we ignore extra data; + realProcessed += size; + if (processedSize) + *processedSize = realProcessed; + m_PosInFolder += size; + return S_OK; + // return E_FAIL; + } + + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + + m_RemainFileSize = item.Size; + + const UInt32 fileOffset = item.Offset; + + if (fileOffset < m_PosInFolder) + return E_FAIL; + + if (fileOffset > m_PosInFolder) + { + const UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size); + realProcessed += numBytesToWrite; + if (processedSize) + *processedSize = realProcessed; + if (data) + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + + if (fileOffset == m_PosInFolder) + { + RINOK(OpenFile()) + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } + } + } + + return WriteEmptyFiles(); + + COM_TRY_END +} + + +HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) +{ + if (!NeedMoreWrite()) + { + CMyComPtr callbackMessage; + m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage); + if (callbackMessage) + { + RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, NExtract::NOperationResult::kDataError)) + } + return S_OK; + } + + for (;;) + { + if (!NeedMoreWrite()) + return S_OK; + const UInt64 remain = GetRemain(); + UInt32 size = (UInt32)1 << 20; + if (size > remain) + size = (UInt32)remain; + UInt32 processedSizeLocal = 0; + RINOK(Write(NULL, size, &processedSizeLocal)) + } +} + + +HRESULT CFolderOutStream::Unsupported() +{ + while (m_CurrentIndex < m_ExtractStatuses->Size()) + { + const HRESULT result = OpenFile(); + if (result != S_FALSE && result != S_OK) + return result; + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + m_CurrentIndex++; + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = m_Database.Items.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalUnPacked = 0; + + UInt32 i; + int lastFolder = -2; + UInt64 lastFolderSize = 0; + + for (i = 0; i < numItems; i++) + { + const unsigned index = allFilesMode ? i : indices[i]; + const CMvItem &mvItem = m_Database.Items[index]; + const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDir()) + continue; + const int folderIndex = m_Database.GetFolderIndex(&mvItem); + if (folderIndex != lastFolder) + totalUnPacked += lastFolderSize; + lastFolder = folderIndex; + lastFolderSize = item.GetEndOffset(); + } + + totalUnPacked += lastFolderSize; + RINOK(extractCallback->SetTotal(totalUnPacked)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + CMyComPtr2 deflateDecoder; + CMyUniquePtr lzxDecoder; + CMyUniquePtr quantumDecoder; + + CBlockPackData blockPackData; + if (!blockPackData.Create()) + return E_OUTOFMEMORY; + + CMyComPtr2_Create inBufStream; + + CRecordVector extractStatuses; + + totalUnPacked = 0; + UInt64 totalPacked = 0; + + for (i = 0;;) + { + lps->OutSize = totalUnPacked; + lps->InSize = totalPacked; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + const unsigned index = allFilesMode ? i : indices[i]; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + const unsigned itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; + + i++; + if (item.IsDir()) + { + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const int folderIndex = m_Database.GetFolderIndex(&mvItem); + + if (folderIndex < 0) + { + // If we need previous archive + const Int32 askMode= testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError)) + continue; + } + + const unsigned startIndex2 = m_Database.FolderStartFileIndex[(unsigned)folderIndex]; + unsigned startIndex = startIndex2; + extractStatuses.Clear(); + for (; startIndex < index; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + UInt64 curUnpack = item.GetEndOffset(); + + for (; i < numItems; i++) + { + const unsigned indexNext = allFilesMode ? i : indices[i]; + const CMvItem &mvItem2 = m_Database.Items[indexNext]; + const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex]; + if (item2.IsDir()) + continue; + const int newFolderIndex = m_Database.GetFolderIndex(&mvItem2); + + if (newFolderIndex != folderIndex) + break; + for (; startIndex < indexNext; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + curUnpack = item2.GetEndOffset(); + } + + CMyComPtr2_Create cabFolderOutStream; + + const int folderIndex2 = item.GetFolderIndex(db.Folders.Size()); + if (folderIndex2 < 0) + return E_FAIL; + const CFolder &folder = db.Folders[(unsigned)folderIndex2]; + + cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, + curUnpack, extractCallback, testMode != 0); + + HRESULT res = S_OK; + + switch (folder.GetMethod()) + { + case NHeader::NMethod::kNone: + break; + + case NHeader::NMethod::kMSZip: + deflateDecoder.Create_if_Empty(); + break; + + case NHeader::NMethod::kLZX: + lzxDecoder.Create_if_Empty(); + res = lzxDecoder->Set_DictBits_and_Alloc(folder.MethodMinor); + break; + + case NHeader::NMethod::kQuantum: + quantumDecoder.Create_if_Empty(); + res = quantumDecoder->SetParams(folder.MethodMinor); + break; + + default: + res = E_INVALIDARG; + break; + } + + if (res == E_INVALIDARG) + { + RINOK(cabFolderOutStream->Unsupported()) + totalUnPacked += curUnpack; + continue; + } + RINOK(res) + + { + unsigned volIndex = mvItem.VolumeIndex; + int locFolderIndex = item.GetFolderIndex(db.Folders.Size()); + bool keepHistory = false; + bool keepInputBuffer = false; + bool thereWasNotAlignedChunk = false; + + for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();) + { + if (volIndex >= m_Database.Volumes.Size()) + { + res = S_FALSE; + break; + } + + const CDatabaseEx &db2 = m_Database.Volumes[volIndex]; + if (locFolderIndex < 0) + return E_FAIL; + const CFolder &folder2 = db2.Folders[(unsigned)locFolderIndex]; + + if (bl == 0) + { + RINOK(InStream_SeekSet(db2.Stream, db2.StartPosition + folder2.DataStart)) + } + + if (bl == folder2.NumDataBlocks) + { + /* + CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit. + But there are some big CAB archives from MS that contain more + than (0xFFFF) CFDATA blocks in folder. + Old cab extracting software can show error (or ask next volume) + but cab extracting library in new Windows ignores this error. + 15.00 : We also try to ignore such error, if archive is not multi-volume. + */ + if (m_Database.Volumes.Size() > 1) + { + volIndex++; + locFolderIndex = 0; + bl = 0; + continue; + } + } + + bl++; + + if (!keepInputBuffer) + blockPackData.InitForNewBlock(); + + UInt32 packSize, unpackSize; + res = blockPackData.Read(db2.Stream, db2.ArcInfo.GetDataBlockReserveSize(), packSize, unpackSize); + if (res == S_FALSE) + break; + RINOK(res) + keepInputBuffer = (unpackSize == 0); + if (keepInputBuffer) + continue; + + const UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); + totalPacked += packSize; + + if (totalUnPacked2 - lps->OutSize >= (1 << 26) + || totalPacked - lps->InSize >= (1 << 24)) + { + lps->OutSize = totalUnPacked2; + lps->InSize = totalPacked; + RINOK(lps->SetCur()) + } + + const unsigned kBlockSizeMax = 1u << 15; + + if (unpackSize != kBlockSizeMax) + { + if (unpackSize > kBlockSizeMax || thereWasNotAlignedChunk) + { + res = S_FALSE; + break; + } + thereWasNotAlignedChunk = true; + } + + /* We don't try to reduce last block. + Note that LZX converts data with x86 filter. + and filter needs larger input data than reduced size. + It's simpler to decompress full chunk here. + also we need full block for quantum for more integrity checks */ + + const UInt64 unpackSize64 = unpackSize; + const UInt32 packSizeChunk = blockPackData.GetPackSize(); + + switch (folder2.GetMethod()) + { + case NHeader::NMethod::kNone: + if (unpackSize != packSizeChunk) + { + res = S_FALSE; + break; + } + res = WriteStream(cabFolderOutStream, blockPackData.GetData(), packSizeChunk); + break; + + case NHeader::NMethod::kMSZip: + { + /* v24.00 : fixed : we check 2-bytes MSZIP signature only + when block was constructed from all volumes. */ + const Byte *packData = blockPackData.GetData(); + if (unpackSize > (1u << 15) + 12 /* MSZIP specification */ + || packSizeChunk < 2 || GetUi16(packData) != 0x4b43) + { + res = S_FALSE; + break; + } + const UInt32 packSizeChunk_2 = packSizeChunk - 2; + inBufStream->Init(packData + 2, packSizeChunk_2); + + deflateDecoder->Set_KeepHistory(keepHistory); + /* v9.31: now we follow MSZIP specification that requires + to finish deflate stream at the end of each block. + But PyCabArc can create CAB archives that don't have + finish marker at the end of block. + Cabarc probably ignores such errors in cab archives. + Maybe we also should ignore such error? + Or we should extract full file and show the warning? */ + deflateDecoder->Set_NeedFinishInput(true); + res = deflateDecoder.Interface()->Code(inBufStream, cabFolderOutStream, NULL, &unpackSize64, NULL); + if (res == S_OK) + { + if (!deflateDecoder->IsFinished()) + res = S_FALSE; + if (!deflateDecoder->IsFinalBlock()) + res = S_FALSE; + if (deflateDecoder->GetInputProcessedSize() != packSizeChunk_2) + res = S_FALSE; + } + break; + } + + case NHeader::NMethod::kLZX: + lzxDecoder->Set_KeepHistory(keepHistory); + lzxDecoder->Set_KeepHistoryForNext(true); + res = lzxDecoder->Code_WithExceedReadWrite(blockPackData.GetData(), + packSizeChunk, unpackSize); + if (res == S_OK) + res = WriteStream(cabFolderOutStream, + lzxDecoder->GetUnpackData(), + lzxDecoder->GetUnpackSize()); + break; + + case NHeader::NMethod::kQuantum: + { + res = quantumDecoder->Code(blockPackData.GetData(), + packSizeChunk, unpackSize, keepHistory); + if (res == S_OK) + { + const UInt32 num = unpackSize; + res = WriteStream(cabFolderOutStream, + quantumDecoder->GetDataPtr() - num, num); + } + break; + } + default: + // it's unexpected case, because we checked method before + // res = E_NOTIMPL; + break; + } + + if (res != S_OK) + { + if (res != S_FALSE) + return res; + break; + } + + keepHistory = true; + } + + if (res == S_OK) + { + RINOK(cabFolderOutStream->WriteEmptyFiles()) + } + } + + if (res != S_OK || cabFolderOutStream->NeedMoreWrite()) + { + RINOK(cabFolderOutStream->FlushCorrupted((unsigned)folderIndex2)) + } + + totalUnPacked += curUnpack; + } + + return S_OK; + + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = m_Database.Items.Size(); + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHandler.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,37 +1,29 @@ -// CabHandler.h - -#ifndef __CAB_HANDLER_H -#define __CAB_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../IArchive.h" - -#include "CabIn.h" - -namespace NArchive { -namespace NCab { - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - -private: - CMvDatabaseEx m_Database; - UString _errorMessage; - bool _isArc; - bool _errorInHeaders; - bool _unexpectedEnd; - // int _mainVolIndex; - UInt32 _phySize; - UInt64 _offset; -}; - -}} - -#endif +// CabHandler.h + +#ifndef ZIP7_INC_CAB_HANDLER_H +#define ZIP7_INC_CAB_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../IArchive.h" + +#include "CabIn.h" + +namespace NArchive { +namespace NCab { + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CMvDatabaseEx m_Database; + UString _errorMessage; + bool _isArc; + bool _errorInHeaders; + bool _unexpectedEnd; + // int _mainVolIndex; + UInt32 _phySize; + UInt64 _offset; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHeader.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHeader.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.cpp 2015-03-25 12:04:59.000000000 +0000 @@ -1,15 +1,15 @@ -// CabHeader.cpp - -#include "StdAfx.h" - -#include "CabHeader.h" - -namespace NArchive { -namespace NCab { -namespace NHeader { - -const Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 }; - -// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; } } g_SignatureInitializer; - -}}} +// CabHeader.cpp + +#include "StdAfx.h" + +#include "CabHeader.h" + +namespace NArchive { +namespace NCab { +namespace NHeader { + +const Byte kMarker[kMarkerSize] = {'M', 'S', 'C', 'F', 0, 0, 0, 0 }; + +// struct CSignatureInitializer { CSignatureInitializer() { kMarker[0]--; } } g_SignatureInitializer; + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabHeader.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,41 +1,41 @@ -// Archive/CabHeader.h - -#ifndef __ARCHIVE_CAB_HEADER_H -#define __ARCHIVE_CAB_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace NCab { -namespace NHeader { - -const unsigned kMarkerSize = 8; -extern const Byte kMarker[kMarkerSize]; - -namespace NArcFlags -{ - const unsigned kPrevCabinet = 1; - const unsigned kNextCabinet = 2; - const unsigned kReservePresent = 4; -} - -namespace NMethod -{ - const Byte kNone = 0; - const Byte kMSZip = 1; - const Byte kQuantum = 2; - const Byte kLZX = 3; -} - -const unsigned kFileNameIsUtf8_Mask = 0x80; - -namespace NFolderIndex -{ - const unsigned kContinuedFromPrev = 0xFFFD; - const unsigned kContinuedToNext = 0xFFFE; - const unsigned kContinuedPrevAndNext = 0xFFFF; -} - -}}} - -#endif +// Archive/CabHeader.h + +#ifndef ZIP7_INC_ARCHIVE_CAB_HEADER_H +#define ZIP7_INC_ARCHIVE_CAB_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace NCab { +namespace NHeader { + +const unsigned kMarkerSize = 8; +extern const Byte kMarker[kMarkerSize]; + +namespace NArcFlags +{ + const unsigned kPrevCabinet = 1; + const unsigned kNextCabinet = 2; + const unsigned kReservePresent = 4; +} + +namespace NMethod +{ + const Byte kNone = 0; + const Byte kMSZip = 1; + const Byte kQuantum = 2; + const Byte kLZX = 3; +} + +const unsigned kFileNameIsUtf8_Mask = 0x80; + +namespace NFolderIndex +{ + const unsigned kContinuedFromPrev = 0xFFFD; + const unsigned kContinuedToNext = 0xFFFE; + const unsigned kContinuedPrevAndNext = 0xFFFF; +} + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabIn.cpp 2016-02-01 16:38:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.cpp 2024-01-01 07:00:00.000000000 +0000 @@ -1,491 +1,490 @@ -// Archive/CabIn.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../../C/CpuArch.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/StreamUtils.h" - -#include "CabIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NCab { - -struct CUnexpectedEndException {}; - -void CInArchive::Skip(unsigned size) -{ - if (_inBuffer.Skip(size) != size) - throw CUnexpectedEndException(); -} - -void CInArchive::Read(Byte *data, unsigned size) -{ - if (_inBuffer.ReadBytes(data, size) != size) - throw CUnexpectedEndException(); -} - -void CInArchive::ReadName(AString &s) -{ - for (size_t i = 0; i < ((size_t)1 << 13); i++) - { - Byte b; - if (!_inBuffer.ReadByte(b)) - throw CUnexpectedEndException(); - if (b == 0) - { - s.SetFrom((const char *)(const Byte *)_tempBuf, (unsigned)i); - return; - } - if (_tempBuf.Size() == i) - _tempBuf.ChangeSize_KeepData(i * 2, i); - _tempBuf[i] = b; - } - - for (;;) - { - Byte b; - if (!_inBuffer.ReadByte(b)) - throw CUnexpectedEndException(); - if (b == 0) - break; - } - - ErrorInNames = true; - s = "[ERROR-LONG-PATH]"; -} - -void CInArchive::ReadOtherArc(COtherArc &oa) -{ - ReadName(oa.FileName); - ReadName(oa.DiskName); -} - - -struct CSignatureFinder -{ - Byte *Buf; - UInt32 Pos; - UInt32 End; - const Byte *Signature; - UInt32 SignatureSize; - - UInt32 _HeaderSize; - UInt32 _AlignSize; - UInt32 _BufUseCapacity; - - ISequentialInStream *Stream; - UInt64 Processed; // Global offset of start of Buf - - const UInt64 *SearchLimit; - - UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize) - { - _HeaderSize = headerSize; - for (_AlignSize = (1 << 5); _AlignSize < _HeaderSize; _AlignSize <<= 1); - _BufUseCapacity = basicSize + _AlignSize; - return _BufUseCapacity + 16; - } - - /* - returns: - S_OK - signature found (at Pos) - S_FALSE - signature not found - */ - HRESULT Find(); -}; - - -HRESULT CSignatureFinder::Find() -{ - for (;;) - { - Buf[End] = Signature[0]; // it's for fast search; - - while (End - Pos >= _HeaderSize) - { - const Byte *p = Buf + Pos; - Byte b = Signature[0]; - for (;;) - { - if (*p == b) break; p++; - if (*p == b) break; p++; - } - Pos = (UInt32)(p - Buf); - if (End - Pos < _HeaderSize) - { - Pos = End - _HeaderSize + 1; - break; - } - UInt32 i; - for (i = 1; i < SignatureSize && p[i] == Signature[i]; i++); - if (i == SignatureSize) - return S_OK; - Pos++; - } - - if (Pos >= _AlignSize) - { - UInt32 num = (Pos & ~(_AlignSize - 1)); - Processed += num; - Pos -= num; - End -= num; - memmove(Buf, Buf + num, End); - } - UInt32 rem = _BufUseCapacity - End; - if (SearchLimit) - { - if (Processed + Pos > *SearchLimit) - return S_FALSE; - UInt64 rem2 = *SearchLimit - (Processed + End) + _HeaderSize; - if (rem > rem2) - rem = (UInt32)rem2; - } - - UInt32 processedSize; - if (Processed == 0 && rem == _BufUseCapacity - _HeaderSize) - rem -= _AlignSize; // to make reads more aligned. - RINOK(Stream->Read(Buf + End, rem, &processedSize)); - if (processedSize == 0) - return S_FALSE; - End += processedSize; - } -} - - -bool CInArcInfo::Parse(const Byte *p) -{ - if (Get32(p + 0x0C) != 0 || - Get32(p + 0x14) != 0) - return false; - Size = Get32(p + 8); - if (Size < 36) - return false; - Flags = Get16(p + 0x1E); - if (Flags > 7) - return false; - FileHeadersOffset = Get32(p + 0x10); - if (FileHeadersOffset != 0 && FileHeadersOffset > Size) - return false; - VersionMinor = p[0x18]; - VersionMajor = p[0x19]; - NumFolders = Get16(p + 0x1A); - NumFiles = Get16(p + 0x1C); - return true; -} - - -HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) -{ - IsArc = false; - ErrorInNames = false; - UnexpectedEnd = false; - HeaderError = false; - - db.Clear(); - RINOK(db.Stream->Seek(0, STREAM_SEEK_CUR, &db.StartPosition)); - // UInt64 temp = db.StartPosition; - - CByteBuffer buffer; - CInArcInfo &ai = db.ArcInfo; - UInt64 startInBuf = 0; - - CLimitedSequentialInStream *limitedStreamSpec = NULL; - CMyComPtr limitedStream; - - // for (int iii = 0; iii < 10000; iii++) - { - // db.StartPosition = temp; RINOK(db.Stream->Seek(db.StartPosition, STREAM_SEEK_SET, NULL)); - - const UInt32 kMainHeaderSize = 32; - Byte header[kMainHeaderSize]; - const UInt32 kBufSize = 1 << 15; - RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize)); - if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header)) - { - limitedStreamSpec = new CLimitedSequentialInStream; - limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(db.Stream); - limitedStreamSpec->Init(ai.Size - NHeader::kMarkerSize); - buffer.Alloc(kBufSize); - memcpy(buffer, header, kMainHeaderSize); - UInt32 numProcessedBytes; - RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes)); - _inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize); - } - else - { - if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) - return S_FALSE; - - CSignatureFinder finder; - - finder.Stream = db.Stream; - finder.Signature = NHeader::kMarker; - finder.SignatureSize = NHeader::kMarkerSize; - finder.SearchLimit = searchHeaderSizeLimit; - - buffer.Alloc(finder.GetTotalCapacity(kBufSize, kMainHeaderSize)); - finder.Buf = buffer; - - memcpy(buffer, header, kMainHeaderSize); - finder.Processed = db.StartPosition; - finder.End = kMainHeaderSize; - finder.Pos = 1; - - for (;;) - { - RINOK(finder.Find()); - if (ai.Parse(finder.Buf + finder.Pos)) - { - db.StartPosition = finder.Processed + finder.Pos; - limitedStreamSpec = new CLimitedSequentialInStream; - limitedStreamSpec->SetStream(db.Stream); - limitedStream = limitedStreamSpec; - UInt32 remInFinder = finder.End - finder.Pos; - if (ai.Size <= remInFinder) - { - limitedStreamSpec->Init(0); - finder.End = finder.Pos + ai.Size; - } - else - limitedStreamSpec->Init(ai.Size - remInFinder); - - startInBuf = finder.Pos; - _inBuffer.SetBuf(buffer, (UInt32)kBufSize, finder.End, finder.Pos + kMainHeaderSize); - break; - } - finder.Pos++; - } - } - } - - IsArc = true; - - _inBuffer.SetStream(limitedStream); - if (_tempBuf.Size() == 0) - _tempBuf.Alloc(1 << 12); - - Byte p[16]; - unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0); - Read(p, nextSize); - ai.SetID = Get16(p); - ai.CabinetNumber = Get16(p + 2); - - if (ai.ReserveBlockPresent()) - { - ai.PerCabinet_AreaSize = Get16(p + 4); - ai.PerFolder_AreaSize = p[6]; - ai.PerDataBlock_AreaSize = p[7]; - Skip(ai.PerCabinet_AreaSize); - } - - if (ai.IsTherePrev()) ReadOtherArc(ai.PrevArc); - if (ai.IsThereNext()) ReadOtherArc(ai.NextArc); - - UInt32 i; - - db.Folders.ClearAndReserve(ai.NumFolders); - - for (i = 0; i < ai.NumFolders; i++) - { - Read(p, 8); - CFolder folder; - folder.DataStart = Get32(p); - folder.NumDataBlocks = Get16(p + 4); - folder.MethodMajor = p[6]; - folder.MethodMinor = p[7]; - Skip(ai.PerFolder_AreaSize); - db.Folders.AddInReserved(folder); - } - - // for (int iii = 0; iii < 10000; iii++) { - - if (_inBuffer.GetProcessedSize() - startInBuf != ai.FileHeadersOffset) - { - // printf("\n!!! Seek Error !!!!\n"); - // fflush(stdout); - RINOK(db.Stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL)); - limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset); - _inBuffer.Init(); - } - - db.Items.ClearAndReserve(ai.NumFiles); - - for (i = 0; i < ai.NumFiles; i++) - { - Read(p, 16); - CItem &item = db.Items.AddNewInReserved(); - item.Size = Get32(p); - item.Offset = Get32(p + 4); - item.FolderIndex = Get16(p + 8); - UInt16 pureDate = Get16(p + 10); - UInt16 pureTime = Get16(p + 12); - item.Time = (((UInt32)pureDate << 16)) | pureTime; - item.Attributes = Get16(p + 14); - - ReadName(item.Name); - - if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size()) - { - HeaderError = true; - return S_FALSE; - } - } - - // } - - return S_OK; -} - - -HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) -{ - try - { - return Open2(db, searchHeaderSizeLimit); - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; } -} - - - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) -{ - const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param; - const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex]; - const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; - const CItem &item1 = db1.Items[p1->ItemIndex]; - const CItem &item2 = db2.Items[p2->ItemIndex];; - bool isDir1 = item1.IsDir(); - bool isDir2 = item2.IsDir(); - if (isDir1 && !isDir2) return -1; - if (isDir2 && !isDir1) return 1; - int f1 = mvDb.GetFolderIndex(p1); - int f2 = mvDb.GetFolderIndex(p2); - RINOZ(MyCompare(f1, f2)); - RINOZ(MyCompare(item1.Offset, item2.Offset)); - RINOZ(MyCompare(item1.Size, item2.Size)); - RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); - return MyCompare(p1->ItemIndex, p2->ItemIndex); -} - - -bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2) -{ - const CMvItem *p1 = &Items[i1]; - const CMvItem *p2 = &Items[i2]; - const CDatabaseEx &db1 = Volumes[p1->VolumeIndex]; - const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; - const CItem &item1 = db1.Items[p1->ItemIndex]; - const CItem &item2 = db2.Items[p2->ItemIndex];; - return GetFolderIndex(p1) == GetFolderIndex(p2) - && item1.Offset == item2.Offset - && item1.Size == item2.Size - && item1.Name == item2.Name; -} - - -void CMvDatabaseEx::FillSortAndShrink() -{ - Items.Clear(); - StartFolderOfVol.Clear(); - FolderStartFileIndex.Clear(); - - int offset = 0; - - FOR_VECTOR (v, Volumes) - { - const CDatabaseEx &db = Volumes[v]; - int curOffset = offset; - if (db.IsTherePrevFolder()) - curOffset--; - StartFolderOfVol.Add(curOffset); - offset += db.GetNumberOfNewFolders(); - - CMvItem mvItem; - mvItem.VolumeIndex = v; - FOR_VECTOR (i, db.Items) - { - mvItem.ItemIndex = i; - Items.Add(mvItem); - } - } - - if (Items.Size() > 1) - { - Items.Sort(CompareMvItems, (void *)this); - unsigned j = 1; - unsigned i = 1; - for (; i < Items.Size(); i++) - if (!AreItemsEqual(i, i - 1)) - Items[j++] = Items[i]; - Items.DeleteFrom(j); - } - - FOR_VECTOR (i, Items) - { - int folderIndex = GetFolderIndex(&Items[i]); - while (folderIndex >= (int)FolderStartFileIndex.Size()) - FolderStartFileIndex.Add(i); - } -} - - -bool CMvDatabaseEx::Check() -{ - for (unsigned v = 1; v < Volumes.Size(); v++) - { - const CDatabaseEx &db1 = Volumes[v]; - if (db1.IsTherePrevFolder()) - { - const CDatabaseEx &db0 = Volumes[v - 1]; - if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty()) - return false; - const CFolder &f0 = db0.Folders.Back(); - const CFolder &f1 = db1.Folders.Front(); - if (f0.MethodMajor != f1.MethodMajor || - f0.MethodMinor != f1.MethodMinor) - return false; - } - } - - UInt32 beginPos = 0; - UInt64 endPos = 0; - int prevFolder = -2; - - FOR_VECTOR (i, Items) - { - const CMvItem &mvItem = Items[i]; - int fIndex = GetFolderIndex(&mvItem); - if (fIndex >= (int)FolderStartFileIndex.Size()) - return false; - const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; - if (item.IsDir()) - continue; - - int folderIndex = GetFolderIndex(&mvItem); - - if (folderIndex != prevFolder) - prevFolder = folderIndex; - else if (item.Offset < endPos && - (item.Offset != beginPos || item.GetEndOffset() != endPos)) - return false; - - beginPos = item.Offset; - endPos = item.GetEndOffset(); - } - - return true; -} - -}} +// Archive/CabIn.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../../C/CpuArch.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +#include "CabIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NCab { + +struct CUnexpectedEndException {}; + +void CInArchive::Skip(unsigned size) +{ + if (_inBuffer.Skip(size) != size) + throw CUnexpectedEndException(); +} + +void CInArchive::Read(Byte *data, unsigned size) +{ + if (_inBuffer.ReadBytes(data, size) != size) + throw CUnexpectedEndException(); +} + +void CInArchive::ReadName(AString &s) +{ + for (size_t i = 0; i < ((size_t)1 << 13); i++) + { + Byte b; + if (!_inBuffer.ReadByte(b)) + throw CUnexpectedEndException(); + if (b == 0) + { + s.SetFrom((const char *)(const Byte *)_tempBuf, (unsigned)i); + return; + } + if (_tempBuf.Size() == i) + _tempBuf.ChangeSize_KeepData(i * 2, i); + _tempBuf[i] = b; + } + + for (;;) + { + Byte b; + if (!_inBuffer.ReadByte(b)) + throw CUnexpectedEndException(); + if (b == 0) + break; + } + + ErrorInNames = true; + s = "[ERROR-LONG-PATH]"; +} + +void CInArchive::ReadOtherArc(COtherArc &oa) +{ + ReadName(oa.FileName); + ReadName(oa.DiskName); +} + + +struct CSignatureFinder +{ + Byte *Buf; + UInt32 Pos; + UInt32 End; + const Byte *Signature; + UInt32 SignatureSize; + + UInt32 _headerSize; + UInt32 _alignSize; + UInt32 _bufUseCapacity; + + const UInt64 *SearchLimit; + ISequentialInStream *Stream; + UInt64 Processed; // Global offset of start of Buf + + UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize) + { + _headerSize = headerSize; + for (_alignSize = (1 << 5); _alignSize < _headerSize; _alignSize <<= 1); + _bufUseCapacity = basicSize + _alignSize; + return _bufUseCapacity + 16; + } + + /* + returns: + S_OK - signature found (at Pos) + S_FALSE - signature not found + */ + HRESULT Find(); +}; + + +HRESULT CSignatureFinder::Find() +{ + for (;;) + { + Buf[End] = Signature[0]; // it's for fast search; + + while (End - Pos >= _headerSize) + { + const Byte *p = Buf + Pos; + const Byte b = Signature[0]; + for (;;) + { + if (*p == b) { break; } p++; + if (*p == b) { break; } p++; + } + Pos = (UInt32)(p - Buf); + if (End - Pos < _headerSize) + { + Pos = End - _headerSize + 1; + break; + } + UInt32 i; + for (i = 1; i < SignatureSize && p[i] == Signature[i]; i++); + if (i == SignatureSize) + return S_OK; + Pos++; + } + + if (Pos >= _alignSize) + { + const UInt32 num = (Pos & ~(_alignSize - 1)); + Processed += num; + Pos -= num; + End -= num; + memmove(Buf, Buf + num, End); + } + UInt32 rem = _bufUseCapacity - End; + if (SearchLimit) + { + if (Processed + Pos > *SearchLimit) + return S_FALSE; + const UInt64 rem2 = *SearchLimit - (Processed + End) + _headerSize; + if (rem > rem2) + rem = (UInt32)rem2; + } + + UInt32 processedSize; + if (Processed == 0 && rem == _bufUseCapacity - _headerSize) + rem -= _alignSize; // to make reads more aligned. + RINOK(Stream->Read(Buf + End, rem, &processedSize)) + if (processedSize == 0) + return S_FALSE; + End += processedSize; + } +} + + +bool CInArcInfo::Parse(const Byte *p) +{ + if (Get32(p + 0x0C) != 0 || + Get32(p + 0x14) != 0) + return false; + Size = Get32(p + 8); + if (Size < 36) + return false; + Flags = Get16(p + 0x1E); + if (Flags > 7) + return false; + FileHeadersOffset = Get32(p + 0x10); + if (FileHeadersOffset != 0 && FileHeadersOffset > Size) + return false; + VersionMinor = p[0x18]; + VersionMajor = p[0x19]; + NumFolders = Get16(p + 0x1A); + NumFiles = Get16(p + 0x1C); + return true; +} + + +HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) +{ + IsArc = false; + ErrorInNames = false; + UnexpectedEnd = false; + HeaderError = false; + + db.Clear(); + RINOK(InStream_GetPos(db.Stream, db.StartPosition)) + // UInt64 temp = db.StartPosition; + + CByteBuffer buffer; + CInArcInfo &ai = db.ArcInfo; + UInt64 startInBuf = 0; + + CLimitedSequentialInStream *limitedStreamSpec = NULL; + CMyComPtr limitedStream; + + // for (int iii = 0; iii < 10000; iii++) + { + // db.StartPosition = temp; RINOK(InStream_SeekSet(db.Stream, db.StartPosition)) + + const UInt32 kMainHeaderSize = 32; + Byte header[kMainHeaderSize]; + const UInt32 kBufSize = 1 << 15; + RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize)) + if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header)) + { + limitedStreamSpec = new CLimitedSequentialInStream; + limitedStream = limitedStreamSpec; + limitedStreamSpec->SetStream(db.Stream); + limitedStreamSpec->Init(ai.Size - NHeader::kMarkerSize); + buffer.Alloc(kBufSize); + memcpy(buffer, header, kMainHeaderSize); + UInt32 numProcessedBytes; + RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes)) + _inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize); + } + else + { + if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) + return S_FALSE; + + CSignatureFinder finder; + + finder.Stream = db.Stream; + finder.Signature = NHeader::kMarker; + finder.SignatureSize = NHeader::kMarkerSize; + finder.SearchLimit = searchHeaderSizeLimit; + + buffer.Alloc(finder.GetTotalCapacity(kBufSize, kMainHeaderSize)); + finder.Buf = buffer; + + memcpy(buffer, header, kMainHeaderSize); + finder.Processed = db.StartPosition; + finder.End = kMainHeaderSize; + finder.Pos = 1; + + for (;;) + { + RINOK(finder.Find()) + if (ai.Parse(finder.Buf + finder.Pos)) + { + db.StartPosition = finder.Processed + finder.Pos; + limitedStreamSpec = new CLimitedSequentialInStream; + limitedStreamSpec->SetStream(db.Stream); + limitedStream = limitedStreamSpec; + const UInt32 remInFinder = finder.End - finder.Pos; + if (ai.Size <= remInFinder) + { + limitedStreamSpec->Init(0); + finder.End = finder.Pos + ai.Size; + } + else + limitedStreamSpec->Init(ai.Size - remInFinder); + + startInBuf = finder.Pos; + _inBuffer.SetBuf(buffer, (UInt32)kBufSize, finder.End, finder.Pos + kMainHeaderSize); + break; + } + finder.Pos++; + } + } + } + + IsArc = true; + + _inBuffer.SetStream(limitedStream); + if (_tempBuf.Size() == 0) + _tempBuf.Alloc(1 << 12); + + Byte p[16]; + const unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0); + Read(p, nextSize); + ai.SetID = Get16(p); + ai.CabinetNumber = Get16(p + 2); + + if (ai.ReserveBlockPresent()) + { + ai.PerCabinet_AreaSize = Get16(p + 4); + ai.PerFolder_AreaSize = p[6]; + ai.PerDataBlock_AreaSize = p[7]; + Skip(ai.PerCabinet_AreaSize); + } + + if (ai.IsTherePrev()) ReadOtherArc(ai.PrevArc); + if (ai.IsThereNext()) ReadOtherArc(ai.NextArc); + + UInt32 i; + + db.Folders.ClearAndReserve(ai.NumFolders); + + for (i = 0; i < ai.NumFolders; i++) + { + Read(p, 8); + CFolder folder; + folder.DataStart = Get32(p); + folder.NumDataBlocks = Get16(p + 4); + folder.MethodMajor = p[6]; + folder.MethodMinor = p[7]; + Skip(ai.PerFolder_AreaSize); + db.Folders.AddInReserved(folder); + } + + // for (int iii = 0; iii < 10000; iii++) { + + if (_inBuffer.GetProcessedSize() - startInBuf != ai.FileHeadersOffset) + { + // printf("\n!!! Seek Error !!!!\n"); + // fflush(stdout); + RINOK(InStream_SeekSet(db.Stream, db.StartPosition + ai.FileHeadersOffset)) + limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset); + _inBuffer.Init(); + } + + db.Items.ClearAndReserve(ai.NumFiles); + + for (i = 0; i < ai.NumFiles; i++) + { + Read(p, 16); + CItem &item = db.Items.AddNewInReserved(); + item.Size = Get32(p); + item.Offset = Get32(p + 4); + item.FolderIndex = Get16(p + 8); + const UInt16 pureDate = Get16(p + 10); + const UInt16 pureTime = Get16(p + 12); + item.Time = (((UInt32)pureDate << 16)) | pureTime; + item.Attributes = Get16(p + 14); + + ReadName(item.Name); + + if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size()) + { + HeaderError = true; + return S_FALSE; + } + } + + // } + + return S_OK; +} + + +HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) +{ + try + { + return Open2(db, searchHeaderSizeLimit); + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; } +} + + + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + +static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) +{ + const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param; + const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex]; + const bool isDir1 = item1.IsDir(); + const bool isDir2 = item2.IsDir(); + if (isDir1 && !isDir2) return -1; + if (isDir2 && !isDir1) return 1; + const int f1 = mvDb.GetFolderIndex(p1); + const int f2 = mvDb.GetFolderIndex(p2); + RINOZ(MyCompare(f1, f2)) + RINOZ(MyCompare(item1.Offset, item2.Offset)) + RINOZ(MyCompare(item1.Size, item2.Size)) + RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)) + return MyCompare(p1->ItemIndex, p2->ItemIndex); +} + + +bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2) +{ + const CMvItem *p1 = &Items[i1]; + const CMvItem *p2 = &Items[i2]; + const CDatabaseEx &db1 = Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex]; + return GetFolderIndex(p1) == GetFolderIndex(p2) + && item1.Offset == item2.Offset + && item1.Size == item2.Size + && item1.Name == item2.Name; +} + + +void CMvDatabaseEx::FillSortAndShrink() +{ + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + + int offset = 0; + + FOR_VECTOR (v, Volumes) + { + const CDatabaseEx &db = Volumes[v]; + int curOffset = offset; + if (db.IsTherePrevFolder()) + curOffset--; + StartFolderOfVol.Add(curOffset); + offset += db.GetNumberOfNewFolders(); + + CMvItem mvItem; + mvItem.VolumeIndex = v; + FOR_VECTOR (i, db.Items) + { + mvItem.ItemIndex = i; + Items.Add(mvItem); + } + } + + if (Items.Size() > 1) + { + Items.Sort(CompareMvItems, (void *)this); + unsigned j = 1; + unsigned i = 1; + for (; i < Items.Size(); i++) + if (!AreItemsEqual(i, i - 1)) + Items[j++] = Items[i]; + Items.DeleteFrom(j); + } + + FOR_VECTOR (i, Items) + { + const int folderIndex = GetFolderIndex(&Items[i]); + while (folderIndex >= (int)FolderStartFileIndex.Size()) + FolderStartFileIndex.Add(i); + } +} + + +bool CMvDatabaseEx::Check() +{ + for (unsigned v = 1; v < Volumes.Size(); v++) + { + const CDatabaseEx &db1 = Volumes[v]; + if (db1.IsTherePrevFolder()) + { + const CDatabaseEx &db0 = Volumes[v - 1]; + if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty()) + return false; + const CFolder &f0 = db0.Folders.Back(); + const CFolder &f1 = db1.Folders.FrontItem(); + if (f0.MethodMajor != f1.MethodMajor || + f0.MethodMinor != f1.MethodMinor) + return false; + } + } + + UInt32 beginPos = 0; + UInt64 endPos = 0; + int prevFolder = -2; + + FOR_VECTOR (i, Items) + { + const CMvItem &mvItem = Items[i]; + const int fIndex = GetFolderIndex(&mvItem); + if (fIndex >= (int)FolderStartFileIndex.Size()) + return false; + const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDir()) + continue; + + const int folderIndex = GetFolderIndex(&mvItem); + + if (folderIndex != prevFolder) + prevFolder = folderIndex; + else if (item.Offset < endPos && + (item.Offset != beginPos || item.GetEndOffset() != endPos)) + return false; + + beginPos = item.Offset; + endPos = item.GetEndOffset(); + } + + return true; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabIn.h 2016-02-01 16:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabIn.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,176 +1,176 @@ -// Archive/CabIn.h - -#ifndef __ARCHIVE_CAB_IN_H -#define __ARCHIVE_CAB_IN_H - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyCom.h" - -#include "../../Common/InBuffer.h" - -#include "CabItem.h" - -namespace NArchive { -namespace NCab { - -struct COtherArc -{ - AString FileName; - AString DiskName; - - void Clear() - { - FileName.Empty(); - DiskName.Empty(); - } -}; - - -struct CArchInfo -{ - Byte VersionMinor; // cabinet file format version, minor - Byte VersionMajor; // cabinet file format version, major - UInt32 NumFolders; // number of CFFOLDER entries in this cabinet - UInt32 NumFiles; // number of CFFILE entries in this cabinet - UInt32 Flags; // cabinet file option indicators - UInt32 SetID; // must be the same for all cabinets in a set - UInt32 CabinetNumber; // number of this cabinet file in a set - - UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area - Byte PerFolder_AreaSize; // (optional) size of per-folder reserved area - Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area - - COtherArc PrevArc; // prev link can skip some volumes !!! - COtherArc NextArc; - - bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; } - bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; } - bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; } - Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); } - - CArchInfo() - { - PerCabinet_AreaSize = 0; - PerFolder_AreaSize = 0; - PerDataBlock_AreaSize = 0; - } - - void Clear() - { - PerCabinet_AreaSize = 0; - PerFolder_AreaSize = 0; - PerDataBlock_AreaSize = 0; - - PrevArc.Clear(); - NextArc.Clear(); - } -}; - - -struct CInArcInfo: public CArchInfo -{ - UInt32 Size; // size of this cabinet file in bytes - UInt32 FileHeadersOffset; // offset of the first CFFILE entry - - bool Parse(const Byte *p); -}; - - -struct CDatabase -{ - CRecordVector Folders; - CObjectVector Items; - UInt64 StartPosition; - CInArcInfo ArcInfo; - - void Clear() - { - ArcInfo.Clear(); - Folders.Clear(); - Items.Clear(); - } - - bool IsTherePrevFolder() const - { - FOR_VECTOR (i, Items) - if (Items[i].ContinuedFromPrev()) - return true; - return false; - } - - int GetNumberOfNewFolders() const - { - int res = Folders.Size(); - if (IsTherePrevFolder()) - res--; - return res; - } -}; - - -struct CDatabaseEx: public CDatabase -{ - CMyComPtr Stream; -}; - - -struct CMvItem -{ - unsigned VolumeIndex; - unsigned ItemIndex; -}; - - -class CMvDatabaseEx -{ - bool AreItemsEqual(unsigned i1, unsigned i2); - -public: - CObjectVector Volumes; - CRecordVector Items; - CRecordVector StartFolderOfVol; // can be negative - CRecordVector FolderStartFileIndex; - - int GetFolderIndex(const CMvItem *mvi) const - { - const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; - return StartFolderOfVol[mvi->VolumeIndex] + - db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size()); - } - - void Clear() - { - Volumes.Clear(); - Items.Clear(); - StartFolderOfVol.Clear(); - FolderStartFileIndex.Clear(); - } - - void FillSortAndShrink(); - bool Check(); -}; - - -class CInArchive -{ - CInBufferBase _inBuffer; - CByteBuffer _tempBuf; - - void Skip(unsigned size); - void Read(Byte *data, unsigned size); - void ReadName(AString &s); - void ReadOtherArc(COtherArc &oa); - HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit); - -public: - bool IsArc; - bool ErrorInNames; - bool UnexpectedEnd; - bool HeaderError; - - HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit); -}; - -}} - -#endif +// Archive/CabIn.h + +#ifndef ZIP7_INC_ARCHIVE_CAB_IN_H +#define ZIP7_INC_ARCHIVE_CAB_IN_H + +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyCom.h" + +#include "../../Common/InBuffer.h" + +#include "CabItem.h" + +namespace NArchive { +namespace NCab { + +struct COtherArc +{ + AString FileName; + AString DiskName; + + void Clear() + { + FileName.Empty(); + DiskName.Empty(); + } +}; + + +struct CArchInfo +{ + Byte VersionMinor; // cabinet file format version, minor + Byte VersionMajor; // cabinet file format version, major + UInt32 NumFolders; // number of CFFOLDER entries in this cabinet + UInt32 NumFiles; // number of CFFILE entries in this cabinet + UInt32 Flags; // cabinet file option indicators + UInt32 SetID; // must be the same for all cabinets in a set + UInt32 CabinetNumber; // number of this cabinet file in a set + + UInt16 PerCabinet_AreaSize; // (optional) size of per-cabinet reserved area + Byte PerFolder_AreaSize; // (optional) size of per-folder reserved area + Byte PerDataBlock_AreaSize; // (optional) size of per-datablock reserved area + + COtherArc PrevArc; // prev link can skip some volumes !!! + COtherArc NextArc; + + bool ReserveBlockPresent() const { return (Flags & NHeader::NArcFlags::kReservePresent) != 0; } + bool IsTherePrev() const { return (Flags & NHeader::NArcFlags::kPrevCabinet) != 0; } + bool IsThereNext() const { return (Flags & NHeader::NArcFlags::kNextCabinet) != 0; } + Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlock_AreaSize : 0); } + + CArchInfo() + { + PerCabinet_AreaSize = 0; + PerFolder_AreaSize = 0; + PerDataBlock_AreaSize = 0; + } + + void Clear() + { + PerCabinet_AreaSize = 0; + PerFolder_AreaSize = 0; + PerDataBlock_AreaSize = 0; + + PrevArc.Clear(); + NextArc.Clear(); + } +}; + + +struct CInArcInfo: public CArchInfo +{ + UInt32 Size; // size of this cabinet file in bytes + UInt32 FileHeadersOffset; // offset of the first CFFILE entry + + bool Parse(const Byte *p); +}; + + +struct CDatabase +{ + CRecordVector Folders; + CObjectVector Items; + UInt64 StartPosition; + CInArcInfo ArcInfo; + + void Clear() + { + ArcInfo.Clear(); + Folders.Clear(); + Items.Clear(); + } + + bool IsTherePrevFolder() const + { + FOR_VECTOR (i, Items) + if (Items[i].ContinuedFromPrev()) + return true; + return false; + } + + int GetNumberOfNewFolders() const + { + int res = (int)Folders.Size(); + if (IsTherePrevFolder()) + res--; + return res; + } +}; + + +struct CDatabaseEx: public CDatabase +{ + CMyComPtr Stream; +}; + + +struct CMvItem +{ + unsigned VolumeIndex; + unsigned ItemIndex; +}; + + +class CMvDatabaseEx +{ + bool AreItemsEqual(unsigned i1, unsigned i2); + +public: + CObjectVector Volumes; + CRecordVector Items; + CRecordVector StartFolderOfVol; // can be negative + CRecordVector FolderStartFileIndex; + + int GetFolderIndex(const CMvItem *mvi) const + { + const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; + return StartFolderOfVol[mvi->VolumeIndex] + + db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size()); + } + + void Clear() + { + Volumes.Clear(); + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + } + + void FillSortAndShrink(); + bool Check(); +}; + + +class CInArchive +{ + CInBufferBase _inBuffer; + CByteBuffer _tempBuf; + + void Skip(unsigned size); + void Read(Byte *data, unsigned size); + void ReadName(AString &s); + void ReadOtherArc(COtherArc &oa); + HRESULT Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit); + +public: + bool IsArc; + bool ErrorInNames; + bool UnexpectedEnd; + bool HeaderError; + + HRESULT Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabItem.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,66 +1,66 @@ -// Archive/CabItem.h - -#ifndef __ARCHIVE_CAB_ITEM_H -#define __ARCHIVE_CAB_ITEM_H - -#include "../../../Common/MyString.h" - -#include "CabHeader.h" - -namespace NArchive { -namespace NCab { - -const unsigned kNumMethodsMax = 16; - -struct CFolder -{ - UInt32 DataStart; // offset of the first CFDATA block in this folder - UInt16 NumDataBlocks; // number of CFDATA blocks in this folder - Byte MethodMajor; - Byte MethodMinor; - - Byte GetMethod() const { return (Byte)(MethodMajor & 0xF); } -}; - -struct CItem -{ - AString Name; - UInt32 Offset; - UInt32 Size; - UInt32 Time; - UInt32 FolderIndex; - UInt16 Flags; - UInt16 Attributes; - - UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } - UInt32 GetWinAttrib() const { return (UInt32)Attributes & ~(UInt32)NHeader::kFileNameIsUtf8_Mask; } - bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUtf8_Mask) != 0; } - bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } - - bool ContinuedFromPrev() const - { - return - FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev || - FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext; - } - - bool ContinuedToNext() const - { - return - FolderIndex == NHeader::NFolderIndex::kContinuedToNext || - FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext; - } - - int GetFolderIndex(unsigned numFolders) const - { - if (ContinuedFromPrev()) - return 0; - if (ContinuedToNext()) - return numFolders - 1; - return FolderIndex; - } -}; - -}} - -#endif +// Archive/CabItem.h + +#ifndef ZIP7_INC_ARCHIVE_CAB_ITEM_H +#define ZIP7_INC_ARCHIVE_CAB_ITEM_H + +#include "../../../Common/MyString.h" + +#include "CabHeader.h" + +namespace NArchive { +namespace NCab { + +const unsigned kNumMethodsMax = 16; + +struct CFolder +{ + UInt32 DataStart; // offset of the first CFDATA block in this folder + UInt16 NumDataBlocks; // number of CFDATA blocks in this folder + Byte MethodMajor; + Byte MethodMinor; + + Byte GetMethod() const { return (Byte)(MethodMajor & 0xF); } +}; + +struct CItem +{ + AString Name; + UInt32 Offset; + UInt32 Size; + UInt32 Time; + UInt32 FolderIndex; + UInt16 Flags; + UInt16 Attributes; + + UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } + UInt32 GetWinAttrib() const { return (UInt32)Attributes & ~(UInt32)NHeader::kFileNameIsUtf8_Mask; } + bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUtf8_Mask) != 0; } + bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } + + bool ContinuedFromPrev() const + { + return + FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev || + FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext; + } + + bool ContinuedToNext() const + { + return + FolderIndex == NHeader::NFolderIndex::kContinuedToNext || + FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext; + } + + int GetFolderIndex(unsigned numFolders) const + { + if (ContinuedFromPrev()) + return 0; + if (ContinuedToNext()) + return (int)numFolders - 1; + return (int)FolderIndex; + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/CabRegister.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/CabRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,19 +1,19 @@ -// CabRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "CabHandler.h" - -namespace NArchive { -namespace NCab { - -REGISTER_ARC_I( - "Cab", "cab", 0, 8, - NHeader::kMarker, - 0, - NArcInfoFlags::kFindSignature, - NULL) - -}} +// CabRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "CabHandler.h" + +namespace NArchive { +namespace NCab { + +REGISTER_ARC_I( + "Cab", "cab", NULL, 8, + NHeader::kMarker, + 0, + NArcInfoFlags::kFindSignature, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Cab/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Cab/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Cab/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.cpp 2024-01-01 08:00:00.000000000 +0000 @@ -1,828 +1,790 @@ -// ChmHandler.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" -#include "../../Common/RegisterArc.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/LzxDecoder.h" - -#include "../Common/ItemNameUtils.h" - -#include "ChmHandler.h" - -using namespace NWindows; -using namespace NTime; - -namespace NArchive { -namespace NChm { - -// #define _CHM_DETAILS - -#ifdef _CHM_DETAILS - -enum -{ - kpidSection = kpidUserDefined -}; - -#endif - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidMethod, - kpidBlock - - #ifdef _CHM_DETAILS - , - L"Section", kpidSection, - kpidOffset - #endif -}; - -/* -static const Byte kArcProps[] = -{ - // kpidNumBlocks, -}; -*/ - -IMP_IInArchive_Props - -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - // COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - /* - case kpidNumBlocks: - { - UInt64 numBlocks = 0; - FOR_VECTOR(i, m_Database.Sections) - { - const CSectionInfo &s = m_Database.Sections[i]; - FOR_VECTOR(j, s.Methods) - { - const CMethodInfo &m = s.Methods[j]; - if (m.IsLzx()) - numBlocks += m.LzxInfo.ResetTable.GetNumBlocks(); - } - } - prop = numBlocks; - break; - } - */ - case kpidOffset: prop = m_Database.StartPosition; break; - case kpidPhySize: prop = m_Database.PhySize; break; - - case kpidErrorFlags: prop = m_ErrorFlags; 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; - - if (m_Database.NewFormat) - { - switch (propID) - { - case kpidSize: - prop = (UInt64)m_Database.NewFormatString.Len(); - break; - } - prop.Detach(value); - return S_OK; - } - - unsigned entryIndex; - if (m_Database.LowLevel) - entryIndex = index; - else - entryIndex = m_Database.Indices[index]; - - const CItem &item = m_Database.Items[entryIndex]; - - switch (propID) - { - case kpidPath: - { - UString us; - // if ( - ConvertUTF8ToUnicode(item.Name, us); - { - if (!m_Database.LowLevel) - { - if (us.Len() > 1 && us[0] == L'/') - us.Delete(0); - } - NItemName::ConvertToOSName2(us); - prop = us; - } - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidMethod: - { - if (!item.IsDir()) - if (item.Section == 0) - prop = "Copy"; - else if (item.Section < m_Database.Sections.Size()) - prop = m_Database.Sections[(unsigned)item.Section].GetMethodName(); - break; - } - case kpidBlock: - if (m_Database.LowLevel) - prop = item.Section; - else if (item.Section != 0 && item.Section < m_Database.Sections.Size()) - prop = m_Database.GetFolder(index); - break; - - #ifdef _CHM_DETAILS - - case kpidSection: prop = (UInt32)item.Section; break; - case kpidOffset: prop = (UInt32)item.Offset; break; - - #endif - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -/* -class CProgressImp: public CProgressVirt -{ - CMyComPtr _callback; -public: - STDMETHOD(SetTotal)(const UInt64 *numFiles); - STDMETHOD(SetCompleted)(const UInt64 *numFiles); - CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}; -}; - -STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles) -{ - if (_callback) - return _callback->SetCompleted(numFiles, NULL); - return S_OK; -} - -STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) -{ - if (_callback) - return _callback->SetCompleted(numFiles, NULL); - return S_OK; -} -*/ - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - try - { - CInArchive archive(_help2); - // CProgressImp progressImp(openArchiveCallback); - HRESULT res = archive.Open(inStream, maxCheckStartPosition, m_Database); - if (!archive.IsArc) m_ErrorFlags |= kpv_ErrorFlags_IsNotArc; - if (archive.HeadersError) m_ErrorFlags |= kpv_ErrorFlags_HeadersError; - if (archive.UnexpectedEnd) m_ErrorFlags |= kpv_ErrorFlags_UnexpectedEnd; - if (archive.UnsupportedFeature) m_ErrorFlags |= kpv_ErrorFlags_UnsupportedFeature; - - RINOK(res); - /* - if (m_Database.LowLevel) - return S_FALSE; - */ - m_Stream = inStream; - } - catch(...) - { - return S_FALSE; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - m_ErrorFlags = 0; - m_Database.Clear(); - m_Stream.Release(); - return S_OK; -} - -class CChmFolderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - - UInt64 m_FolderSize; - UInt64 m_PosInFolder; - UInt64 m_PosInSection; - const CRecordVector *m_ExtractStatuses; - unsigned m_StartIndex; - unsigned m_CurrentIndex; - unsigned m_NumFiles; - -private: - const CFilesDatabase *m_Database; - CMyComPtr m_ExtractCallback; - bool m_TestMode; - - bool m_IsOk; - bool m_FileIsOpen; - UInt64 m_RemainFileSize; - CMyComPtr m_RealOutStream; - - HRESULT OpenFile(); - HRESULT WriteEmptyFiles(); -public: - void Init( - const CFilesDatabase *database, - IArchiveExtractCallback *extractCallback, - bool testMode); - HRESULT FlushCorrupted(UInt64 maxSize); -}; - -void CChmFolderOutStream::Init( - const CFilesDatabase *database, - IArchiveExtractCallback *extractCallback, - bool testMode) -{ - m_Database = database; - m_ExtractCallback = extractCallback; - m_TestMode = testMode; - - m_CurrentIndex = 0; - m_FileIsOpen = false; -} - -HRESULT CChmFolderOutStream::OpenFile() -{ - Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : - NExtract::NAskMode::kSkip; - m_RealOutStream.Release(); - RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); - if (!m_RealOutStream && !m_TestMode) - askMode = NExtract::NAskMode::kSkip; - return m_ExtractCallback->PrepareOperation(askMode); -} - -HRESULT CChmFolderOutStream::WriteEmptyFiles() -{ - if (m_FileIsOpen) - return S_OK; - for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++) - { - UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); - if (fileSize != 0) - return S_OK; - HRESULT result = OpenFile(); - m_RealOutStream.Release(); - RINOK(result); - RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - return S_OK; -} - -// This is WritePart function -HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) -{ - UInt32 realProcessed = 0; - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (m_FileIsOpen) - { - UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); - HRESULT res = S_OK; - if (numBytesToWrite > 0) - { - if (!isOK) - m_IsOk = false; - if (m_RealOutStream) - { - UInt32 processedSizeLocal = 0; - res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); - numBytesToWrite = processedSizeLocal; - } - } - realProcessed += numBytesToWrite; - if (processedSize) - *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); - size -= numBytesToWrite; - m_RemainFileSize -= numBytesToWrite; - m_PosInSection += numBytesToWrite; - m_PosInFolder += numBytesToWrite; - if (res != S_OK) - return res; - if (m_RemainFileSize == 0) - { - m_RealOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult( - m_IsOk ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - m_FileIsOpen = false; - } - if (realProcessed > 0) - break; // with this break this function works as write part - } - else - { - if (m_CurrentIndex >= m_NumFiles) - { - realProcessed += size; - if (processedSize) - *processedSize = realProcessed; - return S_OK; - // return E_FAIL; - } - - unsigned fullIndex = m_StartIndex + m_CurrentIndex; - m_RemainFileSize = m_Database->GetFileSize(fullIndex); - UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); - if (fileOffset < m_PosInSection) - return E_FAIL; - - if (fileOffset > m_PosInSection) - { - UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size)); - realProcessed += numBytesToWrite; - if (processedSize) - *processedSize = realProcessed; - data = (const void *)((const Byte *)data + numBytesToWrite); - size -= numBytesToWrite; - m_PosInSection += numBytesToWrite; - m_PosInFolder += numBytesToWrite; - } - - if (fileOffset == m_PosInSection) - { - RINOK(OpenFile()); - m_FileIsOpen = true; - m_CurrentIndex++; - m_IsOk = true; - } - } - } - - return WriteEmptyFiles(); -} - -STDMETHODIMP CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write2(data, size, processedSize, true); -} - -HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize) -{ - const UInt32 kBufferSize = (1 << 10); - Byte buffer[kBufferSize]; - for (unsigned i = 0; i < kBufferSize; i++) - buffer[i] = 0; - if (maxSize > m_FolderSize) - maxSize = m_FolderSize; - while (m_PosInFolder < maxSize) - { - UInt32 size = (UInt32)MyMin(maxSize - m_PosInFolder, (UInt64)kBufferSize); - UInt32 processedSizeLocal = 0; - RINOK(Write2(buffer, size, &processedSizeLocal, false)); - if (processedSizeLocal == 0) - return S_OK; - } - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - - if (allFilesMode) - numItems = m_Database.NewFormat ? 1: - (m_Database.LowLevel ? - m_Database.Items.Size(): - m_Database.Indices.Size()); - if (numItems == 0) - return S_OK; - bool testMode = (testModeSpec != 0); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - UInt32 i; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(m_Stream); - - if (m_Database.LowLevel) - { - UInt64 currentItemSize = 0; - UInt64 totalSize = 0; - - if (m_Database.NewFormat) - totalSize = m_Database.NewFormatString.Len(); - else - for (i = 0; i < numItems; i++) - totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; - - extractCallback->SetTotal(totalSize); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - currentItemSize = 0; - lps->InSize = currentTotalSize; // Change it - lps->OutSize = currentTotalSize; - - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode= testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (m_Database.NewFormat) - { - if (index != 0) - return E_FAIL; - if (!testMode && !realOutStream) - continue; - if (!testMode) - { - UInt32 size = m_Database.NewFormatString.Len(); - RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)); - } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - const CItem &item = m_Database.Items[index]; - - currentItemSize = item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (item.Section != 0) - { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - } - - UInt64 lastFolderIndex = ((UInt64)0 - 1); - - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - const CItem &item = m_Database.Items[m_Database.Indices[index]]; - const UInt64 sectionIndex = item.Section; - if (item.IsDir() || item.Size == 0) - continue; - if (sectionIndex == 0) - { - currentTotalSize += item.Size; - continue; - } - - if (sectionIndex >= m_Database.Sections.Size()) - continue; - - const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex]; - if (section.IsLzx()) - { - const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; - UInt64 folderIndex = m_Database.GetFolder(index); - if (lastFolderIndex == folderIndex) - folderIndex++; - lastFolderIndex = m_Database.GetLastFolder(index); - for (; folderIndex <= lastFolderIndex; folderIndex++) - currentTotalSize += lzxInfo.GetFolderSize(); - } - } - - RINOK(extractCallback->SetTotal(currentTotalSize)); - - NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; - CMyComPtr lzxDecoder; - CChmFolderOutStream *chmFolderOutStream = 0; - CMyComPtr outStream; - - currentTotalSize = 0; - - CRecordVector extractStatuses; - - CByteBuffer packBuf; - - for (i = 0;;) - { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); - - if (i >= numItems) - break; - - UInt32 index = allFilesMode ? i : indices[i]; - i++; - const CItem &item = m_Database.Items[m_Database.Indices[index]]; - const UInt64 sectionIndex = item.Section; - Int32 askMode= testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - if (item.IsDir()) - { - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - lps->InSize = currentTotalSize; // Change it - lps->OutSize = currentTotalSize; - - if (item.Size == 0 || sectionIndex == 0) - { - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NExtract::NOperationResult::kOK; - if (!testMode && item.Size != 0) - { - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != item.Size) - opRes = NExtract::NOperationResult::kDataError; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - currentTotalSize += item.Size; - continue; - } - - if (sectionIndex >= m_Database.Sections.Size()) - { - // we must report error here; - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)); - continue; - } - - const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex]; - - if (!section.IsLzx()) - { - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; - - if (!chmFolderOutStream) - { - chmFolderOutStream = new CChmFolderOutStream; - outStream = chmFolderOutStream; - } - - chmFolderOutStream->Init(&m_Database, extractCallback, testMode); - - if (!lzxDecoderSpec) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder; - lzxDecoder = lzxDecoderSpec; - } - - UInt64 folderIndex = m_Database.GetFolder(index); - - const UInt64 compressedPos = m_Database.ContentOffset + section.Offset; - RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits())); - - const CItem *lastItem = &item; - extractStatuses.Clear(); - extractStatuses.Add(true); - - for (;; folderIndex++) - { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); - - UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); - UInt64 finishPos = lastItem->Offset + lastItem->Size; - UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); - - lastFolderIndex = m_Database.GetLastFolder(index); - UInt64 folderSize = lzxInfo.GetFolderSize(); - UInt64 unPackSize = folderSize; - - if (extractStatuses.IsEmpty()) - chmFolderOutStream->m_StartIndex = index + 1; - else - chmFolderOutStream->m_StartIndex = index; - - if (limitFolderIndex == folderIndex) - { - for (; i < numItems; i++) - { - const UInt32 nextIndex = allFilesMode ? i : indices[i]; - const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]]; - if (nextItem.Section != sectionIndex) - break; - UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); - if (nextFolderIndex != folderIndex) - break; - for (index++; index < nextIndex; index++) - extractStatuses.Add(false); - extractStatuses.Add(true); - index = nextIndex; - lastItem = &nextItem; - if (nextItem.Size != 0) - finishPos = nextItem.Offset + nextItem.Size; - lastFolderIndex = m_Database.GetLastFolder(index); - } - } - - unPackSize = MyMin(finishPos - startPos, unPackSize); - - chmFolderOutStream->m_FolderSize = folderSize; - chmFolderOutStream->m_PosInFolder = 0; - chmFolderOutStream->m_PosInSection = startPos; - chmFolderOutStream->m_ExtractStatuses = &extractStatuses; - chmFolderOutStream->m_NumFiles = extractStatuses.Size(); - chmFolderOutStream->m_CurrentIndex = 0; - - try - { - UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); - const CResetTable &rt = lzxInfo.ResetTable; - UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); - - for (UInt32 b = 0; b < numBlocks; b++) - { - UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; - RINOK(extractCallback->SetCompleted(&completedSize)); - UInt64 bCur = startBlock + b; - if (bCur >= rt.ResetOffsets.Size()) - return E_FAIL; - UInt64 offset = rt.ResetOffsets[(unsigned)bCur]; - UInt64 compressedSize; - rt.GetCompressedSizeOfBlock(bCur, compressedSize); - - // chm writes full blocks. So we don't need to use reduced size for last block - - RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(m_Stream); - streamSpec->Init(compressedSize); - - lzxDecoderSpec->SetKeepHistory(b > 0); - - size_t compressedSizeT = (size_t)compressedSize; - if (compressedSizeT != compressedSize) - throw 2; - packBuf.AllocAtLeast(compressedSizeT); - - HRESULT res = ReadStream_FALSE(inStream, packBuf, compressedSizeT); - - if (res == S_OK) - { - lzxDecoderSpec->KeepHistoryForNext = true; - res = lzxDecoderSpec->Code(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize; - if (res == S_OK) - res = WriteStream(chmFolderOutStream, - lzxDecoderSpec->GetUnpackData(), - lzxDecoderSpec->GetUnpackSize()); - } - - if (res != S_OK) - { - if (res != S_FALSE) - return res; - throw 1; - } - } - } - catch(...) - { - RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)); - } - - currentTotalSize += folderSize; - if (folderIndex == lastFolderIndex) - break; - extractStatuses.Clear(); - } - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = m_Database.NewFormat ? 1: - (m_Database.LowLevel ? - m_Database.Items.Size(): - m_Database.Indices.Size()); - return S_OK; -} - -namespace NChm { - -static const Byte k_Signature[] = { 'I', 'T', 'S', 'F', 3, 0, 0, 0, 0x60, 0, 0, 0 }; - -REGISTER_ARC_I_CLS( - CHandler(false), - "Chm", "chm chi chq chw", 0, 0xE9, - k_Signature, - 0, - 0, - NULL) - -} - -namespace NHxs { - -static const Byte k_Signature[] = { 'I', 'T', 'O', 'L', 'I', 'T', 'L', 'S', 1, 0, 0, 0, 0x28, 0, 0, 0 }; - -REGISTER_ARC_I_CLS( - CHandler(true), - "Hxs", "hxs hxi hxr hxq hxw lit", 0, 0xCE, - k_Signature, - 0, - NArcInfoFlags::kFindSignature, - NULL) - -} - -}} +// ChmHandler.cpp + +#include "StdAfx.h" + +#include "../../../Common/AutoPtr.h" +#include "../../../Common/ComTry.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" +#include "../../Common/RegisterArc.h" + +#include "../../Compress/CopyCoder.h" +#include "../../Compress/LzxDecoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "ChmHandler.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NChm { + +// #define CHM_DETAILS + +#ifdef CHM_DETAILS + +enum +{ + kpidSection = kpidUserDefined +}; + +#endif + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidMethod, + kpidBlock + + #ifdef CHM_DETAILS + , + L"Section", kpidSection, + kpidOffset + #endif +}; + +/* +static const Byte kArcProps[] = +{ + // kpidNumBlocks, +}; +*/ + +IMP_IInArchive_Props + +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + /* + case kpidNumBlocks: + { + UInt64 numBlocks = 0; + FOR_VECTOR(i, m_Database.Sections) + { + const CSectionInfo &s = m_Database.Sections[i]; + FOR_VECTOR(j, s.Methods) + { + const CMethodInfo &m = s.Methods[j]; + if (m.IsLzx()) + numBlocks += m.LzxInfo.ResetTable.GetNumBlocks(); + } + } + prop = numBlocks; + break; + } + */ + case kpidOffset: prop = m_Database.StartPosition; break; + case kpidPhySize: prop = m_Database.PhySize; break; + + case kpidErrorFlags: prop = m_ErrorFlags; break; + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (m_Database.NewFormat) + { + switch (propID) + { + case kpidSize: + prop = (UInt64)m_Database.NewFormatString.Len(); + break; + } + prop.Detach(value); + return S_OK; + } + + unsigned entryIndex; + if (m_Database.LowLevel) + entryIndex = index; + else + entryIndex = m_Database.Indices[index]; + + const CItem &item = m_Database.Items[entryIndex]; + + switch (propID) + { + case kpidPath: + { + UString us; + // if ( + ConvertUTF8ToUnicode(item.Name, us); + { + if (!m_Database.LowLevel) + { + if (us.Len() > 1 && us[0] == L'/') + us.Delete(0); + } + NItemName::ReplaceToOsSlashes_Remove_TailSlash(us); + prop = us; + } + break; + } + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = item.Size; break; + case kpidMethod: + { + if (!item.IsDir()) + { + if (item.Section == 0) + prop = "Copy"; + else if (item.Section < m_Database.Sections.Size()) + prop = m_Database.Sections[(unsigned)item.Section].GetMethodName(); + } + break; + } + case kpidBlock: + if (m_Database.LowLevel) + prop = item.Section; + else if (item.Section != 0 && item.Section < m_Database.Sections.Size()) + prop = m_Database.GetFolder(index); + break; + + #ifdef CHM_DETAILS + + case kpidSection: prop = (UInt32)item.Section; break; + case kpidOffset: prop = (UInt32)item.Offset; break; + + #endif + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + try + { + CInArchive archive(_help2); + // CProgressImp progressImp(openArchiveCallback); + const HRESULT res = archive.Open(inStream, maxCheckStartPosition, m_Database); + if (!archive.IsArc) m_ErrorFlags |= kpv_ErrorFlags_IsNotArc; + if (archive.HeadersError) m_ErrorFlags |= kpv_ErrorFlags_HeadersError; + if (archive.UnexpectedEnd) m_ErrorFlags |= kpv_ErrorFlags_UnexpectedEnd; + if (archive.UnsupportedFeature) m_ErrorFlags |= kpv_ErrorFlags_UnsupportedFeature; + + RINOK(res) + /* + if (m_Database.LowLevel) + return S_FALSE; + */ + m_Stream = inStream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + m_ErrorFlags = 0; + m_Database.Clear(); + m_Stream.Release(); + return S_OK; +} + +Z7_CLASS_IMP_NOQIB_1( + CChmFolderOutStream + , ISequentialOutStream +) + bool m_TestMode; + bool m_IsOk; + bool m_FileIsOpen; + const CFilesDatabase *m_Database; + CMyComPtr m_ExtractCallback; + CMyComPtr m_RealOutStream; + UInt64 m_RemainFileSize; + + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); + HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); +public: + + UInt64 m_FolderSize; + UInt64 m_PosInFolder; + UInt64 m_PosInSection; + const CRecordVector *m_ExtractStatuses; + unsigned m_StartIndex; + unsigned m_CurrentIndex; + unsigned m_NumFiles; + + void Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(UInt64 maxSize); +}; + +void CChmFolderOutStream::Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + m_Database = database; + m_ExtractCallback = extractCallback; + m_TestMode = testMode; + + m_CurrentIndex = 0; + m_FileIsOpen = false; +} + +HRESULT CChmFolderOutStream::OpenFile() +{ + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract : + NExtract::NAskMode::kSkip; + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)) + if (!m_RealOutStream && !m_TestMode) + askMode = NExtract::NAskMode::kSkip; + return m_ExtractCallback->PrepareOperation(askMode); +} + +HRESULT CChmFolderOutStream::WriteEmptyFiles() +{ + if (m_FileIsOpen) + return S_OK; + for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++) + { + const UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); + if (fileSize != 0) + return S_OK; + const HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result) + RINOK(m_ExtractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + return S_OK; +} + +// This is WritePart function +HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +{ + UInt32 realProcessed = 0; + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (m_FileIsOpen) + { + UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + HRESULT res = S_OK; + if (numBytesToWrite > 0) + { + if (!isOK) + m_IsOk = false; + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + numBytesToWrite = processedSizeLocal; + } + } + realProcessed += numBytesToWrite; + if (processedSize) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + if (res != S_OK) + return res; + if (m_RemainFileSize == 0) + { + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult( + m_IsOk ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)) + m_FileIsOpen = false; + } + if (realProcessed > 0) + break; // with this break this function works as write part + } + else + { + if (m_CurrentIndex >= m_NumFiles) + { + realProcessed += size; + if (processedSize) + *processedSize = realProcessed; + return S_OK; + // return E_FAIL; + } + + unsigned fullIndex = m_StartIndex + m_CurrentIndex; + m_RemainFileSize = m_Database->GetFileSize(fullIndex); + UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); + if (fileOffset < m_PosInSection) + return E_FAIL; + + if (fileOffset > m_PosInSection) + { + UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size)); + realProcessed += numBytesToWrite; + if (processedSize) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + + if (fileOffset == m_PosInSection) + { + RINOK(OpenFile()) + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } + } + } + + return WriteEmptyFiles(); +} + +Z7_COM7F_IMF(CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + return Write2(data, size, processedSize, true); +} + +HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize) +{ + const UInt32 kBufferSize = (1 << 10); + Byte buffer[kBufferSize]; + for (unsigned i = 0; i < kBufferSize; i++) + buffer[i] = 0; + if (maxSize > m_FolderSize) + maxSize = m_FolderSize; + while (m_PosInFolder < maxSize) + { + UInt32 size = (UInt32)MyMin(maxSize - m_PosInFolder, (UInt64)kBufferSize); + UInt32 processedSizeLocal = 0; + RINOK(Write2(buffer, size, &processedSizeLocal, false)) + if (processedSizeLocal == 0) + return S_OK; + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testModeSpec, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + + if (allFilesMode) + numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + if (numItems == 0) + return S_OK; + const bool testMode = (testModeSpec != 0); + + UInt64 currentTotalSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(m_Stream); + + UInt32 i; + + if (m_Database.LowLevel) + { + UInt64 currentItemSize = 0; + UInt64 totalSize = 0; + + if (m_Database.NewFormat) + totalSize = m_Database.NewFormatString.Len(); + else + for (i = 0; i < numItems; i++) + totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; + + RINOK(extractCallback->SetTotal(totalSize)) + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + currentItemSize = 0; + lps->InSize = currentTotalSize; // Change it + lps->OutSize = currentTotalSize; + + RINOK(lps->SetCur()) + CMyComPtr realOutStream; + const Int32 askMode= testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (m_Database.NewFormat) + { + if (index != 0) + return E_FAIL; + if (!testMode && !realOutStream) + continue; + if (!testMode) + { + const unsigned size = m_Database.NewFormatString.Len(); + RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size)) + } + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const CItem &item = m_Database.Items[index]; + + currentItemSize = item.Size; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (item.Section != 0) + { + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + RINOK(InStream_SeekSet(m_Stream, m_Database.ContentOffset + item.Offset)) + inStream->Init(item.Size); + + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult((copyCoder->TotalSize == item.Size) ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)) + } + return S_OK; + } + + UInt64 lastFolderIndex = (UInt64)0 - 1; + + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = m_Database.Items[m_Database.Indices[index]]; + const UInt64 sectionIndex = item.Section; + if (item.IsDir() || item.Size == 0) + continue; + if (sectionIndex == 0) + { + currentTotalSize += item.Size; + continue; + } + + if (sectionIndex >= m_Database.Sections.Size()) + continue; + + const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex]; + if (section.IsLzx()) + { + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + UInt64 folderIndex = m_Database.GetFolder(index); + if (lastFolderIndex == folderIndex) + folderIndex++; + lastFolderIndex = m_Database.GetLastFolder(index); + for (; folderIndex <= lastFolderIndex; folderIndex++) + currentTotalSize += lzxInfo.GetFolderSize(); + } + } + + RINOK(extractCallback->SetTotal(currentTotalSize)) + + CMyUniquePtr lzxDecoder; + CMyComPtr2_Create chmFolderOutStream; + + currentTotalSize = 0; + + CRecordVector extractStatuses; + + CByteBuffer packBuf; + + for (i = 0;;) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)) + + if (i >= numItems) + break; + + UInt32 index = allFilesMode ? i : indices[i]; + i++; + const CItem &item = m_Database.Items[m_Database.Indices[index]]; + const UInt64 sectionIndex = item.Section; + const Int32 askMode= testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + if (item.IsDir()) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + lps->InSize = currentTotalSize; // Change it + lps->OutSize = currentTotalSize; + + if (item.Size == 0 || sectionIndex == 0) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + Int32 opRes = NExtract::NOperationResult::kOK; + if (!testMode && item.Size != 0) + { + RINOK(InStream_SeekSet(m_Stream, m_Database.ContentOffset + item.Offset)) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item.Size) + opRes = NExtract::NOperationResult::kDataError; + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)) + currentTotalSize += item.Size; + continue; + } + + if (sectionIndex >= m_Database.Sections.Size()) + { + // we must report error here; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)) + continue; + } + + const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex]; + + if (!section.IsLzx()) + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + + chmFolderOutStream->Init(&m_Database, extractCallback, testMode); + + lzxDecoder.Create_if_Empty(); + + UInt64 folderIndex = m_Database.GetFolder(index); + + const UInt64 compressedPos = m_Database.ContentOffset + section.Offset; + RINOK(lzxDecoder->Set_DictBits_and_Alloc(lzxInfo.GetNumDictBits())) + + const CItem *lastItem = &item; + extractStatuses.Clear(); + extractStatuses.Add(true); + + for (;; folderIndex++) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)) + + const UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); + UInt64 finishPos = lastItem->Offset + lastItem->Size; + const UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); + + lastFolderIndex = m_Database.GetLastFolder(index); + const UInt64 folderSize = lzxInfo.GetFolderSize(); + UInt64 unPackSize = folderSize; + + if (extractStatuses.IsEmpty()) + chmFolderOutStream->m_StartIndex = index + 1; + else + chmFolderOutStream->m_StartIndex = index; + + if (limitFolderIndex == folderIndex) + { + for (; i < numItems; i++) + { + const UInt32 nextIndex = allFilesMode ? i : indices[i]; + const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]]; + if (nextItem.Section != sectionIndex) + break; + const UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); + if (nextFolderIndex != folderIndex) + break; + for (index++; index < nextIndex; index++) + extractStatuses.Add(false); + extractStatuses.Add(true); + index = nextIndex; + lastItem = &nextItem; + if (nextItem.Size != 0) + finishPos = nextItem.Offset + nextItem.Size; + lastFolderIndex = m_Database.GetLastFolder(index); + } + } + + unPackSize = MyMin(finishPos - startPos, unPackSize); + + chmFolderOutStream->m_FolderSize = folderSize; + chmFolderOutStream->m_PosInFolder = 0; + chmFolderOutStream->m_PosInSection = startPos; + chmFolderOutStream->m_ExtractStatuses = &extractStatuses; + chmFolderOutStream->m_NumFiles = extractStatuses.Size(); + chmFolderOutStream->m_CurrentIndex = 0; + + try + { + const UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); + const CResetTable &rt = lzxInfo.ResetTable; + const UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); + + for (UInt32 b = 0; b < numBlocks; b++) + { + UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; + RINOK(extractCallback->SetCompleted(&completedSize)) + UInt64 bCur = startBlock + b; + if (bCur >= rt.ResetOffsets.Size()) + return E_FAIL; + const UInt64 offset = rt.ResetOffsets[(unsigned)bCur]; + UInt64 compressedSize; + rt.GetCompressedSizeOfBlock(bCur, compressedSize); + + // chm writes full blocks. So we don't need to use reduced size for last block + + RINOK(InStream_SeekSet(m_Stream, compressedPos + offset)) + inStream->Init(compressedSize); + + lzxDecoder->Set_KeepHistory(b > 0); + + HRESULT res = S_FALSE; + if (compressedSize <= (1u << 30)) + { + const unsigned kAdditionalInputSize = 32; + const size_t compressedSizeT = (size_t)compressedSize; + const size_t allocSize = compressedSizeT + kAdditionalInputSize; + if (allocSize <= compressedSize) + throw 2; + packBuf.AllocAtLeast(allocSize); + res = ReadStream_FALSE(inStream, packBuf, compressedSizeT); + if (res == S_OK) + { + memset(packBuf + compressedSizeT, 0xff, kAdditionalInputSize); + lzxDecoder->Set_KeepHistoryForNext(true); + res = lzxDecoder->Code_WithExceedReadWrite(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize; + if (res == S_OK) + res = WriteStream(chmFolderOutStream, + lzxDecoder->GetUnpackData(), + lzxDecoder->GetUnpackSize()); + } + } + + if (res != S_OK) + { + if (res != S_FALSE) + return res; + throw 1; + } + } + } + catch(...) + { + RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)) + } + + currentTotalSize += folderSize; + if (folderIndex == lastFolderIndex) + break; + extractStatuses.Clear(); + } + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + return S_OK; +} + +namespace NChm { + +static const Byte k_Signature[] = { 'I', 'T', 'S', 'F', 3, 0, 0, 0, 0x60, 0, 0, 0 }; + +REGISTER_ARC_I_CLS( + CHandler(false), + "Chm", "chm chi chq chw", NULL, 0xE9, + k_Signature, + 0, + 0, + NULL) + +} + +namespace NHxs { + +static const Byte k_Signature[] = { 'I', 'T', 'O', 'L', 'I', 'T', 'L', 'S', 1, 0, 0, 0, 0x28, 0, 0, 0 }; + +REGISTER_ARC_I_CLS( + CHandler(true), + "Hxs", "hxs hxi hxr hxq hxw lit", NULL, 0xCE, + k_Signature, + 0, + NArcInfoFlags::kFindSignature, + NULL) + +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmHandler.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmHandler.h 2023-03-26 12:00:00.000000000 +0000 @@ -1,35 +1,27 @@ -// ChmHandler.h - -#ifndef __ARCHIVE_CHM_HANDLER_H -#define __ARCHIVE_CHM_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../IArchive.h" - -#include "ChmIn.h" - -namespace NArchive { -namespace NChm { - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - - bool _help2; - CHandler(bool help2): _help2(help2) {} - -private: - CFilesDatabase m_Database; - CMyComPtr m_Stream; - UInt32 m_ErrorFlags; -}; - -}} - -#endif +// ChmHandler.h + +#ifndef ZIP7_INC_ARCHIVE_CHM_HANDLER_H +#define ZIP7_INC_ARCHIVE_CHM_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../IArchive.h" + +#include "ChmIn.h" + +namespace NArchive { +namespace NChm { + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CFilesDatabase m_Database; + CMyComPtr m_Stream; + bool _help2; + UInt32 m_ErrorFlags; +public: + CHandler(bool help2): _help2(help2) {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmIn.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.cpp 2024-01-01 08:00:00.000000000 +0000 @@ -1,1055 +1,1026 @@ -// Archive/ChmIn.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/UTFConvert.h" - -#include "../../Common/LimitedStreams.h" - -#include "ChmIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -namespace NArchive { -namespace NChm { - -static const UInt32 kSignature_ITSP = 0x50535449; -static const UInt32 kSignature_PMGL = 0x4C474D50; -static const UInt32 kSignature_LZXC = 0x43585A4C; - -static const UInt32 kSignature_IFCM = 0x4D434649; -static const UInt32 kSignature_AOLL = 0x4C4C4F41; -static const UInt32 kSignature_CAOL = 0x4C4F4143; - -static const UInt32 kSignature_ITSF = 0x46535449; -static const UInt32 kSignature_ITOL = 0x4C4F5449; -static const UInt32 kSignature_ITLS = 0x534C5449; - -struct CEnexpectedEndException {}; -struct CHeaderErrorException {}; - -// define CHM_LOW, if you want to see low level items -// #define CHM_LOW - -static const GUID kChmLzxGuid = { 0x7FC28940, 0x9D31, 0x11D0, { 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C } }; -static const GUID kHelp2LzxGuid = { 0x0A9007C6, 0x4076, 0x11D3, { 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 } }; -static const GUID kDesGuid = { 0x67F6E4A2, 0x60BF, 0x11D3, { 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF } }; - -static bool AreGuidsEqual(REFGUID g1, REFGUID g2) -{ - if (g1.Data1 != g2.Data1 || - g1.Data2 != g2.Data2 || - g1.Data3 != g2.Data3) - return false; - for (int i = 0; i < 8; i++) - if (g1.Data4[i] != g2.Data4[i]) - return false; - return true; -} - -static char GetHex(unsigned v) -{ - return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); -} - -static void PrintByte(Byte b, AString &s) -{ - s += GetHex(b >> 4); - s += GetHex(b & 0xF); -} - -static void PrintUInt16(UInt16 v, AString &s) -{ - PrintByte((Byte)(v >> 8), s); - PrintByte((Byte)v, s); -} - -static void PrintUInt32(UInt32 v, AString &s) -{ - PrintUInt16((UInt16)(v >> 16), s); - PrintUInt16((UInt16)v, s); -} - -AString CMethodInfo::GetGuidString() const -{ - AString s; - s += '{'; - PrintUInt32(Guid.Data1, s); - s += '-'; - PrintUInt16(Guid.Data2, s); - s += '-'; - PrintUInt16(Guid.Data3, s); - s += '-'; - PrintByte(Guid.Data4[0], s); - PrintByte(Guid.Data4[1], s); - s += '-'; - for (int i = 2; i < 8; i++) - PrintByte(Guid.Data4[i], s); - s += '}'; - return s; -} - -bool CMethodInfo::IsLzx() const -{ - if (AreGuidsEqual(Guid, kChmLzxGuid)) - return true; - return AreGuidsEqual(Guid, kHelp2LzxGuid); -} - -bool CMethodInfo::IsDes() const -{ - return AreGuidsEqual(Guid, kDesGuid); -} - -UString CMethodInfo::GetName() const -{ - UString s; - if (IsLzx()) - { - s.SetFromAscii("LZX:"); - char temp[16]; - ConvertUInt32ToString(LzxInfo.GetNumDictBits(), temp); - s.AddAscii(temp); - } - else - { - AString s2; - if (IsDes()) - s2 = "DES"; - else - { - s2 = GetGuidString(); - if (ControlData.Size() > 0) - { - s2 += ':'; - for (size_t i = 0; i < ControlData.Size(); i++) - PrintByte(ControlData[i], s2); - } - } - ConvertUTF8ToUnicode(s2, s); - } - return s; -} - -bool CSectionInfo::IsLzx() const -{ - if (Methods.Size() != 1) - return false; - return Methods[0].IsLzx(); -} - -UString CSectionInfo::GetMethodName() const -{ - UString s; - if (!IsLzx()) - { - UString temp; - if (ConvertUTF8ToUnicode(Name, temp)) - s += temp; - s.AddAscii(": "); - } - FOR_VECTOR (i, Methods) - { - if (i != 0) - s.Add_Space(); - s += Methods[i].GetName(); - } - return s; -} - -Byte CInArchive::ReadByte() -{ - Byte b; - if (!_inBuffer.ReadByte(b)) - throw CEnexpectedEndException(); - return b; -} - -void CInArchive::Skip(size_t size) -{ - if (_inBuffer.Skip(size) != size) - throw CEnexpectedEndException(); -} - -void CInArchive::ReadBytes(Byte *data, UInt32 size) -{ - if (_inBuffer.ReadBytes(data, size) != size) - throw CEnexpectedEndException(); -} - -UInt16 CInArchive::ReadUInt16() -{ - Byte b0, b1; - if (!_inBuffer.ReadByte(b0)) throw CEnexpectedEndException(); - if (!_inBuffer.ReadByte(b1)) throw CEnexpectedEndException(); - return (UInt16)(((UInt16)b1 << 8) | b0); -} - -UInt32 CInArchive::ReadUInt32() -{ - Byte p[4]; - ReadBytes(p, 4); - return Get32(p); -} - -UInt64 CInArchive::ReadUInt64() -{ - Byte p[8]; - ReadBytes(p, 8); - return Get64(p); -} - -UInt64 CInArchive::ReadEncInt() -{ - UInt64 val = 0; - for (int i = 0; i < 9; i++) - { - Byte b = ReadByte(); - val |= (b & 0x7F); - if (b < 0x80) - return val; - val <<= 7; - } - throw CHeaderErrorException(); -} - -void CInArchive::ReadGUID(GUID &g) -{ - g.Data1 = ReadUInt32(); - g.Data2 = ReadUInt16(); - g.Data3 = ReadUInt16(); - ReadBytes(g.Data4, 8); -} - -void CInArchive::ReadString(unsigned size, AString &s) -{ - s.Empty(); - if (size != 0) - { - ReadBytes((Byte *)s.GetBuf(size), size); - s.ReleaseBuf_CalcLen(size); - } -} - -void CInArchive::ReadUString(unsigned size, UString &s) -{ - s.Empty(); - while (size-- != 0) - { - wchar_t c = ReadUInt16(); - if (c == 0) - { - Skip(2 * size); - return; - } - s += c; - } -} - -HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size) -{ - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr limitedStream(streamSpec); - streamSpec->SetStream(inStream); - streamSpec->Init(size); - m_InStreamRef = limitedStream; - _inBuffer.SetStream(limitedStream); - _inBuffer.Init(); - return S_OK; -} - -HRESULT CInArchive::ReadDirEntry(CDatabase &database) -{ - CItem item; - UInt64 nameLen = ReadEncInt(); - if (nameLen == 0 || nameLen > (1 << 13)) - return S_FALSE; - ReadString((unsigned)nameLen, item.Name); - item.Section = ReadEncInt(); - item.Offset = ReadEncInt(); - item.Size = ReadEncInt(); - database.Items.Add(item); - return S_OK; -} - -HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) -{ - UInt32 headerSize = ReadUInt32(); - if (headerSize != 0x60) - return S_FALSE; - database.PhySize = headerSize; - - UInt32 unknown1 = ReadUInt32(); - if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file - return S_FALSE; - - IsArc = true; - - /* UInt32 timeStamp = */ ReadUInt32(); - // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and - // fractional seconds (second byte). - // The third and fourth bytes may contain even more fractional bits. - // The 4 least significant bits in the last byte are constant. - /* UInt32 lang = */ ReadUInt32(); - GUID g; - ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} - ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} - const unsigned kNumSections = 2; - UInt64 sectionOffsets[kNumSections]; - UInt64 sectionSizes[kNumSections]; - unsigned i; - for (i = 0; i < kNumSections; i++) - { - sectionOffsets[i] = ReadUInt64(); - sectionSizes[i] = ReadUInt64(); - UInt64 end = sectionOffsets[i] + sectionSizes[i]; - database.UpdatePhySize(end); - } - // if (chmVersion == 3) - database.ContentOffset = ReadUInt64(); - /* - else - database.ContentOffset = database.StartPosition + 0x58 - */ - - // Section 0 - ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); - if (sectionSizes[0] < 0x18) - return S_FALSE; - if (ReadUInt32() != 0x01FE) - return S_FALSE; - ReadUInt32(); // unknown: 0 - UInt64 fileSize = ReadUInt64(); - database.UpdatePhySize(fileSize); - ReadUInt32(); // unknown: 0 - ReadUInt32(); // unknown: 0 - - // Section 1: The Directory Listing - ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); - if (ReadUInt32() != kSignature_ITSP) - return S_FALSE; - if (ReadUInt32() != 1) // version - return S_FALSE; - /* UInt32 dirHeaderSize = */ ReadUInt32(); - ReadUInt32(); // 0x0A (unknown) - UInt32 dirChunkSize = ReadUInt32(); // $1000 - if (dirChunkSize < 32) - return S_FALSE; - /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. - /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, - // 2 if there is one level of PMGI chunks. - - /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none - // (though at least one file has 0 despite there being no - // index chunk, probably a bug.) - /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk - /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk - ReadUInt32(); // -1 (unknown) - UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) - /* UInt32 windowsLangId = */ ReadUInt32(); - ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} - ReadUInt32(); // 0x54 (This is the length again) - ReadUInt32(); // -1 (unknown) - ReadUInt32(); // -1 (unknown) - ReadUInt32(); // -1 (unknown) - - for (UInt32 ci = 0; ci < numDirChunks; ci++) - { - UInt64 chunkPos = _inBuffer.GetProcessedSize(); - if (ReadUInt32() == kSignature_PMGL) - { - // The quickref area is written backwards from the end of the chunk. - // One quickref entry exists for every n entries in the file, where n - // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. - - UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk - if (quickrefLength > dirChunkSize || quickrefLength < 2) - return S_FALSE; - ReadUInt32(); // Always 0 - ReadUInt32(); // Chunk number of previous listing chunk when reading - // directory in sequence (-1 if this is the first listing chunk) - ReadUInt32(); // Chunk number of next listing chunk when reading - // directory in sequence (-1 if this is the last listing chunk) - unsigned numItems = 0; - - for (;;) - { - UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; - UInt32 offsetLimit = dirChunkSize - quickrefLength; - if (offset > offsetLimit) - return S_FALSE; - if (offset == offsetLimit) - break; - RINOK(ReadDirEntry(database)); - numItems++; - } - - Skip(quickrefLength - 2); - - unsigned rrr = ReadUInt16(); - if (rrr != numItems) - { - // Lazarus 9-26-2 chm contains 0 here. - if (rrr != 0) - return S_FALSE; - } - } - else - Skip(dirChunkSize - 4); - } - return S_OK; -} - -HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) -{ - if (ReadUInt32() != 1) // version - return S_FALSE; - if (ReadUInt32() != 0x28) // Location of header section table - return S_FALSE; - UInt32 numHeaderSections = ReadUInt32(); - const unsigned kNumHeaderSectionsMax = 5; - if (numHeaderSections != kNumHeaderSectionsMax) - return S_FALSE; - - IsArc = true; - - ReadUInt32(); // Len of post-header table - GUID g; - ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} - - // header section table - UInt64 sectionOffsets[kNumHeaderSectionsMax]; - UInt64 sectionSizes[kNumHeaderSectionsMax]; - UInt32 i; - for (i = 0; i < numHeaderSections; i++) - { - sectionOffsets[i] = ReadUInt64(); - sectionSizes[i] = ReadUInt64(); - UInt64 end = sectionOffsets[i] + sectionSizes[i]; - database.UpdatePhySize(end); - } - - // Post-Header - ReadUInt32(); // 2 - ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) - // ----- Directory information - ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 - ReadUInt64(); // Chunk number of first AOLL chunk in directory - ReadUInt64(); // Chunk number of last AOLL chunk in directory - ReadUInt64(); // 0 (unknown) - ReadUInt32(); // $2000 (Directory chunk size of directory) - ReadUInt32(); // Quickref density for main directory, usually 2 - ReadUInt32(); // 0 (unknown) - ReadUInt32(); // Depth of main directory index tree - // 1 there is no index, 2 if there is one level of AOLI chunks. - ReadUInt64(); // 0 (unknown) - UInt64 numDirEntries = ReadUInt64(); // Number of directory entries - // ----- Directory Index Information - ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) - ReadUInt64(); // Chunk number of first AOLL chunk in directory index - ReadUInt64(); // Chunk number of last AOLL chunk in directory index - ReadUInt64(); // 0 (unknown) - ReadUInt32(); // $200 (Directory chunk size of directory index) - ReadUInt32(); // Quickref density for directory index, usually 2 - ReadUInt32(); // 0 (unknown) - ReadUInt32(); // Depth of directory index index tree. - ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. - ReadUInt64(); // Number of directory index entries (same as number of AOLL - // chunks in main directory) - - // (The obvious guess for the following two fields, which recur in a number - // of places, is they are maximum sizes for the directory and directory index. - // However, I have seen no direct evidence that this is the case.) - - ReadUInt32(); // $100000 (Same as field following chunk size in directory) - ReadUInt32(); // $20000 (Same as field following chunk size in directory index) - - ReadUInt64(); // 0 (unknown) - if (ReadUInt32() != kSignature_CAOL) - return S_FALSE; - if (ReadUInt32() != 2) // (Most likely a version number) - return S_FALSE; - UInt32 caolLength = ReadUInt32(); // $50 (Len of the CAOL section, which includes the ITSF section) - if (caolLength >= 0x2C) - { - /* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built. - // Does not appear to be a checksum. Many files have - // 'HH' (HTML Help?) here, indicating this may be a compiler ID - // field. But at least one ITOL/ITLS compiler does not set this - // field to a constant value. - ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) - ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. - ReadUInt32(); // $2000 (Directory chunk size of directory) - ReadUInt32(); // $200 (Directory chunk size of directory index) - ReadUInt32(); // $100000 (Same as field following chunk size in directory) - ReadUInt32(); // $20000 (Same as field following chunk size in directory index) - ReadUInt32(); // 0 (unknown) - ReadUInt32(); // 0 (Unknown) - if (caolLength == 0x2C) - { - // fprintf(stdout, "\n !!!NewFormat\n"); - // fflush(stdout); - database.ContentOffset = 0; // maybe we must add database.StartPosition here? - database.NewFormat = true; - } - else if (caolLength == 0x50) - { - ReadUInt32(); // 0 (Unknown) - if (ReadUInt32() != kSignature_ITSF) - return S_FALSE; - if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) - return S_FALSE; - if (ReadUInt32() != 0x20) // $20 (length of ITSF) - return S_FALSE; - UInt32 unknown = ReadUInt32(); - if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; - return S_FALSE; - database.ContentOffset = database.StartPosition + ReadUInt64(); - /* UInt32 timeStamp = */ ReadUInt32(); - // A timestamp of some sort. - // Considered as a big-endian DWORD, it appears to contain - // seconds (MSB) and fractional seconds (second byte). - // The third and fourth bytes may contain even more fractional - // bits. The 4 least significant bits in the last byte are constant. - /* UInt32 lang = */ ReadUInt32(); // BE? - } - else - return S_FALSE; - } - - // Section 0 - ReadChunk(inStream, database.StartPosition + sectionOffsets[0], sectionSizes[0]); - if (sectionSizes[0] < 0x18) - return S_FALSE; - if (ReadUInt32() != 0x01FE) - return S_FALSE; - ReadUInt32(); // unknown: 0 - UInt64 fileSize = ReadUInt64(); - database.UpdatePhySize(fileSize); - ReadUInt32(); // unknown: 0 - ReadUInt32(); // unknown: 0 - - // Section 1: The Directory Listing - ReadChunk(inStream, database.StartPosition + sectionOffsets[1], sectionSizes[1]); - if (ReadUInt32() != kSignature_IFCM) - return S_FALSE; - if (ReadUInt32() != 1) // (probably a version number) - return S_FALSE; - UInt32 dirChunkSize = ReadUInt32(); // $2000 - if (dirChunkSize < 64) - return S_FALSE; - ReadUInt32(); // $100000 (unknown) - ReadUInt32(); // -1 (unknown) - ReadUInt32(); // -1 (unknown) - UInt32 numDirChunks = ReadUInt32(); - ReadUInt32(); // 0 (unknown, probably high word of above) - - for (UInt32 ci = 0; ci < numDirChunks; ci++) - { - UInt64 chunkPos = _inBuffer.GetProcessedSize(); - if (ReadUInt32() == kSignature_AOLL) - { - UInt32 quickrefLength = ReadUInt32(); // Len of quickref area at end of directory chunk - if (quickrefLength > dirChunkSize || quickrefLength < 2) - return S_FALSE; - ReadUInt64(); // Directory chunk number - // This must match physical position in file, that is - // the chunk size times the chunk number must be the - // offset from the end of the directory header. - ReadUInt64(); // Chunk number of previous listing chunk when reading - // directory in sequence (-1 if first listing chunk) - ReadUInt64(); // Chunk number of next listing chunk when reading - // directory in sequence (-1 if last listing chunk) - ReadUInt64(); // Number of first listing entry in this chunk - ReadUInt32(); // 1 (unknown -- other values have also been seen here) - ReadUInt32(); // 0 (unknown) - - unsigned numItems = 0; - for (;;) - { - UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; - UInt32 offsetLimit = dirChunkSize - quickrefLength; - if (offset > offsetLimit) - return S_FALSE; - if (offset == offsetLimit) - break; - if (database.NewFormat) - { - UInt16 nameLen = ReadUInt16(); - if (nameLen == 0) - return S_FALSE; - UString name; - ReadUString((unsigned)nameLen, name); - AString s; - ConvertUnicodeToUTF8(name, s); - Byte b = ReadByte(); - s.Add_Space(); - PrintByte(b, s); - s.Add_Space(); - UInt64 len = ReadEncInt(); - // then number of items ? - // then length ? - // then some data (binary encoding?) - while (len-- != 0) - { - b = ReadByte(); - PrintByte(b, s); - } - database.NewFormatString += s; - database.NewFormatString += "\r\n"; - } - else - { - RINOK(ReadDirEntry(database)); - } - numItems++; - } - Skip(quickrefLength - 2); - if (ReadUInt16() != numItems) - return S_FALSE; - if (numItems > numDirEntries) - return S_FALSE; - numDirEntries -= numItems; - } - else - Skip(dirChunkSize - 4); - } - return numDirEntries == 0 ? S_OK : S_FALSE; -} - -HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name) -{ - int index = database.FindItem(name); - if (index < 0) - return S_FALSE; - const CItem &item = database.Items[index]; - _chunkSize = item.Size; - return ReadChunk(inStream, database.ContentOffset + item.Offset, item.Size); -} - - -#define DATA_SPACE "::DataSpace/" -static const char *kNameList = DATA_SPACE "NameList"; -static const char *kStorage = DATA_SPACE "Storage/"; -static const char *kContent = "Content"; -static const char *kControlData = "ControlData"; -static const char *kSpanInfo = "SpanInfo"; -static const char *kTransform = "Transform/"; -static const char *kResetTable = "/InstanceData/ResetTable"; -static const char *kTransformList = "List"; - -static AString GetSectionPrefix(const AString &name) -{ - AString s = kStorage; - s += name; - s += '/'; - return s; -} - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param) -{ - const CObjectVector &items = *(const CObjectVector *)param; - const CItem &item1 = items[*p1]; - const CItem &item2 = items[*p2]; - bool isDir1 = item1.IsDir(); - bool isDir2 = item2.IsDir(); - if (isDir1 && !isDir2) - return -1; - if (isDir2) - { - if (!isDir1) - return 1; - } - else - { - RINOZ(MyCompare(item1.Section, item2.Section)); - RINOZ(MyCompare(item1.Offset, item2.Offset)); - RINOZ(MyCompare(item1.Size, item2.Size)); - } - return MyCompare(*p1, *p2); -} - -void CFilesDatabase::SetIndices() -{ - FOR_VECTOR (i, Items) - { - const CItem &item = Items[i]; - if (item.IsUserItem() && item.Name.Len() != 1) - Indices.Add(i); - } -} - -void CFilesDatabase::Sort() -{ - Indices.Sort(CompareFiles, (void *)&Items); -} - -bool CFilesDatabase::Check() -{ - UInt64 maxPos = 0; - UInt64 prevSection = 0; - FOR_VECTOR (i, Indices) - { - const CItem &item = Items[Indices[i]]; - if (item.Section == 0 || item.IsDir()) - continue; - if (item.Section != prevSection) - { - prevSection = item.Section; - maxPos = 0; - continue; - } - if (item.Offset < maxPos) - return false; - maxPos = item.Offset + item.Size; - if (maxPos < item.Offset) - return false; - } - return true; -} - -bool CFilesDatabase::CheckSectionRefs() -{ - FOR_VECTOR (i, Indices) - { - const CItem &item = Items[Indices[i]]; - if (item.Section == 0 || item.IsDir()) - continue; - if (item.Section >= Sections.Size()) - return false; - } - return true; -} - -static int inline GetLog(UInt32 num) -{ - for (int i = 0; i < 32; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - -HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) -{ - { - // The NameList file - RINOK(DecompressStream(inStream, database, kNameList)); - /* UInt16 length = */ ReadUInt16(); - UInt16 numSections = ReadUInt16(); - for (unsigned i = 0; i < numSections; i++) - { - CSectionInfo section; - UInt16 nameLen = ReadUInt16(); - UString name; - ReadUString(nameLen, name); - if (ReadUInt16() != 0) - return S_FALSE; - ConvertUnicodeToUTF8(name, section.Name); - // if (!ConvertUnicodeToUTF8(name, section.Name)) return S_FALSE; - database.Sections.Add(section); - } - } - - unsigned si; - for (si = 1; si < database.Sections.Size(); si++) - { - CSectionInfo §ion = database.Sections[si]; - AString sectionPrefix = GetSectionPrefix(section.Name); - { - // Content - int index = database.FindItem(sectionPrefix + kContent); - if (index < 0) - return S_FALSE; - const CItem &item = database.Items[index]; - section.Offset = item.Offset; - section.CompressedSize = item.Size; - } - AString transformPrefix = sectionPrefix + kTransform; - if (database.Help2Format) - { - // Transform List - RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); - if ((_chunkSize & 0xF) != 0) - return S_FALSE; - unsigned numGuids = (unsigned)(_chunkSize / 0x10); - if (numGuids < 1) - return S_FALSE; - for (unsigned i = 0; i < numGuids; i++) - { - CMethodInfo method; - ReadGUID(method.Guid); - section.Methods.Add(method); - } - } - else - { - CMethodInfo method; - method.Guid = kChmLzxGuid; - section.Methods.Add(method); - } - - { - // Control Data - RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)); - - FOR_VECTOR (mi, section.Methods) - { - CMethodInfo &method = section.Methods[mi]; - UInt32 numDWORDS = ReadUInt32(); - if (method.IsLzx()) - { - if (numDWORDS < 5) - return S_FALSE; - if (ReadUInt32() != kSignature_LZXC) - return S_FALSE; - CLzxInfo &li = method.LzxInfo; - li.Version = ReadUInt32(); - if (li.Version != 2 && li.Version != 3) - return S_FALSE; - - { - // There is bug in VC6, if we use function call as parameter for inline function - UInt32 val32 = ReadUInt32(); - int n = GetLog(val32); - if (n < 0 || n > 16) - return S_FALSE; - li.ResetIntervalBits = n; - } - - { - UInt32 val32 = ReadUInt32(); - int n = GetLog(val32); - if (n < 0 || n > 16) - return S_FALSE; - li.WindowSizeBits = n; - } - - li.CacheSize = ReadUInt32(); - numDWORDS -= 5; - while (numDWORDS-- != 0) - ReadUInt32(); - } - else - { - UInt32 numBytes = numDWORDS * 4; - method.ControlData.Alloc(numBytes); - ReadBytes(method.ControlData, numBytes); - } - } - } - - { - // SpanInfo - RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)); - section.UncompressedSize = ReadUInt64(); - } - - // read ResetTable for LZX - FOR_VECTOR (mi, section.Methods) - { - CMethodInfo &method = section.Methods[mi]; - if (method.IsLzx()) - { - // ResetTable; - RINOK(DecompressStream(inStream, database, transformPrefix + - method.GetGuidString() + kResetTable)); - CResetTable &rt = method.LzxInfo.ResetTable; - - if (_chunkSize < 4) - { - if (_chunkSize != 0) - return S_FALSE; - // ResetTable is empty in .chw files - if (section.UncompressedSize != 0) - return S_FALSE; - rt.UncompressedSize = 0; - rt.CompressedSize = 0; - // rt.BlockSize = 0; - } - else - { - UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) - if (ver != 2 && ver != 3) - return S_FALSE; - UInt32 numEntries = ReadUInt32(); - const unsigned kEntrySize = 8; - if (ReadUInt32() != kEntrySize) - return S_FALSE; - const unsigned kRtHeaderSize = 4 * 4 + 8 * 3; - if (ReadUInt32() != kRtHeaderSize) - return S_FALSE; - if (kRtHeaderSize + kEntrySize * (UInt64)numEntries != _chunkSize) - return S_FALSE; - - rt.UncompressedSize = ReadUInt64(); - rt.CompressedSize = ReadUInt64(); - UInt64 blockSize = ReadUInt64(); - if (blockSize != kBlockSize) - return S_FALSE; - UInt64 numBlocks = (rt.UncompressedSize + kBlockSize + 1) / kBlockSize; - if (numEntries != numBlocks && - numEntries != numBlocks + 1) - return S_FALSE; - - rt.ResetOffsets.ClearAndReserve(numEntries); - - for (UInt32 i = 0; i < numEntries; i++) - { - UInt64 v = ReadUInt64(); - if (i != 0 && v < rt.ResetOffsets[i - 1]) - return S_FALSE; - rt.ResetOffsets.AddInReserved(v); - } - - if (numEntries != 0) - if (rt.ResetOffsets[0] != 0) - return S_FALSE; - - if (numEntries == numBlocks + 1) - { - // Lazarus 9-26-2 chm contains additional entty - if (rt.ResetOffsets.Back() != rt.CompressedSize) - return S_FALSE; - } - } - } - } - } - - database.SetIndices(); - database.Sort(); - return database.Check() ? S_OK : S_FALSE; -} - -HRESULT CInArchive::Open2(IInStream *inStream, - const UInt64 *searchHeaderSizeLimit, - CFilesDatabase &database) -{ - IsArc = false; - HeadersError = false; - UnexpectedEnd = false; - UnsupportedFeature = false; - - database.Clear(); - database.Help2Format = _help2; - const UInt32 chmVersion = 3; - - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); - - if (!_inBuffer.Create(1 << 14)) - return E_OUTOFMEMORY; - _inBuffer.SetStream(inStream); - _inBuffer.Init(); - - if (_help2) - { - const unsigned kSignatureSize = 8; - const UInt64 signature = ((UInt64)kSignature_ITLS << 32) | kSignature_ITOL; - UInt64 limit = 1 << 18; - - if (searchHeaderSizeLimit) - if (limit > *searchHeaderSizeLimit) - limit = *searchHeaderSizeLimit; - - UInt64 val = 0; - - for (;;) - { - Byte b; - if (!_inBuffer.ReadByte(b)) - return S_FALSE; - val >>= 8; - val |= ((UInt64)b) << ((kSignatureSize - 1) * 8); - if (_inBuffer.GetProcessedSize() >= kSignatureSize) - { - if (val == signature) - break; - if (_inBuffer.GetProcessedSize() > limit) - return S_FALSE; - } - } - - database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize; - RINOK(OpenHelp2(inStream, database)); - if (database.NewFormat) - return S_OK; - } - else - { - if (ReadUInt32() != kSignature_ITSF) - return S_FALSE; - if (ReadUInt32() != chmVersion) - return S_FALSE; - RINOK(OpenChm(inStream, database)); - } - - - #ifndef CHM_LOW - - try - { - try - { - HRESULT res = OpenHighLevel(inStream, database); - if (res == S_FALSE) - { - UnsupportedFeature = true; - database.HighLevelClear(); - return S_OK; - } - RINOK(res); - if (!database.CheckSectionRefs()) - HeadersError = true; - database.LowLevel = false; - } - catch(...) - { - database.HighLevelClear(); - throw; - } - } - // catch(const CInBufferException &e) { return e.ErrorCode; } - catch(CEnexpectedEndException &) { UnexpectedEnd = true; } - catch(CHeaderErrorException &) { HeadersError = true; } - catch(...) { throw; } - - #endif - - return S_OK; -} - -HRESULT CInArchive::Open(IInStream *inStream, - const UInt64 *searchHeaderSizeLimit, - CFilesDatabase &database) -{ - try - { - try - { - HRESULT res = Open2(inStream, searchHeaderSizeLimit, database); - m_InStreamRef.Release(); - return res; - } - catch(...) - { - m_InStreamRef.Release(); - throw; - } - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(CEnexpectedEndException &) { UnexpectedEnd = true; } - catch(CHeaderErrorException &) { HeadersError = true; } - return S_FALSE; -} - -}} +// Archive/ChmIn.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/UTFConvert.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" + +#include "ChmIn.h" + +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +namespace NArchive { +namespace NChm { + +static const UInt32 kSignature_ITSP = 0x50535449; +static const UInt32 kSignature_PMGL = 0x4C474D50; +static const UInt32 kSignature_LZXC = 0x43585A4C; + +static const UInt32 kSignature_IFCM = 0x4D434649; +static const UInt32 kSignature_AOLL = 0x4C4C4F41; +static const UInt32 kSignature_CAOL = 0x4C4F4143; + +static const UInt32 kSignature_ITSF = 0x46535449; +static const UInt32 kSignature_ITOL = 0x4C4F5449; +static const UInt32 kSignature_ITLS = 0x534C5449; + +struct CEnexpectedEndException {}; +struct CHeaderErrorException {}; + +// define CHM_LOW, if you want to see low level items +// #define CHM_LOW + +static const Byte kChmLzxGuid[16] = { 0x40, 0x89, 0xC2, 0x7F, 0x31, 0x9D, 0xD0, 0x11, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C }; +static const Byte kHelp2LzxGuid[16] = { 0xC6, 0x07, 0x90, 0x0A, 0x76, 0x40, 0xD3, 0x11, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 }; +static const Byte kDesGuid[16] = { 0xA2, 0xE4, 0xF6, 0x67, 0xBF, 0x60, 0xD3, 0x11, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF }; + +static bool inline AreGuidsEqual(const Byte *g1, const Byte *g2) +{ + return memcmp(g1, g2, 16) == 0; +} + +static void PrintByte(unsigned b, AString &s) +{ + s += (char)GET_HEX_CHAR_UPPER(b >> 4); + s += (char)GET_HEX_CHAR_LOWER(b & 0xF); +} + +AString CMethodInfo::GetGuidString() const +{ + char s[16 * 2 + 8]; + RawLeGuidToString_Braced(Guid, s); + // MyStringUpper_Ascii(s); + return (AString)s; +} + +bool CMethodInfo::IsLzx() const +{ + if (AreGuidsEqual(Guid, kChmLzxGuid)) + return true; + return AreGuidsEqual(Guid, kHelp2LzxGuid); +} + +bool CMethodInfo::IsDes() const +{ + return AreGuidsEqual(Guid, kDesGuid); +} + +AString CMethodInfo::GetName() const +{ + AString s; + if (IsLzx()) + { + s = "LZX:"; + s.Add_UInt32(LzxInfo.GetNumDictBits()); + } + else + { + if (IsDes()) + s = "DES"; + else + { + s = GetGuidString(); + /* + if (ControlData.Size() > 0 && ControlData.Size() <= (1 << 6)) + { + s.Add_Colon(); + for (size_t i = 0; i < ControlData.Size(); i++) + PrintByte(ControlData[i], s); + } + */ + } + } + return s; +} + +bool CSectionInfo::IsLzx() const +{ + if (Methods.Size() != 1) + return false; + return Methods[0].IsLzx(); +} + +UString CSectionInfo::GetMethodName() const +{ + UString s; + if (!IsLzx()) + { + UString temp; + ConvertUTF8ToUnicode(Name, temp); + s += temp; + s += ": "; + } + FOR_VECTOR (i, Methods) + { + if (i != 0) + s.Add_Space(); + s += Methods[i].GetName(); + } + return s; +} + +Byte CInArchive::ReadByte() +{ + Byte b; + if (!_inBuffer.ReadByte(b)) + throw CEnexpectedEndException(); + return b; +} + +void CInArchive::Skip(size_t size) +{ + if (_inBuffer.Skip(size) != size) + throw CEnexpectedEndException(); +} + +void CInArchive::ReadBytes(Byte *data, UInt32 size) +{ + if (_inBuffer.ReadBytes(data, size) != size) + throw CEnexpectedEndException(); +} + +UInt16 CInArchive::ReadUInt16() +{ + Byte b0, b1; + if (!_inBuffer.ReadByte(b0)) throw CEnexpectedEndException(); + if (!_inBuffer.ReadByte(b1)) throw CEnexpectedEndException(); + return (UInt16)(((UInt16)b1 << 8) | b0); +} + +UInt32 CInArchive::ReadUInt32() +{ + Byte p[4]; + ReadBytes(p, 4); + return Get32(p); +} + +UInt64 CInArchive::ReadUInt64() +{ + Byte p[8]; + ReadBytes(p, 8); + return Get64(p); +} + +UInt64 CInArchive::ReadEncInt() +{ + UInt64 val = 0; + for (int i = 0; i < 9; i++) + { + const unsigned b = ReadByte(); + val |= (b & 0x7F); + if (b < 0x80) + return val; + val <<= 7; + } + throw CHeaderErrorException(); +} + +void CInArchive::ReadGUID(Byte *g) +{ + ReadBytes(g, 16); +} + +void CInArchive::ReadString(unsigned size, AString &s) +{ + s.Empty(); + if (size != 0) + { + ReadBytes((Byte *)s.GetBuf(size), size); + s.ReleaseBuf_CalcLen(size); + } +} + +void CInArchive::ReadUString(unsigned size, UString &s) +{ + s.Empty(); + while (size-- != 0) + { + const wchar_t c = ReadUInt16(); + if (c == 0) + { + Skip(2 * size); + return; + } + s += c; + } +} + +HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size) +{ + RINOK(InStream_SeekSet(inStream, pos)) + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr limitedStream(streamSpec); + streamSpec->SetStream(inStream); + streamSpec->Init(size); + m_InStreamRef = limitedStream; + _inBuffer.SetStream(limitedStream); + _inBuffer.Init(); + return S_OK; +} + +HRESULT CInArchive::ReadDirEntry(CDatabase &database) +{ + CItem item; + const UInt64 nameLen = ReadEncInt(); + if (nameLen == 0 || nameLen > (1 << 13)) + return S_FALSE; + ReadString((unsigned)nameLen, item.Name); + item.Section = ReadEncInt(); + item.Offset = ReadEncInt(); + item.Size = ReadEncInt(); + database.Items.Add(item); + return S_OK; +} + +HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) +{ + UInt32 headerSize = ReadUInt32(); + if (headerSize != 0x60) + return S_FALSE; + database.PhySize = headerSize; + + UInt32 unknown1 = ReadUInt32(); + if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file + return S_FALSE; + + IsArc = true; + + /* UInt32 timeStamp = */ ReadUInt32(); + // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and + // fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional bits. + // The 4 least significant bits in the last byte are constant. + /* UInt32 lang = */ ReadUInt32(); + Byte g[16]; + ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} + ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} + const unsigned kNumSections = 2; + UInt64 sectionOffsets[kNumSections]; + UInt64 sectionSizes[kNumSections]; + unsigned i; + for (i = 0; i < kNumSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + UInt64 end = sectionOffsets[i] + sectionSizes[i]; + database.UpdatePhySize(end); + } + // if (chmVersion == 3) + database.ContentOffset = ReadUInt64(); + /* + else + database.ContentOffset = database.StartPosition + 0x58 + */ + + // Section 0 + ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] < 0x18) + return S_FALSE; + if (ReadUInt32() != 0x01FE) + return S_FALSE; + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + database.UpdatePhySize(fileSize); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + + // Section 1: The Directory Listing + ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != kSignature_ITSP) + return S_FALSE; + if (ReadUInt32() != 1) // version + return S_FALSE; + /* UInt32 dirHeaderSize = */ ReadUInt32(); + ReadUInt32(); // 0x0A (unknown) + UInt32 dirChunkSize = ReadUInt32(); // $1000 + if (dirChunkSize < 32) + return S_FALSE; + /* UInt32 density = */ ReadUInt32(); // "Density" of quickref section, usually 2. + /* UInt32 depth = */ ReadUInt32(); // Depth of the index tree: 1 there is no index, + // 2 if there is one level of PMGI chunks. + + /* UInt32 chunkNumber = */ ReadUInt32(); // Chunk number of root index chunk, -1 if there is none + // (though at least one file has 0 despite there being no + // index chunk, probably a bug.) + /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk + /* UInt32 lastPmglChunkNumber = */ ReadUInt32(); // Chunk number of last PMGL (listing) chunk + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) + /* UInt32 windowsLangId = */ ReadUInt32(); + ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} + ReadUInt32(); // 0x54 (This is the length again) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == kSignature_PMGL) + { + // The quickref area is written backwards from the end of the chunk. + // One quickref entry exists for every n entries in the file, where n + // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. + + const UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt32(); // Always 0 + ReadUInt32(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if this is the first listing chunk) + ReadUInt32(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if this is the last listing chunk) + unsigned numItems = 0; + + for (;;) + { + const UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + const UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + RINOK(ReadDirEntry(database)) + numItems++; + } + + Skip(quickrefLength - 2); + + const unsigned rrr = ReadUInt16(); + if (rrr != numItems) + { + // Lazarus 9-26-2 chm contains 0 here. + if (rrr != 0) + return S_FALSE; + } + } + else + Skip(dirChunkSize - 4); + } + return S_OK; +} + +HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) +{ + if (ReadUInt32() != 1) // version + return S_FALSE; + if (ReadUInt32() != 0x28) // Location of header section table + return S_FALSE; + UInt32 numHeaderSections = ReadUInt32(); + const unsigned kNumHeaderSectionsMax = 5; + if (numHeaderSections != kNumHeaderSectionsMax) + return S_FALSE; + + IsArc = true; + + ReadUInt32(); // Len of post-header table + Byte g[16]; + ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} + + // header section table + UInt64 sectionOffsets[kNumHeaderSectionsMax]; + UInt64 sectionSizes[kNumHeaderSectionsMax]; + UInt32 i; + for (i = 0; i < numHeaderSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + UInt64 end = sectionOffsets[i] + sectionSizes[i]; + database.UpdatePhySize(end); + } + + // Post-Header + ReadUInt32(); // 2 + ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) + // ----- Directory information + ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 + ReadUInt64(); // Chunk number of first AOLL chunk in directory + ReadUInt64(); // Chunk number of last AOLL chunk in directory + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // Quickref density for main directory, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of main directory index tree + // 1 there is no index, 2 if there is one level of AOLI chunks. + ReadUInt64(); // 0 (unknown) + UInt64 numDirEntries = ReadUInt64(); // Number of directory entries + // ----- Directory Index Information + ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) + ReadUInt64(); // Chunk number of first AOLL chunk in directory index + ReadUInt64(); // Chunk number of last AOLL chunk in directory index + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // Quickref density for directory index, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of directory index index tree. + ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. + ReadUInt64(); // Number of directory index entries (same as number of AOLL + // chunks in main directory) + + // (The obvious guess for the following two fields, which recur in a number + // of places, is they are maximum sizes for the directory and directory index. + // However, I have seen no direct evidence that this is the case.) + + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + + ReadUInt64(); // 0 (unknown) + if (ReadUInt32() != kSignature_CAOL) + return S_FALSE; + if (ReadUInt32() != 2) // (Most likely a version number) + return S_FALSE; + UInt32 caolLength = ReadUInt32(); // $50 (Len of the CAOL section, which includes the ITSF section) + if (caolLength >= 0x2C) + { + /* UInt32 c7 = */ ReadUInt16(); // Unknown. Remains the same when identical files are built. + // Does not appear to be a checksum. Many files have + // 'HH' (HTML Help?) here, indicating this may be a compiler ID + // field. But at least one ITOL/ITLS compiler does not set this + // field to a constant value. + ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) + ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // 0 (Unknown) + if (caolLength == 0x2C) + { + // fprintf(stdout, "\n !!!NewFormat\n"); + // fflush(stdout); + database.ContentOffset = 0; // maybe we must add database.StartPosition here? + database.NewFormat = true; + } + else if (caolLength == 0x50) + { + ReadUInt32(); // 0 (Unknown) + if (ReadUInt32() != kSignature_ITSF) + return S_FALSE; + if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) + return S_FALSE; + if (ReadUInt32() != 0x20) // $20 (length of ITSF) + return S_FALSE; + UInt32 unknown = ReadUInt32(); + if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; + return S_FALSE; + database.ContentOffset = database.StartPosition + ReadUInt64(); + /* UInt32 timeStamp = */ ReadUInt32(); + // A timestamp of some sort. + // Considered as a big-endian DWORD, it appears to contain + // seconds (MSB) and fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional + // bits. The 4 least significant bits in the last byte are constant. + /* UInt32 lang = */ ReadUInt32(); // BE? + } + else + return S_FALSE; + } + + // Section 0 + ReadChunk(inStream, database.StartPosition + sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] < 0x18) + return S_FALSE; + if (ReadUInt32() != 0x01FE) + return S_FALSE; + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + database.UpdatePhySize(fileSize); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + + // Section 1: The Directory Listing + ReadChunk(inStream, database.StartPosition + sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != kSignature_IFCM) + return S_FALSE; + if (ReadUInt32() != 1) // (probably a version number) + return S_FALSE; + UInt32 dirChunkSize = ReadUInt32(); // $2000 + if (dirChunkSize < 64) + return S_FALSE; + ReadUInt32(); // $100000 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); + ReadUInt32(); // 0 (unknown, probably high word of above) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == kSignature_AOLL) + { + UInt32 quickrefLength = ReadUInt32(); // Len of quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt64(); // Directory chunk number + // This must match physical position in file, that is + // the chunk size times the chunk number must be the + // offset from the end of the directory header. + ReadUInt64(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if first listing chunk) + ReadUInt64(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if last listing chunk) + ReadUInt64(); // Number of first listing entry in this chunk + ReadUInt32(); // 1 (unknown -- other values have also been seen here) + ReadUInt32(); // 0 (unknown) + + unsigned numItems = 0; + for (;;) + { + const UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + const UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + if (database.NewFormat) + { + const unsigned nameLen = ReadUInt16(); + if (nameLen == 0) + return S_FALSE; + UString name; + ReadUString(nameLen, name); + AString s; + ConvertUnicodeToUTF8(name, s); + { + const unsigned b = ReadByte(); + s.Add_Space(); + PrintByte(b, s); + } + s.Add_Space(); + UInt64 len = ReadEncInt(); + // then number of items ? + // then length ? + // then some data (binary encoding?) + if (len > 1u << 29) // what limit here we need? + return S_FALSE; + if (len) + do + { + const unsigned b = ReadByte(); + PrintByte(b, s); + } + while (--len); + database.NewFormatString += s; + database.NewFormatString += "\r\n"; + } + else + { + RINOK(ReadDirEntry(database)) + } + numItems++; + } + Skip(quickrefLength - 2); + if (ReadUInt16() != numItems) + return S_FALSE; + if (numItems > numDirEntries) + return S_FALSE; + numDirEntries -= numItems; + } + else + Skip(dirChunkSize - 4); + } + return numDirEntries == 0 ? S_OK : S_FALSE; +} + +HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name) +{ + int index = database.FindItem(name); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + _chunkSize = item.Size; + return ReadChunk(inStream, database.ContentOffset + item.Offset, item.Size); +} + + +#define DATA_SPACE "::DataSpace/" +#define kNameList DATA_SPACE "NameList" +#define kStorage DATA_SPACE "Storage/" +#define kContent "Content" +#define kControlData "ControlData" +#define kSpanInfo "SpanInfo" +#define kTransform "Transform/" +#define kResetTable "/InstanceData/ResetTable" +#define kTransformList "List" + +static AString GetSectionPrefix(const AString &name) +{ + AString s (kStorage); + s += name; + s.Add_Slash(); + return s; +} + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + +static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + const CItem &item1 = items[*p1]; + const CItem &item2 = items[*p2]; + bool isDir1 = item1.IsDir(); + bool isDir2 = item2.IsDir(); + if (isDir1 && !isDir2) + return -1; + if (isDir2) + { + if (!isDir1) + return 1; + } + else + { + RINOZ(MyCompare(item1.Section, item2.Section)) + RINOZ(MyCompare(item1.Offset, item2.Offset)) + RINOZ(MyCompare(item1.Size, item2.Size)) + } + return MyCompare(*p1, *p2); +} + +void CFilesDatabase::SetIndices() +{ + FOR_VECTOR (i, Items) + { + const CItem &item = Items[i]; + if (item.IsUserItem() && item.Name.Len() != 1) + Indices.Add(i); + } +} + +void CFilesDatabase::Sort() +{ + Indices.Sort(CompareFiles, (void *)&Items); +} + +bool CFilesDatabase::Check() +{ + UInt64 maxPos = 0; + UInt64 prevSection = 0; + FOR_VECTOR (i, Indices) + { + const CItem &item = Items[Indices[i]]; + if (item.Section == 0 || item.IsDir()) + continue; + if (item.Section != prevSection) + { + prevSection = item.Section; + maxPos = 0; + continue; + } + if (item.Offset < maxPos) + return false; + maxPos = item.Offset + item.Size; + if (maxPos < item.Offset) + return false; + } + return true; +} + +bool CFilesDatabase::CheckSectionRefs() +{ + FOR_VECTOR (i, Indices) + { + const CItem &item = Items[Indices[i]]; + if (item.Section == 0 || item.IsDir()) + continue; + if (item.Section >= Sections.Size()) + return false; + } + return true; +} + +static int inline GetLog(UInt32 num) +{ + for (int i = 0; i < 32; i++) + if (((UInt32)1 << i) == num) + return i; + return -1; +} + +HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) +{ + { + // The NameList file + RINOK(DecompressStream(inStream, database, (AString)kNameList)) + /* UInt16 length = */ ReadUInt16(); + UInt16 numSections = ReadUInt16(); + for (unsigned i = 0; i < numSections; i++) + { + CSectionInfo section; + const unsigned nameLen = ReadUInt16(); + UString name; + ReadUString(nameLen, name); + if (ReadUInt16() != 0) + return S_FALSE; + ConvertUnicodeToUTF8(name, section.Name); + // if (!ConvertUnicodeToUTF8(name, section.Name)) return S_FALSE; + database.Sections.Add(section); + } + } + + unsigned si; + for (si = 1; si < database.Sections.Size(); si++) + { + CSectionInfo §ion = database.Sections[si]; + AString sectionPrefix (GetSectionPrefix(section.Name)); + { + // Content + int index = database.FindItem(sectionPrefix + kContent); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + section.Offset = item.Offset; + section.CompressedSize = item.Size; + } + AString transformPrefix (sectionPrefix + kTransform); + if (database.Help2Format) + { + // Transform List + RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)) + if ((_chunkSize & 0xF) != 0) + return S_FALSE; + unsigned numGuids = (unsigned)(_chunkSize / 0x10); + if (numGuids < 1) + return S_FALSE; + for (unsigned i = 0; i < numGuids; i++) + { + CMethodInfo method; + ReadGUID(method.Guid); + section.Methods.Add(method); + } + } + else + { + CMethodInfo method; + memcpy(method.Guid, kChmLzxGuid, 16); + section.Methods.Add(method); + } + + { + // Control Data + RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)) + + FOR_VECTOR (mi, section.Methods) + { + CMethodInfo &method = section.Methods[mi]; + UInt32 numDWORDS = ReadUInt32(); + if (method.IsLzx()) + { + if (numDWORDS < 5) + return S_FALSE; + if (ReadUInt32() != kSignature_LZXC) + return S_FALSE; + CLzxInfo &li = method.LzxInfo; + li.Version = ReadUInt32(); + if (li.Version != 2 && li.Version != 3) + return S_FALSE; + + { + // There is bug in VC6, if we use function call as parameter for inline function + const UInt32 val32 = ReadUInt32(); + const int n = GetLog(val32); + if (n < 0 || n > 16) + return S_FALSE; + li.ResetIntervalBits = (unsigned)n; + } + + { + const UInt32 val32 = ReadUInt32(); + const int n = GetLog(val32); + if (n < 0 || n > 16) + return S_FALSE; + li.WindowSizeBits = (unsigned)n; + } + + li.CacheSize = ReadUInt32(); + numDWORDS -= 5; + if (numDWORDS) + do + ReadUInt32(); + while (--numDWORDS); + } + else + { + if (numDWORDS > 1u << 27) + return S_FALSE; + const size_t numBytes = (size_t)numDWORDS * 4; + // method.ControlData.Alloc(numBytes); + // ReadBytes(method.ControlData, numBytes); + Skip(numBytes); + } + } + } + + { + // SpanInfo + RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)) + section.UncompressedSize = ReadUInt64(); + } + + // read ResetTable for LZX + FOR_VECTOR (mi, section.Methods) + { + CMethodInfo &method = section.Methods[mi]; + if (method.IsLzx()) + { + // ResetTable; + RINOK(DecompressStream(inStream, database, transformPrefix + + method.GetGuidString() + kResetTable)) + CResetTable &rt = method.LzxInfo.ResetTable; + + if (_chunkSize < 4) + { + if (_chunkSize != 0) + return S_FALSE; + // ResetTable is empty in .chw files + if (section.UncompressedSize != 0) + return S_FALSE; + rt.UncompressedSize = 0; + rt.CompressedSize = 0; + // rt.BlockSize = 0; + } + else + { + const UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) + if (ver != 2 && ver != 3) + return S_FALSE; + const UInt32 numEntries = ReadUInt32(); + const unsigned kEntrySize = 8; + if (ReadUInt32() != kEntrySize) + return S_FALSE; + const unsigned kRtHeaderSize = 4 * 4 + 8 * 3; + if (ReadUInt32() != kRtHeaderSize) + return S_FALSE; + if (kRtHeaderSize + kEntrySize * (UInt64)numEntries != _chunkSize) + return S_FALSE; + + rt.UncompressedSize = ReadUInt64(); + rt.CompressedSize = ReadUInt64(); + UInt64 blockSize = ReadUInt64(); + if (blockSize != kBlockSize) + return S_FALSE; + UInt64 numBlocks = (rt.UncompressedSize + kBlockSize + 1) / kBlockSize; + if (numEntries != numBlocks && + numEntries != numBlocks + 1) + return S_FALSE; + + rt.ResetOffsets.ClearAndReserve(numEntries); + + for (UInt32 i = 0; i < numEntries; i++) + { + UInt64 v = ReadUInt64(); + if (i != 0 && v < rt.ResetOffsets[i - 1]) + return S_FALSE; + rt.ResetOffsets.AddInReserved(v); + } + + if (numEntries != 0) + if (rt.ResetOffsets[0] != 0) + return S_FALSE; + + if (numEntries == numBlocks + 1) + { + // Lazarus 9-26-2 chm contains additional entty + if (rt.ResetOffsets.Back() != rt.CompressedSize) + return S_FALSE; + } + } + } + } + } + + database.SetIndices(); + database.Sort(); + return database.Check() ? S_OK : S_FALSE; +} + +HRESULT CInArchive::Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + IsArc = false; + HeadersError = false; + UnexpectedEnd = false; + UnsupportedFeature = false; + + database.Clear(); + database.Help2Format = _help2; + const UInt32 chmVersion = 3; + + RINOK(InStream_GetPos(inStream, database.StartPosition)) + + if (!_inBuffer.Create(1 << 14)) + return E_OUTOFMEMORY; + _inBuffer.SetStream(inStream); + _inBuffer.Init(); + + if (_help2) + { + const unsigned kSignatureSize = 8; + const UInt64 signature = ((UInt64)kSignature_ITLS << 32) | kSignature_ITOL; + UInt64 limit = 1 << 18; + + if (searchHeaderSizeLimit) + if (limit > *searchHeaderSizeLimit) + limit = *searchHeaderSizeLimit; + + UInt64 val = 0; + + for (;;) + { + Byte b; + if (!_inBuffer.ReadByte(b)) + return S_FALSE; + val >>= 8; + val |= ((UInt64)b) << ((kSignatureSize - 1) * 8); + if (_inBuffer.GetProcessedSize() >= kSignatureSize) + { + if (val == signature) + break; + if (_inBuffer.GetProcessedSize() > limit) + return S_FALSE; + } + } + + database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize; + RINOK(OpenHelp2(inStream, database)) + if (database.NewFormat) + return S_OK; + } + else + { + if (ReadUInt32() != kSignature_ITSF) + return S_FALSE; + if (ReadUInt32() != chmVersion) + return S_FALSE; + RINOK(OpenChm(inStream, database)) + } + + + #ifndef CHM_LOW + + try + { + try + { + HRESULT res = OpenHighLevel(inStream, database); + if (res == S_FALSE) + { + UnsupportedFeature = true; + database.HighLevelClear(); + return S_OK; + } + RINOK(res) + if (!database.CheckSectionRefs()) + HeadersError = true; + database.LowLevel = false; + } + catch(...) + { + database.HighLevelClear(); + throw; + } + } + // catch(const CInBufferException &e) { return e.ErrorCode; } + catch(CEnexpectedEndException &) { UnexpectedEnd = true; } + catch(CHeaderErrorException &) { HeadersError = true; } + catch(...) { throw; } + + #endif + + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + try + { + try + { + HRESULT res = Open2(inStream, searchHeaderSizeLimit, database); + m_InStreamRef.Release(); + return res; + } + catch(...) + { + m_InStreamRef.Release(); + throw; + } + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(CEnexpectedEndException &) { UnexpectedEnd = true; } + catch(CHeaderErrorException &) { HeadersError = true; } + return S_FALSE; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Chm/ChmIn.h 2016-05-20 08:20:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/ChmIn.h 2024-01-01 08:00:00.000000000 +0000 @@ -1,270 +1,282 @@ -// Archive/ChmIn.h - -#ifndef __ARCHIVE_CHM_IN_H -#define __ARCHIVE_CHM_IN_H - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyString.h" - -#include "../../IStream.h" - -#include "../../Common/InBuffer.h" - -namespace NArchive { -namespace NChm { - -struct CItem -{ - UInt64 Section; - UInt64 Offset; - UInt64 Size; - AString Name; - - bool IsFormatRelatedItem() const - { - if (Name.Len() < 2) - return false; - return Name[0] == ':' && Name[1] == ':'; - } - - bool IsUserItem() const - { - if (Name.Len() < 2) - return false; - return Name[0] == '/'; - } - - bool IsDir() const - { - if (Name.IsEmpty()) - return false; - return (Name.Back() == '/'); - } -}; - - -struct CDatabase -{ - UInt64 StartPosition; - UInt64 ContentOffset; - CObjectVector Items; - AString NewFormatString; - bool Help2Format; - bool NewFormat; - UInt64 PhySize; - - void UpdatePhySize(UInt64 v) { if (PhySize < v) PhySize = v; } - - int FindItem(const AString &name) const - { - FOR_VECTOR (i, Items) - if (Items[i].Name == name) - return i; - return -1; - } - - void Clear() - { - NewFormat = false; - NewFormatString.Empty(); - Help2Format = false; - Items.Clear(); - StartPosition = 0; - PhySize = 0; - } -}; - - -const UInt32 kBlockSize = 1 << 15; - -struct CResetTable -{ - UInt64 UncompressedSize; - UInt64 CompressedSize; - // unsigned BlockSizeBits; - CRecordVector ResetOffsets; - - bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const - { - if (blockIndex >= ResetOffsets.Size()) - return false; - UInt64 startPos = ResetOffsets[(unsigned)blockIndex]; - if (blockIndex + numBlocks >= ResetOffsets.Size()) - size = CompressedSize - startPos; - else - size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos; - return true; - } - - bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const - { - return GetCompressedSizeOfBlocks(blockIndex, 1, size); - } - - UInt64 GetNumBlocks(UInt64 size) const - { - return (size + kBlockSize - 1) / kBlockSize; - } -}; - - -struct CLzxInfo -{ - UInt32 Version; - - unsigned ResetIntervalBits; - unsigned WindowSizeBits; - UInt32 CacheSize; - - CResetTable ResetTable; - - unsigned GetNumDictBits() const - { - if (Version == 2 || Version == 3) - return 15 + WindowSizeBits; - return 0; - } - - UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; } - UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); } - UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); } - UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; } - - bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const - { - UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); - if (blockIndex >= ResetTable.ResetOffsets.Size()) - return false; - offset = ResetTable.ResetOffsets[(unsigned)blockIndex]; - return true; - } - - bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const - { - UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); - return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size); - } -}; - - -struct CMethodInfo -{ - GUID Guid; - CByteBuffer ControlData; - CLzxInfo LzxInfo; - - bool IsLzx() const; - bool IsDes() const; - AString GetGuidString() const; - UString GetName() const; -}; - - -struct CSectionInfo -{ - UInt64 Offset; - UInt64 CompressedSize; - UInt64 UncompressedSize; - - AString Name; - CObjectVector Methods; - - bool IsLzx() const; - UString GetMethodName() const; -}; - -class CFilesDatabase: public CDatabase -{ -public: - bool LowLevel; - CUIntVector Indices; - CObjectVector Sections; - - UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; } - UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; } - - UInt64 GetFolder(unsigned fileIndex) const - { - const CItem &item = Items[Indices[fileIndex]]; - if (item.Section < Sections.Size()) - { - const CSectionInfo §ion = Sections[(unsigned)item.Section]; - if (section.IsLzx()) - return section.Methods[0].LzxInfo.GetFolder(item.Offset); - } - return 0; - } - - UInt64 GetLastFolder(unsigned fileIndex) const - { - const CItem &item = Items[Indices[fileIndex]]; - if (item.Section < Sections.Size()) - { - const CSectionInfo §ion = Sections[(unsigned)item.Section]; - if (section.IsLzx()) - return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1); - } - return 0; - } - - void HighLevelClear() - { - LowLevel = true; - Indices.Clear(); - Sections.Clear(); - } - - void Clear() - { - CDatabase::Clear(); - HighLevelClear(); - } - - void SetIndices(); - void Sort(); - bool Check(); - bool CheckSectionRefs(); -}; - - -class CInArchive -{ - CMyComPtr m_InStreamRef; - ::CInBuffer _inBuffer; - UInt64 _chunkSize; - bool _help2; - - Byte ReadByte(); - void ReadBytes(Byte *data, UInt32 size); - void Skip(size_t size); - UInt16 ReadUInt16(); - UInt32 ReadUInt32(); - UInt64 ReadUInt64(); - UInt64 ReadEncInt(); - void ReadString(unsigned size, AString &s); - void ReadUString(unsigned size, UString &s); - void ReadGUID(GUID &g); - - HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size); - - HRESULT ReadDirEntry(CDatabase &database); - HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name); - -public: - bool IsArc; - bool HeadersError; - bool UnexpectedEnd; - bool UnsupportedFeature; - - CInArchive(bool help2) { _help2 = help2; } - - HRESULT OpenChm(IInStream *inStream, CDatabase &database); - HRESULT OpenHelp2(IInStream *inStream, CDatabase &database); - HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database); - HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); - HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); -}; - -}} - -#endif +// Archive/ChmIn.h + +#ifndef ZIP7_INC_ARCHIVE_CHM_IN_H +#define ZIP7_INC_ARCHIVE_CHM_IN_H + +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyString.h" + +#include "../../IStream.h" + +#include "../../Common/InBuffer.h" + +namespace NArchive { +namespace NChm { + +struct CItem +{ + UInt64 Section; + UInt64 Offset; + UInt64 Size; + AString Name; + + bool IsFormatRelatedItem() const + { + if (Name.Len() < 2) + return false; + return Name[0] == ':' && Name[1] == ':'; + } + + bool IsUserItem() const + { + if (Name.Len() < 2) + return false; + return Name[0] == '/'; + } + + bool IsDir() const + { + if (Name.IsEmpty()) + return false; + return (Name.Back() == '/'); + } +}; + + +struct CDatabase +{ + CObjectVector Items; + UInt64 StartPosition; + UInt64 ContentOffset; + AString NewFormatString; + bool Help2Format; + bool NewFormat; + UInt64 PhySize; + + void UpdatePhySize(UInt64 v) { if (PhySize < v) PhySize = v; } + + int FindItem(const AString &name) const + { + FOR_VECTOR (i, Items) + if (Items[i].Name == name) + return (int)i; + return -1; + } + + void Clear() + { + NewFormat = false; + NewFormatString.Empty(); + Help2Format = false; + Items.Clear(); + StartPosition = 0; + PhySize = 0; + } +}; + + +const UInt32 kBlockSize = 1 << 15; + +struct CResetTable +{ + UInt64 UncompressedSize; + UInt64 CompressedSize; + // unsigned BlockSizeBits; + CRecordVector ResetOffsets; + + CResetTable(): + UncompressedSize(0), + CompressedSize(0) + {} + + bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const + { + if (blockIndex >= ResetOffsets.Size()) + return false; + UInt64 startPos = ResetOffsets[(unsigned)blockIndex]; + if (blockIndex + numBlocks >= ResetOffsets.Size()) + size = CompressedSize - startPos; + else + size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos; + return true; + } + + bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const + { + return GetCompressedSizeOfBlocks(blockIndex, 1, size); + } + + UInt64 GetNumBlocks(UInt64 size) const + { + return (size + kBlockSize - 1) / kBlockSize; + } +}; + + +struct CLzxInfo +{ + UInt32 Version; + + unsigned ResetIntervalBits; + unsigned WindowSizeBits; + UInt32 CacheSize; + + CResetTable ResetTable; + + CLzxInfo(): + Version(0), + ResetIntervalBits(0), + WindowSizeBits(0), + CacheSize(0) + {} + + unsigned GetNumDictBits() const + { + if (Version == 2 || Version == 3) + return 15 + WindowSizeBits; + return 0; + } + + UInt64 GetFolderSize() const { return (UInt64)kBlockSize << ResetIntervalBits; } + UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); } + UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); } + UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; } + + bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const + { + const UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + if (blockIndex >= ResetTable.ResetOffsets.Size()) + return false; + offset = ResetTable.ResetOffsets[(unsigned)blockIndex]; + return true; + } + + bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const + { + UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size); + } +}; + + +struct CMethodInfo +{ + Byte Guid[16]; + // CByteBuffer ControlData; + CLzxInfo LzxInfo; + + bool IsLzx() const; + bool IsDes() const; + AString GetGuidString() const; + AString GetName() const; +}; + + +struct CSectionInfo +{ + UInt64 Offset; + UInt64 CompressedSize; + UInt64 UncompressedSize; + + AString Name; + CObjectVector Methods; + + bool IsLzx() const; + UString GetMethodName() const; +}; + +class CFilesDatabase: public CDatabase +{ +public: + CUIntVector Indices; + CObjectVector Sections; + bool LowLevel; + + UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; } + UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; } + + UInt64 GetFolder(unsigned fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + if (item.Section < Sections.Size()) + { + const CSectionInfo §ion = Sections[(unsigned)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset); + } + return 0; + } + + UInt64 GetLastFolder(unsigned fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + if (item.Section < Sections.Size()) + { + const CSectionInfo §ion = Sections[(unsigned)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1); + } + return 0; + } + + void HighLevelClear() + { + LowLevel = true; + Indices.Clear(); + Sections.Clear(); + } + + void Clear() + { + CDatabase::Clear(); + HighLevelClear(); + } + + void SetIndices(); + void Sort(); + bool Check(); + bool CheckSectionRefs(); +}; + + +class CInArchive +{ + CMyComPtr m_InStreamRef; + ::CInBuffer _inBuffer; + UInt64 _chunkSize; + bool _help2; + + Byte ReadByte(); + void ReadBytes(Byte *data, UInt32 size); + void Skip(size_t size); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + UInt64 ReadEncInt(); + void ReadString(unsigned size, AString &s); + void ReadUString(unsigned size, UString &s); + void ReadGUID(Byte *g); + + HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size); + + HRESULT ReadDirEntry(CDatabase &database); + HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name); + +public: + bool IsArc; + bool HeadersError; + bool UnexpectedEnd; + bool UnsupportedFeature; + + CInArchive(bool help2) { _help2 = help2; } + + HRESULT OpenChm(IInStream *inStream, CDatabase &database); + HRESULT OpenHelp2(IInStream *inStream, CDatabase &database); + HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database); + HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Chm/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Chm/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Chm/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ComHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ComHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ComHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ComHandler.cpp 2025-04-26 11:18:00.000000000 +0000 @@ -1,886 +1,898 @@ -// ComHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" - -#include "../../Common/IntToString.h" -#include "../../Common/ComTry.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.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) - -namespace NArchive { -namespace NCom { - -#define SIGNATURE { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } -static const Byte kSignature[] = SIGNATURE; - -enum EType -{ - k_Type_Common, - k_Type_Msi, - k_Type_Msp, - k_Type_Doc, - k_Type_Ppt, - k_Type_Xls, -}; - -static const char * const kExtensions[] = -{ - "compound" - , "msi" - , "msp" - , "doc" - , "ppt" - , "xls" -}; - -namespace NFatID -{ - static const UInt32 kFree = 0xFFFFFFFF; - static const UInt32 kEndOfChain = 0xFFFFFFFE; - static const UInt32 kFatSector = 0xFFFFFFFD; - static const UInt32 kMatSector = 0xFFFFFFFC; - static const UInt32 kMaxValue = 0xFFFFFFFA; -} - -namespace NItemType -{ - static const Byte kEmpty = 0; - static const Byte kStorage = 1; - static const Byte kStream = 2; - static const Byte kLockBytes = 3; - static const Byte kProperty = 4; - static const Byte kRootStorage = 5; -} - -static const UInt32 kNameSizeMax = 64; - -struct CItem -{ - Byte Name[kNameSizeMax]; - // UInt16 NameSize; - // UInt32 Flags; - FILETIME CTime; - FILETIME MTime; - UInt64 Size; - UInt32 LeftDid; - UInt32 RightDid; - UInt32 SonDid; - UInt32 Sid; - Byte Type; - - bool IsEmpty() const { return Type == NItemType::kEmpty; } - bool IsDir() const { return Type == NItemType::kStorage || Type == NItemType::kRootStorage; } - - void Parse(const Byte *p, bool mode64bit); -}; - -struct CRef -{ - int Parent; - UInt32 Did; -}; - -class CDatabase -{ - UInt32 NumSectorsInMiniStream; - CObjArray MiniSids; - - HRESULT AddNode(int parent, UInt32 did); -public: - - CObjArray Fat; - UInt32 FatSize; - - CObjArray Mat; - UInt32 MatSize; - - CObjectVector Items; - CRecordVector Refs; - - UInt32 LongStreamMinSize; - unsigned SectorSizeBits; - unsigned MiniSectorSizeBits; - - Int32 MainSubfile; - - UInt64 PhySize; - EType Type; - - bool IsNotArcType() const - { - return - Type != k_Type_Msi && - Type != k_Type_Msp; - } - - void UpdatePhySize(UInt64 val) - { - if (PhySize < val) - PhySize = val; - } - HRESULT ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid); - HRESULT ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest); - - HRESULT Update_PhySize_WithItem(unsigned index); - - void Clear(); - bool IsLargeStream(UInt64 size) const { return size >= LongStreamMinSize; } - UString GetItemPath(UInt32 index) const; - - UInt64 GetItemPackSize(UInt64 size) const - { - UInt64 mask = ((UInt64)1 << (IsLargeStream(size) ? SectorSizeBits : MiniSectorSizeBits)) - 1; - return (size + mask) & ~mask; - } - - bool GetMiniCluster(UInt32 sid, UInt64 &res) const - { - unsigned subBits = SectorSizeBits - MiniSectorSizeBits; - UInt32 fid = sid >> subBits; - if (fid >= NumSectorsInMiniStream) - return false; - res = (((UInt64)MiniSids[fid] + 1) << subBits) + (sid & ((1 << subBits) - 1)); - return true; - } - - HRESULT Open(IInStream *inStream); -}; - - -HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) -{ - UpdatePhySize(((UInt64)sid + 2) << sectorSizeBits); - RINOK(inStream->Seek((((UInt64)sid + 1) << sectorSizeBits), STREAM_SEEK_SET, NULL)); - return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits); -} - -HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) -{ - RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)); - UInt32 sectorSize = (UInt32)1 << sectorSizeBits; - for (UInt32 t = 0; t < sectorSize; t += 4) - *dest++ = Get32(buf + t); - return S_OK; -} - -static void GetFileTimeFromMem(const Byte *p, FILETIME *ft) -{ - ft->dwLowDateTime = Get32(p); - ft->dwHighDateTime = Get32(p + 4); -} - -void CItem::Parse(const Byte *p, bool mode64bit) -{ - memcpy(Name, p, kNameSizeMax); - // NameSize = Get16(p + 64); - Type = p[66]; - LeftDid = Get32(p + 68); - RightDid = Get32(p + 72); - SonDid = Get32(p + 76); - // Flags = Get32(p + 96); - GetFileTimeFromMem(p + 100, &CTime); - GetFileTimeFromMem(p + 108, &MTime); - Sid = Get32(p + 116); - Size = Get32(p + 120); - if (mode64bit) - Size |= ((UInt64)Get32(p + 124) << 32); -} - -void CDatabase::Clear() -{ - PhySize = 0; - - Fat.Free(); - MiniSids.Free(); - Mat.Free(); - Items.Clear(); - Refs.Clear(); -} - -static const UInt32 kNoDid = 0xFFFFFFFF; - -HRESULT CDatabase::AddNode(int parent, UInt32 did) -{ - if (did == kNoDid) - return S_OK; - if (did >= (UInt32)Items.Size()) - return S_FALSE; - const CItem &item = Items[did]; - if (item.IsEmpty()) - return S_FALSE; - CRef ref; - ref.Parent = parent; - ref.Did = did; - int index = Refs.Add(ref); - if (Refs.Size() > Items.Size()) - return S_FALSE; - RINOK(AddNode(parent, item.LeftDid)); - RINOK(AddNode(parent, item.RightDid)); - if (item.IsDir()) - { - RINOK(AddNode(index, item.SonDid)); - } - return S_OK; -} - -static const wchar_t kCharOpenBracket = L'['; -static const wchar_t kCharCloseBracket = L']'; - -static UString CompoundNameToFileName(const UString &s) -{ - UString res; - for (unsigned i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if (c < 0x20) - { - res += kCharOpenBracket; - wchar_t buf[32]; - ConvertUInt32ToString(c, buf); - res += buf; - res += kCharCloseBracket; - } - else - res += c; - } - return res; -} - -static const char k_Msi_Chars[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._"; - -// static const char *k_Msi_ID = ""; // "{msi}"; -static const wchar_t k_Msi_SpecChar = L'!'; - -static const unsigned k_Msi_NumBits = 6; -static const unsigned k_Msi_NumChars = 1 << k_Msi_NumBits; -static const unsigned k_Msi_CharMask = k_Msi_NumChars - 1; -static const unsigned k_Msi_StartUnicodeChar = 0x3800; -static const unsigned k_Msi_UnicodeRange = k_Msi_NumChars * (k_Msi_NumChars + 1); - - -static bool IsMsiName(const Byte *p) -{ - UInt32 c = Get16(p); - return - c >= k_Msi_StartUnicodeChar && - c <= k_Msi_StartUnicodeChar + k_Msi_UnicodeRange; -} - -static bool AreEqualNames(const Byte *rawName, const char *asciiName) -{ - for (unsigned i = 0; i < kNameSizeMax / 2; i++) - { - wchar_t c = Get16(rawName + i * 2); - wchar_t c2 = (Byte)asciiName[i]; - if (c != c2) - return false; - if (c == 0) - return true; - } - return false; -} - -static bool CompoundMsiNameToFileName(const UString &name, UString &res) -{ - res.Empty(); - for (unsigned i = 0; i < name.Len(); i++) - { - wchar_t c = name[i]; - if (c < k_Msi_StartUnicodeChar || c > k_Msi_StartUnicodeChar + k_Msi_UnicodeRange) - return false; - /* - if (i == 0) - res += k_Msi_ID; - */ - c -= k_Msi_StartUnicodeChar; - - unsigned c0 = (unsigned)c & k_Msi_CharMask; - unsigned c1 = (unsigned)c >> k_Msi_NumBits; - - if (c1 <= k_Msi_NumChars) - { - res += (wchar_t)(Byte)k_Msi_Chars[c0]; - if (c1 == k_Msi_NumChars) - break; - res += (wchar_t)(Byte)k_Msi_Chars[c1]; - } - else - res += k_Msi_SpecChar; - } - return true; -} - -static UString ConvertName(const Byte *p, bool &isMsi) -{ - isMsi = false; - UString s; - - for (unsigned i = 0; i < kNameSizeMax; i += 2) - { - wchar_t c = Get16(p + i); - if (c == 0) - break; - s += c; - } - - UString msiName; - if (CompoundMsiNameToFileName(s, msiName)) - { - isMsi = true; - return msiName; - } - return CompoundNameToFileName(s); -} - -static UString ConvertName(const Byte *p) -{ - bool isMsi; - return ConvertName(p, isMsi); -} - -UString CDatabase::GetItemPath(UInt32 index) const -{ - UString s; - while (index != kNoDid) - { - const CRef &ref = Refs[index]; - const CItem &item = Items[ref.Did]; - if (!s.IsEmpty()) - s.InsertAtFront(WCHAR_PATH_SEPARATOR); - s.Insert(0, ConvertName(item.Name)); - index = ref.Parent; - } - return s; -} - -HRESULT CDatabase::Update_PhySize_WithItem(unsigned index) -{ - const CItem &item = Items[index]; - bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); - if (!isLargeStream) - return S_OK; - unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; - // streamSpec->Size = item.Size; - - UInt32 clusterSize = (UInt32)1 << bsLog; - UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; - if (numClusters64 >= ((UInt32)1 << 31)) - return S_FALSE; - UInt32 sid = item.Sid; - UInt64 size = item.Size; - - if (size != 0) - { - for (;; size -= clusterSize) - { - // if (isLargeStream) - { - if (sid >= FatSize) - return S_FALSE; - UpdatePhySize(((UInt64)sid + 2) << bsLog); - sid = Fat[sid]; - } - if (size <= clusterSize) - break; - } - } - if (sid != NFatID::kEndOfChain) - return S_FALSE; - return S_OK; -} - -// There is name "[!]MsiPatchSequence" in msp files -static const unsigned kMspSequence_Size = 18; -static const Byte kMspSequence[kMspSequence_Size] = - { 0x40, 0x48, 0x96, 0x45, 0x6C, 0x3E, 0xE4, 0x45, - 0xE6, 0x42, 0x16, 0x42, 0x37, 0x41, 0x27, 0x41, - 0x37, 0x41 }; - -HRESULT CDatabase::Open(IInStream *inStream) -{ - MainSubfile = -1; - Type = k_Type_Common; - const UInt32 kHeaderSize = 512; - Byte p[kHeaderSize]; - PhySize = kHeaderSize; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)); - if (memcmp(p, kSignature, ARRAY_SIZE(kSignature)) != 0) - return S_FALSE; - if (Get16(p + 0x1A) > 4) // majorVer - return S_FALSE; - if (Get16(p + 0x1C) != 0xFFFE) // Little-endian - return S_FALSE; - unsigned sectorSizeBits = Get16(p + 0x1E); - bool mode64bit = (sectorSizeBits >= 12); - unsigned miniSectorSizeBits = Get16(p + 0x20); - SectorSizeBits = sectorSizeBits; - MiniSectorSizeBits = miniSectorSizeBits; - - if (sectorSizeBits > 24 || - sectorSizeBits < 7 || - miniSectorSizeBits > 24 || - miniSectorSizeBits < 2 || - miniSectorSizeBits > sectorSizeBits) - return S_FALSE; - UInt32 numSectorsForFAT = Get32(p + 0x2C); // SAT - LongStreamMinSize = Get32(p + 0x38); - - UInt32 sectSize = (UInt32)1 << sectorSizeBits; - - CByteBuffer sect(sectSize); - - unsigned ssb2 = sectorSizeBits - 2; - UInt32 numSidsInSec = (UInt32)1 << ssb2; - UInt32 numFatItems = numSectorsForFAT << ssb2; - if ((numFatItems >> ssb2) != numSectorsForFAT) - return S_FALSE; - FatSize = numFatItems; - - { - UInt32 numSectorsForBat = Get32(p + 0x48); // master sector allocation table - const UInt32 kNumHeaderBatItems = 109; - UInt32 numBatItems = kNumHeaderBatItems + (numSectorsForBat << ssb2); - if (numBatItems < kNumHeaderBatItems || ((numBatItems - kNumHeaderBatItems) >> ssb2) != numSectorsForBat) - return S_FALSE; - CObjArray bat(numBatItems); - UInt32 i; - for (i = 0; i < kNumHeaderBatItems; i++) - bat[i] = Get32(p + 0x4c + i * 4); - UInt32 sid = Get32(p + 0x44); - for (UInt32 s = 0; s < numSectorsForBat; s++) - { - RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)); - i += numSidsInSec - 1; - sid = bat[i]; - } - numBatItems = i; - - Fat.Alloc(numFatItems); - UInt32 j = 0; - - for (i = 0; i < numFatItems; j++, i += numSidsInSec) - { - if (j >= numBatItems) - return S_FALSE; - RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)); - } - FatSize = numFatItems = i; - } - - UInt32 numMatItems; - { - UInt32 numSectorsForMat = Get32(p + 0x40); - numMatItems = (UInt32)numSectorsForMat << ssb2; - if ((numMatItems >> ssb2) != numSectorsForMat) - return S_FALSE; - Mat.Alloc(numMatItems); - UInt32 i; - UInt32 sid = Get32(p + 0x3C); // short-sector table SID - for (i = 0; i < numMatItems; i += numSidsInSec) - { - RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)); - if (sid >= numFatItems) - return S_FALSE; - sid = Fat[sid]; - } - if (sid != NFatID::kEndOfChain) - return S_FALSE; - } - - { - CByteBuffer used(numFatItems); - for (UInt32 i = 0; i < numFatItems; i++) - used[i] = 0; - UInt32 sid = Get32(p + 0x30); // directory stream SID - for (;;) - { - if (sid >= numFatItems) - return S_FALSE; - if (used[sid]) - return S_FALSE; - used[sid] = 1; - RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)); - for (UInt32 i = 0; i < sectSize; i += 128) - { - CItem item; - item.Parse(sect + i, mode64bit); - Items.Add(item); - } - sid = Fat[sid]; - if (sid == NFatID::kEndOfChain) - break; - } - } - - const CItem &root = Items[0]; - - { - UInt32 numSectorsInMiniStream; - { - UInt64 numSatSects64 = (root.Size + sectSize - 1) >> sectorSizeBits; - if (numSatSects64 > NFatID::kMaxValue) - return S_FALSE; - numSectorsInMiniStream = (UInt32)numSatSects64; - } - NumSectorsInMiniStream = numSectorsInMiniStream; - MiniSids.Alloc(numSectorsInMiniStream); - { - UInt64 matSize64 = (root.Size + ((UInt64)1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits; - if (matSize64 > NFatID::kMaxValue) - return S_FALSE; - MatSize = (UInt32)matSize64; - if (numMatItems < MatSize) - return S_FALSE; - } - - UInt32 sid = root.Sid; - for (UInt32 i = 0; ; i++) - { - if (sid == NFatID::kEndOfChain) - { - if (i != numSectorsInMiniStream) - return S_FALSE; - break; - } - if (i >= numSectorsInMiniStream) - return S_FALSE; - MiniSids[i] = sid; - if (sid >= numFatItems) - return S_FALSE; - sid = Fat[sid]; - } - } - - RINOK(AddNode(-1, root.SonDid)); - - unsigned numCabs = 0; - - FOR_VECTOR (i, Refs) - { - const CItem &item = Items[Refs[i].Did]; - if (item.IsDir() || numCabs > 1) - continue; - bool isMsiName; - const UString msiName = ConvertName(item.Name, isMsiName); - if (isMsiName && !msiName.IsEmpty()) - { - // bool isThereExt = (msiName.Find(L'.') >= 0); - bool isMsiSpec = (msiName[0] == k_Msi_SpecChar); - if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab") - || !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe") - // || !isMsiSpec && !isThereExt - ) - - { - numCabs++; - MainSubfile = i; - } - } - } - - if (numCabs > 1) - MainSubfile = -1; - - { - FOR_VECTOR (t, Items) - { - Update_PhySize_WithItem(t); - } - } - { - FOR_VECTOR (t, Items) - { - const CItem &item = Items[t]; - - if (IsMsiName(item.Name)) - { - Type = k_Type_Msi; - if (memcmp(item.Name, kMspSequence, kMspSequence_Size) == 0) - { - Type = k_Type_Msp; - break; - } - continue; - } - if (AreEqualNames(item.Name, "WordDocument")) - { - Type = k_Type_Doc; - break; - } - if (AreEqualNames(item.Name, "PowerPoint Document")) - { - Type = k_Type_Ppt; - break; - } - if (AreEqualNames(item.Name, "Workbook")) - { - Type = k_Type_Xls; - break; - } - } - } - - return S_OK; -} - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - CDatabase _db; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidCTime, - kpidMTime -}; - -static const Byte kArcProps[] = -{ - kpidExtension, - kpidClusterSize, - kpidSectorSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidExtension: prop = kExtensions[(unsigned)_db.Type]; break; - case kpidPhySize: prop = _db.PhySize; break; - case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break; - case kpidSectorSize: prop = (UInt32)1 << _db.MiniSectorSizeBits; break; - case kpidMainSubfile: if (_db.MainSubfile >= 0) prop = (UInt32)_db.MainSubfile; break; - case kpidIsNotArcType: if (_db.IsNotArcType()) prop = true; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CRef &ref = _db.Refs[index]; - const CItem &item = _db.Items[ref.Did]; - - switch (propID) - { - case kpidPath: prop = _db.GetItemPath(index); break; - case kpidIsDir: prop = item.IsDir(); break; - case kpidCTime: prop = item.CTime; break; - case kpidMTime: prop = item.MTime; break; - case kpidPackSize: if (!item.IsDir()) prop = _db.GetItemPackSize(item.Size); break; - case kpidSize: if (!item.IsDir()) prop = item.Size; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - try - { - if (_db.Open(inStream) != S_OK) - return S_FALSE; - _stream = inStream; - } - catch(...) { return S_FALSE; } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _db.Clear(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _db.Refs.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) - { - const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did]; - if (!item.IsDir()) - totalSize += item.Size; - } - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 totalPackSize; - totalSize = totalPackSize = 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 = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _db.Items[_db.Refs[index].Did]; - - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - totalPackSize += _db.GetItemPackSize(item.Size); - totalSize += item.Size; - - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 res = NExtract::NOperationResult::kDataError; - CMyComPtr inStream; - HRESULT hres = GetStream(index, &inStream); - if (hres == S_FALSE) - res = NExtract::NOperationResult::kDataError; - else if (hres == E_NOTIMPL) - res = NExtract::NOperationResult::kUnsupportedMethod; - else - { - RINOK(hres); - if (inStream) - { - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) - res = NExtract::NOperationResult::kOK; - } - } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _db.Refs.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - UInt32 itemIndex = _db.Refs[index].Did; - const CItem &item = _db.Items[itemIndex]; - CClusterInStream *streamSpec = new CClusterInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Stream = _stream; - streamSpec->StartOffset = 0; - - bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); - int bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; - streamSpec->BlockSizeLog = bsLog; - streamSpec->Size = item.Size; - - UInt32 clusterSize = (UInt32)1 << bsLog; - UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; - if (numClusters64 >= ((UInt32)1 << 31)) - return E_NOTIMPL; - streamSpec->Vector.ClearAndReserve((unsigned)numClusters64); - UInt32 sid = item.Sid; - UInt64 size = item.Size; - - if (size != 0) - { - for (;; size -= clusterSize) - { - if (isLargeStream) - { - if (sid >= _db.FatSize) - return S_FALSE; - streamSpec->Vector.AddInReserved(sid + 1); - sid = _db.Fat[sid]; - } - else - { - UInt64 val = 0; - if (sid >= _db.MatSize || !_db.GetMiniCluster(sid, val) || val >= (UInt64)1 << 32) - return S_FALSE; - streamSpec->Vector.AddInReserved((UInt32)val); - sid = _db.Mat[sid]; - } - if (size <= clusterSize) - break; - } - } - if (sid != NFatID::kEndOfChain) - return S_FALSE; - RINOK(streamSpec->InitAndSeek()); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -REGISTER_ARC_I( - "Compound", "msi msp doc xls ppt", 0, 0xE5, - kSignature, - 0, - 0, - NULL) - -}} +// ComHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/IntToString.h" +#include "../../Common/ComTry.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.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) + +namespace NArchive { +namespace NCom { + +static const Byte kSignature[] = + { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; + +enum EType +{ + k_Type_Common, + k_Type_Msi, + k_Type_Msp, + k_Type_Doc, + k_Type_Ppt, + k_Type_Xls +}; + +static const char * const kExtensions[] = +{ + "compound" + , "msi" + , "msp" + , "doc" + , "ppt" + , "xls" +}; + +namespace NFatID +{ + // static const UInt32 kFree = 0xFFFFFFFF; + static const UInt32 kEndOfChain = 0xFFFFFFFE; + // static const UInt32 kFatSector = 0xFFFFFFFD; + // static const UInt32 kMatSector = 0xFFFFFFFC; + static const UInt32 kMaxValue = 0xFFFFFFFA; +} + +namespace NItemType +{ + static const Byte kEmpty = 0; + static const Byte kStorage = 1; + // static const Byte kStream = 2; + // static const Byte kLockBytes = 3; + // static const Byte kProperty = 4; + static const Byte kRootStorage = 5; +} + +static const unsigned kNameSizeMax = 64; + +struct CItem +{ + Byte Name[kNameSizeMax]; + // UInt16 NameSize; + // UInt32 Flags; + FILETIME CTime; + FILETIME MTime; + UInt64 Size; + UInt32 LeftDid; + UInt32 RightDid; + UInt32 SonDid; + UInt32 Sid; + Byte Type; + + bool IsEmpty() const { return Type == NItemType::kEmpty; } + bool IsDir() const { return Type == NItemType::kStorage || Type == NItemType::kRootStorage; } + + void Parse(const Byte *p, bool mode64bit); +}; + +struct CRef +{ + int Parent; + UInt32 Did; +}; + +class CDatabase +{ + CObjArray MiniSids; + + HRESULT AddNode(int parent, UInt32 did); + +public: + CObjArray Fat; + CObjArray Mat; + CObjectVector Items; + CRecordVector Refs; +private: + UInt32 NumSectorsInMiniStream; +public: + UInt32 MatSize; + UInt32 FatSize; + + UInt32 LongStreamMinSize; + unsigned SectorSizeBits; + unsigned MiniSectorSizeBits; + + Int32 MainSubfile; + EType Type; + + UInt64 PhySize; + UInt64 PhySize_Aligned; + + bool IsNotArcType() const + { + return + Type != k_Type_Msi && + Type != k_Type_Msp; + } + + void UpdatePhySize(UInt64 val, UInt64 val_Aligned) + { + if (PhySize < val) + PhySize = val; + if (PhySize_Aligned < val_Aligned) + PhySize_Aligned = val_Aligned; + } + HRESULT ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid); + HRESULT ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest); + + HRESULT Update_PhySize_WithItem(unsigned index); + + void Clear(); + bool IsLargeStream(UInt64 size) const { return size >= LongStreamMinSize; } + UString GetItemPath(UInt32 index) const; + + UInt64 GetItemPackSize(UInt64 size) const + { + const UInt64 mask = ((UInt32)1 << (IsLargeStream(size) ? SectorSizeBits : MiniSectorSizeBits)) - 1; + return (size + mask) & ~mask; + } + + bool GetMiniCluster(UInt32 sid, UInt64 &res) const + { + const unsigned subBits = SectorSizeBits - MiniSectorSizeBits; + const UInt32 fid = sid >> subBits; + if (fid >= NumSectorsInMiniStream) + return false; + res = (((UInt64)MiniSids[fid] + 1) << subBits) + (sid & ((1 << subBits) - 1)); + return true; + } + + HRESULT Open(IInStream *inStream); +}; + + +HRESULT CDatabase::ReadSector(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid) +{ + const UInt64 end = ((UInt64)sid + 2) << sectorSizeBits; + UpdatePhySize(end, end); + RINOK(InStream_SeekSet(inStream, (((UInt64)sid + 1) << sectorSizeBits))) + return ReadStream_FALSE(inStream, buf, (size_t)1 << sectorSizeBits); +} + +HRESULT CDatabase::ReadIDs(IInStream *inStream, Byte *buf, unsigned sectorSizeBits, UInt32 sid, UInt32 *dest) +{ + RINOK(ReadSector(inStream, buf, sectorSizeBits, sid)) + const UInt32 sectorSize = (UInt32)1 << sectorSizeBits; + for (UInt32 t = 0; t < sectorSize; t += 4) + *dest++ = Get32(buf + t); + return S_OK; +} + +static void GetFileTimeFromMem(const Byte *p, FILETIME *ft) +{ + ft->dwLowDateTime = Get32(p); + ft->dwHighDateTime = Get32(p + 4); +} + +void CItem::Parse(const Byte *p, bool mode64bit) +{ + memcpy(Name, p, kNameSizeMax); + // NameSize = Get16(p + 64); + Type = p[66]; + LeftDid = Get32(p + 68); + RightDid = Get32(p + 72); + SonDid = Get32(p + 76); + // Flags = Get32(p + 96); + GetFileTimeFromMem(p + 100, &CTime); + GetFileTimeFromMem(p + 108, &MTime); + Sid = Get32(p + 116); + Size = Get32(p + 120); + if (mode64bit) + Size |= ((UInt64)Get32(p + 124) << 32); +} + +void CDatabase::Clear() +{ + PhySize = 0; + PhySize_Aligned = 0; + + Fat.Free(); + MiniSids.Free(); + Mat.Free(); + Items.Clear(); + Refs.Clear(); +} + +static const UInt32 kNoDid = 0xFFFFFFFF; + +HRESULT CDatabase::AddNode(int parent, UInt32 did) +{ + if (did == kNoDid) + return S_OK; + if (did >= (UInt32)Items.Size()) + return S_FALSE; + const CItem &item = Items[did]; + if (item.IsEmpty()) + return S_FALSE; + CRef ref; + ref.Parent = parent; + ref.Did = did; + const unsigned index = Refs.Add(ref); + if (Refs.Size() > Items.Size()) + return S_FALSE; + RINOK(AddNode(parent, item.LeftDid)) + RINOK(AddNode(parent, item.RightDid)) + if (item.IsDir()) + { + RINOK(AddNode((int)index, item.SonDid)) + } + return S_OK; +} + +static UString CompoundNameToFileName(const UString &s) +{ + UString res; + for (unsigned i = 0; i < s.Len(); i++) + { + const wchar_t c = s[i]; + if ((unsigned)(int)c < 0x20) + { + res.Add_Char('['); + res.Add_UInt32((UInt32)(unsigned)(int)c); + res.Add_Char(']'); + } + else + res += c; + } + return res; +} + +static const char k_Msi_Chars[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._"; + +// static const char * const k_Msi_ID = ""; // "{msi}"; +static const char k_Msi_SpecChar = '!'; + +static const unsigned k_Msi_NumBits = 6; +static const unsigned k_Msi_NumChars = 1 << k_Msi_NumBits; +static const unsigned k_Msi_CharMask = k_Msi_NumChars - 1; +static const unsigned k_Msi_StartUnicodeChar = 0x3800; +static const unsigned k_Msi_UnicodeRange = k_Msi_NumChars * (k_Msi_NumChars + 1); + + +static bool IsMsiName(const Byte *p) +{ + UInt32 c = Get16(p); + return + c >= k_Msi_StartUnicodeChar && + c <= k_Msi_StartUnicodeChar + k_Msi_UnicodeRange; +} + +static bool AreEqualNames(const Byte *rawName, const char *asciiName) +{ + for (unsigned i = 0; i < kNameSizeMax / 2; i++) + { + wchar_t c = Get16(rawName + i * 2); + wchar_t c2 = (Byte)asciiName[i]; + if (c != c2) + return false; + if (c == 0) + return true; + } + return false; +} + +static bool CompoundMsiNameToFileName(const UString &name, UString &res) +{ + res.Empty(); + for (unsigned i = 0; i < name.Len(); i++) + { + wchar_t c = name[i]; + if (c < (wchar_t)k_Msi_StartUnicodeChar || c > (wchar_t)(k_Msi_StartUnicodeChar + k_Msi_UnicodeRange)) + return false; + /* + if (i == 0) + res += k_Msi_ID; + */ + c -= (wchar_t)k_Msi_StartUnicodeChar; + + const unsigned c0 = (unsigned)c & k_Msi_CharMask; + const unsigned c1 = (unsigned)c >> k_Msi_NumBits; + + if (c1 <= k_Msi_NumChars) + { + res.Add_Char(k_Msi_Chars[c0]); + if (c1 == k_Msi_NumChars) + break; + res.Add_Char(k_Msi_Chars[c1]); + } + else + res.Add_Char(k_Msi_SpecChar); + } + return true; +} + +static UString ConvertName(const Byte *p, bool &isMsi) +{ + isMsi = false; + UString s; + + for (unsigned i = 0; i < kNameSizeMax; i += 2) + { + wchar_t c = Get16(p + i); + if (c == 0) + break; + s += c; + } + + UString msiName; + if (CompoundMsiNameToFileName(s, msiName)) + { + isMsi = true; + return msiName; + } + return CompoundNameToFileName(s); +} + +static UString ConvertName(const Byte *p) +{ + bool isMsi; + return ConvertName(p, isMsi); +} + +UString CDatabase::GetItemPath(UInt32 index) const +{ + UString s; + while (index != kNoDid) + { + const CRef &ref = Refs[index]; + const CItem &item = Items[ref.Did]; + if (!s.IsEmpty()) + s.InsertAtFront(WCHAR_PATH_SEPARATOR); + s.Insert(0, ConvertName(item.Name)); + index = (unsigned)ref.Parent; + } + return s; +} + +HRESULT CDatabase::Update_PhySize_WithItem(unsigned index) +{ + const CItem &item = Items[index]; + const bool isLargeStream = (index == 0 || IsLargeStream(item.Size)); + if (!isLargeStream) + return S_OK; + const unsigned bsLog = isLargeStream ? SectorSizeBits : MiniSectorSizeBits; + // streamSpec->Size = item.Size; + + const UInt32 clusterSize = (UInt32)1 << bsLog; + const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; + if (numClusters64 >= ((UInt32)1 << 31)) + return S_FALSE; + UInt32 sid = item.Sid; + UInt64 size = item.Size; + + if (size != 0) + { + for (;; size -= clusterSize) + { + // if (isLargeStream) + { + if (sid >= FatSize) + return S_FALSE; + UInt64 end = ((UInt64)sid + 1) << bsLog; + const UInt64 end_Aligned = end + clusterSize; + if (size < clusterSize) + end += size; + else + end = end_Aligned; + UpdatePhySize(end, end_Aligned); + sid = Fat[sid]; + } + if (size <= clusterSize) + break; + } + } + if (sid != NFatID::kEndOfChain) + return S_FALSE; + return S_OK; +} + +// There is name "[!]MsiPatchSequence" in msp files +static const unsigned kMspSequence_Size = 18; +static const Byte kMspSequence[kMspSequence_Size] = + { 0x40, 0x48, 0x96, 0x45, 0x6C, 0x3E, 0xE4, 0x45, + 0xE6, 0x42, 0x16, 0x42, 0x37, 0x41, 0x27, 0x41, + 0x37, 0x41 }; + +HRESULT CDatabase::Open(IInStream *inStream) +{ + MainSubfile = -1; + Type = k_Type_Common; + const UInt32 kHeaderSize = 512; + Byte p[kHeaderSize]; + PhySize = kHeaderSize; + RINOK(ReadStream_FALSE(inStream, p, kHeaderSize)) + if (memcmp(p, kSignature, Z7_ARRAY_SIZE(kSignature)) != 0) + return S_FALSE; + if (Get16(p + 0x1A) > 4) // majorVer + return S_FALSE; + if (Get16(p + 0x1C) != 0xFFFE) // Little-endian + return S_FALSE; + unsigned sectorSizeBits = Get16(p + 0x1E); + bool mode64bit = (sectorSizeBits >= 12); + unsigned miniSectorSizeBits = Get16(p + 0x20); + SectorSizeBits = sectorSizeBits; + MiniSectorSizeBits = miniSectorSizeBits; + + if (sectorSizeBits > 24 || + sectorSizeBits < 7 || + miniSectorSizeBits > 24 || + miniSectorSizeBits < 2 || + miniSectorSizeBits > sectorSizeBits) + return S_FALSE; + UInt32 numSectorsForFAT = Get32(p + 0x2C); // SAT + LongStreamMinSize = Get32(p + 0x38); + + UInt32 sectSize = (UInt32)1 << sectorSizeBits; + + CByteBuffer sect(sectSize); + + unsigned ssb2 = sectorSizeBits - 2; + UInt32 numSidsInSec = (UInt32)1 << ssb2; + UInt32 numFatItems = numSectorsForFAT << ssb2; + if ((numFatItems >> ssb2) != numSectorsForFAT) + return S_FALSE; + FatSize = numFatItems; + + { + UInt32 numSectorsForBat = Get32(p + 0x48); // master sector allocation table + const UInt32 kNumHeaderBatItems = 109; + UInt32 numBatItems = kNumHeaderBatItems + (numSectorsForBat << ssb2); + if (numBatItems < kNumHeaderBatItems || ((numBatItems - kNumHeaderBatItems) >> ssb2) != numSectorsForBat) + return S_FALSE; + CObjArray bat(numBatItems); + UInt32 i; + for (i = 0; i < kNumHeaderBatItems; i++) + bat[i] = Get32(p + 0x4c + i * 4); + UInt32 sid = Get32(p + 0x44); + for (UInt32 s = 0; s < numSectorsForBat; s++) + { + RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, bat + i)) + i += numSidsInSec - 1; + sid = bat[i]; + } + numBatItems = i; + + Fat.Alloc(numFatItems); + UInt32 j = 0; + + for (i = 0; i < numFatItems; j++, i += numSidsInSec) + { + if (j >= numBatItems) + return S_FALSE; + RINOK(ReadIDs(inStream, sect, sectorSizeBits, bat[j], Fat + i)) + } + FatSize = numFatItems = i; + } + + UInt32 numMatItems; + { + UInt32 numSectorsForMat = Get32(p + 0x40); + numMatItems = (UInt32)numSectorsForMat << ssb2; + if ((numMatItems >> ssb2) != numSectorsForMat) + return S_FALSE; + Mat.Alloc(numMatItems); + UInt32 i; + UInt32 sid = Get32(p + 0x3C); // short-sector table SID + for (i = 0; i < numMatItems; i += numSidsInSec) + { + RINOK(ReadIDs(inStream, sect, sectorSizeBits, sid, Mat + i)) + if (sid >= numFatItems) + return S_FALSE; + sid = Fat[sid]; + } + if (sid != NFatID::kEndOfChain) + return S_FALSE; + } + + { + CByteBuffer used(numFatItems); + for (UInt32 i = 0; i < numFatItems; i++) + used[i] = 0; + UInt32 sid = Get32(p + 0x30); // directory stream SID + for (;;) + { + if (sid >= numFatItems) + return S_FALSE; + if (used[sid]) + return S_FALSE; + used[sid] = 1; + RINOK(ReadSector(inStream, sect, sectorSizeBits, sid)) + for (UInt32 i = 0; i < sectSize; i += 128) + { + CItem item; + item.Parse(sect + i, mode64bit); + // we use (item.Size) check here. + // so we don't need additional overflow checks for (item.Size +) in another code + if (item.Size >= ((UInt64)1 << 63)) + return S_FALSE; + Items.Add(item); + } + sid = Fat[sid]; + if (sid == NFatID::kEndOfChain) + break; + } + } + + const CItem &root = Items[0]; + + { + UInt32 numSectorsInMiniStream; + { + UInt64 numSatSects64 = (root.Size + sectSize - 1) >> sectorSizeBits; + if (numSatSects64 > NFatID::kMaxValue) + return S_FALSE; + numSectorsInMiniStream = (UInt32)numSatSects64; + } + NumSectorsInMiniStream = numSectorsInMiniStream; + MiniSids.Alloc(numSectorsInMiniStream); + { + UInt64 matSize64 = (root.Size + ((UInt64)1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits; + if (matSize64 > NFatID::kMaxValue) + return S_FALSE; + MatSize = (UInt32)matSize64; + if (numMatItems < MatSize) + return S_FALSE; + } + + UInt32 sid = root.Sid; + for (UInt32 i = 0; ; i++) + { + if (sid == NFatID::kEndOfChain) + { + if (i != numSectorsInMiniStream) + return S_FALSE; + break; + } + if (i >= numSectorsInMiniStream) + return S_FALSE; + MiniSids[i] = sid; + if (sid >= numFatItems) + return S_FALSE; + sid = Fat[sid]; + } + } + + RINOK(AddNode(-1, root.SonDid)) + + unsigned numCabs = 0; + + FOR_VECTOR (i, Refs) + { + const CItem &item = Items[Refs[i].Did]; + if (item.IsDir() || numCabs > 1) + continue; + bool isMsiName; + const UString msiName = ConvertName(item.Name, isMsiName); + if (isMsiName && !msiName.IsEmpty()) + { + // bool isThereExt = (msiName.Find(L'.') >= 0); + bool isMsiSpec = (msiName[0] == k_Msi_SpecChar); + if ((msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")) + || (!isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")) + // || (!isMsiSpec && !isThereExt) + ) + { + numCabs++; + MainSubfile = (int)i; + } + } + } + + if (numCabs > 1) + MainSubfile = -1; + + { + FOR_VECTOR (t, Items) + { + Update_PhySize_WithItem(t); + } + } + { + if (PhySize != PhySize_Aligned) + { + /* some msi (in rare cases) have unaligned size of archive, + where there is no padding data after payload data in last cluster of archive */ + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) + if (PhySize != fileSize) + PhySize = PhySize_Aligned; + } + } + { + FOR_VECTOR (t, Items) + { + const CItem &item = Items[t]; + + if (IsMsiName(item.Name)) + { + Type = k_Type_Msi; + if (memcmp(item.Name, kMspSequence, kMspSequence_Size) == 0) + { + Type = k_Type_Msp; + break; + } + continue; + } + if (AreEqualNames(item.Name, "WordDocument")) + { + Type = k_Type_Doc; + break; + } + if (AreEqualNames(item.Name, "PowerPoint Document")) + { + Type = k_Type_Ppt; + break; + } + if (AreEqualNames(item.Name, "Workbook")) + { + Type = k_Type_Xls; + break; + } + } + } + + return S_OK; +} + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CMyComPtr _stream; + CDatabase _db; +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidCTime, + kpidMTime +}; + +static const Byte kArcProps[] = +{ + kpidExtension, + kpidClusterSize, + kpidSectorSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidExtension: prop = kExtensions[(unsigned)_db.Type]; break; + case kpidPhySize: prop = _db.PhySize; break; + case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break; + case kpidSectorSize: prop = (UInt32)1 << _db.MiniSectorSizeBits; break; + case kpidMainSubfile: if (_db.MainSubfile >= 0) prop = (UInt32)_db.MainSubfile; break; + case kpidIsNotArcType: if (_db.IsNotArcType()) prop = true; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CRef &ref = _db.Refs[index]; + const CItem &item = _db.Items[ref.Did]; + + switch (propID) + { + case kpidPath: prop = _db.GetItemPath(index); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidCTime: prop = item.CTime; break; + case kpidMTime: prop = item.MTime; break; + case kpidPackSize: if (!item.IsDir()) prop = _db.GetItemPackSize(item.Size); break; + case kpidSize: if (!item.IsDir()) prop = item.Size; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + try + { + if (_db.Open(inStream) != S_OK) + return S_FALSE; + _stream = inStream; + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _db.Clear(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _db.Refs.Size(); + if (numItems == 0) + return S_OK; + UInt32 i; + UInt64 totalSize = 0; + for (i = 0; i < numItems; i++) + { + const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did]; + if (!item.IsDir()) + totalSize += item.Size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + for (i = 0; i < numItems; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _db.Items[_db.Refs[index].Did]; + Int32 res; + { + CMyComPtr outStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + totalPackSize += _db.GetItemPackSize(item.Size); + totalSize += item.Size; + + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + res = NExtract::NOperationResult::kDataError; + CMyComPtr inStream; + HRESULT hres = GetStream(index, &inStream); + if (hres == S_FALSE) + res = NExtract::NOperationResult::kDataError; + else if (hres == E_NOTIMPL) + res = NExtract::NOperationResult::kUnsupportedMethod; + else + { + RINOK(hres) + if (inStream) + { + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) + res = NExtract::NOperationResult::kOK; + } + } + } + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _db.Refs.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + const UInt32 itemIndex = _db.Refs[index].Did; + const CItem &item = _db.Items[itemIndex]; + CClusterInStream *streamSpec = new CClusterInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Stream = _stream; + streamSpec->StartOffset = 0; + + const bool isLargeStream = (itemIndex == 0 || _db.IsLargeStream(item.Size)); + const unsigned bsLog = isLargeStream ? _db.SectorSizeBits : _db.MiniSectorSizeBits; + streamSpec->BlockSizeLog = bsLog; + streamSpec->Size = item.Size; + + const UInt32 clusterSize = (UInt32)1 << bsLog; + const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog; + if (numClusters64 >= ((UInt32)1 << 31)) + return E_NOTIMPL; + streamSpec->Vector.ClearAndReserve((unsigned)numClusters64); + UInt32 sid = item.Sid; + UInt64 size = item.Size; + + if (size != 0) + { + for (;; size -= clusterSize) + { + if (isLargeStream) + { + if (sid >= _db.FatSize) + return S_FALSE; + streamSpec->Vector.AddInReserved(sid + 1); + sid = _db.Fat[sid]; + } + else + { + UInt64 val = 0; + if (sid >= _db.MatSize || !_db.GetMiniCluster(sid, val) || val >= (UInt64)1 << 32) + return S_FALSE; + streamSpec->Vector.AddInReserved((UInt32)val); + sid = _db.Mat[sid]; + } + if (size <= clusterSize) + break; + } + } + if (sid != NFatID::kEndOfChain) + return S_FALSE; + RINOK(streamSpec->InitAndSeek()) + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "Compound", "msi msp doc xls ppt", NULL, 0xE5, + kSignature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/CoderMixer2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/CoderMixer2.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.cpp 2023-09-26 16:00:00.000000000 +0000 @@ -1,1044 +1,1144 @@ -// CoderMixer2.cpp - -#include "StdAfx.h" - -#include "CoderMixer2.h" - -#ifdef USE_MIXER_ST - -STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessed = 0; - HRESULT result = S_OK; - if (_stream) - result = _stream->Read(data, size, &realProcessed); - _size += realProcessed; - if (size != 0 && realProcessed == 0) - _wasFinished = true; - if (processedSize) - *processedSize = realProcessed; - return result; -} - - -STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - _size += size; - if (processedSize) - *processedSize = size; - return result; -} - -STDMETHODIMP COutStreamCalcSize::OutStreamFinish() -{ - HRESULT result = S_OK; - if (_stream) - { - CMyComPtr outStreamFinish; - _stream.QueryInterface(IID_IOutStreamFinish, &outStreamFinish); - if (outStreamFinish) - result = outStreamFinish->OutStreamFinish(); - } - return result; -} - -#endif - - - - -namespace NCoderMixer2 { - -static void BoolVector_Fill_False(CBoolVector &v, unsigned size) -{ - v.ClearAndSetSize(size); - bool *p = &v[0]; - for (unsigned i = 0; i < size; i++) - p[i] = false; -} - -class CBondsChecks -{ - CBoolVector _coderUsed; - - bool Init(); - bool CheckCoder(unsigned coderIndex); -public: - const CBindInfo *BindInfo; - - bool Check(); -}; - -bool CBondsChecks::CheckCoder(unsigned coderIndex) -{ - const CCoderStreamsInfo &coder = BindInfo->Coders[coderIndex]; - - if (coderIndex >= _coderUsed.Size() || _coderUsed[coderIndex]) - return false; - _coderUsed[coderIndex] = true; - - UInt32 start = BindInfo->Coder_to_Stream[coderIndex]; - - for (unsigned i = 0; i < coder.NumStreams; i++) - { - UInt32 ind = start + i; - - if (BindInfo->IsStream_in_PackStreams(ind)) - continue; - - int bond = BindInfo->FindBond_for_PackStream(ind); - if (bond < 0) - return false; - if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex)) - return false; - } - - return true; -} - -bool CBondsChecks::Check() -{ - BoolVector_Fill_False(_coderUsed, BindInfo->Coders.Size()); - - if (!CheckCoder(BindInfo->UnpackCoder)) - return false; - - FOR_VECTOR(i, _coderUsed) - if (!_coderUsed[i]) - return false; - - return true; -} - -void CBindInfo::ClearMaps() -{ - Coder_to_Stream.Clear(); - Stream_to_Coder.Clear(); -} - -bool CBindInfo::CalcMapsAndCheck() -{ - ClearMaps(); - - UInt32 numStreams = 0; - - if (Coders.Size() == 0) - return false; - if (Coders.Size() - 1 != Bonds.Size()) - return false; - - FOR_VECTOR(i, Coders) - { - Coder_to_Stream.Add(numStreams); - - const CCoderStreamsInfo &c = Coders[i]; - - for (unsigned j = 0; j < c.NumStreams; j++) - Stream_to_Coder.Add(i); - - numStreams += c.NumStreams; - } - - if (numStreams != GetNum_Bonds_and_PackStreams()) - return false; - - CBondsChecks bc; - bc.BindInfo = this; - return bc.Check(); -} - - -void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes) -{ - if (unpackSize) - { - UnpackSize = *unpackSize; - UnpackSizePointer = &UnpackSize; - } - else - { - UnpackSize = 0; - UnpackSizePointer = NULL; - } - - PackSizes.ClearAndSetSize((unsigned)NumStreams); - PackSizePointers.ClearAndSetSize((unsigned)NumStreams); - - for (unsigned i = 0; i < NumStreams; i++) - { - if (packSizes && packSizes[i]) - { - PackSizes[i] = *(packSizes[i]); - PackSizePointers[i] = &PackSizes[i]; - } - else - { - PackSizes[i] = 0; - PackSizePointers[i] = NULL; - } - } -} - -bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex) -{ - if (coderIndex == _bi.UnpackCoder) - return true; - - int bond = _bi.FindBond_for_UnpackStream(coderIndex); - if (bond < 0) - throw 20150213; - - /* - UInt32 coderIndex, coderStreamIndex; - _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex); - */ - UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex]; - - if (!IsFilter_Vector[nextCoder]) - return false; - - return Is_UnpackSize_Correct_for_Coder(nextCoder); -} - -bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex) -{ - if (_bi.IsStream_in_PackStreams(streamIndex)) - return true; - - int bond = _bi.FindBond_for_PackStream(streamIndex); - if (bond < 0) - throw 20150213; - - UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex; - - if (!IsFilter_Vector[nextCoder]) - return false; - - return Is_PackSize_Correct_for_Coder(nextCoder); -} - -bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex) -{ - UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; - UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; - for (UInt32 i = 0; i < numStreams; i++) - if (!Is_PackSize_Correct_for_Stream(startIndex + i)) - return false; - return true; -} - -bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex) -{ - if (IsExternal_Vector[coderIndex]) - return true; - UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; - UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; - for (UInt32 i = 0; i < numStreams; i++) - { - UInt32 si = startIndex + i; - if (_bi.IsStream_in_PackStreams(si)) - continue; - - int bond = _bi.FindBond_for_PackStream(si); - if (bond < 0) - throw 20150213; - - if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex)) - return true; - } - return false; -} - - - - -#ifdef USE_MIXER_ST - -CMixerST::CMixerST(bool encodeMode): - CMixer(encodeMode) - {} - -CMixerST::~CMixerST() {} - -void CMixerST::AddCoder(const CCreatedCoder &cod) -{ - IsFilter_Vector.Add(cod.IsFilter); - IsExternal_Vector.Add(cod.IsExternal); - // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; - CCoderST &c2 = _coders.AddNew(); - c2.NumStreams = cod.NumStreams; - c2.Coder = cod.Coder; - c2.Coder2 = cod.Coder2; - - /* - if (isFilter) - { - c2.CanRead = true; - c2.CanWrite = true; - } - else - */ - { - IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2); - { - CMyComPtr s; - unk->QueryInterface(IID_ISequentialInStream, (void**)&s); - c2.CanRead = (s != NULL); - } - { - CMyComPtr s; - unk->QueryInterface(IID_ISequentialOutStream, (void**)&s); - c2.CanWrite = (s != NULL); - } - } -} - -CCoder &CMixerST::GetCoder(unsigned index) -{ - return _coders[index]; -} - -void CMixerST::ReInit() {} - -HRESULT CMixerST::GetInStream2( - ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ - UInt32 outStreamIndex, ISequentialInStream **inStreamRes) -{ - UInt32 coderIndex = outStreamIndex, coderStreamIndex = 0; - - if (EncodeMode) - { - _bi.GetCoder_for_Stream(outStreamIndex, coderIndex, coderStreamIndex); - if (coderStreamIndex != 0) - return E_NOTIMPL; - } - - const CCoder &coder = _coders[coderIndex]; - - CMyComPtr seqInStream; - coder.QueryInterface(IID_ISequentialInStream, (void **)&seqInStream); - if (!seqInStream) - return E_NOTIMPL; - - UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; - UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; - - bool isSet = false; - - if (numInStreams == 1) - { - CMyComPtr setStream; - coder.QueryInterface(IID_ICompressSetInStream, (void **)&setStream); - if (setStream) - { - CMyComPtr seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)); - RINOK(setStream->SetInStream(seqInStream2)); - isSet = true; - } - } - - if (!isSet && numInStreams != 0) - { - CMyComPtr setStream2; - coder.QueryInterface(IID_ICompressSetInStream2, (void **)&setStream2); - if (!setStream2) - return E_NOTIMPL; - - for (UInt32 i = 0; i < numInStreams; i++) - { - CMyComPtr seqInStream2; - RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)); - RINOK(setStream2->SetInStream2(i, seqInStream2)); - } - } - - *inStreamRes = seqInStream.Detach(); - return S_OK; -} - - -HRESULT CMixerST::GetInStream( - ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ - UInt32 inStreamIndex, ISequentialInStream **inStreamRes) -{ - CMyComPtr seqInStream; - - { - int index = -1; - if (EncodeMode) - { - if (_bi.UnpackCoder == inStreamIndex) - index = 0; - } - else - index = _bi.FindStream_in_PackStreams(inStreamIndex); - - if (index >= 0) - { - seqInStream = inStreams[(unsigned)index]; - *inStreamRes = seqInStream.Detach(); - return S_OK; - } - } - - int bond = FindBond_for_Stream( - true, // forInputStream - inStreamIndex); - if (bond < 0) - return E_INVALIDARG; - - RINOK(GetInStream2(inStreams, /* inSizes, */ - _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream)); - - while (_binderStreams.Size() <= (unsigned)bond) - _binderStreams.AddNew(); - CStBinderStream &bs = _binderStreams[bond]; - - if (bs.StreamRef || bs.InStreamSpec) - return E_NOTIMPL; - - CSequentialInStreamCalcSize *spec = new CSequentialInStreamCalcSize; - bs.StreamRef = spec; - bs.InStreamSpec = spec; - - spec->SetStream(seqInStream); - spec->Init(); - - seqInStream = bs.InStreamSpec; - - *inStreamRes = seqInStream.Detach(); - return S_OK; -} - - -HRESULT CMixerST::GetOutStream( - ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */ - UInt32 outStreamIndex, ISequentialOutStream **outStreamRes) -{ - CMyComPtr seqOutStream; - - { - int index = -1; - if (!EncodeMode) - { - if (_bi.UnpackCoder == outStreamIndex) - index = 0; - } - else - index = _bi.FindStream_in_PackStreams(outStreamIndex); - - if (index >= 0) - { - seqOutStream = outStreams[(unsigned)index]; - *outStreamRes = seqOutStream.Detach(); - return S_OK; - } - } - - int bond = FindBond_for_Stream( - false, // forInputStream - outStreamIndex); - if (bond < 0) - return E_INVALIDARG; - - UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); - - UInt32 coderIndex = inStreamIndex; - UInt32 coderStreamIndex = 0; - - if (!EncodeMode) - _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); - - CCoder &coder = _coders[coderIndex]; - - /* - if (!coder.Coder) - return E_NOTIMPL; - */ - - coder.QueryInterface(IID_ISequentialOutStream, (void **)&seqOutStream); - if (!seqOutStream) - return E_NOTIMPL; - - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; - - bool isSet = false; - - if (numOutStreams == 1) - { - CMyComPtr setOutStream; - coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); - if (setOutStream) - { - CMyComPtr seqOutStream2; - RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)); - RINOK(setOutStream->SetOutStream(seqOutStream2)); - isSet = true; - } - } - - if (!isSet && numOutStreams != 0) - { - return E_NOTIMPL; - /* - CMyComPtr setStream2; - coder.QueryInterface(IID_ICompressSetOutStream2, (void **)&setStream2); - if (!setStream2) - return E_NOTIMPL; - for (UInt32 i = 0; i < numOutStreams; i++) - { - CMyComPtr seqOutStream2; - RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)); - RINOK(setStream2->SetOutStream2(i, seqOutStream2)); - } - */ - } - - while (_binderStreams.Size() <= (unsigned)bond) - _binderStreams.AddNew(); - CStBinderStream &bs = _binderStreams[bond]; - - if (bs.StreamRef || bs.OutStreamSpec) - return E_NOTIMPL; - - COutStreamCalcSize *spec = new COutStreamCalcSize; - bs.StreamRef = (ISequentialOutStream *)spec; - bs.OutStreamSpec = spec; - - spec->SetStream(seqOutStream); - spec->Init(); - - seqOutStream = bs.OutStreamSpec; - - *outStreamRes = seqOutStream.Detach(); - return S_OK; -} - - -static HRESULT GetError(HRESULT res, HRESULT res2) -{ - if (res == res2) - return res; - if (res == S_OK) - return res2; - if (res == k_My_HRESULT_WritingWasCut) - { - if (res2 != S_OK) - return res2; - } - return res; -} - - -HRESULT CMixerST::FinishStream(UInt32 streamIndex) -{ - { - int index = -1; - if (!EncodeMode) - { - if (_bi.UnpackCoder == streamIndex) - index = 0; - } - else - index = _bi.FindStream_in_PackStreams(streamIndex); - - if (index >= 0) - return S_OK; - } - - int bond = FindBond_for_Stream( - false, // forInputStream - streamIndex); - if (bond < 0) - return E_INVALIDARG; - - UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); - - UInt32 coderIndex = inStreamIndex; - UInt32 coderStreamIndex = 0; - if (!EncodeMode) - _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); - - CCoder &coder = _coders[coderIndex]; - CMyComPtr finish; - coder.QueryInterface(IID_IOutStreamFinish, (void **)&finish); - HRESULT res = S_OK; - if (finish) - { - res = finish->OutStreamFinish(); - } - return GetError(res, FinishCoder(coderIndex)); -} - - -HRESULT CMixerST::FinishCoder(UInt32 coderIndex) -{ - CCoder &coder = _coders[coderIndex]; - - UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; - UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; - - HRESULT res = S_OK; - for (unsigned i = 0; i < numOutStreams; i++) - res = GetError(res, FinishStream(startIndex + i)); - return res; -} - - -void CMixerST::SelectMainCoder(bool useFirst) -{ - unsigned ci = _bi.UnpackCoder; - - int firstNonFilter = -1; - int firstAllowed = ci; - - for (;;) - { - const CCoderST &coder = _coders[ci]; - // break; - - if (ci != _bi.UnpackCoder) - if (EncodeMode ? !coder.CanWrite : !coder.CanRead) - { - firstAllowed = ci; - firstNonFilter = -2; - } - - if (coder.NumStreams != 1) - break; - - UInt32 st = _bi.Coder_to_Stream[ci]; - if (_bi.IsStream_in_PackStreams(st)) - break; - int bond = _bi.FindBond_for_PackStream(st); - if (bond < 0) - throw 20150213; - - if (EncodeMode ? !coder.CanRead : !coder.CanWrite) - break; - - if (firstNonFilter == -1 && !IsFilter_Vector[ci]) - firstNonFilter = ci; - - ci = _bi.Bonds[bond].UnpackIndex; - } - - if (useFirst) - ci = firstAllowed; - else if (firstNonFilter >= 0) - ci = firstNonFilter; - - MainCoderIndex = ci; -} - - -HRESULT CMixerST::Code( - ISequentialInStream * const *inStreams, - ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) -{ - _binderStreams.Clear(); - unsigned ci = MainCoderIndex; - - const CCoder &mainCoder = _coders[MainCoderIndex]; - - CObjectVector< CMyComPtr > seqInStreams; - CObjectVector< CMyComPtr > seqOutStreams; - - UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; - UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; - - UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; - UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; - - UInt32 i; - - for (i = 0; i < numInStreams; i++) - { - CMyComPtr seqInStream; - RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)); - seqInStreams.Add(seqInStream); - } - - for (i = 0; i < numOutStreams; i++) - { - CMyComPtr seqOutStream; - RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)); - seqOutStreams.Add(seqOutStream); - } - - CRecordVector< ISequentialInStream * > seqInStreamsSpec; - CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; - - for (i = 0; i < numInStreams; i++) - seqInStreamsSpec.Add(seqInStreams[i]); - for (i = 0; i < numOutStreams; i++) - seqOutStreamsSpec.Add(seqOutStreams[i]); - - for (i = 0; i < _coders.Size(); i++) - { - if (i == ci) - continue; - - CCoder &coder = _coders[i]; - - if (EncodeMode) - { - CMyComPtr initEncoder; - coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder); - if (initEncoder) - RINOK(initEncoder->InitEncoder()); - } - else - { - CMyComPtr setOutStreamSize; - coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); - if (setOutStreamSize) - RINOK(setOutStreamSize->SetOutStreamSize( - EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)); - } - } - - const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : &mainCoder.PackSizePointers.Front(); - const UInt64 * const *outSizes2 = EncodeMode ? &mainCoder.PackSizePointers.Front() : &mainCoder.UnpackSizePointer; - - HRESULT res; - if (mainCoder.Coder) - { - res = mainCoder.Coder->Code( - seqInStreamsSpec[0], seqOutStreamsSpec[0], - isSizes2[0], outSizes2[0], - progress); - } - else - { - res = mainCoder.Coder2->Code( - &seqInStreamsSpec.Front(), isSizes2, numInStreams, - &seqOutStreamsSpec.Front(), outSizes2, numOutStreams, - progress); - } - - if (res == k_My_HRESULT_WritingWasCut) - res = S_OK; - - if (res == S_OK || res == S_FALSE) - { - res = GetError(res, FinishCoder(ci)); - } - - for (i = 0; i < _binderStreams.Size(); i++) - { - const CStBinderStream &bs = _binderStreams[i]; - if (bs.InStreamSpec) - bs.InStreamSpec->ReleaseStream(); - else - bs.OutStreamSpec->ReleaseStream(); - } - - if (res == k_My_HRESULT_WritingWasCut) - res = S_OK; - return res; -} - - -HRESULT CMixerST::GetMainUnpackStream( - ISequentialInStream * const *inStreams, - ISequentialInStream **inStreamRes) -{ - CMyComPtr seqInStream; - - RINOK(GetInStream2(inStreams, /* inSizes, */ - _bi.UnpackCoder, &seqInStream)) - - FOR_VECTOR (i, _coders) - { - CCoder &coder = _coders[i]; - CMyComPtr setOutStreamSize; - coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); - if (setOutStreamSize) - { - RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)); - } - } - - *inStreamRes = seqInStream.Detach(); - return S_OK; -} - - -UInt64 CMixerST::GetBondStreamSize(unsigned bondIndex) const -{ - const CStBinderStream &bs = _binderStreams[bondIndex]; - if (bs.InStreamSpec) - return bs.InStreamSpec->GetSize(); - return bs.OutStreamSpec->GetSize(); -} - -#endif - - - - - - -#ifdef USE_MIXER_MT - - -void CCoderMT::Execute() -{ - try - { - Code(NULL); - } - catch(...) - { - Result = E_FAIL; - } -} - -void CCoderMT::Code(ICompressProgressInfo *progress) -{ - unsigned numInStreams = EncodeMode ? 1 : NumStreams; - unsigned numOutStreams = EncodeMode ? NumStreams : 1; - - InStreamPointers.ClearAndReserve(numInStreams); - OutStreamPointers.ClearAndReserve(numOutStreams); - - unsigned i; - - for (i = 0; i < numInStreams; i++) - InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]); - - for (i = 0; i < numOutStreams; i++) - OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]); - - // we suppose that UnpackSizePointer and PackSizePointers contain correct pointers. - /* - if (UnpackSizePointer) - UnpackSizePointer = &UnpackSize; - for (i = 0; i < NumStreams; i++) - if (PackSizePointers[i]) - PackSizePointers[i] = &PackSizes[i]; - */ - - CReleaser releaser(*this); - - if (Coder) - Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], - EncodeMode ? UnpackSizePointer : PackSizePointers[0], - EncodeMode ? PackSizePointers[0] : UnpackSizePointer, - progress); - else - Result = Coder2->Code( - &InStreamPointers.Front(), EncodeMode ? &UnpackSizePointer : &PackSizePointers.Front(), numInStreams, - &OutStreamPointers.Front(), EncodeMode ? &PackSizePointers.Front(): &UnpackSizePointer, numOutStreams, - progress); -} - -HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo) -{ - CMixer::SetBindInfo(bindInfo); - - _streamBinders.Clear(); - FOR_VECTOR (i, _bi.Bonds) - { - RINOK(_streamBinders.AddNew().CreateEvents()); - } - return S_OK; -} - -void CMixerMT::AddCoder(const CCreatedCoder &cod) -{ - IsFilter_Vector.Add(cod.IsFilter); - IsExternal_Vector.Add(cod.IsExternal); - // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; - CCoderMT &c2 = _coders.AddNew(); - c2.NumStreams = cod.NumStreams; - c2.Coder = cod.Coder; - c2.Coder2 = cod.Coder2; - c2.EncodeMode = EncodeMode; -} - -CCoder &CMixerMT::GetCoder(unsigned index) -{ - return _coders[index]; -} - -void CMixerMT::ReInit() -{ - FOR_VECTOR (i, _streamBinders) - _streamBinders[i].ReInit(); -} - -void CMixerMT::SelectMainCoder(bool useFirst) -{ - unsigned ci = _bi.UnpackCoder; - - if (!useFirst) - for (;;) - { - if (_coders[ci].NumStreams != 1) - break; - if (!IsFilter_Vector[ci]) - break; - - UInt32 st = _bi.Coder_to_Stream[ci]; - if (_bi.IsStream_in_PackStreams(st)) - break; - int bond = _bi.FindBond_for_PackStream(st); - if (bond < 0) - throw 20150213; - ci = _bi.Bonds[bond].UnpackIndex; - } - - MainCoderIndex = ci; -} - -HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams) -{ - unsigned i; - - for (i = 0; i < _coders.Size(); i++) - { - CCoderMT &coderInfo = _coders[i]; - const CCoderStreamsInfo &csi = _bi.Coders[i]; - - UInt32 j; - - unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; - unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; - - coderInfo.InStreams.Clear(); - for (j = 0; j < numInStreams; j++) - coderInfo.InStreams.AddNew(); - - coderInfo.OutStreams.Clear(); - for (j = 0; j < numOutStreams; j++) - coderInfo.OutStreams.AddNew(); - } - - for (i = 0; i < _bi.Bonds.Size(); i++) - { - const CBond &bond = _bi.Bonds[i]; - - UInt32 inCoderIndex, inCoderStreamIndex; - UInt32 outCoderIndex, outCoderStreamIndex; - - { - UInt32 coderIndex, coderStreamIndex; - _bi.GetCoder_for_Stream(bond.PackIndex, coderIndex, coderStreamIndex); - - inCoderIndex = EncodeMode ? bond.UnpackIndex : coderIndex; - outCoderIndex = EncodeMode ? coderIndex : bond.UnpackIndex; - - inCoderStreamIndex = EncodeMode ? 0 : coderStreamIndex; - outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0; - } - - _streamBinders[i].CreateStreams( - &_coders[inCoderIndex].InStreams[inCoderStreamIndex], - &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); - - CMyComPtr inSetSize, outSetSize; - _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize); - _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize); - if (inSetSize && outSetSize) - { - const UInt32 kBufSize = 1 << 19; - inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize); - outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize); - } - } - - { - CCoderMT &cod = _coders[_bi.UnpackCoder]; - if (EncodeMode) - cod.InStreams[0] = inStreams[0]; - else - cod.OutStreams[0] = outStreams[0]; - } - - for (i = 0; i < _bi.PackStreams.Size(); i++) - { - UInt32 coderIndex, coderStreamIndex; - _bi.GetCoder_for_Stream(_bi.PackStreams[i], coderIndex, coderStreamIndex); - CCoderMT &cod = _coders[coderIndex]; - if (EncodeMode) - cod.OutStreams[coderStreamIndex] = outStreams[i]; - else - cod.InStreams[coderStreamIndex] = inStreams[i]; - } - - return S_OK; -} - -HRESULT CMixerMT::ReturnIfError(HRESULT code) -{ - FOR_VECTOR (i, _coders) - if (_coders[i].Result == code) - return code; - return S_OK; -} - -HRESULT CMixerMT::Code( - ISequentialInStream * const *inStreams, - ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) -{ - Init(inStreams, outStreams); - - unsigned i; - for (i = 0; i < _coders.Size(); i++) - if (i != MainCoderIndex) - { - RINOK(_coders[i].Create()); - } - - for (i = 0; i < _coders.Size(); i++) - if (i != MainCoderIndex) - _coders[i].Start(); - - _coders[MainCoderIndex].Code(progress); - - for (i = 0; i < _coders.Size(); i++) - if (i != MainCoderIndex) - _coders[i].WaitExecuteFinish(); - - RINOK(ReturnIfError(E_ABORT)); - RINOK(ReturnIfError(E_OUTOFMEMORY)); - - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result != S_OK - && result != k_My_HRESULT_WritingWasCut - && result != S_FALSE - && result != E_FAIL) - return result; - } - - RINOK(ReturnIfError(S_FALSE)); - - for (i = 0; i < _coders.Size(); i++) - { - HRESULT result = _coders[i].Result; - if (result != S_OK && result != k_My_HRESULT_WritingWasCut) - return result; - } - - return S_OK; -} - -UInt64 CMixerMT::GetBondStreamSize(unsigned bondIndex) const -{ - return _streamBinders[bondIndex].ProcessedSize; -} - -#endif - -} +// CoderMixer2.cpp + +#include "StdAfx.h" + +#include "CoderMixer2.h" + +#ifdef USE_MIXER_ST + +Z7_COM7F_IMF(CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessed = 0; + HRESULT result = S_OK; + if (_stream) + result = _stream->Read(data, size, &realProcessed); + _size += realProcessed; + if (size != 0 && realProcessed == 0) + _wasFinished = true; + if (processedSize) + *processedSize = realProcessed; + return result; +} + + +Z7_COM7F_IMF(COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +Z7_COM7F_IMF(COutStreamCalcSize::OutStreamFinish()) +{ + HRESULT result = S_OK; + if (_stream) + { + CMyComPtr outStreamFinish; + _stream.QueryInterface(IID_IOutStreamFinish, &outStreamFinish); + if (outStreamFinish) + result = outStreamFinish->OutStreamFinish(); + } + return result; +} + +#endif + + + + +namespace NCoderMixer2 { + +static void BoolVector_Fill_False(CBoolVector &v, unsigned size) +{ + v.ClearAndSetSize(size); + bool *p = &v[0]; + for (unsigned i = 0; i < size; i++) + p[i] = false; +} + + +HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const +{ + if (Coder) + { + if (PackSizePointers.IsEmpty() || !PackSizePointers[0]) + return S_OK; + CMyComPtr getInStreamProcessedSize; + Coder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); + // if (!getInStreamProcessedSize) return E_FAIL; + if (getInStreamProcessedSize) + { + UInt64 processed; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) + if (processed != (UInt64)(Int64)-1) + { + const UInt64 size = PackSizes[0]; + if (processed < size && Finish) + dataAfterEnd_Error = true; + if (processed > size) + { + // InternalPackSizeError = true; + // return S_FALSE; + } + } + } + } + else if (Coder2) + { + CMyComPtr getInStreamProcessedSize2; + Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2); + if (getInStreamProcessedSize2) + FOR_VECTOR (i, PackSizePointers) + { + if (!PackSizePointers[i]) + continue; + UInt64 processed; + RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed)) + if (processed != (UInt64)(Int64)-1) + { + const UInt64 size = PackSizes[i]; + if (processed < size && Finish) + dataAfterEnd_Error = true; + else if (processed > size) + { + // InternalPackSizeError = true; + // return S_FALSE; + } + } + } + } + + return S_OK; +} + + + +class CBondsChecks +{ + CBoolVector _coderUsed; + + bool Init(); + bool CheckCoder(unsigned coderIndex); +public: + const CBindInfo *BindInfo; + + bool Check(); +}; + +bool CBondsChecks::CheckCoder(unsigned coderIndex) +{ + const CCoderStreamsInfo &coder = BindInfo->Coders[coderIndex]; + + if (coderIndex >= _coderUsed.Size() || _coderUsed[coderIndex]) + return false; + _coderUsed[coderIndex] = true; + + const UInt32 start = BindInfo->Coder_to_Stream[coderIndex]; + + for (unsigned i = 0; i < coder.NumStreams; i++) + { + UInt32 ind = start + i; + + if (BindInfo->IsStream_in_PackStreams(ind)) + continue; + + const int bond = BindInfo->FindBond_for_PackStream(ind); + if (bond < 0) + return false; + if (!CheckCoder(BindInfo->Bonds[(unsigned)bond].UnpackIndex)) + return false; + } + + return true; +} + +bool CBondsChecks::Check() +{ + BoolVector_Fill_False(_coderUsed, BindInfo->Coders.Size()); + + if (!CheckCoder(BindInfo->UnpackCoder)) + return false; + + FOR_VECTOR(i, _coderUsed) + if (!_coderUsed[i]) + return false; + + return true; +} + +void CBindInfo::ClearMaps() +{ + Coder_to_Stream.Clear(); + Stream_to_Coder.Clear(); +} + +bool CBindInfo::CalcMapsAndCheck() +{ + ClearMaps(); + + UInt32 numStreams = 0; + + if (Coders.Size() == 0) + return false; + if (Coders.Size() - 1 != Bonds.Size()) + return false; + + FOR_VECTOR(i, Coders) + { + Coder_to_Stream.Add(numStreams); + + const CCoderStreamsInfo &c = Coders[i]; + + for (unsigned j = 0; j < c.NumStreams; j++) + Stream_to_Coder.Add(i); + + numStreams += c.NumStreams; + } + + if (numStreams != GetNum_Bonds_and_PackStreams()) + return false; + + CBondsChecks bc; + bc.BindInfo = this; + return bc.Check(); +} + + +void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) +{ + Finish = finish; + + if (unpackSize) + { + UnpackSize = *unpackSize; + UnpackSizePointer = &UnpackSize; + } + else + { + UnpackSize = 0; + UnpackSizePointer = NULL; + } + + PackSizes.ClearAndSetSize((unsigned)NumStreams); + PackSizePointers.ClearAndSetSize((unsigned)NumStreams); + + for (unsigned i = 0; i < NumStreams; i++) + { + if (packSizes && packSizes[i]) + { + PackSizes[i] = *(packSizes[i]); + PackSizePointers[i] = &PackSizes[i]; + } + else + { + PackSizes[i] = 0; + PackSizePointers[i] = NULL; + } + } +} + +bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex) +{ + if (coderIndex == _bi.UnpackCoder) + return true; + + const int bond = _bi.FindBond_for_UnpackStream(coderIndex); + if (bond < 0) + throw 20150213; + + /* + UInt32 coderIndex, coderStreamIndex; + _bi.GetCoder_for_Stream(_bi.Bonds[(unsigned)bond].PackIndex, coderIndex, coderStreamIndex); + */ + const UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[(unsigned)bond].PackIndex]; + + if (!IsFilter_Vector[nextCoder]) + return false; + + return Is_UnpackSize_Correct_for_Coder(nextCoder); +} + +bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex) +{ + if (_bi.IsStream_in_PackStreams(streamIndex)) + return true; + + const int bond = _bi.FindBond_for_PackStream(streamIndex); + if (bond < 0) + throw 20150213; + + const UInt32 nextCoder = _bi.Bonds[(unsigned)bond].UnpackIndex; + + if (!IsFilter_Vector[nextCoder]) + return false; + + return Is_PackSize_Correct_for_Coder(nextCoder); +} + +bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex) +{ + const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; + const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; + for (UInt32 i = 0; i < numStreams; i++) + if (!Is_PackSize_Correct_for_Stream(startIndex + i)) + return false; + return true; +} + +bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex) +{ + if (IsExternal_Vector[coderIndex]) + return true; + const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; + const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; + for (UInt32 i = 0; i < numStreams; i++) + { + const UInt32 si = startIndex + i; + if (_bi.IsStream_in_PackStreams(si)) + continue; + + const int bond = _bi.FindBond_for_PackStream(si); + if (bond < 0) + throw 20150213; + + if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[(unsigned)bond].UnpackIndex)) + return true; + } + return false; +} + + + + +#ifdef USE_MIXER_ST + +CMixerST::CMixerST(bool encodeMode): + CMixer(encodeMode) + {} + +CMixerST::~CMixerST() {} + +void CMixerST::AddCoder(const CCreatedCoder &cod) +{ + IsFilter_Vector.Add(cod.IsFilter); + IsExternal_Vector.Add(cod.IsExternal); + // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; + CCoderST &c2 = _coders.AddNew(); + c2.NumStreams = cod.NumStreams; + c2.Coder = cod.Coder; + c2.Coder2 = cod.Coder2; + + /* + if (isFilter) + { + c2.CanRead = true; + c2.CanWrite = true; + } + else + */ + { + IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2); + { + Z7_DECL_CMyComPtr_QI_FROM(ISequentialInStream, s, unk) + c2.CanRead = (s != NULL); + } + { + Z7_DECL_CMyComPtr_QI_FROM(ISequentialOutStream, s, unk) + c2.CanWrite = (s != NULL); + } + } +} + +CCoder &CMixerST::GetCoder(unsigned index) +{ + return _coders[index]; +} + +HRESULT CMixerST::ReInit2() { return S_OK; } + +HRESULT CMixerST::GetInStream2( + ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ + UInt32 outStreamIndex, ISequentialInStream **inStreamRes) +{ + UInt32 coderIndex = outStreamIndex, coderStreamIndex = 0; + + if (EncodeMode) + { + _bi.GetCoder_for_Stream(outStreamIndex, coderIndex, coderStreamIndex); + if (coderStreamIndex != 0) + return E_NOTIMPL; + } + + const CCoder &coder = _coders[coderIndex]; + + CMyComPtr seqInStream; + coder.QueryInterface(IID_ISequentialInStream, (void **)&seqInStream); + if (!seqInStream) + return E_NOTIMPL; + + const UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; + const UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; + + bool isSet = false; + + if (numInStreams == 1) + { + CMyComPtr setStream; + coder.QueryInterface(IID_ICompressSetInStream, (void **)&setStream); + if (setStream) + { + CMyComPtr seqInStream2; + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)) + RINOK(setStream->SetInStream(seqInStream2)) + isSet = true; + } + } + + if (!isSet && numInStreams != 0) + { + CMyComPtr setStream2; + coder.QueryInterface(IID_ICompressSetInStream2, (void **)&setStream2); + if (!setStream2) + return E_NOTIMPL; + + for (UInt32 i = 0; i < numInStreams; i++) + { + CMyComPtr seqInStream2; + RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)) + RINOK(setStream2->SetInStream2(i, seqInStream2)) + } + } + + *inStreamRes = seqInStream.Detach(); + return S_OK; +} + + +HRESULT CMixerST::GetInStream( + ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ + UInt32 inStreamIndex, ISequentialInStream **inStreamRes) +{ + CMyComPtr seqInStream; + + { + int index = -1; + if (EncodeMode) + { + if (_bi.UnpackCoder == inStreamIndex) + index = 0; + } + else + index = _bi.FindStream_in_PackStreams(inStreamIndex); + + if (index >= 0) + { + seqInStream = inStreams[(unsigned)index]; + *inStreamRes = seqInStream.Detach(); + return S_OK; + } + } + + const int bond = FindBond_for_Stream( + true, // forInputStream + inStreamIndex); + if (bond < 0) + return E_INVALIDARG; + + RINOK(GetInStream2(inStreams, /* inSizes, */ + _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream)) + + while (_binderStreams.Size() <= (unsigned)bond) + _binderStreams.AddNew(); + CStBinderStream &bs = _binderStreams[(unsigned)bond]; + + if (bs.StreamRef || bs.InStreamSpec) + return E_NOTIMPL; + + CSequentialInStreamCalcSize *spec = new CSequentialInStreamCalcSize; + bs.StreamRef = spec; + bs.InStreamSpec = spec; + + spec->SetStream(seqInStream); + spec->Init(); + + seqInStream = bs.InStreamSpec; + + *inStreamRes = seqInStream.Detach(); + return S_OK; +} + + +HRESULT CMixerST::GetOutStream( + ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */ + UInt32 outStreamIndex, ISequentialOutStream **outStreamRes) +{ + CMyComPtr seqOutStream; + + { + int index = -1; + if (!EncodeMode) + { + if (_bi.UnpackCoder == outStreamIndex) + index = 0; + } + else + index = _bi.FindStream_in_PackStreams(outStreamIndex); + + if (index >= 0) + { + seqOutStream = outStreams[(unsigned)index]; + *outStreamRes = seqOutStream.Detach(); + return S_OK; + } + } + + const int bond = FindBond_for_Stream( + false, // forInputStream + outStreamIndex); + if (bond < 0) + return E_INVALIDARG; + + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); + + UInt32 coderIndex = inStreamIndex; + UInt32 coderStreamIndex = 0; + + if (!EncodeMode) + _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); + + CCoder &coder = _coders[coderIndex]; + + /* + if (!coder.Coder) + return E_NOTIMPL; + */ + + coder.QueryInterface(IID_ISequentialOutStream, (void **)&seqOutStream); + if (!seqOutStream) + return E_NOTIMPL; + + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + + bool isSet = false; + + if (numOutStreams == 1) + { + CMyComPtr setOutStream; + coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); + if (setOutStream) + { + CMyComPtr seqOutStream2; + RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)) + RINOK(setOutStream->SetOutStream(seqOutStream2)) + isSet = true; + } + } + + if (!isSet && numOutStreams != 0) + { + return E_NOTIMPL; + /* + CMyComPtr setStream2; + coder.QueryInterface(IID_ICompressSetOutStream2, (void **)&setStream2); + if (!setStream2) + return E_NOTIMPL; + for (UInt32 i = 0; i < numOutStreams; i++) + { + CMyComPtr seqOutStream2; + RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)) + RINOK(setStream2->SetOutStream2(i, seqOutStream2)) + } + */ + } + + while (_binderStreams.Size() <= (unsigned)bond) + _binderStreams.AddNew(); + CStBinderStream &bs = _binderStreams[(unsigned)bond]; + + if (bs.StreamRef || bs.OutStreamSpec) + return E_NOTIMPL; + + COutStreamCalcSize *spec = new COutStreamCalcSize; + bs.StreamRef = (ISequentialOutStream *)spec; + bs.OutStreamSpec = spec; + + spec->SetStream(seqOutStream); + spec->Init(); + + seqOutStream = bs.OutStreamSpec; + + *outStreamRes = seqOutStream.Detach(); + return S_OK; +} + + +static HRESULT GetError(HRESULT res, HRESULT res2) +{ + if (res == res2) + return res; + if (res == S_OK) + return res2; + if (res == k_My_HRESULT_WritingWasCut) + { + if (res2 != S_OK) + return res2; + } + return res; +} + + +HRESULT CMixerST::FinishStream(UInt32 streamIndex) +{ + { + int index = -1; + if (!EncodeMode) + { + if (_bi.UnpackCoder == streamIndex) + index = 0; + } + else + index = _bi.FindStream_in_PackStreams(streamIndex); + + if (index >= 0) + return S_OK; + } + + const int bond = FindBond_for_Stream( + false, // forInputStream + streamIndex); + if (bond < 0) + return E_INVALIDARG; + + const UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode); + + UInt32 coderIndex = inStreamIndex; + UInt32 coderStreamIndex = 0; + if (!EncodeMode) + _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); + + CCoder &coder = _coders[coderIndex]; + CMyComPtr finish; + coder.QueryInterface(IID_IOutStreamFinish, (void **)&finish); + HRESULT res = S_OK; + if (finish) + { + res = finish->OutStreamFinish(); + } + return GetError(res, FinishCoder(coderIndex)); +} + + +HRESULT CMixerST::FinishCoder(UInt32 coderIndex) +{ + CCoder &coder = _coders[coderIndex]; + + const UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; + const UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; + + HRESULT res = S_OK; + for (unsigned i = 0; i < numOutStreams; i++) + res = GetError(res, FinishStream(startIndex + i)); + return res; +} + + +void CMixerST::SelectMainCoder(bool useFirst) +{ + unsigned ci = _bi.UnpackCoder; + + int firstNonFilter = -1; + unsigned firstAllowed = ci; + + for (;;) + { + const CCoderST &coder = _coders[ci]; + // break; + + if (ci != _bi.UnpackCoder) + if (EncodeMode ? !coder.CanWrite : !coder.CanRead) + { + firstAllowed = ci; + firstNonFilter = -2; + } + + if (coder.NumStreams != 1) + break; + + const UInt32 st = _bi.Coder_to_Stream[ci]; + if (_bi.IsStream_in_PackStreams(st)) + break; + const int bond = _bi.FindBond_for_PackStream(st); + if (bond < 0) + throw 20150213; + + if (EncodeMode ? !coder.CanRead : !coder.CanWrite) + break; + + if (firstNonFilter == -1 && !IsFilter_Vector[ci]) + firstNonFilter = (int)ci; + + ci = _bi.Bonds[(unsigned)bond].UnpackIndex; + } + + if (useFirst) + ci = firstAllowed; + else if (firstNonFilter >= 0) + ci = (unsigned)firstNonFilter; + + MainCoderIndex = ci; +} + + +HRESULT CMixerST::Code( + ISequentialInStream * const *inStreams, + ISequentialOutStream * const *outStreams, + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) +{ + // InternalPackSizeError = false; + dataAfterEnd_Error = false; + + _binderStreams.Clear(); + const unsigned ci = MainCoderIndex; + + const CCoder &mainCoder = _coders[MainCoderIndex]; + + CObjectVector< CMyComPtr > seqInStreams; + CObjectVector< CMyComPtr > seqOutStreams; + + const UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; + const UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; + + const UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + const UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; + + UInt32 i; + + for (i = 0; i < numInStreams; i++) + { + CMyComPtr seqInStream; + RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)) + seqInStreams.Add(seqInStream); + } + + for (i = 0; i < numOutStreams; i++) + { + CMyComPtr seqOutStream; + RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)) + seqOutStreams.Add(seqOutStream); + } + + CRecordVector< ISequentialInStream * > seqInStreamsSpec; + CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; + + for (i = 0; i < numInStreams; i++) + seqInStreamsSpec.Add(seqInStreams[i]); + for (i = 0; i < numOutStreams; i++) + seqOutStreamsSpec.Add(seqOutStreams[i]); + + for (i = 0; i < _coders.Size(); i++) + { + if (i == ci) + continue; + + CCoder &coder = _coders[i]; + + if (EncodeMode) + { + CMyComPtr initEncoder; + coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder); + if (initEncoder) + { + RINOK(initEncoder->InitEncoder()) + } + } + else + { + CMyComPtr setOutStreamSize; + coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); + if (setOutStreamSize) + { + RINOK(setOutStreamSize->SetOutStreamSize( + EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)) + } + } + } + + const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : mainCoder.PackSizePointers.ConstData(); + const UInt64 * const *outSizes2 = EncodeMode ? mainCoder.PackSizePointers.ConstData() : &mainCoder.UnpackSizePointer; + + HRESULT res; + if (mainCoder.Coder) + { + res = mainCoder.Coder->Code( + seqInStreamsSpec[0], seqOutStreamsSpec[0], + isSizes2[0], outSizes2[0], + progress); + } + else + { + res = mainCoder.Coder2->Code( + seqInStreamsSpec.ConstData(), isSizes2, numInStreams, + seqOutStreamsSpec.ConstData(), outSizes2, numOutStreams, + progress); + } + + if (res == k_My_HRESULT_WritingWasCut) + res = S_OK; + + if (res == S_OK || res == S_FALSE) + { + res = GetError(res, FinishCoder(ci)); + } + + for (i = 0; i < _binderStreams.Size(); i++) + { + const CStBinderStream &bs = _binderStreams[i]; + if (bs.InStreamSpec) + bs.InStreamSpec->ReleaseStream(); + else + bs.OutStreamSpec->ReleaseStream(); + } + + if (res == k_My_HRESULT_WritingWasCut) + res = S_OK; + + if (res != S_OK) + return res; + + for (i = 0; i < _coders.Size(); i++) + { + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */)) + } + + return S_OK; +} + + +HRESULT CMixerST::GetMainUnpackStream( + ISequentialInStream * const *inStreams, + ISequentialInStream **inStreamRes) +{ + CMyComPtr seqInStream; + + RINOK(GetInStream2(inStreams, /* inSizes, */ + _bi.UnpackCoder, &seqInStream)) + + FOR_VECTOR (i, _coders) + { + CCoder &coder = _coders[i]; + CMyComPtr setOutStreamSize; + coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); + if (setOutStreamSize) + { + RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)) + } + } + + *inStreamRes = seqInStream.Detach(); + return S_OK; +} + + +UInt64 CMixerST::GetBondStreamSize(unsigned bondIndex) const +{ + const CStBinderStream &bs = _binderStreams[bondIndex]; + if (bs.InStreamSpec) + return bs.InStreamSpec->GetSize(); + return bs.OutStreamSpec->GetSize(); +} + +#endif + + + + + + +#ifdef USE_MIXER_MT + + +void CCoderMT::Execute() +{ + try + { + Code(NULL); + } + catch(...) + { + Result = E_FAIL; + } +} + +void CCoderMT::Code(ICompressProgressInfo *progress) +{ + unsigned numInStreams = EncodeMode ? 1 : NumStreams; + unsigned numOutStreams = EncodeMode ? NumStreams : 1; + + InStreamPointers.ClearAndReserve(numInStreams); + OutStreamPointers.ClearAndReserve(numOutStreams); + + unsigned i; + + for (i = 0; i < numInStreams; i++) + InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]); + + for (i = 0; i < numOutStreams; i++) + OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]); + + // we suppose that UnpackSizePointer and PackSizePointers contain correct pointers. + /* + if (UnpackSizePointer) + UnpackSizePointer = &UnpackSize; + for (i = 0; i < NumStreams; i++) + if (PackSizePointers[i]) + PackSizePointers[i] = &PackSizes[i]; + */ + + CReleaser releaser(*this); + + if (Coder) + Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], + EncodeMode ? UnpackSizePointer : PackSizePointers[0], + EncodeMode ? PackSizePointers[0] : UnpackSizePointer, + progress); + else + Result = Coder2->Code( + InStreamPointers.ConstData(), EncodeMode ? &UnpackSizePointer : PackSizePointers.ConstData(), numInStreams, + OutStreamPointers.ConstData(), EncodeMode ? PackSizePointers.ConstData(): &UnpackSizePointer, numOutStreams, + progress); +} + +HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo) +{ + CMixer::SetBindInfo(bindInfo); + + _streamBinders.Clear(); + FOR_VECTOR (i, _bi.Bonds) + { + // RINOK(_streamBinders.AddNew().CreateEvents()) + _streamBinders.AddNew(); + } + return S_OK; +} + +void CMixerMT::AddCoder(const CCreatedCoder &cod) +{ + IsFilter_Vector.Add(cod.IsFilter); + IsExternal_Vector.Add(cod.IsExternal); + // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; + CCoderMT &c2 = _coders.AddNew(); + c2.NumStreams = cod.NumStreams; + c2.Coder = cod.Coder; + c2.Coder2 = cod.Coder2; + c2.EncodeMode = EncodeMode; +} + +CCoder &CMixerMT::GetCoder(unsigned index) +{ + return _coders[index]; +} + +HRESULT CMixerMT::ReInit2() +{ + FOR_VECTOR (i, _streamBinders) + { + RINOK(_streamBinders[i].Create_ReInit()) + } + return S_OK; +} + +void CMixerMT::SelectMainCoder(bool useFirst) +{ + unsigned ci = _bi.UnpackCoder; + + if (!useFirst) + for (;;) + { + if (_coders[ci].NumStreams != 1) + break; + if (!IsFilter_Vector[ci]) + break; + + UInt32 st = _bi.Coder_to_Stream[ci]; + if (_bi.IsStream_in_PackStreams(st)) + break; + const int bond = _bi.FindBond_for_PackStream(st); + if (bond < 0) + throw 20150213; + ci = _bi.Bonds[(unsigned)bond].UnpackIndex; + } + + MainCoderIndex = ci; +} + +HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams) +{ + unsigned i; + + for (i = 0; i < _coders.Size(); i++) + { + CCoderMT &coderInfo = _coders[i]; + const CCoderStreamsInfo &csi = _bi.Coders[i]; + + UInt32 j; + + const unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; + const unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; + + coderInfo.InStreams.Clear(); + for (j = 0; j < numInStreams; j++) + coderInfo.InStreams.AddNew(); + + coderInfo.OutStreams.Clear(); + for (j = 0; j < numOutStreams; j++) + coderInfo.OutStreams.AddNew(); + } + + for (i = 0; i < _bi.Bonds.Size(); i++) + { + const CBond &bond = _bi.Bonds[i]; + + UInt32 inCoderIndex, inCoderStreamIndex; + UInt32 outCoderIndex, outCoderStreamIndex; + + { + UInt32 coderIndex, coderStreamIndex; + _bi.GetCoder_for_Stream(bond.PackIndex, coderIndex, coderStreamIndex); + + inCoderIndex = EncodeMode ? bond.UnpackIndex : coderIndex; + outCoderIndex = EncodeMode ? coderIndex : bond.UnpackIndex; + + inCoderStreamIndex = EncodeMode ? 0 : coderStreamIndex; + outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0; + } + + _streamBinders[i].CreateStreams2( + _coders[inCoderIndex].InStreams[inCoderStreamIndex], + _coders[outCoderIndex].OutStreams[outCoderStreamIndex]); + + CMyComPtr inSetSize, outSetSize; + _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize); + _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize); + if (inSetSize && outSetSize) + { + const UInt32 kBufSize = 1 << 19; + inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize); + outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize); + } + } + + { + CCoderMT &cod = _coders[_bi.UnpackCoder]; + if (EncodeMode) + cod.InStreams[0] = inStreams[0]; + else + cod.OutStreams[0] = outStreams[0]; + } + + for (i = 0; i < _bi.PackStreams.Size(); i++) + { + UInt32 coderIndex, coderStreamIndex; + _bi.GetCoder_for_Stream(_bi.PackStreams[i], coderIndex, coderStreamIndex); + CCoderMT &cod = _coders[coderIndex]; + if (EncodeMode) + cod.OutStreams[coderStreamIndex] = outStreams[i]; + else + cod.InStreams[coderStreamIndex] = inStreams[i]; + } + + return S_OK; +} + +HRESULT CMixerMT::ReturnIfError(HRESULT code) +{ + FOR_VECTOR (i, _coders) + if (_coders[i].Result == code) + return code; + return S_OK; +} + +HRESULT CMixerMT::Code( + ISequentialInStream * const *inStreams, + ISequentialOutStream * const *outStreams, + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) +{ + // InternalPackSizeError = false; + dataAfterEnd_Error = false; + + Init(inStreams, outStreams); + + unsigned i; + for (i = 0; i < _coders.Size(); i++) + if (i != MainCoderIndex) + { + const WRes wres = _coders[i].Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + + for (i = 0; i < _coders.Size(); i++) + if (i != MainCoderIndex) + { + const WRes wres = _coders[i].Start(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + + _coders[MainCoderIndex].Code(progress); + + WRes wres = 0; + for (i = 0; i < _coders.Size(); i++) + if (i != MainCoderIndex) + { + WRes wres2 = _coders[i].WaitExecuteFinish(); + if (wres == 0) + wres = wres2; + } + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + + RINOK(ReturnIfError(E_ABORT)) + RINOK(ReturnIfError(E_OUTOFMEMORY)) + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK + && result != k_My_HRESULT_WritingWasCut + && result != S_FALSE + && result != E_FAIL) + return result; + } + + RINOK(ReturnIfError(S_FALSE)) + + for (i = 0; i < _coders.Size(); i++) + { + HRESULT result = _coders[i].Result; + if (result != S_OK && result != k_My_HRESULT_WritingWasCut) + return result; + } + + for (i = 0; i < _coders.Size(); i++) + { + RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */)) + } + + return S_OK; +} + +UInt64 CMixerMT::GetBondStreamSize(unsigned bondIndex) const +{ + return _streamBinders[bondIndex].ProcessedSize; +} + +#endif + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/CoderMixer2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/CoderMixer2.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/CoderMixer2.h 2023-04-05 10:00:00.000000000 +0000 @@ -1,437 +1,447 @@ -// CoderMixer2.h - -#ifndef __CODER_MIXER2_H -#define __CODER_MIXER2_H - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyVector.h" - -#include "../../ICoder.h" - -#include "../../Common/CreateCoder.h" - -#ifdef _7ZIP_ST - #define USE_MIXER_ST -#else - #define USE_MIXER_MT - #ifndef _SFX - #define USE_MIXER_ST - #endif -#endif - -#ifdef USE_MIXER_MT -#include "../../Common/StreamBinder.h" -#include "../../Common/VirtThread.h" -#endif - - - -#ifdef USE_MIXER_ST - -class CSequentialInStreamCalcSize: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: - CMyComPtr _stream; - UInt64 _size; - bool _wasFinished; -public: - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - _wasFinished = false; - } - void ReleaseStream() { _stream.Release(); } - UInt64 GetSize() const { return _size; } - bool WasFinished() const { return _wasFinished; } -}; - - -class COutStreamCalcSize: - public ISequentialOutStream, - public IOutStreamFinish, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; -public: - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init() { _size = 0; } - UInt64 GetSize() const { return _size; } -}; - -#endif - - - -namespace NCoderMixer2 { - -struct CBond -{ - UInt32 PackIndex; - UInt32 UnpackIndex; - - UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; } - UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; } -}; - - -struct CCoderStreamsInfo -{ - UInt32 NumStreams; -}; - - -struct CBindInfo -{ - CRecordVector Coders; - CRecordVector Bonds; - CRecordVector PackStreams; - unsigned UnpackCoder; - - unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); } - - int FindBond_for_PackStream(UInt32 packStream) const - { - FOR_VECTOR (i, Bonds) - if (Bonds[i].PackIndex == packStream) - return i; - return -1; - } - - int FindBond_for_UnpackStream(UInt32 unpackStream) const - { - FOR_VECTOR (i, Bonds) - if (Bonds[i].UnpackIndex == unpackStream) - return i; - return -1; - } - - bool SetUnpackCoder() - { - bool isOk = false; - FOR_VECTOR(i, Coders) - { - if (FindBond_for_UnpackStream(i) < 0) - { - if (isOk) - return false; - UnpackCoder = i; - isOk = true; - } - } - return isOk; - } - - bool IsStream_in_PackStreams(UInt32 streamIndex) const - { - return FindStream_in_PackStreams(streamIndex) >= 0; - } - - int FindStream_in_PackStreams(UInt32 streamIndex) const - { - FOR_VECTOR(i, PackStreams) - if (PackStreams[i] == streamIndex) - return i; - return -1; - } - - - // that function is used before Maps is calculated - - UInt32 GetStream_for_Coder(UInt32 coderIndex) const - { - UInt32 streamIndex = 0; - for (UInt32 i = 0; i < coderIndex; i++) - streamIndex += Coders[i].NumStreams; - return streamIndex; - } - - // ---------- Maps Section ---------- - - CRecordVector Coder_to_Stream; - CRecordVector Stream_to_Coder; - - void ClearMaps(); - bool CalcMapsAndCheck(); - - // ---------- End of Maps Section ---------- - - void Clear() - { - Coders.Clear(); - Bonds.Clear(); - PackStreams.Clear(); - - ClearMaps(); - } - - void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const - { - coderIndex = Stream_to_Coder[streamIndex]; - coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex]; - } -}; - - - -class CCoder -{ - CLASS_NO_COPY(CCoder); -public: - CMyComPtr Coder; - CMyComPtr Coder2; - UInt32 NumStreams; - - UInt64 UnpackSize; - const UInt64 *UnpackSizePointer; - - CRecordVector PackSizes; - CRecordVector PackSizePointers; - - CCoder() {} - - void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes); - - IUnknown *GetUnknown() const - { - return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2; - } - - HRESULT QueryInterface(REFGUID iid, void** pp) const - { - return GetUnknown()->QueryInterface(iid, pp); - } -}; - - - -class CMixer -{ - bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex); - -protected: - CBindInfo _bi; - - int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const - { - if (EncodeMode == forInputStream) - return _bi.FindBond_for_UnpackStream(streamIndex); - else - return _bi.FindBond_for_PackStream(streamIndex); - } - - CBoolVector IsFilter_Vector; - CBoolVector IsExternal_Vector; - bool EncodeMode; -public: - unsigned MainCoderIndex; - - CMixer(bool encodeMode): - EncodeMode(encodeMode), - MainCoderIndex(0) - {} - - /* - Sequence of calling: - - SetBindInfo(); - for each coder - AddCoder(); - SelectMainCoder(); - - for each file - { - ReInit() - for each coder - SetCoderInfo(); - Code(); - } - */ - - virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) - { - _bi = bindInfo; - IsFilter_Vector.Clear(); - MainCoderIndex = 0; - return S_OK; - } - - virtual void AddCoder(const CCreatedCoder &cod) = 0; - virtual CCoder &GetCoder(unsigned index) = 0; - virtual void SelectMainCoder(bool useFirst) = 0; - virtual void ReInit() = 0; - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) = 0; - virtual HRESULT Code( - ISequentialInStream * const *inStreams, - ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress) = 0; - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0; - - bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex); - bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex); - bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex); -}; - - - - -#ifdef USE_MIXER_ST - -struct CCoderST: public CCoder -{ - bool CanRead; - bool CanWrite; - - CCoderST(): CanRead(false), CanWrite(false) {} -}; - - -struct CStBinderStream -{ - CSequentialInStreamCalcSize *InStreamSpec; - COutStreamCalcSize *OutStreamSpec; - CMyComPtr StreamRef; - - CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {} -}; - - -class CMixerST: - public IUnknown, - public CMixer, - public CMyUnknownImp -{ - HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ - UInt32 outStreamIndex, ISequentialInStream **inStreamRes); - HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ - UInt32 inStreamIndex, ISequentialInStream **inStreamRes); - HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */ - UInt32 outStreamIndex, ISequentialOutStream **outStreamRes); - - HRESULT FinishStream(UInt32 streamIndex); - HRESULT FinishCoder(UInt32 coderIndex); - -public: - CObjectVector _coders; - - CObjectVector _binderStreams; - - MY_UNKNOWN_IMP - - CMixerST(bool encodeMode); - ~CMixerST(); - - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual void ReInit(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) - { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); } - virtual HRESULT Code( - ISequentialInStream * const *inStreams, - ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; - - HRESULT GetMainUnpackStream( - ISequentialInStream * const *inStreams, - ISequentialInStream **inStreamRes); -}; - -#endif - - - - -#ifdef USE_MIXER_MT - -class CCoderMT: public CCoder, public CVirtThread -{ - CLASS_NO_COPY(CCoderMT) - CRecordVector InStreamPointers; - CRecordVector OutStreamPointers; - -private: - void Execute(); -public: - bool EncodeMode; - HRESULT Result; - CObjectVector< CMyComPtr > InStreams; - CObjectVector< CMyComPtr > OutStreams; - - void Release() - { - InStreamPointers.Clear(); - OutStreamPointers.Clear(); - unsigned i; - for (i = 0; i < InStreams.Size(); i++) - InStreams[i].Release(); - for (i = 0; i < OutStreams.Size(); i++) - OutStreams[i].Release(); - } - - class CReleaser - { - CLASS_NO_COPY(CReleaser) - CCoderMT &_c; - public: - CReleaser(CCoderMT &c): _c(c) {} - ~CReleaser() { _c.Release(); } - }; - - CCoderMT(): EncodeMode(false) {} - ~CCoderMT() { CVirtThread::WaitThreadFinish(); } - - void Code(ICompressProgressInfo *progress); -}; - - -class CMixerMT: - public IUnknown, - public CMixer, - public CMyUnknownImp -{ - CObjectVector _streamBinders; - - HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams); - HRESULT ReturnIfError(HRESULT code); - -public: - CObjectVector _coders; - - MY_UNKNOWN_IMP - - virtual HRESULT SetBindInfo(const CBindInfo &bindInfo); - virtual void AddCoder(const CCreatedCoder &cod); - virtual CCoder &GetCoder(unsigned index); - virtual void SelectMainCoder(bool useFirst); - virtual void ReInit(); - virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes) - { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes); } - virtual HRESULT Code( - ISequentialInStream * const *inStreams, - ISequentialOutStream * const *outStreams, - ICompressProgressInfo *progress); - virtual UInt64 GetBondStreamSize(unsigned bondIndex) const; - - CMixerMT(bool encodeMode): CMixer(encodeMode) {} -}; - -#endif - -} - -#endif +// CoderMixer2.h + +#ifndef ZIP7_INC_CODER_MIXER2_H +#define ZIP7_INC_CODER_MIXER2_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" + +#include "../../ICoder.h" + +#include "../../Common/CreateCoder.h" + +#ifdef Z7_ST + #define USE_MIXER_ST +#else + #define USE_MIXER_MT + #ifndef Z7_SFX + #define USE_MIXER_ST + #endif +#endif + +#ifdef USE_MIXER_MT +#include "../../Common/StreamBinder.h" +#include "../../Common/VirtThread.h" +#endif + + + +#ifdef USE_MIXER_ST + +Z7_CLASS_IMP_COM_1( + CSequentialInStreamCalcSize + , ISequentialInStream +) + bool _wasFinished; + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + _wasFinished = false; + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + + +Z7_CLASS_IMP_COM_2( + COutStreamCalcSize + , ISequentialOutStream + , IOutStreamFinish +) + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } +}; + +#endif + + + +namespace NCoderMixer2 { + +struct CBond +{ + UInt32 PackIndex; + UInt32 UnpackIndex; + + UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; } + UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; } +}; + + +struct CCoderStreamsInfo +{ + UInt32 NumStreams; +}; + + +struct CBindInfo +{ + CRecordVector Coders; + CRecordVector Bonds; + CRecordVector PackStreams; + unsigned UnpackCoder; + + unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); } + + int FindBond_for_PackStream(UInt32 packStream) const + { + FOR_VECTOR (i, Bonds) + if (Bonds[i].PackIndex == packStream) + return (int)i; + return -1; + } + + int FindBond_for_UnpackStream(UInt32 unpackStream) const + { + FOR_VECTOR (i, Bonds) + if (Bonds[i].UnpackIndex == unpackStream) + return (int)i; + return -1; + } + + bool SetUnpackCoder() + { + bool isOk = false; + FOR_VECTOR (i, Coders) + { + if (FindBond_for_UnpackStream(i) < 0) + { + if (isOk) + return false; + UnpackCoder = i; + isOk = true; + } + } + return isOk; + } + + bool IsStream_in_PackStreams(UInt32 streamIndex) const + { + return FindStream_in_PackStreams(streamIndex) >= 0; + } + + int FindStream_in_PackStreams(UInt32 streamIndex) const + { + FOR_VECTOR (i, PackStreams) + if (PackStreams[i] == streamIndex) + return (int)i; + return -1; + } + + + // that function is used before Maps is calculated + + UInt32 GetStream_for_Coder(UInt32 coderIndex) const + { + UInt32 streamIndex = 0; + for (UInt32 i = 0; i < coderIndex; i++) + streamIndex += Coders[i].NumStreams; + return streamIndex; + } + + // ---------- Maps Section ---------- + + CRecordVector Coder_to_Stream; + CRecordVector Stream_to_Coder; + + void ClearMaps(); + bool CalcMapsAndCheck(); + + // ---------- End of Maps Section ---------- + + void Clear() + { + Coders.Clear(); + Bonds.Clear(); + PackStreams.Clear(); + + ClearMaps(); + } + + void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const + { + coderIndex = Stream_to_Coder[streamIndex]; + coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex]; + } +}; + + + +class CCoder +{ + Z7_CLASS_NO_COPY(CCoder) +public: + CMyComPtr Coder; + CMyComPtr Coder2; + UInt32 NumStreams; + bool Finish; + + UInt64 UnpackSize; + const UInt64 *UnpackSizePointer; + + CRecordVector PackSizes; + CRecordVector PackSizePointers; + + CCoder(): Finish(false) {} + + void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish); + + HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const; + + IUnknown *GetUnknown() const + { + return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2; + } + + HRESULT QueryInterface(REFGUID iid, void** pp) const + { + return GetUnknown()->QueryInterface(iid, pp); + } +}; + + + +class CMixer +{ + bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex); + +protected: + CBindInfo _bi; + + int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const + { + if (EncodeMode == forInputStream) + return _bi.FindBond_for_UnpackStream(streamIndex); + else + return _bi.FindBond_for_PackStream(streamIndex); + } + + CBoolVector IsFilter_Vector; + CBoolVector IsExternal_Vector; + bool EncodeMode; +public: + unsigned MainCoderIndex; + + // bool InternalPackSizeError; + + CMixer(bool encodeMode): + EncodeMode(encodeMode), + MainCoderIndex(0) + // , InternalPackSizeError(false) + {} + + virtual ~CMixer() {} + /* + Sequence of calling: + + SetBindInfo(); + for each coder + AddCoder(); + SelectMainCoder(); + + for each file + { + ReInit() + for each coder + SetCoderInfo(); + Code(); + } + */ + + virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) + { + _bi = bindInfo; + IsFilter_Vector.Clear(); + MainCoderIndex = 0; + return S_OK; + } + + virtual void AddCoder(const CCreatedCoder &cod) = 0; + virtual CCoder &GetCoder(unsigned index) = 0; + virtual void SelectMainCoder(bool useFirst) = 0; + virtual HRESULT ReInit2() = 0; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0; + virtual HRESULT Code( + ISequentialInStream * const *inStreams, + ISequentialOutStream * const *outStreams, + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) = 0; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0; + + bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex); + bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex); + bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex); +}; + + + + +#ifdef USE_MIXER_ST + +struct CCoderST: public CCoder +{ + bool CanRead; + bool CanWrite; + + CCoderST(): CanRead(false), CanWrite(false) {} +}; + + +struct CStBinderStream +{ + CSequentialInStreamCalcSize *InStreamSpec; + COutStreamCalcSize *OutStreamSpec; + CMyComPtr StreamRef; + + CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {} +}; + + +class CMixerST: + public IUnknown, + public CMixer, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerST) + + HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ + UInt32 outStreamIndex, ISequentialInStream **inStreamRes); + HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ + UInt32 inStreamIndex, ISequentialInStream **inStreamRes); + HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */ + UInt32 outStreamIndex, ISequentialOutStream **outStreamRes); + + HRESULT FinishStream(UInt32 streamIndex); + HRESULT FinishCoder(UInt32 coderIndex); + +public: + CObjectVector _coders; + + CObjectVector _binderStreams; + + CMixerST(bool encodeMode); + ~CMixerST() Z7_DESTRUCTOR_override; + + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override + { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } + virtual HRESULT Code( + ISequentialInStream * const *inStreams, + ISequentialOutStream * const *outStreams, + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; + + HRESULT GetMainUnpackStream( + ISequentialInStream * const *inStreams, + ISequentialInStream **inStreamRes); +}; + +#endif + + + + +#ifdef USE_MIXER_MT + +class CCoderMT: public CCoder, public CVirtThread +{ + Z7_CLASS_NO_COPY(CCoderMT) + CRecordVector InStreamPointers; + CRecordVector OutStreamPointers; + +private: + virtual void Execute() Z7_override; +public: + bool EncodeMode; + HRESULT Result; + CObjectVector< CMyComPtr > InStreams; + CObjectVector< CMyComPtr > OutStreams; + + void Release() + { + InStreamPointers.Clear(); + OutStreamPointers.Clear(); + unsigned i; + for (i = 0; i < InStreams.Size(); i++) + InStreams[i].Release(); + for (i = 0; i < OutStreams.Size(); i++) + OutStreams[i].Release(); + } + + class CReleaser + { + Z7_CLASS_NO_COPY(CReleaser) + CCoderMT &_c; + public: + CReleaser(CCoderMT &c): _c(c) {} + ~CReleaser() { _c.Release(); } + }; + + CCoderMT(): EncodeMode(false) {} + ~CCoderMT() Z7_DESTRUCTOR_override + { + /* WaitThreadFinish() will be called in ~CVirtThread(). + But we need WaitThreadFinish() call before CCoder destructor, + and before destructors of this class members. + */ + CVirtThread::WaitThreadFinish(); + } + + void Code(ICompressProgressInfo *progress); +}; + + +class CMixerMT: + public IUnknown, + public CMixer, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_CLASS_NO_COPY(CMixerMT) + + CObjectVector _streamBinders; + + HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams); + HRESULT ReturnIfError(HRESULT code); + + // virtual ~CMixerMT() {} +public: + CObjectVector _coders; + + virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) Z7_override; + virtual void AddCoder(const CCreatedCoder &cod) Z7_override; + virtual CCoder &GetCoder(unsigned index) Z7_override; + virtual void SelectMainCoder(bool useFirst) Z7_override; + virtual HRESULT ReInit2() Z7_override; + virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) Z7_override + { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); } + virtual HRESULT Code( + ISequentialInStream * const *inStreams, + ISequentialOutStream * const *outStreams, + ICompressProgressInfo *progress, + bool &dataAfterEnd_Error) Z7_override; + virtual UInt64 GetBondStreamSize(unsigned bondIndex) const Z7_override; + + CMixerMT(bool encodeMode): CMixer(encodeMode) {} +}; + +#endif + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/DummyOutStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/DummyOutStream.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -1,17 +1,17 @@ -// DummyOutStream.cpp - -#include "StdAfx.h" - -#include "DummyOutStream.h" - -STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize = size; - HRESULT res = S_OK; - if (_stream) - res = _stream->Write(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return res; -} +// DummyOutStream.cpp + +#include "StdAfx.h" + +#include "DummyOutStream.h" + +Z7_COM7F_IMF(CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize = size; + HRESULT res = S_OK; + if (_stream) + res = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/DummyOutStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/DummyOutStream.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/DummyOutStream.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,25 +1,23 @@ -// DummyOutStream.h - -#ifndef __DUMMY_OUT_STREAM_H -#define __DUMMY_OUT_STREAM_H - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -class CDummyOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; -public: - void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } - void ReleaseStream() { _stream.Release(); } - void Init() { _size = 0; } - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - UInt64 GetSize() const { return _size; } -}; - -#endif +// DummyOutStream.h + +#ifndef ZIP7_INC_DUMMY_OUT_STREAM_H +#define ZIP7_INC_DUMMY_OUT_STREAM_H + +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +Z7_CLASS_IMP_NOQIB_1( + CDummyOutStream + , ISequentialOutStream +) + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *outStream) { _stream = outStream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/FindSignature.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/FindSignature.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.cpp 2024-01-24 17:00:00.000000000 +0000 @@ -1,62 +1,90 @@ -// FindSignature.cpp - -#include "StdAfx.h" - -#include - -#include "../../../Common/MyBuffer.h" - -#include "../../Common/StreamUtils.h" - -#include "FindSignature.h" - -HRESULT FindSignatureInStream(ISequentialInStream *stream, - const Byte *signature, unsigned signatureSize, - const UInt64 *limit, UInt64 &resPos) -{ - resPos = 0; - CByteBuffer byteBuffer2(signatureSize); - RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)); - - if (memcmp(byteBuffer2, signature, signatureSize) == 0) - return S_OK; - - const UInt32 kBufferSize = (1 << 16); - CByteBuffer byteBuffer(kBufferSize); - Byte *buffer = byteBuffer; - UInt32 numPrevBytes = signatureSize - 1; - memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); - resPos = 1; - for (;;) - { - if (limit != NULL) - if (resPos > *limit) - return S_FALSE; - do - { - UInt32 numReadBytes = kBufferSize - numPrevBytes; - UInt32 processedSize; - RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); - numPrevBytes += processedSize; - if (processedSize == 0) - return S_FALSE; - } - while (numPrevBytes < signatureSize); - UInt32 numTests = numPrevBytes - signatureSize + 1; - for (UInt32 pos = 0; pos < numTests; pos++) - { - Byte b = signature[0]; - for (; buffer[pos] != b && pos < numTests; pos++); - if (pos == numTests) - break; - if (memcmp(buffer + pos, signature, signatureSize) == 0) - { - resPos += pos; - return S_OK; - } - } - resPos += numTests; - numPrevBytes -= numTests; - memmove(buffer, buffer + numTests, numPrevBytes); - } -} +// FindSignature.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/MyBuffer.h" + +#include "../../Common/StreamUtils.h" + +#include "FindSignature.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos) +{ + resPos = 0; + CByteBuffer byteBuffer2(signatureSize); + RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize)) + + if (memcmp(byteBuffer2, signature, signatureSize) == 0) + return S_OK; + + const size_t kBufferSize = 1 << 16; + CByteBuffer byteBuffer(kBufferSize); + Byte *buffer = byteBuffer; + size_t numPrevBytes = signatureSize - 1; + memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes); + resPos = 1; + for (;;) + { + if (limit) + if (resPos > *limit) + return S_FALSE; + do + { + const size_t numReadBytes = kBufferSize - numPrevBytes; + UInt32 processedSize; + RINOK(stream->Read(buffer + numPrevBytes, (UInt32)numReadBytes, &processedSize)) + numPrevBytes += (size_t)processedSize; + if (processedSize == 0) + return S_FALSE; + } + while (numPrevBytes < signatureSize); + const size_t numTests = numPrevBytes - signatureSize + 1; + for (size_t pos = 0; pos < numTests; pos++) + { + const Byte b = signature[0]; + for (; buffer[pos] != b && pos < numTests; pos++); + if (pos == numTests) + break; + if (memcmp(buffer + pos, signature, signatureSize) == 0) + { + resPos += pos; + return S_OK; + } + } + resPos += numTests; + numPrevBytes -= numTests; + memmove(buffer, buffer + numTests, numPrevBytes); + } +} + +namespace NArchive { +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) +{ + areThereNonZeros = false; + numZeros = 0; + const size_t kBufSize = 1 << 11; + Byte buf[kBufSize]; + for (;;) + { + UInt32 size = 0; + RINOK(stream->Read(buf, kBufSize, &size)) + if (size == 0) + return S_OK; + for (UInt32 i = 0; i < size; i++) + if (buf[i] != 0) + { + areThereNonZeros = true; + numZeros += i; + return S_OK; + } + numZeros += size; + if (numZeros > maxSize) + return S_OK; + } +} +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/FindSignature.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/FindSignature.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/FindSignature.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,12 +1,12 @@ -// FindSignature.h - -#ifndef __FIND_SIGNATURE_H -#define __FIND_SIGNATURE_H - -#include "../../IStream.h" - -HRESULT FindSignatureInStream(ISequentialInStream *stream, - const Byte *signature, unsigned signatureSize, - const UInt64 *limit, UInt64 &resPos); - -#endif +// FindSignature.h + +#ifndef ZIP7_INC_FIND_SIGNATURE_H +#define ZIP7_INC_FIND_SIGNATURE_H + +#include "../../IStream.h" + +HRESULT FindSignatureInStream(ISequentialInStream *stream, + const Byte *signature, unsigned signatureSize, + const UInt64 *limit, UInt64 &resPos); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/HandlerOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/HandlerOut.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.cpp 2025-07-02 06:00:00.000000000 +0000 @@ -1,157 +1,315 @@ -// HandlerOut.cpp - -#include "StdAfx.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/System.h" -#endif - -#include "../Common/ParseProperties.h" - -#include "HandlerOut.h" - -using namespace NWindows; - -namespace NArchive { - -static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value) -{ - if (m.FindProp(propID) < 0) - m.AddProp32(propID, value); -} - -void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ) -{ - UInt32 level = _level; - if (level != (UInt32)(Int32)-1) - SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level); - - #ifndef _7ZIP_ST - SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); - #endif -} - -void CMultiMethodProps::Init() -{ - #ifndef _7ZIP_ST - _numProcessors = _numThreads = NSystem::GetNumberOfProcessors(); - #endif - - _level = (UInt32)(Int32)-1; - _analysisLevel = -1; - - _autoFilter = true; - _crcSize = 4; - _filterMethod.Clear(); - _methods.Clear(); -} - -HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) -{ - UString name = nameSpec; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - - if (name[0] == 'x') - { - name.Delete(0); - _level = 9; - return ParsePropToUInt32(name, value, _level); - } - - if (name.IsPrefixedBy_Ascii_NoCase("yx")) - { - name.Delete(0, 2); - UInt32 v = 9; - RINOK(ParsePropToUInt32(name, value, v)); - _analysisLevel = (int)v; - return S_OK; - } - - if (name.IsEqualTo("crc")) - { - name.Delete(0, 3); - _crcSize = 4; - return ParsePropToUInt32(name, value, _crcSize); - } - - UInt32 number; - unsigned index = ParseStringToUInt32(name, number); - UString realName = name.Ptr(index); - if (index == 0) - { - if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads)); - #endif - - return S_OK; - } - if (name.IsEqualTo("f")) - { - HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); - if (res == S_OK) - return res; - if (value.vt != VT_BSTR) - return E_INVALIDARG; - return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value); - } - number = 0; - } - if (number > 64) - return E_FAIL; - for (int j = _methods.Size(); j <= (int)number; j++) - _methods.Add(COneMethodInfo()); - return _methods[number].ParseMethodFromPROPVARIANT(realName, value); -} - -void CSingleMethodProps::Init() -{ - Clear(); - _level = (UInt32)(Int32)-1; - - #ifndef _7ZIP_ST - _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors(); - AddProp_NumThreads(_numThreads); - #endif -} - -HRESULT CSingleMethodProps::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - Init(); - for (UInt32 i = 0; i < numProps; i++) - { - UString name = names[i]; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - const PROPVARIANT &value = values[i]; - if (name[0] == L'x') - { - UInt32 a = 9; - RINOK(ParsePropToUInt32(name.Ptr(1), value, a)); - _level = a; - AddProp_Level(a); - } - else if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads)); - AddProp_NumThreads(_numThreads); - #endif - } - else - { - RINOK(ParseMethodFromPROPVARIANT(names[i], value)); - } - } - return S_OK; -} - -} +// HandlerOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringToInt.h" + +#include "HandlerOut.h" + +namespace NArchive { + +bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res) +{ + if (*s == 0) + { + switch (prop.vt) + { + case VT_UI4: res = prop.ulVal; return true; + case VT_UI8: res = prop.uhVal.QuadPart; return true; + case VT_BSTR: + s = prop.bstrVal; + break; + default: return false; + } + } + else if (prop.vt != VT_EMPTY) + return false; + + bool percentMode = false; + { + const wchar_t c = *s; + if (MyCharLower_Ascii(c) == 'p') + { + percentMode = true; + s++; + } + } + + const wchar_t *end; + const UInt64 v = ConvertStringToUInt64(s, &end); + if (s == end) + return false; + const wchar_t c = *end; + + if (percentMode) + { + if (c != 0) + return false; + res = Calc_From_Val_Percents(percentsBase, v); + return true; + } + + if (c == 0) + { + res = v; + return true; + } + if (end[1] != 0) + return false; + + if (c == '%') + { + res = Calc_From_Val_Percents(percentsBase, v); + return true; + } + + unsigned numBits; + switch (MyCharLower_Ascii(c)) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + const UInt64 val2 = v << numBits; + if ((val2 >> numBits) != v) + return false; + res = val2; + return true; +} + + +bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres) +{ + hres = S_OK; + + if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + #ifndef Z7_ST + _numThreads = _numProcessors; + _numThreads_WasForced = false; + hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced); + // "mt" means "_numThreads_WasForced = false" here + #endif + return true; + } + + if (name.IsPrefixedBy_Ascii_NoCase("memuse")) + { + UInt64 v; + if (!ParseSizeString(name.Ptr(6), value, _memAvail, v)) + hres = E_INVALIDARG; + _memUsage_Decompress = v; + _memUsage_Compress = v; + _memUsage_WasSet = true; + return true; + } + + return false; +} + + +#ifndef Z7_EXTRACT_ONLY + +static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value) +{ + if (m.FindProp(propID) < 0) + m.AddProp32(propID, value); +} + +void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const +{ + UInt32 level = _level; + if (level != (UInt32)(Int32)-1) + SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level); +} + +#ifndef Z7_ST + +static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value) +{ + const int i = m.FindProp(propID); + if (i >= 0) + { + NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value; + val = (UInt32)value; + return; + } + m.AddProp32(propID, value); +} + +void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads) +{ + SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); +} + +void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads) +{ + SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); +} + +void CMultiMethodProps::Set_Method_NumThreadGroups_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreadGroups) +{ + SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreadGroups, numThreadGroups); +} + +#endif // Z7_ST + + +void CMultiMethodProps::InitMulti() +{ + _level = (UInt32)(Int32)-1; + _analysisLevel = -1; + _crcSize = 4; + _autoFilter = true; +} + +void CMultiMethodProps::Init() +{ + InitCommon(); + InitMulti(); + _methods.Clear(); + _filterMethod.Clear(); +} + + +HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name[0] == 'x') + { + name.Delete(0); + _level = 9; + return ParsePropToUInt32(name, value, _level); + } + + if (name.IsPrefixedBy_Ascii_NoCase("yx")) + { + name.Delete(0, 2); + UInt32 v = 9; + RINOK(ParsePropToUInt32(name, value, v)) + _analysisLevel = (int)v; + return S_OK; + } + + if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + _crcSize = 4; + return ParsePropToUInt32(name, value, _crcSize); + } + + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + return hres; + } + + UInt32 number; + const unsigned index = ParseStringToUInt32(name, number); + const UString realName = name.Ptr(index); + if (index == 0) + { + if (name.IsEqualTo("f")) + { + const HRESULT res = PROPVARIANT_to_bool(value, _autoFilter); + if (res == S_OK) + return res; + if (value.vt != VT_BSTR) + return E_INVALIDARG; + return _filterMethod.ParseMethodFromPROPVARIANT(UString(), value); + } + number = 0; + } + if (number > 64) + return E_INVALIDARG; + for (unsigned j = _methods.Size(); j <= number; j++) + _methods.AddNew(); + return _methods[number].ParseMethodFromPROPVARIANT(realName, value); +} + + + +void CSingleMethodProps::Init() +{ + InitCommon(); + InitSingle(); + Clear(); +} + + +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++) + { + RINOK(SetProperty(names[i], values[i])) + } + + return S_OK; +} + +#endif + + +static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest) +{ + RINOK(PROPVARIANT_to_bool(prop, dest.Val)) + dest.Def = true; + return S_OK; +} + +HRESULT CHandlerTimeOptions::Parse(const UString &name, const PROPVARIANT &prop, bool &processed) +{ + processed = true; + if (name.IsEqualTo_Ascii_NoCase("tm")) { return PROPVARIANT_to_BoolPair(prop, Write_MTime); } + if (name.IsEqualTo_Ascii_NoCase("ta")) { return PROPVARIANT_to_BoolPair(prop, Write_ATime); } + if (name.IsEqualTo_Ascii_NoCase("tc")) { return PROPVARIANT_to_BoolPair(prop, Write_CTime); } + if (name.IsPrefixedBy_Ascii_NoCase("tp")) + { + UInt32 v = 0; + RINOK(ParsePropToUInt32(name.Ptr(2), prop, v)) + Prec = v; + return S_OK; + } + processed = false; + return S_OK; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/HandlerOut.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/HandlerOut.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/HandlerOut.h 2025-07-02 07:00:00.000000000 +0000 @@ -1,67 +1,169 @@ -// HandlerOut.h - -#ifndef __HANDLER_OUT_H -#define __HANDLER_OUT_H - -#include "../../Common/MethodProps.h" - -namespace NArchive { - -class CMultiMethodProps -{ - UInt32 _level; - int _analysisLevel; -public: - #ifndef _7ZIP_ST - UInt32 _numThreads; - UInt32 _numProcessors; - #endif - - UInt32 _crcSize; - CObjectVector _methods; - COneMethodInfo _filterMethod; - bool _autoFilter; - - void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo - #ifndef _7ZIP_ST - , UInt32 numThreads - #endif - ); - - unsigned GetNumEmptyMethods() const - { - unsigned i; - for (i = 0; i < _methods.Size(); i++) - if (!_methods[i].IsEmpty()) - break; - return i; - } - - int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } - int GetAnalysisLevel() const { return _analysisLevel; } - - void Init(); - - CMultiMethodProps() { Init(); } - HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); -}; - -class CSingleMethodProps: public COneMethodInfo -{ - UInt32 _level; - -public: - #ifndef _7ZIP_ST - UInt32 _numThreads; - UInt32 _numProcessors; - #endif - - void Init(); - CSingleMethodProps() { Init(); } - int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } - HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); -}; - -} - -#endif +// HandlerOut.h + +#ifndef ZIP7_INC_HANDLER_OUT_H +#define ZIP7_INC_HANDLER_OUT_H + +#include "../../../Windows/System.h" + +#include "../../Common/MethodProps.h" + +namespace NArchive { + +bool ParseSizeString(const wchar_t *name, const PROPVARIANT &prop, UInt64 percentsBase, UInt64 &res); + +class CCommonMethodProps +{ +protected: + void InitCommon() + { + // _Write_MTime = true; + { +#ifndef Z7_ST + _numThreads_WasForced = false; + UInt32 numThreads; +#ifdef _WIN32 + NWindows::NSystem::CProcessAffinity aff; + numThreads = aff.Load_and_GetNumberOfThreads(); + _numThreadGroups = aff.IsGroupMode ? aff.Groups.GroupSizes.Size() : 0; +#else + numThreads = NWindows::NSystem::GetNumberOfProcessors(); +#endif // _WIN32 + _numProcessors = _numThreads = numThreads; +#endif // Z7_ST + } + + size_t memAvail = (size_t)sizeof(size_t) << 28; + _memAvail = memAvail; + _memUsage_Compress = memAvail; + _memUsage_Decompress = memAvail; + _memUsage_WasSet = NWindows::NSystem::GetRamSize(memAvail); + if (_memUsage_WasSet) + { + _memAvail = memAvail; + unsigned bits = sizeof(size_t) * 8; + if (bits == 32) + { + const UInt32 limit2 = (UInt32)7 << 28; + if (memAvail > limit2) + memAvail = limit2; + } + // 80% - is auto usage limit in handlers + // _memUsage_Compress = memAvail * 4 / 5; + // _memUsage_Compress = Calc_From_Val_Percents(memAvail, 80); + _memUsage_Compress = Calc_From_Val_Percents_Less100(memAvail, 80); + _memUsage_Decompress = memAvail / 32 * 17; + } + } + +public: +#ifndef Z7_ST + UInt32 _numThreads; + UInt32 _numProcessors; +#ifdef _WIN32 + UInt32 _numThreadGroups; +#endif + bool _numThreads_WasForced; +#endif + + bool _memUsage_WasSet; + UInt64 _memUsage_Compress; + UInt64 _memUsage_Decompress; + size_t _memAvail; + + bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); + + CCommonMethodProps() { InitCommon(); } +}; + + +#ifndef Z7_EXTRACT_ONLY + +class CMultiMethodProps: public CCommonMethodProps +{ + UInt32 _level; + int _analysisLevel; + + void InitMulti(); +public: + UInt32 _crcSize; + CObjectVector _methods; + COneMethodInfo _filterMethod; + bool _autoFilter; + + + void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const; + +#ifndef Z7_ST + static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads); + static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads); + + static void Set_Method_NumThreadGroups_IfNotFinded(CMethodProps &props, UInt32 numThreadGroups); +#endif + + + unsigned GetNumEmptyMethods() const + { + unsigned i; + for (i = 0; i < _methods.Size(); i++) + if (!_methods[i].IsEmpty()) + break; + return i; + } + + int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } + int GetAnalysisLevel() const { return _analysisLevel; } + + void Init(); + CMultiMethodProps() { InitMulti(); } + + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); +}; + + +class CSingleMethodProps: public COneMethodInfo, public CCommonMethodProps +{ + UInt32 _level; + + void InitSingle() + { + _level = (UInt32)(Int32)-1; + } + +public: + void Init(); + CSingleMethodProps() { InitSingle(); } + + int GetLevel() const { return _level == (UInt32)(Int32)-1 ? 5 : (int)_level; } + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &values); + HRESULT SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); +}; + +#endif + +struct CHandlerTimeOptions +{ + CBoolPair Write_MTime; + CBoolPair Write_ATime; + CBoolPair Write_CTime; + UInt32 Prec; + + void Init() + { + Write_MTime.Init(); + Write_MTime.Val = true; + Write_ATime.Init(); + Write_CTime.Init(); + Prec = (UInt32)(Int32)-1; + } + + CHandlerTimeOptions() + { + Init(); + } + + HRESULT Parse(const UString &name, const PROPVARIANT &prop, bool &processed); +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/InStreamWithCRC.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -1,46 +1,57 @@ -// InStreamWithCRC.cpp - -#include "StdAfx.h" - -#include "InStreamWithCRC.h" - -STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessed = 0; - HRESULT result = S_OK; - if (_stream) - result = _stream->Read(data, size, &realProcessed); - _size += realProcessed; - if (size != 0 && realProcessed == 0) - _wasFinished = true; - _crc = CrcUpdate(_crc, data, realProcessed); - if (processedSize) - *processedSize = realProcessed; - return result; -} - -STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessed = 0; - HRESULT result = S_OK; - if (_stream) - result = _stream->Read(data, size, &realProcessed); - _size += realProcessed; - /* - if (size != 0 && realProcessed == 0) - _wasFinished = true; - */ - _crc = CrcUpdate(_crc, data, realProcessed); - if (processedSize) - *processedSize = realProcessed; - return result; -} - -STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin != STREAM_SEEK_SET || offset != 0) - return E_FAIL; - _size = 0; - _crc = CRC_INIT_VAL; - return _stream->Seek(offset, seekOrigin, newPosition); -} +// InStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "InStreamWithCRC.h" + +Z7_COM7F_IMF(CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessed = 0; + HRESULT result = S_OK; + if (size != 0) + { + if (_stream) + result = _stream->Read(data, size, &realProcessed); + _size += realProcessed; + if (realProcessed == 0) + _wasFinished = true; + else + _crc = CrcUpdate(_crc, data, realProcessed); + } + if (processedSize) + *processedSize = realProcessed; + return result; +} + +Z7_COM7F_IMF(CSequentialInStreamWithCRC::GetSize(UInt64 *size)) +{ + *size = _fullSize; + return S_OK; +} + + +Z7_COM7F_IMF(CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessed = 0; + HRESULT result = S_OK; + if (_stream) + result = _stream->Read(data, size, &realProcessed); + _size += realProcessed; + /* + if (size != 0 && realProcessed == 0) + _wasFinished = true; + */ + _crc = CrcUpdate(_crc, data, realProcessed); + if (processedSize) + *processedSize = realProcessed; + return result; +} + +Z7_COM7F_IMF(CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (seekOrigin != STREAM_SEEK_SET || offset != 0) + return E_FAIL; + _size = 0; + _crc = CRC_INIT_VAL; + return _stream->Seek(offset, seekOrigin, newPosition); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/InStreamWithCRC.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/InStreamWithCRC.h 2010-09-14 19:18:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/InStreamWithCRC.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,67 +1,64 @@ -// InStreamWithCRC.h - -#ifndef __IN_STREAM_WITH_CRC_H -#define __IN_STREAM_WITH_CRC_H - -#include "../../../../C/7zCrc.h" - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -class CSequentialInStreamWithCRC: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -private: - CMyComPtr _stream; - UInt64 _size; - UInt32 _crc; - bool _wasFinished; -public: - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - _wasFinished = false; - _crc = CRC_INIT_VAL; - } - void ReleaseStream() { _stream.Release(); } - UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } - UInt64 GetSize() const { return _size; } - bool WasFinished() const { return _wasFinished; } -}; - -class CInStreamWithCRC: - public IInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -private: - CMyComPtr _stream; - UInt64 _size; - UInt32 _crc; - // bool _wasFinished; -public: - void SetStream(IInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - // _wasFinished = false; - _crc = CRC_INIT_VAL; - } - void ReleaseStream() { _stream.Release(); } - UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } - UInt64 GetSize() const { return _size; } - // bool WasFinished() const { return _wasFinished; } -}; - -#endif +// InStreamWithCRC.h + +#ifndef ZIP7_INC_IN_STREAM_WITH_CRC_H +#define ZIP7_INC_IN_STREAM_WITH_CRC_H + +#include "../../../../C/7zCrc.h" + +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +Z7_CLASS_IMP_NOQIB_2( + CSequentialInStreamWithCRC + , ISequentialInStream + , IStreamGetSize +) + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + bool _wasFinished; + UInt64 _fullSize; +public: + + CSequentialInStreamWithCRC(): + _fullSize((UInt64)(Int64)-1) + {} + + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void SetFullSize(UInt64 fullSize) { _fullSize = fullSize; } + void Init() + { + _size = 0; + _crc = CRC_INIT_VAL; + _wasFinished = false; + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } + UInt64 GetSize() const { return _size; } + bool WasFinished() const { return _wasFinished; } +}; + + +Z7_CLASS_IMP_IInStream( + CInStreamWithCRC +) + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + // bool _wasFinished; +public: + void SetStream(IInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + // _wasFinished = false; + _crc = CRC_INIT_VAL; + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } + UInt64 GetSize() const { return _size; } + // bool WasFinished() const { return _wasFinished; } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/ItemNameUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/ItemNameUtils.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.cpp 2025-06-18 11:00:00.000000000 +0000 @@ -1,88 +1,140 @@ -// Archive/Common/ItemNameUtils.cpp - -#include "StdAfx.h" - -#include "ItemNameUtils.h" - -namespace NArchive { -namespace NItemName { - -static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR; -static const wchar_t kDirDelimiter = L'/'; - -void ReplaceToOsPathSeparator(wchar_t *s) -{ - #ifdef _WIN32 - for (;;) - { - wchar_t c = *s; - if (c == 0) - break; - if (c == kDirDelimiter) - *s = kOSDirDelimiter; - s++; - } - #endif -} - -UString MakeLegalName(const UString &name) -{ - UString zipName = name; - zipName.Replace(kOSDirDelimiter, kDirDelimiter); - return zipName; -} - -UString GetOSName(const UString &name) -{ - UString newName = name; - newName.Replace(kDirDelimiter, kOSDirDelimiter); - return newName; -} - -UString GetOSName2(const UString &name) -{ - if (name.IsEmpty()) - return UString(); - UString newName = GetOSName(name); - if (newName.Back() == kOSDirDelimiter) - newName.DeleteBack(); - return newName; -} - -void ConvertToOSName2(UString &name) -{ - if (!name.IsEmpty()) - { - name.Replace(kDirDelimiter, kOSDirDelimiter); - if (name.Back() == kOSDirDelimiter) - name.DeleteBack(); - } -} - -bool HasTailSlash(const AString &name, UINT - #if defined(_WIN32) && !defined(UNDER_CE) - codePage - #endif - ) -{ - if (name.IsEmpty()) - return false; - LPCSTR prev = - #if defined(_WIN32) && !defined(UNDER_CE) - CharPrevExA((WORD)codePage, name, &name[name.Len()], 0); - #else - (LPCSTR)(name) + (name.Len() - 1); - #endif - return (*prev == '/'); -} - -#ifndef _WIN32 -UString WinNameToOSName(const UString &name) -{ - UString newName = name; - newName.Replace(L'\\', kOSDirDelimiter); - return newName; -} -#endif - -}} +// Archive/Common/ItemNameUtils.cpp + +#include "StdAfx.h" + +#include "ItemNameUtils.h" + +namespace NArchive { +namespace NItemName { + +static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR; + +#if WCHAR_PATH_SEPARATOR != L'/' +static const wchar_t kUnixPathSepar = L'/'; +#endif + +void ReplaceSlashes_OsToUnix +#if WCHAR_PATH_SEPARATOR != L'/' + (UString &name) + { + name.Replace(kOsPathSepar, kUnixPathSepar); + } +#else + (UString &) {} +#endif + + +UString GetOsPath(const UString &name) +{ + #if WCHAR_PATH_SEPARATOR != L'/' + UString newName = name; + newName.Replace(kUnixPathSepar, kOsPathSepar); + return newName; + #else + return name; + #endif +} + + +UString GetOsPath_Remove_TailSlash(const UString &name) +{ + if (name.IsEmpty()) + return UString(); + UString newName = GetOsPath(name); + if (newName.Back() == kOsPathSepar) + newName.DeleteBack(); + return newName; +} + + +#if WCHAR_PATH_SEPARATOR != L'/' +void ReplaceToWinSlashes(UString &name, bool useBackslashReplacement) +{ + // name.Replace(kUnixPathSepar, kOsPathSepar); + const unsigned len = name.Len(); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = name[i]; + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + else if (useBackslashReplacement && c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + else + continue; + name.ReplaceOneCharAtPos(i, c); + } +} +#endif + +void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool + #if WCHAR_PATH_SEPARATOR != L'/' + useBackslashReplacement + #endif + ) +{ + if (name.IsEmpty()) + return; + + #if WCHAR_PATH_SEPARATOR != L'/' + ReplaceToWinSlashes(name, useBackslashReplacement); + #endif + + if (name.Back() == kOsPathSepar) + name.DeleteBack(); +} + + +void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *name, unsigned len) +{ + for (unsigned i = 0; i < len; i++) + { + wchar_t c = name[i]; + if (c == L'/') + c = L'_'; + #if WCHAR_PATH_SEPARATOR != L'/' + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + #endif + else + continue; + name[i] = c; + } +} + +void NormalizeSlashes_in_FileName_for_OsPath(UString &name) +{ + NormalizeSlashes_in_FileName_for_OsPath(name.GetBuf(), name.Len()); +} + + +bool HasTailSlash(const AString &name, UINT + #if defined(_WIN32) && !defined(UNDER_CE) + codePage + #endif + ) +{ + if (name.IsEmpty()) + return false; + char c; + #if defined(_WIN32) && !defined(UNDER_CE) + if (codePage != CP_UTF8) + c = *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0); + else + #endif + { + c = name.Back(); + } + return (c == '/'); +} + + +#ifndef _WIN32 +UString WinPathToOsPath(const UString &name) +{ + UString newName = name; + newName.Replace(L'\\', WCHAR_PATH_SEPARATOR); + return newName; +} +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/ItemNameUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/ItemNameUtils.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ItemNameUtils.h 2025-06-16 12:00:00.000000000 +0000 @@ -1,27 +1,33 @@ -// Archive/Common/ItemNameUtils.h - -#ifndef __ARCHIVE_ITEM_NAME_UTILS_H -#define __ARCHIVE_ITEM_NAME_UTILS_H - -#include "../../../Common/MyString.h" - -namespace NArchive { -namespace NItemName { - - void ReplaceToOsPathSeparator(wchar_t *s); - - UString MakeLegalName(const UString &name); - UString GetOSName(const UString &name); - UString GetOSName2(const UString &name); - void ConvertToOSName2(UString &name); - bool HasTailSlash(const AString &name, UINT codePage); - - #ifdef _WIN32 - inline UString WinNameToOSName(const UString &name) { return name; } - #else - UString WinNameToOSName(const UString &name); - #endif - -}} - -#endif +// Archive/Common/ItemNameUtils.h + +#ifndef ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H +#define ZIP7_INC_ARCHIVE_ITEM_NAME_UTILS_H + +#include "../../../Common/MyString.h" + +namespace NArchive { +namespace NItemName { + +void ReplaceSlashes_OsToUnix(UString &name); + +UString GetOsPath(const UString &name); +UString GetOsPath_Remove_TailSlash(const UString &name); + +#if WCHAR_PATH_SEPARATOR != L'/' +void ReplaceToWinSlashes(UString &name, bool useBackslashReplacement); +#endif +void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool useBackslashReplacement = false); +void NormalizeSlashes_in_FileName_for_OsPath(wchar_t *s, unsigned len); +void NormalizeSlashes_in_FileName_for_OsPath(UString &name); + +bool HasTailSlash(const AString &name, UINT codePage); + +#ifdef _WIN32 + inline UString WinPathToOsPath(const UString &name) { return name; } +#else + UString WinPathToOsPath(const UString &name); +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/MultiStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/MultiStream.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.cpp 2023-04-05 08:00:00.000000000 +0000 @@ -1,191 +1,193 @@ -// MultiStream.cpp - -#include "StdAfx.h" - -#include "MultiStream.h" - -STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (_pos >= _totalLength) - return S_OK; - - { - unsigned left = 0, mid = _streamIndex, right = Streams.Size(); - for (;;) - { - CSubStreamInfo &m = Streams[mid]; - if (_pos < m.GlobalOffset) - right = mid; - else if (_pos >= m.GlobalOffset + m.Size) - left = mid + 1; - else - { - _streamIndex = mid; - break; - } - mid = (left + right) / 2; - } - _streamIndex = mid; - } - - CSubStreamInfo &s = Streams[_streamIndex]; - UInt64 localPos = _pos - s.GlobalOffset; - if (localPos != s.LocalPos) - { - RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos)); - } - UInt64 rem = s.Size - localPos; - if (size > rem) - size = (UInt32)rem; - HRESULT result = s.Stream->Read(data, size, &size); - _pos += size; - s.LocalPos += size; - if (processedSize) - *processedSize = size; - return result; -} - -STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _pos; break; - case STREAM_SEEK_END: offset += _totalLength; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - - -/* -class COutVolumeStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - unsigned _volIndex; - UInt64 _volSize; - UInt64 _curPos; - CMyComPtr _volumeStream; - COutArchive _archive; - CCRC _crc; - -public: - MY_UNKNOWN_IMP - - CFileItem _file; - CUpdateOptions _options; - CMyComPtr VolumeCallback; - void Init(IArchiveUpdateCallback2 *volumeCallback, - const UString &name) - { - _file.Name = name; - _file.IsStartPosDefined = true; - _file.StartPos = 0; - - VolumeCallback = volumeCallback; - _volIndex = 0; - _volSize = 0; - } - - HRESULT Flush(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -HRESULT COutVolumeStream::Flush() -{ - if (_volumeStream) - { - _file.UnPackSize = _curPos; - _file.FileCRC = _crc.GetDigest(); - RINOK(WriteVolumeHeader(_archive, _file, _options)); - _archive.Close(); - _volumeStream.Release(); - _file.StartPos += _file.UnPackSize; - } - return S_OK; -} -*/ - -/* -STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - while (size > 0) - { - if (_streamIndex >= Streams.Size()) - { - CSubStreamInfo subStream; - RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)); - RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)); - subStream.Pos = 0; - Streams.Add(subStream); - continue; - } - CSubStreamInfo &subStream = Streams[_streamIndex]; - if (_offsetPos >= subStream.Size) - { - _offsetPos -= subStream.Size; - _streamIndex++; - continue; - } - if (_offsetPos != subStream.Pos) - { - CMyComPtr outStream; - RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); - subStream.Pos = _offsetPos; - } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); - UInt32 realProcessed; - RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); - size -= realProcessed; - subStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (processedSize) - *processedSize += realProcessed; - if (subStream.Pos == subStream.Size) - { - _streamIndex++; - _offsetPos = 0; - } - if (realProcessed != curSize && realProcessed == 0) - return E_FAIL; - } - return S_OK; -} - -STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _absPos; break; - case STREAM_SEEK_END: offset += _length; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _absPos = offset; - _offsetPos = _absPos; - _streamIndex = 0; - if (newPosition) - *newPosition = offset; - return S_OK; -} -*/ +// MultiStream.cpp + +#include "StdAfx.h" + +#include "MultiStream.h" + +Z7_COM7F_IMF(CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= _totalLength) + return S_OK; + + { + unsigned left = 0, mid = _streamIndex, right = Streams.Size(); + for (;;) + { + CSubStreamInfo &m = Streams[mid]; + if (_pos < m.GlobalOffset) + right = mid; + else if (_pos >= m.GlobalOffset + m.Size) + left = mid + 1; + else + break; + mid = (left + right) / 2; + } + _streamIndex = mid; + } + + CSubStreamInfo &s = Streams[_streamIndex]; + UInt64 localPos = _pos - s.GlobalOffset; + if (localPos != s.LocalPos) + { + RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos)) + } + { + const UInt64 rem = s.Size - localPos; + if (size > rem) + size = (UInt32)rem; + } + const HRESULT result = s.Stream->Read(data, size, &size); + _pos += size; + s.LocalPos += size; + if (processedSize) + *processedSize = size; + return result; +} + +Z7_COM7F_IMF(CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _pos; break; + case STREAM_SEEK_END: offset += _totalLength; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _pos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +/* +class COutVolumeStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + unsigned _volIndex; + UInt64 _volSize; + UInt64 _curPos; + CMyComPtr _volumeStream; + COutArchive _archive; + CCRC _crc; + +public: + CFileItem _file; + CUpdateOptions _options; + CMyComPtr VolumeCallback; + void Init(IArchiveUpdateCallback2 *volumeCallback, + const UString &name) + { + _file.Name = name; + _file.IsStartPosDefined = true; + _file.StartPos = 0; + + VolumeCallback = volumeCallback; + _volIndex = 0; + _volSize = 0; + } + + HRESULT Flush(); +}; + +HRESULT COutVolumeStream::Flush() +{ + if (_volumeStream) + { + _file.UnPackSize = _curPos; + _file.FileCRC = _crc.GetDigest(); + RINOK(WriteVolumeHeader(_archive, _file, _options)) + _archive.Close(); + _volumeStream.Release(); + _file.StartPos += _file.UnPackSize; + } + return S_OK; +} +*/ + +/* + +#include "../../../Common/Defs.h" + +Z7_COM7F_IMF(COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + while (size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size)) + RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream)) + subStream.Pos = 0; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + if (_offsetPos >= subStream.Size) + { + _offsetPos -= subStream.Size; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + CMyComPtr outStream; + RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)) + RINOK(outStream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) + subStream.Pos = _offsetPos; + } + + const UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)) + data = (const void *)((const Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if (processedSize) + *processedSize += realProcessed; + if (subStream.Pos == subStream.Size) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed != curSize && realProcessed == 0) + return E_FAIL; + } + return S_OK; +} + +Z7_COM7F_IMF(COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _absPos; break; + case STREAM_SEEK_END: offset += _length; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _absPos = (UInt64)offset; + _offsetPos = _absPos; + _streamIndex = 0; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/MultiStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/MultiStream.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/MultiStream.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,89 +1,86 @@ -// MultiStream.h - -#ifndef __MULTI_STREAM_H -#define __MULTI_STREAM_H - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyVector.h" - -#include "../../IStream.h" - -class CMultiStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _pos; - UInt64 _totalLength; - unsigned _streamIndex; - -public: - - struct CSubStreamInfo - { - CMyComPtr Stream; - UInt64 Size; - UInt64 GlobalOffset; - UInt64 LocalPos; - - CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {} - }; - - CObjectVector Streams; - - HRESULT Init() - { - UInt64 total = 0; - FOR_VECTOR (i, Streams) - { - CSubStreamInfo &s = Streams[i]; - s.GlobalOffset = total; - total += Streams[i].Size; - RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos)); - } - _totalLength = total; - _pos = 0; - _streamIndex = 0; - return S_OK; - } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -/* -class COutMultiStream: - public IOutStream, - public CMyUnknownImp -{ - unsigned _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CSubStreamInfo - { - CMyComPtr Stream; - UInt64 Size; - UInt64 Pos; - }; - CObjectVector Streams; -public: - CMyComPtr VolumeCallback; - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; -*/ - -#endif +// MultiStream.h + +#ifndef ZIP7_INC_MULTI_STREAM_H +#define ZIP7_INC_MULTI_STREAM_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyVector.h" + +#include "../../IStream.h" +#include "../../Archive/IArchive.h" + +Z7_CLASS_IMP_IInStream( + CMultiStream +) + + unsigned _streamIndex; + UInt64 _pos; + UInt64 _totalLength; + +public: + + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Size; + UInt64 GlobalOffset; + UInt64 LocalPos; + CSubStreamInfo(): Size(0), GlobalOffset(0), LocalPos(0) {} + }; + + CMyComPtr updateCallbackFile; + CObjectVector Streams; + + HRESULT Init() + { + UInt64 total = 0; + FOR_VECTOR (i, Streams) + { + CSubStreamInfo &s = Streams[i]; + s.GlobalOffset = total; + total += s.Size; + s.LocalPos = 0; + { + // it was already set to start + // RINOK(InStream_GetPos(s.Stream, s.LocalPos)); + } + } + _totalLength = total; + _pos = 0; + _streamIndex = 0; + return S_OK; + } +}; + +/* +Z7_CLASS_IMP_COM_1( + COutMultiStream, + IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + unsigned _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Size; + UInt64 Pos; + }; + CObjectVector Streams; +public: + CMyComPtr VolumeCallback; + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } +}; +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 2009-05-30 20:19:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -1,18 +1,18 @@ -// OutStreamWithCRC.cpp - -#include "StdAfx.h" - -#include "OutStreamWithCRC.h" - -STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - if (_calculate) - _crc = CrcUpdate(_crc, data, size); - _size += size; - if (processedSize != NULL) - *processedSize = size; - return result; -} +// OutStreamWithCRC.cpp + +#include "StdAfx.h" + +#include "OutStreamWithCRC.h" + +Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (_calculate) + _crc = CrcUpdate(_crc, data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithCRC.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithCRC.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithCRC.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,37 +1,35 @@ -// OutStreamWithCRC.h - -#ifndef __OUT_STREAM_WITH_CRC_H -#define __OUT_STREAM_WITH_CRC_H - -#include "../../../../C/7zCrc.h" - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -class COutStreamWithCRC: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - UInt32 _crc; - bool _calculate; -public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(bool calculate = true) - { - _size = 0; - _calculate = calculate; - _crc = CRC_INIT_VAL; - } - void EnableCalc(bool calculate) { _calculate = calculate; } - void InitCRC() { _crc = CRC_INIT_VAL; } - UInt64 GetSize() const { return _size; } - UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } -}; - -#endif +// OutStreamWithCRC.h + +#ifndef ZIP7_INC_OUT_STREAM_WITH_CRC_H +#define ZIP7_INC_OUT_STREAM_WITH_CRC_H + +#include "../../../../C/7zCrc.h" + +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithCRC + , ISequentialOutStream +) + CMyComPtr _stream; + UInt64 _size; + UInt32 _crc; + bool _calculate; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool calculate = true) + { + _size = 0; + _calculate = calculate; + _crc = CRC_INIT_VAL; + } + void EnableCalc(bool calculate) { _calculate = calculate; } + void InitCRC() { _crc = CRC_INIT_VAL; } + UInt64 GetSize() const { return _size; } + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp 2023-12-14 13:00:00.000000000 +0000 @@ -1,18 +1,29 @@ -// OutStreamWithSha1.cpp - -#include "StdAfx.h" - -#include "OutStreamWithSha1.h" - -STDMETHODIMP COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - if (_calculate) - Sha1_Update(&_sha, (const Byte *)data, size); - _size += size; - if (processedSize) - *processedSize = size; - return result; -} +// OutStreamWithSha1.cpp + +#include "StdAfx.h" + +#include "OutStreamWithSha1.h" + +Z7_COM7F_IMF(COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (_calculate) + Sha1_Update(Sha(), (const Byte *)data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +Z7_COM7F_IMF(CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + Sha1_Update(Sha(), (const Byte *)data, realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + return result; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithSha1.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/OutStreamWithSha1.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/OutStreamWithSha1.h 2023-12-14 13:00:00.000000000 +0000 @@ -1,36 +1,61 @@ -// OutStreamWithSha1.h - -#ifndef __OUT_STREAM_WITH_SHA1_H -#define __OUT_STREAM_WITH_SHA1_H - -#include "../../../../C/Sha1.h" - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -class COutStreamWithSha1: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - CSha1 _sha; - bool _calculate; -public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(bool calculate = true) - { - _size = 0; - _calculate = calculate; - Sha1_Init(&_sha); - } - void InitSha1() { Sha1_Init(&_sha); } - UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { Sha1_Final(&_sha, digest); } -}; - -#endif +// OutStreamWithSha1.h + +#ifndef ZIP7_INC_OUT_STREAM_WITH_SHA1_H +#define ZIP7_INC_OUT_STREAM_WITH_SHA1_H + +#include "../../../../C/Sha1.h" + +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSha1 + , ISequentialOutStream +) + bool _calculate; + CMyComPtr _stream; + CAlignedBuffer1 _sha; + UInt64 _size; + + CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } +public: + COutStreamWithSha1(): _sha(sizeof(CSha1)) {} + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool calculate = true) + { + _calculate = calculate; + _size = 0; + Sha1_Init(Sha()); + } + void InitSha1() { Sha1_Init(Sha()); } + UInt64 GetSize() const { return _size; } + void Final(Byte *digest) { Sha1_Final(Sha(), digest); } +}; + + +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithSha1 + , ISequentialInStream +) + CMyComPtr _stream; + CAlignedBuffer1 _sha; + UInt64 _size; + + CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } +public: + CInStreamWithSha1(): _sha(sizeof(CSha1)) {} + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init() + { + _size = 0; + Sha1_Init(Sha()); + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + void Final(Byte *digest) { Sha1_Final(Sha(), digest); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/ParseProperties.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Common/ParseProperties.cpp 2011-05-08 18:29:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.cpp 2011-02-06 08:34:40.000000000 +0000 @@ -1,3 +1,3 @@ -// ParseProperties.cpp - -#include "StdAfx.h" +// ParseProperties.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/ParseProperties.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/ParseProperties.h 2011-05-08 18:29:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/ParseProperties.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ -// ParseProperties.h - -#ifndef __PARSE_PROPERTIES_H -#define __PARSE_PROPERTIES_H - -#endif +// ParseProperties.h + +#ifndef ZIP7_INC_PARSE_PROPERTIES_H +#define ZIP7_INC_PARSE_PROPERTIES_H + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Common/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Common/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/CpioHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CpioHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/CpioHandler.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CpioHandler.cpp 2025-06-21 07:00:00.000000000 +0000 @@ -1,795 +1,1110 @@ -// CpioHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyLinux.h" -#include "../../Common/StringConvert.h" -#include "../../Common/StringToInt.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#include "Common/ItemNameUtils.h" - -using namespace NWindows; - -namespace NArchive { -namespace NCpio { - -static const Byte kMagicBin0 = 0xC7; -static const Byte kMagicBin1 = 0x71; - -// #define MAGIC_ASCII { '0', '7', '0', '7', '0' } - -static const Byte kMagicHex = '1'; // New ASCII Format -static const Byte kMagicHexCrc = '2'; // New CRC Format -static const Byte kMagicOct = '7'; // Portable ASCII Format - -static const char *kName_TRAILER = "TRAILER!!!"; - -static const unsigned k_BinRecord_Size = 2 + 8 * 2 + 2 * 4; -static const unsigned k_OctRecord_Size = 6 + 8 * 6 + 2 * 11; -static const unsigned k_HexRecord_Size = 6 + 13 * 8; - -static const unsigned k_RecordSize_Max = k_HexRecord_Size; - - /* - struct CBinRecord - { - unsigned short c_magic; - short c_dev; - unsigned short c_ino; - unsigned short c_mode; - unsigned short c_uid; - unsigned short c_gid; - unsigned short c_nlink; - short c_rdev; - unsigned short c_mtimes[2]; - unsigned short c_namesize; - unsigned short c_filesizes[2]; - }; - - struct CHexRecord - { - char Magic[6]; - char inode[8]; - char Mode[8]; - char UID[8]; - char GID[8]; - char nlink[8]; - char mtime[8]; - char Size[8]; // must be 0 for FIFOs and directories - char DevMajor[8]; - char DevMinor[8]; - char RDevMajor[8]; //only valid for chr and blk special files - char RDevMinor[8]; //only valid for chr and blk special files - char NameSize[8]; // count includes terminating NUL in pathname - char ChkSum[8]; // 0 for "new" portable format; for CRC format the sum of all the bytes in the file - }; -*/ - -enum EType -{ - k_Type_BinLe, - k_Type_BinBe, - k_Type_Oct, - k_Type_Hex, - k_Type_HexCrc -}; - -static const char * const k_Types[] = -{ - "Binary LE" - , "Binary BE" - , "Portable ASCII" - , "New ASCII" - , "New CRC" -}; - -struct CItem -{ - AString Name; - UInt32 inode; - UInt32 Mode; - UInt32 UID; - UInt32 GID; - UInt64 Size; - UInt32 MTime; - - UInt32 NumLinks; - UInt32 DevMajor; - UInt32 DevMinor; - UInt32 RDevMajor; - UInt32 RDevMinor; - UInt32 ChkSum; - - UInt32 Align; - EType Type; - - UInt32 HeaderSize; - UInt64 HeaderPos; - - bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; } - bool IsCrcFormat() const { return Type == k_Type_HexCrc; } - bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } - bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; } - UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } -}; - -enum EErrorType -{ - k_ErrorType_OK, - k_ErrorType_Corrupted, - k_ErrorType_UnexpectedEnd, -}; - -struct CInArchive -{ - ISequentialInStream *Stream; - UInt64 Processed; - - HRESULT Read(void *data, size_t *size); - HRESULT GetNextItem(CItem &item, EErrorType &errorType); -}; - -HRESULT CInArchive::Read(void *data, size_t *size) -{ - HRESULT res = ReadStream(Stream, data, size); - Processed += *size; - return res; -} - -static bool ReadHex(const Byte *p, UInt32 &resVal) -{ - char sz[16]; - memcpy(sz, p, 8); - sz[8] = 0; - const char *end; - resVal = ConvertHexStringToUInt32(sz, &end); - return (unsigned)(end - sz) == 8; -} - -static bool ReadOct6(const Byte *p, UInt32 &resVal) -{ - char sz[16]; - memcpy(sz, p, 6); - sz[6] = 0; - const char *end; - resVal = ConvertOctStringToUInt32(sz, &end); - return (unsigned)(end - sz) == 6; -} - -static bool ReadOct11(const Byte *p, UInt64 &resVal) -{ - char sz[16]; - memcpy(sz, p, 11); - sz[11] = 0; - const char *end; - resVal = ConvertOctStringToUInt64(sz, &end); - return (unsigned)(end - sz) == 11; -} - - -#define READ_HEX(y) { if (!ReadHex(p2, y)) return S_OK; p2 += 8; } -#define READ_OCT_6(y) { if (!ReadOct6(p2, y)) return S_OK; p2 += 6; } -#define READ_OCT_11(y) { if (!ReadOct11(p2, y)) return S_OK; p2 += 11; } - -static UInt32 GetAlignedSize(UInt32 size, UInt32 align) -{ - while ((size & (align - 1)) != 0) - size++; - return size; -} - -static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); } -static UInt32 Get32(const Byte *p, bool be) { return ((UInt32)Get16(p, be) << 16) + Get16(p + 2, be); } - -#define G16(offs, v) v = Get16(p + (offs), be) -#define G32(offs, v) v = Get32(p + (offs), be) - -static const unsigned kNameSizeMax = 1 << 12; - -API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size) -{ - if (size < k_BinRecord_Size) - return k_IsArc_Res_NEED_MORE; - - UInt32 nameSize; - UInt32 numLinks; - if (p[0] == '0') - { - if (p[1] != '7' || - p[2] != '0' || - p[3] != '7' || - p[4] != '0') - return k_IsArc_Res_NO; - if (p[5] == '7') - { - if (size < k_OctRecord_Size) - return k_IsArc_Res_NEED_MORE; - for (int i = 6; i < k_OctRecord_Size; i++) - { - char c = p[i]; - if (c < '0' || c > '7') - return k_IsArc_Res_NO; - } - ReadOct6(p + 6 * 6, numLinks); - ReadOct6(p + 8 * 6 + 11, nameSize); - } - else if (p[5] == '1' || p[5] == '2') - { - if (size < k_HexRecord_Size) - return k_IsArc_Res_NEED_MORE; - for (int i = 6; i < k_HexRecord_Size; i++) - { - char c = p[i]; - if ((c < '0' || c > '9') && - (c < 'A' || c > 'F') && - (c < 'a' || c > 'f')) - return k_IsArc_Res_NO; - } - ReadHex(p + 6 + 4 * 8, numLinks); - ReadHex(p + 6 + 11 * 8, nameSize); - } - else - return k_IsArc_Res_NO; - } - else - { - UInt32 rDevMinor; - if (p[0] == kMagicBin0 && p[1] == kMagicBin1) - { - numLinks = GetUi16(p + 12); - rDevMinor = GetUi16(p + 14); - nameSize = GetUi16(p + 20); - } - else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) - { - numLinks = GetBe16(p + 12); - rDevMinor = GetBe16(p + 14); - nameSize = GetBe16(p + 20); - } - else - return k_IsArc_Res_NO; - - if (rDevMinor != 0) - return k_IsArc_Res_NO; - if (nameSize > (1 << 8)) - return k_IsArc_Res_NO; - } - if (numLinks == 0 || numLinks >= (1 << 10)) - return k_IsArc_Res_NO; - if (nameSize == 0 || nameSize > kNameSizeMax) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -#define READ_STREAM(_dest_, _size_) \ - { size_t processed = (_size_); RINOK(Read(_dest_, &processed)); \ -if (processed != (_size_)) { errorType = k_ErrorType_UnexpectedEnd; return S_OK; } } - -HRESULT CInArchive::GetNextItem(CItem &item, EErrorType &errorType) -{ - errorType = k_ErrorType_Corrupted; - - Byte p[k_RecordSize_Max]; - - READ_STREAM(p, k_BinRecord_Size) - - UInt32 nameSize; - - if (p[0] != '0') - { - bool be; - if (p[0] == kMagicBin0 && p[1] == kMagicBin1) { be = false; item.Type = k_Type_BinLe; } - else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) { be = true; item.Type = k_Type_BinBe; } - else return S_FALSE; - - item.Align = 2; - item.DevMajor = 0; - item.RDevMajor =0; - item.ChkSum = 0; - - G16(2, item.DevMinor); - G16(4, item.inode); - G16(6, item.Mode); - G16(8, item.UID); - G16(10, item.GID); - G16(12, item.NumLinks); - G16(14, item.RDevMinor); - G32(16, item.MTime); - G16(20, nameSize); - G32(22, item.Size); - - /* - if (item.RDevMinor != 0) - return S_FALSE; - */ - - item.HeaderSize = GetAlignedSize(nameSize + k_BinRecord_Size, item.Align); - nameSize = item.HeaderSize - k_BinRecord_Size; - } - else - { - if (p[1] != '7' || - p[2] != '0' || - p[3] != '7' || - p[4] != '0') - return S_FALSE; - if (p[5] == kMagicOct) - { - item.Type = k_Type_Oct; - READ_STREAM(p + k_BinRecord_Size, k_OctRecord_Size - k_BinRecord_Size) - item.Align = 1; - item.DevMajor = 0; - item.RDevMajor = 0; - - const Byte *p2 = p + 6; - READ_OCT_6(item.DevMinor); - READ_OCT_6(item.inode); - READ_OCT_6(item.Mode); - READ_OCT_6(item.UID); - READ_OCT_6(item.GID); - READ_OCT_6(item.NumLinks); - READ_OCT_6(item.RDevMinor); - { - UInt64 mTime64; - READ_OCT_11(mTime64); - item.MTime = 0; - if (mTime64 < (UInt32)(Int32)-1) - item.MTime = (UInt32)mTime64; - } - READ_OCT_6(nameSize); - READ_OCT_11(item.Size); // ????? - item.HeaderSize = GetAlignedSize(nameSize + k_OctRecord_Size, item.Align); - nameSize = item.HeaderSize - k_OctRecord_Size; - } - else - { - if (p[5] == kMagicHex) - item.Type = k_Type_Hex; - else if (p[5] == kMagicHexCrc) - item.Type = k_Type_HexCrc; - else - return S_FALSE; - - READ_STREAM(p + k_BinRecord_Size, k_HexRecord_Size - k_BinRecord_Size) - - item.Align = 4; - - const Byte *p2 = p + 6; - READ_HEX(item.inode); - READ_HEX(item.Mode); - READ_HEX(item.UID); - READ_HEX(item.GID); - READ_HEX(item.NumLinks); - READ_HEX(item.MTime); - { - UInt32 size32; - READ_HEX(size32); - item.Size = size32; - } - READ_HEX(item.DevMajor); - READ_HEX(item.DevMinor); - READ_HEX(item.RDevMajor); - READ_HEX(item.RDevMinor); - READ_HEX(nameSize); - READ_HEX(item.ChkSum); - if (nameSize >= kNameSizeMax) - return S_OK; - item.HeaderSize = GetAlignedSize(nameSize + k_HexRecord_Size, item.Align); - nameSize = item.HeaderSize - k_HexRecord_Size; - } - } - if (nameSize > kNameSizeMax) - return S_FALSE; - if (nameSize == 0 || nameSize >= kNameSizeMax) - return S_OK; - char *s = item.Name.GetBuf(nameSize); - size_t processedSize = nameSize; - RINOK(Read(s, &processedSize)); - item.Name.ReleaseBuf_CalcLen(nameSize); - if (processedSize != nameSize) - { - errorType = k_ErrorType_UnexpectedEnd; - return S_OK; - } - errorType = k_ErrorType_OK; - return S_OK; -} - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CObjectVector _items; - CMyComPtr _stream; - UInt64 _phySize; - EType _Type; - EErrorType _error; - bool _isArc; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kArcProps[] = -{ - kpidSubType -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidMTime, - kpidPosixAttrib, - kpidLinks -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidSubType: prop = k_Types[(unsigned)_Type]; break; - case kpidPhySize: prop = _phySize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) - v |= kpv_ErrorFlags_IsNotArc; - switch (_error) - { - case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; - case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; - } - prop = v; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - - UInt64 endPos = 0; - - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - if (callback) - { - RINOK(callback->SetTotal(NULL, &endPos)); - } - - _items.Clear(); - CInArchive arc; - - arc.Stream = stream; - arc.Processed = 0; - - for (;;) - { - CItem item; - item.HeaderPos = arc.Processed; - HRESULT result = arc.GetNextItem(item, _error); - if (result == S_FALSE) - return S_FALSE; - if (result != S_OK) - return S_FALSE; - if (_error != k_ErrorType_OK) - { - if (_error == k_ErrorType_Corrupted) - arc.Processed = item.HeaderPos; - break; - } - if (_items.IsEmpty()) - _Type = item.Type; - else if (_items.Back().Type != item.Type) - { - _error = k_ErrorType_Corrupted; - arc.Processed = item.HeaderPos; - break; - } - if (item.IsTrailer()) - break; - - _items.Add(item); - - { - // archive.SkipDataRecords(item.Size, item.Align); - UInt64 dataSize = item.Size; - UInt32 align = item.Align; - while ((dataSize & (align - 1)) != 0) - dataSize++; - - // _error = k_ErrorType_UnexpectedEnd; break; - - arc.Processed += dataSize; - if (arc.Processed > endPos) - { - _error = k_ErrorType_UnexpectedEnd; - break; - } - - UInt64 newPostion; - RINOK(stream->Seek(dataSize, STREAM_SEEK_CUR, &newPostion)); - if (arc.Processed != newPostion) - return E_FAIL; - } - - if (callback && (_items.Size() & 0xFF) == 0) - { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &item.HeaderPos)); - } - } - _phySize = arc.Processed; - if (_error != k_ErrorType_OK) - { - if (_items.Size() == 0) - return S_FALSE; - if (_items.Size() == 1 && _items[0].IsBin()) - { - // probably it's false detected archive. So we return error - return S_FALSE; - } - } - else - { - // Read tailing zeros. - // Most of cpio files use 512-bytes aligned zeros - UInt64 pos = arc.Processed; - const UInt32 kTailSize_MAX = 1 << 9; - Byte buf[kTailSize_MAX]; - - UInt32 rem = (kTailSize_MAX - (UInt32)pos) & (kTailSize_MAX - 1); - if (rem != 0) - { - rem++; // we need to see that it's end of file - size_t processed = rem; - RINOK(ReadStream(stream, buf, &processed)); - if (processed < rem) - { - unsigned i; - for (i = 0; i < processed && buf[i] == 0; i++); - if (i == processed) - _phySize += processed; - } - } - } - - _isArc = true; - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _items.Clear(); - _stream.Release(); - _phySize = 0; - _Type = k_Type_BinLe; - _isArc = false; - _error = k_ErrorType_OK; - return S_OK; -} - -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 CItem &item = _items[index]; - - switch (propID) - { - case kpidPath: - { - UString res; - bool needConvert = true; - #ifdef _WIN32 - if (ConvertUTF8ToUnicode(item.Name, res)) - needConvert = false; - #endif - if (needConvert) - res = MultiByteToUnicodeString(item.Name, CP_OEMCP); - prop = NItemName::GetOSName(res); - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: - case kpidPackSize: - prop = (UInt64)item.Size; - break; - case kpidMTime: - { - if (item.MTime != 0) - { - FILETIME utc; - NTime::UnixTimeToFileTime(item.MTime, utc); - prop = utc; - } - break; - } - case kpidPosixAttrib: prop = item.Mode; break; - case kpidLinks: prop = item.NumLinks; break; - /* - case kpidinode: prop = item.inode; break; - case kpidiChkSum: prop = item.ChkSum; break; - */ - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class COutStreamWithSum: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - UInt32 _crc; - bool _calculate; -public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(bool calculate = true) - { - _size = 0; - _calculate = calculate; - _crc = 0; - } - void EnableCalc(bool calculate) { _calculate = calculate; } - void InitCRC() { _crc = 0; } - UInt64 GetSize() const { return _size; } - UInt32 GetCRC() const { return _crc; } -}; - -STDMETHODIMP COutStreamWithSum::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - if (_calculate) - { - UInt32 crc = 0; - for (UInt32 i = 0; i < size; i++) - crc += (UInt32)(((const Byte *)data)[i]); - _crc += crc; - } - if (processedSize) - *processedSize = size; - return result; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - 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++) - totalSize += _items[allFilesMode ? i : indices[i]].Size; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - COutStreamWithSum *outStreamSumSpec = new COutStreamWithSum; - CMyComPtr outStreamSum(outStreamSumSpec); - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - currentTotalSize += item.Size; - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - if (!testMode && !outStream) - continue; - outStreamSumSpec->Init(item.IsCrcFormat()); - outStreamSumSpec->SetStream(outStream); - outStream.Release(); - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_stream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, outStreamSum, NULL, NULL, progress)); - outStreamSumSpec->ReleaseStream(); - Int32 res = NExtract::NOperationResult::kDataError; - if (copyCoderSpec->TotalSize == item.Size) - { - res = NExtract::NOperationResult::kOK; - if (item.IsCrcFormat() && item.ChkSum != outStreamSumSpec->GetCRC()) - res = NExtract::NOperationResult::kCRCError; - } - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CItem &item = _items[index]; - return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream); - COM_TRY_END -} - -static const Byte k_Signature[] = { - 5, '0', '7', '0', '7', '0', - 2, kMagicBin0, kMagicBin1, - 2, kMagicBin1, kMagicBin0 }; - -REGISTER_ARC_I( - "Cpio", "cpio", 0, 0xED, - k_Signature, - 0, - NArcInfoFlags::kMultiSignature, - IsArc_Cpio) - -}} +// CpioHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" +#include "../../Common/StringConvert.h" +#include "../../Common/StringToInt.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +#include "Common/ItemNameUtils.h" + +using namespace NWindows; + +namespace NArchive { +namespace NCpio { + +static const Byte kMagicBin0 = 0xC7; +static const Byte kMagicBin1 = 0x71; + +static const Byte kMagicHex = '1'; // New ASCII Format +static const Byte kMagicHexCrc = '2'; // New CRC Format +static const Byte kMagicOct = '7'; // Portable ASCII Format + +static const char * const kName_TRAILER = "TRAILER!!!"; + +static const unsigned k_BinRecord_Size = 2 + 8 * 2 + 2 * 4; +static const unsigned k_OctRecord_Size = 6 + 8 * 6 + 2 * 11; +static const unsigned k_HexRecord_Size = 6 + 13 * 8; + +static const unsigned k_RecordSize_Max = k_HexRecord_Size; + +enum EType +{ + k_Type_BinLe, + k_Type_BinBe, + k_Type_Oct, + k_Type_Hex, + k_Type_HexCrc +}; + +static const char * const k_Types[] = +{ + "Binary LE" + , "Binary BE" + , "Portable ASCII" + , "New ASCII" + , "New CRC" +}; + +struct CItem +{ + UInt32 inode; + unsigned MainIndex_ForInode; + UInt32 Mode; + UInt32 MTime; + UInt32 DevMajor; + UInt32 DevMinor; + UInt64 Size; + AString Name; + UInt32 NumLinks; + UInt32 UID; + UInt32 GID; + UInt32 RDevMajor; + UInt32 RDevMinor; + UInt32 ChkSum; + + UInt32 AlignMask; + EType Type; + + UInt32 HeaderSize; + UInt64 HeaderPos; + + CByteBuffer Data; // for symlink + + + UInt32 GetAlignedSize(UInt32 size) const + { + return (size + AlignMask) & ~(UInt32)AlignMask; + } + + UInt64 GetPackSize() const + { + const UInt64 alignMask64 = AlignMask; + return (Size + alignMask64) & ~(UInt64)alignMask64; + } + + bool IsSame_inode_Dev(const CItem &item) const + { + return inode == item.inode + && DevMajor == item.DevMajor + && DevMinor == item.DevMinor; + } + + bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; } + bool IsCrcFormat() const { return Type == k_Type_HexCrc; } + bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } + bool Is_SymLink() const { return MY_LIN_S_ISLNK(Mode); } + bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; } + UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } +}; + + +enum EErrorType +{ + k_ErrorType_OK, + k_ErrorType_BadSignature, + k_ErrorType_Corrupted, + k_ErrorType_UnexpectedEnd +}; + + +struct CInArchive +{ + EErrorType errorType; + ISequentialInStream *Stream; + UInt64 Processed; + CItem item; + + HRESULT Read(void *data, size_t *size); + HRESULT GetNextItem(); +}; + +HRESULT CInArchive::Read(void *data, size_t *size) +{ + const HRESULT res = ReadStream(Stream, data, size); + Processed += *size; + return res; +} + + +static bool CheckOctRecord(const Byte *p) +{ + for (unsigned i = 6; i < k_OctRecord_Size; i++) + { + const unsigned c = (unsigned)p[i] - '0'; + if (c > 7) + return false; + } + return true; +} + +static bool CheckHexRecord(const Byte *p) +{ + for (unsigned i = 6; i < k_HexRecord_Size; i++) + { + unsigned c = p[i]; + c -= '0'; + if (c > 9) + { + c -= 'A' - '0'; + c &= ~0x20u; + if (c > 5) + return false; + } + } + return true; +} + +static UInt32 ReadHex(const Byte *p) +{ + char sz[16]; + memcpy(sz, p, 8); + sz[8] = 0; + const char *end; + return ConvertHexStringToUInt32(sz, &end); +} + +static UInt32 ReadOct6(const Byte *p) +{ + char sz[16]; + memcpy(sz, p, 6); + sz[6] = 0; + const char *end; + return ConvertOctStringToUInt32(sz, &end); +} + +static UInt64 ReadOct11(const Byte *p) +{ + char sz[16]; + memcpy(sz, p, 11); + sz[11] = 0; + const char *end; + return ConvertOctStringToUInt64(sz, &end); +} + + +#define READ_HEX( y, dest) dest = ReadHex (p + 6 + (y) * 8); +#define READ_OCT_6( y, dest) dest = ReadOct6 (p + 6 + (y)); +#define READ_OCT_11( y, dest) dest = ReadOct11(p + 6 + (y)); + +#define Get32spec(p) (((UInt32)GetUi16(p) << 16) + GetUi16(p + 2)) +#define G16(offs, v) v = GetUi16(p + (offs)) +#define G32(offs, v) v = Get32spec(p + (offs)) + +static const unsigned kNameSizeMax = 1 << 12; + + +API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size) +{ + if (size < k_BinRecord_Size) + return k_IsArc_Res_NEED_MORE; + + UInt32 namePos; + UInt32 nameSize; + UInt32 mode; + // UInt32 rDevMinor; + UInt32 rDevMajor = 0; + + if (p[0] == '0') + { + if (p[1] != '7' || + p[2] != '0' || + p[3] != '7' || + p[4] != '0') + return k_IsArc_Res_NO; + if (p[5] == kMagicOct) + { + if (size < k_OctRecord_Size) + return k_IsArc_Res_NEED_MORE; + if (!CheckOctRecord(p)) + return k_IsArc_Res_NO; + READ_OCT_6 (2 * 6, mode) + // READ_OCT_6 (6 * 6, rDevMinor) + READ_OCT_6 (7 * 6 + 11, nameSize) + namePos = k_OctRecord_Size; + } + else if (p[5] == kMagicHex || p[5] == kMagicHexCrc) + { + if (size < k_HexRecord_Size) + return k_IsArc_Res_NEED_MORE; + if (!CheckHexRecord(p)) + return k_IsArc_Res_NO; + READ_HEX (1, mode) + READ_HEX (9, rDevMajor) + // READ_HEX (10, rDevMinor) + READ_HEX (11, nameSize) + namePos = k_HexRecord_Size; + } + else + return k_IsArc_Res_NO; + } + else + { + if (p[0] == kMagicBin0 && p[1] == kMagicBin1) + { + mode = GetUi16(p + 6); + // rDevMinor = GetUi16(p + 14); + nameSize = GetUi16(p + 20); + } + else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) + { + mode = GetBe16(p + 6); + // rDevMinor = GetBe16(p + 14); + nameSize = GetBe16(p + 20); + } + else + return k_IsArc_Res_NO; + namePos = k_BinRecord_Size; + } + + if (mode >= (1 << 16)) + return k_IsArc_Res_NO; + + /* v23.02: we have disabled rDevMinor check because real file + from Apple contains rDevMinor==255 by some unknown reason */ + if (rDevMajor != 0 + // || rDevMinor != 0 + ) + { + if (!MY_LIN_S_ISCHR(mode) && + !MY_LIN_S_ISBLK(mode)) + return k_IsArc_Res_NO; + } + + // nameSize must include the null byte + if (nameSize == 0 || nameSize > kNameSizeMax) + return k_IsArc_Res_NO; + { + unsigned lim = namePos + nameSize - 1; + if (lim >= size) + lim = (unsigned)size; + else if (p[lim] != 0) + return k_IsArc_Res_NO; + for (unsigned i = namePos; i < lim; i++) + if (p[i] == 0) + return k_IsArc_Res_NO; + } + + return k_IsArc_Res_YES; +} +} + + +#define READ_STREAM(_dest_, _size_) \ + { size_t processed = (_size_); RINOK(Read(_dest_, &processed)); \ +if (processed != (_size_)) { errorType = k_ErrorType_UnexpectedEnd; return S_OK; } } + +HRESULT CInArchive::GetNextItem() +{ + errorType = k_ErrorType_BadSignature; + + Byte p[k_RecordSize_Max]; + + READ_STREAM(p, k_BinRecord_Size) + + UInt32 nameSize; + UInt32 namePos; + + /* we try to reduce probability of false detection, + so we check some fields for unuxpected values */ + + if (p[0] != '0') + { + if (p[0] == kMagicBin0 && p[1] == kMagicBin1) { item.Type = k_Type_BinLe; } + else if (p[0] == kMagicBin1 && p[1] == kMagicBin0) + { + for (unsigned i = 2; i < k_BinRecord_Size; i += 2) + { + const Byte b = p[i]; + p[i] = p[i + 1]; + p[i + 1] = b; + } + item.Type = k_Type_BinBe; + } + else + return S_OK; + + errorType = k_ErrorType_Corrupted; + + item.AlignMask = 2 - 1; + item.DevMajor = 0; + item.RDevMajor = 0; + item.ChkSum = 0; + + G16(2, item.DevMinor); + G16(4, item.inode); + G16(6, item.Mode); + G16(8, item.UID); + G16(10, item.GID); + G16(12, item.NumLinks); + G16(14, item.RDevMinor); + G32(16, item.MTime); + G16(20, nameSize); + G32(22, item.Size); + + namePos = k_BinRecord_Size; + } + else + { + if (p[1] != '7' || + p[2] != '0' || + p[3] != '7' || + p[4] != '0') + return S_OK; + if (p[5] == kMagicOct) + { + errorType = k_ErrorType_Corrupted; + + item.Type = k_Type_Oct; + READ_STREAM(p + k_BinRecord_Size, k_OctRecord_Size - k_BinRecord_Size) + item.AlignMask = 1 - 1; + item.DevMajor = 0; + item.RDevMajor = 0; + item.ChkSum = 0; + + if (!CheckOctRecord(p)) + return S_OK; + + READ_OCT_6 (0, item.DevMinor) + READ_OCT_6 (1 * 6, item.inode) + READ_OCT_6 (2 * 6, item.Mode) + READ_OCT_6 (3 * 6, item.UID) + READ_OCT_6 (4 * 6, item.GID) + READ_OCT_6 (5 * 6, item.NumLinks) + READ_OCT_6 (6 * 6, item.RDevMinor) + { + UInt64 mTime64; + READ_OCT_11 (7 * 6, mTime64) + item.MTime = 0; + if (mTime64 <= (UInt32)(Int32)-1) + item.MTime = (UInt32)mTime64; + } + READ_OCT_6 (7 * 6 + 11, nameSize) + READ_OCT_11 (8 * 6 + 11, item.Size) // ????? + + namePos = k_OctRecord_Size; + } + else + { + if (p[5] == kMagicHex) item.Type = k_Type_Hex; + else if (p[5] == kMagicHexCrc) item.Type = k_Type_HexCrc; + else return S_OK; + + errorType = k_ErrorType_Corrupted; + + READ_STREAM(p + k_BinRecord_Size, k_HexRecord_Size - k_BinRecord_Size) + + if (!CheckHexRecord(p)) + return S_OK; + + item.AlignMask = 4 - 1; + READ_HEX (0, item.inode) + READ_HEX (1, item.Mode) + READ_HEX (2, item.UID) + READ_HEX (3, item.GID) + READ_HEX (4, item.NumLinks) + READ_HEX (5, item.MTime) + READ_HEX (6, item.Size) + READ_HEX (7, item.DevMajor) + READ_HEX (8, item.DevMinor) + READ_HEX (9, item.RDevMajor) + READ_HEX (10, item.RDevMinor) + READ_HEX (11, nameSize) + READ_HEX (12, item.ChkSum) + + if (item.Type == k_Type_Hex && item.ChkSum != 0) + return S_OK; + + namePos = k_HexRecord_Size; + } + } + + if (item.Mode >= (1 << 16)) + return S_OK; + + /* v23.02: we have disabled rDevMinor check because real file + from Apple contains rDevMinor==255 by some unknown reason + cpio 2.13 and older versions: it copies stat::st_rdev to archive. + and stat::st_rdev can be non-zero for some old linux/filesystems cases for regular files. + cpio 2.14 (2023) copies st_rdev to archive only if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) + v25.00: we have disabled RDevMajor check here to support some rare case created by cpio 2.13- with old linux. + But we still keep full check in IsArc_Cpio() to reduce false cpio detection cases. + */ +#if 0 // 0 : to disable check to support some old linux cpio archives. + if (item.RDevMajor != 0 + // || item.RDevMinor != 0 + ) + { + if (!MY_LIN_S_ISCHR(item.Mode) && + !MY_LIN_S_ISBLK(item.Mode)) + return S_OK; + } +#endif + + // Size must be 0 for FIFOs and directories + if (item.IsDir() || MY_LIN_S_ISFIFO(item.Mode)) + if (item.Size != 0) + return S_OK; + + // nameSize must include the null byte + if (nameSize == 0 || nameSize > kNameSizeMax) + return S_OK; + item.HeaderSize = item.GetAlignedSize(namePos + nameSize); + const UInt32 rem = item.HeaderSize - namePos; + char *s = item.Name.GetBuf(rem); + size_t processedSize = rem; + RINOK(Read(s, &processedSize)) + if (processedSize != rem) + { + item.Name.ReleaseBuf_SetEnd(0); + errorType = k_ErrorType_UnexpectedEnd; + return S_OK; + } + bool pad_error = false; + for (size_t i = nameSize; i < processedSize; i++) + if (s[i] != 0) + pad_error = true; + item.Name.ReleaseBuf_CalcLen(nameSize); + if (item.Name.Len() + 1 != nameSize || pad_error) + return S_OK; + errorType = k_ErrorType_OK; + return S_OK; +} + + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CObjectVector _items; + CMyComPtr _stream; + UInt64 _phySize; + EType _type; + EErrorType _error; + bool _isArc; + bool _moreThanOneHardLinks_Error; + bool _numLinks_Error; + bool _pad_Error; + bool _symLink_Error; +}; + +static const Byte kArcProps[] = +{ + kpidSubType +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidPosixAttrib, + kpidLinks, + kpidINode, + kpidUserId, + kpidGroupId, + kpidDevMajor, + kpidDevMinor, + kpidDeviceMajor, + kpidDeviceMinor, + kpidChecksum, + kpidSymLink, + kpidStreamId, // for debug + kpidOffset +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidSubType: prop = k_Types[(unsigned)_type]; break; + case kpidPhySize: prop = _phySize; break; + case kpidINode: prop = true; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) + v |= kpv_ErrorFlags_IsNotArc; + switch (_error) + { + case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break; + case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break; + case k_ErrorType_OK: + case k_ErrorType_BadSignature: + // default: + break; + } + prop = v; + break; + } + case kpidWarningFlags: + { + UInt32 v = 0; + if (_moreThanOneHardLinks_Error) + v |= kpv_ErrorFlags_UnsupportedFeature; // kpv_ErrorFlags_HeadersError + if (_numLinks_Error + || _pad_Error + || _symLink_Error) + v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +static int CompareItems(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + const unsigned index1 = *p1; + const unsigned index2 = *p2; + const CItem &i1 = items[index1]; + const CItem &i2 = items[index2]; + if (i1.DevMajor < i2.DevMajor) return -1; + if (i1.DevMajor > i2.DevMajor) return 1; + if (i1.DevMinor < i2.DevMinor) return -1; + if (i1.DevMinor > i2.DevMinor) return 1; + if (i1.inode < i2.inode) return -1; + if (i1.inode > i2.inode) return 1; + if (i1.IsDir()) + { + if (!i2.IsDir()) + return -1; + } + else if (i2.IsDir()) + return 1; + return MyCompare(index1, index2); +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(stream, endPos)) + if (callback) + { + RINOK(callback->SetTotal(NULL, &endPos)) + } + + CInArchive arc; + + arc.Stream = stream; + arc.Processed = 0; + + for (;;) + { + CItem &item = arc.item; + item.HeaderPos = arc.Processed; + + RINOK(arc.GetNextItem()) + + _error = arc.errorType; + + if (_error != k_ErrorType_OK) + { + if (_error == k_ErrorType_BadSignature || + _error == k_ErrorType_Corrupted) + arc.Processed = item.HeaderPos; + break; + } + + if (_items.IsEmpty()) + _type = item.Type; + else if (_items.Back().Type != item.Type) + { + _error = k_ErrorType_Corrupted; + arc.Processed = item.HeaderPos; + break; + } + + if (item.IsTrailer()) + break; + + item.MainIndex_ForInode = _items.Size(); + _items.Add(item); + + const UInt64 dataSize = item.GetPackSize(); + arc.Processed += dataSize; + if (arc.Processed > endPos) + { + _error = k_ErrorType_UnexpectedEnd; + break; + } + + if (item.Is_SymLink() && dataSize <= (1 << 12) && item.Size != 0) + { + size_t cur = (size_t)dataSize; + CByteBuffer buf; + buf.Alloc(cur); + RINOK(ReadStream(stream, buf, &cur)) + if (cur != dataSize) + { + _error = k_ErrorType_UnexpectedEnd; + break; + } + size_t i; + + for (i = (size_t)item.Size; i < dataSize; i++) + if (buf[i] != 0) + break; + if (i != dataSize) + _pad_Error = true; + + for (i = 0; i < (size_t)item.Size; i++) + if (buf[i] == 0) + break; + if (i != (size_t)item.Size) + _symLink_Error = true; + else + _items.Back().Data.CopyFrom(buf, (size_t)item.Size); + } + else if (dataSize != 0) + { + UInt64 newPos; + RINOK(stream->Seek((Int64)dataSize, STREAM_SEEK_CUR, &newPos)) + if (arc.Processed != newPos) + return E_FAIL; + } + + if (callback && (_items.Size() & 0xFFF) == 0) + { + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &item.HeaderPos)) + } + } + + _phySize = arc.Processed; + } + + { + if (_error != k_ErrorType_OK) + { + // we try to reduce probability of false detection + if (_items.Size() == 0) + return S_FALSE; + // bin file uses small signature. So we do additional check for single item case. + if (_items.Size() == 1 && _items[0].IsBin()) + return S_FALSE; + } + else + { + // Read tailing zeros. + // Most of cpio files use 512-bytes aligned zeros + // rare case: 4K/8K aligment is possible also + const unsigned kTailSize_MAX = 1 << 9; + Byte buf[kTailSize_MAX]; + + unsigned pos = (unsigned)_phySize & (kTailSize_MAX - 1); + if (pos != 0) // use this check to support 512 bytes alignment only + for (;;) + { + const unsigned rem = kTailSize_MAX - pos; + size_t processed = rem; + RINOK(ReadStream(stream, buf + pos, &processed)) + if (processed != rem) + break; + for (; pos < kTailSize_MAX && buf[pos] == 0; pos++) + {} + if (pos != kTailSize_MAX) + break; + _phySize += processed; + pos = 0; + + // use break to support 512 bytes alignment zero tail + // don't use break to support 512*n bytes alignment zero tail + break; + } + } + } + + { + /* there was such cpio archive example with hard links: + { + all hard links (same dev/inode) are stored in neighboring items, and + (item.Size == 0) for non last hard link items + (item.Size != 0) for last hard link item + } + but here we sort items by (dev/inode) to support cases + where hard links (same dev/inode) are not stored in neighboring items. + + // note: some cpio files have (numLinks == 0) ?? + */ + + CUIntVector indices; + { + const unsigned numItems = _items.Size(); + indices.ClearAndSetSize(numItems); + if (numItems != 0) + { + unsigned *vals = &indices[0]; + for (unsigned i = 0; i < numItems; i++) + vals[i] = i; + indices.Sort(CompareItems, (void *)&_items); + } + } + + /* Note: if cpio archive (maybe incorrect) contains + more then one non empty streams with identical inode number, + we want to extract all such data streams too. + + So we place items with identical inode to groups: + all items in group will have same MainIndex_ForInode, + that is index of last item in group with (Size != 0). + Another (non last) items in group have (Size == 0). + If there are another hard links with same inode number + after (Size != 0) item, we place them to another next group(s). + + Check it: maybe we should use single group for items + with identical inode instead, and ignore some extra data streams ? + */ + + for (unsigned i = 0; i < indices.Size();) + { + unsigned k; + { + const CItem &item_Base = _items[indices[i]]; + + if (item_Base.IsDir()) + { + i++; + continue; + } + + if (i != 0) + { + const CItem &item_Prev = _items[indices[i - 1]]; + if (!item_Prev.IsDir()) + if (item_Base.IsSame_inode_Dev(item_Prev)) + _moreThanOneHardLinks_Error = true; + } + + if (item_Base.Size != 0) + { + if (item_Base.NumLinks != 1) + _numLinks_Error = true; + i++; + continue; + } + + for (k = i + 1; k < indices.Size();) + { + const CItem &item = _items[indices[k]]; + if (item.IsDir()) + break; + if (!item.IsSame_inode_Dev(item_Base)) + break; + k++; + if (item.Size != 0) + break; + } + } + + const unsigned numLinks = k - i; + for (;;) + { + CItem &item = _items[indices[i]]; + if (item.NumLinks != numLinks) + _numLinks_Error = true; + if (++i == k) + break; + // if (item.Size == 0) + item.MainIndex_ForInode = indices[k - 1]; + } + } + } + + _isArc = true; + _stream = stream; + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _items.Clear(); + _stream.Release(); + _phySize = 0; + _type = k_Type_BinLe; + _isArc = false; + _moreThanOneHardLinks_Error = false; + _numLinks_Error = false; + _pad_Error = false; + _symLink_Error = false; + _error = k_ErrorType_OK; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CItem &item = _items[index]; + + switch (propID) + { + case kpidPath: + { +#ifdef _WIN32 + UString u; + ConvertUTF8ToUnicode(item.Name, u); +#else + const UString u = MultiByteToUnicodeString(item.Name, CP_OEMCP); +#endif + prop = NItemName::GetOsPath(u); + break; + } + case kpidIsDir: prop = item.IsDir(); break; + + case kpidSize: + prop = (UInt64)_items[item.MainIndex_ForInode].Size; + break; + + case kpidPackSize: + prop = (UInt64)item.GetPackSize(); + break; + + case kpidMTime: + { + if (item.MTime != 0) + PropVariant_SetFrom_UnixTime(prop, item.MTime); + break; + } + case kpidPosixAttrib: prop = item.Mode; break; + case kpidINode: prop = item.inode; break; + case kpidStreamId: + if (!item.IsDir()) + prop = (UInt32)item.MainIndex_ForInode; + break; + case kpidDevMajor: prop = (UInt32)item.DevMajor; break; + case kpidDevMinor: prop = (UInt32)item.DevMinor; break; + + case kpidUserId: prop = item.UID; break; + case kpidGroupId: prop = item.GID; break; + + case kpidSymLink: + if (item.Is_SymLink() && item.Data.Size() != 0) + { + AString s; + s.SetFrom_CalcLen((const char *)(const void *)(const Byte *)item.Data, (unsigned)item.Data.Size()); + if (s.Len() == item.Data.Size()) + { +#ifdef _WIN32 + UString u; + ConvertUTF8ToUnicode(item.Name, u); +#else + const UString u = MultiByteToUnicodeString(s, CP_OEMCP); +#endif + prop = u; + } + } + break; + + case kpidLinks: prop = item.NumLinks; break; + case kpidDeviceMajor: + // if (item.RDevMajor != 0) + prop = (UInt32)item.RDevMajor; + break; + case kpidDeviceMinor: + // if (item.RDevMinor != 0) + prop = (UInt32)item.RDevMinor; + break; + case kpidChecksum: + if (item.IsCrcFormat()) + prop = item.ChkSum; + break; + case kpidOffset: prop = item.GetDataPosition(); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSum + , ISequentialOutStream +) + CMyComPtr _stream; + UInt32 _checksum; + bool _calculate; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool calculate) + { + _calculate = calculate; + _checksum = 0; + } + UInt32 GetChecksum() const { return _checksum; } +}; + + +Z7_COM7F_IMF(COutStreamWithSum::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (processedSize) + *processedSize = size; + if (_calculate) + { + const Byte *p = (const Byte *)data; + const Byte *lim = p + size; + UInt32 sum = _checksum; + if (size >= 4) + { + lim -= 4 - 1; + do + { + sum += p[0] + p[1] + p[2] + p[3]; + p += 4; + } + while (p < lim); + lim += 4 - 1; + } + if (p != lim) { sum += *p++; + if (p != lim) { sum += *p++; + if (p != lim) { sum += *p++; }}} + _checksum = sum; + } + return result; +} + +Z7_COM7F_IMF(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]; + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; + totalSize += item.Size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + CMyComPtr2_Create outStreamSum; + + UInt64 total_PackSize = 0; + UInt64 total_UnpackSize = 0; + + for (i = 0;; i++) + { + lps->InSize = total_PackSize; + lps->OutSize = total_UnpackSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; + { + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + + total_PackSize += item2.GetPackSize(); + total_UnpackSize += item.Size; + + if (item2.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + if (!testMode && !outStream) + continue; + outStreamSum->Init(item.IsCrcFormat()); + outStreamSum->SetStream(outStream); + RINOK(extractCallback->PrepareOperation(askMode)) + } + RINOK(InStream_SeekSet(_stream, item.GetDataPosition())) + inStream->Init(item.Size); + RINOK(copyCoder.Interface()->Code(inStream, outStreamSum, NULL, NULL, lps)) + outStreamSum->ReleaseStream(); + Int32 res = NExtract::NOperationResult::kDataError; + if (copyCoder->TotalSize == item.Size) + { + res = NExtract::NOperationResult::kOK; + if (item.IsCrcFormat() && item.ChkSum != outStreamSum->GetChecksum()) + res = NExtract::NOperationResult::kCRCError; + } + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + const CItem &item2 = _items[index]; + const CItem &item = _items[item2.MainIndex_ForInode]; + return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream); + COM_TRY_END +} + +static const Byte k_Signature[] = { + 5, '0', '7', '0', '7', '0', + 2, kMagicBin0, kMagicBin1, + 2, kMagicBin1, kMagicBin0 }; + +REGISTER_ARC_I( + "Cpio", "cpio", NULL, 0xED, + k_Signature, + 0, + NArcInfoFlags::kMultiSignature, + IsArc_Cpio) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/CramfsHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CramfsHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/CramfsHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/CramfsHandler.cpp 2023-03-26 12:00:00.000000000 +0000 @@ -1,787 +1,784 @@ -// CramfsHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" -#include "../../../C/LzmaDec.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyLinux.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariantUtils.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 "../Compress/ZlibDecoder.h" - -namespace NArchive { -namespace NCramfs { - -#define SIGNATURE { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' } - -static const Byte kSignature[] = SIGNATURE; - -static const UInt32 kArcSizeMax = (256 + 16) << 20; -static const UInt32 kNumFilesMax = (1 << 19); -static const unsigned kNumDirLevelsMax = (1 << 8); - -static const UInt32 kHeaderSize = 0x40; -static const unsigned kHeaderNameSize = 16; -static const UInt32 kNodeSize = 12; - -static const UInt32 kFlag_FsVer2 = (1 << 0); - -static const unsigned k_Flags_BlockSize_Shift = 11; -static const unsigned k_Flags_BlockSize_Mask = 7; -static const unsigned k_Flags_Method_Shift = 14; -static const unsigned k_Flags_Method_Mask = 3; - -/* - There is possible collision in flags: - - Original CramFS writes 0 in method field. But it uses ZLIB. - - Modified CramFS writes 0 in method field for "NONE" compression? - How to solve that collision? -*/ - -#define k_Flags_Method_NONE 0 -#define k_Flags_Method_ZLIB 1 -#define k_Flags_Method_LZMA 2 - -static const char * const k_Methods[] = -{ - "Copy" - , "ZLIB" - , "LZMA" - , "Unknown" -}; - -static const CUInt32PCharPair k_Flags[] = -{ - { 0, "Ver2" }, - { 1, "SortedDirs" }, - { 8, "Holes" }, - { 9, "WrongSignature" }, - { 10, "ShiftedRootOffset" } -}; - -static const unsigned kBlockSizeLog = 12; - -/* -struct CNode -{ - UInt16 Mode; - UInt16 Uid; - UInt32 Size; - Byte Gid; - UInt32 NameLen; - UInt32 Offset; - - void Parse(const Byte *p) - { - Mode = GetUi16(p); - Uid = GetUi16(p + 2); - Size = Get32(p + 4) & 0xFFFFFF; - Gid = p[7]; - NameLen = p[8] & 0x3F; - Offset = Get32(p + 8) >> 6; - } -}; -*/ - -#define Get32(p) (be ? GetBe32(p) : GetUi32(p)) - -static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); } -static bool IsDir(const Byte *p, bool be) { return MY_LIN_S_ISDIR(GetMode(p, be)); } - -static UInt32 GetSize(const Byte *p, bool be) -{ - if (be) - return GetBe32(p + 4) >> 8; - else - return GetUi32(p + 4) & 0xFFFFFF; -} - -static UInt32 GetNameLen(const Byte *p, bool be) -{ - if (be) - return (p[8] & 0xFC); - else - return (p[8] & 0x3F) << 2; -} - -static UInt32 GetOffset(const Byte *p, bool be) -{ - if (be) - return (GetBe32(p + 8) & 0x03FFFFFF) << 2; - else - return GetUi32(p + 8) >> 6 << 2; -} - -struct CItem -{ - UInt32 Offset; - int Parent; -}; - -struct CHeader -{ - bool be; - UInt32 Size; - UInt32 Flags; - // UInt32 Future; - UInt32 Crc; - // UInt32 Edition; - UInt32 NumBlocks; - UInt32 NumFiles; - char Name[kHeaderNameSize]; - - bool Parse(const Byte *p) - { - if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0) - return false; - switch (GetUi32(p)) - { - case 0x28CD3D45: be = false; break; - case 0x453DCD28: be = true; break; - default: return false; - } - Size = Get32(p + 4); - Flags = Get32(p + 8); - // Future = Get32(p + 0xC); - Crc = Get32(p + 0x20); - // Edition = Get32(p + 0x24); - NumBlocks = Get32(p + 0x28); - NumFiles = Get32(p + 0x2C); - memcpy(Name, p + 0x30, kHeaderNameSize); - return true; - } - - bool IsVer2() const { return (Flags & kFlag_FsVer2) != 0; } - unsigned GetBlockSizeShift() const { return (unsigned)(Flags >> k_Flags_BlockSize_Shift) & k_Flags_BlockSize_Mask; } - unsigned GetMethod() const { return (unsigned)(Flags >> k_Flags_Method_Shift) & k_Flags_Method_Mask; } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CRecordVector _items; - CMyComPtr _stream; - Byte *_data; - UInt32 _size; - UInt32 _headersSize; - - UInt32 _errorFlags; - bool _isArc; - - CHeader _h; - UInt32 _phySize; - - unsigned _method; - unsigned _blockSizeLog; - - // Current file - - NCompress::NZlib::CDecoder *_zlibDecoderSpec; - CMyComPtr _zlibDecoder; - - CBufInStream *_inStreamSpec; - CMyComPtr _inStream; - - CBufPtrSeqOutStream *_outStreamSpec; - CMyComPtr _outStream; - - UInt32 _curBlocksOffset; - UInt32 _curNumBlocks; - - HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level); - HRESULT Open2(IInStream *inStream); - AString GetPath(int index) const; - bool GetPackSize(int index, UInt32 &res) const; - void Free(); - - UInt32 GetNumBlocks(UInt32 size) const - { - return (size + ((UInt32)1 << _blockSizeLog) - 1) >> _blockSizeLog; - } - - void UpdatePhySize(UInt32 s) - { - if (_phySize < s) - _phySize = s; - } - -public: - CHandler(): _data(0) {} - ~CHandler() { Free(); } - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidPosixAttrib - // kpidOffset -}; - -static const Byte kArcProps[] = -{ - kpidVolumeName, - kpidBigEndian, - kpidCharacts, - kpidClusterSize, - kpidMethod, - kpidHeadersSize, - kpidNumSubFiles, - kpidNumBlocks -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -HRESULT CHandler::OpenDir(int parent, UInt32 baseOffset, unsigned level) -{ - const Byte *p = _data + baseOffset; - bool be = _h.be; - if (!IsDir(p, be)) - return S_OK; - UInt32 offset = GetOffset(p, be); - UInt32 size = GetSize(p, be); - if (offset == 0 && size == 0) - return S_OK; - UInt32 end = offset + size; - if (offset < kHeaderSize || end > _size || level > kNumDirLevelsMax) - return S_FALSE; - UpdatePhySize(end); - if (end > _headersSize) - _headersSize = end; - - unsigned startIndex = _items.Size(); - - while (size != 0) - { - if (size < kNodeSize || (UInt32)_items.Size() >= kNumFilesMax) - return S_FALSE; - CItem item; - item.Parent = parent; - item.Offset = offset; - _items.Add(item); - UInt32 nodeLen = kNodeSize + GetNameLen(_data + offset, be); - if (size < nodeLen) - return S_FALSE; - offset += nodeLen; - size -= nodeLen; - } - - unsigned endIndex = _items.Size(); - for (unsigned i = startIndex; i < endIndex; i++) - { - RINOK(OpenDir(i, _items[i].Offset, level + 1)); - } - return S_OK; -} - -HRESULT CHandler::Open2(IInStream *inStream) -{ - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); - if (!_h.Parse(buf)) - return S_FALSE; - _method = k_Flags_Method_ZLIB; - _blockSizeLog = kBlockSizeLog; - _phySize = kHeaderSize; - if (_h.IsVer2()) - { - _method = _h.GetMethod(); - // FIT IT. Now we don't know correct way to work with collision in method field. - if (_method == k_Flags_Method_NONE) - _method = k_Flags_Method_ZLIB; - _blockSizeLog = kBlockSizeLog + _h.GetBlockSizeShift(); - if (_h.Size < kHeaderSize || _h.Size > kArcSizeMax || _h.NumFiles > kNumFilesMax) - return S_FALSE; - _phySize = _h.Size; - } - else - { - UInt64 size; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &size)); - if (size > kArcSizeMax) - size = kArcSizeMax; - _h.Size = (UInt32)size; - RINOK(inStream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL)); - } - _data = (Byte *)MidAlloc(_h.Size); - if (_data == 0) - return E_OUTOFMEMORY; - memcpy(_data, buf, kHeaderSize); - size_t processed = _h.Size - kHeaderSize; - RINOK(ReadStream(inStream, _data + kHeaderSize, &processed)); - if (processed < kNodeSize) - return S_FALSE; - _size = kHeaderSize + (UInt32)processed; - if (_h.IsVer2()) - { - if (_size != _h.Size) - _errorFlags = kpv_ErrorFlags_UnexpectedEnd; - else - { - SetUi32(_data + 0x20, 0); - if (CrcCalc(_data, _h.Size) != _h.Crc) - { - _errorFlags = kpv_ErrorFlags_HeadersError; - // _errorMessage = "CRC error"; - } - } - if (_h.NumFiles >= 1) - _items.ClearAndReserve(_h.NumFiles - 1); - } - - RINOK(OpenDir(-1, kHeaderSize, 0)); - - if (!_h.IsVer2()) - { - FOR_VECTOR (i, _items) - { - const CItem &item = _items[i]; - const Byte *p = _data + item.Offset; - bool be = _h.be; - if (IsDir(p, be)) - continue; - UInt32 offset = GetOffset(p, be); - if (offset < kHeaderSize) - continue; - UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); - if (numBlocks == 0) - continue; - UInt32 start = offset + numBlocks * 4; - if (start > _size) - continue; - UInt32 end = Get32(_data + start - 4); - if (end >= start) - UpdatePhySize(end); - } - - // Read tailing zeros. Most cramfs archives use 4096-bytes aligned zeros - const UInt32 kTailSize_MAX = 1 << 12; - UInt32 endPos = (_phySize + kTailSize_MAX - 1) & ~(kTailSize_MAX - 1); - if (endPos > _size) - endPos = _size; - UInt32 pos; - for (pos = _phySize; pos < endPos && _data[pos] == 0; pos++); - if (pos == endPos) - _phySize = endPos; - } - return S_OK; -} - -AString CHandler::GetPath(int index) const -{ - unsigned len = 0; - int indexMem = index; - do - { - const CItem &item = _items[index]; - index = item.Parent; - const Byte *p = _data + item.Offset; - unsigned size = GetNameLen(p, _h.be); - p += kNodeSize; - unsigned i; - for (i = 0; i < size && p[i]; i++); - len += i + 1; - } - while (index >= 0); - len--; - - AString path; - char *dest = path.GetBuf_SetEnd(len) + len; - index = indexMem; - for (;;) - { - const CItem &item = _items[index]; - index = item.Parent; - const Byte *p = _data + item.Offset; - unsigned size = GetNameLen(p, _h.be); - p += kNodeSize; - unsigned i; - for (i = 0; i < size && p[i]; i++); - dest -= i; - memcpy(dest, p, i); - if (index < 0) - break; - *(--dest) = CHAR_PATH_SEPARATOR; - } - return path; -} - -bool CHandler::GetPackSize(int index, UInt32 &res) const -{ - res = 0; - const CItem &item = _items[index]; - const Byte *p = _data + item.Offset; - bool be = _h.be; - UInt32 offset = GetOffset(p, be); - if (offset < kHeaderSize) - return false; - UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); - if (numBlocks == 0) - return true; - UInt32 start = offset + numBlocks * 4; - if (start > _size) - return false; - UInt32 end = Get32(_data + start - 4); - if (end < start) - return false; - res = end - start; - return true; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */) -{ - COM_TRY_BEGIN - { - Close(); - RINOK(Open2(stream)); - _isArc = true; - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -void CHandler::Free() -{ - MidFree(_data); - _data = 0; -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _phySize = 0; - _errorFlags = 0; - _headersSize = 0; - _items.Clear(); - _stream.Release(); - Free(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidVolumeName: - { - char dest[kHeaderNameSize + 4]; - memcpy(dest, _h.Name, kHeaderNameSize); - dest[kHeaderNameSize] = 0; - prop = dest; - break; - } - case kpidBigEndian: prop = _h.be; break; - case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break; - case kpidMethod: prop = k_Methods[_method]; break; - case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; - case kpidNumBlocks: if (_h.IsVer2()) prop = _h.NumBlocks; break; - case kpidNumSubFiles: if (_h.IsVer2()) prop = _h.NumFiles; break; - case kpidPhySize: prop = _phySize; break; - case kpidHeadersSize: prop = _headersSize; break; - case kpidErrorFlags: - { - UInt32 v = _errorFlags; - if (!_isArc) - v |= kpv_ErrorFlags_IsNotArc; - prop = v; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItem &item = _items[index]; - const Byte *p = _data + item.Offset; - bool be = _h.be; - bool isDir = IsDir(p, be); - switch (propID) - { - case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; - case kpidIsDir: prop = isDir; break; - // case kpidOffset: prop = (UInt32)GetOffset(p, be); break; - case kpidSize: if (!isDir) prop = GetSize(p, be); break; - case kpidPackSize: - if (!isDir) - { - UInt32 size; - if (GetPackSize(index, size)) - prop = size; - } - break; - case kpidPosixAttrib: prop = (UInt32)GetMode(p, be); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CCramfsInStream: public CCachedInStream -{ - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); -public: - CHandler *Handler; -}; - -HRESULT CCramfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) -{ - return Handler->ReadBlock(blockIndex, dest, blockSize); -} - -HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) -{ - if (_method == k_Flags_Method_ZLIB) - { - if (!_zlibDecoder) - { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); - _zlibDecoder = _zlibDecoderSpec; - } - } - else - { - if (_method != k_Flags_Method_LZMA) - { - // probably we must support no-compression archives here. - return E_NOTIMPL; - } - } - - const bool be = _h.be; - const Byte *p2 = _data + (_curBlocksOffset + (UInt32)blockIndex * 4); - const UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p2 - 4)); - const UInt32 end = Get32(p2); - if (end < start || end > _size) - return S_FALSE; - const UInt32 inSize = end - start; - - if (_method == k_Flags_Method_LZMA) - { - const unsigned kLzmaHeaderSize = LZMA_PROPS_SIZE + 4; - if (inSize < kLzmaHeaderSize) - return S_FALSE; - const Byte *p = _data + start; - UInt32 destSize32 = GetUi32(p + LZMA_PROPS_SIZE); - if (destSize32 > blockSize) - return S_FALSE; - SizeT destLen = destSize32; - SizeT srcLen = inSize - kLzmaHeaderSize; - ELzmaStatus status; - SRes res = LzmaDecode(dest, &destLen, p + kLzmaHeaderSize, &srcLen, - p, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc); - if (res != SZ_OK - || (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - || destLen != destSize32 - || srcLen != inSize - kLzmaHeaderSize) - return S_FALSE; - return S_OK; - } - - if (!_inStream) - { - _inStreamSpec = new CBufInStream(); - _inStream = _inStreamSpec; - } - if (!_outStream) - { - _outStreamSpec = new CBufPtrSeqOutStream(); - _outStream = _outStreamSpec; - } - _inStreamSpec->Init(_data + start, inSize); - _outStreamSpec->Init(dest, blockSize); - RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL)); - return (inSize == _zlibDecoderSpec->GetInputProcessedSize() && - _outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (numItems == 0) - return S_OK; - bool be = _h.be; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const Byte *p = _data + _items[allFilesMode ? i : indices[i]].Offset; - if (!IsDir(p, be)) - totalSize += GetSize(p, be); - } - extractCallback->SetTotal(totalSize); - - UInt64 totalPackSize; - totalSize = totalPackSize = 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 = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - const Byte *p = _data + item.Offset; - - if (IsDir(p, be)) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - UInt32 curSize = GetSize(p, be); - totalSize += curSize; - UInt32 packSize; - if (GetPackSize(index, packSize)) - totalPackSize += packSize; - - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - UInt32 offset = GetOffset(p, be); - if (offset < kHeaderSize) - curSize = 0; - - int res = NExtract::NOperationResult::kDataError; - { - CMyComPtr inSeqStream; - HRESULT hres = GetStream(index, &inSeqStream); - if (hres == E_OUTOFMEMORY) - return E_OUTOFMEMORY; - if (hres == S_FALSE || !inSeqStream) - res = NExtract::NOperationResult::kUnsupportedMethod; - else - { - RINOK(hres); - { - hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); - if (hres == S_OK) - { - if (copyCoderSpec->TotalSize == curSize) - res = NExtract::NOperationResult::kOK; - } - else if (hres == E_NOTIMPL) - res = NExtract::NOperationResult::kUnsupportedMethod; - else if (hres != S_FALSE) - return hres; - } - } - } - RINOK(extractCallback->SetOperationResult(res)); - } - - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - - const CItem &item = _items[index]; - const Byte *p = _data + item.Offset; - - bool be = _h.be; - if (IsDir(p, be)) - return E_FAIL; - - UInt32 size = GetSize(p, be); - UInt32 numBlocks = GetNumBlocks(size); - UInt32 offset = GetOffset(p, be); - if (offset < kHeaderSize) - { - if (offset != 0) - return S_FALSE; - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Init(NULL, 0); - *stream = streamTemp.Detach(); - return S_OK; - } - - if (offset + numBlocks * 4 > _size) - return S_FALSE; - UInt32 prev = offset; - for (UInt32 i = 0; i < numBlocks; i++) - { - UInt32 next = Get32(_data + offset + i * 4); - if (next < prev || next > _size) - return S_FALSE; - prev = next; - } - - CCramfsInStream *streamSpec = new CCramfsInStream; - CMyComPtr streamTemp = streamSpec; - _curNumBlocks = numBlocks; - _curBlocksOffset = offset; - streamSpec->Handler = this; - if (!streamSpec->Alloc(_blockSizeLog, 21 - _blockSizeLog)) - return E_OUTOFMEMORY; - streamSpec->Init(size); - *stream = streamTemp.Detach(); - - return S_OK; - COM_TRY_END -} - -REGISTER_ARC_I( - "CramFS", "cramfs", 0, 0xD3, - kSignature, - 16, - 0, - NULL) - -}} +// CramfsHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" +#include "../../../C/LzmaDec.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariantUtils.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 "../Compress/ZlibDecoder.h" + +namespace NArchive { +namespace NCramfs { + +static const Byte kSignature[] = + { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' }; + +static const UInt32 kArcSizeMax = (256 + 16) << 20; +static const UInt32 kNumFilesMax = (1 << 19); +static const unsigned kNumDirLevelsMax = (1 << 8); + +static const UInt32 kHeaderSize = 0x40; +static const unsigned kHeaderNameSize = 16; +static const UInt32 kNodeSize = 12; + +static const UInt32 kFlag_FsVer2 = (1 << 0); + +static const unsigned k_Flags_BlockSize_Shift = 11; +static const unsigned k_Flags_BlockSize_Mask = 7; +static const unsigned k_Flags_Method_Shift = 14; +static const unsigned k_Flags_Method_Mask = 3; + +/* + There is possible collision in flags: + - Original CramFS writes 0 in method field. But it uses ZLIB. + - Modified CramFS writes 0 in method field for "NONE" compression? + How to solve that collision? +*/ + +#define k_Flags_Method_NONE 0 +#define k_Flags_Method_ZLIB 1 +#define k_Flags_Method_LZMA 2 + +static const char * const k_Methods[] = +{ + "Copy" + , "ZLIB" + , "LZMA" + , "Unknown" +}; + +static const CUInt32PCharPair k_Flags[] = +{ + { 0, "Ver2" }, + { 1, "SortedDirs" }, + { 8, "Holes" }, + { 9, "WrongSignature" }, + { 10, "ShiftedRootOffset" } +}; + +static const unsigned kBlockSizeLog = 12; + +/* +struct CNode +{ + UInt16 Mode; + UInt16 Uid; + UInt32 Size; + Byte Gid; + UInt32 NameLen; + UInt32 Offset; + + void Parse(const Byte *p) + { + Mode = GetUi16(p); + Uid = GetUi16(p + 2); + Size = Get32(p + 4) & 0xFFFFFF; + Gid = p[7]; + NameLen = p[8] & 0x3F; + Offset = Get32(p + 8) >> 6; + } +}; +*/ + +#define Get32(p) (be ? GetBe32(p) : GetUi32(p)) + +static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); } +static bool IsDir(const Byte *p, bool be) { return MY_LIN_S_ISDIR(GetMode(p, be)); } + +static UInt32 GetSize(const Byte *p, bool be) +{ + if (be) + return GetBe32(p + 4) >> 8; + else + return GetUi32(p + 4) & 0xFFFFFF; +} + +static UInt32 GetNameLen(const Byte *p, bool be) +{ + if (be) + return (p[8] & 0xFC); + else + return ((UInt32)p[8] & (UInt32)0x3F) << 2; +} + +static UInt32 GetOffset(const Byte *p, bool be) +{ + if (be) + return (GetBe32(p + 8) & 0x03FFFFFF) << 2; + else + return GetUi32(p + 8) >> 6 << 2; +} + +struct CItem +{ + UInt32 Offset; + int Parent; +}; + +struct CHeader +{ + bool be; + UInt32 Size; + UInt32 Flags; + // UInt32 Future; + UInt32 Crc; + // UInt32 Edition; + UInt32 NumBlocks; + UInt32 NumFiles; + char Name[kHeaderNameSize]; + + bool Parse(const Byte *p) + { + if (memcmp(p + 16, kSignature, Z7_ARRAY_SIZE(kSignature)) != 0) + return false; + switch (GetUi32(p)) + { + case 0x28CD3D45: be = false; break; + case 0x453DCD28: be = true; break; + default: return false; + } + Size = Get32(p + 4); + Flags = Get32(p + 8); + // Future = Get32(p + 0xC); + Crc = Get32(p + 0x20); + // Edition = Get32(p + 0x24); + NumBlocks = Get32(p + 0x28); + NumFiles = Get32(p + 0x2C); + memcpy(Name, p + 0x30, kHeaderNameSize); + return true; + } + + bool IsVer2() const { return (Flags & kFlag_FsVer2) != 0; } + unsigned GetBlockSizeShift() const { return (unsigned)(Flags >> k_Flags_BlockSize_Shift) & k_Flags_BlockSize_Mask; } + unsigned GetMethod() const { return (unsigned)(Flags >> k_Flags_Method_Shift) & k_Flags_Method_Mask; } +}; + + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CRecordVector _items; + CMyComPtr _stream; + Byte *_data; + UInt32 _size; + UInt32 _headersSize; + + UInt32 _errorFlags; + bool _isArc; + + CHeader _h; + UInt32 _phySize; + + unsigned _method; + unsigned _blockSizeLog; + + // Current file + + NCompress::NZlib::CDecoder *_zlibDecoderSpec; + CMyComPtr _zlibDecoder; + + CBufInStream *_inStreamSpec; + CMyComPtr _inStream; + + CBufPtrSeqOutStream *_outStreamSpec; + CMyComPtr _outStream; + + UInt32 _curBlocksOffset; + UInt32 _curNumBlocks; + + HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level); + HRESULT Open2(IInStream *inStream); + AString GetPath(unsigned index) const; + bool GetPackSize(unsigned index, UInt32 &res) const; + void Free(); + + UInt32 GetNumBlocks(UInt32 size) const + { + return (size + ((UInt32)1 << _blockSizeLog) - 1) >> _blockSizeLog; + } + + void UpdatePhySize(UInt32 s) + { + if (_phySize < s) + _phySize = s; + } + +public: + CHandler(): _data(NULL) {} + ~CHandler() { Free(); } + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidPosixAttrib + // kpidOffset +}; + +static const Byte kArcProps[] = +{ + kpidVolumeName, + kpidBigEndian, + kpidCharacts, + kpidClusterSize, + kpidMethod, + kpidHeadersSize, + kpidNumSubFiles, + kpidNumBlocks +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +HRESULT CHandler::OpenDir(int parent, UInt32 baseOffset, unsigned level) +{ + const Byte *p = _data + baseOffset; + bool be = _h.be; + if (!IsDir(p, be)) + return S_OK; + UInt32 offset = GetOffset(p, be); + UInt32 size = GetSize(p, be); + if (offset == 0 && size == 0) + return S_OK; + UInt32 end = offset + size; + if (offset < kHeaderSize || end > _size || level > kNumDirLevelsMax) + return S_FALSE; + UpdatePhySize(end); + if (end > _headersSize) + _headersSize = end; + + unsigned startIndex = _items.Size(); + + while (size != 0) + { + if (size < kNodeSize || (UInt32)_items.Size() >= kNumFilesMax) + return S_FALSE; + CItem item; + item.Parent = parent; + item.Offset = offset; + _items.Add(item); + UInt32 nodeLen = kNodeSize + GetNameLen(_data + offset, be); + if (size < nodeLen) + return S_FALSE; + offset += nodeLen; + size -= nodeLen; + } + + unsigned endIndex = _items.Size(); + for (unsigned i = startIndex; i < endIndex; i++) + { + RINOK(OpenDir((int)i, _items[i].Offset, level + 1)) + } + return S_OK; +} + +HRESULT CHandler::Open2(IInStream *inStream) +{ + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)) + if (!_h.Parse(buf)) + return S_FALSE; + _method = k_Flags_Method_ZLIB; + _blockSizeLog = kBlockSizeLog; + _phySize = kHeaderSize; + if (_h.IsVer2()) + { + _method = _h.GetMethod(); + // FIT IT. Now we don't know correct way to work with collision in method field. + if (_method == k_Flags_Method_NONE) + _method = k_Flags_Method_ZLIB; + _blockSizeLog = kBlockSizeLog + _h.GetBlockSizeShift(); + if (_h.Size < kHeaderSize || _h.Size > kArcSizeMax || _h.NumFiles > kNumFilesMax) + return S_FALSE; + _phySize = _h.Size; + } + else + { + UInt64 size; + RINOK(InStream_GetSize_SeekToEnd(inStream, size)) + if (size > kArcSizeMax) + size = kArcSizeMax; + _h.Size = (UInt32)size; + RINOK(InStream_SeekSet(inStream, kHeaderSize)) + } + _data = (Byte *)MidAlloc(_h.Size); + if (!_data) + return E_OUTOFMEMORY; + memcpy(_data, buf, kHeaderSize); + size_t processed = _h.Size - kHeaderSize; + RINOK(ReadStream(inStream, _data + kHeaderSize, &processed)) + if (processed < kNodeSize) + return S_FALSE; + _size = kHeaderSize + (UInt32)processed; + if (_h.IsVer2()) + { + if (_size != _h.Size) + _errorFlags = kpv_ErrorFlags_UnexpectedEnd; + else + { + SetUi32(_data + 0x20, 0) + if (CrcCalc(_data, _h.Size) != _h.Crc) + { + _errorFlags = kpv_ErrorFlags_HeadersError; + // _errorMessage = "CRC error"; + } + } + if (_h.NumFiles >= 1) + _items.ClearAndReserve(_h.NumFiles - 1); + } + + RINOK(OpenDir(-1, kHeaderSize, 0)) + + if (!_h.IsVer2()) + { + FOR_VECTOR (i, _items) + { + const CItem &item = _items[i]; + const Byte *p = _data + item.Offset; + bool be = _h.be; + if (IsDir(p, be)) + continue; + UInt32 offset = GetOffset(p, be); + if (offset < kHeaderSize) + continue; + UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); + if (numBlocks == 0) + continue; + UInt32 start = offset + numBlocks * 4; + if (start > _size) + continue; + UInt32 end = Get32(_data + start - 4); + if (end >= start) + UpdatePhySize(end); + } + + // Read tailing zeros. Most cramfs archives use 4096-bytes aligned zeros + const UInt32 kTailSize_MAX = 1 << 12; + UInt32 endPos = (_phySize + kTailSize_MAX - 1) & ~(kTailSize_MAX - 1); + if (endPos > _size) + endPos = _size; + UInt32 pos; + for (pos = _phySize; pos < endPos && _data[pos] == 0; pos++); + if (pos == endPos) + _phySize = endPos; + } + return S_OK; +} + +AString CHandler::GetPath(unsigned index) const +{ + unsigned len = 0; + unsigned indexMem = index; + for (;;) + { + const CItem &item = _items[index]; + const Byte *p = _data + item.Offset; + unsigned size = GetNameLen(p, _h.be); + p += kNodeSize; + unsigned i; + for (i = 0; i < size && p[i]; i++); + len += i + 1; + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; + } + len--; + + AString path; + char *dest = path.GetBuf_SetEnd(len) + len; + index = indexMem; + for (;;) + { + const CItem &item = _items[index]; + const Byte *p = _data + item.Offset; + unsigned size = GetNameLen(p, _h.be); + p += kNodeSize; + unsigned i; + for (i = 0; i < size && p[i]; i++); + dest -= i; + memcpy(dest, p, i); + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; + *(--dest) = CHAR_PATH_SEPARATOR; + } + return path; +} + +bool CHandler::GetPackSize(unsigned index, UInt32 &res) const +{ + res = 0; + const CItem &item = _items[index]; + const Byte *p = _data + item.Offset; + const bool be = _h.be; + const UInt32 offset = GetOffset(p, be); + if (offset < kHeaderSize) + return false; + const UInt32 numBlocks = GetNumBlocks(GetSize(p, be)); + if (numBlocks == 0) + return true; + const UInt32 start = offset + numBlocks * 4; + if (start > _size) + return false; + const UInt32 end = Get32(_data + start - 4); + if (end < start) + return false; + res = end - start; + return true; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)) +{ + COM_TRY_BEGIN + { + Close(); + RINOK(Open2(stream)) + _isArc = true; + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +void CHandler::Free() +{ + MidFree(_data); + _data = NULL; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _phySize = 0; + _errorFlags = 0; + _headersSize = 0; + _items.Clear(); + _stream.Release(); + Free(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidVolumeName: + { + char dest[kHeaderNameSize + 4]; + memcpy(dest, _h.Name, kHeaderNameSize); + dest[kHeaderNameSize] = 0; + prop = dest; + break; + } + case kpidBigEndian: prop = _h.be; break; + case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break; + case kpidMethod: prop = k_Methods[_method]; break; + case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; + case kpidNumBlocks: if (_h.IsVer2()) prop = _h.NumBlocks; break; + case kpidNumSubFiles: if (_h.IsVer2()) prop = _h.NumFiles; break; + case kpidPhySize: prop = _phySize; break; + case kpidHeadersSize: prop = _headersSize; break; + case kpidErrorFlags: + { + UInt32 v = _errorFlags; + if (!_isArc) + v |= kpv_ErrorFlags_IsNotArc; + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = _items[index]; + const Byte *p = _data + item.Offset; + bool be = _h.be; + bool isDir = IsDir(p, be); + switch (propID) + { + case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; + case kpidIsDir: prop = isDir; break; + // case kpidOffset: prop = (UInt32)GetOffset(p, be); break; + case kpidSize: if (!isDir) prop = GetSize(p, be); break; + case kpidPackSize: + if (!isDir) + { + UInt32 size; + if (GetPackSize(index, size)) + prop = size; + } + break; + case kpidPosixAttrib: prop = (UInt32)GetMode(p, be); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CCramfsInStream: public CCachedInStream +{ + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) Z7_override; +public: + CHandler *Handler; +}; + +HRESULT CCramfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) +{ + return Handler->ReadBlock(blockIndex, dest, blockSize); +} + +HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) +{ + if (_method == k_Flags_Method_ZLIB) + { + if (!_zlibDecoder) + { + _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); + _zlibDecoder = _zlibDecoderSpec; + } + } + else + { + if (_method != k_Flags_Method_LZMA) + { + // probably we must support no-compression archives here. + return E_NOTIMPL; + } + } + + const bool be = _h.be; + const Byte *p2 = _data + (_curBlocksOffset + (UInt32)blockIndex * 4); + const UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p2 - 4)); + const UInt32 end = Get32(p2); + if (end < start || end > _size) + return S_FALSE; + const UInt32 inSize = end - start; + + if (_method == k_Flags_Method_LZMA) + { + const unsigned kLzmaHeaderSize = LZMA_PROPS_SIZE + 4; + if (inSize < kLzmaHeaderSize) + return S_FALSE; + const Byte *p = _data + start; + UInt32 destSize32 = GetUi32(p + LZMA_PROPS_SIZE); + if (destSize32 > blockSize) + return S_FALSE; + SizeT destLen = destSize32; + SizeT srcLen = inSize - kLzmaHeaderSize; + ELzmaStatus status; + SRes res = LzmaDecode(dest, &destLen, p + kLzmaHeaderSize, &srcLen, + p, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &g_Alloc); + if (res != SZ_OK + || (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + || destLen != destSize32 + || srcLen != inSize - kLzmaHeaderSize) + return S_FALSE; + return S_OK; + } + + if (!_inStream) + { + _inStreamSpec = new CBufInStream(); + _inStream = _inStreamSpec; + } + if (!_outStream) + { + _outStreamSpec = new CBufPtrSeqOutStream(); + _outStream = _outStreamSpec; + } + _inStreamSpec->Init(_data + start, inSize); + _outStreamSpec->Init(dest, blockSize); + RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL)) + return (inSize == _zlibDecoderSpec->GetInputProcessedSize() && + _outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE; +} + +Z7_COM7F_IMF(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; + bool be = _h.be; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const Byte *p = _data + _items[allFilesMode ? i : indices[i]].Offset; + if (!IsDir(p, be)) + totalSize += GetSize(p, be); + } + extractCallback->SetTotal(totalSize); + + UInt64 totalPackSize; + totalSize = totalPackSize = 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 = totalPackSize; + 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]; + const CItem &item = _items[index]; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + const Byte *p = _data + item.Offset; + + if (IsDir(p, be)) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + UInt32 curSize = GetSize(p, be); + totalSize += curSize; + UInt32 packSize; + if (GetPackSize(index, packSize)) + totalPackSize += packSize; + + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + UInt32 offset = GetOffset(p, be); + if (offset < kHeaderSize) + curSize = 0; + + int res = NExtract::NOperationResult::kDataError; + { + CMyComPtr inSeqStream; + HRESULT hres = GetStream(index, &inSeqStream); + if (hres == E_OUTOFMEMORY) + return E_OUTOFMEMORY; + if (hres == S_FALSE || !inSeqStream) + res = NExtract::NOperationResult::kUnsupportedMethod; + else + { + RINOK(hres) + { + hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); + if (hres == S_OK) + { + if (copyCoderSpec->TotalSize == curSize) + res = NExtract::NOperationResult::kOK; + } + else if (hres == E_NOTIMPL) + res = NExtract::NOperationResult::kUnsupportedMethod; + else if (hres != S_FALSE) + return hres; + } + } + } + RINOK(extractCallback->SetOperationResult(res)) + } + + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + + const CItem &item = _items[index]; + const Byte *p = _data + item.Offset; + + bool be = _h.be; + if (IsDir(p, be)) + return E_FAIL; + + UInt32 size = GetSize(p, be); + UInt32 numBlocks = GetNumBlocks(size); + UInt32 offset = GetOffset(p, be); + if (offset < kHeaderSize) + { + if (offset != 0) + return S_FALSE; + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Init(NULL, 0); + *stream = streamTemp.Detach(); + return S_OK; + } + + if (offset + numBlocks * 4 > _size) + return S_FALSE; + UInt32 prev = offset; + for (UInt32 i = 0; i < numBlocks; i++) + { + UInt32 next = Get32(_data + offset + i * 4); + if (next < prev || next > _size) + return S_FALSE; + prev = next; + } + + CCramfsInStream *streamSpec = new CCramfsInStream; + CMyComPtr streamTemp = streamSpec; + _curNumBlocks = numBlocks; + _curBlocksOffset = offset; + streamSpec->Handler = this; + if (!streamSpec->Alloc(_blockSizeLog, 21 - _blockSizeLog)) + return E_OUTOFMEMORY; + streamSpec->Init(size); + *stream = streamTemp.Detach(); + + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "CramFS", "cramfs", NULL, 0xD3, + kSignature, + 16, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/DeflateProps.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/DeflateProps.cpp 2011-05-08 18:29:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.cpp 2011-01-27 10:53:18.000000000 +0000 @@ -1,3 +1,3 @@ -// DeflateProps.cpp - -#include "StdAfx.h" +// DeflateProps.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/DeflateProps.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.h --- p7zip-rar-16.02/CPP/7zip/Archive/DeflateProps.h 2011-05-08 18:29:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DeflateProps.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ -// DeflateProps.h - -#ifndef __DEFLATE_PROPS_H -#define __DEFLATE_PROPS_H - -#endif +// DeflateProps.h + +#ifndef ZIP7_INC_DEFLATE_PROPS_H +#define ZIP7_INC_DEFLATE_PROPS_H + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/DllExports.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/DllExports.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports.cpp 2023-06-15 04:00:00.000000000 +0000 @@ -0,0 +1,96 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#if defined(Z7_LARGE_PAGES) +#include "../../../C/Alloc.h" +#endif + +#include "../../Common/MyWindows.h" +#include "../../Common/MyInitGuid.h" + +#include "../../Common/ComTry.h" + +#include "../../Windows/NtCheck.h" +#include "../../Windows/PropVariant.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +#include "../Common/CreateCoder.h" + +#include "IArchive.h" + +static +HINSTANCE g_hInstance; + +#define NT_CHECK_FAIL_ACTION return FALSE; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/); +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + NT_CHECK + } + return TRUE; +} + +Z7_DEFINE_GUID(CLSID_CArchiveHandler, + k_7zip_GUID_Data1, + k_7zip_GUID_Data2, + k_7zip_GUID_Data3_Common, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); + +STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject); + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + return CreateArchiver(clsid, iid, outObject); +} + +STDAPI SetLargePageMode() +{ + #if defined(Z7_LARGE_PAGES) + SetLargePageSize(); + #endif + return S_OK; +} + +extern bool g_CaseSensitive; + +STDAPI SetCaseSensitive(Int32 caseSensitive) +{ + g_CaseSensitive = (caseSensitive != 0); + return S_OK; +} + +#ifdef Z7_EXTERNAL_CODECS + +CExternalCodecs g_ExternalCodecs; + +STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo) +{ + COM_TRY_BEGIN + + // OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL"); + if (compressCodecsInfo) + { + g_ExternalCodecs.GetCodecs = compressCodecsInfo; + return g_ExternalCodecs.Load(); + } + g_ExternalCodecs.ClearAndRelease(); + return S_OK; + + COM_TRY_END +} + +#else + +STDAPI SetCodecs(ICompressCodecsInfo *) +{ + return S_OK; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/DllExports2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports2.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/DllExports2.cpp 2015-10-03 09:30:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DllExports2.cpp 2023-03-23 18:00:00.000000000 +0000 @@ -1,122 +1,175 @@ -// DLLExports2.cpp - -#include "StdAfx.h" - -#include "../../Common/MyWindows.h" - -#include "../../Common/MyInitGuid.h" - -#if defined(_7ZIP_LARGE_PAGES) -#include "../../../C/Alloc.h" -#endif - -#include "../../Common/ComTry.h" - -#include "../../Windows/NtCheck.h" -#include "../../Windows/PropVariant.h" - -#include "../ICoder.h" -#include "../IPassword.h" - -#include "../Common/CreateCoder.h" - -#include "IArchive.h" - -HINSTANCE g_hInstance; - -#define NT_CHECK_FAIL_ACTION return FALSE; - -#ifdef _WIN32 -extern "C" -BOOL WINAPI DllMain( - #ifdef UNDER_CE - HANDLE - #else - HINSTANCE - #endif - hInstance, DWORD dwReason, LPVOID /*lpReserved*/) -{ - if (dwReason == DLL_PROCESS_ATTACH) - { - // OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH"); - g_hInstance = (HINSTANCE)hInstance; - NT_CHECK; - } - /* - if (dwReason == DLL_PROCESS_DETACH) - { - OutputDebugStringA("7z.dll DLL_PROCESS_DETACH"); - } - */ - return TRUE; -} -#endif - -DEFINE_GUID(CLSID_CArchiveHandler, - k_7zip_GUID_Data1, - k_7zip_GUID_Data2, - k_7zip_GUID_Data3_Common, - 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); - -STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); -STDAPI CreateHasher(const GUID *clsid, IHasher **hasher); -STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); - -STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) -{ - // COM_TRY_BEGIN - *outObject = 0; - if (*iid == IID_ICompressCoder || - *iid == IID_ICompressCoder2 || - *iid == IID_ICompressFilter) - return CreateCoder(clsid, iid, outObject); - if (*iid == IID_IHasher) - return CreateHasher(clsid, (IHasher **)outObject); - return CreateArchiver(clsid, iid, outObject); - // COM_TRY_END -} - -STDAPI SetLargePageMode() -{ - #if defined(_7ZIP_LARGE_PAGES) - SetLargePageSize(); - #endif - return S_OK; -} - -extern bool g_CaseSensitive; - -STDAPI SetCaseSensitive(Int32 caseSensitive) -{ - g_CaseSensitive = (caseSensitive != 0); - return S_OK; -} - -#ifdef EXTERNAL_CODECS - -CExternalCodecs g_ExternalCodecs; - -STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo) -{ - COM_TRY_BEGIN - - // OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL"); - if (compressCodecsInfo) - { - g_ExternalCodecs.GetCodecs = compressCodecsInfo; - return g_ExternalCodecs.Load(); - } - g_ExternalCodecs.ClearAndRelease(); - return S_OK; - - COM_TRY_END -} - -#else - -STDAPI SetCodecs(ICompressCodecsInfo *) -{ - return S_OK; -} - -#endif +// DLLExports2.cpp + +#include "StdAfx.h" + +#include "../../Common/MyWindows.h" +#include "../../Common/MyInitGuid.h" + +#if defined(Z7_LARGE_PAGES) +#include "../../../C/Alloc.h" +#endif + +#include "../../Common/ComTry.h" + +#include "../../Windows/NtCheck.h" +#include "../../Windows/PropVariant.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +#include "../Common/CreateCoder.h" + +#include "IArchive.h" + + +#ifdef _WIN32 + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION return FALSE; +#endif + +static +HINSTANCE g_hInstance; + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID /*lpReserved*/); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + // OutputDebugStringA("7z.dll DLL_PROCESS_ATTACH"); + g_hInstance = (HINSTANCE)hInstance; + NT_CHECK + } + /* + if (dwReason == DLL_PROCESS_DETACH) + { + OutputDebugStringA("7z.dll DLL_PROCESS_DETACH"); + } + */ + return TRUE; +} + +#else // _WIN32 + +#include "../../Common/StringConvert.h" +// #include + +// STDAPI LibStartup(); +static __attribute__((constructor)) void Init_ForceToUTF8(); +static __attribute__((constructor)) void Init_ForceToUTF8() +{ + g_ForceToUTF8 = IsNativeUTF8(); + // printf("\nDLLExports2.cpp::Init_ForceToUTF8 =%d\n", g_ForceToUTF8 ? 1 : 0); +} + +#endif // _WIN32 + + +Z7_DEFINE_GUID(CLSID_CArchiveHandler, + k_7zip_GUID_Data1, + k_7zip_GUID_Data2, + k_7zip_GUID_Data3_Common, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00); + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateHasher(const GUID *clsid, IHasher **hasher); +STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject); + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + // COM_TRY_BEGIN + *outObject = NULL; + if (*iid == IID_ICompressCoder || + *iid == IID_ICompressCoder2 || + *iid == IID_ICompressFilter) + return CreateCoder(clsid, iid, outObject); + if (*iid == IID_IHasher) + return CreateHasher(clsid, (IHasher **)outObject); + return CreateArchiver(clsid, iid, outObject); + // COM_TRY_END +} + +STDAPI SetLargePageMode(); +STDAPI SetLargePageMode() +{ + #if defined(Z7_LARGE_PAGES) + #ifdef _WIN32 + SetLargePageSize(); + #endif + #endif + return S_OK; +} + +extern bool g_CaseSensitive; + +STDAPI SetCaseSensitive(Int32 caseSensitive); +STDAPI SetCaseSensitive(Int32 caseSensitive) +{ + g_CaseSensitive = (caseSensitive != 0); + return S_OK; +} + +/* +UInt32 g_ClientVersion; +STDAPI SetClientVersion(UInt32 version); +STDAPI SetClientVersion(UInt32 version) +{ + g_ClientVersion = version; + return S_OK; +} +*/ + +/* +STDAPI SetProperty(Int32 id, const PROPVARIANT *value); +STDAPI SetProperty(Int32 id, const PROPVARIANT *value) +{ + return S_OK; +} +*/ + +#ifdef Z7_EXTERNAL_CODECS + +CExternalCodecs g_ExternalCodecs; + +STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo); +STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo) +{ + COM_TRY_BEGIN + + // OutputDebugStringA(compressCodecsInfo ? "SetCodecs" : "SetCodecs NULL"); + if (compressCodecsInfo) + { + g_ExternalCodecs.GetCodecs = compressCodecsInfo; + return g_ExternalCodecs.Load(); + } + g_ExternalCodecs.ClearAndRelease(); + return S_OK; + + COM_TRY_END +} + +#else + +STDAPI SetCodecs(ICompressCodecsInfo *); +STDAPI SetCodecs(ICompressCodecsInfo *) +{ + return S_OK; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/DmgHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DmgHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/DmgHandler.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/DmgHandler.cpp 2025-06-16 09:00:00.000000000 +0000 @@ -1,1586 +1,2336 @@ -// DmgHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyXml.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/BZip2Decoder.h" -#include "../Compress/CopyCoder.h" -#include "../Compress/ZlibDecoder.h" - -#include "Common/OutStreamWithCRC.h" - -// #define DMG_SHOW_RAW - -// #include -#define PRF(x) // x - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -static const Byte k_Base64Table[256] = -{ - 66,77,77,77,77,77,77,77,77,65,65,77,77,65,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63, - 52,53,54,55,56,57,58,59,60,61,77,77,77,64,77,77, - 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77, - 77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, - 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77 -}; - -static Byte *Base64ToBin(Byte *dest, const char *src) -{ - UInt32 val = 1; - - for (;;) - { - UInt32 c = k_Base64Table[(Byte)(*src++)]; - - if (c < 64) - { - val = (val << 6) | c; - if ((val & ((UInt32)1 << 24)) == 0) - continue; - dest[0] = (Byte)(val >> 16); - dest[1] = (Byte)(val >> 8); - dest[2] = (Byte)(val); - dest += 3; - val = 1; - continue; - } - - if (c == 65) // space - continue; - - if (c == 64) // '=' - break; - - if (c == 66 && val == 1) // end of string - return dest; - - return NULL; - } - - if (val < (1 << 12)) - return NULL; - - if (val & (1 << 18)) - { - *dest++ = (Byte)(val >> 10); - *dest++ = (Byte)(val >> 2); - } - else if (k_Base64Table[(Byte)(*src++)] != 64) // '=' - return NULL; - else - *dest++ = (Byte)(val >> 4); - - for (;;) - { - Byte c = k_Base64Table[(Byte)(*src++)]; - if (c == 65) // space - continue; - if (c == 66) // end of string - return dest; - return NULL; - } -} - - -namespace NArchive { -namespace NDmg { - -enum -{ - METHOD_ZERO_0 = 0, - METHOD_COPY = 1, - METHOD_ZERO_2 = 2, // without file CRC calculation - METHOD_ADC = 0x80000004, - METHOD_ZLIB = 0x80000005, - METHOD_BZIP2 = 0x80000006, - METHOD_COMMENT = 0x7FFFFFFE, // is used to comment "+beg" and "+end" in extra field. - METHOD_END = 0xFFFFFFFF -}; - -struct CBlock -{ - UInt32 Type; - UInt64 UnpPos; - UInt64 UnpSize; - UInt64 PackPos; - UInt64 PackSize; - - UInt64 GetNextPackOffset() const { return PackPos + PackSize; } - UInt64 GetNextUnpPos() const { return UnpPos + UnpSize; } - - bool IsZeroMethod() const { return Type == METHOD_ZERO_0 || Type == METHOD_ZERO_2; } - bool ThereAreDataInBlock() const { return Type != METHOD_COMMENT && Type != METHOD_END; } -}; - -static const UInt32 kCheckSumType_CRC = 2; - -static const size_t kChecksumSize_Max = 0x80; - -struct CChecksum -{ - UInt32 Type; - UInt32 NumBits; - Byte Data[kChecksumSize_Max]; - - bool IsCrc32() const { return Type == kCheckSumType_CRC && NumBits == 32; } - UInt32 GetCrc32() const { return Get32(Data); } - void Parse(const Byte *p); -}; - -void CChecksum::Parse(const Byte *p) -{ - Type = Get32(p); - NumBits = Get32(p + 4); - memcpy(Data, p + 8, kChecksumSize_Max); -}; - -struct CFile -{ - UInt64 Size; - UInt64 PackSize; - UInt64 StartPos; - AString Name; - CRecordVector Blocks; - CChecksum Checksum; - bool FullFileChecksum; - - HRESULT Parse(const Byte *p, UInt32 size); -}; - -#ifdef DMG_SHOW_RAW -struct CExtraFile -{ - CByteBuffer Data; - AString Name; -}; -#endif - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr _inStream; - CObjectVector _files; - bool _masterCrcError; - - UInt64 _startPos; - UInt64 _phySize; - - #ifdef DMG_SHOW_RAW - CObjectVector _extras; - #endif - - HRESULT Open2(IInStream *stream); - HRESULT Extract(IInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -// that limit can be increased, if there are such dmg files -static const size_t kXmlSizeMax = 0xFFFF0000; // 4 GB - 64 KB; - -struct CMethods -{ - CRecordVector Types; - CRecordVector ChecksumTypes; - - void Update(const CFile &file); - void GetString(AString &s) const; -}; - -void CMethods::Update(const CFile &file) -{ - ChecksumTypes.AddToUniqueSorted(file.Checksum.Type); - FOR_VECTOR (i, file.Blocks) - Types.AddToUniqueSorted(file.Blocks[i].Type); -} - -void CMethods::GetString(AString &res) const -{ - res.Empty(); - - unsigned i; - - for (i = 0; i < Types.Size(); i++) - { - UInt32 type = Types[i]; - if (type == METHOD_COMMENT || type == METHOD_END) - continue; - char buf[16]; - const char *s; - switch (type) - { - case METHOD_ZERO_0: s = "Zero0"; break; - case METHOD_ZERO_2: s = "Zero2"; break; - case METHOD_COPY: s = "Copy"; break; - case METHOD_ADC: s = "ADC"; break; - case METHOD_ZLIB: s = "ZLIB"; break; - case METHOD_BZIP2: s = "BZip2"; break; - default: ConvertUInt32ToString(type, buf); s = buf; - } - res.Add_Space_if_NotEmpty(); - res += s; - } - - for (i = 0; i < ChecksumTypes.Size(); i++) - { - UInt32 type = ChecksumTypes[i]; - char buf[32]; - const char *s; - switch (type) - { - case kCheckSumType_CRC: s = "CRC"; break; - default: - ConvertUInt32ToString(type, MyStpCpy(buf, "Check")); - s = buf; - } - res.Add_Space_if_NotEmpty(); - res += s; - } -} - -struct CAppleName -{ - bool IsFs; - const char *Ext; - const char *AppleName; -}; - -static const CAppleName k_Names[] = -{ - { true, "hfs", "Apple_HFS" }, - { true, "hfsx", "Apple_HFSX" }, - { true, "ufs", "Apple_UFS" }, - { false, "free", "Apple_Free" }, - { false, "ddm", "DDM" }, - { false, NULL, "Apple_partition_map" }, - { false, NULL, " GPT " }, - { false, NULL, "MBR" }, - { false, NULL, "Driver" }, - { false, NULL, "Patches" } -}; - -static const unsigned kNumAppleNames = ARRAY_SIZE(k_Names); - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidCRC, - kpidComment, - kpidMethod -}; - -IMP_IInArchive_Props - -static const Byte kArcProps[] = -{ - kpidMethod, - kpidNumBlocks -}; - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidMethod: - { - CMethods m; - FOR_VECTOR (i, _files) - m.Update(_files[i]); - AString s; - m.GetString(s); - if (!s.IsEmpty()) - prop = s; - break; - } - case kpidNumBlocks: - { - UInt64 numBlocks = 0; - FOR_VECTOR (i, _files) - numBlocks += _files[i].Blocks.Size(); - prop = numBlocks; - break; - } - case kpidMainSubfile: - { - int mainIndex = -1; - unsigned numFS = 0; - unsigned numUnknown = 0; - FOR_VECTOR (i, _files) - { - const AString &name = _files[i].Name; - unsigned n; - for (n = 0; n < kNumAppleNames; n++) - { - const CAppleName &appleName = k_Names[n]; - // if (name.Find(appleName.AppleName) >= 0) - if (strstr(name, appleName.AppleName)) - { - if (appleName.IsFs) - { - numFS++; - mainIndex = i; - } - break; - } - } - if (n == kNumAppleNames) - { - mainIndex = i; - numUnknown++; - } - } - if (numFS + numUnknown == 1) - prop = (UInt32)mainIndex; - break; - } - case kpidWarning: - if (_masterCrcError) - prop = "Master CRC error"; - break; - case kpidOffset: prop = _startPos; break; - case kpidPhySize: prop = _phySize; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -IMP_IInArchive_ArcProps - -HRESULT CFile::Parse(const Byte *p, UInt32 size) -{ - const UInt32 kHeadSize = 0xCC; - if (size < kHeadSize) - return S_FALSE; - if (Get32(p) != 0x6D697368) // "mish" signature - return S_FALSE; - if (Get32(p + 4) != 1) // version - return S_FALSE; - // UInt64 firstSectorNumber = Get64(p + 8); - UInt64 numSectors = Get64(p + 0x10); - - StartPos = Get64(p + 0x18); - - // UInt32 decompressedBufRequested = Get32(p + 0x20); // ??? - // UInt32 blocksDescriptor = Get32(p + 0x24); // number starting from -1? - // char Reserved1[24]; - - Checksum.Parse(p + 0x40); - PRF(printf("\n\nChecksum Type = %2d", Checksum.Type)); - - UInt32 numBlocks = Get32(p + 0xC8); - if (numBlocks > ((UInt32)1 << 28)) - return S_FALSE; - - const UInt32 kRecordSize = 40; - if (numBlocks * kRecordSize + kHeadSize != size) - return S_FALSE; - - PackSize = 0; - Size = 0; - Blocks.ClearAndReserve(numBlocks); - FullFileChecksum = true; - - p += kHeadSize; - UInt32 i; - - for (i = 0; i < numBlocks; i++, p += kRecordSize) - { - CBlock b; - b.Type = Get32(p); - b.UnpPos = Get64(p + 0x08) << 9; - b.UnpSize = Get64(p + 0x10) << 9; - b.PackPos = Get64(p + 0x18); - b.PackSize = Get64(p + 0x20); - - // b.PackPos can be 0 for some types. So we don't check it - if (!Blocks.IsEmpty()) - if (b.UnpPos != Blocks.Back().GetNextUnpPos()) - return S_FALSE; - - PRF(printf("\nType=%8x m[1]=%8x uPos=%8x uSize=%7x pPos=%8x pSize=%7x", - b.Type, Get32(p + 4), (UInt32)b.UnpPos, (UInt32)b.UnpSize, (UInt32)b.PackPos, (UInt32)b.PackSize)); - - if (b.Type == METHOD_COMMENT) - continue; - if (b.Type == METHOD_END) - break; - PackSize += b.PackSize; - - if (b.UnpSize != 0) - { - if (b.Type == METHOD_ZERO_2) - FullFileChecksum = false; - Blocks.AddInReserved(b); - } - } - - if (i != numBlocks - 1) - return S_FALSE; - if (!Blocks.IsEmpty()) - Size = Blocks.Back().GetNextUnpPos(); - if (Size != (numSectors << 9)) - return S_FALSE; - - return S_OK; -} - -static int FindKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag) -{ - for (unsigned i = 0; i + 1 < item.SubItems.Size(); i++) - { - const CXmlItem &si = item.SubItems[i]; - if (si.IsTagged("key") && si.GetSubString() == key && item.SubItems[i + 1].IsTagged(nextTag)) - return i + 1; - } - return -1; -} - -static const AString *GetStringFromKeyPair(const CXmlItem &item, const AString &key, const AString &nextTag) -{ - int index = FindKeyPair(item, key, nextTag); - if (index >= 0) - return item.SubItems[index].GetSubStringPtr(); - return NULL; -} - -static const unsigned HEADER_SIZE = 0x200; - -static const Byte k_Signature[] = { 'k','o','l','y', 0, 0, 0, 4, 0, 0, 2, 0 }; - -static inline bool IsKoly(const Byte *p) -{ - return memcmp(p, k_Signature, ARRAY_SIZE(k_Signature)) == 0; - /* - if (Get32(p) != 0x6B6F6C79) // "koly" signature - return false; - if (Get32(p + 4) != 4) // version - return false; - if (Get32(p + 8) != HEADER_SIZE) - return false; - return true; - */ -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); - - Byte buf[HEADER_SIZE]; - RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); - - UInt64 headerPos; - if (IsKoly(buf)) - headerPos = _startPos; - else - { - RINOK(stream->Seek(0, STREAM_SEEK_END, &headerPos)); - if (headerPos < HEADER_SIZE) - return S_FALSE; - headerPos -= HEADER_SIZE; - RINOK(stream->Seek(headerPos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)); - if (!IsKoly(buf)) - return S_FALSE; - } - - // UInt32 flags = Get32(buf + 12); - // UInt64 runningDataForkOffset = Get64(buf + 0x10); - UInt64 dataForkOffset = Get64(buf + 0x18); - UInt64 dataForkLen = Get64(buf + 0x20); - UInt64 rsrcOffset = Get64(buf + 0x28); - UInt64 rsrcLen = Get64(buf + 0x30); - // UInt32 segmentNumber = Get32(buf + 0x38); - // UInt32 segmentCount = Get32(buf + 0x3C); - // Byte segmentGUID[16]; - // CChecksum dataForkChecksum; - // dataForkChecksum.Parse(buf + 0x50); - UInt64 xmlOffset = Get64(buf + 0xD8); - UInt64 xmlLen = Get64(buf + 0xE0); - - if ( headerPos < dataForkOffset - || headerPos - dataForkOffset < dataForkLen - || headerPos < rsrcOffset - || headerPos - rsrcOffset < rsrcLen - || headerPos < xmlOffset - || headerPos - xmlOffset < xmlLen) - return S_FALSE; - - UInt64 totalLen = dataForkLen + rsrcLen + xmlLen; - if (totalLen > headerPos) - return S_FALSE; - _startPos = headerPos - totalLen; - _phySize = totalLen + HEADER_SIZE; - headerPos = totalLen; - - // Byte reserved[0x78] - - CChecksum masterChecksum; - masterChecksum.Parse(buf + 0x160); - - // UInt32 imageVariant = Get32(buf + 0x1E8); - // UInt64 numSectors = Get64(buf + 0x1EC); - // Byte reserved[0x12] - - const UInt32 RSRC_HEAD_SIZE = 0x100; - - // We don't know the size of the field "offset" in rsrc. - // We suppose that it uses 24 bits. So we use Rsrc, only if the rsrcLen < (1 << 24). - bool useRsrc = (rsrcLen > RSRC_HEAD_SIZE && rsrcLen < ((UInt32)1 << 24)); - // useRsrc = false; - - if (useRsrc) - { - #ifdef DMG_SHOW_RAW - CExtraFile &extra = _extras.AddNew(); - extra.Name = "rsrc.bin"; - CByteBuffer &rsrcBuf = extra.Data; - #else - CByteBuffer rsrcBuf; - #endif - - size_t rsrcLenT = (size_t)rsrcLen; - rsrcBuf.Alloc(rsrcLenT); - RINOK(stream->Seek(_startPos + rsrcOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, rsrcBuf, rsrcLenT)); - - const Byte *p = rsrcBuf; - UInt32 headSize = Get32(p + 0); - UInt32 footerOffset = Get32(p + 4); - UInt32 mainDataSize = Get32(p + 8); - UInt32 footerSize = Get32(p + 12); - if (headSize != RSRC_HEAD_SIZE || - footerOffset >= rsrcLenT || - mainDataSize >= rsrcLenT || - footerOffset + footerSize != rsrcLenT || - footerOffset != headSize + mainDataSize) - return S_FALSE; - if (footerSize < 16) - return S_FALSE; - if (memcmp(p, p + footerOffset, 16) != 0) - return S_FALSE; - - p += footerOffset; - - if ((UInt32)Get16(p + 0x18) != 0x1C) - return S_FALSE; - UInt32 namesOffset = Get16(p + 0x1A); - if (namesOffset > footerSize) - return S_FALSE; - - UInt32 numItems = (UInt32)Get16(p + 0x1C) + 1; - if (numItems * 8 + 0x1E > namesOffset) - return S_FALSE; - - for (UInt32 i = 0; i < numItems; i++) - { - const Byte *p2 = p + 0x1E + i * 8; - - UInt32 typeId = Get32(p2); - if (typeId != 0x626C6B78) // blkx - continue; - - UInt32 numFiles = (UInt32)Get16(p2 + 4) + 1; - UInt32 offs = Get16(p2 + 6); - if (0x1C + offs + 12 * numFiles > namesOffset) - return S_FALSE; - - for (UInt32 k = 0; k < numFiles; k++) - { - const Byte *p3 = p + 0x1C + offs + k * 12; - // UInt32 id = Get16(p3); - UInt32 namePos = Get16(p3 + 2); - // Byte attributes = p3[4]; // = 0x50 for blkx - // we don't know how many bits we can use. So we use 24 bits only - UInt32 blockOffset = Get32(p3 + 4); - blockOffset &= (((UInt32)1 << 24) - 1); - // UInt32 unknown2 = Get32(p3 + 8); // ??? - if (blockOffset + 4 >= mainDataSize) - return S_FALSE; - const Byte *pBlock = rsrcBuf + headSize + blockOffset; - UInt32 blockSize = Get32(pBlock); - - #ifdef DMG_SHOW_RAW - { - CExtraFile &extra = _extras.AddNew(); - { - char extraName[16]; - ConvertUInt32ToString(_files.Size(), extraName); - extra.Name = extraName; - } - extra.Data.CopyFrom(pBlock + 4, blockSize); - } - #endif - - CFile &file = _files.AddNew(); - if (namePos != 0xFFFF) - { - UInt32 namesBlockSize = footerSize - namesOffset; - if (namePos >= namesBlockSize) - return S_FALSE; - const Byte *namePtr = p + namesOffset + namePos; - UInt32 nameLen = *namePtr; - if (namesBlockSize - namePos <= nameLen) - return S_FALSE; - for (UInt32 r = 1; r <= nameLen; r++) - { - Byte c = namePtr[r]; - if (c < 0x20 || c >= 0x80) - break; - file.Name += (char)c; - } - } - RINOK(file.Parse(pBlock + 4, blockSize)); - } - } - } - else - { - if (xmlLen >= kXmlSizeMax || xmlLen == 0) - return S_FALSE; - size_t size = (size_t)xmlLen; - if (size != xmlLen) - return S_FALSE; - - RINOK(stream->Seek(_startPos + dataForkLen, STREAM_SEEK_SET, NULL)); - - CXml xml; - { - CObjArray xmlStr(size + 1); - RINOK(ReadStream_FALSE(stream, xmlStr, size)); - xmlStr[size] = 0; - // if (strlen(xmlStr) != size) return S_FALSE; - if (!xml.Parse(xmlStr)) - return S_FALSE; - - #ifdef DMG_SHOW_RAW - CExtraFile &extra = _extras.AddNew(); - extra.Name = "a.xml"; - extra.Data.CopyFrom((const Byte *)(const char *)xmlStr, size); - #endif - } - - if (xml.Root.Name != "plist") - return S_FALSE; - - int dictIndex = xml.Root.FindSubTag("dict"); - if (dictIndex < 0) - return S_FALSE; - - const CXmlItem &dictItem = xml.Root.SubItems[dictIndex]; - int rfDictIndex = FindKeyPair(dictItem, "resource-fork", "dict"); - if (rfDictIndex < 0) - return S_FALSE; - - const CXmlItem &rfDictItem = dictItem.SubItems[rfDictIndex]; - int arrIndex = FindKeyPair(rfDictItem, "blkx", "array"); - if (arrIndex < 0) - return S_FALSE; - - const CXmlItem &arrItem = rfDictItem.SubItems[arrIndex]; - - FOR_VECTOR (i, arrItem.SubItems) - { - const CXmlItem &item = arrItem.SubItems[i]; - if (!item.IsTagged("dict")) - continue; - - CByteBuffer rawBuf; - unsigned destLen = 0; - { - const AString *dataString = GetStringFromKeyPair(item, "Data", "data"); - if (!dataString) - return S_FALSE; - destLen = dataString->Len() / 4 * 3 + 4; - rawBuf.Alloc(destLen); - { - const Byte *endPtr = Base64ToBin(rawBuf, *dataString); - if (!endPtr) - return S_FALSE; - destLen = (unsigned)(endPtr - rawBuf); - } - - #ifdef DMG_SHOW_RAW - CExtraFile &extra = _extras.AddNew(); - { - char extraName[16]; - ConvertUInt32ToString(_files.Size(), extraName); - extra.Name = extraName; - } - extra.Data.CopyFrom(rawBuf, destLen); - #endif - } - CFile &file = _files.AddNew(); - { - const AString *name = GetStringFromKeyPair(item, "Name", "string"); - if (!name || name->IsEmpty()) - name = GetStringFromKeyPair(item, "CFName", "string"); - if (name) - file.Name = *name; - } - RINOK(file.Parse(rawBuf, destLen)); - } - } - - if (masterChecksum.IsCrc32()) - { - UInt32 crc = CRC_INIT_VAL; - unsigned i; - for (i = 0; i < _files.Size(); i++) - { - const CChecksum &cs = _files[i].Checksum; - if ((cs.NumBits & 0x7) != 0) - break; - UInt32 len = cs.NumBits >> 3; - if (len > kChecksumSize_Max) - break; - crc = CrcUpdate(crc, cs.Data, (size_t)len); - } - if (i == _files.Size()) - _masterCrcError = (CRC_GET_DIGEST(crc) != masterChecksum.GetCrc32()); - } - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - { - Close(); - if (Open2(stream) != S_OK) - return S_FALSE; - _inStream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - _inStream.Release(); - _files.Clear(); - _masterCrcError = false; - #ifdef DMG_SHOW_RAW - _extras.Clear(); - #endif - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _files.Size() - #ifdef DMG_SHOW_RAW - + _extras.Size() - #endif - ; - return S_OK; -} - -#define RAW_PREFIX "raw" STRING_PATH_SEPARATOR - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - - #ifdef DMG_SHOW_RAW - if (index >= _files.Size()) - { - const CExtraFile &extra = _extras[index - _files.Size()]; - switch (propID) - { - case kpidPath: - prop = (AString)RAW_PREFIX + extra.Name; - break; - case kpidSize: - case kpidPackSize: - prop = (UInt64)extra.Data.Size(); - break; - } - } - else - #endif - { - const CFile &item = _files[index]; - switch (propID) - { - case kpidSize: prop = item.Size; break; - case kpidPackSize: prop = item.PackSize; break; - case kpidCRC: - { - if (item.Checksum.IsCrc32() && item.FullFileChecksum) - prop = item.Checksum.GetCrc32(); - break; - } - - case kpidMethod: - { - CMethods m; - m.Update(item); - AString s; - m.GetString(s); - if (!s.IsEmpty()) - prop = s; - break; - } - - case kpidPath: - { - UString name; - wchar_t s[16]; - ConvertUInt32ToString(index, s); - name = s; - unsigned num = 10; - unsigned numDigits; - for (numDigits = 1; num < _files.Size(); numDigits++) - num *= 10; - while (name.Len() < numDigits) - name.InsertAtFront(L'0'); - - AString subName; - int pos1 = item.Name.Find('('); - if (pos1 >= 0) - { - pos1++; - int pos2 = item.Name.Find(')', pos1); - if (pos2 >= 0) - { - subName.SetFrom(item.Name.Ptr(pos1), pos2 - pos1); - pos1 = subName.Find(':'); - if (pos1 >= 0) - subName.DeleteFrom(pos1); - } - } - subName.Trim(); - if (!subName.IsEmpty()) - { - for (unsigned n = 0; n < kNumAppleNames; n++) - { - const CAppleName &appleName = k_Names[n]; - if (appleName.Ext) - { - if (subName == appleName.AppleName) - { - subName = appleName.Ext; - break; - } - } - } - UString name2; - ConvertUTF8ToUnicode(subName, name2); - name += L'.'; - name += name2; - } - else - { - UString name2; - ConvertUTF8ToUnicode(item.Name, name2); - if (!name2.IsEmpty()) - name.AddAscii(" - "); - name += name2; - } - prop = name; - break; - } - - case kpidComment: - { - UString name; - ConvertUTF8ToUnicode(item.Name, name); - prop = name; - break; - } - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CAdcDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - CInBuffer m_InStream; - - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InStream.ReleaseStream(); - } - */ - - class CCoderReleaser - { - CAdcDecoder *m_Coder; - public: - bool NeedFlush; - CCoderReleaser(CAdcDecoder *coder): m_Coder(coder), NeedFlush(true) {} - ~CCoderReleaser() - { - if (NeedFlush) - m_Coder->m_OutWindowStream.Flush(); - // m_Coder->ReleaseStreams(); - } - }; - friend class CCoderReleaser; - -public: - MY_UNKNOWN_IMP - - STDMETHOD(CodeReal)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); -}; - -STDMETHODIMP CAdcDecoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (!m_OutWindowStream.Create(1 << 18)) - return E_OUTOFMEMORY; - if (!m_InStream.Create(1 << 18)) - return E_OUTOFMEMORY; - - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InStream.SetStream(inStream); - m_InStream.Init(); - - CCoderReleaser coderReleaser(this); - - const UInt32 kStep = (1 << 20); - UInt64 nextLimit = kStep; - - UInt64 pos = 0; - while (pos < *outSize) - { - if (pos > nextLimit && progress) - { - UInt64 packSize = m_InStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - nextLimit += kStep; - } - Byte b; - if (!m_InStream.ReadByte(b)) - return S_FALSE; - UInt64 rem = *outSize - pos; - if (b & 0x80) - { - unsigned num = (b & 0x7F) + 1; - if (num > rem) - return S_FALSE; - for (unsigned i = 0; i < num; i++) - { - if (!m_InStream.ReadByte(b)) - return S_FALSE; - m_OutWindowStream.PutByte(b); - } - pos += num; - continue; - } - Byte b1; - if (!m_InStream.ReadByte(b1)) - return S_FALSE; - - UInt32 len, distance; - - if (b & 0x40) - { - len = ((UInt32)b & 0x3F) + 4; - Byte b2; - if (!m_InStream.ReadByte(b2)) - return S_FALSE; - distance = ((UInt32)b1 << 8) + b2; - } - else - { - b &= 0x3F; - len = ((UInt32)b >> 2) + 3; - distance = (((UInt32)b & 3) << 8) + b1; - } - - if (distance >= pos || len > rem) - return S_FALSE; - m_OutWindowStream.CopyBlock(distance, len); - pos += len; - } - if (*inSize != m_InStream.GetProcessedSize()) - return S_FALSE; - coderReleaser.NeedFlush = false; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CAdcDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress);} - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _files.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - - for (i = 0; i < numItems; i++) - { - UInt32 index = (allFilesMode ? i : indices[i]); - #ifdef DMG_SHOW_RAW - if (index >= _files.Size()) - totalSize += _extras[index - _files.Size()].Data.Size(); - else - #endif - totalSize += _files[index].Size; - } - extractCallback->SetTotal(totalSize); - - UInt64 currentPackTotal = 0; - UInt64 currentUnpTotal = 0; - UInt64 currentPackSize = 0; - UInt64 currentUnpSize = 0; - - const UInt32 kZeroBufSize = (1 << 14); - CByteBuffer zeroBuf(kZeroBufSize); - memset(zeroBuf, 0, kZeroBufSize); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - CMyComPtr bzip2Coder = bzip2CoderSpec; - - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - CAdcDecoder *adcCoderSpec = new CAdcDecoder(); - CMyComPtr adcCoder = adcCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) - { - lps->InSize = currentPackTotal; - lps->OutSize = currentUnpTotal; - currentPackSize = 0; - currentUnpSize = 0; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - - COutStreamWithCRC *outCrcStreamSpec = new COutStreamWithCRC; - CMyComPtr outCrcStream = outCrcStreamSpec; - outCrcStreamSpec->SetStream(realOutStream); - bool needCrc = false; - outCrcStreamSpec->Init(needCrc); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(outCrcStream); - - realOutStream.Release(); - - Int32 opRes = NExtract::NOperationResult::kOK; - #ifdef DMG_SHOW_RAW - if (index >= _files.Size()) - { - const CByteBuffer &buf = _extras[index - _files.Size()].Data; - outStreamSpec->Init(buf.Size()); - RINOK(WriteStream(outStream, buf, buf.Size())); - currentPackSize = currentUnpSize = buf.Size(); - } - else - #endif - { - const CFile &item = _files[index]; - currentPackSize = item.PackSize; - currentUnpSize = item.Size; - - needCrc = item.Checksum.IsCrc32(); - - UInt64 unpPos = 0; - UInt64 packPos = 0; - { - FOR_VECTOR (j, item.Blocks) - { - lps->InSize = currentPackTotal + packPos; - lps->OutSize = currentUnpTotal + unpPos; - RINOK(lps->SetCur()); - - const CBlock &block = item.Blocks[j]; - if (!block.ThereAreDataInBlock()) - continue; - - packPos += block.PackSize; - if (block.UnpPos != unpPos) - { - opRes = NExtract::NOperationResult::kDataError; - break; - } - - RINOK(_inStream->Seek(_startPos + item.StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); - streamSpec->Init(block.PackSize); - bool realMethod = true; - outStreamSpec->Init(block.UnpSize); - HRESULT res = S_OK; - - outCrcStreamSpec->EnableCalc(needCrc); - - switch (block.Type) - { - case METHOD_ZERO_0: - case METHOD_ZERO_2: - realMethod = false; - if (block.PackSize != 0) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - outCrcStreamSpec->EnableCalc(block.Type == METHOD_ZERO_0); - break; - - case METHOD_COPY: - if (block.UnpSize != block.PackSize) - { - opRes = NExtract::NOperationResult::kUnsupportedMethod; - break; - } - res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - break; - - case METHOD_ADC: - { - res = adcCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, progress); - break; - } - - case METHOD_ZLIB: - { - res = zlibCoder->Code(inStream, outStream, NULL, NULL, progress); - if (res == S_OK) - if (zlibCoderSpec->GetInputProcessedSize() != block.PackSize) - opRes = NExtract::NOperationResult::kDataError; - break; - } - - case METHOD_BZIP2: - { - res = bzip2Coder->Code(inStream, outStream, NULL, NULL, progress); - if (res == S_OK) - if (bzip2CoderSpec->GetInputProcessedSize() != block.PackSize) - opRes = NExtract::NOperationResult::kDataError; - break; - } - - default: - opRes = NExtract::NOperationResult::kUnsupportedMethod; - break; - } - - if (res != S_OK) - { - if (res != S_FALSE) - return res; - if (opRes == NExtract::NOperationResult::kOK) - opRes = NExtract::NOperationResult::kDataError; - } - - unpPos += block.UnpSize; - - if (!outStreamSpec->IsFinishedOK()) - { - if (realMethod && opRes == NExtract::NOperationResult::kOK) - opRes = NExtract::NOperationResult::kDataError; - - while (outStreamSpec->GetRem() != 0) - { - UInt64 rem = outStreamSpec->GetRem(); - UInt32 size = (UInt32)MyMin(rem, (UInt64)kZeroBufSize); - RINOK(WriteStream(outStream, zeroBuf, size)); - } - } - } - } - - if (needCrc && opRes == NExtract::NOperationResult::kOK) - { - if (outCrcStreamSpec->GetCRC() != item.Checksum.GetCrc32()) - opRes = NExtract::NOperationResult::kCRCError; - } - } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - - return S_OK; - COM_TRY_END -} - -struct CChunk -{ - int BlockIndex; - UInt64 AccessMark; - CByteBuffer Buf; -}; - -class CInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - int _latestChunk; - int _latestBlock; - UInt64 _accessMark; - CObjectVector _chunks; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec; - CMyComPtr bzip2Coder; - - NCompress::NZlib::CDecoder *zlibCoderSpec; - CMyComPtr zlibCoder; - - CAdcDecoder *adcCoderSpec; - CMyComPtr adcCoder; - - CBufPtrSeqOutStream *outStreamSpec; - CMyComPtr outStream; - - CLimitedSequentialInStream *limitedStreamSpec; - CMyComPtr inStream; - -public: - CMyComPtr Stream; - UInt64 Size; - const CFile *File; - UInt64 _startPos; - - HRESULT InitAndSeek(UInt64 startPos) - { - _startPos = startPos; - _virtPos = 0; - _latestChunk = -1; - _latestBlock = -1; - _accessMark = 0; - - limitedStreamSpec = new CLimitedSequentialInStream; - inStream = limitedStreamSpec; - limitedStreamSpec->SetStream(Stream); - - outStreamSpec = new CBufPtrSeqOutStream; - outStream = outStreamSpec; - return S_OK; - } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - - -unsigned FindBlock(const CRecordVector &blocks, UInt64 pos) -{ - unsigned left = 0, right = blocks.Size(); - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - return left; - if (pos < blocks[mid].UnpPos) - right = mid; - else - left = mid; - } -} - -STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - COM_TRY_BEGIN - - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (_virtPos >= Size) - return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL; - { - UInt64 rem = Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - - if (_latestBlock >= 0) - { - const CBlock &block = File->Blocks[_latestBlock]; - if (_virtPos < block.UnpPos || (_virtPos - block.UnpPos) >= block.UnpSize) - _latestBlock = -1; - } - - if (_latestBlock < 0) - { - _latestChunk = -1; - unsigned blockIndex = FindBlock(File->Blocks, _virtPos); - const CBlock &block = File->Blocks[blockIndex]; - - if (!block.IsZeroMethod() && block.Type != METHOD_COPY) - { - unsigned i; - for (i = 0; i < _chunks.Size(); i++) - if (_chunks[i].BlockIndex == (int)blockIndex) - break; - - if (i != _chunks.Size()) - _latestChunk = i; - else - { - const unsigned kNumChunksMax = 128; - unsigned chunkIndex; - - if (_chunks.Size() != kNumChunksMax) - chunkIndex = _chunks.Add(CChunk()); - else - { - chunkIndex = 0; - for (i = 0; i < _chunks.Size(); i++) - if (_chunks[i].AccessMark < _chunks[chunkIndex].AccessMark) - chunkIndex = i; - } - - CChunk &chunk = _chunks[chunkIndex]; - chunk.BlockIndex = -1; - chunk.AccessMark = 0; - - if (chunk.Buf.Size() < block.UnpSize) - { - chunk.Buf.Free(); - if (block.UnpSize > ((UInt32)1 << 31)) - return E_FAIL; - chunk.Buf.Alloc((size_t)block.UnpSize); - } - - outStreamSpec->Init(chunk.Buf, (size_t)block.UnpSize); - - RINOK(Stream->Seek(_startPos + File->StartPos + block.PackPos, STREAM_SEEK_SET, NULL)); - - limitedStreamSpec->Init(block.PackSize); - HRESULT res = S_OK; - - switch (block.Type) - { - case METHOD_COPY: - if (block.PackSize != block.UnpSize) - return E_FAIL; - res = ReadStream_FAIL(inStream, chunk.Buf, (size_t)block.UnpSize); - break; - - case METHOD_ADC: - if (!adcCoder) - { - adcCoderSpec = new CAdcDecoder(); - adcCoder = adcCoderSpec; - } - res = adcCoder->Code(inStream, outStream, &block.PackSize, &block.UnpSize, NULL); - break; - - case METHOD_ZLIB: - if (!zlibCoder) - { - zlibCoderSpec = new NCompress::NZlib::CDecoder(); - zlibCoder = zlibCoderSpec; - } - res = zlibCoder->Code(inStream, outStream, NULL, NULL, NULL); - if (res == S_OK && zlibCoderSpec->GetInputProcessedSize() != block.PackSize) - res = S_FALSE; - break; - - case METHOD_BZIP2: - if (!bzip2Coder) - { - bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - bzip2Coder = bzip2CoderSpec; - } - res = bzip2Coder->Code(inStream, outStream, NULL, NULL, NULL); - if (res == S_OK && bzip2CoderSpec->GetInputProcessedSize() != block.PackSize) - res = S_FALSE; - break; - - default: - return E_FAIL; - } - - if (res != S_OK) - return res; - if (block.Type != METHOD_COPY && outStreamSpec->GetPos() != block.UnpSize) - return E_FAIL; - chunk.BlockIndex = blockIndex; - _latestChunk = chunkIndex; - } - - _chunks[_latestChunk].AccessMark = _accessMark++; - } - - _latestBlock = blockIndex; - } - - const CBlock &block = File->Blocks[_latestBlock]; - UInt64 offset = _virtPos - block.UnpPos; - UInt64 rem = block.UnpSize - offset; - if (size > rem) - size = (UInt32)rem; - - HRESULT res = S_OK; - - if (block.Type == METHOD_COPY) - { - RINOK(Stream->Seek(_startPos + File->StartPos + block.PackPos + offset, STREAM_SEEK_SET, NULL)); - res = Stream->Read(data, size, &size); - } - else if (block.IsZeroMethod()) - memset(data, 0, size); - else if (size != 0) - memcpy(data, _chunks[_latestChunk].Buf + offset, size); - - _virtPos += size; - if (processedSize) - *processedSize = size; - - return res; - COM_TRY_END -} - -STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - - #ifdef DMG_SHOW_RAW - if (index >= (UInt32)_files.Size()) - return S_FALSE; - #endif - - CInStream *spec = new CInStream; - CMyComPtr specStream = spec; - spec->File = &_files[index]; - const CFile &file = *spec->File; - - FOR_VECTOR (i, file.Blocks) - { - const CBlock &block = file.Blocks[i]; - switch (block.Type) - { - case METHOD_ZERO_0: - case METHOD_ZERO_2: - case METHOD_COPY: - case METHOD_ADC: - case METHOD_ZLIB: - case METHOD_BZIP2: - case METHOD_END: - break; - default: - return S_FALSE; - } - } - - spec->Stream = _inStream; - spec->Size = spec->File->Size; - RINOK(spec->InitAndSeek(_startPos)); - *stream = specStream.Detach(); - return S_OK; - - COM_TRY_END -} - -REGISTER_ARC_I( - "Dmg", "dmg", 0, 0xE4, - k_Signature, - 0, - NArcInfoFlags::kBackwardOpen | - NArcInfoFlags::kUseGlobalOffset, - NULL) - -}} +// DmgHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/AutoPtr.h" +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer2.h" +#include "../../Common/MyXml.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/BZip2Decoder.h" +#include "../Compress/CopyCoder.h" +#include "../Compress/LzfseDecoder.h" +#include "../Compress/XzDecoder.h" +#include "../Compress/ZlibDecoder.h" + +#include "Common/OutStreamWithCRC.h" + +// #define DMG_SHOW_RAW + +// #define SHOW_DEBUG_INFO + +/* for debug only: we can use block cache also for METHOD_COPY blocks. + It can reduce the number of Stream->Read() requests. + But it can increase memory usage. + Note: METHOD_COPY blocks are not fused usually. + But if METHOD_COPY blocks is fused in some dmg example, + block size can exceed k_Chunk_Size_MAX. + So we don't use cache for METHOD_COPY block, if (block_size > k_Chunk_Size_MAX) +*/ +// for debug only: +// #define Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + +#ifdef SHOW_DEBUG_INFO +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +#define Get32a(p) GetBe32a(p) +#define Get64a(p) GetBe64a(p) + +Byte *Base64ToBin(Byte *dest, const char *src); + +namespace NArchive { +namespace NDmg { + +// allocation limits for compressed blocks for GetStream() interface: +static const unsigned k_NumChunks_MAX = 128; +static const size_t k_Chunk_Size_MAX = (size_t)1 << 28; +// 256 MB cache for 32-bit: +// 4 GB cache for 64-bit: +static const size_t k_Chunks_TotalSize_MAX = (size_t)1 << (sizeof(size_t) + 24); + +// 2 GB limit for 32-bit: +// 4 GB limit for 64-bit: +// that limit can be increased for 64-bit mode, if there are such dmg files +static const size_t k_XmlSize_MAX = + ((size_t)1 << (sizeof(size_t) / 4 + 30)) - 256; + +static const UInt32 METHOD_ZERO_0 = 0; // sparse +static const UInt32 METHOD_COPY = 1; +static const UInt32 METHOD_ZERO_2 = 2; // sparse : without file CRC calculation +static const UInt32 METHOD_ADC = 0x80000004; +static const UInt32 METHOD_ZLIB = 0x80000005; +static const UInt32 METHOD_BZIP2 = 0x80000006; +static const UInt32 METHOD_LZFSE = 0x80000007; +static const UInt32 METHOD_XZ = 0x80000008; +static const UInt32 METHOD_COMMENT = 0x7FFFFFFE; // is used to comment "+beg" and "+end" in extra field. +static const UInt32 METHOD_END = 0xFFFFFFFF; + + +struct CBlock +{ + UInt32 Type; + UInt64 UnpPos; + // UInt64 UnpSize; + UInt64 PackPos; + UInt64 PackSize; + + bool NeedCrc() const { return Type != METHOD_ZERO_2; } + bool IsZeroMethod() const + { + return (Type & ~(UInt32)METHOD_ZERO_2) == 0; + // return Type == METHOD_ZERO_0 || Type == METHOD_ZERO_2; + } + + bool IsClusteredMethod() const + { + // most of dmg files have non-fused COPY_METHOD blocks. + // so we don't exclude COPY_METHOD blocks when we try to detect size of cluster. + return !IsZeroMethod(); // include COPY_METHOD blocks. + // Type > METHOD_ZERO_2; // for debug: exclude COPY_METHOD blocks. + } + + bool NeedAllocateBuffer() const + { + return +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + !IsZeroMethod(); +#else + Type > METHOD_ZERO_2; + // !IsZeroMethod() && Type != METHOD_COPY; +#endif + } + // we don't store non-data blocks now + // bool ThereAreDataInBlock() const { return Type != METHOD_COMMENT && Type != METHOD_END; } +}; + +static const UInt32 kCheckSumType_CRC = 2; +static const unsigned kChecksumSize_Max = 0x80; + +struct CChecksum +{ + UInt32 Type; + UInt32 NumBits; + Byte Data[kChecksumSize_Max]; + + bool IsCrc32() const { return Type == kCheckSumType_CRC && NumBits == 32; } + UInt32 GetCrc32() const { return Get32(Data); } + void Parse(const Byte *p); + + void PrintType(AString &s) const; + void Print(AString &s) const; + void Print_with_Name(AString &s) const; + void AddToComment(AString &s, const char *name) const; +}; + +void CChecksum::Parse(const Byte *p) +{ + Type = Get32(p); + NumBits = Get32(p + 4); + memcpy(Data, p + 8, kChecksumSize_Max); +} + + +void CChecksum::PrintType(AString &s) const +{ + if (NumBits == 0) + return; + if (IsCrc32()) + s += "CRC"; + else + { + s += "Checksum"; + s.Add_UInt32(Type); + s.Add_Minus(); + s.Add_UInt32(NumBits); + } +} + +void CChecksum::Print(AString &s) const +{ + if (NumBits == 0) + return; + char temp[kChecksumSize_Max * 2 + 2]; + /* + if (IsCrc32()) + ConvertUInt32ToHex8Digits(GetCrc32(), temp); + else + */ + { + UInt32 numBits = kChecksumSize_Max * 8; + if (numBits > NumBits) + numBits = NumBits; + const unsigned numBytes = (numBits + 7) >> 3; + if (numBytes <= 8) + ConvertDataToHex_Upper(temp, Data, numBytes); + else + ConvertDataToHex_Lower(temp, Data, numBytes); + } + s += temp; +} + +void CChecksum::Print_with_Name(AString &s) const +{ + if (NumBits == 0) + return; + PrintType(s); + s += ": "; + Print(s); +} + +static void AddToComment_Prop(AString &s, const char *name, const char *val) +{ + s += name; + s += ": "; + s += val; + s.Add_LF(); +} + +void CChecksum::AddToComment(AString &s, const char *name) const +{ + AString s2; + Print_with_Name(s2); + if (!s2.IsEmpty()) + AddToComment_Prop(s, name, s2); +} + + +struct CFile +{ + UInt64 Size; + CRecordVector Blocks; + UInt64 PackSize; + UInt64 StartPackPos; + UInt64 BlockSize_MAX; + UInt64 StartUnpackSector; // unpack sector position of this file from all files + UInt64 NumUnpackSectors; + Int32 Descriptor; + bool IsCorrect; + bool FullFileChecksum; + AString Name; + // AString Id; + CChecksum Checksum; + + UInt64 GetUnpackSize_of_Block(unsigned blockIndex) const + { + return (blockIndex == Blocks.Size() - 1 ? + Size : Blocks[blockIndex + 1].UnpPos) - Blocks[blockIndex].UnpPos; + } + + CFile(): + Size(0), + PackSize(0), + StartPackPos(0), + BlockSize_MAX(0), + StartUnpackSector(0), + NumUnpackSectors(0), + Descriptor(0), + IsCorrect(false), + FullFileChecksum(false) + { + Checksum.Type = 0; + Checksum.NumBits = 0; + } + HRESULT Parse(const Byte *p, UInt32 size); +}; + +#ifdef DMG_SHOW_RAW +struct CExtraFile +{ + CByteBuffer Data; + AString Name; +}; +#endif + + +static void AddToComment_UInt64(AString &s, UInt64 v, const char *name) +{ + s += name; + s += ": "; + s.Add_UInt64(v); + s.Add_LF(); +} + +struct CForkPair +{ + UInt64 Offset; + UInt64 Len; + + // (p) is aligned for 8-bytes + void Parse(const Byte *p) + { + Offset = Get64a(p); + Len = Get64a(p + 8); + } + + bool GetEndPos(UInt64 &endPos) + { + endPos = Offset + Len; + return endPos >= Offset; + } + + bool UpdateTop(UInt64 limit, UInt64 &top) + { + if (Offset > limit || Len > limit - Offset) + return false; + const UInt64 top2 = Offset + Len; + if (top <= top2) + top = top2; + return true; + } + + void Print(AString &s, const char *name) const; +}; + +void CForkPair::Print(AString &s, const char *name) const +{ + if (Offset != 0 || Len != 0) + { + s += name; s.Add_Minus(); AddToComment_UInt64(s, Offset, "offset"); + s += name; s.Add_Minus(); AddToComment_UInt64(s, Len, "length"); + } +} + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + bool _masterCrcError; + bool _headersError; + bool _dataForkError; + bool _rsrcMode_wasUsed; + + CMyComPtr _inStream; + CObjectVector _files; + + // UInt32 _dataStartOffset; + UInt64 _startPos; + UInt64 _phySize; + + AString _name; + + CForkPair _dataForkPair; + CForkPair rsrcPair, xmlPair, blobPair; + + // UInt64 _runningDataForkOffset; + // UInt32 _segmentNumber; + // UInt32 _segmentCount; + UInt64 _numSectors; // total unpacked number of sectors + Byte _segmentGUID[16]; + + CChecksum _dataForkChecksum; + CChecksum _masterChecksum; + +#ifdef DMG_SHOW_RAW + CObjectVector _extras; +#endif + + HRESULT ReadData(IInStream *stream, const CForkPair &pair, CByteBuffer &buf); + bool ParseBlob(const CByteBuffer &data); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback); + HRESULT Extract(IInStream *stream); +}; + + +struct CMethods +{ + CRecordVector Types; + + void Update(const CFile &file); + void AddToString(AString &s) const; +}; + +void CMethods::Update(const CFile &file) +{ + FOR_VECTOR (i, file.Blocks) + { + if (Types.Size() >= (1 << 8)) + break; + Types.AddToUniqueSorted(file.Blocks[i].Type); + } +} + +void CMethods::AddToString(AString &res) const +{ + FOR_VECTOR (i, Types) + { + const UInt32 type = Types[i]; + /* + if (type == METHOD_COMMENT || type == METHOD_END) + continue; + */ + char buf[16]; + const char *s; + switch (type) + { + // case METHOD_COMMENT: s = "Comment"; break; + case METHOD_ZERO_0: s = "Zero0"; break; + case METHOD_ZERO_2: s = "Zero2"; break; + case METHOD_COPY: s = "Copy"; break; + case METHOD_ADC: s = "ADC"; break; + case METHOD_ZLIB: s = "ZLIB"; break; + case METHOD_BZIP2: s = "BZip2"; break; + case METHOD_LZFSE: s = "LZFSE"; break; + case METHOD_XZ: s = "XZ"; break; + default: ConvertUInt32ToHex(type, buf); s = buf; + } + res.Add_OptSpaced(s); + } +} + + + +struct CAppleName +{ + bool IsFs; + const char *Ext; + const char *AppleName; +}; + +static const CAppleName k_Names[] = +{ + { true, "hfs", "Apple_HFS" }, + { true, "hfsx", "Apple_HFSX" }, + { true, "ufs", "Apple_UFS" }, + { true, "apfs", "Apple_APFS" }, + { true, "iso", "Apple_ISO" }, + + // efi_sys partition is FAT32, but it's not main file. So we use (IsFs = false) + { false, "efi_sys", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, + + { false, "free", "Apple_Free" }, + { false, "ddm", "DDM" }, + { false, NULL, "Apple_partition_map" }, + { false, NULL, " GPT " }, + /* " GPT " is substring of full name entry in dmg that contains + some small metadata GPT entry. It's not real FS entry: + "Primary GPT Header", + "Primary GPT Table" + "Backup GPT Header", + "Backup GPT Table", + */ + { false, NULL, "MBR" }, + { false, NULL, "Driver" }, + { false, NULL, "Patches" } +}; + +static const unsigned kNumAppleNames = Z7_ARRAY_SIZE(k_Names); + +const char *Find_Apple_FS_Ext(const AString &name); +const char *Find_Apple_FS_Ext(const AString &name) +{ + for (unsigned i = 0; i < kNumAppleNames; i++) + { + const CAppleName &a = k_Names[i]; + if (a.Ext) + if (name.IsEqualTo(a.AppleName)) + return a.Ext; + } + return NULL; +} + + +bool Is_Apple_FS_Or_Unknown(const AString &name); +bool Is_Apple_FS_Or_Unknown(const AString &name) +{ + for (unsigned i = 0; i < kNumAppleNames; i++) + { + const CAppleName &a = k_Names[i]; + // if (name.Find(a.AppleName) >= 0) + if (strstr(name, a.AppleName)) + return a.IsFs; + } + return true; +} + + + +// define it for debug only: +// #define Z7_DMG_SINGLE_FILE_MODE + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidComment, + kpidMethod, + kpidNumBlocks, + kpidClusterSize, + kpidChecksum, + kpidCRC, + kpidId + // kpidOffset +#ifdef Z7_DMG_SINGLE_FILE_MODE + , kpidPosition +#endif +}; + +IMP_IInArchive_Props + +static const Byte kArcProps[] = +{ + kpidMethod, + kpidNumBlocks, + kpidClusterSize, + kpidComment +}; + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidMethod: + { + CMethods m; + CRecordVector ChecksumTypes; + { + FOR_VECTOR (i, _files) + { + const CFile &file = _files[i]; + m.Update(file); + if (ChecksumTypes.Size() < (1 << 8)) + ChecksumTypes.AddToUniqueSorted(file.Checksum.Type); + } + } + AString s; + m.AddToString(s); + + FOR_VECTOR (i, ChecksumTypes) + { + const UInt32 type = ChecksumTypes[i]; + switch (type) + { + case kCheckSumType_CRC: + s.Add_OptSpaced("CRC"); + break; + default: + s.Add_OptSpaced("Checksum"); + s.Add_UInt32(type); + } + } + + if (!s.IsEmpty()) + prop = s; + break; + } + case kpidNumBlocks: + { + UInt64 numBlocks = 0; + FOR_VECTOR (i, _files) + numBlocks += _files[i].Blocks.Size(); + prop = numBlocks; + break; + } + case kpidClusterSize: + { + UInt64 blockSize_MAX = 0; + FOR_VECTOR (i, _files) + { + const UInt64 a = _files[i].BlockSize_MAX; + if (blockSize_MAX < a) + blockSize_MAX = a; + } + prop = blockSize_MAX; + break; + } + case kpidMainSubfile: + { + int mainIndex = -1; + FOR_VECTOR (i, _files) + { + if (Is_Apple_FS_Or_Unknown(_files[i].Name)) + { + if (mainIndex != -1) + { + mainIndex = -1; + break; + } + mainIndex = (int)i; + } + } + if (mainIndex != -1) + prop = (UInt32)(Int32)mainIndex; + break; + } + case kpidWarning: + if (_masterCrcError) + prop = "Master CRC error"; + break; + + case kpidWarningFlags: + { + UInt32 v = 0; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (_dataForkError) v |= kpv_ErrorFlags_CrcError; + if (v != 0) + prop = v; + break; + } + + case kpidOffset: prop = _startPos; break; + case kpidPhySize: prop = _phySize; break; + + case kpidComment: + { + AString s; + if (!_name.IsEmpty()) + AddToComment_Prop(s, "Name", _name); + AddToComment_UInt64(s, _numSectors << 9, "unpack-size"); + { + char temp[sizeof(_segmentGUID) * 2 + 2]; + ConvertDataToHex_Lower(temp, _segmentGUID, sizeof(_segmentGUID)); + AddToComment_Prop(s, "ID", temp); + } + _masterChecksum.AddToComment(s, "master-checksum"); + _dataForkChecksum.AddToComment(s, "pack-checksum"); + { + /* + if (_dataStartOffset != 0) + AddToComment_UInt64(s, _dataStartOffset, "payload-start-offset"); + */ + // if (_dataForkPair.Offset != 0) + _dataForkPair.Print(s, "pack"); + rsrcPair.Print(s, "rsrc"); + xmlPair.Print(s, "xml"); + blobPair.Print(s, "blob"); + } + if (_rsrcMode_wasUsed) + s += "RSRC_MODE\n"; + if (!s.IsEmpty()) + prop = s; + } + break; + + case kpidName: + if (!_name.IsEmpty()) + prop = _name + ".dmg"; + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +IMP_IInArchive_ArcProps + + + +static const UInt64 kSectorNumber_LIMIT = (UInt64)1 << (63 - 9); + +HRESULT CFile::Parse(const Byte *p, UInt32 size) +{ + // CFile was initialized to default values: 0 in size variables and (IsCorrect == false) + const unsigned kHeadSize = 0xCC; + if (size < kHeadSize) + return S_FALSE; + if (Get32(p) != 0x6D697368) // "mish" signature + return S_FALSE; + if (Get32(p + 4) != 1) // version + return S_FALSE; + + StartUnpackSector = Get64(p + 8); + NumUnpackSectors = Get64(p + 0x10); + StartPackPos = Get64(p + 0x18); + +#ifdef SHOW_DEBUG_INFO + /* the number of sectors that must be allocated. + == 0x208 for 256KB clusters + == 0x808 for 1MB clusters + == 0x1001 for 1MB clusters in some example + */ + const UInt32 decompressedBufRequested = Get32(p + 0x20); +#endif + + // Descriptor is file index. usually started from -1 + // in one dmg it was started from 0 + Descriptor = (Int32)Get32(p + 0x24); + // char Reserved1[24]; + + Checksum.Parse(p + 0x40); + PRF(printf("\n" " Checksum Type = %2u" + "\n StartUnpackSector = %8x" + "\n NumUnpackSectors = %8x" + "\n StartPos = %8x" + "\n decompressedBufRequested=%8x" + "\n blocksDescriptor=%8x" + , (unsigned)Checksum.Type + , (unsigned)StartUnpackSector + , (unsigned)NumUnpackSectors + , (unsigned)StartPackPos + , (unsigned)decompressedBufRequested + , (unsigned)Descriptor + );) + + const UInt32 numBlocks = Get32(p + 0xC8); + const unsigned kRecordSize = 40; + if ((UInt64)numBlocks * kRecordSize + kHeadSize != size) + return S_FALSE; + + Blocks.ClearAndReserve(numBlocks); + FullFileChecksum = true; + /* IsCorrect = false; by default + So we return S_OK, if we can ignore some error in headers. + */ + + p += kHeadSize; + UInt32 i; + + for (i = 0; i < numBlocks; i++, p += kRecordSize) + { + CBlock b; + b.Type = Get32(p); + { + const UInt64 a = Get64(p + 0x08); + if (a >= kSectorNumber_LIMIT) + return S_OK; + b.UnpPos = a << 9; + } + UInt64 unpSize; + { + const UInt64 a = Get64(p + 0x10); + if (a >= kSectorNumber_LIMIT) + return S_OK; + unpSize = a << 9; + } + const UInt64 newSize = b.UnpPos + unpSize; + if (newSize >= ((UInt64)1 << 63)) + return S_OK; + + b.PackPos = Get64(p + 0x18); + b.PackSize = Get64(p + 0x20); + // b.PackPos can be 0 for some types. So we don't check it + if (b.UnpPos != Size) + return S_OK; + + PRF(printf("\nType=%8x comment=%8x uPos=%8x uSize=%7x pPos=%8x pSize=%7x", + (unsigned)b.Type, Get32(p + 4), (unsigned)b.UnpPos, (unsigned)unpSize, (unsigned)b.PackPos, (unsigned)b.PackSize)); + + if (b.Type == METHOD_COMMENT) + { + // some files contain 2 comment block records: + // record[0] : Type=METHOD_COMMENT, comment_field = "+beg" + // record[num-2] : Type=METHOD_COMMENT, comment_field = "+end" + // we skip these useless records. + continue; + } + if (b.Type == METHOD_END) + break; + + // we add only blocks that have non empty unpacked data: + if (unpSize != 0) + { + const UInt64 k_max_pos = (UInt64)1 << 63; + if (b.PackPos >= k_max_pos || + b.PackSize >= k_max_pos - b.PackPos) + return S_OK; + + /* we don't count non-ZERO blocks here, because + ZERO blocks in dmg files are not limited by some cluster size. + note: COPY blocks also sometimes are fused to larger blocks. + */ + if (b.IsClusteredMethod()) + if (BlockSize_MAX < unpSize) + BlockSize_MAX = unpSize; + + PackSize += b.PackSize; + if (!b.NeedCrc()) + FullFileChecksum = false; + Blocks.AddInReserved(b); + Size = newSize; + } + } + + PRF(printf("\n");) + + if (i != numBlocks - 1) + { + // return S_FALSE; + return S_OK; + } + + if ((Size >> 9) == NumUnpackSectors) + IsCorrect = true; + return S_OK; +} + + +static const CXmlItem *FindKeyPair(const CXmlItem &item, const char *key, const char *nextTag) +{ + for (unsigned i = 0; i + 1 < item.SubItems.Size(); i++) + { + const CXmlItem &si = item.SubItems[i]; + if (si.IsTagged("key") && si.GetSubString().IsEqualTo(key)) + { + const CXmlItem *si_1 = &item.SubItems[i + 1]; + if (si_1->IsTagged(nextTag)) + return si_1; + } + } + return NULL; +} + +static const AString *GetStringFromKeyPair(const CXmlItem &item, const char *key, const char *nextTag) +{ + const CXmlItem *si_1 = FindKeyPair(item, key, nextTag); + if (si_1) + return si_1->GetSubStringPtr(); + return NULL; +} + +static const Byte k_Signature[] = { 'k','o','l','y', 0, 0, 0, 4, 0, 0, 2, 0 }; + +static inline bool IsKoly(const Byte *p) +{ + return memcmp(p, k_Signature, Z7_ARRAY_SIZE(k_Signature)) == 0; + /* + if (Get32(p) != 0x6B6F6C79) // "koly" signature + return false; + if (Get32(p + 4) != 4) // version + return false; + if (Get32(p + 8) != HEADER_SIZE) + return false; + return true; + */ +} + + +HRESULT CHandler::ReadData(IInStream *stream, const CForkPair &pair, CByteBuffer &buf) +{ + size_t size = (size_t)pair.Len; + if (size != pair.Len) + return E_OUTOFMEMORY; + buf.Alloc(size); + RINOK(InStream_SeekSet(stream, _startPos + pair.Offset)) + return ReadStream_FALSE(stream, buf, size); +} + + + +bool CHandler::ParseBlob(const CByteBuffer &data) +{ + const unsigned kHeaderSize = 3 * 4; + if (data.Size() < kHeaderSize) + return false; + const Byte * const p = (const Byte *)data; + if (Get32a(p) != 0xfade0cc0) // CSMAGIC_EMBEDDED_SIGNATURE + return true; + const UInt32 size = Get32a(p + 4); + if (size != data.Size()) + return false; + const UInt32 num = Get32a(p + 8); + if (num > (size - kHeaderSize) / 8) + return false; + + const UInt32 limit = num * 8 + kHeaderSize; + for (size_t i = kHeaderSize; i < limit; i += 8) + { + // type == 0 == CSSLOT_CODEDIRECTORY for CSMAGIC_CODEDIRECTORY item + // UInt32 type = Get32(p + i); + const UInt32 offset = Get32a(p + i + 4); + if (offset < limit || offset > size - 8) + return false; + // offset is not aligned for 4 here !!! + const Byte * const p2 = p + offset; + const UInt32 magic = Get32(p2); + const UInt32 len = Get32(p2 + 4); + if (size - offset < len || len < 8) + return false; + +#ifdef DMG_SHOW_RAW + CExtraFile &extra = _extras.AddNew(); + extra.Name = "_blob_"; + extra.Data.CopyFrom(p2, len); +#endif + + if (magic == 0xfade0c02) // CSMAGIC_CODEDIRECTORY + { +#ifdef DMG_SHOW_RAW + extra.Name += "codedir"; +#endif + + if (len < 11 * 4) + return false; + const UInt32 idOffset = Get32(p2 + 5 * 4); + if (idOffset >= len) + return false; + UInt32 len2 = len - idOffset; + const UInt32 kNameLenMax = 1 << 8; + if (len2 > kNameLenMax) + len2 = kNameLenMax; + _name.SetFrom_CalcLen((const char *)(p2 + idOffset), len2); + /* + // #define kSecCodeSignatureHashSHA1 1 + // #define kSecCodeSignatureHashSHA256 2 + const UInt32 hashOffset = Get32(p2 + 4 * 4); + const UInt32 nSpecialSlots = Get32(p2 + 6 * 4); + const UInt32 nCodeSlots = Get32(p2 + 7 * 4); + const unsigned hashSize = p2[36]; + const unsigned hashType = p2[37]; + // const unsigned unused = p2[38]; + const unsigned pageSize = p2[39]; + */ + } +#ifdef DMG_SHOW_RAW + else if (magic == 0xfade0c01) extra.Name += "requirements"; + else if (magic == 0xfade0b01) extra.Name += "signed"; + else + { + char temp[16]; + ConvertUInt32ToHex8Digits(magic, temp); + extra.Name += temp; + } +#endif + } + + return true; +} + + + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) +{ + /* + - usual dmg contains Koly Header at the end: + - rare case old dmg contains Koly Header at the begin. + */ + + // _dataStartOffset = 0; + UInt64 fileSize; + RINOK(InStream_GetPos_GetSize(stream, _startPos, fileSize)) + + const unsigned HEADER_SIZE = 0x200; + UInt64 buf[HEADER_SIZE / sizeof(UInt64)]; + RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)) + + UInt64 headerPos; + bool front_Koly_Mode = false; + + /* + _dataForkChecksum.Offset == 0 for koly-at-the-end + _dataForkChecksum.Offset == 512 for koly-at-the-start + so we can use (_dataForkChecksum.Offset) to detect "koly-at-the-start" mode + */ + + if (IsKoly((const Byte *)(const void *)buf)) + { + // it can be normal koly-at-the-end or koly-at-the-start + headerPos = _startPos; + /* + if (_startPos <= (1 << 8)) + { + // we want to support front_Koly_Mode, even if there is + // some data before dmg file, like 128 bytes MacBin header + _dataStartOffset = HEADER_SIZE; + front_Koly_Mode = true; + } + */ + } + else + { + /* we try to open in backward mode only for first attempt + when (_startPos == 0) */ + if (_startPos != 0) + return S_FALSE; + headerPos = fileSize; + if (headerPos < HEADER_SIZE) + return S_FALSE; + headerPos -= HEADER_SIZE; + RINOK(InStream_SeekSet(stream, headerPos)) + RINOK(ReadStream_FALSE(stream, buf, HEADER_SIZE)) + if (!IsKoly((const Byte *)(const void *)buf)) + return S_FALSE; + } + + // UInt32 flags = Get32a((const Byte *)(const void *)buf + 12); + // _runningDataForkOffset = Get64a((const Byte *)(const void *)buf + 0x10); + _dataForkPair.Parse((const Byte *)(const void *)buf + 0x18); + rsrcPair.Parse((const Byte *)(const void *)buf + 0x28); + // _segmentNumber = Get32a(buf + 0x38); // 0 or 1 + // _segmentCount = Get32a(buf + 0x3C); // 0 (if not set) or 1 + memcpy(_segmentGUID, (const Byte *)(const void *)buf + 0x40, 16); + _dataForkChecksum.Parse((const Byte *)(const void *)buf + 0x50); + xmlPair.Parse((const Byte *)(const void *)buf + 0xD8); + // Byte resereved[] + blobPair.Parse((const Byte *)(const void *)buf + 0x128); + _masterChecksum.Parse((const Byte *)(const void *)buf + 0x160); + // UInt32 imageVariant = Get32a((const Byte *)(const void *)buf + 0x1E8); imageVariant = imageVariant; + _numSectors = Get64((const Byte *)(const void *)buf + 0x1EC); // it's not aligned for 8-bytes + // Byte resereved[12]; + + if (_dataForkPair.Offset == HEADER_SIZE + && headerPos + HEADER_SIZE < fileSize) + front_Koly_Mode = true; + + const UInt64 limit = front_Koly_Mode ? fileSize : headerPos; + UInt64 top = 0; + if (!_dataForkPair.UpdateTop(limit, top)) return S_FALSE; + if (!xmlPair.UpdateTop(limit, top)) return S_FALSE; + if (!rsrcPair.UpdateTop(limit, top)) return S_FALSE; + + /* Some old dmg files contain garbage data in blobPair field. + So we need to ignore such garbage case; + And we still need to detect offset of start of archive for "parser" mode. */ + const bool useBlob = blobPair.UpdateTop(limit, top); + + if (front_Koly_Mode) + _phySize = top; + else + { + _phySize = headerPos + HEADER_SIZE; + _startPos = 0; + if (top != headerPos) + { + /* + if expected absolute offset is not equal to real header offset, + 2 cases are possible: + - additional (unknown) headers + - archive with offset. + So we try to read XML with absolute offset to select from these two ways. + */ + CForkPair xmlPair2 = xmlPair; + const char *sz = " len) + xmlPair2.Len = len; + CByteBuffer buf2; + if (xmlPair2.Len < len + || ReadData(stream, xmlPair2, buf2) != S_OK + || memcmp(buf2, sz, len) != 0) + { + // if absolute offset is not OK, probably it's archive with offset + _startPos = headerPos - top; + _phySize = top + HEADER_SIZE; + } + } + } + + if (useBlob + && blobPair.Len != 0 + && blobPair.Len <= (1u << 24)) // we don't want parsing of big blobs + { +#ifdef DMG_SHOW_RAW + CExtraFile &extra = _extras.AddNew(); + extra.Name = "_blob.bin"; + CByteBuffer &blobBuf = extra.Data; +#else + CByteBuffer blobBuf; +#endif + RINOK(ReadData(stream, blobPair, blobBuf)) + if (!ParseBlob(blobBuf)) + _headersError = true; + } + + + UInt64 openTotal = 0; + UInt64 openCur = 0; + if (_dataForkChecksum.IsCrc32()) + openTotal = _dataForkPair.Len; + + const UInt32 RSRC_HEAD_SIZE = 0x100; + + /* we have 2 ways to read files and blocks metadata: + via Xml or via Rsrc. + But some images have no Rsrc fork. + Is it possible that there is no Xml? + Rsrc method will not work for big files. */ + // v23.02: we use xml mode by default + // if (rsrcPair.Len >= RSRC_HEAD_SIZE && rsrcPair.Len <= ((UInt32)1 << 24)) // for debug + if (xmlPair.Len == 0) + { + // We don't know the size of the field "offset" in Rsrc. + // We suppose that it uses 24 bits. So we use Rsrc, only if the rsrcPair.Len <= (1 << 24). + const bool canUseRsrc = (rsrcPair.Len >= RSRC_HEAD_SIZE && rsrcPair.Len <= ((UInt32)1 << 24)); + if (!canUseRsrc) + return S_FALSE; + + _rsrcMode_wasUsed = true; +#ifdef DMG_SHOW_RAW + CExtraFile &extra = _extras.AddNew(); + extra.Name = "rsrc.bin"; + CByteBuffer &rsrcBuf = extra.Data; +#else + CByteBuffer rsrcBuf; +#endif + + RINOK(ReadData(stream, rsrcPair, rsrcBuf)) + + const Byte *p = rsrcBuf; + const UInt32 headSize = Get32a(p + 0); + const UInt32 footerOffset = Get32a(p + 4); + const UInt32 mainDataSize = Get32a(p + 8); + const UInt32 footerSize = Get32a(p + 12); + if (headSize != RSRC_HEAD_SIZE + || footerOffset >= rsrcPair.Len + || mainDataSize >= rsrcPair.Len + || footerOffset < mainDataSize + || footerOffset != headSize + mainDataSize) + return S_FALSE; + + { + const UInt32 footerEnd = footerOffset + footerSize; + if (footerEnd != rsrcPair.Len) + { + // there is rare case dmg example, where there are 4 additional bytes + const UInt64 rem = rsrcPair.Len - footerOffset; + if (rem < footerSize + || rem - footerSize != 4 + || Get32(p + footerEnd) != 0) + return S_FALSE; + } + } + + if (footerSize < 0x1e) + return S_FALSE; + if (memcmp(p, p + footerOffset, 16) != 0) + return S_FALSE; + + p += footerOffset; + + if ((UInt32)Get16(p + 0x18) != 0x1c) + return S_FALSE; + const UInt32 namesOffset = Get16(p + 0x1a); + if (namesOffset > footerSize) + return S_FALSE; + + const UInt32 numItems = (UInt32)Get16(p + 0x1c) + 1; + if (numItems * 8 + 0x1e > namesOffset) + return S_FALSE; + + for (UInt32 i = 0; i < numItems; i++) + { + const Byte *p2 = p + 0x1e + (size_t)i * 8; + const UInt32 typeId = Get32(p2); + const UInt32 k_typeId_blkx = 0x626c6b78; // blkx +#ifndef DMG_SHOW_RAW + if (typeId != k_typeId_blkx) + continue; +#endif + const UInt32 numFiles = (UInt32)Get16(p2 + 4) + 1; + const UInt32 offs = Get16(p2 + 6); + if (0x1c + offs + 12 * numFiles > namesOffset) + return S_FALSE; + + for (UInt32 k = 0; k < numFiles; k++) + { + const Byte *p3 = p + 0x1c + offs + k * 12; + // UInt32 id = Get16(p3); + const UInt32 namePos = Get16(p3 + 2); + // Byte attributes = p3[4]; // = 0x50 for blkx #define (ATTRIBUTE_HDIUTIL) + // we don't know how many bits we can use. So we use 24 bits only + UInt32 blockOffset = Get32(p3 + 4); + blockOffset &= ((UInt32)1 << 24) - 1; + // UInt32 unknown2 = Get32(p3 + 8); // ??? + if (blockOffset + 4 >= mainDataSize) + return S_FALSE; + const Byte *pBlock = rsrcBuf + headSize + blockOffset; + const UInt32 blockSize = Get32(pBlock); + if (mainDataSize - (blockOffset + 4) < blockSize) + return S_FALSE; + + AString name; + + if (namePos != 0xffff) + { + const UInt32 namesBlockSize = footerSize - namesOffset; + if (namePos >= namesBlockSize) + return S_FALSE; + const Byte *namePtr = p + namesOffset + namePos; + const UInt32 nameLen = *namePtr; + if (namesBlockSize - namePos <= nameLen) + return S_FALSE; + for (UInt32 r = 1; r <= nameLen; r++) + { + const Byte c = namePtr[r]; + if (c < 0x20 || c >= 0x80) + break; + name += (char)c; + } + } + + if (typeId == k_typeId_blkx) + { + CFile &file = _files.AddNew(); + file.Name = name; + RINOK(file.Parse(pBlock + 4, blockSize)) + if (!file.IsCorrect) + _headersError = true; + } + +#ifdef DMG_SHOW_RAW + { + AString name2; + name2.Add_UInt32(i); + name2 += '_'; + { + char temp[4 + 1] = { 0 }; + memcpy(temp, p2, 4); + name2 += temp; + } + name2.Trim(); + name2 += '_'; + name2.Add_UInt32(k); + if (!name.IsEmpty()) + { + name2 += '_'; + name2 += name; + } + CExtraFile &extra2 = _extras.AddNew(); + extra2.Name = name2; + extra2.Data.CopyFrom(pBlock + 4, blockSize); + } +#endif + } + } + } + else + { + if (xmlPair.Len > k_XmlSize_MAX) + return S_FALSE; + // if (!canUseXml) return S_FALSE; + const size_t size = (size_t)xmlPair.Len; + // if (size + 1 <= xmlPair.Len) return S_FALSE; // optional check + RINOK(InStream_SeekSet(stream, _startPos + xmlPair.Offset)) + CXml xml; + { + openTotal += size; + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetTotal(NULL, &openTotal)) + } + size_t pos = 0; + CAlignedBuffer1 xmlStr(size + 1); + for (;;) + { + const size_t k_OpenStep = 1 << 24; + const size_t cur = MyMin(k_OpenStep, size - pos); + RINOK(ReadStream_FALSE(stream, xmlStr + pos, cur)) + pos += cur; + openCur += cur; + if (pos == size) + break; + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetCompleted(NULL, &openCur)) + } + } + xmlStr[size] = 0; + // if (strlen((const char *)(const void *)(const Byte *)xmlStr) != size) return S_FALSE; + if (!xml.Parse((char *)(void *)(Byte *)xmlStr)) + return S_FALSE; + +#ifdef DMG_SHOW_RAW + CExtraFile &extra = _extras.AddNew(); + extra.Name = "a.xml"; + extra.Data.CopyFrom(xmlStr, size); +#endif + } + + if (!xml.Root.Name.IsEqualTo("plist")) + return S_FALSE; + + const CXmlItem *dictItem = xml.Root.FindSubTag_GetPtr("dict"); + if (!dictItem) + return S_FALSE; + + const CXmlItem *rfDictItem = FindKeyPair(*dictItem, "resource-fork", "dict"); + if (!rfDictItem) + return S_FALSE; + + const CXmlItem *arrItem = FindKeyPair(*rfDictItem, "blkx", "array"); + if (!arrItem) + return S_FALSE; + + FOR_VECTOR (i, arrItem->SubItems) + { + const CXmlItem &item = arrItem->SubItems[i]; + if (!item.IsTagged("dict")) + continue; + + CByteBuffer rawBuf; + unsigned destLen = 0; + { + const AString *dataString = GetStringFromKeyPair(item, "Data", "data"); + if (!dataString) + return S_FALSE; + destLen = dataString->Len() / 4 * 3 + 4; + rawBuf.Alloc(destLen); + { + const Byte *endPtr = Base64ToBin(rawBuf, *dataString); + if (!endPtr) + return S_FALSE; + destLen = (unsigned)(endPtr - (const Byte *)rawBuf); + } + +#ifdef DMG_SHOW_RAW + CExtraFile &extra = _extras.AddNew(); + extra.Name.Add_UInt32(_files.Size()); + extra.Data.CopyFrom(rawBuf, destLen); +#endif + } + CFile &file = _files.AddNew(); + { + /* xml code removes front space for such string: + (Apple_Free : 3) + maybe we shoud fix xml code and return full string with space. + */ + const AString *name = GetStringFromKeyPair(item, "Name", "string"); + if (!name || name->IsEmpty()) + name = GetStringFromKeyPair(item, "CFName", "string"); + if (name) + file.Name = *name; + } + /* + { + const AString *s = GetStringFromKeyPair(item, "ID", "string"); + if (s) + file.Id = *s; + } + */ + RINOK(file.Parse(rawBuf, destLen)) + if (!file.IsCorrect) + _headersError = true; + } + } + + if (_masterChecksum.IsCrc32()) + { + UInt32 crc = CRC_INIT_VAL; + unsigned i; + for (i = 0; i < _files.Size(); i++) + { + const CChecksum &cs = _files[i].Checksum; + if ((cs.NumBits & 0x7) != 0) + break; + const UInt32 len = cs.NumBits >> 3; + if (len > kChecksumSize_Max) + break; + crc = CrcUpdate(crc, cs.Data, (size_t)len); + } + if (i == _files.Size()) + _masterCrcError = (CRC_GET_DIGEST(crc) != _masterChecksum.GetCrc32()); + } + + { + UInt64 sec = 0; + FOR_VECTOR (i, _files) + { + const CFile &file = _files[i]; + /* + if (file.Descriptor != (Int32)i - 1) + _headersError = true; + */ + if (file.StartUnpackSector != sec) + _headersError = true; + if (file.NumUnpackSectors >= kSectorNumber_LIMIT) + _headersError = true; + sec += file.NumUnpackSectors; + if (sec >= kSectorNumber_LIMIT) + _headersError = true; + } + if (sec != _numSectors) + _headersError = true; + } + + // data checksum calculation can be slow for big dmg file + if (_dataForkChecksum.IsCrc32()) + { + UInt64 endPos; + if (!_dataForkPair.GetEndPos(endPos) + || _dataForkPair.Offset >= ((UInt64)1 << 63)) + _headersError = true; + else + { + const UInt64 seekPos = _startPos + _dataForkPair.Offset; + if (seekPos > fileSize + || endPos > fileSize - _startPos) + { + _headersError = true; + // kpv_ErrorFlags_UnexpectedEnd + } + else + { + const size_t kBufSize = 1 << 15; + CAlignedBuffer1 buf2(kBufSize); + RINOK(InStream_SeekSet(stream, seekPos)) + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetTotal(NULL, &openTotal)) + } + UInt32 crc = CRC_INIT_VAL; + UInt64 pos = 0; + for (;;) + { + const UInt64 rem = _dataForkPair.Len - pos; + size_t cur = kBufSize; + if (cur > rem) + cur = (UInt32)rem; + if (cur == 0) + break; + RINOK(ReadStream_FALSE(stream, buf2, cur)) + crc = CrcUpdate(crc, buf2, cur); + pos += cur; + openCur += cur; + if ((pos & ((1 << 24) - 1)) == 0 && openArchiveCallback) + { + RINOK(openArchiveCallback->SetCompleted(NULL, &openCur)) + } + } + if (_dataForkChecksum.GetCrc32() != CRC_GET_DIGEST(crc)) + _dataForkError = true; + } + } + } + + return S_OK; +} + + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *openArchiveCallback)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(stream, openArchiveCallback)) + _inStream = stream; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _masterCrcError = false; + _headersError = false; + _dataForkError = false; + _rsrcMode_wasUsed = false; + _phySize = 0; + _startPos = 0; + _name.Empty(); + _inStream.Release(); + _files.Clear(); +#ifdef DMG_SHOW_RAW + _extras.Clear(); +#endif + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _files.Size() +#ifdef DMG_SHOW_RAW + + _extras.Size() +#endif + ; + return S_OK; +} + +#ifdef DMG_SHOW_RAW +#define RAW_PREFIX "raw" STRING_PATH_SEPARATOR +#endif + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + +#ifdef DMG_SHOW_RAW + if (index >= _files.Size()) + { + const CExtraFile &extra = _extras[index - _files.Size()]; + switch (propID) + { + case kpidPath: + prop = (AString)RAW_PREFIX + extra.Name; + break; + case kpidSize: + case kpidPackSize: + prop = (UInt64)extra.Data.Size(); + break; + } + } + else +#endif + { + const CFile &item = _files[index]; + switch (propID) + { + case kpidSize: prop = item.Size; break; + case kpidPackSize: prop = item.PackSize; break; + case kpidCRC: + { + if (item.Checksum.IsCrc32() && item.FullFileChecksum) + prop = item.Checksum.GetCrc32(); + break; + } + case kpidChecksum: + { + AString s; + item.Checksum.Print(s); + if (!s.IsEmpty()) + prop = s; + break; + } + + /* + case kpidOffset: + { + prop = item.StartPackPos; + break; + } + */ + + case kpidNumBlocks: + prop = (UInt32)item.Blocks.Size(); + break; + case kpidClusterSize: + prop = item.BlockSize_MAX; + break; + + case kpidMethod: + { + AString s; + if (!item.IsCorrect) + s.Add_OptSpaced("CORRUPTED"); + CMethods m; + m.Update(item); + m.AddToString(s); + { + AString s2; + item.Checksum.PrintType(s2); + if (!s2.IsEmpty()) + s.Add_OptSpaced(s2); + } + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidPath: + { +#ifdef Z7_DMG_SINGLE_FILE_MODE + prop = "a.img"; +#else + UString name; + name.Add_UInt32(index); + unsigned num = 10; + unsigned numDigits; + for (numDigits = 1; num < _files.Size(); numDigits++) + num *= 10; + while (name.Len() < numDigits) + name.InsertAtFront(L'0'); + + AString subName; + int pos1 = item.Name.Find('('); + if (pos1 >= 0) + { + pos1++; + const int pos2 = item.Name.Find(')', pos1); + if (pos2 >= 0) + { + subName.SetFrom(item.Name.Ptr(pos1), pos2 - pos1); + pos1 = subName.Find(':'); + if (pos1 >= 0) + subName.DeleteFrom(pos1); + } + } + else + subName = item.Name; // new apfs dmg can be without braces + subName.Trim(); + if (!subName.IsEmpty()) + { + const char *ext = Find_Apple_FS_Ext(subName); + if (ext) + subName = ext; + UString name2; + ConvertUTF8ToUnicode(subName, name2); + name.Add_Dot(); + name += name2; + } + else + { + UString name2; + ConvertUTF8ToUnicode(item.Name, name2); + if (!name2.IsEmpty()) + name += "_"; + name += name2; + } + prop = name; +#endif + + break; + } + + case kpidComment: + { + UString name; + ConvertUTF8ToUnicode(item.Name, name); + prop = name; + break; + } + case kpidId: + { + prop.Set_Int32((Int32)item.Descriptor); + /* + if (!item.Id.IsEmpty()) + { + UString s; + ConvertUTF8ToUnicode(item.Id, s); + prop = s; + } + */ + break; + } +#ifdef Z7_DMG_SINGLE_FILE_MODE + case kpidPosition: + prop = item.StartUnpackSector << 9; + break; +#endif + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +class CAdcDecoder +{ + CLzOutWindow m_OutWindowStream; + CInBuffer m_InStream; + + class CCoderReleaser Z7_final + { + CAdcDecoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CAdcDecoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + } + }; + friend class CCoderReleaser; + +public: + HRESULT Code(ISequentialInStream * const inStream, + ISequentialOutStream *outStream, + const UInt64 * const inSize, + const UInt64 * const outSize, + ICompressProgressInfo * const progress); +}; + + +HRESULT CAdcDecoder::Code(ISequentialInStream * const inStream, + ISequentialOutStream *outStream, + const UInt64 * const inSize, + const UInt64 * const outSizePtr, + ICompressProgressInfo * const progress) +{ + try { + + if (!m_OutWindowStream.Create(1 << 18)) // at least (1 << 16) is required here + return E_OUTOFMEMORY; + if (!m_InStream.Create(1 << 18)) + return E_OUTOFMEMORY; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InStream.SetStream(inStream); + m_InStream.Init(); + + CCoderReleaser coderReleaser(this); + + const UInt32 kStep = 1 << 22; + UInt64 nextLimit = kStep; + const UInt64 outSize = *outSizePtr; + UInt64 pos = 0; + /* match sequences and literal sequences do not cross 64KB range + in some dmg archive examples. But is it so for any Adc stream? */ + + while (pos < outSize) + { + if (pos >= nextLimit && progress) + { + nextLimit += kStep; + const UInt64 packSize = m_InStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) + } + Byte b; + if (!m_InStream.ReadByte(b)) + return S_FALSE; + const UInt64 rem = outSize - pos; + if (b & 0x80) + { + unsigned num = (unsigned)b - 0x80 + 1; + if (num > rem) + return S_FALSE; + pos += num; + do + { + if (!m_InStream.ReadByte(b)) + return S_FALSE; + m_OutWindowStream.PutByte(b); + } + while (--num); + continue; + } + Byte b1; + if (!m_InStream.ReadByte(b1)) + return S_FALSE; + + UInt32 len, dist; + + if (b & 0x40) + { + len = (UInt32)b - 0x40 + 4; + Byte b2; + if (!m_InStream.ReadByte(b2)) + return S_FALSE; + dist = ((UInt32)b1 << 8) + b2; + } + else + { + len = ((UInt32)b >> 2) + 3; + dist = (((UInt32)b & 3) << 8) + b1; + } + + if (/* dist >= pos || */ len > rem) + return S_FALSE; + if (!m_OutWindowStream.CopyBlock(dist, len)) + return S_FALSE; + pos += len; + } + if (*inSize != m_InStream.GetProcessedSize()) + return S_FALSE; + coderReleaser.NeedFlush = false; + return m_OutWindowStream.Flush(); + + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + + + +struct CDecoders +{ + CMyComPtr2 zlib; + CMyComPtr2 bzip2; + CMyComPtr2 lzfse; + CMyUniquePtr xz; + CMyUniquePtr adc; + + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const CBlock &block, const UInt64 *unpSize, ICompressProgressInfo *progress); +}; + +HRESULT CDecoders::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const CBlock &block, const UInt64 *unpSize, ICompressProgressInfo *progress) +{ + HRESULT hres; + UInt64 processed; + switch (block.Type) + { + case METHOD_ADC: + adc.Create_if_Empty(); + return adc->Code(inStream, outStream, &block.PackSize, unpSize, progress); + case METHOD_LZFSE: + lzfse.Create_if_Empty(); + return lzfse.Interface()->Code(inStream, outStream, &block.PackSize, unpSize, progress); + case METHOD_ZLIB: + zlib.Create_if_Empty(); + hres = zlib.Interface()->Code(inStream, outStream, NULL, unpSize, progress); + processed = zlib->GetInputProcessedSize(); + break; + case METHOD_BZIP2: + bzip2.Create_if_Empty(); + hres = bzip2.Interface()->Code(inStream, outStream, NULL, unpSize, progress); + processed = bzip2->GetInputProcessedSize(); + break; + case METHOD_XZ: + xz.Create_if_Empty(); + hres = xz->Decode(inStream, outStream, unpSize, true, progress); + processed = xz->Stat.InSize; + break; + default: + return E_NOTIMPL; + } + if (hres == S_OK && processed != block.PackSize) + hres = S_FALSE; + return hres; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _files.Size() +#ifdef DMG_SHOW_RAW + + _extras.Size() +#endif + ; + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; +#ifdef DMG_SHOW_RAW + if (index >= _files.Size()) + totalSize += _extras[index - _files.Size()].Data.Size(); + else +#endif + totalSize += _files[index].Size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + const size_t kZeroBufSize = 1 << 14; + CAlignedBuffer1 zeroBuf(kZeroBufSize); + memset(zeroBuf, 0, kZeroBufSize); + + CDecoders decoders; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_inStream); + + UInt64 total_PackSize = 0; + UInt64 total_UnpackSize = 0; + UInt64 cur_PackSize = 0; + UInt64 cur_UnpackSize = 0; + + for (i = 0;; i++, + total_PackSize += cur_PackSize, + total_UnpackSize += cur_UnpackSize) + { + lps->InSize = total_PackSize; + lps->OutSize = total_UnpackSize; + cur_PackSize = 0; + cur_UnpackSize = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + return S_OK; + + Int32 opRes = NExtract::NOperationResult::kOK; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + +#ifdef DMG_SHOW_RAW + if (index >= _files.Size()) + { + const CByteBuffer &buf = _extras[index - _files.Size()].Data; + if (realOutStream) + RINOK(WriteStream(realOutStream, buf, buf.Size())) + cur_PackSize = cur_UnpackSize = buf.Size(); + } + else +#endif + { + const CFile &item = _files[index]; + cur_PackSize = item.PackSize; + cur_UnpackSize = item.Size; + + if (!item.IsCorrect) + opRes = NExtract::NOperationResult::kHeadersError; + else + { + CMyComPtr2_Create outCrcStream; + outCrcStream->SetStream(realOutStream); + // realOutStream.Release(); + const bool needCrc = item.Checksum.IsCrc32(); + outCrcStream->Init(needCrc); + + CMyComPtr2_Create outStream; + outStream->SetStream(outCrcStream); + + UInt64 unpPos = 0; + UInt64 packPos = 0; + + FOR_VECTOR (blockIndex, item.Blocks) + { + lps->InSize = total_PackSize + packPos; + lps->OutSize = total_UnpackSize + unpPos; + RINOK(lps->SetCur()) + + const CBlock &block = item.Blocks[blockIndex]; + // if (!block.ThereAreDataInBlock()) continue; + + packPos += block.PackSize; + if (block.UnpPos != unpPos) + { + opRes = NExtract::NOperationResult::kHeadersError; + break; + } + + RINOK(InStream_SeekSet(_inStream, _startPos + _dataForkPair.Offset + item.StartPackPos + block.PackPos)) + inStream->Init(block.PackSize); + + const UInt64 unpSize = item.GetUnpackSize_of_Block(blockIndex); + + outStream->Init(unpSize); + HRESULT res = S_OK; + + outCrcStream->EnableCalc(needCrc && block.NeedCrc()); + + if (block.IsZeroMethod()) + { + if (block.PackSize != 0) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else if (block.Type == METHOD_COPY) + { + if (unpSize != block.PackSize) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + res = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + } + else + res = decoders.Code(inStream, outStream, block, &unpSize, lps); + + if (res != S_OK) + { + if (res != S_FALSE) + { + if (res != E_NOTIMPL) + return res; + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + if (opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; + } + + unpPos += unpSize; + + if (!outStream->IsFinishedOK()) + { + if (!block.IsZeroMethod() && opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; + + for (unsigned k = 0;;) + { + const UInt64 rem = outStream->GetRem(); + if (rem == 0) + break; + size_t size = kZeroBufSize; + if (size > rem) + size = (size_t)rem; + RINOK(WriteStream(outStream, zeroBuf, size)) + k++; + if ((k & 0xfff) == 0) + { + lps->OutSize = total_UnpackSize + unpPos - outStream->GetRem(); + RINOK(lps->SetCur()) + } + } + } + } + if (needCrc && opRes == NExtract::NOperationResult::kOK) + { + if (outCrcStream->GetCRC() != item.Checksum.GetCrc32()) + opRes = NExtract::NOperationResult::kCRCError; + } + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + + COM_TRY_END +} + + + + +struct CChunk +{ + int BlockIndex; + UInt64 AccessMark; + Byte *Buf; + size_t BufSize; + + void Free() + { + z7_AlignedFree(Buf); + Buf = NULL; + BufSize = 0; + } + void Alloc(size_t size) + { + Buf = (Byte *)z7_AlignedAlloc(size); + } +}; + + +Z7_CLASS_IMP_IInStream( + CInStream +) + bool _errorMode; + UInt64 _virtPos; + int _latestChunk; + int _latestBlock; + UInt64 _accessMark; + UInt64 _chunks_TotalSize; + CRecordVector _chunks; + +public: + CMyComPtr Stream; + const CFile *File; + UInt64 Size; +private: + UInt64 _startPos; + + ~CInStream(); + CMyComPtr2 outStream; + CMyComPtr2 inStream; + CDecoders decoders; +public: + + // HRESULT + void Init(UInt64 startPos) + { + _errorMode = false; + _startPos = startPos; + _virtPos = 0; + _latestChunk = -1; + _latestBlock = -1; + _accessMark = 0; + _chunks_TotalSize = 0; + + inStream.Create_if_Empty(); + inStream->SetStream(Stream); + + outStream.Create_if_Empty(); + // return S_OK; + } +}; + + +CInStream::~CInStream() +{ + unsigned i = _chunks.Size(); + while (i) + _chunks[--i].Free(); +} + +static unsigned FindBlock(const CRecordVector &blocks, UInt64 pos) +{ + unsigned left = 0, right = blocks.Size(); + for (;;) + { + const unsigned mid = (left + right) / 2; + if (mid == left) + return left; + if (pos < blocks[mid].UnpPos) + right = mid; + else + left = mid; + } +} + +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + // COM_TRY_BEGIN + try { + + if (_errorMode) + return E_OUTOFMEMORY; + + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_virtPos >= Size) + return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL; + { + const UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + + if (_latestBlock >= 0) + { + const CBlock &block = File->Blocks[(unsigned)_latestBlock]; + if (_virtPos < block.UnpPos || + _virtPos - block.UnpPos >= File->GetUnpackSize_of_Block((unsigned)_latestBlock)) + _latestBlock = -1; + } + + if (_latestBlock < 0) + { + _latestChunk = -1; + const unsigned blockIndex = FindBlock(File->Blocks, _virtPos); + const CBlock &block = File->Blocks[blockIndex]; + const UInt64 unpSize = File->GetUnpackSize_of_Block(blockIndex); + + if (block.NeedAllocateBuffer() + && unpSize <= k_Chunk_Size_MAX) + { + unsigned i = 0; + { + unsigned numChunks = _chunks.Size(); + if (numChunks) + { + const CChunk *chunk = _chunks.ConstData(); + do + { + if (chunk->BlockIndex == (int)blockIndex) + break; + chunk++; + } + while (--numChunks); + i = _chunks.Size() - numChunks; + } + } + if (i != _chunks.Size()) + _latestChunk = (int)i; + else + { + unsigned chunkIndex; + for (;;) + { + if (_chunks.IsEmpty() || + (_chunks.Size() < k_NumChunks_MAX + && _chunks_TotalSize + unpSize <= k_Chunks_TotalSize_MAX)) + { + CChunk chunk; + chunk.Buf = NULL; + chunk.BufSize = 0; + chunk.BlockIndex = -1; + chunk.AccessMark = 0; + chunkIndex = _chunks.Add(chunk); + break; + } + chunkIndex = 0; + if (_chunks.Size() == 1) + break; + { + const CChunk *chunks = _chunks.ConstData(); + UInt64 accessMark_min = chunks[chunkIndex].AccessMark; + const unsigned numChunks = _chunks.Size(); + for (i = 1; i < numChunks; i++) + { + if (chunks[i].AccessMark < accessMark_min) + { + chunkIndex = i; + accessMark_min = chunks[i].AccessMark; + } + } + } + { + CChunk &chunk = _chunks[chunkIndex]; + const UInt64 newTotalSize = _chunks_TotalSize - chunk.BufSize; + if (newTotalSize + unpSize <= k_Chunks_TotalSize_MAX) + break; + _chunks_TotalSize = newTotalSize; + chunk.Free(); + } + // we have called chunk.Free() before, because + // _chunks.Delete() doesn't call chunk.Free(). + _chunks.Delete(chunkIndex); + PRF(printf("\n++num_chunks=%u, _chunks_TotalSize = %u\n", (unsigned)_chunks.Size(), (unsigned)_chunks_TotalSize);) + } + + CChunk &chunk = _chunks[chunkIndex]; + chunk.BlockIndex = -1; + chunk.AccessMark = 0; + + if (chunk.BufSize < unpSize) + { + _chunks_TotalSize -= chunk.BufSize; + chunk.Free(); + // if (unpSize > k_Chunk_Size_MAX) return E_FAIL; + chunk.Alloc((size_t)unpSize); + if (!chunk.Buf) + return E_OUTOFMEMORY; + chunk.BufSize = (size_t)unpSize; + _chunks_TotalSize += chunk.BufSize; + } + + RINOK(InStream_SeekSet(Stream, _startPos + File->StartPackPos + block.PackPos)) + + inStream->Init(block.PackSize); +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + if (block.Type == METHOD_COPY) + { + if (block.PackSize != unpSize) + return E_FAIL; + RINOK(ReadStream_FAIL(inStream, chunk.Buf, (size_t)unpSize)) + } + else +#endif + { + outStream->Init(chunk.Buf, (size_t)unpSize); + RINOK(decoders.Code(inStream, outStream, block, &unpSize, NULL)) + if (outStream->GetPos() != unpSize) + return E_FAIL; + } + chunk.BlockIndex = (int)blockIndex; + _latestChunk = (int)chunkIndex; + } + + _chunks[_latestChunk].AccessMark = _accessMark++; + } + + _latestBlock = (int)blockIndex; + } + + const CBlock &block = File->Blocks[(unsigned)_latestBlock]; + const UInt64 offset = _virtPos - block.UnpPos; + { + const UInt64 rem = File->GetUnpackSize_of_Block((unsigned)_latestBlock) - offset; + if (size > rem) + size = (UInt32)rem; + if (size == 0) // it's unexpected case. but we check it. + return S_OK; + } + HRESULT res = S_OK; + + if (block.IsZeroMethod()) + memset(data, 0, size); + else if (_latestChunk >= 0) + memcpy(data, _chunks[_latestChunk].Buf + (size_t)offset, size); + else + { + if (block.Type != METHOD_COPY) + return E_FAIL; + RINOK(InStream_SeekSet(Stream, _startPos + File->StartPackPos + block.PackPos + offset)) + res = Stream->Read(data, size, &size); + } + + _virtPos += size; + if (processedSize) + *processedSize = size; + return res; + // COM_TRY_END + } + catch(...) + { + _errorMode = true; + return E_OUTOFMEMORY; + } +} + + +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + +#ifdef DMG_SHOW_RAW + if (index >= _files.Size()) + return S_FALSE; +#endif + + CMyComPtr2 spec; + spec.Create_if_Empty(); + spec->File = &_files[index]; + const CFile &file = *spec->File; + + if (!file.IsCorrect) + return S_FALSE; + + FOR_VECTOR (i, file.Blocks) + { + const CBlock &block = file.Blocks[i]; + if (!block.NeedAllocateBuffer()) + continue; + + switch (block.Type) + { +#ifdef Z7_DMG_USE_CACHE_FOR_COPY_BLOCKS + case METHOD_COPY: + break; +#endif + case METHOD_ADC: + case METHOD_ZLIB: + case METHOD_BZIP2: + case METHOD_LZFSE: + case METHOD_XZ: + // case METHOD_END: + if (file.GetUnpackSize_of_Block(i) > k_Chunk_Size_MAX) + return S_FALSE; + break; + default: + return S_FALSE; + } + } + + spec->Stream = _inStream; + spec->Size = spec->File->Size; + // RINOK( + spec->Init(_startPos + _dataForkPair.Offset); + *stream = spec.Detach(); + return S_OK; + + COM_TRY_END +} + +REGISTER_ARC_I( + "Dmg", "dmg", NULL, 0xE4, + k_Signature, + 0, + NArcInfoFlags::kBackwardOpen | + NArcInfoFlags::kUseGlobalOffset, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ElfHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ElfHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ElfHandler.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ElfHandler.cpp 2024-06-28 07:00:00.000000000 +0000 @@ -1,975 +1,1284 @@ -// ElfHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.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" - -using namespace NWindows; - -static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); } -static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } -static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); } - -#define G16(offs, v) v = Get16(p + (offs), be) -#define G32(offs, v) v = Get32(p + (offs), be) -#define G64(offs, v) v = Get64(p + (offs), be) - -namespace NArchive { -namespace NElf { - -/* - ELF Structure for most files (real order can be different): - Header - Program (segment) header table (used at runtime) - Segment1 (Section ... Section) - Segment2 - ... - SegmentN - Section header table (the data for linking and relocation) -*/ - -#define ELF_CLASS_32 1 -#define ELF_CLASS_64 2 - -#define ELF_DATA_2LSB 1 -#define ELF_DATA_2MSB 2 - -static const UInt32 kHeaderSize32 = 0x34; -static const UInt32 kHeaderSize64 = 0x40; - -static const UInt32 kSegmentSize32 = 0x20; -static const UInt32 kSegmentSize64 = 0x38; - -static const UInt32 kSectionSize32 = 0x28; -static const UInt32 kSectionSize64 = 0x40; - -struct CHeader -{ - bool Mode64; - bool Be; - Byte Os; - Byte AbiVer; - - UInt16 Type; - UInt16 Machine; - // UInt32 Version; - - // UInt64 EntryVa; - UInt64 ProgOffset; - UInt64 SectOffset; - UInt32 Flags; - UInt16 HeaderSize; - UInt16 SegmentEntrySize; - UInt16 NumSegments; - UInt16 SectionEntrySize; - UInt16 NumSections; - UInt16 NamesSectIndex; - - bool Parse(const Byte *buf); - - UInt64 GetHeadersSize() const { return (UInt64)HeaderSize + - (UInt32)NumSegments * SegmentEntrySize + - (UInt32)NumSections * SectionEntrySize; } -}; - -bool CHeader::Parse(const Byte *p) -{ - switch (p[4]) - { - case ELF_CLASS_32: Mode64 = false; break; - case ELF_CLASS_64: Mode64 = true; break; - default: return false; - } - bool be; - switch (p[5]) - { - case ELF_DATA_2LSB: be = false; break; - case ELF_DATA_2MSB: be = true; break; - default: return false; - } - Be = be; - if (p[6] != 1) // Version - return false; - Os = p[7]; - AbiVer = p[8]; - for (int i = 9; i < 16; i++) - if (p[i] != 0) - return false; - - G16(0x10, Type); - G16(0x12, Machine); - if (Get32(p + 0x14, be) != 1) // Version - return false; - - if (Mode64) - { - // G64(0x18, EntryVa); - G64(0x20, ProgOffset); - G64(0x28, SectOffset); - p += 0x30; - } - else - { - // G32(0x18, EntryVa); - G32(0x1C, ProgOffset); - G32(0x20, SectOffset); - p += 0x24; - } - - G32(0, Flags); - G16(4, HeaderSize); - if (HeaderSize != (Mode64 ? kHeaderSize64 : kHeaderSize32)) - return false; - - G16(6, SegmentEntrySize); - G16(8, NumSegments); - G16(10, SectionEntrySize); - G16(12, NumSections); - G16(14, NamesSectIndex); - - if (ProgOffset < HeaderSize && (ProgOffset != 0 || NumSegments != 0)) return false; - if (SectOffset < HeaderSize && (SectOffset != 0 || NumSections != 0)) return false; - - if (SegmentEntrySize == 0) { if (NumSegments != 0) return false; } - else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false; - - if (SectionEntrySize == 0) { if (NumSections != 0) return false; } - else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false; - - return true; -} - -// The program header table itself. - -#define PT_PHDR 6 - -static const char *g_SegnmentTypes[] = -{ - "Unused", - "Loadable segment", - "Dynamic linking tables", - "Program interpreter path name", - "Note section", - "SHLIB", - "Program header table", - "TLS" -}; - -static const CUInt32PCharPair g_SegmentFlags[] = -{ - { 0, "Execute" }, - { 1, "Write" }, - { 2, "Read" } -}; - -struct CSegment -{ - UInt32 Type; - UInt32 Flags; - UInt64 Offset; - UInt64 Va; - // UInt64 Pa; - UInt64 Size; - UInt64 VSize; - UInt64 Align; - - void UpdateTotalSize(UInt64 &totalSize) - { - UInt64 t = Offset + Size; - if (totalSize < t) - totalSize = t; - } - void Parse(const Byte *p, bool mode64, bool be); -}; - -void CSegment::Parse(const Byte *p, bool mode64, bool be) -{ - G32(0, Type); - if (mode64) - { - G32(4, Flags); - G64(8, Offset); - G64(0x10, Va); - // G64(0x18, Pa); - G64(0x20, Size); - G64(0x28, VSize); - G64(0x30, Align); - } - else - { - G32(4, Offset); - G32(8, Va); - // G32(0x0C, Pa); - G32(0x10, Size); - G32(0x14, VSize); - G32(0x18, Flags); - G32(0x1C, Align); - } -} - -// Section_index = 0 means NO section - -#define SHN_UNDEF 0 - -// Section types - -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_UNKNOWN12 12 -#define SHT_UNKNOWN13 13 -#define SHT_INIT_ARRAY 14 -#define SHT_FINI_ARRAY 15 -#define SHT_PREINIT_ARRAY 16 -#define SHT_GROUP 17 -#define SHT_SYMTAB_SHNDX 18 - - -static const CUInt32PCharPair g_SectTypes[] = -{ - { 0, "NULL" }, - { 1, "PROGBITS" }, - { 2, "SYMTAB" }, - { 3, "STRTAB" }, - { 4, "RELA" }, - { 5, "HASH" }, - { 6, "DYNAMIC" }, - { 7, "NOTE" }, - { 8, "NOBITS" }, - { 9, "REL" }, - { 10, "SHLIB" }, - { 11, "DYNSYM" }, - { 12, "UNKNOWN12" }, - { 13, "UNKNOWN13" }, - { 14, "INIT_ARRAY" }, - { 15, "FINI_ARRAY" }, - { 16, "PREINIT_ARRAY" }, - { 17, "GROUP" }, - { 18, "SYMTAB_SHNDX" }, - { 0x6ffffff5, "GNU_ATTRIBUTES" }, - { 0x6ffffff6, "GNU_HASH" }, - { 0x6ffffffd, "GNU_verdef" }, - { 0x6ffffffe, "GNU_verneed" }, - { 0x6fffffff, "GNU_versym" }, - // { 0x70000001, "X86_64_UNWIND" }, - { 0x70000001, "ARM_EXIDX" }, - { 0x70000002, "ARM_PREEMPTMAP" }, - { 0x70000003, "ARM_ATTRIBUTES" }, - { 0x70000004, "ARM_DEBUGOVERLAY" }, - { 0x70000005, "ARM_OVERLAYSECTION" } -}; - -static const CUInt32PCharPair g_SectionFlags[] = -{ - { 0, "WRITE" }, - { 1, "ALLOC" }, - { 2, "EXECINSTR" }, - - { 4, "MERGE" }, - { 5, "STRINGS" }, - { 6, "INFO_LINK" }, - { 7, "LINK_ORDER" }, - { 8, "OS_NONCONFORMING" }, - { 9, "GROUP" }, - { 10, "TLS" }, - { 11, "CP_SECTION" }, - { 12, "DP_SECTION" }, - { 13, "XCORE_SHF_CP_SECTION" }, - { 28, "64_LARGE" }, -}; - -struct CSection -{ - UInt32 Name; - UInt32 Type; - UInt64 Flags; - UInt64 Va; - UInt64 Offset; - UInt64 VSize; - UInt32 Link; - UInt32 Info; - UInt64 AddrAlign; - UInt64 EntSize; - - UInt64 GetSize() const { return Type == SHT_NOBITS ? 0 : VSize; } - - void UpdateTotalSize(UInt64 &totalSize) - { - UInt64 t = Offset + GetSize(); - if (totalSize < t) - totalSize = t; - } - bool Parse(const Byte *p, bool mode64, bool be); -}; - -bool CSection::Parse(const Byte *p, bool mode64, bool be) -{ - G32(0, Name); - G32(4, Type); - if (mode64) - { - G64(0x08, Flags); - G64(0x10, Va); - G64(0x18, Offset); - G64(0x20, VSize); - G32(0x28, Link); - G32(0x2C, Info); - G64(0x30, AddrAlign); - G64(0x38, EntSize); - } - else - { - G32(0x08, Flags); - G32(0x0C, Va); - G32(0x10, Offset); - G32(0x14, VSize); - G32(0x18, Link); - G32(0x1C, Info); - G32(0x20, AddrAlign); - G32(0x24, EntSize); - } - if (EntSize >= ((UInt32)1 << 31)) - return false; - if (EntSize >= ((UInt32)1 << 10) && - EntSize >= VSize && - VSize != 0) - return false; - return true; -} - -static const CUInt32PCharPair g_Machines[] = -{ - { 0, "None" }, - { 1, "AT&T WE 32100" }, - { 2, "SPARC" }, - { 3, "Intel 386" }, - { 4, "Motorola 68000" }, - { 5, "Motorola 88000" }, - { 6, "Intel 486" }, - { 7, "Intel i860" }, - { 8, "MIPS" }, - { 9, "IBM S/370" }, - { 10, "MIPS RS3000 LE" }, - { 11, "RS6000" }, - - { 15, "PA-RISC" }, - { 16, "nCUBE" }, - { 17, "Fujitsu VPP500" }, - { 18, "SPARC 32+" }, - { 19, "Intel i960" }, - { 20, "PowerPC" }, - { 21, "PowerPC 64-bit" }, - { 22, "IBM S/390" }, - { 23, "SPU" }, - - { 36, "NEX v800" }, - { 37, "Fujitsu FR20" }, - { 38, "TRW RH-32" }, - { 39, "Motorola RCE" }, - { 40, "ARM" }, - { 41, "Alpha" }, - { 42, "Hitachi SH" }, - { 43, "SPARC-V9" }, - { 44, "Siemens Tricore" }, - { 45, "ARC" }, - { 46, "H8/300" }, - { 47, "H8/300H" }, - { 48, "H8S" }, - { 49, "H8/500" }, - { 50, "IA-64" }, - { 51, "Stanford MIPS-X" }, - { 52, "Motorola ColdFire" }, - { 53, "M68HC12" }, - { 54, "Fujitsu MMA" }, - { 55, "Siemens PCP" }, - { 56, "Sony nCPU" }, - { 57, "Denso NDR1" }, - { 58, "Motorola StarCore" }, - { 59, "Toyota ME16" }, - { 60, "ST100" }, - { 61, "Advanced Logic TinyJ" }, - { 62, "AMD64" }, - { 63, "Sony DSP" }, - - - { 66, "Siemens FX66" }, - { 67, "ST9+" }, - { 68, "ST7" }, - { 69, "MC68HC16" }, - { 70, "MC68HC11" }, - { 71, "MC68HC08" }, - { 72, "MC68HC05" }, - { 73, "Silicon Graphics SVx" }, - { 74, "ST19" }, - { 75, "Digital VAX" }, - { 76, "Axis CRIS" }, - { 77, "Infineon JAVELIN" }, - { 78, "Element 14 FirePath" }, - { 79, "LSI ZSP" }, - { 80, "MMIX" }, - { 81, "HUANY" }, - { 82, "SiTera Prism" }, - { 83, "Atmel AVR" }, - { 84, "Fujitsu FR30" }, - { 85, "Mitsubishi D10V" }, - { 86, "Mitsubishi D30V" }, - { 87, "NEC v850" }, - { 88, "Mitsubishi M32R" }, - { 89, "Matsushita MN10300" }, - { 90, "Matsushita MN10200" }, - { 91, "picoJava" }, - { 92, "OpenRISC" }, - { 93, "ARC Tangent-A5" }, - { 94, "Tensilica Xtensa" }, - { 95, "Alphamosaic VideoCore" }, - { 96, "Thompson MM GPP" }, - { 97, "National Semiconductor 32K" }, - { 98, "Tenor Network TPC" }, - { 99, "Trebia SNP 1000" }, - { 100, "ST200" }, - { 101, "Ubicom IP2xxx" }, - { 102, "MAX" }, - { 103, "NS CompactRISC" }, - { 104, "Fujitsu F2MC16" }, - { 105, "TI msp430" }, - { 106, "Blackfin (DSP)" }, - { 107, "SE S1C33" }, - { 108, "Sharp embedded" }, - { 109, "Arca RISC" }, - { 110, "Unicore" }, - { 111, "eXcess" }, - { 112, "DXP" }, - { 113, "Altera Nios II" }, - { 114, "NS CRX" }, - { 115, "Motorola XGATE" }, - { 116, "Infineon C16x/XC16x" }, - { 117, "Renesas M16C" }, - { 118, "Microchip Technology dsPIC30F" }, - { 119, "Freescale CE" }, - { 120, "Renesas M32C" }, - - { 131, "Altium TSK3000" }, - { 132, "Freescale RS08" }, - { 133, "Analog Devices SHARC" }, - { 134, "Cyan Technology eCOG2" }, - { 135, "Sunplus S+core7 RISC" }, - { 136, "NJR 24-bit DSP" }, - { 137, "Broadcom VideoCore III" }, - { 138, "Lattice FPGA" }, - { 139, "SE C17" }, - { 140, "TI TMS320C6000" }, - { 141, "TI TMS320C2000" }, - { 142, "TI TMS320C55x" }, - - { 160, "STM 64bit VLIW Data Signal" }, - { 161, "Cypress M8C" }, - { 162, "Renesas R32C" }, - { 163, "NXP TriMedia" }, - { 164, "Qualcomm Hexagon" }, - { 165, "Intel 8051" }, - { 166, "STMicroelectronics STxP7x" }, - { 167, "Andes" }, - { 168, "Cyan Technology eCOG1X" }, - { 169, "Dallas Semiconductor MAXQ30" }, - { 170, "NJR 16-bit DSP" }, - { 171, "M2000" }, - { 172, "Cray NV2" }, - { 173, "Renesas RX" }, - { 174, "Imagination Technologies META" }, - { 175, "MCST Elbrus" }, - { 176, "Cyan Technology eCOG16" }, - { 177, "National Semiconductor CR16" }, - { 178, "Freescale ETPUnit" }, - { 179, "Infineon SLE9X" }, - { 180, "Intel L10M" }, - { 181, "Intel K10M" }, - - { 183, "ARM64" }, - - { 185, "Atmel AVR32" }, - { 186, "STM8" }, - { 187, "Tilera TILE64" }, - { 188, "Tilera TILEPro" }, - { 189, "Xilinx MicroBlaze" }, - { 190, "NVIDIA CUDA" }, - { 191, "Tilera TILE-Gx" }, - { 192, "CloudShield" }, - { 193, "KIPO-KAIST Core-A 1st" }, - { 194, "KIPO-KAIST Core-A 2nd" }, - { 195, "Synopsys ARCompact V2" }, - { 196, "Open8" }, - { 197, "Renesas RL78" }, - { 198, "Broadcom VideoCore V" }, - { 199, "Renesas 78KOR" }, - { 200, "Freescale 56800EX" }, - - { 47787, "Xilinx MicroBlaze" }, - // { 0x9026, "Alpha" } -}; - -static const CUInt32PCharPair g_OS[] = -{ - { 0, "None" }, - { 1, "HP-UX" }, - { 2, "NetBSD" }, - { 3, "Linux" }, - { 4, "Hurd" }, - - { 6, "Solaris" }, - { 7, "AIX" }, - { 8, "IRIX" }, - { 9, "FreeBSD" }, - { 10, "TRU64" }, - { 11, "Novell Modesto" }, - { 12, "OpenBSD" }, - { 13, "OpenVMS" }, - { 14, "HP NSK" }, - { 15, "AROS" }, - { 16, "FenixOS" }, - { 64, "Bare-metal TMS320C6000" }, - { 65, "Linux TMS320C6000" }, - { 97, "ARM" }, - { 255, "Standalone" } -}; - -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 - -static const char *g_Types[] = -{ - "None", - "Relocatable file", - "Executable file", - "Shared object file", - "Core file" -}; - -class CHandler: - public IInArchive, - public IArchiveAllowTail, - public CMyUnknownImp -{ - CRecordVector _segments; - CRecordVector _sections; - CByteBuffer _namesData; - CMyComPtr _inStream; - UInt64 _totalSize; - CHeader _header; - bool _headersError; - bool _allowTail; - - void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const; - HRESULT Open2(IInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(AllowTail)(Int32 allowTail); - - CHandler(): _allowTail(false) {} -}; - -void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const -{ - if (index >= _sections.Size()) - return; - const CSection §ion = _sections[index]; - UInt32 offset = section.Name; - if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */) - { - if (showNULL) - prop = "NULL"; - return; - } - const Byte *p = _namesData; - size_t size = _namesData.Size(); - for (size_t i = offset; i < size; i++) - if (p[i] == 0) - { - prop = (const char *)(p + offset); - return; - } -} - -static const Byte kArcProps[] = -{ - kpidCpu, - kpidBit64, - kpidBigEndian, - kpidHostOS, - kpidCharacts, - kpidHeadersSize, - kpidName -}; - -enum -{ - kpidLinkSection = kpidUserDefined, - kpidInfoSection -}; - -static const CStatProp kProps[] = -{ - { NULL, kpidPath, VT_BSTR }, - { NULL, kpidSize, VT_UI8 }, - { NULL, kpidVirtualSize, VT_UI8 }, - { NULL, kpidOffset, VT_UI8 }, - { NULL, kpidVa, VT_UI8 }, - { NULL, kpidType, VT_BSTR }, - { NULL, kpidCharacts, VT_BSTR } - , { "Link Section", kpidLinkSection, VT_BSTR} - , { "Info Section", kpidInfoSection, VT_BSTR} -}; - -IMP_IInArchive_Props_WITH_NAME -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _header.GetHeadersSize(); break; - case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break; - case kpidBigEndian: if (_header.Be) prop = _header.Be; break; - case kpidShortComment: - case kpidCpu: PAIR_TO_PROP(g_Machines, _header.Machine, prop); break; - case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break; - case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; - case kpidExtension: - { - const char *s = NULL; - if (_header.Type == ET_DYN) - s = "so"; - else if (_header.Type == ET_REL) - s = "o"; - if (s) - prop = s; - break; - } - // case kpidIsSelfExe: prop = (_header.Type != ET_DYN) && (_header.Type == ET_REL); break; - case kpidErrorFlags: - { - UInt32 flags = 0; - if (_headersError) flags |= kpv_ErrorFlags_HeadersError; - if (flags != 0) - prop = flags; - 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; - if (index < _segments.Size()) - { - const CSegment &item = _segments[index]; - switch (propID) - { - case kpidPath: - { - char sz[16]; - ConvertUInt32ToString(index, sz); - prop = sz; - break; - } - case kpidOffset: prop = item.Offset; break; - case kpidVa: prop = item.Va; break; - case kpidSize: - case kpidPackSize: prop = (UInt64)item.Size; break; - case kpidVirtualSize: prop = (UInt64)item.VSize; break; - case kpidType: TYPE_TO_PROP(g_SegnmentTypes, item.Type, prop); break; - case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break; - - } - } - else - { - index -= _segments.Size(); - const CSection &item = _sections[index]; - switch (propID) - { - case kpidPath: GetSectionName(index, prop, true); break; - case kpidOffset: prop = item.Offset; break; - case kpidVa: prop = item.Va; break; - case kpidSize: - case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break; - case kpidVirtualSize: prop = item.GetSize(); break; - case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break; - case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break; - case kpidLinkSection: GetSectionName(item.Link, prop, false); break; - case kpidInfoSection: GetSectionName(item.Info, prop, false); break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - const UInt32 kStartSize = kHeaderSize64; - Byte h[kStartSize]; - RINOK(ReadStream_FALSE(stream, h, kStartSize)); - if (h[0] != 0x7F || h[1] != 'E' || h[2] != 'L' || h[3] != 'F') - return S_FALSE; - if (!_header.Parse(h)) - return S_FALSE; - - _totalSize = _header.HeaderSize; - - bool addSegments = false; - bool addSections = false; - - if (_header.NumSections > 1) - addSections = true; - else - addSegments = true; - - if (_header.NumSegments != 0) - { - if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE; - RINOK(stream->Seek(_header.ProgOffset, STREAM_SEEK_SET, NULL)); - size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments; - - CByteArr buf(size); - - RINOK(ReadStream_FALSE(stream, buf, size)); - - UInt64 total = _header.ProgOffset + size; - if (_totalSize < total) - _totalSize = total; - - const Byte *p = buf; - - if (addSegments) - _segments.ClearAndReserve(_header.NumSegments); - for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize) - { - CSegment seg; - seg.Parse(p, _header.Mode64, _header.Be); - seg.UpdateTotalSize(_totalSize); - if (addSegments) - if (seg.Type != PT_PHDR) - _segments.AddInReserved(seg); - } - } - - if (_header.NumSections != 0) - { - if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE; - RINOK(stream->Seek(_header.SectOffset, STREAM_SEEK_SET, NULL)); - size_t size = (size_t)_header.SectionEntrySize * _header.NumSections; - - CByteArr buf(size); - - RINOK(ReadStream_FALSE(stream, buf, size)); - - UInt64 total = _header.SectOffset + size; - if (_totalSize < total) - _totalSize = total; - - const Byte *p = buf; - - if (addSections) - _sections.ClearAndReserve(_header.NumSections); - for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize) - { - CSection sect; - if (!sect.Parse(p, _header.Mode64, _header.Be)) - { - _headersError = true; - return S_FALSE; - } - sect.UpdateTotalSize(_totalSize); - if (addSections) - _sections.AddInReserved(sect); - } - } - - if (addSections) - { - if (_header.NamesSectIndex < _sections.Size()) - { - const CSection § = _sections[_header.NamesSectIndex]; - UInt64 size = sect.GetSize(); - if (size != 0 - && size < ((UInt64)1 << 31) - && (Int64)sect.Offset >= 0) - { - _namesData.Alloc((size_t)size); - RINOK(stream->Seek(sect.Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size)); - } - } - - /* - // we will not delete NULL sections, since we have links to section via indexes - for (int i = _sections.Size() - 1; i >= 0; i--) - if (_sections[i].Type == SHT_NULL) - _items.Delete(i); - */ - } - - if (!_allowTail) - { - UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - if (fileSize > _totalSize) - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(inStream)); - _inStream = inStream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _headersError = false; - - _inStream.Release(); - _segments.Clear(); - _sections.Clear(); - _namesData.Free(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _segments.Size() + _sections.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _segments.Size() + _sections.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - totalSize += (index < _segments.Size()) ? - _segments[index].Size : - _sections[index - _segments.Size()].GetSize(); - } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - UInt64 offset; - if (index < _segments.Size()) - { - const CSegment &item = _segments[index]; - currentItemSize = item.Size; - offset = item.Offset; - } - else - { - const CSection &item = _sections[index - _segments.Size()]; - currentItemSize = item.GetSize(); - offset = item.Offset; - } - - CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) -{ - _allowTail = IntToBool(allowTail); - return S_OK; -} - -static const Byte k_Signature[] = { 0x7F, 'E', 'L', 'F' }; - -REGISTER_ARC_I( - "ELF", "elf", 0, 0xDE, - k_Signature, - 0, - NArcInfoFlags::kPreArc, - NULL) - -}} +// ElfHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.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 Z7_ELF_SHOW_DETAILS + +using namespace NWindows; + +static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16a(p); return GetUi16a(p); } +static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32a(p); return GetUi32a(p); } +static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64a(p); return GetUi64a(p); } + +#define G16(offs, v) v = Get16(p + (offs), be) +#define G32(offs, v) v = Get32(p + (offs), be) +#define G64(offs, v) v = Get64(p + (offs), be) + +namespace NArchive { +namespace NElf { + +/* +ELF Structure example: +{ + Header + Program header table (is used at runtime) (list of segment metadata records) + { + Segment (Read) + Segment : PT_PHDR : header table itself + Segment : PT_INTERP + Segment : PT_NOTE + .rela.dyn (RELA, ALLOC) + Segment (Execute/Read) + .text section (PROGBITS, SHF_ALLOC | SHF_EXECINSTR) + Segment (Read) + .rodata (PROGBITS, SHF_ALLOC | SHF_WRITE) + Segment : PT_GNU_EH_FRAME + .eh_frame_hdr + .eh_frame + .gcc_except_table + ... + Segment (Write/Read) (VaSize > Size) + Segment (Read) : PT_GNU_RELRO + Segment (Write/Read) + .data + .bss (Size == 0) (VSize != 0) + } + .comment (VA == 0) + .shstrtab (VA == 0) + Section header table (the data for linking and relocation) +} + + Last top level segment contains .bss section that requires additional VA space. + So (VaSize > Size) for that segment. + + Segments can be unsorted (by offset) in table. + Top level segments has Type=PT_LOAD : "Loadable segment". + Top level segments usually are aligned for page size (4 KB). + Another segments (non PT_LOAD segments) are inside PT_LOAD segments. + + (VA-offset == 0) is possible for some sections and segments at the beginning of file. + (VA-offset == 4KB*N) for most sections and segments where (Size != 0), + (VA-offset != 4KB*N) for .bss section (last section), because (Size == 0), + and that section is not mapped from image file. + Some files contain additional "virtual" 4 KB page in VA space after + end of data of top level segments (PT_LOAD) before new top level segments. + So (VA-offset) value can increase by 4 KB step. +*/ + +#define ELF_CLASS_32 1 +#define ELF_CLASS_64 2 + +#define ELF_DATA_2LSB 1 +#define ELF_DATA_2MSB 2 + +static const unsigned kHeaderSize32 = 0x34; +static const unsigned kHeaderSize64 = 0x40; + +static const unsigned kSegmentSize32 = 0x20; +static const unsigned kSegmentSize64 = 0x38; + +static const unsigned kSectionSize32 = 0x28; +static const unsigned kSectionSize64 = 0x40; + +struct CHeader +{ + bool Mode64; + bool Be; + Byte Os; + Byte AbiVer; + + UInt16 Type; + UInt16 Machine; + // UInt32 Version; + + // UInt64 EntryVa; + UInt64 ProgOffset; + UInt64 SectOffset; + UInt32 Flags; + UInt16 HeaderSize; + UInt16 SegmentEntrySize; + UInt16 NumSegments; + UInt16 SectionEntrySize; + UInt16 NumSections; + UInt16 NamesSectIndex; + + bool Parse(const Byte *p); + + UInt32 GetHeadersSize() const { return (UInt32)HeaderSize + + (UInt32)NumSegments * SegmentEntrySize + + (UInt32)NumSections * SectionEntrySize; } +}; + +bool CHeader::Parse(const Byte *p) +{ + switch (p[4]) + { + case ELF_CLASS_32: Mode64 = false; break; + case ELF_CLASS_64: Mode64 = true; break; + default: return false; + } + bool be; + switch (p[5]) + { + case ELF_DATA_2LSB: be = false; break; + case ELF_DATA_2MSB: be = true; break; + default: return false; + } + Be = be; + if (p[6] != 1) // Version + return false; + Os = p[7]; + // AbiVer = p[8]; + for (int i = 9; i < 16; i++) + if (p[i] != 0) + return false; + + G16(0x10, Type); + G16(0x12, Machine); + if (Get32(p + 0x14, be) != 1) // Version + return false; + + if (Mode64) + { + // G64(0x18, EntryVa); + G64(0x20, ProgOffset); // == kHeaderSize64 == 0x40 usually + G64(0x28, SectOffset); + p += 0x30; + // we expect that fields are aligned + if (ProgOffset & 7) return false; + if (SectOffset & 7) return false; + } + else + { + // G32(0x18, EntryVa); + G32(0x1C, ProgOffset); // == kHeaderSize32 == 0x34 usually + G32(0x20, SectOffset); + p += 0x24; + if (ProgOffset & 3) return false; + if (SectOffset & 3) return false; + } + + G32(0, Flags); + G16(4, HeaderSize); + if (HeaderSize != (Mode64 ? kHeaderSize64 : kHeaderSize32)) + return false; + + G16(6, SegmentEntrySize); + G16(8, NumSegments); + G16(10, SectionEntrySize); + G16(12, NumSections); + G16(14, NamesSectIndex); + + if (ProgOffset < HeaderSize && (ProgOffset || NumSegments)) return false; + if (SectOffset < HeaderSize && (SectOffset || NumSections)) return false; + + if (SegmentEntrySize == 0) { if (NumSegments) return false; } + else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false; + + if (SectionEntrySize == 0) { if (NumSections) return false; } + else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false; + + return true; +} + + +#define PT_PHDR 6 // The program header table itself. +#define PT_GNU_STACK 0x6474e551 + +static const CUInt32PCharPair g_SegnmentTypes[] = +{ + { 0, "Unused" }, + { 1, "Loadable segment" }, + { 2, "Dynamic linking tables" }, + { 3, "Program interpreter path name" }, + { 4, "Note section" }, + { 5, "SHLIB" }, + { 6, "Program header table" }, + { 7, "TLS" }, + { 0x6474e550, "GNU_EH_FRAME" }, + { PT_GNU_STACK, "GNU_STACK" }, + { 0x6474e552, "GNU_RELRO" } +}; + + +static const char * const g_SegmentFlags[] = +{ + "Execute" + , "Write" + , "Read" +}; + +struct CSegment +{ + UInt32 Type; + UInt32 Flags; + UInt64 Offset; + UInt64 Va; + UInt64 Size; // size in file + UInt64 VSize; // size in memory +#ifdef Z7_ELF_SHOW_DETAILS + UInt64 Pa; // usually == Va, or == 0 + UInt64 Align; // if (Align != 0), condition must be met: + // (VSize % Align == Offset % Alig) +#endif + void UpdateTotalSize(UInt64 &totalSize) + { + const UInt64 t = Offset + Size; + if (totalSize < t) + totalSize = t; + } + void Parse(const Byte *p, bool mode64, bool be); +}; + +void CSegment::Parse(const Byte *p, bool mode64, bool be) +{ + G32(0, Type); + if (mode64) + { + G32(4, Flags); + G64(8, Offset); + G64(0x10, Va); + G64(0x20, Size); + G64(0x28, VSize); +#ifdef Z7_ELF_SHOW_DETAILS + G64(0x18, Pa); + G64(0x30, Align); +#endif + } + else + { + G32(4, Offset); + G32(8, Va); + G32(0x10, Size); + G32(0x14, VSize); + G32(0x18, Flags); +#ifdef Z7_ELF_SHOW_DETAILS + G32(0x0C, Pa); + G32(0x1C, Align); +#endif + } +} + +// Section_index = 0 means NO section + +#define SHN_UNDEF 0 + +// Section types + +/* +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +*/ +#define SHT_NOBITS 8 +/* +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_UNKNOWN12 12 +#define SHT_UNKNOWN13 13 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +*/ + +static const CUInt32PCharPair g_SectTypes[] = +{ + { 0, "NULL" }, + { 1, "PROGBITS" }, + { 2, "SYMTAB" }, + { 3, "STRTAB" }, + { 4, "RELA" }, + { 5, "HASH" }, + { 6, "DYNAMIC" }, + { 7, "NOTE" }, + { 8, "NOBITS" }, + { 9, "REL" }, + { 10, "SHLIB" }, + { 11, "DYNSYM" }, + { 12, "UNKNOWN12" }, + { 13, "UNKNOWN13" }, + { 14, "INIT_ARRAY" }, + { 15, "FINI_ARRAY" }, + { 16, "PREINIT_ARRAY" }, + { 17, "GROUP" }, + { 18, "SYMTAB_SHNDX" }, + + { 0x6ffffff5, "GNU_ATTRIBUTES" }, + { 0x6ffffff6, "GNU_HASH" }, + { 0x6ffffffd, "GNU_verdef" }, + { 0x6ffffffe, "GNU_verneed" }, + { 0x6fffffff, "GNU_versym" }, + // { 0x70000001, "X86_64_UNWIND" }, + { 0x70000001, "ARM_EXIDX" }, + { 0x70000002, "ARM_PREEMPTMAP" }, + { 0x70000003, "ARM_ATTRIBUTES" }, + { 0x70000004, "ARM_DEBUGOVERLAY" }, + { 0x70000005, "ARM_OVERLAYSECTION" } +}; + + +// SHF_ flags +static const CUInt32PCharPair g_SectionFlags[] = +{ + { 0, "WRITE" }, + { 1, "ALLOC" }, + { 2, "EXECINSTR" }, + + { 4, "MERGE" }, + { 5, "STRINGS" }, + { 6, "INFO_LINK" }, + { 7, "LINK_ORDER" }, + { 8, "OS_NONCONFORMING" }, + { 9, "GROUP" }, + { 10, "TLS" }, + { 11, "COMPRESSED" }, + { 12, "DP_SECTION" }, + { 13, "XCORE_SHF_CP_SECTION" }, + { 28, "64_LARGE" }, +}; + +struct CSection +{ + UInt32 Name; + UInt32 Type; + UInt64 Flags; + UInt64 Va; + UInt64 Offset; + UInt64 VSize; + UInt32 Link; + UInt32 Info; + UInt64 AddrAlign; + UInt64 EntSize; + + UInt64 GetSize() const { return Type == SHT_NOBITS ? 0 : VSize; } + + void UpdateTotalSize(UInt64 &totalSize) + { + const UInt64 t = Offset + GetSize(); + if (totalSize < t) + totalSize = t; + } + bool Parse(const Byte *p, bool mode64, bool be); +}; + +bool CSection::Parse(const Byte *p, bool mode64, bool be) +{ + G32(0, Name); + G32(4, Type); + if (mode64) + { + G64(0x08, Flags); + G64(0x10, Va); + G64(0x18, Offset); + G64(0x20, VSize); + G32(0x28, Link); + G32(0x2C, Info); + G64(0x30, AddrAlign); + G64(0x38, EntSize); + } + else + { + G32(0x08, Flags); + G32(0x0C, Va); + G32(0x10, Offset); + G32(0x14, VSize); + G32(0x18, Link); + G32(0x1C, Info); + G32(0x20, AddrAlign); + G32(0x24, EntSize); + } + if (EntSize >= ((UInt32)1 << 31)) + return false; + if (EntSize >= ((UInt32)1 << 10) && + EntSize >= VSize && + VSize != 0) + return false; + return true; +} + + +static const char * const g_Machines[] = +{ + "None" + , "AT&T WE 32100" + , "SPARC" + , "Intel 386" + , "Motorola 68000" + , "Motorola 88000" + , "Intel 486" + , "Intel i860" + , "MIPS" + , "IBM S/370" + , "MIPS RS3000 LE" + , "RS6000" + , NULL + , NULL + , NULL + , "PA-RISC" + , "nCUBE" + , "Fujitsu VPP500" + , "SPARC 32+" + , "Intel i960" + , "PowerPC" + , "PowerPC 64-bit" + , "IBM S/390" + , "SPU" + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , "NEX v800" + , "Fujitsu FR20" + , "TRW RH-32" + , "Motorola RCE" + , "ARM" + , "Alpha-STD" + , "Hitachi SH" + , "SPARC-V9" + , "Siemens Tricore" + , "ARC" + , "H8/300" + , "H8/300H" + , "H8S" + , "H8/500" + , "IA-64" + , "Stanford MIPS-X" + , "Motorola ColdFire" + , "M68HC12" + , "Fujitsu MMA" + , "Siemens PCP" + , "Sony nCPU" + , "Denso NDR1" + , "Motorola StarCore" + , "Toyota ME16" + , "ST100" + , "Advanced Logic TinyJ" + , "AMD64" + , "Sony DSP" + , NULL + , NULL + , "Siemens FX66" + , "ST9+" + , "ST7" + , "MC68HC16" + , "MC68HC11" + , "MC68HC08" + , "MC68HC05" + , "Silicon Graphics SVx" + , "ST19" + , "Digital VAX" + , "Axis CRIS" + , "Infineon JAVELIN" + , "Element 14 FirePath" + , "LSI ZSP" + , "MMIX" + , "HUANY" + , "SiTera Prism" + , "Atmel AVR" + , "Fujitsu FR30" + , "Mitsubishi D10V" + , "Mitsubishi D30V" + , "NEC v850" + , "Mitsubishi M32R" + , "Matsushita MN10300" + , "Matsushita MN10200" + , "picoJava" + , "OpenRISC" + , "ARC Tangent-A5" + , "Tensilica Xtensa" + , "Alphamosaic VideoCore" + , "Thompson MM GPP" + , "National Semiconductor 32K" + , "Tenor Network TPC" + , "Trebia SNP 1000" + , "ST200" + , "Ubicom IP2xxx" + , "MAX" + , "NS CompactRISC" + , "Fujitsu F2MC16" + , "TI msp430" + , "Blackfin (DSP)" + , "SE S1C33" + , "Sharp embedded" + , "Arca RISC" + , "Unicore" + , "eXcess" + , "DXP" + , "Altera Nios II" + , "NS CRX" + , "Motorola XGATE" + , "Infineon C16x/XC16x" + , "Renesas M16C" + , "Microchip Technology dsPIC30F" + , "Freescale CE" + , "Renesas M32C" + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , "Altium TSK3000" + , "Freescale RS08" + , "Analog Devices SHARC" + , "Cyan Technology eCOG2" + , "Sunplus S+core7 RISC" + , "NJR 24-bit DSP" + , "Broadcom VideoCore III" + , "Lattice FPGA" + , "SE C17" + , "TI TMS320C6000" + , "TI TMS320C2000" + , "TI TMS320C55x" + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , "STM 64bit VLIW Data Signal" + , "Cypress M8C" + , "Renesas R32C" + , "NXP TriMedia" + , "Qualcomm Hexagon" + , "Intel 8051" + , "STMicroelectronics STxP7x" + , "Andes" + , "Cyan Technology eCOG1X" + , "Dallas Semiconductor MAXQ30" + , "NJR 16-bit DSP" + , "M2000" + , "Cray NV2" + , "Renesas RX" + , "Imagination Technologies META" + , "MCST Elbrus" + , "Cyan Technology eCOG16" + , "National Semiconductor CR16" + , "Freescale ETPUnit" + , "Infineon SLE9X" + , "Intel L10M" + , "Intel K10M" + , NULL + , "ARM64" + , NULL + , "Atmel AVR32" + , "STM8" + , "Tilera TILE64" + , "Tilera TILEPro" + , "Xilinx MicroBlaze" + , "NVIDIA CUDA" + , "Tilera TILE-Gx" + , "CloudShield" + , "KIPO-KAIST Core-A 1st" + , "KIPO-KAIST Core-A 2nd" + , "Synopsys ARCompact V2" + , "Open8" + , "Renesas RL78" + , "Broadcom VideoCore V" + , "Renesas 78KOR" + , "Freescale 56800EX" // 200 +}; + +static const CUInt32PCharPair g_MachinePairs[] = +{ + { 243, "RISC-V" }, + { 258, "LoongArch" }, + { 0x9026, "Alpha" }, // EM_ALPHA_EXP, obsolete, (used by NetBSD/alpha) (written in the absence of an ABI) + { 0xbaab, "Xilinx MicroBlaze" } +}; + +static const CUInt32PCharPair g_OS[] = +{ + { 0, "None" }, + { 1, "HP-UX" }, + { 2, "NetBSD" }, + { 3, "Linux" }, + { 4, "Hurd" }, + + { 6, "Solaris" }, + { 7, "AIX" }, + { 8, "IRIX" }, + { 9, "FreeBSD" }, + { 10, "TRU64" }, + { 11, "Novell Modesto" }, + { 12, "OpenBSD" }, + { 13, "OpenVMS" }, + { 14, "HP NSK" }, + { 15, "AROS" }, + { 16, "FenixOS" }, + { 17, "CloudABI" }, + { 18, "OpenVOS" }, + { 64, "Bare-metal TMS320C6000" }, + { 65, "Linux TMS320C6000" }, + { 97, "ARM" }, + { 255, "Standalone" } +}; + +#define k_Machine_MIPS 8 +#define k_Machine_ARM 40 +#define k_Machine_RISCV 243 + +/* +#define EF_ARM_ABIMASK 0xFF000000 +#define EF_ARM_BE8 0x00800000 +#define EF_ARM_GCCMASK 0x00400FFF +#define EF_ARM_ABI_FLOAT_SOFT 0x00000200 +#define EF_ARM_ABI_FLOAT_HARD 0x00000400 +*/ + +static const CUInt32PCharPair g_ARM_Flags[] = +{ + { 1, "HasEntry" }, + { 9, "SF" }, + { 10, "HF" }, + { 23, "BE8" } +}; + + +static const CUInt32PCharPair g_MIPS_Flags[] = +{ + { 0, "NOREORDER" }, + { 1, "PIC" }, + { 2, "CPIC" }, + { 3, "XGOT" }, + { 4, "64BIT_WHIRL" }, + { 5, "ABI2" }, + { 6, "ABI_ON32" }, + { 10, "NAN2008" }, + { 25, "MicroMIPS" }, + { 26, "M16" }, + { 27, "MDMX" } +}; + +static const char * const g_RISCV_Flags[] = +{ + "RVC", + NULL, + NULL, + "RVE", + "TSO" +}; + + +// #define ET_NONE 0 +#define ET_REL 1 +// #define ET_EXEC 2 +#define ET_DYN 3 +// #define ET_CORE 4 + +static const char * const g_Types[] = +{ + "None" + , "Relocatable file" + , "Executable file" + , "Shared object file" + , "Core file" +}; + + + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveAllowTail +) + CRecordVector _segments; + CRecordVector _sections; + CByteBuffer _namesData; + CMyComPtr _inStream; + UInt64 _totalSize; + CHeader _header; + bool _headersError; + bool _allowTail; + bool _stackFlags_Defined; + UInt32 _stackFlags; + + void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const; + HRESULT Open2(IInStream *stream); +public: + CHandler(): _allowTail(false) {} +}; + +void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const +{ + if (index >= _sections.Size()) + prop = index; // it's possible for some file, but maybe it's ERROR case + else + { + const CSection §ion = _sections[index]; + const UInt32 offset = section.Name; + if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */) + { + if (showNULL) + prop = "NULL"; + return; + } + const Byte *p = _namesData; + const size_t size = _namesData.Size(); + for (size_t i = offset; i < size; i++) + if (p[i] == 0) + { + prop = (const char *)(p + offset); + return; + } + prop = "ERROR"; + } +} + +static const Byte kArcProps[] = +{ + kpidCpu, + kpidBit64, + kpidBigEndian, + kpidHostOS, + kpidCharacts, + kpidComment, + kpidHeadersSize +}; + +enum +{ + kpidLinkSection = kpidUserDefined, + kpidInfoSection, + kpidEntrySize +#ifdef Z7_ELF_SHOW_DETAILS + // , kpidAlign + , kpidPa + , kpidDelta + , kpidOffsetEnd +#endif +}; + +static const CStatProp kProps[] = +{ + { NULL, kpidPath, VT_BSTR }, + { NULL, kpidSize, VT_UI8 }, + { NULL, kpidVirtualSize, VT_UI8 }, + { NULL, kpidOffset, VT_UI8 }, + { NULL, kpidVa, VT_UI8 }, + { NULL, kpidType, VT_BSTR }, + { NULL, kpidCharacts, VT_BSTR } +#ifdef Z7_ELF_SHOW_DETAILS + // , { "Align", kpidAlign, VT_UI8 } + , { NULL, kpidClusterSize, VT_UI8 } + , { "PA", kpidPa, VT_UI8 } + , { "End offset", kpidOffsetEnd, VT_UI8 } + , { "Delta (VA-Offset)", kpidDelta, VT_UI8 } +#endif + , { "Entry Size", kpidEntrySize, VT_UI8} + , { "Link Section", kpidLinkSection, VT_BSTR} + , { "Info Section", kpidInfoSection, VT_BSTR} +}; + +IMP_IInArchive_Props_WITH_NAME +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _header.GetHeadersSize(); break; + case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break; + case kpidBigEndian: if (_header.Be) prop = _header.Be; break; + case kpidShortComment: + + case kpidCpu: + { + AString s; + if (_header.Machine < Z7_ARRAY_SIZE(g_Machines)) + { + const char *name = g_Machines[_header.Machine]; + if (name) + s = name; + } + if (s.IsEmpty()) + s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine); + UInt32 flags = _header.Flags; + if (flags) + { + s.Add_Space(); + if (_header.Machine == k_Machine_ARM) + { + s += FlagsToString(g_ARM_Flags, Z7_ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1)); + s += " ABI:"; + s.Add_UInt32(flags >> 24); + } + else if (_header.Machine == k_Machine_MIPS) + { + const UInt32 ver = flags >> 28; + s.Add_Char('v'); + s.Add_UInt32(ver); + flags &= ((UInt32)1 << 28) - 1; + const UInt32 abi = (flags >> 12) & 7; + if (abi) + { + s += " ABI:"; + s.Add_UInt32(abi); + } + flags &= ~((UInt32)7 << 12); + s.Add_Space(); + s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags); + } + else if (_header.Machine == k_Machine_RISCV) + { + s += "FLOAT_"; + const UInt32 fl = (flags >> 1) & 3; + /* + static const char * const g_RISCV_Flags_Float[] = + { "SOFT", "SINGLE", "DOUBLE", "QUAD" }; + s += g_RISCV_Flags_Float[fl]; + */ + if (fl) + s.Add_UInt32(16u << fl); + else + s += "SOFT"; + s.Add_Space(); + flags &= ~(UInt32)6; + s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags); + } +#if 0 +#define k_Machine_LOONGARCH 258 + else if (_header.Machine == k_Machine_LOONGARCH) + { + s += "ABI:"; + s.Add_UInt32((flags >> 6) & 3); + s.Add_Dot(); + s.Add_UInt32((flags >> 3) & 7); + s.Add_Dot(); +#if 1 + s.Add_UInt32(flags & 7); +#else + static const char k_LoongArch_Float_Type[8] = { '0', 's', 'f', 'd', '4' ,'5', '6', '7' }; + s.Add_Char(k_LoongArch_Float_Type[flags & 7]); +#endif + flags &= ~(UInt32)0xff; + if (flags) + { + s.Add_Colon(); + char sz[16]; + ConvertUInt32ToHex(flags, sz); + s += sz; + } + } +#endif + else + { + char sz[16]; + ConvertUInt32ToHex(flags, sz); + s += sz; + } + } + prop = s; + break; + } + + case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break; + case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; + case kpidComment: + { + AString s; + if (_stackFlags_Defined) + { + s += "STACK: "; + s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags); + s.Add_LF(); + /* + if (_header.EntryVa) + { + s += "Entry point: 0x"; + char temp[16 + 4]; + ConvertUInt64ToHex(_header.EntryVa, temp); + s += temp; + s.Add_LF(); + } + */ + } + if (_header.NumSegments) + { + s += "Segments: "; + s.Add_UInt32(_header.NumSegments); + s.Add_LF(); + } + if (_header.NumSections) + { + s += "Sections: "; + s.Add_UInt32(_header.NumSections); + s.Add_LF(); + } + prop = s; + break; + } + case kpidExtension: + { + const char *s = NULL; + if (_header.Type == ET_DYN) + s = "so"; + else if (_header.Type == ET_REL) + s = "o"; + if (s) + prop = s; + break; + } + // case kpidIsSelfExe: prop = (_header.Type != ET_DYN) && (_header.Type == ET_REL); break; + case kpidErrorFlags: + { + UInt32 flags = 0; + if (_headersError) flags |= kpv_ErrorFlags_HeadersError; + if (flags != 0) + prop = flags; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (index < _segments.Size()) + { + const CSegment &item = _segments[index]; + switch (propID) + { + case kpidPath: + { + char sz[16]; + ConvertUInt32ToString(index, sz); + prop = sz; + break; + } + case kpidOffset: prop = item.Offset; break; + case kpidVa: prop = item.Va; break; +#ifdef Z7_ELF_SHOW_DETAILS + case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break; + case kpidOffsetEnd: prop = item.Offset + item.Size; break; + case kpidPa: prop = item.Pa; break; + case kpidClusterSize: prop = item.Align; break; +#endif + case kpidSize: + case kpidPackSize: prop = (UInt64)item.Size; break; + case kpidVirtualSize: prop = (UInt64)item.VSize; break; + case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break; + } + } + else + { + index -= _segments.Size(); + const CSection &item = _sections[index]; + switch (propID) + { + case kpidPath: GetSectionName(index, prop, true); break; + case kpidOffset: prop = item.Offset; break; + case kpidVa: prop = item.Va; break; +#ifdef Z7_ELF_SHOW_DETAILS + case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break; + case kpidOffsetEnd: prop = item.Offset + item.GetSize(); break; +#endif + case kpidSize: + case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break; + case kpidVirtualSize: prop = item.GetSize(); break; + case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break; + // case kpidAlign: prop = item.Align; break; + case kpidLinkSection: GetSectionName(item.Link, prop, false); break; + case kpidInfoSection: GetSectionName(item.Info, prop, false); break; + case kpidEntrySize: prop = (UInt64)item.EntSize; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + { + const UInt32 kStartSize = kHeaderSize64; + UInt64 h64[kStartSize / 8]; + RINOK(ReadStream_FALSE(stream, h64, kStartSize)) + const Byte *h = (const Byte *)(const void *)h64; + if (GetUi32a(h) != 0x464c457f) + return S_FALSE; + if (!_header.Parse(h)) + return S_FALSE; + } + + _totalSize = _header.HeaderSize; + + bool addSegments = false; + bool addSections = false; + // first section usually is NULL (with zero offsets and zero sizes). + if (_header.NumSegments == 0 || _header.NumSections > 1) + addSections = true; + else + addSegments = true; +#ifdef Z7_ELF_SHOW_DETAILS + addSections = true; + addSegments = true; +#endif + + if (_header.NumSegments) + { + if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE; + RINOK(InStream_SeekSet(stream, _header.ProgOffset)) + const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments; + CByteArr buf(size); + RINOK(ReadStream_FALSE(stream, buf, size)) + { + const UInt64 total = _header.ProgOffset + size; + if (_totalSize < total) + _totalSize = total; + } + if (addSegments) + _segments.ClearAndReserve(_header.NumSegments); + const Byte *p = buf; + for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize) + { + CSegment seg; + seg.Parse(p, _header.Mode64, _header.Be); + seg.UpdateTotalSize(_totalSize); + if (seg.Type == PT_GNU_STACK && !_stackFlags_Defined) + { + _stackFlags = seg.Flags; + _stackFlags_Defined = true; + } + if (addSegments + // we don't show program header table segment + && seg.Type != PT_PHDR + ) + _segments.AddInReserved(seg); + } + } + + if (_header.NumSections) + { + if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE; + RINOK(InStream_SeekSet(stream, _header.SectOffset)) + const size_t size = (size_t)_header.SectionEntrySize * _header.NumSections; + CByteArr buf(size); + RINOK(ReadStream_FALSE(stream, buf, size)) + { + const UInt64 total = _header.SectOffset + size; + if (_totalSize < total) + _totalSize = total; + } + if (addSections) + _sections.ClearAndReserve(_header.NumSections); + const Byte *p = buf; + for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize) + { + CSection sect; + if (!sect.Parse(p, _header.Mode64, _header.Be)) + { + _headersError = true; + return S_FALSE; + } + sect.UpdateTotalSize(_totalSize); + if (addSections) + _sections.AddInReserved(sect); + } + } + + if (addSections) + { + if (_header.NamesSectIndex < _sections.Size()) + { + const CSection § = _sections[_header.NamesSectIndex]; + const UInt64 size = sect.GetSize(); + if (size && size < ((UInt64)1 << 31) + && (Int64)sect.Offset >= 0) + { + _namesData.Alloc((size_t)size); + RINOK(InStream_SeekSet(stream, sect.Offset)) + RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size)) + } + } + /* + // we cannot delete "NULL" sections, + // because we have links to sections array via indexes + for (int i = _sections.Size() - 1; i >= 0; i--) + if (_sections[i].Type == SHT_NULL) + _items.Delete(i); + */ + } + + if (!_allowTail) + { + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) + if (fileSize > _totalSize) + return S_FALSE; + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream)) + _inStream = inStream; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _headersError = false; + _stackFlags_Defined = false; + + _inStream.Release(); + _segments.Clear(); + _sections.Clear(); + _namesData.Free(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _segments.Size() + _sections.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _segments.Size() + _sections.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 += (index < _segments.Size()) ? + _segments[index].Size : + _sections[index - _segments.Size()].GetSize(); + } + RINOK(extractCallback->SetTotal(totalSize)) + + totalSize = 0; + UInt64 currentItemSize; + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_inStream); + + for (i = 0;; i++, totalSize += currentItemSize) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + UInt64 offset; + if (index < _segments.Size()) + { + const CSegment &item = _segments[index]; + currentItemSize = item.Size; + offset = item.Offset; + } + else + { + const CSection &item = _sections[index - _segments.Size()]; + currentItemSize = item.GetSize(); + offset = item.Offset; + } + { + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_inStream, offset)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + } + RINOK(extractCallback->SetOperationResult(copyCoder->TotalSize == currentItemSize ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) +{ + _allowTail = IntToBool(allowTail); + return S_OK; +} + +static const Byte k_Signature[] = { 0x7F, 'E', 'L', 'F' }; + +REGISTER_ARC_I( + "ELF", "elf", NULL, 0xDE, + k_Signature, + 0, + NArcInfoFlags::kPreArc, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ExtHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ExtHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ExtHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ExtHandler.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -1,2867 +1,2858 @@ -// ExtHandler.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO - -// #include -// #define PRF2(x) x - -#define PRF2(x) - -#ifdef SHOW_DEBUG_INFO -#include -#define PRF(x) x -#else -#define PRF(x) -#endif - -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyLinux.h" -#include "../../Common/StringConvert.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariantUtils.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -using namespace NWindows; - -namespace NArchive { -namespace NExt { - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -#define LE_16(offs, dest) dest = Get16(p + (offs)); -#define LE_32(offs, dest) dest = Get32(p + (offs)); -#define LE_64(offs, dest) dest = Get64(p + (offs)); - -#define HI_16(offs, dest) dest |= (((UInt32)Get16(p + (offs))) << 16); -#define HI_32(offs, dest) dest |= (((UInt64)Get32(p + (offs))) << 32); - -/* -static UInt32 g_Crc32CTable[256]; - -static struct CInitCrc32C -{ - CInitCrc32C() - { - for (unsigned i = 0; i < 256; i++) - { - UInt32 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (0x82F63B78 & ~((r & 1) - 1)); - g_Crc32CTable[i] = r; - } - } -} g_InitCrc32C; - -#define CRC32C_INIT_VAL 0xFFFFFFFF -#define CRC32C_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) -#define CRC32C_UPDATE_BYTE(crc, b) (g_Crc32CTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -static UInt32 Crc32C_Update(UInt32 crc, Byte const *data, size_t size) -{ - for (size_t i = 0; i < size; i++) - crc = CRC32C_UPDATE_BYTE(crc, data[i]); - return crc; -} - -static UInt32 Crc32C_Calc(Byte const *data, size_t size) -{ - return Crc32C_Update(CRC32C_INIT_VAL, data, size); -} -*/ - - -// CRC-16-ANSI. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) -static UInt16 g_Crc16Table[256]; - -static struct CInitCrc16 -{ - CInitCrc16() - { - for (unsigned i = 0; i < 256; i++) - { - UInt32 r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (0xA001 & ~((r & 1) - 1)); - g_Crc16Table[i] = (UInt16)r; - } - } -} g_InitCrc16; - -#define CRC16_UPDATE_BYTE(crc, b) (g_Crc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -#define CRC16_INIT_VAL 0xFFFF - -static UInt32 Crc16Update(UInt32 crc, Byte const *data, size_t size) -{ - for (size_t i = 0; i < size; i++) - crc = CRC16_UPDATE_BYTE(crc, data[i]); - return crc; -} - -static UInt32 Crc16Calc(Byte const *data, size_t size) -{ - return Crc16Update(CRC16_INIT_VAL, data, size); -} - - -#define EXT4_GOOD_OLD_INODE_SIZE 128 - -// inodes numbers - -// #define k_INODE_BAD 1 // Bad blocks -#define k_INODE_ROOT 2 // Root dir -// #define k_INODE_USR_QUOTA 3 // User quota -// #define k_INODE_GRP_QUOTA 4 // Group quota -// #define k_INODE_BOOT_LOADER 5 // Boot loader -// #define k_INODE_UNDEL_DIR 6 // Undelete dir -#define k_INODE_RESIZE 7 // Reserved group descriptors -// #define k_INODE_JOURNAL 8 // Journal - -// First non-reserved inode for old ext4 filesystems -#define k_INODE_GOOD_OLD_FIRST 11 - -static const char * const k_SysInode_Names[] = -{ - "0" - , "Bad" - , "Root" - , "UserQuota" - , "GroupQuota" - , "BootLoader" - , "Undelete" - , "Resize" - , "Journal" - , "Exclude" - , "Replica" -}; - -static const char * const kHostOS[] = -{ - "Linux" - , "Hurd" - , "Masix" - , "FreeBSD" - , "Lites" -}; - -static const CUInt32PCharPair g_FeatureCompat_Flags[] = -{ - { 0, "DIR_PREALLOC" }, - { 1, "IMAGIC_INODES" }, - { 2, "HAS_JOURNAL" }, - { 3, "EXT_ATTR" }, - { 4, "RESIZE_INODE" }, - { 5, "DIR_INDEX" }, - { 6, "LAZY_BG" }, // not in Linux - // { 7, "EXCLUDE_INODE" }, // not used - // { 8, "EXCLUDE_BITMAP" }, // not in kernel - { 9, "SPARSE_SUPER2" } -}; - - -#define EXT4_FEATURE_INCOMPAT_FILETYPE (1 << 1) -#define EXT4_FEATURE_INCOMPAT_64BIT (1 << 7) - -static const CUInt32PCharPair g_FeatureIncompat_Flags[] = -{ - { 0, "COMPRESSION" }, - { 1, "FILETYPE" }, - { 2, "RECOVER" }, /* Needs recovery */ - { 3, "JOURNAL_DEV" }, /* Journal device */ - { 4, "META_BG" }, - - { 6, "EXTENTS" }, /* extents support */ - { 7, "64BIT" }, - { 8, "MMP" }, - { 9, "FLEX_BG" }, - { 10, "EA_INODE" }, /* EA in inode */ - - { 12, "DIRDATA" }, /* data in dirent */ - { 13, "BG_USE_META_CSUM" }, /* use crc32c for bg */ - { 14, "LARGEDIR" }, /* >2GB or 3-lvl htree */ - { 15, "INLINE_DATA" }, /* data in inode */ - { 16, "ENCRYPT" } -}; - - -static const UInt32 RO_COMPAT_GDT_CSUM = 1 << 4; -static const UInt32 RO_COMPAT_METADATA_CSUM = 1 << 10; - -static const CUInt32PCharPair g_FeatureRoCompat_Flags[] = -{ - { 0, "SPARSE_SUPER" }, - { 1, "LARGE_FILE" }, - { 2, "BTREE_DIR" }, - { 3, "HUGE_FILE" }, - { 4, "GDT_CSUM" }, - { 5, "DIR_NLINK" }, - { 6, "EXTRA_ISIZE" }, - { 7, "HAS_SNAPSHOT" }, - { 8, "QUOTA" }, - { 9, "BIGALLOC" }, - { 10, "METADATA_CSUM" }, - { 11, "REPLICA" }, - { 12, "READONLY" } -}; - - - -static const UInt32 k_NodeFlags_HUGE = (UInt32)1 << 18; -static const UInt32 k_NodeFlags_EXTENTS = (UInt32)1 << 19; - - -static const CUInt32PCharPair g_NodeFlags[] = -{ - { 0, "SECRM" }, - { 1, "UNRM" }, - { 2, "COMPR" }, - { 3, "SYNC" }, - { 4, "IMMUTABLE" }, - { 5, "APPEND" }, - { 6, "NODUMP" }, - { 7, "NOATIME" }, - { 8, "DIRTY" }, - { 9, "COMPRBLK" }, - { 10, "NOCOMPR" }, - { 11, "ENCRYPT" }, - { 12, "INDEX" }, - { 13, "IMAGIC" }, - { 14, "JOURNAL_DATA" }, - { 15, "NOTAIL" }, - { 16, "DIRSYNC" }, - { 17, "TOPDIR" }, - { 18, "HUGE_FILE" }, - { 19, "EXTENTS" }, - - { 21, "EA_INODE" }, - { 22, "EOFBLOCKS" }, - - { 28, "INLINE_DATA" } -}; - - -static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } - -static inline void PrintHex(unsigned v, char *s) -{ - s[0] = GetHex((v >> 4) & 0xF); - s[1] = GetHex(v & 0xF); -} - - -enum -{ - k_Type_UNKNOWN, - k_Type_REG_FILE, - k_Type_DIR, - k_Type_CHRDEV, - k_Type_BLKDEV, - k_Type_FIFO, - k_Type_SOCK, - k_Type_SYMLINK -}; - -static const UInt16 k_TypeToMode[] = -{ - 0, - MY_LIN_S_IFREG, - MY_LIN_S_IFDIR, - MY_LIN_S_IFCHR, - MY_LIN_S_IFBLK, - MY_LIN_S_IFIFO, - MY_LIN_S_IFSOCK, - MY_LIN_S_IFLNK -}; - - -#define EXT4_GOOD_OLD_REV 0 // old (original) format -// #define EXT4_DYNAMIC_REV 1 // V2 format with dynamic inode sizes - -struct CHeader -{ - unsigned BlockBits; - unsigned ClusterBits; - - UInt32 NumInodes; - UInt64 NumBlocks; - // UInt64 NumBlocksSuper; - UInt64 NumFreeBlocks; - UInt32 NumFreeInodes; - // UInt32 FirstDataBlock; - - UInt32 BlocksPerGroup; - UInt32 ClustersPerGroup; - UInt32 InodesPerGroup; - - UInt32 MountTime; - UInt32 WriteTime; - - // UInt16 NumMounts; - // UInt16 NumMountsMax; - - // UInt16 State; - // UInt16 Errors; - // UInt16 MinorRevLevel; - - UInt32 LastCheckTime; - // UInt32 CheckInterval; - UInt32 CreatorOs; - UInt32 RevLevel; - - // UInt16 DefResUid; - // UInt16 DefResGid; - - UInt32 FirstInode; - UInt16 InodeSize; - UInt16 BlockGroupNr; - UInt32 FeatureCompat; - UInt32 FeatureIncompat; - UInt32 FeatureRoCompat; - Byte Uuid[16]; - char VolName[16]; - char LastMount[64]; - // UInt32 BitmapAlgo; - - UInt32 JournalInode; - UInt16 GdSize; // = 64 if 64-bit(); - UInt32 CTime; - UInt16 MinExtraISize; - // UInt16 WantExtraISize; - // UInt32 Flags; - // Byte LogGroupsPerFlex; - // Byte ChecksumType; - - UInt64 WrittenKB; - - bool IsOldRev() const { return RevLevel == EXT4_GOOD_OLD_REV; } - - UInt64 GetNumGroups() const { return (NumBlocks + BlocksPerGroup - 1) / BlocksPerGroup; } - UInt64 GetNumGroups2() const { return ((UInt64)NumInodes + InodesPerGroup - 1) / InodesPerGroup; } - - bool IsThereFileType() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_FILETYPE) != 0; } - bool Is64Bit() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0; } - bool UseGdtChecksum() const { return (FeatureRoCompat & RO_COMPAT_GDT_CSUM) != 0; } - bool UseMetadataChecksum() const { return (FeatureRoCompat & RO_COMPAT_METADATA_CSUM) != 0; } - - bool Parse(const Byte *p); -}; - - -static int inline GetLog(UInt32 num) -{ - for (unsigned i = 0; i < 32; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - -static bool inline IsEmptyData(const Byte *data, unsigned size) -{ - for (unsigned i = 0; i < size; i++) - if (data[i] != 0) - return false; - return true; -} - - -bool CHeader::Parse(const Byte *p) -{ - if (GetUi16(p + 0x38) != 0xEF53) - return false; - - LE_32 (0x18, BlockBits); - LE_32 (0x1C, ClusterBits); - - if (ClusterBits != 0 && BlockBits != ClusterBits) - return false; - - if (BlockBits > 16 - 10) - return false; - BlockBits += 10; - - LE_32 (0x00, NumInodes); - LE_32 (0x04, NumBlocks); - // LE_32 (0x08, NumBlocksSuper); - LE_32 (0x0C, NumFreeBlocks); - LE_32 (0x10, NumFreeInodes); - - if (NumInodes < 2 || NumInodes <= NumFreeInodes) - return false; - - UInt32 FirstDataBlock; - LE_32 (0x14, FirstDataBlock); - if (FirstDataBlock != (unsigned)(BlockBits == 10 ? 1 : 0)) - return false; - - LE_32 (0x20, BlocksPerGroup); - LE_32 (0x24, ClustersPerGroup); - - if (BlocksPerGroup != ClustersPerGroup) - return false; - if (BlocksPerGroup == 0) - return false; - if (BlocksPerGroup != ((UInt32)1 << (BlockBits + 3))) - { - // it's allowed in ext2 - // return false; - } - - LE_32 (0x28, InodesPerGroup); - - if (InodesPerGroup < 1 || InodesPerGroup > NumInodes) - return false; - - LE_32 (0x2C, MountTime); - LE_32 (0x30, WriteTime); - - // LE_16 (0x34, NumMounts); - // LE_16 (0x36, NumMountsMax); - - // LE_16 (0x3A, State); - // LE_16 (0x3C, Errors); - // LE_16 (0x3E, MinorRevLevel); - - LE_32 (0x40, LastCheckTime); - // LE_32 (0x44, CheckInterval); - LE_32 (0x48, CreatorOs); - LE_32 (0x4C, RevLevel); - - // LE_16 (0x50, DefResUid); - // LE_16 (0x52, DefResGid); - - FirstInode = k_INODE_GOOD_OLD_FIRST; - InodeSize = EXT4_GOOD_OLD_INODE_SIZE; - - if (!IsOldRev()) - { - LE_32 (0x54, FirstInode); - LE_16 (0x58, InodeSize); - if (FirstInode < k_INODE_GOOD_OLD_FIRST) - return false; - if (InodeSize > (UInt32)1 << BlockBits) - return false; - if (GetLog(InodeSize) < 0) - return false; - } - - LE_16 (0x5A, BlockGroupNr); - LE_32 (0x5C, FeatureCompat); - LE_32 (0x60, FeatureIncompat); - LE_32 (0x64, FeatureRoCompat); - - memcpy(Uuid, p + 0x68, sizeof(Uuid)); - memcpy(VolName, p + 0x78, sizeof(VolName)); - memcpy(LastMount, p + 0x88, sizeof(LastMount)); - - // LE_32 (0xC8, BitmapAlgo); - - LE_32 (0xE0, JournalInode); - - LE_16 (0xFE, GdSize); - - LE_32 (0x108, CTime); - - if (Is64Bit()) - { - HI_32(150, NumBlocks); - // HI_32(154, NumBlocksSuper); - HI_32(0x158, NumFreeBlocks); - } - - if (NumBlocks >= (UInt64)1 << (63 - BlockBits)) - return false; - - - LE_16(0x15C, MinExtraISize); - // LE_16(0x15E, WantExtraISize); - // LE_32(0x160, Flags); - // LE_16(0x164, RaidStride); - // LE_16(0x166, MmpInterval); - // LE_64(0x168, MmpBlock); - - // LogGroupsPerFlex = p[0x174]; - // ChecksumType = p[0x175]; - - LE_64 (0x178, WrittenKB); - - // LE_32(0x194, ErrorCount); - // LE_32(0x198, ErrorTime); - // LE_32(0x19C, ErrorINode); - // LE_32(0x1A0, ErrorBlock); - - if (NumBlocks < 1) - return false; - if (NumFreeBlocks > NumBlocks) - return false; - - if (GetNumGroups() != GetNumGroups2()) - return false; - - return true; -} - - -struct CGroupDescriptor -{ - UInt64 BlockBitmap; - UInt64 InodeBitmap; - UInt64 InodeTable; - UInt32 NumFreeBlocks; - UInt32 NumFreeInodes; - UInt32 DirCount; - - UInt16 Flags; - - UInt64 ExcludeBitmap; - UInt32 BlockBitmap_Checksum; - UInt32 InodeBitmap_Checksum; - UInt32 UnusedCount; - UInt16 Checksum; - - void Parse(const Byte *p, unsigned size); -}; - -void CGroupDescriptor::Parse(const Byte *p, unsigned size) -{ - LE_32 (0x00, BlockBitmap); - LE_32 (0x04, InodeBitmap); - LE_32 (0x08, InodeTable); - LE_16 (0x0C, NumFreeBlocks); - LE_16 (0x0E, NumFreeInodes); - LE_16 (0x10, DirCount); - LE_16 (0x12, Flags); - LE_32 (0x14, ExcludeBitmap); - LE_16 (0x18, BlockBitmap_Checksum); - LE_16 (0x1A, InodeBitmap_Checksum); - LE_16 (0x1C, UnusedCount); - LE_16 (0x1E, Checksum); - - if (size >= 64) - { - p += 0x20; - HI_32 (0x00, BlockBitmap); - HI_32 (0x04, InodeBitmap); - HI_32 (0x08, InodeTable); - HI_16 (0x0C, NumFreeBlocks); - HI_16 (0x0E, NumFreeInodes); - HI_16 (0x10, DirCount); - HI_16 (0x12, UnusedCount); // instead of Flags - HI_32 (0x14, ExcludeBitmap); - HI_16 (0x18, BlockBitmap_Checksum); - HI_16 (0x1A, InodeBitmap_Checksum); - // HI_16 (0x1C, Reserved); - } -} - - -static const unsigned kNodeBlockFieldSize = 60; - -struct CExtentTreeHeader -{ - UInt16 NumEntries; - UInt16 MaxEntries; - UInt16 Depth; - // UInt32 Generation; - - bool Parse(const Byte *p) - { - LE_16 (0x02, NumEntries); - LE_16 (0x04, MaxEntries); - LE_16 (0x06, Depth); - // LE_32 (0x08, Generation); - return Get16(p) == 0xF30A; // magic - } -}; - -struct CExtentIndexNode -{ - UInt32 VirtBlock; - UInt64 PhyLeaf; - - void Parse(const Byte *p) - { - LE_32 (0x00, VirtBlock); - LE_32 (0x04, PhyLeaf); - PhyLeaf |= (((UInt64)Get16(p + 8)) << 32); - // unused 16-bit field (at offset 0x0A) can be not zero in some cases. Why? - } -}; - -struct CExtent -{ - UInt32 VirtBlock; - UInt16 Len; - bool IsInited; - UInt64 PhyStart; - - UInt32 GetVirtEnd() const { return VirtBlock + Len; } - bool IsLenOK() const { return VirtBlock + Len >= VirtBlock; } - - void Parse(const Byte *p) - { - LE_32 (0x00, VirtBlock); - LE_16 (0x04, Len); - IsInited = true; - if (Len > (UInt32)0x8000) - { - IsInited = false; - Len -= (UInt32)0x8000; - } - LE_32 (0x08, PhyStart); - UInt16 hi; - LE_16 (0x06, hi); - PhyStart |= ((UInt64)hi << 32); - } -}; - - - -struct CExtTime -{ - UInt32 Val; - UInt32 Extra; -}; - -struct CNode -{ - Int32 ParentNode; // in _refs[], -1 if not dir - int ItemIndex; // in _items[] - int SymLinkIndex; // in _symLinks[] - int DirIndex; // in _dirs[] - - UInt16 Mode; - UInt16 Uid; - UInt16 Gid; - // UInt16 Checksum; - - UInt64 FileSize; - CExtTime MTime; - CExtTime ATime; - CExtTime CTime; - // CExtTime InodeChangeTime; - // CExtTime DTime; - - UInt64 NumBlocks; - UInt32 NumLinks; - UInt32 Flags; - - UInt32 NumLinksCalced; - - Byte Block[kNodeBlockFieldSize]; - - CNode(): - ParentNode(-1), - ItemIndex(-1), - SymLinkIndex(-1), - DirIndex(0), - NumLinksCalced(0) - {} - - bool IsFlags_HUGE() const { return (Flags & k_NodeFlags_HUGE) != 0; } - bool IsFlags_EXTENTS() const { return (Flags & k_NodeFlags_EXTENTS) != 0; } - - bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } - bool IsRegular() const { return MY_LIN_S_ISREG(Mode); } - bool IsLink() const { return MY_LIN_S_ISLNK(Mode); } - - bool Parse(const Byte *p, const CHeader &_h); -}; - - -bool CNode::Parse(const Byte *p, const CHeader &_h) -{ - MTime.Extra = 0; - ATime.Extra = 0; - CTime.Extra = 0; - CTime.Val = 0; - // InodeChangeTime.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 (0x10, MTime.Val); - // LE_32 (0x14, DTime.Val); - LE_16 (0x18, Gid); - LE_16 (0x1A, NumLinks); - - LE_32 (0x1C, NumBlocks); - LE_32 (0x20, Flags); - // LE_32 (0x24, Union osd1); - - memcpy(Block, p + 0x28, kNodeBlockFieldSize); - - // LE_32 (0x64, Generation); // File version (for NFS) - // LE_32 (0x68, ACL); - - { - UInt32 highSize; - LE_32 (0x6C, highSize); // In ext2/3 this field was named i_dir_acl - - if (IsRegular()) // do we need that check ? - FileSize |= ((UInt64)highSize << 32); - } - - // UInt32 fragmentAddress; - // LE_32 (0x70, fragmentAddress); - - // osd2 - { - // Linux; - // ext2: - // Byte FragmentNumber = p[0x74]; - // Byte FragmentSize = p[0x74 + 1]; - - // ext4: - UInt32 numBlocksHigh; - LE_16 (0x74, numBlocksHigh); - NumBlocks |= (UInt64)numBlocksHigh << 32; - - HI_16 (0x74 + 4, Uid); - HI_16 (0x74 + 6, Gid); - /* - UInt32 checksum; - LE_16 (0x74 + 8, checksum); - checksum = checksum; - */ - } - - // 0x74: Byte Union osd2[12]; - - if (_h.InodeSize > 128) - { - UInt16 extra_isize; - LE_16 (0x80, extra_isize); - if (128 + extra_isize > _h.InodeSize) - return false; - if (extra_isize >= 0x1C) - { - // UInt16 checksumUpper; - // LE_16 (0x82, checksumUpper); - // LE_32 (0x84, InodeChangeTime.Extra); - LE_32 (0x88, MTime.Extra); - LE_32 (0x8C, ATime.Extra); - LE_32 (0x90, CTime.Val); - LE_32 (0x94, CTime.Extra); - // LE_32 (0x98, VersionHi); - } - } - - PRF(printf("size = %5d", (unsigned)FileSize)); - - return true; -} - - -struct CItem -{ - unsigned Node; // in _refs[] - int ParentNode; // in _refs[] - int SymLinkItemIndex; // in _items[], if the Node contains SymLink to existing dir - Byte Type; - - AString Name; - - CItem(): - Node(0), - ParentNode(-1), - SymLinkItemIndex(-1), - Type(k_Type_UNKNOWN) - {} - - void Clear() - { - Node = 0; - ParentNode = -1; - SymLinkItemIndex = -1; - Type = k_Type_UNKNOWN; - Name.Empty(); - } - - bool IsDir() const { return Type == k_Type_DIR; } - // bool IsNotDir() const { return Type != k_Type_DIR && Type != k_Type_UNKNOWN; } - -}; - - - -static const unsigned kNumTreeLevelsMax = 6; // must be >= 3 - - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CObjectVector _items; - CIntVector _refs; - CRecordVector _nodes; - CObjectVector _dirs; // each CUIntVector contains indexes in _items[] only for dir items; - AStringVector _symLinks; - AStringVector _auxItems; - int _auxSysIndex; - int _auxUnknownIndex; - - CMyComPtr _stream; - UInt64 _phySize; - bool _isArc; - bool _headersError; - bool _headersWarning; - bool _linksError; - - bool _isUTF; - - CHeader _h; - - IArchiveOpenCallback *_openCallback; - UInt64 _totalRead; - UInt64 _totalReadPrev; - - CByteBuffer _tempBufs[kNumTreeLevelsMax]; - - - HRESULT CheckProgress2() - { - const UInt64 numFiles = _items.Size(); - return _openCallback->SetCompleted(&numFiles, &_totalRead); - } - - HRESULT CheckProgress() - { - HRESULT res = S_OK; - if (_openCallback) - { - if (_totalRead - _totalReadPrev >= ((UInt32)1 << 20)) - { - _totalReadPrev = _totalRead; - res = CheckProgress2(); - } - } - return res; - } - - - const int GetParentAux(const CItem &item) const - { - if (item.Node < _h.FirstInode && _auxSysIndex >= 0) - return _auxSysIndex; - return _auxUnknownIndex; - } - - HRESULT SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size); - HRESULT ParseDir(const Byte *data, size_t size, unsigned iNodeDir); - int FindTargetItem_for_SymLink(unsigned dirNode, const AString &path) const; - - HRESULT FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector &blocks); - HRESULT FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector &blocks); - HRESULT FillExtents(const Byte *p, size_t size, CRecordVector &extents, int parentDepth); - - HRESULT GetStream_Node(unsigned nodeIndex, ISequentialInStream **stream); - HRESULT ExtractNode(unsigned nodeIndex, CByteBuffer &data); - - void ClearRefs(); - HRESULT Open2(IInStream *inStream); - - void GetPath(unsigned index, AString &s) const; - bool GetPackSize(unsigned index, UInt64 &res) const; - -public: - CHandler() {} - ~CHandler() {} - - MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - - - -HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned iNodeDir) -{ - bool isThereSelfLink = false; - - PRF(printf("\n\n========= node = %5d size = %5d", (unsigned)iNodeDir, (unsigned)size)); - - CNode &nodeDir = _nodes[_refs[iNodeDir]]; - nodeDir.DirIndex = _dirs.Size(); - CUIntVector &dir = _dirs.AddNew(); - int parentNode = -1; - - CItem item; - - for (;;) - { - if (size == 0) - break; - if (size < 8) - return S_FALSE; - UInt32 iNode; - LE_32 (0x00, iNode); - unsigned recLen; - LE_16 (0x04, recLen); - unsigned nameLen = p[6]; - Byte type = p[7]; - - if (recLen > size) - return S_FALSE; - if (nameLen + 8 > recLen) - return S_FALSE; - - if (iNode >= _refs.Size()) - return S_FALSE; - - item.Clear(); - - if (_h.IsThereFileType()) - item.Type = type; - else if (type != 0) - return S_FALSE; - - item.ParentNode = iNodeDir; - item.Node = iNode; - item.Name.SetFrom_CalcLen((const char *)(p + 8), nameLen); - - p += recLen; - size -= recLen; - - if (item.Name.Len() != nameLen) - return S_FALSE; - - if (_isUTF) - _isUTF = CheckUTF8(item.Name); - - if (iNode == 0) - { - /* - ext3 deleted?? - if (item.Name.Len() != 0) - return S_FALSE; - */ - - PRF(printf("\n EMPTY %6d %d %s", (unsigned)recLen, (unsigned)type, (const char *)item.Name)); - if (type == 0xDE) - { - // checksum - } - continue; - } - - int nodeIndex = _refs[iNode]; - if (nodeIndex < 0) - return S_FALSE; - CNode &node = _nodes[nodeIndex]; - - if (_h.IsThereFileType() && type != 0) - { - if (type >= ARRAY_SIZE(k_TypeToMode)) - return S_FALSE; - if (k_TypeToMode[type] != (node.Mode & MY_LIN_S_IFMT)) - return S_FALSE; - } - - node.NumLinksCalced++; - - PRF(printf("\n%s %6d %s", item.IsDir() ? "DIR " : " ", (unsigned)item.Node, (const char *)item.Name)); - - if (item.Name[0] == '.') - { - if (item.Name[1] == 0) - { - if (isThereSelfLink) - return S_FALSE; - isThereSelfLink = true; - if (iNode != iNodeDir) - return S_FALSE; - continue; - } - - if (item.Name[1] == '.' && item.Name[2] == 0) - { - if (parentNode >= 0) - return S_FALSE; - if (!node.IsDir()) - return S_FALSE; - if (iNode == iNodeDir && iNode != k_INODE_ROOT) - return S_FALSE; - - parentNode = iNode; - - if (nodeDir.ParentNode < 0) - nodeDir.ParentNode = iNode; - else if ((unsigned)nodeDir.ParentNode != iNode) - return S_FALSE; - - continue; - } - } - - if (iNode == iNodeDir) - return S_FALSE; - - if (parentNode < 0) - return S_FALSE; - - if (node.IsDir()) - { - if (node.ParentNode < 0) - node.ParentNode = iNodeDir; - else if ((unsigned)node.ParentNode != iNodeDir) - return S_FALSE; - const unsigned itemIndex = _items.Size(); - dir.Add(itemIndex); - node.ItemIndex = itemIndex; - } - - _items.Add(item); - } - - if (parentNode < 0 || !isThereSelfLink) - return S_FALSE; - - return S_OK; -} - - -int CHandler::FindTargetItem_for_SymLink(unsigned iNode, const AString &path) const -{ - unsigned pos = 0; - - if (path.IsEmpty()) - return -1; - - if (path[0] == '/') - { - iNode = k_INODE_ROOT; - if (iNode >= _refs.Size()) - return -1; - pos = 1; - } - - AString s; - - while (pos != path.Len()) - { - const CNode &node = _nodes[_refs[iNode]]; - int slash = path.Find('/', pos); - - if (slash < 0) - { - s = path.Ptr(pos); - pos = path.Len(); - } - else - { - s.SetFrom(path.Ptr(pos), slash - pos); - pos = slash + 1; - } - - if (s[0] == '.') - { - if (s[1] == 0) - continue; - else if (s[1] == '.' && s[2] == 0) - { - if (node.ParentNode < 0) - return -1; - if (iNode == k_INODE_ROOT) - return -1; - iNode = node.ParentNode; - continue; - } - } - - if (node.DirIndex < 0) - return -1; - - const CUIntVector &dir = _dirs[node.DirIndex]; - - for (unsigned i = 0;; i++) - { - if (i >= dir.Size()) - return -1; - const CItem &item = _items[dir[i]]; - if (item.Name == s) - { - iNode = item.Node; - break; - } - } - } - - return _nodes[_refs[iNode]].ItemIndex; -} - - -HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size) -{ - if (block == 0 || block >= _h.NumBlocks) - return S_FALSE; - if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block) - return S_FALSE; - RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL)); - _totalRead += size; - return ReadStream_FALSE(inStream, data, size); -} - - -static const unsigned kHeaderSize = 2 * 1024; -static const unsigned kHeaderDataOffset = 1024; - -HRESULT CHandler::Open2(IInStream *inStream) -{ - { - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); - if (!_h.Parse(buf + kHeaderDataOffset)) - return S_FALSE; - if (_h.BlockGroupNr != 0) - return S_FALSE; // it's just copy of super block - } - - { - // ---------- Read groups and nodes ---------- - - unsigned numGroups; - { - UInt64 numGroups64 = _h.GetNumGroups(); - if (numGroups64 > (UInt32)1 << 31) - return S_FALSE; - numGroups = (unsigned)numGroups64; - } - - unsigned gdBits = 5; - if (_h.Is64Bit()) - { - if (_h.GdSize != 64) - return S_FALSE; - gdBits = 6; - } - - _isArc = true; - _phySize = _h.NumBlocks << _h.BlockBits; - - if (_openCallback) - { - RINOK(_openCallback->SetTotal(NULL, &_phySize)); - } - - UInt64 fileSize = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize)); - - CRecordVector groups; - - { - // ---------- Read groups ---------- - - CByteBuffer gdBuf; - size_t gdBufSize = (size_t)numGroups << gdBits; - if ((gdBufSize >> gdBits) != numGroups) - return S_FALSE; - gdBuf.Alloc(gdBufSize); - RINOK(SeekAndRead(inStream, (_h.BlockBits <= 10 ? 2 : 1), gdBuf, gdBufSize)); - - for (unsigned i = 0; i < numGroups; i++) - { - CGroupDescriptor gd; - - const Byte *p = gdBuf + ((size_t)i << gdBits); - unsigned gd_Size = (unsigned)1 << gdBits; - gd.Parse(p, gd_Size); - - if (_h.UseMetadataChecksum()) - { - // use CRC32c - } - else if (_h.UseGdtChecksum()) - { - UInt32 crc = Crc16Calc(_h.Uuid, sizeof(_h.Uuid)); - Byte i_le[4]; - SetUi32(i_le, i); - crc = Crc16Update(crc, i_le, 4); - crc = Crc16Update(crc, p, 32 - 2); - if (gd_Size != 32) - crc = Crc16Update(crc, p + 32, gd_Size - 32); - if (crc != gd.Checksum) - return S_FALSE; - } - - groups.Add(gd); - } - } - - { - // ---------- Read nodes ---------- - - if (_h.NumInodes < _h.NumFreeInodes) - return S_FALSE; - - UInt32 numNodes = _h.InodesPerGroup; - if (numNodes > _h.NumInodes) - numNodes = _h.NumInodes; - size_t nodesDataSize = (size_t)numNodes * _h.InodeSize; - - if (nodesDataSize / _h.InodeSize != numNodes) - return S_FALSE; - - // that code to reduce false detecting cases - if (nodesDataSize > fileSize) - { - if (numNodes > (1 << 24)) - return S_FALSE; - } - - UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1; - // numReserveInodes = _h.NumInodes + 1; - if (numReserveInodes != 0) - { - _nodes.Reserve(numReserveInodes); - _refs.Reserve(numReserveInodes); - } - - CByteBuffer nodesData; - nodesData.Alloc(nodesDataSize); - - CByteBuffer nodesMap; - const size_t blockSize = (size_t)1 << _h.BlockBits; - nodesMap.Alloc(blockSize); - - unsigned globalNodeIndex = 0; - // unsigned numEmpty = 0; - unsigned numEmpty_in_Maps = 0; - - FOR_VECTOR (gi, groups) - { - if (globalNodeIndex >= _h.NumInodes) - break; - - const CGroupDescriptor &gd = groups[gi]; - - PRF(printf("\n\ng%6d block = %6x\n", gi, (unsigned)gd.InodeTable)); - - RINOK(SeekAndRead(inStream, gd.InodeBitmap, nodesMap, blockSize)); - RINOK(SeekAndRead(inStream, gd.InodeTable, nodesData, nodesDataSize)); - - unsigned numEmpty_in_Map = 0; - - for (size_t n = 0; n < numNodes && globalNodeIndex < _h.NumInodes; n++, globalNodeIndex++) - { - if ((nodesMap[n >> 3] & ((unsigned)1 << (n & 7))) == 0) - { - numEmpty_in_Map++; - continue; - } - - const Byte *p = nodesData + (size_t)n * _h.InodeSize; - if (IsEmptyData(p, _h.InodeSize)) - { - if (globalNodeIndex + 1 >= _h.FirstInode) - { - _headersError = true; - // return S_FALSE; - } - continue; - } - - CNode node; - - PRF(printf("\nnode = %5d ", (unsigned)n)); - - if (!node.Parse(p, _h)) - return S_FALSE; - - // PRF(printf("\n %6d", (unsigned)n)); - /* - SetUi32(p + 0x7C, 0) - SetUi32(p + 0x82, 0) - - UInt32 crc = Crc32C_Calc(_h.Uuid, sizeof(_h.Uuid)); - Byte i_le[4]; - SetUi32(i_le, n); - crc = Crc32C_Update(crc, i_le, 4); - crc = Crc32C_Update(crc, p, _h.InodeSize); - if (crc != node.Checksum) return S_FALSE; - */ - - while (_refs.Size() < globalNodeIndex + 1) - { - // numEmpty++; - _refs.Add(-1); - } - - _refs.Add(_nodes.Add(node)); - } - - - numEmpty_in_Maps += numEmpty_in_Map; - - if (numEmpty_in_Map != gd.NumFreeInodes) - { - _headersWarning = true; - // return S_FALSE; - } - } - - if (numEmpty_in_Maps != _h.NumFreeInodes) - { - // some ext2 examples has incorrect value in _h.NumFreeInodes. - // so we disable check; - _headersWarning = true; - } - - if (_refs.Size() <= k_INODE_ROOT) - return S_FALSE; - - // printf("\n numReserveInodes = %6d, _refs.Size() = %d, numEmpty = %7d\n", numReserveInodes, _refs.Size(), (unsigned)numEmpty); - } - } - - _stream = inStream; // we need stream for dir nodes - - { - // ---------- Read Dirs ---------- - - CByteBuffer dataBuf; - - FOR_VECTOR (i, _refs) - { - int nodeIndex = _refs[i]; - { - if (nodeIndex < 0) - continue; - const CNode &node = _nodes[nodeIndex]; - if (!node.IsDir()) - continue; - } - RINOK(ExtractNode(nodeIndex, dataBuf)); - if (dataBuf.Size() == 0) - { - // _headersError = true; - return S_FALSE; - } - else - { - RINOK(ParseDir(dataBuf, dataBuf.Size(), i)); - } - RINOK(CheckProgress()); - } - - if (_nodes[_refs[k_INODE_ROOT]].ParentNode != k_INODE_ROOT) - return S_FALSE; - } - - { - // ---------- Check NumLinks and unreferenced dir nodes ---------- - - FOR_VECTOR (i, _refs) - { - int nodeIndex = _refs[i]; - if (nodeIndex < 0) - continue; - const CNode &node = _nodes[nodeIndex]; - - if (node.NumLinks != node.NumLinksCalced) - { - if (node.NumLinks != 1 || node.NumLinksCalced != 0 - // ) && i >= _h.FirstInode - ) - { - _linksError = true; - // return S_FALSE; - } - } - - if (!node.IsDir()) - continue; - - if (node.ParentNode < 0) - { - if (i >= _h.FirstInode) - return S_FALSE; - continue; - } - } - } - - { - // ---------- Check that there is no loops in parents list ---------- - - unsigned numNodes = _refs.Size(); - CIntArr UsedByNode(numNodes); - { - { - for (unsigned i = 0; i < numNodes; i++) - UsedByNode[i] = -1; - } - } - - FOR_VECTOR (i, _refs) - { - { - int nodeIndex = _refs[i]; - if (nodeIndex < 0) - continue; - const CNode &node = _nodes[nodeIndex]; - if (node.ParentNode < 0 // not dir - || i == k_INODE_ROOT) - continue; - } - - unsigned c = i; - - for (;;) - { - int nodeIndex = _refs[c]; - if (nodeIndex < 0) - return S_FALSE; - CNode &node = _nodes[nodeIndex]; - - if (UsedByNode[c] != -1) - { - if ((unsigned)UsedByNode[c] == i) - return S_FALSE; - break; - } - - UsedByNode[c] = i; - if (node.ParentNode < 0 || node.ParentNode == k_INODE_ROOT) - break; - if ((unsigned)node.ParentNode == i) - return S_FALSE; - c = node.ParentNode; - } - } - } - - { - // ---------- Fill SymLinks data ---------- - - AString s; - CByteBuffer data; - - unsigned i; - for (i = 0; i < _refs.Size(); i++) - { - int nodeIndex = _refs[i]; - if (nodeIndex < 0) - continue; - CNode &node = _nodes[nodeIndex]; - if (!node.IsLink()) - continue; - if (node.FileSize > ((UInt32)1 << 14)) - continue; - if (ExtractNode(nodeIndex, data) == S_OK && data.Size() != 0) - { - s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); - if (s.Len() == data.Size()) - node.SymLinkIndex = _symLinks.Add(s); - RINOK(CheckProgress()); - } - } - - unsigned prev = 0; - unsigned complex = 0; - - for (i = 0; i < _items.Size(); i++) - { - CItem &item = _items[i]; - int sym = _nodes[_refs[item.Node]].SymLinkIndex; - if (sym >= 0 && item.ParentNode >= 0) - { - item.SymLinkItemIndex = FindTargetItem_for_SymLink(item.ParentNode, _symLinks[sym]); - if (_openCallback) - { - complex++; - if (complex - prev >= (1 << 10)) - { - RINOK(CheckProgress2()); - prev = complex; - } - } - } - } - } - - { - // ---------- Add items and aux folders for unreferenced files ---------- - - bool useSys = false; - bool useUnknown = false; - - FOR_VECTOR (i, _refs) - { - int nodeIndex = _refs[i]; - if (nodeIndex < 0) - continue; - const CNode &node = _nodes[nodeIndex]; - - if (node.NumLinksCalced == 0 /* || i > 100 && i < 150 */) // for debug - { - CItem item; - item.Node = i; - - // we don't know how to work with k_INODE_RESIZE node (strange FileSize and Block values). - // so we ignore it; - - if (i == k_INODE_RESIZE) - continue; - - if (node.FileSize == 0) - continue; - - if (i < _h.FirstInode) - { - if (item.Node < ARRAY_SIZE(k_SysInode_Names)) - item.Name = k_SysInode_Names[item.Node]; - useSys = true; - } - else - useUnknown = true; - - if (item.Name.IsEmpty()) - { - char temp[16]; - ConvertUInt32ToString(item.Node, temp); - item.Name = temp; - } - - _items.Add(item); - } - } - - if (useSys) - _auxSysIndex = _auxItems.Add("[SYS]"); - if (useUnknown) - _auxUnknownIndex = _auxItems.Add("[UNKNOWN]"); - } - - return S_OK; -} - - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - HRESULT res; - try - { - _openCallback = callback; - res = Open2(stream); - } - catch(...) - { - ClearRefs(); - throw; - } - - if (res != S_OK) - { - ClearRefs(); - return res; - } - _stream = stream; - } - return S_OK; - COM_TRY_END -} - - -void CHandler::ClearRefs() -{ - _stream.Release(); - _items.Clear(); - _nodes.Clear(); - _refs.Clear(); - _auxItems.Clear(); - _symLinks.Clear(); - _dirs.Clear(); - _auxSysIndex = -1; - _auxUnknownIndex = -1; -} - - -STDMETHODIMP CHandler::Close() -{ - _totalRead = 0; - _totalReadPrev = 0; - _phySize = 0; - _isArc = false; - _headersError = false; - _headersWarning = false; - _linksError = false; - _isUTF = true; - - ClearRefs(); - return S_OK; -} - - -void CHandler::GetPath(unsigned index, AString &s) const -{ - s.Empty(); - - if (index >= _items.Size()) - { - s = _auxItems[index - _items.Size()]; - return; - } - - for (;;) - { - const CItem &item = _items[index]; - if (!s.IsEmpty()) - s.InsertAtFront(CHAR_PATH_SEPARATOR); - s.Insert(0, item.Name); - - if (item.ParentNode == k_INODE_ROOT) - return; - - if (item.ParentNode < 0) - { - int aux = GetParentAux(item); - if (aux < 0) - break; - s.InsertAtFront(CHAR_PATH_SEPARATOR); - s.Insert(0, _auxItems[aux]); - return; - } - - const CNode &node = _nodes[_refs[item.ParentNode]]; - if (node.ItemIndex < 0) - return; - index = node.ItemIndex; - - if (s.Len() > ((UInt32)1 << 16)) - { - s.Insert(0, "[LONG]" STRING_PATH_SEPARATOR); - return; - } - } -} - - -bool CHandler::GetPackSize(unsigned index, UInt64 &totalPack) const -{ - if (index >= _items.Size()) - { - totalPack = 0; - return false; - } - - const CItem &item = _items[index]; - const CNode &node = _nodes[_refs[item.Node]]; - - // if (!node.IsFlags_EXTENTS()) - { - totalPack = (UInt64)node.NumBlocks << (node.IsFlags_HUGE() ? _h.BlockBits : 9); - return true; - } - - /* - CExtentTreeHeader eth; - if (!eth.Parse(node.Block)) - return false; - if (eth.NumEntries > 3) - return false; - if (!eth.Depth == 0) - return false; - - UInt64 numBlocks = 0; - { - for (unsigned i = 0; i < eth.NumEntries; i++) - { - CExtent e; - e.Parse(node.Block + 12 + i * 12); - // const CExtent &e = node.leafs[i]; - if (e.IsInited) - numBlocks += e.Len; - } - } - - totalPack = numBlocks << _h.BlockBits; - return true; - */ -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size() + _auxItems.Size(); - return S_OK; -} - -enum -{ - kpidMountTime = kpidUserDefined, - kpidLastCheckTime, - kpidRevision, - kpidINodeSize, - kpidLastMount, - kpidFeatureIncompat, - kpidFeatureRoCompat, - kpidWrittenKB - - // kpidGroupSize, - - // kpidChangeTime = kpidUserDefined + 256, - // kpidDTime -}; - -static const UInt32 kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidPosixAttrib, - kpidMTime, - kpidCTime, - kpidATime, - // kpidChangeTime, - // kpidDTime, - kpidINode, - kpidLinks, - kpidSymLink, - kpidCharacts, - kpidUser, - kpidGroup -}; - - -static const CStatProp kArcProps[] = -{ - { NULL, kpidHeadersSize, VT_BSTR }, - // { NULL, kpidFileSystem, VT_BSTR }, - // kpidMethod, - { NULL, kpidClusterSize, VT_UI4 }, - // { "Group Size", kpidGroupSize, VT_UI8 }, - { NULL, kpidFreeSpace, VT_UI8 }, - - { NULL, kpidMTime, VT_FILETIME }, - { NULL, kpidCTime, VT_FILETIME }, - { "Mount Time", kpidMountTime, VT_FILETIME }, - { "Last Check Time", kpidLastCheckTime, VT_FILETIME }, - - { NULL, kpidHostOS, VT_BSTR}, - { "Revision", kpidRevision, VT_UI4}, - { "inode Size", kpidINodeSize, VT_UI4}, - { NULL, kpidCodePage, VT_BSTR}, - { NULL, kpidVolumeName, VT_BSTR}, - { "Last Mounted", kpidLastMount, VT_BSTR}, - { NULL, kpidId, VT_BSTR}, - { NULL, kpidCharacts, VT_BSTR }, - { "Incompatible Features", kpidFeatureIncompat, VT_BSTR }, - { "Readonly-compatible Features", kpidFeatureRoCompat, VT_BSTR }, - { "Written KiB", kpidWrittenKB, VT_UI8 } -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -static void StringToProp(bool isUTF, const char *s, unsigned size, NCOM::CPropVariant &prop) -{ - UString u; - AString a; - a.SetFrom_CalcLen(s, size); - if (!isUTF || !ConvertUTF8ToUnicode(a, u)) - MultiByteToUnicodeString2(u, a); - prop = u; -} - -static void UnixTimeToProp(UInt32 val, NCOM::CPropVariant &prop) -{ - if (val != 0) - { - FILETIME ft; - NTime::UnixTimeToFileTime(val, ft); - prop = ft; - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - - NCOM::CPropVariant prop; - - switch (propID) - { - /* - case kpidFileSystem: - { - AString res = "Ext4"; - prop = res; - break; - } - */ - - case kpidIsTree: prop = true; break; - case kpidIsAux: prop = true; break; - case kpidINode: prop = true; break; - - case kpidClusterSize: prop = (UInt32)1 << _h.BlockBits; break; - // case kpidGroupSize: prop = (UInt64)_h.BlocksPerGroup << _h.BlockBits; break; - - case kpidFreeSpace: prop = (UInt64)_h.NumFreeBlocks << _h.BlockBits; break; - - case kpidCTime: UnixTimeToProp(_h.CTime, prop); break; - case kpidMTime: UnixTimeToProp(_h.WriteTime, prop); break; - case kpidMountTime: UnixTimeToProp(_h.MountTime, prop); break; - case kpidLastCheckTime: UnixTimeToProp(_h.LastCheckTime, prop); break; - - case kpidHostOS: - { - char temp[16]; - const char *s = NULL; - if (_h.CreatorOs < ARRAY_SIZE(kHostOS)) - s = kHostOS[_h.CreatorOs]; - else - { - ConvertUInt32ToString(_h.CreatorOs, temp); - s = temp; - } - prop = s; - break; - } - - case kpidRevision: prop = _h.RevLevel; break; - - case kpidINodeSize: prop = _h.InodeSize; break; - - case kpidId: - { - if (!IsEmptyData(_h.Uuid, 16)) - { - char s[16 * 2 + 2]; - for (unsigned i = 0; i < 16; i++) - PrintHex(_h.Uuid[i], s + i * 2); - s[16 * 2] = 0; - prop = s; - } - break; - } - - case kpidCodePage: if (_isUTF) prop = "UTF-8"; break; - - case kpidShortComment: - case kpidVolumeName: - StringToProp(_isUTF, _h.VolName, sizeof(_h.VolName), prop); break; - - case kpidLastMount: StringToProp(_isUTF, _h.LastMount, sizeof(_h.LastMount), prop); break; - - case kpidCharacts: FLAGS_TO_PROP(g_FeatureCompat_Flags, _h.FeatureCompat, prop); break; - case kpidFeatureIncompat: FLAGS_TO_PROP(g_FeatureIncompat_Flags, _h.FeatureIncompat, prop); break; - case kpidFeatureRoCompat: FLAGS_TO_PROP(g_FeatureRoCompat_Flags, _h.FeatureRoCompat, prop); break; - case kpidWrittenKB: if (_h.WrittenKB != 0) prop = _h.WrittenKB; break; - - case kpidPhySize: prop = _phySize; break; - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_linksError) v |= kpv_ErrorFlags_HeadersError; - if (_headersError) v |= kpv_ErrorFlags_HeadersError; - if (!_stream && v == 0 && _isArc) - v = kpv_ErrorFlags_HeadersError; - if (v != 0) - prop = v; - break; - } - - case kpidWarningFlags: - { - UInt32 v = 0; - if (_headersWarning) v |= kpv_ErrorFlags_HeadersError; - if (v != 0) - prop = v; - break; - } - } - - prop.Detach(value); - return S_OK; - - COM_TRY_END -} - - -/* -static const Byte kRawProps[] = -{ - // kpidSha1, -}; -*/ - -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) -{ - // *numProps = ARRAY_SIZE(kRawProps); - *numProps = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) -{ - // *propID = kRawProps[index]; - *propID = 0; - *name = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) -{ - *parentType = NParentType::kDir; - *parent = (UInt32)(Int32)-1; - - if (index >= _items.Size()) - return S_OK; - - const CItem &item = _items[index]; - - if (item.ParentNode < 0) - { - int aux = GetParentAux(item); - if (aux >= 0) - *parent = _items.Size() + aux; - } - else - { - int itemIndex = _nodes[_refs[item.ParentNode]].ItemIndex; - if (itemIndex >= 0) - *parent = itemIndex; - } - - return S_OK; -} - - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - if (propID == kpidName && _isUTF) - { - if (index < _items.Size()) - { - const AString &s = _items[index].Name; - if (!s.IsEmpty()) - { - *data = (void *)(const char *)s; - *dataSize = (UInt32)s.Len() + 1; - *propType = NPropDataType::kUtf8z; - } - return S_OK; - } - else - { - const AString &s = _auxItems[index - _items.Size()]; - { - *data = (void *)(const char *)s; - *dataSize = (UInt32)s.Len() + 1; - *propType = NPropDataType::kUtf8z; - } - return S_OK; - } - } - - return S_OK; -} - - -static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop) -{ - /* - UInt32 nano = 0; - if (t.Extra != 0) - { - UInt32 mask = t.Extra & 3; - if (mask != 0) - return; - nano = t.Extra >> 2; - } - UInt64 v; - if (t.Val == 0 && nano == 0) - return; - if (!NTime::UnixTime_to_FileTime64(t.Val, v)) - return; - if (nano != 0) - v += nano / 100; - - FILETIME ft; - ft.dwLowDateTime = (DWORD)v; - ft.dwHighDateTime = (DWORD)(v >> 32); - prop = ft; - */ - if (t.Val == 0) - return; - if (t.Extra != 0) - { - UInt32 mask = t.Extra & 3; - if (mask != 0) - return; - } - FILETIME ft; - if (NTime::UnixTime64ToFileTime(t.Val, ft)) - prop = ft; -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - if (index >= _items.Size()) - { - switch (propID) - { - case kpidPath: - case kpidName: - { - AString s = _auxItems[index - _items.Size()]; - prop = s; - break; - } - case kpidIsDir: prop = true; break; - case kpidIsAux: prop = true; break; - } - } - else - { - - const CItem &item = _items[index]; - const CNode &node = _nodes[_refs[item.Node]]; - bool isDir = node.IsDir(); - - switch (propID) - { - case kpidPath: - { - UString u; - { - AString s; - GetPath(index, s); - if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) - MultiByteToUnicodeString2(u, s); - } - prop = u; - break; - } - - case kpidName: - { - { - UString u; - { - if (!_isUTF || !ConvertUTF8ToUnicode(item.Name, u)) - MultiByteToUnicodeString2(u, item.Name); - } - prop = u; - } - break; - } - - case kpidIsDir: - { - bool isDir2 = isDir; - if (item.SymLinkItemIndex >= 0) - isDir2 = _nodes[_refs[_items[item.SymLinkItemIndex].Node]].IsDir(); - prop = isDir2; - break; - } - - case kpidSize: if (!isDir) prop = node.FileSize; break; - - case kpidPackSize: - if (!isDir) - { - UInt64 size; - if (GetPackSize(index, size)) - prop = size; - } - break; - - case kpidPosixAttrib: - { - /* - if (node.Type != 0 && node.Type < ARRAY_SIZE(k_TypeToMode)) - prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; - */ - prop = (UInt32)(node.Mode); - break; - } - - case kpidMTime: ExtTimeToProp(node.MTime, prop); break; - 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 kpidLinks: prop = node.NumLinks; break; - case kpidINode: prop = (UInt32)item.Node; break; - case kpidStreamId: if (!isDir) prop = (UInt32)item.Node; break; - case kpidCharacts: FLAGS_TO_PROP(g_NodeFlags, (UInt32)node.Flags, prop); break; - - case kpidSymLink: - { - if (node.SymLinkIndex >= 0) - { - UString u; - { - const AString &s = _symLinks[node.SymLinkIndex]; - if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) - MultiByteToUnicodeString2(u, s); - } - prop = u; - } - break; - } - } - - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -class CClusterInStream2: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - UInt64 _physPos; - UInt32 _curRem; -public: - unsigned BlockBits; - UInt64 Size; - CMyComPtr Stream; - CRecordVector Vector; - - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } - - HRESULT InitAndSeek() - { - _curRem = 0; - _virtPos = 0; - _physPos = 0; - if (Vector.Size() > 0) - { - _physPos = (Vector[0] << BlockBits); - return SeekToPhys(); - } - return S_OK; - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - - -STDMETHODIMP CClusterInStream2::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Size) - return S_OK; - { - UInt64 rem = Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - if (size == 0) - return S_OK; - - if (_curRem == 0) - { - const UInt32 blockSize = (UInt32)1 << BlockBits; - const UInt32 virtBlock = (UInt32)(_virtPos >> BlockBits); - const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); - const UInt32 phyBlock = Vector[virtBlock]; - - if (phyBlock == 0) - { - UInt32 cur = blockSize - offsetInBlock; - if (cur > size) - cur = size; - memset(data, 0, cur); - _virtPos += cur; - if (processedSize) - *processedSize = cur; - return S_OK; - } - - UInt64 newPos = ((UInt64)phyBlock << BlockBits) + offsetInBlock; - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - - _curRem = blockSize - offsetInBlock; - - for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) - _curRem += (UInt32)1 << BlockBits; - } - - if (size > _curRem) - size = _curRem; - HRESULT res = Stream->Read(data, size, &size); - if (processedSize) - *processedSize = size; - _physPos += size; - _virtPos += size; - _curRem -= size; - return res; -} - -STDMETHODIMP CClusterInStream2::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - if (_virtPos != (UInt64)offset) - _curRem = 0; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - - -class CExtInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - UInt64 _phyPos; -public: - unsigned BlockBits; - UInt64 Size; - CMyComPtr Stream; - CRecordVector Extents; - - CExtInStream() {} - - HRESULT StartSeek() - { - _virtPos = 0; - _phyPos = 0; - return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -STDMETHODIMP CExtInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Size) - return S_OK; - { - UInt64 rem = Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - if (size == 0) - return S_OK; - - UInt32 blockIndex = (UInt32)(_virtPos >> BlockBits); - - unsigned left = 0, right = Extents.Size(); - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (blockIndex < Extents[mid].VirtBlock) - right = mid; - else - left = mid; - } - - { - const CExtent &extent = Extents[left]; - if (blockIndex < extent.VirtBlock) - return E_FAIL; - UInt32 bo = blockIndex - extent.VirtBlock; - if (bo >= extent.Len) - return E_FAIL; - - UInt32 offset = ((UInt32)_virtPos & (((UInt32)1 << BlockBits) - 1)); - UInt32 remBlocks = extent.Len - bo; - UInt64 remBytes = ((UInt64)remBlocks << BlockBits); - remBytes -= offset; - - if (size > remBytes) - size = (UInt32)remBytes; - - if (!extent.IsInited) - { - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } - - UInt64 phyBlock = extent.PhyStart + bo; - UInt64 phy = (phyBlock << BlockBits) + offset; - - if (phy != _phyPos) - { - RINOK(Stream->Seek(phy, STREAM_SEEK_SET, NULL)); - _phyPos = phy; - } - - UInt32 realProcessSize = 0; - - HRESULT res = Stream->Read(data, size, &realProcessSize); - - _phyPos += realProcessSize; - _virtPos += realProcessSize; - if (processedSize) - *processedSize = realProcessSize; - return res; - } -} - - -STDMETHODIMP CExtInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - - - -HRESULT CHandler::FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector &blocks) -{ - const size_t blockSize = (size_t)1 << _h.BlockBits; - CByteBuffer &tempBuf = _tempBufs[level]; - tempBuf.Alloc(blockSize); - - PRF2(printf("\n level = %d, block = %7d", level, (unsigned)block)); - - RINOK(SeekAndRead(_stream, block, tempBuf, blockSize)); - - const Byte *p = tempBuf; - size_t num = (size_t)1 << (_h.BlockBits - 2); - - for (size_t i = 0; i < num; i++) - { - if (blocks.Size() == numBlocks) - break; - UInt32 val = GetUi32(p + 4 * i); - if (val >= _h.NumBlocks) - return S_FALSE; - - if (level != 0) - { - if (val == 0) - { - /* - size_t num = (size_t)1 << ((_h.BlockBits - 2) * (level)); - PRF2(printf("\n num empty = %3d", (unsigned)num)); - for (size_t k = 0; k < num; k++) - { - blocks.Add(0); - if (blocks.Size() == numBlocks) - return S_OK; - } - continue; - */ - return S_FALSE; - } - - RINOK(FillFileBlocks2(val, level - 1, numBlocks, blocks)); - continue; - } - - PRF2(printf("\n i = %3d, blocks.Size() = %6d, block = %5d ", i, blocks.Size(), (unsigned)val)); - - PRF(printf("\n i = %3d, start = %5d ", (unsigned)i, (unsigned)val)); - - blocks.Add(val); - } - - return S_OK; -} - - -static const unsigned kNumDirectNodeBlocks = 12; - -HRESULT CHandler::FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector &blocks) -{ - // ext2 supports zero blocks (blockIndex == 0). - - blocks.ClearAndReserve(numBlocks); - - for (unsigned i = 0; i < kNumDirectNodeBlocks; i++) - { - if (i == numBlocks) - return S_OK; - UInt32 val = GetUi32(p + 4 * i); - if (val >= _h.NumBlocks) - return S_FALSE; - blocks.Add(val); - } - - for (unsigned level = 0; level < 3; level++) - { - if (blocks.Size() == numBlocks) - break; - UInt32 val = GetUi32(p + 4 * (kNumDirectNodeBlocks + level)); - if (val >= _h.NumBlocks) - return S_FALSE; - - if (val == 0) - { - /* - size_t num = (size_t)1 << ((_h.BlockBits - 2) * (level + 1)); - for (size_t k = 0; k < num; k++) - { - blocks.Add(0); - if (blocks.Size() == numBlocks) - return S_OK; - } - continue; - */ - return S_FALSE; - } - - RINOK(FillFileBlocks2(val, level, numBlocks, blocks)); - } - - return S_OK; -} - - -static void AddSkipExtents(CRecordVector &extents, UInt32 virtBlock, UInt32 numBlocks) -{ - while (numBlocks != 0) - { - UInt32 len = numBlocks; - const UInt32 kLenMax = (UInt32)1 << 15; - if (len > kLenMax) - len = kLenMax; - CExtent e; - e.VirtBlock = virtBlock; - e.Len = (UInt16)len; - e.IsInited = false; - e.PhyStart = 0; - extents.Add(e); - virtBlock += len; - numBlocks -= len; - } -} - -static bool UpdateExtents(CRecordVector &extents, UInt32 block) -{ - if (extents.IsEmpty()) - { - if (block == 0) - return true; - AddSkipExtents(extents, 0, block); - return true; - } - - const CExtent &prev = extents.Back(); - if (block < prev.VirtBlock) - return false; - UInt32 prevEnd = prev.GetVirtEnd(); - if (block == prevEnd) - return true; - AddSkipExtents(extents, prevEnd, block - prevEnd); - return true; -} - - -HRESULT CHandler::FillExtents(const Byte *p, size_t size, CRecordVector &extents, int parentDepth) -{ - CExtentTreeHeader eth; - if (!eth.Parse(p)) - return S_FALSE; - - if (parentDepth >= 0 && eth.Depth != parentDepth - 1) // (eth.Depth >= parentDepth) - return S_FALSE; - - if (12 + 12 * (size_t)eth.NumEntries > size) - return S_FALSE; - - if (eth.Depth >= kNumTreeLevelsMax) - return S_FALSE; - - if (eth.Depth == 0) - { - for (unsigned i = 0; i < eth.NumEntries; i++) - { - CExtent e; - e.Parse(p + 12 + i * 12); - if (e.PhyStart == 0 - || e.PhyStart > _h.NumBlocks - || e.PhyStart + e.Len > _h.NumBlocks - || !e.IsLenOK()) - return S_FALSE; - if (!UpdateExtents(extents, e.VirtBlock)) - return S_FALSE; - extents.Add(e); - } - - return S_OK; - } - - const size_t blockSize = (size_t)1 << _h.BlockBits; - CByteBuffer &tempBuf = _tempBufs[eth.Depth]; - tempBuf.Alloc(blockSize); - - for (unsigned i = 0; i < eth.NumEntries; i++) - { - CExtentIndexNode e; - e.Parse(p + 12 + i * 12); - - if (e.PhyLeaf == 0 || e.PhyLeaf >= _h.NumBlocks) - return S_FALSE; - - if (!UpdateExtents(extents, e.VirtBlock)) - return S_FALSE; - - RINOK(SeekAndRead(_stream, e.PhyLeaf, tempBuf, blockSize)); - RINOK(FillExtents(tempBuf, blockSize, extents, eth.Depth)); - } - - return S_OK; -} - - -HRESULT CHandler::GetStream_Node(unsigned nodeIndex, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - - *stream = NULL; - - const CNode &node = _nodes[nodeIndex]; - - if (!node.IsFlags_EXTENTS()) - { - // maybe sparse file can have (node.NumBlocks == 0) ? - - /* The following code doesn't work correctly for some CentOS images, - where there are nodes with inline data and (node.NumBlocks != 0). - If you know better way to detect inline data, please notify 7-Zip developers. */ - - if (node.NumBlocks == 0 && node.FileSize < kNodeBlockFieldSize) - { - Create_BufInStream_WithNewBuffer(node.Block, (size_t)node.FileSize, stream); - return S_OK; - } - } - - if (node.FileSize >= ((UInt64)1 << 63)) - return S_FALSE; - - CMyComPtr streamTemp; - - UInt64 numBlocks64 = (node.FileSize + (UInt64)(((UInt32)1 << _h.BlockBits) - 1)) >> _h.BlockBits; - - if (node.IsFlags_EXTENTS()) - { - if ((UInt32)numBlocks64 != numBlocks64) - return S_FALSE; - - CExtInStream *streamSpec = new CExtInStream; - streamTemp = streamSpec; - - streamSpec->BlockBits = _h.BlockBits; - streamSpec->Size = node.FileSize; - streamSpec->Stream = _stream; - - RINOK(FillExtents(node.Block, kNodeBlockFieldSize, streamSpec->Extents, -1)); - - UInt32 end = 0; - if (!streamSpec->Extents.IsEmpty()) - end = streamSpec->Extents.Back().GetVirtEnd(); - if (end < numBlocks64) - { - AddSkipExtents(streamSpec->Extents, end, (UInt32)(numBlocks64 - end)); - // return S_FALSE; - } - - RINOK(streamSpec->StartSeek()); - } - else - { - { - UInt64 numBlocks2 = numBlocks64; - - if (numBlocks64 > kNumDirectNodeBlocks) - { - UInt64 rem = numBlocks64 - kNumDirectNodeBlocks; - const unsigned refBits = (_h.BlockBits - 2); - const size_t numRefsInBlocks = (size_t)1 << refBits; - numBlocks2++; - if (rem > numRefsInBlocks) - { - numBlocks2++; - const UInt64 numL2 = (rem - 1) >> refBits; - numBlocks2 += numL2; - if (numL2 > numRefsInBlocks) - { - numBlocks2++; - numBlocks2 += (numL2 - 1) >> refBits; - } - } - } - - const unsigned specBits = (node.IsFlags_HUGE() ? 0 : _h.BlockBits - 9); - const UInt32 specMask = ((UInt32)1 << specBits) - 1;; - if ((node.NumBlocks & specMask) != 0) - return S_FALSE; - const UInt64 numBlocks64_from_header = node.NumBlocks >> specBits; - if (numBlocks64_from_header < numBlocks2) - { - // why (numBlocks64_from_header > numBlocks2) in some cases? - // return S_FALSE; - } - } - - unsigned numBlocks = (unsigned)numBlocks64; - if (numBlocks != numBlocks64) - return S_FALSE; - - CClusterInStream2 *streamSpec = new CClusterInStream2; - streamTemp = streamSpec; - - streamSpec->BlockBits = _h.BlockBits; - streamSpec->Size = node.FileSize; - streamSpec->Stream = _stream; - - RINOK(FillFileBlocks(node.Block, numBlocks, streamSpec->Vector)); - streamSpec->InitAndSeek(); - } - - *stream = streamTemp.Detach(); - - return S_OK; - - COM_TRY_END -} - - -HRESULT CHandler::ExtractNode(unsigned nodeIndex, CByteBuffer &data) -{ - data.Free(); - const CNode &node = _nodes[nodeIndex]; - size_t size = (size_t)node.FileSize; - if (size != node.FileSize) - return S_FALSE; - CMyComPtr inSeqStream; - RINOK(GetStream_Node(nodeIndex, &inSeqStream)); - if (!inSeqStream) - return S_FALSE; - data.Alloc(size); - _totalRead += size; - return ReadStream_FALSE(inSeqStream, data, size); -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size() + _auxItems.Size(); - if (numItems == 0) - return S_OK; - - UInt64 totalSize = 0; - UInt32 i; - - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - if (index >= _items.Size()) - continue; - const CItem &item = _items[index]; - const CNode &node = _nodes[_refs[item.Node]]; - if (!node.IsDir()) - totalSize += node.FileSize; - } - - extractCallback->SetTotal(totalSize); - - UInt64 totalPackSize; - totalSize = totalPackSize = 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++) - { - lps->InSize = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - - if (i == numItems) - break; - - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - UInt32 index = allFilesMode ? i : indices[i]; - - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - - if (index >= _items.Size()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - const CItem &item = _items[index]; - const CNode &node = _nodes[_refs[item.Node]]; - - if (node.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - UInt64 unpackSize = node.FileSize; - totalSize += unpackSize; - UInt64 packSize; - if (GetPackSize(index, packSize)) - totalPackSize += packSize; - - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - int res = NExtract::NOperationResult::kDataError; - { - CMyComPtr inSeqStream; - HRESULT hres = GetStream(index, &inSeqStream); - if (hres == S_FALSE || !inSeqStream) - { - if (hres == E_OUTOFMEMORY) - return hres; - res = NExtract::NOperationResult::kUnsupportedMethod; - } - else - { - RINOK(hres); - { - hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); - if (hres == S_OK) - { - if (copyCoderSpec->TotalSize == unpackSize) - res = NExtract::NOperationResult::kOK; - } - else if (hres == E_NOTIMPL) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - } - else if (hres != S_FALSE) - { - RINOK(hres); - } - } - } - } - RINOK(extractCallback->SetOperationResult(res)); - } - - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - *stream = NULL; - if (index >= _items.Size()) - return S_FALSE; - return GetStream_Node(_refs[_items[index].Node], stream); -} - - -API_FUNC_static_IsArc IsArc_Ext(const Byte *p, size_t size) -{ - if (size < kHeaderSize) - return k_IsArc_Res_NEED_MORE; - CHeader h; - if (!h.Parse(p + kHeaderDataOffset)) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -static const Byte k_Signature[] = { 0x53, 0xEF }; - -REGISTER_ARC_I( - "Ext", "ext ext2 ext3 ext4 img", 0, 0xC7, - k_Signature, - 0x438, - 0, - IsArc_Ext) - -}} +// ExtHandler.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +// #include +// #define PRF2(x) x + +#define PRF2(x) + +#ifdef SHOW_DEBUG_INFO +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyLinux.h" +#include "../../Common/StringConvert.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +using namespace NWindows; + +UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size); + +namespace NArchive { +namespace NExt { + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define LE_16(offs, dest) dest = Get16(p + (offs)); +#define LE_32(offs, dest) dest = Get32(p + (offs)); +#define LE_64(offs, dest) dest = Get64(p + (offs)); + +#define HI_16(offs, dest) dest |= (((UInt32)Get16(p + (offs))) << 16); +#define HI_32(offs, dest) dest |= (((UInt64)Get32(p + (offs))) << 32); + +/* +static UInt32 g_Crc32CTable[256]; + +static struct CInitCrc32C +{ + CInitCrc32C() + { + for (unsigned i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (0x82F63B78 & ~((r & 1) - 1)); + g_Crc32CTable[i] = r; + } + } +} g_InitCrc32C; + +#define CRC32C_INIT_VAL 0xFFFFFFFF +#define CRC32C_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC32C_UPDATE_BYTE(crc, b) (g_Crc32CTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +static UInt32 Crc32C_Update(UInt32 crc, Byte const *data, size_t size) +{ + for (size_t i = 0; i < size; i++) + crc = CRC32C_UPDATE_BYTE(crc, data[i]); + return crc; +} + +static UInt32 Crc32C_Calc(Byte const *data, size_t size) +{ + return Crc32C_Update(CRC32C_INIT_VAL, data, size); +} +*/ + + +#define CRC16_INIT_VAL 0xFFFF + +#define Crc16Update(crc, data, size) LzhCrc16Update(crc, data, size) + +static UInt32 Crc16Calc(Byte const *data, size_t size) +{ + return Crc16Update(CRC16_INIT_VAL, data, size); +} + + +#define EXT4_GOOD_OLD_INODE_SIZE 128 +#define EXT_NODE_SIZE_MIN 128 + + +// inodes numbers + +// #define k_INODE_BAD 1 // Bad blocks +#define k_INODE_ROOT 2 // Root dir +// #define k_INODE_USR_QUOTA 3 // User quota +// #define k_INODE_GRP_QUOTA 4 // Group quota +// #define k_INODE_BOOT_LOADER 5 // Boot loader +// #define k_INODE_UNDEL_DIR 6 // Undelete dir +#define k_INODE_RESIZE 7 // Reserved group descriptors +// #define k_INODE_JOURNAL 8 // Journal + +// First non-reserved inode for old ext4 filesystems +#define k_INODE_GOOD_OLD_FIRST 11 + +static const char * const k_SysInode_Names[] = +{ + "0" + , "Bad" + , "Root" + , "UserQuota" + , "GroupQuota" + , "BootLoader" + , "Undelete" + , "Resize" + , "Journal" + , "Exclude" + , "Replica" +}; + +static const char * const kHostOS[] = +{ + "Linux" + , "Hurd" + , "Masix" + , "FreeBSD" + , "Lites" +}; + +static const char * const g_FeatureCompat_Flags[] = +{ + "DIR_PREALLOC" + , "IMAGIC_INODES" + , "HAS_JOURNAL" + , "EXT_ATTR" + , "RESIZE_INODE" + , "DIR_INDEX" + , "LAZY_BG" // not in Linux + , NULL // { 7, "EXCLUDE_INODE" // not used + , NULL // { 8, "EXCLUDE_BITMAP" // not in kernel + , "SPARSE_SUPER2" +}; + + +#define EXT4_FEATURE_INCOMPAT_FILETYPE (1 << 1) +#define EXT4_FEATURE_INCOMPAT_64BIT (1 << 7) + +static const char * const g_FeatureIncompat_Flags[] = +{ + "COMPRESSION" + , "FILETYPE" + , "RECOVER" /* Needs recovery */ + , "JOURNAL_DEV" /* Journal device */ + , "META_BG" + , NULL + , "EXTENTS" /* extents support */ + , "64BIT" + , "MMP" + , "FLEX_BG" + , "EA_INODE" /* EA in inode */ + , NULL + , "DIRDATA" /* data in dirent */ + , "BG_USE_META_CSUM" /* use crc32c for bg */ + , "LARGEDIR" /* >2GB or 3-lvl htree */ + , "INLINE_DATA" /* data in inode */ + , "ENCRYPT" // 16 +}; + + +static const UInt32 RO_COMPAT_GDT_CSUM = 1 << 4; +static const UInt32 RO_COMPAT_METADATA_CSUM = 1 << 10; + +static const char * const g_FeatureRoCompat_Flags[] = +{ + "SPARSE_SUPER" + , "LARGE_FILE" + , "BTREE_DIR" + , "HUGE_FILE" + , "GDT_CSUM" + , "DIR_NLINK" + , "EXTRA_ISIZE" + , "HAS_SNAPSHOT" + , "QUOTA" + , "BIGALLOC" + , "METADATA_CSUM" + , "REPLICA" + , "READONLY" // 12 +}; + + + +static const UInt32 k_NodeFlags_HUGE = (UInt32)1 << 18; +static const UInt32 k_NodeFlags_EXTENTS = (UInt32)1 << 19; + + +static const char * const g_NodeFlags[] = +{ + "SECRM" + , "UNRM" + , "COMPR" + , "SYNC" + , "IMMUTABLE" + , "APPEND" + , "NODUMP" + , "NOATIME" + , "DIRTY" + , "COMPRBLK" + , "NOCOMPR" + , "ENCRYPT" + , "INDEX" + , "IMAGIC" + , "JOURNAL_DATA" + , "NOTAIL" + , "DIRSYNC" + , "TOPDIR" + , "HUGE_FILE" + , "EXTENTS" + , NULL + , "EA_INODE" + , "EOFBLOCKS" + , NULL + , NULL + , NULL + , NULL + , NULL + , "INLINE_DATA" // 28 +}; + + +enum +{ + k_Type_UNKNOWN, + k_Type_REG_FILE, + k_Type_DIR, + k_Type_CHRDEV, + k_Type_BLKDEV, + k_Type_FIFO, + k_Type_SOCK, + k_Type_SYMLINK +}; + +static const UInt16 k_TypeToMode[] = +{ + 0, + MY_LIN_S_IFREG, + MY_LIN_S_IFDIR, + MY_LIN_S_IFCHR, + MY_LIN_S_IFBLK, + MY_LIN_S_IFIFO, + MY_LIN_S_IFSOCK, + MY_LIN_S_IFLNK +}; + + +#define EXT4_GOOD_OLD_REV 0 // old (original) format +// #define EXT4_DYNAMIC_REV 1 // V2 format with dynamic inode sizes + +struct CHeader +{ + unsigned BlockBits; + unsigned ClusterBits; + + UInt32 NumInodes; + UInt64 NumBlocks; + // UInt64 NumBlocksSuper; + UInt64 NumFreeBlocks; + UInt32 NumFreeInodes; + // UInt32 FirstDataBlock; + + UInt32 BlocksPerGroup; + UInt32 ClustersPerGroup; + UInt32 InodesPerGroup; + + UInt32 MountTime; + UInt32 WriteTime; + + // UInt16 NumMounts; + // UInt16 NumMountsMax; + + // UInt16 State; + // UInt16 Errors; + // UInt16 MinorRevLevel; + + UInt32 LastCheckTime; + // UInt32 CheckInterval; + UInt32 CreatorOs; + UInt32 RevLevel; + + // UInt16 DefResUid; + // UInt16 DefResGid; + + UInt32 FirstInode; + UInt16 InodeSize; + UInt16 BlockGroupNr; + UInt32 FeatureCompat; + UInt32 FeatureIncompat; + UInt32 FeatureRoCompat; + Byte Uuid[16]; + char VolName[16]; + char LastMount[64]; + // UInt32 BitmapAlgo; + + UInt32 JournalInode; + UInt16 GdSize; // = 64 if 64-bit(); + UInt32 CTime; + UInt16 MinExtraISize; + // UInt16 WantExtraISize; + // UInt32 Flags; + // Byte LogGroupsPerFlex; + // Byte ChecksumType; + + UInt64 WrittenKB; + + bool IsOldRev() const { return RevLevel == EXT4_GOOD_OLD_REV; } + + UInt64 GetNumGroups() const { return (NumBlocks + BlocksPerGroup - 1) / BlocksPerGroup; } + UInt64 GetNumGroups2() const { return ((UInt64)NumInodes + InodesPerGroup - 1) / InodesPerGroup; } + + bool IsThereFileType() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_FILETYPE) != 0; } + bool Is64Bit() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0; } + 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); +}; + + +static int inline GetLog(UInt32 num) +{ + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == num) + return (int)i; + return -1; +} + +static bool inline IsEmptyData(const Byte *data, unsigned size) +{ + for (unsigned i = 0; i < size; i++) + if (data[i] != 0) + return false; + return true; +} + + +bool CHeader::Parse(const Byte *p) +{ + if (GetUi16(p + 0x38) != 0xEF53) + return false; + + LE_32 (0x18, BlockBits) + LE_32 (0x1C, ClusterBits) + + if (ClusterBits != 0 && BlockBits != ClusterBits) + return false; + + if (BlockBits > 16 - 10) + return false; + BlockBits += 10; + + LE_32 (0x00, NumInodes) + LE_32 (0x04, NumBlocks) + // LE_32 (0x08, NumBlocksSuper); + LE_32 (0x0C, NumFreeBlocks) + LE_32 (0x10, NumFreeInodes) + + if (NumInodes < 2 || NumInodes <= NumFreeInodes) + return false; + + UInt32 FirstDataBlock; + LE_32 (0x14, FirstDataBlock) + if (FirstDataBlock != (unsigned)(BlockBits == 10 ? 1 : 0)) + return false; + + LE_32 (0x20, BlocksPerGroup) + LE_32 (0x24, ClustersPerGroup) + + if (BlocksPerGroup != ClustersPerGroup) + return false; + if (BlocksPerGroup == 0) + return false; + if (BlocksPerGroup != ((UInt32)1 << (BlockBits + 3))) + { + // it's allowed in ext2 + // return false; + } + + LE_32 (0x28, InodesPerGroup) + + if (InodesPerGroup < 1 || InodesPerGroup > NumInodes) + return false; + + LE_32 (0x2C, MountTime) + LE_32 (0x30, WriteTime) + + // LE_16 (0x34, NumMounts); + // LE_16 (0x36, NumMountsMax); + + // LE_16 (0x3A, State); + // LE_16 (0x3C, Errors); + // LE_16 (0x3E, MinorRevLevel); + + LE_32 (0x40, LastCheckTime) + // LE_32 (0x44, CheckInterval); + LE_32 (0x48, CreatorOs) + LE_32 (0x4C, RevLevel) + + // LE_16 (0x50, DefResUid); + // LE_16 (0x52, DefResGid); + + FirstInode = k_INODE_GOOD_OLD_FIRST; + InodeSize = EXT4_GOOD_OLD_INODE_SIZE; + + if (!IsOldRev()) + { + LE_32 (0x54, FirstInode) + LE_16 (0x58, InodeSize) + if (FirstInode < k_INODE_GOOD_OLD_FIRST) + return false; + if (InodeSize > ((UInt32)1 << BlockBits) + || InodeSize < EXT_NODE_SIZE_MIN + || GetLog(InodeSize) < 0) + return false; + } + + LE_16 (0x5A, BlockGroupNr) + LE_32 (0x5C, FeatureCompat) + LE_32 (0x60, FeatureIncompat) + LE_32 (0x64, FeatureRoCompat) + + memcpy(Uuid, p + 0x68, sizeof(Uuid)); + memcpy(VolName, p + 0x78, sizeof(VolName)); + memcpy(LastMount, p + 0x88, sizeof(LastMount)); + + // LE_32 (0xC8, BitmapAlgo); + + LE_32 (0xE0, JournalInode) + + LE_16 (0xFE, GdSize) + + LE_32 (0x108, CTime) + + if (Is64Bit()) + { + HI_32(0x150, NumBlocks) + // HI_32(0x154, NumBlocksSuper); + HI_32(0x158, NumFreeBlocks) + } + + if (NumBlocks >= (UInt64)1 << (63 - BlockBits)) + return false; + + + LE_16(0x15C, MinExtraISize) + // LE_16(0x15E, WantExtraISize); + // LE_32(0x160, Flags); + // LE_16(0x164, RaidStride); + // LE_16(0x166, MmpInterval); + // LE_64(0x168, MmpBlock); + + // LogGroupsPerFlex = p[0x174]; + // ChecksumType = p[0x175]; + + LE_64 (0x178, WrittenKB) + + // LE_32(0x194, ErrorCount); + // LE_32(0x198, ErrorTime); + // LE_32(0x19C, ErrorINode); + // LE_32(0x1A0, ErrorBlock); + + if (NumBlocks < 1) + return false; + if (NumFreeBlocks > NumBlocks) + return false; + + if (GetNumGroups() != GetNumGroups2()) + return false; + + return true; +} + + +struct CGroupDescriptor +{ + UInt64 BlockBitmap; + UInt64 InodeBitmap; + UInt64 InodeTable; + UInt32 NumFreeBlocks; + UInt32 NumFreeInodes; + UInt32 DirCount; + + UInt16 Flags; + + UInt64 ExcludeBitmap; + UInt32 BlockBitmap_Checksum; + UInt32 InodeBitmap_Checksum; + UInt32 UnusedCount; + UInt16 Checksum; + + void Parse(const Byte *p, unsigned size); +}; + +void CGroupDescriptor::Parse(const Byte *p, unsigned size) +{ + LE_32 (0x00, BlockBitmap) + LE_32 (0x04, InodeBitmap) + LE_32 (0x08, InodeTable) + LE_16 (0x0C, NumFreeBlocks) + LE_16 (0x0E, NumFreeInodes) + LE_16 (0x10, DirCount) + LE_16 (0x12, Flags) + LE_32 (0x14, ExcludeBitmap) + LE_16 (0x18, BlockBitmap_Checksum) + LE_16 (0x1A, InodeBitmap_Checksum) + LE_16 (0x1C, UnusedCount) + LE_16 (0x1E, Checksum) + + if (size >= 64) + { + p += 0x20; + HI_32 (0x00, BlockBitmap) + HI_32 (0x04, InodeBitmap) + HI_32 (0x08, InodeTable) + HI_16 (0x0C, NumFreeBlocks) + HI_16 (0x0E, NumFreeInodes) + HI_16 (0x10, DirCount) + HI_16 (0x12, UnusedCount) // instead of Flags + HI_32 (0x14, ExcludeBitmap) + HI_16 (0x18, BlockBitmap_Checksum) + HI_16 (0x1A, InodeBitmap_Checksum) + // HI_16 (0x1C, Reserved); + } +} + + +static const unsigned kNodeBlockFieldSize = 60; + +struct CExtentTreeHeader +{ + UInt16 NumEntries; + UInt16 MaxEntries; + UInt16 Depth; + // UInt32 Generation; + + bool Parse(const Byte *p) + { + LE_16 (0x02, NumEntries) + LE_16 (0x04, MaxEntries) + LE_16 (0x06, Depth) + // LE_32 (0x08, Generation); + return Get16(p) == 0xF30A; // magic + } +}; + +struct CExtentIndexNode +{ + UInt32 VirtBlock; + UInt64 PhyLeaf; + + void Parse(const Byte *p) + { + LE_32 (0x00, VirtBlock) + LE_32 (0x04, PhyLeaf) + PhyLeaf |= (((UInt64)Get16(p + 8)) << 32); + // unused 16-bit field (at offset 0x0A) can be not zero in some cases. Why? + } +}; + +struct CExtent +{ + UInt32 VirtBlock; + UInt16 Len; + bool IsInited; + UInt64 PhyStart; + + UInt32 GetVirtEnd() const { return VirtBlock + Len; } + bool IsLenOK() const { return VirtBlock + Len >= VirtBlock; } + + void Parse(const Byte *p) + { + LE_32 (0x00, VirtBlock) + LE_16 (0x04, Len) + IsInited = true; + if (Len > (UInt32)0x8000) + { + IsInited = false; + Len = (UInt16)(Len - (UInt32)0x8000); + } + LE_32 (0x08, PhyStart) + UInt16 hi; + LE_16 (0x06, hi) + PhyStart |= ((UInt64)hi << 32); + } +}; + + + +struct CExtTime +{ + UInt32 Val; + UInt32 Extra; +}; + +struct CNode +{ + Int32 ParentNode; // in _refs[], -1 if not dir + int ItemIndex; // in _items[] , (set as >=0 only for if (IsDir()) + int SymLinkIndex; // in _symLinks[] + int DirIndex; // in _dirs[] + + UInt16 Mode; + UInt32 Uid; // fixed 21.02 + UInt32 Gid; // fixed 21.02 + // UInt16 Checksum; + + UInt64 FileSize; + CExtTime MTime; + CExtTime ATime; + CExtTime CTime; + CExtTime ChangeTime; + // CExtTime DTime; + + UInt64 NumBlocks; + UInt32 NumLinks; + UInt32 Flags; + + UInt32 NumLinksCalced; + + Byte Block[kNodeBlockFieldSize]; + + CNode(): + ParentNode(-1), + ItemIndex(-1), + SymLinkIndex(-1), + DirIndex(-1), + NumLinksCalced(0) + {} + + bool IsFlags_HUGE() const { return (Flags & k_NodeFlags_HUGE) != 0; } + bool IsFlags_EXTENTS() const { return (Flags & k_NodeFlags_EXTENTS) != 0; } + + bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } + bool IsRegular() const { return MY_LIN_S_ISREG(Mode); } + bool IsLink() const { return MY_LIN_S_ISLNK(Mode); } + + bool Parse(const Byte *p, const CHeader &_h); +}; + + +bool CNode::Parse(const Byte *p, const CHeader &_h) +{ + MTime.Extra = 0; + ATime.Extra = 0; + CTime.Extra = 0; + CTime.Val = 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, ChangeTime.Val) + LE_32 (0x10, MTime.Val) + // LE_32 (0x14, DTime.Val); + LE_16 (0x18, Gid) + LE_16 (0x1A, NumLinks) + + LE_32 (0x1C, NumBlocks) + LE_32 (0x20, Flags) + // LE_32 (0x24, Union osd1); + + memcpy(Block, p + 0x28, kNodeBlockFieldSize); + + // LE_32 (0x64, Generation); // File version (for NFS) + // LE_32 (0x68, ACL); + + { + UInt32 highSize; + LE_32 (0x6C, highSize) // In ext2/3 this field was named i_dir_acl + + if (IsRegular()) // do we need that check ? + FileSize |= ((UInt64)highSize << 32); + } + + // UInt32 fragmentAddress; + // LE_32 (0x70, fragmentAddress); + + // osd2 + { + // Linux; + // ext2: + // Byte FragmentNumber = p[0x74]; + // Byte FragmentSize = p[0x74 + 1]; + + // ext4: + UInt32 numBlocksHigh; + LE_16 (0x74, numBlocksHigh) + NumBlocks |= (UInt64)numBlocksHigh << 32; + + HI_16 (0x74 + 4, Uid) + HI_16 (0x74 + 6, Gid) + /* + UInt32 checksum; + LE_16 (0x74 + 8, checksum); + checksum = checksum; + */ + } + + // 0x74: Byte Union osd2[12]; + + if (_h.InodeSize > 128) + { + // InodeSize is power of 2, so the following check is not required: + // if (_h.InodeSize < 128 + 2) return false; + UInt16 extra_isize; + LE_16 (0x80, extra_isize) + if (128 + extra_isize > _h.InodeSize) + return false; + if (extra_isize >= 0x1C) + { + // UInt16 checksumUpper; + // LE_16 (0x82, checksumUpper); + LE_32 (0x84, ChangeTime.Extra) + LE_32 (0x88, MTime.Extra) + LE_32 (0x8C, ATime.Extra) + LE_32 (0x90, CTime.Val) + LE_32 (0x94, CTime.Extra) + // LE_32 (0x98, VersionHi) + } + } + + PRF(printf("size = %5d", (unsigned)FileSize)); + + return true; +} + + +struct CItem +{ + unsigned Node; // in _refs[] + int ParentNode; // in _refs[] + int SymLinkItemIndex; // in _items[], if the Node contains SymLink to existing dir + Byte Type; + + AString Name; + + CItem(): + Node(0), + ParentNode(-1), + SymLinkItemIndex(-1), + Type(k_Type_UNKNOWN) + {} + + void Clear() + { + Node = 0; + ParentNode = -1; + SymLinkItemIndex = -1; + Type = k_Type_UNKNOWN; + Name.Empty(); + } + + bool IsDir() const { return Type == k_Type_DIR; } + // bool IsNotDir() const { return Type != k_Type_DIR && Type != k_Type_UNKNOWN; } +}; + + + +static const unsigned kNumTreeLevelsMax = 6; // must be >= 3 + + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IArchiveGetRawProps, + IInArchiveGetStream +) + CObjectVector _items; + CIntVector _refs; // iNode -> (index in _nodes). if (_refs[iNode] < 0), that node is not filled + CRecordVector _nodes; + CObjectVector _dirs; // each CUIntVector contains indexes in _items[] only for dir items; + AStringVector _symLinks; + AStringVector _auxItems; + int _auxSysIndex; + int _auxUnknownIndex; + + CMyComPtr _stream; + UInt64 _phySize; + bool _isArc; + bool _headersError; + bool _headersWarning; + bool _linksError; + + bool _isUTF; + + CHeader _h; + + IArchiveOpenCallback *_openCallback; + UInt64 _totalRead; + UInt64 _totalReadPrev; + + CByteBuffer _tempBufs[kNumTreeLevelsMax]; + + + HRESULT CheckProgress2() + { + const UInt64 numFiles = _items.Size(); + return _openCallback->SetCompleted(&numFiles, &_totalRead); + } + + HRESULT CheckProgress() + { + HRESULT res = S_OK; + if (_openCallback) + { + if (_totalRead - _totalReadPrev >= ((UInt32)1 << 20)) + { + _totalReadPrev = _totalRead; + res = CheckProgress2(); + } + } + return res; + } + + + int GetParentAux(const CItem &item) const + { + if (item.Node < _h.FirstInode && _auxSysIndex >= 0) + return _auxSysIndex; + return _auxUnknownIndex; + } + + HRESULT SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size); + HRESULT ParseDir(const Byte *data, size_t size, unsigned iNodeDir); + int FindTargetItem_for_SymLink(unsigned dirNode, const AString &path) const; + + HRESULT FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector &blocks); + HRESULT FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector &blocks); + HRESULT FillExtents(const Byte *p, size_t size, CRecordVector &extents, int parentDepth); + + HRESULT GetStream_Node(unsigned nodeIndex, ISequentialInStream **stream); + HRESULT ExtractNode(unsigned nodeIndex, CByteBuffer &data); + + void ClearRefs(); + HRESULT Open2(IInStream *inStream); + + void GetPath(unsigned index, AString &s) const; + bool GetPackSize(unsigned index, UInt64 &res) const; +}; + + + +HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned iNodeDir) +{ + bool isThereSelfLink = false; + + PRF(printf("\n\n========= node = %5d size = %5d", (unsigned)iNodeDir, (unsigned)size)); + + CNode &nodeDir = _nodes[_refs[iNodeDir]]; + nodeDir.DirIndex = (int)_dirs.Size(); + CUIntVector &dir = _dirs.AddNew(); + int parentNode = -1; + + CItem item; + + for (;;) + { + if (size == 0) + break; + if (size < 8) + return S_FALSE; + UInt32 iNode; + LE_32 (0x00, iNode) + unsigned recLen; + LE_16 (0x04, recLen) + const unsigned nameLen = p[6]; + const Byte type = p[7]; + + if (recLen > size) + return S_FALSE; + if (nameLen + 8 > recLen) + return S_FALSE; + + if (iNode >= _refs.Size()) + return S_FALSE; + + item.Clear(); + + if (_h.IsThereFileType()) + item.Type = type; + else if (type != 0) + return S_FALSE; + + item.ParentNode = (int)iNodeDir; + item.Node = iNode; + item.Name.SetFrom_CalcLen((const char *)(p + 8), nameLen); + + p += recLen; + size -= recLen; + + if (item.Name.Len() != nameLen) + return S_FALSE; + + if (_isUTF) + { + // 21.07 : we force UTF8 + // _isUTF = CheckUTF8_AString(item.Name); + } + + if (iNode == 0) + { + /* + ext3 deleted?? + if (item.Name.Len() != 0) + return S_FALSE; + */ + + PRF(printf("\n EMPTY %6d %d %s", (unsigned)recLen, (unsigned)type, (const char *)item.Name)); + if (type == 0xDE) + { + // checksum + } + continue; + } + + const int nodeIndex = _refs[iNode]; + if (nodeIndex < 0) + return S_FALSE; + CNode &node = _nodes[nodeIndex]; + + if (_h.IsThereFileType() && type != 0) + { + if (type >= Z7_ARRAY_SIZE(k_TypeToMode)) + return S_FALSE; + if (k_TypeToMode[type] != (node.Mode & MY_LIN_S_IFMT)) + return S_FALSE; + } + + node.NumLinksCalced++; + + PRF(printf("\n%s %6d %s", item.IsDir() ? "DIR " : " ", (unsigned)item.Node, (const char *)item.Name)); + + if (item.Name[0] == '.') + { + if (item.Name[1] == 0) + { + if (isThereSelfLink) + return S_FALSE; + isThereSelfLink = true; + if (iNode != iNodeDir) + return S_FALSE; + continue; + } + + if (item.Name[1] == '.' && item.Name[2] == 0) + { + if (parentNode >= 0) + return S_FALSE; + if (!node.IsDir()) + return S_FALSE; + if (iNode == iNodeDir && iNode != k_INODE_ROOT) + return S_FALSE; + + parentNode = (int)iNode; + + if (nodeDir.ParentNode < 0) + nodeDir.ParentNode = (int)iNode; + else if ((unsigned)nodeDir.ParentNode != iNode) + return S_FALSE; + + continue; + } + } + + if (iNode == iNodeDir) + return S_FALSE; + + if (parentNode < 0) + return S_FALSE; + + if (node.IsDir()) + { + if (node.ParentNode < 0) + node.ParentNode = (int)iNodeDir; + else if ((unsigned)node.ParentNode != iNodeDir) + return S_FALSE; + const unsigned itemIndex = _items.Size(); + dir.Add(itemIndex); + node.ItemIndex = (int)itemIndex; + } + + _items.Add(item); + } + + if (parentNode < 0 || !isThereSelfLink) + return S_FALSE; + + return S_OK; +} + + +static int CompareItemsNames(const unsigned *p1, const unsigned *p2, void *param) +{ + const CObjectVector &items = *(const CObjectVector *)param; + return strcmp(items[*p1].Name, items[*p2].Name); +} + + +int CHandler::FindTargetItem_for_SymLink(unsigned iNode, const AString &path) const +{ + unsigned pos = 0; + + if (path.IsEmpty()) + return -1; + + if (path[0] == '/') + { + iNode = k_INODE_ROOT; + if (iNode >= _refs.Size()) + return -1; + pos = 1; + } + + AString s; + + while (pos != path.Len()) + { + const CNode &node = _nodes[_refs[iNode]]; + const int slash = path.Find('/', pos); + + if (slash < 0) + { + s = path.Ptr(pos); + pos = path.Len(); + } + else + { + s.SetFrom(path.Ptr(pos), (unsigned)slash - pos); + pos = (unsigned)slash + 1; + } + + if (s[0] == '.') + { + if (s[1] == 0) + continue; + else if (s[1] == '.' && s[2] == 0) + { + if (node.ParentNode < 0) + return -1; + if (iNode == k_INODE_ROOT) + return -1; + iNode = (unsigned)node.ParentNode; + continue; + } + } + + if (node.DirIndex < 0) + return -1; + + const CUIntVector &dir = _dirs[node.DirIndex]; + + /* + for (unsigned i = 0;; i++) + { + if (i >= dir.Size()) + return -1; + const CItem &item = _items[dir[i]]; + if (item.Name == s) + { + iNode = item.Node; + break; + } + } + */ + + unsigned left = 0, right = dir.Size(); + for (;;) + { + if (left == right) + return -1; + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const CItem &item = _items[dir[mid]]; + const int comp = strcmp(s, item.Name); + if (comp == 0) + { + iNode = item.Node; + break; + } + if (comp < 0) + right = mid; + else + left = mid + 1; + } + } + + return _nodes[_refs[iNode]].ItemIndex; +} + + +HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size) +{ + if (block == 0 || block >= _h.NumBlocks) + return S_FALSE; + if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block) + return S_FALSE; + RINOK(InStream_SeekSet(inStream, (UInt64)block << _h.BlockBits)) + _totalRead += size; + return ReadStream_FALSE(inStream, data, size); +} + + +static const unsigned kHeaderSize = 2 * 1024; +static const unsigned kHeaderDataOffset = 1024; + +HRESULT CHandler::Open2(IInStream *inStream) +{ + { + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)) + if (!_h.Parse(buf + kHeaderDataOffset)) + return S_FALSE; + if (_h.BlockGroupNr != 0) + return S_FALSE; // it's just copy of super block + } + + { + // ---------- Read groups and nodes ---------- + + unsigned numGroups; + { + const UInt64 numGroups64 = _h.GetNumGroups(); + if (numGroups64 > (UInt32)1 << 31) + return S_FALSE; + numGroups = (unsigned)numGroups64; + } + + unsigned gdBits = 5; + if (_h.Is64Bit()) + { + if (_h.GdSize != 64) + return S_FALSE; + gdBits = 6; + } + + _isArc = true; + _phySize = _h.GetPhySize(); + + if (_openCallback) + { + RINOK(_openCallback->SetTotal(NULL, &_phySize)) + } + + UInt64 fileSize = 0; + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) + + CRecordVector groups; + + { + // ---------- Read groups ---------- + + CByteBuffer gdBuf; + const size_t gdBufSize = (size_t)numGroups << gdBits; + if ((gdBufSize >> gdBits) != numGroups) + return S_FALSE; + gdBuf.Alloc(gdBufSize); + RINOK(SeekAndRead(inStream, (_h.BlockBits <= 10 ? 2 : 1), gdBuf, gdBufSize)) + + for (unsigned i = 0; i < numGroups; i++) + { + CGroupDescriptor gd; + + const Byte *p = gdBuf + ((size_t)i << gdBits); + const unsigned gd_Size = (unsigned)1 << gdBits; + gd.Parse(p, gd_Size); + + if (_h.UseMetadataChecksum()) + { + // use CRC32c + } + else if (_h.UseGdtChecksum()) + { + UInt32 crc = Crc16Calc(_h.Uuid, sizeof(_h.Uuid)); + Byte i_le[4]; + SetUi32(i_le, i) + crc = Crc16Update(crc, i_le, 4); + crc = Crc16Update(crc, p, 32 - 2); + if (gd_Size != 32) + crc = Crc16Update(crc, p + 32, gd_Size - 32); + if (crc != gd.Checksum) + return S_FALSE; + } + + groups.Add(gd); + } + } + + { + // ---------- Read nodes ---------- + + if (_h.NumInodes < _h.NumFreeInodes) + return S_FALSE; + + UInt32 numNodes = _h.InodesPerGroup; + if (numNodes > _h.NumInodes) + numNodes = _h.NumInodes; + const size_t nodesDataSize = (size_t)numNodes * _h.InodeSize; + + if (nodesDataSize / _h.InodeSize != numNodes) + return S_FALSE; + + // that code to reduce false detecting cases + if (nodesDataSize > fileSize) + { + if (numNodes > (1 << 24)) + return S_FALSE; + } + + const UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1; + // numReserveInodes = _h.NumInodes + 1; + if (numReserveInodes != 0) + { + _nodes.Reserve(numReserveInodes); + _refs.Reserve(numReserveInodes); + } + + CByteBuffer nodesData; + nodesData.Alloc(nodesDataSize); + + CByteBuffer nodesMap; + const size_t blockSize = (size_t)1 << _h.BlockBits; + nodesMap.Alloc(blockSize); + + unsigned globalNodeIndex = 0; + // unsigned numEmpty = 0; + unsigned numEmpty_in_Maps = 0; + + FOR_VECTOR (gi, groups) + { + if (globalNodeIndex >= _h.NumInodes) + break; + + const CGroupDescriptor &gd = groups[gi]; + + PRF(printf("\n\ng%6d block = %6x\n", gi, (unsigned)gd.InodeTable)); + + RINOK(SeekAndRead(inStream, gd.InodeBitmap, nodesMap, blockSize)) + RINOK(SeekAndRead(inStream, gd.InodeTable, nodesData, nodesDataSize)) + + unsigned numEmpty_in_Map = 0; + + for (size_t n = 0; n < numNodes && globalNodeIndex < _h.NumInodes; n++, globalNodeIndex++) + { + if ((nodesMap[n >> 3] & ((unsigned)1 << (n & 7))) == 0) + { + numEmpty_in_Map++; + continue; + } + + const Byte *p = nodesData + (size_t)n * _h.InodeSize; + if (IsEmptyData(p, _h.InodeSize)) + { + if (globalNodeIndex + 1 >= _h.FirstInode) + { + _headersError = true; + // return S_FALSE; + } + continue; + } + + CNode node; + + PRF(printf("\nnode = %5d ", (unsigned)n)); + + if (!node.Parse(p, _h)) + return S_FALSE; + + // PRF(printf("\n %6d", (unsigned)n)); + /* + SetUi32(p + 0x7C, 0) + SetUi32(p + 0x82, 0) + + UInt32 crc = Crc32C_Calc(_h.Uuid, sizeof(_h.Uuid)); + Byte i_le[4]; + SetUi32(i_le, n); + crc = Crc32C_Update(crc, i_le, 4); + crc = Crc32C_Update(crc, p, _h.InodeSize); + if (crc != node.Checksum) return S_FALSE; + */ + + while (_refs.Size() < globalNodeIndex + 1) + { + // numEmpty++; + _refs.Add(-1); + } + + _refs.Add((int)_nodes.Add(node)); + } + + + numEmpty_in_Maps += numEmpty_in_Map; + + if (numEmpty_in_Map != gd.NumFreeInodes) + { + _headersWarning = true; + // return S_FALSE; + } + } + + if (numEmpty_in_Maps != _h.NumFreeInodes) + { + // some ext2 examples has incorrect value in _h.NumFreeInodes. + // so we disable check; + _headersWarning = true; + } + + if (_refs.Size() <= k_INODE_ROOT) + return S_FALSE; + + // printf("\n numReserveInodes = %6d, _refs.Size() = %d, numEmpty = %7d\n", numReserveInodes, _refs.Size(), (unsigned)numEmpty); + } + } + + _stream = inStream; // we need stream for dir nodes + + { + // ---------- Read Dirs ---------- + + CByteBuffer dataBuf; + + FOR_VECTOR (i, _refs) + { + const int nodeIndex = _refs[i]; + { + if (nodeIndex < 0) + continue; + const CNode &node = _nodes[nodeIndex]; + if (!node.IsDir()) + continue; + } + RINOK(ExtractNode((unsigned)nodeIndex, dataBuf)) + if (dataBuf.Size() == 0) + { + // _headersError = true; + return S_FALSE; + } + else + { + RINOK(ParseDir(dataBuf, dataBuf.Size(), i)) + } + RINOK(CheckProgress()) + } + + const int ref = _refs[k_INODE_ROOT]; + if (ref < 0 || _nodes[ref].ParentNode != k_INODE_ROOT) + return S_FALSE; + } + + { + // ---------- Check NumLinks and unreferenced dir nodes ---------- + + FOR_VECTOR (i, _refs) + { + int nodeIndex = _refs[i]; + if (nodeIndex < 0) + continue; + const CNode &node = _nodes[nodeIndex]; + + if (node.NumLinks != node.NumLinksCalced) + { + if (node.NumLinks != 1 || node.NumLinksCalced != 0 + // ) && i >= _h.FirstInode + ) + { + _linksError = true; + // return S_FALSE; + } + } + + if (!node.IsDir()) + continue; + + if (node.ParentNode < 0) + { + if (i >= _h.FirstInode) + return S_FALSE; + continue; + } + } + } + + { + // ---------- Check that there is no loops in parents list ---------- + + unsigned numNodes = _refs.Size(); + CIntArr UsedByNode(numNodes); + { + { + for (unsigned i = 0; i < numNodes; i++) + UsedByNode[i] = -1; + } + } + + FOR_VECTOR (i, _refs) + { + { + int nodeIndex = _refs[i]; + if (nodeIndex < 0) + continue; + const CNode &node = _nodes[nodeIndex]; + if (node.ParentNode < 0 // not dir + || i == k_INODE_ROOT) + continue; + } + + unsigned c = i; + + for (;;) + { + const int nodeIndex = _refs[c]; + if (nodeIndex < 0) + return S_FALSE; + CNode &node = _nodes[nodeIndex]; + + if (UsedByNode[c] != -1) + { + if ((unsigned)UsedByNode[c] == i) + return S_FALSE; + break; + } + + UsedByNode[c] = (int)i; + if (node.ParentNode < 0 || node.ParentNode == k_INODE_ROOT) + break; + if ((unsigned)node.ParentNode == i) + return S_FALSE; + c = (unsigned)node.ParentNode; + } + } + } + + { + // ---------- Fill SymLinks data ---------- + + AString s; + CByteBuffer data; + + unsigned i; + for (i = 0; i < _refs.Size(); i++) + { + const int nodeIndex = _refs[i]; + if (nodeIndex < 0) + continue; + CNode &node = _nodes[nodeIndex]; + if (!node.IsLink()) + continue; + if (node.FileSize > ((UInt32)1 << 14)) + continue; + if (ExtractNode((unsigned)nodeIndex, data) == S_OK && data.Size() != 0) + { + s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); + if (s.Len() == data.Size()) + node.SymLinkIndex = (int)_symLinks.Add(s); + RINOK(CheckProgress()) + } + } + + for (i = 0; i < _dirs.Size(); i++) + { + _dirs[i].Sort(CompareItemsNames, (void *)&_items); + } + + unsigned prev = 0; + unsigned complex = 0; + + for (i = 0; i < _items.Size(); i++) + { + CItem &item = _items[i]; + const int sym = _nodes[_refs[item.Node]].SymLinkIndex; + if (sym >= 0 && item.ParentNode >= 0) + { + item.SymLinkItemIndex = FindTargetItem_for_SymLink((unsigned)item.ParentNode, _symLinks[sym]); + if (_openCallback) + { + complex++; + if (complex - prev >= (1 << 10)) + { + prev = complex; + RINOK(CheckProgress2()) + } + } + } + } + } + + { + // ---------- Add items and aux folders for unreferenced files ---------- + + bool useSys = false; + bool useUnknown = false; + + FOR_VECTOR (i, _refs) + { + const int nodeIndex = _refs[i]; + if (nodeIndex < 0) + continue; + const CNode &node = _nodes[nodeIndex]; + + if (node.NumLinksCalced == 0 /* || i > 100 && i < 150 */) // for debug + { + CItem item; + item.Node = i; + + // we don't know how to work with k_INODE_RESIZE node (strange FileSize and Block values). + // so we ignore it; + + if (i == k_INODE_RESIZE) + continue; + + if (node.FileSize == 0) + continue; + + if (i < _h.FirstInode) + { + if (item.Node < Z7_ARRAY_SIZE(k_SysInode_Names)) + item.Name = k_SysInode_Names[item.Node]; + useSys = true; + } + else + useUnknown = true; + + if (item.Name.IsEmpty()) + item.Name.Add_UInt32(item.Node); + + _items.Add(item); + } + } + + if (useSys) + _auxSysIndex = (int)_auxItems.Add((AString)"[SYS]"); + if (useUnknown) + _auxUnknownIndex = (int)_auxItems.Add((AString)"[UNKNOWN]"); + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + HRESULT res; + try + { + _openCallback = callback; + res = Open2(stream); + } + catch(...) + { + ClearRefs(); + throw; + } + + if (res != S_OK) + { + ClearRefs(); + return res; + } + _stream = stream; + } + return S_OK; + COM_TRY_END +} + + +void CHandler::ClearRefs() +{ + _stream.Release(); + _items.Clear(); + _nodes.Clear(); + _refs.Clear(); + _auxItems.Clear(); + _symLinks.Clear(); + _dirs.Clear(); + _auxSysIndex = -1; + _auxUnknownIndex = -1; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalRead = 0; + _totalReadPrev = 0; + _phySize = 0; + _isArc = false; + _headersError = false; + _headersWarning = false; + _linksError = false; + _isUTF = true; + + ClearRefs(); + return S_OK; +} + + +static void ChangeSeparatorsInName(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + { + char c = s[i]; + if (c == CHAR_PATH_SEPARATOR || c == '/') + s[i] = '_'; + } +} + + +void CHandler::GetPath(unsigned index, AString &s) const +{ + s.Empty(); + + if (index >= _items.Size()) + { + s = _auxItems[index - _items.Size()]; + return; + } + + for (;;) + { + const CItem &item = _items[index]; + if (!s.IsEmpty()) + s.InsertAtFront(CHAR_PATH_SEPARATOR); + s.Insert(0, item.Name); + // 18.06 + ChangeSeparatorsInName(s.GetBuf(), item.Name.Len()); + + if (item.ParentNode == k_INODE_ROOT) + return; + + if (item.ParentNode < 0) + { + int aux = GetParentAux(item); + if (aux < 0) + break; + s.InsertAtFront(CHAR_PATH_SEPARATOR); + s.Insert(0, _auxItems[aux]); + return; + } + + const CNode &node = _nodes[_refs[item.ParentNode]]; + if (node.ItemIndex < 0) + return; + index = (unsigned)node.ItemIndex; + + if (s.Len() > ((UInt32)1 << 16)) + { + s.Insert(0, "[LONG]" STRING_PATH_SEPARATOR); + return; + } + } +} + + +bool CHandler::GetPackSize(unsigned index, UInt64 &totalPack) const +{ + if (index >= _items.Size()) + { + totalPack = 0; + return false; + } + + const CItem &item = _items[index]; + const CNode &node = _nodes[_refs[item.Node]]; + + // if (!node.IsFlags_EXTENTS()) + { + totalPack = (UInt64)node.NumBlocks << (node.IsFlags_HUGE() ? _h.BlockBits : 9); + return true; + } + + /* + CExtentTreeHeader eth; + if (!eth.Parse(node.Block)) + return false; + if (eth.NumEntries > 3) + return false; + if (!eth.Depth == 0) + return false; + + UInt64 numBlocks = 0; + { + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtent e; + e.Parse(node.Block + 12 + i * 12); + // const CExtent &e = node.leafs[i]; + if (e.IsInited) + numBlocks += e.Len; + } + } + + totalPack = numBlocks << _h.BlockBits; + return true; + */ +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size() + _auxItems.Size(); + return S_OK; +} + +enum +{ + kpidMountTime = kpidUserDefined, + kpidLastCheckTime, + kpidRevision, + kpidINodeSize, + kpidLastMount, + kpidFeatureIncompat, + kpidFeatureRoCompat, + kpidWrittenKB + + // kpidGroupSize, + + // kpidChangeTime = kpidUserDefined + 256, + // kpidDTime +}; + +static const UInt32 kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidPosixAttrib, + kpidMTime, + kpidCTime, + kpidATime, + // kpidChangeTime, + // kpidDTime, + kpidINode, + kpidLinks, + kpidSymLink, + kpidCharacts, + kpidUserId, + kpidGroupId +}; + + +static const CStatProp kArcProps[] = +{ + { NULL, kpidHeadersSize, VT_BSTR }, + // { NULL, kpidFileSystem, VT_BSTR }, + // kpidMethod, + { NULL, kpidClusterSize, VT_UI4 }, + // { "Group Size", kpidGroupSize, VT_UI8 }, + { NULL, kpidFreeSpace, VT_UI8 }, + + { NULL, kpidMTime, VT_FILETIME }, + { NULL, kpidCTime, VT_FILETIME }, + { "Mount Time", kpidMountTime, VT_FILETIME }, + { "Last Check Time", kpidLastCheckTime, VT_FILETIME }, + + { NULL, kpidHostOS, VT_BSTR}, + { "Revision", kpidRevision, VT_UI4}, + { "inode Size", kpidINodeSize, VT_UI4}, + { NULL, kpidCodePage, VT_BSTR}, + { NULL, kpidVolumeName, VT_BSTR}, + { "Last Mounted", kpidLastMount, VT_BSTR}, + { NULL, kpidId, VT_BSTR}, + { NULL, kpidCharacts, VT_BSTR }, + { "Incompatible Features", kpidFeatureIncompat, VT_BSTR }, + { "Readonly-compatible Features", kpidFeatureRoCompat, VT_BSTR }, + { "Written KiB", kpidWrittenKB, VT_UI8 } +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void StringToProp(bool isUTF, const char *s, unsigned size, NCOM::CPropVariant &prop) +{ + UString u; + AString a; + a.SetFrom_CalcLen(s, size); + if (!isUTF || !ConvertUTF8ToUnicode(a, u)) + MultiByteToUnicodeString2(u, a); + prop = u; +} + +static void UnixTimeToProp(UInt32 val, NCOM::CPropVariant &prop) +{ + if (val != 0) + PropVariant_SetFrom_UnixTime(prop, val); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + + NCOM::CPropVariant prop; + + switch (propID) + { + /* + case kpidFileSystem: + { + AString res = "Ext4"; + prop = res; + break; + } + */ + + case kpidIsTree: prop = true; break; + case kpidIsAux: prop = true; break; + case kpidINode: prop = true; break; + + case kpidClusterSize: prop = (UInt32)1 << _h.BlockBits; break; + // case kpidGroupSize: prop = (UInt64)_h.BlocksPerGroup << _h.BlockBits; break; + + case kpidFreeSpace: prop = (UInt64)_h.NumFreeBlocks << _h.BlockBits; break; + + case kpidCTime: UnixTimeToProp(_h.CTime, prop); break; + case kpidMTime: UnixTimeToProp(_h.WriteTime, prop); break; + case kpidMountTime: UnixTimeToProp(_h.MountTime, prop); break; + case kpidLastCheckTime: UnixTimeToProp(_h.LastCheckTime, prop); break; + + case kpidHostOS: + { + TYPE_TO_PROP(kHostOS, _h.CreatorOs, prop); + break; + } + + case kpidRevision: prop = _h.RevLevel; break; + + case kpidINodeSize: prop = (UInt32)_h.InodeSize; break; + + case kpidId: + { + if (!IsEmptyData(_h.Uuid, sizeof(_h.Uuid))) + { + char s[sizeof(_h.Uuid) * 2 + 2]; + ConvertDataToHex_Lower(s, _h.Uuid, sizeof(_h.Uuid)); + prop = s; + } + break; + } + + case kpidCodePage: if (_isUTF) prop = "UTF-8"; break; + + case kpidShortComment: + case kpidVolumeName: + StringToProp(_isUTF, _h.VolName, sizeof(_h.VolName), prop); break; + + case kpidLastMount: StringToProp(_isUTF, _h.LastMount, sizeof(_h.LastMount), prop); break; + + case kpidCharacts: FLAGS_TO_PROP(g_FeatureCompat_Flags, _h.FeatureCompat, prop); break; + case kpidFeatureIncompat: FLAGS_TO_PROP(g_FeatureIncompat_Flags, _h.FeatureIncompat, prop); break; + case kpidFeatureRoCompat: FLAGS_TO_PROP(g_FeatureRoCompat_Flags, _h.FeatureRoCompat, prop); break; + case kpidWrittenKB: if (_h.WrittenKB != 0) prop = _h.WrittenKB; break; + + case kpidPhySize: prop = _phySize; break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_linksError) v |= kpv_ErrorFlags_HeadersError; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (!_stream && v == 0 && _isArc) + v = kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + + case kpidWarningFlags: + { + UInt32 v = 0; + if (_headersWarning) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + + COM_TRY_END +} + + +/* +static const Byte kRawProps[] = +{ + // kpidSha1, +}; +*/ + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + // *numProps = Z7_ARRAY_SIZE(kRawProps); + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + // *propID = kRawProps[index]; + *propID = 0; + *name = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + + if (index >= _items.Size()) + return S_OK; + + const CItem &item = _items[index]; + + if (item.ParentNode < 0) + { + const int aux = GetParentAux(item); + if (aux >= 0) + *parent = _items.Size() + (unsigned)aux; + } + else + { + const int itemIndex = _nodes[_refs[item.ParentNode]].ItemIndex; + if (itemIndex >= 0) + *parent = (unsigned)itemIndex; + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidName && _isUTF) + { + if (index < _items.Size()) + { + const AString &s = _items[index].Name; + if (!s.IsEmpty()) + { + *data = (void *)(const char *)s; + *dataSize = (UInt32)s.Len() + 1; + *propType = NPropDataType::kUtf8z; + } + return S_OK; + } + else + { + const AString &s = _auxItems[index - _items.Size()]; + { + *data = (void *)(const char *)s; + *dataSize = (UInt32)s.Len() + 1; + *propType = NPropDataType::kUtf8z; + } + return S_OK; + } + } + + return S_OK; +} + + +static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop) +{ + if (t.Val == 0 && t.Extra == 0) + 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::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); + } + /* + else + { + // 1901-2038 : that code is good for ext4 and compatibility with Extra + NTime::UnixTime64ToFileTime((Int32)t.Val, ft); // for + + // 1970-2106 : that code is good if timestamp is used as unsigned 32-bit + // are there such systems? + // NTime::UnixTimeToFileTime(t.Val, ft); // for + } + */ + prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, low100ns); +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (index >= _items.Size()) + { + switch (propID) + { + case kpidPath: + case kpidName: + { + prop = _auxItems[index - _items.Size()]; + break; + } + case kpidIsDir: prop = true; break; + case kpidIsAux: prop = true; break; + } + } + else + { + + const CItem &item = _items[index]; + const CNode &node = _nodes[_refs[item.Node]]; + bool isDir = node.IsDir(); + + switch (propID) + { + case kpidPath: + { + UString u; + { + AString s; + GetPath(index, s); + if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) + MultiByteToUnicodeString2(u, s); + } + prop = u; + break; + } + + case kpidName: + { + { + UString u; + { + if (!_isUTF || !ConvertUTF8ToUnicode(item.Name, u)) + MultiByteToUnicodeString2(u, item.Name); + } + prop = u; + } + break; + } + + case kpidIsDir: + { + bool isDir2 = isDir; + if (item.SymLinkItemIndex >= 0) + isDir2 = _nodes[_refs[_items[item.SymLinkItemIndex].Node]].IsDir(); + prop = isDir2; + break; + } + + case kpidSize: if (!isDir) prop = node.FileSize; break; + + case kpidPackSize: + if (!isDir) + { + UInt64 size; + if (GetPackSize(index, size)) + prop = size; + } + break; + + case kpidPosixAttrib: + { + /* + if (node.Type != 0 && node.Type < Z7_ARRAY_SIZE(k_TypeToMode)) + prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; + */ + prop = (UInt32)(node.Mode); + break; + } + + case kpidMTime: ExtTimeToProp(node.MTime, prop); break; + 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.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; + case kpidCharacts: FLAGS_TO_PROP(g_NodeFlags, (UInt32)node.Flags, prop); break; + + case kpidSymLink: + { + if (node.SymLinkIndex >= 0) + { + UString u; + { + const AString &s = _symLinks[node.SymLinkIndex]; + if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) + MultiByteToUnicodeString2(u, s); + } + prop = u; + } + break; + } + } + + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_CLASS_IMP_IInStream(CClusterInStream2 +) + UInt64 _virtPos; + UInt64 _physPos; + UInt32 _curRem; +public: + unsigned BlockBits; + UInt64 Size; + CMyComPtr Stream; + CRecordVector Vector; + + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } + + HRESULT InitAndSeek() + { + _curRem = 0; + _virtPos = 0; + _physPos = 0; + if (Vector.Size() > 0) + { + _physPos = (Vector[0] << BlockBits); + return SeekToPhys(); + } + return S_OK; + } +}; + + +Z7_COM7F_IMF(CClusterInStream2::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= Size) + return S_OK; + { + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + if (_curRem == 0) + { + const UInt32 blockSize = (UInt32)1 << BlockBits; + const UInt32 virtBlock = (UInt32)(_virtPos >> BlockBits); + const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + const UInt32 phyBlock = Vector[virtBlock]; + + if (phyBlock == 0) + { + UInt32 cur = blockSize - offsetInBlock; + if (cur > size) + cur = size; + memset(data, 0, cur); + _virtPos += cur; + if (processedSize) + *processedSize = cur; + return S_OK; + } + + UInt64 newPos = ((UInt64)phyBlock << BlockBits) + offsetInBlock; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + + _curRem = blockSize - offsetInBlock; + + for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) + _curRem += (UInt32)1 << BlockBits; + } + + if (size > _curRem) + size = _curRem; + HRESULT res = Stream->Read(data, size, &size); + if (processedSize) + *processedSize = size; + _physPos += size; + _virtPos += size; + _curRem -= size; + return res; +} + +Z7_COM7F_IMF(CClusterInStream2::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (_virtPos != (UInt64)offset) + _curRem = 0; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +Z7_CLASS_IMP_IInStream( + CExtInStream +) + UInt64 _virtPos; + UInt64 _phyPos; +public: + unsigned BlockBits; + UInt64 Size; + CMyComPtr Stream; + CRecordVector Extents; + + HRESULT StartSeek() + { + _virtPos = 0; + _phyPos = 0; + return InStream_SeekSet(Stream, _phyPos); + } +}; + +Z7_COM7F_IMF(CExtInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= Size) + return S_OK; + { + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + UInt32 blockIndex = (UInt32)(_virtPos >> BlockBits); + + unsigned left = 0, right = Extents.Size(); + for (;;) + { + unsigned mid = (left + right) / 2; + if (mid == left) + break; + if (blockIndex < Extents[mid].VirtBlock) + right = mid; + else + left = mid; + } + + { + const CExtent &extent = Extents[left]; + if (blockIndex < extent.VirtBlock) + return E_FAIL; + UInt32 bo = blockIndex - extent.VirtBlock; + if (bo >= extent.Len) + return E_FAIL; + + UInt32 offset = ((UInt32)_virtPos & (((UInt32)1 << BlockBits) - 1)); + UInt32 remBlocks = extent.Len - bo; + UInt64 remBytes = ((UInt64)remBlocks << BlockBits); + remBytes -= offset; + + if (size > remBytes) + size = (UInt32)remBytes; + + if (!extent.IsInited) + { + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + const UInt64 phyBlock = extent.PhyStart + bo; + const UInt64 phy = (phyBlock << BlockBits) + offset; + + if (phy != _phyPos) + { + RINOK(InStream_SeekSet(Stream, phy)) + _phyPos = phy; + } + + UInt32 realProcessSize = 0; + + const HRESULT res = Stream->Read(data, size, &realProcessSize); + + _phyPos += realProcessSize; + _virtPos += realProcessSize; + if (processedSize) + *processedSize = realProcessSize; + return res; + } +} + + +Z7_COM7F_IMF(CExtInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + + +HRESULT CHandler::FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector &blocks) +{ + const size_t blockSize = (size_t)1 << _h.BlockBits; + CByteBuffer &tempBuf = _tempBufs[level]; + tempBuf.Alloc(blockSize); + + PRF2(printf("\n level = %d, block = %7d", level, (unsigned)block)); + + RINOK(SeekAndRead(_stream, block, tempBuf, blockSize)) + + const Byte *p = tempBuf; + size_t num = (size_t)1 << (_h.BlockBits - 2); + + for (size_t i = 0; i < num; i++) + { + if (blocks.Size() == numBlocks) + break; + UInt32 val = GetUi32(p + 4 * i); + if (val >= _h.NumBlocks) + return S_FALSE; + + if (level != 0) + { + if (val == 0) + { + /* + size_t num = (size_t)1 << ((_h.BlockBits - 2) * (level)); + PRF2(printf("\n num empty = %3d", (unsigned)num)); + for (size_t k = 0; k < num; k++) + { + blocks.Add(0); + if (blocks.Size() == numBlocks) + return S_OK; + } + continue; + */ + return S_FALSE; + } + + RINOK(FillFileBlocks2(val, level - 1, numBlocks, blocks)) + continue; + } + + PRF2(printf("\n i = %3d, blocks.Size() = %6d, block = %5d ", i, blocks.Size(), (unsigned)val)); + + PRF(printf("\n i = %3d, start = %5d ", (unsigned)i, (unsigned)val)); + + blocks.Add(val); + } + + return S_OK; +} + + +static const unsigned kNumDirectNodeBlocks = 12; + +HRESULT CHandler::FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector &blocks) +{ + // ext2 supports zero blocks (blockIndex == 0). + + blocks.ClearAndReserve(numBlocks); + + for (unsigned i = 0; i < kNumDirectNodeBlocks; i++) + { + if (i == numBlocks) + return S_OK; + UInt32 val = GetUi32(p + 4 * i); + if (val >= _h.NumBlocks) + return S_FALSE; + blocks.Add(val); + } + + for (unsigned level = 0; level < 3; level++) + { + if (blocks.Size() == numBlocks) + break; + UInt32 val = GetUi32(p + 4 * (kNumDirectNodeBlocks + level)); + if (val >= _h.NumBlocks) + return S_FALSE; + + if (val == 0) + { + /* + size_t num = (size_t)1 << ((_h.BlockBits - 2) * (level + 1)); + for (size_t k = 0; k < num; k++) + { + blocks.Add(0); + if (blocks.Size() == numBlocks) + return S_OK; + } + continue; + */ + return S_FALSE; + } + + RINOK(FillFileBlocks2(val, level, numBlocks, blocks)) + } + + return S_OK; +} + + +static void AddSkipExtents(CRecordVector &extents, UInt32 virtBlock, UInt32 numBlocks) +{ + while (numBlocks != 0) + { + UInt32 len = numBlocks; + const UInt32 kLenMax = (UInt32)1 << 15; + if (len > kLenMax) + len = kLenMax; + CExtent e; + e.VirtBlock = virtBlock; + e.Len = (UInt16)len; + e.IsInited = false; + e.PhyStart = 0; + extents.Add(e); + virtBlock += len; + numBlocks -= len; + } +} + +static bool UpdateExtents(CRecordVector &extents, UInt32 block) +{ + if (extents.IsEmpty()) + { + if (block == 0) + return true; + AddSkipExtents(extents, 0, block); + return true; + } + + const CExtent &prev = extents.Back(); + if (block < prev.VirtBlock) + return false; + UInt32 prevEnd = prev.GetVirtEnd(); + if (block == prevEnd) + return true; + AddSkipExtents(extents, prevEnd, block - prevEnd); + return true; +} + + +HRESULT CHandler::FillExtents(const Byte *p, size_t size, CRecordVector &extents, int parentDepth) +{ + CExtentTreeHeader eth; + if (!eth.Parse(p)) + return S_FALSE; + + if (parentDepth >= 0 && eth.Depth != parentDepth - 1) // (eth.Depth >= parentDepth) + return S_FALSE; + + if (12 + 12 * (size_t)eth.NumEntries > size) + return S_FALSE; + + if (eth.Depth >= kNumTreeLevelsMax) + return S_FALSE; + + if (eth.Depth == 0) + { + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtent e; + e.Parse(p + 12 + i * 12); + if (e.PhyStart == 0 + || e.PhyStart > _h.NumBlocks + || e.PhyStart + e.Len > _h.NumBlocks + || !e.IsLenOK()) + return S_FALSE; + if (!UpdateExtents(extents, e.VirtBlock)) + return S_FALSE; + extents.Add(e); + } + + return S_OK; + } + + const size_t blockSize = (size_t)1 << _h.BlockBits; + CByteBuffer &tempBuf = _tempBufs[eth.Depth]; + tempBuf.Alloc(blockSize); + + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtentIndexNode e; + e.Parse(p + 12 + i * 12); + + if (e.PhyLeaf == 0 || e.PhyLeaf >= _h.NumBlocks) + return S_FALSE; + + if (!UpdateExtents(extents, e.VirtBlock)) + return S_FALSE; + + RINOK(SeekAndRead(_stream, e.PhyLeaf, tempBuf, blockSize)) + RINOK(FillExtents(tempBuf, blockSize, extents, eth.Depth)) + } + + return S_OK; +} + + +HRESULT CHandler::GetStream_Node(unsigned nodeIndex, ISequentialInStream **stream) +{ + COM_TRY_BEGIN + + *stream = NULL; + + const CNode &node = _nodes[nodeIndex]; + + if (!node.IsFlags_EXTENTS()) + { + // maybe sparse file can have (node.NumBlocks == 0) ? + + /* The following code doesn't work correctly for some CentOS images, + where there are nodes with inline data and (node.NumBlocks != 0). + If you know better way to detect inline data, please notify 7-Zip developers. */ + + if (node.NumBlocks == 0 && node.FileSize < kNodeBlockFieldSize) + { + Create_BufInStream_WithNewBuffer(node.Block, (size_t)node.FileSize, stream); + return S_OK; + } + } + + if (node.FileSize >= ((UInt64)1 << 63)) + return S_FALSE; + + CMyComPtr streamTemp; + + const UInt64 numBlocks64 = (node.FileSize + (UInt64)(((UInt32)1 << _h.BlockBits) - 1)) >> _h.BlockBits; + + if (node.IsFlags_EXTENTS()) + { + if ((UInt32)numBlocks64 != numBlocks64) + return S_FALSE; + + CExtInStream *streamSpec = new CExtInStream; + streamTemp = streamSpec; + + streamSpec->BlockBits = _h.BlockBits; + streamSpec->Size = node.FileSize; + streamSpec->Stream = _stream; + + RINOK(FillExtents(node.Block, kNodeBlockFieldSize, streamSpec->Extents, -1)) + + UInt32 end = 0; + if (!streamSpec->Extents.IsEmpty()) + end = streamSpec->Extents.Back().GetVirtEnd(); + if (end < numBlocks64) + { + AddSkipExtents(streamSpec->Extents, end, (UInt32)(numBlocks64 - end)); + // return S_FALSE; + } + + RINOK(streamSpec->StartSeek()) + } + else + { + { + UInt64 numBlocks2 = numBlocks64; + + if (numBlocks64 > kNumDirectNodeBlocks) + { + UInt64 rem = numBlocks64 - kNumDirectNodeBlocks; + const unsigned refBits = (_h.BlockBits - 2); + const size_t numRefsInBlocks = (size_t)1 << refBits; + numBlocks2++; + if (rem > numRefsInBlocks) + { + numBlocks2++; + const UInt64 numL2 = (rem - 1) >> refBits; + numBlocks2 += numL2; + if (numL2 > numRefsInBlocks) + { + numBlocks2++; + numBlocks2 += (numL2 - 1) >> refBits; + } + } + } + + const unsigned specBits = (node.IsFlags_HUGE() ? 0 : _h.BlockBits - 9); + const UInt32 specMask = ((UInt32)1 << specBits) - 1; + if ((node.NumBlocks & specMask) != 0) + return S_FALSE; + const UInt64 numBlocks64_from_header = node.NumBlocks >> specBits; + if (numBlocks64_from_header < numBlocks2) + { + // why (numBlocks64_from_header > numBlocks2) in some cases? + // return S_FALSE; + } + } + + unsigned numBlocks = (unsigned)numBlocks64; + if (numBlocks != numBlocks64) + return S_FALSE; + + CClusterInStream2 *streamSpec = new CClusterInStream2; + streamTemp = streamSpec; + + streamSpec->BlockBits = _h.BlockBits; + streamSpec->Size = node.FileSize; + streamSpec->Stream = _stream; + + RINOK(FillFileBlocks(node.Block, numBlocks, streamSpec->Vector)) + streamSpec->InitAndSeek(); + } + + *stream = streamTemp.Detach(); + + return S_OK; + + COM_TRY_END +} + + +HRESULT CHandler::ExtractNode(unsigned nodeIndex, CByteBuffer &data) +{ + data.Free(); + const CNode &node = _nodes[nodeIndex]; + size_t size = (size_t)node.FileSize; + if (size != node.FileSize) + return S_FALSE; + CMyComPtr inSeqStream; + RINOK(GetStream_Node(nodeIndex, &inSeqStream)) + if (!inSeqStream) + return S_FALSE; + data.Alloc(size); + _totalRead += size; + return ReadStream_FALSE(inSeqStream, data, size); +} + + +Z7_COM7F_IMF(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() + _auxItems.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]; + if (index >= _items.Size()) + continue; + const CItem &item = _items[index]; + const CNode &node = _nodes[_refs[item.Node]]; + if (!node.IsDir()) + totalSize += node.FileSize; + } + + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + + for (i = 0;; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + int opRes; + { + 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)) + + if (index >= _items.Size()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const CItem &item = _items[index]; + const CNode &node = _nodes[_refs[item.Node]]; + + if (node.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + UInt64 unpackSize = node.FileSize; + totalSize += unpackSize; + UInt64 packSize; + if (GetPackSize(index, packSize)) + totalPackSize += packSize; + + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + opRes = NExtract::NOperationResult::kDataError; + { + CMyComPtr inSeqStream; + HRESULT hres = GetStream(index, &inSeqStream); + if (hres == S_FALSE || !inSeqStream) + { + if (hres == E_OUTOFMEMORY) + return hres; + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else + { + RINOK(hres) + { + hres = copyCoder.Interface()->Code(inSeqStream, outStream, NULL, NULL, lps); + if (hres == S_OK) + { + if (copyCoder->TotalSize == unpackSize) + opRes = NExtract::NOperationResult::kOK; + } + else if (hres == E_NOTIMPL) + { + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else if (hres != S_FALSE) + { + RINOK(hres) + } + } + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + *stream = NULL; + if (index >= _items.Size()) + return S_FALSE; + return GetStream_Node((unsigned)_refs[_items[index].Node], stream); +} + + +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( + "Ext", "ext ext2 ext3 ext4 img", NULL, 0xC7, + k_Signature, + 0x438, + 0, + IsArc_Ext) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/FatHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FatHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/FatHandler.cpp 2016-02-01 16:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FatHandler.cpp 2025-02-09 09:00:00.000000000 +0000 @@ -1,1056 +1,1324 @@ -// FatHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#include "Common/DummyOutStream.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -#define PRF(x) /* x */ - -namespace NArchive { -namespace NFat { - -static const UInt32 kFatItemUsedByDirMask = (UInt32)1 << 31; - -struct CHeader -{ - UInt32 NumSectors; - UInt16 NumReservedSectors; - Byte NumFats; - UInt32 NumFatSectors; - UInt32 RootDirSector; - UInt32 NumRootDirSectors; - UInt32 DataSector; - - UInt32 FatSize; - UInt32 BadCluster; - - Byte NumFatBits; - Byte SectorSizeLog; - Byte SectorsPerClusterLog; - Byte ClusterSizeLog; - - UInt16 SectorsPerTrack; - UInt16 NumHeads; - UInt32 NumHiddenSectors; - - bool VolFieldsDefined; - - UInt32 VolId; - // Byte VolName[11]; - // Byte FileSys[8]; - - // Byte OemName[5]; - Byte MediaType; - - // 32-bit FAT - UInt16 Flags; - UInt16 FsInfoSector; - UInt32 RootCluster; - - bool IsFat32() const { return NumFatBits == 32; } - UInt64 GetPhySize() const { return (UInt64)NumSectors << SectorSizeLog; } - UInt32 SectorSize() const { return (UInt32)1 << SectorSizeLog; } - UInt32 ClusterSize() const { return (UInt32)1 << ClusterSizeLog; } - UInt32 ClusterToSector(UInt32 c) const { return DataSector + ((c - 2) << SectorsPerClusterLog); } - UInt32 IsEoc(UInt32 c) const { return c > BadCluster; } - UInt32 IsEocAndUnused(UInt32 c) const { return c > BadCluster && (c & kFatItemUsedByDirMask) == 0; } - UInt32 IsValidCluster(UInt32 c) const { return c >= 2 && c < FatSize; } - UInt32 SizeToSectors(UInt32 size) const { return (size + SectorSize() - 1) >> SectorSizeLog; } - UInt32 CalcFatSizeInSectors() const { return SizeToSectors((FatSize * (NumFatBits / 4) + 1) / 2); } - - UInt32 GetFatSector() const - { - UInt32 index = (IsFat32() && (Flags & 0x80) != 0) ? (Flags & 0xF) : 0; - if (index > NumFats) - index = 0; - return NumReservedSectors + index * NumFatSectors; - } - - UInt64 GetFilePackSize(UInt32 unpackSize) const - { - UInt64 mask = ClusterSize() - 1; - return (unpackSize + mask) & ~mask; - } - - UInt32 GetNumClusters(UInt32 size) const - { return (UInt32)(((UInt64)size + ClusterSize() - 1) >> ClusterSizeLog); } - - bool Parse(const Byte *p); -}; - -static int GetLog(UInt32 num) -{ - for (int i = 0; i < 31; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - -static const UInt32 kHeaderSize = 512; - -API_FUNC_static_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) -{ - if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) - return false; - - int codeOffset = 0; - switch (p[0]) - { - case 0xE9: codeOffset = 3 + (Int16)Get16(p + 1); break; - case 0xEB: if (p[2] != 0x90) return false; codeOffset = 2 + (signed char)p[1]; break; - default: return false; - } - { - { - UInt32 val32 = Get16(p + 11); - int s = GetLog(val32); - if (s < 9 || s > 12) - return false; - SectorSizeLog = (Byte)s; - } - { - UInt32 val32 = p[13]; - int s = GetLog(val32); - if (s < 0) - return false; - SectorsPerClusterLog = (Byte)s; - } - ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog); - if (ClusterSizeLog > 24) - return false; - } - - NumReservedSectors = Get16(p + 14); - if (NumReservedSectors == 0) - return false; - - NumFats = p[16]; - if (NumFats < 1 || NumFats > 4) - return false; - - // we also support images that contain 0 in offset field. - bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0)); - - UInt16 numRootDirEntries = Get16(p + 17); - if (numRootDirEntries == 0) - { - if (codeOffset < 90 && !isOkOffset) - return false; - NumFatBits = 32; - NumRootDirSectors = 0; - } - else - { - // Some FAT12s don't contain VolFields - if (codeOffset < 62 - 24 && !isOkOffset) - return false; - NumFatBits = 0; - UInt32 mask = (1 << (SectorSizeLog - 5)) - 1; - if ((numRootDirEntries & mask) != 0) - return false; - NumRootDirSectors = (numRootDirEntries + mask) >> (SectorSizeLog - 5); - } - - NumSectors = Get16(p + 19); - if (NumSectors == 0) - NumSectors = Get32(p + 32); - else if (IsFat32()) - return false; - - MediaType = p[21]; - NumFatSectors = Get16(p + 22); - SectorsPerTrack = Get16(p + 24); - NumHeads = Get16(p + 26); - NumHiddenSectors = Get32(p + 28); - - // memcpy(OemName, p + 3, 5); - - int curOffset = 36; - p += 36; - if (IsFat32()) - { - if (NumFatSectors != 0) - return false; - NumFatSectors = Get32(p); - if (NumFatSectors >= (1 << 24)) - return false; - - Flags = Get16(p + 4); - if (Get16(p + 6) != 0) - return false; - RootCluster = Get32(p + 8); - FsInfoSector = Get16(p + 12); - for (int i = 16; i < 28; i++) - if (p[i] != 0) - return false; - p += 28; - curOffset += 28; - } - - // DriveNumber = p[0]; - VolFieldsDefined = false; - if (codeOffset >= curOffset + 3) - { - VolFieldsDefined = (p[2] == 0x29); // ExtendedBootSig - if (VolFieldsDefined) - { - if (codeOffset < curOffset + 26) - return false; - VolId = Get32(p + 3); - // memcpy(VolName, p + 7, 11); - // memcpy(FileSys, p + 18, 8); - } - } - - if (NumFatSectors == 0) - return false; - RootDirSector = NumReservedSectors + NumFatSectors * NumFats; - DataSector = RootDirSector + NumRootDirSectors; - if (NumSectors < DataSector) - return false; - UInt32 numDataSectors = NumSectors - DataSector; - UInt32 numClusters = numDataSectors >> SectorsPerClusterLog; - - BadCluster = 0x0FFFFFF7; - if (numClusters < 0xFFF5) - { - if (NumFatBits == 32) - return false; - NumFatBits = (Byte)(numClusters < 0xFF5 ? 12 : 16); - BadCluster &= ((1 << NumFatBits) - 1); - } - else if (NumFatBits != 32) - return false; - - FatSize = numClusters + 2; - if (FatSize > BadCluster || CalcFatSizeInSectors() > NumFatSectors) - return false; - return true; -} - -struct CItem -{ - UString UName; - char DosName[11]; - Byte CTime2; - UInt32 CTime; - UInt32 MTime; - UInt16 ADate; - Byte Attrib; - Byte Flags; - UInt32 Size; - UInt32 Cluster; - Int32 Parent; - - // NT uses Flags to store Low Case status - bool NameIsLow() const { return (Flags & 0x8) != 0; } - bool ExtIsLow() const { return (Flags & 0x10) != 0; } - bool IsDir() const { return (Attrib & 0x10) != 0; } - UString GetShortName() const; - UString GetName() const; - UString GetVolName() const; -}; - -static unsigned CopyAndTrim(char *dest, const char *src, unsigned size, bool toLower) -{ - memcpy(dest, src, size); - if (toLower) - { - for (unsigned i = 0; i < size; i++) - { - char c = dest[i]; - if (c >= 'A' && c <= 'Z') - dest[i] = (char)(c + 0x20); - } - } - - for (unsigned i = size;;) - { - if (i == 0) - return 0; - if (dest[i - 1] != ' ') - return i; - i--; - } -} - -static UString FatStringToUnicode(const char *s) -{ - return MultiByteToUnicodeString(s, CP_OEMCP); -} - -UString CItem::GetShortName() const -{ - char s[16]; - unsigned i = CopyAndTrim(s, DosName, 8, NameIsLow()); - s[i++] = '.'; - unsigned j = CopyAndTrim(s + i, DosName + 8, 3, ExtIsLow()); - if (j == 0) - i--; - s[i + j] = 0; - return FatStringToUnicode(s); -} - -UString CItem::GetName() const -{ - if (!UName.IsEmpty()) - return UName; - return GetShortName(); -} - -UString CItem::GetVolName() const -{ - if (!UName.IsEmpty()) - return UName; - char s[12]; - unsigned i = CopyAndTrim(s, DosName, 11, false); - s[i] = 0; - return FatStringToUnicode(s); -} - -struct CDatabase -{ - CHeader Header; - CObjectVector Items; - UInt32 *Fat; - CMyComPtr InStream; - IArchiveOpenCallback *OpenCallback; - - UInt32 NumFreeClusters; - bool VolItemDefined; - CItem VolItem; - UInt32 NumDirClusters; - CByteBuffer ByteBuf; - UInt64 NumCurUsedBytes; - - UInt64 PhySize; - - CDatabase(): Fat(0) {} - ~CDatabase() { ClearAndClose(); } - - void Clear(); - void ClearAndClose(); - HRESULT OpenProgressFat(bool changeTotal = true); - HRESULT OpenProgress(); - - UString GetItemPath(Int32 index) const; - HRESULT Open(); - HRESULT ReadDir(Int32 parent, UInt32 cluster, unsigned level); - - UInt64 GetHeadersSize() const - { - return (UInt64)(Header.DataSector + (NumDirClusters << Header.SectorsPerClusterLog)) << Header.SectorSizeLog; - } - HRESULT SeekToSector(UInt32 sector); - HRESULT SeekToCluster(UInt32 cluster) { return SeekToSector(Header.ClusterToSector(cluster)); } -}; - -HRESULT CDatabase::SeekToSector(UInt32 sector) -{ - return InStream->Seek((UInt64)sector << Header.SectorSizeLog, STREAM_SEEK_SET, NULL); -} - -void CDatabase::Clear() -{ - PhySize = 0; - VolItemDefined = false; - NumDirClusters = 0; - NumCurUsedBytes = 0; - - Items.Clear(); - delete []Fat; - Fat = 0; -} - -void CDatabase::ClearAndClose() -{ - Clear(); - InStream.Release(); -} - -HRESULT CDatabase::OpenProgressFat(bool changeTotal) -{ - if (!OpenCallback) - return S_OK; - if (changeTotal) - { - UInt64 numTotalBytes = (Header.CalcFatSizeInSectors() << Header.SectorSizeLog) + - ((UInt64)(Header.FatSize - NumFreeClusters) << Header.ClusterSizeLog); - RINOK(OpenCallback->SetTotal(NULL, &numTotalBytes)); - } - return OpenCallback->SetCompleted(NULL, &NumCurUsedBytes); -} - -HRESULT CDatabase::OpenProgress() -{ - if (!OpenCallback) - return S_OK; - UInt64 numItems = Items.Size(); - return OpenCallback->SetCompleted(&numItems, &NumCurUsedBytes); -} - -UString CDatabase::GetItemPath(Int32 index) const -{ - const CItem *item = &Items[index]; - UString name = item->GetName(); - for (;;) - { - index = item->Parent; - if (index < 0) - return name; - item = &Items[index]; - name.InsertAtFront(WCHAR_PATH_SEPARATOR); - if (item->UName.IsEmpty()) - name.Insert(0, item->GetShortName()); - else - name.Insert(0, item->UName); - } -} - -static wchar_t *AddSubStringToName(wchar_t *dest, const Byte *p, unsigned numChars) -{ - for (unsigned i = 0; i < numChars; i++) - { - wchar_t c = Get16(p + i * 2); - if (c != 0 && c != 0xFFFF) - *dest++ = c; - } - *dest = 0; - return dest; -} - -HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, unsigned level) -{ - unsigned startIndex = Items.Size(); - if (startIndex >= (1 << 30) || level > 256) - return S_FALSE; - - UInt32 sectorIndex = 0; - UInt32 blockSize = Header.ClusterSize(); - bool clusterMode = (Header.IsFat32() || parent >= 0); - if (!clusterMode) - { - blockSize = Header.SectorSize(); - RINOK(SeekToSector(Header.RootDirSector)); - } - - ByteBuf.Alloc(blockSize); - UString curName; - int checkSum = -1; - int numLongRecords = -1; - - for (UInt32 pos = blockSize;; pos += 32) - { - if (pos == blockSize) - { - pos = 0; - - if ((NumDirClusters & 0xFF) == 0) - { - RINOK(OpenProgress()); - } - - if (clusterMode) - { - if (Header.IsEoc(cluster)) - break; - if (!Header.IsValidCluster(cluster)) - return S_FALSE; - PRF(printf("\nCluster = %4X", cluster)); - RINOK(SeekToCluster(cluster)); - UInt32 newCluster = Fat[cluster]; - if ((newCluster & kFatItemUsedByDirMask) != 0) - return S_FALSE; - Fat[cluster] |= kFatItemUsedByDirMask; - cluster = newCluster; - NumDirClusters++; - NumCurUsedBytes += Header.ClusterSize(); - } - else if (sectorIndex++ >= Header.NumRootDirSectors) - break; - - RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)); - } - - const Byte *p = ByteBuf + pos; - - if (p[0] == 0) - { - /* - // FreeDOS formats FAT partition with cluster chain longer than required. - if (clusterMode && !Header.IsEoc(cluster)) - return S_FALSE; - */ - break; - } - - if (p[0] == 0xE5) - { - if (numLongRecords > 0) - return S_FALSE; - continue; - } - - Byte attrib = p[11]; - if ((attrib & 0x3F) == 0xF) - { - if (p[0] > 0x7F || Get16(p + 26) != 0) - return S_FALSE; - int longIndex = p[0] & 0x3F; - if (longIndex == 0) - return S_FALSE; - bool isLast = (p[0] & 0x40) != 0; - if (numLongRecords < 0) - { - if (!isLast) - return S_FALSE; - numLongRecords = longIndex; - } - else if (isLast || numLongRecords != longIndex) - return S_FALSE; - - numLongRecords--; - - if (p[12] == 0) - { - wchar_t nameBuf[14]; - wchar_t *dest; - - dest = AddSubStringToName(nameBuf, p + 1, 5); - dest = AddSubStringToName(dest, p + 14, 6); - AddSubStringToName(dest, p + 28, 2); - curName = nameBuf + curName; - if (isLast) - checkSum = p[13]; - if (checkSum != p[13]) - return S_FALSE; - } - } - else - { - if (numLongRecords > 0) - return S_FALSE; - CItem item; - memcpy(item.DosName, p, 11); - - if (checkSum >= 0) - { - Byte sum = 0; - for (unsigned i = 0; i < 11; i++) - sum = (Byte)(((sum & 1) ? 0x80 : 0) + (sum >> 1) + (Byte)item.DosName[i]); - if (sum == checkSum) - item.UName = curName; - } - - if (item.DosName[0] == 5) - item.DosName[0] = (char)(Byte)0xE5; - item.Attrib = attrib; - item.Flags = p[12]; - item.Size = Get32(p + 28); - item.Cluster = Get16(p + 26); - if (Header.NumFatBits > 16) - item.Cluster |= ((UInt32)Get16(p + 20) << 16); - else - { - // OS/2 and WinNT probably can store EA (extended atributes) in that field. - } - - item.CTime = Get32(p + 14); - item.CTime2 = p[13]; - item.ADate = Get16(p + 18); - item.MTime = Get32(p + 22); - item.Parent = parent; - - if (attrib == 8) - { - VolItem = item; - VolItemDefined = true; - } - else - if (memcmp(item.DosName, ". ", 11) != 0 && - memcmp(item.DosName, ".. ", 11) != 0) - { - if (!item.IsDir()) - NumCurUsedBytes += Header.GetFilePackSize(item.Size); - Items.Add(item); - PRF(printf("\n%7d: %S", Items.Size(), GetItemPath(Items.Size() - 1))); - } - numLongRecords = -1; - curName.Empty(); - checkSum = -1; - } - } - - unsigned finishIndex = Items.Size(); - for (unsigned i = startIndex; i < finishIndex; i++) - { - const CItem &item = Items[i]; - if (item.IsDir()) - { - PRF(printf("\n%S", GetItemPath(i))); - RINOK(CDatabase::ReadDir(i, item.Cluster, level + 1)); - } - } - return S_OK; -} - -HRESULT CDatabase::Open() -{ - Clear(); - bool numFreeClustersDefined = false; - { - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); - if (!Header.Parse(buf)) - return S_FALSE; - UInt64 fileSize; - RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize)); - - /* we comment that check to support truncated images */ - /* - if (fileSize < Header.GetPhySize()) - return S_FALSE; - */ - - if (Header.IsFat32()) - { - SeekToSector(Header.FsInfoSector); - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); - if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) - return S_FALSE; - if (Get32(buf) == 0x41615252 && Get32(buf + 484) == 0x61417272) - { - NumFreeClusters = Get32(buf + 488); - numFreeClustersDefined = (NumFreeClusters <= Header.FatSize); - } - } - } - - // numFreeClustersDefined = false; // to recalculate NumFreeClusters - if (!numFreeClustersDefined) - NumFreeClusters = 0; - - CByteBuffer byteBuf; - Fat = new UInt32[Header.FatSize]; - - RINOK(OpenProgressFat()); - RINOK(SeekToSector(Header.GetFatSector())); - if (Header.NumFatBits == 32) - { - const UInt32 kBufSize = (1 << 15); - byteBuf.Alloc(kBufSize); - for (UInt32 i = 0; i < Header.FatSize;) - { - UInt32 size = Header.FatSize - i; - const UInt32 kBufSize32 = kBufSize / 4; - if (size > kBufSize32) - size = kBufSize32; - UInt32 readSize = Header.SizeToSectors(size * 4) << Header.SectorSizeLog; - RINOK(ReadStream_FALSE(InStream, byteBuf, readSize)); - NumCurUsedBytes += readSize; - - const UInt32 *src = (const UInt32 *)(const Byte *)byteBuf; - UInt32 *dest = Fat + i; - if (numFreeClustersDefined) - for (UInt32 j = 0; j < size; j++) - dest[j] = Get32(src + j) & 0x0FFFFFFF; - else - { - UInt32 numFreeClusters = 0; - for (UInt32 j = 0; j < size; j++) - { - UInt32 v = Get32(src + j) & 0x0FFFFFFF; - numFreeClusters += (UInt32)(v - 1) >> 31; - dest[j] = v; - } - NumFreeClusters += numFreeClusters; - } - i += size; - if ((i & 0xFFFFF) == 0) - { - RINOK(OpenProgressFat(!numFreeClustersDefined)); - } - } - } - else - { - const UInt32 kBufSize = (UInt32)Header.CalcFatSizeInSectors() << Header.SectorSizeLog; - NumCurUsedBytes += kBufSize; - byteBuf.Alloc(kBufSize); - Byte *p = byteBuf; - RINOK(ReadStream_FALSE(InStream, p, kBufSize)); - UInt32 fatSize = Header.FatSize; - UInt32 *fat = &Fat[0]; - if (Header.NumFatBits == 16) - for (UInt32 j = 0; j < fatSize; j++) - fat[j] = Get16(p + j * 2); - else - for (UInt32 j = 0; j < fatSize; j++) - fat[j] = (Get16(p + j * 3 / 2) >> ((j & 1) << 2)) & 0xFFF; - - if (!numFreeClustersDefined) - { - UInt32 numFreeClusters = 0; - for (UInt32 i = 0; i < fatSize; i++) - numFreeClusters += (UInt32)(fat[i] - 1) >> 31; - NumFreeClusters = numFreeClusters; - } - } - - RINOK(OpenProgressFat()); - - if ((Fat[0] & 0xFF) != Header.MediaType) - return S_FALSE; - - RINOK(ReadDir(-1, Header.RootCluster, 0)); - - PhySize = Header.GetPhySize(); - return S_OK; -} - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp, - CDatabase -{ -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - const CItem &item = Items[index]; - CClusterInStream *streamSpec = new CClusterInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Stream = InStream; - streamSpec->StartOffset = Header.DataSector << Header.SectorSizeLog; - streamSpec->BlockSizeLog = Header.ClusterSizeLog; - streamSpec->Size = item.Size; - - UInt32 numClusters = Header.GetNumClusters(item.Size); - streamSpec->Vector.ClearAndReserve(numClusters); - UInt32 cluster = item.Cluster; - UInt32 size = item.Size; - - if (size == 0) - { - if (cluster != 0) - return S_FALSE; - } - else - { - UInt32 clusterSize = Header.ClusterSize(); - for (;; size -= clusterSize) - { - if (!Header.IsValidCluster(cluster)) - return S_FALSE; - streamSpec->Vector.AddInReserved(cluster - 2); - cluster = Fat[cluster]; - if (size <= clusterSize) - break; - } - if (!Header.IsEocAndUnused(cluster)) - return S_FALSE; - } - RINOK(streamSpec->InitAndSeek()); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - kpidShortName -}; - -enum -{ - kpidNumFats = kpidUserDefined - // kpidOemName, - // kpidVolName, - // kpidFileSysType -}; - -static const CStatProp kArcProps[] = -{ - { NULL, kpidFileSystem, VT_BSTR}, - { NULL, kpidClusterSize, VT_UI4}, - { NULL, kpidFreeSpace, VT_UI8}, - { NULL, kpidHeadersSize, VT_UI8}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidVolumeName, VT_BSTR}, - - { "FATs", kpidNumFats, VT_UI4}, - { NULL, kpidSectorSize, VT_UI4}, - { NULL, kpidId, VT_UI4}, - // { "OEM Name", kpidOemName, VT_BSTR}, - // { "Volume Name", kpidVolName, VT_BSTR}, - // { "File System Type", kpidFileSysType, VT_BSTR} - // { NULL, kpidSectorsPerTrack, VT_UI4}, - // { NULL, kpidNumHeads, VT_UI4}, - // { NULL, kpidHiddenSectors, VT_UI4} -}; - -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 (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; - } -} - -/* -static void StringToProp(const Byte *src, unsigned size, NWindows::NCOM::CPropVariant &prop) -{ - char dest[32]; - memcpy(dest, src, size); - dest[size] = 0; - prop = FatStringToUnicode(dest); -} - -#define STRING_TO_PROP(s, p) StringToProp(s, sizeof(s), prop) -*/ - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidFileSystem: - { - char s[16]; - s[0] = 'F'; - s[1] = 'A'; - s[2] = 'T'; - ConvertUInt32ToString(Header.NumFatBits, s + 3); - prop = s; - break; - } - case kpidClusterSize: prop = Header.ClusterSize(); break; - 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 kpidShortComment: - case kpidVolumeName: if (VolItemDefined) prop = VolItem.GetVolName(); break; - case kpidNumFats: if (Header.NumFats != 2) prop = Header.NumFats; break; - case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; - // case kpidSectorsPerTrack: prop = Header.SectorsPerTrack; break; - // case kpidNumHeads: prop = Header.NumHeads; break; - // case kpidOemName: STRING_TO_PROP(Header.OemName, prop); break; - case kpidId: if (Header.VolFieldsDefined) prop = Header.VolId; break; - // case kpidVolName: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.VolName, prop); break; - // case kpidFileSysType: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.FileSys, prop); break; - // case kpidHiddenSectors: prop = Header.NumHiddenSectors; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItem &item = Items[index]; - switch (propID) - { - 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 kpidCTime: FatTimeToProp(item.CTime, item.CTime2, prop); break; - case kpidATime: FatTimeToProp(((UInt32)item.ADate << 16), 0, prop); 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; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - OpenCallback = callback; - InStream = stream; - HRESULT res; - try - { - res = CDatabase::Open(); - if (res == S_OK) - return S_OK; - } - catch(...) - { - Close(); - throw; - } - Close(); - return res; - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - ClearAndClose(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = Items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) - { - const CItem &item = Items[allFilesMode ? i : indices[i]]; - if (!item.IsDir()) - totalSize += item.Size; - } - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 totalPackSize; - totalSize = totalPackSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems; i++) - { - lps->InSize = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItem &item = Items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - totalPackSize += Header.GetFilePackSize(item.Size); - totalSize += item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(); - - int res = NExtract::NOperationResult::kDataError; - CMyComPtr inStream; - HRESULT hres = GetStream(index, &inStream); - if (hres != S_FALSE) - { - RINOK(hres); - if (inStream) - { - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) - res = NExtract::NOperationResult::kOK; - } - } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = Items.Size(); - return S_OK; -} - -static const Byte k_Signature[] = { 0x55, 0xAA }; - -REGISTER_ARC_I( - "FAT", "fat img", 0, 0xDA, - k_Signature, - 0x1FE, - 0, - IsArc_Fat) - -}} +// FatHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/MyBuffer2.h" +#include "../../Common/MyCom.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +#include "Common/ItemNameUtils.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get16a(p) GetUi16a(p) +#define Get32a(p) GetUi32a(p) + +#if 0 +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +namespace NArchive { +namespace NFat { + +static const UInt32 kFatItemUsedByDirMask = (UInt32)1 << 31; + +struct CHeader +{ + Byte NumFatBits; + Byte SectorSizeLog; + Byte SectorsPerClusterLog; + Byte ClusterSizeLog; + Byte NumFats; + Byte MediaType; + + bool VolFieldsDefined; + bool HeadersWarning; + + UInt32 FatSize; + UInt32 BadCluster; + + UInt16 NumReservedSectors; + UInt32 NumSectors; + UInt32 NumFatSectors; + UInt32 RootDirSector; + UInt32 NumRootDirSectors; + UInt32 DataSector; + + UInt16 SectorsPerTrack; + UInt16 NumHeads; + UInt32 NumHiddenSectors; + + UInt32 VolId; + // Byte VolName[11]; + // Byte FileSys[8]; + // Byte OemName[5]; + + // 32-bit FAT + UInt16 Flags; + UInt16 FsInfoSector; + UInt32 RootCluster; + + bool IsFat32() const { return NumFatBits == 32; } + UInt64 GetPhySize() const { return (UInt64)NumSectors << SectorSizeLog; } + UInt32 SectorSize() const { return (UInt32)1 << SectorSizeLog; } + UInt32 ClusterSize() const { return (UInt32)1 << ClusterSizeLog; } + UInt32 ClusterToSector(UInt32 c) const { return DataSector + ((c - 2) << SectorsPerClusterLog); } + UInt32 IsEoc(UInt32 c) const { return c > BadCluster; } + UInt32 IsEocAndUnused(UInt32 c) const { return c > BadCluster && (c & kFatItemUsedByDirMask) == 0; } + UInt32 IsValidCluster(UInt32 c) const { return c >= 2 && c < FatSize; } + UInt32 SizeToSectors(UInt32 size) const { return (size + SectorSize() - 1) >> SectorSizeLog; } + UInt32 CalcFatSizeInSectors() const { return SizeToSectors((FatSize * (NumFatBits / 4) + 1) / 2); } + + UInt32 GetFatSector() const + { + UInt32 index = (IsFat32() && (Flags & 0x80) != 0) ? (Flags & 0xF) : 0; + if (index > NumFats) + index = 0; + return NumReservedSectors + index * NumFatSectors; + } + + UInt64 GetFilePackSize(UInt32 unpackSize) const + { + UInt64 mask = ClusterSize() - 1; + return (unpackSize + mask) & ~mask; + } + + UInt32 GetNumClusters(UInt32 size) const + { return (UInt32)(((UInt64)size + ClusterSize() - 1) >> ClusterSizeLog); } + + bool Parse(const Byte *p); +}; + + +static const unsigned kHeaderSize = 512; + +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) +{ + if (Get16(p + 0x1FE) != 0xAA55) + return false; + + HeadersWarning = false; + + int codeOffset = 0; + switch (p[0]) + { + case 0xE9: codeOffset = 3 + (Int16)Get16(p + 1); break; + case 0xEB: if (p[2] != 0x90) return false; codeOffset = 2 + (signed char)p[1]; break; + default: return false; + } + { + { + const unsigned num = Get16(p + 11); + unsigned i = 9; + unsigned m = 1 << i; + for (;;) + { + if (m == num) + break; + m <<= 1; + if (++i > 12) + return false; + } + SectorSizeLog = (Byte)i; + } + { + const unsigned num = p[13]; + unsigned i = 0; + unsigned m = 1 << i; + for (;;) + { + if (m == num) + break; + m <<= 1; + if (++i > 7) + return false; + } + SectorsPerClusterLog = (Byte)i; + i += SectorSizeLog; + ClusterSizeLog = (Byte)i; + // (2^15 = 32 KB is safe cluster size that is suported by all system. + // (2^16 = 64 KB is supported by some systems + // (128 KB / 256 KB) can be created by some tools, but it is not supported by many tools. + if (i > 18) // 256 KB + return false; + } + } + + NumReservedSectors = Get16(p + 14); + if (NumReservedSectors == 0) + return false; + + NumFats = p[16]; + if (NumFats < 1 || NumFats > 4) + return false; + + // we also support images that contain 0 in offset field. + const bool isOkOffset = (codeOffset == 0) + || (codeOffset == (p[0] == 0xEB ? 2 : 3)); + + const unsigned numRootDirEntries = Get16(p + 17); + if (numRootDirEntries == 0) + { + if (codeOffset < 90 && !isOkOffset) + return false; + NumFatBits = 32; + NumRootDirSectors = 0; + } + else + { + // Some FAT12s don't contain VolFields + if (codeOffset < 62 - 24 && !isOkOffset) + return false; + NumFatBits = 0; + const unsigned mask = (1u << (SectorSizeLog - 5)) - 1; + if (numRootDirEntries & mask) + return false; + NumRootDirSectors = (numRootDirEntries /* + mask */) >> (SectorSizeLog - 5); + } + + NumSectors = Get16(p + 19); + if (NumSectors == 0) + NumSectors = Get32(p + 32); + /* + // mkfs.fat could create fat32 image with 16-bit number of sectors. + // v23: we allow 16-bit value for number of sectors in fat32. + else if (IsFat32()) + return false; + */ + MediaType = p[21]; + NumFatSectors = Get16(p + 22); + SectorsPerTrack = Get16(p + 24); + NumHeads = Get16(p + 26); + NumHiddenSectors = Get32(p + 28); + + // memcpy(OemName, p + 3, 5); + + int curOffset = 36; + p += 36; + if (IsFat32()) + { + if (NumFatSectors != 0) + return false; + NumFatSectors = Get32(p); + if (NumFatSectors >= (1 << 24)) + return false; + + Flags = Get16(p + 4); + if (Get16(p + 6) != 0) + return false; + RootCluster = Get32(p + 8); + FsInfoSector = Get16(p + 12); + for (unsigned i = 16; i < 28; i++) + if (p[i] != 0) + return false; + p += 28; + curOffset += 28; + } + + // DriveNumber = p[0]; + VolFieldsDefined = false; + if (codeOffset >= curOffset + 3) + { + VolFieldsDefined = (p[2] == 0x29); // ExtendedBootSig + if (VolFieldsDefined) + { + if (codeOffset < curOffset + 26) + return false; + VolId = Get32(p + 3); + // memcpy(VolName, p + 7, 11); + // memcpy(FileSys, p + 18, 8); + } + } + + if (NumFatSectors == 0) + return false; + RootDirSector = NumReservedSectors + NumFatSectors * NumFats; + DataSector = RootDirSector + NumRootDirSectors; + if (NumSectors < DataSector) + return false; + const UInt32 numDataSectors = NumSectors - DataSector; + const UInt32 numClusters = numDataSectors >> SectorsPerClusterLog; + + BadCluster = 0x0FFFFFF7; + // v23: we support unusual (< 0xFFF5) numClusters values in fat32 systems + if (NumFatBits != 32) + { + if (numClusters >= 0xFFF5) + return false; + NumFatBits = (Byte)(numClusters < 0xFF5 ? 12 : 16); + BadCluster &= (((UInt32)1 << NumFatBits) - 1); + } + + FatSize = numClusters + 2; + if (FatSize > BadCluster) + return false; + if (CalcFatSizeInSectors() > NumFatSectors) + { + /* some third-party program can create such FAT image, where + size of FAT table (NumFatSectors from headers) is smaller than + required value that is calculated from calculated (FatSize) value. + Another FAT unpackers probably ignore that error. + v23.02: we also ignore that error, and + we recalculate (FatSize) value from (NumFatSectors). + New (FatSize) will be smaller than original "full" (FatSize) value. + So we will have some unused clusters at the end of archive. + */ + FatSize = (UInt32)(((UInt64)NumFatSectors << (3 + SectorSizeLog)) / NumFatBits); + HeadersWarning = true; + } + return true; +} + + + +class CItem +{ + Z7_CLASS_NO_COPY(CItem) +public: + UInt32 Size; + Byte Attrib; + Byte CTime2; + UInt16 ADate; + CByteBuffer LongName; // if LongName.Size() == 0 : no long name + // if LongName.Size() != 0 : it's NULL terminated UTF16-LE string. + char DosName[11]; + Byte Flags; + UInt32 MTime; + UInt32 CTime; + UInt32 Cluster; + Int32 Parent; + + CItem() {} + + // NT uses Flags to store Low Case status + bool NameIsLow() const { return (Flags & 0x8) != 0; } + bool ExtIsLow() const { return (Flags & 0x10) != 0; } + bool IsDir() const { return (Attrib & 0x10) != 0; } + void GetShortName(UString &dest) const; + void GetName(UString &name) const; +}; + + +static char *CopyAndTrim(char *dest, const char *src, + unsigned size, unsigned toLower) +{ + do + { + if (src[(size_t)size - 1] != ' ') + { + const unsigned range = toLower ? 'Z' - 'A' + 1 : 0; + do + { + unsigned c = (Byte)*src++; + if ((unsigned)(c - 'A') < range) + c += 0x20; + *dest++ = (char)c; + } + while (--size); + break; + } + } + while (--size); + *dest = 0; + return dest; +} + + +static void FatStringToUnicode(UString &dest, const char *s) +{ + MultiByteToUnicodeString2(dest, AString(s), CP_OEMCP); +} + +void CItem::GetShortName(UString &shortName) const +{ + char s[16]; + char *dest = CopyAndTrim(s, DosName, 8, NameIsLow()); + *dest++ = '.'; + char *dest2 = CopyAndTrim(dest, DosName + 8, 3, ExtIsLow()); + if (dest == dest2) + dest[-1] = 0; + FatStringToUnicode(shortName, s); +} + + + +// numWords != 0 +static unsigned ParseLongName(UInt16 *buf, unsigned numWords) +{ + unsigned i; + for (i = 0; i < numWords; i++) + { + const unsigned c = buf[i]; + if (c == 0) + break; + if (c == 0xFFFF) + return 0; + } + if (i == 0) + return 0; + buf[i] = 0; + numWords -= i; + i++; + if (numWords > 1) + { + numWords--; + buf += i; + do + if (*buf++ != 0xFFFF) + return 0; + while (--numWords); + } + return i; // it includes NULL terminator +} + + +void CItem::GetName(UString &name) const +{ + if (LongName.Size() >= 2) + { + const Byte * const p = LongName; + const unsigned numWords = ((unsigned)LongName.Size() - 2) / 2; + wchar_t *dest = name.GetBuf(numWords); + for (unsigned i = 0; i < numWords; i++) + dest[i] = (wchar_t)Get16(p + (size_t)i * 2); + name.ReleaseBuf_SetEnd(numWords); + } + else + GetShortName(name); + if (name.IsEmpty()) // it's unexpected + name = '_'; + NItemName::NormalizeSlashes_in_FileName_for_OsPath(name); +} + + +static void GetVolName(const char dosName[11], NWindows::NCOM::CPropVariant &prop) +{ + char s[12]; + CopyAndTrim(s, dosName, 11, false); + UString u; + FatStringToUnicode(u, AString(s)); + prop = u; +} + + +struct CDatabase +{ + CObjectVector Items; + UInt32 *Fat; + CHeader Header; + CMyComPtr InStream; + IArchiveOpenCallback *OpenCallback; + CAlignedBuffer ByteBuf; + CByteBuffer LfnBuf; + + UInt32 NumFreeClusters; + UInt32 NumDirClusters; + UInt64 NumCurUsedBytes; + UInt64 PhySize; + + UInt32 Vol_MTime; + char VolLabel[11]; + bool VolItem_Defined; + + CDatabase(): Fat(NULL) {} + ~CDatabase() { ClearAndClose(); } + + void Clear(); + void ClearAndClose(); + HRESULT OpenProgressFat(bool changeTotal = true); + HRESULT OpenProgress(); + + void GetItemPath(UInt32 index, UString &s) const; + HRESULT Open(); + HRESULT ReadDir(Int32 parent, UInt32 cluster, unsigned level); + + UInt64 GetHeadersSize() const + { + return (UInt64)(Header.DataSector + (NumDirClusters << Header.SectorsPerClusterLog)) << Header.SectorSizeLog; + } + HRESULT SeekToSector(UInt32 sector); + HRESULT SeekToCluster(UInt32 cluster) { return SeekToSector(Header.ClusterToSector(cluster)); } +}; + + +HRESULT CDatabase::SeekToSector(UInt32 sector) +{ + return InStream_SeekSet(InStream, (UInt64)sector << Header.SectorSizeLog); +} + +void CDatabase::Clear() +{ + PhySize = 0; + VolItem_Defined = false; + NumDirClusters = 0; + NumCurUsedBytes = 0; + + Items.Clear(); + delete []Fat; + Fat = NULL; +} + +void CDatabase::ClearAndClose() +{ + Clear(); + InStream.Release(); +} + +HRESULT CDatabase::OpenProgressFat(bool changeTotal) +{ + if (!OpenCallback) + return S_OK; + if (changeTotal) + { + const UInt64 numTotalBytes = (Header.CalcFatSizeInSectors() << Header.SectorSizeLog) + + ((UInt64)(Header.FatSize - NumFreeClusters) << Header.ClusterSizeLog); + RINOK(OpenCallback->SetTotal(NULL, &numTotalBytes)) + } + return OpenCallback->SetCompleted(NULL, &NumCurUsedBytes); +} + +HRESULT CDatabase::OpenProgress() +{ + if (!OpenCallback) + return S_OK; + const UInt64 numItems = Items.Size(); + return OpenCallback->SetCompleted(&numItems, &NumCurUsedBytes); +} + +void CDatabase::GetItemPath(UInt32 index, UString &s) const +{ + UString name; + for (;;) + { + const CItem &item = Items[index]; + item.GetName(name); + if (item.Parent >= 0) + name.InsertAtFront(WCHAR_PATH_SEPARATOR); + s.Insert(0, name); + index = (UInt32)item.Parent; + if (item.Parent < 0) + break; + } +} + + +HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, unsigned level) +{ + const unsigned startIndex = Items.Size(); + if (startIndex >= (1 << 30) || level > 256) + return S_FALSE; + + UInt32 blockSize = Header.ClusterSize(); + const bool clusterMode = (Header.IsFat32() || parent >= 0); + if (!clusterMode) + { + blockSize = Header.SectorSize(); + RINOK(SeekToSector(Header.RootDirSector)) + } + + ByteBuf.Alloc(blockSize); + + const unsigned k_NumLfnRecords_MAX = 20; // 260 symbols limit (strict limit) + // const unsigned k_NumLfnRecords_MAX = 0x40 - 1; // 1260 symbols limit (relaxed limit) + const unsigned k_NumLfnBytes_in_Record = 13 * 2; + // we reserve 2 additional bytes for NULL terminator + LfnBuf.Alloc(k_NumLfnRecords_MAX * k_NumLfnBytes_in_Record + 2 * 1); + + UInt32 curDirBytes_read = 0; + UInt32 sectorIndex = 0; + unsigned num_lfn_records = 0; + unsigned lfn_RecordIndex = 0; + int checkSum = -1; + bool is_record_error = false; + + for (UInt32 pos = blockSize;; pos += 32) + { + if (pos == blockSize) + { + pos = 0; + + if (clusterMode) + { + if (Header.IsEoc(cluster)) + break; + if (!Header.IsValidCluster(cluster)) + return S_FALSE; + PRF(printf("\nCluster = %4X", cluster)); + RINOK(SeekToCluster(cluster)) + const UInt32 newCluster = Fat[cluster]; + if (newCluster & kFatItemUsedByDirMask) + return S_FALSE; + Fat[cluster] |= kFatItemUsedByDirMask; + cluster = newCluster; + NumDirClusters++; + if ((NumDirClusters & 0xFF) == 0) + { + RINOK(OpenProgress()) + } + NumCurUsedBytes += Header.ClusterSize(); + } + else if (sectorIndex++ >= Header.NumRootDirSectors) + break; + + // if (curDirBytes_read > (1u << 28)) // do we need some relaxed limit for non-MS FATs? + if (curDirBytes_read >= (1u << 21)) // 2MB limit from FAT specification. + return S_FALSE; + RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)) + curDirBytes_read += blockSize; + } + + if (is_record_error) + { + Header.HeadersWarning = true; + num_lfn_records = 0; + lfn_RecordIndex = 0; + checkSum = -1; + } + + const Byte * const p = ByteBuf + pos; + + if (p[0] == 0) + { + /* + // FreeDOS formats FAT partition with cluster chain longer than required. + if (clusterMode && !Header.IsEoc(cluster)) + return S_FALSE; + */ + break; + } + + is_record_error = true; + + if (p[0] == 0xE5) + { + // deleted entry + if (num_lfn_records == 0) + is_record_error = false; + continue; + } + // else + { + const Byte attrib = p[11]; + // maybe we can use more strick check : (attrib == 0xF) ? + if ((attrib & 0x3F) == 0xF) + { + // long file name (LFN) entry + const unsigned longIndex = p[0] & 0x3F; + if (longIndex == 0 + || longIndex > k_NumLfnRecords_MAX + || p[0] > 0x7F + || Get16a(p + 26) != 0 // LDIR_FstClusLO + ) + { + return S_FALSE; + // break; + } + const bool isLast = (p[0] & 0x40) != 0; + if (num_lfn_records == 0) + { + if (!isLast) + continue; // orphan + num_lfn_records = longIndex; + } + else if (isLast || longIndex != lfn_RecordIndex) + { + return S_FALSE; + // break; + } + + lfn_RecordIndex = longIndex - 1; + + if (p[12] == 0) + { + Byte * const dest = LfnBuf + k_NumLfnBytes_in_Record * lfn_RecordIndex; + memcpy(dest, p + 1, 5 * 2); + memcpy(dest + 5 * 2, p + 14, 6 * 2); + memcpy(dest + 11 * 2, p + 28, 2 * 2); + if (isLast) + checkSum = p[13]; + if (checkSum == p[13]) + is_record_error = false; + // else return S_FALSE; + continue; + } + // else + checkSum = -1; // we will ignore LfnBuf in this case + continue; + } + + if (lfn_RecordIndex) + { + Header.HeadersWarning = true; + // return S_FALSE; + } + // lfn_RecordIndex = 0; + + const unsigned type_in_attrib = attrib & 0x18; + if (type_in_attrib == 0x18) + { + // invalid directory record (both flags are set: dir_flag and volume_flag) + return S_FALSE; + // break; + // continue; + } + if (type_in_attrib == 8) // volume_flag + { + if (!VolItem_Defined && level == 0) + { + VolItem_Defined = true; + memcpy(VolLabel, p, 11); + Vol_MTime = Get32(p + 22); + is_record_error = false; + } + } + else if (memcmp(p, ". ", 11) == 0 + || memcmp(p, ".. ", 11) == 0) + { + if (num_lfn_records == 0 && type_in_attrib == 0x10) // dir_flag + is_record_error = false; + } + else + { + CItem &item = Items.AddNew(); + memcpy(item.DosName, p, 11); + if (item.DosName[0] == 5) + item.DosName[0] = (char)(Byte)0xE5; // 0xE5 is valid KANJI lead byte value. + item.Attrib = attrib; + item.Flags = p[12]; + item.Size = Get32a(p + 28); + item.Cluster = Get16a(p + 26); + if (Header.NumFatBits > 16) + item.Cluster |= ((UInt32)Get16a(p + 20) << 16); + else + { + // OS/2 and WinNT probably can store EA (extended atributes) in that field. + } + item.CTime = Get32(p + 14); + item.CTime2 = p[13]; + item.ADate = Get16a(p + 18); + item.MTime = Get32(p + 22); + item.Parent = parent; + { + if (!item.IsDir()) + NumCurUsedBytes += Header.GetFilePackSize(item.Size); + // PRF(printf("\n%7d: %S", Items.Size(), GetItemPath(Items.Size() - 1))); + PRF(printf("\n%7d" /* ": %S" */, Items.Size() /* , item.GetShortName() */ );) + } + if (num_lfn_records == 0) + is_record_error = false; + else if (checkSum >= 0 && lfn_RecordIndex == 0) + { + Byte sum = 0; + for (unsigned i = 0; i < 11; i++) + sum = (Byte)((sum << 7) + (sum >> 1) + (Byte)item.DosName[i]); + if (sum == checkSum) + { + const unsigned numWords = ParseLongName((UInt16 *)(void *)(Byte *)LfnBuf, + num_lfn_records * k_NumLfnBytes_in_Record / 2); + if (numWords > 1) + { + // numWords includes NULL terminator + item.LongName.CopyFrom(LfnBuf, numWords * 2); + is_record_error = false; + } + } + } + + if ( + // item.LongName.Size() < 20 || // for debug + item.LongName.Size() <= 2 * 1 + && memcmp(p, " ", 11) == 0) + { + char s[16 + 16]; + const size_t numChars = (size_t)(ConvertUInt32ToString( + Items.Size() - 1 - startIndex, + MyStpCpy(s, "[NONAME]-")) - s) + 1; + item.LongName.Alloc(numChars * 2); + for (size_t i = 0; i < numChars; i++) + { + SetUi16a(item.LongName + i * 2, (Byte)s[i]) + } + Header.HeadersWarning = true; + } + } + num_lfn_records = 0; + } + } + + if (is_record_error) + Header.HeadersWarning = true; + + const unsigned finishIndex = Items.Size(); + for (unsigned i = startIndex; i < finishIndex; i++) + { + const CItem &item = Items[i]; + if (item.IsDir()) + { + PRF(printf("\n---- %c%c%c%c%c", item.DosName[0], item.DosName[1], item.DosName[2], item.DosName[3], item.DosName[4])); + RINOK(ReadDir((int)i, item.Cluster, level + 1)) + } + } + return S_OK; +} + + + +HRESULT CDatabase::Open() +{ + Clear(); + bool numFreeClusters_Defined = false; + { + UInt32 buf32[kHeaderSize / 4]; + RINOK(ReadStream_FALSE(InStream, buf32, kHeaderSize)) + if (!Header.Parse((Byte *)(void *)buf32)) + return S_FALSE; + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(InStream, fileSize)) + + /* we comment that check to support truncated images */ + /* + if (fileSize < Header.GetPhySize()) + return S_FALSE; + */ + + if (Header.IsFat32()) + { + if (((UInt32)Header.FsInfoSector << Header.SectorSizeLog) + kHeaderSize <= fileSize + && SeekToSector(Header.FsInfoSector) == S_OK + && ReadStream_FALSE(InStream, buf32, kHeaderSize) == S_OK + && 0xaa550000 == Get32a(buf32 + 508 / 4) + && 0x41615252 == Get32a(buf32) + && 0x61417272 == Get32a(buf32 + 484 / 4)) + { + NumFreeClusters = Get32a(buf32 + 488 / 4); + numFreeClusters_Defined = (NumFreeClusters <= Header.FatSize); + } + else + Header.HeadersWarning = true; + } + } + + // numFreeClusters_Defined = false; // to recalculate NumFreeClusters + if (!numFreeClusters_Defined) + NumFreeClusters = 0; + + CByteBuffer byteBuf; + Fat = new UInt32[Header.FatSize]; + + RINOK(OpenProgressFat()) + RINOK(SeekToSector(Header.GetFatSector())) + if (Header.NumFatBits == 32) + { + const UInt32 kBufSize = 1 << 15; + byteBuf.Alloc(kBufSize); + for (UInt32 i = 0;;) + { + UInt32 size = Header.FatSize - i; + if (size == 0) + break; + const UInt32 kBufSize32 = kBufSize / 4; + if (size > kBufSize32) + size = kBufSize32; + const UInt32 readSize = Header.SizeToSectors(size * 4) << Header.SectorSizeLog; + RINOK(ReadStream_FALSE(InStream, byteBuf, readSize)) + NumCurUsedBytes += readSize; + + const UInt32 *src = (const UInt32 *)(const void *)(const Byte *)byteBuf; + UInt32 *dest = Fat + i; + const UInt32 *srcLim = src + size; + if (numFreeClusters_Defined) + do + *dest++ = Get32a(src) & 0x0FFFFFFF; + while (++src != srcLim); + else + { + UInt32 numFreeClusters = 0; + do + { + const UInt32 v = Get32a(src) & 0x0FFFFFFF; + *dest++ = v; + numFreeClusters += (UInt32)(v - 1) >> 31; + } + while (++src != srcLim); + NumFreeClusters += numFreeClusters; + } + i += size; + if ((i & 0xFFFFF) == 0) + { + RINOK(OpenProgressFat(!numFreeClusters_Defined)) + } + } + } + else + { + const UInt32 kBufSize = (UInt32)Header.CalcFatSizeInSectors() << Header.SectorSizeLog; + NumCurUsedBytes += kBufSize; + byteBuf.Alloc(kBufSize); + Byte *p = byteBuf; + RINOK(ReadStream_FALSE(InStream, p, kBufSize)) + const UInt32 fatSize = Header.FatSize; + UInt32 *fat = &Fat[0]; + if (Header.NumFatBits == 16) + for (UInt32 j = 0; j < fatSize; j++) + fat[j] = Get16a(p + j * 2); + else + for (UInt32 j = 0; j < fatSize; j++) + fat[j] = (Get16(p + j * 3 / 2) >> ((j & 1) << 2)) & 0xFFF; + + if (!numFreeClusters_Defined) + { + UInt32 numFreeClusters = 0; + for (UInt32 i = 0; i < fatSize; i++) + numFreeClusters += (UInt32)(fat[i] - 1) >> 31; + NumFreeClusters = numFreeClusters; + } + } + + RINOK(OpenProgressFat()) + + if ((Fat[0] & 0xFF) != Header.MediaType) + { + // that case can mean error in FAT, + // but xdf file: (MediaType == 0xF0 && Fat[0] == 0xFF9) + // 19.00: so we use non-strict check + if ((Fat[0] & 0xFF) < 0xF0) + return S_FALSE; + } + + RINOK(ReadDir(-1, Header.RootCluster, 0)) + + PhySize = Header.GetPhySize(); + return S_OK; +} + + + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveGetRawProps, + public IInArchiveGetStream, + public CMyUnknownImp, + CDatabase +{ + Z7_IFACES_IMP_UNK_3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) +}; + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + const CItem &item = Items[index]; + CClusterInStream *streamSpec = new CClusterInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Stream = InStream; + streamSpec->StartOffset = Header.DataSector << Header.SectorSizeLog; + streamSpec->BlockSizeLog = Header.ClusterSizeLog; + streamSpec->Size = item.Size; + + const UInt32 numClusters = Header.GetNumClusters(item.Size); + streamSpec->Vector.ClearAndReserve(numClusters); + UInt32 cluster = item.Cluster; + UInt32 size = item.Size; + + if (size == 0) + { + if (cluster != 0) + return S_FALSE; + } + else + { + const UInt32 clusterSize = Header.ClusterSize(); + for (;; size -= clusterSize) + { + if (!Header.IsValidCluster(cluster)) + return S_FALSE; + streamSpec->Vector.AddInReserved(cluster - 2); + cluster = Fat[cluster]; + if (size <= clusterSize) + break; + } + if (!Header.IsEocAndUnused(cluster)) + return S_FALSE; + } + RINOK(streamSpec->InitAndSeek()) + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidAttrib, + kpidShortName + // , kpidCharacts +}; + +enum +{ + kpidNumFats = kpidUserDefined + // kpidOemName, + // kpidVolName, + // kpidFileSysType +}; + +static const CStatProp kArcProps[] = +{ + { NULL, kpidFileSystem, VT_BSTR}, + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidFreeSpace, VT_UI8}, + { NULL, kpidHeadersSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidVolumeName, VT_BSTR}, + + { "FATs", kpidNumFats, VT_UI4}, + { NULL, kpidSectorSize, VT_UI4}, + { NULL, kpidId, VT_UI4}, + // { "OEM Name", kpidOemName, VT_BSTR}, + // { "Volume Name", kpidVolName, VT_BSTR}, + // { "File System Type", kpidFileSysType, VT_BSTR} + // { NULL, kpidSectorsPerTrack, VT_UI4}, + // { NULL, kpidNumHeads, VT_UI4}, + // { NULL, kpidHiddenSectors, VT_UI4} +}; + +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::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.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_Base + 2); + } +} + +/* +static void StringToProp(const Byte *src, unsigned size, NWindows::NCOM::CPropVariant &prop) +{ + char dest[32]; + memcpy(dest, src, size); + dest[size] = 0; + prop = FatStringToUnicode(dest); +} + +#define STRING_TO_PROP(s, p) StringToProp(s, sizeof(s), prop) +*/ + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidFileSystem: + { + char s[16]; + s[0] = 'F'; + s[1] = 'A'; + s[2] = 'T'; + ConvertUInt32ToString(Header.NumFatBits, s + 3); + prop = s; + break; + } + case kpidClusterSize: prop = Header.ClusterSize(); break; + case kpidPhySize: prop = PhySize; break; + case kpidFreeSpace: prop = (UInt64)NumFreeClusters << Header.ClusterSizeLog; break; + case kpidHeadersSize: prop = GetHeadersSize(); break; + case kpidMTime: if (VolItem_Defined) PropVariant_SetFrom_DosTime(prop, Vol_MTime); break; + case kpidShortComment: + case kpidVolumeName: if (VolItem_Defined) GetVolName(VolLabel, prop); break; + case kpidNumFats: if (Header.NumFats != 2) prop = Header.NumFats; break; + case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; + // case kpidSectorsPerTrack: prop = Header.SectorsPerTrack; break; + // case kpidNumHeads: prop = Header.NumHeads; break; + // case kpidOemName: STRING_TO_PROP(Header.OemName, prop); break; + case kpidId: if (Header.VolFieldsDefined) prop = Header.VolId; break; + case kpidIsTree: prop = true; break; + // case kpidVolName: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.VolName, prop); break; + // case kpidFileSysType: if (Header.VolFieldsDefined) STRING_TO_PROP(Header.FileSys, prop); break; + // case kpidHiddenSectors: prop = Header.NumHiddenSectors; break; + case kpidWarningFlags: + { + UInt32 v = 0; + if (Header.HeadersWarning) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */ , BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + int par = -1; + if (index < Items.Size()) + par = Items[index].Parent; + *parent = (UInt32)(Int32)par; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (index < Items.Size() + && propID == kpidName) + { + CByteBuffer &buf = Items[index].LongName; + const UInt32 size = (UInt32)buf.Size(); + if (size != 0) + { + *dataSize = size; + *propType = NPropDataType::kUtf16z; + *data = (const void *)(const Byte *)buf; + } + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = Items[index]; + switch (propID) + { + case kpidPath: + case kpidName: + case kpidShortName: + { + UString s; + if (propID == kpidPath) + GetItemPath(index, s); + else if (propID == kpidName) + item.GetName(s); + else + item.GetShortName(s); + prop = s; + break; + } +/* + case kpidCharacts: + { + if (item.LongName.Size()) + prop = "LFN"; + break; + } +*/ + case kpidIsDir: prop = item.IsDir(); break; + case kpidMTime: PropVariant_SetFrom_DosTime(prop, item.MTime); break; + case kpidCTime: FatTimeToProp(item.CTime, item.CTime2, 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; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + OpenCallback = callback; + InStream = stream; + HRESULT res; + try + { + res = CDatabase::Open(); + if (res == S_OK) + return S_OK; + } + catch(...) + { + Close(); + throw; + } + Close(); + return res; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + ClearAndClose(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == (UInt32)(Int32)-1) + { + indices = NULL; + numItems = Items.Size(); + if (numItems == 0) + return S_OK; + } + else + { + if (numItems == 0) + return S_OK; + if (!indices) + return E_INVALIDARG; + } + UInt64 totalSize = 0; + { + UInt32 i = 0; + do + { + UInt32 index = i; + if (indices) + index = indices[i]; + const CItem &item = Items[index]; + if (!item.IsDir()) + totalSize += item.Size; + } + while (++i != numItems); + } + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + UInt32 i; + for (i = 0;; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i == numItems) + break; + int res; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + UInt32 index = i; + if (indices) + index = indices[i]; + const CItem &item = Items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + totalPackSize += Header.GetFilePackSize(item.Size); + totalSize += item.Size; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + res = NExtract::NOperationResult::kDataError; + CMyComPtr inStream; + const HRESULT hres = GetStream(index, &inStream); + if (hres != S_FALSE) + { + RINOK(hres) + if (inStream) + { + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) + res = NExtract::NOperationResult::kOK; + } + } + } + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Items.Size(); + return S_OK; +} + +static const Byte k_Signature[] = { 0x55, 0xAA }; + +REGISTER_ARC_I( + "FAT", "fat img", NULL, 0xDA, + k_Signature, + 0x1FE, + 0, + IsArc_Fat) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/FlvHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FlvHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/FlvHandler.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/FlvHandler.cpp 2023-03-26 12:00:00.000000000 +0000 @@ -1,526 +1,521 @@ -// FlvHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/InBuffer.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#define GetBe24(p) ( \ - ((UInt32)((const Byte *)(p))[0] << 16) | \ - ((UInt32)((const Byte *)(p))[1] << 8) | \ - ((const Byte *)(p))[2] ) - -#define Get16(p) GetBe16(p) -#define Get24(p) GetBe24(p) -#define Get32(p) GetBe32(p) - -namespace NArchive { -namespace NFlv { - -static const UInt32 kFileSizeMax = (UInt32)1 << 30; -static const UInt32 kNumChunksMax = (UInt32)1 << 23; - -static const UInt32 kTagHeaderSize = 11; - -static const Byte kFlag_Video = 1; -static const Byte kFlag_Audio = 4; - -static const Byte kType_Audio = 8; -static const Byte kType_Video = 9; -static const Byte kType_Meta = 18; -static const unsigned kNumTypes = 19; - -struct CItem -{ - CByteBuffer Data; - Byte Type; -}; - -struct CItem2 -{ - Byte Type; - Byte SubType; - Byte Props; - bool SameSubTypes; - unsigned NumChunks; - size_t Size; - - CReferenceBuf *BufSpec; - CMyComPtr RefBuf; - - bool IsAudio() const { return Type == kType_Audio; } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - CObjectVector _items2; - CByteBuffer _metadata; - bool _isRaw; - UInt64 _phySize; - - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); - // AString GetComment(); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kProps[] = -{ - kpidSize, - kpidNumBlocks, - kpidComment -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -static const char *g_AudioTypes[16] = -{ - "pcm" - , "adpcm" - , "mp3" - , "pcm_le" - , "nellymoser16" - , "nellymoser8" - , "nellymoser" - , "g711a" - , "g711m" - , "audio9" - , "aac" - , "speex" - , "audio12" - , "audio13" - , "mp3" - , "audio15" -}; - -static const char *g_VideoTypes[16] = -{ - "video0" - , "jpeg" - , "h263" - , "screen" - , "vp6" - , "vp6alpha" - , "screen2" - , "avc" - , "video8" - , "video9" - , "video10" - , "video11" - , "video12" - , "video13" - , "video14" - , "video15" -}; - -static const char *g_Rates[4] = -{ - "5.5 kHz" - , "11 kHz" - , "22 kHz" - , "44 kHz" -}; - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - const CItem2 &item = _items2[index]; - switch (propID) - { - case kpidExtension: - prop = _isRaw ? - (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) : - (item.IsAudio() ? "audio.flv" : "video.flv"); - break; - case kpidSize: - case kpidPackSize: - prop = (UInt64)item.Size; - break; - case kpidNumBlocks: prop = (UInt32)item.NumChunks; break; - case kpidComment: - { - char sz[64]; - char *s = MyStpCpy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) ); - if (item.IsAudio()) - { - *s++ = ' '; - s = MyStpCpy(s, g_Rates[(item.Props >> 2) & 3]); - s = MyStpCpy(s, (item.Props & 2) ? " 16-bit" : " 8-bit"); - s = MyStpCpy(s, (item.Props & 1) ? " stereo" : " mono"); - } - prop = sz; - break; - } - } - prop.Detach(value); - return S_OK; -} - -/* -AString CHandler::GetComment() -{ - const Byte *p = _metadata; - size_t size = _metadata.Size(); - AString res; - if (size > 0) - { - p++; - size--; - for (;;) - { - if (size < 2) - break; - int len = Get16(p); - p += 2; - size -= 2; - if (len == 0 || (size_t)len > size) - break; - { - AString temp; - temp.SetFrom_CalcLen((const char *)p, len); - if (!res.IsEmpty()) - res += '\n'; - res += temp; - } - p += len; - size -= len; - if (size < 1) - break; - Byte type = *p++; - size--; - bool ok = false; - switch (type) - { - case 0: - { - if (size < 8) - break; - ok = true; - Byte reverse[8]; - for (int i = 0; i < 8; i++) - { - bool little_endian = 1; - if (little_endian) - reverse[i] = p[7 - i]; - else - reverse[i] = p[i]; - } - double d = *(double *)reverse; - char temp[32]; - sprintf(temp, " = %.3f", d); - res += temp; - p += 8; - size -= 8; - break; - } - case 8: - { - if (size < 4) - break; - ok = true; - // UInt32 numItems = Get32(p); - p += 4; - size -= 4; - break; - } - } - if (!ok) - break; - } - } - return res; -} -*/ - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - // COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - // case kpidComment: prop = GetComment(); break; - case kpidPhySize: prop = (UInt64)_phySize; break; - case kpidIsNotArcType: prop = true; break; - } - prop.Detach(value); - return S_OK; - // COM_TRY_END -} - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) -{ - const UInt32 kHeaderSize = 13; - Byte header[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, header, kHeaderSize)); - if (header[0] != 'F' || - header[1] != 'L' || - header[2] != 'V' || - header[3] != 1 || - (header[4] & 0xFA) != 0) - return S_FALSE; - UInt64 offset = Get32(header + 5); - if (offset != 9 || Get32(header + 9) != 0) - return S_FALSE; - offset = kHeaderSize; - - CInBuffer inBuf; - if (!inBuf.Create(1 << 15)) - return E_OUTOFMEMORY; - inBuf.SetStream(stream); - - CObjectVector items; - int lasts[kNumTypes]; - unsigned i; - for (i = 0; i < kNumTypes; i++) - lasts[i] = -1; - - _phySize = offset; - for (;;) - { - Byte buf[kTagHeaderSize]; - CItem item; - if (inBuf.ReadBytes(buf, kTagHeaderSize) != kTagHeaderSize) - break; - item.Type = buf[0]; - UInt32 size = Get24(buf + 1); - if (size < 1) - break; - // item.Time = Get24(buf + 4); - // item.Time |= (UInt32)buf[7] << 24; - if (Get24(buf + 8) != 0) // streamID - break; - - UInt32 curSize = kTagHeaderSize + size + 4; - item.Data.Alloc(curSize); - memcpy(item.Data, buf, kTagHeaderSize); - if (inBuf.ReadBytes(item.Data + kTagHeaderSize, size) != size) - break; - if (inBuf.ReadBytes(item.Data + kTagHeaderSize + size, 4) != 4) - break; - - if (Get32(item.Data + kTagHeaderSize + size) != kTagHeaderSize + size) - break; - - offset += curSize; - - // printf("\noffset = %6X type = %2d time = %6d size = %6d", (UInt32)offset, item.Type, item.Time, item.Size); - - if (item.Type == kType_Meta) - { - // _metadata = item.Buf; - } - else - { - if (item.Type != kType_Audio && item.Type != kType_Video) - break; - if (items.Size() >= kNumChunksMax) - return S_FALSE; - Byte firstByte = item.Data[kTagHeaderSize]; - Byte subType, props; - if (item.Type == kType_Audio) - { - subType = (Byte)(firstByte >> 4); - props = (Byte)(firstByte & 0xF); - } - else - { - subType = (Byte)(firstByte & 0xF); - props = (Byte)(firstByte >> 4); - } - int last = lasts[item.Type]; - if (last < 0) - { - CItem2 item2; - item2.RefBuf = item2.BufSpec = new CReferenceBuf; - item2.Size = curSize; - item2.Type = item.Type; - item2.SubType = subType; - item2.Props = props; - item2.NumChunks = 1; - item2.SameSubTypes = true; - lasts[item.Type] = _items2.Add(item2); - } - else - { - CItem2 &item2 = _items2[last]; - if (subType != item2.SubType) - item2.SameSubTypes = false; - item2.Size += curSize; - item2.NumChunks++; - } - items.Add(item); - } - _phySize = offset; - if (callback && (items.Size() & 0xFF) == 0) - { - RINOK(callback->SetCompleted(NULL, &offset)) - } - } - if (items.IsEmpty()) - return S_FALSE; - - _isRaw = (_items2.Size() == 1); - for (i = 0; i < _items2.Size(); i++) - { - CItem2 &item2 = _items2[i]; - CByteBuffer &itemBuf = item2.BufSpec->Buf; - if (_isRaw) - { - if (!item2.SameSubTypes) - return S_FALSE; - itemBuf.Alloc((size_t)item2.Size - (size_t)(kTagHeaderSize + 4 + 1) * item2.NumChunks); - item2.Size = 0; - } - else - { - itemBuf.Alloc(kHeaderSize + (size_t)item2.Size); - memcpy(itemBuf, header, kHeaderSize); - itemBuf[4] = item2.IsAudio() ? kFlag_Audio : kFlag_Video; - item2.Size = kHeaderSize; - } - } - - for (i = 0; i < items.Size(); i++) - { - const CItem &item = items[i]; - CItem2 &item2 = _items2[lasts[item.Type]]; - size_t size = item.Data.Size(); - const Byte *src = item.Data; - if (_isRaw) - { - src += kTagHeaderSize + 1; - size -= (kTagHeaderSize + 4 + 1); - } - if (size != 0) - { - memcpy(item2.BufSpec->Buf + item2.Size, src, size); - item2.Size += size; - } - } - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - HRESULT res; - try - { - res = Open2(inStream, callback); - if (res == S_OK) - _stream = inStream; - } - catch(...) { res = S_FALSE; } - if (res != S_OK) - { - Close(); - return S_FALSE; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - _stream.Release(); - _items2.Clear(); - // _metadata.SetCapacity(0); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items2.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items2.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _items2[allFilesMode ? i : indices[i]].Size; - extractCallback->SetTotal(totalSize); - - totalSize = 0; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CItem2 &item = _items2[index]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - totalSize += item.Size; - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (outStream) - { - RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.Size())); - } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Init(_items2[index].BufSpec); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -static const Byte k_Signature[] = { 'F', 'L', 'V', 1, }; - -REGISTER_ARC_I( - "FLV", "flv", 0, 0xD6, - k_Signature, - 0, - 0, - NULL) - -}} +// FlvHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/InBuffer.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#define GetBe24(p) ( \ + ((UInt32)((const Byte *)(p))[0] << 16) | \ + ((UInt32)((const Byte *)(p))[1] << 8) | \ + ((const Byte *)(p))[2] ) + +// #define Get16(p) GetBe16(p) +#define Get24(p) GetBe24(p) +#define Get32(p) GetBe32(p) + +namespace NArchive { +namespace NFlv { + +// static const UInt32 kFileSizeMax = (UInt32)1 << 30; +static const UInt32 kNumChunksMax = (UInt32)1 << 23; + +static const UInt32 kTagHeaderSize = 11; + +static const Byte kFlag_Video = 1; +static const Byte kFlag_Audio = 4; + +static const Byte kType_Audio = 8; +static const Byte kType_Video = 9; +static const Byte kType_Meta = 18; +static const unsigned kNumTypes = 19; + +struct CItem +{ + CByteBuffer Data; + Byte Type; +}; + +struct CItem2 +{ + Byte Type; + Byte SubType; + Byte Props; + bool SameSubTypes; + unsigned NumChunks; + size_t Size; + + CReferenceBuf *BufSpec; + CMyComPtr RefBuf; + + bool IsAudio() const { return Type == kType_Audio; } +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CMyComPtr _stream; + CObjectVector _items2; + CByteBuffer _metadata; + bool _isRaw; + UInt64 _phySize; + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + // AString GetComment(); +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidNumBlocks, + kpidComment +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +static const char * const g_AudioTypes[16] = +{ + "pcm" + , "adpcm" + , "mp3" + , "pcm_le" + , "nellymoser16" + , "nellymoser8" + , "nellymoser" + , "g711a" + , "g711m" + , "audio9" + , "aac" + , "speex" + , "audio12" + , "audio13" + , "mp3" + , "audio15" +}; + +static const char * const g_VideoTypes[16] = +{ + "video0" + , "jpeg" + , "h263" + , "screen" + , "vp6" + , "vp6alpha" + , "screen2" + , "avc" + , "video8" + , "video9" + , "video10" + , "video11" + , "video12" + , "video13" + , "video14" + , "video15" +}; + +static const char * const g_Rates[4] = +{ + "5.5 kHz" + , "11 kHz" + , "22 kHz" + , "44 kHz" +}; + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + const CItem2 &item = _items2[index]; + switch (propID) + { + case kpidExtension: + prop = _isRaw ? + (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) : + (item.IsAudio() ? "audio.flv" : "video.flv"); + break; + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.Size; + break; + case kpidNumBlocks: prop = (UInt32)item.NumChunks; break; + case kpidComment: + { + char sz[64]; + char *s = MyStpCpy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) ); + if (item.IsAudio()) + { + *s++ = ' '; + s = MyStpCpy(s, g_Rates[(item.Props >> 2) & 3]); + s = MyStpCpy(s, (item.Props & 2) ? " 16-bit" : " 8-bit"); + s = MyStpCpy(s, (item.Props & 1) ? " stereo" : " mono"); + } + prop = sz; + break; + } + } + prop.Detach(value); + return S_OK; +} + +/* +AString CHandler::GetComment() +{ + const Byte *p = _metadata; + size_t size = _metadata.Size(); + AString res; + if (size > 0) + { + p++; + size--; + for (;;) + { + if (size < 2) + break; + int len = Get16(p); + p += 2; + size -= 2; + if (len == 0 || (size_t)len > size) + break; + { + AString temp; + temp.SetFrom_CalcLen((const char *)p, len); + if (!res.IsEmpty()) + res += '\n'; + res += temp; + } + p += len; + size -= len; + if (size < 1) + break; + Byte type = *p++; + size--; + bool ok = false; + switch (type) + { + case 0: + { + if (size < 8) + break; + ok = true; + Byte reverse[8]; + for (int i = 0; i < 8; i++) + { + bool little_endian = 1; + if (little_endian) + reverse[i] = p[7 - i]; + else + reverse[i] = p[i]; + } + double d = *(double *)reverse; + char temp[32]; + sprintf(temp, " = %.3f", d); + res += temp; + p += 8; + size -= 8; + break; + } + case 8: + { + if (size < 4) + break; + ok = true; + // UInt32 numItems = Get32(p); + p += 4; + size -= 4; + break; + } + } + if (!ok) + break; + } + } + return res; +} +*/ + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + // case kpidComment: prop = GetComment(); break; + case kpidPhySize: prop = (UInt64)_phySize; break; + case kpidIsNotArcType: prop = true; break; + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + const UInt32 kHeaderSize = 13; + Byte header[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, header, kHeaderSize)) + if (header[0] != 'F' || + header[1] != 'L' || + header[2] != 'V' || + header[3] != 1 || + (header[4] & 0xFA) != 0) + return S_FALSE; + UInt64 offset = Get32(header + 5); + if (offset != 9 || Get32(header + 9) != 0) + return S_FALSE; + offset = kHeaderSize; + + CInBuffer inBuf; + if (!inBuf.Create(1 << 15)) + return E_OUTOFMEMORY; + inBuf.SetStream(stream); + + CObjectVector items; + int lasts[kNumTypes]; + unsigned i; + for (i = 0; i < kNumTypes; i++) + lasts[i] = -1; + + _phySize = offset; + for (;;) + { + Byte buf[kTagHeaderSize]; + CItem item; + if (inBuf.ReadBytes(buf, kTagHeaderSize) != kTagHeaderSize) + break; + item.Type = buf[0]; + UInt32 size = Get24(buf + 1); + if (size < 1) + break; + // item.Time = Get24(buf + 4); + // item.Time |= (UInt32)buf[7] << 24; + if (Get24(buf + 8) != 0) // streamID + break; + + UInt32 curSize = kTagHeaderSize + size + 4; + item.Data.Alloc(curSize); + memcpy(item.Data, buf, kTagHeaderSize); + if (inBuf.ReadBytes(item.Data + kTagHeaderSize, size) != size) + break; + if (inBuf.ReadBytes(item.Data + kTagHeaderSize + size, 4) != 4) + break; + + if (Get32(item.Data + kTagHeaderSize + size) != kTagHeaderSize + size) + break; + + offset += curSize; + + // printf("\noffset = %6X type = %2d time = %6d size = %6d", (UInt32)offset, item.Type, item.Time, item.Size); + + if (item.Type == kType_Meta) + { + // _metadata = item.Buf; + } + else + { + if (item.Type != kType_Audio && item.Type != kType_Video) + break; + if (items.Size() >= kNumChunksMax) + return S_FALSE; + Byte firstByte = item.Data[kTagHeaderSize]; + Byte subType, props; + if (item.Type == kType_Audio) + { + subType = (Byte)(firstByte >> 4); + props = (Byte)(firstByte & 0xF); + } + else + { + subType = (Byte)(firstByte & 0xF); + props = (Byte)(firstByte >> 4); + } + int last = lasts[item.Type]; + if (last < 0) + { + CItem2 item2; + item2.RefBuf = item2.BufSpec = new CReferenceBuf; + item2.Size = curSize; + item2.Type = item.Type; + item2.SubType = subType; + item2.Props = props; + item2.NumChunks = 1; + item2.SameSubTypes = true; + lasts[item.Type] = (int)_items2.Add(item2); + } + else + { + CItem2 &item2 = _items2[last]; + if (subType != item2.SubType) + item2.SameSubTypes = false; + item2.Size += curSize; + item2.NumChunks++; + } + items.Add(item); + } + _phySize = offset; + if (callback && (items.Size() & 0xFF) == 0) + { + RINOK(callback->SetCompleted(NULL, &offset)) + } + } + if (items.IsEmpty()) + return S_FALSE; + + _isRaw = (_items2.Size() == 1); + for (i = 0; i < _items2.Size(); i++) + { + CItem2 &item2 = _items2[i]; + CByteBuffer &itemBuf = item2.BufSpec->Buf; + if (_isRaw) + { + if (!item2.SameSubTypes) + return S_FALSE; + itemBuf.Alloc((size_t)item2.Size - (size_t)(kTagHeaderSize + 4 + 1) * item2.NumChunks); + item2.Size = 0; + } + else + { + itemBuf.Alloc(kHeaderSize + (size_t)item2.Size); + memcpy(itemBuf, header, kHeaderSize); + itemBuf[4] = item2.IsAudio() ? kFlag_Audio : kFlag_Video; + item2.Size = kHeaderSize; + } + } + + for (i = 0; i < items.Size(); i++) + { + const CItem &item = items[i]; + CItem2 &item2 = _items2[lasts[item.Type]]; + size_t size = item.Data.Size(); + const Byte *src = item.Data; + if (_isRaw) + { + src += kTagHeaderSize + 1; + size -= (kTagHeaderSize + 4 + 1); + } + if (size != 0) + { + memcpy(item2.BufSpec->Buf + item2.Size, src, size); + item2.Size += size; + } + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + HRESULT res; + try + { + res = Open2(inStream, callback); + if (res == S_OK) + _stream = inStream; + } + catch(...) { res = S_FALSE; } + if (res != S_OK) + { + Close(); + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + _stream.Release(); + _items2.Clear(); + // _metadata.SetCapacity(0); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items2.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _items2.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items2[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + totalSize = 0; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for (i = 0; i < numItems; i++) + { + lps->InSize = 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]; + const CItem2 &item = _items2[index]; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + totalSize += item.Size; + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (outStream) + { + RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.Size())) + } + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Init(_items2[index].BufSpec); + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +static const Byte k_Signature[] = { 'F', 'L', 'V', 1, }; + +REGISTER_ARC_I( + "FLV", "flv", NULL, 0xD6, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/GptHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GptHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/GptHandler.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GptHandler.cpp 2024-06-27 20:00:00.000000000 +0000 @@ -1,405 +1,473 @@ -// GptHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.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 Get64(p) GetUi64(p) - -using namespace NWindows; - -namespace NArchive { -namespace NGpt { - -#define SIGNATURE { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 } - -static const unsigned k_SignatureSize = 12; -static const Byte k_Signature[k_SignatureSize] = SIGNATURE; - -static const UInt32 kSectorSize = 512; - -static const CUInt32PCharPair g_PartitionFlags[] = -{ - { 0, "Sys" }, - { 1, "Ignore" }, - { 2, "Legacy" }, - { 60, "Win-Read-only" }, - { 62, "Win-Hidden" }, - { 63, "Win-Not-Automount" } -}; - -static const unsigned kNameLen = 36; - -struct CPartition -{ - Byte Type[16]; - Byte Id[16]; - UInt64 FirstLba; - UInt64 LastLba; - UInt64 Flags; - Byte Name[kNameLen * 2]; - - bool IsUnused() const - { - for (unsigned i = 0; i < 16; i++) - if (Type[i] != 0) - return false; - return true; - } - - UInt64 GetSize() const { return (LastLba - FirstLba + 1) * kSectorSize; } - UInt64 GetPos() const { return FirstLba * kSectorSize; } - UInt64 GetEnd() const { return (LastLba + 1) * kSectorSize; } - - void Parse(const Byte *p) - { - memcpy(Type, p, 16); - memcpy(Id, p + 16, 16); - FirstLba = Get64(p + 32); - LastLba = Get64(p + 40); - Flags = Get64(p + 48); - memcpy(Name, p + 56, kNameLen * 2); - } -}; - - -struct CPartType -{ - UInt32 Id; - const char *Ext; - const char *Type; -}; - -static const CPartType kPartTypes[] = -{ - // { 0x0, 0, "Unused" }, - - { 0x21686148, 0, "BIOS Boot" }, - - { 0xC12A7328, 0, "EFI System" }, - { 0x024DEE41, 0, "MBR" }, - - { 0xE3C9E316, 0, "Windows MSR" }, - { 0xEBD0A0A2, 0, "Windows BDP" }, - { 0x5808C8AA, 0, "Windows LDM Metadata" }, - { 0xAF9B60A0, 0, "Windows LDM Data" }, - { 0xDE94BBA4, 0, "Windows Recovery" }, - // { 0x37AFFC90, 0, "IBM GPFS" }, - // { 0xE75CAF8F, 0, "Windows Storage Spaces" }, - - { 0x0FC63DAF, 0, "Linux Data" }, - { 0x0657FD6D, 0, "Linux Swap" }, - - { 0x83BD6B9D, 0, "FreeBSD Boot" }, - { 0x516E7CB4, 0, "FreeBSD Data" }, - { 0x516E7CB5, 0, "FreeBSD Swap" }, - { 0x516E7CB6, "ufs", "FreeBSD UFS" }, - { 0x516E7CB8, 0, "FreeBSD Vinum" }, - { 0x516E7CB8, "zfs", "FreeBSD ZFS" }, - - { 0x48465300, "hfsx", "HFS+" }, -}; - -static int FindPartType(const Byte *guid) -{ - UInt32 val = Get32(guid); - for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++) - if (kPartTypes[i].Id == val) - return i; - return -1; -} - -static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } - -static void PrintHex(unsigned v, char *s) -{ - s[0] = GetHex((v >> 4) & 0xF); - s[1] = GetHex(v & 0xF); -} - -static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw() -{ - PrintHex(val >> 8, s); - PrintHex(val & 0xFF, s + 2); -} - -static void GuidToString(const Byte *g, char *s) -{ - ConvertUInt32ToHex8Digits(Get32(g ), s); s += 8; *s++ = '-'; - ConvertUInt16ToHex4Digits(Get16(g + 4), s); s += 4; *s++ = '-'; - ConvertUInt16ToHex4Digits(Get16(g + 6), s); s += 4; *s++ = '-'; - for (unsigned i = 0; i < 8; i++) - { - if (i == 2) - *s++ = '-'; - PrintHex(g[8 + i], s); - s += 2; - } - *s = 0; -} - - -class CHandler: public CHandlerCont -{ - CRecordVector _items; - UInt64 _totalSize; - Byte Guid[16]; - - CByteBuffer _buffer; - - HRESULT Open2(IInStream *stream); - - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const - { - const CPartition &item = _items[index]; - pos = item.GetPos(); - size = item.GetSize(); - return NExtract::NOperationResult::kOK; - } - -public: - INTERFACE_IInArchive_Cont(;) -}; - - -HRESULT CHandler::Open2(IInStream *stream) -{ - _buffer.Alloc(kSectorSize * 2); - RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2)); - - const Byte *buf = _buffer; - if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) - return S_FALSE; - - buf += kSectorSize; - if (memcmp(buf, k_Signature, k_SignatureSize) != 0) - return S_FALSE; - { - // if (Get32(buf + 8) != 0x10000) return S_FALSE; // revision - UInt32 headerSize = Get32(buf + 12); // = 0x5C usually - if (headerSize > kSectorSize) - return S_FALSE; - UInt32 crc = Get32(buf + 0x10); - SetUi32(_buffer + kSectorSize + 0x10, 0); - if (CrcCalc(_buffer + kSectorSize, headerSize) != crc) - return S_FALSE; - } - // UInt32 reserved = Get32(buf + 0x14); - UInt64 curLba = Get64(buf + 0x18); - if (curLba != 1) - return S_FALSE; - UInt64 backupLba = Get64(buf + 0x20); - // UInt64 firstUsableLba = Get64(buf + 0x28); - // UInt64 lastUsableLba = Get64(buf + 0x30); - memcpy(Guid, buf + 0x38, 16); - UInt64 tableLba = Get64(buf + 0x48); - if (tableLba < 2) - return S_FALSE; - UInt32 numEntries = Get32(buf + 0x50); - UInt32 entrySize = Get32(buf + 0x54); // = 128 usually - UInt32 entriesCrc = Get32(buf + 0x58); - - if (entrySize < 128 - || entrySize > (1 << 12) - || numEntries > (1 << 16) - || tableLba < 2 - || tableLba >= ((UInt64)1 << (64 - 10))) - return S_FALSE; - - UInt32 tableSize = entrySize * numEntries; - UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1); - _buffer.Alloc(tableSizeAligned); - UInt64 tableOffset = tableLba * kSectorSize; - RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned)); - - if (CrcCalc(_buffer, tableSize) != entriesCrc) - return S_FALSE; - - _totalSize = tableOffset + tableSizeAligned; - - for (UInt32 i = 0; i < numEntries; i++) - { - CPartition item; - item.Parse(_buffer + i * entrySize); - if (item.IsUnused()) - continue; - UInt64 endPos = item.GetEnd(); - if (_totalSize < endPos) - _totalSize = endPos; - _items.Add(item); - } - - UInt64 end = (backupLba + 1) * kSectorSize; - if (_totalSize < end) - _totalSize = end; - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(stream)); - _stream = stream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - memset(Guid, 0, sizeof(Guid)); - _items.Clear(); - _stream.Release(); - return S_OK; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidFileSystem, - kpidCharacts, - kpidOffset, - kpidId -}; - -static const Byte kArcProps[] = -{ - kpidId -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: - { - if (_items.Size() == 1) - prop = (UInt32)0; - break; - } - case kpidPhySize: prop = _totalSize; break; - case kpidId: - { - char s[48]; - GuidToString(Guid, s); - prop = s; - 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: - { - UString s; - for (unsigned i = 0; i < kNameLen; i++) - { - wchar_t c = (wchar_t)Get16(item.Name + i * 2); - if (c == 0) - break; - s += c; - } - if (s.IsEmpty()) - { - char temp[16]; - ConvertUInt32ToString(index, temp); - s.AddAscii(temp); - } - { - int typeIndex = FindPartType(item.Type); - s += L'.'; - const char *ext = "img"; - if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Ext) - ext = kPartTypes[(unsigned)typeIndex].Ext; - s.AddAscii(ext); - } - prop = s; - break; - } - - case kpidSize: - case kpidPackSize: prop = item.GetSize(); break; - case kpidOffset: prop = item.GetPos(); break; - - case kpidFileSystem: - { - char s[48]; - const char *res; - int typeIndex = FindPartType(item.Type); - if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Type) - res = kPartTypes[(unsigned)typeIndex].Type; - else - { - GuidToString(item.Type, s); - res = s; - } - prop = res; - break; - } - - case kpidId: - { - char s[48]; - GuidToString(item.Id, s); - prop = s; - break; - } - - case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break; - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -REGISTER_ARC_I( - "GPT", "gpt mbr", NULL, 0xCB, - k_Signature, - kSectorSize, - 0, - NULL) - -}} +// GptHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.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 Get64(p) GetUi64(p) + +using namespace NWindows; + +namespace NArchive { + +namespace NMbr { +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize); +} + +namespace NFat { +API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size); +} + +namespace NGpt { + +static const unsigned k_SignatureSize = 12; +static const Byte k_Signature[k_SignatureSize] = + { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }; + +static const CUInt32PCharPair g_PartitionFlags[] = +{ + { 0, "Sys" }, + { 1, "Ignore" }, + { 2, "Legacy" }, + { 60, "Win-Read-only" }, + { 62, "Win-Hidden" }, + { 63, "Win-Not-Automount" } +}; + +static const unsigned kNameLen = 36; + +struct CPartition +{ + Byte Type[16]; + Byte Id[16]; + UInt64 FirstLba; + UInt64 LastLba; + UInt64 Flags; + const char *Ext; // detected later + Byte Name[kNameLen * 2]; + + bool IsUnused() const + { + for (unsigned i = 0; i < 16; i++) + if (Type[i] != 0) + return false; + return true; + } + + UInt64 GetSize(unsigned sectorSizeLog) const { return (LastLba - FirstLba + 1) << sectorSizeLog; } + UInt64 GetPos(unsigned sectorSizeLog) const { return FirstLba << sectorSizeLog; } + UInt64 GetEnd(unsigned sectorSizeLog) const { return (LastLba + 1) << sectorSizeLog; } + + void Parse(const Byte *p) + { + memcpy(Type, p, 16); + memcpy(Id, p + 16, 16); + FirstLba = Get64(p + 32); + LastLba = Get64(p + 40); + Flags = Get64(p + 48); + memcpy(Name, p + 56, kNameLen * 2); + Ext = NULL; + } +}; + + +struct CPartType +{ + UInt32 Id; + const char *Ext; + const char *Type; +}; + +static const CPartType kPartTypes[] = +{ + // { 0x0, NULL, "Unused" }, + + { 0x21686148, NULL, "BIOS Boot" }, + + { 0xC12A7328, NULL, "EFI System" }, + { 0x024DEE41, NULL, "MBR" }, + + { 0xE3C9E316, NULL, "Windows MSR" }, + { 0xEBD0A0A2, NULL, "Windows BDP" }, + { 0x5808C8AA, NULL, "Windows LDM Metadata" }, + { 0xAF9B60A0, NULL, "Windows LDM Data" }, + { 0xDE94BBA4, NULL, "Windows Recovery" }, + // { 0x37AFFC90, NULL, "IBM GPFS" }, + // { 0xE75CAF8F, NULL, "Windows Storage Spaces" }, + + { 0x0FC63DAF, NULL, "Linux Data" }, + { 0x0657FD6D, NULL, "Linux Swap" }, + { 0x44479540, NULL, "Linux root (x86)" }, + { 0x4F68BCE3, NULL, "Linux root (x86-64)" }, + { 0x69DAD710, NULL, "Linux root (ARM)" }, + { 0xB921B045, NULL, "Linux root (ARM64)" }, + { 0x993D8D3D, NULL, "Linux root (IA-64)" }, + + + { 0x83BD6B9D, NULL, "FreeBSD Boot" }, + { 0x516E7CB4, NULL, "FreeBSD Data" }, + { 0x516E7CB5, NULL, "FreeBSD Swap" }, + { 0x516E7CB6, "ufs", "FreeBSD UFS" }, + { 0x516E7CB8, NULL, "FreeBSD Vinum" }, + { 0x516E7CB8, "zfs", "FreeBSD ZFS" }, + + { 0x48465300, "hfsx", "HFS+" }, + { 0x7C3457EF, "apfs", "APFS" }, +}; + +static int FindPartType(const Byte *guid) +{ + const UInt32 val = Get32(guid); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPartTypes); i++) + if (kPartTypes[i].Id == val) + return (int)i; + return -1; +} + + +static void RawLeGuidToString_Upper(const Byte *g, char *s) +{ + RawLeGuidToString(g, s); + // MyStringUpper_Ascii(s); +} + + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + CRecordVector _items; + UInt64 _totalSize; + unsigned _sectorSizeLog; + Byte Guid[16]; + + CByteBuffer _buffer; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + const CPartition &item = _items[index]; + pos = item.GetPos(_sectorSizeLog); + size = item.GetSize(_sectorSizeLog); + return NExtract::NOperationResult::kOK; + } +}; + + +HRESULT CHandler::Open2(IInStream *stream) +{ + const unsigned kBufSize = 2 << 12; + _buffer.Alloc(kBufSize); + RINOK(ReadStream_FALSE(stream, _buffer, kBufSize)) + const Byte *buf = _buffer; + if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) + return S_FALSE; + { + for (unsigned sectorSizeLog = 9;; sectorSizeLog += 3) + { + if (sectorSizeLog > 12) + return S_FALSE; + if (memcmp(buf + ((size_t)1 << sectorSizeLog), k_Signature, k_SignatureSize) == 0) + { + buf += ((size_t)1 << sectorSizeLog); + _sectorSizeLog = sectorSizeLog; + break; + } + } + } + const UInt32 kSectorSize = 1u << _sectorSizeLog; + { + // if (Get32(buf + 8) != 0x10000) return S_FALSE; // revision + const UInt32 headerSize = Get32(buf + 12); // = 0x5C usually + if (headerSize > kSectorSize) + return S_FALSE; + const UInt32 crc = Get32(buf + 0x10); + SetUi32(_buffer + kSectorSize + 0x10, 0) + if (CrcCalc(_buffer + kSectorSize, headerSize) != crc) + return S_FALSE; + } + // UInt32 reserved = Get32(buf + 0x14); + const UInt64 curLba = Get64(buf + 0x18); + if (curLba != 1) + return S_FALSE; + const UInt64 backupLba = Get64(buf + 0x20); + // UInt64 firstUsableLba = Get64(buf + 0x28); + // UInt64 lastUsableLba = Get64(buf + 0x30); + memcpy(Guid, buf + 0x38, 16); + const UInt64 tableLba = Get64(buf + 0x48); + if (tableLba < 2 || (tableLba >> (63 - _sectorSizeLog)) != 0) + return S_FALSE; + const UInt32 numEntries = Get32(buf + 0x50); + if (numEntries > (1 << 16)) + return S_FALSE; + const UInt32 entrySize = Get32(buf + 0x54); // = 128 usually + if (entrySize < 128 || entrySize > (1 << 12)) + return S_FALSE; + const UInt32 entriesCrc = Get32(buf + 0x58); + + const UInt32 tableSize = entrySize * numEntries; + const UInt32 tableSizeAligned = (tableSize + kSectorSize - 1) & ~(kSectorSize - 1); + _buffer.Alloc(tableSizeAligned); + const UInt64 tableOffset = tableLba * kSectorSize; + RINOK(InStream_SeekSet(stream, tableOffset)) + RINOK(ReadStream_FALSE(stream, _buffer, tableSizeAligned)) + + if (CrcCalc(_buffer, tableSize) != entriesCrc) + return S_FALSE; + + _totalSize = tableOffset + tableSizeAligned; + + for (UInt32 i = 0; i < numEntries; i++) + { + CPartition item; + item.Parse(_buffer + i * entrySize); + if (item.IsUnused()) + continue; + if (item.LastLba < item.FirstLba) + return S_FALSE; + if ((item.LastLba >> (63 - _sectorSizeLog)) != 0) + return S_FALSE; + const UInt64 endPos = item.GetEnd(_sectorSizeLog); + if (_totalSize < endPos) + _totalSize = endPos; + _items.Add(item); + } + + _buffer.Free(); + { + if ((backupLba >> (63 - _sectorSizeLog)) != 0) + return S_FALSE; + const UInt64 end = (backupLba + 1) * kSectorSize; + if (_totalSize < end) + _totalSize = end; + } + { + UInt64 fileEnd; + RINOK(InStream_GetSize_SeekToEnd(stream, fileEnd)) + + if (_totalSize < fileEnd) + { + const UInt64 rem = fileEnd - _totalSize; + const UInt64 kRemMax = 1 << 22; + if (rem <= kRemMax) + { + RINOK(InStream_SeekSet(stream, _totalSize)) + bool areThereNonZeros = false; + UInt64 numZeros = 0; + if (ReadZeroTail(stream, areThereNonZeros, numZeros, kRemMax) == S_OK) + if (!areThereNonZeros) + _totalSize += numZeros; + } + } + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + 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 ( + // ((IInArchiveGetStream *)this)-> + GetStream(fileIndex, &inStream) == S_OK && inStream) + { + const char *fs = NMbr::GetFileSystem(inStream, item.GetSize(_sectorSizeLog)); + if (fs) + item.Ext = fs; + } + } + } + + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _sectorSizeLog = 0; + _totalSize = 0; + memset(Guid, 0, sizeof(Guid)); + _items.Clear(); + _stream.Release(); + return S_OK; +} + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidFileSystem, + kpidCharacts, + kpidOffset, + kpidId +}; + +static const Byte kArcProps[] = +{ + kpidSectorSize, + kpidId +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: + { + if (_items.Size() == 1) + prop = (UInt32)0; + break; + } + case kpidPhySize: prop = _totalSize; break; + case kpidSectorSize: prop = (UInt32)((UInt32)1 << _sectorSizeLog); break; + case kpidId: + { + char s[48]; + RawLeGuidToString_Upper(Guid, s); + prop = s; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CPartition &item = _items[index]; + + switch (propID) + { + case kpidPath: + { + // Windows BDP partitions can have identical names. + // So we add the partition number at front + UString s; + s.Add_UInt32(index); + { + UString s2; + for (unsigned i = 0; i < kNameLen; i++) + { + wchar_t c = (wchar_t)Get16(item.Name + i * 2); + if (c == 0) + break; + s2 += c; + } + if (!s2.IsEmpty()) + { + s.Add_Dot(); + s += s2; + } + } + { + s.Add_Dot(); + if (item.Ext) + { + AString fs (item.Ext); + fs.MakeLower_Ascii(); + s += fs; + } + else + s += "img"; + } + prop = s; + break; + } + + case kpidSize: + case kpidPackSize: prop = item.GetSize(_sectorSizeLog); break; + case kpidOffset: prop = item.GetPos(_sectorSizeLog); break; + + case kpidFileSystem: + { + char s[48]; + const char *res; + const int typeIndex = FindPartType(item.Type); + if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Type) + res = kPartTypes[(unsigned)typeIndex].Type; + else + { + RawLeGuidToString_Upper(item.Type, s); + res = s; + } + prop = res; + break; + } + + case kpidId: + { + char s[48]; + RawLeGuidToString_Upper(item.Id, s); + prop = s; + break; + } + + case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +// we suppport signature only for 512-bytes sector. +REGISTER_ARC_I( + "GPT", "gpt mbr", NULL, 0xCB, + k_Signature, + 1 << 9, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/GzHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GzHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/GzHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/GzHandler.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,1044 +1,1202 @@ -// GzHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/Defs.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" -#include "../Compress/DeflateDecoder.h" -#include "../Compress/DeflateEncoder.h" - -#include "Common/HandlerOut.h" -#include "Common/InStreamWithCRC.h" -#include "Common/OutStreamWithCRC.h" - -#define Get32(p) GetUi32(p) - -using namespace NWindows; - -using namespace NCompress; -using namespace NDeflate; - -namespace NArchive { -namespace NGz { - - static const Byte kSignature_0 = 0x1F; - static const Byte kSignature_1 = 0x8B; - static const Byte kSignature_2 = 8; // NCompressionMethod::kDeflate - - // Latest versions of gzip program don't write comment field to gz archive. - // We also don't write comment field to gz archive. - - namespace NFlags - { - const Byte kIsText = 1 << 0; - const Byte kCrc = 1 << 1; - const Byte kExtra = 1 << 2; - const Byte kName = 1 << 3; - const Byte kComment = 1 << 4; - const Byte kReserved = 0xE0; - } - - namespace NExtraFlags - { - const Byte kMaximum = 2; - const Byte kFastest = 4; - } - - namespace NHostOS - { - enum EEnum - { - kFAT = 0, - kAMIGA, - kVMS, - kUnix, - kVM_CMS, - kAtari, - kHPFS, - kMac, - kZ_System, - kCPM, - kTOPS20, - kNTFS, - kQDOS, - kAcorn, - kVFAT, - kMVS, - kBeOS, - kTandem, - - kUnknown = 255 - }; - } - -static const char * const kHostOSes[] = -{ - "FAT" - , "AMIGA" - , "VMS" - , "Unix" - , "VM/CMS" - , "Atari" - , "HPFS" - , "Macintosh" - , "Z-System" - , "CP/M" - , "TOPS-20" - , "NTFS" - , "SMS/QDOS" - , "Acorn" - , "VFAT" - , "MVS" - , "BeOS" - , "Tandem" - , "OS/400" - , "OS/X" -}; - -static const char *kUnknownOS = "Unknown"; - -class CItem -{ - bool TestFlag(Byte flag) const { return (Flags & flag) != 0; } -public: - Byte Flags; - Byte ExtraFlags; - Byte HostOS; - UInt32 Time; - UInt32 Crc; - UInt32 Size32; - - AString Name; - AString Comment; - // CByteBuffer Extra; - - CItem(): - Flags(0), - ExtraFlags(0), - HostOS(0), - Time(0), - Crc(0), - Size32(0) {} - - void Clear() - { - Name.Empty(); - Comment.Empty(); - // Extra.Free(); - } - - void CopyMetaPropsFrom(const CItem &a) - { - Flags = a.Flags; - HostOS = a.HostOS; - Time = a.Time; - Name = a.Name; - Comment = a.Comment; - // Extra = a.Extra; - } - - void CopyDataPropsFrom(const CItem &a) - { - ExtraFlags = a.ExtraFlags; - Crc = a.Crc; - Size32 = a.Size32; - } - - // bool IsText() const { return TestFlag(NFlags::kIsText); } - bool HeaderCrcIsPresent() const { return TestFlag(NFlags::kCrc); } - bool ExtraFieldIsPresent() const { return TestFlag(NFlags::kExtra); } - bool NameIsPresent() const { return TestFlag(NFlags::kName); } - bool CommentIsPresent() const { return TestFlag(NFlags::kComment); } - bool IsSupported() const { return (Flags & NFlags::kReserved) == 0; } - - HRESULT ReadHeader(NDecoder::CCOMCoder *stream); - HRESULT ReadFooter1(NDecoder::CCOMCoder *stream); - HRESULT ReadFooter2(ISequentialInStream *stream); - - HRESULT WriteHeader(ISequentialOutStream *stream); - HRESULT WriteFooter(ISequentialOutStream *stream); -}; - -static HRESULT ReadBytes(NDecoder::CCOMCoder *stream, Byte *data, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) - data[i] = stream->ReadAlignedByte(); - return stream->InputEofError() ? S_FALSE : S_OK; -} - -static HRESULT SkipBytes(NDecoder::CCOMCoder *stream, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) - stream->ReadAlignedByte(); - return stream->InputEofError() ? S_FALSE : S_OK; -} - -static HRESULT ReadUInt16(NDecoder::CCOMCoder *stream, UInt32 &value /* , UInt32 &crc */) -{ - value = 0; - for (int i = 0; i < 2; i++) - { - Byte b = stream->ReadAlignedByte(); - if (stream->InputEofError()) - return S_FALSE; - // crc = CRC_UPDATE_BYTE(crc, b); - value |= ((UInt32)(b) << (8 * i)); - } - return S_OK; -} - -static HRESULT ReadString(NDecoder::CCOMCoder *stream, AString &s, size_t limit /* , UInt32 &crc */) -{ - s.Empty(); - for (size_t i = 0; i < limit; i++) - { - Byte b = stream->ReadAlignedByte(); - if (stream->InputEofError()) - return S_FALSE; - // crc = CRC_UPDATE_BYTE(crc, b); - if (b == 0) - return S_OK; - s += (char)b; - } - return S_FALSE; -} - -static UInt32 Is_Deflate(const Byte *p, size_t size) -{ - if (size < 1) - return k_IsArc_Res_NEED_MORE; - Byte b = *p; - p++; - size--; - unsigned type = ((unsigned)b >> 1) & 3; - if (type == 3) - return k_IsArc_Res_NO; - if (type == 0) - { - // Stored (uncompreessed data) - if ((b >> 3) != 0) - return k_IsArc_Res_NO; - if (size < 4) - return k_IsArc_Res_NEED_MORE; - if (GetUi16(p) != (UInt16)~GetUi16(p + 2)) - return k_IsArc_Res_NO; - } - else if (type == 2) - { - // Dynamic Huffman - if (size < 1) - return k_IsArc_Res_NEED_MORE; - if ((*p & 0x1F) + 1 > 30) // numDistLevels - return k_IsArc_Res_NO; - } - return k_IsArc_Res_YES; -} - -static unsigned kNameMaxLen = 1 << 12; -static unsigned kCommentMaxLen = 1 << 16; - -API_FUNC_static_IsArc IsArc_Gz(const Byte *p, size_t size) -{ - if (size < 10) - return k_IsArc_Res_NEED_MORE; - if (p[0] != kSignature_0 || - p[1] != kSignature_1 || - p[2] != kSignature_2) - return k_IsArc_Res_NO; - - Byte flags = p[3]; - if ((flags & NFlags::kReserved) != 0) - return k_IsArc_Res_NO; - - Byte extraFlags = p[8]; - // maybe that flag can have another values for some gz archives? - if (extraFlags != 0 && - extraFlags != NExtraFlags::kMaximum && - extraFlags != NExtraFlags::kFastest) - return k_IsArc_Res_NO; - - size -= 10; - p += 10; - - if ((flags & NFlags::kExtra) != 0) - { - if (size < 2) - return k_IsArc_Res_NEED_MORE; - unsigned xlen = GetUi16(p); - size -= 2; - p += 2; - while (xlen != 0) - { - if (xlen < 4) - return k_IsArc_Res_NO; - if (size < 4) - return k_IsArc_Res_NEED_MORE; - unsigned len = GetUi16(p + 2); - size -= 4; - xlen -= 4; - p += 4; - if (len > xlen) - return k_IsArc_Res_NO; - if (len > size) - return k_IsArc_Res_NEED_MORE; - size -= len; - xlen -= len; - p += len; - } - } - - if ((flags & NFlags::kName) != 0) - { - size_t limit = kNameMaxLen; - if (limit > size) - limit = size; - size_t i; - for (i = 0; i < limit && p[i] != 0; i++); - if (i == size) - return k_IsArc_Res_NEED_MORE; - if (i == limit) - return k_IsArc_Res_NO; - i++; - p += i; - size -= i; - } - - if ((flags & NFlags::kComment) != 0) - { - size_t limit = kCommentMaxLen; - if (limit > size) - limit = size; - size_t i; - for (i = 0; i < limit && p[i] != 0; i++); - if (i == size) - return k_IsArc_Res_NEED_MORE; - if (i == limit) - return k_IsArc_Res_NO; - i++; - p += i; - size -= i; - } - - if ((flags & NFlags::kCrc) != 0) - { - if (size < 2) - return k_IsArc_Res_NEED_MORE; - p += 2; - size -= 2; - } - - return Is_Deflate(p, size); -} -} - -HRESULT CItem::ReadHeader(NDecoder::CCOMCoder *stream) -{ - Clear(); - - // Header-CRC field had another meaning in old version of gzip! - // UInt32 crc = CRC_INIT_VAL; - Byte buf[10]; - - RINOK(ReadBytes(stream, buf, 10)); - - if (buf[0] != kSignature_0 || - buf[1] != kSignature_1 || - buf[2] != kSignature_2) - return S_FALSE; - - Flags = buf[3]; - if (!IsSupported()) - return S_FALSE; - - Time = Get32(buf + 4); - ExtraFlags = buf[8]; - HostOS = buf[9]; - - // crc = CrcUpdate(crc, buf, 10); - - if (ExtraFieldIsPresent()) - { - UInt32 xlen; - RINOK(ReadUInt16(stream, xlen /* , crc */)); - RINOK(SkipBytes(stream, xlen)); - // Extra.SetCapacity(xlen); - // RINOK(ReadStream_FALSE(stream, Extra, xlen)); - // crc = CrcUpdate(crc, Extra, xlen); - } - if (NameIsPresent()) - RINOK(ReadString(stream, Name, kNameMaxLen /* , crc */)); - if (CommentIsPresent()) - RINOK(ReadString(stream, Comment, kCommentMaxLen /* , crc */)); - - if (HeaderCrcIsPresent()) - { - UInt32 headerCRC; - // UInt32 dummy = 0; - RINOK(ReadUInt16(stream, headerCRC /* , dummy */)); - /* - if ((UInt16)CRC_GET_DIGEST(crc) != headerCRC) - return S_FALSE; - */ - } - return stream->InputEofError() ? S_FALSE : S_OK; -} - -HRESULT CItem::ReadFooter1(NDecoder::CCOMCoder *stream) -{ - Byte buf[8]; - RINOK(ReadBytes(stream, buf, 8)); - Crc = Get32(buf); - Size32 = Get32(buf + 4); - return stream->InputEofError() ? S_FALSE : S_OK; -} - -HRESULT CItem::ReadFooter2(ISequentialInStream *stream) -{ - Byte buf[8]; - RINOK(ReadStream_FALSE(stream, buf, 8)); - Crc = Get32(buf); - Size32 = Get32(buf + 4); - return S_OK; -} - -HRESULT CItem::WriteHeader(ISequentialOutStream *stream) -{ - Byte buf[10]; - buf[0] = kSignature_0; - buf[1] = kSignature_1; - buf[2] = kSignature_2; - buf[3] = (Byte)(Flags & NFlags::kName); - // buf[3] |= NFlags::kCrc; - SetUi32(buf + 4, Time); - buf[8] = ExtraFlags; - buf[9] = HostOS; - RINOK(WriteStream(stream, buf, 10)); - // crc = CrcUpdate(CRC_INIT_VAL, buf, 10); - if (NameIsPresent()) - { - // crc = CrcUpdate(crc, (const char *)Name, Name.Len() + 1); - RINOK(WriteStream(stream, (const char *)Name, Name.Len() + 1)); - } - // SetUi16(buf, (UInt16)CRC_GET_DIGEST(crc)); - // RINOK(WriteStream(stream, buf, 2)); - return S_OK; -} - -HRESULT CItem::WriteFooter(ISequentialOutStream *stream) -{ - Byte buf[8]; - SetUi32(buf, Crc); - SetUi32(buf + 4, Size32); - return WriteStream(stream, buf, 8); -} - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ - CItem _item; - - bool _isArc; - bool _needSeekToStart; - bool _dataAfterEnd; - bool _needMoreInput; - - bool _packSize_Defined; - bool _unpackSize_Defined; - bool _numStreams_Defined; - - UInt64 _packSize; - UInt64 _unpackSize; // real unpack size (NOT from footer) - UInt64 _numStreams; - UInt64 _headerSize; // only start header (without footer) - - CMyComPtr _stream; - CMyComPtr _decoder; - NDecoder::CCOMCoder *_decoderSpec; - - CSingleMethodProps _props; - -public: - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveOpenSeq, - IOutArchive, - ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - CHandler() - { - _decoderSpec = new NDecoder::CCOMCoder; - _decoder = _decoderSpec; - } -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidMTime, - kpidHostOS, - kpidCRC - // kpidComment -}; - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - kpidNumStreams -}; - - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; - case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; - case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; - case kpidHeadersSize: if (_headerSize != 0) prop = _headerSize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - prop = v; - break; - } - case kpidName: - if (_item.NameIsPresent()) - { - UString s = MultiByteToUnicodeString(_item.Name, CP_ACP); - s.AddAscii(".gz"); - prop = s; - } - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPath: - if (_item.NameIsPresent()) - prop = MultiByteToUnicodeString(_item.Name, CP_ACP); - break; - // case kpidComment: if (_item.CommentIsPresent()) prop = MultiByteToUnicodeString(_item.Comment, CP_ACP); break; - case kpidMTime: - if (_item.Time != 0) - { - FILETIME utc; - NTime::UnixTimeToFileTime(_item.Time, utc); - prop = utc; - } - break; - case kpidSize: - { - if (_unpackSize_Defined) - prop = _unpackSize; - else if (_stream) - prop = (UInt64)_item.Size32; - break; - } - case kpidPackSize: - { - if (_packSize_Defined || _stream) - prop = _packSize; - break; - } - case kpidHostOS: prop = (_item.HostOS < ARRAY_SIZE(kHostOSes)) ? - kHostOSes[_item.HostOS] : kUnknownOS; break; - case kpidCRC: if (_stream) prop = _item.Crc; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr Callback; -public: - UInt64 Offset; - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - void Init(IArchiveOpenCallback *callback) { Callback = callback; } -}; - -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) -{ - if (Callback) - { - UInt64 files = 0; - UInt64 value = Offset + *inSize; - return Callback->SetCompleted(&files, &value); - } - return S_OK; -} - -/* -*/ - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - COM_TRY_BEGIN - RINOK(OpenSeq(stream)); - _isArc = false; - UInt64 endPos; - RINOK(stream->Seek(-8, STREAM_SEEK_END, &endPos)); - _packSize = endPos + 8; - RINOK(_item.ReadFooter2(stream)); - _stream = stream; - _isArc = true; - _needSeekToStart = true; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - COM_TRY_BEGIN - try - { - Close(); - _decoderSpec->SetInStream(stream); - _decoderSpec->InitInStream(true); - RINOK(_item.ReadHeader(_decoderSpec)); - if (_decoderSpec->InputEofError()) - return S_FALSE; - _headerSize = _decoderSpec->GetInputProcessedSize(); - _isArc = true; - return S_OK; - } - catch(const CInBufferException &e) { return e.ErrorCode; } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _needSeekToStart = false; - _dataAfterEnd = false; - _needMoreInput = false; - - _packSize_Defined = false; - _unpackSize_Defined = false; - _numStreams_Defined = false; - - _packSize = 0; - _headerSize = 0; - - _stream.Release(); - _decoderSpec->ReleaseInStream(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - if (_packSize_Defined) - extractCallback->SetTotal(_packSize); - // UInt64 currentTotalPacked = 0; - // RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, true); - - bool needReadFirstItem = _needSeekToStart; - - if (_needSeekToStart) - { - if (!_stream) - return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - _decoderSpec->InitInStream(true); - // printf("\nSeek"); - } - else - _needSeekToStart = true; - - bool firstItem = true; - - UInt64 packSize = _decoderSpec->GetInputProcessedSize(); - // printf("\npackSize = %d", (unsigned)packSize); - - UInt64 unpackedSize = 0; - UInt64 numStreams = 0; - - bool crcError = false; - - HRESULT result = S_OK; - - try { - - for (;;) - { - lps->InSize = packSize; - lps->OutSize = unpackedSize; - - RINOK(lps->SetCur()); - - CItem item; - - if (!firstItem || needReadFirstItem) - { - result = item.ReadHeader(_decoderSpec); - - if (result != S_OK && result != S_FALSE) - return result; - - if (_decoderSpec->InputEofError()) - result = S_FALSE; - - if (result != S_OK && firstItem) - { - _isArc = false; - break; - } - - if (packSize == _decoderSpec->GetStreamSize()) - { - result = S_OK; - break; - } - - if (result != S_OK) - { - _dataAfterEnd = true; - break; - } - } - - numStreams++; - firstItem = false; - - UInt64 startOffset = outStreamSpec->GetSize(); - outStreamSpec->InitCRC(); - - result = _decoderSpec->CodeResume(outStream, NULL, progress); - - packSize = _decoderSpec->GetInputProcessedSize(); - unpackedSize = outStreamSpec->GetSize(); - - if (result != S_OK && result != S_FALSE) - return result; - - if (_decoderSpec->InputEofError()) - { - packSize = _decoderSpec->GetStreamSize(); - _needMoreInput = true; - result = S_FALSE; - } - - if (result != S_OK) - break; - - _decoderSpec->AlignToByte(); - - result = item.ReadFooter1(_decoderSpec); - - packSize = _decoderSpec->GetInputProcessedSize(); - - if (result != S_OK && result != S_FALSE) - return result; - - if (result != S_OK) - { - if (_decoderSpec->InputEofError()) - { - _needMoreInput = true; - result = S_FALSE; - } - break; - } - - if (item.Crc != outStreamSpec->GetCRC() || - item.Size32 != (UInt32)(unpackedSize - startOffset)) - { - crcError = true; - result = S_FALSE; - break; - } - - // break; // we can use break, if we need only first stream - } - - } catch(const CInBufferException &e) { return e.ErrorCode; } - - if (!firstItem) - { - _packSize = packSize; - _unpackSize = unpackedSize; - _numStreams = numStreams; - - _packSize_Defined = true; - _unpackSize_Defined = true; - _numStreams_Defined = true; - } - - outStream.Release(); - - Int32 retResult = NExtract::NOperationResult::kDataError; - - if (!_isArc) - retResult = NExtract::NOperationResult::kIsNotArc; - else if (_needMoreInput) - retResult = NExtract::NOperationResult::kUnexpectedEnd; - else if (crcError) - retResult = NExtract::NOperationResult::kCRCError; - else if (_dataAfterEnd) - retResult = NExtract::NOperationResult::kDataAfterEnd; - else if (result == S_FALSE) - retResult = NExtract::NOperationResult::kDataError; - else if (result == S_OK) - retResult = NExtract::NOperationResult::kOK; - else - return result; - - return extractCallback->SetOperationResult(retResult); - - - COM_TRY_END -} - -static const Byte kHostOS = - #ifdef _WIN32 - NHostOS::kFAT; - #else - NHostOS::kUnix; - #endif - -static HRESULT UpdateArchive( - ISequentialOutStream *outStream, - UInt64 unpackSize, - CItem &item, - const CSingleMethodProps &props, - IArchiveUpdateCallback *updateCallback) -{ - UInt64 complexity = 0; - RINOK(updateCallback->SetTotal(unpackSize)); - RINOK(updateCallback->SetCompleted(&complexity)); - - CMyComPtr fileInStream; - - RINOK(updateCallback->GetStream(0, &fileInStream)); - - CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC; - CMyComPtr crcStream(inStreamSpec); - inStreamSpec->SetStream(fileInStream); - inStreamSpec->Init(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - item.ExtraFlags = props.GetLevel() >= 7 ? - NExtraFlags::kMaximum : - NExtraFlags::kFastest; - - item.HostOS = kHostOS; - - RINOK(item.WriteHeader(outStream)); - - NEncoder::CCOMCoder *deflateEncoderSpec = new NEncoder::CCOMCoder; - CMyComPtr deflateEncoder = deflateEncoderSpec; - RINOK(props.SetCoderProps(deflateEncoderSpec, NULL)); - RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress)); - - item.Crc = inStreamSpec->GetCRC(); - item.Size32 = (UInt32)inStreamSpec->GetSize(); - RINOK(item.WriteFooter(outStream)); - return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK); -} - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) -{ - *timeType = NFileTimeType::kUnix; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - - if (numItems != 1) - return E_INVALIDARG; - - Int32 newData, newProps; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); - - CItem newItem; - - if (!IntToBool(newProps)) - { - newItem.CopyMetaPropsFrom(_item); - } - else - { - newItem.HostOS = kHostOS; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidMTime, &prop)); - if (prop.vt == VT_FILETIME) - NTime::FileTimeToUnixTime(prop.filetime, newItem.Time); - else if (prop.vt == VT_EMPTY) - newItem.Time = 0; - else - return E_INVALIDARG; - } - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidPath, &prop)); - if (prop.vt == VT_BSTR) - { - UString name = prop.bstrVal; - int slashPos = name.ReverseFind_PathSepar(); - if (slashPos >= 0) - name.DeleteFrontal(slashPos + 1); - newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); - if (!newItem.Name.IsEmpty()) - newItem.Flags |= NFlags::kName; - } - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); - if (prop.vt != VT_EMPTY) - if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) - return E_INVALIDARG; - } - } - - if (IntToBool(newData)) - { - UInt64 size; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - } - return UpdateArchive(outStream, size, newItem, _props, updateCallback); - } - - if (indexInArchive != 0) - return E_INVALIDARG; - - if (!_stream) - return E_NOTIMPL; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, 0, - NUpdateNotifyOp::kReplicate)) - } - - newItem.CopyDataPropsFrom(_item); - - UInt64 offset = 0; - if (IntToBool(newProps)) - { - newItem.WriteHeader(outStream); - offset += _headerSize; - } - RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); - - return NCompress::CopyStream(_stream, outStream, progress); - - COM_TRY_END -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - return _props.SetProperties(names, values, numProps); -} - -static const Byte k_Signature[] = { kSignature_0, kSignature_1, kSignature_2 }; - -REGISTER_ARC_IO( - "gzip", "gz gzip tgz tpz", "* * .tar .tar", 0xEF, - k_Signature, - 0, - NArcInfoFlags::kKeepName, - IsArc_Gz) - -}} +// GzHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/Defs.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/DeflateDecoder.h" +#include "../Compress/DeflateEncoder.h" + +#include "Common/HandlerOut.h" +#include "Common/InStreamWithCRC.h" +#include "Common/OutStreamWithCRC.h" + +#define Get32(p) GetUi32(p) + +using namespace NWindows; + +using namespace NCompress; +using namespace NDeflate; + +namespace NArchive { +namespace NGz { + + static const Byte kSignature_0 = 0x1F; + static const Byte kSignature_1 = 0x8B; + static const Byte kSignature_2 = 8; // NCompressionMethod::kDeflate + + // Latest versions of gzip program don't write comment field to gz archive. + // We also don't write comment field to gz archive. + + namespace NFlags + { + // const Byte kIsText = 1 << 0; + const Byte kCrc = 1 << 1; + const Byte kExtra = 1 << 2; + const Byte kName = 1 << 3; + const Byte kComment = 1 << 4; + const Byte kReserved = 0xE0; + } + + namespace NExtraFlags + { + const Byte kMaximum = 2; + const Byte kFastest = 4; + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, + kAMIGA, + kVMS, + kUnix, + kVM_CMS, + kAtari, + kHPFS, + kMac, + kZ_System, + kCPM, + kTOPS20, + kNTFS, + kQDOS, + kAcorn, + kVFAT, + kMVS, + kBeOS, + kTandem, + + kUnknown = 255 + }; + } + +static const char * const kHostOSes[] = +{ + "FAT" + , "AMIGA" + , "VMS" + , "Unix" + , "VM/CMS" + , "Atari" + , "HPFS" + , "Macintosh" + , "Z-System" + , "CP/M" + , "TOPS-20" + , "NTFS" + , "SMS/QDOS" + , "Acorn" + , "VFAT" + , "MVS" + , "BeOS" + , "Tandem" + , "OS/400" + , "OS/X" +}; + + +class CItem +{ + bool TestFlag(Byte flag) const { return (Flags & flag) != 0; } +public: + Byte Flags; + Byte ExtraFlags; + Byte HostOS; + UInt32 Time; + UInt32 Crc; + UInt32 Size32; + + AString Name; + AString Comment; + // CByteBuffer Extra; + + CItem(): + Flags(0), + ExtraFlags(0), + HostOS(0), + Time(0), + Crc(0), + Size32(0) {} + + void Clear() + { + Name.Empty(); + Comment.Empty(); + // Extra.Free(); + } + + void CopyMetaPropsFrom(const CItem &a) + { + Flags = a.Flags; + HostOS = a.HostOS; + Time = a.Time; + Name = a.Name; + Comment = a.Comment; + // Extra = a.Extra; + } + + void CopyDataPropsFrom(const CItem &a) + { + ExtraFlags = a.ExtraFlags; + Crc = a.Crc; + Size32 = a.Size32; + } + + // bool IsText() const { return TestFlag(NFlags::kIsText); } + bool HeaderCrcIsPresent() const { return TestFlag(NFlags::kCrc); } + bool ExtraFieldIsPresent() const { return TestFlag(NFlags::kExtra); } + bool NameIsPresent() const { return TestFlag(NFlags::kName); } + bool CommentIsPresent() const { return TestFlag(NFlags::kComment); } + bool IsSupported() const { return (Flags & NFlags::kReserved) == 0; } + + HRESULT ReadHeader(NDecoder::CCOMCoder *stream); + HRESULT ReadFooter1(NDecoder::CCOMCoder *stream); + HRESULT ReadFooter2(ISequentialInStream *stream); + + HRESULT WriteHeader(ISequentialOutStream *stream); + HRESULT WriteFooter(ISequentialOutStream *stream); +}; + +static HRESULT ReadBytes(NDecoder::CCOMCoder *stream, Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + data[i] = stream->ReadAlignedByte(); + return stream->InputEofError() ? S_FALSE : S_OK; +} + +static HRESULT SkipBytes(NDecoder::CCOMCoder *stream, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + stream->ReadAlignedByte(); + return stream->InputEofError() ? S_FALSE : S_OK; +} + +static HRESULT ReadUInt16(NDecoder::CCOMCoder *stream, UInt32 &value /* , UInt32 &crc */) +{ + value = 0; + for (int i = 0; i < 2; i++) + { + Byte b = stream->ReadAlignedByte(); + if (stream->InputEofError()) + return S_FALSE; + // crc = CRC_UPDATE_BYTE(crc, b); + value |= ((UInt32)(b) << (8 * i)); + } + return S_OK; +} + +static HRESULT ReadString(NDecoder::CCOMCoder *stream, AString &s, size_t limit /* , UInt32 &crc */) +{ + s.Empty(); + for (size_t i = 0; i < limit; i++) + { + const Byte b = stream->ReadAlignedByte(); + if (stream->InputEofError()) + return S_FALSE; + // crc = CRC_UPDATE_BYTE(crc, b); + if (b == 0) + return S_OK; + s.Add_Char((char)b); + } + return S_FALSE; +} + +static UInt32 Is_Deflate(const Byte *p, size_t size) +{ + if (size < 1) + return k_IsArc_Res_NEED_MORE; + Byte b = *p; + p++; + size--; + unsigned type = ((unsigned)b >> 1) & 3; + if (type == 3) + return k_IsArc_Res_NO; + if (type == 0) + { + // Stored (uncompreessed data) + if ((b >> 3) != 0) + return k_IsArc_Res_NO; + if (size < 4) + return k_IsArc_Res_NEED_MORE; + UInt16 r = (UInt16)~GetUi16(p + 2); + if (GetUi16(p) != r) + return k_IsArc_Res_NO; + } + else if (type == 2) + { + // Dynamic Huffman + if (size < 1) + return k_IsArc_Res_NEED_MORE; + if ((*p & 0x1F) + 1 > 30) // numDistLevels + return k_IsArc_Res_NO; + } + return k_IsArc_Res_YES; +} + +static const unsigned kNameMaxLen = 1 << 12; +static const unsigned kCommentMaxLen = 1 << 16; + +API_FUNC_static_IsArc IsArc_Gz(const Byte *p, size_t size) +{ + if (size < 10) + return k_IsArc_Res_NEED_MORE; + if (p[0] != kSignature_0 || + p[1] != kSignature_1 || + p[2] != kSignature_2) + return k_IsArc_Res_NO; + + const Byte flags = p[3]; + if ((flags & NFlags::kReserved) != 0) + return k_IsArc_Res_NO; + + const Byte extraFlags = p[8]; + // maybe that flag can have another values for some gz archives? + if (extraFlags != 0 && + extraFlags != NExtraFlags::kMaximum && + extraFlags != NExtraFlags::kFastest) + return k_IsArc_Res_NO; + + size -= 10; + p += 10; + + if ((flags & NFlags::kExtra) != 0) + { + if (size < 2) + return k_IsArc_Res_NEED_MORE; + unsigned xlen = GetUi16(p); + size -= 2; + p += 2; + while (xlen != 0) + { + if (xlen < 4) + return k_IsArc_Res_NO; + if (size < 4) + return k_IsArc_Res_NEED_MORE; + const unsigned len = GetUi16(p + 2); + size -= 4; + xlen -= 4; + p += 4; + if (len > xlen) + return k_IsArc_Res_NO; + if (len > size) + return k_IsArc_Res_NEED_MORE; + size -= len; + xlen -= len; + p += len; + } + } + + if ((flags & NFlags::kName) != 0) + { + size_t limit = kNameMaxLen; + if (limit > size) + limit = size; + size_t i; + for (i = 0; i < limit && p[i] != 0; i++); + if (i == size) + return k_IsArc_Res_NEED_MORE; + if (i == limit) + return k_IsArc_Res_NO; + i++; + p += i; + size -= i; + } + + if ((flags & NFlags::kComment) != 0) + { + size_t limit = kCommentMaxLen; + if (limit > size) + limit = size; + size_t i; + for (i = 0; i < limit && p[i] != 0; i++); + if (i == size) + return k_IsArc_Res_NEED_MORE; + if (i == limit) + return k_IsArc_Res_NO; + i++; + p += i; + size -= i; + } + + if ((flags & NFlags::kCrc) != 0) + { + if (size < 2) + return k_IsArc_Res_NEED_MORE; + p += 2; + size -= 2; + } + + return Is_Deflate(p, size); +} +} + +HRESULT CItem::ReadHeader(NDecoder::CCOMCoder *stream) +{ + Clear(); + + // Header-CRC field had another meaning in old version of gzip! + // UInt32 crc = CRC_INIT_VAL; + Byte buf[10]; + + RINOK(ReadBytes(stream, buf, 10)) + + if (buf[0] != kSignature_0 || + buf[1] != kSignature_1 || + buf[2] != kSignature_2) + return S_FALSE; + + Flags = buf[3]; + if (!IsSupported()) + return S_FALSE; + + Time = Get32(buf + 4); + ExtraFlags = buf[8]; + HostOS = buf[9]; + + // crc = CrcUpdate(crc, buf, 10); + + if (ExtraFieldIsPresent()) + { + UInt32 xlen; + RINOK(ReadUInt16(stream, xlen /* , crc */)) + RINOK(SkipBytes(stream, xlen)) + // Extra.SetCapacity(xlen); + // RINOK(ReadStream_FALSE(stream, Extra, xlen)); + // crc = CrcUpdate(crc, Extra, xlen); + } + if (NameIsPresent()) + RINOK(ReadString(stream, Name, kNameMaxLen /* , crc */)) + if (CommentIsPresent()) + RINOK(ReadString(stream, Comment, kCommentMaxLen /* , crc */)) + + if (HeaderCrcIsPresent()) + { + UInt32 headerCRC; + // UInt32 dummy = 0; + RINOK(ReadUInt16(stream, headerCRC /* , dummy */)) + /* + if ((UInt16)CRC_GET_DIGEST(crc) != headerCRC) + return S_FALSE; + */ + } + return stream->InputEofError() ? S_FALSE : S_OK; +} + +HRESULT CItem::ReadFooter1(NDecoder::CCOMCoder *stream) +{ + Byte buf[8]; + RINOK(ReadBytes(stream, buf, 8)) + Crc = Get32(buf); + Size32 = Get32(buf + 4); + return stream->InputEofError() ? S_FALSE : S_OK; +} + +HRESULT CItem::ReadFooter2(ISequentialInStream *stream) +{ + Byte buf[8]; + RINOK(ReadStream_FALSE(stream, buf, 8)) + Crc = Get32(buf); + Size32 = Get32(buf + 4); + return S_OK; +} + +HRESULT CItem::WriteHeader(ISequentialOutStream *stream) +{ + Byte buf[10]; + buf[0] = kSignature_0; + buf[1] = kSignature_1; + buf[2] = kSignature_2; + buf[3] = (Byte)(Flags & NFlags::kName); + // buf[3] |= NFlags::kCrc; + SetUi32(buf + 4, Time) + buf[8] = ExtraFlags; + buf[9] = HostOS; + RINOK(WriteStream(stream, buf, 10)) + // crc = CrcUpdate(CRC_INIT_VAL, buf, 10); + if (NameIsPresent()) + { + // crc = CrcUpdate(crc, (const char *)Name, Name.Len() + 1); + RINOK(WriteStream(stream, (const char *)Name, Name.Len() + 1)) + } + // SetUi16(buf, (UInt16)CRC_GET_DIGEST(crc)); + // RINOK(WriteStream(stream, buf, 2)); + return S_OK; +} + +HRESULT CItem::WriteFooter(ISequentialOutStream *stream) +{ + Byte buf[8]; + SetUi32(buf, Crc) + SetUi32(buf + 4, Size32) + return WriteStream(stream, buf, 8); +} + +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveOpenSeq, + IOutArchive, + ISetProperties +) + CItem _item; + + bool _isArc; + bool _needSeekToStart; + bool _dataAfterEnd; + bool _needMoreInput; + + bool _packSize_Defined; + bool _unpackSize_Defined; + bool _numStreams_Defined; + + UInt64 _packSize; + UInt64 _unpackSize; // real unpack size (NOT from footer) + UInt64 _numStreams; + UInt64 _headerSize; // only start header (without footer) + + CMyComPtr _stream; + CMyComPtr2 _decoder; + + CSingleMethodProps _props; + CHandlerTimeOptions _timeOptions; + +public: + CHandler(): + _isArc(false) + {} + + void CreateDecoder() + { + _decoder.Create_if_Empty(); + } +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidMTime, + kpidHostOS, + kpidCRC + // kpidComment +}; + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidNumStreams +}; + + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; + case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; + case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; + case kpidHeadersSize: if (_headerSize != 0) prop = _headerSize; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + prop = v; + break; + } + case kpidName: + if (_item.NameIsPresent()) + { + UString s = MultiByteToUnicodeString(_item.Name, CP_ACP); + s += ".gz"; + prop = s; + } + break; + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPath: + if (_item.NameIsPresent()) + prop = MultiByteToUnicodeString(_item.Name, CP_ACP); + 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) + PropVariant_SetFrom_UnixTime(prop, _item.Time); + break; + case kpidTimeType: + if (_item.Time != 0) + prop = (UInt32)NFileTimeType::kUnix; + break; + case kpidSize: + { + if (_unpackSize_Defined) + prop = _unpackSize; + else if (_stream) + prop = (UInt64)_item.Size32; + break; + } + case kpidPackSize: + { + if (_packSize_Defined || _stream) + prop = _packSize; + break; + } + case kpidHostOS: TYPE_TO_PROP(kHostOSes, _item.HostOS, prop); break; + case kpidCRC: if (_stream) prop = _item.Crc; break; + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) + CMyComPtr Callback; +public: + UInt64 Offset; + void Init(IArchiveOpenCallback *callback) { Callback = callback; } +}; + +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) +{ + if (Callback) + { + UInt64 files = 0; + UInt64 value = Offset + *inSize; + return Callback->SetCompleted(&files, &value); + } + return S_OK; +} + +/* +*/ + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) +{ + COM_TRY_BEGIN + RINOK(OpenSeq(stream)) + _isArc = false; + UInt64 endPos; + RINOK(stream->Seek(-8, STREAM_SEEK_END, &endPos)) + _packSize = endPos + 8; + RINOK(_item.ReadFooter2(stream)) + _stream = stream; + _isArc = true; + _needSeekToStart = true; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + COM_TRY_BEGIN + try + { + Close(); + CreateDecoder(); + _decoder->SetInStream(stream); + _decoder->InitInStream(true); + RINOK(_item.ReadHeader(_decoder.ClsPtr())) + if (_decoder->InputEofError()) + return S_FALSE; + _headerSize = _decoder->GetInputProcessedSize(); + _isArc = true; + return S_OK; + } + catch(const CInBufferException &e) { return e.ErrorCode; } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _needSeekToStart = false; + _dataAfterEnd = false; + _needMoreInput = false; + + _packSize_Defined = false; + _unpackSize_Defined = false; + _numStreams_Defined = false; + + _packSize = 0; + _headerSize = 0; + + _stream.Release(); + if (_decoder) + _decoder->ReleaseInStream(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + if (_packSize_Defined) + RINOK(extractCallback->SetTotal(_packSize)) + // UInt64 currentTotalPacked = 0; + // RINOK(extractCallback->SetCompleted(¤tTotalPacked)); + Int32 retResult; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CreateDecoder(); + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + bool needReadFirstItem = _needSeekToStart; + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(InStream_SeekToBegin(_stream)) + _decoder->InitInStream(true); + // printf("\nSeek"); + } + else + _needSeekToStart = true; + + bool firstItem = true; + + UInt64 packSize = _decoder->GetInputProcessedSize(); + // printf("\npackSize = %d", (unsigned)packSize); + + UInt64 unpackedSize = 0; + UInt64 numStreams = 0; + + bool crcError = false; + + HRESULT result = S_OK; + + try { + + for (;;) + { + lps->InSize = packSize; + lps->OutSize = unpackedSize; + + RINOK(lps->SetCur()) + + CItem item; + + if (!firstItem || needReadFirstItem) + { + result = item.ReadHeader(_decoder.ClsPtr()); + + if (result != S_OK && result != S_FALSE) + return result; + + if (_decoder->InputEofError()) + result = S_FALSE; + + if (result != S_OK && firstItem) + { + _isArc = false; + break; + } + + if (packSize == _decoder->GetStreamSize()) + { + result = S_OK; + break; + } + + if (result != S_OK) + { + _dataAfterEnd = true; + break; + } + } + + numStreams++; + firstItem = false; + + const UInt64 startOffset = outStream->GetSize(); + outStream->InitCRC(); + + result = _decoder->CodeResume(outStream, NULL, lps); + + packSize = _decoder->GetInputProcessedSize(); + unpackedSize = outStream->GetSize(); + + if (result != S_OK && result != S_FALSE) + return result; + + if (_decoder->InputEofError()) + { + packSize = _decoder->GetStreamSize(); + _needMoreInput = true; + result = S_FALSE; + } + + if (result != S_OK) + break; + + _decoder->AlignToByte(); + + result = item.ReadFooter1(_decoder.ClsPtr()); + + packSize = _decoder->GetInputProcessedSize(); + + if (result != S_OK && result != S_FALSE) + return result; + + if (result != S_OK) + { + if (_decoder->InputEofError()) + { + _needMoreInput = true; + result = S_FALSE; + } + break; + } + + if (item.Crc != outStream->GetCRC() || + item.Size32 != (UInt32)(unpackedSize - startOffset)) + { + crcError = true; + result = S_FALSE; + break; + } + + // break; // we can use break, if we need only first stream + } + + } catch(const CInBufferException &e) { return e.ErrorCode; } + + if (!firstItem) + { + _packSize = packSize; + _unpackSize = unpackedSize; + _numStreams = numStreams; + + _packSize_Defined = true; + _unpackSize_Defined = true; + _numStreams_Defined = true; + } + + // outStream.Release(); + + retResult = NExtract::NOperationResult::kDataError; + + if (!_isArc) + retResult = NExtract::NOperationResult::kIsNotArc; + else if (_needMoreInput) + retResult = NExtract::NOperationResult::kUnexpectedEnd; + else if (crcError) + retResult = NExtract::NOperationResult::kCRCError; + else if (_dataAfterEnd) + retResult = NExtract::NOperationResult::kDataAfterEnd; + else if (result == S_FALSE) + retResult = NExtract::NOperationResult::kDataError; + else if (result == S_OK) + retResult = NExtract::NOperationResult::kOK; + else + return result; + } + + return extractCallback->SetOperationResult(retResult); + COM_TRY_END +} + +static const Byte kHostOS = + #ifdef _WIN32 + NHostOS::kFAT; + #else + 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, + const CHandlerTimeOptions &timeOptions, + IArchiveUpdateCallback *updateCallback + // , IArchiveUpdateCallbackArcProp *reportArcProp + ) +{ + UInt64 unpackSizeReal; + { + CMyComPtr fileInStream; + + RINOK(updateCallback->GetStream(0, &fileInStream)) + + if (!fileInStream) + return S_FALSE; + + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetProps, + getProps, fileInStream) + 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)) + + CMyComPtr2_Create crcStream; + crcStream->SetStream(fileInStream); + crcStream->Init(); + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + item.ExtraFlags = props.GetLevel() >= 7 ? + NExtraFlags::kMaximum : + NExtraFlags::kFastest; + + item.HostOS = kHostOS; + + RINOK(item.WriteHeader(outStream)) + + CMyComPtr2_Create deflateEncoder; + + RINOK(props.SetCoderProps(deflateEncoder.ClsPtr(), NULL)) + RINOK(deflateEncoder.Interface()->Code(crcStream, outStream, NULL, NULL, lps)) + + item.Crc = crcStream->GetCRC(); + unpackSizeReal = crcStream->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); +} + + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + /* + 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; +} + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + if (numItems != 1) + return E_INVALIDARG; + + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + // Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, reportArcProp, updateCallback) + + CItem newItem; + + if (!IntToBool(newProps)) + { + newItem.CopyMetaPropsFrom(_item); + } + else + { + newItem.HostOS = kHostOS; + if (_timeOptions.Write_MTime.Val) + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidMTime, &prop)) + if (prop.vt == VT_FILETIME) + NTime::FileTime_To_UnixTime(prop.filetime, newItem.Time); + else if (prop.vt == VT_EMPTY) + newItem.Time = 0; + else + return E_INVALIDARG; + } + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidPath, &prop)) + if (prop.vt == VT_BSTR) + { + UString name = prop.bstrVal; + int slashPos = name.ReverseFind_PathSepar(); + if (slashPos >= 0) + name.DeleteFrontal((unsigned)(slashPos + 1)); + newItem.Name = UnicodeStringToMultiByte(name, CP_ACP); + if (!newItem.Name.IsEmpty()) + newItem.Flags |= NFlags::kName; + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt != VT_EMPTY) + if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + return UpdateArchive(outStream, size, newItem, _props, _timeOptions, updateCallback); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + if (!_stream) + return E_NOTIMPL; + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, 0, + NUpdateNotifyOp::kReplicate)) + } + + newItem.CopyDataPropsFrom(_item); + + UInt64 offset = 0; + if (IntToBool(newProps)) + { + newItem.WriteHeader(outStream); + offset += _headerSize; + } + RINOK(InStream_SeekSet(_stream, offset)) + + /* + if (reportArcProp) + ReportArcProps(reportArcProp, newItem, + _props._Write_MTime, + false, // writeCrc + NULL); // unpacksize + */ + + return NCompress::CopyStream(_stream, outStream, lps); + + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 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 + | 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/HandlerCont.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/HandlerCont.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.cpp 2023-12-18 16:00:00.000000000 +0000 @@ -1,288 +1,321 @@ -// HandlerCont.cpp - -#include "StdAfx.h" - -#include "../../Common/ComTry.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#include "HandlerCont.h" - -namespace NArchive { - -STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - { - RINOK(GetNumberOfItems(&numItems)); - } - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt64 pos, size; - GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size); - totalSize += size; - } - 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); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++) - { - lps->InSize = totalSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - - UInt64 pos, size; - int opRes = GetItem_ExtractInfo(index, pos, size); - totalSize += size; - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - - if (opRes == NExtract::NOperationResult::kOK) - { - RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL)); - streamSpec->Init(size); - - 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 -} - -STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = NULL; - UInt64 pos, size; - if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK) - return S_FALSE; - return CreateLimitedInStream(_stream, pos, size, stream); - COM_TRY_END -} - - - -CHandlerImg::CHandlerImg(): - _imgExt(NULL) -{ - ClearStreamVars(); -} - -STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += _size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - -static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }; - -static const char *GetImgExt(ISequentialInStream *stream) -{ - const size_t kHeaderSize = 1 << 10; - Byte buf[kHeaderSize]; - if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK) - { - if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) - { - if (memcmp(buf + 512, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0) - return "gpt"; - return "mbr"; - } - } - return NULL; -} - -void CHandlerImg::CloseAtError() -{ - Stream.Release(); -} - -STDMETHODIMP CHandlerImg::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * openCallback) -{ - COM_TRY_BEGIN - { - Close(); - HRESULT res; - try - { - res = Open2(stream, openCallback); - if (res == S_OK) - { - CMyComPtr inStream; - HRESULT res2 = GetStream(0, &inStream); - if (res2 == S_OK && inStream) - _imgExt = GetImgExt(inStream); - return S_OK; - } - } - catch(...) - { - CloseAtError(); - throw; - } - CloseAtError(); - return res; - } - COM_TRY_END -} - -STDMETHODIMP CHandlerImg::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - RINOK(extractCallback->SetTotal(_size)); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &outStream, askMode)); - if (!testMode && !outStream) - return S_OK; - RINOK(extractCallback->PrepareOperation(askMode)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - int opRes = NExtract::NOperationResult::kDataError; - - ClearStreamVars(); - - CMyComPtr inStream; - HRESULT hres = GetStream(0, &inStream); - if (hres == S_FALSE) - hres = E_NOTIMPL; - - if (hres == S_OK && inStream) - { - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - hres = copyCoder->Code(inStream, outStream, NULL, &_size, progress); - if (hres == S_OK) - { - if (copyCoderSpec->TotalSize == _size) - opRes = NExtract::NOperationResult::kOK; - - if (_stream_unavailData) - opRes = NExtract::NOperationResult::kUnavailable; - else if (_stream_unsupportedMethod) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (_stream_dataError) - opRes = NExtract::NOperationResult::kDataError; - else if (copyCoderSpec->TotalSize < _size) - opRes = NExtract::NOperationResult::kUnexpectedEnd; - } - } - - inStream.Release(); - outStream.Release(); - - if (hres != S_OK) - { - if (hres == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else if (hres == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else - return hres; - } - - return extractCallback->SetOperationResult(opRes); - COM_TRY_END -} - - -HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) -{ - areThereNonZeros = false; - numZeros = 0; - const size_t kBufSize = 1 << 11; - Byte buf[kBufSize]; - for (;;) - { - UInt32 size = 0; - HRESULT(stream->Read(buf, kBufSize, &size)); - if (size == 0) - return S_OK; - for (UInt32 i = 0; i < size; i++) - if (buf[i] != 0) - { - areThereNonZeros = true; - numZeros += i; - return S_OK; - } - numZeros += size; - if (numZeros > maxSize) - return S_OK; - } -} - -} +// HandlerCont.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +#include "HandlerCont.h" + +namespace NArchive { + +namespace NExt { +API_FUNC_IsArc IsArc_Ext(const Byte *p, size_t size); +} + +Z7_COM7F_IMF(CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + { + RINOK(GetNumberOfItems(&numItems)) + } + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt64 pos, size; + GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size); + totalSize += size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + totalSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create streamSpec; + streamSpec->SetStream(_stream); + CMyComPtr2_Create copyCoder; + + for (i = 0;; i++) + { + lps->InSize = totalSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + 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)) + + UInt64 pos, size; + int opRes = GetItem_ExtractInfo(index, pos, size); + totalSize += size; + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + + if (opRes == NExtract::NOperationResult::kOK) + { + RINOK(InStream_SeekSet(_stream, pos)) + streamSpec->Init(size); + + RINOK(copyCoder.Interface()->Code(streamSpec, outStream, NULL, NULL, lps)) + + opRes = NExtract::NOperationResult::kDataError; + if (copyCoder->TotalSize == size) + opRes = NExtract::NOperationResult::kOK; + else if (copyCoder->TotalSize < size) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + } + + outStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + UInt64 pos, size; + if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK) + return S_FALSE; + return CreateLimitedInStream(_stream, pos, size, stream); + COM_TRY_END +} + + + +CHandlerImg::CHandlerImg() +{ + Clear_HandlerImg_Vars(); +} + +Z7_COM7F_IMF(CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + { + if (newPosition) + *newPosition = _virtPos; + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + } + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + +static const Byte k_GDP_Signature[] = + { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T', 0, 0, 1, 0 }; +// 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_for_Ext = (1 << 11); // for ext + const size_t kHeaderSize = 2 << 12; // for 4 KB sector GPT + Byte buf[kHeaderSize]; + size_t processed = kHeaderSize; + if (ReadStream(stream, buf, &processed) == S_OK) + { + if (processed >= kHeaderSize) + if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) + { + for (unsigned k = (1 << 9); k <= (1u << 12); k <<= 3) + if (memcmp(buf + k, k_GDP_Signature, sizeof(k_GDP_Signature)) == 0) + return "gpt"; + return "mbr"; + } + if (NExt::IsArc_Ext(buf, processed) == k_IsArc_Res_YES) + return "ext"; + } + return NULL; +} + +void CHandlerImg::CloseAtError() +{ + Stream.Release(); +} + +void CHandlerImg::Clear_HandlerImg_Vars() +{ + _imgExt = NULL; + _size = 0; + ClearStreamVars(); + Reset_VirtPos(); + Reset_PosInArc(); +} + +Z7_COM7F_IMF(CHandlerImg::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * openCallback)) +{ + COM_TRY_BEGIN + { + Close(); + HRESULT res; + try + { + res = Open2(stream, openCallback); + if (res == S_OK) + { + CMyComPtr inStream; + const HRESULT res2 = GetStream(0, &inStream); + if (res2 == S_OK && inStream) + _imgExt = GetImgExt(inStream); + // _imgExt = GetImgExt(this); // for debug + /* we reset (_virtPos) to support cases, if some code will + call Read() from Handler object instead of GetStream() object. */ + Reset_VirtPos(); + // optional: we reset (_posInArc). if real seek position of stream will be changed in external code + Reset_PosInArc(); + // optional: here we could also reset seek positions in parent streams.. + return S_OK; + } + } + catch(...) + { + CloseAtError(); + throw; + } + CloseAtError(); + return res; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandlerImg::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + + +Z7_CLASS_IMP_NOQIB_1( + CHandlerImgProgress + , ICompressProgressInfo +) +public: + CHandlerImg &Handler; + CMyComPtr _ratioProgress; + + CHandlerImgProgress(CHandlerImg &handler) : Handler(handler) {} +}; + + +Z7_COM7F_IMF(CHandlerImgProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + UInt64 inSize2; + if (Handler.Get_PackSizeProcessed(inSize2)) + inSize = &inSize2; + return _ratioProgress->SetRatioInfo(inSize, outSize); +} + + +Z7_COM7F_IMF(CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + RINOK(extractCallback->SetTotal(_size)) + CMyComPtr outStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &outStream, askMode)) + if (!testMode && !outStream) + return S_OK; + RINOK(extractCallback->PrepareOperation(askMode)) + + int opRes = NExtract::NOperationResult::kDataError; + + ClearStreamVars(); + + CMyComPtr inStream; + HRESULT hres = GetStream(0, &inStream); + if (hres == S_FALSE) + hres = E_NOTIMPL; + + 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; + } + + CMyComPtr2_Create copyCoder; + + hres = copyCoder.Interface()->Code(inStream, outStream, NULL, &_size, progress); + if (hres == S_OK) + { + if (copyCoder->TotalSize == _size) + opRes = NExtract::NOperationResult::kOK; + + if (_stream_unavailData) + opRes = NExtract::NOperationResult::kUnavailable; + else if (_stream_unsupportedMethod) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else if (_stream_dataError) + opRes = NExtract::NOperationResult::kDataError; + else if (copyCoder->TotalSize < _size) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + } + } + + inStream.Release(); + outStream.Release(); + + if (hres != S_OK) + { + if (hres == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else if (hres == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + return hres; + } + + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/HandlerCont.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.h --- p7zip-rar-16.02/CPP/7zip/Archive/HandlerCont.h 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HandlerCont.h 2024-03-28 12:00:00.000000000 +0000 @@ -1,116 +1,134 @@ -// HandlerCont.h - -#ifndef __HANDLER_CONT_H -#define __HANDLER_CONT_H - -#include "../../Common/MyCom.h" - -#include "IArchive.h" - -namespace NArchive { - -#define INTERFACE_IInArchive_Cont(x) \ - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - - -class CHandlerCont: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ -protected: - CMyComPtr _stream; - - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0; - -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive_Cont(PURE) - - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY; - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - - // destructor must be virtual for this class - virtual ~CHandlerCont() {} -}; - - - -#define INTERFACE_IInArchive_Img(x) \ - /* STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - /* STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; */ \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - - -class CHandlerImg: - public IInStream, - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ -protected: - UInt64 _virtPos; - UInt64 _posInArc; - UInt64 _size; - CMyComPtr Stream; - const char *_imgExt; - - bool _stream_unavailData; - bool _stream_unsupportedMethod; - bool _stream_dataError; - // bool _stream_UsePackSize; - // UInt64 _stream_PackSize; - - void ClearStreamVars() - { - _stream_unavailData = false; - _stream_unsupportedMethod = false; - _stream_dataError = false; - // _stream_UsePackSize = false; - // _stream_PackSize = 0; - } - - - virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0; - virtual void CloseAtError(); -public: - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IInStream) - INTERFACE_IInArchive_Img(PURE) - - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback); - STDMETHOD(GetNumberOfItems)(UInt32 *numItems); - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback); - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) = 0; - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0; - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - CHandlerImg(); - // destructor must be virtual for this class - virtual ~CHandlerImg() {} -}; - - -HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); - -} - -#endif +// HandlerCont.h + +#ifndef ZIP7_INC_HANDLER_CONT_H +#define ZIP7_INC_HANDLER_CONT_H + +#include "../../Common/MyCom.h" + +#include "IArchive.h" + +namespace NArchive { + +#define Z7_IFACEM_IInArchive_Cont(x) \ + x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \ + x(Close()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + /* x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) */ \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + + +// #define Z7_COM7F_PUREO(f) virtual Z7_COM7F_IMF(f) Z7_override =0; +// #define Z7_COM7F_PUREO2(t, f) virtual Z7_COM7F_IMF2(t, f) Z7_override =0; + +class CHandlerCont: + public IInArchive, + public IInArchiveGetStream, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_2( + IInArchive, + IInArchiveGetStream) + /* + Z7_IFACEM_IInArchive_Cont(Z7_COM7F_PUREO) + // Z7_IFACE_COM7_PURE(IInArchive_Cont) + */ + Z7_COM7F_IMP(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) +protected: + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + + CMyComPtr _stream; + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0; + // destructor must be virtual for this class + virtual ~CHandlerCont() {} +}; + + + +#define Z7_IFACEM_IInArchive_Img(x) \ + /* x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) */ \ + x(Close()) \ + /* x(GetNumberOfItems(UInt32 *numItems)) */ \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + /* x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) */ \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + + +class CHandlerImg: + public IInArchive, + public IInArchiveGetStream, + public IInStream, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_4( + IInArchive, + IInArchiveGetStream, + ISequentialInStream, + IInStream) + + Z7_COM7F_IMP(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) + Z7_COM7F_IMP(GetNumberOfItems(UInt32 *numItems)) + Z7_COM7F_IMP(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) + Z7_IFACE_COM7_IMP(IInStream) + // Z7_IFACEM_IInArchive_Img(Z7_COM7F_PUREO) + +protected: + bool _stream_unavailData; + bool _stream_unsupportedMethod; + bool _stream_dataError; + // bool _stream_UsePackSize; + // UInt64 _stream_PackSize; + UInt64 _virtPos; + UInt64 _posInArc; + UInt64 _size; + CMyComPtr Stream; + const char *_imgExt; + + void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; } + void Reset_VirtPos() { _virtPos = (UInt64)0; } + + void ClearStreamVars() + { + _stream_unavailData = false; + _stream_unsupportedMethod = false; + _stream_dataError = false; + // _stream_UsePackSize = false; + // _stream_PackSize = 0; + } + + void Clear_HandlerImg_Vars(); // it doesn't Release (Stream) var. + + 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; + } + + CHandlerImg(); + // destructor must be virtual for this class + virtual ~CHandlerImg() {} +}; + + +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/HfsHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/HfsHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.cpp 2024-11-23 08:00:00.000000000 +0000 @@ -1,1880 +1,2626 @@ -// HfsHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/ZlibDecoder.h" - -/* if HFS_SHOW_ALT_STREAMS is defined, the handler will show attribute files - and resource forks. In most cases it looks useless. So we disable it. */ - -// #define HFS_SHOW_ALT_STREAMS - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -namespace NArchive { -namespace NHfs { - -static const char *kResFileName = "rsrc"; // "com.apple.ResourceFork"; - -struct CExtent -{ - UInt32 Pos; - UInt32 NumBlocks; -}; - -struct CIdExtents -{ - UInt32 ID; - UInt32 StartBlock; - CRecordVector Extents; -}; - -struct CFork -{ - UInt64 Size; - UInt32 NumBlocks; - // UInt32 ClumpSize; - CRecordVector Extents; - - CFork(): Size(0), NumBlocks(0) {} - - void Parse(const Byte *p); - - bool IsEmpty() const { return Size == 0 && NumBlocks == 0 && Extents.Size() == 0; } - - UInt32 Calc_NumBlocks_from_Extents() const; - bool Check_NumBlocks() const; - - bool Check_Size_with_NumBlocks(unsigned blockSizeLog) const - { - return Size <= ((UInt64)NumBlocks << blockSizeLog); - } - - bool IsOk(unsigned blockSizeLog) const - { - // we don't check cases with extra (empty) blocks in last extent - return Check_NumBlocks() && Check_Size_with_NumBlocks(blockSizeLog); - } - - bool Upgrade(const CObjectVector &items, UInt32 id); - bool UpgradeAndTest(const CObjectVector &items, UInt32 id, unsigned blockSizeLog) - { - if (!Upgrade(items, id)) - return false; - return IsOk(blockSizeLog); - } -}; - -static const unsigned kNumFixedExtents = 8; - -void CFork::Parse(const Byte *p) -{ - Extents.Clear(); - Size = Get64(p); - // ClumpSize = Get32(p + 8); - NumBlocks = Get32(p + 12); - p += 16; - for (unsigned i = 0; i < kNumFixedExtents; i++, p += 8) - { - CExtent e; - e.Pos = Get32(p); - e.NumBlocks = Get32(p + 4); - if (e.NumBlocks != 0) - Extents.Add(e); - } -} - -UInt32 CFork::Calc_NumBlocks_from_Extents() const -{ - UInt32 num = 0; - FOR_VECTOR (i, Extents) - { - num += Extents[i].NumBlocks; - } - return num; -} - -bool CFork::Check_NumBlocks() const -{ - UInt32 num = 0; - FOR_VECTOR (i, Extents) - { - UInt32 next = num + Extents[i].NumBlocks; - if (next < num) - return false; - num = next; - } - return num == NumBlocks; -} - -struct CIdIndexPair -{ - UInt32 ID; - int Index; - - int Compare(const CIdIndexPair &a) const; -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -int CIdIndexPair::Compare(const CIdIndexPair &a) const -{ - RINOZ(MyCompare(ID, a.ID)); - return MyCompare(Index, a.Index); -} - -static int FindItemIndex(const CRecordVector &items, UInt32 id) -{ - unsigned left = 0, right = items.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - UInt32 midVal = items[mid].ID; - if (id == midVal) - return items[mid].Index; - if (id < midVal) - right = mid; - else - left = mid + 1; - } - return -1; -} - -static int Find_in_IdExtents(const CObjectVector &items, UInt32 id) -{ - unsigned left = 0, right = items.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - UInt32 midVal = items[mid].ID; - if (id == midVal) - return mid; - if (id < midVal) - right = mid; - else - left = mid + 1; - } - return -1; -} - -bool CFork::Upgrade(const CObjectVector &items, UInt32 id) -{ - int index = Find_in_IdExtents(items, id); - if (index < 0) - return true; - const CIdExtents &item = items[index]; - if (Calc_NumBlocks_from_Extents() != item.StartBlock) - return false; - Extents += item.Extents; - return true; -} - - -struct CVolHeader -{ - Byte Header[2]; - UInt16 Version; - // UInt32 Attr; - // UInt32 LastMountedVersion; - // UInt32 JournalInfoBlock; - - UInt32 CTime; - UInt32 MTime; - // UInt32 BackupTime; - // UInt32 CheckedTime; - - UInt32 NumFiles; - UInt32 NumFolders; - unsigned BlockSizeLog; - UInt32 NumBlocks; - UInt32 NumFreeBlocks; - - // UInt32 WriteCount; - // UInt32 FinderInfo[8]; - // UInt64 VolID; - - UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; } - UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; } - bool IsHfsX() const { return Version > 4; } -}; - -inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) -{ - UInt64 v = ((UInt64)3600 * 24 * (365 * 303 + 24 * 3) + hfsTime) * 10000000; - ft.dwLowDateTime = (DWORD)v; - ft.dwHighDateTime = (DWORD)(v >> 32); -} - -enum ERecordType -{ - RECORD_TYPE_FOLDER = 1, - RECORD_TYPE_FILE, - RECORD_TYPE_FOLDER_THREAD, - RECORD_TYPE_FILE_THREAD -}; - -struct CItem -{ - UString Name; - - UInt32 ParentID; - - UInt16 Type; - UInt16 FileMode; - // UInt16 Flags; - // UInt32 Valence; - UInt32 ID; - UInt32 CTime; - UInt32 MTime; - // UInt32 AttrMTime; - UInt32 ATime; - // UInt32 BackupDate; - - /* - UInt32 OwnerID; - UInt32 GroupID; - Byte AdminFlags; - Byte OwnerFlags; - union - { - UInt32 iNodeNum; - UInt32 LinkCount; - UInt32 RawDevice; - } special; - - UInt32 FileType; - UInt32 FileCreator; - UInt16 FinderFlags; - UInt16 Point[2]; - */ - - CFork DataFork; - CFork ResourceFork; - - // for compressed attribute - UInt64 UnpackSize; - size_t DataPos; - UInt32 PackSize; - unsigned Method; - bool UseAttr; - bool UseInlineData; - - CItem(): UseAttr(false), UseInlineData(false) {} - bool IsDir() const { return Type == RECORD_TYPE_FOLDER; } - const CFork &GetFork(bool isResource) const { return (CFork & )*(isResource ? &ResourceFork: &DataFork ); } -}; - -struct CAttr -{ - UInt32 ID; - UInt32 Size; - size_t Pos; - UString Name; -}; - -struct CRef -{ - unsigned ItemIndex; - int AttrIndex; - int Parent; - bool IsResource; - - bool IsAltStream() const { return IsResource || AttrIndex >= 0; } - CRef(): AttrIndex(-1), Parent(-1), IsResource(false) {} -}; - -class CDatabase -{ - HRESULT ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream); - HRESULT LoadExtentFile(const CFork &fork, IInStream *inStream, CObjectVector *overflowExtentsArray); - HRESULT LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpenCallback *progress); - HRESULT LoadCatalog(const CFork &fork, const CObjectVector *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress); - bool Parse_decmpgfs(const CAttr &attr, CItem &item, bool &skip); -public: - CRecordVector Refs; - CObjectVector Items; - CObjectVector Attrs; - - CByteBuffer AttrBuf; - - CVolHeader Header; - bool HeadersError; - bool ThereAreAltStreams; - // bool CaseSensetive; - UString ResFileName; - - UInt64 PhySize; - - void Clear() - { - PhySize = 0; - HeadersError = false; - ThereAreAltStreams = false; - // CaseSensetive = false; - Refs.Clear(); - Items.Clear(); - Attrs.Clear(); - AttrBuf.Free(); - } - - UInt64 Get_UnpackSize_of_Ref(const CRef &ref) const - { - if (ref.AttrIndex >= 0) - return Attrs[ref.AttrIndex].Size; - const CItem &item = Items[ref.ItemIndex]; - if (item.IsDir()) - return 0; - if (item.UseAttr) - return item.UnpackSize; - return item.GetFork(ref.IsResource).Size; - } - - void GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path) const; - HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *progress); -}; - -enum -{ - kHfsID_Root = 1, - kHfsID_RootFolder = 2, - kHfsID_ExtentsFile = 3, - kHfsID_CatalogFile = 4, - kHfsID_BadBlockFile = 5, - kHfsID_AllocationFile = 6, - kHfsID_StartupFile = 7, - kHfsID_AttributesFile = 8, - kHfsID_RepairCatalogFile = 14, - kHfsID_BogusExtentFile = 15, - kHfsID_FirstUserCatalogNode = 16 -}; - -void CDatabase::GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path) const -{ - unsigned len = 0; - const unsigned kNumLevelsMax = (1 << 10); - int cur = index; - unsigned i; - - for (i = 0; i < kNumLevelsMax; i++) - { - const CRef &ref = Refs[cur]; - const UString *s; - - if (ref.IsResource) - s = &ResFileName; - else if (ref.AttrIndex >= 0) - s = &Attrs[ref.AttrIndex].Name; - else - s = &Items[ref.ItemIndex].Name; - - len += s->Len(); - len++; - cur = ref.Parent; - if (cur < 0) - break; - } - - len--; - wchar_t *p = path.AllocBstr(len); - p[len] = 0; - cur = index; - - for (;;) - { - const CRef &ref = Refs[cur]; - const UString *s; - wchar_t delimChar = L':'; - - if (ref.IsResource) - s = &ResFileName; - else if (ref.AttrIndex >= 0) - s = &Attrs[ref.AttrIndex].Name; - else - { - delimChar = WCHAR_PATH_SEPARATOR; - s = &Items[ref.ItemIndex].Name; - } - - unsigned curLen = s->Len(); - len -= curLen; - - const wchar_t *src = (const wchar_t *)*s; - wchar_t *dest = p + len; - for (unsigned j = 0; j < curLen; j++) - dest[j] = src[j]; - - if (len == 0) - break; - p[--len] = delimChar; - cur = ref.Parent; - } -} - -// Actually we read all blocks. It can be larger than fork.Size - -HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream) -{ - if (fork.NumBlocks >= Header.NumBlocks) - return S_FALSE; - size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; - if ((totalSize >> Header.BlockSizeLog) != fork.NumBlocks) - return S_FALSE; - buf.Alloc(totalSize); - UInt32 curBlock = 0; - FOR_VECTOR (i, fork.Extents) - { - if (curBlock >= fork.NumBlocks) - return S_FALSE; - const CExtent &e = fork.Extents[i]; - if (e.Pos > Header.NumBlocks || - e.NumBlocks > fork.NumBlocks - curBlock || - e.NumBlocks > Header.NumBlocks - e.Pos) - return S_FALSE; - RINOK(inStream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, - (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), - (size_t)e.NumBlocks << Header.BlockSizeLog)); - curBlock += e.NumBlocks; - } - return S_OK; -} - -static const unsigned kNodeDescriptor_Size = 14; - -struct CNodeDescriptor -{ - UInt32 fLink; - // UInt32 bLink; - Byte Kind; - // Byte Height; - unsigned NumRecords; - - bool CheckNumRecords(unsigned nodeSizeLog) - { - return (kNodeDescriptor_Size + ((UInt32)NumRecords + 1) * 2 <= ((UInt32)1 << nodeSizeLog)); - } - void Parse(const Byte *p); -}; - -void CNodeDescriptor::Parse(const Byte *p) -{ - fLink = Get32(p); - // bLink = Get32(p + 4); - Kind = p[8]; - // Height = p[9]; - NumRecords = Get16(p + 10); -} - -struct CHeaderRec -{ - // UInt16 TreeDepth; - // UInt32 RootNode; - // UInt32 LeafRecords; - UInt32 FirstLeafNode; - // UInt32 LastLeafNode; - unsigned NodeSizeLog; - // UInt16 MaxKeyLength; - UInt32 TotalNodes; - // UInt32 FreeNodes; - // UInt16 Reserved1; - // UInt32 ClumpSize; - // Byte BtreeType; - // Byte KeyCompareType; - // UInt32 Attributes; - // UInt32 Reserved3[16]; - - HRESULT Parse(const Byte *p); -}; - -HRESULT CHeaderRec::Parse(const Byte *p) -{ - // TreeDepth = Get16(p); - // RootNode = Get32(p + 2); - // LeafRecords = Get32(p + 6); - FirstLeafNode = Get32(p + 0xA); - // LastLeafNode = Get32(p + 0xE); - UInt32 nodeSize = Get16(p + 0x12); - - unsigned i; - for (i = 9; ((UInt32)1 << i) != nodeSize; i++) - if (i == 16) - return S_FALSE; - NodeSizeLog = i; - - // MaxKeyLength = Get16(p + 0x14); - TotalNodes = Get32(p + 0x16); - // FreeNodes = Get32(p + 0x1A); - // Reserved1 = Get16(p + 0x1E); - // ClumpSize = Get32(p + 0x20); - // BtreeType = p[0x24]; - // KeyCompareType = p[0x25]; - // Attributes = Get32(p + 0x26); - /* - for (int i = 0; i < 16; i++) - Reserved3[i] = Get32(p + 0x2A + i * 4); - */ - return S_OK; -} - - -static const Byte kNodeType_Leaf = 0xFF; -// static const Byte kNodeType_Index = 0; -// static const Byte kNodeType_Header = 1; -// static const Byte kNodeType_Mode = 2; - -static const Byte kExtentForkType_Data = 0; -static const Byte kExtentForkType_Resource = 0xFF; - -/* It loads data extents from Extents Overflow File - Most dmg installers are not fragmented. So there are no extents in Overflow File. */ - -HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjectVector *overflowExtentsArray) -{ - if (fork.NumBlocks == 0) - return S_OK; - CByteBuffer buf; - RINOK(ReadFile(fork, buf, inStream)); - const Byte *p = (const Byte *)buf; - - // CNodeDescriptor nodeDesc; - // nodeDesc.Parse(p); - CHeaderRec hr; - RINOK(hr.Parse(p + kNodeDescriptor_Size)); - - if ((buf.Size() >> hr.NodeSizeLog) < hr.TotalNodes) - return S_FALSE; - - UInt32 node = hr.FirstLeafNode; - if (node == 0) - return S_OK; - - CByteBuffer usedBuf(hr.TotalNodes); - memset(usedBuf, 0, hr.TotalNodes); - - while (node != 0) - { - if (node >= hr.TotalNodes || usedBuf[node] != 0) - return S_FALSE; - usedBuf[node] = 1; - - size_t nodeOffset = (size_t)node << hr.NodeSizeLog; - CNodeDescriptor desc; - desc.Parse(p + nodeOffset); - if (!desc.CheckNumRecords(hr.NodeSizeLog)) - return S_FALSE; - if (desc.Kind != kNodeType_Leaf) - return S_FALSE; - - UInt32 endBlock = 0; - - for (unsigned i = 0; i < desc.NumRecords; i++) - { - UInt32 nodeSize = (UInt32)1 << hr.NodeSizeLog; - UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2); - UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2); - if (offs > nodeSize || offsNext > nodeSize) - return S_FALSE; - UInt32 recSize = offsNext - offs; - const unsigned kKeyLen = 10; - - if (recSize != 2 + kKeyLen + kNumFixedExtents * 8) - return S_FALSE; - - const Byte *r = p + nodeOffset + offs; - if (Get16(r) != kKeyLen) - return S_FALSE; - - Byte forkType = r[2]; - unsigned forkTypeIndex; - if (forkType == kExtentForkType_Data) - forkTypeIndex = 0; - else if (forkType == kExtentForkType_Resource) - forkTypeIndex = 1; - else - continue; - CObjectVector &overflowExtents = overflowExtentsArray[forkTypeIndex]; - - UInt32 id = Get32(r + 4); - UInt32 startBlock = Get32(r + 8); - r += 2 + kKeyLen; - - bool needNew = true; - - if (overflowExtents.Size() != 0) - { - CIdExtents &e = overflowExtents.Back(); - if (e.ID == id) - { - if (endBlock != startBlock) - return S_FALSE; - needNew = false; - } - } - - if (needNew) - { - CIdExtents &e = overflowExtents.AddNew(); - e.ID = id; - e.StartBlock = startBlock; - endBlock = startBlock; - } - - CIdExtents &e = overflowExtents.Back(); - - for (unsigned k = 0; k < kNumFixedExtents; k++, r += 8) - { - CExtent ee; - ee.Pos = Get32(r); - ee.NumBlocks = Get32(r + 4); - if (ee.NumBlocks != 0) - { - e.Extents.Add(ee); - endBlock += ee.NumBlocks; - } - } - } - - node = desc.fLink; - } - return S_OK; -} - -static void LoadName(const Byte *data, unsigned len, UString &dest) -{ - wchar_t *p = dest.GetBuf(len); - unsigned i; - for (i = 0; i < len; i++) - { - wchar_t c = Get16(data + i * 2); - if (c == 0) - break; - p[i] = c; - } - p[i] = 0; - dest.ReleaseBuf_SetLen(i); -} - -static bool IsNameEqualTo(const Byte *data, const char *name) -{ - for (unsigned i = 0;; i++) - { - char c = name[i]; - if (c == 0) - return true; - if (Get16(data + i * 2) != (Byte)c) - return false; - } -} - -static const UInt32 kAttrRecordType_Inline = 0x10; -// static const UInt32 kAttrRecordType_Fork = 0x20; -// static const UInt32 kAttrRecordType_Extents = 0x30; - -HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpenCallback *progress) -{ - if (fork.NumBlocks == 0) - return S_OK; - - RINOK(ReadFile(fork, AttrBuf, inStream)); - const Byte *p = (const Byte *)AttrBuf; - - // CNodeDescriptor nodeDesc; - // nodeDesc.Parse(p); - CHeaderRec hr; - RINOK(hr.Parse(p + kNodeDescriptor_Size)); - - // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); - - if ((AttrBuf.Size() >> hr.NodeSizeLog) < hr.TotalNodes) - return S_FALSE; - - UInt32 node = hr.FirstLeafNode; - if (node == 0) - return S_OK; - - CByteBuffer usedBuf(hr.TotalNodes); - memset(usedBuf, 0, hr.TotalNodes); - - CFork resFork; - - while (node != 0) - { - if (node >= hr.TotalNodes || usedBuf[node] != 0) - return S_FALSE; - usedBuf[node] = 1; - - size_t nodeOffset = (size_t)node << hr.NodeSizeLog; - CNodeDescriptor desc; - desc.Parse(p + nodeOffset); - if (!desc.CheckNumRecords(hr.NodeSizeLog)) - return S_FALSE; - if (desc.Kind != kNodeType_Leaf) - return S_FALSE; - - for (unsigned i = 0; i < desc.NumRecords; i++) - { - UInt32 nodeSize = (1 << hr.NodeSizeLog); - UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2); - UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2); - UInt32 recSize = offsNext - offs; - if (offs >= nodeSize - || offsNext >= nodeSize - || offsNext < offs) - return S_FALSE; - - const unsigned kHeadSize = 14; - if (recSize < kHeadSize) - return S_FALSE; - - const Byte *r = p + nodeOffset + offs; - UInt32 keyLen = Get16(r); - - // UInt16 pad = Get16(r + 2); - UInt32 fileID = Get32(r + 4); - unsigned startBlock = Get32(r + 8); - if (startBlock != 0) - { - // that case is still unsupported - HeadersError = true; - continue; - } - unsigned nameLen = Get16(r + 12); - - if (keyLen + 2 > recSize || - keyLen != kHeadSize - 2 + nameLen * 2) - return S_FALSE; - r += kHeadSize; - recSize -= kHeadSize; - - const Byte *name = r; - r += nameLen * 2; - recSize -= nameLen * 2; - - if (recSize < 4) - return S_FALSE; - - UInt32 recordType = Get32(r); - if (recordType != kAttrRecordType_Inline) - { - // Probably only kAttrRecordType_Inline now is used in real HFS files - HeadersError = true; - continue; - } - - const UInt32 kRecordHeaderSize = 16; - if (recSize < kRecordHeaderSize) - return S_FALSE; - UInt32 dataSize = Get32(r + 12); - - r += kRecordHeaderSize; - recSize -= kRecordHeaderSize; - - if (recSize < dataSize) - return S_FALSE; - - CAttr &attr = Attrs.AddNew(); - attr.ID = fileID; - attr.Pos = nodeOffset + offs + 2 + keyLen + kRecordHeaderSize; - attr.Size = dataSize; - LoadName(name, nameLen, attr.Name); - - if (progress && (i & 0xFFF) == 0) - { - UInt64 numFiles = 0; - RINOK(progress->SetCompleted(&numFiles, NULL)); - } - } - - node = desc.fLink; - } - return S_OK; -} - -static const UInt32 kMethod_Attr = 3; // data stored in attribute file -static const UInt32 kMethod_Resource = 4; // data stored in resource fork - -bool CDatabase::Parse_decmpgfs(const CAttr &attr, CItem &item, bool &skip) -{ - skip = false; - if (!attr.Name.IsEqualTo("com.apple.decmpfs")) - return true; - if (item.UseAttr || !item.DataFork.IsEmpty()) - return false; - - const UInt32 k_decmpfs_headerSize = 16; - UInt32 dataSize = attr.Size; - if (dataSize < k_decmpfs_headerSize) - return false; - const Byte *r = AttrBuf + attr.Pos; - if (GetUi32(r) != 0x636D7066) // magic == "fpmc" - return false; - item.Method = GetUi32(r + 4); - item.UnpackSize = GetUi64(r + 8); - dataSize -= k_decmpfs_headerSize; - r += k_decmpfs_headerSize; - if (item.Method == kMethod_Resource) - { - if (dataSize != 0) - return false; - item.UseAttr = true; - } - else if (item.Method == kMethod_Attr) - { - if (dataSize == 0) - return false; - Byte b = r[0]; - if ((b & 0xF) == 0xF) - { - dataSize--; - if (item.UnpackSize > dataSize) - return false; - item.DataPos = attr.Pos + k_decmpfs_headerSize + 1; - item.PackSize = dataSize; - item.UseAttr = true; - item.UseInlineData = true; - } - else - { - item.DataPos = attr.Pos + k_decmpfs_headerSize; - item.PackSize = dataSize; - item.UseAttr = true; - } - } - else - return false; - skip = true; - return true; -} - -HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress) -{ - unsigned reserveSize = (unsigned)(Header.NumFolders + 1 + Header.NumFiles); - Items.ClearAndReserve(reserveSize); - Refs.ClearAndReserve(reserveSize); - - CRecordVector IdToIndexMap; - IdToIndexMap.ClearAndReserve(reserveSize); - - CByteBuffer buf; - RINOK(ReadFile(fork, buf, inStream)); - const Byte *p = (const Byte *)buf; - - // CNodeDescriptor nodeDesc; - // nodeDesc.Parse(p); - CHeaderRec hr; - RINOK(hr.Parse(p + kNodeDescriptor_Size)); - - // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); - - if ((buf.Size() >> hr.NodeSizeLog) < hr.TotalNodes) - return S_FALSE; - - CByteBuffer usedBuf(hr.TotalNodes); - memset(usedBuf, 0, hr.TotalNodes); - - CFork resFork; - - UInt32 node = hr.FirstLeafNode; - UInt32 numFiles = 0; - UInt32 numFolders = 0; - - while (node != 0) - { - if (node >= hr.TotalNodes || usedBuf[node] != 0) - return S_FALSE; - usedBuf[node] = 1; - - size_t nodeOffset = (size_t)node << hr.NodeSizeLog; - CNodeDescriptor desc; - desc.Parse(p + nodeOffset); - if (!desc.CheckNumRecords(hr.NodeSizeLog)) - return S_FALSE; - if (desc.Kind != kNodeType_Leaf) - return S_FALSE; - - for (unsigned i = 0; i < desc.NumRecords; i++) - { - UInt32 nodeSize = (1 << hr.NodeSizeLog); - UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2); - UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2); - UInt32 recSize = offsNext - offs; - if (offs >= nodeSize - || offs >= nodeSize - || offsNext < offs - || recSize < 6) - return S_FALSE; - - const Byte *r = p + nodeOffset + offs; - UInt32 keyLen = Get16(r); - UInt32 parentID = Get32(r + 2); - if (keyLen < 6 || (keyLen & 1) != 0 || keyLen + 2 > recSize) - return S_FALSE; - r += 6; - recSize -= 6; - keyLen -= 6; - - unsigned nameLen = Get16(r); - if (nameLen * 2 != (unsigned)keyLen) - return S_FALSE; - r += 2; - recSize -= 2; - - r += nameLen * 2; - recSize -= nameLen * 2; - - if (recSize < 2) - return S_FALSE; - UInt16 type = Get16(r); - - if (type != RECORD_TYPE_FOLDER && - type != RECORD_TYPE_FILE) - continue; - - const unsigned kBasicRecSize = 0x58; - if (recSize < kBasicRecSize) - return S_FALSE; - - CItem &item = Items.AddNew(); - item.ParentID = parentID; - item.Type = type; - // item.Flags = Get16(r + 2); - // item.Valence = Get32(r + 4); - item.ID = Get32(r + 8); - { - const Byte *name = r - (nameLen * 2); - LoadName(name, nameLen, item.Name); - if (item.Name.Len() <= 1) - { - if (item.Name.IsEmpty() && nameLen == 21) - { - if (GetUi32(name) == 0 && - GetUi32(name + 4) == 0 && - IsNameEqualTo(name + 8, "HFS+ Private Data")) - { - // it's folder for "Hard Links" files - item.Name.SetFromAscii("[HFS+ Private Data]"); - } - } - - // Some dmg files have ' ' folder item. - if (item.Name.IsEmpty() || item.Name[0] == L' ') - item.Name.SetFromAscii("[]"); - } - } - - item.CTime = Get32(r + 0xC); - item.MTime = Get32(r + 0x10); - // item.AttrMTime = Get32(r + 0x14); - item.ATime = Get32(r + 0x18); - // item.BackupDate = Get32(r + 0x1C); - - /* - item.OwnerID = Get32(r + 0x20); - item.GroupID = Get32(r + 0x24); - item.AdminFlags = r[0x28]; - item.OwnerFlags = r[0x29]; - */ - item.FileMode = Get16(r + 0x2A); - /* - item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount - item.FileType = Get32(r + 0x30); - item.FileCreator = Get32(r + 0x34); - item.FinderFlags = Get16(r + 0x38); - item.Point[0] = Get16(r + 0x3A); // v - item.Point[1] = Get16(r + 0x3C); // h - */ - - // const refIndex = Refs.Size(); - CIdIndexPair pair; - pair.ID = item.ID; - pair.Index = Items.Size() - 1; - IdToIndexMap.Add(pair); - - recSize -= kBasicRecSize; - r += kBasicRecSize; - if (item.IsDir()) - { - numFolders++; - if (recSize != 0) - return S_FALSE; - } - else - { - numFiles++; - const unsigned kForkRecSize = 16 + kNumFixedExtents * 8; - if (recSize != kForkRecSize * 2) - return S_FALSE; - - item.DataFork.Parse(r); - - if (!item.DataFork.UpgradeAndTest(overflowExtentsArray[0], item.ID, Header.BlockSizeLog)) - HeadersError = true; - - item.ResourceFork.Parse(r + kForkRecSize); - if (!item.ResourceFork.IsEmpty()) - { - if (!item.ResourceFork.UpgradeAndTest(overflowExtentsArray[1], item.ID, Header.BlockSizeLog)) - HeadersError = true; - ThereAreAltStreams = true; - } - } - if (progress && (Items.Size() & 0xFFF) == 0) - { - UInt64 numItems = Items.Size(); - RINOK(progress->SetCompleted(&numItems, NULL)); - } - } - node = desc.fLink; - } - - if (Header.NumFiles != numFiles || - Header.NumFolders + 1 != numFolders) - HeadersError = true; - - IdToIndexMap.Sort2(); - { - for (unsigned i = 1; i < IdToIndexMap.Size(); i++) - if (IdToIndexMap[i - 1].ID == IdToIndexMap[i].ID) - return S_FALSE; - } - - - CBoolArr skipAttr(Attrs.Size()); - { - for (unsigned i = 0; i < Attrs.Size(); i++) - skipAttr[i] = false; - } - - { - FOR_VECTOR (i, Attrs) - { - const CAttr &attr = Attrs[i]; - - int itemIndex = FindItemIndex(IdToIndexMap, attr.ID); - if (itemIndex < 0) - { - HeadersError = true; - continue; - } - if (!Parse_decmpgfs(attr, Items[itemIndex], skipAttr[i])) - HeadersError = true; - } - } - - IdToIndexMap.ClearAndReserve(Items.Size()); - - { - FOR_VECTOR (i, Items) - { - const CItem &item = Items[i]; - - CIdIndexPair pair; - pair.ID = item.ID; - pair.Index = Refs.Size(); - IdToIndexMap.Add(pair); - - CRef ref; - ref.ItemIndex = i; - Refs.Add(ref); - - #ifdef HFS_SHOW_ALT_STREAMS - - if (item.ResourceFork.IsEmpty()) - continue; - if (item.UseAttr && item.Method == kMethod_Resource) - continue; - CRef resRef; - resRef.ItemIndex = i; - resRef.IsResource = true; - resRef.Parent = Refs.Size() - 1; - Refs.Add(resRef); - - #endif - } - } - - IdToIndexMap.Sort2(); - - { - FOR_VECTOR (i, Refs) - { - CRef &ref = Refs[i]; - if (ref.IsResource) - continue; - CItem &item = Items[ref.ItemIndex]; - ref.Parent = FindItemIndex(IdToIndexMap, item.ParentID); - if (ref.Parent >= 0) - { - if (!Items[Refs[ref.Parent].ItemIndex].IsDir()) - { - ref.Parent = -1; - HeadersError = true; - } - } - } - } - - #ifdef HFS_SHOW_ALT_STREAMS - { - FOR_VECTOR (i, Attrs) - { - if (skipAttr[i]) - continue; - const CAttr &attr = Attrs[i]; - - int refIndex = FindItemIndex(IdToIndexMap, attr.ID); - if (refIndex < 0) - { - HeadersError = true; - continue; - } - - CRef ref; - ref.AttrIndex = i; - ref.Parent = refIndex; - ref.ItemIndex = Refs[refIndex].ItemIndex; - Refs.Add(ref); - } - } - #endif - - return S_OK; -} - -static const unsigned kHeaderPadSize = (1 << 10); - -HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) -{ - Clear(); - static const unsigned kHeaderSize = kHeaderPadSize + 512; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); - { - for (unsigned i = 0; i < kHeaderPadSize; i++) - if (buf[i] != 0) - return S_FALSE; - } - const Byte *p = buf + kHeaderPadSize; - CVolHeader &h = Header; - - h.Header[0] = p[0]; - h.Header[1] = p[1]; - if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) - return S_FALSE; - h.Version = Get16(p + 2); - if (h.Version < 4 || h.Version > 5) - return S_FALSE; - - // h.Attr = Get32(p + 4); - // h.LastMountedVersion = Get32(p + 8); - // h.JournalInfoBlock = Get32(p + 0xC); - - h.CTime = Get32(p + 0x10); - h.MTime = Get32(p + 0x14); - // h.BackupTime = Get32(p + 0x18); - // h.CheckedTime = Get32(p + 0x1C); - - h.NumFiles = Get32(p + 0x20); - h.NumFolders = Get32(p + 0x24); - - if (h.NumFolders > ((UInt32)1 << 29) || - h.NumFiles > ((UInt32)1 << 30)) - return S_FALSE; - if (progress) - { - UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; - RINOK(progress->SetTotal(&numFiles, NULL)); - } - - UInt32 blockSize = Get32(p + 0x28); - - { - unsigned i; - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i == 31) - return S_FALSE; - h.BlockSizeLog = i; - } - - h.NumBlocks = Get32(p + 0x2C); - h.NumFreeBlocks = Get32(p + 0x30); - - /* - h.NextCalatlogNodeID = Get32(p + 0x40); - h.WriteCount = Get32(p + 0x44); - for (i = 0; i < 6; i++) - h.FinderInfo[i] = Get32(p + 0x50 + i * 4); - h.VolID = Get64(p + 0x68); - */ - - /* - UInt64 endPos; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - if ((endPos >> h.BlockSizeLog) < h.NumBlocks) - return S_FALSE; - */ - - ResFileName.SetFromAscii(kResFileName); - - CFork extentsFork, catalogFork, attrFork; - // allocationFork.Parse(p + 0x70 + 0x50 * 0); - extentsFork.Parse(p + 0x70 + 0x50 * 1); - catalogFork.Parse(p + 0x70 + 0x50 * 2); - attrFork.Parse (p + 0x70 + 0x50 * 3); - // startupFork.Parse(p + 0x70 + 0x50 * 4); - - CObjectVector overflowExtents[2]; - if (!extentsFork.IsOk(Header.BlockSizeLog)) - HeadersError = true; - else - { - HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); - if (res == S_FALSE) - HeadersError = true; - else if (res != S_OK) - return res; - } - - if (!catalogFork.UpgradeAndTest(overflowExtents[0], kHfsID_CatalogFile, Header.BlockSizeLog)) - return S_FALSE; - - if (!attrFork.UpgradeAndTest(overflowExtents[0], kHfsID_AttributesFile, Header.BlockSizeLog)) - HeadersError = true; - else - { - if (attrFork.Size != 0) - RINOK(LoadAttrs(attrFork, inStream, progress)); - } - - RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)); - - PhySize = Header.GetPhySize(); - return S_OK; -} - - - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IInArchiveGetStream, - public CMyUnknownImp, - public CDatabase -{ - CMyComPtr _stream; - - HRESULT GetForkStream(const CFork &fork, ISequentialInStream **stream); - - HRESULT ExtractZlibFile( - ISequentialOutStream *realOutStream, - const CItem &item, - NCompress::NZlib::CDecoder *_zlibDecoderSpec, - CByteBuffer &buf, - UInt64 progressStart, - IArchiveExtractCallback *extractCallback); -public: - MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidCTime, - kpidMTime, - kpidATime, - kpidPosixAttrib -}; - -static const Byte kArcProps[] = -{ - kpidMethod, - kpidClusterSize, - kpidFreeSpace, - kpidCTime, - kpidMTime -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static void HfsTimeToProp(UInt32 hfsTime, NWindows::NCOM::CPropVariant &prop) -{ - FILETIME ft; - HfsTimeToFileTime(hfsTime, ft); - prop = ft; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break; - case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break; - case kpidPhySize: prop = PhySize; break; - case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break; - case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break; - case kpidMTime: HfsTimeToProp(Header.MTime, prop); break; - case kpidCTime: - { - FILETIME localFt, ft; - HfsTimeToFileTime(Header.CTime, localFt); - if (LocalFileTimeToFileTime(&localFt, &ft)) - prop = ft; - break; - } - case kpidIsTree: prop = true; break; - case kpidErrorFlags: - { - UInt32 flags = 0; - if (HeadersError) flags |= kpv_ErrorFlags_HeadersError; - if (flags != 0) - prop = flags; - break; - } - case kpidIsAltStream: prop = ThereAreAltStreams; break; - } - 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) -{ - const CRef &ref = Refs[index]; - *parentType = ref.IsAltStream() ? - NParentType::kAltStream : - NParentType::kDir; - *parent = (UInt32)(Int32)ref.Parent; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - #ifdef MY_CPU_LE - if (propID == kpidName) - { - const CRef &ref = Refs[index]; - const UString *s; - if (ref.IsResource) - s = &ResFileName; - else if (ref.AttrIndex >= 0) - s = &Attrs[ref.AttrIndex].Name; - else - s = &Items[ref.ItemIndex].Name; - *data = (const wchar_t *)(*s); - *dataSize = (s->Len() + 1) * sizeof(wchar_t); - *propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE; - return S_OK; - } - #endif - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CRef &ref = Refs[index]; - const CItem &item = Items[ref.ItemIndex]; - switch (propID) - { - case kpidPath: GetItemPath(index, prop); break; - case kpidName: - const UString *s; - if (ref.IsResource) - s = &ResFileName; - else if (ref.AttrIndex >= 0) - s = &Attrs[ref.AttrIndex].Name; - else - s = &item.Name; - prop = *s; - break; - case kpidPackSize: - { - UInt64 size; - if (ref.AttrIndex >= 0) - size = Attrs[ref.AttrIndex].Size; - else if (item.IsDir()) - break; - else if (item.UseAttr) - { - if (item.Method == kMethod_Resource) - size = item.ResourceFork.NumBlocks << Header.BlockSizeLog; - else - size = item.PackSize; - } - else - size = item.GetFork(ref.IsResource).NumBlocks << Header.BlockSizeLog; - prop = size; - break; - } - case kpidSize: - { - UInt64 size; - if (ref.AttrIndex >= 0) - size = Attrs[ref.AttrIndex].Size; - else if (item.IsDir()) - break; - else if (item.UseAttr) - size = item.UnpackSize; - else - size = item.GetFork(ref.IsResource).Size; - prop = size; - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidIsAltStream: prop = ref.IsAltStream(); break; - - case kpidCTime: HfsTimeToProp(item.CTime, prop); break; - case kpidMTime: HfsTimeToProp(item.MTime, prop); break; - case kpidATime: HfsTimeToProp(item.ATime, prop); break; - - case kpidPosixAttrib: if (ref.AttrIndex < 0) prop = (UInt32)item.FileMode; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(inStream, callback)); - _stream = inStream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _stream.Release(); - Clear(); - return S_OK; -} - -static const UInt32 kCompressionBlockSize = 1 << 16; - -HRESULT CHandler::ExtractZlibFile( - ISequentialOutStream *outStream, - const CItem &item, - NCompress::NZlib::CDecoder *_zlibDecoderSpec, - CByteBuffer &buf, - UInt64 progressStart, - IArchiveExtractCallback *extractCallback) -{ - CMyComPtr inStream; - const CFork &fork = item.ResourceFork; - RINOK(GetForkStream(fork, &inStream)); - const unsigned kHeaderSize = 0x100 + 8; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); - UInt32 dataPos = Get32(buf); - UInt32 mapPos = Get32(buf + 4); - UInt32 dataSize = Get32(buf + 8); - UInt32 mapSize = Get32(buf + 12); - - const UInt32 kResMapSize = 50; - - if (mapSize != kResMapSize - || dataPos + dataSize != mapPos - || mapPos + mapSize != fork.Size) - return S_FALSE; - - UInt32 dataSize2 = Get32(buf + 0x100); - if (4 + dataSize2 != dataSize || dataSize2 < 8) - return S_FALSE; - - UInt32 numBlocks = GetUi32(buf + 0x100 + 4); - if (((dataSize2 - 4) >> 3) < numBlocks) - return S_FALSE; - if (item.UnpackSize > (UInt64)numBlocks * kCompressionBlockSize) - return S_FALSE; - - if (item.UnpackSize + kCompressionBlockSize < (UInt64)numBlocks * kCompressionBlockSize) - return S_FALSE; - - UInt32 tableSize = (numBlocks << 3); - - CByteBuffer tableBuf(tableSize); - - RINOK(ReadStream_FALSE(inStream, tableBuf, tableSize)); - - UInt32 prev = 4 + tableSize; - - UInt32 i; - for (i = 0; i < numBlocks; i++) - { - UInt32 offset = GetUi32(tableBuf + i * 8); - UInt32 size = GetUi32(tableBuf + i * 8 + 4); - if (size == 0) - return S_FALSE; - if (prev != offset) - return S_FALSE; - if (offset > dataSize2 || - size > dataSize2 - offset) - return S_FALSE; - prev = offset + size; - } - - if (prev != dataSize2) - return S_FALSE; - - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - - UInt64 outPos = 0; - for (i = 0; i < numBlocks; i++) - { - UInt64 rem = item.UnpackSize - outPos; - if (rem == 0) - return S_FALSE; - UInt32 blockSize = kCompressionBlockSize; - if (rem < kCompressionBlockSize) - blockSize = (UInt32)rem; - - UInt32 size = GetUi32(tableBuf + i * 8 + 4); - - if (size > buf.Size() || size > kCompressionBlockSize + 1) - return S_FALSE; - - RINOK(ReadStream_FALSE(inStream, buf, size)); - - if ((buf[0] & 0xF) == 0xF) - { - // that code was not tested. Are there HFS archives with uncompressed block - if (size - 1 != blockSize) - return S_FALSE; - - if (outStream) - { - RINOK(WriteStream(outStream, buf, blockSize)); - } - } - else - { - UInt64 blockSize64 = blockSize; - bufInStreamSpec->Init(buf, size); - RINOK(_zlibDecoderSpec->Code(bufInStream, outStream, NULL, &blockSize64, NULL)); - if (_zlibDecoderSpec->GetOutputProcessedSize() != blockSize || - _zlibDecoderSpec->GetInputProcessedSize() != size) - return S_FALSE; - } - - outPos += blockSize; - UInt64 progressPos = progressStart + outPos; - RINOK(extractCallback->SetCompleted(&progressPos)); - } - - if (outPos != item.UnpackSize) - return S_FALSE; - - /* We check Resource Map - Are there HFS files with another values in Resource Map ??? */ - - RINOK(ReadStream_FALSE(inStream, buf, mapSize)); - UInt32 types = Get16(buf + 24); - UInt32 names = Get16(buf + 26); - UInt32 numTypes = Get16(buf + 28); - if (numTypes != 0 || types != 28 || names != kResMapSize) - return S_FALSE; - UInt32 resType = Get32(buf + 30); - UInt32 numResources = Get16(buf + 34); - UInt32 resListOffset = Get16(buf + 36); - if (resType != 0x636D7066) // cmpf - return S_FALSE; - if (numResources != 0 || resListOffset != 10) - return S_FALSE; - - UInt32 entryId = Get16(buf + 38); - UInt32 nameOffset = Get16(buf + 40); - // Byte attrib = buf[42]; - UInt32 resourceOffset = Get32(buf + 42) & 0xFFFFFF; - if (entryId != 1 || nameOffset != 0xFFFF || resourceOffset != 0) - return S_FALSE; - - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = Refs.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) - { - const CRef &ref = Refs[allFilesMode ? i : indices[i]]; - totalSize += Get_UnpackSize_of_Ref(ref); - } - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 currentTotalSize = 0, currentItemSize = 0; - - const size_t kBufSize = kCompressionBlockSize; - CByteBuffer buf(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header - - NCompress::NZlib::CDecoder *_zlibDecoderSpec = NULL; - CMyComPtr _zlibDecoder; - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - RINOK(extractCallback->SetCompleted(¤tTotalSize)); - UInt32 index = allFilesMode ? i : indices[i]; - const CRef &ref = Refs[index]; - const CItem &item = Items[ref.ItemIndex]; - currentItemSize = Get_UnpackSize_of_Ref(ref); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (ref.AttrIndex < 0 && item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - UInt64 pos = 0; - int res = NExtract::NOperationResult::kDataError; - if (ref.AttrIndex >= 0) - { - res = NExtract::NOperationResult::kOK; - if (realOutStream) - { - const CAttr &attr = Attrs[ref.AttrIndex]; - RINOK(WriteStream(realOutStream, AttrBuf + attr.Pos, attr.Size)); - } - } - else if (item.UseAttr) - { - if (item.UseInlineData) - { - res = NExtract::NOperationResult::kOK; - if (realOutStream) - { - RINOK(WriteStream(realOutStream, AttrBuf + item.DataPos, (size_t)item.UnpackSize)); - } - } - else - { - if (!_zlibDecoder) - { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); - _zlibDecoder = _zlibDecoderSpec; - } - - if (item.Method == kMethod_Attr) - { - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - bufInStreamSpec->Init(AttrBuf + item.DataPos, item.PackSize); - - HRESULT hres = _zlibDecoder->Code(bufInStream, realOutStream, NULL, &item.UnpackSize, NULL); - if (hres != S_FALSE) - { - if (hres != S_OK) - return hres; - if (_zlibDecoderSpec->GetOutputProcessedSize() == item.UnpackSize && - _zlibDecoderSpec->GetInputProcessedSize() == item.PackSize) - res = NExtract::NOperationResult::kOK; - } - } - else - { - HRESULT hres = ExtractZlibFile(realOutStream, item, _zlibDecoderSpec, buf, - currentTotalSize, extractCallback); - if (hres != S_FALSE) - { - if (hres != S_OK) - return hres; - res = NExtract::NOperationResult::kOK; - } - } - } - } - else - { - const CFork &fork = item.GetFork(ref.IsResource); - if (fork.IsOk(Header.BlockSizeLog)) - { - res = NExtract::NOperationResult::kOK; - unsigned extentIndex; - for (extentIndex = 0; extentIndex < fork.Extents.Size(); extentIndex++) - { - if (res != NExtract::NOperationResult::kOK) - break; - if (fork.Size == pos) - break; - const CExtent &e = fork.Extents[extentIndex]; - RINOK(_stream->Seek((UInt64)e.Pos << Header.BlockSizeLog, STREAM_SEEK_SET, NULL)); - UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog; - while (extentRem != 0) - { - UInt64 rem = fork.Size - pos; - if (rem == 0) - { - // Here we check that there are no extra (empty) blocks in last extent. - if (extentRem >= ((UInt64)1 << Header.BlockSizeLog)) - res = NExtract::NOperationResult::kDataError; - break; - } - size_t cur = kBufSize; - if (cur > rem) - cur = (size_t)rem; - if (cur > extentRem) - cur = (size_t)extentRem; - RINOK(ReadStream(_stream, buf, &cur)); - if (cur == 0) - { - res = NExtract::NOperationResult::kDataError; - break; - } - if (realOutStream) - { - RINOK(WriteStream(realOutStream, buf, cur)); - } - pos += cur; - extentRem -= cur; - UInt64 processed = currentTotalSize + pos; - RINOK(extractCallback->SetCompleted(&processed)); - } - } - if (extentIndex != fork.Extents.Size() || fork.Size != pos) - res = NExtract::NOperationResult::kDataError; - } - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = Refs.Size(); - return S_OK; -} - -HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream) -{ - *stream = 0; - - if (!fork.IsOk(Header.BlockSizeLog)) - return S_FALSE; - - CExtentsStream *extentStreamSpec = new CExtentsStream(); - CMyComPtr extentStream = extentStreamSpec; - - UInt64 rem = fork.Size; - UInt64 virt = 0; - - FOR_VECTOR (i, fork.Extents) - { - const CExtent &e = fork.Extents[i]; - if (e.NumBlocks == 0) - continue; - UInt64 cur = ((UInt64)e.NumBlocks << Header.BlockSizeLog); - if (cur > rem) - { - cur = rem; - if (i != fork.Extents.Size() - 1) - return S_FALSE; - } - CSeekExtent se; - se.Phy = (UInt64)e.Pos << Header.BlockSizeLog; - se.Virt = virt; - virt += cur; - rem -= cur; - extentStreamSpec->Extents.Add(se); - } - - if (rem != 0) - return S_FALSE; - - CSeekExtent se; - se.Phy = 0; - se.Virt = virt; - extentStreamSpec->Extents.Add(se); - extentStreamSpec->Stream = _stream; - extentStreamSpec->Init(); - *stream = extentStream.Detach(); - return S_OK; -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - *stream = 0; - - const CRef &ref = Refs[index]; - if (ref.AttrIndex >= 0) - return S_FALSE; - const CItem &item = Items[ref.ItemIndex]; - if (item.IsDir() || item.UseAttr) - return S_FALSE; - - return GetForkStream(item.GetFork(ref.IsResource), stream); -} - -static const Byte k_Signature[] = { - 4, 'H', '+', 0, 4, - 4, 'H', 'X', 0, 5 }; - -REGISTER_ARC_I( - "HFS", "hfs hfsx", 0, 0xE3, - k_Signature, - kHeaderPadSize, - NArcInfoFlags::kMultiSignature, - NULL) - -}} +// HfsHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariantUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "HfsHandler.h" + +/* if HFS_SHOW_ALT_STREAMS is defined, the handler will show attribute files + and resource forks. In most cases it looks useless. So we disable it. */ + +#define HFS_SHOW_ALT_STREAMS + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +#define Get16a(p) GetBe16a(p) +#define Get32a(p) GetBe32a(p) + +namespace NArchive { +namespace NHfs { + +static const char * const kResFileName = "rsrc"; // "com.apple.ResourceFork"; + +struct CExtent +{ + UInt32 Pos; + UInt32 NumBlocks; +}; + +struct CIdExtents +{ + UInt32 ID; + UInt32 StartBlock; + CRecordVector Extents; +}; + +struct CFork +{ + UInt64 Size; + UInt32 NumBlocks; + // UInt32 ClumpSize; + CRecordVector Extents; + + CFork(): Size(0), NumBlocks(0) {} + + void Parse(const Byte *p); + + bool IsEmpty() const { return Size == 0 && NumBlocks == 0 && Extents.Size() == 0; } + + UInt32 Calc_NumBlocks_from_Extents() const; + bool Check_NumBlocks() const; + + bool Check_Size_with_NumBlocks(unsigned blockSizeLog) const + { + return Size <= ((UInt64)NumBlocks << blockSizeLog); + } + + bool IsOk(unsigned blockSizeLog) const + { + // we don't check cases with extra (empty) blocks in last extent + return Check_NumBlocks() && Check_Size_with_NumBlocks(blockSizeLog); + } + + bool Upgrade(const CObjectVector &items, UInt32 id); + bool UpgradeAndTest(const CObjectVector &items, UInt32 id, unsigned blockSizeLog) + { + if (!Upgrade(items, id)) + return false; + return IsOk(blockSizeLog); + } +}; + +static const unsigned kNumFixedExtents = 8; +static const unsigned kForkRecSize = 16 + kNumFixedExtents * 8; + + +void CFork::Parse(const Byte *p) +{ + Extents.Clear(); + Size = Get64(p); + // ClumpSize = Get32(p + 8); + NumBlocks = Get32(p + 12); + p += 16; + for (unsigned i = 0; i < kNumFixedExtents; i++, p += 8) + { + CExtent e; + e.Pos = Get32(p); + e.NumBlocks = Get32(p + 4); + if (e.NumBlocks != 0) + Extents.Add(e); + } +} + +UInt32 CFork::Calc_NumBlocks_from_Extents() const +{ + UInt32 num = 0; + FOR_VECTOR (i, Extents) + num += Extents[i].NumBlocks; + return num; +} + +bool CFork::Check_NumBlocks() const +{ + UInt32 num = NumBlocks; + FOR_VECTOR (i, Extents) + { + const UInt32 cur = Extents[i].NumBlocks; + if (num < cur) + return false; + num -= cur; + } + return num == 0; +} + +struct CIdIndexPair +{ + UInt32 ID; + unsigned Index; + + int Compare(const CIdIndexPair &a) const; +}; + +#define RINOZ(x) { const int _t_ = (x); if (_t_ != 0) return _t_; } + +int CIdIndexPair::Compare(const CIdIndexPair &a) const +{ + RINOZ(MyCompare(ID, a.ID)) + return MyCompare(Index, a.Index); +} + +static int FindItemIndex(const CRecordVector &items, UInt32 id) +{ + unsigned left = 0, right = items.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const UInt32 midVal = items[mid].ID; + if (id == midVal) + return (int)items[mid].Index; + if (id < midVal) + right = mid; + else + left = mid + 1; + } + return -1; +} + +static int Find_in_IdExtents(const CObjectVector &items, UInt32 id) +{ + unsigned left = 0, right = items.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const UInt32 midVal = items[mid].ID; + if (id == midVal) + return (int)mid; + if (id < midVal) + right = mid; + else + left = mid + 1; + } + return -1; +} + +bool CFork::Upgrade(const CObjectVector &items, UInt32 id) +{ + const int index = Find_in_IdExtents(items, id); + if (index < 0) + return true; + const CIdExtents &item = items[index]; + if (Calc_NumBlocks_from_Extents() != item.StartBlock) + return false; + Extents += item.Extents; + return true; +} + + +struct CVolHeader +{ + unsigned BlockSizeLog; + UInt32 NumFiles; + UInt32 NumFolders; + UInt32 NumBlocks; + UInt32 NumFreeBlocks; + + bool Is_Hsfx_ver5; + // UInt32 Attr; + // UInt32 LastMountedVersion; + // UInt32 JournalInfoBlock; + + UInt32 CTime; + UInt32 MTime; + // UInt32 BackupTime; + // UInt32 CheckedTime; + + // UInt32 WriteCount; + // UInt32 FinderInfo[8]; + // UInt64 VolID; + + UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; } + UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; } + bool IsHfsX() const { return Is_Hsfx_ver5; } +}; + +inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) +{ + UInt64 v = ((UInt64)3600 * 24 * (365 * 303 + 24 * 3) + hfsTime) * 10000000; + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + +enum ERecordType +{ + RECORD_TYPE_FOLDER = 1, + RECORD_TYPE_FILE, + RECORD_TYPE_FOLDER_THREAD, + RECORD_TYPE_FILE_THREAD +}; + + + +// static const UInt32 kMethod_1_NO_COMPRESSION = 1; // in xattr +static const UInt32 kMethod_ZLIB_ATTR = 3; +static const UInt32 kMethod_ZLIB_RSRC = 4; +// static const UInt32 kMethod_DEDUP = 5; // de-dup within the generation store +// macos 10.10 +static const UInt32 kMethod_LZVN_ATTR = 7; +static const UInt32 kMethod_LZVN_RSRC = 8; +static const UInt32 kMethod_COPY_ATTR = 9; +static const UInt32 kMethod_COPY_RSRC = 10; +// macos 10.11 +// static const UInt32 kMethod_LZFSE_ATTR = 11; +static const UInt32 kMethod_LZFSE_RSRC = 12; + +// static const UInt32 kMethod_ZBM_RSRC = 14; + +static const char * const g_Methods[] = +{ + NULL + , NULL + , NULL + , "ZLIB-attr" + , "ZLIB-rsrc" + , NULL + , NULL + , "LZVN-attr" + , "LZVN-rsrc" + , "COPY-attr" + , "COPY-rsrc" + , "LZFSE-attr" + , "LZFSE-rsrc" + , NULL + , "ZBM-rsrc" +}; + + +static const Byte k_COPY_Uncompressed_Marker = 0xcc; +static const Byte k_LZVN_Uncompressed_Marker = 6; + +void CCompressHeader::Parse(const Byte *p, size_t dataSize) +{ + Clear(); + + if (dataSize < k_decmpfs_HeaderSize) + return; + if (GetUi32(p) != 0x636D7066) // magic == "fpmc" + return; + Method = GetUi32(p + 4); + UnpackSize = GetUi64(p + 8); + dataSize -= k_decmpfs_HeaderSize; + IsCorrect = true; + + if ( Method == kMethod_ZLIB_RSRC + || Method == kMethod_COPY_RSRC + || Method == kMethod_LZVN_RSRC + || Method == kMethod_LZFSE_RSRC + // || Method == kMethod_ZBM_RSRC // for debug + ) + { + IsResource = true; + if (dataSize == 0) + IsSupported = ( + Method != kMethod_LZFSE_RSRC && + Method != kMethod_COPY_RSRC); + return; + } + + if ( Method == kMethod_ZLIB_ATTR + || Method == kMethod_COPY_ATTR + || Method == kMethod_LZVN_ATTR + // || Method == kMethod_LZFSE_ATTR + ) + { + if (dataSize == 0) + return; + const Byte b = p[k_decmpfs_HeaderSize]; + if ( (Method == kMethod_ZLIB_ATTR && (b & 0xf) == 0xf) + || (Method == kMethod_COPY_ATTR && b == k_COPY_Uncompressed_Marker) + || (Method == kMethod_LZVN_ATTR && b == k_LZVN_Uncompressed_Marker)) + { + dataSize--; + // if (UnpackSize > dataSize) + if (UnpackSize != dataSize) + return; + DataPos = k_decmpfs_HeaderSize + 1; + IsSupported = true; + } + else + { + if (Method != kMethod_COPY_ATTR) + IsSupported = true; + DataPos = k_decmpfs_HeaderSize; + } + } +} + + +void CCompressHeader::MethodToProp(NWindows::NCOM::CPropVariant &prop) const +{ + if (!IsCorrect) + return; + const UInt32 method = Method; + const char *p = NULL; + if (method < Z7_ARRAY_SIZE(g_Methods)) + p = g_Methods[method]; + AString s; + if (p) + s = p; + else + s.Add_UInt32(method); + // if (!IsSupported) s += "-unsuported"; + prop = s; +} + +void MethodsMaskToProp(UInt32 methodsMask, NWindows::NCOM::CPropVariant &prop) +{ + FLAGS_TO_PROP(g_Methods, methodsMask, prop); +} + + +struct CItem +{ + UString Name; + + UInt32 ParentID; + + UInt16 Type; + UInt16 FileMode; + // UInt16 Flags; + // UInt32 Valence; + UInt32 ID; + UInt32 CTime; + UInt32 MTime; + UInt32 AttrMTime; + UInt32 ATime; + // UInt32 BackupDate; + + /* + UInt32 OwnerID; + UInt32 GroupID; + Byte AdminFlags; + Byte OwnerFlags; + union + { + UInt32 iNodeNum; + UInt32 LinkCount; + UInt32 RawDevice; + } special; + + UInt32 FileType; + UInt32 FileCreator; + UInt16 FinderFlags; + UInt16 Point[2]; + */ + + CFork DataFork; + CFork ResourceFork; + + // for compressed attribute (decmpfs) + int decmpfs_AttrIndex; + CCompressHeader CompressHeader; + + CItem(): + decmpfs_AttrIndex(-1) + {} + bool IsDir() const { return Type == RECORD_TYPE_FOLDER; } + // const CFork *GetFork(bool isResource) const { return (isResource ? &ResourceFork: &DataFork); } +}; + + +struct CAttr +{ + UInt32 ID; + bool Fork_defined; + + // UInt32 Size; // for (Fork_defined == false) case + // size_t DataPos; // for (Fork_defined == false) case + CByteBuffer Data; + + CFork Fork; + + UString Name; + + UInt64 GetSize() const + { + if (Fork_defined) + return Fork.Size; + return Data.Size(); + } + + CAttr(): + Fork_defined(false) + // Size(0), + // DataPos(0), + {} +}; + + +static const int kAttrIndex_Item = -1; +static const int kAttrIndex_Resource = -2; + +struct CRef +{ + unsigned ItemIndex; + int AttrIndex; + int Parent; + + CRef(): AttrIndex(kAttrIndex_Item), Parent(-1) {} + bool IsResource() const { return AttrIndex == kAttrIndex_Resource; } + bool IsAltStream() const { return AttrIndex != kAttrIndex_Item; } + bool IsItem() const { return AttrIndex == kAttrIndex_Item; } +}; + + +class CDatabase +{ + HRESULT ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream); + HRESULT LoadExtentFile(const CFork &fork, IInStream *inStream, CObjectVector *overflowExtentsArray); + HRESULT LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpenCallback *progress); + HRESULT LoadCatalog(const CFork &fork, const CObjectVector *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress); + bool Parse_decmpgfs(unsigned attrIndex, CItem &item, bool &skip); +public: + CRecordVector Refs; + CObjectVector Items; + CObjectVector Attrs; + + // CByteBuffer AttrBuf; + + CVolHeader Header; + bool HeadersError; + bool UnsupportedFeature; + bool ThereAreAltStreams; + // bool CaseSensetive; + UInt32 MethodsMask; + UString ResFileName; + + UInt64 SpecOffset; + // UInt64 PhySize; + UInt64 PhySize2; + UInt64 ArcFileSize; + + void Clear() + { + SpecOffset = 0; + // PhySize = 0; + PhySize2 = 0; + ArcFileSize = 0; + MethodsMask = 0; + HeadersError = false; + UnsupportedFeature = false; + ThereAreAltStreams = false; + // CaseSensetive = false; + + Refs.Clear(); + Items.Clear(); + Attrs.Clear(); + // AttrBuf.Free(); + } + + UInt64 Get_UnpackSize_of_Ref(const CRef &ref) const + { + if (ref.AttrIndex >= 0) + return Attrs[ref.AttrIndex].GetSize(); + const CItem &item = Items[ref.ItemIndex]; + if (ref.IsResource()) + return item.ResourceFork.Size; + if (item.IsDir()) + return 0; + else if (item.CompressHeader.IsCorrect) + return item.CompressHeader.UnpackSize; + return item.DataFork.Size; + } + + void GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path) const; + HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *progress); +}; + +enum +{ + kHfsID_Root = 1, + kHfsID_RootFolder = 2, + kHfsID_ExtentsFile = 3, + kHfsID_CatalogFile = 4, + kHfsID_BadBlockFile = 5, + kHfsID_AllocationFile = 6, + kHfsID_StartupFile = 7, + kHfsID_AttributesFile = 8, + kHfsID_RepairCatalogFile = 14, + kHfsID_BogusExtentFile = 15, + kHfsID_FirstUserCatalogNode = 16 +}; + +void CDatabase::GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path) const +{ + unsigned len = 0; + const unsigned kNumLevelsMax = (1 << 10); + unsigned cur = index; + unsigned i; + + for (i = 0; i < kNumLevelsMax; i++) + { + const CRef &ref = Refs[cur]; + const UString *s; + + if (ref.IsResource()) + s = &ResFileName; + else if (ref.AttrIndex >= 0) + s = &Attrs[ref.AttrIndex].Name; + else + s = &Items[ref.ItemIndex].Name; + + len += s->Len(); + len++; + cur = (unsigned)ref.Parent; + if (ref.Parent < 0) + break; + } + + len--; + wchar_t *p = path.AllocBstr(len); + p[len] = 0; + cur = index; + + for (;;) + { + const CRef &ref = Refs[cur]; + const UString *s; + wchar_t delimChar = L':'; + + if (ref.IsResource()) + s = &ResFileName; + else if (ref.AttrIndex >= 0) + s = &Attrs[ref.AttrIndex].Name; + else + { + delimChar = WCHAR_PATH_SEPARATOR; + s = &Items[ref.ItemIndex].Name; + } + + unsigned curLen = s->Len(); + len -= curLen; + + const wchar_t *src = (const wchar_t *)*s; + wchar_t *dest = p + len; + for (unsigned j = 0; j < curLen; j++) + { + wchar_t c = src[j]; + // 18.06 + if (c == CHAR_PATH_SEPARATOR || c == '/') + c = '_'; + dest[j] = c; + } + + if (len == 0) + break; + p[--len] = delimChar; + cur = (unsigned)ref.Parent; + } +} + +// Actually we read all blocks. It can be larger than fork.Size + +HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inStream) +{ + if (fork.NumBlocks >= Header.NumBlocks) + return S_FALSE; + if (((ArcFileSize - SpecOffset) >> Header.BlockSizeLog) + 1 < fork.NumBlocks) + return S_FALSE; + + const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; + if ((totalSize >> Header.BlockSizeLog) != fork.NumBlocks) + return S_FALSE; + buf.Alloc(totalSize); + UInt32 curBlock = 0; + FOR_VECTOR (i, fork.Extents) + { + if (curBlock >= fork.NumBlocks) + return S_FALSE; + const CExtent &e = fork.Extents[i]; + if (e.Pos > Header.NumBlocks || + e.NumBlocks > fork.NumBlocks - curBlock || + e.NumBlocks > Header.NumBlocks - e.Pos) + return S_FALSE; + RINOK(InStream_SeekSet(inStream, SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog))) + RINOK(ReadStream_FALSE(inStream, + (Byte *)buf + ((size_t)curBlock << Header.BlockSizeLog), + (size_t)e.NumBlocks << Header.BlockSizeLog)) + curBlock += e.NumBlocks; + } + return S_OK; +} + +static const unsigned kNodeDescriptor_Size = 14; + +struct CNodeDescriptor +{ + UInt32 fLink; + // UInt32 bLink; + Byte Kind; + // Byte Height; + unsigned NumRecords; + + bool Parse(const Byte *p, unsigned nodeSizeLog); +}; + + +bool CNodeDescriptor::Parse(const Byte *p, unsigned nodeSizeLog) +{ + fLink = Get32(p); + // bLink = Get32(p + 4); + Kind = p[8]; + // Height = p[9]; + NumRecords = Get16(p + 10); + + const size_t nodeSize = (size_t)1 << nodeSizeLog; + if (kNodeDescriptor_Size + ((UInt32)NumRecords + 1) * 2 > nodeSize) + return false; + const size_t limit = nodeSize - ((UInt32)NumRecords + 1) * 2; + + p += nodeSize - 2; + + for (unsigned i = 0; i < NumRecords; i++) + { + const UInt32 offs = Get16(p); + p -= 2; + const UInt32 offsNext = Get16(p); + if (offs < kNodeDescriptor_Size + || offs >= offsNext + || offsNext > limit) + return false; + } + return true; +} + +struct CHeaderRec +{ + // UInt16 TreeDepth; + // UInt32 RootNode; + // UInt32 LeafRecords; + UInt32 FirstLeafNode; + // UInt32 LastLeafNode; + unsigned NodeSizeLog; + // UInt16 MaxKeyLength; + UInt32 TotalNodes; + // UInt32 FreeNodes; + // UInt16 Reserved1; + // UInt32 ClumpSize; + // Byte BtreeType; + // Byte KeyCompareType; + // UInt32 Attributes; + // UInt32 Reserved3[16]; + + HRESULT Parse2(const CByteBuffer &buf); +}; + +HRESULT CHeaderRec::Parse2(const CByteBuffer &buf) +{ + if (buf.Size() < kNodeDescriptor_Size + 0x2A + 16 * 4) + return S_FALSE; + const Byte * p = (const Byte *)buf + kNodeDescriptor_Size; + // TreeDepth = Get16(p); + // RootNode = Get32(p + 2); + // LeafRecords = Get32(p + 6); + FirstLeafNode = Get32(p + 0xA); + // LastLeafNode = Get32(p + 0xE); + const UInt32 nodeSize = Get16(p + 0x12); + + unsigned i; + for (i = 9; ((UInt32)1 << i) != nodeSize; i++) + if (i == 16) + return S_FALSE; + NodeSizeLog = i; + + // MaxKeyLength = Get16(p + 0x14); + TotalNodes = Get32(p + 0x16); + // FreeNodes = Get32(p + 0x1A); + // Reserved1 = Get16(p + 0x1E); + // ClumpSize = Get32(p + 0x20); + // BtreeType = p[0x24]; + // KeyCompareType = p[0x25]; + // Attributes = Get32(p + 0x26); + /* + for (int i = 0; i < 16; i++) + Reserved3[i] = Get32(p + 0x2A + i * 4); + */ + + if ((buf.Size() >> NodeSizeLog) < TotalNodes) + return S_FALSE; + + return S_OK; +} + + +static const Byte kNodeType_Leaf = 0xFF; +// static const Byte kNodeType_Index = 0; +// static const Byte kNodeType_Header = 1; +// static const Byte kNodeType_Mode = 2; + +static const Byte kExtentForkType_Data = 0; +static const Byte kExtentForkType_Resource = 0xFF; + +/* It loads data extents from Extents Overflow File + Most dmg installers are not fragmented. So there are no extents in Overflow File. */ + +HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjectVector *overflowExtentsArray) +{ + if (fork.NumBlocks == 0) + return S_OK; + CByteBuffer buf; + RINOK(ReadFile(fork, buf, inStream)) + const Byte *p = (const Byte *)buf; + + // CNodeDescriptor nodeDesc; + // nodeDesc.Parse(p); + CHeaderRec hr; + RINOK(hr.Parse2(buf)) + + UInt32 node = hr.FirstLeafNode; + if (node == 0) + return S_OK; + if (hr.TotalNodes == 0) + return S_FALSE; + + CByteArr usedBuf(hr.TotalNodes); + memset(usedBuf, 0, hr.TotalNodes); + + while (node != 0) + { + if (node >= hr.TotalNodes || usedBuf[node] != 0) + return S_FALSE; + usedBuf[node] = 1; + + const size_t nodeOffset = (size_t)node << hr.NodeSizeLog; + CNodeDescriptor desc; + if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog)) + return S_FALSE; + if (desc.Kind != kNodeType_Leaf) + return S_FALSE; + + UInt32 endBlock = 0; + + for (unsigned i = 0; i < desc.NumRecords; i++) + { + const UInt32 nodeSize = ((UInt32)1 << hr.NodeSizeLog); + const Byte *r = p + nodeOffset + nodeSize - i * 2; + const UInt32 offs = Get16(r - 2); + UInt32 recSize = Get16(r - 4) - offs; + const unsigned kKeyLen = 10; + + if (recSize != 2 + kKeyLen + kNumFixedExtents * 8) + return S_FALSE; + + r = p + nodeOffset + offs; + if (Get16(r) != kKeyLen) + return S_FALSE; + + const Byte forkType = r[2]; + unsigned forkTypeIndex; + if (forkType == kExtentForkType_Data) + forkTypeIndex = 0; + else if (forkType == kExtentForkType_Resource) + forkTypeIndex = 1; + else + continue; + CObjectVector &overflowExtents = overflowExtentsArray[forkTypeIndex]; + + const UInt32 id = Get32(r + 4); + const UInt32 startBlock = Get32(r + 8); + r += 2 + kKeyLen; + + bool needNew = true; + + if (overflowExtents.Size() != 0) + { + CIdExtents &e = overflowExtents.Back(); + if (e.ID == id) + { + if (endBlock != startBlock) + return S_FALSE; + needNew = false; + } + } + + if (needNew) + { + CIdExtents &e = overflowExtents.AddNew(); + e.ID = id; + e.StartBlock = startBlock; + endBlock = startBlock; + } + + CIdExtents &e = overflowExtents.Back(); + + for (unsigned k = 0; k < kNumFixedExtents; k++, r += 8) + { + CExtent ee; + ee.Pos = Get32(r); + ee.NumBlocks = Get32(r + 4); + if (ee.NumBlocks != 0) + { + e.Extents.Add(ee); + endBlock += ee.NumBlocks; + } + } + } + + node = desc.fLink; + } + return S_OK; +} + +static void LoadName(const Byte *data, unsigned len, UString &dest) +{ + wchar_t *p = dest.GetBuf(len); + unsigned i; + for (i = 0; i < len; i++) + { + const wchar_t c = Get16(data + i * 2); + if (c == 0) + break; + p[i] = c; + } + p[i] = 0; + dest.ReleaseBuf_SetLen(i); +} + +static bool IsNameEqualTo(const Byte *data, const char *name) +{ + for (unsigned i = 0;; i++) + { + const char c = name[i]; + if (c == 0) + return true; + if (Get16(data + i * 2) != (Byte)c) + return false; + } +} + +static const UInt32 kAttrRecordType_Inline = 0x10; +static const UInt32 kAttrRecordType_Fork = 0x20; +// static const UInt32 kAttrRecordType_Extents = 0x30; + +HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpenCallback *progress) +{ + if (fork.NumBlocks == 0) + return S_OK; + + CByteBuffer AttrBuf; + RINOK(ReadFile(fork, AttrBuf, inStream)) + const Byte *p = (const Byte *)AttrBuf; + + // CNodeDescriptor nodeDesc; + // nodeDesc.Parse(p); + CHeaderRec hr; + RINOK(hr.Parse2(AttrBuf)) + + // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); + + UInt32 node = hr.FirstLeafNode; + if (node == 0) + return S_OK; + if (hr.TotalNodes == 0) + return S_FALSE; + + CByteArr usedBuf(hr.TotalNodes); + memset(usedBuf, 0, hr.TotalNodes); + + CFork resFork; + + while (node != 0) + { + if (node >= hr.TotalNodes || usedBuf[node] != 0) + return S_FALSE; + usedBuf[node] = 1; + + const size_t nodeOffset = (size_t)node << hr.NodeSizeLog; + CNodeDescriptor desc; + if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog)) + return S_FALSE; + if (desc.Kind != kNodeType_Leaf) + return S_FALSE; + + for (unsigned i = 0; i < desc.NumRecords; i++) + { + const UInt32 nodeSize = ((UInt32)1 << hr.NodeSizeLog); + const Byte *r = p + nodeOffset + nodeSize - i * 2; + const UInt32 offs = Get16(r - 2); + UInt32 recSize = Get16(r - 4) - offs; + const unsigned kHeadSize = 14; + if (recSize < kHeadSize) + return S_FALSE; + + r = p + nodeOffset + offs; + const UInt32 keyLen = Get16(r); + + // UInt16 pad = Get16(r + 2); + const UInt32 fileID = Get32(r + 4); + const unsigned startBlock = Get32(r + 8); + if (startBlock != 0) + { + // that case is still unsupported + UnsupportedFeature = true; + continue; + } + const unsigned nameLen = Get16(r + 12); + + if (keyLen + 2 > recSize || + keyLen != kHeadSize - 2 + nameLen * 2) + return S_FALSE; + r += kHeadSize; + recSize -= kHeadSize; + + const Byte *name = r; + r += nameLen * 2; + recSize -= nameLen * 2; + + if (recSize < 4) + return S_FALSE; + + const UInt32 recordType = Get32(r); + + if (progress && (Attrs.Size() & 0xFFF) == 0) + { + const UInt64 numFiles = 0; + RINOK(progress->SetCompleted(&numFiles, NULL)) + } + + if (Attrs.Size() >= ((UInt32)1 << 31)) + return S_FALSE; + + CAttr &attr = Attrs.AddNew(); + attr.ID = fileID; + LoadName(name, nameLen, attr.Name); + + if (recordType == kAttrRecordType_Fork) + { + // 22.00 : some hfs files contain it; + /* spec: If the attribute has more than 8 extents, there will be additional + records (of type kAttrRecordType_Extents) for this attribute. */ + if (recSize != 8 + kForkRecSize) + return S_FALSE; + if (Get32(r + 4) != 0) // reserved + return S_FALSE; + attr.Fork.Parse(r + 8); + attr.Fork_defined = true; + continue; + } + else if (recordType != kAttrRecordType_Inline) + { + UnsupportedFeature = true; + continue; + } + + const unsigned kRecordHeaderSize = 16; + if (recSize < kRecordHeaderSize) + return S_FALSE; + if (Get32(r + 4) != 0 || Get32(r + 8) != 0) // reserved + return S_FALSE; + const UInt32 dataSize = Get32(r + 12); + + r += kRecordHeaderSize; + recSize -= kRecordHeaderSize; + + if (recSize < dataSize) + return S_FALSE; + + attr.Data.CopyFrom(r, dataSize); + // attr.DataPos = nodeOffset + offs + 2 + keyLen + kRecordHeaderSize; + // attr.Size = dataSize; + } + + node = desc.fLink; + } + return S_OK; +} + + +bool CDatabase::Parse_decmpgfs(unsigned attrIndex, CItem &item, bool &skip) +{ + const CAttr &attr = Attrs[attrIndex]; + skip = false; + if (item.CompressHeader.IsCorrect || !item.DataFork.IsEmpty()) + return false; + + item.CompressHeader.Parse(attr.Data, attr.Data.Size()); + + if (item.CompressHeader.IsCorrect) + { + item.decmpfs_AttrIndex = (int)attrIndex; + skip = true; + if (item.CompressHeader.Method < sizeof(MethodsMask) * 8) + MethodsMask |= ((UInt32)1 << item.CompressHeader.Method); + } + + return true; +} + + +HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress) +{ + CByteBuffer buf; + RINOK(ReadFile(fork, buf, inStream)) + const Byte *p = (const Byte *)buf; + + // CNodeDescriptor nodeDesc; + // nodeDesc.Parse(p); + CHeaderRec hr; + RINOK(hr.Parse2(buf)) + + CRecordVector IdToIndexMap; + + const unsigned reserveSize = (unsigned)(Header.NumFolders + 1 + Header.NumFiles); + + const unsigned kBasicRecSize = 0x58; + const unsigned kMinRecSize = kBasicRecSize + 10; + + if ((UInt64)reserveSize * kMinRecSize < buf.Size()) + { + Items.ClearAndReserve(reserveSize); + Refs.ClearAndReserve(reserveSize); + IdToIndexMap.ClearAndReserve(reserveSize); + } + + // CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC); + + CByteArr usedBuf(hr.TotalNodes); + if (hr.TotalNodes != 0) + memset(usedBuf, 0, hr.TotalNodes); + + CFork resFork; + + UInt32 node = hr.FirstLeafNode; + UInt32 numFiles = 0; + UInt32 numFolders = 0; + + while (node != 0) + { + if (node >= hr.TotalNodes || usedBuf[node] != 0) + return S_FALSE; + usedBuf[node] = 1; + + const size_t nodeOffset = (size_t)node << hr.NodeSizeLog; + CNodeDescriptor desc; + if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog)) + return S_FALSE; + if (desc.Kind != kNodeType_Leaf) + return S_FALSE; + + for (unsigned i = 0; i < desc.NumRecords; i++) + { + const UInt32 nodeSize = (1 << hr.NodeSizeLog); + const Byte *r = p + nodeOffset + nodeSize - i * 2; + const UInt32 offs = Get16(r - 2); + UInt32 recSize = Get16(r - 4) - offs; + if (recSize < 6) + return S_FALSE; + + r = p + nodeOffset + offs; + UInt32 keyLen = Get16(r); + UInt32 parentID = Get32(r + 2); + if (keyLen < 6 || (keyLen & 1) != 0 || keyLen + 2 > recSize) + return S_FALSE; + r += 6; + recSize -= 6; + keyLen -= 6; + + unsigned nameLen = Get16(r); + if (nameLen * 2 != (unsigned)keyLen) + return S_FALSE; + r += 2; + recSize -= 2; + + r += nameLen * 2; + recSize -= nameLen * 2; + + if (recSize < 2) + return S_FALSE; + UInt16 type = Get16(r); + + if (type != RECORD_TYPE_FOLDER && + type != RECORD_TYPE_FILE) + continue; + + if (recSize < kBasicRecSize) + return S_FALSE; + + CItem &item = Items.AddNew(); + item.ParentID = parentID; + item.Type = type; + // item.Flags = Get16(r + 2); + // item.Valence = Get32(r + 4); + item.ID = Get32(r + 8); + { + const Byte *name = r - (nameLen * 2); + LoadName(name, nameLen, item.Name); + if (item.Name.Len() <= 1) + { + if (item.Name.IsEmpty() && nameLen == 21) + { + if (GetUi32(name) == 0 && + GetUi32(name + 4) == 0 && + IsNameEqualTo(name + 8, "HFS+ Private Data")) + { + // it's folder for "Hard Links" files + item.Name = "[HFS+ Private Data]"; + } + } + + // Some dmg files have ' ' folder item. + if (item.Name.IsEmpty() || item.Name[0] == L' ') + item.Name = "[]"; + } + } + + item.CTime = Get32(r + 0xC); + item.MTime = Get32(r + 0x10); + item.AttrMTime = Get32(r + 0x14); + item.ATime = Get32(r + 0x18); + // item.BackupDate = Get32(r + 0x1C); + + /* + item.OwnerID = Get32(r + 0x20); + item.GroupID = Get32(r + 0x24); + item.AdminFlags = r[0x28]; + item.OwnerFlags = r[0x29]; + */ + item.FileMode = Get16(r + 0x2A); + /* + item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount + item.FileType = Get32(r + 0x30); + item.FileCreator = Get32(r + 0x34); + item.FinderFlags = Get16(r + 0x38); + item.Point[0] = Get16(r + 0x3A); // v + item.Point[1] = Get16(r + 0x3C); // h + */ + + // const refIndex = Refs.Size(); + CIdIndexPair pair; + pair.ID = item.ID; + pair.Index = Items.Size() - 1; + IdToIndexMap.Add(pair); + + recSize -= kBasicRecSize; + r += kBasicRecSize; + if (item.IsDir()) + { + numFolders++; + if (recSize != 0) + return S_FALSE; + } + else + { + numFiles++; + if (recSize != kForkRecSize * 2) + return S_FALSE; + + item.DataFork.Parse(r); + + if (!item.DataFork.UpgradeAndTest(overflowExtentsArray[0], item.ID, Header.BlockSizeLog)) + HeadersError = true; + + item.ResourceFork.Parse(r + kForkRecSize); + if (!item.ResourceFork.IsEmpty()) + { + if (!item.ResourceFork.UpgradeAndTest(overflowExtentsArray[1], item.ID, Header.BlockSizeLog)) + HeadersError = true; + // ThereAreAltStreams = true; + } + } + if (progress && (Items.Size() & 0xFFF) == 0) + { + const UInt64 numItems = Items.Size(); + RINOK(progress->SetCompleted(&numItems, NULL)) + } + } + node = desc.fLink; + } + + if (Header.NumFiles != numFiles || + Header.NumFolders + 1 != numFolders) + HeadersError = true; + + IdToIndexMap.Sort2(); + { + for (unsigned i = 1; i < IdToIndexMap.Size(); i++) + if (IdToIndexMap[i - 1].ID == IdToIndexMap[i].ID) + return S_FALSE; + } + + + CBoolArr skipAttr(Attrs.Size()); + { + for (unsigned i = 0; i < Attrs.Size(); i++) + skipAttr[i] = false; + } + + { + FOR_VECTOR (i, Attrs) + { + const CAttr &attr = Attrs[i]; + + const int itemIndex = FindItemIndex(IdToIndexMap, attr.ID); + if (itemIndex < 0) + { + HeadersError = true; + continue; + } + + if (attr.Name.IsEqualTo("com.apple.decmpfs")) + { + if (!Parse_decmpgfs(i, Items[itemIndex], skipAttr[i])) + HeadersError = true; + } + } + } + + IdToIndexMap.ClearAndReserve(Items.Size()); + + { + FOR_VECTOR (i, Items) + { + const CItem &item = Items[i]; + + CIdIndexPair pair; + pair.ID = item.ID; + pair.Index = Refs.Size(); + IdToIndexMap.Add(pair); + + CRef ref; + ref.ItemIndex = i; + Refs.Add(ref); + + #ifdef HFS_SHOW_ALT_STREAMS + + if (item.ResourceFork.IsEmpty()) + continue; + if (item.CompressHeader.IsSupported && item.CompressHeader.IsMethod_Resource()) + continue; + + ThereAreAltStreams = true; + ref.AttrIndex = kAttrIndex_Resource; + ref.Parent = (int)(Refs.Size() - 1); + Refs.Add(ref); + + #endif + } + } + + IdToIndexMap.Sort2(); + + { + FOR_VECTOR (i, Refs) + { + CRef &ref = Refs[i]; + if (ref.IsResource()) + continue; + const CItem &item = Items[ref.ItemIndex]; + ref.Parent = FindItemIndex(IdToIndexMap, item.ParentID); + if (ref.Parent >= 0) + { + if (!Items[Refs[ref.Parent].ItemIndex].IsDir()) + { + ref.Parent = -1; + HeadersError = true; + } + } + } + } + + #ifdef HFS_SHOW_ALT_STREAMS + { + FOR_VECTOR (i, Attrs) + { + if (skipAttr[i]) + continue; + const CAttr &attr = Attrs[i]; + + const int refIndex = FindItemIndex(IdToIndexMap, attr.ID); + if (refIndex < 0) + { + HeadersError = true; + continue; + } + + ThereAreAltStreams = true; + + CRef ref; + ref.AttrIndex = (int)i; + ref.Parent = refIndex; + ref.ItemIndex = Refs[refIndex].ItemIndex; + Refs.Add(ref); + } + } + #endif + + return S_OK; +} + +static const unsigned kHeaderPadSize = 1 << 10; +static const unsigned kMainHeaderSize = 512; +static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize; + +static const unsigned k_Signature_LE16_HFS_BD = 'B' + ((unsigned)'D' << 8); +static const unsigned k_Signature_LE16_HPLUS = 'H' + ((unsigned)'+' << 8); +static const UInt32 k_Signature_LE32_HFSP_VER4 = 'H' + ((UInt32)'+' << 8) + ((UInt32)4 << 24); +static const UInt32 k_Signature_LE32_HFSX_VER5 = 'H' + ((UInt32)'X' << 8) + ((UInt32)5 << 24); + +API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size) +{ + if (size < kHfsHeaderSize) + return k_IsArc_Res_NEED_MORE; + p += kHeaderPadSize; + const UInt32 sig = GetUi32(p); + if (sig != k_Signature_LE32_HFSP_VER4) + if (sig != k_Signature_LE32_HFSX_VER5) + if ((UInt16)sig != k_Signature_LE16_HFS_BD + || GetUi16(p + 0x7c) != k_Signature_LE16_HPLUS) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) +{ + Clear(); + UInt32 buf32[kHfsHeaderSize / 4]; + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) + const Byte *p = (const Byte *)buf32 + kHeaderPadSize; + CVolHeader &h = Header; + + if (GetUi16a(p) == k_Signature_LE16_HFS_BD) + { + /* + It's header for old HFS format. + We don't support old HFS format, but we support + special HFS volume that contains embedded HFS+ volume. + HFS MDB : Master directory block + HFS VIB : Volume information block + some old images contain boot data with "LK" signature at start of buf32. + */ +#if 1 + // here we check first bytes of archive, + // because start data can contain signature of some another + // archive type that could have priority over HFS. + const void *buf_ptr = (const void *)buf32; + const unsigned sig = GetUi16a(buf_ptr); + if (sig != 'L' + ((unsigned)'K' << 8)) + { + // some old HFS (non HFS+) files have no "LK" signature, + // but have non-zero data after 2 first bytes in start 1 KiB. + if (sig != 0) + return S_FALSE; +/* + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; +*/ + } +#endif + if (GetUi16a(p + 0x7c) != k_Signature_LE16_HPLUS) // signature of embedded HFS+ volume + return S_FALSE; + /* + h.CTime = Get32(p + 0x2); + h.MTime = Get32(p + 0x6); + + h.NumFiles = Get32(p + 0x54); + h.NumFolders = Get32(p + 0x58); + + if (h.NumFolders > ((UInt32)1 << 29) || + h.NumFiles > ((UInt32)1 << 30)) + return S_FALSE; + if (progress) + { + UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; + RINOK(progress->SetTotal(&numFiles, NULL)) + } + h.NumFreeBlocks = Get16(p + 0x22); + */ + + // v24.09: blockSize in old HFS image can be non-power of 2. + const UInt32 blockSize = Get32a(p + 0x14); // drAlBlkSiz + if (blockSize == 0 || (blockSize & 0x1ff)) + return S_FALSE; + const unsigned numBlocks = Get16a(p + 0x12); // drNmAlBlks + // UInt16 drFreeBks = Get16a(p + 0x22); // number of unused allocation blocks + /* + we suppose that it has the following layout: + { + start data with header + blocks[h.NumBlocks] + end data with header (probably size_of_footer <= blockSize). + } + */ + // PhySize2 = ((UInt64)numBlocks + 2) * blockSize; + const unsigned sector_of_FirstBlock = Get16a(p + 0x1c); // drAlBlSt : first allocation block in volume + const UInt32 startBlock = Get16a(p + 0x7c + 2); + const UInt32 blockCount = Get16a(p + 0x7c + 4); + SpecOffset = (UInt32)sector_of_FirstBlock << 9; // it's 32-bit here + PhySize2 = SpecOffset + (UInt64)numBlocks * blockSize; + SpecOffset += (UInt64)startBlock * blockSize; + // before v24.09: // SpecOffset = (UInt64)(1 + startBlock) * blockSize; + const UInt64 phy = SpecOffset + (UInt64)blockCount * blockSize; + if (PhySize2 < phy) + PhySize2 = phy; + UInt32 tail = 1 << 10; // at least 1 KiB tail (for footer MDB) is expected. + if (tail < blockSize) + tail = blockSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (ArcFileSize > PhySize2 && + ArcFileSize - PhySize2 <= tail) + { + // data after blocks[h.NumBlocks] must contain another copy of MDB. + // In example where blockSize is not power of 2, we have + // (ArcFileSize - PhySize2) < blockSize. + // We suppose that data after blocks[h.NumBlocks] is part of HFS archive. + // Maybe we should scan for footer MDB data (in last 1 KiB)? + PhySize2 = ArcFileSize; + } + RINOK(InStream_SeekSet(inStream, SpecOffset)) + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) + } + + // HFS+ / HFSX volume header (starting from offset==1024): + { + // v24.09: we use strict condition test for pair signature(Version): + // H+(4), HX(5): + const UInt32 sig = GetUi32a(p); + // h.Version = Get16(p + 2); + h.Is_Hsfx_ver5 = false; + if (sig != k_Signature_LE32_HFSP_VER4) + { + if (sig != k_Signature_LE32_HFSX_VER5) + return S_FALSE; + h.Is_Hsfx_ver5 = true; + } + } + { + const UInt32 blockSize = Get32a(p + 0x28); + unsigned i; + for (i = 9; ((UInt32)1 << i) != blockSize; i++) + if (i == 31) + return S_FALSE; + h.BlockSizeLog = i; + } +#if 1 + // HFS Plus DOCs: The first 1024 bytes are reserved for use as boot blocks + // v24.09: we don't check starting 1 KiB before old (HFS MDB) block ("BD" signture) . + // but we still check starting 1 KiB before HFS+ / HFSX volume header. + // are there HFS+ / HFSX images with non-zero data in this reserved area? + { + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; + } +#endif + // h.Attr = Get32a(p + 4); + // h.LastMountedVersion = Get32a(p + 8); + // h.JournalInfoBlock = Get32a(p + 0xC); + h.CTime = Get32a(p + 0x10); + h.MTime = Get32a(p + 0x14); + // h.BackupTime = Get32a(p + 0x18); + // h.CheckedTime = Get32a(p + 0x1C); + h.NumFiles = Get32a(p + 0x20); + h.NumFolders = Get32a(p + 0x24); + if (h.NumFolders > ((UInt32)1 << 29) || + h.NumFiles > ((UInt32)1 << 30)) + return S_FALSE; + + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (progress) + { + const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; + RINOK(progress->SetTotal(&numFiles, NULL)) + } + + h.NumBlocks = Get32a(p + 0x2C); + h.NumFreeBlocks = Get32a(p + 0x30); + /* + h.NextCalatlogNodeID = Get32(p + 0x40); + h.WriteCount = Get32(p + 0x44); + for (i = 0; i < 6; i++) + h.FinderInfo[i] = Get32(p + 0x50 + i * 4); + h.VolID = Get64(p + 0x68); + */ + + ResFileName = kResFileName; + + CFork extentsFork, catalogFork, attrFork; + // allocationFork.Parse(p + 0x70 + 0x50 * 0); + extentsFork.Parse(p + 0x70 + 0x50 * 1); + catalogFork.Parse(p + 0x70 + 0x50 * 2); + attrFork.Parse (p + 0x70 + 0x50 * 3); + // startupFork.Parse(p + 0x70 + 0x50 * 4); + + CObjectVector overflowExtents[2]; + if (!extentsFork.IsOk(Header.BlockSizeLog)) + HeadersError = true; + else + { + const HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); + if (res == S_FALSE) + HeadersError = true; + else if (res != S_OK) + return res; + } + + if (!catalogFork.UpgradeAndTest(overflowExtents[0], kHfsID_CatalogFile, Header.BlockSizeLog)) + return S_FALSE; + + if (!attrFork.UpgradeAndTest(overflowExtents[0], kHfsID_AttributesFile, Header.BlockSizeLog)) + HeadersError = true; + else + { + if (attrFork.Size != 0) + RINOK(LoadAttrs(attrFork, inStream, progress)) + } + + RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)) + + // PhySize = Header.GetPhySize(); + return S_OK; +} + + + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveGetRawProps, + public IInArchiveGetStream, + public CMyUnknownImp, + public CDatabase +{ + Z7_IFACES_IMP_UNK_3( + IInArchive, + IArchiveGetRawProps, + IInArchiveGetStream) + + CMyComPtr _stream; + HRESULT GetForkStream(const CFork &fork, ISequentialInStream **stream); +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidCTime, + kpidMTime, + kpidATime, + kpidChangeTime, + kpidPosixAttrib, + /* + kpidUserId, + kpidGroupId, + */ +#ifdef HFS_SHOW_ALT_STREAMS + kpidIsAltStream, +#endif + kpidMethod +}; + +static const Byte kArcProps[] = +{ + kpidMethod, + kpidCharacts, + kpidClusterSize, + kpidFreeSpace, + kpidCTime, + kpidMTime +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void HfsTimeToProp(UInt32 hfsTime, NWindows::NCOM::CPropVariant &prop) +{ + if (hfsTime == 0) + return; + FILETIME ft; + HfsTimeToFileTime(hfsTime, ft); + prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Base); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidExtension: prop = Header.IsHfsX() ? "hfsx" : "hfs"; break; + case kpidMethod: prop = Header.IsHfsX() ? "HFSX" : "HFS+"; break; + case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break; + case kpidPhySize: + { + UInt64 v = SpecOffset + Header.GetPhySize(); // PhySize; + if (v < PhySize2) + v = PhySize2; + prop = v; + break; + } + case kpidClusterSize: prop = (UInt32)1 << Header.BlockSizeLog; break; + case kpidFreeSpace: prop = (UInt64)Header.GetFreeSize(); break; + case kpidMTime: HfsTimeToProp(Header.MTime, prop); break; + case kpidCTime: + { + if (Header.CTime != 0) + { + FILETIME localFt, ft; + HfsTimeToFileTime(Header.CTime, localFt); + if (LocalFileTimeToFileTime(&localFt, &ft)) + prop.SetAsTimeFrom_FT_Prec(ft, k_PropVar_TimePrec_Base); + } + break; + } + case kpidIsTree: prop = true; break; + case kpidErrorFlags: + { + UInt32 flags = 0; + if (HeadersError) flags |= kpv_ErrorFlags_HeadersError; + if (UnsupportedFeature) flags |= kpv_ErrorFlags_UnsupportedFeature; + if (flags != 0) + prop = flags; + break; + } + case kpidIsAltStream: prop = ThereAreAltStreams; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + const CRef &ref = Refs[index]; + *parentType = ref.IsAltStream() ? + NParentType::kAltStream : + NParentType::kDir; + *parent = (UInt32)(Int32)ref.Parent; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + #ifdef MY_CPU_LE + if (propID == kpidName) + { + const CRef &ref = Refs[index]; + const UString *s; + if (ref.IsResource()) + s = &ResFileName; + else if (ref.AttrIndex >= 0) + s = &Attrs[ref.AttrIndex].Name; + else + s = &Items[ref.ItemIndex].Name; + *data = (const wchar_t *)(*s); + *dataSize = (s->Len() + 1) * (UInt32)sizeof(wchar_t); + *propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE; + return S_OK; + } + #else + UNUSED_VAR(index) + UNUSED_VAR(propID) + #endif + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CRef &ref = Refs[index]; + const CItem &item = Items[ref.ItemIndex]; + switch (propID) + { + case kpidPath: GetItemPath(index, prop); break; + case kpidName: + { + const UString *s; + if (ref.IsResource()) + s = &ResFileName; + else if (ref.AttrIndex >= 0) + s = &Attrs[ref.AttrIndex].Name; + else + s = &item.Name; + prop = *s; + break; + } + case kpidPackSize: + { + UInt64 size; + if (ref.AttrIndex >= 0) + size = Attrs[ref.AttrIndex].GetSize(); + else if (ref.IsResource()) + size = (UInt64)item.ResourceFork.NumBlocks << Header.BlockSizeLog; + else if (item.IsDir()) + break; + else if (item.CompressHeader.IsCorrect) + { + if (item.CompressHeader.IsMethod_Resource()) + size = (UInt64)item.ResourceFork.NumBlocks << Header.BlockSizeLog; + else if (item.decmpfs_AttrIndex >= 0) + { + // size = item.PackSize; + const CAttr &attr = Attrs[item.decmpfs_AttrIndex]; + size = attr.Data.Size() - item.CompressHeader.DataPos; + } + else + size = 0; + } + else + size = (UInt64)item.DataFork.NumBlocks << Header.BlockSizeLog; + prop = size; + break; + } + case kpidSize: + { + UInt64 size; + if (ref.AttrIndex >= 0) + size = Attrs[ref.AttrIndex].GetSize(); + else if (ref.IsResource()) + size = item.ResourceFork.Size; + else if (item.IsDir()) + break; + else if (item.CompressHeader.IsCorrect) + size = item.CompressHeader.UnpackSize; + else + size = item.DataFork.Size; + prop = size; + break; + } + case kpidIsDir: prop = (ref.IsItem() && item.IsDir()); break; + case kpidIsAltStream: prop = ref.IsAltStream(); break; + case kpidCTime: HfsTimeToProp(item.CTime, prop); break; + case kpidMTime: HfsTimeToProp(item.MTime, prop); break; + case kpidATime: HfsTimeToProp(item.ATime, prop); break; + case kpidChangeTime: HfsTimeToProp(item.AttrMTime, prop); break; + case kpidPosixAttrib: if (ref.IsItem()) prop = (UInt32)item.FileMode; break; + /* + case kpidUserId: prop = (UInt32)item.OwnerID; break; + case kpidGroupId: prop = (UInt32)item.GroupID; break; + */ + + case kpidMethod: + if (ref.IsItem()) + item.CompressHeader.MethodToProp(prop); + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream, callback)) + _stream = inStream; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _stream.Release(); + Clear(); + return S_OK; +} + +static const UInt32 kCompressionBlockSize = 1 << 16; + +CDecoder::CDecoder(bool IsAdlerOptional) +{ + /* Some new hfs files contain zlib resource fork without Adler checksum. + We do not know how we must detect case where there is Adler + checksum or there is no Adler checksum. + */ + _zlibDecoder->IsAdlerOptional = IsAdlerOptional; + _lzfseDecoder->LzvnMode = true; +} + +HRESULT CDecoder::ExtractResourceFork_ZLIB( + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback) +{ + const unsigned kHeaderSize = 0x100 + 8; + + const size_t kBufSize = kCompressionBlockSize; + _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header + + RINOK(ReadStream_FALSE(inStream, _buf, kHeaderSize)) + Byte *buf = _buf; + const UInt32 dataPos = Get32(buf); + const UInt32 mapPos = Get32(buf + 4); + const UInt32 dataSize = Get32(buf + 8); + const UInt32 mapSize = Get32(buf + 12); + + const UInt32 kResMapSize = 50; + + if (mapSize != kResMapSize + || dataPos > mapPos + || dataSize != mapPos - dataPos + || mapSize > forkSize + || mapPos != forkSize - mapSize) + return S_FALSE; + + const UInt32 dataSize2 = Get32(buf + 0x100); + if (4 + dataSize2 != dataSize + || dataSize2 < 8 + || dataSize2 > dataSize) + return S_FALSE; + + const UInt32 numBlocks = GetUi32(buf + 0x100 + 4); + if (((dataSize2 - 4) >> 3) < numBlocks) + return S_FALSE; + { + const UInt64 up = unpackSize + kCompressionBlockSize - 1; + if (up < unpackSize || up / kCompressionBlockSize != numBlocks) + return S_FALSE; + } + + const UInt32 tableSize = (numBlocks << 3); + + _tableBuf.AllocAtLeast(tableSize); + + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)) + const Byte *tableBuf = _tableBuf; + + UInt32 prev = 4 + tableSize; + + UInt32 i; + for (i = 0; i < numBlocks; i++) + { + const UInt32 offs = GetUi32(tableBuf + i * 8); + const UInt32 size = GetUi32(tableBuf + i * 8 + 4); + if (size == 0 + || prev != offs + || offs > dataSize2 + || size > dataSize2 - offs) + return S_FALSE; + prev = offs + size; + } + + if (prev != dataSize2) + return S_FALSE; + + CMyComPtr2_Create bufInStream; + + // bool padError = false; + UInt64 outPos = 0; + + for (i = 0; i < numBlocks; i++) + { + const UInt64 rem = unpackSize - outPos; + if (rem == 0) + return S_FALSE; + UInt32 blockSize = kCompressionBlockSize; + if (rem < kCompressionBlockSize) + blockSize = (UInt32)rem; + + const UInt32 size = GetUi32(tableBuf + i * 8 + 4); + + if (size > kCompressionBlockSize + 1) + return S_FALSE; + + RINOK(ReadStream_FALSE(inStream, buf, size)) + + if ((buf[0] & 0xF) == 0xF) + { + // (buf[0] = 0xff) is marker of uncompressed block in APFS + // that code was not tested in HFS + if (size - 1 != blockSize) + return S_FALSE; + + if (outStream) + { + RINOK(WriteStream(outStream, buf + 1, blockSize)) + } + } + else + { + const UInt64 blockSize64 = blockSize; + bufInStream->Init(buf, size); + RINOK(_zlibDecoder.Interface()->Code(bufInStream, outStream, NULL, &blockSize64, NULL)) + if (_zlibDecoder->GetOutputProcessedSize() != blockSize) + return S_FALSE; + const UInt64 inSize = _zlibDecoder->GetInputProcessedSize(); + if (inSize != size) + { + if (inSize > size) + return S_FALSE; + // apfs file can contain junk (non-zeros) after data block. + /* + if (!padError) + { + const Byte *p = buf + (UInt32)inSize; + const Byte *e = p + (size - (UInt32)inSize); + do + { + if (*p != 0) + { + padError = true; + break; + } + } + while (++p != e); + } + */ + } + } + + outPos += blockSize; + if ((i & 0xFF) == 0) + { + const UInt64 progressPos = progressStart + outPos; + RINOK(extractCallback->SetCompleted(&progressPos)) + } + } + + if (outPos != unpackSize) + return S_FALSE; + + // if (padError) return S_FALSE; + + /* We check Resource Map + Are there HFS files with another values in Resource Map ??? */ + + RINOK(ReadStream_FALSE(inStream, buf, mapSize)) + const UInt32 types = Get16(buf + 24); + const UInt32 names = Get16(buf + 26); + const UInt32 numTypes = Get16(buf + 28); + if (numTypes != 0 || types != 28 || names != kResMapSize) + return S_FALSE; + const UInt32 resType = Get32(buf + 30); + const UInt32 numResources = Get16(buf + 34); + const UInt32 resListOffset = Get16(buf + 36); + if (resType != 0x636D7066) // cmpf + return S_FALSE; + if (numResources != 0 || resListOffset != 10) + return S_FALSE; + + const UInt32 entryId = Get16(buf + 38); + const UInt32 nameOffset = Get16(buf + 40); + // Byte attrib = buf[42]; + const UInt32 resourceOffset = Get32(buf + 42) & 0xFFFFFF; + if (entryId != 1 || nameOffset != 0xFFFF || resourceOffset != 0) + return S_FALSE; + + return S_OK; +} + + + +HRESULT CDecoder::ExtractResourceFork_LZFSE( + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback) +{ + const UInt32 kNumBlocksMax = (UInt32)1 << 29; + if (unpackSize >= (UInt64)kNumBlocksMax * kCompressionBlockSize) + return S_FALSE; + const UInt32 numBlocks = (UInt32)((unpackSize + kCompressionBlockSize - 1) / kCompressionBlockSize); + const UInt32 numBlocks2 = numBlocks + 1; + const UInt32 tableSize = (numBlocks2 << 2); + if (tableSize > forkSize) + return S_FALSE; + _tableBuf.AllocAtLeast(tableSize); + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)) + const Byte *tableBuf = _tableBuf; + + { + UInt32 prev = GetUi32(tableBuf); + if (prev != tableSize) + return S_FALSE; + for (UInt32 i = 1; i < numBlocks2; i++) + { + const UInt32 offs = GetUi32(tableBuf + i * 4); + if (offs <= prev) + return S_FALSE; + prev = offs; + } + if (prev != forkSize) + return S_FALSE; + } + + const size_t kBufSize = kCompressionBlockSize; + _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header + + CMyComPtr2_Create bufInStream; + + UInt64 outPos = 0; + + for (UInt32 i = 0; i < numBlocks; i++) + { + const UInt64 rem = unpackSize - outPos; + if (rem == 0) + return S_FALSE; + UInt32 blockSize = kCompressionBlockSize; + if (rem < kCompressionBlockSize) + blockSize = (UInt32)rem; + + const UInt32 size = + GetUi32(tableBuf + i * 4 + 4) - + GetUi32(tableBuf + i * 4); + + if (size > kCompressionBlockSize + 1) + return S_FALSE; + + RINOK(ReadStream_FALSE(inStream, _buf, size)) + const Byte *buf = _buf; + + if (buf[0] == k_LZVN_Uncompressed_Marker) + { + if (size - 1 != blockSize) + return S_FALSE; + if (outStream) + { + RINOK(WriteStream(outStream, buf + 1, blockSize)) + } + } + else + { + const UInt64 blockSize64 = blockSize; + const UInt64 packSize64 = size; + bufInStream->Init(buf, size); + RINOK(_lzfseDecoder.Interface()->Code(bufInStream, outStream, &packSize64, &blockSize64, NULL)) + // in/out sizes were checked in Code() + } + + outPos += blockSize; + if ((i & 0xFF) == 0) + { + const UInt64 progressPos = progressStart + outPos; + RINOK(extractCallback->SetCompleted(&progressPos)) + } + } + + return S_OK; +} + + +/* +static UInt32 GetUi24(const Byte *p) +{ + return p[0] + ((UInt32)p[1] << 8) + ((UInt32)p[2] << 24); +} + +HRESULT CDecoder::ExtractResourceFork_ZBM( + ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback) +{ + const UInt32 kNumBlocksMax = (UInt32)1 << 29; + if (unpackSize >= (UInt64)kNumBlocksMax * kCompressionBlockSize) + return S_FALSE; + const UInt32 numBlocks = (UInt32)((unpackSize + kCompressionBlockSize - 1) / kCompressionBlockSize); + const UInt32 numBlocks2 = numBlocks + 1; + const UInt32 tableSize = (numBlocks2 << 2); + if (tableSize > forkSize) + return S_FALSE; + _tableBuf.AllocAtLeast(tableSize); + RINOK(ReadStream_FALSE(inStream, _tableBuf, tableSize)); + const Byte *tableBuf = _tableBuf; + + { + UInt32 prev = GetUi32(tableBuf); + if (prev != tableSize) + return S_FALSE; + for (UInt32 i = 1; i < numBlocks2; i++) + { + const UInt32 offs = GetUi32(tableBuf + i * 4); + if (offs <= prev) + return S_FALSE; + prev = offs; + } + if (prev != forkSize) + return S_FALSE; + } + + const size_t kBufSize = kCompressionBlockSize; + _buf.Alloc(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header + + CBufInStream *bufInStream = new CBufInStream; + CMyComPtr bufInStream = bufInStream; + + UInt64 outPos = 0; + + for (UInt32 i = 0; i < numBlocks; i++) + { + const UInt64 rem = unpackSize - outPos; + if (rem == 0) + return S_FALSE; + UInt32 blockSize = kCompressionBlockSize; + if (rem < kCompressionBlockSize) + blockSize = (UInt32)rem; + + const UInt32 size = + GetUi32(tableBuf + i * 4 + 4) - + GetUi32(tableBuf + i * 4); + + // if (size > kCompressionBlockSize + 1) + if (size > blockSize + 1) + return S_FALSE; // we don't expect it, because encode will use uncompressed chunk + + RINOK(ReadStream_FALSE(inStream, _buf, size)); + const Byte *buf = _buf; + + // (size != 0) + // if (size == 0) return S_FALSE; + + if (buf[0] == 0xFF) // uncompressed marker + { + if (size != blockSize + 1) + return S_FALSE; + if (outStream) + { + RINOK(WriteStream(outStream, buf + 1, blockSize)); + } + } + else + { + if (size < 4) + return S_FALSE; + if (buf[0] != 'Z' || + buf[1] != 'B' || + buf[2] != 'M' || + buf[3] != 9) + return S_FALSE; + // for debug: + unsigned packPos = 4; + unsigned unpackPos = 0; + unsigned packRem = size - packPos; + for (;;) + { + if (packRem < 6) + return S_FALSE; + const UInt32 packSize = GetUi24(buf + packPos); + const UInt32 chunkUnpackSize = GetUi24(buf + packPos + 3); + if (packSize < 6) + return S_FALSE; + if (packSize > packRem) + return S_FALSE; + if (chunkUnpackSize > blockSize - unpackPos) + return S_FALSE; + packPos += packSize; + packRem -= packSize; + unpackPos += chunkUnpackSize; + if (packSize == 6) + { + if (chunkUnpackSize != 0) + return S_FALSE; + break; + } + if (packSize >= chunkUnpackSize + 6) + { + if (packSize > chunkUnpackSize + 6) + return S_FALSE; + // uncompressed chunk; + } + else + { + // compressed chunk + const Byte *t = buf + packPos - packSize + 6; + UInt32 r = packSize - 6; + if (r < 9) + return S_FALSE; + const UInt32 v0 = GetUi24(t); + const UInt32 v1 = GetUi24(t + 3); + const UInt32 v2 = GetUi24(t + 6); + if (v0 > v1 || v1 > v2 || v2 > packSize) + return S_FALSE; + // here we need the code that will decompress ZBM chunk + } + } + + if (unpackPos != blockSize) + return S_FALSE; + + UInt32 size1 = size; + if (size1 > kCompressionBlockSize) + { + size1 = kCompressionBlockSize; + // return S_FALSE; + } + if (outStream) + { + RINOK(WriteStream(outStream, buf, size1)) + + const UInt32 kTempSize = 1 << 16; + Byte temp[kTempSize]; + memset(temp, 0, kTempSize); + + for (UInt32 k = size1; k < kCompressionBlockSize; k++) + { + UInt32 cur = kCompressionBlockSize - k; + if (cur > kTempSize) + cur = kTempSize; + RINOK(WriteStream(outStream, temp, cur)) + k += cur; + } + } + + // const UInt64 blockSize64 = blockSize; + // const UInt64 packSize64 = size; + // bufInStream->Init(buf, size); + // RINOK(_zbmDecoderSpec->Code(bufInStream, outStream, &packSize64, &blockSize64, NULL)); + // in/out sizes were checked in Code() + } + + outPos += blockSize; + if ((i & 0xFF) == 0) + { + const UInt64 progressPos = progressStart + outPos; + RINOK(extractCallback->SetCompleted(&progressPos)); + } + } + + return S_OK; +} +*/ + +HRESULT CDecoder::Extract( + ISequentialInStream *inStreamFork, ISequentialOutStream *realOutStream, + UInt64 forkSize, + const CCompressHeader &compressHeader, + const CByteBuffer *data, + UInt64 progressStart, IArchiveExtractCallback *extractCallback, + int &opRes) +{ + opRes = NExtract::NOperationResult::kDataError; + + if (compressHeader.IsMethod_Uncompressed_Inline()) + { + const size_t packSize = data->Size() - compressHeader.DataPos; + if (realOutStream) + { + RINOK(WriteStream(realOutStream, *data + compressHeader.DataPos, packSize)) + } + opRes = NExtract::NOperationResult::kOK; + return S_OK; + } + + if (compressHeader.Method == kMethod_ZLIB_ATTR || + compressHeader.Method == kMethod_LZVN_ATTR) + { + CMyComPtr2_Create bufInStream; + const size_t packSize = data->Size() - compressHeader.DataPos; + bufInStream->Init(*data + compressHeader.DataPos, packSize); + + if (compressHeader.Method == kMethod_ZLIB_ATTR) + { + const HRESULT hres = _zlibDecoder.Interface()->Code(bufInStream, realOutStream, + NULL, &compressHeader.UnpackSize, NULL); + if (hres == S_OK) + if (_zlibDecoder->GetOutputProcessedSize() == compressHeader.UnpackSize + && _zlibDecoder->GetInputProcessedSize() == packSize) + opRes = NExtract::NOperationResult::kOK; + return hres; + } + { + const UInt64 packSize64 = packSize; + const HRESULT hres = _lzfseDecoder.Interface()->Code(bufInStream, realOutStream, + &packSize64, &compressHeader.UnpackSize, NULL); + if (hres == S_OK) + { + // in/out sizes were checked in Code() + opRes = NExtract::NOperationResult::kOK; + } + return hres; + } + } + + HRESULT hres; + if (compressHeader.Method == NHfs::kMethod_ZLIB_RSRC) + { + hres = ExtractResourceFork_ZLIB( + inStreamFork, realOutStream, + forkSize, compressHeader.UnpackSize, + progressStart, extractCallback); + // for debug: + // hres = NCompress::CopyStream(inStreamFork, realOutStream, NULL); + } + else if (compressHeader.Method == NHfs::kMethod_LZVN_RSRC) + { + hres = ExtractResourceFork_LZFSE( + inStreamFork, realOutStream, + forkSize, compressHeader.UnpackSize, + progressStart, extractCallback); + } + /* + else if (compressHeader.Method == NHfs::kMethod_ZBM_RSRC) + { + hres = ExtractResourceFork_ZBM( + inStreamFork, realOutStream, + forkSize, compressHeader.UnpackSize, + progressStart, extractCallback); + } + */ + else + { + opRes = NExtract::NOperationResult::kUnsupportedMethod; + hres = S_FALSE; + } + + if (hres == S_OK) + opRes = NExtract::NOperationResult::kOK; + return hres; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = Refs.Size(); + if (numItems == 0) + return S_OK; + UInt32 i; + UInt64 totalSize = 0; + for (i = 0; i < numItems; i++) + { + const CRef &ref = Refs[allFilesMode ? i : indices[i]]; + totalSize += Get_UnpackSize_of_Ref(ref); + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 currentTotalSize = 0, currentItemSize = 0; + + const size_t kBufSize = kCompressionBlockSize; + CByteBuffer buf(kBufSize + 0x10); // we need 1 additional bytes for uncompressed chunk header + + // there are hfs without adler in zlib. + CDecoder decoder(true); // IsAdlerOptional + + for (i = 0;; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)) + if (i >= numItems) + break; + const UInt32 index = allFilesMode ? i : indices[i]; + const CRef &ref = Refs[index]; + const CItem &item = Items[ref.ItemIndex]; + currentItemSize = Get_UnpackSize_of_Ref(ref); + + int opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (ref.IsItem() && item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + + UInt64 pos = 0; + opRes = NExtract::NOperationResult::kDataError; + const CFork *fork = NULL; + + if (ref.AttrIndex >= 0) + { + const CAttr &attr = Attrs[ref.AttrIndex]; + if (attr.Fork_defined && attr.Data.Size() == 0) + fork = &attr.Fork; + else + { + opRes = NExtract::NOperationResult::kOK; + if (realOutStream) + { + RINOK(WriteStream(realOutStream, + // AttrBuf + attr.Pos, attr.Size + attr.Data, attr.Data.Size() + )) + } + } + } + else if (ref.IsResource()) + fork = &item.ResourceFork; + else if (item.CompressHeader.IsSupported) + { + CMyComPtr inStreamFork; + UInt64 forkSize = 0; + const CByteBuffer *decmpfs_Data = NULL; + + if (item.CompressHeader.IsMethod_Resource()) + { + const CFork &resourceFork = item.ResourceFork; + forkSize = resourceFork.Size; + GetForkStream(resourceFork, &inStreamFork); + } + else + { + const CAttr &attr = Attrs[item.decmpfs_AttrIndex]; + decmpfs_Data = &attr.Data; + } + + if (inStreamFork || decmpfs_Data) + { + const HRESULT hres = decoder.Extract( + inStreamFork, realOutStream, + forkSize, + item.CompressHeader, + decmpfs_Data, + currentTotalSize, extractCallback, + opRes); + if (hres != S_FALSE && hres != S_OK) + return hres; + } + } + else if (item.CompressHeader.IsCorrect) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + fork = &item.DataFork; + + if (fork) + { + if (fork->IsOk(Header.BlockSizeLog)) + { + opRes = NExtract::NOperationResult::kOK; + unsigned extentIndex; + for (extentIndex = 0; extentIndex < fork->Extents.Size(); extentIndex++) + { + if (opRes != NExtract::NOperationResult::kOK) + break; + if (fork->Size == pos) + break; + const CExtent &e = fork->Extents[extentIndex]; + RINOK(InStream_SeekSet(_stream, SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog))) + UInt64 extentRem = (UInt64)e.NumBlocks << Header.BlockSizeLog; + while (extentRem != 0) + { + const UInt64 rem = fork->Size - pos; + if (rem == 0) + { + // Here we check that there are no extra (empty) blocks in last extent. + if (extentRem >= ((UInt64)1 << Header.BlockSizeLog)) + opRes = NExtract::NOperationResult::kDataError; + break; + } + size_t cur = kBufSize; + if (cur > rem) + cur = (size_t)rem; + if (cur > extentRem) + cur = (size_t)extentRem; + RINOK(ReadStream(_stream, buf, &cur)) + if (cur == 0) + { + opRes = NExtract::NOperationResult::kDataError; + break; + } + if (realOutStream) + { + RINOK(WriteStream(realOutStream, buf, cur)) + } + pos += cur; + extentRem -= cur; + const UInt64 processed = currentTotalSize + pos; + RINOK(extractCallback->SetCompleted(&processed)) + } + } + if (extentIndex != fork->Extents.Size() || fork->Size != pos) + opRes = NExtract::NOperationResult::kDataError; + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Refs.Size(); + return S_OK; +} + +HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream) +{ + *stream = NULL; + + if (!fork.IsOk(Header.BlockSizeLog)) + return S_FALSE; + + CMyComPtr2 extentStream; + extentStream.Create_if_Empty(); + + UInt64 rem = fork.Size; + UInt64 virt = 0; + + FOR_VECTOR (i, fork.Extents) + { + const CExtent &e = fork.Extents[i]; + if (e.NumBlocks == 0) + continue; + UInt64 cur = ((UInt64)e.NumBlocks << Header.BlockSizeLog); + if (cur > rem) + { + cur = rem; + if (i != fork.Extents.Size() - 1) + return S_FALSE; + } + CSeekExtent se; + se.Phy = SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog); + se.Virt = virt; + virt += cur; + rem -= cur; + extentStream->Extents.Add(se); + } + + if (rem != 0) + return S_FALSE; + + CSeekExtent se; + se.Phy = 0; // = SpecOffset ? + se.Virt = virt; + extentStream->Extents.Add(se); + extentStream->Stream = _stream; + extentStream->Init(); + *stream = extentStream.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + *stream = NULL; + + const CRef &ref = Refs[index]; + const CFork *fork = NULL; + if (ref.AttrIndex >= 0) + { + const CAttr &attr = Attrs[ref.AttrIndex]; + if (!attr.Fork_defined || attr.Data.Size() != 0) + return S_FALSE; + fork = &attr.Fork; + } + else + { + const CItem &item = Items[ref.ItemIndex]; + if (ref.IsResource()) + fork = &item.ResourceFork; + else if (item.IsDir()) + return S_FALSE; + else if (item.CompressHeader.IsCorrect) + return S_FALSE; + else + fork = &item.DataFork; + } + return GetForkStream(*fork, stream); +} + +static const Byte k_Signature[] = { + 2, 'B', 'D', + 4, 'H', '+', 0, 4, + 4, 'H', 'X', 0, 5 }; + +REGISTER_ARC_I( + "HFS", "hfs hfsx", NULL, 0xE3, + k_Signature, + kHeaderPadSize, + NArcInfoFlags::kMultiSignature, + IsArc_HFS) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/HfsHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/HfsHandler.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/HfsHandler.h 2023-12-11 16:00:00.000000000 +0000 @@ -0,0 +1,87 @@ +// HfsHandler.h + +#ifndef ZIP7_INC_HFS_HANDLER_H +#define ZIP7_INC_HFS_HANDLER_H + +#include "../../Windows/PropVariant.h" + +#include "../Compress/LzfseDecoder.h" +#include "../Compress/ZlibDecoder.h" + +namespace NArchive { +namespace NHfs { + +static const UInt32 k_decmpfs_HeaderSize = 16; + +struct CCompressHeader +{ + UInt64 UnpackSize; + UInt32 Method; + Byte DataPos; + bool IsCorrect; + bool IsSupported; + bool IsResource; + + bool IsMethod_Compressed_Inline() const { return DataPos == k_decmpfs_HeaderSize; } + bool IsMethod_Uncompressed_Inline() const { return DataPos == k_decmpfs_HeaderSize + 1; } + bool IsMethod_Resource() const { return IsResource; } + + void Parse(const Byte *p, size_t size); + + void Clear() + { + UnpackSize = 0; + Method = 0; + DataPos = 0; + IsCorrect = false; + IsSupported = false; + IsResource = false; + } + + CCompressHeader() { Clear(); } + + void MethodToProp(NWindows::NCOM::CPropVariant &prop) const; +}; + +void MethodsMaskToProp(UInt32 methodsMask, NWindows::NCOM::CPropVariant &prop); + + +class CDecoder +{ + CMyComPtr2_Create _zlibDecoder; + CMyComPtr2_Create _lzfseDecoder; + + CByteBuffer _tableBuf; + CByteBuffer _buf; + + HRESULT ExtractResourceFork_ZLIB( + ISequentialInStream *inStream, ISequentialOutStream *realOutStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback); + + HRESULT ExtractResourceFork_LZFSE( + ISequentialInStream *inStream, ISequentialOutStream *realOutStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback); + + HRESULT ExtractResourceFork_ZBM( + ISequentialInStream *inStream, ISequentialOutStream *realOutStream, + UInt64 forkSize, UInt64 unpackSize, + UInt64 progressStart, IArchiveExtractCallback *extractCallback); + +public: + + HRESULT Extract( + ISequentialInStream *inStreamFork, ISequentialOutStream *realOutStream, + UInt64 forkSize, + const CCompressHeader &compressHeader, + const CByteBuffer *data, + UInt64 progressStart, IArchiveExtractCallback *extractCallback, + int &opRes); + + CDecoder(bool IsAdlerOptional); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/IArchive.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IArchive.h --- p7zip-rar-16.02/CPP/7zip/Archive/IArchive.h 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IArchive.h 2024-03-20 06:00:00.000000000 +0000 @@ -1,598 +1,754 @@ -// IArchive.h - -#ifndef __IARCHIVE_H -#define __IARCHIVE_H - -#include "../IProgress.h" -#include "../IStream.h" -#include "../PropID.h" - -#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x) -#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) - -namespace NFileTimeType -{ - enum EEnum - { - kWindows, - kUnix, - kDOS - }; -} - -namespace NArcInfoFlags -{ - const UInt32 kKeepName = 1 << 0; // keep name of file in archive name - const UInt32 kAltStreams = 1 << 1; // the handler supports alt streams - const UInt32 kNtSecure = 1 << 2; // the handler supports NT security - const UInt32 kFindSignature = 1 << 3; // the handler can find start of archive - const UInt32 kMultiSignature = 1 << 4; // there are several signatures - const UInt32 kUseGlobalOffset = 1 << 5; // the seek position of stream must be set as global offset - const UInt32 kStartOpen = 1 << 6; // call handler for each start position - const UInt32 kPureStartOpen = 1 << 7; // call handler only for start of file - const UInt32 kBackwardOpen = 1 << 8; // archive can be open backward - const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub) - const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links - const UInt32 kHardLinks = 1 << 11; // the handler supports hard links -} - -namespace NArchive -{ - namespace NHandlerPropID - { - enum - { - kName = 0, // VT_BSTR - kClassID, // binary GUID in VT_BSTR - kExtension, // VT_BSTR - kAddExtension, // VT_BSTR - kUpdate, // VT_BOOL - kKeepName, // VT_BOOL - kSignature, // binary in VT_BSTR - kMultiSignature, // binary in VT_BSTR - kSignatureOffset, // VT_UI4 - kAltStreams, // VT_BOOL - kNtSecure, // VT_BOOL - kFlags // VT_UI4 - // kVersion // VT_UI4 ((VER_MAJOR << 8) | VER_MINOR) - }; - } - - namespace NExtract - { - namespace NAskMode - { - enum - { - kExtract = 0, - kTest, - kSkip - }; - } - - namespace NOperationResult - { - enum - { - kOK = 0, - kUnsupportedMethod, - kDataError, - kCRCError, - kUnavailable, - kUnexpectedEnd, - kDataAfterEnd, - kIsNotArc, - kHeadersError, - kWrongPassword - }; - } - } - - namespace NEventIndexType - { - enum - { - kNoIndex = 0, - kInArcIndex, - kBlockIndex, - kOutArcIndex - }; - } - - namespace NUpdate - { - namespace NOperationResult - { - enum - { - kOK = 0 - , // kError - }; - } - } -} - -#define INTERFACE_IArchiveOpenCallback(x) \ - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) x; \ - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) x; \ - -ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) -{ - INTERFACE_IArchiveOpenCallback(PURE); -}; - -/* -IArchiveExtractCallback:: - -7-Zip doesn't call IArchiveExtractCallback functions - GetStream() - PrepareOperation() - SetOperationResult() -from different threads simultaneously. -But 7-Zip can call functions for IProgress or ICompressProgressInfo functions -from another threads simultaneously with calls for IArchiveExtractCallback interface. - -IArchiveExtractCallback::GetStream() - UInt32 index - index of item in Archive - Int32 askExtractMode (Extract::NAskMode) - if (askMode != NExtract::NAskMode::kExtract) - { - then the callee can not real stream: (*inStream == NULL) - } - - Out: - (*inStream == NULL) - for directories - (*inStream == NULL) - if link (hard link or symbolic link) was created - if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract) - { - then the caller must skip extracting of that file. - } - - returns: - S_OK : OK - S_FALSE : data error (for decoders) - -if (IProgress::SetTotal() was called) -{ - IProgress::SetCompleted(completeValue) uses - packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd). - unpackSize - for another formats. -} -else -{ - IProgress::SetCompleted(completeValue) uses packSize. -} - -SetOperationResult() - 7-Zip calls SetOperationResult at the end of extracting, - so the callee can close the file, set attributes, timestamps and security information. - - Int32 opRes (NExtract::NOperationResult) -*/ - -#define INTERFACE_IArchiveExtractCallback(x) \ - INTERFACE_IProgress(x) \ - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) x; \ - STDMETHOD(PrepareOperation)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) -{ - INTERFACE_IArchiveExtractCallback(PURE) -}; - - - -/* -IArchiveExtractCallbackMessage can be requested from IArchiveExtractCallback object - by Extract() or UpdateItems() functions to report about extracting errors -ReportExtractResult() - UInt32 indexType (NEventIndexType) - UInt32 index - Int32 opRes (NExtract::NOperationResult) -*/ - -#define INTERFACE_IArchiveExtractCallbackMessage(x) \ - STDMETHOD(ReportExtractResult)(UInt32 indexType, UInt32 index, Int32 opRes) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) -{ - INTERFACE_IArchiveExtractCallbackMessage(PURE) -}; - - -#define INTERFACE_IArchiveOpenVolumeCallback(x) \ - STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) x; \ - -ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) -{ - INTERFACE_IArchiveOpenVolumeCallback(PURE); -}; - - -ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) -{ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; -}; - - -ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) -{ - STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; -}; - - -/* -IInArchive::Open - stream - if (kUseGlobalOffset), stream current position can be non 0. - if (!kUseGlobalOffset), stream current position is 0. - if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream - if (*maxCheckStartPosition == 0), the handler must check only current position as archive start - -IInArchive::Extract: - indices must be sorted - numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files" - testMode != 0 means "test files without writing to outStream" - -IInArchive::GetArchiveProperty: - kpidOffset - start offset of archive. - VT_EMPTY : means offset = 0. - VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed - kpidPhySize - size of archive. VT_EMPTY means unknown size. - kpidPhySize is allowed to be larger than file size. In that case it must show - supposed size. - - kpidIsDeleted: - kpidIsAltStream: - kpidIsAux: - kpidINode: - must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty. - - -Notes: - Don't call IInArchive functions for same IInArchive object from different threads simultaneously. - Some IInArchive handlers will work incorrectly in that case. -*/ - -#ifdef _MSC_VER - #define MY_NO_THROW_DECL_ONLY throw() -#else - #define MY_NO_THROW_DECL_ONLY -#endif - -#define INTERFACE_IInArchive(x) \ - STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Close)() MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProps) MY_NO_THROW_DECL_ONLY x; \ - STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) MY_NO_THROW_DECL_ONLY x; \ - -ARCHIVE_INTERFACE(IInArchive, 0x60) -{ - INTERFACE_IInArchive(PURE) -}; - -namespace NParentType -{ - enum - { - kDir = 0, - kAltStream - }; -}; - -namespace NPropDataType -{ - const UInt32 kMask_ZeroEnd = 1 << 4; - // const UInt32 kMask_BigEndian = 1 << 5; - const UInt32 kMask_Utf = 1 << 6; - const UInt32 kMask_Utf8 = kMask_Utf | 0; - const UInt32 kMask_Utf16 = kMask_Utf | 1; - // const UInt32 kMask_Utf32 = kMask_Utf | 2; - - const UInt32 kNotDefined = 0; - const UInt32 kRaw = 1; - - const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd; - const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; -}; - -// UTF string (pointer to wchar_t) with zero end and little-endian. -#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1)) - -/* -GetRawProp: - Result: - S_OK - even if property is not set -*/ - -#define INTERFACE_IArchiveGetRawProps(x) \ - STDMETHOD(GetParent)(UInt32 index, UInt32 *parent, UInt32 *parentType) x; \ - STDMETHOD(GetRawProp)(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ - STDMETHOD(GetNumRawProps)(UInt32 *numProps) x; \ - STDMETHOD(GetRawPropInfo)(UInt32 index, BSTR *name, PROPID *propID) x; - -ARCHIVE_INTERFACE(IArchiveGetRawProps, 0x70) -{ - INTERFACE_IArchiveGetRawProps(PURE) -}; - -#define INTERFACE_IArchiveGetRootProps(x) \ - STDMETHOD(GetRootProp)(PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetRootRawProp)(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) x; \ - -ARCHIVE_INTERFACE(IArchiveGetRootProps, 0x71) -{ - INTERFACE_IArchiveGetRootProps(PURE) -}; - -ARCHIVE_INTERFACE(IArchiveOpenSeq, 0x61) -{ - STDMETHOD(OpenSeq)(ISequentialInStream *stream) PURE; -}; - -/* - OpenForSize - Result: - S_FALSE - is not archive - ? - DATA error -*/ - -/* -const UInt32 kOpenFlags_RealPhySize = 1 << 0; -const UInt32 kOpenFlags_NoSeek = 1 << 1; -// const UInt32 kOpenFlags_BeforeExtract = 1 << 2; -*/ - -/* -Flags: - 0 - opens archive with IInStream, if IInStream interface is supported - - if phySize is not available, it doesn't try to make full parse to get phySize - kOpenFlags_NoSeek - ArcOpen2 function doesn't use IInStream interface, even if it's available - kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file - - if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified, - the handler can return S_OK, but it doesn't check even Signature. - So next Extract can be called for that sequential stream. -*/ - -/* -ARCHIVE_INTERFACE(IArchiveOpen2, 0x62) -{ - STDMETHOD(ArcOpen2)(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback) PURE; -}; -*/ - -// ---------- UPDATE ---------- - -/* -GetUpdateItemInfo outs: -*newData *newProps - 0 0 - Copy data and properties from archive - 0 1 - Copy data from archive, request new properties - 1 0 - that combination is unused now - 1 1 - Request new data and new properties. It can be used even for folders - - indexInArchive = -1 if there is no item in archive, or if it doesn't matter. - - -GetStream out: - Result: - S_OK: - (*inStream == NULL) - only for directories - - the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file - (*inStream != NULL) - for any file, even for empty file or anti-file - S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason) - (*inStream == NULL) - -The order of calling for hard links: - - GetStream() - - GetProperty(kpidHardLink) - -SetOperationResult() - Int32 opRes (NExtract::NOperationResult::kOK) -*/ - -#define INTERFACE_IArchiveUpdateCallback(x) \ - INTERFACE_IProgress(x); \ - STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) x; \ - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) x; \ - STDMETHOD(SetOperationResult)(Int32 operationResult) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) -{ - INTERFACE_IArchiveUpdateCallback(PURE); -}; - -#define INTERFACE_IArchiveUpdateCallback2(x) \ - INTERFACE_IArchiveUpdateCallback(x) \ - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) x; \ - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) x; \ - -ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) -{ - INTERFACE_IArchiveUpdateCallback2(PURE); -}; - -namespace NUpdateNotifyOp -{ - enum - { - kAdd = 0, - kUpdate, - kAnalyze, - kReplicate, - kRepack, - kSkip, - kDelete, - kHeader - - // kNumDefined - }; -}; - -/* -IArchiveUpdateCallbackFile::ReportOperation - UInt32 indexType (NEventIndexType) - UInt32 index - UInt32 notifyOp (NUpdateNotifyOp) -*/ - -#define INTERFACE_IArchiveUpdateCallbackFile(x) \ - STDMETHOD(GetStream2)(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp) x; \ - STDMETHOD(ReportOperation)(UInt32 indexType, UInt32 index, UInt32 notifyOp) x; \ - -ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83) -{ - INTERFACE_IArchiveUpdateCallbackFile(PURE); -}; - - -/* -UpdateItems() -------------- - - outStream: output stream. (the handler) MUST support the case when - Seek position in outStream is not ZERO. - but the caller calls with empty outStream and seek position is ZERO?? - - archives with stub: - - If archive is open and the handler and (Offset > 0), then the handler - knows about stub size. - UpdateItems(): - 1) the handler MUST copy that stub to outStream - 2) the caller MUST NOT copy the stub to outStream, if - "rsfx" property is set with SetProperties - - the handler must support the case where - ISequentialOutStream *outStream -*/ - - -#define INTERFACE_IOutArchive(x) \ - STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(GetFileTimeType)(UInt32 *type) x; - -ARCHIVE_INTERFACE(IOutArchive, 0xA0) -{ - INTERFACE_IOutArchive(PURE) -}; - - -ARCHIVE_INTERFACE(ISetProperties, 0x03) -{ - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) PURE; -}; - -ARCHIVE_INTERFACE(IArchiveKeepModeForNextOpen, 0x04) -{ - STDMETHOD(KeepModeForNextOpen)() PURE; -}; - -/* Exe handler: the handler for executable format (PE, ELF, Mach-O). - SFX archive: executable stub + some tail data. - before 9.31: exe handler didn't parse SFX archives as executable format. - for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */ - -ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05) -{ - STDMETHOD(AllowTail)(Int32 allowTail) PURE; -}; - - -#define IMP_IInArchive_GetProp(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ - - -struct CStatProp -{ - const char *Name; - UInt32 PropID; - VARTYPE vt; -}; - -namespace NWindows { -namespace NCOM { -// PropVariant.cpp -BSTR AllocBstrFromAscii(const char *s) throw(); -}} - -#define IMP_IInArchive_GetProp_WITH_NAME(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - const CStatProp &prop = k[index]; \ - *propID = (PROPID)prop.PropID; *varType = prop.vt; \ - *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \ - -#define IMP_IInArchive_Props \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps) - -#define IMP_IInArchive_Props_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps) - - -#define IMP_IInArchive_ArcProps \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps) - -#define IMP_IInArchive_ArcProps_WITH_NAME \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = ARRAY_SIZE(kArcProps); return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kArcProps) - -#define IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProps) \ - { *numProps = 0; return S_OK; } \ - STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \ - { return E_NOTIMPL; } \ - -#define IMP_IInArchive_ArcProps_NO \ - IMP_IInArchive_ArcProps_NO_Table \ - STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \ - { value->vt = VT_EMPTY; return S_OK; } - - - -#define k_IsArc_Res_NO 0 -#define k_IsArc_Res_YES 1 -#define k_IsArc_Res_NEED_MORE 2 -// #define k_IsArc_Res_YES_LOW_PROB 3 - -#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI -#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI - -extern "C" -{ - typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject); - - typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size); - typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc); - - typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats); - typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value); - typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value); - - typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive); - typedef HRESULT (WINAPI *Func_SetLargePageMode)(); - - typedef IOutArchive * (*Func_CreateOutArchive)(); - typedef IInArchive * (*Func_CreateInArchive)(); -} - -#endif +// IArchive.h + +#ifndef ZIP7_INC_IARCHIVE_H +#define ZIP7_INC_IARCHIVE_H + +#include "../IProgress.h" +#include "../IStream.h" +#include "../PropID.h" + +Z7_PURE_INTERFACES_BEGIN + + +#define Z7_IFACE_CONSTR_ARCHIVE_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 6, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_ARCHIVE(i, n) \ + Z7_IFACE_CONSTR_ARCHIVE_SUB(i, IUnknown, n) + +/* +How the function in 7-Zip returns object for output parameter via pointer + +1) The caller sets the value of variable before function call: + PROPVARIANT : vt = VT_EMPTY + BSTR : NULL + IUnknown* and derived interfaces : NULL + another scalar types : any non-initialized value is allowed + +2) The callee in current 7-Zip code now can free input object for output parameter: + PROPVARIANT : the callee calls VariantClear(propvaiant_ptr) for input + value stored in variable + another types : the callee ignores stored value. + +3) The callee writes new value to variable for output parameter and + returns execution to caller. + +4) The caller must free or release object returned by the callee: + PROPVARIANT : VariantClear(&propvaiant) + BSTR : SysFreeString(bstr) + IUnknown* and derived interfaces : if (ptr) ptr->Relase() +*/ + + +namespace NFileTimeType +{ + enum EEnum + { + kNotDefined = -1, + kWindows = 0, + kUnix, + kDOS, + k1ns + }; +} + +namespace NArcInfoFlags +{ + const UInt32 kKeepName = 1 << 0; // keep name of file in archive name + const UInt32 kAltStreams = 1 << 1; // the handler supports alt streams + const UInt32 kNtSecure = 1 << 2; // the handler supports NT security + const UInt32 kFindSignature = 1 << 3; // the handler can find start of archive + const UInt32 kMultiSignature = 1 << 4; // there are several signatures + const UInt32 kUseGlobalOffset = 1 << 5; // the seek position of stream must be set as global offset + const UInt32 kStartOpen = 1 << 6; // call handler for each start position + const UInt32 kPureStartOpen = 1 << 7; // call handler only for start of file + const UInt32 kBackwardOpen = 1 << 8; // archive can be open backward + const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub) + const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links + const UInt32 kHardLinks = 1 << 11; // the handler supports hard links + const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches + const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums) + const UInt32 kCTime = 1 << 14; + const UInt32 kCTime_Default = 1 << 15; + const UInt32 kATime = 1 << 16; + const UInt32 kATime_Default = 1 << 17; + const UInt32 kMTime = 1 << 18; + const UInt32 kMTime_Default = 1 << 19; + // const UInt32 kTTime_Reserved = 1 << 20; + // const UInt32 kTTime_Reserved_Default = 1 << 21; +} + +namespace NArcInfoTimeFlags +{ + const unsigned kTime_Prec_Mask_bit_index = 0; + const unsigned kTime_Prec_Mask_num_bits = 26; + + const unsigned kTime_Prec_Default_bit_index = 27; + const unsigned kTime_Prec_Default_num_bits = 5; +} + +#define TIME_PREC_TO_ARC_FLAGS_MASK(v) \ + ((UInt32)1 << (NArcInfoTimeFlags::kTime_Prec_Mask_bit_index + (v))) + +#define TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT(v) \ + ((UInt32)(v) << NArcInfoTimeFlags::kTime_Prec_Default_bit_index) + +namespace NArchive +{ + namespace NHandlerPropID + { + enum + { + kName = 0, // VT_BSTR + kClassID, // binary GUID in VT_BSTR + kExtension, // VT_BSTR + kAddExtension, // VT_BSTR + kUpdate, // VT_BOOL + kKeepName, // VT_BOOL + kSignature, // binary in VT_BSTR + kMultiSignature, // binary in VT_BSTR + kSignatureOffset, // VT_UI4 + kAltStreams, // VT_BOOL + kNtSecure, // VT_BOOL + kFlags, // VT_UI4 + kTimeFlags // VT_UI4 + }; + } + + namespace NExtract + { + namespace NAskMode + { + enum + { + kExtract = 0, + kTest, + kSkip, + kReadExternal + }; + } + + namespace NOperationResult + { + enum + { + kOK = 0, + kUnsupportedMethod, + kDataError, + kCRCError, + kUnavailable, + kUnexpectedEnd, + kDataAfterEnd, + kIsNotArc, + kHeadersError, + kWrongPassword + // , kMemError + }; + } + } + + namespace NEventIndexType + { + enum + { + kNoIndex = 0, + kInArcIndex, + kBlockIndex, + kOutArcIndex + // kArcProp + }; + } + + namespace NUpdate + { + namespace NOperationResult + { + enum + { + kOK = 0 + // kError = 1, + // kError_FileChanged + }; + } + } +} + +#define Z7_IFACEM_IArchiveOpenCallback(x) \ + x(SetTotal(const UInt64 *files, const UInt64 *bytes)) \ + x(SetCompleted(const UInt64 *files, const UInt64 *bytes)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenCallback, 0x10) + +/* +IArchiveExtractCallback:: + +7-Zip doesn't call IArchiveExtractCallback functions + GetStream() + PrepareOperation() + SetOperationResult() +from different threads simultaneously. +But 7-Zip can call functions for IProgress or ICompressProgressInfo functions +from another threads simultaneously with calls for IArchiveExtractCallback interface. + +IArchiveExtractCallback::GetStream() + UInt32 index - index of item in Archive + Int32 askExtractMode (Extract::NAskMode) + if (askMode != NExtract::NAskMode::kExtract) + { + then the callee doesn't write data to stream: (*outStream == NULL) + } + + Out: + (*outStream == NULL) - for directories + (*outStream == NULL) - if link (hard link or symbolic link) was created + if (*outStream == NULL && askMode == NExtract::NAskMode::kExtract) + { + then the caller must skip extracting of that file. + } + + returns: + S_OK : OK + S_FALSE : data error (for decoders) + +if (IProgress::SetTotal() was called) +{ + IProgress::SetCompleted(completeValue) uses + packSize - for some stream formats (xz, gz, bz2, lzma, z, ppmd). + unpackSize - for another formats. +} +else +{ + IProgress::SetCompleted(completeValue) uses packSize. +} + +SetOperationResult() + 7-Zip calls SetOperationResult at the end of extracting, + so the callee can close the file, set attributes, timestamps and security information. + + Int32 opRes (NExtract::NOperationResult) +*/ + +// INTERFACE_IProgress(x) + +#define Z7_IFACEM_IArchiveExtractCallback(x) \ + x(GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) \ + x(PrepareOperation(Int32 askExtractMode)) \ + x(SetOperationResult(Int32 opRes)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallback, IProgress, 0x20) + + + +/* +v23: +IArchiveExtractCallbackMessage2 can be requested from IArchiveExtractCallback object + by Extract() or UpdateItems() functions to report about extracting errors +ReportExtractResult() + UInt32 indexType (NEventIndexType) + UInt32 index + Int32 opRes (NExtract::NOperationResult) +*/ +/* +before v23: +#define Z7_IFACEM_IArchiveExtractCallbackMessage(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveExtractCallbackMessage, IProgress, 0x21) +*/ +#define Z7_IFACEM_IArchiveExtractCallbackMessage2(x) \ + x(ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveExtractCallbackMessage2, 0x22) + +#define Z7_IFACEM_IArchiveOpenVolumeCallback(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetStream(const wchar_t *name, IInStream **inStream)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenVolumeCallback, 0x30) + + +#define Z7_IFACEM_IInArchiveGetStream(x) \ + x(GetStream(UInt32 index, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_ARCHIVE(IInArchiveGetStream, 0x40) + +#define Z7_IFACEM_IArchiveOpenSetSubArchiveName(x) \ + x(SetSubArchiveName(const wchar_t *name)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSetSubArchiveName, 0x50) + + +/* +IInArchive::Open + stream + if (kUseGlobalOffset), stream current position can be non 0. + if (!kUseGlobalOffset), stream current position is 0. + if (maxCheckStartPosition == NULL), the handler can try to search archive start in stream + if (*maxCheckStartPosition == 0), the handler must check only current position as archive start + +IInArchive::Extract: + indices must be sorted + numItems = (UInt32)(Int32)-1 = 0xFFFFFFFF means "all files" + testMode != 0 means "test files without writing to outStream" + +IInArchive::GetArchiveProperty: + kpidOffset - start offset of archive. + VT_EMPTY : means offset = 0. + VT_UI4, VT_UI8, VT_I8 : result offset; negative values is allowed + kpidPhySize - size of archive. VT_EMPTY means unknown size. + kpidPhySize is allowed to be larger than file size. In that case it must show + supposed size. + + kpidIsDeleted: + kpidIsAltStream: + kpidIsAux: + kpidINode: + must return VARIANT_TRUE (VT_BOOL), if archive can support that property in GetProperty. + + +Notes: + Don't call IInArchive functions for same IInArchive object from different threads simultaneously. + Some IInArchive handlers will work incorrectly in that case. +*/ + +#if defined(_MSC_VER) && !defined(__clang__) + #define MY_NO_THROW_DECL_ONLY Z7_COM7F_E +#else + #define MY_NO_THROW_DECL_ONLY +#endif + +#define Z7_IFACEM_IInArchive(x) \ + x(Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback)) \ + x(Close()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(Extract(const UInt32 *indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback)) \ + x(GetArchiveProperty(PROPID propID, PROPVARIANT *value)) \ + x(GetNumberOfProperties(UInt32 *numProps)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetNumberOfArchiveProperties(UInt32 *numProps)) \ + x(GetArchivePropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IInArchive, 0x60) + +namespace NParentType +{ + enum + { + kDir = 0, + kAltStream + }; +} + +namespace NPropDataType +{ + const UInt32 kMask_ZeroEnd = 1 << 4; + // const UInt32 kMask_BigEndian = 1 << 5; + const UInt32 kMask_Utf = 1 << 6; + const UInt32 kMask_Utf8 = kMask_Utf | 0; + const UInt32 kMask_Utf16 = kMask_Utf | 1; + // const UInt32 kMask_Utf32 = kMask_Utf | 2; + + const UInt32 kNotDefined = 0; + const UInt32 kRaw = 1; + + const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd; + const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; +} + +// UTF string (pointer to wchar_t) with zero end and little-endian. +#define PROP_DATA_TYPE_wchar_t_PTR_Z_LE ((NPropDataType::kMask_Utf | NPropDataType::kMask_ZeroEnd) + (sizeof(wchar_t) >> 1)) + + +/* +GetRawProp: + Result: + S_OK - even if property is not set +*/ + +#define Z7_IFACEM_IArchiveGetRawProps(x) \ + x(GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) \ + x(GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ + x(GetNumRawProps(UInt32 *numProps)) \ + x(GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRawProps, 0x70) + +#define Z7_IFACEM_IArchiveGetRootProps(x) \ + x(GetRootProp(PROPID propID, PROPVARIANT *value)) \ + x(GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetRootProps, 0x71) + +#define Z7_IFACEM_IArchiveOpenSeq(x) \ + x(OpenSeq(ISequentialInStream *stream)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpenSeq, 0x61) + +/* + OpenForSize + Result: + S_FALSE - is not archive + ? - DATA error +*/ + +/* +const UInt32 kOpenFlags_RealPhySize = 1 << 0; +const UInt32 kOpenFlags_NoSeek = 1 << 1; +// const UInt32 kOpenFlags_BeforeExtract = 1 << 2; +*/ + +/* +Flags: + 0 - opens archive with IInStream, if IInStream interface is supported + - if phySize is not available, it doesn't try to make full parse to get phySize + kOpenFlags_NoSeek - ArcOpen2 function doesn't use IInStream interface, even if it's available + kOpenFlags_RealPhySize - the handler will try to get PhySize, even if it requires full decompression for file + + if handler is not allowed to use IInStream and the flag kOpenFlags_RealPhySize is not specified, + the handler can return S_OK, but it doesn't check even Signature. + So next Extract can be called for that sequential stream. +*/ +/* +#define Z7_IFACEM_IArchiveOpen2(x) \ + x(ArcOpen2(ISequentialInStream *stream, UInt32 flags, IArchiveOpenCallback *openCallback)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveOpen2, 0x62) +*/ + +// ---------- UPDATE ---------- + +/* +GetUpdateItemInfo outs: +*newData *newProps + 0 0 - Copy data and properties from archive + 0 1 - Copy data from archive, request new properties + 1 0 - that combination is unused now + 1 1 - Request new data and new properties. It can be used even for folders + + indexInArchive = -1 if there is no item in archive, or if it doesn't matter. + + +GetStream out: + Result: + S_OK: + (*inStream == NULL) - only for directories + - the bug was fixed in 9.33: (*Stream == NULL) was in case of anti-file + (*inStream != NULL) - for any file, even for empty file or anti-file + S_FALSE - skip that file (don't add item to archive) - (client code can't open stream of that file by some reason) + (*inStream == NULL) + +The order of calling for hard links: + - GetStream() + - GetProperty(kpidHardLink) + +SetOperationResult() + Int32 opRes (NExtract::NOperationResult::kOK) +*/ + +// INTERFACE_IProgress(x) +#define Z7_IFACEM_IArchiveUpdateCallback(x) \ + x(GetUpdateItemInfo(UInt32 index, Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(GetStream(UInt32 index, ISequentialInStream **inStream)) \ + x(SetOperationResult(Int32 operationResult)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback, IProgress, 0x80) + +// INTERFACE_IArchiveUpdateCallback(x) +#define Z7_IFACEM_IArchiveUpdateCallback2(x) \ + x(GetVolumeSize(UInt32 index, UInt64 *size)) \ + x(GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) \ + +Z7_IFACE_CONSTR_ARCHIVE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) + +namespace NUpdateNotifyOp +{ + enum + { + kAdd = 0, + kUpdate, + kAnalyze, + kReplicate, + kRepack, + kSkip, + kDelete, + kHeader, + kHashRead, + kInFileChanged + // , kOpFinished + // , kNumDefined + }; +} + +/* +IArchiveUpdateCallbackFile::ReportOperation + UInt32 indexType (NEventIndexType) + UInt32 index + UInt32 notifyOp (NUpdateNotifyOp) +*/ + +#define Z7_IFACEM_IArchiveUpdateCallbackFile(x) \ + x(GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 notifyOp)) \ + x(ReportOperation(UInt32 indexType, UInt32 index, UInt32 notifyOp)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackFile, 0x83) + + +#define Z7_IFACEM_IArchiveGetDiskProperty(x) \ + x(GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveGetDiskProperty, 0x84) + +/* +#define Z7_IFACEM_IArchiveUpdateCallbackArcProp(x) \ + x(ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) \ + x(ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) \ + x(ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) \ + x(DoNeedArcProp(PROPID propID, Int32 *answer)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveUpdateCallbackArcProp, 0x85) +*/ + +/* +UpdateItems() +------------- + + outStream: output stream. (the handler) MUST support the case when + Seek position in outStream is not ZERO. + but the caller calls with empty outStream and seek position is ZERO?? + + archives with stub: + + If archive is open and the handler and (Offset > 0), then the handler + knows about stub size. + UpdateItems(): + 1) the handler MUST copy that stub to outStream + 2) the caller MUST NOT copy the stub to outStream, if + "rsfx" property is set with SetProperties + + the handler must support the case where + ISequentialOutStream *outStream +*/ + + +#define Z7_IFACEM_IOutArchive(x) \ + x(UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback)) \ + x(GetFileTimeType(UInt32 *type)) + +Z7_IFACE_CONSTR_ARCHIVE(IOutArchive, 0xA0) + + +/* +ISetProperties::SetProperties() + PROPVARIANT values[i].vt: + VT_EMPTY + VT_BOOL + VT_UI4 - if 32-bit number + VT_UI8 - if 64-bit number + VT_BSTR +*/ + +#define Z7_IFACEM_ISetProperties(x) \ + x(SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) + +Z7_IFACE_CONSTR_ARCHIVE(ISetProperties, 0x03) + +#define Z7_IFACEM_IArchiveKeepModeForNextOpen(x) \ + x(KeepModeForNextOpen()) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveKeepModeForNextOpen, 0x04) + +/* Exe handler: the handler for executable format (PE, ELF, Mach-O). + SFX archive: executable stub + some tail data. + before 9.31: exe handler didn't parse SFX archives as executable format. + for 9.31+: exe handler parses SFX archives as executable format, only if AllowTail(1) was called */ + +#define Z7_IFACEM_IArchiveAllowTail(x) \ + x(AllowTail(Int32 allowTail)) \ + +Z7_IFACE_CONSTR_ARCHIVE(IArchiveAllowTail, 0x05) + + +namespace NRequestMemoryUseFlags +{ + const UInt32 k_AllowedSize_WasForced = 1 << 0; // (*allowedSize) was forced by -mmemx or -smemx + const UInt32 k_DefaultLimit_Exceeded = 1 << 1; // default limit of archive format was exceeded + const UInt32 k_MLimit_Exceeded = 1 << 2; // -mmemx value was exceeded + const UInt32 k_SLimit_Exceeded = 1 << 3; // -smemx value was exceeded + + const UInt32 k_NoErrorMessage = 1 << 10; // do not show error message, and show only request + const UInt32 k_IsReport = 1 << 11; // only report is required, without user request + + const UInt32 k_SkipArc_IsExpected = 1 << 12; // NRequestMemoryAnswerFlags::k_SkipArc flag answer is expected + const UInt32 k_Report_SkipArc = 1 << 13; // report about SkipArc operation + + // const UInt32 k_SkipBigFile_IsExpected = 1 << 14; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused) + // const UInt32 k_Report_SkipBigFile = 1 << 15; // report about SkipFile operation (unused) + + // const UInt32 k_SkipBigFiles_IsExpected = 1 << 16; // NRequestMemoryAnswerFlags::k_SkipBigFiles flag answer is expected (unused) + // const UInt32 k_Report_SkipBigFiles = 1 << 17; // report that all big files will be skipped (unused) +} + +namespace NRequestMemoryAnswerFlags +{ + const UInt32 k_Allow = 1 << 0; // allow further archive extraction + const UInt32 k_Stop = 1 << 1; // for exit (and return_code == E_ABORT is used) + const UInt32 k_SkipArc = 1 << 2; // skip current archive extraction + // const UInt32 k_SkipBigFile = 1 << 4; // skip extracting of files that exceed limit (unused) + // const UInt32 k_SkipBigFiles = 1 << 5; // skip extracting of files that exceed limit (unused) + const UInt32 k_Limit_Exceeded = 1 << 10; // limit was exceeded +} + +/* + *allowedSize is in/out: + in : default allowed memory usage size or forced size, if it was changed by switch -mmemx. + out : value specified by user or unchanged value. + + *answerFlags is in/out: + *answerFlags must be set by caller before calling for default action, + + indexType : must be set with NEventIndexType::* constant + (indexType == kNoIndex), if request for whole archive. + index : must be set for some (indexType) types (if + fileIndex , if (indexType == NEventIndexType::kInArcIndex) + 0, if if (indexType == kNoIndex) + path : NULL can be used for any indexType. +*/ +#define Z7_IFACEM_IArchiveRequestMemoryUseCallback(x) \ + x(RequestMemoryUse(UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path, \ + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +Z7_IFACE_CONSTR_ARCHIVE(IArchiveRequestMemoryUseCallback, 0x09) + + +struct CStatProp +{ + const char *Name; + UInt32 PropID; + VARTYPE vt; +}; + +namespace NWindows { +namespace NCOM { +// PropVariant.cpp +BSTR AllocBstrFromAscii(const char *s) throw(); +}} + + +#define IMP_IInArchive_GetProp_Base(fn, f, k) \ + Z7_COM7F_IMF(CHandler::fn(UInt32 *numProps)) \ + { *numProps = Z7_ARRAY_SIZE(k); return S_OK; } \ + Z7_COM7F_IMF(CHandler::f(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \ + +#define IMP_IInArchive_GetProp_NO_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ + *propID = k[index]; \ + *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; \ + *name = NULL; return S_OK; } \ + +#define IMP_IInArchive_GetProp_WITH_NAME(fn, f, k) \ + IMP_IInArchive_GetProp_Base(fn, f, k) \ + const CStatProp &prop = k[index]; \ + *propID = (PROPID)prop.PropID; \ + *varType = prop.vt; \ + *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \ + + +#define IMP_IInArchive_Props \ + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) + +#define IMP_IInArchive_Props_WITH_NAME \ + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfProperties, GetPropertyInfo, kProps) + +#define IMP_IInArchive_ArcProps \ + IMP_IInArchive_GetProp_NO_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) + +#define IMP_IInArchive_ArcProps_WITH_NAME \ + IMP_IInArchive_GetProp_WITH_NAME(GetNumberOfArchiveProperties, GetArchivePropertyInfo, kArcProps) + +#define IMP_IInArchive_ArcProps_NO_Table \ + Z7_COM7F_IMF(CHandler::GetNumberOfArchiveProperties(UInt32 *numProps)) \ + { *numProps = 0; return S_OK; } \ + Z7_COM7F_IMF(CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *)) \ + { return E_NOTIMPL; } \ + +#define IMP_IInArchive_ArcProps_NO \ + IMP_IInArchive_ArcProps_NO_Table \ + Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value)) \ + { value->vt = VT_EMPTY; return S_OK; } + + +#define Z7_class_CHandler_final \ + Z7_class_final(CHandler) + + +#define Z7_CLASS_IMP_CHandler_IInArchive_0 \ + Z7_CLASS_IMP_COM_1(CHandler, IInArchive) +#define Z7_CLASS_IMP_CHandler_IInArchive_1(i1) \ + Z7_CLASS_IMP_COM_2(CHandler, IInArchive, i1) +#define Z7_CLASS_IMP_CHandler_IInArchive_2(i1, i2) \ + Z7_CLASS_IMP_COM_3(CHandler, IInArchive, i1, i2) +#define Z7_CLASS_IMP_CHandler_IInArchive_3(i1, i2, i3) \ + Z7_CLASS_IMP_COM_4(CHandler, IInArchive, i1, i2, i3) +#define Z7_CLASS_IMP_CHandler_IInArchive_4(i1, i2, i3, i4) \ + Z7_CLASS_IMP_COM_5(CHandler, IInArchive, i1, i2, i3, i4) +#define Z7_CLASS_IMP_CHandler_IInArchive_5(i1, i2, i3, i4, i5) \ + Z7_CLASS_IMP_COM_6(CHandler, IInArchive, i1, i2, i3, i4, i5) + + + +#define k_IsArc_Res_NO 0 +#define k_IsArc_Res_YES 1 +#define k_IsArc_Res_NEED_MORE 2 +// #define k_IsArc_Res_YES_LOW_PROB 3 + +#define API_FUNC_IsArc EXTERN_C UInt32 WINAPI +#define API_FUNC_static_IsArc extern "C" { static UInt32 WINAPI + +extern "C" +{ + typedef HRESULT (WINAPI *Func_CreateObject)(const GUID *clsID, const GUID *iid, void **outObject); + + typedef UInt32 (WINAPI *Func_IsArc)(const Byte *p, size_t size); + typedef HRESULT (WINAPI *Func_GetIsArc)(UInt32 formatIndex, Func_IsArc *isArc); + + typedef HRESULT (WINAPI *Func_GetNumberOfFormats)(UInt32 *numFormats); + typedef HRESULT (WINAPI *Func_GetHandlerProperty)(PROPID propID, PROPVARIANT *value); + typedef HRESULT (WINAPI *Func_GetHandlerProperty2)(UInt32 index, PROPID propID, PROPVARIANT *value); + + typedef HRESULT (WINAPI *Func_SetCaseSensitive)(Int32 caseSensitive); + typedef HRESULT (WINAPI *Func_SetLargePageMode)(); + // typedef HRESULT (WINAPI *Func_SetClientVersion)(UInt32 version); + + typedef IOutArchive * (*Func_CreateOutArchive)(); + typedef IInArchive * (*Func_CreateInArchive)(); +} + + +/* + if there is no time in archive, external MTime of archive + will be used instead of _item.Time from archive. + For 7-zip before 22.00 we need to return some supported value. + But (kpidTimeType > kDOS) is not allowed in 7-Zip before 22.00. + So we return highest precision value supported by old 7-Zip. + new 7-Zip 22.00 doesn't use that value in usual cases. +*/ + + +#define DECLARE_AND_SET_CLIENT_VERSION_VAR +#define GET_FileTimeType_NotDefined_for_GetFileTimeType \ + NFileTimeType::kWindows + +/* +extern UInt32 g_ClientVersion; + +#define GET_CLIENT_VERSION(major, minor) \ + ((UInt32)(((UInt32)(major) << 16) | (UInt32)(minor))) + +#define DECLARE_AND_SET_CLIENT_VERSION_VAR \ + UInt32 g_ClientVersion = GET_CLIENT_VERSION(MY_VER_MAJOR, MY_VER_MINOR); + +#define GET_FileTimeType_NotDefined_for_GetFileTimeType \ + ((UInt32)(g_ClientVersion >= GET_CLIENT_VERSION(22, 0) ? \ + (UInt32)(Int32)NFileTimeType::kNotDefined : \ + NFileTimeType::kWindows)) +*/ + +Z7_PURE_INTERFACES_END +#endif Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/7z.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/7z.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/apfs.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/apfs.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/arj.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/arj.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/bz2.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/bz2.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/cab.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/cab.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/cpio.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/cpio.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/deb.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/deb.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/dmg.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/dmg.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/fat.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/fat.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/gz.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/gz.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/hfs.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/hfs.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/iso.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/iso.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/lzh.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/lzh.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/lzma.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/lzma.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/ntfs.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/ntfs.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/rar.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/rar.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/rpm.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/rpm.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/split.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/split.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/squashfs.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/squashfs.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/tar.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/tar.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/vhd.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/vhd.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/wim.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/wim.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/xar.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/xar.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/xz.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/xz.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/z.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/z.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/zip.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/zip.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Archive/Icons/zst.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Icons/zst.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/IhexHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IhexHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/IhexHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/IhexHandler.cpp 2023-10-02 09:00:00.000000000 +0000 @@ -1,497 +1,493 @@ -// IhexHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/DynamicBuffer.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyVector.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" -#include "../Common/InBuffer.h" - -namespace NArchive { -namespace NIhex { - -/* We still don't support files with custom record types: 20, 22: used by Samsung */ - -struct CBlock -{ - CByteDynamicBuffer Data; - UInt32 Offset; -}; - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - bool _isArc; - bool _needMoreInput; - bool _dataError; - - UInt64 _phySize; - - CObjectVector _blocks; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidVa -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _blocks.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_phySize != 0) prop = _phySize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_dataError) v |= kpv_ErrorFlags_DataError; - prop = v; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CBlock &block = _blocks[index]; - switch (propID) - { - case kpidSize: prop = (UInt64)block.Data.GetPos(); break; - case kpidVa: prop = block.Offset; break; - case kpidPath: - { - if (_blocks.Size() != 1) - { - char s[16]; - ConvertUInt32ToString(index, s); - prop = s; - } - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static inline int HexToByte(unsigned c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - return -1; -} - -static int Parse(const Byte *p) -{ - int c1 = HexToByte(p[0]); if (c1 < 0) return -1; - int c2 = HexToByte(p[1]); if (c2 < 0) return -1; - return (c1 << 4) | c2; -} - -#define kType_Data 0 -#define kType_Eof 1 -#define kType_Seg 2 -#define kType_CsIp 3 -#define kType_High 4 -#define kType_Ip32 5 - -#define kType_MAX 5 - -#define IS_LINE_DELIMITER(c) ((c) == 0 || (c) == 10 || (c) == 13) - -API_FUNC_static_IsArc IsArc_Ihex(const Byte *p, size_t size) -{ - if (size < 1) - return k_IsArc_Res_NEED_MORE; - if (p[0] != ':') - return k_IsArc_Res_NO; - p++; - size--; - - const unsigned kNumLinesToCheck = 3; // 1 line is OK also, but we don't want false detection - - for (unsigned j = 0; j < kNumLinesToCheck; j++) - { - if (size < 4 * 2) - return k_IsArc_Res_NEED_MORE; - - int num = Parse(p); - if (num < 0) - return k_IsArc_Res_NO; - - int type = Parse(p + 6); - if (type < 0 || type > kType_MAX) - return k_IsArc_Res_NO; - - unsigned numChars = ((unsigned)num + 5) * 2; - unsigned sum = 0; - - for (unsigned i = 0; i < numChars; i += 2) - { - if (i + 2 > size) - return k_IsArc_Res_NEED_MORE; - int v = Parse(p + i); - if (v < 0) - return k_IsArc_Res_NO; - sum += (unsigned)v; - } - - if ((sum & 0xFF) != 0) - return k_IsArc_Res_NO; - - if (type == kType_Data) - { - // we don't want to open :0000000000 files - if (num == 0) - return k_IsArc_Res_NO; - } - else - { - if (type == kType_Eof) - { - if (num != 0) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; - } - if (p[2] != 0 || - p[3] != 0 || - p[4] != 0 || - p[5] != 0) - return k_IsArc_Res_NO; - if (type == kType_Seg || type == kType_High) - { - if (num != 2) - return k_IsArc_Res_NO; - } - else - { - if (num != 4) - return k_IsArc_Res_NO; - } - } - - p += numChars; - size -= numChars; - - for (;;) - { - if (size == 0) - return k_IsArc_Res_NEED_MORE; - char b = *p++; - size--; - if (IS_LINE_DELIMITER(b)) - continue; - if (b == ':') - break; - return k_IsArc_Res_NO; - } - } - - return k_IsArc_Res_YES; -} -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - COM_TRY_BEGIN - { - Close(); - try - { - const unsigned kStartSize = (2 + (256 + 5) + 2) * 2; - Byte temp[kStartSize]; - { - size_t size = kStartSize; - RINOK(ReadStream(stream, temp, &size)); - UInt32 isArcRes = IsArc_Ihex(temp, size); - if (isArcRes == k_IsArc_Res_NO) - return S_FALSE; - if (isArcRes == k_IsArc_Res_NEED_MORE && size != kStartSize) - return S_FALSE; - } - _isArc = true; - - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - CInBuffer s; - if (!s.Create(1 << 15)) - return E_OUTOFMEMORY; - s.SetStream(stream); - s.Init(); - - { - Byte b; - if (!s.ReadByte(b)) - { - _needMoreInput = true; - return S_FALSE; - } - if (b != ':') - { - _dataError = true; - return S_FALSE; - } - } - - UInt32 globalOffset = 0; - - for (;;) - { - if (s.ReadBytes(temp, 2) != 2) - { - _needMoreInput = true; - return S_FALSE; - } - int num = Parse(temp); - if (num < 0) - { - _dataError = true; - return S_FALSE; - } - - { - size_t numPairs = ((unsigned)num + 4); - size_t numBytes = numPairs * 2; - if (s.ReadBytes(temp, numBytes) != numBytes) - { - _needMoreInput = true; - return S_FALSE; - } - - unsigned sum = num; - for (size_t i = 0; i < numPairs; i++) - { - int a = Parse(temp + i * 2); - if (a < 0) - { - _dataError = true; - return S_FALSE; - } - temp[i] = (Byte)a; - sum += a; - } - if ((sum & 0xFF) != 0) - { - _dataError = true; - return S_FALSE; - } - } - - unsigned type = temp[2]; - if (type > kType_MAX) - { - _dataError = true; - return S_FALSE; - } - - UInt32 a = GetBe16(temp); - - if (type == kType_Data) - { - if (num == 0) - { - // we don't want to open :0000000000 files - // maybe it can mean EOF in old-style files? - _dataError = true; - return S_FALSE; - } - // if (num != 0) - { - UInt32 offs = globalOffset + a; - CBlock *block = NULL; - if (!_blocks.IsEmpty()) - { - block = &_blocks.Back(); - if (block->Offset + block->Data.GetPos() != offs) - block = NULL; - } - if (!block) - { - block = &_blocks.AddNew(); - block->Offset = offs; - } - block->Data.AddData(temp + 3, (unsigned)num); - } - } - else if (type == kType_Eof) - { - _phySize = s.GetProcessedSize(); - { - Byte b; - if (s.ReadByte(b)) - { - if (b == 10) - _phySize++; - else if (b == 13) - { - _phySize++; - if (s.ReadByte(b)) - { - if (b == 10) - _phySize++; - } - } - } - } - return S_OK; - } - else - { - if (a != 0) - { - _dataError = true; - return S_FALSE; - } - if (type == kType_Seg || type == kType_High) - { - if (num != 2) - { - _dataError = true; - return S_FALSE; - } - UInt32 d = GetBe16(temp + 3); - globalOffset = d << (type == kType_Seg ? 4 : 16); - } - else - { - if (num != 4) - { - _dataError = true; - return S_FALSE; - } - } - } - - for (;;) - { - Byte b; - if (!s.ReadByte(b)) - { - _needMoreInput = true; - return S_FALSE; - } - if (IS_LINE_DELIMITER(b)) - continue; - if (b == ':') - break; - _dataError = true; - return S_FALSE; - } - } - } - catch(const CInBufferException &e) { return e.ErrorCode; } - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - - _isArc = false; - _needMoreInput = false; - _dataError = false; - - _blocks.Clear(); - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _blocks.Size(); - if (numItems == 0) - return S_OK; - - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _blocks[allFilesMode ? i : indices[i]].Data.GetPos(); - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - currentItemSize = 0; - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - - UInt32 index = allFilesMode ? i : indices[i]; - const CByteDynamicBuffer &data = _blocks[index].Data; - currentItemSize = data.GetPos(); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (!testMode && !realOutStream) - continue; - - extractCallback->PrepareOperation(askMode); - - if (realOutStream) - { - RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos())); - } - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - - lps->InSize = lps->OutSize = currentTotalSize; - return lps->SetCur(); - - COM_TRY_END -} - -// k_Signature: { ':', '1' } - -REGISTER_ARC_I_NO_SIG( - "IHex", "ihex", 0, 0xCD, - 0, - NArcInfoFlags::kStartOpen, - IsArc_Ihex) - -}} +// IhexHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/DynamicBuffer.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringToInt.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/InBuffer.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +namespace NArchive { +namespace NIhex { + +/* We still don't support files with custom record types: 20, 22: used by Samsung */ + +struct CBlock +{ + CByteDynamicBuffer Data; + UInt32 Offset; +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + bool _isArc; + bool _needMoreInput; + bool _dataError; + + UInt64 _phySize; + + CObjectVector _blocks; +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidVa +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _blocks.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_dataError) v |= kpv_ErrorFlags_DataError; + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CBlock &block = _blocks[index]; + switch (propID) + { + case kpidSize: prop = (UInt64)block.Data.GetPos(); break; + case kpidVa: prop = block.Offset; break; + case kpidPath: + { + if (_blocks.Size() != 1) + { + char s[16]; + ConvertUInt32ToString(index, s); + prop = s; + } + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +static int Parse(const Byte *p) +{ + unsigned v0 = p[0]; Z7_PARSE_HEX_DIGIT(v0, return -1;) + unsigned v1 = p[1]; Z7_PARSE_HEX_DIGIT(v1, return -1;) + return (int)((v0 << 4) | v1); +} + +#define kType_Data 0 +#define kType_Eof 1 +#define kType_Seg 2 +// #define kType_CsIp 3 +#define kType_High 4 +// #define kType_Ip32 5 + +#define kType_MAX 5 + +// we don't want to read files with big number of spaces between records +// it's our limitation (out of specification): +static const unsigned k_NumSpaces_LIMIT = 16 + 1; + +#define IS_LINE_DELIMITER(c) (/* (c) == 0 || */ (c) == 10 || (c) == 13) + +API_FUNC_static_IsArc IsArc_Ihex(const Byte *p, size_t size) +{ + if (size < 1) + return k_IsArc_Res_NEED_MORE; + if (p[0] != ':') + return k_IsArc_Res_NO; + p++; + size--; + + const unsigned kNumLinesToCheck = 3; // 1 line is OK also, but we don't want false detection + + for (unsigned j = 0; j < kNumLinesToCheck; j++) + { + if (size < 4 * 2) + return k_IsArc_Res_NEED_MORE; + + const int num = Parse(p); + if (num < 0) + return k_IsArc_Res_NO; + + const int type = Parse(p + 6); + if (type < 0 || type > kType_MAX) + return k_IsArc_Res_NO; + + unsigned numChars = ((unsigned)num + 5) * 2; + unsigned sum = 0; + + for (unsigned i = 0; i < numChars; i += 2) + { + if (i + 2 > size) + return k_IsArc_Res_NEED_MORE; + int v = Parse(p + i); + if (v < 0) + return k_IsArc_Res_NO; + sum += (unsigned)v; + } + + if (sum & 0xFF) + return k_IsArc_Res_NO; + + if (type == kType_Data) + { + // we don't want to open :0000000000 files + if (num == 0) + return k_IsArc_Res_NO; + } + else + { + if (type == kType_Eof) + { + if (num != 0) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; + } + if (p[2] != 0 || + p[3] != 0 || + p[4] != 0 || + p[5] != 0) + return k_IsArc_Res_NO; + if (type == kType_Seg || type == kType_High) + { + if (num != 2) + return k_IsArc_Res_NO; + } + else + { + if (num != 4) + return k_IsArc_Res_NO; + } + } + + p += numChars; + size -= numChars; + + unsigned numSpaces = k_NumSpaces_LIMIT; + for (;;) + { + if (size == 0) + return k_IsArc_Res_NEED_MORE; + const Byte b = *p++; + size--; + if (b == ':') + break; + if (--numSpaces == 0 || !IS_LINE_DELIMITER(b)) + return k_IsArc_Res_NO; + } + } + + return k_IsArc_Res_YES; +} +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + { + Close(); + try + { + const unsigned kStartSize = (2 + (256 + 5) + 2) * 2; + Byte temp[kStartSize]; + { + size_t size = kStartSize; + RINOK(ReadStream(stream, temp, &size)) + const UInt32 isArcRes = IsArc_Ihex(temp, size); + if (isArcRes == k_IsArc_Res_NO) + return S_FALSE; + if (isArcRes == k_IsArc_Res_NEED_MORE && size != kStartSize) + return S_FALSE; + } + _isArc = true; + + RINOK(InStream_SeekToBegin(stream)) + CInBuffer s; + if (!s.Create(1 << 15)) + return E_OUTOFMEMORY; + s.SetStream(stream); + s.Init(); + { + Byte b; + if (!s.ReadByte(b)) + { + _needMoreInput = true; + return S_FALSE; + } + if (b != ':') + { + _dataError = true; + return S_FALSE; + } + } + + UInt32 globalOffset = 0; + const UInt32 k_progressStep = 1 << 24; + UInt64 progressNext = k_progressStep; + + for (;;) + { + if (s.ReadBytes(temp, 2) != 2) + { + _needMoreInput = true; + return S_FALSE; + } + const int num = Parse(temp); + if (num < 0) + { + _dataError = true; + return S_FALSE; + } + { + const size_t numPairs = (unsigned)num + 4; + const size_t numBytes = numPairs * 2; + if (s.ReadBytes(temp, numBytes) != numBytes) + { + _needMoreInput = true; + return S_FALSE; + } + unsigned sum = (unsigned)num; + for (size_t i = 0; i < numPairs; i++) + { + const int a = Parse(temp + i * 2); + if (a < 0) + { + _dataError = true; + return S_FALSE; + } + temp[i] = (Byte)a; + sum += (unsigned)a; + } + if (sum & 0xFF) + { + _dataError = true; + return S_FALSE; + } + } + + const unsigned type = temp[2]; + if (type > kType_MAX) + { + _dataError = true; + return S_FALSE; + } + + const UInt32 a = GetBe16(temp); + + if (type == kType_Data) + { + if (num == 0) + { + // we don't want to open :0000000000 files + // maybe it can mean EOF in old-style files? + _dataError = true; + return S_FALSE; + } + // if (num != 0) + { + const UInt32 offs = globalOffset + a; + CBlock *block = NULL; + if (!_blocks.IsEmpty()) + { + block = &_blocks.Back(); + if (block->Offset + block->Data.GetPos() != offs) + block = NULL; + } + if (!block) + { + block = &_blocks.AddNew(); + block->Offset = offs; + } + block->Data.AddData(temp + 3, (unsigned)num); + } + } + else + { + if (a != 0) // from description: the address field is typically 0. + { + _dataError = true; + return S_FALSE; + } + if (type == kType_Eof) + { + if (num != 0) + { + _dataError = true; + return S_FALSE; + } + _phySize = s.GetProcessedSize(); + Byte b; + if (s.ReadByte(b)) + { + if (b == 10) + _phySize++; + else if (b == 13) + { + _phySize++; + if (s.ReadByte(b)) + { + if (b == 10) + _phySize++; + } + } + } + return S_OK; + } + + if (type == kType_Seg || type == kType_High) + { + if (num != 2) + { + _dataError = true; + return S_FALSE; + } + // here we use optimization trick for num shift calculation: (type == kType_Seg ? 4 : 16) + globalOffset = (UInt32)GetBe16(temp + 3) << (1u << type); + } + else + { + if (num != 4) + { + _dataError = true; + return S_FALSE; + } + } + } + + if (openCallback) + { + const UInt64 processed = s.GetProcessedSize(); + if (processed >= progressNext) + { + progressNext = processed + k_progressStep; + const UInt64 numFiles = _blocks.Size(); + RINOK(openCallback->SetCompleted(&numFiles, &processed)) + } + } + + unsigned numSpaces = k_NumSpaces_LIMIT; + for (;;) + { + Byte b; + if (!s.ReadByte(b)) + { + _needMoreInput = true; + return S_FALSE; + } + if (b == ':') + break; + if (--numSpaces == 0 || !IS_LINE_DELIMITER(b)) + { + _dataError = true; + return S_FALSE; + } + } + } + } + catch(const CInBufferException &e) { return e.ErrorCode; } + } + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + _isArc = false; + _needMoreInput = false; + _dataError = false; + _blocks.Clear(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _blocks.Size(); + if (numItems == 0) + return S_OK; + + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _blocks[allFilesMode ? i : indices[i]].Data.GetPos(); + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const UInt32 index = allFilesMode ? i : indices[i]; + const CByteDynamicBuffer &data = _blocks[index].Data; + lps->OutSize += data.GetPos(); + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (realOutStream) + RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetPos())) + } + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + + return S_OK; + COM_TRY_END +} + +// k_Signature: { ':' } + +REGISTER_ARC_I_NO_SIG( + "IHex", "ihex", NULL, 0xCD, + 0, + NArcInfoFlags::kStartOpen, + IsArc_Ihex) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.cpp 2024-03-03 16:00:00.000000000 +0000 @@ -1,413 +1,496 @@ -// IsoHandler.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "../Common/ItemNameUtils.h" - -#include "IsoHandler.h" - -using namespace NWindows; -using namespace NTime; - -namespace NArchive { -namespace NIso { - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime -}; - -static const Byte kArcProps[] = -{ - kpidComment, - kpidCTime, - kpidMTime, - // kpidHeadersSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - { - RINOK(_archive.Open(stream)); - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _archive.Clear(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _archive.Refs.Size() + _archive.BootEntries.Size(); - return S_OK; -} - -static void AddString(AString &s, const char *name, const Byte *p, unsigned size) -{ - unsigned i; - for (i = 0; i < size && p[i]; i++); - for (; i > 0 && p[i - 1] == ' '; i--); - if (i != 0) - { - AString d; - d.SetFrom((const char *)p, i); - s += '\n'; - s += name; - s += ": "; - s += d; - } -} - -#define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v)) - -static void AddErrorMessage(AString &s, const char *message) -{ - if (!s.IsEmpty()) - s += ". "; - s += message; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - if (_stream) - { - const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex]; - switch (propID) - { - case kpidComment: - { - AString s; - ADD_STRING("System", SystemId); - ADD_STRING("Volume", VolumeId); - ADD_STRING("VolumeSet", VolumeSetId); - ADD_STRING("Publisher", PublisherId); - ADD_STRING("Preparer", DataPreparerId); - ADD_STRING("Application", ApplicationId); - ADD_STRING("Copyright", CopyrightFileId); - ADD_STRING("Abstract", AbstractFileId); - ADD_STRING("Bib", BibFileId); - 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; } - } - } - - switch (propID) - { - case kpidPhySize: prop = _archive.PhySize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; - if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_archive.HeadersError) v |= kpv_ErrorFlags_HeadersError; - prop = v; - break; - } - - case kpidError: - { - AString s; - if (_archive.IncorrectBigEndian) - AddErrorMessage(s, "Incorrect big-endian headers"); - if (_archive.SelfLinkedDirs) - AddErrorMessage(s, "Self-linked directory"); - if (_archive.TooDeepDirs) - AddErrorMessage(s, "Too deep directory levels"); - if (!s.IsEmpty()) - prop = s; - 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; - if (index >= (UInt32)_archive.Refs.Size()) - { - index -= _archive.Refs.Size(); - const CBootInitialEntry &be = _archive.BootEntries[index]; - switch (propID) - { - case kpidPath: - { - AString s = "[BOOT]" STRING_PATH_SEPARATOR; - if (_archive.BootEntries.Size() != 1) - { - char temp[16]; - ConvertUInt32ToString(index + 1, temp); - s += temp; - s += '-'; - } - s += be.GetName(); - prop = s; - break; - } - case kpidIsDir: prop = false; break; - case kpidSize: - case kpidPackSize: - prop = (UInt64)_archive.GetBootItemSize(index); - break; - } - } - else - { - const CRef &ref = _archive.Refs[index]; - const CDir &item = ref.Dir->_subItems[ref.Index]; - switch (propID) - { - case kpidPath: - // if (item.FileId.GetCapacity() >= 0) - { - UString s; - if (_archive.IsJoliet()) - item.GetPathU(s); - else - s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP); - - if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1') - s.DeleteFrom(s.Len() - 2); - - if (!s.IsEmpty() && s.Back() == L'.') - s.DeleteBack(); - - NItemName::ConvertToOSName2(s); - prop = s; - } - break; - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: - case kpidPackSize: - if (!item.IsDir()) - prop = (UInt64)ref.TotalSize; - break; - case kpidMTime: - { - FILETIME utc; - if (item.DateTime.GetFileTime(utc)) - prop = utc; - break; - } - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _archive.Refs.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt32 index = (allFilesMode ? i : indices[i]); - if (index < (UInt32)_archive.Refs.Size()) - { - const CRef &ref = _archive.Refs[index]; - const CDir &item = ref.Dir->_subItems[ref.Index]; - if (!item.IsDir()) - totalSize += ref.TotalSize; - } - else - totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size()); - } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - currentItemSize = 0; - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - UInt64 blockIndex; - if (index < (UInt32)_archive.Refs.Size()) - { - const CRef &ref = _archive.Refs[index]; - const CDir &item = ref.Dir->_subItems[ref.Index]; - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - currentItemSize = ref.TotalSize; - blockIndex = item.ExtentLocation; - } - else - { - unsigned bootIndex = index - _archive.Refs.Size(); - const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; - currentItemSize = _archive.GetBootItemSize(bootIndex); - blockIndex = be.LoadRBA; - } - - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - - bool isOK = true; - if (index < (UInt32)_archive.Refs.Size()) - { - const CRef &ref = _archive.Refs[index]; - UInt64 offset = 0; - for (UInt32 e = 0; e < ref.NumExtents; e++) - { - lps->InSize = lps->OutSize = currentTotalSize + offset; - const CDir &item2 = ref.Dir->_subItems[ref.Index + e]; - RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item2.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != item2.Size) - { - isOK = false; - break; - } - offset += item2.Size; - } - } - else - { - RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != currentItemSize) - isOK = false; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(isOK ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - UInt64 blockIndex; - UInt64 currentItemSize; - - if (index < _archive.Refs.Size()) - { - const CRef &ref = _archive.Refs[index]; - const CDir &item = ref.Dir->_subItems[ref.Index]; - if (item.IsDir()) - return S_FALSE; - - if (ref.NumExtents > 1) - { - CExtentsStream *extentStreamSpec = new CExtentsStream(); - CMyComPtr extentStream = extentStreamSpec; - - extentStreamSpec->Stream = _stream; - - UInt64 virtOffset = 0; - for (UInt32 i = 0; i < ref.NumExtents; i++) - { - const CDir &item2 = ref.Dir->_subItems[ref.Index + i]; - if (item2.Size == 0) - continue; - CSeekExtent se; - se.Phy = (UInt64)item2.ExtentLocation * kBlockSize; - se.Virt = virtOffset; - extentStreamSpec->Extents.Add(se); - virtOffset += item2.Size; - } - if (virtOffset != ref.TotalSize) - return S_FALSE; - CSeekExtent se; - se.Phy = 0; - se.Virt = virtOffset; - extentStreamSpec->Extents.Add(se); - extentStreamSpec->Init(); - *stream = extentStream.Detach(); - return S_OK; - } - - currentItemSize = item.Size; - blockIndex = item.ExtentLocation; - } - else - { - unsigned bootIndex = index - _archive.Refs.Size(); - const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; - currentItemSize = _archive.GetBootItemSize(bootIndex); - blockIndex = be.LoadRBA; - } - - return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream); - COM_TRY_END -} - -}} +// IsoHandler.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringConvert.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "IsoHandler.h" + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NIso { + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + // kpidCTime, + // kpidATime, + kpidPosixAttrib, + // kpidUserId, + // kpidGroupId, + // kpidLinks, + kpidSymLink +}; + +static const Byte kArcProps[] = +{ + kpidComment, + kpidCTime, + kpidMTime, + // kpidHeadersSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + { + RINOK(_archive.Open(stream)) + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _archive.Clear(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _archive.Refs.Size() + _archive.BootEntries.Size(); + return S_OK; +} + +static void AddString(AString &s, const char *name, const Byte *p, unsigned size) +{ + unsigned i; + for (i = 0; i < size && p[i]; i++); + for (; i > 0 && p[i - 1] == ' '; i--); + if (i != 0) + { + AString d; + d.SetFrom((const char *)p, i); + s += name; + s += ": "; + s += d; + s.Add_LF(); + } +} + +static void AddProp_Size64(AString &s, const char *name, UInt64 size) +{ + s += name; + s += ": "; + s.Add_UInt64(size); + s.Add_LF(); +} + +#define ADD_STRING(n, v) AddString(s, n, vol. v, sizeof(vol. v)) + +static void AddErrorMessage(AString &s, const char *message) +{ + if (!s.IsEmpty()) + s += ". "; + s += message; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (_stream) + { + const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex]; + switch (propID) + { + case kpidComment: + { + AString s; + ADD_STRING("System", SystemId); + ADD_STRING("Volume", VolumeId); + ADD_STRING("VolumeSet", VolumeSetId); + ADD_STRING("Publisher", PublisherId); + ADD_STRING("Preparer", DataPreparerId); + ADD_STRING("Application", ApplicationId); + ADD_STRING("Copyright", CopyrightFileId); + ADD_STRING("Abstract", AbstractFileId); + ADD_STRING("Bib", BibFileId); + // ADD_STRING("EscapeSequence", EscapeSequence); + AddProp_Size64(s, "VolumeSpaceSize", vol.Get_VolumeSpaceSize_inBytes()); + AddProp_Size64(s, "VolumeSetSize", vol.VolumeSetSize); + AddProp_Size64(s, "VolumeSequenceNumber", vol.VolumeSequenceNumber); + + prop = s; + break; + } + case kpidCTime: { vol.CTime.GetFileTime(prop); break; } + case kpidMTime: { vol.MTime.GetFileTime(prop); break; } + } + } + + switch (propID) + { + case kpidPhySize: prop = _archive.PhySize; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_archive.HeadersError) v |= kpv_ErrorFlags_HeadersError; + prop = v; + break; + } + + case kpidError: + { + AString s; + if (_archive.IncorrectBigEndian) + AddErrorMessage(s, "Incorrect big-endian headers"); + if (_archive.SelfLinkedDirs) + AddErrorMessage(s, "Self-linked directory"); + if (_archive.TooDeepDirs) + AddErrorMessage(s, "Too deep directory levels"); + if (!s.IsEmpty()) + prop = s; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (index >= (UInt32)_archive.Refs.Size()) + { + index -= _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[index]; + switch (propID) + { + case kpidPath: + { + AString s ("[BOOT]" STRING_PATH_SEPARATOR); + if (_archive.BootEntries.Size() != 1) + { + s.Add_UInt32(index + 1); + s.Add_Minus(); + } + s += be.GetName(); + prop = s; + break; + } + case kpidIsDir: prop = false; break; + case kpidSize: + case kpidPackSize: + prop = (UInt64)_archive.GetBootItemSize(index); + break; + } + } + else + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + switch (propID) + { + case kpidPath: + // if (item.FileId.GetCapacity() >= 0) + { + UString s; + if (_archive.IsJoliet()) + item.GetPathU(s); + else + s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP); + + if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1') + s.DeleteFrom(s.Len() - 2); + + if (!s.IsEmpty() && s.Back() == L'.') + s.DeleteBack(); + + NItemName::ReplaceToOsSlashes_Remove_TailSlash(s); + prop = s; + } + break; + + case kpidSymLink: + if (_archive.IsSusp) + { + UInt32 mode; + if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode)) + { + if (MY_LIN_S_ISLNK(mode)) + { + AString s8; + if (item.GetSymLink(_archive.SuspSkipSize, s8)) + { + UString s = MultiByteToUnicodeString(s8, CP_OEMCP); + prop = s; + } + } + } + } + break; + + + case kpidPosixAttrib: + /* + case kpidLinks: + case kpidUserId: + case kpidGroupId: + */ + { + if (_archive.IsSusp) + { + UInt32 t = 0; + switch (propID) + { + case kpidPosixAttrib: t = k_Px_Mode; break; + /* + case kpidLinks: t = k_Px_Links; break; + case kpidUserId: t = k_Px_User; break; + case kpidGroupId: t = k_Px_Group; break; + */ + } + UInt32 v; + if (item.GetPx(_archive.SuspSkipSize, t, v)) + prop = v; + } + break; + } + + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: + case kpidPackSize: + if (!item.IsDir()) + prop = (UInt64)ref.TotalSize; + break; + + case kpidMTime: + // case kpidCTime: + // case kpidATime: + { + // if + item.DateTime.GetFileTime(prop); + /* + else + { + UInt32 t = 0; + switch (propID) + { + case kpidMTime: t = k_Tf_MTime; break; + case kpidCTime: t = k_Tf_CTime; break; + case kpidATime: t = k_Tf_ATime; break; + } + CRecordingDateTime dt; + if (item.GetTf(_archive.SuspSkipSize, t, dt)) + { + FILETIME utc; + if (dt.GetFileTime(utc)) + prop = utc; + } + } + */ + break; + } + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _archive.Refs.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt32 index = (allFilesMode ? i : indices[i]); + if (index < (UInt32)_archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + if (!item.IsDir()) + totalSize += ref.TotalSize; + } + else + totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size()); + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + currentItemSize = 0; + Int32 opRes = NExtract::NOperationResult::kOK; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + UInt64 blockIndex; + if (index < (UInt32)_archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + currentItemSize = ref.TotalSize; + blockIndex = item.ExtentLocation; + } + else + { + unsigned bootIndex = index - _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; + currentItemSize = _archive.GetBootItemSize(bootIndex); + blockIndex = be.LoadRBA; + } + + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + + if (index < (UInt32)_archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + UInt64 offset = 0; + for (UInt32 e = 0; e < ref.NumExtents; e++) + { + const CDir &item2 = ref.Dir->_subItems[ref.Index + e]; + if (item2.Size == 0) + continue; + lps->InSize = lps->OutSize = currentTotalSize + offset; + RINOK(InStream_SeekSet(_stream, (UInt64)item2.ExtentLocation * kBlockSize)) + inStream->Init(item2.Size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != item2.Size) + { + opRes = NExtract::NOperationResult::kDataError; + break; + } + offset += item2.Size; + } + } + else + { + RINOK(InStream_SeekSet(_stream, (UInt64)blockIndex * kBlockSize)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != currentItemSize) + opRes = NExtract::NOperationResult::kDataError; + } + // realOutStream.Release(); + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + UInt64 blockIndex; + UInt64 currentItemSize; + + if (index < _archive.Refs.Size()) + { + const CRef &ref = _archive.Refs[index]; + const CDir &item = ref.Dir->_subItems[ref.Index]; + if (item.IsDir()) + return S_FALSE; + + if (ref.NumExtents > 1) + { + CExtentsStream *extentStreamSpec = new CExtentsStream(); + CMyComPtr extentStream = extentStreamSpec; + + extentStreamSpec->Stream = _stream; + + UInt64 virtOffset = 0; + for (UInt32 i = 0; i < ref.NumExtents; i++) + { + const CDir &item2 = ref.Dir->_subItems[ref.Index + i]; + if (item2.Size == 0) + continue; + CSeekExtent se; + se.Phy = (UInt64)item2.ExtentLocation * kBlockSize; + se.Virt = virtOffset; + extentStreamSpec->Extents.Add(se); + virtOffset += item2.Size; + } + if (virtOffset != ref.TotalSize) + return S_FALSE; + CSeekExtent se; + se.Phy = 0; + se.Virt = virtOffset; + extentStreamSpec->Extents.Add(se); + extentStreamSpec->Init(); + *stream = extentStream.Detach(); + return S_OK; + } + + currentItemSize = item.Size; + blockIndex = item.ExtentLocation; + } + else + { + unsigned bootIndex = index - _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; + currentItemSize = _archive.GetBootItemSize(bootIndex); + blockIndex = be.LoadRBA; + } + + return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream); + COM_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHandler.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHandler.h 2023-03-26 13:00:00.000000000 +0000 @@ -1,31 +1,24 @@ -// IsoHandler.h - -#ifndef __ISO_HANDLER_H -#define __ISO_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../IArchive.h" - -#include "IsoIn.h" -#include "IsoItem.h" - -namespace NArchive { -namespace NIso { - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - CInArchive _archive; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -}} - -#endif +// IsoHandler.h + +#ifndef ZIP7_INC_ISO_HANDLER_H +#define ZIP7_INC_ISO_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../IArchive.h" + +#include "IsoIn.h" + +namespace NArchive { +namespace NIso { + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CMyComPtr _stream; + CInArchive _archive; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHeader.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHeader.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.cpp 2017-02-04 17:52:55.000000000 +0000 @@ -1,12 +1,12 @@ -// Archive/Iso/Header.h - -#include "StdAfx.h" - -#include "IsoHeader.h" - -namespace NArchive { -namespace NIso { - -const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0"; - -}} +// Archive/Iso/Header.h + +#include "StdAfx.h" + +#include "IsoHeader.h" + +namespace NArchive { +namespace NIso { + +const char * const kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0"; + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoHeader.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,64 +1,64 @@ -// Archive/IsoHeader.h - -#ifndef __ARCHIVE_ISO_HEADER_H -#define __ARCHIVE_ISO_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace NIso { - -namespace NVolDescType -{ - const Byte kBootRecord = 0; - const Byte kPrimaryVol = 1; - const Byte kSupplementaryVol = 2; - const Byte kVolParttition = 3; - const Byte kTerminator = 255; -} - -const Byte kVersion = 1; - -namespace NFileFlags -{ - const Byte kDirectory = 1 << 1; - const Byte kNonFinalExtent = 1 << 7; -} - -extern const char *kElToritoSpec; - -const UInt32 kStartPos = 0x8000; - -namespace NBootEntryId -{ - const Byte kValidationEntry = 1; - const Byte kInitialEntryNotBootable = 0; - const Byte kInitialEntryBootable = 0x88; - - const Byte kMoreHeaders = 0x90; - const Byte kFinalHeader = 0x91; - - const Byte kExtensionIndicator = 0x44; -} - -namespace NBootPlatformId -{ - const Byte kX86 = 0; - const Byte kPowerPC = 1; - const Byte kMac = 2; -} - -const Byte kBootMediaTypeMask = 0xF; - -namespace NBootMediaType -{ - const Byte kNoEmulation = 0; - const Byte k1d2Floppy = 1; - const Byte k1d44Floppy = 2; - const Byte k2d88Floppy = 3; - const Byte kHardDisk = 4; -} - -}} - -#endif +// Archive/IsoHeader.h + +#ifndef ZIP7_INC_ARCHIVE_ISO_HEADER_H +#define ZIP7_INC_ARCHIVE_ISO_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace NIso { + +namespace NVolDescType +{ + const Byte kBootRecord = 0; + const Byte kPrimaryVol = 1; + const Byte kSupplementaryVol = 2; + const Byte kVolParttition = 3; + const Byte kTerminator = 255; +} + +const Byte kVersion = 1; + +namespace NFileFlags +{ + const Byte kDirectory = 1 << 1; + const Byte kNonFinalExtent = 1 << 7; +} + +extern const char * const kElToritoSpec; + +const UInt32 kStartPos = 0x8000; + +namespace NBootEntryId +{ + const Byte kValidationEntry = 1; + const Byte kInitialEntryNotBootable = 0; + const Byte kInitialEntryBootable = 0x88; + + const Byte kMoreHeaders = 0x90; + const Byte kFinalHeader = 0x91; + + const Byte kExtensionIndicator = 0x44; +} + +namespace NBootPlatformId +{ + const Byte kX86 = 0; + const Byte kPowerPC = 1; + const Byte kMac = 2; +} + +const Byte kBootMediaTypeMask = 0xF; + +namespace NBootMediaType +{ + const Byte kNoEmulation = 0; + const Byte k1d2Floppy = 1; + const Byte k1d44Floppy = 2; + const Byte k2d88Floppy = 3; + const Byte kHardDisk = 4; +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoIn.cpp 2015-11-06 12:02:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.cpp 2024-05-14 09:00:00.000000000 +0000 @@ -1,673 +1,735 @@ -// Archive/IsoIn.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/MyException.h" - -#include "../../Common/StreamUtils.h" - -#include "../HandlerCont.h" - -#include "IsoIn.h" - -namespace NArchive { -namespace NIso { - -struct CUnexpectedEndException {}; -struct CHeaderErrorException {}; -struct CEndianErrorException {}; - -static const char * const kMediaTypes[] = -{ - "NoEmul" - , "1.2M" - , "1.44M" - , "2.88M" - , "HardDisk" -}; - -bool CBootInitialEntry::Parse(const Byte *p) -{ - Bootable = (p[0] == NBootEntryId::kInitialEntryBootable); - BootMediaType = p[1]; - LoadSegment = GetUi16(p + 2); - SystemType = p[4]; - SectorCount = GetUi16(p + 6); - LoadRBA = GetUi32(p + 8); - memcpy(VendorSpec, p + 12, 20); - if (p[5] != 0) - return false; - if (p[0] != NBootEntryId::kInitialEntryBootable - && p[0] != NBootEntryId::kInitialEntryNotBootable) - return false; - return true; -} - -AString CBootInitialEntry::GetName() const -{ - AString s = (Bootable ? "Boot" : "NotBoot"); - s += '-'; - - if (BootMediaType < ARRAY_SIZE(kMediaTypes)) - s += kMediaTypes[BootMediaType]; - else - { - char name[16]; - ConvertUInt32ToString(BootMediaType, name); - s += name; - } - - if (VendorSpec[0] == 1) - { - // "Language and Version Information (IBM)" - - unsigned i; - for (i = 1; i < sizeof(VendorSpec); i++) - if (VendorSpec[i] > 0x7F) - break; - if (i == sizeof(VendorSpec)) - { - s += '-'; - for (i = 1; i < sizeof(VendorSpec); i++) - { - char c = VendorSpec[i]; - if (c == 0) - break; - if (c == '\\' || c == '/') - c = '_'; - s += c; - } - } - } - - s += ".img"; - return s; -} - -Byte CInArchive::ReadByte() -{ - if (m_BufferPos >= kBlockSize) - m_BufferPos = 0; - if (m_BufferPos == 0) - { - size_t processed = kBlockSize; - HRESULT res = ReadStream(_stream, m_Buffer, &processed); - if (res != S_OK) - throw CSystemException(res); - if (processed != kBlockSize) - throw CUnexpectedEndException(); - UInt64 end = _position + processed; - if (PhySize < end) - PhySize = end; - } - Byte b = m_Buffer[m_BufferPos++]; - _position++; - return b; -} - -void CInArchive::ReadBytes(Byte *data, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) - data[i] = ReadByte(); -} - -void CInArchive::Skip(size_t size) -{ - while (size-- != 0) - ReadByte(); -} - -void CInArchive::SkipZeros(size_t size) -{ - while (size-- != 0) - { - Byte b = ReadByte(); - if (b != 0) - throw CHeaderErrorException(); - } -} - -UInt16 CInArchive::ReadUInt16() -{ - Byte b[4]; - ReadBytes(b, 4); - UInt32 val = 0; - for (int i = 0; i < 2; i++) - { - if (b[i] != b[3 - i]) - IncorrectBigEndian = true; - val |= ((UInt16)(b[i]) << (8 * i)); - } - return (UInt16)val; -} - -UInt32 CInArchive::ReadUInt32Le() -{ - UInt32 val = 0; - for (int i = 0; i < 4; i++) - val |= ((UInt32)(ReadByte()) << (8 * i)); - return val; -} - -UInt32 CInArchive::ReadUInt32Be() -{ - UInt32 val = 0; - for (int i = 0; i < 4; i++) - { - val <<= 8; - val |= ReadByte(); - } - return val; -} - -UInt32 CInArchive::ReadUInt32() -{ - Byte b[8]; - ReadBytes(b, 8); - UInt32 val = 0; - for (int i = 0; i < 4; i++) - { - if (b[i] != b[7 - i]) - throw CEndianErrorException(); - val |= ((UInt32)(b[i]) << (8 * i)); - } - return val; -} - -UInt32 CInArchive::ReadDigits(int numDigits) -{ - UInt32 res = 0; - for (int i = 0; i < numDigits; i++) - { - Byte b = ReadByte(); - if (b < '0' || b > '9') - { - if (b == 0) // it's bug in some CD's - b = '0'; - else - throw CHeaderErrorException(); - } - UInt32 d = (UInt32)(b - '0'); - res *= 10; - res += d; - } - return res; -} - -void CInArchive::ReadDateTime(CDateTime &d) -{ - d.Year = (UInt16)ReadDigits(4); - d.Month = (Byte)ReadDigits(2); - d.Day = (Byte)ReadDigits(2); - d.Hour = (Byte)ReadDigits(2); - d.Minute = (Byte)ReadDigits(2); - d.Second = (Byte)ReadDigits(2); - d.Hundredths = (Byte)ReadDigits(2); - d.GmtOffset = (signed char)ReadByte(); -} - -void CInArchive::ReadBootRecordDescriptor(CBootRecordDescriptor &d) -{ - ReadBytes(d.BootSystemId, sizeof(d.BootSystemId)); - ReadBytes(d.BootId, sizeof(d.BootId)); - ReadBytes(d.BootSystemUse, sizeof(d.BootSystemUse)); -} - -void CInArchive::ReadRecordingDateTime(CRecordingDateTime &t) -{ - t.Year = ReadByte(); - t.Month = ReadByte(); - t.Day = ReadByte(); - t.Hour = ReadByte(); - t.Minute = ReadByte(); - t.Second = ReadByte(); - t.GmtOffset = (signed char)ReadByte(); -} - -void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) -{ - r.ExtendedAttributeRecordLen = ReadByte(); - if (r.ExtendedAttributeRecordLen != 0) - throw CHeaderErrorException(); - r.ExtentLocation = ReadUInt32(); - r.Size = ReadUInt32(); - ReadRecordingDateTime(r.DateTime); - r.FileFlags = ReadByte(); - r.FileUnitSize = ReadByte(); - r.InterleaveGapSize = ReadByte(); - r.VolSequenceNumber = ReadUInt16(); - Byte idLen = ReadByte(); - r.FileId.Alloc(idLen); - ReadBytes((Byte *)r.FileId, idLen); - unsigned padSize = 1 - (idLen & 1); - - // SkipZeros(padSize); - Skip(padSize); // it's bug in some cd's. Must be zeros - - unsigned curPos = 33 + idLen + padSize; - if (curPos > len) - throw CHeaderErrorException(); - unsigned rem = len - curPos; - r.SystemUse.Alloc(rem); - ReadBytes((Byte *)r.SystemUse, rem); -} - -void CInArchive::ReadDirRecord(CDirRecord &r) -{ - Byte len = ReadByte(); - // Some CDs can have incorrect value len = 48 ('0') in VolumeDescriptor. - // But maybe we must use real "len" for other records. - len = 34; - ReadDirRecord2(r, len); -} - -void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) -{ - d.VolFlags = ReadByte(); - ReadBytes(d.SystemId, sizeof(d.SystemId)); - ReadBytes(d.VolumeId, sizeof(d.VolumeId)); - SkipZeros(8); - d.VolumeSpaceSize = ReadUInt32(); - ReadBytes(d.EscapeSequence, sizeof(d.EscapeSequence)); - d.VolumeSetSize = ReadUInt16(); - d.VolumeSequenceNumber = ReadUInt16(); - d.LogicalBlockSize = ReadUInt16(); - d.PathTableSize = ReadUInt32(); - d.LPathTableLocation = ReadUInt32Le(); - d.LOptionalPathTableLocation = ReadUInt32Le(); - d.MPathTableLocation = ReadUInt32Be(); - d.MOptionalPathTableLocation = ReadUInt32Be(); - ReadDirRecord(d.RootDirRecord); - ReadBytes(d.VolumeSetId, sizeof(d.VolumeSetId)); - ReadBytes(d.PublisherId, sizeof(d.PublisherId)); - ReadBytes(d.DataPreparerId, sizeof(d.DataPreparerId)); - ReadBytes(d.ApplicationId, sizeof(d.ApplicationId)); - ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId)); - ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId)); - ReadBytes(d.BibFileId, sizeof(d.BibFileId)); - ReadDateTime(d.CTime); - ReadDateTime(d.MTime); - ReadDateTime(d.ExpirationTime); - ReadDateTime(d.EffectiveTime); - d.FileStructureVersion = ReadByte(); // = 1 - SkipZeros(1); - ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); - - // Most ISO contains zeros in the following field (reserved for future standardization). - // But some ISO programs write some data to that area. - // So we disable check for zeros. - Skip(653); // SkipZeros(653); -} - -static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' }; - -static const Byte kSig_NSR02[5] = { 'N', 'S', 'R', '0', '2' }; -static const Byte kSig_NSR03[5] = { 'N', 'S', 'R', '0', '3' }; -static const Byte kSig_BEA01[5] = { 'B', 'E', 'A', '0', '1' }; -static const Byte kSig_TEA01[5] = { 'T', 'E', 'A', '0', '1' }; - -static inline bool CheckSignature(const Byte *sig, const Byte *data) -{ - for (int i = 0; i < 5; i++) - if (sig[i] != data[i]) - return false; - return true; -} - -void CInArchive::SeekToBlock(UInt32 blockIndex) -{ - HRESULT res = _stream->Seek((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize, STREAM_SEEK_SET, &_position); - if (res != S_OK) - throw CSystemException(res); - m_BufferPos = 0; -} - -static const int kNumLevelsMax = 256; - -void CInArchive::ReadDir(CDir &d, int level) -{ - if (!d.IsDir()) - return; - if (level > kNumLevelsMax) - { - TooDeepDirs = true; - return; - } - - { - FOR_VECTOR (i, UniqStartLocations) - if (UniqStartLocations[i] == d.ExtentLocation) - { - SelfLinkedDirs = true; - return; - } - UniqStartLocations.Add(d.ExtentLocation); - } - - SeekToBlock(d.ExtentLocation); - UInt64 startPos = _position; - - bool firstItem = true; - for (;;) - { - UInt64 offset = _position - startPos; - if (offset >= d.Size) - break; - Byte len = ReadByte(); - if (len == 0) - continue; - CDir subItem; - ReadDirRecord2(subItem, len); - if (firstItem && level == 0) - IsSusp = subItem.CheckSusp(SuspSkipSize); - - if (!subItem.IsSystemItem()) - d._subItems.Add(subItem); - - firstItem = false; - } - FOR_VECTOR (i, d._subItems) - ReadDir(d._subItems[i], level + 1); - - UniqStartLocations.DeleteBack(); -} - -void CInArchive::CreateRefs(CDir &d) -{ - if (!d.IsDir()) - return; - for (unsigned i = 0; i < d._subItems.Size();) - { - CRef ref; - CDir &subItem = d._subItems[i]; - subItem.Parent = &d; - ref.Dir = &d; - ref.Index = i++; - ref.NumExtents = 1; - ref.TotalSize = subItem.Size; - if (subItem.IsNonFinalExtent()) - { - for (;;) - { - if (i == d._subItems.Size()) - { - HeadersError = true; - break; - } - const CDir &next = d._subItems[i]; - if (!subItem.AreMultiPartEqualWith(next)) - break; - i++; - ref.NumExtents++; - ref.TotalSize += next.Size; - if (!next.IsNonFinalExtent()) - break; - } - } - Refs.Add(ref); - CreateRefs(subItem); - } -} - -void CInArchive::ReadBootInfo() -{ - if (!_bootIsDefined) - return; - HeadersError = true; - - if (memcmp(_bootDesc.BootSystemId, kElToritoSpec, sizeof(_bootDesc.BootSystemId)) != 0) - return; - - UInt32 blockIndex = GetUi32(_bootDesc.BootSystemUse); - SeekToBlock(blockIndex); - - Byte buf[32]; - ReadBytes(buf, 32); - - if (buf[0] != NBootEntryId::kValidationEntry - || buf[2] != 0 - || buf[3] != 0 - || buf[30] != 0x55 - || buf[31] != 0xAA) - return; - - { - UInt32 sum = 0; - for (unsigned i = 0; i < 32; i += 2) - sum += GetUi16(buf + i); - if ((sum & 0xFFFF) != 0) - return; - /* - CBootValidationEntry e; - e.PlatformId = buf[1]; - memcpy(e.Id, buf + 4, sizeof(e.Id)); - // UInt16 checkSum = GetUi16(p + 28); - */ - } - - ReadBytes(buf, 32); - { - CBootInitialEntry e; - if (!e.Parse(buf)) - return; - BootEntries.Add(e); - } - - bool error = false; - - for (;;) - { - ReadBytes(buf, 32); - Byte headerIndicator = buf[0]; - if (headerIndicator != NBootEntryId::kMoreHeaders - && headerIndicator != NBootEntryId::kFinalHeader) - break; - - // Section Header - // Byte platform = p[1]; - unsigned numEntries = GetUi16(buf + 2); - // id[28] - - for (unsigned i = 0; i < numEntries; i++) - { - ReadBytes(buf, 32); - CBootInitialEntry e; - if (!e.Parse(buf)) - { - error = true; - break; - } - if (e.BootMediaType & (1 << 5)) - { - // Section entry extension - for (unsigned j = 0;; j++) - { - ReadBytes(buf, 32); - if (j > 32 || buf[0] != NBootEntryId::kExtensionIndicator) - { - error = true; - break; - } - if ((buf[1] & (1 << 5)) == 0) - break; - // info += (buf + 2, 30) - } - } - BootEntries.Add(e); - } - - if (headerIndicator != NBootEntryId::kMoreHeaders) - break; - } - - HeadersError = error; -} - -HRESULT CInArchive::Open2() -{ - _position = 0; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &_fileSize)); - if (_fileSize < kStartPos) - return S_FALSE; - RINOK(_stream->Seek(kStartPos, STREAM_SEEK_SET, &_position)); - - PhySize = _position; - m_BufferPos = 0; - // BlockSize = kBlockSize; - - for (;;) - { - Byte sig[7]; - ReadBytes(sig, 7); - Byte ver = sig[6]; - - if (!CheckSignature(kSig_CD001, sig + 1)) - { - return S_FALSE; - /* - if (sig[0] != 0 || ver != 1) - break; - if (CheckSignature(kSig_BEA01, sig + 1)) - { - } - else if (CheckSignature(kSig_TEA01, sig + 1)) - { - break; - } - else if (CheckSignature(kSig_NSR02, sig + 1)) - { - } - else - break; - SkipZeros(0x800 - 7); - continue; - */ - } - - // version = 2 for ISO 9660:1999? - if (ver > 2) - return S_FALSE; - - if (sig[0] == NVolDescType::kTerminator) - { - break; - // Skip(0x800 - 7); - // continue; - } - - switch (sig[0]) - { - case NVolDescType::kBootRecord: - { - _bootIsDefined = true; - ReadBootRecordDescriptor(_bootDesc); - break; - } - case NVolDescType::kPrimaryVol: - case NVolDescType::kSupplementaryVol: - { - // some ISOs have two PrimaryVols. - CVolumeDescriptor vd; - ReadVolumeDescriptor(vd); - if (sig[0] == NVolDescType::kPrimaryVol) - { - // some burners write "Joliet" Escape Sequence to primary volume - memset(vd.EscapeSequence, 0, sizeof(vd.EscapeSequence)); - } - VolDescs.Add(vd); - break; - } - default: - break; - } - } - - if (VolDescs.IsEmpty()) - return S_FALSE; - for (MainVolDescIndex = VolDescs.Size() - 1; MainVolDescIndex > 0; MainVolDescIndex--) - if (VolDescs[MainVolDescIndex].IsJoliet()) - break; - // MainVolDescIndex = 0; // to read primary volume - const CVolumeDescriptor &vd = VolDescs[MainVolDescIndex]; - if (vd.LogicalBlockSize != kBlockSize) - return S_FALSE; - - IsArc = true; - - (CDirRecord &)_rootDir = vd.RootDirRecord; - ReadDir(_rootDir, 0); - CreateRefs(_rootDir); - ReadBootInfo(); - - { - FOR_VECTOR (i, Refs) - { - const CRef &ref = Refs[i]; - for (UInt32 j = 0; j < ref.NumExtents; j++) - { - const CDir &item = ref.Dir->_subItems[ref.Index + j]; - if (!item.IsDir()) - UpdatePhySize(item.ExtentLocation, item.Size); - } - } - } - { - FOR_VECTOR (i, BootEntries) - { - const CBootInitialEntry &be = BootEntries[i]; - UpdatePhySize(be.LoadRBA, GetBootItemSize(i)); - } - } - - if (PhySize < _fileSize) - { - UInt64 rem = _fileSize - PhySize; - const UInt64 kRemMax = 1 << 21; - if (rem <= kRemMax) - { - RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); - bool areThereNonZeros = false; - UInt64 numZeros = 0; - RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax)); - if (!areThereNonZeros) - PhySize += numZeros; - } - } - - return S_OK; -} - -HRESULT CInArchive::Open(IInStream *inStream) -{ - Clear(); - _stream = inStream; - try { return Open2(); } - catch(const CSystemException &e) { return e.ErrorCode; } - catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; } - catch(CHeaderErrorException &) { HeadersError = true; return S_FALSE; } - catch(CEndianErrorException &) { IncorrectBigEndian = true; return S_FALSE; } -} - -void CInArchive::Clear() -{ - IsArc = false; - UnexpectedEnd = false; - HeadersError = false; - IncorrectBigEndian = false; - TooDeepDirs = false; - SelfLinkedDirs = false; - - UniqStartLocations.Clear(); - - Refs.Clear(); - _rootDir.Clear(); - VolDescs.Clear(); - _bootIsDefined = false; - BootEntries.Clear(); - SuspSkipSize = 0; - IsSusp = false; -} - -}} +// Archive/IsoIn.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyException.h" + +#include "../../Common/StreamUtils.h" + +#include "../HandlerCont.h" + +#include "IsoIn.h" + +namespace NArchive { +namespace NIso { + +struct CUnexpectedEndException {}; +struct CHeaderErrorException {}; +struct CEndianErrorException {}; + +static const char * const kMediaTypes[] = +{ + "NoEmul" + , "1.2M" + , "1.44M" + , "2.88M" + , "HardDisk" +}; + +bool CBootInitialEntry::Parse(const Byte *p) +{ + Bootable = (p[0] == NBootEntryId::kInitialEntryBootable); + BootMediaType = p[1]; + LoadSegment = GetUi16(p + 2); + SystemType = p[4]; + SectorCount = GetUi16(p + 6); + LoadRBA = GetUi32(p + 8); + memcpy(VendorSpec, p + 12, 20); + if (p[5] != 0) + return false; + if (p[0] != NBootEntryId::kInitialEntryBootable + && p[0] != NBootEntryId::kInitialEntryNotBootable) + return false; + return true; +} + +AString CBootInitialEntry::GetName() const +{ + AString s (Bootable ? "Boot" : "NotBoot"); + s.Add_Minus(); + + if (BootMediaType < Z7_ARRAY_SIZE(kMediaTypes)) + s += kMediaTypes[BootMediaType]; + else + s.Add_UInt32(BootMediaType); + + if (VendorSpec[0] == 1) + { + // "Language and Version Information (IBM)" + + unsigned i; + for (i = 1; i < sizeof(VendorSpec); i++) + if (VendorSpec[i] > 0x7F) + break; + if (i == sizeof(VendorSpec)) + { + s.Add_Minus(); + for (i = 1; i < sizeof(VendorSpec); i++) + { + char c = (char)VendorSpec[i]; + if (c == 0) + break; + if (c == '\\' || c == '/') + c = '_'; + s += c; + } + } + } + + s += ".img"; + return s; +} + +Byte CInArchive::ReadByte() +{ + if (m_BufferPos >= kBlockSize) + m_BufferPos = 0; + if (m_BufferPos == 0) + { + size_t processed = kBlockSize; + HRESULT res = ReadStream(_stream, m_Buffer, &processed); + if (res != S_OK) + throw CSystemException(res); + if (processed != kBlockSize) + throw CUnexpectedEndException(); + UInt64 end = _position + processed; + if (PhySize < end) + PhySize = end; + } + Byte b = m_Buffer[m_BufferPos++]; + _position++; + return b; +} + +void CInArchive::ReadBytes(Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + data[i] = ReadByte(); +} + +void CInArchive::Skip(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +void CInArchive::SkipZeros(size_t size) +{ + while (size-- != 0) + { + Byte b = ReadByte(); + if (b != 0) + throw CHeaderErrorException(); + } +} + +UInt16 CInArchive::ReadUInt16() +{ + Byte b[4]; + ReadBytes(b, 4); + UInt32 val = 0; + for (int i = 0; i < 2; i++) + { + if (b[i] != b[3 - i]) + IncorrectBigEndian = true; + val |= ((UInt32)(b[i]) << (8 * i)); + } + return (UInt16)val; +} + +UInt32 CInArchive::ReadUInt32Le() +{ + UInt32 val = 0; + for (int i = 0; i < 4; i++) + val |= ((UInt32)(ReadByte()) << (8 * i)); + return val; +} + +UInt32 CInArchive::ReadUInt32Be() +{ + UInt32 val = 0; + for (int i = 0; i < 4; i++) + { + val <<= 8; + val |= ReadByte(); + } + return val; +} + +UInt32 CInArchive::ReadUInt32() +{ + Byte b[8]; + ReadBytes(b, 8); + UInt32 val = 0; + for (int i = 0; i < 4; i++) + { + if (b[i] != b[7 - i]) + throw CEndianErrorException(); + val |= ((UInt32)(b[i]) << (8 * i)); + } + return val; +} + +UInt32 CInArchive::ReadDigits(int numDigits) +{ + UInt32 res = 0; + for (int i = 0; i < numDigits; i++) + { + Byte b = ReadByte(); + if (b < '0' || b > '9') + { + if (b == 0 || b == ' ') // it's bug in some CD's + b = '0'; + else + throw CHeaderErrorException(); + } + UInt32 d = (UInt32)(b - '0'); + res *= 10; + res += d; + } + return res; +} + +void CInArchive::ReadDateTime(CDateTime &d) +{ + d.Year = (UInt16)ReadDigits(4); + d.Month = (Byte)ReadDigits(2); + d.Day = (Byte)ReadDigits(2); + d.Hour = (Byte)ReadDigits(2); + d.Minute = (Byte)ReadDigits(2); + d.Second = (Byte)ReadDigits(2); + d.Hundredths = (Byte)ReadDigits(2); + d.GmtOffset = (signed char)ReadByte(); +} + +void CInArchive::ReadBootRecordDescriptor(CBootRecordDescriptor &d) +{ + ReadBytes(d.BootSystemId, sizeof(d.BootSystemId)); + ReadBytes(d.BootId, sizeof(d.BootId)); + ReadBytes(d.BootSystemUse, sizeof(d.BootSystemUse)); +} + +void CInArchive::ReadRecordingDateTime(CRecordingDateTime &t) +{ + t.Year = ReadByte(); + t.Month = ReadByte(); + t.Day = ReadByte(); + t.Hour = ReadByte(); + t.Minute = ReadByte(); + t.Second = ReadByte(); + t.GmtOffset = (signed char)ReadByte(); +} + +void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len) +{ + r.ExtendedAttributeRecordLen = ReadByte(); + if (r.ExtendedAttributeRecordLen != 0) + throw CHeaderErrorException(); + r.ExtentLocation = ReadUInt32(); + r.Size = ReadUInt32(); + ReadRecordingDateTime(r.DateTime); + r.FileFlags = ReadByte(); + r.FileUnitSize = ReadByte(); + r.InterleaveGapSize = ReadByte(); + r.VolSequenceNumber = ReadUInt16(); + Byte idLen = ReadByte(); + r.FileId.Alloc(idLen); + ReadBytes((Byte *)r.FileId, idLen); + unsigned padSize = 1 - (idLen & 1); + + // SkipZeros(padSize); + Skip(padSize); // it's bug in some cd's. Must be zeros + + unsigned curPos = 33 + idLen + padSize; + if (curPos > len) + throw CHeaderErrorException(); + unsigned rem = len - curPos; + r.SystemUse.Alloc(rem); + ReadBytes((Byte *)r.SystemUse, rem); +} + +void CInArchive::ReadDirRecord(CDirRecord &r) +{ + Byte len = ReadByte(); + // Some CDs can have incorrect value len = 48 ('0') in VolumeDescriptor. + // But maybe we must use real "len" for other records. + len = 34; + ReadDirRecord2(r, len); +} + +void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d) +{ + d.VolFlags = ReadByte(); + ReadBytes(d.SystemId, sizeof(d.SystemId)); + ReadBytes(d.VolumeId, sizeof(d.VolumeId)); + SkipZeros(8); + d.VolumeSpaceSize = ReadUInt32(); + ReadBytes(d.EscapeSequence, sizeof(d.EscapeSequence)); + d.VolumeSetSize = ReadUInt16(); + d.VolumeSequenceNumber = ReadUInt16(); + d.LogicalBlockSize = ReadUInt16(); + d.PathTableSize = ReadUInt32(); + d.LPathTableLocation = ReadUInt32Le(); + d.LOptionalPathTableLocation = ReadUInt32Le(); + d.MPathTableLocation = ReadUInt32Be(); + d.MOptionalPathTableLocation = ReadUInt32Be(); + ReadDirRecord(d.RootDirRecord); + ReadBytes(d.VolumeSetId, sizeof(d.VolumeSetId)); + ReadBytes(d.PublisherId, sizeof(d.PublisherId)); + ReadBytes(d.DataPreparerId, sizeof(d.DataPreparerId)); + ReadBytes(d.ApplicationId, sizeof(d.ApplicationId)); + ReadBytes(d.CopyrightFileId, sizeof(d.CopyrightFileId)); + ReadBytes(d.AbstractFileId, sizeof(d.AbstractFileId)); + ReadBytes(d.BibFileId, sizeof(d.BibFileId)); + ReadDateTime(d.CTime); + ReadDateTime(d.MTime); + ReadDateTime(d.ExpirationTime); + ReadDateTime(d.EffectiveTime); + const Byte fileStructureVersion = ReadByte(); + // d.FileStructureVersion = fileStructureVersion; + if (fileStructureVersion != 1 && // ECMA-119 + fileStructureVersion != 2) // some ISO files have fileStructureVersion == 2. + { + // v24.05: we ignore that field, because we don't know what exact values are allowed there + // throw CHeaderErrorException(); + } + SkipZeros(1); // (Reserved for future standardization) + ReadBytes(d.ApplicationUse, sizeof(d.ApplicationUse)); + // Most ISO contain zeros in the following field (reserved for future standardization). + // But some ISO programs write some data to that area. + // So we disable check for zeros. + Skip(653); // SkipZeros(653); +} + +static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' }; + +/* +static const Byte kSig_NSR02[5] = { 'N', 'S', 'R', '0', '2' }; +static const Byte kSig_NSR03[5] = { 'N', 'S', 'R', '0', '3' }; +static const Byte kSig_BEA01[5] = { 'B', 'E', 'A', '0', '1' }; +static const Byte kSig_TEA01[5] = { 'T', 'E', 'A', '0', '1' }; +*/ + +static inline bool CheckSignature(const Byte *sig, const Byte *data) +{ + for (int i = 0; i < 5; i++) + if (sig[i] != data[i]) + return false; + return true; +} + +void CInArchive::SeekToBlock(UInt32 blockIndex) +{ + const HRESULT res = _stream->Seek( + (Int64)((UInt64)blockIndex * VolDescs[MainVolDescIndex].LogicalBlockSize), + STREAM_SEEK_SET, &_position); + if (res != S_OK) + throw CSystemException(res); + m_BufferPos = 0; +} + +static const int kNumLevelsMax = 256; + +void CInArchive::ReadDir(CDir &d, int level) +{ + if (!d.IsDir()) + return; + if (level > kNumLevelsMax) + { + TooDeepDirs = true; + return; + } + + { + FOR_VECTOR (i, UniqStartLocations) + if (UniqStartLocations[i] == d.ExtentLocation) + { + SelfLinkedDirs = true; + return; + } + UniqStartLocations.Add(d.ExtentLocation); + } + + SeekToBlock(d.ExtentLocation); + UInt64 startPos = _position; + + bool firstItem = true; + for (;;) + { + UInt64 offset = _position - startPos; + if (offset >= d.Size) + break; + Byte len = ReadByte(); + if (len == 0) + continue; + CDir subItem; + ReadDirRecord2(subItem, len); + if (firstItem && level == 0) + IsSusp = subItem.CheckSusp(SuspSkipSize); + + if (!subItem.IsSystemItem()) + d._subItems.Add(subItem); + + firstItem = false; + } + FOR_VECTOR (i, d._subItems) + ReadDir(d._subItems[i], level + 1); + + UniqStartLocations.DeleteBack(); +} + +void CInArchive::CreateRefs(CDir &d) +{ + if (!d.IsDir()) + return; + for (unsigned i = 0; i < d._subItems.Size();) + { + CRef ref; + CDir &subItem = d._subItems[i]; + subItem.Parent = &d; + ref.Dir = &d; + ref.Index = i++; + ref.NumExtents = 1; + ref.TotalSize = subItem.Size; + if (subItem.IsNonFinalExtent()) + { + for (;;) + { + if (i == d._subItems.Size()) + { + HeadersError = true; + break; + } + const CDir &next = d._subItems[i]; + if (!subItem.AreMultiPartEqualWith(next)) + break; + i++; + ref.NumExtents++; + ref.TotalSize += next.Size; + if (!next.IsNonFinalExtent()) + break; + } + } + Refs.Add(ref); + CreateRefs(subItem); + } +} + +void CInArchive::ReadBootInfo() +{ + if (!_bootIsDefined) + return; + HeadersError = true; + + if (memcmp(_bootDesc.BootSystemId, kElToritoSpec, sizeof(_bootDesc.BootSystemId)) != 0) + return; + + UInt32 blockIndex = GetUi32(_bootDesc.BootSystemUse); + SeekToBlock(blockIndex); + + Byte buf[32]; + ReadBytes(buf, 32); + + if (buf[0] != NBootEntryId::kValidationEntry + || buf[2] != 0 + || buf[3] != 0 + || buf[30] != 0x55 + || buf[31] != 0xAA) + return; + + { + UInt32 sum = 0; + for (unsigned i = 0; i < 32; i += 2) + sum += GetUi16(buf + i); + if ((sum & 0xFFFF) != 0) + return; + /* + CBootValidationEntry e; + e.PlatformId = buf[1]; + memcpy(e.Id, buf + 4, sizeof(e.Id)); + // UInt16 checkSum = GetUi16(p + 28); + */ + } + + ReadBytes(buf, 32); + { + CBootInitialEntry e; + if (!e.Parse(buf)) + return; + BootEntries.Add(e); + } + + bool error = false; + + for (;;) + { + ReadBytes(buf, 32); + Byte headerIndicator = buf[0]; + if (headerIndicator != NBootEntryId::kMoreHeaders + && headerIndicator != NBootEntryId::kFinalHeader) + break; + + // Section Header + // Byte platform = p[1]; + unsigned numEntries = GetUi16(buf + 2); + // id[28] + + for (unsigned i = 0; i < numEntries; i++) + { + ReadBytes(buf, 32); + CBootInitialEntry e; + if (!e.Parse(buf)) + { + error = true; + break; + } + if (e.BootMediaType & (1 << 5)) + { + // Section entry extension + for (unsigned j = 0;; j++) + { + ReadBytes(buf, 32); + if (j > 32 || buf[0] != NBootEntryId::kExtensionIndicator) + { + error = true; + break; + } + if ((buf[1] & (1 << 5)) == 0) + break; + // info += (buf + 2, 30) + } + } + BootEntries.Add(e); + } + + if (headerIndicator != NBootEntryId::kMoreHeaders) + break; + } + + HeadersError = error; +} + +HRESULT CInArchive::Open2() +{ + _position = 0; + RINOK(InStream_GetSize_SeekToEnd(_stream, _fileSize)) + if (_fileSize < kStartPos) + return S_FALSE; + RINOK(_stream->Seek(kStartPos, STREAM_SEEK_SET, &_position)) + + PhySize = _position; + m_BufferPos = 0; + // BlockSize = kBlockSize; + + for (;;) + { + Byte sig[7]; + ReadBytes(sig, 7); + Byte ver = sig[6]; + + if (!CheckSignature(kSig_CD001, sig + 1)) + { + return S_FALSE; + /* + if (sig[0] != 0 || ver != 1) + break; + if (CheckSignature(kSig_BEA01, sig + 1)) + { + } + else if (CheckSignature(kSig_TEA01, sig + 1)) + { + break; + } + else if (CheckSignature(kSig_NSR02, sig + 1)) + { + } + else + break; + SkipZeros(0x800 - 7); + continue; + */ + } + + // version = 2 for ISO 9660:1999? + if (ver > 2) + return S_FALSE; + + if (sig[0] == NVolDescType::kTerminator) + { + break; + // Skip(0x800 - 7); + // continue; + } + + switch (sig[0]) + { + case NVolDescType::kBootRecord: + { + _bootIsDefined = true; + ReadBootRecordDescriptor(_bootDesc); + break; + } + case NVolDescType::kPrimaryVol: + case NVolDescType::kSupplementaryVol: + { + // some ISOs have two PrimaryVols. + CVolumeDescriptor vd; + ReadVolumeDescriptor(vd); + if (sig[0] == NVolDescType::kPrimaryVol) + { + // some burners write "Joliet" Escape Sequence to primary volume + memset(vd.EscapeSequence, 0, sizeof(vd.EscapeSequence)); + } + VolDescs.Add(vd); + break; + } + default: + break; + } + } + + if (VolDescs.IsEmpty()) + return S_FALSE; + for (MainVolDescIndex = (int)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) + return S_FALSE; + + { + FOR_VECTOR (i, VolDescs) + { + const CVolumeDescriptor &vd2 = VolDescs[i]; + UpdatePhySize(0, vd2.Get_VolumeSpaceSize_inBytes()); + } + } + + + IsArc = true; + + (CDirRecord &)_rootDir = vd.RootDirRecord; + ReadDir(_rootDir, 0); + CreateRefs(_rootDir); + ReadBootInfo(); + + { + FOR_VECTOR (i, Refs) + { + const CRef &ref = Refs[i]; + for (UInt32 j = 0; j < ref.NumExtents; j++) + { + const CDir &item = ref.Dir->_subItems[ref.Index + j]; + if (!item.IsDir() && item.Size != 0) + UpdatePhySize(item.ExtentLocation, item.Size); + } + } + } + + { + // find boot item for expand: + // UEFI Specification : 13.3.2.1. ISO-9660 and El Torito + _expand_BootEntries_index = -1; + FOR_VECTOR (i, BootEntries) + { + const CBootInitialEntry &be = BootEntries[i]; + if (be.SectorCount <= 1 && be.BootMediaType == NBootMediaType::kNoEmulation) + if (_expand_BootEntries_index == -1 + || be.LoadRBA >= BootEntries[_expand_BootEntries_index].LoadRBA) + _expand_BootEntries_index = (int)i; + } + } + + { + FOR_VECTOR (i, BootEntries) + { + const CBootInitialEntry &be = BootEntries[i]; + UpdatePhySize(be.LoadRBA, GetBootItemSize(i)); + } + } + + if (PhySize < _fileSize) + { + UInt64 rem = _fileSize - PhySize; + const UInt64 kRemMax = 1 << 21; + if (rem <= kRemMax) + { + RINOK(InStream_SeekSet(_stream, PhySize)) + bool areThereNonZeros = false; + UInt64 numZeros = 0; + RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax)) + if (!areThereNonZeros) + PhySize += numZeros; + } + } + + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream) +{ + Clear(); + _stream = inStream; + try { return Open2(); } + catch(const CSystemException &e) { return e.ErrorCode; } + catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; } + catch(CHeaderErrorException &) { HeadersError = true; return S_FALSE; } + catch(CEndianErrorException &) { IncorrectBigEndian = true; return S_FALSE; } +} + +void CInArchive::Clear() +{ + IsArc = false; + UnexpectedEnd = false; + HeadersError = false; + IncorrectBigEndian = false; + TooDeepDirs = false; + SelfLinkedDirs = false; + + UniqStartLocations.Clear(); + + Refs.Clear(); + _rootDir.Clear(); + VolDescs.Clear(); + _bootIsDefined = false; + BootEntries.Clear(); + SuspSkipSize = 0; + IsSusp = false; + + _expand_BootEntries_index = -1; +} + + +UInt64 CInArchive::GetBootItemSize(unsigned index) const +{ + const CBootInitialEntry &be = BootEntries[index]; + UInt64 size = be.GetSize(); + if (be.BootMediaType == NBootMediaType::k1d2Floppy) size = 1200 << 10; + else if (be.BootMediaType == NBootMediaType::k1d44Floppy) size = 1440 << 10; + else if (be.BootMediaType == NBootMediaType::k2d88Floppy) size = 2880 << 10; + const UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize; + if (startPos < _fileSize) + { + const UInt64 rem = _fileSize - startPos; + /* + UEFI modification to ISO specification: + because SectorCount is 16-bit, size is limited by (32 MB). + UEFI Specification : + 13.3.2.1. ISO-9660 and El Torito + If the value of Sector Count is set to 0 or 1, + EFI will assume the system partition consumes the space + from the beginning of the "no emulation" image to the end of the CD-ROM. + */ + // + if ((int)index == _expand_BootEntries_index || rem < size) + size = rem; + } + return size; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoIn.h 2016-02-01 16:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoIn.h 2024-03-03 16:00:00.000000000 +0000 @@ -1,333 +1,322 @@ -// Archive/IsoIn.h - -#ifndef __ARCHIVE_ISO_IN_H -#define __ARCHIVE_ISO_IN_H - -#include "../../../Common/IntToString.h" -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -#include "IsoHeader.h" -#include "IsoItem.h" - -namespace NArchive { -namespace NIso { - -struct CDir: public CDirRecord -{ - CDir *Parent; - CObjectVector _subItems; - - void Clear() - { - Parent = 0; - _subItems.Clear(); - } - - AString GetPath(bool checkSusp, unsigned skipSize) const - { - AString s; - - unsigned len = 0; - const CDir *cur = this; - - for (;;) - { - unsigned curLen; - cur->GetNameCur(checkSusp, skipSize, curLen); - len += curLen; - cur = cur->Parent; - if (!cur || !cur->Parent) - break; - len++; - } - - char *p = s.GetBuf_SetEnd(len) + len; - - cur = this; - - for (;;) - { - unsigned curLen; - const Byte *name = cur->GetNameCur(checkSusp, skipSize, curLen); - p -= curLen; - if (curLen != 0) - memcpy(p, name, curLen); - cur = cur->Parent; - if (!cur || !cur->Parent) - break; - p--; - *p = CHAR_PATH_SEPARATOR; - } - - return s; - } - - void GetPathU(UString &s) const - { - s.Empty(); - - unsigned len = 0; - const CDir *cur = this; - - for (;;) - { - unsigned curLen = (unsigned)(cur->FileId.Size() / 2); - const Byte *fid = cur->FileId; - - unsigned i; - for (i = 0; i < curLen; i++) - if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0) - break; - len += i; - cur = cur->Parent; - if (!cur || !cur->Parent) - break; - len++; - } - - wchar_t *p = s.GetBuf_SetEnd(len) + len; - - cur = this; - - for (;;) - { - unsigned curLen = (unsigned)(cur->FileId.Size() / 2); - const Byte *fid = cur->FileId; - - unsigned i; - for (i = 0; i < curLen; i++) - if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0) - break; - curLen = i; - - p -= curLen; - for (i = 0; i < curLen; i++) - p[i] = (wchar_t)(((wchar_t)fid[i * 2] << 8) | fid[i * 2 + 1]); - cur = cur->Parent; - if (!cur || !cur->Parent) - break; - p--; - *p = WCHAR_PATH_SEPARATOR; - } - } -}; - -struct CDateTime -{ - UInt16 Year; - Byte Month; - Byte Day; - Byte Hour; - Byte Minute; - Byte Second; - Byte Hundredths; - signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. - - bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && - Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; } - - bool GetFileTime(FILETIME &ft) const - { - UInt64 value; - bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, value); - if (res) - { - value -= (Int64)((Int32)GmtOffset * 15 * 60); - value *= 10000000; - } - ft.dwLowDateTime = (DWORD)value; - ft.dwHighDateTime = (DWORD)(value >> 32); - return res; - } -}; - -struct CBootRecordDescriptor -{ - Byte BootSystemId[32]; // a-characters - Byte BootId[32]; // a-characters - Byte BootSystemUse[1977]; -}; - -struct CBootValidationEntry -{ - Byte PlatformId; - Byte Id[24]; // to identify the manufacturer/developer of the CD-ROM. -}; - -struct CBootInitialEntry -{ - bool Bootable; - Byte BootMediaType; - UInt16 LoadSegment; - /* This is the load segment for the initial boot image. If this - value is 0 the system will use the traditional segment of 7C0. If this value - is non-zero the system will use the specified segment. This applies to x86 - architectures only. For "flat" model architectures (such as Motorola) this - is the address divided by 10. */ - Byte SystemType; // This must be a copy of byte 5 (System Type) from the - // Partition Table found in the boot image. - UInt16 SectorCount; // This is the number of virtual/emulated sectors the system - // will store at Load Segment during the initial boot procedure. - UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use - // Relative/Logical block addressing. - - Byte VendorSpec[20]; - - UInt32 GetSize() const - { - // if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10); - return (UInt32)SectorCount * 512; - } - - bool Parse(const Byte *p); - AString GetName() const; -}; - -struct CVolumeDescriptor -{ - Byte VolFlags; - Byte SystemId[32]; // a-characters. An identification of a system - // which can recognize and act upon the content of the Logical - // Sectors with logical Sector Numbers 0 to 15 of the volume. - Byte VolumeId[32]; // d-characters. An identification of the volume. - UInt32 VolumeSpaceSize; // the number of Logical Blocks in which the Volume Space of the volume is recorded - Byte EscapeSequence[32]; - UInt16 VolumeSetSize; - UInt16 VolumeSequenceNumber; // the ordinal number of the volume in the Volume Set of which the volume is a member. - UInt16 LogicalBlockSize; - UInt32 PathTableSize; - UInt32 LPathTableLocation; - UInt32 LOptionalPathTableLocation; - UInt32 MPathTableLocation; - UInt32 MOptionalPathTableLocation; - CDirRecord RootDirRecord; - Byte VolumeSetId[128]; - Byte PublisherId[128]; - Byte DataPreparerId[128]; - Byte ApplicationId[128]; - Byte CopyrightFileId[37]; - Byte AbstractFileId[37]; - Byte BibFileId[37]; - CDateTime CTime; - CDateTime MTime; - CDateTime ExpirationTime; - CDateTime EffectiveTime; - Byte FileStructureVersion; // = 1; - Byte ApplicationUse[512]; - - bool IsJoliet() const - { - if ((VolFlags & 1) != 0) - return false; - Byte b = EscapeSequence[2]; - return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && - (b == 0x40 || b == 0x43 || b == 0x45)); - } -}; - -struct CRef -{ - const CDir *Dir; - UInt32 Index; - UInt32 NumExtents; - UInt64 TotalSize; -}; - -const UInt32 kBlockSize = 1 << 11; - -class CInArchive -{ - IInStream *_stream; - UInt64 _position; - - UInt32 m_BufferPos; - - CDir _rootDir; - bool _bootIsDefined; - CBootRecordDescriptor _bootDesc; - - void Skip(size_t size); - void SkipZeros(size_t size); - Byte ReadByte(); - void ReadBytes(Byte *data, UInt32 size); - UInt16 ReadUInt16(); - UInt32 ReadUInt32Le(); - UInt32 ReadUInt32Be(); - UInt32 ReadUInt32(); - UInt64 ReadUInt64(); - UInt32 ReadDigits(int numDigits); - void ReadDateTime(CDateTime &d); - void ReadRecordingDateTime(CRecordingDateTime &t); - void ReadDirRecord2(CDirRecord &r, Byte len); - void ReadDirRecord(CDirRecord &r); - - void ReadBootRecordDescriptor(CBootRecordDescriptor &d); - void ReadVolumeDescriptor(CVolumeDescriptor &d); - - void SeekToBlock(UInt32 blockIndex); - void ReadDir(CDir &d, int level); - void CreateRefs(CDir &d); - - void ReadBootInfo(); - HRESULT Open2(); -public: - HRESULT Open(IInStream *inStream); - void Clear(); - - UInt64 _fileSize; - UInt64 PhySize; - - CRecordVector Refs; - CObjectVector VolDescs; - int MainVolDescIndex; - // UInt32 BlockSize; - CObjectVector BootEntries; - - bool IsArc; - bool UnexpectedEnd; - bool HeadersError; - bool IncorrectBigEndian; - bool TooDeepDirs; - bool SelfLinkedDirs; - CRecordVector UniqStartLocations; - - Byte m_Buffer[kBlockSize]; - - void UpdatePhySize(UInt32 blockIndex, UInt64 size) - { - const UInt64 alignedSize = (size + kBlockSize - 1) & ~((UInt64)kBlockSize - 1); - const UInt64 end = (UInt64)blockIndex * kBlockSize + alignedSize; - if (PhySize < end) - PhySize = end; - } - - bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } - - UInt64 GetBootItemSize(int index) const - { - const CBootInitialEntry &be = BootEntries[index]; - UInt64 size = be.GetSize(); - if (be.BootMediaType == NBootMediaType::k1d2Floppy) - size = (1200 << 10); - else if (be.BootMediaType == NBootMediaType::k1d44Floppy) - size = (1440 << 10); - else if (be.BootMediaType == NBootMediaType::k2d88Floppy) - size = (2880 << 10); - UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize; - if (startPos < _fileSize) - { - if (_fileSize - startPos < size) - size = _fileSize - startPos; - } - return size; - } - - bool IsSusp; - unsigned SuspSkipSize; -}; - -}} - -#endif +// Archive/IsoIn.h + +#ifndef ZIP7_INC_ARCHIVE_ISO_IN_H +#define ZIP7_INC_ARCHIVE_ISO_IN_H + +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +#include "IsoHeader.h" +#include "IsoItem.h" + +namespace NArchive { +namespace NIso { + +struct CDir: public CDirRecord +{ + CDir *Parent; + CObjectVector _subItems; + + void Clear() + { + Parent = NULL; + _subItems.Clear(); + } + + AString GetPath(bool checkSusp, unsigned skipSize) const + { + AString s; + + unsigned len = 0; + const CDir *cur = this; + + for (;;) + { + unsigned curLen; + cur->GetNameCur(checkSusp, skipSize, curLen); + len += curLen; + cur = cur->Parent; + if (!cur || !cur->Parent) + break; + len++; + } + + char *p = s.GetBuf_SetEnd(len) + len; + + cur = this; + + for (;;) + { + unsigned curLen; + const Byte *name = cur->GetNameCur(checkSusp, skipSize, curLen); + p -= curLen; + if (curLen != 0) + memcpy(p, name, curLen); + cur = cur->Parent; + if (!cur || !cur->Parent) + break; + p--; + *p = CHAR_PATH_SEPARATOR; + } + + return s; + } + + void GetPathU(UString &s) const + { + s.Empty(); + + unsigned len = 0; + const CDir *cur = this; + + for (;;) + { + unsigned curLen = (unsigned)(cur->FileId.Size() / 2); + const Byte *fid = cur->FileId; + + unsigned i; + for (i = 0; i < curLen; i++) + if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0) + break; + len += i; + cur = cur->Parent; + if (!cur || !cur->Parent) + break; + len++; + } + + wchar_t *p = s.GetBuf_SetEnd(len) + len; + + cur = this; + + for (;;) + { + unsigned curLen = (unsigned)(cur->FileId.Size() / 2); + const Byte *fid = cur->FileId; + + unsigned i; + for (i = 0; i < curLen; i++) + if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0) + break; + curLen = i; + + p -= curLen; + for (i = 0; i < curLen; i++) + p[i] = (wchar_t)(((wchar_t)fid[i * 2] << 8) | fid[i * 2 + 1]); + cur = cur->Parent; + if (!cur || !cur->Parent) + break; + p--; + *p = WCHAR_PATH_SEPARATOR; + } + } +}; + +struct CDateTime +{ + UInt16 Year; + Byte Month; + Byte Day; + Byte Hour; + Byte Minute; + Byte Second; + Byte Hundredths; + signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. + + bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 && + Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; } + + bool GetFileTime(NWindows::NCOM::CPropVariant &prop) const + { + UInt64 v; + const bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, v); + if (res) + { + v = (UInt64)((Int64)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); + } + return res; + } +}; + +struct CBootRecordDescriptor +{ + Byte BootSystemId[32]; // a-characters + Byte BootId[32]; // a-characters + Byte BootSystemUse[1977]; +}; + +struct CBootValidationEntry +{ + Byte PlatformId; + Byte Id[24]; // to identify the manufacturer/developer of the CD-ROM. +}; + +struct CBootInitialEntry +{ + bool Bootable; + Byte BootMediaType; + UInt16 LoadSegment; + /* This is the load segment for the initial boot image. If this + value is 0 the system will use the traditional segment of 7C0. If this value + is non-zero the system will use the specified segment. This applies to x86 + architectures only. For "flat" model architectures (such as Motorola) this + is the address divided by 10. */ + Byte SystemType; // This must be a copy of byte 5 (System Type) from the + // Partition Table found in the boot image. + UInt16 SectorCount; // This is the number of virtual/emulated sectors the system + // will store at Load Segment during the initial boot procedure. + UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use + // Relative/Logical block addressing. + + Byte VendorSpec[20]; + + UInt32 GetSize() const + { + // if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10); + return (UInt32)SectorCount * 512; + } + + bool Parse(const Byte *p); + AString GetName() const; +}; + +struct CVolumeDescriptor +{ + Byte VolFlags; + Byte SystemId[32]; // a-characters. An identification of a system + // which can recognize and act upon the content of the Logical + // Sectors with logical Sector Numbers 0 to 15 of the volume. + Byte VolumeId[32]; // d-characters. An identification of the volume. + UInt32 VolumeSpaceSize; // the number of Logical Blocks in which the Volume Space of the volume is recorded + Byte EscapeSequence[32]; + UInt16 VolumeSetSize; + UInt16 VolumeSequenceNumber; // the ordinal number of the volume in the Volume Set of which the volume is a member. + UInt16 LogicalBlockSize; + UInt32 PathTableSize; + UInt32 LPathTableLocation; + UInt32 LOptionalPathTableLocation; + UInt32 MPathTableLocation; + UInt32 MOptionalPathTableLocation; + CDirRecord RootDirRecord; + Byte VolumeSetId[128]; + Byte PublisherId[128]; + Byte DataPreparerId[128]; + Byte ApplicationId[128]; + Byte CopyrightFileId[37]; + Byte AbstractFileId[37]; + Byte BibFileId[37]; + CDateTime CTime; + CDateTime MTime; + CDateTime ExpirationTime; + CDateTime EffectiveTime; + // Byte FileStructureVersion; // = 1; + Byte ApplicationUse[512]; + + bool IsJoliet() const + { + if ((VolFlags & 1) != 0) + return false; + const Byte b = EscapeSequence[2]; + return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F && + (b == 0x40 || b == 0x43 || b == 0x45)); + } + + UInt64 Get_VolumeSpaceSize_inBytes() const { return (UInt64)VolumeSpaceSize * LogicalBlockSize; } +}; + +struct CRef +{ + const CDir *Dir; + UInt32 Index; + UInt32 NumExtents; + UInt64 TotalSize; +}; + +const UInt32 kBlockSize = 1 << 11; + +class CInArchive +{ + IInStream *_stream; + UInt64 _position; + + UInt32 m_BufferPos; + + void Skip(size_t size); + void SkipZeros(size_t size); + Byte ReadByte(); + void ReadBytes(Byte *data, UInt32 size); + UInt16 ReadUInt16(); + UInt32 ReadUInt32Le(); + UInt32 ReadUInt32Be(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + UInt32 ReadDigits(int numDigits); + void ReadDateTime(CDateTime &d); + void ReadRecordingDateTime(CRecordingDateTime &t); + void ReadDirRecord2(CDirRecord &r, Byte len); + void ReadDirRecord(CDirRecord &r); + + void ReadBootRecordDescriptor(CBootRecordDescriptor &d); + void ReadVolumeDescriptor(CVolumeDescriptor &d); + + void SeekToBlock(UInt32 blockIndex); + void ReadDir(CDir &d, int level); + void CreateRefs(CDir &d); + + void ReadBootInfo(); + HRESULT Open2(); +public: + HRESULT Open(IInStream *inStream); + void Clear(); + + UInt64 _fileSize; + UInt64 PhySize; + + CRecordVector Refs; + CObjectVector VolDescs; + int MainVolDescIndex; + // UInt32 BlockSize; + CObjectVector BootEntries; + +private: + bool _bootIsDefined; +public: + bool IsArc; + bool UnexpectedEnd; + bool HeadersError; + bool IncorrectBigEndian; + bool TooDeepDirs; + bool SelfLinkedDirs; + bool IsSusp; + unsigned SuspSkipSize; + + int _expand_BootEntries_index; + + CRecordVector UniqStartLocations; + + void UpdatePhySize(const UInt32 blockIndex, const UInt64 size) + { + const UInt64 alignedSize = (size + kBlockSize - 1) & ~((UInt64)kBlockSize - 1); + const UInt64 end = (UInt64)blockIndex * kBlockSize + alignedSize; + if (PhySize < end) + PhySize = end; + } + + bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } + + UInt64 GetBootItemSize(unsigned index) const; + +private: + CDir _rootDir; + Byte m_Buffer[kBlockSize]; + CBootRecordDescriptor _bootDesc; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoItem.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoItem.h 2023-11-29 11:00:00.000000000 +0000 @@ -1,150 +1,320 @@ -// Archive/IsoItem.h - -#ifndef __ARCHIVE_ISO_ITEM_H -#define __ARCHIVE_ISO_ITEM_H - -#include "../../../Common/MyString.h" -#include "../../../Common/MyBuffer.h" - -#include "../../../Windows/TimeUtils.h" - -#include "IsoHeader.h" - -namespace NArchive { -namespace NIso { - -struct CRecordingDateTime -{ - Byte Year; - Byte Month; - Byte Day; - Byte Hour; - Byte Minute; - Byte Second; - signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. - - bool GetFileTime(FILETIME &ft) const - { - UInt64 value; - bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, value); - if (res) - { - value -= (Int64)((Int32)GmtOffset * 15 * 60); - value *= 10000000; - } - ft.dwLowDateTime = (DWORD)value; - ft.dwHighDateTime = (DWORD)(value >> 32); - return res; - } -}; - -struct CDirRecord -{ - UInt32 ExtentLocation; - UInt32 Size; - CRecordingDateTime DateTime; - Byte FileFlags; - Byte FileUnitSize; - Byte InterleaveGapSize; - Byte ExtendedAttributeRecordLen; - UInt16 VolSequenceNumber; - CByteBuffer FileId; - CByteBuffer SystemUse; - - bool AreMultiPartEqualWith(const CDirRecord &a) const - { - return FileId == a.FileId - && (FileFlags & (~NFileFlags::kNonFinalExtent)) == - (a.FileFlags & (~NFileFlags::kNonFinalExtent)); - } - - bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; } - bool IsNonFinalExtent() const { return (FileFlags & NFileFlags::kNonFinalExtent) != 0; } - - bool IsSystemItem() const - { - if (FileId.Size() != 1) - return false; - Byte b = *(const Byte *)FileId; - return (b == 0 || b == 1); - } - - const Byte* FindSuspName(unsigned skipSize, unsigned &lenRes) const - { - lenRes = 0; - if (SystemUse.Size() < skipSize) - return 0; - const Byte *p = (const Byte *)SystemUse + skipSize; - unsigned rem = (unsigned)(SystemUse.Size() - skipSize); - while (rem >= 5) - { - unsigned len = p[2]; - if (len < 3 || len > rem) - return 0; - if (p[0] == 'N' && p[1] == 'M' && p[3] == 1) - { - if (len < 5) - return 0; // Check it - lenRes = len - 5; - return p + 5; - } - p += len; - rem -= len; - } - return 0; - } - - const Byte* GetNameCur(bool checkSusp, int skipSize, unsigned &nameLenRes) const - { - const Byte *res = NULL; - unsigned len = 0; - if (checkSusp) - res = FindSuspName(skipSize, len); - if (!res) - { - res = (const Byte *)FileId; - len = (unsigned)FileId.Size(); - } - unsigned i; - for (i = 0; i < len; i++) - if (res[i] == 0) - break; - nameLenRes = i; - return res; - } - - - bool CheckSusp(const Byte *p, unsigned &startPos) const - { - if (p[0] == 'S' && - p[1] == 'P' && - p[2] == 0x7 && - p[3] == 0x1 && - p[4] == 0xBE && - p[5] == 0xEF) - { - startPos = p[6]; - return true; - } - return false; - } - - bool CheckSusp(unsigned &startPos) const - { - const Byte *p = (const Byte *)SystemUse; - unsigned len = (int)SystemUse.Size(); - const unsigned kMinLen = 7; - if (len < kMinLen) - return false; - if (CheckSusp(p, startPos)) - return true; - const unsigned kOffset2 = 14; - if (len < kOffset2 + kMinLen) - return false; - return CheckSusp(p + kOffset2, startPos); - } -}; - -}} - -#endif +// Archive/IsoItem.h + +#ifndef ZIP7_INC_ARCHIVE_ISO_ITEM_H +#define ZIP7_INC_ARCHIVE_ISO_ITEM_H + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyString.h" +#include "../../../Common/MyBuffer.h" + +#include "../../../Windows/TimeUtils.h" + +#include "IsoHeader.h" + +namespace NArchive { +namespace NIso { + +struct CRecordingDateTime +{ + Byte Year; + Byte Month; + Byte Day; + Byte Hour; + Byte Minute; + Byte Second; + signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. + + bool GetFileTime(NWindows::NCOM::CPropVariant &prop) const + { + UInt64 v; + const bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, v); + if (res) + { + v = (UInt64)((Int64)v - (Int64)((Int32)GmtOffset * 15 * 60)); + v *= 10000000; + prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base); + } + return res; + } +}; + +enum EPx +{ + k_Px_Mode, + k_Px_Links, + k_Px_User, + k_Px_Group, + k_Px_SerialNumber + + // k_Px_Num +}; + +/* +enum ETf +{ + k_Tf_CTime, + k_Tf_MTime, + k_Tf_ATime, + k_Tf_Attrib, + k_Tf_Backup, + k_Tf_Expiration, + k_Tf_Effective + + // k_Tf_Num +}; +*/ + +struct CDirRecord +{ + UInt32 ExtentLocation; + UInt32 Size; + CRecordingDateTime DateTime; + Byte FileFlags; + Byte FileUnitSize; + Byte InterleaveGapSize; + Byte ExtendedAttributeRecordLen; + UInt16 VolSequenceNumber; + CByteBuffer FileId; + CByteBuffer SystemUse; + + bool AreMultiPartEqualWith(const CDirRecord &a) const + { + return FileId == a.FileId + && (FileFlags & (~NFileFlags::kNonFinalExtent)) == + (a.FileFlags & (~NFileFlags::kNonFinalExtent)); + } + + bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; } + bool IsNonFinalExtent() const { return (FileFlags & NFileFlags::kNonFinalExtent) != 0; } + + bool IsSystemItem() const + { + if (FileId.Size() != 1) + return false; + Byte b = *(const Byte *)FileId; + return (b == 0 || b == 1); + } + + + const Byte* FindSuspRecord(unsigned skipSize, Byte id0, Byte id1, unsigned &lenRes) const + { + lenRes = 0; + if (SystemUse.Size() < skipSize) + return NULL; + const Byte *p = (const Byte *)SystemUse + skipSize; + unsigned rem = (unsigned)(SystemUse.Size() - skipSize); + while (rem >= 5) + { + unsigned len = p[2]; + if (len < 3 || len > rem) + return NULL; + if (p[0] == id0 && p[1] == id1 && p[3] == 1) + { + if (len < 4) + return NULL; // Check it + lenRes = len - 4; + return p + 4; + } + p += len; + rem -= len; + } + return NULL; + } + + + const Byte* GetNameCur(bool checkSusp, unsigned skipSize, unsigned &nameLenRes) const + { + const Byte *res = NULL; + unsigned len = 0; + if (checkSusp) + res = FindSuspRecord(skipSize, 'N', 'M', len); + if (!res || len < 1) + { + res = (const Byte *)FileId; + len = (unsigned)FileId.Size(); + } + else + { + res++; + len--; + } + unsigned i; + for (i = 0; i < len; i++) + if (res[i] == 0) + break; + nameLenRes = i; + return res; + } + + + bool GetSymLink(unsigned skipSize, AString &link) const + { + link.Empty(); + const Byte *p = NULL; + unsigned len = 0; + p = FindSuspRecord(skipSize, 'S', 'L', len); + if (!p || len < 1) + return false; + + if (*p != 0) + return false; + + p++; + len--; + + while (len != 0) + { + if (len < 2) + return false; + unsigned flags = p[0]; + unsigned cl = p[1]; + p += 2; + len -= 2; + + if (cl > len) + return false; + + bool needSlash = false; + + if (flags & (1 << 1)) link += "./"; + else if (flags & (1 << 2)) link += "../"; + else if (flags & (1 << 3)) link.Add_Slash(); + else + needSlash = true; + + for (unsigned i = 0; i < cl; i++) + { + const Byte c = p[i]; + if (c == 0) + { + break; + // return false; + } + link += (char)c; + } + + p += cl; + len -= cl; + + if (len == 0) + break; + + if (needSlash) + link.Add_Slash(); + } + + return true; + } + + static bool GetLe32Be32(const Byte *p, UInt32 &dest) + { + UInt32 v1 = GetUi32(p); + UInt32 v2 = GetBe32(p + 4); + if (v1 == v2) + { + dest = v1; + return true; + } + return false; + } + + + bool GetPx(unsigned skipSize, unsigned pxType, UInt32 &val) const + { + val = 0; + const Byte *p = NULL; + unsigned len = 0; + p = FindSuspRecord(skipSize, 'P', 'X', len); + if (!p) + return false; + // px.Clear(); + if (len < (pxType + 1) * 8) + return false; + + return GetLe32Be32(p + pxType * 8, val); + } + + /* + bool GetTf(int skipSize, unsigned pxType, CRecordingDateTime &t) const + { + const Byte *p = NULL; + unsigned len = 0; + p = FindSuspRecord(skipSize, 'T', 'F', len); + if (!p) + return false; + if (len < 1) + return false; + Byte flags = *p++; + len--; + + unsigned step = 7; + if (flags & 0x80) + { + step = 17; + return false; + } + + if ((flags & (1 << pxType)) == 0) + return false; + + for (unsigned i = 0; i < pxType; i++) + { + if (len < step) + return false; + if (flags & (1 << i)) + { + p += step; + len -= step; + } + } + + if (len < step) + return false; + + t.Year = p[0]; + t.Month = p[1]; + t.Day = p[2]; + t.Hour = p[3]; + t.Minute = p[4]; + t.Second = p[5]; + t.GmtOffset = (signed char)p[6]; + + return true; + } + */ + + bool CheckSusp(const Byte *p, unsigned &startPos) const + { + if (p[0] == 'S' && + p[1] == 'P' && + p[2] == 0x7 && + p[3] == 0x1 && + p[4] == 0xBE && + p[5] == 0xEF) + { + startPos = p[6]; + return true; + } + return false; + } + + bool CheckSusp(unsigned &startPos) const + { + const Byte *p = (const Byte *)SystemUse; + const size_t len = SystemUse.Size(); + const unsigned kMinLen = 7; + if (len < kMinLen) + return false; + if (CheckSusp(p, startPos)) + return true; + const unsigned kOffset2 = 14; + if (len < kOffset2 + kMinLen) + return false; + return CheckSusp(p + kOffset2, startPos); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/IsoRegister.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/IsoRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,21 +1,21 @@ -// IsoRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "IsoHandler.h" - -namespace NArchive { -namespace NIso { - -static const Byte k_Signature[] = { 'C', 'D', '0', '0', '1' }; - -REGISTER_ARC_I( - "Iso", "iso img", 0, 0xE7, - k_Signature, - NArchive::NIso::kStartPos + 1, - 0, - NULL) - -}} +// IsoRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "IsoHandler.h" + +namespace NArchive { +namespace NIso { + +static const Byte k_Signature[] = { 'C', 'D', '0', '0', '1' }; + +REGISTER_ARC_I( + "Iso", "iso img", NULL, 0xE7, + k_Signature, + NArchive::NIso::kStartPos + 1, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Iso/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Iso/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Iso/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/LpHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LpHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/LpHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LpHandler.cpp 2024-11-21 16:00:00.000000000 +0000 @@ -0,0 +1,1170 @@ +// 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 + +static const unsigned k_SignatureSize = 8; +static const Byte k_Signature[k_SignatureSize] = + { 0x67, 0x44, 0x6c, 0x61, 0x34, 0, 0, 0 }; + +// 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) +{ + MY_ALIGN (16) + CSha256 sha; + Sha256_Init(&sha); + Sha256_Update(&sha, data, size); + MY_ALIGN (16) + Byte calced[32]; + Sha256_Final(&sha, calced); + return memcmp(checksum, calced, 32) == 0; +} + +static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset) +{ + MY_ALIGN (4) + Byte checksum[32]; + Byte *shaData = &data[hashOffset]; + memcpy(checksum, shaData, 32); + memset(shaData, 0, 32); + return CheckSha256(data, size, checksum); +} + + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + 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); +}; + + +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(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES)) + { + MY_ALIGN (4) + Byte buf[k_Geometry_Size]; + RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size)) + if (memcmp(buf, k_Signature, k_SignatureSize) != 0) + return S_FALSE; + if (!geom.Parse(buf)) + return S_FALSE; + if (!CheckSha256_csOffset(buf, k_Geometry_Size, 8)) + return S_FALSE; + } + + CByteBuffer buffer; + RINOK(InStream_SeekToBegin(stream)) + 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; +} + + +Z7_COM7F_IMF(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 = (int)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 +} + + +Z7_COM7F_IMF(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 + +Z7_COM7F_IMF(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.Add_Dot(); + 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, Z7_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 +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + + +Z7_COM7F_IMF(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.Add_Dot(); + 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, Z7_ARRAY_SIZE(g_PartitionAttr), item.attributes); + prop = s; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + + +Z7_COM7F_IMF(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 +} + + +Z7_COM7F_IMF(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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/LvmHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LvmHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/LvmHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LvmHandler.cpp 2023-12-19 08:00:00.000000000 +0000 @@ -0,0 +1,1107 @@ +// LvmHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringToInt.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define LE_32(offs, dest) dest = Get32(p + (offs)) +#define LE_64(offs, dest) dest = Get64(p + (offs)) + +using namespace NWindows; + +namespace NArchive { +namespace NLvm { + +#define SIGNATURE { 'L', 'A', 'B', 'E', 'L', 'O', 'N', 'E' } + +static const unsigned k_SignatureSize = 8; +static const Byte k_Signature[k_SignatureSize] = SIGNATURE; + +static const unsigned k_Signature2Size = 8; +static const Byte k_Signature2[k_Signature2Size] = + { 'L', 'V', 'M', '2', ' ', '0', '0', '1' }; + +static const Byte FMTT_MAGIC[16] = + { ' ', 'L', 'V', 'M', '2', ' ', 'x', '[', '5', 'A', '%', 'r', '0', 'N', '*', '>' }; + +static const UInt32 kSectorSize = 512; + + +struct CPropVal +{ + bool IsNumber; + AString String; + UInt64 Number; + + CPropVal(): IsNumber(false), Number(0) {} +}; + + +struct CConfigProp +{ + AString Name; + + bool IsVector; + CPropVal Val; + CObjectVector Vector; + + CConfigProp(): IsVector(false) {} +}; + + +class CConfigItem +{ +public: + AString Name; + CObjectVector Props; + CObjectVector Items; + + const char *ParseItem(const char *s, int numAllowedLevels); + + int FindProp(const char *name) const throw(); + bool GetPropVal_Number(const char *name, UInt64 &val) const throw(); + bool GetPropVal_String(const char *name, AString &val) const; + + int FindSubItem(const char *tag) const throw(); +}; + +struct CConfig +{ + CConfigItem Root; + + bool Parse(const char *s); +}; + + +static bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); +} + +static const char *SkipSpaces(const char * s) +{ + for (;; s++) + { + const char c = *s; + if (c == 0) + return s; + if (!IsSpaceChar(c)) + { + if (c != '#') + return s; + s++; + for (;;) + { + const char c2 = *s; + if (c2 == 0) + return s; + if (c2 == '\n') + break; + s++; + } + } + } +} + +#define SKIP_SPACES(s) s = SkipSpaces(s); + +int CConfigItem::FindProp(const char *name) const throw() +{ + FOR_VECTOR (i, Props) + if (Props[i].Name == name) + return (int)i; + return -1; +} + +bool CConfigItem::GetPropVal_Number(const char *name, UInt64 &val) const throw() +{ + val = 0; + int index = FindProp(name); + if (index < 0) + return false; + const CConfigProp &prop = Props[index]; + if (prop.IsVector) + return false; + if (!prop.Val.IsNumber) + return false; + val = prop.Val.Number; + return true; +} + +bool CConfigItem::GetPropVal_String(const char *name, AString &val) const +{ + val.Empty(); + int index = FindProp(name); + if (index < 0) + return false; + const CConfigProp &prop = Props[index]; + if (prop.IsVector) + return false; + if (prop.Val.IsNumber) + return false; + val = prop.Val.String; + return true; +} + +int CConfigItem::FindSubItem(const char *tag) const throw() +{ + FOR_VECTOR (i, Items) + if (Items[i].Name == tag) + return (int)i; + return -1; +} + +static const char *FillProp(const char *s, CPropVal &val) +{ + SKIP_SPACES(s) + const char c = *s; + if (c == 0) + return NULL; + + if (c == '\"') + { + s++; + val.IsNumber = false; + val.String.Empty(); + + for (;;) + { + const char c2 = *s; + if (c2 == 0) + return NULL; + s++; + if (c2 == '\"') + break; + val.String += c2; + } + } + else + { + const char *end; + val.IsNumber = true; + val.Number = ConvertStringToUInt64(s, &end); + if (s == end) + return NULL; + s = end; + } + + SKIP_SPACES(s) + return s; +} + + +const char *CConfigItem::ParseItem(const char *s, int numAllowedLevels) +{ + if (numAllowedLevels < 0) + return NULL; + + for (;;) + { + SKIP_SPACES(s) + const char *beg = s; + + for (;; s++) + { + char c = *s; + if (c == 0 || c == '}') + { + if (s != beg) + return NULL; + return s; + } + if (IsSpaceChar(c) || c == '=' || c == '{') + break; + } + + if (s == beg) + return NULL; + + AString name; + name.SetFrom(beg, (unsigned)(s - beg)); + + SKIP_SPACES(s) + + if (*s == 0 || *s == '}') + return NULL; + + if (*s == '{') + { + s++; + CConfigItem &item = Items.AddNew(); + item.Name = name; + s = item.ParseItem(s, numAllowedLevels - 1); + if (!s) + return NULL; + if (*s != '}') + return NULL; + s++; + continue; + } + + if (*s != '=') + continue; + + s++; + SKIP_SPACES(s) + if (*s == 0) + return NULL; + CConfigProp &prop = Props.AddNew(); + + prop.Name = name; + + if (*s == '[') + { + s++; + prop.IsVector = true; + + for (;;) + { + SKIP_SPACES(s) + char c = *s; + if (c == 0) + return NULL; + if (c == ']') + { + s++; + break; + } + + CPropVal val; + + s = FillProp(s, val); + if (!s) + return NULL; + prop.Vector.Add(val); + SKIP_SPACES(s) + + if (*s == ',') + { + s++; + continue; + } + if (*s != ']') + return NULL; + s++; + break; + } + } + else + { + prop.IsVector = false; + s = FillProp(s, prop.Val); + if (!s) + return NULL; + } + } +} + + +bool CConfig::Parse(const char *s) +{ + s = Root.ParseItem(s, 10); + if (!s) + return false; + SKIP_SPACES(s) + return *s == 0; +} + + +/* +static const CUInt32PCharPair g_PartitionFlags[] = +{ + { 0, "Sys" }, + { 1, "Ignore" }, + { 2, "Legacy" }, + { 60, "Win-Read-only" }, + { 62, "Win-Hidden" }, + { 63, "Win-Not-Automount" } +}; +*/ + +/* +static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } + +static void PrintHex(unsigned v, char *s) +{ + s[0] = GetHex((v >> 4) & 0xF); + s[1] = GetHex(v & 0xF); +} + +static void ConvertUInt16ToHex4Digits(UInt32 val, char *s) throw() +{ + PrintHex(val >> 8, s); + PrintHex(val & 0xFF, s + 2); +} + +static void GuidToString(const Byte *g, char *s) +{ + ConvertUInt32ToHex8Digits(Get32(g ), s); s += 8; *s++ = '-'; + ConvertUInt16ToHex4Digits(Get16(g + 4), s); s += 4; *s++ = '-'; + ConvertUInt16ToHex4Digits(Get16(g + 6), s); s += 4; *s++ = '-'; + for (unsigned i = 0; i < 8; i++) + { + if (i == 2) + *s++ = '-'; + PrintHex(g[8 + i], s); + s += 2; + } + *s = 0; +} + +*/ + +struct CPhyVol +{ + AString Name; + + // AString id; + // AString device; // "/dev/sda2" + // AString status; // ["ALLOCATABLE"] + // AString flags; // [] + // UInt64 dev_size; // in sectors + UInt64 pe_start; // in sectors + UInt64 pe_count; // in extents + + bool Parse(const CConfigItem &ci) + { + Name = ci.Name; + // ci.GetPropVal_String("id", id); + // ci.GetPropVal_String("device", device); + bool res = true; + // if (!ci.GetPropVal_Number("dev_size", dev_size)) res = false; + if (!ci.GetPropVal_Number("pe_start", pe_start)) res = false; + if (!ci.GetPropVal_Number("pe_count", pe_count)) res = false; + return res; + } +}; + +struct CStripe +{ + AString Name; // "pv0"; + UInt64 ExtentOffset; // ???? +}; + +struct CSegment +{ + UInt64 start_extent; + UInt64 extent_count; + AString type; + CObjectVector stripes; + + bool IsPosSizeOk() const + { + return + (start_extent < ((UInt64)1 << 63)) && + (extent_count < ((UInt64)1 << 63)); + } + + UInt64 GetEndExtent() const { return start_extent + extent_count; } + + bool Parse(const CConfigItem &si) + { + UInt64 stripe_count; + + if (!si.GetPropVal_Number("start_extent", start_extent)) return false; + if (!si.GetPropVal_Number("extent_count", extent_count)) return false; + if (!si.GetPropVal_Number("stripe_count", stripe_count)) return false; + if (!si.GetPropVal_String("type", type)) return false; + + //if (stripe_count != 1) return false; + + const int spi = si.FindProp("stripes"); + if (spi < 0) + return false; + + const CConfigProp &prop = si.Props[spi]; + if (!prop.IsVector) + return false; + + if (stripe_count > (1 << 20)) + return false; + + const unsigned numStripes = (unsigned)stripe_count; + if (prop.Vector.Size() != numStripes * 2) + return false; + + for (unsigned i = 0; i < numStripes; i++) + { + const CPropVal &v0 = prop.Vector[i * 2]; + const CPropVal &v1 = prop.Vector[i * 2 + 1]; + if (v0.IsNumber || !v1.IsNumber) + return false; + CStripe stripe; + stripe.Name = v0.String; + stripe.ExtentOffset = v1.Number; + stripes.Add(stripe); + } + + return true; + } +}; + + +struct CLogVol +{ + bool IsSupported; + + AString Name; + + AString id; + AString status; // ["READ", "WRITE", "VISIBLE"] + AString flags; // [] + + // UInt64 Pos; + // UInt64 Size; + + // UInt64 GetSize() const { return Size; } + // UInt64 GetPos() const { return Pos; } + + CObjectVector Segments; + + CLogVol(): /* Pos(0), Size(0), */ IsSupported(false) {} + + bool Parse(const CConfigItem &ci) + { + Name = ci.Name; + + UInt64 segment_count; + if (!ci.GetPropVal_Number("segment_count", segment_count)) + return false; + + if (ci.Items.Size() != segment_count) + return false; + + FOR_VECTOR (segIndex, ci.Items) + { + const CConfigItem &si = ci.Items[segIndex]; + { + AString t ("segment"); + t.Add_UInt32(segIndex + 1); + if (si.Name != t) + return false; + } + + CSegment segment; + + if (!segment.Parse(si)) + return false; + + // item.Size += (segment.extent_count * _extentSize) << 9; + + Segments.Add(segment); + } + + IsSupported = true; + return true; + } + + bool GetNumExtents(UInt64 &numExtents) const + { + numExtents = 0; + if (Segments.IsEmpty()) + return true; + unsigned i; + for (i = 1; i < Segments.Size(); i++) + if (!Segments[i].IsPosSizeOk()) + return false; + for (i = 1; i < Segments.Size(); i++) + if (Segments[i - 1].GetEndExtent() != Segments[i].start_extent) + return false; + numExtents = Segments.Back().GetEndExtent(); + return true; + } +}; + + +struct CItem +{ + int LogVol; + int PhyVol; + UInt64 Pos; + UInt64 Size; + AString Name; + bool IsSupported; + + CItem(): LogVol(-1), PhyVol(-1), Pos(0), Size(0), IsSupported(false) {} +}; + + +struct CVolGroup +{ + CObjectVector _logVols; + CObjectVector _phyVols; + AString _id; + int _extentSizeBits; + + /* + UInt64 secno; // 3 + AString status; // ["RESIZEABLE", "READ", "WRITE"] + AString flags; // [] + UInt64 max_lv; // 0 + UInt64 max_pv; // 0 + UInt64 metadata_copies; // 0 + */ + + void Clear() + { + _logVols.Clear(); + _phyVols.Clear(); + _id.Empty(); + _extentSizeBits = -1; + } +}; + + +Z7_class_CHandler_final: public CHandlerCont, public CVolGroup +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + CObjectVector _items; + + UInt64 _cTime; + + bool _isArc; + + UInt64 _phySize; + CByteBuffer _buffer; + + UInt64 _cfgPos; + UInt64 _cfgSize; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + if (index >= _items.Size()) + { + pos = _cfgPos; + size = _cfgSize; + return NExtract::NOperationResult::kOK; + } + const CItem &item = _items[index]; + if (!item.IsSupported) + return NExtract::NOperationResult::kUnsupportedMethod; + pos = item.Pos; + size = item.Size; + return NExtract::NOperationResult::kOK; + } +}; + +static const UInt32 LVM_CRC_INIT_VAL = 0xf597a6cf; + +static UInt32 Z7_FASTCALL LvmCrcCalc(const void *data, size_t size) +{ + return CrcUpdate(LVM_CRC_INIT_VAL, data, size); +} + +struct CRawLocn +{ + UInt64 Offset; /* Offset in bytes to start sector */ + UInt64 Size; /* Bytes */ + UInt32 Checksum; + UInt32 Flags; + + bool IsEmpty() const { return Offset == 0 && Size == 0; } + + void Parse(const Byte *p) + { + LE_64(0x00, Offset); + LE_64(0x08, Size); + LE_32(0x10, Checksum); + LE_32(0x14, Flags); + } +}; + +// #define MDA_HEADER_SIZE 512 + +struct mda_header +{ + UInt64 Start; /* Absolute start byte of mda_header */ + UInt64 Size; /* Size of metadata area */ + + CRecordVector raw_locns; + + bool Parse(const Byte *p, size_t size) + { + if (memcmp(p + 4, FMTT_MAGIC, 16) != 0) + return false; + UInt32 version; + LE_32(0x14, version); + if (version != 1) + return false; + LE_64(0x18, Start); + LE_64(0x20, Size); + + unsigned pos = 0x28; + + for (;;) + { + if (pos + 0x18 > size) + return false; + CRawLocn locn; + locn.Parse(p + pos); + if (locn.IsEmpty()) + break; + pos += 0x18; + raw_locns.Add(locn); + } + + return true; + } +}; + + +static int inline GetLog(UInt64 num) +{ + for (unsigned i = 0; i < 64; i++) + if (((UInt64)1 << i) == num) + return (int)i; + return -1; +} + +#define ID_LEN 32 + +HRESULT CHandler::Open2(IInStream *stream) +{ + _buffer.Alloc(kSectorSize * 2); + RINOK(ReadStream_FALSE(stream, _buffer, kSectorSize * 2)) + + const Byte *buf = _buffer; + + buf += kSectorSize; + + // label_header + + if (memcmp(buf, k_Signature, k_SignatureSize) != 0) + return S_FALSE; + const UInt64 sectorNumber = Get64(buf + 8); + if (sectorNumber != 1) + return S_FALSE; + if (Get32(buf + 16) != LvmCrcCalc(buf + 20, kSectorSize - 20)) + return S_FALSE; + + const UInt32 offsetToCont = Get32(buf + 20); + if (memcmp(buf + 24, k_Signature2, k_Signature2Size) != 0) + return S_FALSE; + + if (offsetToCont != 32) + return S_FALSE; + + // pv_header + + size_t pos = offsetToCont; + const Byte *p = buf; + + /* + { + Byte id[ID_LEN]; + memcpy(id, p + pos, ID_LEN); + } + */ + + pos += ID_LEN; + const UInt64 device_size_xl = Get64(p + pos); + pos += 8; + + _phySize = device_size_xl; + _isArc = true; + + for (;;) + { + if (pos > kSectorSize - 16) + return S_FALSE; + // disk_locn (data areas) + UInt64 offset = Get64(p + pos); + UInt64 size = Get64(p + pos + 8); + pos += 16; + if (offset == 0 && size == 0) + break; + } + + CConfig cfg; + // bool isFinded = false; + + // for (;;) + { + if (pos > kSectorSize - 16) + return S_FALSE; + // disk_locn (metadata area headers) + UInt64 offset = Get64(p + pos); + UInt64 size = Get64(p + pos + 8); + pos += 16; + if (offset == 0 && size == 0) + { + // break; + return S_FALSE; + } + + CByteBuffer meta; + const size_t sizeT = (size_t)size; + if (sizeT != size) + return S_FALSE; + meta.Alloc(sizeT); + RINOK(InStream_SeekSet(stream, offset)) + RINOK(ReadStream_FALSE(stream, meta, sizeT)) + if (Get32(meta) != LvmCrcCalc(meta + 4, kSectorSize - 4)) + return S_FALSE; + mda_header mh; + if (!mh.Parse(meta, kSectorSize)) + return S_FALSE; + + if (mh.raw_locns.Size() != 1) + return S_FALSE; + unsigned g = 0; + // for (unsigned g = 0; g < mh.raw_locns.Size(); g++) + { + const CRawLocn &locn = mh.raw_locns[g]; + + CByteBuffer vgBuf; + if (locn.Size > ((UInt32)1 << 24)) + return S_FALSE; + + const size_t vgSize = (size_t)locn.Size; + if (vgSize == 0) + return S_FALSE; + + vgBuf.Alloc(vgSize); + + _cfgPos = offset + locn.Offset; + _cfgSize = vgSize; + RINOK(InStream_SeekSet(stream, _cfgPos)) + RINOK(ReadStream_FALSE(stream, vgBuf, vgSize)) + if (locn.Checksum != LvmCrcCalc(vgBuf, vgSize)) + return S_FALSE; + + { + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)vgBuf, (unsigned)vgSize); + _cfgSize = s.Len(); + if (!cfg.Parse(s)) + return S_FALSE; + // isFinded = true; + // break; + } + } + + // if (isFinded) break; + } + + // if (!isFinded) return S_FALSE; + + if (cfg.Root.Items.Size() != 1) + return S_FALSE; + const CConfigItem &volGroup = cfg.Root.Items[0]; + if (volGroup.Name != "VolGroup00") + return S_FALSE; + + volGroup.GetPropVal_String("id", _id); + + if (!cfg.Root.GetPropVal_Number("creation_time", _cTime)) + _cTime = 0; + + UInt64 extentSize; + if (!volGroup.GetPropVal_Number("extent_size", extentSize)) + return S_FALSE; + + _extentSizeBits = GetLog(extentSize); + if (_extentSizeBits < 0 || _extentSizeBits > (62 - 9)) + return S_FALSE; + + + { + int pvsIndex = volGroup.FindSubItem("physical_volumes"); + if (pvsIndex < 0) + return S_FALSE; + + const CConfigItem &phyVols = volGroup.Items[pvsIndex]; + + FOR_VECTOR (i, phyVols.Items) + { + const CConfigItem &ci = phyVols.Items[i]; + CPhyVol pv; + if (!pv.Parse(ci)) + return S_FALSE; + _phyVols.Add(pv); + } + } + + { + int lvIndex = volGroup.FindSubItem("logical_volumes"); + if (lvIndex < 0) + return S_FALSE; + + const CConfigItem &logVolumes = volGroup.Items[lvIndex]; + + FOR_VECTOR (i, logVolumes.Items) + { + const CConfigItem &ci = logVolumes.Items[i]; + CLogVol &lv = _logVols.AddNew(); + lv.Parse(ci) ; // check error + } + } + + { + FOR_VECTOR (i, _logVols) + { + CLogVol &lv = _logVols[i]; + + CItem item; + + item.LogVol = (int)i; + item.Pos = 0; + item.Size = 0; + item.Name = lv.Name; + + if (lv.IsSupported) + { + UInt64 numExtents; + lv.IsSupported = lv.GetNumExtents(numExtents); + + if (lv.IsSupported) + { + lv.IsSupported = false; + item.Size = numExtents << (_extentSizeBits + 9); + + if (lv.Segments.Size() == 1) + { + const CSegment &segment = lv.Segments[0]; + if (segment.stripes.Size() == 1) + { + const CStripe &stripe = segment.stripes[0]; + FOR_VECTOR (pvIndex, _phyVols) + { + const CPhyVol &pv = _phyVols[pvIndex]; + if (pv.Name == stripe.Name) + { + item.Pos = (pv.pe_start + (stripe.ExtentOffset << _extentSizeBits)) << 9; + lv.IsSupported = true; + item.IsSupported = true; + break; + } + } + } + } + } + } + + _items.Add(item); + } + } + + { + FOR_VECTOR (i, _phyVols) + { + const CPhyVol &pv = _phyVols[i]; + + if (pv.pe_start > (UInt64)1 << (62 - 9)) + return S_FALSE; + if (pv.pe_count > (UInt64)1 << (62 - 9 - _extentSizeBits)) + return S_FALSE; + + CItem item; + + item.PhyVol = (int)i; + item.Pos = pv.pe_start << 9; + item.Size = pv.pe_count << (_extentSizeBits + 9); + item.Name = pv.Name; + item.IsSupported = true; + + _items.Add(item); + } + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(stream)) + _stream = stream; + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + CVolGroup::Clear(); + + _cfgPos = 0; + _cfgSize = 0; + _cTime = 0; + _phySize = 0; + _isArc = false; + _items.Clear(); + + _stream.Release(); + return S_OK; +} + + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidFileSystem, + kpidCharacts, + kpidOffset, + kpidId +}; + +static const Byte kArcProps[] = +{ + kpidId, + kpidCTime, + kpidClusterSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidMainSubfile: + { + /* + if (_items.Size() == 1) + prop = (UInt32)0; + */ + break; + } + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidId: + { + prop = _id; + break; + } + case kpidClusterSize: + { + if (_extentSizeBits >= 0) + prop = ((UInt64)1 << (_extentSizeBits + 9)); + break; + } + case kpidCTime: + { + if (_cTime != 0) + { + FILETIME ft; + NTime::UnixTime64_To_FileTime((Int64)_cTime, ft); + prop = ft; + } + break; + } + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + // if (_headerError) v |= kpv_ErrorFlags_HeadersError; + if (v == 0 && !_stream) + v |= kpv_ErrorFlags_UnsupportedMethod; + if (v != 0) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size() + (_cfgSize == 0 ? 0 : 1); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CItem &item = _items[index]; + + // const CLogVol &item = _items[index]; + + if (index >= _items.Size()) + { + switch (propID) + { + case kpidPath: + { + prop = "meta.txt"; + break; + } + + case kpidSize: + case kpidPackSize: prop = _cfgSize; break; + } + } + else + { + switch (propID) + { + case kpidPath: + { + AString s = item.Name; + s += ".img"; + prop = s; + break; + } + + case kpidSize: + case kpidPackSize: prop = item.Size; break; + case kpidOffset: prop = item.Pos; break; + + case kpidId: + { + // prop = item.id; + break; + } + + // case kpidCharacts: FLAGS64_TO_PROP(g_PartitionFlags, item.Flags, prop); break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "LVM", "lvm", NULL, 0xBF, + k_Signature, + kSectorSize, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/LzhHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzhHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/LzhHandler.cpp 2015-06-19 13:16:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzhHandler.cpp 2024-06-07 04:00:00.000000000 +0000 @@ -1,788 +1,719 @@ -// LzhHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../ICoder.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" -#include "../Compress/LzhDecoder.h" - -#include "IArchive.h" - -#include "Common/ItemNameUtils.h" - -using namespace NWindows; -using namespace NTime; - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NLzh{ - -const int kMethodIdSize = 5; - -const Byte kExtIdFileName = 0x01; -const Byte kExtIdDirName = 0x02; -const Byte kExtIdUnixTime = 0x54; - -struct CExtension -{ - Byte Type; - CByteBuffer Data; - - AString GetString() const - { - AString s; - for (size_t i = 0; i < Data.Size(); i++) - { - char c = (char)Data[i]; - if (c == 0) - break; - s += c; - } - return s; - } -}; - -const UInt32 kBasicPartSize = 22; - -API_FUNC_static_IsArc IsArc_Lzh(const Byte *p, size_t size) -{ - if (size < 2 + kBasicPartSize) - return k_IsArc_Res_NEED_MORE; - if (p[2] != '-' || p[3] != 'l' || p[4] != 'h' || p[6] != '-') - return k_IsArc_Res_NO; - Byte n = p[5]; - if (n != 'd') - if (n < '0' || n > '7') - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -struct CItem -{ - AString Name; - Byte Method[kMethodIdSize]; - Byte Attributes; - Byte Level; - Byte OsId; - UInt32 PackSize; - UInt32 Size; - UInt32 ModifiedTime; - UInt16 CRC; - CObjectVector Extensions; - - bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } - bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } - bool IsDir() const {return (IsLhMethod() && Method[3] == 'd'); } - - bool IsCopyMethod() const - { - return (IsLhMethod() && Method[3] == '0') || - (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); - } - - bool IsLh1GroupMethod() const - { - if (!IsLhMethod()) - return false; - switch (Method[3]) - { - case '1': - return true; - } - return false; - } - - bool IsLh4GroupMethod() const - { - if (!IsLhMethod()) - return false; - switch (Method[3]) - { - case '4': - case '5': - case '6': - case '7': - return true; - } - return false; - } - - int GetNumDictBits() const - { - if (!IsLhMethod()) - return 0; - switch (Method[3]) - { - case '1': return 12; - case '2': return 13; - case '3': return 13; - case '4': return 12; - case '5': return 13; - case '6': return 15; - case '7': return 16; - } - return 0; - } - - int FindExt(Byte type) const - { - FOR_VECTOR (i, Extensions) - if (Extensions[i].Type == type) - return i; - return -1; - } - bool GetUnixTime(UInt32 &value) const - { - value = 0; - int index = FindExt(kExtIdUnixTime); - if (index < 0) - { - if (Level == 2) - { - value = ModifiedTime; - return true; - } - return false; - } - const Byte *data = (const Byte *)(Extensions[index].Data); - value = GetUi32(data); - return true; - } - - AString GetDirName() const - { - int index = FindExt(kExtIdDirName); - if (index < 0) - return AString(); - return Extensions[index].GetString(); - } - - AString GetFileName() const - { - int index = FindExt(kExtIdFileName); - if (index < 0) - return Name; - return Extensions[index].GetString(); - } - - AString GetName() const - { - AString dirName = GetDirName(); - const char kDirSeparator = CHAR_PATH_SEPARATOR; // '\\'; - // check kDirSeparator in Linux - dirName.Replace((char)(unsigned char)0xFF, kDirSeparator); - if (!dirName.IsEmpty() && dirName.Back() != kDirSeparator) - dirName += kDirSeparator; - return dirName + GetFileName(); - } -}; - -static const Byte *ReadUInt16(const Byte *p, UInt16 &v) -{ - v = Get16(p); - return p + 2; -} - -static const Byte *ReadString(const Byte *p, size_t size, AString &s) -{ - s.Empty(); - for (size_t i = 0; i < size; i++) - { - char c = p[i]; - if (c == 0) - break; - s += c; - } - return p + size; -} - -static Byte CalcSum(const Byte *data, size_t size) -{ - Byte sum = 0; - for (size_t i = 0; i < size; i++) - sum = (Byte)(sum + data[i]); - return sum; -} - -static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &item) -{ - filled = false; - - size_t processedSize = 2; - Byte startHeader[2]; - RINOK(ReadStream(stream, startHeader, &processedSize)) - if (processedSize == 0) - return S_OK; - if (processedSize == 1) - return (startHeader[0] == 0) ? S_OK: S_FALSE; - if (startHeader[0] == 0 && startHeader[1] == 0) - return S_OK; - - Byte header[256]; - processedSize = kBasicPartSize; - RINOK(ReadStream(stream, header, &processedSize)); - if (processedSize != kBasicPartSize) - return (startHeader[0] == 0) ? S_OK: S_FALSE; - - const Byte *p = header; - memcpy(item.Method, p, kMethodIdSize); - if (!item.IsValidMethod()) - return S_OK; - p += kMethodIdSize; - item.PackSize = Get32(p); - item.Size = Get32(p + 4); - item.ModifiedTime = Get32(p + 8); - item.Attributes = p[12]; - item.Level = p[13]; - p += 14; - if (item.Level > 2) - return S_FALSE; - UInt32 headerSize; - if (item.Level < 2) - { - headerSize = startHeader[0]; - if (headerSize < kBasicPartSize) - return S_FALSE; - RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize)); - if (startHeader[1] != CalcSum(header, headerSize)) - return S_FALSE; - size_t nameLength = *p++; - if ((p - header) + nameLength + 2 > headerSize) - return S_FALSE; - p = ReadString(p, nameLength, item.Name); - } - else - headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8); - p = ReadUInt16(p, item.CRC); - if (item.Level != 0) - { - if (item.Level == 2) - { - RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2)); - } - if ((size_t)(p - header) + 3 > headerSize) - return S_FALSE; - item.OsId = *p++; - UInt16 nextSize; - p = ReadUInt16(p, nextSize); - while (nextSize != 0) - { - if (nextSize < 3) - return S_FALSE; - if (item.Level == 1) - { - if (item.PackSize < nextSize) - return S_FALSE; - item.PackSize -= nextSize; - } - if (item.Extensions.Size() >= (1 << 8)) - return S_FALSE; - CExtension ext; - RINOK(ReadStream_FALSE(stream, &ext.Type, 1)) - nextSize -= 3; - ext.Data.Alloc(nextSize); - RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize)) - item.Extensions.Add(ext); - Byte hdr2[2]; - RINOK(ReadStream_FALSE(stream, hdr2, 2)); - ReadUInt16(hdr2, nextSize); - } - } - filled = true; - return S_OK; -} - -struct COsPair -{ - Byte Id; - const char *Name; -}; - -static const COsPair g_OsPairs[] = -{ - { 0, "MS-DOS" }, - { 'M', "MS-DOS" }, - { '2', "OS/2" }, - { '9', "OS9" }, - { 'K', "OS/68K" }, - { '3', "OS/386" }, - { 'H', "HUMAN" }, - { 'U', "UNIX" }, - { 'C', "CP/M" }, - { 'F', "FLEX" }, - { 'm', "Mac" }, - { 'R', "Runser" }, - { 'T', "TownsOS" }, - { 'X', "XOSK" }, - { 'w', "Windows 95" }, - { 'W', "Windows NT" }, - { 'J', "Java VM" } -}; - -static const char *kUnknownOS = "Unknown"; - -static const char *GetOS(Byte osId) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_OsPairs); i++) - if (g_OsPairs[i].Id == osId) - return g_OsPairs[i].Name; - return kUnknownOS; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - // kpidAttrib, - kpidCRC, - kpidMethod, - kpidHostOS -}; - -class CCRC -{ - UInt16 _value; -public: - static UInt16 Table[256]; - static void InitTable(); - - CCRC(): _value(0) {} - void Init() { _value = 0; } - void Update(const void *data, size_t size); - UInt16 GetDigest() const { return _value; } -}; - -static const UInt16 kCRCPoly = 0xA001; - -UInt16 CCRC::Table[256]; - -void CCRC::InitTable() -{ - for (UInt32 i = 0; i < 256; i++) - { - UInt32 r = i; - for (int j = 0; j < 8; j++) - if (r & 1) - r = (r >> 1) ^ kCRCPoly; - else - r >>= 1; - CCRC::Table[i] = (UInt16)r; - } -} - -class CCRCTableInit -{ -public: - CCRCTableInit() { CCRC::InitTable(); } -} g_CRCTableInit; - -void CCRC::Update(const void *data, size_t size) -{ - UInt16 v = _value; - const Byte *p = (const Byte *)data; - for (; size > 0; size--, p++) - v = (UInt16)(Table[((Byte)(v)) ^ *p] ^ (v >> 8)); - _value = v; -} - - -class COutStreamWithCRC: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -private: - CCRC _crc; - CMyComPtr _stream; -public: - void Init(ISequentialOutStream *stream) - { - _stream = stream; - _crc.Init(); - } - void ReleaseStream() { _stream.Release(); } - UInt32 GetCRC() const { return _crc.GetDigest(); } - void InitCRC() { _crc.Init(); } -}; - -STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result; - if (!_stream) - { - realProcessedSize = size; - result = S_OK; - } - else - result = _stream->Write(data, size, &realProcessedSize); - _crc.Update(data, realProcessedSize); - if (processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - -struct CItemEx: public CItem -{ - UInt64 DataPosition; -}; - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CObjectVector _items; - CMyComPtr _stream; - UInt64 _phySize; - UInt32 _errorFlags; - bool _isArc; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) - CHandler(); -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -CHandler::CHandler() {} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _phySize; break; - - case kpidErrorFlags: - UInt32 v = _errorFlags; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; - prop = v; - break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CItemEx &item = _items[index]; - switch (propID) - { - case kpidPath: - { - UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP)); - if (!s.IsEmpty()) - { - if (s.Back() == WCHAR_PATH_SEPARATOR) - s.DeleteBack(); - prop = s; - } - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidPackSize: prop = item.PackSize; break; - case kpidCRC: prop = (UInt32)item.CRC; break; - case kpidHostOS: prop = GetOS(item.OsId); break; - case kpidMTime: - { - FILETIME utc; - UInt32 unixTime; - if (item.GetUnixTime(unixTime)) - NTime::UnixTimeToFileTime(unixTime, utc); - 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; - break; - } - // case kpidAttrib: prop = (UInt32)item.Attributes; break; - case kpidMethod: - { - char method2[kMethodIdSize + 1]; - method2[kMethodIdSize] = 0; - memcpy(method2, item.Method, kMethodIdSize); - prop = method2; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - try - { - _items.Clear(); - - UInt64 endPos = 0; - bool needSetTotal = true; - - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - - for (;;) - { - CItemEx item; - bool filled; - HRESULT result = GetNextItem(stream, filled, item); - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition)); - if (result == S_FALSE) - { - _errorFlags = kpv_ErrorFlags_HeadersError; - break; - } - - if (result != S_OK) - return S_FALSE; - _phySize = item.DataPosition; - if (!filled) - break; - _items.Add(item); - - _isArc = true; - - UInt64 newPostion; - RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion)); - if (newPostion > endPos) - { - _phySize = endPos; - _errorFlags = kpv_ErrorFlags_UnexpectedEnd; - break; - } - _phySize = newPostion; - if (callback) - { - if (needSetTotal) - { - RINOK(callback->SetTotal(NULL, &endPos)); - needSetTotal = false; - } - if (_items.Size() % 100 == 0) - { - UInt64 numFiles = _items.Size(); - UInt64 numBytes = item.DataPosition; - RINOK(callback->SetCompleted(&numFiles, &numBytes)); - } - } - } - if (_items.IsEmpty()) - return S_FALSE; - - _stream = stream; - } - catch(...) - { - return S_FALSE; - } - COM_TRY_END - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _phySize = 0; - _errorFlags = 0; - _items.Clear(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool testMode = (testModeSpec != 0); - UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const CItemEx &item = _items[allFilesMode ? i : indices[i]]; - totalUnPacked += item.Size; - totalPacked += item.PackSize; - } - RINOK(extractCallback->SetTotal(totalUnPacked)); - - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; - - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; - CMyComPtr lzhDecoder; - // CMyComPtr lzh1Decoder; - // CMyComPtr arj2Decoder; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - currentItemUnPacked = 0; - currentItemPacked = 0; - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - RINOK(lps->SetCur()); - - CMyComPtr realOutStream; - Int32 askMode; - askMode = testMode ? NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItemEx &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (item.IsDir()) - { - // if (!testMode) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - continue; - } - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - currentItemUnPacked = item.Size; - currentItemPacked = item.PackSize; - - { - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(realOutStream); - realOutStream.Release(); - - UInt64 pos; - _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos); - - streamSpec->Init(item.PackSize); - - HRESULT result = S_OK; - Int32 opRes = NExtract::NOperationResult::kOK; - - if (item.IsCopyMethod()) - { - result = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize) - result = S_FALSE; - } - else if (item.IsLh4GroupMethod()) - { - if (!lzhDecoder) - { - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - } - lzhDecoderSpec->FinishMode = true; - lzhDecoderSpec->SetDictSize(1 << item.GetNumDictBits()); - result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); - if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize) - result = S_FALSE; - } - /* - else if (item.IsLh1GroupMethod()) - { - if (!lzh1Decoder) - { - lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; - lzh1Decoder = lzh1DecoderSpec; - } - lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); - result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress); - } - */ - else - opRes = NExtract::NOperationResult::kUnsupportedMethod; - - if (opRes == NExtract::NOperationResult::kOK) - { - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else - { - RINOK(result); - if (outStreamSpec->GetCRC() != item.CRC) - opRes = NExtract::NOperationResult::kCRCError; - } - } - outStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - } - return S_OK; - COM_TRY_END -} - -static const Byte k_Signature[] = { '-', 'l', 'h' }; - -REGISTER_ARC_I( - "Lzh", "lzh lha", 0, 6, - k_Signature, - 2, - 0, - IsArc_Lzh) - -}} +// LzhHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/AutoPtr.h" +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../ICoder.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/LzhDecoder.h" + +#include "IArchive.h" + +#include "Common/ItemNameUtils.h" + +using namespace NWindows; +using namespace NTime; + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + + +// CRC-16 (-IBM, -ANSI). The poly is 0x8005 (x^16 + x^15 + x^2 + 1) + +static const UInt16 kCrc16Poly = 0xA001; + +MY_ALIGN(64) +static UInt16 g_LzhCrc16Table[256]; + +#define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size); +UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size) +{ + const Byte *p = (const Byte *)data; + const Byte *pEnd = p + size; + for (; p != pEnd; p++) + crc = CRC16_UPDATE_BYTE(crc, *p); + return crc; +} + +static struct CLzhCrc16TableInit +{ + CLzhCrc16TableInit() + { + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i; + for (unsigned j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrc16Poly & ((UInt32)0 - (r & 1))); + g_LzhCrc16Table[i] = (UInt16)r; + } + } +} g_LzhCrc16TableInit; + + +namespace NArchive { +namespace NLzh{ + +const unsigned kMethodIdSize = 5; + +const Byte kExtIdFileName = 0x01; +const Byte kExtIdDirName = 0x02; +const Byte kExtIdUnixTime = 0x54; + +struct CExtension +{ + Byte Type; + CByteBuffer Data; + + AString GetString() const + { + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)Data, (unsigned)Data.Size()); + return s; + } +}; + +const UInt32 kBasicPartSize = 22; + +API_FUNC_static_IsArc IsArc_Lzh(const Byte *p, size_t size) +{ + if (size < 2 + kBasicPartSize) + return k_IsArc_Res_NEED_MORE; + if (p[2] != '-' || p[3] != 'l' || p[4] != 'h' || p[6] != '-') + return k_IsArc_Res_NO; + Byte n = p[5]; + if (n != 'd') + if (n < '0' || n > '7') + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +struct CItem +{ + AString Name; + Byte Method[kMethodIdSize]; + Byte Attributes; + Byte Level; + Byte OsId; + UInt32 PackSize; + UInt32 Size; + UInt32 ModifiedTime; + UInt16 CRC; + CObjectVector Extensions; + + bool IsValidMethod() const { return (Method[0] == '-' && Method[1] == 'l' && Method[4] == '-'); } + bool IsLhMethod() const {return (IsValidMethod() && Method[2] == 'h'); } + bool IsDir() const {return (IsLhMethod() && Method[3] == 'd'); } + + bool IsCopyMethod() const + { + return (IsLhMethod() && Method[3] == '0') || + (IsValidMethod() && Method[2] == 'z' && Method[3] == '4'); + } + + bool IsLh1GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch (Method[3]) + { + case '1': + return true; + } + return false; + } + + bool IsLh4GroupMethod() const + { + if (!IsLhMethod()) + return false; + switch (Method[3]) + { + case '4': + case '5': + case '6': + case '7': + return true; + } + return false; + } + + unsigned GetNumDictBits() const + { + if (!IsLhMethod()) + return 0; + switch (Method[3]) + { + case '1': return 12; + case '2': return 13; + case '3': return 13; + case '4': return 12; + case '5': return 13; + case '6': return 15; + case '7': return 16; + } + return 0; + } + + int FindExt(Byte type) const + { + FOR_VECTOR (i, Extensions) + if (Extensions[i].Type == type) + return (int)i; + return -1; + } + + bool GetUnixTime(UInt32 &value) const + { + value = 0; + int index = FindExt(kExtIdUnixTime); + if (index < 0 + || Extensions[index].Data.Size() < 4) + { + if (Level == 2) + { + value = ModifiedTime; + return true; + } + return false; + } + const Byte *data = (const Byte *)(Extensions[index].Data); + value = GetUi32(data); + return true; + } + + AString GetDirName() const + { + int index = FindExt(kExtIdDirName); + if (index < 0) + return AString(); + return Extensions[index].GetString(); + } + + AString GetFileName() const + { + int index = FindExt(kExtIdFileName); + if (index < 0) + return Name; + return Extensions[index].GetString(); + } + + AString GetName() const + { + AString s (GetDirName()); + const char kDirSeparator = '\\'; + // check kDirSeparator in Linux + s.Replace((char)(Byte)0xFF, kDirSeparator); + if (!s.IsEmpty() && s.Back() != kDirSeparator) + s += kDirSeparator; + s += GetFileName(); + return s; + } +}; + +static const Byte *ReadUInt16(const Byte *p, UInt16 &v) +{ + v = Get16(p); + return p + 2; +} + +static const Byte *ReadString(const Byte *p, size_t size, AString &s) +{ + s.Empty(); + for (size_t i = 0; i < size; i++) + { + const Byte c = p[i]; + if (c == 0) + break; + s += (char)c; + } + return p + size; +} + +static Byte CalcSum(const Byte *data, size_t size) +{ + Byte sum = 0; + for (size_t i = 0; i < size; i++) + sum = (Byte)(sum + data[i]); + return sum; +} + +static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &item) +{ + filled = false; + + size_t processedSize = 2; + Byte startHeader[2]; + RINOK(ReadStream(stream, startHeader, &processedSize)) + if (processedSize == 0) + return S_OK; + if (processedSize == 1) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + if (startHeader[0] == 0 && startHeader[1] == 0) + return S_OK; + + Byte header[256]; + processedSize = kBasicPartSize; + RINOK(ReadStream(stream, header, &processedSize)) + if (processedSize != kBasicPartSize) + return (startHeader[0] == 0) ? S_OK: S_FALSE; + + const Byte *p = header; + memcpy(item.Method, p, kMethodIdSize); + if (!item.IsValidMethod()) + return S_OK; + p += kMethodIdSize; + item.PackSize = Get32(p); + item.Size = Get32(p + 4); + item.ModifiedTime = Get32(p + 8); + item.Attributes = p[12]; + item.Level = p[13]; + p += 14; + if (item.Level > 2) + return S_FALSE; + UInt32 headerSize; + if (item.Level < 2) + { + headerSize = startHeader[0]; + if (headerSize < kBasicPartSize) + return S_FALSE; + RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize)) + if (startHeader[1] != CalcSum(header, headerSize)) + return S_FALSE; + const size_t nameLength = *p++; + if ((size_t)(p - header) + nameLength + 2 > headerSize) + return S_FALSE; + p = ReadString(p, nameLength, item.Name); + } + else + headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8); + p = ReadUInt16(p, item.CRC); + if (item.Level != 0) + { + if (item.Level == 2) + { + RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2)) + } + if ((size_t)(p - header) + 3 > headerSize) + return S_FALSE; + item.OsId = *p++; + UInt16 nextSize; + p = ReadUInt16(p, nextSize); + while (nextSize != 0) + { + if (nextSize < 3) + return S_FALSE; + if (item.Level == 1) + { + if (item.PackSize < nextSize) + return S_FALSE; + item.PackSize -= nextSize; + } + if (item.Extensions.Size() >= (1 << 8)) + return S_FALSE; + CExtension ext; + RINOK(ReadStream_FALSE(stream, &ext.Type, 1)) + nextSize = (UInt16)(nextSize - 3); + ext.Data.Alloc(nextSize); + RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize)) + item.Extensions.Add(ext); + Byte hdr2[2]; + RINOK(ReadStream_FALSE(stream, hdr2, 2)) + ReadUInt16(hdr2, nextSize); + } + } + filled = true; + return S_OK; +} + + +static const CUInt32PCharPair g_OsPairs[] = +{ + { 0, "MS-DOS" }, + { 'M', "MS-DOS" }, + { '2', "OS/2" }, + { '9', "OS9" }, + { 'K', "OS/68K" }, + { '3', "OS/386" }, + { 'H', "HUMAN" }, + { 'U', "UNIX" }, + { 'C', "CP/M" }, + { 'F', "FLEX" }, + { 'm', "Mac" }, + { 'R', "Runser" }, + { 'T', "TownsOS" }, + { 'X', "XOSK" }, + { 'w', "Windows 95" }, + { 'W', "Windows NT" }, + { 'J', "Java VM" } +}; + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + // kpidAttrib, + kpidCRC, + kpidMethod, + kpidHostOS +}; + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithCRC + , ISequentialOutStream +) + UInt32 _crc; + CMyComPtr _stream; +public: + void Init(ISequentialOutStream *stream) + { + _stream = stream; + _crc = 0; + } + void ReleaseStream() { _stream.Release(); } + UInt32 GetCRC() const { return _crc; } +}; + +Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT res = S_OK; + if (_stream) + res = _stream->Write(data, size, &size); + _crc = LzhCrc16Update(_crc, data, size); + if (processedSize) + *processedSize = size; + return res; +} + + +struct CItemEx: public CItem +{ + UInt64 DataPosition; +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CObjectVector _items; + CMyComPtr _stream; + UInt64 _phySize; + UInt32 _errorFlags; + bool _isArc; +public: + CHandler(); +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +CHandler::CHandler() {} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _phySize; break; + + case kpidErrorFlags: + UInt32 v = _errorFlags; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + prop = v; + break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CItemEx &item = _items[index]; + switch (propID) + { + case kpidPath: + { + UString s = NItemName::WinPathToOsPath(MultiByteToUnicodeString(item.GetName(), CP_OEMCP)); + if (!s.IsEmpty()) + { + if (s.Back() == WCHAR_PATH_SEPARATOR) + s.DeleteBack(); + prop = s; + } + break; + } + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: prop = (UInt64)item.Size; break; + case kpidPackSize: prop = (UInt64)item.PackSize; break; + case kpidCRC: prop = (UInt32)item.CRC; break; + case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break; + case kpidMTime: + { + UInt32 unixTime; + if (item.GetUnixTime(unixTime)) + PropVariant_SetFrom_UnixTime(prop, unixTime); + else + PropVariant_SetFrom_DosTime(prop, item.ModifiedTime); + break; + } + // case kpidAttrib: prop = (UInt32)item.Attributes; break; + case kpidMethod: + { + char method2[kMethodIdSize + 1]; + method2[kMethodIdSize] = 0; + memcpy(method2, item.Method, kMethodIdSize); + prop = method2; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + try + { + _items.Clear(); + + UInt64 endPos; + bool needSetTotal = true; + + RINOK(InStream_AtBegin_GetSize(stream, endPos)) + + for (;;) + { + CItemEx item; + bool filled; + const HRESULT res = GetNextItem(stream, filled, item); + RINOK(InStream_GetPos(stream, item.DataPosition)) + if (res == S_FALSE) + { + _errorFlags = kpv_ErrorFlags_HeadersError; + break; + } + + if (res != S_OK) + return S_FALSE; + _phySize = item.DataPosition; + if (!filled) + break; + _items.Add(item); + + _isArc = true; + + UInt64 newPostion; + RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion)) + if (newPostion > endPos) + { + _phySize = endPos; + _errorFlags = kpv_ErrorFlags_UnexpectedEnd; + break; + } + _phySize = newPostion; + if (callback) + { + if (needSetTotal) + { + RINOK(callback->SetTotal(NULL, &endPos)) + needSetTotal = false; + } + if (_items.Size() % 100 == 0) + { + const UInt64 numFiles = _items.Size(); + const UInt64 numBytes = item.DataPosition; + RINOK(callback->SetCompleted(&numFiles, &numBytes)) + } + } + } + if (_items.IsEmpty()) + return S_FALSE; + + _stream = stream; + } + catch(...) + { + return S_FALSE; + } + COM_TRY_END + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _phySize = 0; + _errorFlags = 0; + _items.Clear(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(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 totalUnPacked = 0 /* , totalPacked = 0 */; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CItemEx &item = _items[allFilesMode ? i : indices[i]]; + totalUnPacked += item.Size; + // totalPacked += item.PackSize; + } + RINOK(extractCallback->SetTotal(totalUnPacked)) + + UInt32 cur_Unpacked, cur_Packed; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyUniquePtr lzhDecoder; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + for (i = 0;; i++, + lps->OutSize += cur_Unpacked, + lps->InSize += cur_Packed) + { + cur_Unpacked = 0; + cur_Packed = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItemEx &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (item.IsDir()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + continue; + } + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + cur_Unpacked = item.Size; + cur_Packed = item.PackSize; + + CMyComPtr2_Create outStream; + outStream->Init(realOutStream); + realOutStream.Release(); + + RINOK(InStream_SeekSet(_stream, item.DataPosition)) + + inStream->Init(item.PackSize); + + HRESULT res = S_OK; + opRes = NExtract::NOperationResult::kOK; + + if (item.IsCopyMethod()) + { + res = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + if (res == S_OK && copyCoder->TotalSize != item.PackSize) + res = S_FALSE; + } + else if (item.IsLh4GroupMethod()) + { + lzhDecoder.Create_if_Empty(); + // lzhDecoder->FinishMode = true; + lzhDecoder->SetDictSize((UInt32)1 << item.GetNumDictBits()); + res = lzhDecoder->Code(inStream, outStream, cur_Unpacked, lps); + if (res == S_OK && lzhDecoder->GetInputProcessedSize() != item.PackSize) + res = S_FALSE; + } + /* + else if (item.IsLh1GroupMethod()) + { + if (!lzh1Decoder) + { + lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; + lzh1Decoder = lzh1DecoderSpec; + } + lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); + res = lzh1Decoder->Code(inStream, outStream, NULL, &cur_Unpacked, progress); + } + */ + else + opRes = NExtract::NOperationResult::kUnsupportedMethod; + + if (opRes == NExtract::NOperationResult::kOK) + { + if (res == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(res) + if (outStream->GetCRC() != item.CRC) + opRes = NExtract::NOperationResult::kCRCError; + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +static const Byte k_Signature[] = { '-', 'l', 'h' }; + +REGISTER_ARC_I( + "Lzh", "lzh lha", NULL, 6, + k_Signature, + 2, + 0, + IsArc_Lzh) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/LzmaHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzmaHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/LzmaHandler.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/LzmaHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,573 +1,608 @@ -// LzmaHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/FilterCoder.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/BcjCoder.h" -#include "../Compress/LzmaDecoder.h" - -#include "Common/DummyOutStream.h" - -using namespace NWindows; - -namespace NArchive { -namespace NLzma { - -static bool CheckDicSize(const Byte *p) -{ - UInt32 dicSize = GetUi32(p); - if (dicSize == 1) - return true; - for (unsigned i = 0; i <= 30; i++) - if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i)) - return true; - return (dicSize == 0xFFFFFFFF); -} - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize, - kpidMethod -}; - -static const Byte kArcProps[] = -{ - kpidNumStreams -}; - -struct CHeader -{ - UInt64 Size; - Byte FilterID; - Byte LzmaProps[5]; - - UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); } - bool HasSize() const { return (Size != (UInt64)(Int64)-1); } - bool Parse(const Byte *buf, bool isThereFilter); -}; - -bool CHeader::Parse(const Byte *buf, bool isThereFilter) -{ - FilterID = 0; - if (isThereFilter) - FilterID = buf[0]; - const Byte *sig = buf + (isThereFilter ? 1 : 0); - for (int i = 0; i < 5; i++) - LzmaProps[i] = sig[i]; - Size = GetUi64(sig + 5); - return - LzmaProps[0] < 5 * 5 * 9 && - FilterID < 2 && - (!HasSize() || Size < ((UInt64)1 << 56)) - && CheckDicSize(LzmaProps + 1); -} - -class CDecoder -{ - CMyComPtr _bcjStream; - CFilterCoder *_filterCoder; - CMyComPtr _lzmaDecoder; -public: - NCompress::NLzma::CDecoder *_lzmaDecoderSpec; - - ~CDecoder(); - HRESULT Create(bool filtered, ISequentialInStream *inStream); - - HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress); - - UInt64 GetInputProcessedSize() const { return _lzmaDecoderSpec->GetInputProcessedSize(); } - - void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoderSpec->ReleaseInStream(); } - - HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize) - { return _lzmaDecoderSpec->ReadFromInputStream(data, size, processedSize); } -}; - -HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream) -{ - if (!_lzmaDecoder) - { - _lzmaDecoderSpec = new NCompress::NLzma::CDecoder; - _lzmaDecoderSpec->FinishStream = true; - _lzmaDecoder = _lzmaDecoderSpec; - } - - if (filteredMode) - { - if (!_bcjStream) - { - _filterCoder = new CFilterCoder(false); - CMyComPtr coder = _filterCoder; - _filterCoder->Filter = new NCompress::NBcj::CCoder(false); - _bcjStream = _filterCoder; - } - } - - return _lzmaDecoderSpec->SetInStream(inStream); -} - -CDecoder::~CDecoder() -{ - ReleaseInStream(); -} - -HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, - ICompressProgressInfo *progress) -{ - if (header.FilterID > 1) - return E_NOTIMPL; - - { - CMyComPtr setDecoderProperties; - _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); - if (!setDecoderProperties) - return E_NOTIMPL; - RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5)); - } - - bool filteredMode = (header.FilterID == 1); - - if (filteredMode) - { - RINOK(_filterCoder->SetOutStream(outStream)); - outStream = _bcjStream; - RINOK(_filterCoder->SetOutStreamSize(NULL)); - } - - const UInt64 *Size = header.HasSize() ? &header.Size : NULL; - HRESULT res = _lzmaDecoderSpec->CodeResume(outStream, Size, progress); - - if (filteredMode) - { - { - HRESULT res2 = _filterCoder->OutStreamFinish(); - if (res == S_OK) - res = res2; - } - HRESULT res2 = _filterCoder->ReleaseOutStream(); - if (res == S_OK) - res = res2; - } - - RINOK(res); - - if (header.HasSize()) - if (_lzmaDecoderSpec->GetOutputProcessedSize() != header.Size) - return S_FALSE; - - return S_OK; -} - - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CHeader _header; - bool _lzma86; - CMyComPtr _stream; - CMyComPtr _seqStream; - - bool _isArc; - bool _needSeekToStart; - bool _dataAfterEnd; - bool _needMoreInput; - - bool _packSize_Defined; - bool _unpackSize_Defined; - bool _numStreams_Defined; - - bool _unsupported; - bool _dataError; - - UInt64 _packSize; - UInt64 _unpackSize; - UInt64 _numStreams; - -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - - CHandler(bool lzma86) { _lzma86 = lzma86; } - - unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); } - -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; - case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; - case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - if (_dataError) v |= kpv_ErrorFlags_DataError; - prop = v; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -static void DictSizeToString(UInt32 value, char *s) -{ - for (int i = 0; i <= 31; i++) - if (((UInt32)1 << i) == value) - { - ::ConvertUInt32ToString(i, s); - return; - } - char c = 'b'; - if ((value & ((1 << 20) - 1)) == 0) { value >>= 20; c = 'm'; } - else if ((value & ((1 << 10) - 1)) == 0) { value >>= 10; c = 'k'; } - ::ConvertUInt32ToString(value, s); - s += MyStringLen(s); - *s++ = c; - *s = 0; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break; - case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; - case kpidMethod: - if (_stream) - { - char sz[64]; - char *s = sz; - if (_header.FilterID != 0) - s = MyStpCpy(s, "BCJ "); - s = MyStpCpy(s, "LZMA:"); - DictSizeToString(_header.GetDicSize(), s); - prop = sz; - } - break; - } - prop.Detach(value); - return S_OK; -} - -API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size) -{ - const UInt32 kHeaderSize = 1 + 4 + 8; - if (size < kHeaderSize) - return k_IsArc_Res_NEED_MORE; - if (p[0] >= 5 * 5 * 9) - return k_IsArc_Res_NO; - UInt64 unpackSize = GetUi64(p + 1 + 4); - if (unpackSize != (UInt64)(Int64)-1) - { - if (size >= ((UInt64)1 << 56)) - return k_IsArc_Res_NO; - } - if (unpackSize != 0) - { - if (size < kHeaderSize + 2) - return k_IsArc_Res_NEED_MORE; - if (p[kHeaderSize] != 0) - return k_IsArc_Res_NO; - if (unpackSize != (UInt64)(Int64)-1) - { - if ((p[kHeaderSize + 1] & 0x80) != 0) - return k_IsArc_Res_NO; - } - } - if (!CheckDicSize(p + 1)) - // return k_IsArc_Res_YES_LOW_PROB; - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size) -{ - if (size < 1) - return k_IsArc_Res_NEED_MORE; - Byte filterID = p[0]; - if (filterID != 0 && filterID != 1) - return k_IsArc_Res_NO; - return IsArc_Lzma(p + 1, size - 1); -} -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) -{ - Close(); - - const UInt32 kBufSize = 1 + 5 + 8 + 2; - Byte buf[kBufSize]; - - RINOK(ReadStream_FALSE(inStream, buf, kBufSize)); - - if (!_header.Parse(buf, _lzma86)) - return S_FALSE; - const Byte *start = buf + GetHeaderSize(); - if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80 - return S_FALSE; - - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize)); - if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0) - return S_FALSE; - _isArc = true; - _stream = inStream; - _seqStream = inStream; - _needSeekToStart = true; - return S_OK; -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - Close(); - _isArc = true; - _seqStream = stream; - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _packSize_Defined = false; - _unpackSize_Defined = false; - _numStreams_Defined = false; - - _dataAfterEnd = false; - _needMoreInput = false; - _unsupported = false; - _dataError = false; - - _packSize = 0; - - _needSeekToStart = false; - - _stream.Release(); - _seqStream.Release(); - return S_OK; -} - -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr Callback; -public: - UInt64 Offset; - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - void Init(IArchiveOpenCallback *callback) { Callback = callback; } -}; - -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) -{ - if (Callback) - { - UInt64 files = 0; - UInt64 value = Offset + *inSize; - return Callback->SetCompleted(&files, &value); - } - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - if (_packSize_Defined) - extractCallback->SetTotal(_packSize); - - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, true); - - if (_needSeekToStart) - { - if (!_stream) - return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - else - _needSeekToStart = true; - - CDecoder decoder; - HRESULT result = decoder.Create(_lzma86, _seqStream); - RINOK(result); - - bool firstItem = true; - - UInt64 packSize = 0; - UInt64 unpackSize = 0; - UInt64 numStreams = 0; - - bool dataAfterEnd = false; - - for (;;) - { - lps->InSize = packSize; - lps->OutSize = unpackSize; - RINOK(lps->SetCur()); - - const UInt32 kBufSize = 1 + 5 + 8; - Byte buf[kBufSize]; - const UInt32 headerSize = GetHeaderSize(); - UInt32 processed; - RINOK(decoder.ReadInput(buf, headerSize, &processed)); - if (processed != headerSize) - { - if (processed != 0) - dataAfterEnd = true; - break; - } - - CHeader st; - if (!st.Parse(buf, _lzma86)) - { - dataAfterEnd = true; - break; - } - numStreams++; - firstItem = false; - - result = decoder.Code(st, outStream, progress); - - packSize = decoder.GetInputProcessedSize(); - unpackSize = outStreamSpec->GetSize(); - - if (result == E_NOTIMPL) - { - _unsupported = true; - result = S_FALSE; - break; - } - if (result == S_FALSE) - break; - RINOK(result); - } - - if (firstItem) - { - _isArc = false; - result = S_FALSE; - } - else if (result == S_OK || result == S_FALSE) - { - if (dataAfterEnd) - _dataAfterEnd = true; - else if (decoder._lzmaDecoderSpec->NeedMoreInput) - _needMoreInput = true; - - _packSize = packSize; - _unpackSize = unpackSize; - _numStreams = numStreams; - - _packSize_Defined = true; - _unpackSize_Defined = true; - _numStreams_Defined = true; - } - - Int32 opResult = NExtract::NOperationResult::kOK; - - if (!_isArc) - opResult = NExtract::NOperationResult::kIsNotArc; - else if (_needMoreInput) - opResult = NExtract::NOperationResult::kUnexpectedEnd; - else if (_unsupported) - opResult = NExtract::NOperationResult::kUnsupportedMethod; - else if (_dataAfterEnd) - opResult = NExtract::NOperationResult::kDataAfterEnd; - else if (result == S_FALSE) - opResult = NExtract::NOperationResult::kDataError; - else if (result == S_OK) - opResult = NExtract::NOperationResult::kOK; - else - return result; - - outStream.Release(); - return extractCallback->SetOperationResult(opResult); - - COM_TRY_END -} - -namespace NLzmaAr { - -// 2, { 0x5D, 0x00 }, - -REGISTER_ARC_I_CLS_NO_SIG( - CHandler(false), - "lzma", "lzma", 0, 0xA, - 0, - NArcInfoFlags::kStartOpen | - NArcInfoFlags::kKeepName, - IsArc_Lzma) - -} - -namespace NLzma86Ar { - -REGISTER_ARC_I_CLS_NO_SIG( - CHandler(true), - "lzma86", "lzma86", 0, 0xB, - 0, - NArcInfoFlags::kKeepName, - IsArc_Lzma86) - -} - -}} +// LzmaHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/FilterCoder.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/BcjCoder.h" +#include "../Compress/LzmaDecoder.h" + +#include "Common/DummyOutStream.h" + +using namespace NWindows; + +namespace NArchive { +namespace NLzma { + +static bool CheckDicSize(const Byte *p) +{ + UInt32 dicSize = GetUi32(p); + if (dicSize == 1) + return true; + for (unsigned i = 0; i <= 30; i++) + if (dicSize == ((UInt32)2 << i) || dicSize == ((UInt32)3 << i)) + return true; + return (dicSize == 0xFFFFFFFF); +} + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, + kpidMethod +}; + +static const Byte kArcProps[] = +{ + kpidNumStreams, + kpidMethod +}; + +struct CHeader +{ + UInt64 Size; + Byte FilterID; + Byte LzmaProps[5]; + + Byte GetProp() const { return LzmaProps[0]; } + UInt32 GetDicSize() const { return GetUi32(LzmaProps + 1); } + bool HasSize() const { return (Size != (UInt64)(Int64)-1); } + bool Parse(const Byte *buf, bool isThereFilter); +}; + +bool CHeader::Parse(const Byte *buf, bool isThereFilter) +{ + FilterID = 0; + if (isThereFilter) + FilterID = buf[0]; + const Byte *sig = buf + (isThereFilter ? 1 : 0); + for (int i = 0; i < 5; i++) + LzmaProps[i] = sig[i]; + Size = GetUi64(sig + 5); + return + LzmaProps[0] < 5 * 5 * 9 && + FilterID < 2 && + (!HasSize() || Size < ((UInt64)1 << 56)) + && CheckDicSize(LzmaProps + 1); +} + +class CDecoder Z7_final +{ + CMyComPtr _bcjStream; + CFilterCoder *_filterCoder; +public: + CMyComPtr2 _lzmaDecoder; + + ~CDecoder(); + HRESULT Create(bool filtered, ISequentialInStream *inStream); + + HRESULT Code(const CHeader &header, ISequentialOutStream *outStream, ICompressProgressInfo *progress); + + UInt64 GetInputProcessedSize() const { return _lzmaDecoder->GetInputProcessedSize(); } + + void ReleaseInStream() { if (_lzmaDecoder) _lzmaDecoder->ReleaseInStream(); } + + HRESULT ReadInput(Byte *data, UInt32 size, UInt32 *processedSize) + { return _lzmaDecoder->ReadFromInputStream(data, size, processedSize); } +}; + +HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream) +{ + _lzmaDecoder.Create_if_Empty(); + _lzmaDecoder->FinishStream = true; + + if (filteredMode) + { + if (!_bcjStream) + { + _filterCoder = new CFilterCoder(false); + CMyComPtr coder = _filterCoder; + _filterCoder->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec); + _bcjStream = _filterCoder; + } + } + + return _lzmaDecoder->SetInStream(inStream); +} + +CDecoder::~CDecoder() +{ + ReleaseInStream(); +} + +HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, + ICompressProgressInfo *progress) +{ + if (header.FilterID > 1) + return E_NOTIMPL; + + RINOK(_lzmaDecoder->SetDecoderProperties2(header.LzmaProps, 5)) + + bool filteredMode = (header.FilterID == 1); + + if (filteredMode) + { + RINOK(_filterCoder->SetOutStream(outStream)) + outStream = _bcjStream; + RINOK(_filterCoder->SetOutStreamSize(NULL)) + } + + const UInt64 *Size = header.HasSize() ? &header.Size : NULL; + HRESULT res = _lzmaDecoder->CodeResume(outStream, Size, progress); + + if (filteredMode) + { + { + HRESULT res2 = _filterCoder->OutStreamFinish(); + if (res == S_OK) + res = res2; + } + HRESULT res2 = _filterCoder->ReleaseOutStream(); + if (res == S_OK) + res = res2; + } + + RINOK(res) + + if (header.HasSize()) + if (_lzmaDecoder->GetOutputProcessedSize() != header.Size) + return S_FALSE; + + return S_OK; +} + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) + bool _lzma86; + bool _isArc; + bool _needSeekToStart; + bool _dataAfterEnd; + bool _needMoreInput; + bool _unsupported; + bool _dataError; + + bool _packSize_Defined; + bool _unpackSize_Defined; + bool _numStreams_Defined; + + CHeader _header; + CMyComPtr _stream; + CMyComPtr _seqStream; + + UInt64 _packSize; + UInt64 _unpackSize; + UInt64 _numStreams; + + void GetMethod(NCOM::CPropVariant &prop); + + unsigned GetHeaderSize() const { return 5 + 8 + (_lzma86 ? 1 : 0); } +public: + CHandler(bool lzma86) { _lzma86 = lzma86; } +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; + case kpidNumStreams: if (_numStreams_Defined) prop = _numStreams; break; + case kpidUnpackSize: if (_unpackSize_Defined) prop = _unpackSize; break; + case kpidMethod: GetMethod(prop); break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + if (_dataError) v |= kpv_ErrorFlags_DataError; + prop = v; + break; + } + default: break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + + +static char * DictSizeToString(UInt32 val, char *s) +{ + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == val) + return ::ConvertUInt32ToString(i, s); + char c = 'b'; + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + s = ::ConvertUInt32ToString(val, s); + *s++ = c; + *s = 0; + return s; +} + +static char *AddProp32(char *s, const char *name, UInt32 v) +{ + *s++ = ':'; + s = MyStpCpy(s, name); + return ::ConvertUInt32ToString(v, s); +} + +void CHandler::GetMethod(NCOM::CPropVariant &prop) +{ + if (!_stream) + return; + + char sz[64]; + char *s = sz; + if (_header.FilterID != 0) + s = MyStpCpy(s, "BCJ "); + s = MyStpCpy(s, "LZMA:"); + s = DictSizeToString(_header.GetDicSize(), s); + + UInt32 d = _header.GetProp(); + // if (d != 0x5D) + { + UInt32 lc = d % 9; + d /= 9; + UInt32 pb = d / 5; + UInt32 lp = d % 5; + if (lc != 3) s = AddProp32(s, "lc", lc); + if (lp != 0) s = AddProp32(s, "lp", lp); + if (pb != 2) s = AddProp32(s, "pb", pb); + } + prop = sz; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidSize: if (_stream && _header.HasSize()) prop = _header.Size; break; + case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; + case kpidMethod: GetMethod(prop); break; + default: break; + } + prop.Detach(value); + return S_OK; +} + +API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size) +{ + const UInt32 kHeaderSize = 1 + 4 + 8; + if (size < kHeaderSize) + return k_IsArc_Res_NEED_MORE; + if (p[0] >= 5 * 5 * 9) + return k_IsArc_Res_NO; + const UInt64 unpackSize = GetUi64(p + 1 + 4); + if (unpackSize != (UInt64)(Int64)-1) + { + if (unpackSize >= ((UInt64)1 << 56)) + return k_IsArc_Res_NO; + } + if (unpackSize != 0) + { + if (size < kHeaderSize + 2) + return k_IsArc_Res_NEED_MORE; + if (p[kHeaderSize] != 0) + return k_IsArc_Res_NO; + if (unpackSize != (UInt64)(Int64)-1) + { + if ((p[kHeaderSize + 1] & 0x80) != 0) + return k_IsArc_Res_NO; + } + } + if (!CheckDicSize(p + 1)) + // return k_IsArc_Res_YES_LOW_PROB; + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size) +{ + if (size < 1) + return k_IsArc_Res_NEED_MORE; + Byte filterID = p[0]; + if (filterID != 0 && filterID != 1) + return k_IsArc_Res_NO; + return IsArc_Lzma(p + 1, size - 1); +} +} + + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)) +{ + Close(); + + const unsigned headerSize = GetHeaderSize(); + const UInt32 kBufSize = 1 << 7; + Byte buf[kBufSize]; + size_t processedSize = kBufSize; + RINOK(ReadStream(inStream, buf, &processedSize)) + if (processedSize < headerSize + 2) + return S_FALSE; + if (!_header.Parse(buf, _lzma86)) + return S_FALSE; + const Byte *start = buf + headerSize; + if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80 + return S_FALSE; + + RINOK(InStream_GetSize_SeekToEnd(inStream, _packSize)) + + SizeT srcLen = (SizeT)processedSize - headerSize; + + if (srcLen > 10 + && _header.Size == 0 + // && _header.FilterID == 0 + && _header.LzmaProps[0] == 0 + ) + return S_FALSE; + + const UInt32 outLimit = 1 << 11; + Byte outBuf[outLimit]; + + SizeT outSize = outLimit; + if (outSize > _header.Size) + outSize = (SizeT)_header.Size; + SizeT destLen = outSize; + ELzmaStatus status; + + SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen, + _header.LzmaProps, 5, LZMA_FINISH_ANY, + &status, &g_Alloc); + + if (res != SZ_OK) + if (res != SZ_ERROR_INPUT_EOF) + return S_FALSE; + + _isArc = true; + _stream = inStream; + _seqStream = inStream; + _needSeekToStart = true; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _isArc = true; + _seqStream = stream; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _needSeekToStart = false; + _dataAfterEnd = false; + _needMoreInput = false; + _unsupported = false; + _dataError = false; + + _packSize_Defined = false; + _unpackSize_Defined = false; + _numStreams_Defined = false; + + _packSize = 0; + + _stream.Release(); + _seqStream.Release(); + return S_OK; +} + +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) + CMyComPtr Callback; +public: + UInt64 Offset; + + void Init(IArchiveOpenCallback *callback) { Callback = callback; } +}; + +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) +{ + if (Callback) + { + const UInt64 files = 0; + const UInt64 val = Offset + *inSize; + return Callback->SetCompleted(&files, &val); + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + if (_packSize_Defined) + RINOK(extractCallback->SetTotal(_packSize)) + + Int32 opResult; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(InStream_SeekToBegin(_stream)) + } + else + _needSeekToStart = true; + + CDecoder decoder; + RINOK(decoder.Create(_lzma86, _seqStream)) + + bool firstItem = true; + + UInt64 packSize = 0; + UInt64 unpackSize = 0; + UInt64 numStreams = 0; + + bool dataAfterEnd = false; + + HRESULT hres = S_OK; + + for (;;) + { + lps->InSize = packSize; + lps->OutSize = unpackSize; + RINOK(lps->SetCur()) + + const UInt32 kBufSize = 1 + 5 + 8; + Byte buf[kBufSize]; + const UInt32 headerSize = GetHeaderSize(); + UInt32 processed; + RINOK(decoder.ReadInput(buf, headerSize, &processed)) + if (processed != headerSize) + { + if (processed != 0) + dataAfterEnd = true; + break; + } + + CHeader st; + if (!st.Parse(buf, _lzma86)) + { + dataAfterEnd = true; + break; + } + numStreams++; + firstItem = false; + + hres = decoder.Code(st, outStream, lps); + + packSize = decoder.GetInputProcessedSize(); + unpackSize = outStream->GetSize(); + + if (hres == E_NOTIMPL) + { + _unsupported = true; + hres = S_FALSE; + break; + } + if (hres == S_FALSE) + break; + RINOK(hres) + } + + if (firstItem) + { + _isArc = false; + hres = S_FALSE; + } + else if (hres == S_OK || hres == S_FALSE) + { + if (dataAfterEnd) + _dataAfterEnd = true; + else if (decoder._lzmaDecoder->NeedsMoreInput()) + _needMoreInput = true; + + _packSize = packSize; + _unpackSize = unpackSize; + _numStreams = numStreams; + + _packSize_Defined = true; + _unpackSize_Defined = true; + _numStreams_Defined = true; + } + + opResult = NExtract::NOperationResult::kOK; + + if (!_isArc) + opResult = NExtract::NOperationResult::kIsNotArc; + else if (_needMoreInput) + opResult = NExtract::NOperationResult::kUnexpectedEnd; + else if (_unsupported) + opResult = NExtract::NOperationResult::kUnsupportedMethod; + else if (_dataAfterEnd) + opResult = NExtract::NOperationResult::kDataAfterEnd; + else if (hres == S_FALSE) + opResult = NExtract::NOperationResult::kDataError; + else if (hres == S_OK) + opResult = NExtract::NOperationResult::kOK; + else + return hres; + + // outStream.Release(); + } + return extractCallback->SetOperationResult(opResult); + + COM_TRY_END +} + +namespace NLzmaAr { + +// 2, { 0x5D, 0x00 }, + +REGISTER_ARC_I_CLS_NO_SIG( + CHandler(false), + "lzma", "lzma", NULL, 0xA, + 0, + NArcInfoFlags::kStartOpen | + NArcInfoFlags::kKeepName, + IsArc_Lzma) + +} + +namespace NLzma86Ar { + +REGISTER_ARC_I_CLS_NO_SIG( + CHandler(true), + "lzma86", "lzma86", NULL, 0xB, + 0, + NArcInfoFlags::kKeepName, + IsArc_Lzma86) + +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/MachoHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MachoHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/MachoHandler.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MachoHandler.cpp 2023-03-27 09:00:00.000000000 +0000 @@ -1,660 +1,744 @@ -// MachoHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/StringConvert.h" -#include "../../Common/IntToString.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" - -static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } -static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); } - -using namespace NWindows; -using namespace NCOM; - -namespace NArchive { -namespace NMacho { - -#define CPU_ARCH_ABI64 (1 << 24) -#define CPU_TYPE_386 7 -#define CPU_TYPE_ARM 12 -#define CPU_TYPE_SPARC 14 -#define CPU_TYPE_PPC 18 - -#define CPU_SUBTYPE_I386_ALL 3 - -#define CPU_TYPE_PPC64 (CPU_ARCH_ABI64 | CPU_TYPE_PPC) -#define CPU_TYPE_AMD64 (CPU_ARCH_ABI64 | CPU_TYPE_386) - -#define CPU_SUBTYPE_LIB64 (1 << 31) - -#define CPU_SUBTYPE_POWERPC_970 100 - -static const char * const k_PowerPc_SubTypes[] = -{ - NULL - , "601" - , "602" - , "603" - , "603e" - , "603ev" - , "604" - , "604e" - , "620" - , "750" - , "7400" - , "7450" -}; - -static const CUInt32PCharPair g_CpuPairs[] = -{ - { CPU_TYPE_386, "x86" }, - { CPU_TYPE_ARM, "ARM" }, - { CPU_TYPE_SPARC, "SPARC" }, - { CPU_TYPE_PPC, "PowerPC" } -}; - - -#define CMD_SEGMENT_32 1 -#define CMD_SEGMENT_64 0x19 - -#define SECT_TYPE_MASK 0x000000FF -#define SECT_ATTR_MASK 0xFFFFFF00 - -#define SECT_ATTR_ZEROFILL 1 - -static const char *g_SectTypes[] = -{ - "REGULAR" - , "ZEROFILL" - , "CSTRINGS" - , "4BYTE_LITERALS" - , "8BYTE_LITERALS" - , "LITERAL_POINTERS" - , "NON_LAZY_SYMBOL_POINTERS" - , "LAZY_SYMBOL_POINTERS" - , "SYMBOL_STUBS" - , "MOD_INIT_FUNC_POINTERS" - , "MOD_TERM_FUNC_POINTERS" - , "COALESCED" - , "GB_ZEROFILL" - , "INTERPOSING" - , "16BYTE_LITERALS" -}; - -enum EFileType -{ - kType_OBJECT = 1, - kType_EXECUTE, - kType_FVMLIB, - kType_CORE, - kType_PRELOAD, - kType_DYLIB, - kType_DYLINKER, - kType_BUNDLE, - kType_DYLIB_STUB, - kType_DSYM -}; - -static const char *g_FileTypes[] = -{ - "0" - , "OBJECT" - , "EXECUTE" - , "FVMLIB" - , "CORE" - , "PRELOAD" - , "DYLIB" - , "DYLINKER" - , "BUNDLE" - , "DYLIB_STUB" - , "DSYM" -}; - - -static const char *g_ArcFlags[] = -{ - "NOUNDEFS" - , "INCRLINK" - , "DYLDLINK" - , "BINDATLOAD" - , "PREBOUND" - , "SPLIT_SEGS" - , "LAZY_INIT" - , "TWOLEVEL" - , "FORCE_FLAT" - , "NOMULTIDEFS" - , "NOFIXPREBINDING" - , "PREBINDABLE" - , "ALLMODSBOUND" - , "SUBSECTIONS_VIA_SYMBOLS" - , "CANONICAL" - , "WEAK_DEFINES" - , "BINDS_TO_WEAK" - , "ALLOW_STACK_EXECUTION" - , "ROOT_SAFE" - , "SETUID_SAFE" - , "NO_REEXPORTED_DYLIBS" - , "PIE" - , "DEAD_STRIPPABLE_DYLIB" - , "HAS_TLV_DESCRIPTORS" - , "NO_HEAP_EXECUTION" -}; - - -static const CUInt32PCharPair g_Flags[] = -{ - { 31, "PURE_INSTRUCTIONS" }, - { 30, "NO_TOC" }, - { 29, "STRIP_STATIC_SYMS" }, - { 28, "NO_DEAD_STRIP" }, - { 27, "LIVE_SUPPORT" }, - { 26, "SELF_MODIFYING_CODE" }, - { 25, "DEBUG" }, - { 10, "SOME_INSTRUCTIONS" }, - { 9, "EXT_RELOC" }, - { 8, "LOC_RELOC" } -}; - -static const int kNameSize = 16; - -struct CSegment -{ - char Name[kNameSize]; -}; - -struct CSection -{ - char Name[kNameSize]; - char SegName[kNameSize]; - UInt64 Va; - UInt64 Pa; - UInt64 VSize; - UInt64 PSize; - - UInt32 Flags; - int SegmentIndex; - - bool IsDummy; - - CSection(): IsDummy(false) {} - // UInt64 GetPackSize() const { return Flags == SECT_ATTR_ZEROFILL ? 0 : Size; } - UInt64 GetPackSize() const { return PSize; } -}; - - -class CHandler: - public IInArchive, - public IArchiveAllowTail, - public CMyUnknownImp -{ - CMyComPtr _inStream; - CObjectVector _segments; - CObjectVector _sections; - bool _allowTail; - bool _mode64; - bool _be; - UInt32 _cpuType; - UInt32 _cpuSubType; - UInt32 _type; - UInt32 _flags; - UInt32 _headersSize; - UInt64 _totalSize; - - HRESULT Open2(ISequentialInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(AllowTail)(Int32 allowTail); - CHandler(): _allowTail(false) {} -}; - -static const Byte kArcProps[] = -{ - kpidCpu, - kpidBit64, - kpidBigEndian, - kpidCharacts, - kpidHeadersSize -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidCharacts, - kpidOffset, - kpidVa -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - CPropVariant prop; - switch (propID) - { - case kpidShortComment: - case kpidCpu: - { - AString s; - char temp[16]; - UInt32 cpu = _cpuType & ~(UInt32)CPU_ARCH_ABI64; - if (_cpuType == CPU_TYPE_AMD64) - s = "x64"; - else - { - const char *n = NULL; - for (unsigned i = 0; i < ARRAY_SIZE(g_CpuPairs); i++) - { - const CUInt32PCharPair &pair = g_CpuPairs[i]; - if (pair.Value == cpu) - { - n = pair.Name; - break; - } - } - if (!n) - { - ConvertUInt32ToString(cpu, temp); - n = temp; - } - s = n; - - if (_cpuType & CPU_ARCH_ABI64) - s += " 64-bit"; - else if (_cpuSubType & CPU_SUBTYPE_LIB64) - s += " 64-bit lib"; - } - UInt32 t = _cpuSubType & ~(UInt32)CPU_SUBTYPE_LIB64; - if (t != 0 && (t != CPU_SUBTYPE_I386_ALL || cpu != CPU_TYPE_386)) - { - const char *n = NULL; - if (cpu == CPU_TYPE_PPC) - { - if (t == CPU_SUBTYPE_POWERPC_970) - n = "970"; - else if (t < ARRAY_SIZE(k_PowerPc_SubTypes)) - n = k_PowerPc_SubTypes[t]; - } - if (!n) - { - ConvertUInt32ToString(t, temp); - n = temp; - } - s.Add_Space(); - s += n; - } - prop = s; - break; - } - case kpidCharacts: - { - // TYPE_TO_PROP(g_FileTypes, _type, prop); break; - AString res = TypeToString(g_FileTypes, ARRAY_SIZE(g_FileTypes), _type); - AString s = FlagsToString(g_ArcFlags, ARRAY_SIZE(g_ArcFlags), _flags); - if (!s.IsEmpty()) - { - res.Add_Space(); - res += s; - } - prop = res; - break; - } - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _headersSize; break; - case kpidBit64: if (_mode64) prop = _mode64; break; - case kpidBigEndian: if (_be) prop = _be; break; - case kpidExtension: - { - const char *ext = NULL; - if (_type == kType_OBJECT) - ext = "o"; - else if (_type == kType_BUNDLE) - ext = "bundle"; - else if (_type == kType_DYLIB) - ext = "dylib"; // main shared library usually does not have extension - if (ext) - prop = ext; - break; - } - // case kpidIsSelfExe: prop = (_type == kType_EXECUTE); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static AString GetName(const char *name) -{ - char res[kNameSize + 1]; - memcpy(res, name, kNameSize); - res[kNameSize] = 0; - return res; -} - -static AString SectFlagsToString(UInt32 flags) -{ - AString res = TypeToString(g_SectTypes, ARRAY_SIZE(g_SectTypes), flags & SECT_TYPE_MASK); - AString s = FlagsToString(g_Flags, ARRAY_SIZE(g_Flags), flags & SECT_ATTR_MASK); - if (!s.IsEmpty()) - { - res.Add_Space(); - res += s; - } - return res; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - CPropVariant prop; - const CSection &item = _sections[index]; - switch (propID) - { - case kpidPath: - { - AString s = GetName(_segments[item.SegmentIndex].Name); - if (!item.IsDummy) - s += GetName(item.Name); - prop = MultiByteToUnicodeString(s); - break; - } - case kpidSize: /* prop = (UInt64)item.VSize; break; */ - case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; - case kpidCharacts: if (!item.IsDummy) prop = SectFlagsToString(item.Flags); break; - case kpidOffset: prop = item.Pa; break; - case kpidVa: prop = item.Va; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(ISequentialInStream *stream) -{ - const UInt32 kStartHeaderSize = 7 * 4; - - Byte header[kStartHeaderSize]; - RINOK(ReadStream_FALSE(stream, header, kStartHeaderSize)); - bool be, mode64; - switch (GetUi32(header)) - { - case 0xCEFAEDFE: be = true; mode64 = false; break; - case 0xCFFAEDFE: be = true; mode64 = true; break; - case 0xFEEDFACE: be = false; mode64 = false; break; - case 0xFEEDFACF: be = false; mode64 = true; break; - default: return S_FALSE; - } - - UInt32 numCommands = Get32(header + 0x10, be); - UInt32 commandsSize = Get32(header + 0x14, be); - - if (numCommands == 0) - return S_FALSE; - - if (commandsSize > (1 << 24) || - numCommands > (1 << 21) || - numCommands * 8 > commandsSize) - return S_FALSE; - - _cpuType = Get32(header + 4, be); - _cpuSubType = Get32(header + 8, be); - _type = Get32(header + 0xC, be); - _flags = Get32(header + 0x18, be); - - /* - // Probably the sections are in first commands. So we can reduce the number of commands. - bool reduceCommands = false; - const UInt32 kNumReduceCommands = 16; - if (numCommands > kNumReduceCommands) - { - reduceCommands = true; - numCommands = kNumReduceCommands; - } - */ - - UInt32 startHeaderSize = kStartHeaderSize; - if (mode64) - startHeaderSize += 4; - _headersSize = startHeaderSize + commandsSize; - _totalSize = _headersSize; - CByteArr buffer(_headersSize); - RINOK(ReadStream_FALSE(stream, buffer + kStartHeaderSize, _headersSize - kStartHeaderSize)); - const Byte *buf = buffer + startHeaderSize; - size_t size = _headersSize - startHeaderSize; - for (UInt32 cmdIndex = 0; cmdIndex < numCommands; cmdIndex++) - { - if (size < 8) - return S_FALSE; - UInt32 cmd = Get32(buf, be); - UInt32 cmdSize = Get32(buf + 4, be); - if (cmdSize < 8) - return S_FALSE; - if (size < cmdSize) - return S_FALSE; - if (cmd == CMD_SEGMENT_32 || cmd == CMD_SEGMENT_64) - { - UInt32 offs = (cmd == CMD_SEGMENT_64) ? 0x48 : 0x38; - if (cmdSize < offs) - break; - - UInt64 vmAddr, vmSize, phAddr, phSize; - - { - if (cmd == CMD_SEGMENT_64) - { - vmAddr = Get64(buf + 0x18, be); - vmSize = Get64(buf + 0x20, be); - phAddr = Get64(buf + 0x28, be); - phSize = Get64(buf + 0x30, be); - } - else - { - vmAddr = Get32(buf + 0x18, be); - vmSize = Get32(buf + 0x1C, be); - phAddr = Get32(buf + 0x20, be); - phSize = Get32(buf + 0x24, be); - } - { - UInt64 totalSize = phAddr + phSize; - if (totalSize < phAddr) - return S_FALSE; - if (_totalSize < totalSize) - _totalSize = totalSize; - } - } - - CSegment seg; - memcpy(seg.Name, buf + 8, kNameSize); - _segments.Add(seg); - - UInt32 numSections = Get32(buf + offs - 8, be); - if (numSections > (1 << 8)) - return S_FALSE; - - if (numSections == 0) - { - CSection § = _sections.AddNew(); - sect.IsDummy = true; - sect.SegmentIndex = _segments.Size() - 1; - sect.Va = vmAddr; - sect.PSize = phSize; - sect.VSize = vmSize; - sect.Pa = phAddr; - sect.Flags = 0; - } - else do - { - UInt32 headSize = (cmd == CMD_SEGMENT_64) ? 0x50 : 0x44; - const Byte *p = buf + offs; - if (cmdSize - offs < headSize) - break; - CSection § = _sections.AddNew(); - unsigned f32Offset; - if (cmd == CMD_SEGMENT_64) - { - sect.Va = Get64(p + 0x20, be); - sect.VSize = Get64(p + 0x28, be); - f32Offset = 0x30; - } - else - { - sect.Va = Get32(p + 0x20, be); - sect.VSize = Get32(p + 0x24, be); - f32Offset = 0x28; - } - sect.Pa = Get32(p + f32Offset, be); - sect.Flags = Get32(p + f32Offset + 10, be); - if (sect.Flags == SECT_ATTR_ZEROFILL) - sect.PSize = 0; - else - sect.PSize = sect.VSize; - memcpy(sect.Name, p, kNameSize); - memcpy(sect.SegName, p + kNameSize, kNameSize); - sect.SegmentIndex = _segments.Size() - 1; - offs += headSize; - } - while (--numSections); - - if (offs != cmdSize) - return S_FALSE; - } - buf += cmdSize; - size -= cmdSize; - } - // return (reduceCommands || (size == 0)) ? S_OK : S_FALSE; - if (size != 0) - return S_FALSE; - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(inStream)); - if (!_allowTail) - { - UInt64 fileSize; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize)); - if (fileSize > _totalSize) - return S_FALSE; - } - _inStream = inStream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _inStream.Release(); - _sections.Clear(); - _segments.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _sections.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _sections.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _sections[allFilesMode ? i : indices[i]].GetPackSize(); - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CSection &item = _sections[index]; - currentItemSize = item.GetPackSize(); - - CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) -{ - _allowTail = IntToBool(allowTail); - return S_OK; -} - -static const Byte k_Signature[] = { - 4, 0xCE, 0xFA, 0xED, 0xFE, - 4, 0xCF, 0xFA, 0xED, 0xFE, - 4, 0xFE, 0xED, 0xFA, 0xCE, - 4, 0xFE, 0xED, 0xFA, 0xCF }; - -REGISTER_ARC_I( - "MachO", "macho", 0, 0xDF, - k_Signature, - 0, - NArcInfoFlags::kMultiSignature | - NArcInfoFlags::kPreArc, - NULL) - -}} +// MachoHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringConvert.h" +#include "../../Common/IntToString.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" + +static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } +static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); } + +using namespace NWindows; +using namespace NCOM; + +namespace NArchive { +namespace NMacho { + +#define CPU_ARCH_ABI64 (1 << 24) +#define CPU_TYPE_386 7 +#define CPU_TYPE_ARM 12 +#define CPU_TYPE_SPARC 14 +#define CPU_TYPE_PPC 18 + +#define CPU_SUBTYPE_I386_ALL 3 + +// #define CPU_TYPE_PPC64 (CPU_ARCH_ABI64 | CPU_TYPE_PPC) +#define CPU_TYPE_AMD64 (CPU_ARCH_ABI64 | CPU_TYPE_386) +#define CPU_TYPE_ARM64 (CPU_ARCH_ABI64 | CPU_TYPE_ARM) + +#define CPU_SUBTYPE_LIB64 ((UInt32)1 << 31) + +#define CPU_SUBTYPE_POWERPC_970 100 + +static const char * const k_PowerPc_SubTypes[] = +{ + NULL + , "601" + , "602" + , "603" + , "603e" + , "603ev" + , "604" + , "604e" + , "620" + , "750" + , "7400" + , "7450" +}; + +static const CUInt32PCharPair g_CpuPairs[] = +{ + { CPU_TYPE_AMD64, "x64" }, + { CPU_TYPE_ARM64, "ARM64" }, + { CPU_TYPE_386, "x86" }, + { CPU_TYPE_ARM, "ARM" }, + { CPU_TYPE_SPARC, "SPARC" }, + { CPU_TYPE_PPC, "PowerPC" } +}; + + +#define CMD_SEGMENT_32 1 +#define CMD_SEGMENT_64 0x19 + +#define SECT_TYPE_MASK 0x000000FF +#define SECT_ATTR_MASK 0xFFFFFF00 + +#define SECT_ATTR_ZEROFILL 1 + +static const char * const g_SectTypes[] = +{ + "REGULAR" + , "ZEROFILL" + , "CSTRINGS" + , "4BYTE_LITERALS" + , "8BYTE_LITERALS" + , "LITERAL_POINTERS" + , "NON_LAZY_SYMBOL_POINTERS" + , "LAZY_SYMBOL_POINTERS" + , "SYMBOL_STUBS" + , "MOD_INIT_FUNC_POINTERS" + , "MOD_TERM_FUNC_POINTERS" + , "COALESCED" + , "GB_ZEROFILL" + , "INTERPOSING" + , "16BYTE_LITERALS" + , "DTRACE_DOF" + , "LAZY_DYLIB_SYMBOL_POINTERS" + , "THREAD_LOCAL_REGULAR" + , "THREAD_LOCAL_ZEROFILL" + , "THREAD_LOCAL_VARIABLES" + , "THREAD_LOCAL_VARIABLE_POINTERS" + , "THREAD_LOCAL_INIT_FUNCTION_POINTERS" +}; + +enum EFileType +{ + kType_OBJECT = 1, + kType_EXECUTE, + kType_FVMLIB, + kType_CORE, + kType_PRELOAD, + kType_DYLIB, + kType_DYLINKER, + kType_BUNDLE, + kType_DYLIB_STUB, + kType_DSYM +}; + +static const char * const g_FileTypes[] = +{ + "0" + , "OBJECT" + , "EXECUTE" + , "FVMLIB" + , "CORE" + , "PRELOAD" + , "DYLIB" + , "DYLINKER" + , "BUNDLE" + , "DYLIB_STUB" + , "DSYM" +}; + + +static const char * const g_ArcFlags[] = +{ + "NOUNDEFS" + , "INCRLINK" + , "DYLDLINK" + , "BINDATLOAD" + , "PREBOUND" + , "SPLIT_SEGS" + , "LAZY_INIT" + , "TWOLEVEL" + , "FORCE_FLAT" + , "NOMULTIDEFS" + , "NOFIXPREBINDING" + , "PREBINDABLE" + , "ALLMODSBOUND" + , "SUBSECTIONS_VIA_SYMBOLS" + , "CANONICAL" + , "WEAK_DEFINES" + , "BINDS_TO_WEAK" + , "ALLOW_STACK_EXECUTION" + , "ROOT_SAFE" + , "SETUID_SAFE" + , "NO_REEXPORTED_DYLIBS" + , "PIE" + , "DEAD_STRIPPABLE_DYLIB" + , "HAS_TLV_DESCRIPTORS" + , "NO_HEAP_EXECUTION" +}; + + +static const CUInt32PCharPair g_SectFlags[] = +{ + { 31, "PURE_INSTRUCTIONS" }, + { 30, "NO_TOC" }, + { 29, "STRIP_STATIC_SYMS" }, + { 28, "NO_DEAD_STRIP" }, + { 27, "LIVE_SUPPORT" }, + { 26, "SELF_MODIFYING_CODE" }, + { 25, "DEBUG" }, + { 10, "SOME_INSTRUCTIONS" }, + { 9, "EXT_RELOC" }, + { 8, "LOC_RELOC" } +}; + + +// VM_PROT_* +static const char * const g_SegmentProt[] = +{ + "READ" + , "WRITE" + , "EXECUTE" + /* + , "NO_CHANGE" + , "COPY" + , "TRUSTED" + , "IS_MASK" + */ +}; + +// SG_* + +static const char * const g_SegmentFlags[] = +{ + "SG_HIGHVM" + , "SG_FVMLIB" + , "SG_NORELOC" + , "SG_PROTECTED_VERSION_1" + , "SG_READ_ONLY" +}; + +static const unsigned kNameSize = 16; + +struct CSegment +{ + char Name[kNameSize]; + UInt32 MaxProt; + UInt32 InitProt; + UInt32 Flags; +}; + +struct CSection +{ + char Name[kNameSize]; + // char SegName[kNameSize]; + UInt64 Va; + UInt64 Pa; + UInt64 VSize; + UInt64 PSize; + + UInt32 Align; + UInt32 Flags; + unsigned SegmentIndex; + bool IsDummy; + + CSection(): IsDummy(false) {} + // UInt64 GetPackSize() const { return Flags == SECT_ATTR_ZEROFILL ? 0 : Size; } + UInt64 GetPackSize() const { return PSize; } +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveAllowTail +) + CMyComPtr _inStream; + CObjectVector _segments; + CObjectVector _sections; + bool _allowTail; + bool _mode64; + bool _be; + UInt32 _cpuType; + UInt32 _cpuSubType; + UInt32 _type; + UInt32 _flags; + UInt32 _headersSize; + UInt64 _totalSize; + + HRESULT Open2(ISequentialInStream *stream); +public: + CHandler(): _allowTail(false) {} +}; + +static const Byte kArcProps[] = +{ + kpidCpu, + kpidBit64, + kpidBigEndian, + kpidCharacts, + kpidHeadersSize +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidCharacts, + kpidOffset, + kpidVa, + kpidClusterSize // Align +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + CPropVariant prop; + switch (propID) + { + case kpidShortComment: + case kpidCpu: + { + AString s; + const UInt32 cpu = _cpuType & ~(UInt32)CPU_ARCH_ABI64; + UInt32 flag64 = _cpuType & (UInt32)CPU_ARCH_ABI64; + { + s.Add_UInt32(cpu); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CpuPairs); i++) + { + const CUInt32PCharPair &pair = g_CpuPairs[i]; + if (pair.Value == cpu || pair.Value == _cpuType) + { + if (pair.Value == _cpuType) + flag64 = 0; + s = pair.Name; + break; + } + } + + if (flag64 != 0) + s.Add_OptSpaced("64-bit"); + else if ((_cpuSubType & CPU_SUBTYPE_LIB64) && _cpuType != CPU_TYPE_AMD64) + s.Add_OptSpaced("64-bit-lib"); + } + const UInt32 t = _cpuSubType & ~(UInt32)CPU_SUBTYPE_LIB64; + if (t != 0 && (t != CPU_SUBTYPE_I386_ALL || cpu != CPU_TYPE_386)) + { + const char *n = NULL; + if (cpu == CPU_TYPE_PPC) + { + if (t == CPU_SUBTYPE_POWERPC_970) + n = "970"; + else if (t < Z7_ARRAY_SIZE(k_PowerPc_SubTypes)) + n = k_PowerPc_SubTypes[t]; + } + s.Add_Space(); + if (n) + s += n; + else + s.Add_UInt32(t); + } + prop = s; + break; + } + case kpidCharacts: + { + // TYPE_TO_PROP(g_FileTypes, _type, prop); break; + AString res (TypeToString(g_FileTypes, Z7_ARRAY_SIZE(g_FileTypes), _type)); + const AString s (FlagsToString(g_ArcFlags, Z7_ARRAY_SIZE(g_ArcFlags), _flags)); + if (!s.IsEmpty()) + { + res.Add_Space(); + res += s; + } + prop = res; + break; + } + case kpidPhySize: prop = _totalSize; break; + case kpidHeadersSize: prop = _headersSize; break; + case kpidBit64: if (_mode64) prop = _mode64; break; + case kpidBigEndian: if (_be) prop = _be; break; + case kpidExtension: + { + const char *ext = NULL; + if (_type == kType_OBJECT) + ext = "o"; + else if (_type == kType_BUNDLE) + ext = "bundle"; + else if (_type == kType_DYLIB) + ext = "dylib"; // main shared library usually does not have extension + if (ext) + prop = ext; + break; + } + // case kpidIsSelfExe: prop = (_type == kType_EXECUTE); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static void AddName(AString &s, const char *name) +{ + char temp[kNameSize + 1]; + memcpy(temp, name, kNameSize); + temp[kNameSize] = 0; + s += temp; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + CPropVariant prop; + const CSection &item = _sections[index]; + switch (propID) + { + case kpidPath: + { + AString s; + AddName(s, _segments[item.SegmentIndex].Name); + if (!item.IsDummy) + { + // CSection::SegName and CSegment::Name are same in real cases. + // AddName(s, item.SegName); + AddName(s, item.Name); + } + prop = MultiByteToUnicodeString(s); + break; + } + case kpidSize: /* prop = (UInt64)item.VSize; break; */ + case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; + case kpidCharacts: + { + AString res; + { + if (!item.IsDummy) + { + { + const AString s (TypeToString(g_SectTypes, Z7_ARRAY_SIZE(g_SectTypes), item.Flags & SECT_TYPE_MASK)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("sect_type:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SectFlags, Z7_ARRAY_SIZE(g_SectFlags), item.Flags & SECT_ATTR_MASK)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("sect_flags:"); + res.Add_OptSpaced(s); + } + } + } + const CSegment &seg = _segments[item.SegmentIndex]; + { + const AString s (FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), seg.Flags)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("seg_flags:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SegmentProt, Z7_ARRAY_SIZE(g_SegmentProt), seg.MaxProt)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("max_prot:"); + res.Add_OptSpaced(s); + } + } + { + const AString s (FlagsToString(g_SegmentProt, Z7_ARRAY_SIZE(g_SegmentProt), seg.InitProt)); + if (!s.IsEmpty()) + { + res.Add_OptSpaced("init_prot:"); + res.Add_OptSpaced(s); + } + } + } + if (!res.IsEmpty()) + prop = res; + break; + } + case kpidOffset: prop = item.Pa; break; + case kpidVa: prop = item.Va; break; + case kpidClusterSize: prop = (UInt32)1 << item.Align; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +HRESULT CHandler::Open2(ISequentialInStream *stream) +{ + const UInt32 kStartHeaderSize = 7 * 4; + + Byte header[kStartHeaderSize]; + RINOK(ReadStream_FALSE(stream, header, kStartHeaderSize)) + bool be, mode64; + switch (GetUi32(header)) + { + case 0xCEFAEDFE: be = true; mode64 = false; break; + case 0xCFFAEDFE: be = true; mode64 = true; break; + case 0xFEEDFACE: be = false; mode64 = false; break; + case 0xFEEDFACF: be = false; mode64 = true; break; + default: return S_FALSE; + } + + _mode64 = mode64; + _be = be; + + const UInt32 numCommands = Get32(header + 0x10, be); + const UInt32 commandsSize = Get32(header + 0x14, be); + + if (numCommands == 0) + return S_FALSE; + + if (commandsSize > (1 << 24) || + numCommands > (1 << 21) || + numCommands * 8 > commandsSize) + return S_FALSE; + + _cpuType = Get32(header + 4, be); + _cpuSubType = Get32(header + 8, be); + _type = Get32(header + 0xC, be); + _flags = Get32(header + 0x18, be); + + /* + // Probably the sections are in first commands. So we can reduce the number of commands. + bool reduceCommands = false; + const UInt32 kNumReduceCommands = 16; + if (numCommands > kNumReduceCommands) + { + reduceCommands = true; + numCommands = kNumReduceCommands; + } + */ + + UInt32 startHeaderSize = kStartHeaderSize; + if (mode64) + startHeaderSize += 4; + _headersSize = startHeaderSize + commandsSize; + _totalSize = _headersSize; + CByteArr buffer(_headersSize); + RINOK(ReadStream_FALSE(stream, buffer + kStartHeaderSize, _headersSize - kStartHeaderSize)) + const Byte *buf = buffer + startHeaderSize; + size_t size = _headersSize - startHeaderSize; + for (UInt32 cmdIndex = 0; cmdIndex < numCommands; cmdIndex++) + { + if (size < 8) + return S_FALSE; + UInt32 cmd = Get32(buf, be); + UInt32 cmdSize = Get32(buf + 4, be); + if (cmdSize < 8) + return S_FALSE; + if (size < cmdSize) + return S_FALSE; + if (cmd == CMD_SEGMENT_32 || cmd == CMD_SEGMENT_64) + { + UInt32 offs = (cmd == CMD_SEGMENT_64) ? 0x48 : 0x38; + if (cmdSize < offs) + break; + + UInt64 vmAddr, vmSize, phAddr, phSize; + + { + if (cmd == CMD_SEGMENT_64) + { + vmAddr = Get64(buf + 0x18, be); + vmSize = Get64(buf + 0x20, be); + phAddr = Get64(buf + 0x28, be); + phSize = Get64(buf + 0x30, be); + } + else + { + vmAddr = Get32(buf + 0x18, be); + vmSize = Get32(buf + 0x1C, be); + phAddr = Get32(buf + 0x20, be); + phSize = Get32(buf + 0x24, be); + } + { + UInt64 totalSize = phAddr + phSize; + if (totalSize < phAddr) + return S_FALSE; + if (_totalSize < totalSize) + _totalSize = totalSize; + } + } + + CSegment seg; + seg.MaxProt = Get32(buf + offs - 16, be); + seg.InitProt = Get32(buf + offs - 12, be); + seg.Flags = Get32(buf + offs - 4, be); + memcpy(seg.Name, buf + 8, kNameSize); + _segments.Add(seg); + + UInt32 numSections = Get32(buf + offs - 8, be); + if (numSections > (1 << 8)) + return S_FALSE; + + if (numSections == 0) + { + CSection § = _sections.AddNew(); + sect.IsDummy = true; + sect.SegmentIndex = _segments.Size() - 1; + sect.Va = vmAddr; + sect.PSize = phSize; + sect.VSize = vmSize; + sect.Pa = phAddr; + sect.Align = 0; + sect.Flags = 0; + } + else do + { + const UInt32 headSize = (cmd == CMD_SEGMENT_64) ? 0x50 : 0x44; + const Byte *p = buf + offs; + if (cmdSize - offs < headSize) + break; + CSection § = _sections.AddNew(); + unsigned f32Offset; + if (cmd == CMD_SEGMENT_64) + { + sect.Va = Get64(p + 0x20, be); + sect.VSize = Get64(p + 0x28, be); + f32Offset = 0x30; + } + else + { + sect.Va = Get32(p + 0x20, be); + sect.VSize = Get32(p + 0x24, be); + f32Offset = 0x28; + } + sect.Pa = Get32(p + f32Offset, be); + sect.Align = Get32(p + f32Offset + 4, be); + // sect.reloff = Get32(p + f32Offset + 8, be); + // sect.nreloc = Get32(p + f32Offset + 12, be); + sect.Flags = Get32(p + f32Offset + 16, be); + if ((sect.Flags & SECT_TYPE_MASK) == SECT_ATTR_ZEROFILL) + sect.PSize = 0; + else + sect.PSize = sect.VSize; + memcpy(sect.Name, p, kNameSize); + // memcpy(sect.SegName, p + kNameSize, kNameSize); + sect.SegmentIndex = _segments.Size() - 1; + offs += headSize; + } + while (--numSections); + + if (offs != cmdSize) + return S_FALSE; + } + buf += cmdSize; + size -= cmdSize; + } + // return (reduceCommands || (size == 0)) ? S_OK : S_FALSE; + if (size != 0) + return S_FALSE; + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream)) + if (!_allowTail) + { + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, fileSize)) + if (fileSize > _totalSize) + return S_FALSE; + } + _inStream = inStream; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _inStream.Release(); + _sections.Clear(); + _segments.Clear(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _sections.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _sections.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _sections[allFilesMode ? i : indices[i]].GetPackSize(); + extractCallback->SetTotal(totalSize); + + UInt64 currentTotalSize = 0; + UInt64 currentItemSize; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_inStream); + + for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CSection &item = _sections[index]; + currentItemSize = item.GetPackSize(); + + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_inStream, item.Pa)) + streamSpec->Init(currentItemSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) + outStream.Release(); + RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) +{ + _allowTail = IntToBool(allowTail); + return S_OK; +} + +static const Byte k_Signature[] = { + 4, 0xCE, 0xFA, 0xED, 0xFE, + 4, 0xCF, 0xFA, 0xED, 0xFE, + 4, 0xFE, 0xED, 0xFA, 0xCE, + 4, 0xFE, 0xED, 0xFA, 0xCF }; + +REGISTER_ARC_I( + "MachO", "macho", NULL, 0xDF, + k_Signature, + 0, + NArcInfoFlags::kMultiSignature | + NArcInfoFlags::kPreArc, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/MbrHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MbrHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/MbrHandler.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MbrHandler.cpp 2023-06-26 16:00:00.000000000 +0000 @@ -1,449 +1,643 @@ -// MbrHandler.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -using namespace NWindows; - -namespace NArchive { -namespace NMbr { - -struct CChs -{ - Byte Head; - Byte SectCyl; - Byte Cyl8; - - UInt32 GetSector() const { return SectCyl & 0x3F; } - UInt32 GetCyl() const { return ((UInt32)SectCyl >> 6 << 8) | Cyl8; } - void ToString(NCOM::CPropVariant &prop) const; - - void Parse(const Byte *p) - { - Head = p[0]; - SectCyl = p[1]; - Cyl8 = p[2]; - } - bool Check() const { return GetSector() > 0; } -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -// Chs in some MBRs contains only low bits of "Cyl number". So we disable check. -/* -static int CompareChs(const CChs &c1, const CChs &c2) -{ - RINOZ(MyCompare(c1.GetCyl(), c2.GetCyl())); - RINOZ(MyCompare(c1.Head, c2.Head)); - return MyCompare(c1.GetSector(), c2.GetSector()); -} -*/ - -static void AddUIntToString(UInt32 val, AString &res) -{ - char s[16]; - ConvertUInt32ToString(val, s); - res += s; -} - -void CChs::ToString(NCOM::CPropVariant &prop) const -{ - AString s; - AddUIntToString(GetCyl(), s); - s += '-'; - AddUIntToString(Head, s); - s += '-'; - AddUIntToString(GetSector(), s); - prop = s; -} - -struct CPartition -{ - Byte Status; - CChs BeginChs; - Byte Type; - CChs EndChs; - UInt32 Lba; - UInt32 NumBlocks; - - CPartition() { memset (this, 0, sizeof(*this)); } - - bool IsEmpty() const { return Type == 0; } - bool IsExtended() const { return Type == 5 || Type == 0xF; } - UInt32 GetLimit() const { return Lba + NumBlocks; } - // bool IsActive() const { return Status == 0x80; } - UInt64 GetPos() const { return (UInt64)Lba * 512; } - UInt64 GetSize() const { return (UInt64)NumBlocks * 512; } - - bool CheckLbaLimits() const { return (UInt32)0xFFFFFFFF - Lba >= NumBlocks; } - bool Parse(const Byte *p) - { - Status = p[0]; - BeginChs.Parse(p + 1); - Type = p[4]; - EndChs.Parse(p + 5); - Lba = GetUi32(p + 8); - NumBlocks = GetUi32(p + 12); - if (Type == 0) - return true; - if (Status != 0 && Status != 0x80) - return false; - return BeginChs.Check() - && EndChs.Check() - // && CompareChs(BeginChs, EndChs) <= 0 - && NumBlocks > 0 - && CheckLbaLimits(); - } - - #ifdef SHOW_DEBUG_INFO - void Print() const - { - NCOM::CPropVariant prop, prop2; - BeginChs.ToString(prop); - EndChs.ToString(prop2); - printf(" %2x %2x %8X %8X %12S %12S", (int)Status, (int)Type, Lba, NumBlocks, prop.bstrVal, prop2.bstrVal); - } - #endif -}; - -struct CPartType -{ - UInt32 Id; - const char *Ext; - const char *Name; -}; - -static const char *kFat = "fat"; - -static const CPartType kPartTypes[] = -{ - { 0x01, kFat, "FAT12" }, - { 0x04, kFat, "FAT16 DOS 3.0+" }, - { 0x05, 0, "Extended" }, - { 0x06, kFat, "FAT16 DOS 3.31+" }, - { 0x07, "ntfs", "NTFS" }, - { 0x0B, kFat, "FAT32" }, - { 0x0C, kFat, "FAT32-LBA" }, - { 0x0E, kFat, "FAT16-LBA" }, - { 0x0F, 0, "Extended-LBA" }, - { 0x11, kFat, "FAT12-Hidden" }, - { 0x14, kFat, "FAT16-Hidden < 32 MB" }, - { 0x16, kFat, "FAT16-Hidden >= 32 MB" }, - { 0x1B, kFat, "FAT32-Hidden" }, - { 0x1C, kFat, "FAT32-LBA-Hidden" }, - { 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" }, - { 0x82, 0, "Solaris x86 / Linux swap" }, - { 0x83, 0, "Linux" }, - { 0x8E, "lvm", "Linux LVM" }, - { 0xA5, 0, "BSD slice" }, - { 0xBE, 0, "Solaris 8 boot" }, - { 0xBF, 0, "New Solaris x86" }, - { 0xC2, 0, "Linux-Hidden" }, - { 0xC3, 0, "Linux swap-Hidden" }, - { 0xEE, 0, "GPT" }, - { 0xEE, 0, "EFI" } -}; - -static int FindPartType(UInt32 type) -{ - for (unsigned i = 0; i < ARRAY_SIZE(kPartTypes); i++) - if (kPartTypes[i].Id == type) - return i; - return -1; -} - -struct CItem -{ - bool IsReal; - bool IsPrim; - UInt64 Size; - CPartition Part; -}; - -class CHandler: public CHandlerCont -{ - CObjectVector _items; - UInt64 _totalSize; - CByteBuffer _buffer; - - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const - { - const CItem &item = _items[index]; - pos = item.Part.GetPos(); - size = item.Size; - return NExtract::NOperationResult::kOK; - } - - HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level); -public: - INTERFACE_IInArchive_Cont(;) -}; - -HRESULT CHandler::ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level) -{ - if (level >= 128 || _items.Size() >= 128) - return S_FALSE; - - const unsigned kNumHeaderParts = 4; - CPartition parts[kNumHeaderParts]; - - { - const UInt32 kSectorSize = 512; - _buffer.Alloc(kSectorSize); - Byte *buf = _buffer; - UInt64 newPos = (UInt64)lba << 9; - if (newPos + 512 > _totalSize) - return S_FALSE; - RINOK(stream->Seek(newPos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)); - - if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) - return S_FALSE; - - for (unsigned i = 0; i < kNumHeaderParts; i++) - if (!parts[i].Parse(buf + 0x1BE + 16 * i)) - return S_FALSE; - } - - PRF(printf("\n# %8X", lba)); - - UInt32 limLba = lba + 1; - if (limLba == 0) - return S_FALSE; - - for (unsigned i = 0; i < kNumHeaderParts; i++) - { - CPartition &part = parts[i]; - - if (part.IsEmpty()) - continue; - PRF(printf("\n %2d ", (unsigned)level)); - #ifdef SHOW_DEBUG_INFO - part.Print(); - #endif - - unsigned numItems = _items.Size(); - UInt32 newLba = lba + part.Lba; - - if (part.IsExtended()) - { - // if (part.Type == 5) // Check it! - newLba = baseLba + part.Lba; - if (newLba < limLba) - return S_FALSE; - HRESULT res = ReadTables(stream, level < 1 ? newLba : baseLba, newLba, level + 1); - if (res != S_FALSE && res != S_OK) - return res; - } - if (newLba < limLba) - return S_FALSE; - part.Lba = newLba; - if (!part.CheckLbaLimits()) - return S_FALSE; - - CItem n; - n.Part = part; - bool addItem = false; - if (numItems == _items.Size()) - { - n.IsPrim = (level == 0); - n.IsReal = true; - addItem = true; - } - else - { - const CItem &back = _items.Back(); - UInt32 backLimit = back.Part.GetLimit(); - UInt32 partLimit = part.GetLimit(); - if (backLimit < partLimit) - { - n.IsReal = false; - n.Part.Lba = backLimit; - n.Part.NumBlocks = partLimit - backLimit; - addItem = true; - } - } - if (addItem) - { - if (n.Part.GetLimit() < limLba) - return S_FALSE; - limLba = n.Part.GetLimit(); - n.Size = n.Part.GetSize(); - _items.Add(n); - } - } - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(stream->Seek(0, STREAM_SEEK_END, &_totalSize)); - RINOK(ReadTables(stream, 0, 0, 0)); - if (_items.IsEmpty()) - return S_FALSE; - UInt32 lbaLimit = _items.Back().Part.GetLimit(); - UInt64 lim = (UInt64)lbaLimit << 9; - if (lim < _totalSize) - { - CItem n; - n.Part.Lba = lbaLimit; - n.Size = _totalSize - lim; - n.IsReal = false; - _items.Add(n); - } - _stream = stream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _items.Clear(); - _stream.Release(); - return S_OK; -} - -enum -{ - kpidPrimary = kpidUserDefined, - kpidBegChs, - kpidEndChs -}; - -static const CStatProp kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidFileSystem, VT_BSTR}, - { NULL, kpidOffset, VT_UI8}, - { "Primary", kpidPrimary, VT_BOOL}, - { "Begin CHS", kpidBegChs, VT_BSTR}, - { "End CHS", kpidEndChs, VT_BSTR} -}; - -IMP_IInArchive_Props_WITH_NAME -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: - { - int mainIndex = -1; - FOR_VECTOR (i, _items) - if (_items[i].IsReal) - { - if (mainIndex >= 0) - { - mainIndex = -1; - break; - } - mainIndex = i; - } - if (mainIndex >= 0) - prop = (UInt32)mainIndex; - break; - } - case kpidPhySize: prop = _totalSize; break; - } - prop.Detach(value); - return S_OK; -} - -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 CItem &item = _items[index]; - const CPartition &part = item.Part; - switch (propID) - { - case kpidPath: - { - AString s; - AddUIntToString(index, s); - if (item.IsReal) - { - int typeIndex = FindPartType(part.Type); - s += '.'; - const char *ext = "img"; - if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Ext) - ext = kPartTypes[(unsigned)typeIndex].Ext; - s += ext; - } - prop = s; - break; - } - case kpidFileSystem: - if (item.IsReal) - { - char s[32]; - ConvertUInt32ToString(part.Type, s); - const char *res = s; - int typeIndex = FindPartType(part.Type); - if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Name) - res = kPartTypes[(unsigned)typeIndex].Name; - prop = res; - } - break; - case kpidSize: - case kpidPackSize: prop = item.Size; break; - case kpidOffset: prop = part.GetPos(); break; - case kpidPrimary: if (item.IsReal) prop = item.IsPrim; break; - case kpidBegChs: if (item.IsReal) part.BeginChs.ToString(prop); break; - case kpidEndChs: if (item.IsReal) part.EndChs.ToString(prop); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - - // 3, { 1, 1, 0 }, - // 2, { 0x55, 0x1FF }, - -REGISTER_ARC_I_NO_SIG( - "MBR", "mbr", 0, 0xDB, - 0, - NArcInfoFlags::kPureStartOpen, - NULL) - -}} +// MbrHandler.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +using namespace NWindows; + +namespace NArchive { + +namespace NFat { +API_FUNC_IsArc IsArc_Fat(const Byte *p, size_t size); +} + +namespace NMbr { + +struct CChs +{ + Byte Head; + Byte SectCyl; + Byte Cyl8; + + UInt32 GetSector() const { return SectCyl & 0x3F; } + UInt32 GetCyl() const { return ((UInt32)SectCyl >> 6 << 8) | Cyl8; } + void ToString(NCOM::CPropVariant &prop) const; + + void Parse(const Byte *p) + { + Head = p[0]; + SectCyl = p[1]; + Cyl8 = p[2]; + } + bool Check() const { return GetSector() > 0; } +}; + + +// Chs in some MBRs contains only low bits of "Cyl number". So we disable check. +/* +#define RINOZ(x) { int _t_ = (x); if (_t_ != 0) return _t_; } +static int CompareChs(const CChs &c1, const CChs &c2) +{ + RINOZ(MyCompare(c1.GetCyl(), c2.GetCyl())); + RINOZ(MyCompare(c1.Head, c2.Head)); + return MyCompare(c1.GetSector(), c2.GetSector()); +} +*/ + +void CChs::ToString(NCOM::CPropVariant &prop) const +{ + AString s; + s.Add_UInt32(GetCyl()); + s.Add_Minus(); + s.Add_UInt32(Head); + s.Add_Minus(); + s.Add_UInt32(GetSector()); + prop = s; +} + +struct CPartition +{ + Byte Status; + CChs BeginChs; + Byte Type; + CChs EndChs; + UInt32 Lba; + UInt32 NumBlocks; + + CPartition() { memset (this, 0, sizeof(*this)); } + + bool IsEmpty() const { return Type == 0; } + bool IsExtended() const { return Type == 5 || Type == 0xF; } + UInt32 GetLimit() const { return Lba + NumBlocks; } + // bool IsActive() const { return Status == 0x80; } + UInt64 GetPos(unsigned sectorSizeLog) const { return (UInt64)Lba << sectorSizeLog; } + UInt64 GetSize(unsigned sectorSizeLog) const { return (UInt64)NumBlocks << sectorSizeLog; } + + bool CheckLbaLimits() const { return (UInt32)0xFFFFFFFF - Lba >= NumBlocks; } + bool Parse(const Byte *p) + { + Status = p[0]; + BeginChs.Parse(p + 1); + Type = p[4]; + EndChs.Parse(p + 5); + Lba = GetUi32(p + 8); + NumBlocks = GetUi32(p + 12); + if (Type == 0) + return true; + if (Status != 0 && Status != 0x80) + return false; + return BeginChs.Check() + && EndChs.Check() + // && CompareChs(BeginChs, EndChs) <= 0 + && NumBlocks > 0 + && CheckLbaLimits(); + } + + #ifdef SHOW_DEBUG_INFO + void Print() const + { + NCOM::CPropVariant prop, prop2; + BeginChs.ToString(prop); + EndChs.ToString(prop2); + printf(" %2x %2x %8X %8X %12S %12S", (int)Status, (int)Type, Lba, NumBlocks, prop.bstrVal, prop2.bstrVal); + } + #endif +}; + +struct CPartType +{ + UInt32 Id; + const char *Ext; + const char *Name; +}; + +#define kFat "fat" + +/* +if we use "format" command in Windows 10 for existing partition: + - if we format to ExFAT, it sets type=7 + - if we format to UDF, it doesn't change type from previous value. +*/ + +static const unsigned kType_Windows_NTFS = 7; + +static const CPartType kPartTypes[] = +{ + { 0x01, kFat, "FAT12" }, + { 0x04, kFat, "FAT16 DOS 3.0+" }, + { 0x05, NULL, "Extended" }, + { 0x06, kFat, "FAT16 DOS 3.31+" }, + { 0x07, "ntfs", "NTFS" }, + { 0x0B, kFat, "FAT32" }, + { 0x0C, kFat, "FAT32-LBA" }, + { 0x0E, kFat, "FAT16-LBA" }, + { 0x0F, NULL, "Extended-LBA" }, + { 0x11, kFat, "FAT12-Hidden" }, + { 0x14, kFat, "FAT16-Hidden < 32 MB" }, + { 0x16, kFat, "FAT16-Hidden >= 32 MB" }, + { 0x1B, kFat, "FAT32-Hidden" }, + { 0x1C, kFat, "FAT32-LBA-Hidden" }, + { 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" }, + { 0x27, "ntfs", "NTFS-WinRE" }, + { 0x82, NULL, "Solaris x86 / Linux swap" }, + { 0x83, NULL, "Linux" }, + { 0x8E, "lvm", "Linux LVM" }, + { 0xA5, NULL, "BSD slice" }, + { 0xBE, NULL, "Solaris 8 boot" }, + { 0xBF, NULL, "New Solaris x86" }, + { 0xC2, NULL, "Linux-Hidden" }, + { 0xC3, NULL, "Linux swap-Hidden" }, + { 0xEE, NULL, "GPT" }, + { 0xEE, NULL, "EFI" } +}; + +static int FindPartType(UInt32 type) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kPartTypes); i++) + if (kPartTypes[i].Id == type) + return (int)i; + return -1; +} + +struct CItem +{ + bool IsReal; + bool IsPrim; + bool WasParsed; + const char *FileSystem; + UInt64 Size; + CPartition Part; + + CItem(): + WasParsed(false), + FileSystem(NULL) + {} +}; + + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + CObjectVector _items; + UInt64 _totalSize; + CByteBuffer _buffer; + + UInt32 _signature; + unsigned _sectorSizeLog; + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override Z7_final + { + const CItem &item = _items[index]; + pos = item.Part.GetPos(_sectorSizeLog); + size = item.Size; + return NExtract::NOperationResult::kOK; + } + + HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level); +}; + +/* +static bool IsEmptyBuffer(const Byte *data, size_t size) +{ + for (unsigned i = 0; i < size; i++) + if (data[i] != 0) + return false; + return true; +} +*/ + +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize); + +HRESULT CHandler::ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level) +{ + if (level >= 128 || _items.Size() >= 128) + return S_FALSE; + + const unsigned kNumHeaderParts = 4; + CPartition parts[kNumHeaderParts]; + + if (level == 0) + _sectorSizeLog = 9; + const UInt32 kSectorSize = (UInt32)1 << _sectorSizeLog; + UInt32 bufSize = kSectorSize; + if (level == 0 && _totalSize >= (1 << 12)) + bufSize = (1 << 12); + _buffer.Alloc(bufSize); + { + Byte *buf = _buffer; + const UInt64 newPos = (UInt64)lba << _sectorSizeLog; + if (newPos + bufSize > _totalSize) + return S_FALSE; + RINOK(InStream_SeekSet(stream, newPos)) + RINOK(ReadStream_FALSE(stream, buf, bufSize)) + if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) + return S_FALSE; + if (level == 0) + _signature = GetUi32(buf + 0x1B8); + for (unsigned i = 0; i < kNumHeaderParts; i++) + if (!parts[i].Parse(buf + 0x1BE + 16 * i)) + return S_FALSE; + } + + // 23.02: now we try to detect 4kn format (4 KB sectors case) + if (level == 0) + // if (_totalSize >= (1 << 28)) // we don't expect small images with 4 KB sectors + if (bufSize >= (1 << 12)) + { + UInt32 lastLim = 0; + UInt32 firstLba = 0; + UInt32 numBlocks = 0; // in first partition + for (unsigned i = 0; i < kNumHeaderParts; i++) + { + const CPartition &part = parts[i]; + if (part.IsEmpty()) + continue; + if (firstLba == 0 && part.NumBlocks != 0) + { + firstLba = part.Lba; + numBlocks = part.NumBlocks; + } + const UInt32 newLim = part.GetLimit(); + if (newLim < lastLim) + return S_FALSE; + lastLim = newLim; + } + if (lastLim != 0) + { + const UInt64 lim12 = (UInt64)lastLim << 12; + if (lim12 <= _totalSize + // && _totalSize - lim12 < (1 << 28) // we can try to exclude false positive cases + ) + // if (IsEmptyBuffer(&_buffer[(1 << 9)], (1 << 12) - (1 << 9))) + if (InStream_SeekSet(stream, (UInt64)firstLba << 12) == S_OK) + if (GetFileSystem(stream, (UInt64)numBlocks << 12)) + _sectorSizeLog = 12; + } + } + + PRF(printf("\n# %8X", lba)); + + UInt32 limLba = lba + 1; + if (limLba == 0) + return S_FALSE; + + for (unsigned i = 0; i < kNumHeaderParts; i++) + { + CPartition &part = parts[i]; + + if (part.IsEmpty()) + continue; + PRF(printf("\n %2d ", (unsigned)level)); + #ifdef SHOW_DEBUG_INFO + part.Print(); + #endif + + unsigned numItems = _items.Size(); + UInt32 newLba = lba + part.Lba; + + if (part.IsExtended()) + { + // if (part.Type == 5) // Check it! + newLba = baseLba + part.Lba; + if (newLba < limLba) + return S_FALSE; + const HRESULT res = ReadTables(stream, level < 1 ? newLba : baseLba, newLba, level + 1); + if (res != S_FALSE && res != S_OK) + return res; + } + if (newLba < limLba) + return S_FALSE; + part.Lba = newLba; + if (!part.CheckLbaLimits()) + return S_FALSE; + + CItem n; + n.Part = part; + bool addItem = false; + if (numItems == _items.Size()) + { + n.IsPrim = (level == 0); + n.IsReal = true; + addItem = true; + } + else + { + const CItem &back = _items.Back(); + const UInt32 backLimit = back.Part.GetLimit(); + const UInt32 partLimit = part.GetLimit(); + if (backLimit < partLimit) + { + n.IsReal = false; + n.Part.Lba = backLimit; + n.Part.NumBlocks = partLimit - backLimit; + addItem = true; + } + } + if (addItem) + { + if (n.Part.GetLimit() < limLba) + return S_FALSE; + limLba = n.Part.GetLimit(); + n.Size = n.Part.GetSize(_sectorSizeLog); + _items.Add(n); + } + } + return S_OK; +} + + +static const Byte k_Ntfs_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; + +static bool Is_Ntfs(const Byte *p) +{ + if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + 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 memcmp(p + 3, k_Ntfs_Signature, Z7_ARRAY_SIZE(k_Ntfs_Signature)) == 0; +} + +static const Byte k_ExFat_Signature[] = { 'E', 'X', 'F', 'A', 'T', ' ', ' ', ' ' }; + +static bool Is_ExFat(const Byte *p) +{ + if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + return false; + if (p[0] != 0xEB || p[1] != 0x76 || p[2] != 0x90) + return false; + return memcmp(p + 3, k_ExFat_Signature, Z7_ARRAY_SIZE(k_ExFat_Signature)) == 0; +} + +static bool AllAreZeros(const Byte *p, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p[i] != 0) + return false; + return true; +} + +static const UInt32 k_Udf_StartPos = 0x8000; +static const Byte k_Udf_Signature[] = { 0, 'B', 'E', 'A', '0', '1', 1, 0 }; + +static bool Is_Udf(const Byte *p) +{ + return memcmp(p + k_Udf_StartPos, k_Udf_Signature, sizeof(k_Udf_Signature)) == 0; +} + + +const char *GetFileSystem(ISequentialInStream *stream, UInt64 partitionSize) +{ + const size_t kHeaderSize = 1 << 9; + if (partitionSize >= kHeaderSize) + { + Byte buf[kHeaderSize]; + if (ReadStream_FAIL(stream, buf, kHeaderSize) == S_OK) + { + // NTFS is expected default filesystem for (Type == 7) + if (Is_Ntfs(buf)) + return "NTFS"; + if (Is_ExFat(buf)) + return "exFAT"; + if (NFat::IsArc_Fat(buf, kHeaderSize)) + return "FAT"; + const size_t kHeaderSize2 = k_Udf_StartPos + (1 << 9); + if (partitionSize >= kHeaderSize2) + { + if (AllAreZeros(buf, kHeaderSize)) + { + CByteBuffer buffer(kHeaderSize2); + // memcpy(buffer, buf, kHeaderSize); + if (ReadStream_FAIL(stream, buffer + kHeaderSize, kHeaderSize2 - kHeaderSize) == S_OK) + if (Is_Udf(buffer)) + return "UDF"; + } + } + } + } + return NULL; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + RINOK(InStream_GetSize_SeekToEnd(stream, _totalSize)) + RINOK(ReadTables(stream, 0, 0, 0)) + if (_items.IsEmpty()) + return S_FALSE; + { + const UInt32 lbaLimit = _items.Back().Part.GetLimit(); + const UInt64 lim = (UInt64)lbaLimit << _sectorSizeLog; + if (lim < _totalSize) + { + CItem n; + n.Part.Lba = lbaLimit; + n.Size = _totalSize - lim; + n.IsReal = false; + _items.Add(n); + } + } + + FOR_VECTOR (i, _items) + { + CItem &item = _items[i]; + if (item.Part.Type != kType_Windows_NTFS) + continue; + if (InStream_SeekSet(stream, item.Part.GetPos(_sectorSizeLog)) != S_OK) + continue; + item.FileSystem = GetFileSystem(stream, item.Size); + item.WasParsed = true; + } + + _stream = stream; + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _items.Clear(); + _stream.Release(); + return S_OK; +} + + +enum +{ + kpidPrimary = kpidUserDefined, + kpidBegChs, + kpidEndChs +}; + +static const CStatProp kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidFileSystem, VT_BSTR}, + { NULL, kpidOffset, VT_UI8}, + { "Primary", kpidPrimary, VT_BOOL}, + { "Begin CHS", kpidBegChs, VT_BSTR}, + { "End CHS", kpidEndChs, VT_BSTR} +}; + +static const Byte kArcProps[] = +{ + kpidSectorSize, + kpidId +}; + +IMP_IInArchive_Props_WITH_NAME +IMP_IInArchive_ArcProps + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: + { + int mainIndex = -1; + FOR_VECTOR (i, _items) + if (_items[i].IsReal) + { + if (mainIndex >= 0) + { + mainIndex = -1; + break; + } + mainIndex = (int)i; + } + if (mainIndex >= 0) + prop = (UInt32)(Int32)mainIndex; + break; + } + case kpidPhySize: prop = _totalSize; break; + case kpidSectorSize: prop = (UInt32)((UInt32)1 << _sectorSizeLog); break; + case kpidId: prop = _signature; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CItem &item = _items[index]; + const CPartition &part = item.Part; + switch (propID) + { + case kpidPath: + { + AString s; + s.Add_UInt32(index); + if (item.IsReal) + { + s.Add_Dot(); + const char *ext = NULL; + if (item.FileSystem) + { + ext = ""; + AString fs (item.FileSystem); + fs.MakeLower_Ascii(); + s += fs; + } + else if (!item.WasParsed) + { + const int typeIndex = FindPartType(part.Type); + if (typeIndex >= 0) + ext = kPartTypes[(unsigned)typeIndex].Ext; + } + if (!ext) + ext = "img"; + s += ext; + } + prop = s; + break; + } + case kpidFileSystem: + if (item.IsReal) + { + char s[32]; + ConvertUInt32ToString(part.Type, s); + const char *res = s; + if (item.FileSystem) + { + // strcat(s, "-"); + // strcpy(s, item.FileSystem); + res = item.FileSystem; + } + else if (!item.WasParsed) + { + const int typeIndex = FindPartType(part.Type); + if (typeIndex >= 0 && kPartTypes[(unsigned)typeIndex].Name) + res = kPartTypes[(unsigned)typeIndex].Name; + } + prop = res; + } + break; + case kpidSize: + case kpidPackSize: prop = item.Size; break; + case kpidOffset: prop = part.GetPos(_sectorSizeLog); break; + case kpidPrimary: if (item.IsReal) prop = item.IsPrim; break; + case kpidBegChs: if (item.IsReal) part.BeginChs.ToString(prop); break; + case kpidEndChs: if (item.IsReal) part.EndChs.ToString(prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + + // 3, { 1, 1, 0 }, + // 2, { 0x55, 0x1FF }, + +REGISTER_ARC_I_NO_SIG( + "MBR", "mbr", NULL, 0xDB, + 0, + NArcInfoFlags::kPureStartOpen, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/MslzHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MslzHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/MslzHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MslzHandler.cpp 2024-01-24 17:00:00.000000000 +0000 @@ -1,397 +1,389 @@ -// MslzHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/InBuffer.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "Common/DummyOutStream.h" - -namespace NArchive { -namespace NMslz { - -static const UInt32 kUnpackSizeMax = 0xFFFFFFE0; - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CMyComPtr _inStream; - CMyComPtr _seqStream; - - bool _isArc; - bool _needSeekToStart; - bool _dataAfterEnd; - bool _needMoreInput; - - bool _packSize_Defined; - bool _unpackSize_Defined; - - UInt32 _unpackSize; - UInt64 _packSize; - UInt64 _originalFileSize; - UString _name; - - void ParseName(Byte replaceByte, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidExtension: prop = "mslz"; break; - case kpidIsNotArcType: prop = true; break; - case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - prop = v; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidPath: if (!_name.IsEmpty()) prop = _name; break; - case kpidSize: if (_unpackSize_Defined || _inStream) prop = _unpackSize; break; - case kpidPackSize: if (_packSize_Defined || _inStream) prop = _packSize; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static const unsigned kSignatureSize = 9; -static const unsigned kHeaderSize = kSignatureSize + 1 + 4; -#define MSLZ_SIGNATURE { 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33, 0x41 } -// old signature: 53 5A 20 88 F0 27 33 -static const Byte kSignature[kSignatureSize] = MSLZ_SIGNATURE; - -// we support only 3 chars strings here -static const char * const g_Exts[] = -{ - "bin" - , "dll" - , "exe" - , "kmd" - , "pdf" - , "sys" -}; - -void CHandler::ParseName(Byte replaceByte, IArchiveOpenCallback *callback) -{ - if (!callback) - return; - CMyComPtr volumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); - if (!volumeCallback) - return; - - NWindows::NCOM::CPropVariant prop; - if (volumeCallback->GetProperty(kpidName, &prop) != S_OK || prop.vt != VT_BSTR) - return; - - UString s = prop.bstrVal; - if (s.IsEmpty() || - s.Back() != L'_') - return; - - s.DeleteBack(); - _name = s; - - if (replaceByte == 0) - { - if (s.Len() < 3 || s[s.Len() - 3] != '.') - return; - for (unsigned i = 0; i < ARRAY_SIZE(g_Exts); i++) - { - const char *ext = g_Exts[i]; - if (s[s.Len() - 2] == (Byte)ext[0] && - s[s.Len() - 1] == (Byte)ext[1]) - { - replaceByte = ext[2]; - break; - } - } - } - - if (replaceByte >= 0x20 && replaceByte < 0x80) - _name += (wchar_t)replaceByte; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - _needSeekToStart = true; - Byte buffer[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize)); - if (memcmp(buffer, kSignature, kSignatureSize) != 0) - return S_FALSE; - _unpackSize = GetUi32(buffer + 10); - if (_unpackSize > kUnpackSizeMax) - return S_FALSE; - RINOK(stream->Seek(0, STREAM_SEEK_END, &_originalFileSize)); - _packSize = _originalFileSize; - - ParseName(buffer[kSignatureSize], callback); - - _isArc = true; - _unpackSize_Defined = true; - _inStream = stream; - _seqStream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _originalFileSize = 0; - _packSize = 0; - _unpackSize = 0; - - _isArc = false; - _needSeekToStart = false; - _dataAfterEnd = false; - _needMoreInput = false; - - _packSize_Defined = false; - _unpackSize_Defined = false; - - _seqStream.Release(); - _inStream.Release(); - _name.Empty(); - return S_OK; -} - -// MslzDec is modified LZSS algorithm of Haruhiko Okumura: -// maxLen = 18; Okumura -// maxLen = 16; MS - -#define PROGRESS_AND_WRITE \ - if ((dest & kMask) == 0) { if (outStream) RINOK(WriteStream(outStream, buf, kBufSize)); \ - if ((dest & ((1 << 20) - 1)) == 0) \ - if (progress) \ - { UInt64 inSize = inStream.GetProcessedSize(); UInt64 outSize = dest; \ - RINOK(progress->SetRatioInfo(&inSize, &outSize)); }} - -static HRESULT MslzDec(CInBuffer &inStream, ISequentialOutStream *outStream, UInt32 unpackSize, bool &needMoreData, ICompressProgressInfo *progress) -{ - const unsigned kBufSize = (1 << 12); - const unsigned kMask = kBufSize - 1; - Byte buf[kBufSize]; - UInt32 dest = 0; - memset(buf, ' ', kBufSize); - - while (dest < unpackSize) - { - Byte b; - if (!inStream.ReadByte(b)) - { - needMoreData = true; - return S_FALSE; - } - - for (unsigned mask = (unsigned)b | 0x100; mask > 1 && dest < unpackSize; mask >>= 1) - { - if (!inStream.ReadByte(b)) - { - needMoreData = true; - return S_FALSE; - } - - if (mask & 1) - { - buf[dest++ & kMask] = b; - PROGRESS_AND_WRITE - } - else - { - Byte b1; - if (!inStream.ReadByte(b1)) - { - needMoreData = true; - return S_FALSE; - } - const unsigned kMaxLen = 16; // 18 in Okumura's code. - unsigned src = (((((unsigned)b1 & 0xF0) << 4) | b) + kMaxLen) & kMask; - unsigned len = (b1 & 0xF) + 3; - if (len > kMaxLen || dest + len > unpackSize) - return S_FALSE; - - do - { - buf[dest++ & kMask] = buf[src++ & kMask]; - PROGRESS_AND_WRITE - } - while (--len != 0); - } - } - } - - if (outStream) - RINOK(WriteStream(outStream, buf, dest & kMask)); - return S_OK; -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - COM_TRY_BEGIN - Close(); - _isArc = true; - _seqStream = stream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - // extractCallback->SetTotal(_unpackSize); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - if (_needSeekToStart) - { - if (!_inStream) - return E_FAIL; - RINOK(_inStream->Seek(0, STREAM_SEEK_SET, NULL)); - } - else - _needSeekToStart = true; - - Int32 opRes = NExtract::NOperationResult::kDataError; - - bool isArc = false; - bool needMoreInput = false; - try - { - CInBuffer s; - if (!s.Create(1 << 20)) - return E_OUTOFMEMORY; - s.SetStream(_seqStream); - s.Init(); - - Byte buffer[kHeaderSize]; - if (s.ReadBytes(buffer, kHeaderSize) == kHeaderSize) - { - UInt32 unpackSize; - if (memcmp(buffer, kSignature, kSignatureSize) == 0) - { - unpackSize = GetUi32(buffer + 10); - if (unpackSize <= kUnpackSizeMax) - { - HRESULT result = MslzDec(s, outStream, unpackSize, needMoreInput, progress); - if (result == S_OK) - opRes = NExtract::NOperationResult::kOK; - else if (result != S_FALSE) - return result; - _unpackSize = unpackSize; - _unpackSize_Defined = true; - - _packSize = s.GetProcessedSize(); - _packSize_Defined = true; - - if (_inStream && _packSize < _originalFileSize) - _dataAfterEnd = true; - - isArc = true; - } - } - } - } - catch (CInBufferException &e) { return e.ErrorCode; } - - _isArc = isArc; - if (isArc) - _needMoreInput = needMoreInput; - if (!_isArc) - opRes = NExtract::NOperationResult::kIsNotArc; - else if (_needMoreInput) - opRes = NExtract::NOperationResult::kUnexpectedEnd; - else if (_dataAfterEnd) - opRes = NExtract::NOperationResult::kDataAfterEnd; - - outStream.Release(); - return extractCallback->SetOperationResult(opRes); - COM_TRY_END -} - -REGISTER_ARC_I( - "MsLZ", "mslz", 0, 0xD5, - kSignature, - 0, - 0, - NULL) - -}} +// MslzHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/InBuffer.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "Common/DummyOutStream.h" + +namespace NArchive { +namespace NMslz { + +static const UInt32 kUnpackSizeMax = 0xFFFFFFE0; + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) + CMyComPtr _inStream; + CMyComPtr _seqStream; + + bool _isArc; + bool _needSeekToStart; + bool _dataAfterEnd; + bool _needMoreInput; + + bool _packSize_Defined; + bool _unpackSize_Defined; + + UInt32 _unpackSize; + UInt64 _packSize; + UInt64 _originalFileSize; + UString _name; + + void ParseName(Byte replaceByte, IArchiveOpenCallback *callback); +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidExtension: prop = "mslz"; break; + case kpidIsNotArcType: prop = true; break; + case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPath: if (!_name.IsEmpty()) prop = _name; break; + case kpidSize: if (_unpackSize_Defined || _inStream) prop = _unpackSize; break; + case kpidPackSize: if (_packSize_Defined || _inStream) prop = _packSize; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static const unsigned kSignatureSize = 9; +static const unsigned kHeaderSize = kSignatureSize + 1 + 4; +#define MSLZ_SIGNATURE { 0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33, 0x41 } +// old signature: 53 5A 20 88 F0 27 33 +static const Byte kSignature[kSignatureSize] = MSLZ_SIGNATURE; + +// we support only 3 chars strings here +static const char * const g_Exts[] = +{ + "bin" + , "dll" + , "exe" + , "kmd" + , "pdf" + , "sys" +}; + +void CHandler::ParseName(Byte replaceByte, IArchiveOpenCallback *callback) +{ + if (!callback) + return; + Z7_DECL_CMyComPtr_QI_FROM(IArchiveOpenVolumeCallback, volumeCallback, callback) + if (!volumeCallback) + return; + + NWindows::NCOM::CPropVariant prop; + if (volumeCallback->GetProperty(kpidName, &prop) != S_OK || prop.vt != VT_BSTR) + return; + + UString s = prop.bstrVal; + if (s.IsEmpty() || + s.Back() != L'_') + return; + + s.DeleteBack(); + _name = s; + + if (replaceByte == 0) + { + if (s.Len() < 3 || s[s.Len() - 3] != '.') + return; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Exts); i++) + { + const char *ext = g_Exts[i]; + if (s[s.Len() - 2] == (Byte)ext[0] && + s[s.Len() - 1] == (Byte)ext[1]) + { + replaceByte = (Byte)ext[2]; + break; + } + } + } + + if (replaceByte >= 0x20 && replaceByte < 0x80) + _name.Add_Char((char)replaceByte); +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + _needSeekToStart = true; + Byte buffer[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, buffer, kHeaderSize)) + if (memcmp(buffer, kSignature, kSignatureSize) != 0) + return S_FALSE; + _unpackSize = GetUi32(buffer + 10); + if (_unpackSize > kUnpackSizeMax) + return S_FALSE; + RINOK(InStream_GetSize_SeekToEnd(stream, _originalFileSize)) + _packSize = _originalFileSize; + + ParseName(buffer[kSignatureSize], callback); + + _isArc = true; + _unpackSize_Defined = true; + _inStream = stream; + _seqStream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _originalFileSize = 0; + _packSize = 0; + _unpackSize = 0; + + _isArc = false; + _needSeekToStart = false; + _dataAfterEnd = false; + _needMoreInput = false; + + _packSize_Defined = false; + _unpackSize_Defined = false; + + _seqStream.Release(); + _inStream.Release(); + _name.Empty(); + return S_OK; +} + +// MslzDec is modified LZSS algorithm of Haruhiko Okumura: +// maxLen = 18; Okumura +// maxLen = 16; MS + +#define PROGRESS_AND_WRITE \ + if ((dest & kMask) == 0) { if (outStream) RINOK(WriteStream(outStream, buf, kBufSize)); \ + if ((dest & ((1 << 20) - 1)) == 0) \ + if (progress) \ + { UInt64 inSize = inStream.GetProcessedSize(); UInt64 outSize = dest; \ + RINOK(progress->SetRatioInfo(&inSize, &outSize)); }} + +static HRESULT MslzDec(CInBuffer &inStream, ISequentialOutStream *outStream, UInt32 unpackSize, bool &needMoreData, ICompressProgressInfo *progress) +{ + const unsigned kBufSize = (1 << 12); + const unsigned kMask = kBufSize - 1; + Byte buf[kBufSize]; + UInt32 dest = 0; + memset(buf, ' ', kBufSize); + + while (dest < unpackSize) + { + Byte b; + if (!inStream.ReadByte(b)) + { + needMoreData = true; + return S_FALSE; + } + + for (unsigned mask = (unsigned)b | 0x100; mask > 1 && dest < unpackSize; mask >>= 1) + { + if (!inStream.ReadByte(b)) + { + needMoreData = true; + return S_FALSE; + } + + if (mask & 1) + { + buf[dest++ & kMask] = b; + PROGRESS_AND_WRITE + } + else + { + Byte b1; + if (!inStream.ReadByte(b1)) + { + needMoreData = true; + return S_FALSE; + } + const unsigned kMaxLen = 16; // 18 in Okumura's code. + unsigned src = (((((unsigned)b1 & 0xF0) << 4) | b) + kMaxLen) & kMask; + unsigned len = (b1 & 0xF) + 3; + if (len > kMaxLen || dest + len > unpackSize) + return S_FALSE; + + do + { + buf[dest++ & kMask] = buf[src++ & kMask]; + PROGRESS_AND_WRITE + } + while (--len != 0); + } + } + } + + if (outStream) + RINOK(WriteStream(outStream, buf, dest & kMask)) + return S_OK; +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + COM_TRY_BEGIN + Close(); + _isArc = true; + _seqStream = stream; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + // RINOK(extractCallback->SetTotal(_unpackSize)) + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + if (_needSeekToStart) + { + if (!_inStream) + return E_FAIL; + RINOK(InStream_SeekToBegin(_inStream)) + } + else + _needSeekToStart = true; + + opRes = NExtract::NOperationResult::kDataError; + + bool isArc = false; + bool needMoreInput = false; + try + { + CInBuffer s; + if (!s.Create(1 << 20)) + return E_OUTOFMEMORY; + s.SetStream(_seqStream); + s.Init(); + + Byte buffer[kHeaderSize]; + if (s.ReadBytes(buffer, kHeaderSize) == kHeaderSize) + { + UInt32 unpackSize; + if (memcmp(buffer, kSignature, kSignatureSize) == 0) + { + unpackSize = GetUi32(buffer + 10); + if (unpackSize <= kUnpackSizeMax) + { + const HRESULT result = MslzDec(s, outStream, unpackSize, needMoreInput, lps); + if (result == S_OK) + opRes = NExtract::NOperationResult::kOK; + else if (result != S_FALSE) + return result; + _unpackSize = unpackSize; + _unpackSize_Defined = true; + + _packSize = s.GetProcessedSize(); + _packSize_Defined = true; + + if (_inStream && _packSize < _originalFileSize) + _dataAfterEnd = true; + + isArc = true; + } + } + } + } + catch (CInBufferException &e) { return e.ErrorCode; } + + _isArc = isArc; + if (isArc) + _needMoreInput = needMoreInput; + if (!_isArc) + opRes = NExtract::NOperationResult::kIsNotArc; + else if (_needMoreInput) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else if (_dataAfterEnd) + opRes = NExtract::NOperationResult::kDataAfterEnd; + } + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +REGISTER_ARC_I( + "MsLZ", "mslz", NULL, 0xD5, + kSignature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/MubHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MubHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/MubHandler.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/MubHandler.cpp 2023-03-15 10:00:00.000000000 +0000 @@ -1,242 +1,262 @@ -// MubHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); } - -using namespace NWindows; -using namespace NCOM; - -namespace NArchive { -namespace NMub { - -#define MACH_CPU_ARCH_ABI64 (1 << 24) -#define MACH_CPU_TYPE_386 7 -#define MACH_CPU_TYPE_ARM 12 -#define MACH_CPU_TYPE_SPARC 14 -#define MACH_CPU_TYPE_PPC 18 - -#define MACH_CPU_TYPE_PPC64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_PPC) -#define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386) - -#define MACH_CPU_SUBTYPE_LIB64 (1 << 31) - -#define MACH_CPU_SUBTYPE_I386_ALL 3 - -struct CItem -{ - UInt32 Type; - UInt32 SubType; - UInt32 Offset; - UInt32 Size; - // UInt32 Align; -}; - -static const UInt32 kNumFilesMax = 10; - -class CHandler: public CHandlerCont -{ - // UInt64 _startPos; - UInt64 _phySize; - UInt32 _numItems; - bool _bigEndian; - CItem _items[kNumFilesMax]; - - HRESULT Open2(IInStream *stream); - - virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const - { - const CItem &item = _items[index]; - pos = item.Offset; - size = item.Size; - return NExtract::NOperationResult::kOK; - } - -public: - INTERFACE_IInArchive_Cont(;) -}; - -static const Byte kArcProps[] = -{ - kpidBigEndian -}; - -static const Byte kProps[] = -{ - kpidSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - PropVariant_Clear(value); - switch (propID) - { - case kpidBigEndian: PropVarEm_Set_Bool(value, _bigEndian); break; - case kpidPhySize: PropVarEm_Set_UInt64(value, _phySize); break; - } - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - PropVariant_Clear(value); - const CItem &item = _items[index]; - switch (propID) - { - case kpidExtension: - { - char temp[32]; - const char *ext = 0; - switch (item.Type) - { - case MACH_CPU_TYPE_386: ext = "x86"; break; - case MACH_CPU_TYPE_ARM: ext = "arm"; break; - case MACH_CPU_TYPE_SPARC: ext = "sparc"; break; - case MACH_CPU_TYPE_PPC: ext = "ppc"; break; - case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break; - case MACH_CPU_TYPE_AMD64: ext = "x64"; break; - default: - temp[0] = 'c'; - temp[1] = 'p'; - temp[2] = 'u'; - ConvertUInt32ToString(item.Type, temp + 3); - break; - } - if (ext) - strcpy(temp, ext); - if (item.SubType != 0 && ( - item.Type != MACH_CPU_TYPE_386 && - item.Type != MACH_CPU_TYPE_AMD64 || - (item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL)) - { - unsigned pos = MyStringLen(temp); - temp[pos++] = '-'; - ConvertUInt32ToString(item.SubType, temp + pos); - } - return PropVarEm_Set_Str(value, temp); - } - case kpidSize: - case kpidPackSize: - PropVarEm_Set_UInt64(value, item.Size); - break; - } - return S_OK; -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_startPos)); - - const UInt32 kHeaderSize = 8; - const UInt32 kRecordSize = 5 * 4; - const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize; - Byte buf[kBufSize]; - size_t processed = kBufSize; - RINOK(ReadStream(stream, buf, &processed)); - if (processed < kHeaderSize) - return S_FALSE; - - bool be; - switch (GetBe32(buf)) - { - case 0xCAFEBABE: be = true; break; - case 0xB9FAF10E: be = false; break; - default: return S_FALSE; - } - _bigEndian = be; - UInt32 num = Get32(buf + 4, be); - if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize) - return S_FALSE; - if (num == 0) - return S_FALSE; - UInt64 endPosMax = kHeaderSize; - - for (UInt32 i = 0; i < num; i++) - { - const Byte *p = buf + kHeaderSize + i * kRecordSize; - CItem &sb = _items[i]; - sb.Type = Get32(p, be); - sb.SubType = Get32(p + 4, be); - sb.Offset = Get32(p + 8, be); - sb.Size = Get32(p + 12, be); - UInt32 align = Get32(p + 16, be); - if (align > 31) - return S_FALSE; - if (sb.Offset < kHeaderSize + num * kRecordSize) - return S_FALSE; - if ((sb.Type & ~MACH_CPU_ARCH_ABI64) >= 0x100 || - (sb.SubType & ~MACH_CPU_SUBTYPE_LIB64) >= 0x100) - return S_FALSE; - - UInt64 endPos = (UInt64)sb.Offset + sb.Size; - if (endPosMax < endPos) - endPosMax = endPos; - } - _numItems = num; - _phySize = endPosMax; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - try - { - if (Open2(inStream) != S_OK) - return S_FALSE; - _stream = inStream; - } - catch(...) { return S_FALSE; } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _stream.Release(); - _numItems = 0; - _phySize = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _numItems; - return S_OK; -} - -namespace NBe { - -static const Byte k_Signature[] = { - 7, 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0, - 4, 0xB9, 0xFA, 0xF1, 0x0E }; - -REGISTER_ARC_I( - "Mub", "mub", 0, 0xE2, - k_Signature, - 0, - NArcInfoFlags::kMultiSignature, - NULL) - -} - -}} +// MubHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/SwapBytes.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +using namespace NWindows; +using namespace NCOM; + +namespace NArchive { +namespace NMub { + +#define MACH_CPU_ARCH_ABI64 ((UInt32)1 << 24) +#define MACH_CPU_TYPE_386 7 +#define MACH_CPU_TYPE_ARM 12 +#define MACH_CPU_TYPE_SPARC 14 +#define MACH_CPU_TYPE_PPC 18 + +#define MACH_CPU_TYPE_PPC64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_PPC) +#define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386) +#define MACH_CPU_TYPE_ARM64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_ARM) + +#define MACH_CPU_SUBTYPE_LIB64 ((UInt32)1 << 31) + +#define MACH_CPU_SUBTYPE_I386_ALL 3 + +struct CItem +{ + UInt32 Type; + UInt32 SubType; + UInt32 Offset; + UInt32 Size; + UInt32 Align; +}; + +static const UInt32 kNumFilesMax = 6; + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + // UInt64 _startPos; + UInt64 _phySize; + UInt32 _numItems; + bool _bigEndian; + CItem _items[kNumFilesMax]; + + HRESULT Open2(IInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override + { + const CItem &item = _items[index]; + pos = item.Offset; + size = item.Size; + return NExtract::NOperationResult::kOK; + } +}; + +static const Byte kArcProps[] = +{ + kpidBigEndian +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidOffset, + kpidClusterSize // Align +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + PropVariant_Clear(value); + switch (propID) + { + case kpidBigEndian: PropVarEm_Set_Bool(value, _bigEndian); break; + case kpidPhySize: PropVarEm_Set_UInt64(value, _phySize); break; + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + PropVariant_Clear(value); + const CItem &item = _items[index]; + switch (propID) + { + case kpidExtension: + { + char temp[32]; + const char *ext = NULL; + switch (item.Type) + { + case MACH_CPU_TYPE_386: ext = "x86"; break; + case MACH_CPU_TYPE_ARM: ext = "arm"; break; + case MACH_CPU_TYPE_SPARC: ext = "sparc"; break; + case MACH_CPU_TYPE_PPC: ext = "ppc"; break; + case MACH_CPU_TYPE_AMD64: ext = "x64"; break; + case MACH_CPU_TYPE_ARM64: ext = "arm64"; break; + case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break; + default: + temp[0] = 'c'; + temp[1] = 'p'; + temp[2] = 'u'; + char *p = ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3); + if (item.Type & MACH_CPU_ARCH_ABI64) + MyStringCopy(p, "_64"); + break; + } + if (ext) + MyStringCopy(temp, ext); + if (item.SubType != 0) + if ((item.Type != MACH_CPU_TYPE_386 && + item.Type != MACH_CPU_TYPE_AMD64) + || (item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL + ) + { + unsigned pos = MyStringLen(temp); + temp[pos++] = '-'; + ConvertUInt32ToString(item.SubType, temp + pos); + } + return PropVarEm_Set_Str(value, temp); + } + case kpidSize: + case kpidPackSize: + PropVarEm_Set_UInt64(value, item.Size); + break; + case kpidOffset: + PropVarEm_Set_UInt64(value, item.Offset); + break; + case kpidClusterSize: + PropVarEm_Set_UInt32(value, (UInt32)1 << item.Align); + break; + } + return S_OK; +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + // RINOK(InStream_GetPos(stream, _startPos)); + + const UInt32 kHeaderSize = 2; + const UInt32 kRecordSize = 5; + const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize; + UInt32 buf[kBufSize]; + size_t processed = kBufSize * 4; + RINOK(ReadStream(stream, buf, &processed)) + processed >>= 2; + if (processed < kHeaderSize) + return S_FALSE; + + bool be; + switch (buf[0]) + { + case Z7_CONV_BE_TO_NATIVE_CONST32(0xCAFEBABE): be = true; break; + case Z7_CONV_BE_TO_NATIVE_CONST32(0xB9FAF10E): be = false; break; + default: return S_FALSE; + } + _bigEndian = be; + if ( + #if defined(MY_CPU_BE) + ! + #endif + be) + z7_SwapBytes4(&buf[1], processed - 1); + const UInt32 num = buf[1]; + if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize) + return S_FALSE; + if (num == 0) + return S_FALSE; + UInt64 endPosMax = kHeaderSize; + + for (UInt32 i = 0; i < num; i++) + { + const UInt32 *p = buf + kHeaderSize + i * kRecordSize; + CItem &sb = _items[i]; + sb.Type = p[0]; + sb.SubType = p[1]; + sb.Offset = p[2]; + sb.Size = p[3]; + const UInt32 align = p[4]; + sb.Align = align; + if (align > 31) + return S_FALSE; + if (sb.Offset < kHeaderSize + num * kRecordSize) + return S_FALSE; + if ((sb.Type & ~MACH_CPU_ARCH_ABI64) >= 0x100 || + (sb.SubType & ~MACH_CPU_SUBTYPE_LIB64) >= 0x100) + return S_FALSE; + + const UInt64 endPos = (UInt64)sb.Offset + sb.Size; + if (endPosMax < endPos) + endPosMax = endPos; + } + _numItems = num; + _phySize = endPosMax; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + try + { + if (Open2(inStream) != S_OK) + return S_FALSE; + _stream = inStream; + } + catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _stream.Release(); + _numItems = 0; + _phySize = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _numItems; + return S_OK; +} + +namespace NBe { + +static const Byte k_Signature[] = { + 7, 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0, + 4, 0xB9, 0xFA, 0xF1, 0x0E }; + +REGISTER_ARC_I( + "Mub", "mub", NULL, 0xE2, + k_Signature, + 0, + NArcInfoFlags::kMultiSignature, + NULL) + +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisDecode.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisDecode.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.cpp 2023-03-22 15:00:00.000000000 +0000 @@ -1,251 +1,295 @@ -// NsisDecode.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "NsisDecode.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/MethodId.h" - -#include "../../Compress/BcjCoder.h" -#include "../../Compress/BZip2Decoder.h" -#include "../../Compress/DeflateDecoder.h" - -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NNsis { - -HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) -{ - useFilter = false; - - if (_decoderInStream) - if (Method != _curMethod) - Release(); - _curMethod = Method; - if (!_codecInStream) - { - switch (Method) - { - // case NMethodType::kCopy: return E_NOTIMPL; - case NMethodType::kDeflate: _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); break; - case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break; - case NMethodType::kLZMA: - _lzmaDecoder = new NCompress::NLzma::CDecoder(); - _codecInStream = _lzmaDecoder; - break; - default: return E_NOTIMPL; - } - } - - if (FilterFlag) - { - Byte flag; - RINOK(ReadStream_FALSE(inStream, &flag, 1)); - if (flag > 1) - return E_NOTIMPL; - useFilter = (flag != 0); - } - - if (!useFilter) - _decoderInStream = _codecInStream; - else - { - if (!_filterInStream) - { - _filter = new CFilterCoder(false); - _filterInStream = _filter; - _filter->Filter = new NCompress::NBcj::CCoder(false); - } - RINOK(_filter->SetInStream(_codecInStream)); - _decoderInStream = _filterInStream; - } - - if (Method == NMethodType::kLZMA) - { - const unsigned kPropsSize = LZMA_PROPS_SIZE; - Byte props[kPropsSize]; - RINOK(ReadStream_FALSE(inStream, props, kPropsSize)); - RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize)); - } - - { - CMyComPtr setInStream; - _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); - if (!setInStream) - return E_NOTIMPL; - RINOK(setInStream->SetInStream(inStream)); - } - - { - CMyComPtr setOutStreamSize; - _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); - if (!setOutStreamSize) - return E_NOTIMPL; - RINOK(setOutStreamSize->SetOutStreamSize(NULL)); - } - - if (useFilter) - { - RINOK(_filter->SetOutStreamSize(NULL)); - } - - return S_OK; -} - -static const UInt32 kMask_IsCompressed = (UInt32)1 << 31; - -HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress) -{ - if (StreamPos > pos) - return E_FAIL; - UInt64 inSizeStart = 0; - if (_lzmaDecoder) - inSizeStart = _lzmaDecoder->GetInputProcessedSize(); - UInt64 offset = 0; - while (StreamPos < pos) - { - size_t size = (size_t)MyMin(pos - StreamPos, (UInt64)Buffer.Size()); - RINOK(Read(Buffer, &size)); - if (size == 0) - return S_FALSE; - StreamPos += size; - offset += size; - - UInt64 inSize = 0; - if (_lzmaDecoder) - inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart; - RINOK(progress->SetRatioInfo(&inSize, &offset)); - } - return S_OK; -} - -HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize, - ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, - UInt32 &packSizeRes, UInt32 &unpackSizeRes) -{ - CLimitedSequentialInStream *limitedStreamSpec = NULL; - CMyComPtr limitedStream; - packSizeRes = 0; - unpackSizeRes = 0; - - if (Solid) - { - Byte temp[4]; - size_t processedSize = 4; - RINOK(Read(temp, &processedSize)); - if (processedSize != 4) - return S_FALSE; - StreamPos += processedSize; - UInt32 size = Get32(temp); - if (unpackSizeDefined && size != unpackSize) - return S_FALSE; - unpackSize = size; - unpackSizeDefined = true; - } - else - { - Byte temp[4]; - RINOK(ReadStream_FALSE(InputStream, temp, 4)); - StreamPos += 4; - UInt32 size = Get32(temp); - - if ((size & kMask_IsCompressed) == 0) - { - if (unpackSizeDefined && size != unpackSize) - return S_FALSE; - packSizeRes = size; - if (outBuf) - outBuf->Alloc(size); - - UInt64 offset = 0; - - while (size > 0) - { - UInt32 curSize = (UInt32)MyMin((size_t)size, Buffer.Size()); - UInt32 processedSize; - RINOK(InputStream->Read(Buffer, curSize, &processedSize)); - if (processedSize == 0) - return S_FALSE; - if (outBuf) - memcpy((Byte *)*outBuf + (size_t)offset, Buffer, processedSize); - offset += processedSize; - size -= processedSize; - StreamPos += processedSize; - unpackSizeRes += processedSize; - if (realOutStream) - RINOK(WriteStream(realOutStream, Buffer, processedSize)); - RINOK(progress->SetRatioInfo(&offset, &offset)); - } - - return S_OK; - } - - size &= ~kMask_IsCompressed; - packSizeRes = size; - limitedStreamSpec = new CLimitedSequentialInStream; - limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(InputStream); - limitedStreamSpec->Init(size); - { - bool useFilter; - RINOK(Init(limitedStream, useFilter)); - } - } - - if (outBuf) - { - if (!unpackSizeDefined) - return S_FALSE; - outBuf->Alloc(unpackSize); - } - - UInt64 inSizeStart = 0; - if (_lzmaDecoder) - inSizeStart = _lzmaDecoder->GetInputProcessedSize(); - - // we don't allow files larger than 4 GB; - if (!unpackSizeDefined) - unpackSize = 0xFFFFFFFF; - UInt32 offset = 0; - - for (;;) - { - size_t rem = unpackSize - offset; - if (rem == 0) - break; - size_t size = Buffer.Size(); - if (size > rem) - size = rem; - RINOK(Read(Buffer, &size)); - if (size == 0) - { - if (unpackSizeDefined) - return S_FALSE; - break; - } - if (outBuf) - memcpy((Byte *)*outBuf + (size_t)offset, Buffer, size); - StreamPos += size; - offset += (UInt32)size; - - UInt64 inSize = 0; // it can be improved: we need inSize for Deflate and BZip2 too. - if (_lzmaDecoder) - inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart; - if (Solid) - packSizeRes = (UInt32)inSize; - unpackSizeRes += (UInt32)size; - - UInt64 outSize = offset; - RINOK(progress->SetRatioInfo(&inSize, &outSize)); - if (realOutStream) - RINOK(WriteStream(realOutStream, Buffer, size)); - } - return S_OK; -} - -}} +// NsisDecode.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "NsisDecode.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/MethodId.h" + +#include "../../Compress/BcjCoder.h" + +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NNsis { + +UInt64 CDecoder::GetInputProcessedSize() const +{ + if (_lzmaDecoder) + return _lzmaDecoder->GetInputProcessedSize(); + if (_deflateDecoder) + return _deflateDecoder->GetInputProcessedSize(); + if (_bzDecoder) + return _bzDecoder->GetInputProcessedSize(); + return 0; +} + + +HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) +{ + useFilter = false; + + if (_decoderInStream) + if (Method != _curMethod) + Release(); + _curMethod = Method; + + if (!_codecInStream) + { + switch ((int)Method) + { + // case NMethodType::kCopy: return E_NOTIMPL; + case NMethodType::kDeflate: + _deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder(); + _codecInStream = _deflateDecoder; + break; + case NMethodType::kBZip2: + _bzDecoder = new NCompress::NBZip2::CNsisDecoder(); + _codecInStream = _bzDecoder; + break; + case NMethodType::kLZMA: + _lzmaDecoder = new NCompress::NLzma::CDecoder(); + _codecInStream = _lzmaDecoder; + break; + default: return E_NOTIMPL; + } + } + + if (Method == NMethodType::kDeflate) + _deflateDecoder->SetNsisMode(IsNsisDeflate); + + if (FilterFlag) + { + Byte flag; + RINOK(ReadStream_FALSE(inStream, &flag, 1)) + if (flag > 1) + return E_NOTIMPL; + useFilter = (flag != 0); + } + + if (!useFilter) + _decoderInStream = _codecInStream; + else + { + if (!_filterInStream) + { + _filter = new CFilterCoder(false); + _filterInStream = _filter; + _filter->Filter = new NCompress::NBcj::CCoder2(z7_BranchConvSt_X86_Dec); + } + RINOK(_filter->SetInStream(_codecInStream)) + _decoderInStream = _filterInStream; + } + + if (Method == NMethodType::kLZMA) + { + const unsigned kPropsSize = LZMA_PROPS_SIZE; + Byte props[kPropsSize]; + RINOK(ReadStream_FALSE(inStream, props, kPropsSize)) + RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize)) + } + + { + CMyComPtr setInStream; + _codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream); + if (!setInStream) + return E_NOTIMPL; + RINOK(setInStream->SetInStream(inStream)) + } + + { + CMyComPtr setOutStreamSize; + _codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); + if (!setOutStreamSize) + return E_NOTIMPL; + RINOK(setOutStreamSize->SetOutStreamSize(NULL)) + } + + if (useFilter) + { + RINOK(_filter->SetOutStreamSize(NULL)) + } + + return S_OK; +} + + +static const UInt32 kMask_IsCompressed = (UInt32)1 << 31; + + +HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress) +{ + if (StreamPos > pos) + return E_FAIL; + const UInt64 inSizeStart = GetInputProcessedSize(); + UInt64 offset = 0; + while (StreamPos < pos) + { + size_t size = (size_t)MyMin(pos - StreamPos, (UInt64)Buffer.Size()); + RINOK(Read(Buffer, &size)) + if (size == 0) + return S_FALSE; + StreamPos += size; + offset += size; + + const UInt64 inSize = GetInputProcessedSize() - inSizeStart; + RINOK(progress->SetRatioInfo(&inSize, &offset)) + } + return S_OK; +} + + +HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize, + ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, + UInt32 &packSizeRes, UInt32 &unpackSizeRes) +{ + CLimitedSequentialInStream *limitedStreamSpec = NULL; + CMyComPtr limitedStream; + packSizeRes = 0; + unpackSizeRes = 0; + + if (Solid) + { + Byte temp[4]; + size_t processedSize = 4; + RINOK(Read(temp, &processedSize)) + StreamPos += processedSize; + if (processedSize != 4) + return S_FALSE; + UInt32 size = Get32(temp); + if (unpackSizeDefined && size != unpackSize) + return S_FALSE; + unpackSize = size; + unpackSizeDefined = true; + } + else + { + Byte temp[4]; + { + size_t processedSize = 4; + RINOK(ReadStream(InputStream, temp, &processedSize)) + StreamPos += processedSize; + if (processedSize != 4) + return S_FALSE; + } + UInt32 size = Get32(temp); + + if ((size & kMask_IsCompressed) == 0) + { + if (unpackSizeDefined && size != unpackSize) + return S_FALSE; + packSizeRes = size; + if (outBuf) + outBuf->Alloc(size); + + UInt64 offset = 0; + + while (size > 0) + { + UInt32 curSize = (UInt32)MyMin((size_t)size, Buffer.Size()); + UInt32 processedSize; + RINOK(InputStream->Read(Buffer, curSize, &processedSize)) + if (processedSize == 0) + return S_FALSE; + if (outBuf) + memcpy((Byte *)*outBuf + (size_t)offset, Buffer, processedSize); + offset += processedSize; + size -= processedSize; + StreamPos += processedSize; + unpackSizeRes += processedSize; + if (realOutStream) + RINOK(WriteStream(realOutStream, Buffer, processedSize)) + RINOK(progress->SetRatioInfo(&offset, &offset)) + } + + return S_OK; + } + + size &= ~kMask_IsCompressed; + packSizeRes = size; + limitedStreamSpec = new CLimitedSequentialInStream; + limitedStream = limitedStreamSpec; + limitedStreamSpec->SetStream(InputStream); + limitedStreamSpec->Init(size); + { + bool useFilter; + RINOK(Init(limitedStream, useFilter)) + } + } + + if (outBuf) + { + if (unpackSizeDefined) + outBuf->Alloc(unpackSize); + } + + const UInt64 inSizeStart = GetInputProcessedSize(); + + // we don't allow files larger than 4 GB; + if (!unpackSizeDefined) + unpackSize = 0xFFFFFFFF; + UInt32 offset = 0; + + HRESULT res = S_OK; + + for (;;) + { + size_t rem = unpackSize - offset; + if (rem == 0) + break; + size_t size = Buffer.Size(); + if (size > rem) + size = rem; + RINOK(Read(Buffer, &size)) + if (size == 0) + { + if (unpackSizeDefined) + res = S_FALSE; + break; + } + + if (outBuf) + { + size_t nextSize = offset + size; + if (outBuf->Size() < nextSize) + { + { + const size_t nextSize2 = outBuf->Size() * 2; + if (nextSize < nextSize2) + nextSize = nextSize2; + } + outBuf->ChangeSize_KeepData(nextSize, offset); + } + memcpy((Byte *)*outBuf + (size_t)offset, Buffer, size); + } + + StreamPos += size; + offset += (UInt32)size; + + const UInt64 inSize = GetInputProcessedSize() - inSizeStart; + + if (Solid) + packSizeRes = (UInt32)inSize; + unpackSizeRes += (UInt32)size; + + UInt64 outSize = offset; + RINOK(progress->SetRatioInfo(&inSize, &outSize)) + if (realOutStream) + { + res = WriteStream(realOutStream, Buffer, size); + if (res != S_OK) + break; + } + } + + if (outBuf && offset != outBuf->Size()) + outBuf->ChangeSize_KeepData(offset, offset); + + return res; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisDecode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.h --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisDecode.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisDecode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,76 +1,97 @@ -// NsisDecode.h - -#ifndef __NSIS_DECODE_H -#define __NSIS_DECODE_H - -#include "../../../Common/MyBuffer.h" - -#include "../../Common/FilterCoder.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/LzmaDecoder.h" - -namespace NArchive { -namespace NNsis { - -namespace NMethodType -{ - enum EEnum - { - kCopy, - kDeflate, - kBZip2, - kLZMA - }; -} - -/* 7-Zip installers 4.38 - 9.08 used modified version of NSIS that - supported BCJ filter for better compression ratio. - We support such modified NSIS archives. */ - -class CDecoder -{ - NMethodType::EEnum _curMethod; // method of created decoder - - CFilterCoder *_filter; - CMyComPtr _filterInStream; - CMyComPtr _codecInStream; - CMyComPtr _decoderInStream; - - NCompress::NLzma::CDecoder *_lzmaDecoder; - -public: - CMyComPtr InputStream; // for non-solid - UInt64 StreamPos; // the pos in unpacked for solid, the pos in Packed for non-solid - - NMethodType::EEnum Method; - bool FilterFlag; - bool Solid; - - CByteBuffer Buffer; // temp buf. - - void Release() - { - _filterInStream.Release(); - _codecInStream.Release(); - _decoderInStream.Release(); - InputStream.Release(); - _lzmaDecoder = NULL; - } - - HRESULT Init(ISequentialInStream *inStream, bool &useFilter); - HRESULT Read(void *data, size_t *processedSize) - { - return ReadStream(_decoderInStream, data, processedSize);; - } - - - HRESULT SetToPos(UInt64 pos, ICompressProgressInfo *progress); // for solid - HRESULT Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize, - ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, - UInt32 &packSizeRes, UInt32 &unpackSizeRes); -}; - -}} - -#endif +// NsisDecode.h + +#ifndef ZIP7_INC_NSIS_DECODE_H +#define ZIP7_INC_NSIS_DECODE_H + +#include "../../../Common/MyBuffer.h" + +#include "../../Common/FilterCoder.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/BZip2Decoder.h" +#include "../../Compress/DeflateDecoder.h" +#include "../../Compress/LzmaDecoder.h" + +namespace NArchive { +namespace NNsis { + +namespace NMethodType +{ + enum EEnum + { + kCopy, + kDeflate, + kBZip2, + kLZMA + }; +} + +/* 7-Zip installers 4.38 - 9.08 used modified version of NSIS that + supported BCJ filter for better compression ratio. + We support such modified NSIS archives. */ + +class CDecoder +{ + NMethodType::EEnum _curMethod; // method of created decoder + + CFilterCoder *_filter; + CMyComPtr _filterInStream; + CMyComPtr _codecInStream; + CMyComPtr _decoderInStream; + + NCompress::NBZip2::CNsisDecoder *_bzDecoder; + NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoder; + NCompress::NLzma::CDecoder *_lzmaDecoder; + +public: + CMyComPtr InputStream; // for non-solid + UInt64 StreamPos; // the pos in unpacked for solid, the pos in Packed for non-solid + + NMethodType::EEnum Method; + bool FilterFlag; + bool Solid; + bool IsNsisDeflate; + + CByteBuffer Buffer; // temp buf + + CDecoder(): + FilterFlag(false), + Solid(true), + IsNsisDeflate(true) + { + _bzDecoder = NULL; + _deflateDecoder = NULL; + _lzmaDecoder = NULL; + } + + void Release() + { + _filterInStream.Release(); + _codecInStream.Release(); + _decoderInStream.Release(); + InputStream.Release(); + + _bzDecoder = NULL; + _deflateDecoder = NULL; + _lzmaDecoder = NULL; + } + + UInt64 GetInputProcessedSize() const; + + HRESULT Init(ISequentialInStream *inStream, bool &useFilter); + + HRESULT Read(void *data, size_t *processedSize) + { + return ReadStream(_decoderInStream, data, processedSize); + } + + + HRESULT SetToPos(UInt64 pos, ICompressProgressInfo *progress); // for solid + HRESULT Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize, + ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, + UInt32 &packSizeRes, UInt32 &unpackSizeRes); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -1,680 +1,693 @@ -// NSisHandler.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../Common/ItemNameUtils.h" - -#include "NsisHandler.h" - -#define Get32(p) GetUi32(p) - -using namespace NWindows; - -namespace NArchive { -namespace NNsis { - -static const char *kBcjMethod = "BCJ"; -static const char *kUnknownMethod = "Unknown"; - -static const char * const kMethods[] = -{ - "Copy" - , "Deflate" - , "BZip2" - , "LZMA" -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidMTime, - kpidAttrib, - kpidMethod, - kpidSolid, - kpidOffset -}; - -static const Byte kArcProps[] = -{ - kpidMethod, - kpidSolid, - kpidHeadersSize, - kpidEmbeddedStubSize, - kpidSubType - // kpidCodePage -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - - -static AString UInt32ToString(UInt32 val) -{ - char s[16]; - ConvertUInt32ToString(val, s); - return s; -} - -static AString GetStringForSizeValue(UInt32 val) -{ - for (int i = 31; i >= 0; i--) - if (((UInt32)1 << i) == val) - return UInt32ToString(i); - char c = 'b'; - if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } - else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } - return UInt32ToString(val) + c; -} - -static AString GetMethod(bool useFilter, NMethodType::EEnum method, UInt32 dict) -{ - AString s; - if (useFilter) - { - s += kBcjMethod; - s.Add_Space(); - } - s += ((unsigned)method < ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod; - if (method == NMethodType::kLZMA) - { - s += ':'; - s += GetStringForSizeValue(dict); - } - return s; -} - -/* -AString CHandler::GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const -{ - AString s; - if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter) - { - s += kBcjMethod; - s.Add_Space(); - } - s += (method < ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod; - if (method == NMethodType::kLZMA) - { - s += ':'; - s += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary); - } - return s; -} -*/ - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - // case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break; - case kpidSubType: - { - AString s = _archive.GetFormatDescription(); - if (!_archive.IsInstaller) - { - s.Add_Space_if_NotEmpty(); - s += "(Uninstall)"; - } - if (!s.IsEmpty()) - prop = s; - break; - } - - case kpidMethod: prop = _methodString; break; - case kpidSolid: prop = _archive.IsSolid; break; - case kpidOffset: prop = _archive.StartOffset; break; - case kpidPhySize: prop = (UInt64)((UInt64)_archive.ExeStub.Size() + _archive.FirstHeader.ArcSize); break; - case kpidEmbeddedStubSize: prop = (UInt64)_archive.ExeStub.Size(); break; - case kpidHeadersSize: prop = _archive.FirstHeader.HeaderSize; break; - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; - if (_archive.IsTruncated()) v |= kpv_ErrorFlags_UnexpectedEnd; - prop = v; - break; - } - - case kpidName: - { - AString s; - - #ifdef NSIS_SCRIPT - if (!_archive.Name.IsEmpty()) - s = _archive.Name; - if (!_archive.IsInstaller) - { - if (!s.IsEmpty()) - s += '.'; - s += "Uninstall"; - } - #endif - - if (s.IsEmpty()) - s = _archive.IsInstaller ? "Install" : "Uninstall"; - s += (_archive.ExeStub.Size() == 0) ? ".nsis" : ".exe"; - - prop = _archive.ConvertToUnicode(s); - break; - } - - #ifdef NSIS_SCRIPT - case kpidShortComment: - { - if (!_archive.BrandingText.IsEmpty()) - prop = _archive.ConvertToUnicode(_archive.BrandingText); - break; - } - #endif - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - { - if (_archive.Open(stream, maxCheckStartPosition) != S_OK) - return S_FALSE; - { - UInt32 dict = _archive.DictionarySize; - if (!_archive.IsSolid) - { - FOR_VECTOR (i, _archive.Items) - { - const CItem &item = _archive.Items[i]; - if (item.DictionarySize > dict) - dict = item.DictionarySize; - } - } - _methodString = GetMethod(_archive.UseFilter, _archive.Method, dict); - } - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _archive.Clear(); - _archive.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _archive.Items.Size() - #ifdef NSIS_SCRIPT - + 1 + _archive.LicenseFiles.Size(); - #endif - ; - return S_OK; -} - -bool CHandler::GetUncompressedSize(unsigned index, UInt32 &size) const -{ - size = 0; - const CItem &item = _archive.Items[index]; - if (item.Size_Defined) - size = item.Size; - else if (_archive.IsSolid && item.EstimatedSize_Defined) - size = item.EstimatedSize; - else - return false; - return true; -} - -bool CHandler::GetCompressedSize(unsigned index, UInt32 &size) const -{ - size = 0; - const CItem &item = _archive.Items[index]; - if (item.CompressedSize_Defined) - size = item.CompressedSize; - else - { - if (_archive.IsSolid) - { - if (index == 0) - size = _archive.FirstHeader.GetDataSize(); - else - return false; - } - else - { - if (!item.IsCompressed) - size = item.Size; - else - return false; - } - } - return true; -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - #ifdef NSIS_SCRIPT - if (index >= (UInt32)_archive.Items.Size()) - { - if (index == (UInt32)_archive.Items.Size()) - { - switch (propID) - { - case kpidPath: prop = "[NSIS].nsi"; break; - case kpidSize: - case kpidPackSize: prop = (UInt64)_archive.Script.Len(); break; - case kpidSolid: prop = false; break; - } - } - else - { - const CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)]; - switch (propID) - { - case kpidPath: prop = lic.Name; break; - case kpidSize: - case kpidPackSize: prop = (UInt64)lic.Size; break; - case kpidSolid: prop = false; break; - } - } - } - else - #endif - { - const CItem &item = _archive.Items[index]; - switch (propID) - { - case kpidOffset: prop = item.Pos; break; - case kpidPath: - { - UString s = NItemName::WinNameToOSName(_archive.GetReducedName(index)); - if (!s.IsEmpty()) - prop = (const wchar_t *)s; - break; - } - case kpidSize: - { - UInt32 size; - if (GetUncompressedSize(index, size)) - prop = (UInt64)size; - break; - } - case kpidPackSize: - { - UInt32 size; - if (GetCompressedSize(index, size)) - prop = (UInt64)size; - break; - } - case kpidMTime: - { - if (item.MTime.dwHighDateTime > 0x01000000 && - item.MTime.dwHighDateTime < 0xFF000000) - prop = item.MTime; - break; - } - case kpidAttrib: - { - if (item.Attrib_Defined) - prop = item.Attrib; - break; - } - - case kpidMethod: - if (_archive.IsSolid) - prop = _methodString; - else - prop = GetMethod(_archive.UseFilter, item.IsCompressed ? _archive.Method : - NMethodType::kCopy, item.DictionarySize); - break; - - case kpidSolid: prop = _archive.IsSolid; break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -static bool UninstallerPatch(const Byte *p, size_t size, CByteBuffer &dest) -{ - for (;;) - { - if (size < 4) - return false; - UInt32 len = Get32(p); - if (len == 0) - return size == 4; - if (size < 8) - return false; - UInt32 offs = Get32(p + 4); - p += 8; - size -= 8; - if (size < len || offs > dest.Size() || len > dest.Size() - offs) - return false; - memcpy(dest + offs, p, len); - p += len; - size -= len; - } -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - GetNumberOfItems(&numItems); - if (numItems == 0) - return S_OK; - - UInt64 totalSize = 0; - UInt64 solidPosMax = 0; - - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt32 index = (allFilesMode ? i : indices[i]); - - #ifdef NSIS_SCRIPT - if (index >= _archive.Items.Size()) - { - if (index == _archive.Items.Size()) - totalSize += _archive.Script.Len(); - else - totalSize += _archive.LicenseFiles[index - (_archive.Items.Size() + 1)].Size; - } - else - #endif - { - UInt32 size; - if (_archive.IsSolid) - { - GetUncompressedSize(index, size); - UInt64 pos = (UInt64)_archive.GetPosOfSolidItem(index) + size; - if (solidPosMax < pos) - solidPosMax = pos; - } - else - { - GetCompressedSize(index, size); - totalSize += size; - } - } - } - - extractCallback->SetTotal(totalSize + solidPosMax); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, !_archive.IsSolid); - - if (_archive.IsSolid) - { - RINOK(_archive.SeekTo_DataStreamOffset()); - RINOK(_archive.InitDecoder()); - _archive.Decoder.StreamPos = 0; - } - - /* We use tempBuf for solid archives, if there is duplicate item. - We don't know uncompressed size for non-solid archives, so we can't - allocate exact buffer. - We use tempBuf also for first part (EXE stub) of unistall.exe - and tempBuf2 is used for second part (NSIS script). */ - - CByteBuffer tempBuf; - CByteBuffer tempBuf2; - - /* tempPos is pos in uncompressed stream of previous item for solid archive, that - was written to tempBuf */ - UInt64 tempPos = (UInt64)(Int64)-1; - - /* prevPos is pos in uncompressed stream of previous item for solid archive. - It's used for test mode (where we don't need to test same file second time */ - UInt64 prevPos = (UInt64)(Int64)-1; - - // if there is error in solid archive, we show error for all subsequent files - bool solidDataError = false; - - UInt64 curTotalPacked = 0, curTotalUnpacked = 0; - UInt32 curPacked = 0; - UInt64 curUnpacked = 0; - - for (i = 0; i < numItems; i++, - curTotalPacked += curPacked, - curTotalUnpacked += curUnpacked) - { - lps->InSize = curTotalPacked; - lps->OutSize = curTotalUnpacked; - if (_archive.IsSolid) - lps->OutSize += _archive.Decoder.StreamPos; - - curPacked = 0; - curUnpacked = 0; - RINOK(lps->SetCur()); - - // RINOK(extractCallback->SetCompleted(¤tTotalSize)); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - bool dataError = false; - - #ifdef NSIS_SCRIPT - if (index >= (UInt32)_archive.Items.Size()) - { - const void *data; - size_t size; - if (index == (UInt32)_archive.Items.Size()) - { - data = (const Byte *)_archive.Script; - size = _archive.Script.Len(); - } - else - { - CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)]; - if (lic.Text.Size() != 0) - data = lic.Text; - else - data = _archive._data + lic.Offset; - size = lic.Size; - } - curUnpacked = size; - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (realOutStream) - RINOK(WriteStream(realOutStream, data, size)); - } - else - #endif - { - const CItem &item = _archive.Items[index]; - - if (!_archive.IsSolid) - GetCompressedSize(index, curPacked); - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - - dataError = solidDataError; - - bool needDecompress = !solidDataError; - if (needDecompress) - { - if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos) - needDecompress = false; - } - - if (needDecompress) - { - bool writeToTemp = false; - bool readFromTemp = false; - - if (!_archive.IsSolid) - { - RINOK(_archive.SeekToNonSolidItem(index)); - } - else - { - UInt64 pos = _archive.GetPosOfSolidItem(index); - if (pos < _archive.Decoder.StreamPos) - { - if (pos != tempPos) - solidDataError = dataError = true; - readFromTemp = true; - } - else - { - HRESULT res = _archive.Decoder.SetToPos(pos, progress); - if (res != S_OK) - { - if (res != S_FALSE) - return res; - solidDataError = dataError = true; - } - else if (!testMode && i + 1 < numItems) - { - UInt32 next = allFilesMode ? i + 1 : indices[i + 1]; - if (next < _archive.Items.Size()) - { - UInt64 nextPos = _archive.GetPosOfSolidItem(next); - if (nextPos == pos) - { - writeToTemp = true; - tempPos = pos; - } - } - } - } - prevPos = pos; - } - - if (!dataError) - { - // UInt32 unpackSize = 0; - // bool unpackSize_Defined = false; - bool writeToTemp1 = writeToTemp; - if (item.IsUninstaller) - { - // unpackSize = item.PatchSize; - // unpackSize_Defined = true; - if (!readFromTemp) - writeToTemp = true; - writeToTemp1 = writeToTemp; - if (_archive.ExeStub.Size() == 0) - { - if (writeToTemp1 && !readFromTemp) - tempBuf.Free(); - writeToTemp1 = false; - } - } - - if (readFromTemp) - { - if (realOutStream && !item.IsUninstaller) - RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size())); - } - else - { - UInt32 curUnpacked32 = 0; - HRESULT res = _archive.Decoder.Decode( - writeToTemp1 ? &tempBuf : NULL, - item.IsUninstaller, item.PatchSize, - item.IsUninstaller ? NULL : (ISequentialOutStream *)realOutStream, - progress, - curPacked, curUnpacked32); - curUnpacked = curUnpacked32; - if (_archive.IsSolid) - curUnpacked = 0; - if (res != S_OK) - { - if (res != S_FALSE) - return res; - dataError = true; - if (_archive.IsSolid) - solidDataError = true; - } - } - } - - if (!dataError && item.IsUninstaller) - { - if (_archive.ExeStub.Size() != 0) - { - CByteBuffer destBuf = _archive.ExeStub; - dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf); - - if (realOutStream) - RINOK(WriteStream(realOutStream, destBuf, destBuf.Size())); - } - - if (readFromTemp) - { - if (realOutStream) - RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size())); - } - else - { - UInt32 curPacked2 = 0; - UInt32 curUnpacked2 = 0; - HRESULT res = _archive.Decoder.Decode( - writeToTemp ? &tempBuf2 : NULL, - false, 0, - realOutStream, - progress, - curPacked2, curUnpacked2); - curPacked += curPacked2; - if (!_archive.IsSolid) - curUnpacked += curUnpacked2; - if (res != S_OK) - { - if (res != S_FALSE) - return res; - dataError = true; - if (_archive.IsSolid) - solidDataError = true; - } - } - } - } - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(dataError ? - NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kOK)); - } - return S_OK; - COM_TRY_END -} - -}} +// NSisHandler.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "../Common/ItemNameUtils.h" + +#include "NsisHandler.h" + +#define Get32(p) GetUi32(p) + +using namespace NWindows; + +namespace NArchive { +namespace NNsis { + +#define kBcjMethod "BCJ" +#define kUnknownMethod "Unknown" + +static const char * const kMethods[] = +{ + "Copy" + , "Deflate" + , "BZip2" + , "LZMA" +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidMTime, + kpidAttrib, + kpidMethod, + kpidSolid, + kpidOffset +}; + +static const Byte kArcProps[] = +{ + kpidMethod, + kpidSolid, + kpidBit64, + kpidHeadersSize, + kpidEmbeddedStubSize, + kpidSubType + // kpidCodePage +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +static void AddDictProp(AString &s, UInt32 val) +{ + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == val) + { + s.Add_UInt32(i); + return; + } + char c = 'b'; + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + s.Add_UInt32(val); + s.Add_Char(c); +} + +static AString GetMethod(bool useFilter, NMethodType::EEnum method, UInt32 dict) +{ + AString s; + if (useFilter) + { + s += kBcjMethod; + s.Add_Space(); + } + s += ((unsigned)method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod; + if (method == NMethodType::kLZMA) + { + s.Add_Colon(); + AddDictProp(s, dict); + } + return s; +} + +/* +AString CHandler::GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const +{ + AString s; + if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter) + { + s += kBcjMethod; + s.Add_Space(); + } + s += (method < Z7_ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod; + if (method == NMethodType::kLZMA) + { + s.Add_Colon(); + s += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary); + } + return s; +} +*/ + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + // case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break; + case kpidSubType: + { + AString s (_archive.GetFormatDescription()); + if (!_archive.IsInstaller) + { + s.Add_Space_if_NotEmpty(); + s += "(Uninstall)"; + } + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidBit64: if (_archive.Is64Bit) prop = true; break; + case kpidMethod: prop = _methodString; break; + case kpidSolid: prop = _archive.IsSolid; break; + case kpidOffset: prop = _archive.StartOffset; break; + case kpidPhySize: prop = (UInt64)((UInt64)_archive.ExeStub.Size() + _archive.FirstHeader.ArcSize); break; + case kpidEmbeddedStubSize: prop = (UInt64)_archive.ExeStub.Size(); break; + case kpidHeadersSize: prop = _archive.FirstHeader.HeaderSize; break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (_archive.IsTruncated()) v |= kpv_ErrorFlags_UnexpectedEnd; + prop = v; + break; + } + + case kpidName: + { + AString s; + + #ifdef NSIS_SCRIPT + if (!_archive.Name.IsEmpty()) + s = _archive.Name; + if (!_archive.IsInstaller) + { + if (!s.IsEmpty()) + s.Add_Dot(); + s += "Uninstall"; + } + #endif + + if (s.IsEmpty()) + s = _archive.IsInstaller ? "Install" : "Uninstall"; + s += (_archive.ExeStub.Size() == 0) ? ".nsis" : ".exe"; + + prop = _archive.ConvertToUnicode(s); + break; + } + + #ifdef NSIS_SCRIPT + case kpidShortComment: + { + if (!_archive.BrandingText.IsEmpty()) + prop = _archive.ConvertToUnicode(_archive.BrandingText); + break; + } + #endif + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + { + if (_archive.Open(stream, maxCheckStartPosition) != S_OK) + return S_FALSE; + { + UInt32 dict = _archive.DictionarySize; + if (!_archive.IsSolid) + { + FOR_VECTOR (i, _archive.Items) + { + const CItem &item = _archive.Items[i]; + if (item.DictionarySize > dict) + dict = item.DictionarySize; + } + } + _methodString = GetMethod(_archive.UseFilter, _archive.Method, dict); + } + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _archive.Clear(); + _archive.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _archive.Items.Size() + #ifdef NSIS_SCRIPT + + 1 + _archive.LicenseFiles.Size() + #endif + ; + return S_OK; +} + +bool CHandler::GetUncompressedSize(unsigned index, UInt32 &size) const +{ + size = 0; + const CItem &item = _archive.Items[index]; + if (item.Size_Defined) + size = item.Size; + else if (_archive.IsSolid && item.EstimatedSize_Defined) + size = item.EstimatedSize; + else if (!item.IsEmptyFile) + return false; + return true; +} + +bool CHandler::GetCompressedSize(unsigned index, UInt32 &size) const +{ + size = 0; + const CItem &item = _archive.Items[index]; + if (item.CompressedSize_Defined) + size = item.CompressedSize; + else + { + if (_archive.IsSolid) + { + if (index == 0) + size = _archive.FirstHeader.GetDataSize(); + else + return false; + } + else + { + if (!item.IsCompressed) + size = item.Size; + else + return false; + } + } + return true; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + #ifdef NSIS_SCRIPT + if (index >= (UInt32)_archive.Items.Size()) + { + if (index == (UInt32)_archive.Items.Size()) + { + switch (propID) + { + case kpidPath: prop = "[NSIS].nsi"; break; + case kpidSize: + case kpidPackSize: prop = (UInt64)_archive.Script.Len(); break; + case kpidSolid: prop = false; break; + } + } + else + { + const CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)]; + switch (propID) + { + case kpidPath: prop = lic.Name; break; + case kpidSize: + case kpidPackSize: prop = (UInt64)lic.Size; break; + case kpidSolid: prop = false; break; + } + } + } + else + #endif + { + const CItem &item = _archive.Items[index]; + switch (propID) + { + case kpidOffset: prop = item.Pos; break; + case kpidPath: + { + UString s = NItemName::WinPathToOsPath(_archive.GetReducedName(index)); + if (!s.IsEmpty()) + prop = (const wchar_t *)s; + break; + } + case kpidSize: + { + UInt32 size; + if (GetUncompressedSize(index, size)) + prop = (UInt64)size; + break; + } + case kpidPackSize: + { + UInt32 size; + if (GetCompressedSize(index, size)) + prop = (UInt64)size; + break; + } + case kpidMTime: + { + if (item.MTime.dwHighDateTime > 0x01000000 && + item.MTime.dwHighDateTime < 0xFF000000) + prop = item.MTime; + break; + } + case kpidAttrib: + { + if (item.Attrib_Defined) + prop = item.Attrib; + break; + } + + case kpidMethod: + if (_archive.IsSolid) + prop = _methodString; + else + prop = GetMethod(_archive.UseFilter, item.IsCompressed ? _archive.Method : + NMethodType::kCopy, item.DictionarySize); + break; + + case kpidSolid: prop = _archive.IsSolid; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +static bool UninstallerPatch(const Byte *p, size_t size, Byte *dest, size_t destSize) +{ + for (;;) + { + if (size < 4) + return false; + const UInt32 len = Get32(p); + if (len == 0) + return size == 4; + if (size < 8) + return false; + const UInt32 offs = Get32(p + 4); + p += 8; + size -= 8; + if (size < len || offs > destSize || len > destSize - offs) + return false; + memcpy(dest + offs, p, len); + p += len; + size -= len; + } +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + GetNumberOfItems(&numItems); + if (numItems == 0) + return S_OK; + + UInt64 totalSize = 0; + UInt64 solidPosMax = 0; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + const UInt32 index = (allFilesMode ? i : indices[i]); + + #ifdef NSIS_SCRIPT + if (index >= _archive.Items.Size()) + { + if (index == _archive.Items.Size()) + totalSize += _archive.Script.Len(); + else + totalSize += _archive.LicenseFiles[index - (_archive.Items.Size() + 1)].Size; + } + else + #endif + { + UInt32 size; + if (_archive.IsSolid) + { + GetUncompressedSize(index, size); + UInt64 pos = (UInt64)_archive.GetPosOfSolidItem(index) + size; + if (solidPosMax < pos) + solidPosMax = pos; + } + else + { + GetCompressedSize(index, size); + totalSize += size; + } + } + } + + extractCallback->SetTotal(totalSize + solidPosMax); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, !_archive.IsSolid); + + if (_archive.IsSolid) + { + RINOK(_archive.SeekTo_DataStreamOffset()) + RINOK(_archive.InitDecoder()) + _archive.Decoder.StreamPos = 0; + } + + /* We use tempBuf for solid archives, if there is duplicate item. + We don't know uncompressed size for non-solid archives, so we can't + allocate exact buffer. + We use tempBuf also for first part (EXE stub) of unistall.exe + and tempBuf2 is used for second part (NSIS script). */ + + CByteBuffer tempBuf; + CByteBuffer tempBuf2; + + /* tempPos is pos in uncompressed stream of previous item for solid archive, that + was written to tempBuf */ + UInt64 tempPos = (UInt64)(Int64)-1; + + /* prevPos is pos in uncompressed stream of previous item for solid archive. + It's used for test mode (where we don't need to test same file second time */ + UInt64 prevPos = (UInt64)(Int64)-1; + + // if there is error in solid archive, we show error for all subsequent files + bool solidDataError = false; + + UInt64 curTotalPacked = 0, curTotalUnpacked = 0; + UInt32 curPacked = 0; + UInt64 curUnpacked = 0; + + for (i = 0; i < numItems; i++, + curTotalPacked += curPacked, + curTotalUnpacked += curUnpacked) + { + lps->InSize = curTotalPacked; + lps->OutSize = curTotalUnpacked; + if (_archive.IsSolid) + lps->OutSize += _archive.Decoder.StreamPos; + + curPacked = 0; + curUnpacked = 0; + RINOK(lps->SetCur()) + + // RINOK(extractCallback->SetCompleted(¤tTotalSize)) + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + bool dataError = false; + + #ifdef NSIS_SCRIPT + if (index >= (UInt32)_archive.Items.Size()) + { + const void *data; + size_t size; + if (index == (UInt32)_archive.Items.Size()) + { + data = (const Byte *)_archive.Script; + size = _archive.Script.Len(); + } + else + { + CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)]; + if (lic.Text.Size() != 0) + data = lic.Text; + else + data = _archive._data + lic.Offset; + size = lic.Size; + } + curUnpacked = size; + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (realOutStream) + RINOK(WriteStream(realOutStream, data, size)) + } + else + #endif + { + const CItem &item = _archive.Items[index]; + + if (!_archive.IsSolid) + GetCompressedSize(index, curPacked); + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + + dataError = solidDataError; + + bool needDecompress = false; + + if (!item.IsEmptyFile) + { + needDecompress = !solidDataError; + if (needDecompress) + { + if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos) + needDecompress = false; + } + } + + if (needDecompress) + { + bool writeToTemp = false; + bool readFromTemp = false; + + if (!_archive.IsSolid) + { + RINOK(_archive.SeekToNonSolidItem(index)) + } + else + { + UInt64 pos = _archive.GetPosOfSolidItem(index); + if (pos < _archive.Decoder.StreamPos) + { + if (pos != tempPos) + solidDataError = dataError = true; + readFromTemp = true; + } + else + { + HRESULT res = _archive.Decoder.SetToPos(pos, lps); + if (res != S_OK) + { + if (res != S_FALSE) + return res; + solidDataError = dataError = true; + } + else if (!testMode && i + 1 < numItems) + { + const UInt32 next = allFilesMode ? i + 1 : indices[i + 1]; + if (next < _archive.Items.Size()) + { + // next cannot be IsEmptyFile + const UInt64 nextPos = _archive.GetPosOfSolidItem(next); + if (nextPos == pos) + { + writeToTemp = true; + tempPos = pos; + } + } + } + } + prevPos = pos; + } + + /* nsis 3.08 can use (PatchSize == 0) for uninstaller without patched section */ + + const bool is_PatchedUninstaller = item.Is_PatchedUninstaller(); + + if (!dataError) + { + // UInt32 unpackSize = 0; + // bool unpackSize_Defined = false; + bool writeToTemp1 = writeToTemp; + if (is_PatchedUninstaller) + { + // unpackSize = item.PatchSize; + // unpackSize_Defined = true; + if (!readFromTemp) + writeToTemp = true; + writeToTemp1 = writeToTemp; + if (_archive.ExeStub.Size() == 0) + { + if (writeToTemp1 && !readFromTemp) + tempBuf.Free(); + writeToTemp1 = false; + } + } + + if (readFromTemp) + { + if (realOutStream && !is_PatchedUninstaller) + RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size())) + } + else + { + UInt32 curUnpacked32 = 0; + const HRESULT res = _archive.Decoder.Decode( + writeToTemp1 ? &tempBuf : NULL, + is_PatchedUninstaller, item.PatchSize, + is_PatchedUninstaller ? NULL : (ISequentialOutStream *)realOutStream, + lps, + curPacked, curUnpacked32); + curUnpacked = curUnpacked32; + if (_archive.IsSolid) + curUnpacked = 0; + if (res != S_OK) + { + if (res != S_FALSE) + return res; + dataError = true; + if (_archive.IsSolid) + solidDataError = true; + } + } + } + + if (!dataError && is_PatchedUninstaller) + { + if (_archive.ExeStub.Size() != 0) + { + CByteBuffer destBuf = _archive.ExeStub; + dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf, destBuf.Size()); + if (realOutStream) + RINOK(WriteStream(realOutStream, destBuf, destBuf.Size())) + } + + if (readFromTemp) + { + if (realOutStream) + RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size())) + } + else + { + UInt32 curPacked2 = 0; + UInt32 curUnpacked2 = 0; + + if (!_archive.IsSolid) + { + RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked )) + } + + const HRESULT res = _archive.Decoder.Decode( + writeToTemp ? &tempBuf2 : NULL, + false, 0, + realOutStream, + lps, + curPacked2, curUnpacked2); + curPacked += curPacked2; + if (!_archive.IsSolid) + curUnpacked += curUnpacked2; + if (res != S_OK) + { + if (res != S_FALSE) + return res; + dataError = true; + if (_archive.IsSolid) + solidDataError = true; + } + } + } + } + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(dataError ? + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kOK)) + } + return S_OK; + COM_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisHandler.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,36 +1,30 @@ -// NSisHandler.h - -#ifndef __NSIS_HANDLER_H -#define __NSIS_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../../Common/CreateCoder.h" - -#include "../IArchive.h" - -#include "NsisIn.h" - -namespace NArchive { -namespace NNsis { - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CInArchive _archive; - AString _methodString; - - bool GetUncompressedSize(unsigned index, UInt32 &size) const; - bool GetCompressedSize(unsigned index, UInt32 &size) const; - - // AString GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const; -public: - MY_UNKNOWN_IMP1(IInArchive) - - INTERFACE_IInArchive(;) -}; - -}} - -#endif +// NSisHandler.h + +#ifndef ZIP7_INC_NSIS_HANDLER_H +#define ZIP7_INC_NSIS_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../../Common/CreateCoder.h" + +#include "../IArchive.h" + +#include "NsisIn.h" + +namespace NArchive { +namespace NNsis { + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CInArchive _archive; + AString _methodString; + + bool GetUncompressedSize(unsigned index, UInt32 &size) const; + bool GetCompressedSize(unsigned index, UInt32 &size) const; + + // AString GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisIn.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -1,5898 +1,6138 @@ -// NsisIn.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringToInt.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/StreamUtils.h" - -#include "NsisIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -// #define NUM_SPEED_TESTS 1000 - -namespace NArchive { -namespace NNsis { - -static const size_t kInputBufSize = 1 << 20; - -const Byte kSignature[kSignatureSize] = NSIS_SIGNATURE; -static const UInt32 kMask_IsCompressed = (UInt32)1 << 31; - -static const unsigned kNumCommandParams = 6; -static const unsigned kCmdSize = 4 + kNumCommandParams * 4; - -#ifdef NSIS_SCRIPT -#define CR_LF "\x0D\x0A" -#endif - -static const char * const kErrorStr = "$_ERROR_STR_"; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - - -/* There are several versions of NSIS: - 1) Original NSIS: - NSIS-2 ANSI - NSIS-3 ANSI - NSIS-3 Unicode - 2) NSIS from Jim Park that extends old NSIS-2 to Unicode support: - NSIS-Park-(1,2,3) ANSI - NSIS-Park-(1,2,3) Unicode - - The command IDs layout is slightly different for different versions. - Also there are additional "log" versions of NSIS that support EW_LOG. - We use the layout of "NSIS-3 Unicode" without "log" as main layout. - And we transfer the command IDs to main layout, if another layout is detected. */ - - -enum -{ - EW_INVALID_OPCODE, - EW_RET, // Return - EW_NOP, // Nop, Goto - EW_ABORT, // Abort - EW_QUIT, // Quit - EW_CALL, // Call, InitPluginsDir - EW_UPDATETEXT, // DetailPrint - EW_SLEEP, // Sleep - EW_BRINGTOFRONT, // BringToFront - EW_CHDETAILSVIEW, // SetDetailsView - EW_SETFILEATTRIBUTES, // SetFileAttributes - EW_CREATEDIR, // CreateDirectory, SetOutPath - EW_IFFILEEXISTS, // IfFileExists - EW_SETFLAG, // SetRebootFlag, ... - EW_IFFLAG, // IfAbort, IfSilent, IfErrors, IfRebootFlag - EW_GETFLAG, // GetInstDirError, GetErrorLevel - EW_RENAME, // Rename - EW_GETFULLPATHNAME, // GetFullPathName - EW_SEARCHPATH, // SearchPath - EW_GETTEMPFILENAME, // GetTempFileName - EW_EXTRACTFILE, // File - EW_DELETEFILE, // Delete - EW_MESSAGEBOX, // MessageBox - EW_RMDIR, // RMDir - EW_STRLEN, // StrLen - EW_ASSIGNVAR, // StrCpy - EW_STRCMP, // StrCmp - EW_READENVSTR, // ReadEnvStr, ExpandEnvStrings - EW_INTCMP, // IntCmp, IntCmpU - EW_INTOP, // IntOp - EW_INTFMT, // IntFmt - EW_PUSHPOP, // Push/Pop/Exchange - EW_FINDWINDOW, // FindWindow - EW_SENDMESSAGE, // SendMessage - EW_ISWINDOW, // IsWindow - EW_GETDLGITEM, // GetDlgItem - EW_SETCTLCOLORS, // SetCtlColors - EW_SETBRANDINGIMAGE, // SetBrandingImage - EW_CREATEFONT, // CreateFont - EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow - EW_SHELLEXEC, // ExecShell - EW_EXECUTE, // Exec, ExecWait - EW_GETFILETIME, // GetFileTime - EW_GETDLLVERSION, // GetDLLVersion - - // EW_GETFONTVERSION, // Park : 2.46.2 - // EW_GETFONTNAME, // Park : 2.46.3 - - EW_REGISTERDLL, // RegDLL, UnRegDLL, CallInstDLL - EW_CREATESHORTCUT, // CreateShortCut - EW_COPYFILES, // CopyFiles - EW_REBOOT, // Reboot - EW_WRITEINI, // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI - EW_READINISTR, // ReadINIStr - EW_DELREG, // DeleteRegValue, DeleteRegKey - EW_WRITEREG, // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD - EW_READREGSTR, // ReadRegStr, ReadRegDWORD - EW_REGENUM, // EnumRegKey, EnumRegValue - EW_FCLOSE, // FileClose - EW_FOPEN, // FileOpen - EW_FPUTS, // FileWrite, FileWriteByte - EW_FGETS, // FileRead, FileReadByte - - // Park - // EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord - // EW_FGETWS, // FileReadUTF16LE, FileReadWord - - EW_FSEEK, // FileSeek - EW_FINDCLOSE, // FindClose - EW_FINDNEXT, // FindNext - EW_FINDFIRST, // FindFirst - EW_WRITEUNINSTALLER, // WriteUninstaller - - // Park : since 2.46.3 the log is enabled in main Park version - // EW_LOG, // LogSet, LogText - - EW_SECTIONSET, // Get*, Set* - EW_INSTTYPESET, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType - - // instructions not actually implemented in exehead, but used in compiler. - EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR - EW_GETFUNCTIONADDR, - - EW_LOCKWINDOW, // LockWindow - - // 2 unicode commands available only in Unicode archive - EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord - EW_FGETWS, // FileReadUTF16LE, FileReadWord - - // The following IDs are not IDs in real order. - // We just need some IDs to translate eny extended layout to main layout. - - EW_LOG, // LogSet, LogText - - // Park - EW_FINDPROC, // FindProc - - EW_GETFONTVERSION, // GetFontVersion - EW_GETFONTNAME, // GetFontName - - kNumCmds -}; - -static const unsigned kNumAdditionalParkCmds = 3; - -struct CCommandInfo -{ - Byte NumParams; -}; - -static const CCommandInfo k_Commands[kNumCmds] = -{ - { 0 }, // "Invalid" }, - { 0 }, // Return - { 1 }, // Nop, Goto - { 1 }, // "Abort" }, - { 0 }, // "Quit" }, - { 2 }, // Call - { 6 }, // "DetailPrint" }, // 1 param in new versions, 6 in old NSIS versions - { 1 }, // "Sleep" }, - { 0 }, // "BringToFront" }, - { 2 }, // "SetDetailsView" }, - { 2 }, // "SetFileAttributes" }, - { 2 }, // CreateDirectory, SetOutPath - { 3 }, // "IfFileExists" }, - { 3 }, // SetRebootFlag, ... - { 4 }, // "If" }, // IfAbort, IfSilent, IfErrors, IfRebootFlag - { 2 }, // "Get" }, // GetInstDirError, GetErrorLevel - { 4 }, // "Rename" }, - { 3 }, // "GetFullPathName" }, - { 2 }, // "SearchPath" }, - { 2 }, // "GetTempFileName" }, - { 6 }, // "File" - { 2 }, // "Delete" }, - { 6 }, // "MessageBox" }, - { 2 }, // "RMDir" }, - { 2 }, // "StrLen" }, - { 4 }, // StrCpy, GetCurrentAddress - { 5 }, // "StrCmp" }, - { 3 }, // ReadEnvStr, ExpandEnvStrings - { 6 }, // "IntCmp" }, - { 4 }, // "IntOp" }, - { 3 }, // "IntFmt" }, - { 6 }, // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. - { 5 }, // "FindWindow" }, - { 6 }, // "SendMessage" }, - { 3 }, // "IsWindow" }, - { 3 }, // "GetDlgItem" }, - { 2 }, // "SetCtlColors" }, - { 3 }, // "SetBrandingImage" }, - { 5 }, // "CreateFont" }, - { 4 }, // ShowWindow, EnableWindow, HideWindow - { 6 }, // "ExecShell" }, - { 3 }, // "Exec" }, // Exec, ExecWait - { 3 }, // "GetFileTime" }, - { 3 }, // "GetDLLVersion" }, - { 6 }, // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage. - { 6 }, // "CreateShortCut" }, - { 4 }, // "CopyFiles" }, - { 1 }, // "Reboot" }, - { 5 }, // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI - { 4 }, // "ReadINIStr" }, - { 5 }, // "DeleteReg" }, // DeleteRegKey, DeleteRegValue - { 6 }, // "WriteReg" }, // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD - { 5 }, // "ReadReg" }, // ReadRegStr, ReadRegDWORD - { 5 }, // "EnumReg" }, // EnumRegKey, EnumRegValue - { 1 }, // "FileClose" }, - { 4 }, // "FileOpen" }, - { 3 }, // "FileWrite" }, // FileWrite, FileWriteByte - { 4 }, // "FileRead" }, // FileRead, FileReadByte - { 4 }, // "FileSeek" }, - { 1 }, // "FindClose" }, - { 2 }, // "FindNext" }, - { 3 }, // "FindFirst" }, - { 4 }, // "WriteUninstaller" }, - { 5 }, // "Section" }, // *** - { 4 }, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType - { 6 }, // "GetLabelAddr" }, - { 2 }, // "GetFunctionAddress" }, - { 1 }, // "LockWindow" }, - { 3 }, // "FileWrite" }, // FileWriteUTF16LE, FileWriteWord - { 4 }, // "FileRead" }, // FileReadUTF16LE, FileReadWord - - { 2 }, // "Log" }, // LogSet, LogText - // Park - { 2 }, // "FindProc" }, - { 2 }, // "GetFontVersion" }, - { 2 }, // "GetFontName" } -}; - -#ifdef NSIS_SCRIPT - -static const char * const k_CommandNames[kNumCmds] = -{ - "Invalid" - , NULL // Return - , NULL // Nop, Goto - , "Abort" - , "Quit" - , NULL // Call - , "DetailPrint" // 1 param in new versions, 6 in old NSIS versions - , "Sleep" - , "BringToFront" - , "SetDetailsView" - , "SetFileAttributes" - , NULL // CreateDirectory, SetOutPath - , "IfFileExists" - , NULL // SetRebootFlag, ... - , "If" // IfAbort, IfSilent, IfErrors, IfRebootFlag - , "Get" // GetInstDirError, GetErrorLevel - , "Rename" - , "GetFullPathName" - , "SearchPath" - , "GetTempFileName" - , NULL // File - , "Delete" - , "MessageBox" - , "RMDir" - , "StrLen" - , NULL // StrCpy, GetCurrentAddress - , "StrCmp" - , NULL // ReadEnvStr, ExpandEnvStrings - , "IntCmp" - , "IntOp" - , "IntFmt" - , NULL // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. - , "FindWindow" - , "SendMessage" - , "IsWindow" - , "GetDlgItem" - , "SetCtlColors" - , "SetBrandingImage" - , "CreateFont" - , NULL // ShowWindow, EnableWindow, HideWindow - , "ExecShell" - , "Exec" // Exec, ExecWait - , "GetFileTime" - , "GetDLLVersion" - , NULL // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage. - , "CreateShortCut" - , "CopyFiles" - , "Reboot" - , NULL // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI - , "ReadINIStr" - , "DeleteReg" // DeleteRegKey, DeleteRegValue - , "WriteReg" // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD - , "ReadReg" // ReadRegStr, ReadRegDWORD - , "EnumReg" // EnumRegKey, EnumRegValue - , "FileClose" - , "FileOpen" - , "FileWrite" // FileWrite, FileWriteByte - , "FileRead" // FileRead, FileReadByte - , "FileSeek" - , "FindClose" - , "FindNext" - , "FindFirst" - , "WriteUninstaller" - , "Section" // *** - , NULL // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType - , "GetLabelAddr" - , "GetFunctionAddress" - , "LockWindow" - , "FileWrite" // FileWriteUTF16LE, FileWriteWord - , "FileRead" // FileReadUTF16LE, FileReadWord - - , "Log" // LogSet, LogText - - // Park - , "FindProc" - , "GetFontVersion" - , "GetFontName" -}; - -#endif - -/* NSIS can use one name for two CSIDL_*** and CSIDL_COMMON_*** items (CurrentUser / AllUsers) - Some NSIS shell names are not identical to WIN32 CSIDL_* names. - NSIS doesn't use some CSIDL_* values. But we add name for all CSIDL_ (marked with '+'). */ - -static const char * const kShellStrings[] = -{ - "DESKTOP" // + - , "INTERNET" // + - , "SMPROGRAMS" // CSIDL_PROGRAMS - , "CONTROLS" // + - , "PRINTERS" // + - , "DOCUMENTS" // CSIDL_PERSONAL - , "FAVORITES" // CSIDL_FAVORITES - , "SMSTARTUP" // CSIDL_STARTUP - , "RECENT" // CSIDL_RECENT - , "SENDTO" // CSIDL_SENDTO - , "BITBUCKET" // + - , "STARTMENU" - , NULL // CSIDL_MYDOCUMENTS = CSIDL_PERSONAL - , "MUSIC" // CSIDL_MYMUSIC - , "VIDEOS" // CSIDL_MYVIDEO - , NULL - , "DESKTOP" // CSIDL_DESKTOPDIRECTORY - , "DRIVES" // + - , "NETWORK" // + - , "NETHOOD" - , "FONTS" - , "TEMPLATES" - , "STARTMENU" // CSIDL_COMMON_STARTMENU - , "SMPROGRAMS" // CSIDL_COMMON_PROGRAMS - , "SMSTARTUP" // CSIDL_COMMON_STARTUP - , "DESKTOP" // CSIDL_COMMON_DESKTOPDIRECTORY - , "APPDATA" // CSIDL_APPDATA !!! "QUICKLAUNCH" - , "PRINTHOOD" - , "LOCALAPPDATA" - , "ALTSTARTUP" - , "ALTSTARTUP" // CSIDL_COMMON_ALTSTARTUP - , "FAVORITES" // CSIDL_COMMON_FAVORITES - , "INTERNET_CACHE" - , "COOKIES" - , "HISTORY" - , "APPDATA" // CSIDL_COMMON_APPDATA - , "WINDIR" - , "SYSDIR" - , "PROGRAM_FILES" // + - , "PICTURES" // CSIDL_MYPICTURES - , "PROFILE" - , "SYSTEMX86" // + - , "PROGRAM_FILESX86" // + - , "PROGRAM_FILES_COMMON" // + - , "PROGRAM_FILES_COMMONX8" // + CSIDL_PROGRAM_FILES_COMMONX86 - , "TEMPLATES" // CSIDL_COMMON_TEMPLATES - , "DOCUMENTS" // CSIDL_COMMON_DOCUMENTS - , "ADMINTOOLS" // CSIDL_COMMON_ADMINTOOLS - , "ADMINTOOLS" // CSIDL_ADMINTOOLS - , "CONNECTIONS" // + - , NULL - , NULL - , NULL - , "MUSIC" // CSIDL_COMMON_MUSIC - , "PICTURES" // CSIDL_COMMON_PICTURES - , "VIDEOS" // CSIDL_COMMON_VIDEO - , "RESOURCES" - , "RESOURCES_LOCALIZED" - , "COMMON_OEM_LINKS" // + - , "CDBURN_AREA" - , NULL // unused - , "COMPUTERSNEARME" // + -}; - - -static void UIntToString(AString &s, UInt32 v) -{ - char sz[16]; - ConvertUInt32ToString(v, sz); - s += sz; -} - -#ifdef NSIS_SCRIPT - -void CInArchive::Add_UInt(UInt32 v) -{ - char sz[16]; - ConvertUInt32ToString(v, sz); - Script += sz; -} - -static void Add_SignedInt(CDynLimBuf &s, Int32 v) -{ - char sz[32]; - ConvertInt64ToString(v, sz); - s += sz; -} - -static void Add_Hex(CDynLimBuf &s, UInt32 v) -{ - char sz[16]; - sz[0] = '0'; - sz[1] = 'x'; - ConvertUInt32ToHex(v, sz + 2); - s += sz; -} - -static UInt32 GetUi16Str_Len(const Byte *p) -{ - const Byte *pp = p; - for (; *pp != 0 || *(pp + 1) != 0; pp += 2); - return (UInt32)((pp - p) >> 1); -} - -void CInArchive::AddLicense(UInt32 param, Int32 langID) -{ - Space(); - if (param >= NumStringChars || - param + 1 >= NumStringChars) - { - Script += kErrorStr; - return; - } - strUsed[param] = 1; - - UInt32 start = _stringsPos + (IsUnicode ? param * 2 : param); - UInt32 offset = start + (IsUnicode ? 2 : 1); - { - FOR_VECTOR (i, LicenseFiles) - { - const CLicenseFile &lic = LicenseFiles[i]; - if (offset == lic.Offset) - { - Script += lic.Name; - return; - } - } - } - AString fileName = "[LICENSE]"; - if (langID >= 0) - { - fileName += "\\license-"; - // LangId_To_String(fileName, langID); - UIntToString(fileName, langID); - } - else if (++_numRootLicenses > 1) - { - fileName += '-'; - UIntToString(fileName, _numRootLicenses); - } - const Byte *sz = (_data + start); - unsigned marker = IsUnicode ? Get16(sz) : *sz; - bool isRTF = (marker == 2); - fileName += isRTF ? ".rtf" : ".txt"; // if (*sz == 1) it's text; - Script += fileName; - - CLicenseFile &lic = LicenseFiles.AddNew(); - lic.Name = fileName; - lic.Offset = offset; - if (!IsUnicode) - lic.Size = (UInt32)strlen((const char *)sz + 1); - else - { - sz += 2; - UInt32 len = GetUi16Str_Len(sz); - lic.Size = len * 2; - if (isRTF) - { - lic.Text.Alloc((size_t)len); - for (UInt32 i = 0; i < len; i++, sz += 2) - { - unsigned c = Get16(sz); - if (c >= 256) - c = '?'; - lic.Text[i] = (Byte)(c); - } - lic.Size = len; - lic.Offset = 0; - } - } -} - -#endif - - -#define kVar_CMDLINE 20 -#define kVar_INSTDIR 21 -#define kVar_OUTDIR 22 -#define kVar_EXEDIR 23 -#define kVar_LANGUAGE 24 -#define kVar_TEMP 25 -#define kVar_PLUGINSDIR 26 -#define kVar_EXEPATH 27 // NSIS 2.26+ -#define kVar_EXEFILE 28 // NSIS 2.26+ - -#define kVar_HWNDPARENT_225 27 -#define kVar_HWNDPARENT 29 - -// #define kVar__CLICK 30 -#define kVar_Spec_OUTDIR_225 29 // NSIS 2.04 - 2.25 -#define kVar_Spec_OUTDIR 31 // NSIS 2.26+ - - -static const char * const kVarStrings[] = -{ - "CMDLINE" - , "INSTDIR" - , "OUTDIR" - , "EXEDIR" - , "LANGUAGE" - , "TEMP" - , "PLUGINSDIR" - , "EXEPATH" // NSIS 2.26+ - , "EXEFILE" // NSIS 2.26+ - , "HWNDPARENT" - , "_CLICK" // is set from page->clicknext - , "_OUTDIR" // NSIS 2.04+ -}; - -static const unsigned kNumInternalVars = 20 + ARRAY_SIZE(kVarStrings); - -#define GET_NUM_INTERNAL_VARS (IsNsis200 ? kNumInternalVars - 3 : IsNsis225 ? kNumInternalVars - 2 : kNumInternalVars); - -void CInArchive::GetVar2(AString &res, UInt32 index) -{ - if (index < 20) - { - if (index >= 10) - { - res += 'R'; - index -= 10; - } - UIntToString(res, index); - } - else - { - unsigned numInternalVars = GET_NUM_INTERNAL_VARS; - if (index < numInternalVars) - { - if (IsNsis225 && index >= kVar_EXEPATH) - index += 2; - res += kVarStrings[index - 20]; - } - else - { - res += '_'; - UIntToString(res, index - numInternalVars); - res += '_'; - } - } -} - -void CInArchive::GetVar(AString &res, UInt32 index) -{ - res += '$'; - GetVar2(res, index); -} - -#ifdef NSIS_SCRIPT - -void CInArchive::Add_Var(UInt32 index) -{ - _tempString_for_GetVar.Empty(); - GetVar(_tempString_for_GetVar, index); - Script += _tempString_for_GetVar; -} - -void CInArchive::AddParam_Var(UInt32 index) -{ - Space(); - Add_Var(index); -} - -void CInArchive::AddParam_UInt(UInt32 value) -{ - Space(); - Add_UInt(value); -} - -#endif - - -#define NS_CODE_SKIP 252 -#define NS_CODE_VAR 253 -#define NS_CODE_SHELL 254 -#define NS_CODE_LANG 255 - -#define NS_3_CODE_LANG 1 -#define NS_3_CODE_SHELL 2 -#define NS_3_CODE_VAR 3 -#define NS_3_CODE_SKIP 4 - -#define PARK_CODE_SKIP 0xE000 -#define PARK_CODE_VAR 0xE001 -#define PARK_CODE_SHELL 0xE002 -#define PARK_CODE_LANG 0xE003 - -#define IS_NS_SPEC_CHAR(c) ((c) >= NS_CODE_SKIP) -#define IS_PARK_SPEC_CHAR(c) ((c) >= PARK_CODE_SKIP && (c) <= PARK_CODE_LANG) - -#define DECODE_NUMBER_FROM_2_CHARS(c0, c1) (((c0) & 0x7F) | (((unsigned)((c1) & 0x7F)) << 7)) -#define CONVERT_NUMBER_NS_3_UNICODE(n) n = ((n & 0x7F) | (((n >> 8) & 0x7F) << 7)) -#define CONVERT_NUMBER_PARK(n) n &= 0x7FFF - - -static bool AreStringsEqual_16and8(const Byte *p16, const char *p8) -{ - for (;;) - { - unsigned c16 = Get16(p16); p16 += 2; - unsigned c = (Byte)(*p8++); - if (c16 != c) - return false; - if (c == 0) - return true; - } -} - -void CInArchive::GetShellString(AString &s, unsigned index1, unsigned index2) -{ - // zeros are not allowed here. - // if (index1 == 0 || index2 == 0) throw 333; - - if ((index1 & 0x80) != 0) - { - unsigned offset = (index1 & 0x3F); - - /* NSIS reads registry string: - keyName = HKLM Software\\Microsoft\\Windows\\CurrentVersion - mask = KEY_WOW64_64KEY, If 64-bit flag in index1 is set - valueName = string(offset) - If registry reading is failed, NSIS uses second parameter (index2) - to read string. The recursion is possible in that case in NSIS. - We don't parse index2 string. We only set strUsed status for that - string (but without recursion). */ - - if (offset >= NumStringChars) - { - s += kErrorStr; - return; - } - - #ifdef NSIS_SCRIPT - strUsed[offset] = 1; - if (index2 < NumStringChars) - strUsed[index2] = 1; - #endif - - const Byte *p = (const Byte *)(_data + _stringsPos); - int id = -1; - if (IsUnicode) - { - p += offset * 2; - if (AreStringsEqual_16and8(p, "ProgramFilesDir")) - id = 0; - else if (AreStringsEqual_16and8(p, "CommonFilesDir")) - id = 1; - } - else - { - p += offset; - if (strcmp((const char *)p, "ProgramFilesDir") == 0) - id = 0; - else if (strcmp((const char *)p, "CommonFilesDir") == 0) - id = 1; - } - - s += ((id >= 0) ? (id == 0 ? "$PROGRAMFILES" : "$COMMONFILES") : - "$_ERROR_UNSUPPORTED_VALUE_REGISTRY_"); - // s += ((index1 & 0x40) != 0) ? "64" : "32"; - if ((index1 & 0x40) != 0) - s += "64"; - - if (id < 0) - { - s += '('; - if (IsUnicode) - { - for (unsigned i = 0; i < 256; i++) - { - wchar_t c = Get16(p + i * 2); - if (c == 0) - break; - if (c < 0x80) - s += (char)c; - } - } - else - s += (const char *)p; - s += ')'; - } - return; - } - - s += '$'; - if (index1 < ARRAY_SIZE(kShellStrings)) - { - const char *sz = kShellStrings[index1]; - if (sz) - { - s += sz; - return; - } - } - if (index2 < ARRAY_SIZE(kShellStrings)) - { - const char *sz = kShellStrings[index2]; - if (sz) - { - s += sz; - return; - } - } - s += "_ERROR_UNSUPPORTED_SHELL_"; - s += '['; - UIntToString(s, index1); - s += ','; - UIntToString(s, index2); - s += ']'; -} - -#ifdef NSIS_SCRIPT - -void CInArchive::Add_LangStr_Simple(UInt32 id) -{ - Script += "LSTR_"; - Add_UInt(id); -} - -#endif - -void CInArchive::Add_LangStr(AString &res, UInt32 id) -{ - #ifdef NSIS_SCRIPT - langStrIDs.Add(id); - #endif - res += "$(LSTR_"; - UIntToString(res, id); - res += ')'; -} - -void CInArchive::GetNsisString_Raw(const Byte *s) -{ - Raw_AString.Empty(); - - if (NsisType != k_NsisType_Nsis3) - { - for (;;) - { - Byte c = *s++; - if (c == 0) - return; - if (IS_NS_SPEC_CHAR(c)) - { - Byte c0 = *s++; - if (c0 == 0) - return; - if (c != NS_CODE_SKIP) - { - Byte c1 = *s++; - if (c1 == 0) - return; - - if (c == NS_CODE_SHELL) - GetShellString(Raw_AString, c0, c1); - else - { - unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - if (c == NS_CODE_VAR) - GetVar(Raw_AString, n); - else // if (c == NS_CODE_LANG) - Add_LangStr(Raw_AString, n); - } - continue; - } - c = c0; - } - Raw_AString += (char)c; - } - } - - // NSIS-3 ANSI - for (;;) - { - Byte c = *s++; - if (c <= NS_3_CODE_SKIP) - { - if (c == 0) - return; - Byte c0 = *s++; - if (c0 == 0) - return; - if (c != NS_3_CODE_SKIP) - { - Byte c1 = *s++; - if (c1 == 0) - return; - - if (c == NS_3_CODE_SHELL) - GetShellString(Raw_AString, c0, c1); - else - { - unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - if (c == NS_3_CODE_VAR) - GetVar(Raw_AString, n); - else // if (c == NS_3_CODE_LANG) - Add_LangStr(Raw_AString, n); - } - continue; - } - c = c0; - } - Raw_AString += (char)c; - } -} - -#ifdef NSIS_SCRIPT - -void CInArchive::GetNsisString(AString &res, const Byte *s) -{ - for (;;) - { - Byte c = *s++; - if (c == 0) - return; - if (NsisType != k_NsisType_Nsis3) - { - if (IS_NS_SPEC_CHAR(c)) - { - Byte c0 = *s++; - if (c0 == 0) - return; - if (c != NS_CODE_SKIP) - { - Byte c1 = *s++; - if (c1 == 0) - return; - if (c == NS_CODE_SHELL) - GetShellString(res, c0, c1); - else - { - unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - if (c == NS_CODE_VAR) - GetVar(res, n); - else // if (c == NS_CODE_LANG) - Add_LangStr(res, n); - } - continue; - } - c = c0; - } - } - else - { - // NSIS-3 ANSI - if (c <= NS_3_CODE_SKIP) - { - Byte c0 = *s++; - if (c0 == 0) - return; - if (c0 == 0) - break; - if (c != NS_3_CODE_SKIP) - { - Byte c1 = *s++; - if (c1 == 0) - return; - if (c == NS_3_CODE_SHELL) - GetShellString(res, c0, c1); - else - { - unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - if (c == NS_3_CODE_VAR) - GetVar(res, n); - else // if (c == NS_3_CODE_LANG) - Add_LangStr(res, n); - } - continue; - } - c = c0; - } - } - - { - const char *e; - if (c == 9) e = "$\\t"; - else if (c == 10) e = "$\\n"; - else if (c == 13) e = "$\\r"; - else if (c == '"') e = "$\\\""; - else if (c == '$') e = "$$"; - else - { - res += (char)c; - continue; - } - res += e; - continue; - } - } -} - -#endif - -void CInArchive::GetNsisString_Unicode_Raw(const Byte *p) -{ - Raw_UString.Empty(); - - if (IsPark()) - { - for (;;) - { - unsigned c = Get16(p); - p += 2; - if (c == 0) - break; - if (c < 0x80) - { - Raw_UString += (wchar_t)c; - continue; - } - - if (IS_PARK_SPEC_CHAR(c)) - { - unsigned n = Get16(p); - p += 2; - if (n == 0) - break; - if (c != PARK_CODE_SKIP) - { - Raw_AString.Empty(); - if (c == PARK_CODE_SHELL) - GetShellString(Raw_AString, n & 0xFF, n >> 8); - else - { - CONVERT_NUMBER_PARK(n); - if (c == PARK_CODE_VAR) - GetVar(Raw_AString, n); - else // if (c == PARK_CODE_LANG) - Add_LangStr(Raw_AString, n); - } - Raw_UString.AddAscii(Raw_AString); - continue; - } - c = n; - } - - Raw_UString += (wchar_t)c; - } - - return; - } - - // NSIS-3 Unicode - for (;;) - { - unsigned c = Get16(p); - p += 2; - if (c > NS_3_CODE_SKIP) - { - Raw_UString += (wchar_t)c; - continue; - } - if (c == 0) - break; - - unsigned n = Get16(p); - p += 2; - if (n == 0) - break; - if (c == NS_3_CODE_SKIP) - { - Raw_UString += (wchar_t)n; - continue; - } - - Raw_AString.Empty(); - if (c == NS_3_CODE_SHELL) - GetShellString(Raw_AString, n & 0xFF, n >> 8); - else - { - CONVERT_NUMBER_NS_3_UNICODE(n); - if (c == NS_3_CODE_VAR) - GetVar(Raw_AString, n); - else // if (c == NS_3_CODE_LANG) - Add_LangStr(Raw_AString, n); - } - Raw_UString.AddAscii(Raw_AString); - } -} - -#ifdef NSIS_SCRIPT - -static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -void CInArchive::GetNsisString_Unicode(AString &res, const Byte *p) -{ - for (;;) - { - unsigned c = Get16(p); - p += 2; - if (c == 0) - break; - if (IsPark()) - { - if (IS_PARK_SPEC_CHAR(c)) - { - unsigned n = Get16(p); - p += 2; - if (n == 0) - break; - if (c != PARK_CODE_SKIP) - { - if (c == PARK_CODE_SHELL) - GetShellString(res, n & 0xFF, n >> 8); - else - { - CONVERT_NUMBER_PARK(n); - if (c == PARK_CODE_VAR) - GetVar(res, n); - else // if (c == PARK_CODE_LANG) - Add_LangStr(res, n); - } - continue; - } - c = n; - } - } - else - { - // NSIS-3 Unicode - if (c <= NS_3_CODE_SKIP) - { - unsigned n = Get16(p); - p += 2; - if (n == 0) - break; - if (c != NS_3_CODE_SKIP) - { - if (c == NS_3_CODE_SHELL) - GetShellString(res, n & 0xFF, n >> 8); - else - { - CONVERT_NUMBER_NS_3_UNICODE(n); - if (c == NS_3_CODE_VAR) - GetVar(res, n); - else // if (c == NS_3_CODE_LANG) - Add_LangStr(res, n); - } - continue; - } - c = n; - } - } - - if (c < 0x80) - { - const char *e; - if (c == 9) e = "$\\t"; - else if (c == 10) e = "$\\n"; - else if (c == 13) e = "$\\r"; - else if (c == '"') e = "$\\\""; - else if (c == '$') e = "$$"; - else - { - res += (char)c; - continue; - } - res += e; - continue; - } - - UInt32 value = c; - /* - if (value >= 0xD800 && value < 0xE000) - { - UInt32 c2; - if (value >= 0xDC00 || srcPos == srcLen) - break; - c2 = src[srcPos++]; - if (c2 < 0xDC00 || c2 >= 0xE000) - break; - value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; - } - */ - unsigned numAdds; - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - res += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); - do - { - numAdds--; - res += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); - // destPos++; - } - while (numAdds != 0); - - // AddToUtf8(res, c); - } -} - -#endif - -void CInArchive::ReadString2_Raw(UInt32 pos) -{ - Raw_AString.Empty(); - Raw_UString.Empty(); - if ((Int32)pos < 0) - Add_LangStr(Raw_AString, -((Int32)pos + 1)); - else if (pos >= NumStringChars) - { - Raw_AString += kErrorStr; - // UIntToString(Raw_AString, pos); - } - else - { - if (IsUnicode) - GetNsisString_Unicode_Raw(_data + _stringsPos + pos * 2); - else - GetNsisString_Raw(_data + _stringsPos + pos); - return; - } - Raw_UString.SetFromAscii(Raw_AString); -} - -bool CInArchive::IsGoodString(UInt32 param) const -{ - if (param >= NumStringChars) - return false; - if (param == 0) - return true; - const Byte *p = _data + _stringsPos; - unsigned c; - if (IsUnicode) - c = Get16(p + param * 2 - 2); - else - c = p[param - 1]; - // some files have '\\' character before string? - return (c == 0 || c == '\\'); -} - -bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const -{ - if (param1 == param2) - return true; - - /* NSIS-3.0a1 probably contains bug, so it can use 2 different strings - with same content. So we check real string also. - Also it's possible to check identical postfix parts of strings. */ - - if (param1 >= NumStringChars || - param2 >= NumStringChars) - return false; - - const Byte *p = _data + _stringsPos; - - if (IsUnicode) - { - const Byte *p1 = p + param1 * 2; - const Byte *p2 = p + param2 * 2; - for (;;) - { - UInt16 c = Get16(p1); - if (c != Get16(p2)) - return false; - if (c == 0) - return true; - p1 += 2; - p2 += 2; - } - } - else - { - const Byte *p1 = p + param1; - const Byte *p2 = p + param2; - for (;;) - { - Byte c = *p1++; - if (c != *p2++) - return false; - if (c == 0) - return true; - } - } -} - -#ifdef NSIS_SCRIPT - -UInt32 CInArchive::GetNumUsedVars() const -{ - UInt32 numUsedVars = 0; - const Byte *data = (const Byte *)_data + _stringsPos; - unsigned npi = 0; - for (UInt32 i = 0; i < NumStringChars;) - { - bool process = true; - if (npi < noParseStringIndexes.Size() && noParseStringIndexes[npi] == i) - { - process = false; - npi++; - } - - if (IsUnicode) - { - if (IsPark()) - { - for (;;) - { - unsigned c = Get16(data + i * 2); - i++; - if (c == 0) - break; - if (IS_PARK_SPEC_CHAR(c)) - { - UInt32 n = Get16(data + i * 2); - i++; - if (n == 0) - break; - if (process && c == PARK_CODE_VAR) - { - CONVERT_NUMBER_PARK(n); - n++; - if (numUsedVars < n) - numUsedVars = n; - } - } - } - } - else // NSIS-3 Unicode - { - for (;;) - { - unsigned c = Get16(data + i * 2); - i++; - if (c == 0) - break; - if (c > NS_3_CODE_SKIP) - continue; - UInt32 n = Get16(data + i * 2); - i++; - if (n == 0) - break; - if (process && c == NS_3_CODE_VAR) - { - CONVERT_NUMBER_NS_3_UNICODE(n); - n++; - if (numUsedVars < n) - numUsedVars = n; - } - } - } - } - else // not Unicode (ANSI) - { - if (NsisType != k_NsisType_Nsis3) - { - for (;;) - { - Byte c = data[i++]; - if (c == 0) - break; - if (IS_NS_SPEC_CHAR(c)) - { - Byte c0 = data[i++]; - if (c0 == 0) - break; - if (c == NS_CODE_SKIP) - continue; - Byte c1 = data[i++]; - if (c1 == 0) - break; - if (process && c == NS_CODE_VAR) - { - UInt32 n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - n++; - if (numUsedVars < n) - numUsedVars = n; - } - } - } - } - else - { - // NSIS-3 ANSI - for (;;) - { - Byte c = data[i++]; - if (c == 0) - break; - if (c > NS_3_CODE_SKIP) - continue; - - Byte c0 = data[i++]; - if (c0 == 0) - break; - if (c == NS_3_CODE_SKIP) - continue; - Byte c1 = data[i++]; - if (c1 == 0) - break; - if (process && c == NS_3_CODE_VAR) - { - UInt32 n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); - n++; - if (numUsedVars < n) - numUsedVars = n; - } - } - } - } - } - return numUsedVars; -} - -void CInArchive::ReadString2(AString &s, UInt32 pos) -{ - if ((Int32)pos < 0) - { - Add_LangStr(s, -((Int32)pos + 1)); - return; - } - - if (pos >= NumStringChars) - { - s += kErrorStr; - // UIntToString(s, pos); - return; - } - - #ifdef NSIS_SCRIPT - strUsed[pos] = 1; - #endif - - if (IsUnicode) - GetNsisString_Unicode(s, _data + _stringsPos + pos * 2); - else - GetNsisString(s, _data + _stringsPos + pos); -} - -#endif - -#ifdef NSIS_SCRIPT - -#define DEL_DIR 1 -#define DEL_RECURSE 2 -#define DEL_REBOOT 4 -// #define DEL_SIMPLE 8 - -void CInArchive::AddRegRoot(UInt32 val) -{ - Space(); - const char *s; - switch (val) - { - case 0: s = "SHCTX"; break; - case 0x80000000: s = "HKCR"; break; - case 0x80000001: s = "HKCU"; break; - case 0x80000002: s = "HKLM"; break; - case 0x80000003: s = "HKU"; break; - case 0x80000004: s = "HKPD"; break; - case 0x80000005: s = "HKCC"; break; - case 0x80000006: s = "HKDD"; break; - case 0x80000050: s = "HKPT"; break; - case 0x80000060: s = "HKPN"; break; - default: - // Script += " RRRRR "; - // throw 1; - Add_Hex(Script, val); return; - } - Script += s; -} - -static const char *g_WinAttrib[] = -{ - "READONLY" - , "HIDDEN" - , "SYSTEM" - , NULL - , "DIRECTORY" - , "ARCHIVE" - , "DEVICE" - , "NORMAL" - , "TEMPORARY" - , "SPARSE_FILE" - , "REPARSE_POINT" - , "COMPRESSED" - , "OFFLINE" - , "NOT_CONTENT_INDEXED" - , "ENCRYPTED" - , NULL - , "VIRTUAL" -}; - -#define FLAGS_DELIMITER '|' - -static void FlagsToString2(CDynLimBuf &s, const char * const *table, unsigned num, UInt32 flags) -{ - bool filled = false; - for (unsigned i = 0; i < num; i++) - { - UInt32 f = (UInt32)1 << i; - if ((flags & f) != 0) - { - const char *name = table[i]; - if (name) - { - if (filled) - s += FLAGS_DELIMITER; - filled = true; - s += name; - flags &= ~f; - } - } - } - if (flags != 0) - { - if (filled) - s += FLAGS_DELIMITER; - Add_Hex(s, flags); - } -} - -static bool DoesNeedQuotes(const char *s) -{ - char c = s[0]; - if (c == 0 || c == '#' || c == ';' || (c == '/' && s[1] == '*')) - return true; - for (;;) - { - char c = *s++; - if (c == 0) - return false; - if (c == ' ') - return true; - } -} - -void CInArchive::Add_QuStr(const AString &s) -{ - bool needQuotes = DoesNeedQuotes(s); - if (needQuotes) - Script += '\"'; - Script += s; - if (needQuotes) - Script += '\"'; -} - -void CInArchive::SpaceQuStr(const AString &s) -{ - Space(); - Add_QuStr(s); -} - -void CInArchive::AddParam(UInt32 pos) -{ - _tempString.Empty(); - ReadString2(_tempString, pos); - SpaceQuStr(_tempString); -} - -void CInArchive::AddParams(const UInt32 *params, unsigned num) -{ - for (unsigned i = 0; i < num; i++) - AddParam(params[i]); -} - -void CInArchive::AddOptionalParam(UInt32 pos) -{ - if (pos != 0) - AddParam(pos); -} - -static unsigned GetNumParams(const UInt32 *params, unsigned num) -{ - for (; num > 0 && params[num - 1] == 0; num--); - return num; -} - -void CInArchive::AddOptionalParams(const UInt32 *params, unsigned num) -{ - AddParams(params, GetNumParams(params, num)); -} - - -static const UInt32 CMD_REF_Goto = (1 << 0); -static const UInt32 CMD_REF_Call = (1 << 1); -static const UInt32 CMD_REF_Pre = (1 << 2); -static const UInt32 CMD_REF_Show = (1 << 3); -static const UInt32 CMD_REF_Leave = (1 << 4); -static const UInt32 CMD_REF_OnFunc = (1 << 5); -static const UInt32 CMD_REF_Section = (1 << 6); -static const UInt32 CMD_REF_InitPluginDir = (1 << 7); -// static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead -static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too -static const unsigned CMD_REF_Page_NumShifts = 16; // it uses for onFunc too -static const UInt32 CMD_REF_Page_Mask = 0x0FFF0000; -static const UInt32 CMD_REF_OnFunc_Mask = 0xF0000000; - -inline bool IsPageFunc(UInt32 flag) -{ - return (flag & (CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave)) != 0; -} - -inline bool IsFunc(UInt32 flag) -{ - // return (flag & (CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave | CMD_REF_OnFunc)) != 0; - return (flag & (CMD_REF_Call | CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave | CMD_REF_OnFunc)) != 0; -} - -inline bool IsProbablyEndOfFunc(UInt32 flag) -{ - return (flag != 0 && flag != CMD_REF_Goto); -} - -static const char * const kOnFunc[] = -{ - "Init" - , "InstSuccess" - , "InstFailed" - , "UserAbort" - , "GUIInit" - , "GUIEnd" - , "MouseOverSection" - , "VerifyInstDir" - , "SelChange" - , "RebootFailed" -}; - -void CInArchive::Add_FuncName(const UInt32 *labels, UInt32 index) -{ - UInt32 mask = labels[index]; - if (mask & CMD_REF_OnFunc) - { - Script += ".on"; - Script += kOnFunc[labels[index] >> CMD_REF_OnFunc_NumShifts]; - } - else if (mask & CMD_REF_InitPluginDir) - { - /* - if (!IsInstaller) - Script += "un." - */ - Script += "Initialize_____Plugins"; - } - else - { - Script += "func_"; - Add_UInt(index); - } -} - -void CInArchive::AddParam_Func(const UInt32 *labels, UInt32 index) -{ - Space(); - if ((Int32)index >= 0) - Add_FuncName(labels, index); - else - AddQuotes(); -} - - -void CInArchive::Add_LabelName(UInt32 index) -{ - Script += "label_"; - Add_UInt(index); -} - -// param != 0 -void CInArchive::Add_GotoVar(UInt32 param) -{ - Space(); - if ((Int32)param < 0) - Add_Var(-((Int32)param + 1)); - else - Add_LabelName(param - 1); -} - -void CInArchive::Add_GotoVar1(UInt32 param) -{ - if (param == 0) - Script += " 0"; - else - Add_GotoVar(param); -} - -void CInArchive::Add_GotoVars2(const UInt32 *params) -{ - Add_GotoVar1(params[0]); - if (params[1] != 0) - Add_GotoVar(params[1]); -} - -static bool NoLabels(const UInt32 *labels, UInt32 num) -{ - for (UInt32 i = 0; i < num; i++) - if (labels[i] != 0) - return false; - return true; -} - -static const char * const k_REBOOTOK = " /REBOOTOK"; - -#define MY__MB_ABORTRETRYIGNORE 2 -#define MY__MB_RETRYCANCEL 5 - -static const char * const k_MB_Buttons[] = -{ - "OK" - , "OKCANCEL" - , "ABORTRETRYIGNORE" - , "YESNOCANCEL" - , "YESNO" - , "RETRYCANCEL" - , "CANCELTRYCONTINUE" -}; - -#define MY__MB_ICONSTOP (1 << 4) - -static const char * const k_MB_Icons[] = -{ - NULL - , "ICONSTOP" - , "ICONQUESTION" - , "ICONEXCLAMATION" - , "ICONINFORMATION" -}; - -static const char * const k_MB_Flags[] = -{ - "HELP" - , "NOFOCUS" - , "SETFOREGROUND" - , "DEFAULT_DESKTOP_ONLY" - , "TOPMOST" - , "RIGHT" - , "RTLREADING" - // , "SERVICE_NOTIFICATION" // unsupported. That bit is used for NSIS purposes -}; - -#define MY__IDCANCEL 2 -#define MY__IDIGNORE 5 - -static const char * const k_Button_IDs[] = -{ - "0" - , "IDOK" - , "IDCANCEL" - , "IDABORT" - , "IDRETRY" - , "IDIGNORE" - , "IDYES" - , "IDNO" - , "IDCLOSE" - , "IDHELP" - , "IDTRYAGAIN" - , "IDCONTINUE" -}; - -void CInArchive::Add_ButtonID(UInt32 buttonID) -{ - Space(); - if (buttonID < ARRAY_SIZE(k_Button_IDs)) - Script += k_Button_IDs[buttonID]; - else - { - Script += "Button_"; - Add_UInt(buttonID); - } -} - -bool CInArchive::IsDirectString_Equal(UInt32 offset, const char *s) const -{ - if (offset >= NumStringChars) - return false; - if (IsUnicode) - return AreStringsEqual_16and8(_data + _stringsPos + offset * 2, s); - else - return strcmp((const char *)(const Byte *)_data + _stringsPos + offset, s) == 0; -} - -static bool StringToUInt32(const char *s, UInt32 &res) -{ - const char *end; - if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) - res = ConvertHexStringToUInt32(s + 2, &end); - else - res = ConvertStringToUInt32(s, &end); - return (*end == 0); -} - -static const unsigned k_CtlColors_Size = 24; - -struct CNsis_CtlColors -{ - UInt32 text; // COLORREF - UInt32 bkc; // COLORREF - UInt32 lbStyle; - UInt32 bkb; // HBRUSH - Int32 bkmode; - Int32 flags; - - void Parse(const Byte *p); -}; - -void CNsis_CtlColors::Parse(const Byte *p) -{ - text = Get32(p); - bkc = Get32(p + 4); - lbStyle = Get32(p + 8); - bkb = Get32(p + 12); - bkmode = (Int32)Get32(p + 16); - flags = (Int32)Get32(p + 20); -} - -// Win32 constants -#define MY__TRANSPARENT 1 -#define MY__OPAQUE 2 - -#define MY__GENERIC_READ (1 << 31) -#define MY__GENERIC_WRITE (1 << 30) -#define MY__GENERIC_EXECUTE (1 << 29) -#define MY__GENERIC_ALL (1 << 28) - -#define MY__CREATE_NEW 1 -#define MY__CREATE_ALWAYS 2 -#define MY__OPEN_EXISTING 3 -#define MY__OPEN_ALWAYS 4 -#define MY__TRUNCATE_EXISTING 5 - -// text/bg colors -#define kColorsFlags_TEXT 1 -#define kColorsFlags_TEXT_SYS 2 -#define kColorsFlags_BK 4 -#define kColorsFlags_BK_SYS 8 -#define kColorsFlags_BKB 16 - -void CInArchive::Add_Color2(UInt32 v) -{ - v = ((v & 0xFF) << 16) | (v & 0xFF00) | ((v >> 16) & 0xFF); - char sz[32]; - for (int i = 5; i >= 0; i--) - { - unsigned t = v & 0xF; - v >>= 4; - sz[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); - } - sz[6] = 0; - Script += sz; -} - -void CInArchive::Add_ColorParam(UInt32 v) -{ - Space(); - Add_Color2(v); -} - -void CInArchive::Add_Color(UInt32 v) -{ - Script += "0x"; - Add_Color2(v); -} - -#define MY__SW_HIDE 0 -#define MY__SW_SHOWNORMAL 1 - -#define MY__SW_SHOWMINIMIZED 2 -#define MY__SW_SHOWMINNOACTIVE 7 -#define MY__SW_SHOWNA 8 - -static const char * const kShowWindow_Commands[] = -{ - "HIDE" - , "SHOWNORMAL" // "NORMAL" - , "SHOWMINIMIZED" - , "SHOWMAXIMIZED" // "MAXIMIZE" - , "SHOWNOACTIVATE" - , "SHOW" - , "MINIMIZE" - , "SHOWMINNOACTIVE" - , "SHOWNA" - , "RESTORE" - , "SHOWDEFAULT" - , "FORCEMINIMIZE" // "MAX" -}; - -static void Add_ShowWindow_Cmd_2(AString &s, UInt32 cmd) -{ - if (cmd < ARRAY_SIZE(kShowWindow_Commands)) - { - s += "SW_"; - s += kShowWindow_Commands[cmd]; - } - else - UIntToString(s, cmd); -} - -void CInArchive::Add_ShowWindow_Cmd(UInt32 cmd) -{ - if (cmd < ARRAY_SIZE(kShowWindow_Commands)) - { - Script += "SW_"; - Script += kShowWindow_Commands[cmd]; - } - else - Add_UInt(cmd); -} - -void CInArchive::Add_TypeFromList(const char * const *table, unsigned tableSize, UInt32 type) -{ - if (type < tableSize) - Script += table[type]; - else - { - Script += '_'; - Add_UInt(type); - } -} - -#define ADD_TYPE_FROM_LIST(table, type) Add_TypeFromList(table, ARRAY_SIZE(table), type) - -enum -{ - k_ExecFlags_AutoClose, - k_ExecFlags_ShellVarContext, - k_ExecFlags_Errors, - k_ExecFlags_Abort, - k_ExecFlags_RebootFlag, - k_ExecFlags_reboot_called, - k_ExecFlags_cur_insttype, - k_ExecFlags_plugin_api_version, - k_ExecFlags_Silent, - k_ExecFlags_InstDirError, - k_ExecFlags_rtl, - k_ExecFlags_ErrorLevel, - k_ExecFlags_RegView, - k_ExecFlags_DetailsPrint = 13, -}; - -// Names for NSIS exec_flags_t structure vars -static const char * const kExecFlags_VarsNames[] = -{ - "AutoClose" // autoclose; - , "ShellVarContext" // all_user_var; - , "Errors" // exec_error; - , "Abort" // abort; - , "RebootFlag" // exec_reboot; // NSIS_SUPPORT_REBOOT - , "reboot_called" // reboot_called; // NSIS_SUPPORT_REBOOT - , "cur_insttype" // XXX_cur_insttype; // depreacted - , "plugin_api_version" // plugin_api_version; // see NSISPIAPIVER_CURR - // used to be XXX_insttype_changed - , "Silent" // silent; // NSIS_CONFIG_SILENT_SUPPORT - , "InstDirError" // instdir_error; - , "rtl" // rtl; - , "ErrorLevel" // errlvl; - , "RegView" // alter_reg_view; - , "DetailsPrint" // status_update; -}; - -void CInArchive::Add_ExecFlags(UInt32 flagsType) -{ - ADD_TYPE_FROM_LIST(kExecFlags_VarsNames, flagsType); -} - - -// ---------- Page ---------- - -// page flags -#define PF_CANCEL_ENABLE 4 -#define PF_LICENSE_FORCE_SELECTION 32 -#define PF_LICENSE_NO_FORCE_SELECTION 64 -#define PF_PAGE_EX 512 -#define PF_DIR_NO_BTN_DISABLE 1024 -/* -#define PF_LICENSE_SELECTED 1 -#define PF_NEXT_ENABLE 2 -#define PF_BACK_SHOW 8 -#define PF_LICENSE_STREAM 16 -#define PF_NO_NEXT_FOCUS 128 -#define PF_BACK_ENABLE 256 -*/ - -// page window proc -enum -{ - PWP_LICENSE, - PWP_SELCOM, - PWP_DIR, - PWP_INSTFILES, - PWP_UNINST, - PWP_COMPLETED, - PWP_CUSTOM -}; - -static const char * const kPageTypes[] = -{ - "license" - , "components" - , "directory" - , "instfiles" - , "uninstConfirm" - , "COMPLETED" - , "custom" -}; - -#define SET_FUNC_REF(x, flag) if ((Int32)(x) >= 0 && (x) < bh.Num) \ - { labels[x] = (labels[x] & ~CMD_REF_Page_Mask) | ((flag) | (pageIndex << CMD_REF_Page_NumShifts)); } - -// #define IDD_LICENSE 102 -#define IDD_LICENSE_FSRB 108 -#define IDD_LICENSE_FSCB 109 - -void CInArchive::AddPageOption1(UInt32 param, const char *name) -{ - if (param == 0) - return; - TabString(name); - AddParam(param); - NewLine(); -} - -void CInArchive::AddPageOption(const UInt32 *params, unsigned num, const char *name) -{ - num = GetNumParams(params, num); - if (num == 0) - return; - TabString(name); - AddParams(params, num); - NewLine(); -} - -void CInArchive::Separator() -{ - AddLF(); - AddCommentAndString("--------------------"); - AddLF(); -} - -void CInArchive::Space() -{ - Script += ' '; -} - -void CInArchive::Tab() -{ - Script += " "; -} - -void CInArchive::Tab(bool commented) -{ - Script += commented ? " ; " : " "; -} - -void CInArchive::BigSpaceComment() -{ - Script += " ; "; -} - -void CInArchive::SmallSpaceComment() -{ - Script += " ; "; -} - -void CInArchive::AddCommentAndString(const char *s) -{ - Script += "; "; - Script += s; -} - -void CInArchive::AddError(const char *s) -{ - BigSpaceComment(); - Script += "!!! ERROR: "; - Script += s; -} - -void CInArchive::AddErrorLF(const char *s) -{ - AddError(s); - AddLF(); -} - -void CInArchive::CommentOpen() -{ - AddStringLF("/*"); -} - -void CInArchive::CommentClose() -{ - AddStringLF("*/"); -} - -void CInArchive::AddLF() -{ - Script += CR_LF; -} - -void CInArchive::AddQuotes() -{ - Script += "\"\""; -} - -void CInArchive::TabString(const char *s) -{ - Tab(); - Script += s; -} - -void CInArchive::AddStringLF(const char *s) -{ - Script += s; - AddLF(); -} - -// ---------- Section ---------- - -static const char * const kSection_VarsNames[] = -{ - "Text" - , "InstTypes" - , "Flags" - , "Code" - , "CodeSize" - , "Size" // size in KB -}; - -void CInArchive::Add_SectOp(UInt32 opType) -{ - ADD_TYPE_FROM_LIST(kSection_VarsNames, opType); -} - -void CSection::Parse(const Byte *p) -{ - Name = Get32(p); - InstallTypes = Get32(p + 4); - Flags = Get32(p + 8); - StartCmdIndex = Get32(p + 12); - NumCommands = Get32(p + 16); - SizeKB = Get32(p + 20); -}; - -// used for section->flags -#define SF_SELECTED (1 << 0) -#define SF_SECGRP (1 << 1) -#define SF_SECGRPEND (1 << 2) -#define SF_BOLD (1 << 3) -#define SF_RO (1 << 4) -#define SF_EXPAND (1 << 5) -#define SF_PSELECTED (1 << 6) -#define SF_TOGGLED (1 << 7) -#define SF_NAMECHG (1 << 8) - -bool CInArchive::PrintSectionBegin(const CSection §, unsigned index) -{ - AString name; - if (sect.Flags & SF_BOLD) - name += '!'; - AString s2; - ReadString2(s2, sect.Name); - if (!IsInstaller) - { - if (!StringsAreEqualNoCase_Ascii(s2, "uninstall")) - name += "un."; - } - name += s2; - - if (sect.Flags & SF_SECGRPEND) - { - AddStringLF("SectionGroupEnd"); - return true; - } - - if (sect.Flags & SF_SECGRP) - { - Script += "SectionGroup"; - if (sect.Flags & SF_EXPAND) - Script += " /e"; - SpaceQuStr(name); - Script += " ; Section"; - AddParam_UInt(index); - NewLine(); - return true; - } - - Script += "Section"; - if ((sect.Flags & SF_SELECTED) == 0) - Script += " /o"; - if (!name.IsEmpty()) - SpaceQuStr(name); - - /* - if (!name.IsEmpty()) - Script += ' '; - else - */ - SmallSpaceComment(); - Script += "Section_"; - Add_UInt(index); - - /* - Script += " ; flags = "; - Add_Hex(Script, sect.Flags); - */ - - NewLine(); - - if (sect.SizeKB != 0) - { - // probably we must show AddSize, only if there is additional size. - Tab(); - AddCommentAndString("AddSize"); - AddParam_UInt(sect.SizeKB); - AddLF(); - } - - bool needSectionIn = - (sect.Name != 0 && sect.InstallTypes != 0) || - (sect.Name == 0 && sect.InstallTypes != 0xFFFFFFFF); - if (needSectionIn || (sect.Flags & SF_RO) != 0) - { - TabString("SectionIn"); - UInt32 instTypes = sect.InstallTypes; - for (int i = 0; i < 32; i++, instTypes >>= 1) - if ((instTypes & 1) != 0) - { - AddParam_UInt(i + 1); - } - if ((sect.Flags & SF_RO) != 0) - Script += " RO"; - AddLF(); - } - return false; -} - -void CInArchive::PrintSectionEnd() -{ - AddStringLF("SectionEnd"); - AddLF(); -} - -// static const unsigned kOnFuncShift = 4; - -void CInArchive::ClearLangComment() -{ - langStrIDs.Clear(); -} - -void CInArchive::PrintNumComment(const char *name, UInt32 value) -{ - // size_t len = Script.Len(); - AddCommentAndString(name); - Script += ": "; - Add_UInt(value); - AddLF(); - /* - len = Script.Len() - len; - char sz[16]; - ConvertUInt32ToString(value, sz); - len += MyStringLen(sz); - for (; len < 20; len++) - Space(); - AddStringLF(sz); - */ -} - - -void CInArchive::NewLine() -{ - if (!langStrIDs.IsEmpty()) - { - BigSpaceComment(); - for (unsigned i = 0; i < langStrIDs.Size() && i < 20; i++) - { - /* - if (i != 0) - Script += ' '; - */ - UInt32 langStr = langStrIDs[i]; - if (langStr >= _numLangStrings) - { - AddError("langStr"); - break; - } - UInt32 param = Get32(_mainLang + langStr * 4); - if (param != 0) - AddParam(param); - } - ClearLangComment(); - } - AddLF(); -} - -static const UInt32 kPageSize = 16 * 4; - -static const char * const k_SetOverwrite_Modes[] = -{ - "on" - , "off" - , "try" - , "ifnewer" - , "ifdiff" - // "lastused" -}; - - -void CInArchive::MessageBox_MB_Part(UInt32 param) -{ - { - UInt32 v = param & 0xF; - Script += " MB_"; - if (v < ARRAY_SIZE(k_MB_Buttons)) - Script += k_MB_Buttons[v]; - else - { - Script += "Buttons_"; - Add_UInt(v); - } - } - { - UInt32 icon = (param >> 4) & 0x7; - if (icon != 0) - { - Script += "|MB_"; - if (icon < ARRAY_SIZE(k_MB_Icons) && k_MB_Icons[icon] != 0) - Script += k_MB_Icons[icon]; - else - { - Script += "Icon_"; - Add_UInt(icon); - } - } - } - if ((param & 0x80) != 0) - Script += "|MB_USERICON"; - { - UInt32 defButton = (param >> 8) & 0xF; - if (defButton != 0) - { - Script += "|MB_DEFBUTTON"; - Add_UInt(defButton + 1); - } - } - { - UInt32 modal = (param >> 12) & 0x3; - if (modal == 1) Script += "|MB_SYSTEMMODAL"; - else if (modal == 2) Script += "|MB_TASKMODAL"; - else if (modal == 3) Script += "|0x3000"; - UInt32 flags = (param >> 14); - for (unsigned i = 0; i < ARRAY_SIZE(k_MB_Flags); i++) - if ((flags & (1 << i)) != 0) - { - Script += "|MB_"; - Script += k_MB_Flags[i]; - } - } -} - -#define GET_CMD_PARAM(ppp, index) Get32((ppp) + 4 + (index) * 4) - -static const Byte k_InitPluginDir_Commands[] = - { 13, 26, 31, 13, 19, 21, 11, 14, 25, 31, 1, 22, 4, 1 }; - -bool CInArchive::CompareCommands(const Byte *rawCmds, const Byte *sequence, size_t numCommands) -{ - for (UInt32 kkk = 0; kkk < numCommands; kkk++, rawCmds += kCmdSize) - if (GetCmd(Get32(rawCmds)) != sequence[kkk]) - return false; - return true; -} - -#endif - -static const UInt32 kSectionSize_base = 6 * 4; -static const UInt32 kSectionSize_8bit = kSectionSize_base + 1024; -static const UInt32 kSectionSize_16bit = kSectionSize_base + 1024 * 2; -static const UInt32 kSectionSize_16bit_Big = kSectionSize_base + 8196 * 2; -// 8196 is default string length in NSIS-Unicode since 2.37.3 - - -static void AddString(AString &dest, const char *src) -{ - dest.Add_Space_if_NotEmpty(); - dest += src; -} - -AString CInArchive::GetFormatDescription() const -{ - AString s = "NSIS-"; - char c; - if (IsPark()) - { - s += "Park-"; - c = '1'; - if (NsisType == k_NsisType_Park2) c = '2'; - else if (NsisType == k_NsisType_Park3) c = '3'; - } - else - { - c = '2'; - if (NsisType == k_NsisType_Nsis3) - c = '3'; - } - s += c; - if (IsNsis200) - s += ".00"; - else if (IsNsis225) - s += ".25"; - - if (IsUnicode) - AddString(s, "Unicode"); - if (LogCmdIsEnabled) - AddString(s, "log"); - if (BadCmd >= 0) - { - AddString(s, "BadCmd="); - UIntToString(s, BadCmd); - } - return s; -} - -#ifdef NSIS_SCRIPT - -unsigned CInArchive::GetNumSupportedCommands() const -{ - unsigned numCmds = IsPark() ? kNumCmds : kNumCmds - kNumAdditionalParkCmds; - if (!LogCmdIsEnabled) - numCmds--; - if (!IsUnicode) - numCmds -= 2; - return numCmds; -} - -#endif - -UInt32 CInArchive::GetCmd(UInt32 a) -{ - if (!IsPark()) - { - if (!LogCmdIsEnabled) - return a; - if (a < EW_SECTIONSET) - return a; - if (a == EW_SECTIONSET) - return EW_LOG; - return a - 1; - } - - if (a < EW_REGISTERDLL) - return a; - if (NsisType >= k_NsisType_Park2) - { - if (a == EW_REGISTERDLL) return EW_GETFONTVERSION; - a--; - } - if (NsisType >= k_NsisType_Park3) - { - if (a == EW_REGISTERDLL) return EW_GETFONTNAME; - a--; - } - if (a >= EW_FSEEK) - { - if (IsUnicode) - { - if (a == EW_FSEEK) return EW_FPUTWS; - if (a == EW_FSEEK + 1) return EW_FPUTWS + 1; - a -= 2; - } - - if (a >= EW_SECTIONSET && LogCmdIsEnabled) - { - if (a == EW_SECTIONSET) - return EW_LOG; - return a - 1; - } - if (a == EW_FPUTWS) - return EW_FINDPROC; - // if (a > EW_FPUTWS) return 0; - } - return a; -} - -void CInArchive::FindBadCmd(const CBlockHeader &bh, const Byte *p) -{ - BadCmd = -1; - - for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) - { - UInt32 id = GetCmd(Get32(p)); - if (id >= kNumCmds) - continue; - if (BadCmd >= 0 && id >= (unsigned)BadCmd) - continue; - unsigned i; - if (id == EW_GETLABELADDR || - id == EW_GETFUNCTIONADDR) - { - BadCmd = id; - continue; - } - for (i = 6; i != 0; i--) - { - UInt32 param = Get32(p + i * 4); - if (param != 0) - break; - } - if (id == EW_FINDPROC && i == 0) - { - BadCmd = id; - continue; - } - if (k_Commands[id].NumParams < i) - BadCmd = id; - } -} - -/* We calculate the number of parameters in commands to detect - layout of commands. It's not very good way. - If you know simpler and more robust way to detect Version and layout, - please write to 7-Zip forum */ - -void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p) -{ - bool strongPark = false; - bool strongNsis = false; - - { - const Byte *strData = _data + _stringsPos; - if (IsUnicode) - { - UInt32 num = NumStringChars; - for (UInt32 i = 0; i < num; i++) - { - if (Get16(strData + i * 2) == 0) - { - unsigned c2 = Get16(strData + 2 + i * 2); - // if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL) - if (c2 == NS_3_CODE_VAR) - { - // it can be TXT/RTF string with marker char (1 or 2). so we must next char - // const wchar_t *p2 = (const wchar_t *)(strData + i * 2 + 2); - // p2 = p2; - if ((Get16(strData + 3 + i * 2) & 0x8000) != 0) - { - NsisType = k_NsisType_Nsis3; - strongNsis = true; - break; - } - } - } - } - if (!strongNsis) - { - NsisType = k_NsisType_Park1; - strongPark = true; - } - } - else - { - UInt32 num = NumStringChars; - for (UInt32 i = 0; i < num; i++) - { - if (strData[i] == 0) - { - Byte c2 = strData[i + 1]; - // it can be TXT/RTF with marker char (1 or 2). so we must check next char - // for marker=1 (txt) - if (c2 == NS_3_CODE_VAR) - // if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL && c2 != 1) - { - if ((strData[i+ 2] & 0x80) != 0) - { - // const char *p2 = (const char *)(strData + i + 1); - // p2 = p2; - NsisType = k_NsisType_Nsis3; - strongNsis = true; - break; - } - } - } - } - } - } - - if (NsisType == k_NsisType_Nsis2 && !IsUnicode) - { - const Byte *p2 = p; - - for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p2 += kCmdSize) - { - UInt32 cmd = GetCmd(Get32(p2)); - if (cmd != EW_GETDLGITEM && - cmd != EW_ASSIGNVAR) - continue; - - UInt32 params[kNumCommandParams]; - for (unsigned i = 0; i < kNumCommandParams; i++) - params[i] = Get32(p2 + 4 + 4 * i); - - if (cmd == EW_GETDLGITEM) - { - // we can use also EW_SETCTLCOLORS - if (IsVarStr(params[1], kVar_HWNDPARENT_225)) - { - IsNsis225 = true; - if (params[0] == kVar_Spec_OUTDIR_225) - { - IsNsis200 = true; - break; - } - } - } - else // if (cmd == EW_ASSIGNVAR) - { - if (params[0] == kVar_Spec_OUTDIR_225 && - params[2] == 0 && - params[3] == 0 && - IsVarStr(params[1], kVar_OUTDIR)) - IsNsis225 = true; - } - } - } - - bool parkVer_WasDetected = false; - - if (!strongNsis && !IsNsis225 && !IsNsis200) - { - // it must be before FindBadCmd(bh, p); - unsigned mask = 0; - - unsigned numInsertMax = IsUnicode ? 4 : 2; - - const Byte *p2 = p; - - for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p2 += kCmdSize) - { - UInt32 cmd = Get32(p2); // we use original (not converted) command - - if (cmd < EW_WRITEUNINSTALLER || - cmd > EW_WRITEUNINSTALLER + numInsertMax) - continue; - - UInt32 params[kNumCommandParams]; - for (unsigned i = 0; i < kNumCommandParams; i++) - params[i] = Get32(p2 + 4 + 4 * i); - - if (params[4] != 0 || - params[5] != 0 || - params[0] <= 1 || - params[3] <= 1) - continue; - - UInt32 altParam = params[3]; - if (!IsGoodString(params[0]) || - !IsGoodString(altParam)) - continue; - - UInt32 additional = 0; - if (GetVarIndexFinished(altParam, '\\', additional) != kVar_INSTDIR) - continue; - if (AreTwoParamStringsEqual(altParam + additional, params[0])) - { - unsigned numInserts = cmd - EW_WRITEUNINSTALLER; - mask |= (1 << numInserts); - } - } - - if (mask == 1) - { - parkVer_WasDetected = true; // it can be original NSIS or Park-1 - } - else if (mask != 0) - { - ENsisType newType = NsisType; - if (IsUnicode) - switch (mask) - { - case (1 << 3): newType = k_NsisType_Park2; break; - case (1 << 4): newType = k_NsisType_Park3; break; - } - else - switch (mask) - { - case (1 << 1): newType = k_NsisType_Park2; break; - case (1 << 2): newType = k_NsisType_Park3; break; - } - if (newType != NsisType) - { - parkVer_WasDetected = true; - NsisType = newType; - } - } - } - - FindBadCmd(bh, p); - - /* - if (strongNsis) - return; - */ - - if (BadCmd < EW_REGISTERDLL) - return; - - /* - // in ANSI archive we don't check Park and log version - if (!IsUnicode) - return; - */ - - // We can support Park-ANSI archives, if we remove if (strongPark) check - if (strongPark && !parkVer_WasDetected) - { - if (BadCmd < EW_SECTIONSET) - { - NsisType = k_NsisType_Park3; - LogCmdIsEnabled = true; // version 3 is provided with log enabled - FindBadCmd(bh, p); - if (BadCmd > 0 && BadCmd < EW_SECTIONSET) - { - NsisType = k_NsisType_Park2; - LogCmdIsEnabled = false; - FindBadCmd(bh, p); - if (BadCmd > 0 && BadCmd < EW_SECTIONSET) - { - NsisType = k_NsisType_Park1; - FindBadCmd(bh, p); - } - } - } - } - - if (BadCmd >= EW_SECTIONSET) - { - LogCmdIsEnabled = !LogCmdIsEnabled; - FindBadCmd(bh, p); - if (BadCmd >= EW_SECTIONSET && LogCmdIsEnabled) - { - LogCmdIsEnabled = false; - FindBadCmd(bh, p); - } - } -} - -Int32 CInArchive::GetVarIndex(UInt32 strPos) const -{ - if (strPos >= NumStringChars) - return -1; - - if (IsUnicode) - { - if (NumStringChars - strPos < 3 * 2) - return -1; - const Byte *p = _data + _stringsPos + strPos * 2; - unsigned code = Get16(p); - if (IsPark()) - { - if (code != PARK_CODE_VAR) - return -1; - UInt32 n = Get16(p + 2); - if (n == 0) - return -1; - CONVERT_NUMBER_PARK(n); - return (Int32)n; - } - - // NSIS-3 - { - if (code != NS_3_CODE_VAR) - return -1; - UInt32 n = Get16(p + 2); - if (n == 0) - return -1; - CONVERT_NUMBER_NS_3_UNICODE(n); - return (Int32)n; - } - } - - if (NumStringChars - strPos < 4) - return -1; - - const Byte *p = _data + _stringsPos + strPos; - unsigned c = *p; - if (NsisType == k_NsisType_Nsis3) - { - if (c != NS_3_CODE_VAR) - return -1; - } - else if (c != NS_CODE_VAR) - return -1; - - unsigned c0 = p[1]; - if (c0 == 0) - return -1; - unsigned c1 = p[2]; - if (c1 == 0) - return -1; - return DECODE_NUMBER_FROM_2_CHARS(c0, c1); -} - -Int32 CInArchive::GetVarIndex(UInt32 strPos, UInt32 &resOffset) const -{ - resOffset = 0; - Int32 varIndex = GetVarIndex(strPos); - if (varIndex < 0) - return varIndex; - if (IsUnicode) - { - if (NumStringChars - strPos < 2 * 2) - return -1; - resOffset = 2; - } - else - { - if (NumStringChars - strPos < 3) - return -1; - resOffset = 3; - } - return varIndex; -} - -Int32 CInArchive::GetVarIndexFinished(UInt32 strPos, Byte endChar, UInt32 &resOffset) const -{ - resOffset = 0; - Int32 varIndex = GetVarIndex(strPos); - if (varIndex < 0) - return varIndex; - if (IsUnicode) - { - if (NumStringChars - strPos < 3 * 2) - return -1; - const Byte *p = _data + _stringsPos + strPos * 2; - if (Get16(p + 4) != endChar) - return -1; - resOffset = 3; - } - else - { - if (NumStringChars - strPos < 4) - return -1; - const Byte *p = _data + _stringsPos + strPos; - if (p[3] != endChar) - return -1; - resOffset = 4; - } - return varIndex; -} - -bool CInArchive::IsVarStr(UInt32 strPos, UInt32 varIndex) const -{ - if (varIndex > (UInt32)0x7FFF) - return false; - UInt32 resOffset; - return GetVarIndexFinished(strPos, 0, resOffset) == (Int32)varIndex; -} - -bool CInArchive::IsAbsolutePathVar(UInt32 strPos) const -{ - Int32 varIndex = GetVarIndex(strPos); - if (varIndex < 0) - return false; - switch (varIndex) - { - case kVar_INSTDIR: - case kVar_EXEDIR: - case kVar_TEMP: - case kVar_PLUGINSDIR: - return true; - } - return false; -} - -#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z') - -// We use same check as in NSIS decoder -bool IsDrivePath(const wchar_t *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; } -bool IsDrivePath(const char *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; } - -static bool IsAbsolutePath(const wchar_t *s) -{ - return - s[0] == WCHAR_PATH_SEPARATOR && - s[1] == WCHAR_PATH_SEPARATOR || - IsDrivePath(s); -} - -static bool IsAbsolutePath(const char *s) -{ - return - s[0] == CHAR_PATH_SEPARATOR && - s[1] == CHAR_PATH_SEPARATOR || - IsDrivePath(s); -} - -void CInArchive::SetItemName(CItem &item, UInt32 strPos) -{ - ReadString2_Raw(strPos); - bool isAbs = IsAbsolutePathVar(strPos); - if (IsUnicode) - { - item.NameU = Raw_UString; - if (!isAbs && !IsAbsolutePath(Raw_UString)) - item.Prefix = UPrefixes.Size() - 1; - } - else - { - item.NameA = Raw_AString; - if (!isAbs && !IsAbsolutePath(Raw_AString)) - item.Prefix = APrefixes.Size() - 1; - } -} - -HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) -{ - #ifdef NSIS_SCRIPT - CDynLimBuf &s = Script; - - CObjArray labels; - labels.Alloc(bh.Num); - memset(labels, 0, bh.Num * sizeof(UInt32)); - - { - const Byte *p = _data; - UInt32 i; - for (i = 0; i < numOnFunc; i++) - { - UInt32 func = Get32(p + onFuncOffset + 4 * i); - if (func < bh.Num) - labels[func] = (labels[func] & ~CMD_REF_OnFunc_Mask) | (CMD_REF_OnFunc | (i << CMD_REF_OnFunc_NumShifts)); - } - } - - /* - { - for (int i = 0; i < OnFuncs.Size(); i++) - { - UInt32 address = OnFuncs[i] >> kOnFuncShift; - if (address < bh.Num) - } - } - */ - - if (bhPages.Num != 0) - { - Separator(); - PrintNumComment("PAGES", bhPages.Num); - - if (bhPages.Num > (1 << 12) - || bhPages.Offset > _size - || bhPages.Num * kPageSize > _size - bhPages.Offset) - { - AddErrorLF("Pages error"); - } - else - { - - AddLF(); - const Byte *p = _data + bhPages.Offset; - - for (UInt32 pageIndex = 0; pageIndex < bhPages.Num; pageIndex++, p += kPageSize) - { - UInt32 dlgID = Get32(p); - UInt32 wndProcID = Get32(p + 4); - UInt32 preFunc = Get32(p + 8); - UInt32 showFunc = Get32(p + 12); - UInt32 leaveFunc = Get32(p + 16); - UInt32 flags = Get32(p + 20); - UInt32 caption = Get32(p + 24); - // UInt32 back = Get32(p + 28); - UInt32 next = Get32(p + 32); - // UInt32 clickNext = Get32(p + 36); - // UInt32 cancel = Get32(p + 40); - UInt32 params[5]; - for (int i = 0; i < 5; i++) - params[i] = Get32(p + 44 + 4 * i); - - SET_FUNC_REF(preFunc, CMD_REF_Pre); - SET_FUNC_REF(showFunc, CMD_REF_Show); - SET_FUNC_REF(leaveFunc, CMD_REF_Leave); - - if (wndProcID == PWP_COMPLETED) - CommentOpen(); - - AddCommentAndString("Page "); - Add_UInt(pageIndex); - AddLF(); - - if (flags & PF_PAGE_EX) - { - s += "PageEx "; - if (!IsInstaller) - s += "un."; - } - else - s += IsInstaller ? "Page " : "UninstPage "; - - if (wndProcID < ARRAY_SIZE(kPageTypes)) - s += kPageTypes[wndProcID]; - else - Add_UInt(wndProcID); - - - bool needCallbacks = ( - (Int32)preFunc >= 0 || - (Int32)showFunc >= 0 || - (Int32)leaveFunc >= 0); - - if (flags & PF_PAGE_EX) - { - AddLF(); - if (needCallbacks) - TabString("PageCallbacks"); - } - - if (needCallbacks) - { - AddParam_Func(labels, preFunc); // it's creator_function for PWP_CUSTOM - if (wndProcID != PWP_CUSTOM) - { - AddParam_Func(labels, showFunc); - } - AddParam_Func(labels, leaveFunc); - } - - if ((flags & PF_PAGE_EX) == 0) - { - // AddOptionalParam(caption); - if (flags & PF_CANCEL_ENABLE) - s += " /ENABLECANCEL"; - AddLF(); - } - else - { - AddLF(); - AddPageOption1(caption, "Caption"); - } - - if (wndProcID == PWP_LICENSE) - { - if ((flags & PF_LICENSE_NO_FORCE_SELECTION) != 0 || - (flags & PF_LICENSE_FORCE_SELECTION) != 0) - { - TabString("LicenseForceSelection "); - if (flags & PF_LICENSE_NO_FORCE_SELECTION) - s += "off"; - else - { - if (dlgID == IDD_LICENSE_FSCB) - s += "checkbox"; - else if (dlgID == IDD_LICENSE_FSRB) - s += "radiobuttons"; - else - Add_UInt(dlgID); - AddOptionalParams(params + 2, 2); - } - NewLine(); - } - - if (params[0] != 0 || next != 0) - { - TabString("LicenseText"); - AddParam(params[0]); - AddOptionalParam(next); - NewLine(); - } - if (params[1] != 0) - { - TabString("LicenseData"); - if ((Int32)params[1] < 0) - AddParam(params[1]); - else - AddLicense(params[1], -1); - ClearLangComment(); - NewLine(); - } - } - else if (wndProcID == PWP_SELCOM) - AddPageOption(params, 3, "ComponentsText"); - else if (wndProcID == PWP_DIR) - { - AddPageOption(params, 4, "DirText"); - if (params[4] != 0) - { - TabString("DirVar"); - AddParam_Var(params[4] - 1); - AddLF(); - } - if (flags & PF_DIR_NO_BTN_DISABLE) - { - TabString("DirVerify leave"); - AddLF(); - } - - } - else if (wndProcID == PWP_INSTFILES) - { - AddPageOption1(params[2], "CompletedText"); - AddPageOption1(params[1], "DetailsButtonText"); - } - else if (wndProcID == PWP_UNINST) - { - if (params[4] != 0) - { - TabString("DirVar"); - AddParam_Var(params[4] - 1); - AddLF(); - } - AddPageOption(params, 2, "UninstallText"); - } - - if (flags & PF_PAGE_EX) - { - s += "PageExEnd"; - NewLine(); - } - if (wndProcID == PWP_COMPLETED) - CommentClose(); - NewLine(); - } - } - } - - CObjArray Sections; - - { - Separator(); - PrintNumComment("SECTIONS", bhSections.Num); - PrintNumComment("COMMANDS", bh.Num); - AddLF(); - - if (bhSections.Num > (1 << 15) - // || bhSections.Offset > _size - // || (bhSections.Num * SectionSize > _size - bhSections.Offset) - ) - { - AddErrorLF("Sections error"); - } - else if (bhSections.Num != 0) - { - Sections.Alloc((unsigned)bhSections.Num); - const Byte *p = _data + bhSections.Offset; - for (UInt32 i = 0; i < bhSections.Num; i++, p += SectionSize) - { - CSection §ion = Sections[i]; - section.Parse(p); - if (section.StartCmdIndex < bh.Num) - labels[section.StartCmdIndex] |= CMD_REF_Section; - } - } - } - - #endif - - const Byte *p; - UInt32 kkk; - - #ifdef NSIS_SCRIPT - - p = _data + bh.Offset; - - for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) - { - UInt32 commandId = GetCmd(Get32(p)); - UInt32 mask; - switch (commandId) - { - case EW_NOP: mask = 1 << 0; break; - case EW_IFFILEEXISTS: mask = 3 << 1; break; - case EW_IFFLAG: mask = 3 << 0; break; - case EW_MESSAGEBOX: mask = 5 << 3; break; - case EW_STRCMP: mask = 3 << 2; break; - case EW_INTCMP: mask = 7 << 2; break; - case EW_ISWINDOW: mask = 3 << 1; break; - case EW_CALL: - { - if (Get32(p + 4 + 4) == 1) // it's Call :Label - { - mask = 1 << 0; - break; - } - UInt32 param0 = Get32(p + 4); - if ((Int32)param0 > 0) - labels[param0 - 1] |= CMD_REF_Call; - continue; - } - default: continue; - } - for (unsigned i = 0; mask != 0; i++, mask >>= 1) - if (mask & 1) - { - UInt32 param = Get32(p + 4 + 4 * i); - if ((Int32)param > 0 && (Int32)param <= (Int32)bh.Num) - labels[param - 1] |= CMD_REF_Goto; - } - } - - int InitPluginsDir_Start = -1; - int InitPluginsDir_End = -1; - p = _data + bh.Offset; - for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) - { - UInt32 flg = labels[kkk]; - /* - if (IsFunc(flg)) - { - AddLF(); - for (int i = 0; i < 14; i++) - { - UInt32 commandId = GetCmd(Get32(p + kCmdSize * i)); - s += ", "; - UIntToString(s, commandId); - } - AddLF(); - } - */ - if (IsFunc(flg) - && bh.Num - kkk >= ARRAY_SIZE(k_InitPluginDir_Commands) - && CompareCommands(p, k_InitPluginDir_Commands, ARRAY_SIZE(k_InitPluginDir_Commands))) - { - InitPluginsDir_Start = kkk; - InitPluginsDir_End = kkk + ARRAY_SIZE(k_InitPluginDir_Commands); - labels[kkk] |= CMD_REF_InitPluginDir; - break; - } - } - - #endif - - // AString prefixA_Temp; - // UString prefixU_Temp; - - - // const UInt32 kFindS = 158; - - #ifdef NSIS_SCRIPT - - UInt32 curSectionIndex = 0; - // UInt32 lastSectionEndCmd = 0xFFFFFFFF; - bool sectionIsOpen = false; - // int curOnFunc = 0; - bool onFuncIsOpen = false; - - /* - for (unsigned yyy = 0; yyy + 3 < _data.Size(); yyy++) - { - UInt32 val = Get32(_data + yyy); - if (val == kFindS) - val = val; - } - */ - - UInt32 overwrite_State = 0; // "SetOverwrite on" - Int32 allowSkipFiles_State = -1; // -1: on, -2: off, >=0 : RAW value - UInt32 endCommentIndex = 0; - - unsigned numSupportedCommands = GetNumSupportedCommands(); - - #endif - - p = _data + bh.Offset; - - UString spec_outdir_U; - AString spec_outdir_A; - - UPrefixes.Add(L"$INSTDIR"); - APrefixes.Add("$INSTDIR"); - - p = _data + bh.Offset; - - unsigned spec_outdir_VarIndex = IsNsis225 ? - kVar_Spec_OUTDIR_225 : - kVar_Spec_OUTDIR; - - for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) - { - UInt32 commandId; - UInt32 params[kNumCommandParams]; - commandId = GetCmd(Get32(p)); - { - for (unsigned i = 0; i < kNumCommandParams; i++) - { - params[i] = Get32(p + 4 + 4 * i); - /* - if (params[i] == kFindS) - i = i; - */ - } - } - - #ifdef NSIS_SCRIPT - - bool IsSectionGroup = false; - while (curSectionIndex < bhSections.Num) - { - const CSection § = Sections[curSectionIndex]; - if (sectionIsOpen) - { - if (sect.StartCmdIndex + sect.NumCommands + 1 != kkk) - break; - PrintSectionEnd(); - sectionIsOpen = false; - // lastSectionEndCmd = kkk; - curSectionIndex++; - continue; - } - if (sect.StartCmdIndex != kkk) - break; - if (PrintSectionBegin(sect, curSectionIndex)) - { - IsSectionGroup = true; - curSectionIndex++; - // do we need to flush prefixes in new section? - // FlushOutPathPrefixes(); - } - else - sectionIsOpen = true; - } - - /* - if (curOnFunc < OnFuncs.Size()) - { - if ((OnFuncs[curOnFunc] >> kOnFuncShift) == kkk) - { - s += "Function .on"; - s += kOnFunc[OnFuncs[curOnFunc++] & ((1 << kOnFuncShift) - 1)]; - AddLF(); - onFuncIsOpen = true; - } - } - */ - - if (labels[kkk] != 0 && labels[kkk] != CMD_REF_Section) - { - UInt32 flg = labels[kkk]; - if (IsFunc(flg)) - { - if ((int)kkk == InitPluginsDir_Start) - CommentOpen(); - - onFuncIsOpen = true; - s += "Function "; - Add_FuncName(labels, kkk); - if (IsPageFunc(flg)) - { - BigSpaceComment(); - s += "Page "; - Add_UInt((flg & CMD_REF_Page_Mask) >> CMD_REF_Page_NumShifts); - // if (flg & CMD_REF_Creator) s += ", Creator"; - if (flg & CMD_REF_Leave) s += ", Leave"; - if (flg & CMD_REF_Pre) s += ", Pre"; - if (flg & CMD_REF_Show) s += ", Show"; - } - AddLF(); - } - if (flg & CMD_REF_Goto) - { - Add_LabelName(kkk); - s += ':'; - AddLF(); - } - } - - if (commandId != EW_RET) - { - Tab(kkk < endCommentIndex); - } - - /* - UInt32 originalCmd = Get32(p); - if (originalCmd >= EW_REGISTERDLL) - { - UIntToString(s, originalCmd); - s += ' '; - if (originalCmd != commandId) - { - UIntToString(s, commandId); - s += ' '; - } - } - */ - - unsigned numSkipParams = 0; - - if (commandId < ARRAY_SIZE(k_Commands) && commandId < numSupportedCommands) - { - numSkipParams = k_Commands[commandId].NumParams; - const char *sz = k_CommandNames[commandId]; - if (sz) - s += sz; - } - else - { - s += "Command"; - Add_UInt(commandId); - /* We don't show wrong commands that use overlapped ids. - So we change commandId to big value */ - if (commandId < (1 << 12)) - commandId += (1 << 12); - } - - #endif - - switch (commandId) - { - case EW_CREATEDIR: - { - bool isSetOutPath = (params[1] != 0); - - if (isSetOutPath) - { - UInt32 par0 = params[0]; - - UInt32 resOffset; - Int32 idx = GetVarIndex(par0, resOffset); - if (idx == (Int32)spec_outdir_VarIndex || - idx == kVar_OUTDIR) - par0 += resOffset; - - ReadString2_Raw(par0); - - if (IsUnicode) - { - if (idx == (Int32)spec_outdir_VarIndex) - Raw_UString.Insert(0, spec_outdir_U); - else if (idx == kVar_OUTDIR) - Raw_UString.Insert(0, UPrefixes.Back()); - UPrefixes.Add(Raw_UString); - } - else - { - if (idx == (Int32)spec_outdir_VarIndex) - Raw_AString.Insert(0, spec_outdir_A); - else if (idx == kVar_OUTDIR) - Raw_AString.Insert(0, APrefixes.Back()); - APrefixes.Add(Raw_AString); - } - } - - #ifdef NSIS_SCRIPT - s += isSetOutPath ? "SetOutPath" : "CreateDirectory"; - AddParam(params[0]); - #endif - - break; - } - - - case EW_ASSIGNVAR: - { - if (params[0] == spec_outdir_VarIndex) - { - spec_outdir_U.Empty(); - spec_outdir_A.Empty(); - if (IsVarStr(params[1], kVar_OUTDIR) && - params[2] == 0 && - params[3] == 0) - { - if (IsVarStr(params[1], kVar_OUTDIR)) - { - spec_outdir_U = UPrefixes.Back(); // outdir_U; - spec_outdir_A = APrefixes.Back();// outdir_A; - } - } - } - - #ifdef NSIS_SCRIPT - - if (params[2] == 0 && - params[3] == 0 && - params[4] == 0 && - params[5] == 0 && - params[1] != 0 && - params[1] < NumStringChars) - { - char sz[16]; - ConvertUInt32ToString(kkk + 1, sz); - if (IsDirectString_Equal(params[1], sz)) - { - // we suppose that it's GetCurrentAddress command - // but there is probability that it's StrCpy command - s += "GetCurrentAddress"; - AddParam_Var(params[0]); - SmallSpaceComment(); - } - } - s += "StrCpy"; - AddParam_Var(params[0]); - AddParam(params[1]); - - AddOptionalParams(params + 2, 2); - - #endif - - break; - } - - case EW_EXTRACTFILE: - { - CItem &item = Items.AddNew(); - - UInt32 par1 = params[1]; - - SetItemName(item, par1); - - item.Pos = params[2]; - item.MTime.dwLowDateTime = params[3]; - item.MTime.dwHighDateTime = params[4]; - - #ifdef NSIS_SCRIPT - - { - UInt32 overwrite = params[0] & 0x7; - if (overwrite != overwrite_State) - { - s += "SetOverwrite "; - ADD_TYPE_FROM_LIST(k_SetOverwrite_Modes, overwrite); - overwrite_State = overwrite; - AddLF(); - Tab(kkk < endCommentIndex); - } - } - - { - UInt32 nsisMB = params[0] >> 3; - if ((Int32)nsisMB != allowSkipFiles_State) - { - UInt32 mb = nsisMB & ((1 << 20) - 1); // old/new NSIS - UInt32 b1 = nsisMB >> 21; // NSIS 2.06+ - UInt32 b2 = nsisMB >> 20; // NSIS old - Int32 asf = (Int32)nsisMB; - if (mb == (MY__MB_ABORTRETRYIGNORE | MY__MB_ICONSTOP) && (b1 == MY__IDIGNORE || b2 == MY__IDIGNORE)) - asf = -1; - else if (mb == (MY__MB_RETRYCANCEL | MY__MB_ICONSTOP) && (b1 == MY__IDCANCEL || b2 == MY__IDCANCEL)) - asf = -2; - else - { - AddCommentAndString("AllowSkipFiles [Overwrite]: "); - MessageBox_MB_Part(mb); - if (b1 != 0) - { - s += " /SD"; - Add_ButtonID(b1); - } - } - if (asf != allowSkipFiles_State) - { - if (asf < 0) - { - s += "AllowSkipFiles "; - s += (asf == -1) ? "on" : "off"; - } - AddLF(); - Tab(kkk < endCommentIndex); - } - allowSkipFiles_State = (Int32)nsisMB; - } - } - - s += "File"; - AddParam(params[1]); - - /* params[5] contains link to LangString (negative value) - with NLF_FILE_ERROR or NLF_FILE_ERROR_NOIGNORE message for MessageBox. - We don't need to print it. */ - - #endif - - if (IsVarStr(par1, 10)) // is $R0 - { - // we parse InstallLib macro in 7-Zip installers - unsigned kBackOffset = 28; - if (kkk > 1) - { - // detect old version of InstallLib macro - if (Get32(p - 1 * kCmdSize) == EW_NOP) // goto command - kBackOffset -= 2; - } - - if (kkk > kBackOffset) - { - const Byte *p2 = p - kBackOffset * kCmdSize; - UInt32 cmd = Get32(p2); - if (cmd == EW_ASSIGNVAR) - { - UInt32 pars[6]; - for (int i = 0; i < 6; i++) - pars[i] = Get32(p2 + i * 4 + 4); - if (pars[0] == 10 + 4 && pars[2] == 0 && pars[3] == 0) // 10 + 4 means $R4 - { - item.Prefix = -1; - item.NameA.Empty(); - item.NameU.Empty(); - SetItemName(item, pars[1]); - // maybe here we can restore original item name, if new name is empty - } - } - } - } - /* UInt32 allowIgnore = params[5]; */ - break; - } - - case EW_SETFILEATTRIBUTES: - { - if (kkk > 0 && Get32(p - kCmdSize) == EW_EXTRACTFILE) - { - if (params[0] == Get32(p - kCmdSize + 4 + 4 * 1)) // compare with PrevCmd.Params[1] - { - CItem &item = Items.Back(); - item.Attrib_Defined = true; - item.Attrib = params[1]; - } - } - #ifdef NSIS_SCRIPT - AddParam(params[0]); - Space(); - FlagsToString2(s, g_WinAttrib, ARRAY_SIZE(g_WinAttrib), params[1]); - #endif - break; - } - - case EW_WRITEUNINSTALLER: - { - /* NSIS 2.29+ writes alternative path to params[3] - "$INSTDIR\\" + Str(params[0]) - NSIS installer uses alternative path, if main path - from params[0] is not absolute path */ - - bool pathOk = (params[0] > 0) && IsGoodString(params[0]); - - if (!pathOk) - { - #ifdef NSIS_SCRIPT - AddError("bad path"); - #endif - break; - } - - bool altPathOk = true; - - UInt32 altParam = params[3]; - if (altParam != 0) - { - altPathOk = false; - UInt32 additional = 0; - if (GetVarIndexFinished(altParam, '\\', additional) == kVar_INSTDIR) - altPathOk = AreTwoParamStringsEqual(altParam + additional, params[0]); - } - - - #ifdef NSIS_SCRIPT - - AddParam(params[0]); - - /* - for (int i = 1; i < 3; i++) - AddParam_UInt(params[i]); - */ - - if (params[3] != 0) - { - SmallSpaceComment(); - AddParam(params[3]); - } - - #endif - - if (!altPathOk) - { - #ifdef NSIS_SCRIPT - AddError("alt path error"); - #endif - } - - if (BadCmd >= 0 && BadCmd <= EW_WRITEUNINSTALLER) - { - /* We don't cases with incorrect installer commands. - Such bad installer item can break unpacking for other items. */ - #ifdef NSIS_SCRIPT - AddError("SKIP possible BadCmd"); - #endif - break; - } - - CItem &item = Items.AddNew();; - - SetItemName(item, params[0]); - - item.Pos = params[1]; - item.PatchSize = params[2]; - item.IsUninstaller = true; - - /* - // we can add second time to test the code - CItem item2 = item; - item2.NameU += L'2'; - item2.NameA += '2'; - Items.Add(item2); - */ - - break; - } - - #ifdef NSIS_SCRIPT - - case EW_RET: - { - // bool needComment = false; - if (onFuncIsOpen) - { - if (kkk == bh.Num - 1 || IsProbablyEndOfFunc(labels[kkk + 1])) - { - AddStringLF("FunctionEnd"); - - if ((int)kkk + 1 == InitPluginsDir_End) - CommentClose(); - AddLF(); - onFuncIsOpen = false; - // needComment = true; - break; - } - } - // if (!needComment) - if (IsSectionGroup) - break; - if (sectionIsOpen) - { - const CSection § = Sections[curSectionIndex]; - if (sect.StartCmdIndex + sect.NumCommands == kkk) - { - PrintSectionEnd(); - sectionIsOpen = false; - curSectionIndex++; - break; - } - - // needComment = true; - // break; - } - - /* - if (needComment) - s += " ;"; - */ - TabString("Return"); - AddLF(); - break; - } - - case EW_NOP: - { - if (params[0] == 0) - s += "Nop"; - else - { - s += "Goto"; - Add_GotoVar(params[0]); - } - break; - } - - case EW_ABORT: - { - AddOptionalParam(params[0]); - break; - } - - case EW_CALL: - { - if (kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_EXTRACTFILE) - { - UInt32 par1 = GET_CMD_PARAM(p + kCmdSize, 1); - - UInt32 pluginPar = 0; - - if (GetVarIndexFinished(par1, '\\', pluginPar) == kVar_PLUGINSDIR) - { - pluginPar += par1; - UInt32 commandId2 = GetCmd(Get32(p + kCmdSize * 2)); - if (commandId2 == EW_SETFLAG || commandId2 == EW_UPDATETEXT) - { - UInt32 i; - for (i = kkk + 3; i < bh.Num; i++) - { - const Byte *pCmd = p + kCmdSize * (i - kkk); - UInt32 commandId3 = GetCmd(Get32(pCmd)); - if (commandId3 != EW_PUSHPOP - || GET_CMD_PARAM(pCmd, 1) != 0 - || GET_CMD_PARAM(pCmd, 2) != 0) - break; - } - if (i < bh.Num) - { - const Byte *pCmd = p + kCmdSize * (i - kkk); - - // UInt32 callDll_Param = GET_CMD_PARAM(pCmd, 0); - // UInt32 file_Param = GET_CMD_PARAM(p + kCmdSize, 1); - - if (GetCmd(Get32(pCmd)) == EW_REGISTERDLL && - AreTwoParamStringsEqual( - GET_CMD_PARAM(pCmd, 0), - GET_CMD_PARAM(p + kCmdSize, 1))) - { - // params[4] = 1 means GetModuleHandle attempt before default LoadLibraryEx; - /// new versions of NSIS use params[4] = 1 for Plugin command - if (GET_CMD_PARAM(pCmd, 2) == 0 - // && GET_CMD_PARAM(pCmd, 4) != 0 - ) - { - { - AString s2; - ReadString2(s2, pluginPar); - if (s2.Len() >= 4 && - StringsAreEqualNoCase_Ascii(s2.RightPtr(4), ".dll")) - s2.DeleteFrom(s2.Len() - 4); - s2 += "::"; - AString func; - ReadString2(func, GET_CMD_PARAM(pCmd, 1)); - s2 += func; - Add_QuStr(s2); - - if (GET_CMD_PARAM(pCmd, 3) == 1) - s += " /NOUNLOAD"; - - for (UInt32 j = i - 1; j >= kkk + 3; j--) - { - const Byte *pCmd = p + kCmdSize * (j - kkk); - AddParam(GET_CMD_PARAM(pCmd, 0)); - } - NewLine(); - Tab(true); - endCommentIndex = i + 1; - } - } - } - } - } - } - } - { - const Byte *nextCmd = p + kCmdSize; - UInt32 commandId2 = GetCmd(Get32(nextCmd)); - if (commandId2 == EW_SETFLAG - && GET_CMD_PARAM(nextCmd, 0) == k_ExecFlags_DetailsPrint - && GET_CMD_PARAM(nextCmd, 2) != 0) // is "lastused" - // || commandId2 == EW_UPDATETEXT) - { - if ((Int32)params[0] > 0 && labels[params[0] - 1] & CMD_REF_InitPluginDir) - { - s += "InitPluginsDir"; - AddLF(); - Tab(true); - endCommentIndex = kkk + 2; - } - } - } - - s += "Call "; - if ((Int32)params[0] < 0) - Add_Var(-((Int32)params[0] + 1)); - else if (params[0] == 0) - s += '0'; - else - { - UInt32 val = params[0] - 1; - if (params[1] == 1) // it's Call :Label - { - s += ':'; - Add_LabelName(val); - } - else // if (params[1] == 0) // it's Call Func - Add_FuncName(labels, val); - } - break; - } - - case EW_UPDATETEXT: - case EW_SLEEP: - { - AddParam(params[0]); - break; - } - - case EW_CHDETAILSVIEW: - { - if (params[0] == MY__SW_SHOWNA && params[1] == MY__SW_HIDE) s += " show"; - else if (params[1] == MY__SW_SHOWNA && params[0] == MY__SW_HIDE) s += " hide"; - else - for (int i = 0; i < 2; i++) - { - Space(); - Add_ShowWindow_Cmd(params[i]); - } - break; - } - - case EW_IFFILEEXISTS: - { - AddParam(params[0]); - Add_GotoVars2(¶ms[1]); - break; - } - - case EW_SETFLAG: - { - AString temp; - ReadString2(temp, params[1]); - if (params[0] == k_ExecFlags_Errors && params[2] == 0) - { - s += (temp.Len() == 1 && temp[0] == '0') ? "ClearErrors" : "SetErrors"; - break; - } - s += "Set"; - Add_ExecFlags(params[0]); - - if (params[2] != 0) - { - s += " lastused"; - break; - } - UInt32 v; - if (StringToUInt32(temp, v)) - { - const char *s2 = NULL; - switch (params[0]) - { - case k_ExecFlags_AutoClose: - case k_ExecFlags_RebootFlag: - if (v < 2) s2 = (v == 0) ? "false" : "true"; break; - case k_ExecFlags_ShellVarContext: - if (v < 2) s2 = (v == 0) ? "current" : "all"; break; - case k_ExecFlags_Silent: - if (v < 2) s2 = (v == 0) ? "normal" : "silent"; break; - case k_ExecFlags_RegView: - if (v == 0) s2 = "32"; - else if (v == 256) s2 = "64"; - break; - case k_ExecFlags_DetailsPrint: - if (v == 0) s2 = "both"; - else if (v == 2) s2 = "textonly"; - else if (v == 4) s2 = "listonly"; - else if (v == 6) s2 = "none"; - } - if (s2) - { - s += ' '; - s += s2; - break; - } - } - SpaceQuStr(temp); - break; - } - - case EW_IFFLAG: - { - Add_ExecFlags(params[2]); - Add_GotoVars2(¶ms[0]); - /* - static const unsigned kIfErrors = 2; - if (params[2] != kIfErrors && params[3] != 0xFFFFFFFF || - params[2] == kIfErrors && params[3] != 0) - { - s += " # FLAG &= "; - AddParam_UInt(params[3]); - } - */ - break; - } - - case EW_GETFLAG: - { - Add_ExecFlags(params[1]); - AddParam_Var(params[0]); - break; - } - - case EW_RENAME: - { - if (params[2] != 0) - s += k_REBOOTOK; - AddParams(params, 2); - if (params[3] != 0) - { - SmallSpaceComment(); - AddParam(params[3]); // rename comment for log file - } - break; - } - - case EW_GETFULLPATHNAME: - { - if (params[2] == 0) - s += " /SHORT"; - AddParam_Var(params[1]); - AddParam(params[0]); - break; - } - - case EW_SEARCHPATH: - case EW_STRLEN: - { - AddParam_Var(params[0]); - AddParam(params[1]); - break; - } - - case EW_GETTEMPFILENAME: - { - AddParam_Var(params[0]); - AString temp; - ReadString2(temp, params[1]); - if (temp != "$TEMP") - SpaceQuStr(temp); - break; - } - - case EW_DELETEFILE: - { - UInt32 flag = params[1]; - if ((flag & DEL_REBOOT) != 0) - s += k_REBOOTOK; - AddParam(params[0]); - break; - } - - case EW_MESSAGEBOX: - { - MessageBox_MB_Part(params[0]); - AddParam(params[1]); - { - UInt32 buttonID = (params[0] >> 21); // NSIS 2.06+ - if (buttonID != 0) - { - s += " /SD"; - Add_ButtonID(buttonID); - } - } - for (int i = 2; i < 6; i += 2) - if (params[i] != 0) - { - Add_ButtonID(params[i]); - Add_GotoVar1(params[i + 1]); - } - break; - } - - case EW_RMDIR: - { - UInt32 flag = params[1]; - if ((flag & DEL_RECURSE) != 0) - s += " /r"; - if ((flag & DEL_REBOOT) != 0) - s += k_REBOOTOK; - AddParam(params[0]); - break; - } - - case EW_STRCMP: - { - if (params[4] != 0) - s += 'S'; - AddParams(params, 2); - Add_GotoVars2(¶ms[2]); - break; - } - - case EW_READENVSTR: - { - s += (params[2] != 0) ? - "ReadEnvStr" : - "ExpandEnvStrings"; - AddParam_Var(params[0]); - AString temp; - ReadString2(temp, params[1]); - if (params[2] != 0 &&temp.Len() >= 2 && temp[0] == '%' && temp.Back() == '%') - { - temp.DeleteBack(); - temp.Delete(0); - } - SpaceQuStr(temp); - break; - } - - case EW_INTCMP: - { - if (params[5] != 0) - s += 'U'; - AddParams(params, 2); - Add_GotoVar1(params[2]); - if (params[3] != 0 || params[4] != 0) - Add_GotoVars2(params + 3); - break; - } - - case EW_INTOP: - { - AddParam_Var(params[0]); - const char *kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+ - // "+-*/|&^!|&%"; // NSIS 2.0b4+ - // "+-*/|&^~!|&%"; // NSIS old - UInt32 opIndex = params[3]; - char c = (opIndex < 13) ? kOps[opIndex] : '?'; - char c2 = (opIndex < 8 || opIndex == 10) ? (char)0 : c; - int numOps = (opIndex == 7) ? 1 : 2; - AddParam(params[1]); - if (numOps == 2 && c == '^' && IsDirectString_Equal(params[2], "0xFFFFFFFF")) - s += " ~ ;"; - Space(); - s += c; - if (numOps != 1) - { - if (c2 != 0) - s += c2; - AddParam(params[2]); - } - break; - } - - case EW_INTFMT: - { - AddParam_Var(params[0]); - AddParams(params + 1, 2); - break; - } - - case EW_PUSHPOP: - { - if (params[2] != 0) - { - s += "Exch"; - if (params[2] != 1) - AddParam_UInt(params[2]); - } - else if (params[1] != 0) - { - s += "Pop"; - AddParam_Var(params[0]); - } - else - { - if (NoLabels(labels + kkk + 1, 2) - && Get32(p + kCmdSize) == EW_PUSHPOP // Exch" - && GET_CMD_PARAM(p + kCmdSize, 2) == 1 - && Get32(p + kCmdSize * 2) == EW_PUSHPOP // Pop $VAR - && GET_CMD_PARAM(p + kCmdSize * 2, 1) != 0) - { - if (IsVarStr(params[0], GET_CMD_PARAM(p + kCmdSize * 2, 0))) - { - s += "Exch"; - AddParam(params[0]); - NewLine(); - Tab(true); - endCommentIndex = kkk + 3; - } - } - s += "Push"; - AddParam(params[0]); - } - break; - } - - case EW_FINDWINDOW: - { - AddParam_Var(params[0]); - AddParam(params[1]); - AddOptionalParams(params + 2, 3); - break; - } - - case EW_SENDMESSAGE: - { - // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2] - AddParam(params[1]); - - const char *w = NULL; - AString t; - ReadString2(t, params[2]); - UInt32 wm; - if (StringToUInt32(t, wm)) - { - switch (wm) - { - case 0x0C: w = "SETTEXT"; break; - case 0x10: w = "CLOSE"; break; - case 0x30: w = "SETFONT"; break; - } - } - if (w) - { - s += " ${WM_"; - s += w; - s += '}'; - } - else - SpaceQuStr(t); - - UInt32 spec = params[5]; - for (unsigned i = 0; i < 2; i++) - { - AString s2; - if (spec & ((UInt32)1 << i)) - s2 += "STR:"; - ReadString2(s2, params[3 + i]); - SpaceQuStr(s2); - } - - if ((Int32)params[0] >= 0) - AddParam_Var(params[0]); - - spec >>= 2; - if (spec != 0) - { - s += " /TIMEOUT="; - Add_UInt(spec); - } - break; - } - - case EW_ISWINDOW: - { - AddParam(params[0]); - Add_GotoVars2(¶ms[1]); - break; - } - - case EW_GETDLGITEM: - { - AddParam_Var(params[0]); - AddParams(params + 1, 2); - break; - } - - case EW_SETCTLCOLORS: - { - AddParam(params[0]); - - UInt32 offset = params[1]; - - if (_size < bhCtlColors.Offset - || _size - bhCtlColors.Offset < offset - || _size - bhCtlColors.Offset - offset < k_CtlColors_Size) - { - AddError("bad offset"); - break; - } - - const Byte *p2 = _data + bhCtlColors.Offset + offset; - CNsis_CtlColors colors; - colors.Parse(p2); - - if ((colors.flags & kColorsFlags_BK_SYS) != 0 || - (colors.flags & kColorsFlags_TEXT_SYS) != 0) - s += " /BRANDING"; - - AString bk; - bool bkc = false; - if (colors.bkmode == MY__TRANSPARENT) - bk += " transparent"; - else if (colors.flags & kColorsFlags_BKB) - { - if ((colors.flags & kColorsFlags_BK_SYS) == 0 && - (colors.flags & kColorsFlags_BK) != 0) - bkc = true; - } - if ((colors.flags & kColorsFlags_TEXT) != 0 || !bk.IsEmpty() || bkc) - { - Space(); - if ((colors.flags & kColorsFlags_TEXT_SYS) != 0 || (colors.flags & kColorsFlags_TEXT) == 0) - AddQuotes(); - else - Add_Color(colors.text); - } - s += bk; - if (bkc) - { - Space(); - Add_Color(colors.bkc); - } - - break; - } - - case EW_SETBRANDINGIMAGE: - { - s += " /IMGID="; - Add_UInt(params[1]); - if (params[2] == 1) - s += " /RESIZETOFIT"; - AddParam(params[0]); - break; - } - - case EW_CREATEFONT: - { - AddParam_Var(params[0]); - AddParam(params[1]); - AddOptionalParams(params + 2, 2); - if (params[4] & 1) s += " /ITALIC"; - if (params[4] & 2) s += " /UNDERLINE"; - if (params[4] & 4) s += " /STRIKE"; - break; - } - - case EW_SHOWWINDOW: - { - AString hw, sw; - ReadString2(hw, params[0]); - ReadString2(sw, params[1]); - if (params[3] != 0) - s += "EnableWindow"; - else - { - UInt32 val; - bool valDefined = false; - if (StringToUInt32(sw, val)) - { - if (val < ARRAY_SIZE(kShowWindow_Commands)) - { - sw.Empty(); - sw += "${"; - Add_ShowWindow_Cmd_2(sw, val); - sw += '}'; - valDefined = true; - } - } - bool isHwndParent = IsVarStr(params[0], IsNsis225 ? kVar_HWNDPARENT_225 : kVar_HWNDPARENT); - if (params[2] != 0) - { - if (valDefined && val == 0 && isHwndParent) - { - s += "HideWindow"; - break; - } - } - if (valDefined && val == 5 && isHwndParent && - kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_BRINGTOFRONT) - { - s += " ; "; - } - s += "ShowWindow"; - } - SpaceQuStr(hw); - SpaceQuStr(sw); - break; - } - - case EW_SHELLEXEC: - { - AddParams(params, 2); - if (params[2] != 0 || params[3] != MY__SW_SHOWNORMAL) - { - AddParam(params[2]); - if (params[3] != MY__SW_SHOWNORMAL) - { - Space(); - Add_ShowWindow_Cmd(params[3]); - } - } - if (params[5] != 0) - { - s += " ;"; - AddParam(params[5]); // it's tatus text update - } - break; - } - - case EW_EXECUTE: - { - if (params[2] != 0) - s += "Wait"; - AddParam(params[0]); - if (params[2] != 0) - if ((Int32)params[1] >= 0) - AddParam_Var(params[1]); - break; - } - - case EW_GETFILETIME: - case EW_GETDLLVERSION: - { - AddParam(params[2]); - AddParam_Var(params[0]); - AddParam_Var(params[1]); - break; - } - - case EW_REGISTERDLL: - { - AString func; - ReadString2(func, params[1]); - bool printFunc = true; - // params[4] = 1; for plugin command - if (params[2] == 0) - { - s += "CallInstDLL"; - AddParam(params[0]); - if (params[3] == 1) - s += " /NOUNLOAD"; - } - else - { - if (func == "DllUnregisterServer") - { - s += "UnRegDLL"; - printFunc = false; - } - else - { - s += "RegDLL"; - if (func == "DllRegisterServer") - printFunc = false; - } - AddParam(params[0]); - } - if (printFunc) - SpaceQuStr(func); - break; - } - - case EW_CREATESHORTCUT: - { - unsigned numParams; - for (numParams = 6; numParams > 2; numParams--) - if (params[numParams - 1] != 0) - break; - - UInt32 spec = params[4]; - if (spec & 0x8000) // NSIS 3.0b0 - s += " /NoWorkingDir"; - - AddParams(params, numParams > 4 ? 4 : numParams); - if (numParams <= 4) - break; - - UInt32 icon = (spec & 0xFF); - Space(); - if (icon != 0) - Add_UInt(icon); - else - AddQuotes(); - - if ((spec >> 8) == 0 && numParams < 6) - break; - UInt32 sw = (spec >> 8) & 0x7F; - Space(); - // NSIS encoder replaces these names: - if (sw == MY__SW_SHOWMINNOACTIVE) - sw = MY__SW_SHOWMINIMIZED; - if (sw == 0) - AddQuotes(); - else - Add_ShowWindow_Cmd(sw); - - UInt32 modKey = spec >> 24; - UInt32 key = (spec >> 16) & 0xFF; - - if (modKey == 0 && key == 0) - { - if (numParams < 6) - break; - Space(); - AddQuotes(); - } - else - { - Space(); - if (modKey & 1) s += "SHIFT|"; // HOTKEYF_SHIFT - if (modKey & 2) s += "CONTROL|"; - if (modKey & 4) s += "ALT|"; - if (modKey & 8) s += "EXT|"; - - static const unsigned kMy_VK_F1 = 0x70; - if (key >= kMy_VK_F1 && key <= kMy_VK_F1 + 23) - { - s += 'F'; - Add_UInt(key - kMy_VK_F1 + 1); - } - else if (key >= 'A' && key <= 'Z' || key >= '0' && key <= '9') - s += (char)key; - else - { - s += "Char_"; - Add_UInt(key); - } - } - AddOptionalParam(params[5]); // description - break; - } - - case EW_COPYFILES: - { - if (params[2] & 0x04) s += " /SILENT"; // FOF_SILENT - if (params[2] & 0x80) s += " /FILESONLY"; // FOF_FILESONLY - AddParams(params, 2); - if (params[3] != 0) - { - s += " ;"; - AddParam(params[3]); // status text update - } - break; - } - - case EW_REBOOT: - { - if (params[0] != 0xbadf00d) - s += " ; Corrupted ???"; - else if (kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_QUIT) - endCommentIndex = kkk + 2; - break; - } - - case EW_WRITEINI: - { - unsigned numAlwaysParams = 0; - if (params[0] == 0) // Section - s += "FlushINI"; - else if (params[4] != 0) - { - s += "WriteINIStr"; - numAlwaysParams = 3; - } - else - { - s += "DeleteINI"; - s += (params[1] == 0) ? "Sec" : "Str"; - numAlwaysParams = 1; - } - AddParam(params[3]); // filename - // Section, EntryName, Value - AddParams(params, numAlwaysParams); - AddOptionalParams(params + numAlwaysParams, 3 - numAlwaysParams); - break; - } - - case EW_READINISTR: - { - AddParam_Var(params[0]); - AddParam(params[3]); // FileName - AddParams(params +1, 2); // Section, EntryName - break; - } - - case EW_DELREG: - { - // NSIS 2.00 used another scheme! - - if (params[4] == 0) - s += "Value"; - else - { - s += "Key"; - if (params[4] & 2) - s += " /ifempty"; - } - AddRegRoot(params[1]); - AddParam(params[2]); - AddOptionalParam(params[3]); - break; - } - - case EW_WRITEREG: - { - const char *s2 = 0; - switch (params[4]) - { - case 1: s2 = "Str"; break; - case 2: s2 = "ExpandStr"; break; // maybe unused - case 3: s2 = "Bin"; break; - case 4: s2 = "DWORD"; break; - default: - s += '?'; - Add_UInt(params[4]); - } - if (params[4] == 1 && params[5] == 2) - s2 = "ExpandStr"; - if (s2) - s += s2; - AddRegRoot(params[0]); - AddParams(params + 1, 2); // keyName, valueName - if (params[4] != 3) - AddParam(params[3]); // value - else - { - // Binary data. - Space(); - UInt32 offset = params[3]; - bool isSupported = false; - if (AfterHeaderSize >= 4 - && bhData.Offset <= AfterHeaderSize - 4 - && offset <= AfterHeaderSize - 4 - bhData.Offset) - { - // we support it for solid archives. - const Byte *p2 = _afterHeader + bhData.Offset + offset; - UInt32 size = Get32(p2); - if (size <= AfterHeaderSize - 4 - bhData.Offset - offset) - { - for (UInt32 i = 0; i < size; i++) - { - Byte b = (p2 + 4)[i]; - unsigned t; - t = (b >> 4); s += (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); - t = (b & 15); s += (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); - } - isSupported = true; - } - } - if (!isSupported) - { - // we must read from file here; - s += "data["; - Add_UInt(offset); - s += " ... ]"; - s += " ; !!! Unsupported"; - } - } - break; - } - - case EW_READREGSTR: - { - s += (params[4] == 1) ? "DWORD" : "Str"; - AddParam_Var(params[0]); - AddRegRoot(params[1]); - AddParams(params + 2, 2); - break; - } - - case EW_REGENUM: - { - s += (params[4] != 0) ? "Key" : "Value"; - AddParam_Var(params[0]); - AddRegRoot(params[1]); - AddParams(params + 2, 2); - break; - } - - case EW_FCLOSE: - case EW_FINDCLOSE: - { - AddParam_Var(params[0]); - break; - } - - case EW_FOPEN: - { - AddParam_Var(params[0]); - AddParam(params[3]); - UInt32 acc = params[1]; // dwDesiredAccess - UInt32 creat = params[2]; // dwCreationDisposition - if (acc == 0 && creat == 0) - break; - char cc = 0; - if (acc == MY__GENERIC_READ && creat == OPEN_EXISTING) - cc = 'r'; - else if (creat == CREATE_ALWAYS && acc == MY__GENERIC_WRITE) - cc = 'w'; - else if (creat == OPEN_ALWAYS && (acc == (MY__GENERIC_WRITE | MY__GENERIC_READ))) - cc = 'a'; - // cc = 0; - if (cc != 0) - { - Space(); - s += cc; - break; - } - - if (acc & MY__GENERIC_READ) s += " GENERIC_READ"; - if (acc & MY__GENERIC_WRITE) s += " GENERIC_WRITE"; - if (acc & MY__GENERIC_EXECUTE) s += " GENERIC_EXECUTE"; - if (acc & MY__GENERIC_ALL) s += " GENERIC_ALL"; - - const char *s2 = NULL; - switch (creat) - { - case MY__CREATE_NEW: s2 = "CREATE_NEW"; break; - case MY__CREATE_ALWAYS: s2 = "CREATE_ALWAYS"; break; - case MY__OPEN_EXISTING: s2 = "OPEN_EXISTING"; break; - case MY__OPEN_ALWAYS: s2 = "OPEN_ALWAYS"; break; - case MY__TRUNCATE_EXISTING: s2 = "TRUNCATE_EXISTING"; break; - } - Space(); - if (s2) - s += s2; - else - Add_UInt(creat); - break; - } - - case EW_FPUTS: - case EW_FPUTWS: - { - if (commandId == EW_FPUTWS) - s += (params[2] == 0) ? "UTF16LE" : "Word"; - else if (params[2] != 0) - s += "Byte"; - AddParam_Var(params[0]); - AddParam(params[1]); - break; - } - - case EW_FGETS: - case EW_FGETWS: - { - if (commandId == EW_FPUTWS) - s += (params[3] == 0) ? "UTF16LE" : "Word"; - if (params[3] != 0) - s += "Byte"; - AddParam_Var(params[0]); - AddParam_Var(params[1]); - AString maxLenStr; - ReadString2(maxLenStr, params[2]); - UInt32 maxLen; - if (StringToUInt32(maxLenStr, maxLen)) - { - if (maxLen == 1 && params[3] != 0) - break; - if (maxLen == 1023 && params[3] == 0) // NSIS_MAX_STRLEN - 1; can be other value!! - break; - } - SpaceQuStr(maxLenStr); - break; - } - - case EW_FSEEK: - { - AddParam_Var(params[0]); - AddParam(params[2]); - if (params[3] == 1) s += " CUR"; // FILE_CURRENT - if (params[3] == 2) s += " END"; // FILE_END - if ((Int32)params[1] >= 0) - { - if (params[3] == 0) s += " SET"; // FILE_BEGIN - AddParam_Var(params[1]); - } - break; - } - - case EW_FINDNEXT: - { - AddParam_Var(params[1]); - AddParam_Var(params[0]); - break; - } - - case EW_FINDFIRST: - { - AddParam_Var(params[1]); - AddParam_Var(params[0]); - AddParam(params[2]); - break; - } - - case EW_LOG: - { - if (params[0] != 0) - { - s += "Set "; - s += (params[1] == 0) ? "off" : "on"; - } - else - { - s += "Text"; - AddParam(params[1]); - } - } - - case EW_SECTIONSET: - { - if ((Int32)params[2] >= 0) - { - s += "Get"; - Add_SectOp(params[2]); - AddParam(params[0]); - AddParam_Var(params[1]); - } - else - { - s += "Set"; - UInt32 t = -(Int32)params[2] - 1; - Add_SectOp(t); - AddParam(params[0]); - AddParam(params[t == 0 ? 4 : 1]); - - // params[3] != 0 means call SectionFlagsChanged in installer - // used by SECTIONSETFLAGS command - } - break; - } - - case EW_INSTTYPESET: - { - int numQwParams = 0; - const char *s2; - if (params[3] == 0) - { - if (params[2] == 0) - { - s2 = "InstTypeGetText"; - numQwParams = 1; - } - else - { - s2 = "InstTypeSetText"; - numQwParams = 2; - } - } - else - { - if (params[2] == 0) - s2 = "GetCurInstType"; - else - { - s2 = "SetCurInstType"; - numQwParams = 1; - } - } - s += s2; - AddParams(params, numQwParams); - if (params[2] == 0) - AddParam_Var(params[1]); - break; - } - - case EW_LOCKWINDOW: - { - s += (params[0] == 0) ? " on" : " off"; - break; - } - - case EW_FINDPROC: - { - AddParam_Var(params[0]); - AddParam(params[1]); - break; - } - - default: - { - numSkipParams = 0; - } - #endif - } - - #ifdef NSIS_SCRIPT - - unsigned numParams = kNumCommandParams; - - for (; numParams > 0; numParams--) - if (params[numParams - 1] != 0) - break; - - if (numParams > numSkipParams) - { - s += " ; !!!! Unknown Params: "; - unsigned i; - for (i = 0; i < numParams; i++) - AddParam(params[i]); - - s += " ;"; - - for (i = 0; i < numParams; i++) - { - Space(); - UInt32 v = params[i]; - if (v > 0xFFF00000) - Add_SignedInt(s, (Int32)v); - else - Add_UInt(v); - } - } - - NewLine(); - - #endif - } - - #ifdef NSIS_SCRIPT - - if (sectionIsOpen) - { - if (curSectionIndex < bhSections.Num) - { - const CSection § = Sections[curSectionIndex]; - if (sect.StartCmdIndex + sect.NumCommands + 1 == kkk) - { - PrintSectionEnd(); - sectionIsOpen = false; - // lastSectionEndCmd = kkk; - curSectionIndex++; - } - } - } - - while (curSectionIndex < bhSections.Num) - { - const CSection § = Sections[curSectionIndex]; - if (sectionIsOpen) - { - if (sect.StartCmdIndex + sect.NumCommands != kkk) - AddErrorLF("SECTION ERROR"); - PrintSectionEnd(); - sectionIsOpen = false; - curSectionIndex++; - } - else - { - if (curSectionIndex == 49) - curSectionIndex = curSectionIndex; - - if (PrintSectionBegin(sect, curSectionIndex)) - curSectionIndex++; - else - sectionIsOpen = true; - } - } - - #endif - - return S_OK; -} - -static int CompareItems(void *const *p1, void *const *p2, void *param) -{ - const CItem &i1 = **(CItem **)p1; - const CItem &i2 = **(CItem **)p2; - RINOZ(MyCompare(i1.Pos, i2.Pos)); - const CInArchive *inArchive = (const CInArchive *)param; - if (inArchive->IsUnicode) - { - if (i1.Prefix != i2.Prefix) - { - if (i1.Prefix < 0) return -1; - if (i2.Prefix < 0) return 1; - RINOZ(wcscmp( - inArchive->UPrefixes[i1.Prefix], - inArchive->UPrefixes[i2.Prefix])); - } - RINOZ(wcscmp(i1.NameU, i2.NameU)); - } - else - { - if (i1.Prefix != i2.Prefix) - { - if (i1.Prefix < 0) return -1; - if (i2.Prefix < 0) return 1; - RINOZ(strcmp( - inArchive->APrefixes[i1.Prefix], - inArchive->APrefixes[i2.Prefix])); - } - RINOZ(strcmp(i1.NameA, i2.NameA)); - } - return 0; -} - -HRESULT CInArchive::SortItems() -{ - { - Items.Sort(CompareItems, (void *)this); - unsigned i; - - for (i = 0; i + 1 < Items.Size(); i++) - { - const CItem &i1 = Items[i]; - const CItem &i2 = Items[i + 1]; - if (i1.Pos != i2.Pos) - continue; - - if (IsUnicode) - { - if (i1.NameU != i2.NameU) continue; - if (i1.Prefix != i2.Prefix) - { - if (i1.Prefix < 0 || i2.Prefix < 0) continue; - if (UPrefixes[i1.Prefix] != UPrefixes[i2.Prefix]) continue; - } - } - else - { - if (i1.NameA != i2.NameA) continue; - if (i1.Prefix != i2.Prefix) - { - if (i1.Prefix < 0 || i2.Prefix < 0) continue; - if (APrefixes[i1.Prefix] != APrefixes[i2.Prefix]) continue; - } - } - Items.Delete(i + 1); - i--; - } - - for (i = 0; i < Items.Size(); i++) - { - CItem &item = Items[i]; - UInt32 curPos = item.Pos + 4; - for (unsigned nextIndex = i + 1; nextIndex < Items.Size(); nextIndex++) - { - UInt32 nextPos = Items[nextIndex].Pos; - if (curPos <= nextPos) - { - item.EstimatedSize_Defined = true; - item.EstimatedSize = nextPos - curPos; - break; - } - } - } - - if (!IsSolid) - { - for (i = 0; i < Items.Size(); i++) - { - CItem &item = Items[i]; - RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL)); - const UInt32 kSigSize = 4 + 1 + 1 + 4; // size,[flag],prop,dict - BYTE sig[kSigSize]; - size_t processedSize = kSigSize; - RINOK(ReadStream(_stream, sig, &processedSize)); - if (processedSize < 4) - return S_FALSE; - UInt32 size = Get32(sig); - if ((size & kMask_IsCompressed) != 0) - { - item.IsCompressed = true; - size &= ~kMask_IsCompressed; - if (Method == NMethodType::kLZMA) - { - if (processedSize < 9) - return S_FALSE; - /* - if (FilterFlag) - item.UseFilter = (sig[4] != 0); - */ - item.DictionarySize = Get32(sig + 4 + 1 + (FilterFlag ? 1 : 0)); - } - } - else - { - item.IsCompressed = false; - item.Size = size; - item.Size_Defined = true; - } - item.CompressedSize = size; - item.CompressedSize_Defined = true; - } - } - } - return S_OK; -} - -// Flags for common_header.flags -#define CH_FLAGS_DETAILS_SHOWDETAILS 1 -#define CH_FLAGS_DETAILS_NEVERSHOW 2 -#define CH_FLAGS_PROGRESS_COLORED 4 -#define CH_FLAGS_SILENT 8 -#define CH_FLAGS_SILENT_LOG 16 -#define CH_FLAGS_AUTO_CLOSE 32 -#define CH_FLAGS_DIR_NO_SHOW 64 // unused now -#define CH_FLAGS_NO_ROOT_DIR 128 -#define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256 -#define CH_FLAGS_NO_CUSTOM 512 - -static const char * const k_PostStrings[] = -{ - "install_directory_auto_append" - , "uninstchild" // NSIS 2.25+, used by uninstaller: - , "uninstcmd" // NSIS 2.25+, used by uninstaller: - , "wininit" // NSIS 2.25+, used by move file on reboot -}; - -HRESULT CInArchive::Parse() -{ - // UInt32 offset = ReadUInt32(); - // ???? offset == FirstHeader.HeaderSize - const Byte *p = _data; - - CBlockHeader bhEntries, bhStrings, bhLangTables; - bhEntries.Parse(p + 4 + 8 * 2); - bhStrings.Parse(p + 4 + 8 * 3); - bhLangTables.Parse(p + 4 + 8 * 4); - - #ifdef NSIS_SCRIPT - - CBlockHeader bhFont; - bhPages.Parse(p + 4 + 8 * 0); - bhSections.Parse(p + 4 + 8 * 1); - bhCtlColors.Parse(p + 4 + 8 * 5); - bhFont.Parse(p + 4 + 8 * 6); - bhData.Parse(p + 4 + 8 * 7); - - #endif - - _stringsPos = bhStrings.Offset; - if (_stringsPos > _size) - return S_FALSE; - { - if (bhLangTables.Offset < bhStrings.Offset) - return S_FALSE; - UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset; - if (stringTableSize < 2) - return S_FALSE; - const Byte *strData = _data + _stringsPos; - if (strData[stringTableSize - 1] != 0) - return S_FALSE; - IsUnicode = (Get16(strData) == 0); - NumStringChars = stringTableSize; - if (IsUnicode) - { - if ((stringTableSize & 1) != 0) - return S_FALSE; - NumStringChars >>= 1; - if (strData[stringTableSize - 2] != 0) - return S_FALSE; - } - - } - - if (bhEntries.Num > (1 << 25)) - return S_FALSE; - if (bhEntries.Offset > _size) - return S_FALSE; - if (bhEntries.Num * kCmdSize > _size - bhEntries.Offset) - return S_FALSE; - - DetectNsisType(bhEntries, _data + bhEntries.Offset); - - #ifdef NSIS_SCRIPT - - { - AddCommentAndString("NSIS script"); - if (IsUnicode) - Script += " (UTF-8)"; - Space(); - Script += GetFormatDescription(); - AddLF(); - } - { - AddCommentAndString(IsInstaller ? "Install" : "Uninstall"); - AddLF(); - } - - AddLF(); - if (IsUnicode) - AddStringLF("Unicode true"); - - if (Method != NMethodType::kCopy) - { - const char *m = NULL; - switch (Method) - { - case NMethodType::kDeflate: m = "zlib"; break; - case NMethodType::kBZip2: m = "bzip2"; break; - case NMethodType::kLZMA: m = "lzma"; break; - } - Script += "SetCompressor"; - if (IsSolid) - Script += " /SOLID"; - if (m) - { - Space(); - Script += m; - } - AddLF(); - } - if (Method == NMethodType::kLZMA) - { - // if (DictionarySize != (8 << 20)) - { - Script += "SetCompressorDictSize"; - AddParam_UInt(DictionarySize >> 20); - AddLF(); - } - } - - Separator(); - PrintNumComment("HEADER SIZE", FirstHeader.HeaderSize); - // if (bhPages.Offset != 300 && bhPages.Offset != 288) - if (bhPages.Offset != 0) - { - PrintNumComment("START HEADER SIZE", bhPages.Offset); - } - - if (bhSections.Num > 0) - { - if (bhEntries.Offset < bhSections.Offset) - return S_FALSE; - SectionSize = (bhEntries.Offset - bhSections.Offset) / bhSections.Num; - if (bhSections.Offset + bhSections.Num * SectionSize != bhEntries.Offset) - return S_FALSE; - if (SectionSize < kSectionSize_base) - return S_FALSE; - UInt32 maxStringLen = SectionSize - kSectionSize_base; - if (IsUnicode) - { - if ((maxStringLen & 1) != 0) - return S_FALSE; - maxStringLen >>= 1; - } - // if (maxStringLen != 1024) - { - if (maxStringLen == 0) - PrintNumComment("SECTION SIZE", SectionSize); - else - PrintNumComment("MAX STRING LENGTH", maxStringLen); - } - } - - PrintNumComment("STRING CHARS", NumStringChars); - // PrintNumComment("LANG TABLE SIZE", bhCtlColors.Offset - bhLangTables.Offset); - - if (bhCtlColors.Offset > _size) - AddErrorLF("Bad COLORS TABLE"); - // PrintNumComment("COLORS TABLE SIZE", bhFont.Offset - bhCtlColors.Offset); - if (bhCtlColors.Num != 0) - PrintNumComment("COLORS Num", bhCtlColors.Num); - - // bhData uses offset in _afterHeader (not in _data) - // PrintNumComment("FONT TABLE SIZE", bhData.Offset - bhFont.Offset); - if (bhFont.Num != 0) - PrintNumComment("FONTS Num", bhFont.Num); - - // PrintNumComment("DATA SIZE", FirstHeader.HeaderSize - bhData.Offset); - if (bhData.Num != 0) - PrintNumComment("DATA NUM", bhData.Num); - - AddLF(); - - AddStringLF("OutFile [NSIS].exe"); - AddStringLF("!include WinMessages.nsh"); - - AddLF(); - - strUsed.Alloc(NumStringChars); - memset(strUsed, 0, NumStringChars); - - { - UInt32 ehFlags = Get32(p); - UInt32 showDetails = ehFlags & 3;// CH_FLAGS_DETAILS_SHOWDETAILS & CH_FLAGS_DETAILS_NEVERSHOW; - if (showDetails >= 1 && showDetails <= 2) - { - Script += IsInstaller ? "ShowInstDetails" : "ShowUninstDetails"; - Script += (showDetails == 1) ? " show" : " nevershow"; - AddLF(); - } - if (ehFlags & CH_FLAGS_PROGRESS_COLORED) AddStringLF("InstProgressFlags colored" ); - if ((ehFlags & (CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG)) != 0) - { - Script += IsInstaller ? "SilentInstall " : "SilentUnInstall "; - Script += (ehFlags & CH_FLAGS_SILENT_LOG) ? "silentlog" : "silent"; - AddLF(); - } - if (ehFlags & CH_FLAGS_AUTO_CLOSE) AddStringLF("AutoCloseWindow true"); - if ((ehFlags & CH_FLAGS_NO_ROOT_DIR) == 0) AddStringLF("AllowRootDirInstall true"); - if (ehFlags & CH_FLAGS_NO_CUSTOM) AddStringLF("InstType /NOCUSTOM"); - if (ehFlags & CH_FLAGS_COMP_ONLY_ON_CUSTOM) AddStringLF("InstType /COMPONENTSONLYONCUSTOM"); - } - - // Separator(); - // AddLF(); - - Int32 licenseLangIndex = -1; - { - const Byte *pp = _data + bhPages.Offset; - - for (UInt32 pageIndex = 0; pageIndex < bhPages.Num; pageIndex++, pp += kPageSize) - { - UInt32 wndProcID = Get32(pp + 4); - UInt32 param1 = Get32(pp + 44 + 4 * 1); - if (wndProcID != PWP_LICENSE || param1 == 0) - continue; - if ((Int32)param1 < 0) - licenseLangIndex = - ((Int32)param1 + 1); - else - noParseStringIndexes.AddToUniqueSorted(param1); - } - } - - unsigned paramsOffset = 4 + 8 * 8; - if (bhPages.Offset == 276) - paramsOffset -= 8; - - const Byte *p2 = p + paramsOffset; - - { - UInt32 rootKey = Get32(p2); // (rootKey = -1) in uninstaller by default (the bug in NSIS) - UInt32 subKey = Get32(p2 + 4); - UInt32 value = Get32(p2 + 8); - if ((rootKey != 0 && rootKey != (UInt32)(Int32)-1) || subKey != 0 || value != 0) - { - Script += "InstallDirRegKey"; - AddRegRoot(rootKey); - AddParam(subKey); - AddParam(value); - AddLF(); - } - } - - - { - UInt32 bg_color1 = Get32(p2 + 12); - UInt32 bg_color2 = Get32(p2 + 16); - UInt32 bg_textcolor = Get32(p2 + 20); - if (bg_color1 != (UInt32)(Int32)-1 || bg_color2 != (UInt32)(Int32)-1 || bg_textcolor != (UInt32)(Int32)-1) - { - Script += "BGGradient"; - if (bg_color1 != 0 || bg_color2 != 0xFF0000 || bg_textcolor != (UInt32)(Int32)-1) - { - Add_ColorParam(bg_color1); - Add_ColorParam(bg_color2); - if (bg_textcolor != (UInt32)(Int32)-1) - Add_ColorParam(bg_textcolor); - } - AddLF(); - } - } - - { - UInt32 lb_bg = Get32(p2 + 24); - UInt32 lb_fg = Get32(p2 + 28); - if ((lb_bg != (UInt32)(Int32)-1 || lb_fg != (UInt32)(Int32)-1) && - (lb_bg != 0 || lb_fg != 0xFF00)) - { - Script += "InstallColors"; - Add_ColorParam(lb_fg); - Add_ColorParam(lb_bg); - AddLF(); - } - } - - UInt32 license_bg = Get32(p2 + 36); - if (license_bg != (UInt32)(Int32)-1 && license_bg != -15) // COLOR_BTNFACE - { - Script += "LicenseBkColor"; - if ((Int32)license_bg == -5) // COLOR_WINDOW - Script += " /windows"; - /* - else if ((Int32)license_bg == -15) - Script += " /grey"; - */ - else - Add_ColorParam(license_bg); - AddLF(); - } - - UInt32 langtable_size = Get32(p2 + 32); - if (bhLangTables.Num > 0) - { - if (langtable_size == (UInt32)(Int32)-1) - return E_NOTIMPL; // maybe it's old NSIS archive() - - UInt32 numStrings = (langtable_size - 10) / 4; - _numLangStrings = numStrings; - AddLF(); - Separator(); - PrintNumComment("LANG TABLES", bhLangTables.Num); - PrintNumComment("LANG STRINGS", numStrings); - AddLF(); - - if (licenseLangIndex >= 0) - { - for (UInt32 i = 0; i < bhLangTables.Num; i++) - { - const Byte *p = _data + bhLangTables.Offset + langtable_size * i; - LANGID langID = Get16(p); - UInt32 val = Get32(p + 10 + (UInt32)licenseLangIndex * 4); - if (val != 0) - { - Script += "LicenseLangString "; - Add_LangStr_Simple(licenseLangIndex); - AddParam_UInt(langID); - AddLicense(val, langID); - noParseStringIndexes.AddToUniqueSorted(val); - NewLine(); - } - } - AddLF(); - } - - UInt32 brandingText = 0; - UInt32 caption = 0; - UInt32 name = 0; - UInt32 i; - for (i = 0; i < bhLangTables.Num; i++) - { - const Byte *p = _data + bhLangTables.Offset + langtable_size * i; - LANGID langID = Get16(p); - if (i == 0 || langID == 1033) - _mainLang = p + 10; - { - UInt32 v = Get32(p + 10 + 0 * 4); - if (v != 0 && (langID == 1033 || brandingText == 0)) - brandingText = v; - } - { - UInt32 v = Get32(p + 10 + 1 * 4); - if (v != 0 && (langID == 1033 || caption == 0)) - caption = v; - } - { - UInt32 v = Get32(p + 10 + 2 * 4); - if (v != 0 && (langID == 1033 || name == 0)) - name = v; - } - } - - if (name != 0) - { - Script += "Name"; - AddParam(name); - NewLine(); - - ReadString2(Name, name); - } - - /* - if (caption != 0) - { - Script += "Caption"; - AddParam(caption); - NewLine(); - } - */ - - if (brandingText != 0) - { - Script += "BrandingText"; - AddParam(brandingText); - NewLine(); - - ReadString2(BrandingText, brandingText); - } - - for (i = 0; i < bhLangTables.Num; i++) - { - const Byte *p = _data + bhLangTables.Offset + langtable_size * i; - LANGID langID = Get16(p); - - AddLF(); - AddCommentAndString("LANG:"); - AddParam_UInt(langID); - /* - Script += " ("; - LangId_To_String(Script, langID); - Script += ')'; - */ - AddLF(); - // UInt32 dlg_offset = Get32(p + 2); - // UInt32 g_exec_flags_rtl = Get32(p + 6); - - - for (UInt32 j = 0; j < numStrings; j++) - { - UInt32 val = Get32(p + 10 + j * 4); - if (val != 0) - { - if ((Int32)j != licenseLangIndex) - { - Script += "LangString "; - Add_LangStr_Simple(j); - AddParam_UInt(langID); - AddParam(val); - AddLF(); - } - } - } - AddLF(); - } - ClearLangComment(); - } - - { - unsigned numInternalVars = GET_NUM_INTERNAL_VARS; - UInt32 numUsedVars = GetNumUsedVars(); - if (numUsedVars > numInternalVars) - { - Separator(); - PrintNumComment("VARIABLES", numUsedVars - numInternalVars); - AddLF(); - AString temp; - for (UInt32 i = numInternalVars; i < numUsedVars; i++) - { - Script += "Var "; - temp.Empty(); - GetVar2(temp, i); - AddStringLF(temp); - } - AddLF(); - } - } - - onFuncOffset = paramsOffset + 40; - numOnFunc = ARRAY_SIZE(kOnFunc); - if (bhPages.Offset == 276) - numOnFunc--; - p2 += 40 + numOnFunc * 4; - - #define NSIS_MAX_INST_TYPES 32 - - AddLF(); - - UInt32 i; - for (i = 0; i < NSIS_MAX_INST_TYPES + 1; i++, p2 += 4) - { - UInt32 instType = Get32(p2); - if (instType != 0) - { - Script += "InstType"; - AString s2; - if (!IsInstaller) - s2 += "un."; - ReadString2(s2, instType); - SpaceQuStr(s2); - NewLine(); - } - } - - { - UInt32 installDir = Get32(p2); - p2 += 4; - if (installDir != 0) - { - Script += "InstallDir"; - AddParam(installDir); - NewLine(); - } - } - - if (bhPages.Offset >= 288) - for (i = 0; i < 4; i++) - { - if (i != 0 && bhPages.Offset < 300) - break; - UInt32 param = Get32(p2 + 4 * i); - if (param == 0 || param == (UInt32)(Int32)-1) - continue; - - /* - uninstaller: - UInt32 uninstChild = Get32(p2 + 8); // "$TEMP\\$1u_.exe" - UInt32 uninstCmd = Get32(p2 + 12); // "\"$TEMP\\$1u_.exe\" $0 _?=$INSTDIR\\" - int str_wininit = Get32(p2 + 16); // "$WINDIR\\wininit.ini" - */ - - AddCommentAndString(k_PostStrings[i]); - Script += " ="; - AddParam(param); - NewLine(); - } - - AddLF(); - - #endif - - RINOK(ReadEntries(bhEntries)); - - #ifdef NSIS_SCRIPT - - Separator(); - AddCommentAndString("UNREFERENCED STRINGS:"); - AddLF(); - AddLF(); - CommentOpen(); - - for (i = 0; i < NumStringChars;) - { - if (!strUsed[i] && i != 0) - // Script += "!!! "; - { - Add_UInt(i); - AddParam(i); - NewLine(); - } - if (IsUnicode) - i += GetUi16Str_Len((const Byte *)_data + _stringsPos + i * 2); - else - i += (UInt32)strlen((const char *)(const Byte *)_data + _stringsPos + i); - i++; - } - CommentClose(); - #endif - - return SortItems(); -} - -static bool IsLZMA(const Byte *p, UInt32 &dictionary) -{ - dictionary = Get32(p + 1); - return (p[0] == 0x5D && - p[1] == 0x00 && p[2] == 0x00 && - p[5] == 0x00 && (p[6] & 0x80) == 0x00); -} - -static bool IsLZMA(const Byte *p, UInt32 &dictionary, bool &thereIsFlag) -{ - if (IsLZMA(p, dictionary)) - { - thereIsFlag = false; - return true; - } - if (p[0] <= 1 && IsLZMA(p + 1, dictionary)) - { - thereIsFlag = true; - return true; - } - return false; -} - -static bool IsBZip2(const Byte *p) -{ - return (p[0] == 0x31 && p[1] < 14); -} - -HRESULT CInArchive::Open2(const Byte *sig, size_t size) -{ - const UInt32 kSigSize = 4 + 1 + 5 + 2; // size, flag, 5 - lzma props, 2 - lzma first bytes - if (size < kSigSize) - return S_FALSE; - - _headerIsCompressed = true; - IsSolid = true; - FilterFlag = false; - UseFilter = false; - DictionarySize = 1; - - #ifdef NSIS_SCRIPT - AfterHeaderSize = 0; - #endif - - UInt32 compressedHeaderSize = Get32(sig); - - - /* - XX XX XX XX XX XX XX XX == FirstHeader.HeaderSize, nonsolid, uncompressed - 5D 00 00 dd dd 00 solid LZMA - 00 5D 00 00 dd dd 00 solid LZMA, empty filter (there are no such archives) - 01 5D 00 00 dd dd 00 solid LZMA, BCJ filter (only 7-Zip installer used that format) - - SS SS SS 80 00 5D 00 00 dd dd 00 non-solid LZMA, empty filter - SS SS SS 80 01 5D 00 00 dd dd 00 non-solid LZMA, BCJ filte - SS SS SS 80 01 tt non-solid BZip (tt < 14 - SS SS SS 80 non-solid deflate - - 01 tt solid BZip (tt < 14 - other solid Deflate - */ - - if (compressedHeaderSize == FirstHeader.HeaderSize) - { - _headerIsCompressed = false; - IsSolid = false; - Method = NMethodType::kCopy; - } - else if (IsLZMA(sig, DictionarySize, FilterFlag)) - Method = NMethodType::kLZMA; - else if (sig[3] == 0x80) - { - IsSolid = false; - if (IsLZMA(sig + 4, DictionarySize, FilterFlag) && sig[3] == 0x80) - Method = NMethodType::kLZMA; - else if (IsBZip2(sig + 4)) - Method = NMethodType::kBZip2; - else - Method = NMethodType::kDeflate; - } - else if (IsBZip2(sig)) - Method = NMethodType::kBZip2; - else - Method = NMethodType::kDeflate; - - if (IsSolid) - { - RINOK(_stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL)); - } - else - { - _headerIsCompressed = ((compressedHeaderSize & kMask_IsCompressed) != 0); - compressedHeaderSize &= ~kMask_IsCompressed; - _nonSolidStartOffset = compressedHeaderSize; - RINOK(_stream->Seek(DataStreamOffset + 4, STREAM_SEEK_SET, NULL)); - } - - _data.Alloc(FirstHeader.HeaderSize); - _size = (size_t)FirstHeader.HeaderSize; - - Decoder.Method = Method; - Decoder.FilterFlag = FilterFlag; - Decoder.Solid = IsSolid; - Decoder.InputStream = _stream; - Decoder.Buffer.Alloc(kInputBufSize); - Decoder.StreamPos = 0; - - if (_headerIsCompressed) - { - RINOK(Decoder.Init(_stream, UseFilter)); - if (IsSolid) - { - size_t processedSize = 4; - Byte buf[4]; - RINOK(Decoder.Read(buf, &processedSize)); - if (processedSize != 4) - return S_FALSE; - if (Get32((const Byte *)buf) != FirstHeader.HeaderSize) - return S_FALSE; - } - size_t processedSize = FirstHeader.HeaderSize; - RINOK(Decoder.Read(_data, &processedSize)); - if (processedSize != FirstHeader.HeaderSize) - return S_FALSE; - - #ifdef NSIS_SCRIPT - if (IsSolid) - { - /* we need additional bytes for data for WriteRegBin */ - AfterHeaderSize = (1 << 12); - _afterHeader.Alloc(AfterHeaderSize); - size_t processedSize = AfterHeaderSize; - RINOK(Decoder.Read(_afterHeader, &processedSize)); - AfterHeaderSize = (UInt32)processedSize; - } - #endif - } - else - { - size_t processedSize = FirstHeader.HeaderSize; - RINOK(ReadStream(_stream, (Byte *)_data, &processedSize)); - if (processedSize < FirstHeader.HeaderSize) - return S_FALSE; - } - - #ifdef NUM_SPEED_TESTS - for (unsigned i = 0; i < NUM_SPEED_TESTS; i++) - { - RINOK(Parse()); - Clear2(); - } - #endif - - return Parse(); -} - -/* -NsisExe = -{ - ExeStub - Archive // must start from 512 * N - #ifndef NSIS_CONFIG_CRC_ANAL - { - Some additional data - } -} - -Archive -{ - FirstHeader - Data - #ifdef NSIS_CONFIG_CRC_SUPPORT && FirstHeader.ThereIsCrc() - { - CRC - } -} - -FirstHeader -{ - UInt32 Flags; - Byte Signature[16]; - // points to the header+sections+entries+stringtable in the datablock - UInt32 HeaderSize; - UInt32 ArcSize; -} -*/ - - -// ---------- PE (EXE) parsing ---------- - -static const unsigned k_PE_StartSize = 0x40; -static const unsigned k_PE_HeaderSize = 4 + 20; -static const unsigned k_PE_OptHeader32_Size_MIN = 96; - -static inline bool CheckPeOffset(UInt32 pe) -{ - return (pe >= 0x40 && pe <= 0x1000 && (pe & 7) == 0); -} - - -static bool IsArc_Pe(const Byte *p, size_t size) -{ - if (size < 2) - return false; - if (p[0] != 'M' || p[1] != 'Z') - return false; - if (size < k_PE_StartSize) - return false; // k_IsArc_Res_NEED_MORE; - UInt32 pe = Get32(p + 0x3C); - if (!CheckPeOffset(pe)) - return false; - if (pe + k_PE_HeaderSize > size) - return false; // k_IsArc_Res_NEED_MORE; - - p += pe; - if (Get32(p) != 0x00004550) - return false; - return Get16(p + 4 + 16) >= k_PE_OptHeader32_Size_MIN; -} - -HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition) -{ - Clear(); - - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &StartOffset)); - - const UInt32 kStartHeaderSize = 4 * 7; - const unsigned kStep = 512; // nsis start is aligned for 512 - Byte buf[kStep]; - UInt64 pos = StartOffset; - size_t bufSize = 0; - UInt64 pePos = (UInt64)(Int64)-1; - - for (;;) - { - bufSize = kStep; - RINOK(ReadStream(inStream, buf, &bufSize)); - if (bufSize < kStartHeaderSize) - return S_FALSE; - if (memcmp(buf + 4, kSignature, kSignatureSize) == 0) - break; - if (IsArc_Pe(buf, bufSize)) - pePos = pos; - pos += kStep; - UInt64 proc = pos - StartOffset; - if (maxCheckStartPosition && proc > *maxCheckStartPosition) - { - if (pePos == 0) - { - if (proc > (1 << 20)) - return S_FALSE; - } - else - return S_FALSE; - } - } - - if (pePos == (UInt64)(Int64)-1) - { - UInt64 posCur = StartOffset; - for (;;) - { - if (posCur < kStep) - break; - posCur -= kStep; - if (pos - posCur > (1 << 20)) - break; - bufSize = kStep; - RINOK(inStream->Seek(posCur, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(inStream, buf, &bufSize)); - if (bufSize < kStep) - break; - if (IsArc_Pe(buf, bufSize)) - { - pePos = posCur; - break; - } - } - - // restore buf to nsis header - bufSize = kStep; - RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(inStream, buf, &bufSize)); - if (bufSize < kStartHeaderSize) - return S_FALSE; - } - - StartOffset = pos; - UInt32 peSize = 0; - - if (pePos != (UInt64)(Int64)-1) - { - UInt64 peSize64 = (pos - pePos); - if (peSize64 < (1 << 20)) - { - peSize = (UInt32)peSize64; - StartOffset = pePos; - } - } - - DataStreamOffset = pos + kStartHeaderSize; - FirstHeader.Flags = Get32(buf); - if ((FirstHeader.Flags & (~kFlagsMask)) != 0) - return S_FALSE; - IsInstaller = (FirstHeader.Flags & NFlags::kUninstall) == 0; - - FirstHeader.HeaderSize = Get32(buf + kSignatureSize + 4); - FirstHeader.ArcSize = Get32(buf + kSignatureSize + 8); - if (FirstHeader.ArcSize <= kStartHeaderSize) - return S_FALSE; - - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_fileSize)); - - IsArc = true; - - if (peSize != 0) - { - ExeStub.Alloc(peSize); - RINOK(inStream->Seek(pePos, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, ExeStub, peSize)); - } - - HRESULT res = S_FALSE; - try - { - CLimitedInStream *_limitedStreamSpec = new CLimitedInStream; - _stream = _limitedStreamSpec; - _limitedStreamSpec->SetStream(inStream); - _limitedStreamSpec->InitAndSeek(pos, FirstHeader.ArcSize); - DataStreamOffset -= pos; - res = Open2(buf + kStartHeaderSize, bufSize - kStartHeaderSize); - } - catch(...) - { - _stream.Release(); - throw; - // res = S_FALSE; - } - if (res != S_OK) - { - _stream.Release(); - // Clear(); - } - return res; -} - -UString CInArchive::ConvertToUnicode(const AString &s) const -{ - if (IsUnicode) - { - UString res; - if (ConvertUTF8ToUnicode(s, res)) - return res; - } - return MultiByteToUnicodeString(s); -} - -void CInArchive::Clear2() -{ - IsUnicode = false; - NsisType = k_NsisType_Nsis2; - IsNsis225 = false; - IsNsis200 = false; - LogCmdIsEnabled = false; - BadCmd = -1; - - #ifdef NSIS_SCRIPT - Name.Empty(); - BrandingText.Empty(); - Script.Empty(); - LicenseFiles.Clear(); - _numRootLicenses = 0; - _numLangStrings = 0; - langStrIDs.Clear(); - LangComment.Empty(); - noParseStringIndexes.Clear(); - #endif - - APrefixes.Clear(); - UPrefixes.Clear(); - Items.Clear(); - IsUnicode = false; - ExeStub.Free(); -} - -void CInArchive::Clear() -{ - Clear2(); - IsArc = false; - _stream.Release(); -} - -}} +// NsisIn.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/LimitedStreams.h" + +#include "NsisIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +// #define NUM_SPEED_TESTS 1000 + +namespace NArchive { +namespace NNsis { + +static const size_t kInputBufSize = 1 << 20; + +const Byte kSignature[kSignatureSize] = NSIS_SIGNATURE; +static const UInt32 kMask_IsCompressed = (UInt32)1 << 31; + +static const unsigned kNumCommandParams = 6; +static const unsigned kCmdSize = 4 + kNumCommandParams * 4; + +#ifdef NSIS_SCRIPT +#define CR_LF "\x0D\x0A" +#endif + +static const char * const kErrorStr = "$_ERROR_STR_"; + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + + +/* There are several versions of NSIS: + 1) Original NSIS: + NSIS-2 ANSI + NSIS-3 ANSI + NSIS-3 Unicode + 2) NSIS from Jim Park that extends old NSIS-2 to Unicode support: + NSIS-Park-(1,2,3) ANSI + NSIS-Park-(1,2,3) Unicode + + The command IDs layout is slightly different for different versions. + Also there are additional "log" versions of NSIS that support EW_LOG. + We use the layout of "NSIS-3 Unicode" without "log" as main layout. + And we transfer the command IDs to main layout, if another layout is detected. */ + + +enum +{ + EW_INVALID_OPCODE, + EW_RET, // Return + EW_NOP, // Nop, Goto + EW_ABORT, // Abort + EW_QUIT, // Quit + EW_CALL, // Call, InitPluginsDir + EW_UPDATETEXT, // DetailPrint + EW_SLEEP, // Sleep + EW_BRINGTOFRONT, // BringToFront + EW_CHDETAILSVIEW, // SetDetailsView + EW_SETFILEATTRIBUTES, // SetFileAttributes + EW_CREATEDIR, // CreateDirectory, SetOutPath + EW_IFFILEEXISTS, // IfFileExists + EW_SETFLAG, // SetRebootFlag, ... + EW_IFFLAG, // IfAbort, IfSilent, IfErrors, IfRebootFlag + EW_GETFLAG, // GetInstDirError, GetErrorLevel + EW_RENAME, // Rename + EW_GETFULLPATHNAME, // GetFullPathName + EW_SEARCHPATH, // SearchPath + EW_GETTEMPFILENAME, // GetTempFileName + EW_EXTRACTFILE, // File + EW_DELETEFILE, // Delete + EW_MESSAGEBOX, // MessageBox + EW_RMDIR, // RMDir + EW_STRLEN, // StrLen + EW_ASSIGNVAR, // StrCpy + EW_STRCMP, // StrCmp + EW_READENVSTR, // ReadEnvStr, ExpandEnvStrings + EW_INTCMP, // IntCmp, IntCmpU + EW_INTOP, // IntOp + EW_INTFMT, // IntFmt/Int64Fmt + EW_PUSHPOP, // Push/Pop/Exchange + EW_FINDWINDOW, // FindWindow + EW_SENDMESSAGE, // SendMessage + EW_ISWINDOW, // IsWindow + EW_GETDLGITEM, // GetDlgItem + EW_SETCTLCOLORS, // SetCtlColors + EW_SETBRANDINGIMAGE, // SetBrandingImage / LoadAndSetImage + EW_CREATEFONT, // CreateFont + EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow + EW_SHELLEXEC, // ExecShell + EW_EXECUTE, // Exec, ExecWait + EW_GETFILETIME, // GetFileTime + EW_GETDLLVERSION, // GetDLLVersion + + // EW_GETFONTVERSION, // Park : 2.46.2 + // EW_GETFONTNAME, // Park : 2.46.3 + + EW_REGISTERDLL, // RegDLL, UnRegDLL, CallInstDLL + EW_CREATESHORTCUT, // CreateShortCut + EW_COPYFILES, // CopyFiles + EW_REBOOT, // Reboot + EW_WRITEINI, // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI + EW_READINISTR, // ReadINIStr + EW_DELREG, // DeleteRegValue, DeleteRegKey + EW_WRITEREG, // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD + EW_READREGSTR, // ReadRegStr, ReadRegDWORD + EW_REGENUM, // EnumRegKey, EnumRegValue + EW_FCLOSE, // FileClose + EW_FOPEN, // FileOpen + EW_FPUTS, // FileWrite, FileWriteByte + EW_FGETS, // FileRead, FileReadByte + + // Park + // EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord + // EW_FGETWS, // FileReadUTF16LE, FileReadWord + + EW_FSEEK, // FileSeek + EW_FINDCLOSE, // FindClose + EW_FINDNEXT, // FindNext + EW_FINDFIRST, // FindFirst + EW_WRITEUNINSTALLER, // WriteUninstaller + + // Park : since 2.46.3 the log is enabled in main Park version + // EW_LOG, // LogSet, LogText + + EW_SECTIONSET, // Get*, Set* + EW_INSTTYPESET, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType + + /* + // before v3.06 nsis it was so: + // instructions not actually implemented in exehead, but used in compiler. + EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR + EW_GETFUNCTIONADDR, + */ + + // v3.06 and later it was changed to: + EW_GETOSINFO, + EW_RESERVEDOPCODE, + + EW_LOCKWINDOW, // LockWindow + + // 2 unicode commands available only in Unicode archive + EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord + EW_FGETWS, // FileReadUTF16LE, FileReadWord + + /* + // since v3.06 the fllowing IDs codes was moved here: + // Opcodes listed here are not actually used in exehead. No exehead opcodes should be present after these! + EW_GETLABELADDR, // --> EW_ASSIGNVAR + EW_GETFUNCTIONADDR, // --> EW_ASSIGNVAR + */ + + // The following IDs are not IDs in real order. + // We just need some IDs to translate eny extended layout to main layout. + + EW_LOG, // LogSet, LogText + + // Park + EW_FINDPROC, // FindProc + + EW_GETFONTVERSION, // GetFontVersion + EW_GETFONTNAME, // GetFontName + + kNumCmds +}; + + + +struct CCommandInfo +{ + Byte NumParams; +}; + +static const CCommandInfo k_Commands[kNumCmds] = +{ + { 0 }, // "Invalid" }, + { 0 }, // Return + { 1 }, // Nop, Goto + { 1 }, // "Abort" }, + { 0 }, // "Quit" }, + { 2 }, // Call + { 6 }, // "DetailPrint" }, // 1 param in new versions, 6 in old NSIS versions + { 1 }, // "Sleep" }, + { 0 }, // "BringToFront" }, + { 2 }, // "SetDetailsView" }, + { 2 }, // "SetFileAttributes" }, + { 3 }, // CreateDirectory, SetOutPath + { 3 }, // "IfFileExists" }, + { 3 }, // SetRebootFlag, ... + { 4 }, // "If" }, // IfAbort, IfSilent, IfErrors, IfRebootFlag + { 2 }, // "Get" }, // GetInstDirError, GetErrorLevel + { 4 }, // "Rename" }, + { 3 }, // "GetFullPathName" }, + { 2 }, // "SearchPath" }, + { 2 }, // "GetTempFileName" }, + { 6 }, // "File" + { 2 }, // "Delete" }, + { 6 }, // "MessageBox" }, + { 2 }, // "RMDir" }, + { 2 }, // "StrLen" }, + { 4 }, // StrCpy, GetCurrentAddress + { 5 }, // "StrCmp" }, + { 3 }, // ReadEnvStr, ExpandEnvStrings + { 6 }, // "IntCmp" }, + { 4 }, // "IntOp" }, + { 4 }, // "IntFmt" }, EW_INTFMT + { 6 }, // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. + { 5 }, // "FindWindow" }, + { 6 }, // "SendMessage" }, + { 3 }, // "IsWindow" }, + { 3 }, // "GetDlgItem" }, + { 2 }, // "SetCtlColors" }, + { 4 }, // "SetBrandingImage" } // LoadAndSetImage + { 5 }, // "CreateFont" }, + { 4 }, // ShowWindow, EnableWindow, HideWindow + { 6 }, // "ExecShell" }, + { 3 }, // "Exec" }, // Exec, ExecWait + { 3 }, // "GetFileTime" }, + { 4 }, // "GetDLLVersion" }, + { 6 }, // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage. + { 6 }, // "CreateShortCut" }, + { 4 }, // "CopyFiles" }, + { 1 }, // "Reboot" }, + { 5 }, // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI + { 4 }, // "ReadINIStr" }, + { 5 }, // "DeleteReg" }, // DeleteRegKey, DeleteRegValue + { 6 }, // "WriteReg" }, // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD + { 5 }, // "ReadReg" }, // ReadRegStr, ReadRegDWORD + { 5 }, // "EnumReg" }, // EnumRegKey, EnumRegValue + { 1 }, // "FileClose" }, + { 4 }, // "FileOpen" }, + { 3 }, // "FileWrite" }, // FileWrite, FileWriteByte + { 4 }, // "FileRead" }, // FileRead, FileReadByte + { 4 }, // "FileSeek" }, + { 1 }, // "FindClose" }, + { 2 }, // "FindNext" }, + { 3 }, // "FindFirst" }, + { 4 }, // "WriteUninstaller" }, + { 5 }, // "Section" }, // *** + { 4 }, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType + + // { 6 }, // "GetLabelAddr" }, // before 3.06 + { 6 }, // "GetOsInfo" }, GetKnownFolderPath, ReadMemory, // v3.06+ + + { 2 }, // "GetFunctionAddress" }, // before 3.06 + + { 1 }, // "LockWindow" }, + { 4 }, // "FileWrite" }, // FileWriteUTF16LE, FileWriteWord + { 4 }, // "FileRead" }, // FileReadUTF16LE, FileReadWord + + { 2 }, // "Log" }, // LogSet, LogText + // Park + { 2 }, // "FindProc" }, + { 2 }, // "GetFontVersion" }, + { 2 }, // "GetFontName" } +}; + +#ifdef NSIS_SCRIPT + +static const char * const k_CommandNames[kNumCmds] = +{ + "Invalid" + , NULL // Return + , NULL // Nop, Goto + , "Abort" + , "Quit" + , NULL // Call + , "DetailPrint" // 1 param in new versions, 6 in old NSIS versions + , "Sleep" + , "BringToFront" + , "SetDetailsView" + , "SetFileAttributes" + , NULL // CreateDirectory, SetOutPath + , "IfFileExists" + , NULL // SetRebootFlag, ... + , "If" // IfAbort, IfSilent, IfErrors, IfRebootFlag + , "Get" // GetInstDirError, GetErrorLevel + , "Rename" + , "GetFullPathName" + , "SearchPath" + , "GetTempFileName" + , NULL // File + , "Delete" + , "MessageBox" + , "RMDir" + , "StrLen" + , NULL // StrCpy, GetCurrentAddress + , "StrCmp" + , NULL // ReadEnvStr, ExpandEnvStrings + , NULL // IntCmp / Int64Cmp / EW_INTCMP + , "IntOp" + , NULL // IntFmt / Int64Fmt / EW_INTFMT + , NULL // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. + , "FindWindow" + , "SendMessage" + , "IsWindow" + , "GetDlgItem" + , "SetCtlColors" + , "SetBrandingImage" + , "CreateFont" + , NULL // ShowWindow, EnableWindow, HideWindow + , "ExecShell" + , "Exec" // Exec, ExecWait + , "GetFileTime" + , "GetDLLVersion" + , NULL // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage. + , "CreateShortCut" + , "CopyFiles" + , "Reboot" + , NULL // WriteINIStr, DeleteINISec, DeleteINIStr, FlushINI + , "ReadINIStr" + , "DeleteReg" // DeleteRegKey, DeleteRegValue + , "WriteReg" // WriteRegStr, WriteRegExpandStr, WriteRegBin, WriteRegDWORD + , "ReadReg" // ReadRegStr, ReadRegDWORD + , "EnumReg" // EnumRegKey, EnumRegValue + , "FileClose" + , "FileOpen" + , "FileWrite" // FileWrite, FileWriteByte + , "FileRead" // FileRead, FileReadByte + , "FileSeek" + , "FindClose" + , "FindNext" + , "FindFirst" + , "WriteUninstaller" + , "Section" // *** + , NULL // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType + + , NULL // "GetOsInfo" // , "GetLabelAddr" // + , "GetFunctionAddress" + + , "LockWindow" + , "FileWrite" // FileWriteUTF16LE, FileWriteWord + , "FileRead" // FileReadUTF16LE, FileReadWord + + , "Log" // LogSet, LogText + + // Park + , "FindProc" + , "GetFontVersion" + , "GetFontName" +}; + +#endif + +/* NSIS can use one name for two CSIDL_*** and CSIDL_COMMON_*** items (CurrentUser / AllUsers) + Some NSIS shell names are not identical to WIN32 CSIDL_* names. + NSIS doesn't use some CSIDL_* values. But we add name for all CSIDL_ (marked with '+'). */ + +static const char * const kShellStrings[] = +{ + "DESKTOP" // + + , "INTERNET" // + + , "SMPROGRAMS" // CSIDL_PROGRAMS + , "CONTROLS" // + + , "PRINTERS" // + + , "DOCUMENTS" // CSIDL_PERSONAL + , "FAVORITES" // CSIDL_FAVORITES + , "SMSTARTUP" // CSIDL_STARTUP + , "RECENT" // CSIDL_RECENT + , "SENDTO" // CSIDL_SENDTO + , "BITBUCKET" // + + , "STARTMENU" + , NULL // CSIDL_MYDOCUMENTS = CSIDL_PERSONAL + , "MUSIC" // CSIDL_MYMUSIC + , "VIDEOS" // CSIDL_MYVIDEO + , NULL + , "DESKTOP" // CSIDL_DESKTOPDIRECTORY + , "DRIVES" // + + , "NETWORK" // + + , "NETHOOD" + , "FONTS" + , "TEMPLATES" + , "STARTMENU" // CSIDL_COMMON_STARTMENU + , "SMPROGRAMS" // CSIDL_COMMON_PROGRAMS + , "SMSTARTUP" // CSIDL_COMMON_STARTUP + , "DESKTOP" // CSIDL_COMMON_DESKTOPDIRECTORY + , "APPDATA" // CSIDL_APPDATA !!! "QUICKLAUNCH" + , "PRINTHOOD" + , "LOCALAPPDATA" + , "ALTSTARTUP" + , "ALTSTARTUP" // CSIDL_COMMON_ALTSTARTUP + , "FAVORITES" // CSIDL_COMMON_FAVORITES + , "INTERNET_CACHE" + , "COOKIES" + , "HISTORY" + , "APPDATA" // CSIDL_COMMON_APPDATA + , "WINDIR" + , "SYSDIR" + , "PROGRAM_FILES" // + + , "PICTURES" // CSIDL_MYPICTURES + , "PROFILE" + , "SYSTEMX86" // + + , "PROGRAM_FILESX86" // + + , "PROGRAM_FILES_COMMON" // + + , "PROGRAM_FILES_COMMONX8" // + CSIDL_PROGRAM_FILES_COMMONX86 + , "TEMPLATES" // CSIDL_COMMON_TEMPLATES + , "DOCUMENTS" // CSIDL_COMMON_DOCUMENTS + , "ADMINTOOLS" // CSIDL_COMMON_ADMINTOOLS + , "ADMINTOOLS" // CSIDL_ADMINTOOLS + , "CONNECTIONS" // + + , NULL + , NULL + , NULL + , "MUSIC" // CSIDL_COMMON_MUSIC + , "PICTURES" // CSIDL_COMMON_PICTURES + , "VIDEOS" // CSIDL_COMMON_VIDEO + , "RESOURCES" + , "RESOURCES_LOCALIZED" + , "COMMON_OEM_LINKS" // + + , "CDBURN_AREA" + , NULL // unused + , "COMPUTERSNEARME" // + +}; + + +static inline void UIntToString(AString &s, UInt32 v) +{ + s.Add_UInt32(v); +} + +#ifdef NSIS_SCRIPT + +void CInArchive::Add_UInt(UInt32 v) +{ + char sz[16]; + ConvertUInt32ToString(v, sz); + Script += sz; +} + +static void Add_SignedInt(CDynLimBuf &s, Int32 v) +{ + char sz[32]; + ConvertInt64ToString(v, sz); + s += sz; +} + +static void Add_Hex(CDynLimBuf &s, UInt32 v) +{ + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(v, sz + 2); + s += sz; +} + +static UInt32 GetUi16Str_Len(const Byte *p) +{ + const Byte *pp = p; + for (; *pp != 0 || *(pp + 1) != 0; pp += 2); + return (UInt32)((pp - p) >> 1); +} + +void CInArchive::AddLicense(UInt32 param, Int32 langID) +{ + Space(); + if (param >= NumStringChars || + param + 1 >= NumStringChars) + { + Script += kErrorStr; + return; + } + strUsed[param] = 1; + + const UInt32 start = _stringsPos + (IsUnicode ? param * 2 : param); + const UInt32 offset = start + (IsUnicode ? 2 : 1); + { + FOR_VECTOR (i, LicenseFiles) + { + const CLicenseFile &lic = LicenseFiles[i]; + if (offset == lic.Offset) + { + Script += lic.Name; + return; + } + } + } + AString fileName ("[LICENSE]"); + if (langID >= 0) + { + fileName += "\\license-"; + // LangId_To_String(fileName, langID); + UIntToString(fileName, (UInt32)langID); + } + else if (++_numRootLicenses > 1) + { + fileName.Add_Minus(); + UIntToString(fileName, _numRootLicenses); + } + const Byte *sz = (_data + start); + const unsigned marker = IsUnicode ? Get16(sz) : *sz; + const bool isRTF = (marker == 2); + fileName += isRTF ? ".rtf" : ".txt"; // if (*sz == 1) it's text; + Script += fileName; + + CLicenseFile &lic = LicenseFiles.AddNew(); + lic.Name = fileName; + lic.Offset = offset; + if (!IsUnicode) + lic.Size = (UInt32)strlen((const char *)sz + 1); + else + { + sz += 2; + const UInt32 len = GetUi16Str_Len(sz); + lic.Size = len * 2; + if (isRTF) + { + lic.Text.Alloc((size_t)len); + for (UInt32 i = 0; i < len; i++, sz += 2) + { + unsigned c = Get16(sz); + if (c >= 256) + c = '?'; + lic.Text[i] = (Byte)(c); + } + lic.Size = len; + lic.Offset = 0; + } + } +} + +#endif + + +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_GENERIC_READ ((UInt32)1 << 31) +#endif +#define Z7_NSIS_WIN_GENERIC_WRITE ((UInt32)1 << 30) +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_GENERIC_EXECUTE ((UInt32)1 << 29) +#define Z7_NSIS_WIN_GENERIC_ALL ((UInt32)1 << 28) +#endif + +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_CREATE_NEW 1 +#endif +#define Z7_NSIS_WIN_CREATE_ALWAYS 2 +#ifdef NSIS_SCRIPT +#define Z7_NSIS_WIN_OPEN_EXISTING 3 +#define Z7_NSIS_WIN_OPEN_ALWAYS 4 +#define Z7_NSIS_WIN_TRUNCATE_EXISTING 5 +#endif + + +// #define kVar_CMDLINE 20 +#define kVar_INSTDIR 21 +#define kVar_OUTDIR 22 +#define kVar_EXEDIR 23 +// #define kVar_LANGUAGE 24 +#define kVar_TEMP 25 +#define kVar_PLUGINSDIR 26 +#define kVar_EXEPATH 27 // NSIS 2.26+ +// #define kVar_EXEFILE 28 // NSIS 2.26+ + +#define kVar_HWNDPARENT_225 27 +#ifdef NSIS_SCRIPT +#define kVar_HWNDPARENT 29 +#endif + +// #define kVar__CLICK 30 +#define kVar_Spec_OUTDIR_225 29 // NSIS 2.04 - 2.25 +#define kVar_Spec_OUTDIR 31 // NSIS 2.26+ + + +static const char * const kVarStrings[] = +{ + "CMDLINE" + , "INSTDIR" + , "OUTDIR" + , "EXEDIR" + , "LANGUAGE" + , "TEMP" + , "PLUGINSDIR" + , "EXEPATH" // NSIS 2.26+ + , "EXEFILE" // NSIS 2.26+ + , "HWNDPARENT" + , "_CLICK" // is set from page->clicknext + , "_OUTDIR" // NSIS 2.04+ +}; + +static const unsigned kNumInternalVars = 20 + Z7_ARRAY_SIZE(kVarStrings); + +#define GET_NUM_INTERNAL_VARS (IsNsis200 ? kNumInternalVars - 3 : IsNsis225 ? kNumInternalVars - 2 : kNumInternalVars) + +void CInArchive::GetVar2(AString &res, UInt32 index) +{ + if (index < 20) + { + if (index >= 10) + { + res += 'R'; + index -= 10; + } + UIntToString(res, index); + } + else + { + unsigned numInternalVars = GET_NUM_INTERNAL_VARS; + if (index < numInternalVars) + { + if (IsNsis225 && index >= kVar_EXEPATH) + index += 2; + res += kVarStrings[index - 20]; + } + else + { + res += '_'; + UIntToString(res, index - numInternalVars); + res += '_'; + } + } +} + +void CInArchive::GetVar(AString &res, UInt32 index) +{ + res += '$'; + GetVar2(res, index); +} + +#ifdef NSIS_SCRIPT + +void CInArchive::Add_Var(UInt32 index) +{ + _tempString_for_GetVar.Empty(); + GetVar(_tempString_for_GetVar, index); + Script += _tempString_for_GetVar; +} + +void CInArchive::AddParam_Var(UInt32 index) +{ + Space(); + Add_Var(index); +} + +void CInArchive::AddParam_UInt(UInt32 value) +{ + Space(); + Add_UInt(value); +} + +#endif + + +#define NS_CODE_SKIP 252 +#define NS_CODE_VAR 253 +#define NS_CODE_SHELL 254 +// #define NS_CODE_LANG 255 + +// #define NS_3_CODE_LANG 1 +#define NS_3_CODE_SHELL 2 +#define NS_3_CODE_VAR 3 +#define NS_3_CODE_SKIP 4 + +#define PARK_CODE_SKIP 0xE000 +#define PARK_CODE_VAR 0xE001 +#define PARK_CODE_SHELL 0xE002 +#define PARK_CODE_LANG 0xE003 + +#define IS_NS_SPEC_CHAR(c) ((c) >= NS_CODE_SKIP) +#define IS_PARK_SPEC_CHAR(c) ((c) >= PARK_CODE_SKIP && (c) <= PARK_CODE_LANG) + +#define DECODE_NUMBER_FROM_2_CHARS(c0, c1) (((unsigned)(c0) & 0x7F) | (((unsigned)((c1) & 0x7F)) << 7)) +#define CONVERT_NUMBER_NS_3_UNICODE(n) n = ((n & 0x7F) | (((n >> 8) & 0x7F) << 7)) +#define CONVERT_NUMBER_PARK(n) n &= 0x7FFF + + +static bool AreStringsEqual_16and8(const Byte *p16, const char *p8) +{ + for (;;) + { + unsigned c16 = Get16(p16); p16 += 2; + unsigned c = (Byte)(*p8++); + if (c16 != c) + return false; + if (c == 0) + return true; + } +} + +void CInArchive::GetShellString(AString &s, unsigned index1, unsigned index2) +{ + // zeros are not allowed here. + // if (index1 == 0 || index2 == 0) throw 333; + + if ((index1 & 0x80) != 0) + { + unsigned offset = (index1 & 0x3F); + + /* NSIS reads registry string: + keyName = HKLM Software\\Microsoft\\Windows\\CurrentVersion + mask = KEY_WOW64_64KEY, If 64-bit flag in index1 is set + valueName = string(offset) + If registry reading is failed, NSIS uses second parameter (index2) + to read string. The recursion is possible in that case in NSIS. + We don't parse index2 string. We only set strUsed status for that + string (but without recursion). */ + + if (offset >= NumStringChars) + { + s += kErrorStr; + return; + } + + #ifdef NSIS_SCRIPT + strUsed[offset] = 1; + if (index2 < NumStringChars) + strUsed[index2] = 1; + #endif + + const Byte *p = (const Byte *)(_data + _stringsPos); + int id = -1; + if (IsUnicode) + { + p += offset * 2; + if (AreStringsEqual_16and8(p, "ProgramFilesDir")) + id = 0; + else if (AreStringsEqual_16and8(p, "CommonFilesDir")) + id = 1; + } + else + { + p += offset; + if (strcmp((const char *)p, "ProgramFilesDir") == 0) + id = 0; + else if (strcmp((const char *)p, "CommonFilesDir") == 0) + id = 1; + } + + s += ((id >= 0) ? (id == 0 ? "$PROGRAMFILES" : "$COMMONFILES") : + "$_ERROR_UNSUPPORTED_VALUE_REGISTRY_"); + // s += ((index1 & 0x40) != 0) ? "64" : "32"; + if ((index1 & 0x40) != 0) + s += "64"; + + if (id < 0) + { + s += '('; + if (IsUnicode) + { + for (unsigned i = 0; i < 256; i++) + { + wchar_t c = Get16(p + i * 2); + if (c == 0) + break; + if (c < 0x80) + s += (char)c; + } + } + else + s += (const char *)p; + s += ')'; + } + return; + } + + s += '$'; + if (index1 < Z7_ARRAY_SIZE(kShellStrings)) + { + const char *sz = kShellStrings[index1]; + if (sz) + { + s += sz; + return; + } + } + if (index2 < Z7_ARRAY_SIZE(kShellStrings)) + { + const char *sz = kShellStrings[index2]; + if (sz) + { + s += sz; + return; + } + } + s += "_ERROR_UNSUPPORTED_SHELL_"; + s += '['; + UIntToString(s, index1); + s += ','; + UIntToString(s, index2); + s += ']'; +} + +#ifdef NSIS_SCRIPT + +void CInArchive::Add_LangStr_Simple(UInt32 id) +{ + Script += "LSTR_"; + Add_UInt(id); +} + +#endif + +void CInArchive::Add_LangStr(AString &res, UInt32 id) +{ + #ifdef NSIS_SCRIPT + langStrIDs.Add(id); + #endif + res += "$(LSTR_"; + UIntToString(res, id); + res += ')'; +} + +void CInArchive::GetNsisString_Raw(const Byte *s) +{ + Raw_AString.Empty(); + + if (NsisType != k_NsisType_Nsis3) + { + for (;;) + { + Byte c = *s++; + if (c == 0) + return; + if (IS_NS_SPEC_CHAR(c)) + { + Byte c0 = *s++; + if (c0 == 0) + return; + if (c != NS_CODE_SKIP) + { + Byte c1 = *s++; + if (c1 == 0) + return; + + if (c == NS_CODE_SHELL) + GetShellString(Raw_AString, c0, c1); + else + { + unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + if (c == NS_CODE_VAR) + GetVar(Raw_AString, n); + else // if (c == NS_CODE_LANG) + Add_LangStr(Raw_AString, n); + } + continue; + } + c = c0; + } + Raw_AString += (char)c; + } + } + + // NSIS-3 ANSI + for (;;) + { + Byte c = *s++; + if (c <= NS_3_CODE_SKIP) + { + if (c == 0) + return; + Byte c0 = *s++; + if (c0 == 0) + return; + if (c != NS_3_CODE_SKIP) + { + Byte c1 = *s++; + if (c1 == 0) + return; + + if (c == NS_3_CODE_SHELL) + GetShellString(Raw_AString, c0, c1); + else + { + unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + if (c == NS_3_CODE_VAR) + GetVar(Raw_AString, n); + else // if (c == NS_3_CODE_LANG) + Add_LangStr(Raw_AString, n); + } + continue; + } + c = c0; + } + Raw_AString += (char)c; + } +} + +#ifdef NSIS_SCRIPT + +void CInArchive::GetNsisString(AString &res, const Byte *s) +{ + for (;;) + { + Byte c = *s++; + if (c == 0) + return; + if (NsisType != k_NsisType_Nsis3) + { + if (IS_NS_SPEC_CHAR(c)) + { + Byte c0 = *s++; + if (c0 == 0) + return; + if (c != NS_CODE_SKIP) + { + Byte c1 = *s++; + if (c1 == 0) + return; + if (c == NS_CODE_SHELL) + GetShellString(res, c0, c1); + else + { + unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + if (c == NS_CODE_VAR) + GetVar(res, n); + else // if (c == NS_CODE_LANG) + Add_LangStr(res, n); + } + continue; + } + c = c0; + } + } + else + { + // NSIS-3 ANSI + if (c <= NS_3_CODE_SKIP) + { + Byte c0 = *s++; + if (c0 == 0) + return; + if (c0 == 0) + break; + if (c != NS_3_CODE_SKIP) + { + Byte c1 = *s++; + if (c1 == 0) + return; + if (c == NS_3_CODE_SHELL) + GetShellString(res, c0, c1); + else + { + unsigned n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + if (c == NS_3_CODE_VAR) + GetVar(res, n); + else // if (c == NS_3_CODE_LANG) + Add_LangStr(res, n); + } + continue; + } + c = c0; + } + } + + { + const char *e; + if (c == 9) e = "$\\t"; + else if (c == 10) e = "$\\n"; + else if (c == 13) e = "$\\r"; + else if (c == '"') e = "$\\\""; + else if (c == '$') e = "$$"; + else + { + res += (char)c; + continue; + } + res += e; + continue; + } + } +} + +#endif + +void CInArchive::GetNsisString_Unicode_Raw(const Byte *p) +{ + Raw_UString.Empty(); + + if (IsPark()) + { + for (;;) + { + unsigned c = Get16(p); + p += 2; + if (c == 0) + break; + if (c < 0x80) + { + Raw_UString.Add_Char((char)c); + continue; + } + + if (IS_PARK_SPEC_CHAR(c)) + { + unsigned n = Get16(p); + p += 2; + if (n == 0) + break; + if (c != PARK_CODE_SKIP) + { + Raw_AString.Empty(); + if (c == PARK_CODE_SHELL) + GetShellString(Raw_AString, n & 0xFF, n >> 8); + else + { + CONVERT_NUMBER_PARK(n); + if (c == PARK_CODE_VAR) + GetVar(Raw_AString, n); + else // if (c == PARK_CODE_LANG) + Add_LangStr(Raw_AString, n); + } + Raw_UString += Raw_AString.Ptr(); // check it ! + continue; + } + c = n; + } + + Raw_UString += (wchar_t)c; + } + + return; + } + + // NSIS-3 Unicode + for (;;) + { + unsigned c = Get16(p); + p += 2; + if (c > NS_3_CODE_SKIP) + { + Raw_UString += (wchar_t)c; + continue; + } + if (c == 0) + break; + + unsigned n = Get16(p); + p += 2; + if (n == 0) + break; + if (c == NS_3_CODE_SKIP) + { + Raw_UString += (wchar_t)n; + continue; + } + + Raw_AString.Empty(); + if (c == NS_3_CODE_SHELL) + GetShellString(Raw_AString, n & 0xFF, n >> 8); + else + { + CONVERT_NUMBER_NS_3_UNICODE(n); + if (c == NS_3_CODE_VAR) + GetVar(Raw_AString, n); + else // if (c == NS_3_CODE_LANG) + Add_LangStr(Raw_AString, n); + } + Raw_UString += Raw_AString.Ptr(); + } +} + +#ifdef NSIS_SCRIPT + +static const Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +void CInArchive::GetNsisString_Unicode(AString &res, const Byte *p) +{ + for (;;) + { + unsigned c = Get16(p); + p += 2; + if (c == 0) + break; + if (IsPark()) + { + if (IS_PARK_SPEC_CHAR(c)) + { + unsigned n = Get16(p); + p += 2; + if (n == 0) + break; + if (c != PARK_CODE_SKIP) + { + if (c == PARK_CODE_SHELL) + GetShellString(res, n & 0xFF, n >> 8); + else + { + CONVERT_NUMBER_PARK(n); + if (c == PARK_CODE_VAR) + GetVar(res, n); + else // if (c == PARK_CODE_LANG) + Add_LangStr(res, n); + } + continue; + } + c = n; + } + } + else + { + // NSIS-3 Unicode + if (c <= NS_3_CODE_SKIP) + { + unsigned n = Get16(p); + p += 2; + if (n == 0) + break; + if (c != NS_3_CODE_SKIP) + { + if (c == NS_3_CODE_SHELL) + GetShellString(res, n & 0xFF, n >> 8); + else + { + CONVERT_NUMBER_NS_3_UNICODE(n); + if (c == NS_3_CODE_VAR) + GetVar(res, n); + else // if (c == NS_3_CODE_LANG) + Add_LangStr(res, n); + } + continue; + } + c = n; + } + } + + if (c < 0x80) + { + const char *e; + if (c == 9) e = "$\\t"; + else if (c == 10) e = "$\\n"; + else if (c == 13) e = "$\\r"; + else if (c == '"') e = "$\\\""; + else if (c == '$') e = "$$"; + else + { + res += (char)c; + continue; + } + res += e; + continue; + } + + UInt32 value = c; + /* + if (value >= 0xD800 && value < 0xE000) + { + UInt32 c2; + if (value >= 0xDC00 || srcPos == srcLen) + break; + c2 = src[srcPos++]; + if (c2 < 0xDC00 || c2 >= 0xE000) + break; + value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; + } + */ + unsigned numAdds; + for (numAdds = 1; numAdds < 5; numAdds++) + if (value < (((UInt32)1) << (numAdds * 5 + 6))) + break; + res += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); + do + { + numAdds--; + res += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); + // destPos++; + } + while (numAdds != 0); + + // AddToUtf8(res, c); + } +} + +#endif + +void CInArchive::ReadString2_Raw(UInt32 pos) +{ + Raw_AString.Empty(); + Raw_UString.Empty(); + if ((Int32)pos < 0) + Add_LangStr(Raw_AString, (UInt32)-((Int32)pos + 1)); + else if (pos >= NumStringChars) + { + Raw_AString += kErrorStr; + // UIntToString(Raw_AString, pos); + } + else + { + if (IsUnicode) + GetNsisString_Unicode_Raw(_data + _stringsPos + pos * 2); + else + GetNsisString_Raw(_data + _stringsPos + pos); + return; + } + Raw_UString = Raw_AString.Ptr(); +} + +bool CInArchive::IsGoodString(UInt32 param) const +{ + if (param >= NumStringChars) + return false; + if (param == 0) + return true; + const Byte *p = _data + _stringsPos; + unsigned c; + if (IsUnicode) + c = Get16(p + param * 2 - 2); + else + c = p[param - 1]; + // some files have '\\' character before string? + return (c == 0 || c == '\\'); +} + +bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const +{ + if (param1 == param2) + return true; + + /* NSIS-3.0a1 probably contains bug, so it can use 2 different strings + with same content. So we check real string also. + Also it's possible to check identical postfix parts of strings. */ + + if (param1 >= NumStringChars || + param2 >= NumStringChars) + return false; + + const Byte *p = _data + _stringsPos; + + if (IsUnicode) + { + const Byte *p1 = p + param1 * 2; + const Byte *p2 = p + param2 * 2; + for (;;) + { + UInt16 c = Get16(p1); + if (c != Get16(p2)) + return false; + if (c == 0) + return true; + p1 += 2; + p2 += 2; + } + } + else + { + const Byte *p1 = p + param1; + const Byte *p2 = p + param2; + for (;;) + { + Byte c = *p1++; + if (c != *p2++) + return false; + if (c == 0) + return true; + } + } +} + +#ifdef NSIS_SCRIPT + +UInt32 CInArchive::GetNumUsedVars() const +{ + UInt32 numUsedVars = 0; + const Byte *data = (const Byte *)_data + _stringsPos; + unsigned npi = 0; + for (UInt32 i = 0; i < NumStringChars;) + { + bool process = true; + if (npi < noParseStringIndexes.Size() && noParseStringIndexes[npi] == i) + { + process = false; + npi++; + } + + if (IsUnicode) + { + if (IsPark()) + { + for (;;) + { + unsigned c = Get16(data + i * 2); + i++; + if (c == 0) + break; + if (IS_PARK_SPEC_CHAR(c)) + { + UInt32 n = Get16(data + i * 2); + i++; + if (n == 0) + break; + if (process && c == PARK_CODE_VAR) + { + CONVERT_NUMBER_PARK(n); + n++; + if (numUsedVars < n) + numUsedVars = n; + } + } + } + } + else // NSIS-3 Unicode + { + for (;;) + { + unsigned c = Get16(data + i * 2); + i++; + if (c == 0) + break; + if (c > NS_3_CODE_SKIP) + continue; + UInt32 n = Get16(data + i * 2); + i++; + if (n == 0) + break; + if (process && c == NS_3_CODE_VAR) + { + CONVERT_NUMBER_NS_3_UNICODE(n); + n++; + if (numUsedVars < n) + numUsedVars = n; + } + } + } + } + else // not Unicode (ANSI) + { + if (NsisType != k_NsisType_Nsis3) + { + for (;;) + { + Byte c = data[i++]; + if (c == 0) + break; + if (IS_NS_SPEC_CHAR(c)) + { + Byte c0 = data[i++]; + if (c0 == 0) + break; + if (c == NS_CODE_SKIP) + continue; + Byte c1 = data[i++]; + if (c1 == 0) + break; + if (process && c == NS_CODE_VAR) + { + UInt32 n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + n++; + if (numUsedVars < n) + numUsedVars = n; + } + } + } + } + else + { + // NSIS-3 ANSI + for (;;) + { + Byte c = data[i++]; + if (c == 0) + break; + if (c > NS_3_CODE_SKIP) + continue; + + Byte c0 = data[i++]; + if (c0 == 0) + break; + if (c == NS_3_CODE_SKIP) + continue; + Byte c1 = data[i++]; + if (c1 == 0) + break; + if (process && c == NS_3_CODE_VAR) + { + UInt32 n = DECODE_NUMBER_FROM_2_CHARS(c0, c1); + n++; + if (numUsedVars < n) + numUsedVars = n; + } + } + } + } + } + return numUsedVars; +} + +void CInArchive::ReadString2(AString &s, UInt32 pos) +{ + if ((Int32)pos < 0) + { + Add_LangStr(s, (UInt32)-((Int32)pos + 1)); + return; + } + + if (pos >= NumStringChars) + { + s += kErrorStr; + // UIntToString(s, pos); + return; + } + + #ifdef NSIS_SCRIPT + strUsed[pos] = 1; + #endif + + if (IsUnicode) + GetNsisString_Unicode(s, _data + _stringsPos + pos * 2); + else + GetNsisString(s, _data + _stringsPos + pos); +} + +#endif + +#ifdef NSIS_SCRIPT + +// #define DEL_DIR 1 +#define DEL_RECURSE 2 +#define DEL_REBOOT 4 +// #define DEL_SIMPLE 8 + +void CInArchive::AddRegRoot(UInt32 val) +{ + Space(); + const char *s; + switch (val) + { + case 0: s = "SHCTX"; break; + case 0x80000000: s = "HKCR"; break; + case 0x80000001: s = "HKCU"; break; + case 0x80000002: s = "HKLM"; break; + case 0x80000003: s = "HKU"; break; + case 0x80000004: s = "HKPD"; break; + case 0x80000005: s = "HKCC"; break; + case 0x80000006: s = "HKDD"; break; + case 0x80000050: s = "HKPT"; break; + case 0x80000060: s = "HKPN"; break; + default: + // Script += " RRRRR "; + // throw 1; + Add_Hex(Script, val); return; + } + Script += s; +} + +static const char * const g_WinAttrib[] = +{ + "READONLY" + , "HIDDEN" + , "SYSTEM" + , NULL + , "DIRECTORY" + , "ARCHIVE" + , "DEVICE" + , "NORMAL" + , "TEMPORARY" + , "SPARSE_FILE" + , "REPARSE_POINT" + , "COMPRESSED" + , "OFFLINE" + , "NOT_CONTENT_INDEXED" + , "ENCRYPTED" + , NULL + , "VIRTUAL" +}; + +#define FLAGS_DELIMITER '|' + +static void FlagsToString2(CDynLimBuf &s, const char * const *table, unsigned num, UInt32 flags) +{ + bool filled = false; + for (unsigned i = 0; i < num; i++) + { + UInt32 f = (UInt32)1 << i; + if ((flags & f) != 0) + { + const char *name = table[i]; + if (name) + { + if (filled) + s += FLAGS_DELIMITER; + filled = true; + s += name; + flags &= ~f; + } + } + } + if (flags != 0) + { + if (filled) + s += FLAGS_DELIMITER; + Add_Hex(s, flags); + } +} + +static bool DoesNeedQuotes(const char *s) +{ + { + char c = s[0]; + if (c == 0 || c == '#' || c == ';' || (c == '/' && s[1] == '*')) + return true; + } + for (;;) + { + char c = *s++; + if (c == 0) + return false; + if (c == ' ') + return true; + } +} + +void CInArchive::Add_QuStr(const AString &s) +{ + bool needQuotes = DoesNeedQuotes(s); + if (needQuotes) + Script += '\"'; + Script += s; + if (needQuotes) + Script += '\"'; +} + +void CInArchive::SpaceQuStr(const AString &s) +{ + Space(); + Add_QuStr(s); +} + +void CInArchive::AddParam(UInt32 pos) +{ + _tempString.Empty(); + ReadString2(_tempString, pos); + SpaceQuStr(_tempString); +} + +void CInArchive::AddParams(const UInt32 *params, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + AddParam(params[i]); +} + +void CInArchive::AddOptionalParam(UInt32 pos) +{ + if (pos != 0) + AddParam(pos); +} + +static unsigned GetNumParams(const UInt32 *params, unsigned num) +{ + for (; num > 0 && params[num - 1] == 0; num--); + return num; +} + +void CInArchive::AddOptionalParams(const UInt32 *params, unsigned num) +{ + AddParams(params, GetNumParams(params, num)); +} + + +static const UInt32 CMD_REF_Goto = (1 << 0); +static const UInt32 CMD_REF_Call = (1 << 1); +static const UInt32 CMD_REF_Pre = (1 << 2); +static const UInt32 CMD_REF_Show = (1 << 3); +static const UInt32 CMD_REF_Leave = (1 << 4); +static const UInt32 CMD_REF_OnFunc = (1 << 5); +static const UInt32 CMD_REF_Section = (1 << 6); +static const UInt32 CMD_REF_InitPluginDir = (1 << 7); +// static const UInt32 CMD_REF_Creator = (1 << 5); // CMD_REF_Pre is used instead +static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too +static const unsigned CMD_REF_Page_NumShifts = 16; // it uses for onFunc too +static const UInt32 CMD_REF_Page_Mask = 0x0FFF0000; +static const UInt32 CMD_REF_OnFunc_Mask = 0xF0000000; + +inline bool IsPageFunc(UInt32 flag) +{ + return (flag & (CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave)) != 0; +} + +inline bool IsFunc(UInt32 flag) +{ + // return (flag & (CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave | CMD_REF_OnFunc)) != 0; + return (flag & (CMD_REF_Call | CMD_REF_Pre | CMD_REF_Show | CMD_REF_Leave | CMD_REF_OnFunc)) != 0; +} + +inline bool IsProbablyEndOfFunc(UInt32 flag) +{ + return (flag != 0 && flag != CMD_REF_Goto); +} + +static const char * const kOnFunc[] = +{ + "Init" + , "InstSuccess" + , "InstFailed" + , "UserAbort" + , "GUIInit" + , "GUIEnd" + , "MouseOverSection" + , "VerifyInstDir" + , "SelChange" + , "RebootFailed" +}; + +void CInArchive::Add_FuncName(const UInt32 *labels, UInt32 index) +{ + UInt32 mask = labels[index]; + if (mask & CMD_REF_OnFunc) + { + Script += ".on"; + Script += kOnFunc[labels[index] >> CMD_REF_OnFunc_NumShifts]; + } + else if (mask & CMD_REF_InitPluginDir) + { + /* + if (!IsInstaller) + Script += "un." + */ + Script += "Initialize_____Plugins"; + } + else + { + Script += "func_"; + Add_UInt(index); + } +} + +void CInArchive::AddParam_Func(const UInt32 *labels, UInt32 index) +{ + Space(); + if ((Int32)index >= 0) + Add_FuncName(labels, index); + else + AddQuotes(); +} + + +void CInArchive::Add_LabelName(UInt32 index) +{ + Script += "label_"; + Add_UInt(index); +} + +// param != 0 +void CInArchive::Add_GotoVar(UInt32 param) +{ + Space(); + if ((Int32)param < 0) + Add_Var((UInt32)-((Int32)param + 1)); + else + Add_LabelName(param - 1); +} + +void CInArchive::Add_GotoVar1(UInt32 param) +{ + if (param == 0) + Script += " 0"; + else + Add_GotoVar(param); +} + +void CInArchive::Add_GotoVars2(const UInt32 *params) +{ + Add_GotoVar1(params[0]); + if (params[1] != 0) + Add_GotoVar(params[1]); +} + +static bool NoLabels(const UInt32 *labels, UInt32 num) +{ + for (UInt32 i = 0; i < num; i++) + if (labels[i] != 0) + return false; + return true; +} + +static const char * const k_REBOOTOK = " /REBOOTOK"; + +#define Z7_NSIS_WIN_MB_ABORTRETRYIGNORE 2 +#define Z7_NSIS_WIN_MB_RETRYCANCEL 5 + +static const char * const k_MB_Buttons[] = +{ + "OK" + , "OKCANCEL" + , "ABORTRETRYIGNORE" + , "YESNOCANCEL" + , "YESNO" + , "RETRYCANCEL" + , "CANCELTRYCONTINUE" +}; + +#define Z7_NSIS_WIN_MB_ICONSTOP (1 << 4) + +static const char * const k_MB_Icons[] = +{ + NULL + , "ICONSTOP" + , "ICONQUESTION" + , "ICONEXCLAMATION" + , "ICONINFORMATION" +}; + +static const char * const k_MB_Flags[] = +{ + "HELP" + , "NOFOCUS" + , "SETFOREGROUND" + , "DEFAULT_DESKTOP_ONLY" + , "TOPMOST" + , "RIGHT" + , "RTLREADING" + // , "SERVICE_NOTIFICATION" // unsupported. That bit is used for NSIS purposes +}; + +#define Z7_NSIS_WIN_IDCANCEL 2 +#define Z7_NSIS_WIN_IDIGNORE 5 + +static const char * const k_Button_IDs[] = +{ + "0" + , "IDOK" + , "IDCANCEL" + , "IDABORT" + , "IDRETRY" + , "IDIGNORE" + , "IDYES" + , "IDNO" + , "IDCLOSE" + , "IDHELP" + , "IDTRYAGAIN" + , "IDCONTINUE" +}; + +void CInArchive::Add_ButtonID(UInt32 buttonID) +{ + Space(); + if (buttonID < Z7_ARRAY_SIZE(k_Button_IDs)) + Script += k_Button_IDs[buttonID]; + else + { + Script += "Button_"; + Add_UInt(buttonID); + } +} + +bool CInArchive::IsDirectString_Equal(UInt32 offset, const char *s) const +{ + if (offset >= NumStringChars) + return false; + if (IsUnicode) + return AreStringsEqual_16and8(_data + _stringsPos + offset * 2, s); + else + return strcmp((const char *)(const Byte *)_data + _stringsPos + offset, s) == 0; +} + +static bool StringToUInt32(const char *s, UInt32 &res) +{ + const char *end; + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) + res = ConvertHexStringToUInt32(s + 2, &end); + else + res = ConvertStringToUInt32(s, &end); + return (*end == 0); +} + +static const unsigned k_CtlColors32_Size = 24; +static const unsigned k_CtlColors64_Size = 28; + +#define GET_CtlColors_SIZE(is64) ((is64) ? k_CtlColors64_Size : k_CtlColors32_Size) + +struct CNsis_CtlColors +{ + UInt32 text; // COLORREF + UInt32 bkc; // COLORREF + UInt32 lbStyle; + UInt32 bkb; // HBRUSH + Int32 bkmode; + Int32 flags; + UInt32 bkb_hi32; + + void Parse(const Byte *p, bool is64); +}; + +void CNsis_CtlColors::Parse(const Byte *p, bool is64) +{ + text = Get32(p); + bkc = Get32(p + 4); + if (is64) + { + bkb = Get32(p + 8); + bkb_hi32 = Get32(p + 12); + lbStyle = Get32(p + 16); + p += 4; + } + else + { + lbStyle = Get32(p + 8); + bkb = Get32(p + 12); + } + bkmode = (Int32)Get32(p + 16); + flags = (Int32)Get32(p + 20); +} + +// Win32 constants +#define Z7_NSIS_WIN_TRANSPARENT 1 +// #define Z7_NSIS_WIN_OPAQUE 2 + +// text/bg colors +#define kColorsFlags_TEXT 1 +#define kColorsFlags_TEXT_SYS 2 +#define kColorsFlags_BK 4 +#define kColorsFlags_BK_SYS 8 +#define kColorsFlags_BKB 16 + +void CInArchive::Add_Color2(UInt32 v) +{ + v = ((v & 0xFF) << 16) | (v & 0xFF00) | ((v >> 16) & 0xFF); + char sz[32]; + for (int i = 5; i >= 0; i--) + { + unsigned t = v & 0xF; + v >>= 4; + sz[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + } + sz[6] = 0; + Script += sz; +} + +void CInArchive::Add_ColorParam(UInt32 v) +{ + Space(); + Add_Color2(v); +} + +void CInArchive::Add_Color(UInt32 v) +{ + Script += "0x"; + Add_Color2(v); +} + +#define Z7_NSIS_WIN_SW_HIDE 0 +#define Z7_NSIS_WIN_SW_SHOWNORMAL 1 + +#define Z7_NSIS_WIN_SW_SHOWMINIMIZED 2 +#define Z7_NSIS_WIN_SW_SHOWMINNOACTIVE 7 +#define Z7_NSIS_WIN_SW_SHOWNA 8 + +static const char * const kShowWindow_Commands[] = +{ + "HIDE" + , "SHOWNORMAL" // "NORMAL" + , "SHOWMINIMIZED" + , "SHOWMAXIMIZED" // "MAXIMIZE" + , "SHOWNOACTIVATE" + , "SHOW" + , "MINIMIZE" + , "SHOWMINNOACTIVE" + , "SHOWNA" + , "RESTORE" + , "SHOWDEFAULT" + , "FORCEMINIMIZE" // "MAX" +}; + +static void Add_ShowWindow_Cmd_2(AString &s, UInt32 cmd) +{ + if (cmd < Z7_ARRAY_SIZE(kShowWindow_Commands)) + { + s += "SW_"; + s += kShowWindow_Commands[cmd]; + } + else + UIntToString(s, cmd); +} + +void CInArchive::Add_ShowWindow_Cmd(UInt32 cmd) +{ + if (cmd < Z7_ARRAY_SIZE(kShowWindow_Commands)) + { + Script += "SW_"; + Script += kShowWindow_Commands[cmd]; + } + else + Add_UInt(cmd); +} + +void CInArchive::Add_TypeFromList(const char * const *table, unsigned tableSize, UInt32 type) +{ + if (type < tableSize) + Script += table[type]; + else + { + Script += '_'; + Add_UInt(type); + } +} + +#define ADD_TYPE_FROM_LIST(table, type) Add_TypeFromList(table, Z7_ARRAY_SIZE(table), type) + +enum +{ + k_ExecFlags_AutoClose, + k_ExecFlags_ShellVarContext, + k_ExecFlags_Errors, + k_ExecFlags_Abort, + k_ExecFlags_RebootFlag, + k_ExecFlags_reboot_called, + k_ExecFlags_cur_insttype, + k_ExecFlags_plugin_api_version, + k_ExecFlags_Silent, + k_ExecFlags_InstDirError, + k_ExecFlags_rtl, + k_ExecFlags_ErrorLevel, + k_ExecFlags_RegView, + k_ExecFlags_DetailsPrint = 13 +}; + +// Names for NSIS exec_flags_t structure vars +static const char * const kExecFlags_VarsNames[] = +{ + "AutoClose" // autoclose; + , "ShellVarContext" // all_user_var; + , "Errors" // exec_error; + , "Abort" // abort; + , "RebootFlag" // exec_reboot; // NSIS_SUPPORT_REBOOT + , "reboot_called" // reboot_called; // NSIS_SUPPORT_REBOOT + , "cur_insttype" // XXX_cur_insttype; // depreacted + , "plugin_api_version" // plugin_api_version; // see NSISPIAPIVER_CURR + // used to be XXX_insttype_changed + , "Silent" // silent; // NSIS_CONFIG_SILENT_SUPPORT + , "InstDirError" // instdir_error; + , "rtl" // rtl; + , "ErrorLevel" // errlvl; + , "RegView" // alter_reg_view; + , "DetailsPrint" // status_update; +}; + +void CInArchive::Add_ExecFlags(UInt32 flagsType) +{ + ADD_TYPE_FROM_LIST(kExecFlags_VarsNames, flagsType); +} + + +// ---------- Page ---------- + +// page flags +#define PF_CANCEL_ENABLE 4 +#define PF_LICENSE_FORCE_SELECTION 32 +#define PF_LICENSE_NO_FORCE_SELECTION 64 +#define PF_PAGE_EX 512 +#define PF_DIR_NO_BTN_DISABLE 1024 +/* +#define PF_LICENSE_SELECTED 1 +#define PF_NEXT_ENABLE 2 +#define PF_BACK_SHOW 8 +#define PF_LICENSE_STREAM 16 +#define PF_NO_NEXT_FOCUS 128 +#define PF_BACK_ENABLE 256 +*/ + +// page window proc +enum +{ + PWP_LICENSE, + PWP_SELCOM, + PWP_DIR, + PWP_INSTFILES, + PWP_UNINST, + PWP_COMPLETED, + PWP_CUSTOM +}; + +static const char * const kPageTypes[] = +{ + "license" + , "components" + , "directory" + , "instfiles" + , "uninstConfirm" + , "COMPLETED" + , "custom" +}; + +#define SET_FUNC_REF(x, flag) if ((Int32)(x) >= 0 && (x) < bh.Num) \ + { labels[x] = (labels[x] & ~CMD_REF_Page_Mask) | ((flag) | (pageIndex << CMD_REF_Page_NumShifts)); } + +// #define IDD_LICENSE 102 +#define IDD_LICENSE_FSRB 108 +#define IDD_LICENSE_FSCB 109 + +void CInArchive::AddPageOption1(UInt32 param, const char *name) +{ + if (param == 0) + return; + TabString(name); + AddParam(param); + NewLine(); +} + +void CInArchive::AddPageOption(const UInt32 *params, unsigned num, const char *name) +{ + num = GetNumParams(params, num); + if (num == 0) + return; + TabString(name); + AddParams(params, num); + NewLine(); +} + +void CInArchive::Separator() +{ + AddLF(); + AddCommentAndString("--------------------"); + AddLF(); +} + +void CInArchive::Space() +{ + Script += ' '; +} + +void CInArchive::Tab() +{ + Script += " "; +} + +void CInArchive::Tab(bool commented) +{ + Script += commented ? " ; " : " "; +} + +void CInArchive::BigSpaceComment() +{ + Script += " ; "; +} + +void CInArchive::SmallSpaceComment() +{ + Script += " ; "; +} + +void CInArchive::AddCommentAndString(const char *s) +{ + Script += "; "; + Script += s; +} + +void CInArchive::AddError(const char *s) +{ + BigSpaceComment(); + Script += "!!! ERROR: "; + Script += s; +} + +void CInArchive::AddErrorLF(const char *s) +{ + AddError(s); + AddLF(); +} + +void CInArchive::CommentOpen() +{ + AddStringLF("/*"); +} + +void CInArchive::CommentClose() +{ + AddStringLF("*/"); +} + +void CInArchive::AddLF() +{ + Script += CR_LF; +} + +void CInArchive::AddQuotes() +{ + Script += "\"\""; +} + +void CInArchive::TabString(const char *s) +{ + Tab(); + Script += s; +} + +void CInArchive::AddStringLF(const char *s) +{ + Script += s; + AddLF(); +} + +// ---------- Section ---------- + +static const char * const kSection_VarsNames[] = +{ + "Text" + , "InstTypes" + , "Flags" + , "Code" + , "CodeSize" + , "Size" // size in KB +}; + +void CInArchive::Add_SectOp(UInt32 opType) +{ + ADD_TYPE_FROM_LIST(kSection_VarsNames, opType); +} + +void CSection::Parse(const Byte *p) +{ + Name = Get32(p); + InstallTypes = Get32(p + 4); + Flags = Get32(p + 8); + StartCmdIndex = Get32(p + 12); + NumCommands = Get32(p + 16); + SizeKB = Get32(p + 20); +} + +// used for section->flags +#define SF_SELECTED (1 << 0) +#define SF_SECGRP (1 << 1) +#define SF_SECGRPEND (1 << 2) +#define SF_BOLD (1 << 3) +#define SF_RO (1 << 4) +#define SF_EXPAND (1 << 5) +/* +#define SF_PSELECTED (1 << 6) +#define SF_TOGGLED (1 << 7) +#define SF_NAMECHG (1 << 8) +*/ + +bool CInArchive::PrintSectionBegin(const CSection §, unsigned index) +{ + AString name; + if (sect.Flags & SF_BOLD) + name += '!'; + AString s2; + ReadString2(s2, sect.Name); + if (!IsInstaller) + { + if (!StringsAreEqualNoCase_Ascii(s2, "uninstall")) + name += "un."; + } + name += s2; + + if (sect.Flags & SF_SECGRPEND) + { + AddStringLF("SectionGroupEnd"); + return true; + } + + if (sect.Flags & SF_SECGRP) + { + Script += "SectionGroup"; + if (sect.Flags & SF_EXPAND) + Script += " /e"; + SpaceQuStr(name); + Script += " ; Section"; + AddParam_UInt(index); + NewLine(); + return true; + } + + Script += "Section"; + if ((sect.Flags & SF_SELECTED) == 0) + Script += " /o"; + if (!name.IsEmpty()) + SpaceQuStr(name); + + /* + if (!name.IsEmpty()) + Script += ' '; + else + */ + SmallSpaceComment(); + Script += "Section_"; + Add_UInt(index); + + /* + Script += " ; flags = "; + Add_Hex(Script, sect.Flags); + */ + + NewLine(); + + if (sect.SizeKB != 0) + { + // probably we must show AddSize, only if there is additional size. + Tab(); + AddCommentAndString("AddSize"); + AddParam_UInt(sect.SizeKB); + AddLF(); + } + + bool needSectionIn = + (sect.Name != 0 && sect.InstallTypes != 0) || + (sect.Name == 0 && sect.InstallTypes != 0xFFFFFFFF); + if (needSectionIn || (sect.Flags & SF_RO) != 0) + { + TabString("SectionIn"); + UInt32 instTypes = sect.InstallTypes; + for (unsigned i = 0; i < 32; i++, instTypes >>= 1) + if ((instTypes & 1) != 0) + { + AddParam_UInt(i + 1); + } + if ((sect.Flags & SF_RO) != 0) + Script += " RO"; + AddLF(); + } + return false; +} + +void CInArchive::PrintSectionEnd() +{ + AddStringLF("SectionEnd"); + AddLF(); +} + +// static const unsigned kOnFuncShift = 4; + +void CInArchive::ClearLangComment() +{ + langStrIDs.Clear(); +} + +void CInArchive::PrintNumComment(const char *name, UInt32 value) +{ + // size_t len = Script.Len(); + AddCommentAndString(name); + Script += ": "; + Add_UInt(value); + AddLF(); + /* + len = Script.Len() - len; + char sz[16]; + ConvertUInt32ToString(value, sz); + len += MyStringLen(sz); + for (; len < 20; len++) + Space(); + AddStringLF(sz); + */ +} + + +void CInArchive::NewLine() +{ + if (!langStrIDs.IsEmpty()) + { + BigSpaceComment(); + for (unsigned i = 0; i < langStrIDs.Size() && i < 20; i++) + { + /* + if (i != 0) + Script += ' '; + */ + UInt32 langStr = langStrIDs[i]; + if (langStr >= _numLangStrings) + { + AddError("langStr"); + break; + } + UInt32 param = Get32(_mainLang + langStr * 4); + if (param != 0) + AddParam(param); + } + ClearLangComment(); + } + AddLF(); +} + +static const UInt32 kPageSize = 16 * 4; + +static const char * const k_SetOverwrite_Modes[] = +{ + "on" + , "off" + , "try" + , "ifnewer" + , "ifdiff" + // "lastused" +}; + + +void CInArchive::MessageBox_MB_Part(UInt32 param) +{ + { + UInt32 v = param & 0xF; + Script += " MB_"; + if (v < Z7_ARRAY_SIZE(k_MB_Buttons)) + Script += k_MB_Buttons[v]; + else + { + Script += "Buttons_"; + Add_UInt(v); + } + } + { + UInt32 icon = (param >> 4) & 0x7; + if (icon != 0) + { + Script += "|MB_"; + if (icon < Z7_ARRAY_SIZE(k_MB_Icons) && k_MB_Icons[icon]) + Script += k_MB_Icons[icon]; + else + { + Script += "Icon_"; + Add_UInt(icon); + } + } + } + if ((param & 0x80) != 0) + Script += "|MB_USERICON"; + { + UInt32 defButton = (param >> 8) & 0xF; + if (defButton != 0) + { + Script += "|MB_DEFBUTTON"; + Add_UInt(defButton + 1); + } + } + { + UInt32 modal = (param >> 12) & 0x3; + if (modal == 1) Script += "|MB_SYSTEMMODAL"; + else if (modal == 2) Script += "|MB_TASKMODAL"; + else if (modal == 3) Script += "|0x3000"; + UInt32 flags = (param >> 14); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_MB_Flags); i++) + if ((flags & (1 << i)) != 0) + { + Script += "|MB_"; + Script += k_MB_Flags[i]; + } + } +} + +#define GET_CMD_PARAM(ppp, index) Get32((ppp) + 4 + (index) * 4) + +static const Byte k_InitPluginDir_Commands[] = + { 13, 26, 31, 13, 19, 21, 11, 14, 25, 31, 1, 22, 4, 1 }; + +bool CInArchive::CompareCommands(const Byte *rawCmds, const Byte *sequence, size_t numCommands) +{ + for (UInt32 kkk = 0; kkk < numCommands; kkk++, rawCmds += kCmdSize) + if (GetCmd(Get32(rawCmds)) != sequence[kkk]) + return false; + return true; +} + + +static const UInt32 kSectionSize_base = 6 * 4; +// static const UInt32 kSectionSize_8bit = kSectionSize_base + 1024; +// static const UInt32 kSectionSize_16bit = kSectionSize_base + 1024 * 2; +// static const UInt32 kSectionSize_16bit_Big = kSectionSize_base + 8196 * 2; +// 8196 is default string length in NSIS-Unicode since 2.37.3 + +#endif + + +static void AddString(AString &dest, const char *src) +{ + dest.Add_Space_if_NotEmpty(); + dest += src; +} + +AString CInArchive::GetFormatDescription() const +{ + AString s ("NSIS-"); + char c; + if (IsPark()) + { + s += "Park-"; + c = '1'; + if (NsisType == k_NsisType_Park2) c = '2'; + else if (NsisType == k_NsisType_Park3) c = '3'; + } + else + { + c = '2'; + if (NsisType == k_NsisType_Nsis3) + c = '3'; + } + s += c; + if (IsNsis200) + s += ".00"; + else if (IsNsis225) + s += ".25"; + + if (IsUnicode) + AddString(s, "Unicode"); + + if (Is64Bit) + AddString(s, "64-bit"); + + if (LogCmdIsEnabled) + AddString(s, "log"); + + if (BadCmd >= 0) + { + AddString(s, "BadCmd="); + UIntToString(s, (UInt32)BadCmd); + } + return s; +} + +#ifdef NSIS_SCRIPT + +static const unsigned kNumAdditionalParkCmds = 3; + +unsigned CInArchive::GetNumSupportedCommands() const +{ + unsigned numCmds = IsPark() ? (unsigned)kNumCmds : (unsigned)(kNumCmds) - kNumAdditionalParkCmds; + if (!LogCmdIsEnabled) + numCmds--; + if (!IsUnicode) + numCmds -= 2; + return numCmds; +} + +#endif + +UInt32 CInArchive::GetCmd(UInt32 a) +{ + if (!IsPark()) + { + if (!LogCmdIsEnabled) + return a; + if (a < EW_SECTIONSET) + return a; + if (a == EW_SECTIONSET) + return EW_LOG; + return a - 1; + } + + if (a < EW_REGISTERDLL) + return a; + if (NsisType >= k_NsisType_Park2) + { + if (a == EW_REGISTERDLL) return EW_GETFONTVERSION; + a--; + } + if (NsisType >= k_NsisType_Park3) + { + if (a == EW_REGISTERDLL) return EW_GETFONTNAME; + a--; + } + if (a >= EW_FSEEK) + { + if (IsUnicode) + { + if (a == EW_FSEEK) return EW_FPUTWS; + if (a == EW_FSEEK + 1) return EW_FPUTWS + 1; + a -= 2; + } + + if (a >= EW_SECTIONSET && LogCmdIsEnabled) + { + if (a == EW_SECTIONSET) + return EW_LOG; + return a - 1; + } + if (a == EW_FPUTWS) + return EW_FINDPROC; + // if (a > EW_FPUTWS) return 0; + } + return a; +} + +void CInArchive::FindBadCmd(const CBlockHeader &bh, const Byte *p) +{ + BadCmd = -1; + + for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) + { + const UInt32 id = GetCmd(Get32(p)); + if (id >= kNumCmds) + continue; + if (BadCmd >= 0 && id >= (unsigned)BadCmd) + continue; + unsigned i; + if (IsNsis3_OrHigher()) + { + if (id == EW_RESERVEDOPCODE) + { + BadCmd = (int)id; + continue; + } + } + else + { + // if (id == EW_GETLABELADDR || id == EW_GETFUNCTIONADDR) + if (id == EW_RESERVEDOPCODE || id == EW_GETOSINFO) + { + BadCmd = (int)id; + continue; + } + } + for (i = 6; i != 0; i--) + { + const UInt32 param = Get32(p + i * 4); + if (param != 0) + break; + } + if (id == EW_FINDPROC && i == 0) + { + BadCmd = (int)id; + continue; + } + if (k_Commands[id].NumParams < i) + BadCmd = (int)id; + } +} + +/* We calculate the number of parameters in commands to detect + layout of commands. It's not very good way. + If you know simpler and more robust way to detect Version and layout, + please write to 7-Zip forum */ + +void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p) +{ + bool strongPark = false; + bool strongNsis = false; + + if (NumStringChars > 2) + { + const Byte *strData = _data + _stringsPos; + if (IsUnicode) + { + UInt32 num = NumStringChars - 2; + for (UInt32 i = 0; i < num; i++) + { + if (Get16(strData + i * 2) == 0) + { + unsigned c2 = Get16(strData + 2 + i * 2); + // it can be TXT/RTF with marker char (1 or 2). so we must check next char + // if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL) + if (c2 == NS_3_CODE_VAR) + { + // 18.06: fixed: is it correct ? + // if ((Get16(strData + 3 + i * 2) & 0x8000) != 0) + if ((Get16(strData + 4 + i * 2) & 0x8080) == 0x8080) + { + NsisType = k_NsisType_Nsis3; + strongNsis = true; + break; + } + } + } + } + if (!strongNsis) + { + NsisType = k_NsisType_Park1; + strongPark = true; + } + } + else + { + UInt32 num = NumStringChars - 2; + for (UInt32 i = 0; i < num; i++) + { + if (strData[i] == 0) + { + Byte c2 = strData[i + 1]; + // it can be TXT/RTF with marker char (1 or 2). so we must check next char + // for marker=1 (txt) + if (c2 == NS_3_CODE_VAR) + // if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL && c2 != 1) + { + if ((strData[i + 2] & 0x80) != 0) + { + // const char *p2 = (const char *)(strData + i + 1); + // p2 = p2; + NsisType = k_NsisType_Nsis3; + strongNsis = true; + break; + } + } + } + } + } + } + + if (NsisType == k_NsisType_Nsis2 && !IsUnicode) + { + const Byte *p2 = p; + + for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p2 += kCmdSize) + { + UInt32 cmd = GetCmd(Get32(p2)); + if (cmd != EW_GETDLGITEM && + cmd != EW_ASSIGNVAR) + continue; + + UInt32 params[kNumCommandParams]; + for (unsigned i = 0; i < kNumCommandParams; i++) + params[i] = Get32(p2 + 4 + 4 * i); + + if (cmd == EW_GETDLGITEM) + { + // we can use also EW_SETCTLCOLORS + if (IsVarStr(params[1], kVar_HWNDPARENT_225)) + { + IsNsis225 = true; + if (params[0] == kVar_Spec_OUTDIR_225) + { + IsNsis200 = true; + break; + } + } + } + else // if (cmd == EW_ASSIGNVAR) + { + if (params[0] == kVar_Spec_OUTDIR_225 && + params[2] == 0 && + params[3] == 0 && + IsVarStr(params[1], kVar_OUTDIR)) + IsNsis225 = true; + } + } + } + + bool parkVer_WasDetected = false; + + if (!strongNsis && !IsNsis225 && !IsNsis200) + { + // it must be before FindBadCmd(bh, p); + unsigned mask = 0; + + unsigned numInsertMax = IsUnicode ? 4 : 2; + + const Byte *p2 = p; + + for (UInt32 kkk = 0; kkk < bh.Num; kkk++, p2 += kCmdSize) + { + const UInt32 cmd = Get32(p2); // we use original (not converted) command + + if (cmd < EW_WRITEUNINSTALLER || + cmd > EW_WRITEUNINSTALLER + numInsertMax) + continue; + + UInt32 params[kNumCommandParams]; + for (unsigned i = 0; i < kNumCommandParams; i++) + params[i] = Get32(p2 + 4 + 4 * i); + + if (params[4] != 0 || + params[5] != 0 || + params[0] <= 1 || + params[3] <= 1) + continue; + + const UInt32 altParam = params[3]; + if (!IsGoodString(params[0]) || + !IsGoodString(altParam)) + continue; + + UInt32 additional = 0; + if (GetVarIndexFinished(altParam, '\\', additional) != kVar_INSTDIR) + continue; + if (AreTwoParamStringsEqual(altParam + additional, params[0])) + { + const unsigned numInserts = cmd - EW_WRITEUNINSTALLER; + mask |= ((unsigned)1 << numInserts); + } + } + + if (mask == 1) + { + parkVer_WasDetected = true; // it can be original NSIS or Park-1 + } + else if (mask != 0) + { + ENsisType newType = NsisType; + if (IsUnicode) + switch (mask) + { + case (1 << 3): newType = k_NsisType_Park2; break; + case (1 << 4): newType = k_NsisType_Park3; break; + } + else + switch (mask) + { + case (1 << 1): newType = k_NsisType_Park2; break; + case (1 << 2): newType = k_NsisType_Park3; break; + } + if (newType != NsisType) + { + parkVer_WasDetected = true; + NsisType = newType; + } + } + } + + FindBadCmd(bh, p); + + /* + if (strongNsis) + return; + */ + + if (BadCmd < EW_REGISTERDLL) + return; + + /* + // in ANSI archive we don't check Park and log version + if (!IsUnicode) + return; + */ + + // We can support Park-ANSI archives, if we remove if (strongPark) check + if (strongPark && !parkVer_WasDetected) + { + if (BadCmd < EW_SECTIONSET) + { + NsisType = k_NsisType_Park3; + LogCmdIsEnabled = true; // version 3 is provided with log enabled + FindBadCmd(bh, p); + if (BadCmd > 0 && BadCmd < EW_SECTIONSET) + { + NsisType = k_NsisType_Park2; + LogCmdIsEnabled = false; + FindBadCmd(bh, p); + if (BadCmd > 0 && BadCmd < EW_SECTIONSET) + { + NsisType = k_NsisType_Park1; + FindBadCmd(bh, p); + } + } + } + } + + if (BadCmd >= EW_SECTIONSET) + { + LogCmdIsEnabled = !LogCmdIsEnabled; + FindBadCmd(bh, p); + if (BadCmd >= EW_SECTIONSET && LogCmdIsEnabled) + { + LogCmdIsEnabled = false; + FindBadCmd(bh, p); + } + } +} + +Int32 CInArchive::GetVarIndex(UInt32 strPos) const +{ + if (strPos >= NumStringChars) + return -1; + + if (IsUnicode) + { + if (NumStringChars - strPos < 3 * 2) + return -1; + const Byte *p = _data + _stringsPos + strPos * 2; + unsigned code = Get16(p); + if (IsPark()) + { + if (code != PARK_CODE_VAR) + return -1; + UInt32 n = Get16(p + 2); + if (n == 0) + return -1; + CONVERT_NUMBER_PARK(n); + return (Int32)n; + } + + // NSIS-3 + { + if (code != NS_3_CODE_VAR) + return -1; + UInt32 n = Get16(p + 2); + if (n == 0) + return -1; + CONVERT_NUMBER_NS_3_UNICODE(n); + return (Int32)n; + } + } + + if (NumStringChars - strPos < 4) + return -1; + + const Byte *p = _data + _stringsPos + strPos; + unsigned c = *p; + if (NsisType == k_NsisType_Nsis3) + { + if (c != NS_3_CODE_VAR) + return -1; + } + else if (c != NS_CODE_VAR) + return -1; + + const unsigned c0 = p[1]; + if (c0 == 0) + return -1; + const unsigned c1 = p[2]; + if (c1 == 0) + return -1; + return (Int32)DECODE_NUMBER_FROM_2_CHARS(c0, c1); +} + +Int32 CInArchive::GetVarIndex(UInt32 strPos, UInt32 &resOffset) const +{ + resOffset = 0; + Int32 varIndex = GetVarIndex(strPos); + if (varIndex < 0) + return varIndex; + if (IsUnicode) + { + if (NumStringChars - strPos < 2 * 2) + return -1; + resOffset = 2; + } + else + { + if (NumStringChars - strPos < 3) + return -1; + resOffset = 3; + } + return varIndex; +} + +Int32 CInArchive::GetVarIndexFinished(UInt32 strPos, Byte endChar, UInt32 &resOffset) const +{ + resOffset = 0; + Int32 varIndex = GetVarIndex(strPos); + if (varIndex < 0) + return varIndex; + if (IsUnicode) + { + if (NumStringChars - strPos < 3 * 2) + return -1; + const Byte *p = _data + _stringsPos + strPos * 2; + if (Get16(p + 4) != endChar) + return -1; + resOffset = 3; + } + else + { + if (NumStringChars - strPos < 4) + return -1; + const Byte *p = _data + _stringsPos + strPos; + if (p[3] != endChar) + return -1; + resOffset = 4; + } + return varIndex; +} + +bool CInArchive::IsVarStr(UInt32 strPos, UInt32 varIndex) const +{ + if (varIndex > (UInt32)0x7FFF) + return false; + UInt32 resOffset; + return GetVarIndexFinished(strPos, 0, resOffset) == (Int32)varIndex; +} + +bool CInArchive::IsAbsolutePathVar(UInt32 strPos) const +{ + Int32 varIndex = GetVarIndex(strPos); + if (varIndex < 0) + return false; + switch (varIndex) + { + case kVar_INSTDIR: + case kVar_EXEDIR: + case kVar_TEMP: + case kVar_PLUGINSDIR: + return true; + } + return false; +} + +#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) + +// We use same check as in NSIS decoder +static bool IsDrivePath(const wchar_t *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; } +static bool IsDrivePath(const char *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; } + +static bool IsAbsolutePath(const wchar_t *s) +{ + return (s[0] == WCHAR_PATH_SEPARATOR && s[1] == WCHAR_PATH_SEPARATOR) || IsDrivePath(s); +} + +static bool IsAbsolutePath(const char *s) +{ + return (s[0] == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR) || IsDrivePath(s); +} + +void CInArchive::SetItemName(CItem &item, UInt32 strPos) +{ + ReadString2_Raw(strPos); + const bool isAbs = IsAbsolutePathVar(strPos); + if (IsUnicode) + { + item.NameU = Raw_UString; + if (!isAbs && !IsAbsolutePath(Raw_UString)) + item.Prefix = (int)UPrefixes.Size() - 1; + } + else + { + item.NameA = Raw_AString; + if (!isAbs && !IsAbsolutePath(Raw_AString)) + item.Prefix = (int)APrefixes.Size() - 1; + } +} + +HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) +{ + #ifdef NSIS_SCRIPT + CDynLimBuf &s = Script; + + CObjArray labels; + labels.Alloc(bh.Num); + memset(labels, 0, bh.Num * sizeof(UInt32)); + + { + const Byte *p = _data; + UInt32 i; + for (i = 0; i < numOnFunc; i++) + { + UInt32 func = Get32(p + onFuncOffset + 4 * i); + if (func < bh.Num) + labels[func] = (labels[func] & ~CMD_REF_OnFunc_Mask) | (CMD_REF_OnFunc | (i << CMD_REF_OnFunc_NumShifts)); + } + } + + /* + { + for (int i = 0; i < OnFuncs.Size(); i++) + { + UInt32 address = OnFuncs[i] >> kOnFuncShift; + if (address < bh.Num) + } + } + */ + + if (bhPages.Num != 0) + { + Separator(); + PrintNumComment("PAGES", bhPages.Num); + + if (bhPages.Num > (1 << 12) + || bhPages.Offset > _size + || bhPages.Num * kPageSize > _size - bhPages.Offset) + { + AddErrorLF("Pages error"); + } + else + { + + AddLF(); + const Byte *p = _data + bhPages.Offset; + + for (UInt32 pageIndex = 0; pageIndex < bhPages.Num; pageIndex++, p += kPageSize) + { + UInt32 dlgID = Get32(p); + UInt32 wndProcID = Get32(p + 4); + UInt32 preFunc = Get32(p + 8); + UInt32 showFunc = Get32(p + 12); + UInt32 leaveFunc = Get32(p + 16); + UInt32 flags = Get32(p + 20); + UInt32 caption = Get32(p + 24); + // UInt32 back = Get32(p + 28); + UInt32 next = Get32(p + 32); + // UInt32 clickNext = Get32(p + 36); + // UInt32 cancel = Get32(p + 40); + UInt32 params[5]; + for (int i = 0; i < 5; i++) + params[i] = Get32(p + 44 + 4 * i); + + SET_FUNC_REF(preFunc, CMD_REF_Pre) + SET_FUNC_REF(showFunc, CMD_REF_Show) + SET_FUNC_REF(leaveFunc, CMD_REF_Leave) + + if (wndProcID == PWP_COMPLETED) + CommentOpen(); + + AddCommentAndString("Page "); + Add_UInt(pageIndex); + AddLF(); + + if (flags & PF_PAGE_EX) + { + s += "PageEx "; + if (!IsInstaller) + s += "un."; + } + else + s += IsInstaller ? "Page " : "UninstPage "; + + if (wndProcID < Z7_ARRAY_SIZE(kPageTypes)) + s += kPageTypes[wndProcID]; + else + Add_UInt(wndProcID); + + + bool needCallbacks = ( + (Int32)preFunc >= 0 || + (Int32)showFunc >= 0 || + (Int32)leaveFunc >= 0); + + if (flags & PF_PAGE_EX) + { + AddLF(); + if (needCallbacks) + TabString("PageCallbacks"); + } + + if (needCallbacks) + { + AddParam_Func(labels, preFunc); // it's creator_function for PWP_CUSTOM + if (wndProcID != PWP_CUSTOM) + { + AddParam_Func(labels, showFunc); + } + AddParam_Func(labels, leaveFunc); + } + + if ((flags & PF_PAGE_EX) == 0) + { + // AddOptionalParam(caption); + if (flags & PF_CANCEL_ENABLE) + s += " /ENABLECANCEL"; + AddLF(); + } + else + { + AddLF(); + AddPageOption1(caption, "Caption"); + } + + if (wndProcID == PWP_LICENSE) + { + if ((flags & PF_LICENSE_NO_FORCE_SELECTION) != 0 || + (flags & PF_LICENSE_FORCE_SELECTION) != 0) + { + TabString("LicenseForceSelection "); + if (flags & PF_LICENSE_NO_FORCE_SELECTION) + s += "off"; + else + { + if (dlgID == IDD_LICENSE_FSCB) + s += "checkbox"; + else if (dlgID == IDD_LICENSE_FSRB) + s += "radiobuttons"; + else + Add_UInt(dlgID); + AddOptionalParams(params + 2, 2); + } + NewLine(); + } + + if (params[0] != 0 || next != 0) + { + TabString("LicenseText"); + AddParam(params[0]); + AddOptionalParam(next); + NewLine(); + } + if (params[1] != 0) + { + TabString("LicenseData"); + if ((Int32)params[1] < 0) + AddParam(params[1]); + else + AddLicense(params[1], -1); + ClearLangComment(); + NewLine(); + } + } + else if (wndProcID == PWP_SELCOM) + AddPageOption(params, 3, "ComponentsText"); + else if (wndProcID == PWP_DIR) + { + AddPageOption(params, 4, "DirText"); + if (params[4] != 0) + { + TabString("DirVar"); + AddParam_Var(params[4] - 1); + AddLF(); + } + if (flags & PF_DIR_NO_BTN_DISABLE) + { + TabString("DirVerify leave"); + AddLF(); + } + + } + else if (wndProcID == PWP_INSTFILES) + { + AddPageOption1(params[2], "CompletedText"); + AddPageOption1(params[1], "DetailsButtonText"); + } + else if (wndProcID == PWP_UNINST) + { + if (params[4] != 0) + { + TabString("DirVar"); + AddParam_Var(params[4] - 1); + AddLF(); + } + AddPageOption(params, 2, "UninstallText"); + } + + if (flags & PF_PAGE_EX) + { + s += "PageExEnd"; + NewLine(); + } + if (wndProcID == PWP_COMPLETED) + CommentClose(); + NewLine(); + } + } + } + + CObjArray Sections; + + { + Separator(); + PrintNumComment("SECTIONS", bhSections.Num); + PrintNumComment("COMMANDS", bh.Num); + AddLF(); + + if (bhSections.Num > (1 << 15) + // || bhSections.Offset > _size + // || (bhSections.Num * SectionSize > _size - bhSections.Offset) + ) + { + AddErrorLF("Sections error"); + } + else if (bhSections.Num != 0) + { + Sections.Alloc((unsigned)bhSections.Num); + const Byte *p = _data + bhSections.Offset; + for (UInt32 i = 0; i < bhSections.Num; i++, p += SectionSize) + { + CSection §ion = Sections[i]; + section.Parse(p); + if (section.StartCmdIndex < bh.Num) + labels[section.StartCmdIndex] |= CMD_REF_Section; + } + } + } + + #endif + + const Byte *p; + UInt32 kkk; + + #ifdef NSIS_SCRIPT + + p = _data + bh.Offset; + + for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) + { + UInt32 commandId = GetCmd(Get32(p)); + UInt32 mask; + switch (commandId) + { + case EW_NOP: mask = 1 << 0; break; + case EW_IFFILEEXISTS: mask = 3 << 1; break; + case EW_IFFLAG: mask = 3 << 0; break; + case EW_MESSAGEBOX: mask = 5 << 3; break; + case EW_STRCMP: mask = 3 << 2; break; + case EW_INTCMP: mask = 7 << 2; break; + case EW_ISWINDOW: mask = 3 << 1; break; + case EW_CALL: + { + if (Get32(p + 4 + 4) == 1) // it's Call :Label + { + mask = 1 << 0; + break; + } + UInt32 param0 = Get32(p + 4); + if ((Int32)param0 > 0) + labels[param0 - 1] |= CMD_REF_Call; + continue; + } + default: continue; + } + for (unsigned i = 0; mask != 0; i++, mask >>= 1) + if (mask & 1) + { + UInt32 param = Get32(p + 4 + 4 * i); + if ((Int32)param > 0 && (Int32)param <= (Int32)bh.Num) + labels[param - 1] |= CMD_REF_Goto; + } + } + + int InitPluginsDir_Start = -1; + int InitPluginsDir_End = -1; + p = _data + bh.Offset; + for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) + { + UInt32 flg = labels[kkk]; + /* + if (IsFunc(flg)) + { + AddLF(); + for (int i = 0; i < 14; i++) + { + UInt32 commandId = GetCmd(Get32(p + kCmdSize * i)); + s += ", "; + UIntToString(s, commandId); + } + AddLF(); + } + */ + if (IsFunc(flg) + && bh.Num - kkk >= Z7_ARRAY_SIZE(k_InitPluginDir_Commands) + && CompareCommands(p, k_InitPluginDir_Commands, Z7_ARRAY_SIZE(k_InitPluginDir_Commands))) + { + InitPluginsDir_Start = (int)kkk; + InitPluginsDir_End = (int)(kkk + Z7_ARRAY_SIZE(k_InitPluginDir_Commands)); + labels[kkk] |= CMD_REF_InitPluginDir; + break; + } + } + + #endif + + // AString prefixA_Temp; + // UString prefixU_Temp; + + + // const UInt32 kFindS = 158; + + #ifdef NSIS_SCRIPT + + UInt32 curSectionIndex = 0; + // UInt32 lastSectionEndCmd = 0xFFFFFFFF; + bool sectionIsOpen = false; + // int curOnFunc = 0; + bool onFuncIsOpen = false; + + /* + for (unsigned yyy = 0; yyy + 3 < _data.Size(); yyy++) + { + UInt32 val = Get32(_data + yyy); + if (val == kFindS) + val = val; + } + */ + + UInt32 overwrite_State = 0; // "SetOverwrite on" + Int32 allowSkipFiles_State = -1; // -1: on, -2: off, >=0 : RAW value + UInt32 endCommentIndex = 0; + + unsigned numSupportedCommands = GetNumSupportedCommands(); + + #endif + + p = _data + bh.Offset; + + UString spec_outdir_U; + AString spec_outdir_A; + + UPrefixes.Add(UString("$INSTDIR")); + APrefixes.Add(AString("$INSTDIR")); + + p = _data + bh.Offset; + + unsigned spec_outdir_VarIndex = IsNsis225 ? + kVar_Spec_OUTDIR_225 : + kVar_Spec_OUTDIR; + + for (kkk = 0; kkk < bh.Num; kkk++, p += kCmdSize) + { + UInt32 commandId; + UInt32 params[kNumCommandParams]; + commandId = GetCmd(Get32(p)); + { + for (unsigned i = 0; i < kNumCommandParams; i++) + { + params[i] = Get32(p + 4 + 4 * i); + /* + if (params[i] == kFindS) + i = i; + */ + } + } + + #ifdef NSIS_SCRIPT + + bool IsSectionGroup = false; + while (curSectionIndex < bhSections.Num) + { + const CSection § = Sections[curSectionIndex]; + if (sectionIsOpen) + { + if (sect.StartCmdIndex + sect.NumCommands + 1 != kkk) + break; + PrintSectionEnd(); + sectionIsOpen = false; + // lastSectionEndCmd = kkk; + curSectionIndex++; + continue; + } + if (sect.StartCmdIndex != kkk) + break; + if (PrintSectionBegin(sect, curSectionIndex)) + { + IsSectionGroup = true; + curSectionIndex++; + // do we need to flush prefixes in new section? + // FlushOutPathPrefixes(); + } + else + sectionIsOpen = true; + } + + /* + if (curOnFunc < OnFuncs.Size()) + { + if ((OnFuncs[curOnFunc] >> kOnFuncShift) == kkk) + { + s += "Function .on"; + s += kOnFunc[OnFuncs[curOnFunc++] & ((1 << kOnFuncShift) - 1)]; + AddLF(); + onFuncIsOpen = true; + } + } + */ + + if (labels[kkk] != 0 && labels[kkk] != CMD_REF_Section) + { + UInt32 flg = labels[kkk]; + if (IsFunc(flg)) + { + if ((int)kkk == InitPluginsDir_Start) + CommentOpen(); + + onFuncIsOpen = true; + s += "Function "; + Add_FuncName(labels, kkk); + if (IsPageFunc(flg)) + { + BigSpaceComment(); + s += "Page "; + Add_UInt((flg & CMD_REF_Page_Mask) >> CMD_REF_Page_NumShifts); + // if (flg & CMD_REF_Creator) s += ", Creator"; + if (flg & CMD_REF_Leave) s += ", Leave"; + if (flg & CMD_REF_Pre) s += ", Pre"; + if (flg & CMD_REF_Show) s += ", Show"; + } + AddLF(); + } + if (flg & CMD_REF_Goto) + { + Add_LabelName(kkk); + s += ':'; + AddLF(); + } + } + + if (commandId != EW_RET) + { + Tab(kkk < endCommentIndex); + } + + /* + UInt32 originalCmd = Get32(p); + if (originalCmd >= EW_REGISTERDLL) + { + UIntToString(s, originalCmd); + s += ' '; + if (originalCmd != commandId) + { + UIntToString(s, commandId); + s += ' '; + } + } + */ + + unsigned numSkipParams = 0; + + if (commandId < Z7_ARRAY_SIZE(k_Commands) && commandId < numSupportedCommands) + { + numSkipParams = k_Commands[commandId].NumParams; + const char *sz = k_CommandNames[commandId]; + if (sz) + s += sz; + } + else + { + s += "Command"; + Add_UInt(commandId); + /* We don't show wrong commands that use overlapped ids. + So we change commandId to big value */ + if (commandId < (1 << 12)) + commandId += (1 << 12); + } + + #endif + + switch (commandId) + { + case EW_CREATEDIR: + { + bool isSetOutPath = (params[1] != 0); + + if (isSetOutPath) + { + UInt32 par0 = params[0]; + + UInt32 resOffset; + Int32 idx = GetVarIndex(par0, resOffset); + if (idx == (Int32)spec_outdir_VarIndex || + idx == kVar_OUTDIR) + par0 += resOffset; + + ReadString2_Raw(par0); + + if (IsUnicode) + { + if (idx == (Int32)spec_outdir_VarIndex) + Raw_UString.Insert(0, spec_outdir_U); + else if (idx == kVar_OUTDIR) + Raw_UString.Insert(0, UPrefixes.Back()); + UPrefixes.Add(Raw_UString); + } + else + { + if (idx == (Int32)spec_outdir_VarIndex) + Raw_AString.Insert(0, spec_outdir_A); + else if (idx == kVar_OUTDIR) + Raw_AString.Insert(0, APrefixes.Back()); + APrefixes.Add(Raw_AString); + } + } + + #ifdef NSIS_SCRIPT + s += isSetOutPath ? "SetOutPath" : "CreateDirectory"; + AddParam(params[0]); + if (params[2] != 0) // 2.51+ & 3.0b3+ + { + SmallSpaceComment(); + s += "CreateRestrictedDirectory"; + } + #endif + + break; + } + + + case EW_ASSIGNVAR: + { + if (params[0] == spec_outdir_VarIndex) + { + spec_outdir_U.Empty(); + spec_outdir_A.Empty(); + if (IsVarStr(params[1], kVar_OUTDIR) && + params[2] == 0 && + params[3] == 0) + { + spec_outdir_U = UPrefixes.Back(); // outdir_U; + spec_outdir_A = APrefixes.Back(); // outdir_A; + } + } + + #ifdef NSIS_SCRIPT + + if (params[2] == 0 && + params[3] == 0 && + params[4] == 0 && + params[5] == 0 && + params[1] != 0 && + params[1] < NumStringChars) + { + char sz[16]; + ConvertUInt32ToString(kkk + 1, sz); + if (IsDirectString_Equal(params[1], sz)) + { + // we suppose that it's GetCurrentAddress command + // but there is probability that it's StrCpy command + s += "GetCurrentAddress"; + AddParam_Var(params[0]); + SmallSpaceComment(); + } + } + s += "StrCpy"; + AddParam_Var(params[0]); + AddParam(params[1]); + + AddOptionalParams(params + 2, 2); + + #endif + + break; + } + + case EW_EXTRACTFILE: + { + CItem &item = Items.AddNew(); + + UInt32 par1 = params[1]; + + SetItemName(item, par1); + + item.Pos = params[2]; + item.MTime.dwLowDateTime = params[3]; + item.MTime.dwHighDateTime = params[4]; + + #ifdef NSIS_SCRIPT + + { + UInt32 overwrite = params[0] & 0x7; + if (overwrite != overwrite_State) + { + s += "SetOverwrite "; + ADD_TYPE_FROM_LIST(k_SetOverwrite_Modes, overwrite); + overwrite_State = overwrite; + AddLF(); + Tab(kkk < endCommentIndex); + } + } + + { + UInt32 nsisMB = params[0] >> 3; + if ((Int32)nsisMB != allowSkipFiles_State) + { + UInt32 mb = nsisMB & ((1 << 20) - 1); // old/new NSIS + UInt32 b1 = nsisMB >> 21; // NSIS 2.06+ + UInt32 b2 = nsisMB >> 20; // NSIS old + Int32 asf = (Int32)nsisMB; + if (mb == (Z7_NSIS_WIN_MB_ABORTRETRYIGNORE | Z7_NSIS_WIN_MB_ICONSTOP) && (b1 == Z7_NSIS_WIN_IDIGNORE || b2 == Z7_NSIS_WIN_IDIGNORE)) + asf = -1; + else if (mb == (Z7_NSIS_WIN_MB_RETRYCANCEL | Z7_NSIS_WIN_MB_ICONSTOP) && (b1 == Z7_NSIS_WIN_IDCANCEL || b2 == Z7_NSIS_WIN_IDCANCEL)) + asf = -2; + else + { + AddCommentAndString("AllowSkipFiles [Overwrite]: "); + MessageBox_MB_Part(mb); + if (b1 != 0) + { + s += " /SD"; + Add_ButtonID(b1); + } + } + if (asf != allowSkipFiles_State) + { + if (asf < 0) + { + s += "AllowSkipFiles "; + s += (asf == -1) ? "on" : "off"; + } + AddLF(); + Tab(kkk < endCommentIndex); + } + allowSkipFiles_State = (Int32)nsisMB; + } + } + + s += "File"; + AddParam(params[1]); + + /* params[5] contains link to LangString (negative value) + with NLF_FILE_ERROR or NLF_FILE_ERROR_NOIGNORE message for MessageBox. + We don't need to print it. */ + + #endif + + if (IsVarStr(par1, 10)) // is $R0 + { + // we parse InstallLib macro in 7-Zip installers + unsigned kBackOffset = 28; + if (kkk > 1) + { + // detect old version of InstallLib macro + if (Get32(p - 1 * kCmdSize) == EW_NOP) // goto command + kBackOffset -= 2; + } + + if (kkk > kBackOffset) + { + const Byte *p2 = p - kBackOffset * kCmdSize; + UInt32 cmd = Get32(p2); + if (cmd == EW_ASSIGNVAR) + { + UInt32 pars[6]; + for (int i = 0; i < 6; i++) + pars[i] = Get32(p2 + i * 4 + 4); + if (pars[0] == 10 + 4 && pars[2] == 0 && pars[3] == 0) // 10 + 4 means $R4 + { + item.Prefix = -1; + item.NameA.Empty(); + item.NameU.Empty(); + SetItemName(item, pars[1]); + // maybe here we can restore original item name, if new name is empty + } + } + } + } + /* UInt32 allowIgnore = params[5]; */ + break; + } + + case EW_SETFILEATTRIBUTES: + { + if (kkk > 0 && Get32(p - kCmdSize) == EW_EXTRACTFILE) + { + if (params[0] == Get32(p - kCmdSize + 4 + 4 * 1)) // compare with PrevCmd.Params[1] + { + CItem &item = Items.Back(); + item.Attrib_Defined = true; + item.Attrib = params[1]; + } + } + #ifdef NSIS_SCRIPT + AddParam(params[0]); + Space(); + FlagsToString2(s, g_WinAttrib, Z7_ARRAY_SIZE(g_WinAttrib), params[1]); + #endif + break; + } + + case EW_WRITEUNINSTALLER: + { + /* NSIS 2.29+ writes alternative path to params[3] + "$INSTDIR\\" + Str(params[0]) + NSIS installer uses alternative path, if main path + from params[0] is not absolute path */ + + const bool pathOk = (params[0] > 0) && IsGoodString(params[0]); + + if (!pathOk) + { + #ifdef NSIS_SCRIPT + AddError("bad path"); + #endif + break; + } + + #ifdef NSIS_SCRIPT + + bool altPathOk = true; + + const UInt32 altParam = params[3]; + if (altParam != 0) + { + altPathOk = false; + UInt32 additional = 0; + if (GetVarIndexFinished(altParam, '\\', additional) == kVar_INSTDIR) + altPathOk = AreTwoParamStringsEqual(altParam + additional, params[0]); + } + + AddParam(params[0]); + + /* + for (int i = 1; i < 3; i++) + AddParam_UInt(params[i]); + */ + + if (params[3] != 0) + { + SmallSpaceComment(); + AddParam(params[3]); + } + + if (!altPathOk) + { + #ifdef NSIS_SCRIPT + AddError("alt path error"); + #endif + } + + #endif + + if (BadCmd >= 0 && BadCmd <= EW_WRITEUNINSTALLER) + { + /* We don't support cases with incorrect installer commands. + Such bad installer item can break unpacking for other items. */ + #ifdef NSIS_SCRIPT + AddError("SKIP possible BadCmd"); + #endif + break; + } + + CItem &item = Items.AddNew(); + + SetItemName(item, params[0]); + + item.Pos = params[1]; + item.PatchSize = params[2]; + item.IsUninstaller = true; + const UInt32 param3 = params[3]; + if (param3 != 0 && item.Prefix != -1) + { + /* (item.Prefix != -1) case means that param[0] path was not absolute. + So we use params[3] in that case, as original nsis */ + SetItemName(item, param3); + } + /* UNINSTALLER file doesn't use directory prefixes. + So we remove prefix: */ + item.Prefix = -1; + + /* + // we can add second time to test the code + CItem item2 = item; + item2.NameU += L'2'; + item2.NameA += '2'; + Items.Add(item2); + */ + + break; + } + + #ifdef NSIS_SCRIPT + + case EW_RET: + { + // bool needComment = false; + if (onFuncIsOpen) + { + if (kkk == bh.Num - 1 || IsProbablyEndOfFunc(labels[kkk + 1])) + { + AddStringLF("FunctionEnd"); + + if ((int)kkk + 1 == InitPluginsDir_End) + CommentClose(); + AddLF(); + onFuncIsOpen = false; + // needComment = true; + break; + } + } + // if (!needComment) + if (IsSectionGroup) + break; + if (sectionIsOpen) + { + const CSection § = Sections[curSectionIndex]; + if (sect.StartCmdIndex + sect.NumCommands == kkk) + { + PrintSectionEnd(); + sectionIsOpen = false; + curSectionIndex++; + break; + } + + // needComment = true; + // break; + } + + /* + if (needComment) + s += " ;"; + */ + TabString("Return"); + AddLF(); + break; + } + + case EW_NOP: + { + if (params[0] == 0) + s += "Nop"; + else + { + s += "Goto"; + Add_GotoVar(params[0]); + } + break; + } + + case EW_ABORT: + { + AddOptionalParam(params[0]); + break; + } + + case EW_CALL: + { + if (kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_EXTRACTFILE) + { + UInt32 par1 = GET_CMD_PARAM(p + kCmdSize, 1); + + UInt32 pluginPar = 0; + + if (GetVarIndexFinished(par1, '\\', pluginPar) == kVar_PLUGINSDIR) + { + pluginPar += par1; + UInt32 commandId2 = GetCmd(Get32(p + kCmdSize * 2)); + if (commandId2 == EW_SETFLAG || commandId2 == EW_UPDATETEXT) + { + UInt32 i; + for (i = kkk + 3; i < bh.Num; i++) + { + const Byte *pCmd = p + kCmdSize * (i - kkk); + UInt32 commandId3 = GetCmd(Get32(pCmd)); + if (commandId3 != EW_PUSHPOP + || GET_CMD_PARAM(pCmd, 1) != 0 + || GET_CMD_PARAM(pCmd, 2) != 0) + break; + } + if (i < bh.Num) + { + const Byte *pCmd = p + kCmdSize * (i - kkk); + + // UInt32 callDll_Param = GET_CMD_PARAM(pCmd, 0); + // UInt32 file_Param = GET_CMD_PARAM(p + kCmdSize, 1); + + if (GetCmd(Get32(pCmd)) == EW_REGISTERDLL && + AreTwoParamStringsEqual( + GET_CMD_PARAM(pCmd, 0), + GET_CMD_PARAM(p + kCmdSize, 1))) + { + // params[4] = 1 means GetModuleHandle attempt before default LoadLibraryEx; + /// new versions of NSIS use params[4] = 1 for Plugin command + if (GET_CMD_PARAM(pCmd, 2) == 0 + // && GET_CMD_PARAM(pCmd, 4) != 0 + ) + { + { + AString s2; + ReadString2(s2, pluginPar); + if (s2.Len() >= 4 && + StringsAreEqualNoCase_Ascii(s2.RightPtr(4), ".dll")) + s2.DeleteFrom(s2.Len() - 4); + s2 += "::"; + AString func; + ReadString2(func, GET_CMD_PARAM(pCmd, 1)); + s2 += func; + Add_QuStr(s2); + + if (GET_CMD_PARAM(pCmd, 3) == 1) + s += " /NOUNLOAD"; + + for (UInt32 j = i - 1; j >= kkk + 3; j--) + { + const Byte *pCmd2 = p + kCmdSize * (j - kkk); + AddParam(GET_CMD_PARAM(pCmd2, 0)); + } + NewLine(); + Tab(true); + endCommentIndex = i + 1; + } + } + } + } + } + } + } + { + const Byte *nextCmd = p + kCmdSize; + UInt32 commandId2 = GetCmd(Get32(nextCmd)); + if (commandId2 == EW_SETFLAG + && GET_CMD_PARAM(nextCmd, 0) == k_ExecFlags_DetailsPrint + && GET_CMD_PARAM(nextCmd, 2) != 0) // is "lastused" + // || commandId2 == EW_UPDATETEXT) + { + if ((Int32)params[0] > 0 && labels[params[0] - 1] & CMD_REF_InitPluginDir) + { + s += "InitPluginsDir"; + AddLF(); + Tab(true); + endCommentIndex = kkk + 2; + } + } + } + + s += "Call "; + if ((Int32)params[0] < 0) + Add_Var((UInt32)-((Int32)params[0] + 1)); + else if (params[0] == 0) + s += '0'; + else + { + const UInt32 val = params[0] - 1; + if (params[1] == 1) // it's Call :Label + { + s += ':'; + Add_LabelName(val); + } + else // if (params[1] == 0) // it's Call Func + Add_FuncName(labels, val); + } + break; + } + + case EW_UPDATETEXT: + case EW_SLEEP: + { + AddParam(params[0]); + break; + } + + case EW_CHDETAILSVIEW: + { + if (params[0] == Z7_NSIS_WIN_SW_SHOWNA && params[1] == Z7_NSIS_WIN_SW_HIDE) s += " show"; + else if (params[1] == Z7_NSIS_WIN_SW_SHOWNA && params[0] == Z7_NSIS_WIN_SW_HIDE) s += " hide"; + else + for (int i = 0; i < 2; i++) + { + Space(); + Add_ShowWindow_Cmd(params[i]); + } + break; + } + + case EW_IFFILEEXISTS: + { + AddParam(params[0]); + Add_GotoVars2(¶ms[1]); + break; + } + + case EW_SETFLAG: + { + AString temp; + ReadString2(temp, params[1]); + if (params[0] == k_ExecFlags_Errors && params[2] == 0) + { + s += (temp.Len() == 1 && temp[0] == '0') ? "ClearErrors" : "SetErrors"; + break; + } + s += "Set"; + Add_ExecFlags(params[0]); + + if (params[2] != 0) + { + s += " lastused"; + break; + } + UInt32 v; + if (StringToUInt32(temp, v)) + { + const char *s2 = NULL; + switch (params[0]) + { + case k_ExecFlags_AutoClose: + case k_ExecFlags_RebootFlag: + if (v < 2) { s2 = (v == 0) ? "false" : "true"; } break; + case k_ExecFlags_ShellVarContext: + if (v < 2) { s2 = (v == 0) ? "current" : "all"; } break; + case k_ExecFlags_Silent: + if (v < 2) { s2 = (v == 0) ? "normal" : "silent"; } break; + case k_ExecFlags_RegView: + if (v == 0) s2 = "32"; + else if (v == 256) s2 = "64"; + break; + case k_ExecFlags_DetailsPrint: + if (v == 0) s2 = "both"; + else if (v == 2) s2 = "textonly"; + else if (v == 4) s2 = "listonly"; + else if (v == 6) s2 = "none"; + break; + } + if (s2) + { + s += ' '; + s += s2; + break; + } + } + SpaceQuStr(temp); + break; + } + + case EW_IFFLAG: + { + Add_ExecFlags(params[2]); + Add_GotoVars2(¶ms[0]); + /* + const unsigned kIfErrors = 2; + if (params[2] != kIfErrors && params[3] != 0xFFFFFFFF || + params[2] == kIfErrors && params[3] != 0) + { + s += " # FLAG &= "; + AddParam_UInt(params[3]); + } + */ + break; + } + + case EW_GETFLAG: + { + Add_ExecFlags(params[1]); + AddParam_Var(params[0]); + break; + } + + case EW_RENAME: + { + if (params[2] != 0) + s += k_REBOOTOK; + AddParams(params, 2); + if (params[3] != 0) + { + SmallSpaceComment(); + AddParam(params[3]); // rename comment for log file + } + break; + } + + case EW_GETFULLPATHNAME: + { + if (params[2] == 0) + s += " /SHORT"; + AddParam_Var(params[1]); + AddParam(params[0]); + break; + } + + case EW_SEARCHPATH: + case EW_STRLEN: + { + AddParam_Var(params[0]); + AddParam(params[1]); + break; + } + + case EW_GETTEMPFILENAME: + { + AddParam_Var(params[0]); + AString temp; + ReadString2(temp, params[1]); + if (!temp.IsEqualTo("$TEMP")) + SpaceQuStr(temp); + break; + } + + case EW_DELETEFILE: + { + UInt32 flag = params[1]; + if ((flag & DEL_REBOOT) != 0) + s += k_REBOOTOK; + AddParam(params[0]); + break; + } + + case EW_MESSAGEBOX: + { + MessageBox_MB_Part(params[0]); + AddParam(params[1]); + { + UInt32 buttonID = (params[0] >> 21); // NSIS 2.06+ + if (buttonID != 0) + { + s += " /SD"; + Add_ButtonID(buttonID); + } + } + for (int i = 2; i < 6; i += 2) + if (params[i] != 0) + { + Add_ButtonID(params[i]); + Add_GotoVar1(params[i + 1]); + } + break; + } + + case EW_RMDIR: + { + UInt32 flag = params[1]; + if ((flag & DEL_RECURSE) != 0) + s += " /r"; + if ((flag & DEL_REBOOT) != 0) + s += k_REBOOTOK; + AddParam(params[0]); + break; + } + + case EW_STRCMP: + { + if (params[4] != 0) + s += 'S'; + AddParams(params, 2); + Add_GotoVars2(¶ms[2]); + break; + } + + case EW_READENVSTR: + { + s += (params[2] != 0) ? + "ReadEnvStr" : + "ExpandEnvStrings"; + AddParam_Var(params[0]); + AString temp; + ReadString2(temp, params[1]); + if (params[2] != 0 &&temp.Len() >= 2 && temp[0] == '%' && temp.Back() == '%') + { + temp.DeleteBack(); + temp.Delete(0); + } + SpaceQuStr(temp); + break; + } + + case EW_INTCMP: + { + s += "Int"; + const UInt32 param5 = params[5]; + if (param5 & 0x8000) + s += "64"; // v3.03+ + s += "Cmp"; + if (IsNsis3_OrHigher() ? (param5 & 1) : (param5 != 0)) + s += 'U'; + AddParams(params, 2); + Add_GotoVar1(params[2]); + if (params[3] != 0 || params[4] != 0) + Add_GotoVars2(params + 3); + break; + } + + case EW_INTOP: + { + AddParam_Var(params[0]); + const char * const kOps = "+-*/|&^!|&%<>>"; // NSIS 2.01+ + // "+-*/|&^!|&%"; // NSIS 2.0b4+ + // "+-*/|&^~!|&%"; // NSIS old + const UInt32 opIndex = params[3]; + const char c = (opIndex < 14) ? kOps[opIndex] : '?'; + const char c2 = (opIndex < 8 || opIndex == 10) ? (char)0 : c; + const int numOps = (opIndex == 7) ? 1 : 2; + AddParam(params[1]); + if (numOps == 2 && c == '^' && IsDirectString_Equal(params[2], "0xFFFFFFFF")) + s += " ~ ;"; + Space(); + s += c; + if (numOps != 1) + { + if (opIndex == 13) // v3.03+ : operation ">>>" + s += c; + if (c2 != 0) + s += c2; + AddParam(params[2]); + } + break; + } + + case EW_INTFMT: + { + if (params[3]) + s += "Int64Fmt"; // v3.03+ + else + s += "IntFmt"; + AddParam_Var(params[0]); + AddParams(params + 1, 2); + break; + } + + case EW_PUSHPOP: + { + if (params[2] != 0) + { + s += "Exch"; + if (params[2] != 1) + AddParam_UInt(params[2]); + } + else if (params[1] != 0) + { + s += "Pop"; + AddParam_Var(params[0]); + } + else + { + if (NoLabels(labels + kkk + 1, 2) + && Get32(p + kCmdSize) == EW_PUSHPOP // Exch" + && GET_CMD_PARAM(p + kCmdSize, 2) == 1 + && Get32(p + kCmdSize * 2) == EW_PUSHPOP // Pop $VAR + && GET_CMD_PARAM(p + kCmdSize * 2, 1) != 0) + { + if (IsVarStr(params[0], GET_CMD_PARAM(p + kCmdSize * 2, 0))) + { + s += "Exch"; + AddParam(params[0]); + NewLine(); + Tab(true); + endCommentIndex = kkk + 3; + } + } + s += "Push"; + AddParam(params[0]); + } + break; + } + + case EW_FINDWINDOW: + { + AddParam_Var(params[0]); + AddParam(params[1]); + AddOptionalParams(params + 2, 3); + break; + } + + case EW_SENDMESSAGE: + { + // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2] + AddParam(params[1]); + + const char *w = NULL; + AString t; + ReadString2(t, params[2]); + UInt32 wm; + if (StringToUInt32(t, wm)) + { + switch (wm) + { + case 0x0C: w = "SETTEXT"; break; + case 0x10: w = "CLOSE"; break; + case 0x30: w = "SETFONT"; break; + } + } + if (w) + { + s += " ${WM_"; + s += w; + s += '}'; + } + else + SpaceQuStr(t); + + UInt32 spec = params[5]; + for (unsigned i = 0; i < 2; i++) + { + AString s2; + if (spec & ((UInt32)1 << i)) + s2 += "STR:"; + ReadString2(s2, params[3 + i]); + SpaceQuStr(s2); + } + + if ((Int32)params[0] >= 0) + AddParam_Var(params[0]); + + spec >>= 2; + if (spec != 0) + { + s += " /TIMEOUT="; + Add_UInt(spec); + } + break; + } + + case EW_ISWINDOW: + { + AddParam(params[0]); + Add_GotoVars2(¶ms[1]); + break; + } + + case EW_GETDLGITEM: + { + AddParam_Var(params[0]); + AddParams(params + 1, 2); + break; + } + + case EW_SETCTLCOLORS: + { + AddParam(params[0]); + + UInt32 offset = params[1]; + + if (_size < bhCtlColors.Offset + || _size - bhCtlColors.Offset < offset + || _size - bhCtlColors.Offset - offset < GET_CtlColors_SIZE(Is64Bit)) + { + AddError("bad offset"); + break; + } + + const Byte *p2 = _data + bhCtlColors.Offset + offset; + CNsis_CtlColors colors; + colors.Parse(p2, Is64Bit); + + if ((colors.flags & kColorsFlags_BK_SYS) != 0 || + (colors.flags & kColorsFlags_TEXT_SYS) != 0) + s += " /BRANDING"; + + AString bk; + bool bkc = false; + if (colors.bkmode == Z7_NSIS_WIN_TRANSPARENT) + bk += " transparent"; + else if (colors.flags & kColorsFlags_BKB) + { + if ((colors.flags & kColorsFlags_BK_SYS) == 0 && + (colors.flags & kColorsFlags_BK) != 0) + bkc = true; + } + if ((colors.flags & kColorsFlags_TEXT) != 0 || !bk.IsEmpty() || bkc) + { + Space(); + if ((colors.flags & kColorsFlags_TEXT_SYS) != 0 || (colors.flags & kColorsFlags_TEXT) == 0) + AddQuotes(); + else + Add_Color(colors.text); + } + s += bk; + if (bkc) + { + Space(); + Add_Color(colors.bkc); + } + + break; + } + + // case EW_LOADANDSETIMAGE: + case EW_SETBRANDINGIMAGE: + { + s += " /IMGID="; + Add_UInt(params[1]); + if (params[2] == 1) + s += " /RESIZETOFIT"; + AddParam(params[0]); + break; + } + + case EW_CREATEFONT: + { + AddParam_Var(params[0]); + AddParam(params[1]); + AddOptionalParams(params + 2, 2); + if (params[4] & 1) s += " /ITALIC"; + if (params[4] & 2) s += " /UNDERLINE"; + if (params[4] & 4) s += " /STRIKE"; + break; + } + + case EW_SHOWWINDOW: + { + AString hw, sw; + ReadString2(hw, params[0]); + ReadString2(sw, params[1]); + if (params[3] != 0) + s += "EnableWindow"; + else + { + UInt32 val; + bool valDefined = false; + if (StringToUInt32(sw, val)) + { + if (val < Z7_ARRAY_SIZE(kShowWindow_Commands)) + { + sw.Empty(); + sw += "${"; + Add_ShowWindow_Cmd_2(sw, val); + sw += '}'; + valDefined = true; + } + } + bool isHwndParent = IsVarStr(params[0], IsNsis225 ? kVar_HWNDPARENT_225 : kVar_HWNDPARENT); + if (params[2] != 0) + { + if (valDefined && val == 0 && isHwndParent) + { + s += "HideWindow"; + break; + } + } + if (valDefined && val == 5 && isHwndParent && + kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_BRINGTOFRONT) + { + s += " ; "; + } + s += "ShowWindow"; + } + SpaceQuStr(hw); + SpaceQuStr(sw); + break; + } + + case EW_SHELLEXEC: + { + AddParams(params, 2); + if (params[2] != 0 || params[3] != Z7_NSIS_WIN_SW_SHOWNORMAL) + { + AddParam(params[2]); + if (params[3] != Z7_NSIS_WIN_SW_SHOWNORMAL) + { + Space(); + Add_ShowWindow_Cmd(params[3]); + } + } + if (params[5] != 0) + { + s += " ;"; + AddParam(params[5]); // it's tatus text update + } + break; + } + + case EW_EXECUTE: + { + if (params[2] != 0) + s += "Wait"; + AddParam(params[0]); + if (params[2] != 0) + if ((Int32)params[1] >= 0) + AddParam_Var(params[1]); + break; + } + + case EW_GETFILETIME: + case EW_GETDLLVERSION: + { + if (commandId == EW_GETDLLVERSION) + if (params[3] == 2) + s += " /ProductVersion"; // v3.08+ + AddParam(params[2]); + AddParam_Var(params[0]); + AddParam_Var(params[1]); + break; + } + + case EW_REGISTERDLL: + { + AString func; + ReadString2(func, params[1]); + bool printFunc = true; + // params[4] = 1; for plugin command + if (params[2] == 0) + { + s += "CallInstDLL"; + AddParam(params[0]); + if (params[3] == 1) + s += " /NOUNLOAD"; + } + else + { + if (func.IsEqualTo("DllUnregisterServer")) + { + s += "UnRegDLL"; + printFunc = false; + } + else + { + s += "RegDLL"; + if (func.IsEqualTo("DllRegisterServer")) + printFunc = false; + } + AddParam(params[0]); + } + if (printFunc) + SpaceQuStr(func); + break; + } + + case EW_CREATESHORTCUT: + { + unsigned numParams; + #define IsNsis3d0b3_OrHigher() 0 // change it + const unsigned v3_0b3 = IsNsis3d0b3_OrHigher(); + for (numParams = 6; numParams > 2; numParams--) + if (params[numParams - 1] != 0) + break; + + const UInt32 spec = params[4]; + const unsigned sw_shift = v3_0b3 ? 12 : 8; + const UInt32 sw_mask = v3_0b3 ? 0x7000 : 0x7F; + if (spec & 0x8000) // NSIS 3.0b0 + s += " /NoWorkingDir"; + + AddParams(params, numParams > 4 ? 4 : numParams); + if (numParams <= 4) + break; + + UInt32 icon = (spec & (v3_0b3 ? 0xFFF : 0xFF)); + Space(); + if (icon != 0) + Add_UInt(icon); + else + AddQuotes(); + + if ((spec >> sw_shift) == 0 && numParams < 6) + break; + UInt32 sw = (spec >> sw_shift) & sw_mask; + Space(); + // NSIS encoder replaces these names: + if (sw == Z7_NSIS_WIN_SW_SHOWMINNOACTIVE) + sw = Z7_NSIS_WIN_SW_SHOWMINIMIZED; + if (sw == 0) + AddQuotes(); + else + Add_ShowWindow_Cmd(sw); + + UInt32 modKey = spec >> 24; + UInt32 key = (spec >> 16) & 0xFF; + + if (modKey == 0 && key == 0) + { + if (numParams < 6) + break; + Space(); + AddQuotes(); + } + else + { + Space(); + if (modKey & 1) s += "SHIFT|"; // HOTKEYF_SHIFT + if (modKey & 2) s += "CONTROL|"; + if (modKey & 4) s += "ALT|"; + if (modKey & 8) s += "EXT|"; + + const unsigned kMy_VK_F1 = 0x70; + if (key >= kMy_VK_F1 && key <= kMy_VK_F1 + 23) + { + s += 'F'; + Add_UInt(key - kMy_VK_F1 + 1); + } + else if ((key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9')) + s += (char)key; + else + { + s += "Char_"; + Add_UInt(key); + } + } + AddOptionalParam(params[5]); // description + break; + } + + case EW_COPYFILES: + { + if (params[2] & 0x04) s += " /SILENT"; // FOF_SILENT + if (params[2] & 0x80) s += " /FILESONLY"; // FOF_FILESONLY + AddParams(params, 2); + if (params[3] != 0) + { + s += " ;"; + AddParam(params[3]); // status text update + } + break; + } + + case EW_REBOOT: + { + if (params[0] != 0xbadf00d) + s += " ; Corrupted ???"; + else if (kkk + 1 < bh.Num && GetCmd(Get32(p + kCmdSize)) == EW_QUIT) + endCommentIndex = kkk + 2; + break; + } + + case EW_WRITEINI: + { + unsigned numAlwaysParams = 0; + if (params[0] == 0) // Section + s += "FlushINI"; + else if (params[4] != 0) + { + s += "WriteINIStr"; + numAlwaysParams = 3; + } + else + { + s += "DeleteINI"; + s += (params[1] == 0) ? "Sec" : "Str"; + numAlwaysParams = 1; + } + AddParam(params[3]); // filename + // Section, EntryName, Value + AddParams(params, numAlwaysParams); + AddOptionalParams(params + numAlwaysParams, 3 - numAlwaysParams); + break; + } + + case EW_READINISTR: + { + AddParam_Var(params[0]); + AddParam(params[3]); // FileName + AddParams(params +1, 2); // Section, EntryName + break; + } + + case EW_DELREG: + { + // NSIS 2.00 used another scheme! + + if (params[4] == 0) + s += "Value"; + else + { + s += "Key"; + if (params[4] & 2) + s += " /ifempty"; + // TODO: /ifnosubkeys, /ifnovalues + } + AddRegRoot(params[1]); + AddParam(params[2]); + AddOptionalParam(params[3]); + break; + } + + case EW_WRITEREG: + { + const char *s2 = NULL; + switch (params[4]) + { + case 1: s2 = "Str"; break; + case 2: s2 = "ExpandStr"; break; // maybe unused + case 3: s2 = "Bin"; break; + case 4: s2 = "DWORD"; break; + default: + s += '?'; + Add_UInt(params[4]); + } + if (params[4] == 1 && params[5] == 2) + s2 = "ExpandStr"; + if (params[4] == 3 && params[5] == 7) + s2 = "MultiStr"; // v3.02+ + if (s2) + s += s2; + AddRegRoot(params[0]); + AddParams(params + 1, 2); // keyName, valueName + if (params[4] != 3) + AddParam(params[3]); // value + else + { + // Binary data. + Space(); + UInt32 offset = params[3]; + bool isSupported = false; + if (AfterHeaderSize >= 4 + && bhData.Offset <= AfterHeaderSize - 4 + && offset <= AfterHeaderSize - 4 - bhData.Offset) + { + // we support it for solid archives. + const Byte *p2 = _afterHeader + bhData.Offset + offset; + UInt32 size = Get32(p2); + if (size <= AfterHeaderSize - 4 - bhData.Offset - offset) + { + for (UInt32 i = 0; i < size; i++) + { + Byte b = (p2 + 4)[i]; + unsigned t; + t = (b >> 4); s += (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + t = (b & 15); s += (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); + } + isSupported = true; + } + } + if (!isSupported) + { + // we must read from file here; + s += "data["; + Add_UInt(offset); + s += " ... ]"; + s += " ; !!! Unsupported"; + } + } + break; + } + + case EW_READREGSTR: + { + s += (params[4] == 1) ? "DWORD" : "Str"; + AddParam_Var(params[0]); + AddRegRoot(params[1]); + AddParams(params + 2, 2); + break; + } + + case EW_REGENUM: + { + s += (params[4] != 0) ? "Key" : "Value"; + AddParam_Var(params[0]); + AddRegRoot(params[1]); + AddParams(params + 2, 2); + break; + } + + case EW_FCLOSE: + case EW_FINDCLOSE: + { + AddParam_Var(params[0]); + break; + } + + #endif + + case EW_FOPEN: + { + /* + the pattern for empty files is following: + FileOpen $0 "file_name" w + FileClose $0 + */ + + const UInt32 acc = params[1]; // dwDesiredAccess + const UInt32 creat = params[2]; // dwCreationDisposition + if (creat == Z7_NSIS_WIN_CREATE_ALWAYS && acc == Z7_NSIS_WIN_GENERIC_WRITE) + { + if (kkk + 1 < bh.Num) + if (Get32(p + kCmdSize) == EW_FCLOSE) + if (Get32(p + kCmdSize + 4) == params[0]) + { + CItem &item = Items.AddNew(); + item.IsEmptyFile = true; + SetItemName(item, params[3]); + } + } + + #ifdef NSIS_SCRIPT + + AddParam_Var(params[0]); + AddParam(params[3]); + if (acc == 0 && creat == 0) + break; + char cc = 0; + if (creat == Z7_NSIS_WIN_OPEN_EXISTING && acc == Z7_NSIS_WIN_GENERIC_READ) + cc = 'r'; + else if (creat == Z7_NSIS_WIN_CREATE_ALWAYS && acc == Z7_NSIS_WIN_GENERIC_WRITE) + cc = 'w'; + else if (creat == Z7_NSIS_WIN_OPEN_ALWAYS && (acc == (Z7_NSIS_WIN_GENERIC_WRITE | Z7_NSIS_WIN_GENERIC_READ))) + cc = 'a'; + // cc = 0; + if (cc != 0) + { + Space(); + s += cc; + break; + } + + if (acc & Z7_NSIS_WIN_GENERIC_READ) s += " GENERIC_READ"; + if (acc & Z7_NSIS_WIN_GENERIC_WRITE) s += " GENERIC_WRITE"; + if (acc & Z7_NSIS_WIN_GENERIC_EXECUTE) s += " GENERIC_EXECUTE"; + if (acc & Z7_NSIS_WIN_GENERIC_ALL) s += " GENERIC_ALL"; + + const char *s2 = NULL; + switch (creat) + { + case Z7_NSIS_WIN_CREATE_NEW: s2 = "CREATE_NEW"; break; + case Z7_NSIS_WIN_CREATE_ALWAYS: s2 = "CREATE_ALWAYS"; break; + case Z7_NSIS_WIN_OPEN_EXISTING: s2 = "OPEN_EXISTING"; break; + case Z7_NSIS_WIN_OPEN_ALWAYS: s2 = "OPEN_ALWAYS"; break; + case Z7_NSIS_WIN_TRUNCATE_EXISTING: s2 = "TRUNCATE_EXISTING"; break; + } + Space(); + if (s2) + s += s2; + else + Add_UInt(creat); + #endif + + break; + } + + #ifdef NSIS_SCRIPT + + case EW_FPUTS: + case EW_FPUTWS: + { + if (commandId == EW_FPUTWS) + s += (params[2] == 0) ? "UTF16LE" : "Word"; + else if (params[2] != 0) + s += "Byte"; + if (params[2] == 0 && params[3]) + s += " /BOM"; // v3.0b3+ + AddParam_Var(params[0]); + AddParam(params[1]); + break; + } + + case EW_FGETS: + case EW_FGETWS: + { + if (commandId == EW_FPUTWS) + s += (params[3] == 0) ? "UTF16LE" : "Word"; + if (params[3] != 0) + s += "Byte"; + AddParam_Var(params[0]); + AddParam_Var(params[1]); + AString maxLenStr; + ReadString2(maxLenStr, params[2]); + UInt32 maxLen; + if (StringToUInt32(maxLenStr, maxLen)) + { + if (maxLen == 1 && params[3] != 0) + break; + if (maxLen == 1023 && params[3] == 0) // NSIS_MAX_STRLEN - 1; can be other value!! + break; + } + SpaceQuStr(maxLenStr); + break; + } + + case EW_FSEEK: + { + AddParam_Var(params[0]); + AddParam(params[2]); + if (params[3] == 1) s += " CUR"; // FILE_CURRENT + if (params[3] == 2) s += " END"; // FILE_END + if ((Int32)params[1] >= 0) + { + if (params[3] == 0) s += " SET"; // FILE_BEGIN + AddParam_Var(params[1]); + } + break; + } + + case EW_FINDNEXT: + { + AddParam_Var(params[1]); + AddParam_Var(params[0]); + break; + } + + case EW_FINDFIRST: + { + AddParam_Var(params[1]); + AddParam_Var(params[0]); + AddParam(params[2]); + break; + } + + case EW_LOG: + { + if (params[0] != 0) + { + s += "Set "; + s += (params[1] == 0) ? "off" : "on"; + } + else + { + s += "Text"; + AddParam(params[1]); + } + break; + } + + case EW_SECTIONSET: + { + if ((Int32)params[2] >= 0) + { + s += "Get"; + Add_SectOp(params[2]); + AddParam(params[0]); + AddParam_Var(params[1]); + } + else + { + s += "Set"; + const UInt32 t = (UInt32)(-(Int32)params[2] - 1); + Add_SectOp(t); + AddParam(params[0]); + AddParam(params[t == 0 ? 4 : 1]); + + // params[3] != 0 means call SectionFlagsChanged in installer + // used by SECTIONSETFLAGS command + } + break; + } + + case EW_INSTTYPESET: + { + unsigned numQwParams = 0; + const char *s2; + if (params[3] == 0) + { + if (params[2] == 0) + { + s2 = "InstTypeGetText"; + numQwParams = 1; + } + else + { + s2 = "InstTypeSetText"; + numQwParams = 2; + } + } + else + { + if (params[2] == 0) + s2 = "GetCurInstType"; + else + { + s2 = "SetCurInstType"; + numQwParams = 1; + } + } + s += s2; + AddParams(params, numQwParams); + if (params[2] == 0) + AddParam_Var(params[1]); + break; + } + + case EW_GETOSINFO: + { + if (IsNsis3_OrHigher()) + { + // v3.06+ + if (params[3] == 0) // GETOSINFO_KNOWNFOLDER + { + s += "GetKnownFolderPath"; + AddParam_Var(params[1]); + AddParam(params[2]); + break; + } + else if (params[3] == 1) // GETOSINFO_READMEMORY + { + s += "ReadMemory"; + AddParam_Var(params[1]); + AddParam(params[2]); + AddParam(params[4]); + // if (params[2].IsEqualTo("0")) AddCommentAndString("GetWinVer"); + } + else + s += "GetOsInfo"; + break; + } + s += "GetLabelAddr"; // before v3.06+ + break; + } + + case EW_LOCKWINDOW: + { + s += (params[0] == 0) ? " on" : " off"; + break; + } + + case EW_FINDPROC: + { + AddParam_Var(params[0]); + AddParam(params[1]); + break; + } + + default: + { + numSkipParams = 0; + } + #endif + } + + #ifdef NSIS_SCRIPT + + unsigned numParams = kNumCommandParams; + + for (; numParams > 0; numParams--) + if (params[numParams - 1] != 0) + break; + + if (numParams > numSkipParams) + { + s += " ; !!!! Unknown Params: "; + unsigned i; + for (i = 0; i < numParams; i++) + AddParam(params[i]); + + s += " ;"; + + for (i = 0; i < numParams; i++) + { + Space(); + UInt32 v = params[i]; + if (v > 0xFFF00000) + Add_SignedInt(s, (Int32)v); + else + Add_UInt(v); + } + } + + NewLine(); + + #endif + } + + #ifdef NSIS_SCRIPT + + if (sectionIsOpen) + { + if (curSectionIndex < bhSections.Num) + { + const CSection § = Sections[curSectionIndex]; + if (sect.StartCmdIndex + sect.NumCommands + 1 == kkk) + { + PrintSectionEnd(); + sectionIsOpen = false; + // lastSectionEndCmd = kkk; + curSectionIndex++; + } + } + } + + while (curSectionIndex < bhSections.Num) + { + const CSection § = Sections[curSectionIndex]; + if (sectionIsOpen) + { + if (sect.StartCmdIndex + sect.NumCommands != kkk) + AddErrorLF("SECTION ERROR"); + PrintSectionEnd(); + sectionIsOpen = false; + curSectionIndex++; + } + else + { + if (PrintSectionBegin(sect, curSectionIndex)) + curSectionIndex++; + else + sectionIsOpen = true; + } + } + + #endif + + return S_OK; +} + +static int CompareItems(void *const *p1, void *const *p2, void *param) +{ + const CItem &i1 = **(const CItem *const *)p1; + const CItem &i2 = **(const CItem *const *)p2; + RINOZ(MyCompare(i1.Pos, i2.Pos)) + + /* In another code we check CItem::Pos after each solid item. + So here we place empty files before all non empty files */ + if (i1.IsEmptyFile) + { + if (!i2.IsEmptyFile) + return -1; + } + else if (i2.IsEmptyFile) + return 1; + + const CInArchive *inArchive = (const CInArchive *)param; + if (inArchive->IsUnicode) + { + if (i1.Prefix != i2.Prefix) + { + if (i1.Prefix < 0) return -1; + if (i2.Prefix < 0) return 1; + RINOZ( + inArchive->UPrefixes[i1.Prefix].Compare( + inArchive->UPrefixes[i2.Prefix])) + } + RINOZ(i1.NameU.Compare(i2.NameU)) + } + else + { + if (i1.Prefix != i2.Prefix) + { + if (i1.Prefix < 0) return -1; + if (i2.Prefix < 0) return 1; + RINOZ(strcmp( + inArchive->APrefixes[i1.Prefix], + inArchive->APrefixes[i2.Prefix])) + } + RINOZ(strcmp(i1.NameA, i2.NameA)) + } + return 0; +} + +HRESULT CInArchive::SortItems() +{ + { + Items.Sort(CompareItems, (void *)this); + unsigned i; + + for (i = 0; i + 1 < Items.Size(); i++) + { + const CItem &i1 = Items[i]; + if (i1.IsEmptyFile) + continue; + const CItem &i2 = Items[i + 1]; + if (i1.Pos != i2.Pos) + continue; + + if (IsUnicode) + { + if (i1.NameU != i2.NameU) continue; + if (i1.Prefix != i2.Prefix) + { + if (i1.Prefix < 0 || i2.Prefix < 0) continue; + if (UPrefixes[i1.Prefix] != UPrefixes[i2.Prefix]) continue; + } + } + else + { + if (i1.NameA != i2.NameA) continue; + if (i1.Prefix != i2.Prefix) + { + if (i1.Prefix < 0 || i2.Prefix < 0) continue; + if (APrefixes[i1.Prefix] != APrefixes[i2.Prefix]) continue; + } + } + Items.Delete(i + 1); + i--; + } + + for (i = 0; i < Items.Size(); i++) + { + CItem &item = Items[i]; + if (item.IsEmptyFile) + continue; + const UInt32 curPos = item.Pos + 4; + for (unsigned nextIndex = i + 1; nextIndex < Items.Size(); nextIndex++) + { + const CItem &nextItem = Items[nextIndex]; + // if (nextItem.IsEmptyFile) continue; + const UInt32 nextPos = nextItem.Pos; + if (curPos <= nextPos) + { + item.EstimatedSize_Defined = true; + item.EstimatedSize = nextPos - curPos; + break; + } + } + } + + if (!IsSolid) + { + for (i = 0; i < Items.Size(); i++) + { + CItem &item = Items[i]; + if (item.IsEmptyFile) + continue; + RINOK(SeekToNonSolidItem(i)) + const UInt32 kSigSize = 4 + 1 + 1 + 4; // size,[flag],prop,dict + BYTE sig[kSigSize]; + size_t processedSize = kSigSize; + RINOK(ReadStream(_stream, sig, &processedSize)) + if (processedSize < 4) + return S_FALSE; + UInt32 size = Get32(sig); + if ((size & kMask_IsCompressed) != 0) + { + item.IsCompressed = true; + size &= ~kMask_IsCompressed; + if (Method == NMethodType::kLZMA) + { + if (processedSize < 9) + return S_FALSE; + /* + if (FilterFlag) + item.UseFilter = (sig[4] != 0); + */ + item.DictionarySize = Get32(sig + 4 + 1 + (FilterFlag ? 1 : 0)); + } + } + else + { + item.IsCompressed = false; + item.Size = size; + item.Size_Defined = true; + } + item.CompressedSize = size; + item.CompressedSize_Defined = true; + } + } + } + return S_OK; +} + +#ifdef NSIS_SCRIPT +// Flags for common_header.flags +// #define CH_FLAGS_DETAILS_SHOWDETAILS 1 +// #define CH_FLAGS_DETAILS_NEVERSHOW 2 +#define CH_FLAGS_PROGRESS_COLORED 4 +#define CH_FLAGS_SILENT 8 +#define CH_FLAGS_SILENT_LOG 16 +#define CH_FLAGS_AUTO_CLOSE 32 +// #define CH_FLAGS_DIR_NO_SHOW 64 // unused now +#define CH_FLAGS_NO_ROOT_DIR 128 +#define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256 +#define CH_FLAGS_NO_CUSTOM 512 + +static const char * const k_PostStrings[] = +{ + "install_directory_auto_append" + , "uninstchild" // NSIS 2.25+, used by uninstaller: + , "uninstcmd" // NSIS 2.25+, used by uninstaller: + , "wininit" // NSIS 2.25+, used by move file on reboot +}; +#endif + + +void CBlockHeader::Parse(const Byte *p, unsigned bhoSize) +{ + if (bhoSize == 12) + { + // UInt64 a = GetUi64(p); + if (GetUi32(p + 4) != 0) + throw 1; + } + Offset = GetUi32(p); + Num = GetUi32(p + bhoSize - 4); +} + +#define PARSE_BH(k, bh) bh.Parse (p1 + 4 + bhoSize * k, bhoSize) + + +HRESULT CInArchive::Parse() +{ + // UInt32 offset = ReadUInt32(); + // ???? offset == FirstHeader.HeaderSize + const Byte * const p1 = _data; + + if (_size < 4 + 12 * 8) + Is64Bit = false; + else + { + Is64Bit = true; + // here we test high 32-bit of possible UInt64 CBlockHeader::Offset field + for (int k = 0; k < 8; k++) + if (GetUi32(p1 + 4 + 12 * k + 4) != 0) + Is64Bit = false; + } + + const unsigned bhoSize = Is64Bit ? 12 : 8; + if (_size < 4 + bhoSize * 8) + return S_FALSE; + + CBlockHeader bhEntries, bhStrings, bhLangTables; + + PARSE_BH (2, bhEntries); + PARSE_BH (3, bhStrings); + PARSE_BH (4, bhLangTables); + + #ifdef NSIS_SCRIPT + + CBlockHeader bhFont; + PARSE_BH (0, bhPages); + PARSE_BH (1, bhSections); + PARSE_BH (5, bhCtlColors); + PARSE_BH (6, bhFont); + PARSE_BH (7, bhData); + + #endif + + _stringsPos = bhStrings.Offset; + if (_stringsPos > _size + || bhLangTables.Offset > _size + || bhEntries.Offset > _size) + return S_FALSE; + { + if (bhLangTables.Offset < bhStrings.Offset) + return S_FALSE; + const UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset; + if (stringTableSize < 2) + return S_FALSE; + const Byte *strData = _data + _stringsPos; + if (strData[stringTableSize - 1] != 0) + return S_FALSE; + IsUnicode = (Get16(strData) == 0); + NumStringChars = stringTableSize; + if (IsUnicode) + { + if ((stringTableSize & 1) != 0) + return S_FALSE; + NumStringChars >>= 1; + if (strData[stringTableSize - 2] != 0) + return S_FALSE; + } + } + + if (bhEntries.Num > (1 << 25)) + return S_FALSE; + if (bhEntries.Num * kCmdSize > _size - bhEntries.Offset) + return S_FALSE; + + DetectNsisType(bhEntries, _data + bhEntries.Offset); + + Decoder.IsNsisDeflate = (NsisType != k_NsisType_Nsis3); + + // some NSIS files (that are not detected as k_NsisType_Nsis3) + // use original (non-NSIS) Deflate + // How to detect these cases? + + // Decoder.IsNsisDeflate = false; + + + #ifdef NSIS_SCRIPT + + { + AddCommentAndString("NSIS script"); + if (IsUnicode) + Script += " (UTF-8)"; + Space(); + Script += GetFormatDescription(); + AddLF(); + } + { + AddCommentAndString(IsInstaller ? "Install" : "Uninstall"); + AddLF(); + } + + AddLF(); + if (Is64Bit) + AddStringLF("Target AMD64-Unicode"); // TODO: Read PE machine type and use the correct CPU type + else if (IsUnicode) + AddStringLF("Unicode true"); + else if (IsNsis3_OrHigher()) + AddStringLF("Unicode false"); // Unicode is the default in 3.07+ + + if (Method != NMethodType::kCopy) + { + const char *m = NULL; + switch ((int)Method) + { + case NMethodType::kDeflate: m = "zlib"; break; + case NMethodType::kBZip2: m = "bzip2"; break; + case NMethodType::kLZMA: m = "lzma"; break; + default: break; + } + Script += "SetCompressor"; + if (IsSolid) + Script += " /SOLID"; + if (m) + { + Space(); + Script += m; + } + AddLF(); + } + if (Method == NMethodType::kLZMA) + { + // if (DictionarySize != (8 << 20)) + { + Script += "SetCompressorDictSize"; + AddParam_UInt(DictionarySize >> 20); + AddLF(); + } + } + + Separator(); + PrintNumComment("HEADER SIZE", FirstHeader.HeaderSize); + // if (bhPages.Offset != 300 && bhPages.Offset != 288) + if (bhPages.Offset != 0) + { + PrintNumComment("START HEADER SIZE", bhPages.Offset); + } + + if (bhSections.Num > 0) + { + if (bhEntries.Offset < bhSections.Offset) + return S_FALSE; + SectionSize = (bhEntries.Offset - bhSections.Offset) / bhSections.Num; + if (bhSections.Offset + bhSections.Num * SectionSize != bhEntries.Offset) + return S_FALSE; + if (SectionSize < kSectionSize_base) + return S_FALSE; + UInt32 maxStringLen = SectionSize - kSectionSize_base; + if (IsUnicode) + { + if ((maxStringLen & 1) != 0) + return S_FALSE; + maxStringLen >>= 1; + } + // if (maxStringLen != 1024) + { + if (maxStringLen == 0) + PrintNumComment("SECTION SIZE", SectionSize); + else + PrintNumComment("MAX STRING LENGTH", maxStringLen); + } + } + + PrintNumComment("STRING CHARS", NumStringChars); + // PrintNumComment("LANG TABLE SIZE", bhCtlColors.Offset - bhLangTables.Offset); + + if (bhCtlColors.Offset > _size) + AddErrorLF("Bad COLORS TABLE"); + // PrintNumComment("COLORS TABLE SIZE", bhFont.Offset - bhCtlColors.Offset); + if (bhCtlColors.Num != 0) + PrintNumComment("COLORS Num", bhCtlColors.Num); + + // bhData uses offset in _afterHeader (not in _data) + // PrintNumComment("FONT TABLE SIZE", bhData.Offset - bhFont.Offset); + if (bhFont.Num != 0) + PrintNumComment("FONTS Num", bhFont.Num); + + // PrintNumComment("DATA SIZE", FirstHeader.HeaderSize - bhData.Offset); + if (bhData.Num != 0) + PrintNumComment("DATA NUM", bhData.Num); + + AddLF(); + + AddStringLF("OutFile [NSIS].exe"); + AddStringLF("!include WinMessages.nsh"); + + AddLF(); + + strUsed.Alloc(NumStringChars); + memset(strUsed, 0, NumStringChars); + + { + UInt32 ehFlags = Get32(p1); + UInt32 showDetails = ehFlags & 3;// CH_FLAGS_DETAILS_SHOWDETAILS & CH_FLAGS_DETAILS_NEVERSHOW; + if (showDetails >= 1 && showDetails <= 2) + { + Script += IsInstaller ? "ShowInstDetails" : "ShowUninstDetails"; + Script += (showDetails == 1) ? " show" : " nevershow"; + AddLF(); + } + if (ehFlags & CH_FLAGS_PROGRESS_COLORED) AddStringLF("InstProgressFlags colored" ); + if ((ehFlags & (CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG)) != 0) + { + Script += IsInstaller ? "SilentInstall " : "SilentUnInstall "; + Script += (ehFlags & CH_FLAGS_SILENT_LOG) ? "silentlog" : "silent"; + AddLF(); + } + if (ehFlags & CH_FLAGS_AUTO_CLOSE) AddStringLF("AutoCloseWindow true"); + if ((ehFlags & CH_FLAGS_NO_ROOT_DIR) == 0) AddStringLF("AllowRootDirInstall true"); + if (ehFlags & CH_FLAGS_NO_CUSTOM) AddStringLF("InstType /NOCUSTOM"); + if (ehFlags & CH_FLAGS_COMP_ONLY_ON_CUSTOM) AddStringLF("InstType /COMPONENTSONLYONCUSTOM"); + } + + // Separator(); + // AddLF(); + + Int32 licenseLangIndex = -1; + { + const Byte *pp = _data + bhPages.Offset; + + for (UInt32 pageIndex = 0; pageIndex < bhPages.Num; pageIndex++, pp += kPageSize) + { + UInt32 wndProcID = Get32(pp + 4); + UInt32 param1 = Get32(pp + 44 + 4 * 1); + if (wndProcID != PWP_LICENSE || param1 == 0) + continue; + if ((Int32)param1 < 0) + licenseLangIndex = - ((Int32)param1 + 1); + else + noParseStringIndexes.AddToUniqueSorted(param1); + } + } + + unsigned paramsOffset; + { + unsigned numBhs = 8; + // probably its for old NSIS? + if (bhoSize == 8 && bhPages.Offset == 276) + numBhs = 7; + paramsOffset = 4 + bhoSize * numBhs; + } + + const Byte *p2 = p1 + paramsOffset; + + { + UInt32 rootKey = Get32(p2); // (rootKey = -1) in uninstaller by default (the bug in NSIS) + UInt32 subKey = Get32(p2 + 4); + UInt32 value = Get32(p2 + 8); + if ((rootKey != 0 && rootKey != (UInt32)(Int32)-1) || subKey != 0 || value != 0) + { + Script += "InstallDirRegKey"; + AddRegRoot(rootKey); + AddParam(subKey); + AddParam(value); + AddLF(); + } + } + + + { + UInt32 bg_color1 = Get32(p2 + 12); + UInt32 bg_color2 = Get32(p2 + 16); + UInt32 bg_textcolor = Get32(p2 + 20); + if (bg_color1 != (UInt32)(Int32)-1 || bg_color2 != (UInt32)(Int32)-1 || bg_textcolor != (UInt32)(Int32)-1) + { + Script += "BGGradient"; + if (bg_color1 != 0 || bg_color2 != 0xFF0000 || bg_textcolor != (UInt32)(Int32)-1) + { + Add_ColorParam(bg_color1); + Add_ColorParam(bg_color2); + if (bg_textcolor != (UInt32)(Int32)-1) + Add_ColorParam(bg_textcolor); + } + AddLF(); + } + } + + { + UInt32 lb_bg = Get32(p2 + 24); + UInt32 lb_fg = Get32(p2 + 28); + if ((lb_bg != (UInt32)(Int32)-1 || lb_fg != (UInt32)(Int32)-1) && + (lb_bg != 0 || lb_fg != 0xFF00)) + { + Script += "InstallColors"; + Add_ColorParam(lb_fg); + Add_ColorParam(lb_bg); + AddLF(); + } + } + + UInt32 license_bg = Get32(p2 + 36); + if (license_bg != (UInt32)(Int32)-1 && + license_bg != (UInt32)(Int32)-15) // COLOR_BTNFACE + { + Script += "LicenseBkColor"; + if ((Int32)license_bg == -5) // COLOR_WINDOW + Script += " /windows"; + /* + else if ((Int32)license_bg == -15) + Script += " /grey"; + */ + else + Add_ColorParam(license_bg); + AddLF(); + } + + if (bhLangTables.Num > 0) + { + const UInt32 langtable_size = Get32(p2 + 32); + + if (langtable_size == (UInt32)(Int32)-1) + return E_NOTIMPL; // maybe it's old NSIS archive() + + if (langtable_size < 10) + return S_FALSE; + if (bhLangTables.Num > (_size - bhLangTables.Offset) / langtable_size) + return S_FALSE; + + const UInt32 numStrings = (langtable_size - 10) / 4; + _numLangStrings = numStrings; + AddLF(); + Separator(); + PrintNumComment("LANG TABLES", bhLangTables.Num); + PrintNumComment("LANG STRINGS", numStrings); + AddLF(); + + if (licenseLangIndex >= 0 && (unsigned)licenseLangIndex < numStrings) + { + for (UInt32 i = 0; i < bhLangTables.Num; i++) + { + const Byte * const p = _data + bhLangTables.Offset + langtable_size * i; + const UInt16 langID = Get16(p); + UInt32 val = Get32(p + 10 + (UInt32)licenseLangIndex * 4); + if (val != 0) + { + Script += "LicenseLangString "; + Add_LangStr_Simple((UInt32)licenseLangIndex); + AddParam_UInt(langID); + AddLicense(val, langID); + noParseStringIndexes.AddToUniqueSorted(val); + NewLine(); + } + } + AddLF(); + } + + UInt32 names[3] = { 0 }; + + UInt32 i; + for (i = 0; i < bhLangTables.Num; i++) + { + const Byte * const p = _data + bhLangTables.Offset + langtable_size * i; + const UInt16 langID = Get16(p); + if (i == 0 || langID == 1033) + _mainLang = p + 10; + for (unsigned k = 0; k < Z7_ARRAY_SIZE(names) && k < numStrings; k++) + { + UInt32 v = Get32(p + 10 + k * 4); + if (v != 0 && (langID == 1033 || names[k] == 0)) + names[k] = v; + } + } + + const UInt32 name = names[2]; + if (name != 0) + { + Script += "Name"; + AddParam(name); + NewLine(); + + ReadString2(Name, name); + } + + /* + const UInt32 caption = names[1]; + if (caption != 0) + { + Script += "Caption"; + AddParam(caption); + NewLine(); + } + */ + + const UInt32 brandingText = names[0]; + if (brandingText != 0) + { + Script += "BrandingText"; + AddParam(brandingText); + NewLine(); + + ReadString2(BrandingText, brandingText); + } + + for (i = 0; i < bhLangTables.Num; i++) + { + const Byte * const p = _data + bhLangTables.Offset + langtable_size * i; + const UInt16 langID = Get16(p); + + AddLF(); + AddCommentAndString("LANG:"); + AddParam_UInt(langID); + /* + Script += " ("; + LangId_To_String(Script, langID); + Script += ')'; + */ + AddLF(); + // UInt32 dlg_offset = Get32(p + 2); + // UInt32 g_exec_flags_rtl = Get32(p + 6); + + + for (UInt32 j = 0; j < numStrings; j++) + { + UInt32 val = Get32(p + 10 + j * 4); + if (val != 0) + { + if ((Int32)j != licenseLangIndex) + { + Script += "LangString "; + Add_LangStr_Simple(j); + AddParam_UInt(langID); + AddParam(val); + AddLF(); + } + } + } + AddLF(); + } + ClearLangComment(); + } + + { + unsigned numInternalVars = GET_NUM_INTERNAL_VARS; + UInt32 numUsedVars = GetNumUsedVars(); + if (numUsedVars > numInternalVars) + { + Separator(); + PrintNumComment("VARIABLES", numUsedVars - numInternalVars); + AddLF(); + AString temp; + for (UInt32 i = numInternalVars; i < numUsedVars; i++) + { + Script += "Var "; + temp.Empty(); + GetVar2(temp, i); + AddStringLF(temp); + } + AddLF(); + } + } + + onFuncOffset = paramsOffset + 40; + numOnFunc = Z7_ARRAY_SIZE(kOnFunc); + if (bhPages.Offset == 276) + numOnFunc--; + p2 += 40 + numOnFunc * 4; + + #define NSIS_MAX_INST_TYPES 32 + + AddLF(); + + UInt32 i; + for (i = 0; i < NSIS_MAX_INST_TYPES + 1; i++, p2 += 4) + { + UInt32 instType = Get32(p2); + if (instType != 0) + { + Script += "InstType"; + AString s2; + if (!IsInstaller) + s2 += "un."; + ReadString2(s2, instType); + SpaceQuStr(s2); + NewLine(); + } + } + + { + UInt32 installDir = Get32(p2); + p2 += 4; + if (installDir != 0) + { + Script += "InstallDir"; + AddParam(installDir); + NewLine(); + } + } + + if (bhPages.Offset >= 288) + for (i = 0; i < 4; i++) + { + if (i != 0 && bhPages.Offset < 300) + break; + UInt32 param = Get32(p2 + 4 * i); + if (param == 0 || param == (UInt32)(Int32)-1) + continue; + + /* + uninstaller: + UInt32 uninstChild = Get32(p2 + 8); // "$TEMP\\$1u_.exe" + UInt32 uninstCmd = Get32(p2 + 12); // "\"$TEMP\\$1u_.exe\" $0 _?=$INSTDIR\\" + int str_wininit = Get32(p2 + 16); // "$WINDIR\\wininit.ini" + */ + + AddCommentAndString(k_PostStrings[i]); + Script += " ="; + AddParam(param); + NewLine(); + } + + AddLF(); + + #endif + + RINOK(ReadEntries(bhEntries)) + + #ifdef NSIS_SCRIPT + + Separator(); + AddCommentAndString("UNREFERENCED STRINGS:"); + AddLF(); + AddLF(); + CommentOpen(); + + for (i = 0; i < NumStringChars;) + { + if (!strUsed[i] && i != 0) + // Script += "!!! "; + { + Add_UInt(i); + AddParam(i); + NewLine(); + } + if (IsUnicode) + i += GetUi16Str_Len((const Byte *)_data + _stringsPos + i * 2); + else + i += (UInt32)strlen((const char *)(const Byte *)_data + _stringsPos + i); + i++; + } + CommentClose(); + #endif + + return SortItems(); +} + +static bool IsLZMA(const Byte *p, UInt32 &dictionary) +{ + dictionary = Get32(p + 1); + return (p[0] == 0x5D && + p[1] == 0x00 && p[2] == 0x00 && + p[5] == 0x00 && (p[6] & 0x80) == 0x00); +} + +static bool IsLZMA(const Byte *p, UInt32 &dictionary, bool &thereIsFlag) +{ + if (IsLZMA(p, dictionary)) + { + thereIsFlag = false; + return true; + } + if (p[0] <= 1 && IsLZMA(p + 1, dictionary)) + { + thereIsFlag = true; + return true; + } + return false; +} + +static bool IsBZip2(const Byte *p) +{ + return (p[0] == 0x31 && p[1] < 14); +} + +HRESULT CInArchive::Open2(const Byte *sig, size_t size) +{ + const UInt32 kSigSize = 4 + 1 + 5 + 2; // size, flag, 5 - lzma props, 2 - lzma first bytes + if (size < kSigSize) + return S_FALSE; + + _headerIsCompressed = true; + IsSolid = true; + FilterFlag = false; + UseFilter = false; + DictionarySize = 1; + + #ifdef NSIS_SCRIPT + AfterHeaderSize = 0; + #endif + + UInt32 compressedHeaderSize = Get32(sig); + + + /* + XX XX XX XX XX XX XX XX == FirstHeader.HeaderSize, nonsolid, uncompressed + 5D 00 00 dd dd 00 solid LZMA + 00 5D 00 00 dd dd 00 solid LZMA, empty filter (there are no such archives) + 01 5D 00 00 dd dd 00 solid LZMA, BCJ filter (only 7-Zip installer used that format) + + SS SS SS 80 00 5D 00 00 dd dd 00 non-solid LZMA, empty filter + SS SS SS 80 01 5D 00 00 dd dd 00 non-solid LZMA, BCJ filte + SS SS SS 80 01 tt non-solid BZip (tt < 14 + SS SS SS 80 non-solid deflate + + 01 tt solid BZip (tt < 14 + other solid Deflate + */ + + if (compressedHeaderSize == FirstHeader.HeaderSize) + { + _headerIsCompressed = false; + IsSolid = false; + Method = NMethodType::kCopy; + } + else if (IsLZMA(sig, DictionarySize, FilterFlag)) + Method = NMethodType::kLZMA; + else if (sig[3] == 0x80) + { + IsSolid = false; + if (IsLZMA(sig + 4, DictionarySize, FilterFlag) && sig[3] == 0x80) + Method = NMethodType::kLZMA; + else if (IsBZip2(sig + 4)) + Method = NMethodType::kBZip2; + else + Method = NMethodType::kDeflate; + } + else if (IsBZip2(sig)) + Method = NMethodType::kBZip2; + else + Method = NMethodType::kDeflate; + + if (IsSolid) + { + RINOK(SeekTo_DataStreamOffset()) + } + else + { + _headerIsCompressed = ((compressedHeaderSize & kMask_IsCompressed) != 0); + compressedHeaderSize &= ~kMask_IsCompressed; + _nonSolidStartOffset = compressedHeaderSize; + RINOK(SeekTo(DataStreamOffset + 4)) + } + + if (FirstHeader.HeaderSize == 0) + return S_FALSE; + + _data.Alloc(FirstHeader.HeaderSize); + _size = (size_t)FirstHeader.HeaderSize; + + Decoder.Method = Method; + Decoder.FilterFlag = FilterFlag; + Decoder.Solid = IsSolid; + + Decoder.IsNsisDeflate = true; // we need some smart check that NSIS is not NSIS3 here. + + Decoder.InputStream = _stream; + Decoder.Buffer.Alloc(kInputBufSize); + Decoder.StreamPos = 0; + + if (_headerIsCompressed) + { + RINOK(Decoder.Init(_stream, UseFilter)) + if (IsSolid) + { + size_t processedSize = 4; + Byte buf[4]; + RINOK(Decoder.Read(buf, &processedSize)) + if (processedSize != 4) + return S_FALSE; + if (Get32((const Byte *)buf) != FirstHeader.HeaderSize) + return S_FALSE; + } + { + size_t processedSize = FirstHeader.HeaderSize; + RINOK(Decoder.Read(_data, &processedSize)) + if (processedSize != FirstHeader.HeaderSize) + return S_FALSE; + } + + #ifdef NSIS_SCRIPT + if (IsSolid) + { + /* we need additional bytes for data for WriteRegBin */ + AfterHeaderSize = (1 << 12); + _afterHeader.Alloc(AfterHeaderSize); + size_t processedSize = AfterHeaderSize; + RINOK(Decoder.Read(_afterHeader, &processedSize)) + AfterHeaderSize = (UInt32)processedSize; + } + #endif + } + else + { + size_t processedSize = FirstHeader.HeaderSize; + RINOK(ReadStream(_stream, (Byte *)_data, &processedSize)) + if (processedSize < FirstHeader.HeaderSize) + return S_FALSE; + } + + #ifdef NUM_SPEED_TESTS + for (unsigned i = 0; i < NUM_SPEED_TESTS; i++) + { + RINOK(Parse()); + Clear2(); + } + #endif + + return Parse(); +} + +/* +NsisExe = +{ + ExeStub + Archive // must start from 512 * N + #ifndef NSIS_CONFIG_CRC_ANAL + { + Some additional data + } +} + +Archive +{ + FirstHeader + Data + #ifdef NSIS_CONFIG_CRC_SUPPORT && FirstHeader.ThereIsCrc() + { + CRC + } +} + +FirstHeader +{ + UInt32 Flags; + Byte Signature[16]; + // points to the header+sections+entries+stringtable in the datablock + UInt32 HeaderSize; + UInt32 ArcSize; +} +*/ + + +// ---------- PE (EXE) parsing ---------- + +static const unsigned k_PE_StartSize = 0x40; +static const unsigned k_PE_HeaderSize = 4 + 20; +static const unsigned k_PE_OptHeader32_Size_MIN = 96; + +static inline bool CheckPeOffset(UInt32 pe) +{ + return (pe >= 0x40 && pe <= 0x1000 && (pe & 7) == 0); +} + + +static bool IsArc_Pe(const Byte *p, size_t size) +{ + if (size < 2) + return false; + if (p[0] != 'M' || p[1] != 'Z') + return false; + if (size < k_PE_StartSize) + return false; // k_IsArc_Res_NEED_MORE; + UInt32 pe = Get32(p + 0x3C); + if (!CheckPeOffset(pe)) + return false; + if (pe + k_PE_HeaderSize > size) + return false; // k_IsArc_Res_NEED_MORE; + + p += pe; + if (Get32(p) != 0x00004550) + return false; + return Get16(p + 4 + 16) >= k_PE_OptHeader32_Size_MIN; +} + +HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition) +{ + Clear(); + + RINOK(InStream_GetPos(inStream, StartOffset)) + + const UInt32 kStartHeaderSize = 4 * 7; + const unsigned kStep = 512; // nsis start is aligned for 512 + Byte buf[kStep]; + UInt64 pos = StartOffset; + size_t bufSize = 0; + UInt64 pePos = (UInt64)(Int64)-1; + + for (;;) + { + bufSize = kStep; + RINOK(ReadStream(inStream, buf, &bufSize)) + if (bufSize < kStartHeaderSize) + return S_FALSE; + if (memcmp(buf + 4, kSignature, kSignatureSize) == 0) + break; + if (IsArc_Pe(buf, bufSize)) + pePos = pos; + pos += kStep; + UInt64 proc = pos - StartOffset; + if (maxCheckStartPosition && proc > *maxCheckStartPosition) + { + if (pePos == 0) + { + if (proc > (1 << 20)) + return S_FALSE; + } + else + return S_FALSE; + } + } + + if (pePos == (UInt64)(Int64)-1) + { + UInt64 posCur = StartOffset; + for (;;) + { + if (posCur < kStep) + break; + posCur -= kStep; + if (pos - posCur > (1 << 20)) + break; + bufSize = kStep; + RINOK(InStream_SeekSet(inStream, posCur)) + RINOK(ReadStream(inStream, buf, &bufSize)) + if (bufSize < kStep) + break; + if (IsArc_Pe(buf, bufSize)) + { + pePos = posCur; + break; + } + } + + // restore buf to nsis header + bufSize = kStep; + RINOK(InStream_SeekSet(inStream, pos)) + RINOK(ReadStream(inStream, buf, &bufSize)) + if (bufSize < kStartHeaderSize) + return S_FALSE; + } + + StartOffset = pos; + UInt32 peSize = 0; + + if (pePos != (UInt64)(Int64)-1) + { + UInt64 peSize64 = (pos - pePos); + if (peSize64 < (1 << 20)) + { + peSize = (UInt32)peSize64; + StartOffset = pePos; + } + } + + DataStreamOffset = pos + kStartHeaderSize; + FirstHeader.Flags = Get32(buf); + if ((FirstHeader.Flags & (~kFlagsMask)) != 0) + { + // return E_NOTIMPL; + return S_FALSE; + } + IsInstaller = (FirstHeader.Flags & NFlags::kUninstall) == 0; + + FirstHeader.HeaderSize = Get32(buf + kSignatureSize + 4); + FirstHeader.ArcSize = Get32(buf + kSignatureSize + 8); + if (FirstHeader.ArcSize <= kStartHeaderSize) + return S_FALSE; + + /* + if ((FirstHeader.Flags & NFlags::k_BI_ExternalFileSupport) != 0) + { + UInt32 datablock_low = Get32(buf + kSignatureSize + 12); + UInt32 datablock_high = Get32(buf + kSignatureSize + 16); + } + */ + + RINOK(InStream_GetSize_SeekToEnd(inStream, _fileSize)) + + IsArc = true; + + if (peSize != 0) + { + ExeStub.Alloc(peSize); + RINOK(InStream_SeekSet(inStream, pePos)) + RINOK(ReadStream_FALSE(inStream, ExeStub, peSize)) + } + + HRESULT res = S_FALSE; + try + { + CLimitedInStream *_limitedStreamSpec = new CLimitedInStream; + _stream = _limitedStreamSpec; + _limitedStreamSpec->SetStream(inStream); + _limitedStreamSpec->InitAndSeek(pos, FirstHeader.ArcSize); + DataStreamOffset -= pos; + res = Open2(buf + kStartHeaderSize, bufSize - kStartHeaderSize); + } + catch(...) + { + _stream.Release(); + throw; + // res = S_FALSE; + } + if (res != S_OK) + { + _stream.Release(); + // Clear(); + } + return res; +} + +UString CInArchive::ConvertToUnicode(const AString &s) const +{ + if (IsUnicode) + { + UString res; + // if ( + ConvertUTF8ToUnicode(s, res); + return res; + } + return MultiByteToUnicodeString(s); +} + +void CInArchive::Clear2() +{ + IsUnicode = false; + NsisType = k_NsisType_Nsis2; + IsNsis225 = false; + IsNsis200 = false; + LogCmdIsEnabled = false; + BadCmd = -1; + Is64Bit = false; + + #ifdef NSIS_SCRIPT + Name.Empty(); + BrandingText.Empty(); + Script.Empty(); + LicenseFiles.Clear(); + _numRootLicenses = 0; + _numLangStrings = 0; + langStrIDs.Clear(); + LangComment.Empty(); + noParseStringIndexes.Clear(); + #endif + + APrefixes.Clear(); + UPrefixes.Clear(); + Items.Clear(); + IsUnicode = false; + ExeStub.Free(); +} + +void CInArchive::Clear() +{ + Clear2(); + IsArc = false; + _stream.Release(); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisIn.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisIn.h 2023-12-11 11:00:00.000000000 +0000 @@ -1,445 +1,458 @@ -// NsisIn.h - -#ifndef __ARCHIVE_NSIS_IN_H -#define __ARCHIVE_NSIS_IN_H - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/DynLimBuf.h" -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyCom.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "NsisDecode.h" - -/* If NSIS_SCRIPT is defined, it will decompile NSIS script to [NSIS].nsi file. - The code is much larger in that case. */ - -// #define NSIS_SCRIPT - -namespace NArchive { -namespace NNsis { - -const size_t kScriptSizeLimit = 1 << 27; - -const unsigned kSignatureSize = 16; -extern const Byte kSignature[kSignatureSize]; -#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 'N', 'u', 'l', 'l', 's', 'o', 'f', 't', 'I', 'n', 's', 't' } - -const UInt32 kFlagsMask = 0xF; -namespace NFlags -{ - const UInt32 kUninstall = 1; - const UInt32 kSilent = 2; - const UInt32 kNoCrc = 4; - const UInt32 kForceCrc = 8; -} - -struct CFirstHeader -{ - UInt32 Flags; - UInt32 HeaderSize; - UInt32 ArcSize; - - bool ThereIsCrc() const - { - return - (Flags & NFlags::kForceCrc) != 0 || - (Flags & NFlags::kNoCrc) == 0; - } - - UInt32 GetDataSize() const { return ArcSize - (ThereIsCrc() ? 4 : 0); } -}; - - -struct CBlockHeader -{ - UInt32 Offset; - UInt32 Num; - - void Parse(const Byte *p) - { - Offset = GetUi32(p); - Num = GetUi32(p + 4); - } -}; - -struct CItem -{ - bool IsCompressed; - bool Size_Defined; - bool CompressedSize_Defined; - bool EstimatedSize_Defined; - bool Attrib_Defined; - bool IsUninstaller; - // bool UseFilter; - - UInt32 Attrib; - UInt32 Pos; - UInt32 Size; - UInt32 CompressedSize; - UInt32 EstimatedSize; - UInt32 DictionarySize; - UInt32 PatchSize; // for Uninstaller.exe - int Prefix; // - 1 means no prefix - - FILETIME MTime; - AString NameA; - UString NameU; - - CItem(): - IsCompressed(true), - Size_Defined(false), - CompressedSize_Defined(false), - EstimatedSize_Defined(false), - Attrib_Defined(false), - IsUninstaller(false), - // UseFilter(false), - Attrib(0), - Pos(0), - Size(0), - CompressedSize(0), - EstimatedSize(0), - DictionarySize(1), - PatchSize(0), - Prefix(-1) - { - MTime.dwLowDateTime = 0; - MTime.dwHighDateTime = 0; - } - - /* - bool IsINSTDIR() const - { - return (PrefixA.Len() >= 3 || PrefixU.Len() >= 3); - } - */ -}; - -enum ENsisType -{ - k_NsisType_Nsis2, - k_NsisType_Nsis3, - k_NsisType_Park1, // Park 2.46.1- - k_NsisType_Park2, // Park 2.46.2 : GetFontVersion - k_NsisType_Park3 // Park 2.46.3+ : GetFontName -}; - -#ifdef NSIS_SCRIPT - -struct CSection -{ - UInt32 InstallTypes; // bits set for each of the different install_types, if any. - UInt32 Flags; // SF_* - defined above - UInt32 StartCmdIndex; // code; - UInt32 NumCommands; // code_size; - UInt32 SizeKB; - UInt32 Name; - - void Parse(const Byte *data); -}; - -struct CLicenseFile -{ - UInt32 Offset; - UInt32 Size; - AString Name; - CByteBuffer Text; -}; - -#endif - -class CInArchive -{ -public: - #ifdef NSIS_SCRIPT - CDynLimBuf Script; - #endif - CByteBuffer _data; - CObjectVector Items; - bool IsUnicode; -private: - UInt32 _stringsPos; // relative to _data - UInt32 NumStringChars; - size_t _size; // it's Header Size - - AString Raw_AString; - UString Raw_UString; - - ENsisType NsisType; - bool IsNsis200; // NSIS 2.03 and before - bool IsNsis225; // NSIS 2.25 and before - - bool LogCmdIsEnabled; - int BadCmd; // -1: no bad command; in another cases lowest bad command id - - bool IsPark() const { return NsisType >= k_NsisType_Park1; } - - UInt64 _fileSize; - - bool _headerIsCompressed; - UInt32 _nonSolidStartOffset; - - #ifdef NSIS_SCRIPT - - CByteBuffer strUsed; - - CBlockHeader bhPages; - CBlockHeader bhSections; - CBlockHeader bhCtlColors; - CBlockHeader bhData; - UInt32 AfterHeaderSize; - CByteBuffer _afterHeader; - - UInt32 SectionSize; - const Byte *_mainLang; - UInt32 _numLangStrings; - AString LangComment; - CRecordVector langStrIDs; - UInt32 numOnFunc; - UInt32 onFuncOffset; - // CRecordVector OnFuncs; - unsigned _numRootLicenses; - CRecordVector noParseStringIndexes; - AString _tempString_for_GetVar; - AString _tempString_for_AddFuncName; - AString _tempString; - - #endif - - -public: - CMyComPtr _stream; // it's limited stream that contains only NSIS archive - UInt64 StartOffset; // offset in original stream. - UInt64 DataStreamOffset; // = sizeof(FirstHeader) = offset of Header in _stream - - bool IsArc; - - CDecoder Decoder; - CByteBuffer ExeStub; - CFirstHeader FirstHeader; - NMethodType::EEnum Method; - UInt32 DictionarySize; - bool IsSolid; - bool UseFilter; - bool FilterFlag; - - bool IsInstaller; - AString Name; - AString BrandingText; - UStringVector UPrefixes; - AStringVector APrefixes; - - #ifdef NSIS_SCRIPT - CObjectVector LicenseFiles; - #endif - -private: - void GetShellString(AString &s, unsigned index1, unsigned index2); - void GetNsisString_Raw(const Byte *s); - void GetNsisString_Unicode_Raw(const Byte *s); - void ReadString2_Raw(UInt32 pos); - bool IsGoodString(UInt32 param) const; - bool AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const; - - void Add_LangStr(AString &res, UInt32 id); - - #ifdef NSIS_SCRIPT - - void Add_UInt(UInt32 v); - void AddLicense(UInt32 param, Int32 langID); - - void Add_LangStr_Simple(UInt32 id); - void Add_FuncName(const UInt32 *labels, UInt32 index); - void AddParam_Func(const UInt32 *labels, UInt32 index); - void Add_LabelName(UInt32 index); - - void Add_Color2(UInt32 v); - void Add_ColorParam(UInt32 v); - void Add_Color(UInt32 index); - - void Add_ButtonID(UInt32 buttonID); - - void Add_ShowWindow_Cmd(UInt32 cmd); - void Add_TypeFromList(const char * const *table, unsigned tableSize, UInt32 type); - void Add_ExecFlags(UInt32 flagsType); - void Add_SectOp(UInt32 opType); - - void Add_Var(UInt32 index); - void AddParam_Var(UInt32 value); - void AddParam_UInt(UInt32 value); - - void Add_GotoVar(UInt32 param); - void Add_GotoVar1(UInt32 param); - void Add_GotoVars2(const UInt32 *params); - - - - bool PrintSectionBegin(const CSection §, unsigned index); - void PrintSectionEnd(); - - void GetNsisString(AString &res, const Byte *s); - void GetNsisString_Unicode(AString &res, const Byte *s); - UInt32 GetNumUsedVars() const; - void ReadString2(AString &s, UInt32 pos); - - void MessageBox_MB_Part(UInt32 param); - void AddParam(UInt32 pos); - void AddOptionalParam(UInt32 pos); - void AddParams(const UInt32 *params, unsigned num); - void AddPageOption1(UInt32 param, const char *name); - void AddPageOption(const UInt32 *params, unsigned num, const char *name); - void AddOptionalParams(const UInt32 *params, unsigned num); - void AddRegRoot(UInt32 value); - - - void ClearLangComment(); - void Separator(); - void Space(); - void Tab(); - void Tab(bool commented); - void BigSpaceComment(); - void SmallSpaceComment(); - void AddCommentAndString(const char *s); - void AddError(const char *s); - void AddErrorLF(const char *s); - void CommentOpen(); - void CommentClose(); - void AddLF(); - void AddQuotes(); - void TabString(const char *s); - void AddStringLF(const char *s); - void NewLine(); - void PrintNumComment(const char *name, UInt32 value); - void Add_QuStr(const AString &s); - void SpaceQuStr(const AString &s); - bool CompareCommands(const Byte *rawCmds, const Byte *sequence, size_t numCommands); - - #endif - - #ifdef NSIS_SCRIPT - unsigned GetNumSupportedCommands() const; - #endif - - UInt32 GetCmd(UInt32 a); - void FindBadCmd(const CBlockHeader &bh, const Byte *); - void DetectNsisType(const CBlockHeader &bh, const Byte *); - - HRESULT ReadEntries(const CBlockHeader &bh); - HRESULT SortItems(); - HRESULT Parse(); - HRESULT Open2(const Byte *data, size_t size); - void Clear2(); - - void GetVar2(AString &res, UInt32 index); - void GetVar(AString &res, UInt32 index); - Int32 GetVarIndex(UInt32 strPos) const; - Int32 GetVarIndex(UInt32 strPos, UInt32 &resOffset) const; - Int32 GetVarIndexFinished(UInt32 strPos, Byte endChar, UInt32 &resOffset) const; - bool IsVarStr(UInt32 strPos, UInt32 varIndex) const; - bool IsAbsolutePathVar(UInt32 strPos) const; - void SetItemName(CItem &item, UInt32 strPos); - -public: - HRESULT Open(IInStream *inStream, const UInt64 *maxCheckStartPosition); - AString GetFormatDescription() const; - HRESULT InitDecoder() - { - bool useFilter; - return Decoder.Init(_stream, useFilter); - } - - HRESULT SeekTo_DataStreamOffset() - { - return _stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL); - } - - HRESULT SeekToNonSolidItem(unsigned index) - { - return _stream->Seek(GetPosOfNonSolidItem(index), STREAM_SEEK_SET, NULL); - } - - void Clear(); - - bool IsDirectString_Equal(UInt32 offset, const char *s) const; - /* - UInt64 GetDataPos(unsigned index) - { - const CItem &item = Items[index]; - return GetOffset() + FirstHeader.HeaderSize + item.Pos; - } - */ - - UInt64 GetPosOfSolidItem(unsigned index) const - { - const CItem &item = Items[index]; - return 4 + (UInt64)FirstHeader.HeaderSize + item.Pos; - } - - UInt64 GetPosOfNonSolidItem(unsigned index) const - { - const CItem &item = Items[index]; - return DataStreamOffset + _nonSolidStartOffset + 4 + item.Pos; - } - - void Release() - { - Decoder.Release(); - } - - bool IsTruncated() const { return (_fileSize - StartOffset < FirstHeader.ArcSize); } - - UString GetReducedName(unsigned index) const - { - const CItem &item = Items[index]; - - UString s; - if (item.Prefix >= 0) - { - if (IsUnicode) - s = UPrefixes[item.Prefix]; - else - s = MultiByteToUnicodeString(APrefixes[item.Prefix]); - if (s.Len() > 0) - if (s.Back() != L'\\') - s += L'\\'; - } - - if (IsUnicode) - { - s += item.NameU; - if (item.NameU.IsEmpty()) - s += L"file"; - } - else - { - s += MultiByteToUnicodeString(item.NameA); - if (item.NameA.IsEmpty()) - s += L"file"; - } - - const char *kRemoveStr = "$INSTDIR\\"; - if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr)) - { - s.Delete(0, MyStringLen(kRemoveStr)); - if (s[0] == L'\\') - s.DeleteFrontal(1); - } - if (item.IsUninstaller && ExeStub.Size() == 0) - s += L".nsis"; - return s; - } - - UString ConvertToUnicode(const AString &s) const; - - CInArchive() - #ifdef NSIS_SCRIPT - : Script(kScriptSizeLimit) - #endif - {} -}; - -}} - -#endif +// NsisIn.h + +#ifndef ZIP7_INC_ARCHIVE_NSIS_IN_H +#define ZIP7_INC_ARCHIVE_NSIS_IN_H + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/DynLimBuf.h" +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" + +#include "../../Common/StreamUtils.h" + +#include "NsisDecode.h" + +/* If NSIS_SCRIPT is defined, it will decompile NSIS script to [NSIS].nsi file. + The code is much larger in that case. */ + +// #define NSIS_SCRIPT + +namespace NArchive { +namespace NNsis { + +const size_t kScriptSizeLimit = 1 << 27; + +const unsigned kSignatureSize = 16; +extern const Byte kSignature[kSignatureSize]; +#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 'N', 'u', 'l', 'l', 's', 'o', 'f', 't', 'I', 'n', 's', 't' } + +const UInt32 kFlagsMask = 0xF; +namespace NFlags +{ + const UInt32 kUninstall = 1; + const UInt32 kSilent = 2; + const UInt32 kNoCrc = 4; + const UInt32 kForceCrc = 8; + // NSISBI fork flags: + const UInt32 k_BI_LongOffset = 16; + const UInt32 k_BI_ExternalFileSupport = 32; + const UInt32 k_BI_ExternalFile = 64; + const UInt32 k_BI_IsStubInstaller = 128; +} + +struct CFirstHeader +{ + UInt32 Flags; + UInt32 HeaderSize; + UInt32 ArcSize; + + bool ThereIsCrc() const + { + return + (Flags & NFlags::kForceCrc) != 0 || + (Flags & NFlags::kNoCrc) == 0; + } + + UInt32 GetDataSize() const { return ArcSize - (ThereIsCrc() ? 4 : 0); } +}; + + +struct CBlockHeader +{ + UInt32 Offset; + UInt32 Num; + + void Parse(const Byte *p, unsigned bhoSize); +}; + +struct CItem +{ + bool IsEmptyFile; + bool IsCompressed; + bool Size_Defined; + bool CompressedSize_Defined; + bool EstimatedSize_Defined; + bool Attrib_Defined; + bool IsUninstaller; + // bool UseFilter; + + UInt32 Attrib; + UInt32 Pos; // = 0, if (IsEmptyFile == true) + UInt32 Size; + UInt32 CompressedSize; + UInt32 EstimatedSize; + UInt32 DictionarySize; + UInt32 PatchSize; // for Uninstaller.exe + int Prefix; // - 1 means no prefix + + FILETIME MTime; + AString NameA; + UString NameU; + + bool Is_PatchedUninstaller() const { return PatchSize != 0; } + + CItem(): + IsEmptyFile(false), + IsCompressed(true), + Size_Defined(false), + CompressedSize_Defined(false), + EstimatedSize_Defined(false), + Attrib_Defined(false), + IsUninstaller(false), + // UseFilter(false), + Attrib(0), + Pos(0), + Size(0), + CompressedSize(0), + EstimatedSize(0), + DictionarySize(1), + PatchSize(0), + Prefix(-1) + { + MTime.dwLowDateTime = 0; + MTime.dwHighDateTime = 0; + } + + /* + bool IsINSTDIR() const + { + return (PrefixA.Len() >= 3 || PrefixU.Len() >= 3); + } + */ +}; + +enum ENsisType +{ + k_NsisType_Nsis2, + k_NsisType_Nsis3, + k_NsisType_Park1, // Park 2.46.1- + k_NsisType_Park2, // Park 2.46.2 : GetFontVersion + k_NsisType_Park3 // Park 2.46.3+ : GetFontName +}; + +#ifdef NSIS_SCRIPT + +struct CSection +{ + UInt32 InstallTypes; // bits set for each of the different install_types, if any. + UInt32 Flags; // SF_* - defined above + UInt32 StartCmdIndex; // code; + UInt32 NumCommands; // code_size; + UInt32 SizeKB; + UInt32 Name; + + void Parse(const Byte *data); +}; + +struct CLicenseFile +{ + UInt32 Offset; + UInt32 Size; + AString Name; + CByteBuffer Text; +}; + +#endif + +class CInArchive +{ +public: + #ifdef NSIS_SCRIPT + CDynLimBuf Script; + #endif + CByteBuffer _data; + CObjectVector Items; + bool IsUnicode; + bool Is64Bit; +private: + UInt32 _stringsPos; // relative to _data + UInt32 NumStringChars; + size_t _size; // it's Header Size + + AString Raw_AString; + UString Raw_UString; + + ENsisType NsisType; + bool IsNsis200; // NSIS 2.03 and before + bool IsNsis225; // NSIS 2.25 and before + bool LogCmdIsEnabled; + int BadCmd; // -1: no bad command; in another cases lowest bad command id + + bool IsPark() const { return NsisType >= k_NsisType_Park1; } + bool IsNsis3_OrHigher() const { return NsisType == k_NsisType_Nsis3; } + + UInt64 _fileSize; + + bool _headerIsCompressed; + UInt32 _nonSolidStartOffset; + + #ifdef NSIS_SCRIPT + + CByteBuffer strUsed; + + CBlockHeader bhPages; + CBlockHeader bhSections; + CBlockHeader bhCtlColors; + CBlockHeader bhData; + UInt32 AfterHeaderSize; + CByteBuffer _afterHeader; + + UInt32 SectionSize; + const Byte *_mainLang; + UInt32 _numLangStrings; + AString LangComment; + CRecordVector langStrIDs; + UInt32 numOnFunc; + UInt32 onFuncOffset; + // CRecordVector OnFuncs; + unsigned _numRootLicenses; + CRecordVector noParseStringIndexes; + AString _tempString_for_GetVar; + AString _tempString_for_AddFuncName; + AString _tempString; + + #endif + + +public: + CMyComPtr _stream; // it's limited stream that contains only NSIS archive + UInt64 StartOffset; // offset in original stream. + UInt64 DataStreamOffset; // = sizeof(FirstHeader) = offset of Header in _stream + + bool IsArc; + + CDecoder Decoder; + CByteBuffer ExeStub; + CFirstHeader FirstHeader; + NMethodType::EEnum Method; + UInt32 DictionarySize; + bool IsSolid; + bool UseFilter; + bool FilterFlag; + + bool IsInstaller; + AString Name; + AString BrandingText; + UStringVector UPrefixes; + AStringVector APrefixes; + + #ifdef NSIS_SCRIPT + CObjectVector LicenseFiles; + #endif + +private: + void GetShellString(AString &s, unsigned index1, unsigned index2); + void GetNsisString_Raw(const Byte *s); + void GetNsisString_Unicode_Raw(const Byte *s); + void ReadString2_Raw(UInt32 pos); + bool IsGoodString(UInt32 param) const; + bool AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const; + + void Add_LangStr(AString &res, UInt32 id); + + #ifdef NSIS_SCRIPT + + void Add_UInt(UInt32 v); + void AddLicense(UInt32 param, Int32 langID); + + void Add_LangStr_Simple(UInt32 id); + void Add_FuncName(const UInt32 *labels, UInt32 index); + void AddParam_Func(const UInt32 *labels, UInt32 index); + void Add_LabelName(UInt32 index); + + void Add_Color2(UInt32 v); + void Add_ColorParam(UInt32 v); + void Add_Color(UInt32 index); + + void Add_ButtonID(UInt32 buttonID); + + void Add_ShowWindow_Cmd(UInt32 cmd); + void Add_TypeFromList(const char * const *table, unsigned tableSize, UInt32 type); + void Add_ExecFlags(UInt32 flagsType); + void Add_SectOp(UInt32 opType); + + void Add_Var(UInt32 index); + void AddParam_Var(UInt32 value); + void AddParam_UInt(UInt32 value); + + void Add_GotoVar(UInt32 param); + void Add_GotoVar1(UInt32 param); + void Add_GotoVars2(const UInt32 *params); + + + + bool PrintSectionBegin(const CSection §, unsigned index); + void PrintSectionEnd(); + + void GetNsisString(AString &res, const Byte *s); + void GetNsisString_Unicode(AString &res, const Byte *s); + UInt32 GetNumUsedVars() const; + void ReadString2(AString &s, UInt32 pos); + + void MessageBox_MB_Part(UInt32 param); + void AddParam(UInt32 pos); + void AddOptionalParam(UInt32 pos); + void AddParams(const UInt32 *params, unsigned num); + void AddPageOption1(UInt32 param, const char *name); + void AddPageOption(const UInt32 *params, unsigned num, const char *name); + void AddOptionalParams(const UInt32 *params, unsigned num); + void AddRegRoot(UInt32 value); + + + void ClearLangComment(); + void Separator(); + void Space(); + void Tab(); + void Tab(bool commented); + void BigSpaceComment(); + void SmallSpaceComment(); + void AddCommentAndString(const char *s); + void AddError(const char *s); + void AddErrorLF(const char *s); + void CommentOpen(); + void CommentClose(); + void AddLF(); + void AddQuotes(); + void TabString(const char *s); + void AddStringLF(const char *s); + void NewLine(); + void PrintNumComment(const char *name, UInt32 value); + void Add_QuStr(const AString &s); + void SpaceQuStr(const AString &s); + bool CompareCommands(const Byte *rawCmds, const Byte *sequence, size_t numCommands); + + #endif + + #ifdef NSIS_SCRIPT + unsigned GetNumSupportedCommands() const; + #endif + + UInt32 GetCmd(UInt32 a); + void FindBadCmd(const CBlockHeader &bh, const Byte *); + void DetectNsisType(const CBlockHeader &bh, const Byte *); + + HRESULT ReadEntries(const CBlockHeader &bh); + HRESULT SortItems(); + HRESULT Parse(); + HRESULT Open2(const Byte *data, size_t size); + void Clear2(); + + void GetVar2(AString &res, UInt32 index); + void GetVar(AString &res, UInt32 index); + Int32 GetVarIndex(UInt32 strPos) const; + Int32 GetVarIndex(UInt32 strPos, UInt32 &resOffset) const; + Int32 GetVarIndexFinished(UInt32 strPos, Byte endChar, UInt32 &resOffset) const; + bool IsVarStr(UInt32 strPos, UInt32 varIndex) const; + bool IsAbsolutePathVar(UInt32 strPos) const; + void SetItemName(CItem &item, UInt32 strPos); + +public: + HRESULT Open(IInStream *inStream, const UInt64 *maxCheckStartPosition); + AString GetFormatDescription() const; + HRESULT InitDecoder() + { + bool useFilter; + return Decoder.Init(_stream, useFilter); + } + + HRESULT SeekTo(UInt64 pos) + { + return InStream_SeekSet(_stream, pos); + } + + HRESULT SeekTo_DataStreamOffset() + { + return SeekTo(DataStreamOffset); + } + + HRESULT SeekToNonSolidItem(unsigned index) + { + return SeekTo(GetPosOfNonSolidItem(index)); + } + + void Clear(); + + bool IsDirectString_Equal(UInt32 offset, const char *s) const; + /* + UInt64 GetDataPos(unsigned index) + { + const CItem &item = Items[index]; + return GetOffset() + FirstHeader.HeaderSize + item.Pos; + } + */ + + UInt64 GetPosOfSolidItem(unsigned index) const + { + const CItem &item = Items[index]; + return 4 + (UInt64)FirstHeader.HeaderSize + item.Pos; + } + + UInt64 GetPosOfNonSolidItem(unsigned index) const + { + const CItem &item = Items[index]; + return DataStreamOffset + _nonSolidStartOffset + 4 + item.Pos; + } + + void Release() + { + Decoder.Release(); + } + + bool IsTruncated() const { return (_fileSize - StartOffset < FirstHeader.ArcSize); } + + UString GetReducedName(unsigned index) const + { + const CItem &item = Items[index]; + + UString s; + if (item.Prefix >= 0) + { + if (IsUnicode) + s = UPrefixes[item.Prefix]; + else + s = MultiByteToUnicodeString(APrefixes[item.Prefix]); + if (s.Len() > 0) + if (s.Back() != L'\\') + s.Add_Char('\\'); + } + + if (IsUnicode) + { + s += item.NameU; + if (item.NameU.IsEmpty()) + s += "file"; + } + else + { + s += MultiByteToUnicodeString(item.NameA); + if (item.NameA.IsEmpty()) + s += "file"; + } + + const char * const kRemoveStr = "$INSTDIR\\"; + if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr)) + { + s.Delete(0, MyStringLen(kRemoveStr)); + if (s[0] == L'\\') + s.DeleteFrontal(1); + } + if (item.Is_PatchedUninstaller() && ExeStub.Size() == 0) + s += ".nsis"; + return s; + } + + UString ConvertToUnicode(const AString &s) const; + + CInArchive() + #ifdef NSIS_SCRIPT + : Script(kScriptSizeLimit) + #endif + {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/NsisRegister.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/NsisRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,20 +1,20 @@ -// NsisRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "NsisHandler.h" - -namespace NArchive { -namespace NNsis { - -REGISTER_ARC_I( - "Nsis", "nsis", 0, 0x9, - kSignature, - 4, - NArcInfoFlags::kFindSignature | - NArcInfoFlags::kUseGlobalOffset, - NULL) - -}} +// NsisRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "NsisHandler.h" + +namespace NArchive { +namespace NNsis { + +REGISTER_ARC_I( + "Nsis", "nsis", NULL, 0x9, + kSignature, + 4, + NArcInfoFlags::kFindSignature | + NArcInfoFlags::kUseGlobalOffset, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Nsis/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Nsis/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Nsis/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/NtfsHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/NtfsHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/NtfsHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/NtfsHandler.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -1,2754 +1,2895 @@ -// NtfsHandler.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO -// #define SHOW_DEBUG_INFO2 - -#if defined(SHOW_DEBUG_INFO) || defined(SHOW_DEBUG_INFO2) -#include -#endif - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/MethodProps.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#include "Common/DummyOutStream.h" - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#define PRF_UTF16(x) PRF(printf("%S", x)) -#else -#define PRF(x) -#define PRF_UTF16(x) -#endif - -#ifdef SHOW_DEBUG_INFO2 -#define PRF2(x) x -#else -#define PRF2(x) -#endif - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -#define G16(p, dest) dest = Get16(p); -#define G32(p, dest) dest = Get32(p); -#define G64(p, dest) dest = Get64(p); - -using namespace NWindows; - -namespace NArchive { -namespace Ntfs { - -static const wchar_t *kVirtualFolder_System = L"[SYSTEM]"; -static const wchar_t *kVirtualFolder_Lost_Normal = L"[LOST]"; -static const wchar_t *kVirtualFolder_Lost_Deleted = L"[UNKNOWN]"; - -static const unsigned kNumSysRecs = 16; - -static const unsigned kRecIndex_Volume = 3; -static const unsigned kRecIndex_RootDir = 5; -static const unsigned kRecIndex_BadClus = 8; -static const unsigned kRecIndex_Security = 9; - -struct CHeader -{ - unsigned SectorSizeLog; - unsigned ClusterSizeLog; - // Byte MediaType; - UInt32 NumHiddenSectors; - UInt64 NumSectors; - UInt64 NumClusters; - UInt64 MftCluster; - UInt64 SerialNumber; - UInt16 SectorsPerTrack; - UInt16 NumHeads; - - UInt64 GetPhySize_Clusters() const { return NumClusters << ClusterSizeLog; } - UInt64 GetPhySize_Max() const { return (NumSectors + 1) << SectorSizeLog; } - UInt32 ClusterSize() const { return (UInt32)1 << ClusterSizeLog; } - bool Parse(const Byte *p); -}; - -static int GetLog(UInt32 num) -{ - for (int i = 0; i < 31; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - -bool CHeader::Parse(const Byte *p) -{ - if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) - return false; - - // int codeOffset = 0; - 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; - } - unsigned sectorsPerClusterLog; - - if (memcmp(p + 3, "NTFS ", 8) != 0) - return false; - { - int t = GetLog(Get16(p + 11)); - if (t < 9 || t > 12) - return false; - SectorSizeLog = t; - t = GetLog(p[13]); - if (t < 0) - return false; - sectorsPerClusterLog = t; - ClusterSizeLog = SectorSizeLog + sectorsPerClusterLog; - if (ClusterSizeLog > 30) - return false; - } - - for (int i = 14; i < 21; i++) - if (p[i] != 0) - return false; - - if (p[21] != 0xF8) // MediaType = Fixed_Disk - return false; - if (Get16(p + 22) != 0) // NumFatSectors - return false; - G16(p + 24, SectorsPerTrack); // 63 usually - G16(p + 26, NumHeads); // 255 - G32(p + 28, NumHiddenSectors); // 63 (XP) / 2048 (Vista and win7) / (0 on media that are not partitioned ?) - if (Get32(p + 32) != 0) // NumSectors32 - return false; - - // DriveNumber = p[0x24]; - if (p[0x25] != 0) // CurrentHead - return false; - /* - NTFS-HDD: p[0x26] = 0x80 - NTFS-FLASH: p[0x26] = 0 - */ - if (p[0x26] != 0x80 && p[0x26] != 0) // ExtendedBootSig - return false; - if (p[0x27] != 0) // reserved - return false; - - NumSectors = Get64(p + 0x28); - if (NumSectors >= ((UInt64)1 << (62 - SectorSizeLog))) - return false; - - NumClusters = NumSectors >> sectorsPerClusterLog; - - G64(p + 0x30, MftCluster); - // G64(p + 0x38, Mft2Cluster); - G64(p + 0x48, SerialNumber); - UInt32 numClustersInMftRec; - UInt32 numClustersInIndexBlock; - G32(p + 0x40, numClustersInMftRec); // -10 means 2 ^10 = 1024 bytes. - G32(p + 0x44, numClustersInIndexBlock); - return (numClustersInMftRec < 256 && numClustersInIndexBlock < 256); -} - -struct CMftRef -{ - UInt64 Val; - - UInt64 GetIndex() const { return Val & (((UInt64)1 << 48) - 1); } - UInt16 GetNumber() const { return (UInt16)(Val >> 48); } - bool IsBaseItself() const { return Val == 0; } -}; - -#define ATNAME(n) ATTR_TYPE_ ## n -#define DEF_ATTR_TYPE(v, n) ATNAME(n) = v - -enum -{ - DEF_ATTR_TYPE(0x00, UNUSED), - DEF_ATTR_TYPE(0x10, STANDARD_INFO), - DEF_ATTR_TYPE(0x20, ATTRIBUTE_LIST), - DEF_ATTR_TYPE(0x30, FILE_NAME), - DEF_ATTR_TYPE(0x40, OBJECT_ID), - DEF_ATTR_TYPE(0x50, SECURITY_DESCRIPTOR), - DEF_ATTR_TYPE(0x60, VOLUME_NAME), - DEF_ATTR_TYPE(0x70, VOLUME_INFO), - DEF_ATTR_TYPE(0x80, DATA), - DEF_ATTR_TYPE(0x90, INDEX_ROOT), - DEF_ATTR_TYPE(0xA0, INDEX_ALLOCATION), - DEF_ATTR_TYPE(0xB0, BITMAP), - DEF_ATTR_TYPE(0xC0, REPARSE_POINT), - DEF_ATTR_TYPE(0xD0, EA_INFO), - DEF_ATTR_TYPE(0xE0, EA), - DEF_ATTR_TYPE(0xF0, PROPERTY_SET), - DEF_ATTR_TYPE(0x100, LOGGED_UTILITY_STREAM), - DEF_ATTR_TYPE(0x1000, FIRST_USER_DEFINED_ATTRIBUTE) -}; - - -/* WinXP-64: - Probably only one short name (dos name) per record is allowed. - There are no short names for hard links. - The pair (Win32,Dos) can be in any order. - Posix name can be after or before Win32 name -*/ - -static const Byte kFileNameType_Posix = 0; // for hard links -static const Byte kFileNameType_Win32 = 1; // after Dos name -static const Byte kFileNameType_Dos = 2; // short name -static const Byte kFileNameType_Win32Dos = 3; // short and full name are same - -struct CFileNameAttr -{ - CMftRef ParentDirRef; - - // Probably these timestamps don't contain some useful timestamps. So we don't use them - // UInt64 CTime; - // UInt64 MTime; - // UInt64 ThisRecMTime; // xp-64: the time of previous name change (not last name change. why?) - // UInt64 ATime; - // UInt64 AllocatedSize; - // UInt64 DataSize; - // UInt16 PackedEaSize; - UString2 Name; - UInt32 Attrib; - Byte NameType; - - bool IsDos() const { return NameType == kFileNameType_Dos; } - bool IsWin32() const { return (NameType == kFileNameType_Win32); } - - bool Parse(const Byte *p, unsigned size); -}; - -static void GetString(const Byte *p, unsigned len, UString2 &res) -{ - if (len == 0 && res.IsEmpty()) - return; - wchar_t *s = res.GetBuf(len); - unsigned i; - for (i = 0; i < len; i++) - { - wchar_t c = Get16(p + i * 2); - if (c == 0) - break; - s[i] = c; - } - s[i] = 0; - res.ReleaseBuf_SetLen(i); -} - -bool CFileNameAttr::Parse(const Byte *p, unsigned size) -{ - if (size < 0x42) - return false; - G64(p + 0x00, ParentDirRef.Val); - // G64(p + 0x08, CTime); - // G64(p + 0x10, MTime); - // G64(p + 0x18, ThisRecMTime); - // G64(p + 0x20, ATime); - // G64(p + 0x28, AllocatedSize); - // G64(p + 0x30, DataSize); - G32(p + 0x38, Attrib); - // G16(p + 0x3C, PackedEaSize); - NameType = p[0x41]; - unsigned len = p[0x40]; - if (0x42 + len > size) - return false; - if (len != 0) - GetString(p + 0x42, len, Name); - return true; -} - -struct CSiAttr -{ - UInt64 CTime; - UInt64 MTime; - // UInt64 ThisRecMTime; - UInt64 ATime; - UInt32 Attrib; - - /* - UInt32 MaxVersions; - UInt32 Version; - UInt32 ClassId; - UInt32 OwnerId; - */ - UInt32 SecurityId; // SecurityId = 0 is possible ? - // UInt64 QuotaCharged; - - bool Parse(const Byte *p, unsigned size); -}; - -bool CSiAttr::Parse(const Byte *p, unsigned size) -{ - if (size < 0x24) - return false; - G64(p + 0x00, CTime); - G64(p + 0x08, MTime); - // G64(p + 0x10, ThisRecMTime); - G64(p + 0x18, ATime); - G32(p + 0x20, Attrib); - SecurityId = 0; - if (size >= 0x38) - G32(p + 0x34, SecurityId); - return true; -} - -static const UInt64 kEmptyExtent = (UInt64)(Int64)-1; - -struct CExtent -{ - UInt64 Virt; - UInt64 Phy; - - bool IsEmpty() const { return Phy == kEmptyExtent; } -}; - -struct CVolInfo -{ - Byte MajorVer; - Byte MinorVer; - // UInt16 Flags; - - bool Parse(const Byte *p, unsigned size); -}; - -bool CVolInfo::Parse(const Byte *p, unsigned size) -{ - if (size < 12) - return false; - MajorVer = p[8]; - MinorVer = p[9]; - // Flags = Get16(p + 10); - return true; -} - -struct CAttr -{ - UInt32 Type; - // UInt32 Len; - UString2 Name; - // UInt16 Flags; - // UInt16 Instance; - CByteBuffer Data; - Byte NonResident; - - // Non-Resident - Byte CompressionUnit; - UInt64 LowVcn; - UInt64 HighVcn; - UInt64 AllocatedSize; - UInt64 Size; - UInt64 PackSize; - UInt64 InitializedSize; - - // Resident - // UInt16 ResidentFlags; - - bool IsCompressionUnitSupported() const { return CompressionUnit == 0 || CompressionUnit == 4; } - - UInt32 Parse(const Byte *p, unsigned size); - bool ParseFileName(CFileNameAttr &a) const { return a.Parse(Data, (unsigned)Data.Size()); } - bool ParseSi(CSiAttr &a) const { return a.Parse(Data, (unsigned)Data.Size()); } - bool ParseVolInfo(CVolInfo &a) const { return a.Parse(Data, (unsigned)Data.Size()); } - bool ParseExtents(CRecordVector &extents, UInt64 numClustersMax, unsigned compressionUnit) const; - UInt64 GetSize() const { return NonResident ? Size : Data.Size(); } - UInt64 GetPackSize() const - { - if (!NonResident) - return Data.Size(); - if (CompressionUnit != 0) - return PackSize; - return AllocatedSize; - } -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareAttr(void *const *elem1, void *const *elem2, void *) -{ - const CAttr &a1 = *(*((const CAttr **)elem1)); - const CAttr &a2 = *(*((const CAttr **)elem2)); - RINOZ(MyCompare(a1.Type, a2.Type)); - if (a1.Name.IsEmpty()) - { - if (!a2.Name.IsEmpty()) - return -1; - } - else if (a2.Name.IsEmpty()) - return 1; - else - { - RINOZ(wcscmp(a1.Name.GetRawPtr(), a2.Name.GetRawPtr())); - } - return MyCompare(a1.LowVcn, a2.LowVcn); -} - -UInt32 CAttr::Parse(const Byte *p, unsigned size) -{ - if (size < 4) - return 0; - G32(p, Type); - if (Type == 0xFFFFFFFF) - return 8; // required size is 4, but attributes are 8 bytes aligned. So we return 8 - if (size < 0x18) - return 0; - PRF(printf(" T=%2X", Type)); - - UInt32 len = Get32(p + 0x04); - PRF(printf(" L=%3d", len)); - if (len > size) - return 0; - if ((len & 7) != 0) - return 0; - NonResident = p[0x08]; - { - unsigned nameLen = p[9]; - UInt32 nameOffset = Get16(p + 0x0A); - if (nameLen != 0) - { - if (nameOffset + nameLen * 2 > len) - return 0; - GetString(p + nameOffset, nameLen, Name); - PRF(printf(" N=")); - PRF_UTF16(Name); - } - } - - // G16(p + 0x0C, Flags); - // G16(p + 0x0E, Instance); - // PRF(printf(" F=%4X", Flags)); - // PRF(printf(" Inst=%d", Instance)); - - UInt32 dataSize; - UInt32 offs; - if (NonResident) - { - if (len < 0x40) - return 0; - PRF(printf(" NR")); - G64(p + 0x10, LowVcn); - G64(p + 0x18, HighVcn); - G64(p + 0x28, AllocatedSize); - G64(p + 0x30, Size); - G64(p + 0x38, InitializedSize); - G16(p + 0x20, offs); - CompressionUnit = p[0x22]; - - PackSize = Size; - if (CompressionUnit != 0) - { - if (len < 0x48) - return 0; - G64(p + 0x40, PackSize); - PRF(printf(" PS=%I64x", PackSize)); - } - - // PRF(printf("\n")); - PRF(printf(" ASize=%4I64d", AllocatedSize)); - PRF(printf(" Size=%I64d", Size)); - PRF(printf(" IS=%I64d", InitializedSize)); - PRF(printf(" Low=%I64d", LowVcn)); - PRF(printf(" High=%I64d", HighVcn)); - PRF(printf(" CU=%d", (unsigned)CompressionUnit)); - dataSize = len - offs; - } - else - { - if (len < 0x18) - return 0; - PRF(printf(" RES")); - dataSize = Get32(p + 0x10); - PRF(printf(" dataSize=%3d", dataSize)); - offs = Get16(p + 0x14); - // G16(p + 0x16, ResidentFlags); - // PRF(printf(" ResFlags=%4X", ResidentFlags)); - } - if (offs > len || dataSize > len || len - dataSize < offs) - return 0; - Data.CopyFrom(p + offs, dataSize); - #ifdef SHOW_DEBUG_INFO - PRF(printf(" : ")); - for (unsigned i = 0; i < Data.Size(); i++) - { - PRF(printf(" %02X", (unsigned)Data[i])); - } - #endif - return len; -} - -bool CAttr::ParseExtents(CRecordVector &extents, UInt64 numClustersMax, unsigned compressionUnit) const -{ - const Byte *p = Data; - unsigned size = (unsigned)Data.Size(); - UInt64 vcn = LowVcn; - UInt64 lcn = 0; - UInt64 highVcn1 = HighVcn + 1; - if (LowVcn != extents.Back().Virt || highVcn1 > (UInt64)1 << 63) - return false; - - extents.DeleteBack(); - - PRF2(printf("\n# ParseExtents # LowVcn = %4I64X # HighVcn = %4I64X", LowVcn, HighVcn)); - - while (size > 0) - { - Byte b = *p++; - size--; - if (b == 0) - break; - UInt32 num = b & 0xF; - if (num == 0 || num > 8 || num > size) - return false; - - UInt64 vSize = 0; - { - unsigned i = num; - do vSize = (vSize << 8) | p[--i]; while (i); - } - if (vSize == 0) - return false; - p += num; - size -= num; - if ((highVcn1 - vcn) < vSize) - return false; - - num = (b >> 4) & 0xF; - if (num > 8 || num > size) - return false; - CExtent e; - e.Virt = vcn; - if (num == 0) - { - if (compressionUnit == 0) - return false; - e.Phy = kEmptyExtent; - } - else - { - Int64 v = (signed char)p[num - 1]; - { - for (unsigned i = num - 1; i != 0;) - v = (v << 8) | p[--i]; - } - p += num; - size -= num; - lcn += v; - if (lcn > numClustersMax) - return false; - e.Phy = lcn; - } - extents.Add(e); - vcn += vSize; - } - CExtent e; - e.Phy = kEmptyExtent; - e.Virt = vcn; - extents.Add(e); - return (highVcn1 == vcn); -} - -static const UInt64 kEmptyTag = (UInt64)(Int64)-1; - -static const unsigned kNumCacheChunksLog = 1; -static const size_t kNumCacheChunks = (1 << kNumCacheChunksLog); - -class CInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - UInt64 _physPos; - UInt64 _curRem; - bool _sparseMode; - - - unsigned _chunkSizeLog; - UInt64 _tags[kNumCacheChunks]; - CByteBuffer _inBuf; - CByteBuffer _outBuf; -public: - UInt64 Size; - UInt64 InitializedSize; - unsigned BlockSizeLog; - unsigned CompressionUnit; - CRecordVector Extents; - bool InUse; - CMyComPtr Stream; - - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } - - UInt32 GetCuSize() const { return (UInt32)1 << (BlockSizeLog + CompressionUnit); } - HRESULT InitAndSeek(unsigned compressionUnit) - { - CompressionUnit = compressionUnit; - _chunkSizeLog = BlockSizeLog + CompressionUnit; - if (compressionUnit != 0) - { - UInt32 cuSize = GetCuSize(); - _inBuf.Alloc(cuSize); - _outBuf.Alloc(kNumCacheChunks << _chunkSizeLog); - } - for (size_t i = 0; i < kNumCacheChunks; i++) - _tags[i] = kEmptyTag; - - _sparseMode = false; - _curRem = 0; - _virtPos = 0; - _physPos = 0; - const CExtent &e = Extents[0]; - if (!e.IsEmpty()) - _physPos = e.Phy << BlockSizeLog; - return SeekToPhys(); - } - - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte *src, size_t srcLen) -{ - size_t destSize = 0; - while (destSize < destLen) - { - if (srcLen < 2 || (destSize & 0xFFF) != 0) - break; - UInt32 comprSize; - { - const UInt32 v = Get16(src); - if (v == 0) - break; - src += 2; - srcLen -= 2; - comprSize = (v & 0xFFF) + 1; - if (comprSize > srcLen) - break; - srcLen -= comprSize; - if ((v & 0x8000) == 0) - { - if (comprSize != (1 << 12)) - break; - memcpy(dest + destSize, src, comprSize); - src += comprSize; - destSize += comprSize; - continue; - } - } - { - if (destSize + (1 << 12) > outBufLim || (src[0] & 1) != 0) - return 0; - unsigned numDistBits = 4; - UInt32 sbOffset = 0; - UInt32 pos = 0; - - do - { - comprSize--; - for (UInt32 mask = src[pos++] | 0x100; mask > 1 && comprSize > 0; mask >>= 1) - { - if ((mask & 1) == 0) - { - if (sbOffset >= (1 << 12)) - return 0; - dest[destSize++] = src[pos++]; - sbOffset++; - comprSize--; - } - else - { - if (comprSize < 2) - return 0; - const UInt32 v = Get16(src + pos); - pos += 2; - comprSize -= 2; - - while (((sbOffset - 1) >> numDistBits) != 0) - numDistBits++; - - UInt32 len = (v & (0xFFFF >> numDistBits)) + 3; - if (sbOffset + len > (1 << 12)) - return 0; - UInt32 dist = (v >> (16 - numDistBits)); - if (dist >= sbOffset) - return 0; - Int32 offs = -1 - dist; - Byte *p = dest + destSize; - for (UInt32 t = 0; t < len; t++) - p[t] = p[t + offs]; - destSize += len; - sbOffset += len; - } - } - } - while (comprSize > 0); - src += pos; - } - } - return destSize; -} - -STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Size) - return (Size == _virtPos) ? S_OK: E_FAIL; - if (size == 0) - return S_OK; - { - const UInt64 rem = Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - - if (_virtPos >= InitializedSize) - { - memset((Byte *)data, 0, size); - _virtPos += size; - *processedSize = size; - return S_OK; - } - - { - const UInt64 rem = InitializedSize - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - - while (_curRem == 0) - { - UInt64 cacheTag = _virtPos >> _chunkSizeLog; - UInt32 cacheIndex = (UInt32)cacheTag & (kNumCacheChunks - 1); - if (_tags[cacheIndex] == cacheTag) - { - UInt32 chunkSize = (UInt32)1 << _chunkSizeLog; - UInt32 offset = (UInt32)_virtPos & (chunkSize - 1); - UInt32 cur = MyMin(chunkSize - offset, size); - memcpy(data, _outBuf + (cacheIndex << _chunkSizeLog) + offset, cur); - *processedSize = cur; - _virtPos += cur; - return S_OK; - } - - PRF2(printf("\nVirtPos = %6d", _virtPos)); - - UInt32 comprUnitSize = (UInt32)1 << CompressionUnit; - UInt64 virtBlock = _virtPos >> BlockSizeLog; - UInt64 virtBlock2 = virtBlock & ~((UInt64)comprUnitSize - 1); - - unsigned left = 0, right = Extents.Size(); - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (virtBlock2 < Extents[mid].Virt) - right = mid; - else - left = mid; - } - - bool isCompressed = false; - UInt64 virtBlock2End = virtBlock2 + comprUnitSize; - if (CompressionUnit != 0) - for (unsigned i = left; i < Extents.Size(); i++) - { - const CExtent &e = Extents[i]; - if (e.Virt >= virtBlock2End) - break; - if (e.IsEmpty()) - { - isCompressed = true; - break; - } - } - - unsigned i; - for (i = left; Extents[i + 1].Virt <= virtBlock; i++); - - _sparseMode = false; - if (!isCompressed) - { - const CExtent &e = Extents[i]; - UInt64 newPos = (e.Phy << BlockSizeLog) + _virtPos - (e.Virt << BlockSizeLog); - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - UInt64 next = Extents[i + 1].Virt; - if (next > virtBlock2End) - next &= ~((UInt64)comprUnitSize - 1); - next <<= BlockSizeLog; - if (next > Size) - next = Size; - _curRem = next - _virtPos; - break; - } - bool thereArePhy = false; - for (unsigned i2 = left; i2 < Extents.Size(); i2++) - { - const CExtent &e = Extents[i2]; - if (e.Virt >= virtBlock2End) - break; - if (!e.IsEmpty()) - { - thereArePhy = true; - break; - } - } - if (!thereArePhy) - { - _curRem = (Extents[i + 1].Virt << BlockSizeLog) - _virtPos; - _sparseMode = true; - break; - } - - size_t offs = 0; - UInt64 curVirt = virtBlock2; - for (i = left; i < Extents.Size(); i++) - { - const CExtent &e = Extents[i]; - if (e.IsEmpty()) - break; - if (e.Virt >= virtBlock2End) - return S_FALSE; - UInt64 newPos = (e.Phy + (curVirt - e.Virt)) << BlockSizeLog; - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - UInt64 numChunks = Extents[i + 1].Virt - curVirt; - if (curVirt + numChunks > virtBlock2End) - numChunks = virtBlock2End - curVirt; - size_t compressed = (size_t)numChunks << BlockSizeLog; - RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed)); - curVirt += numChunks; - _physPos += compressed; - offs += compressed; - } - size_t destLenMax = GetCuSize(); - size_t destLen = destLenMax; - const UInt64 rem = Size - (virtBlock2 << BlockSizeLog); - if (destLen > rem) - destLen = (size_t)rem; - - Byte *dest = _outBuf + (cacheIndex << _chunkSizeLog); - size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs); - _tags[cacheIndex] = cacheTag; - - // some files in Vista have destSize > destLen - if (destSizeRes < destLen) - { - memset(dest, 0, destLenMax); - if (InUse) - return S_FALSE; - } - } - if (size > _curRem) - size = (UInt32)_curRem; - HRESULT res = S_OK; - if (_sparseMode) - memset(data, 0, size); - else - { - res = Stream->Read(data, size, &size); - _physPos += size; - } - if (processedSize) - *processedSize = size; - _virtPos += size; - _curRem -= size; - return res; -} - -STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - if (_virtPos != (UInt64)offset) - { - _curRem = 0; - _virtPos = offset; - } - if (newPosition) - *newPosition = offset; - return S_OK; -} - -static HRESULT DataParseExtents(unsigned clusterSizeLog, const CObjectVector &attrs, - unsigned attrIndex, unsigned attrIndexLim, UInt64 numPhysClusters, CRecordVector &Extents) -{ - { - CExtent e; - e.Virt = 0; - e.Phy = kEmptyExtent; - Extents.Add(e); - } - - const CAttr &attr0 = attrs[attrIndex]; - - if (attr0.AllocatedSize < attr0.Size || - (attrs[attrIndexLim - 1].HighVcn + 1) != (attr0.AllocatedSize >> clusterSizeLog) || - (attr0.AllocatedSize & ((1 << clusterSizeLog) - 1)) != 0) - return S_FALSE; - - for (unsigned i = attrIndex; i < attrIndexLim; i++) - if (!attrs[i].ParseExtents(Extents, numPhysClusters, attr0.CompressionUnit)) - return S_FALSE; - - UInt64 packSizeCalc = 0; - FOR_VECTOR (k, Extents) - { - CExtent &e = Extents[k]; - if (!e.IsEmpty()) - packSizeCalc += (Extents[k + 1].Virt - e.Virt) << clusterSizeLog; - PRF2(printf("\nSize = %4I64X", Extents[k + 1].Virt - e.Virt)); - PRF2(printf(" Pos = %4I64X", e.Phy)); - } - - if (attr0.CompressionUnit != 0) - { - if (packSizeCalc != attr0.PackSize) - return S_FALSE; - } - else - { - if (packSizeCalc != attr0.AllocatedSize) - return S_FALSE; - } - return S_OK; -} - -struct CDataRef -{ - unsigned Start; - unsigned Num; -}; - -static const UInt32 kMagic_FILE = 0x454C4946; -static const UInt32 kMagic_BAAD = 0x44414142; - -struct CMftRec -{ - UInt32 Magic; - // UInt64 Lsn; - UInt16 SeqNumber; // Number of times this mft record has been reused - UInt16 Flags; - // UInt16 LinkCount; - // UInt16 NextAttrInstance; - CMftRef BaseMftRef; - // UInt32 ThisRecNumber; - - UInt32 MyNumNameLinks; - int MyItemIndex; // index in Items[] of main item for that record, or -1 if there is no item for that record - - CObjectVector DataAttrs; - CObjectVector FileNames; - CRecordVector DataRefs; - // CAttr SecurityAttr; - - CSiAttr SiAttr; - - CByteBuffer ReparseData; - - int FindWin32Name_for_DosName(unsigned dosNameIndex) const - { - const CFileNameAttr &cur = FileNames[dosNameIndex]; - if (cur.IsDos()) - for (unsigned i = 0; i < FileNames.Size(); i++) - { - const CFileNameAttr &next = FileNames[i]; - if (next.IsWin32() && cur.ParentDirRef.Val == next.ParentDirRef.Val) - return i; - } - return -1; - } - - int FindDosName(unsigned nameIndex) const - { - const CFileNameAttr &cur = FileNames[nameIndex]; - if (cur.IsWin32()) - for (unsigned i = 0; i < FileNames.Size(); i++) - { - const CFileNameAttr &next = FileNames[i]; - if (next.IsDos() && cur.ParentDirRef.Val == next.ParentDirRef.Val) - return i; - } - return -1; - } - - /* - bool IsAltStream(int dataIndex) const - { - return dataIndex >= 0 && ( - (IsDir() || - !DataAttrs[DataRefs[dataIndex].Start].Name.IsEmpty())); - } - */ - - void MoveAttrsFrom(CMftRec &src) - { - DataAttrs += src.DataAttrs; - FileNames += src.FileNames; - src.DataAttrs.ClearAndFree(); - src.FileNames.ClearAndFree(); - } - - UInt64 GetPackSize() const - { - UInt64 res = 0; - FOR_VECTOR (i, DataRefs) - res += DataAttrs[DataRefs[i].Start].GetPackSize(); - return res; - } - - bool Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector *attrs); - - bool IsEmpty() const { return (Magic <= 2); } - bool IsFILE() const { return (Magic == kMagic_FILE); } - bool IsBAAD() const { return (Magic == kMagic_BAAD); } - - bool InUse() const { return (Flags & 1) != 0; } - bool IsDir() const { return (Flags & 2) != 0; } - - void ParseDataNames(); - HRESULT GetStream(IInStream *mainStream, int dataIndex, - unsigned clusterSizeLog, UInt64 numPhysClusters, IInStream **stream) const; - unsigned GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 numPhysClusters) const; - - UInt64 GetSize(unsigned dataIndex) const { return DataAttrs[DataRefs[dataIndex].Start].GetSize(); } - - CMftRec(): MyNumNameLinks(0), MyItemIndex(-1) {} -}; - -void CMftRec::ParseDataNames() -{ - DataRefs.Clear(); - DataAttrs.Sort(CompareAttr, 0); - - for (unsigned i = 0; i < DataAttrs.Size();) - { - CDataRef ref; - ref.Start = i; - for (i++; i < DataAttrs.Size(); i++) - if (DataAttrs[ref.Start].Name != DataAttrs[i].Name) - break; - ref.Num = i - ref.Start; - DataRefs.Add(ref); - } -} - -HRESULT CMftRec::GetStream(IInStream *mainStream, int dataIndex, - unsigned clusterSizeLog, UInt64 numPhysClusters, IInStream **destStream) const -{ - *destStream = 0; - CBufferInStream *streamSpec = new CBufferInStream; - CMyComPtr streamTemp = streamSpec; - - if (dataIndex >= 0) - if ((unsigned)dataIndex < DataRefs.Size()) - { - const CDataRef &ref = DataRefs[dataIndex]; - unsigned numNonResident = 0; - unsigned i; - for (i = ref.Start; i < ref.Start + ref.Num; i++) - if (DataAttrs[i].NonResident) - numNonResident++; - - const CAttr &attr0 = DataAttrs[ref.Start]; - - if (numNonResident != 0 || ref.Num != 1) - { - if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported()) - return S_FALSE; - CInStream *ss = new CInStream; - CMyComPtr streamTemp2 = ss; - RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, ss->Extents)); - ss->Size = attr0.Size; - ss->InitializedSize = attr0.InitializedSize; - ss->Stream = mainStream; - ss->BlockSizeLog = clusterSizeLog; - ss->InUse = InUse(); - RINOK(ss->InitAndSeek(attr0.CompressionUnit)); - *destStream = streamTemp2.Detach(); - return S_OK; - } - - streamSpec->Buf = attr0.Data; - } - - streamSpec->Init(); - *destStream = streamTemp.Detach(); - return S_OK; -} - -unsigned CMftRec::GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 numPhysClusters) const -{ - if (dataIndex < 0) - return 0; - { - const CDataRef &ref = DataRefs[dataIndex]; - unsigned numNonResident = 0; - unsigned i; - for (i = ref.Start; i < ref.Start + ref.Num; i++) - if (DataAttrs[i].NonResident) - numNonResident++; - - const CAttr &attr0 = DataAttrs[ref.Start]; - - if (numNonResident != 0 || ref.Num != 1) - { - if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported()) - return 0; // error; - CRecordVector extents; - if (DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, extents) != S_OK) - return 0; // error; - return extents.Size() - 1; - } - // if (attr0.Data.Size() != 0) - // return 1; - return 0; - } -} - -bool CMftRec::Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 recNumber, - CObjectVector *attrs) -{ - G32(p, Magic); - if (!IsFILE()) - return IsEmpty() || IsBAAD(); - - - { - UInt32 usaOffset; - UInt32 numUsaItems; - G16(p + 0x04, usaOffset); - G16(p + 0x06, numUsaItems); - - /* NTFS stores (usn) to 2 last bytes in each sector (before writing record to disk). - Original values of these two bytes are stored in table. - So we restore original data from table */ - - if ((usaOffset & 1) != 0 - || usaOffset + numUsaItems * 2 > ((UInt32)1 << sectorSizeLog) - 2 - || numUsaItems == 0 - || numUsaItems - 1 != numSectors) - return false; - - if (usaOffset >= 0x30) // NTFS 3.1+ - { - UInt32 iii = Get32(p + 0x2C); - if (iii != recNumber) - { - // ntfs-3g probably writes 0 (that probably is incorrect value) to this field for unused records. - // so we support that "bad" case. - if (iii != 0) - return false; - } - } - - UInt16 usn = Get16(p + usaOffset); - // PRF(printf("\nusn = %d", usn)); - for (UInt32 i = 1; i < numUsaItems; i++) - { - void *pp = p + (i << sectorSizeLog) - 2; - if (Get16(pp) != usn) - return false; - SetUi16(pp, Get16(p + usaOffset + i * 2)); - } - } - - // G64(p + 0x08, Lsn); - G16(p + 0x10, SeqNumber); - // G16(p + 0x12, LinkCount); - // PRF(printf(" L=%d", LinkCount)); - UInt32 attrOffs = Get16(p + 0x14); - G16(p + 0x16, Flags); - PRF(printf(" F=%4X", Flags)); - - UInt32 bytesInUse = Get32(p + 0x18); - UInt32 bytesAlloc = Get32(p + 0x1C); - G64(p + 0x20, BaseMftRef.Val); - if (BaseMftRef.Val != 0) - { - PRF(printf(" BaseRef=%d", (int)BaseMftRef.Val)); - // return false; // Check it; - } - // G16(p + 0x28, NextAttrInstance); - - UInt32 limit = numSectors << sectorSizeLog; - if (attrOffs >= limit - || (attrOffs & 7) != 0 - || (bytesInUse & 7) != 0 - || bytesInUse > limit - || bytesAlloc != limit) - return false; - - limit = bytesInUse; - - for (UInt32 t = attrOffs;;) - { - if (t >= limit) - return false; - - CAttr attr; - // PRF(printf("\n %2d:", Attrs.Size())); - PRF(printf("\n")); - UInt32 len = attr.Parse(p + t, limit - t); - if (len == 0 || limit - t < len) - return false; - t += len; - if (attr.Type == 0xFFFFFFFF) - { - if (t != limit) - return false; - break; - } - switch (attr.Type) - { - case ATTR_TYPE_FILE_NAME: - { - CFileNameAttr fna; - if (!attr.ParseFileName(fna)) - return false; - FileNames.Add(fna); - PRF(printf(" flags = %4x\n ", (int)fna.NameType)); - PRF_UTF16(fna.Name); - break; - } - case ATTR_TYPE_STANDARD_INFO: - if (!attr.ParseSi(SiAttr)) - return false; - break; - case ATTR_TYPE_DATA: - DataAttrs.Add(attr); - break; - case ATTR_TYPE_REPARSE_POINT: - ReparseData = attr.Data; - break; - /* - case ATTR_TYPE_SECURITY_DESCRIPTOR: - SecurityAttr = attr; - break; - */ - default: - if (attrs) - attrs->Add(attr); - break; - } - } - - return true; -} - -/* - NTFS probably creates empty DATA_ATTRIBUTE for empty file, - But it doesn't do it for - $Secure (:$SDS), - $Extend\$Quota - $Extend\$ObjId - $Extend\$Reparse -*/ - -static const int k_Item_DataIndex_IsEmptyFile = -1; // file without unnamed data stream -static const int k_Item_DataIndex_IsDir = -2; - -// static const int k_ParentFolderIndex_Root = -1; -static const int k_ParentFolderIndex_Lost = -2; -static const int k_ParentFolderIndex_Deleted = -3; - -struct CItem -{ - unsigned RecIndex; // index in Recs array - unsigned NameIndex; // index in CMftRec::FileNames - - int DataIndex; /* index in CMftRec::DataRefs - -1: file without unnamed data stream - -2: for directories */ - - int ParentFolder; /* index in Items array - -1: for root items - -2: [LOST] folder - -3: [UNKNOWN] folder (deleted lost) */ - int ParentHost; /* index in Items array, if it's AltStream - -1: if it's not AltStream */ - - CItem(): DataIndex(k_Item_DataIndex_IsDir), ParentFolder(-1), ParentHost(-1) {} - - bool IsAltStream() const { return ParentHost != -1; } - bool IsDir() const { return DataIndex == k_Item_DataIndex_IsDir; } - // check it !!! - // probably NTFS for empty file still creates empty DATA_ATTRIBUTE - // But it doesn't do it for $Secure:$SDS -}; - -struct CDatabase -{ - CRecordVector Items; - CObjectVector Recs; - CMyComPtr InStream; - CHeader Header; - unsigned RecSizeLog; - UInt64 PhySize; - - IArchiveOpenCallback *OpenCallback; - - CByteBuffer ByteBuf; - - CObjectVector VolAttrs; - - CByteBuffer SecurData; - CRecordVector SecurOffsets; - - bool _showSystemFiles; - bool _showDeletedFiles; - CObjectVector VirtFolderNames; - UString EmptyString; - - int _systemFolderIndex; - int _lostFolderIndex_Normal; - int _lostFolderIndex_Deleted; - - // bool _headerWarning; - - bool ThereAreAltStreams; - - void InitProps() - { - _showSystemFiles = true; - // we show SystemFiles by default since it's difficult to track $Extend\* system files - // it must be fixed later - _showDeletedFiles = false; - } - - CDatabase() { InitProps(); } - ~CDatabase() { ClearAndClose(); } - - void Clear(); - void ClearAndClose(); - - void GetItemPath(unsigned index, NCOM::CPropVariant &path) const; - HRESULT Open(); - - HRESULT SeekToCluster(UInt64 cluster); - - int FindDirItemForMtfRec(UInt64 recIndex) const - { - if (recIndex >= Recs.Size()) - return -1; - const CMftRec &rec = Recs[(unsigned)recIndex]; - if (!rec.IsDir()) - return -1; - return rec.MyItemIndex; - /* - unsigned left = 0, right = Items.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - const CItem &item = Items[mid]; - UInt64 midValue = item.RecIndex; - if (recIndex == midValue) - { - // if item is not dir (file or alt stream we don't return it) - // if (item.DataIndex < 0) - if (item.IsDir()) - return mid; - right = mid; - } - else if (recIndex < midValue) - right = mid; - else - left = mid + 1; - } - return -1; - */ - } - - bool FindSecurityDescritor(UInt32 id, UInt64 &offset, UInt32 &size) const; - - HRESULT ParseSecuritySDS_2(); - void ParseSecuritySDS() - { - HRESULT res = ParseSecuritySDS_2(); - if (res != S_OK) - { - SecurOffsets.Clear(); - SecurData.Free(); - } - } - -}; - -HRESULT CDatabase::SeekToCluster(UInt64 cluster) -{ - return InStream->Seek(cluster << Header.ClusterSizeLog, STREAM_SEEK_SET, NULL); -} - -void CDatabase::Clear() -{ - Items.Clear(); - Recs.Clear(); - SecurOffsets.Clear(); - SecurData.Free(); - VirtFolderNames.Clear(); - _systemFolderIndex = -1; - _lostFolderIndex_Normal = -1; - _lostFolderIndex_Deleted = -1; - ThereAreAltStreams = false; - // _headerWarning = false; - PhySize = 0; -} - -void CDatabase::ClearAndClose() -{ - Clear(); - InStream.Release(); -} - -void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const -{ - const CItem *item = &Items[index]; - unsigned size = 0; - const CMftRec &rec = Recs[item->RecIndex]; - size += rec.FileNames[item->NameIndex].Name.Len(); - - bool isAltStream = item->IsAltStream(); - - if (isAltStream) - { - const CAttr &data = rec.DataAttrs[rec.DataRefs[item->DataIndex].Start]; - if (item->RecIndex == kRecIndex_RootDir) - { - wchar_t *s = path.AllocBstr(data.Name.Len() + 1); - s[0] = L':'; - if (!data.Name.IsEmpty()) - MyStringCopy(s + 1, data.Name.GetRawPtr()); - return; - } - - size += data.Name.Len(); - size++; - } - - for (unsigned i = 0;; i++) - { - if (i > 256) - { - path = "[TOO-LONG]"; - return; - } - const wchar_t *servName; - if (item->RecIndex < kNumSysRecs - /* && item->RecIndex != kRecIndex_RootDir */) - servName = kVirtualFolder_System; - else - { - int index2 = item->ParentFolder; - if (index2 >= 0) - { - item = &Items[index2]; - size += Recs[item->RecIndex].FileNames[item->NameIndex].Name.Len() + 1; - continue; - } - if (index2 == -1) - break; - servName = (index2 == k_ParentFolderIndex_Lost) ? - kVirtualFolder_Lost_Normal : - kVirtualFolder_Lost_Deleted; - } - size += MyStringLen(servName) + 1; - break; - } - - wchar_t *s = path.AllocBstr(size); - - item = &Items[index]; - - bool needColon = false; - if (isAltStream) - { - const UString2 &name = rec.DataAttrs[rec.DataRefs[item->DataIndex].Start].Name; - if (!name.IsEmpty()) - { - size -= name.Len(); - MyStringCopy(s + size, name.GetRawPtr()); - } - s[--size] = ':'; - needColon = true; - } - - { - const UString2 &name = rec.FileNames[item->NameIndex].Name; - unsigned len = name.Len(); - if (len != 0) - MyStringCopy(s + size - len, name.GetRawPtr()); - if (needColon) - s[size] = ':'; - size -= len; - } - - for (;;) - { - const wchar_t *servName; - if (item->RecIndex < kNumSysRecs - /* && && item->RecIndex != kRecIndex_RootDir */) - servName = kVirtualFolder_System; - else - { - int index2 = item->ParentFolder; - if (index2 >= 0) - { - item = &Items[index2]; - const UString2 &name = Recs[item->RecIndex].FileNames[item->NameIndex].Name; - unsigned len = name.Len(); - size--; - if (len != 0) - { - size -= len; - MyStringCopy(s + size, name.GetRawPtr()); - } - s[size + len] = WCHAR_PATH_SEPARATOR; - continue; - } - if (index2 == -1) - break; - servName = (index2 == k_ParentFolderIndex_Lost) ? - kVirtualFolder_Lost_Normal : - kVirtualFolder_Lost_Deleted; - } - MyStringCopy(s, servName); - s[MyStringLen(servName)] = WCHAR_PATH_SEPARATOR; - break; - } -} - -bool CDatabase::FindSecurityDescritor(UInt32 item, UInt64 &offset, UInt32 &size) const -{ - offset = 0; - size = 0; - unsigned left = 0, right = SecurOffsets.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - size_t offs = SecurOffsets[mid]; - UInt32 midValue = Get32(((const Byte *)SecurData) + offs + 4); - if (item == midValue) - { - offset = Get64((const Byte *)SecurData + offs + 8) + 20; - size = Get32((const Byte *)SecurData + offs + 16) - 20; - return true; - } - if (item < midValue) - right = mid; - else - left = mid + 1; - } - return false; -} - -/* -static int CompareIDs(const size_t *p1, const size_t *p2, void *data) -{ - UInt32 id1 = Get32(((const Byte *)data) + *p1 + 4); - UInt32 id2 = Get32(((const Byte *)data) + *p2 + 4); - return MyCompare(id1, id2); -} -*/ - -// security data contains duplication copy after each 256 KB. -static const unsigned kSecureDuplicateStepBits = 18; - -HRESULT CDatabase::ParseSecuritySDS_2() -{ - const Byte *p = SecurData; - size_t size = SecurData.Size(); - const size_t kDuplicateStep = (size_t)1 << kSecureDuplicateStepBits; - const size_t kDuplicateMask = kDuplicateStep - 1; - size_t lim = MyMin(size, kDuplicateStep); - UInt32 idPrev = 0; - for (size_t pos = 0; pos < size && size - pos >= 20;) - { - UInt32 id = Get32(p + pos + 4); - UInt64 offs = Get64(p + pos + 8); - UInt32 entrySize = Get32(p + pos + 16); - if (offs == pos && entrySize >= 20 && lim - pos >= entrySize) - { - if (id <= idPrev) - return S_FALSE; - idPrev = id; - SecurOffsets.Add(pos); - pos += entrySize; - pos = (pos + 0xF) & ~(size_t)0xF; - if ((pos & kDuplicateMask) != 0) - continue; - } - else - pos = (pos + kDuplicateStep) & ~kDuplicateMask; - pos += kDuplicateStep; - lim = pos + kDuplicateStep; - if (lim >= size) - lim = size; - } - // we checked that IDs are sorted, so we don't need Sort - // SecurOffsets.Sort(CompareIDs, (void *)p); - return S_OK; -} - -HRESULT CDatabase::Open() -{ - Clear(); - - /* NTFS layout: - 1) main part (as specified by NumClusters). Only that part is available, if we open "\\.\c:" - 2) additional empty sectors (as specified by NumSectors) - 3) the copy of first sector (boot sector) - - We support both cases: - - the file with only main part - - full file (as raw data on partition), including the copy - of first sector (boot sector) at the end of data - - We don't support the case, when only the copy of boot sector - at the end was detected as NTFS signature. - */ - - { - static const UInt32 kHeaderSize = 512; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)); - if (!Header.Parse(buf)) - return S_FALSE; - - UInt64 fileSize; - RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize)); - PhySize = Header.GetPhySize_Clusters(); - if (fileSize < PhySize) - return S_FALSE; - - UInt64 phySizeMax = Header.GetPhySize_Max(); - if (fileSize >= phySizeMax) - { - RINOK(InStream->Seek(Header.NumSectors << Header.SectorSizeLog, STREAM_SEEK_SET, NULL)); - Byte buf2[kHeaderSize]; - if (ReadStream_FALSE(InStream, buf2, kHeaderSize) == S_OK) - { - if (memcmp(buf, buf2, kHeaderSize) == 0) - PhySize = phySizeMax; - // else _headerWarning = true; - } - } - } - - SeekToCluster(Header.MftCluster); - - CMftRec mftRec; - UInt32 numSectorsInRec; - - CMyComPtr mftStream; - { - UInt32 blockSize = 1 << 12; - ByteBuf.Alloc(blockSize); - RINOK(ReadStream_FALSE(InStream, ByteBuf, blockSize)); - - { - UInt32 allocSize = Get32(ByteBuf + 0x1C); - int t = GetLog(allocSize); - if (t < (int)Header.SectorSizeLog) - return S_FALSE; - RecSizeLog = t; - if (RecSizeLog > 15) - return S_FALSE; - } - - numSectorsInRec = 1 << (RecSizeLog - Header.SectorSizeLog); - if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, 0, NULL)) - return S_FALSE; - if (!mftRec.IsFILE()) - return S_FALSE; - mftRec.ParseDataNames(); - if (mftRec.DataRefs.IsEmpty()) - return S_FALSE; - RINOK(mftRec.GetStream(InStream, 0, Header.ClusterSizeLog, Header.NumClusters, &mftStream)); - if (!mftStream) - return S_FALSE; - } - - // CObjectVector SecurityAttrs; - - UInt64 mftSize = mftRec.DataAttrs[0].Size; - if ((mftSize >> 4) > Header.GetPhySize_Clusters()) - return S_FALSE; - - const size_t kBufSize = (1 << 15); - const size_t recSize = ((size_t)1 << RecSizeLog); - if (kBufSize < recSize) - return S_FALSE; - - { - const UInt64 numFiles = mftSize >> RecSizeLog; - if (numFiles > (1 << 30)) - return S_FALSE; - if (OpenCallback) - { - RINOK(OpenCallback->SetTotal(&numFiles, &mftSize)); - } - - ByteBuf.Alloc(kBufSize); - Recs.ClearAndReserve((unsigned)numFiles); - } - - for (UInt64 pos64 = 0;;) - { - if (OpenCallback) - { - const UInt64 numFiles = Recs.Size(); - if ((numFiles & 0x3FF) == 0) - { - RINOK(OpenCallback->SetCompleted(&numFiles, &pos64)); - } - } - size_t readSize = kBufSize; - { - const UInt64 rem = mftSize - pos64; - if (readSize > rem) - readSize = (size_t)rem; - } - if (readSize < recSize) - break; - RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize)); - pos64 += readSize; - - for (size_t i = 0; readSize >= recSize; i += recSize, readSize -= recSize) - { - PRF(printf("\n---------------------")); - PRF(printf("\n%5d:", Recs.Size())); - - Byte *p = ByteBuf + i; - CMftRec rec; - - CObjectVector *attrs = NULL; - unsigned recIndex = Recs.Size(); - switch (recIndex) - { - case kRecIndex_Volume: attrs = &VolAttrs; break; - // case kRecIndex_Security: attrs = &SecurityAttrs; break; - } - - if (!rec.Parse(p, Header.SectorSizeLog, numSectorsInRec, (UInt32)Recs.Size(), attrs)) - return S_FALSE; - Recs.Add(rec); - } - } - - /* - // that code looks too complex. And we can get security info without index parsing - for (i = 0; i < SecurityAttrs.Size(); i++) - { - const CAttr &attr = SecurityAttrs[i]; - if (attr.Name == L"$SII") - { - if (attr.Type == ATTR_TYPE_INDEX_ROOT) - { - const Byte *data = attr.Data; - size_t size = attr.Data.Size(); - - // Index Root - UInt32 attrType = Get32(data); - UInt32 collationRule = Get32(data + 4); - UInt32 indexAllocationEtrySizeSize = Get32(data + 8); - UInt32 clustersPerIndexRecord = Get32(data + 0xC); - data += 0x10; - - // Index Header - UInt32 firstEntryOffset = Get32(data); - UInt32 totalSize = Get32(data + 4); - UInt32 allocSize = Get32(data + 8); - UInt32 flags = Get32(data + 0xC); - - int num = 0; - for (int j = 0 ; j < num; j++) - { - if (Get32(data) != 0x1414 || // offset and size - Get32(data + 4) != 0 || - Get32(data + 8) != 0x428) // KeySize / EntrySize - break; - UInt32 flags = Get32(data + 12); - UInt32 id = Get32(data + 0x10); - if (id = Get32(data + 0x18)) - break; - UInt32 descriptorOffset = Get64(data + 0x1C); - UInt32 descriptorSize = Get64(data + 0x24); - data += 0x28; - } - // break; - } - } - } - */ - - unsigned i; - - for (i = 0; i < Recs.Size(); i++) - { - CMftRec &rec = Recs[i]; - if (!rec.BaseMftRef.IsBaseItself()) - { - UInt64 refIndex = rec.BaseMftRef.GetIndex(); - if (refIndex > (UInt32)Recs.Size()) - return S_FALSE; - CMftRec &refRec = Recs[(unsigned)refIndex]; - bool moveAttrs = (refRec.SeqNumber == rec.BaseMftRef.GetNumber() && refRec.BaseMftRef.IsBaseItself()); - if (rec.InUse() && refRec.InUse()) - { - if (!moveAttrs) - return S_FALSE; - } - else if (rec.InUse() || refRec.InUse()) - moveAttrs = false; - if (moveAttrs) - refRec.MoveAttrsFrom(rec); - } - } - - for (i = 0; i < Recs.Size(); i++) - Recs[i].ParseDataNames(); - - for (i = 0; i < Recs.Size(); i++) - { - CMftRec &rec = Recs[i]; - if (!rec.IsFILE() || !rec.BaseMftRef.IsBaseItself()) - continue; - if (i < kNumSysRecs && !_showSystemFiles) - continue; - if (!rec.InUse() && !_showDeletedFiles) - continue; - - rec.MyNumNameLinks = rec.FileNames.Size(); - - // printf("\n%4d: ", i); - - /* Actually DataAttrs / DataRefs are sorted by name. - It can not be more than one unnamed stream in DataRefs - And indexOfUnnamedStream <= 0. - */ - - int indexOfUnnamedStream = -1; - if (!rec.IsDir()) - { - FOR_VECTOR (di, rec.DataRefs) - if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty()) - { - indexOfUnnamedStream = di; - break; - } - } - - if (rec.FileNames.IsEmpty()) - { - bool needShow = true; - if (i < kNumSysRecs) - { - needShow = false; - FOR_VECTOR (di, rec.DataRefs) - if (rec.GetSize(di) != 0) - { - needShow = true; - break; - } - } - if (needShow) - { - CFileNameAttr &fna = rec.FileNames.AddNew(); - // we set incorrect ParentDirRef, that will place item to [LOST] folder - fna.ParentDirRef.Val = (UInt64)(Int64)-1; - char s[16 + 16]; - ConvertUInt32ToString(i, MyStpCpy(s, "[NONAME]-")); - fna.Name.SetFromAscii(s); - fna.NameType = kFileNameType_Win32Dos; - fna.Attrib = 0; - } - } - - // bool isMainName = true; - - FOR_VECTOR (t, rec.FileNames) - { - #ifdef SHOW_DEBUG_INFO - const CFileNameAttr &fna = rec.FileNames[t]; - #endif - PRF(printf("\n %4d ", (int)fna.NameType)); - PRF_UTF16(fna.Name); - // PRF(printf(" | ")); - - if (rec.FindWin32Name_for_DosName(t) >= 0) - { - rec.MyNumNameLinks--; - continue; - } - - CItem item; - item.NameIndex = t; - item.RecIndex = i; - item.DataIndex = rec.IsDir() ? - k_Item_DataIndex_IsDir : - (indexOfUnnamedStream < 0 ? - k_Item_DataIndex_IsEmptyFile : - indexOfUnnamedStream); - - if (rec.MyItemIndex < 0) - rec.MyItemIndex = Items.Size(); - item.ParentHost = Items.Add(item); - - /* we can use that code to reduce the number of alt streams: - it will not show how alt streams for hard links. */ - // if (!isMainName) continue; isMainName = false; - - unsigned numAltStreams = 0; - - FOR_VECTOR (di, rec.DataRefs) - { - if (!rec.IsDir() && (int)di == indexOfUnnamedStream) - continue; - - const UString2 &subName = rec.DataAttrs[rec.DataRefs[di].Start].Name; - - PRF(printf("\n alt stream: ")); - PRF_UTF16(subName); - - { - // $BadClus:$Bad is sparse file for all clusters. So we skip it. - if (i == kRecIndex_BadClus && subName == L"$Bad") - continue; - } - - numAltStreams++; - ThereAreAltStreams = true; - item.DataIndex = di; - Items.Add(item); - } - } - } - - if (Recs.Size() > kRecIndex_Security) - { - const CMftRec &rec = Recs[kRecIndex_Security]; - FOR_VECTOR (di, rec.DataRefs) - { - const CAttr &attr = rec.DataAttrs[rec.DataRefs[di].Start]; - if (attr.Name == L"$SDS") - { - CMyComPtr sdsStream; - RINOK(rec.GetStream(InStream, di, Header.ClusterSizeLog, Header.NumClusters, &sdsStream)); - if (sdsStream) - { - UInt64 size64 = attr.GetSize(); - if (size64 < (UInt32)1 << 29) - { - size_t size = (size_t)size64; - if ((((size + 1) >> kSecureDuplicateStepBits) & 1) != 0) - { - size -= (1 << kSecureDuplicateStepBits); - SecurData.Alloc(size); - if (ReadStream_FALSE(sdsStream, SecurData, size) == S_OK) - { - ParseSecuritySDS(); - break; - } - } - } - } - break; - } - } - } - - bool thereAreUnknownFolders_Normal = false; - bool thereAreUnknownFolders_Deleted = false; - - for (i = 0; i < Items.Size(); i++) - { - CItem &item = Items[i]; - const CMftRec &rec = Recs[item.RecIndex]; - const CFileNameAttr &fn = rec.FileNames[item.NameIndex]; - const CMftRef &parentDirRef = fn.ParentDirRef; - UInt64 refIndex = parentDirRef.GetIndex(); - if (refIndex == kRecIndex_RootDir) - item.ParentFolder = -1; - else - { - int index = FindDirItemForMtfRec(refIndex); - if (index < 0 || - Recs[Items[index].RecIndex].SeqNumber != parentDirRef.GetNumber()) - { - if (Recs[item.RecIndex].InUse()) - { - thereAreUnknownFolders_Normal = true; - index = k_ParentFolderIndex_Lost; - } - else - { - thereAreUnknownFolders_Deleted = true; - index = k_ParentFolderIndex_Deleted; - } - } - item.ParentFolder = index; - } - } - - unsigned virtIndex = Items.Size(); - if (_showSystemFiles) - { - _systemFolderIndex = virtIndex++; - VirtFolderNames.Add(kVirtualFolder_System); - } - if (thereAreUnknownFolders_Normal) - { - _lostFolderIndex_Normal = virtIndex++; - VirtFolderNames.Add(kVirtualFolder_Lost_Normal); - } - if (thereAreUnknownFolders_Deleted) - { - _lostFolderIndex_Deleted = virtIndex++; - VirtFolderNames.Add(kVirtualFolder_Lost_Deleted); - } - - return S_OK; -} - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IInArchiveGetStream, - public ISetProperties, - public CMyUnknownImp, - CDatabase -{ -public: - MY_UNKNOWN_IMP4( - IInArchive, - IArchiveGetRawProps, - IInArchiveGetStream, - ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); -}; - -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) -{ - *numProps = 2; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) -{ - *name = NULL; - *propID = index == 0 ? kpidNtReparse : kpidNtSecure; - return S_OK; -} - -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) -{ - *parentType = NParentType::kDir; - int par = -1; - - if (index < Items.Size()) - { - const CItem &item = Items[index]; - - if (item.ParentHost >= 0) - { - *parentType = NParentType::kAltStream; - par = (item.RecIndex == kRecIndex_RootDir ? -1 : item.ParentHost); - } - else if (item.RecIndex < kNumSysRecs) - { - if (_showSystemFiles) - par = _systemFolderIndex; - } - else if (item.ParentFolder >= 0) - par = item.ParentFolder; - else if (item.ParentFolder == k_ParentFolderIndex_Lost) - par = _lostFolderIndex_Normal; - else if (item.ParentFolder == k_ParentFolderIndex_Deleted) - par = _lostFolderIndex_Deleted; - } - *parent = (UInt32)(Int32)par; - return S_OK; -} - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - if (propID == kpidName) - { - #ifdef MY_CPU_LE - const UString2 *s; - if (index >= Items.Size()) - s = &VirtFolderNames[index - Items.Size()]; - else - { - const CItem &item = Items[index]; - const CMftRec &rec = Recs[item.RecIndex]; - if (item.IsAltStream()) - s = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start].Name; - else - s = &rec.FileNames[item.NameIndex].Name; - } - if (s->IsEmpty()) - *data = (const wchar_t *)EmptyString; - else - *data = s->GetRawPtr(); - *dataSize = (s->Len() + 1) * sizeof(wchar_t); - *propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE; - #endif - return S_OK; - } - - if (propID == kpidNtReparse) - { - if (index >= Items.Size()) - return S_OK; - const CItem &item = Items[index]; - const CMftRec &rec = Recs[item.RecIndex]; - const CByteBuffer &reparse = rec.ReparseData; - - if (reparse.Size() != 0) - { - *dataSize = (UInt32)reparse.Size(); - *propType = NPropDataType::kRaw; - *data = (const Byte *)reparse; - } - } - - if (propID == kpidNtSecure) - { - if (index >= Items.Size()) - return S_OK; - const CItem &item = Items[index]; - const CMftRec &rec = Recs[item.RecIndex]; - if (rec.SiAttr.SecurityId >= 0) - { - UInt64 offset; - UInt32 size; - if (FindSecurityDescritor(rec.SiAttr.SecurityId, offset, size)) - { - *dataSize = size; - *propType = NPropDataType::kRaw; - *data = (const Byte *)SecurData + offset; - } - } - } - return S_OK; -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - if (index >= Items.Size()) - return S_OK; - IInStream *stream2; - const CItem &item = Items[index]; - const CMftRec &rec = Recs[item.RecIndex]; - HRESULT res = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &stream2); - *stream = (ISequentialInStream *)stream2; - return res; - COM_TRY_END -} - -/* -enum -{ - kpidLink2 = kpidUserDefined, - kpidLinkType, - kpidRecMTime, - kpidRecMTime2, - kpidMTime2, - kpidCTime2, - kpidATime2 -}; - -static const CStatProp kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - - // { NULL, kpidLink, VT_BSTR}, - - // { "Link 2", kpidLink2, VT_BSTR}, - // { "Link Type", kpidLinkType, VT_UI2}, - { NULL, kpidINode, VT_UI8}, - - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidATime, VT_FILETIME}, - - // { "Record Modified", kpidRecMTime, VT_FILETIME}, - - // { "Modified 2", kpidMTime2, VT_FILETIME}, - // { "Created 2", kpidCTime2, VT_FILETIME}, - // { "Accessed 2", kpidATime2, VT_FILETIME}, - // { "Record Modified 2", kpidRecMTime2, VT_FILETIME}, - - { NULL, kpidAttrib, VT_UI4}, - { NULL, kpidNumBlocks, VT_UI4}, - { NULL, kpidIsDeleted, VT_BOOL}, -}; -*/ - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - kpidLinks, - kpidINode, - kpidNumBlocks, - kpidNumAltStreams, - kpidIsAltStream, - kpidShortName, - kpidIsDeleted -}; - -enum -{ - kpidRecordSize = kpidUserDefined -}; - -static const CStatProp kArcProps[] = -{ - { NULL, kpidVolumeName, VT_BSTR}, - { NULL, kpidFileSystem, VT_BSTR}, - { NULL, kpidClusterSize, VT_UI4}, - { NULL, kpidSectorSize, VT_UI4}, - { "Record Size", kpidRecordSize, VT_UI4}, - { NULL, kpidHeadersSize, VT_UI8}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidId, VT_UI8}, -}; - -/* -static const Byte kArcProps[] = -{ - kpidVolumeName, - kpidFileSystem, - kpidClusterSize, - kpidHeadersSize, - kpidCTime, - - kpidSectorSize, - kpidId - // kpidSectorsPerTrack, - // kpidNumHeads, - // kpidHiddenSectors -}; -*/ - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -static void NtfsTimeToProp(UInt64 t, NCOM::CPropVariant &prop) -{ - FILETIME ft; - ft.dwLowDateTime = (DWORD)t; - ft.dwHighDateTime = (DWORD)(t >> 32); - prop = ft; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - const CMftRec *volRec = (Recs.Size() > kRecIndex_Volume ? &Recs[kRecIndex_Volume] : NULL); - - switch (propID) - { - case kpidClusterSize: prop = Header.ClusterSize(); break; - case kpidPhySize: prop = PhySize; break; - /* - case kpidHeadersSize: - { - UInt64 val = 0; - for (unsigned i = 0; i < kNumSysRecs; i++) - { - printf("\n%2d: %8I64d ", i, Recs[i].GetPackSize()); - if (i == 8) - i = i - val += Recs[i].GetPackSize(); - } - prop = val; - break; - } - */ - case kpidCTime: if (volRec) NtfsTimeToProp(volRec->SiAttr.CTime, prop); break; - case kpidMTime: if (volRec) NtfsTimeToProp(volRec->SiAttr.MTime, prop); break; - case kpidShortComment: - case kpidVolumeName: - { - FOR_VECTOR (i, VolAttrs) - { - const CAttr &attr = VolAttrs[i]; - if (attr.Type == ATTR_TYPE_VOLUME_NAME) - { - UString2 name; - GetString(attr.Data, (unsigned)attr.Data.Size() / 2, name); - if (!name.IsEmpty()) - prop = name.GetRawPtr(); - break; - } - } - break; - } - case kpidFileSystem: - { - AString s = "NTFS"; - FOR_VECTOR (i, VolAttrs) - { - const CAttr &attr = VolAttrs[i]; - if (attr.Type == ATTR_TYPE_VOLUME_INFO) - { - CVolInfo vi; - if (attr.ParseVolInfo(vi)) - { - s.Add_Space(); - char temp[16]; - ConvertUInt32ToString(vi.MajorVer, temp); - s += temp; - s += '.'; - ConvertUInt32ToString(vi.MinorVer, temp); - s += temp; - } - break; - } - } - prop = s; - break; - } - case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; - case kpidRecordSize: prop = (UInt32)1 << RecSizeLog; break; - case kpidId: prop = Header.SerialNumber; break; - - case kpidIsTree: prop = true; break; - case kpidIsDeleted: prop = _showDeletedFiles; break; - case kpidIsAltStream: prop = ThereAreAltStreams; break; - case kpidIsAux: prop = true; break; - case kpidINode: prop = true; break; - - case kpidWarning: - if (_lostFolderIndex_Normal >= 0) - prop = "There are lost files"; - break; - - /* - case kpidWarningFlags: - { - UInt32 flags = 0; - if (_headerWarning) - flags |= k_ErrorFlags_HeadersError; - if (flags != 0) - prop = flags; - break; - } - */ - - // case kpidMediaType: prop = Header.MediaType; break; - // case kpidSectorsPerTrack: prop = Header.SectorsPerTrack; break; - // case kpidNumHeads: prop = Header.NumHeads; break; - // case kpidHiddenSectors: prop = Header.NumHiddenSectors; 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; - if (index >= Items.Size()) - { - switch (propID) - { - case kpidName: - case kpidPath: - prop = VirtFolderNames[index - Items.Size()].GetRawPtr(); - break; - case kpidIsDir: prop = true; break; - case kpidIsAux: prop = true; break; - case kpidIsDeleted: - if ((int)index == _lostFolderIndex_Deleted) - prop = true; - break; - } - prop.Detach(value); - return S_OK; - } - - const CItem &item = Items[index]; - const CMftRec &rec = Recs[item.RecIndex]; - - const CAttr *data= NULL; - if (item.DataIndex >= 0) - data = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start]; - - // const CFileNameAttr *fn = &rec.FileNames[item.NameIndex]; - /* - if (rec.FileNames.Size() > 0) - fn = &rec.FileNames[0]; - */ - - switch (propID) - { - case kpidPath: - GetItemPath(index, prop); - break; - - /* - case kpidLink: - if (!rec.ReparseAttr.SubsName.IsEmpty()) - { - prop = rec.ReparseAttr.SubsName; - } - break; - case kpidLink2: - if (!rec.ReparseAttr.PrintName.IsEmpty()) - { - prop = rec.ReparseAttr.PrintName; - } - break; - - case kpidLinkType: - if (rec.ReparseAttr.Tag != 0) - { - prop = (rec.ReparseAttr.Tag & 0xFFFF); - } - break; - */ - - case kpidINode: - { - // const CMftRec &rec = Recs[item.RecIndex]; - // prop = ((UInt64)rec.SeqNumber << 48) | item.RecIndex; - prop = item.RecIndex; - break; - } - case kpidStreamId: - { - if (item.DataIndex >= 0) - prop = ((UInt64)item.RecIndex << 32) | (unsigned)item.DataIndex; - break; - } - - case kpidName: - { - const UString2 *s; - if (item.IsAltStream()) - s = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start].Name; - else - s = &rec.FileNames[item.NameIndex].Name; - if (s->IsEmpty()) - prop = (const wchar_t *)EmptyString; - else - prop = s->GetRawPtr(); - break; - } - - case kpidShortName: - { - if (!item.IsAltStream()) - { - int dosNameIndex = rec.FindDosName(item.NameIndex); - if (dosNameIndex >= 0) - { - const UString2 &s = rec.FileNames[dosNameIndex].Name; - if (s.IsEmpty()) - prop = (const wchar_t *)EmptyString; - else - prop = s.GetRawPtr(); - } - } - break; - } - - case kpidIsDir: prop = item.IsDir(); break; - case kpidIsAltStream: prop = item.IsAltStream(); break; - case kpidIsDeleted: prop = !rec.InUse(); break; - case kpidIsAux: prop = false; break; - - 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 kpidMTime2: if (fn) NtfsTimeToProp(fn->MTime, prop); break; - case kpidCTime2: if (fn) NtfsTimeToProp(fn->CTime, prop); break; - case kpidATime2: if (fn) NtfsTimeToProp(fn->ATime, prop); break; - case kpidRecMTime2: if (fn) NtfsTimeToProp(fn->ThisRecMTime, prop); break; - */ - - case kpidAttrib: - { - UInt32 attrib; - /* WinXP-64: The CFileNameAttr::Attrib is not updated after some changes. Why? - CSiAttr:attrib is updated better. So we use CSiAttr:Sttrib */ - /* - if (fn) - attrib = fn->Attrib; - else - */ - attrib = rec.SiAttr.Attrib; - if (item.IsDir()) - attrib |= FILE_ATTRIBUTE_DIRECTORY; - - /* some system entries can contain extra flags (Index View). - // 0x10000000 (Directory) - // 0x20000000 FILE_ATTR_VIEW_INDEX_PRESENT MFT_RECORD_IS_VIEW_INDEX (Index View) - But we don't need them */ - attrib &= 0xFFFF; - - prop = attrib; - break; - } - case kpidLinks: if (rec.MyNumNameLinks != 1) prop = rec.MyNumNameLinks; break; - - case kpidNumAltStreams: - { - if (!item.IsAltStream()) - { - unsigned num = rec.DataRefs.Size(); - if (num > 0) - { - if (!rec.IsDir() && rec.DataAttrs[rec.DataRefs[0].Start].Name.IsEmpty()) - num--; - if (num > 0) - prop = num; - } - } - break; - } - - case kpidSize: if (data) prop = data->GetSize(); else if (!item.IsDir()) prop = (UInt64)0; break; - case kpidPackSize: if (data) prop = data->GetPackSize(); else if (!item.IsDir()) prop = (UInt64)0; break; - case kpidNumBlocks: if (data) prop = (UInt32)rec.GetNumExtents(item.DataIndex, Header.ClusterSizeLog, Header.NumClusters); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - OpenCallback = callback; - InStream = stream; - HRESULT res; - try - { - res = CDatabase::Open(); - if (res == S_OK) - return S_OK; - } - catch(...) - { - Close(); - throw; - } - Close(); - return res; - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - ClearAndClose(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = Items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - if (index >= (UInt32)Items.Size()) - continue; - const CItem &item = Items[allFilesMode ? i : indices[i]]; - const CMftRec &rec = Recs[item.RecIndex]; - if (item.DataIndex >= 0) - totalSize += rec.GetSize(item.DataIndex); - } - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 totalPackSize; - totalSize = totalPackSize = 0; - - UInt32 clusterSize = Header.ClusterSize(); - CByteBuffer buf(clusterSize); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems; i++) - { - lps->InSize = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (index >= (UInt32)Items.Size() || Items[index].IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - const CItem &item = Items[index]; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(); - - const CMftRec &rec = Recs[item.RecIndex]; - - int res = NExtract::NOperationResult::kDataError; - { - CMyComPtr inStream; - HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream); - if (hres == S_FALSE) - res = NExtract::NOperationResult::kUnsupportedMethod; - else - { - RINOK(hres); - if (inStream) - { - hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); - if (hres != S_OK && hres != S_FALSE) - { - RINOK(hres); - } - if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK) - res = NExtract::NOperationResult::kOK; - } - } - } - if (item.DataIndex >= 0) - { - const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start]; - totalPackSize += data.GetPackSize(); - totalSize += data.GetSize(); - } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = Items.Size() + VirtFolderNames.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - InitProps(); - - for (UInt32 i = 0; i < numProps; i++) - { - UString name = names[i]; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - - const PROPVARIANT &prop = values[i]; - - if (name.IsEqualTo("ld")) - { - RINOK(PROPVARIANT_to_bool(prop, _showDeletedFiles)); - } - else if (name.IsEqualTo("ls")) - { - RINOK(PROPVARIANT_to_bool(prop, _showSystemFiles)); - } - else - return E_INVALIDARG; - } - return S_OK; -} - -static const Byte k_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; - -REGISTER_ARC_I( - "NTFS", "ntfs img", 0, 0xD9, - k_Signature, - 3, - 0, - NULL) - -}} +// NtfsHandler.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO +// #define SHOW_DEBUG_INFO2 + +#if defined(SHOW_DEBUG_INFO) || defined(SHOW_DEBUG_INFO2) +#include +#endif + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/MethodProps.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +#include "Common/DummyOutStream.h" + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#define PRF_UTF16(x) PRF(printf("%S", x)) +#else +#define PRF(x) +#define PRF_UTF16(x) +#endif + +#ifdef SHOW_DEBUG_INFO2 +#define PRF2(x) x +#else +#define PRF2(x) +#endif + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define G16(p, dest) dest = Get16(p) +#define G32(p, dest) dest = Get32(p) +#define G64(p, dest) dest = Get64(p) + +using namespace NWindows; + +namespace NArchive { +namespace Ntfs { + +static const wchar_t * const kVirtualFolder_System = L"[SYSTEM]"; +static const wchar_t * const kVirtualFolder_Lost_Normal = L"[LOST]"; +static const wchar_t * const kVirtualFolder_Lost_Deleted = L"[UNKNOWN]"; + +static const unsigned kNumSysRecs = 16; + +static const unsigned kRecIndex_Volume = 3; +static const unsigned kRecIndex_RootDir = 5; +static const unsigned kRecIndex_BadClus = 8; +static const unsigned kRecIndex_Security = 9; + +struct CHeader +{ + unsigned SectorSizeLog; + unsigned ClusterSizeLog; + unsigned MftRecordSizeLog; + // Byte MediaType; + // UInt32 NumHiddenSectors; + UInt64 NumSectors; + UInt64 NumClusters; + UInt64 MftCluster; + UInt64 SerialNumber; + // UInt16 SectorsPerTrack; + // UInt16 NumHeads; + + UInt64 GetPhySize_Clusters() const { return NumClusters << ClusterSizeLog; } + UInt64 GetPhySize_Max() const { return (NumSectors + 1) << SectorSizeLog; } + UInt32 ClusterSize() const { return (UInt32)1 << ClusterSizeLog; } + bool Parse(const Byte *p); +}; + +static int GetLog(UInt32 num) +{ + for (int i = 0; i < 31; i++) + if (((UInt32)1 << i) == num) + return i; + return -1; +} + +bool CHeader::Parse(const Byte *p) +{ + if (p[0x1FE] != 0x55 || p[0x1FF] != 0xAA) + return false; + + // int codeOffset = 0; + 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; + } + unsigned sectorsPerClusterLog; + + if (memcmp(p + 3, "NTFS ", 8) != 0) + return false; + { + { + const int t = GetLog(Get16(p + 11)); + if (t < 9 || t > 12) + return false; + SectorSizeLog = (unsigned)t; + } + { + const unsigned v = p[13]; + if (v <= 0x80) + { + const int t = GetLog(v); + if (t < 0) + return false; + sectorsPerClusterLog = (unsigned)t; + } + else + sectorsPerClusterLog = 0x100 - v; + ClusterSizeLog = SectorSizeLog + sectorsPerClusterLog; + if (ClusterSizeLog > 30) + return false; + } + } + + for (int i = 14; i < 21; i++) + if (p[i] != 0) + return false; + + // F8 : a hard disk + // F0 : high-density 3.5-inch floppy disk + if (p[21] != 0xF8) // MediaType = Fixed_Disk + return false; + if (Get16(p + 22) != 0) // NumFatSectors + return false; + // G16(p + 24, SectorsPerTrack); // 63 usually + // G16(p + 26, NumHeads); // 255 + // G32(p + 28, NumHiddenSectors); // 63 (XP) / 2048 (Vista and win7) / (0 on media that are not partitioned ?) + if (Get32(p + 32) != 0) // NumSectors32 + return false; + + // DriveNumber = p[0x24]; + if (p[0x25] != 0) // CurrentHead + return false; + /* + NTFS-HDD: p[0x26] = 0x80 + NTFS-FLASH: p[0x26] = 0 + */ + if (p[0x26] != 0x80 && p[0x26] != 0) // ExtendedBootSig + return false; + if (p[0x27] != 0) // reserved + return false; + + NumSectors = Get64(p + 0x28); + if (NumSectors >= ((UInt64)1 << (62 - SectorSizeLog))) + return false; + + NumClusters = NumSectors >> sectorsPerClusterLog; + + G64(p + 0x30, MftCluster); // $MFT. + // G64(p + 0x38, Mft2Cluster); + G64(p + 0x48, SerialNumber); // $MFTMirr + + /* + numClusters_per_MftRecord: + numClusters_per_IndexBlock: + only low byte from 4 bytes is used. Another 3 high bytes are zeros. + If the number is positive (number < 0x80), + then it represents the number of clusters. + If the number is negative (number >= 0x80), + then the size of the file record is 2 raised to the absolute value of this number. + example: (0xF6 == -10) means 2^10 = 1024 bytes. + */ + { + UInt32 numClusters_per_MftRecord; + G32(p + 0x40, numClusters_per_MftRecord); + if (numClusters_per_MftRecord >= 0x100 || numClusters_per_MftRecord == 0) + return false; + if (numClusters_per_MftRecord < 0x80) + { + const int t = GetLog(numClusters_per_MftRecord); + if (t < 0) + return false; + MftRecordSizeLog = (unsigned)t + ClusterSizeLog; + } + else + MftRecordSizeLog = 0x100 - numClusters_per_MftRecord; + // what exact MFT record sizes are possible and supported by Windows? + // do we need to change this limit here? + const unsigned k_MftRecordSizeLog_MAX = 12; + if (MftRecordSizeLog > k_MftRecordSizeLog_MAX) + return false; + if (MftRecordSizeLog < SectorSizeLog) + return false; + } + { + UInt32 numClusters_per_IndexBlock; + G32(p + 0x44, numClusters_per_IndexBlock); + return (numClusters_per_IndexBlock < 0x100); + } +} + +struct CMftRef +{ + UInt64 Val; + + UInt64 GetIndex() const { return Val & (((UInt64)1 << 48) - 1); } + UInt16 GetNumber() const { return (UInt16)(Val >> 48); } + bool IsBaseItself() const { return Val == 0; } + + CMftRef(): Val(0) {} +}; + +#define ATNAME(n) ATTR_TYPE_ ## n +#define DEF_ATTR_TYPE(v, n) ATNAME(n) = v + +enum +{ + DEF_ATTR_TYPE(0x00, UNUSED), + DEF_ATTR_TYPE(0x10, STANDARD_INFO), + DEF_ATTR_TYPE(0x20, ATTRIBUTE_LIST), + DEF_ATTR_TYPE(0x30, FILE_NAME), + DEF_ATTR_TYPE(0x40, OBJECT_ID), + DEF_ATTR_TYPE(0x50, SECURITY_DESCRIPTOR), + DEF_ATTR_TYPE(0x60, VOLUME_NAME), + DEF_ATTR_TYPE(0x70, VOLUME_INFO), + DEF_ATTR_TYPE(0x80, DATA), + DEF_ATTR_TYPE(0x90, INDEX_ROOT), + DEF_ATTR_TYPE(0xA0, INDEX_ALLOCATION), + DEF_ATTR_TYPE(0xB0, BITMAP), + DEF_ATTR_TYPE(0xC0, REPARSE_POINT), + DEF_ATTR_TYPE(0xD0, EA_INFO), + DEF_ATTR_TYPE(0xE0, EA), + DEF_ATTR_TYPE(0xF0, PROPERTY_SET), + DEF_ATTR_TYPE(0x100, LOGGED_UTILITY_STREAM), + DEF_ATTR_TYPE(0x1000, FIRST_USER_DEFINED_ATTRIBUTE) +}; + + +/* WinXP-64: + Probably only one short name (dos name) per record is allowed. + There are no short names for hard links. + The pair (Win32,Dos) can be in any order. + Posix name can be after or before Win32 name +*/ + +// static const Byte kFileNameType_Posix = 0; // for hard links +static const Byte kFileNameType_Win32 = 1; // after Dos name +static const Byte kFileNameType_Dos = 2; // short name +static const Byte kFileNameType_Win32Dos = 3; // short and full name are same + +struct CFileNameAttr +{ + CMftRef ParentDirRef; + + // Probably these timestamps don't contain some useful timestamps. So we don't use them + // UInt64 CTime; + // UInt64 MTime; + // UInt64 ThisRecMTime; // xp-64: the time of previous name change (not last name change. why?) + // UInt64 ATime; + // UInt64 AllocatedSize; + // UInt64 DataSize; + // UInt16 PackedEaSize; + UString2 Name; + UInt32 Attrib; + Byte NameType; + + bool IsDos() const { return NameType == kFileNameType_Dos; } + bool IsWin32() const { return (NameType == kFileNameType_Win32); } + + bool Parse(const Byte *p, unsigned size); + + CFileNameAttr(): + Attrib(0), + NameType(0) + {} +}; + +static void GetString(const Byte *p, const unsigned len, UString2 &res) +{ + if (len == 0 && res.IsEmpty()) + return; + wchar_t *s = res.GetBuf(len); + unsigned i; + for (i = 0; i < len; i++) + { + const wchar_t c = Get16(p + i * 2); + if (c == 0) + break; + s[i] = c; + } + s[i] = 0; + res.ReleaseBuf_SetLen(i); +} + +bool CFileNameAttr::Parse(const Byte *p, unsigned size) +{ + if (size < 0x42) + return false; + G64(p + 0x00, ParentDirRef.Val); + // G64(p + 0x08, CTime); + // G64(p + 0x10, MTime); + // G64(p + 0x18, ThisRecMTime); + // G64(p + 0x20, ATime); + // G64(p + 0x28, AllocatedSize); + // G64(p + 0x30, DataSize); + G32(p + 0x38, Attrib); + // G16(p + 0x3C, PackedEaSize); + NameType = p[0x41]; + const unsigned len = p[0x40]; + if (0x42 + len * 2 > size) + return false; + if (len != 0) + GetString(p + 0x42, len, Name); + return true; +} + +struct CSiAttr +{ + UInt64 CTime; + UInt64 MTime; + UInt64 ThisRecMTime; + UInt64 ATime; + UInt32 Attrib; + + /* + UInt32 MaxVersions; + UInt32 Version; + UInt32 ClassId; + UInt32 OwnerId; + */ + UInt32 SecurityId; // SecurityId = 0 is possible ? + // UInt64 QuotaCharged; + + bool Parse(const Byte *p, unsigned size); + + CSiAttr(): + CTime(0), + MTime(0), + ThisRecMTime(0), + ATime(0), + Attrib(0), + SecurityId(0) + {} +}; + + +bool CSiAttr::Parse(const Byte *p, unsigned size) +{ + if (size < 0x24) + return false; + G64(p + 0x00, CTime); + G64(p + 0x08, MTime); + G64(p + 0x10, ThisRecMTime); + G64(p + 0x18, ATime); + G32(p + 0x20, Attrib); + SecurityId = 0; + if (size >= 0x38) + G32(p + 0x34, SecurityId); + return true; +} + +static const UInt64 kEmptyExtent = (UInt64)(Int64)-1; + +struct CExtent +{ + UInt64 Virt; + UInt64 Phy; + + bool IsEmpty() const { return Phy == kEmptyExtent; } +}; + +struct CVolInfo +{ + Byte MajorVer; + Byte MinorVer; + // UInt16 Flags; + + bool Parse(const Byte *p, unsigned size); +}; + +bool CVolInfo::Parse(const Byte *p, unsigned size) +{ + if (size < 12) + return false; + MajorVer = p[8]; + MinorVer = p[9]; + // Flags = Get16(p + 10); + return true; +} + +struct CAttr +{ + UInt32 Type; + + Byte NonResident; + + // Non-Resident + Byte CompressionUnit; + + // UInt32 Len; + UString2 Name; + // UInt16 Flags; + // UInt16 Instance; + CByteBuffer Data; + + // Non-Resident + UInt64 LowVcn; + UInt64 HighVcn; + UInt64 AllocatedSize; + UInt64 Size; + UInt64 PackSize; + UInt64 InitializedSize; + + // Resident + // UInt16 ResidentFlags; + + bool IsCompressionUnitSupported() const { return CompressionUnit == 0 || CompressionUnit == 4; } + + UInt32 Parse(const Byte *p, unsigned size); + bool ParseFileName(CFileNameAttr &a) const { return a.Parse(Data, (unsigned)Data.Size()); } + bool ParseSi(CSiAttr &a) const { return a.Parse(Data, (unsigned)Data.Size()); } + bool ParseVolInfo(CVolInfo &a) const { return a.Parse(Data, (unsigned)Data.Size()); } + bool ParseExtents(CRecordVector &extents, UInt64 numClustersMax, unsigned compressionUnit) const; + UInt64 GetSize() const { return NonResident ? Size : Data.Size(); } + UInt64 GetPackSize() const + { + if (!NonResident) + return Data.Size(); + if (CompressionUnit != 0) + return PackSize; + return AllocatedSize; + } +}; + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + +static int CompareAttr(void *const *elem1, void *const *elem2, void *) +{ + const CAttr &a1 = *(*((const CAttr *const *)elem1)); + const CAttr &a2 = *(*((const CAttr *const *)elem2)); + RINOZ(MyCompare(a1.Type, a2.Type)) + if (a1.Name.IsEmpty()) + { + if (!a2.Name.IsEmpty()) + return -1; + } + else if (a2.Name.IsEmpty()) + return 1; + else + { + RINOZ(a1.Name.Compare(a2.Name.GetRawPtr())) + } + return MyCompare(a1.LowVcn, a2.LowVcn); +} + +UInt32 CAttr::Parse(const Byte *p, unsigned size) +{ + if (size < 4) + return 0; + G32(p, Type); + if (Type == 0xFFFFFFFF) + return 8; // required size is 4, but attributes are 8 bytes aligned. So we return 8 + if (size < 0x18) + return 0; + + PRF(printf(" T=%2X", Type)); + + UInt32 len = Get32(p + 4); + PRF(printf(" L=%3d", len)); + if (len > size) + return 0; + if ((len & 7) != 0) + return 0; + NonResident = p[8]; + { + unsigned nameLen = p[9]; + UInt32 nameOffset = Get16(p + 0x0A); + if (nameLen != 0) + { + if (nameOffset + nameLen * 2 > len) + return 0; + GetString(p + nameOffset, nameLen, Name); + PRF(printf(" N=")); + PRF_UTF16(Name); + } + } + + // G16(p + 0x0C, Flags); + // G16(p + 0x0E, Instance); + // PRF(printf(" F=%4X", Flags)); + // PRF(printf(" Inst=%d", Instance)); + + UInt32 dataSize; + UInt32 offs; + + if (NonResident) + { + if (len < 0x40) + return 0; + PRF(printf(" NR")); + G64(p + 0x10, LowVcn); + G64(p + 0x18, HighVcn); + G64(p + 0x28, AllocatedSize); + G64(p + 0x30, Size); + G64(p + 0x38, InitializedSize); + G16(p + 0x20, offs); + CompressionUnit = p[0x22]; + + PackSize = Size; + if (CompressionUnit != 0) + { + if (len < 0x48) + return 0; + G64(p + 0x40, PackSize); + PRF(printf(" PS=%I64x", PackSize)); + } + + // PRF(printf("\n")); + PRF(printf(" ASize=%4I64d", AllocatedSize)); + PRF(printf(" Size=%I64d", Size)); + PRF(printf(" IS=%I64d", InitializedSize)); + PRF(printf(" Low=%I64d", LowVcn)); + PRF(printf(" High=%I64d", HighVcn)); + PRF(printf(" CU=%d", (unsigned)CompressionUnit)); + dataSize = len - offs; + } + else + { + if (len < 0x18) + return 0; + G32(p + 0x10, dataSize); + G16(p + 0x14, offs); + // G16(p + 0x16, ResidentFlags); + PRF(printf(" RES")); + PRF(printf(" dataSize=%3d", dataSize)); + // PRF(printf(" ResFlags=%4X", ResidentFlags)); + } + + if (offs > len || dataSize > len || len - dataSize < offs) + return 0; + + Data.CopyFrom(p + offs, dataSize); + + #ifdef SHOW_DEBUG_INFO + PRF(printf(" : ")); + for (unsigned i = 0; i < Data.Size(); i++) + { + PRF(printf(" %02X", (unsigned)Data[i])); + } + #endif + + return len; +} + + +bool CAttr::ParseExtents(CRecordVector &extents, UInt64 numClustersMax, unsigned compressionUnit) const +{ + const Byte *p = Data; + unsigned size = (unsigned)Data.Size(); + UInt64 vcn = LowVcn; + UInt64 lcn = 0; + const UInt64 highVcn1 = HighVcn + 1; + + if (LowVcn != extents.Back().Virt || highVcn1 > (UInt64)1 << 63) + return false; + + extents.DeleteBack(); + + PRF2(printf("\n# ParseExtents # LowVcn = %4I64X # HighVcn = %4I64X", LowVcn, HighVcn)); + + while (size > 0) + { + const unsigned b = *p++; + size--; + if (b == 0) + break; + unsigned num = b & 0xF; + if (num == 0 || num > 8 || num > size) + return false; + + UInt64 vSize = 0; + { + unsigned i = num; + do vSize = (vSize << 8) | p[--i]; while (i); + } + if (vSize == 0) + return false; + p += num; + size -= num; + if ((highVcn1 - vcn) < vSize) + return false; + + CExtent e; + e.Virt = vcn; + vcn += vSize; + + num = b >> 4; + if (num > 8 || num > size) + return false; + + if (num == 0) + { + // Sparse + + /* if Unit is compressed, it can have many Elements for each compressed Unit: + and last Element for unit MUST be without LCN. + Element 0: numCompressedClusters2, LCN_0 + Element 1: numCompressedClusters2, LCN_1 + ... + Last Element : (16 - total_clusters_in_previous_elements), no LCN + */ + + // sparse is not allowed for (compressionUnit == 0) ? Why ? + if (compressionUnit == 0) + return false; + + e.Phy = kEmptyExtent; + } + else + { + Int64 v = (signed char)p[num - 1]; + { + for (unsigned i = num - 1; i != 0;) + v = (v << 8) | p[--i]; + } + p += num; + size -= num; + lcn = (UInt64)((Int64)lcn + v); + if (lcn > numClustersMax) + return false; + e.Phy = lcn; + } + + extents.Add(e); + } + + CExtent e; + e.Phy = kEmptyExtent; + e.Virt = vcn; + extents.Add(e); + return (highVcn1 == vcn); +} + + +static const UInt64 kEmptyTag = (UInt64)(Int64)-1; + +static const unsigned kNumCacheChunksLog = 1; +static const size_t kNumCacheChunks = (size_t)1 << kNumCacheChunksLog; + +Z7_CLASS_IMP_IInStream( + CInStream +) + UInt64 _virtPos; + UInt64 _physPos; + UInt64 _curRem; + bool _sparseMode; +public: + bool InUse; +private: + unsigned _chunkSizeLog; + CByteBuffer _inBuf; + CByteBuffer _outBuf; +public: + UInt64 Size; + UInt64 InitializedSize; + unsigned BlockSizeLog; + unsigned CompressionUnit; + CRecordVector Extents; + CMyComPtr Stream; +private: + UInt64 _tags[kNumCacheChunks]; + + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } + UInt32 GetCuSize() const { return (UInt32)1 << (BlockSizeLog + CompressionUnit); } +public: + HRESULT InitAndSeek(unsigned compressionUnit) + { + CompressionUnit = compressionUnit; + _chunkSizeLog = BlockSizeLog + CompressionUnit; + if (compressionUnit != 0) + { + UInt32 cuSize = GetCuSize(); + _inBuf.Alloc(cuSize); + _outBuf.Alloc(kNumCacheChunks << _chunkSizeLog); + } + for (size_t i = 0; i < kNumCacheChunks; i++) + _tags[i] = kEmptyTag; + + _sparseMode = false; + _curRem = 0; + _virtPos = 0; + _physPos = 0; + const CExtent &e = Extents[0]; + if (!e.IsEmpty()) + _physPos = e.Phy << BlockSizeLog; + return SeekToPhys(); + } +}; + +static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte *src, size_t srcLen) +{ + size_t destSize = 0; + while (destSize < destLen) + { + if (srcLen < 2 || (destSize & 0xFFF) != 0) + break; + UInt32 comprSize; + { + const UInt32 v = Get16(src); + if (v == 0) + break; + src += 2; + srcLen -= 2; + comprSize = (v & 0xFFF) + 1; + if (comprSize > srcLen) + break; + srcLen -= comprSize; + if ((v & 0x8000) == 0) + { + if (comprSize != (1 << 12)) + break; + memcpy(dest + destSize, src, comprSize); + src += comprSize; + destSize += comprSize; + continue; + } + } + { + if (destSize + (1 << 12) > outBufLim || (src[0] & 1) != 0) + return 0; + unsigned numDistBits = 4; + UInt32 sbOffset = 0; + UInt32 pos = 0; + + do + { + comprSize--; + for (UInt32 mask = src[pos++] | 0x100; mask > 1 && comprSize > 0; mask >>= 1) + { + if ((mask & 1) == 0) + { + if (sbOffset >= (1 << 12)) + return 0; + dest[destSize++] = src[pos++]; + sbOffset++; + comprSize--; + } + else + { + if (comprSize < 2) + return 0; + const UInt32 v = Get16(src + pos); + pos += 2; + comprSize -= 2; + + while (((sbOffset - 1) >> numDistBits) != 0) + numDistBits++; + + UInt32 len = (v & (0xFFFF >> numDistBits)) + 3; + if (sbOffset + len > (1 << 12)) + return 0; + UInt32 dist = (v >> (16 - numDistBits)); + if (dist >= sbOffset) + return 0; + const size_t offs = 1 + dist; + Byte *p = dest + destSize - offs; + destSize += len; + sbOffset += len; + const Byte *lim = p + len; + p[offs] = *p; ++p; + p[offs] = *p; ++p; + do + p[offs] = *p; + while (++p != lim); + } + } + } + while (comprSize > 0); + src += pos; + } + } + return destSize; +} + +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= Size) + return (Size == _virtPos) ? S_OK: E_FAIL; + if (size == 0) + return S_OK; + { + const UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + + if (_virtPos >= InitializedSize) + { + memset((Byte *)data, 0, size); + _virtPos += size; + *processedSize = size; + return S_OK; + } + + { + const UInt64 rem = InitializedSize - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + + while (_curRem == 0) + { + const UInt64 cacheTag = _virtPos >> _chunkSizeLog; + const size_t cacheIndex = (size_t)cacheTag & (kNumCacheChunks - 1); + + if (_tags[cacheIndex] == cacheTag) + { + const size_t chunkSize = (size_t)1 << _chunkSizeLog; + const size_t offset = (size_t)_virtPos & (chunkSize - 1); + size_t cur = chunkSize - offset; + if (cur > size) + cur = size; + memcpy(data, _outBuf + (cacheIndex << _chunkSizeLog) + offset, cur); + *processedSize = (UInt32)cur; + _virtPos += cur; + return S_OK; + } + + PRF2(printf("\nVirtPos = %6d", _virtPos)); + + const UInt32 comprUnitSize = (UInt32)1 << CompressionUnit; + const UInt64 virtBlock = _virtPos >> BlockSizeLog; + const UInt64 virtBlock2 = virtBlock & ~((UInt64)comprUnitSize - 1); + + unsigned left = 0, right = Extents.Size(); + for (;;) + { + unsigned mid = (left + right) / 2; + if (mid == left) + break; + if (virtBlock2 < Extents[mid].Virt) + right = mid; + else + left = mid; + } + + bool isCompressed = false; + const UInt64 virtBlock2End = virtBlock2 + comprUnitSize; + if (CompressionUnit != 0) + for (unsigned i = left; i < Extents.Size(); i++) + { + const CExtent &e = Extents[i]; + if (e.Virt >= virtBlock2End) + break; + if (e.IsEmpty()) + { + isCompressed = true; + break; + } + } + + unsigned i; + for (i = left; Extents[i + 1].Virt <= virtBlock; i++); + + _sparseMode = false; + if (!isCompressed) + { + const CExtent &e = Extents[i]; + UInt64 newPos = (e.Phy << BlockSizeLog) + _virtPos - (e.Virt << BlockSizeLog); + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + UInt64 next = Extents[i + 1].Virt; + if (next > virtBlock2End) + next &= ~((UInt64)comprUnitSize - 1); + next <<= BlockSizeLog; + if (next > Size) + next = Size; + _curRem = next - _virtPos; + break; + } + + bool thereArePhy = false; + + for (unsigned i2 = left; i2 < Extents.Size(); i2++) + { + const CExtent &e = Extents[i2]; + if (e.Virt >= virtBlock2End) + break; + if (!e.IsEmpty()) + { + thereArePhy = true; + break; + } + } + + if (!thereArePhy) + { + _curRem = (Extents[i + 1].Virt << BlockSizeLog) - _virtPos; + _sparseMode = true; + break; + } + + size_t offs = 0; + UInt64 curVirt = virtBlock2; + + for (i = left; i < Extents.Size(); i++) + { + const CExtent &e = Extents[i]; + if (e.IsEmpty()) + break; + if (e.Virt >= virtBlock2End) + return S_FALSE; + const UInt64 newPos = (e.Phy + (curVirt - e.Virt)) << BlockSizeLog; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + UInt64 numChunks = Extents[i + 1].Virt - curVirt; + if (curVirt + numChunks > virtBlock2End) + numChunks = virtBlock2End - curVirt; + const size_t compressed = (size_t)numChunks << BlockSizeLog; + RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed)) + curVirt += numChunks; + _physPos += compressed; + offs += compressed; + } + + const size_t destLenMax = GetCuSize(); + size_t destLen = destLenMax; + const UInt64 rem = Size - (virtBlock2 << BlockSizeLog); + if (destLen > rem) + destLen = (size_t)rem; + + Byte *dest = _outBuf + (cacheIndex << _chunkSizeLog); + const size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs); + _tags[cacheIndex] = cacheTag; + + // some files in Vista have destSize > destLen + if (destSizeRes < destLen) + { + memset(dest, 0, destLenMax); + if (InUse) + return S_FALSE; + } + } + + if (size > _curRem) + size = (UInt32)_curRem; + HRESULT res = S_OK; + if (_sparseMode) + memset(data, 0, size); + else + { + res = Stream->Read(data, size, &size); + _physPos += size; + } + if (processedSize) + *processedSize = size; + _virtPos += size; + _curRem -= size; + return res; +} + +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (_virtPos != (UInt64)offset) + { + _curRem = 0; + _virtPos = (UInt64)offset; + } + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + +static HRESULT DataParseExtents(unsigned clusterSizeLog, const CObjectVector &attrs, + unsigned attrIndex, unsigned attrIndexLim, UInt64 numPhysClusters, CRecordVector &Extents) +{ + { + CExtent e; + e.Virt = 0; + e.Phy = kEmptyExtent; + Extents.Add(e); + } + + const CAttr &attr0 = attrs[attrIndex]; + + /* + if (attrs[attrIndexLim - 1].HighVcn + 1 != (attr0.AllocatedSize >> clusterSizeLog)) + { + } + */ + + if (attr0.AllocatedSize < attr0.Size || + (attrs[attrIndexLim - 1].HighVcn + 1) != (attr0.AllocatedSize >> clusterSizeLog) || + (attr0.AllocatedSize & ((1 << clusterSizeLog) - 1)) != 0) + return S_FALSE; + + for (unsigned i = attrIndex; i < attrIndexLim; i++) + if (!attrs[i].ParseExtents(Extents, numPhysClusters, attr0.CompressionUnit)) + return S_FALSE; + + UInt64 packSizeCalc = 0; + FOR_VECTOR (k, Extents) + { + CExtent &e = Extents[k]; + if (!e.IsEmpty()) + packSizeCalc += (Extents[k + 1].Virt - e.Virt) << clusterSizeLog; + PRF2(printf("\nSize = %4I64X", Extents[k + 1].Virt - e.Virt)); + PRF2(printf(" Pos = %4I64X", e.Phy)); + } + + if (attr0.CompressionUnit != 0) + { + if (packSizeCalc != attr0.PackSize) + return S_FALSE; + } + else + { + if (packSizeCalc != attr0.AllocatedSize) + return S_FALSE; + } + return S_OK; +} + +struct CDataRef +{ + unsigned Start; + unsigned Num; +}; + +static const UInt32 kMagic_FILE = 0x454C4946; +static const UInt32 kMagic_BAAD = 0x44414142; + +// 22.02: we support some rare case magic values: +static const UInt32 kMagic_INDX = 0x58444e49; +static const UInt32 kMagic_HOLE = 0x454c4f48; +static const UInt32 kMagic_RSTR = 0x52545352; +static const UInt32 kMagic_RCRD = 0x44524352; +static const UInt32 kMagic_CHKD = 0x444b4843; +static const UInt32 kMagic_FFFFFFFF = 0xFFFFFFFF; + + +struct CMftRec +{ + UInt32 Magic; + // UInt64 Lsn; + UInt16 SeqNumber; // Number of times this mft record has been reused + UInt16 Flags; + // UInt16 LinkCount; + // UInt16 NextAttrInstance; + CMftRef BaseMftRef; + // UInt32 ThisRecNumber; + + UInt32 MyNumNameLinks; + int MyItemIndex; // index in Items[] of main item for that record, or -1 if there is no item for that record + + CObjectVector DataAttrs; + CObjectVector FileNames; + CRecordVector DataRefs; + // CAttr SecurityAttr; + + CSiAttr SiAttr; + + CByteBuffer ReparseData; + + int FindWin32Name_for_DosName(unsigned dosNameIndex) const + { + const CFileNameAttr &cur = FileNames[dosNameIndex]; + if (cur.IsDos()) + for (unsigned i = 0; i < FileNames.Size(); i++) + { + const CFileNameAttr &next = FileNames[i]; + if (next.IsWin32() && cur.ParentDirRef.Val == next.ParentDirRef.Val) + return (int)i; + } + return -1; + } + + int FindDosName(unsigned nameIndex) const + { + const CFileNameAttr &cur = FileNames[nameIndex]; + if (cur.IsWin32()) + for (unsigned i = 0; i < FileNames.Size(); i++) + { + const CFileNameAttr &next = FileNames[i]; + if (next.IsDos() && cur.ParentDirRef.Val == next.ParentDirRef.Val) + return (int)i; + } + return -1; + } + + /* + bool IsAltStream(int dataIndex) const + { + return dataIndex >= 0 && ( + (IsDir() || + !DataAttrs[DataRefs[dataIndex].Start].Name.IsEmpty())); + } + */ + + void MoveAttrsFrom(CMftRec &src) + { + DataAttrs += src.DataAttrs; + FileNames += src.FileNames; + src.DataAttrs.ClearAndFree(); + src.FileNames.ClearAndFree(); + } + + UInt64 GetPackSize() const + { + UInt64 res = 0; + FOR_VECTOR (i, DataRefs) + res += DataAttrs[DataRefs[i].Start].GetPackSize(); + return res; + } + + bool Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 recNumber, CObjectVector *attrs); + + bool Is_Magic_Empty() const + { + // what exact Magic values are possible for empty and unused records? + const UInt32 k_Magic_Unused_MAX = 5; // 22.02 + return (Magic <= k_Magic_Unused_MAX); + } + bool Is_Magic_FILE() const { return (Magic == kMagic_FILE); } + // bool Is_Magic_BAAD() const { return (Magic == kMagic_BAAD); } + bool Is_Magic_CanIgnore() const + { + return Is_Magic_Empty() + || Magic == kMagic_BAAD + || Magic == kMagic_INDX + || Magic == kMagic_HOLE + || Magic == kMagic_RSTR + || Magic == kMagic_RCRD + || Magic == kMagic_CHKD + || Magic == kMagic_FFFFFFFF; + } + + bool InUse() const { return (Flags & 1) != 0; } + bool IsDir() const { return (Flags & 2) != 0; } + + void ParseDataNames(); + HRESULT GetStream(IInStream *mainStream, int dataIndex, + unsigned clusterSizeLog, UInt64 numPhysClusters, IInStream **stream) const; + unsigned GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 numPhysClusters) const; + + UInt64 GetSize(unsigned dataIndex) const { return DataAttrs[DataRefs[dataIndex].Start].GetSize(); } + + CMftRec(): + SeqNumber(0), + Flags(0), + MyNumNameLinks(0), + MyItemIndex(-1) {} +}; + +void CMftRec::ParseDataNames() +{ + DataRefs.Clear(); + DataAttrs.Sort(CompareAttr, NULL); + + for (unsigned i = 0; i < DataAttrs.Size();) + { + CDataRef ref; + ref.Start = i; + for (i++; i < DataAttrs.Size(); i++) + if (DataAttrs[ref.Start].Name != DataAttrs[i].Name) + break; + ref.Num = i - ref.Start; + DataRefs.Add(ref); + } +} + +HRESULT CMftRec::GetStream(IInStream *mainStream, int dataIndex, + unsigned clusterSizeLog, UInt64 numPhysClusters, IInStream **destStream) const +{ + *destStream = NULL; + CBufferInStream *streamSpec = new CBufferInStream; + CMyComPtr streamTemp = streamSpec; + + if (dataIndex >= 0) + if ((unsigned)dataIndex < DataRefs.Size()) + { + const CDataRef &ref = DataRefs[dataIndex]; + unsigned numNonResident = 0; + unsigned i; + for (i = ref.Start; i < ref.Start + ref.Num; i++) + if (DataAttrs[i].NonResident) + numNonResident++; + + const CAttr &attr0 = DataAttrs[ref.Start]; + + if (numNonResident != 0 || ref.Num != 1) + { + if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported()) + return S_FALSE; + CInStream *ss = new CInStream; + CMyComPtr streamTemp2 = ss; + RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, ss->Extents)) + ss->Size = attr0.Size; + ss->InitializedSize = attr0.InitializedSize; + ss->Stream = mainStream; + ss->BlockSizeLog = clusterSizeLog; + ss->InUse = InUse(); + RINOK(ss->InitAndSeek(attr0.CompressionUnit)) + *destStream = streamTemp2.Detach(); + return S_OK; + } + + streamSpec->Buf = attr0.Data; + } + + streamSpec->Init(); + *destStream = streamTemp.Detach(); + return S_OK; +} + +unsigned CMftRec::GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 numPhysClusters) const +{ + if (dataIndex < 0) + return 0; + { + const CDataRef &ref = DataRefs[dataIndex]; + unsigned numNonResident = 0; + unsigned i; + for (i = ref.Start; i < ref.Start + ref.Num; i++) + if (DataAttrs[i].NonResident) + numNonResident++; + + const CAttr &attr0 = DataAttrs[ref.Start]; + + if (numNonResident != 0 || ref.Num != 1) + { + if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported()) + return 0; // error; + CRecordVector extents; + if (DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + ref.Num, numPhysClusters, extents) != S_OK) + return 0; // error; + return extents.Size() - 1; + } + // if (attr0.Data.Size() != 0) + // return 1; + return 0; + } +} + +bool CMftRec::Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 recNumber, + CObjectVector *attrs) +{ + G32(p, Magic); + if (!Is_Magic_FILE()) + return Is_Magic_CanIgnore(); + + { + UInt32 usaOffset; + UInt32 numUsaItems; + G16(p + 0x04, usaOffset); + G16(p + 0x06, numUsaItems); + + /* NTFS stores (usn) to 2 last bytes in each sector (before writing record to disk). + Original values of these two bytes are stored in table. + So we restore original data from table */ + + if ((usaOffset & 1) != 0 + || usaOffset + numUsaItems * 2 > ((UInt32)1 << sectorSizeLog) - 2 + || numUsaItems == 0 + || numUsaItems - 1 != numSectors) + return false; + + if (usaOffset >= 0x30) // NTFS 3.1+ + { + UInt32 iii = Get32(p + 0x2C); + if (iii != recNumber) + { + // ntfs-3g probably writes 0 (that probably is incorrect value) to this field for unused records. + // so we support that "bad" case. + if (iii != 0) + return false; + } + } + + UInt16 usn = Get16(p + usaOffset); + // PRF(printf("\nusn = %d", usn)); + for (UInt32 i = 1; i < numUsaItems; i++) + { + void *pp = p + (i << sectorSizeLog) - 2; + if (Get16(pp) != usn) + return false; + SetUi16(pp, Get16(p + usaOffset + i * 2)) + } + } + + // G64(p + 0x08, Lsn); + G16(p + 0x10, SeqNumber); + // G16(p + 0x12, LinkCount); + // PRF(printf(" L=%d", LinkCount)); + const UInt32 attrOffs = Get16(p + 0x14); + G16(p + 0x16, Flags); + PRF(printf(" F=%4X", Flags)); + + const UInt32 bytesInUse = Get32(p + 0x18); + const UInt32 bytesAlloc = Get32(p + 0x1C); + G64(p + 0x20, BaseMftRef.Val); + if (BaseMftRef.Val != 0) + { + PRF(printf(" BaseRef=%d", (int)BaseMftRef.Val)); + // return false; // Check it; + } + // G16(p + 0x28, NextAttrInstance); + + UInt32 limit = numSectors << sectorSizeLog; + if (attrOffs >= limit + || (attrOffs & 7) != 0 + || (bytesInUse & 7) != 0 + || bytesInUse > limit + || bytesAlloc != limit) + return false; + + limit = bytesInUse; + + for (UInt32 t = attrOffs;;) + { + if (t >= limit) + return false; + + CAttr attr; + // PRF(printf("\n %2d:", Attrs.Size())); + PRF(printf("\n")); + UInt32 len = attr.Parse(p + t, limit - t); + if (len == 0 || limit - t < len) + return false; + t += len; + if (attr.Type == 0xFFFFFFFF) + { + if (t != limit) + return false; + break; + } + switch (attr.Type) + { + case ATTR_TYPE_FILE_NAME: + { + CFileNameAttr fna; + if (!attr.ParseFileName(fna)) + return false; + FileNames.Add(fna); + PRF(printf(" flags = %4x\n ", (int)fna.NameType)); + PRF_UTF16(fna.Name); + break; + } + case ATTR_TYPE_STANDARD_INFO: + if (!attr.ParseSi(SiAttr)) + return false; + break; + case ATTR_TYPE_DATA: + DataAttrs.Add(attr); + break; + case ATTR_TYPE_REPARSE_POINT: + ReparseData = attr.Data; + break; + /* + case ATTR_TYPE_SECURITY_DESCRIPTOR: + SecurityAttr = attr; + break; + */ + default: + if (attrs) + attrs->Add(attr); + break; + } + } + + return true; +} + +/* + NTFS probably creates empty DATA_ATTRIBUTE for empty file, + But it doesn't do it for + $Secure (:$SDS), + $Extend\$Quota + $Extend\$ObjId + $Extend\$Reparse +*/ + +static const int k_Item_DataIndex_IsEmptyFile = -1; // file without unnamed data stream +static const int k_Item_DataIndex_IsDir = -2; + +// static const int k_ParentFolderIndex_Root = -1; +static const int k_ParentFolderIndex_Lost = -2; +static const int k_ParentFolderIndex_Deleted = -3; + +struct CItem +{ + unsigned RecIndex; // index in Recs array + unsigned NameIndex; // index in CMftRec::FileNames + + int DataIndex; /* index in CMftRec::DataRefs + -1: file without unnamed data stream + -2: for directories */ + + int ParentFolder; /* index in Items array + -1: for root items + -2: [LOST] folder + -3: [UNKNOWN] folder (deleted lost) */ + int ParentHost; /* index in Items array, if it's AltStream + -1: if it's not AltStream */ + + CItem(): DataIndex(k_Item_DataIndex_IsDir), ParentFolder(-1), ParentHost(-1) {} + + bool IsAltStream() const { return ParentHost != -1; } + bool IsDir() const { return DataIndex == k_Item_DataIndex_IsDir; } + // check it !!! + // probably NTFS for empty file still creates empty DATA_ATTRIBUTE + // But it doesn't do it for $Secure:$SDS +}; + +struct CDatabase +{ + CRecordVector Items; + CObjectVector Recs; + CMyComPtr InStream; + CHeader Header; + UInt64 PhySize; + + IArchiveOpenCallback *OpenCallback; + + CByteBuffer ByteBuf; + + CObjectVector VolAttrs; + + CByteBuffer SecurData; + CRecordVector SecurOffsets; + + // bool _headerWarning; + bool ThereAreAltStreams; + + bool _showSystemFiles; + bool _showDeletedFiles; + CObjectVector VirtFolderNames; + UString EmptyString; + + int _systemFolderIndex; + int _lostFolderIndex_Normal; + int _lostFolderIndex_Deleted; + + void InitProps() + { + _showSystemFiles = true; + // we show SystemFiles by default since it's difficult to track $Extend\* system files + // it must be fixed later + _showDeletedFiles = false; + } + + CDatabase() { InitProps(); } + ~CDatabase() { ClearAndClose(); } + + void Clear(); + void ClearAndClose(); + + void GetItemPath(unsigned index, NCOM::CPropVariant &path) const; + HRESULT Open(); + + HRESULT SeekToCluster(UInt64 cluster); + + int Find_DirItem_For_MftRec(UInt64 recIndex) const + { + if (recIndex >= Recs.Size()) + return -1; + const CMftRec &rec = Recs[(unsigned)recIndex]; + if (!rec.IsDir()) + return -1; + return rec.MyItemIndex; + /* + unsigned left = 0, right = Items.Size(); + while (left != right) + { + unsigned mid = (left + right) / 2; + const CItem &item = Items[mid]; + UInt64 midValue = item.RecIndex; + if (recIndex == midValue) + { + // if item is not dir (file or alt stream we don't return it) + // if (item.DataIndex < 0) + if (item.IsDir()) + return mid; + right = mid; + } + else if (recIndex < midValue) + right = mid; + else + left = mid + 1; + } + return -1; + */ + } + + bool FindSecurityDescritor(UInt32 id, UInt64 &offset, UInt32 &size) const; + + HRESULT ParseSecuritySDS_2(); + void ParseSecuritySDS() + { + HRESULT res = ParseSecuritySDS_2(); + if (res != S_OK) + { + SecurOffsets.Clear(); + SecurData.Free(); + } + } + +}; + +HRESULT CDatabase::SeekToCluster(UInt64 cluster) +{ + return InStream_SeekSet(InStream, cluster << Header.ClusterSizeLog); +} + +void CDatabase::Clear() +{ + Items.Clear(); + Recs.Clear(); + SecurOffsets.Clear(); + SecurData.Free(); + VirtFolderNames.Clear(); + _systemFolderIndex = -1; + _lostFolderIndex_Normal = -1; + _lostFolderIndex_Deleted = -1; + ThereAreAltStreams = false; + // _headerWarning = false; + PhySize = 0; +} + +void CDatabase::ClearAndClose() +{ + Clear(); + InStream.Release(); +} + + +static void CopyName(wchar_t *dest, const wchar_t *src) +{ + for (;;) + { + wchar_t c = *src++; + // 18.06 + if (c == '\\' || c == '/') + c = '_'; + *dest++ = c; + if (c == 0) + return; + } +} + +void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const +{ + const CItem *item = &Items[index]; + unsigned size = 0; + const CMftRec &rec = Recs[item->RecIndex]; + size += rec.FileNames[item->NameIndex].Name.Len(); + + bool isAltStream = item->IsAltStream(); + + if (isAltStream) + { + const CAttr &data = rec.DataAttrs[rec.DataRefs[item->DataIndex].Start]; + if (item->RecIndex == kRecIndex_RootDir) + { + wchar_t *s = path.AllocBstr(data.Name.Len() + 1); + s[0] = L':'; + if (!data.Name.IsEmpty()) + CopyName(s + 1, data.Name.GetRawPtr()); + return; + } + + size += data.Name.Len(); + size++; + } + + for (unsigned i = 0;; i++) + { + if (i > 256) + { + path = "[TOO-LONG]"; + return; + } + const wchar_t *servName; + if (item->RecIndex < kNumSysRecs + /* && item->RecIndex != kRecIndex_RootDir */) + servName = kVirtualFolder_System; + else + { + int index2 = item->ParentFolder; + if (index2 >= 0) + { + item = &Items[index2]; + size += Recs[item->RecIndex].FileNames[item->NameIndex].Name.Len() + 1; + continue; + } + if (index2 == -1) + break; + servName = (index2 == k_ParentFolderIndex_Lost) ? + kVirtualFolder_Lost_Normal : + kVirtualFolder_Lost_Deleted; + } + size += MyStringLen(servName) + 1; + break; + } + + wchar_t *s = path.AllocBstr(size); + + item = &Items[index]; + + bool needColon = false; + if (isAltStream) + { + const UString2 &name = rec.DataAttrs[rec.DataRefs[item->DataIndex].Start].Name; + if (!name.IsEmpty()) + { + size -= name.Len(); + CopyName(s + size, name.GetRawPtr()); + } + s[--size] = ':'; + needColon = true; + } + + { + const UString2 &name = rec.FileNames[item->NameIndex].Name; + unsigned len = name.Len(); + if (len != 0) + CopyName(s + size - len, name.GetRawPtr()); + if (needColon) + s[size] = ':'; + size -= len; + } + + for (;;) + { + const wchar_t *servName; + if (item->RecIndex < kNumSysRecs + /* && && item->RecIndex != kRecIndex_RootDir */) + servName = kVirtualFolder_System; + else + { + int index2 = item->ParentFolder; + if (index2 >= 0) + { + item = &Items[index2]; + const UString2 &name = Recs[item->RecIndex].FileNames[item->NameIndex].Name; + unsigned len = name.Len(); + size--; + if (len != 0) + { + size -= len; + CopyName(s + size, name.GetRawPtr()); + } + s[size + len] = WCHAR_PATH_SEPARATOR; + continue; + } + if (index2 == -1) + break; + servName = (index2 == k_ParentFolderIndex_Lost) ? + kVirtualFolder_Lost_Normal : + kVirtualFolder_Lost_Deleted; + } + MyStringCopy(s, servName); + s[MyStringLen(servName)] = WCHAR_PATH_SEPARATOR; + break; + } +} + +bool CDatabase::FindSecurityDescritor(UInt32 item, UInt64 &offset, UInt32 &size) const +{ + offset = 0; + size = 0; + unsigned left = 0, right = SecurOffsets.Size(); + while (left != right) + { + unsigned mid = (left + right) / 2; + size_t offs = SecurOffsets[mid]; + UInt32 midValue = Get32(((const Byte *)SecurData) + offs + 4); + if (item == midValue) + { + offset = Get64((const Byte *)SecurData + offs + 8) + 20; + size = Get32((const Byte *)SecurData + offs + 16) - 20; + return true; + } + if (item < midValue) + right = mid; + else + left = mid + 1; + } + return false; +} + +/* +static int CompareIDs(const size_t *p1, const size_t *p2, void *data) +{ + UInt32 id1 = Get32(((const Byte *)data) + *p1 + 4); + UInt32 id2 = Get32(((const Byte *)data) + *p2 + 4); + return MyCompare(id1, id2); +} +*/ + +// security data contains duplication copy after each 256 KB. +static const unsigned kSecureDuplicateStepBits = 18; + +HRESULT CDatabase::ParseSecuritySDS_2() +{ + const Byte *p = SecurData; + size_t size = SecurData.Size(); + const size_t kDuplicateStep = (size_t)1 << kSecureDuplicateStepBits; + const size_t kDuplicateMask = kDuplicateStep - 1; + size_t lim = MyMin(size, kDuplicateStep); + UInt32 idPrev = 0; + for (size_t pos = 0; pos < size && size - pos >= 20;) + { + UInt32 id = Get32(p + pos + 4); + UInt64 offs = Get64(p + pos + 8); + UInt32 entrySize = Get32(p + pos + 16); + if (offs == pos && entrySize >= 20 && lim - pos >= entrySize) + { + if (id <= idPrev) + return S_FALSE; + idPrev = id; + SecurOffsets.Add(pos); + pos += entrySize; + pos = (pos + 0xF) & ~(size_t)0xF; + if ((pos & kDuplicateMask) != 0) + continue; + } + else + pos = (pos + kDuplicateStep) & ~kDuplicateMask; + pos += kDuplicateStep; + lim = pos + kDuplicateStep; + if (lim >= size) + lim = size; + } + // we checked that IDs are sorted, so we don't need Sort + // SecurOffsets.Sort(CompareIDs, (void *)p); + return S_OK; +} + +HRESULT CDatabase::Open() +{ + Clear(); + + /* NTFS layout: + 1) main part (as specified by NumClusters). Only that part is available, if we open "\\.\c:" + 2) additional empty sectors (as specified by NumSectors) + 3) the copy of first sector (boot sector) + + We support both cases: + - the file with only main part + - full file (as raw data on partition), including the copy + of first sector (boot sector) at the end of data + + We don't support the case, when only the copy of boot sector + at the end was detected as NTFS signature. + */ + + { + const UInt32 kHeaderSize = 512; + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(InStream, buf, kHeaderSize)) + if (!Header.Parse(buf)) + return S_FALSE; + + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(InStream, fileSize)) + PhySize = Header.GetPhySize_Clusters(); + if (fileSize < PhySize) + return S_FALSE; + + UInt64 phySizeMax = Header.GetPhySize_Max(); + if (fileSize >= phySizeMax) + { + RINOK(InStream_SeekSet(InStream, Header.NumSectors << Header.SectorSizeLog)) + Byte buf2[kHeaderSize]; + if (ReadStream_FALSE(InStream, buf2, kHeaderSize) == S_OK) + { + if (memcmp(buf, buf2, kHeaderSize) == 0) + PhySize = phySizeMax; + // else _headerWarning = true; + } + } + } + + SeekToCluster(Header.MftCluster); + + // we use ByteBuf for records reading. + // so the size of ByteBuf must be >= mftRecordSize + const size_t recSize = (size_t)1 << Header.MftRecordSizeLog; + const size_t kBufSize = MyMax((size_t)(1 << 15), recSize); + ByteBuf.Alloc(kBufSize); + RINOK(ReadStream_FALSE(InStream, ByteBuf, recSize)) + { + const UInt32 allocSize = Get32(ByteBuf + 0x1C); + if (allocSize != recSize) + return S_FALSE; + } + // MftRecordSizeLog >= SectorSizeLog + const UInt32 numSectorsInRec = 1u << (Header.MftRecordSizeLog - Header.SectorSizeLog); + CMyComPtr mftStream; + CMftRec mftRec; + { + if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, 0, NULL)) + return S_FALSE; + if (!mftRec.Is_Magic_FILE()) + return S_FALSE; + mftRec.ParseDataNames(); + if (mftRec.DataRefs.IsEmpty()) + return S_FALSE; + RINOK(mftRec.GetStream(InStream, 0, Header.ClusterSizeLog, Header.NumClusters, &mftStream)) + if (!mftStream) + return S_FALSE; + } + + // CObjectVector SecurityAttrs; + + const UInt64 mftSize = mftRec.DataAttrs[0].Size; + if ((mftSize >> 4) > Header.GetPhySize_Clusters()) + return S_FALSE; + + { + const UInt64 numFiles = mftSize >> Header.MftRecordSizeLog; + if (numFiles > (1 << 30)) + return S_FALSE; + if (OpenCallback) + { + RINOK(OpenCallback->SetTotal(&numFiles, &mftSize)) + } + Recs.ClearAndReserve((unsigned)numFiles); + } + + for (UInt64 pos64 = 0;;) + { + if (OpenCallback) + { + const UInt64 numFiles = Recs.Size(); + if ((numFiles & 0x3FFF) == 0) + { + RINOK(OpenCallback->SetCompleted(&numFiles, &pos64)) + } + } + size_t readSize = kBufSize; + { + const UInt64 rem = mftSize - pos64; + if (readSize > rem) + readSize = (size_t)rem; + } + if (readSize < recSize) + break; + RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize)) + pos64 += readSize; + + for (size_t i = 0; readSize >= recSize; i += recSize, readSize -= recSize) + { + PRF(printf("\n---------------------")); + PRF(printf("\n%5d:", Recs.Size())); + + Byte *p = ByteBuf + i; + CMftRec rec; + + CObjectVector *attrs = NULL; + unsigned recIndex = Recs.Size(); + switch (recIndex) + { + case kRecIndex_Volume: attrs = &VolAttrs; break; + // case kRecIndex_Security: attrs = &SecurityAttrs; break; + } + + if (!rec.Parse(p, Header.SectorSizeLog, numSectorsInRec, (UInt32)Recs.Size(), attrs)) + return S_FALSE; + Recs.Add(rec); + } + } + + /* + // that code looks too complex. And we can get security info without index parsing + for (i = 0; i < SecurityAttrs.Size(); i++) + { + const CAttr &attr = SecurityAttrs[i]; + if (attr.Name.IsEqualTo("$SII")) + { + if (attr.Type == ATTR_TYPE_INDEX_ROOT) + { + const Byte *data = attr.Data; + size_t size = attr.Data.Size(); + + // Index Root + UInt32 attrType = Get32(data); + UInt32 collationRule = Get32(data + 4); + UInt32 indexAllocationEtrySizeSize = Get32(data + 8); + UInt32 clustersPerIndexRecord = Get32(data + 0xC); + data += 0x10; + + // Index Header + UInt32 firstEntryOffset = Get32(data); + UInt32 totalSize = Get32(data + 4); + UInt32 allocSize = Get32(data + 8); + UInt32 flags = Get32(data + 0xC); + + int num = 0; + for (int j = 0 ; j < num; j++) + { + if (Get32(data) != 0x1414 || // offset and size + Get32(data + 4) != 0 || + Get32(data + 8) != 0x428) // KeySize / EntrySize + break; + UInt32 flags = Get32(data + 12); + UInt32 id = Get32(data + 0x10); + if (id = Get32(data + 0x18)) + break; + UInt32 descriptorOffset = Get64(data + 0x1C); + UInt32 descriptorSize = Get64(data + 0x24); + data += 0x28; + } + // break; + } + } + } + */ + + unsigned i; + + for (i = 0; i < Recs.Size(); i++) + { + CMftRec &rec = Recs[i]; + if (!rec.Is_Magic_FILE()) + continue; + + if (!rec.BaseMftRef.IsBaseItself()) + { + const UInt64 refIndex = rec.BaseMftRef.GetIndex(); + if (refIndex >= Recs.Size()) + return S_FALSE; + CMftRec &refRec = Recs[(unsigned)refIndex]; + if (!refRec.Is_Magic_FILE()) + continue; + + bool moveAttrs = (refRec.SeqNumber == rec.BaseMftRef.GetNumber() && refRec.BaseMftRef.IsBaseItself()); + if (rec.InUse() && refRec.InUse()) + { + if (!moveAttrs) + return S_FALSE; + } + else if (rec.InUse() || refRec.InUse()) + moveAttrs = false; + if (moveAttrs) + refRec.MoveAttrsFrom(rec); + } + } + + for (i = 0; i < Recs.Size(); i++) + { + CMftRec &rec = Recs[i]; + if (!rec.Is_Magic_FILE()) + continue; + rec.ParseDataNames(); + } + + for (i = 0; i < Recs.Size(); i++) + { + CMftRec &rec = Recs[i]; + if (!rec.Is_Magic_FILE() || !rec.BaseMftRef.IsBaseItself()) + continue; + if (i < kNumSysRecs && !_showSystemFiles) + continue; + if (!rec.InUse() && !_showDeletedFiles) + continue; + + rec.MyNumNameLinks = rec.FileNames.Size(); + + // printf("\n%4d: ", i); + + /* Actually DataAttrs / DataRefs are sorted by name. + It can not be more than one unnamed stream in DataRefs + And indexOfUnnamedStream <= 0. + */ + + int indexOfUnnamedStream = -1; + if (!rec.IsDir()) + { + FOR_VECTOR (di, rec.DataRefs) + if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty()) + { + indexOfUnnamedStream = (int)di; + break; + } + } + + if (rec.FileNames.IsEmpty()) + { + bool needShow = true; + if (i < kNumSysRecs) + { + needShow = false; + FOR_VECTOR (di, rec.DataRefs) + if (rec.GetSize(di) != 0) + { + needShow = true; + break; + } + } + if (needShow) + { + CFileNameAttr &fna = rec.FileNames.AddNew(); + // we set incorrect ParentDirRef, that will place item to [LOST] folder + fna.ParentDirRef.Val = (UInt64)(Int64)-1; + char s[16 + 16]; + ConvertUInt32ToString(i, MyStpCpy(s, "[NONAME]-")); + fna.Name.SetFromAscii(s); + fna.NameType = kFileNameType_Win32Dos; + fna.Attrib = 0; + } + } + + // bool isMainName = true; + + FOR_VECTOR (t, rec.FileNames) + { + #ifdef SHOW_DEBUG_INFO + const CFileNameAttr &fna = rec.FileNames[t]; + #endif + PRF(printf("\n %4d ", (int)fna.NameType)); + PRF_UTF16(fna.Name); + // PRF(printf(" | ")); + + if (rec.FindWin32Name_for_DosName(t) >= 0) + { + rec.MyNumNameLinks--; + continue; + } + + CItem item; + item.NameIndex = t; + item.RecIndex = i; + item.DataIndex = rec.IsDir() ? + k_Item_DataIndex_IsDir : + (indexOfUnnamedStream < 0 ? + k_Item_DataIndex_IsEmptyFile : + indexOfUnnamedStream); + + if (rec.MyItemIndex < 0) + rec.MyItemIndex = (int)Items.Size(); + item.ParentHost = (int)Items.Add(item); + + /* we can use that code to reduce the number of alt streams: + it will not show how alt streams for hard links. */ + // if (!isMainName) continue; isMainName = false; + + // unsigned numAltStreams = 0; + + FOR_VECTOR (di, rec.DataRefs) + { + if (!rec.IsDir() && (int)di == indexOfUnnamedStream) + continue; + + const UString2 &subName = rec.DataAttrs[rec.DataRefs[di].Start].Name; + + PRF(printf("\n alt stream: ")); + PRF_UTF16(subName); + + { + // $BadClus:$Bad is sparse file for all clusters. So we skip it. + if (i == kRecIndex_BadClus && subName == L"$Bad") + continue; + } + + // numAltStreams++; + ThereAreAltStreams = true; + item.DataIndex = (int)di; + Items.Add(item); + } + } + } + + if (Recs.Size() > kRecIndex_Security) + { + const CMftRec &rec = Recs[kRecIndex_Security]; + FOR_VECTOR (di, rec.DataRefs) + { + const CAttr &attr = rec.DataAttrs[rec.DataRefs[di].Start]; + if (attr.Name == L"$SDS") + { + CMyComPtr sdsStream; + RINOK(rec.GetStream(InStream, (int)di, Header.ClusterSizeLog, Header.NumClusters, &sdsStream)) + if (sdsStream) + { + const UInt64 size64 = attr.GetSize(); + if (size64 < (UInt32)1 << 29) + { + size_t size = (size_t)size64; + if ((((size + 1) >> kSecureDuplicateStepBits) & 1) != 0) + { + size -= (1 << kSecureDuplicateStepBits); + SecurData.Alloc(size); + if (ReadStream_FALSE(sdsStream, SecurData, size) == S_OK) + { + ParseSecuritySDS(); + break; + } + } + } + } + break; + } + } + } + + bool thereAreUnknownFolders_Normal = false; + bool thereAreUnknownFolders_Deleted = false; + + for (i = 0; i < Items.Size(); i++) + { + CItem &item = Items[i]; + const CMftRec &rec = Recs[item.RecIndex]; + const CFileNameAttr &fn = rec.FileNames[item.NameIndex]; + const CMftRef &parentDirRef = fn.ParentDirRef; + const UInt64 refIndex = parentDirRef.GetIndex(); + if (refIndex == kRecIndex_RootDir) + item.ParentFolder = -1; + else + { + int index = Find_DirItem_For_MftRec(refIndex); + if (index < 0 || + Recs[Items[index].RecIndex].SeqNumber != parentDirRef.GetNumber()) + { + if (Recs[item.RecIndex].InUse()) + { + thereAreUnknownFolders_Normal = true; + index = k_ParentFolderIndex_Lost; + } + else + { + thereAreUnknownFolders_Deleted = true; + index = k_ParentFolderIndex_Deleted; + } + } + item.ParentFolder = index; + } + } + + unsigned virtIndex = Items.Size(); + if (_showSystemFiles) + { + _systemFolderIndex = (int)(virtIndex++); + VirtFolderNames.Add(kVirtualFolder_System); + } + if (thereAreUnknownFolders_Normal) + { + _lostFolderIndex_Normal = (int)(virtIndex++); + VirtFolderNames.Add(kVirtualFolder_Lost_Normal); + } + if (thereAreUnknownFolders_Deleted) + { + _lostFolderIndex_Deleted = (int)(virtIndex++); + VirtFolderNames.Add(kVirtualFolder_Lost_Deleted); + } + + return S_OK; +} + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveGetRawProps, + public IInArchiveGetStream, + public ISetProperties, + public CMyUnknownImp, + public CDatabase +{ + Z7_IFACES_IMP_UNK_4( + IInArchive, + IArchiveGetRawProps, + IInArchiveGetStream, + ISetProperties) +}; + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 2; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = index == 0 ? kpidNtReparse : kpidNtSecure; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + int par = -1; + + if (index < Items.Size()) + { + const CItem &item = Items[index]; + + if (item.ParentHost >= 0) + { + *parentType = NParentType::kAltStream; + par = (item.RecIndex == kRecIndex_RootDir ? -1 : item.ParentHost); + } + else if (item.RecIndex < kNumSysRecs) + { + if (_showSystemFiles) + par = _systemFolderIndex; + } + else if (item.ParentFolder >= 0) + par = item.ParentFolder; + else if (item.ParentFolder == k_ParentFolderIndex_Lost) + par = _lostFolderIndex_Normal; + else if (item.ParentFolder == k_ParentFolderIndex_Deleted) + par = _lostFolderIndex_Deleted; + } + *parent = (UInt32)(Int32)par; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidName) + { + #ifdef MY_CPU_LE + const UString2 *s; + if (index >= Items.Size()) + s = &VirtFolderNames[index - Items.Size()]; + else + { + const CItem &item = Items[index]; + const CMftRec &rec = Recs[item.RecIndex]; + if (item.IsAltStream()) + s = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start].Name; + else + s = &rec.FileNames[item.NameIndex].Name; + } + if (s->IsEmpty()) + *data = (const wchar_t *)EmptyString; + else + *data = s->GetRawPtr(); + *dataSize = (s->Len() + 1) * (UInt32)sizeof(wchar_t); + *propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE; + #endif + return S_OK; + } + + if (propID == kpidNtReparse) + { + if (index >= Items.Size()) + return S_OK; + const CItem &item = Items[index]; + const CMftRec &rec = Recs[item.RecIndex]; + const CByteBuffer &reparse = rec.ReparseData; + + if (reparse.Size() != 0) + { + *dataSize = (UInt32)reparse.Size(); + *propType = NPropDataType::kRaw; + *data = (const Byte *)reparse; + } + } + + if (propID == kpidNtSecure) + { + if (index >= Items.Size()) + return S_OK; + const CItem &item = Items[index]; + const CMftRec &rec = Recs[item.RecIndex]; + if (rec.SiAttr.SecurityId > 0) + { + UInt64 offset; + UInt32 size; + if (FindSecurityDescritor(rec.SiAttr.SecurityId, offset, size)) + { + *dataSize = size; + *propType = NPropDataType::kRaw; + *data = (const Byte *)SecurData + offset; + } + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + if (index >= Items.Size()) + return S_OK; + IInStream *stream2; + const CItem &item = Items[index]; + const CMftRec &rec = Recs[item.RecIndex]; + HRESULT res = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &stream2); + *stream = (ISequentialInStream *)stream2; + return res; + COM_TRY_END +} + +/* +enum +{ + kpidLink2 = kpidUserDefined, + kpidLinkType, + kpidRecMTime, + kpidRecMTime2, + kpidMTime2, + kpidCTime2, + kpidATime2 +}; + +static const CStatProp kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + + // { NULL, kpidLink, VT_BSTR}, + + // { "Link 2", kpidLink2, VT_BSTR}, + // { "Link Type", kpidLinkType, VT_UI2}, + { NULL, kpidINode, VT_UI8}, + + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + + // { "Record Modified", kpidRecMTime, VT_FILETIME}, + + // { "Modified 2", kpidMTime2, VT_FILETIME}, + // { "Created 2", kpidCTime2, VT_FILETIME}, + // { "Accessed 2", kpidATime2, VT_FILETIME}, + // { "Record Modified 2", kpidRecMTime2, VT_FILETIME}, + + { NULL, kpidAttrib, VT_UI4}, + { NULL, kpidNumBlocks, VT_UI4}, + { NULL, kpidIsDeleted, VT_BOOL}, +}; +*/ + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidChangeTime, + kpidAttrib, + kpidLinks, + kpidINode, + kpidNumBlocks, + kpidNumAltStreams, + kpidIsAltStream, + kpidShortName, + kpidIsDeleted +}; + +enum +{ + kpidRecordSize = kpidUserDefined +}; + +static const CStatProp kArcProps[] = +{ + { NULL, kpidVolumeName, VT_BSTR}, + { NULL, kpidFileSystem, VT_BSTR}, + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidSectorSize, VT_UI4}, + { "MFT Record Size", kpidRecordSize, VT_UI4}, + { NULL, kpidHeadersSize, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidId, VT_UI8}, +}; + +/* +static const Byte kArcProps[] = +{ + kpidVolumeName, + kpidFileSystem, + kpidClusterSize, + kpidHeadersSize, + kpidCTime, + + kpidSectorSize, + kpidId + // kpidSectorsPerTrack, + // kpidNumHeads, + // kpidHiddenSectors +}; +*/ + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void NtfsTimeToProp(UInt64 t, NCOM::CPropVariant &prop) +{ + FILETIME ft; + ft.dwLowDateTime = (DWORD)t; + ft.dwHighDateTime = (DWORD)(t >> 32); + prop = ft; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CMftRec *volRec = (Recs.Size() > kRecIndex_Volume ? &Recs[kRecIndex_Volume] : NULL); + + switch (propID) + { + case kpidClusterSize: prop = Header.ClusterSize(); break; + case kpidPhySize: prop = PhySize; break; + /* + case kpidHeadersSize: + { + UInt64 val = 0; + for (unsigned i = 0; i < kNumSysRecs; i++) + { + printf("\n%2d: %8I64d ", i, Recs[i].GetPackSize()); + if (i == 8) + i = i + val += Recs[i].GetPackSize(); + } + prop = val; + break; + } + */ + case kpidCTime: if (volRec) NtfsTimeToProp(volRec->SiAttr.CTime, prop); break; + case kpidMTime: if (volRec) NtfsTimeToProp(volRec->SiAttr.MTime, prop); break; + case kpidShortComment: + case kpidVolumeName: + { + FOR_VECTOR (i, VolAttrs) + { + const CAttr &attr = VolAttrs[i]; + if (attr.Type == ATTR_TYPE_VOLUME_NAME) + { + UString2 name; + GetString(attr.Data, (unsigned)attr.Data.Size() / 2, name); + if (!name.IsEmpty()) + prop = name.GetRawPtr(); + break; + } + } + break; + } + case kpidFileSystem: + { + AString s ("NTFS"); + FOR_VECTOR (i, VolAttrs) + { + const CAttr &attr = VolAttrs[i]; + if (attr.Type == ATTR_TYPE_VOLUME_INFO) + { + CVolInfo vi; + if (attr.ParseVolInfo(vi)) + { + s.Add_Space(); + s.Add_UInt32(vi.MajorVer); + s.Add_Dot(); + s.Add_UInt32(vi.MinorVer); + } + break; + } + } + prop = s; + break; + } + case kpidSectorSize: prop = (UInt32)1 << Header.SectorSizeLog; break; + case kpidRecordSize: prop = (UInt32)1 << Header.MftRecordSizeLog; break; + case kpidId: prop = Header.SerialNumber; break; + + case kpidIsTree: prop = true; break; + case kpidIsDeleted: prop = _showDeletedFiles; break; + case kpidIsAltStream: prop = ThereAreAltStreams; break; + case kpidIsAux: prop = true; break; + case kpidINode: prop = true; break; + + case kpidWarning: + if (_lostFolderIndex_Normal >= 0) + prop = "There are lost files"; + break; + + /* + case kpidWarningFlags: + { + UInt32 flags = 0; + if (_headerWarning) + flags |= k_ErrorFlags_HeadersError; + if (flags != 0) + prop = flags; + break; + } + */ + + // case kpidMediaType: prop = Header.MediaType; break; + // case kpidSectorsPerTrack: prop = Header.SectorsPerTrack; break; + // case kpidNumHeads: prop = Header.NumHeads; break; + // case kpidHiddenSectors: prop = Header.NumHiddenSectors; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (index >= Items.Size()) + { + switch (propID) + { + case kpidName: + case kpidPath: + prop = VirtFolderNames[index - Items.Size()].GetRawPtr(); + break; + case kpidIsDir: prop = true; break; + case kpidIsAux: prop = true; break; + case kpidIsDeleted: + if ((int)index == _lostFolderIndex_Deleted) + prop = true; + break; + } + prop.Detach(value); + return S_OK; + } + + const CItem &item = Items[index]; + const CMftRec &rec = Recs[item.RecIndex]; + + const CAttr *data= NULL; + if (item.DataIndex >= 0) + data = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start]; + + // const CFileNameAttr *fn = &rec.FileNames[item.NameIndex]; + /* + if (rec.FileNames.Size() > 0) + fn = &rec.FileNames[0]; + */ + + switch (propID) + { + case kpidPath: + GetItemPath(index, prop); + break; + + /* + case kpidLink: + if (!rec.ReparseAttr.SubsName.IsEmpty()) + { + prop = rec.ReparseAttr.SubsName; + } + break; + case kpidLink2: + if (!rec.ReparseAttr.PrintName.IsEmpty()) + { + prop = rec.ReparseAttr.PrintName; + } + break; + + case kpidLinkType: + if (rec.ReparseAttr.Tag != 0) + { + prop = (rec.ReparseAttr.Tag & 0xFFFF); + } + break; + */ + + case kpidINode: + { + // const CMftRec &rec = Recs[item.RecIndex]; + // prop = ((UInt64)rec.SeqNumber << 48) | item.RecIndex; + prop = (UInt32)item.RecIndex; + break; + } + case kpidStreamId: + { + if (item.DataIndex >= 0) + prop = ((UInt64)item.RecIndex << 32) | (unsigned)item.DataIndex; + break; + } + + case kpidName: + { + const UString2 *s; + if (item.IsAltStream()) + s = &rec.DataAttrs[rec.DataRefs[item.DataIndex].Start].Name; + else + s = &rec.FileNames[item.NameIndex].Name; + if (s->IsEmpty()) + prop = (const wchar_t *)EmptyString; + else + prop = s->GetRawPtr(); + break; + } + + case kpidShortName: + { + if (!item.IsAltStream()) + { + int dosNameIndex = rec.FindDosName(item.NameIndex); + if (dosNameIndex >= 0) + { + const UString2 &s = rec.FileNames[dosNameIndex].Name; + if (s.IsEmpty()) + prop = (const wchar_t *)EmptyString; + else + prop = s.GetRawPtr(); + } + } + break; + } + + case kpidIsDir: prop = item.IsDir(); break; + case kpidIsAltStream: prop = item.IsAltStream(); break; + case kpidIsDeleted: prop = !rec.InUse(); break; + case kpidIsAux: prop = false; break; + + 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 kpidChangeTime: NtfsTimeToProp(rec.SiAttr.ThisRecMTime, prop); break; + + /* + case kpidMTime2: if (fn) NtfsTimeToProp(fn->MTime, prop); break; + case kpidCTime2: if (fn) NtfsTimeToProp(fn->CTime, prop); break; + case kpidATime2: if (fn) NtfsTimeToProp(fn->ATime, prop); break; + case kpidRecMTime2: if (fn) NtfsTimeToProp(fn->ThisRecMTime, prop); break; + */ + + case kpidAttrib: + { + UInt32 attrib; + /* WinXP-64: The CFileNameAttr::Attrib is not updated after some changes. Why? + CSiAttr:attrib is updated better. So we use CSiAttr:Sttrib */ + /* + if (fn) + attrib = fn->Attrib; + else + */ + attrib = rec.SiAttr.Attrib; + if (item.IsDir()) + attrib |= FILE_ATTRIBUTE_DIRECTORY; + + /* some system entries can contain extra flags (Index View). + // 0x10000000 (Directory) + // 0x20000000 FILE_ATTR_VIEW_INDEX_PRESENT MFT_RECORD_IS_VIEW_INDEX (Index View) + But we don't need them */ + attrib &= 0xFFFF; + + prop = attrib; + break; + } + case kpidLinks: if (rec.MyNumNameLinks != 1) prop = rec.MyNumNameLinks; break; + + case kpidNumAltStreams: + { + if (!item.IsAltStream()) + { + unsigned num = rec.DataRefs.Size(); + if (num > 0) + { + if (!rec.IsDir() && rec.DataAttrs[rec.DataRefs[0].Start].Name.IsEmpty()) + num--; + if (num > 0) + prop = (UInt32)num; + } + } + break; + } + + case kpidSize: if (data) prop = data->GetSize(); else if (!item.IsDir()) prop = (UInt64)0; break; + case kpidPackSize: if (data) prop = data->GetPackSize(); else if (!item.IsDir()) prop = (UInt64)0; break; + case kpidNumBlocks: if (data) prop = (UInt32)rec.GetNumExtents(item.DataIndex, Header.ClusterSizeLog, Header.NumClusters); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + OpenCallback = callback; + InStream = stream; + HRESULT res; + try + { + res = CDatabase::Open(); + if (res == S_OK) + return S_OK; + } + catch(...) + { + Close(); + throw; + } + Close(); + return res; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + ClearAndClose(); + return S_OK; +} + +Z7_COM7F_IMF(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; + UInt32 i; + UInt64 totalSize = 0; + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; + if (index >= (UInt32)Items.Size()) + continue; + const CItem &item = Items[allFilesMode ? i : indices[i]]; + const CMftRec &rec = Recs[item.RecIndex]; + if (item.DataIndex >= 0) + totalSize += rec.GetSize((unsigned)item.DataIndex); + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + UInt32 clusterSize = Header.ClusterSize(); + CByteBuffer buf(clusterSize); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create outStream; + + for (i = 0;; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (index >= (UInt32)Items.Size() || Items[index].IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const CItem &item = Items[index]; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + outStream->SetStream(realOutStream); + realOutStream.Release(); + outStream->Init(); + + const CMftRec &rec = Recs[item.RecIndex]; + + int res = NExtract::NOperationResult::kDataError; + { + CMyComPtr inStream; + HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeLog, Header.NumClusters, &inStream); + if (hres == S_FALSE) + res = NExtract::NOperationResult::kUnsupportedMethod; + else + { + RINOK(hres) + if (inStream) + { + hres = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps); + if (hres != S_OK && hres != S_FALSE) + { + RINOK(hres) + } + if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK) + res = NExtract::NOperationResult::kOK; + } + } + } + if (item.DataIndex >= 0) + { + const CAttr &data = rec.DataAttrs[rec.DataRefs[item.DataIndex].Start]; + totalPackSize += data.GetPackSize(); + totalSize += data.GetSize(); + } + outStream->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(res)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Items.Size() + VirtFolderNames.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + InitProps(); + + for (UInt32 i = 0; i < numProps; i++) + { + const wchar_t *name = names[i]; + const PROPVARIANT &prop = values[i]; + + if (StringsAreEqualNoCase_Ascii(name, "ld")) + { + RINOK(PROPVARIANT_to_bool(prop, _showDeletedFiles)) + } + else if (StringsAreEqualNoCase_Ascii(name, "ls")) + { + RINOK(PROPVARIANT_to_bool(prop, _showSystemFiles)) + } + else if (IsString1PrefixedByString2_NoCase_Ascii(name, "mt")) + { + } + else if (IsString1PrefixedByString2_NoCase_Ascii(name, "memuse")) + { + } + else + return E_INVALIDARG; + } + return S_OK; +} + +static const Byte k_Signature[] = { 'N', 'T', 'F', 'S', ' ', ' ', ' ', ' ', 0 }; + +REGISTER_ARC_I( + "NTFS", "ntfs img", NULL, 0xD9, + k_Signature, + 3, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/PeHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PeHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/PeHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PeHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,3062 +1,3415 @@ -// PeHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/DynamicBuffer.h" -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.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" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -#define G16(offs, v) v = Get16(p + (offs)) -#define G32(offs, v) v = Get32(p + (offs)) -#define G64(offs, v) v = Get64(p + (offs)) - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -using namespace NWindows; - -namespace NArchive { -namespace NPe { - -static const UInt32 k_Signature32 = 0x00004550; - -static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos, UInt32 &res) -{ - const UInt32 kBufSizeMax = (UInt32)1 << 16; - UInt32 bufSize = MyMin(kBufSizeMax, size); - bufSize += (bufSize & 1); - CByteBuffer buffer(bufSize); - Byte *buf = buffer; - UInt32 sum = 0; - UInt32 pos = 0; - for (;;) - { - UInt32 rem = size - pos; - if (rem > bufSize) - rem = bufSize; - if (rem == 0) - break; - size_t processed = rem; - RINOK(ReadStream(stream, buf, &processed)); - - if ((processed & 1) != 0) - buf[processed] = 0; - - for (unsigned j = 0; j < 4; j++) - { - UInt32 e = excludePos + j; - if (pos <= e) - { - e -= pos; - if (e < processed) - buf[e] = 0; - } - } - - for (size_t i = 0; i < processed; i += 2) - { - sum += Get16(buf + i); - sum = (sum + (sum >> 16)) & 0xFFFF; - } - pos += (UInt32)processed; - if (rem != processed) - break; - } - res = sum + pos; - return S_OK; -} - -static AString GetDecString(UInt32 v) -{ - char sz[16]; - ConvertUInt32ToString(v, sz); - return sz; -} - -struct CVersion -{ - UInt16 Major; - UInt16 Minor; - - void Parse(const Byte *p) - { - G16(0, Major); - G16(2, Minor); - } - void ToProp(NCOM::CPropVariant &prop); -}; - -void CVersion::ToProp(NCOM::CPropVariant &prop) -{ - char sz[32]; - ConvertUInt32ToString(Major, sz); - unsigned len = MyStringLen(sz); - sz[len] = '.'; - ConvertUInt32ToString(Minor, sz + len + 1); - prop = sz; -} - -static const unsigned kHeaderSize = 4 + 20; -static const unsigned k_OptHeader32_Size_MIN = 96; -static const unsigned k_OptHeader64_Size_MIN = 112; - -static const UInt32 PE_IMAGE_FILE_DLL = (1 << 13); - -struct CHeader -{ - UInt16 Machine; - UInt16 NumSections; - UInt32 Time; - UInt32 PointerToSymbolTable; - UInt32 NumSymbols; - UInt16 OptHeaderSize; - UInt16 Flags; - - bool Parse(const Byte *p); - bool IsDll() const { return (Flags & PE_IMAGE_FILE_DLL) != 0; } -}; - -bool CHeader::Parse(const Byte *p) -{ - if (Get32(p) != k_Signature32) - return false; - p += 4; - G16( 0, Machine); - G16( 2, NumSections); - G32( 4, Time); - G32( 8, PointerToSymbolTable); - G32(12, NumSymbols); - G16(16, OptHeaderSize); - G16(18, Flags); - return OptHeaderSize >= k_OptHeader32_Size_MIN; -} - -struct CDirLink -{ - UInt32 Va; - UInt32 Size; - - CDirLink(): Va(0), Size(0) {} - void Parse(const Byte *p) - { - G32(0, Va); - G32(4, Size); - } -}; - -enum -{ - kDirLink_Certificate = 4, - kDirLink_Debug = 6 -}; - -static const UInt32 kNumDirItemsMax = 16; - -struct CDebugEntry -{ - UInt32 Flags; - UInt32 Time; - CVersion Ver; - UInt32 Type; - UInt32 Size; - UInt32 Va; - UInt32 Pa; - - void Parse(const Byte *p) - { - G32(0, Flags); - G32(4, Time); - Ver.Parse(p + 8); - G32(12, Type); - G32(16, Size); - G32(20, Va); - G32(24, Pa); - } -}; - -static const UInt32 k_CheckSum_Field_Offset = 64; - -static const UInt32 PE_OptHeader_Magic_32 = 0x10B; -static const UInt32 PE_OptHeader_Magic_64 = 0x20B; - -static const UInt32 k_SubSystems_EFI_First = 10; -static const UInt32 k_SubSystems_EFI_Last = 13; - -struct COptHeader -{ - UInt16 Magic; - Byte LinkerVerMajor; - Byte LinkerVerMinor; - - UInt32 CodeSize; - UInt32 InitDataSize; - UInt32 UninitDataSize; - - // UInt32 AddressOfEntryPoint; - // UInt32 BaseOfCode; - // UInt32 BaseOfData32; - UInt64 ImageBase; - - UInt32 SectAlign; - UInt32 FileAlign; - - CVersion OsVer; - CVersion ImageVer; - CVersion SubsysVer; - - UInt32 ImageSize; - UInt32 HeadersSize; - UInt32 CheckSum; - UInt16 SubSystem; - UInt16 DllCharacts; - - UInt64 StackReserve; - UInt64 StackCommit; - UInt64 HeapReserve; - UInt64 HeapCommit; - - UInt32 NumDirItems; - CDirLink DirItems[kNumDirItemsMax]; - - bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; } - bool Parse(const Byte *p, UInt32 size); - - int GetNumFileAlignBits() const - { - for (unsigned i = 0; i <= 31; i++) - if (((UInt32)1 << i) == FileAlign) - return i; - return -1; - } - - bool IsSybSystem_EFI() const - { - return - SubSystem >= k_SubSystems_EFI_First && - SubSystem <= k_SubSystems_EFI_Last; - } -}; - -bool COptHeader::Parse(const Byte *p, UInt32 size) -{ - if (size < k_OptHeader32_Size_MIN) - return false; - Magic = Get16(p); - switch (Magic) - { - case PE_OptHeader_Magic_32: - case PE_OptHeader_Magic_64: - break; - default: - return false; - } - LinkerVerMajor = p[2]; - LinkerVerMinor = p[3]; - - G32( 4, CodeSize); - G32( 8, InitDataSize); - G32(12, UninitDataSize); - // G32(16, AddressOfEntryPoint); - // G32(20, BaseOfCode); - - G32(32, SectAlign); - G32(36, FileAlign); - - OsVer.Parse(p + 40); - ImageVer.Parse(p + 44); - SubsysVer.Parse(p + 48); - - // reserved = Get32(p + 52); - - G32(56, ImageSize); - G32(60, HeadersSize); - G32(64, CheckSum); - G16(68, SubSystem); - G16(70, DllCharacts); - - UInt32 pos; - if (Is64Bit()) - { - if (size < k_OptHeader64_Size_MIN) - return false; - // BaseOfData32 = 0; - G64(24, ImageBase); - G64(72, StackReserve); - G64(80, StackCommit); - G64(88, HeapReserve); - G64(96, HeapCommit); - pos = 108; - } - else - { - // G32(24, BaseOfData32); - G32(28, ImageBase); - G32(72, StackReserve); - G32(76, StackCommit); - G32(80, HeapReserve); - G32(84, HeapCommit); - pos = 92; - } - - G32(pos, NumDirItems); - if (NumDirItems > (1 << 16)) - return false; - pos += 4; - if (pos + 8 * NumDirItems != size) - return false; - for (UInt32 i = 0; i < NumDirItems && i < kNumDirItemsMax; i++) - DirItems[i].Parse(p + pos + i * 8); - return true; -} - -static const UInt32 kSectionSize = 40; - -struct CSection -{ - AString Name; - - UInt32 VSize; - UInt32 Va; - UInt32 PSize; - UInt32 Pa; - UInt32 Flags; - UInt32 Time; - // UInt16 NumRelocs; - bool IsRealSect; - bool IsDebug; - bool IsAdditionalSection; - - CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} - - const UInt32 GetSizeExtract() const { return PSize; } - const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); } - - void UpdateTotalSize(UInt32 &totalSize) const - { - UInt32 t = Pa + PSize; - if (totalSize < t) - totalSize = t; - } - - void Parse(const Byte *p); - - int Compare(const CSection &s) const - { - RINOZ(MyCompare(Pa, s.Pa)); - UInt32 size1 = GetSizeExtract(); - UInt32 size2 = s.GetSizeExtract(); - return MyCompare(size1, size2); - } -}; - -static const unsigned kNameSize = 8; - -static void GetName(const Byte *name, AString &res) -{ - res.SetFrom_CalcLen((const char *)name, kNameSize); -} - -void CSection::Parse(const Byte *p) -{ - GetName(p, Name); - G32( 8, VSize); - G32(12, Va); - G32(16, PSize); - G32(20, Pa); - // G16(32, NumRelocs); - G32(36, Flags); -} - -static const CUInt32PCharPair g_HeaderCharacts[] = -{ - { 1, "Executable" }, - { 13, "DLL" }, - { 8, "32-bit" }, - { 5, "LargeAddress" }, - { 0, "NoRelocs" }, - { 2, "NoLineNums" }, - { 3, "NoLocalSyms" }, - { 4, "AggressiveWsTrim" }, - { 9, "NoDebugInfo" }, - { 10, "RemovableRun" }, - { 11, "NetRun" }, - { 12, "System" }, - { 14, "UniCPU" }, - { 7, "Little-Endian" }, - { 15, "Big-Endian" } -}; - -static const CUInt32PCharPair g_DllCharacts[] = -{ - { 6, "Relocated" }, - { 7, "Integrity" }, - { 8, "NX-Compatible" }, - { 9, "NoIsolation" }, - { 10, "NoSEH" }, - { 11, "NoBind" }, - { 13, "WDM" }, - { 15, "TerminalServerAware" } -}; - -static const CUInt32PCharPair g_SectFlags[] = -{ - { 3, "NoPad" }, - { 5, "Code" }, - { 6, "InitializedData" }, - { 7, "UninitializedData" }, - { 9, "Comments" }, - { 11, "Remove" }, - { 12, "COMDAT" }, - { 15, "GP" }, - { 24, "ExtendedRelocations" }, - { 25, "Discardable" }, - { 26, "NotCached" }, - { 27, "NotPaged" }, - { 28, "Shared" }, - { 29, "Execute" }, - { 30, "Read" }, - { 31, "Write" } -}; - -static const CUInt32PCharPair g_MachinePairs[] = -{ - { 0x014C, "x86" }, - { 0x014D, "I860" }, - { 0x0162, "MIPS-R3000" }, - { 0x0166, "MIPS-R4000" }, - { 0x0168, "MIPS-R10000" }, - { 0x0169, "MIPS-V2" }, - { 0x0184, "Alpha" }, - { 0x01A2, "SH3" }, - { 0x01A3, "SH3-DSP" }, - { 0x01A4, "SH3E" }, - { 0x01A6, "SH4" }, - { 0x01A8, "SH5" }, - { 0x01C0, "ARM" }, - { 0x01C2, "ARM-Thumb" }, - { 0x01C4, "ARM-NT" }, - { 0x01D3, "AM33" }, - { 0x01F0, "PPC" }, - { 0x01F1, "PPC-FP" }, - { 0x0200, "IA-64" }, - { 0x0266, "MIPS-16" }, - { 0x0284, "Alpha-64" }, - { 0x0366, "MIPS-FPU" }, - { 0x0466, "MIPS-FPU16" }, - { 0x0520, "TriCore" }, - { 0x0CEF, "CEF" }, - { 0x0EBC, "EFI" }, - { 0x8664, "x64" }, - { 0x9041, "M32R" }, - { 0xC0EE, "CEE" } -}; - -static const CUInt32PCharPair g_SubSystems[] = -{ - { 0, "Unknown" }, - { 1, "Native" }, - { 2, "Windows GUI" }, - { 3, "Windows CUI" }, - { 7, "Posix" }, - { 9, "Windows CE" }, - { 10, "EFI" }, - { 11, "EFI Boot" }, - { 12, "EFI Runtime" }, - { 13, "EFI ROM" }, - { 14, "XBOX" } -}; - -static const char * const g_ResTypes[] = -{ - NULL - , "CURSOR" - , "BITMAP" - , "ICON" - , "MENU" - , "DIALOG" - , "STRING" - , "FONTDIR" - , "FONT" - , "ACCELERATOR" - , "RCDATA" - , "MESSAGETABLE" - , "GROUP_CURSOR" - , NULL - , "GROUP_ICON" - , NULL - , "VERSION" - , "DLGINCLUDE" - , NULL - , "PLUGPLAY" - , "VXD" - , "ANICURSOR" - , "ANIICON" - , "HTML" - , "MANIFEST" -}; - -static const UInt32 kFlag = (UInt32)1 << 31; -static const UInt32 kMask = ~kFlag; - -struct CTableItem -{ - UInt32 Offset; - UInt32 ID; -}; - - -static const UInt32 kBmpHeaderSize = 14; -static const UInt32 kIconHeaderSize = 22; - -struct CResItem -{ - UInt32 Type; - UInt32 ID; - UInt32 Lang; - - UInt32 Size; - UInt32 Offset; - - UInt32 HeaderSize; - Byte Header[kIconHeaderSize]; // it must be enough for max size header. - bool Enabled; - - bool IsNameEqual(const CResItem &item) const { return Lang == item.Lang; } - UInt32 GetSize() const { return Size + HeaderSize; } - bool IsBmp() const { return Type == 2; } - bool IsIcon() const { return Type == 3; } - bool IsString() const { return Type == 6; } - bool IsRcData() const { return Type == 10; } - bool IsVersion() const { return Type == 16; } - bool IsRcDataOrUnknown() const { return IsRcData() || Type > 64; } -}; - -struct CTextFile -{ - CByteDynamicBuffer Buf; - - size_t FinalSize() const { return Buf.GetPos(); } - - void AddChar(Byte c); - void AddWChar(UInt16 c); - void AddWChar_Smart(UInt16 c); - void NewLine(); - void AddString(const char *s); - void AddSpaces(int num); - void AddBytes(const Byte *p, size_t size) - { - Buf.AddData(p, size); - } - - void OpenBlock(int num) - { - AddSpaces(num); - AddChar('{'); - NewLine(); - } - void CloseBlock(int num) - { - AddSpaces(num); - AddChar('}'); - NewLine(); - } -}; - -void CTextFile::AddChar(Byte c) -{ - Byte *p = Buf.GetCurPtrAndGrow(2); - p[0] = c; - p[1] = 0; -} - -void CTextFile::AddWChar(UInt16 c) -{ - Byte *p = Buf.GetCurPtrAndGrow(2); - SetUi16(p, c); -} - -void CTextFile::AddWChar_Smart(UInt16 c) -{ - if (c == '\n') - { - AddChar('\\'); - c = 'n'; - } - AddWChar(c); -} - -void CTextFile::NewLine() -{ - AddChar(0x0D); - AddChar(0x0A); -} - -void CTextFile::AddString(const char *s) -{ - for (;; s++) - { - char c = *s; - if (c == 0) - return; - AddChar(c); - } -} - -void CTextFile::AddSpaces(int num) -{ - for (int i = 0; i < num; i++) - AddChar(' '); -} - -struct CStringItem: public CTextFile -{ - UInt32 Lang; -}; - -struct CByteBuffer_WithLang: public CByteBuffer -{ - UInt32 Lang; -}; - - -struct CMixItem -{ - int SectionIndex; - int ResourceIndex; - int StringIndex; - int VersionIndex; - - CMixItem(): SectionIndex(-1), ResourceIndex(-1), StringIndex(-1), VersionIndex(-1) {} - bool IsSectionItem() const { return ResourceIndex < 0 && StringIndex < 0 && VersionIndex < 0; } -}; - -struct CUsedBitmap -{ - CByteBuffer Buf; -public: - void Alloc(size_t size) - { - size = (size + 7) / 8; - Buf.Alloc(size); - memset(Buf, 0, size); - } - - void Free() - { - Buf.Free(); - } - - bool SetRange(size_t from, unsigned size) - { - for (unsigned i = 0; i < size; i++) - { - size_t pos = (from + i) >> 3; - Byte mask = (Byte)(1 << ((from + i) & 7)); - Byte b = Buf[pos]; - if ((b & mask) != 0) - return false; - Buf[pos] = (Byte)(b | mask); - } - return true; - } -}; - -struct CStringKeyValue -{ - UString Key; - UString Value; -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public IArchiveAllowTail, - public CMyUnknownImp -{ - CMyComPtr _stream; - CObjectVector _sections; - UInt32 _peOffset; - CHeader _header; - UInt32 _totalSize; - Int32 _mainSubfile; - - CRecordVector _mixItems; - CRecordVector _items; - CObjectVector _strings; - CObjectVector _versionFiles; - UString _versionFullString; - UString _versionShortString; - UString _originalFilename; - CObjectVector _versionKeys; - - CByteBuffer _buf; - bool _oneLang; - UString _resourcesPrefix; - CUsedBitmap _usedRes; - bool _parseResources; - bool _checksumError; - - COptHeader _optHeader; - - bool _allowTail; - - HRESULT LoadDebugSections(IInStream *stream, bool &thereIsSection); - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); - - void AddResNameToString(UString &s, UInt32 id) const; - void AddLangPrefix(UString &s, UInt32 lang) const; - HRESULT ReadString(UInt32 offset, UString &dest) const; - HRESULT ReadTable(UInt32 offset, CRecordVector &items); - bool ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size); - HRESULT OpenResources(unsigned sectIndex, IInStream *stream, IArchiveOpenCallback *callback); - void CloseResources(); - - - bool CheckItem(const CSection §, const CResItem &item, size_t offset) const - { - return item.Offset >= sect.Va && offset <= _buf.Size() && _buf.Size() - offset >= item.Size; - } - -public: - CHandler(): _allowTail(false) {} - - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(AllowTail)(Int32 allowTail); -}; - - -enum -{ - kpidSectAlign = kpidUserDefined, - kpidFileAlign, - kpidLinkerVer, - kpidOsVer, - kpidImageVer, - kpidSubsysVer, - kpidCodeSize, - kpidImageSize, - kpidInitDataSize, - kpidUnInitDataSize, - kpidHeadersSizeUnInitDataSize, - kpidSubSystem, - kpidDllCharacts, - kpidStackReserve, - kpidStackCommit, - kpidHeapReserve, - kpidHeapCommit, - kpidImageBase - // kpidAddressOfEntryPoint, - // kpidBaseOfCode, - // kpidBaseOfData32, -}; - -static const CStatProp kArcProps[] = -{ - // { NULL, kpidWarning, VT_BSTR}, - { NULL, kpidCpu, VT_BSTR}, - { NULL, kpidBit64, VT_BOOL}, - { NULL, kpidCharacts, VT_BSTR}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidHeadersSize, VT_UI4}, - { NULL, kpidChecksum, VT_UI4}, - { NULL, kpidName, VT_BSTR}, - - { "Image Size", kpidImageSize, VT_UI4}, - { "Section Alignment", kpidSectAlign, VT_UI4}, - { "File Alignment", kpidFileAlign, VT_UI4}, - { "Code Size", kpidCodeSize, VT_UI4}, - { "Initialized Data Size", kpidInitDataSize, VT_UI4}, - { "Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, - { "Linker Version", kpidLinkerVer, VT_BSTR}, - { "OS Version", kpidOsVer, VT_BSTR}, - { "Image Version", kpidImageVer, VT_BSTR}, - { "Subsystem Version", kpidSubsysVer, VT_BSTR}, - { "Subsystem", kpidSubSystem, VT_BSTR}, - { "DLL Characteristics", kpidDllCharacts, VT_BSTR}, - { "Stack Reserve", kpidStackReserve, VT_UI8}, - { "Stack Commit", kpidStackCommit, VT_UI8}, - { "Heap Reserve", kpidHeapReserve, VT_UI8}, - { "Heap Commit", kpidHeapCommit, VT_UI8}, - { "Image Base", kpidImageBase, VT_UI8}, - { NULL, kpidComment, VT_BSTR}, - - // { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, - // { "Base Of Code", kpidBaseOfCode, VT_UI8}, - // { "Base Of Data", kpidBaseOfData32, VT_UI8}, -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidVirtualSize, - kpidCharacts, - kpidOffset, - kpidVa, -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -static void TimeToProp(UInt32 unixTime, NCOM::CPropVariant &prop) -{ - if (unixTime != 0) - { - FILETIME ft; - NTime::UnixTimeToFileTime(unixTime, ft); - prop = ft; - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidSectAlign: prop = _optHeader.SectAlign; break; - case kpidFileAlign: prop = _optHeader.FileAlign; break; - case kpidLinkerVer: - { - CVersion v = { _optHeader.LinkerVerMajor, _optHeader.LinkerVerMinor }; - v.ToProp(prop); - break; - } - - case kpidOsVer: _optHeader.OsVer.ToProp(prop); break; - case kpidImageVer: _optHeader.ImageVer.ToProp(prop); break; - case kpidSubsysVer: _optHeader.SubsysVer.ToProp(prop); break; - case kpidCodeSize: prop = _optHeader.CodeSize; break; - case kpidInitDataSize: prop = _optHeader.InitDataSize; break; - case kpidUnInitDataSize: prop = _optHeader.UninitDataSize; break; - case kpidImageSize: prop = _optHeader.ImageSize; break; - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _optHeader.HeadersSize; break; - case kpidChecksum: prop = _optHeader.CheckSum; break; - case kpidComment: if (!_versionFullString.IsEmpty()) prop = _versionFullString; break; - case kpidShortComment: - if (!_versionShortString.IsEmpty()) - prop = _versionShortString; - else - { - PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); - } - break; - - case kpidName: if (!_originalFilename.IsEmpty()) prop = _originalFilename; break; - case kpidExtension: - if (_header.IsDll()) - prop = _optHeader.IsSybSystem_EFI() ? "efi" : "dll"; - break; - - // case kpidIsSelfExe: prop = !_header.IsDll(); break; - - // case kpidError: - case kpidWarning: if (_checksumError) prop = "Checksum error"; break; - - case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; - case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break; - case kpidSubSystem: PAIR_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break; - - case kpidMTime: - case kpidCTime: TimeToProp(_header.Time, prop); break; - case kpidCharacts: FLAGS_TO_PROP(g_HeaderCharacts, _header.Flags, prop); break; - case kpidDllCharacts: FLAGS_TO_PROP(g_DllCharacts, _optHeader.DllCharacts, prop); break; - case kpidStackReserve: prop = _optHeader.StackReserve; break; - case kpidStackCommit: prop = _optHeader.StackCommit; break; - case kpidHeapReserve: prop = _optHeader.HeapReserve; break; - case kpidHeapCommit: prop = _optHeader.HeapCommit; break; - - case kpidImageBase: prop = _optHeader.ImageBase; break; - // case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break; - // case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break; - // case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break; - - case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::ReadString(UInt32 offset, UString &dest) const -{ - if ((offset & 1) != 0 || offset >= _buf.Size()) - return S_FALSE; - size_t rem = _buf.Size() - offset; - if (rem < 2) - return S_FALSE; - unsigned len = Get16(_buf + offset); - if ((rem - 2) / 2 < len) - return S_FALSE; - dest.Empty(); - wchar_t *destBuf = dest.GetBuf(len); - offset += 2; - const Byte *src = _buf + offset; - unsigned i; - for (i = 0; i < len; i++) - { - wchar_t c = (wchar_t)Get16(src + i * 2); - if (c == 0) - break; - destBuf[i] = c; - } - destBuf[i] = 0; - dest.ReleaseBuf_SetLen(i); - return S_OK; -} - -void CHandler::AddResNameToString(UString &s, UInt32 id) const -{ - if ((id & kFlag) != 0) - { - UString name; - if (ReadString(id & kMask, name) == S_OK) - { - const wchar_t *str = L"[]"; - if (name.Len() > 1 && name[0] == '"' && name.Back() == '"') - { - if (name.Len() != 2) - { - name.DeleteBack(); - str = name.Ptr(1); - } - } - else if (!name.IsEmpty()) - str = name; - s += str; - return; - } - } - wchar_t sz[16]; - ConvertUInt32ToString(id, sz); - s += sz; -} - -void CHandler::AddLangPrefix(UString &s, UInt32 lang) const -{ - if (!_oneLang) - { - AddResNameToString(s, lang); - s.Add_PathSepar(); - } -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CMixItem &mixItem = _mixItems[index]; - if (mixItem.StringIndex >= 0) - { - const CStringItem &item = _strings[mixItem.StringIndex]; - switch (propID) - { - case kpidPath: - { - UString s = _resourcesPrefix; - AddLangPrefix(s, item.Lang); - s.AddAscii("string.txt"); - prop = s; - break; - } - case kpidSize: - case kpidPackSize: - prop = (UInt64)item.FinalSize(); break; - } - } - else if (mixItem.VersionIndex >= 0) - { - const CByteBuffer_WithLang &item = _versionFiles[mixItem.VersionIndex]; - switch (propID) - { - case kpidPath: - { - UString s = _resourcesPrefix; - AddLangPrefix(s, item.Lang); - s.AddAscii("version.txt"); - prop = s; - break; - } - case kpidSize: - case kpidPackSize: - prop = (UInt64)item.Size(); break; - } - } - else if (mixItem.ResourceIndex >= 0) - { - const CResItem &item = _items[mixItem.ResourceIndex]; - switch (propID) - { - case kpidPath: - { - UString s = _resourcesPrefix; - AddLangPrefix(s, item.Lang); - { - const char *p = NULL; - if (item.Type < ARRAY_SIZE(g_ResTypes)) - p = g_ResTypes[item.Type]; - if (p) - s.AddAscii(p); - else - AddResNameToString(s, item.Type); - } - s.Add_PathSepar(); - AddResNameToString(s, item.ID); - if (item.HeaderSize != 0) - { - if (item.IsBmp()) - s.AddAscii(".bmp"); - else if (item.IsIcon()) - s.AddAscii(".ico"); - } - prop = s; - break; - } - case kpidSize: prop = (UInt64)item.GetSize(); break; - case kpidPackSize: prop = (UInt64)item.Size; break; - } - } - else - { - const CSection &item = _sections[mixItem.SectionIndex]; - switch (propID) - { - case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; - case kpidSize: prop = (UInt64)item.PSize; break; - case kpidPackSize: prop = (UInt64)item.PSize; break; - case kpidVirtualSize: prop = (UInt64)item.VSize; break; - case kpidOffset: prop = item.Pa; break; - case kpidVa: if (item.IsRealSect) prop = item.Va; break; - case kpidMTime: - case kpidCTime: - TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; - case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Flags, prop); break; - case kpidZerosTailIsAllowed: if (!item.IsRealSect) prop = true; break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection) -{ - thereIsSection = false; - const CDirLink &debugLink = _optHeader.DirItems[kDirLink_Debug]; - if (debugLink.Size == 0) - return S_OK; - const unsigned kEntrySize = 28; - UInt32 numItems = debugLink.Size / kEntrySize; - if (numItems * kEntrySize != debugLink.Size || numItems > 16) - return S_FALSE; - - UInt64 pa = 0; - unsigned i; - for (i = 0; i < _sections.Size(); i++) - { - const CSection § = _sections[i]; - if (sect.Va <= debugLink.Va && debugLink.Va + debugLink.Size <= sect.Va + sect.PSize) - { - pa = sect.Pa + (debugLink.Va - sect.Va); - break; - } - } - if (i == _sections.Size()) - { - // Exe for ARM requires S_OK - // return S_FALSE; - return S_OK; - } - - CByteBuffer buffer(debugLink.Size); - Byte *buf = buffer; - - RINOK(stream->Seek(pa, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf, debugLink.Size)); - - for (i = 0; i < numItems; i++) - { - CDebugEntry de; - de.Parse(buf); - - if (de.Size == 0) - continue; - - UInt32 totalSize = de.Pa + de.Size; - if (totalSize > _totalSize) - { - _totalSize = totalSize; - thereIsSection = true; - - CSection § = _sections.AddNew(); - sect.Name = ".debug" + GetDecString(i); - sect.IsDebug = true; - sect.Time = de.Time; - sect.Va = de.Va; - sect.Pa = de.Pa; - sect.PSize = sect.VSize = de.Size; - } - buf += kEntrySize; - } - - return S_OK; -} - -HRESULT CHandler::ReadTable(UInt32 offset, CRecordVector &items) -{ - if ((offset & 3) != 0 || offset >= _buf.Size()) - return S_FALSE; - size_t rem = _buf.Size() - offset; - if (rem < 16) - return S_FALSE; - unsigned numNameItems = Get16(_buf + offset + 12); - unsigned numIdItems = Get16(_buf + offset + 14); - unsigned numItems = numNameItems + numIdItems; - if ((rem - 16) / 8 < numItems) - return S_FALSE; - if (!_usedRes.SetRange(offset, 16 + numItems * 8)) - return S_FALSE; - offset += 16; - items.ClearAndReserve(numItems); - for (unsigned i = 0; i < numItems; i++, offset += 8) - { - const Byte *buf = _buf + offset; - CTableItem item; - item.ID = Get32(buf + 0); - if ((bool)((item.ID & kFlag) != 0) != (bool)(i < numNameItems)) - return S_FALSE; - item.Offset = Get32(buf + 4); - items.AddInReserved(item); - } - return S_OK; -} - -static const UInt32 kFileSizeMax = (UInt32)1 << 31; -static const unsigned kNumResItemsMax = (unsigned)1 << 23; -static const unsigned kNumStringLangsMax = 256; - -// BITMAPINFOHEADER -struct CBitmapInfoHeader -{ - // UInt32 HeaderSize; - UInt32 XSize; - Int32 YSize; - UInt16 Planes; - UInt16 BitCount; - UInt32 Compression; - UInt32 SizeImage; - - bool Parse(const Byte *p, size_t size); -}; - -static const UInt32 kBitmapInfoHeader_Size = 0x28; - -bool CBitmapInfoHeader::Parse(const Byte *p, size_t size) -{ - if (size < kBitmapInfoHeader_Size || Get32(p) != kBitmapInfoHeader_Size) - return false; - G32( 4, XSize); - G32( 8, YSize); - G16(12, Planes); - G16(14, BitCount); - G32(16, Compression); - G32(20, SizeImage); - return true; -} - -static UInt32 GetImageSize(UInt32 xSize, UInt32 ySize, UInt32 bitCount) -{ - return ((xSize * bitCount + 7) / 8 + 3) / 4 * 4 * ySize; -} - -static UInt32 SetBitmapHeader(Byte *dest, const Byte *src, UInt32 size) -{ - CBitmapInfoHeader h; - if (!h.Parse(src, size)) - return 0; - if (h.YSize < 0) - h.YSize = -h.YSize; - if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || h.BitCount > 32) - return 0; - if (h.SizeImage == 0) - { - if (h.Compression != 0) // BI_RGB - return 0; - h.SizeImage = GetImageSize(h.XSize, h.YSize, h.BitCount); - } - UInt32 totalSize = kBmpHeaderSize + size; - UInt32 offBits = totalSize - h.SizeImage; - // BITMAPFILEHEADER - SetUi16(dest, 0x4D42); - SetUi32(dest + 2, totalSize); - SetUi32(dest + 6, 0); - SetUi32(dest + 10, offBits); - return kBmpHeaderSize; -} - -static UInt32 SetIconHeader(Byte *dest, const Byte *src, UInt32 size) -{ - CBitmapInfoHeader h; - if (!h.Parse(src, size)) - return 0; - if (h.YSize < 0) - h.YSize = -h.YSize; - if (h.XSize > (1 << 26) || h.YSize > (1 << 26) || h.Planes != 1 || - h.Compression != 0) // BI_RGB - return 0; - - UInt32 numBitCount = h.BitCount; - if (numBitCount != 1 && - numBitCount != 4 && - numBitCount != 8 && - numBitCount != 24 && - numBitCount != 32) - return 0; - - if ((h.YSize & 1) != 0) - return 0; - h.YSize /= 2; - if (h.XSize > 0x100 || h.YSize > 0x100) - return 0; - - UInt32 imageSize; - // imageSize is not correct if AND mask array contains zeros - // in this case it is equal image1Size - - // UInt32 imageSize = h.SizeImage; - // if (imageSize == 0) - // { - UInt32 image1Size = GetImageSize(h.XSize, h.YSize, h.BitCount); - UInt32 image2Size = GetImageSize(h.XSize, h.YSize, 1); - imageSize = image1Size + image2Size; - // } - UInt32 numColors = 0; - if (numBitCount < 16) - numColors = 1 << numBitCount; - - SetUi16(dest, 0); // Reserved - SetUi16(dest + 2, 1); // RES_ICON - SetUi16(dest + 4, 1); // ResCount - - dest[6] = (Byte)h.XSize; // Width - dest[7] = (Byte)h.YSize; // Height - dest[8] = (Byte)numColors; // ColorCount - dest[9] = 0; // Reserved - - SetUi32(dest + 10, 0); // Reserved1 / Reserved2 - - UInt32 numQuadsBytes = numColors * 4; - UInt32 BytesInRes = kBitmapInfoHeader_Size + numQuadsBytes + imageSize; - SetUi32(dest + 14, BytesInRes); - SetUi32(dest + 18, kIconHeaderSize); - - /* - Description = DWORDToString(xSize) + - kDelimiterChar + DWORDToString(ySize) + - kDelimiterChar + DWORDToString(numBitCount); - */ - return kIconHeaderSize; -} - -bool CHandler::ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size) -{ - if ((size & 1) != 0) - return false; - - unsigned i; - for (i = 0; i < _strings.Size(); i++) - if (_strings[i].Lang == lang) - break; - if (i == _strings.Size()) - { - if (_strings.Size() >= kNumStringLangsMax) - return false; - CStringItem &item = _strings.AddNew(); - item.Lang = lang; - } - - CStringItem &item = _strings[i]; - id = (id - 1) << 4; - UInt32 pos = 0; - for (i = 0; i < 16; i++) - { - if (size - pos < 2) - return false; - UInt32 len = Get16(src + pos); - pos += 2; - if (len != 0) - { - if (size - pos < len * 2) - return false; - char temp[32]; - ConvertUInt32ToString(id + i, temp); - size_t tempLen = strlen(temp); - size_t j; - for (j = 0; j < tempLen; j++) - item.AddChar(temp[j]); - item.AddChar('\t'); - for (j = 0; j < len; j++, pos += 2) - item.AddWChar_Smart(Get16(src + pos)); - item.NewLine(); - } - } - if (size == pos) - return true; - - // Some rare case files have additional ZERO. - if (size == pos + 2 && Get16(src + pos) == 0) - return true; - - return false; -} - - -// ---------- VERSION ---------- - -static const UInt32 kMy_VS_FFI_SIGNATURE = 0xFEEF04BD; - -struct CMy_VS_FIXEDFILEINFO -{ - // UInt32 Signature; - // UInt32 StrucVersion; - UInt32 VersionMS; - UInt32 VersionLS; - UInt32 ProductVersionMS; - UInt32 ProductVersionLS; - UInt32 FlagsMask; - UInt32 Flags; - UInt32 OS; - UInt32 Type; - UInt32 Subtype; - UInt32 DateMS; - UInt32 DateLS; - - bool Parse(const Byte *p); - void PrintToTextFile(CTextFile &f, CObjectVector &keys); -}; - -bool CMy_VS_FIXEDFILEINFO::Parse(const Byte *p) -{ - if (Get32(p) != kMy_VS_FFI_SIGNATURE) // signature; - return false; - // G32(0x04, StrucVersion); - G32(0x08, VersionMS); - G32(0x0C, VersionLS); - G32(0x10, ProductVersionMS); - G32(0x14, ProductVersionLS); - G32(0x18, FlagsMask); - G32(0x1C, Flags); - G32(0x20, OS); - G32(0x24, Type); - G32(0x28, Subtype); - G32(0x2C, DateMS); - G32(0x40, DateLS); - return true; -} - -static void PrintUInt32(CTextFile &f, UInt32 v) -{ - char s[16]; - ConvertUInt32ToString(v, s); - f.AddString(s); -} - -static void PrintUInt32(UString &dest, UInt32 v) -{ - wchar_t s[16]; - ConvertUInt32ToString(v, s); - dest += s; -} - -static void PrintHex(CTextFile &f, UInt32 val) -{ - char temp[16]; - temp[0] = '0'; - temp[1] = 'x'; - ConvertUInt32ToHex(val, temp + 2); - f.AddString(temp); -} - -static void PrintVersion(CTextFile &f, UInt32 ms, UInt32 ls) -{ - PrintUInt32(f, HIWORD(ms)); f.AddChar(','); - PrintUInt32(f, LOWORD(ms)); f.AddChar(','); - PrintUInt32(f, HIWORD(ls)); f.AddChar(','); - PrintUInt32(f, LOWORD(ls)); -} - -static void PrintVersion(UString &s, UInt32 ms, UInt32 ls) -{ - PrintUInt32(s, HIWORD(ms)); s += L'.'; - PrintUInt32(s, LOWORD(ms)); s += L'.'; - PrintUInt32(s, HIWORD(ls)); s += L'.'; - PrintUInt32(s, LOWORD(ls)); -} - -static const char * const k_VS_FileFlags[] = -{ - "DEBUG" - , "PRERELEASE" - , "PATCHED" - , "PRIVATEBUILD" - , "INFOINFERRED" - , "SPECIALBUILD" -}; - -static const CUInt32PCharPair k_VS_FileOS[] = -{ - { 0x10001, "VOS_DOS_WINDOWS16" }, - { 0x10004, "VOS_DOS_WINDOWS32" }, - { 0x20002, "VOS_OS216_PM16" }, - { 0x30003, "VOS_OS232_PM32" }, - { 0x40004, "VOS_NT_WINDOWS32" } -}; - -static const char * const k_VS_FileOS_High[] = -{ - "VOS_UNKNOWN" - , "VOS_DOS" - , "VOS_OS216" - , "VOS_OS232" - , "VOS_NT" - , "VOS_WINCE" -}; - -static const UInt32 kMY_VFT_DRV = 3; -static const UInt32 kMY_VFT_FONT = 4; - -static const char * const k_VS_FileOS_Low[] = -{ - "VOS__BASE" - , "VOS__WINDOWS16" - , "VOS__PM16" - , "VOS__PM32" - , "VOS__WINDOWS32" -}; - -static const char * const k_VS_FileType[] = -{ - "VFT_UNKNOWN" - , "VFT_APP" - , "VFT_DLL" - , "VFT_DRV" - , "VFT_FONT" - , "VFT_VXD" - , "0x6" - , "VFT_STATIC_LIB" -}; - -// Subtype for VFT_DRV Type -static const char * const k_VS_FileSubType_DRV[] = -{ - "0" - , "PRINTER" - , "KEYBOARD" - , "LANGUAGE" - , "DISPLAY" - , "MOUSE" - , "NETWORK" - , "SYSTEM" - , "INSTALLABLE" - , "SOUND" - , "COMM" - , "INPUTMETHOD" - , "VERSIONED_PRINTER" -}; - -// Subtype for VFT_FONT Type -static const char * const k_VS_FileSubType_FONT[] = -{ - "0" - , "VFT2_FONT_RASTER" - , "VFT2_FONT_VECTOR" - , "VFT2_FONT_TRUETYPE" -}; - -static int FindKey(CObjectVector &v, const char *key) -{ - FOR_VECTOR (i, v) - if (v[i].Key.IsEqualTo(key)) - return i; - return -1; -} - -static void AddToUniqueUStringVector(CObjectVector &v, const UString &key, const UString &value) -{ - bool needInsert = false; - unsigned i; - for (i = 0; i < v.Size(); i++) - { - if (v[i].Key == key) - { - if (v[i].Value == value) - return; - needInsert = true; - } - else if (needInsert) - break; - } - CStringKeyValue &pair = v.InsertNew(i); - pair.Key = key; - pair.Value = value; -} - -void CMy_VS_FIXEDFILEINFO::PrintToTextFile(CTextFile &f, CObjectVector &keys) -{ - f.AddString("FILEVERSION "); - PrintVersion(f, VersionMS, VersionLS); - f.NewLine(); - - f.AddString("PRODUCTVERSION "); - PrintVersion(f, ProductVersionMS, ProductVersionLS); - f.NewLine(); - - { - UString s; - PrintVersion(s, VersionMS, VersionLS); - AddToUniqueUStringVector(keys, L"FileVersion", s); - } - { - UString s; - PrintVersion(s, ProductVersionMS, ProductVersionLS); - AddToUniqueUStringVector(keys, L"ProductVersion", s); - } - - f.AddString("FILEFLAGSMASK "); - PrintHex(f, FlagsMask); - f.NewLine(); - - f.AddString("FILEFLAGS "); - { - bool wasPrinted = false; - for (unsigned i = 0; i < ARRAY_SIZE(k_VS_FileFlags); i++) - { - if ((Flags & ((UInt32)1 << i)) != 0) - { - if (wasPrinted) - f.AddString(" | "); - f.AddString("VS_FF_"); - f.AddString(k_VS_FileFlags[i]); - wasPrinted = true; - } - } - UInt32 v = Flags & ~(((UInt32)1 << ARRAY_SIZE(k_VS_FileFlags)) - 1); - if (v != 0 || !wasPrinted) - { - if (wasPrinted) - f.AddString(" | "); - PrintHex(f, v); - } - } - f.NewLine(); - - // OS = 0x111230; - f.AddString("FILEOS "); - unsigned i; - for (i = 0; i < ARRAY_SIZE(k_VS_FileOS); i++) - { - const CUInt32PCharPair &pair = k_VS_FileOS[i]; - if (OS == pair.Value) - { - // continue; - // f.AddString("VOS_"); - f.AddString(pair.Name); - break; - } - } - if (i == ARRAY_SIZE(k_VS_FileOS)) - { - UInt32 high = OS >> 16; - if (high < ARRAY_SIZE(k_VS_FileOS_High)) - f.AddString(k_VS_FileOS_High[high]); - else - PrintHex(f, high << 16); - UInt32 low = OS & 0xFFFF; - if (low != 0) - { - f.AddString(" | "); - if (low < ARRAY_SIZE(k_VS_FileOS_Low)) - f.AddString(k_VS_FileOS_Low[low]); - else - PrintHex(f, low); - } - } - f.NewLine(); - - f.AddString("FILETYPE "); - if (Type < ARRAY_SIZE(k_VS_FileType)) - f.AddString(k_VS_FileType[Type]); - else - PrintHex(f, Type); - f.NewLine(); - - f.AddString("FILESUBTYPE "); - bool needPrintSubType = true; - if (Type == kMY_VFT_DRV) - { - if (Subtype != 0 && Subtype < ARRAY_SIZE(k_VS_FileSubType_DRV)) - { - f.AddString("VFT2_DRV_"); - f.AddString(k_VS_FileSubType_DRV[Subtype]); - needPrintSubType = false; - } - } - else if (Type == kMY_VFT_FONT) - { - if (Subtype != 0 && Subtype < ARRAY_SIZE(k_VS_FileSubType_FONT)) - { - f.AddString(k_VS_FileSubType_FONT[Subtype]); - needPrintSubType = false; - } - } - if (needPrintSubType) - PrintHex(f, Subtype); - f.NewLine(); -} - -static void CopyToUString(const Byte *p, UString &s) -{ - for (;;) - { - wchar_t c = (wchar_t)Get16(p); - p += 2; - if (c == 0) - return; - s += c; - } -} - -static bool CompareWStrStrings(const Byte *p, const char *s) -{ - unsigned pos = 0; - for (;;) - { - Byte c = *s++; - if (Get16(p + pos) != c) - return false; - pos += 2; - if (c == 0) - return true; - } -} - -struct CVersionBlock -{ - UInt32 TotalLen; - UInt32 ValueLen; - bool IsTextValue; - unsigned StrSize; - - bool Parse(const Byte *p, UInt32 size); -}; - -static int Get_Utf16Str_Len_InBytes(const Byte *p, size_t size) -{ - unsigned pos = 0; - for (;;) - { - if (pos + 1 >= size) - return -1; - if (Get16(p + pos) == 0) - return pos; - pos += 2; - } -} - -static const unsigned k_ResoureBlockHeader_Size = 6; - -bool CVersionBlock::Parse(const Byte *p, UInt32 size) -{ - if (size < k_ResoureBlockHeader_Size) - return false; - TotalLen = Get16(p); - ValueLen = Get16(p + 2); - if (TotalLen == 0 || TotalLen > size) - return false; - switch (Get16(p + 4)) - { - case 0: IsTextValue = false; break; - case 1: IsTextValue = true; break; - default: return false; - } - StrSize = 0; - int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size, TotalLen - k_ResoureBlockHeader_Size); - if (t < 0) - return false; - StrSize = t; - return true; -} - -static void AddParamString(CTextFile &f, const Byte *p, size_t sLen) -{ - f.AddChar(' '); - f.AddChar('\"'); - f.AddBytes(p, sLen); - f.AddChar('\"'); -} - -static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector &keys) -{ - UInt32 pos; - { - const unsigned k_sizeof_VS_FIXEDFILEINFO = 13 * 4; - - CVersionBlock vb; - if (!vb.Parse(p, size)) - return false; - if (vb.ValueLen != k_sizeof_VS_FIXEDFILEINFO) // maybe 0 is allowed here? - return false; - if (vb.IsTextValue) - return false; - pos = k_ResoureBlockHeader_Size; - if (!CompareWStrStrings(p + pos, "VS_VERSION_INFO")) - return false; - pos += vb.StrSize + 2; - pos += (4 - pos) & 3; - if (pos + vb.ValueLen > vb.TotalLen) - return false; - /* sometimes resource contains zeros in remainder. - So we don't check that size != vb.TotalLen - // if (size != vb.TotalLen) return false; - */ - if (size > vb.TotalLen) - size = vb.TotalLen; - CMy_VS_FIXEDFILEINFO FixedFileInfo; - if (!FixedFileInfo.Parse(p + pos)) - return false; - FixedFileInfo.PrintToTextFile(f, keys); - pos += vb.ValueLen; - } - - f.OpenBlock(0); - - for (;;) - { - pos += (4 - pos) & 3; - if (pos >= size) - break; - - CVersionBlock vb; - if (!vb.Parse(p + pos, size - pos)) - return false; - if (vb.ValueLen != 0) - return false; - UInt32 endPos = pos + vb.TotalLen; - pos += k_ResoureBlockHeader_Size; - - f.AddSpaces(2); - f.AddString("BLOCK"); - AddParamString(f, p + pos, vb.StrSize); - - f.NewLine(); - f.OpenBlock(2); - - if (CompareWStrStrings(p + pos, "VarFileInfo")) - { - pos += vb.StrSize + 2; - for (;;) - { - pos += (4 - pos) & 3; - if (pos >= endPos) - break; - CVersionBlock vb2; - if (!vb2.Parse(p + pos, endPos - pos)) - return false; - UInt32 endPos2 = pos + vb2.TotalLen; - if (vb2.IsTextValue) - return false; - pos += k_ResoureBlockHeader_Size; - f.AddSpaces(4); - f.AddString("VALUE"); - AddParamString(f, p + pos, vb2.StrSize); - if (!CompareWStrStrings(p + pos, "Translation")) - return false; - pos += vb2.StrSize + 2; - pos += (4 - pos) & 3; - if (pos + vb2.ValueLen != endPos2) - return false; - if ((vb2.ValueLen & 3) != 0) - return false; - UInt32 num = (vb2.ValueLen >> 2); - for (; num != 0; num--, pos += 4) - { - UInt32 dw = Get32(p + pos); - UInt32 lang = LOWORD(dw); - UInt32 codePage = HIWORD(dw); - - f.AddString(", "); - PrintHex(f, lang); - f.AddString(", "); - PrintUInt32(f, codePage); - } - f.NewLine(); - } - } - else - { - if (!CompareWStrStrings(p + pos, "StringFileInfo")) - return false; - pos += vb.StrSize + 2; - - for (;;) - { - pos += (4 - pos) & 3; - if (pos >= endPos) - break; - CVersionBlock vb2; - if (!vb2.Parse(p + pos, endPos - pos)) - return false; - UInt32 endPos2 = pos + vb2.TotalLen; - if (vb2.ValueLen != 0) - return false; - pos += k_ResoureBlockHeader_Size; - - f.AddSpaces(4); - f.AddString("BLOCK"); - AddParamString(f, p + pos, vb2.StrSize); - pos += vb2.StrSize + 2; - - f.NewLine(); - f.OpenBlock(4); - - for (;;) - { - pos += (4 - pos) & 3; - if (pos >= endPos2) - break; - - CVersionBlock vb3; - if (!vb3.Parse(p + pos, endPos2 - pos)) - return false; - // ValueLen sometimes is a number of characters (not bytes)? - // So we don't use it. - UInt32 endPos3 = pos + vb3.TotalLen; - pos += k_ResoureBlockHeader_Size; - - // we don't write string if it's not text - if (vb3.IsTextValue) - { - f.AddSpaces(6); - f.AddString("VALUE"); - AddParamString(f, p + pos, vb3.StrSize); - UString key; - UString value; - CopyToUString(p + pos, key); - pos += vb3.StrSize + 2; - - pos += (4 - pos) & 3; - if (vb3.ValueLen > 0 && pos + 2 <= endPos3) - { - f.AddChar(','); - f.AddSpaces((34 - (int)vb3.StrSize) / 2); - int sLen = Get_Utf16Str_Len_InBytes(p + pos, endPos3 - pos); - if (sLen < 0) - return false; - AddParamString(f, p + pos, (unsigned)sLen); - CopyToUString(p + pos, value); - pos += sLen + 2; - } - AddToUniqueUStringVector(keys, key, value); - } - pos = endPos3; - f.NewLine(); - } - f.CloseBlock(4); - } - } - f.CloseBlock(2); - } - - f.CloseBlock(0); - return true; -} - - -HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) -{ - const CSection § = _sections[sectionIndex]; - size_t fileSize = sect.PSize; - { - size_t fileSizeMin = sect.PSize; - - if (sect.VSize < sect.PSize) - { - fileSize = fileSizeMin = sect.VSize; - const int numBits = _optHeader.GetNumFileAlignBits(); - if (numBits > 0) - { - const UInt32 mask = ((UInt32)1 << numBits) - 1; - const size_t end = (size_t)((sect.VSize + mask) & (UInt32)~mask); - if (end > sect.VSize) - if (end <= sect.PSize) - fileSize = end; - else - fileSize = sect.PSize; - } - } - - if (fileSize > kFileSizeMax) - return S_FALSE; - - { - const UInt64 fileSize64 = fileSize; - if (callback) - RINOK(callback->SetTotal(NULL, &fileSize64)); - } - - RINOK(stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); - - _buf.Alloc(fileSize); - - size_t pos; - - for (pos = 0; pos < fileSize;) - { - { - const UInt64 offset64 = pos; - if (callback) - RINOK(callback->SetCompleted(NULL, &offset64)) - } - size_t rem = MyMin(fileSize - pos, (size_t)(1 << 22)); - RINOK(ReadStream(stream, _buf + pos, &rem)); - if (rem == 0) - { - if (pos < fileSizeMin) - return S_FALSE; - break; - } - pos += rem; - } - - if (pos < fileSize) - memset(_buf + pos, 0, fileSize - pos); - } - - _usedRes.Alloc(fileSize); - CRecordVector specItems; - RINOK(ReadTable(0, specItems)); - - _oneLang = true; - bool stringsOk = true; - size_t maxOffset = 0; - - FOR_VECTOR (i, specItems) - { - const CTableItem &item1 = specItems[i]; - if ((item1.Offset & kFlag) == 0) - return S_FALSE; - - CRecordVector specItems2; - RINOK(ReadTable(item1.Offset & kMask, specItems2)); - - FOR_VECTOR (j, specItems2) - { - const CTableItem &item2 = specItems2[j]; - if ((item2.Offset & kFlag) == 0) - return S_FALSE; - - CRecordVector specItems3; - RINOK(ReadTable(item2.Offset & kMask, specItems3)); - - CResItem item; - item.Type = item1.ID; - item.ID = item2.ID; - - FOR_VECTOR (k, specItems3) - { - if (_items.Size() >= kNumResItemsMax) - return S_FALSE; - const CTableItem &item3 = specItems3[k]; - if ((item3.Offset & kFlag) != 0) - return S_FALSE; - if (item3.Offset >= _buf.Size() || _buf.Size() - item3.Offset < 16) - return S_FALSE; - const Byte *buf = _buf + item3.Offset; - item.Lang = item3.ID; - item.Offset = Get32(buf + 0); - item.Size = Get32(buf + 4); - // UInt32 codePage = Get32(buf + 8); - if (Get32(buf + 12) != 0) - return S_FALSE; - if (!_items.IsEmpty() && _oneLang && !item.IsNameEqual(_items.Back())) - _oneLang = false; - - item.HeaderSize = 0; - - size_t offset = item.Offset - sect.Va; - if (offset > maxOffset) - maxOffset = offset; - if (offset + item.Size > maxOffset) - maxOffset = offset + item.Size; - - if (CheckItem(sect, item, offset)) - { - const Byte *data = _buf + offset; - if (item.IsBmp()) - item.HeaderSize = SetBitmapHeader(item.Header, data, item.Size); - else if (item.IsIcon()) - item.HeaderSize = SetIconHeader(item.Header, data, item.Size); - else if (item.IsString()) - { - if (stringsOk) - stringsOk = ParseStringRes(item.ID, item.Lang, data, item.Size); - } - } - - if (item.IsVersion()) - { - if (offset > _buf.Size() || _buf.Size() - offset < item.Size) - continue; - CTextFile f; - if (ParseVersion((const Byte *)_buf + offset, item.Size, f, _versionKeys)) - { - CMixItem mixItem; - mixItem.VersionIndex = _versionFiles.Size(); - mixItem.SectionIndex = sectionIndex; // check it !!!! - CByteBuffer_WithLang &vf = _versionFiles.AddNew(); - vf.Lang = item.Lang; - vf.CopyFrom(f.Buf, f.Buf.GetPos()); - _mixItems.Add(mixItem); - continue; - } - // PrintError("ver.Parse error"); - } - - item.Enabled = true; - _items.Add(item); - } - } - } - - if (stringsOk && !_strings.IsEmpty()) - { - unsigned i; - for (i = 0; i < _items.Size(); i++) - { - CResItem &item = _items[i]; - if (item.IsString()) - item.Enabled = false; - } - for (i = 0; i < _strings.Size(); i++) - { - if (_strings[i].FinalSize() == 0) - continue; - CMixItem mixItem; - mixItem.StringIndex = i; - mixItem.SectionIndex = sectionIndex; - _mixItems.Add(mixItem); - } - } - - _usedRes.Free(); - - { - // PSize can be much larger than VSize in some exe installers. - // it contains archive data after PE resources. - // So we need to use PSize here! - if (maxOffset < sect.PSize) - { - size_t end = fileSize; - - // we skip Zeros to start of aligned block - size_t i; - for (i = maxOffset; i < end; i++) - if (_buf[i] != 0) - break; - if (i == end) - maxOffset = end; - - CSection sect2; - sect2.Flags = 0; - sect2.Pa = sect.Pa + (UInt32)maxOffset; - sect2.Va = sect.Va + (UInt32)maxOffset; - - // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX - // the code for .rsrc_2 is commented. - sect2.PSize = sect.PSize - (UInt32)maxOffset; - - if (sect2.PSize != 0) - { - sect2.VSize = sect2.PSize; - sect2.Name = ".rsrc_1"; - sect2.Time = 0; - sect2.IsAdditionalSection = true; - _sections.Add(sect2); - } - } - } - - return S_OK; -} - -static inline bool CheckPeOffset(UInt32 pe) -{ - return (pe >= 0x40 && pe <= 0x1000 && (pe & 7) == 0); -} - -static const unsigned kStartSize = 0x40; - -API_FUNC_static_IsArc IsArc_Pe(const Byte *p, size_t size) -{ - if (size < 2) - return k_IsArc_Res_NEED_MORE; - if (p[0] != 'M' || p[1] != 'Z') - return k_IsArc_Res_NO; - if (size < kStartSize) - return k_IsArc_Res_NEED_MORE; - UInt32 pe = Get32(p + 0x3C); - if (!CheckPeOffset(pe)) - return k_IsArc_Res_NO; - if (pe + kHeaderSize > size) - return k_IsArc_Res_NEED_MORE; - CHeader header; - if (!header.Parse(p + pe)) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) -{ - { - Byte h[kStartSize]; - _mainSubfile = -1; - RINOK(ReadStream_FALSE(stream, h, kStartSize)); - if (h[0] != 'M' || h[1] != 'Z') - return S_FALSE; - /* most of PE files contain 0x0090 at offset 2. - But some rare PE files contain another values. So we don't use that check. - if (Get16(h + 2) != 0x90) return false; */ - _peOffset = Get32(h + 0x3C); - if (!CheckPeOffset(_peOffset)) - return S_FALSE; - } - { - Byte h[kHeaderSize]; - RINOK(stream->Seek(_peOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, h, kHeaderSize)); - if (!_header.Parse(h)) - return S_FALSE; - } - - UInt32 bufSize = _header.OptHeaderSize + (UInt32)_header.NumSections * kSectionSize; - _totalSize = _peOffset + kHeaderSize + bufSize; - CByteBuffer buffer(bufSize); - - RINOK(ReadStream_FALSE(stream, buffer, bufSize)); - if (!_optHeader.Parse(buffer, _header.OptHeaderSize)) - return S_FALSE; - - UInt32 pos = _header.OptHeaderSize; - unsigned i; - for (i = 0; i < _header.NumSections; i++, pos += kSectionSize) - { - CSection § = _sections.AddNew(); - sect.Parse(buffer + pos); - sect.IsRealSect = true; - - /* PE pre-file in .hxs file has errors: - PSize of resource is larger tnan real size. - So it overlaps next ".its" section. - We correct it. */ - - if (i > 0) - { - CSection &prev = _sections[i - 1]; - if (prev.Pa < sect.Pa && - prev.Pa + prev.PSize > sect.Pa && - sect.PSize > 0) - { - // printf("\n !!!! Section correction: %s\n ", prev.Name); - // fflush(stdout); - prev.PSize = sect.Pa - prev.Pa; - } - } - /* last ".its" section in hxs file has incorrect sect.PSize. - So we reduce it to real sect.VSize */ - if (sect.VSize == 24 && sect.PSize == 512 && i == (unsigned)_header.NumSections - 1) - sect.PSize = sect.VSize; - } - - for (i = 0; i < _sections.Size(); i++) - _sections[i].UpdateTotalSize(_totalSize); - - bool thereISDebug; - RINOK(LoadDebugSections(stream, thereISDebug)); - - const CDirLink &certLink = _optHeader.DirItems[kDirLink_Certificate]; - if (certLink.Size != 0) - { - CSection § = _sections.AddNew(); - sect.Name = "CERTIFICATE"; - sect.Va = 0; - sect.Pa = certLink.Va; - sect.PSize = sect.VSize = certLink.Size; - sect.UpdateTotalSize(_totalSize); - } - - if (thereISDebug) - { - /* sometime there is some data after debug section. - We don't see any reference in exe file to that data. - But we suppose that it's part of EXE file */ - - const UInt32 kAlign = 1 << 12; - UInt32 alignPos = _totalSize & (kAlign - 1); - if (alignPos != 0) - { - UInt32 size = kAlign - alignPos; - RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL)); - buffer.Alloc(kAlign); - Byte *buf = buffer; - size_t processed = size; - RINOK(ReadStream(stream, buf, &processed)); - - /* - if (processed != 0) - { - printf("\ndata after debug %d, %d \n", (int)size, (int)processed); - fflush(stdout); - } - */ - - size_t k; - for (k = 0; k < processed; k++) - if (buf[k] != 0) - break; - if (processed < size && processed < 100) - _totalSize += (UInt32)processed; - else if (((_totalSize + k) & 0x1FF) == 0 || processed < size) - _totalSize += (UInt32)k; - } - } - - if (_header.NumSymbols > 0 && _header.PointerToSymbolTable >= 512) - { - if (_header.NumSymbols >= (1 << 24)) - return S_FALSE; - UInt32 size = _header.NumSymbols * 18; - RINOK(stream->Seek((UInt64)_header.PointerToSymbolTable + size, STREAM_SEEK_SET, NULL)); - Byte buf[4]; - RINOK(ReadStream_FALSE(stream, buf, 4)); - UInt32 size2 = Get32(buf); - if (size2 >= (1 << 28)) - return S_FALSE; - size += size2; - - CSection § = _sections.AddNew(); - sect.Name = "COFF_SYMBOLS"; - sect.Va = 0; - sect.Pa = _header.PointerToSymbolTable; - sect.PSize = sect.VSize = size; - sect.UpdateTotalSize(_totalSize); - } - - { - CObjectVector sections = _sections; - sections.Sort(); - UInt32 limit = (1 << 12); - unsigned num = 0; - FOR_VECTOR (k, sections) - { - const CSection &s = sections[k]; - if (s.Pa > limit) - { - CSection &s2 = _sections.AddNew(); - s2.Pa = s2.Va = limit; - s2.PSize = s2.VSize = s.Pa - limit; - s2.IsAdditionalSection = true; - s2.Name = '['; - s2.Name += GetDecString(num++); - s2.Name += ']'; - limit = s.Pa; - } - UInt32 next = s.Pa + s.PSize; - if (next < s.Pa) - break; - if (next >= limit) - limit = next; - } - } - - - if (_optHeader.CheckSum != 0) - { - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - UInt32 checkSum = 0; - RINOK(CalcCheckSum(stream, _totalSize, _peOffset + kHeaderSize + k_CheckSum_Field_Offset, checkSum)); - _checksumError = (checkSum != _optHeader.CheckSum); - } - - - if (!_allowTail) - { - UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - if (fileSize > _totalSize) - return S_FALSE; - } - - _parseResources = true; - // _parseResources = false; - - UInt64 mainSize = 0, mainSize2 = 0; - - for (i = 0; i < _sections.Size(); i++) - { - const CSection § = _sections[i]; - CMixItem mixItem; - mixItem.SectionIndex = i; - if (_parseResources && sect.Name == ".rsrc" && _items.IsEmpty()) - { - HRESULT res = OpenResources(i, stream, callback); - if (res == S_OK) - { - _resourcesPrefix.SetFromAscii(sect.Name); - _resourcesPrefix.Add_PathSepar(); - FOR_VECTOR (j, _items) - { - const CResItem &item = _items[j]; - if (item.Enabled) - { - mixItem.ResourceIndex = j; - if (item.IsRcDataOrUnknown()) - { - if (item.Size >= mainSize) - { - mainSize2 = mainSize; - mainSize = item.Size; - _mainSubfile = _mixItems.Size(); - } - else if (item.Size >= mainSize2) - mainSize2 = item.Size; - } - _mixItems.Add(mixItem); - } - } - // 9.29: .rsrc_2 code was commented. - // .rsrc_1 now must include that .rsrc_2 block. - /* - if (sect.PSize > sect.VSize) - { - int numBits = _optHeader.GetNumFileAlignBits(); - if (numBits >= 0) - { - UInt32 mask = (1 << numBits) - 1; - UInt32 end = ((sect.VSize + mask) & ~mask); - - if (sect.PSize > end) - { - CSection §2 = _sections.AddNew(); - sect2.Flags = 0; - sect2.Pa = sect.Pa + end; - sect2.Va = sect.Va + end; - sect2.PSize = sect.PSize - end; - sect2.VSize = sect2.PSize; - sect2.Name = ".rsrc_2"; - sect2.Time = 0; - sect2.IsAdditionalSection = true; - } - } - } - */ - continue; - } - if (res != S_FALSE) - return res; - CloseResources(); - } - if (sect.IsAdditionalSection) - { - if (sect.PSize >= mainSize) - { - mainSize2 = mainSize; - mainSize = sect.PSize; - _mainSubfile = _mixItems.Size(); - } - else if (sect.PSize >= mainSize2) - mainSize2 = sect.PSize; - } - _mixItems.Add(mixItem); - } - - if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2) - _mainSubfile = -1; - - for (i = 0; i < _mixItems.Size(); i++) - { - const CMixItem &mixItem = _mixItems[i]; - if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name == "_winzip_") - { - _mainSubfile = i; - break; - } - } - - for (i = 0; i < _versionKeys.Size(); i++) - { - if (i != 0) - _versionFullString.Add_LF(); - const CStringKeyValue &k = _versionKeys[i]; - _versionFullString += k.Key; - _versionFullString += L": "; - _versionFullString += k.Value; - } - - { - int keyIndex = FindKey(_versionKeys, "OriginalFilename"); - if (keyIndex >= 0) - _originalFilename = _versionKeys[keyIndex].Value; - } - { - int keyIndex = FindKey(_versionKeys, "FileDescription"); - if (keyIndex >= 0) - _versionShortString = _versionKeys[keyIndex].Value; - } - { - int keyIndex = FindKey(_versionKeys, "FileVersion"); - if (keyIndex >= 0) - { - _versionShortString.Add_Space(); - _versionShortString += _versionKeys[keyIndex].Value; - } - } - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(inStream, callback)); - _stream = inStream; - return S_OK; - COM_TRY_END -} - -void CHandler::CloseResources() -{ - _usedRes.Free(); - _items.Clear(); - _strings.Clear(); - _versionFiles.Clear(); - _buf.Free(); - _versionFullString.Empty(); - _versionShortString.Empty(); - _originalFilename.Empty(); - _versionKeys.Clear(); -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _checksumError = false; - _stream.Release(); - _sections.Clear(); - _mixItems.Clear(); - CloseResources(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _mixItems.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _mixItems.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const CMixItem &mixItem = _mixItems[allFilesMode ? i : indices[i]]; - UInt64 size; - if (mixItem.StringIndex >= 0) - size = _strings[mixItem.StringIndex].FinalSize(); - else if (mixItem.VersionIndex >= 0) - size = _versionFiles[mixItem.VersionIndex].Size(); - else if (mixItem.ResourceIndex >= 0) - size = _items[mixItem.ResourceIndex].GetSize(); - else - size = _sections[mixItem.SectionIndex].GetSizeExtract(); - totalSize += size; - } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - - CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - const CMixItem &mixItem = _mixItems[index]; - - const CSection § = _sections[mixItem.SectionIndex]; - bool isOk = true; - if (mixItem.StringIndex >= 0) - { - const CStringItem &item = _strings[mixItem.StringIndex]; - currentItemSize = item.FinalSize(); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - if (outStream) - RINOK(WriteStream(outStream, item.Buf, item.FinalSize())); - } - else if (mixItem.VersionIndex >= 0) - { - const CByteBuffer &item = _versionFiles[mixItem.VersionIndex]; - currentItemSize = item.Size(); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - if (outStream) - RINOK(WriteStream(outStream, item, item.Size())); - } - else if (mixItem.ResourceIndex >= 0) - { - const CResItem &item = _items[mixItem.ResourceIndex]; - currentItemSize = item.GetSize(); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - size_t offset = item.Offset - sect.Va; - if (!CheckItem(sect, item, offset)) - isOk = false; - else if (outStream) - { - if (item.HeaderSize != 0) - RINOK(WriteStream(outStream, item.Header, item.HeaderSize)); - RINOK(WriteStream(outStream, _buf + offset, item.Size)); - } - } - else - { - currentItemSize = sect.GetSizeExtract(); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - isOk = (copyCoderSpec->TotalSize == currentItemSize); - } - - outStream.Release(); - RINOK(extractCallback->SetOperationResult(isOk ? - NExtract::NOperationResult::kOK : - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - - const CMixItem &mixItem = _mixItems[index]; - const CSection § = _sections[mixItem.SectionIndex]; - if (mixItem.IsSectionItem()) - return CreateLimitedInStream(_stream, sect.Pa, sect.PSize, stream); - - CBufInStream *inStreamSpec = new CBufInStream; - CMyComPtr streamTemp = inStreamSpec; - CReferenceBuf *referenceBuf = new CReferenceBuf; - CMyComPtr ref = referenceBuf; - if (mixItem.StringIndex >= 0) - { - const CStringItem &item = _strings[mixItem.StringIndex]; - referenceBuf->Buf.CopyFrom(item.Buf, item.FinalSize()); - } - else if (mixItem.VersionIndex >= 0) - { - const CByteBuffer &item = _versionFiles[mixItem.VersionIndex]; - referenceBuf->Buf.CopyFrom(item, item.Size()); - } - else - { - const CResItem &item = _items[mixItem.ResourceIndex]; - size_t offset = item.Offset - sect.Va; - if (!CheckItem(sect, item, offset)) - return S_FALSE; - if (item.HeaderSize == 0) - { - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp2 = streamSpec; - streamSpec->Init(_buf + offset, item.Size, (IInArchive *)this); - *stream = streamTemp2.Detach(); - return S_OK; - } - referenceBuf->Buf.Alloc(item.HeaderSize + item.Size); - memcpy(referenceBuf->Buf, item.Header, item.HeaderSize); - if (item.Size != 0) - memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size); - } - inStreamSpec->Init(referenceBuf); - - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) -{ - _allowTail = IntToBool(allowTail); - return S_OK; -} - -static const Byte k_Signature[] = { 'M', 'Z' }; - -REGISTER_ARC_I( - "PE", "exe dll sys", 0, 0xDD, - k_Signature, - 0, - NArcInfoFlags::kPreArc, - IsArc_Pe) - -} - - - - -namespace NTe { - -// Terse Executable (TE) image - -struct CDataDir -{ - UInt32 Va; - UInt32 Size; - - void Parse(const Byte *p) - { - G32(0, Va); - G32(4, Size); - } -}; - -static const UInt32 kHeaderSize = 40; - -static bool FindValue(const CUInt32PCharPair *pairs, unsigned num, UInt32 value) -{ - for (unsigned i = 0; i < num; i++) - if (pairs[i].Value == value) - return true; - return false; -} - -#define MY_FIND_VALUE(pairs, value) FindValue(pairs, ARRAY_SIZE(pairs), value) - -static const UInt32 kNumSection_MAX = 32; - -struct CHeader -{ - UInt16 Machine; - Byte NumSections; - Byte SubSystem; - UInt16 StrippedSize; - /* - UInt32 AddressOfEntryPoint; - UInt32 BaseOfCode; - UInt64 ImageBase; - */ - CDataDir DataDir[2]; // base relocation and debug directory - - bool ConvertPa(UInt32 &pa) const - { - if (pa < StrippedSize) - return false; - pa = pa - StrippedSize + kHeaderSize; - return true; - } - bool Parse(const Byte *p); -}; - -bool CHeader::Parse(const Byte *p) -{ - NumSections = p[4]; - if (NumSections > kNumSection_MAX) - return false; - SubSystem = p[5]; - G16(2, Machine); - G16(6, StrippedSize); - /* - G32(8, AddressOfEntryPoint); - G32(12, BaseOfCode); - G64(16, ImageBase); - */ - for (int i = 0; i < 2; i++) - { - CDataDir &dd = DataDir[i]; - dd.Parse(p + 24 + i * 8); - if (dd.Size >= ((UInt32)1 << 28)) - return false; - } - return - MY_FIND_VALUE(NPe::g_MachinePairs, Machine) && - MY_FIND_VALUE(NPe::g_SubSystems, SubSystem); -} - -API_FUNC_static_IsArc IsArc_Te(const Byte *p, size_t size) -{ - if (size < 2) - return k_IsArc_Res_NEED_MORE; - if (p[0] != 'V' || p[1] != 'Z') - return k_IsArc_Res_NO; - if (size < kHeaderSize) - return k_IsArc_Res_NEED_MORE; - - CHeader h; - if (!h.Parse(p)) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - - -struct CSection -{ - Byte Name[NPe::kNameSize]; - - UInt32 VSize; - UInt32 Va; - UInt32 PSize; - UInt32 Pa; - UInt32 Flags; - // UInt16 NumRelocs; - - void Parse(const Byte *p) - { - memcpy(Name, p, NPe::kNameSize); - G32(8, VSize); - G32(12, Va); - G32(16, PSize); - G32(20, Pa); - // G32(p + 32, NumRelocs); - G32(36, Flags); - } - - bool Check() const - { - return - Pa <= ((UInt32)1 << 30) && - PSize <= ((UInt32)1 << 30); - } - - void UpdateTotalSize(UInt32 &totalSize) - { - UInt32 t = Pa + PSize; - if (t > totalSize) - totalSize = t; - } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public IArchiveAllowTail, - public CMyUnknownImp -{ - CRecordVector _items; - CMyComPtr _stream; - UInt32 _totalSize; - bool _allowTail; - CHeader _h; - - HRESULT Open2(IInStream *stream); -public: - MY_UNKNOWN_IMP3(IInArchive, IInArchiveGetStream, IArchiveAllowTail) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(AllowTail)(Int32 allowTail); - CHandler(): _allowTail(false) {} -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidVirtualSize, - kpidCharacts, - kpidOffset, - kpidVa -}; - -enum -{ - kpidSubSystem = kpidUserDefined, - // , kpidImageBase -}; - -static const CStatProp kArcProps[] = -{ - // { NULL, kpidHeadersSize, VT_UI4 }, - { NULL, kpidCpu, VT_BSTR}, - { "Subsystem", kpidSubSystem, VT_BSTR }, - // { "Image Base", kpidImageBase, VT_UI8 } -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _totalSize; break; - case kpidCpu: PAIR_TO_PROP(NPe::g_MachinePairs, _h.Machine, prop); break; - case kpidSubSystem: PAIR_TO_PROP(NPe::g_SubSystems, _h.SubSystem, prop); break; - /* - case kpidImageBase: prop = _h.ImageBase; break; - case kpidAddressOfEntryPoint: prop = _h.AddressOfEntryPoint; break; - case kpidBaseOfCode: prop = _h.BaseOfCode; 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; - { - const CSection &item = _items[index]; - switch (propID) - { - case kpidPath: - { - AString name; - NPe::GetName(item.Name, name); - prop = MultiByteToUnicodeString(name); - break; - } - case kpidSize: - case kpidPackSize: prop = (UInt64)item.PSize; break; - case kpidVirtualSize: prop = (UInt64)item.VSize; break; - case kpidOffset: prop = item.Pa; break; - case kpidVa: prop = item.Va; break; - case kpidCharacts: FLAGS_TO_PROP(NPe::g_SectFlags, item.Flags, prop); break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - Byte h[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, h, kHeaderSize)); - if (h[0] != 'V' || h[1] != 'Z') - return S_FALSE; - if (!_h.Parse(h)) - return S_FALSE; - - UInt32 headerSize = NPe::kSectionSize * (UInt32)_h.NumSections; - CByteArr buf(headerSize); - RINOK(ReadStream_FALSE(stream, buf, headerSize)); - headerSize += kHeaderSize; - - _totalSize = headerSize; - _items.ClearAndReserve(_h.NumSections); - for (UInt32 i = 0; i < _h.NumSections; i++) - { - CSection sect; - sect.Parse(buf + i * NPe::kSectionSize); - if (!_h.ConvertPa(sect.Pa)) - return S_FALSE; - if (sect.Pa < headerSize) - return S_FALSE; - if (!sect.Check()) - return S_FALSE; - _items.AddInReserved(sect); - sect.UpdateTotalSize(_totalSize); - } - - if (!_allowTail) - { - UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - if (fileSize > _totalSize) - return S_FALSE; - } - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - try - { - if (Open2(inStream) != S_OK) - return S_FALSE; - _stream = inStream; - } - catch(...) { return S_FALSE; } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _stream.Release(); - _items.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - 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++) - totalSize += _items[allFilesMode ? i : indices[i]].PSize; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CSection &item = _items[index]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentTotalSize += item.PSize; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - int res = NExtract::NOperationResult::kDataError; - - RINOK(_stream->Seek(item.Pa, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.PSize); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.PSize) - res = NExtract::NOperationResult::kOK; - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CSection &item = _items[index]; - return CreateLimitedInStream(_stream, item.Pa, item.PSize, stream); - COM_TRY_END -} - -STDMETHODIMP CHandler::AllowTail(Int32 allowTail) -{ - _allowTail = IntToBool(allowTail); - return S_OK; -} - -static const Byte k_Signature[] = { 'V', 'Z' }; - -REGISTER_ARC_I( - "TE", "te", 0, 0xCF, - k_Signature, - 0, - NArcInfoFlags::kPreArc, - IsArc_Te) - -} -} +// PeHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/DynamicBuffer.h" +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringConvert.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" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define G16(offs, v) v = Get16(p + (offs)) +#define G32(offs, v) v = Get32(p + (offs)) +#define G32_signed(offs, v) v = (Int32)Get32(p + (offs)) +#define G64(offs, v) v = Get64(p + (offs)) + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + +using namespace NWindows; + +namespace NArchive { +namespace NPe { + +static const UInt32 k_Signature32 = 0x00004550; + +static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos, UInt32 &res) +{ + const UInt32 kBufSizeMax = (UInt32)1 << 15; + UInt32 bufSize = kBufSizeMax; + CByteBuffer buffer(bufSize); + Byte *buf = buffer; + UInt32 sum = 0; + UInt32 pos = 0; + for (;;) + { + UInt32 rem = size - pos; + if (rem > bufSize) + rem = bufSize; + if (rem == 0) + break; + size_t processed = rem; + RINOK(ReadStream(stream, buf, &processed)) + + for (unsigned j = 0; j < 4; j++) + { + UInt32 e = excludePos + j; + if (pos <= e) + { + e -= pos; + if (e < processed) + buf[e] = 0; + } + } + + const unsigned kStep = (1 << 4); + { + for (size_t i = processed; (i & (kStep - 1)) != 0; i++) + buf[i] = 0; + } + { + const Byte *buf2 = buf; + const Byte *bufLimit = buf + processed; + UInt64 sum2 = 0; + for (; buf2 < bufLimit; buf2 += kStep) + { + UInt64 sum3 = (UInt64)Get32(buf2) + + Get32(buf2 + 4) + + Get32(buf2 + 8) + + Get32(buf2 + 12); + sum2 += sum3; + } + sum2 = (UInt32)(sum2) + (UInt64)(sum2 >> 32); + UInt32 sum3 = ((UInt32)sum2 + (UInt32)(sum2 >> 32)); + sum += (sum3 & 0xFFFF) + (sum3 >> 16); + sum = (sum & 0xFFFF) + (sum >> 16); + sum = (sum & 0xFFFF) + (sum >> 16); + } + + pos += (UInt32)processed; + if (rem != processed) + break; + } + res = sum + pos; + return S_OK; +} + + +struct CVersion +{ + UInt16 Major; + UInt16 Minor; + + void Parse(const Byte *p) + { + G16(0, Major); + G16(2, Minor); + } + void ToProp(NCOM::CPropVariant &prop); +}; + +void CVersion::ToProp(NCOM::CPropVariant &prop) +{ + char sz[32]; + ConvertUInt32ToString(Major, sz); + unsigned len = MyStringLen(sz); + sz[len] = '.'; + ConvertUInt32ToString(Minor, sz + len + 1); + prop = sz; +} + +static const unsigned kCoffHeaderSize = 20; +static const unsigned kPeHeaderSize = 4 + kCoffHeaderSize; +static const unsigned k_OptHeader32_Size_MIN = 96; +static const unsigned k_OptHeader64_Size_MIN = 112; + +static const UInt32 PE_IMAGE_FILE_DLL = (1 << 13); + +struct CHeader +{ + UInt16 Machine; + UInt16 NumSections; + UInt32 Time; + UInt32 PointerToSymbolTable; + UInt32 NumSymbols; + UInt16 OptHeaderSize; + UInt16 Flags; + + void ParseBase(const Byte *p); + bool ParseCoff(const Byte *p); + bool ParsePe(const Byte *p); + bool IsDll() const { return (Flags & PE_IMAGE_FILE_DLL) != 0; } +}; + +void CHeader::ParseBase(const Byte *p) +{ + G16( 0, Machine); + G16( 2, NumSections); + G32( 4, Time); + G32( 8, PointerToSymbolTable); + G32(12, NumSymbols); + G16(16, OptHeaderSize); + G16(18, Flags); +} + +bool CHeader::ParsePe(const Byte *p) +{ + if (Get32(p) != k_Signature32) + return false; + ParseBase(p + 4); + return OptHeaderSize >= k_OptHeader32_Size_MIN; +} + +struct CDirLink +{ + UInt32 Va; + UInt32 Size; + + CDirLink(): Va(0), Size(0) {} + void Parse(const Byte *p) + { + G32(0, Va); + G32(4, Size); + } +}; + + +// IMAGE_DIRECTORY_ENTRY_* +static const char * const g_Dir_Names[] = +{ + "EXPORT" + , "IMPORT" + , "RESOURCE" + , "EXCEPTION" + , "SECURITY" + , "BASERELOC" + , "DEBUG" + , "ARCHITECTURE" // "COPYRIGHT" + , "GLOBALPTR" + , "TLS" + , "LOAD_CONFIG" + , "BOUND_IMPORT" + , "IAT" + , "DELAY_IMPORT" + , "COM_DESCRIPTOR" +}; + +enum +{ + kDirLink_EXCEPTION = 3, + kDirLink_Certificate = 4, + kDirLink_BASERELOC = 5, + kDirLink_Debug = 6 +}; + +static const UInt32 kNumDirItemsMax = 16; + +struct CDebugEntry +{ + UInt32 Flags; + UInt32 Time; + CVersion Ver; + UInt32 Type; + UInt32 Size; + UInt32 Va; + UInt32 Pa; + + void Parse(const Byte *p) + { + G32(0, Flags); + G32(4, Time); + Ver.Parse(p + 8); + G32(12, Type); + G32(16, Size); + G32(20, Va); + G32(24, Pa); + } +}; + +static const UInt32 k_CheckSum_Field_Offset = 64; + +static const UInt32 PE_OptHeader_Magic_32 = 0x10B; +static const UInt32 PE_OptHeader_Magic_64 = 0x20B; + +static const UInt32 k_SubSystems_EFI_First = 10; +static const UInt32 k_SubSystems_EFI_Last = 13; + +struct COptHeader +{ + UInt16 Magic; + Byte LinkerVerMajor; + Byte LinkerVerMinor; + + UInt32 CodeSize; + UInt32 InitDataSize; + UInt32 UninitDataSize; + + // UInt32 AddressOfEntryPoint; + // UInt32 BaseOfCode; // VA(.text) == 0x1000 in most cases + // UInt32 BaseOfData32; + UInt64 ImageBase; + + UInt32 SectAlign; + UInt32 FileAlign; + + CVersion OsVer; + CVersion ImageVer; + CVersion SubsysVer; + + UInt32 ImageSize; + UInt32 HeadersSize; + UInt32 CheckSum; + UInt16 SubSystem; + UInt16 DllCharacts; + + UInt64 StackReserve; + UInt64 StackCommit; + UInt64 HeapReserve; + UInt64 HeapCommit; + + UInt32 NumDirItems; + CDirLink DirItems[kNumDirItemsMax]; + + bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; } + bool Parse(const Byte *p, UInt32 size); + + int GetNumFileAlignBits() const + { + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == FileAlign) + return (int)i; + return -1; + } + + bool IsSybSystem_EFI() const + { + return + SubSystem >= k_SubSystems_EFI_First && + SubSystem <= k_SubSystems_EFI_Last; + } +}; + +// size is 16-bit +bool COptHeader::Parse(const Byte *p, UInt32 size) +{ + if (size < k_OptHeader32_Size_MIN) + return false; + Magic = Get16(p); + switch (Magic) + { + case PE_OptHeader_Magic_32: + case PE_OptHeader_Magic_64: + break; + default: + return false; + } + LinkerVerMajor = p[2]; + LinkerVerMinor = p[3]; + + G32( 4, CodeSize); + G32( 8, InitDataSize); + G32(12, UninitDataSize); + // G32(16, AddressOfEntryPoint); + // G32(20, BaseOfCode); + + G32(32, SectAlign); + G32(36, FileAlign); + + OsVer.Parse(p + 40); + ImageVer.Parse(p + 44); + SubsysVer.Parse(p + 48); + + // reserved = Get32(p + 52); + + G32(56, ImageSize); + G32(60, HeadersSize); + G32(64, CheckSum); + G16(68, SubSystem); + G16(70, DllCharacts); + + UInt32 pos; + if (Is64Bit()) + { + if (size < k_OptHeader64_Size_MIN) + return false; + // BaseOfData32 = 0; + G64(24, ImageBase); + G64(72, StackReserve); + G64(80, StackCommit); + G64(88, HeapReserve); + G64(96, HeapCommit); + pos = 108; + } + else + { + // G32(24, BaseOfData32); + G32(28, ImageBase); + G32(72, StackReserve); + G32(76, StackCommit); + G32(80, HeapReserve); + G32(84, HeapCommit); + pos = 92; + } + + UInt32 numDirItems; + G32(pos, numDirItems); + NumDirItems = numDirItems; + if (numDirItems > (1 << 13)) + return false; + pos += 4; + if (pos + 8 * numDirItems > size) + return false; + memset((void *)DirItems, 0, sizeof(DirItems)); + if (numDirItems > kNumDirItemsMax) + numDirItems = kNumDirItemsMax; + for (UInt32 i = 0; i < numDirItems; i++) + DirItems[i].Parse(p + pos + i * 8); + return true; +} + +static const UInt32 kSectionSize = 40; + +struct CSection +{ + AString Name; + + UInt32 ExtractSize; + UInt32 VSize; + UInt32 Va; + UInt32 PSize; + UInt32 Pa; + UInt32 Flags; + UInt32 Time; + // UInt16 NumRelocs; // is set to zero for executable images + bool IsRealSect; + bool IsDebug; + bool IsAdditionalSection; + + CSection(): + ExtractSize(0), + IsRealSect(false), + IsDebug(false), + IsAdditionalSection(false) + // , NumRelocs(0) + {} + + void Set_Size_for_all(UInt32 size) + { + PSize = VSize = ExtractSize = size; + } + + UInt32 GetSize_Extract() const + { + return ExtractSize; + } + + void UpdateTotalSize(UInt32 &totalSize) const + { + const UInt32 t = Pa + PSize; + if (totalSize < t) + totalSize = t; + } + + void Parse(const Byte *p); + + int Compare(const CSection &s) const + { + RINOZ(MyCompare(Pa, s.Pa)) + const UInt32 size1 = GetSize_Extract(); + const UInt32 size2 = s.GetSize_Extract(); + return MyCompare(size1, size2); + } +}; + +static const unsigned kNameSize = 8; + +static void GetName(const Byte *name, AString &res) +{ + res.SetFrom_CalcLen((const char *)name, kNameSize); +} + +void CSection::Parse(const Byte *p) +{ + GetName(p, Name); + G32( 8, VSize); + G32(12, Va); + G32(16, PSize); + G32(20, Pa); + // G16(32, NumRelocs); + G32(36, Flags); + // v24.08: we extract only useful data (without extra padding bytes). + // VSize == 0 is not expected, but we support that case too. + // return (VSize && VSize < PSize) ? VSize : PSize; + ExtractSize = (VSize && VSize < PSize) ? VSize : PSize; +} + + + +// IMAGE_FILE_* + +static const CUInt32PCharPair g_HeaderCharacts[] = +{ + { 1, "Executable" }, + { 13, "DLL" }, + { 8, "32-bit" }, + { 5, "LargeAddress" }, + { 0, "NoRelocs" }, + { 2, "NoLineNums" }, + { 3, "NoLocalSyms" }, + { 4, "AggressiveWsTrim" }, + { 9, "NoDebugInfo" }, + { 10, "RemovableRun" }, + { 11, "NetRun" }, + { 12, "System" }, + { 14, "UniCPU" }, + { 7, "Little-Endian" }, + { 15, "Big-Endian" } +}; + +// IMAGE_DLLCHARACTERISTICS_* + +static const char * const g_DllCharacts[] = +{ + NULL + , NULL + , NULL + , NULL + , NULL + , "HighEntropyVA" + , "Relocated" + , "Integrity" + , "NX-Compatible" + , "NoIsolation" + , "NoSEH" + , "NoBind" + , "AppContainer" + , "WDM" + , "GuardCF" + , "TerminalServerAware" +}; + + +// IMAGE_SCN_* constants: + +static const char * const g_SectFlags[] = +{ + NULL + , NULL + , NULL + , "NoPad" + , NULL + , "Code" + , "InitializedData" + , "UninitializedData" + , "Other" + , "Comments" + , NULL // OVER + , "Remove" + , "COMDAT" + , NULL + , "NO_DEFER_SPEC_EXC" + , "GP" // MEM_FARDATA + , NULL // SYSHEAP + , "PURGEABLE" // 16BIT + , "LOCKED" + , "PRELOAD" + , NULL + , NULL + , NULL + , NULL + , "ExtendedRelocations" + , "Discardable" + , "NotCached" + , "NotPaged" + , "Shared" + , "Execute" + , "Read" + , "Write" +}; + +static const CUInt32PCharPair g_MachinePairs[] = +{ + { 0x014C, "x86" }, + { 0x014D, "I860" }, + { 0x0162, "MIPS-R3000" }, + { 0x0166, "MIPS-R4000" }, + { 0x0168, "MIPS-R10000" }, + { 0x0169, "MIPS-V2" }, + { 0x0184, "Alpha" }, + { 0x01A2, "SH3" }, + { 0x01A3, "SH3-DSP" }, + { 0x01A4, "SH3E" }, + { 0x01A6, "SH4" }, + { 0x01A8, "SH5" }, + { 0x01C0, "ARM" }, + { 0x01C2, "ARM-Thumb" }, + { 0x01C4, "ARM-NT" }, + { 0x01D3, "AM33" }, + { 0x01F0, "PPC" }, + { 0x01F1, "PPC-FP" }, + { 0x01F2, "PPC-BE" }, + { 0x0200, "IA-64" }, + { 0x0266, "MIPS-16" }, + { 0x0284, "Alpha-64" }, + { 0x0366, "MIPS-FPU" }, + { 0x0466, "MIPS-FPU16" }, + { 0x0520, "TriCore" }, + { 0x0CEF, "CEF" }, + { 0x0EBC, "EFI" }, + { 0x5032, "RISCV32" }, + { 0x5064, "RISCV64" }, +// { 0x5128, "RISCV128" }, + { 0x6232, "LOONGARCH32" }, + { 0x6264, "LOONGARCH64" }, + { 0x8664, "x64" }, + { 0x9041, "M32R" }, + { 0xA641, "ARM64EC" }, + { 0xA64e, "ARM64X" }, + { 0xAA64, "ARM64" }, + { 0xC0EE, "CEE" } +}; + +static const char * const g_SubSystems[] = +{ + "Unknown" + , "Native" + , "Windows GUI" + , "Windows CUI" + , NULL // "Old Windows CE" + , "OS2" + , NULL + , "Posix" + , "Win9x" + , "Windows CE" + , "EFI" + , "EFI Boot" + , "EFI Runtime" + , "EFI ROM" + , "XBOX" + , NULL + , "Windows Boot" + , "XBOX Catalog" // 17 +}; + +static const char * const g_ResTypes[] = +{ + NULL + , "CURSOR" + , "BITMAP" + , "ICON" + , "MENU" + , "DIALOG" + , "STRING" + , "FONTDIR" + , "FONT" + , "ACCELERATOR" + , "RCDATA" + , "MESSAGETABLE" + , "GROUP_CURSOR" + , NULL + , "GROUP_ICON" + , NULL + , "VERSION" + , "DLGINCLUDE" + , NULL + , "PLUGPLAY" + , "VXD" + , "ANICURSOR" + , "ANIICON" + , "HTML" + , "MANIFEST" +}; + +static const UInt32 kFlag = (UInt32)1 << 31; +static const UInt32 kMask = ~kFlag; + +struct CTableItem +{ + UInt32 Offset; + UInt32 ID; +}; + + +static const UInt32 kBmpHeaderSize = 14; +static const UInt32 kIconHeaderSize = 22; + +struct CResItem +{ + UInt32 Type; + UInt32 ID; + UInt32 Lang; + + UInt32 Size; + UInt32 Offset; + + UInt32 HeaderSize; + Byte Header[kIconHeaderSize]; // it must be enough for max size header. + bool Enabled; + + bool IsNameEqual(const CResItem &item) const { return Lang == item.Lang; } + UInt32 GetSize() const { return Size + HeaderSize; } + bool IsBmp() const { return Type == 2; } + bool IsIcon() const { return Type == 3; } + bool IsString() const { return Type == 6; } + bool IsRcData() const { return Type == 10; } + bool IsVersion() const { return Type == 16; } + bool IsRcDataOrUnknown() const { return IsRcData() || Type > 64; } +}; + +struct CTextFile +{ + CByteDynamicBuffer Buf; + + size_t FinalSize() const { return Buf.GetPos(); } + + void AddChar(char c); + void AddWChar(UInt16 c); + void AddWChar_Smart(UInt16 c); + void NewLine(); + void AddString(const char *s); + void AddSpaces(int num); + void AddBytes(const Byte *p, size_t size) + { + Buf.AddData(p, size); + } + + void OpenBlock(int num) + { + AddSpaces(num); + AddChar('{'); + NewLine(); + } + void CloseBlock(int num) + { + AddSpaces(num); + AddChar('}'); + NewLine(); + } +}; + +void CTextFile::AddChar(char c) +{ + Byte *p = Buf.GetCurPtrAndGrow(2); + p[0] = (Byte)c; + p[1] = 0; +} + +void CTextFile::AddWChar(UInt16 c) +{ + Byte *p = Buf.GetCurPtrAndGrow(2); + SetUi16(p, c) +} + +void CTextFile::AddWChar_Smart(UInt16 c) +{ + if (c == '\n') + { + AddChar('\\'); + c = 'n'; + } + AddWChar(c); +} + +void CTextFile::NewLine() +{ + AddChar(0x0D); + AddChar(0x0A); +} + +void CTextFile::AddString(const char *s) +{ + for (;; s++) + { + char c = *s; + if (c == 0) + return; + AddChar(c); + } +} + +void CTextFile::AddSpaces(int num) +{ + for (int i = 0; i < num; i++) + AddChar(' '); +} + +struct CStringItem: public CTextFile +{ + UInt32 Lang; +}; + +struct CByteBuffer_WithLang: public CByteBuffer +{ + UInt32 Lang; +}; + + +struct CMixItem +{ + int SectionIndex; + int ResourceIndex; + int StringIndex; + int VersionIndex; + + CMixItem(): SectionIndex(-1), ResourceIndex(-1), StringIndex(-1), VersionIndex(-1) {} + bool IsSectionItem() const { return ResourceIndex < 0 && StringIndex < 0 && VersionIndex < 0; } +}; + +struct CUsedBitmap +{ + CByteBuffer Buf; +public: + void Alloc(size_t size) + { + size = (size + 7) / 8; + Buf.Alloc(size); + memset(Buf, 0, size); + } + + void Free() + { + Buf.Free(); + } + + bool SetRange(size_t from, unsigned size) + { + for (unsigned i = 0; i < size; i++) + { + size_t pos = (from + i) >> 3; + Byte mask = (Byte)(1 << ((from + i) & 7)); + Byte b = Buf[pos]; + if ((b & mask) != 0) + return false; + Buf[pos] = (Byte)(b | mask); + } + return true; + } +}; + +struct CStringKeyValue +{ + UString Key; + UString Value; +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IInArchiveGetStream, + IArchiveAllowTail +) + CMyComPtr _stream; + CObjectVector _sections; + CHeader _header; + UInt32 _totalSize; + Int32 _mainSubfile; + + CRecordVector _mixItems; + CRecordVector _items; + CObjectVector _strings; + CObjectVector _versionFiles; + UString _versionFullString; + UString _versionShortString; + UString _originalFilename; + CObjectVector _versionKeys; + + CByteBuffer _buf; + bool _oneLang; + UString _resourcesPrefix; + CUsedBitmap _usedRes; + // bool _parseResources; + bool _checksumError; + bool _sectionsError; + + bool IsOpt() const { return _header.OptHeaderSize != 0; } + + COptHeader _optHeader; + + bool _coffMode; + bool _allowTail; + + HRESULT LoadDebugSections(IInStream *stream, bool &thereIsSection); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + + void AddResNameToString(UString &s, UInt32 id) const; + void AddLangPrefix(UString &s, UInt32 lang) const; + HRESULT ReadString(UInt32 offset, UString &dest) const; + HRESULT ReadTable(UInt32 offset, CRecordVector &items); + bool ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size); + HRESULT OpenResources(unsigned sectIndex, IInStream *stream, IArchiveOpenCallback *callback); + void CloseResources(); + + + bool CheckItem(const CSection §, const CResItem &item, size_t offset) const + { + return item.Offset >= sect.Va && offset <= _buf.Size() && _buf.Size() - offset >= item.Size; + } + +public: + CHandler(bool coffMode = false): + _coffMode(coffMode), + _allowTail(coffMode) + {} +}; + + +enum +{ + kpidSectAlign = kpidUserDefined, + kpidFileAlign, + kpidLinkerVer, + kpidOsVer, + kpidImageVer, + kpidSubsysVer, + kpidCodeSize, + kpidImageSize, + kpidInitDataSize, + kpidUnInitDataSize, + kpidHeadersSizeUnInitDataSize, + kpidSubSystem, + kpidDllCharacts, + kpidStackReserve, + kpidStackCommit, + kpidHeapReserve, + kpidHeapCommit + // , kpidImageBase + // , kpidAddressOfEntryPoint + // , kpidBaseOfCode + // , kpidBaseOfData32 +}; + +static const CStatProp kArcProps[] = +{ + // { NULL, kpidWarning, VT_BSTR}, + { NULL, kpidCpu, VT_BSTR}, + { NULL, kpidBit64, VT_BOOL}, + { NULL, kpidCharacts, VT_BSTR}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidHeadersSize, VT_UI4}, + { NULL, kpidChecksum, VT_UI4}, + { NULL, kpidName, VT_BSTR}, + + { "Image Size", kpidImageSize, VT_UI4}, + { "Section Alignment", kpidSectAlign, VT_UI4}, + { "File Alignment", kpidFileAlign, VT_UI4}, + { "Code Size", kpidCodeSize, VT_UI4}, + { "Initialized Data Size", kpidInitDataSize, VT_UI4}, + { "Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, + { "Linker Version", kpidLinkerVer, VT_BSTR}, + { "OS Version", kpidOsVer, VT_BSTR}, + { "Image Version", kpidImageVer, VT_BSTR}, + { "Subsystem Version", kpidSubsysVer, VT_BSTR}, + { "Subsystem", kpidSubSystem, VT_BSTR}, + { "DLL Characteristics", kpidDllCharacts, VT_BSTR}, + { "Stack Reserve", kpidStackReserve, VT_UI8}, + { "Stack Commit", kpidStackCommit, VT_UI8}, + { "Heap Reserve", kpidHeapReserve, VT_UI8}, + { "Heap Commit", kpidHeapCommit, VT_UI8}, + { NULL, kpidVa, VT_UI8 }, // "Image Base", kpidImageBase, VT_UI8 + { NULL, kpidComment, VT_BSTR} + + // , { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8} + // , { "Base Of Code", kpidBaseOfCode, VT_UI8} + // , { "Base Of Data", kpidBaseOfData32, VT_UI8} +}; + +// #define kpid_NumRelocs 250 + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidVirtualSize, + kpidCharacts, + kpidOffset, + kpidVa + // , kpid_NumRelocs +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void TimeToProp(UInt32 unixTime, NCOM::CPropVariant &prop) +{ + if (unixTime != 0) + PropVariant_SetFrom_UnixTime(prop, unixTime); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _totalSize; break; + case kpidComment: + { + UString s (_versionFullString); + s.Add_LF(); + s += "Data Directories: "; + s.Add_UInt32(_optHeader.NumDirItems); + s.Add_LF(); + s.Add_Char('{'); + s.Add_LF(); + for (unsigned i = 0; i < _optHeader.NumDirItems + && i < Z7_ARRAY_SIZE(_optHeader.DirItems); i++) + { + const CDirLink &di = _optHeader.DirItems[i]; + if (di.Va == 0 && di.Size == 0) + continue; + s += "index="; + s.Add_UInt32(i); + + if (i < Z7_ARRAY_SIZE(g_Dir_Names)) + { + s += " name="; + s += g_Dir_Names[i]; + } + s += " VA=0x"; + char temp[16]; + ConvertUInt32ToHex(di.Va, temp); + s += temp; + s += " Size="; + s.Add_UInt32(di.Size); + s.Add_LF(); + } + s.Add_Char('}'); + s.Add_LF(); + prop = s; + break; + } + case kpidShortComment: + if (!_versionShortString.IsEmpty()) + prop = _versionShortString; + else + { + PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); + } + break; + + case kpidName: if (!_originalFilename.IsEmpty()) prop = _originalFilename; break; + + // case kpidIsSelfExe: prop = !_header.IsDll(); break; + // case kpidError: + case kpidWarning: if (_checksumError) prop = "Checksum error"; break; + + case kpidWarningFlags: + { + UInt32 v = 0; + if (_sectionsError) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + + case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; + case kpidMTime: + case kpidCTime: TimeToProp(_header.Time, prop); break; + case kpidCharacts: FLAGS_TO_PROP(g_HeaderCharacts, _header.Flags, prop); break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; + + default: + if (IsOpt()) + switch (propID) + { + + case kpidSectAlign: prop = _optHeader.SectAlign; break; + case kpidFileAlign: prop = _optHeader.FileAlign; break; + case kpidLinkerVer: + { + CVersion v = { _optHeader.LinkerVerMajor, _optHeader.LinkerVerMinor }; + v.ToProp(prop); + break; + } + + case kpidOsVer: _optHeader.OsVer.ToProp(prop); break; + case kpidImageVer: _optHeader.ImageVer.ToProp(prop); break; + case kpidSubsysVer: _optHeader.SubsysVer.ToProp(prop); break; + case kpidCodeSize: prop = _optHeader.CodeSize; break; + case kpidInitDataSize: prop = _optHeader.InitDataSize; break; + case kpidUnInitDataSize: prop = _optHeader.UninitDataSize; break; + case kpidImageSize: prop = _optHeader.ImageSize; break; + case kpidHeadersSize: prop = _optHeader.HeadersSize; break; + case kpidChecksum: prop = _optHeader.CheckSum; break; + + case kpidExtension: + if (_header.IsDll()) + prop = "dll"; + else if (_optHeader.IsSybSystem_EFI()) + prop = "efi"; + break; + + case kpidBit64: if (_optHeader.Is64Bit()) prop = true; break; + case kpidSubSystem: TYPE_TO_PROP(g_SubSystems, _optHeader.SubSystem, prop); break; + + case kpidDllCharacts: FLAGS_TO_PROP(g_DllCharacts, _optHeader.DllCharacts, prop); break; + case kpidStackReserve: prop = _optHeader.StackReserve; break; + case kpidStackCommit: prop = _optHeader.StackCommit; break; + case kpidHeapReserve: prop = _optHeader.HeapReserve; break; + case kpidHeapCommit: prop = _optHeader.HeapCommit; break; + case kpidVa: prop = _optHeader.ImageBase; break; // kpidImageBase: + // case kpidAddressOfEntryPoint: prop = _optHeader.AddressOfEntryPoint; break; + // case kpidBaseOfCode: prop = _optHeader.BaseOfCode; break; + // case kpidBaseOfData32: if (!_optHeader.Is64Bit()) prop = _optHeader.BaseOfData32; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::ReadString(UInt32 offset, UString &dest) const +{ + if ((offset & 1) != 0 || offset >= _buf.Size()) + return S_FALSE; + size_t rem = _buf.Size() - offset; + if (rem < 2) + return S_FALSE; + unsigned len = Get16(_buf + offset); + if ((rem - 2) / 2 < len) + return S_FALSE; + dest.Empty(); + wchar_t *destBuf = dest.GetBuf(len); + offset += 2; + const Byte *src = _buf + offset; + unsigned i; + for (i = 0; i < len; i++) + { + wchar_t c = (wchar_t)Get16(src + i * 2); + if (c == 0) + break; + destBuf[i] = c; + } + destBuf[i] = 0; + dest.ReleaseBuf_SetLen(i); + return S_OK; +} + +void CHandler::AddResNameToString(UString &s, UInt32 id) const +{ + if ((id & kFlag) != 0) + { + UString name; + if (ReadString(id & kMask, name) == S_OK) + { + const wchar_t *str = L"[]"; + if (name.Len() > 1 && name[0] == '"' && name.Back() == '"') + { + if (name.Len() != 2) + { + name.DeleteBack(); + str = name.Ptr(1); + } + } + else if (!name.IsEmpty()) + str = name; + s += str; + return; + } + } + s.Add_UInt32(id); +} + +void CHandler::AddLangPrefix(UString &s, UInt32 lang) const +{ + if (!_oneLang) + { + AddResNameToString(s, lang); + s.Add_PathSepar(); + } +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CMixItem &mixItem = _mixItems[index]; + if (mixItem.StringIndex >= 0) + { + const CStringItem &item = _strings[mixItem.StringIndex]; + switch (propID) + { + case kpidPath: + { + UString s = _resourcesPrefix; + AddLangPrefix(s, item.Lang); + s += "string.txt"; + prop = s; + break; + } + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.FinalSize(); break; + } + } + else if (mixItem.VersionIndex >= 0) + { + const CByteBuffer_WithLang &item = _versionFiles[mixItem.VersionIndex]; + switch (propID) + { + case kpidPath: + { + UString s = _resourcesPrefix; + AddLangPrefix(s, item.Lang); + s += "version.txt"; + prop = s; + break; + } + case kpidSize: + case kpidPackSize: + prop = (UInt64)item.Size(); break; + } + } + else if (mixItem.ResourceIndex >= 0) + { + const CResItem &item = _items[mixItem.ResourceIndex]; + switch (propID) + { + case kpidPath: + { + UString s = _resourcesPrefix; + AddLangPrefix(s, item.Lang); + { + const char *p = NULL; + if (item.Type < Z7_ARRAY_SIZE(g_ResTypes)) + p = g_ResTypes[item.Type]; + if (p) + s += p; + else + AddResNameToString(s, item.Type); + } + s.Add_PathSepar(); + AddResNameToString(s, item.ID); + if (item.HeaderSize != 0) + { + if (item.IsBmp()) + s += ".bmp"; + else if (item.IsIcon()) + s += ".ico"; + } + prop = s; + break; + } + case kpidSize: prop = (UInt64)item.GetSize(); break; + case kpidPackSize: prop = (UInt64)item.Size; break; + } + } + else + { + const CSection &item = _sections[mixItem.SectionIndex]; + switch (propID) + { + case kpidPath: + { + AString s = item.Name; + s.Replace('/', '_'); + s.Replace('\\', '_'); + prop = MultiByteToUnicodeString(s); + break; + } + case kpidSize: prop = (UInt64)item.GetSize_Extract(); break; + // case kpid_NumRelocs: prop = (UInt32)item.NumRelocs; break; + case kpidPackSize: prop = (UInt64)item.PSize; break; + case kpidVirtualSize: prop = (UInt64)item.VSize; break; + case kpidOffset: prop = item.Pa; break; + case kpidVa: if (item.IsRealSect) prop = item.Va; break; + case kpidMTime: + case kpidCTime: + TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; + case kpidCharacts: + if (item.IsRealSect) + { + UInt32 flags = item.Flags; + const UInt32 MY_IMAGE_SCN_ALIGN_MASK = 0x00F00000; + AString s = FlagsToString(g_SectFlags, Z7_ARRAY_SIZE(g_SectFlags), item.Flags & ~MY_IMAGE_SCN_ALIGN_MASK); + const UInt32 align = ((flags >> 20) & 0xF); + if (align != 0) + { + char sz[32]; + ConvertUInt32ToString(1 << (align - 1), sz); + s.Add_Space(); + s += "align_"; + s += sz; + } + prop = s; + } + break; + case kpidZerosTailIsAllowed: if (!item.IsRealSect) prop = true; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::LoadDebugSections(IInStream *stream, bool &thereIsSection) +{ + thereIsSection = false; + const CDirLink &debugLink = _optHeader.DirItems[kDirLink_Debug]; + if (debugLink.Size == 0) + return S_OK; + const unsigned kEntrySize = 28; + UInt32 numItems = debugLink.Size / kEntrySize; + if (numItems > 16) + return S_FALSE; + + // MAC's EFI file: numItems can be incorrect. Only first CDebugEntry entry is correct. + // debugLink.Size = kEntrySize + some_data, pointed by entry[0]. + if (numItems * kEntrySize != debugLink.Size) + { + // return S_FALSE; + if (numItems > 1) + numItems = 1; + } + + UInt64 pa = 0; + unsigned i; + for (i = 0; i < _sections.Size(); i++) + { + const CSection § = _sections[i]; + if (sect.Va <= debugLink.Va && debugLink.Va + debugLink.Size <= sect.Va + sect.PSize) + { + pa = sect.Pa + (debugLink.Va - sect.Va); + break; + } + } + if (i == _sections.Size()) + { + // Exe for ARM requires S_OK + // return S_FALSE; + return S_OK; + } + + CByteBuffer buffer(debugLink.Size); + Byte *buf = buffer; + + RINOK(InStream_SeekSet(stream, pa)) + RINOK(ReadStream_FALSE(stream, buf, debugLink.Size)) + + for (i = 0; i < numItems; i++) + { + CDebugEntry de; + de.Parse(buf); + + if (de.Size == 0) + continue; + + UInt32 totalSize = de.Pa + de.Size; + if (totalSize > _totalSize) + { + _totalSize = totalSize; + thereIsSection = true; + + CSection § = _sections.AddNew(); + sect.Name = ".debug"; + sect.Name.Add_UInt32(i); + sect.IsDebug = true; + sect.Time = de.Time; + sect.Va = de.Va; + sect.Pa = de.Pa; + sect.Set_Size_for_all(de.Size); + } + buf += kEntrySize; + } + + return S_OK; +} + +HRESULT CHandler::ReadTable(UInt32 offset, CRecordVector &items) +{ + if ((offset & 3) != 0 || offset >= _buf.Size()) + return S_FALSE; + size_t rem = _buf.Size() - offset; + if (rem < 16) + return S_FALSE; + unsigned numNameItems = Get16(_buf + offset + 12); + unsigned numIdItems = Get16(_buf + offset + 14); + unsigned numItems = numNameItems + numIdItems; + if ((rem - 16) / 8 < numItems) + return S_FALSE; + if (!_usedRes.SetRange(offset, 16 + numItems * 8)) + return S_FALSE; + offset += 16; + items.ClearAndReserve(numItems); + for (unsigned i = 0; i < numItems; i++, offset += 8) + { + const Byte *buf = _buf + offset; + CTableItem item; + item.ID = Get32(buf + 0); + if ((bool)((item.ID & kFlag) != 0) != (bool)(i < numNameItems)) + return S_FALSE; + item.Offset = Get32(buf + 4); + items.AddInReserved(item); + } + return S_OK; +} + +static const UInt32 kFileSizeMax = (UInt32)1 << 31; +static const unsigned kNumResItemsMax = (unsigned)1 << 23; +static const unsigned kNumStringLangsMax = 256; + +// BITMAPINFOHEADER +struct CBitmapInfoHeader +{ + // UInt32 HeaderSize; + UInt32 XSize; + Int32 YSize; + UInt16 Planes; + UInt16 BitCount; + UInt32 Compression; + UInt32 SizeImage; + + bool Parse(const Byte *p, size_t size); +}; + +static const UInt32 kBitmapInfoHeader_Size = 0x28; + +bool CBitmapInfoHeader::Parse(const Byte *p, size_t size) +{ + if (size < kBitmapInfoHeader_Size || Get32(p) != kBitmapInfoHeader_Size) + return false; + G32( 4, XSize); + G32_signed( 8, YSize); + G16(12, Planes); + G16(14, BitCount); + G32(16, Compression); + G32(20, SizeImage); + return true; +} + +static UInt32 GetImageSize(UInt32 xSize, UInt32 ySize, UInt32 bitCount) +{ + return ((xSize * bitCount + 7) / 8 + 3) / 4 * 4 * ySize; +} + +static UInt32 SetBitmapHeader(Byte *dest, const Byte *src, UInt32 size) +{ + CBitmapInfoHeader h; + if (!h.Parse(src, size)) + return 0; + if (h.YSize < 0) + h.YSize = -h.YSize; + if (h.XSize > (1 << 26) + || h.YSize > (1 << 26) + || h.YSize < 0 + || h.Planes != 1 || h.BitCount > 32) + return 0; + if (h.SizeImage == 0) + { + if (h.Compression != 0) // BI_RGB + return 0; + h.SizeImage = GetImageSize(h.XSize, (UInt32)h.YSize, h.BitCount); + } + UInt32 totalSize = kBmpHeaderSize + size; + UInt32 offBits = totalSize - h.SizeImage; + // BITMAPFILEHEADER + SetUi16(dest, 0x4D42) + SetUi32(dest + 2, totalSize) + SetUi32(dest + 6, 0) + SetUi32(dest + 10, offBits) + return kBmpHeaderSize; +} + +static UInt32 SetIconHeader(Byte *dest, const Byte *src, UInt32 size) +{ + CBitmapInfoHeader h; + if (!h.Parse(src, size)) + return 0; + if (h.YSize < 0) + h.YSize = -h.YSize; + if (h.XSize > (1 << 26) + || h.YSize > (1 << 26) + || h.YSize < 0 + || h.Planes != 1 + || h.Compression != 0) // BI_RGB + return 0; + + const UInt32 numBitCount = h.BitCount; + if (numBitCount != 1 && + numBitCount != 4 && + numBitCount != 8 && + numBitCount != 24 && + numBitCount != 32) + return 0; + + if ((h.YSize & 1) != 0) + return 0; + h.YSize /= 2; + if (h.XSize > 0x100 || h.YSize > 0x100) + return 0; + + UInt32 imageSize; + // imageSize is not correct if AND mask array contains zeros + // in this case it is equal image1Size + + // UInt32 imageSize = h.SizeImage; + // if (imageSize == 0) + // { + const UInt32 image1Size = GetImageSize(h.XSize, (UInt32)h.YSize, h.BitCount); + const UInt32 image2Size = GetImageSize(h.XSize, (UInt32)h.YSize, 1); + imageSize = image1Size + image2Size; + // } + UInt32 numColors = 0; + if (numBitCount < 16) + numColors = 1 << numBitCount; + + SetUi16(dest, 0) // Reserved + SetUi16(dest + 2, 1) // RES_ICON + SetUi16(dest + 4, 1) // ResCount + + dest[6] = (Byte)h.XSize; // Width + dest[7] = (Byte)h.YSize; // Height + dest[8] = (Byte)numColors; // ColorCount + dest[9] = 0; // Reserved + + SetUi32(dest + 10, 0) // Reserved1 / Reserved2 + + UInt32 numQuadsBytes = numColors * 4; + UInt32 BytesInRes = kBitmapInfoHeader_Size + numQuadsBytes + imageSize; + SetUi32(dest + 14, BytesInRes) + SetUi32(dest + 18, kIconHeaderSize) + + /* + Description = DWORDToString(xSize) + + kDelimiterChar + DWORDToString(ySize) + + kDelimiterChar + DWORDToString(numBitCount); + */ + return kIconHeaderSize; +} + +bool CHandler::ParseStringRes(UInt32 id, UInt32 lang, const Byte *src, UInt32 size) +{ + if ((size & 1) != 0) + return false; + + unsigned i; + for (i = 0; i < _strings.Size(); i++) + if (_strings[i].Lang == lang) + break; + if (i == _strings.Size()) + { + if (_strings.Size() >= kNumStringLangsMax) + return false; + CStringItem &item = _strings.AddNew(); + item.Lang = lang; + } + + CStringItem &item = _strings[i]; + id = (id - 1) << 4; + UInt32 pos = 0; + for (i = 0; i < 16; i++) + { + if (size - pos < 2) + return false; + UInt32 len = Get16(src + pos); + pos += 2; + if (len != 0) + { + if (size - pos < len * 2) + return false; + char temp[32]; + ConvertUInt32ToString(id + i, temp); + size_t tempLen = strlen(temp); + size_t j; + for (j = 0; j < tempLen; j++) + item.AddChar(temp[j]); + item.AddChar('\t'); + for (j = 0; j < len; j++, pos += 2) + item.AddWChar_Smart(Get16(src + pos)); + item.NewLine(); + } + } + if (size == pos) + return true; + + // Some rare case files have additional ZERO. + if (size == pos + 2 && Get16(src + pos) == 0) + return true; + + return false; +} + + +// ---------- VERSION ---------- + +static const UInt32 kMy_VS_FFI_SIGNATURE = 0xFEEF04BD; + +struct CMy_VS_FIXEDFILEINFO +{ + // UInt32 Signature; + // UInt32 StrucVersion; + UInt32 VersionMS; + UInt32 VersionLS; + UInt32 ProductVersionMS; + UInt32 ProductVersionLS; + UInt32 FlagsMask; + UInt32 Flags; + UInt32 OS; + UInt32 Type; + UInt32 Subtype; + UInt32 DateMS; + UInt32 DateLS; + + bool Parse(const Byte *p); + void PrintToTextFile(CTextFile &f, CObjectVector &keys); +}; + +bool CMy_VS_FIXEDFILEINFO::Parse(const Byte *p) +{ + if (Get32(p) != kMy_VS_FFI_SIGNATURE) // signature; + return false; + // G32(0x04, StrucVersion); + G32(0x08, VersionMS); + G32(0x0C, VersionLS); + G32(0x10, ProductVersionMS); + G32(0x14, ProductVersionLS); + G32(0x18, FlagsMask); + G32(0x1C, Flags); + G32(0x20, OS); + G32(0x24, Type); + G32(0x28, Subtype); + G32(0x2C, DateMS); + G32(0x40, DateLS); + return true; +} + +static void PrintUInt32(CTextFile &f, UInt32 v) +{ + char s[16]; + ConvertUInt32ToString(v, s); + f.AddString(s); +} + +static inline void PrintUInt32(UString &dest, UInt32 v) +{ + dest.Add_UInt32(v); +} + +static void PrintHex(CTextFile &f, UInt32 val) +{ + char temp[16]; + temp[0] = '0'; + temp[1] = 'x'; + ConvertUInt32ToHex(val, temp + 2); + f.AddString(temp); +} + +static void PrintVersion(CTextFile &f, UInt32 ms, UInt32 ls) +{ + PrintUInt32(f, HIWORD(ms)); f.AddChar(','); + PrintUInt32(f, LOWORD(ms)); f.AddChar(','); + PrintUInt32(f, HIWORD(ls)); f.AddChar(','); + PrintUInt32(f, LOWORD(ls)); +} + +static void PrintVersion(UString &s, UInt32 ms, UInt32 ls) +{ + PrintUInt32(s, HIWORD(ms)); s.Add_Dot(); + PrintUInt32(s, LOWORD(ms)); s.Add_Dot(); + PrintUInt32(s, HIWORD(ls)); s.Add_Dot(); + PrintUInt32(s, LOWORD(ls)); +} + +static const char * const k_VS_FileFlags[] = +{ + "DEBUG" + , "PRERELEASE" + , "PATCHED" + , "PRIVATEBUILD" + , "INFOINFERRED" + , "SPECIALBUILD" +}; + +static const CUInt32PCharPair k_VS_FileOS[] = +{ + { 0x10001, "VOS_DOS_WINDOWS16" }, + { 0x10004, "VOS_DOS_WINDOWS32" }, + { 0x20002, "VOS_OS216_PM16" }, + { 0x30003, "VOS_OS232_PM32" }, + { 0x40004, "VOS_NT_WINDOWS32" } +}; + +static const char * const k_VS_FileOS_High[] = +{ + "VOS_UNKNOWN" + , "VOS_DOS" + , "VOS_OS216" + , "VOS_OS232" + , "VOS_NT" + , "VOS_WINCE" +}; + +static const UInt32 kMY_VFT_DRV = 3; +static const UInt32 kMY_VFT_FONT = 4; + +static const char * const k_VS_FileOS_Low[] = +{ + "VOS__BASE" + , "VOS__WINDOWS16" + , "VOS__PM16" + , "VOS__PM32" + , "VOS__WINDOWS32" +}; + +static const char * const k_VS_FileType[] = +{ + "VFT_UNKNOWN" + , "VFT_APP" + , "VFT_DLL" + , "VFT_DRV" + , "VFT_FONT" + , "VFT_VXD" + , "0x6" + , "VFT_STATIC_LIB" +}; + +// Subtype for VFT_DRV Type +static const char * const k_VS_FileSubType_DRV[] = +{ + "0" + , "PRINTER" + , "KEYBOARD" + , "LANGUAGE" + , "DISPLAY" + , "MOUSE" + , "NETWORK" + , "SYSTEM" + , "INSTALLABLE" + , "SOUND" + , "COMM" + , "INPUTMETHOD" + , "VERSIONED_PRINTER" +}; + +// Subtype for VFT_FONT Type +static const char * const k_VS_FileSubType_FONT[] = +{ + "0" + , "VFT2_FONT_RASTER" + , "VFT2_FONT_VECTOR" + , "VFT2_FONT_TRUETYPE" +}; + +static int FindKey(CObjectVector &v, const char *key) +{ + FOR_VECTOR (i, v) + if (v[i].Key.IsEqualTo(key)) + return (int)i; + return -1; +} + +static void AddToUniqueUStringVector(CObjectVector &v, const UString &key, const UString &value) +{ + bool needInsert = false; + unsigned i; + for (i = 0; i < v.Size(); i++) + { + if (v[i].Key == key) + { + if (v[i].Value == value) + return; + needInsert = true; + } + else if (needInsert) + break; + } + CStringKeyValue &pair = v.InsertNew(i); + pair.Key = key; + pair.Value = value; +} + +void CMy_VS_FIXEDFILEINFO::PrintToTextFile(CTextFile &f, CObjectVector &keys) +{ + f.AddString("FILEVERSION "); + PrintVersion(f, VersionMS, VersionLS); + f.NewLine(); + + f.AddString("PRODUCTVERSION "); + PrintVersion(f, ProductVersionMS, ProductVersionLS); + f.NewLine(); + + { + UString s; + PrintVersion(s, VersionMS, VersionLS); + AddToUniqueUStringVector(keys, L"FileVersion", s); + } + { + UString s; + PrintVersion(s, ProductVersionMS, ProductVersionLS); + AddToUniqueUStringVector(keys, L"ProductVersion", s); + } + + f.AddString("FILEFLAGSMASK "); + PrintHex(f, FlagsMask); + f.NewLine(); + + f.AddString("FILEFLAGS "); + { + bool wasPrinted = false; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_VS_FileFlags); i++) + { + if ((Flags & ((UInt32)1 << i)) != 0) + { + if (wasPrinted) + f.AddString(" | "); + f.AddString("VS_FF_"); + f.AddString(k_VS_FileFlags[i]); + wasPrinted = true; + } + } + UInt32 v = Flags & ~(((UInt32)1 << Z7_ARRAY_SIZE(k_VS_FileFlags)) - 1); + if (v != 0 || !wasPrinted) + { + if (wasPrinted) + f.AddString(" | "); + PrintHex(f, v); + } + } + f.NewLine(); + + // OS = 0x111230; + f.AddString("FILEOS "); + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(k_VS_FileOS); i++) + { + const CUInt32PCharPair &pair = k_VS_FileOS[i]; + if (OS == pair.Value) + { + // continue; + // f.AddString("VOS_"); + f.AddString(pair.Name); + break; + } + } + if (i == Z7_ARRAY_SIZE(k_VS_FileOS)) + { + UInt32 high = OS >> 16; + if (high < Z7_ARRAY_SIZE(k_VS_FileOS_High)) + f.AddString(k_VS_FileOS_High[high]); + else + PrintHex(f, high << 16); + UInt32 low = OS & 0xFFFF; + if (low != 0) + { + f.AddString(" | "); + if (low < Z7_ARRAY_SIZE(k_VS_FileOS_Low)) + f.AddString(k_VS_FileOS_Low[low]); + else + PrintHex(f, low); + } + } + f.NewLine(); + + f.AddString("FILETYPE "); + if (Type < Z7_ARRAY_SIZE(k_VS_FileType)) + f.AddString(k_VS_FileType[Type]); + else + PrintHex(f, Type); + f.NewLine(); + + f.AddString("FILESUBTYPE "); + bool needPrintSubType = true; + if (Type == kMY_VFT_DRV) + { + if (Subtype != 0 && Subtype < Z7_ARRAY_SIZE(k_VS_FileSubType_DRV)) + { + f.AddString("VFT2_DRV_"); + f.AddString(k_VS_FileSubType_DRV[Subtype]); + needPrintSubType = false; + } + } + else if (Type == kMY_VFT_FONT) + { + if (Subtype != 0 && Subtype < Z7_ARRAY_SIZE(k_VS_FileSubType_FONT)) + { + f.AddString(k_VS_FileSubType_FONT[Subtype]); + needPrintSubType = false; + } + } + if (needPrintSubType) + PrintHex(f, Subtype); + f.NewLine(); +} + +static void CopyToUString(const Byte *p, UString &s) +{ + for (;;) + { + const wchar_t c = (wchar_t)Get16(p); + p += 2; + if (c == 0) + return; + s += c; + } +} + +static void CopyToUString_ByLen16(const Byte *p, unsigned numChars16, UString &s) +{ + for (; numChars16; numChars16--) + { + const wchar_t c = (wchar_t)Get16(p); + p += 2; + s += c; + } +} + +static bool CompareWStrStrings(const Byte *p, const char *s) +{ + unsigned pos = 0; + for (;;) + { + const Byte c = (Byte)*s++; + if (Get16(p + pos) != c) + return false; + pos += 2; + if (c == 0) + return true; + } +} + +struct CVersionBlock +{ + UInt32 TotalLen; + UInt32 ValueLen; + unsigned IsTextValue; + unsigned StrSize; + + bool Parse(const Byte *p, UInt32 size); +}; + +static int Get_Utf16Str_Len_InBytes(const Byte *p, size_t size) +{ + unsigned pos = 0; + for (;;) + { + if (pos + 1 >= size) + return -1; + if (Get16(p + pos) == 0) + return (int)pos; + pos += 2; + } +} + +static int Get_Utf16Str_Len_InBytes_AllowNonZeroTail(const Byte *p, size_t size) +{ + unsigned pos = 0; + for (;;) + { + if (pos + 1 >= size) + { + if (pos == size) + return (int)pos; + return -1; + } + if (Get16(p + pos) == 0) + return (int)pos; + pos += 2; + } +} + +static const unsigned k_ResoureBlockHeader_Size = 6; + +bool CVersionBlock::Parse(const Byte *p, UInt32 size) +{ + if (size < k_ResoureBlockHeader_Size) + return false; + TotalLen = Get16(p); + ValueLen = Get16(p + 2); + if (TotalLen < k_ResoureBlockHeader_Size || TotalLen > size) + return false; + IsTextValue = Get16(p + 4); + if (IsTextValue > 1) + return false; + StrSize = 0; + const int t = Get_Utf16Str_Len_InBytes(p + k_ResoureBlockHeader_Size, + TotalLen - k_ResoureBlockHeader_Size); + if (t < 0) + return false; + StrSize = (unsigned)t; + return true; +} + +static void AddParamString(CTextFile &f, const Byte *p, size_t sLen) +{ + f.AddChar(' '); + f.AddChar('\"'); + f.AddBytes(p, sLen); + f.AddChar('\"'); +} + +static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector &keys) +{ + UInt32 pos; + { + const unsigned k_sizeof_VS_FIXEDFILEINFO = 13 * 4; + + CVersionBlock vb; + if (!vb.Parse(p, size)) + return false; + if (vb.ValueLen != k_sizeof_VS_FIXEDFILEINFO) // maybe 0 is allowed here? + return false; + if (vb.IsTextValue) + return false; + pos = k_ResoureBlockHeader_Size; + if (!CompareWStrStrings(p + pos, "VS_VERSION_INFO")) + return false; + pos += vb.StrSize + 2; + pos += (4 - pos) & 3; + if (pos + vb.ValueLen > vb.TotalLen) + return false; + /* sometimes resource contains zeros in remainder. + So we don't check that size != vb.TotalLen + // if (size != vb.TotalLen) return false; + */ + if (size > vb.TotalLen) + size = vb.TotalLen; + CMy_VS_FIXEDFILEINFO FixedFileInfo; + if (!FixedFileInfo.Parse(p + pos)) + return false; + FixedFileInfo.PrintToTextFile(f, keys); + pos += vb.ValueLen; + } + + f.OpenBlock(0); + + for (;;) + { + pos += (4 - pos) & 3; + if (pos >= size) + break; + + CVersionBlock vb; + if (!vb.Parse(p + pos, size - pos)) + return false; + if (vb.ValueLen != 0) + return false; + const UInt32 endPos = pos + vb.TotalLen; + pos += k_ResoureBlockHeader_Size; + + f.AddSpaces(2); + f.AddString("BLOCK"); + AddParamString(f, p + pos, vb.StrSize); + + f.NewLine(); + f.OpenBlock(2); + + if (CompareWStrStrings(p + pos, "VarFileInfo")) + { + pos += vb.StrSize + 2; + for (;;) + { + pos += (4 - pos) & 3; + if (pos >= endPos) + break; + CVersionBlock vb2; + if (!vb2.Parse(p + pos, endPos - pos)) + return false; + const UInt32 endPos2 = pos + vb2.TotalLen; + if (vb2.IsTextValue) + return false; + pos += k_ResoureBlockHeader_Size; + f.AddSpaces(4); + f.AddString("VALUE"); + AddParamString(f, p + pos, vb2.StrSize); + if (!CompareWStrStrings(p + pos, "Translation")) + return false; + pos += vb2.StrSize + 2; + pos += (4 - pos) & 3; + if (pos + vb2.ValueLen != endPos2) + return false; + if ((vb2.ValueLen & 3) != 0) + return false; + UInt32 num = (vb2.ValueLen >> 2); + for (; num != 0; num--, pos += 4) + { + const UInt32 dw = Get32(p + pos); + const UInt32 lang = LOWORD(dw); + const UInt32 codePage = HIWORD(dw); + + f.AddString(", "); + PrintHex(f, lang); + f.AddString(", "); + PrintUInt32(f, codePage); + } + f.NewLine(); + } + } + else + { + if (!CompareWStrStrings(p + pos, "StringFileInfo")) + return false; + pos += vb.StrSize + 2; + for (;;) + { + pos += (4 - pos) & 3; + if (pos >= endPos) + break; + CVersionBlock vb2; + if (!vb2.Parse(p + pos, endPos - pos)) + return false; + const UInt32 endPos2 = pos + vb2.TotalLen; + if (vb2.ValueLen != 0) + return false; + pos += k_ResoureBlockHeader_Size; + + f.AddSpaces(4); + f.AddString("BLOCK"); + AddParamString(f, p + pos, vb2.StrSize); + pos += vb2.StrSize + 2; + + f.NewLine(); + f.OpenBlock(4); + + for (;;) + { + pos += (4 - pos) & 3; + if (pos >= endPos2) + break; + + CVersionBlock vb3; + if (!vb3.Parse(p + pos, endPos2 - pos)) + return false; + // ValueLen is a number of 16-bit characters (usually it includes zero tail character). + const UInt32 endPos3 = pos + vb3.TotalLen; + pos += k_ResoureBlockHeader_Size; + + // we don't write string if it's not text + if (vb3.IsTextValue) + { + f.AddSpaces(6); + f.AddString("VALUE"); + AddParamString(f, p + pos, vb3.StrSize); + UString key; + UString value; + CopyToUString(p + pos, key); + pos += vb3.StrSize + 2; + + pos += (4 - pos) & 3; + if (vb3.ValueLen != 0 && pos /* + 2 */ <= endPos3) + { + f.AddChar(','); + f.AddSpaces((34 - (int)vb3.StrSize) / 2); + // vb3.TotalLen for some PE files (not from msvc) doesn't include tail zero at the end of Value string. + // we allow that minor error. + const int sLen = Get_Utf16Str_Len_InBytes_AllowNonZeroTail(p + pos, endPos3 - pos); + if (sLen < 0) + return false; + /* + if (vb3.ValueLen - 1 != (unsigned)sLen / 2 && + vb3.ValueLen != (unsigned)sLen / 2) + return false; + */ + AddParamString(f, p + pos, (unsigned)sLen); + CopyToUString_ByLen16(p + pos, (unsigned)sLen / 2, value); + // pos += (unsigned)sLen + 2; + } + AddToUniqueUStringVector(keys, key, value); + } + pos = endPos3; + f.NewLine(); + } + pos = endPos2; + f.CloseBlock(4); + } + } + f.CloseBlock(2); + pos = endPos; + } + + f.CloseBlock(0); + return true; +} + + +HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) +{ + const CSection § = _sections[sectionIndex]; + size_t fileSize = sect.PSize; + { + size_t fileSizeMin = sect.PSize; + + if (sect.VSize < sect.PSize) + { + fileSize = fileSizeMin = sect.VSize; + const int numBits = _optHeader.GetNumFileAlignBits(); + if (numBits > 0) + { + const UInt32 mask = ((UInt32)1 << numBits) - 1; + const size_t end = (size_t)((sect.VSize + mask) & (UInt32)~mask); + if (end > sect.VSize) + { + if (end <= sect.PSize) + fileSize = end; + else + fileSize = sect.PSize; + } + } + } + + if (fileSize > kFileSizeMax) + return S_FALSE; + + { + const UInt64 fileSize64 = fileSize; + if (callback) + RINOK(callback->SetTotal(NULL, &fileSize64)) + } + + RINOK(InStream_SeekSet(stream, sect.Pa)) + + _buf.Alloc(fileSize); + + size_t pos; + + for (pos = 0; pos < fileSize;) + { + { + const UInt64 offset64 = pos; + if (callback) + RINOK(callback->SetCompleted(NULL, &offset64)) + } + size_t rem = MyMin(fileSize - pos, (size_t)(1 << 22)); + RINOK(ReadStream(stream, _buf + pos, &rem)) + if (rem == 0) + { + if (pos < fileSizeMin) + return S_FALSE; + break; + } + pos += rem; + } + + if (pos < fileSize) + memset(_buf + pos, 0, fileSize - pos); + } + + _usedRes.Alloc(fileSize); + CRecordVector specItems; + RINOK(ReadTable(0, specItems)) + + _oneLang = true; + bool stringsOk = true; + size_t maxOffset = 0; + + FOR_VECTOR (i, specItems) + { + const CTableItem &item1 = specItems[i]; + if ((item1.Offset & kFlag) == 0) + return S_FALSE; + + CRecordVector specItems2; + RINOK(ReadTable(item1.Offset & kMask, specItems2)) + + FOR_VECTOR (j, specItems2) + { + const CTableItem &item2 = specItems2[j]; + if ((item2.Offset & kFlag) == 0) + return S_FALSE; + + CRecordVector specItems3; + RINOK(ReadTable(item2.Offset & kMask, specItems3)) + + CResItem item; + item.Type = item1.ID; + item.ID = item2.ID; + + FOR_VECTOR (k, specItems3) + { + if (_items.Size() >= kNumResItemsMax) + return S_FALSE; + const CTableItem &item3 = specItems3[k]; + if ((item3.Offset & kFlag) != 0) + return S_FALSE; + if (item3.Offset >= _buf.Size() || _buf.Size() - item3.Offset < 16) + return S_FALSE; + const Byte *buf = _buf + item3.Offset; + item.Lang = item3.ID; + item.Offset = Get32(buf + 0); + item.Size = Get32(buf + 4); + // UInt32 codePage = Get32(buf + 8); + if (Get32(buf + 12) != 0) + return S_FALSE; + if (!_items.IsEmpty() && _oneLang && !item.IsNameEqual(_items.Back())) + _oneLang = false; + + item.HeaderSize = 0; + + size_t offset = item.Offset - sect.Va; + if (offset > maxOffset) + maxOffset = offset; + if (offset + item.Size > maxOffset) + maxOffset = offset + item.Size; + + if (CheckItem(sect, item, offset)) + { + const Byte *data = _buf + offset; + if (item.IsBmp()) + item.HeaderSize = SetBitmapHeader(item.Header, data, item.Size); + else if (item.IsIcon()) + item.HeaderSize = SetIconHeader(item.Header, data, item.Size); + else if (item.IsString()) + { + if (stringsOk) + stringsOk = ParseStringRes(item.ID, item.Lang, data, item.Size); + } + } + + if (item.IsVersion()) + { + if (offset > _buf.Size() || _buf.Size() - offset < item.Size) + continue; + CTextFile f; + if (ParseVersion((const Byte *)_buf + offset, item.Size, f, _versionKeys)) + { + CMixItem mixItem; + mixItem.VersionIndex = (int)_versionFiles.Size(); + mixItem.SectionIndex = (int)sectionIndex; // check it !!!! + CByteBuffer_WithLang &vf = _versionFiles.AddNew(); + vf.Lang = item.Lang; + vf.CopyFrom(f.Buf, f.Buf.GetPos()); + _mixItems.Add(mixItem); + continue; + } + // PrintError("ver.Parse error"); + } + + item.Enabled = true; + _items.Add(item); + } + } + } + + if (stringsOk && !_strings.IsEmpty()) + { + unsigned i; + for (i = 0; i < _items.Size(); i++) + { + CResItem &item = _items[i]; + if (item.IsString()) + item.Enabled = false; + } + for (i = 0; i < _strings.Size(); i++) + { + if (_strings[i].FinalSize() == 0) + continue; + CMixItem mixItem; + mixItem.StringIndex = (int)i; + mixItem.SectionIndex = (int)sectionIndex; + _mixItems.Add(mixItem); + } + } + + _usedRes.Free(); + + { + // PSize can be much larger than VSize in some exe installers. + // it contains archive data after PE resources. + // So we need to use PSize here! + if (maxOffset < sect.PSize) + { + size_t end = fileSize; + + // we skip Zeros to start of aligned block + size_t i; + for (i = maxOffset; i < end; i++) + if (_buf[i] != 0) + break; + if (i == end) + maxOffset = end; + + CSection sect2; + sect2.Flags = 0; + sect2.Pa = sect.Pa + (UInt32)maxOffset; + sect2.Va = sect.Va + (UInt32)maxOffset; + + // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX + // the code for .rsrc_2 is commented. + sect2.PSize = sect.PSize - (UInt32)maxOffset; + + if (sect2.PSize != 0) + { + sect2.ExtractSize = sect2.VSize = sect2.PSize; + sect2.Name = ".rsrc_1"; + sect2.Time = 0; + sect2.IsAdditionalSection = true; + _sections.Add(sect2); + } + } + } + + return S_OK; +} + + +bool CHeader::ParseCoff(const Byte *p) +{ + ParseBase(p); + if (PointerToSymbolTable < kCoffHeaderSize) + return false; + if (NumSymbols >= (1 << 24)) + return false; + if (OptHeaderSize != 0 && OptHeaderSize < k_OptHeader32_Size_MIN) + return false; + + // 18.04: we reduce false detections + if (NumSections == 0 && OptHeaderSize == 0) + return false; + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_MachinePairs); i++) + if (Machine == g_MachinePairs[i].Value) + return true; + if (Machine == 0) + return true; + + return false; +} + + +static inline bool CheckPeOffset(UInt32 pe) +{ + // ((pe & 7) == 0) is for most PE files. But there is unusual EFI-PE file that uses unaligned pe value. + return pe >= 0x40 && pe <= 0x1000 /* && (pe & 7) == 0 */ ; +} + +static const unsigned kStartSize = 0x40; + +API_FUNC_static_IsArc IsArc_Pe(const Byte *p, size_t size) +{ + if (size < 2) + return k_IsArc_Res_NEED_MORE; + if (p[0] != 'M' || p[1] != 'Z') + return k_IsArc_Res_NO; + if (size < kStartSize) + return k_IsArc_Res_NEED_MORE; + UInt32 pe = Get32(p + 0x3C); + if (!CheckPeOffset(pe)) + return k_IsArc_Res_NO; + if (pe + kPeHeaderSize > size) + return k_IsArc_Res_NEED_MORE; + CHeader header; + if (!header.ParsePe(p + pe)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + UInt32 coffOffset = 0; + if (_coffMode) + { + Byte h[kCoffHeaderSize]; + RINOK(ReadStream_FALSE(stream, h, kCoffHeaderSize)) + if (!_header.ParseCoff(h)) + return S_FALSE; + } + else + { + UInt32 _peOffset; + { + Byte h[kStartSize]; + RINOK(ReadStream_FALSE(stream, h, kStartSize)) + if (h[0] != 'M' || h[1] != 'Z') + return S_FALSE; + /* most of PE files contain 0x0090 at offset 2. + But some rare PE files contain another values. So we don't use that check. + if (Get16(h + 2) != 0x90) return false; */ + _peOffset = Get32(h + 0x3C); + if (!CheckPeOffset(_peOffset)) + return S_FALSE; + coffOffset = _peOffset + 4; + } + { + Byte h[kPeHeaderSize]; + RINOK(InStream_SeekSet(stream, _peOffset)) + RINOK(ReadStream_FALSE(stream, h, kPeHeaderSize)) + if (!_header.ParsePe(h)) + return S_FALSE; + } + } + + const UInt32 optStart = coffOffset + kCoffHeaderSize; + const UInt32 bufSize = _header.OptHeaderSize + (UInt32)_header.NumSections * kSectionSize; + _totalSize = optStart + bufSize; + CByteBuffer buffer(bufSize); + + RINOK(ReadStream_FALSE(stream, buffer, bufSize)) + + // memset((void *)&_optHeader, 0, sizeof(_optHeader)); + if (_header.OptHeaderSize != 0) + if (!_optHeader.Parse(buffer, _header.OptHeaderSize)) + return S_FALSE; + + UInt32 pos = _header.OptHeaderSize; + unsigned i; + for (i = 0; i < _header.NumSections; i++, pos += kSectionSize) + { + CSection § = _sections.AddNew(); + sect.Parse(buffer + pos); + sect.IsRealSect = true; + if (sect.Name.IsEqualTo(".reloc")) + { + const CDirLink &dl = _optHeader.DirItems[kDirLink_BASERELOC]; + if (dl.Va == sect.Va && + dl.Size <= sect.PSize) + sect.ExtractSize = dl.Size; + } + else if (sect.Name.IsEqualTo(".pdata")) + { + const CDirLink &dl = _optHeader.DirItems[kDirLink_EXCEPTION]; + if (dl.Va == sect.Va && + dl.Size <= sect.PSize) + sect.ExtractSize = dl.Size; + } + + /* PE pre-file in .hxs file has errors: + PSize of resource is larger than real size. + So it overlaps next ".its" section. + 7-zip before 22.02: we corrected it. + + 22.02: another bad case is possible in incorrect pe (exe) file: + PSize in .rsrc section is correct, + but next .reloc section has incorrect (Pa) that overlaps with .rsrc. + */ + + if (i != 0) + { + const CSection &prev = _sections[i - 1]; + if (prev.Pa < sect.Pa + && prev.Pa + prev.PSize > sect.Pa + && sect.PSize != 0 + && prev.PSize != 0) + { + _sectionsError = true; + // PRF(printf("\n !!!! Section correction: %s\n ", prev.Name)); + + /* we corrected that case in 7-zip before 22.02: */ + // prev.PSize = sect.Pa - prev.Pa; + + /* 22.02: here we can try to change bad section position to expected postion. + but original Windows code probably will not do same things. */ + // if (prev.PSize <= sect.Va - prev.Va) sect.Pa = prev.Pa + prev.PSize; + } + } + /* last ".its" section in hxs file has incorrect sect.PSize. + 7-zip before 22.02: we reduced section to real sect.VSize */ + /* + if (sect.VSize == 24 && sect.PSize == 512 && i == (unsigned)_header.NumSections - 1) + sect.PSize = sect.VSize; + */ + } + + for (i = 0; i < _sections.Size(); i++) + _sections[i].UpdateTotalSize(_totalSize); + + bool thereISDebug = false; + if (IsOpt()) + { + RINOK(LoadDebugSections(stream, thereISDebug)) + + const CDirLink &certLink = _optHeader.DirItems[kDirLink_Certificate]; + if (certLink.Size != 0) + { + CSection § = _sections.AddNew(); + sect.Name = "CERTIFICATE"; + sect.Va = 0; + sect.Pa = certLink.Va; + sect.Set_Size_for_all(certLink.Size); + sect.UpdateTotalSize(_totalSize); + } + + if (thereISDebug) + { + /* sometime there is some data after debug section. + We don't see any reference in exe file to that data. + But we suppose that it's part of EXE file */ + + const UInt32 kAlign = 1 << 12; + UInt32 alignPos = _totalSize & (kAlign - 1); + if (alignPos != 0) + { + UInt32 size = kAlign - alignPos; + RINOK(InStream_SeekSet(stream, _totalSize)) + buffer.Alloc(kAlign); + Byte *buf = buffer; + size_t processed = size; + RINOK(ReadStream(stream, buf, &processed)) + + /* + if (processed != 0) + { + printf("\ndata after debug %d, %d \n", (int)size, (int)processed); + fflush(stdout); + } + */ + + size_t k; + for (k = 0; k < processed; k++) + if (buf[k] != 0) + break; + if (processed < size && processed < 100) + _totalSize += (UInt32)processed; + else if (((_totalSize + k) & 0x1FF) == 0 || processed < size) + _totalSize += (UInt32)k; + } + } + } + + if (_header.NumSymbols > 0 && _header.PointerToSymbolTable >= optStart) + { + if (_header.NumSymbols >= (1 << 24)) + return S_FALSE; + UInt32 size = _header.NumSymbols * 18; + RINOK(InStream_SeekSet(stream, (UInt64)_header.PointerToSymbolTable + size)) + Byte buf[4]; + RINOK(ReadStream_FALSE(stream, buf, 4)) + UInt32 size2 = Get32(buf); + if (size2 >= (1 << 28)) + return S_FALSE; + size += size2; + + CSection § = _sections.AddNew(); + sect.Name = "COFF_SYMBOLS"; + sect.Va = 0; + sect.Pa = _header.PointerToSymbolTable; + sect.Set_Size_for_all(size); + sect.UpdateTotalSize(_totalSize); + } + + { + CObjectVector sections = _sections; + sections.Sort(); + UInt32 limit = (1 << 12); + unsigned num = 0; + FOR_VECTOR (k, sections) + { + const CSection &s = sections[k]; + if (s.Pa > limit) + { + CSection &s2 = _sections.AddNew(); + s2.Pa = s2.Va = limit; + s2.Set_Size_for_all(s.Pa - limit); + s2.IsAdditionalSection = true; + s2.Name.Add_Char('['); + s2.Name.Add_UInt32(num++); + s2.Name.Add_Char(']'); + limit = s.Pa; + } + UInt32 next = s.Pa + s.PSize; + if (next < s.Pa) + break; + if (next >= limit) + limit = next; + } + } + + + if (IsOpt()) + if (_optHeader.CheckSum != 0) + { + RINOK(InStream_SeekToBegin(stream)) + UInt32 checkSum = 0; + RINOK(CalcCheckSum(stream, _totalSize, optStart + k_CheckSum_Field_Offset, checkSum)) + _checksumError = (checkSum != _optHeader.CheckSum); + } + + + if (!_allowTail) + { + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) + if (fileSize > _totalSize) + return S_FALSE; + } + + bool _parseResources = true; + // _parseResources = false; // for debug + + UInt64 mainSize = 0, mainSize2 = 0; + + for (i = 0; i < _sections.Size(); i++) + { + const CSection § = _sections[i]; + if (IsOpt()) + if (_parseResources && sect.Name.IsEqualTo(".rsrc")) + { + // 20.01: we try to parse only first copy of .rsrc section. + _parseResources = false; + const unsigned numMixItems = _mixItems.Size(); + HRESULT res = OpenResources(i, stream, callback); + if (res == S_OK) + { + _resourcesPrefix = sect.Name.Ptr(); + _resourcesPrefix.Add_PathSepar(); + FOR_VECTOR (j, _items) + { + const CResItem &item = _items[j]; + if (item.Enabled) + { + CMixItem mixItem; + mixItem.SectionIndex = (int)i; + mixItem.ResourceIndex = (int)j; + if (item.IsRcDataOrUnknown()) + { + if (item.Size >= mainSize) + { + mainSize2 = mainSize; + mainSize = item.Size; + _mainSubfile = (Int32)(int)_mixItems.Size(); + } + else if (item.Size >= mainSize2) + mainSize2 = item.Size; + } + _mixItems.Add(mixItem); + } + } + // 9.29: .rsrc_2 code was commented. + // .rsrc_1 now must include that .rsrc_2 block. + /* + if (sect.PSize > sect.VSize) + { + int numBits = _optHeader.GetNumFileAlignBits(); + if (numBits >= 0) + { + UInt32 mask = (1 << numBits) - 1; + UInt32 end = ((sect.VSize + mask) & ~mask); + + if (sect.PSize > end) + { + CSection §2 = _sections.AddNew(); + sect2.Flags = 0; + sect2.Pa = sect.Pa + end; + sect2.Va = sect.Va + end; + sect2.PSize = sect.PSize - end; + sect2.VSize = sect2.PSize; + sect2.Name = ".rsrc_2"; + sect2.Time = 0; + sect2.IsAdditionalSection = true; + } + } + } + */ + continue; + } + if (res != S_FALSE) + return res; + _mixItems.DeleteFrom(numMixItems); + CloseResources(); + } + + if (sect.IsAdditionalSection) + { + if (sect.PSize >= mainSize) + { + mainSize2 = mainSize; + mainSize = sect.PSize; + _mainSubfile = (Int32)(int)_mixItems.Size(); + } + else if (sect.PSize >= mainSize2) + mainSize2 = sect.PSize; + } + + CMixItem mixItem; + mixItem.SectionIndex = (int)i; + _mixItems.Add(mixItem); + } + + if (mainSize2 >= (1 << 20) && mainSize < mainSize2 * 2) + _mainSubfile = -1; + + for (i = 0; i < _mixItems.Size(); i++) + { + const CMixItem &mixItem = _mixItems[i]; + if (mixItem.StringIndex < 0 && mixItem.ResourceIndex < 0 && _sections[mixItem.SectionIndex].Name.IsEqualTo("_winzip_")) + { + _mainSubfile = (Int32)(int)i; + break; + } + } + + for (i = 0; i < _versionKeys.Size(); i++) + { + if (i != 0) + _versionFullString.Add_LF(); + const CStringKeyValue &k = _versionKeys[i]; + _versionFullString += k.Key; + _versionFullString += ": "; + _versionFullString += k.Value; + } + + { + int keyIndex = FindKey(_versionKeys, "OriginalFilename"); + if (keyIndex >= 0) + _originalFilename = _versionKeys[keyIndex].Value; + } + { + int keyIndex = FindKey(_versionKeys, "FileDescription"); + if (keyIndex >= 0) + _versionShortString = _versionKeys[keyIndex].Value; + } + { + int keyIndex = FindKey(_versionKeys, "FileVersion"); + if (keyIndex >= 0) + { + _versionShortString.Add_Space(); + _versionShortString += _versionKeys[keyIndex].Value; + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + RINOK(Open2(inStream, callback)) + _stream = inStream; + return S_OK; + COM_TRY_END +} + +void CHandler::CloseResources() +{ + _usedRes.Free(); + _items.Clear(); + _strings.Clear(); + _versionFiles.Clear(); + _buf.Free(); + _versionFullString.Empty(); + _versionShortString.Empty(); + _originalFilename.Empty(); + _versionKeys.Clear(); +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _checksumError = false; + _sectionsError = false; + _mainSubfile = -1; + + _stream.Release(); + _sections.Clear(); + _mixItems.Clear(); + CloseResources(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _mixItems.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _mixItems.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CMixItem &mixItem = _mixItems[allFilesMode ? i : indices[i]]; + UInt64 size; + if (mixItem.StringIndex >= 0) + size = _strings[mixItem.StringIndex].FinalSize(); + else if (mixItem.VersionIndex >= 0) + size = _versionFiles[mixItem.VersionIndex].Size(); + else if (mixItem.ResourceIndex >= 0) + size = _items[mixItem.ResourceIndex].GetSize(); + else + size = _sections[mixItem.SectionIndex].GetSize_Extract(); + totalSize += size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + totalSize = 0; + UInt64 currentItemSize; + + for (i = 0;; i++, totalSize += currentItemSize) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + const CMixItem &mixItem = _mixItems[index]; + + const CSection § = _sections[mixItem.SectionIndex]; + bool isOk = true; + if (mixItem.StringIndex >= 0) + { + const CStringItem &item = _strings[mixItem.StringIndex]; + currentItemSize = item.FinalSize(); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + if (outStream) + RINOK(WriteStream(outStream, item.Buf, item.FinalSize())) + } + else if (mixItem.VersionIndex >= 0) + { + const CByteBuffer &item = _versionFiles[mixItem.VersionIndex]; + currentItemSize = item.Size(); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + if (outStream) + RINOK(WriteStream(outStream, item, item.Size())) + } + else if (mixItem.ResourceIndex >= 0) + { + const CResItem &item = _items[mixItem.ResourceIndex]; + currentItemSize = item.GetSize(); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + size_t offset = item.Offset - sect.Va; + if (!CheckItem(sect, item, offset)) + isOk = false; + else if (outStream) + { + if (item.HeaderSize != 0) + RINOK(WriteStream(outStream, item.Header, item.HeaderSize)) + RINOK(WriteStream(outStream, _buf + offset, item.Size)) + } + } + else + { + currentItemSize = sect.GetSize_Extract(); + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_stream, sect.Pa)) + inStream->Init(currentItemSize); + RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) + isOk = (copyCoder->TotalSize == currentItemSize); + } + + outStream.Release(); + RINOK(extractCallback->SetOperationResult(isOk ? + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kDataError)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + + const CMixItem &mixItem = _mixItems[index]; + const CSection § = _sections[mixItem.SectionIndex]; + if (mixItem.IsSectionItem()) + return CreateLimitedInStream(_stream, sect.Pa, sect.GetSize_Extract(), stream); + + CBufInStream *inStreamSpec = new CBufInStream; + CMyComPtr streamTemp = inStreamSpec; + CReferenceBuf *referenceBuf = new CReferenceBuf; + CMyComPtr ref = referenceBuf; + if (mixItem.StringIndex >= 0) + { + const CStringItem &item = _strings[mixItem.StringIndex]; + referenceBuf->Buf.CopyFrom(item.Buf, item.FinalSize()); + } + else if (mixItem.VersionIndex >= 0) + { + const CByteBuffer &item = _versionFiles[mixItem.VersionIndex]; + referenceBuf->Buf.CopyFrom(item, item.Size()); + } + else + { + const CResItem &item = _items[mixItem.ResourceIndex]; + size_t offset = item.Offset - sect.Va; + if (!CheckItem(sect, item, offset)) + return S_FALSE; + if (item.HeaderSize == 0) + { + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr streamTemp2 = streamSpec; + streamSpec->Init(_buf + offset, item.Size, (IInArchive *)this); + *stream = streamTemp2.Detach(); + return S_OK; + } + referenceBuf->Buf.Alloc(item.HeaderSize + item.Size); + memcpy(referenceBuf->Buf, item.Header, item.HeaderSize); + if (item.Size != 0) + memcpy(referenceBuf->Buf + item.HeaderSize, _buf + offset, item.Size); + } + inStreamSpec->Init(referenceBuf); + + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) +{ + _allowTail = IntToBool(allowTail); + return S_OK; +} + +static const Byte k_Signature[] = { 'M', 'Z' }; + +REGISTER_ARC_I( + "PE", "exe dll sys", NULL, 0xDD, + k_Signature, + 0, + NArcInfoFlags::kPreArc, + IsArc_Pe) + +} + +namespace NCoff { + +API_FUNC_static_IsArc IsArc_Coff(const Byte *p, size_t size) +{ + if (size < NPe::kCoffHeaderSize) + return k_IsArc_Res_NEED_MORE; + NPe::CHeader header; + if (!header.ParseCoff(p)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +/* +static const Byte k_Signature[] = +{ + 2, 0x4C, 0x01, // x86 + 2, 0x64, 0x86, // x64 + 2, 0x64, 0xAA // ARM64 +}; +REGISTER_ARC_I_CLS( +*/ + +REGISTER_ARC_I_CLS_NO_SIG( + NPe::CHandler(true), + "COFF", "obj", NULL, 0xC6, + // k_Signature, + 0, + // NArcInfoFlags::kMultiSignature | + NArcInfoFlags::kStartOpen, + IsArc_Coff) +} + + +namespace NTe { + +// Terse Executable (TE) image + +struct CDataDir +{ + UInt32 Va; + UInt32 Size; + + void Parse(const Byte *p) + { + G32(0, Va); + G32(4, Size); + } +}; + +static const UInt32 kHeaderSize = 40; + +static bool FindValue(const CUInt32PCharPair *pairs, unsigned num, UInt32 value) +{ + for (unsigned i = 0; i < num; i++) + if (pairs[i].Value == value) + return true; + return false; +} + +#define MY_FIND_VALUE(pairs, val) FindValue(pairs, Z7_ARRAY_SIZE(pairs), val) +#define MY_FIND_VALUE_2(strings, val) (val < Z7_ARRAY_SIZE(strings) && strings[val]) + +static const UInt32 kNumSection_MAX = 32; + +struct CHeader +{ + UInt16 Machine; + Byte NumSections; + Byte SubSystem; + UInt16 StrippedSize; + /* + UInt32 AddressOfEntryPoint; + UInt32 BaseOfCode; + UInt64 ImageBase; + */ + CDataDir DataDir[2]; // base relocation and debug directory + + bool ConvertPa(UInt32 &pa) const + { + if (pa < StrippedSize) + return false; + pa = pa - StrippedSize + kHeaderSize; + return true; + } + bool Parse(const Byte *p); +}; + +bool CHeader::Parse(const Byte *p) +{ + NumSections = p[4]; + if (NumSections > kNumSection_MAX) + return false; + SubSystem = p[5]; + G16(2, Machine); + G16(6, StrippedSize); + /* + G32(8, AddressOfEntryPoint); + G32(12, BaseOfCode); + G64(16, ImageBase); + */ + for (unsigned i = 0; i < 2; i++) + { + CDataDir &dd = DataDir[i]; + dd.Parse(p + 24 + i * 8); + if (dd.Size >= ((UInt32)1 << 28)) + return false; + } + return + MY_FIND_VALUE(NPe::g_MachinePairs, Machine) && + MY_FIND_VALUE_2(NPe::g_SubSystems, SubSystem); +} + +API_FUNC_static_IsArc IsArc_Te(const Byte *p, size_t size) +{ + if (size < 2) + return k_IsArc_Res_NEED_MORE; + if (p[0] != 'V' || p[1] != 'Z') + return k_IsArc_Res_NO; + if (size < kHeaderSize) + return k_IsArc_Res_NEED_MORE; + + CHeader h; + if (!h.Parse(p)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + + +struct CSection +{ + Byte Name[NPe::kNameSize]; + + UInt32 ExtractSize; + UInt32 VSize; + UInt32 Va; + UInt32 PSize; + UInt32 Pa; + UInt32 Flags; + // UInt16 NumRelocs; + + void Parse(const Byte *p) + { + memcpy(Name, p, NPe::kNameSize); + G32(8, VSize); + G32(12, Va); + G32(16, PSize); + G32(20, Pa); + // G32(p + 32, NumRelocs); + G32(36, Flags); + ExtractSize = (VSize && VSize < PSize) ? VSize : PSize; + } + + bool Check() const + { + return + Pa <= ((UInt32)1 << 30) && + PSize <= ((UInt32)1 << 30); + } + + UInt32 GetSize_Extract() const + { + return ExtractSize; + } + + void UpdateTotalSize(UInt32 &totalSize) + { + const UInt32 t = Pa + PSize; + if (totalSize < t) + totalSize = t; + } +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IInArchiveGetStream, + IArchiveAllowTail +) + CRecordVector _items; + CMyComPtr _stream; + UInt32 _totalSize; + bool _allowTail; + CHeader _h; + + HRESULT Open2(IInStream *stream); +public: + CHandler(): _allowTail(false) {} +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidVirtualSize, + kpidCharacts, + kpidOffset, + kpidVa +}; + +enum +{ + kpidSubSystem = kpidUserDefined + // , kpidImageBase +}; + +static const CStatProp kArcProps[] = +{ + // { NULL, kpidHeadersSize, VT_UI4 }, + { NULL, kpidCpu, VT_BSTR}, + { "Subsystem", kpidSubSystem, VT_BSTR }, + // { "Image Base", kpidImageBase, VT_UI8 } +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _totalSize; break; + case kpidCpu: PAIR_TO_PROP(NPe::g_MachinePairs, _h.Machine, prop); break; + case kpidSubSystem: TYPE_TO_PROP(NPe::g_SubSystems, _h.SubSystem, prop); break; + /* + case kpidImageBase: prop = _h.ImageBase; break; + case kpidAddressOfEntryPoint: prop = _h.AddressOfEntryPoint; break; + case kpidBaseOfCode: prop = _h.BaseOfCode; break; + */ + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + { + const CSection &item = _items[index]; + switch (propID) + { + case kpidPath: + { + AString name; + NPe::GetName(item.Name, name); + prop = MultiByteToUnicodeString(name); + break; + } + case kpidSize: prop = (UInt64)item.GetSize_Extract(); break; + case kpidPackSize: prop = (UInt64)item.PSize; break; + case kpidVirtualSize: prop = (UInt64)item.VSize; break; + case kpidOffset: prop = item.Pa; break; + case kpidVa: prop = item.Va; break; + case kpidCharacts: FLAGS_TO_PROP(NPe::g_SectFlags, item.Flags, prop); break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +HRESULT CHandler::Open2(IInStream *stream) +{ + Byte h[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, h, kHeaderSize)) + if (h[0] != 'V' || h[1] != 'Z') + return S_FALSE; + if (!_h.Parse(h)) + return S_FALSE; + + UInt32 headerSize = NPe::kSectionSize * (UInt32)_h.NumSections; + CByteArr buf(headerSize); + RINOK(ReadStream_FALSE(stream, buf, headerSize)) + headerSize += kHeaderSize; + + _totalSize = headerSize; + _items.ClearAndReserve(_h.NumSections); + for (UInt32 i = 0; i < _h.NumSections; i++) + { + CSection sect; + sect.Parse(buf + i * NPe::kSectionSize); + if (!_h.ConvertPa(sect.Pa)) + return S_FALSE; + if (sect.Pa < headerSize) + return S_FALSE; + if (!sect.Check()) + return S_FALSE; + _items.AddInReserved(sect); + sect.UpdateTotalSize(_totalSize); + } + + if (!_allowTail) + { + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(stream, fileSize)) + if (fileSize > _totalSize) + return S_FALSE; + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + Close(); + // try + { + if (Open2(inStream) != S_OK) + return S_FALSE; + _stream = inStream; + } + // catch(...) { return S_FALSE; } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _stream.Release(); + _items.Clear(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(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++) + totalSize += _items[allFilesMode ? i : indices[i]].GetSize_Extract(); + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(_stream); + + totalSize = 0; + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + int opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CSection &item = _items[index]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + const UInt32 size = item.GetSize_Extract(); + totalSize += size; + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(InStream_SeekSet(_stream, item.Pa)) + inStream->Init(size); + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + + opRes = (copyCoder->TotalSize == size) ? + NExtract::NOperationResult::kOK : (copyCoder->TotalSize < size) ? + NExtract::NOperationResult::kUnexpectedEnd : + NExtract::NOperationResult::kDataError; + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + const CSection &item = _items[index]; + return CreateLimitedInStream(_stream, item.Pa, item.GetSize_Extract(), stream); + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail)) +{ + _allowTail = IntToBool(allowTail); + return S_OK; +} + +static const Byte k_Signature[] = { 'V', 'Z' }; + +REGISTER_ARC_I( + "TE", "te", NULL, 0xCF, + k_Signature, + 0, + NArcInfoFlags::kPreArc, + IsArc_Te) + +} +} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/PpmdHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PpmdHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/PpmdHandler.cpp 2016-02-01 16:38:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/PpmdHandler.cpp 2023-12-11 10:00:00.000000000 +0000 @@ -1,471 +1,398 @@ -/* PpmdHandler.cpp -- PPMd format handler -2015-11-30 : Igor Pavlov : Public domain -This code is based on: - PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" -#include "../../../C/Alloc.h" -#include "../../../C/Ppmd7.h" -#include "../../../C/Ppmd8.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/CWrappers.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -using namespace NWindows; - -namespace NArchive { -namespace NPpmd { - -static const UInt32 kBufSize = (1 << 20); - -struct CBuf -{ - Byte *Buf; - - CBuf(): Buf(0) {} - ~CBuf() { ::MidFree(Buf); } - bool Alloc() - { - if (!Buf) - Buf = (Byte *)::MidAlloc(kBufSize); - return (Buf != 0); - } -}; - -static const UInt32 kHeaderSize = 16; -static const UInt32 kSignature = 0x84ACAF8F; -static const unsigned kNewHeaderVer = 8; - -struct CItem -{ - UInt32 Attrib; - UInt32 Time; - AString Name; - - unsigned Order; - unsigned MemInMB; - unsigned Ver; - unsigned Restor; - - HRESULT ReadHeader(ISequentialInStream *s, UInt32 &headerSize); - bool IsSupported() const { return Ver == 7 || (Ver == 8 && Restor <= 1); } -}; - -HRESULT CItem::ReadHeader(ISequentialInStream *s, UInt32 &headerSize) -{ - Byte h[kHeaderSize]; - RINOK(ReadStream_FALSE(s, h, kHeaderSize)); - if (GetUi32(h) != kSignature) - return S_FALSE; - Attrib = GetUi32(h + 4); - Time = GetUi32(h + 12); - unsigned info = GetUi16(h + 8); - Order = (info & 0xF) + 1; - MemInMB = ((info >> 4) & 0xFF) + 1; - Ver = info >> 12; - - if (Ver < 6 || Ver > 11) return S_FALSE; - - UInt32 nameLen = GetUi16(h + 10); - Restor = nameLen >> 14; - if (Restor > 2) - return S_FALSE; - if (Ver >= kNewHeaderVer) - nameLen &= 0x3FFF; - if (nameLen > (1 << 9)) - return S_FALSE; - char *name = Name.GetBuf(nameLen); - HRESULT res = ReadStream_FALSE(s, name, nameLen); - Name.ReleaseBuf_CalcLen(nameLen); - headerSize = kHeaderSize + nameLen; - return res; -} - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CItem _item; - UInt32 _headerSize; - bool _packSize_Defined; - UInt64 _packSize; - CMyComPtr _stream; - -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidMTime, - kpidAttrib, - kpidMethod -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; - } - prop.Detach(value); - return S_OK; -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -static void UIntToString(AString &s, const char *prefix, unsigned value) -{ - s += prefix; - char temp[16]; - ::ConvertUInt32ToString((UInt32)value, temp); - s += temp; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPath: prop = MultiByteToUnicodeString(_item.Name, CP_ACP); break; - case kpidMTime: - { - // time can be in Unix format ??? - FILETIME utc; - if (NTime::DosTimeToFileTime(_item.Time, utc)) - prop = utc; - break; - } - case kpidAttrib: prop = _item.Attrib; break; - case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; - case kpidMethod: - { - AString s = "PPMd"; - s += (char)('A' + _item.Ver); - UIntToString(s, ":o", _item.Order); - UIntToString(s, ":mem", _item.MemInMB); - s += 'm'; - if (_item.Ver >= kNewHeaderVer && _item.Restor != 0) - UIntToString(s, ":r", _item.Restor); - prop = s; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - return OpenSeq(stream); -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - COM_TRY_BEGIN - HRESULT res; - try - { - Close(); - res = _item.ReadHeader(stream, _headerSize); - } - catch(...) { res = S_FALSE; } - if (res == S_OK) - _stream = stream; - else - Close(); - return res; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _packSize = 0; - _packSize_Defined = false; - _stream.Release(); - return S_OK; -} - -static const UInt32 kTopValue = (1 << 24); -static const UInt32 kBot = (1 << 15); - -struct CRangeDecoder -{ - IPpmd7_RangeDec s; - UInt32 Range; - UInt32 Code; - UInt32 Low; - CByteInBufWrap *Stream; - -public: - bool Init() - { - Code = 0; - Low = 0; - Range = 0xFFFFFFFF; - for (int i = 0; i < 4; i++) - Code = (Code << 8) | Stream->ReadByte(); - return Code < 0xFFFFFFFF; - } - - void Normalize() - { - while ((Low ^ (Low + Range)) < kTopValue || - Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) - { - Code = (Code << 8) | Stream->ReadByte(); - Range <<= 8; - Low <<= 8; - } - } - - CRangeDecoder(); -}; - - -extern "C" { - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - return p->Code / (p->Range /= total); -} - -static void Range_Decode(void *pp, UInt32 start, UInt32 size) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - start *= p->Range; - p->Low += start; - p->Code -= start; - p->Range *= size; - p->Normalize(); -} - -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - if (p->Code / (p->Range >>= 14) < size0) - { - Range_Decode(p, 0, size0); - return 0; - } - else - { - Range_Decode(p, size0, (1 << 14) - size0); - return 1; - } -} - -} - -CRangeDecoder::CRangeDecoder() -{ - s.GetThreshold = Range_GetThreshold; - s.Decode = Range_Decode; - s.DecodeBit = Range_DecodeBit; -} - -struct CPpmdCpp -{ - unsigned Ver; - CRangeDecoder _rc; - CPpmd7 _ppmd7; - CPpmd8 _ppmd8; - - CPpmdCpp(unsigned version) - { - Ver = version; - Ppmd7_Construct(&_ppmd7); - Ppmd8_Construct(&_ppmd8); - } - - ~CPpmdCpp() - { - Ppmd7_Free(&_ppmd7, &g_BigAlloc); - Ppmd8_Free(&_ppmd8, &g_BigAlloc); - } - - bool Alloc(UInt32 memInMB) - { - memInMB <<= 20; - if (Ver == 7) - return Ppmd7_Alloc(&_ppmd7, memInMB, &g_BigAlloc) != 0; - return Ppmd8_Alloc(&_ppmd8, memInMB, &g_BigAlloc) != 0; - } - - void Init(unsigned order, unsigned restor) - { - if (Ver == 7) - Ppmd7_Init(&_ppmd7, order); - else - Ppmd8_Init(&_ppmd8, order, restor);; - } - - bool InitRc(CByteInBufWrap *inStream) - { - if (Ver == 7) - { - _rc.Stream = inStream; - return _rc.Init(); - } - else - { - _ppmd8.Stream.In = &inStream->p; - return Ppmd8_RangeDec_Init(&_ppmd8) != 0; - } - } - - bool IsFinishedOK() - { - if (Ver == 7) - return Ppmd7z_RangeDec_IsFinishedOK(&_rc); - return Ppmd8_RangeDec_IsFinishedOK(&_ppmd8); - } -}; - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - // extractCallback->SetTotal(_packSize); - UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CByteInBufWrap inBuf; - if (!inBuf.Alloc(1 << 20)) - return E_OUTOFMEMORY; - inBuf.Stream = _stream; - - CBuf outBuf; - if (!outBuf.Alloc()) - return E_OUTOFMEMORY; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, true); - - CPpmdCpp ppmd(_item.Ver); - if (!ppmd.Alloc(_item.MemInMB)) - return E_OUTOFMEMORY; - - Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod; - - if (_item.IsSupported()) - { - opRes = NExtract::NOperationResult::kDataError; - - ppmd.Init(_item.Order, _item.Restor); - inBuf.Init(); - UInt64 outSize = 0; - - if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK) - for (;;) - { - lps->InSize = _packSize = inBuf.GetProcessed(); - lps->OutSize = outSize; - RINOK(lps->SetCur()); - - size_t i; - int sym = 0; - - if (ppmd.Ver == 7) - { - for (i = 0; i < kBufSize; i++) - { - sym = Ppmd7_DecodeSymbol(&ppmd._ppmd7, &ppmd._rc.s); - if (inBuf.Extra || sym < 0) - break; - outBuf.Buf[i] = (Byte)sym; - } - } - else - { - for (i = 0; i < kBufSize; i++) - { - sym = Ppmd8_DecodeSymbol(&ppmd._ppmd8); - if (inBuf.Extra || sym < 0) - break; - outBuf.Buf[i] = (Byte)sym; - } - } - - outSize += i; - _packSize = _headerSize + inBuf.GetProcessed(); - _packSize_Defined = true; - if (realOutStream) - { - RINOK(WriteStream(realOutStream, outBuf.Buf, i)); - } - - if (inBuf.Extra) - { - opRes = NExtract::NOperationResult::kUnexpectedEnd; - break; - } - - if (sym < 0) - { - if (sym == -1 && ppmd.IsFinishedOK()) - opRes = NExtract::NOperationResult::kOK; - break; - } - } - - RINOK(inBuf.Res); - } - - realOutStream.Release(); - return extractCallback->SetOperationResult(opRes); -} - - -static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 }; - -REGISTER_ARC_I( - "Ppmd", "pmd", 0, 0xD, - k_Signature, - 0, - 0, - NULL) - -}} +/* PpmdHandler.cpp -- PPMd format handler +2020 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain + Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/Alloc.h" +#include "../../../C/Ppmd7.h" +#include "../../../C/Ppmd8.h" + +#include "../../Common/ComTry.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/CWrappers.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +using namespace NWindows; + +namespace NArchive { +namespace NPpmd { + +static const UInt32 kBufSize = (1 << 20); + +struct CBuf +{ + Byte *Buf; + + CBuf(): Buf(NULL) {} + ~CBuf() { ::MidFree(Buf); } + bool Alloc() + { + if (!Buf) + Buf = (Byte *)::MidAlloc(kBufSize); + return (Buf != NULL); + } +}; + +static const UInt32 kHeaderSize = 16; +static const UInt32 kSignature = 0x84ACAF8F; +static const unsigned kNewHeaderVer = 8; + +struct CItem +{ + UInt32 Attrib; + UInt32 Time; + AString Name; + + unsigned Order; + unsigned MemInMB; + unsigned Ver; + unsigned Restor; + + HRESULT ReadHeader(ISequentialInStream *s, UInt32 &headerSize); + bool IsSupported() const + { + return (Ver == 7 && Order >= PPMD7_MIN_ORDER) + || (Ver == 8 && Order >= PPMD8_MIN_ORDER && Restor < PPMD8_RESTORE_METHOD_UNSUPPPORTED); + } +}; + +HRESULT CItem::ReadHeader(ISequentialInStream *s, UInt32 &headerSize) +{ + Byte h[kHeaderSize]; + RINOK(ReadStream_FALSE(s, h, kHeaderSize)) + if (GetUi32(h) != kSignature) + return S_FALSE; + Attrib = GetUi32(h + 4); + Time = GetUi32(h + 12); + const unsigned info = GetUi16(h + 8); + Order = (info & 0xF) + 1; + MemInMB = ((info >> 4) & 0xFF) + 1; + Ver = info >> 12; + + if (Ver < 6 || Ver > 11) return S_FALSE; + + UInt32 nameLen = GetUi16(h + 10); + Restor = nameLen >> 14; + if (Restor > 2) + return S_FALSE; + if (Ver >= kNewHeaderVer) + nameLen &= 0x3FFF; + if (nameLen > (1 << 9)) + return S_FALSE; + char *name = Name.GetBuf(nameLen); + const HRESULT res = ReadStream_FALSE(s, name, nameLen); + Name.ReleaseBuf_CalcLen(nameLen); + headerSize = kHeaderSize + nameLen; + return res; +} + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) + CItem _item; + UInt32 _headerSize; + bool _packSize_Defined; + UInt64 _packSize; + CMyComPtr _stream; + + void GetVersion(NCOM::CPropVariant &prop); +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidMTime, + kpidAttrib, + kpidMethod +}; + +static const Byte kArcProps[] = +{ + kpidMethod +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +void CHandler::GetVersion(NCOM::CPropVariant &prop) +{ + AString s ("PPMd"); + s.Add_Char((char)('A' + _item.Ver)); + s += ":o"; + s.Add_UInt32(_item.Order); + s += ":mem"; + s.Add_UInt32(_item.MemInMB); + s.Add_Char('m'); + if (_item.Ver >= kNewHeaderVer && _item.Restor != 0) + { + s += ":r"; + s.Add_UInt32(_item.Restor); + } + prop = s; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_packSize_Defined) prop = _packSize; break; + case kpidMethod: GetVersion(prop); break; + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPath: prop = MultiByteToUnicodeString(_item.Name, CP_ACP); break; + case kpidMTime: + { + // time can be in Unix format ??? + FILETIME utc; + if (NTime::DosTime_To_FileTime(_item.Time, utc)) + prop = utc; + break; + } + case kpidAttrib: prop = _item.Attrib; break; + case kpidPackSize: if (_packSize_Defined) prop = _packSize; break; + case kpidMethod: GetVersion(prop); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) +{ + return OpenSeq(stream); +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + COM_TRY_BEGIN + HRESULT res; + try + { + Close(); + res = _item.ReadHeader(stream, _headerSize); + } + catch(...) { res = S_FALSE; } + if (res == S_OK) + _stream = stream; + else + Close(); + return res; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _packSize = 0; + _packSize_Defined = false; + _stream.Release(); + return S_OK; +} + + + +struct CPpmdCpp +{ + unsigned Ver; + CPpmd7 _ppmd7; + CPpmd8 _ppmd8; + + CPpmdCpp(unsigned version) + { + Ver = version; + Ppmd7_Construct(&_ppmd7); + Ppmd8_Construct(&_ppmd8); + } + + ~CPpmdCpp() + { + Ppmd7_Free(&_ppmd7, &g_BigAlloc); + Ppmd8_Free(&_ppmd8, &g_BigAlloc); + } + + bool Alloc(UInt32 memInMB) + { + memInMB <<= 20; + if (Ver == 7) + return Ppmd7_Alloc(&_ppmd7, memInMB, &g_BigAlloc) != 0; + return Ppmd8_Alloc(&_ppmd8, memInMB, &g_BigAlloc) != 0; + } + + void Init(unsigned order, unsigned restor) + { + if (Ver == 7) + Ppmd7_Init(&_ppmd7, order); + else + Ppmd8_Init(&_ppmd8, order, restor); + } + + bool InitRc(CByteInBufWrap *inStream) + { + if (Ver == 7) + { + _ppmd7.rc.dec.Stream = &inStream->vt; + return (Ppmd7a_RangeDec_Init(&_ppmd7.rc.dec) != 0); + } + else + { + _ppmd8.Stream.In = &inStream->vt; + return Ppmd8_Init_RangeDec(&_ppmd8) != 0; + } + } + + bool IsFinishedOK() + { + if (Ver == 7) + return Ppmd7z_RangeDec_IsFinishedOK(&_ppmd7.rc.dec); + return Ppmd8_RangeDec_IsFinishedOK(&_ppmd8); + } +}; + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + // extractCallback->SetTotal(_packSize); + UInt64 currentTotalPacked = 0; + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) + Int32 opRes; +{ + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CByteInBufWrap inBuf; + if (!inBuf.Alloc(1 << 20)) + return E_OUTOFMEMORY; + inBuf.Stream = _stream; + + CBuf outBuf; + if (!outBuf.Alloc()) + return E_OUTOFMEMORY; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + CPpmdCpp ppmd(_item.Ver); + if (!ppmd.Alloc(_item.MemInMB)) + return E_OUTOFMEMORY; + + opRes = NExtract::NOperationResult::kUnsupportedMethod; + + if (_item.IsSupported()) + { + opRes = NExtract::NOperationResult::kDataError; + + ppmd.Init(_item.Order, _item.Restor); + inBuf.Init(); + UInt64 outSize = 0; + + if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK) + for (;;) + { + lps->InSize = _packSize = inBuf.GetProcessed(); + lps->OutSize = outSize; + RINOK(lps->SetCur()) + + size_t i; + int sym = 0; + + Byte *buf = outBuf.Buf; + if (ppmd.Ver == 7) + { + for (i = 0; i < kBufSize; i++) + { + sym = Ppmd7a_DecodeSymbol(&ppmd._ppmd7); + if (inBuf.Extra || sym < 0) + break; + buf[i] = (Byte)sym; + } + } + else + { + for (i = 0; i < kBufSize; i++) + { + sym = Ppmd8_DecodeSymbol(&ppmd._ppmd8); + if (inBuf.Extra || sym < 0) + break; + buf[i] = (Byte)sym; + } + } + + outSize += i; + _packSize = _headerSize + inBuf.GetProcessed(); + _packSize_Defined = true; + if (realOutStream) + { + RINOK(WriteStream(realOutStream, outBuf.Buf, i)) + } + + if (inBuf.Extra) + { + opRes = NExtract::NOperationResult::kUnexpectedEnd; + break; + } + + if (sym < 0) + { + if (sym == -1 && ppmd.IsFinishedOK()) + opRes = NExtract::NOperationResult::kOK; + break; + } + } + + RINOK(inBuf.Res) + } +} + return extractCallback->SetOperationResult(opRes); +} + + +static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 }; + +REGISTER_ARC_I( + "Ppmd", "pmd", NULL, 0xD, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/QcowHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/QcowHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/QcowHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/QcowHandler.cpp 2024-06-28 10:00:00.000000000 +0000 @@ -1,615 +1,710 @@ -// QcowHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/DeflateDecoder.h" - -#include "HandlerCont.h" - -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -using namespace NWindows; - -namespace NArchive { -namespace NQcow { - -#define SIGNATURE { 'Q', 'F', 'I', 0xFB, 0, 0, 0 } - -static const Byte k_Signature[] = SIGNATURE; - -class CHandler: public CHandlerImg -{ - unsigned _clusterBits; - unsigned _numMidBits; - UInt64 _compressedFlag; - - CObjectVector _tables; - UInt64 _cacheCluster; - CByteBuffer _cache; - CByteBuffer _cacheCompressed; - - UInt64 _comprPos; - size_t _comprSize; - - UInt64 _phySize; - - CBufInStream *_bufInStreamSpec; - CMyComPtr _bufInStream; - - CBufPtrSeqOutStream *_bufOutStreamSpec; - CMyComPtr _bufOutStream; - - NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoderSpec; - CMyComPtr _deflateDecoder; - - bool _needDeflate; - bool _isArc; - bool _unsupported; - - UInt32 _version; - UInt32 _cryptMethod; - - HRESULT Seek(UInt64 offset) - { - _posInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); - } - - HRESULT InitAndSeek() - { - _virtPos = 0; - return Seek(0); - } - - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); - -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - - -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= _size) - return S_OK; - { - UInt64 rem = _size - _virtPos; - if (size > rem) - size = (UInt32)rem; - if (size == 0) - return S_OK; - } - - for (;;) - { - UInt64 cluster = _virtPos >> _clusterBits; - size_t clusterSize = (size_t)1 << _clusterBits; - size_t lowBits = (size_t)_virtPos & (clusterSize - 1); - { - size_t rem = clusterSize - lowBits; - if (size > rem) - size = (UInt32)rem; - } - - if (cluster == _cacheCluster) - { - memcpy(data, _cache + lowBits, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } - - UInt64 high = cluster >> _numMidBits; - - if (high < _tables.Size()) - { - const CByteBuffer &buffer = _tables[(unsigned)high]; - - if (buffer.Size() != 0) - { - size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1); - const Byte *p = (const Byte *)buffer + (midBits << 3); - UInt64 v = Get64(p); - - if (v != 0) - { - if ((v & _compressedFlag) != 0) - { - if (_version <= 1) - return E_FAIL; - unsigned numOffsetBits = (62 - (_clusterBits - 8)); - UInt64 offset = v & (((UInt64)1 << 62) - 1); - const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; - offset &= ((UInt64)1 << numOffsetBits) - 1; - UInt64 sectorOffset = offset >> 9 << 9; - UInt64 offset2inCache = sectorOffset - _comprPos; - - if (sectorOffset >= _comprPos && offset2inCache < _comprSize) - { - if (offset2inCache != 0) - { - _comprSize -= (size_t)offset2inCache; - memmove(_cacheCompressed, _cacheCompressed + offset2inCache, _comprSize); - _comprPos = sectorOffset; - } - sectorOffset += _comprSize; - } - else - { - _comprPos = sectorOffset; - _comprSize = 0; - } - - // printf("\nDeflate"); - if (sectorOffset != _posInArc) - { - // printf("\nDeflate %12I64x %12I64x\n", sectorOffset, sectorOffset - _posInArc); - RINOK(Seek(sectorOffset)); - } - - if (_cacheCompressed.Size() < dataSize) - return E_FAIL; - size_t dataSize3 = dataSize - _comprSize; - size_t dataSize2 = dataSize3; - RINOK(ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2)); - _posInArc += dataSize2; - if (dataSize2 != dataSize3) - return E_FAIL; - _comprSize += dataSize2; - - const size_t kSectorMask = (1 << 9) - 1; - size_t offsetInSector = ((size_t)offset & kSectorMask); - _bufInStreamSpec->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector); - - _cacheCluster = (UInt64)(Int64)-1; - if (_cache.Size() < clusterSize) - return E_FAIL; - _bufOutStreamSpec->Init(_cache, clusterSize); - - // Do we need to use smaller block than clusterSize for last cluster? - UInt64 blockSize64 = clusterSize; - HRESULT res = _deflateDecoderSpec->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); - - /* - if (_bufOutStreamSpec->GetPos() != clusterSize) - memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos()); - */ - - if (res == S_OK) - if (!_deflateDecoderSpec->IsFinished() - || _bufOutStreamSpec->GetPos() != clusterSize) - res = S_FALSE; - - RINOK(res); - _cacheCluster = cluster; - - continue; - /* - memcpy(data, _cache + lowBits, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - - // version 3 support zero clusters - if (((UInt32)v & 511) != 1) - { - v &= (_compressedFlag - 1); - v += lowBits; - if (v != _posInArc) - { - // printf("\n%12I64x\n", v - _posInArc); - RINOK(Seek(v)); - } - HRESULT res = Stream->Read(data, size, &size); - _posInArc += size; - _virtPos += size; - if (processedSize) - *processedSize = size; - return res; - } - } - } - } - - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } -} - - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize -}; - -static const Byte kArcProps[] = -{ - kpidClusterSize, - kpidUnpackVer, - 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)1 << _clusterBits; break; - case kpidPhySize: if (_phySize != 0) prop = _phySize; break; - case kpidUnpackVer: prop = _version; break; - - case kpidMethod: - { - AString s; - - if (_needDeflate) - s = "Deflate"; - - if (_cryptMethod != 0) - { - s.Add_Space_if_NotEmpty(); - if (_cryptMethod == 1) - s += "AES"; - else - { - char temp[16]; - ConvertUInt32ToString(_cryptMethod, temp); - s += temp; - } - } - - if (!s.IsEmpty()) - prop = s; - - break; - } - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - // if (_headerError) v |= kpv_ErrorFlags_HeadersError; - 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 -} - - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback) -{ - const unsigned kHeaderSize = 18 * 4; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - - if (memcmp(buf, k_Signature, 4) != 0) - return S_FALSE; - - _version = Get32(buf + 4); - if (_version < 1 || _version > 3) - return S_FALSE; - - const UInt64 backOffset = Get64(buf + 8); - // UInt32 backSize = Get32(buf + 0x10); - - UInt64 l1Offset = 0; - UInt32 l1Size = 0; - - if (_version == 1) - { - // _mTime = Get32(buf + 0x14); // is unused im most images - _size = Get64(buf + 0x18); - _clusterBits = buf[0x20]; - _numMidBits = buf[0x21]; - if (_clusterBits < 9 || _clusterBits > 30) - return S_FALSE; - if (_numMidBits < 1 || _numMidBits > 28) - return S_FALSE; - _cryptMethod = Get32(buf + 0x24); - l1Offset = Get64(buf + 0x28); - if (l1Offset < 0x30) - return S_FALSE; - unsigned numBits2 = (_clusterBits + _numMidBits); - UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2; - if (l1Size64 > ((UInt32)1 << 31)) - return S_FALSE; - l1Size = (UInt32)l1Size64; - } - else - { - _clusterBits = Get32(buf + 0x14); - if (_clusterBits < 9 || _clusterBits > 30) - return S_FALSE; - _numMidBits = _clusterBits - 3; - _size = Get64(buf + 0x18); - _cryptMethod = Get32(buf + 0x20); - l1Size = Get32(buf + 0x24); - l1Offset = Get64(buf + 0x28); // must be aligned for cluster - - UInt64 refOffset = Get64(buf + 0x30); // must be aligned for cluster - UInt32 refClusters = Get32(buf + 0x38); - - // UInt32 numSnapshots = Get32(buf + 0x3C); - // UInt64 snapshotsOffset = Get64(buf + 0x40); // must be aligned for cluster - /* - if (numSnapshots != 0) - return S_FALSE; - */ - - if (refClusters != 0) - { - size_t numBytes = refClusters << _clusterBits; - /* - CByteBuffer refs; - refs.Alloc(numBytes); - RINOK(stream->Seek(refOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, refs, numBytes)); - */ - UInt64 end = refOffset + numBytes; - if (_phySize < end) - _phySize = end; - /* - for (size_t i = 0; i < numBytes; i += 2) - { - UInt32 v = GetBe16((const Byte *)refs + (size_t)i); - if (v == 0) - continue; - } - */ - } - } - - _isArc = true; - - if (backOffset != 0) - { - _unsupported = true; - return S_FALSE; - } - - const size_t clusterSize = (size_t)1 << _clusterBits; - - CByteBuffer table; - { - size_t t1SizeBytes = (size_t)l1Size << 3; - if ((t1SizeBytes >> 3) != l1Size) - return S_FALSE; - table.Alloc(t1SizeBytes); - RINOK(stream->Seek(l1Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, table, t1SizeBytes)); - - { - UInt64 end = l1Offset + t1SizeBytes; - // we need to uses align end for empty qcow files - end = (end + clusterSize - 1) >> _clusterBits << _clusterBits; - if (_phySize < end) - _phySize = end; - } - } - - if (openCallback) - { - UInt64 totalBytes = (UInt64)l1Size << (_numMidBits + 3); - RINOK(openCallback->SetTotal(NULL, &totalBytes)); - } - - _compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62); - const UInt64 offsetMask = _compressedFlag - 1; - - for (UInt32 i = 0; i < l1Size; i++) - { - if (openCallback) - { - UInt64 numBytes = (UInt64)i << (_numMidBits + 3); - RINOK(openCallback->SetCompleted(NULL, &numBytes)); - } - - CByteBuffer &buf2 = _tables.AddNew(); - - { - UInt64 v = Get64((const Byte *)table + (size_t)i * 8); - v &= offsetMask; - if (v == 0) - continue; - - buf2.Alloc((size_t)1 << (_numMidBits + 3)); - RINOK(stream->Seek(v, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf2, clusterSize)); - - const UInt64 end = v + clusterSize; - if (_phySize < end) - _phySize = end; - } - - for (size_t k = 0; k < clusterSize; k += 8) - { - const UInt64 v = Get64((const Byte *)buf2 + (size_t)k); - if (v == 0) - continue; - UInt64 offset = v & offsetMask; - size_t dataSize = clusterSize; - - if ((v & _compressedFlag) != 0) - { - if (_version <= 1) - { - unsigned numOffsetBits = (63 - _clusterBits); - dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; - offset &= ((UInt64)1 << numOffsetBits) - 1; - dataSize = 0; - // offset >>= 9; - // offset <<= 9; - } - else - { - unsigned numOffsetBits = (62 - (_clusterBits - 8)); - dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; - offset &= ((UInt64)1 << numOffsetBits) - 1; - offset >>= 9; - offset <<= 9; - } - _needDeflate = true; - } - else - { - UInt32 low = (UInt32)v & 511; - if (low != 0) - { - // version 3 support zero clusters - if (_version < 3 || low != 1) - { - _unsupported = true; - return S_FALSE; - } - } - } - - UInt64 end = offset + dataSize; - if (_phySize < end) - _phySize = end; - } - } - - if (_cryptMethod != 0) - _unsupported = true; - - if (_needDeflate && _version <= 1) // that case was not implemented - _unsupported = true; - - Stream = stream; - return S_OK; -} - - -STDMETHODIMP CHandler::Close() -{ - _tables.Clear(); - _phySize = 0; - _size = 0; - - _cacheCluster = (UInt64)(Int64)-1; - _comprPos = 0; - _comprSize = 0; - _needDeflate = false; - - _isArc = false; - _unsupported = false; - - _imgExt = NULL; - Stream.Release(); - return S_OK; -} - - -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = NULL; - - if (_unsupported) - return S_FALSE; - - if (_needDeflate) - { - if (_version <= 1) - return S_FALSE; - - if (!_bufInStream) - { - _bufInStreamSpec = new CBufInStream; - _bufInStream = _bufInStreamSpec; - } - - if (!_bufOutStream) - { - _bufOutStreamSpec = new CBufPtrSeqOutStream(); - _bufOutStream = _bufOutStreamSpec; - } - - if (!_deflateDecoder) - { - _deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder(); - _deflateDecoder = _deflateDecoderSpec; - _deflateDecoderSpec->Set_NeedFinishInput(true); - } - - size_t clusterSize = (size_t)1 << _clusterBits; - _cache.AllocAtLeast(clusterSize); - _cacheCompressed.AllocAtLeast(clusterSize * 2); - } - - CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - - -REGISTER_ARC_I( - "QCOW", "qcow qcow2 qcow2c", NULL, 0xCA, - k_Signature, - 0, - 0, - NULL) - -}} +// QcowHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer2.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/DeflateDecoder.h" + +#include "HandlerCont.h" + +#define Get32(p) GetBe32a(p) +#define Get64(p) GetBe64a(p) + +using namespace NWindows; + +namespace NArchive { +namespace NQcow { + +static const Byte k_Signature[] = { 'Q', 'F', 'I', 0xFB, 0, 0, 0 }; + +/* +VA to PA maps: + high bits (L1) : : index in L1 (_dir) : _dir[high_index] points to Table. + mid bits (L2) : _numMidBits : index in Table, Table[index] points to cluster start offset in arc file. + low bits : _clusterBits : offset inside cluster. +*/ + +Z7_class_CHandler_final: public CHandlerImg +{ + Z7_IFACE_COM7_IMP(IInArchive_Img) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + + unsigned _clusterBits; + unsigned _numMidBits; + UInt64 _compressedFlag; + + CObjArray2 _dir; + CAlignedBuffer _table; + CByteBuffer _cache; + CByteBuffer _cacheCompressed; + UInt64 _cacheCluster; + + UInt64 _comprPos; + size_t _comprSize; + + bool _needCompression; + bool _isArc; + bool _unsupported; + Byte _compressionType; + + UInt64 _phySize; + + CMyComPtr2 _bufInStream; + CMyComPtr2 _bufOutStream; + CMyComPtr2 _deflateDecoder; + + UInt32 _version; + UInt32 _cryptMethod; + UInt64 _incompatFlags; + + HRESULT Seek2(UInt64 offset) + { + _posInArc = offset; + return InStream_SeekSet(Stream, offset); + } + + HRESULT InitAndSeek() + { + _virtPos = 0; + return Seek2(0); + } + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; +}; + + +static const UInt32 kEmptyDirItem = (UInt32)0 - 1; + +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + // printf("\nRead _virtPos = %6d size = %6d\n", (UInt32)_virtPos, size); + if (_virtPos >= _size) + return S_OK; + { + const UInt64 rem = _size - _virtPos; + if (size > rem) + size = (UInt32)rem; + if (size == 0) + return S_OK; + } + + for (;;) + { + const UInt64 cluster = _virtPos >> _clusterBits; + const size_t clusterSize = (size_t)1 << _clusterBits; + const size_t lowBits = (size_t)_virtPos & (clusterSize - 1); + { + const size_t rem = clusterSize - lowBits; + if (size > rem) + size = (UInt32)rem; + } + if (cluster == _cacheCluster) + { + memcpy(data, _cache + lowBits, size); + break; + } + + const UInt64 high = cluster >> _numMidBits; + + if (high < _dir.Size()) + { + const UInt32 tabl = _dir[(size_t)high]; + if (tabl != kEmptyDirItem) + { + const size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1); + const Byte *p = _table + ((((size_t)tabl << _numMidBits) + midBits) << 3); + UInt64 v = Get64(p); + + if (v) + { + if (v & _compressedFlag) + { + if (_version <= 1) + return E_FAIL; + /* + the example of table record for 12-bit clusters (4KB uncompressed): + 2 bits : isCompressed status + (4 == _clusterBits - 8) bits : (num_sectors - 1) + packSize = num_sectors * 512; + it uses one additional bit over unpacked cluster_bits. + (49 == 61 - _clusterBits) bits : offset of 512-byte sector + 9 bits : offset in 512-byte sector + */ + const unsigned numOffsetBits = 62 - (_clusterBits - 8); + const UInt64 offset = v & (((UInt64)1 << 62) - 1); + const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; + UInt64 sectorOffset = offset & (((UInt64)1 << numOffsetBits) - (1 << 9)); + const UInt64 offset2inCache = sectorOffset - _comprPos; + + // _comprPos is aligned for 512-bytes + // we try to use previous _cacheCompressed that contains compressed data + // that was read for previous unpacking + + if (sectorOffset >= _comprPos && offset2inCache < _comprSize) + { + if (offset2inCache) + { + _comprSize -= (size_t)offset2inCache; + memmove(_cacheCompressed, _cacheCompressed + (size_t)offset2inCache, _comprSize); + _comprPos = sectorOffset; + } + sectorOffset += _comprSize; + } + else + { + _comprPos = sectorOffset; + _comprSize = 0; + } + + if (dataSize > _comprSize) + { + if (sectorOffset != _posInArc) + { + // printf("\nDeflate-Seek %12I64x %12I64x\n", sectorOffset, sectorOffset - _posInArc); + RINOK(Seek2(sectorOffset)) + } + if (_cacheCompressed.Size() < dataSize) + return E_FAIL; + const size_t dataSize3 = dataSize - _comprSize; + size_t dataSize2 = dataSize3; + // printf("\n\n=======\nReadStream = %6d _comprPos = %6d \n", (UInt32)dataSize2, (UInt32)_comprPos); + const HRESULT hres = ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2); + _posInArc += dataSize2; + RINOK(hres) + if (dataSize2 != dataSize3) + return E_FAIL; + _comprSize += dataSize2; + } + + const size_t kSectorMask = (1 << 9) - 1; + const size_t offsetInSector = (size_t)offset & kSectorMask; + _bufInStream->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector); + _cacheCluster = (UInt64)(Int64)-1; + if (_cache.Size() < clusterSize) + return E_FAIL; + _bufOutStream->Init(_cache, clusterSize); + // Do we need to use smaller block than clusterSize for last cluster? + const UInt64 blockSize64 = clusterSize; + HRESULT res = _deflateDecoder.Interface()->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); + /* + if (_bufOutStreamSpec->GetPos() != clusterSize) + memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos()); + */ + if (res == S_OK) + if (!_deflateDecoder->IsFinished() + || _bufOutStream->GetPos() != clusterSize) + res = S_FALSE; + RINOK(res) + _cacheCluster = cluster; + continue; + /* + memcpy(data, _cache + lowBits, size); + break; + */ + } + + // version_3 supports zero clusters + if (((UInt32)v & 511) != 1) + { + v &= _compressedFlag - 1; + v += lowBits; + if (v != _posInArc) + { + // printf("\n%12I64x\n", v - _posInArc); + RINOK(Seek2(v)) + } + const HRESULT res = Stream->Read(data, size, &size); + _posInArc += size; + _virtPos += size; + if (processedSize) + *processedSize = size; + return res; + } + } + } + } + + memset(data, 0, size); + break; + } + + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; +} + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidClusterSize, + kpidSectorSize, // actually we need variable to show table size + kpidHeadersSize, + kpidUnpackVer, + kpidMethod, + kpidCharacts +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static const CUInt32PCharPair g_IncompatFlags_Characts[] = +{ + { 0, "Dirty" }, + { 1, "Corrupt" }, + { 2, "External_Data_File" }, + { 3, "Compression" }, + { 4, "Extended_L2" } +}; + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidClusterSize: prop = (UInt32)1 << _clusterBits; break; + case kpidSectorSize: prop = (UInt32)1 << (_numMidBits + 3); break; + case kpidHeadersSize: prop = _table.Size() + (UInt64)_dir.Size() * 8; break; + case kpidPhySize: if (_phySize) prop = _phySize; break; + case kpidUnpackVer: prop = _version; break; + case kpidCharacts: + { + if (_incompatFlags) + { + AString s ("incompatible: "); + // we need to show also high 32-bits. + s += FlagsToString(g_IncompatFlags_Characts, + Z7_ARRAY_SIZE(g_IncompatFlags_Characts), (UInt32)_incompatFlags); + prop = s; + } + break; + } + case kpidMethod: + { + AString s; + + if (_compressionType) + { + if (_compressionType == 1) + s += "ZSTD"; + else + { + s += "Compression:"; + s.Add_UInt32(_compressionType); + } + } + else if (_needCompression) + s.Add_OptSpaced("Deflate"); + + if (_cryptMethod) + { + s.Add_Space_if_NotEmpty(); + if (_cryptMethod == 1) + s += "AES"; + if (_cryptMethod == 2) + s += "LUKS"; + else + { + s += "Encryption:"; + s.Add_UInt32(_cryptMethod); + } + } + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + // if (_headerError) v |= kpv_ErrorFlags_HeadersError; + if (!Stream && v == 0) + v = kpv_ErrorFlags_HeadersError; + if (v) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(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 +} + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback) +{ + UInt64 buf64[0x70 / 8]; + RINOK(ReadStream_FALSE(stream, buf64, sizeof(buf64))) + const void *buf = (const void *)buf64; + // signature: { 'Q', 'F', 'I', 0xFB } + if (*(const UInt32 *)buf != Z7_CONV_BE_TO_NATIVE_CONST32(0x514649fb)) + return S_FALSE; + _version = Get32((const Byte *)(const void *)buf64 + 4); + if (_version < 1 || _version > 3) + return S_FALSE; + + const UInt64 k_UncompressedSize_MAX = (UInt64)1 << 60; + const UInt64 k_CompressedSize_MAX = (UInt64)1 << 60; + + _size = Get64((const Byte *)(const void *)buf64 + 0x18); + if (_size > k_UncompressedSize_MAX) + return S_FALSE; + size_t l1Size; + UInt32 headerSize; + + if (_version == 1) + { + // _mTime = Get32((const Byte *)(const void *)buf64 + 0x14); // is unused in most images + _clusterBits = ((const Byte *)(const void *)buf64)[0x20]; + _numMidBits = ((const Byte *)(const void *)buf64)[0x21]; + if (_clusterBits < 9 || _clusterBits > 30) + return S_FALSE; + if (_numMidBits < 1 || _numMidBits > 28) + return S_FALSE; + _cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x24); + const unsigned numBits2 = _clusterBits + _numMidBits; + const UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2; + if (l1Size64 > ((UInt32)1 << 31)) + return S_FALSE; + l1Size = (size_t)l1Size64; + headerSize = 0x30; + } + else + { + _clusterBits = Get32((const Byte *)(const void *)buf64 + 0x14); + if (_clusterBits < 9 || _clusterBits > 30) + return S_FALSE; + _numMidBits = _clusterBits - 3; + _cryptMethod = Get32((const Byte *)(const void *)buf64 + 0x20); + l1Size = Get32((const Byte *)(const void *)buf64 + 0x24); + headerSize = 0x48; + if (_version >= 3) + { + _incompatFlags = Get64((const Byte *)(const void *)buf64 + 0x48); + // const UInt64 CompatFlags = Get64((const Byte *)(const void *)buf64 + 0x50); + // const UInt64 AutoClearFlags = Get64((const Byte *)(const void *)buf64 + 0x58); + // const UInt32 RefCountOrder = Get32((const Byte *)(const void *)buf64 + 0x60); + headerSize = 0x68; + const UInt32 headerSize2 = Get32((const Byte *)(const void *)buf64 + 0x64); + if (headerSize2 > (1u << 30)) + return S_FALSE; + if (headerSize < headerSize2) + headerSize = headerSize2; + if (headerSize2 >= 0x68 + 1) + _compressionType = ((const Byte *)(const void *)buf64)[0x68]; + } + + const UInt64 refOffset = Get64((const Byte *)(const void *)buf64 + 0x30); // must be aligned for cluster + const UInt32 refClusters = Get32((const Byte *)(const void *)buf64 + 0x38); + // UInt32 numSnapshots = Get32((const Byte *)(const void *)buf64 + 0x3C); + // UInt64 snapshotsOffset = Get64((const Byte *)(const void *)buf64 + 0x40); // must be aligned for cluster + /* + if (numSnapshots) + return S_FALSE; + */ + if (refClusters) + { + if (refOffset > k_CompressedSize_MAX) + return S_FALSE; + const UInt64 numBytes = (UInt64)refClusters << _clusterBits; + const UInt64 end = refOffset + numBytes; + if (end > k_CompressedSize_MAX) + return S_FALSE; + /* + CByteBuffer refs; + refs.Alloc(numBytes); + RINOK(InStream_SeekSet(stream, refOffset)) + RINOK(ReadStream_FALSE(stream, refs, numBytes)); + */ + if (_phySize < end) + _phySize = end; + /* + for (size_t i = 0; i < numBytes; i += 2) + { + UInt32 v = GetBe16((const Byte *)refs + (size_t)i); + if (v == 0) + continue; + } + */ + } + } + + const UInt64 l1Offset = Get64((const Byte *)(const void *)buf64 + 0x28); // must be aligned for cluster ? + if (l1Offset < headerSize || l1Offset > k_CompressedSize_MAX) + return S_FALSE; + if (_phySize < headerSize) + _phySize = headerSize; + + _isArc = true; + { + const UInt64 backOffset = Get64((const Byte *)(const void *)buf64 + 8); + // UInt32 backSize = Get32((const Byte *)(const void *)buf64 + 0x10); + if (backOffset) + { + _unsupported = true; + return S_FALSE; + } + } + + UInt64 fileSize = 0; + RINOK(InStream_GetSize_SeekToBegin(stream, fileSize)) + + const size_t clusterSize = (size_t)1 << _clusterBits; + const size_t t1SizeBytes = (size_t)l1Size << 3; + { + const UInt64 end = l1Offset + t1SizeBytes; + if (end > k_CompressedSize_MAX) + return S_FALSE; + // we need to use align end for empty qcow files + // some files has no cluster alignment padding at the end + // but has sector alignment + // end = (end + clusterSize - 1) >> _clusterBits << _clusterBits; + if (_phySize < end) + _phySize = end; + if (end > fileSize) + return S_FALSE; + if (_phySize < fileSize) + { + const UInt64 end2 = (end + 511) & ~(UInt64)511; + if (end2 == fileSize) + _phySize = end2; + } + } + CObjArray table64(l1Size); + { + // if ((t1SizeBytes >> 3) != l1Size) return S_FALSE; + RINOK(InStream_SeekSet(stream, l1Offset)) + RINOK(ReadStream_FALSE(stream, table64, t1SizeBytes)) + } + + _compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62); + const UInt64 offsetMask = _compressedFlag - 1; + const size_t midSize = (size_t)1 << (_numMidBits + 3); + size_t numTables = 0; + size_t i; + + for (i = 0; i < l1Size; i++) + { + const UInt64 v = Get64(table64 + (size_t)i) & offsetMask; + if (!v) + continue; + numTables++; + const UInt64 end = v + midSize; + if (end > k_CompressedSize_MAX) + return S_FALSE; + if (_phySize < end) + _phySize = end; + if (end > fileSize) + return S_FALSE; + } + + if (numTables) + { + const size_t size = (size_t)numTables << (_numMidBits + 3); + if (size >> (_numMidBits + 3) != numTables) + return E_OUTOFMEMORY; + _table.Alloc(size); + if (!_table.IsAllocated()) + return E_OUTOFMEMORY; + if (openCallback) + { + const UInt64 totalBytes = size; + RINOK(openCallback->SetTotal(NULL, &totalBytes)) + } + } + + _dir.SetSize((unsigned)l1Size); + + UInt32 curTable = 0; + + for (i = 0; i < l1Size; i++) + { + Byte *buf2; + { + const UInt64 v = Get64(table64 + (size_t)i) & offsetMask; + if (v == 0) + { + _dir[i] = kEmptyDirItem; + continue; + } + _dir[i] = curTable; + const size_t tableOffset = (size_t)curTable << (_numMidBits + 3); + buf2 = (Byte *)_table + tableOffset; + curTable++; + if (openCallback && (tableOffset & 0xFFFFF) == 0) + { + const UInt64 numBytes = tableOffset; + RINOK(openCallback->SetCompleted(NULL, &numBytes)) + } + RINOK(InStream_SeekSet(stream, v)) + RINOK(ReadStream_FALSE(stream, buf2, midSize)) + } + + for (size_t k = 0; k < midSize; k += 8) + { + const UInt64 v = Get64((const Byte *)buf2 + (size_t)k); + if (v == 0) + continue; + UInt64 offset = v & offsetMask; + size_t dataSize = clusterSize; + + if (v & _compressedFlag) + { + if (_version <= 1) + { + const unsigned numOffsetBits = 63 - _clusterBits; + dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; + offset &= ((UInt64)1 << numOffsetBits) - 1; + dataSize = 0; // why ? + // offset &= ~(((UInt64)1 << 9) - 1); + } + else + { + const unsigned numOffsetBits = 62 - (_clusterBits - 8); + dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9; + offset &= ((UInt64)1 << numOffsetBits) - (1 << 9); + } + _needCompression = true; + } + else + { + const UInt32 low = (UInt32)v & 511; + if (low) + { + // version_3 supports zero clusters + if (_version < 3 || low != 1) + { + _unsupported = true; + return S_FALSE; + } + } + } + + const UInt64 end = offset + dataSize; + if (_phySize < end) + _phySize = end; + } + } + + if (curTable != numTables) + return E_FAIL; + + if (_cryptMethod) + _unsupported = true; + if (_needCompression && _version <= 1) // that case was not implemented + _unsupported = true; + if (_compressionType) + _unsupported = true; + + Stream = stream; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _table.Free(); + _dir.Free(); + // _cache.Free(); + // _cacheCompressed.Free(); + _phySize = 0; + + _cacheCluster = (UInt64)(Int64)-1; + _comprPos = 0; + _comprSize = 0; + + _needCompression = false; + _isArc = false; + _unsupported = false; + + _compressionType = 0; + _incompatFlags = 0; + + // CHandlerImg: + Clear_HandlerImg_Vars(); + Stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + if (_unsupported || !Stream) + return S_FALSE; + if (_needCompression) + { + if (_version <= 1 || _compressionType) + return S_FALSE; + _bufInStream.Create_if_Empty(); + _bufOutStream.Create_if_Empty(); + _deflateDecoder.Create_if_Empty(); + _deflateDecoder->Set_NeedFinishInput(true); + const size_t clusterSize = (size_t)1 << _clusterBits; + _cache.AllocAtLeast(clusterSize); + _cacheCompressed.AllocAtLeast(clusterSize * 2); + } + CMyComPtr streamTemp = this; + RINOK(InitAndSeek()) + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + +REGISTER_ARC_I( + "QCOW", "qcow qcow2 qcow2c", NULL, 0xCA, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/Rar5Handler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/Rar5Handler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.cpp 2025-06-18 07:00:00.000000000 +0000 @@ -1,2746 +1,3474 @@ -// Rar5Handler.cpp - -#include "StdAfx.h" - -#include "../../../../C/7zCrc.h" -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/PropVariantUtils.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../IPassword.h" - -#include "../../Common/FilterCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/RegisterArc.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "../../Common/RegisterCodec.h" - -#include "../../Compress/CopyCoder.h" - -#include "../../Crypto/Rar5Aes.h" - -#include "../Common/FindSignature.h" -#include "../Common/ItemNameUtils.h" - -#include "../HandlerCont.h" - -#include "RarVol.h" -#include "Rar5Handler.h" - -using namespace NWindows; - -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NRar5 { - -static const unsigned kMarkerSize = 8; - -#define SIGNATURE { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0 } - -static const Byte kMarker[kMarkerSize] = SIGNATURE; - -static const size_t kCommentSize_Max = (size_t)1 << 16; - -static const char * const kHostOS[] = -{ - "Windows" - , "Unix" -}; - -static const CUInt32PCharPair k_ArcFlags[] = -{ - { 0, "Volume" }, - { 1, "VolumeField" }, - { 2, "Solid" }, - { 3, "Recovery" }, - { 4, "Lock" } -}; - - - -template -struct CAlignedBuffer -{ - Byte *_buf; - Byte *_bufBase; - size_t _size; - - CAlignedBuffer(): _buf(NULL), _bufBase(NULL), _size(0) {} - ~CAlignedBuffer() { ::MyFree(_bufBase); } -public: - operator Byte *() { return _buf; } - operator const Byte *() const { return _buf; } - - void AllocAtLeast(size_t size) - { - if (_buf && _size >= size) - return; - ::MyFree(_bufBase); - _buf = NULL; - _size = 0; - _bufBase = (Byte *)::MyAlloc(size + alignMask); - - if (_bufBase) - { - _size = size; - // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - } - } -}; - -static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val) -{ - *val = 0; - - for (unsigned i = 0; i < maxSize;) - { - Byte b = p[i]; - if (i < 10) - *val |= (UInt64)(b & 0x7F) << (7 * i++); - if ((b & 0x80) == 0) - return i; - } - return 0; -} - - -int CItem::FindExtra(unsigned type, unsigned &recordDataSize) const -{ - recordDataSize = 0; - size_t offset = 0; - - for (;;) - { - size_t rem = Extra.Size() - offset; - if (rem == 0) - return -1; - - { - UInt64 size; - unsigned num = ReadVarInt(Extra + offset, rem, &size); - if (num == 0) - return -1; - offset += num; - rem -= num; - if (size > rem) - return -1; - rem = (size_t)size; - } - { - UInt64 type2; - unsigned num = ReadVarInt(Extra + offset, rem, &type2); - if (num == 0) - return -1; - offset += num; - rem -= num; - - // There was BUG in RAR 5.21- : it stored (size-1) instead of (size) - // for Subdata record in Service header. - // That record always was last in bad archives, so we can fix that case. - if (type2 == NExtraRecordType::kSubdata - && RecordType == NHeaderType::kService - && rem + 1 == Extra.Size() - offset) - rem++; - - if (type2 == type) - { - recordDataSize = (unsigned)rem; - return (int)offset; - } - - offset += rem; - } - } -} - - -bool CCryptoInfo::Parse(const Byte *p, size_t size) -{ - unsigned num = ReadVarInt(p, size, &Algo); - if (num == 0) return false; p += num; size -= num; - - num = ReadVarInt(p, size, &Flags); - if (num == 0) return false; p += num; size -= num; - - if (size != 1 + 16 + 16 + (unsigned)(IsThereCheck() ? 12 : 0)) - return false; - - Cnt = p[0]; - - return true; -} - - -bool CItem::FindExtra_Version(UInt64 &version) const -{ - unsigned size; - int offset = FindExtra(NExtraRecordType::kVersion, size); - if (offset < 0) - return false; - const Byte *p = Extra + (unsigned)offset; - - UInt64 flags; - unsigned num = ReadVarInt(p, size, &flags); - if (num == 0) return false; p += num; size -= num; - - num = ReadVarInt(p, size, &version); - if (num == 0) return false; p += num; size -= num; - - return size == 0; -} - -bool CItem::FindExtra_Link(CLinkInfo &link) const -{ - unsigned size; - int offset = FindExtra(NExtraRecordType::kLink, size); - if (offset < 0) - return false; - const Byte *p = Extra + (unsigned)offset; - - unsigned num = ReadVarInt(p, size, &link.Type); - if (num == 0) return false; p += num; size -= num; - - num = ReadVarInt(p, size, &link.Flags); - if (num == 0) return false; p += num; size -= num; - - UInt64 len; - num = ReadVarInt(p, size, &len); - if (num == 0) return false; p += num; size -= num; - - if (size != len) - return false; - - link.NameLen = (unsigned)len; - link.NameOffset = (unsigned)(p - Extra); - return true; -} - -bool CItem::Is_CopyLink() const -{ - CLinkInfo link; - return FindExtra_Link(link) && link.Type == NLinkType::kFileCopy; -} - -void CItem::Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const -{ - CLinkInfo link; - if (!FindExtra_Link(link)) - return; - - if (link.Type != linkType) - { - if (linkType != NLinkType::kUnixSymLink) - return; - switch ((unsigned)link.Type) - { - case NLinkType::kUnixSymLink: - case NLinkType::kWinSymLink: - case NLinkType::kWinJunction: - break; - default: return; - } - } - - AString s; - s.SetFrom_CalcLen((const char *)(Extra + link.NameOffset), link.NameLen); - - UString unicode; - if (ConvertUTF8ToUnicode(s, unicode)) - prop = NItemName::GetOSName(unicode); -} - -bool CItem::GetAltStreamName(AString &name) const -{ - name.Empty(); - unsigned size; - int offset = FindExtra(NExtraRecordType::kSubdata, size); - if (offset < 0) - return false; - name.SetFrom_CalcLen((const char *)(Extra + (unsigned)offset), size); - return true; -} - - -class CHash -{ - bool _calcCRC; - UInt32 _crc; - int _blakeOffset; - CBlake2sp _blake; -public: - - void Init_NoCalc() - { - _calcCRC = false; - _crc = CRC_INIT_VAL; - _blakeOffset = -1; - } - - void Init(const CItem &item); - void Update(const void *data, size_t size); - UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } - - bool Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoderSpec); -}; - -void CHash::Init(const CItem &item) -{ - _crc = CRC_INIT_VAL; - _calcCRC = item.Has_CRC(); - - _blakeOffset = item.FindExtra_Blake(); - if (_blakeOffset >= 0) - Blake2sp_Init(&_blake); -} - -void CHash::Update(const void *data, size_t size) -{ - if (_calcCRC) - _crc = CrcUpdate(_crc, data, size); - if (_blakeOffset >= 0) - Blake2sp_Update(&_blake, (const Byte *)data, size); -} - -bool CHash::Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoderSpec) -{ - if (_calcCRC) - { - UInt32 crc = GetCRC(); - if (cryptoDecoderSpec) - crc = cryptoDecoderSpec->Hmac_Convert_Crc32(crc); - if (crc != item.CRC) - return false; - } - - if (_blakeOffset >= 0) - { - Byte digest[BLAKE2S_DIGEST_SIZE]; - Blake2sp_Final(&_blake, digest); - if (cryptoDecoderSpec) - cryptoDecoderSpec->Hmac_Convert_32Bytes(digest); - if (memcmp(digest, &item.Extra[(unsigned)_blakeOffset], BLAKE2S_DIGEST_SIZE) != 0) - return false; - } - - return true; -} - - -class COutStreamWithHash: - public ISequentialOutStream, - public CMyUnknownImp -{ - ISequentialOutStream *_stream; - UInt64 _pos; - UInt64 _size; - bool _size_Defined; - Byte *_destBuf; -public: - CHash _hash; - - COutStreamWithHash(): _destBuf(NULL) {} - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void Init(const CItem &item, Byte *destBuf) - { - _size_Defined = false; - _size = 0; - _destBuf = NULL; - if (!item.Is_UnknownSize()) - { - _size_Defined = true; - _size = item.Size; - _destBuf = destBuf; - } - _pos = 0; - _hash.Init(item); - } - UInt64 GetPos() const { return _pos; } -}; - - -STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_size_Defined) - { - UInt64 rem = _size - _pos; - if (size > rem) - size = (UInt32)rem; - } - if (_stream) - result = _stream->Write(data, size, &size); - if (_destBuf) - memcpy(_destBuf + (size_t)_pos, data, size); - _hash.Update(data, size); - _pos += size; - if (processedSize) - *processedSize = size; - return result; -} - - - - - -class CInArchive -{ - CAlignedBuffer _buf; - size_t _bufSize; - size_t _bufPos; - ISequentialInStream *_stream; - - NCrypto::NRar5::CDecoder *m_CryptoDecoderSpec; - CMyComPtr m_CryptoDecoder; - - - - HRESULT ReadStream_Check(void *data, size_t size); - -public: - bool m_CryptoMode; - - bool WrongPassword; - bool IsArc; - bool UnexpectedEnd; - - UInt64 StreamStartPosition; - UInt64 Position; - - bool ReadVar(UInt64 &val); - - struct CHeader - { - UInt64 Type; - UInt64 Flags; - size_t ExtraSize; - UInt64 DataSize; - }; - - HRESULT ReadBlockHeader(CHeader &h); - bool ReadFileHeader(const CHeader &header, CItem &item); - void AddToSeekValue(UInt64 addValue) - { - Position += addValue; - } - - HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, ICryptoGetTextPassword *getTextPassword, - CInArcInfo &info); -}; - - -static HRESULT MySetPassword(ICryptoGetTextPassword *getTextPassword, NCrypto::NRar5::CDecoder *cryptoDecoderSpec) -{ - CMyComBSTR password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); - AString utf8; - const unsigned kPasswordLen_MAX = 127; - UString unicode = (LPCOLESTR)password; - if (unicode.Len() > kPasswordLen_MAX) - unicode.DeleteFrom(kPasswordLen_MAX); - ConvertUnicodeToUTF8(unicode, utf8); - cryptoDecoderSpec->SetPassword((const Byte *)(const char *)utf8, utf8.Len()); - return S_OK; -} - - -bool CInArchive::ReadVar(UInt64 &val) -{ - unsigned offset = ReadVarInt(_buf + _bufPos, _bufSize - _bufPos, &val); - _bufPos += offset; - return (offset != 0); -} - - -HRESULT CInArchive::ReadStream_Check(void *data, size_t size) -{ - size_t size2 = size; - RINOK(ReadStream(_stream, data, &size2)); - if (size2 == size) - return S_OK; - UnexpectedEnd = true; - return S_FALSE; -} - - -HRESULT CInArchive::ReadBlockHeader(CHeader &h) -{ - h.Type = 0; - h.Flags = 0; - h.ExtraSize = 0; - h.DataSize = 0; - - const unsigned kStartSize = 4 + 3; - const unsigned kBufSize = AES_BLOCK_SIZE + AES_BLOCK_SIZE; // must be >= kStartSize; - Byte buf[kBufSize]; - unsigned filled; - - if (m_CryptoMode) - { - RINOK(ReadStream_Check(buf, kBufSize)); - memcpy(m_CryptoDecoderSpec->_iv, buf, AES_BLOCK_SIZE); - RINOK(m_CryptoDecoderSpec->Init()); - - _buf.AllocAtLeast(1 << 12); - if (!(Byte *)_buf) - return E_OUTOFMEMORY; - - memcpy(_buf, buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); - if (m_CryptoDecoderSpec->Filter(_buf, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) - return E_FAIL; - memcpy(buf, _buf, AES_BLOCK_SIZE); - filled = AES_BLOCK_SIZE; - } - else - { - RINOK(ReadStream_Check(buf, kStartSize)); - filled = kStartSize; - } - - UInt64 val; - unsigned offset = ReadVarInt(buf + 4, 3, &val); - if (offset == 0) - return S_FALSE; - { - size_t size = (size_t)val; - _bufPos = (4 + offset); - _bufSize = _bufPos + size; - if (size < 2) - return S_FALSE; - } - - size_t allocSize = _bufSize; - if (m_CryptoMode) - allocSize = (allocSize + AES_BLOCK_SIZE - 1) & ~(size_t)(AES_BLOCK_SIZE - 1); - _buf.AllocAtLeast(allocSize); - if (!(Byte *)_buf) - return E_OUTOFMEMORY; - - memcpy(_buf, buf, filled); - - size_t rem = allocSize - filled; - AddToSeekValue(allocSize + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); - RINOK(ReadStream_Check(_buf + filled, rem)); - if (m_CryptoMode) - { - if (m_CryptoDecoderSpec->Filter(_buf + filled, (UInt32)rem) != rem) - return E_FAIL; - } - - if (CrcCalc(_buf + 4, _bufSize - 4) != Get32(buf)) - return S_FALSE; - - if (!ReadVar(h.Type)) return S_FALSE; - if (!ReadVar(h.Flags)) return S_FALSE; - - if (h.Flags & NHeaderFlags::kExtra) - { - UInt64 extraSize; - if (!ReadVar(extraSize)) - return S_FALSE; - if (extraSize > _bufSize) - return S_FALSE; - h.ExtraSize = (size_t)extraSize; - } - - if (h.Flags & NHeaderFlags::kData) - { - if (!ReadVar(h.DataSize)) - return S_FALSE; - } - - return S_OK; -} - - -/* -int CInArcInfo::FindExtra(unsigned type, unsigned &recordDataSize) const -{ - recordDataSize = 0; - size_t offset = 0; - - for (;;) - { - size_t rem = Extra.Size() - offset; - if (rem == 0) - return -1; - - { - UInt64 size; - unsigned num = ReadVarInt(Extra + offset, rem, &size); - if (num == 0) - return -1; - offset += num; - rem -= num; - if (size > rem) - return -1; - rem = (size_t)size; - } - { - UInt64 type2; - unsigned num = ReadVarInt(Extra + offset, rem, &type2); - if (num == 0) - return -1; - offset += num; - rem -= num; - - if (type2 == type) - { - recordDataSize = (unsigned)rem; - return (int)offset; - } - - offset += rem; - } - } -} - - -bool CInArcInfo::FindExtra_Locator(CLocator &locator) const -{ - locator.Flags = 0; - locator.QuickOpen = 0; - locator.Recovery = 0; - - unsigned size; - int offset = FindExtra(kArcExtraRecordType_Locator, size); - if (offset < 0) - return false; - const Byte *p = Extra + (unsigned)offset; - - unsigned num; - - num = ReadVarInt(p, size, &locator.Flags); - if (num == 0) return false; p += num; size -= num; - - if (locator.Is_QuickOpen()) - { - num = ReadVarInt(p, size, &locator.QuickOpen); - if (num == 0) return false; p += num; size -= num; - } - - if (locator.Is_Recovery()) - { - num = ReadVarInt(p, size, &locator.Recovery); - if (num == 0) return false; p += num; size -= num; - } - - return true; -} -*/ - - -HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit, ICryptoGetTextPassword *getTextPassword, - CInArcInfo &info) -{ - m_CryptoMode = false; - - WrongPassword = false; - IsArc = false; - UnexpectedEnd = false; - - Position = StreamStartPosition; - - UInt64 arcStartPos = StreamStartPosition; - { - Byte marker[kMarkerSize]; - RINOK(ReadStream_FALSE(stream, marker, kMarkerSize)); - if (memcmp(marker, kMarker, kMarkerSize) == 0) - Position += kMarkerSize; - else - { - if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) - return S_FALSE; - RINOK(stream->Seek(StreamStartPosition, STREAM_SEEK_SET, NULL)); - RINOK(FindSignatureInStream(stream, kMarker, kMarkerSize, - searchHeaderSizeLimit, arcStartPos)); - arcStartPos += StreamStartPosition; - Position = arcStartPos + kMarkerSize; - RINOK(stream->Seek(Position, STREAM_SEEK_SET, NULL)); - } - } - - info.StartPos = arcStartPos; - _stream = stream; - - CHeader h; - RINOK(ReadBlockHeader(h)); - info.IsEncrypted = false; - - if (h.Type == NHeaderType::kArcEncrypt) - { - info.IsEncrypted = true; - IsArc = true; - if (!getTextPassword) - return E_NOTIMPL; - - m_CryptoMode = true; - - if (!m_CryptoDecoder) - { - m_CryptoDecoderSpec = new NCrypto::NRar5::CDecoder; - m_CryptoDecoder = m_CryptoDecoderSpec; - } - - RINOK(m_CryptoDecoderSpec->SetDecoderProps( - _buf + _bufPos, (unsigned)(_bufSize - _bufPos), false, false)); - - RINOK(MySetPassword(getTextPassword, m_CryptoDecoderSpec)); - - if (!m_CryptoDecoderSpec->CalcKey_and_CheckPassword()) - { - WrongPassword = True; - return S_FALSE; - } - - RINOK(ReadBlockHeader(h)); - } - - if (h.Type != NHeaderType::kArc) - return S_FALSE; - - IsArc = true; - info.VolNumber = 0; - - if (!ReadVar(info.Flags)) - return S_FALSE; - - if (info.Flags & NArcFlags::kVolNumber) - if (!ReadVar(info.VolNumber)) - return S_FALSE; - - if (h.ExtraSize != 0) - { - if (_bufSize - _bufPos < h.ExtraSize) - return S_FALSE; - /* - info.Extra.Alloc(h.ExtraSize); - memcpy(info.Extra, _buf + _bufPos, h.ExtraSize); - */ - _bufPos += h.ExtraSize; - - /* - CInArcInfo::CLocator locator; - if (info.FindExtra_Locator(locator)) - locator.Flags = locator.Flags; - */ - } - - if (_bufPos != _bufSize) - return S_FALSE; - - return S_OK; -} - - -bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item) -{ - item.UnixMTime = 0; - item.CRC = 0; - item.Flags = 0; - - item.CommonFlags = (UInt32)header.Flags; - item.PackSize = header.DataSize; - - UInt64 flags64; - if (!ReadVar(flags64)) return false; - item.Flags = (UInt32)flags64; - - if (!ReadVar(item.Size)) return false; - - { - UInt64 attrib; - if (!ReadVar(attrib)) return false; - item.Attrib = (UInt32)attrib; - } - - if (item.Has_UnixMTime()) - { - if (_bufSize - _bufPos < 4) - return false; - item.UnixMTime = Get32(_buf + _bufPos); - _bufPos += 4; - } - - if (item.Has_CRC()) - { - if (_bufSize - _bufPos < 4) - return false; - item.CRC = Get32(_buf + _bufPos); - _bufPos += 4; - } - - { - UInt64 method; - if (!ReadVar(method)) return false; - item.Method = (UInt32)method; - } - - if (!ReadVar(item.HostOS)) return false; - - { - UInt64 len; - if (!ReadVar(len)) return false; - if (len > _bufSize - _bufPos) - return false; - item.Name.SetFrom_CalcLen((const char *)(_buf + _bufPos), (unsigned)len); - _bufPos += (unsigned)len; - } - - item.Extra.Free(); - size_t extraSize = header.ExtraSize; - if (extraSize != 0) - { - if (_bufSize - _bufPos < extraSize) - return false; - item.Extra.Alloc(extraSize); - memcpy(item.Extra, _buf + _bufPos, extraSize); - _bufPos += extraSize; - } - - - return (_bufPos == _bufSize); -} - - - -struct CLinkFile -{ - unsigned Index; - unsigned NumLinks; - CByteBuffer Data; - HRESULT Res; - bool crcOK; - - CLinkFile(): Index(0), NumLinks(0), Res(S_OK), crcOK(true) {} -}; - - -struct CUnpacker -{ - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr copyCoder; - - CMyComPtr LzCoders[2]; - bool NeedClearSolid[2]; - - CFilterCoder *filterStreamSpec; - CMyComPtr filterStream; - - NCrypto::NRar5::CDecoder *cryptoDecoderSpec; - CMyComPtr cryptoDecoder; - - CMyComPtr getTextPassword; - - COutStreamWithHash *outStreamSpec; - CMyComPtr outStream; - - CByteBuffer _tempBuf; - - CLinkFile *linkFile; - - CUnpacker(): linkFile(NULL) { NeedClearSolid[0] = NeedClearSolid[1] = true; } - - HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword); - - HRESULT Code(const CItem &item, const CItem &lastItem, UInt64 packSize, - ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress, - bool &isCrcOK); - - HRESULT DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer); -}; - - -static const unsigned kLzMethodMax = 5; - -HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword) -{ - wrongPassword = false; - - if (item.GetAlgoVersion() != 0) - return E_NOTIMPL; - - if (!outStream) - { - outStreamSpec = new COutStreamWithHash; - outStream = outStreamSpec; - } - - unsigned method = item.GetMethod(); - - if (method == 0) - { - if (!copyCoder) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } - } - else - { - if (method > kLzMethodMax) - return E_NOTIMPL; - - /* - if (item.IsSplitBefore()) - return S_FALSE; - */ - - int lzIndex = item.IsService() ? 1 : 0; - CMyComPtr &lzCoder = LzCoders[lzIndex]; - - if (!lzCoder) - { - const UInt32 methodID = 0x40305; - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder)); - if (!lzCoder) - return E_NOTIMPL; - } - - CMyComPtr csdp; - RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)); - - Byte props[2] = { (Byte)(item.GetDictSize()), (Byte)(isSolid ? 1 : 0) }; - RINOK(csdp->SetDecoderProperties2(props, 2)); - } - - unsigned cryptoSize = 0; - int cryptoOffset = item.FindExtra(NExtraRecordType::kCrypto, cryptoSize); - - if (cryptoOffset >= 0) - { - if (!filterStream) - { - filterStreamSpec = new CFilterCoder(false); - filterStream = filterStreamSpec; - } - - if (!cryptoDecoder) - { - cryptoDecoderSpec = new NCrypto::NRar5::CDecoder; - cryptoDecoder = cryptoDecoderSpec; - } - - RINOK(cryptoDecoderSpec->SetDecoderProps(item.Extra + (unsigned)cryptoOffset, cryptoSize, true, item.IsService())); - - if (!getTextPassword) - { - wrongPassword = True; - return E_NOTIMPL; - } - - RINOK(MySetPassword(getTextPassword, cryptoDecoderSpec)); - - if (!cryptoDecoderSpec->CalcKey_and_CheckPassword()) - wrongPassword = True; - } - - return S_OK; -} - - -HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSize, - ISequentialInStream *volsInStream, ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, - bool &isCrcOK) -{ - isCrcOK = true; - - unsigned method = item.GetMethod(); - if (method > kLzMethodMax) - return E_NOTIMPL; - - if (linkFile && !lastItem.Is_UnknownSize()) - { - size_t dataSize = (size_t)lastItem.Size; - if (dataSize != lastItem.Size) - return E_NOTIMPL; - linkFile->Data.Alloc(dataSize); - } - - bool isCryptoMode = false; - ISequentialInStream *inStream; - - if (item.IsEncrypted()) - { - filterStreamSpec->Filter = cryptoDecoder; - filterStreamSpec->SetInStream(volsInStream); - filterStreamSpec->SetOutStreamSize(NULL); - inStream = filterStream; - isCryptoMode = true; - } - else - inStream = volsInStream; - - ICompressCoder *commonCoder = (method == 0) ? copyCoder : LzCoders[item.IsService() ? 1 : 0]; - - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(lastItem, (linkFile ? (Byte *)linkFile->Data : NULL)); - - NeedClearSolid[item.IsService() ? 1 : 0] = false; - - HRESULT res = S_OK; - if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0) - { - res = commonCoder->Code(inStream, outStream, &packSize, - lastItem.Is_UnknownSize() ? NULL : &lastItem.Size, progress); - } - else - { - res = res; - } - - if (isCryptoMode) - filterStreamSpec->ReleaseInStream(); - - UInt64 processedSize = outStreamSpec->GetPos(); - if (res == S_OK && !lastItem.Is_UnknownSize() && processedSize != lastItem.Size) - res = S_FALSE; - - // if (res == S_OK) - { - unsigned cryptoSize = 0; - int cryptoOffset = lastItem.FindExtra(NExtraRecordType::kCrypto, cryptoSize); - NCrypto::NRar5::CDecoder *crypto = NULL; - - if (cryptoOffset >= 0) - { - CCryptoInfo cryptoInfo; - if (cryptoInfo.Parse(lastItem.Extra + (unsigned)cryptoOffset, cryptoSize)) - if (cryptoInfo.UseMAC()) - crypto = cryptoDecoderSpec; - } - - isCrcOK = outStreamSpec->_hash.Check(lastItem, crypto); - } - - if (linkFile) - { - linkFile->Res = res; - linkFile->crcOK = isCrcOK; - if (!lastItem.Is_UnknownSize() && processedSize != lastItem.Size) - linkFile->Data.ChangeSize_KeepData((size_t)processedSize, (size_t)processedSize); - } - - return res; -} - - -HRESULT CUnpacker::DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer) -{ - CBufPtrSeqOutStream *outSpec = new CBufPtrSeqOutStream; - CMyComPtr out = outSpec; - _tempBuf.AllocAtLeast((size_t)item.Size); - outSpec->Init(_tempBuf, (size_t)item.Size); - - bool wrongPassword; - - if (item.IsSolid()) - return E_NOTIMPL; - - HRESULT res = Create(EXTERNAL_CODECS_LOC_VARS item, item.IsSolid(), wrongPassword); - - if (res == S_OK) - { - if (wrongPassword) - return S_FALSE; - - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; - CMyComPtr limitedStream(limitedStreamSpec); - limitedStreamSpec->SetStream(inStream); - limitedStreamSpec->Init(packSize); - - bool crcOK = true; - res = Code(item, item, packSize, limitedStream, out, NULL, crcOK); - if (res == S_OK) - { - if (!crcOK || outSpec->GetPos() != item.Size) - res = S_FALSE; - else - buffer.CopyFrom(_tempBuf, (size_t)item.Size); - } - } - - return res; -} - - -struct CTempBuf -{ - CByteBuffer _buf; - size_t _offset; - bool _isOK; - - void Clear() - { - _offset = 0; - _isOK = true; - } - - CTempBuf() { Clear(); } - - HRESULT Decode(DECL_EXTERNAL_CODECS_LOC_VARS - const CItem &item, - ISequentialInStream *inStream, CUnpacker &unpacker, CByteBuffer &destBuf); -}; - - -HRESULT CTempBuf::Decode(DECL_EXTERNAL_CODECS_LOC_VARS - const CItem &item, - ISequentialInStream *inStream, - CUnpacker &unpacker, - CByteBuffer &destBuf) -{ - const size_t kPackSize_Max = (1 << 24); - if (item.Size > (1 << 24) - || item.Size == 0 - || item.PackSize >= kPackSize_Max) - { - Clear(); - return S_OK; - } - - if (item.IsSplit() /* && _isOK */) - { - size_t packSize = (size_t)item.PackSize; - if (packSize > kPackSize_Max - _offset) - return S_OK; - size_t newSize = _offset + packSize; - if (newSize > _buf.Size()) - _buf.ChangeSize_KeepData(newSize, _offset); - - Byte *data = (Byte *)_buf + _offset; - RINOK(ReadStream_FALSE(inStream, data, packSize)); - - _offset += packSize; - - if (item.IsSplitAfter()) - { - CHash hash; - hash.Init(item); - hash.Update(data, packSize); - _isOK = hash.Check(item, NULL); // RAR5 doesn't use HMAC for packed part - } - } - - if (_isOK) - { - if (!item.IsSplitAfter()) - { - if (_offset == 0) - { - RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS - item, item.PackSize, inStream, destBuf)); - } - else - { - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - bufInStreamSpec->Init(_buf, _offset); - RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS - item, _offset, bufInStream, destBuf)); - } - } - } - - return S_OK; -} - - - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - - kpidIsAltStream, - kpidEncrypted, - kpidSolid, - kpidSplitBefore, - kpidSplitAfter, - kpidCRC, - kpidHostOS, - kpidMethod, - - kpidSymLink, - kpidHardLink, - kpidCopyLink, -}; - - -static const Byte kArcProps[] = -{ - kpidTotalPhySize, - kpidCharacts, - kpidSolid, - kpidNumBlocks, - kpidEncrypted, - kpidIsVolume, - kpidVolumeIndex, - kpidNumVolumes, - kpidComment -}; - - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - - -UInt64 CHandler::GetPackSize(unsigned refIndex) const -{ - UInt64 size = 0; - unsigned index = _refs[refIndex].Item; - for (;;) - { - const CItem &item = _items[index]; - size += item.PackSize; - if (item.NextItem < 0) - return size; - index = item.NextItem; - } -} - - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - - NCOM::CPropVariant prop; - - const CInArcInfo *arcInfo = NULL; - if (!_arcs.IsEmpty()) - arcInfo = &_arcs[0].Info; - - switch (propID) - { - case kpidVolumeIndex: if (arcInfo && arcInfo->IsVolume()) prop = arcInfo->GetVolIndex(); break; - case kpidSolid: if (arcInfo) prop = arcInfo->IsSolid(); break; - case kpidCharacts: - { - if (!_arcs.IsEmpty()) - { - FLAGS_TO_PROP(k_ArcFlags, (UInt32)arcInfo->Flags, prop); - } - break; - } - case kpidEncrypted: if (arcInfo) prop = arcInfo->IsEncrypted; break; // it's for encrypted names. - case kpidIsVolume: if (arcInfo) prop = arcInfo->IsVolume(); break; - case kpidNumVolumes: prop = (UInt32)_arcs.Size(); break; - case kpidOffset: if (arcInfo && arcInfo->StartPos != 0) prop = arcInfo->StartPos; break; - - case kpidTotalPhySize: - { - if (_arcs.Size() > 1) - { - UInt64 sum = 0; - FOR_VECTOR (v, _arcs) - sum += _arcs[v].Info.GetPhySize(); - prop = sum; - } - break; - } - - case kpidPhySize: - { - if (arcInfo) - prop = arcInfo->GetPhySize(); - break; - } - - case kpidComment: - { - // if (!_arcs.IsEmpty()) - { - // const CArc &arc = _arcs[0]; - const CByteBuffer &cmt = _comment; - if (cmt.Size() != 0 && cmt.Size() < (1 << 16)) - { - AString s; - s.SetFrom_CalcLen((const char *)(const Byte *)cmt, (unsigned)cmt.Size()); - UString unicode; - if (ConvertUTF8ToUnicode(s, unicode)) - prop = unicode; - } - } - break; - } - - case kpidNumBlocks: - { - UInt32 numBlocks = 0; - FOR_VECTOR (i, _refs) - if (!_items[_refs[i].Item].IsSolid()) - numBlocks++; - prop = (UInt32)numBlocks; - break; - } - - case kpidError: - { - if (/* &_missingVol || */ !_missingVolName.IsEmpty()) - { - UString s; - s.SetFromAscii("Missing volume : "); - s += _missingVolName; - prop = s; - } - break; - } - - case kpidErrorFlags: - { - UInt32 v = _errorFlags; - if (!_isArc) - v |= kpv_ErrorFlags_IsNotArc; - prop = v; - break; - } - - /* - case kpidWarningFlags: - { - if (_warningFlags != 0) - prop = _warningFlags; - break; - } - */ - - case kpidExtension: - if (_arcs.Size() == 1) - { - if (arcInfo->IsVolume()) - { - char sz[32]; - ConvertUInt64ToString(arcInfo->GetVolIndex() + 1, sz); - unsigned len = MyStringLen(sz); - AString s = "part"; - for (; len < 2; len++) - s += '0'; - s += sz; - s += ".rar"; - prop = s; - } - } - break; - - case kpidIsAltStream: prop = true; break; - } - - prop.Detach(value); - return S_OK; - - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _refs.Size(); - return S_OK; -} - - -static const Byte kRawProps[] = -{ - kpidChecksum, - kpidNtSecure -}; - - -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) -{ - *numProps = ARRAY_SIZE(kRawProps); - return S_OK; -} - -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) -{ - *propID = kRawProps[index]; - *name = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) -{ - *parentType = NParentType::kDir; - *parent = (UInt32)(Int32)-1; - - if (index >= _refs.Size()) - return S_OK; - - const CRefItem &ref = _refs[index]; - const CItem &item = _items[ref.Item]; - - if (item.Is_STM() && ref.Parent >= 0) - { - *parent = (UInt32)ref.Parent; - *parentType = NParentType::kAltStream; - } - - return S_OK; -} - - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - if (index >= _refs.Size()) - return E_INVALIDARG; - - const CItem &item = _items[_refs[index].Item]; - - if (propID == kpidNtSecure) - { - if (item.ACL >= 0) - { - const CByteBuffer &buf = _acls[item.ACL]; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kRaw; - *data = (const Byte *)buf; - } - return S_OK; - } - - if (propID == kpidChecksum) - { - int hashRecOffset = item.FindExtra_Blake(); - if (hashRecOffset >= 0) - { - *dataSize = BLAKE2S_DIGEST_SIZE; - *propType = NPropDataType::kRaw; - *data = &item.Extra[hashRecOffset]; - } - return S_OK; - } - - return S_OK; -} - - -static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CPropVariant &prop) -{ - unsigned size; - int offset = item.FindExtra(NExtraRecordType::kTime, size); - if (offset < 0) - return; - - const Byte *p = item.Extra + (unsigned)offset; - UInt64 flags; - { - unsigned num = ReadVarInt(p, size, &flags); - if (num == 0) - return; - p += num; - size -= num; - } - - if ((flags & (NTimeRecord::NFlags::kMTime << stampIndex)) == 0) - return; - - unsigned numStamps = 0; - unsigned i; - for (i = 0; i < 3; i++) - if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0) - numStamps++; - unsigned stampSizeLog = ((flags & NTimeRecord::NFlags::kUnixTime) != 0) ? 2 : 3; - - if ((numStamps << stampSizeLog) != size) - return; - - numStamps = 0; - for (i = 0; i < stampIndex; i++) - if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0) - numStamps++; - - p += (numStamps << stampSizeLog); - - FILETIME ft; - if ((flags & NTimeRecord::NFlags::kUnixTime) != 0) - NWindows::NTime::UnixTimeToFileTime(Get32(p), ft); - else - { - ft.dwLowDateTime = Get32(p); - ft.dwHighDateTime = Get32(p + 4); - } - - prop = ft; -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - - NCOM::CPropVariant prop; - const CRefItem &ref = _refs[index]; - const CItem &item = _items[ref.Item]; - const CItem &lastItem = _items[ref.Last]; - - switch (propID) - { - case kpidPath: - { - UString unicodeName; - - if (item.Is_STM()) - { - AString s; - if (ref.Parent >= 0) - { - CItem &mainItem = _items[_refs[ref.Parent].Item]; - s = mainItem.Name; - } - - AString name; - item.GetAltStreamName(name); - if (name[0] != ':') - s += ':'; - s += name; - if (!ConvertUTF8ToUnicode(s, unicodeName)) - break; - } - else - { - if (!ConvertUTF8ToUnicode(item.Name, unicodeName)) - break; - if (item.Version_Defined) - { - wchar_t temp[32]; - // temp[0] = ';'; - // ConvertUInt64ToString(item.Version, temp + 1); - // unicodeName += temp; - ConvertUInt64ToString(item.Version, temp); - UString s2 = L"[VER]" WSTRING_PATH_SEPARATOR; - s2 += temp; - s2.Add_PathSepar(); - unicodeName.Insert(0, s2); - } - } - - NItemName::ConvertToOSName2(unicodeName); - prop = unicodeName; - - break; - } - - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: if (!lastItem.Is_UnknownSize()) prop = lastItem.Size; break; - case kpidPackSize: prop = GetPackSize(index); break; - - case kpidMTime: - { - 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; - } - 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; - } - } - break; - } - case kpidCTime: TimeRecordToProp(item, NTimeRecord::k_Index_CTime, prop); break; - case kpidATime: TimeRecordToProp(item, NTimeRecord::k_Index_ATime, prop); break; - - case kpidName: - { - if (item.Is_STM()) - { - AString name; - item.GetAltStreamName(name); - if (name[0] == ':') - { - name.DeleteFrontal(1); - UString unicodeName; - if (ConvertUTF8ToUnicode(name, unicodeName)) - prop = unicodeName; - } - } - break; - } - - case kpidIsAltStream: prop = item.Is_STM(); break; - - case kpidSymLink: item.Link_to_Prop(NLinkType::kUnixSymLink, prop); break; - case kpidHardLink: item.Link_to_Prop(NLinkType::kHardLink, prop); break; - case kpidCopyLink: item.Link_to_Prop(NLinkType::kFileCopy, prop); break; - - case kpidAttrib: prop = item.GetWinAttrib(); break; - case kpidEncrypted: prop = item.IsEncrypted(); break; - case kpidSolid: prop = item.IsSolid(); break; - - case kpidSplitBefore: prop = item.IsSplitBefore(); break; - case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break; - case kpidCRC: - { - const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem); - if (item2->Has_CRC()) - prop = item2->CRC; - break; - } - - case kpidMethod: - { - char temp[64]; - unsigned algo = item.GetAlgoVersion(); - char *s = temp; - if (algo != 0) - { - ConvertUInt32ToString(algo, s); - s += MyStringLen(s); - *s++ = ':'; - } - unsigned m = item.GetMethod(); - { - s[0] = 'm'; - s[1] = (char)(m + '0'); - s[2] = 0; - if (!item.IsDir()) - { - s[2] = ':'; - ConvertUInt32ToString(item.GetDictSize() + 17, s + 3); - } - } - - unsigned cryptoSize = 0; - int cryptoOffset = item.FindExtra(NExtraRecordType::kCrypto, cryptoSize); - if (cryptoOffset >= 0) - { - s = temp + strlen(temp); - *s++ = ' '; - strcpy(s, "AES:"); - CCryptoInfo cryptoInfo; - if (cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize)) - { - s += strlen(s); - ConvertUInt32ToString(cryptoInfo.Cnt, s); - s += strlen(s); - *s++ = ':'; - ConvertUInt64ToString(cryptoInfo.Flags, s); - } - } - - prop = temp; - break; - } - - case kpidHostOS: - if (item.HostOS < ARRAY_SIZE(kHostOS)) - prop = kHostOS[(size_t)item.HostOS]; - else - prop = (UInt64)item.HostOS; - break; - } - - prop.Detach(value); - return S_OK; - - COM_TRY_END -} - - - -// ---------- Copy Links ---------- - -static int CompareItemsPaths(const CHandler &handler, unsigned p1, unsigned p2, const AString *name1) -{ - const CItem &item1 = handler._items[handler._refs[p1].Item]; - const CItem &item2 = handler._items[handler._refs[p2].Item]; - - if (item1.Version_Defined) - { - if (!item2.Version_Defined) - return -1; - int res = MyCompare(item1.Version, item2.Version); - if (res != 0) - return res; - } - else if (item2.Version_Defined) - return 1; - - if (!name1) - name1 = &item1.Name; - return strcmp(*name1, item2.Name); -} - -static int CompareItemsPaths2(const CHandler &handler, unsigned p1, unsigned p2, const AString *name1) -{ - int res = CompareItemsPaths(handler, p1, p2, name1); - if (res != 0) - return res; - return MyCompare(p1, p2); -} - -static int CompareItemsPaths_Sort(const unsigned *p1, const unsigned *p2, void *param) -{ - return CompareItemsPaths2(*(const CHandler *)param, *p1, *p2, NULL); -} - -static int FindLink(const CHandler &handler, const CUIntVector &sorted, - const AString &s, unsigned index) -{ - unsigned left = 0, right = sorted.Size(); - for (;;) - { - if (left == right) - { - if (left > 0) - { - unsigned refIndex = sorted[left - 1]; - if (CompareItemsPaths(handler, index, refIndex, &s) == 0) - return refIndex; - } - if (right < sorted.Size()) - { - unsigned refIndex = sorted[right]; - if (CompareItemsPaths(handler, index, refIndex, &s) == 0) - return refIndex; - } - return -1; - } - - unsigned mid = (left + right) / 2; - unsigned refIndex = sorted[mid]; - int compare = CompareItemsPaths2(handler, index, refIndex, &s); - if (compare == 0) - return refIndex; - if (compare < 0) - right = mid; - else - left = mid + 1; - } -} - -void CHandler::FillLinks() -{ - unsigned i; - - for (i = 0; i < _refs.Size(); i++) - { - const CItem &item = _items[_refs[i].Item]; - if (!item.IsDir() && !item.IsService() && item.NeedUse_as_CopyLink()) - break; - } - - if (i == _refs.Size()) - return; - - CUIntVector sorted; - for (i = 0; i < _refs.Size(); i++) - { - const CItem &item = _items[_refs[i].Item]; - if (!item.IsDir() && !item.IsService()) - sorted.Add(i); - } - - if (sorted.IsEmpty()) - return; - - sorted.Sort(CompareItemsPaths_Sort, (void *)this); - - AString link; - - for (i = 0; i < _refs.Size(); i++) - { - CRefItem &ref = _refs[i]; - const CItem &item = _items[ref.Item]; - if (item.IsDir() || item.IsService() || item.PackSize != 0) - continue; - CItem::CLinkInfo linkInfo; - if (!item.FindExtra_Link(linkInfo) || linkInfo.Type != NLinkType::kFileCopy) - continue; - link.SetFrom_CalcLen((const char *)(item.Extra + linkInfo.NameOffset), linkInfo.NameLen); - int linkIndex = FindLink(*this, sorted, link, i); - if (linkIndex < 0) - continue; - if ((unsigned)linkIndex >= i) - continue; // we don't support forward links that can lead to loops - const CRefItem &linkRef = _refs[linkIndex]; - const CItem &linkItem = _items[linkRef.Item]; - if (linkItem.Size == item.Size) - { - if (linkRef.Link >= 0) - ref.Link = linkRef.Link; - else if (!linkItem.NeedUse_as_CopyLink()) - ref.Link = linkIndex; - } - } -} - - - -HRESULT CHandler::Open2(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) -{ - CMyComPtr openVolumeCallback; - CMyComPtr getTextPassword; - - NRar::CVolumeName seqName; - - UInt64 totalBytes = 0; - UInt64 curBytes = 0; - - if (openCallback) - { - openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); - } - - CTempBuf tempBuf; - - CUnpacker unpacker; - unpacker.getTextPassword = getTextPassword; - - int prevSplitFile = -1; - int prevMainFile = -1; - - bool nextVol_is_Required = false; - - CInArchive arch; - - for (;;) - { - CMyComPtr inStream; - - if (_arcs.IsEmpty()) - inStream = stream; - else - { - if (!openVolumeCallback) - break; - - if (_arcs.Size() == 1) - { - UString baseName; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - break; - baseName = prop.bstrVal; - } - if (!seqName.InitName(baseName)) - break; - } - - const UString volName = seqName.GetNextName(); - - HRESULT result = openVolumeCallback->GetStream(volName, &inStream); - - if (result != S_OK && result != S_FALSE) - return result; - - if (!inStream || result != S_OK) - { - if (nextVol_is_Required) - _missingVolName = volName; - break; - } - } - - UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &arch.StreamStartPosition)); - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(arch.StreamStartPosition, STREAM_SEEK_SET, NULL)); - - if (openCallback) - { - totalBytes += endPos; - RINOK(openCallback->SetTotal(NULL, &totalBytes)); - } - - CInArcInfo arcInfoOpen; - { - HRESULT res = arch.Open(inStream, maxCheckStartPosition, getTextPassword, arcInfoOpen); - if (arch.IsArc && arch.UnexpectedEnd) - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - if (_arcs.IsEmpty()) - { - _isArc = arch.IsArc; - } - - if (res != S_OK) - { - if (res != S_FALSE) - return res; - if (_arcs.IsEmpty()) - return res; - break; - } - } - - CArc &arc = _arcs.AddNew(); - CInArcInfo &arcInfo = arc.Info; - arcInfo = arcInfoOpen; - arc.Stream = inStream; - - CItem item; - - for (;;) - { - item.Clear(); - - arcInfo.EndPos = arch.Position; - - if (arch.Position > endPos) - { - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - break; - } - - RINOK(inStream->Seek(arch.Position, STREAM_SEEK_SET, NULL)); - - { - CInArchive::CHeader h; - HRESULT res = arch.ReadBlockHeader(h); - if (res != S_OK) - { - if (res != S_FALSE) - return res; - if (arch.UnexpectedEnd) - { - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - if (arcInfo.EndPos < arch.Position) - arcInfo.EndPos = arch.Position; - if (arcInfo.EndPos < endPos) - arcInfo.EndPos = endPos; - } - else - _errorFlags |= kpv_ErrorFlags_HeadersError; - break; - } - - if (h.Type == NHeaderType::kEndOfArc) - { - arcInfo.EndPos = arch.Position; - arcInfo.EndOfArchive_was_Read = true; - if (!arch.ReadVar(arcInfo.EndFlags)) - _errorFlags |= kpv_ErrorFlags_HeadersError; - if (arcInfo.IsVolume()) - { - // for multivolume archives RAR can add ZERO bytes at the end for alignment. - // We must skip these bytes to prevent phySize warning. - RINOK(inStream->Seek(arcInfo.EndPos, STREAM_SEEK_SET, NULL)); - bool areThereNonZeros; - UInt64 numZeros; - const UInt64 maxSize = 1 << 12; - RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); - if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) - arcInfo.EndPos += numZeros; - } - break; - } - - if (h.Type != NHeaderType::kFile && - h.Type != NHeaderType::kService) - { - _errorFlags |= kpv_ErrorFlags_UnsupportedFeature; - break; - } - - item.RecordType = (Byte)h.Type; - - if (!arch.ReadFileHeader(h, item)) - { - _errorFlags |= kpv_ErrorFlags_HeadersError; - break; - } - - // item.MainPartSize = (UInt32)(Position - item.Position); - item.DataPos = arch.Position; - } - - bool isOk_packSize = true; - { - arcInfo.EndPos = arch.Position; - if (arch.Position + item.PackSize < arch.Position) - { - isOk_packSize = false; - _errorFlags |= kpv_ErrorFlags_HeadersError; - if (arcInfo.EndPos < endPos) - arcInfo.EndPos = endPos; - } - else - { - arch.AddToSeekValue(item.PackSize); // Position points to next header; - arcInfo.EndPos = arch.Position; - } - } - - bool needAdd = true; - - { - if (_comment.Size() == 0 - && item.Is_CMT() - && item.PackSize < kCommentSize_Max - && item.PackSize == item.Size - && item.PackSize != 0 - && item.GetMethod() == 0 - && !item.IsSplit()) - { - RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_VARS item, item.PackSize, inStream, _comment)); - needAdd = false; - } - } - - if (needAdd) - { - CRefItem ref; - ref.Item = _items.Size(); - ref.Last = ref.Item; - ref.Parent = -1; - ref.Link = -1; - - if (item.IsService()) - { - if (item.Is_STM()) - { - if (prevMainFile >= 0) - ref.Parent = prevMainFile; - } - else - { - needAdd = false; - if (item.Is_ACL() && (!item.IsEncrypted() || arch.m_CryptoMode)) - { - if (prevMainFile >= 0 && item.Size < (1 << 24) && item.Size != 0) - { - CItem &mainItem = _items[_refs[prevMainFile].Item]; - - if (mainItem.ACL < 0) - { - CByteBuffer acl; - HRESULT res = tempBuf.Decode(EXTERNAL_CODECS_VARS item, inStream, unpacker, acl); - if (!item.IsSplitAfter()) - tempBuf.Clear(); - if (res != S_OK) - { - tempBuf.Clear(); - if (res != S_FALSE && res != E_NOTIMPL) - return res; - } - // RINOK(); - - if (res == S_OK && acl.Size() != 0) - { - if (_acls.IsEmpty() || acl != _acls.Back()) - _acls.Add(acl); - mainItem.ACL = _acls.Size() - 1; - } - } - } - } - } - } - - if (needAdd) - { - if (item.IsSplitBefore()) - { - if (prevSplitFile >= 0) - { - CRefItem &ref2 = _refs[prevSplitFile]; - CItem &prevItem = _items[ref2.Last]; - if (item.IsNextForItem(prevItem)) - { - ref2.Last = _items.Size(); - prevItem.NextItem = ref2.Last; - needAdd = false; - } - } - } - } - - if (needAdd) - { - if (item.IsSplitAfter()) - prevSplitFile = _refs.Size(); - if (!item.IsService()) - prevMainFile = _refs.Size(); - _refs.Add(ref); - } - } - - { - UInt64 version; - if (item.FindExtra_Version(version)) - { - item.Version_Defined = true; - item.Version = version; - } - } - - item.VolIndex = _arcs.Size() - 1; - _items.Add(item); - - if (openCallback && (_items.Size() & 0xFF) == 0) - { - UInt64 numFiles = _items.Size(); - UInt64 numBytes = curBytes + item.DataPos; - RINOK(openCallback->SetCompleted(&numFiles, &numBytes)); - } - - if (!isOk_packSize) - break; - } - - curBytes += endPos; - - nextVol_is_Required = false; - - if (!arcInfo.IsVolume()) - break; - - if (arcInfo.EndOfArchive_was_Read) - { - if (!arcInfo.AreMoreVolumes()) - break; - nextVol_is_Required = true; - } - } - - FillLinks(); - - return S_OK; -} - - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) -{ - COM_TRY_BEGIN - Close(); - return Open2(stream, maxCheckStartPosition, openCallback); - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - COM_TRY_BEGIN - _missingVolName.Empty(); - _errorFlags = 0; - // _warningFlags = 0; - _isArc = false; - _refs.Clear(); - _items.Clear(); - _arcs.Clear(); - _acls.Clear(); - _comment.Free(); - return S_OK; - COM_TRY_END -} - - -class CVolsInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - UInt64 _rem; - ISequentialInStream *_stream; - const CObjectVector *_arcs; - const CObjectVector *_items; - int _itemIndex; -public: - bool CrcIsOK; -private: - CHash _hash; -public: - MY_UNKNOWN_IMP - void Init(const CObjectVector *arcs, - const CObjectVector *items, - unsigned itemIndex) - { - _arcs = arcs; - _items = items; - _itemIndex = itemIndex; - _stream = NULL; - CrcIsOK = true; - } - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - UInt32 realProcessedSize = 0; - - while (size != 0) - { - if (!_stream) - { - if (_itemIndex < 0) - break; - const CItem &item = (*_items)[_itemIndex]; - IInStream *s = (*_arcs)[item.VolIndex].Stream; - RINOK(s->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - _stream = s; - if (CrcIsOK && item.IsSplitAfter()) - _hash.Init(item); - else - _hash.Init_NoCalc(); - _rem = item.PackSize; - } - { - UInt32 cur = size; - if (cur > _rem) - cur = (UInt32)_rem; - UInt32 num = cur; - HRESULT res = _stream->Read(data, cur, &cur); - _hash.Update(data, cur); - realProcessedSize += cur; - if (processedSize) - *processedSize = realProcessedSize; - data = (Byte *)data + cur; - size -= cur; - _rem -= cur; - if (_rem == 0) - { - const CItem &item = (*_items)[_itemIndex]; - _itemIndex = item.NextItem; - if (!_hash.Check(item, NULL)) // RAR doesn't use MAC here - CrcIsOK = false; - _stream = NULL; - } - if (res != S_OK) - return res; - if (realProcessedSize != 0) - return S_OK; - if (cur == 0 && num != 0) - return S_OK; - } - } - - return S_OK; -} - - -static int FindLinkBuf(CObjectVector &linkFiles, unsigned index) -{ - unsigned left = 0, right = linkFiles.Size(); - for (;;) - { - if (left == right) - return -1; - unsigned mid = (left + right) / 2; - unsigned linkIndex = linkFiles[mid].Index; - if (index == linkIndex) - return mid; - if (index < linkIndex) - right = mid; - else - left = mid + 1; - } -} - - -static inline int DecoderRes_to_OpRes(HRESULT res, bool crcOK) -{ - if (res == E_NOTIMPL) - return NExtract::NOperationResult::kUnsupportedMethod; - // if (res == S_FALSE) - if (res != S_OK) - return NExtract::NOperationResult::kDataError; - return crcOK ? - NExtract::NOperationResult::kOK : - NExtract::NOperationResult::kCRCError; -} - - -static HRESULT CopyData_with_Progress(const Byte *data, size_t size, - ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - size_t pos = 0; - - while (pos < size) - { - const UInt32 kStepSize = ((UInt32)1 << 24); - UInt32 cur32; - { - size_t cur = size - pos; - if (cur > kStepSize) - cur = kStepSize; - cur32 = (UInt32)cur; - } - RINOK(outStream->Write(data + pos, cur32, &cur32)); - if (cur32 == 0) - return E_FAIL; - pos += cur32; - if (progress) - { - UInt64 pos64 = pos; - RINOK(progress->SetRatioInfo(&pos64, &pos64)); - } - } - - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _refs.Size(); - if (numItems == 0) - return S_OK; - - CByteArr extractStatuses(_refs.Size()); - memset(extractStatuses, 0, _refs.Size()); - - // we don't want to use temp buffer for big link files. - const size_t k_CopyLinkFile_MaxSize = (size_t)1 << (28 + sizeof(size_t) / 2); - - const Byte kStatus_Extract = 1 << 0; - const Byte kStatus_Skip = 1 << 1; - const Byte kStatus_Link = 1 << 2; - - CObjectVector linkFiles; - - { - UInt64 total = 0; - bool isThereUndefinedSize = false; - bool thereAreLinks = false; - - { - unsigned solidLimit = 0; - for (UInt32 t = 0; t < numItems; t++) - { - unsigned index = allFilesMode ? t : indices[t]; - const CRefItem &ref = _refs[index]; - const CItem &item = _items[ref.Item]; - const CItem &lastItem = _items[ref.Last]; - - extractStatuses[index] |= kStatus_Extract; - - if (!lastItem.Is_UnknownSize()) - total += lastItem.Size; - else - isThereUndefinedSize = true; - - if (ref.Link >= 0) - { - if (!testMode) - { - if ((unsigned)ref.Link < index) - { - const CRefItem &linkRef = _refs[(unsigned)ref.Link]; - const CItem &linkItem = _items[linkRef.Item]; - if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) - { - if (extractStatuses[(unsigned)ref.Link] == 0) - { - const CItem &lastLinkItem = _items[linkRef.Last]; - if (!lastLinkItem.Is_UnknownSize()) - total += lastLinkItem.Size; - else - isThereUndefinedSize = true; - } - extractStatuses[(unsigned)ref.Link] |= kStatus_Link; - thereAreLinks = true; - } - } - } - continue; - } - - if (item.IsService()) - continue; - - if (item.IsSolid()) - { - unsigned j = index; - - while (j > solidLimit) - { - j--; - const CRefItem &ref2 = _refs[j]; - const CItem &item2 = _items[ref2.Item]; - if (!item2.IsService()) - { - if (extractStatuses[j] == 0) - { - const CItem &lastItem2 = _items[ref2.Last]; - if (!lastItem2.Is_UnknownSize()) - total += lastItem2.Size; - else - isThereUndefinedSize = true; - } - extractStatuses[j] |= kStatus_Skip; - if (!item2.IsSolid()) - break; - } - } - } - - solidLimit = index + 1; - } - } - - if (thereAreLinks) - { - unsigned solidLimit = 0; - - FOR_VECTOR(i, _refs) - { - if ((extractStatuses[i] & kStatus_Link) == 0) - continue; - const CItem &item = _items[_refs[i].Item]; - /* - if (item.IsService()) - continue; - */ - - CLinkFile &linkFile = linkFiles.AddNew(); - linkFile.Index = i; - - if (item.IsSolid()) - { - unsigned j = i; - - while (j > solidLimit) - { - j--; - const CRefItem &ref2 = _refs[j]; - const CItem &item2 = _items[ref2.Item]; - if (!item2.IsService()) - { - if (extractStatuses[j] != 0) - break; - extractStatuses[j] = kStatus_Skip; - { - const CItem &lastItem2 = _items[ref2.Last]; - if (!lastItem2.Is_UnknownSize()) - total += lastItem2.Size; - else - isThereUndefinedSize = true; - } - if (!item2.IsSolid()) - break; - } - } - } - - solidLimit = i + 1; - } - - for (UInt32 t = 0; t < numItems; t++) - { - unsigned index = allFilesMode ? t : indices[t]; - const CRefItem &ref = _refs[index]; - - int linkIndex = ref.Link; - if (linkIndex < 0 || (unsigned)linkIndex >= index) - continue; - const CItem &linkItem = _items[_refs[(unsigned)linkIndex].Item]; - if (!linkItem.IsSolid() || linkItem.Size > k_CopyLinkFile_MaxSize) - continue; - int bufIndex = FindLinkBuf(linkFiles, linkIndex); - if (bufIndex < 0) - return E_FAIL; - linkFiles[bufIndex].NumLinks++; - } - } - - if (total != 0 || !isThereUndefinedSize) - { - RINOK(extractCallback->SetTotal(total)); - } - } - - - UInt64 totalUnpacked = 0; - UInt64 totalPacked = 0; - UInt64 curUnpackSize = 0; - UInt64 curPackSize = 0; - - CUnpacker unpacker; - - CVolsInStream *volsInStreamSpec = new CVolsInStream; - CMyComPtr volsInStream = volsInStreamSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - // bool needClearSolid = true; - - FOR_VECTOR(i, _refs) - { - if (extractStatuses[i] == 0) - continue; - - totalUnpacked += curUnpackSize; - totalPacked += curPackSize; - lps->InSize = totalPacked; - lps->OutSize = totalUnpacked; - RINOK(lps->SetCur()); - - CMyComPtr realOutStream; - - Int32 askMode = - ((extractStatuses[i] & kStatus_Extract) != 0) ? (testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract) : - NExtract::NAskMode::kSkip; - - unpacker.linkFile = NULL; - - if (((extractStatuses[i] & kStatus_Link) != 0)) - { - int bufIndex = FindLinkBuf(linkFiles, i); - if (bufIndex < 0) - return E_FAIL; - unpacker.linkFile = &linkFiles[bufIndex]; - } - - UInt32 index = i; - - const CRefItem *ref = &_refs[index]; - const CItem *item = &_items[ref->Item]; - const CItem &lastItem = _items[ref->Last]; - - curUnpackSize = 0; - if (!lastItem.Is_UnknownSize()) - curUnpackSize = lastItem.Size; - - curPackSize = GetPackSize(index); - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - bool isSolid; - { - bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0]; - isSolid = (item->IsSolid() && !needClearSolid); - if (item->IsService()) - isSolid = false; - needClearSolid = !item->IsSolid(); - } - - if (item->IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - int index2 = ref->Link; - - int bufIndex = -1; - - if (index2 >= 0) - { - const CRefItem &ref2 = _refs[index2]; - const CItem &item2 = _items[ref2.Item]; - const CItem &lastItem2 = _items[ref2.Last]; - if (!item2.IsSolid()) - { - item = &item2; - ref = &ref2; - if (!lastItem2.Is_UnknownSize()) - curUnpackSize = lastItem2.Size; - else - curUnpackSize = 0; - curPackSize = GetPackSize(index2); - } - else if ((unsigned)index2 < index) - bufIndex = FindLinkBuf(linkFiles, index2); - } - - if (!realOutStream) - { - if (testMode) - { - if (item->Is_CopyLink() && item->PackSize == 0) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - } - else - { - if (item->IsService()) - continue; - - bool needDecode = false; - - for (unsigned n = i + 1; n < _refs.Size(); n++) - { - const CItem &nextItem = _items[_refs[n].Item]; - if (nextItem.IsService()) - continue; - if (!nextItem.IsSolid()) - break; - if (extractStatuses[i] != 0) - { - needDecode = true; - break; - } - } - - if (!needDecode) - continue; - - askMode = NExtract::NAskMode::kSkip; - } - } - - RINOK(extractCallback->PrepareOperation(askMode)); - - if (bufIndex >= 0) - { - CLinkFile &linkFile = linkFiles[bufIndex]; - if (linkFile.NumLinks == 0) - return E_FAIL; - if (realOutStream) - { - RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress)); - } - if (--linkFile.NumLinks == 0) - linkFile.Data.Free(); - RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))); - continue; - } - - if (item->Is_CopyLink() && item->PackSize == 0) - { - RINOK(extractCallback->SetOperationResult( - realOutStream ? - NExtract::NOperationResult::kUnsupportedMethod: - NExtract::NOperationResult::kOK)); - continue; - } - - volsInStreamSpec->Init(&_arcs, &_items, ref->Item); - - UInt64 packSize = curPackSize; - - if (item->IsEncrypted()) - if (!unpacker.getTextPassword) - extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&unpacker.getTextPassword); - - bool wrongPassword; - HRESULT result = unpacker.Create(EXTERNAL_CODECS_VARS *item, isSolid, wrongPassword); - - if (wrongPassword) - { - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kWrongPassword)); - continue; - } - - bool crcOK = true; - if (result == S_OK) - result = unpacker.Code(*item, _items[ref->Last], packSize, volsInStream, realOutStream, progress, crcOK); - realOutStream.Release(); - if (!volsInStreamSpec->CrcIsOK) - crcOK = false; - - int opRes = crcOK ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kCRCError; - - if (result != S_OK) - { - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else if (result == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else - return result; - } - - RINOK(extractCallback->SetOperationResult(opRes)); - } - - { - FOR_VECTOR(i, linkFiles) - if (linkFiles[i].NumLinks != 0) - return E_FAIL; - } - - return S_OK; - - COM_TRY_END -} - - -IMPL_ISetCompressCodecsInfo - -REGISTER_ARC_I( - "Rar5", "rar r00", 0, 0xCC, - kMarker, - 0, - NArcInfoFlags::kFindSignature, - NULL) - -}} - - -class CBlake2spHasher: - public IHasher, - public CMyUnknownImp -{ - CBlake2sp _blake; - Byte mtDummy[1 << 7]; - -public: - CBlake2spHasher() { Init(); } - - MY_UNKNOWN_IMP - INTERFACE_IHasher(;) -}; - -STDMETHODIMP_(void) CBlake2spHasher::Init() throw() -{ - Blake2sp_Init(&_blake); -} - -STDMETHODIMP_(void) CBlake2spHasher::Update(const void *data, UInt32 size) throw() -{ - Blake2sp_Update(&_blake, (const Byte *)data, size); -} - -STDMETHODIMP_(void) CBlake2spHasher::Final(Byte *digest) throw() -{ - Blake2sp_Final(&_blake, digest); -} - -REGISTER_HASHER(CBlake2spHasher, 0x202, "BLAKE2sp", BLAKE2S_DIGEST_SIZE) +// Rar5Handler.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/PropVariantUtils.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../IPassword.h" + +#include "../../Common/FilterCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/MethodProps.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/RegisterArc.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Common/RegisterCodec.h" + +#include "../../Compress/CopyCoder.h" + +#include "../../Crypto/Rar5Aes.h" + +#include "../../Archive/Common/FindSignature.h" +#include "../../Archive/Common/ItemNameUtils.h" +#include "../../Archive/Common/HandlerOut.h" + +#include "../../Archive/HandlerCont.h" + +#include "../../Archive/Rar/RarVol.h" +#include "Rar5Handler.h" + +using namespace NWindows; + +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NRar5 { + +static const unsigned kMarkerSize = 8; + +static const Byte kMarker[kMarkerSize] = + { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0 }; + +// Comment length is limited to 256 KB in rar-encoder. +// So we use same limitation +static const size_t kCommentSize_Max = (size_t)1 << 18; + + +static const char * const kHostOS[] = +{ + "Windows" + , "Unix" +}; + + +static const char * const k_ArcFlags[] = +{ + "Volume" + , "VolumeField" + , "Solid" + , "Recovery" + , "Lock" // 4 +}; + + +static const char * const k_FileFlags[] = +{ + "Dir" + , "UnixTime" + , "CRC" + , "UnknownSize" +}; + + +static const char * const g_ExtraTypes[] = +{ + "0" + , "Crypto" + , "Hash" + , "Time" + , "Version" + , "Link" + , "UnixOwner" + , "Subdata" +}; + + +static const char * const g_LinkTypes[] = +{ + "0" + , "UnixSymLink" + , "WinSymLink" + , "WinJunction" + , "HardLink" + , "FileCopy" +}; + + +static const char g_ExtraTimeFlags[] = { 'u', 'M', 'C', 'A', 'n' }; + + +static +Z7_NO_INLINE +unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val_ptr) +{ + if (maxSize > 10) + maxSize = 10; + UInt64 val = 0; + unsigned i; + for (i = 0; i < maxSize;) + { + const unsigned b = p[i]; + val |= (UInt64)(b & 0x7F) << (7 * i); + i++; + if ((b & 0x80) == 0) + { + *val_ptr = val; + return i; + } + } + *val_ptr = 0; +#if 1 + return 0; // 7zip-unrar : strict check of error +#else + return i; // original-unrar : ignore error +#endif +} + + +#define PARSE_VAR_INT(p, size, dest) \ +{ const unsigned num_ = ReadVarInt(p, size, &dest); \ + if (num_ == 0) return false; \ + p += num_; \ + size -= num_; \ +} + + +bool CLinkInfo::Parse(const Byte *p, unsigned size) +{ + const Byte *pStart = p; + UInt64 len; + PARSE_VAR_INT(p, size, Type) + PARSE_VAR_INT(p, size, Flags) + PARSE_VAR_INT(p, size, len) + if (size != len) + return false; + NameLen = (unsigned)len; + NameOffset = (unsigned)(size_t)(p - pStart); + return true; +} + + +static void AddHex64(AString &s, UInt64 v) +{ + char sz[32]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt64ToHex(v, sz + 2); + s += sz; +} + + +static void PrintType(AString &s, const char * const table[], unsigned num, UInt64 val) +{ + char sz[32]; + const char *p = NULL; + if (val < num) + p = table[(unsigned)val]; + if (!p) + { + ConvertUInt64ToString(val, sz); + p = sz; + } + s += p; +} + + +int CItem::FindExtra(unsigned extraID, unsigned &recordDataSize) const +{ + recordDataSize = 0; + size_t offset = 0; + + for (;;) + { + size_t rem = Extra.Size() - offset; + if (rem == 0) + return -1; + + { + UInt64 size; + const unsigned num = ReadVarInt(Extra + offset, rem, &size); + if (num == 0) + return -1; + offset += num; + rem -= num; + if (size > rem) + return -1; + rem = (size_t)size; + } + { + UInt64 id; + const unsigned num = ReadVarInt(Extra + offset, rem, &id); + if (num == 0) + return -1; + offset += num; + rem -= num; + + // There was BUG in RAR 5.21- : it stored (size-1) instead of (size) + // for Subdata record in Service header. + // That record always was last in bad archives, so we can fix that case. + if (id == NExtraID::kSubdata + && RecordType == NHeaderType::kService + && rem + 1 == Extra.Size() - offset) + rem++; + + if (id == extraID) + { + recordDataSize = (unsigned)rem; + return (int)offset; + } + + offset += rem; + } + } +} + + +void CItem::PrintInfo(AString &s) const +{ + size_t offset = 0; + + for (;;) + { + size_t rem = Extra.Size() - offset; + if (rem == 0) + return; + + { + UInt64 size; + unsigned num = ReadVarInt(Extra + offset, rem, &size); + if (num == 0) + return; + offset += num; + rem -= num; + if (size > rem) + break; + rem = (size_t)size; + } + { + UInt64 id; + { + unsigned num = ReadVarInt(Extra + offset, rem, &id); + if (num == 0) + break; + offset += num; + rem -= num; + } + + // There was BUG in RAR 5.21- : it stored (size-1) instead of (size) + // for Subdata record in Service header. + // That record always was last in bad archives, so we can fix that case. + if (id == NExtraID::kSubdata + && RecordType == NHeaderType::kService + && rem + 1 == Extra.Size() - offset) + rem++; + + s.Add_Space_if_NotEmpty(); + PrintType(s, g_ExtraTypes, Z7_ARRAY_SIZE(g_ExtraTypes), id); + + if (id == NExtraID::kTime) + { + const Byte *p = Extra + offset; + UInt64 flags; + const unsigned num = ReadVarInt(p, rem, &flags); + if (num != 0) + { + s.Add_Colon(); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExtraTimeFlags); i++) + if ((flags & ((UInt64)1 << i)) != 0) + s.Add_Char(g_ExtraTimeFlags[i]); + flags &= ~(((UInt64)1 << Z7_ARRAY_SIZE(g_ExtraTimeFlags)) - 1); + if (flags != 0) + { + s.Add_Char('_'); + AddHex64(s, flags); + } + } + } + else if (id == NExtraID::kLink) + { + CLinkInfo linkInfo; + if (linkInfo.Parse(Extra + offset, (unsigned)rem)) + { + s.Add_Colon(); + PrintType(s, g_LinkTypes, Z7_ARRAY_SIZE(g_LinkTypes), linkInfo.Type); + UInt64 flags = linkInfo.Flags; + if (flags != 0) + { + s.Add_Colon(); + if (flags & NLinkFlags::kTargetIsDir) + { + s.Add_Char('D'); + flags &= ~((UInt64)NLinkFlags::kTargetIsDir); + } + if (flags != 0) + { + s.Add_Char('_'); + AddHex64(s, flags); + } + } + } + } + + offset += rem; + } + } + + s.Add_OptSpaced("ERROR"); +} + + +bool CCryptoInfo::Parse(const Byte *p, size_t size) +{ + Algo = 0; + Flags = 0; + Cnt = 0; + PARSE_VAR_INT(p, size, Algo) + PARSE_VAR_INT(p, size, Flags) + if (size > 0) + Cnt = p[0]; + if (size != 1 + 16 + 16 + (unsigned)(IsThereCheck() ? 12 : 0)) + return false; + return true; +} + + +bool CItem::FindExtra_Version(UInt64 &version) const +{ + unsigned size; + const int offset = FindExtra(NExtraID::kVersion, size); + if (offset < 0) + return false; + const Byte *p = Extra + (unsigned)offset; + + UInt64 flags; + PARSE_VAR_INT(p, size, flags) + PARSE_VAR_INT(p, size, version) + return size == 0; +} + +bool CItem::FindExtra_Link(CLinkInfo &link) const +{ + unsigned size; + const int offset = FindExtra(NExtraID::kLink, size); + if (offset < 0) + return false; + if (!link.Parse(Extra + (unsigned)offset, size)) + return false; + link.NameOffset += (unsigned)offset; + return true; +} + +bool CItem::Is_CopyLink() const +{ + CLinkInfo link; + return FindExtra_Link(link) && link.Type == NLinkType::kFileCopy; +} + +bool CItem::Is_HardLink() const +{ + CLinkInfo link; + return FindExtra_Link(link) && link.Type == NLinkType::kHardLink; +} + +bool CItem::Is_CopyLink_or_HardLink() const +{ + CLinkInfo link; + return FindExtra_Link(link) && (link.Type == NLinkType::kFileCopy || link.Type == NLinkType::kHardLink); +} + +void CItem::Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const +{ + CLinkInfo link; + if (!FindExtra_Link(link)) + return; + + bool isWindows = (HostOS == kHost_Windows); + if (link.Type != linkType) + { + if (linkType != NLinkType::kUnixSymLink) + return; + switch ((unsigned)link.Type) + { + case NLinkType::kUnixSymLink: + isWindows = false; + break; + case NLinkType::kWinSymLink: + case NLinkType::kWinJunction: + isWindows = true; + break; + default: return; + } + } + + AString s; + s.SetFrom_CalcLen((const char *)(Extra + link.NameOffset), link.NameLen); + UString unicode; + ConvertUTF8ToUnicode(s, unicode); + // rar5.0 used '\\' separator for windows symlinks and \??\ prefix for abs paths. + // rar5.1+ uses '/' separator for windows symlinks and /??/ prefix for abs paths. + // v25.00: we convert Windows slashes to Linux slashes: + if (isWindows) + unicode.Replace(L'\\', L'/'); + prop = unicode; + // prop = NItemName::GetOsPath(unicode); +} + +bool CItem::GetAltStreamName(AString &name) const +{ + name.Empty(); + unsigned size; + const int offset = FindExtra(NExtraID::kSubdata, size); + if (offset < 0) + return false; + name.SetFrom_CalcLen((const char *)(Extra + (unsigned)offset), size); + return true; +} + + +class CHash +{ + bool _calcCRC; + UInt32 _crc; + int _blakeOffset; + CAlignedBuffer1 _buf; + // CBlake2sp _blake; + CBlake2sp *BlakeObj() { return (CBlake2sp *)(void *)(Byte *)_buf; } +public: + CHash(): + _buf(sizeof(CBlake2sp)) + {} + + void Init_NoCalc() + { + _calcCRC = false; + _crc = CRC_INIT_VAL; + _blakeOffset = -1; + } + + void Init(const CItem &item); + void Update(const void *data, size_t size); + UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); } + + bool Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoder); +}; + +void CHash::Init(const CItem &item) +{ + _crc = CRC_INIT_VAL; + _calcCRC = item.Has_CRC(); + _blakeOffset = item.FindExtra_Blake(); + if (_blakeOffset >= 0) + Blake2sp_Init(BlakeObj()); +} + +void CHash::Update(const void *data, size_t size) +{ + if (_calcCRC) + _crc = CrcUpdate(_crc, data, size); + if (_blakeOffset >= 0) + Blake2sp_Update(BlakeObj(), (const Byte *)data, size); +} + +bool CHash::Check(const CItem &item, NCrypto::NRar5::CDecoder *cryptoDecoder) +{ + if (_calcCRC) + { + UInt32 crc = GetCRC(); + if (cryptoDecoder) + crc = cryptoDecoder->Hmac_Convert_Crc32(crc); + if (crc != item.CRC) + return false; + } + if (_blakeOffset >= 0) + { + UInt32 digest[Z7_BLAKE2S_DIGEST_SIZE / sizeof(UInt32)]; + Blake2sp_Final(BlakeObj(), (Byte *)(void *)digest); + if (cryptoDecoder) + cryptoDecoder->Hmac_Convert_32Bytes((Byte *)(void *)digest); + if (memcmp(digest, item.Extra + (unsigned)_blakeOffset, Z7_BLAKE2S_DIGEST_SIZE) != 0) + return false; + } + return true; +} + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _size_Defined; + ISequentialOutStream *_stream; + UInt64 _pos; + UInt64 _size; + Byte *_destBuf; +public: + CHash _hash; + + COutStreamWithHash(): _destBuf(NULL) {} + + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init(const CItem &item, Byte *destBuf, bool needChecksumCheck) + { + _size_Defined = false; + _size = 0; + _destBuf = NULL; + if (!item.Is_UnknownSize()) + { + _size_Defined = true; + _size = item.Size; + _destBuf = destBuf; + } + _pos = 0; + if (needChecksumCheck) + _hash.Init(item); + else + _hash.Init_NoCalc(); + } + UInt64 GetPos() const { return _pos; } +}; + + +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_size_Defined) + { + const UInt64 rem = _size - _pos; + if (size > rem) + size = (UInt32)rem; + } + if (_stream) + result = _stream->Write(data, size, &size); + if (_destBuf) + memcpy(_destBuf + (size_t)_pos, data, size); + _hash.Update(data, size); + _pos += size; + if (processedSize) + *processedSize = size; + return result; +} + + + + + +class CInArchive +{ + CAlignedBuffer _buf; + size_t _bufSize; + size_t _bufPos; + ISequentialInStream *_stream; + + CMyComPtr2 m_CryptoDecoder; + + Z7_CLASS_NO_COPY(CInArchive) + + HRESULT ReadStream_Check(void *data, size_t size); + +public: + bool m_CryptoMode; + + bool WrongPassword; + bool IsArc; + bool UnexpectedEnd; + + UInt64 StreamStartPosition; + UInt64 Position; + + size_t Get_Buf_RemainSize() const { return _bufSize - _bufPos; } + bool Is_Buf_Finished() const { return _bufPos == _bufSize; } + const Byte *Get_Buf_Data() const { return _buf + _bufPos; } + void Move_BufPos(size_t num) { _bufPos += num; } + bool ReadVar(UInt64 &val); + + struct CHeader + { + UInt64 Type; + UInt64 Flags; + size_t ExtraSize; + UInt64 DataSize; + }; + + CInArchive() {} + + HRESULT ReadBlockHeader(CHeader &h); + bool ReadFileHeader(const CHeader &header, CItem &item); + void AddToSeekValue(UInt64 addValue) + { + Position += addValue; + } + + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, ICryptoGetTextPassword *getTextPassword, + CInArcInfo &info); +}; + + +static HRESULT MySetPassword(ICryptoGetTextPassword *getTextPassword, NCrypto::NRar5::CDecoder *cryptoDecoder) +{ + CMyComBSTR_Wipe password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + AString_Wipe utf8; + const unsigned kPasswordLen_MAX = 127; + UString_Wipe unicode; + unicode.SetFromBstr(password); + if (unicode.Len() > kPasswordLen_MAX) + unicode.DeleteFrom(kPasswordLen_MAX); + ConvertUnicodeToUTF8(unicode, utf8); + cryptoDecoder->SetPassword((const Byte *)(const char *)utf8, utf8.Len()); + return S_OK; +} + + +bool CInArchive::ReadVar(UInt64 &val) +{ + const unsigned offset = ReadVarInt(Get_Buf_Data(), Get_Buf_RemainSize(), &val); + Move_BufPos(offset); + return (offset != 0); +} + + +HRESULT CInArchive::ReadStream_Check(void *data, size_t size) +{ + size_t size2 = size; + RINOK(ReadStream(_stream, data, &size2)) + if (size2 == size) + return S_OK; + UnexpectedEnd = true; + return S_FALSE; +} + + +HRESULT CInArchive::ReadBlockHeader(CHeader &h) +{ + h.Type = 0; + h.Flags = 0; + h.ExtraSize = 0; + h.DataSize = 0; + + Byte buf[AES_BLOCK_SIZE]; + unsigned filled; + + if (m_CryptoMode) + { + _buf.AllocAtLeast(1 << 12); // at least (AES_BLOCK_SIZE * 2) + if (!(Byte *)_buf) + return E_OUTOFMEMORY; + RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2)) + memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE); + RINOK(m_CryptoDecoder->Init()) + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // data_size == 16 + if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) + return E_FAIL; + memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); + filled = AES_BLOCK_SIZE; + } + else + { + const unsigned kStartSize = 4 + 3; + RINOK(ReadStream_Check(buf, kStartSize)) + filled = kStartSize; + } + + { + UInt64 val; + unsigned offset = ReadVarInt(buf + 4, 3, &val); + if (offset == 0) + return S_FALSE; + size_t size = (size_t)val; + if (size < 2) + return S_FALSE; + offset += 4; + _bufPos = offset; + size += offset; + _bufSize = size; + if (m_CryptoMode) + size = (size + AES_BLOCK_SIZE - 1) & ~(size_t)(AES_BLOCK_SIZE - 1); + _buf.AllocAtLeast(size); + if (!(Byte *)_buf) + return E_OUTOFMEMORY; + memcpy(_buf, buf, filled); + const size_t rem = size - filled; + // if (m_CryptoMode), we add AES_BLOCK_SIZE here, because _iv is not included to size. + AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); + RINOK(ReadStream_Check(_buf + filled, rem)) + if (m_CryptoMode) + { + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // (rem) can be big + if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem) + return E_FAIL; +#if 1 + // optional 7zip-unrar check : remainder must contain zeros. + const size_t pad = size - _bufSize; + const Byte *p = _buf + _bufSize; + for (size_t i = 0; i < pad; i++) + if (p[i]) + return S_FALSE; +#endif + } + } + + if (CrcCalc(_buf + 4, _bufSize - 4) != Get32(buf)) + return S_FALSE; + + if (!ReadVar(h.Type)) return S_FALSE; + if (!ReadVar(h.Flags)) return S_FALSE; + + if (h.Flags & NHeaderFlags::kExtra) + { + UInt64 extraSize; + if (!ReadVar(extraSize)) + return S_FALSE; + if (extraSize >= (1u << 21)) + return S_FALSE; + h.ExtraSize = (size_t)extraSize; + } + + if (h.Flags & NHeaderFlags::kData) + { + if (!ReadVar(h.DataSize)) + return S_FALSE; + } + + if (h.ExtraSize > Get_Buf_RemainSize()) + return S_FALSE; + return S_OK; +} + + +bool CInArcInfo::CLocator::Parse(const Byte *p, size_t size) +{ + Flags = 0; + QuickOpen = 0; + Recovery = 0; + + PARSE_VAR_INT(p, size, Flags) + + if (Is_QuickOpen()) + { + PARSE_VAR_INT(p, size, QuickOpen) + } + if (Is_Recovery()) + { + PARSE_VAR_INT(p, size, Recovery) + } +#if 0 + // another records are possible in future rar formats. + if (size != 0) + return false; +#endif + return true; +} + + +bool CInArcInfo::CMetadata::Parse(const Byte *p, size_t size) +{ + PARSE_VAR_INT(p, size, Flags) + if (Flags & NMetadataFlags::kArcName) + { + UInt64 nameLen; + PARSE_VAR_INT(p, size, nameLen) + if (nameLen > size) + return false; + ArcName.SetFrom_CalcLen((const char *)(const void *)p, (unsigned)nameLen); + p += (size_t)nameLen; + size -= (size_t)nameLen; + } + if (Flags & NMetadataFlags::kCTime) + { + if ((Flags & NMetadataFlags::kUnixTime) && + (Flags & NMetadataFlags::kNanoSec) == 0) + { + if (size < 4) + return false; + CTime = GetUi32(p); + p += 4; + size -= 4; + } + else + { + if (size < 8) + return false; + CTime = GetUi64(p); + p += 8; + size -= 8; + } + } +#if 0 + // another records are possible in future rar formats. + if (size != 0) + return false; +#endif + return true; +} + + +bool CInArcInfo::ParseExtra(const Byte *p, size_t size) +{ + for (;;) + { + if (size == 0) + return true; + UInt64 recSize64, id; + PARSE_VAR_INT(p, size, recSize64) + if (recSize64 > size) + return false; + size_t recSize = (size_t)recSize64; + size -= recSize; + // READ_VAR_INT(p, recSize, recSize) + { + const unsigned num = ReadVarInt(p, recSize, &id); + if (num == 0) + return false; + p += num; + recSize -= num; + } + if (id == kArcExtraRecordType_Metadata) + { + Metadata_Defined = true; + if (!Metadata.Parse(p, recSize)) + Metadata_Error = true; + } + else if (id == kArcExtraRecordType_Locator) + { + Locator_Defined = true; + if (!Locator.Parse(p, recSize)) + Locator_Error = true; + } + else + UnknownExtraRecord = true; + p += recSize; + } +} + + + +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit, ICryptoGetTextPassword *getTextPassword, + CInArcInfo &info) +{ + m_CryptoMode = false; + + WrongPassword = false; + IsArc = false; + UnexpectedEnd = false; + + Position = StreamStartPosition; + + UInt64 arcStartPos = StreamStartPosition; + { + Byte marker[kMarkerSize]; + RINOK(ReadStream_FALSE(stream, marker, kMarkerSize)) + if (memcmp(marker, kMarker, kMarkerSize) == 0) + Position += kMarkerSize; + else + { + if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) + return S_FALSE; + RINOK(InStream_SeekSet(stream, StreamStartPosition)) + RINOK(FindSignatureInStream(stream, kMarker, kMarkerSize, + searchHeaderSizeLimit, arcStartPos)) + arcStartPos += StreamStartPosition; + Position = arcStartPos + kMarkerSize; + RINOK(InStream_SeekSet(stream, Position)) + } + } + + info.StartPos = arcStartPos; + _stream = stream; + + CHeader h; + RINOK(ReadBlockHeader(h)) + info.IsEncrypted = false; + + if (h.Type == NHeaderType::kArcEncrypt) + { + info.IsEncrypted = true; + IsArc = true; + if (!getTextPassword) + return E_NOTIMPL; + m_CryptoMode = true; + m_CryptoDecoder.Create_if_Empty(); + RINOK(m_CryptoDecoder->SetDecoderProps( + Get_Buf_Data(), (unsigned)Get_Buf_RemainSize(), false, false)) + RINOK(MySetPassword(getTextPassword, m_CryptoDecoder.ClsPtr())) + if (!m_CryptoDecoder->CalcKey_and_CheckPassword()) + { + WrongPassword = True; + return S_FALSE; + } + RINOK(ReadBlockHeader(h)) + } + + if (h.Type != NHeaderType::kArc) + return S_FALSE; + + IsArc = true; + info.VolNumber = 0; + + if (!ReadVar(info.Flags)) + return S_FALSE; + + if (info.Flags & NArcFlags::kVolNumber) + if (!ReadVar(info.VolNumber)) + return S_FALSE; + + if (h.ExtraSize != Get_Buf_RemainSize()) + return S_FALSE; + if (h.ExtraSize) + { + if (!info.ParseExtra(Get_Buf_Data(), h.ExtraSize)) + info.Extra_Error = true; + } + return S_OK; +} + + +bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item) +{ + item.CommonFlags = (UInt32)header.Flags; + item.PackSize = header.DataSize; + item.UnixMTime = 0; + item.CRC = 0; + + { + UInt64 flags64; + if (!ReadVar(flags64)) return false; + item.Flags = (UInt32)flags64; + } + + if (!ReadVar(item.Size)) return false; + + { + UInt64 attrib; + if (!ReadVar(attrib)) return false; + item.Attrib = (UInt32)attrib; + } + if (item.Has_UnixMTime()) + { + if (Get_Buf_RemainSize() < 4) + return false; + item.UnixMTime = Get32(Get_Buf_Data()); + Move_BufPos(4); + } + if (item.Has_CRC()) + { + if (Get_Buf_RemainSize() < 4) + return false; + item.CRC = Get32(Get_Buf_Data()); + Move_BufPos(4); + } + { + UInt64 method; + if (!ReadVar(method)) return false; + item.Method = (UInt32)method; + } + + if (!ReadVar(item.HostOS)) return false; + + { + UInt64 len; + if (!ReadVar(len)) return false; + if (len > Get_Buf_RemainSize()) + return false; + item.Name.SetFrom_CalcLen((const char *)Get_Buf_Data(), (unsigned)len); + Move_BufPos((size_t)len); + } + + item.Extra.Free(); + const size_t extraSize = header.ExtraSize; + if (extraSize != 0) + { + if (Get_Buf_RemainSize() < extraSize) + return false; + item.Extra.Alloc(extraSize); + memcpy(item.Extra, Get_Buf_Data(), extraSize); + Move_BufPos(extraSize); + } + + return Is_Buf_Finished(); +} + + + +struct CLinkFile +{ + unsigned Index; + unsigned NumLinks; // the number of links to Data + CByteBuffer Data; + HRESULT Res; + bool crcOK; + + CLinkFile(): Index(0), NumLinks(0), Res(S_OK), crcOK(true) {} +}; + + +struct CUnpacker +{ + CMyComPtr2 copyCoder; + CMyComPtr LzCoders[2]; + bool SolidAllowed; + bool NeedCrc; + CFilterCoder *filterStreamSpec; + CMyComPtr filterStream; + CMyComPtr2 cryptoDecoder; + CMyComPtr getTextPassword; + CMyComPtr2 outStream; + + CByteBuffer _tempBuf; + CLinkFile *linkFile; + + CUnpacker(): linkFile(NULL) { SolidAllowed = false; NeedCrc = true; } + + HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, bool isSolid, bool &wrongPassword); + + HRESULT Code(const CItem &item, const CItem &lastItem, UInt64 packSize, + ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress, + bool &isCrcOK); + + HRESULT DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, UInt64 packSize, ISequentialInStream *inStream, CByteBuffer &buffer); +}; + + +static const unsigned kLzMethodMax = 5; + +HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, bool isSolid, bool &wrongPassword) +{ + wrongPassword = false; + + if (item.Get_AlgoVersion_RawBits() > 1) + return E_NOTIMPL; + + outStream.Create_if_Empty(); + + const unsigned method = item.Get_Method(); + + if (method == 0) + copyCoder.Create_if_Empty(); + else + { + if (method > kLzMethodMax) + return E_NOTIMPL; + /* + if (item.IsSplitBefore()) + return S_FALSE; + */ + const unsigned lzIndex = item.IsService() ? 1 : 0; + CMyComPtr &lzCoder = LzCoders[lzIndex]; + if (!lzCoder) + { + const UInt32 methodID = 0x40305; + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodID, false, lzCoder)) + if (!lzCoder) + return E_NOTIMPL; + } + + CMyComPtr csdp; + RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)) + if (!csdp) + return E_NOTIMPL; + const unsigned ver = item.Get_AlgoVersion_HuffRev(); + if (ver > 1) + return E_NOTIMPL; + const Byte props[2] = + { + (Byte)item.Get_DictSize_Main(), + (Byte)((item.Get_DictSize_Frac() << 3) + (ver << 1) + (isSolid ? 1 : 0)) + }; + RINOK(csdp->SetDecoderProperties2(props, 2)) + } + + unsigned cryptoSize = 0; + const int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); + + if (cryptoOffset >= 0) + { + if (!filterStream) + { + filterStreamSpec = new CFilterCoder(false); + filterStream = filterStreamSpec; + } + + cryptoDecoder.Create_if_Empty(); + + RINOK(cryptoDecoder->SetDecoderProps(item.Extra + (unsigned)cryptoOffset, cryptoSize, true, item.IsService())) + + if (!getTextPassword) + { + wrongPassword = True; + return E_NOTIMPL; + } + + RINOK(MySetPassword(getTextPassword, cryptoDecoder.ClsPtr())) + + if (!cryptoDecoder->CalcKey_and_CheckPassword()) + wrongPassword = True; + } + + return S_OK; +} + + +HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSize, + ISequentialInStream *volsInStream, ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, + bool &isCrcOK) +{ + isCrcOK = true; + + const unsigned method = item.Get_Method(); + if (method > kLzMethodMax) + return E_NOTIMPL; + + const bool needBuf = (linkFile && linkFile->NumLinks != 0); + + if (needBuf && !lastItem.Is_UnknownSize()) + { + const size_t dataSize = (size_t)lastItem.Size; + if (dataSize != lastItem.Size) + return E_NOTIMPL; + linkFile->Data.Alloc(dataSize); + } + + bool isCryptoMode = false; + ISequentialInStream *inStream; + + if (item.IsEncrypted()) + { + filterStreamSpec->Filter = cryptoDecoder; + filterStreamSpec->SetInStream(volsInStream); + filterStreamSpec->SetOutStreamSize(NULL); + inStream = filterStream; + isCryptoMode = true; + } + else + inStream = volsInStream; + + ICompressCoder *commonCoder = (method == 0) ? + copyCoder.Interface() : + LzCoders[item.IsService() ? 1 : 0].Interface(); + + outStream->SetStream(realOutStream); + outStream->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL), NeedCrc); + + HRESULT res = S_OK; + if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0) + { + res = commonCoder->Code(inStream, outStream, &packSize, + lastItem.Is_UnknownSize() ? NULL : &lastItem.Size, progress); + if (!item.IsService()) + SolidAllowed = true; + } + else + { + // res = res; + } + + if (isCryptoMode) + filterStreamSpec->ReleaseInStream(); + + const UInt64 processedSize = outStream->GetPos(); + if (res == S_OK && !lastItem.Is_UnknownSize() && processedSize != lastItem.Size) + res = S_FALSE; + + // if (res == S_OK) + { + unsigned cryptoSize = 0; + const int cryptoOffset = lastItem.FindExtra(NExtraID::kCrypto, cryptoSize); + NCrypto::NRar5::CDecoder *crypto = NULL; + if (cryptoOffset >= 0) + { + CCryptoInfo cryptoInfo; + if (cryptoInfo.Parse(lastItem.Extra + (unsigned)cryptoOffset, cryptoSize)) + if (cryptoInfo.UseMAC()) + crypto = cryptoDecoder.ClsPtr(); + } + if (NeedCrc) + isCrcOK = outStream->_hash.Check(lastItem, crypto); + } + + if (linkFile) + { + linkFile->Res = res; + linkFile->crcOK = isCrcOK; + if (needBuf + && !lastItem.Is_UnknownSize() + && processedSize != lastItem.Size) + linkFile->Data.ChangeSize_KeepData((size_t)processedSize, (size_t)processedSize); + } + + return res; +} + + +HRESULT CUnpacker::DecodeToBuf(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, UInt64 packSize, + ISequentialInStream *inStream, + CByteBuffer &buffer) +{ + CMyComPtr2_Create out; + _tempBuf.AllocAtLeast((size_t)item.Size); + out->Init(_tempBuf, (size_t)item.Size); + + bool wrongPassword; + + if (item.IsSolid()) + return E_NOTIMPL; + + HRESULT res = Create(EXTERNAL_CODECS_LOC_VARS item, item.IsSolid(), wrongPassword); + + if (res == S_OK) + { + if (wrongPassword) + return S_FALSE; + + CMyComPtr2_Create limitedStream; + limitedStream->SetStream(inStream); + limitedStream->Init(packSize); + + bool crcOK = true; + res = Code(item, item, packSize, limitedStream, out, NULL, crcOK); + if (res == S_OK) + { + if (!crcOK || out->GetPos() != item.Size) + res = S_FALSE; + else + buffer.CopyFrom(_tempBuf, (size_t)item.Size); + } + } + + return res; +} + + +struct CTempBuf +{ + CByteBuffer _buf; + size_t _offset; + bool _isOK; + + void Clear() + { + _offset = 0; + _isOK = true; + } + + CTempBuf() { Clear(); } + + HRESULT Decode(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, + ISequentialInStream *inStream, + CUnpacker &unpacker, + CByteBuffer &destBuf); +}; + + +HRESULT CTempBuf::Decode(DECL_EXTERNAL_CODECS_LOC_VARS + const CItem &item, + ISequentialInStream *inStream, + CUnpacker &unpacker, + CByteBuffer &destBuf) +{ + const size_t kPackSize_Max = (1 << 24); + if (item.Size > (1 << 24) + || item.Size == 0 + || item.PackSize >= kPackSize_Max) + { + Clear(); + return S_OK; + } + + if (item.IsSplit() /* && _isOK */) + { + size_t packSize = (size_t)item.PackSize; + if (packSize > kPackSize_Max - _offset) + return S_OK; + size_t newSize = _offset + packSize; + if (newSize > _buf.Size()) + _buf.ChangeSize_KeepData(newSize, _offset); + + Byte *data = (Byte *)_buf + _offset; + RINOK(ReadStream_FALSE(inStream, data, packSize)) + + _offset += packSize; + + if (item.IsSplitAfter()) + { + CHash hash; + hash.Init(item); + hash.Update(data, packSize); + _isOK = hash.Check(item, NULL); // RAR5 doesn't use HMAC for packed part + } + } + + if (_isOK) + { + if (!item.IsSplitAfter()) + { + if (_offset == 0) + { + RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS + item, item.PackSize, inStream, destBuf)) + } + else + { + CMyComPtr2_Create bufInStream; + bufInStream->Init(_buf, _offset); + RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_LOC_VARS + item, _offset, bufInStream, destBuf)) + } + } + } + + return S_OK; +} + + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidAttrib, + // kpidPosixAttrib, // for debug + + kpidIsAltStream, + kpidEncrypted, + kpidSolid, + kpidSplitBefore, + kpidSplitAfter, + kpidCRC, + kpidHostOS, + kpidMethod, + kpidCharacts, + kpidSymLink, + kpidHardLink, + kpidCopyLink, + + kpidVolumeIndex +}; + + +static const Byte kArcProps[] = +{ + kpidTotalPhySize, + kpidCharacts, + kpidEncrypted, + kpidSolid, + kpidNumBlocks, + kpidMethod, + kpidIsVolume, + kpidVolumeIndex, + kpidNumVolumes, + kpidName, + kpidCTime, + kpidComment +}; + + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +UInt64 CHandler::GetPackSize(unsigned refIndex) const +{ + UInt64 size = 0; + unsigned index = _refs[refIndex].Item; + for (;;) + { + const CItem &item = _items[index]; + size += item.PackSize; + if (item.NextItem < 0) + return size; + index = (unsigned)item.NextItem; + } +} + +static char *PrintDictSize(char *s, UInt64 w) +{ + char c = 'K'; w >>= 10; + if ((w & ((1 << 10) - 1)) == 0) { c = 'M'; w >>= 10; + if ((w & ((1 << 10) - 1)) == 0) { c = 'G'; w >>= 10; }} + s = ConvertUInt64ToString(w, s); + *s++ = c; + *s = 0; + return s; +} + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + + NCOM::CPropVariant prop; + + const CInArcInfo *arcInfo = NULL; + if (!_arcs.IsEmpty()) + arcInfo = &_arcs[0].Info; + + switch (propID) + { + case kpidVolumeIndex: if (arcInfo && arcInfo->IsVolume()) prop = arcInfo->GetVolIndex(); break; + case kpidSolid: if (arcInfo) prop = arcInfo->IsSolid(); break; + case kpidCharacts: + { + AString s; + if (arcInfo) + { + s = FlagsToString(k_ArcFlags, Z7_ARRAY_SIZE(k_ArcFlags), (UInt32)arcInfo->Flags); + if (arcInfo->Extra_Error) + s.Add_OptSpaced("Extra-ERROR"); + if (arcInfo->UnsupportedFeature) + s.Add_OptSpaced("unsupported-feature"); + if (arcInfo->Metadata_Defined) + { + s.Add_OptSpaced("Metadata"); + if (arcInfo->Metadata_Error) + s += "-ERROR"; + else + { + if (arcInfo->Metadata.Flags & NMetadataFlags::kArcName) + s.Add_OptSpaced("arc-name"); + if (arcInfo->Metadata.Flags & NMetadataFlags::kCTime) + { + s.Add_OptSpaced("ctime-"); + s += + (arcInfo->Metadata.Flags & NMetadataFlags::kUnixTime) ? + (arcInfo->Metadata.Flags & NMetadataFlags::kNanoSec) ? + "1ns" : "1s" : "win"; + } + } + } + if (arcInfo->Locator_Defined) + { + s.Add_OptSpaced("Locator"); + if (arcInfo->Locator_Error) + s += "-ERROR"; + else + { + if (arcInfo->Locator.Is_QuickOpen()) + { + s.Add_OptSpaced("QuickOpen:"); + s.Add_UInt64(arcInfo->Locator.QuickOpen); + } + if (arcInfo->Locator.Is_Recovery()) + { + s.Add_OptSpaced("Recovery:"); + s.Add_UInt64(arcInfo->Locator.Recovery); + } + } + } + if (arcInfo->UnknownExtraRecord) + s.Add_OptSpaced("Unknown-Extra-Record"); + + } + if (_comment_WasUsedInArc) + { + s.Add_OptSpaced("Comment"); + // s.Add_UInt32((UInt32)_comment.Size()); + } + // + if (_acls.Size() != 0) + { + s.Add_OptSpaced("ACL"); + // s.Add_UInt32(_acls.Size()); + } + if (!s.IsEmpty()) + prop = s; + break; + } + case kpidEncrypted: if (arcInfo) prop = arcInfo->IsEncrypted; break; // it's for encrypted names. + case kpidIsVolume: if (arcInfo) prop = arcInfo->IsVolume(); break; + case kpidNumVolumes: prop = (UInt32)_arcs.Size(); break; + case kpidOffset: if (arcInfo && arcInfo->StartPos != 0) prop = arcInfo->StartPos; break; + + case kpidTotalPhySize: + { + if (_arcs.Size() > 1) + { + UInt64 sum = 0; + FOR_VECTOR (v, _arcs) + sum += _arcs[v].Info.GetPhySize(); + prop = sum; + } + break; + } + + case kpidPhySize: + { + if (arcInfo) + prop = arcInfo->GetPhySize(); + break; + } + + case kpidName: + if (arcInfo) + if (!arcInfo->Metadata_Error + && !arcInfo->Metadata.ArcName.IsEmpty()) + { + UString s; + if (ConvertUTF8ToUnicode(arcInfo->Metadata.ArcName, s)) + prop = s; + } + break; + + case kpidCTime: + if (arcInfo) + if (!arcInfo->Metadata_Error + && (arcInfo->Metadata.Flags & NMetadataFlags::kCTime)) + { + const UInt64 ct = arcInfo->Metadata.CTime; + if (arcInfo->Metadata.Flags & NMetadataFlags::kUnixTime) + { + if (arcInfo->Metadata.Flags & NMetadataFlags::kNanoSec) + { + const UInt64 sec = ct / 1000000000; + const UInt64 ns = ct % 1000000000; + UInt64 wt = NTime::UnixTime64_To_FileTime64((Int64)sec); + wt += ns / 100; + const unsigned ns100 = (unsigned)(ns % 100); + FILETIME ft; + ft.dwLowDateTime = (DWORD)(UInt32)wt; + ft.dwHighDateTime = (DWORD)(UInt32)(wt >> 32); + prop.SetAsTimeFrom_FT_Prec_Ns100(ft, k_PropVar_TimePrec_1ns, ns100); + } + else + { + const UInt64 wt = NTime::UnixTime64_To_FileTime64((Int64)ct); + prop.SetAsTimeFrom_Ft64_Prec(wt, k_PropVar_TimePrec_Unix); + } + } + else + prop.SetAsTimeFrom_Ft64_Prec(ct, k_PropVar_TimePrec_100ns); + } + break; + + case kpidComment: + { + // if (!_arcs.IsEmpty()) + { + // const CArc &arc = _arcs[0]; + const CByteBuffer &cmt = _comment; + if (cmt.Size() != 0 /* && cmt.Size() < (1 << 16) */) + { + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)cmt, (unsigned)cmt.Size()); + UString unicode; + ConvertUTF8ToUnicode(s, unicode); + prop = unicode; + } + } + break; + } + + case kpidNumBlocks: + { + prop = (UInt32)_numBlocks; + break; + } + + case kpidMethod: + { + AString s; + + UInt64 algo = _algo_Mask; + for (unsigned v = 0; algo != 0; v++, algo >>= 1) + { + if ((algo & 1) == 0) + continue; + s.Add_OptSpaced("v"); + s.Add_UInt32(v + 6); + if (v < Z7_ARRAY_SIZE(_methodMasks)) + { + const UInt64 dict = _dictMaxSizes[v]; + if (dict) + { + char temp[24]; + temp[0] = ':'; + PrintDictSize(temp + 1, dict); + s += temp; + } + unsigned method = _methodMasks[v]; + for (unsigned m = 0; method; m++, method >>= 1) + { + if ((method & 1) == 0) + continue; + s += ":m"; + s.Add_UInt32(m); + } + } + } + if (_rar5comapt_mask & 2) + { + s += ":c"; + if (_rar5comapt_mask & 1) + s.Add_Char('n'); + } + prop = s; + break; + } + + case kpidError: + { + if (/* &_missingVol || */ !_missingVolName.IsEmpty()) + { + UString s ("Missing volume : "); + s += _missingVolName; + prop = s; + } + break; + } + + case kpidErrorFlags: + { + UInt32 v = _errorFlags; + if (!_isArc) + v |= kpv_ErrorFlags_IsNotArc; + if (_error_in_ACL) + v |= kpv_ErrorFlags_HeadersError; + if (_split_Error) + v |= kpv_ErrorFlags_HeadersError; + prop = v; + break; + } + + /* + case kpidWarningFlags: + { + if (_warningFlags != 0) + prop = _warningFlags; + break; + } + */ + + case kpidExtension: + if (_arcs.Size() == 1) + { + if (arcInfo->IsVolume()) + { + AString s ("part"); + UInt32 v = (UInt32)arcInfo->GetVolIndex() + 1; + if (v < 10) + s.Add_Char('0'); + s.Add_UInt32(v); + s += ".rar"; + prop = s; + } + } + break; + + case kpidIsAltStream: prop = true; break; + } + + prop.Detach(value); + return S_OK; + + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = (UInt32)_refs.Size(); + return S_OK; +} + + +static const Byte kRawProps[] = +{ + kpidChecksum, + kpidNtSecure +}; + + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + + if (index >= _refs.Size()) + return S_OK; + + const CRefItem &ref = _refs[index]; + const CItem &item = _items[ref.Item]; + + if (item.Is_STM() && ref.Parent >= 0) + { + *parent = (UInt32)ref.Parent; + *parentType = NParentType::kAltStream; + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (index >= _refs.Size()) + return E_INVALIDARG; + + const CItem &item = _items[_refs[index].Item]; + + if (propID == kpidNtSecure) + { + if (item.ACL >= 0) + { + const CByteBuffer &buf = _acls[item.ACL]; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kRaw; + *data = (const Byte *)buf; + } + return S_OK; + } + + if (propID == kpidChecksum) + { + const int hashRecOffset = item.FindExtra_Blake(); + if (hashRecOffset >= 0) + { + *dataSize = Z7_BLAKE2S_DIGEST_SIZE; + *propType = NPropDataType::kRaw; + *data = item.Extra + (unsigned)hashRecOffset; + } + /* + else if (item.Has_CRC() && item.IsEncrypted()) + { + *dataSize = 4; + *propType = NPropDataType::kRaw; + *data = &item->CRC; // we must show same value for big/little endian here + } + */ + return S_OK; + } + + return S_OK; +} + + +static void TimeRecordToProp(const CItem &item, unsigned stampIndex, NCOM::CPropVariant &prop) +{ + unsigned size; + const int offset = item.FindExtra(NExtraID::kTime, size); + if (offset < 0) + return; + + const Byte *p = item.Extra + (unsigned)offset; + UInt64 flags; + // PARSE_VAR_INT(p, size, flags) + { + const unsigned num = ReadVarInt(p, size, &flags); + if (num == 0) + return; + p += num; + size -= num; + } + + if ((flags & (NTimeRecord::NFlags::kMTime << stampIndex)) == 0) + return; + + unsigned numStamps = 0; + unsigned curStamp = 0; + + for (unsigned i = 0; i < 3; i++) + if ((flags & (NTimeRecord::NFlags::kMTime << i)) != 0) + { + if (i == stampIndex) + curStamp = numStamps; + numStamps++; + } + + FILETIME ft; + + unsigned timePrec = 0; + unsigned ns100 = 0; + + if ((flags & NTimeRecord::NFlags::kUnixTime) != 0) + { + curStamp *= 4; + if (curStamp + 4 > size) + return; + 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(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); + } + else + { + curStamp *= 8; + if (curStamp + 8 > size) + return; + p += curStamp; + ft.dwLowDateTime = Get32(p); + ft.dwHighDateTime = Get32(p + 4); + } + + prop.SetAsTimeFrom_FT_Prec_Ns100(ft, timePrec, ns100); +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + + NCOM::CPropVariant prop; + const CRefItem &ref = _refs[index]; + const CItem &item = _items[ref.Item]; + const CItem &lastItem = _items[ref.Last]; + + switch (propID) + { + case kpidPath: + { + UString unicodeName; + + if (item.Is_STM()) + { + AString s; + if (ref.Parent >= 0) + { + const CItem &mainItem = _items[_refs[ref.Parent].Item]; + s = mainItem.Name; + } + + AString name; + item.GetAltStreamName(name); + if (name[0] != ':') + s.Add_Colon(); + s += name; + ConvertUTF8ToUnicode(s, unicodeName); + } + else + { + ConvertUTF8ToUnicode(item.Name, unicodeName); + + if (item.Version_Defined) + { + char temp[32]; + // temp[0] = ';'; + // ConvertUInt64ToString(item.Version, temp + 1); + // unicodeName += temp; + ConvertUInt64ToString(item.Version, temp); + UString s2 ("[VER]" STRING_PATH_SEPARATOR); + s2 += temp; + s2.Add_PathSepar(); + unicodeName.Insert(0, s2); + } + } + + NItemName::ReplaceToOsSlashes_Remove_TailSlash(unicodeName); + prop = unicodeName; + + break; + } + + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: if (!lastItem.Is_UnknownSize()) prop = lastItem.Size; break; + case kpidPackSize: prop = GetPackSize((unsigned)index); break; + + case kpidMTime: + { + TimeRecordToProp(item, NTimeRecord::k_Index_MTime, prop); + if (prop.vt == VT_EMPTY && item.Has_UnixMTime()) + 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()) + PropVariant_SetFrom_UnixTime(prop, baseItem.UnixMTime); + } + break; + } + case kpidCTime: TimeRecordToProp(item, NTimeRecord::k_Index_CTime, prop); break; + case kpidATime: TimeRecordToProp(item, NTimeRecord::k_Index_ATime, prop); break; + + case kpidName: + { + if (item.Is_STM()) + { + AString name; + item.GetAltStreamName(name); + if (name[0] == ':') + { + name.DeleteFrontal(1); + UString unicodeName; + ConvertUTF8ToUnicode(name, unicodeName); + prop = unicodeName; + } + } + break; + } + + case kpidIsAltStream: prop = item.Is_STM(); break; + + case kpidSymLink: item.Link_to_Prop(NLinkType::kUnixSymLink, prop); break; + case kpidHardLink: item.Link_to_Prop(NLinkType::kHardLink, prop); break; + case kpidCopyLink: item.Link_to_Prop(NLinkType::kFileCopy, prop); break; + + case kpidAttrib: prop = item.GetWinAttrib(); break; + case kpidPosixAttrib: + if (item.HostOS == kHost_Unix) + prop = (UInt32)item.Attrib; + break; + + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidSolid: prop = item.IsSolid(); break; + + case kpidSplitBefore: prop = item.IsSplitBefore(); break; + case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break; + + case kpidVolumeIndex: + { + if (item.VolIndex < _arcs.Size()) + { + const CInArcInfo &arcInfo = _arcs[item.VolIndex].Info; + if (arcInfo.IsVolume()) + prop = (UInt64)arcInfo.GetVolIndex(); + } + break; + } + + case kpidCRC: + { + const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem); + // we don't want to show crc for encrypted file here, + // because crc is also encrrypted. + if (item2->Has_CRC() && !item2->IsEncrypted()) + prop = item2->CRC; + break; + } + + case kpidMethod: + { + char temp[128]; + const unsigned algo = item.Get_AlgoVersion_RawBits(); + char *s = temp; + // if (algo != 0) + { + *s++ = 'v'; + s = ConvertUInt32ToString((UInt32)algo + 6, s); + if (item.Is_Rar5_Compat()) + *s++ = 'c'; + *s++ = ':'; + } + { + const unsigned m = item.Get_Method(); + *s++ = 'm'; + *s++ = (char)(m + '0'); + if (!item.IsDir()) + { + *s++ = ':'; + const unsigned dictMain = item.Get_DictSize_Main(); + const unsigned frac = item.Get_DictSize_Frac(); + /* + if (frac == 0 && algo == 0) + s = ConvertUInt32ToString(dictMain + 17, s); + else + */ + s = PrintDictSize(s, (UInt64)(32 + frac) << (12 + dictMain)); + if (item.Is_Rar5_Compat()) + { + *s++ = ':'; + *s++ = 'c'; + } + } + } + unsigned cryptoSize = 0; + const int cryptoOffset = item.FindExtra(NExtraID::kCrypto, cryptoSize); + if (cryptoOffset >= 0) + { + *s++ = ' '; + CCryptoInfo cryptoInfo; + const bool isOK = cryptoInfo.Parse(item.Extra + (unsigned)cryptoOffset, cryptoSize); + if (cryptoInfo.Algo == 0) + s = MyStpCpy(s, "AES"); + else + { + s = MyStpCpy(s, "Crypto_"); + s = ConvertUInt64ToString(cryptoInfo.Algo, s); + } + if (isOK) + { + *s++ = ':'; + s = ConvertUInt32ToString(cryptoInfo.Cnt, s); + *s++ = ':'; + s = ConvertUInt64ToString(cryptoInfo.Flags, s); + } + } + *s = 0; + prop = temp; + break; + } + + case kpidCharacts: + { + AString s; + + if (item.ACL >= 0) + s.Add_OptSpaced("ACL"); + + const UInt32 flags = item.Flags; + if (flags != 0) + { + const AString s2 = FlagsToString(k_FileFlags, Z7_ARRAY_SIZE(k_FileFlags), flags); + if (!s2.IsEmpty()) + s.Add_OptSpaced(s2); + } + + item.PrintInfo(s); + + if (!s.IsEmpty()) + prop = s; + break; + } + + + case kpidHostOS: + if (item.HostOS < Z7_ARRAY_SIZE(kHostOS)) + prop = kHostOS[(size_t)item.HostOS]; + else + prop = (UInt64)item.HostOS; + break; + } + + prop.Detach(value); + return S_OK; + + COM_TRY_END +} + + + +// ---------- Copy Links ---------- + +static int CompareItemsPaths(const CHandler &handler, unsigned p1, unsigned p2, const AString *name1) +{ + const CItem &item1 = handler._items[handler._refs[p1].Item]; + const CItem &item2 = handler._items[handler._refs[p2].Item]; + + if (item1.Version_Defined) + { + if (!item2.Version_Defined) + return -1; + const int res = MyCompare(item1.Version, item2.Version); + if (res != 0) + return res; + } + else if (item2.Version_Defined) + return 1; + + if (!name1) + name1 = &item1.Name; + return strcmp(*name1, item2.Name); +} + +static int CompareItemsPaths2(const CHandler &handler, unsigned p1, unsigned p2, const AString *name1) +{ + const int res = CompareItemsPaths(handler, p1, p2, name1); + if (res != 0) + return res; + return MyCompare(p1, p2); +} + +static int CompareItemsPaths_Sort(const unsigned *p1, const unsigned *p2, void *param) +{ + return CompareItemsPaths2(*(const CHandler *)param, *p1, *p2, NULL); +} + +static int FindLink(const CHandler &handler, const CUIntVector &sorted, + const AString &s, unsigned index) +{ + unsigned left = 0, right = sorted.Size(); + for (;;) + { + if (left == right) + { + if (left > 0) + { + const unsigned refIndex = sorted[left - 1]; + if (CompareItemsPaths(handler, index, refIndex, &s) == 0) + return (int)refIndex; + } + if (right < sorted.Size()) + { + const unsigned refIndex = sorted[right]; + if (CompareItemsPaths(handler, index, refIndex, &s) == 0) + return (int)refIndex; + } + return -1; + } + + const unsigned mid = (left + right) / 2; + const unsigned refIndex = sorted[mid]; + const int compare = CompareItemsPaths2(handler, index, refIndex, &s); + if (compare == 0) + return (int)refIndex; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +void CHandler::FillLinks() +{ + unsigned i; + + bool need_FillLinks = false; + + for (i = 0; i < _refs.Size(); i++) + { + const CItem &item = _items[_refs[i].Item]; + if (!item.IsDir() + && !item.IsService() + && item.NeedUse_as_CopyLink()) + need_FillLinks = true; + + if (!item.IsSolid()) + _numBlocks++; + + const unsigned algo = item.Get_AlgoVersion_RawBits(); + _algo_Mask |= (UInt64)1 << algo; + _rar5comapt_mask |= 1u << item.Get_Rar5_CompatBit(); + if (!item.IsDir() && algo < Z7_ARRAY_SIZE(_methodMasks)) + { + _methodMasks[algo] |= 1u << (item.Get_Method()); + UInt64 d = 32 + item.Get_DictSize_Frac(); + d <<= (12 + item.Get_DictSize_Main()); + if (_dictMaxSizes[algo] < d) + _dictMaxSizes[algo] = d; + } + } + + if (!need_FillLinks) + return; + + CUIntVector sorted; + for (i = 0; i < _refs.Size(); i++) + { + const CItem &item = _items[_refs[i].Item]; + if (!item.IsDir() && !item.IsService()) + sorted.Add(i); + } + + if (sorted.IsEmpty()) + return; + + sorted.Sort(CompareItemsPaths_Sort, (void *)this); + + AString link; + + for (i = 0; i < _refs.Size(); i++) + { + CRefItem &ref = _refs[i]; + const CItem &item = _items[ref.Item]; + if (item.IsDir() || item.IsService() || item.PackSize != 0) + continue; + CLinkInfo linkInfo; + if (!item.FindExtra_Link(linkInfo) || linkInfo.Type != NLinkType::kFileCopy) + continue; + link.SetFrom_CalcLen((const char *)(item.Extra + linkInfo.NameOffset), linkInfo.NameLen); + const int linkIndex = FindLink(*this, sorted, link, i); + if (linkIndex < 0) + continue; + if ((unsigned)linkIndex >= i) + continue; // we don't support forward links that can lead to loops + const CRefItem &linkRef = _refs[linkIndex]; + const CItem &linkItem = _items[linkRef.Item]; + if (linkItem.Size == item.Size) + { + if (linkRef.Link >= 0) + ref.Link = linkRef.Link; + else if (!linkItem.NeedUse_as_CopyLink()) + ref.Link = linkIndex; + } + } +} + + + +HRESULT CHandler::Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback) +{ + CMyComPtr openVolumeCallback; + // CMyComPtr getTextPassword; + NRar::CVolumeName seqName; + CTempBuf tempBuf; + CUnpacker unpacker; + + if (openCallback) + { + openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&unpacker.getTextPassword); + } + // unpacker.getTextPassword = getTextPassword; + + CInArchive arch; + int prevSplitFile = -1; + int prevMainFile = -1; + UInt64 totalBytes = 0; + UInt64 curBytes = 0; + bool nextVol_is_Required = false; + + for (;;) + { + CMyComPtr inStream; + + if (_arcs.IsEmpty()) + inStream = stream; + else + { + if (!openVolumeCallback) + break; + if (_arcs.Size() == 1) + { + UString baseName; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt != VT_BSTR) + break; + baseName = prop.bstrVal; + } + if (!seqName.InitName(baseName)) + break; + } + const UString volName = seqName.GetNextName(); + const HRESULT result = openVolumeCallback->GetStream(volName, &inStream); + if (result != S_OK && result != S_FALSE) + return result; + if (!inStream || result != S_OK) + { + if (nextVol_is_Required) + _missingVolName = volName; + break; + } + } + + UInt64 endPos = 0; + RINOK(InStream_GetPos_GetSize(inStream, arch.StreamStartPosition, endPos)) + + if (openCallback) + { + totalBytes += endPos; + RINOK(openCallback->SetTotal(NULL, &totalBytes)) + } + + CInArcInfo arcInfo_Open; + { + const HRESULT res = arch.Open(inStream, maxCheckStartPosition, unpacker.getTextPassword, arcInfo_Open); + if (arch.IsArc && arch.UnexpectedEnd) + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; + if (_arcs.IsEmpty()) + _isArc = arch.IsArc; + if (res != S_OK) + { + if (res != S_FALSE) + return res; + if (_arcs.IsEmpty()) + return res; + break; + } + } + + CArc &arc = _arcs.AddNew(); + CInArcInfo &arcInfo = arc.Info; + arcInfo = arcInfo_Open; + arc.Stream = inStream; + + CItem item; + + for (;;) + { + item.Clear(); + + arcInfo.EndPos = arch.Position; + if (arch.Position > endPos) + { + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; + break; + } + RINOK(InStream_SeekSet(inStream, arch.Position)) + + { + CInArchive::CHeader h; + const HRESULT res = arch.ReadBlockHeader(h); + if (res != S_OK) + { + if (res != S_FALSE) + return res; + if (arch.UnexpectedEnd) + { + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; + if (arcInfo.EndPos < arch.Position) + arcInfo.EndPos = arch.Position; + if (arcInfo.EndPos < endPos) + arcInfo.EndPos = endPos; + } + else + _errorFlags |= kpv_ErrorFlags_HeadersError; + break; + } + + if (h.Type == NHeaderType::kEndOfArc) + { + arcInfo.EndPos = arch.Position; + arcInfo.EndOfArchive_was_Read = true; + if (!arch.ReadVar(arcInfo.EndFlags)) + _errorFlags |= kpv_ErrorFlags_HeadersError; + if (!arch.Is_Buf_Finished() || h.ExtraSize || h.DataSize) + arcInfo.UnsupportedFeature = true; + if (arcInfo.IsVolume()) + { + // for multivolume archives RAR can add ZERO bytes at the end for alignment. + // We must skip these bytes to prevent phySize warning. + RINOK(InStream_SeekSet(inStream, arcInfo.EndPos)) + bool areThereNonZeros; + UInt64 numZeros; + const UInt64 maxSize = 1 << 12; + RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)) + if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) + arcInfo.EndPos += numZeros; + } + break; + } + + if (h.Type != NHeaderType::kFile && + h.Type != NHeaderType::kService) + { + _errorFlags |= kpv_ErrorFlags_UnsupportedFeature; + break; + } + + item.RecordType = (Byte)h.Type; + if (!arch.ReadFileHeader(h, item)) + { + _errorFlags |= kpv_ErrorFlags_HeadersError; + break; + } + item.DataPos = arch.Position; + } + + bool isOk_packSize = true; + { + arcInfo.EndPos = arch.Position; + if (arch.Position + item.PackSize < arch.Position) + { + isOk_packSize = false; + _errorFlags |= kpv_ErrorFlags_HeadersError; + if (arcInfo.EndPos < endPos) + arcInfo.EndPos = endPos; + } + else + { + arch.AddToSeekValue(item.PackSize); // Position points to next header; + arcInfo.EndPos = arch.Position; + } + } + + bool needAdd = true; + + if (!_comment_WasUsedInArc + && _comment.Size() == 0 + && item.Is_CMT()) + { + _comment_WasUsedInArc = true; + if ( item.PackSize <= kCommentSize_Max + && item.PackSize == item.Size + && item.PackSize != 0 + && item.Get_Method() == 0 + && !item.IsSplit()) + { + RINOK(unpacker.DecodeToBuf(EXTERNAL_CODECS_VARS item, item.PackSize, inStream, _comment)) + needAdd = false; + // item.RecordType = (Byte)NHeaderType::kFile; // for debug + } + } + + CRefItem ref; + ref.Item = _items.Size(); + ref.Last = ref.Item; + ref.Parent = -1; + ref.Link = -1; + + if (needAdd) + { + if (item.IsService()) + { + if (item.Is_STM()) + { + if (prevMainFile >= 0) + ref.Parent = prevMainFile; + } + else + { + needAdd = false; + if (item.Is_ACL()) + { + _acl_Used = true; + if (item.IsEncrypted() && !arch.m_CryptoMode) + _error_in_ACL = true; + else if (item.IsSolid() + || prevMainFile < 0 + || item.Size >= (1 << 24) + || item.Size == 0) + _error_in_ACL = true; + if (prevMainFile >= 0 && item.Size < (1 << 24) && item.Size != 0) + { + CItem &mainItem = _items[_refs[prevMainFile].Item]; + + if (mainItem.ACL < 0) + { + CByteBuffer acl; + const HRESULT res = tempBuf.Decode(EXTERNAL_CODECS_VARS item, inStream, unpacker, acl); + if (!item.IsSplitAfter()) + tempBuf.Clear(); + if (res != S_OK) + { + tempBuf.Clear(); + if (res != S_FALSE && res != E_NOTIMPL) + return res; + _error_in_ACL = true; + } + else if (acl.Size() != 0) + { + if (_acls.IsEmpty() || acl != _acls.Back()) + _acls.Add(acl); + mainItem.ACL = (int)_acls.Size() - 1; + } + } + } + } + } + } // item.IsService() + + if (needAdd) + { + if (item.IsSplitBefore()) + { + if (prevSplitFile >= 0) + { + CRefItem &ref2 = _refs[prevSplitFile]; + CItem &prevItem = _items[ref2.Last]; + if (item.IsNextForItem(prevItem)) + { + ref2.Last = _items.Size(); + prevItem.NextItem = (int)ref2.Last; + needAdd = false; + } + } + else + _split_Error = true; + } + } + + if (needAdd) + { + if (item.IsSplitAfter()) + prevSplitFile = (int)_refs.Size(); + if (!item.IsService()) + prevMainFile = (int)_refs.Size(); + } + } + + { + UInt64 version; + if (item.FindExtra_Version(version)) + { + item.Version_Defined = true; + item.Version = version; + } + } + + item.VolIndex = _arcs.Size() - 1; + _items.Add(item); + if (needAdd) + _refs.Add(ref); + + if (openCallback && (_items.Size() & 0xFF) == 0) + { + const UInt64 numFiles = _refs.Size(); // _items.Size() + const UInt64 numBytes = curBytes + item.DataPos; + RINOK(openCallback->SetCompleted(&numFiles, &numBytes)) + } + + if (!isOk_packSize) + break; + } + + curBytes += endPos; + + nextVol_is_Required = false; + + if (!arcInfo.IsVolume()) + break; + + if (arcInfo.EndOfArchive_was_Read) + { + if (!arcInfo.AreMoreVolumes()) + break; + nextVol_is_Required = true; + } + } + + FillLinks(); + return S_OK; +} + + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + Close(); + return Open2(stream, maxCheckStartPosition, openCallback); + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + COM_TRY_BEGIN + _missingVolName.Empty(); + _errorFlags = 0; + // _warningFlags = 0; + _isArc = false; + _comment_WasUsedInArc = false; + _acl_Used = false; + _error_in_ACL = false; + _split_Error = false; + _numBlocks = 0; + _rar5comapt_mask = 0; + _algo_Mask = 0; // (UInt64)0u - 1; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(_methodMasks); i++) + { + _methodMasks[i] = 0; + _dictMaxSizes[i] = 0; + } + + _refs.Clear(); + _items.Clear(); + _arcs.Clear(); + _acls.Clear(); + _comment.Free(); + return S_OK; + COM_TRY_END +} + + +Z7_CLASS_IMP_NOQIB_1( + CVolsInStream + , ISequentialInStream +) + UInt64 _rem; + ISequentialInStream *_stream; + const CObjectVector *_arcs; + const CObjectVector *_items; + int _itemIndex; +public: + bool CrcIsOK; +private: + CHash _hash; +public: + void Init(const CObjectVector *arcs, + const CObjectVector *items, + unsigned itemIndex) + { + _arcs = arcs; + _items = items; + _itemIndex = (int)itemIndex; + _stream = NULL; + CrcIsOK = true; + } +}; + +Z7_COM7F_IMF(CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + UInt32 realProcessedSize = 0; + + while (size != 0) + { + if (!_stream) + { + if (_itemIndex < 0) + break; + const CItem &item = (*_items)[_itemIndex]; + IInStream *s = (*_arcs)[item.VolIndex].Stream; + RINOK(InStream_SeekSet(s, item.GetDataPosition())) + _stream = s; + if (CrcIsOK && item.IsSplitAfter()) + _hash.Init(item); + else + _hash.Init_NoCalc(); + _rem = item.PackSize; + } + { + UInt32 cur = size; + if (cur > _rem) + cur = (UInt32)_rem; + const UInt32 num = cur; + HRESULT res = _stream->Read(data, cur, &cur); + _hash.Update(data, cur); + realProcessedSize += cur; + if (processedSize) + *processedSize = realProcessedSize; + data = (Byte *)data + cur; + size -= cur; + _rem -= cur; + if (_rem == 0) + { + const CItem &item = (*_items)[_itemIndex]; + _itemIndex = item.NextItem; + if (!_hash.Check(item, NULL)) // RAR doesn't use MAC here + CrcIsOK = false; + _stream = NULL; + } + if (res != S_OK) + return res; + if (realProcessedSize != 0) + return S_OK; + if (cur == 0 && num != 0) + return S_OK; + } + } + + return S_OK; +} + + +static int FindLinkBuf(CObjectVector &linkFiles, unsigned index) +{ + unsigned left = 0, right = linkFiles.Size(); + for (;;) + { + if (left == right) + return -1; + const unsigned mid = (left + right) / 2; + const unsigned linkIndex = linkFiles[mid].Index; + if (index == linkIndex) + return (int)mid; + if (index < linkIndex) + right = mid; + else + left = mid + 1; + } +} + + +static inline int DecoderRes_to_OpRes(HRESULT res, bool crcOK) +{ + if (res == E_NOTIMPL) + return NExtract::NOperationResult::kUnsupportedMethod; + // if (res == S_FALSE) + if (res != S_OK) + return NExtract::NOperationResult::kDataError; + return crcOK ? + NExtract::NOperationResult::kOK : + NExtract::NOperationResult::kCRCError; +} + + +static HRESULT CopyData_with_Progress(const Byte *data, size_t size, + ISequentialOutStream *outStream, ICompressProgressInfo *progress) +{ + UInt64 pos64 = 0; + while (size) + { + const UInt32 kStepSize = (UInt32)1 << 24; + UInt32 cur = kStepSize; + if (cur > size) + cur = (UInt32)size; + RINOK(outStream->Write(data, cur, &cur)) + if (cur == 0) + return E_FAIL; + size -= cur; + data += cur; + pos64 += cur; + if (progress) + { + RINOK(progress->SetRatioInfo(&pos64, &pos64)) + } + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = (UInt32)_refs.Size(); + if (numItems == 0) + return S_OK; + + CByteArr extractStatuses(_refs.Size()); + memset(extractStatuses, 0, _refs.Size()); + + // we don't want to use temp buffer for big link files. + const size_t k_CopyLinkFile_MaxSize = (size_t)1 << (28 + sizeof(size_t) / 2); + + const Byte kStatus_Extract = 1 << 0; + const Byte kStatus_Skip = 1 << 1; + const Byte kStatus_Link = 1 << 2; + + /* + In original RAR: + 1) service streams are not allowed to be solid, + and solid flag must be ignored for service streams. + 2) If RAR creates new solid block and first file in solid block is Link file, + then it can clear solid flag for Link file and + clear solid flag for first non-Link file after Link file. + */ + + CObjectVector linkFiles; + + { + UInt64 total = 0; + bool isThereUndefinedSize = false; + bool thereAreLinks = false; + { + unsigned solidLimit = 0; + for (UInt32 t = 0; t < numItems; t++) + { + const unsigned index = (unsigned)(allFilesMode ? t : indices[t]); + const CRefItem &ref = _refs[index]; + const CItem &item = _items[ref.Item]; + const CItem &lastItem = _items[ref.Last]; + + extractStatuses[index] |= kStatus_Extract; + + if (!lastItem.Is_UnknownSize()) + total += lastItem.Size; + else + isThereUndefinedSize = true; + + if (ref.Link >= 0) + { + // 18.06 fixed: we use links for Test mode too + // if (!testMode) + { + if ((unsigned)ref.Link < index) + { + const CRefItem &linkRef = _refs[(unsigned)ref.Link]; + const CItem &linkItem = _items[linkRef.Item]; + if (linkItem.IsSolid()) + if (testMode || linkItem.Size <= k_CopyLinkFile_MaxSize) + { + if (extractStatuses[(unsigned)ref.Link] == 0) + { + const CItem &lastLinkItem = _items[linkRef.Last]; + if (!lastLinkItem.Is_UnknownSize()) + total += lastLinkItem.Size; + else + isThereUndefinedSize = true; + } + extractStatuses[(unsigned)ref.Link] |= kStatus_Link; + thereAreLinks = true; + } + } + } + continue; + } + + if (item.IsService()) + continue; + + if (item.IsSolid()) + { + unsigned j = index; + + while (j > solidLimit) + { + j--; + const CRefItem &ref2 = _refs[j]; + const CItem &item2 = _items[ref2.Item]; + if (!item2.IsService()) + { + if (extractStatuses[j] == 0) + { + const CItem &lastItem2 = _items[ref2.Last]; + if (!lastItem2.Is_UnknownSize()) + total += lastItem2.Size; + else + isThereUndefinedSize = true; + } + extractStatuses[j] |= kStatus_Skip; + if (!item2.IsSolid()) + break; + } + } + } + + solidLimit = index + 1; + } + } + + if (thereAreLinks) + { + unsigned solidLimit = 0; + + FOR_VECTOR (i, _refs) + { + if ((extractStatuses[i] & kStatus_Link) == 0) + continue; + + // We use CLinkFile for testMode too. + // So we can show errors for copy files. + // if (!testMode) + { + CLinkFile &linkFile = linkFiles.AddNew(); + linkFile.Index = i; + } + + const CItem &item = _items[_refs[i].Item]; + /* + if (item.IsService()) + continue; + */ + + if (item.IsSolid()) + { + unsigned j = i; + + while (j > solidLimit) + { + j--; + const CRefItem &ref2 = _refs[j]; + const CItem &item2 = _items[ref2.Item]; + if (!item2.IsService()) + { + if (extractStatuses[j] != 0) + break; + extractStatuses[j] = kStatus_Skip; + { + const CItem &lastItem2 = _items[ref2.Last]; + if (!lastItem2.Is_UnknownSize()) + total += lastItem2.Size; + else + isThereUndefinedSize = true; + } + if (!item2.IsSolid()) + break; + } + } + } + + solidLimit = i + 1; + } + + if (!testMode) + for (UInt32 t = 0; t < numItems; t++) + { + const unsigned index = (unsigned)(allFilesMode ? t : indices[t]); + const CRefItem &ref = _refs[index]; + + const int linkIndex = ref.Link; + if (linkIndex < 0 || (unsigned)linkIndex >= index) + continue; + const CItem &linkItem = _items[_refs[(unsigned)linkIndex].Item]; + if (!linkItem.IsSolid() || linkItem.Size > k_CopyLinkFile_MaxSize) + continue; + const int bufIndex = FindLinkBuf(linkFiles, (unsigned)linkIndex); + if (bufIndex < 0) + return E_FAIL; + linkFiles[bufIndex].NumLinks++; + } + } + + if (total != 0 || !isThereUndefinedSize) + { + RINOK(extractCallback->SetTotal(total)) + } + } + + + + // ---------- MEMORY REQUEST ---------- + { + UInt64 dictMaxSize = 0; + for (UInt32 i = 0; i < _refs.Size(); i++) + { + if (extractStatuses[i] == 0) + continue; + const CRefItem &ref = _refs[i]; + const CItem &item = _items[ref.Item]; +/* + if (!item.IsDir() && !item.IsService() && item.NeedUse_as_CopyLink()) + { + } +*/ + const unsigned algo = item.Get_AlgoVersion_RawBits(); + if (!item.IsDir() && algo < Z7_ARRAY_SIZE(_methodMasks)) + { + const UInt64 d = item.Get_DictSize64(); + if (dictMaxSize < d) + dictMaxSize = d; + } + } + // we use callback, if dict exceeds (1 GB), because + // client code can set low limit (1 GB) for allowed memory usage. + const UInt64 k_MemLimit_for_Callback = (UInt64)1 << 30; + if (dictMaxSize > (_memUsage_WasSet ? + _memUsage_Decompress : k_MemLimit_for_Callback)) + { + { + CMyComPtr requestMem; + extractCallback->QueryInterface(IID_IArchiveRequestMemoryUseCallback, (void **)&requestMem); + if (!requestMem) + { + if (_memUsage_WasSet) + return E_OUTOFMEMORY; + } + else + { + UInt64 allowedSize = _memUsage_WasSet ? + _memUsage_Decompress : + (UInt64)1 << 32; // 4 GB is default allowed limit for RAR7 + + const UInt32 flags = (_memUsage_WasSet ? + NRequestMemoryUseFlags::k_AllowedSize_WasForced | + NRequestMemoryUseFlags::k_MLimit_Exceeded : + (dictMaxSize > allowedSize) ? + NRequestMemoryUseFlags::k_DefaultLimit_Exceeded: + 0) + | NRequestMemoryUseFlags::k_SkipArc_IsExpected + // | NRequestMemoryUseFlags::k_NoErrorMessage // for debug + ; + + // we set "Allow" for default case, if requestMem doesn't process anything. + UInt32 answerFlags = + (_memUsage_WasSet && dictMaxSize > allowedSize) ? + NRequestMemoryAnswerFlags::k_Limit_Exceeded + | NRequestMemoryAnswerFlags::k_SkipArc + : NRequestMemoryAnswerFlags::k_Allow; + + RINOK(requestMem->RequestMemoryUse( + flags, + NEventIndexType::kNoIndex, + // NEventIndexType::kInArcIndex, // for debug + 0, // index + NULL, // path + dictMaxSize, &allowedSize, &answerFlags)) + if ( (answerFlags & NRequestMemoryAnswerFlags::k_Allow) == 0 + || (answerFlags & NRequestMemoryAnswerFlags::k_Stop) + || (answerFlags & NRequestMemoryAnswerFlags::k_SkipArc) + ) + { + return E_OUTOFMEMORY; + } +/* + if ((answerFlags & NRequestMemoryAnswerFlags::k_AskForBigFile) == 0 && + (answerFlags & NRequestMemoryAnswerFlags::k_ReportForBigFile) == 0) + { + // requestMem.Release(); + } +*/ + } + } + } + } + + + + // ---------- UNPACK ---------- + + UInt64 totalUnpacked = 0; + UInt64 totalPacked = 0; + UInt64 curUnpackSize; + UInt64 curPackSize; + + CUnpacker unpacker; + unpacker.NeedCrc = _needChecksumCheck; + CMyComPtr2_Create volsInStream; + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + +/* + bool prevSolidWasSkipped = false; + UInt64 solidDictSize_Skip = 0; +*/ + + for (unsigned i = 0;; i++, + totalUnpacked += curUnpackSize, + totalPacked += curPackSize) + { + lps->InSize = totalPacked; + lps->OutSize = totalUnpacked; + RINOK(lps->SetCur()) + { + const unsigned num = _refs.Size(); + if (i >= num) + break; + for (;;) + { + if (extractStatuses[i] != 0) + break; + i++; + if (i >= num) + break; + } + if (i >= num) + break; + } + curUnpackSize = 0; + curPackSize = 0; + + // isExtract means that we don't skip that item. So we need read data. + const bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0); + Int32 askMode = + isExtract ? (testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + + unpacker.linkFile = NULL; + + // if (!testMode) + if ((extractStatuses[i] & kStatus_Link) != 0) + { + const int bufIndex = FindLinkBuf(linkFiles, i); + if (bufIndex < 0) + return E_FAIL; + unpacker.linkFile = &linkFiles[bufIndex]; + } + + const unsigned index = i; + const CRefItem *ref = &_refs[index]; + const CItem *item = &_items[ref->Item]; + const CItem &lastItem = _items[ref->Last]; + + curUnpackSize = 0; + if (!lastItem.Is_UnknownSize()) + curUnpackSize = lastItem.Size; + + curPackSize = GetPackSize(index); + + bool isSolid = false; + if (!item->IsService()) + { + if (item->IsSolid()) + isSolid = unpacker.SolidAllowed; + unpacker.SolidAllowed = isSolid; + } + + + // ----- request mem ----- +/* + // link files are complicated cases. (ref->Link >= 0) + // link file can refer to non-solid file that can have big dictionary + // link file can refer to solid files that requres buffer + if (!item->IsDir() && requestMem && ref->Link < 0) + { + bool needSkip = false; + if (isSolid) + needSkip = prevSolidWasSkipped; + else + { + // isSolid == false + const unsigned algo = item->Get_AlgoVersion_RawBits(); + // const unsigned m = item.Get_Method(); + if (algo < Z7_ARRAY_SIZE(_methodMasks)) + { + solidDictSize_Skip = item->Get_DictSize64(); + if (solidDictSize_Skip > allowedSize) + needSkip = true; + } + } + if (needSkip) + { + UInt32 answerFlags = 0; + UInt64 allowedSize_File = allowedSize; + RINOK(requestMem->RequestMemoryUse( + NRequestMemoryUseFlags::k_Limit_Exceeded | + NRequestMemoryUseFlags::k_IsReport, + NEventIndexType::kInArcIndex, + index, + NULL, // path + solidDictSize_Skip, &allowedSize_File, &answerFlags)) + if (!item->IsService()) + prevSolidWasSkipped = true; + continue; + } + } + if (!item->IsService() && item->IsDir()) + prevSolidWasSkipped = false; +*/ + + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream((UInt32)index, &realOutStream, askMode)) + + if (item->IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const int index2 = ref->Link; + + int bufIndex = -1; + + if (index2 >= 0) + { + const CRefItem &ref2 = _refs[index2]; + const CItem &item2 = _items[ref2.Item]; + const CItem &lastItem2 = _items[ref2.Last]; + if (!item2.IsSolid()) + { + item = &item2; + ref = &ref2; + if (!lastItem2.Is_UnknownSize()) + curUnpackSize = lastItem2.Size; + else + curUnpackSize = 0; + curPackSize = GetPackSize((unsigned)index2); + } + else + { + if ((unsigned)index2 < index) + bufIndex = FindLinkBuf(linkFiles, (unsigned)index2); + } + } + + bool needCallback = true; + + if (!realOutStream) + { + if (testMode) + { + if (item->NeedUse_as_CopyLink_or_HardLink()) + { + Int32 opRes = NExtract::NOperationResult::kOK; + if (bufIndex >= 0) + { + const CLinkFile &linkFile = linkFiles[bufIndex]; + opRes = DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK); + } + + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(opRes)) + continue; + } + } + else + { + if (item->IsService()) + continue; + + needCallback = false; + + if (!item->NeedUse_as_HardLink()) + if (index2 < 0) + + for (unsigned n = i + 1; n < _refs.Size(); n++) + { + const CItem &nextItem = _items[_refs[n].Item]; + if (nextItem.IsService()) + continue; + if (!nextItem.IsSolid()) + break; + if (extractStatuses[i] != 0) + { + needCallback = true; + break; + } + } + + askMode = NExtract::NAskMode::kSkip; + } + } + + if (needCallback) + { + RINOK(extractCallback->PrepareOperation(askMode)) + } + + if (bufIndex >= 0) + { + CLinkFile &linkFile = linkFiles[bufIndex]; + + if (isExtract) + { + if (linkFile.NumLinks == 0) + return E_FAIL; + + if (needCallback) + if (realOutStream) + { + RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, lps)) + } + + if (--linkFile.NumLinks == 0) + linkFile.Data.Free(); + } + + if (needCallback) + { + RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))) + } + continue; + } + + if (!needCallback) + continue; + + if (item->NeedUse_as_CopyLink()) + { + const int opRes = realOutStream ? + NExtract::NOperationResult::kUnsupportedMethod: + NExtract::NOperationResult::kOK; + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)) + continue; + } + + volsInStream->Init(&_arcs, &_items, ref->Item); + + const UInt64 packSize = curPackSize; + + if (item->IsEncrypted()) + if (!unpacker.getTextPassword) + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&unpacker.getTextPassword); + + bool wrongPassword; + HRESULT result = unpacker.Create(EXTERNAL_CODECS_VARS *item, isSolid, wrongPassword); + + if (wrongPassword) + { + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kWrongPassword)) + continue; + } + + bool crcOK = true; + if (result == S_OK) + result = unpacker.Code(*item, _items[ref->Last], packSize, volsInStream, realOutStream, lps, crcOK); + realOutStream.Release(); + if (!volsInStream->CrcIsOK) + crcOK = false; + + int opRes = crcOK ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError; + + if (result != S_OK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else if (result == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + return result; + } + + RINOK(extractCallback->SetOperationResult(opRes)) + } + + { + FOR_VECTOR (k, linkFiles) + if (linkFiles[k].NumLinks != 0) + return E_FAIL; + } + + return S_OK; + COM_TRY_END +} + + +CHandler::CHandler() +{ + InitDefaults(); +} + +void CHandler::InitDefaults() +{ + _needChecksumCheck = true; + _memUsage_WasSet = false; + _memUsage_Decompress = (UInt64)1 << 32; +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + InitDefaults(); + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + } + else if (name.IsPrefixedBy_Ascii_NoCase("memx")) + { + size_t memAvail; + if (!NWindows::NSystem::GetRamSize(memAvail)) + memAvail = (size_t)sizeof(size_t) << 28; + UInt64 v; + if (!ParseSizeString(name.Ptr(4), prop, memAvail, v)) + return E_INVALIDARG; + _memUsage_Decompress = v; + _memUsage_WasSet = true; + } + else if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 1; + RINOK(ParsePropToUInt32(name, prop, crcSize)) + _needChecksumCheck = (crcSize != 0); + } + else + { + return E_INVALIDARG; + } + } + return S_OK; +} + + +IMPL_ISetCompressCodecsInfo + +REGISTER_ARC_I( + "Rar5", "rar r00", NULL, 0xCC, + kMarker, + 0, + NArcInfoFlags::kFindSignature, + NULL) + +}} + + +Z7_CLASS_IMP_COM_2( + CBlake2spHasher + , IHasher + , ICompressSetCoderProperties +) + CAlignedBuffer1 _buf; + // CBlake2sp _blake; + #define Z7_BLACK2S_ALIGN_OBJECT_OFFSET 0 + CBlake2sp *Obj() { return (CBlake2sp *)(void *)((Byte *)_buf + Z7_BLACK2S_ALIGN_OBJECT_OFFSET); } +public: + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + CBlake2spHasher(): + _buf(sizeof(CBlake2sp) + Z7_BLACK2S_ALIGN_OBJECT_OFFSET) + { + Blake2sp_SetFunction(Obj(), 0); + Blake2sp_InitState(Obj()); + } +}; + +Z7_COM7F_IMF2(void, CBlake2spHasher::Init()) +{ + Blake2sp_InitState(Obj()); +} + +Z7_COM7F_IMF2(void, CBlake2spHasher::Update(const void *data, UInt32 size)) +{ +#if 1 + Blake2sp_Update(Obj(), (const Byte *)data, (size_t)size); +#else + // for debug: + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 800; + // UInt32 size2 = size / 2; + if (size2 == 0) + size2 = 1; + Blake2sp_Update(Obj(), (const Byte *)data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +#endif +} + +Z7_COM7F_IMF2(void, CBlake2spHasher::Final(Byte *digest)) +{ + Blake2sp_Final(Obj(), digest); +} + +Z7_COM7F_IMF(CBlake2spHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + /* + if (prop.ulVal > Z7_BLAKE2S_ALGO_MAX) + return E_NOTIMPL; + */ + algo = (unsigned)prop.ulVal; + } + } + if (!Blake2sp_SetFunction(Obj(), algo)) + return E_NOTIMPL; + return S_OK; +} + +REGISTER_HASHER(CBlake2spHasher, 0x202, "BLAKE2sp", Z7_BLAKE2S_DIGEST_SIZE) + +static struct CBlake2sp_Prepare { CBlake2sp_Prepare() { z7_Black2sp_Prepare(); } } g_Blake2sp_Prepare; diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/Rar5Handler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/Rar5Handler.h 2015-11-06 12:02:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/Rar5Handler.h 2025-06-16 10:00:00.000000000 +0000 @@ -1,411 +1,527 @@ -// Rar5Handler.h - -#ifndef __RAR5_HANDLER_H -#define __RAR5_HANDLER_H - -#include "../../../../C/Blake2.h" - -#include "../../../Common/MyBuffer.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Common/CreateCoder.h" - -#include "../IArchive.h" - -namespace NArchive { -namespace NRar5 { - -namespace NHeaderFlags -{ - const unsigned kExtra = 1 << 0; - const unsigned kData = 1 << 1; - // const unsigned kUnknown = 1 << 2; - const unsigned kPrevVol = 1 << 3; - const unsigned kNextVol = 1 << 4; - // const unsigned kIsChild = 1 << 5; - // const unsigned kPreserveChild = 1 << 6; -} - -namespace NHeaderType -{ - enum - { - kArc = 1, - kFile, - kService, - kArcEncrypt, - kEndOfArc - }; -} - -namespace NArcFlags -{ - const unsigned kVol = 1 << 0; - const unsigned kVolNumber = 1 << 1; - const unsigned kSolid = 1 << 2; - // const unsigned kRecovery = 1 << 3; - // const unsigned kLocked = 1 << 4; -} - -const unsigned kArcExtraRecordType_Locator = 1; - -namespace NLocatorFlags -{ - const unsigned kQuickOpen = 1 << 0; - const unsigned kRecovery = 1 << 1; -} - -namespace NFileFlags -{ - const unsigned kIsDir = 1 << 0; - const unsigned kUnixTime = 1 << 1; - const unsigned kCrc32 = 1 << 2; - const unsigned kUnknownSize = 1 << 3; -} - -namespace NMethodFlags -{ - // const unsigned kVersionMask = 0x3F; - const unsigned kSolid = 1 << 6; -} - -namespace NArcEndFlags -{ - const unsigned kMoreVols = 1 << 0; -} - -enum EHostOS -{ - kHost_Windows = 0, - kHost_Unix -}; - - - -// ---------- Extra ---------- - -namespace NExtraRecordType -{ - enum - { - kCrypto = 1, - kHash, - kTime, - kVersion, - kLink, - kUnixOwner, - kSubdata - }; -} - -// const unsigned kCryptoAlgo_AES = 0; - -namespace NCryptoFlags -{ - const unsigned kPswCheck = 1 << 0; - const unsigned kUseMAC = 1 << 1; -} - -struct CCryptoInfo -{ - UInt64 Algo; - UInt64 Flags; - Byte Cnt; - - bool UseMAC() const { return (Flags & NCryptoFlags::kUseMAC) != 0; } - bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; } - bool Parse(const Byte *p, size_t size); -}; - -const unsigned kHashID_Blake2sp = 0; - -namespace NTimeRecord -{ - enum - { - k_Index_MTime = 0, - k_Index_CTime, - k_Index_ATime - }; - - namespace NFlags - { - const unsigned kUnixTime = 1 << 0; - const unsigned kMTime = 1 << 1; - // const unsigned kCTime = 1 << 2; - // const unsigned kATime = 1 << 3; - } -} - -namespace NLinkType -{ - enum - { - kUnixSymLink = 1, - kWinSymLink, - kWinJunction, - kHardLink, - kFileCopy - }; -} - -namespace NLinkFlags -{ - const unsigned kTargetIsDir = 1 << 0; -} - - -struct CItem -{ - UInt32 CommonFlags; - UInt32 Flags; - - Byte RecordType; - bool Version_Defined; - - int ACL; - - AString Name; - - int VolIndex; - int NextItem; - - UInt32 UnixMTime; - UInt32 CRC; - UInt32 Attrib; - UInt32 Method; - - CByteBuffer Extra; - - UInt64 Size; - UInt64 PackSize; - UInt64 HostOS; - - UInt64 DataPos; - UInt64 Version; - - CItem() { Clear(); } - - void Clear() - { - CommonFlags = 0; - Flags = 0; - - VolIndex = 0; - NextItem = -1; - - Version_Defined = false; - Version = 0; - - Name.Empty(); - Extra.Free(); - ACL = -1; - } - - bool IsSplitBefore() const { return (CommonFlags & NHeaderFlags::kPrevVol) != 0; } - bool IsSplitAfter() const { return (CommonFlags & NHeaderFlags::kNextVol) != 0; } - bool IsSplit() const { return (CommonFlags & (NHeaderFlags::kPrevVol | NHeaderFlags::kNextVol)) != 0; } - - bool IsDir() const { return (Flags & NFileFlags::kIsDir) != 0; } - bool Has_UnixMTime() const { return (Flags & NFileFlags::kUnixTime) != 0; } - bool Has_CRC() const { return (Flags & NFileFlags::kCrc32) != 0; } - bool Is_UnknownSize() const { return (Flags & NFileFlags::kUnknownSize) != 0; } - - bool IsNextForItem(const CItem &prev) const - { - return !IsDir() && !prev.IsDir() && IsSplitBefore() && prev.IsSplitAfter() && (Name == prev.Name); - // && false; - } - - bool IsSolid() const { return ((UInt32)Method & NMethodFlags::kSolid) != 0; } - unsigned GetAlgoVersion() const { return (unsigned)Method & 0x3F; } - unsigned GetMethod() const { return ((unsigned)Method >> 7) & 0x7; } - UInt32 GetDictSize() const { return (((UInt32)Method >> 10) & 0xF); } - - bool IsService() const { return RecordType == NHeaderType::kService; } - - bool Is_STM() const { return IsService() && Name == "STM"; } - bool Is_CMT() const { return IsService() && Name == "CMT"; } - bool Is_ACL() const { return IsService() && Name == "ACL"; } - // bool Is_QO() const { return IsService() && Name == "QO"; } - - int FindExtra(unsigned type, unsigned &recordDataSize) const; - - bool IsEncrypted() const - { - unsigned size; - return FindExtra(NExtraRecordType::kCrypto, size) >= 0; - } - - int FindExtra_Blake() const - { - unsigned size = 0; - int offset = FindExtra(NExtraRecordType::kHash, size); - if (offset >= 0 - && size == BLAKE2S_DIGEST_SIZE + 1 - && Extra[(unsigned)offset] == kHashID_Blake2sp) - return offset + 1; - return -1; - } - - bool FindExtra_Version(UInt64 &version) const; - - struct CLinkInfo - { - UInt64 Type; - UInt64 Flags; - unsigned NameOffset; - unsigned NameLen; - }; - - bool FindExtra_Link(CLinkInfo &link) const; - void Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const; - bool Is_CopyLink() const; - - bool NeedUse_as_CopyLink() const { return PackSize == 0 && Is_CopyLink(); } - - bool GetAltStreamName(AString &name) const; - - UInt32 GetWinAttrib() const - { - UInt32 a; - switch (HostOS) - { - case kHost_Windows: a = Attrib; break; - case kHost_Unix: a = (Attrib << 16); break; - default: a = 0; - } - // if (IsDir()) a |= FILE_ATTRIBUTE_DIRECTORY; - return a; - } - - UInt64 GetDataPosition() const { return DataPos; } -}; - - -struct CInArcInfo -{ - UInt64 Flags; - UInt64 VolNumber; - UInt64 StartPos; - UInt64 EndPos; - - UInt64 EndFlags; - bool EndOfArchive_was_Read; - - bool IsEncrypted; - - // CByteBuffer Extra; - - /* - struct CLocator - { - UInt64 Flags; - UInt64 QuickOpen; - UInt64 Recovery; - - bool Is_QuickOpen() const { return (Flags & NLocatorFlags::kQuickOpen) != 0; } - bool Is_Recovery() const { return (Flags & NLocatorFlags::kRecovery) != 0; } - }; - - int FindExtra(unsigned type, unsigned &recordDataSize) const; - bool FindExtra_Locator(CLocator &locator) const; - */ - - CInArcInfo(): - Flags(0), - VolNumber(0), - StartPos(0), - EndPos(0), - EndFlags(0), - EndOfArchive_was_Read(false), - IsEncrypted(false) - {} - - /* - void Clear() - { - Flags = 0; - VolNumber = 0; - StartPos = 0; - EndPos = 0; - EndFlags = 0; - EndOfArchive_was_Read = false; - Extra.Free(); - } - */ - - UInt64 GetPhySize() const { return EndPos - StartPos; } - - bool AreMoreVolumes() const { return (EndFlags & NArcEndFlags::kMoreVols) != 0; } - - bool IsVolume() const { return (Flags & NArcFlags::kVol) != 0; } - bool IsSolid() const { return (Flags & NArcFlags::kSolid) != 0; } - bool Is_VolNumber_Defined() const { return (Flags & NArcFlags::kVolNumber) != 0; } - - UInt64 GetVolIndex() const { return Is_VolNumber_Defined() ? VolNumber : 0; } -}; - - -struct CRefItem -{ - unsigned Item; - unsigned Last; - int Parent; - int Link; -}; - - -struct CArc -{ - CMyComPtr Stream; - CInArcInfo Info; -}; - - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - PUBLIC_ISetCompressCodecsInfo - public CMyUnknownImp -{ -public: - CRecordVector _refs; - CObjectVector _items; -private: - CObjectVector _arcs; - CObjectVector _acls; - - UInt32 _errorFlags; - // UInt32 _warningFlags; - bool _isArc; - CByteBuffer _comment; - UString _missingVolName; - - DECL_EXTERNAL_CODECS_VARS - - UInt64 GetPackSize(unsigned refIndex) const; - - void FillLinks(); - - HRESULT Open2(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback); - -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - - DECL_ISetCompressCodecsInfo -}; - -}} - -#endif +// Rar5Handler.h + +#ifndef ZIP7_INC_RAR5_HANDLER_H +#define ZIP7_INC_RAR5_HANDLER_H + +#include "../../../../C/Blake2.h" + +#include "../../../Common/MyBuffer.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../Common/CreateCoder.h" + +#include "../IArchive.h" + +namespace NArchive { +namespace NRar5 { + +namespace NHeaderFlags +{ + const unsigned kExtra = 1 << 0; + const unsigned kData = 1 << 1; + // const unsigned kUnknown = 1 << 2; + const unsigned kPrevVol = 1 << 3; + const unsigned kNextVol = 1 << 4; + // const unsigned kIsChild = 1 << 5; + // const unsigned kPreserveChild = 1 << 6; +} + +namespace NHeaderType +{ + enum + { + kArc = 1, + kFile, + kService, + kArcEncrypt, + kEndOfArc + }; +} + +namespace NArcFlags +{ + const unsigned kVol = 1 << 0; + const unsigned kVolNumber = 1 << 1; + const unsigned kSolid = 1 << 2; + // const unsigned kRecovery = 1 << 3; + // const unsigned kLocked = 1 << 4; +} + +const unsigned kArcExtraRecordType_Locator = 1; +const unsigned kArcExtraRecordType_Metadata = 2; + +namespace NLocatorFlags +{ + const unsigned kQuickOpen = 1 << 0; + const unsigned kRecovery = 1 << 1; +} + +namespace NMetadataFlags +{ + const unsigned kArcName = 1 << 0; + const unsigned kCTime = 1 << 1; + const unsigned kUnixTime = 1 << 2; + const unsigned kNanoSec = 1 << 3; +} + +namespace NFileFlags +{ + const unsigned kIsDir = 1 << 0; + const unsigned kUnixTime = 1 << 1; + const unsigned kCrc32 = 1 << 2; + const unsigned kUnknownSize = 1 << 3; +} + +namespace NMethodFlags +{ + // const unsigned kVersionMask = 0x3F; + const unsigned kSolid = 1 << 6; + const unsigned kRar5_Compat = 1u << 20; +} + +namespace NArcEndFlags +{ + const unsigned kMoreVols = 1 << 0; +} + +enum EHostOS +{ + kHost_Windows = 0, + kHost_Unix +}; + + + +// ---------- Extra ---------- + +namespace NExtraID +{ + enum + { + kCrypto = 1, + kHash, + kTime, + kVersion, + kLink, + kUnixOwner, + kSubdata + }; +} + +const unsigned kCryptoAlgo_AES = 0; + +namespace NCryptoFlags +{ + const unsigned kPswCheck = 1 << 0; + const unsigned kUseMAC = 1 << 1; +} + +struct CCryptoInfo +{ + UInt64 Algo; + UInt64 Flags; + Byte Cnt; + + bool UseMAC() const { return (Flags & NCryptoFlags::kUseMAC) != 0; } + bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; } + bool Parse(const Byte *p, size_t size); +}; + +const unsigned kHashID_Blake2sp = 0; + +namespace NTimeRecord +{ + enum + { + k_Index_MTime = 0, + k_Index_CTime, + k_Index_ATime + }; + + namespace NFlags + { + const unsigned kUnixTime = 1 << 0; + const unsigned kMTime = 1 << 1; + const unsigned kCTime = 1 << 2; + const unsigned kATime = 1 << 3; + const unsigned kUnixNs = 1 << 4; + } +} + +namespace NLinkType +{ + enum + { + kUnixSymLink = 1, + kWinSymLink, + kWinJunction, + kHardLink, + kFileCopy + }; +} + +namespace NLinkFlags +{ + const unsigned kTargetIsDir = 1 << 0; +} + + +struct CLinkInfo +{ + UInt64 Type; + UInt64 Flags; + unsigned NameOffset; + unsigned NameLen; + + bool Parse(const Byte *p, unsigned size); +}; + + +struct CItem +{ + UInt32 CommonFlags; + UInt32 Flags; + + Byte RecordType; + bool Version_Defined; + + int ACL; + + AString Name; + + unsigned VolIndex; + int NextItem; // in _items{} + + UInt32 UnixMTime; + UInt32 CRC; + UInt32 Attrib; + UInt32 Method; + + CByteBuffer Extra; + + UInt64 Size; + UInt64 PackSize; + UInt64 HostOS; + + UInt64 DataPos; + UInt64 Version; + + CItem() { Clear(); } + + void Clear() + { + // CommonFlags = 0; + // Flags = 0; + + // UnixMTime = 0; + // CRC = 0; + + VolIndex = 0; + NextItem = -1; + + Version_Defined = false; + Version = 0; + + Name.Empty(); + Extra.Free(); + ACL = -1; + } + + bool IsSplitBefore() const { return (CommonFlags & NHeaderFlags::kPrevVol) != 0; } + bool IsSplitAfter() const { return (CommonFlags & NHeaderFlags::kNextVol) != 0; } + bool IsSplit() const { return (CommonFlags & (NHeaderFlags::kPrevVol | NHeaderFlags::kNextVol)) != 0; } + + bool IsDir() const { return (Flags & NFileFlags::kIsDir) != 0; } + bool Has_UnixMTime() const { return (Flags & NFileFlags::kUnixTime) != 0; } + bool Has_CRC() const { return (Flags & NFileFlags::kCrc32) != 0; } + bool Is_UnknownSize() const { return (Flags & NFileFlags::kUnknownSize) != 0; } + + bool IsNextForItem(const CItem &prev) const + { + return !IsDir() && !prev.IsDir() && IsSplitBefore() && prev.IsSplitAfter() && (Name == prev.Name); + // && false; + } + + // rar docs: Solid flag can be set only for file headers and is never set for service headers. + bool IsSolid() const { return ((UInt32)Method & NMethodFlags::kSolid) != 0; } + bool Is_Rar5_Compat() const { return ((UInt32)Method & NMethodFlags::kRar5_Compat) != 0; } + unsigned Get_Rar5_CompatBit() const { return ((UInt32)Method >> 20) & 1; } + + unsigned Get_AlgoVersion_RawBits() const { return (unsigned)Method & 0x3F; } + unsigned Get_AlgoVersion_HuffRev() const + { + unsigned w = (unsigned)Method & 0x3F; + if (w == 1 && Is_Rar5_Compat()) + w = 0; + return w; + } + unsigned Get_Method() const { return ((unsigned)Method >> 7) & 0x7; } + + unsigned Get_DictSize_Main() const + { return ((UInt32)Method >> 10) & (Get_AlgoVersion_RawBits() == 0 ? 0xf : 0x1f); } + unsigned Get_DictSize_Frac() const + { + // original-unrar ignores Frac, if (algo==0) (rar5): + if (Get_AlgoVersion_RawBits() == 0) + return 0; + return ((UInt32)Method >> 15) & 0x1f; + } + UInt64 Get_DictSize64() const + { + // ver 6.* check + // return (((UInt32)Method >> 10) & 0xF); + UInt64 winSize = 0; + const unsigned algo = Get_AlgoVersion_RawBits(); + if (algo <= 1) + { + UInt32 w = 32; + if (algo == 1) + w += Get_DictSize_Frac(); + winSize = (UInt64)w << (12 + Get_DictSize_Main()); + } + return winSize; + } + + + bool IsService() const { return RecordType == NHeaderType::kService; } + + bool Is_STM() const { return IsService() && Name.IsEqualTo("STM"); } + bool Is_CMT() const { return IsService() && Name.IsEqualTo("CMT"); } + bool Is_ACL() const { return IsService() && Name.IsEqualTo("ACL"); } + // bool Is_QO() const { return IsService() && Name.IsEqualTo("QO"); } + + int FindExtra(unsigned extraID, unsigned &recordDataSize) const; + void PrintInfo(AString &s) const; + + + bool IsEncrypted() const + { + unsigned size; + return FindExtra(NExtraID::kCrypto, size) >= 0; + } + + int FindExtra_Blake() const + { + unsigned size = 0; + const int offset = FindExtra(NExtraID::kHash, size); + if (offset >= 0 + && size == Z7_BLAKE2S_DIGEST_SIZE + 1 + && Extra[(unsigned)offset] == kHashID_Blake2sp) + return offset + 1; + return -1; + } + + bool FindExtra_Version(UInt64 &version) const; + + bool FindExtra_Link(CLinkInfo &link) const; + void Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop) const; + bool Is_CopyLink() const; + bool Is_HardLink() const; + bool Is_CopyLink_or_HardLink() const; + + bool NeedUse_as_CopyLink() const { return PackSize == 0 && Is_CopyLink(); } + bool NeedUse_as_HardLink() const { return PackSize == 0 && Is_HardLink(); } + bool NeedUse_as_CopyLink_or_HardLink() const { return PackSize == 0 && Is_CopyLink_or_HardLink(); } + + bool GetAltStreamName(AString &name) const; + + UInt32 GetWinAttrib() const + { + UInt32 a; + switch (HostOS) + { + case kHost_Windows: + a = Attrib; + break; + case kHost_Unix: + a = Attrib << 16; + a |= 0x8000; // add posix mode marker + break; + default: + a = 0; + } + if (IsDir()) a |= FILE_ATTRIBUTE_DIRECTORY; + return a; + } + + UInt64 GetDataPosition() const { return DataPos; } +}; + + +struct CInArcInfo +{ + UInt64 Flags; + UInt64 VolNumber; + UInt64 StartPos; + UInt64 EndPos; + + UInt64 EndFlags; + bool EndOfArchive_was_Read; + + bool IsEncrypted; + bool Locator_Defined; + bool Locator_Error; + bool Metadata_Defined; + bool Metadata_Error; + bool UnknownExtraRecord; + bool Extra_Error; + bool UnsupportedFeature; + + struct CLocator + { + UInt64 Flags; + UInt64 QuickOpen; + UInt64 Recovery; + + bool Is_QuickOpen() const { return (Flags & NLocatorFlags::kQuickOpen) != 0; } + bool Is_Recovery() const { return (Flags & NLocatorFlags::kRecovery) != 0; } + + bool Parse(const Byte *p, size_t size); + CLocator(): + Flags(0), + QuickOpen(0), + Recovery(0) + {} + }; + + struct CMetadata + { + UInt64 Flags; + UInt64 CTime; + AString ArcName; + + bool Parse(const Byte *p, size_t size); + CMetadata(): + Flags(0), + CTime(0) + {} + }; + + CLocator Locator; + CMetadata Metadata; + + bool ParseExtra(const Byte *p, size_t size); + + CInArcInfo(): + Flags(0), + VolNumber(0), + StartPos(0), + EndPos(0), + EndFlags(0), + EndOfArchive_was_Read(false), + IsEncrypted(false), + Locator_Defined(false), + Locator_Error(false), + Metadata_Defined(false), + Metadata_Error(false), + UnknownExtraRecord(false), + Extra_Error(false), + UnsupportedFeature(false) + {} + + /* + void Clear() + { + Flags = 0; + VolNumber = 0; + StartPos = 0; + EndPos = 0; + EndFlags = 0; + EndOfArchive_was_Read = false; + } + */ + + UInt64 GetPhySize() const { return EndPos - StartPos; } + + bool AreMoreVolumes() const { return (EndFlags & NArcEndFlags::kMoreVols) != 0; } + + bool IsVolume() const { return (Flags & NArcFlags::kVol) != 0; } + bool IsSolid() const { return (Flags & NArcFlags::kSolid) != 0; } + bool Is_VolNumber_Defined() const { return (Flags & NArcFlags::kVolNumber) != 0; } + + UInt64 GetVolIndex() const { return Is_VolNumber_Defined() ? VolNumber : 0; } +}; + + +struct CRefItem +{ + unsigned Item; // First item in _items[] + unsigned Last; // Last item in _items[] + int Parent; // in _refs[], if alternate stream + int Link; // in _refs[] +}; + + +struct CArc +{ + CMyComPtr Stream; + CInArcInfo Info; +}; + + +class CHandler Z7_final: + public IInArchive, + public IArchiveGetRawProps, + public ISetProperties, + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(ISetProperties) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(ISetProperties) + DECL_ISetCompressCodecsInfo + + void InitDefaults(); + + bool _isArc; + bool _needChecksumCheck; + bool _memUsage_WasSet; + bool _comment_WasUsedInArc; + bool _acl_Used; + bool _error_in_ACL; + bool _split_Error; +public: + CRecordVector _refs; + CObjectVector _items; + + CHandler(); +private: + CObjectVector _arcs; + CObjectVector _acls; + + UInt32 _errorFlags; + // UInt32 _warningFlags; + + UInt32 _numBlocks; + unsigned _rar5comapt_mask; + unsigned _methodMasks[2]; + UInt64 _algo_Mask; + UInt64 _dictMaxSizes[2]; + + CByteBuffer _comment; + UString _missingVolName; + + UInt64 _memUsage_Decompress; + + DECL_EXTERNAL_CODECS_VARS + + UInt64 GetPackSize(unsigned refIndex) const; + + void FillLinks(); + + HRESULT Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHandler.cpp 2016-06-11 08:08:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -1,1755 +1,1782 @@ -// RarHandler.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/PropVariantUtils.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../IPassword.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/FilterCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/MethodId.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/RegisterArc.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "../../Crypto/Rar20Crypto.h" -#include "../../Crypto/RarAes.h" - -#include "../Common/FindSignature.h" -#include "../Common/ItemNameUtils.h" -#include "../Common/OutStreamWithCRC.h" - -#include "../HandlerCont.h" - -#include "RarVol.h" -#include "RarHandler.h" - -using namespace NWindows; - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) - -namespace NArchive { -namespace NRar { - -#define SIGNATURE { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 } - -static const Byte kMarker[NHeader::kMarkerSize] = SIGNATURE; - -const unsigned kPasswordLen_MAX = 127; - -bool CItem::IgnoreItem() const -{ - switch (HostOS) - { - case NHeader::NFile::kHostMSDOS: - case NHeader::NFile::kHostOS2: - case NHeader::NFile::kHostWin32: - return ((Attrib & NHeader::NFile::kLabelFileAttribute) != 0); - } - return false; -} - -bool CItem::IsDir() const -{ - if (GetDictSize() == NHeader::NFile::kDictDirectoryValue) - return true; - switch (HostOS) - { - case NHeader::NFile::kHostMSDOS: - case NHeader::NFile::kHostOS2: - case NHeader::NFile::kHostWin32: - if ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) - return true; - } - return false; -} - -UInt32 CItem::GetWinAttrib() const -{ - UInt32 a; - switch (HostOS) - { - case NHeader::NFile::kHostMSDOS: - case NHeader::NFile::kHostOS2: - case NHeader::NFile::kHostWin32: - a = Attrib; - break; - default: - a = 0; // must be converted from unix value; - } - if (IsDir()) - a |= NHeader::NFile::kWinFileDirectoryAttributeMask; - return a; -} - -static const char * const kHostOS[] = -{ - "MS DOS" - , "OS/2" - , "Win32" - , "Unix" - , "Mac OS" - , "BeOS" -}; - -static const char *kUnknownOS = "Unknown"; - -static const CUInt32PCharPair k_Flags[] = -{ - { 0, "Volume" }, - { 1, "Comment" }, - { 2, "Lock" }, - { 3, "Solid" }, - { 4, "NewVolName" }, // pack_comment in old versuons - { 5, "Authenticity" }, - { 6, "Recovery" }, - { 7, "BlockEncryption" }, - { 8, "FirstVolume" }, - { 9, "EncryptVer" } -}; - -enum EErrorType -{ - k_ErrorType_OK, - k_ErrorType_Corrupted, - k_ErrorType_UnexpectedEnd, - k_ErrorType_DecryptionError -}; - -class CInArchive -{ - IInStream *m_Stream; - UInt64 m_StreamStartPosition; - CBuffer _unicodeNameBuffer; - CByteBuffer _comment; - CByteBuffer m_FileHeaderData; - NHeader::NBlock::CBlock m_BlockHeader; - NCrypto::NRar3::CDecoder *m_RarAESSpec; - CMyComPtr m_RarAES; - CBuffer m_DecryptedData; - Byte *m_DecryptedDataAligned; - UInt32 m_DecryptedDataSize; - bool m_CryptoMode; - UInt32 m_CryptoPos; - - - HRESULT ReadBytesSpec(void *data, size_t *size); - bool ReadBytesAndTestSize(void *data, UInt32 size); - void ReadName(const Byte *p, unsigned nameSize, CItem &item); - bool ReadHeaderReal(const Byte *p, unsigned size, CItem &item); - - HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); - - void AddToSeekValue(UInt64 addValue) - { - m_Position += addValue; - } - - void FinishCryptoBlock() - { - if (m_CryptoMode) - while ((m_CryptoPos & 0xF) != 0) - { - m_CryptoPos++; - m_Position++; - } - } - -public: - UInt64 m_Position; - CInArcInfo ArcInfo; - bool HeaderErrorWarning; - - HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); - HRESULT GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPassword, - bool &filled, EErrorType &error); -}; - -static bool CheckHeaderCrc(const Byte *header, size_t headerSize) -{ - return Get16(header) == (UInt16)(CrcCalc(header + 2, headerSize - 2) & 0xFFFF); -} - -HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) -{ - HeaderErrorWarning = false; - m_CryptoMode = false; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileSize)); - RINOK(stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); - m_Position = m_StreamStartPosition; - - UInt64 arcStartPos = m_StreamStartPosition; - { - Byte marker[NHeader::kMarkerSize]; - RINOK(ReadStream_FALSE(stream, marker, NHeader::kMarkerSize)); - if (memcmp(marker, kMarker, NHeader::kMarkerSize) == 0) - m_Position += NHeader::kMarkerSize; - else - { - if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) - return S_FALSE; - RINOK(stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); - RINOK(FindSignatureInStream(stream, kMarker, NHeader::kMarkerSize, - searchHeaderSizeLimit, arcStartPos)); - m_Position = arcStartPos + NHeader::kMarkerSize; - RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); - } - } - Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1]; - - RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)); - AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); - - - UInt32 blockSize = Get16(buf + 5); - - ArcInfo.EncryptVersion = 0; - ArcInfo.Flags = Get16(buf + 3); - - UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize; - - /* - if (ArcInfo.IsThereEncryptVer()) - { - if (blockSize <= headerSize) - return S_FALSE; - RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1)); - AddToSeekValue(1); - ArcInfo.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize]; - headerSize += 1; - } - */ - - if (blockSize < headerSize - || buf[2] != NHeader::NBlockType::kArchiveHeader - || !CheckHeaderCrc(buf, headerSize)) - return S_FALSE; - - size_t commentSize = blockSize - headerSize; - _comment.Alloc(commentSize); - RINOK(ReadStream_FALSE(stream, _comment, commentSize)); - AddToSeekValue(commentSize); - m_Stream = stream; - ArcInfo.StartPos = arcStartPos; - return S_OK; -} - -HRESULT CInArchive::ReadBytesSpec(void *data, size_t *resSize) -{ - if (m_CryptoMode) - { - size_t size = *resSize; - *resSize = 0; - const Byte *bufData = m_DecryptedDataAligned; - UInt32 bufSize = m_DecryptedDataSize; - size_t i; - for (i = 0; i < size && m_CryptoPos < bufSize; i++) - ((Byte *)data)[i] = bufData[m_CryptoPos++]; - *resSize = i; - return S_OK; - } - return ReadStream(m_Stream, data, resSize); -} - -bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) -{ - size_t processed = size; - if (ReadBytesSpec(data, &processed) != S_OK) - return false; - return processed == size; -} - -static void DecodeUnicodeFileName(const Byte *name, const Byte *encName, - unsigned encSize, wchar_t *unicodeName, unsigned maxDecSize) -{ - unsigned encPos = 0; - unsigned decPos = 0; - unsigned flagBits = 0; - Byte flags = 0; - Byte highByte = encName[encPos++]; - while (encPos < encSize && decPos < maxDecSize) - { - if (flagBits == 0) - { - flags = encName[encPos++]; - flagBits = 8; - } - switch (flags >> 6) - { - case 0: - unicodeName[decPos++] = encName[encPos++]; - break; - case 1: - unicodeName[decPos++] = (wchar_t)(encName[encPos++] + (highByte << 8)); - break; - case 2: - unicodeName[decPos++] = (wchar_t)(encName[encPos] + (encName[encPos + 1] << 8)); - encPos += 2; - break; - case 3: - { - unsigned len = encName[encPos++]; - if (len & 0x80) - { - Byte correction = encName[encPos++]; - for (len = (len & 0x7f) + 2; - len > 0 && decPos < maxDecSize; len--, decPos++) - unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + (highByte << 8)); - } - else - for (len += 2; len > 0 && decPos < maxDecSize; len--, decPos++) - unicodeName[decPos] = name[decPos]; - } - break; - } - flags <<= 2; - flagBits -= 2; - } - unicodeName[decPos < maxDecSize ? decPos : maxDecSize - 1] = 0; -} - -void CInArchive::ReadName(const Byte *p, unsigned nameSize, CItem &item) -{ - item.UnicodeName.Empty(); - if (nameSize > 0) - { - unsigned i; - for (i = 0; i < nameSize && p[i] != 0; i++); - item.Name.SetFrom((const char *)p, i); - - if (item.HasUnicodeName()) - { - if (i < nameSize) - { - i++; - unsigned uNameSizeMax = MyMin(nameSize, (unsigned)0x400); - _unicodeNameBuffer.AllocAtLeast(uNameSizeMax + 1); - DecodeUnicodeFileName(p, p + i, nameSize - i, _unicodeNameBuffer, uNameSizeMax); - item.UnicodeName = _unicodeNameBuffer; - } - else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName)) - item.UnicodeName.Empty(); - } - } - else - item.Name.Empty(); -} - -static int ReadTime(const Byte *p, unsigned size, Byte mask, CRarTime &rarTime) -{ - rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0); - unsigned numDigits = (mask & 3); - rarTime.SubTime[0] = - rarTime.SubTime[1] = - rarTime.SubTime[2] = 0; - if (numDigits > size) - return -1; - for (unsigned i = 0; i < numDigits; i++) - rarTime.SubTime[3 - numDigits + i] = p[i]; - return numDigits; -} - -#define READ_TIME(_mask_, _ttt_) \ - { int size2 = ReadTime(p, size, _mask_, _ttt_); if (size2 < 0) return false; p += (unsigned)size2, size -= (unsigned)size2; } - -#define READ_TIME_2(_mask_, _def_, _ttt_) \ - _def_ = ((_mask_ & 8) != 0); if (_def_) \ - { if (size < 4) return false; \ - _ttt_ .DosTime = Get32(p); p += 4; size -= 4; \ - READ_TIME(_mask_, _ttt_); } \ - - -bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item) -{ - const Byte *pStart = p; - - item.Clear(); - item.Flags = m_BlockHeader.Flags; - - const unsigned kFileHeaderSize = 25; - - if (size < kFileHeaderSize) - return false; - - item.PackSize = Get32(p); - item.Size = Get32(p + 4); - item.HostOS = p[8]; - item.FileCRC = Get32(p + 9); - item.MTime.DosTime = Get32(p + 13); - item.UnPackVersion = p[17]; - item.Method = p[18]; - unsigned nameSize = Get16(p + 19); - item.Attrib = Get32(p + 21); - - item.MTime.LowSecond = 0; - item.MTime.SubTime[0] = - item.MTime.SubTime[1] = - item.MTime.SubTime[2] = 0; - - p += kFileHeaderSize; - size -= kFileHeaderSize; - if ((item.Flags & NHeader::NFile::kSize64Bits) != 0) - { - if (size < 8) - return false; - item.PackSize |= ((UInt64)Get32(p) << 32); - item.Size |= ((UInt64)Get32(p + 4) << 32); - p += 8; - size -= 8; - } - if (nameSize > size) - return false; - ReadName(p, nameSize, item); - p += nameSize; - size -= nameSize; - - /* - // It was commented, since it's difficult to support alt Streams for solid archives. - if (m_BlockHeader.Type == NHeader::NBlockType::kSubBlock) - { - if (item.HasSalt()) - { - if (size < sizeof(item.Salt)) - return false; - size -= sizeof(item.Salt); - p += sizeof(item.Salt); - } - if (item.Name == "ACL" && size == 0) - { - item.IsAltStream = true; - item.Name.Empty(); - item.UnicodeName.SetFromAscii(".ACL"); - } - else if (item.Name == "STM" && size != 0 && (size & 1) == 0) - { - item.IsAltStream = true; - item.Name.Empty(); - for (UInt32 i = 0; i < size; i += 2) - { - wchar_t c = Get16(p + i); - if (c == 0) - return false; - item.UnicodeName += c; - } - } - } - */ - - if (item.HasSalt()) - { - if (size < sizeof(item.Salt)) - return false; - for (unsigned i = 0; i < sizeof(item.Salt); i++) - item.Salt[i] = p[i]; - p += sizeof(item.Salt); - size -= sizeof(item.Salt); - } - - // some rar archives have HasExtTime flag without field. - if (size >= 2 && item.HasExtTime()) - { - Byte aMask = (Byte)(p[0] >> 4); - Byte b = p[1]; - p += 2; - size -= 2; - Byte mMask = (Byte)(b >> 4); - Byte cMask = (Byte)(b & 0xF); - if ((mMask & 8) != 0) - { - READ_TIME(mMask, item.MTime); - } - READ_TIME_2(cMask, item.CTimeDefined, item.CTime); - READ_TIME_2(aMask, item.ATimeDefined, item.ATime); - } - - unsigned fileHeaderWithNameSize = 7 + (unsigned)(p - pStart); - - item.Position = m_Position; - item.MainPartSize = fileHeaderWithNameSize; - item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize); - - if (m_CryptoMode) - item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF); - else - item.AlignSize = 0; - AddToSeekValue(m_BlockHeader.HeadSize); - - // return (m_BlockHeader.Type != NHeader::NBlockType::kSubBlock || item.IsAltStream); - return true; -} - -HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPassword, bool &filled, EErrorType &error) -{ - filled = false; - error = k_ErrorType_OK; - for (;;) - { - m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); - ArcInfo.EndPos = m_Position; - if (!m_CryptoMode && (ArcInfo.Flags & - NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) - { - m_CryptoMode = false; - if (getTextPassword == 0) - { - error = k_ErrorType_DecryptionError; - return S_OK; // return S_FALSE; - } - if (!m_RarAES) - { - m_RarAESSpec = new NCrypto::NRar3::CDecoder; - m_RarAES = m_RarAESSpec; - } - // m_RarAESSpec->SetRar350Mode(ArcInfo.IsEncryptOld()); - - // Salt - const UInt32 kSaltSize = 8; - Byte salt[kSaltSize]; - if (!ReadBytesAndTestSize(salt, kSaltSize)) - return S_FALSE; - m_Position += kSaltSize; - RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) - // Password - CMyComBSTR password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)) - unsigned len = 0; - if (password) - len = MyStringLen(password); - if (len > kPasswordLen_MAX) - len = kPasswordLen_MAX; - - CByteArr buffer(len * 2); - for (unsigned i = 0; i < len; i++) - { - wchar_t c = password[i]; - ((Byte *)buffer)[i * 2] = (Byte)c; - ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); - } - - m_RarAESSpec->SetPassword((const Byte *)buffer, len * 2); - - const UInt32 kDecryptedBufferSize = (1 << 12); - if (m_DecryptedData.Size() == 0) - { - const UInt32 kAlign = 16; - m_DecryptedData.Alloc(kDecryptedBufferSize + kAlign); - m_DecryptedDataAligned = (Byte *)((ptrdiff_t)((Byte *)m_DecryptedData + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1)); - } - RINOK(m_RarAES->Init()); - size_t decryptedDataSizeT = kDecryptedBufferSize; - RINOK(ReadStream(m_Stream, m_DecryptedDataAligned, &decryptedDataSizeT)); - m_DecryptedDataSize = (UInt32)decryptedDataSizeT; - m_DecryptedDataSize = m_RarAES->Filter(m_DecryptedDataAligned, m_DecryptedDataSize); - - m_CryptoMode = true; - m_CryptoPos = 0; - } - - m_FileHeaderData.AllocAtLeast(7); - size_t processed = 7; - RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed)); - if (processed != 7) - { - if (processed != 0) - error = k_ErrorType_UnexpectedEnd; - ArcInfo.EndPos = m_Position + processed; // test it - return S_OK; - } - - const Byte *p = m_FileHeaderData; - m_BlockHeader.CRC = Get16(p + 0); - m_BlockHeader.Type = p[2]; - m_BlockHeader.Flags = Get16(p + 3); - m_BlockHeader.HeadSize = Get16(p + 5); - - if (m_BlockHeader.HeadSize < 7) - { - error = k_ErrorType_Corrupted; - return S_OK; - // ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); - } - - if (m_BlockHeader.Type < NHeader::NBlockType::kFileHeader || - m_BlockHeader.Type > NHeader::NBlockType::kEndOfArchive) - { - error = m_CryptoMode ? - k_ErrorType_DecryptionError : - k_ErrorType_Corrupted; - return S_OK; - } - - if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) - { - bool footerError = false; - - unsigned expectHeadLen = 7; - if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) - expectHeadLen += 4; - if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) - expectHeadLen += 2; - if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_RevSpace) - expectHeadLen += 7; - - // rar 5.0 beta 1 writes incorrect RevSpace and headSize - - if (m_BlockHeader.HeadSize < expectHeadLen) - HeaderErrorWarning = true; - - if (m_BlockHeader.HeadSize > 7) - { - /* We suppose that EndOfArchive header is always small. - It's only 20 bytes for multivolume - Fix the limit, if larger footers are possible */ - if (m_BlockHeader.HeadSize > (1 << 8)) - footerError = true; - else - { - if (m_FileHeaderData.Size() < m_BlockHeader.HeadSize) - m_FileHeaderData.ChangeSize_KeepData(m_BlockHeader.HeadSize, 7); - UInt32 afterSize = m_BlockHeader.HeadSize - 7; - if (ReadBytesAndTestSize(m_FileHeaderData + 7, afterSize)) - processed += afterSize; - else - { - if (!m_CryptoMode) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - footerError = true; - } - } - } - - if (footerError || !CheckHeaderCrc(m_FileHeaderData, m_BlockHeader.HeadSize)) - { - error = m_CryptoMode ? - k_ErrorType_DecryptionError : - k_ErrorType_Corrupted; - } - else - { - ArcInfo.EndFlags = m_BlockHeader.Flags; - UInt32 offset = 7; - - if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) - { - if (processed < offset + 4) - error = k_ErrorType_Corrupted; - else - ArcInfo.DataCRC = Get32(m_FileHeaderData + offset); - offset += 4; - } - - if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) - { - if (processed < offset + 2) - error = k_ErrorType_Corrupted; - ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset); - } - - ArcInfo.EndOfArchive_was_Read = true; - } - - m_Position += processed; - FinishCryptoBlock(); - ArcInfo.EndPos = m_Position; - return S_OK; - } - - if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader - /* || m_BlockHeader.Type == NHeader::NBlockType::kSubBlock */) - { - if (m_FileHeaderData.Size() < m_BlockHeader.HeadSize) - m_FileHeaderData.ChangeSize_KeepData(m_BlockHeader.HeadSize, 7); - // m_CurData = (Byte *)m_FileHeaderData; - // m_PosLimit = m_BlockHeader.HeadSize; - if (!ReadBytesAndTestSize(m_FileHeaderData + 7, m_BlockHeader.HeadSize - 7)) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - - bool okItem = ReadHeaderReal(m_FileHeaderData + 7, m_BlockHeader.HeadSize - 7, item); - if (okItem) - { - if (!CheckHeaderCrc(m_FileHeaderData, (unsigned)m_BlockHeader.HeadSize - item.CommentSize)) - { - error = k_ErrorType_Corrupted; // ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError); - return S_OK; - } - filled = true; - } - - FinishCryptoBlock(); - m_CryptoMode = false; - // Move Position to compressed Data; - m_Stream->Seek(m_Position, STREAM_SEEK_SET, NULL); - AddToSeekValue(item.PackSize); // m_Position points to next header; - // if (okItem) - return S_OK; - /* - else - continue; - */ - } - - if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) - { - error = k_ErrorType_DecryptionError; - return S_OK; - } - - if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) - { - if (m_FileHeaderData.Size() < 7 + 4) - m_FileHeaderData.ChangeSize_KeepData(7 + 4, 7); - if (!ReadBytesAndTestSize(m_FileHeaderData + 7, 4)) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - UInt32 dataSize = Get32(m_FileHeaderData + 7); - AddToSeekValue(dataSize); - if (m_CryptoMode && dataSize > (1 << 27)) - { - error = k_ErrorType_DecryptionError; - return S_OK; - } - m_CryptoPos = m_BlockHeader.HeadSize; - } - else - m_CryptoPos = 0; - - { - UInt64 newPos = m_Position + m_BlockHeader.HeadSize; - if (newPos > ArcInfo.FileSize) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - } - AddToSeekValue(m_BlockHeader.HeadSize); - FinishCryptoBlock(); - m_CryptoMode = false; - } -} - - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - - kpidEncrypted, - kpidSolid, - kpidCommented, - kpidSplitBefore, - kpidSplitAfter, - kpidCRC, - kpidHostOS, - kpidMethod, - kpidUnpackVer -}; - -static const Byte kArcProps[] = -{ - kpidTotalPhySize, - kpidCharacts, - kpidSolid, - kpidNumBlocks, - // kpidEncrypted, - kpidIsVolume, - kpidVolumeIndex, - kpidNumVolumes - // kpidCommented -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -UInt64 CHandler::GetPackSize(unsigned refIndex) const -{ - const CRefItem &refItem = _refItems[refIndex]; - UInt64 totalPackSize = 0; - for (unsigned i = 0; i < refItem.NumItems; i++) - totalPackSize += _items[refItem.ItemIndex + i].PackSize; - return totalPackSize; -} - -bool CHandler::IsSolid(unsigned refIndex) const -{ - const CItem &item = _items[_refItems[refIndex].ItemIndex]; - if (item.UnPackVersion < 20) - { - if (_arcInfo.IsSolid()) - return (refIndex > 0); - return false; - } - return item.IsSolid(); -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidVolumeIndex: if (_arcInfo.Is_VolNumber_Defined()) prop = (UInt32)_arcInfo.VolNumber; break; - case kpidSolid: prop = _arcInfo.IsSolid(); break; - case kpidCharacts: - { - AString s = FlagsToString(k_Flags, ARRAY_SIZE(k_Flags), _arcInfo.Flags); - // FLAGS_TO_PROP(k_Flags, _arcInfo.Flags, prop); - if (_arcInfo.Is_DataCRC_Defined()) - { - s.Add_Space_if_NotEmpty(); - s += "VolCRC"; - } - prop = s; - break; - } - // case kpidEncrypted: prop = _arcInfo.IsEncrypted(); break; // it's for encrypted names. - case kpidIsVolume: prop = _arcInfo.IsVolume(); break; - case kpidNumVolumes: prop = (UInt32)_arcs.Size(); break; - case kpidOffset: if (_arcs.Size() == 1 && _arcInfo.StartPos != 0) prop = _arcInfo.StartPos; break; - - case kpidTotalPhySize: - { - if (_arcs.Size() > 1) - { - UInt64 sum = 0; - FOR_VECTOR (v, _arcs) - sum += _arcs[v].PhySize; - prop = sum; - } - break; - } - - case kpidPhySize: - { - if (_arcs.Size() != 0) - prop = _arcInfo.GetPhySize(); - break; - } - - // case kpidCommented: prop = _arcInfo.IsCommented(); break; - - case kpidNumBlocks: - { - UInt32 numBlocks = 0; - FOR_VECTOR (i, _refItems) - if (!IsSolid(i)) - numBlocks++; - prop = (UInt32)numBlocks; - break; - } - - - case kpidError: - { - // if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; - - if (/* &_missingVol || */ !_missingVolName.IsEmpty()) - { - UString s; - s.SetFromAscii("Missing volume : "); - s += _missingVolName; - prop = s; - } - break; - } - - case kpidErrorFlags: - { - UInt32 v = _errorFlags; - if (!_isArc) - v |= kpv_ErrorFlags_IsNotArc; - prop = v; - break; - } - - case kpidWarningFlags: - { - if (_warningFlags != 0) - prop = _warningFlags; - break; - } - - case kpidExtension: - if (_arcs.Size() == 1) - { - if (_arcInfo.Is_VolNumber_Defined()) - { - char sz[16]; - ConvertUInt32ToString((UInt32)_arcInfo.VolNumber + 1, sz); - unsigned len = MyStringLen(sz); - AString s = "part"; - for (; len < 2; len++) - s += '0'; - s += sz; - s += ".rar"; - prop = s; - } - } - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _refItems.Size(); - return S_OK; -} - -static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result) -{ - if (!NTime::DosTimeToFileTime(rarTime.DosTime, result)) - 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); - 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; - } - else - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - prop = utcFileTime; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CRefItem &refItem = _refItems[index]; - const CItem &item = _items[refItem.ItemIndex]; - const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; - - /* - const CItem *mainItem = &item; - if (item.BaseFileIndex >= 0) - mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; - */ - switch (propID) - { - case kpidPath: - { - /* - UString u; - if (item.BaseFileIndex >= 0) - u = mainItem->GetName(); - u += item.GetName(); - */ - prop = (const wchar_t *)NItemName::WinNameToOSName(item.GetName()); - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break; - case kpidPackSize: prop = GetPackSize(index); break; - case kpidMTime: RarTimeToProp(item.MTime, prop); break; - case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; - case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); break; - case kpidAttrib: prop = item.GetWinAttrib(); break; - case kpidEncrypted: prop = item.IsEncrypted(); break; - case kpidSolid: prop = IsSolid(index); break; - case kpidCommented: prop = item.IsCommented(); break; - case kpidSplitBefore: prop = item.IsSplitBefore(); break; - case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; - case kpidCRC: - { - prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); - break; - } - case kpidUnpackVer: prop = item.UnPackVersion; break; - case kpidMethod: - { - char s[16]; - Byte m = item.Method; - if (m < (Byte)'0' || m > (Byte)'5') - ConvertUInt32ToString(m, s); - else - { - s[0] = 'm'; - s[1] = (char)m; - s[2] = 0; - if (!item.IsDir()) - { - s[2] = ':'; - ConvertUInt32ToString(16 + item.GetDictSize(), &s[3]); - } - } - prop = s; - break; - } - case kpidHostOS: prop = (item.HostOS < ARRAY_SIZE(kHostOS)) ? kHostOS[item.HostOS] : kUnknownOS; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -HRESULT CHandler::Open2(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) -{ - { - CMyComPtr openVolumeCallback; - CMyComPtr getTextPassword; - - CVolumeName seqName; - - UInt64 totalBytes = 0; - UInt64 curBytes = 0; - - if (openCallback) - { - openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); - } - - bool nextVol_is_Required = false; - - CInArchive archive; - - for (;;) - { - CMyComPtr inStream; - if (!_arcs.IsEmpty()) - { - if (!openVolumeCallback) - break; - - if (_arcs.Size() == 1) - { - if (!_arcInfo.IsVolume()) - break; - UString baseName; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - break; - baseName = prop.bstrVal; - } - if (!seqName.InitName(baseName, _arcInfo.HaveNewVolumeName())) - break; - /* - if (_arcInfo.HaveNewVolumeName() && !_arcInfo.IsFirstVolume()) - { - seqName.MakeBeforeFirstName(); - } - */ - } - - const UString volName = seqName.GetNextName(); - - HRESULT result = openVolumeCallback->GetStream(volName, &inStream); - - if (result != S_OK && result != S_FALSE) - return result; - - if (!inStream || result != S_OK) - { - if (nextVol_is_Required) - _missingVolName = volName; - break; - } - } - else - inStream = stream; - - UInt64 endPos = 0; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - if (openCallback) - { - totalBytes += endPos; - RINOK(openCallback->SetTotal(NULL, &totalBytes)); - } - - RINOK(archive.Open(inStream, maxCheckStartPosition)); - _isArc = true; - CItem item; - - for (;;) - { - if (archive.m_Position > endPos) - { - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - break; - } - - EErrorType error; - // bool decryptionError; - // AString errorMessageLoc; - bool filled; - HRESULT result = archive.GetNextItem(item, getTextPassword, filled, error); - - if (error != k_ErrorType_OK) - { - if (error == k_ErrorType_UnexpectedEnd) - _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; - else if (error == k_ErrorType_Corrupted) - _errorFlags |= kpv_ErrorFlags_HeadersError; - else if (error == k_ErrorType_DecryptionError) - _errorFlags |= kpv_ErrorFlags_EncryptedHeadersError; - - // AddErrorMessage(errorMessageLoc); - } - RINOK(result); - - if (!filled) - { - if (error == k_ErrorType_DecryptionError && _items.IsEmpty()) - return S_FALSE; - - if (archive.ArcInfo.ExtraZeroTail_is_Possible()) - { - /* if there is recovery record for multivolume archive, - RAR adds 18 bytes (ZERO bytes) at the end for alignment. - We must skip these bytes to prevent phySize warning. */ - RINOK(inStream->Seek(archive.ArcInfo.EndPos, STREAM_SEEK_SET, NULL)); - bool areThereNonZeros; - UInt64 numZeros; - const UInt64 maxSize = 1 << 12; - RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); - if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) - archive.ArcInfo.EndPos += numZeros; - } - break; - } - - if (item.IgnoreItem()) - continue; - - bool needAdd = true; - - if (item.IsSplitBefore()) - { - if (!_refItems.IsEmpty()) - { - CRefItem &refItem = _refItems.Back(); - refItem.NumItems++; - needAdd = false; - } - } - - if (needAdd) - { - CRefItem refItem; - refItem.ItemIndex = _items.Size(); - refItem.NumItems = 1; - refItem.VolumeIndex = _arcs.Size(); - _refItems.Add(refItem); - } - - _items.Add(item); - - if (openCallback && _items.Size() % 100 == 0) - { - UInt64 numFiles = _items.Size(); - UInt64 numBytes = curBytes + item.Position; - RINOK(openCallback->SetCompleted(&numFiles, &numBytes)); - } - } - - if (archive.HeaderErrorWarning) - _warningFlags |= kpv_ErrorFlags_HeadersError; - - /* - if (archive.m_Position < endPos) - _warningFlags |= kpv_ErrorFlags_DataAfterEnd; - */ - if (_arcs.IsEmpty()) - _arcInfo = archive.ArcInfo; - // _arcInfo.EndPos = archive.EndPos; - - curBytes += endPos; - { - CArc &arc = _arcs.AddNew(); - arc.PhySize = archive.ArcInfo.GetPhySize(); - arc.Stream = inStream; - } - - nextVol_is_Required = false; - - if (!archive.ArcInfo.IsVolume()) - break; - - if (archive.ArcInfo.EndOfArchive_was_Read) - { - if (!archive.ArcInfo.AreMoreVolumes()) - break; - nextVol_is_Required = true; - } - } - } - - /* - int baseFileIndex = -1; - for (unsigned i = 0; i < _refItems.Size(); i++) - { - CItem &item = _items[_refItems[i].ItemIndex]; - if (item.IsAltStream) - item.BaseFileIndex = baseFileIndex; - else - baseFileIndex = i; - } - */ - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback) -{ - COM_TRY_BEGIN - Close(); - // try - { - HRESULT res = Open2(stream, maxCheckStartPosition, openCallback); - /* - if (res != S_OK) - Close(); - */ - - return res; - } - // catch(const CInArchiveException &) { Close(); return S_FALSE; } - // catch(...) { Close(); throw; } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - COM_TRY_BEGIN - // _errorMessage.Empty(); - _missingVolName.Empty(); - _errorFlags = 0; - _warningFlags = 0; - _isArc = false; - _refItems.Clear(); - _items.Clear(); - _arcs.Clear(); - return S_OK; - COM_TRY_END -} - -struct CMethodItem -{ - Byte RarUnPackVersion; - CMyComPtr Coder; -}; - - -class CVolsInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - UInt64 _rem; - ISequentialInStream *_stream; - const CObjectVector *_arcs; - const CObjectVector *_items; - CRefItem _refItem; - unsigned _curIndex; - UInt32 _crc; - bool _calcCrc; - -public: - MY_UNKNOWN_IMP - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - void Init(const CObjectVector *arcs, - const CObjectVector *items, - const CRefItem &refItem) - { - _arcs = arcs; - _items = items; - _refItem = refItem; - _curIndex = 0; - _stream = NULL; - CrcIsOK = true; - } - - bool CrcIsOK; -}; - - -STDMETHODIMP CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - UInt32 realProcessedSize = 0; - - while (size != 0) - { - if (!_stream) - { - if (_curIndex >= _refItem.NumItems) - break; - const CItem &item = (*_items)[_refItem.ItemIndex + _curIndex]; - IInStream *s = (*_arcs)[_refItem.VolumeIndex + _curIndex].Stream; - RINOK(s->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); - _stream = s; - _calcCrc = (CrcIsOK && item.IsSplitAfter()); - _crc = CRC_INIT_VAL; - _rem = item.PackSize; - } - { - UInt32 cur = size; - if (cur > _rem) - cur = (UInt32)_rem; - UInt32 num = cur; - HRESULT res = _stream->Read(data, cur, &cur); - if (_calcCrc) - _crc = CrcUpdate(_crc, data, cur); - realProcessedSize += cur; - if (processedSize) - *processedSize = realProcessedSize; - data = (Byte *)data + cur; - size -= cur; - _rem -= cur; - if (_rem == 0) - { - const CItem &item = (*_items)[_refItem.ItemIndex + _curIndex]; - _curIndex++; - if (_calcCrc && CRC_GET_DIGEST(_crc) != item.FileCRC) - CrcIsOK = false; - _stream = NULL; - } - if (res != S_OK) - return res; - if (realProcessedSize != 0) - return S_OK; - if (cur == 0 && num != 0) - return S_OK; - } - } - - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - CMyComPtr getTextPassword; - UInt64 censoredTotalUnPacked = 0, - // censoredTotalPacked = 0, - importantTotalUnPacked = 0; - // importantTotalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _refItems.Size(); - if (numItems == 0) - return S_OK; - unsigned lastIndex = 0; - CRecordVector importantIndexes; - CRecordVector extractStatuses; - - bool isThereUndefinedSize = false; - - for (UInt32 t = 0; t < numItems; t++) - { - unsigned index = allFilesMode ? t : indices[t]; - - { - const CRefItem &refItem = _refItems[index]; - const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; - - if (item.Is_Size_Defined()) - censoredTotalUnPacked += item.Size; - else - isThereUndefinedSize = true; - - // censoredTotalPacked += item.PackSize; - } - - unsigned j; - for (j = lastIndex; j <= index; j++) - // if (!_items[_refItems[j].ItemIndex].IsSolid()) - if (!IsSolid(j)) - lastIndex = j; - - for (j = lastIndex; j <= index; j++) - { - const CRefItem &refItem = _refItems[j]; - const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; - - if (item.Is_Size_Defined()) - importantTotalUnPacked += item.Size; - else - isThereUndefinedSize = true; - // importantTotalPacked += item.PackSize; - importantIndexes.Add(j); - extractStatuses.Add(j == index); - } - - lastIndex = index + 1; - } - - if (importantTotalUnPacked != 0 || !isThereUndefinedSize) - { - RINOK(extractCallback->SetTotal(importantTotalUnPacked)); - } - - UInt64 currentImportantTotalUnPacked = 0; - UInt64 currentImportantTotalPacked = 0; - UInt64 currentUnPackSize, currentPackSize; - - CObjectVector methodItems; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CFilterCoder *filterStreamSpec = new CFilterCoder(false); - CMyComPtr filterStream = filterStreamSpec; - - NCrypto::NRar2::CDecoder *rar20CryptoDecoderSpec = NULL; - CMyComPtr rar20CryptoDecoder; - NCrypto::NRar3::CDecoder *rar3CryptoDecoderSpec = NULL; - CMyComPtr rar3CryptoDecoder; - - CVolsInStream *volsInStreamSpec = NULL; - CMyComPtr volsInStream; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - bool solidStart = true; - - for (unsigned i = 0;; - i++, - currentImportantTotalUnPacked += currentUnPackSize, - currentImportantTotalPacked += currentPackSize) - { - lps->InSize = currentImportantTotalPacked; - lps->OutSize = currentImportantTotalUnPacked; - RINOK(lps->SetCur()); - - if (i >= importantIndexes.Size()) - break; - - CMyComPtr realOutStream; - - Int32 askMode; - if (extractStatuses[i]) - askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - else - askMode = NExtract::NAskMode::kSkip; - - UInt32 index = importantIndexes[i]; - - const CRefItem &refItem = _refItems[index]; - const CItem &item = _items[refItem.ItemIndex]; - const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; - - UInt64 outSize = (UInt64)(Int64)-1; - currentUnPackSize = 0; - if (lastItem.Is_Size_Defined()) - { - outSize = lastItem.Size; - currentUnPackSize = outSize; - } - - currentPackSize = GetPackSize(index); - - if (item.IgnoreItem()) - continue; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (!IsSolid(index)) - solidStart = true; - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - bool mustBeProcessedAnywhere = false; - if (i < importantIndexes.Size() - 1) - { - // const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]]; - // const CItem &nextItemInfo = _items[nextRefItem.ItemIndex]; - // mustBeProcessedAnywhere = nextItemInfo.IsSolid(); - mustBeProcessedAnywhere = IsSolid(importantIndexes[i + 1]); - } - - if (!mustBeProcessedAnywhere && !testMode && !realOutStream) - continue; - - if (!realOutStream && !testMode) - askMode = NExtract::NAskMode::kSkip; - - RINOK(extractCallback->PrepareOperation(askMode)); - - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - if (!volsInStream) - { - volsInStreamSpec = new CVolsInStream; - volsInStream = volsInStreamSpec; - } - - volsInStreamSpec->Init(&_arcs, &_items, refItem); - - UInt64 packSize = currentPackSize; - - // packedPos += item.PackSize; - // unpackedPos += 0; - - CMyComPtr inStream; - - if (item.IsEncrypted()) - { - // CMyComPtr cryptoSetPassword; - - if (item.UnPackVersion >= 29) - { - if (!rar3CryptoDecoder) - { - rar3CryptoDecoderSpec = new NCrypto::NRar3::CDecoder; - rar3CryptoDecoder = rar3CryptoDecoderSpec; - } - // rar3CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); - /* - CMyComPtr cryptoProperties; - RINOK(rar3CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, - &cryptoProperties)); - */ - RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)); - filterStreamSpec->Filter = rar3CryptoDecoder; - } - else if (item.UnPackVersion >= 20) - { - if (!rar20CryptoDecoder) - { - rar20CryptoDecoderSpec = new NCrypto::NRar2::CDecoder; - rar20CryptoDecoder = rar20CryptoDecoderSpec; - } - filterStreamSpec->Filter = rar20CryptoDecoder; - } - else - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - // RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); - - if (!getTextPassword) - extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); - - if (!getTextPassword) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - // if (getTextPassword) - { - CMyComBSTR password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); - - if (item.UnPackVersion >= 29) - { - unsigned len = 0; - if (password) - len = MyStringLen(password); - if (len > kPasswordLen_MAX) - len = kPasswordLen_MAX; - CByteArr buffer(len * 2); - for (unsigned k = 0; k < len; k++) - { - wchar_t c = password[k]; - ((Byte *)buffer)[k * 2] = (Byte)c; - ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); - } - rar3CryptoDecoderSpec->SetPassword((const Byte *)buffer, len * 2); - } - else - { - AString oemPassword; - if (password) - { - UString unicode = (LPCOLESTR)password; - if (unicode.Len() > kPasswordLen_MAX) - unicode.DeleteFrom(kPasswordLen_MAX); - oemPassword = UnicodeStringToMultiByte(unicode, CP_OEMCP); - } - rar20CryptoDecoderSpec->SetPassword((const Byte *)(const char *)oemPassword, oemPassword.Len()); - } - } - /* - else - { - RINOK(cryptoSetPassword->CryptoSetPassword(NULL, 0)); - } - */ - - filterStreamSpec->SetInStream(volsInStream); - filterStreamSpec->SetOutStreamSize(NULL); - inStream = filterStream; - } - else - { - inStream = volsInStream; - } - - CMyComPtr commonCoder; - - switch (item.Method) - { - case '0': - { - commonCoder = copyCoder; - break; - } - case '1': - case '2': - case '3': - case '4': - case '5': - { - unsigned m; - for (m = 0; m < methodItems.Size(); m++) - if (methodItems[m].RarUnPackVersion == item.UnPackVersion) - break; - if (m == methodItems.Size()) - { - CMethodItem mi; - mi.RarUnPackVersion = item.UnPackVersion; - - mi.Coder.Release(); - if (item.UnPackVersion <= 40) - { - UInt32 methodID = 0x40300; - if (item.UnPackVersion < 20) - methodID += 1; - else if (item.UnPackVersion < 29) - methodID += 2; - else - methodID += 3; - RINOK(CreateCoder(EXTERNAL_CODECS_VARS methodID, false, mi.Coder)); - } - - if (mi.Coder == 0) - { - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - m = methodItems.Add(mi); - } - CMyComPtr decoder = methodItems[m].Coder; - - CMyComPtr compressSetDecoderProperties; - RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, - &compressSetDecoderProperties)); - - Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); - if (solidStart) - { - isSolid = 0; - solidStart = false; - } - - - RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)); - - commonCoder = decoder; - break; - } - default: - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)); - continue; - } - - HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress); - - if (item.IsEncrypted()) - filterStreamSpec->ReleaseInStream(); - - if (outSize == (UInt64)(Int64)-1) - currentUnPackSize = outStreamSpec->GetSize(); - - int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kCRCError; - outStream.Release(); - - if (result != S_OK) - { - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else if (result == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else - return result; - } - RINOK(extractCallback->SetOperationResult(opRes)); - } - - return S_OK; - COM_TRY_END -} - -IMPL_ISetCompressCodecsInfo - -REGISTER_ARC_I( - "Rar", "rar r00", 0, 3, - kMarker, - 0, - NArcInfoFlags::kFindSignature, - NULL) - -}} +// RarHandler.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/PropVariantUtils.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../IPassword.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/FilterCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/MethodId.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/RegisterArc.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../../Crypto/Rar20Crypto.h" +#include "../../Crypto/RarAes.h" + +#include "../Common/FindSignature.h" +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" + +#include "../HandlerCont.h" + +#include "RarVol.h" +#include "RarHandler.h" + +using namespace NWindows; + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +namespace NArchive { +namespace NRar { + +static const Byte kMarker[NHeader::kMarkerSize] = + { 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; + +const unsigned kPasswordLen_MAX = 127; + +bool CItem::IgnoreItem() const +{ + switch (HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + return ((Attrib & NHeader::NFile::kLabelFileAttribute) != 0); + } + return false; +} + +bool CItem::IsDir() const +{ + if (GetDictSize() == NHeader::NFile::kDictDirectoryValue) + return true; + switch (HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + if ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + return true; + } + return false; +} + +UInt32 CItem::GetWinAttrib() const +{ + UInt32 a; + switch (HostOS) + { + case NHeader::NFile::kHostMSDOS: + case NHeader::NFile::kHostOS2: + case NHeader::NFile::kHostWin32: + a = Attrib; + break; + default: + a = 0; // must be converted from unix value; + } + if (IsDir()) + a |= NHeader::NFile::kWinFileDirectoryAttributeMask; + return a; +} + +static const char * const kHostOS[] = +{ + "MS DOS" + , "OS/2" + , "Win32" + , "Unix" + , "Mac OS" + , "BeOS" +}; + +static const char * const k_Flags[] = +{ + "Volume" + , "Comment" + , "Lock" + , "Solid" + , "NewVolName" // pack_comment in old versuons + , "Authenticity" + , "Recovery" + , "BlockEncryption" + , "FirstVolume" + , "EncryptVer" // 9 +}; + +enum EErrorType +{ + k_ErrorType_OK, + k_ErrorType_Corrupted, + k_ErrorType_UnexpectedEnd, + k_ErrorType_DecryptionError +}; + +class CInArchive +{ + IInStream *m_Stream; + UInt64 m_StreamStartPosition; + UString _unicodeNameBuffer; + CByteBuffer _comment; + CByteBuffer m_FileHeaderData; + NHeader::NBlock::CBlock m_BlockHeader; + NCrypto::NRar3::CDecoder *m_RarAESSpec; + CMyComPtr m_RarAES; + CAlignedBuffer m_DecryptedDataAligned; + UInt32 m_DecryptedDataSize; + bool m_CryptoMode; + UInt32 m_CryptoPos; + + + HRESULT ReadBytesSpec(void *data, size_t *size); + bool ReadBytesAndTestSize(void *data, UInt32 size); + void ReadName(const Byte *p, unsigned nameSize, CItem &item); + bool ReadHeaderReal(const Byte *p, unsigned size, CItem &item); + + HRESULT Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit); + + void AddToSeekValue(UInt64 addValue) + { + m_Position += addValue; + } + + void FinishCryptoBlock() + { + if (m_CryptoMode) + while ((m_CryptoPos & 0xF) != 0) + { + m_CryptoPos++; + m_Position++; + } + } + +public: + UInt64 m_Position; + CInArcInfo ArcInfo; + bool HeaderErrorWarning; + + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit); + HRESULT GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPassword, + bool &filled, EErrorType &error); +}; + +static bool CheckHeaderCrc(const Byte *header, size_t headerSize) +{ + return Get16(header) == (UInt16)(CrcCalc(header + 2, headerSize - 2) & 0xFFFF); +} + +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) +{ + HeaderErrorWarning = false; + m_CryptoMode = false; + RINOK(InStream_GetPos_GetSize(stream, m_StreamStartPosition, ArcInfo.FileSize)) + m_Position = m_StreamStartPosition; + + UInt64 arcStartPos = m_StreamStartPosition; + { + Byte marker[NHeader::kMarkerSize]; + RINOK(ReadStream_FALSE(stream, marker, NHeader::kMarkerSize)) + if (memcmp(marker, kMarker, NHeader::kMarkerSize) == 0) + m_Position += NHeader::kMarkerSize; + else + { + if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) + return S_FALSE; + RINOK(InStream_SeekSet(stream, m_StreamStartPosition)) + RINOK(FindSignatureInStream(stream, kMarker, NHeader::kMarkerSize, + searchHeaderSizeLimit, arcStartPos)) + m_Position = arcStartPos + NHeader::kMarkerSize; + RINOK(InStream_SeekSet(stream, m_Position)) + } + } + Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1]; + + RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize)) + AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize); + + + const UInt32 blockSize = Get16(buf + 5); + + ArcInfo.EncryptVersion = 0; + ArcInfo.Flags = Get16(buf + 3); + + UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize; + + /* + if (ArcInfo.IsThereEncryptVer()) + { + if (blockSize <= headerSize) + return S_FALSE; + RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1)); + AddToSeekValue(1); + ArcInfo.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize]; + headerSize += 1; + } + */ + + if (blockSize < headerSize + || buf[2] != NHeader::NBlockType::kArchiveHeader + || !CheckHeaderCrc(buf, headerSize)) + return S_FALSE; + + size_t commentSize = blockSize - headerSize; + _comment.Alloc(commentSize); + RINOK(ReadStream_FALSE(stream, _comment, commentSize)) + AddToSeekValue(commentSize); + m_Stream = stream; + ArcInfo.StartPos = arcStartPos; + return S_OK; +} + +HRESULT CInArchive::ReadBytesSpec(void *data, size_t *resSize) +{ + if (m_CryptoMode) + { + size_t size = *resSize; + *resSize = 0; + const Byte *bufData = m_DecryptedDataAligned; + UInt32 bufSize = m_DecryptedDataSize; + size_t i; + for (i = 0; i < size && m_CryptoPos < bufSize; i++) + ((Byte *)data)[i] = bufData[m_CryptoPos++]; + *resSize = i; + return S_OK; + } + return ReadStream(m_Stream, data, resSize); +} + +bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) +{ + size_t processed = size; + if (ReadBytesSpec(data, &processed) != S_OK) + return false; + return processed == size; +} + + +static unsigned DecodeUnicodeFileName(const Byte *name, const Byte *encName, + unsigned encSize, wchar_t *unicodeName, unsigned maxDecSize) +{ + unsigned encPos = 0; + unsigned decPos = 0; + unsigned flagBits = 0; + Byte flags = 0; + + if (encPos >= encSize) + return 0; // error + const unsigned highBits = ((unsigned)encName[encPos++]) << 8; + + while (encPos < encSize && decPos < maxDecSize) + { + if (flagBits == 0) + { + flags = encName[encPos++]; + flagBits = 8; + } + + if (encPos >= encSize) + break; // error + unsigned len = encName[encPos++]; + + flagBits -= 2; + const unsigned mode = (flags >> flagBits) & 3; + + if (mode != 3) + { + if (mode == 1) + len += highBits; + else if (mode == 2) + { + if (encPos >= encSize) + break; // error + len += ((unsigned)encName[encPos++] << 8); + } + unicodeName[decPos++] = (wchar_t)len; + } + else + { + if (len & 0x80) + { + if (encPos >= encSize) + break; // error + Byte correction = encName[encPos++]; + for (len = (len & 0x7f) + 2; len > 0 && decPos < maxDecSize; len--, decPos++) + unicodeName[decPos] = (wchar_t)(((name[decPos] + correction) & 0xff) + highBits); + } + else + for (len += 2; len > 0 && decPos < maxDecSize; len--, decPos++) + unicodeName[decPos] = name[decPos]; + } + } + + return decPos < maxDecSize ? decPos : maxDecSize - 1; +} + + +void CInArchive::ReadName(const Byte *p, unsigned nameSize, CItem &item) +{ + item.UnicodeName.Empty(); + if (nameSize > 0) + { + unsigned i; + for (i = 0; i < nameSize && p[i] != 0; i++); + item.Name.SetFrom((const char *)p, i); + + if (item.HasUnicodeName()) + { + if (i < nameSize) + { + i++; + unsigned uNameSizeMax = MyMin(nameSize, (unsigned)0x400); + unsigned len = DecodeUnicodeFileName(p, p + i, nameSize - i, _unicodeNameBuffer.GetBuf(uNameSizeMax), uNameSizeMax); + _unicodeNameBuffer.ReleaseBuf_SetEnd(len); + item.UnicodeName = _unicodeNameBuffer; + } + else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName)) + item.UnicodeName.Empty(); + } + } + else + item.Name.Empty(); +} + +static int ReadTime(const Byte *p, unsigned size, Byte mask, CRarTime &rarTime) +{ + rarTime.LowSecond = (Byte)(((mask & 4) != 0) ? 1 : 0); + const unsigned numDigits = (mask & 3); + rarTime.SubTime[0] = + rarTime.SubTime[1] = + rarTime.SubTime[2] = 0; + if (numDigits > size) + return -1; + for (unsigned i = 0; i < numDigits; i++) + rarTime.SubTime[3 - numDigits + i] = p[i]; + return (int)numDigits; +} + +#define READ_TIME(_mask_, _ttt_) \ + { int size2 = ReadTime(p, size, _mask_, _ttt_); if (size2 < 0) return false; p += (unsigned)size2, size -= (unsigned)size2; } + +#define READ_TIME_2(_mask_, _def_, _ttt_) \ + _def_ = ((_mask_ & 8) != 0); if (_def_) \ + { if (size < 4) return false; \ + _ttt_ .DosTime = Get32(p); p += 4; size -= 4; \ + READ_TIME(_mask_, _ttt_); } \ + + +bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item) +{ + const Byte *pStart = p; + + item.Clear(); + item.Flags = m_BlockHeader.Flags; + + const unsigned kFileHeaderSize = 25; + + if (size < kFileHeaderSize) + return false; + + item.PackSize = Get32(p); + item.Size = Get32(p + 4); + item.HostOS = p[8]; + item.FileCRC = Get32(p + 9); + item.MTime.DosTime = Get32(p + 13); + item.UnPackVersion = p[17]; + item.Method = p[18]; + unsigned nameSize = Get16(p + 19); + item.Attrib = Get32(p + 21); + + item.MTime.LowSecond = 0; + item.MTime.SubTime[0] = + item.MTime.SubTime[1] = + item.MTime.SubTime[2] = 0; + + p += kFileHeaderSize; + size -= kFileHeaderSize; + if ((item.Flags & NHeader::NFile::kSize64Bits) != 0) + { + if (size < 8) + return false; + item.PackSize |= ((UInt64)Get32(p) << 32); + if (item.PackSize >= ((UInt64)1 << 63)) + return false; + item.Size |= ((UInt64)Get32(p + 4) << 32); + p += 8; + size -= 8; + } + if (nameSize > size) + return false; + ReadName(p, nameSize, item); + p += nameSize; + size -= nameSize; + + /* + // It was commented, since it's difficult to support alt Streams for solid archives. + if (m_BlockHeader.Type == NHeader::NBlockType::kSubBlock) + { + if (item.HasSalt()) + { + if (size < sizeof(item.Salt)) + return false; + size -= sizeof(item.Salt); + p += sizeof(item.Salt); + } + if (item.Name.IsEqualTo("ACL") && size == 0) + { + item.IsAltStream = true; + item.Name.Empty(); + item.UnicodeName.SetFromAscii(".ACL"); + } + else if (item.Name.IsEqualTo("STM") && size != 0 && (size & 1) == 0) + { + item.IsAltStream = true; + item.Name.Empty(); + for (UInt32 i = 0; i < size; i += 2) + { + wchar_t c = Get16(p + i); + if (c == 0) + return false; + item.UnicodeName += c; + } + } + } + */ + + if (item.HasSalt()) + { + if (size < sizeof(item.Salt)) + return false; + for (unsigned i = 0; i < sizeof(item.Salt); i++) + item.Salt[i] = p[i]; + p += sizeof(item.Salt); + size -= (unsigned)sizeof(item.Salt); + } + + // some rar archives have HasExtTime flag without field. + if (size >= 2 && item.HasExtTime()) + { + Byte aMask = (Byte)(p[0] >> 4); + Byte b = p[1]; + p += 2; + size -= 2; + Byte mMask = (Byte)(b >> 4); + Byte cMask = (Byte)(b & 0xF); + if ((mMask & 8) != 0) + { + READ_TIME(mMask, item.MTime) + } + READ_TIME_2(cMask, item.CTimeDefined, item.CTime) + READ_TIME_2(aMask, item.ATimeDefined, item.ATime) + } + + unsigned fileHeaderWithNameSize = 7 + (unsigned)(p - pStart); + + item.Position = m_Position; + item.MainPartSize = fileHeaderWithNameSize; + item.CommentSize = (UInt16)(m_BlockHeader.HeadSize - fileHeaderWithNameSize); + + if (m_CryptoMode) + item.AlignSize = (UInt16)((16 - ((m_BlockHeader.HeadSize) & 0xF)) & 0xF); + else + item.AlignSize = 0; + AddToSeekValue(m_BlockHeader.HeadSize); + + // return (m_BlockHeader.Type != NHeader::NBlockType::kSubBlock || item.IsAltStream); + return true; +} + +HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPassword, bool &filled, EErrorType &error) +{ + filled = false; + error = k_ErrorType_OK; + for (;;) + { + RINOK(InStream_SeekSet(m_Stream, m_Position)) + ArcInfo.EndPos = m_Position; + if (!m_CryptoMode && (ArcInfo.Flags & + NHeader::NArchive::kBlockHeadersAreEncrypted) != 0) + { + m_CryptoMode = false; + if (!getTextPassword) + { + error = k_ErrorType_DecryptionError; + return S_OK; // return S_FALSE; + } + if (!m_RarAES) + { + m_RarAESSpec = new NCrypto::NRar3::CDecoder; + m_RarAES = m_RarAESSpec; + } + // m_RarAESSpec->SetRar350Mode(ArcInfo.IsEncryptOld()); + + { + // Salt + const UInt32 kSaltSize = 8; + Byte salt[kSaltSize]; + if (!ReadBytesAndTestSize(salt, kSaltSize)) + return S_FALSE; + m_Position += kSaltSize; + RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) + } + + { + // Password + CMyComBSTR_Wipe password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + unsigned len = 0; + if (password) + len = MyStringLen(password); + if (len > kPasswordLen_MAX) + len = kPasswordLen_MAX; + + CByteBuffer_Wipe buffer(len * 2); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = password[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + + m_RarAESSpec->SetPassword((const Byte *)buffer, len * 2); + } + + const UInt32 kDecryptedBufferSize = (1 << 12); + if (m_DecryptedDataAligned.Size() == 0) + { + // const UInt32 kAlign = 16; + m_DecryptedDataAligned.AllocAtLeast(kDecryptedBufferSize); + if (!m_DecryptedDataAligned.IsAllocated()) + return E_OUTOFMEMORY; + } + RINOK(m_RarAES->Init()) + size_t decryptedDataSizeT = kDecryptedBufferSize; + RINOK(ReadStream(m_Stream, m_DecryptedDataAligned, &decryptedDataSizeT)) + m_DecryptedDataSize = (UInt32)decryptedDataSizeT; + m_DecryptedDataSize = m_RarAES->Filter(m_DecryptedDataAligned, m_DecryptedDataSize); + + m_CryptoMode = true; + m_CryptoPos = 0; + } + + m_FileHeaderData.AllocAtLeast(7); + size_t processed = 7; + RINOK(ReadBytesSpec((Byte *)m_FileHeaderData, &processed)) + if (processed != 7) + { + if (processed != 0) + error = k_ErrorType_UnexpectedEnd; + ArcInfo.EndPos = m_Position + processed; // test it + return S_OK; + } + + const Byte *p = m_FileHeaderData; + m_BlockHeader.CRC = Get16(p + 0); + m_BlockHeader.Type = p[2]; + m_BlockHeader.Flags = Get16(p + 3); + m_BlockHeader.HeadSize = Get16(p + 5); + + if (m_BlockHeader.HeadSize < 7) + { + error = k_ErrorType_Corrupted; + return S_OK; + // ThrowExceptionWithCode(CInArchiveException::kIncorrectArchive); + } + + if (m_BlockHeader.Type < NHeader::NBlockType::kFileHeader || + m_BlockHeader.Type > NHeader::NBlockType::kEndOfArchive) + { + error = m_CryptoMode ? + k_ErrorType_DecryptionError : + k_ErrorType_Corrupted; + return S_OK; + } + + if (m_BlockHeader.Type == NHeader::NBlockType::kEndOfArchive) + { + bool footerError = false; + + unsigned expectHeadLen = 7; + if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) + expectHeadLen += 4; + if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) + expectHeadLen += 2; + if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_RevSpace) + expectHeadLen += 7; + + // rar 5.0 beta 1 writes incorrect RevSpace and headSize + + if (m_BlockHeader.HeadSize < expectHeadLen) + HeaderErrorWarning = true; + + if (m_BlockHeader.HeadSize > 7) + { + /* We suppose that EndOfArchive header is always small. + It's only 20 bytes for multivolume + Fix the limit, if larger footers are possible */ + if (m_BlockHeader.HeadSize > (1 << 8)) + footerError = true; + else + { + if (m_FileHeaderData.Size() < m_BlockHeader.HeadSize) + m_FileHeaderData.ChangeSize_KeepData(m_BlockHeader.HeadSize, 7); + UInt32 afterSize = m_BlockHeader.HeadSize - 7; + if (ReadBytesAndTestSize(m_FileHeaderData + 7, afterSize)) + processed += afterSize; + else + { + if (!m_CryptoMode) + { + error = k_ErrorType_UnexpectedEnd; + return S_OK; + } + footerError = true; + } + } + } + + if (footerError || !CheckHeaderCrc(m_FileHeaderData, m_BlockHeader.HeadSize)) + { + error = m_CryptoMode ? + k_ErrorType_DecryptionError : + k_ErrorType_Corrupted; + } + else + { + ArcInfo.EndFlags = m_BlockHeader.Flags; + UInt32 offset = 7; + + if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) + { + if (processed < offset + 4) + error = k_ErrorType_Corrupted; + else + ArcInfo.DataCRC = Get32(m_FileHeaderData + offset); + offset += 4; + } + + if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) + { + if (processed < offset + 2) + error = k_ErrorType_Corrupted; + else + ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset); + } + + ArcInfo.EndOfArchive_was_Read = true; + } + + m_Position += processed; + FinishCryptoBlock(); + ArcInfo.EndPos = m_Position; + return S_OK; + } + + if (m_BlockHeader.Type == NHeader::NBlockType::kFileHeader + /* || m_BlockHeader.Type == NHeader::NBlockType::kSubBlock */) + { + if (m_FileHeaderData.Size() < m_BlockHeader.HeadSize) + m_FileHeaderData.ChangeSize_KeepData(m_BlockHeader.HeadSize, 7); + // m_CurData = (Byte *)m_FileHeaderData; + // m_PosLimit = m_BlockHeader.HeadSize; + if (!ReadBytesAndTestSize(m_FileHeaderData + 7, m_BlockHeader.HeadSize - 7)) + { + error = k_ErrorType_UnexpectedEnd; + return S_OK; + } + + bool okItem = ReadHeaderReal(m_FileHeaderData + 7, m_BlockHeader.HeadSize - 7, item); + if (okItem) + { + if (!CheckHeaderCrc(m_FileHeaderData, (unsigned)m_BlockHeader.HeadSize - item.CommentSize)) + { + error = k_ErrorType_Corrupted; // ThrowExceptionWithCode(CInArchiveException::kFileHeaderCRCError); + return S_OK; + } + filled = true; + } + + FinishCryptoBlock(); + m_CryptoMode = false; + // Move Position to compressed Data; + RINOK(InStream_SeekSet(m_Stream, m_Position)) + AddToSeekValue(item.PackSize); // m_Position points to next header; + // if (okItem) + return S_OK; + /* + else + continue; + */ + } + + if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) + { + error = k_ErrorType_DecryptionError; + return S_OK; + } + + if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) + { + if (m_FileHeaderData.Size() < 7 + 4) + m_FileHeaderData.ChangeSize_KeepData(7 + 4, 7); + if (!ReadBytesAndTestSize(m_FileHeaderData + 7, 4)) + { + error = k_ErrorType_UnexpectedEnd; + return S_OK; + } + UInt32 dataSize = Get32(m_FileHeaderData + 7); + AddToSeekValue(dataSize); + if (m_CryptoMode && dataSize > (1 << 27)) + { + error = k_ErrorType_DecryptionError; + return S_OK; + } + m_CryptoPos = m_BlockHeader.HeadSize; + } + else + m_CryptoPos = 0; + + { + UInt64 newPos = m_Position + m_BlockHeader.HeadSize; + if (newPos > ArcInfo.FileSize) + { + error = k_ErrorType_UnexpectedEnd; + return S_OK; + } + } + AddToSeekValue(m_BlockHeader.HeadSize); + FinishCryptoBlock(); + m_CryptoMode = false; + } +} + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidAttrib, + + kpidEncrypted, + kpidSolid, + kpidCommented, + kpidSplitBefore, + kpidSplitAfter, + kpidCRC, + kpidHostOS, + kpidMethod, + kpidUnpackVer, + + kpidVolumeIndex +}; + +static const Byte kArcProps[] = +{ + kpidTotalPhySize, + kpidCharacts, + kpidSolid, + kpidNumBlocks, + // kpidEncrypted, + kpidIsVolume, + kpidVolumeIndex, + kpidNumVolumes + // kpidCommented +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +UInt64 CHandler::GetPackSize(unsigned refIndex) const +{ + const CRefItem &refItem = _refItems[refIndex]; + UInt64 totalPackSize = 0; + for (unsigned i = 0; i < refItem.NumItems; i++) + totalPackSize += _items[refItem.ItemIndex + i].PackSize; + return totalPackSize; +} + +bool CHandler::IsSolid(unsigned refIndex) const +{ + const CItem &item = _items[_refItems[refIndex].ItemIndex]; + if (item.UnPackVersion < 20) + { + if (_arcInfo.IsSolid()) + return (refIndex > 0); + return false; + } + return item.IsSolid(); +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidVolumeIndex: if (_arcInfo.Is_VolNumber_Defined()) prop = (UInt32)_arcInfo.VolNumber; break; + case kpidSolid: prop = _arcInfo.IsSolid(); break; + case kpidCharacts: + { + AString s (FlagsToString(k_Flags, Z7_ARRAY_SIZE(k_Flags), _arcInfo.Flags)); + // FLAGS_TO_PROP(k_Flags, _arcInfo.Flags, prop); + if (_arcInfo.Is_DataCRC_Defined()) + { + s.Add_Space_if_NotEmpty(); + s += "VolCRC"; + } + prop = s; + break; + } + // case kpidEncrypted: prop = _arcInfo.IsEncrypted(); break; // it's for encrypted names. + case kpidIsVolume: prop = _arcInfo.IsVolume(); break; + case kpidNumVolumes: prop = (UInt32)_arcs.Size(); break; + case kpidOffset: if (_arcs.Size() == 1 && _arcInfo.StartPos != 0) prop = _arcInfo.StartPos; break; + + case kpidTotalPhySize: + { + if (_arcs.Size() > 1) + { + UInt64 sum = 0; + FOR_VECTOR (v, _arcs) + sum += _arcs[v].PhySize; + prop = sum; + } + break; + } + + case kpidPhySize: + { + if (_arcs.Size() != 0) + prop = _arcInfo.GetPhySize(); + break; + } + + // case kpidCommented: prop = _arcInfo.IsCommented(); break; + + case kpidNumBlocks: + { + UInt32 numBlocks = 0; + FOR_VECTOR (i, _refItems) + if (!IsSolid(i)) + numBlocks++; + prop = (UInt32)numBlocks; + break; + } + + + case kpidError: + { + // if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; + + if (/* &_missingVol || */ !_missingVolName.IsEmpty()) + { + UString s ("Missing volume : "); + s += _missingVolName; + prop = s; + } + break; + } + + case kpidErrorFlags: + { + UInt32 v = _errorFlags; + if (!_isArc) + v |= kpv_ErrorFlags_IsNotArc; + prop = v; + break; + } + + case kpidWarningFlags: + { + if (_warningFlags != 0) + prop = _warningFlags; + break; + } + + case kpidExtension: + if (_arcs.Size() == 1) + { + if (_arcInfo.Is_VolNumber_Defined()) + { + AString s ("part"); + UInt32 v = (UInt32)_arcInfo.VolNumber + 1; + if (v < 10) + s += '0'; + s.Add_UInt32(v); + s += ".rar"; + prop = s; + } + } + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _refItems.Size(); + return S_OK; +} + +static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &ft) +{ + if (!NTime::DosTime_To_FileTime(rarTime.DosTime, ft)) + return false; + 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, utc; + if (RarTimeToFileTime(rarTime, localFileTime) + && LocalFileTimeToFileTime(&localFileTime, &utc)) + prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_100ns); + /* + else + utc.dwHighDateTime = utc.dwLowDateTime = 0; + // prop.SetAsTimeFrom_FT_Prec(utc, k_PropVar_TimePrec_100ns); + */ +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CRefItem &refItem = _refItems[index]; + const CItem &item = _items[refItem.ItemIndex]; + const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + /* + const CItem *mainItem = &item; + if (item.BaseFileIndex >= 0) + mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; + */ + switch (propID) + { + case kpidPath: + { + /* + UString u; + if (item.BaseFileIndex >= 0) + u = mainItem->GetName(); + u += item.GetName(); + */ + prop = (const wchar_t *)NItemName::WinPathToOsPath(item.GetName()); + break; + } + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break; + case kpidPackSize: prop = GetPackSize(index); break; + case kpidMTime: RarTimeToProp(item.MTime, prop); break; + case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; + case kpidATime: if (item.ATimeDefined) RarTimeToProp(item.ATime, prop); break; + case kpidAttrib: prop = item.GetWinAttrib(); break; + case kpidEncrypted: prop = item.IsEncrypted(); break; + case kpidSolid: prop = IsSolid(index); break; + case kpidCommented: prop = item.IsCommented(); break; + case kpidSplitBefore: prop = item.IsSplitBefore(); break; + case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; + + case kpidVolumeIndex: + if (_arcInfo.Is_VolNumber_Defined()) + prop = (UInt32)(_arcInfo.VolNumber + refItem.VolumeIndex); + break; + + case kpidCRC: + { + prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); + break; + } + case kpidUnpackVer: prop = item.UnPackVersion; break; + case kpidMethod: + { + char s[16]; + Byte m = item.Method; + if (m < (Byte)'0' || m > (Byte)'5') + ConvertUInt32ToString(m, s); + else + { + s[0] = 'm'; + s[1] = (char)m; + s[2] = 0; + if (!item.IsDir()) + { + s[2] = ':'; + ConvertUInt32ToString(16 + item.GetDictSize(), &s[3]); + } + } + prop = s; + break; + } + case kpidHostOS: + TYPE_TO_PROP(kHostOS, item.HostOS, prop); + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +HRESULT CHandler::Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback) +{ + { + CMyComPtr openVolumeCallback; + CMyComPtr getTextPassword; + + CVolumeName seqName; + + UInt64 totalBytes = 0; + UInt64 curBytes = 0; + + if (openCallback) + { + openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + } + + bool nextVol_is_Required = false; + + CInArchive archive; + + for (;;) + { + CMyComPtr inStream; + if (!_arcs.IsEmpty()) + { + if (!openVolumeCallback) + break; + + if (_arcs.Size() == 1) + { + if (!_arcInfo.IsVolume()) + break; + UString baseName; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt != VT_BSTR) + break; + baseName = prop.bstrVal; + } + if (!seqName.InitName(baseName, _arcInfo.HaveNewVolumeName())) + break; + /* + if (_arcInfo.HaveNewVolumeName() && !_arcInfo.IsFirstVolume()) + { + seqName.MakeBeforeFirstName(); + } + */ + } + + const UString volName = seqName.GetNextName(); + + HRESULT result = openVolumeCallback->GetStream(volName, &inStream); + + if (result != S_OK && result != S_FALSE) + return result; + + if (!inStream || result != S_OK) + { + if (nextVol_is_Required) + _missingVolName = volName; + break; + } + } + else + inStream = stream; + + UInt64 endPos; + RINOK(InStream_AtBegin_GetSize(inStream, endPos)) + if (openCallback) + { + totalBytes += endPos; + RINOK(openCallback->SetTotal(NULL, &totalBytes)) + } + + RINOK(archive.Open(inStream, maxCheckStartPosition)) + _isArc = true; + CItem item; + + for (;;) + { + if (archive.m_Position > endPos) + { + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; + break; + } + + EErrorType error; + // bool decryptionError; + // AString errorMessageLoc; + bool filled; + HRESULT result = archive.GetNextItem(item, getTextPassword, filled, error); + + if (error != k_ErrorType_OK) + { + if (error == k_ErrorType_UnexpectedEnd) + _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; + else if (error == k_ErrorType_Corrupted) + _errorFlags |= kpv_ErrorFlags_HeadersError; + else if (error == k_ErrorType_DecryptionError) + _errorFlags |= kpv_ErrorFlags_EncryptedHeadersError; + + // AddErrorMessage(errorMessageLoc); + } + RINOK(result) + + if (!filled) + { + if (error == k_ErrorType_DecryptionError && _items.IsEmpty()) + return S_FALSE; + + if (archive.ArcInfo.ExtraZeroTail_is_Possible()) + { + /* if there is recovery record for multivolume archive, + RAR adds 18 bytes (ZERO bytes) at the end for alignment. + We must skip these bytes to prevent phySize warning. */ + RINOK(InStream_SeekSet(inStream, archive.ArcInfo.EndPos)) + bool areThereNonZeros; + UInt64 numZeros; + const UInt64 maxSize = 1 << 12; + RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)) + if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) + archive.ArcInfo.EndPos += numZeros; + } + break; + } + + if (item.IgnoreItem()) + continue; + + bool needAdd = true; + + if (item.IsSplitBefore()) + { + if (!_refItems.IsEmpty()) + { + CRefItem &refItem = _refItems.Back(); + refItem.NumItems++; + needAdd = false; + } + } + + if (needAdd) + { + CRefItem refItem; + refItem.ItemIndex = _items.Size(); + refItem.NumItems = 1; + refItem.VolumeIndex = _arcs.Size(); + _refItems.Add(refItem); + } + + _items.Add(item); + + if (openCallback && _items.Size() % 100 == 0) + { + UInt64 numFiles = _items.Size(); + UInt64 numBytes = curBytes + item.Position; + RINOK(openCallback->SetCompleted(&numFiles, &numBytes)) + } + } + + if (archive.HeaderErrorWarning) + _warningFlags |= kpv_ErrorFlags_HeadersError; + + /* + if (archive.m_Position < endPos) + _warningFlags |= kpv_ErrorFlags_DataAfterEnd; + */ + if (_arcs.IsEmpty()) + _arcInfo = archive.ArcInfo; + // _arcInfo.EndPos = archive.EndPos; + + curBytes += endPos; + { + CArc &arc = _arcs.AddNew(); + arc.PhySize = archive.ArcInfo.GetPhySize(); + arc.Stream = inStream; + } + + nextVol_is_Required = false; + + if (!archive.ArcInfo.IsVolume()) + break; + + if (archive.ArcInfo.EndOfArchive_was_Read) + { + if (!archive.ArcInfo.AreMoreVolumes()) + break; + nextVol_is_Required = true; + } + } + } + + /* + int baseFileIndex = -1; + for (unsigned i = 0; i < _refItems.Size(); i++) + { + CItem &item = _items[_refItems[i].ItemIndex]; + if (item.IsAltStream) + item.BaseFileIndex = baseFileIndex; + else + baseFileIndex = i; + } + */ + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + Close(); + // try + { + HRESULT res = Open2(stream, maxCheckStartPosition, openCallback); + /* + if (res != S_OK) + Close(); + */ + + return res; + } + // catch(const CInArchiveException &) { Close(); return S_FALSE; } + // catch(...) { Close(); throw; } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + COM_TRY_BEGIN + // _errorMessage.Empty(); + _missingVolName.Empty(); + _errorFlags = 0; + _warningFlags = 0; + _isArc = false; + _refItems.Clear(); + _items.Clear(); + _arcs.Clear(); + return S_OK; + COM_TRY_END +} + +struct CMethodItem +{ + Byte RarUnPackVersion; + CMyComPtr Coder; +}; + + +Z7_CLASS_IMP_NOQIB_1( + CVolsInStream + , ISequentialInStream +) + UInt64 _rem; + ISequentialInStream *_stream; + const CObjectVector *_arcs; + const CObjectVector *_items; + CRefItem _refItem; + unsigned _curIndex; + UInt32 _crc; + bool _calcCrc; + +public: + void Init(const CObjectVector *arcs, + const CObjectVector *items, + const CRefItem &refItem) + { + _arcs = arcs; + _items = items; + _refItem = refItem; + _curIndex = 0; + _stream = NULL; + CrcIsOK = true; + } + + bool CrcIsOK; +}; + + +Z7_COM7F_IMF(CVolsInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + UInt32 realProcessedSize = 0; + + while (size != 0) + { + if (!_stream) + { + if (_curIndex >= _refItem.NumItems) + break; + const CItem &item = (*_items)[_refItem.ItemIndex + _curIndex]; + unsigned volIndex = _refItem.VolumeIndex + _curIndex; + if (volIndex >= _arcs->Size()) + { + return S_OK; + // return S_FALSE; + } + IInStream *s = (*_arcs)[volIndex].Stream; + RINOK(InStream_SeekSet(s, item.GetDataPosition())) + _stream = s; + _calcCrc = (CrcIsOK && item.IsSplitAfter()); + _crc = CRC_INIT_VAL; + _rem = item.PackSize; + } + { + UInt32 cur = size; + if (cur > _rem) + cur = (UInt32)_rem; + UInt32 num = cur; + HRESULT res = _stream->Read(data, cur, &cur); + if (_calcCrc) + _crc = CrcUpdate(_crc, data, cur); + realProcessedSize += cur; + if (processedSize) + *processedSize = realProcessedSize; + data = (Byte *)data + cur; + size -= cur; + _rem -= cur; + if (_rem == 0) + { + const CItem &item = (*_items)[_refItem.ItemIndex + _curIndex]; + _curIndex++; + if (_calcCrc && CRC_GET_DIGEST(_crc) != item.FileCRC) + CrcIsOK = false; + _stream = NULL; + } + if (res != S_OK) + return res; + if (realProcessedSize != 0) + return S_OK; + if (cur == 0 && num != 0) + return S_OK; + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + CMyComPtr getTextPassword; + UInt64 // censoredTotalUnPacked = 0, + // censoredTotalPacked = 0, + importantTotalUnPacked = 0; + // importantTotalPacked = 0; + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _refItems.Size(); + if (numItems == 0) + return S_OK; + unsigned lastIndex = 0; + CRecordVector importantIndexes; + CRecordVector extractStatuses; + + bool isThereUndefinedSize = false; + + for (UInt32 t = 0; t < numItems; t++) + { + unsigned index = allFilesMode ? t : indices[t]; + + { + const CRefItem &refItem = _refItems[index]; + const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + if (item.Is_Size_Defined()) + { + // censoredTotalUnPacked += item.Size; + } + else + isThereUndefinedSize = true; + + // censoredTotalPacked += item.PackSize; + } + + unsigned j; + for (j = lastIndex; j <= index; j++) + // if (!_items[_refItems[j].ItemIndex].IsSolid()) + if (!IsSolid(j)) + lastIndex = j; + + for (j = lastIndex; j <= index; j++) + { + const CRefItem &refItem = _refItems[j]; + const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + if (item.Is_Size_Defined()) + importantTotalUnPacked += item.Size; + else + isThereUndefinedSize = true; + // importantTotalPacked += item.PackSize; + importantIndexes.Add(j); + extractStatuses.Add(j == index); + } + + lastIndex = index + 1; + } + + if (importantTotalUnPacked != 0 || !isThereUndefinedSize) + { + RINOK(extractCallback->SetTotal(importantTotalUnPacked)) + } + + UInt64 currentImportantTotalUnPacked = 0; + UInt64 currentImportantTotalPacked = 0; + UInt64 currentUnPackSize, currentPackSize; + + CObjectVector methodItems; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + + CFilterCoder *filterStreamSpec = new CFilterCoder(false); + CMyComPtr filterStream = filterStreamSpec; + + NCrypto::NRar2::CDecoder *rar20CryptoDecoderSpec = NULL; + CMyComPtr rar20CryptoDecoder; + NCrypto::NRar3::CDecoder *rar3CryptoDecoderSpec = NULL; + CMyComPtr rar3CryptoDecoder; + + CVolsInStream *volsInStreamSpec = NULL; + CMyComPtr volsInStream; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + bool solidStart = true; + + for (unsigned i = 0;; + i++, + currentImportantTotalUnPacked += currentUnPackSize, + currentImportantTotalPacked += currentPackSize) + { + lps->InSize = currentImportantTotalPacked; + lps->OutSize = currentImportantTotalUnPacked; + RINOK(lps->SetCur()) + + if (i >= importantIndexes.Size()) + break; + + CMyComPtr realOutStream; + + Int32 askMode; + if (extractStatuses[i]) + askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + else + askMode = NExtract::NAskMode::kSkip; + + UInt32 index = importantIndexes[i]; + + const CRefItem &refItem = _refItems[index]; + const CItem &item = _items[refItem.ItemIndex]; + const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + UInt64 outSize = (UInt64)(Int64)-1; + currentUnPackSize = 0; + if (lastItem.Is_Size_Defined()) + { + outSize = lastItem.Size; + currentUnPackSize = outSize; + } + + currentPackSize = GetPackSize(index); + + if (item.IgnoreItem()) + continue; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (!IsSolid(index)) + solidStart = true; + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + bool mustBeProcessedAnywhere = false; + if (i < importantIndexes.Size() - 1) + { + // const CRefItem &nextRefItem = _refItems[importantIndexes[i + 1]]; + // const CItem &nextItemInfo = _items[nextRefItem.ItemIndex]; + // mustBeProcessedAnywhere = nextItemInfo.IsSolid(); + mustBeProcessedAnywhere = IsSolid(importantIndexes[i + 1]); + } + + if (!mustBeProcessedAnywhere && !testMode && !realOutStream) + continue; + + if (!realOutStream && !testMode) + askMode = NExtract::NAskMode::kSkip; + + RINOK(extractCallback->PrepareOperation(askMode)) + + COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + + if (!volsInStream) + { + volsInStreamSpec = new CVolsInStream; + volsInStream = volsInStreamSpec; + } + + volsInStreamSpec->Init(&_arcs, &_items, refItem); + + UInt64 packSize = currentPackSize; + + // packedPos += item.PackSize; + // unpackedPos += 0; + + CMyComPtr inStream; + + if (item.IsEncrypted()) + { + // CMyComPtr cryptoSetPassword; + + if (item.UnPackVersion >= 29) + { + if (!rar3CryptoDecoder) + { + rar3CryptoDecoderSpec = new NCrypto::NRar3::CDecoder; + rar3CryptoDecoder = rar3CryptoDecoderSpec; + } + // rar3CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); + /* + CMyComPtr cryptoProperties; + RINOK(rar3CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &cryptoProperties)); + */ + RINOK(rar3CryptoDecoderSpec->SetDecoderProperties2(item.Salt, item.HasSalt() ? sizeof(item.Salt) : 0)) + filterStreamSpec->Filter = rar3CryptoDecoder; + } + else if (item.UnPackVersion >= 20) + { + if (!rar20CryptoDecoder) + { + rar20CryptoDecoderSpec = new NCrypto::NRar2::CDecoder; + rar20CryptoDecoder = rar20CryptoDecoderSpec; + } + filterStreamSpec->Filter = rar20CryptoDecoder; + } + else + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + // RINOK(filterStreamSpec->Filter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); + + if (!getTextPassword) + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + + if (!getTextPassword) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + // if (getTextPassword) + { + CMyComBSTR_Wipe password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + + if (item.UnPackVersion >= 29) + { + unsigned len = 0; + if (password) + len = MyStringLen(password); + if (len > kPasswordLen_MAX) + len = kPasswordLen_MAX; + CByteBuffer_Wipe buffer(len * 2); + for (unsigned k = 0; k < len; k++) + { + wchar_t c = password[k]; + ((Byte *)buffer)[k * 2] = (Byte)c; + ((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8); + } + rar3CryptoDecoderSpec->SetPassword((const Byte *)buffer, len * 2); + } + else + { + AString_Wipe oemPassword; + if (password) + { + UString_Wipe unicode; + unicode.SetFromBstr(password); + if (unicode.Len() > kPasswordLen_MAX) + unicode.DeleteFrom(kPasswordLen_MAX); + UnicodeStringToMultiByte2(oemPassword, unicode, CP_OEMCP); + } + rar20CryptoDecoderSpec->SetPassword((const Byte *)(const char *)oemPassword, oemPassword.Len()); + } + } + /* + else + { + RINOK(cryptoSetPassword->CryptoSetPassword(NULL, 0)); + } + */ + + filterStreamSpec->SetInStream(volsInStream); + filterStreamSpec->SetOutStreamSize(NULL); + inStream = filterStream; + } + else + { + inStream = volsInStream; + } + + CMyComPtr commonCoder; + + switch (item.Method) + { + case '0': + { + commonCoder = copyCoder; + break; + } + case '1': + case '2': + case '3': + case '4': + case '5': + { + unsigned m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].RarUnPackVersion == item.UnPackVersion) + break; + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.RarUnPackVersion = item.UnPackVersion; + + mi.Coder.Release(); + if (item.UnPackVersion <= 40) + { + UInt32 methodID = 0x40300; + if (item.UnPackVersion < 20) + methodID += 1; + else if (item.UnPackVersion < 29) + methodID += 2; + else + methodID += 3; + RINOK(CreateCoder_Id(EXTERNAL_CODECS_VARS methodID, false, mi.Coder)) + } + + if (!mi.Coder) + { + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + m = methodItems.Add(mi); + } + CMyComPtr decoder = methodItems[m].Coder; + + CMyComPtr compressSetDecoderProperties; + RINOK(decoder.QueryInterface(IID_ICompressSetDecoderProperties2, + &compressSetDecoderProperties)) + + Byte isSolid = (Byte)((IsSolid(index) || item.IsSplitBefore()) ? 1: 0); + if (solidStart) + { + isSolid = 0; + solidStart = false; + } + + + RINOK(compressSetDecoderProperties->SetDecoderProperties2(&isSolid, 1)) + + commonCoder = decoder; + break; + } + default: + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnsupportedMethod)) + continue; + } + + HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress); + + if (item.IsEncrypted()) + filterStreamSpec->ReleaseInStream(); + + if (outSize == (UInt64)(Int64)-1) + currentUnPackSize = outStreamSpec->GetSize(); + + int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kCRCError; + outStream.Release(); + + if (result != S_OK) + { + if (result == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else if (result == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + return result; + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +REGISTER_ARC_I( + "Rar", "rar r00", NULL, 3, + kMarker, + 0, + NArcInfoFlags::kFindSignature, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHandler.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHandler.h 2024-01-05 10:00:00.000000000 +0000 @@ -1,116 +1,115 @@ -// RarHandler.h - -#ifndef __RAR_HANDLER_H -#define __RAR_HANDLER_H - -#include "../IArchive.h" - -#include "../../Common/CreateCoder.h" - -#include "RarItem.h" - -namespace NArchive { -namespace NRar { - -struct CInArcInfo -{ - UInt32 Flags; - Byte EncryptVersion; - - UInt64 StartPos; - UInt64 EndPos; - UInt64 FileSize; - - UInt32 EndFlags; - UInt32 VolNumber; - UInt32 DataCRC; - bool EndOfArchive_was_Read; - - CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {} - - UInt64 GetPhySize() const { return EndPos - StartPos; } - - bool ExtraZeroTail_is_Possible() const { return IsVolume() && IsRecovery() && EndOfArchive_was_Read; } - - bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } - bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } - // kLock - bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } - bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } - // kAuthenticity - bool IsRecovery() const { return (Flags & NHeader::NArchive::kRecovery) != 0; } - bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } - bool IsFirstVolume() const { return (Flags & NHeader::NArchive::kFirstVolume) != 0; } - - // bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } - // bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } - - bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; } - bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; } - bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; } -}; - -struct CArc -{ - CMyComPtr Stream; - UInt64 PhySize; - // CByteBuffer Comment; - - CArc(): PhySize(0) {} - ISequentialInStream *CreateLimitedStream(UInt64 offset, UInt64 size) const; -}; - -struct CRefItem -{ - unsigned VolumeIndex; - unsigned ItemIndex; - unsigned NumItems; -}; - -class CHandler: - public IInArchive, - PUBLIC_ISetCompressCodecsInfo - public CMyUnknownImp -{ - CRecordVector _refItems; - CObjectVector _items; - CObjectVector _arcs; - NArchive::NRar::CInArcInfo _arcInfo; - // AString _errorMessage; - UInt32 _errorFlags; - UInt32 _warningFlags; - bool _isArc; - UString _missingVolName; - - DECL_EXTERNAL_CODECS_VARS - - UInt64 GetPackSize(unsigned refIndex) const; - bool IsSolid(unsigned refIndex) const; - - /* - void AddErrorMessage(const AString &s) - { - if (!_errorMessage.IsEmpty()) - _errorMessage += '\n'; - _errorMessage += s; - } - */ - - HRESULT Open2(IInStream *stream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback); - -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - - DECL_ISetCompressCodecsInfo -}; - -}} - -#endif +// RarHandler.h + +#ifndef ZIP7_INC_RAR_HANDLER_H +#define ZIP7_INC_RAR_HANDLER_H + +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#include "RarItem.h" + +namespace NArchive { +namespace NRar { + +struct CInArcInfo +{ + UInt32 Flags; + Byte EncryptVersion; + + UInt64 StartPos; + UInt64 EndPos; + UInt64 FileSize; + + UInt32 EndFlags; + UInt32 VolNumber; + UInt32 DataCRC; + bool EndOfArchive_was_Read; + + CInArcInfo(): EndFlags(0), VolNumber(0), EndOfArchive_was_Read(false) {} + + UInt64 GetPhySize() const { return EndPos - StartPos; } + + bool ExtraZeroTail_is_Possible() const { return IsVolume() && IsRecovery() && EndOfArchive_was_Read; } + + bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } + bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } + // kLock + bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } + bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } + // kAuthenticity + bool IsRecovery() const { return (Flags & NHeader::NArchive::kRecovery) != 0; } + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } + bool IsFirstVolume() const { return (Flags & NHeader::NArchive::kFirstVolume) != 0; } + + // bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } + // bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } + + bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; } + bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; } + bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; } +}; + +struct CArc +{ + CMyComPtr Stream; + UInt64 PhySize; + // CByteBuffer Comment; + + CArc(): PhySize(0) {} + ISequentialInStream *CreateLimitedStream(UInt64 offset, UInt64 size) const; +}; + +struct CRefItem +{ + unsigned VolumeIndex; + unsigned ItemIndex; + unsigned NumItems; +}; + +class CHandler Z7_final: + public IInArchive, + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + DECL_ISetCompressCodecsInfo + + bool _isArc; + + CRecordVector _refItems; + CObjectVector _items; + CObjectVector _arcs; + NArchive::NRar::CInArcInfo _arcInfo; + // AString _errorMessage; + UInt32 _errorFlags; + UInt32 _warningFlags; + UString _missingVolName; + + DECL_EXTERNAL_CODECS_VARS + + UInt64 GetPackSize(unsigned refIndex) const; + bool IsSolid(unsigned refIndex) const; + + /* + void AddErrorMessage(const AString &s) + { + if (!_errorMessage.IsEmpty()) + _errorMessage.Add_LF(); + _errorMessage += s; + } + */ + + HRESULT Open2(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarHeader.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,209 +1,209 @@ -// Archive/RarHeader.h - -#ifndef __ARCHIVE_RAR_HEADER_H -#define __ARCHIVE_RAR_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace NRar { -namespace NHeader { - -const unsigned kMarkerSize = 7; - -const unsigned kArchiveSolid = 0x1; - -namespace NBlockType -{ - enum EBlockType - { - kMarker = 0x72, - kArchiveHeader, - kFileHeader, - kCommentHeader, - kOldAuthenticity, - kOldSubBlock, - kRecoveryRecord, - kAuthenticity, - kSubBlock, - kEndOfArchive - }; -} - -namespace NArchive -{ - const UInt16 kVolume = 1; - const UInt16 kComment = 2; - const UInt16 kLock = 4; - const UInt16 kSolid = 8; - const UInt16 kNewVolName = 0x10; // ('volname.partN.rar') - const UInt16 kAuthenticity = 0x20; - const UInt16 kRecovery = 0x40; - const UInt16 kBlockEncryption = 0x80; - const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) - - // const UInt16 kEncryptVer = 0x200; // RAR 3.6 : that feature was discarded by origial RAR - - const UInt16 kEndOfArc_Flags_NextVol = 1; - const UInt16 kEndOfArc_Flags_DataCRC = 2; - const UInt16 kEndOfArc_Flags_RevSpace = 4; - const UInt16 kEndOfArc_Flags_VolNumber = 8; - - const unsigned kHeaderSizeMin = 7; - - const unsigned kArchiveHeaderSize = 13; - - const unsigned kBlockHeadersAreEncrypted = 0x80; -} - -namespace NFile -{ - const unsigned kSplitBefore = 1 << 0; - const unsigned kSplitAfter = 1 << 1; - const unsigned kEncrypted = 1 << 2; - const unsigned kComment = 1 << 3; - const unsigned kSolid = 1 << 4; - - const unsigned kDictBitStart = 5; - const unsigned kNumDictBits = 3; - const unsigned kDictMask = (1 << kNumDictBits) - 1; - const unsigned kDictDirectoryValue = 0x7; - - const unsigned kSize64Bits = 1 << 8; - const unsigned kUnicodeName = 1 << 9; - const unsigned kSalt = 1 << 10; - const unsigned kOldVersion = 1 << 11; - const unsigned kExtTime = 1 << 12; - // const unsigned kExtFlags = 1 << 13; - // const unsigned kSkipIfUnknown = 1 << 14; - - const unsigned kLongBlock = 1 << 15; - - /* - struct CBlock - { - // UInt16 HeadCRC; - // Byte Type; - // UInt16 Flags; - // UInt16 HeadSize; - UInt32 PackSize; - UInt32 UnPackSize; - Byte HostOS; - UInt32 FileCRC; - UInt32 Time; - Byte UnPackVersion; - Byte Method; - UInt16 NameSize; - UInt32 Attributes; - }; - */ - - /* - struct CBlock32 - { - UInt16 HeadCRC; - Byte Type; - UInt16 Flags; - UInt16 HeadSize; - UInt32 PackSize; - UInt32 UnPackSize; - Byte HostOS; - UInt32 FileCRC; - UInt32 Time; - Byte UnPackVersion; - Byte Method; - UInt16 NameSize; - UInt32 Attributes; - UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, - bool anExtraDataDefined = false, Byte *anExtraData = 0) const; - }; - struct CBlock64 - { - UInt16 HeadCRC; - Byte Type; - UInt16 Flags; - UInt16 HeadSize; - UInt32 PackSizeLow; - UInt32 UnPackSizeLow; - Byte HostOS; - UInt32 FileCRC; - UInt32 Time; - Byte UnPackVersion; - Byte Method; - UInt16 NameSize; - UInt32 Attributes; - UInt32 PackSizeHigh; - UInt32 UnPackSizeHigh; - UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const; - }; - */ - - const unsigned kLabelFileAttribute = 0x08; - const unsigned kWinFileDirectoryAttributeMask = 0x10; - - enum CHostOS - { - kHostMSDOS = 0, - kHostOS2 = 1, - kHostWin32 = 2, - kHostUnix = 3, - kHostMacOS = 4, - kHostBeOS = 5 - }; -} - -namespace NBlock -{ - const UInt16 kLongBlock = 1 << 15; - struct CBlock - { - UInt16 CRC; - Byte Type; - UInt16 Flags; - UInt16 HeadSize; - // UInt32 DataSize; - }; -} - -/* -struct CSubBlock -{ - UInt16 HeadCRC; - Byte HeadType; - UInt16 Flags; - UInt16 HeadSize; - UInt32 DataSize; - UInt16 SubType; - Byte Level; // Reserved : Must be 0 -}; - -struct CCommentBlock -{ - UInt16 HeadCRC; - Byte HeadType; - UInt16 Flags; - UInt16 HeadSize; - UInt16 UnpSize; - Byte UnpVer; - Byte Method; - UInt16 CommCRC; -}; - - -struct CProtectHeader -{ - UInt16 HeadCRC; - Byte HeadType; - UInt16 Flags; - UInt16 HeadSize; - UInt32 DataSize; - Byte Version; - UInt16 RecSectors; - UInt32 TotalBlocks; - Byte Mark[8]; -}; -*/ - -}}} - -#endif +// Archive/RarHeader.h + +#ifndef ZIP7_INC_ARCHIVE_RAR_HEADER_H +#define ZIP7_INC_ARCHIVE_RAR_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace NRar { +namespace NHeader { + +const unsigned kMarkerSize = 7; + +const unsigned kArchiveSolid = 0x1; + +namespace NBlockType +{ + enum EBlockType + { + kMarker = 0x72, + kArchiveHeader, + kFileHeader, + kCommentHeader, + kOldAuthenticity, + kOldSubBlock, + kRecoveryRecord, + kAuthenticity, + kSubBlock, + kEndOfArchive + }; +} + +namespace NArchive +{ + const UInt16 kVolume = 1; + const UInt16 kComment = 2; + const UInt16 kLock = 4; + const UInt16 kSolid = 8; + const UInt16 kNewVolName = 0x10; // ('volname.partN.rar') + const UInt16 kAuthenticity = 0x20; + const UInt16 kRecovery = 0x40; + const UInt16 kBlockEncryption = 0x80; + const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) + + // const UInt16 kEncryptVer = 0x200; // RAR 3.6 : that feature was discarded by origial RAR + + const UInt16 kEndOfArc_Flags_NextVol = 1; + const UInt16 kEndOfArc_Flags_DataCRC = 2; + const UInt16 kEndOfArc_Flags_RevSpace = 4; + const UInt16 kEndOfArc_Flags_VolNumber = 8; + + const unsigned kHeaderSizeMin = 7; + + const unsigned kArchiveHeaderSize = 13; + + const unsigned kBlockHeadersAreEncrypted = 0x80; +} + +namespace NFile +{ + const unsigned kSplitBefore = 1 << 0; + const unsigned kSplitAfter = 1 << 1; + const unsigned kEncrypted = 1 << 2; + const unsigned kComment = 1 << 3; + const unsigned kSolid = 1 << 4; + + const unsigned kDictBitStart = 5; + const unsigned kNumDictBits = 3; + const unsigned kDictMask = (1 << kNumDictBits) - 1; + const unsigned kDictDirectoryValue = 0x7; + + const unsigned kSize64Bits = 1 << 8; + const unsigned kUnicodeName = 1 << 9; + const unsigned kSalt = 1 << 10; + const unsigned kOldVersion = 1 << 11; + const unsigned kExtTime = 1 << 12; + // const unsigned kExtFlags = 1 << 13; + // const unsigned kSkipIfUnknown = 1 << 14; + + const unsigned kLongBlock = 1 << 15; + + /* + struct CBlock + { + // UInt16 HeadCRC; + // Byte Type; + // UInt16 Flags; + // UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + }; + */ + + /* + struct CBlock32 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSize; + UInt32 UnPackSize; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize, + bool anExtraDataDefined = false, Byte *anExtraData = 0) const; + }; + struct CBlock64 + { + UInt16 HeadCRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + UInt32 PackSizeLow; + UInt32 UnPackSizeLow; + Byte HostOS; + UInt32 FileCRC; + UInt32 Time; + Byte UnPackVersion; + Byte Method; + UInt16 NameSize; + UInt32 Attributes; + UInt32 PackSizeHigh; + UInt32 UnPackSizeHigh; + UInt16 GetRealCRC(const void *aName, UInt32 aNameSize) const; + }; + */ + + const unsigned kLabelFileAttribute = 0x08; + const unsigned kWinFileDirectoryAttributeMask = 0x10; + + enum CHostOS + { + kHostMSDOS = 0, + kHostOS2 = 1, + kHostWin32 = 2, + kHostUnix = 3, + kHostMacOS = 4, + kHostBeOS = 5 + }; +} + +namespace NBlock +{ + const UInt16 kLongBlock = 1 << 15; + struct CBlock + { + UInt16 CRC; + Byte Type; + UInt16 Flags; + UInt16 HeadSize; + // UInt32 DataSize; + }; +} + +/* +struct CSubBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + UInt16 SubType; + Byte Level; // Reserved : Must be 0 +}; + +struct CCommentBlock +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt16 UnpSize; + Byte UnpVer; + Byte Method; + UInt16 CommCRC; +}; + + +struct CProtectHeader +{ + UInt16 HeadCRC; + Byte HeadType; + UInt16 Flags; + UInt16 HeadSize; + UInt32 DataSize; + Byte Version; + UInt16 RecSectors; + UInt32 TotalBlocks; + Byte Mark[8]; +}; +*/ + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarItem.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,97 +1,97 @@ -// RarItem.h - -#ifndef __ARCHIVE_RAR_ITEM_H -#define __ARCHIVE_RAR_ITEM_H - -#include "../../../Common/StringConvert.h" - -#include "RarHeader.h" - -namespace NArchive { -namespace NRar { - -struct CRarTime -{ - UInt32 DosTime; - Byte LowSecond; - Byte SubTime[3]; -}; - -struct CItem -{ - UInt64 Size; - UInt64 PackSize; - - CRarTime CTime; - CRarTime ATime; - CRarTime MTime; - - UInt32 FileCRC; - UInt32 Attrib; - - UInt16 Flags; - Byte HostOS; - Byte UnPackVersion; - Byte Method; - - bool CTimeDefined; - bool ATimeDefined; - - AString Name; - UString UnicodeName; - - Byte Salt[8]; - - bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; } - - bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } - bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } - bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } - bool IsSplitBefore() const { return (Flags & NHeader::NFile::kSplitBefore) != 0; } - bool IsSplitAfter() const { return (Flags & NHeader::NFile::kSplitAfter) != 0; } - bool HasSalt() const { return (Flags & NHeader::NFile::kSalt) != 0; } - bool HasExtTime() const { return (Flags & NHeader::NFile::kExtTime) != 0; } - bool HasUnicodeName()const { return (Flags & NHeader::NFile::kUnicodeName) != 0; } - bool IsOldVersion() const { return (Flags & NHeader::NFile::kOldVersion) != 0; } - - UInt32 GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } - bool IsDir() const; - bool IgnoreItem() const; - UInt32 GetWinAttrib() const; - - UInt64 Position; - unsigned MainPartSize; - UInt16 CommentSize; - UInt16 AlignSize; - - // int BaseFileIndex; - // bool IsAltStream; - - UString GetName() const - { - if (( /* IsAltStream || */ HasUnicodeName()) && !UnicodeName.IsEmpty()) - return UnicodeName; - return MultiByteToUnicodeString(Name, CP_OEMCP); - } - - void Clear() - { - CTimeDefined = false; - ATimeDefined = false; - Name.Empty(); - UnicodeName.Empty(); - // IsAltStream = false; - // BaseFileIndex = -1; - } - - CItem() { Clear(); } - - UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; } - // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; } - UInt64 GetCommentPosition() const { return Position + MainPartSize; } - UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; } -}; - -}} - -#endif +// RarItem.h + +#ifndef ZIP7_INC_ARCHIVE_RAR_ITEM_H +#define ZIP7_INC_ARCHIVE_RAR_ITEM_H + +#include "../../../Common/StringConvert.h" + +#include "RarHeader.h" + +namespace NArchive { +namespace NRar { + +struct CRarTime +{ + UInt32 DosTime; + Byte LowSecond; + Byte SubTime[3]; +}; + +struct CItem +{ + UInt64 Size; + UInt64 PackSize; + + CRarTime CTime; + CRarTime ATime; + CRarTime MTime; + + UInt32 FileCRC; + UInt32 Attrib; + + UInt16 Flags; + Byte HostOS; + Byte UnPackVersion; + Byte Method; + + bool CTimeDefined; + bool ATimeDefined; + + AString Name; + UString UnicodeName; + + Byte Salt[8]; + + bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; } + + bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } + bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } + bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } + bool IsSplitBefore() const { return (Flags & NHeader::NFile::kSplitBefore) != 0; } + bool IsSplitAfter() const { return (Flags & NHeader::NFile::kSplitAfter) != 0; } + bool HasSalt() const { return (Flags & NHeader::NFile::kSalt) != 0; } + bool HasExtTime() const { return (Flags & NHeader::NFile::kExtTime) != 0; } + bool HasUnicodeName()const { return (Flags & NHeader::NFile::kUnicodeName) != 0; } + bool IsOldVersion() const { return (Flags & NHeader::NFile::kOldVersion) != 0; } + + UInt32 GetDictSize() const { return (Flags >> NHeader::NFile::kDictBitStart) & NHeader::NFile::kDictMask; } + bool IsDir() const; + bool IgnoreItem() const; + UInt32 GetWinAttrib() const; + + UInt64 Position; + unsigned MainPartSize; + UInt16 CommentSize; + UInt16 AlignSize; + + // int BaseFileIndex; + // bool IsAltStream; + + UString GetName() const + { + if (( /* IsAltStream || */ HasUnicodeName()) && !UnicodeName.IsEmpty()) + return UnicodeName; + return MultiByteToUnicodeString(Name, CP_OEMCP); + } + + void Clear() + { + CTimeDefined = false; + ATimeDefined = false; + Name.Empty(); + UnicodeName.Empty(); + // IsAltStream = false; + // BaseFileIndex = -1; + } + + CItem() { Clear(); } + + UInt64 GetFullSize() const { return MainPartSize + CommentSize + AlignSize + PackSize; } + // DWORD GetHeaderWithCommentSize() const { return MainPartSize + CommentSize; } + UInt64 GetCommentPosition() const { return Position + MainPartSize; } + UInt64 GetDataPosition() const { return GetCommentPosition() + CommentSize + AlignSize; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarVol.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarVol.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/RarVol.h 2015-09-17 19:02:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/RarVol.h 2023-01-17 12:00:00.000000000 +0000 @@ -1,129 +1,136 @@ -// RarVol.h - -#ifndef __ARCHIVE_RAR_VOL_H -#define __ARCHIVE_RAR_VOL_H - -#include "../../../Common/StringConvert.h" - -#include "RarHeader.h" - -namespace NArchive { -namespace NRar { - -inline bool IsDigit(wchar_t c) -{ - return c >= L'0' && c <= L'9'; -} - -class CVolumeName -{ - bool _needChangeForNext; - UString _before; - UString _changed; - UString _after; -public: - CVolumeName(): _needChangeForNext(true) {}; - - bool InitName(const UString &name, bool newStyle = true) - { - _needChangeForNext = true; - _after.Empty(); - UString base = name; - int dotPos = name.ReverseFind_Dot(); - - if (dotPos >= 0) - { - const UString ext = name.Ptr(dotPos + 1); - if (ext.IsEqualTo_Ascii_NoCase("rar")) - { - _after = name.Ptr(dotPos); - base.DeleteFrom(dotPos); - } - else if (ext.IsEqualTo_Ascii_NoCase("exe")) - { - _after.SetFromAscii(".rar"); - base.DeleteFrom(dotPos); - } - else if (!newStyle) - { - if (ext.IsEqualTo_Ascii_NoCase("000") || - ext.IsEqualTo_Ascii_NoCase("001") || - ext.IsEqualTo_Ascii_NoCase("r00") || - ext.IsEqualTo_Ascii_NoCase("r01")) - { - _changed = ext; - _before = name.Left(dotPos + 1); - return true; - } - } - } - - if (newStyle) - { - unsigned i = base.Len(); - - for (; i != 0; i--) - if (!IsDigit(base[i - 1])) - break; - - if (i != base.Len()) - { - _before = base.Left(i); - _changed = base.Ptr(i); - return true; - } - } - - _after.Empty(); - _before = base; - _before += L'.'; - _changed.SetFromAscii("r00"); - _needChangeForNext = false; - return true; - } - - /* - void MakeBeforeFirstName() - { - unsigned len = _changed.Len(); - _changed.Empty(); - for (unsigned i = 0; i < len; i++) - _changed += L'0'; - } - */ - - UString GetNextName() - { - if (_needChangeForNext) - { - unsigned i = _changed.Len(); - if (i == 0) - return UString(); - for (;;) - { - wchar_t c = _changed[--i]; - if (c == L'9') - { - c = L'0'; - _changed.ReplaceOneCharAtPos(i, c); - if (i == 0) - { - _changed.InsertAtFront(L'1'); - break; - } - continue; - } - c++; - _changed.ReplaceOneCharAtPos(i, c); - break; - } - } - - _needChangeForNext = true; - return _before + _changed + _after; - } -}; - -}} - -#endif +// RarVol.h + +#ifndef ZIP7_INC_ARCHIVE_RAR_VOL_H +#define ZIP7_INC_ARCHIVE_RAR_VOL_H + +#include "../../../Common/StringConvert.h" + +#include "RarHeader.h" + +namespace NArchive { +namespace NRar { + +inline bool IsDigit(wchar_t c) +{ + return c >= L'0' && c <= L'9'; +} + +class CVolumeName +{ + bool _needChangeForNext; + UString _before; + UString _changed; + UString _after; +public: + CVolumeName(): _needChangeForNext(true) {} + + bool InitName(const UString &name, bool newStyle = true) + { + _needChangeForNext = true; + _after.Empty(); + UString base (name); + const int dotPos = name.ReverseFind_Dot(); + + if (dotPos >= 0) + { + const UString ext (name.Ptr(dotPos + 1)); + if (ext.IsEqualTo_Ascii_NoCase("rar")) + { + _after = name.Ptr(dotPos); + base.DeleteFrom(dotPos); + } + else if (ext.IsEqualTo_Ascii_NoCase("exe")) + { + _after = ".rar"; + base.DeleteFrom(dotPos); + } + else if (!newStyle) + { + if (ext.IsEqualTo_Ascii_NoCase("000") || + ext.IsEqualTo_Ascii_NoCase("001") || + ext.IsEqualTo_Ascii_NoCase("r00") || + ext.IsEqualTo_Ascii_NoCase("r01")) + { + _changed = ext; + _before.SetFrom(name.Ptr(), (unsigned)dotPos + 1); + return true; + } + } + } + + if (newStyle) + { + 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 != k) + { + _before.SetFrom(base.Ptr(), i); + _changed.SetFrom(base.Ptr(i), k - i); + _after.Insert(0, base.Ptr(k)); + return true; + } + } + + _after.Empty(); + _before = base; + _before.Add_Dot(); + _changed = "r00"; + _needChangeForNext = false; + return true; + } + + /* + void MakeBeforeFirstName() + { + unsigned len = _changed.Len(); + _changed.Empty(); + for (unsigned i = 0; i < len; i++) + _changed += L'0'; + } + */ + + UString GetNextName() + { + if (_needChangeForNext) + { + unsigned i = _changed.Len(); + if (i == 0) + return UString(); + for (;;) + { + wchar_t c = _changed[--i]; + if (c == L'9') + { + c = L'0'; + _changed.ReplaceOneCharAtPos(i, c); + if (i == 0) + { + _changed.InsertAtFront(L'1'); + break; + } + continue; + } + c++; + _changed.ReplaceOneCharAtPos(i, c); + break; + } + } + + _needChangeForNext = true; + return _before + _changed + _after; + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Rar/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Rar/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Rar/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/RpmHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/RpmHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/RpmHandler.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/RpmHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,739 +1,775 @@ -// RpmHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/MyBuffer.h" -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariant.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -// #define _SHOW_RPM_METADATA - -using namespace NWindows; - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) - -namespace NArchive { -namespace NRpm { - -static const unsigned kNameSize = 66; -static const unsigned kLeadSize = kNameSize + 30; -static const unsigned k_HeaderSig_Size = 16; -static const unsigned k_Entry_Size = 16; - -#define RPMSIG_NONE 0 // Old signature -#define RPMSIG_PGP262_1024 1 // Old signature -#define RPMSIG_HEADERSIG 5 // New signature - -enum -{ - kRpmType_Bin = 0, - kRpmType_Src = 1 -}; - -// There are two sets of TAGs: signature tags and header tags - -// ----- Signature TAGs ----- - -#define RPMSIGTAG_SIZE 1000 // Header + Payload size (32bit) - -// ----- Header TAGs ----- - -#define RPMTAG_NAME 1000 -#define RPMTAG_VERSION 1001 -#define RPMTAG_RELEASE 1002 -#define RPMTAG_BUILDTIME 1006 -#define RPMTAG_OS 1021 // string (old version used int?) -#define RPMTAG_ARCH 1022 // string (old version used int?) -#define RPMTAG_PAYLOADFORMAT 1124 -#define RPMTAG_PAYLOADCOMPRESSOR 1125 -// #define RPMTAG_PAYLOADFLAGS 1126 - -enum -{ - k_EntryType_NULL, - k_EntryType_CHAR, - k_EntryType_INT8, - k_EntryType_INT16, - k_EntryType_INT32, - k_EntryType_INT64, - k_EntryType_STRING, - k_EntryType_BIN, - k_EntryType_STRING_ARRAY, - k_EntryType_I18NSTRING -}; - -static const char * const k_CPUs[] = -{ - "noarch" - , "i386" - , "alpha" - , "sparc" - , "mips" - , "ppc" - , "m68k" - , "sgi" - , "rs6000" - , "ia64" - , "sparc64" // 10 ??? - , "mipsel" - , "arm" - , "m68kmint" - , "s390" - , "s390x" - , "ppc64" - , "sh" - , "xtensa" - , "aarch64" // 19 -}; - -static const char * const k_OS[] = -{ - "0" - , "Linux" - , "Irix" - , "solaris" - , "SunOS" - , "AmigaOS" // AIX - , "HP-UX" - , "osf" - , "FreeBSD" - , "SCO_SV" - , "Irix64" - , "NextStep" - , "bsdi" - , "machten" - , "cygwin32-NT" - , "cygwin32-95" - , "MP_RAS" - , "MiNT" - , "OS/390" - , "VM/ESA" - , "Linux/390" // "Linux/ESA" - , "Darwin" // "MacOSX" 21 -}; - -struct CLead -{ - unsigned char Major; - unsigned char Minor; - UInt16 Type; - UInt16 Cpu; - UInt16 Os; - UInt16 SignatureType; - char Name[kNameSize]; - // char Reserved[16]; - - void Parse(const Byte *p) - { - Major = p[4]; - Minor = p[5]; - Type = Get16(p + 6); - Cpu= Get16(p + 8); - memcpy(Name, p + 10, kNameSize); - p += 10 + kNameSize; - Os = Get16(p); - SignatureType = Get16(p + 2); - } - - bool IsSupported() const { return Major >= 3 && Type <= 1; } -}; - -struct CEntry -{ - UInt32 Tag; - UInt32 Type; - UInt32 Offset; - UInt32 Count; - - void Parse(const Byte *p) - { - Tag = Get32(p + 0); - Type = Get32(p + 4); - Offset = Get32(p + 8); - Count = Get32(p + 12); - } -}; - -class CHandler: public CHandlerCont -{ - UInt64 _headersSize; // is equal to start offset of payload data - UInt64 _payloadSize; - UInt64 _size; - // _size = _payloadSize, if (_payloadSize_Defined) - // _size = (fileSize - _headersSize), if (!_payloadSize_Defined) - UInt64 _phySize; // _headersSize + _payloadSize, if (_phySize_Defined) - UInt32 _headerPlusPayload_Size; - UInt32 _buildTime; - - bool _payloadSize_Defined; - bool _phySize_Defined; - bool _headerPlusPayload_Size_Defined; - bool _time_Defined; - - Byte _payloadSig[6]; // start data of payload - - AString _name; // p7zip - AString _version; // 9.20.1 - AString _release; // 8.1.1 - AString _arch; // x86_64 - AString _os; // linux - - AString _format; // cpio - AString _compressor; // xz, gzip, bzip2 - - CLead _lead; - - #ifdef _SHOW_RPM_METADATA - AString _metadata; - #endif - - void SetTime(NCOM::CPropVariant &prop) const - { - if (_time_Defined && _buildTime != 0) - { - FILETIME ft; - if (NTime::UnixTime64ToFileTime(_buildTime, ft)) - prop = ft; - } - } - - void SetStringProp(const AString &s, NCOM::CPropVariant &prop) const - { - UString us; - if (!ConvertUTF8ToUnicode(s, us)) - us = GetUnicodeString(s); - if (!us.IsEmpty()) - prop = us; - } - - void AddCPU(AString &s) const; - AString GetBaseName() const; - void AddSubFileExtension(AString &res) const; - - HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader); - HRESULT Open2(ISequentialInStream *stream); - - virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const - { - pos = _headersSize; - size = _size; - return NExtract::NOperationResult::kOK; - } - -public: - INTERFACE_IInArchive_Cont(;) -}; - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - kpidCpu, - kpidHostOS, - kpidCTime - #ifdef _SHOW_RPM_METADATA - , kpidComment - #endif -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidCTime -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -void CHandler::AddCPU(AString &s) const -{ - if (!_arch.IsEmpty()) - s += _arch; - else - { - if (_lead.Type == kRpmType_Bin) - { - char temp[16]; - const char *p; - if (_lead.Cpu < ARRAY_SIZE(k_CPUs)) - p = k_CPUs[_lead.Cpu]; - else - { - ConvertUInt32ToString(_lead.Cpu, temp); - p = temp; - } - s += p; - } - } -} - -AString CHandler::GetBaseName() const -{ - AString s; - if (!_name.IsEmpty()) - { - s = _name; - if (!_version.IsEmpty()) - { - s += '-'; - s += _version; - } - if (!_release.IsEmpty()) - { - s += '-'; - s += _release; - } - } - else - s.SetFrom_CalcLen(_lead.Name, kNameSize); - - s += '.'; - if (_lead.Type == kRpmType_Src) - s += "src"; - else - AddCPU(s); - return s; -} - -void CHandler::AddSubFileExtension(AString &res) const -{ - if (!_format.IsEmpty()) - res += _format; - else - res += "cpio"; - res += '.'; - - const char *s; - - if (!_compressor.IsEmpty()) - { - s = _compressor; - if (_compressor == "bzip2") - s = "bz2"; - else if (_compressor == "gzip") - s = "gz"; - } - else - { - const Byte *p = _payloadSig; - if (p[0] == 0x1F && p[1] == 0x8B) - s = "gz"; - else if (p[0] == 0xFD && p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' && p[5] == 0) - s = "xz"; - else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h' && p[3] >= '1' && p[3] <= '9') - s = "bz2"; - else - s = "lzma"; - } - - res += s; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: prop = (UInt32)0; break; - - case kpidHeadersSize: prop = _headersSize; break; - case kpidPhySize: if (_phySize_Defined) prop = _phySize; break; - - case kpidMTime: - case kpidCTime: - SetTime(prop); - break; - - case kpidCpu: - { - AString s; - AddCPU(s); - /* - if (_lead.Type == kRpmType_Src) - s = "src"; - */ - SetStringProp(s, prop); - break; - } - - case kpidHostOS: - { - if (!_os.IsEmpty()) - SetStringProp(_os, prop); - else - { - char temp[16]; - const char *p; - if (_lead.Os < ARRAY_SIZE(k_OS)) - p = k_OS[_lead.Os]; - else - { - ConvertUInt32ToString(_lead.Os, temp); - p = temp; - } - prop = p; - } - break; - } - - #ifdef _SHOW_RPM_METADATA - case kpidComment: SetStringProp(_metadata, prop); break; - #endif - - case kpidName: - { - AString s = GetBaseName(); - s += ".rpm"; - SetStringProp(s, prop); - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidSize: - case kpidPackSize: - prop = _size; - break; - - case kpidMTime: - case kpidCTime: - SetTime(prop); - break; - - case kpidPath: - { - AString s = GetBaseName(); - s += '.'; - AddSubFileExtension(s); - SetStringProp(s, prop); - break; - } - - /* - case kpidExtension: - { - prop = GetSubFileExtension(); - break; - } - */ - } - prop.Detach(value); - return S_OK; -} - -#ifdef _SHOW_RPM_METADATA -static inline char GetHex(unsigned value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} -#endif - -HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader) -{ - UInt32 numEntries; - UInt32 dataLen; - { - char buf[k_HeaderSig_Size]; - RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size)); - if (Get32(buf) != 0x8EADE801) // buf[3] = 0x01 - is version - return S_FALSE; - // reserved = Get32(buf + 4); - numEntries = Get32(buf + 8); - dataLen = Get32(buf + 12); - if (numEntries >= 1 << 24) - return S_FALSE; - } - size_t indexSize = (size_t)numEntries * k_Entry_Size; - size_t headerSize = indexSize + dataLen; - if (headerSize < dataLen) - return S_FALSE; - CByteBuffer buffer(headerSize); - RINOK(ReadStream_FALSE(stream, buffer, headerSize)); - - for (UInt32 i = 0; i < numEntries; i++) - { - CEntry entry; - - entry.Parse(buffer + (size_t)i * k_Entry_Size); - if (entry.Offset > dataLen) - return S_FALSE; - - const Byte *p = buffer + indexSize + entry.Offset; - size_t rem = dataLen - entry.Offset; - - if (!isMainHeader) - { - if (entry.Tag == RPMSIGTAG_SIZE && - entry.Type == k_EntryType_INT32) - { - if (rem < 4 || entry.Count != 1) - return S_FALSE; - _headerPlusPayload_Size = Get32(p); - _headerPlusPayload_Size_Defined = true; - } - } - else - { - #ifdef _SHOW_RPM_METADATA - { - char temp[16]; - ConvertUInt32ToString(entry.Tag, temp); - - _metadata += temp; - _metadata += ": "; - } - #endif - - if (entry.Type == k_EntryType_STRING) - { - if (entry.Count != 1) - return S_FALSE; - size_t j; - for (j = 0; j < rem && p[j] != 0; j++); - if (j == rem) - return S_FALSE; - AString s = (const char *)p; - switch (entry.Tag) - { - case RPMTAG_NAME: _name = s; break; - case RPMTAG_VERSION: _version = s; break; - case RPMTAG_RELEASE: _release = s; break; - case RPMTAG_ARCH: _arch = s; break; - case RPMTAG_OS: _os = s; break; - case RPMTAG_PAYLOADFORMAT: _format = s; break; - case RPMTAG_PAYLOADCOMPRESSOR: _compressor = s; break; - } - - #ifdef _SHOW_RPM_METADATA - _metadata += s; - #endif - } - else if (entry.Type == k_EntryType_INT32) - { - if (rem / 4 < entry.Count) - return S_FALSE; - if (entry.Tag == RPMTAG_BUILDTIME) - { - if (entry.Count != 1) - return S_FALSE; - _buildTime = Get32(p); - _time_Defined = true; - } - - #ifdef _SHOW_RPM_METADATA - for (UInt32 t = 0; t < entry.Count; t++) - { - if (t != 0) - _metadata.Add_Space(); - char temp[16]; - ConvertUInt32ToString(Get32(p + t * 4), temp); - _metadata += temp; - } - #endif - } - - #ifdef _SHOW_RPM_METADATA - - else if ( - entry.Type == k_EntryType_STRING_ARRAY || - entry.Type == k_EntryType_I18NSTRING) - { - const Byte *p2 = p; - size_t rem2 = rem; - for (UInt32 t = 0; t < entry.Count; t++) - { - if (rem2 == 0) - return S_FALSE; - if (t != 0) - _metadata += '\n'; - size_t j; - for (j = 0; j < rem2 && p2[j] != 0; j++); - if (j == rem2) - return S_FALSE; - _metadata += (const char *)p2; - j++; - p2 += j; - rem2 -= j; - } - } - else if (entry.Type == k_EntryType_INT16) - { - if (rem / 2 < entry.Count) - return S_FALSE; - for (UInt32 t = 0; t < entry.Count; t++) - { - if (t != 0) - _metadata.Add_Space(); - char temp[16]; - ConvertUInt32ToString(Get16(p + t * 2), temp); - _metadata += temp; - } - } - else if (entry.Type == k_EntryType_BIN) - { - if (rem < entry.Count) - return S_FALSE; - for (UInt32 t = 0; t < entry.Count; t++) - { - const unsigned b = p[t]; - _metadata += GetHex((b >> 4) & 0xF); - _metadata += GetHex(b & 0xF); - } - } - else - { - // p = p; - } - _metadata += '\n'; - #endif - } - } - - headerSize += k_HeaderSig_Size; - _headersSize += headerSize; - if (isMainHeader && _headerPlusPayload_Size_Defined) - { - if (_headerPlusPayload_Size < headerSize) - return S_FALSE; - _payloadSize = _headerPlusPayload_Size - headerSize; - _size = _payloadSize; - _phySize = _headersSize + _payloadSize; - _payloadSize_Defined = true; - _phySize_Defined = true; - } - return S_OK; -} - -HRESULT CHandler::Open2(ISequentialInStream *stream) -{ - { - Byte buf[kLeadSize]; - RINOK(ReadStream_FALSE(stream, buf, kLeadSize)); - if (Get32(buf) != 0xEDABEEDB) - return S_FALSE; - _lead.Parse(buf); - if (!_lead.IsSupported()) - return S_FALSE; - } - - _headersSize = kLeadSize; - - if (_lead.SignatureType == RPMSIG_NONE) - { - ; - } - else if (_lead.SignatureType == RPMSIG_PGP262_1024) - { - Byte temp[256]; - RINOK(ReadStream_FALSE(stream, temp, sizeof(temp))); - } - else if (_lead.SignatureType == RPMSIG_HEADERSIG) - { - RINOK(ReadHeader(stream, false)); - unsigned pos = (unsigned)_headersSize & 7; - if (pos != 0) - { - Byte temp[8]; - unsigned num = 8 - pos; - RINOK(ReadStream_FALSE(stream, temp, num)); - _headersSize += num; - } - } - else - return S_FALSE; - - return ReadHeader(stream, true); -} - - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) -{ - COM_TRY_BEGIN - { - Close(); - RINOK(Open2(inStream)); - - // start of payload is allowed to be unaligned - RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig))); - - if (!_payloadSize_Defined) - { - UInt64 endPos; - RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); - _size = endPos - _headersSize; - } - _stream = inStream; - return S_OK; - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _headersSize = 0; - _payloadSize = 0; - _size = 0; - _phySize = 0; - _headerPlusPayload_Size = 0; - - _payloadSize_Defined = false; - _phySize_Defined = false; - _headerPlusPayload_Size_Defined = false; - _time_Defined = false; - - _name.Empty(); - _version.Empty(); - _release.Empty(); - _arch.Empty(); - _os.Empty(); - - _format.Empty(); - _compressor.Empty(); - - #ifdef _SHOW_RPM_METADATA - _metadata.Empty(); - #endif - - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -static const Byte k_Signature[] = { 0xED, 0xAB, 0xEE, 0xDB}; - -REGISTER_ARC_I( - "Rpm", "rpm", 0, 0xEB, - k_Signature, - 0, - 0, - NULL) - -}} +// RpmHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/MyBuffer.h" +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringConvert.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +// #define Z7_RPM_SHOW_METADATA + +using namespace NWindows; + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) + +namespace NArchive { +namespace NRpm { + +static const unsigned kNameSize = 66; +static const unsigned kLeadSize = kNameSize + 30; +static const unsigned k_HeaderSig_Size = 16; +static const unsigned k_Entry_Size = 16; + +#define RPMSIG_NONE 0 // Old signature +#define RPMSIG_PGP262_1024 1 // Old signature +#define RPMSIG_HEADERSIG 5 // New signature + +enum +{ + kRpmType_Bin = 0, + kRpmType_Src = 1 +}; + +// There are two sets of TAGs: signature tags and header tags + +// ----- Signature TAGs ----- + +#define RPMSIGTAG_SIZE 1000 // Header + Payload size (32bit) + +// ----- Header TAGs ----- + +#define RPMTAG_NAME 1000 +#define RPMTAG_VERSION 1001 +#define RPMTAG_RELEASE 1002 +#define RPMTAG_BUILDTIME 1006 +#define RPMTAG_OS 1021 // string (old version used int?) +#define RPMTAG_ARCH 1022 // string (old version used int?) +#define RPMTAG_PAYLOADFORMAT 1124 +#define RPMTAG_PAYLOADCOMPRESSOR 1125 +// #define RPMTAG_PAYLOADFLAGS 1126 + +enum +{ + k_EntryType_NULL, + k_EntryType_CHAR, + k_EntryType_INT8, + k_EntryType_INT16, + k_EntryType_INT32, + k_EntryType_INT64, + k_EntryType_STRING, + k_EntryType_BIN, + k_EntryType_STRING_ARRAY, + k_EntryType_I18NSTRING +}; + +static const char * const k_CPUs[] = +{ + "noarch" + , "i386" + , "alpha" + , "sparc" + , "mips" + , "ppc" + , "m68k" + , "sgi" + , "rs6000" + , "ia64" + , "sparc64" // 10 ??? + , "mipsel" + , "arm" + , "m68kmint" + , "s390" + , "s390x" + , "ppc64" + , "sh" + , "xtensa" + , "aarch64" // 19 + , "mipsr6" // 20 + , "mips64r6" // 21 + , "riscv64" // 22 + , "loongarch64" // 23 + // , "24" + // , "25" + // , "loongarch64" // 26 : why 23 and 26 for loongarch64? + // 255 for some non specified arch +}; + +static const char * const k_OS[] = +{ + "0" + , "Linux" + , "Irix" + , "solaris" + , "SunOS" + , "AmigaOS" // AIX + , "HP-UX" + , "osf" + , "FreeBSD" + , "SCO_SV" + , "Irix64" + , "NextStep" + , "bsdi" + , "machten" + , "cygwin32-NT" + , "cygwin32-95" + , "MP_RAS" + , "MiNT" + , "OS/390" + , "VM/ESA" + , "Linux/390" // "Linux/ESA" + , "Darwin" // "MacOSX" 21 +}; + +struct CLead +{ + Byte Major; + // Byte Minor; + UInt16 Type; + UInt16 Cpu; + UInt16 Os; + UInt16 SignatureType; + char Name[kNameSize]; + // char Reserved[16]; + + void Parse(const Byte *p) + { + Major = p[4]; + // Minor = p[5]; + Type = Get16(p + 6); + Cpu= Get16(p + 8); + memcpy(Name, p + 10, kNameSize); + p += 10 + kNameSize; + Os = Get16(p); + SignatureType = Get16(p + 2); + } + + bool IsSupported() const { return Major >= 3 && Type <= 1; } +}; + +struct CEntry +{ + UInt32 Tag; + UInt32 Type; + UInt32 Offset; + UInt32 Count; + + void Parse(const Byte *p) + { + Tag = Get32(p + 0); + Type = Get32(p + 4); + Offset = Get32(p + 8); + Count = Get32(p + 12); + } +}; + + +#ifdef Z7_RPM_SHOW_METADATA +struct CMetaFile +{ + UInt32 Tag; + UInt32 Offset; + UInt32 Size; +}; +#endif + +Z7_class_CHandler_final: public CHandlerCont +{ + Z7_IFACE_COM7_IMP(IInArchive_Cont) + + UInt64 _headersSize; // is equal to start offset of payload data + UInt64 _payloadSize; + UInt64 _size; + // _size = _payloadSize, if (_payloadSize_Defined) + // _size = (fileSize - _headersSize), if (!_payloadSize_Defined) + UInt64 _phySize; // _headersSize + _payloadSize, if (_phySize_Defined) + UInt32 _headerPlusPayload_Size; + UInt32 _buildTime; + + bool _payloadSize_Defined; + bool _phySize_Defined; + bool _headerPlusPayload_Size_Defined; + bool _time_Defined; + + Byte _payloadSig[6]; // start data of payload + + AString _name; // p7zip + AString _version; // 9.20.1 + AString _release; // 8.1.1 + AString _arch; // x86_64 + AString _os; // linux + + AString _format; // cpio + AString _compressor; // xz, gzip, bzip2, lzma, zstd + + CLead _lead; + + #ifdef Z7_RPM_SHOW_METADATA + AString _metadata; + CRecordVector _metaFiles; + #endif + + void SetTime(NCOM::CPropVariant &prop) const + { + if (_time_Defined && _buildTime != 0) + PropVariant_SetFrom_UnixTime(prop, _buildTime); + } + + void SetStringProp(const AString &s, NCOM::CPropVariant &prop) const + { + UString us; + if (!ConvertUTF8ToUnicode(s, us)) + us = GetUnicodeString(s); + if (!us.IsEmpty()) + prop = us; + } + + void AddCPU(AString &s) const; + AString GetBaseName() const; + void AddSubFileExtension(AString &res) const; + + HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader); + HRESULT Open2(ISequentialInStream *stream); + + virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const Z7_override + { + pos = _headersSize; + size = _size; + return NExtract::NOperationResult::kOK; + } +}; + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidCpu, + kpidHostOS, + kpidCTime + #ifdef Z7_RPM_SHOW_METADATA + , kpidComment + #endif +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidCTime +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +void CHandler::AddCPU(AString &s) const +{ + if (!_arch.IsEmpty()) + s += _arch; + else + { + if (_lead.Type == kRpmType_Bin) + { + if (_lead.Cpu < Z7_ARRAY_SIZE(k_CPUs)) + s += k_CPUs[_lead.Cpu]; + else + s.Add_UInt32(_lead.Cpu); + } + } +} + +AString CHandler::GetBaseName() const +{ + AString s; + if (!_name.IsEmpty()) + { + s = _name; + if (!_version.IsEmpty()) + { + s.Add_Minus(); + s += _version; + } + if (!_release.IsEmpty()) + { + s.Add_Minus(); + s += _release; + } + } + else + s.SetFrom_CalcLen(_lead.Name, kNameSize); + + s.Add_Dot(); + if (_lead.Type == kRpmType_Src) + s += "src"; + else + AddCPU(s); + return s; +} + +void CHandler::AddSubFileExtension(AString &res) const +{ + if (!_format.IsEmpty()) + res += _format; + else + res += "cpio"; + res.Add_Dot(); + + const char *s; + + if (!_compressor.IsEmpty()) + { + s = _compressor; + if (_compressor.IsEqualTo("bzip2")) + s = "bz2"; + else if (_compressor.IsEqualTo("gzip")) + s = "gz"; + else if (_compressor.IsEqualTo("zstd")) + s = "zst"; + } + else + { + const Byte *p = _payloadSig; + if (p[0] == 0x1F && p[1] == 0x8B && p[2] == 8) + s = "gz"; + else if (p[0] == 0xFD && p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' && p[5] == 0) + s = "xz"; + else if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h' && p[3] >= '1' && p[3] <= '9') + s = "bz2"; + else if (p[0] == 0x28 && p[1] == 0xb5 && p[2] == 0x2f && p[3] == 0xfd) + s = "zst"; + else + s = "lzma"; + } + + res += s; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + + case kpidHeadersSize: prop = _headersSize; break; + case kpidPhySize: if (_phySize_Defined) prop = _phySize; break; + + case kpidMTime: + case kpidCTime: + SetTime(prop); + break; + + case kpidCpu: + { + AString s; + AddCPU(s); + /* + if (_lead.Type == kRpmType_Src) + s = "src"; + */ + SetStringProp(s, prop); + break; + } + + case kpidHostOS: + { + if (!_os.IsEmpty()) + SetStringProp(_os, prop); + else + { + TYPE_TO_PROP(k_OS, _lead.Os, prop); + } + break; + } + + #ifdef Z7_RPM_SHOW_METADATA + // case kpidComment: SetStringProp(_metadata, prop); break; + #endif + + case kpidName: + { + SetStringProp(GetBaseName() + ".rpm", prop); + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + if (index == 0) + switch (propID) + { + case kpidSize: + case kpidPackSize: + prop = _size; + break; + + case kpidMTime: + case kpidCTime: + SetTime(prop); + break; + + case kpidPath: + { + AString s (GetBaseName()); + s.Add_Dot(); + AddSubFileExtension(s); + SetStringProp(s, prop); + break; + } + + /* + case kpidExtension: + { + prop = GetSubFileExtension(); + break; + } + */ + } + #ifdef Z7_RPM_SHOW_METADATA + else + { + index--; + if (index > _metaFiles.Size()) + return E_INVALIDARG; + const CMetaFile &meta = _metaFiles[index]; + switch (propID) + { + case kpidSize: + case kpidPackSize: + prop = meta.Size; + break; + + case kpidMTime: + case kpidCTime: + SetTime(prop); + break; + + case kpidPath: + { + AString s ("[META]"); + s.Add_PathSepar(); + s.Add_UInt32(meta.Tag); + prop = s; + break; + } + } + } + #endif + + prop.Detach(value); + return S_OK; +} + + +HRESULT CHandler::ReadHeader(ISequentialInStream *stream, bool isMainHeader) +{ + UInt32 numEntries; + UInt32 dataLen; + { + char buf[k_HeaderSig_Size]; + RINOK(ReadStream_FALSE(stream, buf, k_HeaderSig_Size)) + if (Get32(buf) != 0x8EADE801) // buf[3] = 0x01 - is version + return S_FALSE; + // reserved = Get32(buf + 4); + numEntries = Get32(buf + 8); + dataLen = Get32(buf + 12); + if (numEntries >= 1 << 24) + return S_FALSE; + } + size_t indexSize = (size_t)numEntries * k_Entry_Size; + size_t headerSize = indexSize + dataLen; + if (headerSize < dataLen) + return S_FALSE; + CByteBuffer buffer(headerSize); + RINOK(ReadStream_FALSE(stream, buffer, headerSize)) + + for (UInt32 i = 0; i < numEntries; i++) + { + CEntry entry; + + entry.Parse(buffer + (size_t)i * k_Entry_Size); + if (entry.Offset > dataLen) + return S_FALSE; + + const Byte *p = buffer + indexSize + entry.Offset; + size_t rem = dataLen - entry.Offset; + + if (!isMainHeader) + { + if (entry.Tag == RPMSIGTAG_SIZE && + entry.Type == k_EntryType_INT32) + { + if (rem < 4 || entry.Count != 1) + return S_FALSE; + _headerPlusPayload_Size = Get32(p); + _headerPlusPayload_Size_Defined = true; + } + } + else + { + #ifdef Z7_RPM_SHOW_METADATA + { + _metadata.Add_UInt32(entry.Tag); + _metadata += ": "; + } + #endif + + if (entry.Type == k_EntryType_STRING) + { + if (entry.Count != 1) + return S_FALSE; + size_t j; + for (j = 0; j < rem && p[j] != 0; j++); + if (j == rem) + return S_FALSE; + AString s((const char *)p); + switch (entry.Tag) + { + case RPMTAG_NAME: _name = s; break; + case RPMTAG_VERSION: _version = s; break; + case RPMTAG_RELEASE: _release = s; break; + case RPMTAG_ARCH: _arch = s; break; + case RPMTAG_OS: _os = s; break; + case RPMTAG_PAYLOADFORMAT: _format = s; break; + case RPMTAG_PAYLOADCOMPRESSOR: _compressor = s; break; + } + + #ifdef Z7_RPM_SHOW_METADATA + _metadata += s; + #endif + } + else if (entry.Type == k_EntryType_INT32) + { + if (rem / 4 < entry.Count) + return S_FALSE; + if (entry.Tag == RPMTAG_BUILDTIME) + { + if (entry.Count != 1) + return S_FALSE; + _buildTime = Get32(p); + _time_Defined = true; + } + + #ifdef Z7_RPM_SHOW_METADATA + for (UInt32 t = 0; t < entry.Count; t++) + { + if (t != 0) + _metadata.Add_Space(); + _metadata.Add_UInt32(Get32(p + t * 4)); + } + #endif + } + + #ifdef Z7_RPM_SHOW_METADATA + + else if ( + entry.Type == k_EntryType_STRING_ARRAY || + entry.Type == k_EntryType_I18NSTRING) + { + const Byte *p2 = p; + size_t rem2 = rem; + for (UInt32 t = 0; t < entry.Count; t++) + { + if (rem2 == 0) + return S_FALSE; + if (t != 0) + _metadata.Add_LF(); + size_t j; + for (j = 0; j < rem2 && p2[j] != 0; j++); + if (j == rem2) + return S_FALSE; + _metadata += (const char *)p2; + j++; + p2 += j; + rem2 -= j; + } + } + else if (entry.Type == k_EntryType_INT16) + { + if (rem / 2 < entry.Count) + return S_FALSE; + for (UInt32 t = 0; t < entry.Count; t++) + { + if (t != 0) + _metadata.Add_Space(); + _metadata.Add_UInt32(Get16(p + t * 2)); + } + } + else if (entry.Type == k_EntryType_BIN) + { + if (rem < entry.Count) + return S_FALSE; + for (UInt32 t = 0; t < entry.Count; t++) + { + const unsigned b = p[t]; + _metadata += GET_HEX_CHAR_UPPER(b >> 4); + _metadata += GET_HEX_CHAR_UPPER(b & 0xF); + } + } + else + { + // p = p; + } + + _metadata.Add_LF(); + #endif + } + + #ifdef Z7_RPM_SHOW_METADATA + CMetaFile meta; + meta.Offset = entry.Offset; + meta.Tag = entry.Tag; + meta.Size = entry.Count; + _metaFiles.Add(meta); + #endif + } + + headerSize += k_HeaderSig_Size; + _headersSize += headerSize; + if (isMainHeader && _headerPlusPayload_Size_Defined) + { + if (_headerPlusPayload_Size < headerSize) + return S_FALSE; + _payloadSize = _headerPlusPayload_Size - headerSize; + _size = _payloadSize; + _phySize = _headersSize + _payloadSize; + _payloadSize_Defined = true; + _phySize_Defined = true; + } + return S_OK; +} + +HRESULT CHandler::Open2(ISequentialInStream *stream) +{ + { + Byte buf[kLeadSize]; + RINOK(ReadStream_FALSE(stream, buf, kLeadSize)) + if (Get32(buf) != 0xEDABEEDB) + return S_FALSE; + _lead.Parse(buf); + if (!_lead.IsSupported()) + return S_FALSE; + } + + _headersSize = kLeadSize; + + if (_lead.SignatureType == RPMSIG_NONE) + { + + } + else if (_lead.SignatureType == RPMSIG_PGP262_1024) + { + Byte temp[256]; + RINOK(ReadStream_FALSE(stream, temp, sizeof(temp))) + } + else if (_lead.SignatureType == RPMSIG_HEADERSIG) + { + RINOK(ReadHeader(stream, false)) + unsigned pos = (unsigned)_headersSize & 7; + if (pos != 0) + { + Byte temp[8]; + unsigned num = 8 - pos; + RINOK(ReadStream_FALSE(stream, temp, num)) + _headersSize += num; + } + } + else + return S_FALSE; + + return ReadHeader(stream, true); +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)) +{ + COM_TRY_BEGIN + { + Close(); + RINOK(Open2(inStream)) + + // start of payload is allowed to be unaligned + RINOK(ReadStream_FALSE(inStream, _payloadSig, sizeof(_payloadSig))) + + if (!_payloadSize_Defined) + { + UInt64 endPos; + RINOK(InStream_GetSize_SeekToEnd(inStream, endPos)) + _size = endPos - _headersSize; + } + _stream = inStream; + return S_OK; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _headersSize = 0; + _payloadSize = 0; + _size = 0; + _phySize = 0; + _headerPlusPayload_Size = 0; + + _payloadSize_Defined = false; + _phySize_Defined = false; + _headerPlusPayload_Size_Defined = false; + _time_Defined = false; + + _name.Empty(); + _version.Empty(); + _release.Empty(); + _arch.Empty(); + _os.Empty(); + + _format.Empty(); + _compressor.Empty(); + + #ifdef Z7_RPM_SHOW_METADATA + _metadata.Empty(); + _metaFiles.Size(); + #endif + + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1 + #ifdef Z7_RPM_SHOW_METADATA + + _metaFiles.Size() + #endif + ; + + return S_OK; +} + +static const Byte k_Signature[] = { 0xED, 0xAB, 0xEE, 0xDB}; + +REGISTER_ARC_I( + "Rpm", "rpm", NULL, 0xEB, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/SparseHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SparseHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/SparseHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SparseHandler.cpp 2024-02-17 10:00:00.000000000 +0000 @@ -0,0 +1,556 @@ +// 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; + + CChunk() + { + Fill[0] = + Fill[1] = + Fill[2] = + Fill[3] = + 0; + } +}; + +static const Byte k_Signature[] = { 0x3a, 0xff, 0x26, 0xed, 1, 0 }; + + +Z7_class_CHandler_final: public CHandlerImg +{ + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + + 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 InStream_SeekSet(Stream, offset); + } + + 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() Z7_override + { + _packSizeProcessed = 0; + return true; + } + bool Get_PackSizeProcessed(UInt64 &size) Z7_override + { + size = _packSizeProcessed; + return true; + } + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; + HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size, UInt32 &processed); +}; + + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidClusterSize, + kpidNumBlocks, + kpidMethod +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(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 +} + + +Z7_COM7F_IMF(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(InStream_SeekSet(stream, offset)) + } + } + + 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; +} + + +Z7_COM7F_IMF(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; +} + + +Z7_COM7F_IMF(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; + } +} + + +Z7_COM7F_IMF(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; + } + + Byte 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/SplitHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SplitHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/SplitHandler.cpp 2016-06-11 08:08:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SplitHandler.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,359 +1,353 @@ -// SplitHandler.cpp - -#include "StdAfx.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" - -#include "../Compress/CopyCoder.h" - -#include "Common/MultiStream.h" - -using namespace NWindows; - -namespace NArchive { -namespace NSplit { - -static const Byte kProps[] = -{ - kpidPath, - kpidSize -}; - -static const Byte kArcProps[] = -{ - kpidNumVolumes, - kpidTotalPhySize -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CObjectVector > _streams; - CRecordVector _sizes; - UString _subName; - UInt64 _totalSize; - - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: prop = (UInt32)0; break; - case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break; - case kpidTotalPhySize: prop = _totalSize; break; - case kpidNumVolumes: prop = (UInt32)_streams.Size(); break; - } - prop.Detach(value); - return S_OK; -} - -struct CSeqName -{ - UString _unchangedPart; - UString _changedPart; - bool _splitStyle; - - bool GetNextName(UString &s) - { - { - unsigned i = _changedPart.Len(); - for (;;) - { - wchar_t c = _changedPart[--i]; - - if (_splitStyle) - { - if (c == 'z') - { - _changedPart.ReplaceOneCharAtPos(i, L'a'); - if (i == 0) - return false; - continue; - } - else if (c == 'Z') - { - _changedPart.ReplaceOneCharAtPos(i, L'A'); - if (i == 0) - return false; - continue; - } - } - else - { - if (c == '9') - { - _changedPart.ReplaceOneCharAtPos(i, L'0'); - if (i == 0) - { - _changedPart.InsertAtFront(L'1'); - break; - } - continue; - } - } - - c++; - _changedPart.ReplaceOneCharAtPos(i, c); - break; - } - } - - s = _unchangedPart + _changedPart; - return true; - } -}; - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) -{ - Close(); - if (!callback) - return S_FALSE; - - CMyComPtr volumeCallback; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); - if (!volumeCallback) - return S_FALSE; - - UString name; - { - NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - return S_FALSE; - name = prop.bstrVal; - } - - int dotPos = name.ReverseFind_Dot(); - const UString prefix = name.Left(dotPos + 1); - const UString ext = name.Ptr(dotPos + 1); - UString ext2 = ext; - ext2.MakeLower_Ascii(); - - CSeqName seqName; - - unsigned numLetters = 2; - bool splitStyle = false; - - if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa")) - { - splitStyle = true; - while (numLetters < ext2.Len()) - { - if (ext2[ext2.Len() - numLetters - 1] != 'a') - break; - numLetters++; - } - } - else if (ext.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "01")) - { - while (numLetters < ext2.Len()) - { - if (ext2[ext2.Len() - numLetters - 1] != '0') - break; - numLetters++; - } - if (numLetters != ext.Len()) - return S_FALSE; - } - else - return S_FALSE; - - seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters); - seqName._changedPart = ext.RightPtr(numLetters); - seqName._splitStyle = splitStyle; - - if (prefix.Len() < 1) - _subName.SetFromAscii("file"); - else - _subName.SetFrom(prefix, prefix.Len() - 1); - - UInt64 size; - { - /* - NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - */ - RINOK(stream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - - _totalSize += size; - _sizes.Add(size); - _streams.Add(stream); - - { - const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); - } - - for (;;) - { - UString fullName; - if (!seqName.GetNextName(fullName)) - break; - CMyComPtr nextStream; - HRESULT result = volumeCallback->GetStream(fullName, &nextStream); - if (result == S_FALSE) - break; - if (result != S_OK) - return result; - if (!nextStream) - break; - { - /* - NCOM::CPropVariant prop; - RINOK(volumeCallback->GetProperty(kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - */ - RINOK(nextStream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(nextStream->Seek(0, STREAM_SEEK_SET, NULL)); - } - _totalSize += size; - _sizes.Add(size); - _streams.Add(nextStream); - { - const UInt64 numFiles = _streams.Size(); - RINOK(callback->SetCompleted(&numFiles, NULL)); - } - } - - if (_streams.Size() == 1) - { - if (splitStyle) - return S_FALSE; - } - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - HRESULT res = Open2(stream, callback); - if (res != S_OK) - Close(); - return res; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _totalSize = 0; - _subName.Empty(); - _streams.Clear(); - _sizes.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _streams.IsEmpty() ? 0 : 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPath: prop = _subName; break; - case kpidSize: - case kpidPackSize: - prop = _totalSize; - break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - UInt64 currentTotalSize = 0; - RINOK(extractCallback->SetTotal(_totalSize)); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &outStream, askMode)); - if (!testMode && !outStream) - return S_OK; - RINOK(extractCallback->PrepareOperation(askMode)); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - FOR_VECTOR (i, _streams) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - IInStream *inStream = _streams[i]; - RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - currentTotalSize += copyCoderSpec->TotalSize; - } - outStream.Release(); - return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK); - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - if (index != 0) - return E_INVALIDARG; - *stream = 0; - CMultiStream *streamSpec = new CMultiStream; - CMyComPtr streamTemp = streamSpec; - FOR_VECTOR (i, _streams) - { - CMultiStream::CSubStreamInfo subStreamInfo; - subStreamInfo.Stream = _streams[i]; - subStreamInfo.Size = _sizes[i]; - streamSpec->Streams.Add(subStreamInfo); - } - streamSpec->Init(); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -REGISTER_ARC_I_NO_SIG( - "Split", "001", 0, 0xEA, - 0, - 0, - NULL) - -}} +// SplitHandler.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +#include "Common/MultiStream.h" + +using namespace NWindows; + +namespace NArchive { +namespace NSplit { + +static const Byte kProps[] = +{ + kpidPath, + kpidSize +}; + +static const Byte kArcProps[] = +{ + kpidNumVolumes, + kpidTotalPhySize +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CObjectVector > _streams; + CRecordVector _sizes; + UString _subName; + UInt64 _totalSize; + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidPhySize: if (!_sizes.IsEmpty()) prop = _sizes[0]; break; + case kpidTotalPhySize: prop = _totalSize; break; + case kpidNumVolumes: prop = (UInt32)_streams.Size(); break; + default: break; + } + prop.Detach(value); + return S_OK; +} + +struct CSeqName +{ + UString _unchangedPart; + UString _changedPart; + bool _splitStyle; + + bool GetNextName(UString &s) + { + { + unsigned i = _changedPart.Len(); + for (;;) + { + wchar_t c = _changedPart[--i]; + + if (_splitStyle) + { + if (c == 'z') + { + _changedPart.ReplaceOneCharAtPos(i, L'a'); + if (i == 0) + return false; + continue; + } + else if (c == 'Z') + { + _changedPart.ReplaceOneCharAtPos(i, L'A'); + if (i == 0) + return false; + continue; + } + } + else + { + if (c == '9') + { + _changedPart.ReplaceOneCharAtPos(i, L'0'); + if (i == 0) + { + _changedPart.InsertAtFront(L'1'); + break; + } + continue; + } + } + + c++; + _changedPart.ReplaceOneCharAtPos(i, c); + break; + } + } + + s = _unchangedPart + _changedPart; + return true; + } +}; + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + Close(); + if (!callback) + return S_FALSE; + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + volumeCallback, callback) + if (!volumeCallback) + return S_FALSE; + + UString name; + { + NCOM::CPropVariant prop; + RINOK(volumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt != VT_BSTR) + return S_FALSE; + name = prop.bstrVal; + } + + const int dotPos = name.ReverseFind_Dot(); + const UString prefix = name.Left((unsigned)(dotPos + 1)); + const UString ext = name.Ptr((unsigned)(dotPos + 1)); + UString ext2 = ext; + ext2.MakeLower_Ascii(); + + CSeqName seqName; + + unsigned numLetters = 2; + bool splitStyle = false; + + if (ext2.Len() >= 2 && StringsAreEqual_Ascii(ext2.RightPtr(2), "aa")) + { + splitStyle = true; + while (numLetters < ext2.Len()) + { + if (ext2[ext2.Len() - numLetters - 1] != 'a') + break; + numLetters++; + } + } + else if (ext2.Len() >= 2 && ( + StringsAreEqual_Ascii(ext2.RightPtr(2), "01") + || StringsAreEqual_Ascii(ext2.RightPtr(2), "00") + )) + { + while (numLetters < ext2.Len()) + { + if (ext2[ext2.Len() - numLetters - 1] != '0') + break; + numLetters++; + } + if (numLetters != ext2.Len()) + return S_FALSE; + } + else + return S_FALSE; + + seqName._unchangedPart = prefix + ext.Left(ext2.Len() - numLetters); + seqName._changedPart = ext.RightPtr(numLetters); + seqName._splitStyle = splitStyle; + + if (prefix.Len() < 1) + _subName = "file"; + else + _subName.SetFrom(prefix, prefix.Len() - 1); + + UInt64 size; + { + /* + NCOM::CPropVariant prop; + RINOK(volumeCallback->GetProperty(kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + */ + } + RINOK(InStream_AtBegin_GetSize(stream, size)) + + _totalSize += size; + _sizes.Add(size); + _streams.Add(stream); + + { + const UInt64 numFiles = _streams.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)) + } + + for (;;) + { + UString fullName; + if (!seqName.GetNextName(fullName)) + break; + CMyComPtr nextStream; + const HRESULT result = volumeCallback->GetStream(fullName, &nextStream); + if (result == S_FALSE) + break; + if (result != S_OK) + return result; + if (!nextStream) + break; + RINOK(InStream_AtBegin_GetSize(nextStream, size)) + _totalSize += size; + _sizes.Add(size); + _streams.Add(nextStream); + { + const UInt64 numFiles = _streams.Size(); + RINOK(callback->SetCompleted(&numFiles, NULL)) + } + } + + if (_streams.Size() == 1) + { + if (splitStyle) + return S_FALSE; + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + const HRESULT res = Open2(stream, callback); + if (res != S_OK) + Close(); + return res; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _totalSize = 0; + _subName.Empty(); + _streams.Clear(); + _sizes.Clear(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _streams.IsEmpty() ? 0 : 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPath: prop = _subName; break; + case kpidSize: + case kpidPackSize: + prop = _totalSize; + break; + default: break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + UInt64 currentTotalSize = 0; + RINOK(extractCallback->SetTotal(_totalSize)) + CMyComPtr outStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &outStream, askMode)) + if (!testMode && !outStream) + return S_OK; + RINOK(extractCallback->PrepareOperation(askMode)) + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + for (unsigned i = 0;; i++) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + if (i == _streams.Size()) + break; + IInStream *inStream = _streams[i]; + RINOK(InStream_SeekToBegin(inStream)) + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) + currentTotalSize += copyCoderSpec->TotalSize; + } + outStream.Release(); + return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK); + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + if (index != 0) + return E_INVALIDARG; + *stream = NULL; + CMultiStream *streamSpec = new CMultiStream; + CMyComPtr streamTemp = streamSpec; + FOR_VECTOR (i, _streams) + { + CMultiStream::CSubStreamInfo subStreamInfo; + subStreamInfo.Stream = _streams[i]; + subStreamInfo.Size = _sizes[i]; + streamSpec->Streams.Add(subStreamInfo); + } + streamSpec->Init(); + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I_NO_SIG( + "Split", "001", NULL, 0xEA, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/SquashfsHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SquashfsHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/SquashfsHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SquashfsHandler.cpp 2023-12-19 11:00:00.000000000 +0000 @@ -1,2218 +1,2370 @@ -// SquashfsHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" -#include "../../../C/Xz.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyLinux.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariantUtils.h" -#include "../../Windows/TimeUtils.h" - -#include "../Common/CWrappers.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 "../Compress/ZlibDecoder.h" -#include "../Compress/LzmaDecoder.h" - -namespace NArchive { -namespace NSquashfs { - -static const UInt32 kNumFilesMax = (1 << 28); -static const unsigned kNumDirLevelsMax = (1 << 10); - -// Layout: Header, Data, inodes, Directories, Fragments, UIDs, GIDs - -/* -#define Get16(p) (be ? GetBe16(p) : GetUi16(p)) -#define Get32(p) (be ? GetBe32(p) : GetUi32(p)) -#define Get64(p) (be ? GetBe64(p) : GetUi64(p)) -*/ - -UInt16 Get16b(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); } -UInt32 Get32b(const Byte *p, bool be) { return be ? GetBe32(p) : GetUi32(p); } -UInt64 Get64b(const Byte *p, bool be) { return be ? GetBe64(p) : GetUi64(p); } - -#define Get16(p) Get16b(p, be) -#define Get32(p) Get32b(p, be) -#define Get64(p) Get64b(p, be) - -#define LE_16(offs, dest) dest = GetUi16(p + (offs)); -#define LE_32(offs, dest) dest = GetUi32(p + (offs)); -#define LE_64(offs, dest) dest = GetUi64(p + (offs)); - -#define GET_16(offs, dest) dest = Get16(p + (offs)); -#define GET_32(offs, dest) dest = Get32(p + (offs)); -#define GET_64(offs, dest) dest = Get64(p + (offs)); - -static const UInt32 kSignature32_LE = 0x73717368; -static const UInt32 kSignature32_BE = 0x68737173; -static const UInt32 kSignature32_LZ = 0x71736873; - -#define kMethod_ZLIB 1 -#define kMethod_LZMA 2 -#define kMethod_LZO 3 -#define kMethod_XZ 4 - -static const char * const k_Methods[] = -{ - "Unknown" - , "ZLIB" - , "LZMA" - , "LZO" - , "XZ" -}; - -static const UInt32 kMetadataBlockSizeLog = 13; -static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog); - -enum -{ - kType_IPC, - kType_DIR, - kType_FILE, - kType_LNK, - kType_BLK, - kType_CHR, - kType_FIFO, - kType_SOCK -}; - -static const UInt32 k_TypeToMode[] = -{ - 0, - MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK, - MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK -}; - - -enum -{ - kFlag_UNC_INODES, - kFlag_UNC_DATA, - kFlag_CHECK, - kFlag_UNC_FRAGS, - kFlag_NO_FRAGS, - kFlag_ALWAYS_FRAG, - kFlag_DUPLICATE, - kFlag_EXPORT -}; - -static const CUInt32PCharPair k_Flags[] = -{ - { kFlag_UNC_INODES, "UNCOMPRESSED_INODES" }, - { kFlag_UNC_DATA, "UNCOMPRESSED_DATA" }, - { kFlag_CHECK, "CHECK" }, - { kFlag_UNC_FRAGS, "UNCOMPRESSED_FRAGMENTS" }, - { kFlag_NO_FRAGS, "NO_FRAGMENTS" }, - { kFlag_ALWAYS_FRAG, "ALWAYS_FRAGMENTS" }, - { kFlag_DUPLICATE, "DUPLICATES_REMOVED" }, - { kFlag_EXPORT, "EXPORTABLE" } -}; - -static const UInt32 kNotCompressedBit16 = (1 << 15); -static const UInt32 kNotCompressedBit32 = (1 << 24); - -#define GET_COMPRESSED_BLOCK_SIZE(size) ((size) & ~kNotCompressedBit32) -#define IS_COMPRESSED_BLOCK(size) (((size) & kNotCompressedBit32) == 0) - -static const UInt32 kHeaderSize1 = 0x33; -static const UInt32 kHeaderSize2 = 0x3F; -static const UInt32 kHeaderSize3 = 0x77; -static const UInt32 kHeaderSize4 = 0x60; - -struct CHeader -{ - bool be; - bool SeveralMethods; - Byte NumUids; - Byte NumGids; - - UInt32 NumInodes; - UInt32 CTime; - UInt32 BlockSize; - UInt32 NumFrags; - UInt16 Method; - UInt16 BlockSizeLog; - UInt16 Flags; - UInt16 NumIDs; - UInt16 Major; - UInt16 Minor; - UInt64 RootInode; - UInt64 Size; - UInt64 UidTable; - UInt64 GidTable; - UInt64 XattrIdTable; - UInt64 InodeTable; - UInt64 DirTable; - UInt64 FragTable; - UInt64 LookupTable; - - void Parse3(const Byte *p) - { - Method = kMethod_ZLIB; - GET_32 (0x08, Size); - GET_32 (0x0C, UidTable); - GET_32 (0x10, GidTable); - GET_32 (0x14, InodeTable); - GET_32 (0x18, DirTable); - GET_16 (0x20, BlockSize); - GET_16 (0x22, BlockSizeLog); - Flags = p[0x24]; - NumUids = p[0x25]; - NumGids = p[0x26]; - GET_32 (0x27, CTime); - GET_64 (0x2B, RootInode); - NumFrags = 0; - FragTable = UidTable; - - if (Major >= 2) - { - GET_32 (0x33, BlockSize); - GET_32 (0x37, NumFrags); - GET_32 (0x3B, FragTable); - if (Major == 3) - { - GET_64 (0x3F, Size); - GET_64 (0x47, UidTable); - GET_64 (0x4F, GidTable); - GET_64 (0x57, InodeTable); - GET_64 (0x5F, DirTable); - GET_64 (0x67, FragTable); - GET_64 (0x6F, LookupTable); - } - } - } - - void Parse4(const Byte *p) - { - LE_32 (0x08, CTime); - LE_32 (0x0C, BlockSize); - LE_32 (0x10, NumFrags); - LE_16 (0x14, Method); - LE_16 (0x16, BlockSizeLog); - LE_16 (0x18, Flags); - LE_16 (0x1A, NumIDs); - LE_64 (0x20, RootInode); - LE_64 (0x28, Size); - LE_64 (0x30, UidTable); - LE_64 (0x38, XattrIdTable); - LE_64 (0x40, InodeTable); - LE_64 (0x48, DirTable); - LE_64 (0x50, FragTable); - LE_64 (0x58, LookupTable); - GidTable = 0; - } - - bool Parse(const Byte *p) - { - be = false; - SeveralMethods = false; - switch (GetUi32(p)) - { - case kSignature32_LE: break; - case kSignature32_BE: be = true; break; - case kSignature32_LZ: SeveralMethods = true; break; - default: return false; - } - GET_32 (4, NumInodes); - GET_16 (0x1C, Major); - GET_16 (0x1E, Minor); - if (Major <= 3) - Parse3(p); - else - { - if (be) - return false; - Parse4(p); - } - return - InodeTable < DirTable && - DirTable <= FragTable && - FragTable <= Size && - UidTable <= Size && - BlockSizeLog >= 12 && - BlockSizeLog < 31 && - BlockSize == ((UInt32)1 << BlockSizeLog); - } - - bool IsSupported() const { return Major > 0 && Major <= 4 && BlockSizeLog <= 23; } - bool IsOldVersion() const { return Major < 4; } - bool NeedCheckData() const { return (Flags & (1 << kFlag_CHECK)) != 0; } - unsigned GetFileNameOffset() const { return Major <= 2 ? 3 : (Major == 3 ? 5 : 8); } - unsigned GetSymLinkOffset() const { return Major <= 1 ? 5: (Major <= 2 ? 6: (Major == 3 ? 18 : 24)); } - unsigned GetSpecGuidIndex() const { return Major <= 1 ? 0xF: 0xFF; } -}; - -static const UInt32 kFrag_Empty = (UInt32)(Int32)-1; -// static const UInt32 kXattr_Empty = (UInt32)(Int32)-1; - -struct CNode -{ - UInt16 Type; - UInt16 Mode; - UInt16 Uid; - UInt16 Gid; - UInt32 Frag; - UInt32 Offset; - // UInt32 MTime; - // UInt32 Number; - // UInt32 NumLinks; - // UInt32 RDev; - // UInt32 Xattr; - // UInt32 Parent; - - UInt64 FileSize; - UInt64 StartBlock; - // UInt64 Sparse; - - UInt32 Parse1(const Byte *p, UInt32 size, const CHeader &_h); - UInt32 Parse2(const Byte *p, UInt32 size, const CHeader &_h); - UInt32 Parse3(const Byte *p, UInt32 size, const CHeader &_h); - UInt32 Parse4(const Byte *p, UInt32 size, const CHeader &_h); - - bool IsDir() const { return (Type == kType_DIR || Type == kType_DIR + 7); } - bool IsLink() const { return (Type == kType_LNK || Type == kType_LNK + 7); } - UInt64 GetSize() const { return IsDir() ? 0 : FileSize; } - - bool ThereAreFrags() const { return Frag != kFrag_Empty; } - UInt64 GetNumBlocks(const CHeader &_h) const - { - return (FileSize >> _h.BlockSizeLog) + - (!ThereAreFrags() && (FileSize & (_h.BlockSize - 1)) != 0); - } -}; - -UInt32 CNode::Parse1(const Byte *p, UInt32 size, const CHeader &_h) -{ - const bool be = _h.be; - if (size < 4) - return 0; - { - const UInt32 t = Get16(p); - if (be) - { - Type = (UInt16)(t >> 12); - Mode = (UInt16)(t & 0xFFF); - Uid = (UInt16)(p[2] >> 4); - Gid = (UInt16)(p[2] & 0xF); - } - else - { - Type = (UInt16)(t & 0xF); - Mode = (UInt16)(t >> 4); - Uid = (UInt16)(p[2] & 0xF); - Gid = (UInt16)(p[2] >> 4); - } - } - - // Xattr = kXattr_Empty; - // MTime = 0; - FileSize = 0; - StartBlock = 0; - Frag = kFrag_Empty; - - if (Type == 0) - { - Byte t = p[3]; - if (be) - { - Type = (UInt16)(t >> 4); - Offset = (UInt16)(t & 0xF); - } - else - { - Type = (UInt16)(t & 0xF); - Offset = (UInt16)(t >> 4); - } - return (Type == kType_FIFO || Type == kType_SOCK) ? 4 : 0; - } - - Type--; - Uid = (UInt16)(Uid + (Type / 5) * 16); - Type = (UInt16)((Type % 5) + 1); - - if (Type == kType_FILE) - { - if (size < 15) - return 0; - // GET_32 (3, MTime); - GET_32 (7, StartBlock); - UInt32 t; - GET_32 (11, t); - FileSize = t; - UInt32 numBlocks = t >> _h.BlockSizeLog; - if ((t & (_h.BlockSize - 1)) != 0) - numBlocks++; - UInt32 pos = numBlocks * 2 + 15; - return (pos <= size) ? pos : 0; - } - - if (Type == kType_DIR) - { - if (size < 14) - return 0; - UInt32 t = Get32(p + 3); - if (be) - { - FileSize = t >> 13; - Offset = t & 0x1FFF; - } - else - { - FileSize = t & 0x7FFFF; - Offset = t >> 19; - } - // GET_32 (7, MTime); - GET_32 (10, StartBlock); - if (be) - StartBlock &= 0xFFFFFF; - else - StartBlock >>= 8; - return 14; - } - - if (size < 5) - return 0; - - if (Type == kType_LNK) - { - UInt32 len; - GET_16 (3, len); - FileSize = len; - len += 5; - return (len <= size) ? len : 0; - } - - // GET_32 (3, RDev); - return 5; -} - -UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h) -{ - bool be = _h.be; - if (size < 4) - return 0; - { - const UInt32 t = Get16(p); - if (be) - { - Type = (UInt16)(t >> 12); - Mode = (UInt16)(t & 0xFFF); - } - else - { - Type = (UInt16)(t & 0xF); - Mode = (UInt16)(t >> 4); - } - } - - Uid = p[2]; - Gid = p[3]; - - // Xattr = kXattr_Empty; - - if (Type == kType_FILE) - { - if (size < 24) - return 0; - // GET_32 (4, MTime); - GET_32 (8, StartBlock); - GET_32 (12, Frag); - GET_32 (16, Offset); - UInt32 t; - GET_32 (20, t); - FileSize = t; - UInt32 numBlocks = t >> _h.BlockSizeLog; - if (!ThereAreFrags() && (t & (_h.BlockSize - 1)) != 0) - numBlocks++; - UInt32 pos = numBlocks * 4 + 24; - return (pos <= size) ? (UInt32)pos : 0; - } - - FileSize = 0; - // MTime = 0; - StartBlock = 0; - Frag = kFrag_Empty; - - if (Type == kType_DIR) - { - if (size < 15) - return 0; - UInt32 t = Get32(p + 4); - if (be) - { - FileSize = t >> 13; - Offset = t & 0x1FFF; - } - else - { - FileSize = t & 0x7FFFF; - Offset = t >> 19; - } - // GET_32 (8, MTime); - GET_32 (11, StartBlock); - if (be) - StartBlock &= 0xFFFFFF; - else - StartBlock >>= 8; - return 15; - } - - if (Type == kType_DIR + 7) - { - if (size < 18) - return 0; - UInt32 t = Get32(p + 4); - UInt32 t2 = Get16(p + 7); - if (be) - { - FileSize = t >> 5; - Offset = t2 & 0x1FFF; - } - else - { - FileSize = t & 0x7FFFFFF; - Offset = t2 >> 3; - } - // GET_32 (9, MTime); - GET_32 (12, StartBlock); - if (be) - StartBlock &= 0xFFFFFF; - else - StartBlock >>= 8; - UInt32 iCount; - GET_16 (16, iCount); - UInt32 pos = 18; - for (UInt32 i = 0; i < iCount; i++) - { - // 27 bits: index - // 29 bits: startBlock - if (pos + 8 > size) - return 0; - pos += 8 + (UInt32)p[pos + 7] + 1; // nameSize - if (pos > size) - return 0; - } - return pos; - } - - if (Type == kType_FIFO || Type == kType_SOCK) - return 4; - - if (size < 6) - return 0; - - if (Type == kType_LNK) - { - UInt32 len; - GET_16 (4, len); - FileSize = len; - len += 6; - return (len <= size) ? len : 0; - } - - if (Type == kType_BLK || Type == kType_CHR) - { - // GET_16 (4, RDev); - return 6; - } - - return 0; -} - -UInt32 CNode::Parse3(const Byte *p, UInt32 size, const CHeader &_h) -{ - bool be = _h.be; - if (size < 12) - return 0; - - { - const UInt32 t = Get16(p); - if (be) - { - Type = (UInt16)(t >> 12); - Mode = (UInt16)(t & 0xFFF); - } - else - { - Type = (UInt16)(t & 0xF); - Mode = (UInt16)(t >> 4); - } - } - - Uid = p[2]; - Gid = p[3]; - // GET_32 (4, MTime); - // GET_32 (8, Number); - // Xattr = kXattr_Empty; - FileSize = 0; - StartBlock = 0; - - if (Type == kType_FILE || Type == kType_FILE + 7) - { - UInt32 offset; - if (Type == kType_FILE) - { - if (size < 32) - return 0; - GET_64 (12, StartBlock); - GET_32 (20, Frag); - GET_32 (24, Offset); - GET_32 (28, FileSize); - offset = 32; - } - else - { - if (size < 40) - return 0; - // GET_32 (12, NumLinks); - GET_64 (16, StartBlock); - GET_32 (24, Frag); - GET_32 (28, Offset); - GET_64 (32, FileSize); - offset = 40; - } - UInt64 pos = GetNumBlocks(_h) * 4 + offset; - return (pos <= size) ? (UInt32)pos : 0; - } - - if (size < 16) - return 0; - // GET_32 (12, NumLinks); - - if (Type == kType_DIR) - { - if (size < 28) - return 0; - UInt32 t = Get32(p + 16); - if (be) - { - FileSize = t >> 13; - Offset = t & 0x1FFF; - } - else - { - FileSize = t & 0x7FFFF; - Offset = t >> 19; - } - GET_32 (20, StartBlock); - // GET_32 (24, Parent); - return 28; - } - - if (Type == kType_DIR + 7) - { - if (size < 31) - return 0; - UInt32 t = Get32(p + 16); - UInt32 t2 = Get16(p + 19); - if (be) - { - FileSize = t >> 5; - Offset = t2 & 0x1FFF; - } - else - { - FileSize = t & 0x7FFFFFF; - Offset = t2 >> 3; - } - GET_32 (21, StartBlock); - UInt32 iCount; - GET_16 (25, iCount); - // GET_32 (27, Parent); - UInt32 pos = 31; - for (UInt32 i = 0; i < iCount; i++) - { - // UInt32 index - // UInt32 startBlock - if (pos + 9 > size) - return 0; - pos += 9 + (unsigned)p[pos + 8] + 1; // nameSize - if (pos > size) - return 0; - } - return pos; - } - - if (Type == kType_FIFO || Type == kType_SOCK) - return 16; - - if (size < 18) - return 0; - if (Type == kType_LNK) - { - UInt32 len; - GET_16 (16, len); - FileSize = len; - len += 18; - return (len <= size) ? len : 0; - } - - if (Type == kType_BLK || Type == kType_CHR) - { - // GET_16 (16, RDev); - return 18; - } - - return 0; -} - -UInt32 CNode::Parse4(const Byte *p, UInt32 size, const CHeader &_h) -{ - if (size < 20) - return 0; - LE_16 (0, Type); - LE_16 (2, Mode); - LE_16 (4, Uid); - LE_16 (6, Gid); - // LE_32 (8, MTime); - // LE_32 (12, Number); - - // Xattr = kXattr_Empty; - FileSize = 0; - StartBlock = 0; - - if (Type == kType_FILE || Type == kType_FILE + 7) - { - UInt32 offset; - if (Type == kType_FILE) - { - if (size < 32) - return 0; - LE_32 (16, StartBlock); - LE_32 (20, Frag); - LE_32 (24, Offset); - LE_32 (28, FileSize); - offset = 32; - } - else - { - if (size < 56) - return 0; - LE_64 (16, StartBlock); - LE_64 (24, FileSize); - // LE_64 (32, Sparse); - // LE_32 (40, NumLinks); - LE_32 (44, Frag); - LE_32 (48, Offset); - // LE_32 (52, Xattr); - offset = 56; - } - UInt64 pos = GetNumBlocks(_h) * 4 + offset; - return (pos <= size) ? (UInt32)pos : 0; - } - - if (Type == kType_DIR) - { - if (size < 32) - return 0; - LE_32 (16, StartBlock); - // LE_32 (20, NumLinks); - LE_16 (24, FileSize); - LE_16 (26, Offset); - // LE_32 (28, Parent); - return 32; - } - - // LE_32 (16, NumLinks); - - if (Type == kType_DIR + 7) - { - if (size < 40) - return 0; - LE_32 (20, FileSize); - LE_32 (24, StartBlock); - // LE_32 (28, Parent); - UInt32 iCount; - LE_16 (32, iCount); - LE_16 (34, Offset); - // LE_32 (36, Xattr); - - UInt32 pos = 40; - for (UInt32 i = 0; i < iCount; i++) - { - // UInt32 index - // UInt32 startBlock - if (pos + 12 > size) - return 0; - UInt32 nameLen = GetUi32(p + pos + 8); - pos += 12 + nameLen + 1; - if (pos > size || nameLen > (1 << 10)) - return 0; - } - return pos; - } - - unsigned offset = 20; - switch (Type) - { - case kType_FIFO: case kType_FIFO + 7: - case kType_SOCK: case kType_SOCK + 7: - break; - case kType_LNK: case kType_LNK + 7: - { - if (size < 24) - return 0; - UInt32 len; - LE_32 (20, len); - FileSize = len; - offset = len + 24; - if (size < offset || len > (1 << 30)) - return 0; - break; - } - case kType_BLK: case kType_BLK + 7: - case kType_CHR: case kType_CHR + 7: - if (size < 24) - return 0; - // LE_32 (20, RDev); - offset = 24; - break; - default: - return 0; - } - - if (Type >= 8) - { - if (size < offset + 4) - return 0; - // LE_32 (offset, Xattr); - offset += 4; - } - return offset; -} - -struct CItem -{ - int Node; - int Parent; - UInt32 Ptr; - - CItem(): Node(-1), Parent(-1), Ptr(0) {} -}; - -struct CData -{ - CByteBuffer Data; - CRecordVector PackPos; - CRecordVector UnpackPos; // additional item at the end contains TotalUnpackSize - - UInt32 GetNumBlocks() const { return PackPos.Size(); } - void Clear() - { - Data.Free(); - PackPos.Clear(); - UnpackPos.Clear(); - } -}; - -struct CFrag -{ - UInt64 StartBlock; - UInt32 Size; -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CRecordVector _items; - CRecordVector _nodes; - CRecordVector _nodesPos; - CRecordVector _blockToNode; - CData _inodesData; - CData _dirs; - CRecordVector _frags; - // CByteBuffer _uids; - // CByteBuffer _gids; - CHeader _h; - bool _noPropsLZMA; - bool _needCheckLzma; - - CMyComPtr _stream; - UInt64 _sizeCalculated; - - IArchiveOpenCallback *_openCallback; - - int _nodeIndex; - CRecordVector _blockCompressed; - CRecordVector _blockOffsets; - - CByteBuffer _cachedBlock; - UInt64 _cachedBlockStartPos; - UInt32 _cachedPackBlockSize; - UInt32 _cachedUnpackBlockSize; - - CLimitedSequentialInStream *_limitedInStreamSpec; - CMyComPtr _limitedInStream; - - CBufPtrSeqOutStream *_outStreamSpec; - CMyComPtr _outStream; - - NCompress::NLzma::CDecoder *_lzmaDecoderSpec; - CMyComPtr _lzmaDecoder; - - NCompress::NZlib::CDecoder *_zlibDecoderSpec; - CMyComPtr _zlibDecoder; - - CXzUnpacker _xz; - - CByteBuffer _inputBuffer; - - CDynBufSeqOutStream *_dynOutStreamSpec; - CMyComPtr _dynOutStream; - - void ClearCache() - { - _cachedBlockStartPos = 0; - _cachedPackBlockSize = 0; - _cachedUnpackBlockSize = 0; - } - - HRESULT Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize, - UInt32 inSize, UInt32 outSizeMax); - HRESULT ReadMetadataBlock(UInt32 &packSize); - 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 Open2(IInStream *inStream); - AString GetPath(int index) const; - bool GetPackSize(int index, UInt64 &res, bool fillOffsets); - -public: - CHandler(); - ~CHandler() - { - XzUnpacker_Free(&_xz); - } - - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); -}; - -CHandler::CHandler() -{ - XzUnpacker_Construct(&_xz, &g_Alloc); - - _limitedInStreamSpec = new CLimitedSequentialInStream; - _limitedInStream = _limitedInStreamSpec; - - _outStreamSpec = new CBufPtrSeqOutStream(); - _outStream = _outStreamSpec; - - _dynOutStreamSpec = new CDynBufSeqOutStream; - _dynOutStream = _dynOutStreamSpec; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidPosixAttrib - // kpidUser, - // kpidGroup, - // kpidLinks, - // kpidOffset -}; - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - kpidFileSystem, - kpidMethod, - kpidClusterSize, - kpidBigEndian, - kpidCTime, - kpidCharacts - // kpidNumBlocks -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) -{ - SizeT destRem = *destLen; - SizeT srcRem = *srcLen; - *destLen = 0; - *srcLen = 0; - const Byte *destStart = dest; - const Byte *srcStart = src; - unsigned mode = 2; - - { - if (srcRem == 0) - return S_FALSE; - UInt32 b = *src; - if (b > 17) - { - src++; - srcRem--; - b -= 17; - mode = (b < 4 ? 0 : 1); - if (b > srcRem || b > destRem) - return S_FALSE; - srcRem -= b; - destRem -= b; - do - *dest++ = *src++; - while (--b); - } - } - - for (;;) - { - if (srcRem < 3) - return S_FALSE; - UInt32 b = *src++; - srcRem--; - UInt32 len, back; - if (b >= 64) - { - srcRem--; - back = ((b >> 2) & 7) + ((UInt32)*src++ << 3); - len = (b >> 5) + 1; - } - else if (b < 16) - { - if (mode == 2) - { - if (b == 0) - { - for (b = 15;; b += 255) - { - if (srcRem == 0) - return S_FALSE; - UInt32 b2 = *src++; - srcRem--; - if (b2 != 0) - { - b += b2; - break; - } - } - } - b += 3; - if (b > srcRem || b > destRem) - return S_FALSE; - srcRem -= b; - destRem -= b; - mode = 1; - do - *dest++ = *src++; - while (--b); - continue; - } - srcRem--; - back = (b >> 2) + (*src++ << 2); - len = 2; - if (mode == 1) - { - back += (1 << 11); - len = 3; - } - } - else - { - UInt32 bOld = b; - b = (b < 32 ? 7 : 31); - len = bOld & b; - if (len == 0) - { - for (len = b;; len += 255) - { - if (srcRem == 0) - return S_FALSE; - UInt32 b2 = *src++; - srcRem--; - if (b2 != 0) - { - len += b2; - break; - } - } - } - len += 2; - if (srcRem < 2) - return S_FALSE; - b = *src; - back = (b >> 2) + ((UInt32)src[1] << 6); - src += 2; - srcRem -= 2; - if (bOld < 32) - { - if (back == 0) - { - *destLen = dest - destStart; - *srcLen = src - srcStart; - return S_OK; - } - back += ((bOld & 8) << 11) + (1 << 14) - 1; - } - } - back++; - if (len > destRem || (size_t)(dest - destStart) < back) - return S_FALSE; - destRem -= len; - Byte *destTemp = dest - back; - dest += len; - do - { - *(destTemp + back) = *destTemp; - destTemp++; - } - while (--len); - b &= 3; - if (b == 0) - { - mode = 2; - continue; - } - if (b > srcRem || b > destRem) - return S_FALSE; - srcRem -= b; - destRem -= b; - mode = 0; - *dest++ = *src++; - if (b > 1) - { - *dest++ = *src++; - if (b > 2) - *dest++ = *src++; - } - } -} - -HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize, UInt32 inSize, UInt32 outSizeMax) -{ - if (outBuf) - { - *outBufWasWritten = false; - *outBufWasWrittenSize = 0; - } - UInt32 method = _h.Method; - if (_h.SeveralMethods) - { - Byte b; - RINOK(ReadStream_FALSE(_stream, &b, 1)); - RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)); - method = (b == 0x5D ? kMethod_LZMA : kMethod_ZLIB); - } - - if (method == kMethod_ZLIB && _needCheckLzma) - { - Byte b; - RINOK(ReadStream_FALSE(_stream, &b, 1)); - RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)); - if (b == 0) - { - _noPropsLZMA = true; - method = _h.Method = kMethod_LZMA; - } - _needCheckLzma = false; - } - - if (method == kMethod_ZLIB) - { - if (!_zlibDecoder) - { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder(); - _zlibDecoder = _zlibDecoderSpec; - } - RINOK(_zlibDecoder->Code(_limitedInStream, outStream, NULL, NULL, NULL)); - if (inSize != _zlibDecoderSpec->GetInputProcessedSize()) - return S_FALSE; - } - else if (method == kMethod_LZMA) - { - if (!_lzmaDecoder) - { - _lzmaDecoderSpec = new NCompress::NLzma::CDecoder(); - _lzmaDecoderSpec->FinishStream = true; - _lzmaDecoder = _lzmaDecoderSpec; - } - const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; - Byte props[kPropsSize]; - UInt32 propsSize; - UInt64 outSize; - if (_noPropsLZMA) - { - props[0] = 0x5D; - SetUi32(&props[1], _h.BlockSize); - propsSize = 0; - outSize = outSizeMax; - } - else - { - RINOK(ReadStream_FALSE(_limitedInStream, props, kPropsSize)); - propsSize = kPropsSize; - outSize = GetUi64(&props[LZMA_PROPS_SIZE]); - if (outSize > outSizeMax) - return S_FALSE; - } - RINOK(_lzmaDecoderSpec->SetDecoderProperties2(props, LZMA_PROPS_SIZE)); - RINOK(_lzmaDecoder->Code(_limitedInStream, outStream, NULL, &outSize, NULL)); - if (inSize != propsSize + _lzmaDecoderSpec->GetInputProcessedSize()) - return S_FALSE; - } - else - { - if (_inputBuffer.Size() < inSize) - _inputBuffer.Alloc(inSize); - RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize)); - - Byte *dest = outBuf; - if (!outBuf) - { - dest = _dynOutStreamSpec->GetBufPtrForWriting(outSizeMax); - if (!dest) - return E_OUTOFMEMORY; - } - SizeT destLen = outSizeMax, srcLen = inSize; - if (method == kMethod_LZO) - { - RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen)); - } - else - { - ECoderStatus status; - XzUnpacker_Init(&_xz); - SRes res = XzUnpacker_Code(&_xz, dest, &destLen, _inputBuffer, &srcLen, CODER_FINISH_END, &status); - if (res != 0) - return SResToHRESULT(res); - if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz)) - return S_FALSE; - } - if (inSize != srcLen) - return S_FALSE; - if (outBuf) - { - *outBufWasWritten = true; - *outBufWasWrittenSize = (UInt32)destLen; - } - else - _dynOutStreamSpec->UpdateSize(destLen); - } - return S_OK; -} - -HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize) -{ - Byte temp[3]; - 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; - UInt32 size = Get16(temp); - bool isCompressed = ((size & kNotCompressedBit16) == 0); - if (size != kNotCompressedBit16) - size &= ~kNotCompressedBit16; - - if (size > kMetadataBlockSize || offset + size > packSize) - return S_FALSE; - packSize = offset + size; - if (isCompressed) - { - _limitedInStreamSpec->Init(size); - RINOK(Decompress(_dynOutStream, NULL, NULL, NULL, size, kMetadataBlockSize)); - } - else - { - // size != 0 here - Byte *buf = _dynOutStreamSpec->GetBufPtrForWriting(size); - if (!buf) - return E_OUTOFMEMORY; - RINOK(ReadStream_FALSE(_stream, buf, size)); - _dynOutStreamSpec->UpdateSize(size); - } - return S_OK; -} - -HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end) -{ - if (end < start || end - start >= ((UInt64)1 << 32)) - return S_FALSE; - UInt32 size = (UInt32)(end - start); - RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL)); - _dynOutStreamSpec->Init(); - UInt32 packPos = 0; - while (packPos != size) - { - data.PackPos.Add(packPos); - data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize()); - if (packPos > size) - return S_FALSE; - UInt32 packSize = size - packPos; - RINOK(ReadMetadataBlock(packSize)); - if (_dynOutStreamSpec->GetSize() >= ((UInt64)1 << 32)) - return S_FALSE; - packPos += packSize; - } - data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize()); - _dynOutStreamSpec->CopyToBuffer(data.Data); - return S_OK; -} - -struct CTempItem -{ - UInt32 StartBlock; - // UInt32 iNodeNumber1; - UInt32 Offset; - // UInt16 iNodeNumber2; - UInt16 Type; -}; - -HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex) -{ - if (level > kNumDirLevelsMax) - return S_FALSE; - - int blockIndex = _inodesData.PackPos.FindInSorted(startBlock); - if (blockIndex < 0) - return S_FALSE; - UInt32 unpackPos = _inodesData.UnpackPos[blockIndex] + offset; - if (unpackPos < offset) - return S_FALSE; - - nodeIndex = _nodesPos.FindInSorted(unpackPos, _blockToNode[blockIndex], _blockToNode[blockIndex + 1]); - // nodeIndex = _nodesPos.FindInSorted(unpackPos); - if (nodeIndex < 0) - return S_FALSE; - - const CNode &n = _nodes[nodeIndex]; - if (!n.IsDir()) - return S_OK; - blockIndex = _dirs.PackPos.FindInSorted((UInt32)n.StartBlock); - if (blockIndex < 0) - return S_FALSE; - unpackPos = _dirs.UnpackPos[blockIndex] + n.Offset; - if (unpackPos < n.Offset || unpackPos > _dirs.Data.Size()) - return S_FALSE; - - UInt32 rem = (UInt32)_dirs.Data.Size() - unpackPos; - const Byte *p = _dirs.Data + unpackPos; - UInt32 fileSize = (UInt32)n.FileSize; - - // for some squashfs files: fileSize = rem + 3 !!! - if (_h.Major >= 3) - { - if (fileSize < 3) - return S_FALSE; - fileSize -= 3; - } - if (fileSize > rem) - return S_FALSE; - rem = fileSize; - - CRecordVector tempItems; - while (rem != 0) - { - bool be = _h.be; - UInt32 count; - CTempItem tempItem; - if (_h.Major <= 2) - { - if (rem < 4) - return S_FALSE; - count = p[0]; - tempItem.StartBlock = Get32(p); - if (be) - tempItem.StartBlock &= 0xFFFFFF; - else - tempItem.StartBlock >>= 8; - p += 4; - rem -= 4; - } - else - { - if (_h.Major == 3) - { - if (rem < 9) - return S_FALSE; - count = p[0]; - p += 1; - rem -= 1; - } - else - { - if (rem < 12) - return S_FALSE; - count = GetUi32(p); - p += 4; - rem -= 4; - } - GET_32 (0, tempItem.StartBlock); - // GET_32 (4, tempItem.iNodeNumber1); - p += 8; - rem -= 8; - } - count++; - - for (UInt32 i = 0; i < count; i++) - { - if (rem == 0) - return S_FALSE; - - UInt32 nameOffset = _h.GetFileNameOffset(); - if (rem < nameOffset) - return S_FALSE; - - if ((UInt32)_items.Size() >= kNumFilesMax) - return S_FALSE; - if (_openCallback) - { - UInt64 numFiles = _items.Size(); - if ((numFiles & 0xFFFF) == 0) - { - RINOK(_openCallback->SetCompleted(&numFiles, NULL)); - } - } - - CItem item; - item.Ptr = (UInt32)(p - _dirs.Data); - - UInt32 size; - if (_h.IsOldVersion()) - { - UInt32 t = Get16(p); - if (be) - { - tempItem.Offset = t >> 3; - tempItem.Type = (UInt16)(t & 0x7); - } - else - { - tempItem.Offset = t & 0x1FFF; - tempItem.Type = (UInt16)(t >> 13); - } - size = (UInt32)p[2]; - /* - if (_h.Major > 2) - tempItem.iNodeNumber2 = Get16(p + 3); - */ - } - else - { - GET_16 (0, tempItem.Offset); - // GET_16 (2, tempItem.iNodeNumber2); - GET_16 (4, tempItem.Type); - GET_16 (6, size); - } - p += nameOffset; - rem -= nameOffset; - size++; - if (rem < size) - return S_FALSE; - p += size; - rem -= size; - item.Parent = parent; - _items.Add(item); - tempItems.Add(tempItem); - } - } - - int startItemIndex = _items.Size() - tempItems.Size(); - FOR_VECTOR (i, tempItems) - { - const CTempItem &tempItem = tempItems[i]; - int index = startItemIndex + i; - CItem &item = _items[index]; - RINOK(OpenDir(index, tempItem.StartBlock, tempItem.Offset, level + 1, item.Node)); - } - - 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)); - return ReadStream_FALSE(_stream, ids, size); -} -*/ - -HRESULT CHandler::Open2(IInStream *inStream) -{ - { - Byte buf[kHeaderSize3]; - RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize3)); - if (!_h.Parse(buf)) - return S_FALSE; - if (!_h.IsSupported()) - return E_NOTIMPL; - - _noPropsLZMA = false; - _needCheckLzma = false; - switch (_h.Method) - { - case kMethod_ZLIB: _needCheckLzma = true; break; - case kMethod_LZMA: - case kMethod_LZO: - case kMethod_XZ: - break; - default: - return E_NOTIMPL; - } - } - - _stream = inStream; - - if (_h.NumFrags != 0) - { - if (_h.NumFrags > kNumFilesMax) - return S_FALSE; - _frags.ClearAndReserve(_h.NumFrags); - 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); - CByteBuffer data(numBlocksBytes); - RINOK(inStream->Seek(_h.FragTable, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)); - 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(); - if (unpackSize != kMetadataBlockSize) - if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1))) - return S_FALSE; - const Byte *buf = _dynOutStreamSpec->GetBuffer(); - for (UInt32 j = 0; j < kMetadataBlockSize && j < unpackSize;) - { - CFrag frag; - if (bigFrag) - { - frag.StartBlock = Get64(buf + j); - frag.Size = Get32(buf + j + 8); - // some archives contain nonzero in unused (buf + j + 12) - j += 16; - } - else - { - frag.StartBlock = Get32(buf + j); - frag.Size = Get32(buf + j + 4); - j += 8; - } - _frags.Add(frag); - } - } - if ((UInt32)_frags.Size() != _h.NumFrags) - 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)); - - UInt64 absOffset = _h.RootInode >> 16; - if (absOffset >= ((UInt64)1 << 32)) - return S_FALSE; - { - UInt32 pos = 0; - UInt32 totalSize = (UInt32)_inodesData.Data.Size(); - _nodesPos.ClearAndReserve(_h.NumInodes); - _nodes.ClearAndReserve(_h.NumInodes); - // we use _blockToNode for binary search seed optimizations - _blockToNode.ClearAndReserve(_inodesData.GetNumBlocks() + 1); - int curBlock = 0; - for (UInt32 i = 0; i < _h.NumInodes; i++) - { - CNode n; - const Byte *p = _inodesData.Data + pos; - UInt32 size = totalSize - pos; - - switch (_h.Major) - { - case 1: size = n.Parse1(p, size, _h); break; - case 2: size = n.Parse2(p, size, _h); break; - case 3: size = n.Parse3(p, size, _h); break; - default: size = n.Parse4(p, size, _h); break; - } - if (size == 0) - return S_FALSE; - while (pos >= _inodesData.UnpackPos[curBlock]) - { - _blockToNode.Add(_nodesPos.Size()); - curBlock++; - } - _nodesPos.AddInReserved(pos); - _nodes.AddInReserved(n); - pos += size; - } - _blockToNode.Add(_nodesPos.Size()); - if (pos != totalSize) - return S_FALSE; - } - int rootNodeIndex; - RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex)); - - /* - if (_h.Major < 4) - { - RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids)); - RINOK(ReadUids(_h.GidTable, _h.NumGids, _gids)); - } - else - { - UInt32 size = _h.NumIDs * 4; - _uids.SetCapacity(size); - - UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize; - UInt32 numBlocksBytes = numBlocks << 3; - CByteBuffer data; - data.SetCapacity(numBlocksBytes); - RINOK(inStream->Seek(_h.UidTable, STREAM_SEEK_SET, NULL)); - 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)); - if (unpackSize != kMetadataBlockSize) - if (i != numBlocks - 1 || unpackSize != (size & (kMetadataBlockSize - 1))) - return S_FALSE; - } - } - */ - - { - const UInt32 alignSize = 1 << 12; - Byte buf[alignSize]; - RINOK(inStream->Seek(_h.Size, STREAM_SEEK_SET, NULL)); - UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1); - _sizeCalculated = _h.Size; - if (rem != 0) - { - if (ReadStream_FALSE(_stream, buf, rem) == S_OK) - { - size_t i; - for (i = 0; i < rem && buf[i] == 0; i++); - if (i == rem) - _sizeCalculated = _h.Size + rem; - } - } - } - return S_OK; -} - -AString CHandler::GetPath(int index) const -{ - unsigned len = 0; - int indexMem = index; - bool be = _h.be; - do - { - const CItem &item = _items[index]; - index = item.Parent; - const Byte *p = _dirs.Data + item.Ptr; - unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; - p += _h.GetFileNameOffset(); - unsigned i; - for (i = 0; i < size && p[i]; i++); - len += i + 1; - } - while (index >= 0); - len--; - - AString path; - char *dest = path.GetBuf_SetEnd(len) + len; - index = indexMem; - for (;;) - { - const CItem &item = _items[index]; - index = item.Parent; - const Byte *p = _dirs.Data + item.Ptr; - unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; - p += _h.GetFileNameOffset(); - unsigned i; - for (i = 0; i < size && p[i]; i++); - dest -= i; - memcpy(dest, p, i); - if (index < 0) - break; - *(--dest) = CHAR_PATH_SEPARATOR; - } - return path; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - _limitedInStreamSpec->SetStream(stream); - HRESULT res; - try - { - _openCallback = callback; - res = Open2(stream); - } - catch(...) - { - Close(); - throw; - } - if (res != S_OK) - { - Close(); - return res; - } - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _sizeCalculated = 0; - - _limitedInStreamSpec->ReleaseStream(); - _stream.Release(); - - _items.Clear(); - _nodes.Clear(); - _nodesPos.Clear(); - _blockToNode.Clear(); - _frags.Clear(); - _inodesData.Clear(); - _dirs.Clear(); - - // _uids.Free(); - // _gids.Free();; - - _cachedBlock.Free(); - ClearCache(); - - return S_OK; -} - -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 Byte *p = _inodesData.Data + ptr; - bool be = _h.be; - - UInt32 type = node.Type; - UInt32 offset; - if (node.IsLink() || node.FileSize == 0) - { - totalPack = node.FileSize; - return true; - } - - UInt32 numBlocks = (UInt32)node.GetNumBlocks(_h); - - if (fillOffsets) - { - _blockOffsets.Clear(); - _blockCompressed.Clear(); - _blockOffsets.Add(totalPack); - } - - if (_h.Major <= 1) - { - offset = 15; - p += offset; - - for (UInt32 i = 0; i < numBlocks; i++) - { - UInt32 t = Get16(p + i * 2); - if (fillOffsets) - _blockCompressed.Add((t & kNotCompressedBit16) == 0); - if (t != kNotCompressedBit16) - t &= ~kNotCompressedBit16; - totalPack += t; - if (fillOffsets) - _blockOffsets.Add(totalPack); - } - } - else - { - if (_h.Major <= 2) - offset = 24; - else if (type == kType_FILE) - offset = 32; - else if (type == kType_FILE + 7) - offset = (_h.Major <= 3 ? 40 : 56); - else - return false; - - p += offset; - - for (UInt64 i = 0; i < numBlocks; i++) - { - UInt32 t = Get32(p + i * 4); - if (fillOffsets) - _blockCompressed.Add(IS_COMPRESSED_BLOCK(t)); - UInt32 size = GET_COMPRESSED_BLOCK_SIZE(t); - if (size > _h.BlockSize) - return false; - totalPack += size; - if (fillOffsets) - _blockOffsets.Add(totalPack); - } - - if (node.ThereAreFrags()) - { - if (node.Frag >= (UInt32)_frags.Size()) - return false; - const CFrag &frag = _frags[node.Frag]; - if (node.Offset == 0) - { - UInt32 size = GET_COMPRESSED_BLOCK_SIZE(frag.Size); - if (size > _h.BlockSize) - return false; - totalPack += size; - } - } - } - return true; -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidMethod: - { - const char *s; - if (_noPropsLZMA) - s = "LZMA Spec"; - else if (_h.SeveralMethods) - s = "LZMA ZLIB"; - else - { - s = k_Methods[0]; - if (_h.Method < ARRAY_SIZE(k_Methods)) - s = k_Methods[_h.Method]; - } - prop = s; - break; - } - case kpidFileSystem: - { - AString res = "SquashFS"; - if (_h.SeveralMethods) - res += "-LZMA"; - res.Add_Space(); - char s[16]; - ConvertUInt32ToString(_h.Major, s); - res += s; - res += '.'; - ConvertUInt32ToString(_h.Minor, s); - res += s; - prop = res; - break; - } - case kpidClusterSize: prop = _h.BlockSize; break; - case kpidBigEndian: prop = _h.be; break; - case kpidCTime: - if (_h.CTime != 0) - { - FILETIME ft; - NWindows::NTime::UnixTimeToFileTime(_h.CTime, ft); - prop = ft; - } - break; - case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break; - // case kpidNumBlocks: prop = _h.NumFrags; break; - case kpidPhySize: prop = _sizeCalculated; break; - case kpidHeadersSize: - if (_sizeCalculated >= _h.InodeTable) - prop = _sizeCalculated - _h.InodeTable; - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItem &item = _items[index]; - const CNode &node = _nodes[item.Node]; - bool isDir = node.IsDir(); - bool be = _h.be; - - switch (propID) - { - case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; - case kpidIsDir: prop = isDir; break; - // case kpidOffset: if (!node.IsLink()) prop = (UInt64)node.StartBlock; break; - case kpidSize: if (!isDir) prop = node.GetSize(); break; - case kpidPackSize: - if (!isDir) - { - UInt64 size; - if (GetPackSize(index, size, false)) - prop = size; - } - break; - case kpidMTime: - { - UInt32 offset = 0; - switch (_h.Major) - { - case 1: - if (node.Type == kType_FILE) - offset = 3; - else if (node.Type == kType_DIR) - offset = 7; - break; - case 2: - if (node.Type == kType_FILE) - offset = 4; - else if (node.Type == kType_DIR) - offset = 8; - else if (node.Type == kType_DIR + 7) - offset = 9; - break; - case 3: offset = 4; break; - case 4: offset = 8; break; - } - if (offset != 0) - { - const Byte *p = _inodesData.Data + _nodesPos[item.Node] + offset; - FILETIME ft; - NWindows::NTime::UnixTimeToFileTime(Get32(p), ft); - prop = ft; - } - break; - } - case kpidPosixAttrib: - { - if (node.Type != 0 && node.Type < ARRAY_SIZE(k_TypeToMode)) - prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; - break; - } - /* - case kpidUser: - { - UInt32 offset = node.Uid * 4; - if (offset < _uids.Size()) - prop = (UInt32)Get32(_uids + offset); - break; - } - case kpidGroup: - { - if (_h.Major == 4 || node.Gid == _h.GetSpecGuidIndex()) - { - UInt32 offset = node.Uid * 4; - if (offset < _uids.Size()) - prop = (UInt32)Get32(_uids + offset); - } - else - { - UInt32 offset = node.Gid * 4; - if (offset < _gids.Size()) - prop = (UInt32)Get32(_gids + offset); - } - break; - } - */ - /* - case kpidLinks: - if (_h.Major >= 3 && node.Type != kType_FILE) - prop = node.NumLinks; - break; - */ - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CSquashfsInStream: public CCachedInStream -{ - HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); -public: - CHandler *Handler; -}; - -HRESULT CSquashfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) -{ - return Handler->ReadBlock(blockIndex, dest, blockSize); -} - -HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) -{ - const CNode &node = _nodes[_nodeIndex]; - UInt64 blockOffset; - UInt32 packBlockSize; - UInt32 offsetInBlock = 0; - bool compressed; - if (blockIndex < _blockCompressed.Size()) - { - compressed = _blockCompressed[(int)blockIndex]; - blockOffset = _blockOffsets[(int)blockIndex]; - packBlockSize = (UInt32)(_blockOffsets[(int)blockIndex + 1] - blockOffset); - blockOffset += node.StartBlock; - } - else - { - if (!node.ThereAreFrags()) - return S_FALSE; - const CFrag &frag = _frags[node.Frag]; - offsetInBlock = node.Offset; - blockOffset = frag.StartBlock; - packBlockSize = GET_COMPRESSED_BLOCK_SIZE(frag.Size); - compressed = IS_COMPRESSED_BLOCK(frag.Size); - } - - if (packBlockSize == 0) - { - // sparse file ??? - memset(dest, 0, blockSize); - return S_OK; - } - - if (blockOffset != _cachedBlockStartPos || - packBlockSize != _cachedPackBlockSize) - { - ClearCache(); - RINOK(_stream->Seek(blockOffset, STREAM_SEEK_SET, NULL)); - _limitedInStreamSpec->Init(packBlockSize); - - if (compressed) - { - _outStreamSpec->Init((Byte *)_cachedBlock, _h.BlockSize); - bool outBufWasWritten; - UInt32 outBufWasWrittenSize; - HRESULT res = Decompress(_outStream, _cachedBlock, &outBufWasWritten, &outBufWasWrittenSize, packBlockSize, _h.BlockSize); - if (outBufWasWritten) - _cachedUnpackBlockSize = outBufWasWrittenSize; - else - _cachedUnpackBlockSize = (UInt32)_outStreamSpec->GetPos(); - RINOK(res); - } - else - { - RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize)); - _cachedUnpackBlockSize = packBlockSize; - } - _cachedBlockStartPos = blockOffset; - _cachedPackBlockSize = packBlockSize; - } - if (offsetInBlock + blockSize > _cachedUnpackBlockSize) - return S_FALSE; - if (blockSize != 0) - memcpy(dest, _cachedBlock + offsetInBlock, blockSize); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - 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 CItem &item = _items[allFilesMode ? i : indices[i]]; - const CNode &node = _nodes[item.Node]; - totalSize += node.GetSize(); - } - extractCallback->SetTotal(totalSize); - - UInt64 totalPackSize; - totalSize = totalPackSize = 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 = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr outStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[index]; - const CNode &node = _nodes[item.Node]; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - // const Byte *p = _data + item.Offset; - - if (node.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - UInt64 unpackSize = node.GetSize(); - totalSize += unpackSize; - UInt64 packSize; - if (GetPackSize(index, packSize, false)) - totalPackSize += packSize; - - if (!testMode && !outStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - int res = NExtract::NOperationResult::kDataError; - { - CMyComPtr inSeqStream; - HRESULT hres = GetStream(index, &inSeqStream); - if (hres == S_FALSE || !inSeqStream) - { - if (hres == E_OUTOFMEMORY) - return hres; - res = NExtract::NOperationResult::kUnsupportedMethod; - } - else - { - RINOK(hres); - { - hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); - if (hres == S_OK) - { - if (copyCoderSpec->TotalSize == unpackSize) - res = NExtract::NOperationResult::kOK; - } - else if (hres == E_NOTIMPL) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - } - else if (hres != S_FALSE) - { - RINOK(hres); - } - } - } - } - - RINOK(extractCallback->SetOperationResult(res)); - } - - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - - const CItem &item = _items[index]; - const CNode &node = _nodes[item.Node]; - - if (node.IsDir()) - return E_FAIL; - - const Byte *p = _inodesData.Data + _nodesPos[item.Node]; - - if (node.FileSize == 0 || node.IsLink()) - { - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - if (node.IsLink()) - streamSpec->Init(p + _h.GetSymLinkOffset(), (size_t)node.FileSize); - else - streamSpec->Init(NULL, 0); - *stream = streamTemp.Detach(); - return S_OK; - } - - UInt64 packSize; - if (!GetPackSize(index, packSize, true)) - return S_FALSE; - - _nodeIndex = item.Node; - - size_t cacheSize = _h.BlockSize; - if (_cachedBlock.Size() != cacheSize) - { - ClearCache(); - _cachedBlock.Alloc(cacheSize); - } - - CSquashfsInStream *streamSpec = new CSquashfsInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Handler = this; - unsigned cacheSizeLog = 22; - if (cacheSizeLog <= _h.BlockSizeLog) - cacheSizeLog = _h.BlockSizeLog + 1; - if (!streamSpec->Alloc(_h.BlockSizeLog, cacheSizeLog - _h.BlockSizeLog)) - return E_OUTOFMEMORY; - streamSpec->Init(node.FileSize); - *stream = streamTemp.Detach(); - - return S_OK; - - COM_TRY_END -} - -static const Byte k_Signature[] = { - 4, 'h', 's', 'q', 's', - 4, 's', 'q', 's', 'h', - 4, 's', 'h', 's', 'q' }; - -REGISTER_ARC_I( - "SquashFS", "squashfs", 0, 0xD2, - k_Signature, - 0, - NArcInfoFlags::kMultiSignature, - NULL) - -}} +// SquashfsHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/LzmaDec.h" +#include "../../../C/Xz.h" +#include "../../../C/ZstdDec.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringConvert.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/CWrappers.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 "../Compress/ZlibDecoder.h" +// #include "../Compress/LzmaDecoder.h" + +namespace NArchive { +namespace NSquashfs { + +static const UInt32 kNumFilesMax = 1 << 28; +static const unsigned kNumDirLevelsMax = 1 << 10; + +// Layout: Header, Data, inodes, Directories, Fragments, UIDs, GIDs + +/* +#define Get16(p) (be ? GetBe16(p) : GetUi16(p)) +#define Get32(p) (be ? GetBe32(p) : GetUi32(p)) +#define Get64(p) (be ? GetBe64(p) : GetUi64(p)) +*/ + +static UInt16 Get16b(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); } +static UInt32 Get32b(const Byte *p, bool be) { return be ? GetBe32(p) : GetUi32(p); } +static UInt64 Get64b(const Byte *p, bool be) { return be ? GetBe64(p) : GetUi64(p); } + +#define Get16(p) Get16b(p, be) +#define Get32(p) Get32b(p, be) +#define Get64(p) Get64b(p, be) + +#define LE_16(offs, dest) dest = GetUi16(p + (offs)) +#define LE_32(offs, dest) dest = GetUi32(p + (offs)) +#define LE_64(offs, dest) dest = GetUi64(p + (offs)) + +#define GET_16(offs, dest) dest = Get16(p + (offs)) +#define GET_32(offs, dest) dest = Get32(p + (offs)) +#define GET_64(offs, dest) dest = Get64(p + (offs)) + +static const UInt32 kSignature32_LE = 0x73717368; +static const UInt32 kSignature32_BE = 0x68737173; +static const UInt32 kSignature32_LZ = 0x71736873; +static const UInt32 kSignature32_B2 = 0x73687371; + +#define kMethod_ZLIB 1 +#define kMethod_LZMA 2 +#define kMethod_LZO 3 +#define kMethod_XZ 4 +// #define kMethod_LZ4 5 +#define kMethod_ZSTD 6 + +static const char * const k_Methods[] = +{ + "0" + , "ZLIB" + , "LZMA" + , "LZO" + , "XZ" + , "LZ4" + , "ZSTD" +}; + +static const unsigned kMetadataBlockSizeLog = 13; +static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog); + +enum +{ + kType_IPC, + kType_DIR, + kType_FILE, + kType_LNK, + kType_BLK, + kType_CHR, + kType_FIFO, + kType_SOCK +}; + +static const UInt32 k_TypeToMode[] = +{ + 0, + MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK, + MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK +}; + + +enum +{ + kFlag_UNC_INODES, + kFlag_UNC_DATA, + kFlag_CHECK, + kFlag_UNC_FRAGS, + kFlag_NO_FRAGS, + kFlag_ALWAYS_FRAG, + kFlag_DUPLICATE, + kFlag_EXPORT +}; + +static const char * const k_Flags[] = +{ + "UNCOMPRESSED_INODES" + , "UNCOMPRESSED_DATA" + , "CHECK" + , "UNCOMPRESSED_FRAGMENTS" + , "NO_FRAGMENTS" + , "ALWAYS_FRAGMENTS" + , "DUPLICATES_REMOVED" + , "EXPORTABLE" + , "UNCOMPRESSED_XATTRS" + , "NO_XATTRS" + , "COMPRESSOR_OPTIONS" + , "UNCOMPRESSED_IDS" +}; + +static const UInt32 kNotCompressedBit16 = 1 << 15; +static const UInt32 kNotCompressedBit32 = 1 << 24; + +#define GET_COMPRESSED_BLOCK_SIZE(size) ((size) & ~kNotCompressedBit32) +#define IS_COMPRESSED_BLOCK(size) (((size) & kNotCompressedBit32) == 0) + +// static const UInt32 kHeaderSize1 = 0x33; +// static const UInt32 kHeaderSize2 = 0x3F; +static const UInt32 kHeaderSize3 = 0x77; +// static const UInt32 kHeaderSize4 = 0x60; + +struct CHeader +{ + bool be; + bool SeveralMethods; + Byte NumUids; + Byte NumGids; + + UInt32 NumInodes; + UInt32 CTime; + UInt32 BlockSize; + UInt32 NumFrags; + UInt16 Method; + UInt16 BlockSizeLog; + UInt16 Flags; + UInt16 NumIDs; + UInt16 Major; + UInt16 Minor; + UInt64 RootInode; + UInt64 Size; + UInt64 UidTable; + UInt64 GidTable; + UInt64 XattrIdTable; + UInt64 InodeTable; + UInt64 DirTable; + UInt64 FragTable; + UInt64 LookupTable; + + void Parse3(const Byte *p) + { + Method = kMethod_ZLIB; + GET_32 (0x08, Size); + GET_32 (0x0C, UidTable); + GET_32 (0x10, GidTable); + GET_32 (0x14, InodeTable); + GET_32 (0x18, DirTable); + GET_16 (0x20, BlockSize); + GET_16 (0x22, BlockSizeLog); + Flags = p[0x24]; + NumUids = p[0x25]; + NumGids = p[0x26]; + GET_32 (0x27, CTime); + GET_64 (0x2B, RootInode); + NumFrags = 0; + FragTable = UidTable; + + if (Major >= 2) + { + GET_32 (0x33, BlockSize); + GET_32 (0x37, NumFrags); + GET_32 (0x3B, FragTable); + if (Major == 3) + { + GET_64 (0x3F, Size); + GET_64 (0x47, UidTable); + GET_64 (0x4F, GidTable); + GET_64 (0x57, InodeTable); + GET_64 (0x5F, DirTable); + GET_64 (0x67, FragTable); + GET_64 (0x6F, LookupTable); + } + } + } + + void Parse4(const Byte *p) + { + LE_32 (0x08, CTime); + LE_32 (0x0C, BlockSize); + LE_32 (0x10, NumFrags); + LE_16 (0x14, Method); + LE_16 (0x16, BlockSizeLog); + LE_16 (0x18, Flags); + LE_16 (0x1A, NumIDs); + LE_64 (0x20, RootInode); + LE_64 (0x28, Size); + LE_64 (0x30, UidTable); + LE_64 (0x38, XattrIdTable); + LE_64 (0x40, InodeTable); + LE_64 (0x48, DirTable); + LE_64 (0x50, FragTable); + LE_64 (0x58, LookupTable); + GidTable = 0; + } + + bool Parse(const Byte *p) + { + be = false; + SeveralMethods = false; + switch (GetUi32(p)) + { + case kSignature32_LE: break; + case kSignature32_BE: be = true; break; + case kSignature32_LZ: SeveralMethods = true; break; + case kSignature32_B2: SeveralMethods = true; be = true; break; + default: return false; + } + GET_32 (4, NumInodes); + GET_16 (0x1C, Major); + GET_16 (0x1E, Minor); + if (Major <= 3) + Parse3(p); + else + { + if (be) + return false; + Parse4(p); + } + return + InodeTable < DirTable && + DirTable <= FragTable && + FragTable <= Size && + UidTable <= Size && + BlockSizeLog >= 12 && + BlockSizeLog < 31 && + BlockSize == ((UInt32)1 << BlockSizeLog); + } + + bool IsSupported() const { return Major > 0 && Major <= 4 && BlockSizeLog <= 23; } + bool IsOldVersion() const { return Major < 4; } + bool NeedCheckData() const { return (Flags & (1 << kFlag_CHECK)) != 0; } + unsigned GetFileNameOffset() const { return Major <= 2 ? 3 : (Major == 3 ? 5 : 8); } + unsigned GetSymLinkOffset() const { return Major <= 1 ? 5: (Major <= 2 ? 6: (Major == 3 ? 18 : 24)); } + unsigned GetSpecGuidIndex() const { return Major <= 1 ? 0xF: 0xFF; } +}; + +static const UInt32 kFrag_Empty = (UInt32)(Int32)-1; +// static const UInt32 kXattr_Empty = (UInt32)(Int32)-1; + +struct CNode +{ + UInt16 Type; + UInt16 Mode; + UInt16 Uid; + UInt16 Gid; + UInt32 Frag; + UInt32 Offset; + // UInt32 MTime; + // UInt32 Number; + // UInt32 NumLinks; + // UInt32 RDev; + // UInt32 Xattr; + // UInt32 Parent; + + UInt64 FileSize; + UInt64 StartBlock; + // UInt64 Sparse; + + UInt32 Parse1(const Byte *p, UInt32 size, const CHeader &_h); + UInt32 Parse2(const Byte *p, UInt32 size, const CHeader &_h); + UInt32 Parse3(const Byte *p, UInt32 size, const CHeader &_h); + UInt32 Parse4(const Byte *p, UInt32 size, const CHeader &_h); + + bool IsDir() const { return (Type == kType_DIR || Type == kType_DIR + 7); } + bool IsLink() const { return (Type == kType_LNK || Type == kType_LNK + 7); } + UInt64 GetSize() const { return IsDir() ? 0 : FileSize; } + + bool ThereAreFrags() const { return Frag != kFrag_Empty; } + UInt64 GetNumBlocks(const CHeader &_h) const + { + return (FileSize >> _h.BlockSizeLog) + + (!ThereAreFrags() && (FileSize & (_h.BlockSize - 1)) != 0); + } +}; + +UInt32 CNode::Parse1(const Byte *p, UInt32 size, const CHeader &_h) +{ + const bool be = _h.be; + if (size < 4) + return 0; + { + const UInt32 t = Get16(p); + if (be) + { + Type = (UInt16)(t >> 12); + Mode = (UInt16)(t & 0xFFF); + Uid = (UInt16)(p[2] >> 4); + Gid = (UInt16)(p[2] & 0xF); + } + else + { + Type = (UInt16)(t & 0xF); + Mode = (UInt16)(t >> 4); + Uid = (UInt16)(p[2] & 0xF); + Gid = (UInt16)(p[2] >> 4); + } + } + + // Xattr = kXattr_Empty; + // MTime = 0; + FileSize = 0; + StartBlock = 0; + Frag = kFrag_Empty; + + if (Type == 0) + { + Byte t = p[3]; + if (be) + { + Type = (UInt16)(t >> 4); + Offset = (UInt16)(t & 0xF); + } + else + { + Type = (UInt16)(t & 0xF); + Offset = (UInt16)(t >> 4); + } + return (Type == kType_FIFO || Type == kType_SOCK) ? 4 : 0; + } + + Type--; + Uid = (UInt16)(Uid + (Type / 5) * 16); + Type = (UInt16)((Type % 5) + 1); + + if (Type == kType_FILE) + { + if (size < 15) + return 0; + // GET_32 (3, MTime); + GET_32 (7, StartBlock); + UInt32 t; + GET_32 (11, t); + FileSize = t; + UInt32 numBlocks = t >> _h.BlockSizeLog; + if ((t & (_h.BlockSize - 1)) != 0) + numBlocks++; + UInt32 pos = numBlocks * 2 + 15; + return (pos <= size) ? pos : 0; + } + + if (Type == kType_DIR) + { + if (size < 14) + return 0; + UInt32 t = Get32(p + 3); + if (be) + { + FileSize = t >> 13; + Offset = t & 0x1FFF; + } + else + { + FileSize = t & 0x7FFFF; + Offset = t >> 19; + } + // GET_32 (7, MTime); + GET_32 (10, StartBlock); + if (be) + StartBlock &= 0xFFFFFF; + else + StartBlock >>= 8; + return 14; + } + + if (size < 5) + return 0; + + if (Type == kType_LNK) + { + UInt32 len; + GET_16 (3, len); + FileSize = len; + len += 5; + return (len <= size) ? len : 0; + } + + // GET_32 (3, RDev); + return 5; +} + +UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h) +{ + const bool be = _h.be; + if (size < 4) + return 0; + { + const UInt32 t = Get16(p); + if (be) + { + Type = (UInt16)(t >> 12); + Mode = (UInt16)(t & 0xFFF); + } + else + { + Type = (UInt16)(t & 0xF); + Mode = (UInt16)(t >> 4); + } + } + + Uid = p[2]; + Gid = p[3]; + + // Xattr = kXattr_Empty; + + if (Type == kType_FILE) + { + if (size < 24) + return 0; + // GET_32 (4, MTime); + GET_32 (8, StartBlock); + GET_32 (12, Frag); + GET_32 (16, Offset); + UInt32 t; + GET_32 (20, t); + FileSize = t; + UInt32 numBlocks = t >> _h.BlockSizeLog; + if (!ThereAreFrags() && (t & (_h.BlockSize - 1)) != 0) + numBlocks++; + UInt32 pos = numBlocks * 4 + 24; + return (pos <= size) ? (UInt32)pos : 0; + } + + FileSize = 0; + // MTime = 0; + StartBlock = 0; + Frag = kFrag_Empty; + + if (Type == kType_DIR) + { + if (size < 15) + return 0; + UInt32 t = Get32(p + 4); + if (be) + { + FileSize = t >> 13; + Offset = t & 0x1FFF; + } + else + { + FileSize = t & 0x7FFFF; + Offset = t >> 19; + } + // GET_32 (8, MTime); + GET_32 (11, StartBlock); + if (be) + StartBlock &= 0xFFFFFF; + else + StartBlock >>= 8; + return 15; + } + + if (Type == kType_DIR + 7) + { + if (size < 18) + return 0; + UInt32 t = Get32(p + 4); + UInt32 t2 = Get16(p + 7); + if (be) + { + FileSize = t >> 5; + Offset = t2 & 0x1FFF; + } + else + { + FileSize = t & 0x7FFFFFF; + Offset = t2 >> 3; + } + // GET_32 (9, MTime); + GET_32 (12, StartBlock); + if (be) + StartBlock &= 0xFFFFFF; + else + StartBlock >>= 8; + UInt32 iCount; + GET_16 (16, iCount); + UInt32 pos = 18; + for (UInt32 i = 0; i < iCount; i++) + { + // 27 bits: index + // 29 bits: startBlock + if (pos + 8 > size) + return 0; + pos += 8 + (UInt32)p[pos + 7] + 1; // nameSize + if (pos > size) + return 0; + } + return pos; + } + + if (Type == kType_FIFO || Type == kType_SOCK) + return 4; + + if (size < 6) + return 0; + + if (Type == kType_LNK) + { + UInt32 len; + GET_16 (4, len); + FileSize = len; + len += 6; + return (len <= size) ? len : 0; + } + + if (Type == kType_BLK || Type == kType_CHR) + { + // GET_16 (4, RDev); + return 6; + } + + return 0; +} + +UInt32 CNode::Parse3(const Byte *p, UInt32 size, const CHeader &_h) +{ + const bool be = _h.be; + if (size < 12) + return 0; + + { + const UInt32 t = Get16(p); + if (be) + { + Type = (UInt16)(t >> 12); + Mode = (UInt16)(t & 0xFFF); + } + else + { + Type = (UInt16)(t & 0xF); + Mode = (UInt16)(t >> 4); + } + } + + Uid = p[2]; + Gid = p[3]; + // GET_32 (4, MTime); + // GET_32 (8, Number); + // Xattr = kXattr_Empty; + FileSize = 0; + StartBlock = 0; + + if (Type == kType_FILE || Type == kType_FILE + 7) + { + UInt32 offset; + if (Type == kType_FILE) + { + if (size < 32) + return 0; + GET_64 (12, StartBlock); + GET_32 (20, Frag); + GET_32 (24, Offset); + GET_32 (28, FileSize); + offset = 32; + } + else + { + if (size < 40) + return 0; + // GET_32 (12, NumLinks); + GET_64 (16, StartBlock); + GET_32 (24, Frag); + GET_32 (28, Offset); + GET_64 (32, FileSize); + offset = 40; + } + UInt64 pos = GetNumBlocks(_h) * 4 + offset; + return (pos <= size) ? (UInt32)pos : 0; + } + + if (size < 16) + return 0; + // GET_32 (12, NumLinks); + + if (Type == kType_DIR) + { + if (size < 28) + return 0; + UInt32 t = Get32(p + 16); + if (be) + { + FileSize = t >> 13; + Offset = t & 0x1FFF; + } + else + { + FileSize = t & 0x7FFFF; + Offset = t >> 19; + } + GET_32 (20, StartBlock); + // GET_32 (24, Parent); + return 28; + } + + if (Type == kType_DIR + 7) + { + if (size < 31) + return 0; + UInt32 t = Get32(p + 16); + UInt32 t2 = Get16(p + 19); + if (be) + { + FileSize = t >> 5; + Offset = t2 & 0x1FFF; + } + else + { + FileSize = t & 0x7FFFFFF; + Offset = t2 >> 3; + } + GET_32 (21, StartBlock); + UInt32 iCount; + GET_16 (25, iCount); + // GET_32 (27, Parent); + UInt32 pos = 31; + for (UInt32 i = 0; i < iCount; i++) + { + // UInt32 index + // UInt32 startBlock + if (pos + 9 > size) + return 0; + pos += 9 + (unsigned)p[pos + 8] + 1; // nameSize + if (pos > size) + return 0; + } + return pos; + } + + if (Type == kType_FIFO || Type == kType_SOCK) + return 16; + + if (size < 18) + return 0; + if (Type == kType_LNK) + { + UInt32 len; + GET_16 (16, len); + FileSize = len; + len += 18; + return (len <= size) ? len : 0; + } + + if (Type == kType_BLK || Type == kType_CHR) + { + // GET_16 (16, RDev); + return 18; + } + + return 0; +} + +UInt32 CNode::Parse4(const Byte *p, UInt32 size, const CHeader &_h) +{ + if (size < 20) + return 0; + LE_16 (0, Type); + LE_16 (2, Mode); + LE_16 (4, Uid); + LE_16 (6, Gid); + // LE_32 (8, MTime); + // LE_32 (12, Number); + + // Xattr = kXattr_Empty; + FileSize = 0; + StartBlock = 0; + + if (Type == kType_FILE || Type == kType_FILE + 7) + { + UInt32 offset; + if (Type == kType_FILE) + { + if (size < 32) + return 0; + LE_32 (16, StartBlock); + LE_32 (20, Frag); + LE_32 (24, Offset); + LE_32 (28, FileSize); + offset = 32; + } + else + { + if (size < 56) + return 0; + LE_64 (16, StartBlock); + LE_64 (24, FileSize); + // LE_64 (32, Sparse); + // LE_32 (40, NumLinks); + LE_32 (44, Frag); + LE_32 (48, Offset); + // LE_32 (52, Xattr); + offset = 56; + } + UInt64 pos = GetNumBlocks(_h) * 4 + offset; + return (pos <= size) ? (UInt32)pos : 0; + } + + if (Type == kType_DIR) + { + if (size < 32) + return 0; + LE_32 (16, StartBlock); + // LE_32 (20, NumLinks); + LE_16 (24, FileSize); + LE_16 (26, Offset); + // LE_32 (28, Parent); + return 32; + } + + // LE_32 (16, NumLinks); + + if (Type == kType_DIR + 7) + { + if (size < 40) + return 0; + LE_32 (20, FileSize); + LE_32 (24, StartBlock); + // LE_32 (28, Parent); + UInt32 iCount; + LE_16 (32, iCount); + LE_16 (34, Offset); + // LE_32 (36, Xattr); + + UInt32 pos = 40; + for (UInt32 i = 0; i < iCount; i++) + { + // UInt32 index + // UInt32 startBlock + if (pos + 12 > size) + return 0; + UInt32 nameLen = GetUi32(p + pos + 8); + pos += 12 + nameLen + 1; + if (pos > size || nameLen > (1 << 10)) + return 0; + } + return pos; + } + + unsigned offset = 20; + switch (Type) + { + case kType_FIFO: case kType_FIFO + 7: + case kType_SOCK: case kType_SOCK + 7: + break; + case kType_LNK: case kType_LNK + 7: + { + if (size < 24) + return 0; + UInt32 len; + LE_32 (20, len); + FileSize = len; + offset = len + 24; + if (size < offset || len > (1 << 30)) + return 0; + break; + } + case kType_BLK: case kType_BLK + 7: + case kType_CHR: case kType_CHR + 7: + if (size < 24) + return 0; + // LE_32 (20, RDev); + offset = 24; + break; + default: + return 0; + } + + if (Type >= 8) + { + if (size < offset + 4) + return 0; + // LE_32 (offset, Xattr); + offset += 4; + } + return offset; +} + +struct CItem +{ + int Node; + int Parent; + UInt32 Ptr; + + CItem(): Node(-1), Parent(-1), Ptr(0) {} +}; + +struct CData +{ + CByteBuffer Data; + CRecordVector PackPos; + CRecordVector UnpackPos; // additional item at the end contains TotalUnpackSize + + UInt32 GetNumBlocks() const { return PackPos.Size(); } + void Clear() + { + Data.Free(); + PackPos.Clear(); + UnpackPos.Clear(); + } +}; + +struct CFrag +{ + UInt64 StartBlock; + UInt32 Size; +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + bool _noPropsLZMA; + bool _needCheckLzma; + + CRecordVector _items; + CRecordVector _nodes; + CRecordVector _nodesPos; + CRecordVector _blockToNode; + CData _inodesData; + CData _dirs; + CRecordVector _frags; + CByteBuffer _uids; + CByteBuffer _gids; + CHeader _h; + + UInt64 _sizeCalculated; + CMyComPtr _stream; + + IArchiveOpenCallback *_openCallback; + + UInt32 _openCodePage; + int _nodeIndex; + CRecordVector _blockCompressed; + CRecordVector _blockOffsets; + + CByteBuffer _cachedBlock; + UInt64 _cachedBlockStartPos; + UInt32 _cachedPackBlockSize; + UInt32 _cachedUnpackBlockSize; + + CMyComPtr2_Create _limitedInStream; + CMyComPtr2_Create _outStream; + CMyComPtr2_Create _dynOutStream; + + // CMyComPtr2 _lzmaDecoder; + CMyComPtr2 _zlibDecoder; + + CXzUnpacker _xz; + CZstdDecHandle _zstd; + + CByteBuffer _inputBuffer; + + void ClearCache() + { + _cachedBlockStartPos = 0; + _cachedPackBlockSize = 0; + _cachedUnpackBlockSize = 0; + } + + HRESULT Seek2(UInt64 offset) + { + return InStream_SeekSet(_stream, offset); + } + + 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 Open2(IInStream *inStream); + AString GetPath(unsigned index) const; + bool GetPackSize(unsigned index, UInt64 &res, bool fillOffsets); + +public: + CHandler(); + ~CHandler() + { + XzUnpacker_Free(&_xz); + if (_zstd) + ZstdDec_Destroy(_zstd); + } + + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize); +}; + + +CHandler::CHandler(): + _zstd(NULL) +{ + XzUnpacker_Construct(&_xz, &g_Alloc); +} + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidPosixAttrib, + kpidUserId, + kpidGroupId + // kpidLinks, + // kpidOffset +}; + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidFileSystem, + kpidMethod, + kpidClusterSize, + kpidBigEndian, + kpidCTime, + kpidCharacts, + kpidCodePage + // kpidNumBlocks +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SizeT destRem = *destLen; + SizeT srcRem = *srcLen; + *destLen = 0; + *srcLen = 0; + const Byte *destStart = dest; + const Byte *srcStart = src; + unsigned mode = 0; + + { + if (srcRem == 0) + return S_FALSE; + UInt32 b = *src; + if (b > 17) + { + src++; + srcRem--; + b -= 17; + mode = (b < 4 ? 1 : 4); + if (b > srcRem || b > destRem) + return S_FALSE; + srcRem -= b; + destRem -= b; + do + *dest++ = *src++; + while (--b); + } + } + + for (;;) + { + if (srcRem < 3) + return S_FALSE; + UInt32 b = *src++; + srcRem--; + UInt32 len, back; + + if (b >= 64) + { + srcRem--; + back = ((b >> 2) & 7) + ((UInt32)*src++ << 3); + len = (b >> 5) + 1; + } + else if (b < 16) + { + if (mode == 0) + { + if (b == 0) + { + for (b = 15;; b += 255) + { + if (srcRem == 0) + return S_FALSE; + UInt32 b2 = *src++; + srcRem--; + if (b2 != 0) + { + b += b2; + break; + } + } + } + + b += 3; + if (b > srcRem || b > destRem) + return S_FALSE; + srcRem -= b; + destRem -= b; + mode = 4; + do + *dest++ = *src++; + while (--b); + continue; + } + + srcRem--; + back = (b >> 2) + ((UInt32)*src++ << 2); + len = 2; + if (mode == 4) + { + back += (1 << 11); + len = 3; + } + } + else + { + UInt32 bOld = b; + b = (b < 32 ? 7 : 31); + len = bOld & b; + + if (len == 0) + { + for (len = b;; len += 255) + { + if (srcRem == 0) + return S_FALSE; + UInt32 b2 = *src++; + srcRem--; + if (b2 != 0) + { + len += b2; + break; + } + } + } + + len += 2; + if (srcRem < 2) + return S_FALSE; + b = *src; + back = (b >> 2) + ((UInt32)src[1] << 6); + src += 2; + srcRem -= 2; + if (bOld < 32) + { + back += ((bOld & 8) << 11); + if (back == 0) + { + *destLen = (size_t)(dest - destStart); + *srcLen = (size_t)(src - srcStart); + return S_OK; + } + back += (1 << 14) - 1; + } + } + + back++; + if (len > destRem || (size_t)(dest - destStart) < back) + return S_FALSE; + destRem -= len; + Byte *destTemp = dest - back; + dest += len; + + do + { + *(destTemp + back) = *destTemp; + destTemp++; + } + while (--len); + + b &= 3; + mode = b; + if (b == 0) + continue; + if (b > srcRem || b > destRem) + return S_FALSE; + srcRem -= b; + destRem -= b; + *dest++ = *src++; + if (b > 1) + { + *dest++ = *src++; + if (b > 2) + *dest++ = *src++; + } + } +} + +HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize, UInt32 inSize, UInt32 outSizeMax) +{ + if (outBuf) + { + *outBufWasWritten = false; + *outBufWasWrittenSize = 0; + } + UInt32 method = _h.Method; + if (_h.SeveralMethods) + { + Byte b; + RINOK(ReadStream_FALSE(_stream, &b, 1)) + RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)) + method = (b == 0x5D ? kMethod_LZMA : kMethod_ZLIB); + } + + if (method == kMethod_ZLIB && _needCheckLzma) + { + Byte b; + RINOK(ReadStream_FALSE(_stream, &b, 1)) + RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL)) + if (b == 0) + { + _noPropsLZMA = true; + method = _h.Method = kMethod_LZMA; + } + _needCheckLzma = false; + } + + if (method == kMethod_ZLIB) + { + _zlibDecoder.Create_if_Empty(); + RINOK(_zlibDecoder.Interface()->Code(_limitedInStream, outStream, NULL, NULL, NULL)) + if (inSize != _zlibDecoder->GetInputProcessedSize()) + return S_FALSE; + } + /* + else if (method == kMethod_LZMA) + { + _lzmaDecoder.Create_if_Empty(); + // _lzmaDecoder->FinishStream = true; + const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; + Byte props[kPropsSize]; + UInt32 propsSize; + UInt64 outSize; + if (_noPropsLZMA) + { + props[0] = 0x5D; + SetUi32(&props[1], _h.BlockSize); + propsSize = 0; + outSize = outSizeMax; + } + else + { + RINOK(ReadStream_FALSE(_limitedInStream, props, kPropsSize)); + propsSize = kPropsSize; + outSize = GetUi64(&props[LZMA_PROPS_SIZE]); + if (outSize > outSizeMax) + return S_FALSE; + } + RINOK(_lzmaDecoderSpec->SetDecoderProperties2(props, LZMA_PROPS_SIZE)); + RINOK(_lzmaDecoder->Code(_limitedInStream, outStream, NULL, &outSize, NULL)); + if (inSize != propsSize + _lzmaDecoderSpec->GetInputProcessedSize()) + return S_FALSE; + } + */ + else + { + if (_inputBuffer.Size() < inSize) + _inputBuffer.Alloc(inSize); + RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize)) + + Byte *dest = outBuf; + if (!outBuf) + { + dest = _dynOutStream->GetBufPtrForWriting(outSizeMax); + if (!dest) + return E_OUTOFMEMORY; + } + + SizeT destLen = outSizeMax, srcLen = inSize; + + if (method == kMethod_LZO) + { + RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen)) + } + else if (method == kMethod_LZMA) + { + Byte props[5]; + const Byte *src = _inputBuffer; + + if (_noPropsLZMA) + { + props[0] = 0x5D; + SetUi32(&props[1], _h.BlockSize) + } + else + { + const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; + if (inSize < kPropsSize) + return S_FALSE; + memcpy(props, src, LZMA_PROPS_SIZE); + UInt64 outSize = GetUi64(src + LZMA_PROPS_SIZE); + if (outSize > outSizeMax) + return S_FALSE; + destLen = (SizeT)outSize; + src += kPropsSize; + inSize -= kPropsSize; + srcLen = inSize; + } + + ELzmaStatus status; + SRes res = LzmaDecode(dest, &destLen, + src, &srcLen, + props, LZMA_PROPS_SIZE, + LZMA_FINISH_END, + &status, &g_Alloc); + if (res != 0) + return SResToHRESULT(res); + if (status != LZMA_STATUS_FINISHED_WITH_MARK + && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return S_FALSE; + } + else if (method == kMethod_ZSTD) + { + const Byte *src = _inputBuffer; + + if (!_zstd) + { + _zstd = ZstdDec_Create(&g_AlignedAlloc, &g_AlignedAlloc); + if (!_zstd) + return E_OUTOFMEMORY; + } + + CZstdDecState state; + ZstdDecState_Clear(&state); + + state.inBuf = src; + state.inLim = srcLen; // + 1; for debug + // state.outStep = outSizeMax; + + state.outBuf_fromCaller = dest; + state.outBufSize_fromCaller = outSizeMax; + // state.mustBeFinished = True; + + ZstdDec_Init(_zstd); + SRes sres; + for (;;) + { + sres = ZstdDec_Decode(_zstd, &state); + if (sres != SZ_OK) + break; + if (state.inLim == state.inPos + && (state.status == ZSTD_STATUS_NEEDS_MORE_INPUT || + state.status == ZSTD_STATUS_FINISHED_FRAME)) + break; + // sres = sres; + // break; // for debug + } + + CZstdDecResInfo info; + // ZstdDecInfo_Clear(&stat); + // stat->InSize = state.inPos; + ZstdDec_GetResInfo(_zstd, &state, sres, &info); + sres = info.decode_SRes; + if (sres == SZ_OK) + { + if (state.status != ZSTD_STATUS_FINISHED_FRAME + // ||stat.UnexpededEnd + || info.extraSize != 0 + || state.inLim != state.inPos) + sres = SZ_ERROR_DATA; + } + if (sres != SZ_OK) + return SResToHRESULT(sres); + if (state.winPos > outSizeMax) + return E_FAIL; + // memcpy(dest, state.dic, state.dicPos); + destLen = state.winPos; + } + else + { + ECoderStatus status; + const SRes res = XzUnpacker_CodeFull(&_xz, + dest, &destLen, + _inputBuffer, &srcLen, + CODER_FINISH_END, &status); + if (res != 0) + return SResToHRESULT(res); + if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz)) + return S_FALSE; + } + + if (inSize != srcLen) + return S_FALSE; + if (outBuf) + { + *outBufWasWritten = true; + *outBufWasWrittenSize = (UInt32)destLen; + } + else + _dynOutStream->UpdateSize(destLen); + } + return S_OK; +} + +HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize) +{ + Byte temp[3]; + 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 + const bool be = _h.be; + UInt32 size = Get16(temp); + const bool isCompressed = ((size & kNotCompressedBit16) == 0); + if (size != kNotCompressedBit16) + size &= ~kNotCompressedBit16; + + if (size > kMetadataBlockSize || offset + size > packSize) + return S_FALSE; + packSize = offset + size; + if (isCompressed) + { + _limitedInStream->Init(size); + RINOK(Decompress(_dynOutStream, NULL, NULL, NULL, size, kMetadataBlockSize)) + } + else + { + // size != 0 here + Byte *buf = _dynOutStream->GetBufPtrForWriting(size); + if (!buf) + return E_OUTOFMEMORY; + RINOK(ReadStream_FALSE(_stream, buf, size)) + _dynOutStream->UpdateSize(size); + } + return S_OK; +} + + +HRESULT CHandler::ReadMetadataBlock2() +{ + _dynOutStream->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(Seek2(start)) + _dynOutStream->Init(); + UInt32 packPos = 0; + while (packPos != size) + { + data.PackPos.Add(packPos); + data.UnpackPos.Add((UInt32)_dynOutStream->GetSize()); + if (packPos > size) + return S_FALSE; + UInt32 packSize = size - packPos; + RINOK(ReadMetadataBlock(packSize)) + { + const size_t tSize = _dynOutStream->GetSize(); + if (tSize != (UInt32)tSize) + return S_FALSE; + } + packPos += packSize; + } + data.UnpackPos.Add((UInt32)_dynOutStream->GetSize()); + _dynOutStream->CopyToBuffer(data.Data); + return S_OK; +} + +struct CTempItem +{ + UInt32 StartBlock; + // UInt32 iNodeNumber1; + UInt32 Offset; + // UInt16 iNodeNumber2; + UInt16 Type; +}; + +HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex) +{ + if (level > kNumDirLevelsMax) + return S_FALSE; + + int blockIndex = _inodesData.PackPos.FindInSorted(startBlock); + if (blockIndex < 0) + return S_FALSE; + UInt32 unpackPos = _inodesData.UnpackPos[blockIndex] + offset; + if (unpackPos < offset) + return S_FALSE; + + nodeIndex = _nodesPos.FindInSorted(unpackPos, _blockToNode[blockIndex], _blockToNode[blockIndex + 1]); + // nodeIndex = _nodesPos.FindInSorted(unpackPos); + if (nodeIndex < 0) + return S_FALSE; + + const CNode &n = _nodes[nodeIndex]; + if (!n.IsDir()) + return S_OK; + blockIndex = _dirs.PackPos.FindInSorted((UInt32)n.StartBlock); + if (blockIndex < 0) + return S_FALSE; + unpackPos = _dirs.UnpackPos[blockIndex] + n.Offset; + if (unpackPos < n.Offset || unpackPos > _dirs.Data.Size()) + return S_FALSE; + + UInt32 rem = (UInt32)_dirs.Data.Size() - unpackPos; + const Byte *p = _dirs.Data + unpackPos; + UInt32 fileSize = (UInt32)n.FileSize; + + // for some squashfs files: fileSize = rem + 3 !!! + if (_h.Major >= 3) + { + if (fileSize < 3) + return S_FALSE; + fileSize -= 3; + } + if (fileSize > rem) + return S_FALSE; + rem = fileSize; + + AString tempString; + + CRecordVector tempItems; + while (rem != 0) + { + const bool be = _h.be; + UInt32 count; + CTempItem tempItem; + if (_h.Major <= 2) + { + if (rem < 4) + return S_FALSE; + count = p[0]; + tempItem.StartBlock = Get32(p); + if (be) + tempItem.StartBlock &= 0xFFFFFF; + else + tempItem.StartBlock >>= 8; + p += 4; + rem -= 4; + } + else + { + if (_h.Major == 3) + { + if (rem < 9) + return S_FALSE; + count = p[0]; + p += 1; + rem -= 1; + } + else + { + if (rem < 12) + return S_FALSE; + count = GetUi32(p); + p += 4; + rem -= 4; + } + GET_32 (0, tempItem.StartBlock); + // GET_32 (4, tempItem.iNodeNumber1); + p += 8; + rem -= 8; + } + count++; + + for (UInt32 i = 0; i < count; i++) + { + if (rem == 0) + return S_FALSE; + + UInt32 nameOffset = _h.GetFileNameOffset(); + if (rem < nameOffset) + return S_FALSE; + + if (_items.Size() >= kNumFilesMax) + return S_FALSE; + if (_openCallback) + { + UInt64 numFiles = _items.Size(); + if ((numFiles & 0xFFFF) == 0) + { + RINOK(_openCallback->SetCompleted(&numFiles, NULL)) + } + } + + CItem item; + item.Ptr = (UInt32)(p - (const Byte *)_dirs.Data); + + UInt32 size; + if (_h.IsOldVersion()) + { + UInt32 t = Get16(p); + if (be) + { + tempItem.Offset = t >> 3; + tempItem.Type = (UInt16)(t & 0x7); + } + else + { + tempItem.Offset = t & 0x1FFF; + tempItem.Type = (UInt16)(t >> 13); + } + size = (UInt32)p[2]; + /* + if (_h.Major > 2) + tempItem.iNodeNumber2 = Get16(p + 3); + */ + } + else + { + GET_16 (0, tempItem.Offset); + // GET_16 (2, tempItem.iNodeNumber2); + GET_16 (4, tempItem.Type); + GET_16 (6, size); + } + p += nameOffset; + rem -= nameOffset; + size++; + if (rem < size) + return S_FALSE; + + if (_openCodePage == CP_UTF8) + { + tempString.SetFrom_CalcLen((const char *)p, size); + if (!CheckUTF8_AString(tempString)) + _openCodePage = CP_OEMCP; + } + + p += size; + rem -= size; + item.Parent = parent; + _items.Add(item); + tempItems.Add(tempItem); + } + } + + const unsigned startItemIndex = _items.Size() - tempItems.Size(); + FOR_VECTOR (i, tempItems) + { + const CTempItem &tempItem = tempItems[i]; + const unsigned index = startItemIndex + i; + CItem &item = _items[index]; + RINOK(OpenDir((int)index, tempItem.StartBlock, tempItem.Offset, level + 1, item.Node)) + } + + return S_OK; +} + +HRESULT CHandler::ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids) +{ + 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) +{ + { + Byte buf[kHeaderSize3]; + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize3)) + if (!_h.Parse(buf)) + return S_FALSE; + if (!_h.IsSupported()) + return E_NOTIMPL; + + _noPropsLZMA = false; + _needCheckLzma = false; + switch (_h.Method) + { + case kMethod_ZLIB: _needCheckLzma = true; break; + case kMethod_LZMA: + case kMethod_LZO: + case kMethod_XZ: + case kMethod_ZSTD: + break; + default: + return E_NOTIMPL; + } + } + + _stream = inStream; + + if (_h.NumFrags != 0) + { + if (_h.NumFrags > kNumFilesMax) + return S_FALSE; + _frags.ClearAndReserve(_h.NumFrags); + const unsigned bigFrag = (_h.Major > 2); + + 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(Seek2(_h.FragTable)) + RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)) + const bool be = _h.be; + + for (UInt32 i = 0; i < numBlocks; i++) + { + const UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4); + RINOK(Seek2(offset)) + RINOK(ReadMetadataBlock2()) + const UInt32 unpackSize = (UInt32)_dynOutStream->GetSize(); + if (unpackSize != kMetadataBlockSize) + if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1))) + return S_FALSE; + const Byte *buf = _dynOutStream->GetBuffer(); + for (UInt32 j = 0; j < kMetadataBlockSize && j < unpackSize;) + { + CFrag frag; + if (bigFrag) + { + frag.StartBlock = Get64(buf + j); + frag.Size = Get32(buf + j + 8); + // some archives contain nonzero in unused (buf + j + 12) + j += 16; + } + else + { + frag.StartBlock = Get32(buf + j); + frag.Size = Get32(buf + j + 4); + j += 8; + } + _frags.Add(frag); + } + } + if ((UInt32)_frags.Size() != _h.NumFrags) + return S_FALSE; + } + + RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable)) + RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable)) + + UInt64 absOffset = _h.RootInode >> 16; + if (absOffset >= ((UInt64)1 << 32)) + return S_FALSE; + { + UInt32 pos = 0; + UInt32 totalSize = (UInt32)_inodesData.Data.Size(); + const unsigned kMinNodeParseSize = 4; + if (_h.NumInodes > totalSize / kMinNodeParseSize) + return S_FALSE; + _nodesPos.ClearAndReserve(_h.NumInodes); + _nodes.ClearAndReserve(_h.NumInodes); + // we use _blockToNode for binary search seed optimizations + _blockToNode.ClearAndReserve(_inodesData.GetNumBlocks() + 1); + unsigned curBlock = 0; + for (UInt32 i = 0; i < _h.NumInodes; i++) + { + CNode n; + const Byte *p = _inodesData.Data + pos; + UInt32 size = totalSize - pos; + + switch (_h.Major) + { + case 1: size = n.Parse1(p, size, _h); break; + case 2: size = n.Parse2(p, size, _h); break; + case 3: size = n.Parse3(p, size, _h); break; + default: size = n.Parse4(p, size, _h); break; + } + if (size == 0) + return S_FALSE; + while (pos >= _inodesData.UnpackPos[curBlock]) + { + _blockToNode.Add(_nodesPos.Size()); + curBlock++; + } + _nodesPos.AddInReserved(pos); + _nodes.AddInReserved(n); + pos += size; + } + _blockToNode.Add(_nodesPos.Size()); + if (pos != totalSize) + return S_FALSE; + } + int rootNodeIndex; + RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex)) + + if (_h.Major < 4) + { + RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids)) + RINOK(ReadUids(_h.GidTable, _h.NumGids, _gids)) + } + else + { + const UInt32 size = (UInt32)_h.NumIDs * 4; + _uids.Alloc(size); + + const UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize; + const UInt32 numBlocksBytes = numBlocks << 3; + CByteBuffer data(numBlocksBytes); + RINOK(Seek2(_h.UidTable)) + RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes)) + + for (UInt32 i = 0; i < numBlocks; i++) + { + const UInt64 offset = GetUi64(data + i * 8); + RINOK(Seek2(offset)) + // RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize)); + RINOK(ReadMetadataBlock2()) + const size_t unpackSize = _dynOutStream->GetSize(); + const UInt32 remSize = (i == numBlocks - 1) ? + (size & (kMetadataBlockSize - 1)) : kMetadataBlockSize; + if (unpackSize != remSize) + return S_FALSE; + memcpy(_uids + kMetadataBlockSize * i, _dynOutStream->GetBuffer(), remSize); + } + } + + { + const UInt32 alignSize = 1 << 12; + Byte buf[alignSize]; + RINOK(Seek2(_h.Size)) + UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1); + _sizeCalculated = _h.Size; + if (rem != 0) + { + if (ReadStream_FALSE(_stream, buf, rem) == S_OK) + { + size_t i; + for (i = 0; i < rem && buf[i] == 0; i++); + if (i == rem) + _sizeCalculated = _h.Size + rem; + } + } + } + return S_OK; +} + +AString CHandler::GetPath(unsigned index) const +{ + unsigned len = 0; + const unsigned indexMem = index; + const bool be = _h.be; + for (;;) + { + const CItem &item = _items[index]; + const Byte *p = _dirs.Data + item.Ptr; + const unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; + p += _h.GetFileNameOffset(); + unsigned i; + for (i = 0; i < size && p[i]; i++); + len += i + 1; + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; + } + len--; + + AString path; + char *dest = path.GetBuf_SetEnd(len) + len; + index = indexMem; + for (;;) + { + const CItem &item = _items[index]; + const Byte *p = _dirs.Data + item.Ptr; + const unsigned size = (_h.IsOldVersion() ? (unsigned)p[2] : (unsigned)Get16(p + 6)) + 1; + p += _h.GetFileNameOffset(); + unsigned i; + for (i = 0; i < size && p[i]; i++); + dest -= i; + memcpy(dest, p, i); + index = (unsigned)item.Parent; + if (item.Parent < 0) + break; + *(--dest) = CHAR_PATH_SEPARATOR; + } + return path; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + _limitedInStream->SetStream(stream); + HRESULT res; + try + { + _openCallback = callback; + res = Open2(stream); + } + catch(...) + { + Close(); + throw; + } + if (res != S_OK) + { + Close(); + return res; + } + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _openCodePage = CP_UTF8; + _sizeCalculated = 0; + + _limitedInStream->ReleaseStream(); + _stream.Release(); + + _items.Clear(); + _nodes.Clear(); + _nodesPos.Clear(); + _blockToNode.Clear(); + _frags.Clear(); + _inodesData.Clear(); + _dirs.Clear(); + + _uids.Free(); + _gids.Free(); + + _cachedBlock.Free(); + ClearCache(); + + return S_OK; +} + +bool CHandler::GetPackSize(unsigned index, UInt64 &totalPack, bool fillOffsets) +{ + totalPack = 0; + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + const UInt32 ptr = _nodesPos[item.Node]; + const Byte *p = _inodesData.Data + ptr; + const bool be = _h.be; + + const UInt32 type = node.Type; + UInt32 offset; + if (node.IsLink() || node.FileSize == 0) + { + totalPack = node.FileSize; + return true; + } + + const UInt32 numBlocks = (UInt32)node.GetNumBlocks(_h); + + if (fillOffsets) + { + _blockOffsets.Clear(); + _blockCompressed.Clear(); + _blockOffsets.Add(totalPack); + } + + if (_h.Major <= 1) + { + offset = 15; + p += offset; + + for (UInt32 i = 0; i < numBlocks; i++) + { + UInt32 t = Get16(p + i * 2); + if (fillOffsets) + _blockCompressed.Add((t & kNotCompressedBit16) == 0); + if (t != kNotCompressedBit16) + t &= ~kNotCompressedBit16; + totalPack += t; + if (fillOffsets) + _blockOffsets.Add(totalPack); + } + } + else + { + if (_h.Major <= 2) + offset = 24; + else if (type == kType_FILE) + offset = 32; + else if (type == kType_FILE + 7) + offset = (_h.Major <= 3 ? 40 : 56); + else + return false; + + p += offset; + + for (UInt64 i = 0; i < numBlocks; i++) + { + UInt32 t = Get32(p + i * 4); + if (fillOffsets) + _blockCompressed.Add(IS_COMPRESSED_BLOCK(t)); + UInt32 size = GET_COMPRESSED_BLOCK_SIZE(t); + if (size > _h.BlockSize) + return false; + totalPack += size; + if (fillOffsets) + _blockOffsets.Add(totalPack); + } + + if (node.ThereAreFrags()) + { + if (node.Frag >= (UInt32)_frags.Size()) + return false; + const CFrag &frag = _frags[node.Frag]; + if (node.Offset == 0) + { + UInt32 size = GET_COMPRESSED_BLOCK_SIZE(frag.Size); + if (size > _h.BlockSize) + return false; + totalPack += size; + } + } + } + return true; +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidMethod: + { + char sz[16]; + const char *s; + if (_noPropsLZMA) + s = "LZMA Spec"; + else if (_h.SeveralMethods) + s = "LZMA ZLIB"; + else + { + s = NULL; + if (_h.Method < Z7_ARRAY_SIZE(k_Methods)) + s = k_Methods[_h.Method]; + if (!s) + { + ConvertUInt32ToString(_h.Method, sz); + s = sz; + } + } + prop = s; + break; + } + case kpidFileSystem: + { + AString res ("SquashFS"); + if (_h.SeveralMethods) + res += "-LZMA"; + res.Add_Space(); + res.Add_UInt32(_h.Major); + res.Add_Dot(); + res.Add_UInt32(_h.Minor); + prop = res; + break; + } + case kpidClusterSize: prop = _h.BlockSize; break; + case kpidBigEndian: prop = _h.be; break; + case kpidCTime: + if (_h.CTime != 0) + PropVariant_SetFrom_UnixTime(prop, _h.CTime); + break; + case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break; + // case kpidNumBlocks: prop = _h.NumFrags; break; + case kpidPhySize: prop = _sizeCalculated; break; + case kpidHeadersSize: + if (_sizeCalculated >= _h.InodeTable) + prop = _sizeCalculated - _h.InodeTable; + break; + + case kpidCodePage: + { + char sz[16]; + const char *name = NULL; + switch (_openCodePage) + { + case CP_OEMCP: name = "OEM"; break; + case CP_UTF8: name = "UTF-8"; break; + } + if (!name) + { + ConvertUInt32ToString(_openCodePage, sz); + name = sz; + } + prop = name; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + const bool isDir = node.IsDir(); + const bool be = _h.be; + + switch (propID) + { + case kpidPath: + { + AString path (GetPath(index)); + UString s; + if (_openCodePage == CP_UTF8) + ConvertUTF8ToUnicode(path, s); + else + MultiByteToUnicodeString2(s, path, _openCodePage); + prop = s; + break; + } + case kpidIsDir: prop = isDir; break; + // case kpidOffset: if (!node.IsLink()) prop = (UInt64)node.StartBlock; break; + case kpidSize: if (!isDir) prop = node.GetSize(); break; + case kpidPackSize: + if (!isDir) + { + UInt64 size; + if (GetPackSize(index, size, false)) + prop = size; + } + break; + case kpidMTime: + { + UInt32 offset = 0; + switch (_h.Major) + { + case 1: + if (node.Type == kType_FILE) + offset = 3; + else if (node.Type == kType_DIR) + offset = 7; + break; + case 2: + if (node.Type == kType_FILE) + offset = 4; + else if (node.Type == kType_DIR) + offset = 8; + else if (node.Type == kType_DIR + 7) + offset = 9; + break; + case 3: offset = 4; break; + case 4: offset = 8; break; + } + if (offset != 0) + { + const Byte *p = _inodesData.Data + _nodesPos[item.Node] + offset; + PropVariant_SetFrom_UnixTime(prop, Get32(p)); + } + break; + } + case kpidPosixAttrib: + { + if (node.Type != 0 && node.Type < Z7_ARRAY_SIZE(k_TypeToMode)) + prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; + break; + } + case kpidUserId: + case kpidGroupId: + { + UInt32 id = node.Uid; + const CByteBuffer *ids = &_uids; + if (propID == kpidGroupId) + { + id = node.Gid; + if (_h.Major < 4) + { + if (id == _h.GetSpecGuidIndex()) + id = node.Uid; + else + ids = &_gids; + } + } + const UInt32 offset = (UInt32)id * 4; + if (offset < ids->Size()) + prop = (UInt32)Get32(*ids + offset); + break; + } + /* + case kpidLinks: + if (_h.Major >= 3 && node.Type != kType_FILE) + prop = node.NumLinks; + break; + */ + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CSquashfsInStream: public CCachedInStream +{ + HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) Z7_override; +public: + CHandler *Handler; +}; + +HRESULT CSquashfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) +{ + return Handler->ReadBlock(blockIndex, dest, blockSize); +} + +HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) +{ + const CNode &node = _nodes[_nodeIndex]; + UInt64 blockOffset; + UInt32 packBlockSize; + UInt32 offsetInBlock = 0; + bool compressed; + if (blockIndex < _blockCompressed.Size()) + { + compressed = _blockCompressed[(unsigned)blockIndex]; + blockOffset = _blockOffsets[(unsigned)blockIndex]; + packBlockSize = (UInt32)(_blockOffsets[(unsigned)blockIndex + 1] - blockOffset); + blockOffset += node.StartBlock; + } + else + { + if (!node.ThereAreFrags()) + return S_FALSE; + const CFrag &frag = _frags[node.Frag]; + offsetInBlock = node.Offset; + blockOffset = frag.StartBlock; + packBlockSize = GET_COMPRESSED_BLOCK_SIZE(frag.Size); + compressed = IS_COMPRESSED_BLOCK(frag.Size); + } + + if (packBlockSize == 0) + { + // sparse file ??? + memset(dest, 0, blockSize); + return S_OK; + } + + if (blockOffset != _cachedBlockStartPos || + packBlockSize != _cachedPackBlockSize) + { + ClearCache(); + RINOK(Seek2(blockOffset)) + _limitedInStream->Init(packBlockSize); + + if (compressed) + { + _outStream->Init((Byte *)_cachedBlock, _h.BlockSize); + bool outBufWasWritten; + UInt32 outBufWasWrittenSize; + HRESULT res = Decompress(_outStream, _cachedBlock, &outBufWasWritten, &outBufWasWrittenSize, packBlockSize, _h.BlockSize); + RINOK(res) + if (outBufWasWritten) + _cachedUnpackBlockSize = outBufWasWrittenSize; + else + _cachedUnpackBlockSize = (UInt32)_outStream->GetPos(); + } + else + { + if (packBlockSize > _h.BlockSize) + return S_FALSE; + RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize)) + _cachedUnpackBlockSize = packBlockSize; + } + _cachedBlockStartPos = blockOffset; + _cachedPackBlockSize = packBlockSize; + } + if (offsetInBlock + blockSize > _cachedUnpackBlockSize) + return S_FALSE; + if (blockSize != 0) + memcpy(dest, _cachedBlock + offsetInBlock, blockSize); + return S_OK; +} + +Z7_COM7F_IMF(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 CItem &item = _items[allFilesMode ? i : indices[i]]; + const CNode &node = _nodes[item.Node]; + totalSize += node.GetSize(); + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + + for (i = 0;; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + int res; + { + CMyComPtr outStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + // const Byte *p = _data + item.Offset; + + if (node.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + const UInt64 unpackSize = node.GetSize(); + totalSize += unpackSize; + UInt64 packSize; + if (GetPackSize(index, packSize, false)) + totalPackSize += packSize; + + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + res = NExtract::NOperationResult::kDataError; + { + CMyComPtr inSeqStream; + HRESULT hres = GetStream(index, &inSeqStream); + if (hres == S_FALSE || !inSeqStream) + { + if (hres == E_OUTOFMEMORY) + return hres; + res = NExtract::NOperationResult::kUnsupportedMethod; + } + else + { + RINOK(hres) + { + hres = copyCoder.Interface()->Code(inSeqStream, outStream, NULL, NULL, lps); + if (hres == S_OK) + { + if (copyCoder->TotalSize == unpackSize) + res = NExtract::NOperationResult::kOK; + } + else if (hres == E_NOTIMPL) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + } + else if (hres != S_FALSE) + { + RINOK(hres) + } + } + } + } + } + RINOK(extractCallback->SetOperationResult(res)) + } + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + + if (node.IsDir()) + return E_FAIL; + + const Byte *p = _inodesData.Data + _nodesPos[item.Node]; + + if (node.FileSize == 0 || node.IsLink()) + { + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr streamTemp = streamSpec; + if (node.IsLink()) + streamSpec->Init(p + _h.GetSymLinkOffset(), (size_t)node.FileSize); + else + streamSpec->Init(NULL, 0); + *stream = streamTemp.Detach(); + return S_OK; + } + + UInt64 packSize; + if (!GetPackSize(index, packSize, true)) + return S_FALSE; + + _nodeIndex = item.Node; + + size_t cacheSize = _h.BlockSize; + if (_cachedBlock.Size() != cacheSize) + { + ClearCache(); + _cachedBlock.Alloc(cacheSize); + } + + CSquashfsInStream *streamSpec = new CSquashfsInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Handler = this; + unsigned cacheSizeLog = 22; + if (cacheSizeLog <= _h.BlockSizeLog) + cacheSizeLog = _h.BlockSizeLog + 1; + if (!streamSpec->Alloc(_h.BlockSizeLog, cacheSizeLog - _h.BlockSizeLog)) + return E_OUTOFMEMORY; + streamSpec->Init(node.FileSize); + *stream = streamTemp.Detach(); + + return S_OK; + + COM_TRY_END +} + +static const Byte k_Signature[] = { + 4, 'h', 's', 'q', 's', + 4, 's', 'q', 's', 'h', + 4, 's', 'h', 's', 'q', + 4, 'q', 's', 'h', 's' }; + +REGISTER_ARC_I( + "SquashFS", "squashfs", NULL, 0xD2, + k_Signature, + 0, + NArcInfoFlags::kMultiSignature, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/SwfHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SwfHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/SwfHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/SwfHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -1,985 +1,994 @@ -// SwfHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/InBuffer.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 "../Compress/LzmaDecoder.h" -#include "../Compress/LzmaEncoder.h" -#include "../Compress/ZlibDecoder.h" -#include "../Compress/ZlibEncoder.h" - -#include "Common/DummyOutStream.h" -#include "Common/HandlerOut.h" - -using namespace NWindows; - -namespace NArchive { - -static const UInt32 kFileSizeMax = (UInt32)1 << 29; - -namespace NSwfc { - -static const unsigned kHeaderBaseSize = 8; -static const unsigned kHeaderLzmaSize = 17; - -static const Byte SWF_UNCOMPRESSED = 'F'; -static const Byte SWF_COMPRESSED_ZLIB = 'C'; -static const Byte SWF_COMPRESSED_LZMA = 'Z'; - -static const Byte SWF_MIN_COMPRESSED_ZLIB_VER = 6; -static const Byte SWF_MIN_COMPRESSED_LZMA_VER = 13; - -static const Byte kVerLim = 20; - -API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size) -{ - if (size < kHeaderBaseSize) - return k_IsArc_Res_NEED_MORE; - if (p[0] != SWF_UNCOMPRESSED || - p[1] != 'W' || - p[2] != 'S' || - p[3] >= kVerLim) - return k_IsArc_Res_NO; - UInt32 uncompressedSize = GetUi32(p + 4); - if (uncompressedSize > kFileSizeMax) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -API_FUNC_static_IsArc IsArc_Swfc(const Byte *p, size_t size) -{ - if (size < kHeaderBaseSize + 2 + 1) // 2 + 1 (for zlib check) - return k_IsArc_Res_NEED_MORE; - if ((p[0] != SWF_COMPRESSED_ZLIB && - p[0] != SWF_COMPRESSED_LZMA) || - p[1] != 'W' || - p[2] != 'S' || - p[3] >= kVerLim) - return k_IsArc_Res_NO; - UInt32 uncompressedSize = GetUi32(p + 4); - if (uncompressedSize > kFileSizeMax) - return k_IsArc_Res_NO; - - if (p[0] == SWF_COMPRESSED_ZLIB) - { - if (!NCompress::NZlib::IsZlib_3bytes(p + 8)) - return k_IsArc_Res_NO; - } - else - { - if (size < kHeaderLzmaSize + 2) - return k_IsArc_Res_NEED_MORE; - if (p[kHeaderLzmaSize] != 0 || - (p[kHeaderLzmaSize + 1] & 0x80) != 0) - return k_IsArc_Res_NO; - UInt32 lzmaPackSize = GetUi32(p + 8); - UInt32 lzmaProp = p[12]; - UInt32 lzmaDicSize = GetUi32(p + 13); - if (lzmaProp > 5 * 5 * 9 || - lzmaDicSize > ((UInt32)1 << 28) || - lzmaPackSize < 5 || - lzmaPackSize > ((UInt32)1 << 28)) - return k_IsArc_Res_NO; - } - - return k_IsArc_Res_YES; -} -} - -struct CItem -{ - Byte Buf[kHeaderLzmaSize]; - unsigned HeaderSize; - - UInt32 GetSize() const { return GetUi32(Buf + 4); } - UInt32 GetLzmaPackSize() const { return GetUi32(Buf + 8); } - UInt32 GetLzmaDicSize() const { return GetUi32(Buf + 13); } - - bool IsSwf() const { return (Buf[1] == 'W' && Buf[2] == 'S' && Buf[3] < kVerLim); } - bool IsUncompressed() const { return Buf[0] == SWF_UNCOMPRESSED; } - bool IsZlib() const { return Buf[0] == SWF_COMPRESSED_ZLIB; } - bool IsLzma() const { return Buf[0] == SWF_COMPRESSED_LZMA; } - - void MakeUncompressed() - { - Buf[0] = SWF_UNCOMPRESSED; - HeaderSize = kHeaderBaseSize; - } - void MakeZlib() - { - Buf[0] = SWF_COMPRESSED_ZLIB; - if (Buf[3] < SWF_MIN_COMPRESSED_ZLIB_VER) - Buf[3] = SWF_MIN_COMPRESSED_ZLIB_VER; - } - void MakeLzma(UInt32 packSize) - { - Buf[0] = SWF_COMPRESSED_LZMA; - if (Buf[3] < SWF_MIN_COMPRESSED_LZMA_VER) - Buf[3] = SWF_MIN_COMPRESSED_LZMA_VER; - SetUi32(Buf + 8, packSize); - HeaderSize = kHeaderLzmaSize; - } - - HRESULT ReadHeader(ISequentialInStream *stream) - { - HeaderSize = kHeaderBaseSize; - return ReadStream_FALSE(stream, Buf, kHeaderBaseSize); - } - HRESULT WriteHeader(ISequentialOutStream *stream) - { - return WriteStream(stream, Buf, HeaderSize); - } -}; - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IOutArchive, - public ISetProperties, - public CMyUnknownImp -{ - CItem _item; - UInt64 _packSize; - bool _packSizeDefined; - CMyComPtr _seqStream; - CMyComPtr _stream; - - CSingleMethodProps _props; - bool _lzmaMode; - -public: - CHandler(): _lzmaMode(false) {} - MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); -}; - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize, - kpidMethod -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_packSizeDefined) prop = _item.HeaderSize + _packSize; break; - case kpidIsNotArcType: prop = true; break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -static void DicSizeToString(char *s, UInt32 val) -{ - char c = 0; - unsigned i; - for (i = 0; i <= 31; i++) - if (((UInt32)1 << i) == val) - { - val = i; - break; - } - if (i == 32) - { - c = 'b'; - if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } - else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } - } - ::ConvertUInt32ToString(val, s); - unsigned pos = MyStringLen(s); - s[pos++] = c; - s[pos] = 0; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidSize: prop = (UInt64)_item.GetSize(); break; - case kpidPackSize: if (_packSizeDefined) prop = _item.HeaderSize + _packSize; break; - case kpidMethod: - { - char s[32]; - if (_item.IsZlib()) - MyStringCopy(s, "zlib"); - else - { - MyStringCopy(s, "LZMA:"); - DicSizeToString(s + 5, _item.GetLzmaDicSize()); - } - prop = s; - break; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *) -{ - RINOK(OpenSeq(stream)); - _stream = stream; - return S_OK; -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - Close(); - RINOK(_item.ReadHeader(stream)); - if (!_item.IsSwf()) - return S_FALSE; - if (_item.IsLzma()) - { - RINOK(ReadStream_FALSE(stream, _item.Buf + kHeaderBaseSize, kHeaderLzmaSize - kHeaderBaseSize)); - _item.HeaderSize = kHeaderLzmaSize; - _packSize = _item.GetLzmaPackSize(); - _packSizeDefined = true; - } - else if (!_item.IsZlib()) - return S_FALSE; - if (_item.GetSize() < _item.HeaderSize) - return S_FALSE; - _seqStream = stream; - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _packSize = 0; - _packSizeDefined = false; - _seqStream.Release(); - _stream.Release(); - return S_OK; -} - -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr Callback; -public: - UInt64 Offset; - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - void Init(IArchiveOpenCallback *callback) { Callback = callback; } -}; - -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) -{ - if (Callback) - { - UInt64 files = 0; - UInt64 value = Offset + *inSize; - return Callback->SetCompleted(&files, &value); - } - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - extractCallback->SetTotal(_item.GetSize()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - lps->InSize = _item.HeaderSize; - lps->OutSize = outStreamSpec->GetSize(); - RINOK(lps->SetCur()); - - CItem item = _item; - item.MakeUncompressed(); - if (_stream) - RINOK(_stream->Seek(_item.HeaderSize, STREAM_SEEK_SET, NULL)); - NCompress::NZlib::CDecoder *_decoderZlibSpec = NULL; - NCompress::NLzma::CDecoder *_decoderLzmaSpec = NULL; - CMyComPtr _decoder; - - CMyComPtr inStream2; - - UInt64 unpackSize = _item.GetSize() - (UInt32)8; - if (_item.IsZlib()) - { - _decoderZlibSpec = new NCompress::NZlib::CDecoder; - _decoder = _decoderZlibSpec; - inStream2 = _seqStream; - } - else - { - /* Some .swf files with lzma contain additional 8 bytes at the end - in uncompressed stream. - What does that data mean ??? - We don't decompress these additional 8 bytes */ - - // unpackSize = _item.GetSize(); - // SetUi32(item.Buf + 4, (UInt32)(unpackSize + 8)); - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; - inStream2 = limitedStreamSpec; - limitedStreamSpec->SetStream(_seqStream); - limitedStreamSpec->Init(_item.GetLzmaPackSize()); - - _decoderLzmaSpec = new NCompress::NLzma::CDecoder; - _decoder = _decoderLzmaSpec; - // _decoderLzmaSpec->FinishStream = true; - - Byte props[5]; - memcpy(props, _item.Buf + 12, 5); - UInt32 dicSize = _item.GetLzmaDicSize(); - if (dicSize > (UInt32)unpackSize) - { - dicSize = (UInt32)unpackSize; - SetUi32(props + 1, dicSize); - } - RINOK(_decoderLzmaSpec->SetDecoderProperties2(props, 5)); - } - RINOK(item.WriteHeader(outStream)); - HRESULT result = _decoder->Code(inStream2, outStream, NULL, &unpackSize, progress); - Int32 opRes = NExtract::NOperationResult::kDataError; - if (result == S_OK) - { - if (item.GetSize() == outStreamSpec->GetSize()) - { - if (_item.IsZlib()) - { - _packSizeDefined = true; - _packSize = _decoderZlibSpec->GetInputProcessedSize(); - opRes = NExtract::NOperationResult::kOK; - } - else - { - // if (_decoderLzmaSpec->GetInputProcessedSize() == _packSize) - opRes = NExtract::NOperationResult::kOK; - } - } - } - else if (result != S_FALSE) - return result; - - outStream.Release(); - return extractCallback->SetOperationResult(opRes); - COM_TRY_END -} - -static HRESULT UpdateArchive(ISequentialOutStream *outStream, UInt64 size, - bool lzmaMode, const CSingleMethodProps &props, - IArchiveUpdateCallback *updateCallback) -{ - UInt64 complexity = 0; - RINOK(updateCallback->SetTotal(size)); - RINOK(updateCallback->SetCompleted(&complexity)); - - CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); - - /* - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - */ - - CItem item; - HRESULT res = item.ReadHeader(fileInStream); - if (res == S_FALSE) - return E_INVALIDARG; - RINOK(res); - if (!item.IsSwf() || !item.IsUncompressed() || size != item.GetSize()) - return E_INVALIDARG; - - NCompress::NZlib::CEncoder *encoderZlibSpec = NULL; - NCompress::NLzma::CEncoder *encoderLzmaSpec = NULL; - CMyComPtr encoder; - CMyComPtr outSeekStream; - if (lzmaMode) - { - outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream); - if (!outSeekStream) - return E_NOTIMPL; - encoderLzmaSpec = new NCompress::NLzma::CEncoder; - encoder = encoderLzmaSpec; - RINOK(props.SetCoderProps(encoderLzmaSpec, &size)); - item.MakeLzma((UInt32)0xFFFFFFFF); - CBufPtrSeqOutStream *propStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr propStream = propStreamSpec; - propStreamSpec->Init(item.Buf + 12, 5); - RINOK(encoderLzmaSpec->WriteCoderProperties(propStream)); - } - else - { - encoderZlibSpec = new NCompress::NZlib::CEncoder; - encoder = encoderZlibSpec; - encoderZlibSpec->Create(); - RINOK(props.SetCoderProps(encoderZlibSpec->DeflateEncoderSpec, NULL)); - item.MakeZlib(); - } - RINOK(item.WriteHeader(outStream)); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress)); - UInt64 inputProcessed; - if (lzmaMode) - { - UInt64 curPos = 0; - RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &curPos)); - UInt64 packSize = curPos - kHeaderLzmaSize; - if (packSize > (UInt32)0xFFFFFFFF) - return E_INVALIDARG; - item.MakeLzma((UInt32)packSize); - RINOK(outSeekStream->Seek(0, STREAM_SEEK_SET, NULL)); - item.WriteHeader(outStream); - inputProcessed = encoderLzmaSpec->GetInputProcessedSize(); - } - else - { - inputProcessed = encoderZlibSpec->GetInputProcessedSize(); - } - if (inputProcessed + kHeaderBaseSize != size) - return E_INVALIDARG; - return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK); -} - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) -{ - *timeType = NFileTimeType::kUnix; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - if (numItems != 1) - return E_INVALIDARG; - - Int32 newData, newProps; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); - - if (IntToBool(newProps)) - { - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); - if (prop.vt == VT_BOOL) - { - if (prop.boolVal != VARIANT_FALSE) - return E_INVALIDARG; - } - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - } - - if (IntToBool(newData)) - { - UInt64 size; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - } - return UpdateArchive(outStream, size, _lzmaMode, _props, updateCallback); - } - - if (indexInArchive != 0) - return E_INVALIDARG; - - if (!_seqStream) - return E_NOTIMPL; - - if (_stream) - { - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - else - _item.WriteHeader(outStream); - return NCompress::CopyStream(_seqStream, outStream, NULL); -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - _lzmaMode = false; - RINOK(_props.SetProperties(names, values, numProps)); - AString m = _props.MethodName; - m.MakeLower_Ascii(); - if (m.IsEqualTo("lzma")) - { - return E_NOTIMPL; - // _lzmaMode = true; - } - else if (m.IsEqualTo("deflate") || m.IsEmpty()) - _lzmaMode = false; - else - return E_INVALIDARG; - return S_OK; -} - -static const Byte k_Signature[] = { - 3, 'C', 'W', 'S', - 3, 'Z', 'W', 'S' }; - -REGISTER_ARC_IO( - "SWFc", "swf", "~.swf", 0xD8, - k_Signature, - 0, - NArcInfoFlags::kMultiSignature, - IsArc_Swfc) - -} - -namespace NSwf { - -static const unsigned kNumTagsMax = 1 << 23; - -struct CTag -{ - UInt32 Type; - CByteBuffer Buf; -}; - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public CMyUnknownImp -{ - CObjectVector _tags; - NSwfc::CItem _item; - UInt64 _phySize; - - HRESULT OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback); - HRESULT OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback); -public: - MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq) - INTERFACE_IInArchive(;) - - STDMETHOD(OpenSeq)(ISequentialInStream *stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidComment, -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _phySize; break; - case kpidIsNotArcType: prop = true; break; - } - prop.Detach(value); - return S_OK; -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _tags.Size(); - return S_OK; -} - -static const char *g_TagDesc[92] = -{ - "End" - , "ShowFrame" - , "DefineShape" - , NULL - , "PlaceObject" - , "RemoveObject" - , "DefineBits" - , "DefineButton" - , "JPEGTables" - , "SetBackgroundColor" - , "DefineFont" - , "DefineText" - , "DoAction" - , "DefineFontInfo" - , "DefineSound" - , "StartSound" - , NULL - , "DefineButtonSound" - , "SoundStreamHead" - , "SoundStreamBlock" - , "DefineBitsLossless" - , "DefineBitsJPEG2" - , "DefineShape2" - , "DefineButtonCxform" - , "Protect" - , NULL - , "PlaceObject2" - , NULL - , "RemoveObject2" - , NULL - , NULL - , NULL - , "DefineShape3" - , "DefineText2" - , "DefineButton2" - , "DefineBitsJPEG3" - , "DefineBitsLossless2" - , "DefineEditText" - , NULL - , "DefineSprite" - , NULL - , "41" - , NULL - , "FrameLabel" - , NULL - , "SoundStreamHead2" - , "DefineMorphShape" - , NULL - , "DefineFont2" - , NULL - , NULL - , NULL - , NULL - , NULL - , NULL - , NULL - , "ExportAssets" - , "ImportAssets" - , "EnableDebugger" - , "DoInitAction" - , "DefineVideoStream" - , "VideoFrame" - , "DefineFontInfo2" - , NULL - , "EnableDebugger2" - , "ScriptLimits" - , "SetTabIndex" - , NULL - , NULL - , "FileAttributes" - , "PlaceObject3" - , "ImportAssets2" - , NULL - , "DefineFontAlignZones" - , "CSMTextSettings" - , "DefineFont3" - , "SymbolClass" - , "Metadata" - , "DefineScalingGrid" - , NULL - , NULL - , NULL - , "DoABC" - , "DefineShape4" - , "DefineMorphShape2" - , NULL - , "DefineSceneAndFrameLabelData" - , "DefineBinaryData" - , "DefineFontName" - , "StartSound2" - , "DefineBitsJPEG4" - , "DefineFont4" -}; - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - const CTag &tag = _tags[index]; - switch (propID) - { - case kpidPath: - { - char s[32]; - ConvertUInt32ToString(index, s); - size_t i = strlen(s); - s[i++] = '.'; - ConvertUInt32ToString(tag.Type, s + i); - prop = s; - break; - } - case kpidSize: - case kpidPackSize: - prop = (UInt64)tag.Buf.Size(); break; - case kpidComment: - if (tag.Type < ARRAY_SIZE(g_TagDesc)) - { - const char *s = g_TagDesc[tag.Type]; - if (s != NULL) - prop = s; - } - break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - return OpenSeq2(stream, callback); -} - -static UInt16 Read16(CInBuffer &stream) -{ - UInt16 res = 0; - for (int i = 0; i < 2; i++) - { - Byte b; - if (!stream.ReadByte(b)) - throw 1; - res |= (UInt16)b << (i * 8); - } - return res; -} - -static UInt32 Read32(CInBuffer &stream) -{ - UInt32 res = 0; - for (int i = 0; i < 4; i++) - { - Byte b; - if (!stream.ReadByte(b)) - throw 1; - res |= (UInt32)b << (i * 8); - } - return res; -} - -struct CBitReader -{ - CInBuffer *stream; - unsigned NumBits; - Byte Val; - - CBitReader(): NumBits(0), Val(0) {} - - UInt32 ReadBits(unsigned numBits); -}; - -UInt32 CBitReader::ReadBits(unsigned numBits) -{ - UInt32 res = 0; - while (numBits > 0) - { - if (NumBits == 0) - { - Val = stream->ReadByte(); - NumBits = 8; - } - if (numBits <= NumBits) - { - res <<= numBits; - NumBits -= numBits; - res |= (Val >> NumBits); - Val &= (1 << NumBits) - 1; - break; - } - else - { - res <<= NumBits; - res |= Val; - numBits -= NumBits; - NumBits = 0; - } - } - return res; -} - -HRESULT CHandler::OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback) -{ - RINOK(_item.ReadHeader(stream)) - if (!_item.IsSwf() || !_item.IsUncompressed()) - return S_FALSE; - UInt32 uncompressedSize = _item.GetSize(); - if (uncompressedSize > kFileSizeMax) - return S_FALSE; - - - CInBuffer s; - if (!s.Create(1 << 20)) - return E_OUTOFMEMORY; - s.SetStream(stream); - s.Init(); - { - CBitReader br; - br.stream = &s; - unsigned numBits = br.ReadBits(5); - /* UInt32 xMin = */ br.ReadBits(numBits); - /* UInt32 xMax = */ br.ReadBits(numBits); - /* UInt32 yMin = */ br.ReadBits(numBits); - /* UInt32 yMax = */ br.ReadBits(numBits); - } - /* UInt32 frameDelay = */ Read16(s); - /* UInt32 numFrames = */ Read16(s); - - _tags.Clear(); - UInt64 offsetPrev = 0; - for (;;) - { - UInt32 pair = Read16(s); - UInt32 type = pair >> 6; - UInt32 length = pair & 0x3F; - if (length == 0x3F) - length = Read32(s); - if (type == 0) - break; - UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderBaseSize + length; - if (offset > uncompressedSize || _tags.Size() >= kNumTagsMax) - return S_FALSE; - CTag &tag = _tags.AddNew(); - tag.Type = type; - tag.Buf.Alloc(length); - if (s.ReadBytes(tag.Buf, length) != length) - return S_FALSE; - if (callback && offset >= offsetPrev + (1 << 20)) - { - UInt64 numItems = _tags.Size(); - RINOK(callback->SetCompleted(&numItems, &offset)); - offsetPrev = offset; - } - } - _phySize = s.GetProcessedSize() + NSwfc::kHeaderBaseSize; - if (_phySize != uncompressedSize) - { - // do we need to support files extracted from SFW-LZMA with additional 8 bytes? - return S_FALSE; - } - return S_OK; -} - -HRESULT CHandler::OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback) -{ - HRESULT res; - try { res = OpenSeq3(stream, callback); } - catch(...) { res = S_FALSE; } - return res; -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - return OpenSeq2(stream, NULL); -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _tags.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _tags[allFilesMode ? i : indices[i]].Buf.Size(); - extractCallback->SetTotal(totalSize); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - totalSize = 0; - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = totalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CByteBuffer &buf = _tags[index].Buf; - totalSize += buf.Size(); - - CMyComPtr outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - if (outStream) - RINOK(WriteStream(outStream, buf, buf.Size())); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - return S_OK; - COM_TRY_END -} - -static const Byte k_Signature[] = { 'F', 'W', 'S' }; - -REGISTER_ARC_I( - "SWF", "swf", 0, 0xD7, - k_Signature, - 0, - NArcInfoFlags::kKeepName, - NSwfc::IsArc_Swf) - -}} +// SwfHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/MyString.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" + +#include "../Common/InBuffer.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 "../Compress/LzmaDecoder.h" +#include "../Compress/ZlibDecoder.h" + +#include "Common/DummyOutStream.h" + +// #define Z7_SWF_UPDATE + +#ifdef Z7_SWF_UPDATE + +#include "../Compress/LzmaEncoder.h" +#include "../Compress/ZlibEncoder.h" + +#include "Common/HandlerOut.h" + +#endif + +using namespace NWindows; + +namespace NArchive { + +static const UInt32 kFileSizeMax = (UInt32)1 << 29; + +namespace NSwfc { + +static const unsigned kHeaderBaseSize = 8; +static const unsigned kHeaderLzmaSize = 17; + +static const Byte SWF_UNCOMPRESSED = 'F'; +static const Byte SWF_COMPRESSED_ZLIB = 'C'; +static const Byte SWF_COMPRESSED_LZMA = 'Z'; + +static const Byte SWF_MIN_COMPRESSED_ZLIB_VER = 6; +static const Byte SWF_MIN_COMPRESSED_LZMA_VER = 13; + +static const Byte kVerLim = 64; + +API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size) +{ + if (size < kHeaderBaseSize) + return k_IsArc_Res_NEED_MORE; + if (p[0] != SWF_UNCOMPRESSED || + p[1] != 'W' || + p[2] != 'S' || + p[3] >= kVerLim) + return k_IsArc_Res_NO; + UInt32 uncompressedSize = GetUi32(p + 4); + if (uncompressedSize > kFileSizeMax) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +API_FUNC_static_IsArc IsArc_Swfc(const Byte *p, size_t size) +{ + if (size < kHeaderBaseSize + 2 + 1) // 2 + 1 (for zlib check) + return k_IsArc_Res_NEED_MORE; + if ((p[0] != SWF_COMPRESSED_ZLIB && + p[0] != SWF_COMPRESSED_LZMA) || + p[1] != 'W' || + p[2] != 'S' || + p[3] >= kVerLim) + return k_IsArc_Res_NO; + UInt32 uncompressedSize = GetUi32(p + 4); + if (uncompressedSize > kFileSizeMax) + return k_IsArc_Res_NO; + + if (p[0] == SWF_COMPRESSED_ZLIB) + { + if (!NCompress::NZlib::IsZlib_3bytes(p + 8)) + return k_IsArc_Res_NO; + } + else + { + if (size < kHeaderLzmaSize + 2) + return k_IsArc_Res_NEED_MORE; + if (p[kHeaderLzmaSize] != 0 || + (p[kHeaderLzmaSize + 1] & 0x80) != 0) + return k_IsArc_Res_NO; + UInt32 lzmaPackSize = GetUi32(p + 8); + UInt32 lzmaProp = p[12]; + UInt32 lzmaDicSize = GetUi32(p + 13); + if (lzmaProp > 5 * 5 * 9 || + lzmaDicSize > ((UInt32)1 << 28) || + lzmaPackSize < 5 || + lzmaPackSize > ((UInt32)1 << 28)) + return k_IsArc_Res_NO; + } + + return k_IsArc_Res_YES; +} +} + +struct CItem +{ + Byte Buf[kHeaderLzmaSize]; + unsigned HeaderSize; + + UInt32 GetSize() const { return GetUi32(Buf + 4); } + UInt32 GetLzmaPackSize() const { return GetUi32(Buf + 8); } + UInt32 GetLzmaDicSize() const { return GetUi32(Buf + 13); } + + bool IsSwf() const { return (Buf[1] == 'W' && Buf[2] == 'S' && Buf[3] < kVerLim); } + bool IsUncompressed() const { return Buf[0] == SWF_UNCOMPRESSED; } + bool IsZlib() const { return Buf[0] == SWF_COMPRESSED_ZLIB; } + bool IsLzma() const { return Buf[0] == SWF_COMPRESSED_LZMA; } + + void MakeUncompressed() + { + Buf[0] = SWF_UNCOMPRESSED; + HeaderSize = kHeaderBaseSize; + } + void MakeZlib() + { + Buf[0] = SWF_COMPRESSED_ZLIB; + if (Buf[3] < SWF_MIN_COMPRESSED_ZLIB_VER) + Buf[3] = SWF_MIN_COMPRESSED_ZLIB_VER; + } + void MakeLzma(UInt32 packSize) + { + Buf[0] = SWF_COMPRESSED_LZMA; + if (Buf[3] < SWF_MIN_COMPRESSED_LZMA_VER) + Buf[3] = SWF_MIN_COMPRESSED_LZMA_VER; + SetUi32(Buf + 8, packSize) + HeaderSize = kHeaderLzmaSize; + } + + HRESULT ReadHeader(ISequentialInStream *stream) + { + HeaderSize = kHeaderBaseSize; + return ReadStream_FALSE(stream, Buf, kHeaderBaseSize); + } + HRESULT WriteHeader(ISequentialOutStream *stream) + { + return WriteStream(stream, Buf, HeaderSize); + } +}; + + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveOpenSeq, + #ifdef Z7_SWF_UPDATE + public IOutArchive, + public ISetProperties, + #endif + public CMyUnknownImp +{ + #ifdef Z7_SWF_UPDATE + Z7_IFACES_IMP_UNK_4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties) + #else + Z7_IFACES_IMP_UNK_2(IInArchive, IArchiveOpenSeq) + #endif + + CItem _item; + UInt64 _packSize; + bool _packSizeDefined; + CMyComPtr _seqStream; + CMyComPtr _stream; + +#ifdef Z7_SWF_UPDATE + CSingleMethodProps _props; + bool _lzmaMode; +#endif + +public: + #ifdef Z7_SWF_UPDATE + CHandler(): _lzmaMode(false) {} + #endif +}; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, + kpidMethod +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_packSizeDefined) prop = _item.HeaderSize + _packSize; break; + case kpidIsNotArcType: prop = true; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +static void DicSizeToString(char *s, UInt32 val) +{ + char c = 0; + unsigned i; + for (i = 0; i < 32; i++) + if (((UInt32)1 << i) == val) + { + val = i; + break; + } + if (i == 32) + { + c = 'b'; + if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; } + else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; } + } + ::ConvertUInt32ToString(val, s); + unsigned pos = MyStringLen(s); + s[pos++] = c; + s[pos] = 0; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidSize: prop = (UInt64)_item.GetSize(); break; + case kpidPackSize: if (_packSizeDefined) prop = _item.HeaderSize + _packSize; break; + case kpidMethod: + { + char s[32]; + if (_item.IsZlib()) + MyStringCopy(s, "zlib"); + else + { + MyStringCopy(s, "LZMA:"); + DicSizeToString(s + 5, _item.GetLzmaDicSize()); + } + prop = s; + break; + } + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *)) +{ + RINOK(OpenSeq(stream)) + _stream = stream; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + RINOK(_item.ReadHeader(stream)) + if (!_item.IsSwf()) + return S_FALSE; + if (_item.IsLzma()) + { + RINOK(ReadStream_FALSE(stream, _item.Buf + kHeaderBaseSize, kHeaderLzmaSize - kHeaderBaseSize)) + _item.HeaderSize = kHeaderLzmaSize; + _packSize = _item.GetLzmaPackSize(); + _packSizeDefined = true; + } + else if (!_item.IsZlib()) + return S_FALSE; + if (_item.GetSize() < _item.HeaderSize) + return S_FALSE; + _seqStream = stream; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _packSize = 0; + _packSizeDefined = false; + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp, + ICompressProgressInfo +) + CMyComPtr Callback; +public: + UInt64 Offset; + void Init(IArchiveOpenCallback *callback) { Callback = callback; } +}; + +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) +{ + if (Callback) + { + const UInt64 files = 0; + const UInt64 value = Offset + *inSize; + return Callback->SetCompleted(&files, &value); + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + RINOK(extractCallback->SetTotal(_item.GetSize())) + Int32 opRes; +{ + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + lps->InSize = _item.HeaderSize; + lps->OutSize = outStream->GetSize(); + RINOK(lps->SetCur()) + + CItem item = _item; + item.MakeUncompressed(); + if (_stream) + RINOK(InStream_SeekSet(_stream, _item.HeaderSize)) + NCompress::NZlib::CDecoder *_decoderZlibSpec = NULL; + NCompress::NLzma::CDecoder *_decoderLzmaSpec = NULL; + CMyComPtr _decoder; + + CMyComPtr inStream2; + + const UInt64 unpackSize = _item.GetSize() - (UInt32)8; + if (_item.IsZlib()) + { + _decoderZlibSpec = new NCompress::NZlib::CDecoder; + _decoder = _decoderZlibSpec; + inStream2 = _seqStream; + } + else + { + /* Some .swf files with lzma contain additional 8 bytes at the end + in uncompressed stream. + What does that data mean ??? + We don't decompress these additional 8 bytes */ + + // unpackSize = _item.GetSize(); + // SetUi32(item.Buf + 4, (UInt32)(unpackSize + 8)); + CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; + inStream2 = limitedStreamSpec; + limitedStreamSpec->SetStream(_seqStream); + limitedStreamSpec->Init(_item.GetLzmaPackSize()); + + _decoderLzmaSpec = new NCompress::NLzma::CDecoder; + _decoder = _decoderLzmaSpec; + // _decoderLzmaSpec->FinishStream = true; + + Byte props[5]; + memcpy(props, _item.Buf + 12, 5); + UInt32 dicSize = _item.GetLzmaDicSize(); + if (dicSize > (UInt32)unpackSize) + { + dicSize = (UInt32)unpackSize; + SetUi32(props + 1, dicSize) + } + RINOK(_decoderLzmaSpec->SetDecoderProperties2(props, 5)) + } + RINOK(item.WriteHeader(outStream)) + const HRESULT result = _decoder->Code(inStream2, outStream, NULL, &unpackSize, lps); + opRes = NExtract::NOperationResult::kDataError; + if (result == S_OK) + { + if (item.GetSize() == outStream->GetSize()) + { + if (_item.IsZlib()) + { + _packSizeDefined = true; + _packSize = _decoderZlibSpec->GetInputProcessedSize(); + opRes = NExtract::NOperationResult::kOK; + } + else + { + // if (_decoderLzmaSpec->GetInputProcessedSize() == _packSize) + opRes = NExtract::NOperationResult::kOK; + } + } + } + else if (result != S_FALSE) + return result; + + // outStream.Release(); + } + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + + +#ifdef Z7_SWF_UPDATE + +static HRESULT UpdateArchive(ISequentialOutStream *outStream, UInt64 size, + bool lzmaMode, const CSingleMethodProps &props, + IArchiveUpdateCallback *updateCallback) +{ + UInt64 complexity = 0; + RINOK(updateCallback->SetTotal(size)) + RINOK(updateCallback->SetCompleted(&complexity)) + + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)) + + /* + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + realOutStream.Release(); + */ + + CItem item; + const HRESULT res = item.ReadHeader(fileInStream); + if (res == S_FALSE) + return E_INVALIDARG; + RINOK(res) + if (!item.IsSwf() || !item.IsUncompressed() || size != item.GetSize()) + return E_INVALIDARG; + + NCompress::NZlib::CEncoder *encoderZlibSpec = NULL; + NCompress::NLzma::CEncoder *encoderLzmaSpec = NULL; + CMyComPtr encoder; + CMyComPtr outSeekStream; + if (lzmaMode) + { + outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream); + if (!outSeekStream) + return E_NOTIMPL; + encoderLzmaSpec = new NCompress::NLzma::CEncoder; + encoder = encoderLzmaSpec; + RINOK(props.SetCoderProps(encoderLzmaSpec, &size)) + item.MakeLzma((UInt32)0xFFFFFFFF); + CBufPtrSeqOutStream *propStreamSpec = new CBufPtrSeqOutStream; + CMyComPtr propStream = propStreamSpec; + propStreamSpec->Init(item.Buf + 12, 5); + RINOK(encoderLzmaSpec->WriteCoderProperties(propStream)) + } + else + { + encoderZlibSpec = new NCompress::NZlib::CEncoder; + encoder = encoderZlibSpec; + encoderZlibSpec->Create(); + RINOK(props.SetCoderProps(encoderZlibSpec->DeflateEncoderSpec, NULL)) + item.MakeZlib(); + } + RINOK(item.WriteHeader(outStream)) + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, lps)) + UInt64 inputProcessed; + if (lzmaMode) + { + UInt64 curPos = 0; + RINOK(outSeekStream->Seek(0, STREAM_SEEK_CUR, &curPos)) + const UInt64 packSize = curPos - kHeaderLzmaSize; + if (packSize > (UInt32)0xFFFFFFFF) + return E_INVALIDARG; + item.MakeLzma((UInt32)packSize); + RINOK(outSeekStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(item.WriteHeader(outStream)) + inputProcessed = encoderLzmaSpec->GetInputProcessedSize(); + } + else + { + inputProcessed = encoderZlibSpec->GetInputProcessedSize(); + } + if (inputProcessed + kHeaderBaseSize != size) + return E_INVALIDARG; + return updateCallback->SetOperationResult(NUpdate::NOperationResult::kOK); +} + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = NFileTimeType::kUnix; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + if (numItems != 1) + return E_INVALIDARG; + + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt == VT_BOOL) + { + if (prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + return UpdateArchive(outStream, size, _lzmaMode, _props, updateCallback); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + if (!_seqStream) + return E_NOTIMPL; + + if (_stream) + { + RINOK(InStream_SeekToBegin(_stream)) + } + else + _item.WriteHeader(outStream); + return NCompress::CopyStream(_seqStream, outStream, NULL); +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + _lzmaMode = false; + RINOK(_props.SetProperties(names, values, numProps)) + const AString &m = _props.MethodName; + if (m.IsEqualTo_Ascii_NoCase("lzma")) + { + return E_NOTIMPL; + // _lzmaMode = true; + } + else if (m.IsEqualTo_Ascii_NoCase("Deflate") || m.IsEmpty()) + _lzmaMode = false; + else + return E_INVALIDARG; + return S_OK; +} + +#endif + + +static const Byte k_Signature[] = { + 3, 'C', 'W', 'S', + 3, 'Z', 'W', 'S' }; + +REGISTER_ARC_I( + "SWFc", "swf", "~.swf", 0xD8, + k_Signature, + 0, + NArcInfoFlags::kMultiSignature, + IsArc_Swfc) + +} + +namespace NSwf { + +static const unsigned kNumTagsMax = 1 << 23; + +struct CTag +{ + UInt32 Type; + CByteBuffer Buf; +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IArchiveOpenSeq +) + CObjectVector _tags; + NSwfc::CItem _item; + UInt64 _phySize; + + HRESULT OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback); + HRESULT OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback); +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidComment, +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _phySize; break; + case kpidIsNotArcType: prop = true; break; + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _tags.Size(); + return S_OK; +} + +static const char * const g_TagDesc[92] = +{ + "End" + , "ShowFrame" + , "DefineShape" + , NULL + , "PlaceObject" + , "RemoveObject" + , "DefineBits" + , "DefineButton" + , "JPEGTables" + , "SetBackgroundColor" + , "DefineFont" + , "DefineText" + , "DoAction" + , "DefineFontInfo" + , "DefineSound" + , "StartSound" + , NULL + , "DefineButtonSound" + , "SoundStreamHead" + , "SoundStreamBlock" + , "DefineBitsLossless" + , "DefineBitsJPEG2" + , "DefineShape2" + , "DefineButtonCxform" + , "Protect" + , NULL + , "PlaceObject2" + , NULL + , "RemoveObject2" + , NULL + , NULL + , NULL + , "DefineShape3" + , "DefineText2" + , "DefineButton2" + , "DefineBitsJPEG3" + , "DefineBitsLossless2" + , "DefineEditText" + , NULL + , "DefineSprite" + , NULL + , "41" + , NULL + , "FrameLabel" + , NULL + , "SoundStreamHead2" + , "DefineMorphShape" + , NULL + , "DefineFont2" + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , NULL + , "ExportAssets" + , "ImportAssets" + , "EnableDebugger" + , "DoInitAction" + , "DefineVideoStream" + , "VideoFrame" + , "DefineFontInfo2" + , NULL + , "EnableDebugger2" + , "ScriptLimits" + , "SetTabIndex" + , NULL + , NULL + , "FileAttributes" + , "PlaceObject3" + , "ImportAssets2" + , NULL + , "DefineFontAlignZones" + , "CSMTextSettings" + , "DefineFont3" + , "SymbolClass" + , "Metadata" + , "DefineScalingGrid" + , NULL + , NULL + , NULL + , "DoABC" + , "DefineShape4" + , "DefineMorphShape2" + , NULL + , "DefineSceneAndFrameLabelData" + , "DefineBinaryData" + , "DefineFontName" + , "StartSound2" + , "DefineBitsJPEG4" + , "DefineFont4" +}; + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + const CTag &tag = _tags[index]; + switch (propID) + { + case kpidPath: + { + char s[32]; + ConvertUInt32ToString(index, s); + size_t i = strlen(s); + s[i++] = '.'; + ConvertUInt32ToString(tag.Type, s + i); + prop = s; + break; + } + case kpidSize: + case kpidPackSize: + prop = (UInt64)tag.Buf.Size(); break; + case kpidComment: + TYPE_TO_PROP(g_TagDesc, tag.Type, prop); + break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + return OpenSeq2(stream, callback); +} + +static UInt16 Read16(CInBuffer &stream) +{ + UInt32 res = 0; + for (unsigned i = 0; i < 2; i++) + { + Byte b; + if (!stream.ReadByte(b)) + throw 1; + res |= (UInt32)b << (i * 8); + } + return (UInt16)res; +} + +static UInt32 Read32(CInBuffer &stream) +{ + UInt32 res = 0; + for (unsigned i = 0; i < 4; i++) + { + Byte b; + if (!stream.ReadByte(b)) + throw 1; + res |= (UInt32)b << (i * 8); + } + return res; +} + +struct CBitReader +{ + CInBuffer *stream; + unsigned NumBits; + Byte Val; + + CBitReader(): NumBits(0), Val(0) {} + + UInt32 ReadBits(unsigned numBits); +}; + +UInt32 CBitReader::ReadBits(unsigned numBits) +{ + UInt32 res = 0; + while (numBits > 0) + { + if (NumBits == 0) + { + Val = stream->ReadByte(); + NumBits = 8; + } + if (numBits <= NumBits) + { + res <<= numBits; + NumBits -= numBits; + res |= (Val >> NumBits); + Val = (Byte)(Val & (((unsigned)1 << NumBits) - 1)); + break; + } + else + { + res <<= NumBits; + res |= Val; + numBits -= NumBits; + NumBits = 0; + } + } + return res; +} + +HRESULT CHandler::OpenSeq3(ISequentialInStream *stream, IArchiveOpenCallback *callback) +{ + RINOK(_item.ReadHeader(stream)) + if (!_item.IsSwf() || !_item.IsUncompressed()) + return S_FALSE; + const UInt32 uncompressedSize = _item.GetSize(); + if (uncompressedSize > kFileSizeMax) + return S_FALSE; + + + CInBuffer s; + if (!s.Create(1 << 20)) + return E_OUTOFMEMORY; + s.SetStream(stream); + s.Init(); + { + CBitReader br; + br.stream = &s; + const unsigned numBits = br.ReadBits(5); + /* UInt32 xMin = */ br.ReadBits(numBits); + /* UInt32 xMax = */ br.ReadBits(numBits); + /* UInt32 yMin = */ br.ReadBits(numBits); + /* UInt32 yMax = */ br.ReadBits(numBits); + } + /* UInt32 frameDelay = */ Read16(s); + /* UInt32 numFrames = */ Read16(s); + + _tags.Clear(); + UInt64 offsetPrev = 0; + for (;;) + { + const UInt32 pair = Read16(s); + const UInt32 type = pair >> 6; + UInt32 length = pair & 0x3F; + if (length == 0x3F) + length = Read32(s); + if (type == 0) + break; + const UInt64 offset = s.GetProcessedSize() + NSwfc::kHeaderBaseSize + length; + if (offset > uncompressedSize || _tags.Size() >= kNumTagsMax) + return S_FALSE; + CTag &tag = _tags.AddNew(); + tag.Type = type; + tag.Buf.Alloc(length); + if (s.ReadBytes(tag.Buf, length) != length) + return S_FALSE; + if (callback && offset >= offsetPrev + (1 << 20)) + { + const UInt64 numItems = _tags.Size(); + RINOK(callback->SetCompleted(&numItems, &offset)) + offsetPrev = offset; + } + } + _phySize = s.GetProcessedSize() + NSwfc::kHeaderBaseSize; + if (_phySize != uncompressedSize) + { + // do we need to support files extracted from SFW-LZMA with additional 8 bytes? + return S_FALSE; + } + return S_OK; +} + +HRESULT CHandler::OpenSeq2(ISequentialInStream *stream, IArchiveOpenCallback *callback) +{ + HRESULT res; + try { res = OpenSeq3(stream, callback); } + catch(...) { res = S_FALSE; } + return res; +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + return OpenSeq2(stream, NULL); +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _tags.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _tags[allFilesMode ? i : indices[i]].Buf.Size(); + RINOK(extractCallback->SetTotal(totalSize)) + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + totalSize = 0; + + for (i = 0; i < numItems; i++) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CByteBuffer &buf = _tags[index].Buf; + totalSize += buf.Size(); + + CMyComPtr outStream; + RINOK(extractCallback->GetStream(index, &outStream, askMode)) + if (!testMode && !outStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + if (outStream) + RINOK(WriteStream(outStream, buf, buf.Size())) + outStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + return S_OK; + COM_TRY_END +} + +static const Byte k_Signature[] = { 'F', 'W', 'S' }; + +REGISTER_ARC_I( + "SWF", "swf", NULL, 0xD7, + k_Signature, + 0, + NArcInfoFlags::kKeepName, + NSwfc::IsArc_Swf) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandler.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.cpp 2024-03-04 13:00:00.000000000 +0000 @@ -1,677 +1,1094 @@ -// TarHandler.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/MethodProps.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "../Common/ItemNameUtils.h" - -#include "TarHandler.h" - -using namespace NWindows; - -namespace NArchive { -namespace NTar { - -static const UINT k_DefaultCodePage = CP_OEMCP; // it uses it if UTF8 check in names shows error - - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidPosixAttrib, - kpidUser, - kpidGroup, - kpidSymLink, - kpidHardLink, - // kpidLinkType -}; - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - kpidCodePage -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -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 kpidErrorFlags: - { - UInt32 flags = 0; - if (!_isArc) - flags |= kpv_ErrorFlags_IsNotArc; - else switch (_error) - { - case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break; - case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break; - } - prop = flags; - break; - } - - case kpidCodePage: - { - const char *name = NULL; - switch (_openCodePage) - { - case CP_OEMCP: name = "OEM"; break; - case CP_UTF8: name = "UTF-8"; break; - } - if (name != NULL) - prop = name; - else - { - char sz[16]; - ConvertUInt32ToString(_openCodePage, sz); - prop = sz; - }; - break; - } - } - prop.Detach(value); - return S_OK; -} - -HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &item) -{ - item.HeaderPos = _phySize; - RINOK(ReadItem(stream, filled, item, _error)); - if (filled) - { - /* - if (item.IsSparse()) - _isSparse = true; - */ - if (item.IsPaxExtendedHeader()) - _thereIsPaxExtendedHeader = true; - } - _phySize += item.HeaderSize; - _headersSize += item.HeaderSize; - return S_OK; -} - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) -{ - UInt64 endPos = 0; - { - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - - _phySizeDefined = true; - - bool utf8_OK = true; - if (!_forceCodePage) - { - if (!utf8_OK) - _curCodePage = k_DefaultCodePage; - } - - for (;;) - { - CItemEx item; - bool filled; - RINOK(ReadItem2(stream, filled, item)); - if (!filled) - break; - - _isArc = true; - _items.Add(item); - - if (!_forceCodePage) - { - if (utf8_OK) utf8_OK = CheckUTF8(item.Name, item.NameCouldBeReduced); - if (utf8_OK) utf8_OK = CheckUTF8(item.LinkName, item.LinkNameCouldBeReduced); - if (utf8_OK) utf8_OK = CheckUTF8(item.User); - if (utf8_OK) utf8_OK = CheckUTF8(item.Group); - } - - RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize)); - if (_phySize > endPos) - { - _error = k_ErrorType_UnexpectedEnd; - break; - } - /* - if (_phySize == endPos) - { - _errorMessage = "There are no trailing zero-filled records"; - break; - } - */ - if (callback) - { - if (_items.Size() == 1) - { - RINOK(callback->SetTotal(NULL, &endPos)); - } - if ((_items.Size() & 0x3FF) == 0) - { - UInt64 numFiles = _items.Size(); - RINOK(callback->SetCompleted(&numFiles, &_phySize)); - } - } - } - - if (!_forceCodePage) - { - if (!utf8_OK) - _curCodePage = k_DefaultCodePage; - } - _openCodePage = _curCodePage; - - if (_items.Size() == 0) - { - if (_error != k_ErrorType_OK) - { - _isArc = false; - return S_FALSE; - } - CMyComPtr openVolumeCallback; - if (!callback) - return S_FALSE; - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - if (!openVolumeCallback) - return S_FALSE; - NCOM::CPropVariant prop; - if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) - return S_FALSE; - if (prop.vt != VT_BSTR) - return S_FALSE; - unsigned len = MyStringLen(prop.bstrVal); - if (len < 4 || MyStringCompareNoCase(prop.bstrVal + len - 4, L".tar") != 0) - return S_FALSE; - } - - _isArc = true; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - { - Close(); - RINOK(Open2(stream, openArchiveCallback)); - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - Close(); - _seqStream = stream; - _isArc = true; - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _isArc = false; - _error = k_ErrorType_OK; - - _phySizeDefined = false; - _phySize = 0; - _headersSize = 0; - _curIndex = 0; - _latestIsRead = false; - // _isSparse = false; - _thereIsPaxExtendedHeader = false; - _items.Clear(); - _seqStream.Release(); - _stream.Release(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = (_stream ? _items.Size() : (UInt32)(Int32)-1); - return S_OK; -} - -CHandler::CHandler() -{ - copyCoderSpec = new NCompress::CCopyCoder(); - copyCoder = copyCoderSpec; - _openCodePage = CP_UTF8; - Init(); -} - -HRESULT CHandler::SkipTo(UInt32 index) -{ - while (_curIndex < index || !_latestIsRead) - { - if (_latestIsRead) - { - UInt64 packSize = _latestItem.GetPackSizeAligned(); - RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL)); - _phySize += copyCoderSpec->TotalSize; - if (copyCoderSpec->TotalSize != packSize) - { - _error = k_ErrorType_UnexpectedEnd; - return S_FALSE; - } - _latestIsRead = false; - _curIndex++; - } - else - { - bool filled; - RINOK(ReadItem2(_seqStream, filled, _latestItem)); - if (!filled) - { - _phySizeDefined = true; - return E_INVALIDARG; - } - _latestIsRead = true; - } - } - return S_OK; -} - -void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant &prop, bool toOs) const -{ - UString dest; - if (_curCodePage == CP_UTF8) - ConvertUTF8ToUnicode(s, dest); - else - MultiByteToUnicodeString2(dest, s, _curCodePage); - if (toOs) - NItemName::ConvertToOSName2(dest); - prop = dest; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - const CItemEx *item; - if (_stream) - item = &_items[index]; - else - { - if (index < _curIndex) - return E_INVALIDARG; - else - { - RINOK(SkipTo(index)); - item = &_latestItem; - } - } - - switch (propID) - { - 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 kpidMTime: - if (item->MTime != 0) - { - FILETIME ft; - if (NTime::UnixTime64ToFileTime(item->MTime, ft)) - prop = ft; - } - break; - case kpidPosixAttrib: prop = item->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; - } - 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); - if (!seqMode) - stream = _stream; - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (_stream && numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _items[allFilesMode ? i : indices[i]].GetUnpackSize(); - extractCallback->SetTotal(totalSize); - - UInt64 totalPackSize; - totalSize = totalPackSize = 0; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(stream); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems || seqMode; i++) - { - lps->InSize = totalPackSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CItemEx *item; - if (seqMode) - { - HRESULT res = SkipTo(index); - if (res == E_INVALIDARG) - break; - RINOK(res); - item = &_latestItem; - } - else - item = &_items[index]; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - UInt64 unpackSize = item->GetUnpackSize(); - totalSize += unpackSize; - totalPackSize += item->GetPackSizeAligned(); - if (item->IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - bool skipMode = false; - if (!testMode && !realOutStream) - { - if (!seqMode) - { - /* - // probably we must show extracting info it callback handler instead - if (item->IsHardLink() || - item->IsSymLink()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - */ - continue; - } - skipMode = true; - askMode = NExtract::NAskMode::kSkip; - } - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(skipMode ? 0 : unpackSize, true); - - Int32 opRes = NExtract::NOperationResult::kOK; - CMyComPtr inStream2; - if (!item->IsSparse()) - inStream2 = inStream; - else - { - GetStream(index, &inStream2); - if (!inStream2) - return E_FAIL; - } - - { - if (item->IsSymLink()) - { - RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len())); - } - else - { - if (!seqMode) - { - RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL)); - } - streamSpec->Init(item->GetPackSizeAligned()); - RINOK(copyCoder->Code(inStream2, outStream, NULL, NULL, progress)); - } - if (outStreamSpec->GetRem() != 0) - opRes = NExtract::NOperationResult::kDataError; - } - if (seqMode) - { - _latestIsRead = false; - _curIndex++; - } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - return S_OK; - COM_TRY_END -} - -class CSparseStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _phyPos; - UInt64 _virtPos; - bool _needStartSeek; - -public: - CHandler *Handler; - CMyComPtr HandlerRef; - unsigned ItemIndex; - CRecordVector PhyOffsets; - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - void Init() - { - _virtPos = 0; - _phyPos = 0; - _needStartSeek = true; - } -}; - - -STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - const CItemEx &item = Handler->_items[ItemIndex]; - if (_virtPos >= item.Size) - return S_OK; - { - UInt64 rem = item.Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - - HRESULT res = S_OK; - - if (item.SparseBlocks.IsEmpty()) - memset(data, 0, size); - else - { - unsigned left = 0, right = item.SparseBlocks.Size(); - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (_virtPos < item.SparseBlocks[mid].Offset) - right = mid; - else - left = mid; - } - - const CSparseBlock &sb = item.SparseBlocks[left]; - UInt64 relat = _virtPos - sb.Offset; - - if (_virtPos >= sb.Offset && relat < sb.Size) - { - UInt64 rem = sb.Size - relat; - if (size > rem) - size = (UInt32)rem; - UInt64 phyPos = PhyOffsets[left] + relat; - if (_needStartSeek || _phyPos != phyPos) - { - RINOK(Handler->_stream->Seek(item.GetDataPosition() + phyPos, STREAM_SEEK_SET, NULL)); - _needStartSeek = false; - _phyPos = phyPos; - } - res = Handler->_stream->Read(data, size, &size); - _phyPos += size; - } - else - { - UInt64 next = item.Size; - if (_virtPos < sb.Offset) - next = sb.Offset; - else if (left + 1 < item.SparseBlocks.Size()) - next = item.SparseBlocks[left + 1].Offset; - UInt64 rem = next - _virtPos; - if (size > rem) - size = (UInt32)rem; - memset(data, 0, size); - } - } - - _virtPos += size; - if (processedSize) - *processedSize = size; - return res; -} - -STDMETHODIMP CSparseStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Handler->_items[ItemIndex].Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return S_OK; -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - - const CItemEx &item = _items[index]; - - if (item.IsSparse()) - { - CSparseStream *streamSpec = new CSparseStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->Init(); - streamSpec->Handler = this; - streamSpec->HandlerRef = (IInArchive *)this; - streamSpec->ItemIndex = index; - streamSpec->PhyOffsets.Reserve(item.SparseBlocks.Size()); - UInt64 offs = 0; - FOR_VECTOR(i, item.SparseBlocks) - { - const CSparseBlock &sb = item.SparseBlocks[i]; - streamSpec->PhyOffsets.AddInReserved(offs); - offs += sb.Size; - } - *stream = streamTemp.Detach(); - return S_OK; - } - - if (item.IsSymLink()) - { - 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); - - COM_TRY_END -} - -void CHandler::Init() -{ - _forceCodePage = false; - // _codePage = CP_OEMCP; - _curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP; - _thereIsPaxExtendedHeader = false; -} - -STDMETHODIMP CHandler::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 &prop = values[i]; - - if (name[0] == L'x') - { - // some clients write 'x' property. So we support it - UInt32 level = 0; - RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)); - } - else if (name.IsEqualTo("cp")) - { - UInt32 cp = CP_OEMCP; - RINOK(ParsePropToUInt32(L"", prop, cp)); - _forceCodePage = true; - _curCodePage = _specifiedCodePage = cp; - } - else - return E_INVALIDARG; - } - return S_OK; -} - -}} +// TarHandler.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/MethodProps.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../Common/ItemNameUtils.h" + +#include "TarHandler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NTar { + +// 21.02: we use UTF8 code page by default, even if some files show error +// before 21.02 : CP_OEMCP; +// static const UINT k_DefaultCodePage = CP_UTF8; + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidPosixAttrib, +#if 0 + kpidAttrib, +#endif + kpidUser, + kpidGroup, + kpidUserId, + kpidGroupId, + kpidSymLink, + kpidHardLink, + kpidCharacts, + kpidComment + , kpidDeviceMajor + , kpidDeviceMinor + // , kpidDevice + // , kpidHeadersSize // for debug + // , kpidOffset // for debug +}; + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidCodePage, + kpidCharacts, + kpidComment +}; + +static const char *k_Characts_Prefix = "PREFIX"; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + 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 ((int)_arc._error) + { + case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break; + case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break; + // case k_ErrorType_OK: break; + // case k_ErrorType_Warning: break; + // case k_ErrorType_OK: + default: break; + } + if (flags != 0) + prop = flags; + break; + } + + case kpidWarningFlags: + { + if (_arc._is_Warning) + prop = kpv_ErrorFlags_HeadersError; + break; + } + + case kpidCodePage: + { + char sz[16]; + const char *name = NULL; + switch (_openCodePage) + { + case CP_OEMCP: name = "OEM"; break; + case CP_UTF8: name = "UTF-8"; break; + default: break; + } + if (!name) + { + ConvertUInt32ToString(_openCodePage, sz); + name = sz; + } + prop = name; + break; + } + + case kpidCharacts: + { + 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._are_SCHILY_fflags) s.Add_OptSpaced("SCHILY.fflags"); + if (_arc._is_PaxGlobal_Error) s.Add_OptSpaced("PAX_GLOBAL_ERROR"); + s.Add_OptSpaced(_encodingCharacts.GetCharactsString()); + prop = s; + break; + } + + case kpidComment: + { + if (_arc.PaxGlobal_Defined) + { + AString s; + _arc.PaxGlobal.Print_To_String(s); + if (!s.IsEmpty()) + prop = s; + } + break; + } + default: break; + } + prop.Detach(value); + return S_OK; +} + + +void CEncodingCharacts::Check(const AString &s) +{ + IsAscii = s.IsAscii(); + if (!IsAscii) + { + /* + { + Oem_Checked = true; + UString u; + MultiByteToUnicodeString2(u, s, CP_OEMCP); + Oem_Ok = (u.Find((wchar_t)0xfffd) <= 0); + } + Utf_Checked = true; + */ + UtfCheck.Check_AString(s); + } +} + + +AString CEncodingCharacts::GetCharactsString() const +{ + AString s; + if (IsAscii) + { + s += "ASCII"; + } + /* + if (Oem_Checked) + { + s.Add_Space_if_NotEmpty(); + s += (Oem_Ok ? "oem-ok" : "oem-error"); + } + if (Utf_Checked) + */ + else + { + s.Add_Space_if_NotEmpty(); + s += (UtfCheck.IsOK() ? "UTF8" : "UTF8-ERROR"); // "UTF8-error" + { + AString s2; + UtfCheck.PrintStatus(s2); + s.Add_Space_if_NotEmpty(); + s += s2; + } + } + return s; +} + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) +{ + UInt64 endPos; + { + RINOK(InStream_AtBegin_GetSize(stream, endPos)) + } + + _arc._phySize_Defined = true; + + // bool utf8_OK = true; + + _arc.SeqStream = stream; + _arc.InStream = stream; + _arc.OpenCallback = callback; + + CItemEx item; + for (;;) + { + _arc.NumFiles = _items.Size(); + RINOK(_arc.ReadItem(item)) + if (!_arc.filled) + break; + + _isArc = true; + + /* + if (!_forceCodePage) + { + if (utf8_OK) utf8_OK = CheckUTF8(item.Name, item.NameCouldBeReduced); + if (utf8_OK) utf8_OK = CheckUTF8(item.LinkName, item.LinkNameCouldBeReduced); + if (utf8_OK) utf8_OK = CheckUTF8(item.User); + if (utf8_OK) utf8_OK = CheckUTF8(item.Group); + } + */ + + item.EncodingCharacts.Check(item.Name); + _encodingCharacts.Update(item.EncodingCharacts); + + _items.Add(item); + + RINOK(stream->Seek((Int64)item.Get_PackSize_Aligned(), STREAM_SEEK_CUR, &_arc._phySize)) + if (_arc._phySize > endPos) + { + _arc._error = k_ErrorType_UnexpectedEnd; + break; + } + /* + if (_phySize == endPos) + { + _errorMessage = "There are no trailing zero-filled records"; + break; + } + */ + /* + if (callback) + { + if (_items.Size() == 1) + { + RINOK(callback->SetTotal(NULL, &endPos)); + } + if ((_items.Size() & 0x3FF) == 0) + { + const UInt64 numFiles = _items.Size(); + RINOK(callback->SetCompleted(&numFiles, &_phySize)); + } + } + */ + } + + /* + if (!_forceCodePage) + { + if (!utf8_OK) + _curCodePage = k_DefaultCodePage; + } + */ + _openCodePage = _curCodePage; + + if (_items.Size() == 0) + { + if (_arc._error != k_ErrorType_OK) + { + _isArc = false; + return S_FALSE; + } + if (!callback) + return S_FALSE; + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, callback) + if (!openVolumeCallback) + return S_FALSE; + NCOM::CPropVariant prop; + if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK) + return S_FALSE; + if (prop.vt != VT_BSTR) + return S_FALSE; + unsigned len = MyStringLen(prop.bstrVal); + if (len < 4 || MyStringCompareNoCase(prop.bstrVal + len - 4, L".tar") != 0) + return S_FALSE; + } + + _isArc = true; + return S_OK; +} + +Z7_COM7F_IMF(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)) + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _seqStream = stream; + _isArc = true; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + + _arc.Clear(); + + _curIndex = 0; + _latestIsRead = false; + _encodingCharacts.Clear(); + _items.Clear(); + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = (_stream ? _items.Size() : (UInt32)(Int32)-1); + return S_OK; +} + +CHandler::CHandler() +{ + // copyCoder = new NCompress::CCopyCoder(); + // copyCoder = copyCoder; + _openCodePage = CP_UTF8; + Init(); +} + +HRESULT CHandler::SkipTo(UInt32 index) +{ + while (_curIndex < index || !_latestIsRead) + { + if (_latestIsRead) + { + const UInt64 packSize = _latestItem.Get_PackSize_Aligned(); + RINOK(copyCoder.Interface()->Code(_seqStream, NULL, &packSize, &packSize, NULL)) + _arc._phySize += copyCoder->TotalSize; + if (copyCoder->TotalSize != packSize) + { + _arc._error = k_ErrorType_UnexpectedEnd; + return S_FALSE; + } + _latestIsRead = false; + _curIndex++; + } + else + { + _arc.SeqStream = _seqStream; + _arc.InStream = NULL; + RINOK(_arc.ReadItem(_latestItem)) + if (!_arc.filled) + { + _arc._phySize_Defined = true; + return E_INVALIDARG; + } + _latestIsRead = true; + } + } + return S_OK; +} + +void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant &prop, bool toOs) const +{ + UString dest; + if (_curCodePage == CP_UTF8) + ConvertUTF8ToUnicode(s, dest); + else + MultiByteToUnicodeString2(dest, s, _curCodePage); + if (toOs) + NItemName::ReplaceToOsSlashes_Remove_TailSlash(dest, + true); // useBackslashReplacement + prop = dest; +} + + +// CPaxTime is defined (NumDigits >= 0) +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 + (unsigned)pt.NumDigits, pt.Ns % 100); +} + + +static void AddSpecCharToString(const char c, AString &s) +{ + if ((Byte)c <= 0x20 || (Byte)c > 127) + { + s.Add_Char('['); + s.Add_Char(GET_HEX_CHAR_LOWER((Byte)c >> 4)); + s.Add_Char(GET_HEX_CHAR_LOWER(c & 15)); + s.Add_Char(']'); + } + else + s.Add_Char(c); +} + +static void AddSpecUInt64(AString &s, const char *name, UInt64 v) +{ + if (v != 0) + { + s.Add_OptSpaced(name); + if (v > 1) + { + s.Add_Colon(); + 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.Add_Char('*'); + } +} + + +#if 0 +static bool Parse_Attrib_from_SCHILY_fflags(const AString &s, UInt32 &attribRes) +{ + UInt32 attrib = 0; + attribRes = attrib; + unsigned pos = 0; + while (pos < s.Len()) + { + int pos2 = s.Find(',', pos); + if (pos2 < 0) + pos2 = (int)s.Len(); + const AString str = s.Mid(pos, (unsigned)pos2 - pos); + if (str.IsEqualTo("hidden")) attrib |= FILE_ATTRIBUTE_HIDDEN; + else if (str.IsEqualTo("rdonly")) attrib |= FILE_ATTRIBUTE_READONLY; + else if (str.IsEqualTo("system")) attrib |= FILE_ATTRIBUTE_SYSTEM; + else + return false; + pos = (unsigned)pos2 + 1; + } + attribRes = attrib; + return true; +} +#endif + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CItemEx *item; + if (_stream) + item = &_items[index]; + else + { + if (index < _curIndex) + return E_INVALIDARG; + else + { + RINOK(SkipTo(index)) + item = &_latestItem; + } + } + + switch (propID) + { + case kpidPath: TarStringToUnicode(item->Name, prop, true); break; + case kpidIsDir: prop = item->IsDir(); break; + case kpidSize: prop = item->Get_UnpackSize(); break; + case kpidPackSize: prop = item->Get_PackSize_Aligned(); break; + case kpidMTime: + { + /* + // 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::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; + + // kpidAttrib has priority over kpidPosixAttrib in 7-Zip. + // but if we want kpidPosixAttrib priority for TAR, we disable kpidAttrib. +#if 0 + case kpidAttrib: + { + if (!item->SCHILY_fflags.IsEmpty()) + { + UInt32 attrib = 0; + if (Parse_Attrib_from_SCHILY_fflags(item->SCHILY_fflags, attrib)) + { + if (attrib != 0) + { + if (item->IsDir()) + attrib |= FILE_ATTRIBUTE_DIRECTORY; + attrib |= ((UInt32)item->Get_Combined_Mode() << 16) | 0x8000; // FILE_ATTRIBUTE_UNIX_EXTENSION; + prop = attrib; + } + } + } + break; + } +#endif + + 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; + { + s.Add_Space_if_NotEmpty(); + AddSpecCharToString(item->LinkFlag, 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->SCHILY_fflags.IsEmpty()) + { + s.Add_OptSpaced("SCHILY.fflags="); + s += item->SCHILY_fflags; + } + 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 + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + ISequentialInStream *stream = _seqStream; + const bool seqMode = (_stream == NULL); + if (!seqMode) + stream = _stream; + + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _items.Size(); + if (_stream && numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Get_UnpackSize(); + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create inStream; + inStream->SetStream(stream); + CMyComPtr2_Create outStreamSpec; + + for (i = 0; ; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems && !seqMode) + break; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItemEx *item; + if (seqMode) + { + const HRESULT res = SkipTo(index); + if (res == E_INVALIDARG) + break; + RINOK(res) + item = &_latestItem; + } + else + item = &_items[index]; + + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + const UInt64 unpackSize = item->Get_UnpackSize(); + totalSize += unpackSize; + totalPackSize += item->Get_PackSize_Aligned(); + if (item->IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + // realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + bool skipMode = false; + if (!testMode && !realOutStream) + { + if (!seqMode) + { + /* + // GetStream() creates link. + // so we can show extracting info in GetStream() instead + if (item->Is_HardLink() || + item->Is_SymLink()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + */ + continue; + } + skipMode = true; + askMode = NExtract::NAskMode::kSkip; + } + RINOK(extractCallback->PrepareOperation(askMode)) + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(skipMode ? 0 : unpackSize, true); + + Int32 opRes = NExtract::NOperationResult::kOK; + CMyComPtr inStream2; + if (!item->Is_Sparse()) + inStream2 = inStream; + else + { + GetStream(index, &inStream2); + if (!inStream2) + return E_FAIL; + } + + { + if (item->Is_SymLink()) + { + RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len())) + } + else + { + if (!seqMode) + { + RINOK(InStream_SeekSet(_stream, item->Get_DataPos())) + } + inStream->Init(item->Get_PackSize_Aligned()); + RINOK(copyCoder.Interface()->Code(inStream2, outStreamSpec, NULL, NULL, lps)) + } + if (outStreamSpec->GetRem() != 0) + opRes = NExtract::NOperationResult::kDataError; + } + if (seqMode) + { + _latestIsRead = false; + _curIndex++; + } + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + + +Z7_CLASS_IMP_IInStream( + CSparseStream +) + UInt64 _phyPos; + UInt64 _virtPos; + bool _needStartSeek; + +public: + CHandler *Handler; + CMyComPtr HandlerRef; + unsigned ItemIndex; + CRecordVector PhyOffsets; + + void Init() + { + _virtPos = 0; + _phyPos = 0; + _needStartSeek = true; + } +}; + + +Z7_COM7F_IMF(CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + const CItemEx &item = Handler->_items[ItemIndex]; + if (_virtPos >= item.Size) + return S_OK; + { + UInt64 rem = item.Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + + HRESULT res = S_OK; + + if (item.SparseBlocks.IsEmpty()) + memset(data, 0, size); + else + { + unsigned left = 0, right = item.SparseBlocks.Size(); + for (;;) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + if (mid == left) + break; + if (_virtPos < item.SparseBlocks[mid].Offset) + right = mid; + else + left = mid; + } + + const CSparseBlock &sb = item.SparseBlocks[left]; + UInt64 relat = _virtPos - sb.Offset; + + if (_virtPos >= sb.Offset && relat < sb.Size) + { + UInt64 rem = sb.Size - relat; + if (size > rem) + size = (UInt32)rem; + UInt64 phyPos = PhyOffsets[left] + relat; + if (_needStartSeek || _phyPos != phyPos) + { + RINOK(InStream_SeekSet(Handler->_stream, (item.Get_DataPos() + phyPos))) + _needStartSeek = false; + _phyPos = phyPos; + } + res = Handler->_stream->Read(data, size, &size); + _phyPos += size; + } + else + { + UInt64 next = item.Size; + if (_virtPos < sb.Offset) + next = sb.Offset; + else if (left + 1 < item.SparseBlocks.Size()) + next = item.SparseBlocks[left + 1].Offset; + UInt64 rem = next - _virtPos; + if (size > rem) + size = (UInt32)rem; + memset(data, 0, size); + } + } + + _virtPos += size; + if (processedSize) + *processedSize = size; + return res; +} + +Z7_COM7F_IMF(CSparseStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Handler->_items[ItemIndex].Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + + const CItemEx &item = _items[index]; + + if (item.Is_Sparse()) + { + CSparseStream *streamSpec = new CSparseStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->Init(); + streamSpec->Handler = this; + streamSpec->HandlerRef = (IInArchive *)this; + streamSpec->ItemIndex = index; + streamSpec->PhyOffsets.Reserve(item.SparseBlocks.Size()); + UInt64 offs = 0; + FOR_VECTOR(i, item.SparseBlocks) + { + const CSparseBlock &sb = item.SparseBlocks[i]; + streamSpec->PhyOffsets.AddInReserved(offs); + offs += sb.Size; + } + *stream = streamTemp.Detach(); + return S_OK; + } + + 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.Get_DataPos(), item.PackSize, stream); + + COM_TRY_END +} + + +void CHandler::Init() +{ + _forceCodePage = false; + _curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP; + _posixMode = false; + _posixMode_WasForced = false; + // TimeOptions.Clear(); + _handlerTimeOptions.Init(); + // _handlerTimeOptions.Write_MTime.Val = true; // it's default already +} + + +Z7_COM7F_IMF(CHandler::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 &prop = values[i]; + + if (name[0] == L'x') + { + // some clients write 'x' property. So we support it + UInt32 level = 0; + RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)) + } + else if (name.IsEqualTo("cp")) + { + UInt32 cp = CP_OEMCP; + RINOK(ParsePropToUInt32(L"", prop, cp)) + _forceCodePage = true; + _curCodePage = _specifiedCodePage = cp; + } + else if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + } + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandler.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandler.h 2023-12-19 09:00:00.000000000 +0000 @@ -1,78 +1,57 @@ -// TarHandler.h - -#ifndef __TAR_HANDLER_H -#define __TAR_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Compress/CopyCoder.h" - -#include "../IArchive.h" - -#include "TarIn.h" - -namespace NArchive { -namespace NTar { - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - public IInArchiveGetStream, - public ISetProperties, - public IOutArchive, - public CMyUnknownImp -{ -public: - CObjectVector _items; - CMyComPtr _stream; - CMyComPtr _seqStream; -private: - UInt32 _curIndex; - bool _latestIsRead; - CItemEx _latestItem; - - UInt64 _phySize; - UInt64 _headersSize; - bool _phySizeDefined; - EErrorType _error; - bool _isArc; - - // bool _isSparse; - bool _thereIsPaxExtendedHeader; - - bool _forceCodePage; - UInt32 _specifiedCodePage; - UInt32 _curCodePage; - UInt32 _openCodePage; - - 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; -public: - MY_UNKNOWN_IMP5( - IInArchive, - IArchiveOpenSeq, - IInArchiveGetStream, - ISetProperties, - IOutArchive - ) - - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - void Init(); - CHandler(); -}; - -}} - -#endif +// TarHandler.h + +#ifndef ZIP7_INC_TAR_HANDLER_H +#define ZIP7_INC_TAR_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/HandlerOut.h" + +#include "TarIn.h" + +namespace NArchive { +namespace NTar { + +Z7_CLASS_IMP_CHandler_IInArchive_4( + IArchiveOpenSeq + , IInArchiveGetStream + , ISetProperties + , IOutArchive +) +public: + CObjectVector _items; + CMyComPtr _stream; + CMyComPtr _seqStream; +private: + bool _isArc; + 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; + + CMyComPtr2_Create copyCoder; + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback); + HRESULT SkipTo(UInt32 index); + void TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant &prop, bool toOs = false) const; +public: + void Init(); + CHandler(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandlerOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandlerOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHandlerOut.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHandlerOut.cpp 2023-11-29 11:00:00.000000000 +0000 @@ -1,174 +1,332 @@ -// TarHandlerOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/Defs.h" -#include "../../../Common/MyLinux.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "TarHandler.h" -#include "TarUpdate.h" - -using namespace NWindows; - -namespace NArchive { -namespace NTar { - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kUnix; - return S_OK; -} - -HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, - AString &res, UINT codePage, bool convertSlash = false) -{ - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propId, &prop)); - - if (prop.vt == VT_BSTR) - { - UString s = prop.bstrVal; - if (convertSlash) - s = NItemName::MakeLegalName(s); - - if (codePage == CP_UTF8) - { - ConvertUnicodeToUTF8(s, res); - // if (!ConvertUnicodeToUTF8(s, res)) // return E_INVALIDARG; - } - else - UnicodeStringToMultiByte2(res, s, codePage); - } - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - - return S_OK; -} - - -// sort old files with original order. - -static int CompareUpdateItems(void *const *p1, void *const *p2, void *) -{ - const CUpdateItem &u1 = *(*((const CUpdateItem **)p1)); - const CUpdateItem &u2 = *(*((const CUpdateItem **)p2)); - if (!u1.NewProps) - { - if (u2.NewProps) - return -1; - return MyCompare(u1.IndexInArc, u2.IndexInArc); - } - if (!u2.NewProps) - return 1; - return MyCompare(u1.IndexInClient, u2.IndexInClient); -} - - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) -{ - COM_TRY_BEGIN - - if ((_stream && (_error != k_ErrorType_OK /* || _isSparse */)) || _seqStream) - return E_NOTIMPL; - CObjectVector updateItems; - UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage); - - for (UInt32 i = 0; i < numItems; i++) - { - CUpdateItem ui; - Int32 newData; - Int32 newProps; - UInt32 indexInArc; - - if (!callback) - return E_FAIL; - - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)); - - ui.NewProps = IntToBool(newProps); - ui.NewData = IntToBool(newData); - ui.IndexInArc = indexInArc; - ui.IndexInClient = i; - - if (IntToBool(newProps)) - { - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); - if (prop.vt == VT_EMPTY) - ui.IsDir = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - ui.IsDir = (prop.boolVal != VARIANT_FALSE); - } - - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)); - if (prop.vt == VT_EMPTY) - ui.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 - ui.Mode = prop.ulVal; - } - - { - 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); - } - - RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, true)); - if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') - ui.Name += '/'; - RINOK(GetPropString(callback, i, kpidUser, ui.User, codePage)); - RINOK(GetPropString(callback, i, kpidGroup, ui.Group, codePage)); - } - - if (IntToBool(newData)) - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - ui.Size = prop.uhVal.QuadPart; - /* - // now we support GNU extension for big files - if (ui.Size >= ((UInt64)1 << 33)) - return E_INVALIDARG; - */ - } - - updateItems.Add(ui); - } - - if (_thereIsPaxExtendedHeader) - { - // we restore original order of files, if there is pax header block - updateItems.Sort(CompareUpdateItems, NULL); - } - - return UpdateArchive(_stream, outStream, _items, updateItems, codePage, callback); - - COM_TRY_END -} - -}} +// TarHandlerOut.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../Common/ComTry.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/TimeUtils.h" + +#include "../Common/ItemNameUtils.h" + +#include "TarHandler.h" +#include "TarUpdate.h" + +using namespace NWindows; + +namespace NArchive { +namespace NTar { + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) +{ + 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) +{ + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(index, propId, &prop)) + + if (prop.vt == VT_BSTR) + { + UString s = prop.bstrVal; + if (convertSlash) + NItemName::ReplaceSlashes_OsToUnix(s); + Get_AString_From_UString(s, res, codePage, utfFlags); + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + + return S_OK; +} + + +// sort old files with original order. + +static int CompareUpdateItems(void *const *p1, void *const *p2, void *) +{ + const CUpdateItem &u1 = *(*((const CUpdateItem *const *)p1)); + const CUpdateItem &u2 = *(*((const CUpdateItem *const *)p2)); + if (!u1.NewProps) + { + if (u2.NewProps) + return -1; + return MyCompare(u1.IndexInArc, u2.IndexInArc); + } + if (!u2.NewProps) + return 1; + return MyCompare(u1.IndexInClient, u2.IndexInClient); +} + + +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; +} + + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) +{ + COM_TRY_BEGIN + + if ((_stream && (_arc._error != k_ErrorType_OK || _arc._is_Warning + /* || _isSparse */ + )) || _seqStream) + return E_NOTIMPL; + CObjectVector updateItems; + const UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage); + const unsigned utfFlags = g_Unicode_To_UTF8_Flags; + /* + // for debug only: + unsigned utfFlags = 0; + utfFlags |= Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE; + utfFlags |= Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR; + */ + + for (UInt32 i = 0; i < numItems; i++) + { + CUpdateItem ui; + Int32 newData; + Int32 newProps; + UInt32 indexInArc; + + if (!callback) + return E_FAIL; + + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) + + ui.NewProps = IntToBool(newProps); + ui.NewData = IntToBool(newData); + ui.IndexInArc = (int)indexInArc; + ui.IndexInClient = i; + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) + if (prop.vt == VT_EMPTY) + ui.IsDir = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + ui.IsDir = (prop.boolVal != VARIANT_FALSE); + } + + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)) + if (prop.vt == VT_EMPTY) + ui.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 + ui.Mode = prop.ulVal; + // 21.07 : we clear high file type bits as GNU TAR. + // we will clear it later + // ui.Mode &= ~(UInt32)MY_LIN_S_IFMT; + } + + 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.Add_Slash(); + // ui.Name.Add_Slash(); // 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)) + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + ui.Size = prop.uhVal.QuadPart; + /* + // now we support GNU extension for big files + if (ui.Size >= ((UInt64)1 << 33)) + return E_INVALIDARG; + */ + } + + updateItems.Add(ui); + } + + if (_arc._are_Pax_Items) + { + // 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; + + // 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHeader.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHeader.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,23 +1,99 @@ -// Archive/TarHeader.cpp - -#include "StdAfx.h" - -#include "TarHeader.h" - -namespace NArchive { -namespace NTar { -namespace NFileHeader { - - const char *kLongLink = "././@LongLink"; - const char *kLongLink2 = "@LongLink"; - - // The magic field is filled with this if uname and gname are valid. - namespace NMagic - { - // const char *kUsTar = "ustar"; // 5 chars - // const char *kGNUTar = "GNUtar "; // 7 chars and a null - // const char *kEmpty = "\0\0\0\0\0\0\0\0"; - const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ; - } - -}}} +// Archive/TarHeader.cpp + +#include "StdAfx.h" + +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { +namespace NFileHeader { + + const char * const kLongLink = "././@LongLink"; + const char * const kLongLink2 = "@LongLink"; + + // The magic field is filled with this if uname and gname are valid. + namespace NMagic + { + // const char * const kUsTar = "ustar"; // 5 chars + // 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 k_Posix_ustar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ; + // GNU TAR uses such header: + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarHeader.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,84 +1,90 @@ -// Archive/TarHeader.h - -#ifndef __ARCHIVE_TAR_HEADER_H -#define __ARCHIVE_TAR_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace NTar { - -namespace NFileHeader -{ - const unsigned kRecordSize = 512; - const unsigned kNameSize = 100; - const unsigned kUserNameSize = 32; - const unsigned kGroupNameSize = 32; - const unsigned kPrefixSize = 155; - - const unsigned kUstarMagic_Offset = 257; - - /* - struct CHeader - { - char Name[kNameSize]; - char Mode[8]; - char UID[8]; - char GID[8]; - char Size[12]; - char ModificationTime[12]; - char CheckSum[8]; - char LinkFlag; - char LinkName[kNameSize]; - char Magic[8]; - char UserName[kUserNameSize]; - char GroupName[kGroupNameSize]; - char DeviceMajor[8]; - char DeviceMinor[8]; - char Prefix[155]; - }; - union CRecord - { - CHeader Header; - Byte Padding[kRecordSize]; - }; - */ - - namespace NLinkFlag - { - const char kOldNormal = 0; // Normal disk file, Unix compatible - const char kNormal = '0'; // Normal disk file - const char kHardLink = '1'; // Link to previously dumped file - const char kSymLink = '2'; // Symbolic link - const char kCharacter = '3'; // Character special file - const char kBlock = '4'; // Block special file - const char kDirectory = '5'; // Directory - const char kFIFO = '6'; // FIFO special file - const char kContiguous = '7'; // Contiguous file - const char kGnu_LongLink = 'K'; - const char kGnu_LongName = 'L'; - const char kSparse = 'S'; - const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR. - data: list of files created by the --incremental (-G) option - Each file name is preceded by either - - 'Y' (file should be in this archive) - - '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. */ - } - - extern const char *kLongLink; // = "././@LongLink"; - extern const char *kLongLink2; // = "@LongLink"; - - namespace NMagic - { - // extern const char *kUsTar; // = "ustar"; // 5 chars - // extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null - // extern const char *kEmpty; // = "\0\0\0\0\0\0\0\0" - extern const char kUsTar_00[]; - } -} - -}} - -#endif +// Archive/TarHeader.h + +#ifndef ZIP7_INC_ARCHIVE_TAR_HEADER_H +#define ZIP7_INC_ARCHIVE_TAR_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace NTar { + +namespace NFileHeader +{ + const unsigned kRecordSize = 512; + const unsigned kNameSize = 100; + const unsigned kUserNameSize = 32; + const unsigned kGroupNameSize = 32; + const unsigned kPrefixSize = 155; + + const unsigned kUstarMagic_Offset = 257; + + /* + struct CHeader + { + char Name[kNameSize]; + char Mode[8]; + char UID[8]; + char GID[8]; + char Size[12]; + char ModificationTime[12]; + char CheckSum[8]; + char LinkFlag; + char LinkName[kNameSize]; + char Magic[8]; + char UserName[kUserNameSize]; + char GroupName[kGroupNameSize]; + char DeviceMajor[8]; + char DeviceMinor[8]; + char Prefix[155]; + }; + union CRecord + { + CHeader Header; + Byte Padding[kRecordSize]; + }; + */ + + namespace NLinkFlag + { + const char kOldNormal = 0; // Normal disk file, Unix compatible + const char kNormal = '0'; // Normal disk file + const char kHardLink = '1'; // Link to previously dumped file + const char kSymLink = '2'; // Symbolic link + const char kCharacter = '3'; // Character special file + const char kBlock = '4'; // Block special file + const char kDirectory = '5'; // Directory + const char kFIFO = '6'; // FIFO special file + const char kContiguous = '7'; // Contiguous file + const char kGnu_LongLink = 'K'; + 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 + - 'Y' (file should be in this archive) + - '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"; + extern const char * const kLongLink2; // = "@LongLink"; + + namespace NMagic + { + // 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 k_Posix_ustar_00[8]; + extern const char k_GNU_ustar[8]; + } +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarIn.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.cpp 2024-03-04 13:00:00.000000000 +0000 @@ -1,422 +1,1150 @@ -// TarIn.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/StringToInt.h" - -#include "../../Common/StreamUtils.h" - -#include "../IArchive.h" - -#include "TarIn.h" - -namespace NArchive { -namespace NTar { - -static void MyStrNCpy(char *dest, const char *src, unsigned size) -{ - for (unsigned i = 0; i < size; i++) - { - char c = src[i]; - dest[i] = c; - if (c == 0) - break; - } -} - -static bool OctalToNumber(const char *srcString, unsigned size, UInt64 &res) -{ - char sz[32]; - MyStrNCpy(sz, srcString, size); - sz[size] = 0; - const char *end; - unsigned i; - for (i = 0; sz[i] == ' '; i++); - res = ConvertOctStringToUInt64(sz + i, &end); - if (end == sz + i) - return false; - return (*end == ' ' || *end == 0); -} - -static bool OctalToNumber32(const char *srcString, unsigned size, UInt32 &res) -{ - UInt64 res64; - if (!OctalToNumber(srcString, size, res64)) - return false; - res = (UInt32)res64; - return (res64 <= 0xFFFFFFFF); -} - -#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) -{ - char temp[NFileHeader::kRecordSize + 1]; - MyStrNCpy(temp, s, size); - temp[size] = '\0'; - result = temp; -} - -static bool ParseInt64(const char *p, Int64 &val) -{ - UInt32 h = GetBe32(p); - val = GetBe64(p + 4); - 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 = uv; - return res; -} - -static bool ParseSize(const char *p, UInt64 &val) -{ - if (GetBe32(p) == (UInt32)1 << 31) - { - // GNU extension - val = GetBe64(p + 4); - return ((val >> 63) & 1) == 0; - } - return OctalToNumber(p, 12, val); -} - -#define CHECK(x) { if (!(x)) return k_IsArc_Res_NO; } - -API_FUNC_IsArc IsArc_Tar(const Byte *p2, size_t size) -{ - if (size < NFileHeader::kRecordSize) - return k_IsArc_Res_NEED_MORE; - - const char *p = (const char *)p2; - p += NFileHeader::kNameSize; - - UInt32 mode; - CHECK(OctalToNumber32(p, 8, mode)); p += 8; - - // if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; - p += 8; - // if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; - p += 8; - - UInt64 packSize; - Int64 time; - UInt32 checkSum; - CHECK(ParseSize(p, packSize)); p += 12; - CHECK(ParseInt64(p, time)); p += 12; - CHECK(OctalToNumber32(p, 8, checkSum)); - return k_IsArc_Res_YES; -} - -static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, EErrorType &error) -{ - char buf[NFileHeader::kRecordSize]; - char *p = buf; - - error = k_ErrorType_OK; - filled = false; - - bool thereAreEmptyRecords = false; - for (;;) - { - size_t processedSize = NFileHeader::kRecordSize; - RINOK(ReadStream(stream, buf, &processedSize)); - if (processedSize == 0) - { - if (!thereAreEmptyRecords) - error = k_ErrorType_UnexpectedEnd; // "There are no trailing zero-filled records"; - return S_OK; - } - if (processedSize != NFileHeader::kRecordSize) - { - if (!thereAreEmptyRecords) - error = k_ErrorType_UnexpectedEnd; // error = "There is no correct record at the end of archive"; - else - { - /* - if (IsEmptyData(buf, processedSize)) - error = k_ErrorType_UnexpectedEnd; - else - { - // extraReadSize = processedSize; - // error = k_ErrorType_Corrupted; // some data after the end tail zeros - } - */ - } - - return S_OK; - } - if (!IsRecordLast(buf)) - break; - item.HeaderSize += NFileHeader::kRecordSize; - thereAreEmptyRecords = true; - } - if (thereAreEmptyRecords) - { - // error = "There are data after end of archive"; - return S_OK; - } - - error = k_ErrorType_Corrupted; - ReadString(p, NFileHeader::kNameSize, item.Name); p += NFileHeader::kNameSize; - item.NameCouldBeReduced = - (item.Name.Len() == NFileHeader::kNameSize || - item.Name.Len() == NFileHeader::kNameSize - 1); - - RIF(OctalToNumber32(p, 8, item.Mode)); p += 8; - - if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8; - if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8; - - RIF(ParseSize(p, item.PackSize)); - item.Size = item.PackSize; - p += 12; - RIF(ParseInt64(p, item.MTime)); p += 12; - - UInt32 checkSum; - RIF(OctalToNumber32(p, 8, checkSum)); - memset(p, ' ', 8); p += 8; - - item.LinkFlag = *p++; - - ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; - item.LinkNameCouldBeReduced = - (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; - - if (p[0] != 0) - { - AString prefix; - ReadString(p, NFileHeader::kPrefixSize, prefix); - if (!prefix.IsEmpty() - && item.IsUstarMagic() - && (item.LinkFlag != 'L' /* || prefix != "00000000000" */ )) - item.Name = prefix + '/' + item.Name; - } - - p += NFileHeader::kPrefixSize; - - if (item.LinkFlag == NFileHeader::NLinkFlag::kHardLink) - { - item.PackSize = 0; - item.Size = 0; - } - /* - TAR standard requires sum of unsigned byte values. - But some 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++) - { - char c = buf[i]; - checkSumReal_Signed += (signed char)c; - checkSumReal += (Byte)buf[i]; - } - - if (checkSumReal != checkSum) - { - if ((UInt32)checkSumReal_Signed != checkSum) - return S_OK; - } - - item.HeaderSize += NFileHeader::kRecordSize; - - if (item.LinkFlag == NFileHeader::NLinkFlag::kSparse) - { - Byte isExtended = buf[482]; - if (isExtended != 0 && isExtended != 1) - return S_OK; - RIF(ParseSize(buf + 483, item.Size)); - UInt64 min = 0; - for (unsigned i = 0; i < 4; i++) - { - p = buf + 386 + 24 * i; - if (GetBe32(p) == 0) - { - if (isExtended != 0) - return S_OK; - break; - } - CSparseBlock sb; - RIF(ParseSize(p, sb.Offset)); - RIF(ParseSize(p + 12, sb.Size)); - item.SparseBlocks.Add(sb); - if (sb.Offset < min || sb.Offset > item.Size) - return S_OK; - if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0) - return S_OK; - min = sb.Offset + sb.Size; - if (min < sb.Offset) - return S_OK; - } - if (min > item.Size) - return S_OK; - - while (isExtended != 0) - { - size_t processedSize = NFileHeader::kRecordSize; - RINOK(ReadStream(stream, buf, &processedSize)); - if (processedSize != NFileHeader::kRecordSize) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - - item.HeaderSize += NFileHeader::kRecordSize; - isExtended = buf[21 * 24]; - if (isExtended != 0 && isExtended != 1) - return S_OK; - for (unsigned i = 0; i < 21; i++) - { - p = buf + 24 * i; - if (GetBe32(p) == 0) - { - if (isExtended != 0) - return S_OK; - break; - } - CSparseBlock sb; - RIF(ParseSize(p, sb.Offset)); - RIF(ParseSize(p + 12, sb.Size)); - item.SparseBlocks.Add(sb); - if (sb.Offset < min || sb.Offset > item.Size) - return S_OK; - if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0) - return S_OK; - min = sb.Offset + sb.Size; - if (min < sb.Offset) - return S_OK; - } - } - if (min > item.Size) - return S_OK; - } - - filled = true; - error = k_ErrorType_OK; - return S_OK; -} - -HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErrorType &error) -{ - item.HeaderSize = 0; - bool flagL = false; - bool flagK = false; - AString nameL; - AString nameK; - - for (;;) - { - RINOK(GetNextItemReal(stream, filled, item, error)); - if (!filled) - { - if (error == k_ErrorType_OK && (flagL || flagK)) - 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 - { - 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; } - - if (item.Name != NFileHeader::kLongLink && - item.Name != NFileHeader::kLongLink2) - return S_OK; - if (item.PackSize > (1 << 14)) - return S_OK; - unsigned packSize = (unsigned)item.GetPackSizeAligned(); - char *buf = name->GetBuf(packSize); - size_t processedSize = packSize; - HRESULT res = ReadStream(stream, buf, &processedSize); - item.HeaderSize += (unsigned)processedSize; - name->ReleaseBuf_CalcLen((unsigned)item.PackSize); - RINOK(res); - if (processedSize != packSize) - { - error = k_ErrorType_UnexpectedEnd; - return S_OK; - } - continue; - } - - switch (item.LinkFlag) - { - case 'g': - case 'x': - case 'X': - { - // pax Extended Header - break; - } - case NFileHeader::NLinkFlag::kDumpDir: - { - break; - // GNU Extensions to the Archive Format - } - case NFileHeader::NLinkFlag::kSparse: - { - break; - // GNU Extensions to the Archive Format - } - default: - if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0)) - return S_OK; - } - - if (flagL) - { - item.Name = nameL; - item.NameCouldBeReduced = false; - } - - if (flagK) - { - item.LinkName = nameK; - item.LinkNameCouldBeReduced = false; - } - - error = k_ErrorType_OK; - return S_OK; - } -} - -}} +// TarIn.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/StringToInt.h" + +#include "../../Common/StreamUtils.h" + +#include "../IArchive.h" + +#include "TarIn.h" + +#define NUM_UNROLL_BYTES (8 * 4) + +Z7_NO_INLINE static bool IsBufNonZero(const void *data, size_t size); +Z7_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 { + +static void MyStrNCpy(char *dest, const char *src, unsigned size) +{ + for (unsigned i = 0; i < size; i++) + { + char c = src[i]; + dest[i] = c; + if (c == 0) + break; + } +} + +static bool OctalToNumber(const char *srcString, unsigned size, UInt64 &res, bool allowEmpty = false) +{ + res = 0; + char sz[32]; + MyStrNCpy(sz, srcString, size); + sz[size] = 0; + const char *end; + unsigned i; + for (i = 0; sz[i] == ' '; i++); + if (sz[i] == 0) + return allowEmpty; + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *srcString, UInt32 &res, bool allowEmpty = false) +{ + const unsigned kSize = 8; + UInt64 res64; + if (!OctalToNumber(srcString, kSize, res64, allowEmpty)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + +#define RIF(x) { if (!(x)) return S_OK; } + +static void ReadString(const char *s, unsigned size, AString &result) +{ + result.SetFrom_CalcLen(s, size); +} + +static bool ParseInt64(const char *p, Int64 &val, bool &isBin) +{ + 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; + 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, 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, isBin); + val = 0; + return true; +} + +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) +{ + if (size < NFileHeader::kRecordSize) + return k_IsArc_Res_NEED_MORE; + + const char *p = (const char *)p2; + p += NFileHeader::kNameSize; + + UInt32 mode; + // we allow empty Mode value for LongName prefix items + CHECK(OctalToNumber32(p, mode, true)) p += 8; + + // if (!OctalToNumber32(p, item.UID)) item.UID = 0; + p += 8; + // if (!OctalToNumber32(p, item.GID)) item.GID = 0; + p += 8; + + UInt64 packSize; + Int64 time; + UInt32 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; +} + + +HRESULT CArchive::GetNextItemReal(CItemEx &item) +{ + char buf[NFileHeader::kRecordSize]; + + error = k_ErrorType_OK; + filled = false; + + bool thereAreEmptyRecords = false; + for (;;) + { + size_t processedSize = NFileHeader::kRecordSize; + RINOK(ReadStream(SeqStream, buf, &processedSize)) + if (processedSize == 0) + { + if (!thereAreEmptyRecords) + error = k_ErrorType_UnexpectedEnd; // "There are no trailing zero-filled records"; + return S_OK; + } + if (processedSize != NFileHeader::kRecordSize) + { + if (!thereAreEmptyRecords) + error = k_ErrorType_UnexpectedEnd; // error = "There is no correct record at the end of archive"; + else + { + /* + if (IsEmptyData(buf, processedSize)) + error = k_ErrorType_UnexpectedEnd; + else + { + // extraReadSize = processedSize; + // error = k_ErrorType_Corrupted; // some data after the end tail zeros + } + */ + } + + return S_OK; + } + if (IsBufNonZero(buf, NFileHeader::kRecordSize)) + break; + item.HeaderSize += NFileHeader::kRecordSize; + thereAreEmptyRecords = true; + if (OpenCallback) + { + RINOK(Progress(item, 0)) + } + } + if (thereAreEmptyRecords) + { + // error = "There are data after end of archive"; + return S_OK; + } + + char *p = buf; + + error = k_ErrorType_Corrupted; + + // 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, item.Mode, true)) 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, item.PackSize_IsBin)) + item.Size = item.PackSize; + item.Size_IsBin = item.PackSize_IsBin; + p += 12; + RIF(ParseInt64_MTime(p, item.MTime, item.MTime_IsBin)) p += 12; + + UInt32 checkSum; + RIF(OctalToNumber32(p, checkSum)) + memset(p, ' ', 8); p += 8; + + item.LinkFlag = *p++; + + ReadString(p, NFileHeader::kNameSize, item.LinkName); p += NFileHeader::kNameSize; + + /* + 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.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 + && item.IsMagic_ustar_5chars() + && (item.LinkFlag != 'L' )) + { + item.Prefix_WasUsed = true; + ReadString(p, NFileHeader::kPrefixSize, item.Name); + item.Name.Add_Slash(); + 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) + { + item.PackSize = 0; + item.Size = 0; + } + + if (item.LinkFlag == NFileHeader::NLinkFlag::kDirectory) + { + // GNU tar ignores Size field, if LinkFlag is kDirectory + // 21.02 : we set PackSize = 0 to be more compatible with GNU tar + item.PackSize = 0; + // item.Size = 0; + } + + /* + TAR standard requires sum of unsigned byte values. + But some old TAR programs use sum of signed byte values. + So we check both values. + */ + // for (int y = 0; y < 100; y++) // for debug + { + 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; + + if (item.LinkFlag == NFileHeader::NLinkFlag::kSparse) + { + Byte isExtended = (Byte)buf[482]; + if (isExtended != 0 && isExtended != 1) + return S_OK; + RIF(ParseSize(buf + 483, item.Size, item.Size_IsBin)) + UInt64 min = 0; + for (unsigned i = 0; i < 4; i++) + { + p = buf + 386 + 24 * i; + if (GetBe32(p) == 0) + { + if (isExtended != 0) + return S_OK; + break; + } + CSparseBlock sb; + RIF(ParseSize(p, sb.Offset)) + RIF(ParseSize(p + 12, sb.Size)) + item.SparseBlocks.Add(sb); + if (sb.Offset < min || sb.Offset > item.Size) + return S_OK; + if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0) + return S_OK; + min = sb.Offset + sb.Size; + if (min < sb.Offset) + return S_OK; + } + if (min > item.Size) + return S_OK; + + while (isExtended != 0) + { + size_t processedSize = NFileHeader::kRecordSize; + RINOK(ReadStream(SeqStream, buf, &processedSize)) + if (processedSize != NFileHeader::kRecordSize) + { + error = k_ErrorType_UnexpectedEnd; + return S_OK; + } + + item.HeaderSize += NFileHeader::kRecordSize; + + if (OpenCallback) + { + RINOK(Progress(item, 0)) + } + + isExtended = (Byte)buf[21 * 24]; + if (isExtended != 0 && isExtended != 1) + return S_OK; + for (unsigned i = 0; i < 21; i++) + { + p = buf + 24 * i; + if (GetBe32(p) == 0) + { + if (isExtended != 0) + return S_OK; + break; + } + CSparseBlock sb; + RIF(ParseSize(p, sb.Offset)) + RIF(ParseSize(p + 12, sb.Size)) + item.SparseBlocks.Add(sb); + if (sb.Offset < min || sb.Offset > item.Size) + return S_OK; + if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0) + return S_OK; + min = sb.Offset + sb.Size; + if (min < sb.Offset) + return S_OK; + } + } + if (min > item.Size) + return S_OK; + } + + if (item.PackSize >= (UInt64)1 << 63) + return S_OK; + + filled = true; + error = k_ErrorType_OK; + return S_OK; +} + + +HRESULT CArchive::Progress(const CItemEx &item, UInt64 posOffset) +{ + 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; +} + + + +struct CPaxInfo: public CPaxTimes +{ + 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; + bool SCHILY_fflags_Defined; + + UInt64 Size; + UInt32 UID; + UInt32 GID; + + AString Path; + AString Link; + AString User; + AString Group; + AString UnknownLines; + AString SCHILY_fflags; + + bool ParseID(const AString &val, bool &defined, UInt32 &res) + { + if (defined) + DoubleTagError = true; + if (val.IsEmpty()) + return false; + const char *end2; + res = ConvertStringToUInt32(val.Ptr(), &end2); + if (*end2 != 0) + return false; + 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 (sec >= ((UInt64)1 << 63)) + return false; + if (isNegative) + sec = (UInt64)-(Int64)sec; + pt.Sec = (Int64)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; + // we ignore digits after 9 digits as GNU TAR + if (i < kNsDigits) + { + ns *= 10; + ns += (unsigned)(c - '0'); + } + } + pt.NumDigits = (int)(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; + SCHILY_fflags_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++) + { + if (i > 24 || i >= rem) // we use limitation for size of (size) field + return false; + 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; + + 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, (unsigned)(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 if (name.IsEqualTo("SCHILY.fflags")) + { + if (SCHILY_fflags_Defined) + DoubleTagError = true; + SCHILY_fflags = val; + SCHILY_fflags_Defined = true; + parsed = true; + } + else + isDetectedName = false; + if (isDetectedName && !parsed) + TagParsingError = true; + } + 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 CArchive::ReadItem2(CItemEx &item) +{ + // CItem + + item.SparseBlocks.Clear(); + item.PaxTimes.Clear(); + + // CItemEx + + item.HeaderSize = 0; + item.Num_Pax_Records = 0; + + 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; + + 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.SCHILY_fflags.Empty(); + + item.EncodingCharacts.Clear(); + + // CArchive temp variable + + NameBuf.Init(); + LinkBuf.Init(); + PaxBuf.Init(); + PaxBuf_global.Init(); + + UInt64 numExtraRecords = 0; + + for (;;) + { + if (OpenCallback) + { + RINOK(Progress(item, 0)) + } + + RINOK(GetNextItemReal(item)) + + // NumRecords++; + + if (!filled) + { + if (error == k_ErrorType_OK) + if (numExtraRecords != 0 + || 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; + + numExtraRecords++; + + const char lf = item.LinkFlag; + if (lf == NFileHeader::NLinkFlag::kGnu_LongName || + lf == NFileHeader::NLinkFlag::kGnu_LongLink) + { + // 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; + } + */ + + 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; + } + + if (lf == NFileHeader::NLinkFlag::kGlobal || + lf == NFileHeader::NLinkFlag::kPax || + lf == NFileHeader::NLinkFlag::kPax_2) + { + // GNU tar ignores item.Name after LinkFlag test + // 22.00 : now we also ignore item.Name here + /* + if (item.PackSize > (UInt32)1 << 26) + { + break; // we don't want big PaxBuf files + // return S_OK; + } + */ + 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) + { + item.PaxExtra.RecordPath = item.Name; + continue; + } + // break; // for debug + { + 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 + && item.Num_Pax_Records == 1 + && numExtraRecords == 1) + { + // we skip global pax header info after parsing + item.HeaderPos += item.HeaderSize; + item.HeaderSize = 0; + item.Num_Pax_Records = 0; + numExtraRecords = 0; + } + else + _is_PaxGlobal_Error = true; + } + continue; + } + + /* + if (lf == NFileHeader::NLinkFlag::kDumpDir || + lf == NFileHeader::NLinkFlag::kSparse) + { + // GNU Extensions to the Archive Format + break; + } + if (lf > '7' || (lf < '0' && lf != 0)) + { + break; + // return S_OK; + } + */ + 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 + { + 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.SCHILY_fflags_Defined) + { + item.SCHILY_fflags = paxInfo.SCHILY_fflags; + // item.SCHILY_fflags_WasUsed = true; + } + if (paxInfo.UID_Defined) + { + item.UID = (UInt32)paxInfo.UID; + } + 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; +} + + + +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.SCHILY_fflags.IsEmpty()) _are_SCHILY_fflags = 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarIn.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarIn.h 2024-03-04 11:00:00.000000000 +0000 @@ -1,26 +1,151 @@ -// TarIn.h - -#ifndef __ARCHIVE_TAR_IN_H -#define __ARCHIVE_TAR_IN_H - -#include "../../IStream.h" - -#include "TarItem.h" - -namespace NArchive { -namespace NTar { - -enum EErrorType -{ - k_ErrorType_OK, - k_ErrorType_Corrupted, - k_ErrorType_UnexpectedEnd, -}; - -HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo, EErrorType &error); - -API_FUNC_IsArc IsArc_Tar(const Byte *p, size_t size); - -}} - -#endif +// TarIn.h + +#ifndef ZIP7_INC_ARCHIVE_TAR_IN_H +#define ZIP7_INC_ARCHIVE_TAR_IN_H + +#include "../IArchive.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +enum EErrorType +{ + k_ErrorType_OK, + k_ErrorType_Corrupted, + 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 _are_SCHILY_fflags; + // 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; + _are_SCHILY_fflags = 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); +}; + + +API_FUNC_IsArc IsArc_Tar(const Byte *p, size_t size); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarItem.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarItem.h 2024-03-04 11:00:00.000000000 +0000 @@ -1,98 +1,364 @@ -// TarItem.h - -#ifndef __ARCHIVE_TAR_ITEM_H -#define __ARCHIVE_TAR_ITEM_H - -#include "../Common/ItemNameUtils.h" - -#include "TarHeader.h" - -namespace NArchive { -namespace NTar { - -struct CSparseBlock -{ - UInt64 Offset; - UInt64 Size; -}; - -struct CItem -{ - AString Name; - UInt64 PackSize; - UInt64 Size; - Int64 MTime; - - UInt32 Mode; - UInt32 UID; - UInt32 GID; - UInt32 DeviceMajor; - UInt32 DeviceMinor; - - AString LinkName; - AString User; - AString Group; - - char Magic[8]; - char LinkFlag; - bool DeviceMajorDefined; - bool DeviceMinorDefined; - - CRecordVector SparseBlocks; - - 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 - { - switch (LinkFlag) - { - case 'g': - case 'x': - case 'X': // Check it - return true; - } - return false; - } - - bool IsDir() const - { - switch (LinkFlag) - { - case NFileHeader::NLinkFlag::kDirectory: - case NFileHeader::NLinkFlag::kDumpDir: - return true; - case NFileHeader::NLinkFlag::kOldNormal: - case NFileHeader::NLinkFlag::kNormal: - case NFileHeader::NLinkFlag::kSymLink: - return NItemName::HasTailSlash(Name, CP_OEMCP); - } - return false; - } - - bool IsUstarMagic() const - { - for (int i = 0; i < 5; i++) - if (Magic[i] != NFileHeader::NMagic::kUsTar_00[i]) - return false; - return true; - } - - UInt64 GetPackSizeAligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); } -}; - -struct CItemEx: public CItem -{ - UInt64 HeaderPos; - unsigned HeaderSize; - bool NameCouldBeReduced; - bool LinkNameCouldBeReduced; - - UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } - UInt64 GetFullSize() const { return HeaderSize + PackSize; } -}; - -}} - -#endif +// TarItem.h + +#ifndef ZIP7_INC_ARCHIVE_TAR_ITEM_H +#define ZIP7_INC_ARCHIVE_TAR_ITEM_H + +#include "../../../Common/MyLinux.h" +#include "../../../Common/UTFConvert.h" + +#include "TarHeader.h" + +namespace NArchive { +namespace NTar { + +struct CSparseBlock +{ + UInt64 Offset; + 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 +{ + 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]; + + CPaxTimes PaxTimes; + + CRecordVector SparseBlocks; + + void SetMagic_Posix(bool posixMode) + { + memcpy(Magic, posixMode ? + NFileHeader::NMagic::k_Posix_ustar_00 : + NFileHeader::NMagic::k_GNU_ustar, + 8); + } + + 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 NFileHeader::NLinkFlag::kPax: + case NFileHeader::NLinkFlag::kPax_2: + case NFileHeader::NLinkFlag::kGlobal: + return true; + default: break; + } + return false; + } + + UInt32 Get_Combined_Mode() const + { + return (Mode & ~(UInt32)MY_LIN_S_IFMT) | Get_FileTypeMode_from_LinkFlag(); + } + + void Set_LinkFlag_for_File(UInt32 mode) + { + char 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 + { + switch (LinkFlag) + { + /* + case NFileHeader::NLinkFlag::kDirectory: + 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 return MY_LIN_S_IFSOCK; + default: break; + } + + if (IsDir()) + return MY_LIN_S_IFDIR; + return MY_LIN_S_IFREG; + } + + bool IsDir() const + { + switch (LinkFlag) + { + case NFileHeader::NLinkFlag::kDirectory: + case NFileHeader::NLinkFlag::kDumpDir: + return true; + case NFileHeader::NLinkFlag::kOldNormal: + case NFileHeader::NLinkFlag::kNormal: + case NFileHeader::NLinkFlag::kSymLink: + 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); + default: break; + } + return false; + } + + 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 (unsigned i = 0; i < 8; i++) + if (Magic[i] != NFileHeader::NMagic::k_GNU_ustar[i]) + return false; + return true; + } + + UInt64 Get_PackSize_Aligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); } + + bool IsThereWarning() const + { + // that Header Warning is possible if (Size != 0) for dir item + return (PackSize < Size) && (LinkFlag == NFileHeader::NLinkFlag::kDirectory); + } +}; + + + +struct CEncodingCharacts +{ + bool IsAscii; + // bool Oem_Checked; + // bool Oem_Ok; + // bool Utf_Checked; + CUtf8Check UtfCheck; + + void Clear() + { + IsAscii = true; + // Oem_Checked = false; + // Oem_Ok = false; + // Utf_Checked = false; + UtfCheck.Clear(); + } + + void Update(const CEncodingCharacts &ec) + { + if (!ec.IsAscii) + IsAscii = false; + + // if (ec.Utf_Checked) + { + UtfCheck.Update(ec.UtfCheck); + // Utf_Checked = true; + } + } + + CEncodingCharacts() { Clear(); } + void Check(const AString &s); + AString GetCharactsString() const; +}; + + +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; + UInt64 HeaderSize; + + UInt64 Num_Pax_Records; + CPaxExtra PaxExtra; + AString SCHILY_fflags; + + CEncodingCharacts EncodingCharacts; + + UInt64 Get_DataPos() const { return HeaderPos + HeaderSize; } + // UInt64 GetFullSize() const { return HeaderSize + PackSize; } + UInt64 Get_FullSize_Aligned() const { return HeaderSize + Get_PackSize_Aligned(); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarOut.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.cpp 2023-12-11 13:00:00.000000000 +0000 @@ -1,245 +1,644 @@ -// TarOut.cpp - -#include "StdAfx.h" - -#include "../../Common/StreamUtils.h" - -#include "TarOut.h" - -namespace NArchive { -namespace NTar { - -HRESULT COutArchive::WriteBytes(const void *data, unsigned size) -{ - Pos += size; - return WriteStream(m_Stream, data, size); -} - -static void MyStrNCpy(char *dest, const char *src, unsigned size) -{ - for (unsigned i = 0; i < size; i++) - { - char c = src[i]; - dest[i] = c; - if (c == 0) - break; - } -} - -static bool WriteOctal_8(char *s, UInt32 val) -{ - const unsigned kNumDigits = 8 - 1; - if (val >= ((UInt32)1 << (kNumDigits * 3))) - return false; - for (unsigned i = 0; i < kNumDigits; i++) - { - s[kNumDigits - 1 - i] = (char)('0' + (val & 7)); - val >>= 3; - } - return true; -} - -static void WriteOctal_12(char *s, UInt64 val) -{ - const unsigned kNumDigits = 12 - 1; - if (val >= ((UInt64)1 << (kNumDigits * 3))) - { - // GNU extension; - s[0] = (char)(Byte)0x80; - s[1] = s[2] = s[3] = 0; - for (unsigned i = 0; i < 8; i++, val <<= 8) - s[4 + i] = (char)(val >> 56); - return; - } - for (unsigned i = 0; i < kNumDigits; i++) - { - s[kNumDigits - 1 - i] = (char)('0' + (val & 7)); - val >>= 3; - } -} - -static void WriteOctal_12_Signed(char *s, Int64 val) -{ - if (val >= 0) - { - WriteOctal_12(s, val); - return; - } - s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF; - for (unsigned i = 0; i < 8; i++, val <<= 8) - s[4 + i] = (char)(val >> 56); -} - -static bool CopyString(char *dest, const AString &src, unsigned maxSize) -{ - if (src.Len() >= maxSize) - return false; - MyStringCopy(dest, (const char *)src); - return true; -} - -#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; } - -HRESULT COutArchive::WriteHeaderReal(const CItem &item) -{ - char record[NFileHeader::kRecordSize]; - memset(record, 0, NFileHeader::kRecordSize); - char *cur = record; - - if (item.Name.Len() > NFileHeader::kNameSize) - return E_FAIL; - MyStrNCpy(cur, item.Name, NFileHeader::kNameSize); - cur += NFileHeader::kNameSize; - - RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.Mode)); cur += 8; - RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.UID)); cur += 8; - RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.GID)); cur += 8; - - WriteOctal_12(cur, item.PackSize); cur += 12; - WriteOctal_12_Signed(cur, item.MTime); cur += 12; - - memset(cur, ' ', 8); - cur += 8; - - *cur++ = item.LinkFlag; - - RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize)); - cur += NFileHeader::kNameSize; - - memcpy(cur, item.Magic, 8); - cur += 8; - - RETURN_IF_NOT_TRUE(CopyString(cur, item.User, NFileHeader::kUserNameSize)); - cur += NFileHeader::kUserNameSize; - RETURN_IF_NOT_TRUE(CopyString(cur, item.Group, NFileHeader::kGroupNameSize)); - cur += NFileHeader::kGroupNameSize; - - - if (item.DeviceMajorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMajor)); cur += 8; - if (item.DeviceMinorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMinor)); cur += 8; - - if (item.IsSparse()) - { - record[482] = (char)(item.SparseBlocks.Size() > 4 ? 1 : 0); - WriteOctal_12(record + 483, item.Size); - for (unsigned i = 0; i < item.SparseBlocks.Size() && i < 4; i++) - { - const CSparseBlock &sb = item.SparseBlocks[i]; - char *p = record + 386 + 24 * i; - WriteOctal_12(p, sb.Offset); - WriteOctal_12(p + 12, sb.Size); - } - } - - { - UInt32 checkSum = 0; - { - for (unsigned i = 0; i < NFileHeader::kRecordSize; i++) - checkSum += (Byte)record[i]; - } - /* we use GNU TAR scheme: - checksum field is formatted differently from the - other fields: it has [6] digits, a null, then a space. */ - // RETURN_IF_NOT_TRUE(WriteOctal_8(record + 148, checkSum)); - const unsigned kNumDigits = 6; - for (unsigned i = 0; i < kNumDigits; i++) - { - record[148 + kNumDigits - 1 - i] = (char)('0' + (checkSum & 7)); - checkSum >>= 3; - } - record[148 + 6] = 0; - } - - RINOK(WriteBytes(record, NFileHeader::kRecordSize)); - - if (item.IsSparse()) - { - for (unsigned i = 4; i < item.SparseBlocks.Size();) - { - memset(record, 0, NFileHeader::kRecordSize); - for (unsigned t = 0; t < 21 && i < item.SparseBlocks.Size(); t++, i++) - { - const CSparseBlock &sb = item.SparseBlocks[i]; - char *p = record + 24 * t; - WriteOctal_12(p, sb.Offset); - WriteOctal_12(p + 12, sb.Size); - } - record[21 * 24] = (char)(i < item.SparseBlocks.Size() ? 1 : 0); - RINOK(WriteBytes(record, NFileHeader::kRecordSize)); - } - } - - return S_OK; -} - -HRESULT COutArchive::WriteHeader(const CItem &item) -{ - unsigned nameSize = item.Name.Len(); - unsigned linkSize = item.LinkName.Len(); - - /* There two versions of GNU tar: - OLDGNU_FORMAT: it writes short name and zero at the end - GNU_FORMAT: it writes only short name without zero at the end - we write it as OLDGNU_FORMAT with zero at the end */ - - if (nameSize < NFileHeader::kNameSize && - linkSize < NFileHeader::kNameSize) - return WriteHeaderReal(item); - - CItem mi = item; - mi.Name = NFileHeader::kLongLink; - mi.LinkName.Empty(); - for (int i = 0; i < 2; i++) - { - const AString *name; - // We suppose that GNU tar also writes item for long link before item for LongName? - if (i == 0) - { - mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongLink; - name = &item.LinkName; - } - else - { - mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongName; - name = &item.Name; - } - if (name->Len() < NFileHeader::kNameSize) - continue; - unsigned nameStreamSize = name->Len() + 1; - mi.PackSize = nameStreamSize; - RINOK(WriteHeaderReal(mi)); - RINOK(WriteBytes((const char *)*name, nameStreamSize)); - RINOK(FillDataResidual(nameStreamSize)); - } - - mi = item; - if (mi.Name.Len() >= NFileHeader::kNameSize) - mi.Name.SetFrom(item.Name, NFileHeader::kNameSize - 1); - if (mi.LinkName.Len() >= NFileHeader::kNameSize) - mi.LinkName.SetFrom(item.LinkName, NFileHeader::kNameSize - 1); - return WriteHeaderReal(mi); -} - -HRESULT COutArchive::FillDataResidual(UInt64 dataSize) -{ - unsigned lastRecordSize = ((unsigned)dataSize & (NFileHeader::kRecordSize - 1)); - if (lastRecordSize == 0) - return S_OK; - unsigned rem = NFileHeader::kRecordSize - lastRecordSize; - Byte buf[NFileHeader::kRecordSize]; - memset(buf, 0, rem); - return WriteBytes(buf, rem); -} - -HRESULT COutArchive::WriteFinishHeader() -{ - Byte record[NFileHeader::kRecordSize]; - memset(record, 0, NFileHeader::kRecordSize); - for (unsigned i = 0; i < 2; i++) - { - RINOK(WriteBytes(record, NFileHeader::kRecordSize)); - } - return S_OK; -} - -}} +// TarOut.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" + +#include "../../../Common/IntToString.h" + +#include "../../Common/StreamUtils.h" + +#include "TarOut.h" + +namespace NArchive { +namespace NTar { + +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 void WriteOctal_8(char *s, UInt32 val) +{ + const unsigned kNumDigits = 8 - 1; + if (val >= ((UInt32)1 << (kNumDigits * 3))) + { + val = 0; + // return false; + } + for (unsigned i = 0; i < kNumDigits; i++) + { + s[kNumDigits - 1 - i] = (char)('0' + (val & 7)); + val >>= 3; + } + // return true; +} + +static void WriteBin_64bit(char *s, UInt64 val) +{ + for (unsigned i = 0; i < 8; i++, val <<= 8) + s[i] = (char)(val >> 56); +} + +static void WriteOctal_12(char *s, UInt64 val) +{ + const unsigned kNumDigits = 12 - 1; + if (val >= ((UInt64)1 << (kNumDigits * 3))) + { + // GNU extension; + s[0] = (char)(Byte)0x80; + s[1] = s[2] = s[3] = 0; + WriteBin_64bit(s + 4, val); + return; + } + for (unsigned i = 0; i < kNumDigits; i++) + { + s[kNumDigits - 1 - i] = (char)('0' + (val & 7)); + val >>= 3; + } +} + +static void WriteOctal_12_Signed(char *s, const Int64 val) +{ + if (val >= 0) + { + WriteOctal_12(s, (UInt64)val); + return; + } + s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF; + WriteBin_64bit(s + 4, (UInt64)val); +} + +static void CopyString(char *dest, const AString &src, const unsigned maxSize) +{ + unsigned len = src.Len(); + if (len == 0) + return; + // 21.07: new gnu : we don't require additional 0 character at the end + // if (len >= maxSize) + if (len > maxSize) + { + len = maxSize; + /* + // oldgnu needs 0 character at the end + len = maxSize - 1; + dest[len] = 0; + */ + } + memcpy(dest, src.Ptr(), len); +} + +// #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)) + + +HRESULT COutArchive::WriteHeaderReal(const CItem &item, bool isPax + // , bool zero_PackSize + // , bool zero_MTime + ) +{ + /* + 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, + (!isPax && !Glob_Name.IsEmpty()) ? Glob_Name : item.Name, + kNameSize) + + 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, /* zero_PackSize ? 0 : */ item.PackSize); cur += 12; + WriteOctal_12_Signed (cur, /* zero_MTime ? 0 : */ item.MTime); cur += 12; + + // 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, kNameSize) + + memcpy(cur, item.Magic, 8); + cur += 8; + + COPY_STRING_CHECK (cur, item.User, kUserNameSize) + COPY_STRING_CHECK (cur, item.Group, kGroupNameSize) + + 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.DeviceMinor_Defined) + WRITE_OCTAL_8_CHECK (cur, item.DeviceMinor) + else if (needDevice) + WRITE_OCTAL_8_CHECK (cur, 0) + cur += 8; + + 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); + for (unsigned i = 0; i < item.SparseBlocks.Size() && i < 4; i++) + { + const CSparseBlock &sb = item.SparseBlocks[i]; + char *p = record + 386 + 24 * i; + WriteOctal_12(p, sb.Offset); + WriteOctal_12(p + 12, sb.Size); + } + } + + { + UInt32 sum = (unsigned)(' ') * 8; // we use binary init + { + for (unsigned i = 0; i < kRecordSize; i++) + sum += (Byte)record[i]; + } + /* checksum field is formatted differently from the + other fields: it has [6] digits, a null, then a space. */ + // 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' + (sum & 7)); + sum >>= 3; + } + // record[148 + 6] = 0; // we need it, if we use memset(' ') init + record[148 + 7] = ' '; // we need it, if we use binary init + } + + RINOK(Write_Data(record, kRecordSize)) + + if (item.Is_Sparse()) + { + for (unsigned i = 4; i < item.SparseBlocks.Size();) + { + memset(record, 0, kRecordSize); + for (unsigned t = 0; t < 21 && i < item.SparseBlocks.Size(); t++, i++) + { + const CSparseBlock &sb = item.SparseBlocks[i]; + char *p = record + 24 * t; + WriteOctal_12(p, sb.Offset); + WriteOctal_12(p + 12, sb.Size); + } + record[21 * 24] = (char)(i < item.SparseBlocks.Size() ? 1 : 0); + RINOK(Write_Data(record, kRecordSize)) + } + } + + return S_OK; +} + + +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.Add_Char('='); + s += val; + s.Add_LF(); +} + +// pt is defined : (pt.NumDigits >= 0) +static void AddPaxTime(AString &s, const char *name, const CPaxTime &pt, + const CTimeOptions &options) +{ + unsigned numDigits = (unsigned)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.Add_Minus(); + if (ns != 0) + { + ns = 1000*1000*1000 - ns; + sec--; + } + } + v.Add_UInt64((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.Add_Dot(); + 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 = + 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) +{ + Glob_Name.Empty(); + Prefix.Empty(); + + 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; + } + + 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) */ + } + } + + 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)) + { + // 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++) + { + 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 + { + 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(); + } + } + Glob_Name.AddFrom(item.Name.Ptr(namePos), nameLen); + } + + return WriteHeaderReal(item); +} + + +HRESULT COutArchive::Write_Data(const void *data, unsigned size) +{ + 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; + const unsigned rem = kRecordSize - v; + Byte buf[kRecordSize]; + memset(buf, 0, 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[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 / 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(Write_Data(record, kRecordSize)) + } + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarOut.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarOut.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarOut.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,36 +1,53 @@ -// Archive/TarOut.h - -#ifndef __ARCHIVE_TAR_OUT_H -#define __ARCHIVE_TAR_OUT_H - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -#include "TarItem.h" - -namespace NArchive { -namespace NTar { - -class COutArchive -{ - CMyComPtr m_Stream; - - HRESULT WriteBytes(const void *data, unsigned size); - HRESULT WriteHeaderReal(const CItem &item); -public: - UInt64 Pos; - - void Create(ISequentialOutStream *outStream) - { - m_Stream = outStream; - } - - HRESULT WriteHeader(const CItem &item); - HRESULT FillDataResidual(UInt64 dataSize); - HRESULT WriteFinishHeader(); -}; - -}} - -#endif +// Archive/TarOut.h + +#ifndef ZIP7_INC_ARCHIVE_TAR_OUT_H +#define ZIP7_INC_ARCHIVE_TAR_OUT_H + +#include "../../../Common/MyCom.h" + +#include "../../IStream.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +class COutArchive +{ + 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); + +public: + UInt64 Pos; + bool IsPosixMode; + // bool IsPrefixAllowed; // it's used only if (IsPosixMode == true) + CTimeOptions TimeOptions; + + void Create(ISequentialOutStream *outStream) + { + Stream = outStream; + } + HRESULT WriteHeader(const CItem &item); + HRESULT Write_AfterDataResidual(UInt64 dataSize); + HRESULT WriteFinishHeader(); + + COutArchive(): + Pos(0), + IsPosixMode(false) + // , IsPrefixAllowed(true) + {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarRegister.cpp 2015-09-17 19:02:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,23 +1,31 @@ -// TarRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "TarHandler.h" - -namespace NArchive { -namespace NTar { - -static const Byte k_Signature[] = { 'u', 's', 't', 'a', 'r' }; - -REGISTER_ARC_IO( - "tar", "tar ova", 0, 0xEE, - k_Signature, - NFileHeader::kUstarMagic_Offset, - NArcInfoFlags::kStartOpen | - NArcInfoFlags::kSymLinks | - NArcInfoFlags::kHardLinks, - IsArc_Tar) - -}} +// TarRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "TarHandler.h" + +namespace NArchive { +namespace NTar { + +static const Byte k_Signature[] = { 'u', 's', 't', 'a', 'r' }; + +REGISTER_ARC_IO( + "tar", "tar ova", NULL, 0xEE, + k_Signature, + NFileHeader::kUstarMagic_Offset, + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarUpdate.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarUpdate.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.cpp 2024-02-19 13:00:00.000000000 +0000 @@ -1,266 +1,563 @@ -// TarUpdate.cpp - -#include "StdAfx.h" - -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "TarOut.h" -#include "TarUpdate.h" - -namespace NArchive { -namespace NTar { - -HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, - AString &res, UINT codePage, bool convertSlash = false); - -HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, - const CObjectVector &inputItems, - const CObjectVector &updateItems, - UINT codePage, - IArchiveUpdateCallback *updateCallback) -{ - COutArchive outArchive; - outArchive.Create(outStream); - outArchive.Pos = 0; - - CMyComPtr outSeekStream; - outStream->QueryInterface(IID_IOutStream, (void **)&outSeekStream); - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - - UInt64 complexity = 0; - - unsigned i; - for (i = 0; i < updateItems.Size(); i++) - { - const CUpdateItem &ui = updateItems[i]; - if (ui.NewData) - complexity += ui.Size; - else - complexity += inputItems[ui.IndexInArc].GetFullSize(); - } - - RINOK(updateCallback->SetTotal(complexity)); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLimited(streamSpec); - streamSpec->SetStream(inStream); - - complexity = 0; - - for (i = 0; i < updateItems.Size(); i++) - { - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - - const CUpdateItem &ui = updateItems[i]; - CItem item; - - if (ui.NewProps) - { - item.Mode = ui.Mode; - item.Name = ui.Name; - item.User = ui.User; - item.Group = ui.Group; - - if (ui.IsDir) - { - item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; - item.PackSize = 0; - } - else - { - item.LinkFlag = NFileHeader::NLinkFlag::kNormal; - item.PackSize = ui.Size; - } - - item.MTime = ui.MTime; - item.DeviceMajorDefined = false; - item.DeviceMinorDefined = false; - item.UID = 0; - item.GID = 0; - memcpy(item.Magic, NFileHeader::NMagic::kUsTar_00, 8); - } - else - item = inputItems[ui.IndexInArc]; - - AString symLink; - if (ui.NewData || ui.NewProps) - { - RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, codePage, true)); - if (!symLink.IsEmpty()) - { - item.LinkFlag = NFileHeader::NLinkFlag::kSymLink; - item.LinkName = symLink; - } - } - - if (ui.NewData) - { - item.SparseBlocks.Clear(); - item.PackSize = ui.Size; - item.Size = ui.Size; - if (ui.Size == (UInt64)(Int64)-1) - return E_INVALIDARG; - - CMyComPtr fileInStream; - - bool needWrite = true; - - if (!symLink.IsEmpty()) - { - item.PackSize = 0; - item.Size = 0; - } - else - { - HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); - - if (res == S_FALSE) - needWrite = false; - else - { - RINOK(res); - - if (fileInStream) - { - CMyComPtr getProps; - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); - if (getProps) - { - FILETIME mTime; - UInt64 size2; - if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK) - { - item.PackSize = size2; - item.Size = size2; - item.MTime = NWindows::NTime::FileTimeToUnixTime64(mTime);; - } - } - } - else - { - item.PackSize = 0; - item.Size = 0; - } - - { - AString hardLink; - RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, true)); - if (!hardLink.IsEmpty()) - { - item.LinkFlag = NFileHeader::NLinkFlag::kHardLink; - item.LinkName = hardLink; - item.PackSize = 0; - item.Size = 0; - fileInStream.Release(); - } - } - } - } - - if (needWrite) - { - UInt64 fileHeaderStartPos = outArchive.Pos; - RINOK(outArchive.WriteHeader(item)); - if (fileInStream) - { - RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress)); - outArchive.Pos += copyCoderSpec->TotalSize; - if (copyCoderSpec->TotalSize != item.PackSize) - { - if (!outSeekStream) - return E_FAIL; - UInt64 backOffset = outArchive.Pos - fileHeaderStartPos; - RINOK(outSeekStream->Seek(-(Int64)backOffset, STREAM_SEEK_CUR, NULL)); - outArchive.Pos = fileHeaderStartPos; - item.PackSize = copyCoderSpec->TotalSize; - RINOK(outArchive.WriteHeader(item)); - RINOK(outSeekStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL)); - outArchive.Pos += item.PackSize; - } - RINOK(outArchive.FillDataResidual(item.PackSize)); - } - } - - complexity += item.PackSize; - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - } - else - { - const CItemEx &existItem = inputItems[ui.IndexInArc]; - UInt64 size; - - if (ui.NewProps) - { - // memcpy(item.Magic, NFileHeader::NMagic::kEmpty, 8); - - if (!symLink.IsEmpty()) - { - item.PackSize = 0; - item.Size = 0; - } - else - { - if (ui.IsDir == existItem.IsDir()) - item.LinkFlag = existItem.LinkFlag; - - item.SparseBlocks = existItem.SparseBlocks; - item.Size = existItem.Size; - item.PackSize = existItem.PackSize; - } - - item.DeviceMajorDefined = existItem.DeviceMajorDefined; - item.DeviceMinorDefined = existItem.DeviceMinorDefined; - item.DeviceMajor = existItem.DeviceMajor; - item.DeviceMinor = existItem.DeviceMinor; - item.UID = existItem.UID; - item.GID = existItem.GID; - - RINOK(outArchive.WriteHeader(item)); - RINOK(inStream->Seek(existItem.GetDataPosition(), STREAM_SEEK_SET, NULL)); - size = existItem.PackSize; - } - else - { - RINOK(inStream->Seek(existItem.HeaderPos, STREAM_SEEK_SET, NULL)); - size = existItem.GetFullSize(); - } - - streamSpec->Init(size); - - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, - NUpdateNotifyOp::kReplicate)) - } - - 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(); -} - -}} +// TarUpdate.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "TarOut.h" +#include "TarUpdate.h" + +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 = (int)(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, + const CUpdateOptions &options, + IArchiveUpdateCallback *updateCallback) +{ + COutArchive outArchive; + outArchive.Create(outStream); + outArchive.Pos = 0; + outArchive.IsPosixMode = options.PosixMode; + outArchive.TimeOptions = options.TimeOptions; + + Z7_DECL_CMyComPtr_QI_FROM(IOutStream, outSeekStream, outStream) + Z7_DECL_CMyComPtr_QI_FROM(IStreamSetRestriction, setRestriction, outStream) + Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackFile, opCallback, outStream) + + 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)) + } + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + + UInt64 complexity = 0; + + unsigned i; + for (i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + { + if (ui.Size == (UInt64)(Int64)-1) + break; + complexity += ui.Size; + } + else + complexity += inputItems[(unsigned)ui.IndexInArc].Get_FullSize_Aligned(); + } + + if (i == updateItems.Size()) + RINOK(updateCallback->SetTotal(complexity)) + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create inStreamLimited; + inStreamLimited->SetStream(inStream); + + complexity = 0; + + // const int kNumReduceDigits = -1; // for debug + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()) + + if (i == updateItems.Size()) + { + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + return outArchive.WriteFinishHeader(); + } + + const CUpdateItem &ui = updateItems[i]; + CItem item; + + if (ui.NewProps) + { + 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) + { + item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; + item.PackSize = 0; + } + else + { + item.PackSize = ui.Size; + item.Set_LinkFlag_for_File(ui.Mode); + } + + // 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]; + + AString symLink; + if (ui.NewData || ui.NewProps) + { + RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, + options.CodePage, options.UtfFlags, true)) + if (!symLink.IsEmpty()) + { + item.LinkFlag = NFileHeader::NLinkFlag::kSymLink; + item.LinkName = symLink; + } + } + + if (ui.NewData) + { + item.SparseBlocks.Clear(); + item.PackSize = ui.Size; + item.Size = ui.Size; +#if 0 + if (ui.Size == (UInt64)(Int64)-1) + return E_INVALIDARG; +#endif + CMyComPtr fileInStream; + + bool needWrite = true; + + if (!symLink.IsEmpty()) + { + item.PackSize = 0; + item.Size = 0; + } + else + { + const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); + + if (res == S_FALSE) + needWrite = false; + else + { + RINOK(res) + + if (!fileInStream) + { + item.PackSize = 0; + item.Size = 0; + } + else + { + Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProp, getProp, fileInStream) + 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; + // printf("\nTAR after GetProperty(kpidSize size = %8d\n", (unsigned)size); + item.PackSize = size; + item.Size = size; + } + /* + printf("\nNum digits = %d %d\n", + (int)item.PaxTimes.MTime.NumDigits, + (int)item.PaxTimes.MTime.Ns); + */ + } + else + { + Z7_DECL_CMyComPtr_QI_FROM(IStreamGetProps, getProps, fileInStream) + if (getProps) + { + 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); + } + } + } + } + + { + // we must request kpidHardLink after updateCallback->GetStream() + AString hardLink; + RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, + options.CodePage, options.UtfFlags, true)) + if (!hardLink.IsEmpty()) + { + item.LinkFlag = NFileHeader::NLinkFlag::kHardLink; + item.LinkName = hardLink; + item.PackSize = 0; + item.Size = 0; + fileInStream.Release(); + } + } + } + } + + // item.PaxTimes.ReducePrecison(kNumReduceDigits); // for debug + + if (ui.NewProps) + item.MTime = item.PaxTimes.MTime.GetSec(); + + if (needWrite) + { + if (fileInStream) + // if (item.PackSize == (UInt64)(Int64)-1) + if (item.Size == (UInt64)(Int64)-1) + return E_INVALIDARG; + + const UInt64 headerPos = outArchive.Pos; + // item.PackSize = ((UInt64)1 << 33); // for debug + + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(outArchive.Pos, (UInt64)(Int64)-1)) + + RINOK(outArchive.WriteHeader(item)) + if (fileInStream) + { + for (unsigned numPasses = 0;; numPasses++) + { + // printf("\nTAR numPasses = %d" " old size = %8d\n", numPasses, (unsigned)item.PackSize); + /* 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.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + outArchive.Pos += copyCoder->TotalSize; + RINOK(outArchive.Write_AfterDataResidual(copyCoder->TotalSize)) + // printf("\nTAR after Code old size = %8d copyCoder->TotalSize = %8d \n", (unsigned)item.PackSize, (unsigned)copyCoder->TotalSize); + // if (numPasses >= 10) // for debug + if (copyCoder->TotalSize == item.PackSize) + break; + + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kOutArcIndex, (UInt32)ui.IndexInClient, + NUpdateNotifyOp::kInFileChanged)) + } + + if (!outSeekStream) + return E_FAIL; + const UInt64 nextPos = outArchive.Pos; + RINOK(outSeekStream->Seek(-(Int64)(nextPos - headerPos), STREAM_SEEK_CUR, NULL)) + outArchive.Pos = headerPos; + item.PackSize = copyCoder->TotalSize; + + RINOK(outArchive.WriteHeader(item)) + + // if (numPasses >= 10) // for debug + if (outArchive.Pos == dataPos) + { + const UInt64 alignedSize = nextPos - dataPos; + if (alignedSize != 0) + { + RINOK(outSeekStream->Seek((Int64)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 + Z7_DECL_CMyComPtr_QI_FROM(IInStream, fileSeekStream, fileInStream) + if (!fileSeekStream) + return E_FAIL; + RINOK(InStream_SeekToBegin(fileSeekStream)) + RINOK(outSeekStream->SetSize(outArchive.Pos)) + if (item.PackSize == 0) + break; + } + } + } + + 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, pos; + + if (ui.NewProps) + { + // memcpy(item.Magic, NFileHeader::NMagic::kEmpty, 8); + + if (!symLink.IsEmpty()) + { + item.PackSize = 0; + item.Size = 0; + } + else + { + if (ui.IsDir == existItem.IsDir()) + item.LinkFlag = existItem.LinkFlag; + + item.SparseBlocks = existItem.SparseBlocks; + item.Size = existItem.Size; + item.PackSize = existItem.PackSize; + } + + 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)) + size = existItem.Get_PackSize_Aligned(); + pos = existItem.Get_DataPos(); + } + else + { + size = existItem.Get_FullSize_Aligned(); + pos = existItem.HeaderPos; + } + + if (size != 0) + { + RINOK(InStream_SeekSet(inStream, pos)) + inStreamLimited->Init(size); + if (outSeekStream && setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + // 22.00 : we copy Residual data from old archive to new archive instead of zeroing + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != size) + return E_FAIL; + outArchive.Pos += size; + // RINOK(outArchive.Write_AfterDataResidual(existItem.PackSize)); + complexity += size; + } + } + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarUpdate.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.h --- p7zip-rar-16.02/CPP/7zip/Archive/Tar/TarUpdate.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Tar/TarUpdate.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,38 +1,74 @@ -// TarUpdate.h - -#ifndef __TAR_UPDATE_H -#define __TAR_UPDATE_H - -#include "../IArchive.h" - -#include "TarItem.h" - -namespace NArchive { -namespace NTar { - -struct CUpdateItem -{ - int IndexInArc; - int IndexInClient; - UInt64 Size; - Int64 MTime; - UInt32 Mode; - bool NewData; - bool NewProps; - bool IsDir; - AString Name; - AString User; - AString Group; - - CUpdateItem(): Size(0), IsDir(false) {} -}; - -HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream, - const CObjectVector &inputItems, - const CObjectVector &updateItems, - UINT codePage, - IArchiveUpdateCallback *updateCallback); - -}} - -#endif +// TarUpdate.h + +#ifndef ZIP7_INC_TAR_UPDATE_H +#define ZIP7_INC_TAR_UPDATE_H + +#include "../IArchive.h" + +#include "TarItem.h" + +namespace NArchive { +namespace NTar { + +struct CUpdateItem +{ + int IndexInArc; + unsigned IndexInClient; + UInt64 Size; + // 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; + + 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, + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Udf/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Udf/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfHandler.cpp 2015-11-20 20:40:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.cpp 2023-12-19 10:00:00.000000000 +0000 @@ -1,376 +1,427 @@ -// UdfHandler.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/RegisterArc.h" -#include "../../Common/StreamObjects.h" - -#include "../../Compress/CopyCoder.h" - -#include "UdfHandler.h" - -namespace NArchive { -namespace NUdf { - -static void UdfTimeToFileTime(const CTime &t, NWindows::NCOM::CPropVariant &prop) -{ - UInt64 numSecs; - const Byte *d = t.Data; - if (!NWindows::NTime::GetSecondsSince1601(t.GetYear(), d[4], d[5], d[6], d[7], d[8], numSecs)) - 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; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidATime -}; - -static const Byte kArcProps[] = -{ - kpidComment, - kpidClusterSize, - kpidCTime -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: prop = _archive.PhySize; break; - - case kpidComment: - { - UString comment = _archive.GetComment(); - if (!comment.IsEmpty()) - prop = comment; - break; - } - - case kpidClusterSize: - if (_archive.LogVols.Size() > 0) - { - UInt32 blockSize = _archive.LogVols[0].BlockSize; - unsigned i; - for (i = 1; i < _archive.LogVols.Size(); i++) - if (_archive.LogVols[i].BlockSize != blockSize) - break; - if (i == _archive.LogVols.Size()) - prop = blockSize; - } - break; - - case kpidCTime: - if (_archive.LogVols.Size() == 1) - { - const CLogVol &vol = _archive.LogVols[0]; - if (vol.FileSets.Size() >= 1) - UdfTimeToFileTime(vol.FileSets[0].RecodringTime, prop); - } - break; - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; - if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature; - if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_archive.NoEndAnchor) v |= kpv_ErrorFlags_HeadersError; - prop = v; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CProgressImp: public CProgressVirt -{ - CMyComPtr _callback; - UInt64 _numFiles; - UInt64 _numBytes; -public: - HRESULT SetTotal(UInt64 numBytes); - HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes); - HRESULT SetCompleted(); - CProgressImp(IArchiveOpenCallback *callback): _callback(callback), _numFiles(0), _numBytes(0) {} -}; - -HRESULT CProgressImp::SetTotal(UInt64 numBytes) -{ - if (_callback) - return _callback->SetTotal(NULL, &numBytes); - return S_OK; -} - -HRESULT CProgressImp::SetCompleted(UInt64 numFiles, UInt64 numBytes) -{ - _numFiles = numFiles; - _numBytes = numBytes; - return SetCompleted(); -} - -HRESULT CProgressImp::SetCompleted() -{ - if (_callback) - return _callback->SetCompleted(&_numFiles, &_numBytes); - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - CProgressImp progressImp(callback); - RINOK(_archive.Open(stream, &progressImp)); - bool showVolName = (_archive.LogVols.Size() > 1); - FOR_VECTOR (volIndex, _archive.LogVols) - { - const CLogVol &vol = _archive.LogVols[volIndex]; - bool showFileSetName = (vol.FileSets.Size() > 1); - FOR_VECTOR (fsIndex, vol.FileSets) - { - const CFileSet &fs = vol.FileSets[fsIndex]; - for (unsigned i = ((showVolName || showFileSetName) ? 0 : 1); i < fs.Refs.Size(); i++) - { - CRef2 ref2; - ref2.Vol = volIndex; - ref2.Fs = fsIndex; - ref2.Ref = i; - _refs2.Add(ref2); - } - } - } - _inStream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _inStream.Release(); - _archive.Clear(); - _refs2.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _refs2.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - { - const CRef2 &ref2 = _refs2[index]; - const CLogVol &vol = _archive.LogVols[ref2.Vol]; - const CRef &ref = vol.FileSets[ref2.Fs].Refs[ref2.Ref]; - const CFile &file = _archive.Files[ref.FileIndex]; - const CItem &item = _archive.Items[file.ItemIndex]; - switch (propID) - { - case kpidPath: prop = _archive.GetItemPath(ref2.Vol, ref2.Fs, ref2.Ref, - _archive.LogVols.Size() > 1, vol.FileSets.Size() > 1); break; - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: if (!item.IsDir()) prop = (UInt64)item.Size; break; - 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; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - *stream = 0; - - const CRef2 &ref2 = _refs2[index]; - const CLogVol &vol = _archive.LogVols[ref2.Vol]; - const CRef &ref = vol.FileSets[ref2.Fs].Refs[ref2.Ref]; - const CFile &file = _archive.Files[ref.FileIndex]; - const CItem &item = _archive.Items[file.ItemIndex]; - UInt64 size = item.Size; - - if (!item.IsRecAndAlloc() || !item.CheckChunkSizes() || ! _archive.CheckItemExtents(ref2.Vol, item)) - return E_NOTIMPL; - - if (item.IsInline) - { - Create_BufInStream_WithNewBuffer(item.InlineData, stream); - return S_OK; - } - - CExtentsStream *extentStreamSpec = new CExtentsStream(); - CMyComPtr extentStream = extentStreamSpec; - - extentStreamSpec->Stream = _inStream; - - UInt64 virtOffset = 0; - FOR_VECTOR (extentIndex, item.Extents) - { - const CMyExtent &extent = item.Extents[extentIndex]; - UInt32 len = extent.GetLen(); - if (len == 0) - continue; - if (size < len) - return S_FALSE; - - int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex; - UInt32 logBlockNumber = extent.Pos; - const CPartition &partition = _archive.Partitions[partitionIndex]; - UInt64 offset = ((UInt64)partition.Pos << _archive.SecLogSize) + - (UInt64)logBlockNumber * vol.BlockSize; - - CSeekExtent se; - se.Phy = offset; - se.Virt = virtOffset; - virtOffset += len; - extentStreamSpec->Extents.Add(se); - - size -= len; - } - if (size != 0) - return S_FALSE; - CSeekExtent se; - se.Phy = 0; - se.Virt = virtOffset; - extentStreamSpec->Extents.Add(se); - extentStreamSpec->Init(); - *stream = extentStream.Detach(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _refs2.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - - for (i = 0; i < numItems; i++) - { - UInt32 index = (allFilesMode ? i : indices[i]); - const CRef2 &ref2 = _refs2[index]; - const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; - const CFile &file = _archive.Files[ref.FileIndex]; - const CItem &item = _archive.Items[file.ItemIndex]; - if (!item.IsDir()) - totalSize += item.Size; - } - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - - for (i = 0; i < numItems; i++) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - const CRef2 &ref2 = _refs2[index]; - const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; - const CFile &file = _archive.Files[ref.FileIndex]; - const CItem &item = _archive.Items[file.ItemIndex]; - - if (item.IsDir()) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - currentTotalSize += item.Size; - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(item.Size); - Int32 opRes; - CMyComPtr udfInStream; - HRESULT res = GetStream(index, &udfInStream); - if (res == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (res != S_OK) - opRes = NExtract::NOperationResult::kDataError; - else - { - RINOK(copyCoder->Code(udfInStream, outStream, NULL, NULL, progress)); - opRes = outStreamSpec->IsFinishedOK() ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError; - } - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - return S_OK; - COM_TRY_END -} - -static const UInt32 kIsoStartPos = 0x8000; - -// 5, { 0, 'N', 'S', 'R', '0' }, -static const Byte k_Signature[] = { 1, 'C', 'D', '0', '0', '1' }; - -REGISTER_ARC_I( - "Udf", "udf iso img", 0, 0xE0, - k_Signature, - kIsoStartPos, - NArcInfoFlags::kStartOpen, - IsArc_Udf) - -}} +// UdfHandler.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/RegisterArc.h" +#include "../../Common/StreamObjects.h" + +#include "../../Compress/CopyCoder.h" + +#include "UdfHandler.h" + +namespace NArchive { +namespace NUdf { + +static void UdfTimeToFileTime(const CTime &t, NWindows::NCOM::CPropVariant &prop) +{ + UInt64 numSecs; + const Byte *d = t.Data; + if (!NWindows::NTime::GetSecondsSince1601(t.GetYear(), d[4], d[5], d[6], d[7], d[8], numSecs)) + return; + if (t.IsLocal()) + numSecs = (UInt64)((Int64)numSecs - (Int64)((Int32)t.GetMinutesOffset() * 60)); + 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[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidATime, + kpidCTime, + kpidChangeTime, + // kpidUserId, + // kpidGroupId, + // kpidPosixAttrib, + kpidLinks +}; + +static const Byte kArcProps[] = +{ + kpidUnpackVer, + kpidClusterSize, + kpidSectorSize, + kpidCTime, + kpidMTime, + kpidComment +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: prop = _archive.PhySize; break; + + case kpidUnpackVer: + { + if (_archive.LogVols.Size() == 1) + { + UString s; + const CLogVol &vol = _archive.LogVols[0]; + vol.DomainId.AddUdfVersionTo(s); + if (!s.IsEmpty()) + prop = s; + } + break; + } + case kpidComment: + { + UString comment = _archive.GetComment(); + if (!comment.IsEmpty()) + prop = comment; + break; + } + + case kpidClusterSize: + if (_archive.LogVols.Size() > 0) + { + UInt32 blockSize = _archive.LogVols[0].BlockSize; + unsigned i; + for (i = 1; i < _archive.LogVols.Size(); i++) + if (_archive.LogVols[i].BlockSize != blockSize) + break; + if (i == _archive.LogVols.Size()) + prop = blockSize; + } + break; + + case kpidSectorSize: prop = ((UInt32)1 << _archive.SecLogSize); break; + + case kpidCTime: + if (_archive.LogVols.Size() == 1) + { + const CLogVol &vol = _archive.LogVols[0]; + if (vol.FileSets.Size() >= 1) + UdfTimeToFileTime(vol.FileSets[0].RecordingTime, prop); + } + break; + case kpidMTime: + if (_archive.PrimeVols.Size() == 1) + { + const CPrimeVol &pv = _archive.PrimeVols[0]; + UdfTimeToFileTime(pv.RecordingTime, prop); + } + break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature; + if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_archive.NoEndAnchor) v |= kpv_ErrorFlags_HeadersError; + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +class CProgressImp Z7_final: public CProgressVirt +{ + CMyComPtr _callback; + UInt64 _numFiles; + UInt64 _numBytes; +public: + HRESULT SetTotal(UInt64 numBytes) Z7_override; + HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) Z7_override; + HRESULT SetCompleted() Z7_override; + CProgressImp(IArchiveOpenCallback *callback): _callback(callback), _numFiles(0), _numBytes(0) {} +}; + +HRESULT CProgressImp::SetTotal(UInt64 numBytes) +{ + if (_callback) + return _callback->SetTotal(NULL, &numBytes); + return S_OK; +} + +HRESULT CProgressImp::SetCompleted(UInt64 numFiles, UInt64 numBytes) +{ + _numFiles = numFiles; + _numBytes = numBytes; + return SetCompleted(); +} + +HRESULT CProgressImp::SetCompleted() +{ + if (_callback) + return _callback->SetCompleted(&_numFiles, &_numBytes); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + CProgressImp progressImp(callback); + RINOK(_archive.Open(stream, &progressImp)) + bool showVolName = (_archive.LogVols.Size() > 1); + FOR_VECTOR (volIndex, _archive.LogVols) + { + const CLogVol &vol = _archive.LogVols[volIndex]; + bool showFileSetName = (vol.FileSets.Size() > 1); + // showFileSetName = true; // for debug + FOR_VECTOR (fsIndex, vol.FileSets) + { + const CFileSet &fs = vol.FileSets[fsIndex]; + for (unsigned i = ((showVolName || showFileSetName) ? 0 : 1); i < fs.Refs.Size(); i++) + { + CRef2 ref2; + ref2.Vol = volIndex; + ref2.Fs = fsIndex; + ref2.Ref = i; + _refs2.Add(ref2); + } + } + } + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _inStream.Release(); + _archive.Clear(); + _refs2.Clear(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _refs2.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + { + const CRef2 &ref2 = _refs2[index]; + const CLogVol &vol = _archive.LogVols[ref2.Vol]; + const CRef &ref = vol.FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + switch (propID) + { + case kpidPath: prop = _archive.GetItemPath(ref2.Vol, ref2.Fs, ref2.Ref, + _archive.LogVols.Size() > 1, vol.FileSets.Size() > 1); break; + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: if (!item.IsDir()) prop = (UInt64)item.Size; break; + 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 kpidCTime: + if (item.IsExtended) + UdfTimeToFileTime(item.CreateTime, prop); + break; + case kpidChangeTime: UdfTimeToFileTime(item.AttribTime, prop); break; + // case kpidUserId: prop = item.Uid; break; + // case kpidGroupId: prop = item.Gid; break; + // case kpidPosixAttrib: prop = (UInt32)item.Permissions; break; + case kpidLinks: prop = (UInt32)item.FileLinkCount; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + *stream = NULL; + + const CRef2 &ref2 = _refs2[index]; + const CLogVol &vol = _archive.LogVols[ref2.Vol]; + const CRef &ref = vol.FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + UInt64 size = item.Size; + + if (!item.IsRecAndAlloc() || !item.CheckChunkSizes() || ! _archive.CheckItemExtents(ref2.Vol, item)) + return E_NOTIMPL; + + if (item.IsInline) + { + Create_BufInStream_WithNewBuffer(item.InlineData, stream); + return S_OK; + } + + CExtentsStream *extentStreamSpec = new CExtentsStream(); + CMyComPtr extentStream = extentStreamSpec; + + extentStreamSpec->Stream = _inStream; + + UInt64 virtOffset = 0; + FOR_VECTOR (extentIndex, item.Extents) + { + const CMyExtent &extent = item.Extents[extentIndex]; + UInt32 len = extent.GetLen(); + if (len == 0) + continue; + if (size < len) + return S_FALSE; + + const unsigned partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex; + UInt32 logBlockNumber = extent.Pos; + const CPartition &partition = _archive.Partitions[partitionIndex]; + UInt64 offset = ((UInt64)partition.Pos << _archive.SecLogSize) + + (UInt64)logBlockNumber * vol.BlockSize; + + CSeekExtent se; + se.Phy = offset; + se.Virt = virtOffset; + virtOffset += len; + extentStreamSpec->Extents.Add(se); + + size -= len; + } + if (size != 0) + return S_FALSE; + CSeekExtent se; + se.Phy = 0; + se.Virt = virtOffset; + extentStreamSpec->Extents.Add(se); + extentStreamSpec->Init(); + *stream = extentStream.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(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; + UInt64 totalSize = 0; + UInt32 i; + + for (i = 0; i < numItems; i++) + { + const UInt32 index = (allFilesMode ? i : indices[i]); + const CRef2 &ref2 = _refs2[index]; + const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + if (!item.IsDir()) + totalSize += item.Size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + UInt64 currentTotalSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create outStream; + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize = currentTotalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + const CRef2 &ref2 = _refs2[index]; + const CRef &ref = _archive.LogVols[ref2.Vol].FileSets[ref2.Fs].Refs[ref2.Ref]; + const CFile &file = _archive.Files[ref.FileIndex]; + const CItem &item = _archive.Items[file.ItemIndex]; + + if (item.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)) + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + currentTotalSize += item.Size; + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + outStream->SetStream(realOutStream); + realOutStream.Release(); + outStream->Init(item.Size); + Int32 opRes; + { + CMyComPtr udfInStream; + const HRESULT res = GetStream(index, &udfInStream); + if (res == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else if (res != S_OK) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(copyCoder.Interface()->Code(udfInStream, outStream, NULL, NULL, lps)) + opRes = outStream->IsFinishedOK() ? + NExtract::NOperationResult::kOK: + NExtract::NOperationResult::kDataError; + } + } + outStream->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +static const UInt32 kIsoStartPos = 0x8000; + +// 5, { 0, 'N', 'S', 'R', '0' }, + +static const Byte k_Signature[] = +{ + 8, 0, 'B', 'E', 'A', '0', '1', 1, 0, + 6, 1, 'C', 'D', '0', '0', '1' +}; + +REGISTER_ARC_I( + "Udf", "udf iso img", NULL, 0xE0, + k_Signature, + kIsoStartPos, + NArcInfoFlags::kMultiSignature | + NArcInfoFlags::kStartOpen, + IsArc_Udf) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfHandler.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfHandler.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,38 +1,32 @@ -// UdfHandler.h - -#ifndef __UDF_HANDLER_H -#define __UDF_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "../IArchive.h" - -#include "UdfIn.h" - -namespace NArchive { -namespace NUdf { - -struct CRef2 -{ - unsigned Vol; - unsigned Fs; - unsigned Ref; -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CMyComPtr _inStream; - CInArchive _archive; - CRecordVector _refs2; -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -}} - -#endif +// UdfHandler.h + +#ifndef ZIP7_INC_UDF_HANDLER_H +#define ZIP7_INC_UDF_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../IArchive.h" + +#include "UdfIn.h" + +namespace NArchive { +namespace NUdf { + +struct CRef2 +{ + unsigned Vol; + unsigned Fs; + unsigned Ref; +}; + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CRecordVector _refs2; + CMyComPtr _inStream; + CInArchive _archive; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfIn.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,1141 +1,1741 @@ -// Archive/UdfIn.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include "../../../../C/CpuArch.h" - -#include "../../Common/RegisterArc.h" -#include "../../Common/StreamUtils.h" - -#include "UdfIn.h" - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -namespace NArchive { -namespace NUdf { - -static const unsigned kNumPartitionsMax = 64; -static const unsigned kNumLogVolumesMax = 64; -static const unsigned kNumRecursionLevelsMax = 1 << 10; -static const unsigned kNumItemsMax = 1 << 27; -static const unsigned kNumFilesMax = 1 << 28; -static const unsigned kNumRefsMax = 1 << 28; -static const UInt32 kNumExtentsMax = (UInt32)1 << 30; -static const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33; -static const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33; - -#define CRC16_INIT_VAL 0 -#define CRC16_GET_DIGEST(crc) (crc) -#define CRC16_UPDATE_BYTE(crc, b) ((UInt16)(g_Crc16Table[(((crc) >> 8) ^ (b)) & 0xFF] ^ ((crc) << 8))) - -#define kCrc16Poly 0x1021 -static UInt16 g_Crc16Table[256]; - -void MY_FAST_CALL Crc16GenerateTable(void) -{ - UInt32 i; - for (i = 0; i < 256; i++) - { - UInt32 r = (i << 8); - for (int j = 8; j > 0; j--) - r = ((r & 0x8000) ? ((r << 1) ^ kCrc16Poly) : (r << 1)) & 0xFFFF; - g_Crc16Table[i] = (UInt16)r; - } -} - -UInt16 MY_FAST_CALL Crc16_Update(UInt16 v, const void *data, size_t size) -{ - const Byte *p = (const Byte *)data; - for (; size > 0 ; size--, p++) - v = CRC16_UPDATE_BYTE(v, *p); - return v; -} - -UInt16 MY_FAST_CALL Crc16Calc(const void *data, size_t size) -{ - return Crc16_Update(CRC16_INIT_VAL, data, size); -} - -struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit; - - - -void CDString::Parse(const Byte *p, unsigned size) -{ - Data.CopyFrom(p, size); -} - -static UString ParseDString(const Byte *data, unsigned size) -{ - UString res; - if (size > 0) - { - wchar_t *p; - Byte type = data[0]; - if (type == 8) - { - p = res.GetBuf(size); - for (unsigned i = 1; i < size; i++) - { - wchar_t c = data[i]; - if (c == 0) - break; - *p++ = c; - } - } - else if (type == 16) - { - p = res.GetBuf(size / 2); - for (unsigned i = 1; i + 2 <= size; i += 2) - { - wchar_t c = GetBe16(data + i); - if (c == 0) - break; - *p++ = c; - } - } - else - return L"[unknow]"; - *p = 0; - res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res)); - } - return res; -} - -UString CDString128::GetString() const -{ - unsigned size = Data[sizeof(Data) - 1]; - return ParseDString(Data, MyMin(size, (unsigned)(sizeof(Data) - 1))); -} - -UString CDString::GetString() const { return ParseDString(Data, (unsigned)Data.Size()); } - -void CTime::Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } - -/* -void CRegId::Parse(const Byte *buf) -{ - Flags = buf[0]; - memcpy(Id, buf + 1, sizeof(Id)); - memcpy(Suffix, buf + 24, sizeof(Suffix)); -} -*/ - -// ECMA 3/7.1 - -struct CExtent -{ - UInt32 Len; - UInt32 Pos; - - void Parse(const Byte *buf); -}; - -void CExtent::Parse(const Byte *buf) -{ - Len = Get32(buf); - Pos = Get32(buf + 4); -} - -// ECMA 3/7.2 - -struct CTag -{ - UInt16 Id; - UInt16 Version; - // Byte Checksum; - // UInt16 SerialNumber; - // UInt16 Crc; - // UInt16 CrcLen; - // UInt32 TagLocation; - - HRESULT Parse(const Byte *buf, size_t size); -}; - -HRESULT CTag::Parse(const Byte *buf, size_t size) -{ - if (size < 16) - return S_FALSE; - Byte sum = 0; - int i; - for (i = 0; i < 4; i++) sum = (Byte)(sum + buf[i]); - for (i = 5; i < 16; i++) sum = (Byte)(sum + buf[i]); - if (sum != buf[4] || buf[5] != 0) return S_FALSE; - - Id = Get16(buf); - Version = Get16(buf + 2); - // SerialNumber = Get16(buf + 6); - UInt16 crc = Get16(buf + 8); - UInt16 crcLen = Get16(buf + 10); - // TagLocation = Get32(buf + 12); - - if (size >= 16 + (size_t)crcLen) - if (crc == Crc16Calc(buf + 16, crcLen)) - return S_OK; - return S_FALSE; -} - -// ECMA 3/7.2.1 - -enum EDescriptorType -{ - DESC_TYPE_SpoaringTable = 0, // UDF - DESC_TYPE_PrimVol = 1, - DESC_TYPE_AnchorVolPtr = 2, - DESC_TYPE_VolPtr = 3, - DESC_TYPE_ImplUseVol = 4, - DESC_TYPE_Partition = 5, - DESC_TYPE_LogicalVol = 6, - DESC_TYPE_UnallocSpace = 7, - DESC_TYPE_Terminating = 8, - DESC_TYPE_LogicalVolIntegrity = 9, - DESC_TYPE_FileSet = 256, - DESC_TYPE_FileId = 257, - DESC_TYPE_AllocationExtent = 258, - DESC_TYPE_Indirect = 259, - DESC_TYPE_Terminal = 260, - DESC_TYPE_File = 261, - DESC_TYPE_ExtendedAttrHeader = 262, - DESC_TYPE_UnallocatedSpace = 263, - DESC_TYPE_SpaceBitmap = 264, - DESC_TYPE_PartitionIntegrity = 265, - DESC_TYPE_ExtendedFile = 266 -}; - - -void CLogBlockAddr::Parse(const Byte *buf) -{ - Pos = Get32(buf); - PartitionRef = Get16(buf + 4); -} - -void CShortAllocDesc::Parse(const Byte *buf) -{ - Len = Get32(buf); - Pos = Get32(buf + 4); -} - -/* -void CADImpUse::Parse(const Byte *buf) -{ - Flags = Get16(buf); - UdfUniqueId = Get32(buf + 2); -} -*/ - -void CLongAllocDesc::Parse(const Byte *buf) -{ - Len = Get32(buf); - Location.Parse(buf + 4); - // memcpy(ImplUse, buf + 10, sizeof(ImplUse)); - // adImpUse.Parse(ImplUse); -} - -bool CInArchive::CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const -{ - const CLogVol &vol = LogVols[volIndex]; - if (partitionRef >= (int)vol.PartitionMaps.Size()) - return false; - const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; - UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize; - return (offset + len) <= (((UInt64)partition.Pos + partition.Len) << SecLogSize); -} - -bool CInArchive::CheckItemExtents(int volIndex, const CItem &item) const -{ - FOR_VECTOR (i, item.Extents) - { - const CMyExtent &e = item.Extents[i]; - if (!CheckExtent(volIndex, e.PartitionRef, e.Pos, e.GetLen())) - return false; - } - return true; -} - -HRESULT CInArchive::Read(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len, Byte *buf) -{ - if (!CheckExtent(volIndex, partitionRef, blockPos, len)) - return S_FALSE; - const CLogVol &vol = LogVols[volIndex]; - const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; - UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize; - RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); - HRESULT res = ReadStream_FALSE(_stream, buf, len); - if (res == S_FALSE && offset + len > FileSize) - UnexpectedEnd = true; - RINOK(res); - UpdatePhySize(offset + len); - return S_OK; -} - -HRESULT CInArchive::Read(int volIndex, const CLongAllocDesc &lad, Byte *buf) -{ - return Read(volIndex, lad.Location.PartitionRef, lad.Location.Pos, lad.GetLen(), (Byte *)buf); -} - -HRESULT CInArchive::ReadFromFile(int volIndex, const CItem &item, CByteBuffer &buf) -{ - if (item.Size >= (UInt32)1 << 30) - return S_FALSE; - if (item.IsInline) - { - buf = item.InlineData; - return S_OK; - } - buf.Alloc((size_t)item.Size); - size_t pos = 0; - FOR_VECTOR (i, item.Extents) - { - const CMyExtent &e = item.Extents[i]; - UInt32 len = e.GetLen(); - RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos)); - pos += len; - } - return S_OK; -} - - -void CIcbTag::Parse(const Byte *p) -{ - // PriorDirectNum = Get32(p); - // StrategyType = Get16(p + 4); - // StrategyParam = Get16(p + 6); - // MaxNumOfEntries = Get16(p + 8); - FileType = p[11]; - // ParentIcb.Parse(p + 12); - Flags = Get16(p + 18); -} - -void CItem::Parse(const Byte *p) -{ - // Uid = Get32(p + 36); - // Gid = Get32(p + 40); - // Permissions = Get32(p + 44); - // FileLinkCount = Get16(p + 48); - // RecordFormat = p[50]; - // RecordDisplayAttr = p[51]; - // RecordLen = Get32(p + 52); - Size = Get64(p + 56); - NumLogBlockRecorded = Get64(p + 64); - ATime.Parse(p + 72); - MTime.Parse(p + 84); - // AttrtTime.Parse(p + 96); - // CheckPoint = Get32(p + 108); - // ExtendedAttrIcb.Parse(p + 112); - // ImplId.Parse(p + 128); - // UniqueId = Get64(p + 160); -} - -// 4/14.4 -struct CFileId -{ - // UInt16 FileVersion; - Byte FileCharacteristics; - // CByteBuffer ImplUse; - CDString Id; - CLongAllocDesc Icb; - - bool IsItLinkParent() const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; } - HRESULT Parse(const Byte *p, size_t size, size_t &processed); -}; - -HRESULT CFileId::Parse(const Byte *p, size_t size, size_t &processed) -{ - processed = 0; - if (size < 38) - return S_FALSE; - CTag tag; - RINOK(tag.Parse(p, size)); - if (tag.Id != DESC_TYPE_FileId) - return S_FALSE; - // FileVersion = Get16(p + 16); - FileCharacteristics = p[18]; - unsigned idLen = p[19]; - Icb.Parse(p + 20); - unsigned impLen = Get16(p + 36); - if (size < 38 + idLen + impLen) - return S_FALSE; - // ImplUse.SetCapacity(impLen); - processed = 38; - // memcpy(ImplUse, p + processed, impLen); - processed += impLen; - Id.Parse(p + processed, idLen); - processed += idLen; - for (;(processed & 3) != 0; processed++) - if (p[processed] != 0) - return S_FALSE; - return (processed <= size) ? S_OK : S_FALSE; -} - -HRESULT CInArchive::ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) -{ - if (Files.Size() % 100 == 0) - RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes)); - if (numRecurseAllowed-- == 0) - return S_FALSE; - CFile &file = Files.Back(); - const CLogVol &vol = LogVols[volIndex]; - unsigned partitionRef = lad.Location.PartitionRef; - if (partitionRef >= vol.PartitionMaps.Size()) - return S_FALSE; - CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; - - UInt32 key = lad.Location.Pos; - UInt32 value; - const UInt32 kRecursedErrorValue = (UInt32)(Int32)-1; - if (partition.Map.Find(key, value)) - { - if (value == kRecursedErrorValue) - return S_FALSE; - file.ItemIndex = value; - } - else - { - value = Items.Size(); - file.ItemIndex = (int)value; - if (partition.Map.Set(key, kRecursedErrorValue)) - return S_FALSE; - RINOK(ReadItem(volIndex, fsIndex, lad, numRecurseAllowed)); - if (!partition.Map.Set(key, value)) - return S_FALSE; - } - return S_OK; -} - -HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed) -{ - if (Items.Size() > kNumItemsMax) - return S_FALSE; - Items.Add(CItem()); - CItem &item = Items.Back(); - - const CLogVol &vol = LogVols[volIndex]; - - if (lad.GetLen() != vol.BlockSize) - return S_FALSE; - - const size_t size = lad.GetLen(); - CByteBuffer buf(size); - RINOK(Read(volIndex, lad, buf)); - - CTag tag; - const Byte *p = buf; - RINOK(tag.Parse(p, size)); - if (size < 176) - return S_FALSE; - if (tag.Id != DESC_TYPE_File) - return S_FALSE; - - item.IcbTag.Parse(p + 16); - if (item.IcbTag.FileType != ICB_FILE_TYPE_DIR && - item.IcbTag.FileType != ICB_FILE_TYPE_FILE) - return S_FALSE; - - item.Parse(p); - - _processedProgressBytes += (UInt64)item.NumLogBlockRecorded * vol.BlockSize + size; - - UInt32 extendedAttrLen = Get32(p + 168); - UInt32 allocDescriptorsLen = Get32(p + 172); - - if ((extendedAttrLen & 3) != 0) - return S_FALSE; - size_t pos = 176; - if (extendedAttrLen > size - pos) - return S_FALSE; - /* - if (extendedAttrLen != 16) - { - if (extendedAttrLen < 24) - return S_FALSE; - CTag attrTag; - RINOK(attrTag.Parse(p + pos, size)); - if (attrTag.Id != DESC_TYPE_ExtendedAttrHeader) - return S_FALSE; - // UInt32 implAttrLocation = Get32(p + pos + 16); - // UInt32 applicationlAttrLocation = Get32(p + pos + 20); - } - */ - pos += extendedAttrLen; - - int desctType = item.IcbTag.GetDescriptorType(); - if (allocDescriptorsLen > size - pos) - return S_FALSE; - if (desctType == ICB_DESC_TYPE_INLINE) - { - item.IsInline = true; - item.InlineData.CopyFrom(p + pos, allocDescriptorsLen); - } - else - { - item.IsInline = false; - if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG) - return S_FALSE; - for (UInt32 i = 0; i < allocDescriptorsLen;) - { - CMyExtent e; - if (desctType == ICB_DESC_TYPE_SHORT) - { - if (i + 8 > allocDescriptorsLen) - return S_FALSE; - CShortAllocDesc sad; - sad.Parse(p + pos + i); - e.Pos = sad.Pos; - e.Len = sad.Len; - e.PartitionRef = lad.Location.PartitionRef; - i += 8; - } - else - { - if (i + 16 > allocDescriptorsLen) - return S_FALSE; - CLongAllocDesc ladNew; - ladNew.Parse(p + pos + i); - e.Pos = ladNew.Location.Pos; - e.PartitionRef = ladNew.Location.PartitionRef; - e.Len = ladNew.Len; - i += 16; - } - item.Extents.Add(e); - } - } - - if (item.IcbTag.IsDir()) - { - if (!item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) - return S_FALSE; - CByteBuffer buf2; - RINOK(ReadFromFile(volIndex, item, buf2)); - item.Size = 0; - item.Extents.ClearAndFree(); - item.InlineData.Free(); - - const Byte *p2 = buf2; - const size_t size2 = buf2.Size(); - size_t processedTotal = 0; - for (; processedTotal < size2;) - { - size_t processedCur; - CFileId fileId; - RINOK(fileId.Parse(p2 + processedTotal, size2 - processedTotal, processedCur)); - if (!fileId.IsItLinkParent()) - { - CFile file; - // file.FileVersion = fileId.FileVersion; - // file.FileCharacteristics = fileId.FileCharacteristics; - // file.ImplUse = fileId.ImplUse; - file.Id = fileId.Id; - - _fileNameLengthTotal += file.Id.Data.Size(); - if (_fileNameLengthTotal > kFileNameLengthTotalMax) - return S_FALSE; - - item.SubFiles.Add(Files.Size()); - if (Files.Size() > kNumFilesMax) - return S_FALSE; - Files.Add(file); - RINOK(ReadFileItem(volIndex, fsIndex, fileId.Icb, numRecurseAllowed)); - } - processedTotal += processedCur; - } - } - else - { - if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents) - return S_FALSE; - _numExtents += item.Extents.Size(); - - if (item.InlineData.Size() > kInlineExtentsSizeMax - _inlineExtentsSize) - return S_FALSE; - _inlineExtentsSize += item.InlineData.Size(); - } - - return S_OK; -} - -HRESULT CInArchive::FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed) -{ - if ((_numRefs & 0xFFF) == 0) - { - RINOK(_progress->SetCompleted()); - } - if (numRecurseAllowed-- == 0) - return S_FALSE; - if (_numRefs >= kNumRefsMax) - return S_FALSE; - _numRefs++; - CRef ref; - ref.FileIndex = fileIndex; - ref.Parent = parent; - parent = fs.Refs.Size(); - fs.Refs.Add(ref); - const CItem &item = Items[Files[fileIndex].ItemIndex]; - FOR_VECTOR (i, item.SubFiles) - { - RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed)); - } - return S_OK; -} - -API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size) -{ - UInt32 res = k_IsArc_Res_NO; - unsigned SecLogSize; - for (SecLogSize = 11;; SecLogSize -= 3) - { - if (SecLogSize < 8) - return res; - const UInt32 offset = (UInt32)256 << SecLogSize; - const UInt32 bufSize = (UInt32)1 << SecLogSize; - if (offset + bufSize > size) - res = k_IsArc_Res_NEED_MORE; - else - { - CTag tag; - if (tag.Parse(p + offset, bufSize) == S_OK) - if (tag.Id == DESC_TYPE_AnchorVolPtr) - return k_IsArc_Res_YES; - } - } -} - - -HRESULT CInArchive::Open2() -{ - Clear(); - UInt64 fileSize; - RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); - FileSize = fileSize; - - // Some UDFs contain additional pad zeros (2 KB). - // Seek to STREAM_SEEK_END for direct DVD reading can return 8 KB more, so we check last 16 KB. - // And when we read last block, result read size can be smaller than required size. - - /* - const size_t kBufSize = 1 << 14; - Byte buf[kBufSize]; - size_t readSize = (fileSize < kBufSize) ? (size_t)fileSize : kBufSize; - RINOK(_stream->Seek(fileSize - readSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(_stream, buf, &readSize)); - size_t i = readSize; - for (;;) - { - const size_t kSecSizeMin = 1 << 8; - if (i < kSecSizeMin) - return S_FALSE; - i -= kSecSizeMin; - SecLogSize = (readSize - i < ((size_t)1 << 11)) ? 8 : 11; - CTag tag; - if (tag.Parse(buf + i, (1 << SecLogSize)) == S_OK) - if (tag.Id == DESC_TYPE_AnchorVolPtr) - break; - } - PhySize = fileSize; - CExtent extentVDS; - extentVDS.Parse(buf + i + 16); - */ - - const size_t kBufSize = 1 << 11; - Byte buf[kBufSize]; - - for (SecLogSize = 11;; SecLogSize -= 3) - { - if (SecLogSize < 8) - return S_FALSE; - UInt32 offset = (UInt32)256 << SecLogSize; - if (offset >= fileSize) - continue; - RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL)); - const size_t bufSize = (size_t)1 << SecLogSize; - size_t readSize = bufSize; - RINOK(ReadStream(_stream, buf, &readSize)); - if (readSize == bufSize) - { - CTag tag; - if (tag.Parse(buf, readSize) == S_OK) - if (tag.Id == DESC_TYPE_AnchorVolPtr) - break; - } - } - - PhySize = (UInt32)(256 + 1) << SecLogSize; - IsArc = true; - - CExtent extentVDS; - extentVDS.Parse(buf + 16); - { - CExtent extentVDS2; - extentVDS2.Parse(buf + 24); - UpdatePhySize(((UInt64)extentVDS.Pos << SecLogSize) + extentVDS.Len); - UpdatePhySize(((UInt64)extentVDS2.Pos << SecLogSize) + extentVDS2.Len); - } - - for (UInt32 location = 0; ; location++) - { - const size_t bufSize = (size_t)1 << SecLogSize; - if (((UInt64)(location + 1) << SecLogSize) > extentVDS.Len) - return S_FALSE; - - UInt64 offs = (UInt64)(extentVDS.Pos + location) << SecLogSize; - RINOK(_stream->Seek(offs, STREAM_SEEK_SET, NULL)); - HRESULT res = ReadStream_FALSE(_stream, buf, bufSize); - if (res == S_FALSE && offs + bufSize > FileSize) - UnexpectedEnd = true; - RINOK(res); - - - CTag tag; - { - const size_t pos = 0; - RINOK(tag.Parse(buf + pos, bufSize - pos)); - } - if (tag.Id == DESC_TYPE_Terminating) - break; - - if (tag.Id == DESC_TYPE_Partition) - { - // Partition Descriptor - // ECMA 167 3/10.5 - // UDF / 2.2.14 - - if (Partitions.Size() >= kNumPartitionsMax) - return S_FALSE; - CPartition partition; - // UInt32 volDescSeqNumer = Get32(buf + 16); - // partition.Flags = Get16(buf + 20); - partition.Number = Get16(buf + 22); - // partition.ContentsId.Parse(buf + 24); - - // memcpy(partition.ContentsUse, buf + 56, sizeof(partition.ContentsUse)); - // ContentsUse is Partition Header Description. - - // partition.AccessType = Get32(buf + 184); - partition.Pos = Get32(buf + 188); - partition.Len = Get32(buf + 192); - // partition.ImplId.Parse(buf + 196); - // memcpy(partition.ImplUse, buf + 228, sizeof(partition.ImplUse)); - - PRF(printf("\nPartition number = %2d pos = %d len = %d", partition.Number, partition.Pos, partition.Len)); - Partitions.Add(partition); - } - else if (tag.Id == DESC_TYPE_LogicalVol) - { - /* Logical Volume Descriptor - ECMA 3/10.6 - UDF 2.60 2.2.4 */ - - if (LogVols.Size() >= kNumLogVolumesMax) - return S_FALSE; - CLogVol vol; - vol.Id.Parse(buf + 84); - vol.BlockSize = Get32(buf + 212); - // vol.DomainId.Parse(buf + 216); - - if (vol.BlockSize < 512 || vol.BlockSize > ((UInt32)1 << 30)) - return S_FALSE; - - // memcpy(vol.ContentsUse, buf + 248, sizeof(vol.ContentsUse)); - vol.FileSetLocation.Parse(buf + 248); - /* the extent in which the first File Set Descriptor Sequence - of the logical volume is recorded */ - - // UInt32 mapTableLength = Get32(buf + 264); - UInt32 numPartitionMaps = Get32(buf + 268); - if (numPartitionMaps > kNumPartitionsMax) - return S_FALSE; - // vol.ImplId.Parse(buf + 272); - // memcpy(vol.ImplUse, buf + 128, sizeof(vol.ImplUse)); - - PRF(printf("\nLogicalVol numPartitionMaps = %2d", numPartitionMaps)); - size_t pos = 440; - for (UInt32 i = 0; i < numPartitionMaps; i++) - { - if (pos + 2 > bufSize) - return S_FALSE; - CPartitionMap pm; - pm.Type = buf[pos]; - // pm.Length = buf[pos + 1]; - Byte len = buf[pos + 1]; - - if (pos + len > bufSize) - return S_FALSE; - - // memcpy(pm.Data, buf + pos + 2, pm.Length - 2); - if (pm.Type == 1) - { - if (len != 6) // < 6 - return S_FALSE; - // pm.VolSeqNumber = Get16(buf + pos + 2); - pm.PartitionNumber = Get16(buf + pos + 4); - PRF(printf("\nPartitionMap type 1 PartitionNumber = %2d", pm.PartitionNumber)); - } - else if (pm.Type == 2) - { - if (len != 64) - return S_FALSE; - /* ECMA 10.7.3 / Type 2 Partition Map - 62 bytes: Partition Identifier. */ - - /* UDF 2.6 - 2.2.8 Virtual Partition Map - This is an extension of ECMA 167 to expand its scope to include - sequentially written media (eg. CD-R). This extension is for a - Partition Map entry to describe a virtual space. */ - - // It's not implemented still. - if (Get16(buf + pos + 2) != 0) - return S_FALSE; - // pm.VolSeqNumber = Get16(buf + pos + 36); - pm.PartitionNumber = Get16(buf + pos + 38); - PRF(printf("\nPartitionMap type 2 PartitionNumber = %2d", pm.PartitionNumber)); - // Unsupported = true; - return S_FALSE; - } - else - return S_FALSE; - pos += len; - vol.PartitionMaps.Add(pm); - } - LogVols.Add(vol); - } - } - - UInt64 totalSize = 0; - - unsigned volIndex; - for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) - { - CLogVol &vol = LogVols[volIndex]; - FOR_VECTOR (pmIndex, vol.PartitionMaps) - { - CPartitionMap &pm = vol.PartitionMaps[pmIndex]; - unsigned i; - for (i = 0; i < Partitions.Size(); i++) - { - CPartition &part = Partitions[i]; - if (part.Number == pm.PartitionNumber) - { - if (part.VolIndex >= 0) - { - // it's for 2.60. Fix it - if (part.VolIndex != (int)volIndex) - return S_FALSE; - // return S_FALSE; - } - pm.PartitionIndex = i; - part.VolIndex = volIndex; - - totalSize += (UInt64)part.Len << SecLogSize; - break; - } - } - if (i == Partitions.Size()) - return S_FALSE; - } - } - - RINOK(_progress->SetTotal(totalSize)); - - PRF(printf("\n Read files")); - - for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) - { - CLogVol &vol = LogVols[volIndex]; - - PRF(printf("\nLogVol %2d", volIndex)); - - CLongAllocDesc nextExtent = vol.FileSetLocation; - // while (nextExtent.ExtentLen != 0) - // for (int i = 0; i < 1; i++) - { - if (nextExtent.GetLen() < 512) - return S_FALSE; - CByteBuffer buf2(nextExtent.GetLen()); - RINOK(Read(volIndex, nextExtent, buf2)); - const Byte *p = buf2; - size_t size = nextExtent.GetLen(); - - CTag tag; - RINOK(tag.Parse(p, size)); - - if (tag.Id == DESC_TYPE_ExtendedFile) - { - // ECMA 4 / 14.17 - // 2.60 ?? - return S_FALSE; - } - - if (tag.Id != DESC_TYPE_FileSet) - return S_FALSE; - - PRF(printf("\n FileSet", volIndex)); - CFileSet fs; - fs.RecodringTime.Parse(p + 16); - // fs.InterchangeLevel = Get16(p + 18); - // fs.MaxInterchangeLevel = Get16(p + 20); - // fs.FileSetNumber = Get32(p + 40); - // fs.FileSetDescNumber = Get32(p + 44); - - // fs.Id.Parse(p + 304); - // fs.CopyrightId.Parse(p + 336); - // fs.AbstractId.Parse(p + 368); - - fs.RootDirICB.Parse(p + 400); - // fs.DomainId.Parse(p + 416); - - // fs.SystemStreamDirICB.Parse(p + 464); - - vol.FileSets.Add(fs); - - // nextExtent.Parse(p + 448); - } - - FOR_VECTOR (fsIndex, vol.FileSets) - { - CFileSet &fs = vol.FileSets[fsIndex]; - unsigned fileIndex = Files.Size(); - Files.AddNew(); - RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB, kNumRecursionLevelsMax)); - RINOK(FillRefs(fs, fileIndex, -1, kNumRecursionLevelsMax)); - } - } - - - for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) - { - const CLogVol &vol = LogVols[volIndex]; - // bool showFileSetName = (vol.FileSets.Size() > 1); - FOR_VECTOR (fsIndex, vol.FileSets) - { - const CFileSet &fs = vol.FileSets[fsIndex]; - for (unsigned i = - // ((showVolName || showFileSetName) ? 0 : 1) - 0; i < fs.Refs.Size(); i++) - { - const CRef &ref = vol.FileSets[fsIndex].Refs[i]; - const CFile &file = Files[ref.FileIndex]; - const CItem &item = Items[file.ItemIndex]; - UInt64 size = item.Size; - - if (!item.IsRecAndAlloc() || !item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) - continue; - - FOR_VECTOR (extentIndex, item.Extents) - { - const CMyExtent &extent = item.Extents[extentIndex]; - UInt32 len = extent.GetLen(); - if (len == 0) - continue; - if (size < len) - break; - - int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex; - UInt32 logBlockNumber = extent.Pos; - const CPartition &partition = Partitions[partitionIndex]; - UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + - (UInt64)logBlockNumber * vol.BlockSize; - UpdatePhySize(offset + len); - } - } - } - } - - { - const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1; - PhySize = (PhySize + secMask) & ~(UInt64)secMask; - } - - NoEndAnchor = true; - - if (PhySize < fileSize) - { - UInt64 rem = fileSize - PhySize; - const size_t secSize = (size_t)1 << SecLogSize; - - RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); - - // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end - - for (unsigned sec = 0; sec < 1024; sec++) - { - if (rem == 0) - break; - - size_t readSize = secSize; - if (readSize > rem) - readSize = (size_t)rem; - - RINOK(ReadStream(_stream, buf, &readSize)); - - if (readSize == 0) - break; - - if (readSize == secSize && NoEndAnchor) - { - CTag tag; - if (tag.Parse(buf, readSize) == S_OK && - tag.Id == DESC_TYPE_AnchorVolPtr) - { - NoEndAnchor = false; - rem -= readSize; - PhySize = fileSize - rem; - continue; - } - } - - size_t i; - for (i = 0; i < readSize && buf[i] == 0; i++); - if (i != readSize) - break; - rem -= readSize; - } - - if (rem == 0) - PhySize = fileSize; - } - - return S_OK; -} - - -HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress) -{ - _progress = progress; - _stream = inStream; - HRESULT res = Open2(); - if (res == S_FALSE && IsArc && !UnexpectedEnd) - Unsupported = true; - return res; - - /* - HRESULT res; - try - { - res = Open2(); - } - catch(...) - { - // Clear(); - // res = S_FALSE; - _stream.Release(); - throw; - } - _stream.Release(); - return res; - */ -} - -void CInArchive::Clear() -{ - IsArc = false; - Unsupported = false; - UnexpectedEnd = false; - NoEndAnchor = false; - - PhySize = 0; - FileSize = 0; - - Partitions.Clear(); - LogVols.Clear(); - Items.Clear(); - Files.Clear(); - _fileNameLengthTotal = 0; - _numRefs = 0; - _numExtents = 0; - _inlineExtentsSize = 0; - _processedProgressBytes = 0; -} - -UString CInArchive::GetComment() const -{ - UString res; - FOR_VECTOR (i, LogVols) - { - if (i != 0) - res.Add_Space(); - res += LogVols[i].GetName(); - } - return res; -} - -static UString GetSpecName(const UString &name) -{ - UString name2 = name; - name2.Trim(); - if (name2.IsEmpty()) - { - /* - wchar_t s[32]; - ConvertUInt64ToString(id, s); - return L"[" + (UString)s + L"]"; - */ - return L"[]"; - } - return name; -} - -static void UpdateWithName(UString &res, const UString &addString) -{ - if (res.IsEmpty()) - res = addString; - else - res.Insert(0, addString + WCHAR_PATH_SEPARATOR); -} - -UString CInArchive::GetItemPath(int volIndex, int fsIndex, int refIndex, - bool showVolName, bool showFsName) const -{ - // showVolName = true; - const CLogVol &vol = LogVols[volIndex]; - const CFileSet &fs = vol.FileSets[fsIndex]; - - UString name; - - for (;;) - { - const CRef &ref = fs.Refs[refIndex]; - refIndex = ref.Parent; - if (refIndex < 0) - break; - UpdateWithName(name, GetSpecName(Files[ref.FileIndex].GetName())); - } - - if (showFsName) - { - wchar_t s[32]; - ConvertUInt32ToString(fsIndex, s); - UString newName = L"File Set "; - newName += s; - UpdateWithName(name, newName); - } - - if (showVolName) - { - wchar_t s[32]; - ConvertUInt32ToString(volIndex, s); - UString newName = s; - UString newName2 = vol.GetName(); - if (newName2.IsEmpty()) - newName2 = L"Volume"; - newName += L'-'; - newName += newName2; - UpdateWithName(name, newName); - } - return name; -} - -}} +// Archive/UdfIn.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "../../../../C/CpuArch.h" + +#include "../../../Windows/PropVariantUtils.h" + +#include "../../Common/RegisterArc.h" +#include "../../Common/StreamUtils.h" + +#include "UdfIn.h" + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#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 NUdf { + +static const unsigned kNumPartitionsMax = 64; +static const unsigned kNumLogVolumesMax = 64; +static const unsigned kNumRecursionLevelsMax = 1 << 10; +static const unsigned kNumItemsMax = 1 << 27; +static const unsigned kNumFilesMax = 1 << 28; +static const unsigned kNumRefsMax = 1 << 28; +static const UInt32 kNumExtentsMax = (UInt32)1 << 30; +static const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33; +static const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33; + +#define CRC16_INIT_VAL 0 +#define CRC16_UPDATE_BYTE(crc, b) ((UInt16)(g_Crc16Table[(((crc) >> 8) ^ (b)) & 0xFF] ^ ((crc) << 8))) + +#define kCrc16Poly 0x1021 +static UInt16 g_Crc16Table[256]; + +static void Z7_FASTCALL Crc16GenerateTable(void) +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = (i << 8); + for (unsigned j = 0; j < 8; j++) + r = ((r << 1) ^ (kCrc16Poly & ((UInt32)0 - (r >> 15)))) & 0xFFFF; + g_Crc16Table[i] = (UInt16)r; + } +} + +static UInt32 Z7_FASTCALL Crc16Calc(const void *data, size_t size) +{ + UInt32 v = CRC16_INIT_VAL; + const Byte *p = (const Byte *)data; + const Byte *pEnd = p + size; + for (; p != pEnd; p++) + v = CRC16_UPDATE_BYTE(v, *p); + return v; +} + +static struct CCrc16TableInit { CCrc16TableInit() { Crc16GenerateTable(); } } g_Crc16TableInit; + + +// ---------- ECMA Part 1 ---------- + +void CDString::Parse(const Byte *p, unsigned size) +{ + Data.CopyFrom(p, size); +} + +static UString ParseDString(const Byte *data, unsigned size) +{ + UString res; + if (size != 0) + { + wchar_t *p; + const Byte type = *data++; + size--; + if (type == 8) + { + p = res.GetBuf(size); + for (unsigned i = 0; i < size; i++) + { + const wchar_t c = data[i]; + if (c == 0) + break; + *p++ = c; + } + } + else if (type == 16) + { + size &= ~(unsigned)1; + p = res.GetBuf(size / 2); + for (unsigned i = 0; i < size; i += 2) + { + const wchar_t c = GetBe16(data + i); + if (c == 0) + break; + *p++ = c; + } + } + else + return UString("[unknown]"); + *p = 0; + res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res)); + } + return res; +} + +UString CDString32::GetString() const +{ + const unsigned size = Data[sizeof(Data) - 1]; + return ParseDString(Data, MyMin(size, (unsigned)(sizeof(Data) - 1))); +} + +UString CDString128::GetString() const +{ + const unsigned size = Data[sizeof(Data) - 1]; + return ParseDString(Data, MyMin(size, (unsigned)(sizeof(Data) - 1))); +} + +UString CDString::GetString() const { return ParseDString(Data, (unsigned)Data.Size()); } + +void CTime::Parse(const Byte *p) { memcpy(Data, p, sizeof(Data)); } + + +static void AddCommentChars(UString &dest, const char *s, size_t size) +{ + for (size_t i = 0; i < size; i++) + { + char c = s[i]; + if (c == 0) + break; + if (c < 0x20) + c = '_'; + dest += (wchar_t)c; + } +} + + +void CRegId::Parse(const Byte *p) +{ + Flags = p[0]; + memcpy(Id, p + 1, sizeof(Id)); + memcpy(Suffix, p + 24, sizeof(Suffix)); +} + +void CRegId::AddCommentTo(UString &s) const +{ + AddCommentChars(s, Id, sizeof(Id)); +} + +void CRegId::AddUdfVersionTo(UString &s) const +{ + // use it only for "Domain Identifier Suffix" and "UDF Identifier Suffix" + // UDF 2.1.5.3 + // Revision in hex (3 digits) + const Byte minor = Suffix[0]; + const Byte major = Suffix[1]; + if (major != 0 || minor != 0) + { + char temp[16]; + ConvertUInt32ToHex(major, temp); + s += temp; + s.Add_Dot(); + ConvertUInt32ToHex8Digits(minor, temp); + s += &temp[8 - 2]; + } +} + + +// ---------- ECMA Part 3: Volume Structure ---------- + +void CExtent::Parse(const Byte *p) +{ + /* Len shall be less than < 2^30. + Unless otherwise specified, the length shall be an integral multiple of the logical sector size. + If (Len == 0), no extent is specified and (Pos) shall contain 0 */ + G32 (0, Len); + G32 (4, Pos); +} + + +// ECMA 3/7.2 + +struct CTag +{ + UInt16 Id; + // UInt16 Version; + // Byte Checksum; + // UInt16 SerialNumber; + // UInt16 Crc; + UInt16 CrcLen; + // UInt32 TagLocation; // the number of the logical sector + + HRESULT Parse(const Byte *p, size_t size); +}; + +HRESULT CTag::Parse(const Byte *p, size_t size) +{ + if (size < 16) + return S_FALSE; + { + unsigned sum = 0; + for (unsigned i = 0; i < 16; i++) + sum = sum + p[i]; + if ((Byte)(sum - p[4]) != p[4] || p[5] != 0) + return S_FALSE; + } + Id = Get16(p); + const UInt16 Version = Get16(p + 2); + if (Version != 2 && Version != 3) + return S_FALSE; + // SerialNumber = Get16(p + 6); + const UInt32 crc = Get16(p + 8); + CrcLen = Get16(p + 10); + // TagLocation = Get32(p + 12); + + if (size >= 16 + (size_t)CrcLen) + if (crc == Crc16Calc(p + 16, (size_t)CrcLen)) + return S_OK; + return S_FALSE; +} + +// ECMA 3/7.2.1 + +enum EDescriptorType +{ + DESC_TYPE_SpoaringTable = 0, // UDF + DESC_TYPE_PrimVol = 1, + DESC_TYPE_AnchorVolPtr = 2, + DESC_TYPE_VolPtr = 3, + DESC_TYPE_ImplUseVol = 4, + DESC_TYPE_Partition = 5, + DESC_TYPE_LogicalVol = 6, + DESC_TYPE_UnallocSpace = 7, + DESC_TYPE_Terminating = 8, + DESC_TYPE_LogicalVolIntegrity = 9, + DESC_TYPE_FileSet = 256, + DESC_TYPE_FileId = 257, + DESC_TYPE_AllocationExtent = 258, + DESC_TYPE_Indirect = 259, + DESC_TYPE_Terminal = 260, + DESC_TYPE_File = 261, + DESC_TYPE_ExtendedAttrHeader = 262, + DESC_TYPE_UnallocatedSpaceEntry = 263, + DESC_TYPE_SpaceBitmap = 264, + DESC_TYPE_PartitionIntegrity = 265, + DESC_TYPE_ExtendedFile = 266 +}; + + +void CLogBlockAddr::Parse(const Byte *p) +{ + G32 (0, Pos); + G16 (4, PartitionRef); +} + +void CShortAllocDesc::Parse(const Byte *p) +{ + G32 (0, Len); + G32 (4, Pos); +} + +/* +void CADImpUse::Parse(const Byte *p) +{ + G16 (0, Flags); + G32 (2, UdfUniqueId); +} +*/ + +void CLongAllocDesc::Parse(const Byte *p) +{ + G32 (0, Len); + Location.Parse(p + 4); + // memcpy(ImplUse, p + 10, sizeof(ImplUse)); + // adImpUse.Parse(ImplUse); +} + + +void CPrimeVol::Parse(const Byte *p) +{ + // G32 (16, VolumeDescriptorSequenceNumber); + G32 (20, PrimaryVolumeDescriptorNumber); + VolumeId.Parse(p + 24); + G16 (56, VolumeSequenceNumber); + G16 (58, MaximumVolumeSequenceNumber); + // G16 (60, InterchangeLevel); + // G16 (62, MaximumInterchangeLevel); + // G32 (64, CharacterSetList) + // G32 (68, MaximumCharacterSetList) + VolumeSetId.Parse(p + 72); + // 200 64 Descriptor Character Set charspec (1/7.2.1) + // 264 64 Explanatory Character Set charspec (1/7.2.1) + // VolumeAbstract.Parse(p + 328); + // VolumeCopyrightNotice.Parse(p + 336); + ApplicationId.Parse(p + 344); + RecordingTime.Parse(p + 376); + ImplId.Parse(p + 388); + // 420 64 Implementation Use bytes + // G32 (484, PredecessorVolumeDescriptorSequenceLocation); + // G16 (488, Flags); +} + + + +bool CInArchive::CheckExtent(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len) const +{ + const CLogVol &vol = LogVols[volIndex]; + if (partitionRef >= vol.PartitionMaps.Size()) + return false; + const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; + return ((UInt64)blockPos * vol.BlockSize + len) <= ((UInt64)partition.Len << SecLogSize); +} + +bool CInArchive::CheckItemExtents(unsigned volIndex, const CItem &item) const +{ + FOR_VECTOR (i, item.Extents) + { + const CMyExtent &e = item.Extents[i]; + if (!CheckExtent(volIndex, e.PartitionRef, e.Pos, e.GetLen())) + return false; + } + return true; +} + +HRESULT CInArchive::Read(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len, Byte *buf) +{ + if (!CheckExtent(volIndex, partitionRef, blockPos, len)) + return S_FALSE; + const CLogVol &vol = LogVols[volIndex]; + const CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; + UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + (UInt64)blockPos * vol.BlockSize; + RINOK(InStream_SeekSet(_stream, offset)) + offset += len; + UpdatePhySize(offset); + const HRESULT res = ReadStream_FALSE(_stream, buf, len); + if (res == S_FALSE && offset > FileSize) + UnexpectedEnd = true; + return res; +} + +HRESULT CInArchive::ReadLad(unsigned volIndex, const CLongAllocDesc &lad, Byte *buf) +{ + return Read(volIndex, lad.Location.PartitionRef, lad.Location.Pos, lad.GetLen(), (Byte *)buf); +} + +HRESULT CInArchive::ReadFromFile(unsigned volIndex, const CItem &item, CByteBuffer &buf) +{ + if (item.Size >= (UInt32)1 << 30) + return S_FALSE; + if (item.IsInline) + { + buf = item.InlineData; + return S_OK; + } + buf.Alloc((size_t)item.Size); + size_t pos = 0; + FOR_VECTOR (i, item.Extents) + { + const CMyExtent &e = item.Extents[i]; + const UInt32 len = e.GetLen(); + RINOK(Read(volIndex, e.PartitionRef, e.Pos, len, (Byte *)buf + pos)) + pos += len; + } + return S_OK; +} + + +void CIcbTag::Parse(const Byte *p) +{ + // G32 (0, PriorDirectNum); + // G16 (4, StrategyType); + // G16 (6, StrategyParam); + // G16 (8, MaxNumOfEntries); + FileType = p[11]; + // ParentIcb.Parse(p + 12); + G16 (18, Flags); +} + + +// ECMA 4/14.9 File Entry +// UDF FileEntry 2.3.6 + +// ECMA 4/14.17 Extended File Entry + +void CItem::Parse(const Byte *p) +{ + // (-1) can be stored in Uid/Gid. + // G32 (36, Uid); + // G32 (40, Gid); + // G32 (44, Permissions); + G16 (48, FileLinkCount); + // RecordFormat = p[50]; + // RecordDisplayAttr = p[51]; + // G32 (52, RecordLen); + G64 (56, Size); + if (IsExtended) + { + // The sum of all Information Length fields for all streams of a file (including the default stream). If this file has no + // streams, the Object Size shall be equal to the Information Length. + // G64 (64, ObjectSize); + p += 8; + } + G64 (64, NumLogBlockRecorded); + ATime.Parse(p + 72); + MTime.Parse(p + 84); + if (IsExtended) + { + CreateTime.Parse(p + 96); + p += 12; + } + AttribTime.Parse(p + 96); + // G32 (108, CheckPoint); + /* + if (IsExtended) + { + // Get32(p + 112); // reserved + p += 4; + } + // ExtendedAttrIcb.Parse(p + 112); + if (IsExtended) + { + StreamDirectoryIcb.Parse(p + 128); + p += 16; + } + */ + + // ImplId.Parse(p + 128); + // G64 (160, UniqueId); +} + + +// ECMA 4/14.4 +// UDF 2.3.4 + +/* +File Characteristics: +Deleted bit: + ECMA: If set to ONE, shall mean this File Identifier Descriptor + identifies a file that has been deleted; + UDF: If the space for the file or directory is deallocated, + the implementation shall set the ICB field to zero. + ECMA 167 4/8.6 requires that the File Identifiers of all FIDs in a directory shall be unique. + The implementations shall follow these rules when a Deleted bit is set: + rewrire the compression ID of the File Identifier: 8 -> 254, 16 -> 255. +*/ + +struct CFileId +{ + // UInt16 FileVersion; + Byte FileCharacteristics; + // CByteBuffer ImplUse; + CDString Id; + CLongAllocDesc Icb; + + bool IsItLink_Dir () const { return (FileCharacteristics & FILEID_CHARACS_Dir) != 0; } + bool IsItLink_Deleted() const { return (FileCharacteristics & FILEID_CHARACS_Deleted) != 0; } + bool IsItLink_Parent () const { return (FileCharacteristics & FILEID_CHARACS_Parent) != 0; } + + size_t Parse(const Byte *p, size_t size); +}; + +size_t CFileId::Parse(const Byte *p, size_t size) +{ + size_t processed = 0; + if (size < 38) + return 0; + CTag tag; + if (tag.Parse(p, size) != S_OK) + return 0; + if (tag.Id != DESC_TYPE_FileId) + return 0; + // FileVersion = Get16(p + 16); + // UDF: There shall be only one version of a file as specified below with the value being set to 1. + + FileCharacteristics = p[18]; + const unsigned idLen = p[19]; + Icb.Parse(p + 20); + const unsigned impLen = Get16(p + 36); + if (size < 38 + idLen + impLen) + return 0; + processed = 38; + // ImplUse.CopyFrom(p + processed, impLen); + processed += impLen; + Id.Parse(p + processed, idLen); + processed += idLen; + for (;(processed & 3) != 0; processed++) + if (p[processed] != 0) + return 0; + if ((size_t)tag.CrcLen + 16 != processed) return 0; + return (processed <= size) ? processed : 0; +} + + + +HRESULT CInArchive::ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed) +{ + if (Files.Size() % 100 == 0) + RINOK(_progress->SetCompleted(Files.Size(), _processedProgressBytes)) + if (numRecurseAllowed-- == 0) + return S_FALSE; + CFile &file = Files.Back(); + const CLogVol &vol = LogVols[volIndex]; + const unsigned partitionRef = lad.Location.PartitionRef; + if (partitionRef >= vol.PartitionMaps.Size()) + return S_FALSE; + CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex]; + + const UInt32 key = lad.Location.Pos; + UInt32 value; + const UInt32 kRecursedErrorValue = (UInt32)(Int32)-1; + if (partition.Map.Find(key, value)) + { + if (value == kRecursedErrorValue) + return S_FALSE; + file.ItemIndex = (int)(Int32)value; + } + else + { + value = Items.Size(); + file.ItemIndex = (int)(Int32)value; + if (partition.Map.Set(key, kRecursedErrorValue)) + return S_FALSE; + RINOK(ReadItem(volIndex, (int)fsIndex, lad, isDir, numRecurseAllowed)) + if (!partition.Map.Set(key, value)) + return S_FALSE; + } + return S_OK; +} + + +// (fsIndex = -1) means that it's metadata file + +HRESULT CInArchive::ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed) +{ + if (Items.Size() >= kNumItemsMax) + return S_FALSE; + CItem &item = Items.AddNew(); + + const CLogVol &vol = LogVols[volIndex]; + + const size_t size = lad.GetLen(); + if (size != vol.BlockSize) + return S_FALSE; + + CByteBuffer buf(size); + RINOK(ReadLad(volIndex, lad, buf)) + + CTag tag; + const Byte *p = buf; + RINOK(tag.Parse(p, size)) + + item.IsExtended = (tag.Id == DESC_TYPE_ExtendedFile); + const size_t kExtendOffset = item.IsExtended ? 40 : 0; + + if (size < kExtendOffset + 176) + return S_FALSE; + if (tag.Id != DESC_TYPE_File && + tag.Id != DESC_TYPE_ExtendedFile) + return S_FALSE; + + item.IcbTag.Parse(p + 16); + + if (fsIndex < 0) + { + if (item.IcbTag.FileType != ICB_FILE_TYPE_METADATA && + item.IcbTag.FileType != ICB_FILE_TYPE_METADATA_MIRROR) + return S_FALSE; + } + else if ( + item.IcbTag.FileType != ICB_FILE_TYPE_DIR && + item.IcbTag.FileType != ICB_FILE_TYPE_FILE) + return S_FALSE; + + item.Parse(p); + + _processedProgressBytes += (UInt64)item.NumLogBlockRecorded * vol.BlockSize + size; + + const UInt32 extendedAttrLen = Get32(p + 168 + kExtendOffset); + const UInt32 allocDescriptorsLen = Get32(p + 172 + kExtendOffset); + + if ((extendedAttrLen & 3) != 0) + return S_FALSE; + size_t pos = 176 + kExtendOffset; + if (extendedAttrLen > size - pos) + return S_FALSE; + /* + if (extendedAttrLen != 16) + { + if (extendedAttrLen < 24) + return S_FALSE; + CTag attrTag; + RINOK(attrTag.Parse(p + pos, size)); + if (attrTag.Id != DESC_TYPE_ExtendedAttrHeader) + return S_FALSE; + // UInt32 implAttrLocation = Get32(p + pos + 16); + // UInt32 applicationlAttrLocation = Get32(p + pos + 20); + } + */ + pos += extendedAttrLen; + + const int descType = item.IcbTag.GetDescriptorType(); + if (allocDescriptorsLen > size - pos) + return S_FALSE; + if (descType == ICB_DESC_TYPE_INLINE) + { + item.IsInline = true; + item.InlineData.CopyFrom(p + pos, allocDescriptorsLen); + } + else + { + item.IsInline = false; + if (descType != ICB_DESC_TYPE_SHORT && descType != ICB_DESC_TYPE_LONG) + return S_FALSE; + for (UInt32 i = 0; i < allocDescriptorsLen;) + { + CMyExtent e; + if (descType == ICB_DESC_TYPE_SHORT) + { + if (i + 8 > allocDescriptorsLen) + return S_FALSE; + CShortAllocDesc sad; + sad.Parse(p + pos + i); + e.Pos = sad.Pos; + e.Len = sad.Len; + e.PartitionRef = lad.Location.PartitionRef; + i += 8; + } + else + { + if (i + 16 > allocDescriptorsLen) + return S_FALSE; + CLongAllocDesc ladNew; + ladNew.Parse(p + pos + i); + e.Pos = ladNew.Location.Pos; + e.PartitionRef = ladNew.Location.PartitionRef; + e.Len = ladNew.Len; + i += 16; + } + item.Extents.Add(e); + } + } + + if (isDir != item.IcbTag.IsDir()) + return S_FALSE; + + if (item.IcbTag.IsDir()) + { + if (fsIndex < 0) + return S_FALSE; + + if (!item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) + return S_FALSE; + CByteBuffer buf2; + RINOK(ReadFromFile(volIndex, item, buf2)) + item.Size = 0; + item.Extents.ClearAndFree(); + item.InlineData.Free(); + + const Byte *p2 = buf2; + size_t size2 = buf2.Size(); + while (size2 != 0) + { + CFileId fileId; + { + const size_t cur = fileId.Parse(p2, size2); + if (cur == 0) + return S_FALSE; + p2 += cur; + size2 -= cur; + } + if (fileId.IsItLink_Parent()) + continue; + if (fileId.IsItLink_Deleted()) + continue; + { + CFile file; + // file.FileVersion = fileId.FileVersion; + // file.FileCharacteristics = fileId.FileCharacteristics; + // file.ImplUse = fileId.ImplUse; + file.Id = fileId.Id; + + _fileNameLengthTotal += file.Id.Data.Size(); + if (_fileNameLengthTotal > kFileNameLengthTotalMax) + return S_FALSE; + + item.SubFiles.Add(Files.Size()); + if (Files.Size() >= kNumFilesMax) + return S_FALSE; + Files.Add(file); + RINOK(ReadFileItem(volIndex, (unsigned)fsIndex, fileId.Icb, + fileId.IsItLink_Dir(), numRecurseAllowed)) + } + } + } + else + { + if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents) + return S_FALSE; + _numExtents += item.Extents.Size(); + + if (item.InlineData.Size() > kInlineExtentsSizeMax - _inlineExtentsSize) + return S_FALSE; + _inlineExtentsSize += item.InlineData.Size(); + } + + return S_OK; +} + + +HRESULT CInArchive::FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed) +{ + if ((_numRefs & 0xFFF) == 0) + { + RINOK(_progress->SetCompleted()) + } + if (numRecurseAllowed-- == 0) + return S_FALSE; + if (_numRefs >= kNumRefsMax) + return S_FALSE; + _numRefs++; + CRef ref; + ref.FileIndex = fileIndex; + ref.Parent = parent; + parent = (int)fs.Refs.Size(); + fs.Refs.Add(ref); + const CItem &item = Items[Files[fileIndex].ItemIndex]; + FOR_VECTOR (i, item.SubFiles) + { + RINOK(FillRefs(fs, item.SubFiles[i], parent, numRecurseAllowed)) + } + return S_OK; +} + + +API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size) +{ + UInt32 res = k_IsArc_Res_NO; + unsigned SecLogSize; + for (SecLogSize = 11;; SecLogSize -= 2) + { + if (SecLogSize < 9) + return res; + const UInt32 offset = (UInt32)256 << SecLogSize; + const UInt32 bufSize = (UInt32)1 << SecLogSize; + if (offset + bufSize > size) + res = k_IsArc_Res_NEED_MORE; + else + { + CTag tag; + if (tag.Parse(p + offset, bufSize) == S_OK) + if (tag.Id == DESC_TYPE_AnchorVolPtr) + { + if (Get32(p + offset + 12) == 256 && // TagLocation + tag.CrcLen >= 16) + return k_IsArc_Res_YES; + } + } + } +} + + +HRESULT CInArchive::Open2() +{ + Clear(); + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(_stream, fileSize)) + FileSize = fileSize; + + // Some UDFs contain additional pad zeros (2 KB). + // Seek to STREAM_SEEK_END for direct DVD reading can return 8 KB more, so we check last 16 KB. + // And when we read last block, result read size can be smaller than required size. + + /* + const size_t kBufSize = 1 << 14; + Byte buf[kBufSize]; + size_t readSize = (fileSize < kBufSize) ? (size_t)fileSize : kBufSize; + RINOK(InStream_SeekSet(_stream, fileSize - readSize)) + RINOK(ReadStream(_stream, buf, &readSize)); + size_t i = readSize; + for (;;) + { + const size_t kSecSizeMin = 1 << 8; + if (i < kSecSizeMin) + return S_FALSE; + i -= kSecSizeMin; + SecLogSize = (readSize - i < ((size_t)1 << 11)) ? 8 : 11; + CTag tag; + if (tag.Parse(buf + i, (1 << SecLogSize)) == S_OK) + if (tag.Id == DESC_TYPE_AnchorVolPtr) + break; + } + PhySize = fileSize; + CExtent extentVDS; + extentVDS.Parse(buf + i + 16); + */ + + /* + An Anchor Volume Descriptor Pointer structure shall be recorded in at + least 2 of the following 3 locations on the media: + Logical Sector 256. + Logical Sector (N - 256). + N + */ + + const size_t kBufSize = 1 << 11; + Byte buf[kBufSize]; + + for (SecLogSize = 11;; SecLogSize -= 2) + { + // Windows 10 uses unusual (SecLogSize = 9) + if (SecLogSize < 9) + return S_FALSE; + const UInt32 offset = (UInt32)256 << SecLogSize; + if (offset >= fileSize) + continue; + RINOK(InStream_SeekSet(_stream, offset)) + const size_t bufSize = (size_t)1 << SecLogSize; + size_t readSize = bufSize; + RINOK(ReadStream(_stream, buf, &readSize)) + if (readSize == bufSize) + { + CTag tag; + if (tag.Parse(buf, readSize) == S_OK) + if (tag.Id == DESC_TYPE_AnchorVolPtr) + { + if (Get32(buf + 12) == 256 && + tag.CrcLen >= 16) // TagLocation + break; + } + } + } + + PhySize = (UInt32)(256 + 1) << SecLogSize; + IsArc = true; + + // UDF 2.2.3 AnchorVolumeDescriptorPointer + + CExtent extentVDS; + extentVDS.Parse(buf + 16); + { + CExtent extentVDS2; + extentVDS2.Parse(buf + 24); + UpdatePhySize(extentVDS); + UpdatePhySize(extentVDS2); + } + + for (UInt32 location = 0; ; location++) + { + if (location >= (extentVDS.Len >> SecLogSize)) + return S_FALSE; + + const size_t bufSize = (size_t)1 << SecLogSize; + { + const UInt64 offs = ((UInt64)extentVDS.Pos + location) << SecLogSize; + RINOK(InStream_SeekSet(_stream, offs)) + const HRESULT res = ReadStream_FALSE(_stream, buf, bufSize); + if (res == S_FALSE && offs + bufSize > FileSize) + UnexpectedEnd = true; + RINOK(res) + } + + CTag tag; + RINOK(tag.Parse(buf, bufSize)) + + if (tag.Id == DESC_TYPE_Terminating) + break; + + if (tag.Id == DESC_TYPE_PrimVol) + { + CPrimeVol &pm = PrimeVols.AddNew(); + pm.Parse(buf); + continue; + } + + if (tag.Id == DESC_TYPE_Partition) + { + // Partition Descriptor + // ECMA 3/10.5 + // UDF 2.2.14 + if (Partitions.Size() >= kNumPartitionsMax) + return S_FALSE; + CPartition partition; + // const UInt32 volDescSeqNumer = Get32(buf + 16); + partition.Flags = Get16(buf + 20); + partition.Number = Get16(buf + 22); + partition.ContentsId.Parse(buf + 24); + + // memcpy(partition.ContentsUse, buf + 56, sizeof(partition.ContentsUse)); + // ContentsUse contains Partition Header Description. + // ECMA 4/14.3 + // UDF PartitionHeaderDescriptor 2.3.3 + + partition.AccessType = Get32(buf + 184); + partition.Pos = Get32(buf + 188); + partition.Len = Get32(buf + 192); + partition.ImplId.Parse(buf + 196); + // memcpy(partition.ImplUse, buf + 228, sizeof(partition.ImplUse)); + + PRF(printf("\nPartition number = %2d pos = %d len = %d", partition.Number, partition.Pos, partition.Len)); + Partitions.Add(partition); + continue; + } + + if (tag.Id == DESC_TYPE_LogicalVol) + { + /* Logical Volume Descriptor + ECMA 3/10.6 + UDF 2.60 2.2.4 */ + + if (LogVols.Size() >= kNumLogVolumesMax) + return S_FALSE; + CLogVol &vol = LogVols.AddNew(); + + vol.Id.Parse(buf + 84); + vol.BlockSize = Get32(buf + 212); + if (vol.BlockSize != ((UInt32)1 << SecLogSize)) + { + // UDF 2.2.4.2 LogicalBlockSize + // UDF probably doesn't allow different sizes + return S_FALSE; + } + /* + if (vol.BlockSize < 512 || vol.BlockSize > ((UInt32)1 << 30)) + return S_FALSE; + */ + + vol.DomainId.Parse(buf + 216); + + // ECMA 4/3.1 + // UDF 2.2.4.4 LogicalVolumeContentsUse + /* the extent in which the first File Set Descriptor Sequence + of the logical volume is recorded */ + vol.FileSetLocation.Parse(buf + 248); + // memcpy(vol.ContentsUse, buf + 248, sizeof(vol.ContentsUse)); + + vol.ImplId.Parse(buf + 272); + // memcpy(vol.ImplUse, buf + 304, sizeof(vol.ImplUse)); + // vol.IntegritySequenceExtent.Parse(buf + 432); + + const UInt32 mapTableLen = Get32(buf + 264); + const UInt32 numPartitionMaps = Get32(buf + 268); + if (numPartitionMaps > kNumPartitionsMax) + return S_FALSE; + + PRF(printf("\nLogicalVol numPartitionMaps = %2d", numPartitionMaps)); + + size_t pos = 440; + if (mapTableLen > bufSize - pos) + return S_FALSE; + const size_t posLimit = pos + mapTableLen; + + for (UInt32 i = 0; i < numPartitionMaps; i++) + { + // ECMA 3/10.7 Partition maps + if (pos + 2 > posLimit) + return S_FALSE; + CPartitionMap pm; + pm.Type = buf[pos + 0]; + // pm.Length = buf[pos + 1]; + const Byte len = buf[pos + 1]; + if (pos + len > posLimit) + return S_FALSE; + + // memcpy(pm.Data, buf + pos + 2, pm.Length - 2); + if (pm.Type == 1) + { + // ECMA 3/10.7.2 + if (len != 6) + return S_FALSE; + pm.VolumeSequenceNumber = Get16(buf + pos + 2); + pm.PartitionNumber = Get16(buf + pos + 4); + PRF(printf("\nPartitionMap type 1 PartitionNumber = %2d", pm.PartitionNumber)); + } + else if (pm.Type == 2) + { + if (len != 64) + return S_FALSE; + /* ECMA 10.7.3 / Type 2 Partition Map + 62 bytes: Partition Identifier. */ + + /* UDF + 2.2.8 "*UDF Virtual Partition" + 2.2.9 "*UDF Sparable Partition" + 2.2.10 "*UDF Metadata Partition" + */ + + if (Get16(buf + pos + 2) != 0) // reserved + return S_FALSE; + + pm.PartitionTypeId.Parse(buf + pos + 4); + pm.VolumeSequenceNumber = Get16(buf + pos + 36); + pm.PartitionNumber = Get16(buf + pos + 38); + + if (memcmp(pm.PartitionTypeId.Id, "*UDF Metadata Partition", 23) != 0) + return S_FALSE; + + // UDF 2.2.10 Metadata Partition Map + pm.MetadataFileLocation = Get32(buf + pos + 40); + // pm.MetadataMirrorFileLocation = Get32(buf + pos + 44); + // pm.MetadataBitmapFileLocation = Get32(buf + pos + 48); + // pm.AllocationUnitSize = Get32(buf + pos + 52); + // pm.AlignmentUnitSize = Get16(buf + pos + 56); + // pm.Flags = buf[pos + 58]; + + PRF(printf("\nPartitionMap type 2 PartitionNumber = %2d", pm.PartitionNumber)); + // Unsupported = true; + // return S_FALSE; + } + else + return S_FALSE; + pos += len; + vol.PartitionMaps.Add(pm); + } + continue; + } + + /* + if (tag.Id == DESC_TYPE_UnallocSpace) + { + // UInt32 volDescSeqNumer = Get32(buf + 16); + const UInt32 numAlocDescs = Get32(buf + 20); + // we need examples for (numAlocDescs != 0) case + if (numAlocDescs > (bufSize - 24) / 8) + return S_FALSE; + for (UInt32 i = 0; i < numAlocDescs; i++) + { + CExtent e; + e.Parse(buf + 24 + i * 8); + } + continue; + } + else + continue; + */ + } + + UInt64 totalSize = 0; + + unsigned volIndex; + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + CLogVol &vol = LogVols[volIndex]; + FOR_VECTOR (pmIndex, vol.PartitionMaps) + { + CPartitionMap &pm = vol.PartitionMaps[pmIndex]; + for (unsigned i = 0;; i++) + { + if (i == Partitions.Size()) + return S_FALSE; + CPartition &part = Partitions[i]; + if (part.Number == pm.PartitionNumber) + { + pm.PartitionIndex = i; + if (pm.Type == 2) + break; + + /* + if (part.VolIndex >= 0) + { + // it's for 2.60. Fix it + if (part.VolIndex != (int)volIndex) + return S_FALSE; + // return S_FALSE; + } + part.VolIndex = volIndex; + */ + + totalSize += (UInt64)part.Len << SecLogSize; + break; + } + } + } + } + + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + CLogVol &vol = LogVols[volIndex]; + FOR_VECTOR (pmIndex, vol.PartitionMaps) + { + CPartitionMap &pm = vol.PartitionMaps[pmIndex]; + if (pm.Type != 2) + continue; + + { + CLongAllocDesc lad; + lad.Len = vol.BlockSize; + lad.Location.Pos = pm.MetadataFileLocation; + // lad.Location.Pos = pm.MetadataMirrorFileLocation; + + lad.Location.PartitionRef = (UInt16)pmIndex; + + /* we need correct PartitionMaps[lad.Location.PartitionRef].PartitionIndex. + so we can use pmIndex or find (Type==1) PartitionMap */ + FOR_VECTOR (pmIndex2, vol.PartitionMaps) + { + const CPartitionMap &pm2 = vol.PartitionMaps[pmIndex2]; + if (pm2.PartitionNumber == pm.PartitionNumber && pm2.Type == 1) + { + lad.Location.PartitionRef = (UInt16)pmIndex2; + break; + } + } + + RINOK(ReadItem(volIndex, + -1, // (fsIndex = -1) means that it's metadata + lad, + false, // isDir + 1)) // numRecurseAllowed + } + { + const CItem &item = Items.Back(); + if (!CheckItemExtents(volIndex, item)) + return S_FALSE; + if (item.Extents.Size() != 1) + { + if (item.Extents.Size() < 1) + return S_FALSE; + /* Windows 10 writes empty record item.Extents[1]. + we ignore such extent here */ + for (unsigned k = 1; k < item.Extents.Size(); k++) + { + const CMyExtent &e = item.Extents[k]; + if (e.GetLen() != 0) + return S_FALSE; + } + } + + const CMyExtent &e = item.Extents[0]; + const CPartition &part = Partitions[pm.PartitionIndex]; + CPartition mp = part; + mp.IsMetadata = true; + // mp.Number = part.Number; + mp.Pos = part.Pos + e.Pos; + mp.Len = e.Len >> SecLogSize; + pm.PartitionIndex = Partitions.Add(mp); + } + // Items.DeleteBack(); // we can delete that metadata item + + /* + // short version of code to read metadata file. + RINOK(CInArchive::Read(volIndex, pmIndex, pm.MetadataFileLocation, 224, buf)); + CTag tag; + RINOK(tag.Parse(buf, 224)); + if (tag.Id != DESC_TYPE_ExtendedFile) + return S_FALSE; + CShortAllocDesc sad; + sad.Parse(buf + 216); + const CPartition &part = Partitions[pm.PartitionIndex]; + CPartition mp = part; + mp.IsMetadata = true; + // mp.Number = part.Number; + mp.Pos = part.Pos + sad.Pos; + mp.Len = sad.Len >> SecLogSize; + pm.PartitionIndex = Partitions.Add(mp); + */ + } + } + + RINOK(_progress->SetTotal(totalSize)) + + PRF(printf("\n Read files")); + + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + CLogVol &vol = LogVols[volIndex]; + + PRF(printf("\nLogVol %2d", volIndex)); + + CLongAllocDesc nextExtent = vol.FileSetLocation; + // while (nextExtent.ExtentLen != 0) + // for (int i = 0; i < 1; i++) + { + if (nextExtent.GetLen() < 512) + return S_FALSE; + CByteBuffer buf2(nextExtent.GetLen()); + RINOK(ReadLad(volIndex, nextExtent, buf2)) + const Byte *p = buf2; + const size_t size = nextExtent.GetLen(); + + CTag tag; + RINOK(tag.Parse(p, size)) + + /* + // commented in 22.01 + if (tag.Id == DESC_TYPE_ExtendedFile) + { + // ECMA 4 / 14.17 + // 2.60 ?? + return S_FALSE; + } + */ + + if (tag.Id != DESC_TYPE_FileSet) + return S_FALSE; + + PRF(printf("\n FileSet", volIndex)); + CFileSet fs; + fs.RecordingTime.Parse(p + 16); + // fs.InterchangeLevel = Get16(p + 18); + // fs.MaxInterchangeLevel = Get16(p + 20); + fs.FileSetNumber = Get32(p + 40); + fs.FileSetDescNumber = Get32(p + 44); + + fs.LogicalVolumeId.Parse(p + 112); + fs.Id.Parse(p + 304); + fs.CopyrightId.Parse(p + 336); + fs.AbstractId.Parse(p + 368); + + fs.RootDirICB.Parse(p + 400); + fs.DomainId.Parse(p + 416); + + // fs.SystemStreamDirICB.Parse(p + 464); + + vol.FileSets.Add(fs); + + // nextExtent.Parse(p + 448); + } + + FOR_VECTOR (fsIndex, vol.FileSets) + { + CFileSet &fs = vol.FileSets[fsIndex]; + const unsigned fileIndex = Files.Size(); + Files.AddNew(); + RINOK(ReadFileItem(volIndex, fsIndex, fs.RootDirICB, + true, // isDir + kNumRecursionLevelsMax)) + RINOK(FillRefs(fs, fileIndex, -1, kNumRecursionLevelsMax)) + } + } + + + for (volIndex = 0; volIndex < LogVols.Size(); volIndex++) + { + const CLogVol &vol = LogVols[volIndex]; + // bool showFileSetName = (vol.FileSets.Size() > 1); + FOR_VECTOR (fsIndex, vol.FileSets) + { + const CFileSet &fs = vol.FileSets[fsIndex]; + for (unsigned i = + // ((showVolName || showFileSetName) ? 0 : 1) + 0; i < fs.Refs.Size(); i++) + { + const CRef &ref = vol.FileSets[fsIndex].Refs[i]; + const CFile &file = Files[ref.FileIndex]; + const CItem &item = Items[file.ItemIndex]; + UInt64 size = item.Size; + + if (!item.IsRecAndAlloc() || !item.CheckChunkSizes() || !CheckItemExtents(volIndex, item)) + continue; + + FOR_VECTOR (extentIndex, item.Extents) + { + const CMyExtent &extent = item.Extents[extentIndex]; + const UInt32 len = extent.GetLen(); + if (len == 0) + continue; + if (size < len) + break; + + const unsigned partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex; + const UInt32 logBlockNumber = extent.Pos; + const CPartition &partition = Partitions[partitionIndex]; + const UInt64 offset = ((UInt64)partition.Pos << SecLogSize) + + (UInt64)logBlockNumber * vol.BlockSize; + UpdatePhySize(offset + len); + } + } + } + } + + { + const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1; + PhySize = (PhySize + secMask) & ~(UInt64)secMask; + } + + NoEndAnchor = true; + + if (PhySize < fileSize) + { + UInt64 rem = fileSize - PhySize; + const size_t secSize = (size_t)1 << SecLogSize; + + RINOK(InStream_SeekSet(_stream, PhySize)) + + // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end + + for (unsigned sec = 0; sec < 1024; sec++) + { + if (rem == 0) + break; + + size_t readSize = secSize; + if (readSize > rem) + readSize = (size_t)rem; + + RINOK(ReadStream(_stream, buf, &readSize)) + + if (readSize == 0) + break; + + // some udf contain many EndAnchors + if (readSize == secSize /* && NoEndAnchor */) + { + CTag tag; + if (tag.Parse(buf, readSize) == S_OK + && tag.Id == DESC_TYPE_AnchorVolPtr + && Get32(buf + 12) == (UInt32)((fileSize - rem) >> SecLogSize)) + { + NoEndAnchor = false; + rem -= readSize; + PhySize = fileSize - rem; + continue; + } + } + + size_t i; + for (i = 0; i < readSize && buf[i] == 0; i++); + if (i != readSize) + break; + rem -= readSize; + } + + if (rem == 0) + PhySize = fileSize; + } + + return S_OK; +} + + +HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress) +{ + _progress = progress; + _stream = inStream; + HRESULT res = Open2(); + if (res == S_FALSE && IsArc && !UnexpectedEnd) + Unsupported = true; + return res; + + /* + HRESULT res; + try + { + res = Open2(); + } + catch(...) + { + // Clear(); + // res = S_FALSE; + _stream.Release(); + throw; + } + _stream.Release(); + return res; + */ +} + +void CInArchive::Clear() +{ + IsArc = false; + Unsupported = false; + UnexpectedEnd = false; + NoEndAnchor = false; + + PhySize = 0; + FileSize = 0; + + Partitions.Clear(); + LogVols.Clear(); + PrimeVols.Clear(); + Items.Clear(); + Files.Clear(); + _fileNameLengthTotal = 0; + _numRefs = 0; + _numExtents = 0; + _inlineExtentsSize = 0; + _processedProgressBytes = 0; +} + + +static const char * const g_PartitionTypes[] = +{ + "Pseudo-Overwritable" // UDF + , "Read-Only" + , "Write-Once" + , "Rewritable" + , "Overwritable" +}; + + +static void AddComment_Align(UString &s) +{ + s += " "; +} + +static void AddComment_PropName(UString &s, const char *name) +{ + AddComment_Align(s); + s += name; + s += ": "; +} + +static void AddComment_UInt32(UString &s, const char *name, UInt32 val) +{ + AddComment_PropName(s, name); + s.Add_UInt32(val); + s.Add_LF(); +} + +static void AddComment_UInt32_2(UString &s, const char *name, UInt32 val) +{ + AddComment_Align(s); + AddComment_UInt32(s, name, val); +} + + +static void AddComment_UInt64(UString &s, const char *name, UInt64 val) +{ + AddComment_PropName(s, name); + s.Add_UInt64(val); + s.Add_LF(); +} + +static void AddComment_RegId(UString &s, const char *name, const CRegId &ri) +{ + AddComment_PropName(s, name); + ri.AddCommentTo(s); + s.Add_LF(); +} + +static void AddComment_RegId_Domain(UString &s, const char *name, const CRegId &ri) +{ + AddComment_PropName(s, name); + ri.AddCommentTo(s); + { + UString s2; + ri.AddUdfVersionTo(s2); + if (!s2.IsEmpty()) + { + s += "::"; + s += s2; + } + } + s.Add_LF(); +} + + +// UDF 6.3.1 OS Class + +static const char * const g_OsClasses[] = +{ + NULL + , "DOS" + , "OS/2" + , "Macintosh OS" + , "UNIX" + , "Windows 9x" + , "Windows NT" + , "OS/400" + , "BeOS" + , "Windows CE" +}; + +// UDF 6.3.2 OS Identifier + +static const char * const g_OsIds_Unix[] = +{ + NULL // "Generic" + , "AIX" + , "SUN OS / Solaris" + , "HP/UX" + , "Silicon Graphics Irix" + , "Linux" + , "MKLinux" + , "FreeBSD" + , "NetBSD" +}; + +static void AddOs_Class_Id(UString &s, const Byte *p) +{ + // UDF 2.1.5.3 Implementation Identifier Suffix + // Appendix 6.3 Operating System Identifiers. + const Byte osClass = p[0]; + if (osClass != 0) + { + s += "::"; + s += TypeToString(g_OsClasses, Z7_ARRAY_SIZE(g_OsClasses), osClass); + } + const Byte osId = p[1]; + if (osId != 0) + { + s += "::"; + if (osClass == 4) // unix + { + s += TypeToString(g_OsIds_Unix, Z7_ARRAY_SIZE(g_OsIds_Unix), osId); + } + else + s.Add_UInt32(osId); + } +} + + +static void AddComment_RegId_Impl(UString &s, const char *name, const CRegId &ri) +{ + AddComment_PropName(s, name); + ri.AddCommentTo(s); + { + AddOs_Class_Id(s, ri.Suffix); + } + s.Add_LF(); +} + + +static void AddComment_RegId_UdfId(UString &s, const char *name, const CRegId &ri) +{ + AddComment_PropName(s, name); + ri.AddCommentTo(s); + { + // UDF 2.1.5.3 + // UDF Identifier Suffix format + UString s2; + ri.AddUdfVersionTo(s2); + if (!s2.IsEmpty()) + { + s += "::"; + s += s2; + } + AddOs_Class_Id(s, &ri.Suffix[2]); + } + s.Add_LF(); +} + +static void AddComment_DString32(UString &s, const char *name, const CDString32 &d) +{ + AddComment_Align(s); + AddComment_PropName(s, name); + s += d.GetString(); + s.Add_LF(); +} + +UString CInArchive::GetComment() const +{ + UString s; + { + s += "Primary Volumes:"; + s.Add_LF(); + FOR_VECTOR (i, PrimeVols) + { + if (i != 0) + s.Add_LF(); + const CPrimeVol &pv = PrimeVols[i]; + // AddComment_UInt32(s, "VolumeDescriptorSequenceNumber", pv.VolumeDescriptorSequenceNumber); + // if (PrimeVols.Size() != 1 || pv.PrimaryVolumeDescriptorNumber != 0) + AddComment_UInt32(s, "PrimaryVolumeDescriptorNumber", pv.PrimaryVolumeDescriptorNumber); + // if (pv.MaximumVolumeSequenceNumber != 1 || pv.VolumeSequenceNumber != 1) + AddComment_UInt32(s, "VolumeSequenceNumber", pv.VolumeSequenceNumber); + if (pv.MaximumVolumeSequenceNumber != 1) + AddComment_UInt32(s, "MaximumVolumeSequenceNumber", pv.MaximumVolumeSequenceNumber); + AddComment_PropName(s, "VolumeId"); + s += pv.VolumeId.GetString(); + s.Add_LF(); + AddComment_PropName(s, "VolumeSetId"); + s += pv.VolumeSetId.GetString(); + s.Add_LF(); + // AddComment_UInt32(s, "InterchangeLevel", pv.InterchangeLevel); + // AddComment_UInt32(s, "MaximumInterchangeLevel", pv.MaximumInterchangeLevel); + AddComment_RegId(s, "ApplicationId", pv.ApplicationId); + AddComment_RegId_Impl(s, "ImplementationId", pv.ImplId); + } + } + { + s += "Partitions:"; + s.Add_LF(); + FOR_VECTOR (i, Partitions) + { + if (i != 0) + s.Add_LF(); + const CPartition &part = Partitions[i]; + AddComment_UInt32(s, "PartitionIndex", i); + AddComment_UInt32(s, "PartitionNumber", part.Number); + if (part.IsMetadata) + AddComment_UInt32(s, "IsMetadata", 1); + else + { + AddComment_RegId(s, "ContentsId", part.ContentsId); + AddComment_RegId_Impl(s, "ImplementationId", part.ImplId); + AddComment_PropName(s, "AccessType"); + s += TypeToString(g_PartitionTypes, Z7_ARRAY_SIZE(g_PartitionTypes), part.AccessType); + s.Add_LF(); + } + AddComment_UInt64(s, "Size", (UInt64)part.Len << SecLogSize); + AddComment_UInt64(s, "Pos", (UInt64)part.Pos << SecLogSize); + } + } + s += "Logical Volumes:"; + s.Add_LF(); + { + FOR_VECTOR (i, LogVols) + { + if (i != 0) + s.Add_LF(); + const CLogVol &vol = LogVols[i]; + if (LogVols.Size() != 1) + AddComment_UInt32(s, "Number", i); + AddComment_PropName(s, "Id"); + s += vol.Id.GetString(); + s.Add_LF(); + AddComment_UInt32(s, "BlockSize", vol.BlockSize); + AddComment_RegId_Domain(s, "DomainId", vol.DomainId); + AddComment_RegId_Impl(s, "ImplementationId", vol.ImplId); + // AddComment_UInt64(s, "IntegritySequenceExtent_Len", vol.IntegritySequenceExtent.Len); + // AddComment_UInt64(s, "IntegritySequenceExtent_Pos", (UInt64)vol.IntegritySequenceExtent.Pos << SecLogSize); + + s += " Partition Maps:"; + s.Add_LF(); + { + FOR_VECTOR (j, vol.PartitionMaps) + { + if (j != 0) + s.Add_LF(); + const CPartitionMap &pm = vol.PartitionMaps[j]; + AddComment_UInt32_2(s, "PartitionMap", j); + AddComment_UInt32_2(s, "Type", pm.Type); + AddComment_UInt32_2(s, "VolumeSequenceNumber", pm.VolumeSequenceNumber); + AddComment_UInt32_2(s, "PartitionNumber", pm.PartitionNumber); + if (pm.Type == 2) + { + AddComment_UInt32_2(s, "MetadataFileLocation", pm.MetadataFileLocation); + // AddComment_UInt32_2(s, "MetadataMirrorFileLocation", pm.MetadataMirrorFileLocation); + // AddComment_UInt32_2(s, "MetadataBitmapFileLocation", pm.MetadataBitmapFileLocation); + // AddComment_UInt32_2(s, "AllocationUnitSize", pm.AllocationUnitSize); + // AddComment_UInt32_2(s, "AlignmentUnitSize", pm.AlignmentUnitSize); + // AddComment_UInt32_2(s, "Flags", pm.Flags); + AddComment_Align(s); AddComment_RegId_UdfId(s, "PartitionTypeId", pm.PartitionTypeId); + } + } + } + s += " File Sets:"; + s.Add_LF(); + { + FOR_VECTOR (j, vol.FileSets) + { + if (j != 0) + s.Add_LF(); + const CFileSet &fs = vol.FileSets[j]; + AddComment_Align(s); AddComment_UInt32(s, "FileSetNumber", fs.FileSetNumber); + AddComment_Align(s); AddComment_UInt32(s, "FileSetDescNumber", fs.FileSetDescNumber); + + AddComment_Align(s); + AddComment_PropName(s, "LogicalVolumeId"); + s += fs.LogicalVolumeId.GetString(); + s.Add_LF(); + + AddComment_DString32(s, "Id", fs.Id); + AddComment_DString32(s, "CopyrightId", fs.CopyrightId); + AddComment_DString32(s, "AbstractId", fs.AbstractId); + + AddComment_Align(s); + AddComment_RegId_Domain(s, "DomainId", fs.DomainId); + } + } + } + } + return s; +} + +static UString GetSpecName(const UString &name) +{ + UString name2 = name; + name2.Trim(); + if (name2.IsEmpty()) + return UString("[]"); + return name; +} + +static void UpdateWithName(UString &res, const UString &addString) +{ + if (res.IsEmpty()) + res = addString; + else + res.Insert(0, addString + WCHAR_PATH_SEPARATOR); +} + +UString CInArchive::GetItemPath(unsigned volIndex, unsigned fsIndex, unsigned refIndex, + bool showVolName, bool showFsName) const +{ + // showVolName = true; + const CLogVol &vol = LogVols[volIndex]; + const CFileSet &fs = vol.FileSets[fsIndex]; + + UString name; + + for (;;) + { + const CRef &ref = fs.Refs[refIndex]; + // we break on root file (that probably has empty name) + if (ref.Parent < 0) + break; + refIndex = (unsigned)ref.Parent; + UpdateWithName(name, GetSpecName(Files[ref.FileIndex].GetName())); + } + + if (showFsName) + { + UString newName ("File Set "); + newName.Add_UInt32(fsIndex); + UpdateWithName(name, newName); + } + + if (showVolName) + { + UString newName; + newName.Add_UInt32(volIndex); + UString newName2 = vol.GetName(); + if (newName2.IsEmpty()) + newName2 = "Volume"; + newName.Add_Minus(); + newName += newName2; + UpdateWithName(name, newName); + } + return name; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Udf/UdfIn.h 2015-11-20 20:39:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Udf/UdfIn.h 2023-03-23 08:00:00.000000000 +0000 @@ -1,394 +1,507 @@ -// Archive/UdfIn.h -- UDF / ECMA-167 - -#ifndef __ARCHIVE_UDF_IN_H -#define __ARCHIVE_UDF_IN_H - -#include "../../../Common/IntToString.h" -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyCom.h" -#include "../../../Common/MyMap.h" -#include "../../../Common/MyString.h" - -#include "../../IStream.h" - -namespace NArchive { -namespace NUdf { - -// ---------- ECMA Part 1 ---------- - -// ECMA 1/7.2.12 - -/* -struct CDString32 -{ - Byte Data[32]; - - void Parse(const Byte *buf); - // UString GetString() const; -}; -*/ - -struct CDString128 -{ - Byte Data[128]; - - void Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } - UString GetString() const; -}; - -struct CDString -{ - CByteBuffer Data; - - void Parse(const Byte *p, unsigned size); - UString GetString() const; -}; - - -// ECMA 1/7.3 - -struct CTime -{ - Byte Data[12]; - - unsigned GetType() const { return Data[1] >> 4; } - bool IsLocal() const { return GetType() == 1; } - int GetMinutesOffset() const - { - int t = (Data[0] | ((unsigned)Data[1] << 8)) & 0xFFF; - if ((t >> 11) != 0) - t -= (1 << 12); - return (t > (60 * 24) || t < -(60 * 24)) ? 0 : t; - } - unsigned GetYear() const { return (Data[2] | ((unsigned)Data[3] << 8)); } - void Parse(const Byte *buf); -}; - - -// ECMA 1/7.4 - -/* -struct CRegId -{ - Byte Flags; - char Id[23]; - char Suffix[8]; - - void Parse(const Byte *buf); -}; -*/ - -// ---------- ECMA Part 3: Volume Structure ---------- - -// ECMA 3/10.5 - -struct CPartition -{ - // UInt16 Flags; - UInt16 Number; - // CRegId ContentsId; - // Byte ContentsUse[128]; - // UInt32 AccessType; - - UInt32 Pos; - UInt32 Len; - - // CRegId ImplId; - // Byte ImplUse[128]; - - int VolIndex; - CMap32 Map; - - CPartition(): VolIndex(-1) {} - - // bool IsNsr() const { return (strncmp(ContentsId.Id, "+NSR0", 5) == 0); } - // bool IsAllocated() const { return ((Flags & 1) != 0); } -}; - -struct CLogBlockAddr -{ - UInt32 Pos; - UInt16 PartitionRef; - - void Parse(const Byte *buf); -}; - -enum EShortAllocDescType -{ - SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated = 0, - SHORT_ALLOC_DESC_TYPE_NotRecordedButAllocated = 1, - SHORT_ALLOC_DESC_TYPE_NotRecordedAndNotAllocated = 2, - SHORT_ALLOC_DESC_TYPE_NextExtent = 3 -}; - -struct CShortAllocDesc -{ - UInt32 Len; - UInt32 Pos; - - // 4/14.14.1 - // UInt32 GetLen() const { return Len & 0x3FFFFFFF; } - // UInt32 GetType() const { return Len >> 30; } - // bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } - void Parse(const Byte *buf); -}; - -/* -struct CADImpUse -{ - UInt16 Flags; - UInt32 UdfUniqueId; - void Parse(const Byte *buf); -}; -*/ - -struct CLongAllocDesc -{ - UInt32 Len; - CLogBlockAddr Location; - - // Byte ImplUse[6]; - // CADImpUse adImpUse; // UDF - - UInt32 GetLen() const { return Len & 0x3FFFFFFF; } - UInt32 GetType() const { return Len >> 30; } - bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } - void Parse(const Byte *buf); -}; - -struct CPartitionMap -{ - Byte Type; - // Byte Len; - - // Type - 1 - // UInt16 VolSeqNumber; - UInt16 PartitionNumber; - - // Byte Data[256]; - - int PartitionIndex; -}; - -// ECMA 4/14.6 - -enum EIcbFileType -{ - ICB_FILE_TYPE_DIR = 4, - ICB_FILE_TYPE_FILE = 5 -}; - -enum EIcbDescriptorType -{ - ICB_DESC_TYPE_SHORT = 0, - ICB_DESC_TYPE_LONG = 1, - ICB_DESC_TYPE_EXTENDED = 2, - ICB_DESC_TYPE_INLINE = 3 -}; - -struct CIcbTag -{ - // UInt32 PriorDirectNum; - // UInt16 StrategyType; - // UInt16 StrategyParam; - // UInt16 MaxNumOfEntries; - Byte FileType; - // CLogBlockAddr ParentIcb; - UInt16 Flags; - - bool IsDir() const { return FileType == ICB_FILE_TYPE_DIR; } - int GetDescriptorType() const { return Flags & 3; } - void Parse(const Byte *p); -}; - -// const Byte FILEID_CHARACS_Existance = (1 << 0); -const Byte FILEID_CHARACS_Parent = (1 << 3); - -struct CFile -{ - // UInt16 FileVersion; - // Byte FileCharacteristics; - // CByteBuffer ImplUse; - CDString Id; - - int ItemIndex; - - CFile(): /* FileVersion(0), FileCharacteristics(0), */ ItemIndex(-1) {} - UString GetName() const { return Id.GetString(); } -}; - -struct CMyExtent -{ - UInt32 Pos; - UInt32 Len; - unsigned PartitionRef; - - UInt32 GetLen() const { return Len & 0x3FFFFFFF; } - UInt32 GetType() const { return Len >> 30; } - bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } -}; - -struct CItem -{ - CIcbTag IcbTag; - - // UInt32 Uid; - // UInt32 Gid; - // UInt32 Permissions; - // UInt16 FileLinkCount; - // Byte RecordFormat; - // Byte RecordDisplayAttr; - // UInt32 RecordLen; - UInt64 Size; - UInt64 NumLogBlockRecorded; - CTime ATime; - CTime MTime; - // CTime AttrtTime; - // UInt32 CheckPoint; - // CLongAllocDesc ExtendedAttrIcb; - // CRegId ImplId; - // UInt64 UniqueId; - - bool IsInline; - CByteBuffer InlineData; - CRecordVector Extents; - CUIntVector SubFiles; - - void Parse(const Byte *buf); - - bool IsRecAndAlloc() const - { - FOR_VECTOR (i, Extents) - if (!Extents[i].IsRecAndAlloc()) - return false; - return true; - } - - UInt64 GetChunksSumSize() const - { - if (IsInline) - return InlineData.Size(); - UInt64 size = 0; - FOR_VECTOR (i, Extents) - size += Extents[i].GetLen(); - return size; - } - - bool CheckChunkSizes() const { return GetChunksSumSize() == Size; } - - bool IsDir() const { return IcbTag.IsDir(); } -}; - -struct CRef -{ - int Parent; - unsigned FileIndex; -}; - - -// ECMA 4 / 14.1 -struct CFileSet -{ - CTime RecodringTime; - // UInt16 InterchangeLevel; - // UInt16 MaxInterchangeLevel; - // UInt32 FileSetNumber; - // UInt32 FileSetDescNumber; - // CDString32 Id; - // CDString32 CopyrightId; - // CDString32 AbstractId; - - CLongAllocDesc RootDirICB; - // CRegId DomainId; - // CLongAllocDesc SystemStreamDirICB; - - CRecordVector Refs; -}; - - -// ECMA 3/10.6 - -struct CLogVol -{ - CDString128 Id; - UInt32 BlockSize; - // CRegId DomainId; - - // Byte ContentsUse[16]; - CLongAllocDesc FileSetLocation; // UDF - - // CRegId ImplId; - // Byte ImplUse[128]; - - CObjectVector PartitionMaps; - CObjectVector FileSets; - - UString GetName() const { return Id.GetString(); } -}; - -struct CProgressVirt -{ - virtual HRESULT SetTotal(UInt64 numBytes) PURE; - virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) PURE; - virtual HRESULT SetCompleted() PURE; -}; - -class CInArchive -{ - IInStream *_stream; - CProgressVirt *_progress; - - HRESULT Read(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len, Byte *buf); - HRESULT Read(int volIndex, const CLongAllocDesc &lad, Byte *buf); - HRESULT ReadFromFile(int volIndex, const CItem &item, CByteBuffer &buf); - - HRESULT ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); - HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed); - - HRESULT Open2(); - HRESULT FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed); - - UInt64 _processedProgressBytes; - - UInt64 _fileNameLengthTotal; - int _numRefs; - UInt32 _numExtents; - UInt64 _inlineExtentsSize; - bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const; - -public: - CObjectVector Partitions; - CObjectVector LogVols; - - CObjectVector Items; - CObjectVector Files; - - unsigned SecLogSize; - UInt64 PhySize; - UInt64 FileSize; - - bool IsArc; - bool Unsupported; - bool UnexpectedEnd; - bool NoEndAnchor; - - void UpdatePhySize(UInt64 val) - { - if (PhySize < val) - PhySize = val; - } - HRESULT Open(IInStream *inStream, CProgressVirt *progress); - void Clear(); - - UString GetComment() const; - UString GetItemPath(int volIndex, int fsIndex, int refIndex, - bool showVolName, bool showFsName) const; - - bool CheckItemExtents(int volIndex, const CItem &item) const; -}; - -API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size); - -}} - -#endif +// Archive/UdfIn.h -- UDF / ECMA-167 + +#ifndef ZIP7_INC_ARCHIVE_UDF_IN_H +#define ZIP7_INC_ARCHIVE_UDF_IN_H + +#include "../../../Common/IntToString.h" +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/MyMap.h" +#include "../../../Common/MyString.h" + +#include "../../IStream.h" + +namespace NArchive { +namespace NUdf { + +// ---------- ECMA Part 1 ---------- + +// ECMA 1/7.2.12 +// UDF 2.1.3 + +struct CDString32 +{ + Byte Data[32]; + + void Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } + UString GetString() const; +}; + +struct CDString128 +{ + Byte Data[128]; + + void Parse(const Byte *buf) { memcpy(Data, buf, sizeof(Data)); } + UString GetString() const; +}; + +struct CDString +{ + CByteBuffer Data; + + void Parse(const Byte *p, unsigned size); + UString GetString() const; +}; + + +// ECMA 1/7.3 +// UDF 2.1.4 timestamp + +struct CTime +{ + Byte Data[12]; + + unsigned GetType() const { return Data[1] >> 4; } + bool IsLocal() const { return GetType() == 1; } + int GetMinutesOffset() const + { + int t = (Data[0] | ((unsigned)Data[1] << 8)) & 0xFFF; + if ((t >> 11) != 0) + t -= (1 << 12); + return (t > (60 * 24) || t < -(60 * 24)) ? 0 : t; + } + unsigned GetYear() const { return (Data[2] | ((unsigned)Data[3] << 8)); } + void Parse(const Byte *buf); +}; + + +// ECMA 1/7.4 regid +// UDF 2.1.5 EntityID + +struct CRegId +{ + Byte Flags; + char Id[23]; + Byte Suffix[8]; + + void Parse(const Byte *buf); + void AddCommentTo(UString &s) const; + void AddUdfVersionTo(UString &s) const; +}; + + + +// ---------- ECMA Part 3: Volume Structure ---------- + +// ECMA 3/7.1 + +struct CExtent +{ + UInt32 Len; + UInt32 Pos; // logical sector number + + void Parse(const Byte *p); +}; + + +// ECMA 3/10.1 +// UDF 2.2.2 PrimaryVolumeDescriptor + +struct CPrimeVol +{ + // UInt32 VolumeDescriptorSequenceNumber; + UInt32 PrimaryVolumeDescriptorNumber; + CDString32 VolumeId; + UInt16 VolumeSequenceNumber; + UInt16 MaximumVolumeSequenceNumber; + // UInt16 InterchangeLevel; + // UInt16 MaximumInterchangeLevel; + // UInt32 CharacterSetList; + // UInt32 MaximumCharacterSetList; + CDString128 VolumeSetId; + // charspec DescriptorCharacterSet; // (1/7.2.1) + // charspec ExplanatoryCharacterSet; // (1/7.2.1) + // CExtent VolumeAbstract; + // CExtent VolumeCopyrightNotice; + CRegId ApplicationId; + CTime RecordingTime; + CRegId ImplId; + // bytes ImplementationUse + // UInt32 PredecessorVolumeDescriptorSequenceLocation; + // UInt16 Flags; + + void Parse(const Byte *p); +}; + + +// ECMA 3/10.5 +// UDF 2.2.14 PartitionDescriptor + +struct CPartition +{ + UInt32 Pos; + UInt32 Len; + + UInt16 Flags; + UInt16 Number; + CRegId ContentsId; + // Byte ContentsUse[128]; + UInt32 AccessType; + + CRegId ImplId; + // Byte ImplUse[128]; + + // int VolIndex; + CMap32 Map; + + bool IsMetadata; + + CPartition(): + // VolIndex(-1), + IsMetadata(false) {} + + // bool IsNsr() const { return (strncmp(ContentsId.Id, "+NSR0", 5) == 0); } + // bool IsAllocated() const { return ((Flags & 1) != 0); } +}; + + +// ECMA 4/7.1 lb_addr + +struct CLogBlockAddr +{ + UInt32 Pos; + UInt16 PartitionRef; + + void Parse(const Byte *p); +}; + + +enum EShortAllocDescType +{ + SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated = 0, + SHORT_ALLOC_DESC_TYPE_NotRecordedButAllocated = 1, + SHORT_ALLOC_DESC_TYPE_NotRecordedAndNotAllocated = 2, + SHORT_ALLOC_DESC_TYPE_NextExtent = 3 +}; + + +// ECMA 4/14.14.1 short_ad + +struct CShortAllocDesc +{ + UInt32 Len; + UInt32 Pos; + + // UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + // UInt32 GetType() const { return Len >> 30; } + // bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } + void Parse(const Byte *p); +}; + +/* +struct CADImpUse +{ + UInt16 Flags; + UInt32 UdfUniqueId; + void Parse(const Byte *p); +}; +*/ + +// ECMA 4/14.14.2 long_ad +// UDF 2.3.10.1 + +struct CLongAllocDesc +{ + UInt32 Len; + CLogBlockAddr Location; + + // Byte ImplUse[6]; + // CADImpUse adImpUse; // UDF + + UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + UInt32 GetType() const { return Len >> 30; } + bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } + void Parse(const Byte *p); +}; + + +// ECMA 3/10.7 Partition maps +// UDF 2.2.8-2.2.10 Partition Maps + +struct CPartitionMap +{ + unsigned PartitionIndex; + + Byte Type; + // Byte Len; + + // ECMA 10.7.2 + UInt16 VolumeSequenceNumber; + UInt16 PartitionNumber; + + CRegId PartitionTypeId; + + // UDF 2.2.10 Metadata Partition Map + UInt32 MetadataFileLocation; + // UInt32 MetadataMirrorFileLocation; + // UInt32 MetadataBitmapFileLocation; + // UInt32 AllocationUnitSize; // (Blocks) + // UInt16 AlignmentUnitSize; // (Blocks) + // Byte Flags; + + // Byte Data[256]; + // CPartitionMap(): PartitionIndex(-1) {} +}; + + +// ECMA 4/14.6.6 + +enum EIcbFileType +{ + ICB_FILE_TYPE_DIR = 4, + ICB_FILE_TYPE_FILE = 5, + + ICB_FILE_TYPE_METADATA = 250, // 2.2.13.1 Metadata File + ICB_FILE_TYPE_METADATA_MIRROR = 251 +}; + +enum EIcbDescriptorType +{ + ICB_DESC_TYPE_SHORT = 0, + ICB_DESC_TYPE_LONG = 1, + ICB_DESC_TYPE_EXTENDED = 2, + ICB_DESC_TYPE_INLINE = 3 +}; + +// ECMA 4/14.6 +// UDF 3.3.2 + +struct CIcbTag +{ + // UInt32 PriorDirectNum; + // UInt16 StrategyType; + // UInt16 StrategyParam; + // UInt16 MaxNumOfEntries; + Byte FileType; + // CLogBlockAddr ParentIcb; + UInt16 Flags; + + bool IsDir() const { return FileType == ICB_FILE_TYPE_DIR; } + int GetDescriptorType() const { return Flags & 3; } + void Parse(const Byte *p); +}; + + +// ECMA 4/14.4.3 +// UDF 2.3.4.2 FileCharacteristics + +// const Byte FILEID_CHARACS_Existance = (1 << 0); +const Byte FILEID_CHARACS_Dir = (1 << 1); +const Byte FILEID_CHARACS_Deleted = (1 << 2); +const Byte FILEID_CHARACS_Parent = (1 << 3); +// const Byte FILEID_CHARACS_Metadata = (1 << 4); + +struct CFile +{ + int ItemIndex; + // UInt16 FileVersion; + // Byte FileCharacteristics; + // CByteBuffer ImplUse; + CDString Id; + + CFile(): /* FileVersion(0), FileCharacteristics(0), */ ItemIndex(-1) {} + UString GetName() const { return Id.GetString(); } +}; + + +struct CMyExtent +{ + UInt32 Pos; + UInt32 Len; + unsigned PartitionRef; // index in CLogVol::PartitionMaps + + UInt32 GetLen() const { return Len & 0x3FFFFFFF; } + UInt32 GetType() const { return Len >> 30; } + bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; } +}; + + +struct CItem +{ + CIcbTag IcbTag; + + // UInt32 Uid; + // UInt32 Gid; + // UInt32 Permissions; + UInt16 FileLinkCount; + // Byte RecordFormat; + // Byte RecordDisplayAttr; + // UInt32 RecordLen; + UInt64 Size; + UInt64 NumLogBlockRecorded; + // UInt64 ObjectSize; + + CTime ATime; + CTime MTime; + CTime AttribTime; // Attribute time : most recent date and time of the day of file creation or modification of the attributes of. + CTime CreateTime; + // UInt32 CheckPoint; + // CLongAllocDesc ExtendedAttrIcb; + // CRegId ImplId; + // UInt64 UniqueId; + + bool IsExtended; + bool IsInline; + CByteBuffer InlineData; + CRecordVector Extents; + CUIntVector SubFiles; + + void Parse(const Byte *p); + + bool IsRecAndAlloc() const + { + FOR_VECTOR (i, Extents) + if (!Extents[i].IsRecAndAlloc()) + return false; + return true; + } + + UInt64 GetChunksSumSize() const + { + if (IsInline) + return InlineData.Size(); + UInt64 size = 0; + FOR_VECTOR (i, Extents) + size += Extents[i].GetLen(); + return size; + } + + bool CheckChunkSizes() const { return GetChunksSumSize() == Size; } + + bool IsDir() const { return IcbTag.IsDir(); } +}; + + +struct CRef +{ + unsigned FileIndex; + int Parent; +}; + + +// ECMA 4 / 14.1 +struct CFileSet +{ + CRecordVector Refs; + + CTime RecordingTime; + // UInt16 InterchangeLevel; + // UInt16 MaxInterchangeLevel; + UInt32 FileSetNumber; + UInt32 FileSetDescNumber; + CDString128 LogicalVolumeId; + CDString32 Id; + CDString32 CopyrightId; + CDString32 AbstractId; + + CLongAllocDesc RootDirICB; + CRegId DomainId; + // CLongAllocDesc SystemStreamDirICB; +}; + + +/* 8.3 Volume descriptors +8.4 +A Volume Descriptor Sequence: + shall contain one or more Primary Volume Descriptors. +*/ + +// ECMA 3/10.6 +// UDF 2.2.4 LogicalVolumeDescriptor + +struct CLogVol +{ + CObjectVector PartitionMaps; + CObjectVector FileSets; + + UInt32 BlockSize; + CDString128 Id; + CRegId DomainId; + + // Byte ContentsUse[16]; + CLongAllocDesc FileSetLocation; // UDF + + CRegId ImplId; + // Byte ImplUse[128]; + // CExtent IntegritySequenceExtent; + + UString GetName() const { return Id.GetString(); } +}; + + +Z7_PURE_INTERFACES_BEGIN +struct Z7_DECLSPEC_NOVTABLE CProgressVirt +{ + virtual HRESULT SetTotal(UInt64 numBytes) =0; \ + virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) =0; \ + virtual HRESULT SetCompleted() =0; \ +}; +Z7_PURE_INTERFACES_END + +class CInArchive +{ +public: + CObjectVector LogVols; + CObjectVector Items; + CObjectVector Files; + CObjectVector Partitions; + + unsigned SecLogSize; + UInt64 PhySize; + UInt64 FileSize; + + bool IsArc; + bool Unsupported; + bool UnexpectedEnd; + bool NoEndAnchor; + + CObjectVector PrimeVols; + + HRESULT Open(IInStream *inStream, CProgressVirt *progress); + void Clear(); + + UString GetComment() const; + UString GetItemPath(unsigned volIndex, unsigned fsIndex, unsigned refIndex, + bool showVolName, bool showFsName) const; + + bool CheckItemExtents(unsigned volIndex, const CItem &item) const; + +private: + IInStream *_stream; + CProgressVirt *_progress; + + HRESULT Read(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len, Byte *buf); + HRESULT ReadLad(unsigned volIndex, const CLongAllocDesc &lad, Byte *buf); + HRESULT ReadFromFile(unsigned volIndex, const CItem &item, CByteBuffer &buf); + + HRESULT ReadFileItem(unsigned volIndex, unsigned fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed); + HRESULT ReadItem(unsigned volIndex, int fsIndex, const CLongAllocDesc &lad, bool isDir, int numRecurseAllowed); + + HRESULT Open2(); + HRESULT FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed); + + UInt64 _processedProgressBytes; + + UInt64 _fileNameLengthTotal; + unsigned _numRefs; + UInt32 _numExtents; + UInt64 _inlineExtentsSize; + bool CheckExtent(unsigned volIndex, unsigned partitionRef, UInt32 blockPos, UInt32 len) const; + + void UpdatePhySize(UInt64 val) + { + if (PhySize < val) + PhySize = val; + } + + void UpdatePhySize(const CExtent &e) + { + UpdatePhySize(((UInt64)e.Pos << SecLogSize) + e.Len); + } +}; + +API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/UefiHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/UefiHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/UefiHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/UefiHandler.cpp 2024-06-17 08:00:00.000000000 +0000 @@ -1,1618 +1,1884 @@ -// UefiHandler.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include "../../../C/7zCrc.h" -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" -#include "../../../C/LzmaDec.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/StringConvert.h" - -#include "../../Windows/PropVariantUtils.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" -#include "../Compress/LzhDecoder.h" - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) -#define Get24(p) (Get32(p) & 0xFFFFFF) - -namespace NArchive { -namespace NUefi { - -static const size_t kBufTotalSizeMax = (1 << 29); -static const unsigned kNumFilesMax = (1 << 18); -static const unsigned kLevelMax = 64; - -static const unsigned kFvHeaderSize = 0x38; - -static const unsigned kGuidSize = 16; -#define CAPSULE_SIGNATURE \ - { 0xBD,0x86,0x66,0x3B,0x76,0x0D,0x30,0x40,0xB7,0x0E,0xB5,0x51,0x9E,0x2F,0xC5,0xA0 } -static const Byte kCapsuleSig[kGuidSize] = CAPSULE_SIGNATURE; - -static const unsigned kFfsGuidOffset = 16; -#define FFS_SIGNATURE \ - { 0xD9,0x54,0x93,0x7A,0x68,0x04,0x4A,0x44,0x81,0xCE,0x0B,0xF6,0x17,0xD8,0x90,0xDF } -static const Byte k_FFS_Guid[kGuidSize] = FFS_SIGNATURE; - -static const Byte k_MacFS_Guid[kGuidSize] = - { 0xAD,0xEE,0xAD,0x04,0xFF,0x61,0x31,0x4D,0xB6,0xBA,0x64,0xF8,0xBF,0x90,0x1F,0x5A }; - -static const UInt32 kFvSignature = 0x4856465F; // "_FVH" - -static const Byte kGuids[][kGuidSize] = -{ - { 0xB0,0xCD,0x1B,0xFC,0x31,0x7D,0xAA,0x49,0x93,0x6A,0xA4,0x60,0x0D,0x9D,0xD0,0x83 }, - { 0x2E,0x06,0xA0,0x1B,0x79,0xC7,0x82,0x45,0x85,0x66,0x33,0x6A,0xE8,0xF7,0x8F,0x09 }, - { 0x25,0x4E,0x37,0x7E,0x01,0x8E,0xEE,0x4F,0x87,0xf2,0x39,0x0C,0x23,0xC6,0x06,0xCD }, - { 0x97,0xE5,0x1B,0x16,0xC5,0xE9,0xDB,0x49,0xAE,0x50,0xC4,0x62,0xAB,0x54,0xEE,0xDA }, - { 0xDB,0x7F,0xAD,0x77,0x2A,0xDF,0x02,0x43,0x88,0x98,0xC7,0x2E,0x4C,0xDB,0xD0,0xF4 }, - { 0xAB,0x71,0xCF,0xF5,0x4B,0xB0,0x7E,0x4B,0x98,0x8A,0xD8,0xA0,0xD4,0x98,0xE6,0x92 }, - { 0x91,0x45,0x53,0x7A,0xCE,0x37,0x81,0x48,0xB3,0xC9,0x71,0x38,0x14,0xF4,0x5D,0x6B }, - { 0x84,0xE6,0x7A,0x36,0x5D,0x33,0x71,0x46,0xA1,0x6D,0x89,0x9D,0xBF,0xEA,0x6B,0x88 }, - { 0x98,0x07,0x40,0x24,0x07,0x38,0x42,0x4A,0xB4,0x13,0xA1,0xEC,0xEE,0x20,0x5D,0xD8 }, - { 0xEE,0xA2,0x3F,0x28,0x2C,0x53,0x4D,0x48,0x93,0x83,0x9F,0x93,0xB3,0x6F,0x0B,0x7E }, - { 0x9B,0xD5,0xB8,0x98,0xBA,0xE8,0xEE,0x48,0x98,0xDD,0xC2,0x95,0x39,0x2F,0x1E,0xDB }, - { 0x09,0x6D,0xE3,0xC3,0x94,0x82,0x97,0x4B,0xA8,0x57,0xD5,0x28,0x8F,0xE3,0x3E,0x28 }, - { 0x18,0x88,0x53,0x4A,0xE0,0x5A,0xB2,0x4E,0xB2,0xEB,0x48,0x8B,0x23,0x65,0x70,0x22 } -}; - - -static const char * const kGuidNames[] = -{ - "CRC" - , "VolumeTopFile" - , "ACPI" - , "ACPI2" - , "Main" - , "Intel32" - , "Intel64" - , "Intel32c" - , "Intel64c" - , "MacVolume" - , "MacUpdate.txt" - , "MacName" - , "Insyde" -}; - -enum -{ - kGuidIndex_CRC = 0 -}; - -struct CSigExtPair -{ - const char *ext; - unsigned sigSize; - Byte sig[16]; -}; - -static const CSigExtPair g_Sigs[] = -{ - { "bmp", 2, { 'B','M' } }, - { "riff", 4, { 'R','I','F','F' } }, - { "pe", 2, { 'M','Z'} }, - { "gif", 6, { 'G','I','F','8','9', 'a' } }, - { "png", 8, { 0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A } }, - { "jpg", 10, { 0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46 } }, - { "rom", 2, { 0x55,0xAA } } -}; - -enum -{ - kSig_BMP, - kSig_RIFF, - kSig_PE -}; - -static const char *FindExt(const Byte *p, size_t size) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE(g_Sigs); i++) - { - const CSigExtPair &pair = g_Sigs[i]; - if (size >= pair.sigSize) - if (memcmp(p, pair.sig, pair.sigSize) == 0) - break; - } - if (i == ARRAY_SIZE(g_Sigs)) - return NULL; - switch (i) - { - case kSig_BMP: - if (GetUi32(p + 2) > size || GetUi32(p + 0xA) > size) - return NULL; - break; - case kSig_RIFF: - if (GetUi32(p + 8) == 0x45564157 || GetUi32(p + 0xC) == 0x20746D66 ) - return "wav"; - break; - case kSig_PE: - { - if (size < 512) - return NULL; - UInt32 peOffset = GetUi32(p + 0x3C); - if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0) - return NULL; - if (GetUi32(p + peOffset) != 0x00004550) - return NULL; - break; - } - } - return g_Sigs[i].ext; -} - -static bool AreGuidsEq(const Byte *p1, const Byte *p2) -{ - return memcmp(p1, p2, kGuidSize) == 0; -} - -static int FindGuid(const Byte *p) -{ - for (unsigned i = 0; i < ARRAY_SIZE(kGuids); i++) - if (AreGuidsEq(p, kGuids[i])) - return i; - return -1; -} - -static bool IsFfs(const Byte *p) -{ - return (Get32(p + 0x28) == kFvSignature && AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid)); -} - -#define FVB_ERASE_POLARITY (1 << 11) - -/* -static const CUInt32PCharPair g_FV_Attribs[] = -{ - { 0, "ReadDisabledCap" }, - { 1, "ReadEnabledCap" }, - { 2, "ReadEnabled" }, - { 3, "WriteDisabledCap" }, - { 4, "WriteEnabledCap" }, - { 5, "WriteEnabled" }, - { 6, "LockCap" }, - { 7, "Locked" }, - - { 9, "StickyWrite" }, - { 10, "MemoryMapped" }, - { 11, "ErasePolarity" }, - - { 12, "ReadLockCap" }, - { 13, "WriteLockCap" }, - { 14, "WriteLockCap" } -}; -*/ - -enum -{ - FV_FILETYPE_ALL, - FV_FILETYPE_RAW, - FV_FILETYPE_FREEFORM, - FV_FILETYPE_SECURITY_CORE, - FV_FILETYPE_PEI_CORE, - FV_FILETYPE_DXE_CORE, - FV_FILETYPE_PEIM, - FV_FILETYPE_DRIVER, - FV_FILETYPE_COMBINED_PEIM_DRIVER, - FV_FILETYPE_APPLICATION, - // The value 0x0A is reserved and should not be used - FV_FILETYPE_FIRMWARE_VOLUME_IMAGE = 0x0B, - // types 0xF0 - 0xFF are FFS file types - FV_FILETYPE_FFS_PAD = 0xF0 -}; - -static const char *g_FileTypes[] = -{ - "ALL" - , "RAW" - , "FREEFORM" - , "SECURITY_CORE" - , "PEI_CORE" - , "DXE_CORE" - , "PEIM" - , "DRIVER" - , "COMBINED_PEIM_DRIVER" - , "APPLICATION" - , "0xA" - , "VOLUME" -}; - -// typedef Byte FFS_FILE_ATTRIBUTES; -// FFS File Attributes -#define FFS_ATTRIB_TAIL_PRESENT 0x01 -// #define FFS_ATTRIB_RECOVERY 0x02 -// #define FFS_ATTRIB_HEADER_EXTENSION 0x04 -// #define FFS_ATTRIB_DATA_ALIGNMENT 0x38 -#define FFS_ATTRIB_CHECKSUM 0x40 - -static const CUInt32PCharPair g_FFS_FILE_ATTRIBUTES[] = -{ - { 0, "" /* "TAIL" */ }, - { 1, "RECOVERY" }, - // { 2, "HEADER_EXTENSION" }, // reserved for future - { 6, "" /* "CHECKSUM" */ } -}; - -// static const Byte g_Allignment[8] = { 3, 4, 7, 9, 10, 12, 15, 16 }; - -// typedef Byte FFS_FILE_STATE; - -// Look also FVB_ERASE_POLARITY. -// Lower-order State bits are superceded by higher-order State bits. - -// #define FILE_HEADER_CONSTRUCTION 0x01 -// #define FILE_HEADER_VALID 0x02 -#define FILE_DATA_VALID 0x04 -// #define FILE_MARKED_FOR_UPDATE 0x08 -// #define FILE_DELETED 0x10 -// #define FILE_HEADER_INVALID 0x20 - -// SECTION_TYPE - -#define SECTION_ALL 0x00 - -#define SECTION_COMPRESSION 0x01 -#define SECTION_GUID_DEFINED 0x02 - -// Leaf section Type values -#define SECTION_PE32 0x10 -#define SECTION_PIC 0x11 -#define SECTION_TE 0x12 -#define SECTION_DXE_DEPEX 0x13 -#define SECTION_VERSION 0x14 -#define SECTION_USER_INTERFACE 0x15 -#define SECTION_COMPATIBILITY16 0x16 -#define SECTION_FIRMWARE_VOLUME_IMAGE 0x17 -#define SECTION_FREEFORM_SUBTYPE_GUID 0x18 -#define SECTION_RAW 0x19 -#define SECTION_PEI_DEPEX 0x1B - - -// #define GUIDED_SECTION_PROCESSING_REQUIRED 0x01 -// #define GUIDED_SECTION_AUTH_STATUS_VALID 0x02 - -static const CUInt32PCharPair g_GUIDED_SECTION_ATTRIBUTES[] = -{ - { 0, "PROCESSING_REQUIRED" }, - { 1, "AUTH" } -}; - -static const CUInt32PCharPair g_SECTION_TYPE[] = -{ - { 0x01, "COMPRESSION" }, - { 0x02, "GUID" }, - { 0x10, "efi" }, - { 0x11, "PIC" }, - { 0x12, "te" }, - { 0x13, "DXE_DEPEX" }, - { 0x14, "VERSION" }, - { 0x15, "USER_INTERFACE" }, - { 0x16, "COMPATIBILITY16" }, - { 0x17, "VOLUME" }, - { 0x18, "FREEFORM_SUBTYPE_GUID" }, - { 0x19, "raw" }, - { 0x1B, "PEI_DEPEX" } -}; - -#define COMPRESSION_TYPE_NONE 0 -#define COMPRESSION_TYPE_LZH 1 -#define COMPRESSION_TYPE_LZMA 2 - -static const char * const g_Methods[] = -{ - "COPY" - , "LZH" - , "LZMA" -}; - -static AString UInt32ToString(UInt32 val) -{ - char sz[16]; - ConvertUInt32ToString(val, sz); - return sz; -} - -static void ConvertByteToHex(unsigned value, char *s) -{ - for (int i = 0; i < 2; i++) - { - unsigned t = value & 0xF; - value >>= 4; - s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } -} - -static AString GuidToString(const Byte *p, bool full) -{ - char s[16 * 2 + 8]; - int i; - for (i = 0; i < 4; i++) - ConvertByteToHex(p[3 - i], s + i * 2); - s[8] = 0; - - if (full) - { - s[8] = '-'; - for (i = 4; i < kGuidSize; i++) - ConvertByteToHex(p[i], s + 1 + i * 2); - s[32 + 1] = 0; - } - return s; -} - -static const char * const kExpressionCommands[] = -{ - "BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR" -}; - -static bool ParseDepedencyExpression(const Byte *p, UInt32 size, AString &res) -{ - res.Empty(); - for (UInt32 i = 0; i < size;) - { - unsigned command = p[i++]; - if (command > ARRAY_SIZE(kExpressionCommands)) - return false; - res += kExpressionCommands[command]; - if (command < 3) - { - if (i + kGuidSize > size) - return false; - res.Add_Space(); - res += GuidToString(p + i, false); - i += kGuidSize; - } - res += "; "; - } - return true; -} - -static bool ParseUtf16zString(const Byte *p, UInt32 size, UString &res) -{ - if ((size & 1) != 0) - return false; - res.Empty(); - UInt32 i; - for (i = 0; i < size; i += 2) - { - wchar_t c = Get16(p + i); - if (c == 0) - break; - res += c; - } - return (i == size - 2); -} - -static bool ParseUtf16zString2(const Byte *p, UInt32 size, AString &res) -{ - UString s; - if (!ParseUtf16zString(p, size, s)) - return false; - res = UnicodeStringToMultiByte(s); - return true; -} - -#define FLAGS_TO_STRING(pairs, value) FlagsToString(pairs, ARRAY_SIZE(pairs), value) -#define TYPE_TO_STRING(table, value) TypeToString(table, ARRAY_SIZE(table), value) -#define TYPE_PAIR_TO_STRING(table, value) TypePairToString(table, ARRAY_SIZE(table), value) - -static const UInt32 kFileHeaderSize = 24; - -static void AddSpaceAndString(AString &res, const AString &newString) -{ - if (!newString.IsEmpty()) - { - res.Add_Space_if_NotEmpty(); - res += newString; - } -} - -class CFfsFileHeader -{ - Byte CheckHeader; - Byte CheckFile; - Byte Attrib; - Byte State; - - UInt16 GetTailReference() const { return (UInt16)(CheckHeader | ((UInt16)CheckFile << 8)); } - UInt32 GetTailSize() const { return IsThereTail() ? 2 : 0; } - bool IsThereFileChecksum() const { return (Attrib & FFS_ATTRIB_CHECKSUM) != 0; } - bool IsThereTail() const { return (Attrib & FFS_ATTRIB_TAIL_PRESENT) != 0; } -public: - Byte GuidName[kGuidSize]; - Byte Type; - UInt32 Size; - - bool Parse(const Byte *p) - { - int i; - for (i = 0; i < kFileHeaderSize; i++) - if (p[i] != 0xFF) - break; - if (i == kFileHeaderSize) - return false; - memcpy(GuidName, p, kGuidSize); - CheckHeader = p[0x10]; - CheckFile = p[0x11]; - Type = p[0x12]; - Attrib = p[0x13]; - Size = Get24(p + 0x14); - State = p[0x17]; - return true; - } - - UInt32 GetDataSize() const { return Size - kFileHeaderSize - GetTailSize(); } - UInt32 GetDataSize2(UInt32 rem) const { return rem - kFileHeaderSize - GetTailSize(); } - - bool Check(const Byte *p, UInt32 size) - { - if (Size > size) - return false; - UInt32 tailSize = GetTailSize(); - if (Size < kFileHeaderSize + tailSize) - return false; - - { - unsigned checkSum = 0; - for (UInt32 i = 0; i < kFileHeaderSize; i++) - checkSum += p[i]; - checkSum -= p[0x17]; - checkSum -= p[0x11]; - if ((Byte)checkSum != 0) - return false; - } - - if (IsThereFileChecksum()) - { - unsigned checkSum = 0; - UInt32 checkSize = Size - tailSize; - for (UInt32 i = 0; i < checkSize; i++) - checkSum += p[i]; - checkSum -= p[0x17]; - if ((Byte)checkSum != 0) - return false; - } - - if (IsThereTail()) - if (GetTailReference() != (UInt16)~Get16(p + Size - 2)) - return false; - - int polarity = 0; - int i; - for (i = 5; i >= 0; i--) - if (((State >> i) & 1) == polarity) - { - // AddSpaceAndString(s, g_FFS_FILE_STATE_Flags[i]); - if ((1 << i) != FILE_DATA_VALID) - return false; - break; - } - if (i < 0) - return false; - - return true; - } - - AString GetCharacts() const - { - AString s; - if (Type == FV_FILETYPE_FFS_PAD) - s += "PAD"; - else - s += TYPE_TO_STRING(g_FileTypes, Type); - AddSpaceAndString(s, FLAGS_TO_STRING(g_FFS_FILE_ATTRIBUTES, Attrib & 0xC7)); - /* - int align = (Attrib >> 3) & 7; - if (align != 0) - { - s += " Align:"; - s += UInt32ToString((UInt32)1 << g_Allignment[align]); - } - */ - return s; - } -}; - -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); - -struct CCapsuleHeader -{ - UInt32 HeaderSize; - UInt32 Flags; - UInt32 CapsuleImageSize; - UInt32 SequenceNumber; - // Guid InstanceId; - UInt32 OffsetToSplitInformation; - UInt32 OffsetToCapsuleBody; - UInt32 OffsetToOemDefinedHeader; - UInt32 OffsetToAuthorInformation; - UInt32 OffsetToRevisionInformation; - UInt32 OffsetToShortDescription; - UInt32 OffsetToLongDescription; - UInt32 OffsetToApplicableDevices; - - void Clear() { memset(this, 0, sizeof(*this)); } - - void Parse(const Byte *p) - { - G32(0x10, HeaderSize); - G32(0x14, Flags); - G32(0x18, CapsuleImageSize); - G32(0x1C, SequenceNumber); - G32(0x30, OffsetToSplitInformation); - G32(0x34, OffsetToCapsuleBody); - G32(0x38, OffsetToOemDefinedHeader); - G32(0x3C, OffsetToAuthorInformation); - G32(0x40, OffsetToRevisionInformation); - G32(0x44, OffsetToShortDescription); - G32(0x48, OffsetToLongDescription); - G32(0x4C, OffsetToApplicableDevices); - } -}; - -struct CItem -{ - AString Name; - AString Characts; - int Parent; - int Method; - int NameIndex; - int NumChilds; - bool IsDir; - bool Skip; - bool ThereAreSubDirs; - bool ThereIsUniqueName; - bool KeepName; - - int BufIndex; - UInt32 Offset; - UInt32 Size; - - CItem(): Parent(-1), Method(-1), NameIndex(-1), NumChilds(0), - IsDir(false), Skip(false), ThereAreSubDirs(false), ThereIsUniqueName(false), KeepName(true) {} - void SetGuid(const Byte *guidName, bool full = false); - AString GetName(int numChildsInParent) const; -}; - -void CItem::SetGuid(const Byte *guidName, bool full) -{ - ThereIsUniqueName = true; - int index = FindGuid(guidName); - if (index >= 0) - Name = kGuidNames[(unsigned)index]; - else - Name = GuidToString(guidName, full); -} - -AString CItem::GetName(int numChildsInParent) const -{ - if (numChildsInParent <= 1 || NameIndex < 0) - return Name; - char sz[32]; - char sz2[32]; - ConvertUInt32ToString(NameIndex, sz); - ConvertUInt32ToString(numChildsInParent - 1, sz2); - unsigned numZeros = (unsigned)strlen(sz2) - (unsigned)strlen(sz); - AString res; - for (unsigned i = 0; i < numZeros; i++) - res += '0'; - return res + (AString)sz + '.' + Name; -} - -struct CItem2 -{ - AString Name; - AString Characts; - int MainIndex; - int Parent; - - CItem2(): Parent(-1) {} -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - CObjectVector _items; - CObjectVector _items2; - CObjectVector _bufs; - UString _comment; - UInt32 _methodsMask; - bool _capsuleMode; - - size_t _totalBufsSize; - CCapsuleHeader _h; - UInt64 _phySize; - - void AddCommentString(const wchar_t *name, UInt32 pos); - int AddItem(const CItem &item); - int AddFileItemWithIndex(CItem &item); - int AddDirItem(CItem &item); - unsigned AddBuf(size_t size); - - HRESULT ParseSections(int bufIndex, UInt32 pos, UInt32 size, int parent, int method, unsigned level); - HRESULT ParseVolume(int bufIndex, UInt32 posBase, - UInt32 exactSize, UInt32 limitSize, - int parent, int method, int level); - HRESULT OpenCapsule(IInStream *stream); - HRESULT OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback); - HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback); -public: - CHandler(bool capsuleMode): _capsuleMode(capsuleMode) {} - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidMethod, - kpidCharacts -}; - -static const Byte kArcProps[] = -{ - kpidComment, - kpidMethod, - kpidCharacts -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItem2 &item2 = _items2[index]; - const CItem &item = _items[item2.MainIndex]; - switch (propID) - { - case kpidPath: - { - AString path = item2.Name; - int cur = item2.Parent; - while (cur >= 0) - { - const CItem2 &item3 = _items2[cur]; - path.InsertAtFront(CHAR_PATH_SEPARATOR); - path.Insert(0, item3.Name); - cur = item3.Parent; - } - prop = path; - break; - } - case kpidIsDir: prop = item.IsDir; break; - case kpidMethod: if (item.Method >= 0) prop = g_Methods[(unsigned)item.Method]; break; - case kpidCharacts: if (!item2.Characts.IsEmpty()) prop = item2.Characts; break; - case kpidSize: if (!item.IsDir) prop = (UInt64)item.Size; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -void CHandler::AddCommentString(const wchar_t *name, UInt32 pos) -{ - UString s; - const Byte *buf = _bufs[0]; - if (pos < _h.HeaderSize) - return; - for (UInt32 i = pos;; i += 2) - { - if (s.Len() > (1 << 16) || i >= _h.OffsetToCapsuleBody) - return; - wchar_t c = Get16(buf + i); - if (c == 0) - { - i += 2; - if (i >= _h.OffsetToCapsuleBody) - return; - c = Get16(buf + i); - if (c == 0) - break; - s.Add_LF(); - } - s += c; - } - if (s.IsEmpty()) - return; - _comment.Add_LF(); - _comment += name; - _comment.AddAscii(": "); - _comment += s; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidMethod: - { - AString s; - for (unsigned i = 0; i < 32; i++) - if ((_methodsMask & ((UInt32)1 << i)) != 0) - AddSpaceAndString(s, g_Methods[i]); - if (!s.IsEmpty()) - prop = s; - break; - } - case kpidComment: if (!_comment.IsEmpty()) prop = _comment; break; - case kpidPhySize: prop = (UInt64)_phySize; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -#ifdef SHOW_DEBUG_INFO -static void PrintLevel(int level) -{ - PRF(printf("\n")); - for (int i = 0; i < level; i++) - PRF(printf(" ")); -} -static void MyPrint(UInt32 posBase, UInt32 size, int level, const char *name) -{ - PrintLevel(level); - PRF(printf("%s, pos = %6x, size = %6d", name, posBase, size)); -} -#else -#define PrintLevel(level) -#define MyPrint(posBase, size, level, name) -#endif - - - -int CHandler::AddItem(const CItem &item) -{ - if (_items.Size() >= kNumFilesMax) - throw 2; - return _items.Add(item); -} - -int CHandler::AddFileItemWithIndex(CItem &item) -{ - int nameIndex = _items.Size(); - if (item.Parent >= 0) - nameIndex = _items[item.Parent].NumChilds++; - item.NameIndex = nameIndex; - return AddItem(item); -} - -int CHandler::AddDirItem(CItem &item) -{ - if (item.Parent >= 0) - _items[item.Parent].ThereAreSubDirs = true; - item.IsDir = true; - item.Size = 0; - return AddItem(item); -} - -unsigned CHandler::AddBuf(size_t size) -{ - if (size > kBufTotalSizeMax - _totalBufsSize) - throw 1; - _totalBufsSize += size; - unsigned index = _bufs.Size(); - _bufs.AddNew().Alloc(size); - return index; -} - -HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level) -{ - if (level > kLevelMax) - return S_FALSE; - MyPrint(posBase, size, level, "Sections"); - level++; - const Byte *bufData = _bufs[bufIndex]; - UInt32 pos = 0; - for (;;) - { - if (size == pos) - return S_OK; - PrintLevel(level); - PRF(printf("%s, pos = %6x", "Sect", pos)); - pos = (pos + 3) & ~(UInt32)3; - if (pos > size) - return S_FALSE; - UInt32 rem = size - pos; - if (rem == 0) - return S_OK; - if (rem < 4) - return S_FALSE; - const Byte *p = bufData + posBase + pos; - UInt32 sectSize = Get24(p); - if (sectSize > rem || sectSize < 4) - return S_FALSE; - - Byte type = p[3]; - PrintLevel(level); - PRF(printf("%s, type = %2x, pos = %6x, size = %6d", "Sect", type, pos, sectSize)); - CItem item; - item.Method = method; - item.BufIndex = bufIndex; - item.Parent = parent; - item.Offset = posBase + pos + 4; - UInt32 sectDataSize = sectSize - 4; - item.Size = sectDataSize; - item.Name = TYPE_PAIR_TO_STRING(g_SECTION_TYPE, type); - - if (type == SECTION_COMPRESSION) - { - if (sectSize < 4 + 5) - return S_FALSE; - UInt32 uncompressedSize = Get32(p + 4); - Byte compressionType = p[8]; - - UInt32 newSectSize = sectSize - 9; - UInt32 newOffset = posBase + pos + 9; - const Byte *pStart = p + 9; - - item.KeepName = false; - if (compressionType > 2) - { - // AddFileItemWithIndex(item); - return S_FALSE; - } - else - { - item.Name = g_Methods[compressionType]; - // int parent = AddDirItem(item); - if (compressionType == COMPRESSION_TYPE_NONE) - { - RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level)); - } - else if (compressionType == COMPRESSION_TYPE_LZH) - { - unsigned newBufIndex = AddBuf(uncompressedSize); - CByteBuffer &buf = _bufs[newBufIndex]; - - NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; - CMyComPtr lzhDecoder; - - lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; - lzhDecoder = lzhDecoderSpec; - - { - const Byte *src = pStart; - if (newSectSize < 8) - return S_FALSE; - UInt32 packSize = Get32(src); - UInt32 unpackSize = Get32(src + 4); - if (uncompressedSize != unpackSize || newSectSize - 8 != packSize) - return S_FALSE; - if (packSize < 1) - return S_FALSE; - packSize--; - src += 8; - if (src[packSize] != 0) - return S_FALSE; - - CBufInStream *inStreamSpec = new CBufInStream; - CMyComPtr inStream = inStreamSpec; - inStreamSpec->Init(src, packSize); - - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream = outStreamSpec; - outStreamSpec->Init(buf, uncompressedSize); - - UInt64 uncompressedSize64 = uncompressedSize; - lzhDecoderSpec->FinishMode = true; - /* - EFI 1.1 probably used small dictionary and (pbit = 4) in LZH. We don't support such archives. - New version of compression code (named Tiano) uses LZH with (1 << 19) dictionary. - But maybe LZH decoder in UEFI decoder supports larger than (1 << 19) dictionary. - */ - lzhDecoderSpec->SetDictSize(1 << 19); - - HRESULT res = lzhDecoder->Code(inStream, outStream, NULL, &uncompressedSize64, NULL); - if (res != S_OK) - return res; - - if (lzhDecoderSpec->GetInputProcessedSize() != packSize) - return S_FALSE; - } - - RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level)); - } - else - { - if (newSectSize < 4 + 5 + 8) - return S_FALSE; - unsigned addSize = 4; - if (pStart[0] == 0x5d && pStart[1] == 0 && pStart[2] == 0 && pStart[3] == 0x80 && pStart[4] == 0) - { - addSize = 0; - // some archives have such header - } - else - { - // normal BIOS contains uncompressed size here - // UInt32 uncompressedSize2 = Get24(pStart); - // Byte firstSectType = p[9 + 3]; - // firstSectType can be 0 in some archives - } - pStart += addSize; - UInt64 lzmaUncompressedSize = Get64(pStart + 5); - if (lzmaUncompressedSize > (1 << 30)) - return S_FALSE; - if (lzmaUncompressedSize < uncompressedSize) - return S_FALSE; - SizeT destLen = (SizeT)lzmaUncompressedSize; - unsigned newBufIndex = AddBuf((size_t)lzmaUncompressedSize); - CByteBuffer &buf = _bufs[newBufIndex]; - ELzmaStatus status; - SizeT srcLen = newSectSize - (addSize + 5 + 8); - SizeT srcLen2 = srcLen; - SRes res = LzmaDecode(buf, &destLen, pStart + 13, &srcLen, - pStart, 5, LZMA_FINISH_END, &status, &g_Alloc); - if (res != 0) - return S_FALSE; - if (srcLen != srcLen2 || destLen != lzmaUncompressedSize || ( - status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - return S_FALSE; - RINOK(ParseSections(newBufIndex, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level)); - } - _methodsMask |= (1 << compressionType); - } - } - else if (type == SECTION_GUID_DEFINED) - { - const unsigned kHeaderSize = 4 + kGuidSize + 4; - if (sectSize < kHeaderSize) - return S_FALSE; - item.SetGuid(p + 4); - UInt32 dataOffset = Get16(p + 4 + kGuidSize); - UInt32 attrib = Get16(p + 4 + kGuidSize + 2); - if (dataOffset > sectSize || dataOffset < kHeaderSize) - return S_FALSE; - UInt32 newSectSize = sectSize - dataOffset; - item.Size = newSectSize; - UInt32 newOffset = posBase + pos + dataOffset; - item.Offset = newOffset; - UInt32 propsSize = dataOffset - kHeaderSize; - bool needDir = true; - AddSpaceAndString(item.Characts, FLAGS_TO_STRING(g_GUIDED_SECTION_ATTRIBUTES, attrib)); - if (AreGuidsEq(p + 0x4, kGuids[kGuidIndex_CRC]) && propsSize == 4) - { - needDir = false; - item.KeepName = false; - if (CrcCalc(bufData + newOffset, newSectSize) != Get32(p + kHeaderSize)) - return S_FALSE; - } - else - { - if (propsSize != 0) - { - CItem item2 = item; - item2.Name += ".prop"; - item2.Size = propsSize; - item2.Offset = posBase + pos + kHeaderSize; - AddItem(item2); - } - } - int newParent = parent; - if (needDir) - newParent = AddDirItem(item); - RINOK(ParseSections(bufIndex, newOffset, newSectSize, newParent, method, level)); - } - else if (type == SECTION_FIRMWARE_VOLUME_IMAGE) - { - item.KeepName = false; - int newParent = AddDirItem(item); - RINOK(ParseVolume(bufIndex, posBase + pos + 4, - sectSize - 4, - sectSize - 4, - newParent, method, level)); - } - else - { - bool needAdd = true; - switch (type) - { - case SECTION_RAW: - { - const UInt32 kInsydeOffset = 12; - if (sectDataSize >= kFvHeaderSize + kInsydeOffset) - { - if (IsFfs(p + 4 + kInsydeOffset) && - sectDataSize - kInsydeOffset == Get64(p + 4 + kInsydeOffset + 0x20)) - { - needAdd = false; - item.Name = "vol"; - int newParent = AddDirItem(item); - RINOK(ParseVolume(bufIndex, posBase + pos + 4 + kInsydeOffset, - sectDataSize - kInsydeOffset, - sectDataSize - kInsydeOffset, - newParent, method, level)); - } - - if (needAdd) - { - const char *ext = FindExt(p + 4, sectDataSize); - if (ext) - item.Name = ext; - } - } - break; - } - case SECTION_DXE_DEPEX: - case SECTION_PEI_DEPEX: - { - AString s; - if (ParseDepedencyExpression(p + 4, sectDataSize, s)) - { - if (s.Len() < (1 << 9)) - { - s.InsertAtFront('['); - s += ']'; - AddSpaceAndString(_items[item.Parent].Characts, s); - needAdd = false; - } - else - { - item.BufIndex = AddBuf(s.Len()); - CByteBuffer &buf0 = _bufs[item.BufIndex]; - if (s.Len() != 0) - memcpy(buf0, s, s.Len()); - item.Offset = 0; - item.Size = s.Len(); - } - } - break; - } - case SECTION_VERSION: - { - if (sectDataSize > 2) - { - AString s; - if (ParseUtf16zString2(p + 6, sectDataSize - 2, s)) - { - AString s2 = "ver:"; - s2 += UInt32ToString(Get16(p + 4)); - s2.Add_Space(); - s2 += s; - AddSpaceAndString(_items[item.Parent].Characts, s2); - needAdd = false; - } - } - break; - } - case SECTION_USER_INTERFACE: - { - AString s; - if (ParseUtf16zString2(p + 4, sectDataSize, s)) - { - _items[parent].Name = s; - needAdd = false; - } - break; - } - case SECTION_FREEFORM_SUBTYPE_GUID: - { - if (sectDataSize >= kGuidSize) - { - item.SetGuid(p + 4); - item.Size = sectDataSize - kGuidSize; - item.Offset = posBase + pos + 4 + kGuidSize; - } - break; - } - } - - if (needAdd) - AddFileItemWithIndex(item); - } - pos += sectSize; - } -} - -static UInt32 Count_FF_Bytes(const Byte *p, UInt32 size) -{ - UInt32 i; - for (i = 0; i < size && p[i] == 0xFF; i++); - return i; -} - -static bool Is_FF_Stream(const Byte *p, UInt32 size) -{ - return (Count_FF_Bytes(p, size) == size); -} - -struct CVolFfsHeader -{ - UInt32 HeaderLen; - UInt64 VolSize; - - bool Parse(const Byte *p); -}; - -bool CVolFfsHeader::Parse(const Byte *p) -{ - if (Get32(p + 0x28) != kFvSignature) - return false; - - UInt32 attribs = Get32(p + 0x2C); - if ((attribs & FVB_ERASE_POLARITY) == 0) - return false; - VolSize = Get64(p + 0x20); - HeaderLen = Get16(p + 0x30); - if (HeaderLen < kFvHeaderSize || (HeaderLen & 0x7) != 0 || VolSize < HeaderLen) - return false; - return true; -}; - -HRESULT CHandler::ParseVolume( - int bufIndex, UInt32 posBase, - UInt32 exactSize, UInt32 limitSize, - int parent, int method, int level) -{ - if (level > kLevelMax) - return S_FALSE; - MyPrint(posBase, size, level, "Volume"); - level++; - if (exactSize < kFvHeaderSize) - return S_FALSE; - const Byte *p = _bufs[bufIndex] + posBase; - // first 16 bytes must be zeros, but they are not zeros sometimes. - if (!AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid) && - !AreGuidsEq(p + kFfsGuidOffset, k_MacFS_Guid)) - { - CItem item; - item.Method = method; - item.BufIndex = bufIndex; - item.Parent = parent; - item.Offset = posBase; - item.Size = exactSize; - item.SetGuid(p + kFfsGuidOffset); - item.Name += " [VOLUME]"; - AddItem(item); - return S_OK; - } - - CVolFfsHeader ffsHeader; - if (!ffsHeader.Parse(p)) - return S_FALSE; - // if (parent >= 0) AddSpaceAndString(_items[parent].Characts, FLAGS_TO_STRING(g_FV_Attribs, attribs)); - - // VolSize > exactSize (fh.Size) for some UEFI archives (is it correct UEFI?) - // so we check VolSize for limitSize instead. - - if (ffsHeader.HeaderLen > limitSize || ffsHeader.VolSize > limitSize) - return S_FALSE; - - { - UInt32 checkCalc = 0; - for (UInt32 i = 0; i < ffsHeader.HeaderLen; i += 2) - checkCalc += Get16(p + i); - if ((checkCalc & 0xFFFF) != 0) - return S_FALSE; - } - - // 3 reserved bytes are not zeros sometimes. - // UInt16 ExtHeaderOffset; // in new SPECIFICATION? - // Byte revision = p[0x37]; - - UInt32 pos = kFvHeaderSize; - for (;;) - { - if (pos >= ffsHeader.HeaderLen) - return S_FALSE; - UInt32 numBlocks = Get32(p + pos); - UInt32 length = Get32(p + pos + 4); - pos += 8; - if (numBlocks == 0 && length == 0) - break; - } - if (pos != ffsHeader.HeaderLen) - return S_FALSE; - - CRecordVector guidsVector; - - for (;;) - { - UInt32 rem = (UInt32)ffsHeader.VolSize - pos; - if (rem < kFileHeaderSize) - break; - pos = (pos + 7) & ~7; - rem = (UInt32)ffsHeader.VolSize - pos; - if (rem < kFileHeaderSize) - break; - - CItem item; - item.Method = method; - item.BufIndex = bufIndex; - item.Parent = parent; - - const Byte *pFile = p + pos; - CFfsFileHeader fh; - if (!fh.Parse(pFile)) - { - UInt32 num_FF_bytes = Count_FF_Bytes(pFile, rem); - if (num_FF_bytes != rem) - { - item.Name = "[junk]"; - item.Offset = posBase + pos + num_FF_bytes; - item.Size = rem - num_FF_bytes; - AddItem(item); - } - break; - } - PrintLevel(level); PRF(printf("%s, pos = %6x, size = %6d", "FILE", posBase + pos, fh.Size)); - if (!fh.Check(pFile, rem)) - return S_FALSE; - - UInt32 offset = posBase + pos + kFileHeaderSize; - UInt32 sectSize = fh.GetDataSize(); - item.Offset = offset; - item.Size = sectSize; - - pos += fh.Size; - - if (fh.Type == FV_FILETYPE_FFS_PAD) - if (Is_FF_Stream(pFile + kFileHeaderSize, sectSize)) - continue; - - UInt32 guid32 = Get32(fh.GuidName); - bool full = true; - if (guidsVector.FindInSorted(guid32) < 0) - { - guidsVector.AddToUniqueSorted(guid32); - full = false; - } - item.SetGuid(fh.GuidName, full); - - item.Characts = fh.GetCharacts(); - PrintLevel(level); - PRF(printf("%s", item.Characts)); - - if (fh.Type == FV_FILETYPE_FFS_PAD || - fh.Type == FV_FILETYPE_RAW) - { - bool isVolume = false; - if (fh.Type == FV_FILETYPE_RAW) - { - if (sectSize >= kFvHeaderSize) - if (IsFfs(pFile + kFileHeaderSize)) - isVolume = true; - } - if (isVolume) - { - int newParent = AddDirItem(item); - UInt32 limSize = fh.GetDataSize2(rem); - // volume.VolSize > fh.Size for some UEFI archives (is it correct UEFI?) - // so we will check VolSize for limitSize instead. - RINOK(ParseVolume(bufIndex, offset, sectSize, limSize, newParent, method, level)); - } - else - AddItem(item); - } - else - { - int newParent = AddDirItem(item); - RINOK(ParseSections(bufIndex, offset, sectSize, newParent, method, level)); - } - } - return S_OK; -} - -HRESULT CHandler::OpenCapsule(IInStream *stream) -{ - const unsigned kHeaderSize = 80; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - _h.Parse(buf); - if (_h.HeaderSize != kHeaderSize || - _h.CapsuleImageSize < kHeaderSize || - _h.OffsetToCapsuleBody < kHeaderSize || - _h.OffsetToCapsuleBody > _h.CapsuleImageSize) - return S_FALSE; - _phySize = _h.CapsuleImageSize; - - if (_h.SequenceNumber != 0 || - _h.OffsetToSplitInformation != 0 ) - return E_NOTIMPL; - - unsigned bufIndex = AddBuf(_h.CapsuleImageSize); - CByteBuffer &buf0 = _bufs[bufIndex]; - memcpy(buf0, buf, kHeaderSize); - ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize); - - AddCommentString(L"Author", _h.OffsetToAuthorInformation); - AddCommentString(L"Revision", _h.OffsetToRevisionInformation); - AddCommentString(L"Short Description", _h.OffsetToShortDescription); - AddCommentString(L"Long Description", _h.OffsetToLongDescription); - - return ParseVolume(bufIndex, _h.OffsetToCapsuleBody, - _h.CapsuleImageSize - _h.OffsetToCapsuleBody, - _h.CapsuleImageSize - _h.OffsetToCapsuleBody, - -1, -1, 0); -} - -HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* callback */) -{ - Byte buf[kFvHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kFvHeaderSize)); - if (!IsFfs(buf)) - return S_FALSE; - CVolFfsHeader ffsHeader; - if (!ffsHeader.Parse(buf)) - return S_FALSE; - if (ffsHeader.VolSize > ((UInt32)1 << 30)) - return S_FALSE; - _phySize = ffsHeader.VolSize; - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - UInt32 fvSize32 = (UInt32)ffsHeader.VolSize; - unsigned bufIndex = AddBuf(fvSize32); - RINOK(ReadStream_FALSE(stream, _bufs[bufIndex], fvSize32)); - return ParseVolume(bufIndex, 0, fvSize32, fvSize32, -1, -1, 0); -} - -HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) -{ - if (_capsuleMode) - { - RINOK(OpenCapsule(stream)); - } - else - { - RINOK(OpenFv(stream, maxCheckStartPosition, callback)); - } - - unsigned num = _items.Size(); - CIntArr numChilds(num); - - unsigned i; - - for (i = 0; i < num; i++) - numChilds[i] = 0; - - for (i = 0; i < num; i++) - { - int parent = _items[i].Parent; - if (parent >= 0) - numChilds[(unsigned)parent]++; - } - - for (i = 0; i < num; i++) - { - const CItem &item = _items[i]; - int parent = item.Parent; - if (parent >= 0) - { - CItem &parentItem = _items[(unsigned)parent]; - if (numChilds[(unsigned)parent] == 1) - if (!item.ThereIsUniqueName || !parentItem.ThereIsUniqueName || !parentItem.ThereAreSubDirs) - parentItem.Skip = true; - } - } - - CUIntVector mainToReduced; - - for (i = 0; i < _items.Size(); i++) - { - mainToReduced.Add(_items2.Size()); - const CItem &item = _items[i]; - if (item.Skip) - continue; - AString name; - int numItems = -1; - int parent = item.Parent; - if (parent >= 0) - numItems = numChilds[(unsigned)parent]; - AString name2 = item.GetName(numItems); - AString characts2 = item.Characts; - if (item.KeepName) - name = name2; - - while (parent >= 0) - { - const CItem &item3 = _items[(unsigned)parent]; - if (!item3.Skip) - break; - if (item3.KeepName) - { - AString name3 = item3.GetName(-1); - if (name.IsEmpty()) - name = name3; - else - name = name3 + '.' + name; - } - AddSpaceAndString(characts2, item3.Characts); - parent = item3.Parent; - } - - if (name.IsEmpty()) - name = name2; - - CItem2 item2; - item2.MainIndex = i; - item2.Name = name; - item2.Characts = characts2; - if (parent >= 0) - item2.Parent = mainToReduced[(unsigned)parent]; - _items2.Add(item2); - /* - CItem2 item2; - item2.MainIndex = i; - item2.Name = item.Name; - item2.Parent = item.Parent; - _items2.Add(item2); - */ - } - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - Close(); - { - HRESULT res = Open2(inStream, maxCheckStartPosition, callback); - if (res == E_NOTIMPL) - res = S_FALSE; - return res; - } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - _totalBufsSize = 0; - _methodsMask = 0; - _items.Clear(); - _items2.Clear(); - _bufs.Clear(); - _comment.Empty(); - _h.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _items2.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items2.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _items[_items2[allFilesMode ? i : indices[i]].MainIndex].Size; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 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 = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CItem &item = _items[_items2[index].MainIndex]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - currentTotalSize += item.Size; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - if (testMode || item.IsDir) - { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - int res = NExtract::NOperationResult::kDataError; - CMyComPtr inStream; - GetStream(index, &inStream); - if (inStream) - { - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize == item.Size) - res = NExtract::NOperationResult::kOK; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(res)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CItem &item = _items[_items2[index].MainIndex]; - if (item.IsDir) - return S_FALSE; - CBufInStream *streamSpec = new CBufInStream; - CMyComPtr streamTemp = streamSpec; - const CByteBuffer &buf = _bufs[item.BufIndex]; - /* - if (item.Offset + item.Size > buf.GetCapacity()) - return S_FALSE; - */ - streamSpec->Init(buf + item.Offset, item.Size, (IInArchive *)this); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - - -namespace UEFIc { - -REGISTER_ARC_I_CLS( - CHandler(true), - "UEFIc", "scap", 0, 0xD0, - kCapsuleSig, - 0, - NArcInfoFlags::kFindSignature, - NULL) - -} - -namespace UEFIf { - -REGISTER_ARC_I_CLS( - CHandler(false), - "UEFIf", "uefif", 0, 0xD1, - k_FFS_Guid, - kFfsGuidOffset, - NArcInfoFlags::kFindSignature, - NULL) - -} - -}} +// UefiHandler.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "../../../C/7zCrc.h" +#include "../../../C/Alloc.h" +#include "../../../C/LzmaDec.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/AutoPtr.h" +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringConvert.h" + +#include "../../Windows/PropVariantUtils.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/LzhDecoder.h" + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) +#define Get24(p) (Get32(p) & 0xFFFFFF) + +namespace NArchive { +namespace NUefi { + +static const size_t kBufTotalSizeMax = 1 << 29; +static const unsigned kNumFilesMax = 1 << 18; +static const unsigned kLevelMax = 64; + +static const Byte k_IntelMeSignature[] = +{ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x5A, 0xA5, 0xF0, 0x0F +}; + +static bool IsIntelMe(const Byte *p) +{ + return memcmp(p, k_IntelMeSignature, sizeof(k_IntelMeSignature)) == 0; +} + +static const unsigned kFvHeaderSize = 0x38; + +static const unsigned kGuidSize = 16; + +#define CAPSULE_SIGNATURE 0xBD,0x86,0x66,0x3B,0x76,0x0D,0x30,0x40,0xB7,0x0E,0xB5,0x51,0x9E,0x2F,0xC5,0xA0 +#define CAPSULE2_SIGNATURE 0x8B,0xA6,0x3C,0x4A,0x23,0x77,0xFB,0x48,0x80,0x3D,0x57,0x8C,0xC1,0xFE,0xC4,0x4D +#define CAPSULE_UEFI_SIGNATURE 0xB9,0x82,0x91,0x53,0xB5,0xAB,0x91,0x43,0xB6,0x9A,0xE3,0xA9,0x43,0xF7,0x2F,0xCC +/* + 6dcbd5ed-e82d-4c44-bda1-7194199ad92a : Firmware Management ` +*/ + +static const Byte k_Guids_Capsules[][kGuidSize] = +{ + { CAPSULE_SIGNATURE }, + { CAPSULE2_SIGNATURE }, + { CAPSULE_UEFI_SIGNATURE } +}; + + +static const unsigned kFfsGuidOffset = 16; + +#define FFS1_SIGNATURE 0xD9,0x54,0x93,0x7A,0x68,0x04,0x4A,0x44,0x81,0xCE,0x0B,0xF6,0x17,0xD8,0x90,0xDF +#define FFS2_SIGNATURE 0x78,0xE5,0x8C,0x8C,0x3D,0x8A,0x1C,0x4F,0x99,0x35,0x89,0x61,0x85,0xC3,0x2D,0xD3 +#define MACFS_SIGNATURE 0xAD,0xEE,0xAD,0x04,0xFF,0x61,0x31,0x4D,0xB6,0xBA,0x64,0xF8,0xBF,0x90,0x1F,0x5A +// APPLE_BOOT +/* + "FFS3": "5473c07a-3dcb-4dca-bd6f-1e9689e7349a", + "NVRAM_EVSA": "fff12b8d-7696-4c8b-a985-2747075b4f50", + "NVRAM_NVAR": "cef5b9a3-476d-497f-9fdc-e98143e0422c", + "NVRAM_EVSA2": "00504624-8a59-4eeb-bd0f-6b36e96128e0", +static const Byte k_NVRAM_NVAR_Guid[kGuidSize] = + { 0xA3,0xB9,0xF5,0xCE,0x6D,0x47,0x7F,0x49,0x9F,0xDC,0xE9,0x81,0x43,0xE0,0x42,0x2C }; +*/ + +static const Byte k_Guids_FS[][kGuidSize] = +{ + { FFS1_SIGNATURE }, + { FFS2_SIGNATURE }, + { MACFS_SIGNATURE } +}; + + +static const UInt32 kFvSignature = 0x4856465F; // "_FVH" + +static const Byte kGuids[][kGuidSize] = +{ + { 0xB0,0xCD,0x1B,0xFC,0x31,0x7D,0xAA,0x49,0x93,0x6A,0xA4,0x60,0x0D,0x9D,0xD0,0x83 }, + { 0x2E,0x06,0xA0,0x1B,0x79,0xC7,0x82,0x45,0x85,0x66,0x33,0x6A,0xE8,0xF7,0x8F,0x09 }, + { 0x25,0x4E,0x37,0x7E,0x01,0x8E,0xEE,0x4F,0x87,0xf2,0x39,0x0C,0x23,0xC6,0x06,0xCD }, + { 0x97,0xE5,0x1B,0x16,0xC5,0xE9,0xDB,0x49,0xAE,0x50,0xC4,0x62,0xAB,0x54,0xEE,0xDA }, + { 0xDB,0x7F,0xAD,0x77,0x2A,0xDF,0x02,0x43,0x88,0x98,0xC7,0x2E,0x4C,0xDB,0xD0,0xF4 }, + { 0xAB,0x71,0xCF,0xF5,0x4B,0xB0,0x7E,0x4B,0x98,0x8A,0xD8,0xA0,0xD4,0x98,0xE6,0x92 }, + { 0x91,0x45,0x53,0x7A,0xCE,0x37,0x81,0x48,0xB3,0xC9,0x71,0x38,0x14,0xF4,0x5D,0x6B }, + { 0x84,0xE6,0x7A,0x36,0x5D,0x33,0x71,0x46,0xA1,0x6D,0x89,0x9D,0xBF,0xEA,0x6B,0x88 }, + { 0x98,0x07,0x40,0x24,0x07,0x38,0x42,0x4A,0xB4,0x13,0xA1,0xEC,0xEE,0x20,0x5D,0xD8 }, + { 0xEE,0xA2,0x3F,0x28,0x2C,0x53,0x4D,0x48,0x93,0x83,0x9F,0x93,0xB3,0x6F,0x0B,0x7E }, + { 0x9B,0xD5,0xB8,0x98,0xBA,0xE8,0xEE,0x48,0x98,0xDD,0xC2,0x95,0x39,0x2F,0x1E,0xDB }, + { 0x09,0x6D,0xE3,0xC3,0x94,0x82,0x97,0x4B,0xA8,0x57,0xD5,0x28,0x8F,0xE3,0x3E,0x28 }, + { 0x18,0x88,0x53,0x4A,0xE0,0x5A,0xB2,0x4E,0xB2,0xEB,0x48,0x8B,0x23,0x65,0x70,0x22 } +}; + +static const Byte k_Guid_LZMA_COMPRESSED[kGuidSize] = + { 0x98,0x58,0x4E,0xEE,0x14,0x39,0x59,0x42,0x9D,0x6E,0xDC,0x7B,0xD7,0x94,0x03,0xCF }; + +static const char * const kGuidNames[] = +{ + "CRC" + , "VolumeTopFile" + , "ACPI" + , "ACPI2" + , "Main" + , "Intel32" + , "Intel64" + , "Intel32c" + , "Intel64c" + , "MacVolume" + , "MacUpdate.txt" + , "MacName" + , "Insyde" +}; + +enum +{ + kGuidIndex_CRC = 0 +}; + +struct CSigExtPair +{ + const char *ext; + unsigned sigSize; + Byte sig[16]; +}; + +static const CSigExtPair g_Sigs[] = +{ + { "bmp", 2, { 'B','M' } }, + { "riff", 4, { 'R','I','F','F' } }, + { "pe", 2, { 'M','Z'} }, + { "gif", 6, { 'G','I','F','8','9', 'a' } }, + { "png", 8, { 0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A } }, + { "jpg", 10, { 0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46 } }, + { "rom", 2, { 0x55,0xAA } } +}; + +enum +{ + kSig_BMP, + kSig_RIFF, + kSig_PE +}; + +static const char *FindExt(const Byte *p, size_t size) +{ + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(g_Sigs); i++) + { + const CSigExtPair &pair = g_Sigs[i]; + if (size >= pair.sigSize) + if (memcmp(p, pair.sig, pair.sigSize) == 0) + break; + } + if (i == Z7_ARRAY_SIZE(g_Sigs)) + return NULL; + switch (i) + { + case kSig_BMP: + if (GetUi32(p + 2) > size || GetUi32(p + 0xA) > size) + return NULL; + break; + case kSig_RIFF: + if (GetUi32(p + 8) == 0x45564157 || GetUi32(p + 0xC) == 0x20746D66 ) + return "wav"; + break; + case kSig_PE: + { + if (size < 512) + return NULL; + UInt32 peOffset = GetUi32(p + 0x3C); + if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0) + return NULL; + if (GetUi32(p + peOffset) != 0x00004550) + return NULL; + break; + } + } + return g_Sigs[i].ext; +} + +static bool AreGuidsEq(const Byte *p1, const Byte *p2) +{ + return memcmp(p1, p2, kGuidSize) == 0; +} + +static int FindGuid(const Byte *p) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kGuids); i++) + if (AreGuidsEq(p, kGuids[i])) + return (int)i; + return -1; +} + +static bool IsFfs(const Byte *p) +{ + if (Get32(p + 0x28) != kFvSignature) + return false; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Guids_FS); i++) + if (AreGuidsEq(p + kFfsGuidOffset, k_Guids_FS[i])) + return true; + return false; +} + +#define FVB_ERASE_POLARITY (1 << 11) + +/* +static const CUInt32PCharPair g_FV_Attribs[] = +{ + { 0, "ReadDisabledCap" }, + { 1, "ReadEnabledCap" }, + { 2, "ReadEnabled" }, + { 3, "WriteDisabledCap" }, + { 4, "WriteEnabledCap" }, + { 5, "WriteEnabled" }, + { 6, "LockCap" }, + { 7, "Locked" }, + + { 9, "StickyWrite" }, + { 10, "MemoryMapped" }, + { 11, "ErasePolarity" }, + + { 12, "ReadLockCap" }, + { 13, "WriteLockCap" }, + { 14, "WriteLockCap" } +}; +*/ + +enum +{ + FV_FILETYPE_ALL, + FV_FILETYPE_RAW, + FV_FILETYPE_FREEFORM, + FV_FILETYPE_SECURITY_CORE, + FV_FILETYPE_PEI_CORE, + FV_FILETYPE_DXE_CORE, + FV_FILETYPE_PEIM, + FV_FILETYPE_DRIVER, + FV_FILETYPE_COMBINED_PEIM_DRIVER, + FV_FILETYPE_APPLICATION, + // The value 0x0A is reserved and should not be used + FV_FILETYPE_FIRMWARE_VOLUME_IMAGE = 0x0B, + // types 0xF0 - 0xFF are FFS file types + FV_FILETYPE_FFS_PAD = 0xF0 +}; + +static const char * const g_FileTypes[] = +{ + "ALL" + , "RAW" + , "FREEFORM" + , "SECURITY_CORE" + , "PEI_CORE" + , "DXE_CORE" + , "PEIM" + , "DRIVER" + , "COMBINED_PEIM_DRIVER" + , "APPLICATION" + , "0xA" + , "VOLUME" +}; + +// typedef Byte FFS_FILE_ATTRIBUTES; +// FFS File Attributes +#define FFS_ATTRIB_TAIL_PRESENT 0x01 +// #define FFS_ATTRIB_RECOVERY 0x02 +// #define FFS_ATTRIB_HEADER_EXTENSION 0x04 +// #define FFS_ATTRIB_DATA_ALIGNMENT 0x38 +#define FFS_ATTRIB_CHECKSUM 0x40 + +static const CUInt32PCharPair g_FFS_FILE_ATTRIBUTES[] = +{ + { 0, "" /* "TAIL" */ }, + { 1, "RECOVERY" }, + // { 2, "HEADER_EXTENSION" }, // reserved for future + { 6, "" /* "CHECKSUM" */ } +}; + +// static const Byte g_Allignment[8] = { 3, 4, 7, 9, 10, 12, 15, 16 }; + +// typedef Byte FFS_FILE_STATE; + +// Look also FVB_ERASE_POLARITY. +// Lower-order State bits are superceded by higher-order State bits. + +// #define FILE_HEADER_CONSTRUCTION 0x01 +// #define FILE_HEADER_VALID 0x02 +#define FILE_DATA_VALID 0x04 +// #define FILE_MARKED_FOR_UPDATE 0x08 +// #define FILE_DELETED 0x10 +// #define FILE_HEADER_INVALID 0x20 + +// SECTION_TYPE + +// #define SECTION_ALL 0x00 + +#define SECTION_COMPRESSION 0x01 +#define SECTION_GUID_DEFINED 0x02 + +// Leaf section Type values +// #define SECTION_PE32 0x10 +// #define SECTION_PIC 0x11 +// #define SECTION_TE 0x12 +#define SECTION_DXE_DEPEX 0x13 +#define SECTION_VERSION 0x14 +#define SECTION_USER_INTERFACE 0x15 +// #define SECTION_COMPATIBILITY16 0x16 +#define SECTION_FIRMWARE_VOLUME_IMAGE 0x17 +#define SECTION_FREEFORM_SUBTYPE_GUID 0x18 +#define SECTION_RAW 0x19 +#define SECTION_PEI_DEPEX 0x1B + + +// #define GUIDED_SECTION_PROCESSING_REQUIRED 0x01 +// #define GUIDED_SECTION_AUTH_STATUS_VALID 0x02 + +static const CUInt32PCharPair g_GUIDED_SECTION_ATTRIBUTES[] = +{ + { 0, "PROCESSING_REQUIRED" }, + { 1, "AUTH" } +}; + +static const CUInt32PCharPair g_SECTION_TYPE[] = +{ + { 0x01, "COMPRESSION" }, + { 0x02, "GUID" }, + { 0x10, "efi" }, + { 0x11, "PIC" }, + { 0x12, "te" }, + { 0x13, "DXE_DEPEX" }, + { 0x14, "VERSION" }, + { 0x15, "USER_INTERFACE" }, + { 0x16, "COMPATIBILITY16" }, + { 0x17, "VOLUME" }, + { 0x18, "FREEFORM_SUBTYPE_GUID" }, + { 0x19, "raw" }, + { 0x1B, "PEI_DEPEX" } +}; + +#define COMPRESSION_TYPE_NONE 0 +#define COMPRESSION_TYPE_LZH 1 +#define COMPRESSION_TYPE_LZMA 2 + +static const char * const g_Methods[] = +{ + "COPY" + , "LZH" + , "LZMA" +}; + + +static void AddGuid(AString &dest, const Byte *p, bool full) +{ + char s[64]; + ::RawLeGuidToString(p, s); + // MyStringUpper_Ascii(s); + if (!full) + s[8] = 0; + dest += s; +} + +static const char * const kExpressionCommands[] = +{ + "BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR" +}; + +static bool ParseDepedencyExpression(const Byte *p, UInt32 size, AString &res) +{ + res.Empty(); + for (UInt32 i = 0; i < size;) + { + unsigned command = p[i++]; + if (command > Z7_ARRAY_SIZE(kExpressionCommands)) + return false; + res += kExpressionCommands[command]; + if (command < 3) + { + if (i + kGuidSize > size) + return false; + res.Add_Space(); + AddGuid(res, p + i, false); + i += kGuidSize; + } + res += "; "; + } + return true; +} + +static bool ParseUtf16zString(const Byte *p, UInt32 size, UString &res) +{ + if ((size & 1) != 0) + return false; + res.Empty(); + UInt32 i; + for (i = 0; i < size; i += 2) + { + wchar_t c = Get16(p + i); + if (c == 0) + break; + res += c; + } + return (i == size - 2); +} + +static bool ParseUtf16zString2(const Byte *p, UInt32 size, AString &res) +{ + UString s; + if (!ParseUtf16zString(p, size, s)) + return false; + res = UnicodeStringToMultiByte(s); + return true; +} + +#define FLAGS_TO_STRING(pairs, value) FlagsToString(pairs, Z7_ARRAY_SIZE(pairs), value) +#define TYPE_TO_STRING(table, value) TypeToString(table, Z7_ARRAY_SIZE(table), value) +#define TYPE_PAIR_TO_STRING(table, value) TypePairToString(table, Z7_ARRAY_SIZE(table), value) + +static const UInt32 kFileHeaderSize = 24; + +static void AddSpaceAndString(AString &res, const AString &newString) +{ + if (!newString.IsEmpty()) + { + res.Add_Space_if_NotEmpty(); + res += newString; + } +} + +class CFfsFileHeader +{ +PRF(public:) + Byte CheckHeader; + Byte CheckFile; + Byte Attrib; + Byte State; + + UInt16 GetTailReference() const { return (UInt16)(CheckHeader | ((UInt16)CheckFile << 8)); } + UInt32 GetTailSize() const { return IsThereTail() ? 2 : 0; } + bool IsThereFileChecksum() const { return (Attrib & FFS_ATTRIB_CHECKSUM) != 0; } + bool IsThereTail() const { return (Attrib & FFS_ATTRIB_TAIL_PRESENT) != 0; } +public: + Byte GuidName[kGuidSize]; + Byte Type; + UInt32 Size; + + bool Parse(const Byte *p) + { + unsigned i; + for (i = 0; i < kFileHeaderSize; i++) + if (p[i] != 0xFF) + break; + if (i == kFileHeaderSize) + return false; + memcpy(GuidName, p, kGuidSize); + CheckHeader = p[0x10]; + CheckFile = p[0x11]; + Type = p[0x12]; + Attrib = p[0x13]; + Size = Get24(p + 0x14); + State = p[0x17]; + return true; + } + + UInt32 GetDataSize() const { return Size - kFileHeaderSize - GetTailSize(); } + UInt32 GetDataSize2(UInt32 rem) const { return rem - kFileHeaderSize - GetTailSize(); } + + bool Check(const Byte *p, UInt32 size) + { + if (Size > size) + return false; + UInt32 tailSize = GetTailSize(); + if (Size < kFileHeaderSize + tailSize) + return false; + + { + unsigned checkSum = 0; + for (UInt32 i = 0; i < kFileHeaderSize; i++) + checkSum += p[i]; + checkSum -= p[0x17]; + checkSum -= p[0x11]; + if ((Byte)checkSum != 0) + return false; + } + + if (IsThereFileChecksum()) + { + unsigned checkSum = 0; + UInt32 checkSize = Size - tailSize; + for (UInt32 i = 0; i < checkSize; i++) + checkSum += p[i]; + checkSum -= p[0x17]; + if ((Byte)checkSum != 0) + return false; + } + + if (IsThereTail()) + if (GetTailReference() != (UInt16)~Get16(p + Size - 2)) + return false; + + int polarity = 0; + int i; + for (i = 5; i >= 0; i--) + if (((State >> i) & 1) == polarity) + { + // AddSpaceAndString(s, g_FFS_FILE_STATE_Flags[i]); + if ((1 << i) != FILE_DATA_VALID) + return false; + break; + } + if (i < 0) + return false; + + return true; + } + + AString GetCharacts() const + { + AString s; + if (Type == FV_FILETYPE_FFS_PAD) + s += "PAD"; + else + s += TYPE_TO_STRING(g_FileTypes, Type); + AddSpaceAndString(s, FLAGS_TO_STRING(g_FFS_FILE_ATTRIBUTES, Attrib & 0xC7)); + /* + int align = (Attrib >> 3) & 7; + if (align != 0) + { + s += " Align:"; + s.Add_UInt32((UInt32)1 << g_Allignment[align]); + } + */ + return s; + } +}; + +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G16(_offs_, dest) dest = Get16(p + (_offs_)) + +struct CCapsuleHeader +{ + UInt32 HeaderSize; + UInt32 Flags; + UInt32 CapsuleImageSize; + UInt32 SequenceNumber; + // Guid InstanceId; + UInt32 OffsetToSplitInformation; + UInt32 OffsetToCapsuleBody; + UInt32 OffsetToOemDefinedHeader; + UInt32 OffsetToAuthorInformation; + UInt32 OffsetToRevisionInformation; + UInt32 OffsetToShortDescription; + UInt32 OffsetToLongDescription; + UInt32 OffsetToApplicableDevices; + + void Clear() { memset(this, 0, sizeof(*this)); } + + bool Parse(const Byte *p) + { + Clear(); + G32(0x10, HeaderSize); + G32(0x14, Flags); + G32(0x18, CapsuleImageSize); + if (HeaderSize < 0x1C) + return false; + if (AreGuidsEq(p, k_Guids_Capsules[0])) + { + const unsigned kHeaderSize = 80; + if (HeaderSize != kHeaderSize) + return false; + G32(0x1C, SequenceNumber); + G32(0x30, OffsetToSplitInformation); + G32(0x34, OffsetToCapsuleBody); + G32(0x38, OffsetToOemDefinedHeader); + G32(0x3C, OffsetToAuthorInformation); + G32(0x40, OffsetToRevisionInformation); + G32(0x44, OffsetToShortDescription); + G32(0x48, OffsetToLongDescription); + G32(0x4C, OffsetToApplicableDevices); + return true; + } + else if (AreGuidsEq(p, k_Guids_Capsules[1])) + { + // capsule v2 + G16(0x1C, OffsetToCapsuleBody); + G16(0x1E, OffsetToOemDefinedHeader); + return true; + } + else if (AreGuidsEq(p, k_Guids_Capsules[2])) + { + OffsetToCapsuleBody = HeaderSize; + return true; + } + else + { + // here we must check for another capsule types + return false; + } + } +}; + + +struct CItem +{ + AString Name; + AString Characts; + int Parent; + int Method; + int NameIndex; + unsigned NumChilds; + bool IsDir; + bool Skip; + bool ThereAreSubDirs; + bool ThereIsUniqueName; + bool KeepName; + + unsigned BufIndex; + UInt32 Offset; + UInt32 Size; + + CItem(): Parent(-1), Method(-1), NameIndex(-1), NumChilds(0), + IsDir(false), Skip(false), ThereAreSubDirs(false), ThereIsUniqueName(false), KeepName(true) {} + void SetGuid(const Byte *guidName, bool full = false); + AString GetName(int numChildsInParent) const; +}; + +void CItem::SetGuid(const Byte *guidName, bool full) +{ + ThereIsUniqueName = true; + int index = FindGuid(guidName); + if (index >= 0) + Name = kGuidNames[(unsigned)index]; + else + { + Name.Empty(); + AddGuid(Name, guidName, full); + } +} + +AString CItem::GetName(int numChildsInParent) const +{ + if (numChildsInParent <= 1 || NameIndex < 0) + return Name; + char sz[32]; + char sz2[32]; + ConvertUInt32ToString((unsigned)NameIndex, sz); + ConvertUInt32ToString((unsigned)numChildsInParent - 1, sz2); + const int numZeros = (int)strlen(sz2) - (int)strlen(sz); + AString res; + for (int i = 0; i < numZeros; i++) + res += '0'; + res += sz; + res.Add_Dot(); + res += Name; + return res; +} + +struct CItem2 +{ + AString Name; + AString Characts; + unsigned MainIndex; + int Parent; + + CItem2(): Parent(-1) {} +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) + CObjectVector _items; + CObjectVector _items2; + CObjectVector _bufs; + UString _comment; + UInt32 _methodsMask; + bool _capsuleMode; + bool _headersError; + + size_t _totalBufsSize; + CCapsuleHeader _h; + UInt64 _phySize; + + void AddCommentString(const char *name, UInt32 pos); + unsigned AddItem(const CItem &item); + unsigned AddFileItemWithIndex(CItem &item); + unsigned AddDirItem(CItem &item); + unsigned AddBuf(size_t size); + + HRESULT DecodeLzma(const Byte *data, size_t inputSize); + + HRESULT ParseSections(unsigned bufIndex, UInt32 pos, + UInt32 size, + int parent, int method, unsigned level, + bool &error); + + HRESULT ParseIntelMe(unsigned bufIndex, UInt32 posBase, + UInt32 exactSize, UInt32 limitSize, + int parent, int method, unsigned level); + + HRESULT ParseVolume(unsigned bufIndex, UInt32 posBase, + UInt32 exactSize, UInt32 limitSize, + int parent, int method, unsigned level); + + HRESULT OpenCapsule(IInStream *stream); + HRESULT OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback); + HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback); +public: + CHandler(bool capsuleMode): _capsuleMode(capsuleMode) {} +}; + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + // kpidOffset, + kpidMethod, + kpidCharacts +}; + +static const Byte kArcProps[] = +{ + kpidComment, + kpidMethod, + kpidCharacts +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItem2 &item2 = _items2[index]; + const CItem &item = _items[item2.MainIndex]; + switch (propID) + { + case kpidPath: + { + AString path (item2.Name); + int cur = item2.Parent; + while (cur >= 0) + { + const CItem2 &item3 = _items2[cur]; + path.InsertAtFront(CHAR_PATH_SEPARATOR); + path.Insert(0, item3.Name); + cur = item3.Parent; + } + prop = path; + break; + } + case kpidIsDir: prop = item.IsDir; break; + case kpidMethod: if (item.Method >= 0) prop = g_Methods[(unsigned)item.Method]; break; + case kpidCharacts: if (!item2.Characts.IsEmpty()) prop = item2.Characts; break; + case kpidSize: if (!item.IsDir) prop = (UInt64)item.Size; break; + // case kpidOffset: if (!item.IsDir) prop = item.Offset; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +void CHandler::AddCommentString(const char *name, UInt32 pos) +{ + UString s; + if (pos < _h.HeaderSize) + return; + if (pos >= _h.OffsetToCapsuleBody) + return; + UInt32 limit = (_h.OffsetToCapsuleBody - pos) & ~(UInt32)1; + const Byte *buf = _bufs[0] + pos; + for (UInt32 i = 0;;) + { + if (s.Len() > (1 << 16) || i >= limit) + return; + wchar_t c = Get16(buf + i); + i += 2; + if (c == 0) + { + if (i >= limit) + return; + c = Get16(buf + i); + i += 2; + if (c == 0) + break; + s.Add_LF(); + } + s += c; + } + if (s.IsEmpty()) + return; + _comment.Add_LF(); + _comment += name; + _comment += ": "; + _comment += s; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidMethod: + { + AString s; + for (unsigned i = 0; i < 32; i++) + if ((_methodsMask & ((UInt32)1 << i)) != 0) + AddSpaceAndString(s, (AString)g_Methods[i]); + if (!s.IsEmpty()) + prop = s; + break; + } + case kpidComment: if (!_comment.IsEmpty()) prop = _comment; break; + case kpidPhySize: prop = (UInt64)_phySize; break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +#ifdef SHOW_DEBUG_INFO +static void PrintLevel(unsigned level) +{ + PRF(printf("\n")); + for (unsigned i = 0; i < level; i++) + PRF(printf(" ")); +} +static void MyPrint(UInt32 posBase, UInt32 size, unsigned level, const char *name) +{ + PrintLevel(level); + PRF(printf("%s, pos = %6x, size = %6x", name, posBase, size)); +} +#else +#define PrintLevel(level) +#define MyPrint(posBase, size, level, name) +#endif + + + +unsigned CHandler::AddItem(const CItem &item) +{ + if (_items.Size() >= kNumFilesMax) + throw 2; + return _items.Add(item); +} + +unsigned CHandler::AddFileItemWithIndex(CItem &item) +{ + unsigned nameIndex = _items.Size(); + if (item.Parent >= 0) + nameIndex = _items[item.Parent].NumChilds++; + item.NameIndex = (int)nameIndex; + return AddItem(item); +} + +unsigned CHandler::AddDirItem(CItem &item) +{ + if (item.Parent >= 0) + _items[item.Parent].ThereAreSubDirs = true; + item.IsDir = true; + item.Size = 0; + return AddItem(item); +} + +unsigned CHandler::AddBuf(size_t size) +{ + if (size > kBufTotalSizeMax - _totalBufsSize) + throw 1; + _totalBufsSize += size; + unsigned index = _bufs.Size(); + _bufs.AddNew().Alloc(size); + return index; +} + + +HRESULT CHandler::DecodeLzma(const Byte *data, size_t inputSize) +{ + if (inputSize < 5 + 8) + return S_FALSE; + const UInt64 unpackSize = Get64(data + 5); + if (unpackSize > ((UInt32)1 << 30)) + return S_FALSE; + SizeT destLen = (SizeT)unpackSize; + const unsigned newBufIndex = AddBuf((size_t)unpackSize); + CByteBuffer &buf = _bufs[newBufIndex]; + ELzmaStatus status; + SizeT srcLen = inputSize - (5 + 8); + const SizeT srcLen2 = srcLen; + SRes res = LzmaDecode(buf, &destLen, data + 13, &srcLen, + data, 5, LZMA_FINISH_END, &status, &g_Alloc); + if (res != 0) + return S_FALSE; + if (srcLen != srcLen2 || destLen != unpackSize || ( + status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + return S_FALSE; + return S_OK; +} + + +HRESULT CHandler::ParseSections(unsigned bufIndex, UInt32 posBase, UInt32 size, int parent, int method, unsigned level, bool &error) +{ + error = false; + + if (level > kLevelMax) + return S_FALSE; + MyPrint(posBase, size, level, "Sections"); + level++; + const Byte *bufData = _bufs[bufIndex]; + UInt32 pos = 0; + for (;;) + { + if (size == pos) + return S_OK; + PrintLevel(level); + PRF(printf("%s, abs = %6x, relat = %6x", "Sect", posBase + pos, pos)); + pos = (pos + 3) & ~(UInt32)3; + if (pos > size) + return S_FALSE; + UInt32 rem = size - pos; + if (rem == 0) + return S_OK; + if (rem < 4) + return S_FALSE; + + const Byte *p = bufData + posBase + pos; + + const UInt32 sectSize = Get24(p); + const Byte type = p[3]; + + // PrintLevel(level); + PRF(printf(" type = %2x, sectSize = %6x", type, sectSize)); + + if (sectSize > rem || sectSize < 4) + { + _headersError = true; + error = true; + return S_OK; + // return S_FALSE; + } + + CItem item; + item.Method = method; + item.BufIndex = bufIndex; + item.Parent = parent; + item.Offset = posBase + pos + 4; + UInt32 sectDataSize = sectSize - 4; + item.Size = sectDataSize; + item.Name = TYPE_PAIR_TO_STRING(g_SECTION_TYPE, type); + + if (type == SECTION_COMPRESSION) + { + if (sectSize < 4 + 5) + return S_FALSE; + const UInt32 uncompressedSize = Get32(p + 4); + const Byte compressionType = p[8]; + + UInt32 newSectSize = sectSize - 9; + UInt32 newOffset = posBase + pos + 9; + const Byte *pStart = p + 9; + + item.KeepName = false; + if (compressionType > 2) + { + // AddFileItemWithIndex(item); + return S_FALSE; + } + else + { + item.Name = g_Methods[compressionType]; + // int parent = AddDirItem(item); + if (compressionType == COMPRESSION_TYPE_NONE) + { + bool error2; + RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level, error2)) + } + else if (compressionType == COMPRESSION_TYPE_LZH) + { + const unsigned newBufIndex = AddBuf(uncompressedSize); + CByteBuffer &buf = _bufs[newBufIndex]; + CMyUniquePtr lzhDecoder; + lzhDecoder.Create_if_Empty(); + { + const Byte *src = pStart; + if (newSectSize < 8) + return S_FALSE; + UInt32 packSize = Get32(src); + const UInt32 unpackSize = Get32(src + 4); + + PRF(printf(" LZH packSize = %6x, unpackSize = %6x", packSize, unpackSize)); + + if (uncompressedSize != unpackSize || newSectSize - 8 != packSize) + return S_FALSE; + if (packSize < 1) + return S_FALSE; + packSize--; + src += 8; + if (src[packSize] != 0) + return S_FALSE; + + CMyComPtr2_Create inStream; + CMyComPtr2_Create outStream; + // const UInt64 uncompressedSize64 = uncompressedSize; + // lzhDecoder->FinishMode = true; + /* + EFI 1.1 probably used LZH with small dictionary and (pbit = 4). It was named "Efi compression". + New version of compression code (named Tiano) uses LZH with (1 << 19) dictionary. + But maybe LZH decoder in UEFI decoder supports larger than (1 << 19) dictionary. + We check both LZH versions: Tiano and then Efi. + */ + HRESULT res = S_FALSE; + for (unsigned m = 0 ; m < 2; m++) + { + inStream->Init(src, packSize); + outStream->Init(buf, uncompressedSize); + lzhDecoder->SetDictSize(m == 0 ? ((UInt32)1 << 19) : ((UInt32)1 << 14)); + res = lzhDecoder->Code(inStream, outStream, uncompressedSize, NULL); + if (res == S_OK) + break; + } + RINOK(res) + } + bool error2; + RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level, error2)) + } + else + { + if (newSectSize < 4 + 5 + 8) + return S_FALSE; + unsigned addSize = 4; + if (pStart[0] == 0x5d && pStart[1] == 0 && pStart[2] == 0 && pStart[3] == 0x80 && pStart[4] == 0) + { + addSize = 0; + // some archives have such header + } + else + { + // normal BIOS contains uncompressed size here + // UInt32 uncompressedSize2 = Get24(pStart); + // Byte firstSectType = p[9 + 3]; + // firstSectType can be 0 in some archives + } + pStart += addSize; + + RINOK(DecodeLzma(pStart, newSectSize - addSize)) + const size_t lzmaUncompressedSize = _bufs.Back().Size(); + // if (lzmaUncompressedSize != uncompressedSize) + if (lzmaUncompressedSize < uncompressedSize) + return S_FALSE; + bool error2; + RINOK(ParseSections(_bufs.Size() - 1, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level, error2)) + } + _methodsMask |= (1 << compressionType); + } + } + else if (type == SECTION_GUID_DEFINED) + { + const unsigned kHeaderSize = 4 + kGuidSize + 4; + if (sectSize < kHeaderSize) + return S_FALSE; + item.SetGuid(p + 4); + const UInt32 dataOffset = Get16(p + 4 + kGuidSize); + const UInt32 attrib = Get16(p + 4 + kGuidSize + 2); + if (dataOffset > sectSize || dataOffset < kHeaderSize) + return S_FALSE; + UInt32 newSectSize = sectSize - dataOffset; + item.Size = newSectSize; + UInt32 newOffset = posBase + pos + dataOffset; + item.Offset = newOffset; + const UInt32 propsSize = dataOffset - kHeaderSize; + AddSpaceAndString(item.Characts, FLAGS_TO_STRING(g_GUIDED_SECTION_ATTRIBUTES, attrib)); + + bool needDir = true; + unsigned newBufIndex = bufIndex; + int newMethod = method; + + if (AreGuidsEq(p + 0x4, k_Guid_LZMA_COMPRESSED)) + { + // item.Name = "guid.lzma"; + // AddItem(item); + const Byte *pStart = bufData + newOffset; + // do we need correct pStart here for lzma steram offset? + RINOK(DecodeLzma(pStart, newSectSize)) + _methodsMask |= (1 << COMPRESSION_TYPE_LZMA); + newBufIndex = _bufs.Size() - 1; + newOffset = 0; + newSectSize = (UInt32)_bufs.Back().Size(); + newMethod = COMPRESSION_TYPE_LZMA; + } + else if (AreGuidsEq(p + 0x4, kGuids[kGuidIndex_CRC]) && propsSize == 4) + { + needDir = false; + item.KeepName = false; + if (CrcCalc(bufData + newOffset, newSectSize) != Get32(p + kHeaderSize)) + return S_FALSE; + } + else + { + if (propsSize != 0) + { + CItem item2 = item; + item2.Name += ".prop"; + item2.Size = propsSize; + item2.Offset = posBase + pos + kHeaderSize; + AddItem(item2); + } + } + + int newParent = parent; + if (needDir) + newParent = (int)AddDirItem(item); + bool error2; + RINOK(ParseSections(newBufIndex, newOffset, newSectSize, newParent, newMethod, level, error2)) + } + else if (type == SECTION_FIRMWARE_VOLUME_IMAGE) + { + item.KeepName = false; + const int newParent = (int)AddDirItem(item); + RINOK(ParseVolume(bufIndex, posBase + pos + 4, + sectSize - 4, + sectSize - 4, + newParent, method, level)) + } + else + { + bool needAdd = true; + switch (type) + { + case SECTION_RAW: + { + const UInt32 kInsydeOffset = 12; + if (sectDataSize >= kFvHeaderSize + kInsydeOffset) + { + if (IsFfs(p + 4 + kInsydeOffset) && + sectDataSize - kInsydeOffset == Get64(p + 4 + kInsydeOffset + 0x20)) + { + needAdd = false; + item.Name = "vol"; + const unsigned newParent = AddDirItem(item); + RINOK(ParseVolume(bufIndex, posBase + pos + 4 + kInsydeOffset, + sectDataSize - kInsydeOffset, + sectDataSize - kInsydeOffset, + (int)newParent, method, level)) + } + + if (needAdd) + { + const char *ext = FindExt(p + 4, sectDataSize); + if (ext) + item.Name = ext; + } + } + break; + } + case SECTION_DXE_DEPEX: + case SECTION_PEI_DEPEX: + { + AString s; + if (ParseDepedencyExpression(p + 4, sectDataSize, s)) + { + if (s.Len() < (1 << 9)) + { + s.InsertAtFront('['); + s += ']'; + AddSpaceAndString(_items[item.Parent].Characts, s); + needAdd = false; + } + else + { + item.BufIndex = AddBuf(s.Len()); + CByteBuffer &buf0 = _bufs[item.BufIndex]; + if (s.Len() != 0) + memcpy(buf0, s, s.Len()); + item.Offset = 0; + item.Size = s.Len(); + } + } + break; + } + case SECTION_VERSION: + { + if (sectDataSize > 2) + { + AString s; + if (ParseUtf16zString2(p + 6, sectDataSize - 2, s)) + { + AString s2 ("ver:"); + s2.Add_UInt32(Get16(p + 4)); + s2.Add_Space(); + s2 += s; + AddSpaceAndString(_items[item.Parent].Characts, s2); + needAdd = false; + } + } + break; + } + case SECTION_USER_INTERFACE: + { + AString s; + if (ParseUtf16zString2(p + 4, sectDataSize, s)) + { + _items[parent].Name = s; + needAdd = false; + } + break; + } + case SECTION_FREEFORM_SUBTYPE_GUID: + { + if (sectDataSize >= kGuidSize) + { + item.SetGuid(p + 4); + item.Size = sectDataSize - kGuidSize; + item.Offset = posBase + pos + 4 + kGuidSize; + } + break; + } + } + + if (needAdd) + AddFileItemWithIndex(item); + } + + pos += sectSize; + } +} + +static UInt32 Count_FF_Bytes(const Byte *p, UInt32 size) +{ + UInt32 i; + for (i = 0; i < size && p[i] == 0xFF; i++); + return i; +} + +static bool Is_FF_Stream(const Byte *p, UInt32 size) +{ + return (Count_FF_Bytes(p, size) == size); +} + +struct CVolFfsHeader +{ + UInt32 HeaderLen; + UInt64 VolSize; + + bool Parse(const Byte *p); +}; + +bool CVolFfsHeader::Parse(const Byte *p) +{ + if (Get32(p + 0x28) != kFvSignature) + return false; + + UInt32 attribs = Get32(p + 0x2C); + if ((attribs & FVB_ERASE_POLARITY) == 0) + return false; + VolSize = Get64(p + 0x20); + HeaderLen = Get16(p + 0x30); + if (HeaderLen < kFvHeaderSize || (HeaderLen & 0x7) != 0 || VolSize < HeaderLen) + return false; + return true; +} + + +HRESULT CHandler::ParseVolume( + unsigned bufIndex, UInt32 posBase, + UInt32 exactSize, UInt32 limitSize, + int parent, int method, unsigned level) +{ + if (level > kLevelMax) + return S_FALSE; + MyPrint(posBase, exactSize, level, "Volume"); + level++; + if (exactSize < kFvHeaderSize) + return S_FALSE; + const Byte *p = _bufs[bufIndex] + posBase; + // first 16 bytes must be zeros, but they are not zeros sometimes. + if (!IsFfs(p)) + { + CItem item; + item.Method = method; + item.BufIndex = bufIndex; + item.Parent = parent; + item.Offset = posBase; + item.Size = exactSize; + if (!Is_FF_Stream(p + kFfsGuidOffset, 16)) + item.SetGuid(p + kFfsGuidOffset); + // if (item.Name.IsEmpty()) + item.Name += "[VOL]"; + AddItem(item); + return S_OK; + } + + CVolFfsHeader ffsHeader; + if (!ffsHeader.Parse(p)) + return S_FALSE; + // if (parent >= 0) AddSpaceAndString(_items[parent].Characts, FLAGS_TO_STRING(g_FV_Attribs, attribs)); + + // VolSize > exactSize (fh.Size) for some UEFI archives (is it correct UEFI?) + // so we check VolSize for limitSize instead. + + if (ffsHeader.HeaderLen > limitSize || ffsHeader.VolSize > limitSize) + return S_FALSE; + + { + UInt32 checkCalc = 0; + for (UInt32 i = 0; i < ffsHeader.HeaderLen; i += 2) + checkCalc += Get16(p + i); + if ((checkCalc & 0xFFFF) != 0) + return S_FALSE; + } + + // 3 reserved bytes are not zeros sometimes. + // UInt16 ExtHeaderOffset; // in new SPECIFICATION? + // Byte revision = p[0x37]; + + UInt32 pos = kFvHeaderSize; + for (;;) + { + if (pos >= ffsHeader.HeaderLen) + return S_FALSE; + UInt32 numBlocks = Get32(p + pos); + UInt32 length = Get32(p + pos + 4); + pos += 8; + if (numBlocks == 0 && length == 0) + break; + } + if (pos != ffsHeader.HeaderLen) + return S_FALSE; + + CRecordVector guidsVector; + + for (;;) + { + UInt32 rem = (UInt32)ffsHeader.VolSize - pos; + if (rem < kFileHeaderSize) + break; + pos = (pos + 7) & ~7u; + rem = (UInt32)ffsHeader.VolSize - pos; + if (rem < kFileHeaderSize) + break; + + CItem item; + item.Method = method; + item.BufIndex = bufIndex; + item.Parent = parent; + + const Byte *pFile = p + pos; + CFfsFileHeader fh; + if (!fh.Parse(pFile)) + { + UInt32 num_FF_bytes = Count_FF_Bytes(pFile, rem); + if (num_FF_bytes != rem) + { + item.Name = "[junk]"; + item.Offset = posBase + pos + num_FF_bytes; + item.Size = rem - num_FF_bytes; + AddItem(item); + } + PrintLevel(level); PRF(printf("== FF FF reminder")); + + break; + } + + PrintLevel(level); PRF(printf("%s, type = %3d, pos = %7x, size = %7x", "FILE", fh.Type, posBase + pos, fh.Size)); + + if (!fh.Check(pFile, rem)) + return S_FALSE; + + UInt32 offset = posBase + pos + kFileHeaderSize; + UInt32 sectSize = fh.GetDataSize(); + item.Offset = offset; + item.Size = sectSize; + + pos += fh.Size; + + if (fh.Type == FV_FILETYPE_FFS_PAD) + if (Is_FF_Stream(pFile + kFileHeaderSize, sectSize)) + continue; + + UInt32 guid32 = Get32(fh.GuidName); + bool full = true; + if (guidsVector.FindInSorted(guid32) < 0) + { + guidsVector.AddToUniqueSorted(guid32); + full = false; + } + item.SetGuid(fh.GuidName, full); + + item.Characts = fh.GetCharacts(); + // PrintLevel(level); + PRF(printf(" : %s", item.Characts)); + + { + PRF(printf(" attrib = %2d State = %3d ", (unsigned)fh.Attrib, (unsigned)fh.State)); + PRF(char s[64]); + PRF(RawLeGuidToString(fh.GuidName, s)); + PRF(printf(" : %s ", s)); + } + + if (fh.Type == FV_FILETYPE_FFS_PAD || + fh.Type == FV_FILETYPE_RAW) + { + bool isVolume = false; + if (fh.Type == FV_FILETYPE_RAW) + { + if (sectSize >= kFvHeaderSize) + if (IsFfs(pFile + kFileHeaderSize)) + isVolume = true; + } + if (isVolume) + { + const unsigned newParent = AddDirItem(item); + const UInt32 limSize = fh.GetDataSize2(rem); + // volume.VolSize > fh.Size for some UEFI archives (is it correct UEFI?) + // so we will check VolSize for limitSize instead. + RINOK(ParseVolume(bufIndex, offset, sectSize, limSize, (int)newParent, method, level)) + } + else + AddItem(item); + } + else + { + /* + if (fh.Type == FV_FILETYPE_FREEFORM) + { + // in intel bio example: one FV_FILETYPE_FREEFORM file is wav file (not sections) + // AddItem(item); + } + else + */ + { + const unsigned newParent = AddDirItem(item); + bool error2; + RINOK(ParseSections(bufIndex, offset, sectSize, (int)newParent, method, level + 1, error2)) + if (error2) + { + // in intel bio example: one FV_FILETYPE_FREEFORM file is wav file (not sections) + item.IsDir = false; + item.Size = sectSize; + item.Name.Insert(0, "[ERROR]"); + AddItem(item); + } + } + } + } + + return S_OK; +} + + +static const char * const kRegionName[] = +{ + "Descriptor" + , "BIOS" + , "ME" + , "GbE" + , "PDR" + , "Region5" + , "Region6" + , "Region7" +}; + + +HRESULT CHandler::ParseIntelMe( + unsigned bufIndex, UInt32 posBase, + UInt32 exactSize, UInt32 limitSize, + int parent, int method, unsigned /* level */) +{ + UNUSED_VAR(limitSize) + // level++; + + const Byte *p = _bufs[bufIndex] + posBase; + if (exactSize < 16 + 16) + return S_FALSE; + if (!IsIntelMe(p)) + return S_FALSE; + + UInt32 v0 = GetUi32(p + 20); + // UInt32 numRegions = (v0 >> 24) & 0x7; + UInt32 regAddr = (v0 >> 12) & 0xFF0; + // UInt32 numComps = (v0 >> 8) & 0x3; + // UInt32 fcba = (v0 << 4) & 0xFF0; + + // (numRegions == 0) in header in some new images. + // So we don't use the value from header + UInt32 numRegions = 7; + + for (unsigned i = 0; i <= numRegions; i++) + { + UInt32 offset = regAddr + i * 4; + if (offset + 4 > exactSize) + break; + UInt32 val = GetUi32(p + offset); + + // only 12 bits probably are OK. + // How does it work for files larger than 16 MB? + const UInt32 kMask = 0xFFF; + // const UInt32 kMask = 0xFFFF; // 16-bit is more logical + const UInt32 lim = (val >> 16) & kMask; + const UInt32 base = (val & kMask); + + /* + strange combinations: + PDR: base = 0x1FFF lim = 0; + empty: base = 0xFFFF lim = 0xFFFF; + + PDR: base = 0x7FFF lim = 0; + empty: base = 0x7FFF lim = 0; + */ + if (base == kMask && lim == 0) + continue; // unused + + if (lim < base) + continue; // unused + + CItem item; + item.Name = kRegionName[i]; + item.Method = method; + item.BufIndex = bufIndex; + item.Parent = parent; + item.Offset = posBase + (base << 12); + if (item.Offset > exactSize) + continue; + item.Size = (lim + 1 - base) << 12; + // item.SetGuid(p + kFfsGuidOffset); + // item.Name += " [VOLUME]"; + AddItem(item); + } + return S_OK; +} + + +HRESULT CHandler::OpenCapsule(IInStream *stream) +{ + const unsigned kHeaderSize = 80; + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)) + if (!_h.Parse(buf)) + return S_FALSE; + if (_h.CapsuleImageSize < kHeaderSize + || _h.CapsuleImageSize < _h.HeaderSize + || _h.OffsetToCapsuleBody < _h.HeaderSize + || _h.OffsetToCapsuleBody > _h.CapsuleImageSize + || _h.CapsuleImageSize > (1u << 30) // to reduce false detection + || _h.HeaderSize > (1u << 28) // to reduce false detection + ) + return S_FALSE; + _phySize = _h.CapsuleImageSize; + + if (_h.SequenceNumber != 0 || + _h.OffsetToSplitInformation != 0 ) + return E_NOTIMPL; + + const unsigned bufIndex = AddBuf(_h.CapsuleImageSize); + CByteBuffer &buf0 = _bufs[bufIndex]; + memcpy(buf0, buf, kHeaderSize); + ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize); + + AddCommentString("Author", _h.OffsetToAuthorInformation); + AddCommentString("Revision", _h.OffsetToRevisionInformation); + AddCommentString("Short Description", _h.OffsetToShortDescription); + AddCommentString("Long Description", _h.OffsetToLongDescription); + + + const UInt32 size = _h.CapsuleImageSize - _h.OffsetToCapsuleBody; + + if (size >= 32 && IsIntelMe(buf0 + _h.OffsetToCapsuleBody)) + return ParseIntelMe(bufIndex, _h.OffsetToCapsuleBody, size, size, -1, -1, 0); + + return ParseVolume(bufIndex, _h.OffsetToCapsuleBody, size, size, -1, -1, 0); +} + + +HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback * /* callback */) +{ + Byte buf[kFvHeaderSize]; + RINOK(ReadStream_FALSE(stream, buf, kFvHeaderSize)) + if (!IsFfs(buf)) + return S_FALSE; + CVolFfsHeader ffsHeader; + if (!ffsHeader.Parse(buf)) + return S_FALSE; + if (ffsHeader.VolSize > ((UInt32)1 << 30)) + return S_FALSE; + _phySize = ffsHeader.VolSize; + RINOK(InStream_SeekToBegin(stream)) + UInt32 fvSize32 = (UInt32)ffsHeader.VolSize; + unsigned bufIndex = AddBuf(fvSize32); + RINOK(ReadStream_FALSE(stream, _bufs[bufIndex], fvSize32)) + return ParseVolume(bufIndex, 0, fvSize32, fvSize32, -1, -1, 0); +} + + +HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) +{ + if (_capsuleMode) + { + RINOK(OpenCapsule(stream)) + } + else + { + RINOK(OpenFv(stream, maxCheckStartPosition, callback)) + } + + const unsigned num = _items.Size(); + CIntArr numChilds(num); + + unsigned i; + + for (i = 0; i < num; i++) + numChilds[i] = 0; + + for (i = 0; i < num; i++) + { + const int parent = _items[i].Parent; + if (parent >= 0) + numChilds[(unsigned)parent]++; + } + + for (i = 0; i < num; i++) + { + const CItem &item = _items[i]; + const int parent = item.Parent; + if (parent >= 0) + { + CItem &parentItem = _items[(unsigned)parent]; + if (numChilds[(unsigned)parent] == 1) + if (!item.ThereIsUniqueName || !parentItem.ThereIsUniqueName || !parentItem.ThereAreSubDirs) + parentItem.Skip = true; + } + } + + CUIntVector mainToReduced; + + for (i = 0; i < _items.Size(); i++) + { + mainToReduced.Add(_items2.Size()); + const CItem &item = _items[i]; + if (item.Skip) + continue; + AString name; + int numItems = -1; + int parent = item.Parent; + if (parent >= 0) + numItems = numChilds[(unsigned)parent]; + AString name2 (item.GetName(numItems)); + AString characts2 (item.Characts); + if (item.KeepName) + name = name2; + + while (parent >= 0) + { + const CItem &item3 = _items[(unsigned)parent]; + if (!item3.Skip) + break; + if (item3.KeepName) + { + AString name3 (item3.GetName(-1)); + if (name.IsEmpty()) + name = name3; + else + name = name3 + '.' + name; + } + AddSpaceAndString(characts2, item3.Characts); + parent = item3.Parent; + } + + if (name.IsEmpty()) + name = name2; + + CItem2 item2; + item2.MainIndex = i; + item2.Name = name; + item2.Characts = characts2; + if (parent >= 0) + item2.Parent = (int)mainToReduced[(unsigned)parent]; + _items2.Add(item2); + /* + CItem2 item2; + item2.MainIndex = i; + item2.Name = item.Name; + item2.Parent = item.Parent; + _items2.Add(item2); + */ + } + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + { + HRESULT res = Open2(inStream, maxCheckStartPosition, callback); + if (res == E_NOTIMPL) + res = S_FALSE; + return res; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + _totalBufsSize = 0; + _methodsMask = 0; + _items.Clear(); + _items2.Clear(); + _bufs.Clear(); + _comment.Empty(); + _headersError = false; + _h.Clear(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items2.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _items2.Size(); + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items[_items2[allFilesMode ? i : indices[i]].MainIndex].Size; + RINOK(extractCallback->SetTotal(totalSize)) + totalSize = 0; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CMyComPtr2_Create copyCoder; + + for (i = 0;; i++) + { + lps->InSize = lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CItem &item = _items[_items2[index].MainIndex]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + totalSize += item.Size; + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + if (testMode || item.IsDir) + opRes = NExtract::NOperationResult::kOK; + else + { + opRes = NExtract::NOperationResult::kDataError; + CMyComPtr inStream; + GetStream(index, &inStream); + if (inStream) + { + RINOK(copyCoder.Interface()->Code(inStream, realOutStream, NULL, NULL, lps)) + if (copyCoder->TotalSize == item.Size) + opRes = NExtract::NOperationResult::kOK; + } + } + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + const CItem &item = _items[_items2[index].MainIndex]; + if (item.IsDir) + return S_FALSE; + CBufInStream *streamSpec = new CBufInStream; + CMyComPtr streamTemp = streamSpec; + const CByteBuffer &buf = _bufs[item.BufIndex]; + if (item.Offset > buf.Size()) + return S_FALSE; + size_t size = buf.Size() - item.Offset; + if (size > item.Size) + size = item.Size; + streamSpec->Init(buf + item.Offset, size, (IInArchive *)this); + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + +namespace UEFIc { + +static const Byte k_Capsule_Signatures[] = +{ + 16, CAPSULE_SIGNATURE, + 16, CAPSULE2_SIGNATURE, + 16, CAPSULE_UEFI_SIGNATURE +}; + +REGISTER_ARC_I_CLS( + CHandler(true), + "UEFIc", "scap", NULL, 0xD0, + k_Capsule_Signatures, + 0, + NArcInfoFlags::kMultiSignature | + NArcInfoFlags::kFindSignature, + NULL) + +} + +namespace UEFIf { + +static const Byte k_FFS_Signatures[] = +{ + 16, FFS1_SIGNATURE, + 16, FFS2_SIGNATURE +}; + + +REGISTER_ARC_I_CLS( + CHandler(false), + "UEFIf", "uefif", NULL, 0xD1, + k_FFS_Signatures, + kFfsGuidOffset, + NArcInfoFlags::kMultiSignature | + NArcInfoFlags::kFindSignature, + NULL) + +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/VdiHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VdiHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/VdiHandler.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VdiHandler.cpp 2023-03-06 17:00:00.000000000 +0000 @@ -1,362 +1,438 @@ -// VdiHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/MyBuffer.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -using namespace NWindows; - -namespace NArchive { -namespace NVdi { - -#define SIGNATURE { 0x7F, 0x10, 0xDA, 0xBE } - -static const Byte k_Signature[] = SIGNATURE; - -static const unsigned k_ClusterBits = 20; -static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits; -static const UInt32 k_UnusedCluster = 0xFFFFFFFF; - -// static const UInt32 kDiskType_Dynamic = 1; -// static const UInt32 kDiskType_Static = 2; - -static const char * const kDiskTypes[] = -{ - "0" - , "Dynamic" - , "Static" -}; - -class CHandler: public CHandlerImg -{ - UInt32 _dataOffset; - CByteBuffer _table; - UInt64 _phySize; - UInt32 _imageType; - bool _isArc; - bool _unsupported; - - HRESULT Seek(UInt64 offset) - { - _posInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); - } - - HRESULT InitAndSeek() - { - _virtPos = 0; - return Seek(0); - } - - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); - -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - - -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= _size) - return S_OK; - { - UInt64 rem = _size - _virtPos; - if (size > rem) - size = (UInt32)rem; - if (size == 0) - return S_OK; - } - - { - UInt64 cluster = _virtPos >> k_ClusterBits; - UInt32 lowBits = (UInt32)_virtPos & (k_ClusterSize - 1); - { - UInt32 rem = k_ClusterSize - lowBits; - if (size > rem) - size = rem; - } - - cluster <<= 2; - if (cluster < _table.Size()) - { - const Byte *p = (const Byte *)_table + (size_t)cluster; - UInt32 v = Get32(p); - if (v != k_UnusedCluster) - { - UInt64 offset = _dataOffset + ((UInt64)v << k_ClusterBits); - offset += lowBits; - if (offset != _posInArc) - { - RINOK(Seek(offset)); - } - HRESULT res = Stream->Read(data, size, &size); - _posInArc += size; - _virtPos += size; - if (processedSize) - *processedSize = size; - return res; - } - } - - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } -} - - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize -}; - -static const Byte kArcProps[] = -{ - kpidHeadersSize, - 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 kpidPhySize: if (_phySize != 0) prop = _phySize; break; - case kpidHeadersSize: prop = _dataOffset; break; - - case kpidMethod: - { - char s[16]; - const char *ptr; - if (_imageType < ARRAY_SIZE(kDiskTypes)) - ptr = kDiskTypes[_imageType]; - else - { - ConvertUInt32ToString(_imageType, s); - ptr = s; - } - prop = ptr; - break; - } - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - // if (_headerError) v |= kpv_ErrorFlags_HeadersError; - 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 - _dataOffset; break; - case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -static bool IsEmptyGuid(const Byte *data) -{ - for (unsigned i = 0; i < 16; i++) - if (data[i] != 0) - return false; - return true; -} - - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallback */) -{ - const unsigned kHeaderSize = 512; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - - if (memcmp(buf + 0x40, k_Signature, sizeof(k_Signature)) != 0) - return S_FALSE; - - UInt32 version = Get32(buf + 0x44); - if (version >= 0x20000) - return S_FALSE; - - UInt32 headerSize = Get32(buf + 0x48); - if (headerSize < 0x140 || headerSize > 0x1B8) - return S_FALSE; - - _imageType = Get32(buf + 0x4C); - _dataOffset = Get32(buf + 0x158); - - UInt32 tableOffset = Get32(buf + 0x154); - if (tableOffset < 0x200) - return S_FALSE; - - UInt32 sectorSize = Get32(buf + 0x168); - if (sectorSize != 0x200) - return S_FALSE; - - _size = Get64(buf + 0x170); - _isArc = true; - - if (_imageType > 2) - { - _unsupported = true; - return S_FALSE; - } - - if (_dataOffset < tableOffset) - return S_FALSE; - - UInt32 blockSize = Get32(buf + 0x178); - if (blockSize != ((UInt32)1 << k_ClusterBits)) - { - _unsupported = true; - return S_FALSE; - } - - UInt32 totalBlocks = Get32(buf + 0x180); - - { - UInt64 size2 = (UInt64)totalBlocks << k_ClusterBits; - if (size2 < _size) - { - _unsupported = true; - return S_FALSE; - } - /* - if (size2 > _size) - _size = size2; - */ - } - - if (headerSize >= 0x180) - { - if (!IsEmptyGuid(buf + 0x1A8) || - !IsEmptyGuid(buf + 0x1B8)) - { - _unsupported = true; - return S_FALSE; - } - } - - UInt32 numAllocatedBlocks = Get32(buf + 0x184); - - { - UInt32 tableReserved = _dataOffset - tableOffset; - if ((tableReserved >> 2) < totalBlocks) - return S_FALSE; - } - - _phySize = _dataOffset + ((UInt64)numAllocatedBlocks << k_ClusterBits); - - size_t numBytes = (size_t)totalBlocks * 4; - if ((numBytes >> 2) != totalBlocks) - { - _unsupported = true; - return S_FALSE; - } - - _table.Alloc(numBytes); - RINOK(stream->Seek(tableOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _table, numBytes)); - - const Byte *data = _table; - for (UInt32 i = 0; i < totalBlocks; i++) - { - UInt32 v = Get32(data + (size_t)i * 4); - if (v == k_UnusedCluster) - continue; - if (v >= numAllocatedBlocks) - return S_FALSE; - } - - Stream = stream; - return S_OK; -} - - -STDMETHODIMP CHandler::Close() -{ - _table.Free(); - _phySize = 0; - _size = 0; - _isArc = false; - _unsupported = false; - - _imgExt = NULL; - Stream.Release(); - return S_OK; -} - - -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = NULL; - if (_unsupported) - return S_FALSE; - CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - - -REGISTER_ARC_I( - "VDI", "vdi", NULL, 0xC9, - k_Signature, - 0x40, - 0, - NULL) - -}} +// VdiHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/PropVariantUtils.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +using namespace NWindows; + +namespace NArchive { +namespace NVdi { + +static const Byte k_Signature[] = { 0x7F, 0x10, 0xDA, 0xBE }; + +static const unsigned k_ClusterBits = 20; +static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits; + + +/* +VDI_IMAGE_BLOCK_FREE = (~0) // returns any random data +VDI_IMAGE_BLOCK_ZERO = (~1) // returns zeros +*/ + +// static const UInt32 k_ClusterType_Free = 0xffffffff; +static const UInt32 k_ClusterType_Zero = 0xfffffffe; + +#define IS_CLUSTER_ALLOCATED(v) ((UInt32)(v) < k_ClusterType_Zero) + + +// static const UInt32 kDiskType_Dynamic = 1; +// static const UInt32 kDiskType_Static = 2; + +static const char * const kDiskTypes[] = +{ + "0" + , "Dynamic" + , "Static" + , "Undo" + , "Diff" +}; + + +enum EGuidType +{ + k_GuidType_Creat, + k_GuidType_Modif, + k_GuidType_Link, + k_GuidType_PModif +}; + +static const unsigned kNumGuids = 4; +static const char * const kGuidNames[kNumGuids] = +{ + "Creat " + , "Modif " + , "Link " + , "PModif" +}; + +static bool IsEmptyGuid(const Byte *data) +{ + for (unsigned i = 0; i < 16; i++) + if (data[i] != 0) + return false; + return true; +} + + + +Z7_class_CHandler_final: public CHandlerImg +{ + UInt32 _dataOffset; + CByteBuffer _table; + UInt64 _phySize; + UInt32 _imageType; + bool _isArc; + bool _unsupported; + + Byte Guids[kNumGuids][16]; + + HRESULT Seek2(UInt64 offset) + { + _posInArc = offset; + return InStream_SeekSet(Stream, offset); + } + + HRESULT InitAndSeek() + { + _virtPos = 0; + return Seek2(0); + } + + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; + +public: + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) +}; + + +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= _size) + return S_OK; + { + UInt64 rem = _size - _virtPos; + if (size > rem) + size = (UInt32)rem; + if (size == 0) + return S_OK; + } + + { + UInt64 cluster = _virtPos >> k_ClusterBits; + UInt32 lowBits = (UInt32)_virtPos & (k_ClusterSize - 1); + { + UInt32 rem = k_ClusterSize - lowBits; + if (size > rem) + size = rem; + } + + cluster <<= 2; + if (cluster < _table.Size()) + { + const Byte *p = (const Byte *)_table + (size_t)cluster; + const UInt32 v = Get32(p); + if (IS_CLUSTER_ALLOCATED(v)) + { + UInt64 offset = _dataOffset + ((UInt64)v << k_ClusterBits); + offset += lowBits; + if (offset != _posInArc) + { + RINOK(Seek2(offset)) + } + HRESULT res = Stream->Read(data, size, &size); + _posInArc += size; + _virtPos += size; + if (processedSize) + *processedSize = size; + return res; + } + } + + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } +} + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidHeadersSize, + kpidMethod, + kpidComment, + kpidName +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidHeadersSize: prop = _dataOffset; break; + + case kpidMethod: + { + TYPE_TO_PROP(kDiskTypes, _imageType, prop); + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + // if (_headerError) v |= kpv_ErrorFlags_HeadersError; + if (!Stream && v == 0 && _isArc) + v = kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + + case kpidComment: + { + AString s; + for (unsigned i = 0; i < kNumGuids; i++) + { + const Byte *guid = Guids[i]; + if (!IsEmptyGuid(guid)) + { + s.Add_LF(); + s += kGuidNames[i]; + s += " : "; + char temp[64]; + RawLeGuidToString_Braced(guid, temp); + MyStringLower_Ascii(temp); + s += temp; + } + } + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidName: + { + const Byte *guid = Guids[k_GuidType_Creat]; + if (!IsEmptyGuid(guid)) + { + char temp[64]; + RawLeGuidToString_Braced(guid, temp); + MyStringLower_Ascii(temp); + MyStringCat(temp, ".vdi"); + prop = temp; + } + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(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 - _dataOffset; break; + case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallback */) +{ + const unsigned kHeaderSize = 512; + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)) + + if (memcmp(buf + 0x40, k_Signature, sizeof(k_Signature)) != 0) + return S_FALSE; + + const UInt32 version = Get32(buf + 0x44); + if (version >= 0x20000) + return S_FALSE; + if (version < 0x10000) + { + _unsupported = true; + return S_FALSE; + } + + const unsigned kHeaderOffset = 0x48; + const unsigned kGuidsOffsets = 0x188; + const UInt32 headerSize = Get32(buf + kHeaderOffset); + if (headerSize < kGuidsOffsets - kHeaderOffset || headerSize > 0x200 - kHeaderOffset) + return S_FALSE; + + _imageType = Get32(buf + 0x4C); + // Int32 flags = Get32(buf + 0x50); + // Byte Comment[0x100] + + const UInt32 tableOffset = Get32(buf + 0x154); + if (tableOffset < 0x200) + return S_FALSE; + + _dataOffset = Get32(buf + 0x158); + + // UInt32 geometry[3]; + + const UInt32 sectorSize = Get32(buf + 0x168); + if (sectorSize != 0x200) + return S_FALSE; + + _size = Get64(buf + 0x170); + const UInt32 blockSize = Get32(buf + 0x178); + const UInt32 totalBlocks = Get32(buf + 0x180); + const UInt32 numAllocatedBlocks = Get32(buf + 0x184); + + _isArc = true; + + if (_dataOffset < tableOffset) + return S_FALSE; + + if (_imageType > 4) + _unsupported = true; + + if (blockSize != k_ClusterSize) + { + _unsupported = true; + return S_FALSE; + } + + if (headerSize >= kGuidsOffsets + kNumGuids * 16 - kHeaderOffset) + { + for (unsigned i = 0; i < kNumGuids; i++) + memcpy(Guids[i], buf + kGuidsOffsets + 16 * i, 16); + + if (!IsEmptyGuid(Guids[k_GuidType_Link]) || + !IsEmptyGuid(Guids[k_GuidType_PModif])) + _unsupported = true; + } + + { + UInt64 size2 = (UInt64)totalBlocks << k_ClusterBits; + if (size2 < _size) + { + _unsupported = true; + return S_FALSE; + } + /* + if (size2 > _size) + _size = size2; + */ + } + + { + UInt32 tableReserved = _dataOffset - tableOffset; + if ((tableReserved >> 2) < totalBlocks) + return S_FALSE; + } + + _phySize = _dataOffset + ((UInt64)numAllocatedBlocks << k_ClusterBits); + + const size_t numBytes = (size_t)totalBlocks * 4; + if ((numBytes >> 2) != totalBlocks) + { + _unsupported = true; + return E_OUTOFMEMORY; + } + + _table.Alloc(numBytes); + RINOK(InStream_SeekSet(stream, tableOffset)) + RINOK(ReadStream_FALSE(stream, _table, numBytes)) + + const Byte *data = _table; + for (UInt32 i = 0; i < totalBlocks; i++) + { + const UInt32 v = Get32(data + (size_t)i * 4); + if (!IS_CLUSTER_ALLOCATED(v)) + continue; + if (v >= numAllocatedBlocks) + { + _unsupported = true; + return S_FALSE; + } + } + + Stream = stream; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _table.Free(); + _phySize = 0; + _isArc = false; + _unsupported = false; + + for (unsigned i = 0; i < kNumGuids; i++) + memset(Guids[i], 0, 16); + + // CHandlerImg: + Clear_HandlerImg_Vars(); + Stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + if (_unsupported) + return S_FALSE; + CMyComPtr streamTemp = this; + RINOK(InitAndSeek()) + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + +REGISTER_ARC_I( + "VDI", "vdi", NULL, 0xC9, + k_Signature, + 0x40, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/VhdHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/VhdHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -1,925 +1,966 @@ -// VhdHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "HandlerCont.h" - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -#define G32(_offs_, dest) dest = Get32(p + (_offs_)); -#define G64(_offs_, dest) dest = Get64(p + (_offs_)); - -using namespace NWindows; - -namespace NArchive { -namespace NVhd { - -#define SIGNATURE { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x', 0, 0 } - -static const unsigned kSignatureSize = 10; -static const Byte kSignature[kSignatureSize] = SIGNATURE; - -static const UInt32 kUnusedBlock = 0xFFFFFFFF; - -static const UInt32 kDiskType_Fixed = 2; -static const UInt32 kDiskType_Dynamic = 3; -static const UInt32 kDiskType_Diff = 4; - -static const char * const kDiskTypes[] = -{ - "0" - , "1" - , "Fixed" - , "Dynamic" - , "Differencing" -}; - -struct CFooter -{ - // UInt32 Features; - // UInt32 FormatVersion; - UInt64 DataOffset; - UInt32 CTime; - UInt32 CreatorApp; - UInt32 CreatorVersion; - UInt32 CreatorHostOS; - // UInt64 OriginalSize; - UInt64 CurrentSize; - UInt32 DiskGeometry; - UInt32 Type; - Byte Id[16]; - Byte SavedState; - - bool IsFixed() const { return Type == kDiskType_Fixed; } - bool ThereIsDynamic() const { return Type == kDiskType_Dynamic || Type == kDiskType_Diff; } - // bool IsSupported() const { return Type == kDiskType_Fixed || Type == kDiskType_Dynamic || Type == kDiskType_Diff; } - UInt32 NumCyls() const { return DiskGeometry >> 16; } - UInt32 NumHeads() const { return (DiskGeometry >> 8) & 0xFF; } - UInt32 NumSectorsPerTrack() const { return DiskGeometry & 0xFF; } - AString GetTypeString() const; - bool Parse(const Byte *p); -}; - -AString CFooter::GetTypeString() const -{ - if (Type < ARRAY_SIZE(kDiskTypes)) - return kDiskTypes[Type]; - char s[16]; - ConvertUInt32ToString(Type, s); - return s; -} - -static bool CheckBlock(const Byte *p, unsigned size, unsigned checkSumOffset, unsigned zeroOffset) -{ - UInt32 sum = 0; - unsigned i; - for (i = 0; i < checkSumOffset; i++) - sum += p[i]; - for (i = checkSumOffset + 4; i < size; i++) - sum += p[i]; - if (~sum != Get32(p + checkSumOffset)) - return false; - for (i = zeroOffset; i < size; i++) - if (p[i] != 0) - return false; - return true; -} - -static const unsigned kSectorSize_Log = 9; -static const unsigned kSectorSize = 1 << kSectorSize_Log; -static const unsigned kHeaderSize = 512; - -bool CFooter::Parse(const Byte *p) -{ - if (memcmp(p, kSignature, kSignatureSize) != 0) - return false; - // G32(0x08, Features); - // G32(0x0C, FormatVersion); - G64(0x10, DataOffset); - G32(0x18, CTime); - G32(0x1C, CreatorApp); - G32(0x20, CreatorVersion); - G32(0x24, CreatorHostOS); - // G64(0x28, OriginalSize); - G64(0x30, CurrentSize); - G32(0x38, DiskGeometry); - G32(0x3C, Type); - if (Type < kDiskType_Fixed || - Type > kDiskType_Diff) - return false; - memcpy(Id, p + 0x44, 16); - SavedState = p[0x54]; - // if (DataOffset > ((UInt64)1 << 62)) return false; - // if (CurrentSize > ((UInt64)1 << 62)) return false; - return CheckBlock(p, kHeaderSize, 0x40, 0x55); -} - -struct CParentLocatorEntry -{ - UInt32 Code; - UInt32 DataSpace; - UInt32 DataLen; - UInt64 DataOffset; - - bool Parse(const Byte *p) - { - G32(0x00, Code); - G32(0x04, DataSpace); - G32(0x08, DataLen); - G64(0x10, DataOffset); - return Get32(p + 0x0C) == 0; // Reserved - } -}; - -struct CDynHeader -{ - // UInt64 DataOffset; - UInt64 TableOffset; - // UInt32 HeaderVersion; - UInt32 NumBlocks; - unsigned BlockSizeLog; - UInt32 ParentTime; - Byte ParentId[16]; - bool RelativeNameWasUsed; - UString ParentName; - UString RelativeParentNameFromLocator; - CParentLocatorEntry ParentLocators[8]; - - bool Parse(const Byte *p); - UInt32 NumBitMapSectors() const - { - UInt32 numSectorsInBlock = (1 << (BlockSizeLog - kSectorSize_Log)); - return (numSectorsInBlock + kSectorSize * 8 - 1) / (kSectorSize * 8); - } - void Clear() - { - RelativeNameWasUsed = false; - ParentName.Empty(); - RelativeParentNameFromLocator.Empty(); - } -}; - -bool CDynHeader::Parse(const Byte *p) -{ - if (memcmp(p, "cxsparse", 8) != 0) - return false; - // G64(0x08, DataOffset); - G64(0x10, TableOffset); - // G32(0x18, HeaderVersion); - G32(0x1C, NumBlocks); - { - UInt32 blockSize = Get32(p + 0x20); - unsigned i; - for (i = kSectorSize_Log;; i++) - { - if (i > 31) - return false; - if (((UInt32)1 << i) == blockSize) - break; - } - BlockSizeLog = i; - } - G32(0x38, ParentTime); - if (Get32(p + 0x3C) != 0) // reserved - return false; - memcpy(ParentId, p + 0x28, 16); - { - const unsigned kNameLen = 256; - wchar_t *s = ParentName.GetBuf(kNameLen); - unsigned i; - for (i = 0; i < kNameLen; i++) - { - wchar_t c = Get16(p + 0x40 + i * 2); - if (c == 0) - break; - s[i] = c; - } - s[i] = 0; - ParentName.ReleaseBuf_SetLen(i); - } - for (unsigned i = 0; i < 8; i++) - if (!ParentLocators[i].Parse(p + 0x240 + i * 24)) - return false; - return CheckBlock(p, 1024, 0x24, 0x240 + 8 * 24); -} - -class CHandler: public CHandlerImg -{ - UInt64 _posInArcLimit; - UInt64 _startOffset; - UInt64 _phySize; - - CFooter Footer; - CDynHeader Dyn; - CRecordVector Bat; - CByteBuffer BitMap; - UInt32 BitMapTag; - UInt32 NumUsedBlocks; - // CMyComPtr Stream; - CMyComPtr ParentStream; - CHandler *Parent; - UString _errorMessage; - // bool _unexpectedEnd; - - void AddErrorMessage(const wchar_t *s) - { - if (!_errorMessage.IsEmpty()) - _errorMessage.Add_LF(); - _errorMessage += s; - } - void UpdatePhySize(UInt64 value) - { - if (_phySize < value) - _phySize = value; - } - - void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; } - HRESULT Seek(UInt64 offset); - HRESULT InitAndSeek(); - HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size); - - bool NeedParent() const { return Footer.Type == kDiskType_Diff; } - UInt64 GetPackSize() const - { return Footer.ThereIsDynamic() ? ((UInt64)NumUsedBlocks << Dyn.BlockSizeLog) : Footer.CurrentSize; } - - UString GetParentSequence() const - { - const CHandler *p = this; - UString res; - while (p && p->NeedParent()) - { - if (!res.IsEmpty()) - res.AddAscii(" -> "); - UString mainName; - UString anotherName; - if (Dyn.RelativeNameWasUsed) - { - mainName = p->Dyn.RelativeParentNameFromLocator; - anotherName = p->Dyn.ParentName; - } - else - { - mainName = p->Dyn.ParentName; - anotherName = p->Dyn.RelativeParentNameFromLocator; - } - res += mainName; - if (mainName != anotherName && !anotherName.IsEmpty()) - { - res.Add_Space(); - res += L'('; - res += anotherName; - res += L')'; - } - p = p->Parent; - } - return res; - } - - bool AreParentsOK() const - { - const CHandler *p = this; - while (p->NeedParent()) - { - p = p->Parent; - if (!p) - return false; - } - return true; - } - - HRESULT Open3(); - HRESULT Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level); - HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) - { - return Open2(stream, NULL, openArchiveCallback, 0); - } - void CloseAtError(); - -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -HRESULT CHandler::Seek(UInt64 offset) { return Stream->Seek(_startOffset + offset, STREAM_SEEK_SET, NULL); } - -HRESULT CHandler::InitAndSeek() -{ - if (ParentStream) - { - RINOK(Parent->InitAndSeek()); - } - _virtPos = _posInArc = 0; - BitMapTag = kUnusedBlock; - BitMap.Alloc(Dyn.NumBitMapSectors() << kSectorSize_Log); - return Seek(0); -} - -HRESULT CHandler::ReadPhy(UInt64 offset, void *data, UInt32 size) -{ - if (offset + size > _posInArcLimit) - return S_FALSE; - if (offset != _posInArc) - { - _posInArc = offset; - RINOK(Seek(offset)); - } - HRESULT res = ReadStream_FALSE(Stream, data, size); - if (res == S_OK) - _posInArc += size; - else - Reset_PosInArc(); - return res; -} - -HRESULT CHandler::Open3() -{ - // Fixed archive uses only footer - - UInt64 startPos; - RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &startPos)); - _startOffset = startPos; - Byte header[kHeaderSize]; - RINOK(ReadStream_FALSE(Stream, header, kHeaderSize)); - bool headerIsOK = Footer.Parse(header); - _size = Footer.CurrentSize; - - if (headerIsOK && !Footer.ThereIsDynamic()) - { - // fixed archive - if (startPos < Footer.CurrentSize) - return S_FALSE; - _posInArcLimit = Footer.CurrentSize; - _phySize = Footer.CurrentSize + kHeaderSize; - _startOffset = startPos - Footer.CurrentSize; - _posInArc = _phySize; - return S_OK; - } - - UInt64 fileSize; - RINOK(Stream->Seek(0, STREAM_SEEK_END, &fileSize)); - if (fileSize < kHeaderSize) - return S_FALSE; - - const UInt32 kDynSize = 1024; - Byte buf[kDynSize]; - - RINOK(Stream->Seek(fileSize - kHeaderSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(Stream, buf, kHeaderSize)); - - if (!headerIsOK) - { - if (!Footer.Parse(buf)) - return S_FALSE; - _size = Footer.CurrentSize; - if (Footer.ThereIsDynamic()) - return S_FALSE; // we can't open Dynamic Archive backward. - _posInArcLimit = Footer.CurrentSize; - _phySize = Footer.CurrentSize + kHeaderSize; - _startOffset = fileSize - kHeaderSize - Footer.CurrentSize; - _posInArc = _phySize; - return S_OK; - } - - _phySize = kHeaderSize; - _posInArc = fileSize - startPos; - _posInArcLimit = _posInArc - kHeaderSize; - - bool headerAndFooterAreEqual = false; - if (memcmp(header, buf, kHeaderSize) == 0) - { - headerAndFooterAreEqual = true; - _phySize = fileSize - _startOffset; - } - - RINOK(ReadPhy(Footer.DataOffset, buf, kDynSize)); - if (!Dyn.Parse(buf)) - return S_FALSE; - - UpdatePhySize(Footer.DataOffset + kDynSize); - - for (int i = 0; i < 8; i++) - { - const CParentLocatorEntry &locator = Dyn.ParentLocators[i]; - const UInt32 kNameBufSizeMax = 1024; - if (locator.DataLen < kNameBufSizeMax && - locator.DataOffset < _posInArcLimit && - locator.DataOffset + locator.DataLen <= _posInArcLimit) - { - if (locator.Code == 0x57327275 && (locator.DataLen & 1) == 0) - { - // "W2ru" locator - // Path is encoded as little-endian UTF-16 - Byte nameBuf[kNameBufSizeMax]; - UString tempString; - unsigned len = (locator.DataLen >> 1); - { - wchar_t *s = tempString.GetBuf(len); - RINOK(ReadPhy(locator.DataOffset, nameBuf, locator.DataLen)); - unsigned j; - for (j = 0; j < len; j++) - { - wchar_t c = GetUi16(nameBuf + j * 2); - if (c == 0) - break; - s[j] = c; - } - s[j] = 0; - tempString.ReleaseBuf_SetLen(j); - } - if (tempString[0] == L'.' && tempString[1] == L'\\') - tempString.DeleteFrontal(2); - Dyn.RelativeParentNameFromLocator = tempString; - } - } - if (locator.DataLen != 0) - UpdatePhySize(locator.DataOffset + locator.DataLen); - } - - if (Dyn.NumBlocks >= (UInt32)1 << 31) - return S_FALSE; - if (Footer.CurrentSize == 0) - { - if (Dyn.NumBlocks != 0) - return S_FALSE; - } - else if (((Footer.CurrentSize - 1) >> Dyn.BlockSizeLog) + 1 != Dyn.NumBlocks) - return S_FALSE; - - Bat.ClearAndReserve(Dyn.NumBlocks); - - UInt32 bitmapSize = Dyn.NumBitMapSectors() << kSectorSize_Log; - - while ((UInt32)Bat.Size() < Dyn.NumBlocks) - { - RINOK(ReadPhy(Dyn.TableOffset + (UInt64)Bat.Size() * 4, buf, kSectorSize)); - UpdatePhySize(Dyn.TableOffset + kSectorSize); - for (UInt32 j = 0; j < kSectorSize; j += 4) - { - UInt32 v = Get32(buf + j); - if (v != kUnusedBlock) - { - UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; - UpdatePhySize(((UInt64)v << kSectorSize_Log) + bitmapSize + blockSize); - NumUsedBlocks++; - } - Bat.AddInReserved(v); - if ((UInt32)Bat.Size() >= Dyn.NumBlocks) - break; - } - } - - if (headerAndFooterAreEqual) - return S_OK; - - if (_startOffset + _phySize + kHeaderSize > fileSize) - { - // _unexpectedEnd = true; - _posInArcLimit = _phySize; - _phySize += kHeaderSize; - return S_OK; - } - - RINOK(ReadPhy(_phySize, buf, kHeaderSize)); - if (memcmp(header, buf, kHeaderSize) == 0) - { - _posInArcLimit = _phySize; - _phySize += kHeaderSize; - return S_OK; - } - - if (_phySize == 0x800) - { - /* WHY does empty archive contain additional empty sector? - We skip that sector and check footer again. */ - unsigned i; - for (i = 0; i < kSectorSize && buf[i] == 0; i++); - if (i == kSectorSize) - { - RINOK(ReadPhy(_phySize + kSectorSize, buf, kHeaderSize)); - if (memcmp(header, buf, kHeaderSize) == 0) - { - _phySize += kSectorSize; - _posInArcLimit = _phySize; - _phySize += kHeaderSize; - return S_OK; - } - } - } - _posInArcLimit = _phySize; - _phySize += kHeaderSize; - AddErrorMessage(L"Can't find footer"); - return S_OK; -} - -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Footer.CurrentSize) - return S_OK; - { - const UInt64 rem = Footer.CurrentSize - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - if (size == 0) - return S_OK; - UInt32 blockIndex = (UInt32)(_virtPos >> Dyn.BlockSizeLog); - UInt32 blockSectIndex = Bat[blockIndex]; - UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; - UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); - size = MyMin(blockSize - offsetInBlock, size); - - HRESULT res = S_OK; - if (blockSectIndex == kUnusedBlock) - { - if (ParentStream) - { - RINOK(ParentStream->Seek(_virtPos, STREAM_SEEK_SET, NULL)); - res = ParentStream->Read(data, size, &size); - } - else - memset(data, 0, size); - } - else - { - UInt64 newPos = (UInt64)blockSectIndex << kSectorSize_Log; - if (BitMapTag != blockIndex) - { - RINOK(ReadPhy(newPos, BitMap, (UInt32)BitMap.Size())); - BitMapTag = blockIndex; - } - RINOK(ReadPhy(newPos + BitMap.Size() + offsetInBlock, data, size)); - for (UInt32 cur = 0; cur < size;) - { - const UInt32 rem = MyMin(0x200 - (offsetInBlock & 0x1FF), size - cur); - UInt32 bmi = offsetInBlock >> kSectorSize_Log; - if (((BitMap[bmi >> 3] >> (7 - (bmi & 7))) & 1) == 0) - { - if (ParentStream) - { - RINOK(ParentStream->Seek(_virtPos + cur, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(ParentStream, (Byte *)data + cur, rem)); - } - else - { - const Byte *p = (const Byte *)data + cur; - for (UInt32 i = 0; i < rem; i++) - if (p[i] != 0) - return S_FALSE; - } - } - offsetInBlock += rem; - cur += rem; - } - } - if (processedSize) - *processedSize = size; - _virtPos += size; - return res; -} - - -enum -{ - kpidParent = kpidUserDefined, - kpidSavedState -}; - -static const CStatProp kArcProps[] = -{ - { NULL, kpidSize, VT_UI8}, - { NULL, kpidOffset, VT_UI8}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidClusterSize, VT_UI8}, - { NULL, kpidMethod, VT_BSTR}, - { "Parent", kpidParent, VT_BSTR}, - { NULL, kpidCreatorApp, VT_BSTR}, - { NULL, kpidHostOS, VT_BSTR}, - { "Saved State", kpidSavedState, VT_BOOL}, - { NULL, kpidId, VT_BSTR} - }; - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize, - kpidCTime - - /* - { kpidNumCyls, VT_UI4}, - { kpidNumHeads, VT_UI4}, - { kpidSectorsPerTrack, VT_UI4} - */ -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -// VHD start time: 2000-01-01 -static const UInt64 kVhdTimeStartValue = (UInt64)3600 * 24 * (399 * 365 + 24 * 4); - -static void VhdTimeToFileTime(UInt32 vhdTime, NCOM::CPropVariant &prop) -{ - FILETIME ft, utc; - UInt64 v = (kVhdTimeStartValue + vhdTime) * 10000000; - ft.dwLowDateTime = (DWORD)v; - ft.dwHighDateTime = (DWORD)(v >> 32); - // specification says that it's UTC time, but Virtual PC 6 writes local time. Why? - LocalFileTimeToFileTime(&ft, &utc); - prop = utc; -} - -static void StringToAString(char *dest, UInt32 val) -{ - for (int i = 24; i >= 0; i -= 8) - { - Byte b = (Byte)((val >> i) & 0xFF); - if (b < 0x20 || b > 0x7F) - break; - *dest++ = b; - } - *dest = 0; -} - -static void ConvertByteToHex(unsigned value, char *s) -{ - for (int i = 0; i < 2; i++) - { - unsigned t = value & 0xF; - value >>= 4; - s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidMainSubfile: prop = (UInt32)0; break; - case kpidCTime: VhdTimeToFileTime(Footer.CTime, prop); break; - case kpidClusterSize: if (Footer.ThereIsDynamic()) prop = (UInt32)1 << Dyn.BlockSizeLog; break; - case kpidShortComment: - case kpidMethod: - { - AString s = Footer.GetTypeString(); - if (NeedParent()) - { - s += " -> "; - const CHandler *p = this; - while (p && p->NeedParent()) - p = p->Parent; - if (!p) - s += '?'; - else - s += p->Footer.GetTypeString(); - } - prop = s; - break; - } - case kpidCreatorApp: - { - char s[16]; - StringToAString(s, Footer.CreatorApp); - AString res = s; - res.Trim(); - ConvertUInt32ToString(Footer.CreatorVersion >> 16, s); - res.Add_Space(); - res += s; - res += '.'; - ConvertUInt32ToString(Footer.CreatorVersion & 0xFFFF, s); - res += s; - prop = res; - break; - } - case kpidHostOS: - { - if (Footer.CreatorHostOS == 0x5769326B) - prop = "Windows"; - else - { - char s[16]; - StringToAString(s, Footer.CreatorHostOS); - prop = s; - } - break; - } - case kpidId: - { - char s[32 + 4]; - for (int i = 0; i < 16; i++) - ConvertByteToHex(Footer.Id[i], s + i * 2); - s[32] = 0; - prop = s; - break; - } - case kpidSavedState: prop = Footer.SavedState ? true : false; break; - case kpidParent: if (NeedParent()) prop = GetParentSequence(); break; - case kpidOffset: prop = _startOffset; break; - case kpidPhySize: prop = _phySize; break; - /* - case kpidErrorFlags: - { - UInt32 flags = 0; - if (_unexpectedEnd) - flags |= kpv_ErrorFlags_UnexpectedEndOfArc; - if (flags != 0) - prop = flags; - break; - } - */ - case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level) -{ - Close(); - Stream = stream; - if (level > (1 << 12)) // Maybe we need to increase that limit - return S_FALSE; - - RINOK(Open3()); - - if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0) - return S_FALSE; - if (Footer.Type != kDiskType_Diff) - return S_OK; - - bool useRelative; - UString name; - - if (!Dyn.RelativeParentNameFromLocator.IsEmpty()) - { - useRelative = true; - name = Dyn.RelativeParentNameFromLocator; - } - else - { - useRelative = false; - name = Dyn.ParentName; - } - - Dyn.RelativeNameWasUsed = useRelative; - - CMyComPtr openVolumeCallback; - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - - if (openVolumeCallback) - { - CMyComPtr nextStream; - HRESULT res = openVolumeCallback->GetStream(name, &nextStream); - - if (res == S_FALSE) - { - if (useRelative && Dyn.ParentName != Dyn.RelativeParentNameFromLocator) - { - res = openVolumeCallback->GetStream(Dyn.ParentName, &nextStream); - if (res == S_OK) - Dyn.RelativeNameWasUsed = false; - } - } - - if (res != S_OK && res != S_FALSE) - return res; - - if (res == S_FALSE || !nextStream) - { - UString s; - s.SetFromAscii("Missing volume : "); - s += name; - AddErrorMessage(s); - return S_OK; - } - - Parent = new CHandler; - ParentStream = Parent; - - res = Parent->Open2(nextStream, this, openArchiveCallback, level + 1); - - if (res != S_OK) - { - Parent = NULL; - ParentStream.Release(); - if (res == E_ABORT) - return res; - if (res != S_FALSE) - { - // we must show that error code - } - } - } - { - const CHandler *p = this; - while (p->NeedParent()) - { - p = p->Parent; - if (!p) - { - AddErrorMessage(L"Can't open parent VHD file:"); - AddErrorMessage(Dyn.ParentName); - break; - } - } - } - return S_OK; -} - - -void CHandler::CloseAtError() -{ - _phySize = 0; - Bat.Clear(); - NumUsedBlocks = 0; - Parent = NULL; - Stream.Release(); - ParentStream.Release(); - Dyn.Clear(); - _errorMessage.Empty(); - // _unexpectedEnd = false; - _imgExt = NULL; -} - -STDMETHODIMP CHandler::Close() -{ - CloseAtError(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - switch (propID) - { - case kpidSize: prop = Footer.CurrentSize; break; - case kpidPackSize: prop = GetPackSize(); break; - case kpidCTime: VhdTimeToFileTime(Footer.CTime, prop); break; - case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; - - /* - case kpidNumCyls: prop = Footer.NumCyls(); break; - case kpidNumHeads: prop = Footer.NumHeads(); break; - case kpidSectorsPerTrack: prop = Footer.NumSectorsPerTrack(); break; - */ - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - if (Footer.IsFixed()) - { - CLimitedInStream *streamSpec = new CLimitedInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->SetStream(Stream); - streamSpec->InitAndSeek(0, Footer.CurrentSize); - RINOK(streamSpec->SeekToStart()); - *stream = streamTemp.Detach(); - return S_OK; - } - if (!Footer.ThereIsDynamic() || !AreParentsOK()) - return S_FALSE; - CMyComPtr streamTemp = this; - RINOK(InitAndSeek()); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -REGISTER_ARC_I( - "VHD", "vhd", NULL, 0xDC, - kSignature, - 0, - NArcInfoFlags::kUseGlobalOffset, - NULL) - -}} +// VhdHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) + +using namespace NWindows; + +namespace NArchive { +namespace NVhd { + +static const unsigned kSignatureSize = 10; +static const Byte kSignature[kSignatureSize] = + { 'c', 'o', 'n', 'e', 'c', 't', 'i', 'x', 0, 0 }; + +static const UInt32 kUnusedBlock = 0xFFFFFFFF; + +static const UInt32 kDiskType_Fixed = 2; +static const UInt32 kDiskType_Dynamic = 3; +static const UInt32 kDiskType_Diff = 4; + +static const char * const kDiskTypes[] = +{ + "0" + , "1" + , "Fixed" + , "Dynamic" + , "Differencing" +}; + +struct CFooter +{ + // UInt32 Features; + // UInt32 FormatVersion; + UInt64 DataOffset; + UInt32 CTime; + UInt32 CreatorApp; + UInt32 CreatorVersion; + UInt32 CreatorHostOS; + // UInt64 OriginalSize; + UInt64 CurrentSize; + UInt32 DiskGeometry; + UInt32 Type; + Byte Id[16]; + Byte SavedState; + + bool IsFixed() const { return Type == kDiskType_Fixed; } + bool ThereIsDynamic() const { return Type == kDiskType_Dynamic || Type == kDiskType_Diff; } + // bool IsSupported() const { return Type == kDiskType_Fixed || Type == kDiskType_Dynamic || Type == kDiskType_Diff; } + UInt32 NumCyls() const { return DiskGeometry >> 16; } + UInt32 NumHeads() const { return (DiskGeometry >> 8) & 0xFF; } + UInt32 NumSectorsPerTrack() const { return DiskGeometry & 0xFF; } + void AddTypeString(AString &s) const; + bool Parse(const Byte *p); +}; + +void CFooter::AddTypeString(AString &s) const +{ + if (Type < Z7_ARRAY_SIZE(kDiskTypes)) + s += kDiskTypes[Type]; + else + s.Add_UInt32(Type); +} + +static bool CheckBlock(const Byte *p, unsigned size, unsigned checkSumOffset, unsigned zeroOffset) +{ + UInt32 sum = 0; + unsigned i; + for (i = 0; i < checkSumOffset; i++) + sum += p[i]; + for (i = checkSumOffset + 4; i < size; i++) + sum += p[i]; + if (~sum != Get32(p + checkSumOffset)) + return false; + for (i = zeroOffset; i < size; i++) + if (p[i] != 0) + return false; + return true; +} + +static const unsigned kSectorSize_Log = 9; +static const unsigned kSectorSize = 1 << kSectorSize_Log; +static const unsigned kHeaderSize = 512; + +bool CFooter::Parse(const Byte *p) +{ + if (memcmp(p, kSignature, kSignatureSize) != 0) + return false; + // G32(0x08, Features); + // G32(0x0C, FormatVersion); + G64(0x10, DataOffset); + G32(0x18, CTime); + G32(0x1C, CreatorApp); + G32(0x20, CreatorVersion); + G32(0x24, CreatorHostOS); + // G64(0x28, OriginalSize); + G64(0x30, CurrentSize); + G32(0x38, DiskGeometry); + G32(0x3C, Type); + if (Type < kDiskType_Fixed || + Type > kDiskType_Diff) + return false; + memcpy(Id, p + 0x44, 16); + SavedState = p[0x54]; + // if (DataOffset > ((UInt64)1 << 62)) return false; + // if (CurrentSize > ((UInt64)1 << 62)) return false; + return CheckBlock(p, kHeaderSize, 0x40, 0x55); +} + +struct CParentLocatorEntry +{ + UInt32 Code; + UInt32 DataSpace; + UInt32 DataLen; + UInt64 DataOffset; + + bool Parse(const Byte *p) + { + G32(0x00, Code); + G32(0x04, DataSpace); + G32(0x08, DataLen); + G64(0x10, DataOffset); + return Get32(p + 0x0C) == 0; // Reserved + } +}; + +struct CDynHeader +{ + // UInt64 DataOffset; + UInt64 TableOffset; + // UInt32 HeaderVersion; + UInt32 NumBlocks; + unsigned BlockSizeLog; + UInt32 ParentTime; + Byte ParentId[16]; + bool RelativeNameWasUsed; + UString ParentName; + UString RelativeParentNameFromLocator; + CParentLocatorEntry ParentLocators[8]; + + bool Parse(const Byte *p); + UInt32 NumBitMapSectors() const + { + UInt32 numSectorsInBlock = (1 << (BlockSizeLog - kSectorSize_Log)); + return (numSectorsInBlock + kSectorSize * 8 - 1) / (kSectorSize * 8); + } + void Clear() + { + RelativeNameWasUsed = false; + ParentName.Empty(); + RelativeParentNameFromLocator.Empty(); + } +}; + +bool CDynHeader::Parse(const Byte *p) +{ + if (memcmp(p, "cxsparse", 8) != 0) + return false; + // G64(0x08, DataOffset); + G64(0x10, TableOffset); + // G32(0x18, HeaderVersion); + G32(0x1C, NumBlocks); + { + UInt32 blockSize = Get32(p + 0x20); + unsigned i; + for (i = kSectorSize_Log;; i++) + { + if (i > 31) + return false; + if (((UInt32)1 << i) == blockSize) + break; + } + BlockSizeLog = i; + } + G32(0x38, ParentTime); + if (Get32(p + 0x3C) != 0) // reserved + return false; + memcpy(ParentId, p + 0x28, 16); + { + const unsigned kNameLen = 256; + wchar_t *s = ParentName.GetBuf(kNameLen); + unsigned i; + for (i = 0; i < kNameLen; i++) + { + wchar_t c = Get16(p + 0x40 + i * 2); + if (c == 0) + break; + s[i] = c; + } + s[i] = 0; + ParentName.ReleaseBuf_SetLen(i); + } + for (unsigned i = 0; i < 8; i++) + if (!ParentLocators[i].Parse(p + 0x240 + i * 24)) + return false; + return CheckBlock(p, 1024, 0x24, 0x240 + 8 * 24); +} + +Z7_class_CHandler_final: public CHandlerImg +{ + UInt64 _posInArcLimit; + UInt64 _startOffset; + UInt64 _phySize; + + CFooter Footer; + CDynHeader Dyn; + CRecordVector Bat; + CByteBuffer BitMap; + UInt32 BitMapTag; + UInt32 NumUsedBlocks; + CMyComPtr ParentStream; + CHandler *Parent; + UInt64 NumLevels; + UString _errorMessage; + // bool _unexpectedEnd; + + void AddErrorMessage(const char *message, const wchar_t *name = NULL) + { + if (!_errorMessage.IsEmpty()) + _errorMessage.Add_LF(); + _errorMessage += message; + if (name) + _errorMessage += name; + } + + void UpdatePhySize(UInt64 value) + { + if (_phySize < value) + _phySize = value; + } + + HRESULT Seek2(UInt64 offset); + HRESULT InitAndSeek(); + HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size); + + bool NeedParent() const { return Footer.Type == kDiskType_Diff; } + UInt64 GetPackSize() const + { return Footer.ThereIsDynamic() ? ((UInt64)NumUsedBlocks << Dyn.BlockSizeLog) : Footer.CurrentSize; } + + UString GetParentSequence() const + { + const CHandler *p = this; + UString res; + while (p && p->NeedParent()) + { + if (!res.IsEmpty()) + res += " -> "; + UString mainName; + UString anotherName; + if (Dyn.RelativeNameWasUsed) + { + mainName = p->Dyn.RelativeParentNameFromLocator; + anotherName = p->Dyn.ParentName; + } + else + { + mainName = p->Dyn.ParentName; + anotherName = p->Dyn.RelativeParentNameFromLocator; + } + res += mainName; + if (mainName != anotherName && !anotherName.IsEmpty()) + { + res.Add_Space(); + res.Add_Char('('); + res += anotherName; + res.Add_Char(')'); + } + p = p->Parent; + } + return res; + } + + bool AreParentsOK() const + { + const CHandler *p = this; + while (p->NeedParent()) + { + p = p->Parent; + if (!p) + return false; + } + return true; + } + + HRESULT Open3(); + HRESULT Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) Z7_override + { + return Open2(stream, NULL, openArchiveCallback, 0); + } + void CloseAtError() Z7_override; + +public: + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) +}; + +HRESULT CHandler::Seek2(UInt64 offset) { return InStream_SeekSet(Stream, _startOffset + offset); } + +HRESULT CHandler::InitAndSeek() +{ + if (ParentStream) + { + RINOK(Parent->InitAndSeek()) + } + _virtPos = _posInArc = 0; + BitMapTag = kUnusedBlock; + BitMap.Alloc(Dyn.NumBitMapSectors() << kSectorSize_Log); + return Seek2(0); +} + +HRESULT CHandler::ReadPhy(UInt64 offset, void *data, UInt32 size) +{ + if (offset + size > _posInArcLimit) + return S_FALSE; + if (offset != _posInArc) + { + _posInArc = offset; + RINOK(Seek2(offset)) + } + HRESULT res = ReadStream_FALSE(Stream, data, size); + if (res == S_OK) + _posInArc += size; + else + Reset_PosInArc(); + return res; +} + +HRESULT CHandler::Open3() +{ + // Fixed archive uses only footer + + UInt64 startPos; + RINOK(InStream_GetPos(Stream, startPos)) + _startOffset = startPos; + Byte header[kHeaderSize]; + RINOK(ReadStream_FALSE(Stream, header, kHeaderSize)) + bool headerIsOK = Footer.Parse(header); + _size = Footer.CurrentSize; + + if (headerIsOK && !Footer.ThereIsDynamic()) + { + // fixed archive + if (startPos < Footer.CurrentSize) + return S_FALSE; + _posInArcLimit = Footer.CurrentSize; + _phySize = Footer.CurrentSize + kHeaderSize; + _startOffset = startPos - Footer.CurrentSize; + _posInArc = _phySize; + return S_OK; + } + + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(Stream, fileSize)) + if (fileSize < kHeaderSize) + return S_FALSE; + + const UInt32 kDynSize = 1024; + Byte buf[kDynSize]; + + RINOK(InStream_SeekSet(Stream, fileSize - kHeaderSize)) + RINOK(ReadStream_FALSE(Stream, buf, kHeaderSize)) + + if (!headerIsOK) + { + if (!Footer.Parse(buf)) + return S_FALSE; + _size = Footer.CurrentSize; + if (Footer.ThereIsDynamic()) + return S_FALSE; // we can't open Dynamic Archive backward. + // fixed archive + _posInArcLimit = Footer.CurrentSize; + _phySize = Footer.CurrentSize + kHeaderSize; + _startOffset = fileSize - kHeaderSize - Footer.CurrentSize; + _posInArc = _phySize; + return S_OK; + } + + _phySize = kHeaderSize; + _posInArc = fileSize - startPos; + _posInArcLimit = _posInArc - kHeaderSize; + + bool headerAndFooterAreEqual = false; + if (memcmp(header, buf, kHeaderSize) == 0) + { + headerAndFooterAreEqual = true; + _phySize = fileSize - _startOffset; + } + + RINOK(ReadPhy(Footer.DataOffset, buf, kDynSize)) + if (!Dyn.Parse(buf)) + return S_FALSE; + + UpdatePhySize(Footer.DataOffset + kDynSize); + + for (int i = 0; i < 8; i++) + { + const CParentLocatorEntry &locator = Dyn.ParentLocators[i]; + const UInt32 kNameBufSizeMax = 1024; + if (locator.DataLen < kNameBufSizeMax && + locator.DataOffset < _posInArcLimit && + locator.DataOffset + locator.DataLen <= _posInArcLimit) + { + if (locator.Code == 0x57327275 && (locator.DataLen & 1) == 0) + { + // "W2ru" locator + // Path is encoded as little-endian UTF-16 + Byte nameBuf[kNameBufSizeMax]; + UString tempString; + unsigned len = (locator.DataLen >> 1); + { + wchar_t *s = tempString.GetBuf(len); + RINOK(ReadPhy(locator.DataOffset, nameBuf, locator.DataLen)) + unsigned j; + for (j = 0; j < len; j++) + { + wchar_t c = GetUi16(nameBuf + j * 2); + if (c == 0) + break; + s[j] = c; + } + s[j] = 0; + tempString.ReleaseBuf_SetLen(j); + } + if (tempString[0] == L'.' && tempString[1] == L'\\') + tempString.DeleteFrontal(2); + Dyn.RelativeParentNameFromLocator = tempString; + } + } + if (locator.DataLen != 0) + UpdatePhySize(locator.DataOffset + locator.DataLen); + } + + if (Dyn.NumBlocks >= (UInt32)1 << 31) + return S_FALSE; + if (Footer.CurrentSize == 0) + { + if (Dyn.NumBlocks != 0) + return S_FALSE; + } + else if (((Footer.CurrentSize - 1) >> Dyn.BlockSizeLog) + 1 != Dyn.NumBlocks) + return S_FALSE; + + Bat.ClearAndReserve(Dyn.NumBlocks); + + UInt32 bitmapSize = Dyn.NumBitMapSectors() << kSectorSize_Log; + + while ((UInt32)Bat.Size() < Dyn.NumBlocks) + { + RINOK(ReadPhy(Dyn.TableOffset + (UInt64)Bat.Size() * 4, buf, kSectorSize)) + UpdatePhySize(Dyn.TableOffset + kSectorSize); + for (UInt32 j = 0; j < kSectorSize; j += 4) + { + UInt32 v = Get32(buf + j); + if (v != kUnusedBlock) + { + UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; + UpdatePhySize(((UInt64)v << kSectorSize_Log) + bitmapSize + blockSize); + NumUsedBlocks++; + } + Bat.AddInReserved(v); + if ((UInt32)Bat.Size() >= Dyn.NumBlocks) + break; + } + } + + if (headerAndFooterAreEqual) + return S_OK; + + if (_startOffset + _phySize + kHeaderSize > fileSize) + { + // _unexpectedEnd = true; + _posInArcLimit = _phySize; + _phySize += kHeaderSize; + return S_OK; + } + + RINOK(ReadPhy(_phySize, buf, kHeaderSize)) + if (memcmp(header, buf, kHeaderSize) == 0) + { + _posInArcLimit = _phySize; + _phySize += kHeaderSize; + return S_OK; + } + + if (_phySize == 0x800) + { + /* WHY does empty archive contain additional empty sector? + We skip that sector and check footer again. */ + unsigned i; + for (i = 0; i < kSectorSize && buf[i] == 0; i++); + if (i == kSectorSize) + { + RINOK(ReadPhy(_phySize + kSectorSize, buf, kHeaderSize)) + if (memcmp(header, buf, kHeaderSize) == 0) + { + _phySize += kSectorSize; + _posInArcLimit = _phySize; + _phySize += kHeaderSize; + return S_OK; + } + } + } + _posInArcLimit = _phySize; + _phySize += kHeaderSize; + AddErrorMessage("Can't find footer"); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= Footer.CurrentSize) + return S_OK; + { + const UInt64 rem = Footer.CurrentSize - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + if (Footer.IsFixed()) + { + if (_virtPos > _posInArcLimit) + return S_FALSE; + { + const UInt64 rem = _posInArcLimit - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + HRESULT res = S_OK; + if (_virtPos != _posInArc) + { + _posInArc = _virtPos; + res = Seek2(_virtPos); + } + if (res == S_OK) + { + UInt32 processedSize2 = 0; + res = Stream->Read(data, size, &processedSize2); + if (processedSize) + *processedSize = processedSize2; + _posInArc += processedSize2; + } + if (res != S_OK) + Reset_PosInArc(); + return res; + } + + const UInt32 blockIndex = (UInt32)(_virtPos >> Dyn.BlockSizeLog); + if (blockIndex >= Bat.Size()) + return E_FAIL; // it's some unexpected case + const UInt32 blockSectIndex = Bat[blockIndex]; + const UInt32 blockSize = (UInt32)1 << Dyn.BlockSizeLog; + UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + size = MyMin(blockSize - offsetInBlock, size); + + HRESULT res = S_OK; + if (blockSectIndex == kUnusedBlock) + { + if (ParentStream) + { + RINOK(InStream_SeekSet(ParentStream, _virtPos)) + res = ParentStream->Read(data, size, &size); + } + else + memset(data, 0, size); + } + else + { + const UInt64 newPos = (UInt64)blockSectIndex << kSectorSize_Log; + if (BitMapTag != blockIndex) + { + RINOK(ReadPhy(newPos, BitMap, (UInt32)BitMap.Size())) + BitMapTag = blockIndex; + } + RINOK(ReadPhy(newPos + BitMap.Size() + offsetInBlock, data, size)) + for (UInt32 cur = 0; cur < size;) + { + const UInt32 rem = MyMin(0x200 - (offsetInBlock & 0x1FF), size - cur); + const UInt32 bmi = offsetInBlock >> kSectorSize_Log; + if (((BitMap[bmi >> 3] >> (7 - (bmi & 7))) & 1) == 0) + { + if (ParentStream) + { + RINOK(InStream_SeekSet(ParentStream, _virtPos + cur)) + RINOK(ReadStream_FALSE(ParentStream, (Byte *)data + cur, rem)) + } + else + { + const Byte *p = (const Byte *)data + cur; + for (UInt32 i = 0; i < rem; i++) + if (p[i] != 0) + return S_FALSE; + } + } + offsetInBlock += rem; + cur += rem; + } + } + if (processedSize) + *processedSize = size; + _virtPos += size; + return res; +} + + +enum +{ + kpidParent = kpidUserDefined, + kpidSavedState +}; + +static const CStatProp kArcProps[] = +{ + { NULL, kpidOffset, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidClusterSize, VT_UI8}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidNumVolumes, VT_UI4}, + { NULL, kpidTotalPhySize, VT_UI8}, + { "Parent", kpidParent, VT_BSTR}, + { NULL, kpidCreatorApp, VT_BSTR}, + { NULL, kpidHostOS, VT_BSTR}, + { "Saved State", kpidSavedState, VT_BOOL}, + { NULL, kpidId, VT_BSTR} + }; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, + kpidCTime + + /* + { kpidNumCyls, VT_UI4}, + { kpidNumHeads, VT_UI4}, + { kpidSectorsPerTrack, VT_UI4} + */ +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +// VHD start time: 2000-01-01 +static const UInt64 kVhdTimeStartValue = (UInt64)3600 * 24 * (399 * 365 + 24 * 4); + +static void VhdTimeToFileTime(UInt32 vhdTime, NCOM::CPropVariant &prop) +{ + FILETIME ft, utc; + UInt64 v = (kVhdTimeStartValue + vhdTime) * 10000000; + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); + // specification says that it's UTC time, but Virtual PC 6 writes local time. Why? + LocalFileTimeToFileTime(&ft, &utc); + prop = utc; +} + +static void StringToAString(char *dest, UInt32 val) +{ + for (int i = 24; i >= 0; i -= 8) + { + const Byte b = (Byte)((val >> i) & 0xFF); + if (b < 0x20 || b > 0x7F) + break; + *dest++ = (char)b; + } + *dest = 0; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidCTime: VhdTimeToFileTime(Footer.CTime, prop); break; + case kpidClusterSize: if (Footer.ThereIsDynamic()) prop = (UInt32)1 << Dyn.BlockSizeLog; break; + case kpidShortComment: + case kpidMethod: + { + AString s; + Footer.AddTypeString(s); + if (NeedParent()) + { + s += " -> "; + const CHandler *p = this; + while (p && p->NeedParent()) + p = p->Parent; + if (!p) + s += '?'; + else + p->Footer.AddTypeString(s); + } + prop = s; + break; + } + case kpidCreatorApp: + { + char s[16]; + StringToAString(s, Footer.CreatorApp); + AString res (s); + res.Trim(); + res.Add_Space(); + res.Add_UInt32(Footer.CreatorVersion >> 16); + res.Add_Dot(); + res.Add_UInt32(Footer.CreatorVersion & 0xFFFF); + prop = res; + break; + } + case kpidHostOS: + { + if (Footer.CreatorHostOS == 0x5769326B) + prop = "Windows"; + else + { + char s[16]; + StringToAString(s, Footer.CreatorHostOS); + prop = s; + } + break; + } + case kpidId: + { + char s[sizeof(Footer.Id) * 2 + 2]; + ConvertDataToHex_Upper(s, Footer.Id, sizeof(Footer.Id)); + prop = s; + break; + } + case kpidSavedState: prop = Footer.SavedState ? true : false; break; + case kpidParent: if (NeedParent()) prop = GetParentSequence(); break; + case kpidOffset: prop = _startOffset; break; + case kpidPhySize: prop = _phySize; break; + case kpidTotalPhySize: + { + const CHandler *p = this; + UInt64 sum = 0; + do + { + sum += p->_phySize; + p = p->Parent; + } + while (p); + prop = sum; + break; + } + case kpidNumVolumes: if (NumLevels != 1) prop = (UInt32)NumLevels; break; + + /* + case kpidErrorFlags: + { + UInt32 flags = 0; + if (_unexpectedEnd) + flags |= kpv_ErrorFlags_UnexpectedEndOfArc; + if (flags != 0) + prop = flags; + break; + } + */ + case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback *openArchiveCallback, unsigned level) +{ + Close(); + Stream = stream; + if (level > (1 << 12)) // Maybe we need to increase that limit + return S_FALSE; + + RINOK(Open3()) + + NumLevels = 1; + if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0) + return S_FALSE; + if (Footer.Type != kDiskType_Diff) + return S_OK; + + bool useRelative; + UString name; + + if (!Dyn.RelativeParentNameFromLocator.IsEmpty()) + { + useRelative = true; + name = Dyn.RelativeParentNameFromLocator; + } + else + { + useRelative = false; + name = Dyn.ParentName; + } + + Dyn.RelativeNameWasUsed = useRelative; + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openArchiveCallback) + + if (openVolumeCallback) + { + CMyComPtr nextStream; + HRESULT res = openVolumeCallback->GetStream(name, &nextStream); + + if (res == S_FALSE) + { + if (useRelative && Dyn.ParentName != Dyn.RelativeParentNameFromLocator) + { + res = openVolumeCallback->GetStream(Dyn.ParentName, &nextStream); + if (res == S_OK) + Dyn.RelativeNameWasUsed = false; + } + } + + if (res != S_OK && res != S_FALSE) + return res; + + if (res == S_FALSE || !nextStream) + { + AddErrorMessage("Missing volume : ", name); + return S_OK; + } + + Parent = new CHandler; + ParentStream = Parent; + + res = Parent->Open2(nextStream, this, openArchiveCallback, level + 1); + + if (res != S_OK) + { + Parent = NULL; + ParentStream.Release(); + if (res == E_ABORT) + return res; + if (res != S_FALSE) + { + // we must show that error code + } + } + if (res == S_OK) + { + NumLevels = Parent->NumLevels + 1; + } + } + { + const CHandler *p = this; + while (p->NeedParent()) + { + p = p->Parent; + if (!p) + { + AddErrorMessage("Can't open parent VHD file : ", Dyn.ParentName); + break; + } + } + } + return S_OK; +} + + +void CHandler::CloseAtError() +{ + // CHandlerImg: + Stream.Release(); + Clear_HandlerImg_Vars(); + + _phySize = 0; + NumLevels = 0; + Bat.Clear(); + NumUsedBlocks = 0; + Parent = NULL; + ParentStream.Release(); + Dyn.Clear(); + _errorMessage.Empty(); + // _unexpectedEnd = false; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + CloseAtError(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidSize: prop = Footer.CurrentSize; break; + case kpidPackSize: prop = GetPackSize(); break; + case kpidCTime: VhdTimeToFileTime(Footer.CTime, prop); break; + case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; + + /* + case kpidNumCyls: prop = Footer.NumCyls(); break; + case kpidNumHeads: prop = Footer.NumHeads(); break; + case kpidSectorsPerTrack: prop = Footer.NumSectorsPerTrack(); break; + */ + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + if (Footer.IsFixed()) + { + CMyComPtr2 streamSpec; + streamSpec.Create_if_Empty(); + streamSpec->SetStream(Stream); + // fixme : check (startOffset = 0) + streamSpec->InitAndSeek(_startOffset, Footer.CurrentSize); + RINOK(streamSpec->SeekToStart()) + *stream = streamSpec.Detach(); + return S_OK; + } + if (!Footer.ThereIsDynamic() || !AreParentsOK()) + return S_FALSE; + CMyComPtr streamTemp = this; + RINOK(InitAndSeek()) + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "VHD", "vhd", NULL, 0xDC, + kSignature, + 0, + NArcInfoFlags::kUseGlobalOffset, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/VhdxHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdxHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/VhdxHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VhdxHandler.cpp 2023-12-11 17:00:00.000000000 +0000 @@ -0,0 +1,2083 @@ +// VhdxHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringToInt.h" +#include "../../Common/MyBuffer.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "HandlerCont.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define G32(_offs_, dest) dest = Get32(p + (_offs_)) +#define G64(_offs_, dest) dest = Get64(p + (_offs_)) + +using namespace NWindows; + + +EXTERN_C_BEGIN + +// CRC-32C (Castagnoli) : reversed for poly 0x1EDC6F41 +#define k_Crc32c_Poly 0x82f63b78 + +MY_ALIGN(64) +static UInt32 g_Crc32c_Table[256]; + +static void Z7_FASTCALL Crc32c_GenerateTable() +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (k_Crc32c_Poly & ((UInt32)0 - (r & 1))); + g_Crc32c_Table[i] = r; + } +} + + +#define CRC32C_INIT_VAL 0xFFFFFFFF + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +// UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); +static UInt32 Z7_FASTCALL CrcUpdateT1_vhdx(UInt32 v, const void *data, size_t size, const UInt32 *table) +{ + const Byte *p = (const Byte *)data; + const Byte *pEnd = p + size; + for (; p != pEnd; p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +static UInt32 Z7_FASTCALL Crc32c_Calc(const void *data, size_t size) +{ + return CrcUpdateT1_vhdx(CRC32C_INIT_VAL, data, size, g_Crc32c_Table) ^ CRC32C_INIT_VAL; +} + +EXTERN_C_END + + +namespace NArchive { +namespace NVhdx { + +static struct C_CRC32c_TableInit { C_CRC32c_TableInit() { Crc32c_GenerateTable(); } } g_CRC32c_TableInit; + +static const unsigned kSignatureSize = 8; +static const Byte kSignature[kSignatureSize] = + { 'v', 'h', 'd', 'x', 'f', 'i', 'l', 'e' }; + +static const unsigned kBitmapSize_Log = 20; +static const size_t kBitmapSize = (size_t)1 << kBitmapSize_Log; + + +static bool IsZeroArr(const Byte *p, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p[i] != 0) + return false; + return true; +} + + + +Z7_FORCE_INLINE +static int DecodeFrom2HexChars(const wchar_t *s) +{ + unsigned v0 = (unsigned)s[0]; Z7_PARSE_HEX_DIGIT(v0, return -1;) + unsigned v1 = (unsigned)s[1]; Z7_PARSE_HEX_DIGIT(v1, return -1;) + return (int)((v0 << 4) | v1); +} + + +struct CGuid +{ + Byte Data[16]; + + bool IsZero() const { return IsZeroArr(Data, 16); } + bool IsEqualTo(const Byte *a) const { return memcmp(Data, a, 16) == 0; } + bool IsEqualTo(const CGuid &g) const { return IsEqualTo(g.Data); } + void AddHexToString(UString &s) const; + + void SetFrom(const Byte *p) { memcpy(Data, p, 16); } + + bool ParseFromFormatedHexString(const UString &s) + { + const unsigned kLen = 16 * 2 + 4 + 2; + if (s.Len() != kLen || s[0] != '{' || s[kLen - 1] != '}') + return false; + unsigned pos = 0; + for (unsigned i = 1; i < kLen - 1;) + { + if (i == 9 || i == 14 || i == 19 || i == 24) + { + if (s[i] != '-') + return false; + i++; + continue; + } + const int v = DecodeFrom2HexChars(s.Ptr(i)); + if (v < 0) + return false; + unsigned pos2 = pos; + if (pos < 8) + pos2 ^= (pos < 4 ? 3 : 1); + Data[pos2] = (Byte)v; + pos++; + i += 2; + } + return true; // pos == 16; + } +}; + +void CGuid::AddHexToString(UString &s) const +{ + char temp[sizeof(Data) * 2 + 2]; + ConvertDataToHex_Lower(temp, Data, sizeof(Data)); + s += temp; +} + + +#define IS_NON_ALIGNED(v) (((v) & 0xFFFFF) != 0) + +static const unsigned kHeader_GUID_Index_FileWriteGuid = 0; +static const unsigned kHeader_GUID_Index_DataWriteGuid = 1; +static const unsigned kHeader_GUID_Index_LogGuid = 2; + +struct CHeader +{ + UInt64 SequenceNumber; + // UInt16 LogVersion; + // UInt16 Version; + UInt32 LogLength; + 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); +}; + +static const unsigned kHeader2Size = 1 << 12; + +bool CHeader::Parse(Byte *p) +{ + if (Get32(p) != 0x64616568) // "head" + return false; + const UInt32 crc = Get32(p + 4); + SetUi32(p + 4, 0) + if (Crc32c_Calc(p, kHeader2Size) != crc) + return false; + G64(8, SequenceNumber); + for (unsigned i = 0; i < 3; i++) + Guids[i].SetFrom(p + 0x10 + 0x10 * i); + // LogVersion = Get16(p + 0x40); + /* LogVersion MUST be set to zero, for known log format + but we don't parse log so we ignore it */ + G32(0x44, LogLength); + G64(0x48, LogOffset); + if (Get16(p + 0x42) != 1) // Header format Version + return false; + if (IS_NON_ALIGNED(LogLength)) + return false; + if (IS_NON_ALIGNED(LogOffset)) + return false; + return true; + // return IsZeroArr(p + 0x50, kHeader2Size - 0x50); +} + + + +static const Byte kBat[16] = + { 0x66,0x77,0xC2,0x2D,0x23,0xF6,0x00,0x42,0x9D,0x64,0x11,0x5E,0x9B,0xFD,0x4A,0x08 }; +static const Byte kMetadataRegion[16] = + { 0x06,0xA2,0x7C,0x8B,0x90,0x47,0x9A,0x4B,0xB8,0xFE,0x57,0x5F,0x05,0x0F,0x88,0x6E }; + +struct CRegionEntry +{ + // CGuid Guid; + UInt64 Offset; + UInt32 Len; + UInt32 Required; + + UInt64 GetEndPos() const { return Offset + Len; } + bool Parse(const Byte *p); +}; + +bool CRegionEntry::Parse(const Byte *p) +{ + // Guid.SetFrom(p); + G64(0x10, Offset); + G32(0x18, Len); + G32(0x1c, Required); + if (IS_NON_ALIGNED(Offset)) + return false; + if (IS_NON_ALIGNED(Len)) + return false; + if (Offset + Len < Offset) + return false; + return true; +} + + +struct CRegion +{ + bool Bat_Defined; + bool Meta_Defined; + UInt64 EndPos; + UInt64 DataSize; + + CRegionEntry BatEntry; + CRegionEntry MetaEntry; + + bool Parse(Byte *p); +}; + + +static const size_t kRegionSize = 1 << 16; +static const unsigned kNumRegionEntriesMax = (1 << 11) - 1; + +bool CRegion::Parse(Byte *p) +{ + Bat_Defined = false; + Meta_Defined = false; + EndPos = 0; + DataSize = 0; + + if (Get32(p) != 0x69676572) // "regi" + return false; + const UInt32 crc = Get32(p + 4); + SetUi32(p + 4, 0) + const UInt32 crc_calced = Crc32c_Calc(p, kRegionSize); + if (crc_calced != crc) + return false; + + const UInt32 EntryCount = Get32(p + 8); + if (Get32(p + 12) != 0) // reserved field must be set to 0. + return false; + if (EntryCount > kNumRegionEntriesMax) + return false; + for (UInt32 i = 0; i < EntryCount; i++) + { + CRegionEntry e; + const Byte *p2 = p + 0x10 + 0x20 * (size_t)i; + if (!e.Parse(p2)) + return false; + DataSize += e.Len; + const UInt64 endPos = e.GetEndPos(); + if (EndPos < endPos) + EndPos = endPos; + CGuid Guid; + Guid.SetFrom(p2); + if (Guid.IsEqualTo(kBat)) + { + if (Bat_Defined) + return false; + BatEntry = e; + Bat_Defined = true; + } + else if (Guid.IsEqualTo(kMetadataRegion)) + { + if (Meta_Defined) + return false; + MetaEntry = e; + Meta_Defined = true; + } + else + { + if (e.Required != 0) + return false; + // it's allowed to ignore unknown non-required region entries + } + } + /* + const size_t k = 0x10 + 0x20 * EntryCount; + return IsZeroArr(p + k, kRegionSize - k); + */ + return true; +} + + + + +struct CMetaEntry +{ + CGuid Guid; + UInt32 Offset; + UInt32 Len; + UInt32 Flags0; + // UInt32 Flags1; + + bool IsUser() const { return (Flags0 & 1) != 0; } + bool IsVirtualDisk() const { return (Flags0 & 2) != 0; } + bool IsRequired() const { return (Flags0 & 4) != 0; } + + bool CheckLimit(size_t regionSize) const + { + return Offset <= regionSize && Len <= regionSize - Offset; + } + + bool Parse(const Byte *p); +}; + + +bool CMetaEntry::Parse(const Byte *p) +{ + Guid.SetFrom(p); + + G32(0x10, Offset); + G32(0x14, Len); + G32(0x18, Flags0); + UInt32 Flags1; + G32(0x1C, Flags1); + + if (Offset != 0 && Offset < (1 << 16)) + return false; + if (Len > (1 << 20)) + return false; + if (Len == 0 && Offset != 0) + return false; + if ((Flags0 >> 3) != 0) // Reserved + return false; + if ((Flags1 & 3) != 0) // Reserved2 + return false; + return true; +} + + +struct CParentPair +{ + UString Key; + UString Value; +}; + + +struct CMetaHeader +{ + // UInt16 EntryCount; + bool Guid_Defined; + bool VirtualDiskSize_Defined; + bool Locator_Defined; + + unsigned BlockSize_Log; + unsigned LogicalSectorSize_Log; + unsigned PhysicalSectorSize_Log; + + UInt32 Flags; + UInt64 VirtualDiskSize; + CGuid Guid; + // CGuid LocatorType; + + CObjectVector ParentPairs; + + int FindParentKey(const char *name) const + { + FOR_VECTOR (i, ParentPairs) + { + const CParentPair &pair = ParentPairs[i]; + if (pair.Key.IsEqualTo(name)) + return (int)i; + } + return -1; + } + + bool Is_LeaveBlockAllocated() const { return (Flags & 1) != 0; } + bool Is_HasParent() const { return (Flags & 2) != 0; } + + void Clear() + { + Guid_Defined = false; + VirtualDiskSize_Defined = false; + Locator_Defined = false; + BlockSize_Log = 0; + LogicalSectorSize_Log = 0; + PhysicalSectorSize_Log = 0; + Flags = 0; + VirtualDiskSize = 0; + ParentPairs.Clear(); + } + + bool Parse(const Byte *p, size_t size); +}; + + +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 kMetadataSize = 8; +static const Byte kMetadata[kMetadataSize] = + { 'm','e','t','a','d','a','t','a' }; + +static const unsigned k_Num_MetaEntries_Max = (1 << 11) - 1; + +static const Byte kFileParameters[16] = + { 0x37,0x67,0xa1,0xca,0x36,0xfa,0x43,0x4d,0xb3,0xb6,0x33,0xf0,0xaa,0x44,0xe7,0x6b }; +static const Byte kVirtualDiskSize[16] = + { 0x24,0x42,0xa5,0x2f,0x1b,0xcd,0x76,0x48,0xb2,0x11,0x5d,0xbe,0xd8,0x3b,0xf4,0xb8 }; +static const Byte kVirtualDiskID[16] = + { 0xab,0x12,0xca,0xbe,0xe6,0xb2,0x23,0x45,0x93,0xef,0xc3,0x09,0xe0,0x00,0xc7,0x46 }; +static const Byte kLogicalSectorSize[16] = + { 0x1d,0xbf,0x41,0x81,0x6f,0xa9,0x09,0x47,0xba,0x47,0xf2,0x33,0xa8,0xfa,0xab,0x5f }; +static const Byte kPhysicalSectorSize[16] = + { 0xc7,0x48,0xa3,0xcd,0x5d,0x44,0x71,0x44,0x9c,0xc9,0xe9,0x88,0x52,0x51,0xc5,0x56 }; +static const Byte kParentLocator[16] = + { 0x2d,0x5f,0xd3,0xa8,0x0b,0xb3,0x4d,0x45,0xab,0xf7,0xd3,0xd8,0x48,0x34,0xab,0x0c }; + +static bool GetString16(UString &s, const Byte *p, size_t size) +{ + s.Empty(); + if (size & 1) + return false; + for (size_t i = 0; i < size; i += 2) + { + const wchar_t c = Get16(p + i); + if (c == 0) + return false; + s += c; + } + return true; +} + + +bool CMetaHeader::Parse(const Byte *p, size_t size) +{ + if (memcmp(p, kMetadata, kMetadataSize) != 0) + return false; + if (Get16(p + 8) != 0) // Reserved + return false; + const UInt32 EntryCount = Get16(p + 10); + if (EntryCount > k_Num_MetaEntries_Max) + return false; + if (!IsZeroArr(p + 12, 20)) // Reserved + return false; + + for (unsigned i = 0; i < EntryCount; i++) + { + CMetaEntry e; + if (!e.Parse(p + 32 + 32 * (size_t)i)) + return false; + if (!e.CheckLimit(size)) + return false; + const Byte *p2 = p + e.Offset; + + if (e.Guid.IsEqualTo(kFileParameters)) + { + if (BlockSize_Log != 0) + return false; + if (e.Len != 8) + return false; + const UInt32 v = Get32(p2); + Flags = Get32(p2 + 4); + BlockSize_Log = GetLogSize(v); + if (BlockSize_Log < 20 || BlockSize_Log > 28) // specification from 1 MB to 256 MB + return false; + if ((Flags >> 2) != 0) // reserved + return false; + } + else if (e.Guid.IsEqualTo(kVirtualDiskSize)) + { + if (VirtualDiskSize_Defined) + return false; + if (e.Len != 8) + return false; + VirtualDiskSize = Get64(p2); + VirtualDiskSize_Defined = true; + } + else if (e.Guid.IsEqualTo(kVirtualDiskID)) + { + if (e.Len != 16) + return false; + Guid.SetFrom(p2); + Guid_Defined = true; + } + else if (e.Guid.IsEqualTo(kLogicalSectorSize)) + { + if (LogicalSectorSize_Log != 0) + return false; + if (e.Len != 4) + return false; + const UInt32 v = Get32(p2); + LogicalSectorSize_Log = GetLogSize(v); + if (LogicalSectorSize_Log != 9 && LogicalSectorSize_Log != 12) + return false; + } + else if (e.Guid.IsEqualTo(kPhysicalSectorSize)) + { + if (PhysicalSectorSize_Log != 0) + return false; + if (e.Len != 4) + return false; + const UInt32 v = Get32(p2); + PhysicalSectorSize_Log = GetLogSize(v); + if (PhysicalSectorSize_Log != 9 && PhysicalSectorSize_Log != 12) + return false; + } + else if (e.Guid.IsEqualTo(kParentLocator)) + { + if (Locator_Defined) + return false; + if (e.Len < 20) + return false; + // LocatorType.SetFrom(p2); + /* Specifies the type of the parent virtual disk. + is different for each type: VHDX, VHD or iSCSI. + only "B04AEFB7-D19E-4A81-B789-25B8E9445913" (for VHDX) is supported now + */ + Locator_Defined = true; + if (Get16(p2 + 16) != 0) // reserved + return false; + const UInt32 KeyValueCount = Get16(p2 + 18); + if (20 + (UInt32)KeyValueCount * 12 > e.Len) + return false; + for (unsigned k = 0; k < KeyValueCount; k++) + { + const Byte *p3 = p2 + 20 + (size_t)k * 12; + const UInt32 KeyOffset = Get32(p3); + const UInt32 ValueOffset = Get32(p3 + 4); + const UInt32 KeyLength = Get16(p3 + 8); + const UInt32 ValueLength = Get16(p3 + 10); + if (KeyOffset > e.Len || KeyLength > e.Len - KeyOffset) + return false; + if (ValueOffset > e.Len || ValueLength > e.Len - ValueOffset) + return false; + CParentPair pair; + if (!GetString16(pair.Key, p2 + KeyOffset, KeyLength)) + return false; + if (!GetString16(pair.Value, p2 + ValueOffset, ValueLength)) + return false; + ParentPairs.Add(pair); + } + } + else + { + if (e.IsRequired()) + return false; + // return false; // unknown metadata; + } + } + + // some properties are required for correct processing + + if (BlockSize_Log == 0) + return false; + if (LogicalSectorSize_Log == 0) + return false; + if (!VirtualDiskSize_Defined) + return false; + if (((UInt32)VirtualDiskSize & ((UInt32)1 << LogicalSectorSize_Log)) != 0) + return false; + + // vhdx specification sets limit for 64 TB. + // do we need to check over same limit ? + const UInt64 kVirtualDiskSize_Max = (UInt64)1 << 46; + if (VirtualDiskSize > kVirtualDiskSize_Max) + return false; + + return true; +} + + + +struct CBat +{ + CByteBuffer Data; + + void Clear() { Data.Free(); } + UInt64 GetItem(size_t n) const + { + return Get64(Data + n * 8); + } +}; + + + +Z7_class_CHandler_final: public CHandlerImg +{ + UInt64 _phySize; + + CBat Bat; + CObjectVector BitMaps; + + unsigned ChunkRatio_Log; + size_t ChunkRatio; + size_t TotalBatEntries; + + CMetaHeader Meta; + CHeader Header; + + UInt32 NumUsedBlocks; + UInt32 NumUsedBitMaps; + UInt64 HeadersSize; + + UInt32 NumLevels; + UInt64 PackSize_Total; + + /* + UInt64 NumUsed_1MB_Blocks; // data and bitmaps + bool NumUsed_1MB_Blocks_Defined; + */ + + CMyComPtr ParentStream; + CHandler *Parent; + UString _errorMessage; + UString _creator; + + bool _nonEmptyLog; + bool _isDataContiguous; + // bool _batOverlap; + + CGuid _parentGuid; + bool _parentGuid_IsDefined; + UStringVector ParentNames; + UString ParentName_Used; + + const CHandler *_child; + unsigned _level; + bool _isCyclic; + bool _isCyclic_or_CyclicParent; + + void AddErrorMessage(const char *message); + void AddErrorMessage(const char *message, const wchar_t *name); + + void UpdatePhySize(UInt64 value) + { + if (_phySize < value) + _phySize = value; + } + + HRESULT Seek2(UInt64 offset); + HRESULT Read_FALSE(Byte *data, size_t size) + { + return ReadStream_FALSE(Stream, data, size); + } + HRESULT ReadToBuf_FALSE(CByteBuffer &buf, size_t size) + { + buf.Alloc(size); + return ReadStream_FALSE(Stream, buf, size); + } + + void InitSeekPositions(); + HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size, UInt32 &processed); + + bool IsDiff() const + { + // here we suppose that only HasParent() flag is mandatory for Diff archive type + return Meta.Is_HasParent(); + // return _parentGuid_IsDefined; + } + + void AddTypeString(AString &s) const + { + if (IsDiff()) + s += "Differencing"; + else + { + if (Meta.Is_LeaveBlockAllocated()) + s += _isDataContiguous ? "fixed" : "fixed-non-cont"; + else + s += "dynamic"; + } + } + + void AddComment(UString &s) const; + + UInt64 GetPackSize() const + { + return (UInt64)NumUsedBlocks << Meta.BlockSize_Log; + } + + UString GetParentSequence() const + { + const CHandler *p = this; + UString res; + while (p && p->IsDiff()) + { + if (!res.IsEmpty()) + res += " -> "; + res += ParentName_Used; + p = p->Parent; + } + return res; + } + + bool AreParentsOK() const + { + if (_isCyclic_or_CyclicParent) + return false; + const CHandler *p = this; + while (p->IsDiff()) + { + p = p->Parent; + if (!p) + return false; + } + return true; + } + + // bool ParseLog(CByteBuffer &log); + bool ParseBat(); + bool CheckBat(); + + HRESULT Open3(); + HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) Z7_override; + HRESULT OpenParent(IArchiveOpenCallback *openArchiveCallback, bool &_parentFileWasOpen); + virtual void CloseAtError() Z7_override; + +public: + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + + CHandler(): + _child(NULL), + _level(0), + _isCyclic(false), + _isCyclic_or_CyclicParent(false) + {} +}; + + +HRESULT CHandler::Seek2(UInt64 offset) +{ + return InStream_SeekSet(Stream, offset); +} + + +void CHandler::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(); + if (ParentStream) + Parent->InitSeekPositions(); +} + + +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; + } + _posInArc = offset; + } + { + size_t size2 = size; + const HRESULT res = ReadStream(Stream, data, &size2); + processed = (UInt32)size2; + _posInArc += size2; + if (res != S_OK) + Reset_PosInArc(); // we don't trust seek_pos in case of reading error + return res; + } +} + + +#define PAYLOAD_BLOCK_NOT_PRESENT 0 +#define PAYLOAD_BLOCK_UNDEFINED 1 +#define PAYLOAD_BLOCK_ZERO 2 +#define PAYLOAD_BLOCK_UNMAPPED 3 +#define PAYLOAD_BLOCK_FULLY_PRESENT 6 +#define PAYLOAD_BLOCK_PARTIALLY_PRESENT 7 + +#define SB_BLOCK_NOT_PRESENT 0 +#define SB_BLOCK_PRESENT 6 + +#define BAT_GET_OFFSET(v) ((v) & ~(UInt64)0xFFFFF) +#define BAT_GET_STATE(v) ((UInt32)(v) & 7) + +/* The log contains only updates to metadata, bat and region tables + The log doesn't contain updates to start header, and 2 headers (first 192 KB of file). + The log is array of 4 KB blocks and each block has 4-byte signature. + So it's possible to scan whole log to find the latest entry sequence (and header for replay). +*/ + +/* +struct CLogEntry +{ + UInt32 EntryLength; + UInt32 Tail; + UInt64 SequenceNumber; + CGuid LogGuid; + UInt32 DescriptorCount; + UInt64 FlushedFileOffset; + UInt64 LastFileOffset; + + bool Parse(const Byte *p); +}; + +bool CLogEntry::Parse(const Byte *p) +{ + G32 (8, EntryLength); + G32 (12,Tail); + G64 (16, SequenceNumber); + G32 (24, DescriptorCount); // it's 32-bit, but specification says 64-bit + if (Get32(p + 28) != 0) // reserved + return false; + LogGuid.SetFrom(p + 32); + G64 (48, FlushedFileOffset); + G64 (56, LastFileOffset); + + if (SequenceNumber == 0) + return false; + if ((Tail & 0xfff) != 0) + return false; + if (IS_NON_ALIGNED(FlushedFileOffset)) + return false; + if (IS_NON_ALIGNED(LastFileOffset)) + return false; + return true; +} + + +bool CHandler::ParseLog(CByteBuffer &log) +{ + CLogEntry lastEntry; + lastEntry.SequenceNumber = 0; + bool lastEntry_found = false; + size_t lastEntry_Offset = 0; + for (size_t i = 0; i < log.Size(); i += 1 << 12) + { + Byte *p = (Byte *)(log + i); + + if (Get32(p) != 0x65676F6C) // "loge" + continue; + const UInt32 crc = Get32(p + 4); + + CLogEntry e; + if (!e.Parse(p)) + { + return false; + continue; + } + const UInt32 entryLength = Get32(p + 8); + if (e.EntryLength > log.Size() || (e.EntryLength & 0xFFF) != 0 || e.EntryLength == 0) + { + return false; + continue; + } + SetUi32(p + 4, 0); + const UInt32 crc_calced = Crc32c_Calc(p, entryLength); + SetUi32(p + 4, crc); // we must restore crc if we want same data in log + if (crc_calced != crc) + continue; + if (!lastEntry_found || lastEntry.SequenceNumber < e.SequenceNumber) + { + lastEntry = e; + lastEntry_found = true; + lastEntry_Offset = i; + } + } + + return true; +} +*/ + + +bool CHandler::ParseBat() +{ + ChunkRatio_Log = kBitmapSize_Log + 3 + Meta.LogicalSectorSize_Log - Meta.BlockSize_Log; + ChunkRatio = (size_t)1 << (ChunkRatio_Log); + + UInt64 totalBatEntries64; + const bool isDiff = IsDiff(); + const UInt32 blockSize = (UInt32)1 << Meta.BlockSize_Log; + { + const UInt64 up = Meta.VirtualDiskSize + blockSize - 1; + if (up < Meta.VirtualDiskSize) + return false; + const UInt64 numDataBlocks = up >> Meta.BlockSize_Log; + + if (isDiff) + { + // differencing table must be finished with bitmap entry + const UInt64 numBitmaps = (numDataBlocks + ChunkRatio - 1) >> ChunkRatio_Log; + totalBatEntries64 = numBitmaps * (ChunkRatio + 1); + } + else + { + // we don't need last Bitmap entry + totalBatEntries64 = numDataBlocks + ((numDataBlocks - 1) >> ChunkRatio_Log); + } + } + + if (totalBatEntries64 > Bat.Data.Size() / 8) + return false; + + const size_t totalBatEntries = (size_t)totalBatEntries64; + TotalBatEntries = totalBatEntries; + + bool isCont = (!isDiff && Meta.Is_LeaveBlockAllocated()); + UInt64 prevBlockOffset = 0; + UInt64 maxBlockOffset = 0; + + size_t remEntries = ChunkRatio + 1; + + size_t i; + for (i = 0; i < totalBatEntries; i++) + { + const UInt64 v = Bat.GetItem(i); + if ((v & 0xFFFF8) != 0) + return false; + const UInt64 offset = BAT_GET_OFFSET(v); + const unsigned state = BAT_GET_STATE(v); + + /* + UInt64 index64 = v >> 20; + printf("\n%7d", i); + printf("%10d, ", (unsigned)index64); + printf("%4x, ", (unsigned)state); + */ + + remEntries--; + if (remEntries == 0) + { + // printf(" ========"); + // printf("\n"); + remEntries = ChunkRatio + 1; + if (state == SB_BLOCK_PRESENT) + { + isCont = false; + if (!isDiff) + return false; + if (offset == 0) + return false; + const UInt64 lim = offset + kBitmapSize; + if (lim < offset) + return false; + if (_phySize < lim) + _phySize = lim; + NumUsedBitMaps++; + } + else if (state != SB_BLOCK_NOT_PRESENT) + return false; + } + else + { + if (state == PAYLOAD_BLOCK_FULLY_PRESENT + || state == PAYLOAD_BLOCK_PARTIALLY_PRESENT) + { + if (offset == 0) + return false; + if (maxBlockOffset < offset) + maxBlockOffset = offset; + + if (state == PAYLOAD_BLOCK_PARTIALLY_PRESENT) + { + isCont = false; + if (!isDiff) + return false; + } + else if (isCont) + { + if (prevBlockOffset != 0 && prevBlockOffset + blockSize != offset) + isCont = false; + else + prevBlockOffset = offset; + } + + NumUsedBlocks++; + } + else if (state == PAYLOAD_BLOCK_UNMAPPED) + { + isCont = false; + // non-empty (offset) is allowed + } + else if (state == PAYLOAD_BLOCK_NOT_PRESENT + || state == PAYLOAD_BLOCK_UNDEFINED + || state == PAYLOAD_BLOCK_ZERO) + { + isCont = false; + /* (offset) is reserved and (offset == 0) is expected here, + but we ignore (offset) here */ + // if (offset != 0) return false; + } + else + return false; + } + } + + _isDataContiguous = isCont; + + if (maxBlockOffset != 0) + { + const UInt64 lim = maxBlockOffset + blockSize; + if (lim < maxBlockOffset) + return false; + if (_phySize < lim) + _phySize = lim; + const UInt64 kPhyLimit = (UInt64)1 << 62; + if (maxBlockOffset >= kPhyLimit) + return false; + } + return true; +} + + +bool CHandler::CheckBat() +{ + const UInt64 upSize = _phySize + kBitmapSize * 8 - 1; + if (upSize < _phySize) + return false; + const UInt64 useMapSize64 = upSize >> (kBitmapSize_Log + 3); + const size_t useMapSize = (size_t)useMapSize64; + + const UInt32 blockSizeMB = (UInt32)1 << (Meta.BlockSize_Log - kBitmapSize_Log); + + // we don't check useMap, if it's too big. + if (useMapSize != useMapSize64) + return true; + if (useMapSize == 0 || useMapSize > ((size_t)1 << 28)) + return true; + + CByteArr useMap; + useMap.Alloc(useMapSize); + memset(useMap, 0, useMapSize); + // useMap[0] = (Byte)(1 << 0); // first 1 MB is used by headers + // we can also update useMap for log, and region data. + + const size_t totalBatEntries = TotalBatEntries; + size_t remEntries = ChunkRatio + 1; + + size_t i; + for (i = 0; i < totalBatEntries; i++) + { + const UInt64 v = Bat.GetItem(i); + const UInt64 offset = BAT_GET_OFFSET(v); + const unsigned state = BAT_GET_STATE(v); + const UInt64 index = offset >> kBitmapSize_Log; + UInt32 numBlocks = 1; + remEntries--; + if (remEntries == 0) + { + remEntries = ChunkRatio + 1; + if (state != SB_BLOCK_PRESENT) + continue; + } + else + { + if (state != PAYLOAD_BLOCK_FULLY_PRESENT && + state != PAYLOAD_BLOCK_PARTIALLY_PRESENT) + continue; + numBlocks = blockSizeMB; + } + + for (unsigned k = 0; k < numBlocks; k++) + { + const UInt64 index2 = index + k; + const unsigned flag = (unsigned)1 << ((unsigned)index2 & 7); + const size_t byteIndex = (size_t)(index2 >> 3); + if (byteIndex >= useMapSize) + return false; + const unsigned m = useMap[byteIndex]; + if (m & flag) + return false; + useMap[byteIndex] = (Byte)(m | flag); + } + } + + /* + UInt64 num = 0; + for (i = 0; i < useMapSize; i++) + { + Byte b = useMap[i]; + unsigned t = 0; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); b >>= 1; + t += (b & 1); + num += t; + } + NumUsed_1MB_Blocks = num; + NumUsed_1MB_Blocks_Defined = true; + */ + + return true; +} + + + +HRESULT CHandler::Open3() +{ + { + const unsigned kHeaderSize = 512; // + 8 + Byte header[kHeaderSize]; + + RINOK(Read_FALSE(header, kHeaderSize)) + + if (memcmp(header, kSignature, kSignatureSize) != 0) + return S_FALSE; + + const Byte *p = &header[0]; + for (unsigned i = kSignatureSize; i < kHeaderSize; i += 2) + { + const wchar_t c = Get16(p + i); + if (c < 0x20 || c > 0x7F) + break; + _creator += c; + } + } + + HeadersSize = (UInt32)1 << 20; + CHeader headers[2]; + { + Byte header[kHeader2Size]; + for (unsigned i = 0; i < 2; i++) + { + RINOK(Seek2((1 << 16) * (1 + i))) + RINOK(Read_FALSE(header, kHeader2Size)) + bool headerIsOK = headers[i].Parse(header); + if (!headerIsOK) + return S_FALSE; + } + } + unsigned mainIndex; + if (headers[0].SequenceNumber > headers[1].SequenceNumber) mainIndex = 0; + else if (headers[0].SequenceNumber < headers[1].SequenceNumber) mainIndex = 1; + 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; + if (h.LogLength != 0) + { + HeadersSize += h.LogLength; + UpdatePhySize(h.LogOffset + h.LogLength); + if (!h.Guids[kHeader_GUID_Index_LogGuid].IsZero()) + { + _nonEmptyLog = true; + AddErrorMessage("non-empty LOG was not replayed"); + /* + if (h.LogVersion != 0) + AddErrorMessage("unknown LogVresion"); + else + { + CByteBuffer log; + RINOK(Seek2(h.LogOffset)); + RINOK(ReadToBuf_FALSE(log, h.LogLength)); + if (!ParseLog(log)) + { + return S_FALSE; + } + } + */ + } + } + CRegion regions[2]; + int correctRegionIndex = -1; + + { + CByteBuffer temp; + temp.Alloc(kRegionSize * 2); + RINOK(Seek2((1 << 16) * 3)) + RINOK(Read_FALSE(temp, kRegionSize * 2)) + unsigned numTables = 1; + if (memcmp(temp, temp + kRegionSize, kRegionSize) != 0) + { + AddErrorMessage("Region tables mismatch"); + numTables = 2; + } + + for (unsigned i = 0; i < numTables; i++) + { + // RINOK(Seek2((1 << 16) * (3 + i))); + // RINOK(Read_FALSE(temp, kRegionSize)); + if (regions[i].Parse(temp)) + { + if (correctRegionIndex < 0) + correctRegionIndex = (int)i; + } + else + { + AddErrorMessage("Incorrect region table"); + } + } + if (correctRegionIndex < 0) + return S_FALSE; + /* + if (!regions[0].IsEqualTo(regions[1])) + return S_FALSE; + */ + } + + // UpdatePhySize((1 << 16) * 5); + UpdatePhySize(1 << 20); + + { + const CRegion ®ion = regions[correctRegionIndex]; + HeadersSize += region.DataSize; + UpdatePhySize(region.EndPos); + { + if (!region.Meta_Defined) + return S_FALSE; + const CRegionEntry &e = region.MetaEntry; + if (e.Len == 0) + return S_FALSE; + { + // static const kMetaTableSize = 1 << 16; + CByteBuffer temp; + { + RINOK(Seek2(e.Offset)) + RINOK(ReadToBuf_FALSE(temp, e.Len)) + } + if (!Meta.Parse(temp, temp.Size())) + return S_FALSE; + } + // UpdatePhySize(e.GetEndPos()); + } + { + if (!region.Bat_Defined) + return S_FALSE; + const CRegionEntry &e = region.BatEntry; + if (e.Len == 0) + return S_FALSE; + // UpdatePhySize(e.GetEndPos()); + { + RINOK(Seek2(e.Offset)) + RINOK(ReadToBuf_FALSE(Bat.Data, e.Len)) + } + if (!ParseBat()) + return S_FALSE; + if (!CheckBat()) + { + AddErrorMessage("BAT overlap"); + // _batOverlap = true; + // return S_FALSE; + } + } + } + + { + // do we need to check "parent_linkage2" also? + FOR_VECTOR (i, Meta.ParentPairs) + { + const CParentPair &pair = Meta.ParentPairs[i]; + if (pair.Key.IsEqualTo("parent_linkage")) + { + _parentGuid_IsDefined = _parentGuid.ParseFromFormatedHexString(pair.Value); + break; + } + } + } + + { + // absolute paths for parent stream can be rejected later in client callback + // the order of check by specification: + const char * const g_ParentKeys[] = + { + "relative_path" // "..\..\path2\sub3\parent.vhdx" + , "volume_path" // "\\?\Volume{26A21BDA-A627-11D7-9931-806E6F6E6963}\path2\sub3\parent.vhdx") + , "absolute_win32_path" // "d:\path2\sub3\parent.vhdx" + }; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ParentKeys); i++) + { + const int index = Meta.FindParentKey(g_ParentKeys[i]); + if (index < 0) + continue; + ParentNames.Add(Meta.ParentPairs[index].Value); + } + } + + if (Meta.Is_HasParent()) + { + if (!Meta.Locator_Defined) + AddErrorMessage("Parent locator is not defined"); + else + { + if (!_parentGuid_IsDefined) + AddErrorMessage("Parent GUID is not defined"); + if (ParentNames.IsEmpty()) + AddErrorMessage("Parent VHDX file name is not defined"); + } + } + else + { + if (Meta.Locator_Defined) + AddErrorMessage("Unexpected parent locator"); + } + + // here we suppose that and locator can be used only with HasParent flag + + // return S_FALSE; + + _size = Meta.VirtualDiskSize; // CHandlerImg + + // _posInArc = 0; + // Reset_PosInArc(); + // RINOK(InStream_SeekToBegin(Stream)) + + return S_OK; +} + + +/* +static UInt32 g_NumCalls = 0; +static UInt32 g_NumCalls2 = 0; +static struct CCounter { ~CCounter() +{ + printf("\nNumCalls = %10u\n", g_NumCalls); + printf("NumCalls2 = %10u\n", g_NumCalls2); +} } g_Counter; +*/ + +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + // g_NumCalls++; + if (processedSize) + *processedSize = 0; + if (_virtPos >= Meta.VirtualDiskSize) + return S_OK; + { + const UInt64 rem = Meta.VirtualDiskSize - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + const size_t blockIndex = (size_t)(_virtPos >> Meta.BlockSize_Log); + const size_t chunkIndex = blockIndex >> ChunkRatio_Log; + const size_t chunkRatio = (size_t)1 << ChunkRatio_Log; + const size_t blockIndex2 = chunkIndex * (chunkRatio + 1) + (blockIndex & (chunkRatio - 1)); + const UInt64 blockSectVal = Bat.GetItem(blockIndex2); + const UInt64 blockOffset = BAT_GET_OFFSET(blockSectVal); + const UInt32 blockState = BAT_GET_STATE(blockSectVal); + + const UInt32 blockSize = (UInt32)1 << Meta.BlockSize_Log; + const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + size = MyMin(blockSize - offsetInBlock, size); + + bool needParent = false; + bool needRead = false; + + if (blockState == PAYLOAD_BLOCK_FULLY_PRESENT) + needRead = true; + else if (blockState == PAYLOAD_BLOCK_NOT_PRESENT) + { + /* for a differencing VHDX: parent virtual disk SHOULD be + inspected to determine the associated contents (SPECIFICATION). + we suppose that we should not check BitMap. + for fixed or dynamic VHDX files: the block contents are undefined and + can contain arbitrary data (SPECIFICATION). NTFS::pagefile.sys can use such state. */ + if (IsDiff()) + needParent = true; + } + else if (blockState == PAYLOAD_BLOCK_PARTIALLY_PRESENT) + { + // only allowed for differencing VHDX files. + // associated sector bitmap block MUST be valid + if (chunkIndex >= BitMaps.Size()) + return S_FALSE; + // else + { + const CByteBuffer &bitmap = BitMaps[(unsigned)chunkIndex]; + const Byte *p = (const Byte *)bitmap; + if (!p) + return S_FALSE; + // else + { + // g_NumCalls2++; + const UInt64 sectorIndex = _virtPos >> Meta.LogicalSectorSize_Log; + + #define BIT_MAP_UNIT_LOG 3 // it's for small block (4 KB) + // #define BIT_MAP_UNIT_LOG 5 // speed optimization for large blocks (16 KB) + + const size_t offs = (size_t)(sectorIndex >> 3) & + ( + (kBitmapSize - 1) + & ~(((UInt32)1 << (BIT_MAP_UNIT_LOG - 3)) - 1) + ); + + unsigned sector2 = (unsigned)sectorIndex & ((1 << BIT_MAP_UNIT_LOG) - 1); + #if BIT_MAP_UNIT_LOG == 5 + UInt32 v = GetUi32(p + offs) >> sector2; + #else + unsigned v = (unsigned)p[offs] >> sector2; + #endif + // UInt32 v = GetUi32(p + offs) >> sector2; + const UInt32 sectorSize = (UInt32)1 << Meta.LogicalSectorSize_Log; + const UInt32 offsetInSector = (UInt32)_virtPos & (sectorSize - 1); + const unsigned bit = (unsigned)(v & 1); + if (bit) + needRead = true; + else + needParent = true; // zero - from the parent VHDX file + UInt32 rem = sectorSize - offsetInSector; + for (sector2++; sector2 < (1 << BIT_MAP_UNIT_LOG); sector2++) + { + v >>= 1; + if (bit != (v & 1)) + break; + rem += sectorSize; + } + if (size > rem) + size = rem; + } + } + } + + bool needZero = true; + + HRESULT res = S_OK; + + if (needParent) + { + if (!ParentStream) + return S_FALSE; + // if (ParentStream) + { + RINOK(InStream_SeekSet(ParentStream, _virtPos)) + size_t processed = size; + res = ReadStream(ParentStream, (Byte *)data, &processed); + size = (UInt32)processed; + needZero = false; + } + } + else if (needRead) + { + UInt32 processed = 0; + res = ReadPhy(blockOffset + offsetInBlock, data, size, processed); + size = processed; + needZero = false; + } + + if (needZero) + memset(data, 0, size); + + if (processedSize) + *processedSize = size; + + _virtPos += size; + return res; +} + + +enum +{ + kpidParent = kpidUserDefined +}; + +static const CStatProp kArcProps[] = +{ + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidSectorSize, VT_UI4}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidNumVolumes, VT_UI4}, + { NULL, kpidTotalPhySize, VT_UI8}, + { "Parent", kpidParent, VT_BSTR}, + { NULL, kpidCreatorApp, VT_BSTR}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidId, VT_BSTR} + }; + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + + +void CHandler::AddErrorMessage(const char *message) +{ + if (!_errorMessage.IsEmpty()) + _errorMessage.Add_LF(); + _errorMessage += message; +} + +void CHandler::AddErrorMessage(const char *message, const wchar_t *name) +{ + AddErrorMessage(message); + _errorMessage += name; +} + + +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.Add_Char(val ? '+' : '-'); + s.Add_LF(); +} + +static void AddComment_UInt64(UString &s, const char *name, UInt64 v, bool showMB = false) +{ + AddComment_Name(s, name); + s.Add_UInt64(v); + if (showMB) + { + s += " ("; + s.Add_UInt64(v >> 20); + s += " MiB)"; + } + s.Add_LF(); +} + +static void AddComment_BlockSize(UString &s, const char *name, unsigned logSize) +{ + if (logSize != 0) + AddComment_UInt64(s, name, ((UInt64)1 << logSize)); +} + + +void CHandler::AddComment(UString &s) const +{ + AddComment_UInt64(s, "VirtualDiskSize", Meta.VirtualDiskSize); + AddComment_UInt64(s, "PhysicalSize", _phySize); + + if (!_errorMessage.IsEmpty()) + { + AddComment_Name(s, "Error"); + s += _errorMessage; + s.Add_LF(); + } + + if (Meta.Guid_Defined) + { + AddComment_Name(s, "Id"); + Meta.Guid.AddHexToString(s); + s.Add_LF(); + } + + AddComment_UInt64(s, "SequenceNumber", Header.SequenceNumber); + AddComment_UInt64(s, "LogLength", Header.LogLength, true); + + for (unsigned i = 0; i < 3; i++) + { + const CGuid &g = Header.Guids[i]; + if (g.IsZero()) + continue; + if (i == 0) + s += "FileWrite"; + else if (i == 1) + s += "DataWrite"; + else + s += "Log"; + AddComment_Name(s, "Guid"); + g.AddHexToString(s); + s.Add_LF(); + } + + AddComment_Bool(s, "HasParent", Meta.Is_HasParent()); + AddComment_Bool(s, "Fixed", Meta.Is_LeaveBlockAllocated()); + if (Meta.Is_LeaveBlockAllocated()) + AddComment_Bool(s, "DataContiguous", _isDataContiguous); + + AddComment_BlockSize(s, "BlockSize", Meta.BlockSize_Log); + AddComment_BlockSize(s, "LogicalSectorSize", Meta.LogicalSectorSize_Log); + AddComment_BlockSize(s, "PhysicalSectorSize", Meta.PhysicalSectorSize_Log); + + { + const UInt64 packSize = GetPackSize(); + AddComment_UInt64(s, "PackSize", packSize, true); + const UInt64 headersSize = HeadersSize + ((UInt64)NumUsedBitMaps << kBitmapSize_Log); + AddComment_UInt64(s, "HeadersSize", headersSize, true); + AddComment_UInt64(s, "FreeSpace", _phySize - packSize - headersSize, true); + /* + if (NumUsed_1MB_Blocks_Defined) + AddComment_UInt64(s, "used2", (NumUsed_1MB_Blocks << 20)); + */ + } + + if (Meta.ParentPairs.Size() != 0) + { + s += "Parent:"; + s.Add_LF(); + FOR_VECTOR(i, Meta.ParentPairs) + { + const CParentPair &pair = Meta.ParentPairs[i]; + s += " "; + s += pair.Key; + s += ": "; + s += pair.Value; + s.Add_LF(); + } + s.Add_LF(); + } +} + + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidClusterSize: prop = (UInt32)1 << Meta.BlockSize_Log; break; + case kpidSectorSize: prop = (UInt32)1 << Meta.LogicalSectorSize_Log; break; + case kpidShortComment: + case kpidMethod: + { + AString s; + AddTypeString(s); + if (IsDiff()) + { + s += " -> "; + const CHandler *p = this; + while (p && p->IsDiff()) + p = p->Parent; + if (!p) + s += '?'; + else + p->AddTypeString(s); + } + prop = s; + break; + } + case kpidComment: + { + UString s; + { + if (NumLevels > 1) + { + AddComment_UInt64(s, "NumVolumeLevels", NumLevels); + AddComment_UInt64(s, "PackSizeTotal", PackSize_Total, true); + s += "----"; + s.Add_LF(); + } + + const CHandler *p = this; + for (;;) + { + if (p->_level != 0 || p->Parent) + AddComment_UInt64(s, "VolumeLevel", p->_level + 1); + p->AddComment(s); + if (!p->Parent) + break; + s += "----"; + s.Add_LF(); + { + s.Add_LF(); + if (!p->ParentName_Used.IsEmpty()) + { + AddComment_Name(s, "Name"); + s += p->ParentName_Used; + s.Add_LF(); + } + } + p = p->Parent; + } + } + prop = s; + break; + } + case kpidCreatorApp: + { + if (!_creator.IsEmpty()) + prop = _creator; + break; + } + case kpidId: + { + if (Meta.Guid_Defined) + { + UString s; + Meta.Guid.AddHexToString(s); + prop = s; + } + break; + } + case kpidName: + { + if (Meta.Guid_Defined) + { + UString s; + Meta.Guid.AddHexToString(s); + s += ".vhdx"; + prop = s; + } + break; + } + case kpidParent: if (IsDiff()) prop = GetParentSequence(); break; + case kpidPhySize: prop = _phySize; break; + case kpidTotalPhySize: + { + const CHandler *p = this; + UInt64 sum = 0; + do + { + sum += p->_phySize; + p = p->Parent; + } + while (p); + prop = sum; + break; + } + case kpidNumVolumes: if (NumLevels != 1) prop = (UInt32)NumLevels; break; + case kpidError: + { + UString s; + const CHandler *p = this; + do + { + if (!p->_errorMessage.IsEmpty()) + { + if (!s.IsEmpty()) + s.Add_LF(); + s += p->_errorMessage; + } + p = p->Parent; + } + while (p); + if (!s.IsEmpty()) + prop = s; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openArchiveCallback) +{ + Stream = stream; + if (_level >= (1 << 20)) + return S_FALSE; + + RINOK(Open3()) + + NumLevels = 1; + PackSize_Total = GetPackSize(); + + if (_child) + { + if (!_child->_parentGuid.IsEqualTo(Header.Guids[kHeader_GUID_Index_DataWriteGuid])) + return S_FALSE; + const CHandler *child = _child; + do + { + /* We suppose that only FileWriteGuid is unique. + Another IDs must be identical in in difference and parent archives. */ + if (Header.Guids[kHeader_GUID_Index_FileWriteGuid].IsEqualTo( + child->Header.Guids[kHeader_GUID_Index_FileWriteGuid]) + && _phySize == child->_phySize) + { + _isCyclic = true; + _isCyclic_or_CyclicParent = true; + AddErrorMessage("Cyclic parent archive was blocked"); + return S_OK; + } + child = child->_child; + } + while (child); + } + + if (!Meta.Is_HasParent()) + return S_OK; + + if (!Meta.Locator_Defined + || !_parentGuid_IsDefined + || ParentNames.IsEmpty()) + { + return S_OK; + } + + ParentName_Used = ParentNames.Front(); + + HRESULT res; + const unsigned kNumLevelsMax = (1 << 8); // Maybe we need to increase that limit + if (_level >= kNumLevelsMax - 1) + { + AddErrorMessage("Too many parent levels"); + return S_OK; + } + + bool _parentFileWasOpen = false; + + if (!openArchiveCallback) + res = S_FALSE; + else + res = OpenParent(openArchiveCallback, _parentFileWasOpen); + + if (res != S_OK) + { + if (res != S_FALSE) + return res; + + if (_parentFileWasOpen) + AddErrorMessage("Can't parse parent VHDX file : ", ParentName_Used); + else + AddErrorMessage("Missing parent VHDX file : ", ParentName_Used); + } + + + return S_OK; +} + + +HRESULT CHandler::OpenParent(IArchiveOpenCallback *openArchiveCallback, bool &_parentFileWasOpen) +{ + _parentFileWasOpen = false; + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openArchiveCallback) + if (!openVolumeCallback) + return S_FALSE; + { + CMyComPtr nextStream; + HRESULT res = S_FALSE; + UString name; + + FOR_VECTOR (i, ParentNames) + { + name = ParentNames[i]; + + // we remove prefix ".\\', but client already can support any variant + if (name[0] == L'.' && name[1] == L'\\') + name.DeleteFrontal(2); + + res = openVolumeCallback->GetStream(name, &nextStream); + + if (res == S_OK && nextStream) + break; + + if (res != S_OK && res != S_FALSE) + return res; + } + + if (res == S_FALSE || !nextStream) + return S_FALSE; + + ParentName_Used = name; + _parentFileWasOpen = true; + + Parent = new CHandler; + ParentStream = Parent; + + try + { + Parent->_level = _level + 1; + Parent->_child = this; + /* we could call CHandlerImg::Open() here. + but we don't need (_imgExt) in (Parent). So we call Open2() here */ + Parent->Close(); + res = Parent->Open2(nextStream, openArchiveCallback); + } + catch(...) + { + Parent = NULL; + ParentStream.Release(); + res = S_FALSE; + throw; + } + + if (res != S_OK) + { + Parent = NULL; + ParentStream.Release(); + if (res == E_ABORT) + return res; + if (res != S_FALSE) + { + // we must show that error code + } + } + + if (res == S_OK) + { + if (Parent->_isCyclic_or_CyclicParent) + _isCyclic_or_CyclicParent = true; + + NumLevels = Parent->NumLevels + 1; + PackSize_Total += Parent->GetPackSize(); + + // we read BitMaps only if Parent was open + + UInt64 numBytes = (UInt64)NumUsedBitMaps << kBitmapSize_Log; + if (openArchiveCallback && numBytes != 0) + { + RINOK(openArchiveCallback->SetTotal(NULL, &numBytes)) + } + numBytes = 0; + for (size_t i = ChunkRatio; i < TotalBatEntries; i += ChunkRatio + 1) + { + const UInt64 v = Bat.GetItem(i); + const UInt64 offset = BAT_GET_OFFSET(v); + const unsigned state = BAT_GET_STATE(v); + + CByteBuffer &buf = BitMaps.AddNew(); + if (state == SB_BLOCK_PRESENT) + { + if (openArchiveCallback) + { + RINOK(openArchiveCallback->SetCompleted(NULL, &numBytes)) + } + numBytes += kBitmapSize; + buf.Alloc(kBitmapSize); + RINOK(Seek2(offset)) + RINOK(Read_FALSE(buf, kBitmapSize)) + /* + for (unsigned i = 0; i < (1 << 20); i+=4) + { + UInt32 v = GetUi32(buf + i); + if (v != 0 && v != (UInt32)(Int32)-1) + printf("\n%7d %8x", i, v); + } + */ + } + } + } + } + + return S_OK; +} + + +void CHandler::CloseAtError() +{ + // CHandlerImg + Clear_HandlerImg_Vars(); + Stream.Release(); + + _phySize = 0; + Bat.Clear(); + BitMaps.Clear(); + NumUsedBlocks = 0; + NumUsedBitMaps = 0; + HeadersSize = 0; + /* + NumUsed_1MB_Blocks = 0; + NumUsed_1MB_Blocks_Defined = false; + */ + + Parent = NULL; + ParentStream.Release(); + _errorMessage.Empty(); + _creator.Empty(); + _nonEmptyLog = false; + _parentGuid_IsDefined = false; + _isDataContiguous = false; + // _batOverlap = false; + + ParentNames.Clear(); + ParentName_Used.Empty(); + + Meta.Clear(); + + ChunkRatio_Log = 0; + ChunkRatio = 0; + TotalBatEntries = 0; + NumLevels = 0; + PackSize_Total = 0; + + _isCyclic = false; + _isCyclic_or_CyclicParent = false; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + CloseAtError(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidSize: prop = Meta.VirtualDiskSize; break; + case kpidPackSize: prop = PackSize_Total; break; + case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + // if some prarent is not OK, we don't create stream + if (!AreParentsOK()) + return S_FALSE; + InitSeekPositions(); + CMyComPtr streamTemp = this; + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + +REGISTER_ARC_I( + "VHDX", "vhdx avhdx", NULL, 0xc4, + kSignature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/VmdkHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VmdkHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/VmdkHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/VmdkHandler.cpp 2025-06-16 09:00:00.000000000 +0000 @@ -1,1518 +1,1530 @@ -// VmdkHandler.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/IntToString.h" -#include "../../Common/StringConvert.h" -#include "../../Common/StringToInt.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/RegisterArc.h" -#include "../Common/StreamObjects.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/ZlibDecoder.h" - -#include "HandlerCont.h" - -using namespace NWindows; - -namespace NArchive { -namespace NVmdk { - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -#define LE_16(offs, dest) dest = Get16(p + (offs)); -#define LE_32(offs, dest) dest = Get32(p + (offs)); -#define LE_64(offs, dest) dest = Get64(p + (offs)); - - -#define SIGNATURE { 'K', 'D', 'M', 'V' } - -static const Byte k_Signature[] = SIGNATURE; - -static const UInt32 k_Flags_NL = (UInt32)1 << 0; -static const UInt32 k_Flags_RGD = (UInt32)1 << 1; -static const UInt32 k_Flags_ZeroGrain = (UInt32)1 << 2; -static const UInt32 k_Flags_Compressed = (UInt32)1 << 16; -static const UInt32 k_Flags_Marker = (UInt32)1 << 17; - -static const unsigned k_NumMidBits = 9; // num bits for index in Grain Table - -struct CHeader -{ - UInt32 flags; - UInt32 version; - - UInt64 capacity; - UInt64 grainSize; - UInt64 descriptorOffset; - UInt64 descriptorSize; - - UInt32 numGTEsPerGT; - UInt16 algo; - // Byte uncleanShutdown; - // UInt64 rgdOffset; - UInt64 gdOffset; - UInt64 overHead; - - bool Is_NL() const { return (flags & k_Flags_NL) != 0; }; - bool Is_ZeroGrain() const { return (flags & k_Flags_ZeroGrain) != 0; }; - bool Is_Compressed() const { return (flags & k_Flags_Compressed) != 0; }; - bool Is_Marker() const { return (flags & k_Flags_Marker) != 0; }; - - bool Parse(const Byte *p); - - bool IsSameImageFor(const CHeader &h) const - { - return flags == h.flags - && version == h.version - && capacity == h.capacity - && grainSize == h.grainSize - && algo == h.algo; - } -}; - -bool CHeader::Parse(const Byte *p) -{ - if (memcmp(p, k_Signature, sizeof(k_Signature)) != 0) - return false; - - LE_32 (0x04, version); - LE_32 (0x08, flags); - LE_64 (0x0C, capacity); - LE_64 (0x14, grainSize); - LE_64 (0x1C, descriptorOffset); - LE_64 (0x24, descriptorSize); - LE_32 (0x2C, numGTEsPerGT); - // LE_64 (0x30, rgdOffset); - LE_64 (0x38, gdOffset); - LE_64 (0x40, overHead); - // uncleanShutdown = buf[0x48]; - LE_16(0x4D, algo); - - if (Is_NL() && Get32(p + 0x49) != 0x0A0D200A) // do we need Is_NL() check here? - return false; - - return (numGTEsPerGT == (1 << k_NumMidBits)) && (version <= 3); -} - - -enum -{ - k_Marker_END_OF_STREAM = 0, - k_Marker_GRAIN_TABLE = 1, - k_Marker_GRAIN_DIR = 2, - k_Marker_FOOTER = 3 -}; - -struct CMarker -{ - UInt64 NumSectors; - UInt32 SpecSize; // = 0 for metadata sectors - UInt32 Type; - - void Parse(const Byte *p) - { - LE_64 (0, NumSectors); - LE_32 (8, SpecSize); - LE_32 (12, Type); - } -}; - - -static bool Str_to_ValName(const AString &s, AString &name, AString &val) -{ - name.Empty(); - val.Empty(); - int qu = s.Find('"'); - int eq = s.Find('='); - if (eq < 0 || (qu >= 0 && eq > qu)) - return false; - name = s.Left(eq); - name.Trim(); - val = s.Ptr(eq + 1); - val.Trim(); - return true; -} - -static inline bool IsSpaceChar(char c) -{ - return (c == ' ' || c == '\t'); -} - -static const char *SkipSpaces(const char *s) -{ - for (;; s++) - { - char c = *s; - if (c == 0 || !IsSpaceChar(c)) - return s; - } -} - -#define SKIP_SPACES(s) s = SkipSpaces(s); - -static const char *GetNextWord(const char *s, AString &dest) -{ - dest.Empty(); - SKIP_SPACES(s); - const char *start = s; - for (;; s++) - { - char c = *s; - if (c == 0 || IsSpaceChar(c)) - { - dest.SetFrom(start, (unsigned)(s - start)); - return s; - } - } -} - -static const char *GetNextNumber(const char *s, UInt64 &val) -{ - SKIP_SPACES(s); - if (*s == 0) - return s; - const char *end; - val = ConvertStringToUInt64(s, &end); - char c = *end; - if (c != 0 && !IsSpaceChar(c)) - return NULL; - return end; -} - - -struct CExtentInfo -{ - AString Access; // RW, RDONLY, or NOACCESS - UInt64 NumSectors; // 512 bytes sectors - AString Type; // FLAT, SPARSE, ZERO, VMFS, VMFSSPARSE, VMFSRDM, VMFSRAW - AString FileName; - UInt64 StartSector; // used for FLAT - - // for VMWare Player 9: - // PartitionUUID - // DeviceIdentifier - - bool IsType_ZERO() const { return Type == "ZERO"; } - // bool IsType_FLAT() const { return Type == "FLAT"; } - bool IsType_Flat() const { return Type == "FLAT" || Type == "VMFS" || Type == "VMFSRAW"; } - - bool Parse(const char *s); -}; - -bool CExtentInfo::Parse(const char *s) -{ - NumSectors = 0; - StartSector = 0; - Access.Empty(); - Type.Empty(); - FileName.Empty(); - - s = GetNextWord(s, Access); - s = GetNextNumber(s, NumSectors); - if (!s) - return false; - s = GetNextWord(s, Type); - - if (Type.IsEmpty()) - return false; - - SKIP_SPACES(s); - - if (IsType_ZERO()) - return (*s == 0); - - if (*s != '\"') - return false; - s++; - { - const char *s2 = strchr(s, '\"'); - if (!s2) - return false; - FileName.SetFrom(s, (unsigned)(s2 - s)); - s = s2 + 1; - } - SKIP_SPACES(s); - if (*s == 0) - return true; - - s = GetNextNumber(s, StartSector); - if (!s) - return false; - return true; - // SKIP_SPACES(s); - // return (*s == 0); -} - - -struct CDescriptor -{ - AString CID; - AString parentCID; - AString createType; - // AString encoding; // UTF-8, windows-1252 - default is UTF-8 - - CObjectVector Extents; - - static void GetUnicodeName(const AString &s, UString &res) - { - if (!ConvertUTF8ToUnicode(s, res)) - MultiByteToUnicodeString2(res, s); - } - - void Clear() - { - CID.Empty(); - parentCID.Empty(); - createType.Empty(); - Extents.Clear(); - } - - bool IsThere_Parent() const - { - return !parentCID.IsEmpty() && !parentCID.IsEqualTo_Ascii_NoCase("ffffffff"); - } - - bool Parse(const Byte *p, size_t size); -}; - - -bool CDescriptor::Parse(const Byte *p, size_t size) -{ - Clear(); - - AString s; - AString name; - AString val; - - for (size_t i = 0;; i++) - { - const char c = p[i]; - if (i == size || c == 0 || c == 0xA || c == 0xD) - { - if (!s.IsEmpty() && s[0] != '#') - { - if (Str_to_ValName(s, name, val)) - { - if (name.IsEqualTo_Ascii_NoCase("CID")) - CID = val; - else if (name.IsEqualTo_Ascii_NoCase("parentCID")) - parentCID = val; - else if (name.IsEqualTo_Ascii_NoCase("createType")) - createType = val; - } - else - { - CExtentInfo ei; - if (!ei.Parse(s)) - return false; - Extents.Add(ei); - } - } - - s.Empty(); - if (c == 0 || i >= size) - break; - } - else - s += (char)c; - } - - return true; -} - - -struct CExtent -{ - bool IsOK; - bool IsArc; - bool NeedDeflate; - bool Unsupported; - bool IsZero; - bool IsFlat; - bool DescriptorOK; - bool HeadersError; - - unsigned ClusterBits; - UInt32 ZeroSector; - - CObjectVector Tables; - - CMyComPtr Stream; - UInt64 PosInArc; - - UInt64 PhySize; - UInt64 VirtSize; // from vmdk header of volume - - UInt64 StartOffset; // virtual offset of this extent - UInt64 NumBytes; // from main descriptor, if multi-vol - UInt64 FlatOffset; // in Stream - - CByteBuffer DescriptorBuf; - CDescriptor Descriptor; - - CHeader h; - - UInt64 GetEndOffset() const { return StartOffset + NumBytes; } - - bool IsVmdk() const { return !IsZero && !IsFlat; }; - // if (IsOK && IsVmdk()), then VMDK header of this extent was read - - CExtent(): - IsOK(false), - IsArc(false), - NeedDeflate(false), - Unsupported(false), - IsZero(false), - IsFlat(false), - DescriptorOK(false), - HeadersError(false), - - ClusterBits(0), - ZeroSector(0), - - PosInArc(0), - - PhySize(0), - VirtSize(0), - - StartOffset(0), - NumBytes(0), - FlatOffset(0) - {} - - - HRESULT ReadForHeader(IInStream *stream, UInt64 sector, void *data, size_t numSectors); - HRESULT Open3(IInStream *stream, IArchiveOpenCallback *openCallback, - unsigned numVols, unsigned volIndex, UInt64 &complexity); - - HRESULT Seek(UInt64 offset) - { - PosInArc = offset; - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); - } - - HRESULT InitAndSeek() - { - if (Stream) - return Seek(0); - return S_OK; - } - - HRESULT Read(void *data, size_t *size) - { - HRESULT res = ReadStream(Stream, data, size); - PosInArc += *size; - return res; - } -}; - - -class CHandler: public CHandlerImg -{ - bool _isArc; - bool _unsupported; - bool _unsupportedSome; - bool _headerError; - bool _missingVol; - bool _isMultiVol; - bool _needDeflate; - - UInt64 _cacheCluster; - unsigned _cacheExtent; - CByteBuffer _cache; - CByteBuffer _cacheCompressed; - - unsigned _clusterBitsMax; - UInt64 _phySize; - - CObjectVector _extents; - - CBufInStream *_bufInStreamSpec; - CMyComPtr _bufInStream; - - CBufPtrSeqOutStream *_bufOutStreamSpec; - CMyComPtr _bufOutStream; - - NCompress::NZlib::CDecoder *_zlibDecoderSpec; - CMyComPtr _zlibDecoder; - - CByteBuffer _descriptorBuf; - CDescriptor _descriptor; - - UString _missingVolName; - - void InitAndSeekMain() - { - _virtPos = 0; - } - - virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback); - virtual void CloseAtError(); -public: - INTERFACE_IInArchive_Img(;) - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - - -STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= _size) - return S_OK; - { - UInt64 rem = _size - _virtPos; - if (size > rem) - size = (UInt32)rem; - if (size == 0) - return S_OK; - } - - unsigned extentIndex; - { - unsigned left = 0, right = _extents.Size(); - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (_virtPos < _extents[mid].StartOffset) - right = mid; - else - left = mid; - } - extentIndex = left; - } - - CExtent &extent = _extents[extentIndex]; - - { - const UInt64 vir = _virtPos - extent.StartOffset; - if (vir >= extent.NumBytes) - { - return E_FAIL; - /* - if (vir > extent.NumBytes) - _stream_dataError = true; - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - - { - const UInt64 rem = extent.NumBytes - vir; - if (size > rem) - size = (UInt32)rem; - } - - if (vir >= extent.VirtSize) - { - // if vmdk's VirtSize is smaller than VirtSize from main multi-volume descriptor - _stream_dataError = true; - return S_FALSE; - /* - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - - { - const UInt64 rem = extent.VirtSize - vir; - if (size > rem) - size = (UInt32)rem; - } - - if (extent.IsZero || !extent.IsOK || !extent.Stream || extent.Unsupported) - { - if (extent.Unsupported) - { - _stream_unsupportedMethod = true; - return S_FALSE; - } - if (!extent.IsOK || !extent.Stream) - { - _stream_unavailData = true; - return S_FALSE; - } - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } - - if (extent.IsFlat) - { - UInt64 offset = extent.FlatOffset + vir; - if (offset != extent.PosInArc) - { - RINOK(extent.Seek(offset)); - } - UInt32 size2 = 0; - HRESULT res = extent.Stream->Read(data, size, &size2); - if (res == S_OK && size2 == 0) - { - _stream_unavailData = true; - /* - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - // _stream_PackSize += size2; - extent.PosInArc += size2; - _virtPos += size2; - if (processedSize) - *processedSize = size2; - return res; - } - } - - - for (;;) - { - const UInt64 vir = _virtPos - extent.StartOffset; - const unsigned clusterBits = extent.ClusterBits; - const UInt64 cluster = vir >> clusterBits; - const size_t clusterSize = (size_t)1 << clusterBits; - const size_t lowBits = (size_t)vir & (clusterSize - 1); - { - size_t rem = clusterSize - lowBits; - if (size > rem) - size = (UInt32)rem; - } - - if (extentIndex == _cacheExtent && cluster == _cacheCluster) - { - memcpy(data, _cache + lowBits, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } - - const UInt64 high = cluster >> k_NumMidBits; - - if (high < extent.Tables.Size()) - { - const CByteBuffer &table = extent.Tables[(unsigned)high]; - - if (table.Size() != 0) - { - const size_t midBits = (size_t)cluster & ((1 << k_NumMidBits) - 1); - const Byte *p = (const Byte *)table + (midBits << 2); - const UInt32 v = Get32(p); - - if (v != 0 && v != extent.ZeroSector) - { - UInt64 offset = (UInt64)v << 9; - if (extent.NeedDeflate) - { - if (offset != extent.PosInArc) - { - // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); - RINOK(extent.Seek(offset)); - } - - const size_t kStartSize = 1 << 9; - { - size_t curSize = kStartSize; - RINOK(extent.Read(_cacheCompressed, &curSize)); - // _stream_PackSize += curSize; - if (curSize != kStartSize) - return S_FALSE; - } - - if (Get64(_cacheCompressed) != (cluster << (clusterBits - 9))) - return S_FALSE; - - UInt32 dataSize = Get32(_cacheCompressed + 8); - if (dataSize > ((UInt32)1 << 31)) - return S_FALSE; - - size_t dataSize2 = (size_t)dataSize + 12; - - if (dataSize2 > kStartSize) - { - dataSize2 = (dataSize2 + 511) & ~(size_t)511; - if (dataSize2 > _cacheCompressed.Size()) - return S_FALSE; - size_t curSize = dataSize2 - kStartSize; - const size_t curSize2 = curSize; - RINOK(extent.Read(_cacheCompressed + kStartSize, &curSize)); - // _stream_PackSize += curSize; - if (curSize != curSize2) - return S_FALSE; - } - - _bufInStreamSpec->Init(_cacheCompressed + 12, dataSize); - - _cacheCluster = (UInt64)(Int64)-1; - _cacheExtent = (unsigned)(int)-1; - - if (_cache.Size() < clusterSize) - return E_FAIL; - _bufOutStreamSpec->Init(_cache, clusterSize); - - // Do we need to use smaller block than clusterSize for last cluster? - UInt64 blockSize64 = clusterSize; - HRESULT res = _zlibDecoderSpec->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); - - /* - if (_bufOutStreamSpec->GetPos() != clusterSize) - { - _stream_dataError = true; - memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos()); - } - */ - - if (_bufOutStreamSpec->GetPos() != clusterSize - || _zlibDecoderSpec->GetInputProcessedSize() != dataSize) - { - _stream_dataError = true; - if (res == S_OK) - res = S_FALSE; - } - - RINOK(res); - - _cacheCluster = cluster; - _cacheExtent = extentIndex; - - continue; - /* - memcpy(data, _cache + lowBits, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - { - offset += lowBits; - if (offset != extent.PosInArc) - { - // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); - RINOK(extent.Seek(offset)); - } - UInt32 size2 = 0; - HRESULT res = extent.Stream->Read(data, size, &size2); - if (res == S_OK && size2 == 0) - { - _stream_unavailData = true; - /* - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - */ - } - extent.PosInArc += size2; - // _stream_PackSize += size2; - _virtPos += size2; - if (processedSize) - *processedSize = size2; - return res; - } - } - } - } - - memset(data, 0, size); - _virtPos += size; - if (processedSize) - *processedSize = size; - return S_OK; - } -} - - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize -}; - -static const Byte kArcProps[] = -{ - kpidNumVolumes, - kpidMethod, - kpidClusterSize, - kpidHeadersSize, - kpidId, - kpidName, - kpidComment -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - const CExtent *e = NULL; - const CDescriptor *desc = NULL; - - if (_isMultiVol) - desc = &_descriptor; - else if (_extents.Size() == 1) - { - e = &_extents[0]; - desc = &e->Descriptor; - } - - switch (propID) - { - case kpidMainSubfile: prop = (UInt32)0; break; - case kpidPhySize: if (_phySize != 0) prop = _phySize; break; - case kpidClusterSize: prop = (UInt32)((UInt32)1 << _clusterBitsMax); break; - case kpidHeadersSize: if (e) prop = (e->h.overHead << 9); break; - case kpidMethod: - { - AString s; - - if (desc && !desc->createType.IsEmpty()) - s = desc->createType; - - bool zlib = false; - bool marker = false; - int algo = -1; - - FOR_VECTOR (i, _extents) - { - const CExtent &extent = _extents[i]; - if (!extent.IsOK || !extent.IsVmdk()) - continue; - - const CHeader &h = extent.h; - - if (h.algo != 0) - { - if (h.algo == 1) - zlib = true; - else if (algo != (int)h.algo) - { - s.Add_Space_if_NotEmpty(); - char temp[16]; - ConvertUInt32ToString(h.algo, temp); - s += temp; - algo = h.algo; - } - } - - if (h.Is_Marker()) - marker = true; - } - - if (zlib) - { - s.Add_Space_if_NotEmpty(); - s += "zlib"; - } - - if (marker) - { - s.Add_Space_if_NotEmpty(); - s += "Marker"; - } - - if (!s.IsEmpty()) - prop = s; - break; - } - - case kpidComment: - { - if (e && e->DescriptorBuf.Size() != 0) - { - AString s; - s.SetFrom_CalcLen((const char *)(const Byte *)e->DescriptorBuf, (unsigned)e->DescriptorBuf.Size()); - if (!s.IsEmpty() && s.Len() <= (1 << 16)) - prop = s; - } - break; - } - - case kpidId: - if (desc && !desc->CID.IsEmpty()) - { - prop = desc->CID; - break; - } - - case kpidName: - { - if (!_isMultiVol && desc && desc->Extents.Size() == 1) - { - const CExtentInfo &ei = desc->Extents[0]; - if (!ei.FileName.IsEmpty()) - { - UString u; - CDescriptor::GetUnicodeName(ei.FileName, u); - if (!u.IsEmpty()) - prop = u; - } - } - break; - } - - case kpidNumVolumes: if (_isMultiVol) prop = (UInt32)_extents.Size(); break; - - case kpidError: - { - if (_missingVol || !_missingVolName.IsEmpty()) - { - UString s; - s.SetFromAscii("Missing volume : "); - if (!_missingVolName.IsEmpty()) - s += _missingVolName; - prop = s; - } - break; - } - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod; - if (_headerError) v |= kpv_ErrorFlags_HeadersError; - // if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd; - 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: - { - UInt64 packSize = 0; - FOR_VECTOR (i, _extents) - { - const CExtent &e = _extents[i]; - if (!e.IsOK) - continue; - if (e.IsVmdk() && !_isMultiVol) - { - UInt64 ov = (e.h.overHead << 9); - if (e.PhySize >= ov) - packSize += e.PhySize - ov; - } - else - packSize += e.PhySize; - } - prop = packSize; - break; - } - case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -static int inline GetLog(UInt64 num) -{ - for (int i = 0; i < 64; i++) - if (((UInt64)1 << i) == num) - return i; - return -1; -} - - -HRESULT CExtent::ReadForHeader(IInStream *stream, UInt64 sector, void *data, size_t numSectors) -{ - sector <<= 9; - RINOK(stream->Seek(sector, STREAM_SEEK_SET, NULL)); - size_t size = numSectors << 9; - RINOK(ReadStream_FALSE(stream, data, size)); - UInt64 end = sector + size; - if (PhySize < end) - PhySize = end; - return S_OK; -} - - -void CHandler::CloseAtError() -{ - _extents.Clear(); - CHandlerImg::CloseAtError(); -} - - -HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback) -{ - const unsigned kSectoreSize = 512; - Byte buf[kSectoreSize]; - size_t headerSize = kSectoreSize; - RINOK(ReadStream(stream, buf, &headerSize)); - - if (headerSize < sizeof(k_Signature)) - return S_FALSE; - - CMyComPtr volumeCallback; - - if (memcmp(buf, k_Signature, sizeof(k_Signature)) != 0) - { - const char *kSignature_Descriptor = "# Disk DescriptorFile"; - const size_t k_SigDesc_Size = strlen(kSignature_Descriptor); - if (headerSize < k_SigDesc_Size) - return S_FALSE; - if (memcmp(buf, kSignature_Descriptor, k_SigDesc_Size) != 0) - return S_FALSE; - - UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - if (endPos > (1 << 20)) - return S_FALSE; - const size_t numBytes = (size_t)endPos; - _descriptorBuf.Alloc(numBytes); - RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, _descriptorBuf, numBytes)); - - if (!_descriptor.Parse(_descriptorBuf, _descriptorBuf.Size())) - return S_FALSE; - _isMultiVol = true; - _isArc = true; - _phySize = numBytes; - if (_descriptor.IsThere_Parent()) - _unsupported = true; - - if (openCallback) - { - openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); - } - if (!volumeCallback) - { - _unsupported = true; - return E_NOTIMPL; - } - - /* - UInt64 totalVirtSize = 0; - FOR_VECTOR (i, _descriptor.Extents) - { - const CExtentInfo &ei = _descriptor.Extents[i]; - if (ei.NumSectors >= ((UInt64)1 << (63 - 9))) - return S_FALSE; - totalVirtSize += ei.NumSectors; - if (totalVirtSize >= ((UInt64)1 << (63 - 9))) - return S_FALSE; - } - totalVirtSize <<= 9; - */ - - if (_descriptor.Extents.Size() > 1) - { - const UInt64 numFiles = _descriptor.Extents.Size(); - RINOK(openCallback->SetTotal(&numFiles, NULL)); - } - } - - UInt64 complexity = 0; - - for (;;) - { - CExtent *e = NULL; - CMyComPtr nextStream; - - if (_isMultiVol) - { - const unsigned extentIndex = _extents.Size(); - if (extentIndex >= _descriptor.Extents.Size()) - break; - const CExtentInfo &ei = _descriptor.Extents[extentIndex]; - e = &_extents.AddNew(); - e->StartOffset = 0; - if (ei.NumSectors >= ((UInt64)1 << (62 - 9)) || - ei.StartSector >= ((UInt64)1 << (62 - 9))) - return S_FALSE; - e->NumBytes = ei.NumSectors << 9; - e->IsZero = ei.IsType_ZERO(); - if (extentIndex != 0) - e->StartOffset = _extents[extentIndex - 1].GetEndOffset(); - if (e->GetEndOffset() < e->StartOffset) - return S_FALSE; - - e->VirtSize = e->NumBytes; - if (e->IsZero) - { - e->IsOK = true; - continue; - } - - e->IsFlat = ei.IsType_Flat(); - e->FlatOffset = ei.StartSector << 9; - - UString u; - CDescriptor::GetUnicodeName(ei.FileName, u); - if (u.IsEmpty()) - { - _missingVol = true; - continue; - } - - HRESULT result = volumeCallback->GetStream(u, &nextStream); - - if (result != S_OK && result != S_FALSE) - return result; - - if (!nextStream || result != S_OK) - { - if (_missingVolName.IsEmpty()) - _missingVolName = u; - _missingVol = true; - continue; - } - - if (e->IsFlat) - { - e->IsOK = true; - e->Stream = nextStream; - e->PhySize = e->NumBytes; - continue; - } - - stream = nextStream; - - headerSize = kSectoreSize; - RINOK(ReadStream(stream, buf, &headerSize)); - - if (headerSize != kSectoreSize) - continue; - if (memcmp(buf, k_Signature, sizeof(k_Signature)) != 0) - continue; - } - else - { - if (headerSize != kSectoreSize) - return S_FALSE; - e = &_extents.AddNew(); - e->StartOffset = 0; - } - - HRESULT res = S_FALSE; - if (e->h.Parse(buf)) - res = e->Open3(stream, openCallback, _isMultiVol ? _descriptor.Extents.Size() : 1, _extents.Size() - 1, complexity); - - if (!_isMultiVol) - { - _isArc = e->IsArc; - _phySize = e->PhySize; - _unsupported = e->Unsupported; - } - - if (e->Unsupported) - _unsupportedSome = true; - if (e->HeadersError) - _headerError = true; - - if (res != S_OK) - { - if (res != S_FALSE) - return res; - if (!_isMultiVol) - return res; - continue; - } - - e->Stream = stream; - e->IsOK = true; - - if (!_isMultiVol) - { - e->NumBytes = e->VirtSize; - break; - } - - if (e->NumBytes != e->VirtSize) - _headerError = true; - } - - if (!_extents.IsEmpty()) - _size = _extents.Back().GetEndOffset(); - - _needDeflate = false; - _clusterBitsMax = 0; - - unsigned numOKs = 0; - unsigned numUnsupported = 0; - - FOR_VECTOR (i, _extents) - { - const CExtent &e = _extents[i]; - if (e.Unsupported) - numUnsupported++; - if (!e.IsOK) - continue; - numOKs++; - if (e.IsVmdk()) - { - if (e.NeedDeflate) - _needDeflate = true; - if (_clusterBitsMax < e.ClusterBits) - _clusterBitsMax = e.ClusterBits; - } - } - - if (numUnsupported != 0 && numUnsupported == _extents.Size()) - _unsupported = true; - - return S_OK; -} - - -HRESULT CExtent::Open3(IInStream *stream, IArchiveOpenCallback *openCallback, - unsigned numVols, unsigned volIndex, UInt64 &complexity) -{ - if (h.descriptorSize != 0) - { - if (h.descriptorOffset == 0 || - h.descriptorSize > (1 << 10)) - return S_FALSE; - DescriptorBuf.Alloc((size_t)h.descriptorSize << 9); - RINOK(ReadForHeader(stream, h.descriptorOffset, DescriptorBuf, (size_t)h.descriptorSize)); - if (h.descriptorOffset == 1 && h.Is_Marker() && Get64(DescriptorBuf) == 0) - { - // We check data as end marker. - // and if probably it's footer's copy of header, we don't want to open it. - return S_FALSE; - } - - DescriptorOK = Descriptor.Parse(DescriptorBuf, DescriptorBuf.Size()); - if (!DescriptorOK) - HeadersError = true; - if (Descriptor.IsThere_Parent()) - Unsupported = true; - } - - if (h.gdOffset == (UInt64)(Int64)-1) - { - // Grain Dir is at end of file - UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - if ((endPos & 511) != 0) - return S_FALSE; - - const size_t kEndSize = 512 * 3; - Byte buf2[kEndSize]; - if (endPos < kEndSize) - return S_FALSE; - RINOK(stream->Seek(endPos - kEndSize, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(stream, buf2, kEndSize)); - - CHeader h2; - if (!h2.Parse(buf2 + 512)) - return S_FALSE; - if (!h.IsSameImageFor(h2)) - return S_FALSE; - - h = h2; - - CMarker m; - m.Parse(buf2); - if (m.NumSectors != 1 || m.SpecSize != 0 || m.Type != k_Marker_FOOTER) - return S_FALSE; - m.Parse(buf2 + 512 * 2); - if (m.NumSectors != 0 || m.SpecSize != 0 || m.Type != k_Marker_END_OF_STREAM) - return S_FALSE; - PhySize = endPos; - } - - int grainSize_Log = GetLog(h.grainSize); - if (grainSize_Log < 3 || grainSize_Log > 30 - 9) // grain size must be >= 4 KB - return S_FALSE; - if (h.capacity >= ((UInt64)1 << (63 - 9))) - return S_FALSE; - if (h.overHead >= ((UInt64)1 << (63 - 9))) - return S_FALSE; - - IsArc = true; - ClusterBits = (9 + grainSize_Log); - VirtSize = h.capacity << 9; - NeedDeflate = (h.algo >= 1); - - if (h.Is_Compressed() ? (h.algo > 1 || !h.Is_Marker()) : (h.algo != 0)) - { - Unsupported = true; - PhySize = 0; - return S_FALSE; - } - - { - UInt64 overHeadBytes = h.overHead << 9; - if (PhySize < overHeadBytes) - PhySize = overHeadBytes; - } - - ZeroSector = 0; - if (h.Is_ZeroGrain()) - ZeroSector = 1; - - const UInt64 numSectorsPerGde = (UInt64)1 << (grainSize_Log + k_NumMidBits); - const UInt64 numGdeEntries = (h.capacity + numSectorsPerGde - 1) >> (grainSize_Log + k_NumMidBits); - CByteBuffer table; - - if (numGdeEntries != 0) - { - if (h.gdOffset == 0) - return S_FALSE; - - size_t numSectors = (size_t)((numGdeEntries + ((1 << (9 - 2)) - 1)) >> (9 - 2)); - size_t t1SizeBytes = numSectors << 9; - if ((t1SizeBytes >> 2) < numGdeEntries) - return S_FALSE; - table.Alloc(t1SizeBytes); - - if (h.Is_Marker()) - { - Byte buf2[1 << 9]; - if (ReadForHeader(stream, h.gdOffset - 1, buf2, 1) != S_OK) - return S_FALSE; - { - CMarker m; - m.Parse(buf2); - if (m.Type != k_Marker_GRAIN_DIR - || m.NumSectors != numSectors - || m.SpecSize != 0) - return S_FALSE; - } - } - - RINOK(ReadForHeader(stream, h.gdOffset, table, numSectors)); - } - - const size_t clusterSize = (size_t)1 << ClusterBits; - - const UInt64 complexityStart = complexity; - - if (openCallback) - { - complexity += (UInt64)numGdeEntries << (k_NumMidBits + 2); - { - const UInt64 numVols2 = numVols; - RINOK(openCallback->SetTotal((numVols == 1) ? NULL : &numVols2, &complexity)); - } - if (numVols != 1) - { - const UInt64 volIndex2 = volIndex; - RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &complexityStart)); - } - } - - UInt64 lastSector = 0; - UInt64 lastVirtCluster = 0; - size_t numProcessed_Prev = 0; - - for (size_t i = 0; i < numGdeEntries; i++) - { - const size_t k_NumSectors = (size_t)1 << (k_NumMidBits - 9 + 2); - const size_t k_NumMidItems = (size_t)1 << k_NumMidBits; - - CByteBuffer &buf = Tables.AddNew(); - - { - const UInt32 v = Get32((const Byte *)table + (size_t)i * 4); - if (v == 0 || v == ZeroSector) - continue; - if (openCallback && (i - numProcessed_Prev) >= 1024) - { - const UInt64 comp = complexityStart + ((UInt64)i << (k_NumMidBits + 2)); - const UInt64 volIndex2 = volIndex; - RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &comp)); - numProcessed_Prev = i; - } - - if (h.Is_Marker()) - { - Byte buf2[1 << 9]; - if (ReadForHeader(stream, v - 1, buf2, 1) != S_OK) - return S_FALSE; - { - CMarker m; - m.Parse(buf2); - if (m.Type != k_Marker_GRAIN_TABLE - || m.NumSectors != k_NumSectors - || m.SpecSize != 0) - return S_FALSE; - } - } - - buf.Alloc(k_NumMidItems * 4); - RINOK(ReadForHeader(stream, v, buf, k_NumSectors)); - } - - for (size_t k = 0; k < k_NumMidItems; k++) - { - const UInt32 v = Get32((const Byte *)buf + (size_t)k * 4); - if (v == 0 || v == ZeroSector) - continue; - if (v < h.overHead) - return S_FALSE; - if (lastSector < v) - { - lastSector = v; - if (NeedDeflate) - lastVirtCluster = ((UInt64)i << k_NumMidBits) + k; - } - } - } - - if (!NeedDeflate) - { - UInt64 end = ((UInt64)lastSector << 9) + clusterSize; - if (PhySize < end) - PhySize = end; - } - else if (lastSector != 0) - { - Byte buf[1 << 9]; - if (ReadForHeader(stream, lastSector, buf, 1) == S_OK) - { - UInt64 lba = Get64(buf); - if (lba == (lastVirtCluster << (ClusterBits - 9))) - { - UInt32 dataSize = Get32(buf + 8); - size_t dataSize2 = (size_t)dataSize + 12; - dataSize2 = (dataSize2 + 511) & ~(size_t)511; - UInt64 end = ((UInt64)lastSector << 9) + dataSize2; - if (PhySize < end) - PhySize = end; - } - } - } - - return S_OK; -} - - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - _size = 0; - - _cacheCluster = (UInt64)(Int64)-1; - _cacheExtent = (unsigned)(int)-1; - - _clusterBitsMax = 0; - - _isArc = false; - _unsupported = false; - _unsupportedSome = false; - _headerError = false; - _missingVol = false; - _isMultiVol = false; - _needDeflate = false; - - _missingVolName.Empty(); - - _descriptorBuf.Free(); - _descriptor.Clear(); - - _imgExt = NULL; - Stream.Release(); // Stream vriable is unused - _extents.Clear(); - return S_OK; -} - - -STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - *stream = 0; - - if (_unsupported) - return S_FALSE; - - ClearStreamVars(); - // _stream_UsePackSize = true; - - if (_needDeflate) - { - if (!_bufInStream) - { - _bufInStreamSpec = new CBufInStream; - _bufInStream = _bufInStreamSpec; - } - - if (!_bufOutStream) - { - _bufOutStreamSpec = new CBufPtrSeqOutStream(); - _bufOutStream = _bufOutStreamSpec; - } - - if (!_zlibDecoder) - { - _zlibDecoderSpec = new NCompress::NZlib::CDecoder; - _zlibDecoder = _zlibDecoderSpec; - } - - const size_t clusterSize = (size_t)1 << _clusterBitsMax; - _cache.AllocAtLeast(clusterSize); - _cacheCompressed.AllocAtLeast(clusterSize * 2); - } - - FOR_VECTOR (i, _extents) - { - RINOK(_extents[i].InitAndSeek()); - } - - CMyComPtr streamTemp = this; - InitAndSeekMain(); - *stream = streamTemp.Detach(); - return S_OK; - COM_TRY_END -} - - -REGISTER_ARC_I( - "VMDK", "vmdk", NULL, 0xC8, - k_Signature, - 0, - 0, - NULL) - -}} +// VmdkHandler.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/StringConvert.h" +#include "../../Common/StringToInt.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/ZlibDecoder.h" + +#include "HandlerCont.h" + +using namespace NWindows; + +namespace NArchive { +namespace NVmdk { + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define LE_16(offs, dest) dest = Get16(p + (offs)) +#define LE_32(offs, dest) dest = Get32(p + (offs)) +#define LE_64(offs, dest) dest = Get64(p + (offs)) + + +static const Byte k_Signature[] = { 'K', 'D', 'M', 'V' }; + +static const UInt32 k_Flags_NL = (UInt32)1 << 0; +// static const UInt32 k_Flags_RGD = (UInt32)1 << 1; +static const UInt32 k_Flags_ZeroGrain = (UInt32)1 << 2; +static const UInt32 k_Flags_Compressed = (UInt32)1 << 16; +static const UInt32 k_Flags_Marker = (UInt32)1 << 17; + +static const unsigned k_NumMidBits = 9; // num bits for index in Grain Table + +struct CHeader +{ + UInt32 flags; + UInt32 version; + + UInt64 capacity; + UInt64 grainSize; + UInt64 descriptorOffset; + UInt64 descriptorSize; + + UInt32 numGTEsPerGT; + UInt16 algo; + // Byte uncleanShutdown; + // UInt64 rgdOffset; + UInt64 gdOffset; + UInt64 overHead; + + bool Is_NL() const { return (flags & k_Flags_NL) != 0; } + bool Is_ZeroGrain() const { return (flags & k_Flags_ZeroGrain) != 0; } + bool Is_Compressed() const { return (flags & k_Flags_Compressed) != 0; } + bool Is_Marker() const { return (flags & k_Flags_Marker) != 0; } + + bool Parse(const Byte *p); + + bool IsSameImageFor(const CHeader &h) const + { + return flags == h.flags + && version == h.version + && capacity == h.capacity + && grainSize == h.grainSize + && algo == h.algo; + } +}; + +bool CHeader::Parse(const Byte *p) +{ + if (memcmp(p, k_Signature, sizeof(k_Signature)) != 0) + return false; + + LE_32 (0x04, version); + LE_32 (0x08, flags); + LE_64 (0x0C, capacity); + LE_64 (0x14, grainSize); + LE_64 (0x1C, descriptorOffset); + LE_64 (0x24, descriptorSize); + LE_32 (0x2C, numGTEsPerGT); + // LE_64 (0x30, rgdOffset); + LE_64 (0x38, gdOffset); + LE_64 (0x40, overHead); + // uncleanShutdown = buf[0x48]; + LE_16(0x4D, algo); + + if (Is_NL() && Get32(p + 0x49) != 0x0A0D200A) // do we need Is_NL() check here? + return false; + + return (numGTEsPerGT == (1 << k_NumMidBits)) && (version <= 3); +} + + +enum +{ + k_Marker_END_OF_STREAM = 0, + k_Marker_GRAIN_TABLE = 1, + k_Marker_GRAIN_DIR = 2, + k_Marker_FOOTER = 3 +}; + +struct CMarker +{ + UInt64 NumSectors; + UInt32 SpecSize; // = 0 for metadata sectors + UInt32 Type; + + void Parse(const Byte *p) + { + LE_64 (0, NumSectors); + LE_32 (8, SpecSize); + LE_32 (12, Type); + } +}; + + +static bool Str_to_ValName(const AString &s, AString &name, AString &val) +{ + name.Empty(); + val.Empty(); + int qu = s.Find('"'); + int eq = s.Find('='); + if (eq < 0 || (qu >= 0 && eq > qu)) + return false; + name.SetFrom(s.Ptr(), eq); + name.Trim(); + val = s.Ptr(eq + 1); + val.Trim(); + return true; +} + +static inline bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t'); +} + +static const char *SkipSpaces(const char *s) +{ + for (;; s++) + { + char c = *s; + if (c == 0 || !IsSpaceChar(c)) + return s; + } +} + +#define SKIP_SPACES(s) s = SkipSpaces(s); + +static const char *GetNextWord(const char *s, AString &dest) +{ + dest.Empty(); + SKIP_SPACES(s) + const char *start = s; + for (;; s++) + { + char c = *s; + if (c == 0 || IsSpaceChar(c)) + { + dest.SetFrom(start, (unsigned)(s - start)); + return s; + } + } +} + +static const char *GetNextNumber(const char *s, UInt64 &val) +{ + SKIP_SPACES(s) + if (*s == 0) + return s; + const char *end; + val = ConvertStringToUInt64(s, &end); + char c = *end; + if (c != 0 && !IsSpaceChar(c)) + return NULL; + return end; +} + + +struct CExtentInfo +{ + AString Access; // RW, RDONLY, or NOACCESS + UInt64 NumSectors; // 512 bytes sectors + AString Type; // FLAT, SPARSE, ZERO, VMFS, VMFSSPARSE, VMFSRDM, VMFSRAW + AString FileName; + UInt64 StartSector; // used for FLAT + + // for VMWare Player 9: + // PartitionUUID + // DeviceIdentifier + + bool IsType_ZERO() const { return Type.IsEqualTo("ZERO"); } + // bool IsType_FLAT() const { return Type.IsEqualTo("FLAT"); } + bool IsType_Flat() const + { return Type.IsEqualTo("FLAT") + || Type.IsEqualTo("VMFS") + || Type.IsEqualTo("VMFSRAW"); } + + bool Parse(const char *s); +}; + +bool CExtentInfo::Parse(const char *s) +{ + NumSectors = 0; + StartSector = 0; + Access.Empty(); + Type.Empty(); + FileName.Empty(); + + s = GetNextWord(s, Access); + s = GetNextNumber(s, NumSectors); + if (!s) + return false; + s = GetNextWord(s, Type); + + if (Type.IsEmpty()) + return false; + + SKIP_SPACES(s) + + if (IsType_ZERO()) + return (*s == 0); + + if (*s != '\"') + return false; + s++; + { + const char *s2 = strchr(s, '\"'); + if (!s2) + return false; + FileName.SetFrom(s, (unsigned)(s2 - s)); + s = s2 + 1; + } + SKIP_SPACES(s) + if (*s == 0) + return true; + + s = GetNextNumber(s, StartSector); + if (!s) + return false; + return true; + // SKIP_SPACES(s); + // return (*s == 0); +} + + +struct CDescriptor +{ + AString CID; + AString parentCID; + AString createType; + // AString encoding; // UTF-8, windows-1252 - default is UTF-8 + + CObjectVector Extents; + + static void GetUnicodeName(const AString &s, UString &res) + { + if (!ConvertUTF8ToUnicode(s, res)) + MultiByteToUnicodeString2(res, s); + } + + void Clear() + { + CID.Empty(); + parentCID.Empty(); + createType.Empty(); + Extents.Clear(); + } + + bool IsThere_Parent() const + { + return !parentCID.IsEmpty() && !parentCID.IsEqualTo_Ascii_NoCase("ffffffff"); + } + + bool Parse(const Byte *p, size_t size); +}; + + +bool CDescriptor::Parse(const Byte *p, size_t size) +{ + Clear(); + + AString s; + AString name; + AString val; + + for (;;) + { + Byte c = 0; + if (size != 0) + { + size--; + c = *p++; + } + if (c == 0 || c == 0xA || c == 0xD) + { + if (!s.IsEmpty() && s[0] != '#') + { + if (Str_to_ValName(s, name, val)) + { + if (name.IsEqualTo_Ascii_NoCase("CID")) + CID = val; + else if (name.IsEqualTo_Ascii_NoCase("parentCID")) + parentCID = val; + else if (name.IsEqualTo_Ascii_NoCase("createType")) + createType = val; + } + else + { + CExtentInfo ei; + if (!ei.Parse(s)) + return false; + Extents.Add(ei); + } + } + + s.Empty(); + if (c == 0) + return true; + } + else + s += (char)c; + } +} + + +struct CExtent +{ + bool IsOK; + bool IsArc; + bool NeedDeflate; + bool Unsupported; + bool IsZero; + bool IsFlat; + bool DescriptorOK; + bool HeadersError; + + unsigned ClusterBits; + UInt32 ZeroSector; + + CObjectVector Tables; + + CMyComPtr Stream; + UInt64 PosInArc; + + UInt64 PhySize; + UInt64 VirtSize; // from vmdk header of volume + + UInt64 StartOffset; // virtual offset of this extent + UInt64 NumBytes; // from main descriptor, if multi-vol + UInt64 FlatOffset; // in Stream + + CByteBuffer DescriptorBuf; + CDescriptor Descriptor; + + CHeader h; + + UInt64 GetEndOffset() const { return StartOffset + NumBytes; } + + bool IsVmdk() const { return !IsZero && !IsFlat; } + // if (IsOK && IsVmdk()), then VMDK header of this extent was read + + CExtent(): + IsOK(false), + IsArc(false), + NeedDeflate(false), + Unsupported(false), + IsZero(false), + IsFlat(false), + DescriptorOK(false), + HeadersError(false), + + ClusterBits(0), + ZeroSector(0), + + PosInArc(0), + + PhySize(0), + VirtSize(0), + + StartOffset(0), + NumBytes(0), + FlatOffset(0) + {} + + + HRESULT ReadForHeader(IInStream *stream, UInt64 sector, void *data, size_t numSectors); + HRESULT Open3(IInStream *stream, IArchiveOpenCallback *openCallback, + unsigned numVols, unsigned volIndex, UInt64 &complexity); + + HRESULT Seek(UInt64 offset) + { + PosInArc = offset; + return InStream_SeekSet(Stream, offset); + } + + HRESULT InitAndSeek() + { + if (Stream) + return Seek(0); + return S_OK; + } + + HRESULT Read(void *data, size_t *size) + { + HRESULT res = ReadStream(Stream, data, size); + PosInArc += *size; + return res; + } +}; + + +Z7_class_CHandler_final: public CHandlerImg +{ + bool _isArc; + bool _unsupported; + bool _unsupportedSome; + bool _headerError; + bool _missingVol; + bool _isMultiVol; + bool _needDeflate; + + UInt64 _cacheCluster; + unsigned _cacheExtent; + CByteBuffer _cache; + CByteBuffer _cacheCompressed; + + unsigned _clusterBitsMax; + UInt64 _phySize; + + CObjectVector _extents; + + CBufInStream *_bufInStreamSpec; + CMyComPtr _bufInStream; + + CBufPtrSeqOutStream *_bufOutStreamSpec; + CMyComPtr _bufOutStream; + + NCompress::NZlib::CDecoder *_zlibDecoderSpec; + CMyComPtr _zlibDecoder; + + CByteBuffer _descriptorBuf; + CDescriptor _descriptor; + + UString _missingVolName; + + void InitAndSeekMain() + { + _virtPos = 0; + } + + virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) Z7_override; + virtual void CloseAtError() Z7_override; +public: + Z7_IFACE_COM7_IMP(IInArchive_Img) + + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) +}; + + +Z7_COM7F_IMF(CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= _size) + return S_OK; + { + UInt64 rem = _size - _virtPos; + if (size > rem) + size = (UInt32)rem; + if (size == 0) + return S_OK; + } + + unsigned extentIndex; + { + unsigned left = 0, right = _extents.Size(); + for (;;) + { + unsigned mid = (left + right) / 2; + if (mid == left) + break; + if (_virtPos < _extents[mid].StartOffset) + right = mid; + else + left = mid; + } + extentIndex = left; + } + + CExtent &extent = _extents[extentIndex]; + + { + const UInt64 vir = _virtPos - extent.StartOffset; + if (vir >= extent.NumBytes) + { + return E_FAIL; + /* + if (vir > extent.NumBytes) + _stream_dataError = true; + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + */ + } + + { + const UInt64 rem = extent.NumBytes - vir; + if (size > rem) + size = (UInt32)rem; + } + + if (vir >= extent.VirtSize) + { + // if vmdk's VirtSize is smaller than VirtSize from main multi-volume descriptor + _stream_dataError = true; + return S_FALSE; + /* + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + */ + } + + { + const UInt64 rem = extent.VirtSize - vir; + if (size > rem) + size = (UInt32)rem; + } + + if (extent.IsZero || !extent.IsOK || !extent.Stream || extent.Unsupported) + { + if (extent.Unsupported) + { + _stream_unsupportedMethod = true; + return S_FALSE; + } + if (!extent.IsOK || !extent.Stream) + { + _stream_unavailData = true; + return S_FALSE; + } + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + if (extent.IsFlat) + { + UInt64 offset = extent.FlatOffset + vir; + if (offset != extent.PosInArc) + { + RINOK(extent.Seek(offset)) + } + UInt32 size2 = 0; + HRESULT res = extent.Stream->Read(data, size, &size2); + if (res == S_OK && size2 == 0) + { + _stream_unavailData = true; + /* + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + */ + } + // _stream_PackSize += size2; + extent.PosInArc += size2; + _virtPos += size2; + if (processedSize) + *processedSize = size2; + return res; + } + } + + + for (;;) + { + const UInt64 vir = _virtPos - extent.StartOffset; + const unsigned clusterBits = extent.ClusterBits; + const UInt64 cluster = vir >> clusterBits; + const size_t clusterSize = (size_t)1 << clusterBits; + const size_t lowBits = (size_t)vir & (clusterSize - 1); + { + size_t rem = clusterSize - lowBits; + if (size > rem) + size = (UInt32)rem; + } + + if (extentIndex == _cacheExtent && cluster == _cacheCluster) + { + memcpy(data, _cache + lowBits, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + const UInt64 high = cluster >> k_NumMidBits; + + if (high < extent.Tables.Size()) + { + const CByteBuffer &table = extent.Tables[(unsigned)high]; + + if (table.Size() != 0) + { + const size_t midBits = (size_t)cluster & ((1 << k_NumMidBits) - 1); + const Byte *p = (const Byte *)table + (midBits << 2); + const UInt32 v = Get32(p); + + if (v != 0 && v != extent.ZeroSector) + { + UInt64 offset = (UInt64)v << 9; + if (extent.NeedDeflate) + { + if (offset != extent.PosInArc) + { + // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); + RINOK(extent.Seek(offset)) + } + + const size_t kStartSize = 1 << 9; + { + size_t curSize = kStartSize; + RINOK(extent.Read(_cacheCompressed, &curSize)) + // _stream_PackSize += curSize; + if (curSize != kStartSize) + return S_FALSE; + } + + if (Get64(_cacheCompressed) != (cluster << (clusterBits - 9))) + return S_FALSE; + + UInt32 dataSize = Get32(_cacheCompressed + 8); + if (dataSize > ((UInt32)1 << 31)) + return S_FALSE; + + size_t dataSize2 = (size_t)dataSize + 12; + + if (dataSize2 > kStartSize) + { + dataSize2 = (dataSize2 + 511) & ~(size_t)511; + if (dataSize2 > _cacheCompressed.Size()) + return S_FALSE; + size_t curSize = dataSize2 - kStartSize; + const size_t curSize2 = curSize; + RINOK(extent.Read(_cacheCompressed + kStartSize, &curSize)) + // _stream_PackSize += curSize; + if (curSize != curSize2) + return S_FALSE; + } + + _bufInStreamSpec->Init(_cacheCompressed + 12, dataSize); + + _cacheCluster = (UInt64)(Int64)-1; + _cacheExtent = (unsigned)(int)-1; + + if (_cache.Size() < clusterSize) + return E_FAIL; + _bufOutStreamSpec->Init(_cache, clusterSize); + + // Do we need to use smaller block than clusterSize for last cluster? + const UInt64 blockSize64 = clusterSize; + HRESULT res = _zlibDecoder->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL); + + /* + if (_bufOutStreamSpec->GetPos() != clusterSize) + { + _stream_dataError = true; + memset(_cache + _bufOutStreamSpec->GetPos(), 0, clusterSize - _bufOutStreamSpec->GetPos()); + } + */ + + if (_bufOutStreamSpec->GetPos() != clusterSize + || _zlibDecoderSpec->GetInputProcessedSize() != dataSize) + { + _stream_dataError = true; + if (res == S_OK) + res = S_FALSE; + } + + RINOK(res) + + _cacheCluster = cluster; + _cacheExtent = extentIndex; + + continue; + /* + memcpy(data, _cache + lowBits, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + */ + } + { + offset += lowBits; + if (offset != extent.PosInArc) + { + // printf("\n%12x %12x\n", (unsigned)offset, (unsigned)(offset - extent.PosInArc)); + RINOK(extent.Seek(offset)) + } + UInt32 size2 = 0; + HRESULT res = extent.Stream->Read(data, size, &size2); + if (res == S_OK && size2 == 0) + { + _stream_unavailData = true; + /* + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + */ + } + extent.PosInArc += size2; + // _stream_PackSize += size2; + _virtPos += size2; + if (processedSize) + *processedSize = size2; + return res; + } + } + } + } + + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } +} + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidNumVolumes, + kpidTotalPhySize, + kpidMethod, + kpidClusterSize, + kpidHeadersSize, + kpidId, + kpidName, + kpidComment +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CExtent *e = NULL; + const CDescriptor *desc = NULL; + + if (_isMultiVol) + desc = &_descriptor; + else if (_extents.Size() == 1) + { + e = &_extents[0]; + desc = &e->Descriptor; + } + + switch (propID) + { + case kpidMainSubfile: prop = (UInt32)0; break; + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + case kpidTotalPhySize: + { + UInt64 sum = _phySize; + if (_isMultiVol) + { + FOR_VECTOR (i, _extents) + sum += _extents[i].PhySize; + } + prop = sum; + break; + } + case kpidClusterSize: prop = (UInt32)((UInt32)1 << _clusterBitsMax); break; + case kpidHeadersSize: if (e) prop = (e->h.overHead << 9); break; + case kpidMethod: + { + AString s; + + if (desc && !desc->createType.IsEmpty()) + s = desc->createType; + + bool zlib = false; + bool marker = false; + Int32 algo = -1; + + FOR_VECTOR (i, _extents) + { + const CExtent &extent = _extents[i]; + if (!extent.IsOK || !extent.IsVmdk()) + continue; + + const CHeader &h = extent.h; + + if (h.algo != 0) + { + if (h.algo == 1) + zlib = true; + else if (algo != h.algo) + { + s.Add_Space_if_NotEmpty(); + s.Add_UInt32(h.algo); + algo = h.algo; + } + } + + if (h.Is_Marker()) + marker = true; + } + + if (zlib) + s.Add_OptSpaced("zlib"); + + if (marker) + s.Add_OptSpaced("Marker"); + + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidComment: + { + if (e && e->DescriptorBuf.Size() != 0) + { + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)e->DescriptorBuf, (unsigned)e->DescriptorBuf.Size()); + if (!s.IsEmpty() && s.Len() <= (1 << 16)) + prop = s; + } + break; + } + + case kpidId: + { + if (desc && !desc->CID.IsEmpty()) + { + prop = desc->CID; + } + break; + } + + case kpidName: + { + if (!_isMultiVol && desc && desc->Extents.Size() == 1) + { + const CExtentInfo &ei = desc->Extents[0]; + if (!ei.FileName.IsEmpty()) + { + UString u; + CDescriptor::GetUnicodeName(ei.FileName, u); + if (!u.IsEmpty()) + prop = u; + } + } + break; + } + + case kpidNumVolumes: if (_isMultiVol) prop = (UInt32)_extents.Size(); break; + + case kpidError: + { + if (_missingVol || !_missingVolName.IsEmpty()) + { + UString s ("Missing volume : "); + if (!_missingVolName.IsEmpty()) + s += _missingVolName; + prop = s; + } + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (_unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; + if (_unsupportedSome) v |= kpv_ErrorFlags_UnsupportedMethod; + if (_headerError) v |= kpv_ErrorFlags_HeadersError; + // if (_missingVol) v |= kpv_ErrorFlags_UnexpectedEnd; + if (v != 0) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + switch (propID) + { + case kpidSize: prop = _size; break; + case kpidPackSize: + { + UInt64 packSize = 0; + FOR_VECTOR (i, _extents) + { + const CExtent &e = _extents[i]; + if (!e.IsOK) + continue; + if (e.IsVmdk() && !_isMultiVol) + { + UInt64 ov = (e.h.overHead << 9); + if (e.PhySize >= ov) + packSize += e.PhySize - ov; + } + else + packSize += e.PhySize; + } + prop = packSize; + break; + } + case kpidExtension: prop = (_imgExt ? _imgExt : "img"); break; + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +static int inline GetLog(UInt64 num) +{ + for (int i = 0; i < 64; i++) + if (((UInt64)1 << i) == num) + return i; + return -1; +} + + +HRESULT CExtent::ReadForHeader(IInStream *stream, UInt64 sector, void *data, size_t numSectors) +{ + sector <<= 9; + RINOK(InStream_SeekSet(stream, sector)) + size_t size = numSectors << 9; + RINOK(ReadStream_FALSE(stream, data, size)) + UInt64 end = sector + size; + if (PhySize < end) + PhySize = end; + return S_OK; +} + + +void CHandler::CloseAtError() +{ + _extents.Clear(); + CHandlerImg::CloseAtError(); +} + + +static const char * const kSignature_Descriptor = "# Disk DescriptorFile"; + + +HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback) +{ + const unsigned kSectoreSize = 512; + Byte buf[kSectoreSize]; + size_t headerSize = kSectoreSize; + RINOK(ReadStream(stream, buf, &headerSize)) + + if (headerSize < sizeof(k_Signature)) + return S_FALSE; + + CMyComPtr volumeCallback; + + if (memcmp(buf, k_Signature, sizeof(k_Signature)) != 0) + { + const size_t k_SigDesc_Size = strlen(kSignature_Descriptor); + if (headerSize < k_SigDesc_Size) + return S_FALSE; + if (memcmp(buf, kSignature_Descriptor, k_SigDesc_Size) != 0) + return S_FALSE; + + UInt64 endPos; + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) + if (endPos > (1 << 20)) + return S_FALSE; + const size_t numBytes = (size_t)endPos; + _descriptorBuf.Alloc(numBytes); + RINOK(InStream_SeekToBegin(stream)) + RINOK(ReadStream_FALSE(stream, _descriptorBuf, numBytes)) + + if (!_descriptor.Parse(_descriptorBuf, _descriptorBuf.Size())) + return S_FALSE; + _isMultiVol = true; + _isArc = true; + _phySize = numBytes; + if (_descriptor.IsThere_Parent()) + _unsupported = true; + + if (openCallback) + { + openCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volumeCallback); + } + if (!volumeCallback) + { + _unsupported = true; + return E_NOTIMPL; + } + + /* + UInt64 totalVirtSize = 0; + FOR_VECTOR (i, _descriptor.Extents) + { + const CExtentInfo &ei = _descriptor.Extents[i]; + if (ei.NumSectors >= ((UInt64)1 << (63 - 9))) + return S_FALSE; + totalVirtSize += ei.NumSectors; + if (totalVirtSize >= ((UInt64)1 << (63 - 9))) + return S_FALSE; + } + totalVirtSize <<= 9; + */ + + if (_descriptor.Extents.Size() > 1) + { + const UInt64 numFiles = _descriptor.Extents.Size(); + RINOK(openCallback->SetTotal(&numFiles, NULL)) + } + } + + UInt64 complexity = 0; + + for (;;) + { + CExtent *e = NULL; + CMyComPtr nextStream; + + if (_isMultiVol) + { + const unsigned extentIndex = _extents.Size(); + if (extentIndex >= _descriptor.Extents.Size()) + break; + const CExtentInfo &ei = _descriptor.Extents[extentIndex]; + e = &_extents.AddNew(); + e->StartOffset = 0; + if (ei.NumSectors >= ((UInt64)1 << (62 - 9)) || + ei.StartSector >= ((UInt64)1 << (62 - 9))) + return S_FALSE; + e->NumBytes = ei.NumSectors << 9; + e->IsZero = ei.IsType_ZERO(); + if (extentIndex != 0) + e->StartOffset = _extents[extentIndex - 1].GetEndOffset(); + if (e->GetEndOffset() < e->StartOffset) + return S_FALSE; + + e->VirtSize = e->NumBytes; + if (e->IsZero) + { + e->IsOK = true; + continue; + } + + e->IsFlat = ei.IsType_Flat(); + e->FlatOffset = ei.StartSector << 9; + + UString u; + CDescriptor::GetUnicodeName(ei.FileName, u); + if (u.IsEmpty()) + { + _missingVol = true; + continue; + } + + HRESULT result = volumeCallback->GetStream(u, &nextStream); + + if (result != S_OK && result != S_FALSE) + return result; + + if (!nextStream || result != S_OK) + { + if (_missingVolName.IsEmpty()) + _missingVolName = u; + _missingVol = true; + continue; + } + + if (e->IsFlat) + { + e->IsOK = true; + e->Stream = nextStream; + e->PhySize = e->NumBytes; + continue; + } + + stream = nextStream; + + headerSize = kSectoreSize; + RINOK(ReadStream(stream, buf, &headerSize)) + + if (headerSize != kSectoreSize) + continue; + if (memcmp(buf, k_Signature, sizeof(k_Signature)) != 0) + continue; + } + else + { + if (headerSize != kSectoreSize) + return S_FALSE; + e = &_extents.AddNew(); + e->StartOffset = 0; + } + + HRESULT res = S_FALSE; + if (e->h.Parse(buf)) + res = e->Open3(stream, openCallback, _isMultiVol ? _descriptor.Extents.Size() : 1, _extents.Size() - 1, complexity); + + if (!_isMultiVol) + { + _isArc = e->IsArc; + _phySize = e->PhySize; + _unsupported = e->Unsupported; + } + + if (e->Unsupported) + _unsupportedSome = true; + if (e->HeadersError) + _headerError = true; + + if (res != S_OK) + { + if (res != S_FALSE) + return res; + if (!_isMultiVol) + return res; + continue; + } + + e->Stream = stream; + e->IsOK = true; + + if (!_isMultiVol) + { + e->NumBytes = e->VirtSize; + break; + } + + if (e->NumBytes != e->VirtSize) + _headerError = true; + } + + if (!_extents.IsEmpty()) + _size = _extents.Back().GetEndOffset(); + + _needDeflate = false; + _clusterBitsMax = 0; + + // unsigned numOKs = 0; + unsigned numUnsupported = 0; + + FOR_VECTOR (i, _extents) + { + const CExtent &e = _extents[i]; + if (e.Unsupported) + numUnsupported++; + if (!e.IsOK) + continue; + // numOKs++; + if (e.IsVmdk()) + { + if (e.NeedDeflate) + _needDeflate = true; + if (_clusterBitsMax < e.ClusterBits) + _clusterBitsMax = e.ClusterBits; + } + } + + if (numUnsupported != 0 && numUnsupported == _extents.Size()) + _unsupported = true; + + return S_OK; +} + + +HRESULT CExtent::Open3(IInStream *stream, IArchiveOpenCallback *openCallback, + unsigned numVols, unsigned volIndex, UInt64 &complexity) +{ + if (h.descriptorSize != 0) + { + if (h.descriptorOffset == 0 || + h.descriptorSize > (1 << 10)) + return S_FALSE; + DescriptorBuf.Alloc((size_t)h.descriptorSize << 9); + RINOK(ReadForHeader(stream, h.descriptorOffset, DescriptorBuf, (size_t)h.descriptorSize)) + if (h.descriptorOffset == 1 && h.Is_Marker() && Get64(DescriptorBuf) == 0) + { + // We check data as end marker. + // and if probably it's footer's copy of header, we don't want to open it. + return S_FALSE; + } + + DescriptorOK = Descriptor.Parse(DescriptorBuf, DescriptorBuf.Size()); + if (!DescriptorOK) + HeadersError = true; + if (Descriptor.IsThere_Parent()) + Unsupported = true; + } + + if (h.gdOffset == (UInt64)(Int64)-1) + { + // Grain Dir is at end of file + UInt64 endPos; + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) + if ((endPos & 511) != 0) + return S_FALSE; + + const size_t kEndSize = 512 * 3; + Byte buf2[kEndSize]; + if (endPos < kEndSize) + return S_FALSE; + RINOK(InStream_SeekSet(stream, endPos - kEndSize)) + RINOK(ReadStream_FALSE(stream, buf2, kEndSize)) + + CHeader h2; + if (!h2.Parse(buf2 + 512)) + return S_FALSE; + if (!h.IsSameImageFor(h2)) + return S_FALSE; + + h = h2; + + CMarker m; + m.Parse(buf2); + if (m.NumSectors != 1 || m.SpecSize != 0 || m.Type != k_Marker_FOOTER) + return S_FALSE; + m.Parse(buf2 + 512 * 2); + if (m.NumSectors != 0 || m.SpecSize != 0 || m.Type != k_Marker_END_OF_STREAM) + return S_FALSE; + PhySize = endPos; + } + + const int grainSize_Log = GetLog(h.grainSize); + if (grainSize_Log < 3 || grainSize_Log > 30 - 9) // grain size must be >= 4 KB + return S_FALSE; + if (h.capacity >= ((UInt64)1 << (63 - 9))) + return S_FALSE; + if (h.overHead >= ((UInt64)1 << (63 - 9))) + return S_FALSE; + + IsArc = true; + ClusterBits = (9 + (unsigned)grainSize_Log); + VirtSize = h.capacity << 9; + NeedDeflate = (h.algo >= 1); + + if (h.Is_Compressed() ? (h.algo > 1 || !h.Is_Marker()) : (h.algo != 0)) + { + Unsupported = true; + PhySize = 0; + return S_FALSE; + } + + { + const UInt64 overHeadBytes = h.overHead << 9; + if (PhySize < overHeadBytes) + PhySize = overHeadBytes; + } + + ZeroSector = 0; + if (h.Is_ZeroGrain()) + ZeroSector = 1; + + const UInt64 numSectorsPerGde = (UInt64)1 << ((unsigned)grainSize_Log + k_NumMidBits); + const UInt64 numGdeEntries = (h.capacity + numSectorsPerGde - 1) >> ((unsigned)grainSize_Log + k_NumMidBits); + CByteBuffer table; + + if (numGdeEntries != 0) + { + if (h.gdOffset == 0) + return S_FALSE; + + size_t numSectors = (size_t)((numGdeEntries + ((1 << (9 - 2)) - 1)) >> (9 - 2)); + size_t t1SizeBytes = numSectors << 9; + if ((t1SizeBytes >> 2) < numGdeEntries) + return S_FALSE; + table.Alloc(t1SizeBytes); + + if (h.Is_Marker()) + { + Byte buf2[1 << 9]; + if (ReadForHeader(stream, h.gdOffset - 1, buf2, 1) != S_OK) + return S_FALSE; + { + CMarker m; + m.Parse(buf2); + if (m.Type != k_Marker_GRAIN_DIR + || m.NumSectors != numSectors + || m.SpecSize != 0) + return S_FALSE; + } + } + + RINOK(ReadForHeader(stream, h.gdOffset, table, numSectors)) + } + + const size_t clusterSize = (size_t)1 << ClusterBits; + + const UInt64 complexityStart = complexity; + + if (openCallback) + { + complexity += (UInt64)numGdeEntries << (k_NumMidBits + 2); + { + const UInt64 numVols2 = numVols; + RINOK(openCallback->SetTotal((numVols == 1) ? NULL : &numVols2, &complexity)) + } + if (numVols != 1) + { + const UInt64 volIndex2 = volIndex; + RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &complexityStart)) + } + } + + UInt64 lastSector = 0; + UInt64 lastVirtCluster = 0; + size_t numProcessed_Prev = 0; + + for (size_t i = 0; i < numGdeEntries; i++) + { + const size_t k_NumSectors = (size_t)1 << (k_NumMidBits - 9 + 2); + const size_t k_NumMidItems = (size_t)1 << k_NumMidBits; + + CByteBuffer &buf = Tables.AddNew(); + + { + const UInt32 v = Get32((const Byte *)table + (size_t)i * 4); + if (v == 0 || v == ZeroSector) + continue; + if (openCallback && (i - numProcessed_Prev) >= 1024) + { + const UInt64 comp = complexityStart + ((UInt64)i << (k_NumMidBits + 2)); + const UInt64 volIndex2 = volIndex; + RINOK(openCallback->SetCompleted(numVols == 1 ? NULL : &volIndex2, &comp)) + numProcessed_Prev = i; + } + + if (h.Is_Marker()) + { + Byte buf2[1 << 9]; + if (ReadForHeader(stream, v - 1, buf2, 1) != S_OK) + return S_FALSE; + { + CMarker m; + m.Parse(buf2); + if (m.Type != k_Marker_GRAIN_TABLE + || m.NumSectors != k_NumSectors + || m.SpecSize != 0) + return S_FALSE; + } + } + + buf.Alloc(k_NumMidItems * 4); + RINOK(ReadForHeader(stream, v, buf, k_NumSectors)) + } + + for (size_t k = 0; k < k_NumMidItems; k++) + { + const UInt32 v = Get32((const Byte *)buf + (size_t)k * 4); + if (v == 0 || v == ZeroSector) + continue; + if (v < h.overHead) + return S_FALSE; + if (lastSector < v) + { + lastSector = v; + if (NeedDeflate) + lastVirtCluster = ((UInt64)i << k_NumMidBits) + k; + } + } + } + + if (!NeedDeflate) + { + UInt64 end = ((UInt64)lastSector << 9) + clusterSize; + if (PhySize < end) + PhySize = end; + } + else if (lastSector != 0) + { + Byte buf[1 << 9]; + if (ReadForHeader(stream, lastSector, buf, 1) == S_OK) + { + UInt64 lba = Get64(buf); + if (lba == (lastVirtCluster << (ClusterBits - 9))) + { + UInt32 dataSize = Get32(buf + 8); + size_t dataSize2 = (size_t)dataSize + 12; + dataSize2 = (dataSize2 + 511) & ~(size_t)511; + UInt64 end = ((UInt64)lastSector << 9) + dataSize2; + if (PhySize < end) + PhySize = end; + } + } + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + + _cacheCluster = (UInt64)(Int64)-1; + _cacheExtent = (unsigned)(int)-1; + + _clusterBitsMax = 0; + + _isArc = false; + _unsupported = false; + _unsupportedSome = false; + _headerError = false; + _missingVol = false; + _isMultiVol = false; + _needDeflate = false; + + _missingVolName.Empty(); + + _descriptorBuf.Free(); + _descriptor.Clear(); + + // CHandlerImg: + Clear_HandlerImg_Vars(); + Stream.Release(); + + _extents.Clear(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + *stream = NULL; + + if (_unsupported) + return S_FALSE; + + ClearStreamVars(); + // _stream_UsePackSize = true; + + if (_needDeflate) + { + if (!_bufInStream) + { + _bufInStreamSpec = new CBufInStream; + _bufInStream = _bufInStreamSpec; + } + + if (!_bufOutStream) + { + _bufOutStreamSpec = new CBufPtrSeqOutStream(); + _bufOutStream = _bufOutStreamSpec; + } + + if (!_zlibDecoder) + { + _zlibDecoderSpec = new NCompress::NZlib::CDecoder; + _zlibDecoder = _zlibDecoderSpec; + } + + const size_t clusterSize = (size_t)1 << _clusterBitsMax; + _cache.AllocAtLeast(clusterSize); + _cacheCompressed.AllocAtLeast(clusterSize * 2); + } + + FOR_VECTOR (i, _extents) + { + RINOK(_extents[i].InitAndSeek()) + } + + CMyComPtr streamTemp = this; + InitAndSeekMain(); + *stream = streamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + +REGISTER_ARC_I( + "VMDK", "vmdk", NULL, 0xC8, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandler.cpp 2016-06-11 08:08:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.cpp 2024-01-01 09:00:00.000000000 +0000 @@ -1,1248 +1,1238 @@ -// WimHandler.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" - -#include "../../Common/MethodProps.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "WimHandler.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -using namespace NWindows; - -namespace NArchive { -namespace NWim { - -#define FILES_DIR_NAME "[DELETED]" - -// #define WIM_DETAILS - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - kpidMethod, - kpidSolid, - kpidShortName, - kpidINode, - kpidLinks, - kpidIsAltStream, - kpidNumAltStreams, - - #ifdef WIM_DETAILS - , kpidVolume - , kpidOffset - #endif -}; - -enum -{ - kpidNumImages = kpidUserDefined, - kpidBootImage -}; - -static const CStatProp kArcProps[] = -{ - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidClusterSize, VT_UI4}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidComment, VT_BSTR}, - { NULL, kpidUnpackVer, VT_BSTR}, - { NULL, kpidIsVolume, VT_BOOL}, - { NULL, kpidVolume, VT_UI4}, - { NULL, kpidNumVolumes, VT_UI4}, - { "Images", kpidNumImages, VT_UI4}, - { "Boot Image", kpidBootImage, VT_UI4} -}; - - -static const char * const k_Methods[] = -{ - "Copy" - , "XPress" - , "LZX" - , "LZMS" -}; - - - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_WITH_NAME - -static void AddErrorMessage(AString &s, const char *message) -{ - if (!s.IsEmpty()) - s += ". "; - s += message; -} - -static void ConvertByteToHex(unsigned value, char *s) -{ - for (int i = 0; i < 2; i++) - { - unsigned t = value & 0xF; - value >>= 4; - s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - const CImageInfo *image = NULL; - if (_xmls.Size() == 1) - { - const CWimXml &xml = _xmls[0]; - if (xml.Images.Size() == 1) - image = &xml.Images[0]; - } - - switch (propID) - { - case kpidPhySize: prop = _phySize; break; - case kpidSize: prop = _db.GetUnpackSize(); break; - case kpidPackSize: prop = _db.GetPackSize(); break; - - case kpidCTime: - if (_xmls.Size() == 1) - { - const CWimXml &xml = _xmls[0]; - int index = -1; - FOR_VECTOR (i, xml.Images) - { - const CImageInfo &image2 = xml.Images[i]; - if (image2.CTimeDefined) - if (index < 0 || ::CompareFileTime(&image2.CTime, &xml.Images[index].CTime) < 0) - index = i; - } - if (index >= 0) - prop = xml.Images[index].CTime; - } - break; - - case kpidMTime: - if (_xmls.Size() == 1) - { - const CWimXml &xml = _xmls[0]; - int index = -1; - FOR_VECTOR (i, xml.Images) - { - const CImageInfo &image2 = xml.Images[i]; - if (image2.MTimeDefined) - if (index < 0 || ::CompareFileTime(&image2.MTime, &xml.Images[index].MTime) > 0) - index = i; - } - if (index >= 0) - prop = xml.Images[index].MTime; - } - break; - - case kpidComment: - if (image) - { - if (_xmlInComments) - { - UString s; - _xmls[0].ToUnicode(s); - prop = s; - } - else if (image->NameDefined) - prop = image->Name; - } - break; - - case kpidUnpackVer: - { - UInt32 ver1 = _version >> 16; - UInt32 ver2 = (_version >> 8) & 0xFF; - UInt32 ver3 = (_version) & 0xFF; - - char s[16]; - ConvertUInt32ToString(ver1, s); - AString res = s; - res += '.'; - ConvertUInt32ToString(ver2, s); - res += s; - if (ver3 != 0) - { - res += '.'; - ConvertUInt32ToString(ver3, s); - res += s; - } - prop = res; - break; - } - - case kpidIsVolume: - if (_xmls.Size() > 0) - { - UInt16 volIndex = _xmls[0].VolIndex; - if (volIndex < _volumes.Size()) - prop = (_volumes[volIndex].Header.NumParts > 1); - } - break; - case kpidVolume: - if (_xmls.Size() > 0) - { - UInt16 volIndex = _xmls[0].VolIndex; - if (volIndex < _volumes.Size()) - prop = (UInt32)_volumes[volIndex].Header.PartNumber; - } - break; - case kpidNumVolumes: if (_volumes.Size() > 0) prop = (UInt32)(_volumes.Size() - 1); break; - - case kpidClusterSize: - if (_xmls.Size() > 0) - { - UInt16 volIndex = _xmls[0].VolIndex; - if (volIndex < _volumes.Size()) - { - const CHeader &h = _volumes[volIndex].Header; - prop = (UInt32)1 << h.ChunkSizeBits; - } - } - break; - - case kpidName: - if (_firstVolumeIndex >= 0) - { - const CHeader &h = _volumes[_firstVolumeIndex].Header; - if (GetUi32(h.Guid) != 0) - { - char temp[16 * 2 + 4]; - int i; - for (i = 0; i < 4; i++) - ConvertByteToHex(h.Guid[i], temp + i * 2); - temp[i * 2] = 0; - AString s = temp; - const char *ext = ".wim"; - if (h.NumParts != 1) - { - s += '_'; - if (h.PartNumber != 1) - { - char sz[16]; - ConvertUInt32ToString(h.PartNumber, sz); - s += sz; - } - ext = ".swm"; - } - s += ext; - prop = s; - } - } - break; - - case kpidExtension: - if (_firstVolumeIndex >= 0) - { - const CHeader &h = _volumes[_firstVolumeIndex].Header; - if (h.NumParts > 1) - { - AString s; - if (h.PartNumber != 1) - { - char sz[16]; - ConvertUInt32ToString(h.PartNumber, sz); - s = sz; - s += '.'; - } - s += "swm"; - prop = s; - } - } - break; - - case kpidNumImages: prop = (UInt32)_db.Images.Size(); break; - case kpidBootImage: if (_bootIndex != 0) prop = (UInt32)_bootIndex; break; - - case kpidMethod: - { - UInt32 methodUnknown = 0; - UInt32 methodMask = 0; - unsigned chunkSizeBits = 0; - - { - FOR_VECTOR (i, _xmls) - { - const CHeader &header = _volumes[_xmls[i].VolIndex].Header; - unsigned method = header.GetMethod(); - if (method < ARRAY_SIZE(k_Methods)) - methodMask |= ((UInt32)1 << method); - else - methodUnknown = method; - if (chunkSizeBits < header.ChunkSizeBits) - chunkSizeBits = header.ChunkSizeBits; - } - } - - AString res; - - bool numMethods = 0; - for (unsigned i = 0; i < ARRAY_SIZE(k_Methods); i++) - { - if (methodMask & ((UInt32)1 << i)) - { - res.Add_Space_if_NotEmpty(); - res += k_Methods[i]; - numMethods++; - } - } - - if (methodUnknown != 0) - { - char temp[32]; - ConvertUInt32ToString(methodUnknown, temp); - res.Add_Space_if_NotEmpty(); - res += temp; - numMethods++; - } - - if (numMethods == 1 && chunkSizeBits != 0) - { - char temp[32]; - temp[0] = ':'; - ConvertUInt32ToString((UInt32)chunkSizeBits, temp + 1); - res += temp; - } - - prop = res; - break; - } - - case kpidIsTree: prop = true; break; - case kpidIsAltStream: prop = _db.ThereAreAltStreams; break; - case kpidIsAux: prop = true; break; - // WIM uses special prefix to represent deleted items - // case kpidIsDeleted: prop = _db.ThereAreDeletedStreams; break; - case kpidINode: prop = true; break; - - case kpidErrorFlags: - { - UInt32 flags = 0; - if (!_isArc) flags |= kpv_ErrorFlags_IsNotArc; - if (_db.HeadersError) flags |= kpv_ErrorFlags_HeadersError; - if (_unsupported) flags |= kpv_ErrorFlags_UnsupportedMethod; - prop = flags; - break; - } - - case kpidWarning: - { - AString s; - if (_xmlError) - AddErrorMessage(s, "XML error"); - if (_db.RefCountError) - AddErrorMessage(s, "Some files have incorrect reference count"); - if (!s.IsEmpty()) - prop = s; - break; - } - - case kpidReadOnly: - { - bool readOnly = !IsUpdateSupported(); - if (readOnly) - prop = readOnly; - break; - } - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -void GetFileTime(const Byte *p, NCOM::CPropVariant &prop) -{ - prop.vt = VT_FILETIME; - prop.filetime.dwLowDateTime = Get32(p); - prop.filetime.dwHighDateTime = Get32(p + 4); -} - - -static void MethodToProp(int method, int chunksSizeBits, NCOM::CPropVariant &prop) -{ - if (method >= 0) - { - char temp[32]; - - if ((unsigned)method < ARRAY_SIZE(k_Methods)) - strcpy(temp, k_Methods[(unsigned)method]); - else - ConvertUInt32ToString((unsigned)method, temp); - - if (chunksSizeBits >= 0) - { - size_t pos = strlen(temp); - temp[pos++] = ':'; - ConvertUInt32ToString((unsigned)chunksSizeBits, temp + pos); - } - - prop = temp; - } -} - - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - if (index < _db.SortedItems.Size()) - { - unsigned realIndex = _db.SortedItems[index]; - const CItem &item = _db.Items[realIndex]; - const CStreamInfo *si = NULL; - const CVolume *vol = NULL; - if (item.StreamIndex >= 0) - { - si = &_db.DataStreams[item.StreamIndex]; - vol = &_volumes[si->PartNumber]; - } - - const CItem *mainItem = &item; - if (item.IsAltStream) - mainItem = &_db.Items[item.Parent]; - const Byte *metadata = NULL; - if (mainItem->ImageIndex >= 0) - metadata = _db.Images[mainItem->ImageIndex].Meta + mainItem->Offset; - - switch (propID) - { - case kpidPath: - if (item.ImageIndex >= 0) - _db.GetItemPath(realIndex, _showImageNumber, prop); - else - { - char sz[16]; - ConvertUInt32ToString(item.StreamIndex, sz); - AString s = sz; - /* - while (s.Len() < _nameLenForStreams) - s = '0' + s; - */ - /* - if (si->Resource.IsFree()) - s = (AString)("[Free]" STRING_PATH_SEPARATOR) + sz; - else - */ - s = (AString)(FILES_DIR_NAME STRING_PATH_SEPARATOR) + sz; - prop = s; - } - break; - - case kpidName: - if (item.ImageIndex >= 0) - _db.GetItemName(realIndex, prop); - else - { - char sz[16]; - ConvertUInt32ToString(item.StreamIndex, sz); - /* - AString s = sz; - while (s.Len() < _nameLenForStreams) - s = '0' + s; - */ - prop = sz; - } - break; - - case kpidShortName: - if (item.ImageIndex >= 0 && !item.IsAltStream) - _db.GetShortName(realIndex, prop); - break; - - case kpidPackSize: - { - if (si) - { - if (!si->Resource.IsSolidSmall()) - prop = si->Resource.PackSize; - else - { - if (si->Resource.SolidIndex >= 0) - { - const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; - if (ss.FirstSmallStream == item.StreamIndex) - prop = _db.DataStreams[ss.StreamIndex].Resource.PackSize; - } - } - } - else if (!item.IsDir) - prop = (UInt64)0; - - break; - } - - case kpidSize: - { - if (si) - { - if (si->Resource.IsSolid()) - { - if (si->Resource.IsSolidBig()) - { - if (si->Resource.SolidIndex >= 0) - { - const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; - prop = ss.UnpackSize; - } - } - else - prop = si->Resource.PackSize; - } - else - prop = si->Resource.UnpackSize; - } - else if (!item.IsDir) - prop = (UInt64)0; - - break; - } - - case kpidIsDir: prop = item.IsDir; break; - case kpidIsAltStream: prop = item.IsAltStream; break; - case kpidNumAltStreams: - { - if (!item.IsAltStream && mainItem->HasMetadata()) - { - UInt32 dirRecordSize = _db.IsOldVersion ? kDirRecordSizeOld : kDirRecordSize; - UInt32 numAltStreams = Get16(metadata + dirRecordSize - 6); - if (numAltStreams != 0) - { - if (!item.IsDir) - numAltStreams--; - prop = numAltStreams; - } - } - break; - } - - case kpidAttrib: - if (!item.IsAltStream && mainItem->ImageIndex >= 0) - { - /* - if (fileNameLen == 0 && isDir && !item.HasStream()) - item.Attrib = 0x10; // some swm archives have system/hidden attributes for root - */ - prop = (UInt32)Get32(metadata + 8); - } - break; - case kpidCTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break; - case kpidATime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break; - case kpidMTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break; - - case kpidINode: - if (mainItem->HasMetadata() && !_isOldVersion) - { - UInt32 attrib = (UInt32)Get32(metadata + 8); - if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0) - { - // we don't know about that field in OLD WIM format - unsigned offset = 0x58; // (_db.IsOldVersion ? 0x30: 0x58); - UInt64 val = Get64(metadata + offset); - if (val != 0) - prop = val; - } - } - break; - - case kpidStreamId: - if (item.StreamIndex >= 0) - prop = (UInt32)item.StreamIndex; - break; - - case kpidMethod: - if (si) - { - const CResource &r = si->Resource; - if (r.IsSolid()) - { - if (r.SolidIndex >= 0) - { - CSolid &ss = _db.Solids[r.SolidIndex]; - MethodToProp(ss.Method, ss.ChunkSizeBits, prop); - } - } - else - { - int method = 0; - int chunkSizeBits = -1; - if (r.IsCompressed()) - { - method = vol->Header.GetMethod(); - chunkSizeBits = vol->Header.ChunkSizeBits; - } - MethodToProp(method, chunkSizeBits, prop); - } - } - break; - - case kpidSolid: if (si) prop = si->Resource.IsSolid(); break; - case kpidLinks: if (si) prop = (UInt32)si->RefCount; break; - #ifdef WIM_DETAILS - case kpidVolume: if (si) prop = (UInt32)si->PartNumber; break; - case kpidOffset: if (si) prop = (UInt64)si->Resource.Offset; break; - #endif - } - } - else - { - index -= _db.SortedItems.Size(); - if (index < _numXmlItems) - { - switch (propID) - { - case kpidPath: - case kpidName: prop = _xmls[index].FileName; break; - case kpidIsDir: prop = false; break; - case kpidPackSize: - case kpidSize: prop = (UInt64)_xmls[index].Data.Size(); break; - case kpidMethod: /* prop = k_Method_Copy; */ break; - } - } - else - { - index -= _numXmlItems; - switch (propID) - { - case kpidPath: - case kpidName: - if (index < (UInt32)_db.VirtualRoots.Size()) - prop = _db.Images[_db.VirtualRoots[index]].RootName; - else - prop = FILES_DIR_NAME; - break; - case kpidIsDir: prop = true; break; - case kpidIsAux: prop = true; break; - } - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetRootProp(PROPID propID, PROPVARIANT *value) -{ - // COM_TRY_BEGIN - NCOM::CPropVariant prop; - if (_db.Images.Size() != 0 && _db.NumExcludededItems != 0) - { - const CImage &image = _db.Images[_db.IndexOfUserImage]; - const CItem &item = _db.Items[image.StartItem]; - if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage) - return E_FAIL; - const Byte *metadata = image.Meta + item.Offset; - - switch (propID) - { - case kpidIsDir: prop = true; break; - case kpidAttrib: prop = (UInt32)Get32(metadata + 8); break; - case kpidCTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break; - case kpidATime: GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break; - case kpidMTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break; - } - } - prop.Detach(value); - return S_OK; - // COM_TRY_END -} - -HRESULT CHandler::GetSecurity(UInt32 realIndex, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - const CItem &item = _db.Items[realIndex]; - if (item.IsAltStream || item.ImageIndex < 0) - return S_OK; - const CImage &image = _db.Images[item.ImageIndex]; - const Byte *metadata = image.Meta + item.Offset; - UInt32 securityId = Get32(metadata + 0xC); - if (securityId == (UInt32)(Int32)-1) - return S_OK; - if (securityId >= (UInt32)image.SecurOffsets.Size()) - return E_FAIL; - UInt32 offs = image.SecurOffsets[securityId]; - UInt32 len = image.SecurOffsets[securityId + 1] - offs; - const CByteBuffer &buf = image.Meta; - if (offs <= buf.Size() && buf.Size() - offs >= len) - { - *data = buf + offs; - *dataSize = len; - *propType = NPropDataType::kRaw; - } - return S_OK; -} - -STDMETHODIMP CHandler::GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = 0; - *dataSize = 0; - *propType = 0; - if (propID == kpidNtSecure && _db.Images.Size() != 0 && _db.NumExcludededItems != 0) - { - const CImage &image = _db.Images[_db.IndexOfUserImage]; - const CItem &item = _db.Items[image.StartItem]; - if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage) - return E_FAIL; - return GetSecurity(image.StartItem, data, dataSize, propType); - } - return S_OK; -} - -static const Byte kRawProps[] = -{ - kpidSha1, - kpidNtReparse, - kpidNtSecure -}; - - -STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) -{ - *numProps = ARRAY_SIZE(kRawProps); - return S_OK; -} - -STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) -{ - *propID = kRawProps[index]; - *name = 0; - return S_OK; -} - -STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) -{ - *parentType = NParentType::kDir; - *parent = (UInt32)(Int32)-1; - if (index >= _db.SortedItems.Size()) - return S_OK; - - const CItem &item = _db.Items[_db.SortedItems[index]]; - - if (item.ImageIndex >= 0) - { - *parentType = item.IsAltStream ? NParentType::kAltStream : NParentType::kDir; - if (item.Parent >= 0) - { - if (_db.ExludedItem != item.Parent) - *parent = _db.Items[item.Parent].IndexInSorted; - } - else - { - CImage &image = _db.Images[item.ImageIndex]; - if (image.VirtualRootIndex >= 0) - *parent = _db.SortedItems.Size() + _numXmlItems + image.VirtualRootIndex; - } - } - else - *parent = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - if (propID == kpidName) - { - if (index < _db.SortedItems.Size()) - { - const CItem &item = _db.Items[_db.SortedItems[index]]; - if (item.ImageIndex < 0) - return S_OK; - const CImage &image = _db.Images[item.ImageIndex]; - *propType = NPropDataType::kUtf16z; - if (image.NumEmptyRootItems != 0 && item.Parent < 0) - { - const CByteBuffer &buf = _db.Images[item.ImageIndex].RootNameBuf; - *data = (void *)(const Byte *)buf; - *dataSize = (UInt32)buf.Size(); - return S_OK; - } - const Byte *meta = image.Meta + item.Offset + - (item.IsAltStream ? - (_isOldVersion ? 0x10 : 0x24) : - (_isOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2)); - *data = (const void *)(meta + 2); - *dataSize = (UInt32)Get16(meta) + 2; - return S_OK; - } - { - index -= _db.SortedItems.Size(); - if (index < _numXmlItems) - return S_OK; - index -= _numXmlItems; - if (index >= (UInt32)_db.VirtualRoots.Size()) - return S_OK; - const CByteBuffer &buf = _db.Images[_db.VirtualRoots[index]].RootNameBuf; - *data = (void *)(const Byte *)buf; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kUtf16z; - return S_OK; - } - } - - if (index >= _db.SortedItems.Size()) - return S_OK; - - unsigned index2 = _db.SortedItems[index]; - - if (propID == kpidNtSecure) - { - return GetSecurity(index2, data, dataSize, propType); - } - - const CItem &item = _db.Items[index2]; - if (propID == kpidSha1) - { - if (item.StreamIndex >= 0) - *data = _db.DataStreams[item.StreamIndex].Hash; - else - { - if (_isOldVersion) - return S_OK; - const Byte *sha1 = _db.Images[item.ImageIndex].Meta + item.Offset + (item.IsAltStream ? 0x10 : 0x40); - if (IsEmptySha(sha1)) - return S_OK; - *data = sha1; - } - *dataSize = kHashSize; - *propType = NPropDataType::kRaw; - return S_OK; - } - - if (propID == kpidNtReparse && !_isOldVersion) - { - // we don't know about Reparse field in OLD WIM format - - if (item.StreamIndex < 0) - return S_OK; - if (index2 >= _db.ItemToReparse.Size()) - return S_OK; - int reparseIndex = _db.ItemToReparse[index2]; - if (reparseIndex < 0) - return S_OK; - const CByteBuffer &buf = _db.ReparseItems[reparseIndex]; - if (buf.Size() == 0) - return S_OK; - *data = buf; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kRaw; - return S_OK; - } - - return S_OK; -} - -class CVolumeName -{ - UString _before; - UString _after; -public: - void InitName(const UString &name) - { - int dotPos = name.ReverseFind_Dot(); - if (dotPos < 0) - dotPos = name.Len(); - _before = name.Left(dotPos); - _after = name.Ptr(dotPos); - } - - UString GetNextName(UInt32 index) const - { - wchar_t s[16]; - ConvertUInt32ToString(index, s); - return _before + (UString)s + _after; - } -}; - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - - Close(); - { - CMyComPtr openVolumeCallback; - - CVolumeName seqName; - if (callback) - callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - - UInt32 numVolumes = 1; - - for (UInt32 i = 1; i <= numVolumes; i++) - { - CMyComPtr curStream; - - if (i == 1) - curStream = inStream; - else - { - UString fullName = seqName.GetNextName(i); - HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); - if (result == S_FALSE) - continue; - if (result != S_OK) - return result; - if (!curStream) - break; - } - - CHeader header; - HRESULT res = NWim::ReadHeader(curStream, header, _phySize); - - if (res != S_OK) - { - if (i != 1 && res == S_FALSE) - continue; - return res; - } - - _isArc = true; - _bootIndex = header.BootIndex; - _version = header.Version; - _isOldVersion = header.IsOldVersion(); - if (_firstVolumeIndex >= 0) - if (!header.AreFromOnArchive(_volumes[_firstVolumeIndex].Header)) - break; - if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream) - break; - CWimXml xml; - xml.VolIndex = header.PartNumber; - res = _db.OpenXml(curStream, header, xml.Data); - - if (res == S_OK) - { - if (!xml.Parse()) - _xmlError = true; - - if (xml.IsEncrypted) - { - _unsupported = true; - return S_FALSE; - } - - UInt64 totalFiles = xml.GetTotalFilesAndDirs() + xml.Images.Size(); - totalFiles += 16 + xml.Images.Size() * 4; // we reserve some additional items - if (totalFiles >= ((UInt32)1 << 30)) - totalFiles = 0; - res = _db.Open(curStream, header, (unsigned)totalFiles, callback); - } - - if (res != S_OK) - { - if (i != 1 && res == S_FALSE) - continue; - return res; - } - - while (_volumes.Size() <= header.PartNumber) - _volumes.AddNew(); - CVolume &volume = _volumes[header.PartNumber]; - volume.Header = header; - volume.Stream = curStream; - - _firstVolumeIndex = header.PartNumber; - - if (_xmls.IsEmpty() || xml.Data != _xmls[0].Data) - { - char sz[16]; - ConvertUInt32ToString(xml.VolIndex, sz); - xml.FileName = L'['; - xml.FileName.AddAscii(sz); - xml.FileName.AddAscii("].xml"); - _xmls.Add(xml); - } - - if (i == 1) - { - if (header.PartNumber != 1) - break; - if (!openVolumeCallback) - break; - numVolumes = header.NumParts; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - break; - seqName.InitName(prop.bstrVal); - } - } - } - - RINOK(_db.FillAndCheck(_volumes)); - int defaultImageIndex = (int)_defaultImageNumber - 1; - - bool showImageNumber = (_db.Images.Size() != 1 && defaultImageIndex < 0); - if (!showImageNumber && _set_use_ShowImageNumber) - showImageNumber = _set_showImageNumber; - - if (!showImageNumber && _keepMode_ShowImageNumber) - showImageNumber = true; - - _showImageNumber = showImageNumber; - - RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber)); - RINOK(_db.ExtractReparseStreams(_volumes, callback)); - - /* - wchar_t sz[16]; - ConvertUInt32ToString(_db.DataStreams.Size(), sz); - _nameLenForStreams = MyStringLen(sz); - */ - - _xmlInComments = !_showImageNumber; - _numXmlItems = (_xmlInComments ? 0 : _xmls.Size()); - _numIgnoreItems = _db.ThereAreDeletedStreams ? 1 : 0; - } - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::Close() -{ - _firstVolumeIndex = -1; - _phySize = 0; - _db.Clear(); - _volumes.Clear(); - _xmls.Clear(); - // _nameLenForStreams = 0; - _xmlInComments = false; - _numXmlItems = 0; - _numIgnoreItems = 0; - _xmlError = false; - _isArc = false; - _unsupported = false; - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - - if (allFilesMode) - numItems = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size() + _numIgnoreItems; - if (numItems == 0) - return S_OK; - - UInt32 i; - UInt64 totalSize = 0; - - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - if (index < _db.SortedItems.Size()) - { - int streamIndex = _db.Items[_db.SortedItems[index]].StreamIndex; - if (streamIndex >= 0) - { - const CStreamInfo &si = _db.DataStreams[streamIndex]; - totalSize += _db.Get_UnpackSize_of_Resource(si.Resource); - } - } - else - { - index -= _db.SortedItems.Size(); - if (index < (UInt32)_numXmlItems) - totalSize += _xmls[index].Data.Size(); - } - } - - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 currentTotalUnPacked = 0; - UInt64 currentItemUnPacked; - - int prevSuccessStreamIndex = -1; - - CUnpacker unpacker; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - for (i = 0;; i++, - currentTotalUnPacked += currentItemUnPacked) - { - currentItemUnPacked = 0; - - lps->InSize = unpacker.TotalPacked; - lps->OutSize = currentTotalUnPacked; - - RINOK(lps->SetCur()); - - if (i >= numItems) - break; - - UInt32 index = allFilesMode ? i : indices[i]; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - CMyComPtr realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (index >= _db.SortedItems.Size()) - { - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - index -= _db.SortedItems.Size(); - if (index < (UInt32)_numXmlItems) - { - const CByteBuffer &data = _xmls[index].Data; - currentItemUnPacked = data.Size(); - if (realOutStream) - { - RINOK(WriteStream(realOutStream, (const Byte *)data, data.Size())); - realOutStream.Release(); - } - } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - const CItem &item = _db.Items[_db.SortedItems[index]]; - int streamIndex = item.StreamIndex; - if (streamIndex < 0) - { - if (!item.IsDir) - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(!item.IsDir && _db.ItemHasStream(item) ? - NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kOK)); - continue; - } - - const CStreamInfo &si = _db.DataStreams[streamIndex]; - currentItemUnPacked = _db.Get_UnpackSize_of_Resource(si.Resource); - // currentItemPacked = _db.Get_PackSize_of_Resource(streamIndex); - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NExtract::NOperationResult::kOK; - - if (streamIndex != prevSuccessStreamIndex || realOutStream) - { - Byte digest[kHashSize]; - const CVolume &vol = _volumes[si.PartNumber]; - bool needDigest = !si.IsEmptyHash(); - - HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db, - realOutStream, progress, needDigest ? digest : NULL); - - if (res == S_OK) - { - if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0) - prevSuccessStreamIndex = streamIndex; - else - opRes = NExtract::NOperationResult::kCRCError; - } - else if (res == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else if (res == E_NOTIMPL) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else - return res; - } - - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _db.SortedItems.Size() + - _numXmlItems + - _db.VirtualRoots.Size() + - _numIgnoreItems; - return S_OK; -} - -CHandler::CHandler() -{ - _keepMode_ShowImageNumber = false; - InitDefaults(); - _xmlError = false; -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - InitDefaults(); - - for (UInt32 i = 0; i < numProps; i++) - { - UString name = names[i]; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - - const PROPVARIANT &prop = values[i]; - - if (name[0] == L'x') - { - // some clients write 'x' property. So we support it - UInt32 level = 0; - RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)); - } - else if (name.IsEqualTo("is")) - { - RINOK(PROPVARIANT_to_bool(prop, _set_showImageNumber)); - _set_use_ShowImageNumber = true; - } - else if (name.IsEqualTo("im")) - { - UInt32 image = 9; - RINOK(ParsePropToUInt32(L"", prop, image)); - _defaultImageNumber = image; - } - else - return E_INVALIDARG; - } - return S_OK; -} - -STDMETHODIMP CHandler::KeepModeForNextOpen() -{ - _keepMode_ShowImageNumber = _showImageNumber; - return S_OK; -} - -}} +// WimHandler.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" + +#include "../../Common/MethodProps.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "WimHandler.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +using namespace NWindows; + +namespace NArchive { +namespace NWim { + +#define FILES_DIR_NAME "[DELETED]" + +// #define WIM_DETAILS + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidAttrib, + kpidMethod, + kpidSolid, + kpidShortName, + kpidINode, + kpidLinks, + kpidIsAltStream, + kpidNumAltStreams, + + #ifdef WIM_DETAILS + , kpidVolume + , kpidOffset + #endif +}; + +enum +{ + kpidNumImages = kpidUserDefined, + kpidBootImage +}; + +static const CStatProp kArcProps[] = +{ + { NULL, kpidSize, VT_UI8}, + { NULL, kpidPackSize, VT_UI8}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidClusterSize, VT_UI4}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidUnpackVer, VT_BSTR}, + { NULL, kpidIsVolume, VT_BOOL}, + { NULL, kpidVolume, VT_UI4}, + { NULL, kpidNumVolumes, VT_UI4}, + { "Images", kpidNumImages, VT_UI4}, + { "Boot Image", kpidBootImage, VT_UI4} +}; + + +static const char * const k_Methods[] = +{ + "Copy" + , "XPress" + , "LZX" + , "LZMS" +}; + + + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void AddErrorMessage(AString &s, const char *message) +{ + if (!s.IsEmpty()) + s += ". "; + s += message; +} + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CImageInfo *image = NULL; + if (_xmls.Size() == 1) + { + const CWimXml &xml = _xmls[0]; + if (xml.Images.Size() == 1) + image = &xml.Images[0]; + } + + switch (propID) + { + case kpidPhySize: prop = _phySize; break; + case kpidSize: prop = _db.GetUnpackSize(); break; + case kpidPackSize: prop = _db.GetPackSize(); break; + + case kpidCTime: + if (_xmls.Size() == 1) + { + const CWimXml &xml = _xmls[0]; + int index = -1; + FOR_VECTOR (i, xml.Images) + { + const CImageInfo &image2 = xml.Images[i]; + if (image2.CTimeDefined) + if (index < 0 || ::CompareFileTime(&image2.CTime, &xml.Images[index].CTime) < 0) + index = (int)i; + } + if (index >= 0) + prop = xml.Images[index].CTime; + } + break; + + case kpidMTime: + if (_xmls.Size() == 1) + { + const CWimXml &xml = _xmls[0]; + int index = -1; + FOR_VECTOR (i, xml.Images) + { + const CImageInfo &image2 = xml.Images[i]; + if (image2.MTimeDefined) + if (index < 0 || ::CompareFileTime(&image2.MTime, &xml.Images[index].MTime) > 0) + index = (int)i; + } + if (index >= 0) + prop = xml.Images[index].MTime; + } + break; + + case kpidComment: + if (image) + { + if (_xmlInComments) + { + UString s; + _xmls[0].ToUnicode(s); + prop = s; + } + else if (image->NameDefined) + prop = image->Name; + } + break; + + case kpidUnpackVer: + { + UInt32 ver1 = _version >> 16; + UInt32 ver2 = (_version >> 8) & 0xFF; + UInt32 ver3 = (_version) & 0xFF; + + AString res; + res.Add_UInt32(ver1); + res.Add_Dot(); + res.Add_UInt32(ver2); + if (ver3 != 0) + { + res.Add_Dot(); + res.Add_UInt32(ver3); + } + prop = res; + break; + } + + case kpidIsVolume: + if (_xmls.Size() > 0) + { + UInt16 volIndex = _xmls[0].VolIndex; + if (volIndex < _volumes.Size()) + prop = (_volumes[volIndex].Header.NumParts > 1); + } + break; + case kpidVolume: + if (_xmls.Size() > 0) + { + UInt16 volIndex = _xmls[0].VolIndex; + if (volIndex < _volumes.Size()) + prop = (UInt32)_volumes[volIndex].Header.PartNumber; + } + break; + case kpidNumVolumes: if (_volumes.Size() > 0) prop = (UInt32)(_volumes.Size() - 1); break; + + case kpidClusterSize: + if (_xmls.Size() > 0) + { + UInt16 volIndex = _xmls[0].VolIndex; + if (volIndex < _volumes.Size()) + { + const CHeader &h = _volumes[volIndex].Header; + prop = (UInt32)1 << h.ChunkSizeBits; + } + } + break; + + case kpidName: + if (_firstVolumeIndex >= 0) + { + const CHeader &h = _volumes[_firstVolumeIndex].Header; + if (GetUi32(h.Guid) != 0) + { + char temp[64]; + RawLeGuidToString(h.Guid, temp); + temp[8] = 0; // for reduced GUID + AString s (temp); + const char *ext = ".wim"; + if (h.NumParts != 1) + { + s += '_'; + if (h.PartNumber != 1) + s.Add_UInt32(h.PartNumber); + ext = ".swm"; + } + s += ext; + prop = s; + } + } + break; + + case kpidExtension: + if (_firstVolumeIndex >= 0) + { + const CHeader &h = _volumes[_firstVolumeIndex].Header; + if (h.NumParts > 1) + { + AString s; + if (h.PartNumber != 1) + { + s.Add_UInt32(h.PartNumber); + s.Add_Dot(); + } + s += "swm"; + prop = s; + } + } + break; + + case kpidNumImages: prop = (UInt32)_db.Images.Size(); break; + case kpidBootImage: if (_bootIndex != 0) prop = (UInt32)_bootIndex; break; + + case kpidMethod: + { + UInt32 methodUnknown = 0; + UInt32 methodMask = 0; + unsigned chunkSizeBits = 0; + + { + FOR_VECTOR (i, _xmls) + { + const CHeader &header = _volumes[_xmls[i].VolIndex].Header; + unsigned method = header.GetMethod(); + if (method < Z7_ARRAY_SIZE(k_Methods)) + methodMask |= ((UInt32)1 << method); + else + methodUnknown = method; + if (chunkSizeBits < header.ChunkSizeBits) + chunkSizeBits = header.ChunkSizeBits; + } + } + + AString res; + + unsigned numMethods = 0; + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Methods); i++) + { + if (methodMask & ((UInt32)1 << i)) + { + res.Add_Space_if_NotEmpty(); + res += k_Methods[i]; + numMethods++; + } + } + + if (methodUnknown != 0) + { + res.Add_Space_if_NotEmpty(); + res.Add_UInt32(methodUnknown); + numMethods++; + } + + if (numMethods == 1 && chunkSizeBits != 0) + { + res.Add_Colon(); + res.Add_UInt32((UInt32)chunkSizeBits); + } + + prop = res; + break; + } + + case kpidIsTree: prop = true; break; + case kpidIsAltStream: prop = _db.ThereAreAltStreams; break; + case kpidIsAux: prop = true; break; + // WIM uses special prefix to represent deleted items + // case kpidIsDeleted: prop = _db.ThereAreDeletedStreams; break; + case kpidINode: prop = true; break; + + case kpidErrorFlags: + { + UInt32 flags = 0; + if (!_isArc) flags |= kpv_ErrorFlags_IsNotArc; + if (_db.HeadersError) flags |= kpv_ErrorFlags_HeadersError; + if (_unsupported) flags |= kpv_ErrorFlags_UnsupportedMethod; + prop = flags; + break; + } + + case kpidWarning: + { + AString s; + if (_xmlError) + AddErrorMessage(s, "XML error"); + if (_db.RefCountError) + AddErrorMessage(s, "Some files have incorrect reference count"); + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidReadOnly: + { + bool readOnly = !IsUpdateSupported(); + if (readOnly) + prop = readOnly; + break; + } + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +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); +} + + +static void MethodToProp(int method, int chunksSizeBits, NCOM::CPropVariant &prop) +{ + if (method >= 0) + { + char temp[32]; + + if ((unsigned)method < Z7_ARRAY_SIZE(k_Methods)) + MyStringCopy(temp, k_Methods[(unsigned)method]); + else + ConvertUInt32ToString((UInt32)(unsigned)method, temp); + + if (chunksSizeBits >= 0) + { + size_t pos = strlen(temp); + temp[pos++] = ':'; + ConvertUInt32ToString((unsigned)chunksSizeBits, temp + pos); + } + + prop = temp; + } +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (index < _db.SortedItems.Size()) + { + unsigned realIndex = _db.SortedItems[index]; + const CItem &item = _db.Items[realIndex]; + const CStreamInfo *si = NULL; + const CVolume *vol = NULL; + if (item.StreamIndex >= 0) + { + si = &_db.DataStreams[item.StreamIndex]; + vol = &_volumes[si->PartNumber]; + } + + const CItem *mainItem = &item; + if (item.IsAltStream) + mainItem = &_db.Items[item.Parent]; + const Byte *metadata = NULL; + if (mainItem->ImageIndex >= 0) + metadata = _db.Images[mainItem->ImageIndex].Meta + mainItem->Offset; + + switch (propID) + { + case kpidPath: + if (item.ImageIndex >= 0) + _db.GetItemPath(realIndex, _showImageNumber, prop); + else + { + /* + while (s.Len() < _nameLenForStreams) + s = '0' + s; + */ + /* + if (si->Resource.IsFree()) + s = (AString)("[Free]" STRING_PATH_SEPARATOR) + sz; + else + */ + AString s (FILES_DIR_NAME STRING_PATH_SEPARATOR); + s.Add_UInt32((UInt32)(Int32)item.StreamIndex); + prop = s; + } + break; + + case kpidName: + if (item.ImageIndex >= 0) + _db.GetItemName(realIndex, prop); + else + { + char sz[16]; + ConvertUInt32ToString((UInt32)(Int32)item.StreamIndex, sz); + /* + AString s = sz; + while (s.Len() < _nameLenForStreams) + s = '0' + s; + */ + prop = sz; + } + break; + + case kpidShortName: + if (item.ImageIndex >= 0 && !item.IsAltStream) + _db.GetShortName(realIndex, prop); + break; + + case kpidPackSize: + { + if (si) + { + if (!si->Resource.IsSolidSmall()) + prop = si->Resource.PackSize; + else + { + if (si->Resource.SolidIndex >= 0) + { + const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; + if (ss.FirstSmallStream == item.StreamIndex) + prop = _db.DataStreams[ss.StreamIndex].Resource.PackSize; + } + } + } + else if (!item.IsDir) + prop = (UInt64)0; + + break; + } + + case kpidSize: + { + if (si) + { + if (si->Resource.IsSolid()) + { + if (si->Resource.IsSolidBig()) + { + if (si->Resource.SolidIndex >= 0) + { + const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; + prop = ss.UnpackSize; + } + } + else + prop = si->Resource.PackSize; + } + else + prop = si->Resource.UnpackSize; + } + else if (!item.IsDir) + prop = (UInt64)0; + + break; + } + + case kpidIsDir: prop = item.IsDir; break; + case kpidIsAltStream: prop = item.IsAltStream; break; + case kpidNumAltStreams: + { + if (!item.IsAltStream && mainItem->HasMetadata()) + { + UInt32 dirRecordSize = _db.IsOldVersion ? kDirRecordSizeOld : kDirRecordSize; + UInt32 numAltStreams = Get16(metadata + dirRecordSize - 6); + if (numAltStreams != 0) + { + if (!item.IsDir) + numAltStreams--; + prop = numAltStreams; + } + } + break; + } + + case kpidAttrib: + if (!item.IsAltStream && mainItem->ImageIndex >= 0) + { + /* + if (fileNameLen == 0 && isDir && !item.HasStream()) + item.Attrib = 0x10; // some swm archives have system/hidden attributes for root + */ + prop = (UInt32)Get32(metadata + 8); + } + break; + case kpidCTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break; + case kpidATime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break; + case kpidMTime: if (mainItem->HasMetadata()) GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break; + + case kpidINode: + if (mainItem->HasMetadata() && !_isOldVersion) + { + UInt32 attrib = (UInt32)Get32(metadata + 8); + if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0) + { + // we don't know about that field in OLD WIM format + unsigned offset = 0x58; // (_db.IsOldVersion ? 0x30: 0x58); + UInt64 val = Get64(metadata + offset); + if (val != 0) + prop = val; + } + } + break; + + case kpidStreamId: + if (item.StreamIndex >= 0) + prop = (UInt32)item.StreamIndex; + break; + + case kpidMethod: + if (si) + { + const CResource &r = si->Resource; + if (r.IsSolid()) + { + if (r.SolidIndex >= 0) + { + CSolid &ss = _db.Solids[r.SolidIndex]; + MethodToProp(ss.Method, (int)ss.ChunkSizeBits, prop); + } + } + else + { + int method = 0; + int chunkSizeBits = -1; + if (r.IsCompressed()) + { + method = (int)vol->Header.GetMethod(); + chunkSizeBits = (int)vol->Header.ChunkSizeBits; + } + MethodToProp(method, chunkSizeBits, prop); + } + } + break; + + case kpidSolid: if (si) prop = si->Resource.IsSolid(); break; + case kpidLinks: if (si) prop = (UInt32)si->RefCount; break; + #ifdef WIM_DETAILS + case kpidVolume: if (si) prop = (UInt32)si->PartNumber; break; + case kpidOffset: if (si) prop = (UInt64)si->Resource.Offset; break; + #endif + } + } + else + { + index -= _db.SortedItems.Size(); + if (index < _numXmlItems) + { + switch (propID) + { + case kpidPath: + case kpidName: prop = _xmls[index].FileName; break; + case kpidIsDir: prop = false; break; + case kpidPackSize: + case kpidSize: prop = (UInt64)_xmls[index].Data.Size(); break; + case kpidMethod: /* prop = k_Method_Copy; */ break; + } + } + else + { + index -= _numXmlItems; + switch (propID) + { + case kpidPath: + case kpidName: + if (index < (UInt32)_db.VirtualRoots.Size()) + prop = _db.Images[_db.VirtualRoots[index]].RootName; + else + prop = FILES_DIR_NAME; + break; + case kpidIsDir: prop = true; break; + case kpidIsAux: prop = true; break; + } + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetRootProp(PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (_db.Images.Size() != 0 && _db.NumExcludededItems != 0) + { + const CImage &image = _db.Images[_db.IndexOfUserImage]; + const CItem &item = _db.Items[image.StartItem]; + if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage) + return E_FAIL; + const Byte *metadata = image.Meta + item.Offset; + + switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidAttrib: prop = (UInt32)Get32(metadata + 8); break; + case kpidCTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x18: 0x28), prop); break; + case kpidATime: GetFileTime(metadata + (_db.IsOldVersion ? 0x20: 0x30), prop); break; + case kpidMTime: GetFileTime(metadata + (_db.IsOldVersion ? 0x28: 0x38), prop); break; + } + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + +HRESULT CHandler::GetSecurity(UInt32 realIndex, const void **data, UInt32 *dataSize, UInt32 *propType) +{ + const CItem &item = _db.Items[realIndex]; + if (item.IsAltStream || item.ImageIndex < 0) + return S_OK; + const CImage &image = _db.Images[item.ImageIndex]; + const Byte *metadata = image.Meta + item.Offset; + UInt32 securityId = Get32(metadata + 0xC); + if (securityId == (UInt32)(Int32)-1) + return S_OK; + if (securityId >= (UInt32)image.SecurOffsets.Size()) + return E_FAIL; + UInt32 offs = image.SecurOffsets[securityId]; + UInt32 len = image.SecurOffsets[securityId + 1] - offs; + const CByteBuffer &buf = image.Meta; + if (offs <= buf.Size() && buf.Size() - offs >= len) + { + *data = buf + offs; + *dataSize = len; + *propType = NPropDataType::kRaw; + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRootRawProp(PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + if (propID == kpidNtSecure && _db.Images.Size() != 0 && _db.NumExcludededItems != 0) + { + const CImage &image = _db.Images[_db.IndexOfUserImage]; + const CItem &item = _db.Items[image.StartItem]; + if (!item.IsDir || item.ImageIndex != _db.IndexOfUserImage) + return E_FAIL; + return GetSecurity(image.StartItem, data, dataSize, propType); + } + return S_OK; +} + +static const Byte kRawProps[] = +{ + kpidSha1, + kpidNtReparse, + kpidNtSecure +}; + + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + if (index >= _db.SortedItems.Size()) + return S_OK; + + const CItem &item = _db.Items[_db.SortedItems[index]]; + + if (item.ImageIndex >= 0) + { + *parentType = item.IsAltStream ? NParentType::kAltStream : NParentType::kDir; + if (item.Parent >= 0) + { + if (_db.ExludedItem != item.Parent) + *parent = (unsigned)_db.Items[item.Parent].IndexInSorted; + } + else + { + CImage &image = _db.Images[item.ImageIndex]; + if (image.VirtualRootIndex >= 0) + *parent = _db.SortedItems.Size() + _numXmlItems + (unsigned)image.VirtualRootIndex; + } + } + else + *parent = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidName) + { + if (index < _db.SortedItems.Size()) + { + const CItem &item = _db.Items[_db.SortedItems[index]]; + if (item.ImageIndex < 0) + return S_OK; + const CImage &image = _db.Images[item.ImageIndex]; + *propType = NPropDataType::kUtf16z; + if (image.NumEmptyRootItems != 0 && item.Parent < 0) + { + const CByteBuffer &buf = _db.Images[item.ImageIndex].RootNameBuf; + *data = (void *)(const Byte *)buf; + *dataSize = (UInt32)buf.Size(); + return S_OK; + } + const Byte *meta = image.Meta + item.Offset + + (item.IsAltStream ? + (_isOldVersion ? 0x10 : 0x24) : + (_isOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2)); + *data = (const void *)(meta + 2); + *dataSize = (UInt32)Get16(meta) + 2; + return S_OK; + } + { + index -= _db.SortedItems.Size(); + if (index < _numXmlItems) + return S_OK; + index -= _numXmlItems; + if (index >= (UInt32)_db.VirtualRoots.Size()) + return S_OK; + const CByteBuffer &buf = _db.Images[_db.VirtualRoots[index]].RootNameBuf; + *data = (void *)(const Byte *)buf; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kUtf16z; + return S_OK; + } + } + + if (index >= _db.SortedItems.Size()) + return S_OK; + + unsigned index2 = _db.SortedItems[index]; + + if (propID == kpidNtSecure) + { + return GetSecurity(index2, data, dataSize, propType); + } + + const CItem &item = _db.Items[index2]; + if (propID == kpidSha1) + { + if (item.StreamIndex >= 0) + *data = _db.DataStreams[item.StreamIndex].Hash; + else + { + if (_isOldVersion) + return S_OK; + const Byte *sha1 = _db.Images[item.ImageIndex].Meta + item.Offset + (item.IsAltStream ? 0x10 : 0x40); + if (IsEmptySha(sha1)) + return S_OK; + *data = sha1; + } + *dataSize = kHashSize; + *propType = NPropDataType::kRaw; + return S_OK; + } + + if (propID == kpidNtReparse && !_isOldVersion) + { + // we don't know about Reparse field in OLD WIM format + + if (item.StreamIndex < 0) + return S_OK; + if (index2 >= _db.ItemToReparse.Size()) + return S_OK; + int reparseIndex = _db.ItemToReparse[index2]; + if (reparseIndex < 0) + return S_OK; + const CByteBuffer &buf = _db.ReparseItems[reparseIndex]; + if (buf.Size() == 0) + return S_OK; + *data = buf; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kRaw; + return S_OK; + } + + return S_OK; +} + +class CVolumeName +{ + UString _before; + UString _after; +public: + void InitName(const UString &name) + { + int dotPos = name.ReverseFind_Dot(); + if (dotPos < 0) + dotPos = (int)name.Len(); + _before.SetFrom(name.Ptr(), (unsigned)dotPos); + _after = name.Ptr(dotPos); + } + + UString GetNextName(UInt32 index) const + { + UString s = _before; + s.Add_UInt32(index); + s += _after; + return s; + } +}; + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + + Close(); + { + CMyComPtr openVolumeCallback; + + CVolumeName seqName; + if (callback) + callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); + + UInt32 numVolumes = 1; + + for (UInt32 i = 1; i <= numVolumes; i++) + { + CMyComPtr curStream; + + if (i == 1) + curStream = inStream; + else + { + if (!openVolumeCallback) + continue; + const UString fullName = seqName.GetNextName(i); + const HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); + if (result == S_FALSE) + continue; + if (result != S_OK) + return result; + if (!curStream) + break; + } + + CHeader header; + HRESULT res = NWim::ReadHeader(curStream, header, _phySize); + + if (res != S_OK) + { + if (i != 1 && res == S_FALSE) + continue; + return res; + } + + _isArc = true; + _bootIndex = header.BootIndex; + _version = header.Version; + _isOldVersion = header.IsOldVersion(); + if (_firstVolumeIndex >= 0) + if (!header.AreFromOnArchive(_volumes[_firstVolumeIndex].Header)) + break; + if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream) + break; + CWimXml xml; + xml.VolIndex = header.PartNumber; + res = _db.OpenXml(curStream, header, xml.Data); + + if (res == S_OK) + { + if (!xml.Parse()) + _xmlError = true; + + if (xml.IsEncrypted) + { + _unsupported = true; + return S_FALSE; + } + + UInt64 totalFiles = xml.GetTotalFilesAndDirs() + xml.Images.Size(); + totalFiles += 16 + xml.Images.Size() * 4; // we reserve some additional items + if (totalFiles >= ((UInt32)1 << 30)) + totalFiles = 0; + res = _db.Open(curStream, header, (unsigned)totalFiles, callback); + } + + if (res != S_OK) + { + if (i != 1 && res == S_FALSE) + continue; + return res; + } + + while (_volumes.Size() <= header.PartNumber) + _volumes.AddNew(); + CVolume &volume = _volumes[header.PartNumber]; + volume.Header = header; + volume.Stream = curStream; + + _firstVolumeIndex = header.PartNumber; + + if (_xmls.IsEmpty() || xml.Data != _xmls[0].Data) + { + xml.FileName = '['; + xml.FileName.Add_UInt32(xml.VolIndex); + xml.FileName += "].xml"; + _xmls.Add(xml); + } + + if (i == 1) + { + if (header.PartNumber != 1) + break; + if (!openVolumeCallback) + break; + numVolumes = header.NumParts; + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt != VT_BSTR) + break; + seqName.InitName(prop.bstrVal); + } + } + } + + RINOK(_db.FillAndCheck(_volumes)) + int defaultImageIndex = (int)_defaultImageNumber - 1; + + bool showImageNumber = (_db.Images.Size() != 1 && defaultImageIndex < 0); + if (!showImageNumber && _set_use_ShowImageNumber) + showImageNumber = _set_showImageNumber; + + if (!showImageNumber && _keepMode_ShowImageNumber) + showImageNumber = true; + + _showImageNumber = showImageNumber; + + RINOK(_db.GenerateSortedItems(defaultImageIndex, showImageNumber)) + RINOK(_db.ExtractReparseStreams(_volumes, callback)) + + /* + wchar_t sz[16]; + ConvertUInt32ToString(_db.DataStreams.Size(), sz); + _nameLenForStreams = MyStringLen(sz); + */ + + _xmlInComments = !_showImageNumber; + _numXmlItems = (_xmlInComments ? 0 : _xmls.Size()); + _numIgnoreItems = _db.ThereAreDeletedStreams ? 1 : 0; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _firstVolumeIndex = -1; + _phySize = 0; + _db.Clear(); + _volumes.Clear(); + _xmls.Clear(); + // _nameLenForStreams = 0; + _xmlInComments = false; + _numXmlItems = 0; + _numIgnoreItems = 0; + _xmlError = false; + _isArc = false; + _unsupported = false; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + + if (allFilesMode) + numItems = _db.SortedItems.Size() + _numXmlItems + _db.VirtualRoots.Size() + _numIgnoreItems; + if (numItems == 0) + return S_OK; + + UInt32 i; + UInt64 totalSize = 0; + + for (i = 0; i < numItems; i++) + { + UInt32 index = allFilesMode ? i : indices[i]; + if (index < _db.SortedItems.Size()) + { + int streamIndex = _db.Items[_db.SortedItems[index]].StreamIndex; + if (streamIndex >= 0) + { + const CStreamInfo &si = _db.DataStreams[streamIndex]; + totalSize += _db.Get_UnpackSize_of_Resource(si.Resource); + } + } + else + { + index -= _db.SortedItems.Size(); + if (index < _numXmlItems) + totalSize += _xmls[index].Data.Size(); + } + } + + RINOK(extractCallback->SetTotal(totalSize)) + + totalSize = 0; + UInt64 currentItemUnPacked; + + int prevSuccessStreamIndex = -1; + + CUnpacker unpacker; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + for (i = 0;; i++, + totalSize += currentItemUnPacked) + { + currentItemUnPacked = 0; + lps->InSize = unpacker.TotalPacked; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + UInt32 index = allFilesMode ? i : indices[i]; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (index >= _db.SortedItems.Size()) + { + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + index -= _db.SortedItems.Size(); + if (index < _numXmlItems) + { + const CByteBuffer &data = _xmls[index].Data; + currentItemUnPacked = data.Size(); + if (realOutStream) + { + RINOK(WriteStream(realOutStream, (const Byte *)data, data.Size())) + realOutStream.Release(); + } + } + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + + const CItem &item = _db.Items[_db.SortedItems[index]]; + const int streamIndex = item.StreamIndex; + if (streamIndex < 0) + { + if (!item.IsDir) + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(!item.IsDir && _db.ItemHasStream(item) ? + NExtract::NOperationResult::kDataError : + NExtract::NOperationResult::kOK)) + continue; + } + + const CStreamInfo &si = _db.DataStreams[streamIndex]; + currentItemUnPacked = _db.Get_UnpackSize_of_Resource(si.Resource); + // currentItemPacked = _db.Get_PackSize_of_Resource(streamIndex); + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + Int32 opRes = NExtract::NOperationResult::kOK; + + if (streamIndex != prevSuccessStreamIndex || realOutStream) + { + Byte digest[kHashSize]; + const CVolume &vol = _volumes[si.PartNumber]; + const bool needDigest = !si.IsEmptyHash() && !_disable_Sha1Check; + const HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header, &_db, + realOutStream, lps, needDigest ? digest : NULL); + + if (res == S_OK) + { + if (!needDigest || memcmp(digest, si.Hash, kHashSize) == 0) + prevSuccessStreamIndex = streamIndex; + else + opRes = NExtract::NOperationResult::kCRCError; + } + else if (res == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else if (res == E_NOTIMPL) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else + return res; + } + + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _db.SortedItems.Size() + + _numXmlItems + + _db.VirtualRoots.Size() + + _numIgnoreItems; + return S_OK; +} + +CHandler::CHandler() +{ + _keepMode_ShowImageNumber = false; + InitDefaults(); + _xmlError = false; +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + InitDefaults(); + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name[0] == L'x') + { + // some clients write 'x' property. So we support it + UInt32 level = 0; + RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)) + } + else if (name.IsEqualTo("is")) + { + RINOK(PROPVARIANT_to_bool(prop, _set_showImageNumber)) + _set_use_ShowImageNumber = true; + } + else if (name.IsEqualTo("im")) + { + UInt32 image = 9; + RINOK(ParsePropToUInt32(L"", prop, image)) + _defaultImageNumber = (int)image; + } + else if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + } + else if (name.IsPrefixedBy_Ascii_NoCase("memuse")) + { + } + else if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 1; + RINOK(ParsePropToUInt32(name, prop, crcSize)) + _disable_Sha1Check = (crcSize == 0); + } + else + { + bool processed = false; + RINOK(_timeOptions.Parse(name, prop, processed)) + if (!processed) + return E_INVALIDARG; + } + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::KeepModeForNextOpen()) +{ + _keepMode_ShowImageNumber = _showImageNumber; + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandler.h 2015-09-17 19:02:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandler.h 2023-12-25 20:00:00.000000000 +0000 @@ -1,103 +1,95 @@ -// WimHandler.h - -#ifndef __ARCHIVE_WIM_HANDLER_H -#define __ARCHIVE_WIM_HANDLER_H - -#include "../../../Common/MyCom.h" - -#include "WimIn.h" - -namespace NArchive { -namespace NWim { - -static const Int32 kNumImagesMaxUpdate = (1 << 10); - -class CHandler: - public IInArchive, - public IArchiveGetRawProps, - public IArchiveGetRootProps, - public IArchiveKeepModeForNextOpen, - public ISetProperties, - public IOutArchive, - public CMyUnknownImp -{ - CDatabase _db; - UInt32 _version; - bool _isOldVersion; - UInt32 _bootIndex; - - CObjectVector _volumes; - CObjectVector _xmls; - // unsigned _nameLenForStreams; - bool _xmlInComments; - - unsigned _numXmlItems; - unsigned _numIgnoreItems; - - bool _xmlError; - bool _isArc; - bool _unsupported; - - bool _set_use_ShowImageNumber; - bool _set_showImageNumber; - int _defaultImageNumber; - - bool _showImageNumber; - - bool _keepMode_ShowImageNumber; - - UInt64 _phySize; - int _firstVolumeIndex; - - void InitDefaults() - { - _set_use_ShowImageNumber = false; - _set_showImageNumber = false; - _defaultImageNumber = -1; - } - - bool IsUpdateSupported() const - { - if (ThereIsError()) return false; - if (_db.Images.Size() > kNumImagesMaxUpdate) return false; - - // Solid format is complicated. So we disable updating now. - if (!_db.Solids.IsEmpty()) return false; - - if (_volumes.Size() == 0) - return true; - - if (_volumes.Size() != 2) return false; - if (_volumes[0].Stream) return false; - if (_version != k_Version_NonSolid - // && _version != k_Version_Solid - ) return false; - - return true; - } - - bool ThereIsError() const { return _xmlError || _db.ThereIsError(); } - HRESULT GetSecurity(UInt32 realIndex, const void **data, UInt32 *dataSize, UInt32 *propType); - - HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value); - HRESULT GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, FILETIME &ft); -public: - CHandler(); - MY_UNKNOWN_IMP6( - IInArchive, - IArchiveGetRawProps, - IArchiveGetRootProps, - IArchiveKeepModeForNextOpen, - ISetProperties, - IOutArchive) - INTERFACE_IInArchive(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IArchiveGetRootProps(;) - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - STDMETHOD(KeepModeForNextOpen)(); - INTERFACE_IOutArchive(;) -}; - -}} - -#endif +// WimHandler.h + +#ifndef ZIP7_INC_ARCHIVE_WIM_HANDLER_H +#define ZIP7_INC_ARCHIVE_WIM_HANDLER_H + +#include "../../../Common/MyCom.h" + +#include "../Common/HandlerOut.h" + +#include "WimIn.h" + +namespace NArchive { +namespace NWim { + +const Int32 kNumImagesMaxUpdate = 1 << 10; + +Z7_CLASS_IMP_CHandler_IInArchive_5( + IArchiveGetRawProps + , IArchiveGetRootProps + , IArchiveKeepModeForNextOpen + , ISetProperties + , IOutArchive +) + CDatabase _db; + UInt32 _version; + UInt32 _bootIndex; + + CObjectVector _volumes; + CObjectVector _xmls; + // unsigned _nameLenForStreams; + + unsigned _numXmlItems; + unsigned _numIgnoreItems; + + bool _isOldVersion; + bool _xmlInComments; + + bool _xmlError; + bool _isArc; + bool _unsupported; + + bool _set_use_ShowImageNumber; + bool _set_showImageNumber; + int _defaultImageNumber; + + bool _showImageNumber; + bool _keepMode_ShowImageNumber; + bool _disable_Sha1Check; + + UInt64 _phySize; + Int32 _firstVolumeIndex; + + CHandlerTimeOptions _timeOptions; + + void InitDefaults() + { + _disable_Sha1Check = false; + _set_use_ShowImageNumber = false; + _set_showImageNumber = false; + _defaultImageNumber = -1; + _timeOptions.Init(); + } + + bool IsUpdateSupported() const + { + if (ThereIsError()) return false; + if (_db.Images.Size() > kNumImagesMaxUpdate) return false; + + // Solid format is complicated. So we disable updating now. + if (!_db.Solids.IsEmpty()) return false; + + if (_volumes.Size() == 0) + return true; + + if (_volumes.Size() != 2) return false; + if (_volumes[0].Stream) return false; + if (_version != k_Version_NonSolid + // && _version != k_Version_Solid + ) return false; + + return true; + } + + bool ThereIsError() const { return _xmlError || _db.ThereIsError(); } + HRESULT GetSecurity(UInt32 realIndex, const void **data, UInt32 *dataSize, UInt32 *propType); + + HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value); + HRESULT GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, FILETIME &ft); +public: + CHandler(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandlerOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandlerOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimHandlerOut.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimHandlerOut.cpp 2023-12-19 09:00:00.000000000 +0000 @@ -1,1902 +1,1971 @@ -// WimHandlerOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/UTFConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" -#include "../../Common/UniqBlocks.h" - -#include "../../Crypto/RandGen.h" -#include "../../Crypto/Sha1Cls.h" - -#include "WimHandler.h" - -using namespace NWindows; - -namespace NArchive { -namespace NWim { - -static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const Byte *h, int streamIndexForInsert) -{ - unsigned left = 0, right = sorted.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - unsigned index = sorted[mid]; - const Byte *hash2 = streams[index].Hash; - - unsigned i; - for (i = 0; i < kHashSize; i++) - if (h[i] != hash2[i]) - break; - - if (i == kHashSize) - return index; - - if (h[i] < hash2[i]) - right = mid; - else - left = mid + 1; - } - - if (streamIndexForInsert >= 0) - sorted.Insert(left, streamIndexForInsert); - - return -1; -} - - -struct CAltStream -{ - int UpdateIndex; - int HashIndex; - UInt64 Size; - UString Name; - bool Skip; - - CAltStream(): UpdateIndex(-1), HashIndex(-1), Skip(false) {} -}; - - -struct CMetaItem -{ - int UpdateIndex; - int HashIndex; - - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UInt32 Attrib; - UInt64 FileID; - UInt64 VolID; - - UString Name; - UString ShortName; - - int SecurityId; // -1: means no secutity ID - bool IsDir; - bool Skip; - unsigned NumSkipAltStreams; - CObjectVector AltStreams; - - CByteBuffer Reparse; - - unsigned GetNumAltStreams() const { return AltStreams.Size() - NumSkipAltStreams; } - CMetaItem(): UpdateIndex(-1), HashIndex(-1), SecurityId(-1), - FileID(0), VolID(0), - Skip(false), NumSkipAltStreams(0) {} -}; - - -static int Compare_HardLink_MetaItems(const CMetaItem &a1, const CMetaItem &a2) -{ - if (a1.VolID < a2.VolID) return -1; - if (a1.VolID > a2.VolID) return 1; - if (a1.FileID < a2.FileID) return -1; - if (a1.FileID > a2.FileID) return 1; - if (a1.Size < a2.Size) return -1; - if (a1.Size > a2.Size) return 1; - return ::CompareFileTime(&a1.MTime, &a2.MTime); -} - - -static int AddToHardLinkList(const CObjectVector &metaItems, unsigned indexOfItem, CUIntVector &indexes) -{ - const CMetaItem &mi = metaItems[indexOfItem]; - 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]); - if (comp == 0) - return index; - if (comp < 0) - right = mid; - else - left = mid + 1; - } - indexes.Insert(left, indexOfItem); - return -1; -} - - -struct CUpdateItem -{ - unsigned CallbackIndex; // index in callback - - int MetaIndex; // index in in MetaItems[] - - int AltStreamIndex; // index in CMetaItem::AltStreams vector - // -1: if not alt stream? - - int InArcIndex; // >= 0, if we use OLD Data - // -1, if we use NEW Data - - CUpdateItem(): MetaIndex(-1), AltStreamIndex(-1), InArcIndex(-1) {} -}; - - -struct CDir -{ - int MetaIndex; - CObjectVector Dirs; - CUIntVector Files; // indexes in MetaItems[] - - CDir(): MetaIndex(-1) {} - unsigned GetNumDirs() const; - unsigned GetNumFiles() const; - UInt64 GetTotalSize(const CObjectVector &metaItems) const; - bool FindDir(const CObjectVector &items, const UString &name, unsigned &index); -}; - -/* imagex counts Junctions as files (not as dirs). - We suppose that it's not correct */ - -unsigned CDir::GetNumDirs() const -{ - unsigned num = Dirs.Size(); - FOR_VECTOR (i, Dirs) - num += Dirs[i].GetNumDirs(); - return num; -} - -unsigned CDir::GetNumFiles() const -{ - unsigned num = Files.Size(); - FOR_VECTOR (i, Dirs) - num += Dirs[i].GetNumFiles(); - return num; -} - -UInt64 CDir::GetTotalSize(const CObjectVector &metaItems) const -{ - UInt64 sum = 0; - unsigned i; - for (i = 0; i < Files.Size(); i++) - sum += metaItems[Files[i]].Size; - for (i = 0; i < Dirs.Size(); i++) - sum += Dirs[i].GetTotalSize(metaItems); - return sum; -} - -bool CDir::FindDir(const CObjectVector &items, const UString &name, unsigned &index) -{ - unsigned left = 0, right = Dirs.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - int comp = CompareFileNames(name, items[Dirs[mid].MetaIndex].Name); - if (comp == 0) - { - index = mid; - return true; - } - if (comp < 0) - right = mid; - else - left = mid + 1; - } - index = left; - return false; -} - - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kWindows; - return S_OK; -} - - -HRESULT CHandler::GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value) -{ - if (arcIndex >= 0) - return GetProperty(arcIndex, propID, value); - return callback->GetProperty(callbackIndex, propID, value); -} - - -HRESULT CHandler::GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, FILETIME &ft) -{ - ft.dwLowDateTime = ft.dwHighDateTime = 0; - NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)); - if (prop.vt == VT_FILETIME) - ft = prop.filetime; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - return S_OK; -} - - -static HRESULT GetRootTime( - IArchiveGetRootProps *callback, - IArchiveGetRootProps *arcRoot, - PROPID propID, FILETIME &ft) -{ - NCOM::CPropVariant prop; - if (callback) - { - RINOK(callback->GetRootProp(propID, &prop)); - if (prop.vt == VT_FILETIME) - { - ft = prop.filetime; - return S_OK; - } - if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - if (arcRoot) - { - RINOK(arcRoot->GetRootProp(propID, &prop)); - if (prop.vt == VT_FILETIME) - { - ft = prop.filetime; - return S_OK; - } - if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - return S_OK; -} - -#define Set16(p, d) SetUi16(p, d) -#define Set32(p, d) SetUi32(p, d) -#define Set64(p, d) SetUi64(p, d) - -void CResource::WriteTo(Byte *p) const -{ - Set64(p, PackSize); - p[7] = Flags; - Set64(p + 8, Offset); - Set64(p + 16, UnpackSize); -} - - -void CHeader::WriteTo(Byte *p) const -{ - memcpy(p, kSignature, kSignatureSize); - Set32(p + 8, kHeaderSizeMax); - Set32(p + 0xC, Version); - Set32(p + 0x10, Flags); - Set32(p + 0x14, ChunkSize); - memcpy(p + 0x18, Guid, 16); - Set16(p + 0x28, PartNumber); - Set16(p + 0x2A, NumParts); - Set32(p + 0x2C, NumImages); - OffsetResource.WriteTo(p + 0x30); - XmlResource.WriteTo(p + 0x48); - MetadataResource.WriteTo(p + 0x60); - IntegrityResource.WriteTo(p + 0x7C); - Set32(p + 0x78, BootIndex); - memset(p + 0x94, 0, 60); -} - - -void CStreamInfo::WriteTo(Byte *p) const -{ - Resource.WriteTo(p); - Set16(p + 0x18, PartNumber); - Set32(p + 0x1A, RefCount); - memcpy(p + 0x1E, Hash, kHashSize); -} - - -class CInStreamWithSha1: - public ISequentialInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - NCrypto::NSha1::CContext _sha; -public: - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - _sha.Init(); - } - void ReleaseStream() { _stream.Release(); } - UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { _sha.Final(digest); } -}; - -STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); - _size += realProcessedSize; - _sha.Update((const Byte *)data, realProcessedSize); - if (processedSize) - *processedSize = realProcessedSize; - return result; -} - - -static void SetFileTimeToMem(Byte *p, const FILETIME &ft) -{ - Set32(p, ft.dwLowDateTime); - Set32(p + 4, ft.dwHighDateTime); -} - -static size_t WriteItem_Dummy(const CMetaItem &item) -{ - if (item.Skip) - return 0; - unsigned fileNameLen = item.Name.Len() * 2; - // we write fileNameLen + 2 + 2 to be same as original WIM. - unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); - - unsigned shortNameLen = item.ShortName.Len() * 2; - unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); - - size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); - if (item.GetNumAltStreams() != 0) - { - if (!item.IsDir) - { - UInt32 curLen = (((0x26 + 0) + 6) & ~7); - totalLen += curLen; - } - FOR_VECTOR (i, item.AltStreams) - { - const CAltStream &ss = item.AltStreams[i]; - if (ss.Skip) - continue; - fileNameLen = ss.Name.Len() * 2; - fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); - UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); - totalLen += curLen; - } - } - return totalLen; -} - - -static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte *p) -{ - if (item.Skip) - return 0; - unsigned fileNameLen = item.Name.Len() * 2; - unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); - unsigned shortNameLen = item.ShortName.Len() * 2; - unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); - - size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); - - memset(p, 0, totalLen); - Set64(p, totalLen); - Set64(p + 8, item.Attrib); - Set32(p + 0xC, (Int32)item.SecurityId); - SetFileTimeToMem(p + 0x28, item.CTime); - SetFileTimeToMem(p + 0x30, item.ATime); - SetFileTimeToMem(p + 0x38, item.MTime); - - /* WIM format probably doesn't support hard links to symbolic links. - In these cases it just stores symbolic links (REPARSE TAGS). - Check it in new versions of WIM software form MS !!! - We also follow that scheme */ - - if (item.Reparse.Size() != 0) - { - UInt32 tag = GetUi32(item.Reparse); - Set32(p + 0x58, tag); - // Set32(p + 0x5C, 0); // probably it's always ZERO - } - else if (item.FileID != 0) - { - Set64(p + 0x58, item.FileID); - } - - Set16(p + 0x62, (UInt16)shortNameLen); - Set16(p + 0x64, (UInt16)fileNameLen); - unsigned i; - for (i = 0; i * 2 < fileNameLen; i++) - Set16(p + kDirRecordSize + i * 2, item.Name[i]); - for (i = 0; i * 2 < shortNameLen; i++) - Set16(p + kDirRecordSize + fileNameLen2 + i * 2, item.ShortName[i]); - - if (item.GetNumAltStreams() == 0) - { - if (item.HashIndex >= 0) - memcpy(p + 0x40, streams[item.HashIndex].Hash, kHashSize); - } - else - { - Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))); - p += totalLen; - - if (!item.IsDir) - { - UInt32 curLen = (((0x26 + 0) + 6) & ~7); - memset(p, 0, curLen); - Set64(p, curLen); - if (item.HashIndex >= 0) - memcpy(p + 0x10, streams[item.HashIndex].Hash, kHashSize); - totalLen += curLen; - p += curLen; - } - - FOR_VECTOR (si, item.AltStreams) - { - const CAltStream &ss = item.AltStreams[si]; - if (ss.Skip) - continue; - - fileNameLen = ss.Name.Len() * 2; - fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); - UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); - memset(p, 0, curLen); - - Set64(p, curLen); - if (ss.HashIndex >= 0) - memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize); - Set16(p + 0x24, (UInt16)fileNameLen); - for (i = 0; i * 2 < fileNameLen; i++) - Set16(p + 0x26 + i * 2, ss.Name[i]); - totalLen += curLen; - p += curLen; - } - } - - return totalLen; -} - - -struct CDb -{ - CMetaItem DefaultDirItem; - const CStreamInfo *Hashes; - CObjectVector MetaItems; - CRecordVector UpdateItems; - CUIntVector UpdateIndexes; /* indexes in UpdateItems in order of writing data streams - to disk (the order of tree items). */ - - size_t WriteTree_Dummy(const CDir &tree) const; - void WriteTree(const CDir &tree, Byte *dest, size_t &pos) const; - void WriteOrderList(const CDir &tree); -}; - - -size_t CDb::WriteTree_Dummy(const CDir &tree) const -{ - unsigned i; - size_t pos = 0; - for (i = 0; i < tree.Files.Size(); i++) - pos += WriteItem_Dummy(MetaItems[tree.Files[i]]); - for (i = 0; i < tree.Dirs.Size(); i++) - { - const CDir &subDir = tree.Dirs[i]; - pos += WriteItem_Dummy(MetaItems[subDir.MetaIndex]); - pos += WriteTree_Dummy(subDir); - } - return pos + 8; -} - - -void CDb::WriteTree(const CDir &tree, Byte *dest, size_t &pos) const -{ - unsigned i; - for (i = 0; i < tree.Files.Size(); i++) - pos += WriteItem(Hashes, MetaItems[tree.Files[i]], dest + pos); - - size_t posStart = pos; - for (i = 0; i < tree.Dirs.Size(); i++) - pos += WriteItem_Dummy(MetaItems[tree.Dirs[i].MetaIndex]); - - Set64(dest + pos, 0); - - pos += 8; - - for (i = 0; i < tree.Dirs.Size(); i++) - { - const CDir &subDir = tree.Dirs[i]; - const CMetaItem &metaItem = MetaItems[subDir.MetaIndex]; - bool needCreateTree = (metaItem.Reparse.Size() == 0) - || !subDir.Files.IsEmpty() - || !subDir.Dirs.IsEmpty(); - size_t len = WriteItem(Hashes, metaItem, dest + posStart); - posStart += len; - if (needCreateTree) - { - Set64(dest + posStart - len + 0x10, pos); // subdirOffset - WriteTree(subDir, dest, pos); - } - } -} - - -void CDb::WriteOrderList(const CDir &tree) -{ - if (tree.MetaIndex >= 0) - { - const CMetaItem &mi = MetaItems[tree.MetaIndex]; - if (mi.UpdateIndex >= 0) - UpdateIndexes.Add(mi.UpdateIndex); - FOR_VECTOR (si, mi.AltStreams) - UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); - } - - unsigned i; - for (i = 0; i < tree.Files.Size(); i++) - { - const CMetaItem &mi = MetaItems[tree.Files[i]]; - UpdateIndexes.Add(mi.UpdateIndex); - FOR_VECTOR (si, mi.AltStreams) - UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); - } - - for (i = 0; i < tree.Dirs.Size(); i++) - WriteOrderList(tree.Dirs[i]); -} - - -static void AddTag_ToString(AString &s, const char *name, const char *value) -{ - s += '<'; - s += name; - s += '>'; - s += value; - s += '<'; - s += '/'; - s += name; - s += '>'; -} - - -static void AddTagUInt64_ToString(AString &s, const char *name, UInt64 value) -{ - char temp[32]; - ConvertUInt64ToString(value, temp); - AddTag_ToString(s, name, temp); -} - - -static CXmlItem &AddUniqueTag(CXmlItem &parentItem, const char *name) -{ - int index = parentItem.FindSubTag(name); - if (index < 0) - { - CXmlItem &subItem = parentItem.SubItems.AddNew(); - subItem.IsTag = true; - subItem.Name = name; - return subItem; - } - CXmlItem &subItem = parentItem.SubItems[index]; - subItem.SubItems.Clear(); - return subItem; -} - - -static void AddTag_UInt64_2(CXmlItem &item, UInt64 value) -{ - CXmlItem &subItem = item.SubItems.AddNew(); - subItem.IsTag = false; - char temp[32]; - ConvertUInt64ToString(value, temp); - subItem.Name = temp; -} - - -static void AddTag_UInt64(CXmlItem &parentItem, const char *name, UInt64 value) -{ - AddTag_UInt64_2(AddUniqueTag(parentItem, name), value); -} - - -static void AddTag_Hex(CXmlItem &item, const char *name, UInt32 value) -{ - item.IsTag = true; - item.Name = name; - char temp[16]; - temp[0] = '0'; - temp[1] = 'x'; - ConvertUInt32ToHex8Digits(value, temp + 2); - CXmlItem &subItem = item.SubItems.AddNew(); - subItem.IsTag = false; - subItem.Name = temp; -} - - -static void AddTag_Time_2(CXmlItem &item, const FILETIME &ft) -{ - AddTag_Hex(item.SubItems.AddNew(), "HIGHPART", ft.dwHighDateTime); - AddTag_Hex(item.SubItems.AddNew(), "LOWPART", ft.dwLowDateTime); -} - - -static void AddTag_Time(CXmlItem &parentItem, const char *name, const FILETIME &ft) -{ - AddTag_Time_2(AddUniqueTag(parentItem, name), ft); -} - - -static void AddTag_String_IfEmpty(CXmlItem &parentItem, const char *name, const char *value) -{ - int index = parentItem.FindSubTag(name); - if (index >= 0) - return; - CXmlItem &tag = parentItem.SubItems.AddNew(); - tag.IsTag = true; - tag.Name = name; - CXmlItem &subItem = tag.SubItems.AddNew(); - subItem.IsTag = false; - subItem.Name = value; -} - - -void CHeader::SetDefaultFields(bool useLZX) -{ - Version = k_Version_NonSolid; - Flags = NHeaderFlags::kReparsePointFixup; - ChunkSize = 0; - if (useLZX) - { - Flags |= NHeaderFlags::kCompression | NHeaderFlags::kLZX; - ChunkSize = kChunkSize; - ChunkSizeBits = kChunkSizeBits; - } - g_RandomGenerator.Generate(Guid, 16); - PartNumber = 1; - NumParts = 1; - NumImages = 1; - BootIndex = 0; - OffsetResource.Clear(); - XmlResource.Clear(); - MetadataResource.Clear(); - IntegrityResource.Clear(); -} - - -static void AddTrees(CObjectVector &trees, CObjectVector &metaItems, const CMetaItem &ri, int curTreeIndex) -{ - while (curTreeIndex >= (int)trees.Size()) - trees.AddNew().Dirs.AddNew().MetaIndex = metaItems.Add(ri); -} - - -#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z') - - - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback) -{ - COM_TRY_BEGIN - - if (!IsUpdateSupported()) - return E_NOTIMPL; - - bool isUpdate = (_volumes.Size() != 0); - int defaultImageIndex = _defaultImageNumber - 1; - bool showImageNumber; - - if (isUpdate) - { - showImageNumber = _showImageNumber; - if (!showImageNumber) - defaultImageIndex = _db.IndexOfUserImage; - } - else - { - showImageNumber = (_set_use_ShowImageNumber && _set_showImageNumber); - if (!showImageNumber) - defaultImageIndex = 0; - } - - if (defaultImageIndex >= kNumImagesMaxUpdate) - return E_NOTIMPL; - - CMyComPtr outStream; - RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)); - if (!outStream) - return E_NOTIMPL; - if (!callback) - return E_FAIL; - - CDb db; - CObjectVector trees; - - CMetaItem ri; // default DIR item - FILETIME ftCur; - NTime::GetCurUtcFileTime(ftCur); - ri.MTime = ri.ATime = ri.CTime = ftCur; - ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; - ri.IsDir = true; - - - // ---------- Detect changed images ---------- - - unsigned i; - CBoolVector isChangedImage; - { - CUIntVector numUnchangedItemsInImage; - for (i = 0; i < _db.Images.Size(); i++) - { - numUnchangedItemsInImage.Add(0); - isChangedImage.Add(false); - } - - for (i = 0; i < numItems; i++) - { - UInt32 indexInArchive; - Int32 newData, newProps; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); - if (newProps == 0) - { - if (indexInArchive >= _db.SortedItems.Size()) - continue; - const CItem &item = _db.Items[_db.SortedItems[indexInArchive]]; - if (newData == 0) - { - if (item.ImageIndex >= 0) - numUnchangedItemsInImage[item.ImageIndex]++; - } - else - { - // oldProps & newData. Current version of 7-Zip doesn't use it - if (item.ImageIndex >= 0) - isChangedImage[item.ImageIndex] = true; - } - } - else if (!showImageNumber) - { - if (defaultImageIndex >= 0 && defaultImageIndex < (int)isChangedImage.Size()) - isChangedImage[defaultImageIndex] = true; - } - else - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPath, &prop)); - - if (prop.vt != VT_BSTR) - return E_INVALIDARG; - const wchar_t *path = prop.bstrVal; - if (!path) - return E_INVALIDARG; - - const wchar_t *end; - UInt64 val = ConvertStringToUInt64(path, &end); - if (end == path) - return E_INVALIDARG; - if (val == 0 || val > kNumImagesMaxUpdate) - return E_INVALIDARG; - wchar_t c = *end; - if (c != 0 && c != ':' && c != L'/' && c != WCHAR_PATH_SEPARATOR) - return E_INVALIDARG; - unsigned imageIndex = (unsigned)val - 1; - if (imageIndex < _db.Images.Size()) - isChangedImage[imageIndex] = true; - if (_defaultImageNumber > 0 && val != (unsigned)_defaultImageNumber) - return E_INVALIDARG; - } - } - - for (i = 0; i < _db.Images.Size(); i++) - if (!isChangedImage[i]) - isChangedImage[i] = _db.GetNumUserItemsInImage(i) != numUnchangedItemsInImage[i]; - } - - if (defaultImageIndex >= 0) - { - for (i = 0; i < _db.Images.Size(); i++) - if ((int)i != defaultImageIndex) - isChangedImage[i] = false; - } - - CMyComPtr getRawProps; - callback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); - - CMyComPtr getRootProps; - callback->QueryInterface(IID_IArchiveGetRootProps, (void **)&getRootProps); - - CObjectVector secureBlocks; - - if (!showImageNumber && (getRootProps || isUpdate) && - ( - defaultImageIndex >= (int)isChangedImage.Size() - || defaultImageIndex < 0 // test it - || isChangedImage[defaultImageIndex] - )) - { - // Fill Root Item: Metadata and security - CMetaItem rootItem = ri; - { - const void *data = NULL; - UInt32 dataSize = 0; - UInt32 propType = 0; - if (getRootProps) - { - RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); - } - if (dataSize == 0 && isUpdate) - { - RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); - } - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - while (defaultImageIndex >= (int)secureBlocks.Size()) - secureBlocks.AddNew(); - CUniqBlocks &secUniqBlocks = secureBlocks[defaultImageIndex]; - rootItem.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); - } - } - - IArchiveGetRootProps *thisGetRoot = isUpdate ? this : NULL; - - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)); - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)); - RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)); - - { - NCOM::CPropVariant prop; - if (getRootProps) - { - RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - rootItem.Attrib = prop.ulVal; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - if (prop.vt == VT_EMPTY && thisGetRoot) - { - RINOK(GetRootProp(kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - rootItem.Attrib = prop.ulVal; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - rootItem.Attrib |= FILE_ATTRIBUTE_DIRECTORY; - } - - AddTrees(trees, db.MetaItems, ri, defaultImageIndex); - db.MetaItems[trees[defaultImageIndex].Dirs[0].MetaIndex] = rootItem; - } - - // ---------- Request Metadata for changed items ---------- - - UString fileName; - - for (i = 0; i < numItems; i++) - { - CUpdateItem ui; - UInt32 indexInArchive; - Int32 newData, newProps; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); - - if (newData == 0 || newProps == 0) - { - if (indexInArchive >= _db.SortedItems.Size()) - continue; - - const CItem &item = _db.Items[_db.SortedItems[indexInArchive]]; - - if (item.ImageIndex >= 0) - { - if (!isChangedImage[item.ImageIndex]) - { - if (newData == 0 && newProps == 0) - continue; - return E_FAIL; - } - } - else - { - // if deleted item was not renamed, we just skip it - if (newProps == 0) - continue; - if (item.StreamIndex >= 0) - { - // we don't support property change for SolidBig streams - if (_db.DataStreams[item.StreamIndex].Resource.IsSolidBig()) - return E_NOTIMPL; - } - } - - if (newData == 0) - ui.InArcIndex = indexInArchive; - } - - // we set arcIndex only if we must use old props - Int32 arcIndex = (newProps ? -1 : indexInArchive); - - bool isDir = false; - { - NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)); - if (prop.vt == VT_BOOL) - isDir = (prop.boolVal != VARIANT_FALSE); - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - - bool isAltStream = false; - { - NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)); - if (prop.vt == VT_BOOL) - isAltStream = (prop.boolVal != VARIANT_FALSE); - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - - if (isDir && isAltStream) - return E_INVALIDARG; - - UInt64 size = 0; - UInt64 iNode = 0; - - if (!isDir) - { - if (!newData) - { - NCOM::CPropVariant prop; - GetProperty(indexInArchive, kpidINode, &prop); - if (prop.vt == VT_UI8) - iNode = prop.uhVal.QuadPart; - } - - NCOM::CPropVariant prop; - - if (newData) - { - RINOK(callback->GetProperty(i, kpidSize, &prop)); - } - else - { - RINOK(GetProperty(indexInArchive, kpidSize, &prop)); - } - - if (prop.vt == VT_UI8) - size = prop.uhVal.QuadPart; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - - { - NCOM::CPropVariant propPath; - const wchar_t *path = NULL; - RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)); - if (propPath.vt == VT_BSTR) - path = propPath.bstrVal; - else if (propPath.vt != VT_EMPTY) - return E_INVALIDARG; - - if (!path) - return E_INVALIDARG; - - CDir *curItem = NULL; - bool isRootImageDir = false; - fileName.Empty(); - - int imageIndex; - - if (!showImageNumber) - { - imageIndex = defaultImageIndex; - AddTrees(trees, db.MetaItems, ri, imageIndex); - curItem = &trees[imageIndex].Dirs[0]; - } - else - { - const wchar_t *end; - UInt64 val = ConvertStringToUInt64(path, &end); - if (end == path) - return E_INVALIDARG; - if (val == 0 || val > kNumImagesMaxUpdate) - return E_INVALIDARG; - - imageIndex = (int)val - 1; - if (imageIndex < (int)isChangedImage.Size()) - if (!isChangedImage[imageIndex]) - return E_FAIL; - - AddTrees(trees, db.MetaItems, ri, imageIndex); - curItem = &trees[imageIndex].Dirs[0]; - wchar_t c = *end; - - if (c == 0) - { - if (!isDir || isAltStream) - return E_INVALIDARG; - ui.MetaIndex = curItem->MetaIndex; - isRootImageDir = true; - } - else if (c == ':') - { - if (isDir || !isAltStream) - return E_INVALIDARG; - ui.MetaIndex = curItem->MetaIndex; - CAltStream ss; - ss.Size = size; - ss.Name = end + 1; - ss.UpdateIndex = db.UpdateItems.Size(); - ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); - } - else if (c == WCHAR_PATH_SEPARATOR || c == L'/') - { - path = end + 1; - if (*path == 0) - return E_INVALIDARG; - } - else - return E_INVALIDARG; - } - - if (ui.MetaIndex < 0) - { - for (;;) - { - wchar_t c = *path++; - if (c == 0) - break; - if (c == WCHAR_PATH_SEPARATOR || c == L'/') - { - unsigned indexOfDir; - if (!curItem->FindDir(db.MetaItems, fileName, indexOfDir)) - { - CDir &dir = curItem->Dirs.InsertNew(indexOfDir); - dir.MetaIndex = db.MetaItems.Add(ri); - db.MetaItems.Back().Name = fileName; - } - curItem = &curItem->Dirs[indexOfDir]; - fileName.Empty(); - } - else - fileName += c; - } - - if (isAltStream) - { - int colonPos = fileName.Find(L':'); - if (colonPos < 0) - return E_INVALIDARG; - - // we want to support cases of c::substream, where c: is drive name - if (colonPos == 1 && fileName[2] == L':' && IS_LETTER_CHAR(fileName[0])) - colonPos = 2; - const UString mainName = fileName.Left(colonPos); - unsigned indexOfDir; - - if (mainName.IsEmpty()) - ui.MetaIndex = curItem->MetaIndex; - else if (curItem->FindDir(db.MetaItems, mainName, indexOfDir)) - ui.MetaIndex = curItem->Dirs[indexOfDir].MetaIndex; - else - { - for (int j = (int)curItem->Files.Size() - 1; j >= 0; j--) - { - int metaIndex = curItem->Files[j]; - const CMetaItem &mi = db.MetaItems[metaIndex]; - if (CompareFileNames(mainName, mi.Name) == 0) - { - ui.MetaIndex = metaIndex; - break; - } - } - } - - if (ui.MetaIndex >= 0) - { - CAltStream ss; - ss.Size = size; - ss.Name = fileName.Ptr(colonPos + 1); - ss.UpdateIndex = db.UpdateItems.Size(); - ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); - } - } - } - - - if (ui.MetaIndex < 0 || isRootImageDir) - { - if (!isRootImageDir) - { - ui.MetaIndex = db.MetaItems.Size(); - db.MetaItems.AddNew(); - } - - CMetaItem &mi = db.MetaItems[ui.MetaIndex]; - mi.Size = size; - mi.IsDir = isDir; - mi.Name = fileName; - mi.UpdateIndex = db.UpdateItems.Size(); - { - NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)); - if (prop.vt == VT_EMPTY) - mi.Attrib = 0; - else if (prop.vt == VT_UI4) - mi.Attrib = prop.ulVal; - else - return E_INVALIDARG; - if (isDir) - mi.Attrib |= FILE_ATTRIBUTE_DIRECTORY; - } - RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)); - RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)); - RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)); - - { - NCOM::CPropVariant prop; - RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)); - if (prop.vt == VT_BSTR) - mi.ShortName.SetFromBstr(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - } - - while (imageIndex >= (int)secureBlocks.Size()) - secureBlocks.AddNew(); - - if (!isAltStream && (getRawProps || arcIndex >= 0)) - { - CUniqBlocks &secUniqBlocks = secureBlocks[imageIndex]; - const void *data; - UInt32 dataSize; - UInt32 propType; - - data = NULL; - dataSize = 0; - propType = 0; - - if (arcIndex >= 0) - { - GetRawProp(arcIndex, kpidNtSecure, &data, &dataSize, &propType); - } - else - { - getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType); - } - - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - mi.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); - } - - data = NULL; - dataSize = 0; - propType = 0; - - if (arcIndex >= 0) - { - GetRawProp(arcIndex, kpidNtReparse, &data, &dataSize, &propType); - } - else - { - getRawProps->GetRawProp(i, kpidNtReparse, &data, &dataSize, &propType); - } - - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - mi.Reparse.CopyFrom((const Byte *)data, dataSize); - } - } - - if (!isRootImageDir) - { - if (isDir) - { - unsigned indexOfDir; - if (curItem->FindDir(db.MetaItems, fileName, indexOfDir)) - curItem->Dirs[indexOfDir].MetaIndex = ui.MetaIndex; - else - curItem->Dirs.InsertNew(indexOfDir).MetaIndex = ui.MetaIndex; - } - else - curItem->Files.Add(ui.MetaIndex); - } - } - - } - - if (iNode != 0 && ui.MetaIndex >= 0 && ui.AltStreamIndex < 0) - db.MetaItems[ui.MetaIndex].FileID = iNode; - - ui.CallbackIndex = i; - db.UpdateItems.Add(ui); - } - - unsigned numNewImages = trees.Size(); - for (i = numNewImages; i < isChangedImage.Size(); i++) - if (!isChangedImage[i]) - numNewImages = i + 1; - - AddTrees(trees, db.MetaItems, ri, numNewImages - 1); - - for (i = 0; i < trees.Size(); i++) - if (i >= isChangedImage.Size() || isChangedImage[i]) - db.WriteOrderList(trees[i]); - - - UInt64 complexity = 0; - - unsigned numDataStreams = _db.DataStreams.Size(); - CUIntArr streamsRefs(numDataStreams); - for (i = 0; i < numDataStreams; i++) - streamsRefs[i] = 0; - - // ---------- Calculate Streams Refs Counts in unchanged images - - for (i = 0; i < _db.Images.Size(); i++) - { - if (isChangedImage[i]) - continue; - complexity += _db.MetaStreams[i].Resource.PackSize; - const CImage &image = _db.Images[i]; - unsigned endItem = image.StartItem + image.NumItems; - for (unsigned k = image.StartItem; k < endItem; k++) - { - const CItem &item = _db.Items[k]; - if (item.StreamIndex >= 0) - streamsRefs[(unsigned)item.StreamIndex]++; - } - } - - - // ---------- Update Streams Refs Counts in changed images - - for (i = 0; i < db.UpdateIndexes.Size(); i++) - { - const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; - - if (ui.InArcIndex >= 0) - { - if ((unsigned)ui.InArcIndex >= _db.SortedItems.Size()) - continue; - const CItem &item = _db.Items[_db.SortedItems[ui.InArcIndex]]; - if (item.StreamIndex >= 0) - streamsRefs[(unsigned)item.StreamIndex]++; - } - else - { - const CMetaItem &mi = db.MetaItems[ui.MetaIndex]; - UInt64 size; - if (ui.AltStreamIndex < 0) - size = mi.Size; - else - size = mi.AltStreams[ui.AltStreamIndex].Size; - complexity += size; - } - } - - // Clear ref counts for SolidBig streams - - for (i = 0; i < _db.DataStreams.Size(); i++) - if (_db.DataStreams[i].Resource.IsSolidBig()) - streamsRefs[i] = 0; - - // Set ref counts for SolidBig streams - - for (i = 0; i < _db.DataStreams.Size(); i++) - if (streamsRefs[i] != 0) - { - const CResource &rs = _db.DataStreams[i].Resource; - if (rs.IsSolidSmall()) - streamsRefs[_db.Solids[rs.SolidIndex].StreamIndex] = 1; - } - - for (i = 0; i < _db.DataStreams.Size(); i++) - if (streamsRefs[i] != 0) - { - const CResource &rs = _db.DataStreams[i].Resource; - if (!rs.IsSolidSmall()) - complexity += rs.PackSize; - } - - RINOK(callback->SetTotal(complexity)); - UInt64 totalComplexity = complexity; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(callback, true); - - complexity = 0; - - // bool useResourceCompression = false; - // use useResourceCompression only if CHeader::Flags compression is also set - - CHeader header; - header.SetDefaultFields(false); - - if (isUpdate) - { - const CHeader &srcHeader = _volumes[1].Header; - header.Flags = srcHeader.Flags; - header.Version = srcHeader.Version; - header.ChunkSize = srcHeader.ChunkSize; - header.ChunkSizeBits = srcHeader.ChunkSizeBits; - } - - { - Byte buf[kHeaderSizeMax]; - header.WriteTo(buf); - RINOK(WriteStream(outStream, buf, kHeaderSizeMax)); - } - - UInt64 curPos = kHeaderSizeMax; - - CInStreamWithSha1 *inShaStreamSpec = new CInStreamWithSha1; - CMyComPtr inShaStream = inShaStreamSpec; - - CLimitedSequentialInStream *inStreamLimitedSpec = NULL; - CMyComPtr inStreamLimited; - if (_volumes.Size() == 2) - { - inStreamLimitedSpec = new CLimitedSequentialInStream; - inStreamLimited = inStreamLimitedSpec; - inStreamLimitedSpec->SetStream(_volumes[1].Stream); - } - - - CRecordVector streams; - CUIntVector sortedHashes; // indexes to streams, sorted by SHA1 - - // ---------- Copy unchanged data streams ---------- - - UInt64 solidRunOffset = 0; - UInt64 curSolidSize = 0; - - for (i = 0; i < _db.DataStreams.Size(); i++) - { - const CStreamInfo &siOld = _db.DataStreams[i]; - const CResource &rs = siOld.Resource; - - unsigned numRefs = streamsRefs[i]; - - if (numRefs == 0) - { - if (!rs.IsSolidSmall()) - continue; - if (streamsRefs[_db.Solids[rs.SolidIndex].StreamIndex] == 0) - continue; - } - - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - - int streamIndex = streams.Size(); - CStreamInfo s; - s.Resource = rs; - s.PartNumber = 1; - s.RefCount = numRefs; - - memcpy(s.Hash, siOld.Hash, kHashSize); - - if (rs.IsSolid()) - { - CSolid &ss = _db.Solids[rs.SolidIndex]; - if (rs.IsSolidSmall()) - { - UInt64 oldOffset = ss.SolidOffset; - if (rs.Offset < oldOffset) - return E_FAIL; - UInt64 relatOffset = rs.Offset - oldOffset; - s.Resource.Offset = solidRunOffset + relatOffset; - } - else - { - // IsSolidBig - solidRunOffset += curSolidSize; - curSolidSize = ss.UnpackSize; - } - } - else - { - solidRunOffset = 0; - curSolidSize = 0; - } - - if (!rs.IsSolid() || rs.IsSolidSmall()) - { - int find = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, streamIndex); - if (find >= 0) - return E_FAIL; // two streams with same SHA-1 - } - - if (!rs.IsSolid() || rs.IsSolidBig()) - { - RINOK(_volumes[siOld.PartNumber].Stream->Seek(rs.Offset, STREAM_SEEK_SET, NULL)); - inStreamLimitedSpec->Init(rs.PackSize); - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != rs.PackSize) - return E_FAIL; - s.Resource.Offset = curPos; - curPos += rs.PackSize; - lps->ProgressOffset += rs.PackSize; - } - - streams.Add(s); - } - - - // ---------- Write new items ---------- - - CUIntVector hlIndexes; // sorted indexes for hard link items - - for (i = 0; i < db.UpdateIndexes.Size(); i++) - { - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; - CMetaItem &mi = db.MetaItems[ui.MetaIndex]; - UInt64 size = 0; - - if (ui.AltStreamIndex >= 0) - { - if (mi.Skip) - continue; - size = mi.AltStreams[ui.AltStreamIndex].Size; - } - else - { - size = mi.Size; - if (mi.IsDir) - { - // we support LINK files here - if (mi.Reparse.Size() == 0) - continue; - } - } - - if (ui.InArcIndex >= 0) - { - // data streams with OLD Data were written already - // we just need to find HashIndex in hashes. - - if ((unsigned)ui.InArcIndex >= _db.SortedItems.Size()) - return E_FAIL; - - const CItem &item = _db.Items[_db.SortedItems[ui.InArcIndex]]; - - if (item.StreamIndex < 0) - { - if (size == 0) - continue; - // if (_db.ItemHasStream(item)) - return E_FAIL; - } - - // We support empty file (size = 0, but with stream and SHA-1) from old archive - - const CStreamInfo &siOld = _db.DataStreams[item.StreamIndex]; - - int index = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, -1); - // we must have written that stream already - if (index < 0) - return E_FAIL; - - if (ui.AltStreamIndex < 0) - mi.HashIndex = index; - else - mi.AltStreams[ui.AltStreamIndex].HashIndex = index; - - continue; - } - - CMyComPtr fileInStream; - HRESULT res = callback->GetStream(ui.CallbackIndex, &fileInStream); - - if (res == S_FALSE) - { - if (ui.AltStreamIndex >= 0) - { - mi.NumSkipAltStreams++; - mi.AltStreams[ui.AltStreamIndex].Skip = true; - } - else - mi.Skip = true; - } - else - { - RINOK(res); - - int miIndex = -1; - - if (!fileInStream) - { - if (!mi.IsDir) - return E_INVALIDARG; - } - else if (ui.AltStreamIndex < 0) - { - CMyComPtr getProps2; - fileInStream->QueryInterface(IID_IStreamGetProps2, (void **)&getProps2); - if (getProps2) - { - CStreamFileProps props; - if (getProps2->GetProps2(&props) == S_OK) - { - mi.Attrib = props.Attrib; - mi.CTime = props.CTime; - mi.ATime = props.ATime; - mi.MTime = props.MTime; - mi.FileID = props.FileID_Low; - if (props.NumLinks <= 1) - mi.FileID = 0; - mi.VolID = props.VolID; - if (mi.FileID != 0) - miIndex = AddToHardLinkList(db.MetaItems, ui.MetaIndex, hlIndexes); - - if (props.Size != size && props.Size != (UInt64)(Int64)-1) - { - Int64 delta = (Int64)props.Size - (Int64)size; - Int64 newComplexity = totalComplexity + delta; - if (newComplexity > 0) - { - totalComplexity = newComplexity; - callback->SetTotal(totalComplexity); - } - mi.Size = props.Size; - size = props.Size; - } - } - } - } - - if (miIndex >= 0) - { - mi.HashIndex = db.MetaItems[miIndex].HashIndex; - if (mi.HashIndex >= 0) - streams[mi.HashIndex].RefCount++; - // fix for future: maybe we need to check also that real size is equal to size from IStreamGetProps2 - } - else if (ui.AltStreamIndex < 0 && mi.Reparse.Size() != 0) - { - if (mi.Reparse.Size() < 8) - return E_FAIL; - NCrypto::NSha1::CContext sha1; - sha1.Init(); - size_t packSize = mi.Reparse.Size() - 8; - sha1.Update((const Byte *)mi.Reparse + 8, packSize); - Byte hash[kHashSize]; - sha1.Final(hash); - - int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); - - if (index >= 0) - streams[index].RefCount++; - else - { - index = streams.Size(); - RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)); - CStreamInfo s; - s.Resource.PackSize = packSize; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = packSize; - s.Resource.Flags = 0; // check it - /* - if (useResourceCompression) - s.Resource.Flags = NResourceFlags::Compressed; - */ - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, hash, kHashSize); - curPos += packSize; - - streams.Add(s); - } - - mi.HashIndex = index; - } - else - { - inShaStreamSpec->SetStream(fileInStream); - fileInStream.Release(); - inShaStreamSpec->Init(); - UInt64 offsetBlockSize = 0; - /* - if (useResourceCompression) - { - for (UInt64 t = kChunkSize; t < size; t += kChunkSize) - { - Byte buf[8]; - SetUi32(buf, (UInt32)t); - RINOK(WriteStream(outStream, buf, 4)); - offsetBlockSize += 4; - } - } - */ - - RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress)); - size = copyCoderSpec->TotalSize; - - if (size != 0) - { - Byte hash[kHashSize]; - UInt64 packSize = offsetBlockSize + size; - inShaStreamSpec->Final(hash); - - int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); - - if (index >= 0) - { - streams[index].RefCount++; - outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); - outStream->SetSize(curPos); - } - else - { - index = streams.Size(); - CStreamInfo s; - s.Resource.PackSize = packSize; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = size; - s.Resource.Flags = 0; - /* - if (useResourceCompression) - s.Resource.Flags = NResourceFlags::Compressed; - */ - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, hash, kHashSize); - curPos += packSize; - - streams.Add(s); - } - - if (ui.AltStreamIndex < 0) - mi.HashIndex = index; - else - mi.AltStreams[ui.AltStreamIndex].HashIndex = index; - } - } - } - fileInStream.Release(); - complexity += size; - RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - } - - while (secureBlocks.Size() < numNewImages) - secureBlocks.AddNew(); - - - - // ---------- Write Images ---------- - - for (i = 0; i < numNewImages; i++) - { - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - if (i < isChangedImage.Size() && !isChangedImage[i]) - { - CStreamInfo s = _db.MetaStreams[i]; - - RINOK(_volumes[1].Stream->Seek(s.Resource.Offset, STREAM_SEEK_SET, NULL)); - inStreamLimitedSpec->Init(s.Resource.PackSize); - RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != s.Resource.PackSize) - return E_FAIL; - - s.Resource.Offset = curPos; - s.PartNumber = 1; - s.RefCount = 1; - streams.Add(s); - - if (_bootIndex != 0 && _bootIndex == (UInt32)i + 1) - { - header.MetadataResource = s.Resource; - header.BootIndex = _bootIndex; - } - - lps->ProgressOffset += s.Resource.PackSize; - curPos += s.Resource.PackSize; - // printf("\nWrite old image %x\n", i + 1); - continue; - } - - const CDir &tree = trees[i]; - const UInt32 kSecuritySize = 8; - - size_t pos = kSecuritySize; - - const CUniqBlocks &secUniqBlocks = secureBlocks[i]; - const CObjectVector &secBufs = secUniqBlocks.Bufs; - pos += (size_t)secUniqBlocks.GetTotalSizeInBytes(); - pos += secBufs.Size() * 8; - pos = (pos + 7) & ~(size_t)7; - - db.DefaultDirItem = ri; - pos += db.WriteTree_Dummy(tree); - - CByteArr meta(pos); - - Set32((Byte *)meta + 4, secBufs.Size()); // num security entries - pos = kSecuritySize; - - if (secBufs.Size() == 0) - { - // we can write 0 here only if there is no security data, imageX does it, - // but some programs expect size = 8 - Set32((Byte *)meta, 8); // size of security data - // Set32((Byte *)meta, 0); - } - else - { - unsigned k; - for (k = 0; k < secBufs.Size(); k++, pos += 8) - { - Set64(meta + pos, secBufs[k].Size()); - } - for (k = 0; k < secBufs.Size(); k++) - { - const CByteBuffer &buf = secBufs[k]; - size_t size = buf.Size(); - if (size != 0) - { - memcpy(meta + pos, buf, size); - pos += size; - } - } - while ((pos & 7) != 0) - meta[pos++] = 0; - Set32((Byte *)meta, (UInt32)pos); // size of security data - } - - db.Hashes = &streams.Front(); - db.WriteTree(tree, (Byte *)meta, pos); - - { - NCrypto::NSha1::CContext sha; - sha.Init(); - sha.Update((const Byte *)meta, pos); - - Byte digest[kHashSize]; - sha.Final(digest); - - CStreamInfo s; - s.Resource.PackSize = pos; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = pos; - s.Resource.Flags = NResourceFlags::kMetadata; - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, digest, kHashSize); - streams.Add(s); - - if (_bootIndex != 0 && _bootIndex == (UInt32)i + 1) - { - header.MetadataResource = s.Resource; - header.BootIndex = _bootIndex; - } - - RINOK(WriteStream(outStream, (const Byte *)meta, pos)); - meta.Free(); - curPos += pos; - } - } - - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - - header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; - header.OffsetResource.Offset = curPos; - header.OffsetResource.Flags = NResourceFlags::kMetadata; - - - - // ---------- Write Streams Info Tables ---------- - - for (i = 0; i < streams.Size(); i++) - { - Byte buf[kStreamInfoSize]; - streams[i].WriteTo(buf); - RINOK(WriteStream(outStream, buf, kStreamInfoSize)); - curPos += kStreamInfoSize; - } - - AString xml = ""; - AddTagUInt64_ToString(xml, "TOTALBYTES", curPos); - for (i = 0; i < trees.Size(); i++) - { - CDir &tree = trees[i]; - - CXmlItem item; - if (_xmls.Size() == 1) - { - const CWimXml &_oldXml = _xmls[0]; - if ((int)i < _oldXml.Images.Size()) - { - // int ttt = _oldXml.Images[i].ItemIndexInXml; - item = _oldXml.Xml.Root.SubItems[_oldXml.Images[i].ItemIndexInXml]; - } - } - if (i >= isChangedImage.Size() || isChangedImage[i]) - { - char temp[16]; - if (item.Name.IsEmpty()) - { - ConvertUInt32ToString(i + 1, temp); - item.Name = "IMAGE"; - item.IsTag = true; - CXmlProp &prop = item.Props.AddNew(); - prop.Name = "INDEX"; - prop.Value = temp; - } - - AddTag_String_IfEmpty(item, "NAME", temp); - AddTag_UInt64(item, "DIRCOUNT", tree.GetNumDirs() - 1); - AddTag_UInt64(item, "FILECOUNT", tree.GetNumFiles()); - AddTag_UInt64(item, "TOTALBYTES", tree.GetTotalSize(db.MetaItems)); - - AddTag_Time(item, "CREATIONTIME", ftCur); - AddTag_Time(item, "LASTMODIFICATIONTIME", ftCur); - } - - item.AppendTo(xml); - } - xml += ""; - - size_t xmlSize; - { - UString utf16; - if (!ConvertUTF8ToUnicode(xml, utf16)) - return S_FALSE; - xmlSize = (utf16.Len() + 1) * 2; - - CByteArr xmlBuf(xmlSize); - Set16((Byte *)xmlBuf, 0xFEFF); - for (i = 0; i < (unsigned)utf16.Len(); i++) - Set16((Byte *)xmlBuf + 2 + i * 2, utf16[i]); - RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)); - } - - header.XmlResource.UnpackSize = header.XmlResource.PackSize = xmlSize; - header.XmlResource.Offset = curPos; - header.XmlResource.Flags = NResourceFlags::kMetadata; - - outStream->Seek(0, STREAM_SEEK_SET, NULL); - header.NumImages = trees.Size(); - { - Byte buf[kHeaderSizeMax]; - header.WriteTo(buf); - return WriteStream(outStream, buf, kHeaderSizeMax); - } - - COM_TRY_END -} - -}} +// WimHandlerOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" +#include "../../Common/UniqBlocks.h" + +#include "../../Crypto/RandGen.h" +#include "../../Crypto/Sha1Cls.h" + +#include "../Common/OutStreamWithSha1.h" + +#include "WimHandler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NWim { + +static const unsigned k_NumSubVectors_Bits = 12; // must be <= 16 + +struct CSortedIndex +{ + CObjectVector Vectors; + + CSortedIndex() + { + const unsigned k_NumSubVectors = 1 << k_NumSubVectors_Bits; + Vectors.ClearAndReserve(k_NumSubVectors); + for (unsigned i = 0; i < k_NumSubVectors; i++) + Vectors.AddNew(); + } +}; + +static int AddUniqHash(const CStreamInfo *streams, CSortedIndex &sorted2, const Byte *h, int streamIndexForInsert) +{ + const unsigned hash = (((unsigned)h[0] << 8) | (unsigned)h[1]) >> (16 - k_NumSubVectors_Bits); + CUIntVector &sorted = sorted2.Vectors[hash]; + unsigned left = 0, right = sorted.Size(); + while (left != right) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned index = sorted[mid]; + const Byte *hash2 = streams[index].Hash; + + unsigned i; + for (i = 0; i < kHashSize; i++) + if (h[i] != hash2[i]) + break; + + if (i == kHashSize) + return (int)index; + + if (h[i] < hash2[i]) + right = mid; + else + left = mid + 1; + } + + if (streamIndexForInsert != -1) + sorted.Insert(left, (unsigned)streamIndexForInsert); + + return -1; +} + + +struct CAltStream +{ + int UpdateIndex; + int HashIndex; + UInt64 Size; + UString Name; + bool Skip; + + CAltStream(): UpdateIndex(-1), HashIndex(-1), Skip(false) {} +}; + + +struct CMetaItem +{ + int UpdateIndex; + int HashIndex; + + UInt64 Size; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + UInt64 FileID; + UInt64 VolID; + + UString Name; + UString ShortName; + + UInt32 Attrib; + int SecurityId; // -1: means no secutity ID + bool IsDir; + bool Skip; + unsigned NumSkipAltStreams; + CObjectVector AltStreams; + + CByteBuffer Reparse; + + unsigned GetNumAltStreams() const { return AltStreams.Size() - NumSkipAltStreams; } + CMetaItem(): + UpdateIndex(-1) + , HashIndex(-1) + , Size(0) + , FileID(0) + , VolID(0) + , Attrib(0) + , SecurityId(-1) + , IsDir(false) + , Skip(false) + , NumSkipAltStreams(0) + { + FILETIME_Clear(CTime); + FILETIME_Clear(ATime); + FILETIME_Clear(MTime); + } +}; + + +static int Compare_HardLink_MetaItems(const CMetaItem &a1, const CMetaItem &a2) +{ + if (a1.VolID < a2.VolID) return -1; + if (a1.VolID > a2.VolID) return 1; + if (a1.FileID < a2.FileID) return -1; + if (a1.FileID > a2.FileID) return 1; + if (a1.Size < a2.Size) return -1; + if (a1.Size > a2.Size) return 1; + return ::CompareFileTime(&a1.MTime, &a2.MTime); +} + + +static int AddToHardLinkList(const CObjectVector &metaItems, unsigned indexOfItem, CUIntVector &indexes) +{ + const CMetaItem &mi = metaItems[indexOfItem]; + unsigned left = 0, right = indexes.Size(); + while (left != right) + { + 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 (int)index; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + indexes.Insert(left, indexOfItem); + return -1; +} + + +struct CUpdateItem +{ + unsigned CallbackIndex; // index in callback + + int MetaIndex; // index in in MetaItems[] + + int AltStreamIndex; // index in CMetaItem::AltStreams vector + // -1: if not alt stream? + + int InArcIndex; // >= 0, if we use OLD Data + // -1, if we use NEW Data + + CUpdateItem(): MetaIndex(-1), AltStreamIndex(-1), InArcIndex(-1) {} +}; + + +struct CDir +{ + int MetaIndex; + CObjectVector Dirs; + CUIntVector Files; // indexes in MetaItems[] + + CDir(): MetaIndex(-1) {} + unsigned GetNumDirs() const; + unsigned GetNumFiles() const; + UInt64 GetTotalSize(const CObjectVector &metaItems) const; + bool FindDir(const CObjectVector &items, const UString &name, unsigned &index); +}; + +/* imagex counts Junctions as files (not as dirs). + We suppose that it's not correct */ + +unsigned CDir::GetNumDirs() const +{ + unsigned num = Dirs.Size(); + FOR_VECTOR (i, Dirs) + num += Dirs[i].GetNumDirs(); + return num; +} + +unsigned CDir::GetNumFiles() const +{ + unsigned num = Files.Size(); + FOR_VECTOR (i, Dirs) + num += Dirs[i].GetNumFiles(); + return num; +} + +UInt64 CDir::GetTotalSize(const CObjectVector &metaItems) const +{ + UInt64 sum = 0; + unsigned i; + for (i = 0; i < Files.Size(); i++) + sum += metaItems[Files[i]].Size; + for (i = 0; i < Dirs.Size(); i++) + sum += Dirs[i].GetTotalSize(metaItems); + return sum; +} + +bool CDir::FindDir(const CObjectVector &items, const UString &name, unsigned &index) +{ + unsigned left = 0, right = Dirs.Size(); + while (left != right) + { + 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; + return true; + } + if (comp < 0) + right = mid; + else + left = mid + 1; + } + index = left; + return false; +} + + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) +{ + *type = NFileTimeType::kWindows; + return S_OK; +} + + +HRESULT CHandler::GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value) +{ + if (arcIndex != -1) + return GetProperty((UInt32)arcIndex, propID, value); + return callback->GetProperty(callbackIndex, propID, value); +} + + +HRESULT CHandler::GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, FILETIME &ft) +{ + ft.dwLowDateTime = ft.dwHighDateTime = 0; + NCOM::CPropVariant prop; + RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)) + if (prop.vt == VT_FILETIME) + ft = prop.filetime; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + + +static HRESULT GetRootTime( + IArchiveGetRootProps *callback, + IArchiveGetRootProps *arcRoot, + PROPID propID, FILETIME &ft) +{ + NCOM::CPropVariant prop; + if (callback) + { + RINOK(callback->GetRootProp(propID, &prop)) + if (prop.vt == VT_FILETIME) + { + ft = prop.filetime; + return S_OK; + } + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + if (arcRoot) + { + RINOK(arcRoot->GetRootProp(propID, &prop)) + if (prop.vt == VT_FILETIME) + { + ft = prop.filetime; + return S_OK; + } + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + return S_OK; +} + +#define Set16(p, d) SetUi16(p, d) +#define Set32(p, d) SetUi32(p, d) +#define Set64(p, d) SetUi64(p, d) + +void CResource::WriteTo(Byte *p) const +{ + Set64(p, PackSize) + p[7] = Flags; + Set64(p + 8, Offset) + Set64(p + 16, UnpackSize) +} + + +void CHeader::WriteTo(Byte *p) const +{ + memcpy(p, kSignature, kSignatureSize); + Set32(p + 8, kHeaderSizeMax) + Set32(p + 0xC, Version) + Set32(p + 0x10, Flags) + Set32(p + 0x14, ChunkSize) + memcpy(p + 0x18, Guid, 16); + Set16(p + 0x28, PartNumber) + Set16(p + 0x2A, NumParts) + Set32(p + 0x2C, NumImages) + OffsetResource.WriteTo(p + 0x30); + XmlResource.WriteTo(p + 0x48); + MetadataResource.WriteTo(p + 0x60); + IntegrityResource.WriteTo(p + 0x7C); + Set32(p + 0x78, BootIndex) + memset(p + 0x94, 0, 60); +} + + +void CStreamInfo::WriteTo(Byte *p) const +{ + Resource.WriteTo(p); + Set16(p + 0x18, PartNumber) + Set32(p + 0x1A, RefCount) + memcpy(p + 0x1E, Hash, kHashSize); +} + + +static void SetFileTimeToMem(Byte *p, const FILETIME &ft) +{ + Set32(p, ft.dwLowDateTime) + Set32(p + 4, ft.dwHighDateTime) +} + +static size_t WriteItem_Dummy(const CMetaItem &item) +{ + if (item.Skip) + return 0; + unsigned fileNameLen = item.Name.Len() * 2; + // we write fileNameLen + 2 + 2 to be same as original WIM. + unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); + + const unsigned shortNameLen = item.ShortName.Len() * 2; + const unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); + + size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); + if (item.GetNumAltStreams() != 0) + { + if (!item.IsDir) + { + const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); + totalLen += curLen; + } + FOR_VECTOR (i, item.AltStreams) + { + const CAltStream &ss = item.AltStreams[i]; + if (ss.Skip) + continue; + fileNameLen = ss.Name.Len() * 2; + fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); + const UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); + totalLen += curLen; + } + } + return totalLen; +} + + +static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte *p) +{ + if (item.Skip) + return 0; + unsigned fileNameLen = item.Name.Len() * 2; + unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); + unsigned shortNameLen = item.ShortName.Len() * 2; + unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); + + size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); + + memset(p, 0, totalLen); + Set64(p, totalLen) + Set64(p + 8, item.Attrib) + Set32(p + 0xC, (UInt32)(Int32)item.SecurityId) + SetFileTimeToMem(p + 0x28, item.CTime); + SetFileTimeToMem(p + 0x30, item.ATime); + SetFileTimeToMem(p + 0x38, item.MTime); + + /* WIM format probably doesn't support hard links to symbolic links. + In these cases it just stores symbolic links (REPARSE TAGS). + Check it in new versions of WIM software form MS !!! + We also follow that scheme */ + + if (item.Reparse.Size() != 0) + { + UInt32 tag = GetUi32(item.Reparse); + Set32(p + 0x58, tag) + // Set32(p + 0x5C, 0); // probably it's always ZERO + } + else if (item.FileID != 0) + { + Set64(p + 0x58, item.FileID) + } + + Set16(p + 0x62, (UInt16)shortNameLen) + Set16(p + 0x64, (UInt16)fileNameLen) + unsigned i; + for (i = 0; i * 2 < fileNameLen; i++) + Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]) + for (i = 0; i * 2 < shortNameLen; i++) + Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]) + + if (item.GetNumAltStreams() == 0) + { + if (item.HashIndex >= 0) + memcpy(p + 0x40, streams[item.HashIndex].Hash, kHashSize); + } + else + { + Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))) + p += totalLen; + + if (!item.IsDir) + { + const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); + memset(p, 0, curLen); + Set64(p, curLen) + if (item.HashIndex >= 0) + memcpy(p + 0x10, streams[item.HashIndex].Hash, kHashSize); + totalLen += curLen; + p += curLen; + } + + FOR_VECTOR (si, item.AltStreams) + { + const CAltStream &ss = item.AltStreams[si]; + if (ss.Skip) + continue; + + fileNameLen = ss.Name.Len() * 2; + fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); + UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); + memset(p, 0, curLen); + + Set64(p, curLen) + if (ss.HashIndex >= 0) + memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize); + Set16(p + 0x24, (UInt16)fileNameLen) + for (i = 0; i * 2 < fileNameLen; i++) + Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]) + totalLen += curLen; + p += curLen; + } + } + + return totalLen; +} + + +struct CDb +{ + CMetaItem DefaultDirItem; + const CStreamInfo *Hashes; + CObjectVector MetaItems; + CRecordVector UpdateItems; + CUIntVector UpdateIndexes; /* indexes in UpdateItems in order of writing data streams + to disk (the order of tree items). */ + + size_t WriteTree_Dummy(const CDir &tree) const; + void WriteTree(const CDir &tree, Byte *dest, size_t &pos) const; + void WriteOrderList(const CDir &tree); +}; + + +size_t CDb::WriteTree_Dummy(const CDir &tree) const +{ + unsigned i; + size_t pos = 0; + for (i = 0; i < tree.Files.Size(); i++) + pos += WriteItem_Dummy(MetaItems[tree.Files[i]]); + for (i = 0; i < tree.Dirs.Size(); i++) + { + const CDir &subDir = tree.Dirs[i]; + pos += WriteItem_Dummy(MetaItems[subDir.MetaIndex]); + pos += WriteTree_Dummy(subDir); + } + return pos + 8; +} + + +void CDb::WriteTree(const CDir &tree, Byte *dest, size_t &pos) const +{ + unsigned i; + for (i = 0; i < tree.Files.Size(); i++) + pos += WriteItem(Hashes, MetaItems[tree.Files[i]], dest + pos); + + size_t posStart = pos; + for (i = 0; i < tree.Dirs.Size(); i++) + pos += WriteItem_Dummy(MetaItems[tree.Dirs[i].MetaIndex]); + + Set64(dest + pos, 0) + + pos += 8; + + for (i = 0; i < tree.Dirs.Size(); i++) + { + const CDir &subDir = tree.Dirs[i]; + const CMetaItem &metaItem = MetaItems[subDir.MetaIndex]; + bool needCreateTree = (metaItem.Reparse.Size() == 0) + || !subDir.Files.IsEmpty() + || !subDir.Dirs.IsEmpty(); + size_t len = WriteItem(Hashes, metaItem, dest + posStart); + posStart += len; + if (needCreateTree) + { + Set64(dest + posStart - len + 0x10, pos) // subdirOffset + WriteTree(subDir, dest, pos); + } + } +} + + +void CDb::WriteOrderList(const CDir &tree) +{ + if (tree.MetaIndex >= 0) + { + const CMetaItem &mi = MetaItems[tree.MetaIndex]; + if (mi.UpdateIndex >= 0) + UpdateIndexes.Add((unsigned)mi.UpdateIndex); + FOR_VECTOR (si, mi.AltStreams) + UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); + } + + unsigned i; + for (i = 0; i < tree.Files.Size(); i++) + { + const CMetaItem &mi = MetaItems[tree.Files[i]]; + UpdateIndexes.Add((unsigned)mi.UpdateIndex); + FOR_VECTOR (si, mi.AltStreams) + UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); + } + + for (i = 0; i < tree.Dirs.Size(); i++) + WriteOrderList(tree.Dirs[i]); +} + + +static void AddTag_ToString(AString &s, const char *name, const char *value) +{ + s.Add_Char('<'); + s += name; + s.Add_Char('>'); + s += value; + s.Add_Char('<'); + s.Add_Slash(); + s += name; + s.Add_Char('>'); +} + + +static void AddTagUInt64_ToString(AString &s, const char *name, UInt64 value) +{ + char temp[32]; + ConvertUInt64ToString(value, temp); + AddTag_ToString(s, name, temp); +} + + +static CXmlItem &AddUniqueTag(CXmlItem &parentItem, const char *name) +{ + const int index = parentItem.FindSubTag(name); + if (index < 0) + { + CXmlItem &subItem = parentItem.SubItems.AddNew(); + subItem.IsTag = true; + subItem.Name = name; + return subItem; + } + CXmlItem &subItem = parentItem.SubItems[index]; + subItem.SubItems.Clear(); + return subItem; +} + + +static void AddTag_UInt64_2(CXmlItem &item, UInt64 value) +{ + CXmlItem &subItem = item.SubItems.AddNew(); + subItem.IsTag = false; + char temp[32]; + ConvertUInt64ToString(value, temp); + subItem.Name = temp; +} + + +static void AddTag_UInt64(CXmlItem &parentItem, const char *name, UInt64 value) +{ + AddTag_UInt64_2(AddUniqueTag(parentItem, name), value); +} + + +static void AddTag_Hex(CXmlItem &item, const char *name, UInt32 value) +{ + item.IsTag = true; + item.Name = name; + char temp[16]; + temp[0] = '0'; + temp[1] = 'x'; + ConvertUInt32ToHex8Digits(value, temp + 2); + CXmlItem &subItem = item.SubItems.AddNew(); + subItem.IsTag = false; + subItem.Name = temp; +} + + +static void AddTag_Time_2(CXmlItem &item, const FILETIME &ft) +{ + AddTag_Hex(item.SubItems.AddNew(), "HIGHPART", ft.dwHighDateTime); + AddTag_Hex(item.SubItems.AddNew(), "LOWPART", ft.dwLowDateTime); +} + + +static void AddTag_Time(CXmlItem &parentItem, const char *name, const FILETIME &ft) +{ + AddTag_Time_2(AddUniqueTag(parentItem, name), ft); +} + + +static void AddTag_String_IfEmpty(CXmlItem &parentItem, const char *name, const char *value) +{ + if (parentItem.FindSubTag(name) >= 0) + return; + CXmlItem &tag = parentItem.SubItems.AddNew(); + tag.IsTag = true; + tag.Name = name; + CXmlItem &subItem = tag.SubItems.AddNew(); + subItem.IsTag = false; + subItem.Name = value; +} + + +void CHeader::SetDefaultFields(bool useLZX) +{ + Version = k_Version_NonSolid; + Flags = NHeaderFlags::kReparsePointFixup; + ChunkSize = 0; + if (useLZX) + { + Flags |= NHeaderFlags::kCompression | NHeaderFlags::kLZX; + ChunkSize = kChunkSize; + ChunkSizeBits = kChunkSizeBits; + } + MY_RAND_GEN(Guid, 16); + PartNumber = 1; + NumParts = 1; + NumImages = 1; + BootIndex = 0; + OffsetResource.Clear(); + XmlResource.Clear(); + MetadataResource.Clear(); + IntegrityResource.Clear(); +} + + +static void AddTrees(CObjectVector &trees, CObjectVector &metaItems, const CMetaItem &ri, int curTreeIndex) +{ + while (curTreeIndex >= (int)trees.Size()) + trees.AddNew().Dirs.AddNew().MetaIndex = (int)metaItems.Add(ri); +} + + +#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) + + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback)) +{ + COM_TRY_BEGIN + + if (!IsUpdateSupported()) + return E_NOTIMPL; + + bool isUpdate = (_volumes.Size() != 0); + int defaultImageIndex = _defaultImageNumber - 1; + bool showImageNumber; + + if (isUpdate) + { + showImageNumber = _showImageNumber; + if (!showImageNumber) + defaultImageIndex = _db.IndexOfUserImage; + } + else + { + showImageNumber = (_set_use_ShowImageNumber && _set_showImageNumber); + if (!showImageNumber) + defaultImageIndex = 0; + } + + if (defaultImageIndex >= kNumImagesMaxUpdate) + return E_NOTIMPL; + + CMyComPtr outStream; + RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)) + if (!outStream) + return E_NOTIMPL; + if (!callback) + return E_FAIL; + + CDb db; + CObjectVector trees; + + CMetaItem ri; // default DIR item + FILETIME ftCur; + NTime::GetCurUtcFileTime(ftCur); + // ri.MTime = ri.ATime = ri.CTime = ftCur; + ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; + ri.IsDir = true; + + + // ---------- Detect changed images ---------- + + unsigned i; + CBoolVector isChangedImage; + { + CUIntVector numUnchangedItemsInImage; + for (i = 0; i < _db.Images.Size(); i++) + { + numUnchangedItemsInImage.Add(0); + isChangedImage.Add(false); + } + + for (i = 0; i < numItems; i++) + { + UInt32 indexInArchive; + Int32 newData, newProps; + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) + if (newProps == 0) + { + if (indexInArchive >= _db.SortedItems.Size()) + continue; + const CItem &item = _db.Items[_db.SortedItems[indexInArchive]]; + if (newData == 0) + { + if (item.ImageIndex >= 0) + numUnchangedItemsInImage[item.ImageIndex]++; + } + else + { + // oldProps & newData. Current version of 7-Zip doesn't use it + if (item.ImageIndex >= 0) + isChangedImage[item.ImageIndex] = true; + } + } + else if (!showImageNumber) + { + if (defaultImageIndex >= 0 && defaultImageIndex < (int)isChangedImage.Size()) + isChangedImage[defaultImageIndex] = true; + } + else + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidPath, &prop)) + + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + const wchar_t *path = prop.bstrVal; + if (!path) + return E_INVALIDARG; + + const wchar_t *end; + UInt64 val = ConvertStringToUInt64(path, &end); + if (end == path) + return E_INVALIDARG; + if (val == 0 || val > kNumImagesMaxUpdate) + return E_INVALIDARG; + wchar_t c = *end; + if (c != 0 && c != ':' && c != L'/' && c != WCHAR_PATH_SEPARATOR) + return E_INVALIDARG; + unsigned imageIndex = (unsigned)val - 1; + if (imageIndex < _db.Images.Size()) + isChangedImage[imageIndex] = true; + if (_defaultImageNumber > 0 && val != (unsigned)_defaultImageNumber) + return E_INVALIDARG; + } + } + + for (i = 0; i < _db.Images.Size(); i++) + if (!isChangedImage[i]) + isChangedImage[i] = _db.GetNumUserItemsInImage(i) != numUnchangedItemsInImage[i]; + } + + if (defaultImageIndex >= 0) + { + for (i = 0; i < _db.Images.Size(); i++) + if ((int)i != defaultImageIndex) + isChangedImage[i] = false; + } + + CMyComPtr getRawProps; + callback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); + + CMyComPtr getRootProps; + callback->QueryInterface(IID_IArchiveGetRootProps, (void **)&getRootProps); + + CObjectVector secureBlocks; + + if (!showImageNumber && (getRootProps || isUpdate) && + ( + defaultImageIndex >= (int)isChangedImage.Size() + || defaultImageIndex < 0 // test it + || isChangedImage[defaultImageIndex] + )) + { + // Fill Root Item: Metadata and security + CMetaItem rootItem = ri; + { + const void *data = NULL; + UInt32 dataSize = 0; + UInt32 propType = 0; + if (getRootProps) + { + RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) + } + if (dataSize == 0 && isUpdate) + { + RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) + } + if (dataSize != 0) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + while (defaultImageIndex >= (int)secureBlocks.Size()) + secureBlocks.AddNew(); + CUniqBlocks &secUniqBlocks = secureBlocks[defaultImageIndex]; + rootItem.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); + } + } + + IArchiveGetRootProps *thisGetRoot = isUpdate ? this : NULL; + + if (_timeOptions.Write_CTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)) + if (_timeOptions.Write_ATime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)) + if (_timeOptions.Write_MTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)) + + { + NCOM::CPropVariant prop; + if (getRootProps) + { + RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + rootItem.Attrib = prop.ulVal; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + if (prop.vt == VT_EMPTY && thisGetRoot) + { + RINOK(GetRootProp(kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + rootItem.Attrib = prop.ulVal; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + rootItem.Attrib |= FILE_ATTRIBUTE_DIRECTORY; + } + + AddTrees(trees, db.MetaItems, ri, defaultImageIndex); + db.MetaItems[trees[defaultImageIndex].Dirs[0].MetaIndex] = rootItem; + } + + // ---------- Request Metadata for changed items ---------- + + UString fileName; + + for (i = 0; i < numItems; i++) + { + CUpdateItem ui; + UInt32 indexInArchive; + Int32 newData, newProps; + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) + + if (newData == 0 || newProps == 0) + { + if (indexInArchive >= _db.SortedItems.Size()) + continue; + + const CItem &item = _db.Items[_db.SortedItems[indexInArchive]]; + + if (item.ImageIndex >= 0) + { + if (!isChangedImage[item.ImageIndex]) + { + if (newData == 0 && newProps == 0) + continue; + return E_FAIL; + } + } + else + { + // if deleted item was not renamed, we just skip it + if (newProps == 0) + continue; + if (item.StreamIndex >= 0) + { + // we don't support property change for SolidBig streams + if (_db.DataStreams[item.StreamIndex].Resource.IsSolidBig()) + return E_NOTIMPL; + } + } + + if (newData == 0) + ui.InArcIndex = (Int32)indexInArchive; + } + + // we set arcIndex only if we must use old props + const Int32 arcIndex = (newProps ? -1 : (Int32)indexInArchive); + + bool isDir = false; + { + NCOM::CPropVariant prop; + RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)) + if (prop.vt == VT_BOOL) + isDir = (prop.boolVal != VARIANT_FALSE); + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + + bool isAltStream = false; + { + NCOM::CPropVariant prop; + RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)) + if (prop.vt == VT_BOOL) + isAltStream = (prop.boolVal != VARIANT_FALSE); + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + + if (isDir && isAltStream) + return E_INVALIDARG; + + UInt64 size = 0; + UInt64 iNode = 0; + + if (!isDir) + { + if (!newData) + { + NCOM::CPropVariant prop; + GetProperty(indexInArchive, kpidINode, &prop); + if (prop.vt == VT_UI8) + iNode = prop.uhVal.QuadPart; + } + + NCOM::CPropVariant prop; + + if (newData) + { + RINOK(callback->GetProperty(i, kpidSize, &prop)) + } + else + { + RINOK(GetProperty(indexInArchive, kpidSize, &prop)) + } + + if (prop.vt == VT_UI8) + size = prop.uhVal.QuadPart; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + + { + NCOM::CPropVariant propPath; + const wchar_t *path = NULL; + RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)) + if (propPath.vt == VT_BSTR) + path = propPath.bstrVal; + else if (propPath.vt != VT_EMPTY) + return E_INVALIDARG; + + if (!path) + return E_INVALIDARG; + + CDir *curItem = NULL; + bool isRootImageDir = false; + fileName.Empty(); + + int imageIndex; + + if (!showImageNumber) + { + imageIndex = defaultImageIndex; + AddTrees(trees, db.MetaItems, ri, imageIndex); + curItem = &trees[imageIndex].Dirs[0]; + } + else + { + const wchar_t *end; + UInt64 val = ConvertStringToUInt64(path, &end); + if (end == path) + return E_INVALIDARG; + if (val == 0 || val > kNumImagesMaxUpdate) + return E_INVALIDARG; + + imageIndex = (int)val - 1; + if (imageIndex < (int)isChangedImage.Size()) + if (!isChangedImage[imageIndex]) + return E_FAIL; + + AddTrees(trees, db.MetaItems, ri, imageIndex); + curItem = &trees[imageIndex].Dirs[0]; + wchar_t c = *end; + + if (c == 0) + { + if (!isDir || isAltStream) + return E_INVALIDARG; + ui.MetaIndex = curItem->MetaIndex; + isRootImageDir = true; + } + else if (c == ':') + { + if (isDir || !isAltStream) + return E_INVALIDARG; + ui.MetaIndex = curItem->MetaIndex; + CAltStream ss; + ss.Size = size; + ss.Name = end + 1; + ss.UpdateIndex = (int)db.UpdateItems.Size(); + ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); + } + else if (c == WCHAR_PATH_SEPARATOR || c == L'/') + { + path = end + 1; + if (*path == 0) + return E_INVALIDARG; + } + else + return E_INVALIDARG; + } + + if (ui.MetaIndex < 0) + { + for (;;) + { + const wchar_t c = *path++; + if (c == 0) + break; + if (c == WCHAR_PATH_SEPARATOR || c == L'/') + { + unsigned indexOfDir; + if (!curItem->FindDir(db.MetaItems, fileName, indexOfDir)) + { + CDir &dir = curItem->Dirs.InsertNew(indexOfDir); + dir.MetaIndex = (int)db.MetaItems.Add(ri); + db.MetaItems.Back().Name = fileName; + } + curItem = &curItem->Dirs[indexOfDir]; + fileName.Empty(); + } + else + { + /* + #if WCHAR_MAX > 0xffff + if (c >= 0x10000) + { + c -= 0x10000; + + if (c < (1 << 20)) + { + wchar_t c0 = 0xd800 + ((c >> 10) & 0x3FF); + fileName += c0; + c = 0xdc00 + (c & 0x3FF); + } + else + c = '_'; // we change character unsupported by UTF16 + } + #endif + */ + + fileName += c; + } + } + + if (isAltStream) + { + int colonPos = fileName.Find(L':'); + if (colonPos < 0) + return E_INVALIDARG; + + // we want to support cases of c::substream, where c: is drive name + if (colonPos == 1 && fileName[2] == L':' && IS_LETTER_CHAR(fileName[0])) + colonPos = 2; + const UString mainName = fileName.Left((unsigned)colonPos); + unsigned indexOfDir; + + if (mainName.IsEmpty()) + ui.MetaIndex = curItem->MetaIndex; + else if (curItem->FindDir(db.MetaItems, mainName, indexOfDir)) + ui.MetaIndex = curItem->Dirs[indexOfDir].MetaIndex; + else + { + for (int j = (int)curItem->Files.Size() - 1; j >= 0; j--) + { + const unsigned metaIndex = curItem->Files[j]; + const CMetaItem &mi = db.MetaItems[metaIndex]; + if (CompareFileNames(mainName, mi.Name) == 0) + { + ui.MetaIndex = (int)metaIndex; + break; + } + } + } + + if (ui.MetaIndex >= 0) + { + CAltStream ss; + ss.Size = size; + ss.Name = fileName.Ptr(colonPos + 1); + ss.UpdateIndex = (int)db.UpdateItems.Size(); + ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); + } + } + } + + + if (ui.MetaIndex < 0 || isRootImageDir) + { + if (!isRootImageDir) + { + ui.MetaIndex = (int)db.MetaItems.Size(); + db.MetaItems.AddNew(); + } + + CMetaItem &mi = db.MetaItems[ui.MetaIndex]; + mi.Size = size; + mi.IsDir = isDir; + mi.Name = fileName; + mi.UpdateIndex = (int)db.UpdateItems.Size(); + { + NCOM::CPropVariant prop; + RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)) + if (prop.vt == VT_EMPTY) + mi.Attrib = 0; + else if (prop.vt == VT_UI4) + mi.Attrib = prop.ulVal; + else + return E_INVALIDARG; + if (isDir) + mi.Attrib |= FILE_ATTRIBUTE_DIRECTORY; + } + + if (arcIndex != -1 || _timeOptions.Write_CTime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)) + if (arcIndex != -1 || _timeOptions.Write_ATime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)) + if (arcIndex != -1 || _timeOptions.Write_MTime.Val) + RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)) + + { + NCOM::CPropVariant prop; + RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)) + if (prop.vt == VT_BSTR) + mi.ShortName.SetFromBstr(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + + while (imageIndex >= (int)secureBlocks.Size()) + secureBlocks.AddNew(); + + if (!isAltStream && (getRawProps || arcIndex >= 0)) + { + CUniqBlocks &secUniqBlocks = secureBlocks[imageIndex]; + const void *data; + UInt32 dataSize; + UInt32 propType; + + data = NULL; + dataSize = 0; + propType = 0; + + if (arcIndex >= 0) + { + GetRawProp((UInt32)arcIndex, kpidNtSecure, &data, &dataSize, &propType); + } + else + { + getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType); + } + + if (dataSize != 0) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + mi.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); + } + + data = NULL; + dataSize = 0; + propType = 0; + + if (arcIndex >= 0) + { + GetRawProp((UInt32)arcIndex, kpidNtReparse, &data, &dataSize, &propType); + } + else + { + getRawProps->GetRawProp(i, kpidNtReparse, &data, &dataSize, &propType); + } + + if (dataSize != 0) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + mi.Reparse.CopyFrom((const Byte *)data, dataSize); + } + } + + if (!isRootImageDir) + { + if (isDir) + { + unsigned indexOfDir; + if (curItem->FindDir(db.MetaItems, fileName, indexOfDir)) + curItem->Dirs[indexOfDir].MetaIndex = ui.MetaIndex; + else + curItem->Dirs.InsertNew(indexOfDir).MetaIndex = ui.MetaIndex; + } + else + curItem->Files.Add((unsigned)ui.MetaIndex); + } + } + + } + + if (iNode != 0 && ui.MetaIndex >= 0 && ui.AltStreamIndex < 0) + db.MetaItems[ui.MetaIndex].FileID = iNode; + + ui.CallbackIndex = i; + db.UpdateItems.Add(ui); + } + + unsigned numNewImages = trees.Size(); + for (i = numNewImages; i < isChangedImage.Size(); i++) + if (!isChangedImage[i]) + numNewImages = i + 1; + + AddTrees(trees, db.MetaItems, ri, (int)numNewImages - 1); + + for (i = 0; i < trees.Size(); i++) + if (i >= isChangedImage.Size() || isChangedImage[i]) + db.WriteOrderList(trees[i]); + + + UInt64 complexity = 0; + + unsigned numDataStreams = _db.DataStreams.Size(); + CUIntArr streamsRefs(numDataStreams); + for (i = 0; i < numDataStreams; i++) + streamsRefs[i] = 0; + + // ---------- Calculate Streams Refs Counts in unchanged images + + for (i = 0; i < _db.Images.Size(); i++) + { + if (isChangedImage[i]) + continue; + complexity += _db.MetaStreams[i].Resource.PackSize; + const CImage &image = _db.Images[i]; + unsigned endItem = image.StartItem + image.NumItems; + for (unsigned k = image.StartItem; k < endItem; k++) + { + const CItem &item = _db.Items[k]; + if (item.StreamIndex >= 0) + streamsRefs[(unsigned)item.StreamIndex]++; + } + } + + + // ---------- Update Streams Refs Counts in changed images + + for (i = 0; i < db.UpdateIndexes.Size(); i++) + { + const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; + + if (ui.InArcIndex >= 0) + { + if ((unsigned)ui.InArcIndex >= _db.SortedItems.Size()) + continue; + const CItem &item = _db.Items[_db.SortedItems[ui.InArcIndex]]; + if (item.StreamIndex >= 0) + streamsRefs[(unsigned)item.StreamIndex]++; + } + else + { + const CMetaItem &mi = db.MetaItems[ui.MetaIndex]; + UInt64 size; + if (ui.AltStreamIndex < 0) + size = mi.Size; + else + size = mi.AltStreams[ui.AltStreamIndex].Size; + complexity += size; + } + } + + // Clear ref counts for SolidBig streams + + for (i = 0; i < _db.DataStreams.Size(); i++) + if (_db.DataStreams[i].Resource.IsSolidBig()) + streamsRefs[i] = 0; + + // Set ref counts for SolidBig streams + + for (i = 0; i < _db.DataStreams.Size(); i++) + if (streamsRefs[i] != 0) + { + const CResource &rs = _db.DataStreams[i].Resource; + if (rs.IsSolidSmall()) + streamsRefs[_db.Solids[rs.SolidIndex].StreamIndex] = 1; + } + + for (i = 0; i < _db.DataStreams.Size(); i++) + if (streamsRefs[i] != 0) + { + const CResource &rs = _db.DataStreams[i].Resource; + if (!rs.IsSolidSmall()) + complexity += rs.PackSize; + } + + RINOK(callback->SetTotal(complexity)) + UInt64 totalComplexity = complexity; + + CMyComPtr2_Create lps; + lps->Init(callback, true); + CMyComPtr2_Create copyCoder; + + complexity = 0; + + // bool useResourceCompression = false; + // use useResourceCompression only if CHeader::Flags compression is also set + + CHeader header; + header.SetDefaultFields(false); + + if (isUpdate) + { + const CHeader &srcHeader = _volumes[1].Header; + header.Flags = srcHeader.Flags; + header.Version = srcHeader.Version; + header.ChunkSize = srcHeader.ChunkSize; + header.ChunkSizeBits = srcHeader.ChunkSizeBits; + } + + CMyComPtr setRestriction; + outSeqStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, kHeaderSizeMax)) + + { + Byte buf[kHeaderSizeMax]; + header.WriteTo(buf); + RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) + } + + UInt64 curPos = kHeaderSizeMax; + + CMyComPtr2_Create inShaStream; + + CLimitedSequentialInStream *inStreamLimitedSpec = NULL; + CMyComPtr inStreamLimited; + if (_volumes.Size() == 2) + { + inStreamLimitedSpec = new CLimitedSequentialInStream; + inStreamLimited = inStreamLimitedSpec; + inStreamLimitedSpec->SetStream(_volumes[1].Stream); + } + + + CRecordVector streams; + CSortedIndex sortedHashes; // indexes to streams, sorted by SHA1 + + // ---------- Copy unchanged data streams ---------- + + UInt64 solidRunOffset = 0; + UInt64 curSolidSize = 0; + + for (i = 0; i < _db.DataStreams.Size(); i++) + { + const CStreamInfo &siOld = _db.DataStreams[i]; + const CResource &rs = siOld.Resource; + + const unsigned numRefs = streamsRefs[i]; + + if (numRefs == 0) + { + if (!rs.IsSolidSmall()) + continue; + if (streamsRefs[_db.Solids[rs.SolidIndex].StreamIndex] == 0) + continue; + } + + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()) + + const unsigned streamIndex = streams.Size(); + CStreamInfo s; + s.Resource = rs; + s.PartNumber = 1; + s.RefCount = numRefs; + + memcpy(s.Hash, siOld.Hash, kHashSize); + + if (rs.IsSolid()) + { + CSolid &ss = _db.Solids[rs.SolidIndex]; + if (rs.IsSolidSmall()) + { + UInt64 oldOffset = ss.SolidOffset; + if (rs.Offset < oldOffset) + return E_FAIL; + UInt64 relatOffset = rs.Offset - oldOffset; + s.Resource.Offset = solidRunOffset + relatOffset; + } + else + { + // IsSolidBig + solidRunOffset += curSolidSize; + curSolidSize = ss.UnpackSize; + } + } + else + { + solidRunOffset = 0; + curSolidSize = 0; + } + + if (!rs.IsSolid() || rs.IsSolidSmall()) + { + const int find = AddUniqHash(streams.ConstData(), sortedHashes, siOld.Hash, (int)streamIndex); + if (find != -1) + return E_FAIL; // two streams with same SHA-1 + } + + if (!rs.IsSolid() || rs.IsSolidBig()) + { + RINOK(InStream_SeekSet(_volumes[siOld.PartNumber].Stream, rs.Offset)) + inStreamLimitedSpec->Init(rs.PackSize); + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != rs.PackSize) + return E_FAIL; + s.Resource.Offset = curPos; + curPos += rs.PackSize; + lps->ProgressOffset += rs.PackSize; + } + + streams.Add(s); + } + + + // ---------- Write new items ---------- + + CUIntVector hlIndexes; // sorted indexes for hard link items + + for (i = 0; i < db.UpdateIndexes.Size(); i++) + { + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()) + const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; + CMetaItem &mi = db.MetaItems[ui.MetaIndex]; + UInt64 size = 0; + + if (ui.AltStreamIndex >= 0) + { + if (mi.Skip) + continue; + size = mi.AltStreams[ui.AltStreamIndex].Size; + } + else + { + size = mi.Size; + if (mi.IsDir) + { + // we support LINK files here + if (mi.Reparse.Size() == 0) + continue; + } + } + + if (ui.InArcIndex >= 0) + { + // data streams with OLD Data were written already + // we just need to find HashIndex in hashes. + + if ((unsigned)ui.InArcIndex >= _db.SortedItems.Size()) + return E_FAIL; + + const CItem &item = _db.Items[_db.SortedItems[ui.InArcIndex]]; + + if (item.StreamIndex < 0) + { + if (size == 0) + continue; + // if (_db.ItemHasStream(item)) + return E_FAIL; + } + + // We support empty file (size = 0, but with stream and SHA-1) from old archive + + const CStreamInfo &siOld = _db.DataStreams[item.StreamIndex]; + + const int index = AddUniqHash(streams.ConstData(), sortedHashes, siOld.Hash, -1); + // we must have written that stream already + if (index == -1) + return E_FAIL; + + if (ui.AltStreamIndex < 0) + mi.HashIndex = index; + else + mi.AltStreams[ui.AltStreamIndex].HashIndex = index; + + continue; + } + + CMyComPtr fileInStream; + HRESULT res = callback->GetStream(ui.CallbackIndex, &fileInStream); + + if (res == S_FALSE) + { + if (ui.AltStreamIndex >= 0) + { + mi.NumSkipAltStreams++; + mi.AltStreams[ui.AltStreamIndex].Skip = true; + } + else + mi.Skip = true; + } + else + { + RINOK(res) + + int miIndex = -1; + + if (!fileInStream) + { + if (!mi.IsDir) + return E_INVALIDARG; + } + else if (ui.AltStreamIndex < 0) + { + CMyComPtr getProps2; + fileInStream->QueryInterface(IID_IStreamGetProps2, (void **)&getProps2); + if (getProps2) + { + CStreamFileProps props; + if (getProps2->GetProps2(&props) == S_OK) + { + mi.Attrib = props.Attrib; + if (_timeOptions.Write_CTime.Val) mi.CTime = props.CTime; + if (_timeOptions.Write_ATime.Val) mi.ATime = props.ATime; + if (_timeOptions.Write_MTime.Val) mi.MTime = props.MTime; + mi.FileID = props.FileID_Low; + if (props.NumLinks <= 1) + mi.FileID = 0; + mi.VolID = props.VolID; + if (mi.FileID != 0) + miIndex = AddToHardLinkList(db.MetaItems, (unsigned)ui.MetaIndex, hlIndexes); + + if (props.Size != size && props.Size != (UInt64)(Int64)-1) + { + const Int64 delta = (Int64)props.Size - (Int64)size; + const Int64 newComplexity = (Int64)totalComplexity + delta; + if (newComplexity > 0) + { + totalComplexity = (UInt64)newComplexity; + callback->SetTotal(totalComplexity); + } + mi.Size = props.Size; + size = props.Size; + } + } + } + } + + if (miIndex >= 0) + { + mi.HashIndex = db.MetaItems[miIndex].HashIndex; + if (mi.HashIndex >= 0) + streams[mi.HashIndex].RefCount++; + // fix for future: maybe we need to check also that real size is equal to size from IStreamGetProps2 + } + else if (ui.AltStreamIndex < 0 && mi.Reparse.Size() != 0) + { + if (mi.Reparse.Size() < 8) + return E_FAIL; + NCrypto::NSha1::CContext sha1; + sha1.Init(); + const size_t packSize = mi.Reparse.Size() - 8; + sha1.Update((const Byte *)mi.Reparse + 8, packSize); + Byte hash[kHashSize]; + sha1.Final(hash); + + int index = AddUniqHash(streams.ConstData(), sortedHashes, hash, (int)streams.Size()); + + if (index != -1) + streams[index].RefCount++; + else + { + index = (int)streams.Size(); + RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)) + CStreamInfo s; + s.Resource.PackSize = packSize; + s.Resource.Offset = curPos; + s.Resource.UnpackSize = packSize; + s.Resource.Flags = 0; // check it + /* + if (useResourceCompression) + s.Resource.Flags = NResourceFlags::Compressed; + */ + s.PartNumber = 1; + s.RefCount = 1; + memcpy(s.Hash, hash, kHashSize); + curPos += packSize; + + streams.Add(s); + } + + mi.HashIndex = index; + } + else + { + inShaStream->SetStream(fileInStream); + + CMyComPtr inSeekStream; + fileInStream.QueryInterface(IID_IInStream, (void **)&inSeekStream); + + fileInStream.Release(); + inShaStream->Init(); + UInt64 offsetBlockSize = 0; + /* + if (useResourceCompression) + { + for (UInt64 t = kChunkSize; t < size; t += kChunkSize) + { + Byte buf[8]; + SetUi32(buf, (UInt32)t); + RINOK(WriteStream(outStream, buf, 4)); + offsetBlockSize += 4; + } + } + */ + + // 22.02: we use additional read-only pass to calculate SHA-1 + bool needWritePass = true; + int index = -1; + + if (inSeekStream /* && !sortedHashes.IsEmpty() */) + { + RINOK(copyCoder.Interface()->Code(inShaStream, NULL, NULL, NULL, lps)) + size = copyCoder->TotalSize; + if (size == 0) + needWritePass = false; + else + { + Byte hash[kHashSize]; + inShaStream->Final(hash); + + index = AddUniqHash(streams.ConstData(), sortedHashes, hash, -1); + if (index != -1) + { + streams[index].RefCount++; + needWritePass = false; + } + else + { + RINOK(InStream_SeekToBegin(inSeekStream)) + inShaStream->Init(); + } + } + } + + if (needWritePass) + { + RINOK(copyCoder.Interface()->Code(inShaStream, outStream, NULL, NULL, lps)) + size = copyCoder->TotalSize; + } + + if (size != 0) + { + if (needWritePass) + { + Byte hash[kHashSize]; + const UInt64 packSize = offsetBlockSize + size; + inShaStream->Final(hash); + + index = AddUniqHash(streams.ConstData(), sortedHashes, hash, (int)streams.Size()); + + if (index != -1) + { + streams[index].RefCount++; + outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); + outStream->SetSize(curPos); + } + else + { + index = (int)streams.Size(); + CStreamInfo s; + s.Resource.PackSize = packSize; + s.Resource.Offset = curPos; + s.Resource.UnpackSize = size; + s.Resource.Flags = 0; + /* + if (useResourceCompression) + s.Resource.Flags = NResourceFlags::Compressed; + */ + s.PartNumber = 1; + s.RefCount = 1; + memcpy(s.Hash, hash, kHashSize); + curPos += packSize; + + streams.Add(s); + } + } // needWritePass + if (ui.AltStreamIndex < 0) + mi.HashIndex = index; + else + mi.AltStreams[ui.AltStreamIndex].HashIndex = index; + } // (size != 0) + } + } + fileInStream.Release(); + complexity += size; + RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + } + + while (secureBlocks.Size() < numNewImages) + secureBlocks.AddNew(); + + + + // ---------- Write Images ---------- + + for (i = 0; i < numNewImages; i++) + { + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()) + if (i < isChangedImage.Size() && !isChangedImage[i]) + { + CStreamInfo s = _db.MetaStreams[i]; + + RINOK(InStream_SeekSet(_volumes[1].Stream, s.Resource.Offset)) + inStreamLimitedSpec->Init(s.Resource.PackSize); + RINOK(copyCoder.Interface()->Code(inStreamLimited, outStream, NULL, NULL, lps)) + if (copyCoder->TotalSize != s.Resource.PackSize) + return E_FAIL; + + s.Resource.Offset = curPos; + s.PartNumber = 1; + s.RefCount = 1; + streams.Add(s); + + if (_bootIndex != 0 && _bootIndex == (UInt32)i + 1) + { + header.MetadataResource = s.Resource; + header.BootIndex = _bootIndex; + } + + lps->ProgressOffset += s.Resource.PackSize; + curPos += s.Resource.PackSize; + // printf("\nWrite old image %x\n", i + 1); + continue; + } + + const CDir &tree = trees[i]; + const UInt32 kSecuritySize = 8; + + size_t pos = kSecuritySize; + + const CUniqBlocks &secUniqBlocks = secureBlocks[i]; + const CObjectVector &secBufs = secUniqBlocks.Bufs; + pos += (size_t)secUniqBlocks.GetTotalSizeInBytes(); + pos += secBufs.Size() * 8; + pos = (pos + 7) & ~(size_t)7; + + db.DefaultDirItem = ri; + pos += db.WriteTree_Dummy(tree); + + CByteArr meta(pos); + + Set32((Byte *)meta + 4, secBufs.Size()) // num security entries + pos = kSecuritySize; + + if (secBufs.Size() == 0) + { + // we can write 0 here only if there is no security data, imageX does it, + // but some programs expect size = 8 + Set32((Byte *)meta, 8) // size of security data + // Set32((Byte *)meta, 0); + } + else + { + unsigned k; + for (k = 0; k < secBufs.Size(); k++, pos += 8) + { + Set64(meta + pos, secBufs[k].Size()) + } + for (k = 0; k < secBufs.Size(); k++) + { + const CByteBuffer &buf = secBufs[k]; + size_t size = buf.Size(); + if (size != 0) + { + memcpy(meta + pos, buf, size); + pos += size; + } + } + while ((pos & 7) != 0) + meta[pos++] = 0; + Set32((Byte *)meta, (UInt32)pos) // size of security data + } + + db.Hashes = streams.ConstData(); + db.WriteTree(tree, (Byte *)meta, pos); + + { + NCrypto::NSha1::CContext sha; + sha.Init(); + sha.Update((const Byte *)meta, pos); + + Byte digest[kHashSize]; + sha.Final(digest); + + CStreamInfo s; + s.Resource.PackSize = pos; + s.Resource.Offset = curPos; + s.Resource.UnpackSize = pos; + s.Resource.Flags = NResourceFlags::kMetadata; + s.PartNumber = 1; + s.RefCount = 1; + memcpy(s.Hash, digest, kHashSize); + streams.Add(s); + + if (_bootIndex != 0 && _bootIndex == (UInt32)i + 1) + { + header.MetadataResource = s.Resource; + header.BootIndex = _bootIndex; + } + + RINOK(WriteStream(outStream, (const Byte *)meta, pos)) + meta.Free(); + curPos += pos; + } + } + + lps->InSize = lps->OutSize = complexity; + RINOK(lps->SetCur()) + + header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; + header.OffsetResource.Offset = curPos; + header.OffsetResource.Flags = NResourceFlags::kMetadata; + + + + // ---------- Write Streams Info Tables ---------- + + for (i = 0; i < streams.Size(); i++) + { + Byte buf[kStreamInfoSize]; + streams[i].WriteTo(buf); + RINOK(WriteStream(outStream, buf, kStreamInfoSize)) + curPos += kStreamInfoSize; + } + + AString xml (""); + AddTagUInt64_ToString(xml, "TOTALBYTES", curPos); + for (i = 0; i < trees.Size(); i++) + { + const CDir &tree = trees[i]; + + CXmlItem item; + if (_xmls.Size() == 1) + { + const CWimXml &_oldXml = _xmls[0]; + if (i < _oldXml.Images.Size()) + { + // int ttt = _oldXml.Images[i].ItemIndexInXml; + item = _oldXml.Xml.Root.SubItems[_oldXml.Images[i].ItemIndexInXml]; + } + } + if (i >= isChangedImage.Size() || isChangedImage[i]) + { + char temp[16]; + if (item.Name.IsEmpty()) + { + ConvertUInt32ToString(i + 1, temp); + item.Name = "IMAGE"; + item.IsTag = true; + CXmlProp &prop = item.Props.AddNew(); + prop.Name = "INDEX"; + prop.Value = temp; + } + + AddTag_String_IfEmpty(item, "NAME", temp); + AddTag_UInt64(item, "DIRCOUNT", tree.GetNumDirs() - 1); + AddTag_UInt64(item, "FILECOUNT", tree.GetNumFiles()); + AddTag_UInt64(item, "TOTALBYTES", tree.GetTotalSize(db.MetaItems)); + + AddTag_Time(item, "CREATIONTIME", ftCur); + AddTag_Time(item, "LASTMODIFICATIONTIME", ftCur); + } + + item.AppendTo(xml); + } + xml += ""; + + size_t xmlSize; + { + UString utf16; + if (!ConvertUTF8ToUnicode(xml, utf16)) + return S_FALSE; + xmlSize = ((size_t)utf16.Len() + 1) * 2; + + CByteArr xmlBuf(xmlSize); + Set16((Byte *)xmlBuf, 0xFEFF) + for (i = 0; i < (unsigned)utf16.Len(); i++) + { + Set16((Byte *)xmlBuf + 2 + (size_t)i * 2, (UInt16)utf16[i]) + } + RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)) + } + + header.XmlResource.UnpackSize = + header.XmlResource.PackSize = xmlSize; + header.XmlResource.Offset = curPos; + header.XmlResource.Flags = NResourceFlags::kMetadata; + + outStream->Seek(0, STREAM_SEEK_SET, NULL); + header.NumImages = trees.Size(); + { + Byte buf[kHeaderSizeMax]; + header.WriteTo(buf); + RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) + } + + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + + return S_OK; + + COM_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimIn.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,1861 +1,1856 @@ -// Archive/WimIn.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/IntToString.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/UTFConvert.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/XpressDecoder.h" - -#include "../Common/OutStreamWithSha1.h" - -#include "WimIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -namespace NArchive { -namespace NWim { - -static int inline GetLog(UInt32 num) -{ - for (int i = 0; i < 32; i++) - if (((UInt32)1 << i) == num) - return i; - return -1; -} - - -CUnpacker::~CUnpacker() -{ - if (lzmsDecoder) - delete lzmsDecoder; -} - - -HRESULT CUnpacker::UnpackChunk( - ISequentialInStream *inStream, - unsigned method, unsigned chunkSizeBits, - size_t inSize, size_t outSize, - ISequentialOutStream *outStream) -{ - if (inSize == outSize) - { - } - else if (method == NMethod::kXPRESS) - { - } - else if (method == NMethod::kLZX) - { - if (!lzxDecoder) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder(true); - lzxDecoder = lzxDecoderSpec; - } - } - else if (method == NMethod::kLZMS) - { - if (!lzmsDecoder) - lzmsDecoder = new NCompress::NLzms::CDecoder(); - } - else - return E_NOTIMPL; - - const size_t chunkSize = (size_t)1 << chunkSizeBits; - - unpackBuf.EnsureCapacity(chunkSize); - if (!unpackBuf.Data) - return E_OUTOFMEMORY; - - HRESULT res = S_FALSE; - size_t unpackedSize = 0; - - if (inSize == outSize) - { - unpackedSize = outSize; - res = ReadStream(inStream, unpackBuf.Data, &unpackedSize); - TotalPacked += unpackedSize; - } - else if (inSize < chunkSize) - { - packBuf.EnsureCapacity(chunkSize); - if (!packBuf.Data) - return E_OUTOFMEMORY; - - RINOK(ReadStream_FALSE(inStream, packBuf.Data, inSize)); - - TotalPacked += inSize; - - if (method == NMethod::kXPRESS) - { - res = NCompress::NXpress::Decode(packBuf.Data, inSize, unpackBuf.Data, outSize); - if (res == S_OK) - unpackedSize = outSize; - } - else if (method == NMethod::kLZX) - { - lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits); - lzxDecoderSpec->KeepHistoryForNext = false; - lzxDecoderSpec->SetKeepHistory(false); - res = lzxDecoderSpec->Code(packBuf.Data, inSize, (UInt32)outSize); - unpackedSize = lzxDecoderSpec->GetUnpackSize(); - if (res == S_OK && !lzxDecoderSpec->WasBlockFinished()) - res = S_FALSE; - } - else - { - res = lzmsDecoder->Code(packBuf.Data, inSize, unpackBuf.Data, outSize); - unpackedSize = lzmsDecoder->GetUnpackSize();; - } - } - - if (unpackedSize != outSize) - { - if (res == S_OK) - res = S_FALSE; - - if (unpackedSize > outSize) - res = S_FALSE; - else - memset(unpackBuf.Data + unpackedSize, 0, outSize - unpackedSize); - } - - if (outStream) - { - RINOK(WriteStream(outStream, unpackBuf.Data, outSize)); - } - - return res; -} - - -HRESULT CUnpacker::Unpack2( - IInStream *inStream, - const CResource &resource, - const CHeader &header, - const CDatabase *db, - ISequentialOutStream *outStream, - ICompressProgressInfo *progress) -{ - if (!resource.IsCompressed() && !resource.IsSolid()) - { - if (!copyCoder) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } - - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream(); - CMyComPtr limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(inStream); - - RINOK(inStream->Seek(resource.Offset, STREAM_SEEK_SET, NULL)); - if (resource.PackSize != resource.UnpackSize) - return S_FALSE; - - limitedStreamSpec->Init(resource.PackSize); - TotalPacked += resource.PackSize; - - HRESULT res = copyCoder->Code(limitedStream, outStream, NULL, NULL, progress); - - if (res == S_OK && copyCoderSpec->TotalSize != resource.UnpackSize) - res = S_FALSE; - return res; - } - - if (resource.IsSolid()) - { - if (!db || resource.SolidIndex < 0) - return E_NOTIMPL; - if (resource.IsCompressed()) - return E_NOTIMPL; - - const CSolid &ss = db->Solids[resource.SolidIndex]; - - const unsigned chunkSizeBits = ss.ChunkSizeBits; - const size_t chunkSize = (size_t)1 << chunkSizeBits; - - size_t chunkIndex = 0; - UInt64 rem = ss.UnpackSize; - size_t offsetInChunk = 0; - - if (resource.IsSolidSmall()) - { - UInt64 offs = resource.Offset; - if (offs < ss.SolidOffset) - return E_NOTIMPL; - offs -= ss.SolidOffset; - if (offs > ss.UnpackSize) - return E_NOTIMPL; - rem = resource.PackSize; - if (rem > ss.UnpackSize - offs) - return E_NOTIMPL; - chunkIndex = (size_t)(offs >> chunkSizeBits); - offsetInChunk = (size_t)offs & (chunkSize - 1); - } - - UInt64 packProcessed = 0; - UInt64 outProcessed = 0; - - if (_solidIndex == resource.SolidIndex && _unpackedChunkIndex == chunkIndex) - { - size_t cur = chunkSize - offsetInChunk; - if (cur > rem) - cur = (size_t)rem; - RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)); - outProcessed += cur; - rem -= cur; - offsetInChunk = 0; - chunkIndex++; - } - - for (;;) - { - if (rem == 0) - return S_OK; - - UInt64 offset = ss.Chunks[chunkIndex]; - UInt64 packSize = ss.GetChunkPackSize(chunkIndex); - const CResource &rs = db->DataStreams[ss.StreamIndex].Resource; - RINOK(inStream->Seek(rs.Offset + ss.HeadersSize + offset, STREAM_SEEK_SET, NULL)); - - size_t cur = chunkSize; - UInt64 unpackRem = ss.UnpackSize - ((UInt64)chunkIndex << chunkSizeBits); - if (cur > unpackRem) - cur = (size_t)unpackRem; - - _solidIndex = -1; - _unpackedChunkIndex = 0; - - HRESULT res = UnpackChunk(inStream, ss.Method, chunkSizeBits, (size_t)packSize, cur, NULL); - - if (res != S_OK) - { - // We ignore data errors in solid stream. SHA will show what files are bad. - if (res != S_FALSE) - return res; - } - - _solidIndex = resource.SolidIndex; - _unpackedChunkIndex = chunkIndex; - - if (cur < offsetInChunk) - return E_FAIL; - - cur -= offsetInChunk; - - if (cur > rem) - cur = (size_t)rem; - - RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)); - - if (progress) - { - RINOK(progress->SetRatioInfo(&packProcessed, &outProcessed)); - packProcessed += packSize; - outProcessed += cur; - } - - rem -= cur; - offsetInChunk = 0; - chunkIndex++; - } - } - - - // ---------- NON Solid ---------- - - const UInt64 unpackSize = resource.UnpackSize; - if (unpackSize == 0) - { - if (resource.PackSize == 0) - return S_OK; - return S_FALSE; - } - - if (unpackSize > ((UInt64)1 << 63)) - return E_NOTIMPL; - - const unsigned chunkSizeBits = header.ChunkSizeBits; - const unsigned entrySizeShifts = (resource.UnpackSize < ((UInt64)1 << 32) ? 2 : 3); - - UInt64 baseOffset = resource.Offset; - UInt64 packDataSize; - size_t numChunks; - { - UInt64 numChunks64 = (unpackSize + (((UInt32)1 << chunkSizeBits) - 1)) >> chunkSizeBits; - UInt64 sizesBufSize64 = (numChunks64 - 1) << entrySizeShifts; - if (sizesBufSize64 > resource.PackSize) - return S_FALSE; - packDataSize = resource.PackSize - sizesBufSize64; - size_t sizesBufSize = (size_t)sizesBufSize64; - if (sizesBufSize != sizesBufSize64) - return E_OUTOFMEMORY; - sizesBuf.AllocAtLeast(sizesBufSize); - RINOK(inStream->Seek(baseOffset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)); - baseOffset += sizesBufSize64; - numChunks = (size_t)numChunks64; - } - - _solidIndex = -1; - _unpackedChunkIndex = 0; - - UInt64 outProcessed = 0; - UInt64 offset = 0; - - for (size_t i = 0; i < numChunks; i++) - { - UInt64 nextOffset = packDataSize; - - if (i + 1 < numChunks) - { - const Byte *p = (const Byte *)sizesBuf + (i << entrySizeShifts); - nextOffset = (entrySizeShifts == 2) ? Get32(p): Get64(p); - } - - if (nextOffset < offset) - return S_FALSE; - - UInt64 inSize64 = nextOffset - offset; - size_t inSize = (size_t)inSize64; - if (inSize != inSize64) - return S_FALSE; - - RINOK(inStream->Seek(baseOffset + offset, STREAM_SEEK_SET, NULL)); - - if (progress) - { - RINOK(progress->SetRatioInfo(&offset, &outProcessed)); - } - - size_t outSize = (size_t)1 << chunkSizeBits; - const UInt64 rem = unpackSize - outProcessed; - if (outSize > rem) - outSize = (size_t)rem; - - RINOK(UnpackChunk(inStream, header.GetMethod(), chunkSizeBits, inSize, outSize, outStream)); - - outProcessed += outSize; - offset = nextOffset; - } - - return S_OK; -} - - -HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, const CHeader &header, const CDatabase *db, - ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest) -{ - COutStreamWithSha1 *shaStreamSpec = NULL; - CMyComPtr shaStream; - - // outStream can be NULL, so we use COutStreamWithSha1 even if sha1 is not required - // if (digest) - { - shaStreamSpec = new COutStreamWithSha1(); - shaStream = shaStreamSpec; - shaStreamSpec->SetStream(outStream); - shaStreamSpec->Init(digest != NULL); - outStream = shaStream; - } - - HRESULT res = Unpack2(inStream, resource, header, db, outStream, progress); - - if (digest) - shaStreamSpec->Final(digest); - - return res; -} - - -HRESULT CUnpacker::UnpackData(IInStream *inStream, - const CResource &resource, const CHeader &header, - const CDatabase *db, - CByteBuffer &buf, Byte *digest) -{ - // if (resource.IsSolid()) return E_NOTIMPL; - - UInt64 unpackSize64 = resource.UnpackSize; - if (db) - unpackSize64 = db->Get_UnpackSize_of_Resource(resource); - - size_t size = (size_t)unpackSize64; - if (size != unpackSize64) - return E_OUTOFMEMORY; - - buf.Alloc(size); - - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream(); - CMyComPtr outStream = outStreamSpec; - outStreamSpec->Init((Byte *)buf, size); - - return Unpack(inStream, resource, header, db, outStream, NULL, digest); -} - - -void CResource::Parse(const Byte *p) -{ - Flags = p[7]; - PackSize = Get64(p) & (((UInt64)1 << 56) - 1); - Offset = Get64(p + 8); - UnpackSize = Get64(p + 16); - KeepSolid = false; - SolidIndex = -1; -} - -#define GET_RESOURCE(_p_, res) res.ParseAndUpdatePhySize(_p_, phySize) - -static inline void ParseStream(bool oldVersion, const Byte *p, CStreamInfo &s) -{ - s.Resource.Parse(p); - if (oldVersion) - { - s.PartNumber = 1; - s.Id = Get32(p + 24); - p += 28; - } - else - { - s.PartNumber = Get16(p + 24); - p += 26; - } - s.RefCount = Get32(p); - memcpy(s.Hash, p + 4, kHashSize); -} - - -static const char *kLongPath = "[LongPath]"; - -void CDatabase::GetShortName(unsigned index, NWindows::NCOM::CPropVariant &name) const -{ - const CItem &item = Items[index]; - const CImage &image = Images[item.ImageIndex]; - if (item.Parent < 0 && image.NumEmptyRootItems != 0) - { - name.Clear(); - return; - } - const Byte *meta = image.Meta + item.Offset + - (IsOldVersion ? kDirRecordSizeOld : kDirRecordSize); - UInt32 fileNameLen = Get16(meta - 2); - UInt32 shortLen = Get16(meta - 4) / 2; - wchar_t *s = name.AllocBstr(shortLen); - if (fileNameLen != 0) - meta += fileNameLen + 2; - for (UInt32 i = 0; i < shortLen; i++) - s[i] = Get16(meta + i * 2); - s[shortLen] = 0; - // empty shortName has no ZERO at the end ? -} - - -void CDatabase::GetItemName(unsigned index, NWindows::NCOM::CPropVariant &name) const -{ - const CItem &item = Items[index]; - const CImage &image = Images[item.ImageIndex]; - if (item.Parent < 0 && image.NumEmptyRootItems != 0) - { - name = image.RootName; - return; - } - const Byte *meta = image.Meta + item.Offset + - (item.IsAltStream ? - (IsOldVersion ? 0x10 : 0x24) : - (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2)); - UInt32 len = Get16(meta) / 2; - wchar_t *s = name.AllocBstr(len); - meta += 2; - len++; - for (UInt32 i = 0; i < len; i++) - s[i] = Get16(meta + i * 2); -} - - -void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCOM::CPropVariant &path) const -{ - unsigned size = 0; - int index = index1; - int imageIndex = Items[index].ImageIndex; - const CImage &image = Images[imageIndex]; - - unsigned newLevel = 0; - bool needColon = false; - - for (;;) - { - const CItem &item = Items[index]; - index = item.Parent; - if (index >= 0 || image.NumEmptyRootItems == 0) - { - const Byte *meta = image.Meta + item.Offset; - meta += item.IsAltStream ? - (IsOldVersion ? 0x10 : 0x24) : - (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2); - needColon = item.IsAltStream; - size += Get16(meta) / 2; - size += newLevel; - newLevel = 1; - if (size >= ((UInt32)1 << 15)) - { - path = kLongPath; - return; - } - } - if (index < 0) - break; - } - - if (showImageNumber) - { - size += image.RootName.Len(); - size += newLevel; - } - else if (needColon) - size++; - - wchar_t *s = path.AllocBstr(size); - s[size] = 0; - - if (showImageNumber) - { - MyStringCopy(s, (const wchar_t *)image.RootName); - if (newLevel) - s[image.RootName.Len()] = (wchar_t)(needColon ? L':' : WCHAR_PATH_SEPARATOR); - } - else if (needColon) - s[0] = L':'; - - index = index1; - wchar_t separator = 0; - - for (;;) - { - const CItem &item = Items[index]; - index = item.Parent; - if (index >= 0 || image.NumEmptyRootItems == 0) - { - if (separator != 0) - s[--size] = separator; - const Byte *meta = image.Meta + item.Offset; - meta += (item.IsAltStream) ? - (IsOldVersion ? 0x10: 0x24) : - (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2); - unsigned len = Get16(meta) / 2; - size -= len; - wchar_t *dest = s + size; - meta += 2; - for (unsigned i = 0; i < len; i++) - dest[i] = Get16(meta + i * 2); - } - if (index < 0) - return; - separator = item.IsAltStream ? L':' : WCHAR_PATH_SEPARATOR; - } -} - - -// if (ver <= 1.10), root folder contains real items. -// if (ver >= 1.12), root folder contains only one folder with empty name. - -HRESULT CDatabase::ParseDirItem(size_t pos, int parent) -{ - const unsigned align = GetDirAlignMask(); - if ((pos & align) != 0) - return S_FALSE; - - for (unsigned numItems = 0;; numItems++) - { - if (OpenCallback && (Items.Size() & 0xFFFF) == 0) - { - UInt64 numFiles = Items.Size(); - RINOK(OpenCallback->SetCompleted(&numFiles, NULL)); - } - - const size_t rem = DirSize - pos; - if (pos < DirStartOffset || pos > DirSize || rem < 8) - return S_FALSE; - - const Byte *p = DirData + pos; - - UInt64 len = Get64(p); - if (len == 0) - { - DirProcessed += 8; - return S_OK; - } - - if ((len & align) != 0 || rem < len) - return S_FALSE; - - DirProcessed += (size_t)len; - if (DirProcessed > DirSize) - return S_FALSE; - - const unsigned dirRecordSize = IsOldVersion ? kDirRecordSizeOld : kDirRecordSize; - if (len < dirRecordSize) - return S_FALSE; - - CItem item; - UInt32 attrib = Get32(p + 8); - item.IsDir = ((attrib & 0x10) != 0); - UInt64 subdirOffset = Get64(p + 0x10); - - const UInt32 numAltStreams = Get16(p + dirRecordSize - 6); - const UInt32 shortNameLen = Get16(p + dirRecordSize - 4); - const UInt32 fileNameLen = Get16(p + dirRecordSize - 2); - if ((shortNameLen & 1) != 0 || (fileNameLen & 1) != 0) - return S_FALSE; - const UInt32 shortNameLen2 = (shortNameLen == 0 ? shortNameLen : shortNameLen + 2); - const UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2); - if (((dirRecordSize + fileNameLen2 + shortNameLen2 + align) & ~align) > len) - return S_FALSE; - - p += dirRecordSize; - - { - if (*(const UInt16 *)(p + fileNameLen) != 0) - return S_FALSE; - for (UInt32 j = 0; j < fileNameLen; j += 2) - if (*(const UInt16 *)(p + j) == 0) - return S_FALSE; - } - - // PRF(printf("\n%S", p)); - - if (shortNameLen != 0) - { - // empty shortName has no ZERO at the end ? - const Byte *p2 = p + fileNameLen2; - if (*(const UInt16 *)(p2 + shortNameLen) != 0) - return S_FALSE; - for (UInt32 j = 0; j < shortNameLen; j += 2) - if (*(const UInt16 *)(p2 + j) == 0) - return S_FALSE; - } - - item.Offset = pos; - item.Parent = parent; - item.ImageIndex = Images.Size() - 1; - - const unsigned prevIndex = Items.Add(item); - - pos += (size_t)len; - - for (UInt32 i = 0; i < numAltStreams; i++) - { - const size_t rem2 = DirSize - pos; - if (pos < DirStartOffset || pos > DirSize || rem2 < 8) - return S_FALSE; - const Byte *p2 = DirData + pos; - const UInt64 len2 = Get64(p2); - if ((len2 & align) != 0 || rem2 < len2 || len2 < (IsOldVersion ? 0x18 : 0x28)) - return S_FALSE; - - DirProcessed += (size_t)len2; - if (DirProcessed > DirSize) - return S_FALSE; - - unsigned extraOffset = 0; - - if (IsOldVersion) - extraOffset = 0x10; - else - { - if (Get64(p2 + 8) != 0) - return S_FALSE; - extraOffset = 0x24; - } - - const UInt32 fileNameLen111 = Get16(p2 + extraOffset); - if ((fileNameLen111 & 1) != 0) - return S_FALSE; - /* Probably different versions of ImageX can use different number of - additional ZEROs. So we don't use exact check. */ - const UInt32 fileNameLen222 = (fileNameLen111 == 0 ? fileNameLen111 : fileNameLen111 + 2); - if (((extraOffset + 2 + fileNameLen222 + align) & ~align) > len2) - return S_FALSE; - - { - const Byte *p3 = p2 + extraOffset + 2; - if (*(const UInt16 *)(p3 + fileNameLen111) != 0) - return S_FALSE; - for (UInt32 j = 0; j < fileNameLen111; j += 2) - if (*(const UInt16 *)(p3 + j) == 0) - return S_FALSE; - - // PRF(printf("\n %S", p3)); - } - - - /* wim uses alt sreams list, if there is at least one alt stream. - And alt stream without name is main stream. */ - - // Why wimlib writes two alt streams for REPARSE_POINT, with empty second alt stream? - - Byte *prevMeta = DirData + item.Offset; - - if (fileNameLen111 == 0 && - ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) || !item.IsDir) - && (IsOldVersion || IsEmptySha(prevMeta + 0x40))) - { - if (IsOldVersion) - memcpy(prevMeta + 0x10, p2 + 8, 4); // It's 32-bit Id - else if (!IsEmptySha(p2 + 0x10)) - { - // if (IsEmptySha(prevMeta + 0x40)) - memcpy(prevMeta + 0x40, p2 + 0x10, kHashSize); - // else HeadersError = true; - } - } - else - { - ThereAreAltStreams = true; - CItem item2; - item2.Offset = pos; - item2.IsAltStream = true; - item2.Parent = prevIndex; - item2.ImageIndex = Images.Size() - 1; - Items.Add(item2); - } - - pos += (size_t)len2; - } - - if (parent < 0 && numItems == 0 && shortNameLen == 0 && fileNameLen == 0 && item.IsDir) - { - const Byte *p2 = DirData + pos; - if (DirSize - pos >= 8 && Get64(p2) == 0) - { - CImage &image = Images.Back(); - image.NumEmptyRootItems = 1; - - if (subdirOffset != 0 - && DirSize - pos >= 16 - && Get64(p2 + 8) != 0 - && pos + 8 < subdirOffset) - { - // Longhorn.4093 contains hidden files after empty root folder and before items of next folder. Why? - // That code shows them. If we want to ignore them, we need to update DirProcessed. - // DirProcessed += (size_t)(subdirOffset - (pos + 8)); - // printf("\ndirOffset = %5d hiddenOffset = %5d\n", (int)subdirOffset, (int)pos + 8); - subdirOffset = pos + 8; - // return S_FALSE; - } - } - } - - if (item.IsDir && subdirOffset != 0) - { - RINOK(ParseDirItem((size_t)subdirOffset, prevIndex)); - } - } -} - - -HRESULT CDatabase::ParseImageDirs(CByteBuffer &buf, int parent) -{ - DirData = buf; - DirSize = buf.Size(); - if (DirSize < 8) - return S_FALSE; - const Byte *p = DirData; - size_t pos = 0; - CImage &image = Images.Back(); - - if (IsOldVersion) - { - UInt32 numEntries = Get32(p + 4); - - if (numEntries > (1 << 28) || - numEntries > (DirSize >> 3)) - return S_FALSE; - - UInt32 sum = 8; - if (numEntries != 0) - sum = numEntries * 8; - - image.SecurOffsets.ClearAndReserve(numEntries + 1); - image.SecurOffsets.AddInReserved(sum); - - for (UInt32 i = 0; i < numEntries; i++) - { - const Byte *pp = p + (size_t)i * 8; - UInt32 len = Get32(pp); - if (i != 0 && Get32(pp + 4) != 0) - return S_FALSE; - if (len > DirSize - sum) - return S_FALSE; - sum += len; - if (sum < len) - return S_FALSE; - image.SecurOffsets.AddInReserved(sum); - } - - pos = sum; - - const size_t align = GetDirAlignMask(); - pos = (pos + align) & ~(size_t)align; - } - else - { - UInt32 totalLen = Get32(p); - if (totalLen == 0) - pos = 8; - else - { - if (totalLen < 8) - return S_FALSE; - UInt32 numEntries = Get32(p + 4); - pos = 8; - if (totalLen > DirSize || numEntries > ((totalLen - 8) >> 3)) - return S_FALSE; - UInt32 sum = (UInt32)pos + numEntries * 8; - image.SecurOffsets.ClearAndReserve(numEntries + 1); - image.SecurOffsets.AddInReserved(sum); - - for (UInt32 i = 0; i < numEntries; i++, pos += 8) - { - UInt64 len = Get64(p + pos); - if (len > totalLen - sum) - return S_FALSE; - sum += (UInt32)len; - image.SecurOffsets.AddInReserved(sum); - } - - pos = sum; - pos = (pos + 7) & ~(size_t)7; - if (pos != (((size_t)totalLen + 7) & ~(size_t)7)) - return S_FALSE; - } - } - - if (pos > DirSize) - return S_FALSE; - - DirStartOffset = DirProcessed = pos; - image.StartItem = Items.Size(); - - RINOK(ParseDirItem(pos, parent)); - - image.NumItems = Items.Size() - image.StartItem; - if (DirProcessed == DirSize) - return S_OK; - - /* Original program writes additional 8 bytes (END_OF_ROOT_FOLDER), - but the reference to that folder is empty */ - - // we can't use DirProcessed - DirStartOffset == 112 check if there is alt stream in root - if (DirProcessed == DirSize - 8 && Get64(p + DirSize - 8) != 0) - return S_OK; - - return S_FALSE; -} - - -HRESULT CHeader::Parse(const Byte *p, UInt64 &phySize) -{ - UInt32 headerSize = Get32(p + 8); - phySize = headerSize; - Version = Get32(p + 0x0C); - Flags = Get32(p + 0x10); - if (!IsSupported()) - return S_FALSE; - - { - ChunkSize = Get32(p + 0x14); - ChunkSizeBits = kChunkSizeBits; - if (ChunkSize != 0) - { - int log = GetLog(ChunkSize); - if (log < 12) - return S_FALSE; - ChunkSizeBits = log; - } - } - - _IsOldVersion = false; - _IsNewVersion = false; - - if (IsSolidVersion()) - _IsNewVersion = true; - else - { - if (Version < 0x010900) - return S_FALSE; - _IsOldVersion = (Version <= 0x010A00); - // We don't know details about 1.11 version. So we use headerSize to guess exact features. - if (Version == 0x010B00 && headerSize == 0x60) - _IsOldVersion = true; - _IsNewVersion = (Version >= 0x010D00); - } - - unsigned offset; - - if (IsOldVersion()) - { - if (headerSize != 0x60) - return S_FALSE; - memset(Guid, 0, 16); - offset = 0x18; - PartNumber = 1; - NumParts = 1; - } - else - { - if (headerSize < 0x74) - return S_FALSE; - memcpy(Guid, p + 0x18, 16); - PartNumber = Get16(p + 0x28); - NumParts = Get16(p + 0x2A); - if (PartNumber == 0 || PartNumber > NumParts) - return S_FALSE; - offset = 0x2C; - if (IsNewVersion()) - { - // if (headerSize < 0xD0) - if (headerSize != 0xD0) - return S_FALSE; - NumImages = Get32(p + offset); - offset += 4; - } - } - - GET_RESOURCE(p + offset , OffsetResource); - GET_RESOURCE(p + offset + 0x18, XmlResource); - GET_RESOURCE(p + offset + 0x30, MetadataResource); - BootIndex = 0; - - if (IsNewVersion()) - { - BootIndex = Get32(p + offset + 0x48); - GET_RESOURCE(p + offset + 0x4C, IntegrityResource); - } - - return S_OK; -} - - -const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }; - -HRESULT ReadHeader(IInStream *inStream, CHeader &h, UInt64 &phySize) -{ - Byte p[kHeaderSizeMax]; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); - if (memcmp(p, kSignature, kSignatureSize) != 0) - return S_FALSE; - return h.Parse(p, phySize); -} - - -static HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) -{ - CByteBuffer offsetBuf; - - CUnpacker unpacker; - RINOK(unpacker.UnpackData(inStream, h.OffsetResource, h, NULL, offsetBuf, NULL)); - - const size_t streamInfoSize = h.IsOldVersion() ? kStreamInfoSize + 2 : kStreamInfoSize; - { - const unsigned numItems = (unsigned)(offsetBuf.Size() / streamInfoSize); - if ((size_t)numItems * streamInfoSize != offsetBuf.Size()) - return S_FALSE; - const unsigned numItems2 = db.DataStreams.Size() + numItems; - if (numItems2 < numItems) - return S_FALSE; - db.DataStreams.Reserve(numItems2); - } - - bool keepSolid = false; - - for (size_t i = 0; i < offsetBuf.Size(); i += streamInfoSize) - { - CStreamInfo s; - ParseStream(h.IsOldVersion(), (const Byte *)offsetBuf + i, s); - - PRF(printf("\n")); - PRF(printf(s.Resource.IsMetadata() ? "### META" : " DATA")); - PRF(printf(" %2X", s.Resource.Flags)); - PRF(printf(" %9I64X", s.Resource.Offset)); - PRF(printf(" %9I64X", s.Resource.PackSize)); - PRF(printf(" %9I64X", s.Resource.UnpackSize)); - PRF(printf(" %d", s.RefCount)); - - if (s.PartNumber != h.PartNumber) - continue; - - if (s.Resource.IsSolid()) - { - s.Resource.KeepSolid = keepSolid; - keepSolid = true; - } - else - { - s.Resource.KeepSolid = false; - keepSolid = false; - } - - if (!s.Resource.IsMetadata()) - db.DataStreams.AddInReserved(s); - else - { - if (s.Resource.IsSolid()) - return E_NOTIMPL; - if (s.RefCount == 0) - { - // some wims have such (deleted?) metadata stream. - // examples: boot.wim in VistaBeta2, WinPE.wim from WAIK. - // db.DataStreams.Add(s); - // we can show these delete images, if we comment "continue" command; - continue; - } - - if (s.RefCount > 1) - { - return S_FALSE; - // s.RefCount--; - // db.DataStreams.Add(s); - } - - db.MetaStreams.Add(s); - } - } - - PRF(printf("\n")); - - return S_OK; -} - - -HRESULT CDatabase::OpenXml(IInStream *inStream, const CHeader &h, CByteBuffer &xml) -{ - CUnpacker unpacker; - return unpacker.UnpackData(inStream, h.XmlResource, h, this, xml, NULL); -} - -static void SetRootNames(CImage &image, unsigned value) -{ - wchar_t temp[16]; - ConvertUInt32ToString(value, temp); - image.RootName = temp; - image.RootNameBuf.Alloc(image.RootName.Len() * 2 + 2); - Byte *p = image.RootNameBuf; - unsigned len = image.RootName.Len() + 1; - for (unsigned k = 0; k < len; k++) - { - p[k * 2] = (Byte)temp[k]; - p[k * 2 + 1] = 0; - } -} - - -HRESULT CDatabase::Open(IInStream *inStream, const CHeader &h, unsigned numItemsReserve, IArchiveOpenCallback *openCallback) -{ - OpenCallback = openCallback; - IsOldVersion = h.IsOldVersion(); - IsOldVersion9 = (h.Version == 0x10900); - - RINOK(ReadStreams(inStream, h, *this)); - - bool needBootMetadata = !h.MetadataResource.IsEmpty(); - unsigned numNonDeletedImages = 0; - - CUnpacker unpacker; - - FOR_VECTOR (i, MetaStreams) - { - const CStreamInfo &si = MetaStreams[i]; - - if (h.PartNumber != 1 || si.PartNumber != h.PartNumber) - continue; - - const int userImage = Images.Size() + GetStartImageIndex(); - CImage &image = Images.AddNew(); - SetRootNames(image, userImage); - - CByteBuffer &metadata = image.Meta; - Byte hash[kHashSize]; - - RINOK(unpacker.UnpackData(inStream, si.Resource, h, this, metadata, hash)); - - if (memcmp(hash, si.Hash, kHashSize) != 0 && - !(h.IsOldVersion() && IsEmptySha(si.Hash))) - return S_FALSE; - - image.NumEmptyRootItems = 0; - - if (Items.IsEmpty()) - Items.ClearAndReserve(numItemsReserve); - - RINOK(ParseImageDirs(metadata, -1)); - - if (needBootMetadata) - { - bool sameRes = (h.MetadataResource.Offset == si.Resource.Offset); - if (sameRes) - needBootMetadata = false; - if (h.IsNewVersion()) - { - if (si.RefCount == 1) - { - numNonDeletedImages++; - bool isBootIndex = (h.BootIndex == numNonDeletedImages); - if (sameRes && !isBootIndex) - return S_FALSE; - if (isBootIndex && !sameRes) - return S_FALSE; - } - } - } - } - - if (needBootMetadata) - return S_FALSE; - return S_OK; -} - - -bool CDatabase::ItemHasStream(const CItem &item) const -{ - if (item.ImageIndex < 0) - return true; - const Byte *meta = Images[item.ImageIndex].Meta + item.Offset; - if (IsOldVersion) - { - // old wim use same field for file_id and dir_offset; - if (item.IsDir) - return false; - meta += (item.IsAltStream ? 0x8 : 0x10); - UInt32 id = GetUi32(meta); - return id != 0; - } - meta += (item.IsAltStream ? 0x10 : 0x40); - return !IsEmptySha(meta); -} - - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */) -{ - RINOZ(MyCompare(p1->PartNumber, p2->PartNumber)); - RINOZ(MyCompare(p1->Resource.Offset, p2->Resource.Offset)); - return MyCompare(p1->Resource.PackSize, p2->Resource.PackSize); -} - -static int CompareIDs(const unsigned *p1, const unsigned *p2, void *param) -{ - const CStreamInfo *streams = (const CStreamInfo *)param; - return MyCompare(streams[*p1].Id, streams[*p2].Id); -} - -static int CompareHashRefs(const unsigned *p1, const unsigned *p2, void *param) -{ - const CStreamInfo *streams = (const CStreamInfo *)param; - return memcmp(streams[*p1].Hash, streams[*p2].Hash, kHashSize); -} - -static int FindId(const CStreamInfo *streams, const CUIntVector &sorted, UInt32 id) -{ - unsigned left = 0, right = sorted.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - unsigned streamIndex = sorted[mid]; - UInt32 id2 = streams[streamIndex].Id; - if (id == id2) - return streamIndex; - if (id < id2) - right = mid; - else - left = mid + 1; - } - return -1; -} - -static int FindHash(const CStreamInfo *streams, const CUIntVector &sorted, const Byte *hash) -{ - unsigned left = 0, right = sorted.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - unsigned streamIndex = sorted[mid]; - const Byte *hash2 = streams[streamIndex].Hash; - unsigned i; - for (i = 0; i < kHashSize; i++) - if (hash[i] != hash2[i]) - break; - if (i == kHashSize) - return streamIndex; - if (hash[i] < hash2[i]) - right = mid; - else - left = mid + 1; - } - return -1; -} - -static int CompareItems(const unsigned *a1, const unsigned *a2, void *param) -{ - const CRecordVector &items = ((CDatabase *)param)->Items; - const CItem &i1 = items[*a1]; - const CItem &i2 = items[*a2]; - - if (i1.IsDir != i2.IsDir) - return i1.IsDir ? -1 : 1; - if (i1.IsAltStream != i2.IsAltStream) - return i1.IsAltStream ? 1 : -1; - RINOZ(MyCompare(i1.StreamIndex, i2.StreamIndex)); - RINOZ(MyCompare(i1.ImageIndex, i2.ImageIndex)); - return MyCompare(i1.Offset, i2.Offset); -} - - -HRESULT CDatabase::FillAndCheck(const CObjectVector &volumes) -{ - CUIntVector sortedByHash; - sortedByHash.Reserve(DataStreams.Size()); - { - CByteBuffer sizesBuf; - - for (unsigned iii = 0; iii < DataStreams.Size();) - { - { - const CResource &r = DataStreams[iii].Resource; - if (!r.IsSolid()) - { - sortedByHash.AddInReserved(iii++); - continue; - } - } - - UInt64 solidRunOffset = 0; - unsigned k; - unsigned numSolidsStart = Solids.Size(); - - for (k = iii; k < DataStreams.Size(); k++) - { - CStreamInfo &si = DataStreams[k]; - CResource &r = si.Resource; - - if (!r.IsSolid()) - break; - if (!r.KeepSolid && k != iii) - break; - - if (r.Flags != NResourceFlags::kSolid) - return S_FALSE; - - if (!r.IsSolidBig()) - continue; - - if (!si.IsEmptyHash()) - return S_FALSE; - if (si.RefCount != 1) - return S_FALSE; - - r.SolidIndex = Solids.Size(); - - CSolid &ss = Solids.AddNew(); - ss.StreamIndex = k; - ss.SolidOffset = solidRunOffset; - { - const size_t kSolidHeaderSize = 8 + 4 + 4; - Byte header[kSolidHeaderSize]; - - if (si.PartNumber >= volumes.Size()) - return S_FALSE; - - const CVolume &vol = volumes[si.PartNumber]; - IInStream *inStream = vol.Stream; - RINOK(inStream->Seek(r.Offset, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream_FALSE(inStream, (Byte *)header, kSolidHeaderSize)); - - ss.UnpackSize = GetUi64(header); - - if (ss.UnpackSize > ((UInt64)1 << 63)) - return S_FALSE; - - solidRunOffset += ss.UnpackSize; - if (solidRunOffset < ss.UnpackSize) - return S_FALSE; - - const UInt32 solidChunkSize = GetUi32(header + 8); - int log = GetLog(solidChunkSize); - if (log < 8 || log > 31) - return S_FALSE; - ss.ChunkSizeBits = log; - ss.Method = GetUi32(header + 12); - - UInt64 numChunks64 = (ss.UnpackSize + (((UInt32)1 << ss.ChunkSizeBits) - 1)) >> ss.ChunkSizeBits; - UInt64 sizesBufSize64 = 4 * numChunks64; - ss.HeadersSize = kSolidHeaderSize + sizesBufSize64; - size_t sizesBufSize = (size_t)sizesBufSize64; - if (sizesBufSize != sizesBufSize64) - return E_OUTOFMEMORY; - sizesBuf.AllocAtLeast(sizesBufSize); - - RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)); - - size_t numChunks = (size_t)numChunks64; - ss.Chunks.Alloc(numChunks + 1); - - UInt64 offset = 0; - - size_t c; - for (c = 0; c < numChunks; c++) - { - ss.Chunks[c] = offset; - UInt32 packSize = GetUi32((const Byte *)sizesBuf + c * 4); - offset += packSize; - if (offset < packSize) - return S_FALSE; - } - ss.Chunks[c] = offset; - - if (ss.Chunks[0] != 0) - return S_FALSE; - if (ss.HeadersSize + offset != r.PackSize) - return S_FALSE; - } - } - - unsigned solidLim = k; - - for (k = iii; k < solidLim; k++) - { - CStreamInfo &si = DataStreams[k]; - CResource &r = si.Resource; - - if (!r.IsSolidSmall()) - continue; - - if (si.IsEmptyHash()) - return S_FALSE; - - unsigned solidIndex; - { - UInt64 offset = r.Offset; - for (solidIndex = numSolidsStart;; solidIndex++) - { - if (solidIndex == Solids.Size()) - return S_FALSE; - UInt64 unpackSize = Solids[solidIndex].UnpackSize; - if (offset < unpackSize) - break; - offset -= unpackSize; - } - } - CSolid &ss = Solids[solidIndex]; - if (r.Offset < ss.SolidOffset) - return S_FALSE; - UInt64 relat = r.Offset - ss.SolidOffset; - if (relat > ss.UnpackSize) - return S_FALSE; - if (r.PackSize > ss.UnpackSize - relat) - return S_FALSE; - r.SolidIndex = solidIndex; - if (ss.FirstSmallStream < 0) - ss.FirstSmallStream = k; - - sortedByHash.AddInReserved(k); - // ss.NumRefs++; - } - - iii = solidLim; - } - } - - if (Solids.IsEmpty()) - { - /* We want to check that streams layout is OK. - So we need resources sorted by offset. - Another code can work with non-sorted streams. - NOTE: all WIM programs probably create wim archives with - sorted data streams. So it doesn't call Sort() here. */ - - { - unsigned i; - for (i = 1; i < DataStreams.Size(); i++) - { - const CStreamInfo &s0 = DataStreams[i - 1]; - const CStreamInfo &s1 = DataStreams[i]; - if (s0.PartNumber < s1.PartNumber) continue; - if (s0.PartNumber > s1.PartNumber) break; - if (s0.Resource.Offset < s1.Resource.Offset) continue; - if (s0.Resource.Offset > s1.Resource.Offset) break; - if (s0.Resource.PackSize > s1.Resource.PackSize) break; - } - - if (i < DataStreams.Size()) - { - // return E_FAIL; - DataStreams.Sort(CompareStreamsByPos, NULL); - } - } - - for (unsigned i = 1; i < DataStreams.Size(); i++) - { - const CStreamInfo &s0 = DataStreams[i - 1]; - const CStreamInfo &s1 = DataStreams[i]; - if (s0.PartNumber == s1.PartNumber) - if (s0.Resource.GetEndLimit() > s1.Resource.Offset) - return S_FALSE; - } - } - - { - { - const CStreamInfo *streams = &DataStreams.Front(); - - if (IsOldVersion) - { - sortedByHash.Sort(CompareIDs, (void *)streams); - - for (unsigned i = 1; i < sortedByHash.Size(); i++) - if (streams[sortedByHash[i - 1]].Id >= - streams[sortedByHash[i]].Id) - return S_FALSE; - } - else - { - sortedByHash.Sort(CompareHashRefs, (void *)streams); - - if (!sortedByHash.IsEmpty()) - { - if (IsEmptySha(streams[sortedByHash[0]].Hash)) - HeadersError = true; - - for (unsigned i = 1; i < sortedByHash.Size(); i++) - if (memcmp( - streams[sortedByHash[i - 1]].Hash, - streams[sortedByHash[i]].Hash, - kHashSize) >= 0) - return S_FALSE; - } - } - } - - FOR_VECTOR (i, Items) - { - CItem &item = Items[i]; - item.StreamIndex = -1; - const Byte *hash = Images[item.ImageIndex].Meta + item.Offset; - if (IsOldVersion) - { - if (!item.IsDir) - { - hash += (item.IsAltStream ? 0x8 : 0x10); - UInt32 id = GetUi32(hash); - if (id != 0) - item.StreamIndex = FindId(&DataStreams.Front(), sortedByHash, id); - } - } - /* - else if (item.IsDir) - { - // reparse points can have dirs some dir - } - */ - else - { - hash += (item.IsAltStream ? 0x10 : 0x40); - if (!IsEmptySha(hash)) - { - item.StreamIndex = FindHash(&DataStreams.Front(), sortedByHash, hash); - } - } - } - } - { - CUIntVector refCounts; - refCounts.ClearAndSetSize(DataStreams.Size()); - unsigned i; - - for (i = 0; i < DataStreams.Size(); i++) - { - UInt32 startVal = 0; - // const CStreamInfo &s = DataStreams[i]; - /* - if (s.Resource.IsMetadata() && s.PartNumber == 1) - startVal = 1; - */ - refCounts[i] = startVal; - } - - for (i = 0; i < Items.Size(); i++) - { - int streamIndex = Items[i].StreamIndex; - if (streamIndex >= 0) - refCounts[streamIndex]++; - } - - for (i = 0; i < DataStreams.Size(); i++) - { - const CStreamInfo &s = DataStreams[i]; - if (s.RefCount != refCounts[i] - && !s.Resource.IsSolidBig()) - { - /* - printf("\ni=%5d si.Ref=%2d realRefs=%2d size=%8d offset=%8x id=%4d ", - i, s.RefCount, refCounts[i], (unsigned)s.Resource.UnpackSize, (unsigned)s.Resource.Offset, s.Id); - */ - RefCountError = true; - } - - if (refCounts[i] == 0) - { - const CResource &r = DataStreams[i].Resource; - if (!r.IsSolidBig() || Solids[r.SolidIndex].FirstSmallStream < 0) - { - CItem item; - item.Offset = 0; - item.StreamIndex = i; - item.ImageIndex = -1; - Items.Add(item); - ThereAreDeletedStreams = true; - } - } - } - } - - return S_OK; -} - - -HRESULT CDatabase::GenerateSortedItems(int imageIndex, bool showImageNumber) -{ - SortedItems.Clear(); - VirtualRoots.Clear(); - IndexOfUserImage = imageIndex; - NumExcludededItems = 0; - ExludedItem = -1; - - if (Images.Size() != 1 && imageIndex < 0) - showImageNumber = true; - - unsigned startItem = 0; - unsigned endItem = 0; - - if (imageIndex < 0) - { - endItem = Items.Size(); - if (Images.Size() == 1) - { - IndexOfUserImage = 0; - const CImage &image = Images[0]; - if (!showImageNumber) - NumExcludededItems = image.NumEmptyRootItems; - } - } - else if ((unsigned)imageIndex < Images.Size()) - { - const CImage &image = Images[imageIndex]; - startItem = image.StartItem; - endItem = startItem + image.NumItems; - if (!showImageNumber) - NumExcludededItems = image.NumEmptyRootItems; - } - - if (NumExcludededItems != 0) - { - ExludedItem = startItem; - startItem += NumExcludededItems; - } - - unsigned num = endItem - startItem; - SortedItems.ClearAndSetSize(num); - unsigned i; - for (i = 0; i < num; i++) - SortedItems[i] = startItem + i; - - SortedItems.Sort(CompareItems, this); - for (i = 0; i < SortedItems.Size(); i++) - Items[SortedItems[i]].IndexInSorted = i; - - if (showImageNumber) - for (i = 0; i < Images.Size(); i++) - { - CImage &image = Images[i]; - if (image.NumEmptyRootItems != 0) - continue; - image.VirtualRootIndex = VirtualRoots.Size(); - VirtualRoots.Add(i); - } - - return S_OK; -} - - -static void IntVector_SetMinusOne_IfNeed(CIntVector &v, unsigned size) -{ - if (v.Size() == size) - return; - v.ClearAndSetSize(size); - int *vals = &v[0]; - for (unsigned i = 0; i < size; i++) - vals[i] = -1; -} - - -HRESULT CDatabase::ExtractReparseStreams(const CObjectVector &volumes, IArchiveOpenCallback *openCallback) -{ - ItemToReparse.Clear(); - ReparseItems.Clear(); - - // we don't know about Reparse field for OLD WIM format - if (IsOldVersion) - return S_OK; - - CIntVector streamToReparse; - CUnpacker unpacker; - UInt64 totalPackedPrev = 0; - - FOR_VECTOR(indexInSorted, SortedItems) - { - // we use sorted items for faster access - unsigned itemIndex = SortedItems[indexInSorted]; - const CItem &item = Items[itemIndex]; - - if (!item.HasMetadata() || item.IsAltStream) - continue; - - if (item.ImageIndex < 0) - continue; - - const Byte *metadata = Images[item.ImageIndex].Meta + item.Offset; - - const UInt32 attrib = Get32(metadata + 8); - if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0) - continue; - - if (item.StreamIndex < 0) - continue; // it's ERROR - - const CStreamInfo &si = DataStreams[item.StreamIndex]; - if (si.Resource.UnpackSize >= (1 << 16)) - continue; // reparse data can not be larger than 64 KB - - IntVector_SetMinusOne_IfNeed(streamToReparse, DataStreams.Size()); - IntVector_SetMinusOne_IfNeed(ItemToReparse, Items.Size()); - - const unsigned offset = 0x58; // we don't know about Reparse field for OLD WIM format - UInt32 tag = Get32(metadata + offset); - int reparseIndex = streamToReparse[item.StreamIndex]; - CByteBuffer buf; - - if (openCallback) - { - if ((unpacker.TotalPacked - totalPackedPrev) >= ((UInt32)1 << 16)) - { - UInt64 numFiles = Items.Size(); - RINOK(openCallback->SetCompleted(&numFiles, &unpacker.TotalPacked)); - totalPackedPrev = unpacker.TotalPacked; - } - } - - if (reparseIndex >= 0) - { - const CByteBuffer &reparse = ReparseItems[reparseIndex]; - if (tag == Get32(reparse)) - { - ItemToReparse[itemIndex] = reparseIndex; - continue; - } - buf = reparse; - // we support that strange and unusual situation with different tags and same reparse data. - } - else - { - /* - if (si.PartNumber >= volumes.Size()) - continue; - */ - const CVolume &vol = volumes[si.PartNumber]; - /* - if (!vol.Stream) - continue; - */ - - Byte digest[kHashSize]; - HRESULT res = unpacker.UnpackData(vol.Stream, si.Resource, vol.Header, this, buf, digest); - - if (res == S_FALSE) - continue; - - RINOK(res); - - if (memcmp(digest, si.Hash, kHashSize) != 0 - // && !(h.IsOldVersion() && IsEmptySha(si.Hash)) - ) - { - // setErrorStatus; - continue; - } - } - - CByteBuffer &reparse = ReparseItems.AddNew(); - reparse.Alloc(8 + buf.Size()); - Byte *dest = (Byte *)reparse; - SetUi32(dest, tag); - SetUi32(dest + 4, (UInt32)buf.Size()); - if (buf.Size() != 0) - memcpy(dest + 8, buf, buf.Size()); - ItemToReparse[itemIndex] = ReparseItems.Size() - 1; - } - - return S_OK; -} - - - -static bool ParseNumber64(const AString &s, UInt64 &res) -{ - const char *end; - if (s.IsPrefixedBy("0x")) - { - if (s.Len() == 2) - return false; - res = ConvertHexStringToUInt64(s.Ptr(2), &end); - } - else - { - if (s.IsEmpty()) - return false; - res = ConvertStringToUInt64(s, &end); - } - return *end == 0; -} - - -static bool ParseNumber32(const AString &s, UInt32 &res) -{ - UInt64 res64; - if (!ParseNumber64(s, res64) || res64 >= ((UInt64)1 << 32)) - return false; - res = (UInt32)res64; - return true; -} - - -static bool ParseTime(const CXmlItem &item, FILETIME &ft, const char *tag) -{ - int index = item.FindSubTag(tag); - if (index >= 0) - { - const CXmlItem &timeItem = item.SubItems[index]; - UInt32 low = 0, high = 0; - if (ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low) && - ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high)) - { - ft.dwLowDateTime = low; - ft.dwHighDateTime = high; - return true; - } - } - return false; -} - - -void CImageInfo::Parse(const CXmlItem &item) -{ - CTimeDefined = ParseTime(item, CTime, "CREATIONTIME"); - MTimeDefined = ParseTime(item, MTime, "LASTMODIFICATIONTIME"); - NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name); - - ParseNumber64(item.GetSubStringForTag("DIRCOUNT"), DirCount); - ParseNumber64(item.GetSubStringForTag("FILECOUNT"), FileCount); - IndexDefined = ParseNumber32(item.GetPropVal("INDEX"), Index); -} - -void CWimXml::ToUnicode(UString &s) -{ - size_t size = Data.Size(); - if (size < 2 || (size & 1) != 0 || size > (1 << 24)) - return; - const Byte *p = Data; - if (Get16(p) != 0xFEFF) - return; - wchar_t *chars = s.GetBuf((unsigned)(size / 2)); - for (size_t i = 2; i < size; i += 2) - { - wchar_t c = Get16(p + i); - if (c == 0) - break; - *chars++ = c; - } - *chars = 0; - s.ReleaseBuf_SetLen((unsigned)(chars - (const wchar_t *)s)); -} - - -bool CWimXml::Parse() -{ - IsEncrypted = false; - AString utf; - { - UString s; - ToUnicode(s); - // if (!ConvertUnicodeToUTF8(s, utf)) return false; - ConvertUnicodeToUTF8(s, utf); - } - - if (!Xml.Parse(utf)) - return false; - if (Xml.Root.Name != "WIM") - return false; - - FOR_VECTOR (i, Xml.Root.SubItems) - { - const CXmlItem &item = Xml.Root.SubItems[i]; - - if (item.IsTagged("IMAGE")) - { - CImageInfo imageInfo; - imageInfo.Parse(item); - if (!imageInfo.IndexDefined) - return false; - - if (imageInfo.Index != (UInt32)Images.Size() + 1) - { - // old wim (1.09) uses zero based image index - if (imageInfo.Index != (UInt32)Images.Size()) - return false; - } - - imageInfo.ItemIndexInXml = i; - Images.Add(imageInfo); - } - - if (item.IsTagged("ESD")) - { - FOR_VECTOR (k, item.SubItems) - { - const CXmlItem &item2 = item.SubItems[k]; - if (item2.IsTagged("ENCRYPTED")) - IsEncrypted = true; - } - } - } - - return true; -} - -}} +// Archive/WimIn.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/IntToString.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/XpressDecoder.h" + +#include "../Common/OutStreamWithSha1.h" + +#include "WimIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +namespace NArchive { +namespace NWim { + +static bool inline GetLog_val_min_dest(const UInt32 val, unsigned i, unsigned &dest) +{ + UInt32 v = (UInt32)1 << i; + for (; i < 32; i++) + { + if (v == val) + { + dest = i; + return true; + } + v += v; + } + return false; +} + + +HRESULT CUnpacker::UnpackChunk( + ISequentialInStream *inStream, + unsigned method, unsigned chunkSizeBits, + size_t inSize, size_t outSize, + ISequentialOutStream *outStream) +{ + if (inSize == outSize) + { + } + else if (method == NMethod::kXPRESS) + { + } + else if (method == NMethod::kLZX) + { + lzxDecoder.Create_if_Empty(); + lzxDecoder->Set_WimMode(true); + } + else if (method == NMethod::kLZMS) + { + lzmsDecoder.Create_if_Empty(); + } + else + return E_NOTIMPL; + + const size_t chunkSize = (size_t)1 << chunkSizeBits; + + { + const unsigned + kAdditionalOutputBufSize = MyMax(NCompress::NLzx:: + kAdditionalOutputBufSize, NCompress::NXpress:: + kAdditionalOutputBufSize); + unpackBuf.EnsureCapacity(chunkSize + kAdditionalOutputBufSize); + if (!unpackBuf.Data) + return E_OUTOFMEMORY; + } + + HRESULT res = S_FALSE; + size_t unpackedSize = 0; + + if (inSize == outSize) + { + unpackedSize = outSize; + res = ReadStream(inStream, unpackBuf.Data, &unpackedSize); + TotalPacked += unpackedSize; + } + else if (inSize < chunkSize) + { + const unsigned kAdditionalInputSize = 32; + packBuf.EnsureCapacity(chunkSize + kAdditionalInputSize); + if (!packBuf.Data) + return E_OUTOFMEMORY; + + RINOK(ReadStream_FALSE(inStream, packBuf.Data, inSize)) + memset(packBuf.Data + inSize, 0xff, kAdditionalInputSize); + + TotalPacked += inSize; + + if (method == NMethod::kXPRESS) + { + res = NCompress::NXpress::Decode_WithExceedWrite(packBuf.Data, inSize, unpackBuf.Data, outSize); + if (res == S_OK) + unpackedSize = outSize; + } + else if (method == NMethod::kLZX) + { + res = lzxDecoder->Set_ExternalWindow_DictBits(unpackBuf.Data, chunkSizeBits); + if (res != S_OK) + return E_NOTIMPL; + lzxDecoder->Set_KeepHistoryForNext(false); + lzxDecoder->Set_KeepHistory(false); + res = lzxDecoder->Code_WithExceedReadWrite(packBuf.Data, inSize, (UInt32)outSize); + unpackedSize = lzxDecoder->GetUnpackSize(); + if (res == S_OK && !lzxDecoder->WasBlockFinished()) + res = S_FALSE; + } + else + { + res = lzmsDecoder->Code(packBuf.Data, inSize, unpackBuf.Data, outSize); + unpackedSize = lzmsDecoder->GetUnpackSize(); + } + } + + if (unpackedSize != outSize) + { + if (res == S_OK) + res = S_FALSE; + + if (unpackedSize > outSize) + res = S_FALSE; + else + memset(unpackBuf.Data + unpackedSize, 0, outSize - unpackedSize); + } + + if (outStream) + { + RINOK(WriteStream(outStream, unpackBuf.Data, outSize)) + } + + return res; +} + + +HRESULT CUnpacker::Unpack2( + IInStream *inStream, + const CResource &resource, + const CHeader &header, + const CDatabase *db, + ISequentialOutStream *outStream, + ICompressProgressInfo *progress) +{ + if (!resource.IsCompressed() && !resource.IsSolid()) + { + copyCoder.Create_if_Empty(); + + CMyComPtr2_Create limitedStream; + limitedStream->SetStream(inStream); + + RINOK(InStream_SeekSet(inStream, resource.Offset)) + if (resource.PackSize != resource.UnpackSize) + return S_FALSE; + + limitedStream->Init(resource.PackSize); + TotalPacked += resource.PackSize; + + HRESULT res = copyCoder.Interface()->Code(limitedStream, outStream, NULL, NULL, progress); + + if (res == S_OK && copyCoder->TotalSize != resource.UnpackSize) + res = S_FALSE; + return res; + } + + if (resource.IsSolid()) + { + if (!db || resource.SolidIndex < 0) + return E_NOTIMPL; + if (resource.IsCompressed()) + return E_NOTIMPL; + + const CSolid &ss = db->Solids[resource.SolidIndex]; + + const unsigned chunkSizeBits = ss.ChunkSizeBits; + const size_t chunkSize = (size_t)1 << chunkSizeBits; + + size_t chunkIndex = 0; + UInt64 rem = ss.UnpackSize; + size_t offsetInChunk = 0; + + if (resource.IsSolidSmall()) + { + UInt64 offs = resource.Offset; + if (offs < ss.SolidOffset) + return E_NOTIMPL; + offs -= ss.SolidOffset; + if (offs > ss.UnpackSize) + return E_NOTIMPL; + rem = resource.PackSize; + if (rem > ss.UnpackSize - offs) + return E_NOTIMPL; + chunkIndex = (size_t)(offs >> chunkSizeBits); + offsetInChunk = (size_t)offs & (chunkSize - 1); + } + + UInt64 packProcessed = 0; + UInt64 outProcessed = 0; + + if (_solidIndex == resource.SolidIndex && _unpackedChunkIndex == chunkIndex) + { + size_t cur = chunkSize - offsetInChunk; + if (cur > rem) + cur = (size_t)rem; + RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)) + outProcessed += cur; + rem -= cur; + offsetInChunk = 0; + chunkIndex++; + } + + for (;;) + { + if (rem == 0) + return S_OK; + + const UInt64 offset = ss.Chunks[chunkIndex]; + const UInt64 packSize = ss.GetChunkPackSize(chunkIndex); + const CResource &rs = db->DataStreams[ss.StreamIndex].Resource; + RINOK(InStream_SeekSet(inStream, rs.Offset + ss.HeadersSize + offset)) + + size_t cur = chunkSize; + const UInt64 unpackRem = ss.UnpackSize - ((UInt64)chunkIndex << chunkSizeBits); + if (cur > unpackRem) + cur = (size_t)unpackRem; + + _solidIndex = -1; + _unpackedChunkIndex = 0; + + const HRESULT res = UnpackChunk(inStream, (unsigned)ss.Method, chunkSizeBits, (size_t)packSize, cur, NULL); + + if (res != S_OK) + { + // We ignore data errors in solid stream. SHA will show what files are bad. + if (res != S_FALSE) + return res; + } + + _solidIndex = resource.SolidIndex; + _unpackedChunkIndex = chunkIndex; + + if (cur < offsetInChunk) + return E_FAIL; + + cur -= offsetInChunk; + + if (cur > rem) + cur = (size_t)rem; + + RINOK(WriteStream(outStream, unpackBuf.Data + offsetInChunk, cur)) + + if (progress) + { + RINOK(progress->SetRatioInfo(&packProcessed, &outProcessed)) + packProcessed += packSize; + outProcessed += cur; + } + + rem -= cur; + offsetInChunk = 0; + chunkIndex++; + } + } + + + // ---------- NON Solid ---------- + + const UInt64 unpackSize = resource.UnpackSize; + if (unpackSize == 0) + { + if (resource.PackSize == 0) + return S_OK; + return S_FALSE; + } + + if (unpackSize > ((UInt64)1 << 63)) + return E_NOTIMPL; + + const unsigned chunkSizeBits = header.ChunkSizeBits; + const unsigned entrySizeShifts = (resource.UnpackSize < ((UInt64)1 << 32) ? 2 : 3); + + UInt64 baseOffset = resource.Offset; + UInt64 packDataSize; + size_t numChunks; + { + const UInt64 numChunks64 = (unpackSize + (((UInt32)1 << chunkSizeBits) - 1)) >> chunkSizeBits; + const UInt64 sizesBufSize64 = (numChunks64 - 1) << entrySizeShifts; + if (sizesBufSize64 > resource.PackSize) + return S_FALSE; + packDataSize = resource.PackSize - sizesBufSize64; + const size_t sizesBufSize = (size_t)sizesBufSize64; + if (sizesBufSize != sizesBufSize64) + return E_OUTOFMEMORY; + sizesBuf.AllocAtLeast(sizesBufSize); + RINOK(InStream_SeekSet(inStream, baseOffset)) + RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)) + baseOffset += sizesBufSize64; + numChunks = (size_t)numChunks64; + } + + _solidIndex = -1; + _unpackedChunkIndex = 0; + + UInt64 outProcessed = 0; + UInt64 offset = 0; + + for (size_t i = 0; i < numChunks; i++) + { + UInt64 nextOffset = packDataSize; + + if (i + 1 < numChunks) + { + const Byte *p = (const Byte *)sizesBuf + (i << entrySizeShifts); + nextOffset = (entrySizeShifts == 2) ? Get32(p): Get64(p); + } + + if (nextOffset < offset) + return S_FALSE; + + UInt64 inSize64 = nextOffset - offset; + size_t inSize = (size_t)inSize64; + if (inSize != inSize64) + return S_FALSE; + + RINOK(InStream_SeekSet(inStream, baseOffset + offset)) + + if (progress) + { + RINOK(progress->SetRatioInfo(&offset, &outProcessed)) + } + + size_t outSize = (size_t)1 << chunkSizeBits; + const UInt64 rem = unpackSize - outProcessed; + if (outSize > rem) + outSize = (size_t)rem; + + RINOK(UnpackChunk(inStream, header.GetMethod(), chunkSizeBits, inSize, outSize, outStream)) + + outProcessed += outSize; + offset = nextOffset; + } + + return S_OK; +} + + +HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, const CHeader &header, const CDatabase *db, + ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest) +{ + CMyComPtr2_Create shaStream; + // outStream can be NULL, so we use COutStreamWithSha1 even if sha1 is not required + shaStream->SetStream(outStream); + shaStream->Init(digest != NULL); + const HRESULT res = Unpack2(inStream, resource, header, db, shaStream, progress); + if (digest) + shaStream->Final(digest); + return res; +} + + +HRESULT CUnpacker::UnpackData(IInStream *inStream, + const CResource &resource, const CHeader &header, + const CDatabase *db, + CByteBuffer &buf, Byte *digest) +{ + // if (resource.IsSolid()) return E_NOTIMPL; + UInt64 unpackSize64 = resource.UnpackSize; + if (db) + unpackSize64 = db->Get_UnpackSize_of_Resource(resource); + const size_t size = (size_t)unpackSize64; + if (size != unpackSize64) + return E_OUTOFMEMORY; + buf.Alloc(size); + + CMyComPtr2_Create outStream; + outStream->Init((Byte *)buf, size); + return Unpack(inStream, resource, header, db, outStream, NULL, digest); +} + + +void CResource::Parse(const Byte *p) +{ + Flags = p[7]; + PackSize = Get64(p) & (((UInt64)1 << 56) - 1); + Offset = Get64(p + 8); + UnpackSize = Get64(p + 16); + KeepSolid = false; + SolidIndex = -1; +} + +#define GET_RESOURCE(_p_, res) res.ParseAndUpdatePhySize(_p_, phySize) + +static inline void ParseStream(bool oldVersion, const Byte *p, CStreamInfo &s) +{ + s.Resource.Parse(p); + if (oldVersion) + { + s.PartNumber = 1; + s.Id = Get32(p + 24); + p += 28; + } + else + { + s.PartNumber = Get16(p + 24); + p += 26; + } + s.RefCount = Get32(p); + memcpy(s.Hash, p + 4, kHashSize); +} + + +#define kLongPath "[LongPath]" + +void CDatabase::GetShortName(unsigned index, NWindows::NCOM::CPropVariant &name) const +{ + const CItem &item = Items[index]; + const CImage &image = Images[item.ImageIndex]; + if (item.Parent < 0 && image.NumEmptyRootItems != 0) + { + name.Clear(); + return; + } + const Byte *meta = image.Meta + item.Offset + + (IsOldVersion ? kDirRecordSizeOld : kDirRecordSize); + UInt32 fileNameLen = Get16(meta - 2); + UInt32 shortLen = Get16(meta - 4) / 2; + wchar_t *s = name.AllocBstr(shortLen); + if (fileNameLen != 0) + meta += fileNameLen + 2; + for (UInt32 i = 0; i < shortLen; i++) + s[i] = Get16(meta + i * 2); + s[shortLen] = 0; + // empty shortName has no ZERO at the end ? +} + + +void CDatabase::GetItemName(unsigned index, NWindows::NCOM::CPropVariant &name) const +{ + const CItem &item = Items[index]; + const CImage &image = Images[item.ImageIndex]; + if (item.Parent < 0 && image.NumEmptyRootItems != 0) + { + name = image.RootName; + return; + } + const Byte *meta = image.Meta + item.Offset + + (item.IsAltStream ? + (IsOldVersion ? 0x10 : 0x24) : + (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2)); + UInt32 len = Get16(meta) / 2; + wchar_t *s = name.AllocBstr(len); + meta += 2; + len++; + for (UInt32 i = 0; i < len; i++) + s[i] = Get16(meta + i * 2); +} + + +void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCOM::CPropVariant &path) const +{ + unsigned size = 0; + int index = (int)index1; + const int imageIndex = Items[index].ImageIndex; + const CImage &image = Images[imageIndex]; + + unsigned newLevel = 0; + bool needColon = false; + + for (;;) + { + const CItem &item = Items[index]; + index = item.Parent; + if (index >= 0 || image.NumEmptyRootItems == 0) + { + const Byte *meta = image.Meta + item.Offset; + meta += item.IsAltStream ? + (IsOldVersion ? 0x10 : 0x24) : + (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2); + needColon = item.IsAltStream; + size += Get16(meta) / 2; + size += newLevel; + newLevel = 1; + if (size >= ((UInt32)1 << 15)) + { + path = kLongPath; + return; + } + } + if (index < 0) + break; + } + + if (showImageNumber) + { + size += image.RootName.Len(); + size += newLevel; + } + else if (needColon) + size++; + + wchar_t *s = path.AllocBstr(size); + s[size] = 0; + + if (showImageNumber) + { + MyStringCopy(s, (const wchar_t *)image.RootName); + if (newLevel) + s[image.RootName.Len()] = (wchar_t)(needColon ? L':' : WCHAR_PATH_SEPARATOR); + } + else if (needColon) + s[0] = L':'; + + index = (int)index1; + wchar_t separator = 0; + + for (;;) + { + const CItem &item = Items[index]; + index = item.Parent; + if (index >= 0 || image.NumEmptyRootItems == 0) + { + if (separator != 0) + s[--size] = separator; + const Byte *meta = image.Meta + item.Offset; + meta += (item.IsAltStream) ? + (IsOldVersion ? 0x10: 0x24) : + (IsOldVersion ? kDirRecordSizeOld - 2 : kDirRecordSize - 2); + unsigned len = Get16(meta) / 2; + size -= len; + wchar_t *dest = s + size; + meta += 2; + for (unsigned i = 0; i < len; i++) + { + wchar_t c = Get16(meta + i * 2); + 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; + } + } + if (index < 0) + return; + separator = item.IsAltStream ? L':' : WCHAR_PATH_SEPARATOR; + } +} + + +// if (ver <= 1.10), root folder contains real items. +// if (ver >= 1.12), root folder contains only one folder with empty name. + +HRESULT CDatabase::ParseDirItem(size_t pos, int parent) +{ + const unsigned align = GetDirAlignMask(); + if ((pos & align) != 0) + return S_FALSE; + + for (unsigned numItems = 0;; numItems++) + { + if (OpenCallback && (Items.Size() & 0xFFFF) == 0) + { + UInt64 numFiles = Items.Size(); + RINOK(OpenCallback->SetCompleted(&numFiles, NULL)) + } + + const size_t rem = DirSize - pos; + if (pos < DirStartOffset || pos > DirSize || rem < 8) + return S_FALSE; + + const Byte *p = DirData + pos; + + UInt64 len = Get64(p); + if (len == 0) + { + DirProcessed += 8; + return S_OK; + } + + if ((len & align) != 0 || rem < len) + return S_FALSE; + + DirProcessed += (size_t)len; + if (DirProcessed > DirSize) + return S_FALSE; + + const unsigned dirRecordSize = IsOldVersion ? kDirRecordSizeOld : kDirRecordSize; + if (len < dirRecordSize) + return S_FALSE; + + CItem item; + UInt32 attrib = Get32(p + 8); + item.IsDir = ((attrib & 0x10) != 0); + UInt64 subdirOffset = Get64(p + 0x10); + + const UInt32 numAltStreams = Get16(p + dirRecordSize - 6); + const UInt32 shortNameLen = Get16(p + dirRecordSize - 4); + const UInt32 fileNameLen = Get16(p + dirRecordSize - 2); + if ((shortNameLen & 1) != 0 || (fileNameLen & 1) != 0) + return S_FALSE; + const UInt32 shortNameLen2 = (shortNameLen == 0 ? shortNameLen : shortNameLen + 2); + const UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2); + if (((dirRecordSize + fileNameLen2 + shortNameLen2 + align) & ~align) > len) + return S_FALSE; + + p += dirRecordSize; + + { + if (*(const UInt16 *)(const void *)(p + fileNameLen) != 0) + return S_FALSE; + for (UInt32 j = 0; j < fileNameLen; j += 2) + if (*(const UInt16 *)(const void *)(p + j) == 0) + return S_FALSE; + } + + // PRF(printf("\n%S", p)); + + if (shortNameLen != 0) + { + // empty shortName has no ZERO at the end ? + const Byte *p2 = p + fileNameLen2; + if (*(const UInt16 *)(const void *)(p2 + shortNameLen) != 0) + return S_FALSE; + for (UInt32 j = 0; j < shortNameLen; j += 2) + if (*(const UInt16 *)(const void *)(p2 + j) == 0) + return S_FALSE; + } + + item.Offset = pos; + item.Parent = parent; + item.ImageIndex = (int)Images.Size() - 1; + + const unsigned prevIndex = Items.Add(item); + + pos += (size_t)len; + + for (UInt32 i = 0; i < numAltStreams; i++) + { + const size_t rem2 = DirSize - pos; + if (pos < DirStartOffset || pos > DirSize || rem2 < 8) + return S_FALSE; + const Byte *p2 = DirData + pos; + const UInt64 len2 = Get64(p2); + if ((len2 & align) != 0 || rem2 < len2 + || len2 < (unsigned)(IsOldVersion ? 0x18 : 0x28)) + return S_FALSE; + + DirProcessed += (size_t)len2; + if (DirProcessed > DirSize) + return S_FALSE; + + unsigned extraOffset = 0; + + if (IsOldVersion) + extraOffset = 0x10; + else + { + if (Get64(p2 + 8) != 0) + return S_FALSE; + extraOffset = 0x24; + } + + const UInt32 fileNameLen111 = Get16(p2 + extraOffset); + if ((fileNameLen111 & 1) != 0) + return S_FALSE; + /* Probably different versions of ImageX can use different number of + additional ZEROs. So we don't use exact check. */ + const UInt32 fileNameLen222 = (fileNameLen111 == 0 ? fileNameLen111 : fileNameLen111 + 2); + if (((extraOffset + 2 + fileNameLen222 + align) & ~align) > len2) + return S_FALSE; + + { + const Byte *p3 = p2 + extraOffset + 2; + if (*(const UInt16 *)(const void *)(p3 + fileNameLen111) != 0) + return S_FALSE; + for (UInt32 j = 0; j < fileNameLen111; j += 2) + if (*(const UInt16 *)(const void *)(p3 + j) == 0) + return S_FALSE; + + // PRF(printf("\n %S", p3)); + } + + + /* wim uses alt sreams list, if there is at least one alt stream. + And alt stream without name is main stream. */ + + // Why wimlib writes two alt streams for REPARSE_POINT, with empty second alt stream? + + Byte *prevMeta = DirData + item.Offset; + + if (fileNameLen111 == 0 && + ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) || !item.IsDir) + && (IsOldVersion || IsEmptySha(prevMeta + 0x40))) + { + if (IsOldVersion) + memcpy(prevMeta + 0x10, p2 + 8, 4); // It's 32-bit Id + else if (!IsEmptySha(p2 + 0x10)) + { + // if (IsEmptySha(prevMeta + 0x40)) + memcpy(prevMeta + 0x40, p2 + 0x10, kHashSize); + // else HeadersError = true; + } + } + else + { + ThereAreAltStreams = true; + CItem item2; + item2.Offset = pos; + item2.IsAltStream = true; + item2.Parent = (int)prevIndex; + item2.ImageIndex = (int)Images.Size() - 1; + Items.Add(item2); + } + + pos += (size_t)len2; + } + + if (parent < 0 && numItems == 0 && shortNameLen == 0 && fileNameLen == 0 && item.IsDir) + { + const Byte *p2 = DirData + pos; + if (DirSize - pos >= 8 && Get64(p2) == 0) + { + CImage &image = Images.Back(); + image.NumEmptyRootItems = 1; + + if (subdirOffset != 0 + && DirSize - pos >= 16 + && Get64(p2 + 8) != 0 + && pos + 8 < subdirOffset) + { + // Longhorn.4093 contains hidden files after empty root folder and before items of next folder. Why? + // That code shows them. If we want to ignore them, we need to update DirProcessed. + // DirProcessed += (size_t)(subdirOffset - (pos + 8)); + // printf("\ndirOffset = %5d hiddenOffset = %5d\n", (int)subdirOffset, (int)pos + 8); + subdirOffset = pos + 8; + // return S_FALSE; + } + } + } + + if (item.IsDir && subdirOffset != 0) + { + RINOK(ParseDirItem((size_t)subdirOffset, (int)prevIndex)) + } + } +} + + +HRESULT CDatabase::ParseImageDirs(CByteBuffer &buf, int parent) +{ + DirData = buf; + DirSize = buf.Size(); + if (DirSize < 8) + return S_FALSE; + const Byte *p = DirData; + size_t pos = 0; + CImage &image = Images.Back(); + + if (IsOldVersion) + { + UInt32 numEntries = Get32(p + 4); + + if (numEntries > (1 << 28) || + numEntries > (DirSize >> 3)) + return S_FALSE; + + UInt32 sum = 8; + if (numEntries != 0) + sum = numEntries * 8; + + image.SecurOffsets.ClearAndReserve(numEntries + 1); + image.SecurOffsets.AddInReserved(sum); + + for (UInt32 i = 0; i < numEntries; i++) + { + const Byte *pp = p + (size_t)i * 8; + UInt32 len = Get32(pp); + if (i != 0 && Get32(pp + 4) != 0) + return S_FALSE; + if (len > DirSize - sum) + return S_FALSE; + sum += len; + if (sum < len) + return S_FALSE; + image.SecurOffsets.AddInReserved(sum); + } + + pos = sum; + + const size_t align = GetDirAlignMask(); + pos = (pos + align) & ~(size_t)align; + } + else + { + UInt32 totalLen = Get32(p); + if (totalLen == 0) + pos = 8; + else + { + if (totalLen < 8) + return S_FALSE; + UInt32 numEntries = Get32(p + 4); + pos = 8; + if (totalLen > DirSize || numEntries > ((totalLen - 8) >> 3)) + return S_FALSE; + UInt32 sum = (UInt32)pos + numEntries * 8; + image.SecurOffsets.ClearAndReserve(numEntries + 1); + image.SecurOffsets.AddInReserved(sum); + + for (UInt32 i = 0; i < numEntries; i++, pos += 8) + { + UInt64 len = Get64(p + pos); + if (len > totalLen - sum) + return S_FALSE; + sum += (UInt32)len; + image.SecurOffsets.AddInReserved(sum); + } + + pos = sum; + pos = (pos + 7) & ~(size_t)7; + if (pos != (((size_t)totalLen + 7) & ~(size_t)7)) + return S_FALSE; + } + } + + if (pos > DirSize) + return S_FALSE; + + DirStartOffset = DirProcessed = pos; + image.StartItem = Items.Size(); + + RINOK(ParseDirItem(pos, parent)) + + image.NumItems = Items.Size() - image.StartItem; + if (DirProcessed == DirSize) + return S_OK; + + /* Original program writes additional 8 bytes (END_OF_ROOT_FOLDER), + but the reference to that folder is empty */ + + // we can't use DirProcessed - DirStartOffset == 112 check if there is alt stream in root + if (DirProcessed == DirSize - 8 && Get64(p + DirSize - 8) != 0) + return S_OK; + + // 18.06: we support cases, when some old dism can capture images + // where DirProcessed much smaller than DirSize + HeadersError = true; + return S_OK; + // return S_FALSE; +} + + +HRESULT CHeader::Parse(const Byte *p, UInt64 &phySize) +{ + UInt32 headerSize = Get32(p + 8); + phySize = headerSize; + Version = Get32(p + 0x0C); + Flags = Get32(p + 0x10); + if (!IsSupported()) + return S_FALSE; + + { + ChunkSize = Get32(p + 0x14); + ChunkSizeBits = kChunkSizeBits; + if (ChunkSize != 0) + { + if (!GetLog_val_min_dest(ChunkSize, 12, ChunkSizeBits)) + return S_FALSE; + } + } + + _isOldVersion = false; + _isNewVersion = false; + + if (IsSolidVersion()) + _isNewVersion = true; + else + { + if (Version < 0x010900) + return S_FALSE; + _isOldVersion = (Version <= 0x010A00); + // We don't know details about 1.11 version. So we use headerSize to guess exact features. + if (Version == 0x010B00 && headerSize == 0x60) + _isOldVersion = true; + _isNewVersion = (Version >= 0x010D00); + } + + unsigned offset; + + if (IsOldVersion()) + { + if (headerSize != 0x60) + return S_FALSE; + memset(Guid, 0, 16); + offset = 0x18; + PartNumber = 1; + NumParts = 1; + } + else + { + if (headerSize < 0x74) + return S_FALSE; + memcpy(Guid, p + 0x18, 16); + PartNumber = Get16(p + 0x28); + NumParts = Get16(p + 0x2A); + if (PartNumber == 0 || PartNumber > NumParts) + return S_FALSE; + offset = 0x2C; + if (IsNewVersion()) + { + // if (headerSize < 0xD0) + if (headerSize != 0xD0) + return S_FALSE; + NumImages = Get32(p + offset); + offset += 4; + } + } + + GET_RESOURCE(p + offset , OffsetResource); + GET_RESOURCE(p + offset + 0x18, XmlResource); + GET_RESOURCE(p + offset + 0x30, MetadataResource); + BootIndex = 0; + + if (IsNewVersion()) + { + BootIndex = Get32(p + offset + 0x48); + GET_RESOURCE(p + offset + 0x4C, IntegrityResource); + } + + return S_OK; +} + + +const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }; + +HRESULT ReadHeader(IInStream *inStream, CHeader &h, UInt64 &phySize) +{ + Byte p[kHeaderSizeMax]; + RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)) + if (memcmp(p, kSignature, kSignatureSize) != 0) + return S_FALSE; + return h.Parse(p, phySize); +} + + +static HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) +{ + CByteBuffer offsetBuf; + + CUnpacker unpacker; + RINOK(unpacker.UnpackData(inStream, h.OffsetResource, h, NULL, offsetBuf, NULL)) + + const size_t streamInfoSize = h.IsOldVersion() ? kStreamInfoSize + 2 : kStreamInfoSize; + { + const unsigned numItems = (unsigned)(offsetBuf.Size() / streamInfoSize); + if ((size_t)numItems * streamInfoSize != offsetBuf.Size()) + return S_FALSE; + const unsigned numItems2 = db.DataStreams.Size() + numItems; + if (numItems2 < numItems) + return S_FALSE; + db.DataStreams.Reserve(numItems2); + } + + bool keepSolid = false; + + for (size_t i = 0; i < offsetBuf.Size(); i += streamInfoSize) + { + CStreamInfo s; + ParseStream(h.IsOldVersion(), (const Byte *)offsetBuf + i, s); + + PRF(printf("\n")); + PRF(printf(s.Resource.IsMetadata() ? "### META" : " DATA")); + PRF(printf(" %2X", s.Resource.Flags)); + PRF(printf(" %9I64X", s.Resource.Offset)); + PRF(printf(" %9I64X", s.Resource.PackSize)); + PRF(printf(" %9I64X", s.Resource.UnpackSize)); + PRF(printf(" %d", s.RefCount)); + + if (s.PartNumber != h.PartNumber) + continue; + + if (s.Resource.IsSolid()) + { + s.Resource.KeepSolid = keepSolid; + keepSolid = true; + } + else + { + s.Resource.KeepSolid = false; + keepSolid = false; + } + + if (!s.Resource.IsMetadata()) + db.DataStreams.AddInReserved(s); + else + { + if (s.Resource.IsSolid()) + return E_NOTIMPL; + if (s.RefCount == 0) + { + // some wims have such (deleted?) metadata stream. + // examples: boot.wim in VistaBeta2, WinPE.wim from WAIK. + // db.DataStreams.Add(s); + // we can show these delete images, if we comment "continue" command; + continue; + } + + if (s.RefCount > 1) + { + return S_FALSE; + // s.RefCount--; + // db.DataStreams.Add(s); + } + + db.MetaStreams.Add(s); + } + } + + PRF(printf("\n")); + + return S_OK; +} + + +HRESULT CDatabase::OpenXml(IInStream *inStream, const CHeader &h, CByteBuffer &xml) +{ + CUnpacker unpacker; + return unpacker.UnpackData(inStream, h.XmlResource, h, this, xml, NULL); +} + +static void SetRootNames(CImage &image, unsigned value) +{ + wchar_t temp[16]; + ConvertUInt32ToString(value, temp); + image.RootName = temp; + image.RootNameBuf.Alloc(image.RootName.Len() * 2 + 2); + Byte *p = image.RootNameBuf; + unsigned len = image.RootName.Len() + 1; + for (unsigned k = 0; k < len; k++) + { + p[k * 2] = (Byte)temp[k]; + p[k * 2 + 1] = 0; + } +} + + +HRESULT CDatabase::Open(IInStream *inStream, const CHeader &h, unsigned numItemsReserve, IArchiveOpenCallback *openCallback) +{ + OpenCallback = openCallback; + IsOldVersion = h.IsOldVersion(); + IsOldVersion9 = (h.Version == 0x10900); + + RINOK(ReadStreams(inStream, h, *this)) + + bool needBootMetadata = !h.MetadataResource.IsEmpty(); + unsigned numNonDeletedImages = 0; + + CUnpacker unpacker; + + FOR_VECTOR (i, MetaStreams) + { + const CStreamInfo &si = MetaStreams[i]; + + if (h.PartNumber != 1 || si.PartNumber != h.PartNumber) + continue; + + const unsigned userImage = Images.Size() + GetStartImageIndex(); + CImage &image = Images.AddNew(); + SetRootNames(image, userImage); + + CByteBuffer &metadata = image.Meta; + Byte hash[kHashSize]; + + RINOK(unpacker.UnpackData(inStream, si.Resource, h, this, metadata, hash)) + + if (memcmp(hash, si.Hash, kHashSize) != 0 && + !(h.IsOldVersion() && IsEmptySha(si.Hash))) + return S_FALSE; + + image.NumEmptyRootItems = 0; + + if (Items.IsEmpty()) + Items.ClearAndReserve(numItemsReserve); + + RINOK(ParseImageDirs(metadata, -1)) + + if (needBootMetadata) + { + bool sameRes = (h.MetadataResource.Offset == si.Resource.Offset); + if (sameRes) + needBootMetadata = false; + if (h.IsNewVersion()) + { + if (si.RefCount == 1) + { + numNonDeletedImages++; + bool isBootIndex = (h.BootIndex == numNonDeletedImages); + if (sameRes && !isBootIndex) + return S_FALSE; + if (isBootIndex && !sameRes) + return S_FALSE; + } + } + } + } + + if (needBootMetadata) + return S_FALSE; + return S_OK; +} + + +bool CDatabase::ItemHasStream(const CItem &item) const +{ + if (item.ImageIndex < 0) + return true; + const Byte *meta = Images[item.ImageIndex].Meta + item.Offset; + if (IsOldVersion) + { + // old wim use same field for file_id and dir_offset; + if (item.IsDir) + return false; + meta += (item.IsAltStream ? 0x8 : 0x10); + UInt32 id = GetUi32(meta); + return id != 0; + } + meta += (item.IsAltStream ? 0x10 : 0x40); + return !IsEmptySha(meta); +} + + +#define RINOZ(x) { int _tt_ = (x); if (_tt_ != 0) return _tt_; } + +static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */) +{ + RINOZ(MyCompare(p1->PartNumber, p2->PartNumber)) + RINOZ(MyCompare(p1->Resource.Offset, p2->Resource.Offset)) + return MyCompare(p1->Resource.PackSize, p2->Resource.PackSize); +} + +static int CompareIDs(const unsigned *p1, const unsigned *p2, void *param) +{ + const CStreamInfo *streams = (const CStreamInfo *)param; + return MyCompare(streams[*p1].Id, streams[*p2].Id); +} + +static int CompareHashRefs(const unsigned *p1, const unsigned *p2, void *param) +{ + const CStreamInfo *streams = (const CStreamInfo *)param; + return memcmp(streams[*p1].Hash, streams[*p2].Hash, kHashSize); +} + +static int FindId(const CStreamInfo *streams, const CUIntVector &sorted, UInt32 id) +{ + unsigned left = 0, right = sorted.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const unsigned streamIndex = sorted[mid]; + const UInt32 id2 = streams[streamIndex].Id; + if (id == id2) + return (int)streamIndex; + if (id < id2) + right = mid; + else + left = mid + 1; + } + return -1; +} + +static int FindHash(const CStreamInfo *streams, const CUIntVector &sorted, const Byte *hash) +{ + unsigned left = 0, right = sorted.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const unsigned streamIndex = sorted[mid]; + const Byte *hash2 = streams[streamIndex].Hash; + unsigned i; + for (i = 0; i < kHashSize; i++) + if (hash[i] != hash2[i]) + break; + if (i == kHashSize) + return (int)streamIndex; + if (hash[i] < hash2[i]) + right = mid; + else + left = mid + 1; + } + return -1; +} + +static int CompareItems(const unsigned *a1, const unsigned *a2, void *param) +{ + const CRecordVector &items = ((CDatabase *)param)->Items; + const CItem &i1 = items[*a1]; + const CItem &i2 = items[*a2]; + + if (i1.IsDir != i2.IsDir) + return i1.IsDir ? -1 : 1; + if (i1.IsAltStream != i2.IsAltStream) + return i1.IsAltStream ? 1 : -1; + RINOZ(MyCompare(i1.StreamIndex, i2.StreamIndex)) + RINOZ(MyCompare(i1.ImageIndex, i2.ImageIndex)) + return MyCompare(i1.Offset, i2.Offset); +} + + +HRESULT CDatabase::FillAndCheck(const CObjectVector &volumes) +{ + CUIntVector sortedByHash; + sortedByHash.Reserve(DataStreams.Size()); + { + CByteBuffer sizesBuf; + + for (unsigned iii = 0; iii < DataStreams.Size();) + { + { + const CResource &r = DataStreams[iii].Resource; + if (!r.IsSolid()) + { + sortedByHash.AddInReserved(iii++); + continue; + } + } + + UInt64 solidRunOffset = 0; + unsigned k; + unsigned numSolidsStart = Solids.Size(); + + for (k = iii; k < DataStreams.Size(); k++) + { + CStreamInfo &si = DataStreams[k]; + CResource &r = si.Resource; + + if (!r.IsSolid()) + break; + if (!r.KeepSolid && k != iii) + break; + + if (r.Flags != NResourceFlags::kSolid) + return S_FALSE; + + if (!r.IsSolidBig()) + continue; + + if (!si.IsEmptyHash()) + return S_FALSE; + if (si.RefCount != 1) + return S_FALSE; + + r.SolidIndex = (int)Solids.Size(); + + CSolid &ss = Solids.AddNew(); + ss.StreamIndex = k; + ss.SolidOffset = solidRunOffset; + { + const size_t kSolidHeaderSize = 8 + 4 + 4; + Byte header[kSolidHeaderSize]; + + if (si.PartNumber >= volumes.Size()) + return S_FALSE; + + const CVolume &vol = volumes[si.PartNumber]; + IInStream *inStream = vol.Stream; + RINOK(InStream_SeekSet(inStream, r.Offset)) + RINOK(ReadStream_FALSE(inStream, (Byte *)header, kSolidHeaderSize)) + + ss.UnpackSize = GetUi64(header); + + if (ss.UnpackSize > ((UInt64)1 << 63)) + return S_FALSE; + + solidRunOffset += ss.UnpackSize; + if (solidRunOffset < ss.UnpackSize) + return S_FALSE; + + const UInt32 solidChunkSize = GetUi32(header + 8); + if (!GetLog_val_min_dest(solidChunkSize, 8, ss.ChunkSizeBits)) + return S_FALSE; + ss.Method = (Int32)GetUi32(header + 12); + + const UInt64 numChunks64 = (ss.UnpackSize + (((UInt32)1 << ss.ChunkSizeBits) - 1)) >> ss.ChunkSizeBits; + const UInt64 sizesBufSize64 = 4 * numChunks64; + ss.HeadersSize = kSolidHeaderSize + sizesBufSize64; + const size_t sizesBufSize = (size_t)sizesBufSize64; + if (sizesBufSize != sizesBufSize64) + return E_OUTOFMEMORY; + sizesBuf.AllocAtLeast(sizesBufSize); + + RINOK(ReadStream_FALSE(inStream, sizesBuf, sizesBufSize)) + + const size_t numChunks = (size_t)numChunks64; + ss.Chunks.Alloc(numChunks + 1); + + UInt64 offset = 0; + + size_t c; + for (c = 0; c < numChunks; c++) + { + ss.Chunks[c] = offset; + UInt32 packSize = GetUi32((const Byte *)sizesBuf + c * 4); + offset += packSize; + if (offset < packSize) + return S_FALSE; + } + ss.Chunks[c] = offset; + + if (ss.Chunks[0] != 0) + return S_FALSE; + if (ss.HeadersSize + offset != r.PackSize) + return S_FALSE; + } + } + + unsigned solidLim = k; + + for (k = iii; k < solidLim; k++) + { + CStreamInfo &si = DataStreams[k]; + CResource &r = si.Resource; + + if (!r.IsSolidSmall()) + continue; + + if (si.IsEmptyHash()) + return S_FALSE; + + unsigned solidIndex; + { + UInt64 offset = r.Offset; + for (solidIndex = numSolidsStart;; solidIndex++) + { + if (solidIndex == Solids.Size()) + return S_FALSE; + UInt64 unpackSize = Solids[solidIndex].UnpackSize; + if (offset < unpackSize) + break; + offset -= unpackSize; + } + } + CSolid &ss = Solids[solidIndex]; + if (r.Offset < ss.SolidOffset) + return S_FALSE; + const UInt64 relat = r.Offset - ss.SolidOffset; + if (relat > ss.UnpackSize) + return S_FALSE; + if (r.PackSize > ss.UnpackSize - relat) + return S_FALSE; + r.SolidIndex = (int)solidIndex; + if (ss.FirstSmallStream < 0) + ss.FirstSmallStream = (int)k; + + sortedByHash.AddInReserved(k); + // ss.NumRefs++; + } + + iii = solidLim; + } + } + + if (Solids.IsEmpty()) + { + /* We want to check that streams layout is OK. + So we need resources sorted by offset. + Another code can work with non-sorted streams. + NOTE: all WIM programs probably create wim archives with + sorted data streams. So it doesn't call Sort() here. */ + + { + unsigned i; + for (i = 1; i < DataStreams.Size(); i++) + { + const CStreamInfo &s0 = DataStreams[i - 1]; + const CStreamInfo &s1 = DataStreams[i]; + if (s0.PartNumber < s1.PartNumber) continue; + if (s0.PartNumber > s1.PartNumber) break; + if (s0.Resource.Offset < s1.Resource.Offset) continue; + if (s0.Resource.Offset > s1.Resource.Offset) break; + if (s0.Resource.PackSize > s1.Resource.PackSize) break; + } + + if (i < DataStreams.Size()) + { + // return E_FAIL; + DataStreams.Sort(CompareStreamsByPos, NULL); + } + } + + for (unsigned i = 1; i < DataStreams.Size(); i++) + { + const CStreamInfo &s0 = DataStreams[i - 1]; + const CStreamInfo &s1 = DataStreams[i]; + if (s0.PartNumber == s1.PartNumber) + if (s0.Resource.GetEndLimit() > s1.Resource.Offset) + return S_FALSE; + } + } + + { + { + const CStreamInfo *streams = DataStreams.ConstData(); + + if (IsOldVersion) + { + sortedByHash.Sort(CompareIDs, (void *)streams); + + for (unsigned i = 1; i < sortedByHash.Size(); i++) + if (streams[sortedByHash[i - 1]].Id >= + streams[sortedByHash[i]].Id) + return S_FALSE; + } + else + { + sortedByHash.Sort(CompareHashRefs, (void *)streams); + + if (!sortedByHash.IsEmpty()) + { + if (IsEmptySha(streams[sortedByHash[0]].Hash)) + HeadersError = true; + + for (unsigned i = 1; i < sortedByHash.Size(); i++) + if (memcmp( + streams[sortedByHash[i - 1]].Hash, + streams[sortedByHash[i]].Hash, + kHashSize) >= 0) + return S_FALSE; + } + } + } + + FOR_VECTOR (i, Items) + { + CItem &item = Items[i]; + item.StreamIndex = -1; + const Byte *hash = Images[item.ImageIndex].Meta + item.Offset; + if (IsOldVersion) + { + if (!item.IsDir) + { + hash += (item.IsAltStream ? 0x8 : 0x10); + UInt32 id = GetUi32(hash); + if (id != 0) + item.StreamIndex = FindId(DataStreams.ConstData(), sortedByHash, id); + } + } + /* + else if (item.IsDir) + { + // reparse points can have dirs some dir + } + */ + else + { + hash += (item.IsAltStream ? 0x10 : 0x40); + if (!IsEmptySha(hash)) + { + item.StreamIndex = FindHash(DataStreams.ConstData(), sortedByHash, hash); + } + } + } + } + { + CUIntVector refCounts; + refCounts.ClearAndSetSize(DataStreams.Size()); + unsigned i; + + for (i = 0; i < DataStreams.Size(); i++) + { + UInt32 startVal = 0; + // const CStreamInfo &s = DataStreams[i]; + /* + if (s.Resource.IsMetadata() && s.PartNumber == 1) + startVal = 1; + */ + refCounts[i] = startVal; + } + + for (i = 0; i < Items.Size(); i++) + { + const int streamIndex = Items[i].StreamIndex; + if (streamIndex >= 0) + refCounts[streamIndex]++; + } + + for (i = 0; i < DataStreams.Size(); i++) + { + const CStreamInfo &s = DataStreams[i]; + if (s.RefCount != refCounts[i] + && !s.Resource.IsSolidBig()) + { + /* + printf("\ni=%5d si.Ref=%2d realRefs=%2d size=%8d offset=%8x id=%4d ", + i, s.RefCount, refCounts[i], (unsigned)s.Resource.UnpackSize, (unsigned)s.Resource.Offset, s.Id); + */ + RefCountError = true; + } + + if (refCounts[i] == 0) + { + const CResource &r = DataStreams[i].Resource; + if (!r.IsSolidBig() || Solids[r.SolidIndex].FirstSmallStream < 0) + { + CItem item; + item.Offset = 0; + item.StreamIndex = (int)i; + item.ImageIndex = -1; + Items.Add(item); + ThereAreDeletedStreams = true; + } + } + } + } + + return S_OK; +} + + +HRESULT CDatabase::GenerateSortedItems(int imageIndex, bool showImageNumber) +{ + SortedItems.Clear(); + VirtualRoots.Clear(); + IndexOfUserImage = imageIndex; + NumExcludededItems = 0; + ExludedItem = -1; + + if (Images.Size() != 1 && imageIndex < 0) + showImageNumber = true; + + unsigned startItem = 0; + unsigned endItem = 0; + + if (imageIndex < 0) + { + endItem = Items.Size(); + if (Images.Size() == 1) + { + IndexOfUserImage = 0; + const CImage &image = Images[0]; + if (!showImageNumber) + NumExcludededItems = image.NumEmptyRootItems; + } + } + else if ((unsigned)imageIndex < Images.Size()) + { + const CImage &image = Images[imageIndex]; + startItem = image.StartItem; + endItem = startItem + image.NumItems; + if (!showImageNumber) + NumExcludededItems = image.NumEmptyRootItems; + } + + if (NumExcludededItems != 0) + { + ExludedItem = (int)startItem; + startItem += NumExcludededItems; + } + + unsigned num = endItem - startItem; + SortedItems.ClearAndSetSize(num); + unsigned i; + for (i = 0; i < num; i++) + SortedItems[i] = startItem + i; + + SortedItems.Sort(CompareItems, this); + for (i = 0; i < SortedItems.Size(); i++) + Items[SortedItems[i]].IndexInSorted = (int)i; + + if (showImageNumber) + for (i = 0; i < Images.Size(); i++) + { + CImage &image = Images[i]; + if (image.NumEmptyRootItems != 0) + continue; + image.VirtualRootIndex = (int)VirtualRoots.Size(); + VirtualRoots.Add(i); + } + + return S_OK; +} + + +static void IntVector_SetMinusOne_IfNeed(CIntVector &v, unsigned size) +{ + if (v.Size() == size) + return; + v.ClearAndSetSize(size); + int *vals = &v[0]; + for (unsigned i = 0; i < size; i++) + vals[i] = -1; +} + + +HRESULT CDatabase::ExtractReparseStreams(const CObjectVector &volumes, IArchiveOpenCallback *openCallback) +{ + ItemToReparse.Clear(); + ReparseItems.Clear(); + + // we don't know about Reparse field for OLD WIM format + if (IsOldVersion) + return S_OK; + + CIntVector streamToReparse; + CUnpacker unpacker; + UInt64 totalPackedPrev = 0; + + FOR_VECTOR(indexInSorted, SortedItems) + { + // we use sorted items for faster access + unsigned itemIndex = SortedItems[indexInSorted]; + const CItem &item = Items[itemIndex]; + + if (!item.HasMetadata() || item.IsAltStream) + continue; + + if (item.ImageIndex < 0) + continue; + + const Byte *metadata = Images[item.ImageIndex].Meta + item.Offset; + + const UInt32 attrib = Get32(metadata + 8); + if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0) + continue; + + if (item.StreamIndex < 0) + continue; // it's ERROR + + const CStreamInfo &si = DataStreams[item.StreamIndex]; + if (si.Resource.UnpackSize >= (1 << 16)) + continue; // reparse data can not be larger than 64 KB + + IntVector_SetMinusOne_IfNeed(streamToReparse, DataStreams.Size()); + IntVector_SetMinusOne_IfNeed(ItemToReparse, Items.Size()); + + const unsigned offset = 0x58; // we don't know about Reparse field for OLD WIM format + UInt32 tag = Get32(metadata + offset); + int reparseIndex = streamToReparse[item.StreamIndex]; + CByteBuffer buf; + + if (openCallback) + { + if ((unpacker.TotalPacked - totalPackedPrev) >= ((UInt32)1 << 16)) + { + UInt64 numFiles = Items.Size(); + RINOK(openCallback->SetCompleted(&numFiles, &unpacker.TotalPacked)) + totalPackedPrev = unpacker.TotalPacked; + } + } + + if (reparseIndex >= 0) + { + const CByteBuffer &reparse = ReparseItems[reparseIndex]; + if (tag == Get32(reparse)) + { + ItemToReparse[itemIndex] = reparseIndex; + continue; + } + buf = reparse; + // we support that strange and unusual situation with different tags and same reparse data. + } + else + { + /* + if (si.PartNumber >= volumes.Size()) + continue; + */ + const CVolume &vol = volumes[si.PartNumber]; + /* + if (!vol.Stream) + continue; + */ + + Byte digest[kHashSize]; + HRESULT res = unpacker.UnpackData(vol.Stream, si.Resource, vol.Header, this, buf, digest); + + if (res == S_FALSE) + continue; + + RINOK(res) + + if (memcmp(digest, si.Hash, kHashSize) != 0 + // && !(h.IsOldVersion() && IsEmptySha(si.Hash)) + ) + { + // setErrorStatus; + continue; + } + } + + CByteBuffer &reparse = ReparseItems.AddNew(); + reparse.Alloc(8 + buf.Size()); + Byte *dest = (Byte *)reparse; + SetUi32(dest, tag) + SetUi32(dest + 4, (UInt32)buf.Size()) + if (buf.Size() != 0) + memcpy(dest + 8, buf, buf.Size()); + ItemToReparse[itemIndex] = (int)ReparseItems.Size() - 1; + } + + return S_OK; +} + + + +static bool ParseNumber64(const AString &s, UInt64 &res) +{ + const char *end; + if (s.IsPrefixedBy("0x")) + { + if (s.Len() == 2) + return false; + res = ConvertHexStringToUInt64(s.Ptr(2), &end); + } + else + { + if (s.IsEmpty()) + return false; + res = ConvertStringToUInt64(s, &end); + } + return *end == 0; +} + + +static bool ParseNumber32(const AString &s, UInt32 &res) +{ + UInt64 res64; + if (!ParseNumber64(s, res64) || res64 >= ((UInt64)1 << 32)) + return false; + res = (UInt32)res64; + return true; +} + + +static bool ParseTime(const CXmlItem &item, FILETIME &ft, const char *tag) +{ + const CXmlItem *timeItem = item.FindSubTag_GetPtr(tag); + if (timeItem) + { + UInt32 low = 0, high = 0; + if (ParseNumber32(timeItem->GetSubStringForTag("LOWPART"), low) && + ParseNumber32(timeItem->GetSubStringForTag("HIGHPART"), high)) + { + ft.dwLowDateTime = low; + ft.dwHighDateTime = high; + return true; + } + } + return false; +} + + +void CImageInfo::Parse(const CXmlItem &item) +{ + CTimeDefined = ParseTime(item, CTime, "CREATIONTIME"); + MTimeDefined = ParseTime(item, MTime, "LASTMODIFICATIONTIME"); + NameDefined = true; + ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name); + + ParseNumber64(item.GetSubStringForTag("DIRCOUNT"), DirCount); + ParseNumber64(item.GetSubStringForTag("FILECOUNT"), FileCount); + IndexDefined = ParseNumber32(item.GetPropVal("INDEX"), Index); +} + +void CWimXml::ToUnicode(UString &s) +{ + size_t size = Data.Size(); + if (size < 2 || (size & 1) != 0 || size > (1 << 24)) + return; + const Byte *p = Data; + if (Get16(p) != 0xFEFF) + return; + wchar_t *chars = s.GetBuf((unsigned)(size / 2)); + for (size_t i = 2; i < size; i += 2) + { + wchar_t c = Get16(p + i); + if (c == 0) + break; + *chars++ = c; + } + *chars = 0; + s.ReleaseBuf_SetLen((unsigned)(chars - (const wchar_t *)s)); +} + + +bool CWimXml::Parse() +{ + IsEncrypted = false; + AString utf; + { + UString s; + ToUnicode(s); + // if (!ConvertUnicodeToUTF8(s, utf)) return false; + ConvertUnicodeToUTF8(s, utf); + } + + if (!Xml.Parse(utf)) + return false; + if (!Xml.Root.Name.IsEqualTo("WIM")) + return false; + + FOR_VECTOR (i, Xml.Root.SubItems) + { + const CXmlItem &item = Xml.Root.SubItems[i]; + + if (item.IsTagged("IMAGE")) + { + CImageInfo imageInfo; + imageInfo.Parse(item); + if (!imageInfo.IndexDefined) + return false; + + if (imageInfo.Index != (UInt32)Images.Size() + 1) + { + // old wim (1.09) uses zero based image index + if (imageInfo.Index != (UInt32)Images.Size()) + return false; + } + + imageInfo.ItemIndexInXml = (int)i; + Images.Add(imageInfo); + } + + if (item.IsTagged("ESD")) + { + FOR_VECTOR (k, item.SubItems) + { + const CXmlItem &item2 = item.SubItems[k]; + if (item2.IsTagged("ENCRYPTED")) + IsEncrypted = true; + } + } + } + + return true; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimIn.h 2015-10-03 08:49:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimIn.h 2024-01-01 09:00:00.000000000 +0000 @@ -1,656 +1,655 @@ -// Archive/WimIn.h - -#ifndef __ARCHIVE_WIM_IN_H -#define __ARCHIVE_WIM_IN_H - -#include "../../../../C/Alloc.h" - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyXml.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/LzmsDecoder.h" -#include "../../Compress/LzxDecoder.h" - -#include "../IArchive.h" - -namespace NArchive { -namespace NWim { - -/* -WIM versions: -hexVer : headerSize : ver - : 1.07.01 - 1.08.01 : Longhorn.4001-4015 - another header, no signature, CAB compression -10900 : 60 : 1.09 : Longhorn.4029-4039 (2003) -10A00 : 60 : 1.10 : Longhorn.4083 (2004) image starting from 1 -10B00 : ?? : 1.11 : ?? -10C00 : 74 : 1.12 : Longhorn.4093 - VistaBeta1.5112 (2005) - (Multi-Part, SHA1) -10D00 : D0 : 1.13 : VistaBeta2 - Win10, (NumImages, BootIndex, IntegrityResource) -00E00 : D0 : 0.14 : LZMS, solid, esd, dism -*/ - -const unsigned kDirRecordSizeOld = 62; -const unsigned kDirRecordSize = 102; - -/* - There is error in WIM specification about dwReparseTag, dwReparseReserved and liHardLink fields. - - Correct DIRENTRY structure: - { - hex offset - 0 UInt64 Len; - 8 UInt32 Attrib; - C UInt32 SecurityId; - - 10 UInt64 SubdirOffset; // = 0 for files - - 18 UInt64 unused1; // = 0? - 20 UInt64 unused2; // = 0? - - 28 UInt64 CTime; - 30 UInt64 ATime; - 38 UInt64 MTime; - - 40 Byte Sha1[20]; - - 54 UInt32 Unknown1; // is it 0 always? - - - union - { - 58 UInt64 NtNodeId; - { - 58 UInt32 ReparseTag; - 5C UInt32 ReparseFlags; // is it 0 always? Check with new imagex. - } - } - - 60 UInt16 Streams; - - 62 UInt16 ShortNameLen; - 64 UInt16 FileNameLen; - - 66 UInt16 Name[]; - UInt16 ShortName[]; - } - - // DIRENTRY for WIM_VERSION <= 1.10 - DIRENTRY_OLD structure: - { - hex offset - 0 UInt64 Len; - 8 UInt32 Attrib; - C UInt32 SecurityId; - - union - { - 10 UInt64 SubdirOffset; // - - 10 UInt32 OldWimFileId; // used for files in old WIMs - 14 UInt32 OldWimFileId_Reserved; // = 0 - } - - 18 UInt64 CTime; - 20 UInt64 ATime; - 28 UInt64 MTime; - - 30 UInt64 Unknown; // NtNodeId ? - - 38 UInt16 Streams; - 3A UInt16 ShortNameLen; - 3C UInt16 FileNameLen; - 3E UInt16 FileName[]; - UInt16 ShortName[]; - } - - ALT_STREAM structure: - { - hex offset - 0 UInt64 Len; - 8 UInt64 Unused; - 10 Byte Sha1[20]; - 24 UInt16 FileNameLen; - 26 UInt16 FileName[]; - } - - ALT_STREAM_OLD structure: - { - hex offset - 0 UInt64 Len; - 8 UInt64 StreamId; // 32-bit value - 10 UInt16 FileNameLen; - 12 UInt16 FileName[]; - } - - If item is file (not Directory) and there are alternative streams, - there is additional ALT_STREAM item of main "unnamed" stream in Streams array. - -*/ - - -namespace NResourceFlags -{ - // const Byte kFree = 1 << 0; - const Byte kMetadata = 1 << 1; - const Byte kCompressed = 1 << 2; - // const Byte kSpanned = 1 << 3; - const Byte kSolid = 1 << 4; -} - -const UInt64 k_SolidBig_Resource_Marker = (UInt64)1 << 32; - -struct CResource -{ - UInt64 PackSize; - UInt64 Offset; - UInt64 UnpackSize; - Byte Flags; - bool KeepSolid; - int SolidIndex; - - void Clear() - { - PackSize = 0; - Offset = 0; - UnpackSize = 0; - Flags = 0; - KeepSolid = false; - SolidIndex = -1; - } - - UInt64 GetEndLimit() const { return Offset + PackSize; } - void Parse(const Byte *p); - void ParseAndUpdatePhySize(const Byte *p, UInt64 &phySize) - { - Parse(p); - UInt64 v = GetEndLimit(); - if (phySize < v) - phySize = v; - } - - void WriteTo(Byte *p) const; - - bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; } - bool IsCompressed() const { return (Flags & NResourceFlags::kCompressed) != 0; } - bool IsSolid() const { return (Flags & NResourceFlags::kSolid) != 0; } - bool IsSolidBig() const { return IsSolid() && UnpackSize == k_SolidBig_Resource_Marker; } - bool IsSolidSmall() const { return IsSolid() && UnpackSize == 0; } - - bool IsEmpty() const { return (UnpackSize == 0); } -}; - - -struct CSolid -{ - unsigned StreamIndex; - // unsigned NumRefs; - int FirstSmallStream; - - UInt64 SolidOffset; - - UInt64 UnpackSize; - int Method; - int ChunkSizeBits; - - UInt64 HeadersSize; - // size_t NumChunks; - CObjArray Chunks; // [NumChunks + 1] (start offset) - - UInt64 GetChunkPackSize(size_t chunkIndex) const { return Chunks[chunkIndex + 1] - Chunks[chunkIndex]; } - - CSolid(): - FirstSmallStream(-1), - // NumRefs(0), - Method(-1) - {} -}; - - -namespace NHeaderFlags -{ - const UInt32 kCompression = 1 << 1; - const UInt32 kReadOnly = 1 << 2; - const UInt32 kSpanned = 1 << 3; - const UInt32 kResourceOnly = 1 << 4; - const UInt32 kMetadataOnly = 1 << 5; - const UInt32 kWriteInProgress = 1 << 6; - const UInt32 kReparsePointFixup = 1 << 7; - - const UInt32 kXPRESS = (UInt32)1 << 17; - const UInt32 kLZX = (UInt32)1 << 18; - const UInt32 kLZMS = (UInt32)1 << 19; - const UInt32 kXPRESS2 = (UInt32)1 << 21; // XPRESS with nonstandard chunk size ? - - const UInt32 kMethodMask = 0xFFFE0000; -} - - -namespace NMethod -{ - const UInt32 kXPRESS = 1; - const UInt32 kLZX = 2; - const UInt32 kLZMS = 3; -} - - -const UInt32 k_Version_NonSolid = 0x10D00; -const UInt32 k_Version_Solid = 0xE00; - -const unsigned kHeaderSizeMax = 0xD0; -const unsigned kSignatureSize = 8; -extern const Byte kSignature[kSignatureSize]; - -const unsigned kChunkSizeBits = 15; -const UInt32 kChunkSize = (UInt32)1 << kChunkSizeBits; - - -struct CHeader -{ - UInt32 Version; - UInt32 Flags; - UInt32 ChunkSize; - unsigned ChunkSizeBits; - Byte Guid[16]; - UInt16 PartNumber; - UInt16 NumParts; - UInt32 NumImages; - UInt32 BootIndex; - - bool _IsOldVersion; // 1.10- - bool _IsNewVersion; // 1.13+ or 0.14 - - CResource OffsetResource; - CResource XmlResource; - CResource MetadataResource; - CResource IntegrityResource; - - void SetDefaultFields(bool useLZX); - - void WriteTo(Byte *p) const; - HRESULT Parse(const Byte *p, UInt64 &phySize); - - bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; } - - bool IsSupported() const - { - return (!IsCompressed() - || (Flags & NHeaderFlags::kLZX) != 0 - || (Flags & NHeaderFlags::kXPRESS) != 0 - || (Flags & NHeaderFlags::kLZMS) != 0 - || (Flags & NHeaderFlags::kXPRESS2) != 0); - } - - unsigned GetMethod() const - { - if (!IsCompressed()) - return 0; - UInt32 mask = (Flags & NHeaderFlags::kMethodMask); - if (mask == 0) return 0; - if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS; - if (mask == NHeaderFlags::kLZX) return NMethod::kLZX; - if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS; - if (mask == NHeaderFlags::kXPRESS2) return NMethod::kXPRESS; - return mask; - } - - bool IsOldVersion() const { return _IsOldVersion; } - bool IsNewVersion() const { return _IsNewVersion; } - bool IsSolidVersion() const { return (Version == k_Version_Solid); } - - bool AreFromOnArchive(const CHeader &h) - { - return (memcmp(Guid, h.Guid, sizeof(Guid)) == 0) && (h.NumParts == NumParts); - } -}; - - -const unsigned kHashSize = 20; - -inline bool IsEmptySha(const Byte *data) -{ - for (unsigned i = 0; i < kHashSize; i++) - if (data[i] != 0) - return false; - return true; -} - -const unsigned kStreamInfoSize = 24 + 2 + 4 + kHashSize; - -struct CStreamInfo -{ - CResource Resource; - UInt16 PartNumber; // for NEW WIM format, we set it to 1 for OLD WIM format - UInt32 RefCount; - UInt32 Id; // for OLD WIM format - Byte Hash[kHashSize]; - - bool IsEmptyHash() const { return IsEmptySha(Hash); } - - void WriteTo(Byte *p) const; -}; - - -struct CItem -{ - size_t Offset; - int IndexInSorted; - int StreamIndex; - int Parent; - int ImageIndex; // -1 means that file is unreferenced in Images (deleted item?) - bool IsDir; - bool IsAltStream; - - bool HasMetadata() const { return ImageIndex >= 0; } - - CItem(): - IndexInSorted(-1), - StreamIndex(-1), - Parent(-1), - IsDir(false), - IsAltStream(false) - {} -}; - -struct CImage -{ - CByteBuffer Meta; - CRecordVector SecurOffsets; - unsigned StartItem; - unsigned NumItems; - unsigned NumEmptyRootItems; - int VirtualRootIndex; // index in CDatabase::VirtualRoots[] - UString RootName; - CByteBuffer RootNameBuf; - - CImage(): VirtualRootIndex(-1) {} -}; - - -struct CImageInfo -{ - bool CTimeDefined; - bool MTimeDefined; - bool NameDefined; - bool IndexDefined; - - FILETIME CTime; - FILETIME MTime; - UString Name; - - UInt64 DirCount; - UInt64 FileCount; - UInt32 Index; - - int ItemIndexInXml; - - UInt64 GetTotalFilesAndDirs() const { return DirCount + FileCount; } - - CImageInfo(): CTimeDefined(false), MTimeDefined(false), NameDefined(false), - IndexDefined(false), ItemIndexInXml(-1) {} - void Parse(const CXmlItem &item); -}; - - -struct CWimXml -{ - CByteBuffer Data; - CXml Xml; - - UInt16 VolIndex; - CObjectVector Images; - - UString FileName; - bool IsEncrypted; - - UInt64 GetTotalFilesAndDirs() const - { - UInt64 sum = 0; - FOR_VECTOR (i, Images) - sum += Images[i].GetTotalFilesAndDirs(); - return sum; - } - - void ToUnicode(UString &s); - bool Parse(); - - CWimXml(): IsEncrypted(false) {} -}; - - -struct CVolume -{ - CHeader Header; - CMyComPtr Stream; -}; - - -class CDatabase -{ - Byte *DirData; - size_t DirSize; - size_t DirProcessed; - size_t DirStartOffset; - IArchiveOpenCallback *OpenCallback; - - HRESULT ParseDirItem(size_t pos, int parent); - HRESULT ParseImageDirs(CByteBuffer &buf, int parent); - -public: - CRecordVector DataStreams; - CRecordVector MetaStreams; - - CObjectVector Solids; - - CRecordVector Items; - CObjectVector ReparseItems; - CIntVector ItemToReparse; // from index_in_Items to index_in_ReparseItems - // -1 means no reparse; - - CObjectVector Images; - - bool IsOldVersion9; - bool IsOldVersion; - bool ThereAreDeletedStreams; - bool ThereAreAltStreams; - bool RefCountError; - bool HeadersError; - - bool GetStartImageIndex() const { return IsOldVersion9 ? 0 : 1; } - unsigned GetDirAlignMask() const { return IsOldVersion9 ? 3 : 7; } - - // User Items can contain all images or just one image from all. - CUIntVector SortedItems; - int IndexOfUserImage; // -1 : if more than one images was filled to Sorted Items - - unsigned NumExcludededItems; - int ExludedItem; // -1 : if there are no exclude items - CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives - - bool ThereIsError() const { return RefCountError; } - - unsigned GetNumUserItemsInImage(unsigned imageIndex) const - { - if (IndexOfUserImage >= 0 && imageIndex != (unsigned)IndexOfUserImage) - return 0; - if (imageIndex >= Images.Size()) - return 0; - return Images[imageIndex].NumItems - NumExcludededItems; - } - - bool ItemHasStream(const CItem &item) const; - - UInt64 Get_UnpackSize_of_Resource(const CResource &r) const - { - if (!r.IsSolid()) - return r.UnpackSize; - if (r.IsSolidSmall()) - return r.PackSize; - if (r.IsSolidBig() && r.SolidIndex >= 0) - return Solids[(unsigned)r.SolidIndex].UnpackSize; - return 0; - } - - UInt64 Get_PackSize_of_Resource(unsigned streamIndex) const - { - const CResource &r = DataStreams[streamIndex].Resource; - if (!r.IsSolidSmall()) - return r.PackSize; - if (r.SolidIndex >= 0) - { - const CSolid &ss = Solids[(unsigned)r.SolidIndex]; - if (ss.FirstSmallStream == (int)streamIndex) - return DataStreams[ss.StreamIndex].Resource.PackSize; - } - return 0; - } - - UInt64 GetUnpackSize() const - { - UInt64 res = 0; - FOR_VECTOR (i, DataStreams) - res += DataStreams[i].Resource.UnpackSize; - return res; - } - - UInt64 GetPackSize() const - { - UInt64 res = 0; - FOR_VECTOR (i, DataStreams) - res += DataStreams[i].Resource.PackSize; - return res; - } - - void Clear() - { - DataStreams.Clear(); - MetaStreams.Clear(); - Solids.Clear(); - - Items.Clear(); - ReparseItems.Clear(); - ItemToReparse.Clear(); - - SortedItems.Clear(); - - Images.Clear(); - VirtualRoots.Clear(); - - IsOldVersion = false; - ThereAreDeletedStreams = false; - ThereAreAltStreams = false; - RefCountError = false; - HeadersError = false; - } - - CDatabase(): RefCountError(false) {} - - void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const; - void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const; - void GetItemPath(unsigned index, bool showImageNumber, NWindows::NCOM::CPropVariant &res) const; - - HRESULT OpenXml(IInStream *inStream, const CHeader &h, CByteBuffer &xml); - HRESULT Open(IInStream *inStream, const CHeader &h, unsigned numItemsReserve, IArchiveOpenCallback *openCallback); - HRESULT FillAndCheck(const CObjectVector &volumes); - - /* - imageIndex showImageNumber NumImages - * true * Show Image_Number - -1 * >1 Show Image_Number - -1 false 1 Don't show Image_Number - N false * Don't show Image_Number - */ - HRESULT GenerateSortedItems(int imageIndex, bool showImageNumber); - - HRESULT ExtractReparseStreams(const CObjectVector &volumes, IArchiveOpenCallback *openCallback); -}; - -HRESULT ReadHeader(IInStream *inStream, CHeader &header, UInt64 &phySize); - - -struct CMidBuf -{ - Byte *Data; - size_t _size; - - CMidBuf(): Data(NULL), _size(0) {} - - void EnsureCapacity(size_t size) - { - if (size > _size) - { - ::MidFree(Data); - _size = 0; - Data = (Byte *)::MidAlloc(size); - if (Data) - _size = size; - } - } - - ~CMidBuf() { ::MidFree(Data); } -}; - - -class CUnpacker -{ - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr copyCoder; - - NCompress::NLzx::CDecoder *lzxDecoderSpec; - CMyComPtr lzxDecoder; - - NCompress::NLzms::CDecoder *lzmsDecoder; - - CByteBuffer sizesBuf; - - CMidBuf packBuf; - CMidBuf unpackBuf; - - // solid resource - int _solidIndex; - size_t _unpackedChunkIndex; - - HRESULT UnpackChunk( - ISequentialInStream *inStream, - unsigned method, unsigned chunkSizeBits, - size_t inSize, size_t outSize, - ISequentialOutStream *outStream); - - HRESULT Unpack2( - IInStream *inStream, - const CResource &res, - const CHeader &header, - const CDatabase *db, - ISequentialOutStream *outStream, - ICompressProgressInfo *progress); - -public: - UInt64 TotalPacked; - - CUnpacker(): - lzmsDecoder(NULL), - _solidIndex(-1), - _unpackedChunkIndex(0), - TotalPacked(0) - {} - ~CUnpacker(); - - HRESULT Unpack( - IInStream *inStream, - const CResource &res, - const CHeader &header, - const CDatabase *db, - ISequentialOutStream *outStream, - ICompressProgressInfo *progress, - Byte *digest); - - HRESULT UnpackData(IInStream *inStream, - const CResource &resource, const CHeader &header, - const CDatabase *db, - CByteBuffer &buf, Byte *digest); -}; - -}} - -#endif +// Archive/WimIn.h + +#ifndef ZIP7_INC_ARCHIVE_WIM_IN_H +#define ZIP7_INC_ARCHIVE_WIM_IN_H + +#include "../../../../C/Alloc.h" + +#include "../../../Common/AutoPtr.h" +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyXml.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../Compress/CopyCoder.h" +#include "../../Compress/LzmsDecoder.h" +#include "../../Compress/LzxDecoder.h" + +#include "../IArchive.h" + +namespace NArchive { +namespace NWim { + +/* +WIM versions: +hexVer : headerSize : ver + : 1.07.01 - 1.08.01 : Longhorn.4001-4015 - another header, no signature, CAB compression +10900 : 60 : 1.09 : Longhorn.4029-4039 (2003) +10A00 : 60 : 1.10 : Longhorn.4083 (2004) image starting from 1 +10B00 : ?? : 1.11 : ?? +10C00 : 74 : 1.12 : Longhorn.4093 - VistaBeta1.5112 (2005) - (Multi-Part, SHA1) +10D00 : D0 : 1.13 : VistaBeta2 - Win10, (NumImages, BootIndex, IntegrityResource) +00E00 : D0 : 0.14 : LZMS, solid, esd, dism +*/ + +const unsigned kDirRecordSizeOld = 62; +const unsigned kDirRecordSize = 102; + +/* + There is error in WIM specification about dwReparseTag, dwReparseReserved and liHardLink fields. + + Correct DIRENTRY structure: + { + hex offset + 0 UInt64 Len; + 8 UInt32 Attrib; + C UInt32 SecurityId; + + 10 UInt64 SubdirOffset; // = 0 for files + + 18 UInt64 unused1; // = 0? + 20 UInt64 unused2; // = 0? + + 28 UInt64 CTime; + 30 UInt64 ATime; + 38 UInt64 MTime; + + 40 Byte Sha1[20]; + + 54 UInt32 Unknown1; // is it 0 always? + + + union + { + 58 UInt64 NtNodeId; + { + 58 UInt32 ReparseTag; + 5C UInt32 ReparseFlags; // is it 0 always? Check with new imagex. + } + } + + 60 UInt16 Streams; + + 62 UInt16 ShortNameLen; + 64 UInt16 FileNameLen; + + 66 UInt16 Name[]; + UInt16 ShortName[]; + } + + // DIRENTRY for WIM_VERSION <= 1.10 + DIRENTRY_OLD structure: + { + hex offset + 0 UInt64 Len; + 8 UInt32 Attrib; + C UInt32 SecurityId; + + union + { + 10 UInt64 SubdirOffset; // + + 10 UInt32 OldWimFileId; // used for files in old WIMs + 14 UInt32 OldWimFileId_Reserved; // = 0 + } + + 18 UInt64 CTime; + 20 UInt64 ATime; + 28 UInt64 MTime; + + 30 UInt64 Unknown; // NtNodeId ? + + 38 UInt16 Streams; + 3A UInt16 ShortNameLen; + 3C UInt16 FileNameLen; + 3E UInt16 FileName[]; + UInt16 ShortName[]; + } + + ALT_STREAM structure: + { + hex offset + 0 UInt64 Len; + 8 UInt64 Unused; + 10 Byte Sha1[20]; + 24 UInt16 FileNameLen; + 26 UInt16 FileName[]; + } + + ALT_STREAM_OLD structure: + { + hex offset + 0 UInt64 Len; + 8 UInt64 StreamId; // 32-bit value + 10 UInt16 FileNameLen; + 12 UInt16 FileName[]; + } + + If item is file (not Directory) and there are alternative streams, + there is additional ALT_STREAM item of main "unnamed" stream in Streams array. + +*/ + + +namespace NResourceFlags +{ + // const Byte kFree = 1 << 0; + const Byte kMetadata = 1 << 1; + const Byte kCompressed = 1 << 2; + // const Byte kSpanned = 1 << 3; + const Byte kSolid = 1 << 4; +} + +const UInt64 k_SolidBig_Resource_Marker = (UInt64)1 << 32; + +struct CResource +{ + UInt64 PackSize; + UInt64 Offset; + UInt64 UnpackSize; + Byte Flags; + bool KeepSolid; + int SolidIndex; + + void Clear() + { + PackSize = 0; + Offset = 0; + UnpackSize = 0; + Flags = 0; + KeepSolid = false; + SolidIndex = -1; + } + + UInt64 GetEndLimit() const { return Offset + PackSize; } + void Parse(const Byte *p); + void ParseAndUpdatePhySize(const Byte *p, UInt64 &phySize) + { + Parse(p); + UInt64 v = GetEndLimit(); + if (phySize < v) + phySize = v; + } + + void WriteTo(Byte *p) const; + + bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; } + bool IsCompressed() const { return (Flags & NResourceFlags::kCompressed) != 0; } + bool IsSolid() const { return (Flags & NResourceFlags::kSolid) != 0; } + bool IsSolidBig() const { return IsSolid() && UnpackSize == k_SolidBig_Resource_Marker; } + bool IsSolidSmall() const { return IsSolid() && UnpackSize == 0; } + + bool IsEmpty() const { return (UnpackSize == 0); } +}; + + +struct CSolid +{ + unsigned StreamIndex; + // unsigned NumRefs; + int FirstSmallStream; + + UInt64 SolidOffset; + + UInt64 UnpackSize; + int Method; + unsigned ChunkSizeBits; + + UInt64 HeadersSize; + // size_t NumChunks; + CObjArray Chunks; // [NumChunks + 1] (start offset) + + UInt64 GetChunkPackSize(size_t chunkIndex) const { return Chunks[chunkIndex + 1] - Chunks[chunkIndex]; } + + CSolid(): + FirstSmallStream(-1), + // NumRefs(0), + Method(-1) + {} +}; + + +namespace NHeaderFlags +{ + const UInt32 kCompression = 1 << 1; + const UInt32 kReadOnly = 1 << 2; + const UInt32 kSpanned = 1 << 3; + const UInt32 kResourceOnly = 1 << 4; + const UInt32 kMetadataOnly = 1 << 5; + const UInt32 kWriteInProgress = 1 << 6; + const UInt32 kReparsePointFixup = 1 << 7; + + const UInt32 kXPRESS = (UInt32)1 << 17; + const UInt32 kLZX = (UInt32)1 << 18; + const UInt32 kLZMS = (UInt32)1 << 19; + const UInt32 kXPRESS2 = (UInt32)1 << 21; // XPRESS with nonstandard chunk size ? + + const UInt32 kMethodMask = 0xFFFE0000; +} + + +namespace NMethod +{ + const UInt32 kXPRESS = 1; + const UInt32 kLZX = 2; + const UInt32 kLZMS = 3; +} + + +const UInt32 k_Version_NonSolid = 0x10D00; +const UInt32 k_Version_Solid = 0xE00; + +const unsigned kHeaderSizeMax = 0xD0; +const unsigned kSignatureSize = 8; +extern const Byte kSignature[kSignatureSize]; + +const unsigned kChunkSizeBits = 15; +const UInt32 kChunkSize = (UInt32)1 << kChunkSizeBits; + + +struct CHeader +{ + UInt32 Version; + UInt32 Flags; + UInt32 ChunkSize; + unsigned ChunkSizeBits; + Byte Guid[16]; + UInt16 PartNumber; + UInt16 NumParts; + UInt32 NumImages; + UInt32 BootIndex; + + bool _isOldVersion; // 1.10- + bool _isNewVersion; // 1.13+ or 0.14 + + CResource OffsetResource; + CResource XmlResource; + CResource MetadataResource; + CResource IntegrityResource; + + void SetDefaultFields(bool useLZX); + + void WriteTo(Byte *p) const; + HRESULT Parse(const Byte *p, UInt64 &phySize); + + bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; } + + bool IsSupported() const + { + return (!IsCompressed() + || (Flags & NHeaderFlags::kLZX) != 0 + || (Flags & NHeaderFlags::kXPRESS) != 0 + || (Flags & NHeaderFlags::kLZMS) != 0 + || (Flags & NHeaderFlags::kXPRESS2) != 0); + } + + unsigned GetMethod() const + { + if (!IsCompressed()) + return 0; + UInt32 mask = (Flags & NHeaderFlags::kMethodMask); + if (mask == 0) return 0; + if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS; + if (mask == NHeaderFlags::kLZX) return NMethod::kLZX; + if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS; + if (mask == NHeaderFlags::kXPRESS2) return NMethod::kXPRESS; + return mask; + } + + bool IsOldVersion() const { return _isOldVersion; } + bool IsNewVersion() const { return _isNewVersion; } + bool IsSolidVersion() const { return (Version == k_Version_Solid); } + + bool AreFromOnArchive(const CHeader &h) + { + return (memcmp(Guid, h.Guid, sizeof(Guid)) == 0) && (h.NumParts == NumParts); + } +}; + + +const unsigned kHashSize = 20; + +inline bool IsEmptySha(const Byte *data) +{ + for (unsigned i = 0; i < kHashSize; i++) + if (data[i] != 0) + return false; + return true; +} + +const unsigned kStreamInfoSize = 24 + 2 + 4 + kHashSize; + +struct CStreamInfo +{ + CResource Resource; + UInt16 PartNumber; // for NEW WIM format, we set it to 1 for OLD WIM format + UInt32 RefCount; + UInt32 Id; // for OLD WIM format + Byte Hash[kHashSize]; + + bool IsEmptyHash() const { return IsEmptySha(Hash); } + + void WriteTo(Byte *p) const; +}; + + +struct CItem +{ + size_t Offset; + int IndexInSorted; + int StreamIndex; + int Parent; + int ImageIndex; // -1 means that file is unreferenced in Images (deleted item?) + bool IsDir; + bool IsAltStream; + + bool HasMetadata() const { return ImageIndex >= 0; } + + CItem(): + IndexInSorted(-1), + StreamIndex(-1), + Parent(-1), + IsDir(false), + IsAltStream(false) + {} +}; + +struct CImage +{ + CByteBuffer Meta; + CRecordVector SecurOffsets; + unsigned StartItem; + unsigned NumItems; + unsigned NumEmptyRootItems; + int VirtualRootIndex; // index in CDatabase::VirtualRoots[] + UString RootName; + CByteBuffer RootNameBuf; + + CImage(): VirtualRootIndex(-1) {} +}; + + +struct CImageInfo +{ + bool CTimeDefined; + bool MTimeDefined; + bool NameDefined; + bool IndexDefined; + + FILETIME CTime; + FILETIME MTime; + UString Name; + + UInt64 DirCount; + UInt64 FileCount; + UInt32 Index; + + int ItemIndexInXml; + + UInt64 GetTotalFilesAndDirs() const { return DirCount + FileCount; } + + CImageInfo(): CTimeDefined(false), MTimeDefined(false), NameDefined(false), + IndexDefined(false), ItemIndexInXml(-1) {} + void Parse(const CXmlItem &item); +}; + + +struct CWimXml +{ + CByteBuffer Data; + CXml Xml; + + UInt16 VolIndex; + CObjectVector Images; + + UString FileName; + bool IsEncrypted; + + UInt64 GetTotalFilesAndDirs() const + { + UInt64 sum = 0; + FOR_VECTOR (i, Images) + sum += Images[i].GetTotalFilesAndDirs(); + return sum; + } + + void ToUnicode(UString &s); + bool Parse(); + + CWimXml(): IsEncrypted(false) {} +}; + + +struct CVolume +{ + CHeader Header; + CMyComPtr Stream; +}; + + +class CDatabase +{ + Byte *DirData; + size_t DirSize; + size_t DirProcessed; + size_t DirStartOffset; + IArchiveOpenCallback *OpenCallback; + + HRESULT ParseDirItem(size_t pos, int parent); + HRESULT ParseImageDirs(CByteBuffer &buf, int parent); + +public: + CRecordVector DataStreams; + CRecordVector MetaStreams; + + CObjectVector Solids; + + CRecordVector Items; + CObjectVector ReparseItems; + CIntVector ItemToReparse; // from index_in_Items to index_in_ReparseItems + // -1 means no reparse; + + CObjectVector Images; + + bool IsOldVersion9; + bool IsOldVersion; + bool ThereAreDeletedStreams; + bool ThereAreAltStreams; + bool RefCountError; + bool HeadersError; + + unsigned GetStartImageIndex() const { return IsOldVersion9 ? 0 : 1; } + unsigned GetDirAlignMask() const { return IsOldVersion9 ? 3 : 7; } + + // User Items can contain all images or just one image from all. + CUIntVector SortedItems; + int IndexOfUserImage; // -1 : if more than one images was filled to Sorted Items + + unsigned NumExcludededItems; + int ExludedItem; // -1 : if there are no exclude items + CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives + + bool ThereIsError() const { return RefCountError || HeadersError; } + + unsigned GetNumUserItemsInImage(unsigned imageIndex) const + { + if (IndexOfUserImage >= 0 && imageIndex != (unsigned)IndexOfUserImage) + return 0; + if (imageIndex >= Images.Size()) + return 0; + return Images[imageIndex].NumItems - NumExcludededItems; + } + + bool ItemHasStream(const CItem &item) const; + + UInt64 Get_UnpackSize_of_Resource(const CResource &r) const + { + if (!r.IsSolid()) + return r.UnpackSize; + if (r.IsSolidSmall()) + return r.PackSize; + if (r.IsSolidBig() && r.SolidIndex >= 0) + return Solids[(unsigned)r.SolidIndex].UnpackSize; + return 0; + } + + UInt64 Get_PackSize_of_Resource(unsigned streamIndex) const + { + const CResource &r = DataStreams[streamIndex].Resource; + if (!r.IsSolidSmall()) + return r.PackSize; + if (r.SolidIndex >= 0) + { + const CSolid &ss = Solids[(unsigned)r.SolidIndex]; + if (ss.FirstSmallStream == (int)streamIndex) + return DataStreams[ss.StreamIndex].Resource.PackSize; + } + return 0; + } + + UInt64 GetUnpackSize() const + { + UInt64 res = 0; + FOR_VECTOR (i, DataStreams) + res += DataStreams[i].Resource.UnpackSize; + return res; + } + + UInt64 GetPackSize() const + { + UInt64 res = 0; + FOR_VECTOR (i, DataStreams) + res += DataStreams[i].Resource.PackSize; + return res; + } + + void Clear() + { + DataStreams.Clear(); + MetaStreams.Clear(); + Solids.Clear(); + + Items.Clear(); + ReparseItems.Clear(); + ItemToReparse.Clear(); + + SortedItems.Clear(); + + Images.Clear(); + VirtualRoots.Clear(); + + IsOldVersion = false; + ThereAreDeletedStreams = false; + ThereAreAltStreams = false; + RefCountError = false; + HeadersError = false; + } + + CDatabase(): + RefCountError(false), + HeadersError(false) + {} + + void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const; + void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const; + void GetItemPath(unsigned index, bool showImageNumber, NWindows::NCOM::CPropVariant &res) const; + + HRESULT OpenXml(IInStream *inStream, const CHeader &h, CByteBuffer &xml); + HRESULT Open(IInStream *inStream, const CHeader &h, unsigned numItemsReserve, IArchiveOpenCallback *openCallback); + HRESULT FillAndCheck(const CObjectVector &volumes); + + /* + imageIndex showImageNumber NumImages + * true * Show Image_Number + -1 * >1 Show Image_Number + -1 false 1 Don't show Image_Number + N false * Don't show Image_Number + */ + HRESULT GenerateSortedItems(int imageIndex, bool showImageNumber); + + HRESULT ExtractReparseStreams(const CObjectVector &volumes, IArchiveOpenCallback *openCallback); +}; + +HRESULT ReadHeader(IInStream *inStream, CHeader &header, UInt64 &phySize); + + +struct CMidBuf +{ + Byte *Data; + size_t _size; + + CMidBuf(): Data(NULL), _size(0) {} + + void EnsureCapacity(size_t size) + { + if (size > _size) + { + ::z7_AlignedFree(Data); + _size = 0; + Data = (Byte *)::z7_AlignedAlloc(size); + if (Data) + _size = size; + } + } + + ~CMidBuf() { ::z7_AlignedFree(Data); } +}; + + +class CUnpacker +{ + CMyComPtr2 copyCoder; + CMyUniquePtr lzxDecoder; + CMyUniquePtr lzmsDecoder; + + CByteBuffer sizesBuf; + + CMidBuf packBuf; + CMidBuf unpackBuf; + + // solid resource + int _solidIndex; + size_t _unpackedChunkIndex; + + HRESULT UnpackChunk( + ISequentialInStream *inStream, + unsigned method, unsigned chunkSizeBits, + size_t inSize, size_t outSize, + ISequentialOutStream *outStream); + + HRESULT Unpack2( + IInStream *inStream, + const CResource &res, + const CHeader &header, + const CDatabase *db, + ISequentialOutStream *outStream, + ICompressProgressInfo *progress); + +public: + UInt64 TotalPacked; + + CUnpacker(): + lzmsDecoder(NULL), + _solidIndex(-1), + _unpackedChunkIndex(0), + TotalPacked(0) + {} + + HRESULT Unpack( + IInStream *inStream, + const CResource &res, + const CHeader &header, + const CDatabase *db, + ISequentialOutStream *outStream, + ICompressProgressInfo *progress, + Byte *digest); + + HRESULT UnpackData(IInStream *inStream, + const CResource &resource, const CHeader &header, + const CDatabase *db, + CByteBuffer &buf, Byte *digest); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Wim/WimRegister.cpp 2015-09-17 19:02:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Wim/WimRegister.cpp 2022-05-04 11:00:00.000000000 +0000 @@ -1,22 +1,29 @@ -// WimRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "WimHandler.h" - -namespace NArchive { -namespace NWim { - -REGISTER_ARC_IO( - "wim", "wim swm esd", 0, 0xE6, - kSignature, - 0, - NArcInfoFlags::kAltStreams | - NArcInfoFlags::kNtSecure | - NArcInfoFlags::kSymLinks | - NArcInfoFlags::kHardLinks - , NULL) - -}} +// WimRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "WimHandler.h" + +namespace NArchive { +namespace NWim { + +REGISTER_ARC_IO( + "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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/XarHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XarHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/XarHandler.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XarHandler.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,732 +1,1316 @@ -// XarHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyLinux.h" -#include "../../Common/MyXml.h" -#include "../../Common/StringToInt.h" -#include "../../Common/UTFConvert.h" - -#include "../../Windows/PropVariant.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/BZip2Decoder.h" -#include "../Compress/CopyCoder.h" -#include "../Compress/ZlibDecoder.h" - -#include "Common/OutStreamWithSha1.h" - -using namespace NWindows; - -#define XAR_SHOW_RAW - -#define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) -#define Get64(p) GetBe64(p) - -namespace NArchive { -namespace NXar { - -static const size_t kXmlSizeMax = ((size_t )1 << 30) - (1 << 14); -static const size_t kXmlPackSizeMax = kXmlSizeMax; - -/* -#define XAR_CKSUM_NONE 0 -#define XAR_CKSUM_SHA1 1 -#define XAR_CKSUM_MD5 2 - -static const char * const k_ChecksumAlgos[] = -{ - "None" - , "SHA-1" - , "MD5" -}; -*/ - -#define METHOD_NAME_ZLIB "zlib" - - -struct CFile -{ - AString Name; - AString Method; - UInt64 Size; - UInt64 PackSize; - UInt64 Offset; - - UInt64 CTime; - UInt64 MTime; - UInt64 ATime; - UInt32 Mode; - - AString User; - AString Group; - - bool IsDir; - bool HasData; - bool ModeDefined; - bool Sha1IsDefined; - // bool packSha1IsDefined; - - Byte Sha1[SHA1_DIGEST_SIZE]; - // Byte packSha1[SHA1_DIGEST_SIZE]; - - int Parent; - - CFile(): IsDir(false), HasData(false), ModeDefined(false), Sha1IsDefined(false), - /* packSha1IsDefined(false), */ - Parent(-1), - Size(0), PackSize(0), Offset(0), - CTime(0), MTime(0), ATime(0), Mode(0) {} - - bool IsCopyMethod() const - { - return Method.IsEmpty() || Method == "octet-stream"; - } - - void UpdateTotalPackSize(UInt64 &totalSize) const - { - UInt64 t = Offset + PackSize; - if (totalSize < t) - totalSize = t; - } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ - UInt64 _dataStartPos; - CMyComPtr _inStream; - CByteArr _xml; - size_t _xmlLen; - CObjectVector _files; - // UInt32 _checkSumAlgo; - UInt64 _phySize; - Int32 _mainSubfile; - bool _is_pkg; - - HRESULT Open2(IInStream *stream); - HRESULT Extract(IInStream *stream); -public: - MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); -}; - -static const Byte kArcProps[] = -{ - kpidSubType, - kpidHeadersSize -}; - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidPosixAttrib, - kpidUser, - kpidGroup, - kpidMethod -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -#define PARSE_NUM(_num_, _dest_) \ - { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ - if ((unsigned)(end - p) != _num_) return 0; p += _num_ + 1; } - -static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) -{ - const AString s = item.GetSubStringForTag(name); - if (s.IsEmpty()) - return false; - const char *end; - res = ConvertStringToUInt64(s, &end); - return *end == 0; -} - -static UInt64 ParseTime(const CXmlItem &item, const char *name) -{ - const AString s = item.GetSubStringForTag(name); - if (s.Len() < 20) - return 0; - const char *p = s; - if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || - p[13] != ':' || p[16] != ':' || p[19] != 'Z') - return 0; - UInt32 year, month, day, hour, min, sec; - PARSE_NUM(4, year) - PARSE_NUM(2, month) - PARSE_NUM(2, day) - PARSE_NUM(2, hour) - PARSE_NUM(2, min) - PARSE_NUM(2, sec) - - UInt64 numSecs; - if (!NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) - return 0; - return numSecs * 10000000; -} - -static int HexToByte(unsigned char c) -{ - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - return -1; -} - -static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) -{ - int index = item.FindSubTag(name); - if (index < 0) - return false; - const CXmlItem &checkItem = item.SubItems[index]; - const AString style = checkItem.GetPropVal("style"); - if (style == "SHA1") - { - const AString s = checkItem.GetSubString(); - if (s.Len() != SHA1_DIGEST_SIZE * 2) - return false; - for (unsigned i = 0; i < s.Len(); i += 2) - { - int b0 = HexToByte(s[i]); - int b1 = HexToByte(s[i + 1]); - if (b0 < 0 || b1 < 0) - return false; - digest[i / 2] = (Byte)((b0 << 4) | b1); - } - return true; - } - return false; -} - -static bool AddItem(const CXmlItem &item, CObjectVector &files, int parent) -{ - if (!item.IsTag) - return true; - if (item.Name == "file") - { - CFile file; - file.Parent = parent; - parent = files.Size(); - file.Name = item.GetSubStringForTag("name"); - AString type = item.GetSubStringForTag("type"); - if (type == "directory") - file.IsDir = true; - else if (type == "file") - file.IsDir = false; - else - return false; - - int dataIndex = item.FindSubTag("data"); - if (dataIndex >= 0 && !file.IsDir) - { - file.HasData = true; - const CXmlItem &dataItem = item.SubItems[dataIndex]; - if (!ParseUInt64(dataItem, "size", file.Size)) - return false; - if (!ParseUInt64(dataItem, "length", file.PackSize)) - return false; - if (!ParseUInt64(dataItem, "offset", file.Offset)) - return false; - file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); - // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); - int encodingIndex = dataItem.FindSubTag("encoding"); - if (encodingIndex >= 0) - { - const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; - if (encodingItem.IsTag) - { - AString s = encodingItem.GetPropVal("style"); - if (s.Len() >= 0) - { - AString appl = "application/"; - if (s.IsPrefixedBy(appl)) - { - s.DeleteFrontal(appl.Len()); - AString xx = "x-"; - if (s.IsPrefixedBy(xx)) - { - s.DeleteFrontal(xx.Len()); - if (s == "gzip") - s = METHOD_NAME_ZLIB; - } - } - file.Method = s; - } - } - } - } - - file.CTime = ParseTime(item, "ctime"); - file.MTime = ParseTime(item, "mtime"); - file.ATime = ParseTime(item, "atime"); - - { - const AString s = item.GetSubStringForTag("mode"); - if (s[0] == '0') - { - const char *end; - file.Mode = ConvertOctStringToUInt32(s, &end); - file.ModeDefined = (*end == 0); - } - } - - file.User = item.GetSubStringForTag("user"); - file.Group = item.GetSubStringForTag("group"); - - files.Add(file); - } - FOR_VECTOR (i, item.SubItems) - if (!AddItem(item.SubItems[i], files, parent)) - return false; - return true; -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - const UInt32 kHeaderSize = 0x1C; - Byte buf[kHeaderSize]; - RINOK(ReadStream_FALSE(stream, buf, kHeaderSize)); - - UInt32 size = Get16(buf + 4); - // UInt32 ver = Get16(buf + 6); // == 1 - if (Get32(buf) != 0x78617221 || size != kHeaderSize) - return S_FALSE; - - UInt64 packSize = Get64(buf + 8); - UInt64 unpackSize = Get64(buf + 0x10); - - // _checkSumAlgo = Get32(buf + 0x18); - - if (packSize >= kXmlPackSizeMax || - unpackSize >= kXmlSizeMax) - return S_FALSE; - - _dataStartPos = kHeaderSize + packSize; - _phySize = _dataStartPos; - - _xml.Alloc((size_t)unpackSize + 1); - _xmlLen = (size_t)unpackSize; - - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream; - CMyComPtr inStreamLim(inStreamLimSpec); - inStreamLimSpec->SetStream(stream); - inStreamLimSpec->Init(packSize); - - CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream; - CMyComPtr outStreamLim(outStreamLimSpec); - outStreamLimSpec->Init(_xml, (size_t)unpackSize); - - RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL)); - - if (outStreamLimSpec->GetPos() != (size_t)unpackSize) - return S_FALSE; - - _xml[(size_t)unpackSize] = 0; - if (strlen((const char *)(const Byte *)_xml) != unpackSize) return S_FALSE; - - CXml xml; - if (!xml.Parse((const char *)(const Byte *)_xml)) - return S_FALSE; - - if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1) - return S_FALSE; - const CXmlItem &toc = xml.Root.SubItems[0]; - if (!toc.IsTagged("toc")) - return S_FALSE; - if (!AddItem(toc, _files, -1)) - return S_FALSE; - - UInt64 totalPackSize = 0; - unsigned numMainFiles = 0; - - FOR_VECTOR (i, _files) - { - const CFile &file = _files[i]; - file.UpdateTotalPackSize(totalPackSize); - if (file.Name == "Payload") - { - _mainSubfile = i; - numMainFiles++; - } - if (file.Name == "PackageInfo") - _is_pkg = true; - } - - if (numMainFiles > 1) - _mainSubfile = -1; - - _phySize = _dataStartPos + totalPackSize; - - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - { - Close(); - if (Open2(stream) != S_OK) - return S_FALSE; - _inStream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _phySize = 0; - _inStream.Release(); - _files.Clear(); - _xmlLen = 0; - _xml.Free(); - _mainSubfile = -1; - _is_pkg = false; - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _files.Size() - #ifdef XAR_SHOW_RAW - + 1 - #endif - ; - return S_OK; -} - -static void TimeToProp(UInt64 t, NCOM::CPropVariant &prop) -{ - if (t != 0) - { - FILETIME ft; - ft.dwLowDateTime = (UInt32)(t); - ft.dwHighDateTime = (UInt32)(t >> 32); - prop = ft; - } -} - -static void Utf8StringToProp(const AString &s, NCOM::CPropVariant &prop) -{ - if (!s.IsEmpty()) - { - UString us; - if (ConvertUTF8ToUnicode(s, us)) - prop = us; - } -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidHeadersSize: prop = _dataStartPos; break; - case kpidPhySize: prop = _phySize; break; - case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; - case kpidSubType: if (_is_pkg) prop = "pkg"; break; - case kpidExtension: prop = _is_pkg ? "pkg" : "xar"; 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; - - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) - { - switch (propID) - { - case kpidPath: prop = "[TOC].xml"; break; - case kpidSize: - case kpidPackSize: prop = (UInt64)_xmlLen; break; - } - } - else - #endif - { - const CFile &item = _files[index]; - switch (propID) - { - case kpidMethod: Utf8StringToProp(item.Method, prop); break; - - case kpidPath: - { - AString path; - int cur = index; - do - { - const CFile &item2 = _files[cur]; - if (!path.IsEmpty()) - path.InsertAtFront(CHAR_PATH_SEPARATOR); - if (item2.Name.IsEmpty()) - path.Insert(0, "unknown"); - else - path.Insert(0, item2.Name); - cur = item2.Parent; - } - while (cur >= 0); - - Utf8StringToProp(path, prop); - break; - } - - case kpidIsDir: prop = item.IsDir; break; - case kpidSize: if (!item.IsDir) prop = item.Size; break; - case kpidPackSize: if (!item.IsDir) prop = item.PackSize; break; - - case kpidMTime: TimeToProp(item.MTime, prop); break; - case kpidCTime: TimeToProp(item.CTime, prop); break; - case kpidATime: TimeToProp(item.ATime, prop); break; - case kpidPosixAttrib: - if (item.ModeDefined) - { - UInt32 mode = item.Mode; - if ((mode & MY_LIN_S_IFMT) == 0) - mode |= (item.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG); - prop = mode; - } - break; - case kpidUser: Utf8StringToProp(item.User, prop); break; - case kpidGroup: Utf8StringToProp(item.Group, prop); break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _files.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - UInt32 index = (allFilesMode ? i : indices[i]); - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) - totalSize += _xmlLen; - else - #endif - totalSize += _files[index].Size; - } - extractCallback->SetTotal(totalSize); - - UInt64 currentPackTotal = 0; - UInt64 currentUnpTotal = 0; - UInt64 currentPackSize = 0; - UInt64 currentUnpSize = 0; - - const UInt32 kZeroBufSize = (1 << 14); - CByteBuffer zeroBuf(kZeroBufSize); - memset(zeroBuf, 0, kZeroBufSize); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder(); - CMyComPtr zlibCoder = zlibCoderSpec; - - NCompress::NBZip2::CDecoder *bzip2CoderSpec = new NCompress::NBZip2::CDecoder(); - CMyComPtr bzip2Coder = bzip2CoderSpec; - - NCompress::NDeflate::NDecoder::CCOMCoder *deflateCoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder(); - CMyComPtr deflateCoder = deflateCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(inStreamSpec); - inStreamSpec->SetStream(_inStream); - - - CLimitedSequentialOutStream *outStreamLimSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamLimSpec); - - COutStreamWithSha1 *outStreamSha1Spec = new COutStreamWithSha1; - { - CMyComPtr outStreamSha1(outStreamSha1Spec); - outStreamLimSpec->SetStream(outStreamSha1); - } - - for (i = 0; i < numItems; i++, currentPackTotal += currentPackSize, currentUnpTotal += currentUnpSize) - { - lps->InSize = currentPackTotal; - lps->OutSize = currentUnpTotal; - currentPackSize = 0; - currentUnpSize = 0; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (index < _files.Size()) - { - const CFile &item = _files[index]; - if (item.IsDir) - { - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - } - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSha1Spec->SetStream(realOutStream); - realOutStream.Release(); - - Int32 opRes = NExtract::NOperationResult::kOK; - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) - { - outStreamSha1Spec->Init(false); - outStreamLimSpec->Init(_xmlLen); - RINOK(WriteStream(outStream, _xml, _xmlLen)); - currentPackSize = currentUnpSize = _xmlLen; - } - else - #endif - { - const CFile &item = _files[index]; - if (item.HasData) - { - currentPackSize = item.PackSize; - currentUnpSize = item.Size; - - RINOK(_inStream->Seek(_dataStartPos + item.Offset, STREAM_SEEK_SET, NULL)); - inStreamSpec->Init(item.PackSize); - outStreamSha1Spec->Init(item.Sha1IsDefined); - outStreamLimSpec->Init(item.Size); - HRESULT res = S_OK; - - ICompressCoder *coder = NULL; - if (item.IsCopyMethod()) - if (item.PackSize == item.Size) - coder = copyCoder; - else - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (item.Method == METHOD_NAME_ZLIB) - coder = zlibCoder; - else if (item.Method == "bzip2") - coder = bzip2Coder; - else - opRes = NExtract::NOperationResult::kUnsupportedMethod; - - if (coder) - res = coder->Code(inStream, outStream, NULL, NULL, progress); - - if (res != S_OK) - { - if (!outStreamLimSpec->IsFinishedOK()) - opRes = NExtract::NOperationResult::kDataError; - else if (res != S_FALSE) - return res; - if (opRes == NExtract::NOperationResult::kOK) - opRes = NExtract::NOperationResult::kDataError; - } - - if (opRes == NExtract::NOperationResult::kOK) - { - if (outStreamLimSpec->IsFinishedOK() && - outStreamSha1Spec->GetSize() == item.Size) - { - if (!outStreamLimSpec->IsFinishedOK()) - { - opRes = NExtract::NOperationResult::kDataError; - } - else if (item.Sha1IsDefined) - { - Byte digest[SHA1_DIGEST_SIZE]; - outStreamSha1Spec->Final(digest); - if (memcmp(digest, item.Sha1, SHA1_DIGEST_SIZE) != 0) - opRes = NExtract::NOperationResult::kCRCError; - } - } - else - opRes = NExtract::NOperationResult::kDataError; - } - } - } - outStreamSha1Spec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - *stream = NULL; - COM_TRY_BEGIN - #ifdef XAR_SHOW_RAW - if (index == _files.Size()) - { - Create_BufInStream_WithNewBuffer(_xml, _xmlLen, stream); - return S_OK; - } - else - #endif - { - const CFile &item = _files[index]; - if (item.HasData && item.IsCopyMethod() && item.PackSize == item.Size) - return CreateLimitedInStream(_inStream, _dataStartPos + item.Offset, item.Size, stream); - } - return S_FALSE; - COM_TRY_END -} - -static const Byte k_Signature[] = { 'x', 'a', 'r', '!', 0, 0x1C }; - -REGISTER_ARC_I( - "Xar", "xar pkg", 0, 0xE1, - k_Signature, - 0, - 0, - NULL) - -}} +// XarHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/Sha256.h" +#include "../../../C/Sha512.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" +#include "../../Common/MyXml.h" +#include "../../Common/StringToInt.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariant.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/BZip2Decoder.h" +#include "../Compress/CopyCoder.h" +#include "../Compress/ZlibDecoder.h" + +#include "Common/OutStreamWithSha1.h" + +using namespace NWindows; + +#define XAR_SHOW_RAW + +#define Get16(p) GetBe16(p) +#define Get32(p) GetBe32(p) +#define Get64(p) GetBe64(p) + +namespace NArchive { +namespace NXar { + +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithSha256 + , ISequentialInStream +) + bool _sha512Mode; + CMyComPtr _stream; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; + UInt64 _size; + + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } +public: + CInStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void Init(bool sha512Mode) + { + _sha512Mode = sha512Mode; + _size = 0; + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); + } + void ReleaseStream() { _stream.Release(); } + UInt64 GetSize() const { return _size; } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } +}; + +Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _stream->Read(data, size, &realProcessedSize); + _size += realProcessedSize; + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, realProcessedSize); + else + Sha256_Update(Sha256(), (const Byte *)data, realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithSha256 + , ISequentialOutStream +) + bool _sha512Mode; + CMyComPtr _stream; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; + UInt64 _size; + + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } +public: + COutStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool sha512Mode) + { + _sha512Mode = sha512Mode; + _size = 0; + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); + } + UInt64 GetSize() const { return _size; } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } +}; + +Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + // if (_calculate) + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, size); + else + Sha256_Update(Sha256(), (const Byte *)data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +// we limit supported xml sizes: +// ((size_t)1 << (sizeof(size_t) / 2 + 28)) - (1u << 14); +static const size_t kXmlSizeMax = ((size_t)1 << 30) - (1u << 14); +static const size_t kXmlPackSizeMax = kXmlSizeMax; + +#define XAR_CKSUM_NONE 0 +#define XAR_CKSUM_SHA1 1 +#define XAR_CKSUM_MD5 2 +#define XAR_CKSUM_SHA256 3 +#define XAR_CKSUM_SHA512 4 +// #define XAR_CKSUM_OTHER 3 +// fork version of xar can use (3) as special case, +// where name of hash is stored as string at the end of header +// we do not support such hash still. + +static const char * const k_ChecksumNames[] = +{ + "NONE" + , "SHA1" + , "MD5" + , "SHA256" + , "SHA512" +}; + +static unsigned GetHashSize(int algo) +{ + if (algo <= XAR_CKSUM_NONE || algo > XAR_CKSUM_SHA512) + return 0; + if (algo == XAR_CKSUM_SHA1) + return SHA1_DIGEST_SIZE; + return (16u >> XAR_CKSUM_MD5) << algo; +} + +#define METHOD_NAME_ZLIB "zlib" + +static int Find_ChecksumId_for_Name(const AString &style) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ChecksumNames); i++) + { + // old xars used upper case in "style" + // new xars use lower case in "style" + if (style.IsEqualTo_Ascii_NoCase(k_ChecksumNames[i])) + return (int)i; + } + return -1; +} + + +struct CCheckSum +{ + int AlgoNumber; + bool Error; + CByteBuffer Data; + AString Style; + + CCheckSum(): AlgoNumber(-1), Error(false) {} + void AddNameToString(AString &s) const; +}; + +void CCheckSum::AddNameToString(AString &s) const +{ + if (Style.IsEmpty()) + s.Add_OptSpaced("NO-CHECKSUM"); + else + { + s.Add_OptSpaced(Style); + if (Error) + s += "-ERROR"; + } +} + + +struct CFile +{ + bool IsDir; + bool Is_SymLink; + bool HasData; + bool Mode_Defined; + bool INode_Defined; + bool UserId_Defined; + bool GroupId_Defined; + // bool Device_Defined; + bool Id_Defined; + + int Parent; + UInt32 Mode; + + UInt64 Size; + UInt64 PackSize; + UInt64 Offset; + UInt64 MTime; + UInt64 CTime; + UInt64 ATime; + UInt64 INode; + UInt64 UserId; + UInt64 GroupId; + // UInt64 Device; + + AString Name; + AString Method; + AString User; + AString Group; + // AString Id; + AString Type; + AString Link; + // AString LinkType; + // AString LinkFrom; + + UInt64 Id; + CCheckSum extracted_checksum; + CCheckSum archived_checksum; + + CFile(int parent): + IsDir(false), + Is_SymLink(false), + HasData(false), + Mode_Defined(false), + INode_Defined(false), + UserId_Defined(false), + GroupId_Defined(false), + // Device_Defined(false), + Id_Defined(false), + Parent(parent), + Mode(0), + Size(0), PackSize(0), Offset(0), + MTime(0), CTime(0), ATime(0), + INode(0) + {} + + bool IsCopyMethod() const + { + return Method.IsEmpty() || Method.IsEqualTo("octet-stream"); + } + + void UpdateTotalPackSize(UInt64 &totalSize) const + { + const UInt64 t = Offset + PackSize; + if (t >= Offset) + if (totalSize < t) + totalSize = t; + } +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_2( + IArchiveGetRawProps, + IInArchiveGetStream +) + bool _is_pkg; + bool _toc_CrcError; + CObjectVector _files; + CMyComPtr _inStream; + UInt64 _dataStartPos; + UInt64 _phySize; + CAlignedBuffer _xmlBuf; + size_t _xmlLen; + // UInt64 CreationTime; + AString CreationTime_String; + UInt32 _checkSumAlgo; + Int32 _mainSubfile; + + HRESULT Open2(IInStream *stream); +}; + + +static const Byte kArcProps[] = +{ + kpidSubType, + // kpidHeadersSize, + kpidMethod, + kpidCTime +}; + +// #define kpidLinkType 250 +// #define kpidLinkFrom 251 + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidPosixAttrib, + kpidType, + kpidUser, + kpidGroup, + kpidUserId, + kpidGroupId, + kpidINode, + // kpidDeviceMajor, + // kpidDeviceMinor, + kpidSymLink, + // kpidLinkType, + // kpidLinkFrom, + kpidMethod, + kpidId, + kpidOffset +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) +{ + const AString s (item.GetSubStringForTag(name)); + if (s.IsEmpty()) + return false; + const char *end; + res = ConvertStringToUInt64(s, &end); + return *end == 0; +} + + +#define PARSE_NUM(_num_, _dest_) \ + { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ + if ((unsigned)(end - p) != _num_) return 0; \ + p += _num_ + 1; } + +static UInt64 ParseTime(const CXmlItem &item, const char *name /* , bool z_isRequired */ ) +{ + const AString s (item.GetSubStringForTag(name)); + if (s.Len() < 20 /* (z_isRequired ? 20u : 19u) */) + return 0; + const char *p = s; + if (p[ 4] != '-' || + p[ 7] != '-' || + p[10] != 'T' || + p[13] != ':' || + p[16] != ':') + return 0; + // if (z_isRequired) + if (p[19] != 'Z') + return 0; + UInt32 year, month, day, hour, min, sec; + PARSE_NUM(4, year) + PARSE_NUM(2, month) + PARSE_NUM(2, day) + PARSE_NUM(2, hour) + PARSE_NUM(2, min) + PARSE_NUM(2, sec) + UInt64 numSecs; + if (!NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) + return 0; + return numSecs * 10000000; +} + + +static void ParseChecksum(const CXmlItem &item, const char *name, CCheckSum &checksum) +{ + const CXmlItem *checkItem = item.FindSubTag_GetPtr(name); + if (!checkItem) + return; // false; + checksum.Style = checkItem->GetPropVal("style"); + const AString s (checkItem->GetSubString()); + if ((s.Len() & 1) == 0 && s.Len() <= (2u << 7)) // 1024-bit max + { + const size_t size = s.Len() / 2; + CByteBuffer temp(size); + if ((size_t)(ParseHexString(s, temp) - temp) == size) + { + checksum.Data = temp; + const int index = Find_ChecksumId_for_Name(checksum.Style); + if (index >= 0 && checksum.Data.Size() == GetHashSize(index)) + { + checksum.AlgoNumber = index; + return; + } + } + } + checksum.Error = true; +} + + +static bool AddItem(const CXmlItem &item, CObjectVector &files, int parent, int level) +{ + if (!item.IsTag) + return true; + if (level >= 1024) + return false; + if (item.Name.IsEqualTo("file")) + { + CFile file(parent); + parent = (int)files.Size(); + { + const AString id = item.GetPropVal("id"); + const char *end; + file.Id = ConvertStringToUInt64(id, &end); + if (*end == 0) + file.Id_Defined = true; + } + file.Name = item.GetSubStringForTag("name"); + z7_xml_DecodeString(file.Name); + { + const CXmlItem *typeItem = item.FindSubTag_GetPtr("type"); + if (typeItem) + { + file.Type = typeItem->GetSubString(); + // file.LinkFrom = typeItem->GetPropVal("link"); + if (file.Type.IsEqualTo("directory")) + file.IsDir = true; + else + { + // file.IsDir = false; + /* + else if (file.Type.IsEqualTo("file")) + {} + else if (file.Type.IsEqualTo("hardlink")) + {} + else + */ + if (file.Type.IsEqualTo("symlink")) + file.Is_SymLink = true; + // file.IsDir = false; + } + } + } + { + const CXmlItem *linkItem = item.FindSubTag_GetPtr("link"); + if (linkItem) + { + // file.LinkType = linkItem->GetPropVal("type"); + file.Link = linkItem->GetSubString(); + z7_xml_DecodeString(file.Link); + } + } + + const CXmlItem *dataItem = item.FindSubTag_GetPtr("data"); + if (dataItem && !file.IsDir) + { + file.HasData = true; + if (!ParseUInt64(*dataItem, "size", file.Size)) + return false; + if (!ParseUInt64(*dataItem, "length", file.PackSize)) + return false; + if (!ParseUInt64(*dataItem, "offset", file.Offset)) + return false; + ParseChecksum(*dataItem, "extracted-checksum", file.extracted_checksum); + ParseChecksum(*dataItem, "archived-checksum", file.archived_checksum); + const CXmlItem *encodingItem = dataItem->FindSubTag_GetPtr("encoding"); + if (encodingItem) + { + AString s (encodingItem->GetPropVal("style")); + if (!s.IsEmpty()) + { + const AString appl ("application/"); + if (s.IsPrefixedBy(appl)) + { + s.DeleteFrontal(appl.Len()); + const AString xx ("x-"); + if (s.IsPrefixedBy(xx)) + { + s.DeleteFrontal(xx.Len()); + if (s.IsEqualTo("gzip")) + s = METHOD_NAME_ZLIB; + } + } + file.Method = s; + } + } + } + + file.INode_Defined = ParseUInt64(item, "inode", file.INode); + file.UserId_Defined = ParseUInt64(item, "uid", file.UserId); + file.GroupId_Defined = ParseUInt64(item, "gid", file.GroupId); + // file.Device_Defined = ParseUInt64(item, "deviceno", file.Device); + file.MTime = ParseTime(item, "mtime"); // z_IsRequied = true + file.CTime = ParseTime(item, "ctime"); + file.ATime = ParseTime(item, "atime"); + { + const AString s (item.GetSubStringForTag("mode")); + if (s[0] == '0') + { + const char *end; + file.Mode = ConvertOctStringToUInt32(s, &end); + file.Mode_Defined = (*end == 0); + } + } + file.User = item.GetSubStringForTag("user"); + file.Group = item.GetSubStringForTag("group"); + + files.Add(file); + } + + FOR_VECTOR (i, item.SubItems) + if (!AddItem(item.SubItems[i], files, parent, level + 1)) + return false; + return true; +} + + + +struct CInStreamWithHash +{ + CMyComPtr2_Create inStreamSha1; + CMyComPtr2_Create inStreamSha256; + CMyComPtr2_Create inStreamLim; + + void SetStreamAndInit(ISequentialInStream *stream, int algo); + bool CheckHash(int algo, const Byte *digest_from_arc) const; +}; + + +void CInStreamWithHash::SetStreamAndInit(ISequentialInStream *stream, int algo) +{ + if (algo == XAR_CKSUM_SHA1) + { + inStreamSha1->SetStream(stream); + inStreamSha1->Init(); + stream = inStreamSha1; + } + else if (algo == XAR_CKSUM_SHA256 + || algo == XAR_CKSUM_SHA512) + { + inStreamSha256->SetStream(stream); + inStreamSha256->Init(algo == XAR_CKSUM_SHA512); + stream = inStreamSha256; + } + inStreamLim->SetStream(stream); +} + +bool CInStreamWithHash::CheckHash(int algo, const Byte *digest_from_arc) const +{ + if (algo == XAR_CKSUM_SHA1) + { + Byte digest[SHA1_DIGEST_SIZE]; + inStreamSha1->Final(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + else if (algo == XAR_CKSUM_SHA256) + { + Byte digest[SHA256_DIGEST_SIZE]; + inStreamSha256->Final256(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + else if (algo == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + inStreamSha256->Final512(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + return true; +} + + +HRESULT CHandler::Open2(IInStream *stream) +{ + const unsigned kHeaderSize = 28; + UInt32 buf32[kHeaderSize / sizeof(UInt32)]; + RINOK(ReadStream_FALSE(stream, buf32, kHeaderSize)) + const unsigned headerSize = Get16((const Byte *)(const void *)buf32 + 4); + // xar library now writes 1 to version field. + // some old xars could have version == 0 ? + // specification allows (headerSize != 28), + // but we don't expect big value in (headerSize). + // so we restrict (headerSize) with 64 bytes to reduce false open. + const unsigned kHeaderSize_MAX = 64; + if (Get32(buf32) != 0x78617221 // signature: "xar!" + || headerSize < kHeaderSize + || headerSize > kHeaderSize_MAX + || Get16((const Byte *)(const void *)buf32 + 6) > 1 // version + ) + return S_FALSE; + _checkSumAlgo = Get32(buf32 + 6); + const UInt64 packSize = Get64(buf32 + 2); + const UInt64 unpackSize = Get64(buf32 + 4); + if (packSize >= kXmlPackSizeMax || + unpackSize >= kXmlSizeMax) + return S_FALSE; + /* some xar archives can have padding bytes at offset 28, + or checksum algorithm name at offset 28 (in xar fork, if cksum_alg==3) + But we didn't see such xar archives. + */ + if (headerSize != kHeaderSize) + { + RINOK(InStream_SeekSet(stream, headerSize)) + } + _dataStartPos = headerSize + packSize; + _phySize = _dataStartPos; + + _xmlBuf.Alloc((size_t)unpackSize + 1); + if (!_xmlBuf.IsAllocated()) + return E_OUTOFMEMORY; + _xmlLen = (size_t)unpackSize; + + CInStreamWithHash hashStream; + { + CMyComPtr2_Create zlibCoder; + hashStream.SetStreamAndInit(stream, (int)(unsigned)_checkSumAlgo); + hashStream.inStreamLim->Init(packSize); + CMyComPtr2_Create outStreamLim; + outStreamLim->Init(_xmlBuf, (size_t)unpackSize); + RINOK(zlibCoder.Interface()->Code(hashStream.inStreamLim, outStreamLim, NULL, &unpackSize, NULL)) + if (outStreamLim->GetPos() != (size_t)unpackSize) + return S_FALSE; + } + _xmlBuf[(size_t)unpackSize] = 0; + if (strlen((const char *)(const Byte *)_xmlBuf) != (size_t)unpackSize) + return S_FALSE; + CXml xml; + if (!xml.Parse((const char *)(const Byte *)_xmlBuf)) + return S_FALSE; + + if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1) + return S_FALSE; + const CXmlItem &toc = xml.Root.SubItems[0]; + if (!toc.IsTagged("toc")) + return S_FALSE; + + // CreationTime = ParseTime(toc, "creation-time", false); // z_IsRequied + CreationTime_String = toc.GetSubStringForTag("creation-time"); + { + // we suppose that offset of checksum is always 0; + // but [TOC].xml contains exact offset value in block. + const UInt64 offset = 0; + const unsigned hashSize = GetHashSize((int)(unsigned)_checkSumAlgo); + if (hashSize) + { + /* + const CXmlItem *csItem = toc.FindSubTag_GetPtr("checksum"); + if (csItem) + { + const int checkSumAlgo2 = Find_ChecksumId_for_Name(csItem->GetPropVal("style")); + UInt64 csSize, csOffset; + if (ParseUInt64(*csItem, "size", csSize) && + ParseUInt64(*csItem, "offset", csOffset) && + csSize == hashSize && + (unsigned)checkSumAlgo2 == _checkSumAlgo) + offset = csOffset; + } + */ + CByteBuffer digest_from_arc(hashSize); + RINOK(InStream_SeekSet(stream, _dataStartPos + offset)) + RINOK(ReadStream_FALSE(stream, digest_from_arc, hashSize)) + if (!hashStream.CheckHash((int)(unsigned)_checkSumAlgo, digest_from_arc)) + _toc_CrcError = true; + } + } + + if (!AddItem(toc, _files, + -1, // parent + 0)) // level + return S_FALSE; + + UInt64 totalPackSize = 0; + unsigned numMainFiles = 0; + + FOR_VECTOR (i, _files) + { + const CFile &file = _files[i]; + file.UpdateTotalPackSize(totalPackSize); + if (file.Parent == -1) + { + if (file.Name.IsEqualTo("Payload") || + file.Name.IsEqualTo("Content")) + { + _mainSubfile = (Int32)(int)i; + numMainFiles++; + } + else if (file.Name.IsEqualTo("PackageInfo")) + _is_pkg = true; + } + } + + if (numMainFiles > 1) + _mainSubfile = -1; + + const UInt64 k_PhySizeLim = (UInt64)1 << 62; + _phySize = (totalPackSize > k_PhySizeLim - _dataStartPos) ? + k_PhySizeLim : + _dataStartPos + totalPackSize; + + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + { + Close(); + RINOK(Open2(stream)) + _inStream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _phySize = 0; + _dataStartPos = 0; + _inStream.Release(); + _files.Clear(); + _xmlLen = 0; + _xmlBuf.Free(); + _mainSubfile = -1; + _is_pkg = false; + _toc_CrcError = false; + _checkSumAlgo = 0; + // CreationTime = 0; + CreationTime_String.Empty(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _files.Size() +#ifdef XAR_SHOW_RAW + + 1 +#endif + ; + return S_OK; +} + +static void TimeToProp(UInt64 t, NCOM::CPropVariant &prop) +{ + if (t != 0) + { + FILETIME ft; + ft.dwLowDateTime = (UInt32)(t); + ft.dwHighDateTime = (UInt32)(t >> 32); + prop = ft; + } +} + +static void Utf8StringToProp(const AString &s, NCOM::CPropVariant &prop) +{ + if (!s.IsEmpty()) + { + UString us; + ConvertUTF8ToUnicode(s, us); + prop = us; + } +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + // case kpidHeadersSize: prop = _dataStartPos; break; + case kpidPhySize: prop = _phySize; break; + case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break; + case kpidSubType: if (_is_pkg) prop = "pkg"; break; + case kpidExtension: prop = _is_pkg ? "pkg" : "xar"; break; + case kpidCTime: + { + // it's local time. We can transfer it to UTC time, if we use FILETIME. + // TimeToProp(CreationTime, prop); break; + if (!CreationTime_String.IsEmpty()) + prop = CreationTime_String; + break; + } + case kpidMethod: + { + AString s; + if (_checkSumAlgo < Z7_ARRAY_SIZE(k_ChecksumNames)) + s = k_ChecksumNames[_checkSumAlgo]; + else + { + s += "Checksum"; + s.Add_UInt32(_checkSumAlgo); + } + prop = s; + break; + } + case kpidWarningFlags: + { + UInt32 v = 0; + if (_toc_CrcError) v |= kpv_ErrorFlags_CrcError; + prop = v; + break; + } + case kpidINode: prop = true; break; + case kpidIsTree: prop = true; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +/* +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) & ~(UInt32)0xff); +} +*/ + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + switch (propID) + { + case kpidName: + case kpidPath: + prop = "[TOC].xml"; break; + case kpidSize: + case kpidPackSize: prop = (UInt64)_xmlLen; break; + } + } + else +#endif + { + const CFile &item = _files[index]; + switch (propID) + { + case kpidPath: + { + AString path; + unsigned cur = index; + for (;;) + { + const CFile &item2 = _files[cur]; + if (!path.IsEmpty()) + path.InsertAtFront(CHAR_PATH_SEPARATOR); +// #define XAR_EMPTY_NAME_REPLACEMENT "[]" + if (item2.Name.IsEmpty()) + { + AString s('['); + s.Add_UInt32(cur); + s.Add_Char(']'); + path.Insert(0, s); + } + else + path.Insert(0, item2.Name); + if (item2.Parent < 0) + break; + cur = (unsigned)item2.Parent; + } + Utf8StringToProp(path, prop); + break; + } + + case kpidName: + { + if (item.Name.IsEmpty()) + { + AString s('['); + s.Add_UInt32(index); + s.Add_Char(']'); + prop = s; + } + else + Utf8StringToProp(item.Name, prop); + break; + } + + case kpidIsDir: prop = item.IsDir; break; + + case kpidSize: if (item.HasData && !item.IsDir) prop = item.Size; break; + case kpidPackSize: if (item.HasData && !item.IsDir) prop = item.PackSize; break; + + case kpidMethod: + { + if (item.HasData) + { + AString s = item.Method; + item.extracted_checksum.AddNameToString(s); + item.archived_checksum.AddNameToString(s); + Utf8StringToProp(s, prop); + } + break; + } + + case kpidMTime: TimeToProp(item.MTime, prop); break; + case kpidCTime: TimeToProp(item.CTime, prop); break; + case kpidATime: TimeToProp(item.ATime, prop); break; + + case kpidPosixAttrib: + if (item.Mode_Defined) + { + UInt32 mode = item.Mode; + if ((mode & MY_LIN_S_IFMT) == 0) + mode |= ( + item.Is_SymLink ? MY_LIN_S_IFLNK : + item.IsDir ? MY_LIN_S_IFDIR : + MY_LIN_S_IFREG); + prop = mode; + } + break; + + case kpidType: Utf8StringToProp(item.Type, prop); break; + case kpidUser: Utf8StringToProp(item.User, prop); break; + case kpidGroup: Utf8StringToProp(item.Group, prop); break; + case kpidSymLink: if (item.Is_SymLink) Utf8StringToProp(item.Link, prop); break; + + case kpidUserId: if (item.UserId_Defined) prop = item.UserId; break; + case kpidGroupId: if (item.GroupId_Defined) prop = item.GroupId; break; + case kpidINode: if (item.INode_Defined) prop = item.INode; break; + case kpidId: if (item.Id_Defined) prop = item.Id; break; + // Utf8StringToProp(item.Id, prop); + /* + case kpidDeviceMajor: if (item.Device_Defined) prop = (UInt32)MY_dev_major(item.Device); break; + case kpidDeviceMinor: if (item.Device_Defined) prop = (UInt32)MY_dev_minor(item.Device); break; + case kpidLinkType: + if (!item.LinkType.IsEmpty()) + Utf8StringToProp(item.LinkType, prop); + break; + case kpidLinkFrom: + if (!item.LinkFrom.IsEmpty()) + Utf8StringToProp(item.LinkFrom, prop); + break; + */ + case kpidOffset: + if (item.HasData) + prop = _dataStartPos + item.Offset; + break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +// for debug: +// #define Z7_XAR_SHOW_CHECKSUM_PACK + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK +enum +{ + kpidChecksumPack = kpidUserDefined +}; +#endif + +static const Byte kRawProps[] = +{ + kpidChecksum +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + , kpidCRC // instead of kpidUserDefined / kpidCRC +#endif +}; + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + if (index != 0) + { + *propID = kpidChecksumPack; + *name = NWindows::NCOM::AllocBstrFromAscii("archived-checksum"); + } +#endif + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + return S_OK; +#endif + { + const CFile &item = _files[index]; + *parent = (UInt32)(Int32)item.Parent; + } + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + // COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (propID == kpidChecksum) + { +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + // case kpidPath: prop = "[TOC].xml"; break; + } + else +#endif + { + const CFile &item = _files[index]; + const size_t size = item.extracted_checksum.Data.Size(); + if (size != 0) + { + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + *data = item.extracted_checksum.Data; + } + } + } + +#ifdef Z7_XAR_SHOW_CHECKSUM_PACK + if (propID == kpidChecksumPack) + { +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + // we can show digest check sum here + } + else +#endif + { + const CFile &item = _files[index]; + const size_t size = (UInt32)item.archived_checksum.Data.Size(); + if (size != 0) + { + *dataSize = (UInt32)size; + *propType = NPropDataType::kRaw; + *data = item.archived_checksum.Data; + } + } + } +#endif + return S_OK; +} + + + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _files.Size() +#ifdef XAR_SHOW_RAW + + 1 +#endif + ; + if (numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + totalSize += _xmlLen; + else +#endif + totalSize += _files[index].Size; + } + RINOK(extractCallback->SetTotal(totalSize)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + CInStreamWithHash inHashStream; + CMyComPtr2_Create outStreamSha1; + CMyComPtr2_Create outStreamSha256; + CMyComPtr2_Create outStreamLim; + CMyComPtr2_Create copyCoder; + CMyComPtr2_Create zlibCoder; + CMyComPtr2_Create bzip2Coder; + bzip2Coder->FinishMode = true; + + UInt64 cur_PackSize, cur_UnpSize; + + for (i = 0;; i++, + lps->InSize += cur_PackSize, + lps->OutSize += cur_UnpSize) + { + cur_PackSize = 0; + cur_UnpSize = 0; + RINOK(lps->SetCur()) + if (i >= numItems) + break; + + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (index < _files.Size()) + { + const CFile &item = _files[index]; + if (item.IsDir) + { + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + continue; + } + } + + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + Int32 opRes = NExtract::NOperationResult::kOK; + +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + cur_PackSize = cur_UnpSize = _xmlLen; + if (realOutStream) + RINOK(WriteStream(realOutStream, _xmlBuf, _xmlLen)) + realOutStream.Release(); + } + else +#endif + { + const CFile &item = _files[index]; + if (!item.HasData) + realOutStream.Release(); + else + { + cur_PackSize = item.PackSize; + cur_UnpSize = item.Size; + + RINOK(InStream_SeekSet(_inStream, _dataStartPos + item.Offset)) + + inHashStream.SetStreamAndInit(_inStream, item.archived_checksum.AlgoNumber); + inHashStream.inStreamLim->Init(item.PackSize); + + const int checksum_method = item.extracted_checksum.AlgoNumber; + if (checksum_method == XAR_CKSUM_SHA1) + { + outStreamLim->SetStream(outStreamSha1); + outStreamSha1->SetStream(realOutStream); + outStreamSha1->Init(); + } + else if (checksum_method == XAR_CKSUM_SHA256 + || checksum_method == XAR_CKSUM_SHA512) + { + outStreamLim->SetStream(outStreamSha256); + outStreamSha256->SetStream(realOutStream); + outStreamSha256->Init(checksum_method == XAR_CKSUM_SHA512); + } + else + outStreamLim->SetStream(realOutStream); + + realOutStream.Release(); + + // outStreamSha1->Init(item.Sha1IsDefined); + + outStreamLim->Init(item.Size); + HRESULT res = S_OK; + + ICompressCoder *coder = NULL; + if (item.IsCopyMethod()) + { + if (item.PackSize == item.Size) + coder = copyCoder; + else + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else if (item.Method.IsEqualTo(METHOD_NAME_ZLIB)) + coder = zlibCoder; + else if (item.Method.IsEqualTo("bzip2")) + coder = bzip2Coder; + else + opRes = NExtract::NOperationResult::kUnsupportedMethod; + + if (coder) + res = coder->Code(inHashStream.inStreamLim, outStreamLim, NULL, &item.Size, lps); + + if (res != S_OK) + { + if (!outStreamLim->IsFinishedOK()) + opRes = NExtract::NOperationResult::kDataError; + else if (res != S_FALSE) + return res; + if (opRes == NExtract::NOperationResult::kOK) + opRes = NExtract::NOperationResult::kDataError; + } + + if (opRes == NExtract::NOperationResult::kOK) + { + if (outStreamLim->IsFinishedOK()) + { + if (checksum_method == XAR_CKSUM_SHA1) + { + Byte digest[SHA1_DIGEST_SIZE]; + outStreamSha1->Final(digest); + if (memcmp(digest, item.extracted_checksum.Data, SHA1_DIGEST_SIZE) != 0) + opRes = NExtract::NOperationResult::kCRCError; + } + else if (checksum_method == XAR_CKSUM_SHA256) + { + Byte digest[SHA256_DIGEST_SIZE]; + outStreamSha256->Final256(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) + opRes = NExtract::NOperationResult::kCRCError; + } + else if (checksum_method == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + outStreamSha256->Final512(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) + opRes = NExtract::NOperationResult::kCRCError; + } + if (opRes == NExtract::NOperationResult::kOK) + if (!inHashStream.CheckHash( + item.archived_checksum.AlgoNumber, + item.archived_checksum.Data)) + opRes = NExtract::NOperationResult::kCRCError; + } + else + opRes = NExtract::NOperationResult::kDataError; + } + if (checksum_method == XAR_CKSUM_SHA1) + outStreamSha1->ReleaseStream(); + else if (checksum_method == XAR_CKSUM_SHA256) + outStreamSha256->ReleaseStream(); + } + outStreamLim->ReleaseStream(); + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + *stream = NULL; + COM_TRY_BEGIN +#ifdef XAR_SHOW_RAW + if (index >= _files.Size()) + { + Create_BufInStream_WithNewBuffer(_xmlBuf, _xmlLen, stream); + return S_OK; + } + else +#endif + { + const CFile &item = _files[index]; + if (item.HasData && item.IsCopyMethod() && item.PackSize == item.Size) + return CreateLimitedInStream(_inStream, _dataStartPos + item.Offset, item.Size, stream); + } + return S_FALSE; + COM_TRY_END +} + +// 0x1c == 28 is expected header size value for most archives. +// but we want to support another (rare case) headers sizes. +// so we must reduce signature to 4 or 5 bytes. +static const Byte k_Signature[] = +// { 'x', 'a', 'r', '!', 0, 0x1C, 0 }; + { 'x', 'a', 'r', '!', 0 }; + +REGISTER_ARC_I( + "Xar", "xar pkg xip", NULL, 0xE1, + k_Signature, + 0, + 0, + NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/XzHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/XzHandler.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.cpp 2025-07-03 11:00:00.000000000 +0000 @@ -1,956 +1,1452 @@ -// XzHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/XzCrc64.h" -#include "../../../C/XzEnc.h" - -#include "../../Common/ComTry.h" -#include "../../Common/Defs.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/PropVariant.h" - -#include "../ICoder.h" - -#include "../Common/CWrappers.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -#include "IArchive.h" - -#ifndef EXTRACT_ONLY -#include "Common/HandlerOut.h" -#endif - -#include "XzHandler.h" - -using namespace NWindows; - -namespace NCompress { -namespace NLzma2 { - -HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); - -}} - -namespace NArchive { -namespace NXz { - -struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit; - -static const char *k_LZMA2_Name = "LZMA2"; - -void CStatInfo::Clear() -{ - InSize = 0; - OutSize = 0; - PhySize = 0; - - NumStreams = 0; - NumBlocks = 0; - - UnpackSize_Defined = false; - - NumStreams_Defined = false; - NumBlocks_Defined = false; - - IsArc = false; - UnexpectedEnd = false; - DataAfterEnd = false; - Unsupported = false; - HeadersError = false; - DataError = false; - CrcError = false; -} - -class CHandler: - public IInArchive, - public IArchiveOpenSeq, - #ifndef EXTRACT_ONLY - public IOutArchive, - public ISetProperties, - public CMultiMethodProps, - #endif - public CMyUnknownImp -{ - CStatInfo _stat; - - bool _isArc; - bool _needSeekToStart; - bool _phySize_Defined; - - CMyComPtr _stream; - CMyComPtr _seqStream; - - AString _methodsString; - - #ifndef EXTRACT_ONLY - - UInt32 _filterId; - - void Init() - { - _filterId = 0; - CMultiMethodProps::Init(); - } - - #endif - - HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback); - - HRESULT Decode2(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, - CDecoder &decoder, ICompressProgressInfo *progress) - { - RINOK(decoder.Decode(seqInStream, outStream, progress)); - _stat = decoder; - _phySize_Defined = true; - return S_OK; - } - -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSeq) - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - STDMETHOD(OpenSeq)(ISequentialInStream *stream); - - #ifndef EXTRACT_ONLY - INTERFACE_IOutArchive(;) - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif - - CHandler(); -}; - -CHandler::CHandler() -{ - #ifndef EXTRACT_ONLY - Init(); - #endif -} - - -static const Byte kProps[] = -{ - kpidSize, - kpidPackSize, - kpidMethod -}; - -static const Byte kArcProps[] = -{ - kpidMethod, - kpidNumStreams, - kpidNumBlocks -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -static inline char GetHex(unsigned value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} - -static inline void AddHexToString(AString &s, Byte value) -{ - s += GetHex(value >> 4); - s += GetHex(value & 0xF); -} - -static void AddUInt32ToString(AString &s, UInt32 value) -{ - char temp[16]; - ConvertUInt32ToString(value, temp); - s += temp; -} - -static void Lzma2PropToString(AString &s, unsigned prop) -{ - char c = 0; - UInt32 size; - if ((prop & 1) == 0) - size = prop / 2 + 12; - else - { - c = 'k'; - size = (UInt32)(2 | (prop & 1)) << (prop / 2 + 1); - if (prop > 17) - { - size >>= 10; - c = 'm'; - } - } - AddUInt32ToString(s, size); - if (c != 0) - s += c; -} - -struct CMethodNamePair -{ - UInt32 Id; - const char *Name; -}; - -static const CMethodNamePair g_NamePairs[] = -{ - { XZ_ID_Subblock, "SB" }, - { XZ_ID_Delta, "Delta" }, - { XZ_ID_X86, "BCJ" }, - { XZ_ID_PPC, "PPC" }, - { XZ_ID_IA64, "IA64" }, - { XZ_ID_ARM, "ARM" }, - { XZ_ID_ARMT, "ARMT" }, - { XZ_ID_SPARC, "SPARC" }, - { XZ_ID_LZMA2, "LZMA2" } -}; - -static AString GetMethodString(const CXzFilter &f) -{ - const char *p = NULL; - for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++) - if (g_NamePairs[i].Id == f.id) - { - p = g_NamePairs[i].Name; - break; - } - char temp[32]; - if (!p) - { - ::ConvertUInt64ToString(f.id, temp); - p = temp; - } - - AString s = p; - - if (f.propsSize > 0) - { - s += ':'; - if (f.id == XZ_ID_LZMA2 && f.propsSize == 1) - Lzma2PropToString(s, f.props[0]); - else if (f.id == XZ_ID_Delta && f.propsSize == 1) - AddUInt32ToString(s, (UInt32)f.props[0] + 1); - else - { - s += '['; - for (UInt32 bi = 0; bi < f.propsSize; bi++) - AddHexToString(s, f.props[bi]); - s += ']'; - } - } - return s; -} - -static void AddString(AString &dest, const AString &src) -{ - dest.Add_Space_if_NotEmpty(); - dest += src; -} - -static const char * const kChecks[] = -{ - "NoCheck" - , "CRC32" - , NULL - , NULL - , "CRC64" - , NULL - , NULL - , NULL - , NULL - , NULL - , "SHA256" - , NULL - , NULL - , NULL - , NULL - , NULL -}; - -static AString GetCheckString(const CXzs &xzs) -{ - size_t i; - UInt32 mask = 0; - for (i = 0; i < xzs.num; i++) - mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags)); - AString s; - for (i = 0; i <= XZ_CHECK_MASK; i++) - if (((mask >> i) & 1) != 0) - { - AString s2; - if (kChecks[i]) - s2 = kChecks[i]; - else - { - s2 = "Check-"; - AddUInt32ToString(s2, (UInt32)i); - } - AddString(s, s2); - } - return s; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySize: if (_phySize_Defined) prop = _stat.PhySize; break; - case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break; - case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break; - case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break; - case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; - case kpidErrorFlags: - { - UInt32 v = 0; - if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; - if (_stat.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; - if (_stat.HeadersError) v |= kpv_ErrorFlags_HeadersError; - if (_stat.Unsupported) v |= kpv_ErrorFlags_UnsupportedMethod; - if (_stat.DataError) v |= kpv_ErrorFlags_DataError; - if (_stat.CrcError) v |= kpv_ErrorFlags_CrcError; - prop = v; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break; - case kpidPackSize: if (_phySize_Defined) prop = _stat.PhySize; break; - case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -struct COpenCallbackWrap -{ - ICompressProgress p; - IArchiveOpenCallback *OpenCallback; - HRESULT Res; - COpenCallbackWrap(IArchiveOpenCallback *progress); -}; - -static SRes OpenCallbackProgress(void *pp, UInt64 inSize, UInt64 /* outSize */) -{ - COpenCallbackWrap *p = (COpenCallbackWrap *)pp; - if (p->OpenCallback) - p->Res = p->OpenCallback->SetCompleted(NULL, &inSize); - return (SRes)p->Res; -} - -COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback) -{ - p.Progress = OpenCallbackProgress; - OpenCallback = callback; - Res = SZ_OK; -} - -struct CXzsCPP -{ - CXzs p; - CXzsCPP() { Xzs_Construct(&p); } - ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); } -}; - -static HRESULT SRes_to_Open_HRESULT(SRes res) -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PROGRESS: return E_ABORT; - /* - case SZ_ERROR_UNSUPPORTED: - case SZ_ERROR_CRC: - case SZ_ERROR_DATA: - case SZ_ERROR_ARCHIVE: - case SZ_ERROR_NO_ARCHIVE: - return S_FALSE; - */ - } - return S_FALSE; -} - -HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback) -{ - _needSeekToStart = true; - - { - CXzStreamFlags st; - CSeqInStreamWrap inStreamWrap(inStream); - SRes res = Xz_ReadHeader(&st, &inStreamWrap.p); - if (res != SZ_OK) - return SRes_to_Open_HRESULT(res); - - { - CXzBlock block; - Bool isIndex; - UInt32 headerSizeRes; - SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.p, &isIndex, &headerSizeRes); - if (res2 == SZ_OK && !isIndex) - { - unsigned numFilters = XzBlock_GetNumFilters(&block); - for (unsigned i = 0; i < numFilters; i++) - AddString(_methodsString, GetMethodString(block.filters[i])); - } - } - } - - RINOK(inStream->Seek(0, STREAM_SEEK_END, &_stat.PhySize)); - if (callback) - { - RINOK(callback->SetTotal(NULL, &_stat.PhySize)); - } - - CSeekInStreamWrap inStreamImp(inStream); - - CLookToRead lookStream; - LookToRead_CreateVTable(&lookStream, True); - lookStream.realStream = &inStreamImp.p; - LookToRead_Init(&lookStream); - - COpenCallbackWrap openWrap(callback); - - CXzsCPP xzs; - Int64 startPosition; - SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.s, &startPosition, &openWrap.p, &g_Alloc); - if (res == SZ_ERROR_PROGRESS) - return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res; - /* - if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0) - res = SZ_OK; - */ - if (res == SZ_OK && startPosition == 0) - { - _phySize_Defined = true; - - _stat.OutSize = Xzs_GetUnpackSize(&xzs.p); - _stat.UnpackSize_Defined = true; - - _stat.NumStreams = xzs.p.num; - _stat.NumStreams_Defined = true; - - _stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p); - _stat.NumBlocks_Defined = true; - - AddString(_methodsString, GetCheckString(xzs.p)); - } - else - { - res = SZ_OK; - } - - RINOK(SRes_to_Open_HRESULT(res)); - _stream = inStream; - _seqStream = inStream; - _isArc = true; - return S_OK; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - { - Close(); - return Open2(inStream, callback); - } - COM_TRY_END -} - -STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream) -{ - Close(); - _seqStream = stream; - _isArc = true; - _needSeekToStart = false; - return S_OK; -} - -STDMETHODIMP CHandler::Close() -{ - _stat.Clear(); - - _isArc = false; - _needSeekToStart = false; - - _phySize_Defined = false; - - _methodsString.Empty(); - _stream.Release(); - _seqStream.Release(); - return S_OK; -} - -class CSeekToSeqStream: - public IInStream, - public CMyUnknownImp -{ -public: - CMyComPtr Stream; - MY_UNKNOWN_IMP1(IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -STDMETHODIMP CSeekToSeqStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - return Stream->Read(data, size, processedSize); -} - -STDMETHODIMP CSeekToSeqStream::Seek(Int64, UInt32, UInt64 *) { return E_NOTIMPL; } - -CXzUnpackerCPP::CXzUnpackerCPP(): InBuf(0), OutBuf(0) -{ - XzUnpacker_Construct(&p, &g_Alloc); -} - -CXzUnpackerCPP::~CXzUnpackerCPP() -{ - XzUnpacker_Free(&p); - MyFree(InBuf); - MyFree(OutBuf); -} - -HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - const size_t kInBufSize = 1 << 15; - const size_t kOutBufSize = 1 << 21; - - Clear(); - DecodeRes = SZ_OK; - - XzUnpacker_Init(&xzu.p); - if (!xzu.InBuf) - xzu.InBuf = (Byte *)MyAlloc(kInBufSize); - if (!xzu.OutBuf) - xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize); - - UInt32 inSize = 0; - SizeT inPos = 0; - SizeT outPos = 0; - - for (;;) - { - if (inPos == inSize) - { - inPos = inSize = 0; - RINOK(seqInStream->Read(xzu.InBuf, kInBufSize, &inSize)); - } - - SizeT inLen = inSize - inPos; - SizeT outLen = kOutBufSize - outPos; - ECoderStatus status; - - SRes res = XzUnpacker_Code(&xzu.p, - xzu.OutBuf + outPos, &outLen, - xzu.InBuf + inPos, &inLen, - (inSize == 0 ? CODER_FINISH_END : CODER_FINISH_ANY), &status); - - inPos += inLen; - outPos += outLen; - - InSize += inLen; - OutSize += outLen; - - DecodeRes = res; - - bool finished = ((inLen == 0 && outLen == 0) || res != SZ_OK); - - if (outStream) - { - if (outPos == kOutBufSize || finished) - { - if (outPos != 0) - { - RINOK(WriteStream(outStream, xzu.OutBuf, outPos)); - outPos = 0; - } - } - } - else - outPos = 0; - - if (progress) - { - RINOK(progress->SetRatioInfo(&InSize, &OutSize)); - } - - if (finished) - { - PhySize = InSize; - NumStreams = xzu.p.numStartedStreams; - if (NumStreams > 0) - IsArc = true; - NumBlocks = xzu.p.numTotalBlocks; - - UnpackSize_Defined = true; - NumStreams_Defined = true; - NumBlocks_Defined = true; - - UInt64 extraSize = XzUnpacker_GetExtraSize(&xzu.p); - - if (res == SZ_OK) - { - if (status == CODER_STATUS_NEEDS_MORE_INPUT) - { - extraSize = 0; - if (!XzUnpacker_IsStreamWasFinished(&xzu.p)) - { - // finished at padding bytes, but padding is not aligned for 4 - UnexpectedEnd = true; - res = SZ_ERROR_DATA; - } - } - else // status == CODER_STATUS_NOT_FINISHED - res = SZ_ERROR_DATA; - } - else if (res == SZ_ERROR_NO_ARCHIVE) - { - if (InSize == extraSize) - IsArc = false; - else - { - if (extraSize != 0 || inPos != inSize) - { - DataAfterEnd = true; - res = SZ_OK; - } - } - } - - DecodeRes = res; - PhySize -= extraSize; - - switch (res) - { - case SZ_OK: break; - case SZ_ERROR_NO_ARCHIVE: IsArc = false; break; - case SZ_ERROR_ARCHIVE: HeadersError = true; break; - case SZ_ERROR_UNSUPPORTED: Unsupported = true; break; - case SZ_ERROR_CRC: CrcError = true; break; - case SZ_ERROR_DATA: DataError = true; break; - default: DataError = true; break; - } - - break; - } - } - - return S_OK; -} - -Int32 CDecoder::Get_Extract_OperationResult() const -{ - Int32 opRes; - if (!IsArc) - opRes = NExtract::NOperationResult::kIsNotArc; - else if (UnexpectedEnd) - opRes = NExtract::NOperationResult::kUnexpectedEnd; - else if (DataAfterEnd) - opRes = NExtract::NOperationResult::kDataAfterEnd; - else if (CrcError) - opRes = NExtract::NOperationResult::kCRCError; - else if (Unsupported) - opRes = NExtract::NOperationResult::kUnsupportedMethod; - else if (HeadersError) - opRes = NExtract::NOperationResult::kDataError; - else if (DataError) - opRes = NExtract::NOperationResult::kDataError; - else if (DecodeRes != SZ_OK) - opRes = NExtract::NOperationResult::kDataError; - else - opRes = NExtract::NOperationResult::kOK; - return opRes; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - if (_phySize_Defined) - extractCallback->SetTotal(_stat.PhySize); - - UInt64 currentTotalPacked = 0; - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr lpsRef = lps; - lps->Init(extractCallback, true); - - if (_needSeekToStart) - { - if (!_stream) - return E_FAIL; - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - else - _needSeekToStart = true; - - CDecoder decoder; - RINOK(Decode2(_seqStream, realOutStream, decoder, lpsRef)); - Int32 opRes = decoder.Get_Extract_OperationResult(); - - realOutStream.Release(); - return extractCallback->SetOperationResult(opRes); - COM_TRY_END -} - -#ifndef EXTRACT_ONLY - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) -{ - *timeType = NFileTimeType::kUnix; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - - CSeqOutStreamWrap seqOutStream(outStream); - - if (numItems == 0) - { - SRes res = Xz_EncodeEmpty(&seqOutStream.p); - return SResToHRESULT(res); - } - - if (numItems != 1) - return E_INVALIDARG; - - Int32 newData, newProps; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)); - - if (IntToBool(newProps)) - { - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)); - if (prop.vt != VT_EMPTY) - if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) - return E_INVALIDARG; - } - } - - if (IntToBool(newData)) - { - UInt64 size; - { - NCOM::CPropVariant prop; - RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - RINOK(updateCallback->SetTotal(size)); - } - - CLzma2EncProps lzma2Props; - Lzma2EncProps_Init(&lzma2Props); - - lzma2Props.lzmaProps.level = GetLevel(); - - CMyComPtr fileInStream; - RINOK(updateCallback->GetStream(0, &fileInStream)); - - CSeqInStreamWrap seqInStream(fileInStream); - - { - NCOM::CPropVariant prop = (UInt64)size; - RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props)); - } - - FOR_VECTOR (i, _methods) - { - COneMethodInfo &m = _methods[i]; - SetGlobalLevelAndThreads(m - #ifndef _7ZIP_ST - , _numThreads - #endif - ); - { - FOR_VECTOR (j, m.Props) - { - const CProp &prop = m.Props[j]; - RINOK(NCompress::NLzma2::SetLzma2Prop(prop.Id, prop.Value, lzma2Props)); - } - } - } - - #ifndef _7ZIP_ST - lzma2Props.numTotalThreads = _numThreads; - #endif - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - CCompressProgressWrap progressWrap(progress); - CXzProps xzProps; - CXzFilterProps filter; - XzProps_Init(&xzProps); - XzFilterProps_Init(&filter); - xzProps.lzma2Props = &lzma2Props; - xzProps.filterProps = (_filterId != 0 ? &filter : NULL); - switch (_crcSize) - { - case 0: xzProps.checkId = XZ_CHECK_NO; break; - case 4: xzProps.checkId = XZ_CHECK_CRC32; break; - case 8: xzProps.checkId = XZ_CHECK_CRC64; break; - case 32: xzProps.checkId = XZ_CHECK_SHA256; break; - default: return E_INVALIDARG; - } - filter.id = _filterId; - if (_filterId == XZ_ID_Delta) - { - bool deltaDefined = false; - FOR_VECTOR (j, _filterMethod.Props) - { - const CProp &prop = _filterMethod.Props[j]; - if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4) - { - UInt32 delta = (UInt32)prop.Value.ulVal; - if (delta < 1 || delta > 256) - return E_INVALIDARG; - filter.delta = delta; - deltaDefined = true; - } - } - if (!deltaDefined) - return E_INVALIDARG; - } - SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p); - if (res == SZ_OK) - return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); - return SResToHRESULT(res); - } - - if (indexInArchive != 0) - return E_INVALIDARG; - - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - if (opCallback) - { - RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate)) - } - - if (_stream) - { - if (_phySize_Defined) - RINOK(updateCallback->SetTotal(_stat.PhySize)); - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - return NCompress::CopyStream(_stream, outStream, progress); - - COM_TRY_END -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - COM_TRY_BEGIN - - Init(); - for (UInt32 i = 0; i < numProps; i++) - { - RINOK(SetProperty(names[i], values[i])); - } - - if (!_filterMethod.MethodName.IsEmpty()) - { - unsigned k; - for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++) - { - const CMethodNamePair &pair = g_NamePairs[k]; - if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name)) - { - _filterId = pair.Id; - break; - } - } - if (k == ARRAY_SIZE(g_NamePairs)) - return E_INVALIDARG; - } - - _methods.DeleteFrontal(GetNumEmptyMethods()); - if (_methods.Size() > 1) - return E_INVALIDARG; - if (_methods.Size() == 1) - { - AString &methodName = _methods[0].MethodName; - if (methodName.IsEmpty()) - methodName = k_LZMA2_Name; - else if (!methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name)) - return E_INVALIDARG; - } - - return S_OK; - - COM_TRY_END -} - -#endif - -REGISTER_ARC_IO( - "xz", "xz txz", "* .tar", 0xC, - XZ_SIG, - 0, - NArcInfoFlags::kKeepName, - NULL) - -}} +// XzHandler.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../../Common/ComTry.h" +#include "../../Common/Defs.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyBuffer.h" +#include "../../Common/StringToInt.h" + +#include "../../Windows/PropVariant.h" +#include "../../Windows/System.h" + +#include "../Common/CWrappers.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/XzDecoder.h" +#include "../Compress/XzEncoder.h" + +#include "IArchive.h" + +#include "Common/HandlerOut.h" + +using namespace NWindows; + +namespace NArchive { +namespace NXz { + +#define k_LZMA2_Name "LZMA2" + + +struct CBlockInfo +{ + unsigned StreamFlags; + UInt64 PackPos; + UInt64 PackSize; // pure value from Index record, it doesn't include pad zeros + UInt64 UnpackPos; +}; + + +Z7_class_CHandler_final: + public IInArchive, + public IArchiveOpenSeq, + public IInArchiveGetStream, + public ISetProperties, + #ifndef Z7_EXTRACT_ONLY + public IOutArchive, + #endif + public CMyUnknownImp, + #ifndef Z7_EXTRACT_ONLY + public CMultiMethodProps + #else + public CCommonMethodProps + #endif +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveOpenSeq) + Z7_COM_QI_ENTRY(IInArchiveGetStream) + Z7_COM_QI_ENTRY(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutArchive) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveOpenSeq) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(ISetProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(IOutArchive) + #endif + + bool _stat_defined; + bool _stat2_defined; + bool _isArc; + bool _needSeekToStart; + bool _firstBlockWasRead; + SRes _stat2_decode_SRes; + + CXzStatInfo _stat; // it's stat from backward parsing + CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called + + const CXzStatInfo *GetStat() const + { + if (_stat_defined) return &_stat; + if (_stat2_defined) return &_stat2; + return NULL; + } + + AString _methodsString; + + + #ifndef Z7_EXTRACT_ONLY + + UInt32 _filterId; + UInt64 _numSolidBytes; + + void InitXz() + { + _filterId = 0; + _numSolidBytes = XZ_PROPS_BLOCK_SIZE_AUTO; + } + + #endif + + + void Init() + { + #ifndef Z7_EXTRACT_ONLY + InitXz(); + CMultiMethodProps::Init(); + #else + CCommonMethodProps::InitCommon(); + #endif + } + + HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value); + + HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback); + + HRESULT Decode(NCompress::NXz::CDecoder &decoder, + ISequentialInStream *seqInStream, + ISequentialOutStream *outStream, + ICompressProgressInfo *progress) + { + #ifndef Z7_ST + decoder._numThreads = _numThreads; + #endif + decoder._memUsage = _memUsage_Decompress; + + const HRESULT hres = decoder.Decode(seqInStream, outStream, + NULL, // *outSizeLimit + true, // finishStream + progress); + + if (decoder.MainDecodeSRes_wasUsed + && decoder.MainDecodeSRes != SZ_ERROR_MEM + && decoder.MainDecodeSRes != SZ_ERROR_UNSUPPORTED) + { + // if (!_stat2_defined) + { + _stat2_decode_SRes = decoder.MainDecodeSRes; + _stat2 = decoder.Stat; + _stat2_defined = true; + } + } + + if (hres == S_OK && progress) + { + // RINOK( + progress->SetRatioInfo(&decoder.Stat.InSize, &decoder.Stat.OutSize); + } + return hres; + } + +public: + CBlockInfo *_blocks; + size_t _blocksArraySize; + UInt64 _maxBlocksSize; + CMyComPtr _stream; + CMyComPtr _seqStream; + + CXzBlock _firstBlock; + + CHandler(); + ~CHandler(); + + HRESULT SeekToPackPos(UInt64 pos) + { + return InStream_SeekSet(_stream, pos); + } +}; + + +CHandler::CHandler(): + _blocks(NULL), + _blocksArraySize(0) +{ + #ifndef Z7_EXTRACT_ONLY + InitXz(); + #endif +} + +CHandler::~CHandler() +{ + MyFree(_blocks); +} + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize, + kpidMethod +}; + +static const Byte kArcProps[] = +{ + kpidMethod, + kpidNumStreams, + kpidNumBlocks, + kpidClusterSize, + kpidCharacts +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +static void Lzma2PropToString(AString &s, unsigned prop) +{ + char c = 0; + UInt32 size; + if ((prop & 1) == 0) + size = prop / 2 + 12; + else + { + c = 'k'; + size = (UInt32)(2 | (prop & 1)) << (prop / 2 + 1); + if (prop > 17) + { + size >>= 10; + c = 'm'; + } + } + s.Add_UInt32(size); + if (c != 0) + s.Add_Char(c); +} + +struct CMethodNamePair +{ + UInt32 Id; + const char *Name; +}; + +static const CMethodNamePair g_NamePairs[] = +{ + { XZ_ID_Subblock, "SB" }, + { XZ_ID_Delta, "Delta" }, + { XZ_ID_X86, "BCJ" }, + { XZ_ID_PPC, "PPC" }, + { XZ_ID_IA64, "IA64" }, + { XZ_ID_ARM, "ARM" }, + { XZ_ID_ARMT, "ARMT" }, + { XZ_ID_SPARC, "SPARC" }, + { XZ_ID_ARM64, "ARM64" }, + { XZ_ID_RISCV, "RISCV" }, + { XZ_ID_LZMA2, "LZMA2" } +}; + +static void AddMethodString(AString &s, const CXzFilter &f) +{ + const char *p = NULL; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) + if (g_NamePairs[i].Id == f.id) + { + p = g_NamePairs[i].Name; + break; + } + char temp[32]; + if (!p) + { + ::ConvertUInt64ToString(f.id, temp); + p = temp; + } + + s += p; + + if (f.propsSize > 0) + { + s.Add_Colon(); + if (f.id == XZ_ID_LZMA2 && f.propsSize == 1) + Lzma2PropToString(s, f.props[0]); + else if (f.id == XZ_ID_Delta && f.propsSize == 1) + s.Add_UInt32((UInt32)f.props[0] + 1); + else if (f.id == XZ_ID_ARM64 && f.propsSize == 1) + s.Add_UInt32((UInt32)f.props[0] + 16 + 2); + else + { + s.Add_Char('['); + for (UInt32 bi = 0; bi < f.propsSize; bi++) + { + const unsigned v = f.props[bi]; + s.Add_Char(GET_HEX_CHAR_UPPER(v >> 4)); + s.Add_Char(GET_HEX_CHAR_UPPER(v & 15)); + } + s.Add_Char(']'); + } + } +} + +static const char * const kChecks[] = +{ + "NoCheck" + , "CRC32" + , NULL + , NULL + , "CRC64" + , NULL + , NULL + , NULL + , NULL + , NULL + , "SHA256" + , NULL + , NULL + , NULL + , NULL + , NULL +}; + +static void AddCheckString(AString &s, const CXzs &xzs) +{ + size_t i; + UInt32 mask = 0; + for (i = 0; i < xzs.num; i++) + mask |= ((UInt32)1 << XzFlags_GetCheckType(xzs.streams[i].flags)); + for (i = 0; i <= XZ_CHECK_MASK; i++) + if (((mask >> i) & 1) != 0) + { + s.Add_Space_if_NotEmpty(); + if (kChecks[i]) + s += kChecks[i]; + else + { + s += "Check-"; + s.Add_UInt32((UInt32)i); + } + } +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CXzStatInfo *stat = GetStat(); + + switch (propID) + { + case kpidPhySize: if (stat) prop = stat->InSize; break; + case kpidNumStreams: if (stat && stat->NumStreams_Defined) prop = stat->NumStreams; break; + case kpidNumBlocks: if (stat && stat->NumBlocks_Defined) prop = stat->NumBlocks; break; + case kpidUnpackSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break; + case kpidClusterSize: if (_stat_defined && _stat.NumBlocks_Defined && stat->NumBlocks > 1) prop = _maxBlocksSize; break; + case kpidCharacts: + if (_firstBlockWasRead) + { + AString s; + if (XzBlock_HasPackSize(&_firstBlock)) + s.Add_OptSpaced("BlockPackSize"); + if (XzBlock_HasUnpackSize(&_firstBlock)) + s.Add_OptSpaced("BlockUnpackSize"); + if (!s.IsEmpty()) + prop = s; + } + break; + + + case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; + case kpidErrorFlags: + { + UInt32 v = 0; + SRes sres = _stat2_decode_SRes; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + if (sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd; + if (_stat2_defined && _stat2.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + if (sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError; + if (sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod; + if (sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError; + if (sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError; + if (v != 0) + prop = v; + break; + } + + case kpidMainSubfile: + { + // debug only, comment it: + // if (_blocks) prop = (UInt32)0; + break; + } + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + const CXzStatInfo *stat = GetStat(); + NCOM::CPropVariant prop; + switch (propID) + { + case kpidSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break; + case kpidPackSize: if (stat) prop = stat->InSize; break; + case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break; + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +struct COpenCallbackWrap +{ + ICompressProgress vt; + IArchiveOpenCallback *OpenCallback; + HRESULT Res; + + // new clang shows "non-POD" warning for offsetof(), if we use constructor instead of Init() + void Init(IArchiveOpenCallback *progress); +}; + +static SRes OpenCallbackProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 /* outSize */) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(COpenCallbackWrap) + if (p->OpenCallback) + p->Res = p->OpenCallback->SetCompleted(NULL, &inSize); + return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); +} + +void COpenCallbackWrap::Init(IArchiveOpenCallback *callback) +{ + vt.Progress = OpenCallbackProgress; + OpenCallback = callback; + Res = SZ_OK; +} + + +struct CXzsCPP +{ + CXzs p; + CXzsCPP() { Xzs_CONSTRUCT(&p) } + ~CXzsCPP() { Xzs_Free(&p, &g_Alloc); } +}; + +#define kInputBufSize ((size_t)1 << 10) + +struct CLookToRead2_CPP: public CLookToRead2 +{ + CLookToRead2_CPP() + { + buf = NULL; + LookToRead2_CreateVTable(this, + True // Lookahead ? + ); + } + void Alloc(size_t allocSize) + { + buf = (Byte *)MyAlloc(allocSize); + if (buf) + this->bufSize = allocSize; + } + ~CLookToRead2_CPP() + { + MyFree(buf); + } +}; + + +static HRESULT SRes_to_Open_HRESULT(SRes res) +{ + switch (res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PROGRESS: return E_ABORT; + /* + case SZ_ERROR_UNSUPPORTED: + case SZ_ERROR_CRC: + case SZ_ERROR_DATA: + case SZ_ERROR_ARCHIVE: + case SZ_ERROR_NO_ARCHIVE: + return S_FALSE; + */ + default: break; + } + return S_FALSE; +} + + + +HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback) +{ + _needSeekToStart = true; + + { + CXzStreamFlags st; + CSeqInStreamWrap inStreamWrap; + + inStreamWrap.Init(inStream); + + SRes res = Xz_ReadHeader(&st, &inStreamWrap.vt); + + if (inStreamWrap.Res != S_OK) + return inStreamWrap.Res; + if (res != SZ_OK) + return SRes_to_Open_HRESULT(res); + + { + CXzBlock block; + BoolInt isIndex; + UInt32 headerSizeRes; + + SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes); + + if (inStreamWrap.Res != S_OK) + return inStreamWrap.Res; + + if (res2 != SZ_OK) + { + if (res2 == SZ_ERROR_INPUT_EOF) + { + _stat2_decode_SRes = res2; + _stream = inStream; + _seqStream = inStream; + _isArc = true; + return S_OK; + } + + if (res2 == SZ_ERROR_ARCHIVE) + return S_FALSE; + // what codes are possible here ? + // ?? res2 == SZ_ERROR_MEM : is possible here + // ?? res2 == SZ_ERROR_UNSUPPORTED : is possible here + } + else if (!isIndex) + { + _firstBlockWasRead = true; + _firstBlock = block; + + unsigned numFilters = XzBlock_GetNumFilters(&block); + for (unsigned i = 0; i < numFilters; i++) + { + _methodsString.Add_Space_if_NotEmpty(); + AddMethodString(_methodsString, block.filters[i]); + } + } + } + } + + RINOK(InStream_GetSize_SeekToEnd(inStream, _stat.InSize)) + if (callback) + { + RINOK(callback->SetTotal(NULL, &_stat.InSize)) + } + + CSeekInStreamWrap inStreamImp; + + inStreamImp.Init(inStream); + + CLookToRead2_CPP lookStream; + + lookStream.Alloc(kInputBufSize); + + if (!lookStream.buf) + return E_OUTOFMEMORY; + + lookStream.realStream = &inStreamImp.vt; + LookToRead2_INIT(&lookStream) + + COpenCallbackWrap openWrap; + openWrap.Init(callback); + + CXzsCPP xzs; + Int64 startPosition; + SRes res = Xzs_ReadBackward(&xzs.p, &lookStream.vt, &startPosition, &openWrap.vt, &g_Alloc); + if (res == SZ_ERROR_PROGRESS) + return (openWrap.Res == S_OK) ? E_FAIL : openWrap.Res; + /* + if (res == SZ_ERROR_NO_ARCHIVE && xzs.p.num > 0) + res = SZ_OK; + */ + if (res == SZ_OK && startPosition == 0) + { + _stat_defined = true; + + _stat.OutSize = Xzs_GetUnpackSize(&xzs.p); + _stat.UnpackSize_Defined = true; + + _stat.NumStreams = xzs.p.num; + _stat.NumStreams_Defined = true; + + _stat.NumBlocks = Xzs_GetNumBlocks(&xzs.p); + _stat.NumBlocks_Defined = true; + + AddCheckString(_methodsString, xzs.p); + + const size_t numBlocks = (size_t)_stat.NumBlocks + 1; + const size_t bytesAlloc = numBlocks * sizeof(CBlockInfo); + + if (bytesAlloc / sizeof(CBlockInfo) == _stat.NumBlocks + 1) + { + _blocks = (CBlockInfo *)MyAlloc(bytesAlloc); + if (_blocks) + { + unsigned blockIndex = 0; + UInt64 unpackPos = 0; + + for (size_t si = xzs.p.num; si != 0;) + { + si--; + const CXzStream &str = xzs.p.streams[si]; + UInt64 packPos = str.startOffset + XZ_STREAM_HEADER_SIZE; + + for (size_t bi = 0; bi < str.numBlocks; bi++) + { + const CXzBlockSizes &bs = str.blocks[bi]; + const UInt64 packSizeAligned = bs.totalSize + ((0 - (unsigned)bs.totalSize) & 3); + + if (bs.unpackSize != 0) + { + if (blockIndex >= _stat.NumBlocks) + return E_FAIL; + + CBlockInfo &block = _blocks[blockIndex++]; + block.StreamFlags = str.flags; + block.PackSize = bs.totalSize; // packSizeAligned; + block.PackPos = packPos; + block.UnpackPos = unpackPos; + } + packPos += packSizeAligned; + unpackPos += bs.unpackSize; + if (_maxBlocksSize < bs.unpackSize) + _maxBlocksSize = bs.unpackSize; + } + } + + /* + if (blockIndex != _stat.NumBlocks) + { + // there are Empty blocks; + } + */ + if (_stat.OutSize != unpackPos) + return E_FAIL; + CBlockInfo &block = _blocks[blockIndex++]; + block.StreamFlags = 0; + block.PackSize = 0; + block.PackPos = 0; + block.UnpackPos = unpackPos; + _blocksArraySize = blockIndex; + } + } + } + else + { + res = SZ_OK; + } + + RINOK(SRes_to_Open_HRESULT(res)) + + _stream = inStream; + _seqStream = inStream; + _isArc = true; + return S_OK; +} + + + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + { + Close(); + return Open2(inStream, callback); + } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _seqStream = stream; + _isArc = true; + _needSeekToStart = false; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + XzStatInfo_Clear(&_stat); + XzStatInfo_Clear(&_stat2); + _stat_defined = false; + _stat2_defined = false; + _stat2_decode_SRes = SZ_OK; + + _isArc = false; + _needSeekToStart = false; + _firstBlockWasRead = false; + + _methodsString.Empty(); + _stream.Release(); + _seqStream.Release(); + + MyFree(_blocks); + _blocks = NULL; + _blocksArraySize = 0; + _maxBlocksSize = 0; + + return S_OK; +} + + +struct CXzUnpackerCPP2 +{ + Byte *InBuf; + // Byte *OutBuf; + CXzUnpacker p; + + CXzUnpackerCPP2(); + ~CXzUnpackerCPP2(); +}; + +CXzUnpackerCPP2::CXzUnpackerCPP2(): InBuf(NULL) + // , OutBuf(NULL) +{ + XzUnpacker_Construct(&p, &g_Alloc); +} + +CXzUnpackerCPP2::~CXzUnpackerCPP2() +{ + XzUnpacker_Free(&p); + MidFree(InBuf); + // MidFree(OutBuf); +} + + +Z7_CLASS_IMP_IInStream( + CInStream +) + + UInt64 _virtPos; +public: + UInt64 Size; + UInt64 _cacheStartPos; + size_t _cacheSize; + CByteBuffer _cache; + // UInt64 _startPos; + CXzUnpackerCPP2 xz; + + void InitAndSeek() + { + _virtPos = 0; + _cacheStartPos = 0; + _cacheSize = 0; + // _startPos = startPos; + } + + CMyComPtr2 _handlerSpec; + // ~CInStream(); +}; + +/* +CInStream::~CInStream() +{ + // _cache.Free(); +} +*/ + +static size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos) +{ + size_t left = 0, right = numBlocks; + for (;;) + { + size_t mid = (left + right) / 2; + if (mid == left) + return left; + if (pos < blocks[mid].UnpackPos) + right = mid; + else + left = mid; + } +} + + + +static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu, + ISequentialInStream *seqInStream, + unsigned streamFlags, + UInt64 packSize, // pure size from Index record, it doesn't include pad zeros + size_t unpackSize, Byte *dest + // , ICompressProgressInfo *progress + ) +{ + const size_t kInBufSize = (size_t)1 << 16; + + XzUnpacker_Init(&xzu.p); + + if (!xzu.InBuf) + { + xzu.InBuf = (Byte *)MidAlloc(kInBufSize); + if (!xzu.InBuf) + return E_OUTOFMEMORY; + } + + xzu.p.streamFlags = (UInt16)streamFlags; + XzUnpacker_PrepareToRandomBlockDecoding(&xzu.p); + + XzUnpacker_SetOutBuf(&xzu.p, dest, unpackSize); + + const UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + UInt64 packRem = packSizeAligned; + + UInt32 inSize = 0; + SizeT inPos = 0; + SizeT outPos = 0; + + HRESULT readRes = S_OK; + + for (;;) + { + if (inPos == inSize && readRes == S_OK) + { + inPos = 0; + inSize = 0; + UInt32 rem = kInBufSize; + if (rem > packRem) + rem = (UInt32)packRem; + if (rem != 0) + readRes = seqInStream->Read(xzu.InBuf, rem, &inSize); + } + + SizeT inLen = inSize - inPos; + SizeT outLen = unpackSize - outPos; + + ECoderStatus status; + + const SRes res = XzUnpacker_Code(&xzu.p, + // dest + outPos, + NULL, + &outLen, + xzu.InBuf + inPos, &inLen, + (inLen == 0), // srcFinished + CODER_FINISH_END, &status); + + // return E_OUTOFMEMORY; + // res = SZ_ERROR_CRC; + + if (res != SZ_OK) + { + if (res == SZ_ERROR_CRC) + return S_FALSE; + return SResToHRESULT(res); + } + + inPos += inLen; + outPos += outLen; + + packRem -= inLen; + + const BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); + + if ((inLen == 0 && outLen == 0) || blockFinished) + { + if (packRem != 0 || !blockFinished || unpackSize != outPos) + return S_FALSE; + if (XzUnpacker_GetPackSizeForIndex(&xzu.p) != packSize) + return S_FALSE; + return S_OK; + } + } +} + + +Z7_COM7F_IMF(CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + { + if (_virtPos >= Size) + return S_OK; // (Size == _virtPos) ? S_OK: E_FAIL; + { + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + } + + if (size == 0) + return S_OK; + + if (_virtPos < _cacheStartPos || _virtPos >= _cacheStartPos + _cacheSize) + { + const size_t bi = FindBlock(_handlerSpec->_blocks, _handlerSpec->_blocksArraySize, _virtPos); + const CBlockInfo &block = _handlerSpec->_blocks[bi]; + const UInt64 unpackSize = _handlerSpec->_blocks[bi + 1].UnpackPos - block.UnpackPos; + if (_cache.Size() < unpackSize) + return E_FAIL; + + _cacheSize = 0; + + RINOK(_handlerSpec->SeekToPackPos(block.PackPos)) + RINOK(DecodeBlock(xz, _handlerSpec->_seqStream, block.StreamFlags, block.PackSize, + (size_t)unpackSize, _cache)) + _cacheStartPos = block.UnpackPos; + _cacheSize = (size_t)unpackSize; + } + + { + const size_t offset = (size_t)(_virtPos - _cacheStartPos); + const size_t rem = _cacheSize - offset; + if (size > rem) + size = (UInt32)rem; + memcpy(data, _cache.ConstData() + offset, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + COM_TRY_END +} + + +Z7_COM7F_IMF(CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + + +static const UInt64 kMaxBlockSize_for_GetStream = (UInt64)1 << 40; + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + + *stream = NULL; + + if (index != 0) + return E_INVALIDARG; + + if (!_stat.UnpackSize_Defined + || _maxBlocksSize == 0 // 18.02 + || _maxBlocksSize > kMaxBlockSize_for_GetStream + || _maxBlocksSize != (size_t)_maxBlocksSize) + return S_FALSE; + + size_t memSize; + if (!NSystem::GetRamSize(memSize)) + memSize = (size_t)sizeof(size_t) << 28; + { + if (_maxBlocksSize > memSize / 4) + return S_FALSE; + } + + CMyComPtr2 spec; + spec.Create_if_Empty(); + spec->_cache.Alloc((size_t)_maxBlocksSize); + spec->_handlerSpec.SetFromCls(this); + // spec->_handler = (IInArchive *)this; + spec->Size = _stat.OutSize; + spec->InitAndSeek(); + + *stream = spec.Detach(); + return S_OK; + + COM_TRY_END +} + + +static Int32 Get_Extract_OperationResult(const NCompress::NXz::CDecoder &decoder) +{ + Int32 opRes; + SRes sres = decoder.MainDecodeSRes; + if (sres == SZ_ERROR_NO_ARCHIVE) // (!IsArc) + opRes = NExtract::NOperationResult::kIsNotArc; + else if (sres == SZ_ERROR_INPUT_EOF) // (UnexpectedEnd) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else if (decoder.Stat.DataAfterEnd) + opRes = NExtract::NOperationResult::kDataAfterEnd; + else if (sres == SZ_ERROR_CRC) // (CrcError) + opRes = NExtract::NOperationResult::kCRCError; + else if (sres == SZ_ERROR_UNSUPPORTED) // (Unsupported) + opRes = NExtract::NOperationResult::kUnsupportedMethod; + else if (sres == SZ_ERROR_ARCHIVE) // (HeadersError) + opRes = NExtract::NOperationResult::kDataError; + else if (sres == SZ_ERROR_DATA) // (DataError) + opRes = NExtract::NOperationResult::kDataError; + else if (sres != SZ_OK) + opRes = NExtract::NOperationResult::kDataError; + else + opRes = NExtract::NOperationResult::kOK; + return opRes; +} + + + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + + const CXzStatInfo *stat = GetStat(); + + if (stat) + RINOK(extractCallback->SetTotal(stat->InSize)) + + UInt64 currentTotalPacked = 0; + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(InStream_SeekToBegin(_stream)) + } + else + _needSeekToStart = true; + + + NCompress::NXz::CDecoder decoder; + + const HRESULT hres = Decode(decoder, _seqStream, realOutStream, lps); + + if (!decoder.MainDecodeSRes_wasUsed) + return hres == S_OK ? E_FAIL : hres; + + opRes = Get_Extract_OperationResult(decoder); + if (opRes == NExtract::NOperationResult::kOK + && hres != S_OK) + opRes = NExtract::NOperationResult::kDataError; + + // realOutStream.Release(); + } + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + + + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; + // *timeType = NFileTimeType::kUnix; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + if (numItems == 0) + { + CSeqOutStreamWrap seqOutStream; + seqOutStream.Init(outStream); + SRes res = Xz_EncodeEmpty(&seqOutStream.vt); + return SResToHRESULT(res); + } + + if (numItems != 1) + return E_INVALIDARG; + + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamSetRestriction, + setRestriction, outStream) + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt != VT_EMPTY) + if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 dataSize; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + dataSize = prop.uhVal.QuadPart; + } + + CMyComPtr2_Create encoder; + + CXzProps &xzProps = encoder->xzProps; + CLzma2EncProps &lzma2Props = xzProps.lzma2Props; + + lzma2Props.lzmaProps.level = GetLevel(); + + xzProps.reduceSize = dataSize; + /* + { + NCOM::CPropVariant prop = (UInt64)dataSize; + RINOK(encoder->SetCoderProp(NCoderPropID::kReduceSize, prop)) + } + */ + + #ifndef Z7_ST + +#ifdef _WIN32 + // we don't use chunk multithreading inside lzma2 stream. + // so we don't set xzProps.lzma2Props.numThreadGroups. + if (_numThreadGroups > 1) + xzProps.numThreadGroups = _numThreadGroups; +#endif + + UInt32 numThreads = _numThreads; + + const UInt32 kNumThreads_Max = 1024; + if (numThreads > kNumThreads_Max) + numThreads = kNumThreads_Max; + + if (!_numThreads_WasForced + && _numThreads >= 1 + && _memUsage_WasSet) + { + COneMethodInfo oneMethodInfo; + if (!_methods.IsEmpty()) + oneMethodInfo = _methods[0]; + + SetGlobalLevelTo(oneMethodInfo); + + const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0); + if (!numThreads_WasSpecifiedInMethod) + { + // here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already + CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads); + } + + // printf("\n====== GetProcessGroupAffinity : \n"); + + UInt64 cs = _numSolidBytes; + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO) + oneMethodInfo.AddProp_BlockSize2(cs); + cs = oneMethodInfo.Get_Xz_BlockSize(); + + if (cs != XZ_PROPS_BLOCK_SIZE_AUTO && + cs != XZ_PROPS_BLOCK_SIZE_SOLID) + { + const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads(); + const UInt32 numBlockThreads_Original = numThreads / lzmaThreads; + + if (numBlockThreads_Original > 1) + { + UInt32 numBlockThreads = numBlockThreads_Original; + { + const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); + for (; numBlockThreads > 1; numBlockThreads--) + { + UInt64 size = numBlockThreads * (lzmaMemUsage + cs); + UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; + if (cs < ((UInt32)1 << 26)) numPackChunks++; + if (cs < ((UInt32)1 << 24)) numPackChunks++; + if (cs < ((UInt32)1 << 22)) numPackChunks++; + size += numPackChunks * cs; + // printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20)); + if (size <= _memUsage_Compress) + break; + } + } + if (numBlockThreads == 0) + numBlockThreads = 1; + if (numBlockThreads != numBlockThreads_Original) + numThreads = numBlockThreads * lzmaThreads; + } + } + } + xzProps.numTotalThreads = (int)numThreads; + + #endif // Z7_ST + + + xzProps.blockSize = _numSolidBytes; + if (_numSolidBytes == XZ_PROPS_BLOCK_SIZE_SOLID) + { + xzProps.lzma2Props.blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + } + + RINOK(encoder->SetCheckSize(_crcSize)) + + { + CXzFilterProps &filter = xzProps.filterProps; + + if (_filterId == XZ_ID_Delta) + { + bool deltaDefined = false; + FOR_VECTOR (j, _filterMethod.Props) + { + const CProp &prop = _filterMethod.Props[j]; + if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4) + { + UInt32 delta = (UInt32)prop.Value.ulVal; + if (delta < 1 || delta > 256) + return E_INVALIDARG; + filter.delta = delta; + deltaDefined = true; + } + else + return E_INVALIDARG; + } + if (!deltaDefined) + return E_INVALIDARG; + } + filter.id = _filterId; + } + + FOR_VECTOR (i, _methods) + { + COneMethodInfo &m = _methods[i]; + + FOR_VECTOR (j, m.Props) + { + const CProp &prop = m.Props[j]; + RINOK(encoder->SetCoderProp(prop.Id, prop.Value)) + } + } + + { + 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)) + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + } + + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + opCallback, updateCallback) + if (opCallback) + { + RINOK(opCallback->ReportOperation(NEventIndexType::kInArcIndex, 0, NUpdateNotifyOp::kReplicate)) + } + + if (_stream) + { + const CXzStatInfo *stat = GetStat(); + if (stat) + { + RINOK(updateCallback->SetTotal(stat->InSize)) + } + RINOK(InStream_SeekToBegin(_stream)) + } + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + return NCompress::CopyStream(_stream, outStream, lps); + + COM_TRY_END +} + +#endif + + +HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + #ifndef Z7_EXTRACT_ONLY + + if (name[0] == L's') + { + const wchar_t *s = name.Ptr(1); + if (*s == 0) + { + bool useStr = false; + bool isSolid; + switch (value.vt) + { + case VT_EMPTY: isSolid = true; break; + case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break; + case VT_BSTR: + if (!StringToBool(value.bstrVal, isSolid)) + useStr = true; + break; + default: return E_INVALIDARG; + } + if (!useStr) + { + _numSolidBytes = (isSolid ? XZ_PROPS_BLOCK_SIZE_SOLID : XZ_PROPS_BLOCK_SIZE_AUTO); + return S_OK; + } + } + return ParseSizeString(s, value, + 0, // percentsBase + _numSolidBytes) ? S_OK: E_INVALIDARG; + } + + return CMultiMethodProps::SetProperty(name, value); + + #else + + { + HRESULT hres; + if (SetCommonProperty(name, value, hres)) + return hres; + } + + return E_INVALIDARG; + + #endif +} + + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + COM_TRY_BEGIN + + Init(); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetProperty(names[i], values[i])) + } + + #ifndef Z7_EXTRACT_ONLY + + if (!_filterMethod.MethodName.IsEmpty()) + { + unsigned k; + for (k = 0; k < Z7_ARRAY_SIZE(g_NamePairs); k++) + { + const CMethodNamePair &pair = g_NamePairs[k]; + if (StringsAreEqualNoCase_Ascii(_filterMethod.MethodName, pair.Name)) + { + _filterId = pair.Id; + break; + } + } + if (k == Z7_ARRAY_SIZE(g_NamePairs)) + return E_INVALIDARG; + } + + _methods.DeleteFrontal(GetNumEmptyMethods()); + if (_methods.Size() > 1) + return E_INVALIDARG; + if (_methods.Size() == 1) + { + AString &methodName = _methods[0].MethodName; + if (methodName.IsEmpty()) + methodName = k_LZMA2_Name; + else if ( + !methodName.IsEqualTo_Ascii_NoCase(k_LZMA2_Name) + && !methodName.IsEqualTo_Ascii_NoCase("xz")) + return E_INVALIDARG; + } + + #endif + + return S_OK; + + COM_TRY_END +} + + +REGISTER_ARC_IO( + "xz", "xz txz", "* .tar", 0xC, + XZ_SIG, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/XzHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/XzHandler.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/XzHandler.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,65 +1,11 @@ -// XzHandler.h - -#ifndef __XZ_HANDLER_H -#define __XZ_HANDLER_H - -#include "../../../C/Xz.h" - -#include "../ICoder.h" - -namespace NArchive { -namespace NXz { - -struct CXzUnpackerCPP -{ - Byte *InBuf; - Byte *OutBuf; - CXzUnpacker p; - - CXzUnpackerCPP(); - ~CXzUnpackerCPP(); -}; - -struct CStatInfo -{ - UInt64 InSize; - UInt64 OutSize; - UInt64 PhySize; - - UInt64 NumStreams; - UInt64 NumBlocks; - - bool UnpackSize_Defined; - - bool NumStreams_Defined; - bool NumBlocks_Defined; - - bool IsArc; - bool UnexpectedEnd; - bool DataAfterEnd; - bool Unsupported; - bool HeadersError; - bool DataError; - bool CrcError; - - CStatInfo() { Clear(); } - - void Clear(); -}; - -struct CDecoder: public CStatInfo -{ - CXzUnpackerCPP xzu; - SRes DecodeRes; // it's not HRESULT - - CDecoder(): DecodeRes(SZ_OK) {} - - /* Decode() can return ERROR code only if there is progress or stream error. - Decode() returns S_OK in case of xz decoding error, but DecodeRes and CStatInfo contain error information */ - HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress); - Int32 Get_Extract_OperationResult() const; -}; - -}} - -#endif +// XzHandler.h + +#ifndef ZIP7_INC_XZ_HANDLER_H +#define ZIP7_INC_XZ_HANDLER_H + +namespace NArchive { +namespace NXz { + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ZHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ZHandler.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZHandler.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -1,236 +1,225 @@ -// ZHandler.cpp - -#include "StdAfx.h" - -#include "../../Common/ComTry.h" - -#include "../../Windows/PropVariant.h" - -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/ZDecoder.h" - -#include "Common/DummyOutStream.h" - -namespace NArchive { -namespace NZ { - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _packSize; - // UInt64 _unpackSize; - // bool _unpackSize_Defined; -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) -}; - -static const Byte kProps[] = -{ - kpidPackSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO_Table - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = 1; - return S_OK; -} - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidPhySizeCantBeDetected: prop = true; break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) -{ - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - // case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break; - case kpidPackSize: prop = _packSize; break; - } - prop.Detach(value); - return S_OK; -} - -/* -class CCompressProgressInfoImp: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr Callback; -public: - MY_UNKNOWN_IMP1(ICompressProgressInfo) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - void Init(IArchiveOpenCallback *callback) { Callback = callback; } -}; - -STDMETHODIMP CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - if (Callback) - { - UInt64 files = 1; - return Callback->SetCompleted(&files, inSize); - } - return S_OK; -} -*/ - -API_FUNC_static_IsArc IsArc_Z(const Byte *p, size_t size) -{ - if (size < 3) - return k_IsArc_Res_NEED_MORE; - if (size > NCompress::NZ::kRecommendedCheckSize) - size = NCompress::NZ::kRecommendedCheckSize; - if (!NCompress::NZ::CheckStream(p, size)) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; -} -} - -STDMETHODIMP CHandler::Open(IInStream *stream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openCallback */) -{ - COM_TRY_BEGIN - { - // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); - Byte buffer[NCompress::NZ::kRecommendedCheckSize]; - // Byte buffer[1500]; - size_t size = NCompress::NZ::kRecommendedCheckSize; - // size = 700; - RINOK(ReadStream(stream, buffer, &size)); - if (!NCompress::NZ::CheckStream(buffer, size)) - return S_FALSE; - - UInt64 endPos; - RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); - _packSize = endPos; - - /* - bool fullCheck = false; - if (fullCheck) - { - CCompressProgressInfoImp *compressProgressSpec = new CCompressProgressInfoImp; - CMyComPtr compressProgress = compressProgressSpec; - compressProgressSpec->Init(openCallback); - - NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; - CMyComPtr decoder = decoderSpec; - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(NULL); - outStreamSpec->Init(); - decoderSpec->SetProp(_prop); - if (openCallback) - { - UInt64 files = 1; - RINOK(openCallback->SetTotal(&files, &endPos)); - } - RINOK(stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); - HRESULT res = decoder->Code(stream, outStream, NULL, NULL, openCallback ? compressProgress : NULL); - if (res != S_OK) - return S_FALSE; - _packSize = decoderSpec->PackSize; - } - */ - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _packSize = 0; - // _unpackSize_Defined = false; - _stream.Release(); - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - if (numItems == 0) - return S_OK; - if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) - return E_INVALIDARG; - - extractCallback->SetTotal(_packSize); - - UInt64 currentTotalPacked = 0; - - RINOK(extractCallback->SetCompleted(¤tTotalPacked)); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); - - if (!testMode && !realOutStream) - return S_OK; - - extractCallback->PrepareOperation(askMode); - - CDummyOutStream *outStreamSpec = new CDummyOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(); - realOutStream.Release(); - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, true); - - RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)); - - NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; - CMyComPtr decoder = decoderSpec; - - int opRes; - { - HRESULT result = decoder->Code(_stream, outStream, NULL, NULL, progress); - if (result == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else - { - RINOK(result); - opRes = NExtract::NOperationResult::kOK; - } - } - // _unpackSize = outStreamSpec->GetSize(); - // _unpackSize_Defined = true; - outStream.Release(); - return extractCallback->SetOperationResult(opRes); - COM_TRY_END -} - -static const Byte k_Signature[] = { 0x1F, 0x9D }; - -REGISTER_ARC_I( - "Z", "z taz", "* .tar", 5, - k_Signature, - 0, - 0, - IsArc_Z) - -}} +// ZHandler.cpp + +#include "StdAfx.h" + +#include "../../Common/ComTry.h" + +#include "../../Windows/PropVariant.h" + +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/ZDecoder.h" + +#include "Common/DummyOutStream.h" + +namespace NArchive { +namespace NZ { + +Z7_CLASS_IMP_CHandler_IInArchive_0 + + CMyComPtr _stream; + UInt64 _packSize; + // UInt64 _unpackSize; + // bool _unpackSize_Defined; +}; + +static const Byte kProps[] = +{ + kpidPackSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO_Table + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySizeCantBeDetected: prop = true; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + // case kpidSize: if (_unpackSize_Defined) prop = _unpackSize; break; + case kpidPackSize: prop = _packSize; break; + } + prop.Detach(value); + return S_OK; +} + +/* +Z7_CLASS_IMP_COM_1( + CCompressProgressInfoImp + , ICompressProgressInfo +) + CMyComPtr Callback; +public: + void Init(IArchiveOpenCallback *callback) { Callback = callback; } +}; + +Z7_COM7F_IMF(CCompressProgressInfoImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + outSize = outSize; + if (Callback) + { + const UInt64 files = 1; + return Callback->SetCompleted(&files, inSize); + } + return S_OK; +} +*/ + +API_FUNC_static_IsArc IsArc_Z(const Byte *p, size_t size) +{ + if (size < 3) + return k_IsArc_Res_NEED_MORE; + if (size > NCompress::NZ::kRecommendedCheckSize) + size = NCompress::NZ::kRecommendedCheckSize; + if (!NCompress::NZ::CheckStream(p, size)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, + const UInt64 * /* maxCheckStartPosition */, + IArchiveOpenCallback * /* openCallback */)) +{ + COM_TRY_BEGIN + { + // RINOK(InStream_GetPos(stream, _streamStartPosition)); + Byte buffer[NCompress::NZ::kRecommendedCheckSize]; + // Byte buffer[1500]; + size_t size = NCompress::NZ::kRecommendedCheckSize; + // size = 700; + RINOK(ReadStream(stream, buffer, &size)) + if (!NCompress::NZ::CheckStream(buffer, size)) + return S_FALSE; + + UInt64 endPos; + RINOK(InStream_GetSize_SeekToEnd(stream, endPos)) + _packSize = endPos; + + /* + bool fullCheck = false; + if (fullCheck) + { + CCompressProgressInfoImp *compressProgressSpec = new CCompressProgressInfoImp; + CMyComPtr compressProgress = compressProgressSpec; + compressProgressSpec->Init(openCallback); + + NCompress::NZ::CDecoder *decoderSpec = new NCompress::NZ::CDecoder; + CMyComPtr decoder = decoderSpec; + + CDummyOutStream *outStreamSpec = new CDummyOutStream; + CMyComPtr outStream(outStreamSpec); + outStreamSpec->SetStream(NULL); + outStreamSpec->Init(); + decoderSpec->SetProp(_prop); + if (openCallback) + { + UInt64 files = 1; + RINOK(openCallback->SetTotal(&files, &endPos)); + } + RINOK(InStream_SeekSet(stream, _streamStartPosition + kSignatureSize)) + HRESULT res = decoder->Code(stream, outStream, NULL, NULL, openCallback ? compressProgress : NULL); + if (res != S_OK) + return S_FALSE; + _packSize = decoderSpec->PackSize; + } + */ + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _packSize = 0; + // _unpackSize_Defined = false; + _stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + RINOK(extractCallback->SetTotal(_packSize)) + UInt64 currentTotalPacked = 0; + RINOK(extractCallback->SetCompleted(¤tTotalPacked)) + + int opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + + if (!testMode && !realOutStream) + return S_OK; + + RINOK(extractCallback->PrepareOperation(askMode)) + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(); + // realOutStream.Release(); + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + + RINOK(InStream_SeekToBegin(_stream)) + + NCompress::NZ::CDecoder decoder; + { + const HRESULT hres = decoder.Code(_stream, outStream, lps); + if (hres == S_FALSE) + opRes = NExtract::NOperationResult::kDataError; + else + { + RINOK(hres) + opRes = NExtract::NOperationResult::kOK; + } + } + // _unpackSize = outStreamSpec->GetSize(); + // _unpackSize_Defined = true; + // outStream.Release(); + } + return extractCallback->SetOperationResult(opRes); + COM_TRY_END +} + +static const Byte k_Signature[] = { 0x1F, 0x9D }; + +REGISTER_ARC_I( + "Z", "z taz", "* .tar", 5, + k_Signature, + 0, + 0, + IsArc_Z) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipAddCommon.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipAddCommon.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,363 +1,484 @@ -// ZipAddCommon.cpp - -#include "StdAfx.h" - -#include "../../../../C/7zCrc.h" -#include "../../../../C/Alloc.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../ICoder.h" -#include "../../IPassword.h" -#include "../../MyVersion.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/LzmaEncoder.h" -#include "../../Compress/PpmdZip.h" - -#include "../Common/InStreamWithCRC.h" - -#include "ZipAddCommon.h" -#include "ZipHeader.h" - -namespace NArchive { -namespace NZip { - -static const CMethodId kMethodId_ZipBase = 0x040100; -static const CMethodId kMethodId_BZip2 = 0x040202; - -static const UInt32 kLzmaPropsSize = 5; -static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize; - -class CLzmaEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ - NCompress::NLzma::CEncoder *EncoderSpec; - CMyComPtr Encoder; - Byte Header[kLzmaHeaderSize]; -public: - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - MY_UNKNOWN_IMP1(ICompressSetCoderProperties) -}; - -STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) -{ - if (!Encoder) - { - EncoderSpec = new NCompress::NLzma::CEncoder; - Encoder = EncoderSpec; - } - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(Header + 4, kLzmaPropsSize); - RINOK(EncoderSpec->SetCoderProperties(propIDs, props, numProps)); - RINOK(EncoderSpec->WriteCoderProperties(outStream)); - if (outStreamSpec->GetPos() != kLzmaPropsSize) - return E_FAIL; - Header[0] = MY_VER_MAJOR; - Header[1] = MY_VER_MINOR; - Header[2] = kLzmaPropsSize; - Header[3] = 0; - return S_OK; -} - -STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - RINOK(WriteStream(outStream, Header, kLzmaHeaderSize)); - return Encoder->Code(inStream, outStream, inSize, outSize, progress); -} - - -CAddCommon::CAddCommon(const CCompressionMethodMode &options): - _options(options), - _copyCoderSpec(NULL), - _cryptoStreamSpec(NULL), - _buf(NULL) - {} - -CAddCommon::~CAddCommon() -{ - MidFree(_buf); -} - -static const UInt32 kBufSize = ((UInt32)1 << 16); - -HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) -{ - if (!_buf) - { - _buf = (Byte *)MidAlloc(kBufSize); - if (!_buf) - return E_OUTOFMEMORY; - } - - UInt32 crc = CRC_INIT_VAL; - for (;;) - { - UInt32 processed; - RINOK(inStream->Read(_buf, kBufSize, &processed)); - if (processed == 0) - { - resultCRC = CRC_GET_DIGEST(crc); - return S_OK; - } - crc = CrcUpdate(crc, _buf, (size_t)processed); - } -} - -HRESULT CAddCommon::Compress( - DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, IOutStream *outStream, - UInt32 /* fileTime */, - ICompressProgressInfo *progress, CCompressingResult &opRes) -{ - if (!inStream) - { - // We can create empty stream here. But it was already implemented in caller code in 9.33+ - return E_INVALIDARG; - } - - // CSequentialInStreamWithCRC *inSecCrcStreamSpec = NULL; - CInStreamWithCRC *inCrcStreamSpec = NULL; - CMyComPtr inCrcStream; - { - CMyComPtr inStream2; - - inStream->QueryInterface(IID_IInStream, (void **)&inStream2); - - if (inStream2) - { - inCrcStreamSpec = new CInStreamWithCRC; - inCrcStream = inCrcStreamSpec; - inCrcStreamSpec->SetStream(inStream2); - inCrcStreamSpec->Init(); - } - else - { - // we don't support stdin, since stream from stdin can require 64-bit size header - return E_NOTIMPL; - /* - inSecCrcStreamSpec = new CSequentialInStreamWithCRC; - inCrcStream = inSecCrcStreamSpec; - inSecCrcStreamSpec->SetStream(inStream); - inSecCrcStreamSpec->Init(); - */ - } - } - - unsigned numTestMethods = _options.MethodSequence.Size(); - - if (numTestMethods > 1 && !inCrcStreamSpec) - numTestMethods = 1; - - UInt32 crc = 0; - bool crc_IsCalculated = false; - - Byte method = 0; - CFilterCoder::C_OutStream_Releaser outStreamReleaser; - opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Default; - opRes.FileTimeWasUsed = false; - - for (unsigned i = 0; i < numTestMethods; i++) - { - opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Default; - if (inCrcStreamSpec) - RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(outStream->SetSize(0)); - RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)); - - if (_options.PasswordIsDefined) - { - opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_ZipCrypto; - - if (!_cryptoStream) - { - _cryptoStreamSpec = new CFilterCoder(true); - _cryptoStream = _cryptoStreamSpec; - } - - if (_options.IsAesMode) - { - opRes.ExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_Aes; - if (!_cryptoStreamSpec->Filter) - { - _cryptoStreamSpec->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder; - _filterAesSpec->SetKeyMode(_options.AesKeyMode); - RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len())); - } - RINOK(_filterAesSpec->WriteHeader(outStream)); - } - else - { - if (!_cryptoStreamSpec->Filter) - { - _cryptoStreamSpec->Filter = _filterSpec = new NCrypto::NZip::CEncoder; - _filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len()); - } - - UInt32 check; - - // if (inCrcStreamSpec) - { - if (!crc_IsCalculated) - { - RINOK(CalcStreamCRC(inStream, crc)); - crc_IsCalculated = true; - RINOK(inCrcStreamSpec->Seek(0, STREAM_SEEK_SET, NULL)); - } - check = (crc >> 16); - } - /* - else - { - opRes.FileTimeWasUsed = true; - check = (fileTime & 0xFFFF); - } - */ - - RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check)); - } - - RINOK(_cryptoStreamSpec->SetOutStream(outStream)); - RINOK(_cryptoStreamSpec->InitEncoder()); - outStreamReleaser.FilterCoder = _cryptoStreamSpec; - } - - method = _options.MethodSequence[i]; - - switch (method) - { - case NFileHeader::NCompressionMethod::kStored: - { - if (_copyCoderSpec == NULL) - { - _copyCoderSpec = new NCompress::CCopyCoder; - _copyCoder = _copyCoderSpec; - } - CMyComPtr outStreamNew; - if (_options.PasswordIsDefined) - outStreamNew = _cryptoStream; - else - outStreamNew = outStream; - RINOK(_copyCoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); - break; - } - - default: - { - if (!_compressEncoder) - { - if (method == NFileHeader::NCompressionMethod::kLZMA) - { - _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_LZMA; - CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder(); - _compressEncoder = _lzmaEncoder; - } - else if (method == NFileHeader::NCompressionMethod::kPPMd) - { - _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd; - NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder(); - _compressEncoder = encoder; - } - else - { - CMethodId methodId; - switch (method) - { - case NFileHeader::NCompressionMethod::kBZip2: - methodId = kMethodId_BZip2; - _compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_BZip2; - break; - default: - _compressExtractVersion = ((method == NFileHeader::NCompressionMethod::kDeflated64) ? - NFileHeader::NCompressionMethod::kExtractVersion_Deflate64 : - NFileHeader::NCompressionMethod::kExtractVersion_Deflate); - methodId = kMethodId_ZipBase + method; - break; - } - RINOK(CreateCoder( - EXTERNAL_CODECS_LOC_VARS - methodId, true, _compressEncoder)); - if (!_compressEncoder) - return E_NOTIMPL; - - if (method == NFileHeader::NCompressionMethod::kDeflated || - method == NFileHeader::NCompressionMethod::kDeflated64) - { - } - else if (method == NFileHeader::NCompressionMethod::kBZip2) - { - } - } - { - CMyComPtr setCoderProps; - _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps); - if (setCoderProps) - { - RINOK(_options.MethodInfo.SetCoderProps(setCoderProps, - _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL)); - } - } - } - CMyComPtr outStreamNew; - if (_options.PasswordIsDefined) - outStreamNew = _cryptoStream; - else - outStreamNew = outStream; - if (_compressExtractVersion > opRes.ExtractVersion) - opRes.ExtractVersion = _compressExtractVersion; - RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)); - break; - } - } - - if (_options.PasswordIsDefined) - { - RINOK(_cryptoStreamSpec->OutStreamFinish()); - - if (_options.IsAesMode) - { - RINOK(_filterAesSpec->WriteFooter(outStream)); - } - } - - RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize)); - - // if (inCrcStreamSpec) - { - opRes.CRC = inCrcStreamSpec->GetCRC(); - opRes.UnpackSize = inCrcStreamSpec->GetSize(); - } - /* - else - { - opRes.CRC = inSecCrcStreamSpec->GetCRC(); - opRes.UnpackSize = inSecCrcStreamSpec->GetSize(); - } - */ - - if (_options.PasswordIsDefined) - { - if (opRes.PackSize < opRes.UnpackSize + - (_options.IsAesMode ? _filterAesSpec->GetAddPackSize() : NCrypto::NZip::kHeaderSize)) - break; - } - else if (opRes.PackSize < opRes.UnpackSize) - break; - } - - - opRes.Method = method; - return S_OK; -} - -}} +// ZipAddCommon.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" +#include "../../../../C/Alloc.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../../MyVersion.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/LzmaEncoder.h" +#include "../../Compress/PpmdZip.h" +#include "../../Compress/XzEncoder.h" + +#include "../Common/InStreamWithCRC.h" + +#include "ZipAddCommon.h" +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +using namespace NFileHeader; + + +static const unsigned kLzmaPropsSize = 5; +static const unsigned kLzmaHeaderSize = 4 + kLzmaPropsSize; + +Z7_CLASS_IMP_NOQIB_3( + CLzmaEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressSetCoderPropertiesOpt +) +public: + CMyComPtr2 Encoder; + Byte Header[kLzmaHeaderSize]; +}; + +Z7_COM7F_IMF(CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + Encoder.Create_if_Empty(); + CMyComPtr2_Create outStream; + outStream->Init(Header + 4, kLzmaPropsSize); + RINOK(Encoder->SetCoderProperties(propIDs, props, numProps)) + RINOK(Encoder->WriteCoderProperties(outStream)) + if (outStream->GetPos() != kLzmaPropsSize) + return E_FAIL; + Header[0] = MY_VER_MAJOR; + Header[1] = MY_VER_MINOR; + Header[2] = kLzmaPropsSize; + Header[3] = 0; + return S_OK; +} + +Z7_COM7F_IMF(CLzmaEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + return Encoder->SetCoderPropertiesOpt(propIDs, props, numProps); +} + +Z7_COM7F_IMF(CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + RINOK(WriteStream(outStream, Header, kLzmaHeaderSize)) + return Encoder.Interface()->Code(inStream, outStream, inSize, outSize, progress); +} + + +CAddCommon::CAddCommon(): + _isLzmaEos(false), + _buf(NULL) + {} + +void CAddCommon::SetOptions(const CCompressionMethodMode &options) +{ + _options = options; +} + +CAddCommon::~CAddCommon() +{ + MidFree(_buf); +} + +static const UInt32 kBufSize = ((UInt32)1 << 16); + +HRESULT CAddCommon::CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC) +{ + if (!_buf) + { + _buf = (Byte *)MidAlloc(kBufSize); + if (!_buf) + return E_OUTOFMEMORY; + } + + UInt32 crc = CRC_INIT_VAL; + for (;;) + { + UInt32 processed; + RINOK(inStream->Read(_buf, kBufSize, &processed)) + if (processed == 0) + { + resultCRC = CRC_GET_DIGEST(crc); + return S_OK; + } + crc = CrcUpdate(crc, _buf, (size_t)processed); + } +} + + +HRESULT CAddCommon::Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, UInt64 unpackSize, + CCompressingResult &opRes) const +{ + // We use Zip64, if unPackSize size is larger than 0xF8000000 to support + // cases when compressed size can be about 3% larger than uncompressed size + + const UInt32 kUnpackZip64Limit = 0xF8000000; + + opRes.UnpackSize = unpackSize; + opRes.PackSize = (UInt64)1 << 60; // we use big value to force Zip64 mode. + + if (unpackSize < kUnpackZip64Limit) + opRes.PackSize = (UInt32)0xFFFFFFFF - 1; // it will not use Zip64 for that size + + if (opRes.PackSize < unpackSize) + opRes.PackSize = unpackSize; + + const Byte method = _options.MethodSequence[0]; + + if (method == NCompressionMethod::kStore && !_options.Password_Defined) + opRes.PackSize = unpackSize; + + opRes.CRC = 0; + + opRes.LzmaEos = false; + + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; + opRes.DescriptorMode = outSeqMode; + + if (_options.Password_Defined) + { + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto; + if (_options.IsAesMode) + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes; + else + { + if (inSeqMode) + opRes.DescriptorMode = true; + } + } + + opRes.Method = method; + Byte ver = 0; + + switch (method) + { + case NCompressionMethod::kStore: break; + case NCompressionMethod::kDeflate: ver = NCompressionMethod::kExtractVersion_Deflate; break; + case NCompressionMethod::kDeflate64: ver = NCompressionMethod::kExtractVersion_Deflate64; break; + case NCompressionMethod::kXz : ver = NCompressionMethod::kExtractVersion_Xz; break; + case NCompressionMethod::kPPMd : ver = NCompressionMethod::kExtractVersion_PPMd; break; + case NCompressionMethod::kBZip2: ver = NCompressionMethod::kExtractVersion_BZip2; break; + case NCompressionMethod::kLZMA : + { + ver = NCompressionMethod::kExtractVersion_LZMA; + const COneMethodInfo *oneMethodMain = &_options._methods[0]; + opRes.LzmaEos = oneMethodMain->Get_Lzma_Eos(); + break; + } + default: break; + } + if (opRes.ExtractVersion < ver) + opRes.ExtractVersion = ver; + + return S_OK; +} + + +HRESULT CAddCommon::Compress( + DECL_EXTERNAL_CODECS_LOC_VARS + ISequentialInStream *inStream, IOutStream *outStream, + bool inSeqMode, bool outSeqMode, + UInt32 fileTime, + UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed, + ICompressProgressInfo *progress, CCompressingResult &opRes) +{ + // opRes.LzmaEos = false; + + if (!inStream) + { + // We can create empty stream here. But it was already implemented in caller code in 9.33+ + return E_INVALIDARG; + } + + CMyComPtr2_Create inCrcStream; + + CMyComPtr inStream2; + if (!inSeqMode) + { + inStream->QueryInterface(IID_IInStream, (void **)&inStream2); + if (!inStream2) + { + // inSeqMode = true; + // inSeqMode must be correct before + return E_FAIL; + } + } + + inCrcStream->SetStream(inStream); + inCrcStream->SetFullSize(expectedDataSize_IsConfirmed ? expectedDataSize : (UInt64)(Int64)-1); + // inCrcStream->Init(); + + unsigned numTestMethods = _options.MethodSequence.Size(); + // numTestMethods != 0 + + bool descriptorMode = outSeqMode; + + // ZipCrypto without descriptor requires additional reading pass for + // inStream to calculate CRC for password check field. + // The descriptor allows to use ZipCrypto check field without CRC (InfoZip's modification). + + if (!outSeqMode) + if (inSeqMode && _options.Password_Defined && !_options.IsAesMode) + descriptorMode = true; + opRes.DescriptorMode = descriptorMode; + + if (numTestMethods > 1) + if (inSeqMode || outSeqMode || !inStream2) + numTestMethods = 1; + + UInt32 crc = 0; + bool crc_IsCalculated = false; + + CFilterCoder::C_OutStream_Releaser outStreamReleaser; + // opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; + + for (unsigned i = 0; i < numTestMethods; i++) + { + inCrcStream->Init(); + + if (i != 0) + { + // if (inStream2) + { + RINOK(InStream_SeekToBegin(inStream2)) + } + RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(outStream->SetSize(0)) + } + + opRes.LzmaEos = false; + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Default; + + const Byte method = _options.MethodSequence[i]; + if (method == NCompressionMethod::kStore && descriptorMode) + { + // we still can create descriptor_mode archives with "Store" method, but they are not good for 100% + return E_NOTIMPL; + } + + bool needCode = true; + + if (_options.Password_Defined) + { + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_ZipCrypto; + + if (!_cryptoStream.IsDefined()) + _cryptoStream.SetFromCls(new CFilterCoder(true)); + + if (_options.IsAesMode) + { + opRes.ExtractVersion = NCompressionMethod::kExtractVersion_Aes; + if (!_cryptoStream->Filter) + { + _cryptoStream->Filter = _filterAesSpec = new NCrypto::NWzAes::CEncoder; + _filterAesSpec->SetKeyMode(_options.AesKeyMode); + RINOK(_filterAesSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len())) + } + RINOK(_filterAesSpec->WriteHeader(outStream)) + } + else + { + if (!_cryptoStream->Filter) + { + _cryptoStream->Filter = _filterSpec = new NCrypto::NZip::CEncoder; + _filterSpec->CryptoSetPassword((const Byte *)(const char *)_options.Password, _options.Password.Len()); + } + + UInt32 check; + + if (descriptorMode) + { + // it's Info-ZIP modification for stream_mode descriptor_mode (bit 3 of the general purpose bit flag is set) + check = (fileTime & 0xFFFF); + } + else + { + if (!crc_IsCalculated) + { + RINOK(CalcStreamCRC(inStream, crc)) + crc_IsCalculated = true; + RINOK(InStream_SeekToBegin(inStream2)) + inCrcStream->Init(); + } + check = (crc >> 16); + } + + RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check)) + } + + if (method == NCompressionMethod::kStore) + { + needCode = false; + RINOK(_cryptoStream->Code(inCrcStream, outStream, NULL, NULL, progress)) + } + else + { + RINOK(_cryptoStream->SetOutStream(outStream)) + RINOK(_cryptoStream->InitEncoder()) + outStreamReleaser.FilterCoder = _cryptoStream.ClsPtr(); + } + } + + if (needCode) + { + switch (method) + { + case NCompressionMethod::kStore: + { + _copyCoder.Create_if_Empty(); + CMyComPtr outStreamNew; + if (_options.Password_Defined) + outStreamNew = _cryptoStream; + else + outStreamNew = outStream; + RINOK(_copyCoder.Interface()->Code(inCrcStream, outStreamNew, NULL, NULL, progress)) + break; + } + + default: + { + if (!_compressEncoder) + { + CLzmaEncoder *_lzmaEncoder = NULL; + if (method == NCompressionMethod::kLZMA) + { + _compressExtractVersion = NCompressionMethod::kExtractVersion_LZMA; + _lzmaEncoder = new CLzmaEncoder(); + _compressEncoder = _lzmaEncoder; + } + else if (method == NCompressionMethod::kXz) + { + _compressExtractVersion = NCompressionMethod::kExtractVersion_Xz; + NCompress::NXz::CEncoder *encoder = new NCompress::NXz::CEncoder(); + _compressEncoder = encoder; + } + else if (method == NCompressionMethod::kPPMd) + { + _compressExtractVersion = NCompressionMethod::kExtractVersion_PPMd; + NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder(); + _compressEncoder = encoder; + } + else + { + CMethodId methodId; + switch (method) + { + case NCompressionMethod::kBZip2: + methodId = kMethodId_BZip2; + _compressExtractVersion = NCompressionMethod::kExtractVersion_BZip2; + break; + default: + _compressExtractVersion = ((method == NCompressionMethod::kDeflate64) ? + NCompressionMethod::kExtractVersion_Deflate64 : + NCompressionMethod::kExtractVersion_Deflate); + methodId = kMethodId_ZipBase + method; + break; + } + RINOK(CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + methodId, true, _compressEncoder)) + if (!_compressEncoder) + return E_NOTIMPL; + + if (method == NCompressionMethod::kDeflate || + method == NCompressionMethod::kDeflate64) + { + } + else if (method == NCompressionMethod::kBZip2) + { + } + } + { + CMyComPtr setCoderProps; + _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps); + if (setCoderProps) + { + if (!_options._methods.IsEmpty()) + { + COneMethodInfo *oneMethodMain = &_options._methods[0]; + + RINOK(oneMethodMain->SetCoderProps(setCoderProps, + _options.DataSizeReduce_Defined ? &_options.DataSizeReduce : NULL)) + } + } + } + if (method == NCompressionMethod::kLZMA) + _isLzmaEos = _lzmaEncoder->Encoder->IsWriteEndMark(); + } + + if (method == NCompressionMethod::kLZMA) + opRes.LzmaEos = _isLzmaEos; + + CMyComPtr outStreamNew; + if (_options.Password_Defined) + outStreamNew = _cryptoStream; + else + outStreamNew = outStream; + if (_compressExtractVersion > opRes.ExtractVersion) + opRes.ExtractVersion = _compressExtractVersion; + + { + CMyComPtr optProps; + _compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps); + if (optProps) + { + const PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)expectedDataSize; + RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + } + } + + try { + RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress)) + } catch (...) { return E_FAIL; } + break; + } + } // switch end + + if (_options.Password_Defined) + { + RINOK(_cryptoStream->OutStreamFinish()) + } + } + + if (_options.Password_Defined) + { + if (_options.IsAesMode) + { + RINOK(_filterAesSpec->WriteFooter(outStream)) + } + } + + RINOK(outStream->Seek(0, STREAM_SEEK_CUR, &opRes.PackSize)) + + { + opRes.CRC = inCrcStream->GetCRC(); + opRes.UnpackSize = inCrcStream->GetSize(); + opRes.Method = method; + } + + if (!inCrcStream->WasFinished()) + return E_FAIL; + + if (_options.Password_Defined) + { + if (opRes.PackSize < opRes.UnpackSize + + (_options.IsAesMode ? _filterAesSpec->GetAddPackSize() : NCrypto::NZip::kHeaderSize)) + break; + } + else if (opRes.PackSize < opRes.UnpackSize) + break; + } + + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipAddCommon.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipAddCommon.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipAddCommon.h 2023-12-19 21:00:00.000000000 +0000 @@ -1,62 +1,76 @@ -// ZipAddCommon.h - -#ifndef __ZIP_ADD_COMMON_H -#define __ZIP_ADD_COMMON_H - -#include "../../ICoder.h" -#include "../../IProgress.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/FilterCoder.h" - -#include "../../Compress/CopyCoder.h" - -#include "../../Crypto/ZipCrypto.h" -#include "../../Crypto/WzAes.h" - -#include "ZipCompressionMode.h" - -namespace NArchive { -namespace NZip { - -struct CCompressingResult -{ - UInt64 UnpackSize; - UInt64 PackSize; - UInt32 CRC; - UInt16 Method; - Byte ExtractVersion; - bool FileTimeWasUsed; -}; - -class CAddCommon -{ - CCompressionMethodMode _options; - NCompress::CCopyCoder *_copyCoderSpec; - CMyComPtr _copyCoder; - - CMyComPtr _compressEncoder; - Byte _compressExtractVersion; - - CFilterCoder *_cryptoStreamSpec; - CMyComPtr _cryptoStream; - - NCrypto::NZip::CEncoder *_filterSpec; - NCrypto::NWzAes::CEncoder *_filterAesSpec; - - Byte *_buf; - - HRESULT CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC); -public: - CAddCommon(const CCompressionMethodMode &options); - ~CAddCommon(); - HRESULT Compress( - DECL_EXTERNAL_CODECS_LOC_VARS - ISequentialInStream *inStream, IOutStream *outStream, - UInt32 fileTime, - ICompressProgressInfo *progress, CCompressingResult &operationResult); -}; - -}} - -#endif +// ZipAddCommon.h + +#ifndef ZIP7_INC_ZIP_ADD_COMMON_H +#define ZIP7_INC_ZIP_ADD_COMMON_H + +#include "../../ICoder.h" +#include "../../IProgress.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/FilterCoder.h" + +#include "../../Compress/CopyCoder.h" + +#include "../../Crypto/ZipCrypto.h" +#include "../../Crypto/WzAes.h" + +#include "ZipCompressionMode.h" + +namespace NArchive { +namespace NZip { + +struct CCompressingResult +{ + UInt64 UnpackSize; + UInt64 PackSize; + UInt32 CRC; + UInt16 Method; + Byte ExtractVersion; + bool DescriptorMode; + bool LzmaEos; + + CCompressingResult() + { + // for GCC: + UnpackSize = 0; + } +}; + +class CAddCommon MY_UNCOPYABLE +{ + CCompressionMethodMode _options; + CMyComPtr2 _copyCoder; + + CMyComPtr _compressEncoder; + Byte _compressExtractVersion; + bool _isLzmaEos; + + CMyComPtr2 _cryptoStream; + + NCrypto::NZip::CEncoder *_filterSpec; + NCrypto::NWzAes::CEncoder *_filterAesSpec; + + Byte *_buf; + + HRESULT CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC); +public: + // CAddCommon(const CCompressionMethodMode &options); + CAddCommon(); + void SetOptions(const CCompressionMethodMode &options); + ~CAddCommon(); + + HRESULT Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, UInt64 unpackSize, + CCompressingResult &opRes) const; + + HRESULT Compress( + DECL_EXTERNAL_CODECS_LOC_VARS + ISequentialInStream *inStream, IOutStream *outStream, + bool inSeqMode, bool outSeqMode, + UInt32 fileTime, + UInt64 expectedDataSize, bool expectedDataSize_IsConfirmed, + ICompressProgressInfo *progress, CCompressingResult &opRes); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipCompressionMode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipCompressionMode.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipCompressionMode.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipCompressionMode.h 2023-05-04 17:00:00.000000000 +0000 @@ -1,62 +1,62 @@ -// CompressionMode.h - -#ifndef __ZIP_COMPRESSION_MODE_H -#define __ZIP_COMPRESSION_MODE_H - -#include "../../../Common/MyString.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/System.h" -#endif - -#include "../Common/HandlerOut.h" - -namespace NArchive { -namespace NZip { - -struct CBaseProps -{ - CMethodProps MethodInfo; - Int32 Level; - - #ifndef _7ZIP_ST - UInt32 NumThreads; - bool NumThreadsWasChanged; - #endif - bool IsAesMode; - Byte AesKeyMode; - - void Init() - { - MethodInfo.Clear(); - Level = -1; - #ifndef _7ZIP_ST - NumThreads = NWindows::NSystem::GetNumberOfProcessors();; - NumThreadsWasChanged = false; - #endif - IsAesMode = false; - AesKeyMode = 3; - } -}; - -struct CCompressionMethodMode: public CBaseProps -{ - CRecordVector MethodSequence; - bool PasswordIsDefined; - AString Password; - - UInt64 _dataSizeReduce; - bool _dataSizeReduceDefined; - - bool IsRealAesMode() const { return PasswordIsDefined && IsAesMode; } - - CCompressionMethodMode(): PasswordIsDefined(false) - { - _dataSizeReduceDefined = false; - _dataSizeReduce = 0; - } -}; - -}} - -#endif +// CompressionMode.h + +#ifndef ZIP7_INC_ZIP_COMPRESSION_MODE_H +#define ZIP7_INC_ZIP_COMPRESSION_MODE_H + +#include "../../../Common/MyString.h" + +#ifndef Z7_ST +#include "../../../Windows/System.h" +#endif + +#include "../Common/HandlerOut.h" + +namespace NArchive { +namespace NZip { + +const CMethodId kMethodId_ZipBase = 0x040100; +const CMethodId kMethodId_BZip2 = 0x040202; + +struct CBaseProps: public CMultiMethodProps +{ + bool IsAesMode; + Byte AesKeyMode; + + void Init() + { + CMultiMethodProps::Init(); + + IsAesMode = false; + AesKeyMode = 3; + } +}; + +struct CCompressionMethodMode: public CBaseProps +{ + CRecordVector MethodSequence; + AString Password; // _Wipe + bool Password_Defined; + bool Force_SeqOutMode; + bool DataSizeReduce_Defined; + UInt64 DataSizeReduce; + + bool IsRealAesMode() const { return Password_Defined && IsAesMode; } + + CCompressionMethodMode() + { + Password_Defined = false; + Force_SeqOutMode = false; + DataSizeReduce_Defined = false; + DataSizeReduce = 0; + } + +#ifdef Z7_CPP_IS_SUPPORTED_default + CCompressionMethodMode(const CCompressionMethodMode &) = default; + CCompressionMethodMode& operator =(const CCompressionMethodMode &) = default; +#endif + ~CCompressionMethodMode() { Password.Wipe_and_Empty(); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandler.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.cpp 2024-05-12 12:00:00.000000000 +0000 @@ -1,1089 +1,1679 @@ -// ZipHandler.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../IPassword.h" - -#include "../../Common/FilterCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/LzmaDecoder.h" -#include "../../Compress/ImplodeDecoder.h" -#include "../../Compress/PpmdZip.h" -#include "../../Compress/ShrinkDecoder.h" - -#include "../../Crypto/WzAes.h" -#include "../../Crypto/ZipCrypto.h" -#include "../../Crypto/ZipStrong.h" - -#include "../Common/ItemNameUtils.h" -#include "../Common/OutStreamWithCRC.h" - -#include "../XzHandler.h" - -#include "ZipHandler.h" - -using namespace NWindows; - -namespace NArchive { -namespace NZip { - -static const CMethodId kMethodId_ZipBase = 0x040100; -static const CMethodId kMethodId_BZip2 = 0x040202; - -static const char * const kHostOS[] = -{ - "FAT" - , "AMIGA" - , "VMS" - , "Unix" - , "VM/CMS" - , "Atari" - , "HPFS" - , "Macintosh" - , "Z-System" - , "CP/M" - , "TOPS-20" - , "NTFS" - , "SMS/QDOS" - , "Acorn" - , "VFAT" - , "MVS" - , "BeOS" - , "Tandem" - , "OS/400" - , "OS/X" -}; - -static const char * const kMethods[] = -{ - "Store" - , "Shrink" - , "Reduced1" - , "Reduced2" - , "Reduced3" - , "Reduced4" - , "Implode" - , "Tokenizing" - , "Deflate" - , "Deflate64" - , "PKImploding" -}; - -static const char *kMethod_AES = "AES"; -static const char *kMethod_ZipCrypto = "ZipCrypto"; -static const char *kMethod_StrongCrypto = "StrongCrypto"; - -struct CIdToNamePair -{ - unsigned Id; - const char *Name; -}; - -static const CIdToNamePair k_MethodIdNamePairs[] = -{ - { NFileHeader::NCompressionMethod::kBZip2, "BZip2" }, - { NFileHeader::NCompressionMethod::kLZMA, "LZMA" }, - { NFileHeader::NCompressionMethod::kXz, "xz" }, - { NFileHeader::NCompressionMethod::kJpeg, "Jpeg" }, - { NFileHeader::NCompressionMethod::kWavPack, "WavPack" }, - { NFileHeader::NCompressionMethod::kPPMd, "PPMd" } -}; - -static const CIdToNamePair k_StrongCryptoPairs[] = -{ - { NStrongCrypto_AlgId::kDES, "DES" }, - { NStrongCrypto_AlgId::kRC2old, "RC2a" }, - { NStrongCrypto_AlgId::k3DES168, "3DES-168" }, - { NStrongCrypto_AlgId::k3DES112, "3DES-112" }, - { NStrongCrypto_AlgId::kAES128, "pkAES-128" }, - { NStrongCrypto_AlgId::kAES192, "pkAES-192" }, - { NStrongCrypto_AlgId::kAES256, "pkAES-256" }, - { NStrongCrypto_AlgId::kRC2, "RC2" }, - { NStrongCrypto_AlgId::kBlowfish, "Blowfish" }, - { NStrongCrypto_AlgId::kTwofish, "Twofish" }, - { NStrongCrypto_AlgId::kRC4, "RC4" } -}; - -const char *FindNameForId(const CIdToNamePair *pairs, unsigned num, unsigned id) -{ - for (unsigned i = 0; i < num; i++) - { - const CIdToNamePair &pair = pairs[i]; - if (id == pair.Id) - return pair.Name; - } - return NULL; -} - -static const Byte kProps[] = -{ - kpidPath, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - // kpidPosixAttrib, - kpidEncrypted, - kpidComment, - kpidCRC, - kpidMethod, - kpidHostOS, - kpidUnpackVer, - kpidVolumeIndex -}; - -static const Byte kArcProps[] = -{ - kpidEmbeddedStubSize, - kpidBit64, - kpidComment, - kpidTotalPhySize, - kpidIsVolume, - kpidVolumeIndex, - kpidNumVolumes -}; - -CHandler::CHandler() -{ - InitMethodProps(); -} - -static AString BytesToString(const CByteBuffer &data) -{ - AString s; - s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); - return s; -} - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; - case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break; - - case kpidPhySize: prop = m_Archive.GetPhySize(); break; - case kpidOffset: prop = m_Archive.GetOffset(); break; - - case kpidEmbeddedStubSize: - { - UInt64 stubSize = m_Archive.GetEmbeddedStubSize(); - if (stubSize != 0) - prop = stubSize; - break; - } - - case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.GetTotalSize(); break; - case kpidVolumeIndex: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.StartVolIndex; break; - case kpidIsVolume: if (m_Archive.IsMultiVol) prop = true; break; - case kpidNumVolumes: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.Streams.Size(); break; - - case kpidWarningFlags: - { - UInt32 v = 0; - // if (m_Archive.ExtraMinorError) v |= kpv_ErrorFlags_HeadersError; - if (m_Archive.HeadersWarning) v |= kpv_ErrorFlags_HeadersError; - if (v != 0) - prop = v; - break; - } - - case kpidError: - { - if (!m_Archive.Vols.MissingName.IsEmpty()) - { - UString s; - s.SetFromAscii("Missing volume : "); - s += m_Archive.Vols.MissingName; - prop = s; - } - break; - } - - case kpidErrorFlags: - { - UInt32 v = 0; - if (!m_Archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; - if (m_Archive.HeadersError) v |= kpv_ErrorFlags_HeadersError; - if (m_Archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; - if (m_Archive.ArcInfo.Base < 0) - { - /* We try to support case when we have sfx-zip with embedded stub, - but the stream has access only to zip part. - In that case we ignore UnavailableStart error. - maybe we must show warning in that case. */ - UInt64 stubSize = m_Archive.GetEmbeddedStubSize(); - if (stubSize < (UInt64)-m_Archive.ArcInfo.Base) - v |= kpv_ErrorFlags_UnavailableStart; - } - if (m_Archive.NoCentralDir) v |= kpv_ErrorFlags_UnconfirmedStart; - prop = v; - break; - } - - case kpidReadOnly: - { - if (m_Archive.IsOpen()) - if (!m_Archive.CanUpdate()) - prop = true; - break; - } - } - prop.Detach(value); - COM_TRY_END - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = m_Items.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - const CItemEx &item = m_Items[index]; - const CExtraBlock &extra = item.GetMainExtra(); - - switch (propID) - { - case kpidPath: - { - UString res; - item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage); - NItemName::ConvertToOSName2(res); - prop = res; - break; - } - - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidPackSize: prop = item.PackSize; break; - - case kpidTimeType: - { - FILETIME ft; - UInt32 unixTime; - UInt32 type; - if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft)) - type = NFileTimeType::kWindows; - else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) - type = NFileTimeType::kUnix; - else - type = NFileTimeType::kDOS; - prop = type; - break; - } - - case kpidCTime: - { - FILETIME ft; - if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) - prop = ft; - break; - } - - case kpidATime: - { - FILETIME ft; - if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) - prop = ft; - break; - } - - case kpidMTime: - { - FILETIME utc; - bool defined = true; - if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc)) - { - UInt32 unixTime = 0; - if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) - NTime::UnixTimeToFileTime(unixTime, utc); - else - { - FILETIME localFileTime; - if (item.Time == 0) - defined = false; - else if (!NTime::DosTimeToFileTime(item.Time, localFileTime) || - !LocalFileTimeToFileTime(&localFileTime, &utc)) - utc.dwHighDateTime = utc.dwLowDateTime = 0; - } - } - if (defined) - prop = utc; - break; - } - - case kpidAttrib: prop = item.GetWinAttrib(); break; - - case kpidPosixAttrib: - { - UInt32 attrib; - if (item.GetPosixAttrib(attrib)) - prop = attrib; - break; - } - - case kpidEncrypted: prop = item.IsEncrypted(); break; - - case kpidComment: - { - if (item.Comment.Size() != 0) - { - UString res; - item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage); - prop = res; - } - break; - } - - case kpidCRC: if (item.IsThereCrc()) prop = item.Crc; break; - - case kpidMethod: - { - unsigned id = item.Method; - AString m; - - if (item.IsEncrypted()) - { - if (id == NFileHeader::NCompressionMethod::kWzAES) - { - m += kMethod_AES; - CWzAesExtra aesField; - if (extra.GetWzAes(aesField)) - { - char s[16]; - s[0] = '-'; - ConvertUInt32ToString(((unsigned)aesField.Strength + 1) * 64 , s + 1); - m += s; - id = aesField.Method; - } - } - else if (item.IsStrongEncrypted()) - { - CStrongCryptoExtra f; - f.AlgId = 0; - if (extra.GetStrongCrypto(f)) - { - const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); - if (s) - m += s; - else - { - m += kMethod_StrongCrypto; - char temp[16]; - temp[0] = ':'; - ConvertUInt32ToString(f.AlgId, temp + 1); - m += temp; - } - if (f.CertificateIsUsed()) - m += "-Cert"; - } - else - m += kMethod_StrongCrypto; - } - else - m += kMethod_ZipCrypto; - m += ' '; - } - - { - char temp[16]; - const char *s = NULL; - if (id < ARRAY_SIZE(kMethods)) - s = kMethods[id]; - else - { - s = FindNameForId(k_MethodIdNamePairs, ARRAY_SIZE(k_MethodIdNamePairs), id); - if (!s) - { - ConvertUInt32ToString(id, temp); - s = temp; - } - } - m += s; - if (id == NFileHeader::NCompressionMethod::kLZMA && item.IsLzmaEOS()) - m += ":EOS"; - } - - prop = m; - break; - } - - case kpidHostOS: - { - Byte hostOS = item.GetHostOS(); - char temp[16]; - const char *s = NULL; - if (hostOS < ARRAY_SIZE(kHostOS)) - s = kHostOS[hostOS]; - else - { - ConvertUInt32ToString(hostOS, temp); - s = temp; - } - prop = s; - break; - } - - case kpidUnpackVer: - prop = (UInt32)item.ExtractVersion.Version; - break; - - case kpidVolumeIndex: - prop = item.Disk; - break; - } - - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) -{ - COM_TRY_BEGIN - try - { - Close(); - HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items); - if (res != S_OK) - { - m_Items.Clear(); - m_Archive.ClearRefs(); - } - return res; - } - catch(...) { Close(); throw; } - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - m_Items.Clear(); - m_Archive.Close(); - return S_OK; -} - - -class CLzmaDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - NCompress::NLzma::CDecoder *DecoderSpec; - CMyComPtr Decoder; -public: - CLzmaDecoder(); - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - MY_UNKNOWN_IMP -}; - -CLzmaDecoder::CLzmaDecoder() -{ - DecoderSpec = new NCompress::NLzma::CDecoder; - Decoder = DecoderSpec; -} - -HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - Byte buf[9]; - RINOK(ReadStream_FALSE(inStream, buf, 9)); - if (buf[2] != 5 || buf[3] != 0) - return E_NOTIMPL; - RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, 5)); - return Decoder->Code(inStream, outStream, NULL, outSize, progress); -} - - -class CXzDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - NArchive::NXz::CDecoder _decoder; -public: - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - MY_UNKNOWN_IMP -}; - -HRESULT CXzDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - RINOK(_decoder.Decode(inStream, outStream, progress)); - Int32 opRes = _decoder.Get_Extract_OperationResult(); - if (opRes == NExtract::NOperationResult::kUnsupportedMethod) - return E_NOTIMPL; - if (opRes != NExtract::NOperationResult::kOK) - return S_FALSE; - return S_OK; -} - - -struct CMethodItem -{ - unsigned ZipMethod; - CMyComPtr Coder; -}; - - - -class CZipDecoder -{ - NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; - NCrypto::NZipStrong::CDecoder *_pkAesDecoderSpec; - NCrypto::NWzAes::CDecoder *_wzAesDecoderSpec; - - CMyComPtr _zipCryptoDecoder; - CMyComPtr _pkAesDecoder; - CMyComPtr _wzAesDecoder; - - CFilterCoder *filterStreamSpec; - CMyComPtr filterStream; - CMyComPtr getTextPassword; - CObjectVector methodItems; - -public: - CZipDecoder(): - _zipCryptoDecoderSpec(0), - _pkAesDecoderSpec(0), - _wzAesDecoderSpec(0), - filterStreamSpec(0) {} - - HRESULT Decode( - DECL_EXTERNAL_CODECS_LOC_VARS - CInArchive &archive, const CItemEx &item, - ISequentialOutStream *realOutStream, - IArchiveExtractCallback *extractCallback, - ICompressProgressInfo *compressProgress, - #ifndef _7ZIP_ST - UInt32 numThreads, - #endif - Int32 &res); -}; - - -static HRESULT SkipStreamData(ISequentialInStream *stream, UInt64 size) -{ - const size_t kBufSize = 1 << 12; - Byte buf[kBufSize]; - for (;;) - { - if (size == 0) - return S_OK; - size_t curSize = kBufSize; - if (curSize > size) - curSize = (size_t)size; - RINOK(ReadStream_FALSE(stream, buf, curSize)); - size -= curSize; - } -} - - -HRESULT CZipDecoder::Decode( - DECL_EXTERNAL_CODECS_LOC_VARS - CInArchive &archive, const CItemEx &item, - ISequentialOutStream *realOutStream, - IArchiveExtractCallback *extractCallback, - ICompressProgressInfo *compressProgress, - #ifndef _7ZIP_ST - UInt32 numThreads, - #endif - Int32 &res) -{ - res = NExtract::NOperationResult::kDataError; - CFilterCoder::C_InStream_Releaser inStreamReleaser; - - bool needCRC = true; - bool wzAesMode = false; - bool pkAesMode = false; - unsigned id = item.Method; - - if (item.IsEncrypted()) - { - if (item.IsStrongEncrypted()) - { - CStrongCryptoExtra f; - if (item.CentralExtra.GetStrongCrypto(f)) - { - pkAesMode = true; - } - if (!pkAesMode) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - return S_OK; - } - } - if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES) - { - CWzAesExtra aesField; - if (item.GetMainExtra().GetWzAes(aesField)) - { - wzAesMode = true; - needCRC = aesField.NeedCrc(); - } - } - } - - COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; - CMyComPtr outStream = outStreamSpec; - outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(needCRC); - - CMyComPtr packStream; - - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(limitedStreamSpec); - - { - UInt64 packSize = item.PackSize; - if (wzAesMode) - { - if (packSize < NCrypto::NWzAes::kMacSize) - return S_OK; - packSize -= NCrypto::NWzAes::kMacSize; - } - RINOK(archive.GetItemStream(item, true, packStream)); - if (!packStream) - { - res = NExtract::NOperationResult::kUnavailable; - return S_OK; - } - limitedStreamSpec->SetStream(packStream); - limitedStreamSpec->Init(packSize); - } - - CMyComPtr cryptoFilter; - - if (item.IsEncrypted()) - { - if (wzAesMode) - { - CWzAesExtra aesField; - if (!item.GetMainExtra().GetWzAes(aesField)) - return S_OK; - id = aesField.Method; - if (!_wzAesDecoder) - { - _wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder; - _wzAesDecoder = _wzAesDecoderSpec; - } - cryptoFilter = _wzAesDecoder; - if (!_wzAesDecoderSpec->SetKeyMode(aesField.Strength)) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - return S_OK; - } - } - else if (pkAesMode) - { - if (!_pkAesDecoder) - { - _pkAesDecoderSpec = new NCrypto::NZipStrong::CDecoder; - _pkAesDecoder = _pkAesDecoderSpec; - } - cryptoFilter = _pkAesDecoder; - } - else - { - if (!_zipCryptoDecoder) - { - _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder; - _zipCryptoDecoder = _zipCryptoDecoderSpec; - } - cryptoFilter = _zipCryptoDecoder; - } - - CMyComPtr cryptoSetPassword; - RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); - - if (!getTextPassword) - extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); - - if (getTextPassword) - { - CMyComBSTR password; - RINOK(getTextPassword->CryptoGetTextPassword(&password)); - AString charPassword; - if (password) - { - if (wzAesMode || pkAesMode) - { - charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP); - /* - for (unsigned i = 0;; i++) - { - wchar_t c = password[i]; - if (c == 0) - break; - if (c >= 0x80) - { - res = NExtract::NOperationResult::kDataError; - return S_OK; - } - charPassword += (char)c; - } - */ - } - else - { - /* pkzip25 / WinZip / Windows probably use ANSI for some files - We use OEM for compatibility with previous versions of 7-Zip? */ - charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); - } - } - HRESULT result = cryptoSetPassword->CryptoSetPassword( - (const Byte *)(const char *)charPassword, charPassword.Len()); - if (result != S_OK) - return S_OK; - } - else - { - RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); - } - } - - unsigned m; - for (m = 0; m < methodItems.Size(); m++) - if (methodItems[m].ZipMethod == id) - break; - - if (m == methodItems.Size()) - { - CMethodItem mi; - mi.ZipMethod = id; - if (id == NFileHeader::NCompressionMethod::kStored) - mi.Coder = new NCompress::CCopyCoder; - else if (id == NFileHeader::NCompressionMethod::kShrunk) - mi.Coder = new NCompress::NShrink::CDecoder; - else if (id == NFileHeader::NCompressionMethod::kImploded) - mi.Coder = new NCompress::NImplode::NDecoder::CCoder; - else if (id == NFileHeader::NCompressionMethod::kLZMA) - mi.Coder = new CLzmaDecoder; - else if (id == NFileHeader::NCompressionMethod::kXz) - mi.Coder = new CXzDecoder; - else if (id == NFileHeader::NCompressionMethod::kPPMd) - mi.Coder = new NCompress::NPpmdZip::CDecoder(true); - else - { - CMethodId szMethodID; - if (id == NFileHeader::NCompressionMethod::kBZip2) - szMethodID = kMethodId_BZip2; - else - { - if (id > 0xFF) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - return S_OK; - } - szMethodID = kMethodId_ZipBase + (Byte)id; - } - - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder)); - - if (mi.Coder == 0) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - return S_OK; - } - } - m = methodItems.Add(mi); - } - - ICompressCoder *coder = methodItems[m].Coder; - - { - CMyComPtr setDecoderProperties; - coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); - if (setDecoderProperties) - { - Byte properties = (Byte)item.Flags; - RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); - } - } - - #ifndef _7ZIP_ST - { - CMyComPtr setCoderMt; - coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); - if (setCoderMt) - { - RINOK(setCoderMt->SetNumberOfThreads(numThreads)); - } - } - #endif - - { - HRESULT result = S_OK; - CMyComPtr inStreamNew; - if (item.IsEncrypted()) - { - if (!filterStream) - { - filterStreamSpec = new CFilterCoder(false); - filterStream = filterStreamSpec; - } - - filterStreamSpec->Filter = cryptoFilter; - - if (wzAesMode) - { - result = _wzAesDecoderSpec->ReadHeader(inStream); - if (result == S_OK) - { - if (!_wzAesDecoderSpec->Init_and_CheckPassword()) - { - res = NExtract::NOperationResult::kWrongPassword; - return S_OK; - } - } - } - else if (pkAesMode) - { - result =_pkAesDecoderSpec->ReadHeader(inStream, item.Crc, item.Size); - if (result == S_OK) - { - bool passwOK; - result = _pkAesDecoderSpec->Init_and_CheckPassword(passwOK); - if (result == S_OK && !passwOK) - { - res = NExtract::NOperationResult::kWrongPassword; - return S_OK; - } - } - } - else - { - result = _zipCryptoDecoderSpec->ReadHeader(inStream); - if (result == S_OK) - { - _zipCryptoDecoderSpec->Init_BeforeDecode(); - - /* Info-ZIP modification to ZipCrypto format: - if bit 3 of the general purpose bit flag is set, - it uses high byte of 16-bit File Time. - Info-ZIP code probably writes 2 bytes of File Time. - We check only 1 byte. */ - - // UInt32 v1 = GetUi16(_zipCryptoDecoderSpec->_header + NCrypto::NZip::kHeaderSize - 2); - // UInt32 v2 = (item.HasDescriptor() ? (item.Time & 0xFFFF) : (item.Crc >> 16)); - - Byte v1 = _zipCryptoDecoderSpec->_header[NCrypto::NZip::kHeaderSize - 1]; - Byte v2 = (Byte)(item.HasDescriptor() ? (item.Time >> 8) : (item.Crc >> 24)); - - if (v1 != v2) - { - res = NExtract::NOperationResult::kWrongPassword; - return S_OK; - } - } - } - - if (result == S_OK) - { - inStreamReleaser.FilterCoder = filterStreamSpec; - RINOK(filterStreamSpec->SetInStream(inStream)); - - /* IFilter::Init() does nothing in all zip crypto filters. - So we can call any Initialize function in CFilterCoder. */ - - RINOK(filterStreamSpec->Init_NoSubFilterInit()); - // RINOK(filterStreamSpec->SetOutStreamSize(NULL)); - - inStreamNew = filterStream; - } - } - else - inStreamNew = inStream; - - if (result == S_OK) - result = coder->Code(inStreamNew, outStream, NULL, &item.Size, compressProgress); - - if (result == S_FALSE) - return S_OK; - - if (result == E_NOTIMPL) - { - res = NExtract::NOperationResult::kUnsupportedMethod; - return S_OK; - } - - RINOK(result); - } - - bool crcOK = true; - bool authOk = true; - if (needCRC) - crcOK = (outStreamSpec->GetCRC() == item.Crc); - - if (wzAesMode) - { - const UInt64 rem = limitedStreamSpec->GetRem(); - if (rem != 0) - if (SkipStreamData(inStream, rem) != S_OK) - authOk = false; - - limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize); - if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) - authOk = false; - } - - res = ((crcOK && authOk) ? - NExtract::NOperationResult::kOK : - NExtract::NOperationResult::kCRCError); - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - CZipDecoder myDecoder; - UInt64 totalUnPacked = 0, totalPacked = 0; - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = m_Items.Size(); - if (numItems == 0) - return S_OK; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; - totalUnPacked += item.Size; - totalPacked += item.PackSize; - } - RINOK(extractCallback->SetTotal(totalUnPacked)); - - UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - for (i = 0; i < numItems; i++, - currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - currentItemUnPacked = 0; - currentItemPacked = 0; - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - RINOK(lps->SetCur()); - - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - - CItemEx item = m_Items[index]; - bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item); - bool skip = !isLocalOffsetOK && !item.IsDir(); - if (skip) - askMode = NExtract::NAskMode::kSkip; - - currentItemUnPacked = item.Size; - currentItemPacked = item.PackSize; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - - if (!isLocalOffsetOK) - { - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)); - continue; - } - - if (!item.FromLocal) - { - bool isAvail = true; - HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail); - if (res == S_FALSE) - { - if (item.IsDir() || realOutStream || testMode) - { - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult( - isAvail ? - NExtract::NOperationResult::kHeadersError : - NExtract::NOperationResult::kUnavailable)); - } - continue; - } - RINOK(res); - } - - if (item.IsDir()) - { - // if (!testMode) - { - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - } - continue; - } - - if (!testMode && !realOutStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - - Int32 res; - HRESULT hres = myDecoder.Decode( - EXTERNAL_CODECS_VARS - m_Archive, item, realOutStream, extractCallback, - progress, - #ifndef _7ZIP_ST - _props.NumThreads, - #endif - res); - RINOK(hres); - realOutStream.Release(); - - RINOK(extractCallback->SetOperationResult(res)) - } - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - return lps->SetCur(); - COM_TRY_END -} - -IMPL_ISetCompressCodecsInfo - -}} +// ZipHandler.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantUtils.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../IPassword.h" + +#include "../../Common/FilterCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" +#ifndef Z7_ZIP_LZFSE_DISABLE +#include "../../Compress/LzfseDecoder.h" +#endif +#include "../../Compress/LzmaDecoder.h" +#include "../../Compress/ImplodeDecoder.h" +#include "../../Compress/PpmdZip.h" +#include "../../Compress/ShrinkDecoder.h" +#include "../../Compress/XzDecoder.h" +#include "../../Compress/ZstdDecoder.h" + +#include "../../Crypto/WzAes.h" +#include "../../Crypto/ZipCrypto.h" +#include "../../Crypto/ZipStrong.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/OutStreamWithCRC.h" + + +#include "ZipHandler.h" + +using namespace NWindows; + +namespace NArchive { +namespace NZip { + +static const char * const kHostOS[] = +{ + "FAT" + , "AMIGA" + , "VMS" + , "Unix" + , "VM/CMS" + , "Atari" + , "HPFS" + , "Macintosh" + , "Z-System" + , "CP/M" + , "TOPS-20" + , "NTFS" + , "SMS/QDOS" + , "Acorn" + , "VFAT" + , "MVS" + , "BeOS" + , "Tandem" + , "OS/400" + , "OS/X" +}; + + +const char * const kMethodNames1[kNumMethodNames1] = +{ + "Store" + , "Shrink" + , "Reduce1" + , "Reduce2" + , "Reduce3" + , "Reduce4" + , "Implode" + , NULL // "Tokenize" + , "Deflate" + , "Deflate64" + , "PKImploding" + , NULL + , "BZip2" + , NULL + , "LZMA" + /* + , NULL + , NULL + , NULL + , NULL + , NULL + , "zstd-pk" // deprecated + */ +}; + + +const char * const kMethodNames2[kNumMethodNames2] = +{ + "zstd" + , "MP3" + , "xz" + , "Jpeg" + , "WavPack" + , "PPMd" + , "LZFSE" // , "WzAES" +}; + +#define kMethod_AES "AES" +#define kMethod_ZipCrypto "ZipCrypto" +#define kMethod_StrongCrypto "StrongCrypto" + +static const char * const kDeflateLevels[4] = +{ + "Normal" + , "Maximum" + , "Fast" + , "Fastest" +}; + + +static const CUInt32PCharPair g_HeaderCharacts[] = +{ + { 0, "Encrypt" }, + { 3, "Descriptor" }, + // { 4, "Enhanced" }, + // { 5, "Patched" }, + { 6, kMethod_StrongCrypto }, + { 11, "UTF8" }, + { 14, "Alt" } +}; + +struct CIdToNamePair +{ + unsigned Id; + const char *Name; +}; + + +static const CIdToNamePair k_StrongCryptoPairs[] = +{ + { NStrongCrypto_AlgId::kDES, "DES" }, + { NStrongCrypto_AlgId::kRC2old, "RC2a" }, + { NStrongCrypto_AlgId::k3DES168, "3DES-168" }, + { NStrongCrypto_AlgId::k3DES112, "3DES-112" }, + { NStrongCrypto_AlgId::kAES128, "pkAES-128" }, + { NStrongCrypto_AlgId::kAES192, "pkAES-192" }, + { NStrongCrypto_AlgId::kAES256, "pkAES-256" }, + { NStrongCrypto_AlgId::kRC2, "RC2" }, + { NStrongCrypto_AlgId::kBlowfish, "Blowfish" }, + { NStrongCrypto_AlgId::kTwofish, "Twofish" }, + { NStrongCrypto_AlgId::kRC4, "RC4" } +}; + +static const char *FindNameForId(const CIdToNamePair *pairs, unsigned num, unsigned id) +{ + for (unsigned i = 0; i < num; i++) + { + const CIdToNamePair &pair = pairs[i]; + if (id == pair.Id) + return pair.Name; + } + return NULL; +} + + +static const Byte kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidMTime, + kpidCTime, + kpidATime, + kpidAttrib, + // kpidPosixAttrib, + kpidEncrypted, + kpidComment, + kpidCRC, + kpidMethod, + kpidCharacts, + kpidHostOS, + kpidUnpackVer, + kpidVolumeIndex, + kpidOffset + // kpidIsAltStream + // , kpidChangeTime // for debug + // , 255 // for debug +}; + +static const Byte kArcProps[] = +{ + kpidEmbeddedStubSize, + kpidBit64, + kpidComment, + kpidCharacts, + kpidTotalPhySize, + kpidIsVolume, + kpidVolumeIndex, + kpidNumVolumes +}; + +CHandler::CHandler() +{ + InitMethodProps(); +} + +static AString BytesToString(const CByteBuffer &data) +{ + AString s; + s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); + return s; +} + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; + case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break; + + case kpidPhySize: prop = m_Archive.GetPhySize(); break; + case kpidOffset: prop = m_Archive.GetOffset(); break; + + case kpidEmbeddedStubSize: + { + UInt64 stubSize = m_Archive.GetEmbeddedStubSize(); + if (stubSize != 0) + prop = stubSize; + break; + } + + case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.TotalBytesSize; break; + case kpidVolumeIndex: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.StartVolIndex; break; + case kpidIsVolume: if (m_Archive.IsMultiVol) prop = true; break; + case kpidNumVolumes: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.Streams.Size(); break; + + case kpidCharacts: + { + AString s; + + if (m_Archive.LocalsWereRead) + { + s.Add_OptSpaced("Local"); + + if (m_Archive.LocalsCenterMerged) + s.Add_OptSpaced("Central"); + } + + if (m_Archive.IsZip64) + s.Add_OptSpaced("Zip64"); + + if (m_Archive.IsCdUnsorted) + s.Add_OptSpaced("Unsorted_CD"); + + if (m_Archive.IsApk) + s.Add_OptSpaced("apk"); + + if (m_Archive.ExtraMinorError) + s.Add_OptSpaced("Minor_Extra_ERROR"); + + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidWarningFlags: + { + UInt32 v = 0; + // if (m_Archive.ExtraMinorError) v |= kpv_ErrorFlags_HeadersError; + if (m_Archive.HeadersWarning) v |= kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + + case kpidWarning: + { + AString s; + if (m_Archive.Overflow32bit) + s.Add_OptSpaced("32-bit overflow in headers"); + if (m_Archive.Cd_NumEntries_Overflow_16bit) + s.Add_OptSpaced("16-bit overflow for number of files in headers"); + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidError: + { + if (!m_Archive.Vols.MissingName.IsEmpty()) + { + UString s("Missing volume : "); + s += m_Archive.Vols.MissingName; + prop = s; + } + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!m_Archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; + if (m_Archive.HeadersError) v |= kpv_ErrorFlags_HeadersError; + if (m_Archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; + if (m_Archive.ArcInfo.Base < 0) + { + /* We try to support case when we have sfx-zip with embedded stub, + but the stream has access only to zip part. + In that case we ignore UnavailableStart error. + maybe we must show warning in that case. */ + UInt64 stubSize = m_Archive.GetEmbeddedStubSize(); + if (stubSize < (UInt64)-m_Archive.ArcInfo.Base) + v |= kpv_ErrorFlags_UnavailableStart; + } + if (m_Archive.NoCentralDir) v |= kpv_ErrorFlags_UnconfirmedStart; + prop = v; + break; + } + + case kpidReadOnly: + { + if (m_Archive.IsOpen()) + if (!m_Archive.CanUpdate()) + prop = true; + break; + } + + // case kpidIsAltStream: prop = true; break; + default: break; + } + return prop.Detach(value); + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = m_Items.Size(); + 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; + } +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + const CItemEx &item = m_Items[index]; + const CExtraBlock &extra = item.GetMainExtra(); + + switch (propID) + { + case kpidPath: + { + UString res; + item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage); + NItemName::ReplaceToOsSlashes_Remove_TailSlash(res, + item.Is_MadeBy_Unix() // useBackslashReplacement + ); + /* + if (item.ParentOfAltStream >= 0) + { + const CItemEx &prevItem = m_Items[item.ParentOfAltStream]; + UString prevName; + prevItem.GetUnicodeString(prevName, prevItem.Name, false, _forceCodePage, _specifiedCodePage); + NItemName::ReplaceToOsSlashes_Remove_TailSlash(prevName); + if (res.IsPrefixedBy(prevName)) + if (IsString1PrefixedByString2(res.Ptr(prevName.Len()), k_SpecName_NTFS_STREAM)) + { + res.Delete(prevName.Len(), (unsigned)strlen(k_SpecName_NTFS_STREAM)); + res.Insert(prevName.Len(), L":"); + } + } + */ + prop = res; + break; + } + + case kpidIsDir: prop = item.IsDir(); break; + case kpidSize: + { + if (!item.IsBadDescriptor()) + prop = item.Size; + break; + } + + 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; + UInt32 unixTime; + UInt32 type; + if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft)) + type = NFileTimeType::kWindows; + else if (extra.GetUnixTime(item.FromCentral, NFileHeader::NUnixTime::kMTime, unixTime)) + type = NFileTimeType::kUnix; + else + type = NFileTimeType::kDOS; + prop = type; + break; + } + + /* + // 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: + { + if (NtfsUnixTimeToProp(item.FromCentral, extra, + NFileHeader::NNtfsExtra::kMTime, + NFileHeader::NUnixTime::kMTime, prop)) + { + FILETIME localFileTime; + if (item.Time != 0 && NTime::DosTime_To_FileTime(item.Time, localFileTime)) + { + UInt64 t1 = FILETIME_To_UInt64(prop.filetime); + UInt64 t2 = FILETIME_To_UInt64(localFileTime); + prop.Set_Int64(t2 - t1); + } + } + break; + } + */ + + case kpidAttrib: prop = item.GetWinAttrib(); break; + + case kpidPosixAttrib: + { + UInt32 attrib; + if (item.GetPosixAttrib(attrib)) + prop = attrib; + break; + } + + case kpidEncrypted: prop = item.IsEncrypted(); break; + + case kpidComment: + { + if (item.Comment.Size() != 0) + { + UString res; + item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage); + prop = res; + } + break; + } + + case kpidCRC: if (item.IsThereCrc()) prop = item.Crc; break; + + case kpidMethod: + { + AString m; + bool isWzAes = false; + unsigned id = item.Method; + + if (id == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtra aesField; + if (extra.GetWzAes(aesField)) + { + m += kMethod_AES; + m.Add_Minus(); + m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64); + id = aesField.Method; + isWzAes = true; + } + } + + if (item.IsEncrypted()) + if (!isWzAes) + { + if (item.IsStrongEncrypted()) + { + CStrongCryptoExtra f; + f.AlgId = 0; + if (extra.GetStrongCrypto(f)) + { + const char *s = FindNameForId(k_StrongCryptoPairs, Z7_ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); + if (s) + m += s; + else + { + m += kMethod_StrongCrypto; + m.Add_Colon(); + m.Add_UInt32(f.AlgId); + } + if (f.CertificateIsUsed()) + m += "-Cert"; + } + else + m += kMethod_StrongCrypto; + } + else + m += kMethod_ZipCrypto; + } + + m.Add_Space_if_NotEmpty(); + + { + const char *s = NULL; + if (id < kNumMethodNames1) + s = kMethodNames1[id]; + else + { + const int id2 = (int)id - (int)kMethodNames2Start; + if (id2 >= 0 && (unsigned)id2 < kNumMethodNames2) + s = kMethodNames2[id2]; + } + if (s) + m += s; + else + m.Add_UInt32(id); + } + { + unsigned level = item.GetDeflateLevel(); + if (level != 0) + { + if (id == NFileHeader::NCompressionMethod::kLZMA) + { + if (level & 1) + m += ":eos"; + level &= ~(unsigned)1; + } + else if (id == NFileHeader::NCompressionMethod::kDeflate) + { + m.Add_Colon(); + m += kDeflateLevels[level]; + level = 0; + } + + if (level != 0) + { + m += ":v"; + m.Add_UInt32(level); + } + } + } + + prop = m; + break; + } + + case kpidCharacts: + { + AString s; + + if (item.FromLocal) + { + s.Add_OptSpaced("Local"); + + item.LocalExtra.PrintInfo(s); + + if (item.FromCentral) + { + s.Add_OptSpaced(":"); + s.Add_OptSpaced("Central"); + } + } + + if (item.FromCentral) + { + item.CentralExtra.PrintInfo(s); + } + + UInt32 flags = item.Flags; + flags &= ~(unsigned)6; // we don't need compression related bits here. + + if (flags != 0) + { + const AString s2 = FlagsToString(g_HeaderCharacts, Z7_ARRAY_SIZE(g_HeaderCharacts), flags); + if (!s2.IsEmpty()) + { + if (!s.IsEmpty()) + s.Add_OptSpaced(":"); + s.Add_OptSpaced(s2); + } + } + + if (item.IsBadDescriptor()) + s.Add_OptSpaced("Descriptor_ERROR"); + + if (!s.IsEmpty()) + prop = s; + break; + } + + case kpidHostOS: + { + if (item.FromCentral) + { + // 18.06: now we use HostOS only from Central::MadeByVersion + const Byte hostOS = item.MadeByVersion.HostOS; + TYPE_TO_PROP(kHostOS, hostOS, prop); + } + break; + } + + case kpidUnpackVer: + prop = (UInt32)item.ExtractVersion.Version; + break; + + case kpidVolumeIndex: + prop = item.Disk; + break; + + case kpidOffset: + prop = item.LocalHeaderPos; + break; + + /* + case kpidIsAltStream: + prop = (bool)(item.ParentOfAltStream >= 0); // item.IsAltStream(); + break; + + case kpidName: + if (item.ParentOfAltStream >= 0) + { + // extract name of stream here + } + break; + */ + default: break; + } + + return prop.Detach(value); + COM_TRY_END +} + + + +/* +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps) +{ + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) +{ + UNUSED_VAR(index); + *propID = 0; + *name = 0; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + if (index >= m_Items.Size()) + return S_OK; + const CItemEx &item = m_Items[index]; + + if (item.ParentOfAltStream >= 0) + { + *parentType = NParentType::kAltStream; + *parent = item.ParentOfAltStream; + } + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +{ + UNUSED_VAR(index); + UNUSED_VAR(propID); + *data = NULL; + *dataSize = 0; + *propType = 0; + return S_OK; +} + + +void CHandler::MarkAltStreams(CObjectVector &items) +{ + int prevIndex = -1; + UString prevName; + UString name; + + for (unsigned i = 0; i < items.Size(); i++) + { + CItemEx &item = m_Items[i]; + if (item.IsAltStream()) + { + if (prevIndex == -1) + continue; + if (prevName.IsEmpty()) + { + const CItemEx &prevItem = m_Items[prevIndex]; + prevItem.GetUnicodeString(prevName, prevItem.Name, false, _forceCodePage, _specifiedCodePage); + NItemName::ReplaceToOsSlashes_Remove_TailSlash(prevName); + } + name.Empty(); + item.GetUnicodeString(name, item.Name, false, _forceCodePage, _specifiedCodePage); + NItemName::ReplaceToOsSlashes_Remove_TailSlash(name); + + if (name.IsPrefixedBy(prevName)) + if (IsString1PrefixedByString2(name.Ptr(prevName.Len()), k_SpecName_NTFS_STREAM)) + item.ParentOfAltStream = prevIndex; + } + else + { + prevIndex = i; + prevName.Empty(); + } + } +} +*/ + +Z7_COM7F_IMF(CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + try + { + Close(); + m_Archive.Force_ReadLocals_Mode = _force_OpenSeq; + // m_Archive.Disable_VolsRead = _force_OpenSeq; + // m_Archive.Disable_FindMarker = _force_OpenSeq; + HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items); + if (res != S_OK) + { + m_Items.Clear(); + m_Archive.ClearRefs(); // we don't want to clear error flags + } + // MarkAltStreams(m_Items); + return res; + } + catch(...) { Close(); throw; } + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + m_Items.Clear(); + m_Archive.Close(); + return S_OK; +} + + +Z7_CLASS_IMP_NOQIB_3( + CLzmaDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) +public: + CMyComPtr2_Create Decoder; +}; + +static const unsigned kZipLzmaPropsSize = 4 + LZMA_PROPS_SIZE; + +Z7_COM7F_IMF(CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + Byte buf[kZipLzmaPropsSize]; + RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize)) + if (buf[2] != LZMA_PROPS_SIZE || buf[3] != 0) + return E_NOTIMPL; + RINOK(Decoder->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE)) + UInt64 inSize2 = 0; + if (inSize) + { + inSize2 = *inSize; + if (inSize2 < kZipLzmaPropsSize) + return S_FALSE; + inSize2 -= kZipLzmaPropsSize; + } + return Decoder.Interface()->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress); +} + +Z7_COM7F_IMF(CLzmaDecoder::SetFinishMode(UInt32 finishMode)) +{ + Decoder->FinishStream = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = Decoder->GetInputProcessedSize() + kZipLzmaPropsSize; + return S_OK; +} + + + + + + + +struct CMethodItem +{ + unsigned ZipMethod; + CMyComPtr Coder; +}; + + + +class CZipDecoder +{ + CMyComPtr2 _zipCryptoDecoder; + CMyComPtr2 _pkAesDecoder; + CMyComPtr2 _wzAesDecoder; + + CMyComPtr2 filterStream; + CMyComPtr getTextPassword; + CObjectVector methodItems; + + CLzmaDecoder *lzmaDecoderSpec; +public: + CZipDecoder(): + lzmaDecoderSpec(NULL) + {} + + HRESULT Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + #ifndef Z7_ST + UInt32 numThreads, UInt64 memUsage, + #endif + Int32 &res); +}; + + +static HRESULT SkipStreamData(ISequentialInStream *stream, + ICompressProgressInfo *progress, UInt64 packSize, UInt64 unpackSize, + bool &thereAreData) +{ + thereAreData = false; + const size_t kBufSize = 1 << 12; + Byte buf[kBufSize]; + UInt64 prev = packSize; + for (;;) + { + size_t size = kBufSize; + RINOK(ReadStream(stream, buf, &size)) + if (size == 0) + return S_OK; + thereAreData = true; + packSize += size; + if ((packSize - prev) >= (1 << 22)) + { + prev = packSize; + RINOK(progress->SetRatioInfo(&packSize, &unpackSize)) + } + } +} + + + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithPadPKCS7 + , ISequentialOutStream +) + CMyComPtr _stream; + UInt64 _size; + UInt64 _padPos; + UInt32 _padSize; + bool _padFailure; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + + // padSize == 0 means (no_pad Mode) + void Init(UInt64 padPos, UInt32 padSize) + { + _padPos = padPos; + _padSize = padSize; + _size = 0; + _padFailure = false; + } + UInt64 GetSize() const { return _size; } + bool WasPadFailure() const { return _padFailure; } +}; + + +Z7_COM7F_IMF(COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 written = 0; + HRESULT result = S_OK; + if (_size < _padPos) + { + const UInt64 rem = _padPos - _size; + UInt32 num = size; + if (num > rem) + num = (UInt32)rem; + result = _stream->Write(data, num, &written); + _size += written; + if (processedSize) + *processedSize = written; + if (_size != _padPos || result != S_OK) + return result; + size -= written; + data = ((const Byte *)data) + written; + } + _size += size; + written += size; + if (processedSize) + *processedSize = written; + if (_padSize != 0) + for (; size != 0; size--) + { + if (*(const Byte *)data != _padSize) + _padFailure = true; + data = ((const Byte *)data) + 1; + } + return result; +} + + + +HRESULT CZipDecoder::Decode( + DECL_EXTERNAL_CODECS_LOC_VARS + CInArchive &archive, const CItemEx &item, + ISequentialOutStream *realOutStream, + IArchiveExtractCallback *extractCallback, + ICompressProgressInfo *compressProgress, + #ifndef Z7_ST + UInt32 numThreads, UInt64 memUsage, + #endif + Int32 &res) +{ + res = NExtract::NOperationResult::kHeadersError; + + CFilterCoder::C_InStream_Releaser inStreamReleaser; + CFilterCoder::C_Filter_Releaser filterReleaser; + + bool needCRC = true; + bool wzAesMode = false; + bool pkAesMode = false; + + bool badDescriptor = item.IsBadDescriptor(); + if (badDescriptor) + needCRC = false; + + + unsigned id = item.Method; + + CWzAesExtra aesField; + // LZFSE and WinZip's AES use same id - kWzAES. + + if (id == NFileHeader::NCompressionMethod::kWzAES) + { + if (item.GetMainExtra().GetWzAes(aesField)) + { + if (!item.IsEncrypted()) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + wzAesMode = true; + needCRC = aesField.NeedCrc(); + } + } + + if (!wzAesMode) + if (item.IsEncrypted()) + { + if (item.IsStrongEncrypted()) + { + CStrongCryptoExtra f; + if (!item.CentralExtra.GetStrongCrypto(f)) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + pkAesMode = true; + } + } + + CMyComPtr2_Create outStream; + outStream->SetStream(realOutStream); + outStream->Init(needCRC); + + CMyComPtr packStream; + CMyComPtr2_Create inStream; + + { + UInt64 packSize = item.PackSize; + if (wzAesMode) + { + if (packSize < NCrypto::NWzAes::kMacSize) + return S_OK; + packSize -= NCrypto::NWzAes::kMacSize; + } + RINOK(archive.GetItemStream(item, true, packStream)) + if (!packStream) + { + res = NExtract::NOperationResult::kUnavailable; + return S_OK; + } + inStream->SetStream(packStream); + inStream->Init(packSize); + } + + + res = NExtract::NOperationResult::kDataError; + + CMyComPtr cryptoFilter; + + if (item.IsEncrypted()) + { + if (wzAesMode) + { + id = aesField.Method; + _wzAesDecoder.Create_if_Empty(); + cryptoFilter = _wzAesDecoder; + if (!_wzAesDecoder->SetKeyMode(aesField.Strength)) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + } + else if (pkAesMode) + { + _pkAesDecoder.Create_if_Empty(); + cryptoFilter = _pkAesDecoder; + } + else + { + _zipCryptoDecoder.Create_if_Empty(); + cryptoFilter = _zipCryptoDecoder; + } + + CMyComPtr cryptoSetPassword; + RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)) + if (!cryptoSetPassword) + return E_FAIL; + + if (!getTextPassword) + extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); + + if (getTextPassword) + { + CMyComBSTR_Wipe password; + RINOK(getTextPassword->CryptoGetTextPassword(&password)) + AString_Wipe charPassword; + if (password) + { +#if 0 && defined(_WIN32) + // do we need UTF-8 passwords here ? + if (item.GetHostOS() == NFileHeader::NHostOS::kUnix // 24.05 + // || item.IsUtf8() // 22.00 + ) + { + // throw 1; + ConvertUnicodeToUTF8((LPCOLESTR)password, charPassword); + } + else +#endif + { + UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP); + } + /* + if (wzAesMode || pkAesMode) + { + } + else + { + // PASSWORD encoding for ZipCrypto: + // pkzip25 / WinZip / Windows probably use ANSI + // 7-Zip < 4.43 creates ZIP archives with OEM encoding in password + // 7-Zip >= 4.43 creates ZIP archives only with ASCII characters in password + // 7-Zip < 17.00 uses CP_OEMCP for password decoding + // 7-Zip >= 17.00 uses CP_ACP for password decoding + } + */ + } + HRESULT result = cryptoSetPassword->CryptoSetPassword( + (const Byte *)(const char *)charPassword, charPassword.Len()); + if (result != S_OK) + { + res = NExtract::NOperationResult::kWrongPassword; + return S_OK; + } + } + else + { + res = NExtract::NOperationResult::kWrongPassword; + return S_OK; + // RINOK(cryptoSetPassword->CryptoSetPassword(NULL, 0)); + } + } + + unsigned m; + for (m = 0; m < methodItems.Size(); m++) + if (methodItems[m].ZipMethod == id) + break; + + if (m == methodItems.Size()) + { + CMethodItem mi; + mi.ZipMethod = id; + if (id == NFileHeader::NCompressionMethod::kStore) + mi.Coder = new NCompress::CCopyCoder; + else if (id == NFileHeader::NCompressionMethod::kShrink) + mi.Coder = new NCompress::NShrink::CDecoder; + else if (id == NFileHeader::NCompressionMethod::kImplode) + mi.Coder = new NCompress::NImplode::NDecoder::CCoder; + else if (id == NFileHeader::NCompressionMethod::kLZMA) + { + lzmaDecoderSpec = new CLzmaDecoder; + mi.Coder = lzmaDecoderSpec; + } + else if (id == NFileHeader::NCompressionMethod::kXz) + mi.Coder = new NCompress::NXz::CComDecoder; + else if (id == NFileHeader::NCompressionMethod::kPPMd) + mi.Coder = new NCompress::NPpmdZip::CDecoder(true); + else if (id == NFileHeader::NCompressionMethod::kZstdWz) + mi.Coder = new NCompress::NZstd::CDecoder(); +#ifndef Z7_ZIP_LZFSE_DISABLE + else if (id == NFileHeader::NCompressionMethod::kWzAES) + mi.Coder = new NCompress::NLzfse::CDecoder; +#endif + else + { + CMethodId szMethodID; + if (id == NFileHeader::NCompressionMethod::kBZip2) + szMethodID = kMethodId_BZip2; + else + { + if (id > 0xFF) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + szMethodID = kMethodId_ZipBase + (Byte)id; + } + + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder)) + + if (!mi.Coder) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + } + m = methodItems.Add(mi); + } + + const CMethodItem &mi = methodItems[m]; + ICompressCoder *coder = mi.Coder; + + + #ifndef Z7_ST + { + CMyComPtr setCoderMt; + coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(numThreads)) + } + } + // if (memUsage != 0) + { + CMyComPtr setMemLimit; + coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit); + if (setMemLimit) + { + RINOK(setMemLimit->SetMemLimit(memUsage)) + } + } + #endif + + { + CMyComPtr setDecoderProperties; + coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); + if (setDecoderProperties) + { + Byte properties = (Byte)item.Flags; + RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)) + } + } + + + bool isFullStreamExpected = (!item.HasDescriptor() || item.PackSize != 0); + bool needReminderCheck = false; + + bool dataAfterEnd = false; + bool truncatedError = false; + bool lzmaEosError = false; + bool headersError = false; + bool padError = false; + bool readFromFilter = false; + + const bool useUnpackLimit = (id == NFileHeader::NCompressionMethod::kStore + || !item.HasDescriptor() + || item.Size >= ((UInt64)1 << 32) + || item.LocalExtra.IsZip64 + || item.CentralExtra.IsZip64 + ); + + { + HRESULT result = S_OK; + if (item.IsEncrypted()) + { + if (!filterStream.IsDefined()) + filterStream.SetFromCls(new CFilterCoder(false)); + + filterReleaser.FilterCoder = filterStream.ClsPtr(); + filterStream->Filter = cryptoFilter; + + if (wzAesMode) + { + result = _wzAesDecoder->ReadHeader(inStream); + if (result == S_OK) + { + if (!_wzAesDecoder->Init_and_CheckPassword()) + { + res = NExtract::NOperationResult::kWrongPassword; + return S_OK; + } + } + } + else if (pkAesMode) + { + isFullStreamExpected = false; + result = _pkAesDecoder->ReadHeader(inStream, item.Crc, item.Size); + if (result == S_OK) + { + bool passwOK; + result = _pkAesDecoder->Init_and_CheckPassword(passwOK); + if (result == S_OK && !passwOK) + { + res = NExtract::NOperationResult::kWrongPassword; + return S_OK; + } + } + } + else + { + result = _zipCryptoDecoder->ReadHeader(inStream); + if (result == S_OK) + { + _zipCryptoDecoder->Init_BeforeDecode(); + + /* Info-ZIP modification to ZipCrypto format: + if bit 3 of the general purpose bit flag is set, + it uses high byte of 16-bit File Time. + Info-ZIP code probably writes 2 bytes of File Time. + We check only 1 byte. */ + + // UInt32 v1 = GetUi16(_zipCryptoDecoder->_header + NCrypto::NZip::kHeaderSize - 2); + // UInt32 v2 = (item.HasDescriptor() ? (item.Time & 0xFFFF) : (item.Crc >> 16)); + + Byte v1 = _zipCryptoDecoder->_header[NCrypto::NZip::kHeaderSize - 1]; + Byte v2 = (Byte)(item.HasDescriptor() ? (item.Time >> 8) : (item.Crc >> 24)); + + if (v1 != v2) + { + res = NExtract::NOperationResult::kWrongPassword; + return S_OK; + } + } + } + } + + if (result == S_OK) + { + CMyComPtr setFinishMode; + coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + if (setFinishMode) + { + RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))) + } + + const UInt64 coderPackSize = inStream->GetRem(); + + 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; + CMyComPtr padStream; + UInt32 padSize = 0; + + if (pkAesMode) + { + padStreamSpec = new COutStreamWithPadPKCS7; + padStream = padStreamSpec; + padSize = _pkAesDecoder->GetPadSize((UInt32)item.Size); + padStreamSpec->SetStream(outStream); + padStreamSpec->Init(item.Size, padSize); + } + + // Here we decode minimal required size, including padding + const UInt64 expectedSize = item.Size + padSize; + UInt64 size = coderPackSize; + if (item.Size > coderPackSize) + headersError = true; + else if (expectedSize != coderPackSize) + { + headersError = true; + if (coderPackSize > expectedSize) + size = expectedSize; + } + + result = filterStream->Code(inStream, padStream ? + padStream.Interface() : + outStream.Interface(), + NULL, &size, compressProgress); + + if (outStream->GetSize() != item.Size) + truncatedError = true; + + if (pkAesMode) + { + if (padStreamSpec->GetSize() != size) + truncatedError = true; + if (padStreamSpec->WasPadFailure()) + padError = true; + } + } + else + { + if (item.IsEncrypted()) + { + readFromFilter = true; + inStreamReleaser.FilterCoder = filterStream.ClsPtr(); + RINOK(filterStream->SetInStream(inStream)) + + /* IFilter::Init() does nothing in all zip crypto filters. + So we can call any Initialize function in CFilterCoder. */ + + RINOK(filterStream->Init_NoSubFilterInit()) + // RINOK(filterStream->SetOutStreamSize(NULL)); + } + + try { + result = coder->Code(readFromFilter ? + filterStream.Interface() : + inStream.Interface(), + outStream, + isFullStreamExpected ? &coderPackSize : NULL, + // NULL, + useUnpackLimit ? &item.Size : NULL, + compressProgress); + } catch (...) { return E_FAIL; } + + if (result == S_OK) + { + CMyComPtr getInStreamProcessedSize; + coder->QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); + if (getInStreamProcessedSize && setFinishMode) + { + UInt64 processed; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) + if (processed != (UInt64)(Int64)-1) + { + if (pkAesMode) + { + const UInt32 padSize = _pkAesDecoder->GetPadSize((UInt32)processed); + if (processed + padSize > coderPackSize) + truncatedError = true; + else if (processed + padSize < coderPackSize) + dataAfterEnd = true; + else + { + { + // here we check PKCS7 padding data from reminder (it can be inside stream buffer in coder). + CMyComPtr readInStream; + coder->QueryInterface(IID_ICompressReadUnusedFromInBuf, (void **)&readInStream); + // CCopyCoder() for kStore doesn't read data outside of (item.Size) + if (readInStream || id == NFileHeader::NCompressionMethod::kStore) + { + // 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 = 0; + if (readInStream) + { + RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize)) + } + if (processedSize > padSize) + dataAfterEnd = true; + else + { + 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; + } + } + } + } + } + } + else + { + if (processed < coderPackSize) + { + if (isFullStreamExpected) + dataAfterEnd = true; + } + else if (processed > coderPackSize) + { + // that case is additional check, that can show the bugs in code (coder) + truncatedError = true; + } + needReminderCheck = isFullStreamExpected; + } + } + } + } + } + + if (result == S_OK && id == NFileHeader::NCompressionMethod::kLZMA) + if (!lzmaDecoderSpec->Decoder->CheckFinishStatus(item.IsLzmaEOS())) + lzmaEosError = true; + } + + if (result == S_FALSE) + return S_OK; + + if (result == E_NOTIMPL) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + return S_OK; + } + + RINOK(result) + } + + bool crcOK = true; + bool authOk = true; + if (needCRC) + crcOK = (outStream->GetCRC() == item.Crc); + + if (useUnpackLimit) + if (outStream->GetSize() != item.Size) + truncatedError = true; + + if (wzAesMode) + { + const UInt64 unpackSize = outStream->GetSize(); + const UInt64 packSize = inStream->GetSize(); + bool thereAreData = false; + // read to the end from filter or from packed stream + if (SkipStreamData(readFromFilter ? + filterStream.Interface() : + inStream.Interface(), + compressProgress, packSize, unpackSize, thereAreData) != S_OK) + authOk = false; + if (needReminderCheck && thereAreData) + dataAfterEnd = true; + + if (inStream->GetRem() != 0) + truncatedError = true; + else + { + inStream->Init(NCrypto::NWzAes::kMacSize); + if (_wzAesDecoder->CheckMac(inStream, authOk) != S_OK) + authOk = false; + } + } + + res = NExtract::NOperationResult::kCRCError; + + if (crcOK && authOk) + { + res = NExtract::NOperationResult::kOK; + + if (dataAfterEnd) + res = NExtract::NOperationResult::kDataAfterEnd; + else if (padError) + res = NExtract::NOperationResult::kCRCError; + else if (truncatedError) + res = NExtract::NOperationResult::kUnexpectedEnd; + else if (headersError) + res = NExtract::NOperationResult::kHeadersError; + else if (lzmaEosError) + res = NExtract::NOperationResult::kHeadersError; + else if (badDescriptor) + res = NExtract::NOperationResult::kUnexpectedEnd; + + // CheckDescriptor() supports only data descriptor with signature and + // it doesn't support "old" pkzip's data descriptor without signature. + // So we disable that check. + /* + if (item.HasDescriptor() && archive.CheckDescriptor(item) != S_OK) + res = NExtract::NOperationResult::kHeadersError; + */ + } + + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = m_Items.Size(); + if (numItems == 0) + return S_OK; + UInt64 total = 0; // , totalPacked = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CItemEx &item = m_Items[allFilesMode ? i : indices[i]]; + total += item.Size; + // totalPacked += item.PackSize; + } + RINOK(extractCallback->SetTotal(total)) + + CZipDecoder myDecoder; + UInt64 cur_Unpacked, cur_Packed; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + for (i = 0;; i++, + lps->OutSize += cur_Unpacked, + lps->InSize += cur_Packed) + { + RINOK(lps->SetCur()) + if (i >= numItems) + return S_OK; + const UInt32 index = allFilesMode ? i : indices[i]; + CItemEx item = m_Items[index]; + cur_Unpacked = item.Size; + cur_Packed = item.PackSize; + + const bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item); + const bool skip = !isLocalOffsetOK && !item.IsDir(); + const Int32 askMode = skip ? + NExtract::NAskMode::kSkip : testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + Int32 opRes; + { + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + if (!isLocalOffsetOK) + { + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)) + continue; + } + + bool headersError = false; + + if (!item.FromLocal) + { + bool isAvail = true; + const HRESULT hres = m_Archive.Read_LocalItem_After_CdItem(item, isAvail, headersError); + if (hres == S_FALSE) + { + if (item.IsDir() || realOutStream || testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult( + isAvail ? + NExtract::NOperationResult::kHeadersError : + NExtract::NOperationResult::kUnavailable)) + } + continue; + } + RINOK(hres) + } + + if (item.IsDir()) + { + // if (!testMode) + { + RINOK(extractCallback->PrepareOperation(askMode)) + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) + } + continue; + } + + if (!testMode && !realOutStream) + continue; + + RINOK(extractCallback->PrepareOperation(askMode)) + + const HRESULT hres = myDecoder.Decode( + EXTERNAL_CODECS_VARS + m_Archive, item, realOutStream, extractCallback, + lps, + #ifndef Z7_ST + _props._numThreads, _props._memUsage_Decompress, + #endif + opRes); + + RINOK(hres) + // realOutStream.Release(); + + if (opRes == NExtract::NOperationResult::kOK && headersError) + opRes = NExtract::NOperationResult::kHeadersError; + } + RINOK(extractCallback->SetOperationResult(opRes)) + } + + COM_TRY_END +} + +IMPL_ISetCompressCodecsInfo + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandler.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandler.h 2015-09-20 17:55:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandler.h 2023-03-26 11:00:00.000000000 +0000 @@ -1,74 +1,94 @@ -// Zip/Handler.h - -#ifndef __ZIP_HANDLER_H -#define __ZIP_HANDLER_H - -#include "../../../Common/DynamicBuffer.h" -#include "../../ICoder.h" -#include "../IArchive.h" - -#include "../../Common/CreateCoder.h" - -#include "ZipIn.h" -#include "ZipCompressionMode.h" - -namespace NArchive { -namespace NZip { - -class CHandler: - public IInArchive, - public IOutArchive, - public ISetProperties, - PUBLIC_ISetCompressCodecsInfo - public CMyUnknownImp -{ -public: - MY_QUERYINTERFACE_BEGIN2(IInArchive) - MY_QUERYINTERFACE_ENTRY(IOutArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - QUERY_ENTRY_ISetCompressCodecsInfo - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInArchive(;) - INTERFACE_IOutArchive(;) - - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - - DECL_ISetCompressCodecsInfo - - CHandler(); -private: - CObjectVector m_Items; - CInArchive m_Archive; - - CBaseProps _props; - - int m_MainMethod; - bool m_ForceAesMode; - bool m_WriteNtfsTimeExtra; - bool _removeSfxBlock; - bool m_ForceLocal; - bool m_ForceUtf8; - bool _forceCodePage; - UInt32 _specifiedCodePage; - - DECL_EXTERNAL_CODECS_VARS - - void InitMethodProps() - { - _props.Init(); - m_MainMethod = -1; - m_ForceAesMode = false; - m_WriteNtfsTimeExtra = true; - _removeSfxBlock = false; - m_ForceLocal = false; - m_ForceUtf8 = false; - _forceCodePage = false; - _specifiedCodePage = CP_OEMCP; - } -}; - -}} - -#endif +// Zip/Handler.h + +#ifndef ZIP7_INC_ZIP_HANDLER_H +#define ZIP7_INC_ZIP_HANDLER_H + +#include "../../../Common/DynamicBuffer.h" +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#include "ZipCompressionMode.h" +#include "ZipIn.h" + +namespace NArchive { +namespace NZip { + +const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kZstdPk + 1; +const unsigned kMethodNames2Start = NFileHeader::NCompressionMethod::kZstdWz; +const unsigned kNumMethodNames2 = NFileHeader::NCompressionMethod::kWzAES + 1 - kMethodNames2Start; + +extern const char * const kMethodNames1[kNumMethodNames1]; +extern const char * const kMethodNames2[kNumMethodNames2]; + + +class CHandler Z7_final: + public IInArchive, + // public IArchiveGetRawProps, + public IOutArchive, + public ISetProperties, + Z7_PUBLIC_ISetCompressCodecsInfo_IFEC + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInArchive) + // Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IOutArchive) + Z7_COM_QI_ENTRY(ISetProperties) + Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + // Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IOutArchive) + Z7_IFACE_COM7_IMP(ISetProperties) + DECL_ISetCompressCodecsInfo + +private: + CObjectVector m_Items; + CInArchive m_Archive; + + CBaseProps _props; + CHandlerTimeOptions TimeOptions; + + int m_MainMethod; + bool m_ForceAesMode; + + bool _removeSfxBlock; + bool m_ForceLocal; + bool m_ForceUtf8; + bool _force_SeqOutMode; // for creation + bool _force_OpenSeq; + bool _forceCodePage; + UInt32 _specifiedCodePage; + + DECL_EXTERNAL_CODECS_VARS + + void InitMethodProps() + { + _props.Init(); + TimeOptions.Init(); + TimeOptions.Prec = k_PropVar_TimePrec_0; + m_MainMethod = -1; + m_ForceAesMode = false; + _removeSfxBlock = false; + m_ForceLocal = false; + m_ForceUtf8 = false; + _force_SeqOutMode = false; + _force_OpenSeq = false; + _forceCodePage = false; + _specifiedCodePage = CP_OEMCP; + } + + // void MarkAltStreams(CObjectVector &items); + + HRESULT GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value); + +public: + CHandler(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp 2015-09-01 18:28:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp 2023-10-14 18:00:00.000000000 +0000 @@ -1,448 +1,626 @@ -// ZipHandlerOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../IPassword.h" - -#include "../../Common/OutBuffer.h" - -#include "../../Crypto/WzAes.h" - -#include "../Common/ItemNameUtils.h" -#include "../Common/ParseProperties.h" - -#include "ZipHandler.h" -#include "ZipUpdate.h" - -using namespace NWindows; -using namespace NCOM; -using namespace NTime; - -namespace NArchive { -namespace NZip { - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType) -{ - *timeType = NFileTimeType::kDOS; - return S_OK; -} - -static bool IsSimpleAsciiString(const wchar_t *s) -{ - for (;;) - { - wchar_t c = *s++; - if (c == 0) - return true; - if (c < 0x20 || c > 0x7F) - return false; - } -} - -#define COM_TRY_BEGIN2 try { -#define COM_TRY_END2 } \ -catch(const CSystemException &e) { return e.ErrorCode; } \ -catch(...) { return E_OUTOFMEMORY; } - -static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &filetime) -{ - filetime.dwHighDateTime = filetime.dwLowDateTime = 0; - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propID, &prop)); - if (prop.vt == VT_FILETIME) - filetime = prop.filetime; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) -{ - COM_TRY_BEGIN2 - - if (m_Archive.IsOpen()) - { - if (!m_Archive.CanUpdate()) - return E_NOTIMPL; - } - - CObjectVector updateItems; - bool thereAreAesUpdates = false; - UInt64 largestSize = 0; - bool largestSizeDefined = false; - - for (UInt32 i = 0; i < numItems; i++) - { - CUpdateItem ui; - Int32 newData; - Int32 newProps; - UInt32 indexInArchive; - if (!callback) - return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); - ui.NewProps = IntToBool(newProps); - ui.NewData = IntToBool(newData); - ui.IndexInArc = indexInArchive; - ui.IndexInClient = i; - bool existInArchive = (indexInArchive != (UInt32)(Int32)-1); - if (existInArchive && newData) - if (m_Items[indexInArchive].IsAesEncrypted()) - thereAreAesUpdates = true; - - if (IntToBool(newProps)) - { - UString name; - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidAttrib, &prop)); - if (prop.vt == VT_EMPTY) - ui.Attrib = 0; - else if (prop.vt != VT_UI4) - return E_INVALIDARG; - else - ui.Attrib = prop.ulVal; - } - - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPath, &prop)); - if (prop.vt == VT_EMPTY) - name.Empty(); - else if (prop.vt != VT_BSTR) - return E_INVALIDARG; - else - name = prop.bstrVal; - } - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); - if (prop.vt == VT_EMPTY) - ui.IsDir = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - ui.IsDir = (prop.boolVal != VARIANT_FALSE); - } - - { - CPropVariant prop; - RINOK(callback->GetProperty(i, kpidTimeType, &prop)); - if (prop.vt == VT_UI4) - ui.NtfsTimeIsDefined = (prop.ulVal == NFileTimeType::kWindows); - else - ui.NtfsTimeIsDefined = m_WriteNtfsTimeExtra; - } - RINOK(GetTime(callback, i, kpidMTime, ui.Ntfs_MTime)); - RINOK(GetTime(callback, i, kpidATime, ui.Ntfs_ATime)); - RINOK(GetTime(callback, i, kpidCTime, ui.Ntfs_CTime)); - - { - 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); - } - - name = NItemName::MakeLegalName(name); - bool needSlash = ui.IsDir; - const wchar_t kSlash = L'/'; - if (!name.IsEmpty()) - { - if (name.Back() == kSlash) - { - if (!ui.IsDir) - return E_INVALIDARG; - needSlash = false; - } - } - if (needSlash) - name += kSlash; - - UINT codePage = _forceCodePage ? _specifiedCodePage : CP_OEMCP; - - bool tryUtf8 = true; - if ((m_ForceLocal || !m_ForceUtf8) && codePage != CP_UTF8) - { -#ifdef _WIN32 - bool defaultCharWasUsed; - ui.Name = UnicodeStringToMultiByte(name, codePage, '_', defaultCharWasUsed); - tryUtf8 = (!m_ForceLocal && (defaultCharWasUsed || - MultiByteToUnicodeString(ui.Name, codePage) != name)); -#else - // FIXME - ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP); - tryUtf8 = (!m_ForceLocal); -#endif - } - - if (tryUtf8) - { - ui.IsUtf8 = !name.IsAscii(); - ConvertUnicodeToUTF8(name, ui.Name); - } - - if (ui.Name.Len() >= (1 << 16)) - return E_INVALIDARG; - - ui.IndexInClient = i; - /* - if (existInArchive) - { - const CItemEx &itemInfo = m_Items[indexInArchive]; - // ui.Commented = itemInfo.IsCommented(); - ui.Commented = false; - if (ui.Commented) - { - ui.CommentRange.Position = itemInfo.GetCommentPosition(); - ui.CommentRange.Size = itemInfo.CommentSize; - } - } - else - ui.Commented = false; - */ - } - if (IntToBool(newData)) - { - UInt64 size = 0; - if (!ui.IsDir) - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - size = prop.uhVal.QuadPart; - if (largestSize < size) - largestSize = size; - largestSizeDefined = true; - } - ui.Size = size; - - // ui.Size -= ui.Size / 2; - } - updateItems.Add(ui); - } - - CMyComPtr getTextPassword; - { - CMyComPtr udateCallBack2(callback); - udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); - } - CCompressionMethodMode options; - (CBaseProps &)options = _props; - options._dataSizeReduce = largestSize; - options._dataSizeReduceDefined = largestSizeDefined; - - options.PasswordIsDefined = false; - options.Password.Empty(); - if (getTextPassword) - { - CMyComBSTR password; - Int32 passwordIsDefined; - RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password)); - options.PasswordIsDefined = IntToBool(passwordIsDefined); - if (options.PasswordIsDefined) - { - if (!m_ForceAesMode) - options.IsAesMode = thereAreAesUpdates; - - if (!IsSimpleAsciiString(password)) - return E_INVALIDARG; - if (password) - options.Password = UnicodeStringToMultiByte((LPCOLESTR)password, CP_OEMCP); - if (options.IsAesMode) - { - if (options.Password.Len() > NCrypto::NWzAes::kPasswordSizeMax) - return E_INVALIDARG; - } - } - } - - Byte mainMethod; - if (m_MainMethod < 0) - mainMethod = (Byte)(((_props.Level == 0) ? - NFileHeader::NCompressionMethod::kStored : - NFileHeader::NCompressionMethod::kDeflated)); - else - mainMethod = (Byte)m_MainMethod; - options.MethodSequence.Add(mainMethod); - if (mainMethod != NFileHeader::NCompressionMethod::kStored) - options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored); - - return Update( - EXTERNAL_CODECS_VARS - m_Items, updateItems, outStream, - m_Archive.IsOpen() ? &m_Archive : NULL, _removeSfxBlock, - &options, callback); - - COM_TRY_END2 -} - -struct CMethodIndexToName -{ - unsigned Method; - const char *Name; -}; - -static const CMethodIndexToName k_SupportedMethods[] = -{ - { NFileHeader::NCompressionMethod::kStored, "copy" }, - { NFileHeader::NCompressionMethod::kDeflated, "deflate" }, - { NFileHeader::NCompressionMethod::kDeflated64, "deflate64" }, - { NFileHeader::NCompressionMethod::kBZip2, "bzip2" }, - { NFileHeader::NCompressionMethod::kLZMA, "lzma" }, - { NFileHeader::NCompressionMethod::kPPMd, "ppmd" } -}; - -STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - InitMethodProps(); - #ifndef _7ZIP_ST - const UInt32 numProcessors = _props.NumThreads; - #endif - - for (UInt32 i = 0; i < numProps; i++) - { - UString name = names[i]; - name.MakeLower_Ascii(); - if (name.IsEmpty()) - return E_INVALIDARG; - - const PROPVARIANT &prop = values[i]; - - if (name[0] == L'x') - { - UInt32 level = 9; - RINOK(ParsePropToUInt32(name.Ptr(1), prop, level)); - _props.Level = level; - _props.MethodInfo.AddProp_Level(level); - } - else if (name == L"m") - { - if (prop.vt == VT_BSTR) - { - UString m = prop.bstrVal, m2; - m.MakeLower_Ascii(); - int colonPos = m.Find(L':'); - if (colonPos >= 0) - { - m2 = m.Ptr(colonPos + 1); - m.DeleteFrom(colonPos); - } - unsigned k; - for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++) - { - const CMethodIndexToName &pair = k_SupportedMethods[k]; - if (m.IsEqualTo(pair.Name)) - { - if (!m2.IsEmpty()) - { - RINOK(_props.MethodInfo.ParseParamsFromString(m2)); - } - m_MainMethod = pair.Method; - break; - } - } - if (k == ARRAY_SIZE(k_SupportedMethods)) - return E_INVALIDARG; - } - else if (prop.vt == VT_UI4) - { - unsigned k; - for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++) - { - unsigned method = k_SupportedMethods[k].Method; - if (prop.ulVal == method) - { - m_MainMethod = method; - break; - } - } - if (k == ARRAY_SIZE(k_SupportedMethods)) - return E_INVALIDARG; - } - else - return E_INVALIDARG; - } - else if (name.IsPrefixedBy(L"em")) - { - if (prop.vt != VT_BSTR) - return E_INVALIDARG; - { - UString m = prop.bstrVal; - m.MakeLower_Ascii(); - if (m.IsPrefixedBy(L"aes")) - { - m.DeleteFrontal(3); - if (m == L"128") - _props.AesKeyMode = 1; - else if (m == L"192") - _props.AesKeyMode = 2; - else if (m == L"256" || m.IsEmpty()) - _props.AesKeyMode = 3; - else - return E_INVALIDARG; - _props.IsAesMode = true; - m_ForceAesMode = true; - } - else if (m == L"zipcrypto") - { - _props.IsAesMode = false; - m_ForceAesMode = true; - } - else - return E_INVALIDARG; - } - } - else if (name.IsPrefixedBy(L"mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), prop, numProcessors, _props.NumThreads)); - _props.NumThreadsWasChanged = true; - #endif - } - else if (name.IsEqualTo("tc")) - { - RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra)); - } - else if (name.IsEqualTo("cl")) - { - RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal)); - if (m_ForceLocal) - m_ForceUtf8 = false; - } - else if (name.IsEqualTo("cu")) - { - RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8)); - if (m_ForceUtf8) - m_ForceLocal = false; - } - else if (name.IsEqualTo("cp")) - { - UInt32 cp = CP_OEMCP; - RINOK(ParsePropToUInt32(L"", prop, cp)); - _forceCodePage = true; - _specifiedCodePage = cp; - } - else if (name.IsEqualTo("rsfx")) - { - RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock)); - } - else - { - RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop)); - } - } - return S_OK; -} - -}} +// ZipHandlerOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../IPassword.h" + +#include "../../Common/OutBuffer.h" + +#include "../../Crypto/WzAes.h" + +#include "../Common/ItemNameUtils.h" +#include "../Common/ParseProperties.h" + +#include "ZipHandler.h" +#include "ZipUpdate.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NTime; + +namespace NArchive { +namespace NZip { + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = TimeOptions.Prec; + return S_OK; +} + +static bool IsSimpleAsciiString(const wchar_t *s) +{ + for (;;) + { + wchar_t c = *s++; + if (c == 0) + return true; + if (c < 0x20 || c > 0x7F) + return false; + } +} + + +static int FindZipMethod(const char *s, const char * const *names, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + { + const char *name = names[i]; + if (name && StringsAreEqualNoCase_Ascii(s, name)) + return (int)i; + } + return -1; +} + +static int FindZipMethod(const char *s) +{ + int k = FindZipMethod(s, kMethodNames1, kNumMethodNames1); + if (k >= 0) + return k; + k = FindZipMethod(s, kMethodNames2, kNumMethodNames2); + if (k >= 0) + return (int)kMethodNames2Start + k; + return -1; +} + + +#define COM_TRY_BEGIN2 try { +#define COM_TRY_END2 } \ +catch(const CSystemException &e) { return e.ErrorCode; } \ +catch(...) { return E_OUTOFMEMORY; } + +static HRESULT GetTime(IArchiveUpdateCallback *callback, unsigned index, PROPID propID, FILETIME &filetime) +{ + filetime.dwHighDateTime = filetime.dwLowDateTime = 0; + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(index, propID, &prop)) + if (prop.vt == VT_FILETIME) + filetime = prop.filetime; + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) +{ + COM_TRY_BEGIN2 + + if (m_Archive.IsOpen()) + { + if (!m_Archive.CanUpdate()) + return E_NOTIMPL; + } + + CObjectVector updateItems; + updateItems.ClearAndReserve(numItems); + + bool thereAreAesUpdates = false; + UInt64 largestSize = 0; + bool largestSizeDefined = false; + + #ifdef _WIN32 + const UINT oemCP = GetOEMCP(); + #endif + + UString name; + CUpdateItem ui; + + for (UInt32 i = 0; i < numItems; i++) + { + Int32 newData; + Int32 newProps; + UInt32 indexInArc; + + if (!callback) + return E_FAIL; + + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) + + name.Empty(); + ui.Clear(); + + ui.NewProps = IntToBool(newProps); + ui.NewData = IntToBool(newData); + ui.IndexInArc = (int)indexInArc; + ui.IndexInClient = i; + + bool existInArchive = (indexInArc != (UInt32)(Int32)-1); + if (existInArchive) + { + const CItemEx &inputItem = m_Items[indexInArc]; + if (inputItem.IsAesEncrypted()) + thereAreAesUpdates = true; + if (!IntToBool(newProps)) + ui.IsDir = inputItem.IsDir(); + // ui.IsAltStream = inputItem.IsAltStream(); + } + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidAttrib, &prop)) + if (prop.vt == VT_EMPTY) + ui.Attrib = 0; + else if (prop.vt != VT_UI4) + return E_INVALIDARG; + else + ui.Attrib = prop.ulVal; + } + + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidPath, &prop)) + if (prop.vt == VT_EMPTY) + { + // name.Empty(); + } + else if (prop.vt != VT_BSTR) + return E_INVALIDARG; + else + name = prop.bstrVal; + } + + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) + if (prop.vt == VT_EMPTY) + ui.IsDir = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + ui.IsDir = (prop.boolVal != VARIANT_FALSE); + } + + /* + { + bool isAltStream = false; + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsAltStream, &prop)); + if (prop.vt == VT_BOOL) + isAltStream = (prop.boolVal != VARIANT_FALSE); + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + } + + if (isAltStream) + { + if (ui.IsDir) + return E_INVALIDARG; + int delim = name.ReverseFind(L':'); + if (delim >= 0) + { + name.Delete(delim, 1); + name.Insert(delim, UString(k_SpecName_NTFS_STREAM)); + ui.IsAltStream = true; + } + } + } + */ + + // 22.00 : kpidTimeType is useless here : the code was disabled + /* + { + CPropVariant prop; + RINOK(callback->GetProperty(i, kpidTimeType, &prop)); + if (prop.vt == VT_UI4) + ui.NtfsTime_IsDefined = (prop.ulVal == NFileTimeType::kWindows); + else + ui.NtfsTime_IsDefined = _Write_NtfsTime; + } + */ + + 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) + { + 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; + const wchar_t kSlash = L'/'; + if (!name.IsEmpty()) + { + if (name.Back() == kSlash) + { + if (!ui.IsDir) + return E_INVALIDARG; + needSlash = false; + } + } + if (needSlash) + name += kSlash; + + const UINT codePage = _forceCodePage ? _specifiedCodePage : CP_OEMCP; + bool tryUtf8 = true; + + /* + Windows 10 allows users to set UTF-8 in Region Settings via option: + "Beta: Use Unicode UTF-8 for worldwide language support" + In that case Windows uses CP_UTF8 when we use CP_OEMCP. + 21.02 fixed: + we set UTF-8 mark for non-latin files for such UTF-8 mode in Windows. + we write additional Info-Zip Utf-8 FileName Extra for non-latin names/ + */ + + if ((codePage != CP_UTF8) && + #ifdef _WIN32 + (m_ForceLocal || !m_ForceUtf8) && (oemCP != CP_UTF8) + #else + (m_ForceLocal && !m_ForceUtf8) + #endif + ) + { + bool defaultCharWasUsed; + ui.Name = UnicodeStringToMultiByte(name, codePage, '_', defaultCharWasUsed); + tryUtf8 = (!m_ForceLocal && (defaultCharWasUsed || + MultiByteToUnicodeString(ui.Name, codePage) != name)); + } + + const bool isNonLatin = !name.IsAscii(); + + if (tryUtf8) + { + ui.IsUtf8 = isNonLatin; + ConvertUnicodeToUTF8(name, ui.Name); + + #ifndef _WIN32 + if (ui.IsUtf8 && !CheckUTF8_AString(ui.Name)) + { + // if it's non-Windows and there are non-UTF8 characters we clear UTF8-flag + ui.IsUtf8 = false; + } + #endif + } + else if (isNonLatin) + Convert_Unicode_To_UTF8_Buf(name, ui.Name_Utf); + + if (ui.Name.Len() >= (1 << 16) + || ui.Name_Utf.Size() >= (1 << 16) - 128) + return E_INVALIDARG; + + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidComment, &prop)) + if (prop.vt == VT_EMPTY) + { + // ui.Comment.Free(); + } + else if (prop.vt != VT_BSTR) + return E_INVALIDARG; + else + { + UString s = prop.bstrVal; + AString a; + if (ui.IsUtf8) + ConvertUnicodeToUTF8(s, a); + else + { + bool defaultCharWasUsed; + a = UnicodeStringToMultiByte(s, codePage, '_', defaultCharWasUsed); + } + if (a.Len() >= (1 << 16)) + return E_INVALIDARG; + ui.Comment.CopyFrom((const Byte *)(const char *)a, a.Len()); + } + } + + + /* + if (existInArchive) + { + const CItemEx &itemInfo = m_Items[indexInArc]; + // ui.Commented = itemInfo.IsCommented(); + ui.Commented = false; + if (ui.Commented) + { + ui.CommentRange.Position = itemInfo.GetCommentPosition(); + ui.CommentRange.Size = itemInfo.CommentSize; + } + } + else + ui.Commented = false; + */ + } + + + if (IntToBool(newData)) + { + UInt64 size = 0; + if (!ui.IsDir) + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + if (largestSize < size) + largestSize = size; + largestSizeDefined = true; + } + ui.Size = size; + } + + updateItems.Add(ui); + } + + + CMyComPtr getTextPassword; + { + CMyComPtr udateCallBack2(callback); + udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); + } + CCompressionMethodMode options; + (CBaseProps &)options = _props; + options.DataSizeReduce = largestSize; + options.DataSizeReduce_Defined = largestSizeDefined; + + options.Password_Defined = false; + options.Password.Wipe_and_Empty(); + if (getTextPassword) + { + CMyComBSTR_Wipe password; + Int32 passwordIsDefined; + RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password)) + options.Password_Defined = IntToBool(passwordIsDefined); + if (options.Password_Defined) + { + if (!m_ForceAesMode) + options.IsAesMode = thereAreAesUpdates; + + if (!IsSimpleAsciiString(password)) + return E_INVALIDARG; + if (password) + UnicodeStringToMultiByte2(options.Password, (LPCOLESTR)password, CP_OEMCP); + if (options.IsAesMode) + { + if (options.Password.Len() > NCrypto::NWzAes::kPasswordSizeMax) + return E_INVALIDARG; + } + } + } + + + int mainMethod = m_MainMethod; + + if (mainMethod < 0) + { + if (!_props._methods.IsEmpty()) + { + const AString &methodName = _props._methods.Front().MethodName; + if (!methodName.IsEmpty()) + { + mainMethod = FindZipMethod(methodName); + if (mainMethod < 0) + { + CMethodId methodId; + UInt32 numStreams; + bool isFilter; + if (FindMethod_Index(EXTERNAL_CODECS_VARS methodName, true, + methodId, numStreams, isFilter) < 0) + return E_NOTIMPL; + if (numStreams != 1) + return E_NOTIMPL; + if (methodId == kMethodId_BZip2) + mainMethod = NFileHeader::NCompressionMethod::kBZip2; + else + { + if (methodId < kMethodId_ZipBase) + return E_NOTIMPL; + methodId -= kMethodId_ZipBase; + if (methodId > 0xFF) + return E_NOTIMPL; + mainMethod = (int)methodId; + } + } + } + } + } + + if (mainMethod < 0) + mainMethod = (Byte)(((_props.GetLevel() == 0) ? + NFileHeader::NCompressionMethod::kStore : + NFileHeader::NCompressionMethod::kDeflate)); + else + mainMethod = (Byte)mainMethod; + + options.MethodSequence.Add((Byte)mainMethod); + + if (mainMethod != NFileHeader::NCompressionMethod::kStore) + options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore); + + options.Force_SeqOutMode = _force_SeqOutMode; + + 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, + uo, options, callback); + + COM_TRY_END2 +} + + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + InitMethodProps(); + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + const PROPVARIANT &prop = values[i]; + + if (name.IsEqualTo_Ascii_NoCase("em")) + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + { + const wchar_t *m = prop.bstrVal; + if (IsString1PrefixedByString2_NoCase_Ascii(m, "AES")) + { + m += 3; + UInt32 v = 3; + if (*m != 0) + { + if (*m == '-') + m++; + const wchar_t *end; + v = ConvertStringToUInt32(m, &end); + if (*end != 0 || v % 64 != 0) + return E_INVALIDARG; + v /= 64; + v -= 2; + if (v >= 3) + return E_INVALIDARG; + v++; + } + _props.AesKeyMode = (Byte)v; + _props.IsAesMode = true; + m_ForceAesMode = true; + } + else if (StringsAreEqualNoCase_Ascii(m, "ZipCrypto")) + { + _props.IsAesMode = false; + m_ForceAesMode = true; + } + else + return E_INVALIDARG; + } + } + + + + else if (name.IsEqualTo("cl")) + { + RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal)) + if (m_ForceLocal) + m_ForceUtf8 = false; + } + else if (name.IsEqualTo("cu")) + { + RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8)) + if (m_ForceUtf8) + m_ForceLocal = false; + } + else if (name.IsEqualTo("cp")) + { + UInt32 cp = CP_OEMCP; + RINOK(ParsePropToUInt32(L"", prop, cp)) + _forceCodePage = true; + _specifiedCodePage = cp; + } + else if (name.IsEqualTo("rsfx")) + { + RINOK(PROPVARIANT_to_bool(prop, _removeSfxBlock)) + } + else if (name.IsEqualTo("rws")) + { + RINOK(PROPVARIANT_to_bool(prop, _force_SeqOutMode)) + } + else if (name.IsEqualTo("ros")) + { + RINOK(PROPVARIANT_to_bool(prop, _force_OpenSeq)) + } + else + { + if (name.IsEqualTo_Ascii_NoCase("m") && prop.vt == VT_UI4) + { + UInt32 id = prop.ulVal; + if (id > 0xFF) + return E_INVALIDARG; + m_MainMethod = (int)id; + } + else + { + bool processed = false; + RINOK(TimeOptions.Parse(name, prop, processed)) + if (!processed) + { + RINOK(_props.SetProperty(name, prop)) + } + } + // RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop)); + } + } + + _props._methods.DeleteFrontal(_props.GetNumEmptyMethods()); + if (_props._methods.Size() > 1) + return E_INVALIDARG; + if (_props._methods.Size() == 1) + { + const AString &methodName = _props._methods[0].MethodName; + + if (!methodName.IsEmpty()) + { + const char *end; + UInt32 id = ConvertStringToUInt32(methodName, &end); + if (*end == 0 && id <= 0xFF) + m_MainMethod = (int)id; + else if (methodName.IsEqualTo_Ascii_NoCase("Copy")) // it's alias for "Store" + m_MainMethod = 0; + } + } + + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHeader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHeader.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipHeader.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipHeader.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,176 +1,201 @@ -// ZipHeader.h - -#ifndef __ARCHIVE_ZIP_HEADER_H -#define __ARCHIVE_ZIP_HEADER_H - -#include "../../../Common/MyTypes.h" - -namespace NArchive { -namespace NZip { - -const unsigned kMarkerSize = 4; - -namespace NSignature -{ - const UInt32 kLocalFileHeader = 0x04034B50; - const UInt32 kDataDescriptor = 0x08074B50; - const UInt32 kCentralFileHeader = 0x02014B50; - const UInt32 kEcd = 0x06054B50; - const UInt32 kEcd64 = 0x06064B50; - const UInt32 kEcd64Locator = 0x07064B50; - const UInt32 kSpan = 0x08074B50; - const UInt32 kNoSpan = 0x30304B50; // PK00, replaces kSpan, if there is only 1 segment -} - -const unsigned kLocalHeaderSize = 4 + 26; // including signature -const unsigned kDataDescriptorSize = 4 + 12; // including signature -const unsigned kCentralHeaderSize = 4 + 42; // including signature - -const unsigned kEcdSize = 22; // including signature -const unsigned kEcd64_MainSize = 44; -const unsigned kEcd64_FullSize = 12 + kEcd64_MainSize; -const unsigned kEcd64Locator_Size = 20; - -namespace NFileHeader -{ - namespace NCompressionMethod - { - enum EType - { - kStored = 0, - kShrunk = 1, - kReduced1 = 2, - kReduced2 = 3, - kReduced3 = 4, - kReduced4 = 5, - kImploded = 6, - kReservedTokenizing = 7, // reserved for tokenizing - kDeflated = 8, - kDeflated64 = 9, - kPKImploding = 10, - - kBZip2 = 12, - kLZMA = 14, - kTerse = 18, - kLz77 = 19, - - kXz = 0x5F, - kJpeg = 0x60, - kWavPack = 0x61, - kPPMd = 0x62, - kWzAES = 0x63 - }; - - const Byte kMadeByProgramVersion = 63; - - const Byte kExtractVersion_Default = 10; - const Byte kExtractVersion_Dir = 20; - const Byte kExtractVersion_ZipCrypto = 20; - const Byte kExtractVersion_Deflate = 20; - const Byte kExtractVersion_Deflate64 = 21; - const Byte kExtractVersion_Zip64 = 45; - const Byte kExtractVersion_BZip2 = 46; - const Byte kExtractVersion_Aes = 51; - const Byte kExtractVersion_LZMA = 63; - const Byte kExtractVersion_PPMd = 63; - } - - namespace NExtraID - { - enum - { - kZip64 = 0x01, - kNTFS = 0x0A, - kStrongEncrypt = 0x17, - kUnixTime = 0x5455, - kIzUnicodeComment = 0x6375, - kIzUnicodeName = 0x7075, - kWzAES = 0x9901 - }; - } - - namespace NNtfsExtra - { - const UInt16 kTagTime = 1; - enum - { - kMTime = 0, - kATime, - kCTime - }; - } - - namespace NUnixTime - { - enum - { - kMTime = 0, - kATime, - kCTime - }; - } - - namespace NFlags - { - const unsigned kEncrypted = 1 << 0; - const unsigned kLzmaEOS = 1 << 1; - const unsigned kDescriptorUsedMask = 1 << 3; - const unsigned kStrongEncrypted = 1 << 6; - const unsigned kUtf8 = 1 << 11; - - const unsigned kImplodeDictionarySizeMask = 1 << 1; - const unsigned kImplodeLiteralsOnMask = 1 << 2; - - const unsigned kDeflateTypeBitStart = 1; - const unsigned kNumDeflateTypeBits = 2; - const unsigned kNumDeflateTypes = (1 << kNumDeflateTypeBits); - const unsigned kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1; - } - - namespace NHostOS - { - enum EEnum - { - kFAT = 0, - kAMIGA = 1, - kVMS = 2, // VAX/VMS - kUnix = 3, - kVM_CMS = 4, - kAtari = 5, // what if it's a minix filesystem? [cjh] - kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) - kMac = 7, - kZ_System = 8, - kCPM = 9, - kTOPS20 = 10, // pkzip 2.50 NTFS - kNTFS = 11, // filesystem used by Windows NT - kQDOS = 12, // SMS/QDOS - kAcorn = 13, // Archimedes Acorn RISC OS - kVFAT = 14, // filesystem used by Windows 95, NT - kMVS = 15, - kBeOS = 16, // hybrid POSIX/database filesystem - kTandem = 17, - kOS400 = 18, - kOSX = 19 - }; - } - - - namespace NAmigaAttrib - { - const UInt32 kIFMT = 06000; // Amiga file type mask - const UInt32 kIFDIR = 04000; // Amiga directory - const UInt32 kIFREG = 02000; // Amiga regular file - const UInt32 kIHIDDEN = 00200; // to be supported in AmigaDOS 3.x - const UInt32 kISCRIPT = 00100; // executable script (text command file) - const UInt32 kIPURE = 00040; // allow loading into resident memory - const UInt32 kIARCHIVE = 00020; // not modified since bit was last set - const UInt32 kIREAD = 00010; // can be opened for reading - const UInt32 kIWRITE = 00004; // can be opened for writing - const UInt32 kIEXECUTE = 00002; // executable image, a loadable runfile - const UInt32 kIDELETE = 00001; // can be deleted - } -} - -}} - -#endif +// ZipHeader.h + +#ifndef ZIP7_INC_ARCHIVE_ZIP_HEADER_H +#define ZIP7_INC_ARCHIVE_ZIP_HEADER_H + +#include "../../../Common/MyTypes.h" + +namespace NArchive { +namespace NZip { + +const unsigned kMarkerSize = 4; + +namespace NSignature +{ + const UInt32 kLocalFileHeader = 0x04034B50; + const UInt32 kDataDescriptor = 0x08074B50; + const UInt32 kCentralFileHeader = 0x02014B50; + const UInt32 kEcd = 0x06054B50; + const UInt32 kEcd64 = 0x06064B50; + const UInt32 kEcd64Locator = 0x07064B50; + const UInt32 kSpan = 0x08074B50; + const UInt32 kNoSpan = 0x30304B50; // PK00, replaces kSpan, if there is only 1 segment +} + +const unsigned kLocalHeaderSize = 4 + 26; // including signature +const unsigned kDataDescriptorSize32 = 4 + 4 + 4 * 2; // including signature +const unsigned kDataDescriptorSize64 = 4 + 4 + 8 * 2; // including signature +const unsigned kCentralHeaderSize = 4 + 42; // including signature + +const unsigned kEcdSize = 22; // including signature +const unsigned kEcd64_MainSize = 44; +const unsigned kEcd64_FullSize = 12 + kEcd64_MainSize; +const unsigned kEcd64Locator_Size = 20; + +namespace NFileHeader +{ + namespace NCompressionMethod + { + enum EType + { + kStore = 0, + kShrink = 1, + kReduce1 = 2, + kReduce2 = 3, + kReduce3 = 4, + kReduce4 = 5, + kImplode = 6, + kTokenize = 7, + kDeflate = 8, + kDeflate64 = 9, + kPKImploding = 10, + + kBZip2 = 12, + + kLZMA = 14, + + kTerse = 18, + kLz77 = 19, + kZstdPk = 20, + + kZstdWz = 93, + kMP3 = 94, + kXz = 95, + kJpeg = 96, + kWavPack = 97, + kPPMd = 98, + kWzAES = 99 + }; + + const Byte kMadeByProgramVersion = 63; + + const Byte kExtractVersion_Default = 10; + const Byte kExtractVersion_Dir = 20; + const Byte kExtractVersion_ZipCrypto = 20; + const Byte kExtractVersion_Deflate = 20; + const Byte kExtractVersion_Deflate64 = 21; + const Byte kExtractVersion_Zip64 = 45; + const Byte kExtractVersion_BZip2 = 46; + const Byte kExtractVersion_Aes = 51; + const Byte kExtractVersion_LZMA = 63; + const Byte kExtractVersion_PPMd = 63; + const Byte kExtractVersion_Xz = 20; // test it + } + + namespace NExtraID + { + enum + { + kZip64 = 0x01, + kNTFS = 0x0A, + kUnix0 = 0x0D, // Info-ZIP : (UNIX) PK + kStrongEncrypt = 0x17, + kIzNtSecurityDescriptor = 0x4453, + kUnixTime = 0x5455, // "UT" (time) Info-ZIP + kUnix1 = 0x5855, // Info-ZIP + kIzUnicodeComment = 0x6375, + kIzUnicodeName = 0x7075, + kUnix2 = 0x7855, // Info-ZIP + kUnixN = 0x7875, // Info-ZIP + kWzAES = 0x9901, + kApkAlign = 0xD935 + }; + } + + namespace NNtfsExtra + { + const UInt16 kTagTime = 1; + enum + { + kMTime = 0, + kATime, + kCTime + }; + } + + namespace NUnixTime + { + enum + { + kMTime = 0, + kATime, + kCTime + }; + } + + namespace NUnixExtra + { + enum + { + kATime = 0, + kMTime + }; + } + + namespace NFlags + { + const unsigned kEncrypted = 1 << 0; + const unsigned kLzmaEOS = 1 << 1; + const unsigned kDescriptorUsedMask = 1 << 3; + const unsigned kStrongEncrypted = 1 << 6; + const unsigned kUtf8 = 1 << 11; + const unsigned kAltStream = 1 << 14; + + const unsigned kImplodeDictionarySizeMask = 1 << 1; + const unsigned kImplodeLiteralsOnMask = 1 << 2; + + /* + const unsigned kDeflateTypeBitStart = 1; + const unsigned kNumDeflateTypeBits = 2; + const unsigned kNumDeflateTypes = (1 << kNumDeflateTypeBits); + const unsigned kDeflateTypeMask = (1 << kNumDeflateTypeBits) - 1; + */ + } + + namespace NHostOS + { + enum EEnum + { + kFAT = 0, + kAMIGA = 1, + kVMS = 2, // VAX/VMS + kUnix = 3, + kVM_CMS = 4, + kAtari = 5, // what if it's a minix filesystem? [cjh] + kHPFS = 6, // filesystem used by OS/2 (and NT 3.x) + kMac = 7, + kZ_System = 8, + kCPM = 9, + kTOPS20 = 10, // pkzip 2.50 NTFS + kNTFS = 11, // filesystem used by Windows NT + kQDOS = 12, // SMS/QDOS + kAcorn = 13, // Archimedes Acorn RISC OS + kVFAT = 14, // filesystem used by Windows 95, NT + kMVS = 15, + kBeOS = 16, // hybrid POSIX/database filesystem + kTandem = 17, + kOS400 = 18, + kOSX = 19 + }; + } + + + namespace NAmigaAttrib + { + const UInt32 kIFMT = 06000; // Amiga file type mask + const UInt32 kIFDIR = 04000; // Amiga directory + const UInt32 kIFREG = 02000; // Amiga regular file + const UInt32 kIHIDDEN = 00200; // to be supported in AmigaDOS 3.x + const UInt32 kISCRIPT = 00100; // executable script (text command file) + const UInt32 kIPURE = 00040; // allow loading into resident memory + const UInt32 kIARCHIVE = 00020; // not modified since bit was last set + const UInt32 kIREAD = 00010; // can be opened for reading + const UInt32 kIWRITE = 00004; // can be opened for writing + const UInt32 kIEXECUTE = 00002; // executable image, a loadable runfile + const UInt32 kIDELETE = 00001; // can be deleted + } +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipIn.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.cpp 2023-12-20 09:00:00.000000000 +0000 @@ -1,2277 +1,3485 @@ -// Archive/ZipIn.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../Common/DynamicBuffer.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Common/StreamUtils.h" - -#include "../IArchive.h" - -#include "ZipIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -#define G16(offs, v) v = Get16(p + (offs)) -#define G32(offs, v) v = Get32(p + (offs)) -#define G64(offs, v) v = Get64(p + (offs)) - -namespace NArchive { -namespace NZip { - -struct CEcd -{ - UInt16 ThisDisk; - UInt16 CdDisk; - UInt16 NumEntries_in_ThisDisk; - UInt16 NumEntries; - UInt32 Size; - UInt32 Offset; - UInt16 CommentSize; - - bool IsEmptyArc() const - { - return ThisDisk == 0 - && CdDisk == 0 - && NumEntries_in_ThisDisk == 0 - && NumEntries == 0 - && Size == 0 - && Offset == 0 // test it - ; - } - - void Parse(const Byte *p); // (p) doesn't include signature -}; - -void CEcd::Parse(const Byte *p) -{ - // (p) doesn't include signature - G16(0, ThisDisk); - G16(2, CdDisk); - G16(4, NumEntries_in_ThisDisk); - G16(6, NumEntries); - G32(8, Size); - G32(12, Offset); - G16(16, CommentSize); -} - - -void CCdInfo::ParseEcd32(const Byte *p) -{ - // (p) includes signature - p += 4; - G16(0, ThisDisk); - G16(2, CdDisk); - G16(4, NumEntries_in_ThisDisk); - G16(6, NumEntries); - G32(8, Size); - G32(12, Offset); - G16(16, CommentSize); -} - -void CCdInfo::ParseEcd64e(const Byte *p) -{ - // (p) exclude signature - G16(0, VersionMade); - G16(2, VersionNeedExtract); - G32(4, ThisDisk); - G32(8, CdDisk); - - G64(12, NumEntries_in_ThisDisk); - G64(20, NumEntries); - G64(28, Size); - G64(36, Offset); -} - - -struct CLocator -{ - UInt32 Ecd64Disk; - UInt32 NumDisks; - UInt64 Ecd64Offset; - - CLocator(): Ecd64Disk(0), NumDisks(0), Ecd64Offset(0) {} - - void Parse(const Byte *p) - { - G32(0, Ecd64Disk); - G64(4, Ecd64Offset); - G32(12, NumDisks); - } -}; - - - - -void CInArchive::ClearRefs() -{ - StreamRef.Release(); - Stream = NULL; - StartStream = NULL; - Callback = NULL; - - Vols.Clear(); -} - -void CInArchive::Close() -{ - _processedCnt = 0; - IsArc = false; - IsArcOpen = false; - IsMultiVol = false; - UseDisk_in_SingleVol = false; - EcdVolIndex = 0; - HeadersError = false; - HeadersWarning = false; - ExtraMinorError = false; - UnexpectedEnd = false; - NoCentralDir = false; - IsZip64 = false; - MarkerIsFound = false; - - ClearRefs(); -} - - -HRESULT CInArchive::Seek(UInt64 offset) -{ - return Stream->Seek(offset, STREAM_SEEK_SET, NULL); -} - - -static bool CheckDosTime(UInt32 dosTime) -{ - if (dosTime == 0) - return true; - unsigned month = (dosTime >> 21) & 0xF; - unsigned day = (dosTime >> 16) & 0x1F; - unsigned hour = (dosTime >> 11) & 0x1F; - unsigned min = (dosTime >> 5) & 0x3F; - unsigned sec = (dosTime & 0x1F) * 2; - if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) - return false; - return true; -} - -API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size) -{ - if (size < 8) - return k_IsArc_Res_NEED_MORE; - if (p[0] != 'P') - return k_IsArc_Res_NO; - - UInt32 value = Get32(p); - - if (value == NSignature::kNoSpan - || value == NSignature::kSpan) - { - p += 4; - size -= 4; - } - - value = Get32(p); - - if (value == NSignature::kEcd) - { - if (size < kEcdSize) - return k_IsArc_Res_NEED_MORE; - CEcd ecd; - ecd.Parse(p + 4); - // if (ecd.cdSize != 0) - if (!ecd.IsEmptyArc()) - return k_IsArc_Res_NO; - return k_IsArc_Res_YES; // k_IsArc_Res_YES_2; - } - - if (value != NSignature::kLocalFileHeader) - return k_IsArc_Res_NO; - - if (size < kLocalHeaderSize) - return k_IsArc_Res_NEED_MORE; - - p += 4; - - { - const unsigned kPureHeaderSize = kLocalHeaderSize - 4; - unsigned i; - for (i = 0; i < kPureHeaderSize && p[i] == 0; i++); - if (i == kPureHeaderSize) - return k_IsArc_Res_NEED_MORE; - } - - /* - if (p[0] >= 128) // ExtractVersion.Version; - return k_IsArc_Res_NO; - */ - - // ExtractVersion.Version = p[0]; - // ExtractVersion.HostOS = p[1]; - // Flags = Get16(p + 2); - // Method = Get16(p + 4); - /* - // 9.33: some zip archives contain incorrect value in timestamp. So we don't check it now - UInt32 dosTime = Get32(p + 6); - if (!CheckDosTime(dosTime)) - return k_IsArc_Res_NO; - */ - // Crc = Get32(p + 10); - // PackSize = Get32(p + 14); - // Size = Get32(p + 18); - const unsigned nameSize = Get16(p + 22); - unsigned extraSize = Get16(p + 24); - const UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize; - if (extraOffset + extraSize > (1 << 16)) - return k_IsArc_Res_NO; - - p -= 4; - - { - size_t rem = size - kLocalHeaderSize; - if (rem > nameSize) - rem = nameSize; - const Byte *p2 = p + kLocalHeaderSize; - for (size_t i = 0; i < rem; i++) - if (p2[i] == 0) - if (i != nameSize - 1) - return k_IsArc_Res_NO; - } - - if (size < extraOffset) - return k_IsArc_Res_NEED_MORE; - - if (extraSize > 0) - { - p += extraOffset; - size -= extraOffset; - while (extraSize != 0) - { - if (extraSize < 4) - { - // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. - // so we return k_IsArc_Res_YES to support such archives. - // return k_IsArc_Res_NO; // do we need to support such extra ? - return k_IsArc_Res_YES; - } - if (size < 4) - return k_IsArc_Res_NEED_MORE; - unsigned dataSize = Get16(p + 2); - size -= 4; - extraSize -= 4; - p += 4; - if (dataSize > extraSize) - return k_IsArc_Res_NO; - if (dataSize > size) - return k_IsArc_Res_NEED_MORE; - size -= dataSize; - extraSize -= dataSize; - p += dataSize; - } - } - - return k_IsArc_Res_YES; -} - -static UInt32 IsArc_Zip_2(const Byte *p, size_t size, bool isFinal) -{ - UInt32 res = IsArc_Zip(p, size); - if (res == k_IsArc_Res_NEED_MORE && isFinal) - return k_IsArc_Res_NO; - return res; -} - - - -HRESULT CInArchive::FindMarker(IInStream *stream, const UInt64 *searchLimit) -{ - ArcInfo.MarkerPos = m_Position; - ArcInfo.MarkerPos2 = m_Position; - - if (searchLimit && *searchLimit == 0) - { - Byte startBuf[kMarkerSize]; - { - size_t processed = kMarkerSize; - RINOK(ReadStream(stream, startBuf, &processed)); - m_Position += processed; - if (processed != kMarkerSize) - return S_FALSE; - } - - m_Signature = Get32(startBuf); - - if (m_Signature != NSignature::kEcd && - m_Signature != NSignature::kLocalFileHeader) - { - if (m_Signature != NSignature::kNoSpan) - { - if (m_Signature != NSignature::kSpan) - return S_FALSE; - if (m_Position != 4) // we don't support multivol archives with sfx stub - return S_FALSE; - ArcInfo.IsSpanMode = true; - } - size_t processed = kMarkerSize; - RINOK(ReadStream(stream, startBuf, &processed)); - m_Position += processed; - if (processed != kMarkerSize) - return S_FALSE; - m_Signature = Get32(startBuf); - if (m_Signature != NSignature::kEcd && - m_Signature != NSignature::kLocalFileHeader) - return S_FALSE; - ArcInfo.MarkerPos2 += 4; - } - - // we use weak test in case of (*searchLimit == 0) - // since error will be detected later in Open function - return S_OK; // maybe we need to search backward. - } - - const size_t kBufSize = (size_t)1 << 18; // must be larger than kCheckSize - const size_t kCheckSize = (size_t)1 << 16; // must be smaller than kBufSize - CByteArr buffer(kBufSize); - - size_t numBytesInBuffer = 0; - UInt64 curScanPos = 0; - - for (;;) - { - size_t numReadBytes = kBufSize - numBytesInBuffer; - RINOK(ReadStream(stream, buffer + numBytesInBuffer, &numReadBytes)); - m_Position += numReadBytes; - numBytesInBuffer += numReadBytes; - const bool isFinished = (numBytesInBuffer != kBufSize); - - size_t limit = numBytesInBuffer;; - if (isFinished) - { - if (limit == 0) - break; - limit--; - } - else - limit -= kCheckSize; - - if (searchLimit && curScanPos + limit > *searchLimit) - limit = (size_t)(*searchLimit - curScanPos + 1); - - if (limit < 1) - break; - - const Byte *buf = buffer; - for (size_t pos = 0; pos < limit; pos++) - { - if (buf[pos] != 0x50) - continue; - if (buf[pos + 1] != 0x4B) - continue; - size_t rem = numBytesInBuffer - pos; - UInt32 res = IsArc_Zip_2(buf + pos, rem, isFinished); - if (res != k_IsArc_Res_NO) - { - if (rem < kMarkerSize) - return S_FALSE; - m_Signature = Get32(buf + pos); - ArcInfo.MarkerPos += curScanPos + pos; - ArcInfo.MarkerPos2 = ArcInfo.MarkerPos; - if (m_Signature == NSignature::kNoSpan - || m_Signature == NSignature::kSpan) - { - m_Signature = Get32(buf + pos + 4); - ArcInfo.MarkerPos2 += 4; - } - m_Position = ArcInfo.MarkerPos2 + kMarkerSize; - return S_OK; - } - } - - if (isFinished) - break; - - curScanPos += limit; - numBytesInBuffer -= limit; - memmove(buffer, buffer + limit, numBytesInBuffer); - } - - return S_FALSE; -} - - -HRESULT CInArchive::IncreaseRealPosition(Int64 addValue, bool &isFinished) -{ - isFinished = false; - if (!IsMultiVol) - return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position); - - for (;;) - { - if (addValue == 0) - return S_OK; - if (addValue > 0) - { - if (Vols.StreamIndex < 0) - return S_FALSE; - if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size()) - { - isFinished = true; - return S_OK; - } - { - const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex]; - if (!s.Stream) - { - isFinished = true; - return S_OK; - } - if (m_Position > s.Size) - return S_FALSE; - UInt64 rem = s.Size - m_Position; - if ((UInt64)addValue <= rem) - return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position); - RINOK(Stream->Seek(s.Size, STREAM_SEEK_SET, &m_Position)); - addValue -= rem; - Stream = NULL; - Vols.StreamIndex++; - if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size()) - { - isFinished = true; - return S_OK; - } - } - const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex]; - if (!s2.Stream) - { - isFinished = true; - return S_OK; - } - Stream = s2.Stream; - m_Position = 0; - RINOK(Stream->Seek(0, STREAM_SEEK_SET, &m_Position)); - } - else - { - if (!Stream) - return S_FALSE; - { - if (m_Position >= (UInt64)(-addValue)) - return Stream->Seek(addValue, STREAM_SEEK_CUR, &m_Position); - addValue += m_Position; - RINOK(Stream->Seek(0, STREAM_SEEK_SET, &m_Position)); - m_Position = 0; - Stream = NULL; - if (--Vols.StreamIndex < 0) - return S_FALSE; - } - const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex]; - if (!s2.Stream) - return S_FALSE; - Stream = s2.Stream; - m_Position = s2.Size; - RINOK(Stream->Seek(s2.Size, STREAM_SEEK_SET, &m_Position)); - } - } -} - - -class CUnexpectEnd {}; - - -HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) -{ - size_t realProcessedSize = size; - HRESULT result = S_OK; - if (_inBufMode) - { - try { realProcessedSize = _inBuffer.ReadBytes((Byte *)data, size); } - catch (const CInBufferException &e) { return e.ErrorCode; } - } - else - result = ReadStream(Stream, data, &realProcessedSize); - if (processedSize) - *processedSize = (UInt32)realProcessedSize; - m_Position += realProcessedSize; - return result; -} - -void CInArchive::SafeReadBytes(void *data, unsigned size) -{ - size_t processed = size; - - HRESULT result = S_OK; - - if (!_inBufMode) - result = ReadStream(Stream, data, &processed); - else - { - for (;;) - { - processed = _inBuffer.ReadBytes((Byte *)data, size); - if (processed != 0 - || IsMultiVol - || !CanStartNewVol - || Vols.StreamIndex < 0 - || (unsigned)Vols.StreamIndex >= Vols.Streams.Size()) - break; - Vols.StreamIndex++; - const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex]; - if (!s.Stream) - break; - // if (Vols.NeedSeek) - { - result = s.Stream->Seek(0, STREAM_SEEK_SET, NULL); - m_Position = 0; - if (result != S_OK) - break; - Vols.NeedSeek = false; - } - _inBuffer.SetStream(s.Stream); - _inBuffer.Init(); - } - CanStartNewVol = false; - } - - m_Position += processed; - _processedCnt += processed; - - if (result != S_OK) - throw CSystemException(result); - - if (processed != size) - throw CUnexpectEnd(); -} - -void CInArchive::ReadBuffer(CByteBuffer &buffer, unsigned size) -{ - buffer.Alloc(size); - if (size > 0) - SafeReadBytes(buffer, size); -} - -Byte CInArchive::ReadByte() -{ - Byte b; - SafeReadBytes(&b, 1); - return b; -} - -UInt16 CInArchive::ReadUInt16() { Byte buf[2]; SafeReadBytes(buf, 2); return Get16(buf); } -UInt32 CInArchive::ReadUInt32() { Byte buf[4]; SafeReadBytes(buf, 4); return Get32(buf); } -UInt64 CInArchive::ReadUInt64() { Byte buf[8]; SafeReadBytes(buf, 8); return Get64(buf); } - -// we use Skip() inside headers only, so no need for stream change in multivol. - -void CInArchive::Skip(unsigned num) -{ - if (_inBufMode) - { - size_t skip = _inBuffer.Skip(num); - m_Position += skip; - _processedCnt += skip; - if (skip != num) - throw CUnexpectEnd(); - } - else - { - for (unsigned i = 0; i < num; i++) - ReadByte(); - } -} - -void CInArchive::Skip64(UInt64 num) -{ - for (UInt64 i = 0; i < num; i++) - ReadByte(); -} - - -void CInArchive::ReadFileName(unsigned size, AString &s) -{ - if (size == 0) - { - s.Empty(); - return; - } - SafeReadBytes(s.GetBuf(size), size); - s.ReleaseBuf_CalcLen(size); -} - - -bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, - UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber) -{ - extraBlock.Clear(); - - UInt32 remain = extraSize; - - while (remain >= 4) - { - CExtraSubBlock subBlock; - subBlock.ID = ReadUInt16(); - unsigned dataSize = ReadUInt16(); - remain -= 4; - if (dataSize > remain) // it's bug - { - HeadersWarning = true; - Skip(remain); - return false; - } - if (subBlock.ID == NFileHeader::NExtraID::kZip64) - { - if (unpackSize == 0xFFFFFFFF) - { - if (dataSize < 8) - { - HeadersWarning = true; - Skip(remain); - return false; - } - unpackSize = ReadUInt64(); - remain -= 8; - dataSize -= 8; - } - if (packSize == 0xFFFFFFFF) - { - if (dataSize < 8) - break; - packSize = ReadUInt64(); - remain -= 8; - dataSize -= 8; - } - if (localHeaderOffset == 0xFFFFFFFF) - { - if (dataSize < 8) - break; - localHeaderOffset = ReadUInt64(); - remain -= 8; - dataSize -= 8; - } - if (diskStartNumber == 0xFFFF) - { - if (dataSize < 4) - break; - diskStartNumber = ReadUInt32(); - remain -= 4; - dataSize -= 4; - } - Skip(dataSize); - } - else - { - ReadBuffer(subBlock.Data, dataSize); - extraBlock.SubBlocks.Add(subBlock); - } - remain -= dataSize; - } - - if (remain != 0) - { - ExtraMinorError = true; - // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers. - // so we don't return false, but just set warning flag - // return false; - } - - Skip(remain); - return true; -} - - -bool CInArchive::ReadLocalItem(CItemEx &item) -{ - item.Disk = 0; - if (IsMultiVol && Vols.StreamIndex >= 0) - item.Disk = Vols.StreamIndex; - const unsigned kPureHeaderSize = kLocalHeaderSize - 4; - Byte p[kPureHeaderSize]; - SafeReadBytes(p, kPureHeaderSize); - { - unsigned i; - for (i = 0; i < kPureHeaderSize && p[i] == 0; i++); - if (i == kPureHeaderSize) - return false; - } - - item.ExtractVersion.Version = p[0]; - item.ExtractVersion.HostOS = p[1]; - G16(2, item.Flags); - G16(4, item.Method); - G32(6, item.Time); - G32(10, item.Crc); - G32(14, item.PackSize); - G32(18, item.Size); - const unsigned nameSize = Get16(p + 22); - const unsigned extraSize = Get16(p + 24); - ReadFileName(nameSize, item.Name); - item.LocalFullHeaderSize = kLocalHeaderSize + (UInt32)nameSize + extraSize; - - /* - if (item.IsDir()) - item.Size = 0; // check It - */ - - if (extraSize > 0) - { - UInt64 localHeaderOffset = 0; - UInt32 diskStartNumber = 0; - if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize, - localHeaderOffset, diskStartNumber)) - { - /* Most of archives are OK for Extra. But there are some rare cases - that have error. And if error in first item, it can't open archive. - So we ignore that error */ - // return false; - } - } - - if (!CheckDosTime(item.Time)) - { - HeadersWarning = true; - // return false; - } - - if (item.Name.Len() != nameSize) - { - // we support "bad" archives with null-terminated name. - if (item.Name.Len() + 1 != nameSize) - return false; - HeadersWarning = true; - } - - return item.LocalFullHeaderSize <= ((UInt32)1 << 16); -} - - -static bool FlagsAreSame(const CItem &i1, const CItem &i2) -{ - if (i1.Method != i2.Method) - return false; - if (i1.Flags == i2.Flags) - return true; - UInt32 mask = 0xFFFF; - switch (i1.Method) - { - case NFileHeader::NCompressionMethod::kDeflated: - mask = 0x7FF9; - break; - default: - if (i1.Method <= NFileHeader::NCompressionMethod::kImploded) - mask = 0x7FFF; - } - - // we can ignore utf8 flag, if name is ascii - if ((i1.Flags ^ i2.Flags) & NFileHeader::NFlags::kUtf8) - if (i1.Name.IsAscii() && i2.Name.IsAscii()) - mask &= ~NFileHeader::NFlags::kUtf8; - - return ((i1.Flags & mask) == (i2.Flags & mask)); -} - - -// #ifdef _WIN32 -static bool AreEqualPaths_IgnoreSlashes(const char *s1, const char *s2) -{ - for (;;) - { - char c1 = *s1++; - char c2 = *s2++; - if (c1 == c2) - { - if (c1 == 0) - return true; - } - else - { - if (c1 == '\\') c1 = '/'; - if (c2 == '\\') c2 = '/'; - if (c1 != c2) - return false; - } - } -} -// #endif - - -static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem) -{ - if (!FlagsAreSame(cdItem, localItem)) - return false; - if (!localItem.HasDescriptor()) - { - if (cdItem.Crc != localItem.Crc || - cdItem.PackSize != localItem.PackSize || - cdItem.Size != localItem.Size) - return false; - } - /* pkzip 2.50 creates incorrect archives. It uses - - WIN encoding for name in local header - - OEM encoding for name in central header - We don't support these strange items. */ - - /* if (cdItem.Name.Len() != localItem.Name.Len()) - return false; - */ - if (cdItem.Name != localItem.Name) - { - // #ifdef _WIN32 - // some xap files use backslash in central dir items. - // we can ignore such errors in windows, where all slashes are converted to backslashes - unsigned hostOs = cdItem.GetHostOS(); - - if (hostOs == NFileHeader::NHostOS::kFAT || - hostOs == NFileHeader::NHostOS::kNTFS) - { - if (!AreEqualPaths_IgnoreSlashes(cdItem.Name, localItem.Name)) - { - // pkzip 2.50 uses DOS encoding in central dir and WIN encoding in local header. - // so we ignore that error - if (hostOs != NFileHeader::NHostOS::kFAT - || cdItem.MadeByVersion.Version != 25) - return false; - } - } - /* - else - #endif - return false; - */ - } - return true; -} - - -HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail) -{ - isAvail = true; - if (item.FromLocal) - return S_OK; - try - { - UInt64 offset = item.LocalHeaderPos; - - if (IsMultiVol) - { - if (item.Disk >= Vols.Streams.Size()) - { - isAvail = false; - return S_FALSE; - } - IInStream *str2 = Vols.Streams[item.Disk].Stream; - if (!str2) - { - isAvail = false; - return S_FALSE; - } - RINOK(str2->Seek(offset, STREAM_SEEK_SET, NULL)); - Stream = str2; - Vols.StreamIndex = item.Disk; - } - else - { - if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex) - { - isAvail = false; - return S_FALSE; - } - Stream = StreamRef; - - offset += ArcInfo.Base; - if (ArcInfo.Base < 0 && (Int64)offset < 0) - { - isAvail = false; - return S_FALSE; - } - RINOK(Seek(offset)); - } - - - CItemEx localItem; - if (ReadUInt32() != NSignature::kLocalFileHeader) - return S_FALSE; - ReadLocalItem(localItem); - if (!AreItemsEqual(localItem, item)) - return S_FALSE; - item.LocalFullHeaderSize = localItem.LocalFullHeaderSize; - item.LocalExtra = localItem.LocalExtra; - item.FromLocal = true; - } - catch(...) { return S_FALSE; } - return S_OK; -} - - -HRESULT CInArchive::ReadLocalItemDescriptor(CItemEx &item) -{ - const unsigned kBufSize = (1 << 12); - Byte buf[kBufSize]; - - UInt32 numBytesInBuffer = 0; - UInt32 packedSize = 0; - - for (;;) - { - UInt32 processedSize; - RINOK(ReadBytes(buf + numBytesInBuffer, kBufSize - numBytesInBuffer, &processedSize)); - numBytesInBuffer += processedSize; - if (numBytesInBuffer < kDataDescriptorSize) - return S_FALSE; - - UInt32 i; - for (i = 0; i <= numBytesInBuffer - kDataDescriptorSize; i++) - { - // descriptor signature field is Info-ZIP's extension to pkware Zip specification. - // New ZIP specification also allows descriptorSignature. - if (buf[i] != 0x50) - continue; - // !!!! It must be fixed for Zip64 archives - if (Get32(buf + i) == NSignature::kDataDescriptor) - { - UInt32 descriptorPackSize = Get32(buf + i + 8); - if (descriptorPackSize == packedSize + i) - { - item.Crc = Get32(buf + i + 4); - item.PackSize = descriptorPackSize; - item.Size = Get32(buf + i + 12); - bool isFinished; - return IncreaseRealPosition((Int64)(Int32)(0 - (numBytesInBuffer - i - kDataDescriptorSize)), isFinished); - } - } - } - - packedSize += i; - unsigned j; - for (j = 0; i < numBytesInBuffer; i++, j++) - buf[j] = buf[i]; - numBytesInBuffer = j; - } -} - - -HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) -{ - if (item.FromLocal) - return S_OK; - try - { - bool isAvail = true; - RINOK(ReadLocalItemAfterCdItem(item, isAvail)); - if (item.HasDescriptor()) - { - // pkzip's version without descriptor is not supported - RINOK(Seek(ArcInfo.Base + item.GetDataPosition() + item.PackSize)); - if (ReadUInt32() != NSignature::kDataDescriptor) - return S_FALSE; - UInt32 crc = ReadUInt32(); - UInt64 packSize, unpackSize; - - /* - if (IsZip64) - { - packSize = ReadUInt64(); - unpackSize = ReadUInt64(); - } - else - */ - { - packSize = ReadUInt32(); - unpackSize = ReadUInt32(); - } - - if (crc != item.Crc || item.PackSize != packSize || item.Size != unpackSize) - return S_FALSE; - } - } - catch(...) { return S_FALSE; } - return S_OK; -} - - -HRESULT CInArchive::ReadCdItem(CItemEx &item) -{ - item.FromCentral = true; - Byte p[kCentralHeaderSize - 4]; - SafeReadBytes(p, kCentralHeaderSize - 4); - - item.MadeByVersion.Version = p[0]; - item.MadeByVersion.HostOS = p[1]; - item.ExtractVersion.Version = p[2]; - item.ExtractVersion.HostOS = p[3]; - G16(4, item.Flags); - G16(6, item.Method); - G32(8, item.Time); - G32(12, item.Crc); - G32(16, item.PackSize); - G32(20, item.Size); - const unsigned nameSize = Get16(p + 24); - const unsigned extraSize = Get16(p + 26); - const unsigned commentSize = Get16(p + 28); - G16(30, item.Disk); - G16(32, item.InternalAttrib); - G32(34, item.ExternalAttrib); - G32(38, item.LocalHeaderPos); - ReadFileName(nameSize, item.Name); - - if (extraSize > 0) - ReadExtra(extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk); - - // May be these strings must be deleted - /* - if (item.IsDir()) - item.Size = 0; - */ - - ReadBuffer(item.Comment, commentSize); - return S_OK; -} - - -HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) -{ - if (offset >= ((UInt64)1 << 63)) - return S_FALSE; - RINOK(Seek(offset)); - Byte buf[kEcd64_FullSize]; - - RINOK(ReadStream_FALSE(Stream, buf, kEcd64_FullSize)); - - if (Get32(buf) != NSignature::kEcd64) - return S_FALSE; - UInt64 mainSize = Get64(buf + 4); - if (mainSize < kEcd64_MainSize || mainSize > ((UInt64)1 << 32)) - return S_FALSE; - cdInfo.ParseEcd64e(buf + 12); - return S_OK; -} - - -HRESULT CInArchive::FindCd(bool checkOffsetMode) -{ - CCdInfo &cdInfo = Vols.ecd; - - UInt64 endPos; - - RINOK(Stream->Seek(0, STREAM_SEEK_END, &endPos)); - - const UInt32 kBufSizeMax = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize; - const UInt32 bufSize = (endPos < kBufSizeMax) ? (UInt32)endPos : kBufSizeMax; - if (bufSize < kEcdSize) - return S_FALSE; - CByteArr byteBuffer(bufSize); - - const UInt64 startPos = endPos - bufSize; - RINOK(Stream->Seek(startPos, STREAM_SEEK_SET, &m_Position)); - if (m_Position != startPos) - return S_FALSE; - - RINOK(ReadStream_FALSE(Stream, byteBuffer, bufSize)); - - for (UInt32 i = bufSize - kEcdSize + 1;;) - { - if (i == 0) - return S_FALSE; - - const Byte *buf = byteBuffer; - - for (;;) - { - i--; - if (buf[i] == 0x50) - break; - if (i == 0) - return S_FALSE; - } - - if (Get32(buf + i) != NSignature::kEcd) - continue; - - cdInfo.ParseEcd32(buf + i); - - if (i >= kEcd64Locator_Size) - { - const Byte *locatorPtr = buf + i - kEcd64Locator_Size; - if (Get32(locatorPtr) == NSignature::kEcd64Locator) - { - CLocator locator; - locator.Parse(locatorPtr + 4); - if ((cdInfo.ThisDisk == locator.NumDisks - 1 || cdInfo.ThisDisk == 0xFFFF) - && locator.Ecd64Disk < locator.NumDisks) - { - if (locator.Ecd64Disk != cdInfo.ThisDisk && cdInfo.ThisDisk != 0xFFFF) - return E_NOTIMPL; - - // Most of the zip64 use fixed size Zip64 ECD - // we try relative backward reading. - - UInt64 absEcd64 = endPos - bufSize + i - (kEcd64Locator_Size + kEcd64_FullSize); - if (checkOffsetMode || absEcd64 == locator.Ecd64Offset) - { - const Byte *ecd64 = locatorPtr - kEcd64_FullSize; - if (Get32(ecd64) == NSignature::kEcd64) - { - UInt64 mainEcd64Size = Get64(ecd64 + 4); - if (mainEcd64Size == kEcd64_MainSize) - { - cdInfo.ParseEcd64e(ecd64 + 12); - ArcInfo.Base = absEcd64 - locator.Ecd64Offset; - // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; - return S_OK; - } - } - } - - // some zip64 use variable size Zip64 ECD. - // we try to use absolute offset from locator. - - if (absEcd64 != locator.Ecd64Offset) - { - if (TryEcd64(locator.Ecd64Offset, cdInfo) == S_OK) - { - ArcInfo.Base = 0; - // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; - return S_OK; - } - } - - // for variable Zip64 ECD with for archives with offset != 0. - - if (checkOffsetMode - && ArcInfo.MarkerPos != 0 - && ArcInfo.MarkerPos + locator.Ecd64Offset != absEcd64) - { - if (TryEcd64(ArcInfo.MarkerPos + locator.Ecd64Offset, cdInfo) == S_OK) - { - ArcInfo.Base = ArcInfo.MarkerPos; - // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; - return S_OK; - } - } - } - } - } - - // bool isVolMode = (Vols.EndVolIndex != -1); - // UInt32 searchDisk = (isVolMode ? Vols.EndVolIndex : 0); - - if (/* searchDisk == thisDisk && */ cdInfo.CdDisk <= cdInfo.ThisDisk) - { - // if (isVolMode) - { - if (cdInfo.CdDisk != cdInfo.ThisDisk) - return S_OK; - } - - UInt64 absEcdPos = endPos - bufSize + i; - UInt64 cdEnd = cdInfo.Size + cdInfo.Offset; - ArcInfo.Base = 0; - // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; - if (absEcdPos != cdEnd) - { - /* - if (cdInfo.Offset <= 16 && cdInfo.Size != 0) - { - // here we support some rare ZIP files with Central directory at the start - ArcInfo.Base = 0; - } - else - */ - ArcInfo.Base = absEcdPos - cdEnd; - } - return S_OK; - } - } -} - - -HRESULT CInArchive::TryReadCd(CObjectVector &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize) -{ - items.Clear(); - - ISequentialInStream *stream; - - if (!IsMultiVol) - { - stream = this->StartStream; - Vols.StreamIndex = -1; - RINOK(this->StartStream->Seek(cdOffset, STREAM_SEEK_SET, &m_Position)); - if (m_Position != cdOffset) - return S_FALSE; - } - else - { - if (cdInfo.CdDisk >= Vols.Streams.Size()) - return S_FALSE; - IInStream *str2 = Vols.Streams[cdInfo.CdDisk].Stream; - if (!str2) - return S_FALSE; - RINOK(str2->Seek(cdOffset, STREAM_SEEK_SET, NULL)); - stream = str2; - Vols.NeedSeek = false; - Vols.StreamIndex = cdInfo.CdDisk; - m_Position = cdOffset; - } - - _inBuffer.SetStream(stream); - - _inBuffer.Init(); - _inBufMode = true; - - _processedCnt = 0; - - while (_processedCnt < cdSize) - { - CanStartNewVol = true; - if (ReadUInt32() != NSignature::kCentralFileHeader) - return S_FALSE; - { - CItemEx cdItem; - RINOK(ReadCdItem(cdItem)); - items.Add(cdItem); - } - if (Callback && (items.Size() & 0xFFF) == 0) - { - const UInt64 numFiles = items.Size(); - RINOK(Callback->SetCompleted(&numFiles, NULL)); - } - } - - CanStartNewVol = true; - - return (_processedCnt == cdSize) ? S_OK : S_FALSE; -} - - -HRESULT CInArchive::ReadCd(CObjectVector &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize) -{ - bool checkOffsetMode = true; - - if (IsMultiVol) - { - if (Vols.EndVolIndex == -1) - return S_FALSE; - Stream = Vols.Streams[Vols.EndVolIndex].Stream; - if (!Vols.StartIsZip) - checkOffsetMode = false; - } - else - Stream = StartStream; - - if (!Vols.ecd_wasRead) - { - RINOK(FindCd(checkOffsetMode)); - } - - CCdInfo &cdInfo = Vols.ecd; - - HRESULT res = S_FALSE; - - cdSize = cdInfo.Size; - cdOffset = cdInfo.Offset; - cdDisk = cdInfo.CdDisk; - - if (Callback) - { - RINOK(Callback->SetTotal(&cdInfo.NumEntries, NULL)); - } - - const UInt64 base = (IsMultiVol ? 0 : ArcInfo.Base); - res = TryReadCd(items, cdInfo, base + cdOffset, cdSize); - - if (res == S_FALSE && !IsMultiVol && base != ArcInfo.MarkerPos) - { - // do we need that additional attempt to read cd? - res = TryReadCd(items, cdInfo, ArcInfo.MarkerPos + cdOffset, cdSize); - if (res == S_OK) - ArcInfo.Base = ArcInfo.MarkerPos; - } - - return res; -} - - -static int FindItem(const CObjectVector &items, const CItemEx &item) -{ - unsigned left = 0, right = items.Size(); - for (;;) - { - if (left >= right) - return -1; - unsigned index = (left + right) / 2; - const CItemEx &item2 = items[index]; - if (item.Disk < item2.Disk) - right = index; - else if (item.Disk > item2.Disk) - left = index + 1; - else if (item.LocalHeaderPos == item2.LocalHeaderPos) - return index; - else if (item.LocalHeaderPos < item2.LocalHeaderPos) - right = index; - else - left = index + 1; - } -} - -static bool IsStrangeItem(const CItem &item) -{ - return item.Name.Len() > (1 << 14) || item.Method > (1 << 8); -} - - -HRESULT CInArchive::ReadLocals(CObjectVector &items) -{ - items.Clear(); - - while (m_Signature == NSignature::kLocalFileHeader) - { - CItemEx item; - item.LocalHeaderPos = m_Position - 4; - if (!IsMultiVol) - item.LocalHeaderPos -= ArcInfo.MarkerPos; - - // we write ralative LocalHeaderPos here. Later we can correct it to real Base. - - try - { - ReadLocalItem(item); - item.FromLocal = true; - bool isFinished = false; - - if (item.HasDescriptor()) - ReadLocalItemDescriptor(item); - else - { - /* - if (IsMultiVol) - { - const int kStep = 10000; - RINOK(IncreaseRealPosition(-kStep, isFinished)); - RINOK(IncreaseRealPosition(item.PackSize + kStep, isFinished)); - } - else - */ - RINOK(IncreaseRealPosition(item.PackSize, isFinished)); - } - - items.Add(item); - - if (isFinished) - throw CUnexpectEnd(); - - m_Signature = ReadUInt32(); - } - catch (CUnexpectEnd &) - { - if (items.IsEmpty() || items.Size() == 1 && IsStrangeItem(items[0])) - return S_FALSE; - throw; - } - - if (Callback && (items.Size() & 0xFF) == 0) - { - const UInt64 numFiles = items.Size(); - UInt64 numBytes = 0; - // if (!sMultiVol) - numBytes = item.LocalHeaderPos; - RINOK(Callback->SetCompleted(&numFiles, &numBytes)); - } - } - - if (items.Size() == 1 && m_Signature != NSignature::kCentralFileHeader) - if (IsStrangeItem(items[0])) - return S_FALSE; - - return S_OK; -} - - - -HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback) -{ - UString name; - { - NWindows::NCOM::CPropVariant prop; - RINOK(volCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - return S_OK; - name = prop.bstrVal; - } - - UString base = name; - int dotPos = name.ReverseFind_Dot(); - - if (dotPos < 0) - return S_OK; - - base.DeleteFrom(dotPos + 1); - - const UString ext = name.Ptr(dotPos + 1); - StartVolIndex = (Int32)(-1); - - if (ext.IsEmpty()) - return S_OK; - else - { - wchar_t c = ext[0]; - IsUpperCase = (c >= 'A' && c <= 'Z'); - if (ext.IsEqualTo_Ascii_NoCase("zip")) - { - BaseName = base; - StartIsZ = true; - StartIsZip = true; - return S_OK; - } - else if (ext.IsEqualTo_Ascii_NoCase("exe")) - { - StartIsExe = true; - BaseName = base; - StartVolIndex = 0; - } - else if (ext[0] == 'z' || ext[0] == 'Z') - { - if (ext.Len() < 3) - return S_OK; - const wchar_t *end = NULL; - UInt32 volNum = ConvertStringToUInt32(ext.Ptr(1), &end); - if (*end != 0 || volNum < 1 || volNum > ((UInt32)1 << 30)) - return S_OK; - StartVolIndex = volNum - 1; - BaseName = base; - StartIsZ = true; - } - else - return S_OK; - } - - UString volName = BaseName; - volName.AddAscii(IsUpperCase ? "ZIP" : "zip"); - HRESULT result = volCallback->GetStream(volName, &ZipStream); - if (result == S_FALSE || !ZipStream) - { - if (MissingName.IsEmpty()) - MissingName = volName; - return S_OK; - } - - return result; -} - - -HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback, - unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols) -{ - numMissingVols = 0; - - for (unsigned i = start;; i++) - { - if (lastDisk >= 0 && i >= (unsigned)lastDisk) - break; - - if (i < Vols.Streams.Size()) - if (Vols.Streams[i].Stream) - continue; - - CMyComPtr stream; - - if ((int)i == zipDisk) - { - stream = Vols.ZipStream; - } - else if ((int)i == Vols.StartVolIndex) - { - stream = StartStream; - } - else - { - UString volName = Vols.BaseName; - { - volName += (wchar_t)(Vols.IsUpperCase ? 'Z' : 'z'); - { - char s[32]; - ConvertUInt32ToString(i + 1, s); - unsigned len = (unsigned)strlen(s); - while (len < 2) - { - volName += (wchar_t)'0'; - len++; - } - volName.AddAscii(s); - } - } - - HRESULT result = volCallback->GetStream(volName, &stream); - if (result != S_OK && result != S_FALSE) - return result; - if (result == S_FALSE || !stream) - { - if (Vols.MissingName.IsEmpty()) - Vols.MissingName = volName; - numMissingVols++; - if (numMissingVols > numMissingVolsMax) - return S_OK; - if (lastDisk == -1 && numMissingVols != 0) - return S_OK; - continue; - } - } - - UInt64 size; - - UInt64 pos; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &pos)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &size)); - RINOK(stream->Seek(pos, STREAM_SEEK_SET, NULL)); - - while (i >= Vols.Streams.Size()) - Vols.Streams.AddNew(); - - CVols::CSubStreamInfo &ss = Vols.Streams[i]; - Vols.NumVols++; - ss.Stream = stream; - ss.Size = size; - - if ((int)i == zipDisk) - { - Vols.EndVolIndex = Vols.Streams.Size() - 1; - break; - } - } - - return S_OK; -} - - -HRESULT CInArchive::ReadVols() -{ - CMyComPtr volCallback; - - Callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volCallback); - if (!volCallback) - return S_OK; - - RINOK(Vols.ParseArcName(volCallback)); - - int startZIndex = Vols.StartVolIndex; - - if (!Vols.StartIsZ) - { - // if (!Vols.StartIsExe) - return S_OK; - } - - int zipDisk = -1; - int cdDisk = -1; - - if (Vols.StartIsZip) - Vols.ZipStream = StartStream; - - // bool cdOK = false; - - if (Vols.ZipStream) - { - Stream = Vols.ZipStream; - HRESULT res = FindCd(true); - CCdInfo &ecd = Vols.ecd; - if (res == S_OK) - { - zipDisk = ecd.ThisDisk; - Vols.ecd_wasRead = true; - if (ecd.ThisDisk == 0 - || ecd.ThisDisk >= ((UInt32)1 << 30) - || ecd.ThisDisk < ecd.CdDisk) - return S_OK; - cdDisk = ecd.CdDisk; - if (Vols.StartVolIndex < 0) - Vols.StartVolIndex = ecd.ThisDisk; - // Vols.StartVolIndex = ecd.ThisDisk; - // Vols.EndVolIndex = ecd.ThisDisk; - unsigned numMissingVols; - if (cdDisk == zipDisk) - { - // cdOK = true; - } - else - { - RINOK(ReadVols2(volCallback, cdDisk, zipDisk, zipDisk, 0, numMissingVols)); - if (numMissingVols == 0) - { - // cdOK = false; - } - } - } - else if (res != S_FALSE) - return res; - } - - if (Vols.Streams.Size() > 0) - IsMultiVol = true; - - if (Vols.StartVolIndex < 0) - return S_OK; - - unsigned numMissingVols; - - if (cdDisk != 0) - { - RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, 1 << 10, numMissingVols)); - } - - if (Vols.ZipStream) - { - if (Vols.Streams.IsEmpty()) - if (zipDisk > (1 << 10)) - return S_OK; - RINOK(ReadVols2(volCallback, zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols)); - } - - if (!Vols.Streams.IsEmpty()) - { - IsMultiVol = true; - /* - if (cdDisk) - IsMultiVol = true; - */ - if (startZIndex >= 0) - { - if (Vols.Streams.Size() >= (unsigned)startZIndex) - { - for (unsigned i = 0; i < (unsigned)startZIndex; i++) - if (!Vols.Streams[i].Stream) - { - Vols.StartParsingVol = startZIndex; - break; - } - } - } - } - - return S_OK; -} - - - - - - - -HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - - for (;;) - { - if (StreamIndex < 0) - return S_OK; - if ((unsigned)StreamIndex >= Streams.Size()) - return S_OK; - const CVols::CSubStreamInfo &s = Streams[StreamIndex]; - if (!s.Stream) - return S_FALSE; - if (NeedSeek) - { - RINOK(s.Stream->Seek(0, STREAM_SEEK_SET, NULL)); - NeedSeek = false; - } - UInt32 realProcessedSize = 0; - HRESULT res = s.Stream->Read(data, size, &realProcessedSize); - if (processedSize) - *processedSize = realProcessedSize; - if (res != S_OK) - return res; - if (realProcessedSize != 0) - return res; - StreamIndex++; - NeedSeek = true; - } -} - -STDMETHODIMP CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - return Vols->Read(data, size, processedSize); -} - - - - -#define COPY_ECD_ITEM_16(n) if (!isZip64 || ecd. n != 0xFFFF) ecd64. n = ecd. n; -#define COPY_ECD_ITEM_32(n) if (!isZip64 || ecd. n != 0xFFFFFFFF) ecd64. n = ecd. n; - - -HRESULT CInArchive::ReadHeaders2(CObjectVector &items) -{ - HRESULT res = S_OK; - - bool localsWereRead = false; - UInt64 cdSize = 0, cdRelatOffset = 0, cdAbsOffset = 0; - UInt32 cdDisk = 0; - - if (!_inBuffer.Create(1 << 15)) - return E_OUTOFMEMORY; - - if (!MarkerIsFound) - { - IsArc = true; - res = ReadCd(items, cdDisk, cdRelatOffset, cdSize); - if (res == S_OK) - m_Signature = ReadUInt32(); - } - else - { - - // m_Signature must be kLocalFileHeader or kEcd - // m_Position points to next byte after signature - RINOK(Stream->Seek(m_Position, STREAM_SEEK_SET, NULL)); - - _inBuffer.SetStream(Stream); - - bool needReadCd = true; - - if (m_Signature == NSignature::kEcd) - { - // It must be empty archive or backware archive - // we don't support backware archive still - - const unsigned kBufSize = kEcdSize - 4; - Byte buf[kBufSize]; - SafeReadBytes(buf, kBufSize); - CEcd ecd; - ecd.Parse(buf); - // if (ecd.cdSize != 0) - // Do we need also to support the case where empty zip archive with PK00 uses cdOffset = 4 ?? - if (!ecd.IsEmptyArc()) - return S_FALSE; - - ArcInfo.Base = ArcInfo.MarkerPos; - needReadCd = false; - IsArc = true; // check it: we need more tests? - RINOK(Stream->Seek(ArcInfo.MarkerPos2 + 4, STREAM_SEEK_SET, &m_Position)); - } - - if (needReadCd) - { - CItemEx firstItem; - // try - { - try - { - if (!ReadLocalItem(firstItem)) - return S_FALSE; - } - catch(CUnexpectEnd &) - { - return S_FALSE; - } - - IsArc = true; - res = ReadCd(items, cdDisk, cdRelatOffset, cdSize); - if (res == S_OK) - m_Signature = ReadUInt32(); - } - // catch() { res = S_FALSE; } - if (res != S_FALSE && res != S_OK) - return res; - - if (res == S_OK && items.Size() == 0) - res = S_FALSE; - - if (res == S_OK) - { - // we can't read local items here to keep _inBufMode state - if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base) - res = S_FALSE; - else - { - firstItem.LocalHeaderPos = ArcInfo.MarkerPos2 - ArcInfo.Base; - int index = FindItem(items, firstItem); - if (index == -1) - res = S_FALSE; - else if (!AreItemsEqual(firstItem, items[index])) - res = S_FALSE; - else - { - ArcInfo.CdWasRead = true; - ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos; - } - } - } - } - } - - - - CObjectVector cdItems; - - bool needSetBase = false; - unsigned numCdItems = items.Size(); - - if (res == S_FALSE) - { - // CD doesn't match firstItem, - // so we clear items and read Locals. - items.Clear(); - localsWereRead = true; - _inBufMode = false; - ArcInfo.Base = ArcInfo.MarkerPos; - - if (IsMultiVol) - { - Vols.StreamIndex = Vols.StartParsingVol; - if (Vols.StartParsingVol >= (int)Vols.Streams.Size()) - return S_FALSE; - Stream = Vols.Streams[Vols.StartParsingVol].Stream; - if (!Stream) - return S_FALSE; - } - - RINOK(Stream->Seek(ArcInfo.MarkerPos2, STREAM_SEEK_SET, &m_Position)); - m_Signature = ReadUInt32(); - - RINOK(ReadLocals(items)); - - if (m_Signature != NSignature::kCentralFileHeader) - { - // if (!UnexpectedEnd) - m_Position -= 4; - NoCentralDir = true; - HeadersError = true; - return S_OK; - } - - _inBufMode = true; - _inBuffer.Init(); - - cdAbsOffset = m_Position - 4; - cdDisk = Vols.StreamIndex; - - for (;;) - { - CItemEx cdItem; - CanStartNewVol = true; - - RINOK(ReadCdItem(cdItem)); - - cdItems.Add(cdItem); - if (Callback && (cdItems.Size() & 0xFFF) == 0) - { - const UInt64 numFiles = items.Size(); - RINOK(Callback->SetCompleted(&numFiles, NULL)); - } - CanStartNewVol = true; - m_Signature = ReadUInt32(); - if (m_Signature != NSignature::kCentralFileHeader) - break; - } - - cdSize = (m_Position - 4) - cdAbsOffset; - needSetBase = true; - numCdItems = cdItems.Size(); - - if (!cdItems.IsEmpty()) - { - ArcInfo.CdWasRead = true; - ArcInfo.FirstItemRelatOffset = cdItems[0].LocalHeaderPos; - } - } - - - - CCdInfo ecd64; - CLocator locator; - bool isZip64 = false; - const UInt64 ecd64AbsOffset = m_Position - 4; - int ecd64Disk = -1; - - if (m_Signature == NSignature::kEcd64) - { - ecd64Disk = Vols.StreamIndex; - - IsZip64 = isZip64 = true; - - { - const UInt64 recordSize = ReadUInt64(); - if (recordSize < kEcd64_MainSize) - { - HeadersError = true; - return S_OK; - } - - { - const unsigned kBufSize = kEcd64_MainSize; - Byte buf[kBufSize]; - SafeReadBytes(buf, kBufSize); - ecd64.ParseEcd64e(buf); - } - - Skip64(recordSize - kEcd64_MainSize); - } - - - m_Signature = ReadUInt32(); - - if (m_Signature != NSignature::kEcd64Locator) - { - HeadersError = true; - return S_OK; - } - - { - const unsigned kBufSize = 16; - Byte buf[kBufSize]; - SafeReadBytes(buf, kBufSize); - locator.Parse(buf); - } - - m_Signature = ReadUInt32(); - } - - - if (m_Signature != NSignature::kEcd) - { - HeadersError = true; - return S_OK; - } - - - // ---------- ECD ---------- - - CEcd ecd; - { - const unsigned kBufSize = kEcdSize - 4; - Byte buf[kBufSize]; - SafeReadBytes(buf, kBufSize); - ecd.Parse(buf); - } - - COPY_ECD_ITEM_16(ThisDisk); - COPY_ECD_ITEM_16(CdDisk); - COPY_ECD_ITEM_16(NumEntries_in_ThisDisk); - COPY_ECD_ITEM_16(NumEntries); - COPY_ECD_ITEM_32(Size); - COPY_ECD_ITEM_32(Offset); - - if (IsMultiVol) - { - if (cdDisk != (int)ecd64.CdDisk) - HeadersError = true; - } - else if (needSetBase) - { - if (isZip64) - { - if (ecd64Disk == Vols.StartVolIndex) - { - ArcInfo.Base = ecd64AbsOffset - locator.Ecd64Offset; - // cdRelatOffset = ecd64.Offset; - needSetBase = false; - } - } - else - { - if ((int)cdDisk == Vols.StartVolIndex) - { - ArcInfo.Base = cdAbsOffset - ecd64.Offset; - cdRelatOffset = ecd64.Offset; - needSetBase = false; - } - } - } - - EcdVolIndex = ecd64.ThisDisk; - - if (!IsMultiVol) - { - UseDisk_in_SingleVol = true; - - if (localsWereRead) - { - if ((UInt64)ArcInfo.Base != ArcInfo.MarkerPos) - { - const UInt64 delta = ArcInfo.MarkerPos - ArcInfo.Base; - FOR_VECTOR (i, items) - items[i].LocalHeaderPos += delta; - } - - if (EcdVolIndex != 0) - { - FOR_VECTOR (i, items) - items[i].Disk = EcdVolIndex; - } - } - } - - if (isZip64) - { - if (ecd64.ThisDisk == 0 && ecd64AbsOffset != ArcInfo.Base + locator.Ecd64Offset - // || ecd64.NumEntries_in_ThisDisk != numCdItems - || ecd64.NumEntries != numCdItems - || ecd64.Size != cdSize - || (ecd64.Offset != cdRelatOffset && !items.IsEmpty())) - { - HeadersError = true; - return S_OK; - } - } - - // ---------- merge Central Directory Items ---------- - - if (!cdItems.IsEmpty()) - { - CObjectVector items2; - - FOR_VECTOR (i, cdItems) - { - const CItemEx &cdItem = cdItems[i]; - int index = FindItem(items, cdItem); - if (index == -1) - { - items2.Add(cdItem); - HeadersError = true; - continue; - } - CItemEx &item = items[index]; - if (item.Name != cdItem.Name - // || item.Name.Len() != cdItem.Name.Len() - || item.PackSize != cdItem.PackSize - || item.Size != cdItem.Size - // item.ExtractVersion != cdItem.ExtractVersion - || !FlagsAreSame(item, cdItem) - || item.Crc != cdItem.Crc) - { - HeadersError = true; - continue; - } - - // item.Name = cdItem.Name; - item.MadeByVersion = cdItem.MadeByVersion; - item.CentralExtra = cdItem.CentralExtra; - item.InternalAttrib = cdItem.InternalAttrib; - item.ExternalAttrib = cdItem.ExternalAttrib; - item.Comment = cdItem.Comment; - item.FromCentral = cdItem.FromCentral; - } - - items += items2; - } - - - if (ecd.NumEntries < ecd.NumEntries_in_ThisDisk) - HeadersError = true; - - if (ecd.ThisDisk == 0) - { - // if (isZip64) - { - if (ecd.NumEntries != ecd.NumEntries_in_ThisDisk) - HeadersError = true; - } - } - - if (ecd.NumEntries > items.Size()) - HeadersError = true; - - if (isZip64) - { - if (ecd64.NumEntries != items.Size()) - HeadersError = true; - } - else - { - // old 7-zip could store 32-bit number of CD items to 16-bit field. - /* - if ((UInt16)ecd64.NumEntries == (UInt16)items.Size()) - HeadersError = true; - */ - } - - ReadBuffer(ArcInfo.Comment, ecd.CommentSize); - _inBufMode = false; - _inBuffer.Free(); - - if ((UInt16)ecd64.NumEntries != (UInt16)numCdItems - || (UInt32)ecd64.Size != (UInt32)cdSize - || ((UInt32)ecd64.Offset != (UInt32)cdRelatOffset && !items.IsEmpty())) - { - // return S_FALSE; - HeadersError = true; - } - - // printf("\nOpen OK"); - return S_OK; -} - - - -HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit, - IArchiveOpenCallback *callback, CObjectVector &items) -{ - _inBufMode = false; - items.Clear(); - - Close(); - ArcInfo.Clear(); - - UInt64 startPos; - RINOK(stream->Seek(0, STREAM_SEEK_CUR, &startPos)); - RINOK(stream->Seek(0, STREAM_SEEK_END, &ArcInfo.FileEndPos)); - m_Position = ArcInfo.FileEndPos; - - StartStream = stream; - Callback = callback; - - bool volWasRequested = false; - - if (callback - && (startPos == 0 || !searchLimit || *searchLimit != 0)) - { - volWasRequested = true; - RINOK(ReadVols()); - } - - if (IsMultiVol && Vols.StartVolIndex != 0) - { - Stream = Vols.Streams[0].Stream; - if (Stream) - { - m_Position = 0; - RINOK(Stream->Seek(0, STREAM_SEEK_SET, NULL)); - UInt64 limit = 0; - HRESULT res = FindMarker(Stream, &limit); - if (res == S_OK) - MarkerIsFound = true; - else if (res != S_FALSE) - return res; - } - } - else - { - // printf("\nOpen offset = %u\n", (unsigned)startPos); - RINOK(stream->Seek(startPos, STREAM_SEEK_SET, NULL)); - m_Position = startPos; - HRESULT res = FindMarker(stream, searchLimit); - UInt64 curPos = m_Position; - if (res == S_OK) - MarkerIsFound = true; - else - { - // if (res != S_FALSE) - return res; - } - - MarkerIsFound = true; - - if (ArcInfo.IsSpanMode && !volWasRequested) - { - RINOK(ReadVols()); - } - - if (IsMultiVol && (unsigned)Vols.StartVolIndex < Vols.Streams.Size()) - { - Stream = Vols.Streams[Vols.StartVolIndex].Stream; - if (!Stream) - IsMultiVol = false; - else - { - RINOK(Stream->Seek(curPos, STREAM_SEEK_SET, NULL)); - m_Position = curPos; - } - } - else - IsMultiVol = false; - - if (!IsMultiVol) - { - RINOK(stream->Seek(curPos, STREAM_SEEK_SET, NULL)); - m_Position = curPos; - StreamRef = stream; - Stream = stream; - } - } - - - { - HRESULT res; - try - { - res = ReadHeaders2(items); - } - catch (const CInBufferException &e) { res = e.ErrorCode; } - catch (const CUnexpectEnd &) - { - if (items.IsEmpty()) - return S_FALSE; - UnexpectedEnd = true; - res = S_OK; - } - catch (...) - { - _inBufMode = false; - throw; - } - - if (IsMultiVol) - { - ArcInfo.FinishPos = ArcInfo.FileEndPos; - if ((unsigned)Vols.StreamIndex < Vols.Streams.Size()) - if (m_Position < Vols.Streams[Vols.StreamIndex].Size) - ArcInfo.ThereIsTail = true; - } - else - { - ArcInfo.FinishPos = m_Position; - ArcInfo.ThereIsTail = (ArcInfo.FileEndPos > m_Position); - } - - _inBufMode = false; - IsArcOpen = true; - if (!IsMultiVol) - Vols.Streams.Clear(); - return res; - } -} - - -HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr &stream) -{ - stream.Release(); - - UInt64 pos = item.LocalHeaderPos; - if (seekPackData) - pos += item.LocalFullHeaderSize; - - if (!IsMultiVol) - { - if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex) - return S_OK; - pos += ArcInfo.Base; - RINOK(StreamRef->Seek(pos, STREAM_SEEK_SET, NULL)); - stream = StreamRef; - return S_OK; - } - - if (item.Disk >= Vols.Streams.Size()) - return S_OK; - - IInStream *str2 = Vols.Streams[item.Disk].Stream; - if (!str2) - return S_OK; - RINOK(str2->Seek(pos, STREAM_SEEK_SET, NULL)); - - Vols.NeedSeek = false; - Vols.StreamIndex = item.Disk; - - CVolStream *volsStreamSpec = new CVolStream; - volsStreamSpec->Vols = &Vols; - stream = volsStreamSpec; - - return S_OK; -} - -}} +// Archive/ZipIn.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../Common/DynamicBuffer.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/PropVariant.h" + +#include "../IArchive.h" + +#include "ZipIn.h" + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define G16(offs, v) v = Get16(p + (offs)) +#define G32(offs, v) v = Get32(p + (offs)) +#define G64(offs, v) v = Get64(p + (offs)) + +namespace NArchive { +namespace NZip { + +/* we try to use same size of Buffer (1 << 17) for all tasks. + it allow to avoid reallocations and cache clearing. */ + +static const size_t kSeqBufferSize = (size_t)1 << 17; + +/* +Open() +{ + _inBufMode = false; + ReadVols() + FindCd(); + TryEcd64() + SeekToVol() + FindMarker() + _inBufMode = true; + ReadHeaders() + _inBufMode = false; + ReadCd() + FindCd() + TryEcd64() + TryReadCd() + { + SeekToVol(); + _inBufMode = true; + } + _inBufMode = true; + ReadLocals() + ReadCdItem() + .... +} +FindCd() writes to Buffer without touching (_inBufMode) +*/ + +/* + if (not defined ZIP_SELF_CHECK) : it reads CD and if error in first pass CD reading, it reads LOCALS-CD-MODE + if ( defined ZIP_SELF_CHECK) : it always reads CD and LOCALS-CD-MODE + use ZIP_SELF_CHECK to check LOCALS-CD-MODE for any zip archive +*/ + +// #define ZIP_SELF_CHECK + + +struct CEcd +{ + UInt16 ThisDisk; + UInt16 CdDisk; + UInt16 NumEntries_in_ThisDisk; + UInt16 NumEntries; + UInt32 Size; + UInt32 Offset; + UInt16 CommentSize; + + bool IsEmptyArc() const + { + return ThisDisk == 0 + && CdDisk == 0 + && NumEntries_in_ThisDisk == 0 + && NumEntries == 0 + && Size == 0 + && Offset == 0 // test it + ; + } + + void Parse(const Byte *p); // (p) doesn't include signature +}; + +void CEcd::Parse(const Byte *p) +{ + // (p) doesn't include signature + G16(0, ThisDisk); + G16(2, CdDisk); + G16(4, NumEntries_in_ThisDisk); + G16(6, NumEntries); + G32(8, Size); + G32(12, Offset); + G16(16, CommentSize); +} + + +void CCdInfo::ParseEcd32(const Byte *p) +{ + IsFromEcd64 = false; + // (p) includes signature + p += 4; + G16(0, ThisDisk); + G16(2, CdDisk); + G16(4, NumEntries_in_ThisDisk); + G16(6, NumEntries); + G32(8, Size); + G32(12, Offset); + G16(16, CommentSize); +} + +void CCdInfo::ParseEcd64e(const Byte *p) +{ + IsFromEcd64 = true; + // (p) exclude signature + G16(0, VersionMade); + G16(2, VersionNeedExtract); + G32(4, ThisDisk); + G32(8, CdDisk); + + G64(12, NumEntries_in_ThisDisk); + G64(20, NumEntries); + G64(28, Size); + G64(36, Offset); +} + + +struct CLocator +{ + UInt32 Ecd64Disk; + UInt32 NumDisks; + UInt64 Ecd64Offset; + + CLocator(): Ecd64Disk(0), NumDisks(0), Ecd64Offset(0) {} + + void Parse(const Byte *p) + { + G32(0, Ecd64Disk); + G64(4, Ecd64Offset); + G32(12, NumDisks); + } + + bool IsEmptyArc() const + { + return Ecd64Disk == 0 && NumDisks == 0 && Ecd64Offset == 0; + } +}; + + + + +void CInArchive::ClearRefs() +{ + StreamRef.Release(); + Stream = NULL; + StartStream = NULL; + Callback = NULL; + + Vols.Clear(); +} + +void CInArchive::Close() +{ + _cnt = 0; + DisableBufMode(); + + IsArcOpen = false; + + IsArc = false; + IsZip64 = false; + + IsApk = false; + IsCdUnsorted = false; + + HeadersError = false; + HeadersWarning = false; + ExtraMinorError = false; + + UnexpectedEnd = false; + LocalsWereRead = false; + LocalsCenterMerged = false; + NoCentralDir = false; + Overflow32bit = false; + Cd_NumEntries_Overflow_16bit = false; + + MarkerIsFound = false; + MarkerIsSafe = false; + + IsMultiVol = false; + UseDisk_in_SingleVol = false; + EcdVolIndex = 0; + + ArcInfo.Clear(); + + ClearRefs(); +} + + + +HRESULT CInArchive::Seek_SavePos(UInt64 offset) +{ + // InitBuf(); + // if (!Stream) return S_FALSE; + return Stream->Seek((Int64)offset, STREAM_SEEK_SET, &_streamPos); +} + + +/* SeekToVol() will keep the cached mode, if new volIndex is + same Vols.StreamIndex volume, and offset doesn't go out of cached region */ + +HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset) +{ + if (volIndex != Vols.StreamIndex) + { + if (IsMultiVol && volIndex >= 0) + { + if ((unsigned)volIndex >= Vols.Streams.Size()) + return S_FALSE; + if (!Vols.Streams[(unsigned)volIndex].Stream) + return S_FALSE; + Stream = Vols.Streams[(unsigned)volIndex].Stream; + } + else if (volIndex == -2) + { + if (!Vols.ZipStream) + return S_FALSE; + Stream = Vols.ZipStream; + } + else + Stream = StartStream; + Vols.StreamIndex = volIndex; + } + else + { + if (offset <= _streamPos) + { + const UInt64 back = _streamPos - offset; + if (back <= _bufCached) + { + _bufPos = _bufCached - (size_t)back; + return S_OK; + } + } + } + InitBuf(); + return Seek_SavePos(offset); +} + + +HRESULT CInArchive::AllocateBuffer(size_t size) +{ + if (size <= Buffer.Size()) + return S_OK; + /* in cached mode virtual_pos is not equal to phy_pos (_streamPos) + so we change _streamPos and do Seek() to virtual_pos before cache clearing */ + if (_bufPos != _bufCached) + { + RINOK(Seek_SavePos(GetVirtStreamPos())) + } + InitBuf(); + Buffer.AllocAtLeast(size); + if (!Buffer.IsAllocated()) + return E_OUTOFMEMORY; + return S_OK; +} + +// ---------- ReadFromCache ---------- +// reads from cache and from Stream +// move to next volume can be allowed if (CanStartNewVol) and only before first byte reading + +HRESULT CInArchive::ReadFromCache(Byte *data, unsigned size, unsigned &processed) +{ + HRESULT result = S_OK; + processed = 0; + + for (;;) + { + if (size == 0) + return S_OK; + + const size_t avail = GetAvail(); + + if (avail != 0) + { + unsigned cur = size; + if (cur > avail) + cur = (unsigned)avail; + memcpy(data, (const Byte *)Buffer + _bufPos, cur); + + data += cur; + size -= cur; + processed += cur; + + _bufPos += cur; + _cnt += cur; + + CanStartNewVol = false; + + continue; + } + + InitBuf(); + + if (_inBufMode) + { + UInt32 cur = 0; + result = Stream->Read(Buffer, (UInt32)Buffer.Size(), &cur); + _bufPos = 0; + _bufCached = cur; + _streamPos += cur; + if (cur != 0) + CanStartNewVol = false; + if (result != S_OK) + break; + if (cur != 0) + continue; + } + else + { + size_t cur = size; + result = ReadStream(Stream, data, &cur); + data += cur; + size -= (unsigned)cur; + processed += (unsigned)cur; + _streamPos += cur; + _cnt += cur; + if (cur != 0) + { + CanStartNewVol = false; + break; + } + if (result != S_OK) + break; + } + + if ( !IsMultiVol + || !CanStartNewVol + || Vols.StreamIndex < 0 + || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size()) + break; + + const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1]; + if (!s.Stream) + break; + result = s.SeekToStart(); + if (result != S_OK) + break; + Vols.StreamIndex++; + _streamPos = 0; + // Vols.NeedSeek = false; + + Stream = s.Stream; + } + + return result; +} + + +HRESULT CInArchive::ReadFromCache_FALSE(Byte *data, unsigned size) +{ + unsigned processed; + HRESULT res = ReadFromCache(data, size, processed); + if (res == S_OK && size != processed) + return S_FALSE; + return res; +} + + +static bool CheckDosTime(UInt32 dosTime) +{ + if (dosTime == 0) + return true; + unsigned month = (dosTime >> 21) & 0xF; + unsigned day = (dosTime >> 16) & 0x1F; + unsigned hour = (dosTime >> 11) & 0x1F; + unsigned min = (dosTime >> 5) & 0x3F; + unsigned sec = (dosTime & 0x1F) * 2; + if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) + return false; + return true; +} + +API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size) +{ + if (size < 8) + return k_IsArc_Res_NEED_MORE; + if (p[0] != 'P') + return k_IsArc_Res_NO; + + UInt32 sig = Get32(p); + + if (sig == NSignature::kNoSpan || sig == NSignature::kSpan) + { + p += 4; + size -= 4; + } + + sig = Get32(p); + + if (sig == NSignature::kEcd64) + { + if (size < kEcd64_FullSize) + return k_IsArc_Res_NEED_MORE; + + const UInt64 recordSize = Get64(p + 4); + if ( recordSize < kEcd64_MainSize + || recordSize > kEcd64_MainSize + (1 << 20)) + return k_IsArc_Res_NO; + CCdInfo cdInfo; + cdInfo.ParseEcd64e(p + 12); + if (!cdInfo.IsEmptyArc()) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; // k_IsArc_Res_YES_2; + } + + if (sig == NSignature::kEcd) + { + if (size < kEcdSize) + return k_IsArc_Res_NEED_MORE; + CEcd ecd; + ecd.Parse(p + 4); + // if (ecd.cdSize != 0) + if (!ecd.IsEmptyArc()) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; // k_IsArc_Res_YES_2; + } + + if (sig != NSignature::kLocalFileHeader) + return k_IsArc_Res_NO; + + if (size < kLocalHeaderSize) + return k_IsArc_Res_NEED_MORE; + + p += 4; + + { + const unsigned kPureHeaderSize = kLocalHeaderSize - 4; + unsigned i; + for (i = 0; i < kPureHeaderSize && p[i] == 0; i++); + if (i == kPureHeaderSize) + return k_IsArc_Res_NEED_MORE; + } + + /* + if (p[0] >= 128) // ExtractVersion.Version; + return k_IsArc_Res_NO; + */ + + // ExtractVersion.Version = p[0]; + // ExtractVersion.HostOS = p[1]; + // Flags = Get16(p + 2); + // Method = Get16(p + 4); + /* + // 9.33: some zip archives contain incorrect value in timestamp. So we don't check it now + UInt32 dosTime = Get32(p + 6); + if (!CheckDosTime(dosTime)) + return k_IsArc_Res_NO; + */ + // Crc = Get32(p + 10); + // PackSize = Get32(p + 14); + // Size = Get32(p + 18); + const unsigned nameSize = Get16(p + 22); + unsigned extraSize = Get16(p + 24); + const UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize; + + /* + // 21.02: fixed. we don't use the following check + if (extraOffset + extraSize > (1 << 16)) + return k_IsArc_Res_NO; + */ + + p -= 4; + + { + size_t rem = size - kLocalHeaderSize; + if (rem > nameSize) + rem = nameSize; + const Byte *p2 = p + kLocalHeaderSize; + for (size_t i = 0; i < rem; i++) + if (p2[i] == 0) + { + // we support some "bad" zip archives that contain zeros after name + for (size_t k = i + 1; k < rem; k++) + if (p2[k] != 0) + return k_IsArc_Res_NO; + break; + /* + if (i != nameSize - 1) + return k_IsArc_Res_NO; + */ + } + } + + if (size < extraOffset) + return k_IsArc_Res_NEED_MORE; + + if (extraSize > 0) + { + p += extraOffset; + size -= extraOffset; + while (extraSize != 0) + { + if (extraSize < 4) + { + // 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers. + // so we return k_IsArc_Res_YES to support such archives. + // return k_IsArc_Res_NO; // do we need to support such extra ? + return k_IsArc_Res_YES; + } + if (size < 4) + return k_IsArc_Res_NEED_MORE; + unsigned dataSize = Get16(p + 2); + size -= 4; + extraSize -= 4; + p += 4; + if (dataSize > extraSize) + { + // It can be error on header. + // We want to support such rare case bad archives. + // We use additional checks to reduce false-positive probability. + if (nameSize == 0 + || nameSize > (1 << 9) + || extraSize > (1 << 9)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; + } + if (dataSize > size) + return k_IsArc_Res_NEED_MORE; + size -= dataSize; + extraSize -= dataSize; + p += dataSize; + } + } + + return k_IsArc_Res_YES; +} + +static UInt32 IsArc_Zip_2(const Byte *p, size_t size, bool isFinal) +{ + UInt32 res = IsArc_Zip(p, size); + if (res == k_IsArc_Res_NEED_MORE && isFinal) + return k_IsArc_Res_NO; + return res; +} + + + +/* FindPK_4() is allowed to access data up to and including &limit[3]. + limit[4] access is not allowed. + return: + (return_ptr < limit) : "PK" was found at (return_ptr) + (return_ptr >= limit) : limit was reached or crossed. So no "PK" found before limit +*/ +Z7_NO_INLINE +static const Byte *FindPK_4(const Byte *p, const Byte *limit) +{ + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + Byte b = p[1]; + if (b == 0x4B) { if (p[0] == 0x50) { return p; } p += 1; break; } + if (b == 0x50) { if (p[2] == 0x4B) { return p + 1; } p += 2; break; } + b = p[3]; + p += 4; + if (b == 0x4B) { if (p[-2]== 0x50) { return p - 2; } p -= 1; break; } + if (b == 0x50) { if (p[0] == 0x4B) { return p - 1; } break; } + } + } + /* + for (;;) + { + for (;;) + { + if (p >= limit) + return limit; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; + if (*p++ == 0x50) break; + } + if (*p == 0x4B) + return p - 1; + } + */ +} + + +/* +---------- FindMarker ---------- +returns: + S_OK: + ArcInfo.MarkerVolIndex : volume of marker + ArcInfo.MarkerPos : Pos of first signature + ArcInfo.MarkerPos2 : Pos of main signature (local item signature in most cases) + _streamPos : stream pos + _cnt : The number of virtal Bytes after start of search to offset after signature + _signature : main signature + + S_FALSE: can't find marker, or there is some non-zip data after marker + + Error code: stream reading error. +*/ + +HRESULT CInArchive::FindMarker(const UInt64 *searchLimit) +{ + ArcInfo.MarkerPos = GetVirtStreamPos(); + ArcInfo.MarkerPos2 = ArcInfo.MarkerPos; + ArcInfo.MarkerVolIndex = Vols.StreamIndex; + + _cnt = 0; + + CanStartNewVol = false; + + if (searchLimit && *searchLimit == 0) + { + Byte startBuf[kMarkerSize]; + RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)) + + UInt32 marker = Get32(startBuf); + _signature = marker; + + if ( marker == NSignature::kNoSpan + || marker == NSignature::kSpan) + { + RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize)) + _signature = Get32(startBuf); + } + + if ( _signature != NSignature::kEcd + && _signature != NSignature::kEcd64 + && _signature != NSignature::kLocalFileHeader) + return S_FALSE; + + ArcInfo.MarkerPos2 = GetVirtStreamPos() - 4; + ArcInfo.IsSpanMode = (marker == NSignature::kSpan); + + // we use weak test in case of (*searchLimit == 0) + // since error will be detected later in Open function + return S_OK; + } + + // zip specification: (_zip_header_size < (1 << 16)) + // so we need such size to check header + const size_t kCheckSize = (size_t)1 << 16; + const size_t kBufSize = (size_t)1 << 17; // (kBufSize must be > kCheckSize) + + RINOK(AllocateBuffer(kBufSize)) + + _inBufMode = true; + + UInt64 progressPrev = 0; + + for (;;) + { + RINOK(LookAhead(kBufSize)) + + const size_t avail = GetAvail(); + + size_t limitPos; + // (avail > kBufSize) is possible, if (Buffer.Size() > kBufSize) + const bool isFinished = (avail < kBufSize); + if (isFinished) + { + const unsigned kMinAllowed = 4; + if (avail <= kMinAllowed) + { + if ( !IsMultiVol + || Vols.StreamIndex < 0 + || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size()) + break; + + SkipLookahed(avail); + + const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1]; + if (!s.Stream) + break; + + RINOK(s.SeekToStart()) + + InitBuf(); + Vols.StreamIndex++; + _streamPos = 0; + Stream = s.Stream; + continue; + } + limitPos = avail - kMinAllowed; + } + else + limitPos = (avail - kCheckSize); + + // we don't check at (limitPos) for good fast aligned operations + + if (searchLimit) + { + if (_cnt > *searchLimit) + break; + UInt64 rem = *searchLimit - _cnt; + if (limitPos > rem) + limitPos = (size_t)rem + 1; + } + + if (limitPos == 0) + break; + + const Byte * const pStart = Buffer + _bufPos; + const Byte * p = pStart; + const Byte * const limit = pStart + limitPos; + + for (;; p++) + { + p = FindPK_4(p, limit); + if (p >= limit) + break; + size_t rem = (size_t)(pStart + avail - p); + /* 22.02 : we limit check size with kCheckSize to be consistent for + any different combination of _bufPos in Buffer and size of Buffer. */ + if (rem > kCheckSize) + rem = kCheckSize; + const UInt32 res = IsArc_Zip_2(p, rem, isFinished); + if (res != k_IsArc_Res_NO) + { + if (rem < kMarkerSize) + return S_FALSE; + _signature = Get32(p); + SkipLookahed((size_t)(p - pStart)); + ArcInfo.MarkerVolIndex = Vols.StreamIndex; + ArcInfo.MarkerPos = GetVirtStreamPos(); + ArcInfo.MarkerPos2 = ArcInfo.MarkerPos; + SkipLookahed(4); + if ( _signature == NSignature::kNoSpan + || _signature == NSignature::kSpan) + { + if (rem < kMarkerSize * 2) + return S_FALSE; + ArcInfo.IsSpanMode = (_signature == NSignature::kSpan); + _signature = Get32(p + 4); + ArcInfo.MarkerPos2 += 4; + SkipLookahed(4); + } + return S_OK; + } + } + + if (!IsMultiVol && isFinished) + break; + + SkipLookahed((size_t)(p - pStart)); + + if (Callback && (_cnt - progressPrev) >= ((UInt32)1 << 23)) + { + progressPrev = _cnt; + // const UInt64 numFiles64 = 0; + RINOK(Callback->SetCompleted(NULL, &_cnt)) + } + } + + return S_FALSE; +} + + +/* +---------- IncreaseRealPosition ---------- +moves virtual offset in virtual stream. +changing to new volumes is allowed +*/ + +HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished) +{ + isFinished = false; + + for (;;) + { + const size_t avail = GetAvail(); + + if (offset <= avail) + { + _bufPos += (size_t)offset; + _cnt += offset; + return S_OK; + } + + _cnt += avail; + offset -= avail; + + _bufCached = 0; + _bufPos = 0; + + if (!_inBufMode) + break; + + CanStartNewVol = true; + LookAhead(1); + + if (GetAvail() == 0) + return S_OK; + } + + // cache is empty + + if (!IsMultiVol) + { + _cnt += offset; + return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos); + } + + for (;;) + { + if (offset == 0) + return S_OK; + + if (Vols.StreamIndex < 0) + return S_FALSE; + if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size()) + { + isFinished = true; + return S_OK; + } + { + const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex]; + if (!s.Stream) + { + isFinished = true; + return S_OK; + } + if (_streamPos > s.Size) + return S_FALSE; + const UInt64 rem = s.Size - _streamPos; + if ((UInt64)offset <= rem) + { + _cnt += offset; + return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos); + } + RINOK(Seek_SavePos(s.Size)) + offset -= rem; + _cnt += rem; + } + + Stream = NULL; + _streamPos = 0; + Vols.StreamIndex++; + if ((unsigned)Vols.StreamIndex >= Vols.Streams.Size()) + { + isFinished = true; + return S_OK; + } + const CVols::CSubStreamInfo &s2 = Vols.Streams[(unsigned)Vols.StreamIndex]; + if (!s2.Stream) + { + isFinished = true; + return S_OK; + } + Stream = s2.Stream; + RINOK(Seek_SavePos(0)) + } +} + + + +/* +---------- LookAhead ---------- +Reads data to buffer, if required. + +It can read from volumes as long as Buffer.Size(). +But it moves to new volume, only if it's required to provide minRequired bytes in buffer. + +in: + (minRequired <= Buffer.Size()) + +return: + S_OK : if (GetAvail() < minRequired) after function return, it's end of stream(s) data, or no new volume stream. + Error codes: IInStream::Read() error or IInStream::Seek() error for multivol +*/ + +HRESULT CInArchive::LookAhead(size_t minRequired) +{ + for (;;) + { + const size_t avail = GetAvail(); + + if (minRequired <= avail) + return S_OK; + + if (_bufPos != 0) + { + if (avail != 0) + memmove(Buffer, Buffer + _bufPos, avail); + _bufPos = 0; + _bufCached = avail; + } + + const size_t pos = _bufCached; + UInt32 processed = 0; + HRESULT res = Stream->Read(Buffer + pos, (UInt32)(Buffer.Size() - pos), &processed); + _streamPos += processed; + _bufCached += processed; + + if (res != S_OK) + return res; + + if (processed != 0) + continue; + + if ( !IsMultiVol + || !CanStartNewVol + || Vols.StreamIndex < 0 + || (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size()) + return S_OK; + + const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1]; + if (!s.Stream) + return S_OK; + + RINOK(s.SeekToStart()) + + Vols.StreamIndex++; + _streamPos = 0; + Stream = s.Stream; + // Vols.NeedSeek = false; + } +} + + +class CUnexpectEnd {}; + + +/* +---------- SafeRead ---------- + +reads data of exact size from stream(s) + +in: + _inBufMode + if (CanStartNewVol) it can go to next volume before first byte reading, if there is end of volume data. + +in, out: + _streamPos : position in Stream + Stream + Vols : if (IsMultiVol) + _cnt + +out: + (CanStartNewVol == false), if some data was read + +return: + S_OK : success reading of requested data + +exceptions: + CSystemException() - stream reading error + CUnexpectEnd() : could not read data of requested size +*/ + +void CInArchive::SafeRead(Byte *data, unsigned size) +{ + unsigned processed; + HRESULT result = ReadFromCache(data, size, processed); + if (result != S_OK) + throw CSystemException(result); + if (size != processed) + throw CUnexpectEnd(); +} + +void CInArchive::ReadBuffer(CByteBuffer &buffer, unsigned size) +{ + buffer.Alloc(size); + if (size != 0) + SafeRead(buffer, size); +} + +// Byte CInArchive::ReadByte () { Byte b; SafeRead(&b, 1); return b; } +// UInt16 CInArchive::ReadUInt16() { Byte buf[2]; SafeRead(buf, 2); return Get16(buf); } +UInt32 CInArchive::ReadUInt32() { Byte buf[4]; SafeRead(buf, 4); return Get32(buf); } +UInt64 CInArchive::ReadUInt64() { Byte buf[8]; SafeRead(buf, 8); return Get64(buf); } + +void CInArchive::ReadSignature() +{ + CanStartNewVol = true; + _signature = ReadUInt32(); + // CanStartNewVol = false; // it's already changed in SafeRead +} + + +// we Skip() inside headers only, so no need for stream change in multivol. + +void CInArchive::Skip(size_t num) +{ + while (num != 0) + { + const unsigned kBufSize = (size_t)1 << 10; + Byte buf[kBufSize]; + unsigned step = kBufSize; + if (step > num) + step = (unsigned)num; + SafeRead(buf, step); + num -= step; + } +} + +/* +HRESULT CInArchive::Callback_Completed(unsigned numFiles) +{ + const UInt64 numFiles64 = numFiles; + return Callback->SetCompleted(&numFiles64, &_cnt); +} +*/ + +HRESULT CInArchive::Skip64(UInt64 num, unsigned numFiles) +{ + if (num == 0) + return S_OK; + + for (;;) + { + size_t step = (size_t)1 << 24; + if (step > num) + step = (size_t)num; + Skip(step); + num -= step; + if (num == 0) + return S_OK; + if (Callback) + { + const UInt64 numFiles64 = numFiles; + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) + } + } +} + + +bool CInArchive::ReadFileName(unsigned size, AString &s) +{ + if (size == 0) + { + s.Empty(); + return true; + } + char *p = s.GetBuf(size); + SafeRead((Byte *)p, size); + unsigned i = size; + do + { + if (p[i - 1] != 0) + break; + } + while (--i); + s.ReleaseBuf_CalcLen(size); + return s.Len() == i; +} + + +#define ZIP64_IS_32_MAX(n) ((n) == 0xFFFFFFFF) +#define ZIP64_IS_16_MAX(n) ((n) == 0xFFFF) + + +bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra, + UInt64 &unpackSize, UInt64 &packSize, + CItem *cdItem) +{ + extra.Clear(); + + while (extraSize >= 4) + { + CExtraSubBlock subBlock; + const UInt32 pair = ReadUInt32(); + subBlock.ID = (pair & 0xFFFF); + unsigned size = (unsigned)(pair >> 16); + // const unsigned origSize = size; + + extraSize -= 4; + + if (size > extraSize) + { + // it's error in extra + HeadersWarning = true; + extra.Error = true; + Skip(extraSize); + return false; + } + + extraSize -= size; + + if (subBlock.ID == NFileHeader::NExtraID::kZip64) + { + extra.IsZip64 = true; + bool isOK = true; + + if (!cdItem + && size == 16 + && !ZIP64_IS_32_MAX(unpackSize) + && !ZIP64_IS_32_MAX(packSize)) + { + /* Win10 Explorer's "Send to Zip" for big (3500 MiB) files + creates Zip64 Extra in local file header. + But if both uncompressed and compressed sizes are smaller than 4 GiB, + Win10 doesn't store 0xFFFFFFFF in 32-bit fields as expected by zip specification. + 21.04: we ignore these minor errors in Win10 zip archives. */ + if (ReadUInt64() != unpackSize) + isOK = false; + if (ReadUInt64() != packSize) + isOK = false; + size = 0; + } + else + { + if (ZIP64_IS_32_MAX(unpackSize)) + { if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }} + + if (isOK && ZIP64_IS_32_MAX(packSize)) + { if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }} + + if (cdItem) + { + 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(); }} + } + } + + // we can ignore errors, when some zip archiver still write all fields to zip64 extra in local header + // if (&& (cdItem || !isOK || origSize != 8 * 3 + 4 || size != 8 * 1 + 4)) + if (!isOK || size != 0) + { + HeadersWarning = true; + extra.Error = true; + extra.IsZip64_Error = true; + } + Skip(size); + } + else + { + ReadBuffer(subBlock.Data, size); + extra.SubBlocks.Add(subBlock); + if (subBlock.ID == NFileHeader::NExtraID::kIzUnicodeName) + { + if (!subBlock.CheckIzUnicode(item.Name)) + extra.Error = true; + } + } + } + + if (extraSize != 0) + { + ExtraMinorError = true; + extra.MinorError = true; + // 7-Zip before 9.31 created incorrect WzAES Extra in folder's local headers. + // so we don't return false, but just set warning flag + // return false; + Skip(extraSize); + } + + return true; +} + + +bool CInArchive::ReadLocalItem(CItemEx &item) +{ + item.Disk = 0; + if (IsMultiVol && Vols.StreamIndex >= 0) + item.Disk = (UInt32)Vols.StreamIndex; + const unsigned kPureHeaderSize = kLocalHeaderSize - 4; + Byte p[kPureHeaderSize]; + SafeRead(p, kPureHeaderSize); + { + unsigned i; + for (i = 0; i < kPureHeaderSize && p[i] == 0; i++); + if (i == kPureHeaderSize) + return false; + } + + item.ExtractVersion.Version = p[0]; + item.ExtractVersion.HostOS = p[1]; + G16(2, item.Flags); + G16(4, item.Method); + G32(6, item.Time); + G32(10, item.Crc); + G32(14, item.PackSize); + G32(18, item.Size); + const unsigned nameSize = Get16(p + 22); + const unsigned extraSize = Get16(p + 24); + bool isOkName = ReadFileName(nameSize, item.Name); + item.LocalFullHeaderSize = kLocalHeaderSize + (UInt32)nameSize + extraSize; + item.DescriptorWasRead = false; + + /* + if (item.IsDir()) + item.Size = 0; // check It + */ + + if (extraSize > 0) + { + if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, NULL)) + { + /* Most of archives are OK for Extra. But there are some rare cases + that have error. And if error in first item, it can't open archive. + So we ignore that error */ + // return false; + } + } + + if (!CheckDosTime(item.Time)) + { + HeadersWarning = true; + // return false; + } + + if (item.Name.Len() != nameSize) + { + // we support some "bad" zip archives that contain zeros after name + if (!isOkName) + return false; + HeadersWarning = true; + } + + // return item.LocalFullHeaderSize <= ((UInt32)1 << 16); + return true; +} + + +static bool FlagsAreSame(const CItem &i1, const CItem &i2_cd) +{ + if (i1.Method != i2_cd.Method) + return false; + + UInt32 mask = i1.Flags ^ i2_cd.Flags; + if (mask == 0) + return true; + switch (i1.Method) + { + case NFileHeader::NCompressionMethod::kDeflate: + mask &= 0x7FF9; + break; + default: + if (i1.Method <= NFileHeader::NCompressionMethod::kImplode) + mask &= 0x7FFF; + } + + // we can ignore utf8 flag, if name is ascii, or if only cdItem has utf8 flag + if (mask & NFileHeader::NFlags::kUtf8) + if ((i1.Name.IsAscii() && i2_cd.Name.IsAscii()) + || (i2_cd.Flags & NFileHeader::NFlags::kUtf8)) + mask &= ~NFileHeader::NFlags::kUtf8; + + // some bad archive in rare case can use descriptor without descriptor flag in Central Dir + // if (i1.HasDescriptor()) + mask &= ~NFileHeader::NFlags::kDescriptorUsedMask; + + return (mask == 0); +} + + +// #ifdef _WIN32 +static bool AreEqualPaths_IgnoreSlashes(const char *s1, const char *s2) +{ + for (;;) + { + char c1 = *s1++; + char c2 = *s2++; + if (c1 == c2) + { + if (c1 == 0) + return true; + } + else + { + if (c1 == '\\') c1 = '/'; + if (c2 == '\\') c2 = '/'; + if (c1 != c2) + return false; + } + } +} +// #endif + + +static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem) +{ + if (!FlagsAreSame(localItem, cdItem)) + return false; + if (!localItem.HasDescriptor()) + { + if (cdItem.PackSize != localItem.PackSize + || cdItem.Size != localItem.Size + || (cdItem.Crc != localItem.Crc && cdItem.Crc != 0)) // some program writes 0 to crc field in central directory + return false; + } + /* pkzip 2.50 creates incorrect archives. It uses + - WIN encoding for name in local header + - OEM encoding for name in central header + We don't support these strange items. */ + + /* if (cdItem.Name.Len() != localItem.Name.Len()) + return false; + */ + if (cdItem.Name != localItem.Name) + { + // #ifdef _WIN32 + // some xap files use backslash in central dir items. + // we can ignore such errors in windows, where all slashes are converted to backslashes + unsigned hostOs = cdItem.GetHostOS(); + + if (hostOs == NFileHeader::NHostOS::kFAT || + hostOs == NFileHeader::NHostOS::kNTFS) + { + if (!AreEqualPaths_IgnoreSlashes(cdItem.Name, localItem.Name)) + { + // pkzip 2.50 uses DOS encoding in central dir and WIN encoding in local header. + // so we ignore that error + if (hostOs != NFileHeader::NHostOS::kFAT + || cdItem.MadeByVersion.Version < 25 + || cdItem.MadeByVersion.Version > 40) + return false; + } + } + /* + else + #endif + return false; + */ + } + return true; +} + + +HRESULT CInArchive::Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError) +{ + isAvail = true; + headersError = false; + if (item.FromLocal) + return S_OK; + try + { + UInt64 offset = item.LocalHeaderPos; + + if (IsMultiVol) + { + if (item.Disk >= Vols.Streams.Size()) + { + isAvail = false; + return S_FALSE; + } + Stream = Vols.Streams[item.Disk].Stream; + Vols.StreamIndex = (int)item.Disk; + if (!Stream) + { + isAvail = false; + return S_FALSE; + } + } + else + { + if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex) + { + isAvail = false; + return S_FALSE; + } + Stream = StreamRef; + + offset = (UInt64)((Int64)offset + ArcInfo.Base); + if (ArcInfo.Base < 0 && (Int64)offset < 0) + { + isAvail = false; + return S_FALSE; + } + } + + _inBufMode = false; + RINOK(Seek_SavePos(offset)) + InitBuf(); + /* + // we can use buf mode with small buffer to reduce + // the number of Read() calls in ReadLocalItem() + _inBufMode = true; + Buffer.Alloc(1 << 10); + if (!Buffer.IsAllocated()) + return E_OUTOFMEMORY; + */ + + CItemEx localItem; + if (ReadUInt32() != NSignature::kLocalFileHeader) + return S_FALSE; + ReadLocalItem(localItem); + if (!AreItemsEqual(localItem, item)) + return S_FALSE; + item.LocalFullHeaderSize = localItem.LocalFullHeaderSize; + item.LocalExtra = localItem.LocalExtra; + if (item.Crc != localItem.Crc && !localItem.HasDescriptor()) + { + item.Crc = localItem.Crc; + headersError = true; + } + if ((item.Flags ^ localItem.Flags) & NFileHeader::NFlags::kDescriptorUsedMask) + { + item.Flags = (UInt16)(item.Flags ^ NFileHeader::NFlags::kDescriptorUsedMask); + headersError = true; + } + item.FromLocal = true; + } + catch(...) { return S_FALSE; } + return S_OK; +} + + +/* +---------- FindDescriptor ---------- + +in: + _streamPos : position in Stream + Stream : + Vols : if (IsMultiVol) + +action: + searches descriptor in input stream(s). + sets + item.DescriptorWasRead = true; + item.Size + item.PackSize + item.Crc + if descriptor was found + +out: + S_OK: + if ( item.DescriptorWasRead) : if descriptor was found + if (!item.DescriptorWasRead) : if descriptor was not found : unexpected end of stream(s) + + S_FALSE: if no items or there is just one item with strange properies that doesn't look like real archive. + + another error code: Callback error. + +exceptions : + CSystemException() : stream reading error +*/ + +HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles) +{ + // const size_t kBufSize = (size_t)1 << 5; // don't increase it too much. It reads data look ahead. + + // Buffer.Alloc(kBufSize); + // Byte *buf = Buffer; + + UInt64 packedSize = 0; + + UInt64 progressPrev = _cnt; + + for (;;) + { + /* appnote specification claims that we must use 64-bit descriptor, if there is zip64 extra. + But some old third-party xps archives used 64-bit descriptor without zip64 extra. */ + // unsigned descriptorSize = kDataDescriptorSize64 + kNextSignatureSize; + + // const unsigned kNextSignatureSize = 0; // we can disable check for next signatuire + const unsigned kNextSignatureSize = 4; // we check also for signature for next File headear + + const unsigned descriptorSize4 = item.GetDescriptorSize() + kNextSignatureSize; + + if (descriptorSize4 > Buffer.Size()) return E_FAIL; + + // size_t processedSize; + CanStartNewVol = true; + RINOK(LookAhead(descriptorSize4)) + const size_t avail = GetAvail(); + + if (avail < descriptorSize4) + { + // we write to packSize all these available bytes. + // later it's simpler to work with such value than with 0 + // if (item.PackSize == 0) + item.PackSize = packedSize + avail; + if (item.Method == 0) + item.Size = item.PackSize; + SkipLookahed(avail); + return S_OK; + } + + const Byte * const pStart = Buffer + _bufPos; + const Byte * p = pStart; + const Byte * const limit = pStart + (avail - descriptorSize4); + + for (; p <= limit; p++) + { + // descriptor signature field is Info-ZIP's extension to pkware Zip specification. + // New ZIP specification also allows descriptorSignature. + + p = FindPK_4(p, limit + 1); + if (p > limit) + break; + + /* + if (*p != 0x50) + continue; + */ + + if (Get32(p) != NSignature::kDataDescriptor) + continue; + + // we check next signatuire after descriptor + // maybe we need check only 2 bytes "PK" instead of 4 bytes, if some another type of header is possible after descriptor + const UInt32 sig = Get32(p + descriptorSize4 - kNextSignatureSize); + if ( sig != NSignature::kLocalFileHeader + && sig != NSignature::kCentralFileHeader) + continue; + + const UInt64 packSizeCur = packedSize + (size_t)(p - pStart); + if (descriptorSize4 == kDataDescriptorSize64 + kNextSignatureSize) // if (item.LocalExtra.IsZip64) + { + const UInt64 descriptorPackSize = Get64(p + 8); + if (descriptorPackSize != packSizeCur) + continue; + item.Size = Get64(p + 16); + } + else + { + const UInt32 descriptorPackSize = Get32(p + 8); + if (descriptorPackSize != (UInt32)packSizeCur) + continue; + item.Size = Get32(p + 12); + // that item.Size can be truncated to 32-bit value here + } + // We write calculated 64-bit packSize, even if descriptor64 was not used + item.PackSize = packSizeCur; + + item.DescriptorWasRead = true; + item.Crc = Get32(p + 4); + + const size_t skip = (size_t)(p - pStart) + descriptorSize4 - kNextSignatureSize; + + SkipLookahed(skip); + + return S_OK; + } + + const size_t skip = (size_t)(p - pStart); + SkipLookahed(skip); + + packedSize += skip; + + if (Callback) + if (_cnt - progressPrev >= ((UInt32)1 << 22)) + { + progressPrev = _cnt; + const UInt64 numFiles64 = numFiles; + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) + } + } +} + + +HRESULT CInArchive::CheckDescriptor(const CItemEx &item) +{ + if (!item.HasDescriptor()) + return S_OK; + + // pkzip's version without descriptor signature is not supported + + bool isFinished = false; + RINOK(IncreaseRealPosition(item.PackSize, isFinished)) + if (isFinished) + return S_FALSE; + + /* + if (!IsMultiVol) + { + RINOK(Seek_SavePos(ArcInfo.Base + item.GetDataPosition() + item.PackSize)); + } + */ + + Byte buf[kDataDescriptorSize64]; + try + { + CanStartNewVol = true; + SafeRead(buf, item.GetDescriptorSize()); + } + catch (const CSystemException &e) { return e.ErrorCode; } + // catch (const CUnexpectEnd &) + catch(...) + { + return S_FALSE; + } + // RINOK(ReadStream_FALSE(Stream, buf, item.GetDescriptorSize())); + + if (Get32(buf) != NSignature::kDataDescriptor) + return S_FALSE; + UInt32 crc = Get32(buf + 4); + UInt64 packSize, unpackSize; + + if (item.LocalExtra.IsZip64) + { + packSize = Get64(buf + 8); + unpackSize = Get64(buf + 16); + } + else + { + packSize = Get32(buf + 8); + unpackSize = Get32(buf + 12); + } + + if (crc != item.Crc || item.PackSize != packSize || item.Size != unpackSize) + return S_FALSE; + return S_OK; +} + + +HRESULT CInArchive::Read_LocalItem_After_CdItem_Full(CItemEx &item) +{ + if (item.FromLocal) + return S_OK; + try + { + bool isAvail = true; + bool headersError = false; + RINOK(Read_LocalItem_After_CdItem(item, isAvail, headersError)) + if (headersError) + return S_FALSE; + if (item.HasDescriptor()) + return CheckDescriptor(item); + } + catch(...) { return S_FALSE; } + return S_OK; +} + + +HRESULT CInArchive::ReadCdItem(CItemEx &item) +{ + item.FromCentral = true; + Byte p[kCentralHeaderSize - 4]; + SafeRead(p, kCentralHeaderSize - 4); + + item.MadeByVersion.Version = p[0]; + item.MadeByVersion.HostOS = p[1]; + item.ExtractVersion.Version = p[2]; + item.ExtractVersion.HostOS = p[3]; + G16(4, item.Flags); + G16(6, item.Method); + G32(8, item.Time); + G32(12, item.Crc); + G32(16, item.PackSize); + G32(20, item.Size); + const unsigned nameSize = Get16(p + 24); + const unsigned extraSize = Get16(p + 26); + const unsigned commentSize = Get16(p + 28); + G16(30, item.Disk); + G16(32, item.InternalAttrib); + G32(34, item.ExternalAttrib); + G32(38, item.LocalHeaderPos); + ReadFileName(nameSize, item.Name); + + if (extraSize > 0) + ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, &item); + + // May be these strings must be deleted + /* + if (item.IsDir()) + item.Size = 0; + */ + + ReadBuffer(item.Comment, commentSize); + return S_OK; +} + + +/* +TryEcd64() + (_inBufMode == false) is expected here + so TryEcd64() can't change the Buffer. + if (Ecd64 is not covered by cached region), + TryEcd64() can change cached region ranges (_bufCached, _bufPos) and _streamPos. +*/ + +HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo) +{ + if (offset >= ((UInt64)1 << 63)) + return S_FALSE; + Byte buf[kEcd64_FullSize]; + + RINOK(SeekToVol(Vols.StreamIndex, offset)) + RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize)) + + if (Get32(buf) != NSignature::kEcd64) + return S_FALSE; + UInt64 mainSize = Get64(buf + 4); + if (mainSize < kEcd64_MainSize || mainSize > ((UInt64)1 << 40)) + return S_FALSE; + cdInfo.ParseEcd64e(buf + 12); + return S_OK; +} + + +/* FindCd() doesn't use previous cached region, + but it uses Buffer. So it sets new cached region */ + +HRESULT CInArchive::FindCd(bool checkOffsetMode) +{ + CCdInfo &cdInfo = Vols.ecd; + + UInt64 endPos; + + // There are no useful data in cache in most cases here. + // So here we don't use cache data from previous operations . + + InitBuf(); + RINOK(InStream_GetSize_SeekToEnd(Stream, endPos)) + _streamPos = endPos; + + // const UInt32 kBufSizeMax2 = ((UInt32)1 << 16) + kEcdSize + kEcd64Locator_Size + kEcd64_FullSize; + const size_t kBufSizeMax = ((size_t)1 << 17); // must be larger than kBufSizeMax2 + + const size_t bufSize = (endPos < kBufSizeMax) ? (size_t)endPos : kBufSizeMax; + if (bufSize < kEcdSize) + return S_FALSE; + // CByteArr byteBuffer(bufSize); + + RINOK(AllocateBuffer(kBufSizeMax)) + + RINOK(Seek_SavePos(endPos - bufSize)) + + size_t processed = bufSize; + HRESULT res = ReadStream(Stream, Buffer, &processed); + _streamPos += processed; + _bufCached = processed; + _bufPos = 0; + _cnt += processed; + if (res != S_OK) + return res; + if (processed != bufSize) + return S_FALSE; + + + for (size_t i = bufSize - kEcdSize + 1;;) + { + if (i == 0) + return S_FALSE; + + const Byte *buf = Buffer; + + for (;;) + { + i--; + if (buf[i] == 0x50) + break; + if (i == 0) + return S_FALSE; + } + + if (Get32(buf + i) != NSignature::kEcd) + continue; + + cdInfo.ParseEcd32(buf + i); + + if (i >= kEcd64Locator_Size) + { + const size_t locatorIndex = i - kEcd64Locator_Size; + if (Get32(buf + locatorIndex) == NSignature::kEcd64Locator) + { + CLocator locator; + locator.Parse(buf + locatorIndex + 4); + UInt32 numDisks = locator.NumDisks; + // we ignore the error, where some zip creators use (NumDisks == 0) + if (numDisks == 0) + numDisks = 1; + if ((cdInfo.ThisDisk == numDisks - 1 || ZIP64_IS_16_MAX(cdInfo.ThisDisk)) + && locator.Ecd64Disk < numDisks) + { + if (locator.Ecd64Disk != cdInfo.ThisDisk && !ZIP64_IS_16_MAX(cdInfo.ThisDisk)) + return E_NOTIMPL; + + // Most of the zip64 use fixed size Zip64 ECD + // we try relative backward reading. + + UInt64 absEcd64 = endPos - bufSize + i - (kEcd64Locator_Size + kEcd64_FullSize); + + if (locatorIndex >= kEcd64_FullSize) + if (checkOffsetMode || absEcd64 == locator.Ecd64Offset) + { + const Byte *ecd64 = buf + locatorIndex - kEcd64_FullSize; + if (Get32(ecd64) == NSignature::kEcd64) + { + UInt64 mainEcd64Size = Get64(ecd64 + 4); + if (mainEcd64Size == kEcd64_MainSize) + { + cdInfo.ParseEcd64e(ecd64 + 12); + ArcInfo.Base = (Int64)(absEcd64 - locator.Ecd64Offset); + // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; + return S_OK; + } + } + } + + // some zip64 use variable size Zip64 ECD. + // we try to use absolute offset from locator. + + if (absEcd64 != locator.Ecd64Offset) + { + if (TryEcd64(locator.Ecd64Offset, cdInfo) == S_OK) + { + ArcInfo.Base = 0; + // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; + return S_OK; + } + } + + // for variable Zip64 ECD with for archives with offset != 0. + + if (checkOffsetMode + && ArcInfo.MarkerPos != 0 + && ArcInfo.MarkerPos + locator.Ecd64Offset != absEcd64) + { + if (TryEcd64(ArcInfo.MarkerPos + locator.Ecd64Offset, cdInfo) == S_OK) + { + ArcInfo.Base = (Int64)ArcInfo.MarkerPos; + // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; + return S_OK; + } + } + } + } + } + + // bool isVolMode = (Vols.EndVolIndex != -1); + // UInt32 searchDisk = (isVolMode ? Vols.EndVolIndex : 0); + + if (/* searchDisk == thisDisk && */ cdInfo.CdDisk <= cdInfo.ThisDisk) + { + // if (isVolMode) + { + if (cdInfo.CdDisk != cdInfo.ThisDisk) + return S_OK; + } + + UInt64 absEcdPos = endPos - bufSize + i; + UInt64 cdEnd = cdInfo.Size + cdInfo.Offset; + ArcInfo.Base = 0; + // ArcInfo.BaseVolIndex = cdInfo.ThisDisk; + if (absEcdPos != cdEnd) + { + /* + if (cdInfo.Offset <= 16 && cdInfo.Size != 0) + { + // here we support some rare ZIP files with Central directory at the start + ArcInfo.Base = 0; + } + else + */ + ArcInfo.Base = (Int64)(absEcdPos - cdEnd); + } + return S_OK; + } + } +} + + +HRESULT CInArchive::TryReadCd(CObjectVector &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize) +{ + items.Clear(); + IsCdUnsorted = false; + + // _startLocalFromCd_Disk = (UInt32)(Int32)-1; + // _startLocalFromCd_Offset = (UInt64)(Int64)-1; + + RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset)) + + _inBufMode = true; + _cnt = 0; + + if (Callback) + { + RINOK(Callback->SetTotal(&cdInfo.NumEntries, IsMultiVol ? &Vols.TotalBytesSize : NULL)) + } + UInt64 numFileExpected = cdInfo.NumEntries; + const UInt64 *totalFilesPtr = &numFileExpected; + bool isCorrect_NumEntries = (cdInfo.IsFromEcd64 || numFileExpected >= ((UInt32)1 << 16)); + + while (_cnt < cdSize) + { + CanStartNewVol = true; + if (ReadUInt32() != NSignature::kCentralFileHeader) + return S_FALSE; + CanStartNewVol = false; + { + CItemEx cdItem; + RINOK(ReadCdItem(cdItem)) + + /* + if (cdItem.Disk < _startLocalFromCd_Disk || + cdItem.Disk == _startLocalFromCd_Disk && + cdItem.LocalHeaderPos < _startLocalFromCd_Offset) + { + _startLocalFromCd_Disk = cdItem.Disk; + _startLocalFromCd_Offset = cdItem.LocalHeaderPos; + } + */ + + if (items.Size() > 0 && !IsCdUnsorted) + { + const CItemEx &prev = items.Back(); + if (cdItem.Disk < prev.Disk + || (cdItem.Disk == prev.Disk && + cdItem.LocalHeaderPos < prev.LocalHeaderPos)) + IsCdUnsorted = true; + } + + items.Add(cdItem); + } + if (Callback && (items.Size() & 0xFFF) == 0) + { + const UInt64 numFiles = items.Size(); + + if (numFiles > numFileExpected && totalFilesPtr) + { + if (isCorrect_NumEntries) + totalFilesPtr = NULL; + else + while (numFiles > numFileExpected) + numFileExpected += (UInt32)1 << 16; + RINOK(Callback->SetTotal(totalFilesPtr, NULL)) + } + + RINOK(Callback->SetCompleted(&numFiles, &_cnt)) + } + } + + CanStartNewVol = true; + + return (_cnt == cdSize) ? S_OK : S_FALSE; +} + + +/* +static int CompareCdItems(void *const *elem1, void *const *elem2, void *) +{ + const CItemEx *i1 = *(const CItemEx **)elem1; + const CItemEx *i2 = *(const CItemEx **)elem2; + + if (i1->Disk < i2->Disk) return -1; + if (i1->Disk > i2->Disk) return 1; + if (i1->LocalHeaderPos < i2->LocalHeaderPos) return -1; + if (i1->LocalHeaderPos > i2->LocalHeaderPos) return 1; + if (i1 < i2) return -1; + if (i1 > i2) return 1; + return 0; +} +*/ + +HRESULT CInArchive::ReadCd(CObjectVector &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize) +{ + bool checkOffsetMode = true; + + if (IsMultiVol) + { + if (Vols.EndVolIndex == -1) + return S_FALSE; + Stream = Vols.Streams[(unsigned)Vols.EndVolIndex].Stream; + if (!Vols.StartIsZip) + checkOffsetMode = false; + } + else + Stream = StartStream; + + if (!Vols.ecd_wasRead) + { + RINOK(FindCd(checkOffsetMode)) + } + + CCdInfo &cdInfo = Vols.ecd; + + HRESULT res = S_FALSE; + + cdSize = cdInfo.Size; + cdOffset = cdInfo.Offset; + cdDisk = cdInfo.CdDisk; + + if (!IsMultiVol) + { + if (cdInfo.ThisDisk != cdInfo.CdDisk) + return S_FALSE; + } + + const UInt64 base = (IsMultiVol ? 0 : (UInt64)ArcInfo.Base); + res = TryReadCd(items, cdInfo, base + cdOffset, cdSize); + + if (res == S_FALSE && !IsMultiVol && base != ArcInfo.MarkerPos) + { + // do we need that additional attempt to read cd? + res = TryReadCd(items, cdInfo, ArcInfo.MarkerPos + cdOffset, cdSize); + if (res == S_OK) + ArcInfo.Base = (Int64)ArcInfo.MarkerPos; + } + + // Some rare case files are unsorted + // items.Sort(CompareCdItems, NULL); + return res; +} + + +static int FindItem(const CObjectVector &items, const CItemEx &item) +{ + unsigned left = 0, right = items.Size(); + for (;;) + { + if (left >= right) + return -1; + const unsigned index = (unsigned)(((size_t)left + (size_t)right) / 2); + const CItemEx &item2 = items[index]; + if (item.Disk < item2.Disk) + right = index; + else if (item.Disk > item2.Disk) + left = index + 1; + else if (item.LocalHeaderPos == item2.LocalHeaderPos) + return (int)index; + else if (item.LocalHeaderPos < item2.LocalHeaderPos) + right = index; + else + left = index + 1; + } +} + +static bool IsStrangeItem(const CItem &item) +{ + return item.Name.Len() > (1 << 14) || item.Method > (1 << 8); +} + + + +/* + ---------- ReadLocals ---------- + +in: + (_signature == NSignature::kLocalFileHeader) + VirtStreamPos : after _signature : position in Stream + Stream : + Vols : if (IsMultiVol) + (_inBufMode == false) + +action: + it parses local items. + + if ( IsMultiVol) it writes absolute offsets to CItemEx::LocalHeaderPos + if (!IsMultiVol) it writes relative (from ArcInfo.Base) offsets to CItemEx::LocalHeaderPos + later we can correct CItemEx::LocalHeaderPos values, if + some new value for ArcInfo.Base will be detected +out: + S_OK: + (_signature != NSignature::kLocalFileHeade) + _streamPos : after _signature + + S_FALSE: if no items or there is just one item with strange properies that doesn't look like real archive. + + another error code: stream reading error or Callback error. + + CUnexpectEnd() exception : it's not fatal exception here. + It means that reading was interrupted by unexpected end of input stream, + but some CItemEx items were parsed OK. + We can stop further archive parsing. + But we can use all filled CItemEx items. +*/ + +HRESULT CInArchive::ReadLocals(CObjectVector &items) +{ + items.Clear(); + + UInt64 progressPrev = _cnt; + + if (Callback) + { + RINOK(Callback->SetTotal(NULL, IsMultiVol ? &Vols.TotalBytesSize : NULL)) + } + + while (_signature == NSignature::kLocalFileHeader) + { + CItemEx item; + + item.LocalHeaderPos = GetVirtStreamPos() - 4; + if (!IsMultiVol) + item.LocalHeaderPos = (UInt64)((Int64)item.LocalHeaderPos - ArcInfo.Base); + + try + { + ReadLocalItem(item); + item.FromLocal = true; + bool isFinished = false; + + if (item.HasDescriptor()) + { + RINOK(FindDescriptor(item, items.Size())) + isFinished = !item.DescriptorWasRead; + } + else + { + if (item.PackSize >= ((UInt64)1 << 62)) + throw CUnexpectEnd(); + RINOK(IncreaseRealPosition(item.PackSize, isFinished)) + } + + items.Add(item); + + if (isFinished) + throw CUnexpectEnd(); + + ReadSignature(); + } + catch (CUnexpectEnd &) + { + if (items.IsEmpty() || (items.Size() == 1 && IsStrangeItem(items[0]))) + return S_FALSE; + throw; + } + + + if (Callback) + if ((items.Size() & 0xFF) == 0 + || _cnt - progressPrev >= ((UInt32)1 << 22)) + { + progressPrev = _cnt; + const UInt64 numFiles = items.Size(); + RINOK(Callback->SetCompleted(&numFiles, &_cnt)) + } + } + + if (items.Size() == 1 && _signature != NSignature::kCentralFileHeader) + if (IsStrangeItem(items[0])) + return S_FALSE; + + return S_OK; +} + + + +HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback) +{ + UString name; + { + NWindows::NCOM::CPropVariant prop; + RINOK(volCallback->GetProperty(kpidName, &prop)) + if (prop.vt != VT_BSTR) + return S_OK; + name = prop.bstrVal; + } + + const int dotPos = name.ReverseFind_Dot(); + if (dotPos < 0) + return S_OK; + const UString ext = name.Ptr((unsigned)(dotPos + 1)); + name.DeleteFrom((unsigned)(dotPos + 1)); + + StartVolIndex = (Int32)(-1); + + if (ext.IsEmpty()) + return S_OK; + { + wchar_t c = ext[0]; + IsUpperCase = (c >= 'A' && c <= 'Z'); + if (ext.IsEqualTo_Ascii_NoCase("zip")) + { + BaseName = name; + StartIsZ = true; + StartIsZip = true; + return S_OK; + } + else if (ext.IsEqualTo_Ascii_NoCase("exe")) + { + /* possible cases: + - exe with zip inside + - sfx: a.exe, a.z02, a.z03,... , a.zip + a.exe is start volume. + - zip renamed to exe + */ + + StartIsExe = true; + BaseName = name; + StartVolIndex = 0; + /* sfx-zip can use both arc.exe and arc.zip + We can open arc.zip, if it was requesed to open arc.exe. + But it's possible that arc.exe and arc.zip are not parts of same archive. + So we can disable such operation */ + + // 18.04: we still want to open zip renamed to exe. + /* + { + UString volName = name; + volName += IsUpperCase ? "Z01" : "z01"; + { + CMyComPtr stream; + HRESULT res2 = volCallback->GetStream(volName, &stream); + if (res2 == S_OK) + DisableVolsSearch = true; + } + } + */ + DisableVolsSearch = true; + return S_OK; + } + else if (ext[0] == 'z' || ext[0] == 'Z') + { + if (ext.Len() < 3) + return S_OK; + const wchar_t *end = NULL; + UInt32 volNum = ConvertStringToUInt32(ext.Ptr(1), &end); + if (*end != 0 || volNum < 1 || volNum > ((UInt32)1 << 30)) + return S_OK; + StartVolIndex = (Int32)(volNum - 1); + BaseName = name; + StartIsZ = true; + } + else + return S_OK; + } + + UString volName = BaseName; + volName += (IsUpperCase ? "ZIP" : "zip"); + + HRESULT res = volCallback->GetStream(volName, &ZipStream); + + if (res == S_FALSE || !ZipStream) + { + if (MissingName.IsEmpty()) + { + MissingZip = true; + MissingName = volName; + } + return S_OK; + } + + return res; +} + + +HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback, + unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols) +{ + if (Vols.DisableVolsSearch) + return S_OK; + + numMissingVols = 0; + + for (unsigned i = start;; i++) + { + if (lastDisk >= 0 && i >= (unsigned)lastDisk) + break; + + if (i < Vols.Streams.Size()) + if (Vols.Streams[i].Stream) + continue; + + CMyComPtr stream; + + if ((int)i == zipDisk) + { + stream = Vols.ZipStream; + } + else if ((int)i == Vols.StartVolIndex) + { + stream = StartStream; + } + else + { + UString volName = Vols.BaseName; + { + volName.Add_Char(Vols.IsUpperCase ? 'Z' : 'z'); + const unsigned v = i + 1; + if (v < 10) + volName.Add_Char('0'); + volName.Add_UInt32(v); + } + + HRESULT res = volCallback->GetStream(volName, &stream); + if (res != S_OK && res != S_FALSE) + return res; + if (res == S_FALSE || !stream) + { + if (i == 0) + { + UString volName_exe = Vols.BaseName; + volName_exe += (Vols.IsUpperCase ? "EXE" : "exe"); + + HRESULT res2 = volCallback->GetStream(volName_exe, &stream); + if (res2 != S_OK && res2 != S_FALSE) + return res2; + res = res2; + } + } + if (res == S_FALSE || !stream) + { + if (i == 1 && Vols.StartIsExe) + return S_OK; + if (Vols.MissingName.IsEmpty()) + Vols.MissingName = volName; + numMissingVols++; + if (numMissingVols > numMissingVolsMax) + return S_OK; + if (lastDisk == -1 && numMissingVols != 0) + return S_OK; + continue; + } + } + + UInt64 pos, size; + RINOK(InStream_GetPos_GetSize(stream, pos, size)) + + while (i >= Vols.Streams.Size()) + Vols.Streams.AddNew(); + + CVols::CSubStreamInfo &ss = Vols.Streams[i]; + Vols.NumVols++; + Vols.TotalBytesSize += size; + + ss.Stream = stream; + ss.Size = size; + + if ((int)i == zipDisk) + { + Vols.EndVolIndex = (int)(Vols.Streams.Size() - 1); + break; + } + } + + return S_OK; +} + + +HRESULT CInArchive::ReadVols() +{ + CMyComPtr volCallback; + + Callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&volCallback); + if (!volCallback) + return S_OK; + + RINOK(Vols.ParseArcName(volCallback)) + + // const int startZIndex = Vols.StartVolIndex; + + if (!Vols.StartIsZ) + { + if (!Vols.StartIsExe) + return S_OK; + } + + int zipDisk = -1; + int cdDisk = -1; + + if (Vols.StartIsZip) + Vols.ZipStream = StartStream; + + if (Vols.ZipStream) + { + Stream = Vols.ZipStream; + + if (Vols.StartIsZip) + Vols.StreamIndex = -1; + else + { + Vols.StreamIndex = -2; + InitBuf(); + } + + HRESULT res = FindCd(true); + + CCdInfo &ecd = Vols.ecd; + if (res == S_OK) + { + zipDisk = (int)ecd.ThisDisk; + Vols.ecd_wasRead = true; + + // if is not multivol or bad multivol, we return to main single stream code + if (ecd.ThisDisk == 0 + || ecd.ThisDisk >= ((UInt32)1 << 30) + || ecd.ThisDisk < ecd.CdDisk) + return S_OK; + + cdDisk = (int)ecd.CdDisk; + if (Vols.StartVolIndex < 0) + Vols.StartVolIndex = (Int32)ecd.ThisDisk; + else if ((UInt32)Vols.StartVolIndex >= ecd.ThisDisk) + return S_OK; + + // Vols.StartVolIndex = ecd.ThisDisk; + // Vols.EndVolIndex = ecd.ThisDisk; + unsigned numMissingVols; + if (cdDisk != zipDisk) + { + // get volumes required for cd. + RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols)) + if (numMissingVols != 0) + { + // cdOK = false; + } + } + } + else if (res != S_FALSE) + return res; + } + + if (Vols.StartVolIndex < 0) + { + // is not mutivol; + return S_OK; + } + + /* + if (!Vols.Streams.IsEmpty()) + IsMultiVol = true; + */ + + unsigned numMissingVols; + + if (cdDisk != 0) + { + // get volumes that were no requested still + const unsigned kNumMissingVolsMax = 1 << 12; + RINOK(ReadVols2(volCallback, 0, cdDisk < 0 ? -1 : cdDisk, zipDisk, kNumMissingVolsMax, numMissingVols)) + } + + // if (Vols.StartVolIndex >= 0) + { + if (Vols.Streams.IsEmpty()) + if (Vols.StartVolIndex > (1 << 20)) + return S_OK; + if ((unsigned)Vols.StartVolIndex >= Vols.Streams.Size() + || !Vols.Streams[(unsigned)Vols.StartVolIndex].Stream) + { + // we get volumes starting from StartVolIndex, if they we not requested before know the volume index (if FindCd() was ok) + RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols)) + } + } + + if (Vols.ZipStream) + { + // if there is no another volumes and volumeIndex is too big, we don't use multivol mode + if (Vols.Streams.IsEmpty()) + if (zipDisk > (1 << 10)) + return S_OK; + if (zipDisk >= 0) + { + // we create item in Streams for ZipStream, if we know the volume index (if FindCd() was ok) + RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols)) + } + } + + if (!Vols.Streams.IsEmpty()) + { + IsMultiVol = true; + /* + if (cdDisk) + IsMultiVol = true; + */ + const int startZIndex = Vols.StartVolIndex; + if (startZIndex >= 0) + { + // if all volumes before start volume are OK, we can start parsing from 0 + // if there are missing volumes before startZIndex, we start parsing in current startZIndex + if ((unsigned)startZIndex < Vols.Streams.Size()) + { + for (unsigned i = 0; i <= (unsigned)startZIndex; i++) + if (!Vols.Streams[i].Stream) + { + Vols.StartParsingVol = startZIndex; + break; + } + } + } + } + + return S_OK; +} + + + +HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + for (;;) + { + if (StreamIndex < 0) + return S_OK; + if ((unsigned)StreamIndex >= Streams.Size()) + return S_OK; + const CVols::CSubStreamInfo &s = Streams[(unsigned)StreamIndex]; + if (!s.Stream) + return S_FALSE; + if (NeedSeek) + { + RINOK(s.SeekToStart()) + NeedSeek = false; + } + UInt32 realProcessedSize = 0; + HRESULT res = s.Stream->Read(data, size, &realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + if (res != S_OK) + return res; + if (realProcessedSize != 0) + return res; + StreamIndex++; + NeedSeek = true; + } +} + +Z7_COM7F_IMF(CVolStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + return Vols->Read(data, size, processedSize); +} + + + + +#define COPY_ECD_ITEM_16(n) if (!isZip64 || !ZIP64_IS_16_MAX(ecd. n)) cdInfo. n = ecd. n; +#define COPY_ECD_ITEM_32(n) if (!isZip64 || !ZIP64_IS_32_MAX(ecd. n)) cdInfo. n = ecd. n; + + +HRESULT CInArchive::ReadHeaders(CObjectVector &items) +{ + // buffer that can be used for cd reading + RINOK(AllocateBuffer(kSeqBufferSize)) + + // here we can read small records. So we switch off _inBufMode. + _inBufMode = false; + + HRESULT res = S_OK; + + bool localsWereRead = false; + + /* we try to open archive with the following modes: + 1) CD-MODE : fast mode : we read backward ECD and CD, compare CD items with first Local item. + 2) LOCALS-CD-MODE : slow mode, if CD-MODE fails : we sequentially read all Locals and then CD. + Then we read sequentially ECD64, Locator, ECD again at the end. + + - in LOCALS-CD-MODE we use use the following + variables (with real cd properties) to set Base archive offset + and check real cd properties with values from ECD/ECD64. + */ + + UInt64 cdSize = 0; + UInt64 cdRelatOffset = 0; + UInt32 cdDisk = 0; + + UInt64 cdAbsOffset = 0; // absolute cd offset, for LOCALS-CD-MODE only. + +if (Force_ReadLocals_Mode) +{ + IsArc = true; + res = S_FALSE; // we will use LOCALS-CD-MODE mode +} +else +{ + if (!MarkerIsFound || !MarkerIsSafe) + { + IsArc = true; + res = ReadCd(items, cdDisk, cdRelatOffset, cdSize); + if (res == S_OK) + ReadSignature(); + else if (res != S_FALSE) + return res; + } + else // (MarkerIsFound && MarkerIsSafe) + { + + // _signature must be kLocalFileHeader or kEcd or kEcd64 + + SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2 + 4); + + CanStartNewVol = false; + + if (_signature == NSignature::kEcd64) + { + // UInt64 ecd64Offset = GetVirtStreamPos() - 4; + IsZip64 = true; + + { + const UInt64 recordSize = ReadUInt64(); + if (recordSize < kEcd64_MainSize) + return S_FALSE; + if (recordSize >= ((UInt64)1 << 62)) + return S_FALSE; + + { + const unsigned kBufSize = kEcd64_MainSize; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + CCdInfo cdInfo; + cdInfo.ParseEcd64e(buf); + if (!cdInfo.IsEmptyArc()) + return S_FALSE; + } + + RINOK(Skip64(recordSize - kEcd64_MainSize, 0)) + } + + ReadSignature(); + if (_signature != NSignature::kEcd64Locator) + return S_FALSE; + + { + const unsigned kBufSize = 16; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + CLocator locator; + locator.Parse(buf); + if (!locator.IsEmptyArc()) + return S_FALSE; + } + + ReadSignature(); + if (_signature != NSignature::kEcd) + return S_FALSE; + } + + if (_signature == NSignature::kEcd) + { + // It must be empty archive or backware archive + // we don't support backware archive still + + const unsigned kBufSize = kEcdSize - 4; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + CEcd ecd; + ecd.Parse(buf); + // if (ecd.cdSize != 0) + // Do we need also to support the case where empty zip archive with PK00 uses cdOffset = 4 ?? + if (!ecd.IsEmptyArc()) + return S_FALSE; + + ArcInfo.Base = (Int64)ArcInfo.MarkerPos; + IsArc = true; // check it: we need more tests? + + RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)) + ReadSignature(); + } + else + { + CItemEx firstItem; + try + { + try + { + if (!ReadLocalItem(firstItem)) + return S_FALSE; + } + catch(CUnexpectEnd &) + { + return S_FALSE; + } + + IsArc = true; + res = ReadCd(items, cdDisk, cdRelatOffset, cdSize); + if (res == S_OK) + ReadSignature(); + } + catch(CUnexpectEnd &) { res = S_FALSE; } + + if (res != S_FALSE && res != S_OK) + return res; + + if (res == S_OK && items.Size() == 0) + res = S_FALSE; + + if (res == S_OK) + { + // we can't read local items here to keep _inBufMode state + if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base) + res = S_FALSE; + else + { + firstItem.LocalHeaderPos = (UInt64)((Int64)ArcInfo.MarkerPos2 - ArcInfo.Base); + int index = -1; + + UInt32 min_Disk = (UInt32)(Int32)-1; + UInt64 min_LocalHeaderPos = (UInt64)(Int64)-1; + + if (!IsCdUnsorted) + index = FindItem(items, firstItem); + else + { + FOR_VECTOR (i, items) + { + const CItemEx &cdItem = items[i]; + if (cdItem.Disk == firstItem.Disk + && (cdItem.LocalHeaderPos == firstItem.LocalHeaderPos)) + index = (int)i; + + if (i == 0 + || cdItem.Disk < min_Disk + || (cdItem.Disk == min_Disk && cdItem.LocalHeaderPos < min_LocalHeaderPos)) + { + min_Disk = cdItem.Disk; + min_LocalHeaderPos = cdItem.LocalHeaderPos; + } + } + } + + if (index == -1) + res = S_FALSE; + else if (!AreItemsEqual(firstItem, items[(unsigned)index])) + res = S_FALSE; + else + { + ArcInfo.CdWasRead = true; + if (IsCdUnsorted) + ArcInfo.FirstItemRelatOffset = min_LocalHeaderPos; + else + ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos; + + // ArcInfo.FirstItemRelatOffset = _startLocalFromCd_Offset; + } + } + } + } + } // (MarkerIsFound && MarkerIsSafe) + +} // (!onlyLocalsMode) + + + CObjectVector cdItems; + + bool needSetBase = false; // we set needSetBase only for LOCALS_CD_MODE + unsigned numCdItems = items.Size(); + + #ifdef ZIP_SELF_CHECK + res = S_FALSE; // if uncommented, it uses additional LOCALS-CD-MODE mode to check the code + #endif + + if (res != S_OK) + { + // ---------- LOCALS-CD-MODE ---------- + // CD doesn't match firstItem, + // so we clear items and read Locals and CD. + + items.Clear(); + localsWereRead = true; + + HeadersError = false; + HeadersWarning = false; + ExtraMinorError = false; + + /* we can use any mode: with buffer and without buffer + without buffer : skips packed data : fast for big files : slow for small files + with buffer : reads packed data : slow for big files : fast for small files + Buffer mode is more effective. */ + // _inBufMode = false; + _inBufMode = true; + // we could change the buffer size here, if we want smaller Buffer. + // RINOK(ReAllocateBuffer(kSeqBufferSize)); + // InitBuf() + + ArcInfo.Base = 0; + + if (!Disable_FindMarker) + { + if (!MarkerIsFound) + { + if (!IsMultiVol) + return S_FALSE; + if (Vols.StartParsingVol != 0) + return S_FALSE; + // if (StartParsingVol == 0) and we didn't find marker, we use default zero marker. + // so we suppose that there is no sfx stub + RINOK(SeekToVol(0, ArcInfo.MarkerPos2)) + } + else + { + if (ArcInfo.MarkerPos != 0) + { + /* + If multi-vol or there is (No)Span-marker at start of stream, we set (Base) as 0. + In another caes: + (No)Span-marker is supposed as false positive. So we set (Base) as main marker (MarkerPos2). + The (Base) can be corrected later after ECD reading. + But sfx volume with stub and (No)Span-marker in (!IsMultiVol) mode will have incorrect (Base) here. + */ + ArcInfo.Base = (Int64)ArcInfo.MarkerPos2; + } + RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2)) + } + } + _cnt = 0; + + ReadSignature(); + + LocalsWereRead = true; + + RINOK(ReadLocals(items)) + + if (_signature != NSignature::kCentralFileHeader) + { + // GetVirtStreamPos() - 4 + if (items.IsEmpty()) + return S_FALSE; + + bool isError = true; + + const UInt32 apkSize = _signature; + const unsigned kApkFooterSize = 16 + 8; + if (apkSize >= kApkFooterSize && apkSize <= (1 << 20)) + { + if (ReadUInt32() == 0) + { + CByteBuffer apk; + apk.Alloc(apkSize); + SafeRead(apk, apkSize); + ReadSignature(); + const Byte *footer = apk + apkSize - kApkFooterSize; + if (_signature == NSignature::kCentralFileHeader) + if (GetUi64(footer) == apkSize) + if (memcmp(footer + 8, "APK Sig Block 42", 16) == 0) + { + isError = false; + IsApk = true; + } + } + } + + if (isError) + { + NoCentralDir = true; + HeadersError = true; + return S_OK; + } + } + + _inBufMode = true; + + cdAbsOffset = GetVirtStreamPos() - 4; + cdDisk = (UInt32)Vols.StreamIndex; + + #ifdef ZIP_SELF_CHECK + if (!IsMultiVol && _cnt != GetVirtStreamPos() - ArcInfo.MarkerPos2) + return E_FAIL; + #endif + + const UInt64 processedCnt_start = _cnt; + + for (;;) + { + CItemEx cdItem; + + RINOK(ReadCdItem(cdItem)) + + cdItems.Add(cdItem); + if (Callback && (cdItems.Size() & 0xFFF) == 0) + { + const UInt64 numFiles = items.Size(); + const UInt64 numBytes = _cnt; + RINOK(Callback->SetCompleted(&numFiles, &numBytes)) + } + ReadSignature(); + if (_signature != NSignature::kCentralFileHeader) + break; + } + + cdSize = _cnt - processedCnt_start; + + #ifdef ZIP_SELF_CHECK + if (!IsMultiVol) + { + if (_cnt != GetVirtStreamPos() - ArcInfo.MarkerPos2) + return E_FAIL; + if (cdSize != (GetVirtStreamPos() - 4) - cdAbsOffset) + return E_FAIL; + } + #endif + + needSetBase = true; + numCdItems = cdItems.Size(); + cdRelatOffset = (UInt64)((Int64)cdAbsOffset - ArcInfo.Base); + + if (!cdItems.IsEmpty()) + { + ArcInfo.CdWasRead = true; + ArcInfo.FirstItemRelatOffset = cdItems[0].LocalHeaderPos; + } + } + + + + CCdInfo cdInfo; + CLocator locator; + bool isZip64 = false; + const UInt64 ecd64AbsOffset = GetVirtStreamPos() - 4; + int ecd64Disk = -1; + + if (_signature == NSignature::kEcd64) + { + ecd64Disk = Vols.StreamIndex; + + IsZip64 = isZip64 = true; + + { + const UInt64 recordSize = ReadUInt64(); + if (recordSize < kEcd64_MainSize + || recordSize >= ((UInt64)1 << 62)) + { + HeadersError = true; + return S_OK; + } + + { + const unsigned kBufSize = kEcd64_MainSize; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + cdInfo.ParseEcd64e(buf); + } + + RINOK(Skip64(recordSize - kEcd64_MainSize, items.Size())) + } + + + ReadSignature(); + + if (_signature != NSignature::kEcd64Locator) + { + HeadersError = true; + return S_OK; + } + + { + const unsigned kBufSize = 16; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + locator.Parse(buf); + // we ignore the error, where some zip creators use (NumDisks == 0) + // if (locator.NumDisks == 0) HeadersWarning = true; + } + + ReadSignature(); + } + + + if (_signature != NSignature::kEcd) + { + HeadersError = true; + return S_OK; + } + + + CanStartNewVol = false; + + // ---------- ECD ---------- + + CEcd ecd; + { + const unsigned kBufSize = kEcdSize - 4; + Byte buf[kBufSize]; + SafeRead(buf, kBufSize); + ecd.Parse(buf); + } + + COPY_ECD_ITEM_16(ThisDisk) + COPY_ECD_ITEM_16(CdDisk) + COPY_ECD_ITEM_16(NumEntries_in_ThisDisk) + COPY_ECD_ITEM_16(NumEntries) + COPY_ECD_ITEM_32(Size) + COPY_ECD_ITEM_32(Offset) + + bool cdOK = true; + + if ((UInt32)cdInfo.Size != (UInt32)cdSize) + { + // return S_FALSE; + cdOK = false; + } + + if (isZip64) + { + if (cdInfo.NumEntries != numCdItems + || cdInfo.Size != cdSize) + { + cdOK = false; + } + } + + + if (IsMultiVol) + { + if (cdDisk != cdInfo.CdDisk) + HeadersError = true; + } + else if (needSetBase && cdOK) + { + const UInt64 oldBase = (UInt64)ArcInfo.Base; + // localsWereRead == true + // ArcInfo.Base == ArcInfo.MarkerPos2 + // cdRelatOffset == (cdAbsOffset - ArcInfo.Base) + + if (isZip64) + { + if (ecd64Disk == Vols.StartVolIndex) + { + const Int64 newBase = (Int64)ecd64AbsOffset - (Int64)locator.Ecd64Offset; + if (newBase <= (Int64)ecd64AbsOffset) + { + if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2) + { + ArcInfo.Base = newBase; + cdRelatOffset = (UInt64)((Int64)cdAbsOffset - newBase); + } + else + cdOK = false; + } + } + } + else if (numCdItems != 0) // we can't use ecd.Offset in empty archive? + { + if ((int)cdDisk == Vols.StartVolIndex) + { + const Int64 newBase = (Int64)cdAbsOffset - (Int64)cdInfo.Offset; + if (newBase <= (Int64)cdAbsOffset) + { + if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2) + { + // cd can be more accurate, when it points before Locals + // so we change Base and cdRelatOffset + ArcInfo.Base = newBase; + cdRelatOffset = cdInfo.Offset; + } + else + { + // const UInt64 delta = ((UInt64)cdRelatOffset - cdInfo.Offset); + const UInt64 delta = ((UInt64)(newBase - ArcInfo.Base)); + if ((UInt32)delta == 0) + { + // we set Overflow32bit mode, only if there is (x<<32) offset + // between real_CD_offset_from_MarkerPos and CD_Offset_in_ECD. + // Base and cdRelatOffset unchanged + Overflow32bit = true; + } + else + cdOK = false; + } + } + else + cdOK = false; + } + } + // cdRelatOffset = cdAbsOffset - ArcInfo.Base; + + if (localsWereRead) + { + const UInt64 delta = (UInt64)((Int64)oldBase - ArcInfo.Base); + if (delta != 0) + { + FOR_VECTOR (i, items) + items[i].LocalHeaderPos += delta; + } + } + } + + if (!cdOK) + HeadersError = true; + + EcdVolIndex = cdInfo.ThisDisk; + + if (!IsMultiVol) + { + if (EcdVolIndex == 0 && Vols.MissingZip && Vols.StartIsExe) + { + Vols.MissingName.Empty(); + Vols.MissingZip = false; + } + + if (localsWereRead) + { + if (EcdVolIndex != 0) + { + FOR_VECTOR (i, items) + items[i].Disk = EcdVolIndex; + } + } + + UseDisk_in_SingleVol = true; + } + + if (isZip64) + { + if ((cdInfo.ThisDisk == 0 && ecd64AbsOffset != (UInt64)(ArcInfo.Base + (Int64)locator.Ecd64Offset)) + // || cdInfo.NumEntries_in_ThisDisk != numCdItems + || cdInfo.NumEntries != numCdItems + || cdInfo.Size != cdSize + || (cdInfo.Offset != cdRelatOffset && !items.IsEmpty())) + { + HeadersError = true; + return S_OK; + } + } + + if (cdOK && !cdItems.IsEmpty()) + { + // ---------- merge Central Directory Items ---------- + + CRecordVector items2; + + int nextLocalIndex = 0; + + LocalsCenterMerged = true; + + FOR_VECTOR (i, cdItems) + { + if (Callback) + if ((i & 0x3FFF) == 0) + { + const UInt64 numFiles64 = items.Size() + items2.Size(); + RINOK(Callback->SetCompleted(&numFiles64, &_cnt)) + } + + const CItemEx &cdItem = cdItems[i]; + + int index = -1; + + if (nextLocalIndex != -1) + { + if ((unsigned)nextLocalIndex < items.Size()) + { + CItemEx &item = items[(unsigned)nextLocalIndex]; + if (item.Disk == cdItem.Disk && + (item.LocalHeaderPos == cdItem.LocalHeaderPos + || (Overflow32bit && (UInt32)item.LocalHeaderPos == cdItem.LocalHeaderPos))) + index = nextLocalIndex++; + else + nextLocalIndex = -1; + } + } + + if (index == -1) + index = FindItem(items, cdItem); + + // index = -1; + + if (index == -1) + { + items2.Add(i); + HeadersError = true; + continue; + } + + CItemEx &item = items[(unsigned)index]; + if (item.Name != cdItem.Name + // || item.Name.Len() != cdItem.Name.Len() + || item.PackSize != cdItem.PackSize + || item.Size != cdItem.Size + // item.ExtractVersion != cdItem.ExtractVersion + || !FlagsAreSame(item, cdItem) + || item.Crc != cdItem.Crc) + { + HeadersError = true; + continue; + } + + // item.Name = cdItem.Name; + item.MadeByVersion = cdItem.MadeByVersion; + item.CentralExtra = cdItem.CentralExtra; + item.InternalAttrib = cdItem.InternalAttrib; + item.ExternalAttrib = cdItem.ExternalAttrib; + item.Comment = cdItem.Comment; + item.FromCentral = cdItem.FromCentral; + // 22.02: we force utf8 flag, if central header has utf8 flag + if (cdItem.Flags & NFileHeader::NFlags::kUtf8) + item.Flags |= NFileHeader::NFlags::kUtf8; + } + + FOR_VECTOR (k, items2) + items.Add(cdItems[items2[k]]); + } + + if (ecd.NumEntries < ecd.NumEntries_in_ThisDisk) + HeadersError = true; + + if (ecd.ThisDisk == 0) + { + // if (isZip64) + { + if (ecd.NumEntries != ecd.NumEntries_in_ThisDisk) + HeadersError = true; + } + } + + if (isZip64) + { + if (cdInfo.NumEntries != items.Size() + || (ecd.NumEntries != items.Size() && ecd.NumEntries != 0xFFFF)) + HeadersError = true; + } + else + { + // old 7-zip could store 32-bit number of CD items to 16-bit field. + // if (ecd.NumEntries != items.Size()) + if (ecd.NumEntries > items.Size()) + HeadersError = true; + + if (cdInfo.NumEntries != numCdItems) + { + if ((UInt16)cdInfo.NumEntries != (UInt16)numCdItems) + HeadersError = true; + else + Cd_NumEntries_Overflow_16bit = true; + } + } + + ReadBuffer(ArcInfo.Comment, ecd.CommentSize); + + _inBufMode = false; + + // DisableBufMode(); + // Buffer.Free(); + /* we can't clear buf varibles. we need them to calculate PhySize of archive */ + + if ((UInt16)cdInfo.NumEntries != (UInt16)numCdItems + || (UInt32)cdInfo.Size != (UInt32)cdSize + || ((UInt32)cdInfo.Offset != (UInt32)cdRelatOffset && !items.IsEmpty())) + { + // return S_FALSE; + HeadersError = true; + } + + #ifdef ZIP_SELF_CHECK + if (localsWereRead) + { + const UInt64 endPos = ArcInfo.MarkerPos2 + _cnt; + if (endPos != (IsMultiVol ? Vols.TotalBytesSize : ArcInfo.FileEndPos)) + { + // there are some data after the end of archive or error in code; + return E_FAIL; + } + } + #endif + + // printf("\nOpen OK"); + return S_OK; +} + + + +HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit, + IArchiveOpenCallback *callback, CObjectVector &items) +{ + items.Clear(); + + Close(); + + UInt64 startPos; + RINOK(InStream_GetPos(stream, startPos)) + RINOK(InStream_GetSize_SeekToEnd(stream, ArcInfo.FileEndPos)) + _streamPos = ArcInfo.FileEndPos; + + StartStream = stream; + Stream = stream; + Callback = callback; + + DisableBufMode(); + + bool volWasRequested = false; + + if (!Disable_VolsRead) + if (callback + && (startPos == 0 || !searchLimit || *searchLimit != 0)) + { + // we try to read volumes only if it's first call (offset == 0) or scan is allowed. + volWasRequested = true; + RINOK(ReadVols()) + } + + if (Disable_FindMarker) + { + RINOK(SeekToVol(-1, startPos)) + StreamRef = stream; + Stream = stream; + MarkerIsFound = true; + MarkerIsSafe = true; + ArcInfo.MarkerPos = startPos; + ArcInfo.MarkerPos2 = startPos; + } + else + if (IsMultiVol && Vols.StartParsingVol == 0 && (unsigned)Vols.StartParsingVol < Vols.Streams.Size()) + { + // only StartParsingVol = 0 is safe search. + RINOK(SeekToVol(0, 0)) + // if (Stream) + { + // UInt64 limit = 1 << 22; // for sfx + UInt64 limit = 0; // without sfx + + HRESULT res = FindMarker(&limit); + + if (res == S_OK) + { + MarkerIsFound = true; + MarkerIsSafe = true; + } + else if (res != S_FALSE) + return res; + } + } + else + { + // printf("\nOpen offset = %u\n", (unsigned)startPos); + if (IsMultiVol + && (unsigned)Vols.StartParsingVol < Vols.Streams.Size() + && Vols.Streams[(unsigned)Vols.StartParsingVol].Stream) + { + RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0)) + } + else + { + RINOK(SeekToVol(-1, startPos)) + } + + // UInt64 limit = 1 << 22; + // HRESULT res = FindMarker(&limit); + + HRESULT res = FindMarker(searchLimit); + + // const UInt64 curPos = GetVirtStreamPos(); + const UInt64 curPos = ArcInfo.MarkerPos2 + 4; + + if (res == S_OK) + MarkerIsFound = true; + else if (!IsMultiVol) + { + /* + // if (startPos != 0), probably CD could be already tested with another call with (startPos == 0). + // so we don't want to try to open CD again in that case. + if (startPos != 0) + return res; + // we can try to open CD, if there is no Marker and (startPos == 0). + // is it OK to open such files as ZIP, or big number of false positive, when CD can be find in end of file ? + */ + return res; + } + + if (ArcInfo.IsSpanMode && !volWasRequested) + { + RINOK(ReadVols()) + if (IsMultiVol && MarkerIsFound && ArcInfo.MarkerVolIndex < 0) + ArcInfo.MarkerVolIndex = Vols.StartVolIndex; + } + + MarkerIsSafe = !IsMultiVol + || (ArcInfo.MarkerVolIndex == 0 && ArcInfo.MarkerPos == 0) + ; + + + if (IsMultiVol) + { + if ((unsigned)Vols.StartVolIndex < Vols.Streams.Size()) + { + Stream = Vols.Streams[(unsigned)Vols.StartVolIndex].Stream; + if (Stream) + { + RINOK(Seek_SavePos(curPos)) + } + else + IsMultiVol = false; + } + else + IsMultiVol = false; + } + + if (!IsMultiVol) + { + if (Vols.StreamIndex != -1) + { + Stream = StartStream; + Vols.StreamIndex = -1; + InitBuf(); + RINOK(Seek_SavePos(curPos)) + } + + ArcInfo.MarkerVolIndex = -1; + StreamRef = stream; + Stream = stream; + } + } + + + if (!IsMultiVol) + Vols.ClearRefs(); + + { + HRESULT res; + try + { + res = ReadHeaders(items); + } + catch (const CSystemException &e) { res = e.ErrorCode; } + catch (const CUnexpectEnd &) + { + if (items.IsEmpty()) + return S_FALSE; + UnexpectedEnd = true; + res = S_OK; + } + catch (...) + { + DisableBufMode(); + throw; + } + + if (IsMultiVol) + { + ArcInfo.FinishPos = ArcInfo.FileEndPos; + if ((unsigned)Vols.StreamIndex < Vols.Streams.Size()) + if (GetVirtStreamPos() < Vols.Streams[(unsigned)Vols.StreamIndex].Size) + ArcInfo.ThereIsTail = true; + } + else + { + ArcInfo.FinishPos = GetVirtStreamPos(); + ArcInfo.ThereIsTail = (ArcInfo.FileEndPos > ArcInfo.FinishPos); + } + + DisableBufMode(); + + IsArcOpen = true; + if (!IsMultiVol) + Vols.Streams.Clear(); + return res; + } +} + + +HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr &stream) +{ + stream.Release(); + + UInt64 pos = item.LocalHeaderPos; + if (seekPackData) + pos += item.LocalFullHeaderSize; + + if (!IsMultiVol) + { + if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex) + return S_OK; + pos = (UInt64)((Int64)pos + ArcInfo.Base); + RINOK(InStream_SeekSet(StreamRef, pos)) + stream = StreamRef; + return S_OK; + } + + if (item.Disk >= Vols.Streams.Size()) + return S_OK; + + IInStream *str2 = Vols.Streams[item.Disk].Stream; + if (!str2) + return S_OK; + RINOK(InStream_SeekSet(str2, pos)) + + Vols.NeedSeek = false; + Vols.StreamIndex = (int)item.Disk; + + CVolStream *volsStreamSpec = new CVolStream; + volsStreamSpec->Vols = &Vols; + stream = volsStreamSpec; + + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipIn.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipIn.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipIn.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,356 +1,449 @@ -// Archive/ZipIn.h - -#ifndef __ZIP_IN_H -#define __ZIP_IN_H - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" - -#include "../../Common/InBuffer.h" - -#include "ZipHeader.h" -#include "ZipItem.h" - -API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size); - -namespace NArchive { -namespace NZip { - -class CItemEx: public CItem -{ -public: - UInt32 LocalFullHeaderSize; // including Name and Extra - - UInt64 GetLocalFullSize() const - { return LocalFullHeaderSize + PackSize + (HasDescriptor() ? kDataDescriptorSize : 0); } - UInt64 GetDataPosition() const - { return LocalHeaderPos + LocalFullHeaderSize; } -}; - - -struct CInArchiveInfo -{ - Int64 Base; /* Base offset of start of archive in stream. - Offsets in headers must be calculated from that Base. - Base is equal to MarkerPos for normal ZIPs. - Base can point to PE stub for some ZIP SFXs. - if CentralDir was read, - Base can be negative, if start of data is not available, - if CentralDirs was not read, - Base = ArcInfo.MarkerPos; */ - - /* The following *Pos variables contain absolute offsets in Stream */ - - UInt64 MarkerPos; /* Pos of first signature, it can point to kSpan/kNoSpan signature - = MarkerPos2 in most archives - = MarkerPos2 - 4 if there is kSpan/kNoSpan signature */ - UInt64 MarkerPos2; // Pos of first local item signature in stream - UInt64 FinishPos; // Finish pos of archive data in starting volume - UInt64 FileEndPos; // Finish pos of stream - - UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). - = 0 in most archives - = size of stub for some SFXs */ - bool CdWasRead; - bool IsSpanMode; - bool ThereIsTail; - - // UInt32 BaseVolIndex; - - CByteBuffer Comment; - - - CInArchiveInfo(): - Base(0), - MarkerPos(0), - MarkerPos2(0), - FinishPos(0), - FileEndPos(0), - FirstItemRelatOffset(0), - CdWasRead(false), - IsSpanMode(false), - ThereIsTail(false) - // BaseVolIndex(0) - {} - - void Clear() - { - // BaseVolIndex = 0; - Base = 0; - MarkerPos = 0; - MarkerPos2 = 0; - FinishPos = 0; - FileEndPos = 0; - ThereIsTail = false; - - FirstItemRelatOffset = 0; - - CdWasRead = false; - IsSpanMode = false; - - Comment.Free(); - } -}; - - -struct CCdInfo -{ - // 64 - UInt16 VersionMade; - UInt16 VersionNeedExtract; - - // old zip - UInt32 ThisDisk; - UInt32 CdDisk; - UInt64 NumEntries_in_ThisDisk; - UInt64 NumEntries; - UInt64 Size; - UInt64 Offset; - - UInt16 CommentSize; - - CCdInfo() { memset(this, 0, sizeof(*this)); } - - void ParseEcd32(const Byte *p); // (p) includes signature - void ParseEcd64e(const Byte *p); // (p) exclude signature -}; - - -class CVols -{ -public: - - struct CSubStreamInfo - { - CMyComPtr Stream; - UInt64 Size; - - CSubStreamInfo(): Size(0) {} - }; - - CObjectVector Streams; - int StreamIndex; - bool NeedSeek; - - CMyComPtr ZipStream; - - bool StartIsExe; // is .exe - bool StartIsZ; // is .zip or .zNN - bool StartIsZip; // is .zip - bool IsUpperCase; - Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN - - Int32 StartParsingVol; // if we need local parsing, we must use that stream - unsigned NumVols; - - int EndVolIndex; // index of last volume (ecd volume), - // -1, if is not multivol - - UString BaseName; // including '.' - - UString MissingName; - - CCdInfo ecd; - bool ecd_wasRead; - - void Clear() - { - StreamIndex = -1; - NeedSeek = false; - - - StartIsExe = false; - StartIsZ = false; - StartIsZip = false; - IsUpperCase = false; - - StartVolIndex = -1; - StartParsingVol = 0; - NumVols = 0; - EndVolIndex = -1; - - BaseName.Empty(); - MissingName.Empty(); - - ecd_wasRead = false; - - Streams.Clear(); - ZipStream.Release(); - } - - HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback); - - HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); - - UInt64 GetTotalSize() const - { - UInt64 total = 0; - FOR_VECTOR (i, Streams) - total += Streams[i].Size; - return total; - } -}; - - -class CVolStream: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - CVols *Vols; - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - - -class CInArchive -{ - CInBuffer _inBuffer; - bool _inBufMode; - UInt32 m_Signature; - UInt64 m_Position; - - UInt64 _processedCnt; - - bool CanStartNewVol; - - CMyComPtr StreamRef; - IInStream *Stream; - IInStream *StartStream; - - bool IsArcOpen; - - HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback, - unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols); - HRESULT ReadVols(); - - HRESULT Seek(UInt64 offset); - HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit); - HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished); - - HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); - void SafeReadBytes(void *data, unsigned size); - void ReadBuffer(CByteBuffer &buffer, unsigned size); - Byte ReadByte(); - UInt16 ReadUInt16(); - UInt32 ReadUInt32(); - UInt64 ReadUInt64(); - void Skip(unsigned num); - void Skip64(UInt64 num); - void ReadFileName(unsigned nameSize, AString &dest); - - bool ReadExtra(unsigned extraSize, CExtraBlock &extraBlock, - UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber); - bool ReadLocalItem(CItemEx &item); - HRESULT ReadLocalItemDescriptor(CItemEx &item); - HRESULT ReadCdItem(CItemEx &item); - HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); - HRESULT FindCd(bool checkOffsetMode); - HRESULT TryReadCd(CObjectVector &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize); - HRESULT ReadCd(CObjectVector &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize); - HRESULT ReadLocals(CObjectVector &localItems); - - HRESULT ReadHeaders2(CObjectVector &items); - - HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr &stream); -public: - CInArchiveInfo ArcInfo; - - bool IsArc; - bool IsZip64; - bool HeadersError; - bool HeadersWarning; - bool ExtraMinorError; - bool UnexpectedEnd; - bool NoCentralDir; - - bool MarkerIsFound; - - bool IsMultiVol; - bool UseDisk_in_SingleVol; - UInt32 EcdVolIndex; - - CVols Vols; - - IArchiveOpenCallback *Callback; - - CInArchive(): Stream(NULL), Callback(NULL), IsArcOpen(false) {} - - UInt64 GetPhySize() const - { - if (IsMultiVol) - return ArcInfo.FinishPos; - else - return ArcInfo.FinishPos - ArcInfo.Base; - } - - UInt64 GetOffset() const - { - if (IsMultiVol) - return 0; - else - return ArcInfo.Base; - } - - - void ClearRefs(); - void Close(); - HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector &items); - HRESULT ReadHeaders(CObjectVector &items); - - bool IsOpen() const { return IsArcOpen; } - - bool AreThereErrors() const - { - return HeadersError - || UnexpectedEnd - || !Vols.MissingName.IsEmpty(); - } - - bool IsLocalOffsetOK(const CItemEx &item) const - { - if (item.FromLocal) - return true; - return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0; - } - - UInt64 GetEmbeddedStubSize() const - { - if (ArcInfo.CdWasRead) - return ArcInfo.FirstItemRelatOffset; - if (IsMultiVol) - return 0; - return ArcInfo.MarkerPos2 - ArcInfo.Base; - } - - - HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail); - HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); - - HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr &stream); - - IInStream *GetBaseStream() { return StreamRef; } - - bool CanUpdate() const - { - if (AreThereErrors() - || IsMultiVol - || ArcInfo.Base < 0 - || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base - || ArcInfo.ThereIsTail - || GetEmbeddedStubSize() != 0) - return false; - - // 7-zip probably can update archives with embedded stubs. - // we just disable that feature for more safety. - - return true; - } -}; - -}} - -#endif +// Archive/ZipIn.h + +#ifndef ZIP7_INC_ZIP_IN_H +#define ZIP7_INC_ZIP_IN_H + +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/MyCom.h" + +#include "../../Common/StreamUtils.h" +#include "../../IStream.h" + +#include "ZipHeader.h" +#include "ZipItem.h" + +API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size); + +namespace NArchive { +namespace NZip { + +class CItemEx: public CItem +{ +public: + UInt32 LocalFullHeaderSize; // including Name and Extra + // int ParentOfAltStream; // -1, if not AltStream + + bool DescriptorWasRead; + + CItemEx(): + // ParentOfAltStream(-1), + DescriptorWasRead(false) {} + + UInt64 GetLocalFullSize() const + { return LocalFullHeaderSize + GetPackSizeWithDescriptor(); } + UInt64 GetDataPosition() const + { return LocalHeaderPos + LocalFullHeaderSize; } + + bool IsBadDescriptor() const + { + return !FromCentral && FromLocal && HasDescriptor() && !DescriptorWasRead; + } +}; + + +struct CInArchiveInfo +{ + Int64 Base; /* Base offset of start of archive in stream. + Offsets in headers must be calculated from that Base. + Base is equal to MarkerPos for normal ZIPs. + Base can point to PE stub for some ZIP SFXs. + if CentralDir was read, + Base can be negative, if start of data is not available, + if CentralDirs was not read, + Base = ArcInfo.MarkerPos; */ + + /* The following *Pos variables contain absolute offsets in Stream */ + + UInt64 MarkerPos; /* Pos of first signature, it can point to kSpan/kNoSpan signature + = MarkerPos2 in most archives + = MarkerPos2 - 4 if there is kSpan/kNoSpan signature */ + UInt64 MarkerPos2; // Pos of first local item signature in stream + UInt64 FinishPos; // Finish pos of archive data in starting volume + UInt64 FileEndPos; // Finish pos of stream + + UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). + = 0 in most archives + = size of stub for some SFXs */ + + + int MarkerVolIndex; + + bool CdWasRead; + bool IsSpanMode; + bool ThereIsTail; + + // UInt32 BaseVolIndex; + + CByteBuffer Comment; + + + CInArchiveInfo(): + Base(0), + MarkerPos(0), + MarkerPos2(0), + FinishPos(0), + FileEndPos(0), + FirstItemRelatOffset(0), + MarkerVolIndex(-1), + CdWasRead(false), + IsSpanMode(false), + ThereIsTail(false) + // BaseVolIndex(0) + {} + + void Clear() + { + // BaseVolIndex = 0; + Base = 0; + MarkerPos = 0; + MarkerPos2 = 0; + FinishPos = 0; + FileEndPos = 0; + MarkerVolIndex = -1; + ThereIsTail = false; + + FirstItemRelatOffset = 0; + + CdWasRead = false; + IsSpanMode = false; + + Comment.Free(); + } +}; + + +struct CCdInfo +{ + bool IsFromEcd64; + + UInt16 CommentSize; + + // 64 + UInt16 VersionMade; + UInt16 VersionNeedExtract; + + // old zip + UInt32 ThisDisk; + UInt32 CdDisk; + UInt64 NumEntries_in_ThisDisk; + UInt64 NumEntries; + UInt64 Size; + UInt64 Offset; + + CCdInfo() { memset(this, 0, sizeof(*this)); IsFromEcd64 = false; } + + void ParseEcd32(const Byte *p); // (p) includes signature + void ParseEcd64e(const Byte *p); // (p) exclude signature + + bool IsEmptyArc() const + { + return ThisDisk == 0 + && CdDisk == 0 + && NumEntries_in_ThisDisk == 0 + && NumEntries == 0 + && Size == 0 + && Offset == 0 // test it + ; + } +}; + + +struct CVols +{ + struct CSubStreamInfo + { + CMyComPtr Stream; + UInt64 Size; + + HRESULT SeekToStart() const { return InStream_SeekToBegin(Stream); } + + CSubStreamInfo(): Size(0) {} + }; + + CObjectVector Streams; + + int StreamIndex; // -1 for StartStream + // -2 for ZipStream at multivol detection code + // >=0 volume index in multivol + + bool NeedSeek; + + bool DisableVolsSearch; + bool StartIsExe; // is .exe + bool StartIsZ; // is .zip or .zNN + bool StartIsZip; // is .zip + bool IsUpperCase; + bool MissingZip; + + bool ecd_wasRead; + + Int32 StartVolIndex; // -1, if unknown vol index + // = (NN - 1), if StartStream is .zNN + // = 0, if start vol is exe + + Int32 StartParsingVol; // if we need local parsing, we must use that stream + unsigned NumVols; + + int EndVolIndex; // index of last volume (ecd volume), + // -1, if is not multivol + + UString BaseName; // name of archive including '.' + UString MissingName; + + CMyComPtr ZipStream; + + CCdInfo ecd; + + UInt64 TotalBytesSize; // for MultiVol only + + void ClearRefs() + { + Streams.Clear(); + ZipStream.Release(); + TotalBytesSize = 0; + } + + void Clear() + { + StreamIndex = -1; + NeedSeek = false; + + DisableVolsSearch = false; + StartIsExe = false; + StartIsZ = false; + StartIsZip = false; + IsUpperCase = false; + + StartVolIndex = -1; + StartParsingVol = 0; + NumVols = 0; + EndVolIndex = -1; + + BaseName.Empty(); + MissingName.Empty(); + + MissingZip = false; + ecd_wasRead = false; + + ClearRefs(); + } + + HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback); + + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); +}; + + +Z7_CLASS_IMP_COM_1( + CVolStream + , ISequentialInStream +) +public: + CVols *Vols; +}; + + +class CInArchive +{ + CMidBuffer Buffer; + size_t _bufPos; + size_t _bufCached; + + UInt64 _streamPos; + UInt64 _cnt; + + // UInt32 _startLocalFromCd_Disk; + // UInt64 _startLocalFromCd_Offset; + + size_t GetAvail() const { return _bufCached - _bufPos; } + + void InitBuf() { _bufPos = 0; _bufCached = 0; } + void DisableBufMode() { InitBuf(); _inBufMode = false; } + + void SkipLookahed(size_t skip) + { + _bufPos += skip; + _cnt += skip; + } + + HRESULT AllocateBuffer(size_t size); + + UInt64 GetVirtStreamPos() { return _streamPos - _bufCached + _bufPos; } + + bool _inBufMode; + + bool IsArcOpen; + bool CanStartNewVol; + + UInt32 _signature; + + CMyComPtr StreamRef; + IInStream *Stream; + IInStream *StartStream; + IArchiveOpenCallback *Callback; + + HRESULT Seek_SavePos(UInt64 offset); + HRESULT SeekToVol(int volIndex, UInt64 offset); + + HRESULT ReadFromCache(Byte *data, unsigned size, unsigned &processed); + HRESULT ReadFromCache_FALSE(Byte *data, unsigned size); + + HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback, + unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols); + HRESULT ReadVols(); + + HRESULT FindMarker(const UInt64 *searchLimit); + HRESULT IncreaseRealPosition(UInt64 addValue, bool &isFinished); + + HRESULT LookAhead(size_t minRequiredInBuffer); + void SafeRead(Byte *data, unsigned size); + void ReadBuffer(CByteBuffer &buffer, unsigned size); + // Byte ReadByte(); + // UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + + void ReadSignature(); + + void Skip(size_t num); + HRESULT Skip64(UInt64 num, unsigned numFiles); + + bool ReadFileName(unsigned nameSize, AString &dest); + + bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra, + UInt64 &unpackSize, UInt64 &packSize, CItem *cdItem); + bool ReadLocalItem(CItemEx &item); + HRESULT FindDescriptor(CItemEx &item, unsigned numFiles); + HRESULT ReadCdItem(CItemEx &item); + HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); + HRESULT FindCd(bool checkOffsetMode); + HRESULT TryReadCd(CObjectVector &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize); + HRESULT ReadCd(CObjectVector &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize); + HRESULT ReadLocals(CObjectVector &localItems); + + HRESULT ReadHeaders(CObjectVector &items); + + HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr &stream); + +public: + CInArchiveInfo ArcInfo; + + bool IsArc; + bool IsZip64; + + bool IsApk; + bool IsCdUnsorted; + + bool HeadersError; + bool HeadersWarning; + bool ExtraMinorError; + bool UnexpectedEnd; + bool LocalsWereRead; + bool LocalsCenterMerged; + bool NoCentralDir; + bool Overflow32bit; // = true, if zip without Zip64 extension support and it has some fields values truncated to 32-bits. + bool Cd_NumEntries_Overflow_16bit; // = true, if no Zip64 and 16-bit ecd:NumEntries was overflowed. + + bool MarkerIsFound; + bool MarkerIsSafe; + + bool IsMultiVol; + bool UseDisk_in_SingleVol; + UInt32 EcdVolIndex; + + CVols Vols; + + bool Force_ReadLocals_Mode; + bool Disable_VolsRead; + bool Disable_FindMarker; + + CInArchive(): + IsArcOpen(false), + Stream(NULL), + StartStream(NULL), + Callback(NULL), + Force_ReadLocals_Mode(false), + Disable_VolsRead(false), + Disable_FindMarker(false) + {} + + UInt64 GetPhySize() const + { + if (IsMultiVol) + return ArcInfo.FinishPos; + else + return (UInt64)((Int64)ArcInfo.FinishPos - ArcInfo.Base); + } + + UInt64 GetOffset() const + { + if (IsMultiVol) + return 0; + else + return (UInt64)ArcInfo.Base; + } + + + void ClearRefs(); + void Close(); + HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector &items); + + bool IsOpen() const { return IsArcOpen; } + + bool AreThereErrors() const + { + return HeadersError + || UnexpectedEnd + || !Vols.MissingName.IsEmpty(); + } + + bool IsLocalOffsetOK(const CItemEx &item) const + { + if (item.FromLocal) + return true; + return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0; + } + + UInt64 GetEmbeddedStubSize() const + { + // it's possible that first item in CD doesn refers to first local item + // so FirstItemRelatOffset is not first local item + + if (ArcInfo.CdWasRead) + return ArcInfo.FirstItemRelatOffset; + if (IsMultiVol) + return 0; + return (UInt64)((Int64)ArcInfo.MarkerPos2 - ArcInfo.Base); + } + + + HRESULT CheckDescriptor(const CItemEx &item); + HRESULT Read_LocalItem_After_CdItem(CItemEx &item, bool &isAvail, bool &headersError); + HRESULT Read_LocalItem_After_CdItem_Full(CItemEx &item); + + HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr &stream); + + IInStream *GetBaseStream() { return StreamRef; } + + bool CanUpdate() const + { + if (AreThereErrors() + || IsMultiVol + || ArcInfo.Base < 0 + || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base + || ArcInfo.ThereIsTail + || GetEmbeddedStubSize() != 0 + || IsApk + || IsCdUnsorted) + return false; + + // 7-zip probably can update archives with embedded stubs. + // we just disable that feature for more safety. + + return true; + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipItem.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipItem.cpp 2016-02-01 16:50:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,255 +1,464 @@ -// Archive/ZipItem.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" -#include "../../../../C/7zCrc.h" - -#include "../../../Common/MyLinux.h" -#include "../../../Common/StringConvert.h" - -#include "../Common/ItemNameUtils.h" - -#include "ZipItem.h" - -namespace NArchive { -namespace NZip { - -using namespace NFileHeader; - -bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const -{ - ft.dwHighDateTime = ft.dwLowDateTime = 0; - UInt32 size = (UInt32)Data.Size(); - if (ID != NExtraID::kNTFS || size < 32) - return false; - const Byte *p = (const Byte *)Data; - p += 4; // for reserved - size -= 4; - while (size > 4) - { - UInt16 tag = GetUi16(p); - unsigned attrSize = GetUi16(p + 2); - p += 4; - size -= 4; - if (attrSize > size) - attrSize = size; - - if (tag == NNtfsExtra::kTagTime && attrSize >= 24) - { - p += 8 * index; - ft.dwLowDateTime = GetUi32(p); - ft.dwHighDateTime = GetUi32(p + 4); - return true; - } - p += attrSize; - size -= attrSize; - } - return false; -} - -bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const -{ - res = 0; - UInt32 size = (UInt32)Data.Size(); - if (ID != NExtraID::kUnixTime || size < 5) - return false; - const Byte *p = (const Byte *)Data; - Byte flags = *p++; - size--; - if (isCentral) - { - if (index != NUnixTime::kMTime || - (flags & (1 << NUnixTime::kMTime)) == 0 || - size < 4) - return false; - res = GetUi32(p); - return true; - } - for (unsigned i = 0; i < 3; i++) - if ((flags & (1 << i)) != 0) - { - if (size < 4) - return false; - if (index == i) - { - res = GetUi32(p); - return true; - } - p += 4; - size -= 4; - } - return false; -} - - -bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const -{ - FOR_VECTOR (i, SubBlocks) - { - const CExtraSubBlock &sb = SubBlocks[i]; - if (sb.ID == NFileHeader::NExtraID::kNTFS) - return sb.ExtractNtfsTime(index, ft); - } - return false; -} - -bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const -{ - FOR_VECTOR (i, SubBlocks) - { - const CExtraSubBlock &sb = SubBlocks[i]; - if (sb.ID == NFileHeader::NExtraID::kUnixTime) - return sb.ExtractUnixTime(isCentral, index, res); - } - return false; -} - - -bool CLocalItem::IsDir() const -{ - return NItemName::HasTailSlash(Name, GetCodePage()); -} - -bool CItem::IsDir() const -{ - if (NItemName::HasTailSlash(Name, GetCodePage())) - return true; - - Byte hostOS = GetHostOS(); - - if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\') - { - // do we need to use CharPrevExA? - // .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers? - // so we support that case - switch (hostOS) - { - case NHostOS::kFAT: - case NHostOS::kNTFS: - case NHostOS::kHPFS: - case NHostOS::kVFAT: - return true; - } - } - - if (!FromCentral) - return false; - - UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF); - - switch (hostOS) - { - case NHostOS::kAMIGA: - switch (highAttrib & NAmigaAttrib::kIFMT) - { - case NAmigaAttrib::kIFDIR: return true; - case NAmigaAttrib::kIFREG: return false; - default: return false; // change it throw kUnknownAttributes; - } - case NHostOS::kFAT: - case NHostOS::kNTFS: - case NHostOS::kHPFS: - case NHostOS::kVFAT: - return ((ExternalAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0); - case NHostOS::kAtari: - case NHostOS::kMac: - case NHostOS::kVMS: - case NHostOS::kVM_CMS: - case NHostOS::kAcorn: - case NHostOS::kMVS: - return false; // change it throw kUnknownAttributes; - case NHostOS::kUnix: - return MY_LIN_S_ISDIR(highAttrib); - default: - return false; - } -} - -UInt32 CItem::GetWinAttrib() const -{ - UInt32 winAttrib = 0; - switch (GetHostOS()) - { - case NHostOS::kFAT: - case NHostOS::kNTFS: - if (FromCentral) - winAttrib = ExternalAttrib; - break; -#ifdef FILE_ATTRIBUTE_UNIX_EXTENSION - case NFileHeader::NHostOS::kUnix: - winAttrib = (ExternalAttrib & 0xFFFF0000) | FILE_ATTRIBUTE_UNIX_EXTENSION; - if (winAttrib & (MY_LIN_S_IFDIR << 16)) - winAttrib |= FILE_ATTRIBUTE_DIRECTORY; - return winAttrib; -#endif - } - if (IsDir()) // test it; - winAttrib |= FILE_ATTRIBUTE_DIRECTORY; - return winAttrib; -} - -bool CItem::GetPosixAttrib(UInt32 &attrib) const -{ - // some archivers can store PosixAttrib in high 16 bits even with HostOS=FAT. - if (FromCentral && GetHostOS() == NHostOS::kUnix) - { - attrib = ExternalAttrib >> 16; - return (attrib != 0); - } - attrib = 0; - if (IsDir()) - attrib = MY_LIN_S_IFDIR; - return false; -} - -void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const -{ - bool isUtf8 = IsUtf8(); - bool ignore_Utf8_Errors = true; - - if (!isUtf8) - { - { - const unsigned id = isComment ? - NFileHeader::NExtraID::kIzUnicodeComment: - NFileHeader::NExtraID::kIzUnicodeName; - const CObjectVector &subBlocks = GetMainExtra().SubBlocks; - - FOR_VECTOR (i, subBlocks) - { - const CExtraSubBlock &sb = subBlocks[i]; - if (sb.ID == id) - { - AString utf; - if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf)) - if (ConvertUTF8ToUnicode(utf, res)) - return; - break; - } - } - } - - if (useSpecifiedCodePage) - isUtf8 = (codePage == CP_UTF8); - #ifdef _WIN32 - else if (GetHostOS() == NFileHeader::NHostOS::kUnix) - { - /* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header. - We try to get name as UTF-8. - Do we need to do it in POSIX version also? */ - isUtf8 = true; - ignore_Utf8_Errors = false; - } - #endif - } - - - if (isUtf8) - if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors) - return; - - MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage()); -} - -}} +// Archive/ZipItem.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" +#include "../../../../C/7zCrc.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/PropVariantUtils.h" + +#include "../Common/ItemNameUtils.h" + +#include "ZipItem.h" + +namespace NArchive { +namespace NZip { + +using namespace NFileHeader; + + +/* +const char *k_SpecName_NTFS_STREAM = "@@NTFS@STREAM@"; +const char *k_SpecName_MAC_RESOURCE_FORK = "@@MAC@RESOURCE-FORK@"; +*/ + +static const CUInt32PCharPair g_ExtraTypes[] = +{ + { NExtraID::kZip64, "Zip64" }, + { NExtraID::kNTFS, "NTFS" }, + { NExtraID::kUnix0, "UNIX" }, + { NExtraID::kStrongEncrypt, "StrongCrypto" }, + { NExtraID::kUnixTime, "UT" }, + { NExtraID::kUnix1, "UX" }, + { NExtraID::kUnix2, "Ux" }, + { NExtraID::kUnixN, "ux" }, + { NExtraID::kIzUnicodeComment, "uc" }, + { NExtraID::kIzUnicodeName, "up" }, + { NExtraID::kIzNtSecurityDescriptor, "SD" }, + { NExtraID::kWzAES, "WzAES" }, + { NExtraID::kApkAlign, "ApkAlign" } +}; + +void CExtraSubBlock::PrintInfo(AString &s) const +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ExtraTypes); i++) + { + const CUInt32PCharPair &pair = g_ExtraTypes[i]; + if (pair.Value == ID) + { + s += pair.Name; + if (ID == NExtraID::kUnixTime) + { + if (Data.Size() >= 1) + { + s.Add_Colon(); + const Byte flags = Data[0]; + if (flags & 1) s.Add_Char('M'); + if (flags & 2) s.Add_Char('A'); + if (flags & 4) s.Add_Char('C'); + const UInt32 size = (UInt32)(Data.Size()) - 1; + if (size % 4 == 0) + { + s.Add_Colon(); + s.Add_UInt32(size / 4); + } + } + } + /* + if (ID == NExtraID::kApkAlign && Data.Size() >= 2) + { + char sz[32]; + sz[0] = ':'; + ConvertUInt32ToHex(GetUi16(Data), sz + 1); + s += sz; + for (unsigned j = 2; j < Data.Size(); j++) + { + char sz[32]; + sz[0] = '-'; + ConvertUInt32ToHex(Data[j], sz + 1); + s += sz; + } + } + */ + return; + } + } + { + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(ID, sz + 2); + s += sz; + } +} + + +void CExtraBlock::PrintInfo(AString &s) const +{ + if (Error) + s.Add_OptSpaced("Extra_ERROR"); + + if (MinorError) + s.Add_OptSpaced("Minor_Extra_ERROR"); + + if (IsZip64 || IsZip64_Error) + { + s.Add_OptSpaced("Zip64"); + if (IsZip64_Error) + s += "_ERROR"; + } + + FOR_VECTOR (i, SubBlocks) + { + s.Add_Space_if_NotEmpty(); + SubBlocks[i].PrintInfo(s); + } +} + + +bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const +{ + ft.dwHighDateTime = ft.dwLowDateTime = 0; + UInt32 size = (UInt32)Data.Size(); + if (ID != NExtraID::kNTFS || size < 32) + return false; + const Byte *p = (const Byte *)Data; + p += 4; // for reserved + size -= 4; + while (size > 4) + { + UInt16 tag = GetUi16(p); + unsigned attrSize = GetUi16(p + 2); + p += 4; + size -= 4; + if (attrSize > size) + attrSize = size; + + if (tag == NNtfsExtra::kTagTime && attrSize >= 24) + { + p += 8 * index; + ft.dwLowDateTime = GetUi32(p); + ft.dwHighDateTime = GetUi32(p + 4); + return true; + } + p += attrSize; + size -= attrSize; + } + return false; +} + +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; + const Byte flags = *p++; + size--; + if (isCentral) + { + if (index != NUnixTime::kMTime || + (flags & (1 << NUnixTime::kMTime)) == 0 || + size < 4) + return false; + res = GetUi32(p); + return true; + } + for (unsigned i = 0; i < 3; i++) + if ((flags & (1 << i)) != 0) + { + if (size < 4) + return false; + if (index == i) + { + res = GetUi32(p); + return true; + } + p += 4; + size -= 4; + } + return false; +} + + +// Info-ZIP's abandoned "Unix1 timestamps & owner ID info" + +bool CExtraSubBlock::Extract_Unix01_Time(unsigned index, UInt32 &res) const +{ + res = 0; + 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 +{ + FOR_VECTOR (i, SubBlocks) + { + const CExtraSubBlock &sb = SubBlocks[i]; + if (sb.ID == NFileHeader::NExtraID::kNTFS) + return sb.ExtractNtfsTime(index, ft); + } + return false; +} + +bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const +{ + { + FOR_VECTOR (i, SubBlocks) + { + const CExtraSubBlock &sb = SubBlocks[i]; + if (sb.ID == NFileHeader::NExtraID::kUnixTime) + return sb.Extract_UnixTime(isCentral, index, res); + } + } + + switch (index) + { + case NUnixTime::kMTime: index = NUnixExtra::kMTime; break; + case NUnixTime::kATime: index = NUnixExtra::kATime; break; + default: return false; + } + + { + FOR_VECTOR (i, SubBlocks) + { + const CExtraSubBlock &sb = SubBlocks[i]; + if (sb.ID == NFileHeader::NExtraID::kUnix0 || + sb.ID == NFileHeader::NExtraID::kUnix1) + return sb.Extract_Unix01_Time(index, res); + } + } + return false; +} + + +bool CLocalItem::IsDir() const +{ + return NItemName::HasTailSlash(Name, GetCodePage()); +} + +bool CItem::IsDir() const +{ + // FIXME: we can check InfoZip UTF-8 name at first. + if (NItemName::HasTailSlash(Name, GetCodePage())) + return true; + + Byte hostOS = GetHostOS(); + + if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\') + { + // do we need to use CharPrevExA? + // .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers? + // so we support that case + switch (hostOS) + { + case NHostOS::kFAT: + case NHostOS::kNTFS: + case NHostOS::kHPFS: + case NHostOS::kVFAT: + return true; + default: break; + } + } + + if (!FromCentral) + return false; + + UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF); + + switch (hostOS) + { + case NHostOS::kAMIGA: + switch (highAttrib & NAmigaAttrib::kIFMT) + { + case NAmigaAttrib::kIFDIR: return true; + case NAmigaAttrib::kIFREG: return false; + default: return false; // change it throw kUnknownAttributes; + } + case NHostOS::kFAT: + case NHostOS::kNTFS: + case NHostOS::kHPFS: + case NHostOS::kVFAT: + return ((ExternalAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0); + case NHostOS::kAtari: + case NHostOS::kMac: + case NHostOS::kVMS: + case NHostOS::kVM_CMS: + case NHostOS::kAcorn: + case NHostOS::kMVS: + return false; // change it throw kUnknownAttributes; + case NHostOS::kUnix: + return MY_LIN_S_ISDIR(highAttrib); + default: + return false; + } +} + +UInt32 CItem::GetWinAttrib() const +{ + UInt32 winAttrib = 0; + switch (GetHostOS()) + { + case NHostOS::kFAT: + case NHostOS::kNTFS: + if (FromCentral) + winAttrib = ExternalAttrib; + break; + case NHostOS::kUnix: + // do we need to clear 16 low bits in this case? + if (FromCentral) + { + /* + Some programs write posix attributes in high 16 bits of ExternalAttrib + Also some programs can write additional marker flag: + 0x8000 - p7zip + 0x4000 - Zip in MacOS + no marker - Info-Zip + + Client code has two options to detect posix field: + 1) check 0x8000 marker. In that case we must add 0x8000 marker here. + 2) check that high 4 bits (file type bits in posix field) of attributes are not zero. + */ + + winAttrib = ExternalAttrib & 0xFFFF0000; + + // #ifndef _WIN32 + winAttrib |= 0x8000; // add posix mode marker + // #endif + } + break; + default: break; + } + if (IsDir()) // test it; + winAttrib |= FILE_ATTRIBUTE_DIRECTORY; + return winAttrib; +} + +bool CItem::GetPosixAttrib(UInt32 &attrib) const +{ + // some archivers can store PosixAttrib in high 16 bits even with HostOS=FAT. + if (FromCentral && GetHostOS() == NHostOS::kUnix) + { + attrib = ExternalAttrib >> 16; + return (attrib != 0); + } + attrib = 0; + if (IsDir()) + attrib = MY_LIN_S_IFDIR; + return false; +} + + +bool CExtraSubBlock::CheckIzUnicode(const AString &s) const +{ + size_t size = Data.Size(); + if (size < 1 + 4) + return false; + const Byte *p = (const Byte *)Data; + if (p[0] > 1) + return false; + if (CrcCalc(s, s.Len()) != GetUi32(p + 1)) + return false; + size -= 5; + p += 5; + for (size_t i = 0; i < size; i++) + if (p[i] == 0) + return false; + return Check_UTF8_Buf((const char *)(const void *)p, size, false); +} + + +void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const +{ + bool isUtf8 = IsUtf8(); + // bool ignore_Utf8_Errors = true; + + if (!isUtf8) + { + { + const unsigned id = isComment ? + NFileHeader::NExtraID::kIzUnicodeComment: + NFileHeader::NExtraID::kIzUnicodeName; + const CObjectVector &subBlocks = GetMainExtra().SubBlocks; + + FOR_VECTOR (i, subBlocks) + { + const CExtraSubBlock &sb = subBlocks[i]; + if (sb.ID == id) + { + if (sb.CheckIzUnicode(s)) + { + // const unsigned kIzUnicodeHeaderSize = 5; + if (Convert_UTF8_Buf_To_Unicode( + (const char *)(const void *)(const Byte *)sb.Data + 5, + sb.Data.Size() - 5, res)) + return; + } + break; + } + } + } + + if (useSpecifiedCodePage) + isUtf8 = (codePage == CP_UTF8); + #ifdef _WIN32 + else if (GetHostOS() == NFileHeader::NHostOS::kUnix) + { + /* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header. + We try to get name as UTF-8. + Do we need to do it in POSIX version also? */ + isUtf8 = true; + + /* 21.02: we want to ignore UTF-8 errors to support file paths that are mixed + of UTF-8 and non-UTF-8 characters. */ + // ignore_Utf8_Errors = false; + // ignore_Utf8_Errors = true; + } + #endif + } + + + if (isUtf8) + { + ConvertUTF8ToUnicode(s, res); + return; + } + + MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage()); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipItem.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipItem.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,310 +1,356 @@ -// Archive/ZipItem.h - -#ifndef __ARCHIVE_ZIP_ITEM_H -#define __ARCHIVE_ZIP_ITEM_H - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyString.h" -#include "../../../Common/UTFConvert.h" - -#include "ZipHeader.h" - -namespace NArchive { -namespace NZip { - -struct CVersion -{ - Byte Version; - Byte HostOS; -}; - -struct CExtraSubBlock -{ - UInt16 ID; - CByteBuffer Data; - - bool ExtractNtfsTime(unsigned index, FILETIME &ft) const; - bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const; - - bool ExtractIzUnicode(UInt32 crc, AString &name) const - { - unsigned size = (unsigned)Data.Size(); - if (size < 1 + 4) - return false; - const Byte *p = (const Byte *)Data; - if (p[0] > 1) - return false; - if (crc != GetUi32(p + 1)) - return false; - size -= 5; - name.SetFrom_CalcLen((const char *)p + 5, size); - if (size != name.Len()) - return false; - return CheckUTF8(name, false); - } -}; - -const unsigned k_WzAesExtra_Size = 7; - -struct CWzAesExtra -{ - UInt16 VendorVersion; // 1: AE-1, 2: AE-2, - // UInt16 VendorId; // 'A' 'E' - Byte Strength; // 1: 128-bit, 2: 192-bit, 3: 256-bit - UInt16 Method; - - CWzAesExtra(): VendorVersion(2), Strength(3), Method(0) {} - - bool NeedCrc() const { return (VendorVersion == 1); } - - bool ParseFromSubBlock(const CExtraSubBlock &sb) - { - if (sb.ID != NFileHeader::NExtraID::kWzAES) - return false; - if (sb.Data.Size() < k_WzAesExtra_Size) - return false; - const Byte *p = (const Byte *)sb.Data; - VendorVersion = GetUi16(p); - if (p[2] != 'A' || p[3] != 'E') - return false; - Strength = p[4]; - // 9.31: The BUG was fixed: - Method = GetUi16(p + 5); - return true; - } - - void SetSubBlock(CExtraSubBlock &sb) const - { - sb.Data.Alloc(k_WzAesExtra_Size); - sb.ID = NFileHeader::NExtraID::kWzAES; - Byte *p = (Byte *)sb.Data; - p[0] = (Byte)VendorVersion; - p[1] = (Byte)(VendorVersion >> 8); - p[2] = 'A'; - p[3] = 'E'; - p[4] = Strength; - p[5] = (Byte)Method; - p[6] = (Byte)(Method >> 8); - } -}; - -namespace NStrongCrypto_AlgId -{ - const UInt16 kDES = 0x6601; - const UInt16 kRC2old = 0x6602; - const UInt16 k3DES168 = 0x6603; - const UInt16 k3DES112 = 0x6609; - const UInt16 kAES128 = 0x660E; - const UInt16 kAES192 = 0x660F; - const UInt16 kAES256 = 0x6610; - const UInt16 kRC2 = 0x6702; - const UInt16 kBlowfish = 0x6720; - const UInt16 kTwofish = 0x6721; - const UInt16 kRC4 = 0x6801; -} - -struct CStrongCryptoExtra -{ - UInt16 Format; - UInt16 AlgId; - UInt16 BitLen; - UInt16 Flags; - - bool ParseFromSubBlock(const CExtraSubBlock &sb) - { - if (sb.ID != NFileHeader::NExtraID::kStrongEncrypt) - return false; - const Byte *p = (const Byte *)sb.Data; - if (sb.Data.Size() < 8) - return false; - Format = GetUi16(p + 0); - AlgId = GetUi16(p + 2); - BitLen = GetUi16(p + 4); - Flags = GetUi16(p + 6); - return (Format == 2); - } - - bool CertificateIsUsed() const { return (Flags > 0x0001); } -}; - -struct CExtraBlock -{ - CObjectVector SubBlocks; - - void Clear() { SubBlocks.Clear(); } - - size_t GetSize() const - { - size_t res = 0; - FOR_VECTOR (i, SubBlocks) - res += SubBlocks[i].Data.Size() + 2 + 2; - return res; - } - - bool GetWzAes(CWzAesExtra &e) const - { - FOR_VECTOR (i, SubBlocks) - if (e.ParseFromSubBlock(SubBlocks[i])) - return true; - return false; - } - - bool HasWzAes() const - { - CWzAesExtra e; - return GetWzAes(e); - } - - bool GetStrongCrypto(CStrongCryptoExtra &e) const - { - FOR_VECTOR (i, SubBlocks) - if (e.ParseFromSubBlock(SubBlocks[i])) - return true; - return false; - } - - /* - bool HasStrongCrypto() const - { - CStrongCryptoExtra e; - return GetStrongCrypto(e); - } - */ - - bool GetNtfsTime(unsigned index, FILETIME &ft) const; - bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const; - - void RemoveUnknownSubBlocks() - { - for (unsigned i = SubBlocks.Size(); i != 0;) - { - i--; - if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES) - SubBlocks.Delete(i); - } - } -}; - - -class CLocalItem -{ -public: - UInt16 Flags; - UInt16 Method; - CVersion ExtractVersion; - - UInt64 Size; - UInt64 PackSize; - UInt32 Time; - UInt32 Crc; - - UInt32 Disk; - - AString Name; - - CExtraBlock LocalExtra; - - bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; } - bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } - bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; } - bool IsAesEncrypted() const { return IsEncrypted() && (IsStrongEncrypted() || Method == NFileHeader::NCompressionMethod::kWzAES); } - bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; } - bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } - - bool IsDir() const; - - /* - void GetUnicodeString(const AString &s, UString &res) const - { - bool isUtf8 = IsUtf8(); - if (isUtf8) - if (ConvertUTF8ToUnicode(s, res)) - return; - MultiByteToUnicodeString2(res, s, GetCodePage()); - } - */ - -private: - - void SetFlag(unsigned bitMask, bool enable) - { - if (enable) - Flags |= bitMask; - else - Flags &= ~bitMask; - } - -public: - - void ClearFlags() { Flags = 0; } - void SetEncrypted(bool encrypted) { SetFlag(NFileHeader::NFlags::kEncrypted, encrypted); } - void SetUtf8(bool isUtf8) { SetFlag(NFileHeader::NFlags::kUtf8, isUtf8); } - void SetDescriptorMode(bool useDescriptor) { SetFlag(NFileHeader::NFlags::kDescriptorUsedMask, useDescriptor); } - - UINT GetCodePage() const { return CP_OEMCP; } -}; - - -class CItem: public CLocalItem -{ -public: - CVersion MadeByVersion; - UInt16 InternalAttrib; - UInt32 ExternalAttrib; - - UInt64 LocalHeaderPos; - - CExtraBlock CentralExtra; - CByteBuffer Comment; - - bool FromLocal; - bool FromCentral; - - // CItem can be used as CLocalItem. So we must clear unused fields - CItem(): - InternalAttrib(0), - ExternalAttrib(0), - FromLocal(false), - FromCentral(false) - { - MadeByVersion.Version = 0; - MadeByVersion.HostOS = 0; - } - - const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); } - - bool IsDir() const; - UInt32 GetWinAttrib() const; - bool GetPosixAttrib(UInt32 &attrib) const; - - Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; } - - void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const; - - bool IsThereCrc() const - { - if (Method == NFileHeader::NCompressionMethod::kWzAES) - { - CWzAesExtra aesField; - if (GetMainExtra().GetWzAes(aesField)) - return aesField.NeedCrc(); - } - return (Crc != 0 || !IsDir()); - } - - UINT GetCodePage() const - { - Byte hostOS = GetHostOS(); - return (UINT)(( - hostOS == NFileHeader::NHostOS::kFAT - || hostOS == NFileHeader::NHostOS::kNTFS - || hostOS == NFileHeader::NHostOS::kUnix // do we need it? - ) ? CP_OEMCP : CP_ACP); - } -}; - -}} - -#endif +// Archive/ZipItem.h + +#ifndef ZIP7_INC_ARCHIVE_ZIP_ITEM_H +#define ZIP7_INC_ARCHIVE_ZIP_ITEM_H + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyString.h" +#include "../../../Common/UTFConvert.h" + +#include "ZipHeader.h" + +namespace NArchive { +namespace NZip { + +/* +extern const char *k_SpecName_NTFS_STREAM; +extern const char *k_SpecName_MAC_RESOURCE_FORK; +*/ + +struct CVersion +{ + Byte Version; + Byte HostOS; +}; + +struct CExtraSubBlock +{ + UInt32 ID; + CByteBuffer Data; + + bool ExtractNtfsTime(unsigned index, FILETIME &ft) 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; + + void PrintInfo(AString &s) const; +}; + +const unsigned k_WzAesExtra_Size = 7; + +struct CWzAesExtra +{ + UInt16 VendorVersion; // 1: AE-1, 2: AE-2, + // UInt16 VendorId; // 'A' 'E' + Byte Strength; // 1: 128-bit, 2: 192-bit, 3: 256-bit + UInt16 Method; + + CWzAesExtra(): VendorVersion(2), Strength(3), Method(0) {} + + bool NeedCrc() const { return (VendorVersion == 1); } + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kWzAES) + return false; + if (sb.Data.Size() < k_WzAesExtra_Size) + return false; + const Byte *p = (const Byte *)sb.Data; + VendorVersion = GetUi16(p); + if (p[2] != 'A' || p[3] != 'E') + return false; + Strength = p[4]; + // 9.31: The BUG was fixed: + Method = GetUi16(p + 5); + return true; + } + + void SetSubBlock(CExtraSubBlock &sb) const + { + sb.Data.Alloc(k_WzAesExtra_Size); + sb.ID = NFileHeader::NExtraID::kWzAES; + Byte *p = (Byte *)sb.Data; + p[0] = (Byte)VendorVersion; + p[1] = (Byte)(VendorVersion >> 8); + p[2] = 'A'; + p[3] = 'E'; + p[4] = Strength; + p[5] = (Byte)Method; + p[6] = (Byte)(Method >> 8); + } +}; + +namespace NStrongCrypto_AlgId +{ + const UInt16 kDES = 0x6601; + const UInt16 kRC2old = 0x6602; + const UInt16 k3DES168 = 0x6603; + const UInt16 k3DES112 = 0x6609; + const UInt16 kAES128 = 0x660E; + const UInt16 kAES192 = 0x660F; + const UInt16 kAES256 = 0x6610; + const UInt16 kRC2 = 0x6702; + const UInt16 kBlowfish = 0x6720; + const UInt16 kTwofish = 0x6721; + const UInt16 kRC4 = 0x6801; +} + +struct CStrongCryptoExtra +{ + UInt16 Format; + UInt16 AlgId; + UInt16 BitLen; + UInt16 Flags; + + bool ParseFromSubBlock(const CExtraSubBlock &sb) + { + if (sb.ID != NFileHeader::NExtraID::kStrongEncrypt) + return false; + const Byte *p = (const Byte *)sb.Data; + if (sb.Data.Size() < 8) + return false; + Format = GetUi16(p + 0); + AlgId = GetUi16(p + 2); + BitLen = GetUi16(p + 4); + Flags = GetUi16(p + 6); + return (Format == 2); + } + + bool CertificateIsUsed() const { return (Flags > 0x0001); } +}; + + +struct CExtraBlock +{ + CObjectVector SubBlocks; + bool Error; + bool MinorError; + bool IsZip64; + bool IsZip64_Error; + + CExtraBlock(): Error(false), MinorError(false), IsZip64(false), IsZip64_Error(false) {} + + void Clear() + { + SubBlocks.Clear(); + IsZip64 = false; + } + + size_t GetSize() const + { + size_t res = 0; + FOR_VECTOR (i, SubBlocks) + res += SubBlocks[i].Data.Size() + 2 + 2; + return res; + } + + bool GetWzAes(CWzAesExtra &e) const + { + FOR_VECTOR (i, SubBlocks) + if (e.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + + bool HasWzAes() const + { + CWzAesExtra e; + return GetWzAes(e); + } + + bool GetStrongCrypto(CStrongCryptoExtra &e) const + { + FOR_VECTOR (i, SubBlocks) + if (e.ParseFromSubBlock(SubBlocks[i])) + return true; + return false; + } + + /* + bool HasStrongCrypto() const + { + CStrongCryptoExtra e; + return GetStrongCrypto(e); + } + */ + + bool GetNtfsTime(unsigned index, FILETIME &ft) const; + bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const; + + void PrintInfo(AString &s) const; + + void RemoveUnknownSubBlocks() + { + for (unsigned i = SubBlocks.Size(); i != 0;) + { + i--; + switch (SubBlocks[i].ID) + { + case NFileHeader::NExtraID::kStrongEncrypt: + case NFileHeader::NExtraID::kWzAES: + break; + default: + SubBlocks.Delete(i); + } + } + } +}; + + +class CLocalItem +{ +public: + UInt16 Flags; + UInt16 Method; + + /* + Zip specification doesn't mention that ExtractVersion field uses HostOS subfield. + 18.06: 7-Zip now doesn't use ExtractVersion::HostOS to detect codePage + */ + + CVersion ExtractVersion; + + UInt64 Size; + UInt64 PackSize; + UInt32 Time; + UInt32 Crc; + + UInt32 Disk; + + AString Name; + + CExtraBlock LocalExtra; + + unsigned GetDescriptorSize() const { return LocalExtra.IsZip64 ? kDataDescriptorSize64 : kDataDescriptorSize32; } + + UInt64 GetPackSizeWithDescriptor() const + { return PackSize + (HasDescriptor() ? GetDescriptorSize() : 0); } + + bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; } + bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; } + bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; } + bool IsAesEncrypted() const { return IsEncrypted() && (IsStrongEncrypted() || Method == NFileHeader::NCompressionMethod::kWzAES); } + bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; } + bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; } + // bool IsAltStream() const { return (Flags & NFileHeader::NFlags::kAltStream) != 0; } + + unsigned GetDeflateLevel() const { return (Flags >> 1) & 3; } + + bool IsDir() const; + + /* + void GetUnicodeString(const AString &s, UString &res) const + { + bool isUtf8 = IsUtf8(); + if (isUtf8) + if (ConvertUTF8ToUnicode(s, res)) + return; + MultiByteToUnicodeString2(res, s, GetCodePage()); + } + */ + +private: + + void SetFlag(unsigned bitMask, bool enable) + { + if (enable) + Flags = (UInt16)(Flags | bitMask); + else + Flags = (UInt16)(Flags & ~bitMask); + } + +public: + + void ClearFlags() { Flags = 0; } + void SetEncrypted(bool encrypted) { SetFlag(NFileHeader::NFlags::kEncrypted, encrypted); } + void SetUtf8(bool isUtf8) { SetFlag(NFileHeader::NFlags::kUtf8, isUtf8); } + // void SetFlag_AltStream(bool isAltStream) { SetFlag(NFileHeader::NFlags::kAltStream, isAltStream); } + void SetDescriptorMode(bool useDescriptor) { SetFlag(NFileHeader::NFlags::kDescriptorUsedMask, useDescriptor); } + + UINT GetCodePage() const + { + if (IsUtf8()) + return CP_UTF8; + return CP_OEMCP; + } +}; + + +class CItem: public CLocalItem +{ +public: + CVersion MadeByVersion; + UInt16 InternalAttrib; + UInt32 ExternalAttrib; + + UInt64 LocalHeaderPos; + + CExtraBlock CentralExtra; + CByteBuffer Comment; + + bool FromLocal; + bool FromCentral; + + // CItem can be used as CLocalItem. So we must clear unused fields + CItem(): + InternalAttrib(0), + ExternalAttrib(0), + FromLocal(false), + FromCentral(false) + { + MadeByVersion.Version = 0; + MadeByVersion.HostOS = 0; + } + + const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); } + + bool IsDir() const; + UInt32 GetWinAttrib() const; + bool GetPosixAttrib(UInt32 &attrib) const; + + // 18.06: 0 instead of ExtractVersion.HostOS for local item + Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : (Byte)0; } + + void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const; + + bool IsThereCrc() const + { + if (Method == NFileHeader::NCompressionMethod::kWzAES) + { + CWzAesExtra aesField; + if (GetMainExtra().GetWzAes(aesField)) + return aesField.NeedCrc(); + } + return (Crc != 0 || !IsDir()); + } + + bool Is_MadeBy_Unix() const + { + if (!FromCentral) + return false; + return (MadeByVersion.HostOS == NFileHeader::NHostOS::kUnix); + } + + UINT GetCodePage() const + { + // 18.06: now we use HostOS only from Central::MadeByVersion + if (IsUtf8()) + return CP_UTF8; + if (!FromCentral) + return CP_OEMCP; + Byte hostOS = MadeByVersion.HostOS; + return (UINT)(( + hostOS == NFileHeader::NHostOS::kFAT + || hostOS == NFileHeader::NHostOS::kNTFS + || hostOS == NFileHeader::NHostOS::kUnix // do we need it? + ) ? CP_OEMCP : CP_ACP); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipOut.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.cpp 2023-03-26 11:00:00.000000000 +0000 @@ -1,312 +1,420 @@ -// ZipOut.cpp - -#include "StdAfx.h" - -#include "../../Common/OffsetStream.h" - -#include "ZipOut.h" - -namespace NArchive { -namespace NZip { - -HRESULT COutArchive::Create(IOutStream *outStream) -{ - m_CurPos = 0; - if (!m_OutBuffer.Create(1 << 16)) - return E_OUTOFMEMORY; - m_Stream = outStream; - m_OutBuffer.SetStream(outStream); - m_OutBuffer.Init(); - - return m_Stream->Seek(0, STREAM_SEEK_CUR, &m_Base); -} - -void COutArchive::MoveCurPos(UInt64 distanceToMove) -{ - m_CurPos += distanceToMove; // test overflow -} - -void COutArchive::SeekToRelatPos(UInt64 offset) -{ - HRESULT res = m_Stream->Seek(m_Base + offset, STREAM_SEEK_SET, NULL); - if (res != S_OK) - throw CSystemException(res); -} - -void COutArchive::PrepareWriteCompressedDataZip64(unsigned fileNameLen, bool isZip64, bool aesEncryption) -{ - m_IsZip64 = isZip64; - m_ExtraSize = isZip64 ? (4 + 8 + 8) : 0; - if (aesEncryption) - m_ExtraSize += 4 + k_WzAesExtra_Size; - m_LocalFileHeaderSize = kLocalHeaderSize + fileNameLen + m_ExtraSize; -} - -void COutArchive::PrepareWriteCompressedData(unsigned fileNameLen, UInt64 unPackSize, bool aesEncryption) -{ - // We use Zip64, if unPackSize size is larger than 0xF8000000 to support - // cases when compressed size can be about 3% larger than uncompressed size - - PrepareWriteCompressedDataZip64(fileNameLen, unPackSize >= (UInt32)0xF8000000, aesEncryption); -} - -#define DOES_NEED_ZIP64(v) (v >= (UInt32)0xFFFFFFFF) - -void COutArchive::PrepareWriteCompressedData2(unsigned fileNameLen, UInt64 unPackSize, UInt64 packSize, bool aesEncryption) -{ - bool isZip64 = - DOES_NEED_ZIP64(unPackSize) || - DOES_NEED_ZIP64(packSize); - PrepareWriteCompressedDataZip64(fileNameLen, isZip64, aesEncryption); -} - -void COutArchive::WriteBytes(const void *buffer, UInt32 size) -{ - m_OutBuffer.WriteBytes(buffer, size); - m_CurPos += size; -} - -void COutArchive::Write8(Byte b) -{ - m_OutBuffer.WriteByte(b); - m_CurPos++; -} - -void COutArchive::Write16(UInt16 val) -{ - for (int i = 0; i < 2; i++) - { - Write8((Byte)val); - val >>= 8; - } -} - -void COutArchive::Write32(UInt32 val) -{ - for (int i = 0; i < 4; i++) - { - Write8((Byte)val); - val >>= 8; - } -} - -void COutArchive::Write64(UInt64 val) -{ - for (int i = 0; i < 8; i++) - { - Write8((Byte)val); - val >>= 8; - } -} - -void COutArchive::WriteExtra(const CExtraBlock &extra) -{ - if (extra.SubBlocks.Size() != 0) - { - FOR_VECTOR (i, extra.SubBlocks) - { - const CExtraSubBlock &subBlock = extra.SubBlocks[i]; - Write16(subBlock.ID); - Write16((UInt16)subBlock.Data.Size()); - WriteBytes(subBlock.Data, (UInt32)subBlock.Data.Size()); - } - } -} - -void COutArchive::WriteCommonItemInfo(const CLocalItem &item, bool isZip64) -{ - { - Byte ver = item.ExtractVersion.Version; - if (isZip64 && ver < NFileHeader::NCompressionMethod::kExtractVersion_Zip64) - ver = NFileHeader::NCompressionMethod::kExtractVersion_Zip64; - Write8(ver); - } - Write8(item.ExtractVersion.HostOS); - Write16(item.Flags); - Write16(item.Method); - Write32(item.Time); - Write32(item.Crc); -} - -#define WRITE_32_VAL_SPEC(__v, __isZip64) Write32((__isZip64) ? 0xFFFFFFFF : (UInt32)(__v)); - -void COutArchive::WriteLocalHeader(const CLocalItem &item) -{ - SeekToCurPos(); - - bool isZip64 = m_IsZip64 || - DOES_NEED_ZIP64(item.PackSize) || - DOES_NEED_ZIP64(item.Size); - - Write32(NSignature::kLocalFileHeader); - WriteCommonItemInfo(item, isZip64); - - WRITE_32_VAL_SPEC(item.PackSize, isZip64); - WRITE_32_VAL_SPEC(item.Size, isZip64); - - Write16((UInt16)item.Name.Len()); - { - UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 8 + 8): 0) + item.LocalExtra.GetSize()); - if (localExtraSize != m_ExtraSize) - throw CSystemException(E_FAIL); - } - Write16((UInt16)m_ExtraSize); - WriteBytes((const char *)item.Name, item.Name.Len()); - - if (isZip64) - { - Write16(NFileHeader::NExtraID::kZip64); - Write16(8 + 8); - Write64(item.Size); - Write64(item.PackSize); - } - - WriteExtra(item.LocalExtra); - - // Why don't we write NTFS timestamps to local header? - // Probably we want to reduce size of archive? - - m_OutBuffer.FlushWithCheck(); - MoveCurPos(item.PackSize); -} - -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; - - Write32(NSignature::kCentralFileHeader); - Write8(item.MadeByVersion.Version); - Write8(item.MadeByVersion.HostOS); - - WriteCommonItemInfo(item, isZip64); - - WRITE_32_VAL_SPEC(item.PackSize, isPack64); - WRITE_32_VAL_SPEC(item.Size, isUnPack64); - - Write16((UInt16)item.Name.Len()); - - UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); - const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8); - const UInt16 centralExtraSize = (UInt16)( - (isZip64 ? 4 + zip64ExtraSize : 0) + - (item.NtfsTimeIsDefined ? 4 + kNtfsExtraSize : 0) + - item.CentralExtra.GetSize()); - - Write16(centralExtraSize); // test it; - Write16((UInt16)item.Comment.Size()); - Write16(0); // DiskNumberStart; - Write16(item.InternalAttrib); - Write32(item.ExternalAttrib); - WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64); - WriteBytes((const char *)item.Name, item.Name.Len()); - - if (isZip64) - { - Write16(NFileHeader::NExtraID::kZip64); - Write16(zip64ExtraSize); - if (isUnPack64) - Write64(item.Size); - if (isPack64) - Write64(item.PackSize); - if (isPosition64) - 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); - } - - WriteExtra(item.CentralExtra); - if (item.Comment.Size() > 0) - WriteBytes(item.Comment, (UInt32)item.Comment.Size()); -} - -void COutArchive::WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment) -{ - SeekToCurPos(); - - 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); - - // isZip64 = true; // to test Zip64 - - if (isZip64) - { - Write32(NSignature::kEcd64); - Write64(kEcd64_MainSize); - Write16(45); // made by version - Write16(45); // extract version - Write32(0); // ThisDiskNumber = 0; - Write32(0); // StartCentralDirectoryDiskNumber;; - Write64((UInt64)items.Size()); - Write64((UInt64)items.Size()); - Write64((UInt64)cdSize); - Write64((UInt64)cdOffset); - - Write32(NSignature::kEcd64Locator); - Write32(0); // number of the disk with the start of the zip64 end of central directory - Write64(cd64EndOffset); - Write32(1); // total number of disks - } - - Write32(NSignature::kEcd); - Write16(0); // ThisDiskNumber = 0; - Write16(0); // StartCentralDirectoryDiskNumber; - Write16((UInt16)(items64 ? 0xFFFF: items.Size())); - Write16((UInt16)(items64 ? 0xFFFF: items.Size())); - - WRITE_32_VAL_SPEC(cdSize, cdSize64); - WRITE_32_VAL_SPEC(cdOffset, cdOffset64); - - UInt32 commentSize = (UInt32)(comment ? comment->Size() : 0); - Write16((UInt16)commentSize); - if (commentSize > 0) - WriteBytes((const Byte *)*comment, commentSize); - m_OutBuffer.FlushWithCheck(); -} - -void COutArchive::CreateStreamForCompressing(IOutStream **outStream) -{ - COffsetOutStream *streamSpec = new COffsetOutStream; - CMyComPtr tempStream(streamSpec); - streamSpec->Init(m_Stream, m_Base + m_CurPos + m_LocalFileHeaderSize); - *outStream = tempStream.Detach(); -} - -/* -void COutArchive::SeekToPackedDataPosition() -{ - SeekTo(m_BasePosition + m_LocalFileHeaderSize); -} -*/ - -void COutArchive::SeekToCurPos() -{ - SeekToRelatPos(m_CurPos); -} - -void COutArchive::CreateStreamForCopying(ISequentialOutStream **outStream) -{ - CMyComPtr tempStream(m_Stream); - *outStream = tempStream.Detach(); -} - -}} +// ZipOut.cpp + +#include "StdAfx.h" + +#include "../../../../C/7zCrc.h" + +#include "../../../Windows/TimeUtils.h" +#include "../../Common/OffsetStream.h" + +#include "ZipOut.h" + +namespace NArchive { +namespace NZip { + +HRESULT COutArchive::ClearRestriction() +{ + if (SetRestriction) + return SetRestriction->SetRestriction(0, 0); + return S_OK; +} + +HRESULT COutArchive::SetRestrictionFromCurrent() +{ + if (SetRestriction) + return SetRestriction->SetRestriction(m_Base + m_CurPos, (UInt64)(Int64)-1); + return S_OK; +} + +HRESULT COutArchive::Create(IOutStream *outStream) +{ + m_CurPos = 0; + if (!m_OutBuffer.Create(1 << 16)) + return E_OUTOFMEMORY; + m_Stream = outStream; + m_OutBuffer.SetStream(outStream); + m_OutBuffer.Init(); + + return m_Stream->Seek(0, STREAM_SEEK_CUR, &m_Base); +} + +void COutArchive::SeekToCurPos() +{ + HRESULT res = m_Stream->Seek((Int64)(m_Base + m_CurPos), STREAM_SEEK_SET, NULL); + if (res != S_OK) + throw CSystemException(res); +} + +#define DOES_NEED_ZIP64(v) (v >= (UInt32)0xFFFFFFFF) +// #define DOES_NEED_ZIP64(v) (v >= 0) + + +void COutArchive::WriteBytes(const void *data, size_t size) +{ + m_OutBuffer.WriteBytes(data, size); + m_CurPos += size; +} + +void COutArchive::Write8(Byte b) +{ + m_OutBuffer.WriteByte(b); + m_CurPos++; +} + +void COutArchive::Write16(UInt16 val) +{ + Write8((Byte)val); + Write8((Byte)(val >> 8)); +} + +void COutArchive::Write32(UInt32 val) +{ + for (int i = 0; i < 4; i++) + { + Write8((Byte)val); + val >>= 8; + } +} + +void COutArchive::Write64(UInt64 val) +{ + for (int i = 0; i < 8; i++) + { + Write8((Byte)val); + val >>= 8; + } +} + +void COutArchive::WriteExtra(const CExtraBlock &extra) +{ + FOR_VECTOR (i, extra.SubBlocks) + { + const CExtraSubBlock &subBlock = extra.SubBlocks[i]; + Write16((UInt16)subBlock.ID); + Write16((UInt16)subBlock.Data.Size()); + WriteBytes(subBlock.Data, (UInt16)subBlock.Data.Size()); + } +} + +void COutArchive::WriteCommonItemInfo(const CLocalItem &item, bool isZip64) +{ + { + Byte ver = item.ExtractVersion.Version; + if (isZip64 && ver < NFileHeader::NCompressionMethod::kExtractVersion_Zip64) + ver = NFileHeader::NCompressionMethod::kExtractVersion_Zip64; + Write8(ver); + } + Write8(item.ExtractVersion.HostOS); + Write16(item.Flags); + Write16(item.Method); + Write32(item.Time); +} + + +#define WRITE_32_VAL_SPEC(_v_, _isZip64_) Write32((_isZip64_) ? 0xFFFFFFFF : (UInt32)(_v_)); + + +void COutArchive::WriteUtfName(const CItemOut &item) +{ + if (item.Name_Utf.Size() == 0) + return; + Write16(NFileHeader::NExtraID::kIzUnicodeName); + Write16((UInt16)(5 + item.Name_Utf.Size())); + Write8(1); // (1 = version) of that extra field + Write32(CrcCalc(item.Name.Ptr(), item.Name.Len())); + 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; + item.LocalHeaderPos = m_CurPos; + + bool isZip64 = + DOES_NEED_ZIP64(item.PackSize) || + DOES_NEED_ZIP64(item.Size); + + 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) + throw CSystemException(E_FAIL); + if (needCheck && m_ExtraSize != localExtraSize) + throw CSystemException(E_FAIL); + + m_IsZip64 = isZip64; + m_ExtraSize = localExtraSize; + + item.LocalExtra.IsZip64 = isZip64; + + Write32(NSignature::kLocalFileHeader); + + WriteCommonItemInfo(item, isZip64); + + Write32(item.HasDescriptor() ? 0 : item.Crc); + + UInt64 packSize = item.PackSize; + UInt64 size = item.Size; + + if (item.HasDescriptor()) + { + packSize = 0; + size = 0; + } + + WRITE_32_VAL_SPEC(packSize, isZip64) + WRITE_32_VAL_SPEC(size, isZip64) + + Write16((UInt16)item.Name.Len()); + + Write16((UInt16)localExtraSize); + + WriteBytes((const char *)item.Name, (UInt16)item.Name.Len()); + + if (isZip64) + { + Write16(NFileHeader::NExtraID::kZip64); + Write16(8 + 8); + Write64(size); + Write64(packSize); + } + + WriteTimeExtra(item, writeNtfs); + + WriteUtfName(item); + + WriteExtra(item.LocalExtra); + + const UInt32 localFileHeaderSize = (UInt32)(m_CurPos - m_LocalHeaderPos); + if (needCheck && m_LocalFileHeaderSize != localFileHeaderSize) + throw CSystemException(E_FAIL); + m_LocalFileHeaderSize = localFileHeaderSize; + + m_OutBuffer.FlushWithCheck(); +} + + +void COutArchive::WriteLocalHeader_Replace(CItemOut &item) +{ + m_CurPos = m_LocalHeaderPos + m_LocalFileHeaderSize + item.PackSize; + + if (item.HasDescriptor()) + { + WriteDescriptor(item); + m_OutBuffer.FlushWithCheck(); + return; + // we don't replace local header, if we write Descriptor. + // so local header with Descriptor flag must be written to local header before. + } + + const UInt64 nextPos = m_CurPos; + m_CurPos = m_LocalHeaderPos; + SeekToCurPos(); + WriteLocalHeader(item, true); + m_CurPos = nextPos; + SeekToCurPos(); +} + + +void COutArchive::WriteDescriptor(const CItemOut &item) +{ + Byte buf[kDataDescriptorSize64]; + SetUi32(buf, NSignature::kDataDescriptor) + SetUi32(buf + 4, item.Crc) + unsigned descriptorSize; + if (m_IsZip64) + { + SetUi64(buf + 8, item.PackSize) + SetUi64(buf + 16, item.Size) + descriptorSize = kDataDescriptorSize64; + } + else + { + SetUi32(buf + 8, (UInt32)item.PackSize) + SetUi32(buf + 12, (UInt32)item.Size) + descriptorSize = kDataDescriptorSize32; + } + WriteBytes(buf, descriptorSize); +} + + + +void COutArchive::WriteCentralHeader(const CItemOut &item) +{ + 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); + Write8(item.MadeByVersion.HostOS); + + WriteCommonItemInfo(item, isZip64); + Write32(item.Crc); + + WRITE_32_VAL_SPEC(item.PackSize, isPack64) + WRITE_32_VAL_SPEC(item.Size, isUnPack64) + + Write16((UInt16)item.Name.Len()); + + const UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); + const bool writeNtfs = item.Write_NtfsTime; + const size_t centralExtraSize = + (isZip64 ? 4 + zip64ExtraSize : 0) + + (writeNtfs ? 4 + k_Ntfs_ExtraSize : 0) + + (item.Write_UnixTime ? 4 + k_UnixTime_ExtraSize : 0) + + item.Get_UtfName_ExtraSize() + + item.CentralExtra.GetSize(); + + const UInt16 centralExtraSize16 = (UInt16)centralExtraSize; + if (centralExtraSize16 != centralExtraSize) + throw CSystemException(E_FAIL); + + Write16(centralExtraSize16); + + const UInt16 commentSize = (UInt16)item.Comment.Size(); + + Write16(commentSize); + Write16(0); // DiskNumberStart + Write16(item.InternalAttrib); + Write32(item.ExternalAttrib); + WRITE_32_VAL_SPEC(item.LocalHeaderPos, isPosition64) + WriteBytes((const char *)item.Name, item.Name.Len()); + + if (isZip64) + { + Write16(NFileHeader::NExtraID::kZip64); + Write16(zip64ExtraSize); + if (isUnPack64) + Write64(item.Size); + if (isPack64) + Write64(item.PackSize); + if (isPosition64) + Write64(item.LocalHeaderPos); + } + + WriteTimeExtra(item, writeNtfs); + WriteUtfName(item); + + WriteExtra(item.CentralExtra); + if (commentSize != 0) + WriteBytes(item.Comment, commentSize); +} + +HRESULT COutArchive::WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment) +{ + RINOK(ClearRestriction()) + + const UInt64 cdOffset = GetCurPos(); + FOR_VECTOR (i, items) + WriteCentralHeader(items[i]); + 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 + + if (isZip64) + { + Write32(NSignature::kEcd64); + Write64(kEcd64_MainSize); + + // to test extra block: + // const UInt32 extraSize = 1 << 26; + // Write64(kEcd64_MainSize + extraSize); + + Write16(45); // made by version + Write16(45); // extract version + Write32(0); // ThisDiskNumber + Write32(0); // StartCentralDirectoryDiskNumber + Write64((UInt64)items.Size()); + Write64((UInt64)items.Size()); + Write64((UInt64)cdSize); + Write64((UInt64)cdOffset); + + // for (UInt32 iii = 0; iii < extraSize; iii++) Write8(1); + + Write32(NSignature::kEcd64Locator); + Write32(0); // number of the disk with the start of the zip64 end of central directory + Write64(cd64EndOffset); + Write32(1); // total number of disks + } + + Write32(NSignature::kEcd); + Write16(0); // ThisDiskNumber + Write16(0); // StartCentralDirectoryDiskNumber + Write16((UInt16)(items64 ? 0xFFFF: items.Size())); + Write16((UInt16)(items64 ? 0xFFFF: items.Size())); + + WRITE_32_VAL_SPEC(cdSize, cdSize64) + WRITE_32_VAL_SPEC(cdOffset, cdOffset64) + + const UInt16 commentSize = (UInt16)(comment ? comment->Size() : 0); + Write16((UInt16)commentSize); + if (commentSize != 0) + WriteBytes((const Byte *)*comment, commentSize); + m_OutBuffer.FlushWithCheck(); + return S_OK; +} + +void COutArchive::CreateStreamForCompressing(CMyComPtr &outStream) +{ + COffsetOutStream *streamSpec = new COffsetOutStream; + outStream = streamSpec; + streamSpec->Init(m_Stream, m_Base + m_CurPos); +} + +void COutArchive::CreateStreamForCopying(CMyComPtr &outStream) +{ + outStream = m_Stream; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipOut.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipOut.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipOut.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,88 +1,103 @@ -// ZipOut.h - -#ifndef __ZIP_OUT_H -#define __ZIP_OUT_H - -#include "../../../Common/MyCom.h" - -#include "../../IStream.h" -#include "../../Common/OutBuffer.h" - -#include "ZipItem.h" - -namespace NArchive { -namespace NZip { - -// can throw CSystemException and COutBufferException - -class CItemOut: public CItem -{ -public: - FILETIME Ntfs_MTime; - FILETIME Ntfs_ATime; - FILETIME Ntfs_CTime; - bool NtfsTimeIsDefined; - - // It's possible that NtfsTime is not defined, but there is NtfsTime in Extra. - - CItemOut(): NtfsTimeIsDefined(false) {} -}; - -class COutArchive -{ - CMyComPtr m_Stream; - COutBuffer m_OutBuffer; - - UInt64 m_Base; // Base of arc (offset in output Stream) - UInt64 m_CurPos; // Curent position in archive (relative from m_Base) - - UInt32 m_LocalFileHeaderSize; - UInt32 m_ExtraSize; - bool m_IsZip64; - - void SeekToRelatPos(UInt64 offset); - - void WriteBytes(const void *buffer, UInt32 size); - void Write8(Byte b); - void Write16(UInt16 val); - void Write32(UInt32 val); - void Write64(UInt64 val); - void WriteNtfsTime(const FILETIME &ft) - { - Write32(ft.dwLowDateTime); - Write32(ft.dwHighDateTime); - } - - void WriteExtra(const CExtraBlock &extra); - void WriteCommonItemInfo(const CLocalItem &item, bool isZip64); - void WriteCentralHeader(const CItemOut &item); - - void PrepareWriteCompressedDataZip64(unsigned fileNameLen, bool isZip64, bool aesEncryption); - -public: - HRESULT Create(IOutStream *outStream); - - void MoveCurPos(UInt64 distanceToMove); - UInt64 GetCurPos() const { return m_CurPos; } - - void SeekToCurPos(); - - void PrepareWriteCompressedData(unsigned fileNameLen, UInt64 unPackSize, bool aesEncryption); - void PrepareWriteCompressedData2(unsigned fileNameLen, UInt64 unPackSize, UInt64 packSize, bool aesEncryption); - void WriteLocalHeader(const CLocalItem &item); - - void WriteLocalHeader_And_SeekToNextFile(const CLocalItem &item) - { - WriteLocalHeader(item); - SeekToCurPos(); - } - - void WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment); - - void CreateStreamForCompressing(IOutStream **outStream); - void CreateStreamForCopying(ISequentialOutStream **outStream); -}; - -}} - -#endif +// ZipOut.h + +#ifndef ZIP7_INC_ZIP_OUT_H +#define ZIP7_INC_ZIP_OUT_H + +#include "../../../Common/MyCom.h" + +#include "../../Common/OutBuffer.h" + +#include "ZipItem.h" + +namespace NArchive { +namespace NZip { + +class CItemOut: public CItem +{ +public: + FILETIME Ntfs_MTime; + FILETIME Ntfs_ATime; + FILETIME Ntfs_CTime; + bool Write_NtfsTime; + bool Write_UnixTime; + + // It's possible that NtfsTime is not defined, but there is NtfsTime in Extra. + + CByteBuffer Name_Utf; // for Info-Zip (kIzUnicodeName) Extra + + size_t Get_UtfName_ExtraSize() const + { + const size_t size = Name_Utf.Size(); + if (size == 0) + return 0; + return 4 + 5 + size; + } + + CItemOut(): + Write_NtfsTime(false), + Write_UnixTime(false) + {} +}; + + +// COutArchive can throw CSystemException and COutBufferException + +class COutArchive +{ + COutBuffer m_OutBuffer; + CMyComPtr m_Stream; + + UInt64 m_Base; // Base of archive (offset in output Stream) + UInt64 m_CurPos; // Curent position in archive (relative from m_Base) + UInt64 m_LocalHeaderPos; // LocalHeaderPos (relative from m_Base) for last WriteLocalHeader() call + + UInt32 m_LocalFileHeaderSize; + UInt32 m_ExtraSize; + bool m_IsZip64; + + void WriteBytes(const void *data, size_t size); + void Write8(Byte b); + void Write16(UInt16 val); + void Write32(UInt32 val); + void Write64(UInt64 val); + void WriteNtfsTime(const FILETIME &ft) + { + Write32(ft.dwLowDateTime); + 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); + void WriteCentralHeader(const CItemOut &item); + + void SeekToCurPos(); +public: + CMyComPtr SetRestriction; + + HRESULT ClearRestriction(); + HRESULT SetRestrictionFromCurrent(); + HRESULT Create(IOutStream *outStream); + + UInt64 GetCurPos() const { return m_CurPos; } + + void MoveCurPos(UInt64 distanceToMove) + { + m_CurPos += distanceToMove; + } + + void WriteLocalHeader(CItemOut &item, bool needCheck = false); + void WriteLocalHeader_Replace(CItemOut &item); + + void WriteDescriptor(const CItemOut &item); + + HRESULT WriteCentralDir(const CObjectVector &items, const CByteBuffer *comment); + + void CreateStreamForCompressing(CMyComPtr &outStream); + void CreateStreamForCopying(CMyComPtr &outStream); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipRegister.cpp 2016-05-18 17:31:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipRegister.cpp 2022-12-20 16:00:00.000000000 +0000 @@ -1,27 +1,38 @@ -// ZipRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "ZipHandler.h" - -namespace NArchive { -namespace NZip { - -static const Byte k_Signature[] = { - 4, 0x50, 0x4B, 0x03, 0x04, - 4, 0x50, 0x4B, 0x05, 0x06, - 6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B, - 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; - -REGISTER_ARC_IO( - "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub", 0, 1, - k_Signature, - 0, - NArcInfoFlags::kFindSignature | - NArcInfoFlags::kMultiSignature | - NArcInfoFlags::kUseGlobalOffset, - IsArc_Zip) - -}} +// ZipRegister.cpp + +#include "StdAfx.h" + +#include "../../Common/RegisterArc.h" + +#include "ZipHandler.h" + +namespace NArchive { +namespace NZip { + +static const Byte k_Signature[] = { + 4, 0x50, 0x4B, 0x03, 0x04, // Local + 4, 0x50, 0x4B, 0x05, 0x06, // Ecd + 4, 0x50, 0x4B, 0x06, 0x06, // Ecd64 + 6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B, // Span / Descriptor + 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; // NoSpan + +REGISTER_ARC_IO( + "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", NULL, 1, + k_Signature, + 0, + 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 -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipUpdate.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2016-05-20 08:35:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2025-07-03 09:00:00.000000000 +0000 @@ -1,1242 +1,2165 @@ -// ZipUpdate.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" - -#include "../../../Common/AutoPtr.h" -#include "../../../Common/Defs.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/TimeUtils.h" -#include "../../../Windows/Thread.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/OutMemStream.h" -#include "../../Common/ProgressUtils.h" -#ifndef _7ZIP_ST -#include "../../Common/ProgressMt.h" -#endif -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "ZipAddCommon.h" -#include "ZipOut.h" -#include "ZipUpdate.h" - -using namespace NWindows; -using namespace NSynchronization; - -namespace NArchive { -namespace NZip { - -static const Byte kHostOS = - #ifdef _WIN32 - NFileHeader::NHostOS::kFAT; - #else - NFileHeader::NHostOS::kUnix; - #endif - -static const Byte kMadeByHostOS = kHostOS; -static const Byte kExtractHostOS = kHostOS; - -static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored; - -static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size, - COutArchive &outArchive, ICompressProgressInfo *progress) -{ - CMyComPtr outStream; - outArchive.CreateStreamForCopying(&outStream); - return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress); -} - -static void SetFileHeader( - COutArchive &archive, - const CCompressionMethodMode &options, - const CUpdateItem &ui, - // bool isSeqMode, - CItemOut &item) -{ - item.Size = ui.Size; - bool isDir; - - item.ClearFlags(); - - if (ui.NewProps) - { - isDir = ui.IsDir; - item.Name = ui.Name; - item.SetUtf8(ui.IsUtf8); - item.ExternalAttrib = ui.Attrib; - item.Time = ui.Time; - item.Ntfs_MTime = ui.Ntfs_MTime; - item.Ntfs_ATime = ui.Ntfs_ATime; - item.Ntfs_CTime = ui.Ntfs_CTime; - item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; - } - else - isDir = item.IsDir(); - - item.LocalHeaderPos = archive.GetCurPos(); - item.MadeByVersion.HostOS = kMadeByHostOS; - item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion; - - item.ExtractVersion.HostOS = kExtractHostOS; - - item.InternalAttrib = 0; // test it - item.SetEncrypted(!isDir && options.PasswordIsDefined); - // item.SetDescriptorMode(isSeqMode); - - if (isDir) - { - item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir; - item.Method = kMethodForDirectory; - item.PackSize = 0; - item.Size = 0; - item.Crc = 0; - } -} - - -static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult, - bool isAesMode, Byte aesKeyMode, CItem &item) -{ - item.ExtractVersion.Version = compressingResult.ExtractVersion; - item.Method = compressingResult.Method; - item.Crc = compressingResult.CRC; - item.Size = compressingResult.UnpackSize; - item.PackSize = compressingResult.PackSize; - - item.LocalExtra.Clear(); - item.CentralExtra.Clear(); - - if (isAesMode) - { - CWzAesExtra wzAesField; - wzAesField.Strength = aesKeyMode; - wzAesField.Method = compressingResult.Method; - item.Method = NFileHeader::NCompressionMethod::kWzAES; - item.Crc = 0; - CExtraSubBlock sb; - wzAesField.SetSubBlock(sb); - item.LocalExtra.SubBlocks.Add(sb); - item.CentralExtra.SubBlocks.Add(sb); - } -} - - -#ifndef _7ZIP_ST - -static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo); - -struct CThreadInfo -{ - DECL_EXTERNAL_CODECS_LOC_VARS2; - - NWindows::CThread Thread; - NWindows::NSynchronization::CAutoResetEvent CompressEvent; - NWindows::NSynchronization::CAutoResetEventWFMO CompressionCompletedEvent; - bool ExitThread; - - CMtCompressProgress *ProgressSpec; - CMyComPtr Progress; - - COutMemStream *OutStreamSpec; - CMyComPtr OutStream; - CMyComPtr InStream; - - CAddCommon Coder; - HRESULT Result; - CCompressingResult CompressingResult; - - bool IsFree; - UInt32 UpdateIndex; - UInt32 FileTime; - - CThreadInfo(const CCompressionMethodMode &options): - ExitThread(false), - ProgressSpec(0), - OutStreamSpec(0), - Coder(options), - FileTime(0) - {} - - HRESULT CreateEvents(CSynchro *sync) - { - RINOK(CompressEvent.CreateIfNotCreated()); - return CompressionCompletedEvent.CreateIfNotCreated(sync); - } - HRes CreateThread() { return Thread.Create(CoderThread, this); } - - void WaitAndCode(); - void StopWaitClose() - { - ExitThread = true; - if (OutStreamSpec != 0) - OutStreamSpec->StopWriting(E_ABORT); - if (CompressEvent.IsCreated()) - CompressEvent.Set(); - Thread.Wait(); - Thread.Close(); - } -}; - -void CThreadInfo::WaitAndCode() -{ - for (;;) - { - CompressEvent.Lock(); - if (ExitThread) - return; - - Result = Coder.Compress( - EXTERNAL_CODECS_LOC_VARS - InStream, OutStream, FileTime, Progress, CompressingResult); - - if (Result == S_OK && Progress) - Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize); - CompressionCompletedEvent.Set(); - } -} - -static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo) -{ - ((CThreadInfo *)threadCoderInfo)->WaitAndCode(); - return 0; -} - -class CThreads -{ -public: - CObjectVector Threads; - ~CThreads() - { - FOR_VECTOR (i, Threads) - Threads[i].StopWaitClose(); - } -}; - -struct CMemBlocks2: public CMemLockBlocks -{ - CCompressingResult CompressingResult; - bool Defined; - bool Skip; - CMemBlocks2(): Defined(false), Skip(false) {} -}; - -class CMemRefs -{ -public: - CMemBlockManagerMt *Manager; - CObjectVector Refs; - CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} ; - ~CMemRefs() - { - FOR_VECTOR (i, Refs) - Refs[i].FreeOpt(Manager); - } -}; - -class CMtProgressMixer2: - public ICompressProgressInfo, - public CMyUnknownImp -{ - UInt64 ProgressOffset; - UInt64 InSizes[2]; - UInt64 OutSizes[2]; - CMyComPtr Progress; - CMyComPtr RatioProgress; - bool _inSizeIsMain; -public: - NWindows::NSynchronization::CCriticalSection CriticalSection; - MY_UNKNOWN_IMP - void Create(IProgress *progress, bool inSizeIsMain); - void SetProgressOffset(UInt64 progressOffset); - HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize); - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -void CMtProgressMixer2::Create(IProgress *progress, bool inSizeIsMain) -{ - Progress = progress; - Progress.QueryInterface(IID_ICompressProgressInfo, &RatioProgress); - _inSizeIsMain = inSizeIsMain; - ProgressOffset = InSizes[0] = InSizes[1] = OutSizes[0] = OutSizes[1] = 0; -} - -void CMtProgressMixer2::SetProgressOffset(UInt64 progressOffset) -{ - CriticalSection.Enter(); - InSizes[1] = OutSizes[1] = 0; - ProgressOffset = progressOffset; - CriticalSection.Leave(); -} - -HRESULT CMtProgressMixer2::SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - if (index == 0 && RatioProgress) - { - RINOK(RatioProgress->SetRatioInfo(inSize, outSize)); - } - if (inSize) - InSizes[index] = *inSize; - if (outSize) - OutSizes[index] = *outSize; - UInt64 v = ProgressOffset + (_inSizeIsMain ? - (InSizes[0] + InSizes[1]) : - (OutSizes[0] + OutSizes[1])); - return Progress->SetCompleted(&v); -} - -STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - return SetRatioInfo(0, inSize, outSize); -} - -class CMtProgressMixer: - public ICompressProgressInfo, - public CMyUnknownImp -{ -public: - CMtProgressMixer2 *Mixer2; - CMyComPtr RatioProgress; - void Create(IProgress *progress, bool inSizeIsMain); - MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -void CMtProgressMixer::Create(IProgress *progress, bool inSizeIsMain) -{ - Mixer2 = new CMtProgressMixer2; - RatioProgress = Mixer2; - Mixer2->Create(progress, inSizeIsMain); -} - -STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - return Mixer2->SetRatioInfo(1, inSize, outSize); -} - - -#endif - - -static HRESULT UpdateItemOldData( - COutArchive &archive, - CInArchive *inArchive, - const CItemEx &itemEx, - const CUpdateItem &ui, - CItemOut &item, - /* bool izZip64, */ - ICompressProgressInfo *progress, - IArchiveUpdateCallbackFile *opCallback, - UInt64 &complexity) -{ - if (opCallback) - { - RINOK(opCallback->ReportOperation( - NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, - NUpdateNotifyOp::kReplicate)) - } - - if (ui.NewProps) - { - if (item.HasDescriptor()) - return E_NOTIMPL; - - // use old name size. - - CMyComPtr packStream; - RINOK(inArchive->GetItemStream(itemEx, true, packStream)); - if (!packStream) - return E_NOTIMPL; - - // we keep ExternalAttrib and some another properties from old archive - // item.ExternalAttrib = ui.Attrib; - - item.Name = ui.Name; - item.SetUtf8(ui.IsUtf8); - item.Time = ui.Time; - item.Ntfs_MTime = ui.Ntfs_MTime; - item.Ntfs_ATime = ui.Ntfs_ATime; - item.Ntfs_CTime = ui.Ntfs_CTime; - item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; - - item.CentralExtra.RemoveUnknownSubBlocks(); - item.LocalExtra.RemoveUnknownSubBlocks(); - item.LocalHeaderPos = archive.GetCurPos(); - - archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes()); - archive.WriteLocalHeader(item); - - RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress)); - - complexity += itemEx.PackSize; - } - else - { - CMyComPtr packStream; - RINOK(inArchive->GetItemStream(itemEx, false, packStream)); - if (!packStream) - return E_NOTIMPL; - - // set new header position - item.LocalHeaderPos = archive.GetCurPos(); - - const UInt64 rangeSize = itemEx.GetLocalFullSize(); - - RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress)); - - complexity += rangeSize; - archive.MoveCurPos(rangeSize); - } - - return S_OK; -} - - -static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, - const CUpdateItem &ui, CItemOut &item) -{ - SetFileHeader(archive, *options, ui, item); - archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, - // options->IsRealAesMode() - false // fixed 9.31 - ); - archive.WriteLocalHeader_And_SeekToNextFile(item); -} - - -static inline bool IsZero_FILETIME(const FILETIME &ft) -{ - return (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0); -} - -static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileInStream, - IArchiveUpdateCallback *updateCallback, UInt64 &totalComplexity) -{ - CMyComPtr getProps; - fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); - if (!getProps) - return; - - FILETIME cTime, aTime, mTime; - UInt64 size; - // UInt32 attrib; - if (getProps->GetProps(&size, &cTime, &aTime, &mTime, NULL) != S_OK) - return; - - if (size != item.Size && size != (UInt64)(Int64)-1) - { - Int64 newComplexity = totalComplexity + ((Int64)size - (Int64)item.Size); - if (newComplexity > 0) - { - totalComplexity = newComplexity; - updateCallback->SetTotal(totalComplexity); - } - item.Size = size; - } - - if (!IsZero_FILETIME(mTime)) - { - item.Ntfs_MTime = mTime; - FILETIME loc = { 0, 0 }; - if (FileTimeToLocalFileTime(&mTime, &loc)) - { - item.Time = 0; - NTime::FileTimeToDosTime(loc, item.Time); - } - } - - if (!IsZero_FILETIME(cTime)) item.Ntfs_CTime = cTime; - if (!IsZero_FILETIME(aTime)) item.Ntfs_ATime = aTime; - - // item.Attrib = attrib; -} - - -static HRESULT Update2St( - DECL_EXTERNAL_CODECS_LOC_VARS - COutArchive &archive, - CInArchive *inArchive, - const CObjectVector &inputItems, - CObjectVector &updateItems, - const CCompressionMethodMode *options, - const CByteBuffer *comment, - IArchiveUpdateCallback *updateCallback, - UInt64 &totalComplexity, - IArchiveUpdateCallbackFile *opCallback) -{ - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(updateCallback, true); - - CAddCommon compressor(*options); - - CObjectVector items; - UInt64 unpackSizeTotal = 0, packSizeTotal = 0; - - FOR_VECTOR (itemIndex, updateItems) - { - lps->InSize = unpackSizeTotal; - lps->OutSize = packSizeTotal; - RINOK(lps->SetCur()); - CUpdateItem &ui = updateItems[itemIndex]; - CItemEx itemEx; - CItemOut item; - - if (!ui.NewProps || !ui.NewData) - { - itemEx = inputItems[ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) - return E_NOTIMPL; - (CItem &)item = itemEx; - } - - if (ui.NewData) - { - bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); - if (isDir) - { - WriteDirHeader(archive, options, ui, item); - } - else - { - CMyComPtr fileInStream; - HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); - if (res == S_FALSE) - { - lps->ProgressOffset += ui.Size; - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - continue; - } - RINOK(res); - if (!fileInStream) - return E_INVALIDARG; - - // bool isSeqMode = false; - /* - { - CMyComPtr inStream2; - fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2); - isSeqMode = (inStream2 == NULL); - } - */ - - UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity); - SetFileHeader(archive, *options, ui, item); - - // file Size can be 64-bit !!! - archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode()); - CCompressingResult compressingResult; - CMyComPtr outStream; - archive.CreateStreamForCompressing(&outStream); - - RINOK(compressor.Compress( - EXTERNAL_CODECS_LOC_VARS - fileInStream, outStream, - ui.Time, - progress, compressingResult)); - - if (compressingResult.FileTimeWasUsed) - { - /* - if (!item.HasDescriptor()) - return E_FAIL; - */ - item.SetDescriptorMode(true); - } - - SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item); - archive.WriteLocalHeader_And_SeekToNextFile(item); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - unpackSizeTotal += item.Size; - packSizeTotal += item.PackSize; - } - } - else - { - UInt64 complexity = 0; - lps->SendRatio = false; - RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)); - lps->SendRatio = true; - lps->ProgressOffset += complexity; - } - - items.Add(item); - lps->ProgressOffset += kLocalHeaderSize; - } - - lps->InSize = unpackSizeTotal; - lps->OutSize = packSizeTotal; - RINOK(lps->SetCur()); - archive.WriteCentralDir(items, comment); - return S_OK; -} - - -static HRESULT Update2( - DECL_EXTERNAL_CODECS_LOC_VARS - COutArchive &archive, - CInArchive *inArchive, - const CObjectVector &inputItems, - CObjectVector &updateItems, - const CCompressionMethodMode *options, - const CByteBuffer *comment, - IArchiveUpdateCallback *updateCallback) -{ - CMyComPtr opCallback; - updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); - - UInt64 complexity = 0; - UInt64 numFilesToCompress = 0; - UInt64 numBytesToCompress = 0; - - unsigned i; - - for (i = 0; i < updateItems.Size(); i++) - { - const CUpdateItem &ui = updateItems[i]; - if (ui.NewData) - { - complexity += ui.Size; - numBytesToCompress += ui.Size; - numFilesToCompress++; - /* - if (ui.Commented) - complexity += ui.CommentRange.Size; - */ - } - else - { - CItemEx inputItem = inputItems[ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK) - return E_NOTIMPL; - complexity += inputItem.GetLocalFullSize(); - // complexity += inputItem.GetCentralExtraPlusCommentSize(); - } - complexity += kLocalHeaderSize; - complexity += kCentralHeaderSize; - } - - if (comment) - complexity += comment->Size(); - complexity++; // end of central - updateCallback->SetTotal(complexity); - - UInt64 totalComplexity = complexity; - - CAddCommon compressor(*options); - - complexity = 0; - - CCompressionMethodMode options2; - if (options != 0) - options2 = *options; - - #ifndef _7ZIP_ST - - UInt32 numThreads = options->NumThreads; - const UInt32 kNumMaxThreads = 64; - if (numThreads > kNumMaxThreads) - numThreads = kNumMaxThreads; - if (numThreads > MAXIMUM_WAIT_OBJECTS) // is 64 in Windows (is it 64 in all versions?) - numThreads = MAXIMUM_WAIT_OBJECTS; - if (numThreads < 1) - numThreads = 1; - - - const size_t kMemPerThread = (1 << 25); - const size_t kBlockSize = 1 << 16; - - bool mtMode = ((options != 0) && (numThreads > 1)); - - if (numFilesToCompress <= 1) - mtMode = false; - - Byte method = options->MethodSequence.Front(); - - if (!mtMode) - { - if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0) - { - // fixed for 9.31. bzip2 default is just one thread. - if (options2.NumThreadsWasChanged || method == NFileHeader::NCompressionMethod::kBZip2) - options2.MethodInfo.AddProp_NumThreads(numThreads); - } - } - else - { - if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined) - numThreads = 1; - if (method == NFileHeader::NCompressionMethod::kBZip2) - { - bool fixedNumber; - UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber); - if (!fixedNumber) - { - UInt64 averageSize = numBytesToCompress / numFilesToCompress; - UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize(); - UInt64 averageNumberOfBlocks = averageSize / blockSize + 1; - numBZip2Threads = 32; - if (averageNumberOfBlocks < numBZip2Threads) - numBZip2Threads = (UInt32)averageNumberOfBlocks; - options2.MethodInfo.AddProp_NumThreads(numBZip2Threads); - } - numThreads /= numBZip2Threads; - } - if (method == NFileHeader::NCompressionMethod::kLZMA) - { - bool fixedNumber; - // we suppose that default LZMA is 2 thread. So we don't change it - UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber); - numThreads /= numLZMAThreads; - } - if (numThreads > numFilesToCompress) - numThreads = (UInt32)numFilesToCompress; - if (numThreads <= 1) - mtMode = false; - } - - if (!mtMode) - #endif - return Update2St( - EXTERNAL_CODECS_LOC_VARS - archive, inArchive, - inputItems, updateItems, &options2, comment, updateCallback, totalComplexity, opCallback); - - - #ifndef _7ZIP_ST - - // Warning : before memManager, threads and compressingCompletedEvents - // in order to have a "good" order for the destructor - NWindows::NSynchronization::CSynchro synchroForCompressingCompletedEvents; - synchroForCompressingCompletedEvents.Create(); - NWindows::NSynchronization::CSynchro synchroForOutStreamSpec; - synchroForOutStreamSpec.Create(); - - CObjectVector items; - - CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer; - CMyComPtr progress = mtProgressMixerSpec; - mtProgressMixerSpec->Create(updateCallback, true); - - CMtCompressProgressMixer mtCompressProgressMixer; - mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress); - - CMemBlockManagerMt memManager(kBlockSize); - CMemRefs refs(&memManager); - - CThreads threads; - CRecordVector compressingCompletedEvents; - CUIntVector threadIndices; // list threads in order of updateItems - - { - RINOK(memManager.AllocateSpaceAlways(&synchroForOutStreamSpec,(size_t)numThreads * (kMemPerThread / kBlockSize))); - for (i = 0; i < updateItems.Size(); i++) - refs.Refs.Add(CMemBlocks2()); - - for (i = 0; i < numThreads; i++) - threads.Threads.Add(CThreadInfo(options2)); - - for (i = 0; i < numThreads; i++) - { - CThreadInfo &threadInfo = threads.Threads[i]; - #ifdef EXTERNAL_CODECS - threadInfo.__externalCodecs = __externalCodecs; - #endif - RINOK(threadInfo.CreateEvents(&synchroForCompressingCompletedEvents)); - threadInfo.OutStreamSpec = new COutMemStream(&memManager); - RINOK(threadInfo.OutStreamSpec->CreateEvents(&synchroForOutStreamSpec)); - threadInfo.OutStream = threadInfo.OutStreamSpec; - threadInfo.IsFree = true; - threadInfo.ProgressSpec = new CMtCompressProgress(); - threadInfo.Progress = threadInfo.ProgressSpec; - threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i); - threadInfo.FileTime = 0; // fix it ! - RINOK(threadInfo.CreateThread()); - } - } - - unsigned mtItemIndex = 0; - unsigned itemIndex = 0; - int lastRealStreamItemIndex = -1; - - while (itemIndex < updateItems.Size()) - { - if (threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size()) - { - CUpdateItem &ui = updateItems[mtItemIndex++]; - if (!ui.NewData) - continue; - CItemEx itemEx; - CItemOut item; - - if (ui.NewProps) - { - if (ui.IsDir) - continue; - } - else - { - itemEx = inputItems[ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) - return E_NOTIMPL; - (CItem &)item = itemEx; - if (item.IsDir()) - continue; - } - - CMyComPtr fileInStream; - - { - NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection); - HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); - if (res == S_FALSE) - { - complexity += ui.Size; - complexity += kLocalHeaderSize; - mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - refs.Refs[mtItemIndex - 1].Skip = true; - continue; - } - RINOK(res); - if (!fileInStream) - return E_INVALIDARG; - UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity); - RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - } - - for (UInt32 k = 0; k < numThreads; k++) - { - CThreadInfo &threadInfo = threads.Threads[k]; - if (threadInfo.IsFree) - { - threadInfo.IsFree = false; - threadInfo.InStream = fileInStream; - - // !!!!! we must release ref before sending event - // BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time - fileInStream.Release(); - - threadInfo.OutStreamSpec->Init(); - threadInfo.ProgressSpec->Reinit(); - threadInfo.CompressEvent.Set(); - threadInfo.UpdateIndex = mtItemIndex - 1; - - compressingCompletedEvents.Add(threadInfo.CompressionCompletedEvent); - threadIndices.Add(k); - break; - } - } - - continue; - } - - if (refs.Refs[itemIndex].Skip) - { - itemIndex++; - continue; - } - - const CUpdateItem &ui = updateItems[itemIndex]; - - CItemEx itemEx; - CItemOut item; - - if (!ui.NewProps || !ui.NewData) - { - itemEx = inputItems[ui.IndexInArc]; - if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK) - return E_NOTIMPL; - (CItem &)item = itemEx; - } - - if (ui.NewData) - { - bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); - - if (isDir) - { - WriteDirHeader(archive, options, ui, item); - } - else - { - if (lastRealStreamItemIndex < (int)itemIndex) - { - lastRealStreamItemIndex = itemIndex; - SetFileHeader(archive, *options, ui, item); - // file Size can be 64-bit !!! - archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode()); - } - - CMemBlocks2 &memRef = refs.Refs[itemIndex]; - - if (memRef.Defined) - { - CMyComPtr outStream; - archive.CreateStreamForCompressing(&outStream); - memRef.WriteToStream(memManager.GetBlockSize(), outStream); - SetFileHeader(archive, *options, ui, item); - // the BUG was fixed in 9.26: - // SetItemInfoFromCompressingResult must be after SetFileHeader - // to write correct Size. - SetItemInfoFromCompressingResult(memRef.CompressingResult, - options->IsRealAesMode(), options->AesKeyMode, item); - archive.WriteLocalHeader_And_SeekToNextFile(item); - // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - memRef.FreeOpt(&memManager); - } - else - { - { - CThreadInfo &thread = threads.Threads[threadIndices.Front()]; - if (!thread.OutStreamSpec->WasUnlockEventSent()) - { - CMyComPtr outStream; - archive.CreateStreamForCompressing(&outStream); - thread.OutStreamSpec->SetOutStream(outStream); - thread.OutStreamSpec->SetRealStreamMode(); - } - } - - DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(), - &compressingCompletedEvents.Front(), FALSE, INFINITE); -#ifdef _WIN32 // FIXME - if (result == WAIT_FAILED) - { - DWORD lastError = GetLastError(); - return lastError != 0 ? lastError : E_FAIL; - } -#endif - unsigned t = (unsigned)(result - WAIT_OBJECT_0); - if (t >= compressingCompletedEvents.Size()) - return E_FAIL; - - CThreadInfo &threadInfo = threads.Threads[threadIndices[t]]; - threadInfo.InStream.Release(); - threadInfo.IsFree = true; - RINOK(threadInfo.Result); - threadIndices.Delete(t); - compressingCompletedEvents.Delete(t); - - if (t == 0) - { - RINOK(threadInfo.OutStreamSpec->WriteToRealStream()); - threadInfo.OutStreamSpec->ReleaseOutStream(); - SetFileHeader(archive, *options, ui, item); - SetItemInfoFromCompressingResult(threadInfo.CompressingResult, - options->IsRealAesMode(), options->AesKeyMode, item); - archive.WriteLocalHeader_And_SeekToNextFile(item); - } - else - { - CMemBlocks2 &memRef2 = refs.Refs[threadInfo.UpdateIndex]; - threadInfo.OutStreamSpec->DetachData(memRef2); - memRef2.CompressingResult = threadInfo.CompressingResult; - memRef2.Defined = true; - continue; - } - } - } - } - else - { - RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)); - } - - items.Add(item); - complexity += kLocalHeaderSize; - mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity); - itemIndex++; - } - - RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL)); - archive.WriteCentralDir(items, comment); - return S_OK; - #endif -} - - -static const size_t kCacheBlockSize = (1 << 20); -static const size_t kCacheSize = (kCacheBlockSize << 2); -static const size_t kCacheMask = (kCacheSize - 1); - -class CCacheOutStream: - public IOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - Byte *_cache; - UInt64 _virtPos; - UInt64 _virtSize; - UInt64 _phyPos; - UInt64 _phySize; // <= _virtSize - UInt64 _cachedPos; // (_cachedPos + _cachedSize) <= _virtSize - size_t _cachedSize; - - HRESULT MyWrite(size_t size); - HRESULT MyWriteBlock() - { - return MyWrite(kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1))); - } - HRESULT FlushCache(); -public: - CCacheOutStream(): _cache(0) {} - ~CCacheOutStream(); - bool Allocate(); - HRESULT Init(IOutStream *stream); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); -}; - -bool CCacheOutStream::Allocate() -{ - if (!_cache) - _cache = (Byte *)::MidAlloc(kCacheSize); - return (_cache != NULL); -} - -HRESULT CCacheOutStream::Init(IOutStream *stream) -{ - _virtPos = _phyPos = 0; - _stream = stream; - RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &_virtPos)); - RINOK(_stream->Seek(0, STREAM_SEEK_END, &_virtSize)); - RINOK(_stream->Seek(_virtPos, STREAM_SEEK_SET, &_virtPos)); - _phyPos = _virtPos; - _phySize = _virtSize; - _cachedPos = 0; - _cachedSize = 0; - return S_OK; -} - -HRESULT CCacheOutStream::MyWrite(size_t size) -{ - while (size != 0 && _cachedSize != 0) - { - if (_phyPos != _cachedPos) - { - RINOK(_stream->Seek(_cachedPos, STREAM_SEEK_SET, &_phyPos)); - } - size_t pos = (size_t)_cachedPos & kCacheMask; - size_t curSize = MyMin(kCacheSize - pos, _cachedSize); - curSize = MyMin(curSize, size); - RINOK(WriteStream(_stream, _cache + pos, curSize)); - _phyPos += curSize; - if (_phySize < _phyPos) - _phySize = _phyPos; - _cachedPos += curSize; - _cachedSize -= curSize; - size -= curSize; - } - return S_OK; -} - -HRESULT CCacheOutStream::FlushCache() -{ - return MyWrite(_cachedSize); -} - -CCacheOutStream::~CCacheOutStream() -{ - FlushCache(); - if (_virtSize != _phySize) - _stream->SetSize(_virtSize); - if (_virtPos != _phyPos) - _stream->Seek(_virtPos, STREAM_SEEK_SET, NULL); - ::MidFree(_cache); -} - -STDMETHODIMP CCacheOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - - UInt64 zerosStart = _virtPos; - if (_cachedSize != 0) - { - if (_virtPos < _cachedPos) - { - RINOK(FlushCache()); - } - else - { - UInt64 cachedEnd = _cachedPos + _cachedSize; - if (cachedEnd < _virtPos) - { - if (cachedEnd < _phySize) - { - RINOK(FlushCache()); - } - else - zerosStart = cachedEnd; - } - } - } - - if (_cachedSize == 0 && _phySize < _virtPos) - _cachedPos = zerosStart = _phySize; - - if (zerosStart != _virtPos) - { - // write zeros to [cachedEnd ... _virtPos) - - for (;;) - { - UInt64 cachedEnd = _cachedPos + _cachedSize; - size_t endPos = (size_t)cachedEnd & kCacheMask; - size_t curSize = kCacheSize - endPos; - if (curSize > _virtPos - cachedEnd) - curSize = (size_t)(_virtPos - cachedEnd); - if (curSize == 0) - break; - while (curSize > (kCacheSize - _cachedSize)) - { - RINOK(MyWriteBlock()); - } - memset(_cache + endPos, 0, curSize); - _cachedSize += curSize; - } - } - - if (_cachedSize == 0) - _cachedPos = _virtPos; - - size_t pos = (size_t)_virtPos & kCacheMask; - size = (UInt32)MyMin((size_t)size, kCacheSize - pos); - UInt64 cachedEnd = _cachedPos + _cachedSize; - if (_virtPos != cachedEnd) // _virtPos < cachedEnd - size = (UInt32)MyMin((size_t)size, (size_t)(cachedEnd - _virtPos)); - else - { - // _virtPos == cachedEnd - if (_cachedSize == kCacheSize) - { - RINOK(MyWriteBlock()); - } - size_t startPos = (size_t)_cachedPos & kCacheMask; - if (startPos > pos) - size = (UInt32)MyMin((size_t)size, (size_t)(startPos - pos)); - _cachedSize += size; - } - memcpy(_cache + pos, data, size); - if (processedSize) - *processedSize = size; - _virtPos += size; - if (_virtSize < _virtPos) - _virtSize = _virtPos; - return S_OK; -} - -STDMETHODIMP CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += _virtSize; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - -STDMETHODIMP CCacheOutStream::SetSize(UInt64 newSize) -{ - _virtSize = newSize; - if (newSize < _phySize) - { - RINOK(_stream->SetSize(newSize)); - _phySize = newSize; - } - if (newSize <= _cachedPos) - { - _cachedSize = 0; - _cachedPos = newSize; - } - if (newSize < _cachedPos + _cachedSize) - _cachedSize = (size_t)(newSize - _cachedPos); - return S_OK; -} - - -HRESULT Update( - DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector &inputItems, - CObjectVector &updateItems, - ISequentialOutStream *seqOutStream, - CInArchive *inArchive, bool removeSfx, - CCompressionMethodMode *compressionMethodMode, - IArchiveUpdateCallback *updateCallback) -{ - if (inArchive) - { - if (!inArchive->CanUpdate()) - return E_NOTIMPL; - } - - - CMyComPtr outStream; - { - CMyComPtr outStreamReal; - seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); - if (!outStreamReal) - return E_NOTIMPL; - - if (inArchive) - { - if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx) - { - IInStream *baseStream = inArchive->GetBaseStream(); - RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(baseStream, outStreamReal, inArchive->ArcInfo.Base, NULL)); - } - } - - CCacheOutStream *cacheStream = new CCacheOutStream(); - outStream = cacheStream; - if (!cacheStream->Allocate()) - return E_OUTOFMEMORY; - RINOK(cacheStream->Init(outStreamReal)); - } - - COutArchive outArchive; - RINOK(outArchive.Create(outStream)); - - if (inArchive) - { - if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) - { - IInStream *baseStream = inArchive->GetBaseStream(); - RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL)); - UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base; - RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL)); - outArchive.MoveCurPos(embStubSize); - } - } - - return Update2( - EXTERNAL_CODECS_LOC_VARS - outArchive, inArchive, - inputItems, updateItems, - compressionMethodMode, - inArchive ? &inArchive->ArcInfo.Comment : NULL, - updateCallback); -} - -}} +// ZipUpdate.cpp + +#include "StdAfx.h" + +// #define DEBUG_CACHE + +#ifdef DEBUG_CACHE +#include + #define PRF(x) x +#else + #define PRF(x) +#endif + +#include "../../../../C/Alloc.h" + +#include "../../../Common/AutoPtr.h" +#include "../../../Common/Defs.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/TimeUtils.h" +#include "../../../Windows/Thread.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/OutMemStream.h" +#include "../../Common/ProgressUtils.h" +#ifndef Z7_ST +#include "../../Common/ProgressMt.h" +#endif +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" +// #include "../../Compress/ZstdEncoderProps.h" + +#include "ZipAddCommon.h" +#include "ZipOut.h" +#include "ZipUpdate.h" + +using namespace NWindows; +using namespace NSynchronization; + +namespace NArchive { +namespace NZip { + +static const Byte kHostOS = + #ifdef _WIN32 + NFileHeader::NHostOS::kFAT; + #else + NFileHeader::NHostOS::kUnix; + #endif + +static const Byte kMadeByHostOS = kHostOS; + +// 18.06: now we always write zero to high byte of ExtractVersion field. +// Previous versions of p7zip wrote (NFileHeader::NHostOS::kUnix) there, that is not correct +static const Byte kExtractHostOS = 0; + +static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore; + + +static void AddAesExtra(CItem &item, Byte aesKeyMode, UInt16 method) +{ + CWzAesExtra wzAesField; + wzAesField.Strength = aesKeyMode; + wzAesField.Method = method; + item.Method = NFileHeader::NCompressionMethod::kWzAES; + item.Crc = 0; + CExtraSubBlock sb; + wzAesField.SetSubBlock(sb); + item.LocalExtra.SubBlocks.Add(sb); + item.CentralExtra.SubBlocks.Add(sb); +} + + +static void Copy_From_UpdateItem_To_ItemOut(const CUpdateItem &ui, CItemOut &item) +{ + item.Name = ui.Name; + item.Name_Utf = ui.Name_Utf; + item.Comment = ui.Comment; + item.SetUtf8(ui.IsUtf8); + // item.SetFlag_AltStream(ui.IsAltStream); + // item.ExternalAttrib = ui.Attrib; + item.Time = ui.Time; + item.Ntfs_MTime = ui.Ntfs_MTime; + item.Ntfs_ATime = ui.Ntfs_ATime; + item.Ntfs_CTime = ui.Ntfs_CTime; + + item.Write_UnixTime = ui.Write_UnixTime; + item.Write_NtfsTime = ui.Write_NtfsTime; +} + +static void SetFileHeader( + const CCompressionMethodMode &options, + const CUpdateItem &ui, + bool useDescriptor, + CItemOut &item) +{ + item.Size = ui.Size; + const bool isDir = ui.IsDir; + + item.ClearFlags(); + + if (ui.NewProps) + { + Copy_From_UpdateItem_To_ItemOut(ui, item); + // item.SetFlag_AltStream(ui.IsAltStream); + item.ExternalAttrib = ui.Attrib; + } + /* + else + isDir = item.IsDir(); + */ + + item.MadeByVersion.HostOS = kMadeByHostOS; + item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion; + + item.ExtractVersion.HostOS = kExtractHostOS; + + item.InternalAttrib = 0; // test it + item.SetEncrypted(!isDir && options.Password_Defined); + item.SetDescriptorMode(useDescriptor); + + if (isDir) + { + item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir; + item.Method = kMethodForDirectory; + item.PackSize = 0; + item.Size = 0; + item.Crc = 0; + } + + item.LocalExtra.Clear(); + item.CentralExtra.Clear(); + + if (isDir) + { + item.ExtractVersion.Version = NFileHeader::NCompressionMethod::kExtractVersion_Dir; + item.Method = kMethodForDirectory; + item.PackSize = 0; + item.Size = 0; + item.Crc = 0; + } + else if (options.IsRealAesMode()) + AddAesExtra(item, options.AesKeyMode, (Byte)(options.MethodSequence.IsEmpty() ? 8 : options.MethodSequence[0])); +} + + +// we call SetItemInfoFromCompressingResult() after SetFileHeader() + +static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult, + bool isAesMode, Byte aesKeyMode, CItem &item) +{ + item.ExtractVersion.Version = compressingResult.ExtractVersion; + item.Method = compressingResult.Method; + if (compressingResult.Method == NFileHeader::NCompressionMethod::kLZMA && compressingResult.LzmaEos) + item.Flags |= NFileHeader::NFlags::kLzmaEOS; + item.Crc = compressingResult.CRC; + item.Size = compressingResult.UnpackSize; + item.PackSize = compressingResult.PackSize; + + item.LocalExtra.Clear(); + item.CentralExtra.Clear(); + + if (isAesMode) + AddAesExtra(item, aesKeyMode, compressingResult.Method); +} + + +#ifndef Z7_ST + +struct CMtSem +{ + NWindows::NSynchronization::CSemaphore Semaphore; + NWindows::NSynchronization::CCriticalSection CS; + CIntVector Indexes; + int Head; + + void ReleaseItem(unsigned index) + { + { + CCriticalSectionLock lock(CS); + Indexes[index] = Head; + Head = (int)index; + } + Semaphore.Release(); + } + + int GetFreeItem() + { + int i; + { + CCriticalSectionLock lock(CS); + i = Head; + Head = Indexes[(unsigned)i]; + } + return i; + } +}; + +static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo); + +struct CThreadInfo +{ + DECL_EXTERNAL_CODECS_LOC_VARS_DECL + + NWindows::CThread Thread; + NWindows::NSynchronization::CAutoResetEvent CompressEvent; + CMtSem *MtSem; + unsigned ThreadIndex; + + bool ExitThread; + + CMtCompressProgress *ProgressSpec; + CMyComPtr Progress; + + COutMemStream *OutStreamSpec; + CMyComPtr OutStream; + CMyComPtr InStream; + + CAddCommon Coder; + HRESULT Result; + CCompressingResult CompressingResult; + + bool IsFree; + bool InSeqMode; + bool OutSeqMode; + bool ExpectedDataSize_IsConfirmed; + + UInt32 UpdateIndex; + UInt32 FileTime; + UInt64 ExpectedDataSize; + + CThreadInfo(): + MtSem(NULL), + ExitThread(false), + ProgressSpec(NULL), + OutStreamSpec(NULL), + IsFree(true), + InSeqMode(false), + OutSeqMode(false), + ExpectedDataSize_IsConfirmed(false), + FileTime(0), + ExpectedDataSize((UInt64)(Int64)-1) + {} + + void SetOptions(const CCompressionMethodMode &options) + { + Coder.SetOptions(options); + } + + HRESULT CreateEvents() + { + const WRes wres = CompressEvent.CreateIfNotCreated_Reset(); + return HRESULT_FROM_WIN32(wres); + } + + // (group < 0) means no_group. + HRESULT CreateThread_with_group( +#ifdef _WIN32 + int group +#endif + ) + { + // tested in win10: If thread is created by another thread, + // child thread probably uses same group as parent thread. + // So we don't need to send (group) to encoder in created thread. + const WRes wres = +#ifdef _WIN32 + group >= 0 ? + Thread.Create_With_Group(CoderThread, this, (unsigned)group) : +#endif + Thread.Create(CoderThread, this); + return HRESULT_FROM_WIN32(wres); + } + + void WaitAndCode(); + + void StopWait_Close() + { + ExitThread = true; + if (OutStreamSpec) + OutStreamSpec->StopWriting(E_ABORT); + if (CompressEvent.IsCreated()) + CompressEvent.Set(); + Thread.Wait_Close(); + } +}; + +void CThreadInfo::WaitAndCode() +{ + for (;;) + { + CompressEvent.Lock(); + if (ExitThread) + return; + + Result = Coder.Compress( + EXTERNAL_CODECS_LOC_VARS + InStream, OutStream, + InSeqMode, OutSeqMode, FileTime, ExpectedDataSize, + ExpectedDataSize_IsConfirmed, + Progress, CompressingResult); + + if (Result == S_OK && Progress) + Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize); + + MtSem->ReleaseItem(ThreadIndex); + } +} + +static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo) +{ + ((CThreadInfo *)threadCoderInfo)->WaitAndCode(); + return 0; +} + +class CThreads +{ +public: + CObjectVector Threads; + ~CThreads() + { + FOR_VECTOR (i, Threads) + Threads[i].StopWait_Close(); + } +}; + +struct CMemBlocks2: public CMemLockBlocks +{ + bool Skip; + bool InSeqMode; + bool PreDescriptorMode; + bool Finished; + CCompressingResult CompressingResult; + + CMemBlocks2(): Skip(false), InSeqMode(false), PreDescriptorMode(false), Finished(false), + CompressingResult() {} +}; + +class CMemRefs +{ +public: + CMemBlockManagerMt *Manager; + CObjectVector Refs; + CMemRefs(CMemBlockManagerMt *manager): Manager(manager) {} + ~CMemRefs() + { + FOR_VECTOR (i, Refs) + Refs[i].FreeOpt(Manager); + } +}; + + +Z7_CLASS_IMP_NOQIB_1( + CMtProgressMixer2 + , ICompressProgressInfo +) + UInt64 ProgressOffset; + UInt64 InSizes[2]; + UInt64 OutSizes[2]; + CMyComPtr Progress; + CMyComPtr RatioProgress; + bool _inSizeIsMain; +public: + NWindows::NSynchronization::CCriticalSection CriticalSection; + void Create(IProgress *progress, bool inSizeIsMain); + void SetProgressOffset(UInt64 progressOffset); + void SetProgressOffset_NoLock(UInt64 progressOffset); + HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize); +}; + +void CMtProgressMixer2::Create(IProgress *progress, bool inSizeIsMain) +{ + Progress = progress; + Progress.QueryInterface(IID_ICompressProgressInfo, &RatioProgress); + _inSizeIsMain = inSizeIsMain; + ProgressOffset = InSizes[0] = InSizes[1] = OutSizes[0] = OutSizes[1] = 0; +} + +void CMtProgressMixer2::SetProgressOffset_NoLock(UInt64 progressOffset) +{ + InSizes[1] = OutSizes[1] = 0; + ProgressOffset = progressOffset; +} + +void CMtProgressMixer2::SetProgressOffset(UInt64 progressOffset) +{ + CriticalSection.Enter(); + SetProgressOffset_NoLock(progressOffset); + CriticalSection.Leave(); +} + +HRESULT CMtProgressMixer2::SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + if (index == 0 && RatioProgress) + { + RINOK(RatioProgress->SetRatioInfo(inSize, outSize)) + } + if (inSize) + InSizes[index] = *inSize; + if (outSize) + OutSizes[index] = *outSize; + UInt64 v = ProgressOffset + (_inSizeIsMain ? + (InSizes[0] + InSizes[1]) : + (OutSizes[0] + OutSizes[1])); + return Progress->SetCompleted(&v); +} + +Z7_COM7F_IMF(CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + return SetRatioInfo(0, inSize, outSize); +} + + +Z7_CLASS_IMP_NOQIB_1( + CMtProgressMixer + , ICompressProgressInfo +) +public: + CMtProgressMixer2 *Mixer2; + CMyComPtr RatioProgress; + void Create(IProgress *progress, bool inSizeIsMain); +}; + +void CMtProgressMixer::Create(IProgress *progress, bool inSizeIsMain) +{ + Mixer2 = new CMtProgressMixer2; + RatioProgress = Mixer2; + Mixer2->Create(progress, inSizeIsMain); +} + +Z7_COM7F_IMF(CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + return Mixer2->SetRatioInfo(1, inSize, outSize); +} + + +#endif + +static HRESULT UpdateItemOldData( + COutArchive &archive, + CInArchive *inArchive, + const CItemEx &itemEx, + const CUpdateItem &ui, + CItemOut &item, + /* bool izZip64, */ + ICompressProgressInfo *progress, + IArchiveUpdateCallbackFile *opCallback, + UInt64 &complexity) +{ + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, (UInt32)ui.IndexInArc, + NUpdateNotifyOp::kReplicate)) + } + + UInt64 rangeSize; + + RINOK(archive.ClearRestriction()) + + if (ui.NewProps) + { + if (item.HasDescriptor()) + { + // we know compressed / uncompressed sizes and crc. + // so we remove descriptor here + item.Flags = (UInt16)(item.Flags & ~NFileHeader::NFlags::kDescriptorUsedMask); + // return E_NOTIMPL; + } + // we keep ExternalAttrib and some another properties from old archive + // item.ExternalAttrib = ui.Attrib; + // if we don't change Comment, we keep Comment from OldProperties + Copy_From_UpdateItem_To_ItemOut(ui, item); + // item.SetFlag_AltStream(ui.IsAltStream); + + item.CentralExtra.RemoveUnknownSubBlocks(); + item.LocalExtra.RemoveUnknownSubBlocks(); + + archive.WriteLocalHeader(item); + rangeSize = item.GetPackSizeWithDescriptor(); + } + else + { + item.LocalHeaderPos = archive.GetCurPos(); + rangeSize = itemEx.GetLocalFullSize(); + } + + CMyComPtr packStream; + + RINOK(inArchive->GetItemStream(itemEx, ui.NewProps, packStream)) + if (!packStream) + return E_NOTIMPL; + + complexity += rangeSize; + + CMyComPtr outStream; + archive.CreateStreamForCopying(outStream); + HRESULT res = NCompress::CopyStream_ExactSize(packStream, outStream, rangeSize, progress); + archive.MoveCurPos(rangeSize); + return res; +} + + +static HRESULT WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options, + const CUpdateItem &ui, CItemOut &item) +{ + SetFileHeader(*options, ui, false, item); + RINOK(archive.ClearRestriction()) + archive.WriteLocalHeader(item); + return S_OK; +} + + +static void UpdatePropsFromStream( + const CUpdateOptions &options, + CUpdateItem &item, ISequentialInStream *fileInStream, + IArchiveUpdateCallback *updateCallback, UInt64 &totalComplexity) +{ + CMyComPtr getProps; + fileInStream->QueryInterface(IID_IStreamGetProps, (void **)&getProps); + UInt64 size = (UInt64)(Int64)-1; + bool size_WasSet = false; + + if (getProps) + { + FILETIME cTime, aTime, mTime; + UInt32 attrib; + if (getProps->GetProps(&size, &cTime, &aTime, &mTime, &attrib) == S_OK) + { + if (options.Write_MTime) + if (!FILETIME_IsZero(mTime)) + { + item.Ntfs_MTime = mTime; + NTime::UtcFileTime_To_LocalDosTime(mTime, item.Time); + } + + 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; + size_WasSet = true; + } + } + + if (!size_WasSet) + { + CMyComPtr streamGetSize; + fileInStream->QueryInterface(IID_IStreamGetSize, (void **)&streamGetSize); + if (streamGetSize) + { + if (streamGetSize->GetSize(&size) == S_OK) + size_WasSet = true; + } + } + + if (size_WasSet && size != (UInt64)(Int64)-1) + { + item.Size_WasSetFromStream = true; + if (size != item.Size) + { + const Int64 newComplexity = (Int64)totalComplexity + ((Int64)size - (Int64)item.Size); + if (newComplexity > 0) + { + totalComplexity = (UInt64)newComplexity; + updateCallback->SetTotal(totalComplexity); + } + item.Size = size; + } + } +} + + +/* +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 + // , IArchiveUpdateCallbackArcProp *reportArcProp + ) +{ + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(updateCallback, true); + + CAddCommon compressor; + compressor.SetOptions(*options); + + CObjectVector items; + UInt64 unpackSizeTotal = 0, packSizeTotal = 0; + + FOR_VECTOR (itemIndex, updateItems) + { + lps->InSize = unpackSizeTotal; + lps->OutSize = packSizeTotal; + RINOK(lps->SetCur()) + CUpdateItem &ui = updateItems[itemIndex]; + CItemEx itemEx; + CItemOut item; + + if (!ui.NewProps || !ui.NewData) + { + // Note: for (ui.NewProps && !ui.NewData) it copies Props from old archive, + // But we will rewrite all important properties later. But we can keep some properties like Comment + itemEx = inputItems[(unsigned)ui.IndexInArc]; + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) + return E_NOTIMPL; + (CItem &)item = itemEx; + } + + if (ui.NewData) + { + // bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); + bool isDir = ui.IsDir; + if (isDir) + { + RINOK(WriteDirHeader(archive, options, ui, item)) + } + else + { + CMyComPtr fileInStream; + { + HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); + if (res == S_FALSE) + { + lps->ProgressOffset += ui.Size; + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + continue; + } + RINOK(res) + if (!fileInStream) + return E_INVALIDARG; + + bool inSeqMode = false; + if (!inSeqMode) + { + CMyComPtr inStream2; + fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2); + inSeqMode = (inStream2 == NULL); + } + // seqMode = true; // to test seqMode + + UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity); + + CCompressingResult compressingResult; + + RINOK(compressor.Set_Pre_CompressionResult( + inSeqMode, outSeqMode, + ui.Size, + compressingResult)) + + SetFileHeader(*options, ui, compressingResult.DescriptorMode, item); + + // file Size can be 64-bit !!! + + SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item); + + RINOK(archive.SetRestrictionFromCurrent()) + archive.WriteLocalHeader(item); + + CMyComPtr outStream; + archive.CreateStreamForCompressing(outStream); + + RINOK(compressor.Compress( + EXTERNAL_CODECS_LOC_VARS + fileInStream, outStream, + inSeqMode, outSeqMode, + ui.Time, + ui.Size, ui.Size_WasSetFromStream, + progress, compressingResult)) + + if (item.HasDescriptor() != compressingResult.DescriptorMode) + return E_FAIL; + + SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item); + + archive.WriteLocalHeader_Replace(item); + } + // if (reportArcProp) RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options->IsRealAesMode())) + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + unpackSizeTotal += item.Size; + packSizeTotal += item.PackSize; + } + } + else + { + UInt64 complexity = 0; + lps->SendRatio = false; + + RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)) + + lps->SendRatio = true; + lps->ProgressOffset += complexity; + } + + items.Add(item); + lps->ProgressOffset += kLocalHeaderSize; + } + + lps->InSize = unpackSizeTotal; + lps->OutSize = packSizeTotal; + RINOK(lps->SetCur()) + + RINOK(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(); +} + +#ifndef Z7_ST + + +static const size_t kBlockSize = 1 << 16; +// kMemPerThread must be >= kBlockSize +// +static const size_t kMemPerThread = (size_t)sizeof(size_t) << 23; +// static const size_t kMemPerThread = (size_t)sizeof(size_t) << 16; // for debug +// static const size_t kMemPerThread = (size_t)1 << 16; // for debug + +/* +in: + nt_Zip >= 1: the starting maximum number of ZIP threads for search +out: + nt_Zip: calculated number of ZIP threads + returns: calculated number of ZSTD threads +*/ +/* +static UInt32 CalcThreads_for_ZipZstd(CZstdEncProps *zstdProps, + UInt64 memLimit, UInt32 totalThreads, + UInt32 &nt_Zip) +{ + for (; nt_Zip > 1; nt_Zip--) + { + UInt64 mem1 = memLimit / nt_Zip; + if (mem1 <= kMemPerThread) + continue; + mem1 -= kMemPerThread; + UInt32 n_ZSTD = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + zstdProps, mem1, totalThreads / nt_Zip); + // we don't allow (nbWorkers == 1) here + if (n_ZSTD <= 1) + n_ZSTD = 0; + zstdProps->nbWorkers = n_ZSTD; + mem1 = ZstdEncProps_GetMemUsage(zstdProps); + if ((mem1 + kMemPerThread) * nt_Zip <= memLimit) + return n_ZSTD; + } + return ZstdEncProps_GetNumThreads_for_MemUsageLimit( + zstdProps, memLimit, totalThreads); +} + + +static UInt32 SetZstdThreads( + const CCompressionMethodMode &options, + COneMethodInfo *oneMethodMain, + UInt32 numThreads, + UInt32 numZipThreads_limit, + UInt64 numFilesToCompress, + UInt64 numBytesToCompress) +{ + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(encoderProps.SetFromMethodProps(*oneMethodMain)); + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + if (oneMethodMain->FindProp(NCoderPropID::kNumThreads) >= 0) + { + // threads for ZSTD are fixed + if (zstdProps.nbWorkers > 1) + numThreads /= zstdProps.nbWorkers; + if (numThreads > numZipThreads_limit) + numThreads = numZipThreads_limit; + if (options._memUsage_WasSet + && !options._numThreads_WasForced) + { + const UInt64 mem1 = ZstdEncProps_GetMemUsage(&zstdProps); + const UInt64 numZipThreads = options._memUsage_Compress / (mem1 + kMemPerThread); + if (numThreads > numZipThreads) + numThreads = (UInt32)numZipThreads; + } + return numThreads; + } + { + // threads for ZSTD are not fixed + + // calculate estimated required number of ZST threads per file size statistics + UInt32 t = MY_ZSTDMT_NBWORKERS_MAX; + { + UInt64 averageNumberOfBlocks = 0; + const UInt64 averageSize = numBytesToCompress / numFilesToCompress; + const UInt64 jobSize = zstdProps.jobSize; + if (jobSize != 0) + averageNumberOfBlocks = averageSize / jobSize + 0; + if (t > averageNumberOfBlocks) + t = (UInt32)averageNumberOfBlocks; + } + if (t > numThreads) + t = numThreads; + + // calculate the nuber of zip threads + UInt32 numZipThreads = numThreads; + if (t > 1) + numZipThreads = numThreads / t; + if (numZipThreads > numZipThreads_limit) + numZipThreads = numZipThreads_limit; + if (numZipThreads < 1) + numZipThreads = 1; + { + // recalculate the number of ZSTD threads via the number of ZIP threads + const UInt32 t2 = numThreads / numZipThreads; + if (t < t2) + t = t2; + } + + if (options._memUsage_WasSet + && !options._numThreads_WasForced) + { + t = CalcThreads_for_ZipZstd(&zstdProps, + options._memUsage_Compress, numThreads, numZipThreads); + numThreads = numZipThreads; + } + // we don't use (nbWorkers = 1) here + if (t <= 1) + t = 0; + oneMethodMain->AddProp_NumThreads(t); + return numThreads; + } +} +*/ + +#endif + + + + +static HRESULT Update2( + 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) +{ + CMyComPtr opCallback; + updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + + /* + CMyComPtr reportArcProp; + updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp); + */ + + bool unknownComplexity = false; + UInt64 complexity = 0; + #ifndef Z7_ST + UInt64 numFilesToCompress = 0; + UInt64 numBytesToCompress = 0; + #endif + + unsigned i; + + for (i = 0; i < updateItems.Size(); i++) + { + const CUpdateItem &ui = updateItems[i]; + if (ui.NewData) + { + if (ui.Size == (UInt64)(Int64)-1) + unknownComplexity = true; + else + complexity += ui.Size; + #ifndef Z7_ST + numBytesToCompress += ui.Size; + numFilesToCompress++; + #endif + /* + if (ui.Commented) + complexity += ui.CommentRange.Size; + */ + } + else + { + CItemEx inputItem = inputItems[(unsigned)ui.IndexInArc]; + if (inArchive->Read_LocalItem_After_CdItem_Full(inputItem) != S_OK) + return E_NOTIMPL; + complexity += inputItem.GetLocalFullSize(); + // complexity += inputItem.GetCentralExtraPlusCommentSize(); + } + complexity += kLocalHeaderSize; + complexity += kCentralHeaderSize; + } + + if (comment) + complexity += comment->Size(); + complexity++; // end of central + + if (!unknownComplexity) + updateCallback->SetTotal(complexity); + + UInt64 totalComplexity = complexity; + + CCompressionMethodMode options2 = options; + + if (options2._methods.IsEmpty()) + { + // we need method item, if default method was used + options2._methods.AddNew(); + } + + CAddCommon compressor; + compressor.SetOptions(options2); + + complexity = 0; + + const Byte method = options.MethodSequence.FrontItem(); + + COneMethodInfo *oneMethodMain = NULL; + if (!options2._methods.IsEmpty()) + oneMethodMain = &options2._methods[0]; + + { + FOR_VECTOR (mi, options2._methods) + { + options2.SetGlobalLevelTo(options2._methods[mi]); + } + } + + if (oneMethodMain) + { + // appnote recommends to use EOS marker for LZMA. + if (method == NFileHeader::NCompressionMethod::kLZMA) + oneMethodMain->AddProp_EndMarker_if_NotFound(true); + } + + + #ifndef Z7_ST + + UInt32 numThreads = options._numThreads; +#ifdef _WIN32 + const UInt32 numThreadGroups = options._numThreadGroups; +#endif + + UInt32 numZipThreads_limit = numThreads; + if (numZipThreads_limit > numFilesToCompress) + numZipThreads_limit = (UInt32)numFilesToCompress; + + if (numZipThreads_limit > 1) + { + const unsigned numFiles_OPEN_MAX = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + // printf("\nzip:numFiles_OPEN_MAX =%d\n", (unsigned)numFiles_OPEN_MAX); + if (numZipThreads_limit > numFiles_OPEN_MAX) + numZipThreads_limit = (UInt32)numFiles_OPEN_MAX; + } + + { + // we reduce number of threads for 32-bit to reduce memory usege to 256 MB + const UInt32 kNumMaxThreads = + // _WIN32 (64-bit) supports only 64 threads in one group. + 8 << (sizeof(size_t) / 2); // 32 threads for 32-bit : 128 threads for 64-bit + if (numThreads > kNumMaxThreads) + numThreads = kNumMaxThreads; + } + /* + if (numThreads > MAXIMUM_WAIT_OBJECTS) // is 64 in Windows + numThreads = MAXIMUM_WAIT_OBJECTS; + */ + + + /* + // zstd supports (numThreads == 0); + if (numThreads < 1) + numThreads = 1; + */ + + bool mtMode = (numThreads > 1); + + if (numFilesToCompress <= 1) + mtMode = false; + + // mtMode = true; // debug: to test mtMode + + if (!mtMode) + { + // if (oneMethodMain) { + /* + if (method == NFileHeader::NCompressionMethod::kZstdWz) + { + if (oneMethodMain->FindProp(NCoderPropID::kNumThreads) < 0) + { + // numZstdThreads was not forced in oneMethodMain + if (numThreads >= 1 + && options._memUsage_WasSet + && !options._numThreads_WasForced) + { + NCompress::NZstd::CEncoderProps encoderProps; + RINOK(encoderProps.SetFromMethodProps(*oneMethodMain)) + CZstdEncProps &zstdProps = encoderProps.EncProps; + ZstdEncProps_NormalizeFull(&zstdProps); + numThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps, options._memUsage_Compress, numThreads); + // we allow (nbWorkers = 1) here. + } + oneMethodMain->AddProp_NumThreads(numThreads); + } + } // kZstdWz + */ + // } // oneMethodMain + + FOR_VECTOR (mi, options2._methods) + { + COneMethodInfo &onem = options2._methods[mi]; + + if (onem.FindProp(NCoderPropID::kNumThreads) < 0) + { + // fixme: we should check the number of threads for xz method also + // fixed for 9.31. bzip2 default is just one thread. + onem.AddProp_NumThreads(numThreads); + } + } + } + else // mtMode + { + if (method == NFileHeader::NCompressionMethod::kStore && !options.Password_Defined) + numThreads = 1; + + if (oneMethodMain) + { + + if (method == NFileHeader::NCompressionMethod::kBZip2) + { + bool fixedNumber; + UInt32 numBZip2Threads = oneMethodMain->Get_BZip2_NumThreads(fixedNumber); + if (!fixedNumber) + { + const UInt64 averageSize = numBytesToCompress / numFilesToCompress; + const UInt32 blockSize = oneMethodMain->Get_BZip2_BlockSize(); + const UInt64 averageNumberOfBlocks = averageSize / blockSize + 1; + numBZip2Threads = 64; + if (numBZip2Threads > averageNumberOfBlocks) + numBZip2Threads = (UInt32)averageNumberOfBlocks; + if (numBZip2Threads > numThreads) + numBZip2Threads = numThreads; + oneMethodMain->AddProp_NumThreads(numBZip2Threads); + } + numThreads /= numBZip2Threads; + } + else if (method == NFileHeader::NCompressionMethod::kXz) + { + UInt32 numLzmaThreads = 1; + int numXzThreads = oneMethodMain->Get_Xz_NumThreads(numLzmaThreads); + if (numXzThreads < 0) + { + // numXzThreads is unknown + const UInt64 averageSize = numBytesToCompress / numFilesToCompress; + const UInt64 blockSize = oneMethodMain->Get_Xz_BlockSize(); + UInt64 averageNumberOfBlocks = 1; + if (blockSize != (UInt64)(Int64)-1) + averageNumberOfBlocks = averageSize / blockSize + 1; + UInt32 t = 256; + if (t > averageNumberOfBlocks) + t = (UInt32)averageNumberOfBlocks; + t *= numLzmaThreads; + if (t > numThreads) + t = numThreads; + oneMethodMain->AddProp_NumThreads(t); + numXzThreads = (int)t; + } + numThreads /= (unsigned)numXzThreads; + } + /* + else if (method == NFileHeader::NCompressionMethod::kZstdWz) + { + numThreads = SetZstdThreads(options, + oneMethodMain, numThreads, + numZipThreads_limit, + numFilesToCompress, numBytesToCompress); + } + */ + else if ( + method == NFileHeader::NCompressionMethod::kDeflate + || method == NFileHeader::NCompressionMethod::kDeflate64 + || method == NFileHeader::NCompressionMethod::kPPMd) + { + if (numThreads > 1 + && options._memUsage_WasSet + && !options._numThreads_WasForced) + { + UInt64 methodMemUsage; + if (method == NFileHeader::NCompressionMethod::kPPMd) + methodMemUsage = oneMethodMain->Get_Ppmd_MemSize(); + else + methodMemUsage = (4 << 20); // for deflate + const UInt64 threadMemUsage = kMemPerThread + methodMemUsage; + const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage; + if (numThreads64 < numThreads) + numThreads = (UInt32)numThreads64; + } + } + else if (method == NFileHeader::NCompressionMethod::kLZMA) + { + // we suppose that default LZMA is 2 thread. So we don't change it + const UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads(); + numThreads /= numLZMAThreads; + + if (numThreads > 1 + && options._memUsage_WasSet + && !options._numThreads_WasForced) + { + const UInt64 methodMemUsage = oneMethodMain->Get_Lzma_MemUsage(true); + const UInt64 threadMemUsage = kMemPerThread + methodMemUsage; + const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage; + if (numThreads64 < numThreads) + numThreads = (UInt32)numThreads64; + } + } + } // (oneMethodMain) + + if (numThreads > numZipThreads_limit) + numThreads = numZipThreads_limit; + if (numThreads <= 1) + { + mtMode = false; + numThreads = 1; + } + } + + // mtMode = true; // to test mtMode for seqMode + + if (!mtMode) + #endif + return Update2St( + EXTERNAL_CODECS_LOC_VARS + archive, inArchive, + inputItems, updateItems, + updateOptions, + &options2, outSeqMode, + comment, updateCallback, totalComplexity, + opCallback + // , reportArcProp + ); + + + #ifndef Z7_ST + + /* + CTotalStats stat; + stat.Size = 0; + stat.PackSize = 0; + */ + if (numThreads < 1) + numThreads = 1; + + CObjectVector items; + + CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer; + CMyComPtr progress = mtProgressMixerSpec; + mtProgressMixerSpec->Create(updateCallback, true); + + CMtCompressProgressMixer mtCompressProgressMixer; + mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress); + + CMemBlockManagerMt memManager(kBlockSize); + CMemRefs refs(&memManager); + + CMtSem mtSem; + CThreads threads; + mtSem.Head = -1; + mtSem.Indexes.ClearAndSetSize(numThreads); + { + WRes wres = mtSem.Semaphore.Create(0, numThreads); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + + CUIntVector threadIndices; // list threads in order of updateItems + + { + RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize))) + for (i = 0; i < updateItems.Size(); i++) + refs.Refs.Add(CMemBlocks2()); + + for (i = 0; i < numThreads; i++) + { + threads.Threads.AddNew(); + // mtSem.Indexes[i] = -1; // actually we don't use these values + } + + for (i = 0; i < numThreads; i++) + { + CThreadInfo &threadInfo = threads.Threads[i]; + threadInfo.ThreadIndex = i; + threadInfo.SetOptions(options2); + #ifdef Z7_EXTERNAL_CODECS + threadInfo._externalCodecs = _externalCodecs; + #endif + RINOK(threadInfo.CreateEvents()) + threadInfo.OutStreamSpec = new COutMemStream(&memManager); + RINOK(threadInfo.OutStreamSpec->CreateEvents(SYNC_WFMO(&memManager.Synchro))) + threadInfo.OutStream = threadInfo.OutStreamSpec; + threadInfo.ProgressSpec = new CMtCompressProgress(); + threadInfo.Progress = threadInfo.ProgressSpec; + threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, i); + threadInfo.MtSem = &mtSem; + const HRESULT hres = + threadInfo.CreateThread_with_group( +#ifdef _WIN32 + (numThreadGroups > 1 && numThreads > 1) ? + (int)(i % numThreadGroups) : -1 +#endif + ); + RINOK(hres) + } + } + + unsigned mtItemIndex = 0; + unsigned itemIndex = 0; + int lastRealStreamItemIndex = -1; + + + while (itemIndex < updateItems.Size()) + { + if (threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size()) + { + // we start ahead the threads for compressing + // also we set refs.Refs[itemIndex].SeqMode that is used later + // don't move that code block + + CUpdateItem &ui = updateItems[mtItemIndex++]; + if (!ui.NewData) + continue; + CItemEx itemEx; + CItemOut item; + + if (ui.NewProps) + { + if (ui.IsDir) + continue; + } + else + { + itemEx = inputItems[(unsigned)ui.IndexInArc]; + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) + return E_NOTIMPL; + (CItem &)item = itemEx; + if (item.IsDir() != ui.IsDir) + return E_NOTIMPL; + if (ui.IsDir) + continue; + } + + CMyComPtr fileInStream; + + CMemBlocks2 &memRef2 = refs.Refs[mtItemIndex - 1]; + + { + NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection); + const HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream); + if (res == S_FALSE) + { + complexity += ui.Size; + complexity += kLocalHeaderSize; + mtProgressMixerSpec->Mixer2->SetProgressOffset_NoLock(complexity); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + memRef2.Skip = true; + continue; + } + RINOK(res) + if (!fileInStream) + return E_INVALIDARG; + UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity); + RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + } + + UInt32 k; + for (k = 0; k < numThreads; k++) + if (threads.Threads[k].IsFree) + break; + + if (k == numThreads) + return E_FAIL; + { + { + CThreadInfo &threadInfo = threads.Threads[k]; + threadInfo.IsFree = false; + threadInfo.InStream = fileInStream; + + bool inSeqMode = false; + + if (!inSeqMode) + { + CMyComPtr inStream2; + fileInStream->QueryInterface(IID_IInStream, (void **)&inStream2); + inSeqMode = (inStream2 == NULL); + } + memRef2.InSeqMode = inSeqMode; + + // !!!!! we must release ref before sending event + // BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time + fileInStream.Release(); + + threadInfo.OutStreamSpec->Init(); + threadInfo.ProgressSpec->Reinit(); + + threadInfo.UpdateIndex = mtItemIndex - 1; + threadInfo.InSeqMode = inSeqMode; + threadInfo.OutSeqMode = outSeqMode; + threadInfo.FileTime = ui.Time; // FileTime is used for ZipCrypto only in seqMode + threadInfo.ExpectedDataSize = ui.Size; + threadInfo.ExpectedDataSize_IsConfirmed = ui.Size_WasSetFromStream; + + threadInfo.CompressEvent.Set(); + + threadIndices.Add(k); + } + } + + continue; + } + + if (refs.Refs[itemIndex].Skip) + { + itemIndex++; + continue; + } + + const CUpdateItem &ui = updateItems[itemIndex]; + + CItemEx itemEx; + CItemOut item; + + if (!ui.NewProps || !ui.NewData) + { + itemEx = inputItems[(unsigned)ui.IndexInArc]; + if (inArchive->Read_LocalItem_After_CdItem_Full(itemEx) != S_OK) + return E_NOTIMPL; + (CItem &)item = itemEx; + } + + if (ui.NewData) + { + // bool isDir = ((ui.NewProps) ? ui.IsDir : item.IsDir()); + const bool isDir = ui.IsDir; + + if (isDir) + { + RINOK(WriteDirHeader(archive, &options, ui, item)) + } + else + { + CMemBlocks2 &memRef = refs.Refs[itemIndex]; + + if (memRef.Finished) + { + if (lastRealStreamItemIndex < (int)itemIndex) + lastRealStreamItemIndex = (int)itemIndex; + + SetFileHeader(options, ui, memRef.CompressingResult.DescriptorMode, item); + + // the BUG was fixed in 9.26: + // SetItemInfoFromCompressingResult must be after SetFileHeader + // to write correct Size. + + SetItemInfoFromCompressingResult(memRef.CompressingResult, + options.IsRealAesMode(), options.AesKeyMode, item); + RINOK(archive.ClearRestriction()) + archive.WriteLocalHeader(item); + // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); + CMyComPtr outStream; + archive.CreateStreamForCopying(outStream); + memRef.WriteToStream(memManager.GetBlockSize(), outStream); + // v23: we fixed the bug: we need to write descriptor also + if (item.HasDescriptor()) + { + /* that function doesn't rewrite local header, if item.HasDescriptor(). + it just writes descriptor */ + archive.WriteLocalHeader_Replace(item); + } + else + archive.MoveCurPos(item.PackSize); + memRef.FreeOpt(&memManager); + /* + if (reportArcProp) + { + stat.UpdateWithItem(item); + RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode())); + } + */ + } + else + { + // current file was not finished + + if (lastRealStreamItemIndex < (int)itemIndex) + { + // LocalHeader was not written for current itemIndex still + + lastRealStreamItemIndex = (int)itemIndex; + + // thread was started before for that item already, and memRef.SeqMode was set + + CCompressingResult compressingResult; + RINOK(compressor.Set_Pre_CompressionResult( + memRef.InSeqMode, outSeqMode, + ui.Size, + compressingResult)) + + memRef.PreDescriptorMode = compressingResult.DescriptorMode; + SetFileHeader(options, ui, compressingResult.DescriptorMode, item); + + SetItemInfoFromCompressingResult(compressingResult, options.IsRealAesMode(), options.AesKeyMode, item); + + // file Size can be 64-bit !!! + RINOK(archive.SetRestrictionFromCurrent()) + archive.WriteLocalHeader(item); + } + + { + CThreadInfo &thread = threads.Threads[threadIndices.FrontItem()]; + if (!thread.OutStreamSpec->WasUnlockEventSent()) + { + CMyComPtr outStream; + archive.CreateStreamForCompressing(outStream); + thread.OutStreamSpec->SetOutStream(outStream); + thread.OutStreamSpec->SetRealStreamMode(); + } + } + + const WRes wres = mtSem.Semaphore.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + + const int ti = mtSem.GetFreeItem(); + if (ti < 0) + return E_FAIL; + + CThreadInfo &threadInfo = threads.Threads[(unsigned)ti]; + threadInfo.InStream.Release(); + threadInfo.IsFree = true; + RINOK(threadInfo.Result) + + unsigned t = 0; + + for (;;) + { + if (t == threadIndices.Size()) + return E_FAIL; + if (threadIndices[t] == (unsigned)ti) + break; + t++; + } + threadIndices.Delete(t); + + if (t == 0) + { + // if thread for current file was finished. + if (threadInfo.UpdateIndex != itemIndex) + return E_FAIL; + + if (memRef.PreDescriptorMode != threadInfo.CompressingResult.DescriptorMode) + return E_FAIL; + + RINOK(threadInfo.OutStreamSpec->WriteToRealStream()) + threadInfo.OutStreamSpec->ReleaseOutStream(); + SetFileHeader(options, ui, threadInfo.CompressingResult.DescriptorMode, item); + SetItemInfoFromCompressingResult(threadInfo.CompressingResult, + options.IsRealAesMode(), options.AesKeyMode, item); + + archive.WriteLocalHeader_Replace(item); + + /* + if (reportArcProp) + { + stat.UpdateWithItem(item); + RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode())); + } + */ + } + else + { + // it's not current file. So we must store information in array + CMemBlocks2 &memRef2 = refs.Refs[threadInfo.UpdateIndex]; + threadInfo.OutStreamSpec->DetachData(memRef2); + memRef2.CompressingResult = threadInfo.CompressingResult; + // memRef2.SeqMode = threadInfo.SeqMode; // it was set before + memRef2.Finished = true; + continue; + } + } + } + } + else + { + RINOK(UpdateItemOldData(archive, inArchive, itemEx, ui, item, progress, opCallback, complexity)) + } + + items.Add(item); + complexity += kLocalHeaderSize; + mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity); + itemIndex++; + } + + RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL)) + + RINOK(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); + + #endif +} + +/* +// we need CSeekOutStream, if we need Seek(0, STREAM_SEEK_CUR) for seqential stream +Z7_CLASS_IMP_COM_1( + CSeekOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + CMyComPtr _seqStream; + UInt64 _size; +public: + void Init(ISequentialOutStream *seqStream) + { + _size = 0; + _seqStream = seqStream; + } +}; + +Z7_COM7F_IMF(CSeekOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + const HRESULT result = _seqStream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +Z7_COM7F_IMF(CSeekOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (seekOrigin != STREAM_SEEK_CUR || offset != 0) + return E_NOTIMPL; + if (newPosition) + *newPosition = (UInt64)_size; + return S_OK; +} + +Z7_COM7F_IMF(CSeekOutStream::SetSize(UInt64 newSize)) +{ + UNUSED_VAR(newSize) + return E_NOTIMPL; +} +*/ + +static const size_t kCacheBlockSize = 1 << 20; +static const size_t kCacheSize = kCacheBlockSize << 2; +static const size_t kCacheMask = kCacheSize - 1; + +Z7_CLASS_IMP_NOQIB_2( + CCacheOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + HRESULT _hres; + CMyComPtr _seqStream; + CMyComPtr _stream; + CMyComPtr _setRestriction; + Byte *_cache; + size_t _cachedSize; + UInt64 _cachedPos; + UInt64 _virtPos; + UInt64 _virtSize; + UInt64 _phyPos; + UInt64 _phySize; + UInt64 _restrict_begin; + UInt64 _restrict_end; + + HRESULT FlushFromCache(size_t size); + HRESULT FlushNonRestrictedBlocks(); + HRESULT FlushCache(); + HRESULT SetRestriction_ForWrite(size_t writeSize) const; + + HRESULT SeekPhy(UInt64 pos) + { + if (pos == _phyPos) + return S_OK; + if (!_stream) + return E_NOTIMPL; + _hres = _stream->Seek((Int64)pos, STREAM_SEEK_SET, &_phyPos); + if (_hres == S_OK && _phyPos != pos) + _hres = E_FAIL; + return _hres; + } + +public: + CCacheOutStream(): _cache(NULL) {} + ~CCacheOutStream(); + bool Allocate() + { + if (!_cache) + _cache = (Byte *)::MidAlloc(kCacheSize); + return _cache != NULL; + } + HRESULT Init(ISequentialOutStream *seqStream, IOutStream *stream, IStreamSetRestriction *setRestriction); + HRESULT FinalFlush(); +}; + +CCacheOutStream::~CCacheOutStream() +{ + ::MidFree(_cache); +} + + +HRESULT CCacheOutStream::Init(ISequentialOutStream *seqStream, IOutStream *stream, IStreamSetRestriction *setRestriction) +{ + _hres = S_OK; + _cachedSize = 0; + _cachedPos = 0; + _virtPos = 0; + _virtSize = 0; + // by default we have no restriction + _restrict_begin = 0; + _restrict_end = 0; + _seqStream = seqStream; + _stream = stream; + _setRestriction = setRestriction; + if (_stream) + { + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &_virtPos)) + RINOK(_stream->Seek(0, STREAM_SEEK_END, &_virtSize)) + RINOK(_stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, &_virtPos)) + } + _phyPos = _virtPos; + _phySize = _virtSize; + return S_OK; +} + + +/* we call SetRestriction_ForWrite() just before Write() from cache. + (_phyPos == _cachedPos) + (writeSize != 0) +*/ +HRESULT CCacheOutStream::SetRestriction_ForWrite(size_t writeSize) const +{ + if (!_setRestriction) + return S_OK; + PRF(printf("\n-- CCacheOutStream::SetRestriction_ForWrite _cachedPos = 0x%x, writeSize = %d\n", (unsigned)_cachedPos, (unsigned)writeSize)); + UInt64 begin = _restrict_begin; + UInt64 end = _restrict_end; + const UInt64 phyPos = _phyPos; + if (phyPos != _cachedPos) return E_FAIL; + if (phyPos == _phySize) + { + // The writing will be to the end of phy stream. + // So we will try to use non-restricted write, if possible. + if (begin == end) + begin = _virtPos; // _virtSize; // it's supposed that (_virtSize == _virtPos) + if (phyPos + writeSize <= begin) + { + // the write is not restricted + PRF(printf("\n+++ write is not restricted \n")); + begin = 0; + end = 0; + } + else + { + if (begin > phyPos) + begin = phyPos; + end = (UInt64)(Int64)-1; + } + } + else + { + // (phyPos != _phySize) + if (begin == end || begin > phyPos) + begin = phyPos; + end = (UInt64)(Int64)-1; + } + return _setRestriction->SetRestriction(begin, end); +} + + +/* it writes up to (size) bytes from cache. + (size > _cachedSize) is allowed +*/ +HRESULT CCacheOutStream::FlushFromCache(size_t size) +{ + PRF(printf("\n-- CCacheOutStream::FlushFromCache %u\n", (unsigned)size)); + if (_hres != S_OK) + return _hres; + if (size > _cachedSize) + size = _cachedSize; + // (size <= _cachedSize) + if (size == 0) + return S_OK; + RINOK(SeekPhy(_cachedPos)) + for (;;) + { + // (_phyPos == _cachedPos) + const size_t pos = (size_t)_cachedPos & kCacheMask; + const size_t cur = MyMin(kCacheSize - pos, size); + _hres = SetRestriction_ForWrite(cur); + RINOK(_hres) + PRF(printf("\n-- CCacheOutStream::WriteFromCache _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)cur)); + _hres = WriteStream(_seqStream, _cache + pos, cur); + RINOK(_hres) + _phyPos += cur; + if (_phySize < _phyPos) + _phySize = _phyPos; + _cachedPos += cur; + _cachedSize -= cur; + size -= cur; + if (size == 0) + return S_OK; + } +} + + +HRESULT CCacheOutStream::FlushNonRestrictedBlocks() +{ + for (;;) + { + const size_t size = kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1)); + if (_cachedSize < size) + break; + UInt64 begin = _restrict_begin; + if (begin == _restrict_end) + begin = _virtPos; + // we don't flush the data to restricted area + if (_cachedPos + size > begin) + break; + RINOK(FlushFromCache(size)) + } + return S_OK; +} + + +HRESULT CCacheOutStream::FlushCache() +{ + return FlushFromCache(_cachedSize); +} + +HRESULT CCacheOutStream::FinalFlush() +{ + _restrict_begin = 0; + _restrict_end = 0; + RINOK(FlushCache()) + if (_stream && _hres == S_OK) + { + if (_virtSize != _phySize) + { + // it's unexpected + RINOK(_stream->SetSize(_virtSize)) + _phySize = _virtSize; + } + _hres = SeekPhy(_virtPos); + } + return _hres; +} + + +Z7_COM7F_IMF(CCacheOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + PRF(printf("\n==== CCacheOutStream::Write virtPos=0x%x, %u\n", (unsigned)_virtPos, (unsigned)size)); + + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_hres != S_OK) + return _hres; + + if (_cachedSize != 0) + if (_virtPos < _cachedPos || + _virtPos > _cachedPos + _cachedSize) + { + RINOK(FlushCache()) + } + + if (_cachedSize == 0) + _cachedPos = _virtPos; + + const size_t pos = (size_t)_virtPos & kCacheMask; + { + const size_t blockRem = kCacheBlockSize - ((size_t)_virtPos & (kCacheBlockSize - 1)); + if (size > blockRem) + size = (UInt32)blockRem; + } + // _cachedPos <= _virtPos <= _cachedPos + _cachedSize + const UInt64 cachedRem = _cachedPos + _cachedSize - _virtPos; + if (cachedRem) + { + // _virtPos < _cachedPos + _cachedSize + // we rewrite only existing data in cache. So _cachedSize will be not changed + if (size > cachedRem) + size = (UInt32)cachedRem; + } + else + { + // _virtPos == _cachedPos + _cachedSize + // so we need to add new data to the end of cache + if (_cachedSize == kCacheSize) + { + // cache is full. So we need to flush some part of cache. + // we flush only one block, but we are allowed to flush any size here + RINOK(FlushFromCache(kCacheBlockSize - ((size_t)_cachedPos & (kCacheBlockSize - 1)))) + } + // _cachedSize != kCacheSize + // so we have some space for new data in cache + if (_cachedSize == 0) + { + /* this code is optional (for optimization): + we write data directly without cache, + if there is no restriction and we have full block. */ + if (_restrict_begin == _restrict_end + && size == kCacheBlockSize) + { + RINOK(SeekPhy(_virtPos)) + if (_setRestriction) + { + _hres = _setRestriction->SetRestriction(_restrict_begin, _restrict_end); + RINOK(_hres) + } + PRF(printf("\n-- CCacheOutStream::WriteDirectly _phyPos = 0x%x, size = %d\n", (unsigned)_phyPos, (unsigned)size)); + _hres = WriteStream(_seqStream, data, size); + RINOK(_hres) + if (processedSize) + *processedSize = size; + _virtPos += size; + if (_virtSize < _virtPos) + _virtSize = _virtPos; + _phyPos += size; + if (_phySize < _phyPos) + _phySize = _phyPos; + return S_OK; + } + } + else // (_cachedSize != 0) + { + const size_t startPos = (size_t)_cachedPos & kCacheMask; + // we don't allow new data to overwrite old start data in cache. + // (startPos == pos) here means that cache is empty. + // (startPos == pos) is not possible here. + if (startPos > pos) + size = (UInt32)MyMin((size_t)size, (size_t)(startPos - pos)); + } + // _virtPos == (_cachedPos + _cachedSize) still + _cachedSize += size; + } + + memcpy(_cache + pos, data, size); + if (processedSize) + *processedSize = size; + _virtPos += size; + if (_virtSize < _virtPos) + _virtSize = _virtPos; + return FlushNonRestrictedBlocks(); +} + + +Z7_COM7F_IMF(CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + PRF(printf("\n==== CCacheOutStream::Seek seekOrigin=%d Seek =%u\n", seekOrigin, (unsigned)offset)); + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _virtSize; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +Z7_COM7F_IMF(CCacheOutStream::SetSize(UInt64 newSize)) +{ + if (_hres != S_OK) + return _hres; + + if (newSize <= _cachedPos || _cachedSize == 0) + { + _cachedSize = 0; + _cachedPos = newSize; + } + else + { + // _cachedSize != 0 + // newSize > _cachedPos + const UInt64 offset = newSize - _cachedPos; + if (offset <= _cachedSize) + { + // newSize is inside cached block or is touching cached block. + // so we reduce cache + _cachedSize = (size_t)offset; + if (_phySize <= newSize) + { + // _phySize will be restored later after cache flush + _virtSize = newSize; + return S_OK; + } + // (_phySize > newSize) + // so we must reduce phyStream size to (newSize) or to (_cachedPos) + // newPhySize = _cachedPos; // optional reduce to _cachedPos + } + else + { + // newSize > _cachedPos + _cachedSize + /* It's possible that we need to write zeros, + if new size is larger than old size. + We don't optimize for possible cases here. + So we just flush the cache. */ + _hres = FlushCache(); + } + } + + _virtSize = newSize; + + if (_hres != S_OK) + return _hres; + + if (newSize != _phySize) + { + if (!_stream) + return E_NOTIMPL; + // if (_phyPos > newSize) + RINOK(SeekPhy(newSize)) + if (_setRestriction) + { + UInt64 begin = _restrict_begin; + UInt64 end = _restrict_end; + if (_cachedSize != 0) + { + if (begin > _cachedPos) + begin = _cachedPos; + end = (UInt64)(Int64)-1; + } + _hres = _setRestriction->SetRestriction(begin, end); + RINOK(_hres) + } + _hres = _stream->SetSize(newSize); + RINOK(_hres) + _phySize = newSize; + } + return S_OK; +} + + +Z7_COM7F_IMF(CCacheOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + PRF(printf("\n============ CCacheOutStream::SetRestriction 0x%x, %u\n", (unsigned)begin, (unsigned)end)); + _restrict_begin = begin; + _restrict_end = end; + return FlushNonRestrictedBlocks(); +} + + + +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) +{ + /* + // it was tested before + if (inArchive) + { + if (!inArchive->CanUpdate()) + return E_NOTIMPL; + } + */ + + CMyComPtr setRestriction; + seqOutStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + { + RINOK(setRestriction->SetRestriction(0, 0)) + } + + CMyComPtr outStream; + CCacheOutStream *cacheStream; + bool outSeqMode; + + { + CMyComPtr outStreamReal; + + if (!compressionMethodMode.Force_SeqOutMode) + { + seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStreamReal); + /* + if (!outStreamReal) + return E_NOTIMPL; + */ + } + + if (inArchive) + { + if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx) + { + IInStream *baseStream = inArchive->GetBaseStream(); + RINOK(InStream_SeekToBegin(baseStream)) + RINOK(NCompress::CopyStream_ExactSize(baseStream, seqOutStream, (UInt64)inArchive->ArcInfo.Base, NULL)) + } + } + + outSeqMode = (outStreamReal == NULL); + if (outSeqMode) + setRestriction.Release(); + /* CCacheOutStream works as non-restricted by default. + So we use (setRestriction == NULL) for outSeqMode */ + // bool use_cacheStream = true; + // if (use_cacheStream) + { + cacheStream = new CCacheOutStream(); + outStream = cacheStream; + if (!cacheStream->Allocate()) + return E_OUTOFMEMORY; + RINOK(cacheStream->Init(seqOutStream, outStreamReal, setRestriction)) + setRestriction.Release(); + if (!outSeqMode) + setRestriction = cacheStream; + } + /* + else if (!outStreamReal) + { + CSeekOutStream *seekOutStream = new CSeekOutStream(); + outStream = seekOutStream; + seekOutStream->Init(seqOutStream); + } + else + outStream = outStreamReal; + */ + } + + COutArchive outArchive; + outArchive.SetRestriction = setRestriction; + + RINOK(outArchive.Create(outStream)) + + if (inArchive) + { + if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) + { + IInStream *baseStream = inArchive->GetBaseStream(); + RINOK(InStream_SeekSet(baseStream, (UInt64)inArchive->ArcInfo.Base)) + const UInt64 embStubSize = (UInt64)((Int64)inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base); + RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL)) + outArchive.MoveCurPos(embStubSize); + } + } + + RINOK (Update2( + EXTERNAL_CODECS_LOC_VARS + outArchive, inArchive, + inputItems, updateItems, + updateOptions, + compressionMethodMode, outSeqMode, + inArchive ? &inArchive->ArcInfo.Comment : NULL, + updateCallback)) + + return cacheStream->FinalFlush(); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipUpdate.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.h --- p7zip-rar-16.02/CPP/7zip/Archive/Zip/ZipUpdate.h 2015-09-17 19:02:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/Zip/ZipUpdate.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,59 +1,107 @@ -// ZipUpdate.h - -#ifndef __ZIP_UPDATE_H -#define __ZIP_UPDATE_H - -#include "../../ICoder.h" -#include "../IArchive.h" - -#include "../../Common/CreateCoder.h" - -#include "ZipCompressionMode.h" -#include "ZipIn.h" - -namespace NArchive { -namespace NZip { - -struct CUpdateRange -{ - UInt64 Position; - UInt64 Size; - - // CUpdateRange() {}; - CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {}; -}; - -struct CUpdateItem -{ - bool NewData; - bool NewProps; - bool IsDir; - bool NtfsTimeIsDefined; - bool IsUtf8; - int IndexInArc; - int IndexInClient; - UInt32 Attrib; - UInt32 Time; - UInt64 Size; - AString Name; - // bool Commented; - // CUpdateRange CommentRange; - FILETIME Ntfs_MTime; - FILETIME Ntfs_ATime; - FILETIME Ntfs_CTime; - - CUpdateItem(): NtfsTimeIsDefined(false), IsUtf8(false), Size(0) {} -}; - -HRESULT Update( - DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector &inputItems, - CObjectVector &updateItems, - ISequentialOutStream *seqOutStream, - CInArchive *inArchive, bool removeSfx, - CCompressionMethodMode *compressionMethodMode, - IArchiveUpdateCallback *updateCallback); - -}} - -#endif +// ZipUpdate.h + +#ifndef ZIP7_INC_ZIP_UPDATE_H +#define ZIP7_INC_ZIP_UPDATE_H + +#include "../../ICoder.h" +#include "../IArchive.h" + +#include "../../Common/CreateCoder.h" + +#include "ZipCompressionMode.h" +#include "ZipIn.h" + +namespace NArchive { +namespace NZip { + +/* +struct CUpdateRange +{ + UInt64 Position; + UInt64 Size; + + // CUpdateRange() {} + CUpdateRange(UInt64 position, UInt64 size): Position(position), Size(size) {} +}; +*/ + +struct CUpdateItem +{ + bool NewData; + bool NewProps; + bool IsDir; + bool Write_NtfsTime; + bool Write_UnixTime; + // bool Write_UnixTime_ATime; + bool IsUtf8; + bool Size_WasSetFromStream; + // bool IsAltStream; + int IndexInArc; + unsigned IndexInClient; + UInt32 Attrib; + UInt32 Time; + UInt64 Size; + AString Name; + CByteBuffer Name_Utf; // for Info-Zip (kIzUnicodeName) Extra + CByteBuffer Comment; + // bool Commented; + // CUpdateRange CommentRange; + FILETIME Ntfs_MTime; + FILETIME Ntfs_ATime; + FILETIME Ntfs_CTime; + + void Clear() + { + IsDir = false; + + Write_NtfsTime = false; + Write_UnixTime = false; + + IsUtf8 = false; + Size_WasSetFromStream = 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), + Write_NtfsTime(false), + Write_UnixTime(false), + IsUtf8(false), + Size_WasSetFromStream(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); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/ZstdHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZstdHandler.cpp --- p7zip-rar-16.02/CPP/7zip/Archive/ZstdHandler.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/ZstdHandler.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -0,0 +1,1147 @@ +// ZstdHandler.cpp + +#include "StdAfx.h" + +// #define Z7_USE_ZSTD_ORIG_DECODER +// #define Z7_USE_ZSTD_COMPRESSION + +#include "../../Common/ComTry.h" + +#include "../Common/MethodProps.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" +#include "../Compress/ZstdDecoder.h" +#ifdef Z7_USE_ZSTD_ORIG_DECODER +#include "../Compress/Zstd2Decoder.h" +#endif + +#ifdef Z7_USE_ZSTD_COMPRESSION +#include "../Compress/ZstdEncoder.h" +#include "../Compress/ZstdEncoderProps.h" +#include "Common/HandlerOut.h" +#endif + +#include "Common/DummyOutStream.h" + +#include "../../../C/CpuArch.h" + +using namespace NWindows; + +namespace NArchive { +namespace NZstd { + +#define DESCRIPTOR_Get_DictionaryId_Flag(d) ((d) & 3) +#define DESCRIPTOR_FLAG_CHECKSUM (1 << 2) +#define DESCRIPTOR_FLAG_RESERVED (1 << 3) +#define DESCRIPTOR_FLAG_UNUSED (1 << 4) +#define DESCRIPTOR_FLAG_SINGLE (1 << 5) +#define DESCRIPTOR_Get_ContentSize_Flag3(d) ((d) >> 5) +#define DESCRIPTOR_Is_ContentSize_Defined(d) (((d) & 0xe0) != 0) + +struct CFrameHeader +{ + Byte Descriptor; + Byte WindowDescriptor; + UInt32 DictionaryId; + UInt64 ContentSize; + + /* by zstd specification: + the decoder must check that (Is_Reserved() == false) + the decoder must ignore Unused_bit */ + bool Is_Reserved() const { return (Descriptor & DESCRIPTOR_FLAG_RESERVED) != 0; } + bool Is_Checksum() const { return (Descriptor & DESCRIPTOR_FLAG_CHECKSUM) != 0; } + bool Is_SingleSegment() const { return (Descriptor & DESCRIPTOR_FLAG_SINGLE) != 0; } + bool Is_ContentSize_Defined() const { return DESCRIPTOR_Is_ContentSize_Defined(Descriptor); } + unsigned Get_DictionaryId_Flag() const { return DESCRIPTOR_Get_DictionaryId_Flag(Descriptor); } + unsigned Get_ContentSize_Flag3() const { return DESCRIPTOR_Get_ContentSize_Flag3(Descriptor); } + + const Byte *Parse(const Byte *p, int size) + { + if ((unsigned)size < 2) + return NULL; + Descriptor = *p++; + size--; + { + Byte w = 0; + if (!Is_SingleSegment()) + { + w = *p++; + size--; + } + WindowDescriptor = w; + } + { + unsigned n = Get_DictionaryId_Flag(); + UInt32 d = 0; + if (n) + { + n = (unsigned)1 << (n - 1); + if ((size -= (int)n) < 0) + return NULL; + d = GetUi32(p) & ((UInt32)(Int32)-1 >> (32 - 8u * n)); + p += n; + } + DictionaryId = d; + } + { + unsigned n = Get_ContentSize_Flag3(); + UInt64 v = 0; + if (n) + { + n >>= 1; + if (n == 1) + v = 256; + n = (unsigned)1 << n; + if ((size -= (int)n) < 0) + return NULL; + v += GetUi64(p) & ((UInt64)(Int64)-1 >> (64 - 8u * n)); + p += n; + } + ContentSize = v; + } + return p; + } +}; + + + +class CHandler Z7_final: + public IInArchive, + public IArchiveOpenSeq, + public ISetProperties, +#ifdef Z7_USE_ZSTD_COMPRESSION + public IOutArchive, +#endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInArchive) + Z7_COM_QI_ENTRY(IArchiveOpenSeq) + Z7_COM_QI_ENTRY(ISetProperties) +#ifdef Z7_USE_ZSTD_COMPRESSION + Z7_COM_QI_ENTRY(IOutArchive) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInArchive) + Z7_IFACE_COM7_IMP(IArchiveOpenSeq) + Z7_IFACE_COM7_IMP(ISetProperties) +#ifdef Z7_USE_ZSTD_COMPRESSION + Z7_IFACE_COM7_IMP(IOutArchive) +#endif + + bool _isArc; + bool _needSeekToStart; + // bool _dataAfterEnd; + // bool _needMoreInput; + bool _unsupportedBlock; + + bool _wasParsed; + bool _phySize_Decoded_Defined; + bool _unpackSize_Defined; // decoded + bool _decoded_Info_Defined; + + bool _parseMode; + bool _disableHash; + // bool _smallMode; + + UInt64 _phySize; + UInt64 _phySize_Decoded; + UInt64 _unpackSize; + + CZstdDecInfo _parsed_Info; + CZstdDecInfo _decoded_Info; + + CMyComPtr _stream; + CMyComPtr _seqStream; + +#ifdef Z7_USE_ZSTD_COMPRESSION + CSingleMethodProps _props; +#endif + +public: + CHandler(): + _parseMode(false), + _disableHash(false) + // _smallMode(false) + {} +}; + + +static const Byte kProps[] = +{ + kpidSize, + kpidPackSize +}; + +static const Byte kArcProps[] = +{ + kpidNumStreams, + kpidNumBlocks, + kpidMethod, + // kpidChecksum + kpidCRC +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + + +// static const unsigned kBlockType_Raw = 0; +static const unsigned kBlockType_RLE = 1; +// static const unsigned kBlockType_Compressed = 2; +static const unsigned kBlockType_Reserved = 3; +/* +static const char * const kNames[] = +{ + "RAW" + , "RLE" + , "Compressed" + , "Reserved" +}; +*/ + +static void Add_UInt64(AString &s, const char *name, UInt64 v) +{ + s.Add_OptSpaced(name); + s.Add_Colon(); + s.Add_UInt64(v); +} + + +static void PrintSize(AString &s, UInt64 w) +{ + char c = 0; + if ((w & ((1 << 30) - 1)) == 0) { c = 'G'; w >>= 30; } + else if ((w & ((1 << 20) - 1)) == 0) { c = 'M'; w >>= 20; } + else if ((w & ((1 << 10) - 1)) == 0) { c = 'K'; w >>= 10; } + s.Add_UInt64(w); + if (c) + { + s.Add_Char(c); + s += "iB"; + } +} + + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + + CZstdDecInfo *p = NULL; + if (_wasParsed || !_decoded_Info_Defined) + p = &_parsed_Info; + else if (_decoded_Info_Defined) + p = &_decoded_Info; + + switch (propID) + { + case kpidPhySize: + if (_wasParsed) + prop = _phySize; + else if (_phySize_Decoded_Defined) + prop = _phySize_Decoded; + break; + + case kpidUnpackSize: + if (_unpackSize_Defined) + prop = _unpackSize; + break; + + case kpidNumStreams: + if (p) + if (_wasParsed || _decoded_Info_Defined) + prop = p->num_DataFrames; + break; + + case kpidNumBlocks: + if (p) + if (_wasParsed || _decoded_Info_Defined) + prop = p->num_Blocks; + break; + + // case kpidChecksum: + case kpidCRC: + if (p) + if (p->checksum_Defined && p->num_DataFrames == 1) + prop = p->checksum; // it's checksum from last frame + break; + + case kpidMethod: + { + AString s; + s.Add_OptSpaced(p == &_decoded_Info ? + "decoded:" : _wasParsed ? + "parsed:" : + "header-open-only:"); + + if (p->dictionaryId != 0) + { + if (p->are_DictionaryId_Different) + s.Add_OptSpaced("different-dictionary-IDs"); + s.Add_OptSpaced("dictionary-ID:"); + s.Add_UInt32(p->dictionaryId); + } + /* + if (ContentSize_Defined) + { + s.Add_OptSpaced("ContentSize="); + s.Add_UInt64(ContentSize_Total); + } + */ + // if (p->are_Checksums) + if (p->descriptor_OR & DESCRIPTOR_FLAG_CHECKSUM) + s.Add_OptSpaced("XXH64"); + if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_CHECKSUM) + s.Add_OptSpaced("NO-XXH64"); + + if (p->descriptor_OR & DESCRIPTOR_FLAG_UNUSED) + s.Add_OptSpaced("unused_bit"); + + if (p->descriptor_OR & DESCRIPTOR_FLAG_SINGLE) + s.Add_OptSpaced("single-segments"); + + if (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE) + { + // Add_UInt64(s, "wnd-descriptors", p->num_WindowDescriptors); + s.Add_OptSpaced("wnd-desc-log-MAX:"); + // WindowDescriptor_MAX = 16 << 3; // for debug + const unsigned e = p->windowDescriptor_MAX >> 3; + s.Add_UInt32(e + 10); + const unsigned m = p->windowDescriptor_MAX & 7; + if (m != 0) + { + s.Add_Dot(); + s.Add_UInt32(m); + } + } + + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR) || + (p->descriptor_NOT_OR & DESCRIPTOR_FLAG_SINGLE)) + /* + if (p->are_ContentSize_Known || + p->are_WindowDescriptors) + */ + { + s.Add_OptSpaced("wnd-MAX:"); + PrintSize(s, p->windowSize_MAX); + if (p->windowSize_MAX != p->windowSize_Allocate_MAX) + { + s.Add_OptSpaced("wnd-use-MAX:"); + PrintSize(s, p->windowSize_Allocate_MAX); + } + } + + if (p->num_DataFrames != 1) + Add_UInt64(s, "data-frames", p->num_DataFrames); + if (p->num_SkipFrames != 0) + { + Add_UInt64(s, "skip-frames", p->num_SkipFrames); + Add_UInt64(s, "skip-frames-size-total", p->skipFrames_Size); + } + + if (p->are_ContentSize_Unknown) + s.Add_OptSpaced("unknown-content-size"); + + if (DESCRIPTOR_Is_ContentSize_Defined(p->descriptor_OR)) + { + Add_UInt64(s, "content-size-frame-max", p->contentSize_MAX); + Add_UInt64(s, "content-size-total", p->contentSize_Total); + } + + /* + for (unsigned i = 0; i < 4; i++) + { + const UInt64 n = p->num_Blocks_forType[i]; + if (n) + { + s.Add_OptSpaced(kNames[i]); + s += "-blocks:"; + s.Add_UInt64(n); + + s.Add_OptSpaced(kNames[i]); + s += "-block-bytes:"; + s.Add_UInt64(p->num_BlockBytes_forType[i]); + } + } + */ + prop = s; + break; + } + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_needMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + // if (_dataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd; + if (_unsupportedBlock) v |= kpv_ErrorFlags_UnsupportedMethod; + /* + if (_parsed_Info.numBlocks_forType[kBlockType_Reserved]) + v |= kpv_ErrorFlags_UnsupportedMethod; + */ + prop = v; + break; + } + + default: break; + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = 1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPackSize: + if (_wasParsed) + prop = _phySize; + else if (_phySize_Decoded_Defined) + prop = _phySize_Decoded; + break; + + case kpidSize: + if (_wasParsed && !_parsed_Info.are_ContentSize_Unknown) + prop = _parsed_Info.contentSize_Total; + else if (_unpackSize_Defined) + prop = _unpackSize; + break; + + default: break; + } + prop.Detach(value); + return S_OK; +} + +static const unsigned kSignatureSize = 4; +static const Byte k_Signature[kSignatureSize] = { 0x28, 0xb5, 0x2f, 0xfd } ; + +static const UInt32 kDataFrameSignature32 = 0xfd2fb528; +static const UInt32 kSkipFrameSignature = 0x184d2a50; +static const UInt32 kSkipFrameSignature_Mask = 0xfffffff0; + +/* +API_FUNC_static_IsArc IsArc_Zstd(const Byte *p, size_t size) +{ + if (size < kSignatureSize) + return k_IsArc_Res_NEED_MORE; + if (memcmp(p, k_Signature, kSignatureSize) != 0) + { + const UInt32 v = GetUi32(p); + if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; + } + p += 4; + // return k_IsArc_Res_YES; +} +} +*/ + +// kBufSize must be >= (ZSTD_FRAMEHEADERSIZE_MAX = 18) +// we use big buffer for fast parsing of worst case small blocks. +static const unsigned kBufSize = + 1 << 9; + // 1 << 14; // fastest in real file + +struct CStreamBuffer +{ + unsigned pos; + unsigned lim; + IInStream *Stream; + UInt64 StreamOffset; + Byte buf[kBufSize]; + + CStreamBuffer(): + pos(0), + lim(0), + StreamOffset(0) + {} + unsigned Avail() const { return lim - pos; } + const Byte *GetPtr() const { return &buf[pos]; } + UInt64 GetCurOffset() const { return StreamOffset - Avail(); } + void SkipInBuf(UInt32 size) { pos += size; } + HRESULT Skip(UInt32 size); + HRESULT Read(unsigned num); +}; + +HRESULT CStreamBuffer::Skip(UInt32 size) +{ + unsigned rem = lim - pos; + if (rem != 0) + { + if (rem > size) + rem = size; + pos += rem; + size -= rem; + if (pos != lim) + return S_OK; + } + if (size == 0) + return S_OK; + return Stream->Seek(size, STREAM_SEEK_CUR, &StreamOffset); +} + +HRESULT CStreamBuffer::Read(unsigned num) +{ + if (lim - pos >= num) + return S_OK; + if (pos != 0) + { + lim -= pos; + memmove(buf, buf + pos, lim); + pos = 0; + } + size_t processed = kBufSize - ((unsigned)StreamOffset & (kBufSize - 1)); + const unsigned avail = kBufSize - lim; + num -= lim; + if (avail < processed || processed < num) + processed = avail; + const HRESULT res = ReadStream(Stream, buf + lim, &processed); + StreamOffset += processed; + lim += (unsigned)processed; + return res; +} + + +static const unsigned k_ZSTD_FRAMEHEADERSIZE_MAX = 4 + 14; + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback)) +{ + COM_TRY_BEGIN + Close(); + + CZstdDecInfo *p = &_parsed_Info; + // p->are_ContentSize_Unknown = False; + CStreamBuffer sb; + sb.Stream = stream; + + for (;;) + { + RINOK(sb.Read(k_ZSTD_FRAMEHEADERSIZE_MAX)) + if (sb.Avail() < kSignatureSize) + break; + + if (callback && (ZstdDecInfo_GET_NUM_FRAMES(p) & 0xFFF) == 2) + { + const UInt64 numBytes = sb.GetCurOffset(); + RINOK(callback->SetCompleted(NULL, &numBytes)) + } + + const UInt32 v = GetUi32(sb.GetPtr()); + if (v != kDataFrameSignature32) + { + if ((v & kSkipFrameSignature_Mask) != kSkipFrameSignature) + break; + _phySize = sb.GetCurOffset() + 8; + p->num_SkipFrames++; + sb.SkipInBuf(4); + if (sb.Avail() < 4) + break; + const UInt32 size = GetUi32(sb.GetPtr()); + p->skipFrames_Size += size; + sb.SkipInBuf(4); + _phySize = sb.GetCurOffset() + size; + RINOK(sb.Skip(size)) + continue; + } + + p->num_DataFrames++; + // _numStreams_Defined = true; + sb.SkipInBuf(4); + CFrameHeader fh; + { + const Byte *data = fh.Parse(sb.GetPtr(), (int)sb.Avail()); + if (!data) + { + // _needMoreInput = true; + // we set size for one byte more to show that stream was truncated + _phySize = sb.StreamOffset + 1; + break; + } + if (fh.Is_Reserved()) + { + // we don't want false detection + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1) + return S_FALSE; + // _phySize = sb.GetCurOffset(); + break; + } + sb.SkipInBuf((unsigned)(data - sb.GetPtr())); + } + + p->descriptor_OR = (Byte)(p->descriptor_OR | fh.Descriptor); + p->descriptor_NOT_OR = (Byte)(p->descriptor_NOT_OR | ~fh.Descriptor); + + // _numBlocks_Defined = true; + // if (fh.Get_DictionaryId_Flag()) + // p->dictionaryId_Cur = fh.DictionaryId; + if (fh.DictionaryId != 0) + { + if (p->dictionaryId == 0) + p->dictionaryId = fh.DictionaryId; + else if (p->dictionaryId != fh.DictionaryId) + p->are_DictionaryId_Different = True; + } + + UInt32 blockSizeAllowedMax = (UInt32)1 << 17; + { + UInt64 winSize = fh.ContentSize; + UInt64 winSize_forAllocate = fh.ContentSize; + if (!fh.Is_SingleSegment()) + { + if (p->windowDescriptor_MAX < fh.WindowDescriptor) + p->windowDescriptor_MAX = fh.WindowDescriptor; + const unsigned e = (fh.WindowDescriptor >> 3); + const unsigned m = (fh.WindowDescriptor & 7); + winSize = (UInt64)(8 + m) << (e + 10 - 3); + if (!fh.Is_ContentSize_Defined() + || fh.DictionaryId != 0 + || winSize_forAllocate > winSize) + winSize_forAllocate = winSize; + // p->are_WindowDescriptors = true; + } + else + { + // p->are_SingleSegments = True; + } + if (blockSizeAllowedMax > winSize) + blockSizeAllowedMax = (UInt32)winSize; + if (p->windowSize_MAX < winSize) + p->windowSize_MAX = winSize; + if (p->windowSize_Allocate_MAX < winSize_forAllocate) + p->windowSize_Allocate_MAX = winSize_forAllocate; + } + + if (fh.Is_ContentSize_Defined()) + { + // p->are_ContentSize_Known = True; + p->contentSize_Total += fh.ContentSize; + if (p->contentSize_MAX < fh.ContentSize) + p->contentSize_MAX = fh.ContentSize; + } + else + { + p->are_ContentSize_Unknown = True; + } + + p->checksum_Defined = false; + + // p->numBlocks_forType[3] += 99; // for debug + + if (!_parseMode) + { + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1) + break; + } + + _wasParsed = true; + + bool blocksWereParsed = false; + + for (;;) + { + if (callback && (p->num_Blocks & 0xFFF) == 2) + { + // Sleep(10); + const UInt64 numBytes = sb.GetCurOffset(); + RINOK(callback->SetCompleted(NULL, &numBytes)) + } + _phySize = sb.GetCurOffset() + 3; + RINOK(sb.Read(3)) + if (sb.Avail() < 3) + { + // _needMoreInput = true; + // return S_FALSE; + break; // change it + } + const unsigned pos = sb.pos; + sb.pos = pos + 3; + UInt32 b = 0; + b += (UInt32)sb.buf[pos]; + b += (UInt32)sb.buf[pos + 1] << (8 * 1); + b += (UInt32)sb.buf[pos + 2] << (8 * 2); + p->num_Blocks++; + const unsigned blockType = (b >> 1) & 3; + UInt32 size = b >> 3; + // p->num_Blocks_forType[blockType]++; + // p->num_BlockBytes_forType[blockType] += size; + if (size > blockSizeAllowedMax + || blockType == kBlockType_Reserved) + { + _unsupportedBlock = true; + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 1 && p->num_Blocks == 1) + return S_FALSE; + break; + } + if (blockType == kBlockType_RLE) + size = 1; + _phySize = sb.GetCurOffset() + size; + RINOK(sb.Skip(size)) + if (b & 1) + { + // it's last block + blocksWereParsed = true; + break; + } + } + + if (!blocksWereParsed) + break; + + if (fh.Is_Checksum()) + { + _phySize = sb.GetCurOffset() + 4; + RINOK(sb.Read(4)) + if (sb.Avail() < 4) + break; + p->checksum_Defined = true; + // if (p->num_DataFrames == 1) + p->checksum = GetUi32(sb.GetPtr()); + sb.SkipInBuf(4); + } + } + + if (ZstdDecInfo_GET_NUM_FRAMES(p) == 0) + return S_FALSE; + + _needSeekToStart = true; + // } // _parseMode + _isArc = true; + _stream = stream; + _seqStream = stream; + + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::OpenSeq(ISequentialInStream *stream)) +{ + Close(); + _isArc = true; + _seqStream = stream; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + _isArc = false; + _needSeekToStart = false; + // _dataAfterEnd = false; + // _needMoreInput = false; + _unsupportedBlock = false; + + _wasParsed = false; + _phySize_Decoded_Defined = false; + _unpackSize_Defined = false; + _decoded_Info_Defined = false; + + ZstdDecInfo_CLEAR(&_parsed_Info) + ZstdDecInfo_CLEAR(&_decoded_Info) + + _phySize = 0; + _phySize_Decoded = 0; + _unpackSize = 0; + + _seqStream.Release(); + _stream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + if (numItems == 0) + return S_OK; + if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0)) + return E_INVALIDARG; + if (_wasParsed) + { + RINOK(extractCallback->SetTotal(_phySize)) + } + + Int32 opRes; + { + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + RINOK(extractCallback->GetStream(0, &realOutStream, askMode)) + if (!testMode && !realOutStream) + return S_OK; + + extractCallback->PrepareOperation(askMode); + + if (_needSeekToStart) + { + if (!_stream) + return E_FAIL; + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)) + } + else + _needSeekToStart = true; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, true); + +#ifdef Z7_USE_ZSTD_ORIG_DECODER + CMyComPtr2_Create decoder; +#else + CMyComPtr2_Create decoder; +#endif + + CMyComPtr2_Create outStreamSpec; + outStreamSpec->SetStream(realOutStream); + outStreamSpec->Init(); + // realOutStream.Release(); + + decoder->FinishMode = true; +#ifndef Z7_USE_ZSTD_ORIG_DECODER + decoder->DisableHash = _disableHash; +#endif + + // _dataAfterEnd = false; + // _needMoreInput = false; + const HRESULT hres = decoder.Interface()->Code(_seqStream, outStreamSpec, NULL, NULL, lps); + /* + { + UInt64 t1 = decoder->GetInputProcessedSize(); + // for debug + const UInt32 kTempSize = 64; + Byte buf[kTempSize]; + UInt32 processedSize = 0; + RINOK(decoder->ReadUnusedFromInBuf(buf, kTempSize, &processedSize)) + processedSize -= processedSize; + UInt64 t2 = decoder->GetInputProcessedSize(); + t2 = t2; + t1 = t1; + } + */ + const UInt64 outSize = outStreamSpec->GetSize(); + // } + + // if (hres == E_ABORT) return hres; + opRes = NExtract::NOperationResult::kDataError; + + if (hres == E_OUTOFMEMORY) + { + return hres; + // opRes = NExtract::NOperationResult::kMemError; + } + else if (hres == S_OK || hres == S_FALSE) + { +#ifndef Z7_USE_ZSTD_ORIG_DECODER + _decoded_Info_Defined = true; + _decoded_Info = decoder->_state.info; + // NumDataFrames_Decoded = decoder->_state.info.num_DataFrames; + // NumSkipFrames_Decoded = decoder->_state.info.num_SkipFrames; + const UInt64 inSize = decoder->_inProcessed; +#else + const UInt64 inSize = decoder->GetInputProcessedSize(); +#endif + _phySize_Decoded = inSize; + _phySize_Decoded_Defined = true; + + _unpackSize_Defined = true; + _unpackSize = outSize; + + // RINOK( + lps.Interface()->SetRatioInfo(&inSize, &outSize); + +#ifdef Z7_USE_ZSTD_ORIG_DECODER + if (hres == S_OK) + opRes = NExtract::NOperationResult::kOK; +#else + if (decoder->ResInfo.decode_SRes == SZ_ERROR_CRC) + { + opRes = NExtract::NOperationResult::kCRCError; + } + else if (decoder->ResInfo.decode_SRes == SZ_ERROR_NO_ARCHIVE) + { + _isArc = false; + opRes = NExtract::NOperationResult::kIsNotArc; + } + else if (decoder->ResInfo.decode_SRes == SZ_ERROR_INPUT_EOF) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + else + { + if (hres == S_OK && decoder->ResInfo.decode_SRes == SZ_OK) + opRes = NExtract::NOperationResult::kOK; + if (decoder->ResInfo.extraSize) + { + // if (inSize == 0) _isArc = false; + opRes = NExtract::NOperationResult::kDataAfterEnd; + } + /* + if (decoder->ResInfo.unexpededEnd) + opRes = NExtract::NOperationResult::kUnexpectedEnd; + */ + } +#endif + } + else if (hres == E_NOTIMPL) + { + opRes = NExtract::NOperationResult::kUnsupportedMethod; + } + else + return hres; + } + + return extractCallback->SetOperationResult(opRes); + + COM_TRY_END +} + + + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + // return _props.SetProperties(names, values, numProps); + // _smallMode = false; + _disableHash = false; + _parseMode = false; + // _parseMode = true; // for debug +#ifdef Z7_USE_ZSTD_COMPRESSION + _props.Init(); +#endif + + for (UInt32 i = 0; i < numProps; i++) + { + UString name = names[i]; + const PROPVARIANT &value = values[i]; + + if (name.IsEqualTo("parse")) + { + bool parseMode = true; + RINOK(PROPVARIANT_to_bool(value, parseMode)) + _parseMode = parseMode; + continue; + } + if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + UInt32 crcSize = 4; + RINOK(ParsePropToUInt32(name, value, crcSize)) + if (crcSize == 0) + _disableHash = true; + else if (crcSize == 4) + _disableHash = false; + else + return E_INVALIDARG; + continue; + } +#ifdef Z7_USE_ZSTD_COMPRESSION + /* + if (name.IsEqualTo("small")) + { + bool smallMode = true; + RINOK(PROPVARIANT_to_bool(value, smallMode)) + _smallMode = smallMode; + continue; + } + */ + RINOK(_props.SetProperty(names[i], value)) +#endif + } + return S_OK; +} + + + + +#ifdef Z7_USE_ZSTD_COMPRESSION + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *timeType)) +{ + *timeType = GET_FileTimeType_NotDefined_for_GetFileTimeType; + // *timeType = NFileTimeType::kUnix; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *updateCallback)) +{ + COM_TRY_BEGIN + + if (numItems != 1) + return E_INVALIDARG; + { + CMyComPtr setRestriction; + outStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); + if (setRestriction) + RINOK(setRestriction->SetRestriction(0, 0)) + } + Int32 newData, newProps; + UInt32 indexInArchive; + if (!updateCallback) + return E_FAIL; + RINOK(updateCallback->GetUpdateItemInfo(0, &newData, &newProps, &indexInArchive)) + + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop)) + if (prop.vt != VT_EMPTY) + if (prop.vt != VT_BOOL || prop.boolVal != VARIANT_FALSE) + return E_INVALIDARG; + } + } + + if (IntToBool(newData)) + { + UInt64 size; + { + NCOM::CPropVariant prop; + RINOK(updateCallback->GetProperty(0, kpidSize, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + size = prop.uhVal.QuadPart; + } + + if (!_props.MethodName.IsEmpty() + && !_props.MethodName.IsEqualTo_Ascii_NoCase("zstd")) + return E_INVALIDARG; + + { + CMyComPtr fileInStream; + RINOK(updateCallback->GetStream(0, &fileInStream)) + if (!fileInStream) + return S_FALSE; + { + CMyComPtr streamGetSize; + fileInStream.QueryInterface(IID_IStreamGetSize, &streamGetSize); + if (streamGetSize) + { + UInt64 size2; + if (streamGetSize->GetSize(&size2) == S_OK) + size = size2; + } + } + RINOK(updateCallback->SetTotal(size)) + + CMethodProps props2 = _props; + +#ifndef Z7_ST + /* + CSingleMethodProps (_props) + derives from + CMethodProps (props2) + So we transfer additional variable (num Threads) to CMethodProps list of properties + */ + + UInt32 numThreads = _props._numThreads; + + if (numThreads > Z7_ZSTDMT_NBWORKERS_MAX) + numThreads = Z7_ZSTDMT_NBWORKERS_MAX; + + if (_props.FindProp(NCoderPropID::kNumThreads) < 0) + { + if (!_props._numThreads_WasForced + && numThreads >= 1 + && _props._memUsage_WasSet) + { + NCompress::NZstd::CEncoderProps zstdProps; + RINOK(zstdProps.SetFromMethodProps(_props)) + ZstdEncProps_NormalizeFull(&zstdProps.EncProps); + numThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit( + &zstdProps.EncProps, _props._memUsage_Compress, numThreads); + } + props2.AddProp_NumThreads(numThreads); + } + +#endif // Z7_ST + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + { + CMyComPtr2_Create encoder; + // size = 1 << 24; // for debug + RINOK(props2.SetCoderProps(encoder.ClsPtr(), size != (UInt64)(Int64)-1 ? &size : NULL)) + // encoderSpec->_props.SmallFileOpt = _smallMode; + // we must set kExpectedDataSize just before Code(). + encoder->SrcSizeHint64 = size; + /* + CMyComPtr optProps; + _compressEncoder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void**)&optProps); + if (optProps) + { + PROPID propID = NCoderPropID::kExpectedDataSize; + NWindows::NCOM::CPropVariant prop = (UInt64)size; + // RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1)) + RINOK(encoderSpec->SetCoderPropertiesOpt(&propID, &prop, 1)) + } + */ + RINOK(encoder.Interface()->Code(fileInStream, outStream, NULL, NULL, lps)) + } + } + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); + } + + if (indexInArchive != 0) + return E_INVALIDARG; + + CMyComPtr2_Create lps; + lps->Init(updateCallback, true); + + CMyComPtr opCallback; + updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback); + if (opCallback) + { + RINOK(opCallback->ReportOperation( + NEventIndexType::kInArcIndex, 0, + NUpdateNotifyOp::kReplicate)) + } + + if (_stream) + RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL)) + + return NCompress::CopyStream(_stream, outStream, lps); + + COM_TRY_END +} +#endif + + + +#ifndef Z7_USE_ZSTD_COMPRESSION +#undef IMP_CreateArcOut +#define IMP_CreateArcOut +#undef CreateArcOut +#define CreateArcOut NULL +#endif + +#ifdef Z7_USE_ZSTD_COMPRESSION +REGISTER_ARC_IO( + "zstd2", "zst tzst", "* .tar", 0xe + 1, + k_Signature, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) +#else +REGISTER_ARC_IO( + "zstd", "zst tzst", "* .tar", 0xe, + k_Signature, 0 + , NArcInfoFlags::kKeepName + , 0 + , NULL) +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Archive/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/makefile --- p7zip-rar-16.02/CPP/7zip/Archive/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Archive/makefile 2006-05-01 07:41:11.000000000 +0000 @@ -0,0 +1,23 @@ +DIRS = \ + 7z\~ \ + Arj\~ \ + BZip2\~ \ + Cab\~ \ + Chm\~ \ + Cpio\~ \ + Deb\~ \ + GZip\~ \ + Iso\~ \ + Lzh\~ \ + Nsis\~ \ + Rar\~ \ + RPM\~ \ + Split\~ \ + Tar\~ \ + Z\~ \ + Zip\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Asm.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Asm.mak --- p7zip-rar-16.02/CPP/7zip/Asm.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Asm.mak 2024-02-29 08:00:00.000000000 +0000 @@ -0,0 +1,12 @@ +!IFDEF ASM_OBJS +!IF "$(PLATFORM)" == "arm64" +$(ASM_OBJS): ../../../../Asm/arm64/$(*B).S + $(COMPL_ASM_CLANG) +!ELSEIF "$(PLATFORM)" == "arm" +$(ASM_OBJS): ../../../../Asm/arm/$(*B).asm + $(COMPL_ASM) +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" +$(ASM_OBJS): ../../../../Asm/x86/$(*B).asm + $(COMPL_ASM) +!ENDIF +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/Alone.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/Alone.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsp 2024-01-29 10:00:00.000000000 +0000 @@ -0,0 +1,3344 @@ +# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Alone - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Alone - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zan.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zan.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Alone - Win32 Release" +# Name "Alone - Win32 Debug" +# Name "Alone - Win32 ReleaseU" +# Name "Alone - Win32 DebugU" +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\ArError.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\HashCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\HashCon.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\Main.cpp +# ADD CPP /D "Z7_PROG_VARIANT_A" +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CrcReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyException.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Xxh64Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Init.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Reg.cpp +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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 + +SOURCE=..\..\..\Windows\PropVariantUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "BZip2" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Crc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Crc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Decoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Encoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Register.cpp +# End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate64Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateRegister.cpp +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\HuffmanDecoder.h +# End Source File +# End Group +# Begin Group "Implode" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\ImplodeDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ImplodeDecoder.h +# End Source File +# End Group +# Begin Group "LZMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# End Group +# Begin Group "PPMd" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdEncoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.h +# End Source File +# End Group +# Begin Group "RangeCoder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\RangeCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoderBit.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoderBitTree.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RangeCoderOpt.h +# End Source File +# End Group +# Begin Group "Shrink" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\ShrinkDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ShrinkDecoder.h +# End Source File +# End Group +# Begin Group "BWT" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Mtf8.h +# End Source File +# End Group +# Begin Group "LZX" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzxDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzxDecoder.h +# End Source File +# End Group +# Begin Group "Quantum" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\QuantumDecoder.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\QuantumDecoder.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitlDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitlDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitlEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitmDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitmEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ByteSwap.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ByteSwap.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzOutWindow.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.h +# End Source File +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# End Group +# Begin Group "tar" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.h +# End Source File +# End Group +# Begin Group "zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.cpp +# ADD CPP /D "Z7_ZIP_LZFSE_DISABLE" +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderLoader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "cab" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabRegister.cpp +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Archive\Bz2Handler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DeflateProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DeflateProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GzHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\LzmaHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\XzHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ZstdHandler.cpp +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAesRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha1.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAesReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Pbkdf2HmacSha1.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Pbkdf2HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Sha1Cls.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipCrypto.cpp + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O1 + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipCrypto.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipStrong.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipStrong.h +# End Source File +# End Group +# Begin Group "7-zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IMyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "Xz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64Opt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzIn.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\AesOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BwtSort.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BwtSort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\HuffEnc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\HuffEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/Alone.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/Alone.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/Alone.dsw 2001-09-02 17:24:54.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Alone"=.\Alone.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile 2016-03-10 20:20:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile 2025-07-02 07:00:00.000000000 +0000 @@ -1,9 +1,245 @@ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -include ../../../../makefile.glb +PROG = 7za.exe + +CFLAGS = $(CFLAGS) -DZ7_ZIP_LZFSE_DISABLE +# -DZ7_PROG_VARIANT_A +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_A +# ZIP_FLAGS=-DZ7_ZIP_LZFSE_DISABLE + +# USE_C_SORT=1 +# USE_C_AES = 1 +# USE_C_SHA = 1 +# USE_C_LZFINDOPT = 1 + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\LzFindPrepare.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + $O\Sha1Reg.obj \ + $O\Sha256Reg.obj \ + $O\Xxh64Reg.obj \ + $O\XzCrc64Init.obj \ + $O\XzCrc64Reg.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\PropVariantUtils.obj \ + $O\Registry.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\LimitedStreams.obj \ + $O\MemBlocks.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\MultiOutStream.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\OutMemStream.obj \ + $O\ProgressMt.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\Bz2Handler.obj \ + $O\DeflateProps.obj \ + $O\GzHandler.obj \ + $O\LzmaHandler.obj \ + $O\SplitHandler.obj \ + $O\XzHandler.obj \ + $O\ZstdHandler.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\DummyOutStream.obj \ + $O\FindSignature.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + +CAB_OBJS = \ + $O\CabBlockInStream.obj \ + $O\CabHandler.obj \ + $O\CabHeader.obj \ + $O\CabIn.obj \ + $O\CabRegister.obj \ + +TAR_OBJS = \ + $O\TarHandler.obj \ + $O\TarHandlerOut.obj \ + $O\TarHeader.obj \ + $O\TarIn.obj \ + $O\TarOut.obj \ + $O\TarUpdate.obj \ + $O\TarRegister.obj \ + +ZIP_OBJS = \ + $O\ZipAddCommon.obj \ + $O\ZipHandler.obj \ + $O\ZipHandlerOut.obj \ + $O\ZipIn.obj \ + $O\ZipItem.obj \ + $O\ZipOut.obj \ + $O\ZipUpdate.obj \ + $O\ZipRegister.obj \ + + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BitlDecoder.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\BZip2Crc.obj \ + $O\BZip2Decoder.obj \ + $O\BZip2Encoder.obj \ + $O\BZip2Register.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\Deflate64Register.obj \ + $O\DeflateDecoder.obj \ + $O\DeflateEncoder.obj \ + $O\DeflateRegister.obj \ + $O\DeltaFilter.obj \ + $O\ImplodeDecoder.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Encoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + $O\LzOutWindow.obj \ + $O\LzxDecoder.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdEncoder.obj \ + $O\PpmdRegister.obj \ + $O\PpmdZip.obj \ + $O\QuantumDecoder.obj \ + $O\ShrinkDecoder.obj \ + $O\XzDecoder.obj \ + $O\XzEncoder.obj \ + $O\ZstdDecoder.obj \ + +# $O\LzfseDecoder.obj \ +# $O\ZstdRegister.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\HmacSha1.obj \ + $O\MyAes.obj \ + $O\MyAesReg.obj \ + $O\Pbkdf2HmacSha1.obj \ + $O\RandGen.obj \ + $O\WzAes.obj \ + $O\ZipCrypto.obj \ + $O\ZipStrong.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bcj2Enc.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\BwtSort.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\HuffEnc.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\Lzma2Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ + $O\Ppmd8.obj \ + $O\Ppmd8Dec.obj \ + $O\Ppmd8Enc.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + $O\Xxh64.obj \ + $O\Xz.obj \ + $O\XzDec.obj \ + $O\XzEnc.obj \ + $O\XzIn.obj \ + $O\ZstdDec.obj \ + +!include "../../UI/Console/Console.mak" + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../Crc64.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" +!include "../../Sha1.mak" +!include "../../Sha256.mak" +!include "../../Sort.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -0,0 +1,357 @@ +PROG = 7za + +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_A +ZIP_FLAGS=-DZ7_ZIP_LZFSE_DISABLE + + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/Threads.o \ + $O/MemBlocks.o \ + $O/OutMemStream.o \ + $O/ProgressMt.o \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES \ +# -DZ7_LONG_PATH \ + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/DynLimBuf.o \ + $O/IntToString.o \ + $O/ListFileUtils.o \ + $O/LzFindPrepare.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/Sha1Prepare.o \ + $O/Sha1Reg.o \ + $O/Sha256Prepare.o \ + $O/Sha256Reg.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + $O/Xxh64Reg.o \ + $O/XzCrc64Init.o \ + $O/XzCrc64Reg.o \ + +WIN_OBJS = \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileLink.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/PropVariantUtils.o \ + $O/System.o \ + $O/SystemInfo.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/MultiOutStream.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +AR_OBJS = \ + $O/Bz2Handler.o \ + $O/GzHandler.o \ + $O/LzmaHandler.o \ + $O/SplitHandler.o \ + $O/XzHandler.o \ + $O/ZstdHandler.o \ + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/DummyOutStream.o \ + $O/HandlerOut.o \ + $O/InStreamWithCRC.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + $O/ParseProperties.o \ + +7Z_OBJS = \ + $O/7zCompressionMode.o \ + $O/7zDecode.o \ + $O/7zEncode.o \ + $O/7zExtract.o \ + $O/7zFolderInStream.o \ + $O/7zHandler.o \ + $O/7zHandlerOut.o \ + $O/7zHeader.o \ + $O/7zIn.o \ + $O/7zOut.o \ + $O/7zProperties.o \ + $O/7zRegister.o \ + $O/7zSpecStream.o \ + $O/7zUpdate.o \ + +CAB_OBJS = \ + $O/CabBlockInStream.o \ + $O/CabHandler.o \ + $O/CabHeader.o \ + $O/CabIn.o \ + $O/CabRegister.o \ + +TAR_OBJS = \ + $O/TarHandler.o \ + $O/TarHandlerOut.o \ + $O/TarHeader.o \ + $O/TarIn.o \ + $O/TarOut.o \ + $O/TarUpdate.o \ + $O/TarRegister.o \ + +ZIP_OBJS = \ + $O/ZipAddCommon.o \ + $O/ZipHandler.o \ + $O/ZipHandlerOut.o \ + $O/ZipIn.o \ + $O/ZipItem.o \ + $O/ZipOut.o \ + $O/ZipUpdate.o \ + $O/ZipRegister.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BitlDecoder.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/ByteSwap.o \ + $O/BZip2Crc.o \ + $O/BZip2Decoder.o \ + $O/BZip2Encoder.o \ + $O/BZip2Register.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/Deflate64Register.o \ + $O/DeflateDecoder.o \ + $O/DeflateEncoder.o \ + $O/DeflateRegister.o \ + $O/DeltaFilter.o \ + $O/ImplodeDecoder.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Encoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + $O/LzOutWindow.o \ + $O/LzxDecoder.o \ + $O/PpmdDecoder.o \ + $O/PpmdEncoder.o \ + $O/PpmdRegister.o \ + $O/PpmdZip.o \ + $O/QuantumDecoder.o \ + $O/ShrinkDecoder.o \ + $O/XzDecoder.o \ + $O/XzEncoder.o \ + $O/ZstdDecoder.o \ + +# $O/LzfseDecoder.o \ +# $O/ZstdRegister.o + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/HmacSha1.o \ + $O/MyAes.o \ + $O/MyAesReg.o \ + $O/Pbkdf2HmacSha1.o \ + $O/RandGen.o \ + $O/WzAes.o \ + $O/ZipCrypto.o \ + $O/ZipStrong.o \ + +C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bcj2Enc.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/BwtSort.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/HuffEnc.o \ + $O/LzFind.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/Lzma2Enc.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/MtCoder.o \ + $O/MtDec.o \ + $O/Ppmd7.o \ + $O/Ppmd7Dec.o \ + $O/Ppmd7Enc.o \ + $O/Ppmd8.o \ + $O/Ppmd8Dec.o \ + $O/Ppmd8Enc.o \ + $O/Sha1.o \ + $O/Sha1Opt.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/Sort.o \ + $O/SwapBytes.o \ + $O/Xxh64.o \ + $O/Xz.o \ + $O/XzDec.o \ + $O/XzEnc.o \ + $O/XzIn.o \ + $O/XzCrc64.o \ + $O/XzCrc64Opt.o \ + $O/ZstdDec.o \ + + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(CAB_OBJS) \ + $(TAR_OBJS) \ + $(ZIP_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.list --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,897 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7za$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -7zStream.o : ../../../../C/7zStream.c - $(CC) $(CFLAGS) ../../../../C/7zStream.c -Aes.o : ../../../../C/Aes.c - $(CC) $(CFLAGS) ../../../../C/Aes.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -Bcj2.o : ../../../../C/Bcj2.c - $(CC) $(CFLAGS) ../../../../C/Bcj2.c -Bcj2Enc.o : ../../../../C/Bcj2Enc.c - $(CC) $(CFLAGS) ../../../../C/Bcj2Enc.c -Bra.o : ../../../../C/Bra.c - $(CC) $(CFLAGS) ../../../../C/Bra.c -Bra86.o : ../../../../C/Bra86.c - $(CC) $(CFLAGS) ../../../../C/Bra86.c -BraIA64.o : ../../../../C/BraIA64.c - $(CC) $(CFLAGS) ../../../../C/BraIA64.c -BwtSort.o : ../../../../C/BwtSort.c - $(CC) $(CFLAGS) ../../../../C/BwtSort.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Delta.o : ../../../../C/Delta.c - $(CC) $(CFLAGS) ../../../../C/Delta.c -HuffEnc.o : ../../../../C/HuffEnc.c - $(CC) $(CFLAGS) ../../../../C/HuffEnc.c -LzFind.o : ../../../../C/LzFind.c - $(CC) $(CFLAGS) ../../../../C/LzFind.c -LzFindMt.o : ../../../../C/LzFindMt.c - $(CC) $(CFLAGS) ../../../../C/LzFindMt.c -Lzma2Dec.o : ../../../../C/Lzma2Dec.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Dec.c -Lzma2Enc.o : ../../../../C/Lzma2Enc.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Enc.c -LzmaDec.o : ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) ../../../../C/LzmaDec.c -LzmaEnc.o : ../../../../C/LzmaEnc.c - $(CC) $(CFLAGS) ../../../../C/LzmaEnc.c -MtCoder.o : ../../../../C/MtCoder.c - $(CC) $(CFLAGS) ../../../../C/MtCoder.c -Ppmd7.o : ../../../../C/Ppmd7.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7.c -Ppmd7Dec.o : ../../../../C/Ppmd7Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Dec.c -Ppmd7Enc.o : ../../../../C/Ppmd7Enc.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Enc.c -Ppmd8.o : ../../../../C/Ppmd8.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8.c -Ppmd8Dec.o : ../../../../C/Ppmd8Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8Dec.c -Ppmd8Enc.o : ../../../../C/Ppmd8Enc.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8Enc.c -Sha1.o : ../../../../C/Sha1.c - $(CC) $(CFLAGS) ../../../../C/Sha1.c -Sha256.o : ../../../../C/Sha256.c - $(CC) $(CFLAGS) ../../../../C/Sha256.c -Sort.o : ../../../../C/Sort.c - $(CC) $(CFLAGS) ../../../../C/Sort.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -Xz.o : ../../../../C/Xz.c - $(CC) $(CFLAGS) ../../../../C/Xz.c -XzCrc64.o : ../../../../C/XzCrc64.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64.c -XzCrc64Opt.o : ../../../../C/XzCrc64Opt.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64Opt.c -XzDec.o : ../../../../C/XzDec.c - $(CC) $(CFLAGS) ../../../../C/XzDec.c -XzEnc.o : ../../../../C/XzEnc.c - $(CC) $(CFLAGS) ../../../../C/XzEnc.c -XzIn.o : ../../../../C/XzIn.c - $(CC) $(CFLAGS) ../../../../C/XzIn.c -7zCompressionMode.o : ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp -7zDecode.o : ../../../../CPP/7zip/Archive/7z/7zDecode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zDecode.cpp -7zEncode.o : ../../../../CPP/7zip/Archive/7z/7zEncode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zEncode.cpp -7zExtract.o : ../../../../CPP/7zip/Archive/7z/7zExtract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zExtract.cpp -7zFolderInStream.o : ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp -7zHandler.o : ../../../../CPP/7zip/Archive/7z/7zHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp -7zHandlerOut.o : ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp -7zHeader.o : ../../../../CPP/7zip/Archive/7z/7zHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHeader.cpp -7zIn.o : ../../../../CPP/7zip/Archive/7z/7zIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zIn.cpp -7zOut.o : ../../../../CPP/7zip/Archive/7z/7zOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zOut.cpp -7zProperties.o : ../../../../CPP/7zip/Archive/7z/7zProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zProperties.cpp -7zRegister.o : ../../../../CPP/7zip/Archive/7z/7zRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zRegister.cpp -7zSpecStream.o : ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp -7zUpdate.o : ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp -Bz2Handler.o : ../../../../CPP/7zip/Archive/Bz2Handler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Bz2Handler.cpp -CabBlockInStream.o : ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp -CabHandler.o : ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp -CabHeader.o : ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp -CabIn.o : ../../../../CPP/7zip/Archive/Cab/CabIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabIn.cpp -CabRegister.o : ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp -CoderMixer2.o : ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp -DummyOutStream.o : ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp -FindSignature.o : ../../../../CPP/7zip/Archive/Common/FindSignature.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/FindSignature.cpp -HandlerOut.o : ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp -InStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp -ItemNameUtils.o : ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp -MultiStream.o : ../../../../CPP/7zip/Archive/Common/MultiStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/MultiStream.cpp -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -ParseProperties.o : ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp -DeflateProps.o : ../../../../CPP/7zip/Archive/DeflateProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/DeflateProps.cpp -GzHandler.o : ../../../../CPP/7zip/Archive/GzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/GzHandler.cpp -LzmaHandler.o : ../../../../CPP/7zip/Archive/LzmaHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/LzmaHandler.cpp -PpmdHandler.o : ../../../../CPP/7zip/Archive/PpmdHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/PpmdHandler.cpp -SplitHandler.o : ../../../../CPP/7zip/Archive/SplitHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/SplitHandler.cpp -TarHandler.o : ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp -TarHandlerOut.o : ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp -TarHeader.o : ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp -TarIn.o : ../../../../CPP/7zip/Archive/Tar/TarIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarIn.cpp -TarOut.o : ../../../../CPP/7zip/Archive/Tar/TarOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarOut.cpp -TarRegister.o : ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp -TarUpdate.o : ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp -XzHandler.o : ../../../../CPP/7zip/Archive/XzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/XzHandler.cpp -ZHandler.o : ../../../../CPP/7zip/Archive/ZHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ZHandler.cpp -ZipAddCommon.o : ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp -ZipHandler.o : ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp -ZipHandlerOut.o : ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp -ZipIn.o : ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp -ZipItem.o : ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp -ZipOut.o : ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp -ZipRegister.o : ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp -ZipUpdate.o : ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp -CWrappers.o : ../../../../CPP/7zip/Common/CWrappers.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CWrappers.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -InBuffer.o : ../../../../CPP/7zip/Common/InBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InBuffer.cpp -InOutTempBuffer.o : ../../../../CPP/7zip/Common/InOutTempBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InOutTempBuffer.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MemBlocks.o : ../../../../CPP/7zip/Common/MemBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MemBlocks.cpp -MethodId.o : ../../../../CPP/7zip/Common/MethodId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodId.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -OffsetStream.o : ../../../../CPP/7zip/Common/OffsetStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OffsetStream.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -OutMemStream.o : ../../../../CPP/7zip/Common/OutMemStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutMemStream.cpp -ProgressMt.o : ../../../../CPP/7zip/Common/ProgressMt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressMt.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamBinder.o : ../../../../CPP/7zip/Common/StreamBinder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamBinder.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -VirtThread.o : ../../../../CPP/7zip/Common/VirtThread.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/VirtThread.cpp -BZip2Crc.o : ../../../../CPP/7zip/Compress/BZip2Crc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Crc.cpp -BZip2Decoder.o : ../../../../CPP/7zip/Compress/BZip2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Decoder.cpp -BZip2Encoder.o : ../../../../CPP/7zip/Compress/BZip2Encoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Encoder.cpp -BZip2Register.o : ../../../../CPP/7zip/Compress/BZip2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Register.cpp -Bcj2Coder.o : ../../../../CPP/7zip/Compress/Bcj2Coder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Coder.cpp -Bcj2Register.o : ../../../../CPP/7zip/Compress/Bcj2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Register.cpp -BcjCoder.o : ../../../../CPP/7zip/Compress/BcjCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjCoder.cpp -BcjRegister.o : ../../../../CPP/7zip/Compress/BcjRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjRegister.cpp -BitlDecoder.o : ../../../../CPP/7zip/Compress/BitlDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BitlDecoder.cpp -BranchMisc.o : ../../../../CPP/7zip/Compress/BranchMisc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchMisc.cpp -BranchRegister.o : ../../../../CPP/7zip/Compress/BranchRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchRegister.cpp -ByteSwap.o : ../../../../CPP/7zip/Compress/ByteSwap.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ByteSwap.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -CopyRegister.o : ../../../../CPP/7zip/Compress/CopyRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyRegister.cpp -Deflate64Register.o : ../../../../CPP/7zip/Compress/Deflate64Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Deflate64Register.cpp -DeflateDecoder.o : ../../../../CPP/7zip/Compress/DeflateDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateDecoder.cpp -DeflateEncoder.o : ../../../../CPP/7zip/Compress/DeflateEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateEncoder.cpp -DeflateRegister.o : ../../../../CPP/7zip/Compress/DeflateRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateRegister.cpp -DeltaFilter.o : ../../../../CPP/7zip/Compress/DeltaFilter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeltaFilter.cpp -ImplodeDecoder.o : ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp -ImplodeHuffmanDecoder.o : ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp -LzOutWindow.o : ../../../../CPP/7zip/Compress/LzOutWindow.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzOutWindow.cpp -Lzma2Decoder.o : ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp -Lzma2Encoder.o : ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp -Lzma2Register.o : ../../../../CPP/7zip/Compress/Lzma2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Register.cpp -LzmaDecoder.o : ../../../../CPP/7zip/Compress/LzmaDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaDecoder.cpp -LzmaEncoder.o : ../../../../CPP/7zip/Compress/LzmaEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaEncoder.cpp -LzmaRegister.o : ../../../../CPP/7zip/Compress/LzmaRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaRegister.cpp -LzxDecoder.o : ../../../../CPP/7zip/Compress/LzxDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzxDecoder.cpp -PpmdDecoder.o : ../../../../CPP/7zip/Compress/PpmdDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdDecoder.cpp -PpmdEncoder.o : ../../../../CPP/7zip/Compress/PpmdEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdEncoder.cpp -PpmdRegister.o : ../../../../CPP/7zip/Compress/PpmdRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdRegister.cpp -PpmdZip.o : ../../../../CPP/7zip/Compress/PpmdZip.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdZip.cpp -QuantumDecoder.o : ../../../../CPP/7zip/Compress/QuantumDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/QuantumDecoder.cpp -ShrinkDecoder.o : ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp -ZDecoder.o : ../../../../CPP/7zip/Compress/ZDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ZDecoder.cpp -7zAes.o : ../../../../CPP/7zip/Crypto/7zAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAes.cpp -7zAesRegister.o : ../../../../CPP/7zip/Crypto/7zAesRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAesRegister.cpp -HmacSha1.o : ../../../../CPP/7zip/Crypto/HmacSha1.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/HmacSha1.cpp -MyAes.o : ../../../../CPP/7zip/Crypto/MyAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/MyAes.cpp -MyAesReg.o : ../../../../CPP/7zip/Crypto/MyAesReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/MyAesReg.cpp -Pbkdf2HmacSha1.o : ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp -RandGen.o : ../../../../CPP/7zip/Crypto/RandGen.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/RandGen.cpp -WzAes.o : ../../../../CPP/7zip/Crypto/WzAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/WzAes.cpp -ZipCrypto.o : ../../../../CPP/7zip/Crypto/ZipCrypto.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/ZipCrypto.cpp -ZipStrong.o : ../../../../CPP/7zip/Crypto/ZipStrong.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/ZipStrong.cpp -ArchiveCommandLine.o : ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -Bench.o : ../../../../CPP/7zip/UI/Common/Bench.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Bench.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -EnumDirItems.o : ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp -Extract.o : ../../../../CPP/7zip/UI/Common/Extract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Extract.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -HashCalc.o : ../../../../CPP/7zip/UI/Common/HashCalc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/HashCalc.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -SetProperties.o : ../../../../CPP/7zip/UI/Common/SetProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SetProperties.cpp -SortUtils.o : ../../../../CPP/7zip/UI/Common/SortUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SortUtils.cpp -TempFiles.o : ../../../../CPP/7zip/UI/Common/TempFiles.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/TempFiles.cpp -Update.o : ../../../../CPP/7zip/UI/Common/Update.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Update.cpp -UpdateAction.o : ../../../../CPP/7zip/UI/Common/UpdateAction.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateAction.cpp -UpdateCallback.o : ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp -UpdatePair.o : ../../../../CPP/7zip/UI/Common/UpdatePair.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdatePair.cpp -UpdateProduce.o : ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp -BenchCon.o : ../../../../CPP/7zip/UI/Console/BenchCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/BenchCon.cpp -ConsoleClose.o : ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp -ExtractCallbackConsole.o : ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp -HashCon.o : ../../../../CPP/7zip/UI/Console/HashCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/HashCon.cpp -List.o : ../../../../CPP/7zip/UI/Console/List.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/List.cpp -Main.o : ../../../../CPP/7zip/UI/Console/Main.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/Main.cpp -MainAr.o : ../../../../CPP/7zip/UI/Console/MainAr.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/MainAr.cpp -OpenCallbackConsole.o : ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp -PercentPrinter.o : ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp -UpdateCallbackConsole.o : ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp -UserInputUtils.o : ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -CrcReg.o : ../../../../CPP/Common/CrcReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CrcReg.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -ListFileUtils.o : ../../../../CPP/Common/ListFileUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/ListFileUtils.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -Sha1Reg.o : ../../../../CPP/Common/Sha1Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Sha1Reg.cpp -Sha256Reg.o : ../../../../CPP/Common/Sha256Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Sha256Reg.cpp -StdInStream.o : ../../../../CPP/Common/StdInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdInStream.cpp -StdOutStream.o : ../../../../CPP/Common/StdOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdOutStream.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -XzCrc64Reg.o : ../../../../CPP/Common/XzCrc64Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/XzCrc64Reg.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -myAddExeFlag.o : ../../../../CPP/myWindows/myAddExeFlag.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/myAddExeFlag.cpp -mySplitCommandLine.o : ../../../../CPP/myWindows/mySplitCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/mySplitCommandLine.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - 7zStream.o \ - Aes.o \ - Alloc.o \ - Bcj2.o \ - Bcj2Enc.o \ - Bra.o \ - Bra86.o \ - BraIA64.o \ - BwtSort.o \ - CpuArch.o \ - Delta.o \ - HuffEnc.o \ - LzFind.o \ - LzFindMt.o \ - Lzma2Dec.o \ - Lzma2Enc.o \ - LzmaDec.o \ - LzmaEnc.o \ - MtCoder.o \ - Ppmd7.o \ - Ppmd7Dec.o \ - Ppmd7Enc.o \ - Ppmd8.o \ - Ppmd8Dec.o \ - Ppmd8Enc.o \ - Sha1.o \ - Sha256.o \ - Sort.o \ - Threads.o \ - Xz.o \ - XzCrc64.o \ - XzCrc64Opt.o \ - XzDec.o \ - XzEnc.o \ - XzIn.o \ - 7zCompressionMode.o \ - 7zDecode.o \ - 7zEncode.o \ - 7zExtract.o \ - 7zFolderInStream.o \ - 7zHandler.o \ - 7zHandlerOut.o \ - 7zHeader.o \ - 7zIn.o \ - 7zOut.o \ - 7zProperties.o \ - 7zRegister.o \ - 7zSpecStream.o \ - 7zUpdate.o \ - Bz2Handler.o \ - CabBlockInStream.o \ - CabHandler.o \ - CabHeader.o \ - CabIn.o \ - CabRegister.o \ - CoderMixer2.o \ - DummyOutStream.o \ - FindSignature.o \ - HandlerOut.o \ - InStreamWithCRC.o \ - ItemNameUtils.o \ - MultiStream.o \ - OutStreamWithCRC.o \ - ParseProperties.o \ - DeflateProps.o \ - GzHandler.o \ - LzmaHandler.o \ - PpmdHandler.o \ - SplitHandler.o \ - TarHandler.o \ - TarHandlerOut.o \ - TarHeader.o \ - TarIn.o \ - TarOut.o \ - TarRegister.o \ - TarUpdate.o \ - XzHandler.o \ - ZHandler.o \ - ZipAddCommon.o \ - ZipHandler.o \ - ZipHandlerOut.o \ - ZipIn.o \ - ZipItem.o \ - ZipOut.o \ - ZipRegister.o \ - ZipUpdate.o \ - CWrappers.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - InBuffer.o \ - InOutTempBuffer.o \ - LimitedStreams.o \ - MemBlocks.o \ - MethodId.o \ - MethodProps.o \ - OffsetStream.o \ - OutBuffer.o \ - OutMemStream.o \ - ProgressMt.o \ - ProgressUtils.o \ - PropId.o \ - StreamBinder.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - VirtThread.o \ - BZip2Crc.o \ - BZip2Decoder.o \ - BZip2Encoder.o \ - BZip2Register.o \ - Bcj2Coder.o \ - Bcj2Register.o \ - BcjCoder.o \ - BcjRegister.o \ - BitlDecoder.o \ - BranchMisc.o \ - BranchRegister.o \ - ByteSwap.o \ - CopyCoder.o \ - CopyRegister.o \ - Deflate64Register.o \ - DeflateDecoder.o \ - DeflateEncoder.o \ - DeflateRegister.o \ - DeltaFilter.o \ - ImplodeDecoder.o \ - ImplodeHuffmanDecoder.o \ - LzOutWindow.o \ - Lzma2Decoder.o \ - Lzma2Encoder.o \ - Lzma2Register.o \ - LzmaDecoder.o \ - LzmaEncoder.o \ - LzmaRegister.o \ - LzxDecoder.o \ - PpmdDecoder.o \ - PpmdEncoder.o \ - PpmdRegister.o \ - PpmdZip.o \ - QuantumDecoder.o \ - ShrinkDecoder.o \ - ZDecoder.o \ - 7zAes.o \ - 7zAesRegister.o \ - HmacSha1.o \ - MyAes.o \ - MyAesReg.o \ - Pbkdf2HmacSha1.o \ - RandGen.o \ - WzAes.o \ - ZipCrypto.o \ - ZipStrong.o \ - ArchiveCommandLine.o \ - ArchiveExtractCallback.o \ - ArchiveOpenCallback.o \ - Bench.o \ - DefaultName.o \ - EnumDirItems.o \ - Extract.o \ - ExtractingFilePath.o \ - HashCalc.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - SetProperties.o \ - SortUtils.o \ - TempFiles.o \ - Update.o \ - UpdateAction.o \ - UpdateCallback.o \ - UpdatePair.o \ - UpdateProduce.o \ - BenchCon.o \ - ConsoleClose.o \ - ExtractCallbackConsole.o \ - HashCon.o \ - List.o \ - Main.o \ - MainAr.o \ - OpenCallbackConsole.o \ - PercentPrinter.o \ - UpdateCallbackConsole.o \ - UserInputUtils.o \ - CRC.o \ - CommandLineParser.o \ - CrcReg.o \ - IntToString.o \ - ListFileUtils.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - Sha1Reg.o \ - Sha256Reg.o \ - StdInStream.o \ - StdOutStream.o \ - StringConvert.o \ - StringToInt.o \ - UTFConvert.o \ - Wildcard.o \ - XzCrc64Reg.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - Synchronization.o \ - System.o \ - TimeUtils.o \ - myAddExeFlag.o \ - mySplitCommandLine.o \ - wine_date_and_time.o \ - $(OBJ_AES) \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone/resource.rc 2018-04-23 08:23:39.000000000 +0000 @@ -0,0 +1,7 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile 2024-01-29 10:00:00.000000000 +0000 @@ -0,0 +1,31 @@ +PROG = 7zz.exe +# USE_C_AES = 1 +# USE_C_SHA = 1 + +CFLAGS = $(CFLAGS) -DZ7_PROG_VARIANT_Z +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_Z + +!include "../Format7zF/Arc.mak" +!include "../../UI/Console/Console.mak" + +COMMON_OBJS = $(COMMON_OBJS) \ + $O\CommandLineParser.obj \ + $O\ListFileUtils.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + +WIN_OBJS = $(WIN_OBJS) \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileLink.obj \ + $O\FileSystem.obj \ + $O\MemoryLock.obj \ + $O\Registry.obj \ + $O\SystemInfo.obj \ + +7ZIP_COMMON_OBJS = $(7ZIP_COMMON_OBJS) \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\MultiOutStream.obj \ + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -0,0 +1,111 @@ +PROG = 7zz + +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_Z + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +include ../Format7zF/Arc_gcc.mak + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LONG_PATH \ +# -DZ7_DEVICE_FILE \ + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_SYS) \ + $(LOCAL_FLAGS_ST) \ + + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +COMMON_OBJS_2 = \ + $O/CommandLineParser.o \ + $O/ListFileUtils.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + +WIN_OBJS_2 = \ + $O/ErrorMsg.o \ + $O/FileLink.o \ + $O/SystemInfo.o \ + +7ZIP_COMMON_OBJS_2 = \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/MultiOutStream.o \ + +OBJS = \ + $(ARC_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS_2) \ + $(WIN_OBJS_2) \ + $(7ZIP_COMMON_OBJS_2) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone2/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone2/resource.rc 2021-01-14 10:12:03.000000000 +0000 @@ -0,0 +1,7 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Standalone 2 Console", "7zz") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/Alone.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/Alone.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsp 2024-01-27 09:00:00.000000000 +0000 @@ -0,0 +1,2090 @@ +# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Alone - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Alone - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Alone - Win32 Release" +# Name "Alone - Win32 Debug" +# Name "Alone - Win32 ReleaseU" +# Name "Alone - Win32 DebugU" +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\HashCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\HashCon.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\Main.cpp +# ADD CPP /D "PROG_VARIANT_R" +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CrcReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyException.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Init.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Reg.cpp +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ByteSwap.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.h +# End Source File +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\LzmaHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\SplitHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\XzHandler.cpp +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.h +# End Source File +# End Group +# Begin Group "7-zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "Xz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64Opt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzIn.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\AesOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "Alone - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Alone - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAesRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAesReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/Alone.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/Alone.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/Alone.dsw 2001-09-02 17:24:54.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Alone"=.\Alone.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile 2016-03-10 20:23:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,9 +1,168 @@ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -include ../../../../makefile.glb +PROG = 7zr.exe + +# USE_C_AES = 1 +# USE_C_SHA = 1 +# USE_C_CRC64 = 1 +# USE_C_CRC = 1 +# NO_ASM_GNU=1 +# NO_ASM=1 + +CFLAGS = $(CFLAGS) -DZ7_PROG_VARIANT_R +# CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_R + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\LzFindPrepare.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\MyString.obj \ + $O\Sha256Reg.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + $O\XzCrc64Init.obj \ + $O\XzCrc64Reg.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Registry.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\MultiOutStream.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\LzmaHandler.obj \ + $O\SplitHandler.obj \ + $O\XzHandler.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\DummyOutStream.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zRegister.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Encoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + $O\XzDecoder.obj \ + $O\XzEncoder.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\MyAes.obj \ + $O\MyAesReg.obj \ + $O\RandGen.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bcj2Enc.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\Lzma2Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + $O\Xz.obj \ + $O\XzDec.obj \ + $O\XzEnc.obj \ + $O\XzIn.obj \ + +!include "../../UI/Console/Console.mak" + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../Crc64.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" +!include "../../Sort.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -0,0 +1,279 @@ +PROG = 7zr + +CONSOLE_VARIANT_FLAGS=-DZ7_PROG_VARIANT_R + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/Threads.o \ + $O/StreamBinder.o \ + $O/VirtThread.o \ + + + + + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES \ +# -DZ7_LONG_PATH \ + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/DynLimBuf.o \ + $O/IntToString.o \ + $O/ListFileUtils.o \ + $O/LzFindPrepare.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/Sha256Prepare.o \ + $O/Sha256Reg.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + $O/XzCrc64Init.o \ + $O/XzCrc64Reg.o \ + +WIN_OBJS = \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileLink.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/System.o \ + $O/SystemInfo.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/MultiOutStream.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +AR_OBJS = \ + $O/LzmaHandler.o \ + $O/SplitHandler.o \ + $O/XzHandler.o \ + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/DummyOutStream.o \ + $O/HandlerOut.o \ + $O/InStreamWithCRC.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + $O/ParseProperties.o \ + +7Z_OBJS = \ + $O/7zCompressionMode.o \ + $O/7zDecode.o \ + $O/7zEncode.o \ + $O/7zExtract.o \ + $O/7zFolderInStream.o \ + $O/7zHandler.o \ + $O/7zHandlerOut.o \ + $O/7zHeader.o \ + $O/7zIn.o \ + $O/7zOut.o \ + $O/7zProperties.o \ + $O/7zRegister.o \ + $O/7zSpecStream.o \ + $O/7zUpdate.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/ByteSwap.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/DeltaFilter.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Encoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + $O/XzDecoder.o \ + $O/XzEncoder.o \ + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/MyAes.o \ + $O/MyAesReg.o \ + $O/RandGen.o \ + +C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bcj2Enc.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/LzFind.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/Lzma2Enc.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/MtCoder.o \ + $O/MtDec.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/SwapBytes.o \ + $O/Xz.o \ + $O/XzDec.o \ + $O/XzEnc.o \ + $O/XzIn.o \ + $O/XzCrc64.o \ + $O/XzCrc64Opt.o \ + + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.list --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,618 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7zr$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -D_NO_CRYPTO \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Sha256.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -7zStream.o : ../../../../C/7zStream.c - $(CC) $(CFLAGS) ../../../../C/7zStream.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -Bcj2.o : ../../../../C/Bcj2.c - $(CC) $(CFLAGS) ../../../../C/Bcj2.c -Bcj2Enc.o : ../../../../C/Bcj2Enc.c - $(CC) $(CFLAGS) ../../../../C/Bcj2Enc.c -Bra.o : ../../../../C/Bra.c - $(CC) $(CFLAGS) ../../../../C/Bra.c -Bra86.o : ../../../../C/Bra86.c - $(CC) $(CFLAGS) ../../../../C/Bra86.c -BraIA64.o : ../../../../C/BraIA64.c - $(CC) $(CFLAGS) ../../../../C/BraIA64.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Delta.o : ../../../../C/Delta.c - $(CC) $(CFLAGS) ../../../../C/Delta.c -LzFind.o : ../../../../C/LzFind.c - $(CC) $(CFLAGS) ../../../../C/LzFind.c -LzFindMt.o : ../../../../C/LzFindMt.c - $(CC) $(CFLAGS) ../../../../C/LzFindMt.c -Lzma2Dec.o : ../../../../C/Lzma2Dec.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Dec.c -Lzma2Enc.o : ../../../../C/Lzma2Enc.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Enc.c -LzmaDec.o : ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) ../../../../C/LzmaDec.c -LzmaEnc.o : ../../../../C/LzmaEnc.c - $(CC) $(CFLAGS) ../../../../C/LzmaEnc.c -MtCoder.o : ../../../../C/MtCoder.c - $(CC) $(CFLAGS) ../../../../C/MtCoder.c -Sha256.o : ../../../../C/Sha256.c - $(CC) $(CFLAGS) ../../../../C/Sha256.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -Xz.o : ../../../../C/Xz.c - $(CC) $(CFLAGS) ../../../../C/Xz.c -XzCrc64.o : ../../../../C/XzCrc64.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64.c -XzCrc64Opt.o : ../../../../C/XzCrc64Opt.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64Opt.c -XzDec.o : ../../../../C/XzDec.c - $(CC) $(CFLAGS) ../../../../C/XzDec.c -XzEnc.o : ../../../../C/XzEnc.c - $(CC) $(CFLAGS) ../../../../C/XzEnc.c -XzIn.o : ../../../../C/XzIn.c - $(CC) $(CFLAGS) ../../../../C/XzIn.c -7zCompressionMode.o : ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp -7zDecode.o : ../../../../CPP/7zip/Archive/7z/7zDecode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zDecode.cpp -7zEncode.o : ../../../../CPP/7zip/Archive/7z/7zEncode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zEncode.cpp -7zExtract.o : ../../../../CPP/7zip/Archive/7z/7zExtract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zExtract.cpp -7zFolderInStream.o : ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp -7zHandler.o : ../../../../CPP/7zip/Archive/7z/7zHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp -7zHandlerOut.o : ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp -7zHeader.o : ../../../../CPP/7zip/Archive/7z/7zHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHeader.cpp -7zIn.o : ../../../../CPP/7zip/Archive/7z/7zIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zIn.cpp -7zOut.o : ../../../../CPP/7zip/Archive/7z/7zOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zOut.cpp -7zProperties.o : ../../../../CPP/7zip/Archive/7z/7zProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zProperties.cpp -7zRegister.o : ../../../../CPP/7zip/Archive/7z/7zRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zRegister.cpp -7zSpecStream.o : ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp -7zUpdate.o : ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp -CoderMixer2.o : ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp -DummyOutStream.o : ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp -HandlerOut.o : ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp -InStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp -ItemNameUtils.o : ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp -MultiStream.o : ../../../../CPP/7zip/Archive/Common/MultiStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/MultiStream.cpp -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -ParseProperties.o : ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp -LzmaHandler.o : ../../../../CPP/7zip/Archive/LzmaHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/LzmaHandler.cpp -SplitHandler.o : ../../../../CPP/7zip/Archive/SplitHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/SplitHandler.cpp -XzHandler.o : ../../../../CPP/7zip/Archive/XzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/XzHandler.cpp -CWrappers.o : ../../../../CPP/7zip/Common/CWrappers.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CWrappers.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -InBuffer.o : ../../../../CPP/7zip/Common/InBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InBuffer.cpp -InOutTempBuffer.o : ../../../../CPP/7zip/Common/InOutTempBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InOutTempBuffer.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MethodId.o : ../../../../CPP/7zip/Common/MethodId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodId.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -OffsetStream.o : ../../../../CPP/7zip/Common/OffsetStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OffsetStream.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamBinder.o : ../../../../CPP/7zip/Common/StreamBinder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamBinder.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -VirtThread.o : ../../../../CPP/7zip/Common/VirtThread.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/VirtThread.cpp -Bcj2Coder.o : ../../../../CPP/7zip/Compress/Bcj2Coder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Coder.cpp -Bcj2Register.o : ../../../../CPP/7zip/Compress/Bcj2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Register.cpp -BcjCoder.o : ../../../../CPP/7zip/Compress/BcjCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjCoder.cpp -BcjRegister.o : ../../../../CPP/7zip/Compress/BcjRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjRegister.cpp -BranchMisc.o : ../../../../CPP/7zip/Compress/BranchMisc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchMisc.cpp -BranchRegister.o : ../../../../CPP/7zip/Compress/BranchRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchRegister.cpp -ByteSwap.o : ../../../../CPP/7zip/Compress/ByteSwap.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ByteSwap.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -CopyRegister.o : ../../../../CPP/7zip/Compress/CopyRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyRegister.cpp -DeltaFilter.o : ../../../../CPP/7zip/Compress/DeltaFilter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeltaFilter.cpp -Lzma2Decoder.o : ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp -Lzma2Encoder.o : ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp -Lzma2Register.o : ../../../../CPP/7zip/Compress/Lzma2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Register.cpp -LzmaDecoder.o : ../../../../CPP/7zip/Compress/LzmaDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaDecoder.cpp -LzmaEncoder.o : ../../../../CPP/7zip/Compress/LzmaEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaEncoder.cpp -LzmaRegister.o : ../../../../CPP/7zip/Compress/LzmaRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaRegister.cpp -ArchiveCommandLine.o : ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -Bench.o : ../../../../CPP/7zip/UI/Common/Bench.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Bench.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -EnumDirItems.o : ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp -Extract.o : ../../../../CPP/7zip/UI/Common/Extract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Extract.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -HashCalc.o : ../../../../CPP/7zip/UI/Common/HashCalc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/HashCalc.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -SetProperties.o : ../../../../CPP/7zip/UI/Common/SetProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SetProperties.cpp -SortUtils.o : ../../../../CPP/7zip/UI/Common/SortUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SortUtils.cpp -TempFiles.o : ../../../../CPP/7zip/UI/Common/TempFiles.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/TempFiles.cpp -Update.o : ../../../../CPP/7zip/UI/Common/Update.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Update.cpp -UpdateAction.o : ../../../../CPP/7zip/UI/Common/UpdateAction.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateAction.cpp -UpdateCallback.o : ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp -UpdatePair.o : ../../../../CPP/7zip/UI/Common/UpdatePair.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdatePair.cpp -UpdateProduce.o : ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp -BenchCon.o : ../../../../CPP/7zip/UI/Console/BenchCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/BenchCon.cpp -ConsoleClose.o : ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp -ExtractCallbackConsole.o : ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp -HashCon.o : ../../../../CPP/7zip/UI/Console/HashCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/HashCon.cpp -List.o : ../../../../CPP/7zip/UI/Console/List.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/List.cpp -Main.o : ../../../../CPP/7zip/UI/Console/Main.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/Main.cpp -MainAr.o : ../../../../CPP/7zip/UI/Console/MainAr.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/MainAr.cpp -OpenCallbackConsole.o : ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp -PercentPrinter.o : ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp -UpdateCallbackConsole.o : ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp -UserInputUtils.o : ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -CrcReg.o : ../../../../CPP/Common/CrcReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CrcReg.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -ListFileUtils.o : ../../../../CPP/Common/ListFileUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/ListFileUtils.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -Sha256Reg.o : ../../../../CPP/Common/Sha256Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Sha256Reg.cpp -StdInStream.o : ../../../../CPP/Common/StdInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdInStream.cpp -StdOutStream.o : ../../../../CPP/Common/StdOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdOutStream.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -XzCrc64Reg.o : ../../../../CPP/Common/XzCrc64Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/XzCrc64Reg.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -myAddExeFlag.o : ../../../../CPP/myWindows/myAddExeFlag.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/myAddExeFlag.cpp -mySplitCommandLine.o : ../../../../CPP/myWindows/mySplitCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/mySplitCommandLine.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - 7zStream.o \ - Alloc.o \ - Bcj2.o \ - Bcj2Enc.o \ - Bra.o \ - Bra86.o \ - BraIA64.o \ - CpuArch.o \ - Delta.o \ - LzFind.o \ - LzFindMt.o \ - Lzma2Dec.o \ - Lzma2Enc.o \ - LzmaDec.o \ - LzmaEnc.o \ - MtCoder.o \ - Sha256.o \ - Threads.o \ - Xz.o \ - XzCrc64.o \ - XzCrc64Opt.o \ - XzDec.o \ - XzEnc.o \ - XzIn.o \ - 7zCompressionMode.o \ - 7zDecode.o \ - 7zEncode.o \ - 7zExtract.o \ - 7zFolderInStream.o \ - 7zHandler.o \ - 7zHandlerOut.o \ - 7zHeader.o \ - 7zIn.o \ - 7zOut.o \ - 7zProperties.o \ - 7zRegister.o \ - 7zSpecStream.o \ - 7zUpdate.o \ - CoderMixer2.o \ - DummyOutStream.o \ - HandlerOut.o \ - InStreamWithCRC.o \ - ItemNameUtils.o \ - MultiStream.o \ - OutStreamWithCRC.o \ - ParseProperties.o \ - LzmaHandler.o \ - SplitHandler.o \ - XzHandler.o \ - CWrappers.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - InBuffer.o \ - InOutTempBuffer.o \ - LimitedStreams.o \ - MethodId.o \ - MethodProps.o \ - OffsetStream.o \ - OutBuffer.o \ - ProgressUtils.o \ - PropId.o \ - StreamBinder.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - VirtThread.o \ - Bcj2Coder.o \ - Bcj2Register.o \ - BcjCoder.o \ - BcjRegister.o \ - BranchMisc.o \ - BranchRegister.o \ - ByteSwap.o \ - CopyCoder.o \ - CopyRegister.o \ - DeltaFilter.o \ - Lzma2Decoder.o \ - Lzma2Encoder.o \ - Lzma2Register.o \ - LzmaDecoder.o \ - LzmaEncoder.o \ - LzmaRegister.o \ - ArchiveCommandLine.o \ - ArchiveExtractCallback.o \ - ArchiveOpenCallback.o \ - Bench.o \ - DefaultName.o \ - EnumDirItems.o \ - Extract.o \ - ExtractingFilePath.o \ - HashCalc.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - SetProperties.o \ - SortUtils.o \ - TempFiles.o \ - Update.o \ - UpdateAction.o \ - UpdateCallback.o \ - UpdatePair.o \ - UpdateProduce.o \ - BenchCon.o \ - ConsoleClose.o \ - ExtractCallbackConsole.o \ - HashCon.o \ - List.o \ - Main.o \ - MainAr.o \ - OpenCallbackConsole.o \ - PercentPrinter.o \ - UpdateCallbackConsole.o \ - UserInputUtils.o \ - CRC.o \ - CommandLineParser.o \ - CrcReg.o \ - IntToString.o \ - ListFileUtils.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - NewHandler.o \ - Sha256Reg.o \ - StdInStream.o \ - StdOutStream.o \ - StringConvert.o \ - StringToInt.o \ - UTFConvert.o \ - Wildcard.o \ - XzCrc64Reg.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - Synchronization.o \ - System.o \ - TimeUtils.o \ - myAddExeFlag.o \ - mySplitCommandLine.o \ - wine_date_and_time.o \ - $(OBJ_AES) \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Alone7z/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Alone7z/resource.rc 2018-04-23 08:24:13.000000000 +0000 @@ -0,0 +1,7 @@ +#include "../../../../C/7zVersion.rc" + +MY_VERSION_INFO_APP("7-Zip Reduced Standalone Console", "7zr") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/AloneGCOV/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/AloneGCOV/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/AloneGCOV/makefile 2015-11-06 16:12:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/AloneGCOV/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ - -# gcov *.c *.cpp - -# -fprofile-arcs -ftest-coverage - -# gprof -# Compiling a Program for Profiling : -pg -# Once the program is compiled for profiling, you must run it in order to generate the information that gprof needs -# gprof 7za.exe > gprof.output - - - -# Profile guided optimization with gcc -# ====================================== -# Compile all code with -fprofile-generate in {C|CXX|LD}FLAGS : -fprofile-generate -# Run the binary -# Run your application/benchmark against that binary -# Recompile all code with -fprofile-use (above steps will place lots of .gcda files in source tree) - -LOCAL_FLAGS=\ - -pg -g2 \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../Archive \ - -I../../Archive/7z \ - -I../../Archive/BZip2 \ - -I../../Archive/Common \ - -I../../Archive/GZip \ - -I../../Archive/Cab \ - -I../../Archive/Lzma \ - -I../../Archive/Tar \ - -I../../Archive/Zip \ - -I../../Archive/Split \ - -I../../Archive/Z \ - -I../../Compress \ - -I../../Crypto \ - -I../../UI/Console \ - -I../../UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -include ../../../../makefile.machine - -SRCS=\ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderOutStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -all : copy 7za.exe - -7za.exe: - $(CXX) $(LOCAL_FLAGS) -c *.cpp - $(CC) $(LOCAL_FLAGS) -c *.c - $(CXX) $(LOCAL_FLAGS) *.o -o 7za.exe $(LOCAL_LIBS_DLL) - ld -r *.o -o 7za.ld - nm -u -C 7za.ld > 7za.undefined -copy: - rm -f *.cpp *.c - cp -p $(SRCS) $(SRCS_C) . - -clean: - rm -f 7za.exe 7za.ld 7za.undefined *.cpp *.c *.gcov *.gcda *.gcno *.o core *~ gmon* gprof.output - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/FM.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/FM.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsp 2024-04-02 12:00:00.000000000 +0000 @@ -0,0 +1,2275 @@ +# Microsoft Developer Studio Project File - Name="FM" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=FM - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "FM.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "FM.mak" CFG="FM - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "FM - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "FM - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS_2" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "FM - Win32 Release" +# Name "FM - Win32 Debug" +# Name "FM - Win32 ReleaseU" +# Name "FM - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\add.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ClassDefs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Copy.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Delete.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Extract.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FM.ico +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Move.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Parent.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Properties.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Test.bmp +# End Source File +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# End Group +# Begin Group "Folders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\AltStreamsFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\AltStreamsFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FSDrives.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FSDrives.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FSFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FSFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FSFolderCopy.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\IFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\NetFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\NetFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RootFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RootFolder.h +# End Source File +# End Group +# Begin Group "Registry" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryAssociations.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryAssociations.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryPlugins.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryPlugins.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ViewSettings.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ViewSettings.h +# End Source File +# End Group +# Begin Group "Panel" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\App.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\App.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\AppState.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EnumFormatEtc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EnumFormatEtc.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FileFolderPluginOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FileFolderPluginOpen.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Panel.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Panel.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelCopy.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelCrc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelDrag.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelFolderChange.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelItemOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelKey.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelListNotify.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelOperations.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelSelect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelSort.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PanelSplitFile.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\VerCtrl.cpp +# End Source File +# End Group +# Begin Group "Dialog" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\EditPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EditPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FoldersPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FoldersPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LangPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LangPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MenuPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MenuPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SettingsPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SettingsPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SystemPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\UI\FileManager\AboutDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\AboutDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog2.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog2Res.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\CopyDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\CopyDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\DialogSize.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\EditDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LinkDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LinkDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ListViewDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MemDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MemDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MemDialogRes.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MessagesDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PasswordDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog2.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SplitDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SplitDialog.h +# End Source File +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c + +!IF "$(CFG)" == "FM - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c + +!IF "$(CFG)" == "FM - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c + +!IF "$(CFG)" == "FM - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\CommandBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ImageList.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ReBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Static.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\StatusBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ToolBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Trackbar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\COM.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CrcReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Init.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Reg.cpp +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\CompressCall2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\ArchiveFolderOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Explorer\ContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\ContextMenu.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\RegistryContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\RegistryContextMenu.h +# End Source File +# End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\GUI\BenchmarkDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\BenchmarkDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\BenchmarkDialogRes.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\CompressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\CompressDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\HashGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\HashGUI.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateCallbackGUI2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateCallbackGUI2.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\UpdateGUI.h +# End Source File +# End Group +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\UI\FileManager\7zFM.exe.manifest +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Add2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Copy2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Delete2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Extract2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FilePlugins.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FilePlugins.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FM.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Info.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Info2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Move2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MyCom2.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MyLoadMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\MyLoadMenu.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PluginInterface.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PluginLoader.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\resource.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SysIconUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\Test2.bmp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\TextPairs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\TextPairs.h +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/FM.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/FM.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/FM.dsw 2002-07-20 18:14:30.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "FM"=.\FM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.cpp 2006-10-11 10:05:07.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// StdAfx.h + +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/makefile 2024-01-27 13:00:00.000000000 +0000 @@ -0,0 +1,84 @@ +PROG = 7zFM.exe + +# CFLAGS = $(CFLAGS) -DZ7_LARGE_PAGES + +!include "../Format7zF/Arc.mak" + +!include "../../UI/FileManager/FM.mak" + +COMMON_OBJS = $(COMMON_OBJS) \ + $O\CommandLineParser.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\Random.obj \ + +WIN_OBJS = $(WIN_OBJS) \ + $O\Clipboard.obj \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileLink.obj \ + $O\MemoryGlobal.obj \ + $O\MemoryLock.obj \ + $O\Menu.obj \ + $O\ProcessUtils.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\SystemInfo.obj \ + $O\Shell.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + $O\PropertyPage.obj \ + $O\Window2.obj \ + +7ZIP_COMMON_OBJS = $(7ZIP_COMMON_OBJS) \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\MultiOutStream.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveName.obj \ + $O\ArchiveOpenCallback.obj \ + $O\Bench.obj \ + $O\CompressCall2.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +EXPLORER_OBJS = \ + $O\ContextMenu.obj \ + $O\MyMessages.obj \ + $O\RegistryContextMenu.obj \ + +GUI_OBJS = \ + $O\BenchmarkDialog.obj \ + $O\CompressDialog.obj \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + $O\HashGUI.obj \ + $O\UpdateCallbackGUI.obj \ + $O\UpdateCallbackGUI2.obj \ + $O\UpdateGUI.obj \ + + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Fm/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Fm/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Fm/resource.rc 2022-01-05 09:00:00.000000000 +0000 @@ -0,0 +1,7 @@ +#include "../../UI/FileManager/resource.rc" +#include "../../UI/GUI/resource2.rc" + +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 apfs" +END diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -0,0 +1,148 @@ +PROG = 7za.dll +DEF_FILE = ../../Archive/Archive2.def +CFLAGS = $(CFLAGS) \ + -DZ7_DEFLATE_EXTRACT_ONLY \ + -DZ7_BZIP2_EXTRACT_ONLY \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\IntToString.obj \ + $O\LzFindPrepare.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\Sha256Reg.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + + +COMPRESS_OBJS = \ + $O\CodecExports.obj \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BitlDecoder.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\BZip2Crc.obj \ + $O\BZip2Decoder.obj \ + $O\BZip2Register.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeflateDecoder.obj \ + $O\DeflateRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Encoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + $O\LzOutWindow.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdEncoder.obj \ + $O\PpmdRegister.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\MyAes.obj \ + $O\MyAesReg.obj \ + $O\RandGen.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bcj2Enc.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\BwtSort.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\HuffEnc.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\Lzma2Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7Enc.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" +!include "../../Sort.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7z/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7z/resource.rc 2008-07-04 06:52:43.000000000 +0000 @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za") + +101 ICON "../../Archive/Icons/7z.ico" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/makefile 2023-03-19 18:00:00.000000000 +0000 @@ -0,0 +1,116 @@ +PROG = 7zxa.dll +DEF_FILE = ../../Archive/Archive2.def +CFLAGS = $(CFLAGS) \ + -DZ7_EXTRACT_ONLY \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\IntToString.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\Sha256Reg.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\InBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\HandlerOut.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zProperties.obj \ + $O\7zRegister.obj \ + + +COMPRESS_OBJS = \ + $O\CodecExports.obj \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BitlDecoder.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\BZip2Crc.obj \ + $O\BZip2Decoder.obj \ + $O\BZip2Register.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeflateDecoder.obj \ + $O\DeflateRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaRegister.obj \ + $O\LzOutWindow.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdRegister.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\MyAes.obj \ + $O\MyAesReg.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtract/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtract/resource.rc 2008-07-04 06:53:13.000000000 +0000 @@ -0,0 +1,5 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxa") + +101 ICON "../../Archive/Icons/7z.ico" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/makefile 2023-03-19 18:00:00.000000000 +0000 @@ -0,0 +1,98 @@ +PROG = 7zxr.dll +DEF_FILE = ../../Archive/Archive2.def +CFLAGS = $(CFLAGS) \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_CRYPTO + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\InBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\HandlerOut.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHandler.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zProperties.obj \ + $O\7zRegister.obj \ + + +COMPRESS_OBJS = \ + $O\CodecExports.obj \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaRegister.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../LzmaDec.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zExtractR/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zExtractR/resource.rc 2011-04-18 11:41:49.000000000 +0000 @@ -0,0 +1,5 @@ +#include "../../../../C/7zVersion.rc" + +MY_VERSION_INFO_DLL("7z Extracting Reduced Standalone Plugin", "7zxr") + +101 ICON "../../Archive/Icons/7z.ico" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Arc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc.mak --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Arc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc.mak 2025-07-01 15:00:00.000000000 +0000 @@ -0,0 +1,310 @@ +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\LzFindPrepare.obj \ + $O\Md5Reg.obj \ + $O\MyMap.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\MyXml.obj \ + $O\NewHandler.obj \ + $O\Sha1Reg.obj \ + $O\Sha256Reg.obj \ + $O\Sha3Reg.obj \ + $O\Sha512Reg.obj \ + $O\Sha512Prepare.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + $O\Xxh64Reg.obj \ + $O\XzCrc64Init.obj \ + $O\XzCrc64Reg.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\PropVariantUtils.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\LockedStream.obj \ + $O\MemBlocks.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OffsetStream.obj \ + $O\OutBuffer.obj \ + $O\OutMemStream.obj \ + $O\ProgressMt.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\ApfsHandler.obj \ + $O\ApmHandler.obj \ + $O\ArHandler.obj \ + $O\ArjHandler.obj \ + $O\Base64Handler.obj \ + $O\Bz2Handler.obj \ + $O\ComHandler.obj \ + $O\CpioHandler.obj \ + $O\CramfsHandler.obj \ + $O\DeflateProps.obj \ + $O\DmgHandler.obj \ + $O\ElfHandler.obj \ + $O\ExtHandler.obj \ + $O\FatHandler.obj \ + $O\FlvHandler.obj \ + $O\GzHandler.obj \ + $O\GptHandler.obj \ + $O\HandlerCont.obj \ + $O\HfsHandler.obj \ + $O\IhexHandler.obj \ + $O\LpHandler.obj \ + $O\LzhHandler.obj \ + $O\LzmaHandler.obj \ + $O\MachoHandler.obj \ + $O\MbrHandler.obj \ + $O\MslzHandler.obj \ + $O\MubHandler.obj \ + $O\NtfsHandler.obj \ + $O\PeHandler.obj \ + $O\PpmdHandler.obj \ + $O\QcowHandler.obj \ + $O\RpmHandler.obj \ + $O\SparseHandler.obj \ + $O\SplitHandler.obj \ + $O\SquashfsHandler.obj \ + $O\SwfHandler.obj \ + $O\UefiHandler.obj \ + $O\VdiHandler.obj \ + $O\VhdHandler.obj \ + $O\VhdxHandler.obj \ + $O\VmdkHandler.obj \ + $O\XarHandler.obj \ + $O\XzHandler.obj \ + $O\ZHandler.obj \ + $O\ZstdHandler.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\DummyOutStream.obj \ + $O\FindSignature.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + $O\OutStreamWithSha1.obj \ + $O\HandlerOut.obj \ + $O\ParseProperties.obj \ + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + +CAB_OBJS = \ + $O\CabBlockInStream.obj \ + $O\CabHandler.obj \ + $O\CabHeader.obj \ + $O\CabIn.obj \ + $O\CabRegister.obj \ + +CHM_OBJS = \ + $O\ChmHandler.obj \ + $O\ChmIn.obj \ + +ISO_OBJS = \ + $O\IsoHandler.obj \ + $O\IsoHeader.obj \ + $O\IsoIn.obj \ + $O\IsoRegister.obj \ + +NSIS_OBJS = \ + $O\NsisDecode.obj \ + $O\NsisHandler.obj \ + $O\NsisIn.obj \ + $O\NsisRegister.obj \ + +RAR_OBJS = \ + $O\RarHandler.obj \ + $O\Rar5Handler.obj \ + +TAR_OBJS = \ + $O\TarHandler.obj \ + $O\TarHandlerOut.obj \ + $O\TarHeader.obj \ + $O\TarIn.obj \ + $O\TarOut.obj \ + $O\TarUpdate.obj \ + $O\TarRegister.obj \ + +UDF_OBJS = \ + $O\UdfHandler.obj \ + $O\UdfIn.obj \ + +WIM_OBJS = \ + $O\WimHandler.obj \ + $O\WimHandlerOut.obj \ + $O\WimIn.obj \ + $O\WimRegister.obj \ + +ZIP_OBJS = \ + $O\ZipAddCommon.obj \ + $O\ZipHandler.obj \ + $O\ZipHandlerOut.obj \ + $O\ZipIn.obj \ + $O\ZipItem.obj \ + $O\ZipOut.obj \ + $O\ZipUpdate.obj \ + $O\ZipRegister.obj \ + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BitlDecoder.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\BZip2Crc.obj \ + $O\BZip2Decoder.obj \ + $O\BZip2Encoder.obj \ + $O\BZip2Register.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\Deflate64Register.obj \ + $O\DeflateDecoder.obj \ + $O\DeflateEncoder.obj \ + $O\DeflateRegister.obj \ + $O\DeltaFilter.obj \ + $O\ImplodeDecoder.obj \ + $O\LzfseDecoder.obj \ + $O\LzhDecoder.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Encoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + $O\LzmsDecoder.obj \ + $O\LzOutWindow.obj \ + $O\LzxDecoder.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdEncoder.obj \ + $O\PpmdRegister.obj \ + $O\PpmdZip.obj \ + $O\QuantumDecoder.obj \ + $O\Rar1Decoder.obj \ + $O\Rar2Decoder.obj \ + $O\Rar3Decoder.obj \ + $O\Rar3Vm.obj \ + $O\Rar5Decoder.obj \ + $O\RarCodecsRegister.obj \ + $O\ShrinkDecoder.obj \ + $O\XpressDecoder.obj \ + $O\XzDecoder.obj \ + $O\XzEncoder.obj \ + $O\ZlibDecoder.obj \ + $O\ZlibEncoder.obj \ + $O\ZDecoder.obj \ + $O\ZstdDecoder.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\HmacSha1.obj \ + $O\HmacSha256.obj \ + $O\MyAes.obj \ + $O\MyAesReg.obj \ + $O\Pbkdf2HmacSha1.obj \ + $O\RandGen.obj \ + $O\Rar20Crypto.obj \ + $O\Rar5Aes.obj \ + $O\RarAes.obj \ + $O\WzAes.obj \ + $O\ZipCrypto.obj \ + $O\ZipStrong.obj \ + +C_OBJS = \ + $O\7zBuf2.obj \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bcj2Enc.obj \ + $O\Blake2s.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\BwtSort.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\HuffEnc.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\Lzma2Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\Md5.obj \ + $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Ppmd7aDec.obj \ + $O\Ppmd7Enc.obj \ + $O\Ppmd8.obj \ + $O\Ppmd8Dec.obj \ + $O\Ppmd8Enc.obj \ + $O\Sha3.obj \ + $O\Sha512.obj \ + $O\Sha512Opt.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + $O\Xxh64.obj \ + $O\Xz.obj \ + $O\XzDec.obj \ + $O\XzEnc.obj \ + $O\XzIn.obj \ + $O\ZstdDec.obj \ + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../Crc64.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" +!include "../../Sha1.mak" +!include "../../Sha256.mak" +!include "../../Sort.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak 2024-11-26 11:00:00.000000000 +0000 @@ -0,0 +1,395 @@ +include ../../LzmaDec_gcc.mak + +LOCAL_FLAGS_ST = +MT_OBJS = + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/Threads.o \ + $O/MemBlocks.o \ + $O/OutMemStream.o \ + $O/ProgressMt.o \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ + +endif + + + +COMMON_OBJS = \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/DynLimBuf.o \ + $O/IntToString.o \ + $O/LzFindPrepare.o \ + $O/Md5Reg.o \ + $O/MyMap.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/MyXml.o \ + $O/NewHandler.o \ + $O/Sha1Prepare.o \ + $O/Sha1Reg.o \ + $O/Sha256Prepare.o \ + $O/Sha256Reg.o \ + $O/Sha3Reg.o \ + $O/Sha512Prepare.o \ + $O/Sha512Reg.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + $O/Xxh64Reg.o \ + $O/XzCrc64Init.o \ + $O/XzCrc64Reg.o \ + +WIN_OBJS = \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/PropVariantUtils.o \ + $O/System.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/LockedStream.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +AR_OBJS = \ + $O/ApfsHandler.o \ + $O/ApmHandler.o \ + $O/ArHandler.o \ + $O/ArjHandler.o \ + $O/Base64Handler.o \ + $O/Bz2Handler.o \ + $O/ComHandler.o \ + $O/CpioHandler.o \ + $O/CramfsHandler.o \ + $O/DeflateProps.o \ + $O/DmgHandler.o \ + $O/ElfHandler.o \ + $O/ExtHandler.o \ + $O/FatHandler.o \ + $O/FlvHandler.o \ + $O/GzHandler.o \ + $O/GptHandler.o \ + $O/HandlerCont.o \ + $O/HfsHandler.o \ + $O/IhexHandler.o \ + $O/LpHandler.o \ + $O/LzhHandler.o \ + $O/LzmaHandler.o \ + $O/MachoHandler.o \ + $O/MbrHandler.o \ + $O/MslzHandler.o \ + $O/MubHandler.o \ + $O/NtfsHandler.o \ + $O/PeHandler.o \ + $O/PpmdHandler.o \ + $O/QcowHandler.o \ + $O/RpmHandler.o \ + $O/SparseHandler.o \ + $O/SplitHandler.o \ + $O/SquashfsHandler.o \ + $O/SwfHandler.o \ + $O/UefiHandler.o \ + $O/VdiHandler.o \ + $O/VhdHandler.o \ + $O/VhdxHandler.o \ + $O/VmdkHandler.o \ + $O/XarHandler.o \ + $O/XzHandler.o \ + $O/ZHandler.o \ + $O/ZstdHandler.o \ + +# $O/AvbHandler.o +# $O/LvmHandler.o + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/DummyOutStream.o \ + $O/FindSignature.o \ + $O/InStreamWithCRC.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + $O/OutStreamWithSha1.o \ + $O/HandlerOut.o \ + $O/ParseProperties.o \ + + +7Z_OBJS = \ + $O/7zCompressionMode.o \ + $O/7zDecode.o \ + $O/7zEncode.o \ + $O/7zExtract.o \ + $O/7zFolderInStream.o \ + $O/7zHandler.o \ + $O/7zHandlerOut.o \ + $O/7zHeader.o \ + $O/7zIn.o \ + $O/7zOut.o \ + $O/7zProperties.o \ + $O/7zSpecStream.o \ + $O/7zUpdate.o \ + $O/7zRegister.o \ + +CAB_OBJS = \ + $O/CabBlockInStream.o \ + $O/CabHandler.o \ + $O/CabHeader.o \ + $O/CabIn.o \ + $O/CabRegister.o \ + +CHM_OBJS = \ + $O/ChmHandler.o \ + $O/ChmIn.o \ + +ISO_OBJS = \ + $O/IsoHandler.o \ + $O/IsoHeader.o \ + $O/IsoIn.o \ + $O/IsoRegister.o \ + +NSIS_OBJS = \ + $O/NsisDecode.o \ + $O/NsisHandler.o \ + $O/NsisIn.o \ + $O/NsisRegister.o \ + +ifndef DISABLE_RAR +RAR_OBJS = \ + $O/RarHandler.o \ + $O/Rar5Handler.o \ + +endif + + +TAR_OBJS = \ + $O/TarHandler.o \ + $O/TarHandlerOut.o \ + $O/TarHeader.o \ + $O/TarIn.o \ + $O/TarOut.o \ + $O/TarUpdate.o \ + $O/TarRegister.o \ + +UDF_OBJS = \ + $O/UdfHandler.o \ + $O/UdfIn.o \ + +WIM_OBJS = \ + $O/WimHandler.o \ + $O/WimHandlerOut.o \ + $O/WimIn.o \ + $O/WimRegister.o \ + +ZIP_OBJS = \ + $O/ZipAddCommon.o \ + $O/ZipHandler.o \ + $O/ZipHandlerOut.o \ + $O/ZipIn.o \ + $O/ZipItem.o \ + $O/ZipOut.o \ + $O/ZipUpdate.o \ + $O/ZipRegister.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BitlDecoder.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/ByteSwap.o \ + $O/BZip2Crc.o \ + $O/BZip2Decoder.o \ + $O/BZip2Encoder.o \ + $O/BZip2Register.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/Deflate64Register.o \ + $O/DeflateDecoder.o \ + $O/DeflateEncoder.o \ + $O/DeflateRegister.o \ + $O/DeltaFilter.o \ + $O/ImplodeDecoder.o \ + $O/LzfseDecoder.o \ + $O/LzhDecoder.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Encoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + $O/LzmsDecoder.o \ + $O/LzOutWindow.o \ + $O/LzxDecoder.o \ + $O/PpmdDecoder.o \ + $O/PpmdEncoder.o \ + $O/PpmdRegister.o \ + $O/PpmdZip.o \ + $O/QuantumDecoder.o \ + $O/ShrinkDecoder.o \ + $O/XpressDecoder.o \ + $O/XzDecoder.o \ + $O/XzEncoder.o \ + $O/ZlibDecoder.o \ + $O/ZlibEncoder.o \ + $O/ZDecoder.o \ + $O/ZstdDecoder.o \ + +ifdef DISABLE_RAR +DISABLE_RAR_COMPRESS=1 +endif + +ifndef DISABLE_RAR_COMPRESS +COMPRESS_OBJS += \ + $O/Rar1Decoder.o \ + $O/Rar2Decoder.o \ + $O/Rar3Decoder.o \ + $O/Rar3Vm.o \ + $O/Rar5Decoder.o \ + $O/RarCodecsRegister.o \ + +endif + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/HmacSha1.o \ + $O/HmacSha256.o \ + $O/MyAes.o \ + $O/MyAesReg.o \ + $O/Pbkdf2HmacSha1.o \ + $O/RandGen.o \ + $O/WzAes.o \ + $O/ZipCrypto.o \ + $O/ZipStrong.o \ + +ifndef DISABLE_RAR +CRYPTO_OBJS += \ + $O/Rar20Crypto.o \ + $O/Rar5Aes.o \ + $O/RarAes.o \ + +endif + + +C_OBJS = \ + $O/7zBuf2.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/7zStream.o \ + $O/Aes.o \ + $O/AesOpt.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bcj2Enc.o \ + $O/Blake2s.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/BwtSort.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/HuffEnc.o \ + $O/LzFind.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/Lzma2Enc.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/Md5.o \ + $O/MtCoder.o \ + $O/MtDec.o \ + $O/Ppmd7.o \ + $O/Ppmd7Dec.o \ + $O/Ppmd7aDec.o \ + $O/Ppmd7Enc.o \ + $O/Ppmd8.o \ + $O/Ppmd8Dec.o \ + $O/Ppmd8Enc.o \ + $O/Sha1.o \ + $O/Sha1Opt.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/Sha3.o \ + $O/Sha512.o \ + $O/Sha512Opt.o \ + $O/Sort.o \ + $O/SwapBytes.o \ + $O/Xxh64.o \ + $O/Xz.o \ + $O/XzDec.o \ + $O/XzEnc.o \ + $O/XzIn.o \ + $O/XzCrc64.o \ + $O/XzCrc64Opt.o \ + $O/ZstdDec.o \ + +ARC_OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(CAB_OBJS) \ + $(CHM_OBJS) \ + $(COM_OBJS) \ + $(ISO_OBJS) \ + $(NSIS_OBJS) \ + $(RAR_OBJS) \ + $(TAR_OBJS) \ + $(UDF_OBJS) \ + $(WIM_OBJS) \ + $(ZIP_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + +# we need empty line after last line above diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Format7z.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Format7z.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsp 2024-11-26 08:00:00.000000000 +0000 @@ -0,0 +1,3426 @@ +# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Format7z.mak" CFG="7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_ST_9" /FAcs /Yu"StdAfx.h" /FD /GF /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Util\7z.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none /debug + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\SDK" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_ST_9" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7z.dll" /pdbtype:sept /ignore:4033 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "7z - Win32 Release" +# Name "7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Group "Icons" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Icons\7z.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\arj.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\bz2.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\cab.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\cpio.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\deb.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\dmg.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\fat.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\gz.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\hfs.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\iso.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\lzh.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\lzma.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\ntfs.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\rar.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\rpm.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\split.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\squashfs.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\tar.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\vhd.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\wim.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\xar.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\xz.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\z.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\zip.ico +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Icons\zst.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Archive\Archive2.def +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ArchiveExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CodecExports.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DllExports2.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CrcReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Md5Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyException.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyMap.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyMap.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyXml.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyXml.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha1Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha3Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Xxh64Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Init.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\XzCrc64Reg.cpp +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "Bit Coder" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BitlDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitlDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitlEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitmDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BitmEncoder.h +# End Source File +# End Group +# Begin Group "Rar Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Rar1Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar1Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar3Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar3Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar3Vm.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar3Vm.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar5Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Rar5Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\RarCodecsRegister.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# End Group +# Begin Group "BZip2 Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\BZip2Const.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Crc.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Crc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Decoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Encoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BZip2Register.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Mtf8.h +# End Source File +# End Group +# Begin Group "Zip Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Deflate64Register.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateConst.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeflateRegister.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ImplodeDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ImplodeDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdZip.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ShrinkDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ShrinkDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZlibDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZlibDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZlibEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZlibEncoder.h +# End Source File +# End Group +# Begin Group "7z Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ByteSwap.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Encoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdEncoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdRegister.cpp +# End Source File +# End Group +# Begin Group "Cab Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzxDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzxDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\QuantumDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\QuantumDecoder.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\HuffmanDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzfseDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzfseDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzhDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzhDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmsDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmsDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzOutWindow.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XpressDecoder.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XpressDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\XzEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\ZstdDecoder.h +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAesRegister.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha1.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha256.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\HmacSha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAesReg.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Pbkdf2HmacSha1.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Pbkdf2HmacSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RandGen.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar20Crypto.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar20Crypto.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar5Aes.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Rar5Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RarAes.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\RarAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\Sha1Cls.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAes.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\WzAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipCrypto.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipCrypto.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipStrong.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\ZipStrong.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InOutTempBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MemBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodId.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutMemStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Group "xz" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /W4 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# ADD CPP /W4 /WX +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xz.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /W4 /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# ADD CPP /W4 /WX +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzCrc64Opt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /W4 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# ADD CPP /W4 /WX +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\XzIn.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /W4 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# ADD CPP /W4 /WX +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\C\7zBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zBuf2.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Blake2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Blake2s.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BwtSort.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BwtSort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\HuffEnc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\HuffEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindOpt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Enc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Md5.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Md5.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7aDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Dec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd8Enc.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\RotateDefs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha3.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha3.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512Opt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\SwapBytes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Xxh64.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\ZstdDec.h +# End Source File +# End Group +# Begin Group "Archive" + +# PROP Default_Filter "" +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zEncode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zFolderInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zProperties.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zSpecStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdate.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zUpdateItem.h +# End Source File +# End Group +# Begin Group "Rar" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Rar\Rar5Handler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\Rar5Handler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\RarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\RarHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\RarHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\RarItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Rar\RarVol.h +# End Source File +# End Group +# Begin Group "Cab" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabBlockInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Cab\CabRegister.cpp +# End Source File +# End Group +# Begin Group "Chm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Chm\ChmHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Chm\ChmHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Chm\ChmIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Chm\ChmIn.h +# End Source File +# End Group +# Begin Group "Archive common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\DummyOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\FindSignature.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\InStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithSha1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithSha1.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ParseProperties.h +# End Source File +# End Group +# Begin Group "Iso" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Iso\IsoRegister.cpp +# End Source File +# End Group +# Begin Group "Nsis" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Nsis\NsisRegister.cpp +# End Source File +# End Group +# Begin Group "Tar" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Tar\TarUpdate.h +# End Source File +# End Group +# Begin Group "Zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipAddCommon.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipCompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Zip\ZipUpdate.h +# End Source File +# End Group +# Begin Group "Wim" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimHandlerOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Wim\WimRegister.cpp +# End Source File +# End Group +# Begin Group "Udf" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Udf\UdfHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Udf\UdfHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Udf\UdfIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Udf\UdfIn.h +# End Source File +# 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 + +SOURCE=..\..\Archive\ArHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ArjHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Base64Handler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Bz2Handler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ComHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\CpioHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\CramfsHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DeflateProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DeflateProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\DmgHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ElfHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ExtHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\FatHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\FlvHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GptHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\GzHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\HandlerCont.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\HandlerCont.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\HfsHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\HfsHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +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 + +SOURCE=..\..\Archive\LzmaHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\MachoHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\MbrHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\MslzHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\MubHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\NtfsHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\PeHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\PpmdHandler.cpp + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\QcowHandler.cpp +# End Source File +# Begin Source File + +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 + +SOURCE=..\..\Archive\SquashfsHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\SwfHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\UefiHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\VdiHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\VhdHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\VhdxHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\VmdkHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\XarHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\XzHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\XzHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ZHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\ZstdHandler.cpp +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\MyVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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 + +SOURCE=..\..\..\Windows\PropVariantUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "Asm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\7zAsm.asm +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\7zCrcOpt.asm + +!IF "$(CFG)" == "7z - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# Begin Custom Build +OutDir=.\Debug +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\AesOpt.asm + +!IF "$(CFG)" == "7z - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +OutDir=.\Release +InputPath=..\..\..\..\Asm\x86\AesOpt.asm +InputName=AesOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build +OutDir=.\Debug +InputPath=..\..\..\..\Asm\x86\AesOpt.asm +InputName=AesOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -WX -W3 -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\Sha1Opt.asm + +!IF "$(CFG)" == "7z - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=..\..\..\..\Asm\x86\Sha1Opt.asm +InputName=Sha1Opt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# Begin Custom Build +OutDir=.\Debug +InputPath=..\..\..\..\Asm\x86\Sha1Opt.asm +InputName=Sha1Opt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\Sha256Opt.asm + +!IF "$(CFG)" == "7z - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=..\..\..\..\Asm\x86\Sha256Opt.asm +InputName=Sha256Opt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# Begin Custom Build +OutDir=.\Debug +InputPath=..\..\..\..\Asm\x86\Sha256Opt.asm +InputName=Sha256Opt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Format7z.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/Format7z.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/Format7z.dsw 2002-08-11 15:48:22.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "7z"=.\Format7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile 2024-01-27 16:00:00.000000000 +0000 @@ -0,0 +1,21 @@ +PROG = 7z.dll +# USE_C_LZFINDOPT = 1 +DEF_FILE = ../../Archive/Archive2.def +CFLAGS = $(CFLAGS) \ + -DZ7_EXTERNAL_CODECS \ + +!IFNDEF UNDER_CE +# CFLAGS = $(CFLAGS) -DZ7_LARGE_PAGES +!ENDIF + +!include "Arc.mak" + +COMPRESS_OBJS = $(COMPRESS_OBJS) \ + $O\CodecExports.obj \ + +AR_OBJS = $(AR_OBJS) \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -0,0 +1,57 @@ +PROG = 7z +DEF_FILE = ../../Archive/Archive2.def + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +include Arc_gcc.mak + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + $(LOCAL_FLAGS_ST) \ + +# -DZ7_LARGE_PAGES \ + +SYS_OBJS = \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + -DZ7_EXTERNAL_CODECS \ + $(LOCAL_FLAGS_SYS) \ + $(LOCAL_FLAGS_ST) \ + + +COMPRESS_OBJS_2 = \ + $O/CodecExports.o \ + +AR_OBJS_2 = \ + $O/ArchiveExports.o \ + $O/DllExports2.o \ + +OBJS = \ + $(ARC_OBJS) \ + $(AR_OBJS_2) \ + $(COMPRESS_OBJS_2) \ + $(SYS_OBJS) \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zF/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zF/resource.rc 2024-01-31 07:00:00.000000000 +0000 @@ -0,0 +1,39 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7z Plugin" , "7z") + + +0 ICON "../../Archive/Icons/7z.ico" +1 ICON "../../Archive/Icons/zip.ico" +2 ICON "../../Archive/Icons/bz2.ico" +3 ICON "../../Archive/Icons/rar.ico" +4 ICON "../../Archive/Icons/arj.ico" +5 ICON "../../Archive/Icons/z.ico" +6 ICON "../../Archive/Icons/lzh.ico" +7 ICON "../../Archive/Icons/cab.ico" +8 ICON "../../Archive/Icons/iso.ico" +9 ICON "../../Archive/Icons/split.ico" +10 ICON "../../Archive/Icons/rpm.ico" +11 ICON "../../Archive/Icons/deb.ico" +12 ICON "../../Archive/Icons/cpio.ico" +13 ICON "../../Archive/Icons/tar.ico" +14 ICON "../../Archive/Icons/gz.ico" +15 ICON "../../Archive/Icons/wim.ico" +16 ICON "../../Archive/Icons/lzma.ico" +17 ICON "../../Archive/Icons/dmg.ico" +18 ICON "../../Archive/Icons/hfs.ico" +19 ICON "../../Archive/Icons/xar.ico" +20 ICON "../../Archive/Icons/vhd.ico" +21 ICON "../../Archive/Icons/fat.ico" +22 ICON "../../Archive/Icons/ntfs.ico" +23 ICON "../../Archive/Icons/xz.ico" +24 ICON "../../Archive/Icons/squashfs.ico" +25 ICON "../../Archive/Icons/apfs.ico" +26 ICON "../../Archive/Icons/zst.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 zst:26 tzst:26 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 -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zFree/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zFree/makefile 2016-03-10 20:20:27.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ - -TARGET_FLAGS=$(CC_SHARED) -DRegisterArc=DllRegisterArc -DRegisterCodec=DllRegisterCodec - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LOCAL_LINK=$(LINK_SHARED) -LIBS=$(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile.list --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zFree/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zFree/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,1010 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7z.so - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/ApmHandler.cpp \ - ../../../../CPP/7zip/Archive/ArHandler.cpp \ - ../../../../CPP/7zip/Archive/ArchiveExports.cpp \ - ../../../../CPP/7zip/Archive/ArjHandler.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmIn.cpp \ - ../../../../CPP/7zip/Archive/ComHandler.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/CpioHandler.cpp \ - ../../../../CPP/7zip/Archive/CramfsHandler.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/DllExports2.cpp \ - ../../../../CPP/7zip/Archive/DmgHandler.cpp \ - ../../../../CPP/7zip/Archive/ElfHandler.cpp \ - ../../../../CPP/7zip/Archive/ExtHandler.cpp \ - ../../../../CPP/7zip/Archive/FatHandler.cpp \ - ../../../../CPP/7zip/Archive/FlvHandler.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/GptHandler.cpp \ - ../../../../CPP/7zip/Archive/HandlerCont.cpp \ - ../../../../CPP/7zip/Archive/HfsHandler.cpp \ - ../../../../CPP/7zip/Archive/IhexHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoIn.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp \ - ../../../../CPP/7zip/Archive/LzhHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/MachoHandler.cpp \ - ../../../../CPP/7zip/Archive/MbrHandler.cpp \ - ../../../../CPP/7zip/Archive/MslzHandler.cpp \ - ../../../../CPP/7zip/Archive/MubHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp \ - ../../../../CPP/7zip/Archive/NtfsHandler.cpp \ - ../../../../CPP/7zip/Archive/PeHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/QcowHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/RarHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp \ - ../../../../CPP/7zip/Archive/RpmHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/SquashfsHandler.cpp \ - ../../../../CPP/7zip/Archive/SwfHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfIn.cpp \ - ../../../../CPP/7zip/Archive/UefiHandler.cpp \ - ../../../../CPP/7zip/Archive/VdiHandler.cpp \ - ../../../../CPP/7zip/Archive/VhdHandler.cpp \ - ../../../../CPP/7zip/Archive/VmdkHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimIn.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimRegister.cpp \ - ../../../../CPP/7zip/Archive/XarHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/LzhDecoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzmsDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Compress/XpressDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibEncoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha256.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/Rar20Crypto.cpp \ - ../../../../CPP/7zip/Crypto/Rar5Aes.cpp \ - ../../../../CPP/7zip/Crypto/RarAes.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/DynLimBuf.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyMap.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/MyXml.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantUtils.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zBuf2.c \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Blake2s.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zBuf2.o : ../../../../C/7zBuf2.c - $(CC) $(CFLAGS) ../../../../C/7zBuf2.c -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -7zStream.o : ../../../../C/7zStream.c - $(CC) $(CFLAGS) ../../../../C/7zStream.c -Aes.o : ../../../../C/Aes.c - $(CC) $(CFLAGS) ../../../../C/Aes.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -Bcj2.o : ../../../../C/Bcj2.c - $(CC) $(CFLAGS) ../../../../C/Bcj2.c -Bcj2Enc.o : ../../../../C/Bcj2Enc.c - $(CC) $(CFLAGS) ../../../../C/Bcj2Enc.c -Blake2s.o : ../../../../C/Blake2s.c - $(CC) $(CFLAGS) ../../../../C/Blake2s.c -Bra.o : ../../../../C/Bra.c - $(CC) $(CFLAGS) ../../../../C/Bra.c -Bra86.o : ../../../../C/Bra86.c - $(CC) $(CFLAGS) ../../../../C/Bra86.c -BraIA64.o : ../../../../C/BraIA64.c - $(CC) $(CFLAGS) ../../../../C/BraIA64.c -BwtSort.o : ../../../../C/BwtSort.c - $(CC) $(CFLAGS) ../../../../C/BwtSort.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Delta.o : ../../../../C/Delta.c - $(CC) $(CFLAGS) ../../../../C/Delta.c -HuffEnc.o : ../../../../C/HuffEnc.c - $(CC) $(CFLAGS) ../../../../C/HuffEnc.c -LzFind.o : ../../../../C/LzFind.c - $(CC) $(CFLAGS) ../../../../C/LzFind.c -LzFindMt.o : ../../../../C/LzFindMt.c - $(CC) $(CFLAGS) ../../../../C/LzFindMt.c -Lzma2Dec.o : ../../../../C/Lzma2Dec.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Dec.c -Lzma2Enc.o : ../../../../C/Lzma2Enc.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Enc.c -LzmaDec.o : ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) ../../../../C/LzmaDec.c -LzmaEnc.o : ../../../../C/LzmaEnc.c - $(CC) $(CFLAGS) ../../../../C/LzmaEnc.c -MtCoder.o : ../../../../C/MtCoder.c - $(CC) $(CFLAGS) ../../../../C/MtCoder.c -Ppmd7.o : ../../../../C/Ppmd7.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7.c -Ppmd7Dec.o : ../../../../C/Ppmd7Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Dec.c -Ppmd7Enc.o : ../../../../C/Ppmd7Enc.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Enc.c -Ppmd8.o : ../../../../C/Ppmd8.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8.c -Ppmd8Dec.o : ../../../../C/Ppmd8Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8Dec.c -Ppmd8Enc.o : ../../../../C/Ppmd8Enc.c - $(CC) $(CFLAGS) ../../../../C/Ppmd8Enc.c -Sha1.o : ../../../../C/Sha1.c - $(CC) $(CFLAGS) ../../../../C/Sha1.c -Sha256.o : ../../../../C/Sha256.c - $(CC) $(CFLAGS) ../../../../C/Sha256.c -Sort.o : ../../../../C/Sort.c - $(CC) $(CFLAGS) ../../../../C/Sort.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -Xz.o : ../../../../C/Xz.c - $(CC) $(CFLAGS) ../../../../C/Xz.c -XzCrc64.o : ../../../../C/XzCrc64.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64.c -XzCrc64Opt.o : ../../../../C/XzCrc64Opt.c - $(CC) $(CFLAGS) ../../../../C/XzCrc64Opt.c -XzDec.o : ../../../../C/XzDec.c - $(CC) $(CFLAGS) ../../../../C/XzDec.c -XzEnc.o : ../../../../C/XzEnc.c - $(CC) $(CFLAGS) ../../../../C/XzEnc.c -XzIn.o : ../../../../C/XzIn.c - $(CC) $(CFLAGS) ../../../../C/XzIn.c -7zCompressionMode.o : ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp -7zDecode.o : ../../../../CPP/7zip/Archive/7z/7zDecode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zDecode.cpp -7zEncode.o : ../../../../CPP/7zip/Archive/7z/7zEncode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zEncode.cpp -7zExtract.o : ../../../../CPP/7zip/Archive/7z/7zExtract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zExtract.cpp -7zFolderInStream.o : ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp -7zHandler.o : ../../../../CPP/7zip/Archive/7z/7zHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp -7zHandlerOut.o : ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp -7zHeader.o : ../../../../CPP/7zip/Archive/7z/7zHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHeader.cpp -7zIn.o : ../../../../CPP/7zip/Archive/7z/7zIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zIn.cpp -7zOut.o : ../../../../CPP/7zip/Archive/7z/7zOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zOut.cpp -7zProperties.o : ../../../../CPP/7zip/Archive/7z/7zProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zProperties.cpp -7zRegister.o : ../../../../CPP/7zip/Archive/7z/7zRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zRegister.cpp -7zSpecStream.o : ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp -7zUpdate.o : ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp -ApmHandler.o : ../../../../CPP/7zip/Archive/ApmHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ApmHandler.cpp -ArHandler.o : ../../../../CPP/7zip/Archive/ArHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ArHandler.cpp -ArchiveExports.o : ../../../../CPP/7zip/Archive/ArchiveExports.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ArchiveExports.cpp -ArjHandler.o : ../../../../CPP/7zip/Archive/ArjHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ArjHandler.cpp -Bz2Handler.o : ../../../../CPP/7zip/Archive/Bz2Handler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Bz2Handler.cpp -CabBlockInStream.o : ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp -CabHandler.o : ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp -CabHeader.o : ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp -CabIn.o : ../../../../CPP/7zip/Archive/Cab/CabIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabIn.cpp -CabRegister.o : ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp -ChmHandler.o : ../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp -ChmIn.o : ../../../../CPP/7zip/Archive/Chm/ChmIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Chm/ChmIn.cpp -ComHandler.o : ../../../../CPP/7zip/Archive/ComHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ComHandler.cpp -CoderMixer2.o : ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp -DummyOutStream.o : ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp -FindSignature.o : ../../../../CPP/7zip/Archive/Common/FindSignature.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/FindSignature.cpp -HandlerOut.o : ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp -InStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp -ItemNameUtils.o : ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp -MultiStream.o : ../../../../CPP/7zip/Archive/Common/MultiStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/MultiStream.cpp -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -OutStreamWithSha1.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp -ParseProperties.o : ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp -CpioHandler.o : ../../../../CPP/7zip/Archive/CpioHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/CpioHandler.cpp -CramfsHandler.o : ../../../../CPP/7zip/Archive/CramfsHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/CramfsHandler.cpp -DeflateProps.o : ../../../../CPP/7zip/Archive/DeflateProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/DeflateProps.cpp -DllExports2.o : ../../../../CPP/7zip/Archive/DllExports2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/DllExports2.cpp -DmgHandler.o : ../../../../CPP/7zip/Archive/DmgHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/DmgHandler.cpp -ElfHandler.o : ../../../../CPP/7zip/Archive/ElfHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ElfHandler.cpp -ExtHandler.o : ../../../../CPP/7zip/Archive/ExtHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ExtHandler.cpp -FatHandler.o : ../../../../CPP/7zip/Archive/FatHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/FatHandler.cpp -FlvHandler.o : ../../../../CPP/7zip/Archive/FlvHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/FlvHandler.cpp -GzHandler.o : ../../../../CPP/7zip/Archive/GzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/GzHandler.cpp -GptHandler.o : ../../../../CPP/7zip/Archive/GptHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/GptHandler.cpp -HandlerCont.o : ../../../../CPP/7zip/Archive/HandlerCont.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/HandlerCont.cpp -HfsHandler.o : ../../../../CPP/7zip/Archive/HfsHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/HfsHandler.cpp -IhexHandler.o : ../../../../CPP/7zip/Archive/IhexHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/IhexHandler.cpp -IsoHandler.o : ../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp -IsoHeader.o : ../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp -IsoIn.o : ../../../../CPP/7zip/Archive/Iso/IsoIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Iso/IsoIn.cpp -IsoRegister.o : ../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp -LzhHandler.o : ../../../../CPP/7zip/Archive/LzhHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/LzhHandler.cpp -LzmaHandler.o : ../../../../CPP/7zip/Archive/LzmaHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/LzmaHandler.cpp -MachoHandler.o : ../../../../CPP/7zip/Archive/MachoHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/MachoHandler.cpp -MbrHandler.o : ../../../../CPP/7zip/Archive/MbrHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/MbrHandler.cpp -MslzHandler.o : ../../../../CPP/7zip/Archive/MslzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/MslzHandler.cpp -MubHandler.o : ../../../../CPP/7zip/Archive/MubHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/MubHandler.cpp -NsisDecode.o : ../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp -NsisHandler.o : ../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp -NsisIn.o : ../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp -NsisRegister.o : ../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp -NtfsHandler.o : ../../../../CPP/7zip/Archive/NtfsHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/NtfsHandler.cpp -PeHandler.o : ../../../../CPP/7zip/Archive/PeHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/PeHandler.cpp -PpmdHandler.o : ../../../../CPP/7zip/Archive/PpmdHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/PpmdHandler.cpp -QcowHandler.o : ../../../../CPP/7zip/Archive/QcowHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/QcowHandler.cpp -RarHandler.o : ../../../../CPP/7zip/Archive/Rar/RarHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Rar/RarHandler.cpp -Rar5Handler.o : ../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp -RpmHandler.o : ../../../../CPP/7zip/Archive/RpmHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/RpmHandler.cpp -SplitHandler.o : ../../../../CPP/7zip/Archive/SplitHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/SplitHandler.cpp -SquashfsHandler.o : ../../../../CPP/7zip/Archive/SquashfsHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/SquashfsHandler.cpp -SwfHandler.o : ../../../../CPP/7zip/Archive/SwfHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/SwfHandler.cpp -TarHandler.o : ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp -TarHandlerOut.o : ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp -TarHeader.o : ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp -TarIn.o : ../../../../CPP/7zip/Archive/Tar/TarIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarIn.cpp -TarOut.o : ../../../../CPP/7zip/Archive/Tar/TarOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarOut.cpp -TarRegister.o : ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp -TarUpdate.o : ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp -UdfHandler.o : ../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp -UdfIn.o : ../../../../CPP/7zip/Archive/Udf/UdfIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Udf/UdfIn.cpp -UefiHandler.o : ../../../../CPP/7zip/Archive/UefiHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/UefiHandler.cpp -VdiHandler.o : ../../../../CPP/7zip/Archive/VdiHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/VdiHandler.cpp -VhdHandler.o : ../../../../CPP/7zip/Archive/VhdHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/VhdHandler.cpp -VmdkHandler.o : ../../../../CPP/7zip/Archive/VmdkHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/VmdkHandler.cpp -WimHandler.o : ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp -WimHandlerOut.o : ../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp -WimIn.o : ../../../../CPP/7zip/Archive/Wim/WimIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Wim/WimIn.cpp -WimRegister.o : ../../../../CPP/7zip/Archive/Wim/WimRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Wim/WimRegister.cpp -XarHandler.o : ../../../../CPP/7zip/Archive/XarHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/XarHandler.cpp -XzHandler.o : ../../../../CPP/7zip/Archive/XzHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/XzHandler.cpp -ZHandler.o : ../../../../CPP/7zip/Archive/ZHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/ZHandler.cpp -ZipAddCommon.o : ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp -ZipHandler.o : ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp -ZipHandlerOut.o : ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp -ZipIn.o : ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp -ZipItem.o : ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp -ZipOut.o : ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp -ZipRegister.o : ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp -ZipUpdate.o : ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp -CWrappers.o : ../../../../CPP/7zip/Common/CWrappers.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CWrappers.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -InBuffer.o : ../../../../CPP/7zip/Common/InBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InBuffer.cpp -InOutTempBuffer.o : ../../../../CPP/7zip/Common/InOutTempBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InOutTempBuffer.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MemBlocks.o : ../../../../CPP/7zip/Common/MemBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MemBlocks.cpp -MethodId.o : ../../../../CPP/7zip/Common/MethodId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodId.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -OffsetStream.o : ../../../../CPP/7zip/Common/OffsetStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OffsetStream.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -OutMemStream.o : ../../../../CPP/7zip/Common/OutMemStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutMemStream.cpp -ProgressMt.o : ../../../../CPP/7zip/Common/ProgressMt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressMt.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamBinder.o : ../../../../CPP/7zip/Common/StreamBinder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamBinder.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -VirtThread.o : ../../../../CPP/7zip/Common/VirtThread.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/VirtThread.cpp -BZip2Crc.o : ../../../../CPP/7zip/Compress/BZip2Crc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Crc.cpp -BZip2Decoder.o : ../../../../CPP/7zip/Compress/BZip2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Decoder.cpp -BZip2Encoder.o : ../../../../CPP/7zip/Compress/BZip2Encoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Encoder.cpp -BZip2Register.o : ../../../../CPP/7zip/Compress/BZip2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BZip2Register.cpp -Bcj2Coder.o : ../../../../CPP/7zip/Compress/Bcj2Coder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Coder.cpp -Bcj2Register.o : ../../../../CPP/7zip/Compress/Bcj2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Register.cpp -BcjCoder.o : ../../../../CPP/7zip/Compress/BcjCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjCoder.cpp -BcjRegister.o : ../../../../CPP/7zip/Compress/BcjRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjRegister.cpp -BitlDecoder.o : ../../../../CPP/7zip/Compress/BitlDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BitlDecoder.cpp -BranchMisc.o : ../../../../CPP/7zip/Compress/BranchMisc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchMisc.cpp -BranchRegister.o : ../../../../CPP/7zip/Compress/BranchRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchRegister.cpp -ByteSwap.o : ../../../../CPP/7zip/Compress/ByteSwap.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ByteSwap.cpp -CodecExports.o : ../../../../CPP/7zip/Compress/CodecExports.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CodecExports.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -CopyRegister.o : ../../../../CPP/7zip/Compress/CopyRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyRegister.cpp -Deflate64Register.o : ../../../../CPP/7zip/Compress/Deflate64Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Deflate64Register.cpp -DeflateDecoder.o : ../../../../CPP/7zip/Compress/DeflateDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateDecoder.cpp -DeflateEncoder.o : ../../../../CPP/7zip/Compress/DeflateEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateEncoder.cpp -DeflateRegister.o : ../../../../CPP/7zip/Compress/DeflateRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeflateRegister.cpp -DeltaFilter.o : ../../../../CPP/7zip/Compress/DeltaFilter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeltaFilter.cpp -ImplodeDecoder.o : ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp -ImplodeHuffmanDecoder.o : ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp -LzOutWindow.o : ../../../../CPP/7zip/Compress/LzOutWindow.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzOutWindow.cpp -LzhDecoder.o : ../../../../CPP/7zip/Compress/LzhDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzhDecoder.cpp -Lzma2Decoder.o : ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp -Lzma2Encoder.o : ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp -Lzma2Register.o : ../../../../CPP/7zip/Compress/Lzma2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Register.cpp -LzmaDecoder.o : ../../../../CPP/7zip/Compress/LzmaDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaDecoder.cpp -LzmaEncoder.o : ../../../../CPP/7zip/Compress/LzmaEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaEncoder.cpp -LzmaRegister.o : ../../../../CPP/7zip/Compress/LzmaRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaRegister.cpp -LzmsDecoder.o : ../../../../CPP/7zip/Compress/LzmsDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmsDecoder.cpp -LzxDecoder.o : ../../../../CPP/7zip/Compress/LzxDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzxDecoder.cpp -PpmdDecoder.o : ../../../../CPP/7zip/Compress/PpmdDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdDecoder.cpp -PpmdEncoder.o : ../../../../CPP/7zip/Compress/PpmdEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdEncoder.cpp -PpmdRegister.o : ../../../../CPP/7zip/Compress/PpmdRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdRegister.cpp -PpmdZip.o : ../../../../CPP/7zip/Compress/PpmdZip.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdZip.cpp -QuantumDecoder.o : ../../../../CPP/7zip/Compress/QuantumDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/QuantumDecoder.cpp -ShrinkDecoder.o : ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp -ZDecoder.o : ../../../../CPP/7zip/Compress/ZDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ZDecoder.cpp -XpressDecoder.o : ../../../../CPP/7zip/Compress/XpressDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/XpressDecoder.cpp -ZlibDecoder.o : ../../../../CPP/7zip/Compress/ZlibDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ZlibDecoder.cpp -ZlibEncoder.o : ../../../../CPP/7zip/Compress/ZlibEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/ZlibEncoder.cpp -7zAes.o : ../../../../CPP/7zip/Crypto/7zAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAes.cpp -7zAesRegister.o : ../../../../CPP/7zip/Crypto/7zAesRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAesRegister.cpp -HmacSha1.o : ../../../../CPP/7zip/Crypto/HmacSha1.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/HmacSha1.cpp -HmacSha256.o : ../../../../CPP/7zip/Crypto/HmacSha256.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/HmacSha256.cpp -MyAes.o : ../../../../CPP/7zip/Crypto/MyAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/MyAes.cpp -MyAesReg.o : ../../../../CPP/7zip/Crypto/MyAesReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/MyAesReg.cpp -Pbkdf2HmacSha1.o : ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp -RandGen.o : ../../../../CPP/7zip/Crypto/RandGen.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/RandGen.cpp -Rar20Crypto.o : ../../../../CPP/7zip/Crypto/Rar20Crypto.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/Rar20Crypto.cpp -Rar5Aes.o : ../../../../CPP/7zip/Crypto/Rar5Aes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/Rar5Aes.cpp -RarAes.o : ../../../../CPP/7zip/Crypto/RarAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/RarAes.cpp -WzAes.o : ../../../../CPP/7zip/Crypto/WzAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/WzAes.cpp -ZipCrypto.o : ../../../../CPP/7zip/Crypto/ZipCrypto.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/ZipCrypto.cpp -ZipStrong.o : ../../../../CPP/7zip/Crypto/ZipStrong.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/ZipStrong.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CrcReg.o : ../../../../CPP/Common/CrcReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CrcReg.cpp -DynLimBuf.o : ../../../../CPP/Common/DynLimBuf.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/DynLimBuf.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -MyMap.o : ../../../../CPP/Common/MyMap.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyMap.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -MyXml.o : ../../../../CPP/Common/MyXml.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyXml.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -Sha1Reg.o : ../../../../CPP/Common/Sha1Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Sha1Reg.cpp -Sha256Reg.o : ../../../../CPP/Common/Sha256Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Sha256Reg.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -XzCrc64Reg.o : ../../../../CPP/Common/XzCrc64Reg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/XzCrc64Reg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantUtils.o : ../../../../CPP/Windows/PropVariantUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantUtils.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zBuf2.o \ - 7zCrc.o \ - $(OBJ_CRC32) \ - 7zStream.o \ - Aes.o \ - Alloc.o \ - Bcj2.o \ - Bcj2Enc.o \ - Blake2s.o \ - Bra.o \ - Bra86.o \ - BraIA64.o \ - BwtSort.o \ - CpuArch.o \ - Delta.o \ - HuffEnc.o \ - LzFind.o \ - LzFindMt.o \ - Lzma2Dec.o \ - Lzma2Enc.o \ - LzmaDec.o \ - LzmaEnc.o \ - MtCoder.o \ - Ppmd7.o \ - Ppmd7Dec.o \ - Ppmd7Enc.o \ - Ppmd8.o \ - Ppmd8Dec.o \ - Ppmd8Enc.o \ - Sha1.o \ - Sha256.o \ - Sort.o \ - Threads.o \ - Xz.o \ - XzCrc64.o \ - XzCrc64Opt.o \ - XzDec.o \ - XzEnc.o \ - XzIn.o \ - 7zCompressionMode.o \ - 7zDecode.o \ - 7zEncode.o \ - 7zExtract.o \ - 7zFolderInStream.o \ - 7zHandler.o \ - 7zHandlerOut.o \ - 7zHeader.o \ - 7zIn.o \ - 7zOut.o \ - 7zProperties.o \ - 7zRegister.o \ - 7zSpecStream.o \ - 7zUpdate.o \ - ApmHandler.o \ - ArHandler.o \ - ArchiveExports.o \ - ArjHandler.o \ - Bz2Handler.o \ - CabBlockInStream.o \ - CabHandler.o \ - CabHeader.o \ - CabIn.o \ - CabRegister.o \ - ChmHandler.o \ - ChmIn.o \ - ComHandler.o \ - CoderMixer2.o \ - DummyOutStream.o \ - FindSignature.o \ - HandlerOut.o \ - InStreamWithCRC.o \ - ItemNameUtils.o \ - MultiStream.o \ - OutStreamWithCRC.o \ - OutStreamWithSha1.o \ - ParseProperties.o \ - CpioHandler.o \ - CramfsHandler.o \ - DeflateProps.o \ - DllExports2.o \ - DmgHandler.o \ - ElfHandler.o \ - ExtHandler.o \ - FatHandler.o \ - FlvHandler.o \ - GzHandler.o \ - GptHandler.o \ - HandlerCont.o \ - HfsHandler.o \ - IhexHandler.o \ - IsoHandler.o \ - IsoHeader.o \ - IsoIn.o \ - IsoRegister.o \ - LzhHandler.o \ - LzmaHandler.o \ - MachoHandler.o \ - MbrHandler.o \ - MslzHandler.o \ - MubHandler.o \ - NsisDecode.o \ - NsisHandler.o \ - NsisIn.o \ - NsisRegister.o \ - NtfsHandler.o \ - PeHandler.o \ - PpmdHandler.o \ - QcowHandler.o \ - RarHandler.o \ - Rar5Handler.o \ - RpmHandler.o \ - SplitHandler.o \ - SquashfsHandler.o \ - SwfHandler.o \ - TarHandler.o \ - TarHandlerOut.o \ - TarHeader.o \ - TarIn.o \ - TarOut.o \ - TarRegister.o \ - TarUpdate.o \ - UdfHandler.o \ - UdfIn.o \ - UefiHandler.o \ - VdiHandler.o \ - VhdHandler.o \ - VmdkHandler.o \ - WimHandler.o \ - WimHandlerOut.o \ - WimIn.o \ - WimRegister.o \ - XarHandler.o \ - XzHandler.o \ - ZHandler.o \ - ZipAddCommon.o \ - ZipHandler.o \ - ZipHandlerOut.o \ - ZipIn.o \ - ZipItem.o \ - ZipOut.o \ - ZipRegister.o \ - ZipUpdate.o \ - CWrappers.o \ - CreateCoder.o \ - FilterCoder.o \ - InBuffer.o \ - InOutTempBuffer.o \ - LimitedStreams.o \ - MemBlocks.o \ - MethodId.o \ - MethodProps.o \ - OffsetStream.o \ - OutBuffer.o \ - OutMemStream.o \ - ProgressMt.o \ - ProgressUtils.o \ - PropId.o \ - StreamBinder.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - VirtThread.o \ - BZip2Crc.o \ - BZip2Decoder.o \ - BZip2Encoder.o \ - BZip2Register.o \ - Bcj2Coder.o \ - Bcj2Register.o \ - BcjCoder.o \ - BcjRegister.o \ - BitlDecoder.o \ - BranchMisc.o \ - BranchRegister.o \ - ByteSwap.o \ - CodecExports.o \ - CopyCoder.o \ - CopyRegister.o \ - Deflate64Register.o \ - DeflateDecoder.o \ - DeflateEncoder.o \ - DeflateRegister.o \ - DeltaFilter.o \ - ImplodeDecoder.o \ - ImplodeHuffmanDecoder.o \ - LzOutWindow.o \ - LzhDecoder.o \ - Lzma2Decoder.o \ - Lzma2Encoder.o \ - Lzma2Register.o \ - LzmaDecoder.o \ - LzmaEncoder.o \ - LzmaRegister.o \ - LzmsDecoder.o \ - LzxDecoder.o \ - PpmdDecoder.o \ - PpmdEncoder.o \ - PpmdRegister.o \ - PpmdZip.o \ - QuantumDecoder.o \ - ShrinkDecoder.o \ - ZDecoder.o \ - XpressDecoder.o \ - ZlibDecoder.o \ - ZlibEncoder.o \ - 7zAes.o \ - 7zAesRegister.o \ - HmacSha1.o \ - HmacSha256.o \ - MyAes.o \ - MyAesReg.o \ - Pbkdf2HmacSha1.o \ - RandGen.o \ - Rar20Crypto.o \ - Rar5Aes.o \ - RarAes.o \ - WzAes.o \ - ZipCrypto.o \ - ZipStrong.o \ - CRC.o \ - CrcReg.o \ - DynLimBuf.o \ - IntToString.o \ - MyMap.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - MyXml.o \ - NewHandler.o \ - Sha1Reg.o \ - Sha256Reg.o \ - StringConvert.o \ - StringToInt.o \ - UTFConvert.o \ - Wildcard.o \ - XzCrc64Reg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantUtils.o \ - Synchronization.o \ - System.o \ - TimeUtils.o \ - wine_date_and_time.o \ - $(OBJ_AES) \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,121 @@ +PROG = 7zra.dll +DEF_FILE = ../../Archive/Archive2.def +CFLAGS = $(CFLAGS) \ + -DZ7_NO_CRYPTO + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\IntToString.obj \ + $O\LzFindPrepare.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\InBuffer.obj \ + $O\InOutTempBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodId.obj \ + $O\MethodProps.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + $O\VirtThread.obj \ + +AR_OBJS = \ + $O\ArchiveExports.obj \ + $O\DllExports2.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\HandlerOut.obj \ + $O\InStreamWithCRC.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + $O\ParseProperties.obj \ + + +7Z_OBJS = \ + $O\7zCompressionMode.obj \ + $O\7zDecode.obj \ + $O\7zEncode.obj \ + $O\7zExtract.obj \ + $O\7zFolderInStream.obj \ + $O\7zHandler.obj \ + $O\7zHandlerOut.obj \ + $O\7zHeader.obj \ + $O\7zIn.obj \ + $O\7zOut.obj \ + $O\7zProperties.obj \ + $O\7zSpecStream.obj \ + $O\7zUpdate.obj \ + $O\7zRegister.obj \ + + +COMPRESS_OBJS = \ + $O\CodecExports.obj \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\ByteSwap.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Encoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bcj2Enc.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\Lzma2Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\MtCoder.obj \ + $O\MtDec.obj \ + $O\SwapBytes.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/Format7zR/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/Format7zR/resource.rc 2011-04-18 11:40:26.000000000 +0000 @@ -0,0 +1,5 @@ +#include "../../../../C/7zVersion.rc" + +MY_VERSION_INFO_DLL("7z Reduced Standalone Plugin", "7zr") + +101 ICON "../../Archive/Icons/7z.ico" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp 2024-11-29 10:00:00.000000000 +0000 @@ -1,779 +1,817 @@ -// LzmaAlone.cpp - -#include "StdAfx.h" - -#include - -#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE) -#include -#include -#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY) -#else -#define MY_SET_BINARY_MODE(file) -#endif - -#include "../../../Common/MyWindows.h" -#include "../../../Common/MyInitGuid.h" - -#include "../../../../C/7zVersion.h" -#include "../../../../C/Alloc.h" -#include "../../../../C/Lzma86.h" - -#include "../../../Windows/NtCheck.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/System.h" -#endif - -#include "../../../Common/IntToString.h" -#include "../../../Common/CommandLineParser.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/LzmaDecoder.h" -#include "../../Compress/LzmaEncoder.h" - -#include "../../UI/Console/BenchCon.h" -#include "../../UI/Console/ConsoleClose.h" - -using namespace NCommandLineParser; - -static const unsigned kDictSizeLog = 24; - -static const char *kCopyrightString = "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n\n"; - -static const char *kHelpString = - "Usage: LZMA [inputFile] [outputFile] [...]\n" - "\n" - "\n" - " e : Encode file\n" - " d : Decode file\n" - " b : Benchmark\n" - "\n" - " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" - " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n" - " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" - " -mc{N} : set number of cycles for match finder\n" - " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" - " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" - " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" - " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n" - " -mt{N} : set number of CPU threads\n" - " -eos : write end of stream marker\n" - " -si : read data from stdin\n" - " -so : write data to stdout\n"; - - -static const char *kCantAllocate = "Can not allocate memory"; -static const char *kReadError = "Read error"; -static const char *kWriteError = "Write error"; - - -namespace NKey { -enum Enum -{ - kHelp1 = 0, - kHelp2, - kMethod, - kLevel, - kAlgo, - kDict, - kFb, - kMc, - kLc, - kLp, - kPb, - kMatchFinder, - kMultiThread, - kEOS, - kStdIn, - kStdOut, - kFilter86 -}; -} - -static const CSwitchForm kSwitchForms[] = -{ - { "?", NSwitchType::kSimple, false }, - { "H", NSwitchType::kSimple, false }, - { "MM", NSwitchType::kString, false, 1 }, - { "X", NSwitchType::kString, false, 1 }, - { "A", NSwitchType::kString, false, 1 }, - { "D", NSwitchType::kString, false, 1 }, - { "FB", NSwitchType::kString, false, 1 }, - { "MC", NSwitchType::kString, false, 1 }, - { "LC", NSwitchType::kString, false, 1 }, - { "LP", NSwitchType::kString, false, 1 }, - { "PB", NSwitchType::kString, false, 1 }, - { "MF", NSwitchType::kString, false, 1 }, - { "MT", NSwitchType::kString, false, 0 }, - { "EOS", NSwitchType::kSimple, false }, - { "SI", NSwitchType::kSimple, false }, - { "SO", NSwitchType::kSimple, false }, - { "F86", NSwitchType::kChar, false, 0, "+" } -}; - - -static void PrintErr(const char *s) -{ - fputs(s, stderr); -} - -static void PrintErr_LF(const char *s) -{ - PrintErr(s); - fputc('\n', stderr); -} - - -static void PrintError(const char *s) -{ - PrintErr("\nERROR: "); - PrintErr_LF(s); -} - -static void PrintError2(const char *s1, const wchar_t *s2) -{ - PrintError(s1); - PrintErr_LF(GetOemString(s2)); -} - -static void PrintError_int(const char *s, int code) -{ - PrintError(s); - char temp[32]; - ConvertInt64ToString(code, temp); - PrintErr("Error code = "); - PrintErr_LF(temp); -} - - - -static void Print(const char *s) -{ - fputs(s, stdout); -} - -static void Print_UInt64(UInt64 v) -{ - char temp[32]; - ConvertUInt64ToString(v, temp); - Print(temp); -} - -static void Print_MB(UInt64 v) -{ - Print_UInt64(v); - Print(" MiB"); -} - -static void Print_Size(const char *s, UInt64 v) -{ - Print(s); - Print_UInt64(v); - Print(" ("); - Print_MB(v >> 20); - Print(")\n"); -} - -static void PrintTitle() -{ - Print(kCopyrightString); -} - -static void PrintHelp() -{ - PrintTitle(); - Print(kHelpString); -} - -class CProgressPrint: - public ICompressProgressInfo, - public CMyUnknownImp -{ - UInt64 _size1; - UInt64 _size2; -public: - CProgressPrint(): _size1(0), _size2(0) {} - - void ClosePrint(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -#define BACK_STR \ -"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" -static const char *kBackSpaces = -BACK_STR -" " -BACK_STR; - - -void CProgressPrint::ClosePrint() -{ - Print(kBackSpaces); -} - -STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - if (inSize) - { - UInt64 v1 = *inSize >> 20; - UInt64 v2 = _size2; - if (outSize) - v2 = *outSize >> 20; - if (v1 != _size1 || v2 != _size2) - { - _size1 = v1; - _size2 = v2; - ClosePrint(); - Print_MB(_size1); - Print(" -> "); - Print_MB(_size2); - } - } - return S_OK; -} - - -static void IncorrectCommand() -{ - throw "Incorrect command"; -} - -static UInt32 GetNumber(const wchar_t *s) -{ - const wchar_t *end; - UInt32 v = ConvertStringToUInt32(s, &end); - if (*end != 0) - IncorrectCommand(); - return v; -} - -static void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res) -{ - if (parser[index].ThereIs) - res = GetNumber(parser[index].PostStrings[0]); -} - - -static int Error_HRESULT(const char *s, HRESULT res) -{ - if (res == E_ABORT) - { - Print("\n\nBreak signaled\n"); - return 255; - } - - PrintError(s); - - if (res == E_OUTOFMEMORY) - { - PrintErr_LF(kCantAllocate); - return 8; - } - if (res == E_INVALIDARG) - { - PrintErr_LF("Ununsupported parameter"); - } - else - { - char temp[32]; - ConvertUInt32ToHex(res, temp); - PrintErr("Error code = 0x"); - PrintErr_LF(temp); - } - return 1; -} - -#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; - -static void AddProp(CObjectVector &props2, const char *name, const wchar_t *val) -{ - CProperty &prop = props2.AddNew(); - prop.Name.SetFromAscii(name); - prop.Value = val; -} - -static int main2(int numArgs, const char *args[]) -{ - NT_CHECK - - if (numArgs == 1) - { - PrintHelp(); - return 0; - } - - /* - bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 8); - if (unsupportedTypes) - throw "Unsupported base types. Edit Common/Types.h and recompile"; - */ - - UStringVector commandStrings; - for (int i = 1; i < numArgs; i++) - commandStrings.Add(MultiByteToUnicodeString(args[i])); - - CParser parser(ARRAY_SIZE(kSwitchForms)); - try - { - if (!parser.ParseStrings(kSwitchForms, commandStrings)) - { - PrintError2(parser.ErrorMessage, parser.ErrorLine); - return 1; - } - } - catch(...) - { - IncorrectCommand(); - } - - if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) - { - PrintHelp(); - return 0; - } - - bool stdInMode = parser[NKey::kStdIn].ThereIs; - bool stdOutMode = parser[NKey::kStdOut].ThereIs; - - if (!stdOutMode) - PrintTitle(); - - const UStringVector ¶ms = parser.NonSwitchStrings; - - unsigned paramIndex = 0; - if (paramIndex >= params.Size()) - IncorrectCommand(); - const UString &command = params[paramIndex++]; - - CObjectVector props2; - bool dictDefined = false; - UInt32 dict = (UInt32)(Int32)-1; - - if (parser[NKey::kDict].ThereIs) - { - UInt32 dictLog; - const UString &s = parser[NKey::kDict].PostStrings[0]; - dictLog = GetNumber(s); - dict = 1 << dictLog; - dictDefined = true; - AddProp(props2, "d", s); - } - - if (parser[NKey::kLevel].ThereIs) - { - const UString &s = parser[NKey::kLevel].PostStrings[0]; - /* UInt32 level = */ GetNumber(s); - AddProp(props2, "x", s); - } - - UString mf = L"BT4"; - if (parser[NKey::kMatchFinder].ThereIs) - mf = parser[NKey::kMatchFinder].PostStrings[0]; - - UInt32 numThreads = (UInt32)(Int32)-1; - - #ifndef _7ZIP_ST - - if (parser[NKey::kMultiThread].ThereIs) - { - const UString &s = parser[NKey::kMultiThread].PostStrings[0]; - if (s.IsEmpty()) - numThreads = NWindows::NSystem::GetNumberOfProcessors(); - else - numThreads = GetNumber(s); - AddProp(props2, "mt", s); - } - - #endif - - - if (parser[NKey::kMethod].ThereIs) - { - const UString &s = parser[NKey::kMethod].PostStrings[0]; - if (s.IsEmpty() || s[0] != '=') - IncorrectCommand(); - AddProp(props2, "m", s.Ptr(1)); - } - - if (StringsAreEqualNoCase_Ascii(command, "b")) - { - UInt32 numIterations = 1; - if (paramIndex < params.Size()) - numIterations = GetNumber(params[paramIndex++]); - if (params.Size() != paramIndex) - IncorrectCommand(); - - HRESULT res = BenchCon(props2, numIterations, stdout); - - if (res == S_OK) - return 0; - return Error_HRESULT("Benchmark error", res); - } - - { - UInt32 needParams = 3; - if (stdInMode) needParams--; - if (stdOutMode) needParams--; - if (needParams != params.Size()) - IncorrectCommand(); - } - - if (numThreads == (UInt32)(Int32)-1) - numThreads = 1; - - bool encodeMode = false; - - if (StringsAreEqualNoCase_Ascii(command, "e")) - encodeMode = true; - else if (!StringsAreEqualNoCase_Ascii(command, "d")) - IncorrectCommand(); - - CMyComPtr inStream; - CInFileStream *inStreamSpec = NULL; - - if (stdInMode) - { - inStream = new CStdInFileStream; - MY_SET_BINARY_MODE(stdin); - } - else - { - const UString &inputName = params[paramIndex++]; - inStreamSpec = new CInFileStream; - inStream = inStreamSpec; - if (!inStreamSpec->Open(us2fs(inputName))) - { - PrintError2("can not open input file", inputName); - return 1; - } - } - - CMyComPtr outStream; - COutFileStream *outStreamSpec = NULL; - - if (stdOutMode) - { - outStream = new CStdOutFileStream; - MY_SET_BINARY_MODE(stdout); - } - else - { - const UString &outputName = params[paramIndex++]; - outStreamSpec = new COutFileStream; - outStream = outStreamSpec; - if (!outStreamSpec->Create(us2fs(outputName), true)) - { - PrintError2("can not open output file", outputName); - return 1; - } - } - - bool fileSizeDefined = false; - UInt64 fileSize = 0; - - if (inStreamSpec) - { - if (!inStreamSpec->File.GetLength(fileSize)) - throw "Can not get file length"; - fileSizeDefined = true; - if (!stdOutMode) - Print_Size("Input size: ", fileSize); - } - - if (encodeMode && !dictDefined) - { - dict = 1 << kDictSizeLog; - if (fileSizeDefined) - { - unsigned i; - for (i = 16; i < kDictSizeLog; i++) - if ((UInt32)((UInt32)1 << i) >= fileSize) - break; - dict = (UInt32)1 << i; - } - } - - if (parser[NKey::kFilter86].ThereIs) - { - /* -f86 switch is for x86 filtered mode: BCJ + LZMA. - It uses modified header format. - It's not recommended to use -f86 mode now. - You can use xz format instead, if you want to use filters */ - - if (parser[NKey::kEOS].ThereIs || stdInMode) - throw "Can not use stdin in this mode"; - - size_t inSize = (size_t)fileSize; - - if (inSize != fileSize) - throw "File is too big"; - - Byte *inBuffer = NULL; - - if (inSize != 0) - { - inBuffer = (Byte *)MyAlloc((size_t)inSize); - if (!inBuffer) - throw kCantAllocate; - } - - if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK) - throw "Can not read"; - - Byte *outBuffer = NULL; - size_t outSize; - - if (encodeMode) - { - // we allocate 105% of original size for output buffer - UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16); - - outSize = (size_t)outSize64; - - if (outSize != outSize64) - throw "File is too big"; - - if (outSize != 0) - { - outBuffer = (Byte *)MyAlloc((size_t)outSize); - if (!outBuffer) - throw kCantAllocate; - } - - int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize, - 5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO); - - if (res != 0) - { - PrintError_int("Encode error", (int)res); - return 1; - } - } - else - { - UInt64 outSize64; - - if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0) - throw "data error"; - - outSize = (size_t)outSize64; - if (outSize != outSize64) - throw "Unpack size is too big"; - if (outSize != 0) - { - outBuffer = (Byte *)MyAlloc(outSize); - if (!outBuffer) - throw kCantAllocate; - } - - int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize); - - if (inSize != (size_t)fileSize) - throw "incorrect processed size"; - if (res != 0) - { - PrintError_int("Decode error", (int)res); - return 1; - } - } - - if (WriteStream(outStream, outBuffer, outSize) != S_OK) - throw kWriteError; - - MyFree(outBuffer); - MyFree(inBuffer); - } - else - { - - CProgressPrint *progressSpec = NULL; - CMyComPtr progress; - - if (!stdOutMode) - { - progressSpec = new CProgressPrint; - progress = progressSpec; - } - - if (encodeMode) - { - NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder; - CMyComPtr encoder = encoderSpec; - - UInt32 pb = 2; - UInt32 lc = 3; // = 0; for 32-bit data - UInt32 lp = 0; // = 2; for 32-bit data - UInt32 algo = 1; - UInt32 fb = 128; - UInt32 mc = 16 + fb / 2; - bool mcDefined = false; - - bool eos = parser[NKey::kEOS].ThereIs || stdInMode; - - ParseUInt32(parser, NKey::kAlgo, algo); - ParseUInt32(parser, NKey::kFb, fb); - ParseUInt32(parser, NKey::kLc, lc); - ParseUInt32(parser, NKey::kLp, lp); - ParseUInt32(parser, NKey::kPb, pb); - - mcDefined = parser[NKey::kMc].ThereIs; - if (mcDefined) - mc = GetNumber(parser[NKey::kMc].PostStrings[0]); - - const PROPID propIDs[] = - { - NCoderPropID::kDictionarySize, - NCoderPropID::kPosStateBits, - NCoderPropID::kLitContextBits, - NCoderPropID::kLitPosBits, - NCoderPropID::kAlgorithm, - NCoderPropID::kNumFastBytes, - NCoderPropID::kMatchFinder, - NCoderPropID::kEndMarker, - NCoderPropID::kNumThreads, - NCoderPropID::kMatchFinderCycles, - }; - - const unsigned kNumPropsMax = ARRAY_SIZE(propIDs); - - PROPVARIANT props[kNumPropsMax]; - for (int p = 0; p < 6; p++) - props[p].vt = VT_UI4; - - props[0].ulVal = (UInt32)dict; - props[1].ulVal = (UInt32)pb; - props[2].ulVal = (UInt32)lc; - props[3].ulVal = (UInt32)lp; - props[4].ulVal = (UInt32)algo; - props[5].ulVal = (UInt32)fb; - - props[6].vt = VT_BSTR; - props[6].bstrVal = const_cast((const wchar_t *)mf); - - props[7].vt = VT_BOOL; - props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; - - props[8].vt = VT_UI4; - props[8].ulVal = (UInt32)numThreads; - - // it must be last in property list - props[9].vt = VT_UI4; - props[9].ulVal = (UInt32)mc; - - unsigned numProps = kNumPropsMax; - if (!mcDefined) - numProps--; - - HRESULT res = encoderSpec->SetCoderProperties(propIDs, props, numProps); - if (res != S_OK) - return Error_HRESULT("incorrect encoder properties", res); - - if (encoderSpec->WriteCoderProperties(outStream) != S_OK) - throw kWriteError; - - bool fileSizeWasUsed = true; - if (eos || stdInMode) - { - fileSize = (UInt64)(Int64)-1; - fileSizeWasUsed = false; - } - - { - Byte temp[8]; - for (int i = 0; i < 8; i++) - temp[i]= (Byte)(fileSize >> (8 * i)); - if (WriteStream(outStream, temp, 8) != S_OK) - throw kWriteError; - } - - res = encoder->Code(inStream, outStream, NULL, NULL, progress); - if (progressSpec) - progressSpec->ClosePrint(); - - if (res != S_OK) - return Error_HRESULT("Encoding error", res); - - UInt64 processedSize = encoderSpec->GetInputProcessedSize(); - - if (fileSizeWasUsed && processedSize != fileSize) - throw "Incorrect size of processed data"; - } - else - { - NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder; - CMyComPtr decoder = decoderSpec; - - decoderSpec->FinishStream = true; - - const unsigned kPropertiesSize = 5; - Byte header[kPropertiesSize + 8]; - - if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK) - throw kReadError; - - if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK) - throw "SetDecoderProperties error"; - - UInt64 unpackSize = 0; - for (int i = 0; i < 8; i++) - unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i); - - bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1); - - HRESULT res = decoder->Code(inStream, outStream, NULL, unpackSizeDefined ? &unpackSize : NULL, progress); - if (progressSpec) - progressSpec->ClosePrint(); - - if (res != S_OK) - { - if (res == S_FALSE) - { - PrintError("Decoding error"); - return 1; - } - return Error_HRESULT("Decoding error", res); - } - - if (unpackSizeDefined && unpackSize != decoderSpec->GetOutputProcessedSize()) - throw "incorrect uncompressed size in header"; - } - } - - if (!stdOutMode) - Print_Size("Output size: ", outStreamSpec->ProcessedSize); - - if (outStreamSpec) - { - if (outStreamSpec->Close() != S_OK) - throw "File closing error"; - } - - return 0; -} - -int MY_CDECL main(int numArgs, const char *args[]) -{ - NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; - - try { return main2(numArgs, args); } - catch (const char *s) - { - PrintError(s); - return 1; - } - catch(...) - { - PrintError("Unknown Error"); - return 1; - } -} + // LzmaAlone.cpp + +#include "StdAfx.h" + +// #include + +#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE) +#include +#include +#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY) +#else +#define MY_SET_BINARY_MODE(file) +#endif + +#include "../../../../C/CpuArch.h" +#include "../../../../C/7zVersion.h" +#include "../../../../C/Alloc.h" +#include "../../../../C/Lzma86.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../Windows/NtCheck.h" + +#ifndef Z7_ST +#include "../../../Windows/System.h" +#endif + +#include "../../../Common/IntToString.h" +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/LzmaDecoder.h" +#include "../../Compress/LzmaEncoder.h" + +#include "../../UI/Console/BenchCon.h" +#include "../../UI/Console/ConsoleClose.h" + +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; + +using namespace NCommandLineParser; + +static const unsigned kDictSizeLog = 24; + +#define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n" + +static const char * const kHelpString = + "Usage: lzma [inputFile] [outputFile] [...]\n" + "\n" + "\n" + " e : Encode file\n" + " d : Decode file\n" + " b : Benchmark\n" + "\n" + " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" + " -d{N} : set dictionary size : [12, 31] : default = 24 (16 MiB)\n" + " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" + " -mc{N} : set number of cycles for match finder\n" + " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" + " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" + " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" + " -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n" + " -mt{N} : set number of CPU threads\n" + " -eos : write end of stream marker\n" + " -si : read data from stdin\n" + " -so : write data to stdout\n"; + + +static const char * const kCantAllocate = "Cannot allocate memory"; +static const char * const kReadError = "Read error"; +static const char * const kWriteError = "Write error"; + + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kMethod, + kLevel, + kAlgo, + kDict, + kFb, + kMc, + kLc, + kLp, + kPb, + kMatchFinder, + kMultiThread, + kEOS, + kStdIn, + kStdOut, + kFilter86 +}; +} + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL + +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_STRING SWFRM_1(NSwitchType::kString) + +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) + +static const CSwitchForm kSwitchForms[] = +{ + { "?", SWFRM_SIMPLE }, + { "H", SWFRM_SIMPLE }, + { "MM", SWFRM_STRING_SINGL(1) }, + { "X", SWFRM_STRING_SINGL(1) }, + { "A", SWFRM_STRING_SINGL(1) }, + { "D", SWFRM_STRING_SINGL(1) }, + { "FB", SWFRM_STRING_SINGL(1) }, + { "MC", SWFRM_STRING_SINGL(1) }, + { "LC", SWFRM_STRING_SINGL(1) }, + { "LP", SWFRM_STRING_SINGL(1) }, + { "PB", SWFRM_STRING_SINGL(1) }, + { "MF", SWFRM_STRING_SINGL(1) }, + { "MT", SWFRM_STRING }, + { "EOS", SWFRM_SIMPLE }, + { "SI", SWFRM_SIMPLE }, + { "SO", SWFRM_SIMPLE }, + { "F86", NSwitchType::kChar, false, 0, "+" } +}; + + +static void Convert_UString_to_AString(const UString &s, AString &temp) +{ + int codePage = CP_OEMCP; + /* + int g_CodePage = -1; + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + */ + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); +} + +static void PrintErr(const char *s) +{ + fputs(s, stderr); +} + +static void PrintErr_LF(const char *s) +{ + PrintErr(s); + fputc('\n', stderr); +} + + +static void PrintError(const char *s) +{ + PrintErr("\nERROR: "); + PrintErr_LF(s); +} + +static void PrintError2(const char *s1, const UString &s2) +{ + PrintError(s1); + AString a; + Convert_UString_to_AString(s2, a); + PrintErr_LF(a); +} + +static void PrintError_int(const char *s, int code) +{ + PrintError(s); + char temp[32]; + ConvertInt64ToString(code, temp); + PrintErr("Error code = "); + PrintErr_LF(temp); +} + + + +static void Print(const char *s) +{ + fputs(s, stdout); +} + +static void Print_UInt64(UInt64 v) +{ + char temp[32]; + ConvertUInt64ToString(v, temp); + Print(temp); +} + +static void Print_MB(UInt64 v) +{ + Print_UInt64(v); + Print(" MiB"); +} + +static void Print_Size(const char *s, UInt64 v) +{ + Print(s); + Print_UInt64(v); + Print(" ("); + Print_MB(v >> 20); + Print(")\n"); +} + +static void PrintTitle() +{ + Print(kCopyrightString); +} + +static void PrintHelp() +{ + PrintTitle(); + Print(kHelpString); +} + + +Z7_CLASS_IMP_COM_1( + CProgressPrint, + ICompressProgressInfo +) + UInt64 _size1; + UInt64 _size2; +public: + CProgressPrint(): _size1(0), _size2(0) {} + + void ClosePrint(); +}; + +#define BACK_STR \ +"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" +static const char * const kBackSpaces = +BACK_STR +" " +BACK_STR; + + +void CProgressPrint::ClosePrint() +{ + Print(kBackSpaces); +} + +Z7_COM7F_IMF(CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + if (inSize) + { + UInt64 v1 = *inSize >> 20; + UInt64 v2 = _size2; + if (outSize) + v2 = *outSize >> 20; + if (v1 != _size1 || v2 != _size2) + { + _size1 = v1; + _size2 = v2; + ClosePrint(); + Print_MB(_size1); + Print(" -> "); + Print_MB(_size2); + } + } + return S_OK; +} + + +Z7_ATTR_NORETURN +static void IncorrectCommand() +{ + throw "Incorrect command"; +} + +static UInt32 GetNumber(const wchar_t *s) +{ + const wchar_t *end; + UInt32 v = ConvertStringToUInt32(s, &end); + if (*end != 0) + IncorrectCommand(); + return v; +} + +static void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res) +{ + if (parser[index].ThereIs) + res = GetNumber(parser[index].PostStrings[0]); +} + + +static int Error_HRESULT(const char *s, HRESULT res) +{ + if (res == E_ABORT) + { + Print("\n\nBreak signaled\n"); + return 255; + } + + PrintError(s); + + if (res == E_OUTOFMEMORY) + { + PrintErr_LF(kCantAllocate); + return 8; + } + if (res == E_INVALIDARG) + { + PrintErr_LF("Ununsupported parameter"); + } + else + { + char temp[32]; + ConvertUInt32ToHex((UInt32)res, temp); + PrintErr("Error code = 0x"); + PrintErr_LF(temp); + } + return 1; +} + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; +#endif + +static void AddProp(CObjectVector &props2, const char *name, const wchar_t *val) +{ + CProperty &prop = props2.AddNew(); + prop.Name = name; + prop.Value = val; +} + +static int main2(int numArgs, const char *args[]) +{ + NT_CHECK + + if (numArgs == 1) + { + PrintHelp(); + return 0; + } + + /* + bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 8); + if (unsupportedTypes) + throw "Unsupported base types. Edit Common/Types.h and recompile"; + */ + + UStringVector commandStrings; + for (int i = 1; i < numArgs; i++) + commandStrings.Add(MultiByteToUnicodeString(args[i])); + + CParser parser; + try + { + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) + { + PrintError2(parser.ErrorMessage, parser.ErrorLine); + return 1; + } + } + catch(...) + { + IncorrectCommand(); + } + + if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + + const bool stdInMode = parser[NKey::kStdIn].ThereIs; + const bool stdOutMode = parser[NKey::kStdOut].ThereIs; + + if (!stdOutMode) + PrintTitle(); + + const UStringVector ¶ms = parser.NonSwitchStrings; + + unsigned paramIndex = 0; + if (paramIndex >= params.Size()) + IncorrectCommand(); + const UString &command = params[paramIndex++]; + + CObjectVector props2; + bool dictDefined = false; + UInt32 dict = (UInt32)(Int32)-1; + + if (parser[NKey::kDict].ThereIs) + { + UInt32 dictLog; + const UString &s = parser[NKey::kDict].PostStrings[0]; + dictLog = GetNumber(s); + if (dictLog >= 32) + throw "unsupported dictionary size"; + // we only want to use dictionary sizes that are powers of 2, + // because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0 +#if 0 + if (dictLog == 32) + dict = (UInt32)3840 << 20; + else +#endif + dict = (UInt32)1 << dictLog; + dictDefined = true; + AddProp(props2, "d", s); + } + + if (parser[NKey::kLevel].ThereIs) + { + const UString &s = parser[NKey::kLevel].PostStrings[0]; + /* UInt32 level = */ GetNumber(s); + AddProp(props2, "x", s); + } + + UString mf ("BT4"); + if (parser[NKey::kMatchFinder].ThereIs) + mf = parser[NKey::kMatchFinder].PostStrings[0]; + + UInt32 numThreads = (UInt32)(Int32)-1; + + #ifndef Z7_ST + + if (parser[NKey::kMultiThread].ThereIs) + { + const UString &s = parser[NKey::kMultiThread].PostStrings[0]; + if (s.IsEmpty()) + numThreads = NWindows::NSystem::GetNumberOfProcessors(); + else + numThreads = GetNumber(s); + AddProp(props2, "mt", s); + } + + #endif + + + if (parser[NKey::kMethod].ThereIs) + { + const UString &s = parser[NKey::kMethod].PostStrings[0]; + if (s.IsEmpty() || s[0] != '=') + IncorrectCommand(); + AddProp(props2, "m", s.Ptr(1)); + } + + if (StringsAreEqualNoCase_Ascii(command, "b")) + { + UInt32 numIterations = 1; + if (paramIndex < params.Size()) + numIterations = GetNumber(params[paramIndex++]); + if (params.Size() != paramIndex) + IncorrectCommand(); + + HRESULT res = BenchCon(props2, numIterations, stdout); + + if (res == S_OK) + return 0; + return Error_HRESULT("Benchmark error", res); + } + + { + UInt32 needParams = 3; + if (stdInMode) needParams--; + if (stdOutMode) needParams--; + if (needParams != params.Size()) + IncorrectCommand(); + } + + if (numThreads == (UInt32)(Int32)-1) + numThreads = 1; + + bool encodeMode = false; + + if (StringsAreEqualNoCase_Ascii(command, "e")) + encodeMode = true; + else if (!StringsAreEqualNoCase_Ascii(command, "d")) + IncorrectCommand(); + + CMyComPtr inStream; + CInFileStream *inStreamSpec = NULL; + + if (stdInMode) + { + inStream = new CStdInFileStream; + MY_SET_BINARY_MODE(stdin); + } + else + { + const UString &inputName = params[paramIndex++]; + inStreamSpec = new CInFileStream; + inStream = inStreamSpec; + if (!inStreamSpec->Open(us2fs(inputName))) + { + PrintError2("Cannot open input file", inputName); + return 1; + } + } + + CMyComPtr outStream; + COutFileStream *outStreamSpec = NULL; + + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + const UString &outputName = params[paramIndex++]; + outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + if (!outStreamSpec->Create_ALWAYS(us2fs(outputName))) + { + PrintError2("Cannot open output file", outputName); + return 1; + } + } + + bool fileSizeDefined = false; + UInt64 fileSize = 0; + + if (inStreamSpec) + { + if (!inStreamSpec->GetLength(fileSize)) + throw "Cannot get file length"; + fileSizeDefined = true; + if (!stdOutMode) + Print_Size("Input size: ", fileSize); + } + + if (encodeMode && !dictDefined) + { + dict = (UInt32)1 << kDictSizeLog; + if (fileSizeDefined) + { + unsigned i; + for (i = 16; i < kDictSizeLog; i++) + if ((UInt32)((UInt32)1 << i) >= fileSize) + break; + dict = (UInt32)1 << i; + } + } + + if (parser[NKey::kFilter86].ThereIs) + { + /* -f86 switch is for x86 filtered mode: BCJ + LZMA. + It uses modified header format. + It's not recommended to use -f86 mode now. + You can use xz format instead, if you want to use filters */ + + if (parser[NKey::kEOS].ThereIs || stdInMode) + throw "Cannot use stdin in this mode"; + + size_t inSize = (size_t)fileSize; + + if (inSize != fileSize) + throw "File is too big"; + + Byte *inBuffer = NULL; + + if (inSize != 0) + { + inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (!inBuffer) + throw kCantAllocate; + } + + if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK) + throw "Cannot read"; + + Byte *outBuffer = NULL; + size_t outSize; + + if (encodeMode) + { + // we allocate 105% of original size for output buffer + UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16); + + outSize = (size_t)outSize64; + + if (outSize != outSize64) + throw "File is too big"; + + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (!outBuffer) + throw kCantAllocate; + } + + int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize, + 5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO); + + if (res != 0) + { + PrintError_int("Encode error", (int)res); + return 1; + } + } + else + { + UInt64 outSize64; + + if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0) + throw "data error"; + + outSize = (size_t)outSize64; + if (outSize != outSize64) + throw "Unpack size is too big"; + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc(outSize); + if (!outBuffer) + throw kCantAllocate; + } + + int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize); + + if (inSize != (size_t)fileSize) + throw "incorrect processed size"; + if (res != 0) + { + PrintError_int("Decode error", (int)res); + return 1; + } + } + + if (WriteStream(outStream, outBuffer, outSize) != S_OK) + throw kWriteError; + + MyFree(outBuffer); + MyFree(inBuffer); + } + else + { + + CProgressPrint *progressSpec = NULL; + CMyComPtr progress; + + if (!stdOutMode) + { + progressSpec = new CProgressPrint; + progress = progressSpec; + } + + if (encodeMode) + { + NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder; + CMyComPtr encoder = encoderSpec; + + UInt32 pb = 2; + UInt32 lc = 3; // = 0; for 32-bit data + UInt32 lp = 0; // = 2; for 32-bit data + UInt32 algo = 1; + UInt32 fb = 128; + UInt32 mc = 16 + fb / 2; + bool mcDefined = false; + + bool eos = parser[NKey::kEOS].ThereIs || stdInMode; + + ParseUInt32(parser, NKey::kAlgo, algo); + ParseUInt32(parser, NKey::kFb, fb); + ParseUInt32(parser, NKey::kLc, lc); + ParseUInt32(parser, NKey::kLp, lp); + ParseUInt32(parser, NKey::kPb, pb); + + mcDefined = parser[NKey::kMc].ThereIs; + if (mcDefined) + mc = GetNumber(parser[NKey::kMc].PostStrings[0]); + + const PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker, + NCoderPropID::kNumThreads, + NCoderPropID::kMatchFinderCycles, + }; + + const unsigned kNumPropsMax = Z7_ARRAY_SIZE(propIDs); + + PROPVARIANT props[kNumPropsMax]; + for (int p = 0; p < 6; p++) + props[p].vt = VT_UI4; + + props[0].ulVal = (UInt32)dict; + props[1].ulVal = (UInt32)pb; + props[2].ulVal = (UInt32)lc; + props[3].ulVal = (UInt32)lp; + props[4].ulVal = (UInt32)algo; + props[5].ulVal = (UInt32)fb; + + props[6].vt = VT_BSTR; + props[6].bstrVal = const_cast((const wchar_t *)mf); + + props[7].vt = VT_BOOL; + props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE; + + props[8].vt = VT_UI4; + props[8].ulVal = (UInt32)numThreads; + + // it must be last in property list + props[9].vt = VT_UI4; + props[9].ulVal = (UInt32)mc; + + unsigned numProps = kNumPropsMax; + if (!mcDefined) + numProps--; + + HRESULT res = encoderSpec->SetCoderProperties(propIDs, props, numProps); + if (res != S_OK) + return Error_HRESULT("incorrect encoder properties", res); + + if (encoderSpec->WriteCoderProperties(outStream) != S_OK) + throw kWriteError; + + bool fileSizeWasUsed = true; + if (eos || stdInMode) + { + fileSize = (UInt64)(Int64)-1; + fileSizeWasUsed = false; + } + + { + Byte temp[8]; + for (int i = 0; i < 8; i++) + temp[i]= (Byte)(fileSize >> (8 * i)); + if (WriteStream(outStream, temp, 8) != S_OK) + throw kWriteError; + } + + res = encoder->Code(inStream, outStream, NULL, NULL, progress); + if (progressSpec) + progressSpec->ClosePrint(); + + if (res != S_OK) + return Error_HRESULT("Encoding error", res); + + UInt64 processedSize = encoderSpec->GetInputProcessedSize(); + + if (fileSizeWasUsed && processedSize != fileSize) + throw "Incorrect size of processed data"; + } + else + { + NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder; + CMyComPtr decoder = decoderSpec; + + decoderSpec->FinishStream = true; + + const unsigned kPropertiesSize = 5; + Byte header[kPropertiesSize + 8]; + + if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK) + throw kReadError; + + if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK) + throw "SetDecoderProperties error"; + + UInt64 unpackSize = 0; + for (unsigned i = 0; i < 8; i++) + unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i); + + bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1); + + HRESULT res = decoder->Code(inStream, outStream, NULL, unpackSizeDefined ? &unpackSize : NULL, progress); + if (progressSpec) + progressSpec->ClosePrint(); + + if (res != S_OK) + { + if (res == S_FALSE) + { + PrintError("Decoding error"); + return 1; + } + return Error_HRESULT("Decoding error", res); + } + + if (unpackSizeDefined && unpackSize != decoderSpec->GetOutputProcessedSize()) + throw "incorrect uncompressed size in header"; + } + } + + if (outStreamSpec) + { + if (!stdOutMode) + Print_Size("Output size: ", outStreamSpec->ProcessedSize); + if (outStreamSpec->Close() != S_OK) + throw "File closing error"; + } + + return 0; +} + +int Z7_CDECL main(int numArgs, const char *args[]) +{ + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; + + try { return main2(numArgs, args); } + catch (const char *s) + { + PrintError(s); + return 1; + } + catch(...) + { + PrintError("Unknown Error"); + return 1; + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp 2024-01-27 10:00:00.000000000 +0000 @@ -0,0 +1,540 @@ +# Microsoft Developer Studio Project File - Name="LzmaCon" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=LzmaCon - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LzmaCon.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LzmaCon.mak" CFG="LzmaCon - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LzmaCon - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "LzmaCon - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LzmaCon - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_NO_LONG_PATH" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\lzma.exe" + +!ELSEIF "$(CFG)" == "LzmaCon - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_NO_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\lzma.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "LzmaCon - Win32 Release" +# Name "LzmaCon - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaEncoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CrcReg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\LzFindPrepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyUnknown.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Bench.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\BenchCon.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzFindOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzHash.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma86.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma86Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma86Enc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaEnc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\LzmaAlone.cpp +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsw 2009-12-01 20:50:26.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "LzmaCon"=.\LzmaCon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile 2016-03-10 20:23:25.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile 2024-01-27 10:00:00.000000000 +0000 @@ -1,32 +1,68 @@ - -# TARGET_FLAGS=-D_7ZIP_ST - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -include ../../../../makefile.glb - -test: $(PROG) - echo TOOLS=$(TOOLS) - cp LzmaAlone.cpp testfile - $(TOOLS) ./$(PROG) e testfile testfile.lzma - $(TOOLS) ./$(PROG) d testfile.lzma testfile.lzma.d - diff -s testfile testfile.lzma.d - $(TOOLS) ./$(PROG) e testfile testfile.lzma - $(TOOLS) ./$(PROG) d testfile.lzma testfile.lzma.d - diff -s testfile testfile.lzma.d - $(TOOLS) ./$(PROG) e -si -so < testfile > testfile.lzma.2 - $(TOOLS) ./$(PROG) d -si -so < testfile.lzma.2 > testfile.lzma.2.d - diff -s testfile testfile.lzma.2.d - @echo ========= - @echo All Done - @echo ========= - - -clean2: clean - rm -f testfile* - +PROG = lzma.exe +MY_CONSOLE = 1 + +CFLAGS = $(CFLAGS) -DZ7_NO_LONG_PATH +# CFLAGS = $(CFLAGS) -DZ7_ST + + +CURRENT_OBJS = \ + $O\LzmaAlone.obj \ + +COMPRESS_OBJS = \ + $O\LzmaDecoder.obj \ + $O\LzmaEncoder.obj \ + $O\LzmaRegister.obj \ + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\CrcReg.obj \ + $O\IntToString.obj \ + $O\LzFindPrepare.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\FileIO.obj \ + $O\PropVariant.obj \ + $O\Registry.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\MethodProps.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\Bench.obj \ + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\BenchCon.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\Bra86.obj \ + $O\CpuArch.obj \ + $O\LzFind.obj \ + $O\LzFindMt.obj \ + $O\Lzma86Dec.obj \ + $O\Lzma86Enc.obj \ + $O\LzmaDec.obj \ + $O\LzmaEnc.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../LzFindOpt.mak" +!include "../../LzmaDec.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -0,0 +1,131 @@ +PROG = lzma + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +else + +MT_OBJS = \ + $O/LzFindMt.o \ + $O/LzFindOpt.o \ + $O/Threads.o \ + $O/Synchronization.o \ + + + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +SYS_OBJS = \ + $O/Registry.o \ + $O/resource.o \ + +LOCAL_FLAGS_SYS = \ + -DZ7_NO_LONG_PATH \ + +else + +SYS_OBJS = \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileName.o \ + $O/MyWindows.o \ + $O/TimeUtils.o \ + +endif + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/IntToString.o \ + $O/LzFindPrepare.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/FileIO.o \ + $O/PropVariant.o \ + $O/System.o \ + $O/SystemInfo.o \ + +COMPRESS_OBJS = \ + $O/LzmaDecoder.o \ + $O/LzmaEncoder.o \ + $O/LzmaRegister.o \ + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FileStreams.o \ + $O/FilterCoder.o \ + $O/MethodProps.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + +C_OBJS = \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/Alloc.o \ + $O/Bra86.o \ + $O/CpuArch.o \ + $O/LzFind.o \ + $O/LzmaDec.o \ + $O/LzmaEnc.o \ + $O/Lzma86Dec.o \ + $O/Lzma86Enc.o \ + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + $O/LzmaAlone.o \ + $O/Bench.o \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.list --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/LzmaCon$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -SRCS=\ - ../../../../CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/C_FileIO.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bra86.c \ - ../../../../C/CpuArch.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/Lzma86Dec.c \ - ../../../../C/Lzma86Enc.c \ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -Bra86.o : ../../../../C/Bra86.c - $(CC) $(CFLAGS) ../../../../C/Bra86.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -LzFind.o : ../../../../C/LzFind.c - $(CC) $(CFLAGS) ../../../../C/LzFind.c -LzFindMt.o : ../../../../C/LzFindMt.c - $(CC) $(CFLAGS) ../../../../C/LzFindMt.c -LzmaDec.o : ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) ../../../../C/LzmaDec.c -LzmaEnc.o : ../../../../C/LzmaEnc.c - $(CC) $(CFLAGS) ../../../../C/LzmaEnc.c -Lzma86Dec.o : ../../../../C/Lzma86Dec.c - $(CC) $(CFLAGS) ../../../../C/Lzma86Dec.c -Lzma86Enc.o : ../../../../C/Lzma86Enc.c - $(CC) $(CFLAGS) ../../../../C/Lzma86Enc.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -LzmaAlone.o : ../../../../CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp -CWrappers.o : ../../../../CPP/7zip/Common/CWrappers.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CWrappers.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -LzmaDecoder.o : ../../../../CPP/7zip/Compress/LzmaDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaDecoder.cpp -LzmaEncoder.o : ../../../../CPP/7zip/Compress/LzmaEncoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaEncoder.cpp -LzmaRegister.o : ../../../../CPP/7zip/Compress/LzmaRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaRegister.cpp -Bench.o : ../../../../CPP/7zip/UI/Common/Bench.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Bench.cpp -BenchCon.o : ../../../../CPP/7zip/UI/Console/BenchCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/BenchCon.cpp -ConsoleClose.o : ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -CrcReg.o : ../../../../CPP/Common/CrcReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CrcReg.cpp -C_FileIO.o : ../../../../CPP/Common/C_FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/C_FileIO.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Alloc.o \ - Bra86.o \ - CpuArch.o \ - LzFind.o \ - LzFindMt.o \ - LzmaDec.o \ - LzmaEnc.o \ - Lzma86Dec.o \ - Lzma86Enc.o \ - Threads.o \ - LzmaAlone.o \ - CWrappers.o \ - CreateCoder.o \ - FileStreams.o \ - FilterCoder.o \ - MethodProps.o \ - OutBuffer.o \ - StreamUtils.o \ - LzmaDecoder.o \ - LzmaEncoder.o \ - LzmaRegister.o \ - Bench.o \ - BenchCon.o \ - ConsoleClose.o \ - CRC.o \ - CommandLineParser.o \ - CrcReg.o \ - C_FileIO.o \ - IntToString.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - NewHandler.o \ - StringConvert.o \ - StringToInt.o \ - PropVariant.o \ - System.o \ - wine_date_and_time.o \ - $(OBJ_AES) \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/LzmaCon/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/LzmaCon/resource.rc 2013-01-25 07:38:49.000000000 +0000 @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("LZMA", "lzma") Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/7z.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/7z.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SFXCon.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SFXCon.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsp 2024-02-09 08:00:00.000000000 +0000 @@ -0,0 +1,1017 @@ +# Microsoft Developer Studio Project File - Name="SFXCon" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=SFXCon - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXCon.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXCon.mak" CFG="SFXCon - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXCon - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "SFXCon - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXCon - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /FAcs /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\Util\7zCon.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /I "..\..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_SFX" /D "Z7_NO_READ_FROM_CODER" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\Util\7zCon.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "SFXCon - Win32 Release" +# Name "SFXCon - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\HandlerOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\List.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Console\UserInputUtils.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\SplitHandler.cpp +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdRegister.cpp +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAesRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OffsetStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterCodec.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\PropIDUtils.h +# End Source File +# End Group +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\AesOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c + +!IF "$(CFG)" == "SFXCon - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "SFXCon - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico +# End Source File +# Begin Source File + +SOURCE=.\SfxCon.cpp +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SFXCon.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SFXCon.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SFXCon.dsw 2001-09-24 23:36:34.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXCon"=.\SFXCon.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SfxCon.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SfxCon.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/SfxCon.cpp 2016-05-20 08:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/SfxCon.cpp 2024-06-18 08:00:00.000000000 +0000 @@ -1,466 +1,521 @@ -// Main.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyWindows.h" - -#include "../../../Common/MyInitGuid.h" - -#include "../../../Common/CommandLineParser.h" -#include "../../../Common/MyException.h" - -#ifdef _WIN32 -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" -#else -#include "myPrivate.h" -#endif -#include "../../../Windows/FileName.h" - -#include "../../UI/Common/ExitCode.h" -#include "../../UI/Common/Extract.h" - -#include "../../UI/Console/ExtractCallbackConsole.h" -#include "../../UI/Console/List.h" -#include "../../UI/Console/OpenCallbackConsole.h" - -#include "../../MyVersion.h" - -using namespace NWindows; -using namespace NFile; -// FIXME using namespace NDir; -using namespace NCommandLineParser; - -#ifdef _WIN32 -HINSTANCE g_hInstance = 0; -#endif -int g_CodePage = -1; -extern CStdOutStream *g_StdStream; - -static const char *kCopyrightString = -"\n7-Zip SFX " MY_VERSION_COPYRIGHT_DATE "\n"; - -static const int kNumSwitches = 6; - -namespace NKey { -enum Enum -{ - kHelp1 = 0, - kHelp2, - kDisablePercents, - kYes, - kPassword, - kOutputDir -}; - -} - -namespace NRecursedType { -enum EEnum -{ - kRecursed, - kWildcardOnlyRecursed, - kNonRecursed -}; -} -/* -static const char kRecursedIDChar = 'R'; -static const wchar_t *kRecursedPostCharSet = L"0-"; - -namespace NRecursedPostCharIndex { - enum EEnum - { - kWildcardRecursionOnly = 0, - kNoRecursion = 1 - }; -} - -static const char kFileListID = '@'; -static const char kImmediateNameID = '!'; - -static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be -static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be -*/ -static const CSwitchForm kSwitchForms[kNumSwitches] = -{ - { "?", NSwitchType::kSimple }, - { "H", NSwitchType::kSimple }, - { "BD", NSwitchType::kSimple }, - { "Y", NSwitchType::kSimple }, - { "P", NSwitchType::kString, false, 1 }, - { "O", NSwitchType::kString, false, 1 }, -}; - -static const int kNumCommandForms = 3; - -static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] = -{ - NRecursedType::kRecursed -}; - -// static const bool kTestExtractRecursedDefault = true; -// static const bool kAddRecursedDefault = false; - -static const wchar_t *kUniversalWildcard = L"*"; -static const int kCommandIndex = 0; - -static const char *kHelpString = - "\nUsage: 7zSFX [] [...]\n" - "\n" - "\n" - // " l: List contents of archive\n" - " t: Test integrity of archive\n" - " x: eXtract files with full pathname (default)\n" - "\n" - // " -bd Disable percentage indicator\n" - " -o{Directory}: set Output directory\n" - " -p{Password}: set Password\n" - " -y: assume Yes on all queries\n"; - - -// --------------------------- -// exception messages - -static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError -// static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; -static const char *kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line"; - -// static const CSysString kFileIsNotArchiveMessageBefore = "File \""; -// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; - -// static const char *kProcessArchiveMessage = " archive: "; - -static const char *kCantFindSFX = " cannot find sfx"; - -namespace NCommandType -{ - enum EEnum - { - kTest = 0, - kFullExtract, - kList - }; -} - -static const char *g_Commands = "txl"; - -struct CArchiveCommand -{ - NCommandType::EEnum CommandType; - - NRecursedType::EEnum DefaultRecursedType() const; -}; - -bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) -{ - UString s = commandString; - s.MakeLower_Ascii(); - if (s.Len() != 1) - return false; - if (s[0] >= 0x80) - return false; - int index = FindCharPosInString(g_Commands, (char)s[0]); - if (index < 0) - return false; - command.CommandType = (NCommandType::EEnum)index; - return true; -} - -NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const -{ - return kCommandRecursedDefault[CommandType]; -} - -void PrintHelp(void) -{ - g_StdOut << kHelpString; -} - -static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code) -{ - g_StdOut << message << endl; - throw code; -} - -static void PrintHelpAndExit() // yyy -{ - PrintHelp(); - ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); -} - -// ------------------------------------------------------------------ -// filenames functions - -static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, - const UString &name, bool include, NRecursedType::EEnum type) -{ - /* - if (!IsWildcardFilePathLegal(name)) - return false; - */ - bool isWildcard = DoesNameContainWildcard(name); - bool recursed = false; - - switch (type) - { - case NRecursedType::kWildcardOnlyRecursed: - recursed = isWildcard; - break; - case NRecursedType::kRecursed: - recursed = true; - break; - case NRecursedType::kNonRecursed: - recursed = false; - break; - } - wildcardCensor.AddPreItem(include, name, recursed, true); - return true; -} - -void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor, - const UString &name, bool include, NRecursedType::EEnum type) -{ - if (!AddNameToCensor(wildcardCensor, name, include, type)) - ShowMessageAndThrowException(kIncorrectWildcardInCommandLine, NExitCode::kUserError); -} - -void AddToCensorFromNonSwitchesStrings(NWildcard::CCensor &wildcardCensor, - const UStringVector & /* nonSwitchStrings */, NRecursedType::EEnum type, - bool /* thereAreSwitchIncludeWildcards */) -{ - AddCommandLineWildcardToCensor(wildcardCensor, kUniversalWildcard, true, type); -} - - -#if 0 // #ifndef _WIN32 -static void GetArguments(int numArgs, const char *args[], UStringVector &parts) -{ - parts.Clear(); - for (int i = 0; i < numArgs; i++) - { - UString s = MultiByteToUnicodeString(args[i]); - parts.Add(s); - } -} -#endif - -int Main2( - #ifndef _WIN32 - int numArgs, char *args[] - #endif -) -{ - #if defined(_WIN32) && !defined(UNDER_CE) - SetFileApisToOEM(); - #endif - - g_StdOut << kCopyrightString; - - UStringVector commandStrings; - #ifdef _WIN32 - NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); - #else - // GetArguments(numArgs, args, commandStrings); - mySplitCommandLine(numArgs,args,commandStrings); - #endif - - #ifdef _WIN32 - - FString arcPath; - { - FString path; - NDLL::MyGetModuleFileName(path); - if (!MyGetFullPathName(path, arcPath)) - { - g_StdOut << "GetFullPathName Error"; - return NExitCode::kFatalError; - } - } - - #else - // After mySplitCommandLine - showP7zipInfo(&g_StdOut); - - UString arcPath = commandStrings.Front(); - - #endif - - commandStrings.Delete(0); - - NCommandLineParser::CParser parser(kNumSwitches); - try - { - parser.ParseStrings(kSwitchForms, commandStrings); - } - catch(...) - { - PrintHelpAndExit(); - } - - if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) - { - PrintHelp(); - return 0; - } - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - - int numNonSwitchStrings = nonSwitchStrings.Size(); - - CArchiveCommand command; - if (numNonSwitchStrings == 0) - command.CommandType = NCommandType::kFullExtract; - else - { - if (numNonSwitchStrings > 1) - PrintHelpAndExit(); - if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], command)) - PrintHelpAndExit(); - } - - - NRecursedType::EEnum recursedType; - recursedType = command.DefaultRecursedType(); - - NWildcard::CCensor wildcardCensor; - - bool thereAreSwitchIncludeWildcards; - thereAreSwitchIncludeWildcards = false; - - AddToCensorFromNonSwitchesStrings(wildcardCensor, nonSwitchStrings, recursedType, - thereAreSwitchIncludeWildcards); - - bool yesToAll = parser[NKey::kYes].ThereIs; - - // NExtractMode::EEnum extractMode; - // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); - - bool passwordEnabled = parser[NKey::kPassword].ThereIs; - - UString password; - if (passwordEnabled) - password = parser[NKey::kPassword].PostStrings[0]; - - if (!NFind::DoesFileExist(arcPath)) - throw kCantFindSFX; - - FString outputDir; - if (parser[NKey::kOutputDir].ThereIs) - { - outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); - NName::NormalizeDirPathPrefix(outputDir); - } - - - wildcardCensor.AddPathsToCensor(NWildcard::k_RelatPath); - - { - UStringVector v1, v2; - v1.Add(fs2us(arcPath)); - v2.Add(fs2us(arcPath)); - const NWildcard::CCensorNode &wildcardCensorHead = - wildcardCensor.Pairs.Front().Head; - - CCodecs *codecs = new CCodecs; - CMyComPtr< - #ifdef EXTERNAL_CODECS - ICompressCodecsInfo - #else - IUnknown - #endif - > compressCodecsInfo = codecs; - { - HRESULT result = codecs->Load(); - if (result != S_OK) - throw CSystemException(result); - } - - if (command.CommandType != NCommandType::kList) - { - CExtractCallbackConsole *ecs = new CExtractCallbackConsole; - CMyComPtr extractCallback = ecs; - ecs->Init(g_StdStream, &g_StdErr, g_StdStream); - - #ifndef _NO_CRYPTO - ecs->PasswordIsDefined = passwordEnabled; - ecs->Password = password; - #endif - - /* - COpenCallbackConsole openCallback; - openCallback.Init(g_StdStream, g_StdStream); - - #ifndef _NO_CRYPTO - openCallback.PasswordIsDefined = passwordEnabled; - openCallback.Password = password; - #endif - */ - - CExtractOptions eo; - eo.StdOutMode = false; - eo.YesToAll = yesToAll; - eo.TestMode = command.CommandType == NCommandType::kTest; - eo.PathMode = NExtract::NPathMode::kFullPaths; - eo.OverwriteMode = yesToAll ? - NExtract::NOverwriteMode::kOverwrite : - NExtract::NOverwriteMode::kAsk; - eo.OutputDir = outputDir; - - UString errorMessage; - CDecompressStat stat; - HRESULT result = Extract( - codecs, CObjectVector(), CIntVector(), - v1, v2, - wildcardCensorHead, - eo, ecs, ecs, - // NULL, // hash - errorMessage, stat); - if (!errorMessage.IsEmpty()) - { - (*g_StdStream) << endl << "Error: " << errorMessage;; - if (result == S_OK) - result = E_FAIL; - } - - if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) - { - if (ecs->NumArcsWithError != 0) - (*g_StdStream) << endl << "Archive Errors" << endl; - if (ecs->NumFileErrors != 0) - (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; - return NExitCode::kFatalError; - } - if (result != S_OK) - throw CSystemException(result); - } - else - { - throw CSystemException(E_NOTIMPL); - - /* - UInt64 numErrors = 0; - UInt64 numWarnings = 0; - HRESULT result = ListArchives( - codecs, CObjectVector(), CIntVector(), - false, // stdInMode - v1, v2, - true, // processAltStreams - false, // showAltStreams - wildcardCensorHead, - true, // enableHeaders - false, // techMode - #ifndef _NO_CRYPTO - passwordEnabled, password, - #endif - numErrors, numWarnings); - if (numErrors > 0) - { - g_StdOut << endl << "Errors: " << numErrors; - return NExitCode::kFatalError; - } - if (result != S_OK) - throw CSystemException(result); - */ - } - } - return 0; -} +// Main.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" +#include "../../../../C/DllSecur.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/MyException.h" + +#ifdef _WIN32 +#include "../../../Windows/DLL.h" +#else +#include "../../../Common/StringConvert.h" +#endif +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" + +#include "../../UI/Common/ExitCode.h" +#include "../../UI/Common/Extract.h" + +#include "../../UI/Console/ExtractCallbackConsole.h" +#include "../../UI/Console/List.h" +#include "../../UI/Console/OpenCallbackConsole.h" + +#include "../../MyVersion.h" + + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NCommandLineParser; + +#ifdef _WIN32 +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; +#endif +extern +int g_CodePage; +int g_CodePage = -1; +extern CStdOutStream *g_StdStream; + +static const char * const kCopyrightString = +"\n7-Zip SFX " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n"; + +static const int kNumSwitches = 6; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kDisablePercents, + kYes, + kPassword, + kOutputDir +}; + +} + +namespace NRecursedType { +enum EEnum +{ + kRecursed, + kWildcardOnlyRecursed, + kNonRecursed +}; +} +/* +static const char kRecursedIDChar = 'R'; + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildcardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +static const char kFileListID = '@'; +static const char kImmediateNameID = '!'; + +static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be +static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be +*/ + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) + +static const CSwitchForm kSwitchForms[kNumSwitches] = +{ + { "?", SWFRM_SIMPLE }, + { "H", SWFRM_SIMPLE }, + { "BD", SWFRM_SIMPLE }, + { "Y", SWFRM_SIMPLE }, + { "P", SWFRM_STRING_SINGL(1) }, + { "O", SWFRM_STRING_SINGL(1) }, +}; + +static const int kNumCommandForms = 3; + +static const NRecursedType::EEnum kCommandRecursedDefault[kNumCommandForms] = +{ + NRecursedType::kRecursed +}; + +// static const bool kTestExtractRecursedDefault = true; +// static const bool kAddRecursedDefault = false; + +static const char * const kUniversalWildcard = "*"; + +static const char * const kHelpString = + "\nUsage: 7zSFX [] [...] [...]\n" + "\n" + "\n" + // " l: List contents of archive\n" + " t: Test integrity of archive\n" + " x: eXtract files with full pathname (default)\n" + "\n" + // " -bd Disable percentage indicator\n" + " -o{Directory}: set Output directory\n" + " -p{Password}: set Password\n" + " -y: assume Yes on all queries\n"; + + +// --------------------------- +// exception messages + +static const char * const kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError +// static const char * const kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char * const kIncorrectWildcardInCommandLine = "Incorrect wildcard in command line"; + +// static const CSysString kFileIsNotArchiveMessageBefore = "File \""; +// static const CSysString kFileIsNotArchiveMessageAfter = "\" is not archive"; + +// static const char * const kProcessArchiveMessage = " archive: "; + +static const char * const kCantFindSFX = " cannot find sfx"; + +namespace NCommandType +{ + enum EEnum + { + kTest = 0, + kFullExtract, + kList + }; +} + +static const char *g_Commands = "txl"; + +struct CArchiveCommand +{ + NCommandType::EEnum CommandType; + + NRecursedType::EEnum DefaultRecursedType() const; +}; + +static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +{ + UString s = commandString; + s.MakeLower_Ascii(); + if (s.Len() != 1) + return false; + if (s[0] >= 0x80) + return false; + int index = FindCharPosInString(g_Commands, (char)s[0]); + if (index < 0) + return false; + command.CommandType = (NCommandType::EEnum)index; + return true; +} + +NRecursedType::EEnum CArchiveCommand::DefaultRecursedType() const +{ + return kCommandRecursedDefault[CommandType]; +} + +static void PrintHelp(void) +{ + g_StdOut << kHelpString; +} + +Z7_ATTR_NORETURN +static void ShowMessageAndThrowException(const char *message, NExitCode::EEnum code) +{ + g_StdOut << message << endl; + throw code; +} + +Z7_ATTR_NORETURN +static void PrintHelpAndExit() // yyy +{ + PrintHelp(); + ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); +} + +// ------------------------------------------------------------------ +// filenames functions + +static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + /* + if (!IsWildcardFilePathLegal(name)) + return false; + */ + const bool isWildcard = DoesNameContainWildcard(name); + bool recursed = false; + + switch (type) + { + case NRecursedType::kWildcardOnlyRecursed: + recursed = isWildcard; + break; + case NRecursedType::kRecursed: + recursed = true; + break; + case NRecursedType::kNonRecursed: + recursed = false; + break; + } + + NWildcard::CCensorPathProps props; + props.Recursive = recursed; + wildcardCensor.AddPreItem(include, name, props); + return true; +} + +static void AddCommandLineWildcardToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + if (!AddNameToCensor(wildcardCensor, name, include, type)) + ShowMessageAndThrowException(kIncorrectWildcardInCommandLine, NExitCode::kUserError); +} + + +#ifndef _WIN32 +static void GetArguments(int numArgs, char *args[], UStringVector &parts) +{ + parts.Clear(); + for (int i = 0; i < numArgs; i++) + { + UString s = MultiByteToUnicodeString(args[i]); + parts.Add(s); + } +} +#endif + + +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +); +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +) +{ + #ifdef _WIN32 + // do we need load Security DLLs for console program? + LoadSecurityDlls(); + #endif + + #if defined(_WIN32) && !defined(UNDER_CE) + SetFileApisToOEM(); + #endif + + #ifdef ENV_HAVE_LOCALE + MY_SetLocale(); + #endif + + g_StdOut << kCopyrightString; + + UStringVector commandStrings; + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArgs, args, commandStrings); + #endif + + #ifdef _WIN32 + + FString arcPath; + { + FString path; + NDLL::MyGetModuleFileName(path); + if (!MyGetFullPathName(path, arcPath)) + { + g_StdOut << "GetFullPathName Error"; + return NExitCode::kFatalError; + } + } + + #else + + if (commandStrings.IsEmpty()) + return NExitCode::kFatalError; + + const FString arcPath = us2fs(commandStrings.Front()); + + #endif + + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif + + NCommandLineParser::CParser parser; + + try + { + if (!parser.ParseStrings(kSwitchForms, kNumSwitches, commandStrings)) + { + g_StdOut << "Command line error:" << endl + << parser.ErrorMessage << endl + << parser.ErrorLine << endl; + return NExitCode::kUserError; + } + } + catch(...) + { + PrintHelpAndExit(); + } + + if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + + unsigned curCommandIndex = 0; + + CArchiveCommand command; + if (nonSwitchStrings.IsEmpty()) + command.CommandType = NCommandType::kFullExtract; + else + { + const UString &cmd = nonSwitchStrings[curCommandIndex]; + if (!ParseArchiveCommand(cmd, command)) + { + g_StdOut << "ERROR: Unknown command:" << endl << cmd << endl; + return NExitCode::kUserError; + } + curCommandIndex = 1; + } + + + NRecursedType::EEnum recursedType; + recursedType = command.DefaultRecursedType(); + + NWildcard::CCensor wildcardCensor; + + { + if (nonSwitchStrings.Size() == curCommandIndex) + AddCommandLineWildcardToCensor(wildcardCensor, (UString)kUniversalWildcard, true, recursedType); + for (; curCommandIndex < nonSwitchStrings.Size(); curCommandIndex++) + { + const UString &s = nonSwitchStrings[curCommandIndex]; + if (s.IsEmpty()) + throw "Empty file path"; + AddCommandLineWildcardToCensor(wildcardCensor, s, true, recursedType); + } + } + + const bool yesToAll = parser[NKey::kYes].ThereIs; + + // NExtractMode::EEnum extractMode; + // bool isExtractGroupCommand = command.IsFromExtractGroup(extractMode); + + const bool passwordEnabled = parser[NKey::kPassword].ThereIs; + + UString password; + if (passwordEnabled) + password = parser[NKey::kPassword].PostStrings[0]; + + if (!NFind::DoesFileExist_FollowLink(arcPath)) + throw kCantFindSFX; + + FString outputDir; + if (parser[NKey::kOutputDir].ThereIs) + { + outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); + NName::NormalizeDirPathPrefix(outputDir); + } + + + wildcardCensor.AddPathsToCensor(NWildcard::k_RelatPath); + + { + UStringVector v1, v2; + v1.Add(fs2us(arcPath)); + v2.Add(fs2us(arcPath)); + const NWildcard::CCensorNode &wildcardCensorHead = + wildcardCensor.Pairs.Front().Head; + + CCodecs *codecs = new CCodecs; + CMyComPtr< + #ifdef Z7_EXTERNAL_CODECS + ICompressCodecsInfo + #else + IUnknown + #endif + > compressCodecsInfo = codecs; + { + HRESULT result = codecs->Load(); + if (result != S_OK) + throw CSystemException(result); + } + + if (command.CommandType != NCommandType::kList) + { + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr extractCallback = ecs; + ecs->Init(g_StdStream, &g_StdErr, g_StdStream, false); + + #ifndef Z7_NO_CRYPTO + ecs->PasswordIsDefined = passwordEnabled; + ecs->Password = password; + #endif + + /* + COpenCallbackConsole openCallback; + openCallback.Init(g_StdStream, g_StdStream); + + #ifndef Z7_NO_CRYPTO + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + #endif + */ + + CExtractOptions eo; + eo.StdOutMode = false; + eo.YesToAll = yesToAll; + eo.TestMode = command.CommandType == NCommandType::kTest; + eo.PathMode = NExtract::NPathMode::kFullPaths; + eo.OverwriteMode = yesToAll ? + NExtract::NOverwriteMode::kOverwrite : + NExtract::NOverwriteMode::kAsk; + eo.OutputDir = outputDir; + + UString errorMessage; + CDecompressStat stat; + HRESULT result = Extract( + codecs, CObjectVector(), CIntVector(), + v1, v2, + wildcardCensorHead, + eo, + ecs, ecs, ecs, + // NULL, // hash + errorMessage, stat); + + ecs->ClosePercents(); + + if (!errorMessage.IsEmpty()) + { + (*g_StdStream) << endl << "Error: " << errorMessage; + if (result == S_OK) + result = E_FAIL; + } + + if ( 0 != ecs->NumCantOpenArcs + || 0 != ecs->NumArcsWithError + || 0 != ecs->NumFileErrors + || 0 != ecs->NumOpenArcErrors) + { + if (ecs->NumCantOpenArcs != 0) + (*g_StdStream) << endl << "Can't open as archive" << endl; + if (ecs->NumArcsWithError != 0) + (*g_StdStream) << endl << "Archive Errors" << endl; + if (ecs->NumFileErrors != 0) + (*g_StdStream) << endl << "Sub items Errors: " << ecs->NumFileErrors << endl; + if (ecs->NumOpenArcErrors != 0) + (*g_StdStream) << endl << "Open Errors: " << ecs->NumOpenArcErrors << endl; + return NExitCode::kFatalError; + } + if (result != S_OK) + throw CSystemException(result); + } + else + { + throw CSystemException(E_NOTIMPL); + + /* + UInt64 numErrors = 0; + UInt64 numWarnings = 0; + HRESULT result = ListArchives( + codecs, CObjectVector(), CIntVector(), + false, // stdInMode + v1, v2, + true, // processAltStreams + false, // showAltStreams + wildcardCensorHead, + true, // enableHeaders + false, // techMode + #ifndef Z7_NO_CRYPTO + passwordEnabled, password, + #endif + numErrors, numWarnings); + if (numErrors > 0) + { + g_StdOut << endl << "Errors: " << numErrors; + return NExitCode::kFatalError; + } + if (result != S_OK) + throw CSystemException(result); + */ + } + } + return 0; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile 2016-03-10 20:23:19.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile 2024-03-20 06:00:00.000000000 +0000 @@ -1,10 +1,137 @@ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -include ../../../../makefile.glb - +PROG = 7zCon.sfx +MY_CONSOLE = 1 +MY_FIXED = 1 + +CFLAGS = $(CFLAGS) \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ + +CURRENT_OBJS = \ + $O\SfxCon.obj \ + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\StringConvert.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\DefaultName.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + +AR_OBJS = \ + $O\SplitHandler.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHandler.obj \ + $O\7zIn.obj \ + $O\7zRegister.obj \ + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaRegister.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdRegister.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\MyAes.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\DllSecur.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Threads.obj \ + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.gcc 2024-01-27 16:00:00.000000000 +0000 @@ -0,0 +1,215 @@ +PROG = 7zCon + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + +include ../../LzmaDec_gcc.mak + + +LOCAL_FLAGS_ST = +MT_OBJS = + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/StreamBinder.o \ + $O/Synchronization.o \ + $O/VirtThread.o \ + $O/Threads.o \ + +endif + + + +LOCAL_FLAGS_SYS = + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ + +SYS_OBJS = \ + $O/DLL.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + +LOCAL_FLAGS = \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + $(LOCAL_FLAGS_ST) \ + $(LOCAL_FLAGS_SYS) \ + + +CURRENT_OBJS = \ + $O/SfxCon.o \ + +CONSOLE_OBJS = \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/List.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UserInputUtils.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/IntToString.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/Sha256Prepare.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/StringConvert.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + \ + $O/System.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + \ + +UI_COMMON_OBJS = \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/DefaultName.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + +AR_OBJS = \ + $O/SplitHandler.o \ + +AR_COMMON_OBJS = \ + $O/CoderMixer2.o \ + $O/ItemNameUtils.o \ + $O/MultiStream.o \ + $O/OutStreamWithCRC.o \ + +7Z_OBJS = \ + $O/7zDecode.o \ + $O/7zExtract.o \ + $O/7zHandler.o \ + $O/7zIn.o \ + $O/7zRegister.o \ + +COMPRESS_OBJS = \ + $O/Bcj2Coder.o \ + $O/Bcj2Register.o \ + $O/BcjCoder.o \ + $O/BcjRegister.o \ + $O/BranchMisc.o \ + $O/BranchRegister.o \ + $O/CopyCoder.o \ + $O/CopyRegister.o \ + $O/DeltaFilter.o \ + $O/Lzma2Decoder.o \ + $O/Lzma2Register.o \ + $O/LzmaDecoder.o \ + $O/LzmaRegister.o \ + $O/PpmdDecoder.o \ + $O/PpmdRegister.o \ + +CRYPTO_OBJS = \ + $O/7zAes.o \ + $O/7zAesRegister.o \ + $O/MyAes.o \ + +C_OBJS = \ + $O/7zStream.o \ + $O/Alloc.o \ + $O/Bcj2.o \ + $O/Bra.o \ + $O/Bra86.o \ + $O/BraIA64.o \ + $O/CpuArch.o \ + $O/Delta.o \ + $O/Lzma2Dec.o \ + $O/Lzma2DecMt.o \ + $O/LzmaDec.o \ + $O/MtDec.o \ + $O/Ppmd7.o \ + $O/Ppmd7Dec.o \ + $O/Sha256.o \ + $O/Sha256Opt.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + $O/Aes.o \ + $O/AesOpt.o \ + +OBJS = \ + $(LZMA_DEC_OPT_OBJS) \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(SYS_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(COMPRESS_OBJS) \ + $(CRYPTO_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7Z_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + $(CURRENT_OBJS) \ + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.list --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,408 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7zCon.sfx$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -DEXTRACT_ONLY \ - -DNO_READ_FROM_CODER \ - -D_SFX \ - -SRCS=\ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Bundles/SFXCon/SfxCon.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Sha256.c \ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Aes.o : ../../../../C/Aes.c - $(CC) $(CFLAGS) ../../../../C/Aes.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -Bcj2.o : ../../../../C/Bcj2.c - $(CC) $(CFLAGS) ../../../../C/Bcj2.c -Bra.o : ../../../../C/Bra.c - $(CC) $(CFLAGS) ../../../../C/Bra.c -Bra86.o : ../../../../C/Bra86.c - $(CC) $(CFLAGS) ../../../../C/Bra86.c -BraIA64.o : ../../../../C/BraIA64.c - $(CC) $(CFLAGS) ../../../../C/BraIA64.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Delta.o : ../../../../C/Delta.c - $(CC) $(CFLAGS) ../../../../C/Delta.c -Lzma2Dec.o : ../../../../C/Lzma2Dec.c - $(CC) $(CFLAGS) ../../../../C/Lzma2Dec.c -LzmaDec.o : ../../../../C/LzmaDec.c - $(CC) $(CFLAGS) ../../../../C/LzmaDec.c -Ppmd7.o : ../../../../C/Ppmd7.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7.c -Ppmd7Dec.o : ../../../../C/Ppmd7Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Dec.c -Sha256.o : ../../../../C/Sha256.c - $(CC) $(CFLAGS) ../../../../C/Sha256.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -7zDecode.o : ../../../../CPP/7zip/Archive/7z/7zDecode.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zDecode.cpp -7zExtract.o : ../../../../CPP/7zip/Archive/7z/7zExtract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zExtract.cpp -7zHandler.o : ../../../../CPP/7zip/Archive/7z/7zHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp -7zHeader.o : ../../../../CPP/7zip/Archive/7z/7zHeader.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zHeader.cpp -7zIn.o : ../../../../CPP/7zip/Archive/7z/7zIn.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zIn.cpp -7zRegister.o : ../../../../CPP/7zip/Archive/7z/7zRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/7z/7zRegister.cpp -CoderMixer2.o : ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp -ItemNameUtils.o : ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -SfxCon.o : ../../../../CPP/7zip/Bundles/SFXCon/SfxCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Bundles/SFXCon/SfxCon.cpp -CWrappers.o : ../../../../CPP/7zip/Common/CWrappers.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CWrappers.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -InBuffer.o : ../../../../CPP/7zip/Common/InBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InBuffer.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -StreamBinder.o : ../../../../CPP/7zip/Common/StreamBinder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamBinder.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -VirtThread.o : ../../../../CPP/7zip/Common/VirtThread.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/VirtThread.cpp -Bcj2Coder.o : ../../../../CPP/7zip/Compress/Bcj2Coder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Coder.cpp -Bcj2Register.o : ../../../../CPP/7zip/Compress/Bcj2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Bcj2Register.cpp -BcjCoder.o : ../../../../CPP/7zip/Compress/BcjCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjCoder.cpp -BcjRegister.o : ../../../../CPP/7zip/Compress/BcjRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BcjRegister.cpp -BranchMisc.o : ../../../../CPP/7zip/Compress/BranchMisc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchMisc.cpp -BranchRegister.o : ../../../../CPP/7zip/Compress/BranchRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/BranchRegister.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -CopyRegister.o : ../../../../CPP/7zip/Compress/CopyRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyRegister.cpp -DeltaFilter.o : ../../../../CPP/7zip/Compress/DeltaFilter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DeltaFilter.cpp -Lzma2Decoder.o : ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp -Lzma2Register.o : ../../../../CPP/7zip/Compress/Lzma2Register.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzma2Register.cpp -LzmaDecoder.o : ../../../../CPP/7zip/Compress/LzmaDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaDecoder.cpp -LzmaRegister.o : ../../../../CPP/7zip/Compress/LzmaRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzmaRegister.cpp -PpmdDecoder.o : ../../../../CPP/7zip/Compress/PpmdDecoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdDecoder.cpp -PpmdRegister.o : ../../../../CPP/7zip/Compress/PpmdRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/PpmdRegister.cpp -7zAes.o : ../../../../CPP/7zip/Crypto/7zAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAes.cpp -7zAesRegister.o : ../../../../CPP/7zip/Crypto/7zAesRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/7zAesRegister.cpp -MyAes.o : ../../../../CPP/7zip/Crypto/MyAes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Crypto/MyAes.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -Extract.o : ../../../../CPP/7zip/UI/Common/Extract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Extract.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -ConsoleClose.o : ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp -ExtractCallbackConsole.o : ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp -List.o : ../../../../CPP/7zip/UI/Console/List.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/List.cpp -MainAr.o : ../../../../CPP/7zip/UI/Console/MainAr.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/MainAr.cpp -OpenCallbackConsole.o : ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp -PercentPrinter.o : ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp -UserInputUtils.o : ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -StdInStream.o : ../../../../CPP/Common/StdInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdInStream.cpp -StdOutStream.o : ../../../../CPP/Common/StdOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdOutStream.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -mySplitCommandLine.o : ../../../../CPP/myWindows/mySplitCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/mySplitCommandLine.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Aes.o \ - Alloc.o \ - Bcj2.o \ - Bra.o \ - Bra86.o \ - BraIA64.o \ - CpuArch.o \ - Delta.o \ - Lzma2Dec.o \ - LzmaDec.o \ - Ppmd7.o \ - Ppmd7Dec.o \ - Sha256.o \ - Threads.o \ - 7zDecode.o \ - 7zExtract.o \ - 7zHandler.o \ - 7zHeader.o \ - 7zIn.o \ - 7zRegister.o \ - CoderMixer2.o \ - ItemNameUtils.o \ - OutStreamWithCRC.o \ - SfxCon.o \ - CWrappers.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - InBuffer.o \ - LimitedStreams.o \ - OutBuffer.o \ - ProgressUtils.o \ - StreamBinder.o \ - StreamObjects.o \ - StreamUtils.o \ - VirtThread.o \ - Bcj2Coder.o \ - Bcj2Register.o \ - BcjCoder.o \ - BcjRegister.o \ - BranchMisc.o \ - BranchRegister.o \ - CopyCoder.o \ - CopyRegister.o \ - DeltaFilter.o \ - Lzma2Decoder.o \ - Lzma2Register.o \ - LzmaDecoder.o \ - LzmaRegister.o \ - PpmdDecoder.o \ - PpmdRegister.o \ - 7zAes.o \ - 7zAesRegister.o \ - MyAes.o \ - ArchiveExtractCallback.o \ - ArchiveOpenCallback.o \ - DefaultName.o \ - Extract.o \ - ExtractingFilePath.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - ConsoleClose.o \ - ExtractCallbackConsole.o \ - List.o \ - MainAr.o \ - OpenCallbackConsole.o \ - PercentPrinter.o \ - UserInputUtils.o \ - CRC.o \ - CommandLineParser.o \ - IntToString.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - StdInStream.o \ - StdOutStream.o \ - StringConvert.o \ - UTFConvert.o \ - Wildcard.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - Synchronization.o \ - System.o \ - mySplitCommandLine.o \ - wine_date_and_time.o \ - $(OBJ_AES) \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXCon/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXCon/resource.rc 2022-12-28 17:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7z Console SFX", "7z.sfx") + +101 ICON "7z.ico" + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/Console/Console.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp 2023-12-03 16:00:00.000000000 +0000 @@ -0,0 +1,246 @@ +// ExtractCallbackSfx.h + +#include "StdAfx.h" + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "ExtractCallbackSfx.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static LPCSTR const kCantDeleteFile = "Cannot delete output file"; +static LPCSTR const kCantOpenFile = "Cannot open output file"; +static LPCSTR const kUnsupportedMethod = "Unsupported Method"; + +void CExtractCallbackImp::Init(IInArchive *archiveHandler, + const FString &directoryPath, + const UString &itemDefaultName, + const FILETIME &defaultMTime, + UInt32 defaultAttributes) +{ + _message.Empty(); + _isCorrupt = false; + _itemDefaultName = itemDefaultName; + _defaultMTime = defaultMTime; + _defaultAttributes = defaultAttributes; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NName::NormalizeDirPathPrefix(_directoryPath); +} + +HRESULT CExtractCallbackImp::Open_CheckBreak() +{ + #ifndef _NO_PROGRESS + return ProgressDialog.Sync.ProcessStopAndPause(); + #else + return S_OK; + #endif +} + +HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) +{ + return S_OK; +} + +HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) +{ + #ifndef _NO_PROGRESS + return ProgressDialog.Sync.ProcessStopAndPause(); + #else + return S_OK; + #endif +} + +HRESULT CExtractCallbackImp::Open_Finished() +{ + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) +{ + #ifndef _NO_PROGRESS + ProgressDialog.Sync.SetProgress(size, 0); + #endif + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) +{ + #ifndef _NO_PROGRESS + RINOK(ProgressDialog.Sync.ProcessStopAndPause()) + if (completeValue != NULL) + ProgressDialog.Sync.SetPos(*completeValue); + #endif + return S_OK; +} + +void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts) +{ + FString fullPath = _directoryPath; + FOR_VECTOR (i, dirPathParts) + { + fullPath += us2fs(dirPathParts[i]); + CreateDir(fullPath); + fullPath.Add_PathSepar(); + } +} + +Z7_COM7F_IMF(CExtractCallbackImp::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) +{ + #ifndef _NO_PROGRESS + if (ProgressDialog.Sync.GetStopped()) + return E_ABORT; + #endif + _outFileStream.Release(); + + UString fullPath; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) + if (prop.vt == VT_EMPTY) + fullPath = _itemDefaultName; + else + { + if (prop.vt != VT_BSTR) + return E_FAIL; + fullPath.SetFromBstr(prop.bstrVal); + } + _filePath = fullPath; + } + + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) + if (prop.vt == VT_EMPTY) + _processedFileInfo.Attributes = _defaultAttributes; + else + { + if (prop.vt != VT_UI4) + return E_FAIL; + _processedFileInfo.Attributes = prop.ulVal; + } + + RINOK(_archiveHandler->GetProperty(index, kpidIsDir, &prop)) + _processedFileInfo.IsDir = VARIANT_BOOLToBool(prop.boolVal); + + bool isAnti = false; + { + NCOM::CPropVariant propTemp; + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propTemp)) + if (propTemp.vt == VT_BOOL) + isAnti = VARIANT_BOOLToBool(propTemp.boolVal); + } + + RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)) + switch (prop.vt) + { + case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; + case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break; + default: return E_FAIL; + } + + UStringVector pathParts; + SplitPathToParts(fullPath, pathParts); + if (pathParts.IsEmpty()) + return E_FAIL; + + UString processedPath = fullPath; + + if (!_processedFileInfo.IsDir) + pathParts.DeleteBack(); + if (!pathParts.IsEmpty()) + { + if (!isAnti) + CreateComplexDirectory(pathParts); + } + + FString fullProcessedPath = _directoryPath + us2fs(processedPath); + + if (_processedFileInfo.IsDir) + { + _diskFilePath = fullProcessedPath; + + if (isAnti) + RemoveDir(_diskFilePath); + else + SetDirTime(_diskFilePath, NULL, NULL, &_processedFileInfo.MTime); + return S_OK; + } + + NFind::CFileInfo fileInfo; + if (fileInfo.Find(fullProcessedPath)) + { + if (!DeleteFileAlways(fullProcessedPath)) + { + _message = kCantDeleteFile; + return E_FAIL; + } + } + + if (!isAnti) + { + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath)) + { + _message = kCantOpenFile; + return E_FAIL; + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + _diskFilePath = fullProcessedPath; + } + else + { + *outStream = NULL; + } + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(Int32 askExtractMode)) +{ + _extractMode = (askExtractMode == NArchive::NExtract::NAskMode::kExtract); + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult)) +{ + switch (resultEOperationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + + default: + { + _outFileStream.Release(); + switch (resultEOperationResult) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + _message = kUnsupportedMethod; + break; + default: + _isCorrupt = true; + } + return E_FAIL; + } + } + if (_outFileStream != NULL) + { + _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); + RINOK(_outFileStreamSpec->Close()) + } + _outFileStream.Release(); + if (_extractMode) + SetFileAttrib(_diskFilePath, _processedFileInfo.Attributes); + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.h 2023-04-03 07:00:00.000000000 +0000 @@ -0,0 +1,83 @@ +// ExtractCallbackSfx.h + +#ifndef ZIP7_INC_EXTRACT_CALLBACK_SFX_H +#define ZIP7_INC_EXTRACT_CALLBACK_SFX_H + +#include "resource.h" + +#include "../../../Windows/ResourceString.h" + +#include "../../Archive/IArchive.h" + +#include "../../Common/FileStreams.h" +#include "../../ICoder.h" + +#include "../../UI/FileManager/LangUtils.h" + +#ifndef _NO_PROGRESS +#include "../../UI/FileManager/ProgressDialog.h" +#endif +#include "../../UI/Common/ArchiveOpenCallback.h" + +class CExtractCallbackImp Z7_final: + public IArchiveExtractCallback, + public IOpenCallbackUI, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_IMP(IOpenCallbackUI) + + CMyComPtr _archiveHandler; + FString _directoryPath; + UString _filePath; + FString _diskFilePath; + + bool _extractMode; + struct CProcessedFileInfo + { + FILETIME MTime; + bool IsDir; + UInt32 Attributes; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + + UString _itemDefaultName; + FILETIME _defaultMTime; + UInt32 _defaultAttributes; + + void CreateComplexDirectory(const UStringVector &dirPathParts); +public: + #ifndef _NO_PROGRESS + CProgressDialog ProgressDialog; + #endif + + bool _isCorrupt; + UString _message; + + void Init(IInArchive *archiveHandler, + const FString &directoryPath, + const UString &itemDefaultName, + const FILETIME &defaultMTime, + UInt32 defaultAttributes); + + #ifndef _NO_PROGRESS + HRESULT StartProgressDialog(const UString &title, NWindows::CThread &thread) + { + ProgressDialog.Create(title, thread, NULL); + { + ProgressDialog.SetText(LangString(IDS_PROGRESS_EXTRACTING)); + } + + ProgressDialog.Show(SW_SHOWNORMAL); + return S_OK; + } + ~CExtractCallbackImp() { ProgressDialog.Destroy(); } + #endif + +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp 2023-03-20 18:00:00.000000000 +0000 @@ -0,0 +1,135 @@ +// ExtractEngine.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Thread.h" + +#include "../../UI/Common/OpenArchive.h" + +#include "../../UI/FileManager/FormatUtils.h" +#include "../../UI/FileManager/LangUtils.h" + +#include "ExtractCallbackSfx.h" +#include "ExtractEngine.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static LPCSTR const kCantFindArchive = "Cannot find archive file"; +static LPCSTR const kCantOpenArchive = "Cannot open the file as archive"; + +struct CThreadExtracting +{ + CCodecs *Codecs; + FString FileName; + FString DestFolder; + + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + + CArchiveLink ArchiveLink; + HRESULT Result; + UString ErrorMessage; + + void Process2() + { + NFind::CFileInfo fi; + if (!fi.Find(FileName)) + { + ErrorMessage = kCantFindArchive; + Result = E_FAIL; + return; + } + + CObjectVector incl; + CIntVector excl; + COpenOptions options; + options.codecs = Codecs; + options.types = &incl; + options.excludedFormats = ! + options.filePath = fs2us(FileName); + + Result = ArchiveLink.Open2(options, ExtractCallbackSpec); + if (Result != S_OK) + { + ErrorMessage = kCantOpenArchive; + return; + } + + FString dirPath = DestFolder; + NName::NormalizeDirPathPrefix(dirPath); + + if (!CreateComplexDir(dirPath)) + { + ErrorMessage = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, fs2us(dirPath)); + Result = E_FAIL; + return; + } + + ExtractCallbackSpec->Init(ArchiveLink.GetArchive(), dirPath, (UString)"Default", fi.MTime, 0); + + Result = ArchiveLink.GetArchive()->Extract(NULL, (UInt32)(Int32)-1 , BoolToInt(false), ExtractCallback); + } + + void Process() + { + try + { + #ifndef _NO_PROGRESS + CProgressCloser closer(ExtractCallbackSpec->ProgressDialog); + #endif + Process2(); + } + catch(...) { Result = E_FAIL; } + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + ((CThreadExtracting *)param)->Process(); + return 0; + } +}; + +HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder, + bool showProgress, bool &isCorrupt, UString &errorMessage) +{ + isCorrupt = false; + CThreadExtracting t; + + t.Codecs = codecs; + t.FileName = fileName; + t.DestFolder = destFolder; + + t.ExtractCallbackSpec = new CExtractCallbackImp; + t.ExtractCallback = t.ExtractCallbackSpec; + + #ifndef _NO_PROGRESS + + if (showProgress) + { + t.ExtractCallbackSpec->ProgressDialog.IconID = IDI_ICON; + NWindows::CThread thread; + const WRes wres = thread.Create(CThreadExtracting::MyThreadFunction, &t); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + + UString title; + LangString(IDS_PROGRESS_EXTRACTING, title); + t.ExtractCallbackSpec->StartProgressDialog(title, thread); + } + else + + #endif + { + t.Process2(); + } + + errorMessage = t.ErrorMessage; + if (errorMessage.IsEmpty()) + errorMessage = t.ExtractCallbackSpec->_message; + isCorrupt = t.ExtractCallbackSpec->_isCorrupt; + return t.Result; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h 2023-01-10 19:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// ExtractEngine.h + +#ifndef ZIP7_INC_EXTRACT_ENGINE_H +#define ZIP7_INC_EXTRACT_ENGINE_H + +#include "../../UI/Common/LoadCodecs.h" + +HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder, + bool showProgress, bool &isCorrupt, UString &errorMessage); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsp 2024-03-10 09:00:00.000000000 +0000 @@ -0,0 +1,872 @@ +# Microsoft Developer Studio Project File - Name="SFXSetup" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=SFXSetup - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXSetup.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXSetup.mak" CFG="SFXSetup - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXSetup - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "SFXSetup - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "SFXSetup - Win32 ReleaseD" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXSetup - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXSetup - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "SFXSetup - Win32 ReleaseD" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseD" +# PROP BASE Intermediate_Dir "ReleaseD" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseD" +# PROP Intermediate_Dir "ReleaseD" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /D "Z7_NO_CRYPTO" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" +# SUBTRACT BASE LINK32 /debug /nodefaultlib +# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zSD.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "SFXSetup - Win32 Release" +# Name "SFXSetup - Win32 Debug" +# Name "SFXSetup - Win32 ReleaseD" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zItem.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# End Group +# End Group +# Begin Group "File Manager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ExtractCallbackSfx.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackSfx.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.h +# End Source File +# Begin Source File + +SOURCE=.\setup.ico +# End Source File +# Begin Source File + +SOURCE=.\SfxSetup.cpp +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SFXSetup.dsw 2002-01-24 23:25:50.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXSetup"=.\SFXSetup.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -0,0 +1,371 @@ +// Main.cpp + +#include "StdAfx.h" + +#include "../../../../C/DllSecur.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/TextConfig.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/ResourceString.h" + +#include "../../UI/Explorer/MyMessages.h" + +#include "ExtractEngine.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance; +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + +static CFSTR const kTempDirPrefix = FTEXT("7zS"); + +#define MY_SHELL_EXECUTE + +static bool ReadDataString(CFSTR fileName, LPCSTR startID, + LPCSTR endID, AString &stringResult) +{ + stringResult.Empty(); + NIO::CInFile inFile; + if (!inFile.Open(fileName)) + return false; + const size_t kBufferSize = (1 << 12); + + Byte buffer[kBufferSize]; + const unsigned signatureStartSize = MyStringLen(startID); + const unsigned signatureEndSize = MyStringLen(endID); + + size_t numBytesPrev = 0; + bool writeMode = false; + UInt64 posTotal = 0; + for (;;) + { + if (posTotal > (1 << 20)) + return (stringResult.IsEmpty()); + const size_t numReadBytes = kBufferSize - numBytesPrev; + size_t processedSize; + if (!inFile.ReadFull(buffer + numBytesPrev, numReadBytes, processedSize)) + return false; + if (processedSize == 0) + return true; + const size_t numBytesInBuffer = numBytesPrev + processedSize; + UInt32 pos = 0; + for (;;) + { + if (writeMode) + { + if (pos + signatureEndSize > numBytesInBuffer) + break; + if (memcmp(buffer + pos, endID, signatureEndSize) == 0) + return true; + const Byte b = buffer[pos]; + if (b == 0) + return false; + stringResult += (char)b; + pos++; + } + else + { + if (pos + signatureStartSize > numBytesInBuffer) + break; + if (memcmp(buffer + pos, startID, signatureStartSize) == 0) + { + writeMode = true; + pos += signatureStartSize; + } + else + pos++; + } + } + numBytesPrev = numBytesInBuffer - pos; + posTotal += pos; + memmove(buffer, buffer + pos, numBytesPrev); + } +} + +static char kStartID[] = { ',','!','@','I','n','s','t','a','l','l','@','!','U','T','F','-','8','!', 0 }; +static char kEndID[] = { ',','!','@','I','n','s','t','a','l','l','E','n','d','@','!', 0 }; + +static struct CInstallIDInit +{ + CInstallIDInit() + { + kStartID[0] = ';'; + kEndID[0] = ';'; + } +} g_CInstallIDInit; + + +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return 1; +#endif + +static void ShowErrorMessageSpec(const UString &name) +{ + UString message = NError::MyFormatMessage(::GetLastError()); + const int pos = message.Find(L"%1"); + if (pos >= 0) + { + message.Delete((unsigned)pos, 2); + message.Insert((unsigned)pos, name); + } + ShowErrorMessage(NULL, message); +} + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + /* lpCmdLine */,int /* nCmdShow */) +{ + g_hInstance = (HINSTANCE)hInstance; + + NT_CHECK + + #ifdef _WIN32 + LoadSecurityDlls(); + #endif + + // InitCommonControls(); + + UString archiveName, switches; + #ifdef MY_SHELL_EXECUTE + UString executeFile, executeParameters; + #endif + NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches); + + FString fullPath; + NDLL::MyGetModuleFileName(fullPath); + + switches.Trim(); + bool assumeYes = false; + if (switches.IsPrefixedBy_Ascii_NoCase("-y")) + { + assumeYes = true; + switches = switches.Ptr(2); + switches.Trim(); + } + + AString config; + if (!ReadDataString(fullPath, kStartID, kEndID, config)) + { + if (!assumeYes) + ShowErrorMessage(L"Can't load config info"); + return 1; + } + + UString dirPrefix ("." STRING_PATH_SEPARATOR); + UString appLaunched; + bool showProgress = true; + if (!config.IsEmpty()) + { + CObjectVector pairs; + if (!GetTextConfig(config, pairs)) + { + if (!assumeYes) + ShowErrorMessage(L"Config failed"); + return 1; + } + const UString friendlyName = GetTextConfigValue(pairs, "Title"); + const UString installPrompt = GetTextConfigValue(pairs, "BeginPrompt"); + const UString progress = GetTextConfigValue(pairs, "Progress"); + if (progress.IsEqualTo_Ascii_NoCase("no")) + showProgress = false; + const int index = FindTextConfigItem(pairs, "Directory"); + if (index >= 0) + dirPrefix = pairs[index].String; + if (!installPrompt.IsEmpty() && !assumeYes) + { + if (MessageBoxW(NULL, installPrompt, friendlyName, MB_YESNO | + MB_ICONQUESTION) != IDYES) + return 0; + } + appLaunched = GetTextConfigValue(pairs, "RunProgram"); + + #ifdef MY_SHELL_EXECUTE + executeFile = GetTextConfigValue(pairs, "ExecuteFile"); + executeParameters = GetTextConfigValue(pairs, "ExecuteParameters"); + #endif + } + + CTempDir tempDir; + if (!tempDir.Create(kTempDirPrefix)) + { + if (!assumeYes) + ShowErrorMessage(L"Cannot create temp folder archive"); + return 1; + } + + CCodecs *codecs = new CCodecs; + CMyComPtr compressCodecsInfo = codecs; + { + const HRESULT result = codecs->Load(); + if (result != S_OK) + { + ShowErrorMessage(L"Cannot load codecs"); + return 1; + } + } + + const FString tempDirPath = tempDir.GetPath(); + // tempDirPath = "M:\\1\\"; // to test low disk space + { + bool isCorrupt = false; + UString errorMessage; + HRESULT result = ExtractArchive(codecs, fullPath, tempDirPath, showProgress, + isCorrupt, errorMessage); + + if (result != S_OK) + { + if (!assumeYes) + { + if (result == S_FALSE || isCorrupt) + { + NWindows::MyLoadString(IDS_EXTRACTION_ERROR_MESSAGE, errorMessage); + result = E_FAIL; + } + if (result != E_ABORT) + { + if (errorMessage.IsEmpty()) + errorMessage = NError::MyFormatMessage(result); + ::MessageBoxW(NULL, errorMessage, NWindows::MyLoadString(IDS_EXTRACTION_ERROR_TITLE), MB_ICONERROR); + } + } + return 1; + } + } + + #ifndef UNDER_CE + CCurrentDirRestorer currentDirRestorer; + if (!SetCurrentDir(tempDirPath)) + return 1; + #endif + + HANDLE hProcess = NULL; +#ifdef MY_SHELL_EXECUTE + if (!executeFile.IsEmpty()) + { + CSysString filePath (GetSystemString(executeFile)); + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS + #ifndef UNDER_CE + | SEE_MASK_FLAG_DDEWAIT + #endif + ; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = filePath; + + if (!switches.IsEmpty()) + { + executeParameters.Add_Space_if_NotEmpty(); + executeParameters += switches; + } + + const CSysString parametersSys (GetSystemString(executeParameters)); + if (parametersSys.IsEmpty()) + execInfo.lpParameters = NULL; + else + execInfo.lpParameters = parametersSys; + + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = NULL; + /* BOOL success = */ ::ShellExecuteEx(&execInfo); + UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; + if (result <= 32) + { + if (!assumeYes) + ShowErrorMessage(L"Cannot open file"); + return 1; + } + hProcess = execInfo.hProcess; + } + else +#endif + { + if (appLaunched.IsEmpty()) + { + appLaunched = "setup.exe"; + if (!NFind::DoesFileExist_FollowLink(us2fs(appLaunched))) + { + if (!assumeYes) + ShowErrorMessage(L"Cannot find setup.exe"); + return 1; + } + } + + { + FString s2 = tempDirPath; + NName::NormalizeDirPathPrefix(s2); + appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2)); + } + + const UString appNameForError = appLaunched; // actually we need to rtemove parameters also + + appLaunched.Replace(L"%%T", fs2us(tempDirPath)); + + if (!switches.IsEmpty()) + { + appLaunched.Add_Space(); + appLaunched += switches; + } + STARTUPINFO startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = NULL; + startupInfo.lpDesktop = NULL; + startupInfo.lpTitle = NULL; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = NULL; + + PROCESS_INFORMATION processInformation; + + const CSysString appLaunchedSys (GetSystemString(dirPrefix + appLaunched)); + + const BOOL createResult = CreateProcess(NULL, + appLaunchedSys.Ptr_non_const(), + NULL, NULL, FALSE, 0, NULL, NULL /*tempDir.GetPath() */, + &startupInfo, &processInformation); + if (createResult == 0) + { + if (!assumeYes) + { + // we print name of exe file, if error message is + // ERROR_BAD_EXE_FORMAT: "%1 is not a valid Win32 application". + ShowErrorMessageSpec(appNameForError); + } + return 1; + } + ::CloseHandle(processInformation.hThread); + hProcess = processInformation.hProcess; + } + if (hProcess) + { + WaitForSingleObject(hProcess, INFINITE); + ::CloseHandle(hProcess); + } + return 0; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// StdAfx.h + +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,121 @@ +PROG = 7zS.sfx +MY_FIXED = 1 + +CFLAGS = $(CFLAGS) \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_CRYPTO \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ + +CURRENT_OBJS = \ + $O\SfxSetup.obj \ + $O\ExtractCallbackSfx.obj \ + $O\ExtractEngine.obj \ + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\ResourceString.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveOpenCallback.obj \ + $O\DefaultName.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + +EXPLORER_OBJS = \ + $O\MyMessages.obj \ + +FM_OBJS = \ + $O\FormatUtils.obj \ + $O\ProgressDialog.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHandler.obj \ + $O\7zIn.obj \ + $O\7zRegister.obj \ + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaRegister.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\DllSecur.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../LzmaDec.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/resource.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/resource.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.h 2011-05-16 05:36:46.000000000 +0000 @@ -0,0 +1,6 @@ +#define IDI_ICON 1 + +#define IDS_EXTRACTION_ERROR_TITLE 7 +#define IDS_EXTRACTION_ERROR_MESSAGE 8 +#define IDS_CANNOT_CREATE_FOLDER 3003 +#define IDS_PROGRESS_EXTRACTING 3300 diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/resource.rc 2011-05-16 05:42:01.000000000 +0000 @@ -0,0 +1,16 @@ +#include "../../MyVersionInfo.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7z Setup SFX", "7zS.sfx") + +IDI_ICON ICON "setup.ico" + +STRINGTABLE +BEGIN + IDS_EXTRACTION_ERROR_TITLE "Extraction Failed" + IDS_EXTRACTION_ERROR_MESSAGE "File is corrupt" + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_PROGRESS_EXTRACTING "Extracting" +END + +#include "../../UI/FileManager/ProgressDialog.rc" Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Bundles/SFXSetup/setup.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXSetup/setup.ico differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/7z.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/7z.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SFXWin.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SFXWin.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsp 2024-03-10 09:00:00.000000000 +0000 @@ -0,0 +1,1074 @@ +# Microsoft Developer Studio Project File - Name="SFXWin" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=SFXWin - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SFXWin.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SFXWin.mak" CFG="SFXWin - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SFXWin - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "SFXWin - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "SFXWin - Win32 ReleaseD" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SFXWin - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "SFXWin - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zsfx.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "SFXWin - Win32 ReleaseD" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "SFXWin___Win32_ReleaseD" +# PROP BASE Intermediate_Dir "SFXWin___Win32_ReleaseD" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "SFXWin___Win32_ReleaseD" +# PROP Intermediate_Dir "SFXWin___Win32_ReleaseD" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_SFX" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "Z7_EXTRACT_ONLY" /D "Z7_NO_REGISTRY" /D "Z7_NO_READ_FROM_CODER" /D "Z7_SFX" /D "Z7_NO_LONG_PATH" /D "Z7_NO_LARGE_PAGES" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7z.sfx" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zD.sfx" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "SFXWin - Win32 Release" +# Name "SFXWin - Win32 Debug" +# Name "SFXWin - Win32 ReleaseD" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "7z" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zDecode.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zExtract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zHeader.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\7z\7zRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\SplitHandler.cpp +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\CoderMixer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\MultiStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Coder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Bcj2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BcjRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchMisc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\BranchRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\DeltaFilter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Decoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzma2Register.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LzmaRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\PpmdRegister.cpp +# End Source File +# End Group +# Begin Group "Crypto" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAes.h +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\7zAesRegister.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Crypto\MyAes.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\BrowseDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PasswordDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ProgressDialog2.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CWrappers.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LockedStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamBinder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\VirtThread.h +# End Source File +# End Group +# Begin Group "File Manager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\FileManager\SysIconUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha256Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Common\OpenArchive.h +# End Source File +# End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\GUI\ExtractGUI.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\UI\Explorer\MyMessages.h +# End Source File +# End Group +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zStream.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Aes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\AesOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bcj2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Bra86.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\BraIA64.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Delta.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2Dec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Lzma2DecMt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\LzmaDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\MtDec.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Ppmd7Dec.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha256Opt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7z.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\SfxWin.cpp +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SFXWin.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsw --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SFXWin.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SFXWin.dsw 2001-09-29 00:19:22.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SFXWin"=.\SFXWin.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SfxWin.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SfxWin.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/SfxWin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/SfxWin.cpp 2024-03-14 11:00:00.000000000 +0000 @@ -0,0 +1,268 @@ +// Main.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../../C/DllSecur.h" + +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/ResourceString.h" + +#include "../../ICoder.h" +#include "../../IPassword.h" +#include "../../Archive/IArchive.h" +#include "../../UI/Common/Extract.h" +#include "../../UI/Common/ExitCode.h" +#include "../../UI/Explorer/MyMessages.h" +#include "../../UI/FileManager/MyWindowsNew.h" +#include "../../UI/GUI/ExtractGUI.h" +#include "../../UI/GUI/ExtractRes.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance; +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + +#ifndef UNDER_CE + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000 +#define Z7_USE_DYN_ComCtl32Version +#endif + +#ifdef Z7_USE_DYN_ComCtl32Version +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +static DWORD GetDllVersion(LPCTSTR dllName) +{ + DWORD dwVersion = 0; + const HINSTANCE hinstDll = LoadLibrary(dllName); + if (hinstDll) + { + const + DLLGETVERSIONPROC func_DllGetVersion = Z7_GET_PROC_ADDRESS( + DLLGETVERSIONPROC, hinstDll, "DllGetVersion"); + if (func_DllGetVersion) + { + DLLVERSIONINFO dvi; + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + const HRESULT hr = func_DllGetVersion(&dvi); + if (SUCCEEDED(hr)) + dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + FreeLibrary(hinstDll); + } + return dwVersion; +} + +#endif +#endif + +extern +bool g_LVN_ITEMACTIVATE_Support; +bool g_LVN_ITEMACTIVATE_Support = true; + +static const wchar_t * const kUnknownExceptionMessage = L"ERROR: Unknown Error!"; + +static void ErrorMessageForHRESULT(HRESULT res) +{ + ShowErrorMessage(HResultToMessage(res)); +} + +static int APIENTRY WinMain2() +{ + // OleInitialize is required for ProgressBar in TaskBar. +#ifndef UNDER_CE + OleInitialize(NULL); +#endif + +#ifndef UNDER_CE +#ifdef Z7_USE_DYN_ComCtl32Version + { + const DWORD g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); + } +#endif +#endif + + UString password; + bool assumeYes = false; + bool outputFolderDefined = false; + FString outputFolder; + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif + + FOR_VECTOR (i, commandStrings) + { + const UString &s = commandStrings[i]; + if (s.Len() > 1 && s[0] == '-') + { + const wchar_t c = MyCharLower_Ascii(s[1]); + if (c == 'y') + { + assumeYes = true; + if (s.Len() != 2) + { + ShowErrorMessage(L"Bad command"); + return 1; + } + } + else if (c == 'o') + { + outputFolder = us2fs(s.Ptr(2)); + NName::NormalizeDirPathPrefix(outputFolder); + outputFolderDefined = !outputFolder.IsEmpty(); + } + else if (c == 'p') + { + password = s.Ptr(2); + } + } + } + + g_DisableUserQuestions = assumeYes; + + FString path; + NDLL::MyGetModuleFileName(path); + + FString fullPath; + if (!MyGetFullPathName(path, fullPath)) + { + ShowErrorMessage(L"Error 1329484"); + return 1; + } + + CCodecs *codecs = new CCodecs; + CMyComPtr compressCodecsInfo = codecs; + HRESULT result = codecs->Load(); + if (result != S_OK) + { + ErrorMessageForHRESULT(result); + return 1; + } + + // COpenCallbackGUI openCallback; + + // openCallback.PasswordIsDefined = !password.IsEmpty(); + // openCallback.Password = password; + + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + ecs->Init(); + + #ifndef Z7_NO_CRYPTO + ecs->PasswordIsDefined = !password.IsEmpty(); + ecs->Password = password; + #endif + + CExtractOptions eo; + + FString dirPrefix; + if (!GetOnlyDirPrefix(path, dirPrefix)) + { + ShowErrorMessage(L"Error 1329485"); + return 1; + } + + eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix; + eo.YesToAll = assumeYes; + eo.OverwriteMode = assumeYes ? + NExtract::NOverwriteMode::kOverwrite : + NExtract::NOverwriteMode::kAsk; + eo.PathMode = NExtract::NPathMode::kFullPaths; + eo.TestMode = false; + + UStringVector v1, v2; + v1.Add(fs2us(fullPath)); + v2.Add(fs2us(fullPath)); + NWildcard::CCensorNode wildcardCensor; + wildcardCensor.Add_Wildcard(); + + bool messageWasDisplayed = false; + result = ExtractGUI(codecs, + CObjectVector(), CIntVector(), + v1, v2, + wildcardCensor, eo, (assumeYes ? false: true), messageWasDisplayed, ecs); + + if (result == S_OK) + { + if (!ecs->IsOK()) + return NExitCode::kFatalError; + return 0; + } + if (result == E_ABORT) + return NExitCode::kUserBreak; + if (!messageWasDisplayed) + { + if (result == S_FALSE) + ShowErrorMessage(L"Error in archive"); + else + ErrorMessageForHRESULT(result); + } + if (result == E_OUTOFMEMORY) + return NExitCode::kMemoryError; + return NExitCode::kFatalError; +} + +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION ShowErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError; +#endif + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + /* lpCmdLine */, int /* nCmdShow */) +{ + g_hInstance = (HINSTANCE)hInstance; + + NT_CHECK + + try + { + #ifdef _WIN32 + LoadSecurityDlls(); + #endif + + return WinMain2(); + } + catch(const CNewException &) + { + ErrorMessageForHRESULT(E_OUTOFMEMORY); + return NExitCode::kMemoryError; + } + catch(...) + { + ShowErrorMessage(kUnknownExceptionMessage); + return NExitCode::kFatalError; + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/StdAfx.h 2023-03-06 19:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// StdAfx.h + +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../UI/FileManager/StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/makefile 2024-03-14 11:00:00.000000000 +0000 @@ -0,0 +1,159 @@ +PROG = 7z.sfx +MY_FIXED = 1 + +CFLAGS = $(CFLAGS) \ + -DZ7_NO_REGISTRY \ + -DZ7_EXTRACT_ONLY \ + -DZ7_NO_READ_FROM_CODER \ + -DZ7_SFX \ + -DZ7_NO_LONG_PATH \ + -DZ7_NO_LARGE_PAGES \ + +!IFDEF UNDER_CE +LIBS = $(LIBS) ceshell.lib Commctrl.lib +!ELSE +LIBS = $(LIBS) comctl32.lib comdlg32.lib +!ENDIF + +CURRENT_OBJS = \ + $O\SfxWin.obj \ + +GUI_OBJS = \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\CommandLineParser.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\Clipboard.obj \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryGlobal.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\CWrappers.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\InBuffer.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamBinder.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\VirtThread.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\DefaultName.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + +EXPLORER_OBJS = \ + $O\MyMessages.obj \ + +FM_OBJS = \ + $O\BrowseDialog.obj \ + $O\ComboDialog.obj \ + $O\ExtractCallback.obj \ + $O\FormatUtils.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog2.obj \ + $O\PropertyName.obj \ + $O\SysIconUtils.obj \ + +AR_OBJS = \ + $O\SplitHandler.obj \ + +AR_COMMON_OBJS = \ + $O\CoderMixer2.obj \ + $O\ItemNameUtils.obj \ + $O\MultiStream.obj \ + $O\OutStreamWithCRC.obj \ + +7Z_OBJS = \ + $O\7zDecode.obj \ + $O\7zExtract.obj \ + $O\7zHandler.obj \ + $O\7zIn.obj \ + $O\7zRegister.obj \ + +COMPRESS_OBJS = \ + $O\Bcj2Coder.obj \ + $O\Bcj2Register.obj \ + $O\BcjCoder.obj \ + $O\BcjRegister.obj \ + $O\BranchMisc.obj \ + $O\BranchRegister.obj \ + $O\CopyCoder.obj \ + $O\CopyRegister.obj \ + $O\DeltaFilter.obj \ + $O\Lzma2Decoder.obj \ + $O\Lzma2Register.obj \ + $O\LzmaDecoder.obj \ + $O\LzmaRegister.obj \ + $O\PpmdDecoder.obj \ + $O\PpmdRegister.obj \ + +CRYPTO_OBJS = \ + $O\7zAes.obj \ + $O\7zAesRegister.obj \ + $O\MyAes.obj \ + +C_OBJS = \ + $O\7zStream.obj \ + $O\Alloc.obj \ + $O\Bcj2.obj \ + $O\Bra.obj \ + $O\Bra86.obj \ + $O\BraIA64.obj \ + $O\CpuArch.obj \ + $O\Delta.obj \ + $O\DllSecur.obj \ + $O\Lzma2Dec.obj \ + $O\Lzma2DecMt.obj \ + $O\LzmaDec.obj \ + $O\MtDec.obj \ + $O\Ppmd7.obj \ + $O\Ppmd7Dec.obj \ + $O\Threads.obj \ + +!include "../../Aes.mak" +!include "../../Crc.mak" +!include "../../LzmaDec.mak" +!include "../../Sha256.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/resource.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.h --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/resource.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.h 2011-05-16 05:40:01.000000000 +0000 @@ -0,0 +1 @@ +#define IDI_ICON 1 diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.rc --- p7zip-rar-16.02/CPP/7zip/Bundles/SFXWin/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/SFXWin/resource.rc 2022-12-28 17:00:00.000000000 +0000 @@ -0,0 +1,55 @@ +#include "../../MyVersionInfo.rc" +#include "../../GuiCommon.rc" +#include "../../UI/GUI/ExtractDialogRes.h" +#include "../../UI/FileManager/PropertyNameRes.h" + +#include "resource.h" + +MY_VERSION_INFO_APP("7z SFX", "7z.sfx") + +#define xc 240 +#define yc 64 + +IDI_ICON ICON "7z.ico" + +IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "7-Zip self-extracting archive" +BEGIN + LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 + EDITTEXT IDC_EXTRACT_PATH, m, 21, xc - bxsDots - 12, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, 20, bxsDots, bys, WS_GROUP + DEFPUSHBUTTON "Extract", IDOK, bx2, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +END + +#ifdef UNDER_CE + +#undef xc +#define xc 144 + +IDD_EXTRACT_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "7-Zip self-extracting archive" +BEGIN + LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc - bxsDots - 12, 8 + EDITTEXT IDC_EXTRACT_PATH, m, m + bys + 4, xc, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m, bxsDots, bys, WS_GROUP + DEFPUSHBUTTON "Extract", IDOK, bx2, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +END + +#endif + +#include "../../UI/FileManager/OverwriteDialog.rc" +#include "../../UI/FileManager/PasswordDialog.rc" +#include "../../UI/FileManager/ProgressDialog2.rc" +#include "../../UI/GUI/Extract.rc" + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROP_MTIME "Modified" +END + + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/GUI/7zG.exe.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Bundles/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/makefile --- p7zip-rar-16.02/CPP/7zip/Bundles/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Bundles/makefile 2021-01-14 10:06:55.000000000 +0000 @@ -0,0 +1,19 @@ +DIRS = \ + Alone\~ \ + Alone2\~ \ + Alone7z\~ \ + Fm\~ \ + Format7z\~ \ + Format7zF\~ \ + Format7zR\~ \ + Format7zExtract\~ \ + Format7zExtractR\~ \ + LzmaCon\~ \ + SFXCon\~ \ + SFXSetup\~ \ + SFXWin\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/7zFM/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zFM/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/7zFM/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zFM/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -DLANG -DNEW_FOLDER_INTERFACE -DEXTERNAL_CODECS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -DBREAK_HANDLER -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_executable(7zFM_do_not_use - - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/Alloc.c" - "../../../../C/CpuArch.c" - "../../../../C/Sha256.c" - "../../../../C/Sort.c" - "../../../../C/Threads.c" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp" - "../../../../CPP/7zip/Common/FileStreams.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/UI/Agent/Agent.cpp" - "../../../../CPP/7zip/UI/Agent/AgentOut.cpp" - "../../../../CPP/7zip/UI/Agent/AgentProxy.cpp" - "../../../../CPP/7zip/UI/Agent/ArchiveFolder.cpp" - "../../../../CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp" - "../../../../CPP/7zip/UI/Agent/ArchiveFolderOut.cpp" - "../../../../CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveName.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp" - "../../../../CPP/7zip/UI/Common/CompressCall.cpp" - "../../../../CPP/7zip/UI/Common/DefaultName.cpp" - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp" - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp" - "../../../../CPP/7zip/UI/Common/HashCalc.cpp" - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp" - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp" - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp" - "../../../../CPP/7zip/UI/Common/SetProperties.cpp" - "../../../../CPP/7zip/UI/Common/SortUtils.cpp" - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp" - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp" - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp" - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp" - "../../../../CPP/7zip/UI/Common/WorkDir.cpp" - "../../../../CPP/7zip/UI/Common/ZipRegistry.cpp" - "../../../../CPP/7zip/UI/FileManager/App.cpp" - "../../../../CPP/7zip/UI/FileManager/ClassDefs.cpp" - "../../../../CPP/7zip/UI/FileManager/ComboDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/ComboDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/CopyDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/CopyDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp" - "../../../../CPP/7zip/UI/FileManager/FM.cpp" - "../../../../CPP/7zip/UI/FileManager/FM_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/FSDrives.cpp" - "../../../../CPP/7zip/UI/FileManager/FSFolder.cpp" - "../../../../CPP/7zip/UI/FileManager/FSFolderCopy.cpp" - "../../../../CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp" - "../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/LangUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/ListViewDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/MessagesDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/MyLoadMenu.cpp" - "../../../../CPP/7zip/UI/FileManager/OpenCallback.cpp" - "../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/Panel.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelCopy.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelCrc.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelFolderChange.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelItemOpen.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelItems.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelListNotify.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelMenu.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelOperations.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelSelect.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelSort.cpp" - "../../../../CPP/7zip/UI/FileManager/PanelSplitFile.cpp" - "../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/PropertyName.cpp" - "../../../../CPP/7zip/UI/FileManager/RegistryUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/RootFolder.cpp" - "../../../../CPP/7zip/UI/FileManager/SplitDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/SplitDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/StringUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/SysIconUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/TextPairs.cpp" - "../../../../CPP/7zip/UI/FileManager/UpdateCallback100.cpp" - "../../../../CPP/7zip/UI/FileManager/ViewSettings.cpp" - "../../../../CPP/7zip/UI/FileManager/wxFM.cpp" - "../../../../CPP/7zip/UI/GUI/HashGUI.cpp" - "../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CrcReg.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/Lang.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/NewHandler.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/TextConfig.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Windows/Clipboard.cpp" - "../../../../CPP/Windows/Control/Controls.cpp" - "../../../../CPP/Windows/Control/Dialog.cpp" - "../../../../CPP/Windows/Control/Window2.cpp" - "../../../../CPP/Windows/DLL.cpp" - "../../../../CPP/Windows/ErrorMsg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantConv.cpp" - "../../../../CPP/Windows/Registry.cpp" - "../../../../CPP/Windows/Synchronization.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/Windows/Window.cpp" - "../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zFM_do_not_use ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zFM_do_not_use ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/7zG/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zG/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/7zG/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zG/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -DLANG -DEXTERNAL_CODECS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_executable(7zG - - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/Alloc.c" - "../../../../C/CpuArch.c" - "../../../../C/Threads.c" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp" - "../../../../CPP/7zip/Common/FileStreams.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp" - "../../../../CPP/7zip/UI/Common/Bench.cpp" - "../../../../CPP/7zip/UI/Common/DefaultName.cpp" - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp" - "../../../../CPP/7zip/UI/Common/Extract.cpp" - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp" - "../../../../CPP/7zip/UI/Common/HashCalc.cpp" - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp" - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp" - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp" - "../../../../CPP/7zip/UI/Common/SetProperties.cpp" - "../../../../CPP/7zip/UI/Common/SortUtils.cpp" - "../../../../CPP/7zip/UI/Common/TempFiles.cpp" - "../../../../CPP/7zip/UI/Common/Update.cpp" - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp" - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp" - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp" - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp" - "../../../../CPP/7zip/UI/Common/WorkDir.cpp" - "../../../../CPP/7zip/UI/Common/ZipRegistry.cpp" - "../../../../CPP/7zip/UI/Explorer/MyMessages.cpp" - "../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp" - "../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/LangUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp" - "../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp" - "../../../../CPP/7zip/UI/FileManager/PropertyName.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp" - "../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp" - "../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp" - "../../../../CPP/7zip/UI/FileManager/StringUtils.cpp" - "../../../../CPP/7zip/UI/GUI/BenchmarkDialog.cpp" - "../../../../CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp" - "../../../../CPP/7zip/UI/GUI/CompressDialog.cpp" - "../../../../CPP/7zip/UI/GUI/CompressDialog_rc.cpp" - "../../../../CPP/7zip/UI/GUI/ExtractDialog.cpp" - "../../../../CPP/7zip/UI/GUI/ExtractDialog_rc.cpp" - "../../../../CPP/7zip/UI/GUI/ExtractGUI.cpp" - "../../../../CPP/7zip/UI/GUI/GUI.cpp" - "../../../../CPP/7zip/UI/GUI/HashGUI.cpp" - "../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp" - "../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp" - "../../../../CPP/7zip/UI/GUI/UpdateGUI.cpp" - "../../../../CPP/7zip/UI/GUI/wxGUI.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CommandLineParser.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/Lang.cpp" - "../../../../CPP/Common/ListFileUtils.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/NewHandler.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Windows/Control/Controls.cpp" - "../../../../CPP/Windows/Control/Dialog.cpp" - "../../../../CPP/Windows/DLL.cpp" - "../../../../CPP/Windows/ErrorMsg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantConv.cpp" - "../../../../CPP/Windows/Registry.cpp" - "../../../../CPP/Windows/Synchronization.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/Windows/Window.cpp" - "../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zG ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zG ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/7z_/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7z_/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/7z_/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7z_/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -DEXTERNAL_CODECS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -DBREAK_HANDLER -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_executable(7z_ - - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/Alloc.c" - "../../../../C/CpuArch.c" - "../../../../C/Threads.c" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp" - "../../../../CPP/7zip/Common/FileStreams.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp" - "../../../../CPP/7zip/UI/Common/Bench.cpp" - "../../../../CPP/7zip/UI/Common/DefaultName.cpp" - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp" - "../../../../CPP/7zip/UI/Common/Extract.cpp" - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp" - "../../../../CPP/7zip/UI/Common/HashCalc.cpp" - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp" - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp" - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp" - "../../../../CPP/7zip/UI/Common/SetProperties.cpp" - "../../../../CPP/7zip/UI/Common/SortUtils.cpp" - "../../../../CPP/7zip/UI/Common/TempFiles.cpp" - "../../../../CPP/7zip/UI/Common/Update.cpp" - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp" - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp" - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp" - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp" - "../../../../CPP/7zip/UI/Console/BenchCon.cpp" - "../../../../CPP/7zip/UI/Console/ConsoleClose.cpp" - "../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/HashCon.cpp" - "../../../../CPP/7zip/UI/Console/List.cpp" - "../../../../CPP/7zip/UI/Console/Main.cpp" - "../../../../CPP/7zip/UI/Console/MainAr.cpp" - "../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/PercentPrinter.cpp" - "../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/UserInputUtils.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CommandLineParser.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/ListFileUtils.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/NewHandler.cpp" - "../../../../CPP/Common/StdInStream.cpp" - "../../../../CPP/Common/StdOutStream.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Windows/DLL.cpp" - "../../../../CPP/Windows/ErrorMsg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantConv.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/myWindows/myAddExeFlag.cpp" - "../../../../CPP/myWindows/mySplitCommandLine.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -find_library(DL_LIB dl) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7z_ ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7z_ ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/7za/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7za/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/7za/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7za/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -DBREAK_HANDLER -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_executable(7za - - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/7zStream.c" - "../../../../C/Aes.c" - "../../../../C/Alloc.c" - "../../../../C/Bcj2.c" - "../../../../C/Bcj2Enc.c" - "../../../../C/Bra.c" - "../../../../C/Bra86.c" - "../../../../C/BraIA64.c" - "../../../../C/BwtSort.c" - "../../../../C/CpuArch.c" - "../../../../C/Delta.c" - "../../../../C/HuffEnc.c" - "../../../../C/LzFind.c" - "../../../../C/LzFindMt.c" - "../../../../C/Lzma2Dec.c" - "../../../../C/Lzma2Enc.c" - "../../../../C/LzmaDec.c" - "../../../../C/LzmaEnc.c" - "../../../../C/MtCoder.c" - "../../../../C/Ppmd7.c" - "../../../../C/Ppmd7Dec.c" - "../../../../C/Ppmd7Enc.c" - "../../../../C/Ppmd8.c" - "../../../../C/Ppmd8Dec.c" - "../../../../C/Ppmd8Enc.c" - "../../../../C/Sha1.c" - "../../../../C/Sha256.c" - "../../../../C/Sort.c" - "../../../../C/Threads.c" - "../../../../C/Xz.c" - "../../../../C/XzCrc64.c" - "../../../../C/XzCrc64Opt.c" - "../../../../C/XzDec.c" - "../../../../C/XzEnc.c" - "../../../../C/XzIn.c" - "../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp" - "../../../../CPP/7zip/Archive/7z/7zDecode.cpp" - "../../../../CPP/7zip/Archive/7z/7zEncode.cpp" - "../../../../CPP/7zip/Archive/7z/7zExtract.cpp" - "../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandler.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zHeader.cpp" - "../../../../CPP/7zip/Archive/7z/7zIn.cpp" - "../../../../CPP/7zip/Archive/7z/7zOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zProperties.cpp" - "../../../../CPP/7zip/Archive/7z/7zRegister.cpp" - "../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zUpdate.cpp" - "../../../../CPP/7zip/Archive/Bz2Handler.cpp" - "../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp" - "../../../../CPP/7zip/Archive/Cab/CabHandler.cpp" - "../../../../CPP/7zip/Archive/Cab/CabHeader.cpp" - "../../../../CPP/7zip/Archive/Cab/CabIn.cpp" - "../../../../CPP/7zip/Archive/Cab/CabRegister.cpp" - "../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp" - "../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp" - "../../../../CPP/7zip/Archive/Common/FindSignature.cpp" - "../../../../CPP/7zip/Archive/Common/HandlerOut.cpp" - "../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp" - "../../../../CPP/7zip/Archive/Common/MultiStream.cpp" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/ParseProperties.cpp" - "../../../../CPP/7zip/Archive/DeflateProps.cpp" - "../../../../CPP/7zip/Archive/GzHandler.cpp" - "../../../../CPP/7zip/Archive/LzmaHandler.cpp" - "../../../../CPP/7zip/Archive/PpmdHandler.cpp" - "../../../../CPP/7zip/Archive/SplitHandler.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHandler.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHeader.cpp" - "../../../../CPP/7zip/Archive/Tar/TarIn.cpp" - "../../../../CPP/7zip/Archive/Tar/TarOut.cpp" - "../../../../CPP/7zip/Archive/Tar/TarRegister.cpp" - "../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp" - "../../../../CPP/7zip/Archive/XzHandler.cpp" - "../../../../CPP/7zip/Archive/ZHandler.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipIn.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipItem.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipOut.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp" - "../../../../CPP/7zip/Common/CWrappers.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp" - "../../../../CPP/7zip/Common/FileStreams.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/InBuffer.cpp" - "../../../../CPP/7zip/Common/InOutTempBuffer.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MemBlocks.cpp" - "../../../../CPP/7zip/Common/MethodId.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/OffsetStream.cpp" - "../../../../CPP/7zip/Common/OutBuffer.cpp" - "../../../../CPP/7zip/Common/OutMemStream.cpp" - "../../../../CPP/7zip/Common/ProgressMt.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamBinder.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Common/VirtThread.cpp" - "../../../../CPP/7zip/Compress/BZip2Crc.cpp" - "../../../../CPP/7zip/Compress/BZip2Decoder.cpp" - "../../../../CPP/7zip/Compress/BZip2Encoder.cpp" - "../../../../CPP/7zip/Compress/BZip2Register.cpp" - "../../../../CPP/7zip/Compress/Bcj2Coder.cpp" - "../../../../CPP/7zip/Compress/Bcj2Register.cpp" - "../../../../CPP/7zip/Compress/BcjCoder.cpp" - "../../../../CPP/7zip/Compress/BcjRegister.cpp" - "../../../../CPP/7zip/Compress/BitlDecoder.cpp" - "../../../../CPP/7zip/Compress/BranchMisc.cpp" - "../../../../CPP/7zip/Compress/BranchRegister.cpp" - "../../../../CPP/7zip/Compress/ByteSwap.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/Compress/CopyRegister.cpp" - "../../../../CPP/7zip/Compress/Deflate64Register.cpp" - "../../../../CPP/7zip/Compress/DeflateDecoder.cpp" - "../../../../CPP/7zip/Compress/DeflateEncoder.cpp" - "../../../../CPP/7zip/Compress/DeflateRegister.cpp" - "../../../../CPP/7zip/Compress/DeltaFilter.cpp" - "../../../../CPP/7zip/Compress/ImplodeDecoder.cpp" - "../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp" - "../../../../CPP/7zip/Compress/LzOutWindow.cpp" - "../../../../CPP/7zip/Compress/Lzma2Decoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Encoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Register.cpp" - "../../../../CPP/7zip/Compress/LzmaDecoder.cpp" - "../../../../CPP/7zip/Compress/LzmaEncoder.cpp" - "../../../../CPP/7zip/Compress/LzmaRegister.cpp" - "../../../../CPP/7zip/Compress/LzxDecoder.cpp" - "../../../../CPP/7zip/Compress/PpmdDecoder.cpp" - "../../../../CPP/7zip/Compress/PpmdEncoder.cpp" - "../../../../CPP/7zip/Compress/PpmdRegister.cpp" - "../../../../CPP/7zip/Compress/PpmdZip.cpp" - "../../../../CPP/7zip/Compress/QuantumDecoder.cpp" - "../../../../CPP/7zip/Compress/ShrinkDecoder.cpp" - "../../../../CPP/7zip/Compress/ZDecoder.cpp" - "../../../../CPP/7zip/Crypto/7zAes.cpp" - "../../../../CPP/7zip/Crypto/7zAesRegister.cpp" - "../../../../CPP/7zip/Crypto/HmacSha1.cpp" - "../../../../CPP/7zip/Crypto/MyAes.cpp" - "../../../../CPP/7zip/Crypto/MyAesReg.cpp" - "../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp" - "../../../../CPP/7zip/Crypto/RandGen.cpp" - "../../../../CPP/7zip/Crypto/WzAes.cpp" - "../../../../CPP/7zip/Crypto/ZipCrypto.cpp" - "../../../../CPP/7zip/Crypto/ZipStrong.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp" - "../../../../CPP/7zip/UI/Common/Bench.cpp" - "../../../../CPP/7zip/UI/Common/DefaultName.cpp" - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp" - "../../../../CPP/7zip/UI/Common/Extract.cpp" - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp" - "../../../../CPP/7zip/UI/Common/HashCalc.cpp" - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp" - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp" - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp" - "../../../../CPP/7zip/UI/Common/SetProperties.cpp" - "../../../../CPP/7zip/UI/Common/SortUtils.cpp" - "../../../../CPP/7zip/UI/Common/TempFiles.cpp" - "../../../../CPP/7zip/UI/Common/Update.cpp" - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp" - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp" - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp" - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp" - "../../../../CPP/7zip/UI/Console/BenchCon.cpp" - "../../../../CPP/7zip/UI/Console/ConsoleClose.cpp" - "../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/HashCon.cpp" - "../../../../CPP/7zip/UI/Console/List.cpp" - "../../../../CPP/7zip/UI/Console/Main.cpp" - "../../../../CPP/7zip/UI/Console/MainAr.cpp" - "../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/PercentPrinter.cpp" - "../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/UserInputUtils.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CommandLineParser.cpp" - "../../../../CPP/Common/CrcReg.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/ListFileUtils.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/Sha1Reg.cpp" - "../../../../CPP/Common/Sha256Reg.cpp" - "../../../../CPP/Common/StdInStream.cpp" - "../../../../CPP/Common/StdOutStream.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Common/XzCrc64Reg.cpp" - "../../../../CPP/Windows/ErrorMsg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantConv.cpp" - "../../../../CPP/Windows/Synchronization.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/myWindows/myAddExeFlag.cpp" - "../../../../CPP/myWindows/mySplitCommandLine.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -IF(APPLE) - TARGET_LINK_LIBRARIES(7za ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7za ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/7zr/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zr/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/7zr/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/7zr/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -D_NO_CRYPTO -DBREAK_HANDLER -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_executable(7zr - - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/7zStream.c" - "../../../../C/Alloc.c" - "../../../../C/Bcj2.c" - "../../../../C/Bcj2Enc.c" - "../../../../C/Bra.c" - "../../../../C/Bra86.c" - "../../../../C/BraIA64.c" - "../../../../C/CpuArch.c" - "../../../../C/Delta.c" - "../../../../C/LzFind.c" - "../../../../C/LzFindMt.c" - "../../../../C/Lzma2Dec.c" - "../../../../C/Lzma2Enc.c" - "../../../../C/LzmaDec.c" - "../../../../C/LzmaEnc.c" - "../../../../C/MtCoder.c" - "../../../../C/Sha256.c" - "../../../../C/Threads.c" - "../../../../C/Xz.c" - "../../../../C/XzCrc64.c" - "../../../../C/XzCrc64Opt.c" - "../../../../C/XzDec.c" - "../../../../C/XzEnc.c" - "../../../../C/XzIn.c" - "../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp" - "../../../../CPP/7zip/Archive/7z/7zDecode.cpp" - "../../../../CPP/7zip/Archive/7z/7zEncode.cpp" - "../../../../CPP/7zip/Archive/7z/7zExtract.cpp" - "../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandler.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zHeader.cpp" - "../../../../CPP/7zip/Archive/7z/7zIn.cpp" - "../../../../CPP/7zip/Archive/7z/7zOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zProperties.cpp" - "../../../../CPP/7zip/Archive/7z/7zRegister.cpp" - "../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zUpdate.cpp" - "../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp" - "../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp" - "../../../../CPP/7zip/Archive/Common/HandlerOut.cpp" - "../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp" - "../../../../CPP/7zip/Archive/Common/MultiStream.cpp" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/ParseProperties.cpp" - "../../../../CPP/7zip/Archive/LzmaHandler.cpp" - "../../../../CPP/7zip/Archive/SplitHandler.cpp" - "../../../../CPP/7zip/Archive/XzHandler.cpp" - "../../../../CPP/7zip/Common/CWrappers.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp" - "../../../../CPP/7zip/Common/FileStreams.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/InBuffer.cpp" - "../../../../CPP/7zip/Common/InOutTempBuffer.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MethodId.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/OffsetStream.cpp" - "../../../../CPP/7zip/Common/OutBuffer.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamBinder.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Common/VirtThread.cpp" - "../../../../CPP/7zip/Compress/Bcj2Coder.cpp" - "../../../../CPP/7zip/Compress/Bcj2Register.cpp" - "../../../../CPP/7zip/Compress/BcjCoder.cpp" - "../../../../CPP/7zip/Compress/BcjRegister.cpp" - "../../../../CPP/7zip/Compress/BranchMisc.cpp" - "../../../../CPP/7zip/Compress/BranchRegister.cpp" - "../../../../CPP/7zip/Compress/ByteSwap.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/Compress/CopyRegister.cpp" - "../../../../CPP/7zip/Compress/DeltaFilter.cpp" - "../../../../CPP/7zip/Compress/Lzma2Decoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Encoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Register.cpp" - "../../../../CPP/7zip/Compress/LzmaDecoder.cpp" - "../../../../CPP/7zip/Compress/LzmaEncoder.cpp" - "../../../../CPP/7zip/Compress/LzmaRegister.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp" - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp" - "../../../../CPP/7zip/UI/Common/Bench.cpp" - "../../../../CPP/7zip/UI/Common/DefaultName.cpp" - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp" - "../../../../CPP/7zip/UI/Common/Extract.cpp" - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp" - "../../../../CPP/7zip/UI/Common/HashCalc.cpp" - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp" - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp" - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp" - "../../../../CPP/7zip/UI/Common/SetProperties.cpp" - "../../../../CPP/7zip/UI/Common/SortUtils.cpp" - "../../../../CPP/7zip/UI/Common/TempFiles.cpp" - "../../../../CPP/7zip/UI/Common/Update.cpp" - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp" - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp" - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp" - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp" - "../../../../CPP/7zip/UI/Console/BenchCon.cpp" - "../../../../CPP/7zip/UI/Console/ConsoleClose.cpp" - "../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/HashCon.cpp" - "../../../../CPP/7zip/UI/Console/List.cpp" - "../../../../CPP/7zip/UI/Console/Main.cpp" - "../../../../CPP/7zip/UI/Console/MainAr.cpp" - "../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/PercentPrinter.cpp" - "../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp" - "../../../../CPP/7zip/UI/Console/UserInputUtils.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CommandLineParser.cpp" - "../../../../CPP/Common/CrcReg.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/ListFileUtils.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/NewHandler.cpp" - "../../../../CPP/Common/Sha256Reg.cpp" - "../../../../CPP/Common/StdInStream.cpp" - "../../../../CPP/Common/StdOutStream.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Common/XzCrc64Reg.cpp" - "../../../../CPP/Windows/ErrorMsg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantConv.cpp" - "../../../../CPP/Windows/Synchronization.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/myWindows/myAddExeFlag.cpp" - "../../../../CPP/myWindows/mySplitCommandLine.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zr ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zr ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/CMakeLists.txt 2016-02-17 06:16:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - -project(p7zip) - -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin - CACHE STRING "Where binaries and .dll files go" FORCE) - - -IF(HAVE_WCHAR_H) - OPTION(HAVE_UNICODE_WCHAR "Enable Unicode Support" YES) - MARK_AS_ADVANCED(HAVE_UNICODE_WCHAR) -ELSE(HAVE_WCHAR_H) - SET(HAVE_UNICODE_WCHAR 0) -ENDIF(HAVE_WCHAR_H) - -SET(HAVE_PTHREADS 0) -FIND_PACKAGE(Threads) -IF(WIN32 OR CMAKE_USE_PTHREADS_INIT) - SET(HAVE_PTHREADS 1) -ENDIF(WIN32 OR CMAKE_USE_PTHREADS_INIT) - -add_definitions(-DENV_HAVE_GCCVISIBILITYPATCH) - -SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fvisibility-inlines-hidden") - -add_subdirectory(7za) - -add_subdirectory(7z_) - -add_subdirectory(7zr) - -add_subdirectory(Format7zFree bin) - -find_package(wxWidgets COMPONENTS core base adv) - -if(wxWidgets_FOUND) - - add_subdirectory(7zG) - - add_subdirectory(7zFM) - -else(wxWidgets_FOUND) - message("Warning : wxWidgets not found") -endif(wxWidgets_FOUND) - - - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,278 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -include_directories( - "../../../myWindows" - "../../../" - "../../../include_windows" -) - -add_definitions( -DEXTERNAL_CODECS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_REENTRANT -DENV_UNIX -DBREAK_HANDLER -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE) - -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -add_library(7z MODULE - - "../../../../C/7zBuf2.c" - "../../../../C/7zCrc.c" - "../../../../C/7zCrcOpt.c" - "../../../../C/7zStream.c" - "../../../../C/Aes.c" - "../../../../C/Alloc.c" - "../../../../C/Bcj2.c" - "../../../../C/Bcj2Enc.c" - "../../../../C/Blake2s.c" - "../../../../C/Bra.c" - "../../../../C/Bra86.c" - "../../../../C/BraIA64.c" - "../../../../C/BwtSort.c" - "../../../../C/CpuArch.c" - "../../../../C/Delta.c" - "../../../../C/HuffEnc.c" - "../../../../C/LzFind.c" - "../../../../C/LzFindMt.c" - "../../../../C/Lzma2Dec.c" - "../../../../C/Lzma2Enc.c" - "../../../../C/LzmaDec.c" - "../../../../C/LzmaEnc.c" - "../../../../C/MtCoder.c" - "../../../../C/Ppmd7.c" - "../../../../C/Ppmd7Dec.c" - "../../../../C/Ppmd7Enc.c" - "../../../../C/Ppmd8.c" - "../../../../C/Ppmd8Dec.c" - "../../../../C/Ppmd8Enc.c" - "../../../../C/Sha1.c" - "../../../../C/Sha256.c" - "../../../../C/Sort.c" - "../../../../C/Threads.c" - "../../../../C/Xz.c" - "../../../../C/XzCrc64.c" - "../../../../C/XzCrc64Opt.c" - "../../../../C/XzDec.c" - "../../../../C/XzEnc.c" - "../../../../C/XzIn.c" - "../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp" - "../../../../CPP/7zip/Archive/7z/7zDecode.cpp" - "../../../../CPP/7zip/Archive/7z/7zEncode.cpp" - "../../../../CPP/7zip/Archive/7z/7zExtract.cpp" - "../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandler.cpp" - "../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zHeader.cpp" - "../../../../CPP/7zip/Archive/7z/7zIn.cpp" - "../../../../CPP/7zip/Archive/7z/7zOut.cpp" - "../../../../CPP/7zip/Archive/7z/7zProperties.cpp" - "../../../../CPP/7zip/Archive/7z/7zRegister.cpp" - "../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp" - "../../../../CPP/7zip/Archive/7z/7zUpdate.cpp" - "../../../../CPP/7zip/Archive/ApmHandler.cpp" - "../../../../CPP/7zip/Archive/ArHandler.cpp" - "../../../../CPP/7zip/Archive/ArchiveExports.cpp" - "../../../../CPP/7zip/Archive/ArjHandler.cpp" - "../../../../CPP/7zip/Archive/Bz2Handler.cpp" - "../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp" - "../../../../CPP/7zip/Archive/Cab/CabHandler.cpp" - "../../../../CPP/7zip/Archive/Cab/CabHeader.cpp" - "../../../../CPP/7zip/Archive/Cab/CabIn.cpp" - "../../../../CPP/7zip/Archive/Cab/CabRegister.cpp" - "../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp" - "../../../../CPP/7zip/Archive/Chm/ChmIn.cpp" - "../../../../CPP/7zip/Archive/ComHandler.cpp" - "../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp" - "../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp" - "../../../../CPP/7zip/Archive/Common/FindSignature.cpp" - "../../../../CPP/7zip/Archive/Common/HandlerOut.cpp" - "../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp" - "../../../../CPP/7zip/Archive/Common/MultiStream.cpp" - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp" - "../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp" - "../../../../CPP/7zip/Archive/Common/ParseProperties.cpp" - "../../../../CPP/7zip/Archive/CpioHandler.cpp" - "../../../../CPP/7zip/Archive/CramfsHandler.cpp" - "../../../../CPP/7zip/Archive/DeflateProps.cpp" - "../../../../CPP/7zip/Archive/DllExports2.cpp" - "../../../../CPP/7zip/Archive/DmgHandler.cpp" - "../../../../CPP/7zip/Archive/ElfHandler.cpp" - "../../../../CPP/7zip/Archive/ExtHandler.cpp" - "../../../../CPP/7zip/Archive/FatHandler.cpp" - "../../../../CPP/7zip/Archive/FlvHandler.cpp" - "../../../../CPP/7zip/Archive/GzHandler.cpp" - "../../../../CPP/7zip/Archive/GptHandler.cpp" - "../../../../CPP/7zip/Archive/HandlerCont.cpp" - "../../../../CPP/7zip/Archive/HfsHandler.cpp" - "../../../../CPP/7zip/Archive/IhexHandler.cpp" - "../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp" - "../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp" - "../../../../CPP/7zip/Archive/Iso/IsoIn.cpp" - "../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp" - "../../../../CPP/7zip/Archive/LzhHandler.cpp" - "../../../../CPP/7zip/Archive/LzmaHandler.cpp" - "../../../../CPP/7zip/Archive/MachoHandler.cpp" - "../../../../CPP/7zip/Archive/MbrHandler.cpp" - "../../../../CPP/7zip/Archive/MslzHandler.cpp" - "../../../../CPP/7zip/Archive/MubHandler.cpp" - "../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp" - "../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp" - "../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp" - "../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp" - "../../../../CPP/7zip/Archive/NtfsHandler.cpp" - "../../../../CPP/7zip/Archive/PeHandler.cpp" - "../../../../CPP/7zip/Archive/PpmdHandler.cpp" - "../../../../CPP/7zip/Archive/QcowHandler.cpp" - "../../../../CPP/7zip/Archive/Rar/RarHandler.cpp" - "../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp" - "../../../../CPP/7zip/Archive/RpmHandler.cpp" - "../../../../CPP/7zip/Archive/SplitHandler.cpp" - "../../../../CPP/7zip/Archive/SquashfsHandler.cpp" - "../../../../CPP/7zip/Archive/SwfHandler.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHandler.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp" - "../../../../CPP/7zip/Archive/Tar/TarHeader.cpp" - "../../../../CPP/7zip/Archive/Tar/TarIn.cpp" - "../../../../CPP/7zip/Archive/Tar/TarOut.cpp" - "../../../../CPP/7zip/Archive/Tar/TarRegister.cpp" - "../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp" - "../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp" - "../../../../CPP/7zip/Archive/Udf/UdfIn.cpp" - "../../../../CPP/7zip/Archive/UefiHandler.cpp" - "../../../../CPP/7zip/Archive/VdiHandler.cpp" - "../../../../CPP/7zip/Archive/VhdHandler.cpp" - "../../../../CPP/7zip/Archive/VmdkHandler.cpp" - "../../../../CPP/7zip/Archive/Wim/WimHandler.cpp" - "../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp" - "../../../../CPP/7zip/Archive/Wim/WimIn.cpp" - "../../../../CPP/7zip/Archive/Wim/WimRegister.cpp" - "../../../../CPP/7zip/Archive/XarHandler.cpp" - "../../../../CPP/7zip/Archive/XzHandler.cpp" - "../../../../CPP/7zip/Archive/ZHandler.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipIn.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipItem.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipOut.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp" - "../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp" - "../../../../CPP/7zip/Common/CWrappers.cpp" - "../../../../CPP/7zip/Common/CreateCoder.cpp" - "../../../../CPP/7zip/Common/FilterCoder.cpp" - "../../../../CPP/7zip/Common/InBuffer.cpp" - "../../../../CPP/7zip/Common/InOutTempBuffer.cpp" - "../../../../CPP/7zip/Common/LimitedStreams.cpp" - "../../../../CPP/7zip/Common/MemBlocks.cpp" - "../../../../CPP/7zip/Common/MethodId.cpp" - "../../../../CPP/7zip/Common/MethodProps.cpp" - "../../../../CPP/7zip/Common/OffsetStream.cpp" - "../../../../CPP/7zip/Common/OutBuffer.cpp" - "../../../../CPP/7zip/Common/OutMemStream.cpp" - "../../../../CPP/7zip/Common/ProgressMt.cpp" - "../../../../CPP/7zip/Common/ProgressUtils.cpp" - "../../../../CPP/7zip/Common/PropId.cpp" - "../../../../CPP/7zip/Common/StreamBinder.cpp" - "../../../../CPP/7zip/Common/StreamObjects.cpp" - "../../../../CPP/7zip/Common/StreamUtils.cpp" - "../../../../CPP/7zip/Common/UniqBlocks.cpp" - "../../../../CPP/7zip/Common/VirtThread.cpp" - "../../../../CPP/7zip/Compress/BZip2Crc.cpp" - "../../../../CPP/7zip/Compress/BZip2Decoder.cpp" - "../../../../CPP/7zip/Compress/BZip2Encoder.cpp" - "../../../../CPP/7zip/Compress/BZip2Register.cpp" - "../../../../CPP/7zip/Compress/Bcj2Coder.cpp" - "../../../../CPP/7zip/Compress/Bcj2Register.cpp" - "../../../../CPP/7zip/Compress/BcjCoder.cpp" - "../../../../CPP/7zip/Compress/BcjRegister.cpp" - "../../../../CPP/7zip/Compress/BitlDecoder.cpp" - "../../../../CPP/7zip/Compress/BranchMisc.cpp" - "../../../../CPP/7zip/Compress/BranchRegister.cpp" - "../../../../CPP/7zip/Compress/ByteSwap.cpp" - "../../../../CPP/7zip/Compress/CodecExports.cpp" - "../../../../CPP/7zip/Compress/CopyCoder.cpp" - "../../../../CPP/7zip/Compress/CopyRegister.cpp" - "../../../../CPP/7zip/Compress/Deflate64Register.cpp" - "../../../../CPP/7zip/Compress/DeflateDecoder.cpp" - "../../../../CPP/7zip/Compress/DeflateEncoder.cpp" - "../../../../CPP/7zip/Compress/DeflateRegister.cpp" - "../../../../CPP/7zip/Compress/DeltaFilter.cpp" - "../../../../CPP/7zip/Compress/ImplodeDecoder.cpp" - "../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp" - "../../../../CPP/7zip/Compress/LzOutWindow.cpp" - "../../../../CPP/7zip/Compress/LzhDecoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Decoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Encoder.cpp" - "../../../../CPP/7zip/Compress/Lzma2Register.cpp" - "../../../../CPP/7zip/Compress/LzmaDecoder.cpp" - "../../../../CPP/7zip/Compress/LzmaEncoder.cpp" - "../../../../CPP/7zip/Compress/LzmaRegister.cpp" - "../../../../CPP/7zip/Compress/LzmsDecoder.cpp" - "../../../../CPP/7zip/Compress/LzxDecoder.cpp" - "../../../../CPP/7zip/Compress/PpmdDecoder.cpp" - "../../../../CPP/7zip/Compress/PpmdEncoder.cpp" - "../../../../CPP/7zip/Compress/PpmdRegister.cpp" - "../../../../CPP/7zip/Compress/PpmdZip.cpp" - "../../../../CPP/7zip/Compress/QuantumDecoder.cpp" - "../../../../CPP/7zip/Compress/ShrinkDecoder.cpp" - "../../../../CPP/7zip/Compress/ZDecoder.cpp" - "../../../../CPP/7zip/Compress/XpressDecoder.cpp" - "../../../../CPP/7zip/Compress/ZlibDecoder.cpp" - "../../../../CPP/7zip/Compress/ZlibEncoder.cpp" - "../../../../CPP/7zip/Crypto/7zAes.cpp" - "../../../../CPP/7zip/Crypto/7zAesRegister.cpp" - "../../../../CPP/7zip/Crypto/HmacSha1.cpp" - "../../../../CPP/7zip/Crypto/HmacSha256.cpp" - "../../../../CPP/7zip/Crypto/MyAes.cpp" - "../../../../CPP/7zip/Crypto/MyAesReg.cpp" - "../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp" - "../../../../CPP/7zip/Crypto/RandGen.cpp" - "../../../../CPP/7zip/Crypto/Rar20Crypto.cpp" - "../../../../CPP/7zip/Crypto/Rar5Aes.cpp" - "../../../../CPP/7zip/Crypto/RarAes.cpp" - "../../../../CPP/7zip/Crypto/WzAes.cpp" - "../../../../CPP/7zip/Crypto/ZipCrypto.cpp" - "../../../../CPP/7zip/Crypto/ZipStrong.cpp" - "../../../../CPP/Common/CRC.cpp" - "../../../../CPP/Common/CrcReg.cpp" - "../../../../CPP/Common/DynLimBuf.cpp" - "../../../../CPP/Common/IntToString.cpp" - "../../../../CPP/Common/MyMap.cpp" - "../../../../CPP/Common/MyString.cpp" - "../../../../CPP/Common/MyVector.cpp" - "../../../../CPP/Common/MyWindows.cpp" - "../../../../CPP/Common/MyXml.cpp" - "../../../../CPP/Common/NewHandler.cpp" - "../../../../CPP/Common/Sha1Reg.cpp" - "../../../../CPP/Common/Sha256Reg.cpp" - "../../../../CPP/Common/StringConvert.cpp" - "../../../../CPP/Common/StringToInt.cpp" - "../../../../CPP/Common/UTFConvert.cpp" - "../../../../CPP/Common/Wildcard.cpp" - "../../../../CPP/Common/XzCrc64Reg.cpp" - "../../../../CPP/Windows/FileDir.cpp" - "../../../../CPP/Windows/FileFind.cpp" - "../../../../CPP/Windows/FileIO.cpp" - "../../../../CPP/Windows/FileName.cpp" - "../../../../CPP/Windows/PropVariant.cpp" - "../../../../CPP/Windows/PropVariantUtils.cpp" - "../../../../CPP/Windows/Synchronization.cpp" - "../../../../CPP/Windows/System.cpp" - "../../../../CPP/Windows/TimeUtils.cpp" - "../../../../CPP/myWindows/wine_date_and_time.cpp" -) - - -SET_TARGET_PROPERTIES(7z PROPERTIES PREFIX "") - -IF(APPLE) - TARGET_LINK_LIBRARIES(7z ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7z ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/generate.sh p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate.sh --- p7zip-rar-16.02/CPP/7zip/CMAKE/generate.sh 2016-02-03 04:54:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - -doit() -{ - cd .. - rm -fr "P7ZIP.$1" - mkdir "P7ZIP.$1" - cd "P7ZIP.$1" - - cmake -G "$2" -DCMAKE_BUILD_TYPE=Debug ../CMAKE/ - #cmake -G "$2" -DCMAKE_BUILD_TYPE=Release ../CMAKE/ -} - -CURDIR=$PWD - -cd $CURDIR -doit "Unix" "Unix Makefiles" - -cd $CURDIR -doit "codeblocks" "CodeBlocks - Unix Makefiles" - -#cd $CURDIR -#doit "KDevelop3" "KDevelop3" - -cd $CURDIR -doit "EclipseCDT4" "Eclipse CDT4 - Unix Makefiles" - -cd $CURDIR -doit "ninja" "Ninja" - diff -Nru p7zip-rar-16.02/CPP/7zip/CMAKE/generate_xcode.sh p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate_xcode.sh --- p7zip-rar-16.02/CPP/7zip/CMAKE/generate_xcode.sh 2015-01-18 17:01:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/CMAKE/generate_xcode.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ - -doit() -{ - cd .. - rm -fr "P7ZIP.$1" - mkdir "P7ZIP.$1" - cd "P7ZIP.$1" - - cmake -G "$2" -DCMAKE_BUILD_TYPE=Debug ../CMAKE/ - #cmake -G "$2" -DCMAKE_BUILD_TYPE=Release ../CMAKE/ -} - -CURDIR=$PWD - -cd $CURDIR -CMAKE_OSX_ARCHITECTURES=i386 -export CMAKE_OSX_ARCHITECTURES -doit "Xcode" "Xcode" - diff -Nru p7zip-rar-16.02/CPP/7zip/Common/CWrappers.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.cpp --- p7zip-rar-16.02/CPP/7zip/Common/CWrappers.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,230 +1,358 @@ -// CWrappers.h - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "CWrappers.h" - -#include "StreamUtils.h" - -#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1) - -#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) - -static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw() -{ - CCompressProgressWrap *p = (CCompressProgressWrap *)pp; - p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize)); - return (SRes)p->Res; -} - -CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw() -{ - p.Progress = CompressProgress; - Progress = progress; - Res = SZ_OK; -} - -static const UInt32 kStreamStepSize = (UInt32)1 << 31; - -SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) -{ - switch (res) - { - case S_OK: return SZ_OK; - case E_OUTOFMEMORY: return SZ_ERROR_MEM; - case E_INVALIDARG: return SZ_ERROR_PARAM; - case E_ABORT: return SZ_ERROR_PROGRESS; - case S_FALSE: return SZ_ERROR_DATA; - case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; - } - return defaultRes; -} - -static SRes MyRead(void *object, void *data, size_t *size) throw() -{ - CSeqInStreamWrap *p = (CSeqInStreamWrap *)object; - UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); - p->Res = (p->Stream->Read(data, curSize, &curSize)); - *size = curSize; - p->Processed += curSize; - if (p->Res == S_OK) - return SZ_OK; - return HRESULT_To_SRes(p->Res, SZ_ERROR_READ); -} - -static size_t MyWrite(void *object, const void *data, size_t size) throw() -{ - CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object; - if (p->Stream) - { - p->Res = WriteStream(p->Stream, data, size); - if (p->Res != 0) - return 0; - } - else - p->Res = S_OK; - p->Processed += size; - return size; -} - -CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw() -{ - p.Read = MyRead; - Stream = stream; - Processed = 0; -} - -CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() -{ - p.Write = MyWrite; - Stream = stream; - Res = SZ_OK; - Processed = 0; -} - -HRESULT SResToHRESULT(SRes res) throw() -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - case SZ_ERROR_PROGRESS: return E_ABORT; - case SZ_ERROR_DATA: return S_FALSE; - case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; - } - return E_FAIL; -} - -static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw() -{ - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; - UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); - p->Res = p->Stream->Read(data, curSize, &curSize); - *size = curSize; - return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; -} - -static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() -{ - CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; - UInt32 moveMethod; - switch (origin) - { - case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; - case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; - case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break; - default: return SZ_ERROR_PARAM; - } - UInt64 newPosition; - p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition); - *offset = (Int64)newPosition; - return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; -} - -CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw() -{ - Stream = stream; - p.Read = InStreamWrap_Read; - p.Seek = InStreamWrap_Seek; - Res = S_OK; -} - - -/* ---------- CByteInBufWrap ---------- */ - -void CByteInBufWrap::Free() throw() -{ - ::MidFree(Buf); - Buf = 0; -} - -bool CByteInBufWrap::Alloc(UInt32 size) throw() -{ - if (Buf == 0 || size != Size) - { - Free(); - Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); - Size = size; - } - return (Buf != 0); -} - -Byte CByteInBufWrap::ReadByteFromNewBlock() throw() -{ - if (Res == S_OK) - { - UInt32 avail; - Processed += (Cur - Buf); - Res = Stream->Read(Buf, Size, &avail); - Cur = Buf; - Lim = Buf + avail; - if (avail != 0) - return *Cur++; - } - Extra = true; - return 0; -} - -static Byte Wrap_ReadByte(void *pp) throw() -{ - CByteInBufWrap *p = (CByteInBufWrap *)pp; - if (p->Cur != p->Lim) - return *p->Cur++; - return p->ReadByteFromNewBlock(); -} - -CByteInBufWrap::CByteInBufWrap(): Buf(0) -{ - p.Read = Wrap_ReadByte; -} - - -/* ---------- CByteOutBufWrap ---------- */ - -void CByteOutBufWrap::Free() throw() -{ - ::MidFree(Buf); - Buf = 0; -} - -bool CByteOutBufWrap::Alloc(size_t size) throw() -{ - if (Buf == 0 || size != Size) - { - Free(); - Buf = (Byte *)::MidAlloc(size); - Size = size; - } - return (Buf != 0); -} - -HRESULT CByteOutBufWrap::Flush() throw() -{ - if (Res == S_OK) - { - size_t size = (Cur - Buf); - Res = WriteStream(Stream, Buf, size); - if (Res == S_OK) - Processed += size; - Cur = Buf; - } - return Res; -} - -static void Wrap_WriteByte(void *pp, Byte b) throw() -{ - CByteOutBufWrap *p = (CByteOutBufWrap *)pp; - Byte *dest = p->Cur; - *dest = b; - p->Cur = ++dest; - if (dest == p->Lim) - p->Flush(); -} - -CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0) -{ - p.Write = Wrap_WriteByte; -} +// CWrappers.c + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "CWrappers.h" + +#include "StreamUtils.h" + +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw() +{ + switch (res) + { + case S_OK: return SZ_OK; + case E_OUTOFMEMORY: return SZ_ERROR_MEM; + case E_INVALIDARG: return SZ_ERROR_PARAM; + case E_ABORT: return SZ_ERROR_PROGRESS; + case S_FALSE: return SZ_ERROR_DATA; + case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED; + default: break; + } + return defaultRes; +} + + +HRESULT SResToHRESULT(SRes res) throw() +{ + switch (res) + { + case SZ_OK: return S_OK; + + case SZ_ERROR_DATA: + case SZ_ERROR_CRC: + case SZ_ERROR_INPUT_EOF: + case SZ_ERROR_ARCHIVE: + case SZ_ERROR_NO_ARCHIVE: + return S_FALSE; + + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_PROGRESS: return E_ABORT; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + // case SZ_ERROR_OUTPUT_EOF: + // case SZ_ERROR_READ: + // case SZ_ERROR_WRITE: + // case SZ_ERROR_THREAD: + // case SZ_ERROR_ARCHIVE: + // case SZ_ERROR_NO_ARCHIVE: + // return E_FAIL; + default: break; + } + if (res < 0) + return res; + return E_FAIL; +} + + +#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1) + +#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x) + + +static SRes CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) throw() +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CCompressProgressWrap) + p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize)); + return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS); +} + +void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw() +{ + vt.Progress = CompressProgress; + Progress = progress; + Res = SZ_OK; +} + +static const UInt32 kStreamStepSize = (UInt32)1 << 31; + +static SRes MyRead(ISeqInStreamPtr pp, void *data, size_t *size) throw() +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInStreamWrap) + UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); + p->Res = (p->Stream->Read(data, curSize, &curSize)); + *size = curSize; + p->Processed += curSize; + if (p->Res == S_OK) + return SZ_OK; + return HRESULT_To_SRes(p->Res, SZ_ERROR_READ); +} + +static size_t MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size) throw() +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqOutStreamWrap) + if (p->Stream) + { + p->Res = WriteStream(p->Stream, data, size); + if (p->Res != 0) + return 0; + } + else + p->Res = S_OK; + p->Processed += size; + return size; +} + + +void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw() +{ + vt.Read = MyRead; + Stream = stream; + Processed = 0; + Res = S_OK; +} + +void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw() +{ + vt.Write = MyWrite; + Stream = stream; + Res = SZ_OK; + Processed = 0; +} + + +static SRes InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size) throw() +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) + UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize); + p->Res = p->Stream->Read(data, curSize, &curSize); + *size = curSize; + return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin) throw() +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap) + UInt32 moveMethod; + /* we need (int)origin to eliminate the clang warning: + default label in switch which covers all enumeration values + [-Wcovered-switch-default */ + switch ((int)origin) + { + case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break; + default: return SZ_ERROR_PARAM; + } + UInt64 newPosition; + p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition); + *offset = (Int64)newPosition; + return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ; +} + +void CSeekInStreamWrap::Init(IInStream *stream) throw() +{ + Stream = stream; + vt.Read = InStreamWrap_Read; + vt.Seek = InStreamWrap_Seek; + Res = S_OK; +} + + +/* ---------- CByteInBufWrap ---------- */ + +void CByteInBufWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = NULL; +} + +bool CByteInBufWrap::Alloc(UInt32 size) throw() +{ + if (!Buf || size != Size) + { + Free(); + Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (Buf != NULL); +} + +Byte CByteInBufWrap::ReadByteFromNewBlock() throw() +{ + if (!Extra && Res == S_OK) + { + UInt32 avail; + Res = Stream->Read(Buf, Size, &avail); + Processed += (size_t)(Cur - Buf); + Cur = Buf; + Lim = Buf + avail; + if (avail != 0) + return *Cur++; + } + Extra = true; + return 0; +} + +// #pragma GCC diagnostic ignored "-Winvalid-offsetof" + +static Byte Wrap_ReadByte(IByteInPtr pp) throw() +{ + CByteInBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInBufWrap) + if (p->Cur != p->Lim) + return *p->Cur++; + return p->ReadByteFromNewBlock(); +} + +CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL) +{ + vt.Read = Wrap_ReadByte; +} + + + +/* ---------- CByteOutBufWrap ---------- */ + +/* +void CLookToSequentialWrap::Free() throw() +{ + ::MidFree(BufBase); + BufBase = NULL; +} + +bool CLookToSequentialWrap::Alloc(UInt32 size) throw() +{ + if (!BufBase || size != Size) + { + Free(); + BufBase = (Byte *)::MidAlloc((size_t)size); + Size = size; + } + return (BufBase != NULL); +} +*/ + +/* +EXTERN_C_BEGIN + +void CLookToSequentialWrap_Look(ILookInSeqStreamPtr pp) +{ + CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj; + + if (p->Extra || p->Res != S_OK) + return; + { + UInt32 avail; + p->Res = p->Stream->Read(p->BufBase, p->Size, &avail); + p->Processed += avail; + pp->Buf = p->BufBase; + pp->Limit = pp->Buf + avail; + if (avail == 0) + p->Extra = true; + } +} + +EXTERN_C_END +*/ + + +/* ---------- CByteOutBufWrap ---------- */ + +void CByteOutBufWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = NULL; +} + +bool CByteOutBufWrap::Alloc(size_t size) throw() +{ + if (!Buf || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != NULL); +} + +HRESULT CByteOutBufWrap::Flush() throw() +{ + if (Res == S_OK) + { + const size_t size = (size_t)(Cur - Buf); + Res = WriteStream(Stream, Buf, size); + if (Res == S_OK) + Processed += size; + // else throw 11; + } + Cur = Buf; // reset pointer for later Wrap_WriteByte() + return Res; +} + +static void Wrap_WriteByte(IByteOutPtr pp, Byte b) throw() +{ + CByteOutBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt); + // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteOutBufWrap) + Byte *dest = p->Cur; + *dest = b; + p->Cur = ++dest; + if (dest == p->Lim) + p->Flush(); +} + +CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0) +{ + vt.Write = Wrap_WriteByte; +} + + +/* ---------- CLookOutWrap ---------- */ + +/* +void CLookOutWrap::Free() throw() +{ + ::MidFree(Buf); + Buf = NULL; +} + +bool CLookOutWrap::Alloc(size_t size) throw() +{ + if (!Buf || size != Size) + { + Free(); + Buf = (Byte *)::MidAlloc(size); + Size = size; + } + return (Buf != NULL); +} + +static size_t LookOutWrap_GetOutBuf(ILookOutStreamPtr pp, void **buf) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + *buf = p->Buf; + return p->Size; +} + +static size_t LookOutWrap_Write(ILookOutStreamPtr pp, size_t size) throw() +{ + CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt); + if (p->Res == S_OK && size != 0) + { + p->Res = WriteStream(p->Stream, p->Buf, size); + if (p->Res == S_OK) + { + p->Processed += size; + return size; + } + } + return 0; +} + +CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0) +{ + vt.GetOutBuf = LookOutWrap_GetOutBuf; + vt.Write = LookOutWrap_Write; +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/Common/CWrappers.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.h --- p7zip-rar-16.02/CPP/7zip/Common/CWrappers.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CWrappers.h 2023-05-04 09:00:00.000000000 +0000 @@ -1,114 +1,182 @@ -// CWrappers.h - -#ifndef __C_WRAPPERS_H -#define __C_WRAPPERS_H - -#include "../ICoder.h" -#include "../../Common/MyCom.h" - -struct CCompressProgressWrap -{ - ICompressProgress p; - ICompressProgressInfo *Progress; - HRESULT Res; - - CCompressProgressWrap(ICompressProgressInfo *progress) throw(); -}; - -struct CSeqInStreamWrap -{ - ISeqInStream p; - ISequentialInStream *Stream; - HRESULT Res; - UInt64 Processed; - - CSeqInStreamWrap(ISequentialInStream *stream) throw(); -}; - -struct CSeekInStreamWrap -{ - ISeekInStream p; - IInStream *Stream; - HRESULT Res; - - CSeekInStreamWrap(IInStream *stream) throw(); -}; - -struct CSeqOutStreamWrap -{ - ISeqOutStream p; - ISequentialOutStream *Stream; - HRESULT Res; - UInt64 Processed; - - CSeqOutStreamWrap(ISequentialOutStream *stream) throw(); -}; - -HRESULT SResToHRESULT(SRes res) throw(); - -struct CByteInBufWrap -{ - IByteIn p; - const Byte *Cur; - const Byte *Lim; - Byte *Buf; - UInt32 Size; - ISequentialInStream *Stream; - UInt64 Processed; - bool Extra; - HRESULT Res; - - CByteInBufWrap(); - ~CByteInBufWrap() { Free(); } - void Free() throw(); - bool Alloc(UInt32 size) throw(); - void Init() - { - Lim = Cur = Buf; - Processed = 0; - Extra = false; - Res = S_OK; - } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } - Byte ReadByteFromNewBlock() throw(); - Byte ReadByte() - { - if (Cur != Lim) - return *Cur++; - return ReadByteFromNewBlock(); - } -}; - -struct CByteOutBufWrap -{ - IByteOut p; - Byte *Cur; - const Byte *Lim; - Byte *Buf; - size_t Size; - ISequentialOutStream *Stream; - UInt64 Processed; - HRESULT Res; - - CByteOutBufWrap() throw(); - ~CByteOutBufWrap() { Free(); } - void Free() throw(); - bool Alloc(size_t size) throw(); - void Init() - { - Cur = Buf; - Lim = Buf + Size; - Processed = 0; - Res = S_OK; - } - UInt64 GetProcessed() const { return Processed + (Cur - Buf); } - HRESULT Flush() throw(); - void WriteByte(Byte b) - { - *Cur++ = b; - if (Cur == Lim) - Flush(); - } -}; - -#endif +// CWrappers.h + +#ifndef ZIP7_INC_C_WRAPPERS_H +#define ZIP7_INC_C_WRAPPERS_H + +#include "../ICoder.h" +#include "../../Common/MyCom.h" + +SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw(); +HRESULT SResToHRESULT(SRes res) throw(); + +struct CCompressProgressWrap +{ + ICompressProgress vt; + ICompressProgressInfo *Progress; + HRESULT Res; + + void Init(ICompressProgressInfo *progress) throw(); +}; + + +struct CSeqInStreamWrap +{ + ISeqInStream vt; + ISequentialInStream *Stream; + HRESULT Res; + UInt64 Processed; + + void Init(ISequentialInStream *stream) throw(); +}; + + +struct CSeekInStreamWrap +{ + ISeekInStream vt; + IInStream *Stream; + HRESULT Res; + + void Init(IInStream *stream) throw(); +}; + + +struct CSeqOutStreamWrap +{ + ISeqOutStream vt; + ISequentialOutStream *Stream; + HRESULT Res; + UInt64 Processed; + + void Init(ISequentialOutStream *stream) throw(); +}; + + +struct CByteInBufWrap +{ + IByteIn vt; + const Byte *Cur; + const Byte *Lim; + Byte *Buf; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CByteInBufWrap() throw(); + ~CByteInBufWrap() { Free(); } + void Free() throw(); + bool Alloc(UInt32 size) throw(); + void Init() + { + Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } + Byte ReadByteFromNewBlock() throw(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + + +/* +struct CLookToSequentialWrap +{ + Byte *BufBase; + UInt32 Size; + ISequentialInStream *Stream; + UInt64 Processed; + bool Extra; + HRESULT Res; + + CLookToSequentialWrap(): BufBase(NULL) {} + ~CLookToSequentialWrap() { Free(); } + void Free() throw(); + bool Alloc(UInt32 size) throw(); + void Init() + { + // Lim = Cur = Buf; + Processed = 0; + Extra = false; + Res = S_OK; + } + // UInt64 GetProcessed() const { return Processed + (Cur - Buf); } + + Byte ReadByteFromNewBlock() throw(); + Byte ReadByte() + { + if (Cur != Lim) + return *Cur++; + return ReadByteFromNewBlock(); + } +}; + +EXTERN_C_BEGIN +// void CLookToSequentialWrap_Look(ILookInSeqStream *pp); +EXTERN_C_END +*/ + + + +struct CByteOutBufWrap +{ + IByteOut vt; + Byte *Cur; + const Byte *Lim; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CByteOutBufWrap() throw(); + ~CByteOutBufWrap() { Free(); } + void Free() throw(); + bool Alloc(size_t size) throw(); + void Init() + { + Cur = Buf; + Lim = Buf + Size; + Processed = 0; + Res = S_OK; + } + UInt64 GetProcessed() const { return Processed + (size_t)(Cur - Buf); } + HRESULT Flush() throw(); + void WriteByte(Byte b) + { + *Cur++ = b; + if (Cur == Lim) + Flush(); + } +}; + + +/* +struct CLookOutWrap +{ + ILookOutStream vt; + Byte *Buf; + size_t Size; + ISequentialOutStream *Stream; + UInt64 Processed; + HRESULT Res; + + CLookOutWrap() throw(); + ~CLookOutWrap() { Free(); } + void Free() throw(); + bool Alloc(size_t size) throw(); + void Init() + { + Processed = 0; + Res = S_OK; + } +}; +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/CreateCoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.cpp --- p7zip-rar-16.02/CPP/7zip/Common/CreateCoder.cpp 2015-06-21 08:10:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.cpp 2024-10-27 08:00:00.000000000 +0000 @@ -1,461 +1,548 @@ -// CreateCoder.cpp - -#include "StdAfx.h" - -#include "../../Windows/Defs.h" -#include "../../Windows/PropVariant.h" - -#include "CreateCoder.h" - -#include "FilterCoder.h" -#include "RegisterCodec.h" - -static const unsigned kNumCodecsMax = 64; -unsigned g_NumCodecs = 0; -const CCodecInfo *g_Codecs[kNumCodecsMax]; - -// We use g_ExternalCodecs in other stages. -/* -#ifdef EXTERNAL_CODECS -extern CExternalCodecs g_ExternalCodecs; -#define CHECK_GLOBAL_CODECS \ - if (!__externalCodecs || !__externalCodecs->IsSet()) __externalCodecs = &g_ExternalCodecs; -#endif -*/ - -#define CHECK_GLOBAL_CODECS - -void RegisterCodec(const CCodecInfo *codecInfo) throw() -{ - if (g_NumCodecs < kNumCodecsMax) - g_Codecs[g_NumCodecs++] = codecInfo; -} - -static const unsigned kNumHashersMax = 16; -unsigned g_NumHashers = 0; -const CHasherInfo *g_Hashers[kNumHashersMax]; - -void RegisterHasher(const CHasherInfo *hashInfo) throw() -{ - if (g_NumHashers < kNumHashersMax) - g_Hashers[g_NumHashers++] = hashInfo; -} - - -#ifdef EXTERNAL_CODECS - -static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) -{ - NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); - if (prop.vt == VT_EMPTY) - res = 1; - else if (prop.vt == VT_UI4) - res = prop.ulVal; - else - return E_INVALIDARG; - return S_OK; -} - -static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) -{ - NWindows::NCOM::CPropVariant prop; - RINOK(codecsInfo->GetProperty(index, propID, &prop)); - if (prop.vt == VT_EMPTY) - res = true; - else if (prop.vt == VT_BOOL) - res = VARIANT_BOOLToBool(prop.boolVal); - else - return E_INVALIDARG; - return S_OK; -} - -HRESULT CExternalCodecs::Load() -{ - Codecs.Clear(); - Hashers.Clear(); - - if (GetCodecs) - { - CCodecInfoEx info; - - UString s; - UInt32 num; - RINOK(GetCodecs->GetNumMethods(&num)); - - for (UInt32 i = 0; i < num; i++) - { - NWindows::NCOM::CPropVariant prop; - - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)); - if (prop.vt != VT_UI8) - continue; // old Interface - info.Id = prop.uhVal.QuadPart; - - prop.Clear(); - - info.Name.Empty(); - RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)); - if (prop.vt == VT_BSTR) - info.Name.SetFromWStr_if_Ascii(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - continue; - - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)); - { - UInt32 numUnpackStreams = 1; - RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)); - if (numUnpackStreams != 1) - continue; - } - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); - RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); - - Codecs.Add(info); - } - } - - if (GetHashers) - { - UInt32 num = GetHashers->GetNumHashers(); - CHasherInfoEx info; - - for (UInt32 i = 0; i < num; i++) - { - NWindows::NCOM::CPropVariant prop; - - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)); - if (prop.vt != VT_UI8) - continue; - info.Id = prop.uhVal.QuadPart; - - prop.Clear(); - - info.Name.Empty(); - RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)); - if (prop.vt == VT_BSTR) - info.Name.SetFromWStr_if_Ascii(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - continue; - - Hashers.Add(info); - } - } - - return S_OK; -} - -#endif - - -bool FindMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - const AString &name, - CMethodId &methodId, UInt32 &numStreams) -{ - unsigned i; - for (i = 0; i < g_NumCodecs; i++) - { - const CCodecInfo &codec = *g_Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) - { - methodId = codec.Id; - numStreams = codec.NumStreams; - return true; - } - } - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) - { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) - { - methodId = codec.Id; - numStreams = codec.NumStreams; - return true; - } - } - - #endif - - return false; -} - -bool FindMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, - AString &name) -{ - name.Empty(); - - unsigned i; - for (i = 0; i < g_NumCodecs; i++) - { - const CCodecInfo &codec = *g_Codecs[i]; - if (methodId == codec.Id) - { - name = codec.Name; - return true; - } - } - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) - { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (methodId == codec.Id) - { - name = codec.Name; - return true; - } - } - - #endif - - return false; -} - -bool FindHashMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - const AString &name, - CMethodId &methodId) -{ - unsigned i; - for (i = 0; i < g_NumHashers; i++) - { - const CHasherInfo &codec = *g_Hashers[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) - { - methodId = codec.Id; - return true; - } - } - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; - if (StringsAreEqualNoCase_Ascii(name, codec.Name)) - { - methodId = codec.Id; - return true; - } - } - - #endif - - return false; -} - -void GetHashMethods( - DECL_EXTERNAL_CODECS_LOC_VARS - CRecordVector &methods) -{ - methods.ClearAndSetSize(g_NumHashers); - unsigned i; - for (i = 0; i < g_NumHashers; i++) - methods[i] = (*g_Hashers[i]).Id; - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (__externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - methods.Add(__externalCodecs->Hashers[i].Id); - - #endif -} - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &filter, - CCreatedCoder &cod) -{ - cod.IsExternal = false; - cod.IsFilter = false; - cod.NumStreams = 1; - - unsigned i; - for (i = 0; i < g_NumCodecs; i++) - { - const CCodecInfo &codec = *g_Codecs[i]; - if (codec.Id == methodId) - { - if (encode) - { - if (codec.CreateEncoder) - { - void *p = codec.CreateEncoder(); - if (codec.IsFilter) filter = (ICompressFilter *)p; - else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p; - else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; } - return S_OK; - } - } - else - if (codec.CreateDecoder) - { - void *p = codec.CreateDecoder(); - if (codec.IsFilter) filter = (ICompressFilter *)p; - else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p; - else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; } - return S_OK; - } - } - } - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (__externalCodecs) - { - cod.IsExternal = true; - for (i = 0; i < __externalCodecs->Codecs.Size(); i++) - { - const CCodecInfoEx &codec = __externalCodecs->Codecs[i]; - if (codec.Id == methodId) - { - if (encode) - { - if (codec.EncoderIsAssigned) - { - if (codec.NumStreams == 1) - { - HRESULT res = __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); - if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) - return res; - if (cod.Coder) - return res; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); - } - cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); - } - } - else - if (codec.DecoderIsAssigned) - { - if (codec.NumStreams == 1) - { - HRESULT res = __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); - if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) - return res; - if (cod.Coder) - return res; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); - } - cod.NumStreams = codec.NumStreams; - return __externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); - } - } - } - } - #endif - - return S_OK; -} - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CCreatedCoder &cod) -{ - CMyComPtr filter; - HRESULT res = CreateCoder( - EXTERNAL_CODECS_LOC_VARS - methodId, encode, - filter, cod); - - if (filter) - { - cod.IsFilter = true; - CFilterCoder *coderSpec = new CFilterCoder(encode); - cod.Coder = coderSpec; - coderSpec->Filter = filter; - } - - return res; -} - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &coder) -{ - CCreatedCoder cod; - HRESULT res = CreateCoder( - EXTERNAL_CODECS_LOC_VARS - methodId, encode, - cod); - coder = cod.Coder; - return res; -} - -HRESULT CreateFilter( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &filter) -{ - CCreatedCoder cod; - return CreateCoder( - EXTERNAL_CODECS_LOC_VARS - methodId, encode, - filter, cod); -} - - -HRESULT CreateHasher( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, - AString &name, - CMyComPtr &hasher) -{ - name.Empty(); - - unsigned i; - for (i = 0; i < g_NumHashers; i++) - { - const CHasherInfo &codec = *g_Hashers[i]; - if (codec.Id == methodId) - { - hasher = codec.CreateHasher(); - name = codec.Name; - break; - } - } - - #ifdef EXTERNAL_CODECS - - CHECK_GLOBAL_CODECS - - if (!hasher && __externalCodecs) - for (i = 0; i < __externalCodecs->Hashers.Size(); i++) - { - const CHasherInfoEx &codec = __externalCodecs->Hashers[i]; - if (codec.Id == methodId) - { - name = codec.Name; - return __externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); - } - } - - #endif - - return S_OK; -} +// CreateCoder.cpp + +#include "StdAfx.h" + +#include "../../Windows/Defs.h" +#include "../../Windows/PropVariant.h" + +#include "CreateCoder.h" + +#include "FilterCoder.h" +#include "RegisterCodec.h" + +static const unsigned kNumCodecsMax = 64; +extern +unsigned g_NumCodecs; +unsigned g_NumCodecs = 0; +extern +const CCodecInfo *g_Codecs[]; +const CCodecInfo *g_Codecs[kNumCodecsMax]; + +// We use g_ExternalCodecs in other stages. +#ifdef Z7_EXTERNAL_CODECS +/* +extern CExternalCodecs g_ExternalCodecs; +#define CHECK_GLOBAL_CODECS \ + if (!_externalCodecs || !_externalCodecs->IsSet()) _externalCodecs = &g_ExternalCodecs; +*/ +#define CHECK_GLOBAL_CODECS +#endif + + +void RegisterCodec(const CCodecInfo *codecInfo) throw() +{ + if (g_NumCodecs < kNumCodecsMax) + g_Codecs[g_NumCodecs++] = codecInfo; +} + +static const unsigned kNumHashersMax = 32; +extern +unsigned g_NumHashers; +unsigned g_NumHashers = 0; +extern +const CHasherInfo *g_Hashers[]; +const CHasherInfo *g_Hashers[kNumHashersMax]; + +void RegisterHasher(const CHasherInfo *hashInfo) throw() +{ + if (g_NumHashers < kNumHashersMax) + g_Hashers[g_NumHashers++] = hashInfo; +} + + +#ifdef Z7_EXTERNAL_CODECS + +static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)) + if (prop.vt == VT_EMPTY) + res = 1; + else if (prop.vt == VT_UI4) + res = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; +} + +static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) +{ + NWindows::NCOM::CPropVariant prop; + RINOK(codecsInfo->GetProperty(index, propID, &prop)) + if (prop.vt == VT_EMPTY) + res = true; + else if (prop.vt == VT_BOOL) + res = VARIANT_BOOLToBool(prop.boolVal); + else + return E_INVALIDARG; + return S_OK; +} + +HRESULT CExternalCodecs::Load() +{ + Codecs.Clear(); + Hashers.Clear(); + + if (GetCodecs) + { + CCodecInfoEx info; + + UString s; + UInt32 num; + RINOK(GetCodecs->GetNumMethods(&num)) + + for (UInt32 i = 0; i < num; i++) + { + NWindows::NCOM::CPropVariant prop; + + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kID, &prop)) + if (prop.vt != VT_UI8) + continue; // old Interface + info.Id = prop.uhVal.QuadPart; + + prop.Clear(); + + info.Name.Empty(); + RINOK(GetCodecs->GetProperty(i, NMethodPropID::kName, &prop)) + if (prop.vt == VT_BSTR) + info.Name.SetFromWStr_if_Ascii(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + continue; + + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kPackStreams, info.NumStreams)) + { + UInt32 numUnpackStreams = 1; + RINOK(ReadNumberOfStreams(GetCodecs, i, NMethodPropID::kUnpackStreams, numUnpackStreams)) + if (numUnpackStreams != 1) + continue; + } + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)) + RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter)) + + Codecs.Add(info); + } + } + + if (GetHashers) + { + UInt32 num = GetHashers->GetNumHashers(); + CHasherInfoEx info; + + for (UInt32 i = 0; i < num; i++) + { + NWindows::NCOM::CPropVariant prop; + + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kID, &prop)) + if (prop.vt != VT_UI8) + continue; + info.Id = prop.uhVal.QuadPart; + + prop.Clear(); + + info.Name.Empty(); + RINOK(GetHashers->GetHasherProp(i, NMethodPropID::kName, &prop)) + if (prop.vt == VT_BSTR) + info.Name.SetFromWStr_if_Ascii(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + continue; + + Hashers.Add(info); + } + } + + return S_OK; +} + +#endif + + +int FindMethod_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + const AString &name, + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter) +{ + unsigned i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if ((encode ? codec.CreateEncoder : codec.CreateDecoder) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) + { + methodId = codec.Id; + numStreams = codec.NumStreams; + isFilter = codec.IsFilter; + return (int)i; + } + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if ((encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned) + && StringsAreEqualNoCase_Ascii(name, codec.Name)) + { + methodId = codec.Id; + numStreams = codec.NumStreams; + isFilter = codec.IsFilter; + return (int)(g_NumCodecs + i); + } + } + + #endif + + return -1; +} + + +static int FindMethod_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode) +{ + unsigned i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (codec.Id == methodId && (encode ? codec.CreateEncoder : codec.CreateDecoder)) + return (int)i; + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if (codec.Id == methodId && (encode ? codec.EncoderIsAssigned : codec.DecoderIsAssigned)) + return (int)(g_NumCodecs + i); + } + + #endif + + return -1; +} + + +bool FindMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + AString &name) +{ + name.Empty(); + + unsigned i; + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Codecs.Size(); i++) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + if (methodId == codec.Id) + { + name = codec.Name; + return true; + } + } + + #endif + + return false; +} + +bool FindHashMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + const AString &name, + CMethodId &methodId) +{ + unsigned i; + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + { + methodId = codec.Id; + return true; + } + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + { + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; + if (StringsAreEqualNoCase_Ascii(name, codec.Name)) + { + methodId = codec.Id; + return true; + } + } + + #endif + + return false; +} + +void GetHashMethods( + DECL_EXTERNAL_CODECS_LOC_VARS + CRecordVector &methods) +{ + methods.ClearAndSetSize(g_NumHashers); + unsigned i; + for (i = 0; i < g_NumHashers; i++) + methods[i] = (*g_Hashers[i]).Id; + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + methods.Add(_externalCodecs->Hashers[i].Id); + + #endif +} + + + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned i, bool encode, + CMyComPtr &filter, + CCreatedCoder &cod) +{ + cod.IsExternal = false; + cod.IsFilter = false; + cod.NumStreams = 1; + + if (i < g_NumCodecs) + { + const CCodecInfo &codec = *g_Codecs[i]; + // if (codec.Id == methodId) + { + if (encode) + { + if (codec.CreateEncoder) + { + void *p = codec.CreateEncoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p; + else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; } + return S_OK; + } + } + else + if (codec.CreateDecoder) + { + void *p = codec.CreateDecoder(); + if (codec.IsFilter) filter = (ICompressFilter *)p; + else if (codec.NumStreams == 1) cod.Coder = (ICompressCoder *)p; + else { cod.Coder2 = (ICompressCoder2 *)p; cod.NumStreams = codec.NumStreams; } + return S_OK; + } + } + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (_externalCodecs) + { + i -= g_NumCodecs; + cod.IsExternal = true; + if (i < _externalCodecs->Codecs.Size()) + { + const CCodecInfoEx &codec = _externalCodecs->Codecs[i]; + // if (codec.Id == methodId) + { + if (encode) + { + if (codec.EncoderIsAssigned) + { + if (codec.NumStreams == 1) + { + const HRESULT res = _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) + return res; + if (cod.Coder) + return res; + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter); + } + cod.NumStreams = codec.NumStreams; + return _externalCodecs->GetCodecs->CreateEncoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + } + } + else + if (codec.DecoderIsAssigned) + { + if (codec.NumStreams == 1) + { + const HRESULT res = _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder, (void **)&cod.Coder); + if (res != S_OK && res != E_NOINTERFACE && res != CLASS_E_CLASSNOTAVAILABLE) + return res; + if (cod.Coder) + return res; + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter); + } + cod.NumStreams = codec.NumStreams; + return _externalCodecs->GetCodecs->CreateDecoder(i, &IID_ICompressCoder2, (void **)&cod.Coder2); + } + } + } + } + #endif + + return S_OK; +} + + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod) +{ + CMyComPtr filter; + const HRESULT res = CreateCoder_Index( + EXTERNAL_CODECS_LOC_VARS + index, encode, + filter, cod); + + if (filter) + { + cod.IsFilter = true; + CFilterCoder *coderSpec = new CFilterCoder(encode); + cod.Coder = coderSpec; + coderSpec->Filter = filter; + } + + return res; +} + + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &filter, + CCreatedCoder &cod) +{ + const int index = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS methodId, encode); + if (index < 0) + return S_OK; + return CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)index, encode, filter, cod); +} + + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CCreatedCoder &cod) +{ + CMyComPtr filter; + const HRESULT res = CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + methodId, encode, + filter, cod); + + if (filter) + { + cod.IsFilter = true; + CFilterCoder *coderSpec = new CFilterCoder(encode); + cod.Coder = coderSpec; + coderSpec->Filter = filter; + } + + return res; +} + + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &coder) +{ + CCreatedCoder cod; + const HRESULT res = CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + methodId, encode, + cod); + coder = cod.Coder; + return res; +} + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &filter) +{ + CCreatedCoder cod; + return CreateCoder_Id( + EXTERNAL_CODECS_LOC_VARS + methodId, encode, + filter, cod); +} + + +HRESULT CreateHasher( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + AString &name, + CMyComPtr &hasher) +{ + name.Empty(); + + unsigned i; + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + if (codec.Id == methodId) + { + hasher = codec.CreateHasher(); + name = codec.Name; + break; + } + } + + #ifdef Z7_EXTERNAL_CODECS + + CHECK_GLOBAL_CODECS + + if (!hasher && _externalCodecs) + for (i = 0; i < _externalCodecs->Hashers.Size(); i++) + { + const CHasherInfoEx &codec = _externalCodecs->Hashers[i]; + if (codec.Id == methodId) + { + name = codec.Name; + return _externalCodecs->GetHashers->CreateHasher((UInt32)i, &hasher); + } + } + + #endif + + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/CreateCoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.h --- p7zip-rar-16.02/CPP/7zip/Common/CreateCoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/CreateCoder.h 2023-03-18 12:00:00.000000000 +0000 @@ -1,182 +1,200 @@ -// CreateCoder.h - -#ifndef __CREATE_CODER_H -#define __CREATE_CODER_H - -#include "../../Common/MyCom.h" -#include "../../Common/MyString.h" - -#include "../ICoder.h" - -#include "MethodId.h" - -/* - if EXTERNAL_CODECS is not defined, the code supports only codecs that - are statically linked at compile-time and link-time. - - if EXTERNAL_CODECS is defined, the code supports also codecs from another - executable modules, that can be linked dynamically at run-time: - - EXE module can use codecs from external DLL files. - - DLL module can use codecs from external EXE and DLL files. - - CExternalCodecs contains information about codecs and interfaces to create them. - - The order of codecs: - 1) Internal codecs - 2) External codecs -*/ - -#ifdef EXTERNAL_CODECS - -struct CCodecInfoEx -{ - CMethodId Id; - AString Name; - UInt32 NumStreams; - bool EncoderIsAssigned; - bool DecoderIsAssigned; - - CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} -}; - -struct CHasherInfoEx -{ - CMethodId Id; - AString Name; -}; - -#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo, -#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo) -#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo); -#define IMPL_ISetCompressCodecsInfo2(x) \ -STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \ - COM_TRY_BEGIN __externalCodecs.GetCodecs = compressCodecsInfo; return __externalCodecs.Load(); COM_TRY_END } -#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) - -struct CExternalCodecs -{ - CMyComPtr GetCodecs; - CMyComPtr GetHashers; - - CObjectVector Codecs; - CObjectVector Hashers; - - bool IsSet() const { return GetCodecs != NULL || GetHashers != NULL; } - - HRESULT Load(); - - void ClearAndRelease() - { - Hashers.Clear(); - Codecs.Clear(); - GetHashers.Release(); - GetCodecs.Release(); - } - - ~CExternalCodecs() - { - GetHashers.Release(); - GetCodecs.Release(); - } -}; - -extern CExternalCodecs g_ExternalCodecs; - -#define EXTERNAL_CODECS_VARS2 (__externalCodecs.IsSet() ? &__externalCodecs : &g_ExternalCodecs) -#define EXTERNAL_CODECS_VARS2_L (&__externalCodecs) -#define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs) - -#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs __externalCodecs; - -#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, -#define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L, -#define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G, - -#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *__externalCodecs -#define EXTERNAL_CODECS_LOC_VARS2 __externalCodecs - -#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, -#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, - -#else - -#define PUBLIC_ISetCompressCodecsInfo -#define QUERY_ENTRY_ISetCompressCodecsInfo -#define DECL_ISetCompressCodecsInfo -#define IMPL_ISetCompressCodecsInfo -#define EXTERNAL_CODECS_VARS2 -#define DECL_EXTERNAL_CODECS_VARS -#define EXTERNAL_CODECS_VARS -#define EXTERNAL_CODECS_VARS_L -#define EXTERNAL_CODECS_VARS_G -#define DECL_EXTERNAL_CODECS_LOC_VARS2 -#define EXTERNAL_CODECS_LOC_VARS2 -#define DECL_EXTERNAL_CODECS_LOC_VARS -#define EXTERNAL_CODECS_LOC_VARS - -#endif - - - - -bool FindMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - const AString &name, - CMethodId &methodId, UInt32 &numStreams); - -bool FindMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, - AString &name); - -bool FindHashMethod( - DECL_EXTERNAL_CODECS_LOC_VARS - const AString &name, - CMethodId &methodId); - -void GetHashMethods( - DECL_EXTERNAL_CODECS_LOC_VARS - CRecordVector &methods); - - -struct CCreatedCoder -{ - CMyComPtr Coder; - CMyComPtr Coder2; - - bool IsExternal; - bool IsFilter; // = true, if Coder was created from filter - UInt32 NumStreams; - - // CCreatedCoder(): IsExternal(false), IsFilter(false), NumStreams(1) {} -}; - - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &filter, - CCreatedCoder &cod); - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CCreatedCoder &cod); - -HRESULT CreateCoder( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &coder); - -HRESULT CreateFilter( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, bool encode, - CMyComPtr &filter); - -HRESULT CreateHasher( - DECL_EXTERNAL_CODECS_LOC_VARS - CMethodId methodId, - AString &name, - CMyComPtr &hasher); - -#endif +// CreateCoder.h + +#ifndef ZIP7_INC_CREATE_CODER_H +#define ZIP7_INC_CREATE_CODER_H + +#include "../../Common/MyCom.h" +#include "../../Common/MyString.h" + +#include "../ICoder.h" + +#include "MethodId.h" + +/* + if Z7_EXTERNAL_CODECS is not defined, the code supports only codecs that + are statically linked at compile-time and link-time. + + if Z7_EXTERNAL_CODECS is defined, the code supports also codecs from another + executable modules, that can be linked dynamically at run-time: + - EXE module can use codecs from external DLL files. + - DLL module can use codecs from external EXE and DLL files. + + CExternalCodecs contains information about codecs and interfaces to create them. + + The order of codecs: + 1) Internal codecs + 2) External codecs +*/ + +#ifdef Z7_EXTERNAL_CODECS + +struct CCodecInfoEx +{ + CMethodId Id; + AString Name; + UInt32 NumStreams; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + bool IsFilter; // it's unused + + CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false), IsFilter(false) {} +}; + +struct CHasherInfoEx +{ + CMethodId Id; + AString Name; +}; + +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC \ + public ISetCompressCodecsInfo, +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC \ + Z7_COM_QI_ENTRY(ISetCompressCodecsInfo) +#define DECL_ISetCompressCodecsInfo \ + Z7_COM7F_IMP(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +#define IMPL_ISetCompressCodecsInfo2(cls) \ + Z7_COM7F_IMF(cls::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) \ + { COM_TRY_BEGIN _externalCodecs.GetCodecs = compressCodecsInfo; \ + return _externalCodecs.Load(); COM_TRY_END } +#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler) + +struct CExternalCodecs +{ + CMyComPtr GetCodecs; + CMyComPtr GetHashers; + + CObjectVector Codecs; + CObjectVector Hashers; + + bool IsSet() const { return GetCodecs != NULL || GetHashers != NULL; } + + HRESULT Load(); + + void ClearAndRelease() + { + Hashers.Clear(); + Codecs.Clear(); + GetHashers.Release(); + GetCodecs.Release(); + } + + ~CExternalCodecs() + { + GetHashers.Release(); + GetCodecs.Release(); + } +}; + +extern CExternalCodecs g_ExternalCodecs; + +#define EXTERNAL_CODECS_VARS2 (_externalCodecs.IsSet() ? &_externalCodecs : &g_ExternalCodecs) +#define EXTERNAL_CODECS_VARS2_L (&_externalCodecs) +#define EXTERNAL_CODECS_VARS2_G (&g_ExternalCodecs) + +#define DECL_EXTERNAL_CODECS_VARS CExternalCodecs _externalCodecs; + +#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2, +#define EXTERNAL_CODECS_VARS_L EXTERNAL_CODECS_VARS2_L, +#define EXTERNAL_CODECS_VARS_G EXTERNAL_CODECS_VARS2_G, + +#define DECL_EXTERNAL_CODECS_LOC_VARS2 const CExternalCodecs *_externalCodecs +#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2, +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL DECL_EXTERNAL_CODECS_LOC_VARS2; + +#define EXTERNAL_CODECS_LOC_VARS2 _externalCodecs +#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2, + +#else + +#define Z7_PUBLIC_ISetCompressCodecsInfo_IFEC +#define Z7_COM_QI_ENTRY_ISetCompressCodecsInfo_IFEC +#define DECL_ISetCompressCodecsInfo +#define IMPL_ISetCompressCodecsInfo +#define EXTERNAL_CODECS_VARS2 +#define DECL_EXTERNAL_CODECS_VARS +#define EXTERNAL_CODECS_VARS +#define EXTERNAL_CODECS_VARS_L +#define EXTERNAL_CODECS_VARS_G +#define DECL_EXTERNAL_CODECS_LOC_VARS2 +#define DECL_EXTERNAL_CODECS_LOC_VARS +#define DECL_EXTERNAL_CODECS_LOC_VARS_DECL +#define EXTERNAL_CODECS_LOC_VARS2 +#define EXTERNAL_CODECS_LOC_VARS + +#endif + +int FindMethod_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + const AString &name, + bool encode, + CMethodId &methodId, + UInt32 &numStreams, + bool &isFilter); + +bool FindMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + AString &name); + +bool FindHashMethod( + DECL_EXTERNAL_CODECS_LOC_VARS + const AString &name, + CMethodId &methodId); + +void GetHashMethods( + DECL_EXTERNAL_CODECS_LOC_VARS + CRecordVector &methods); + + +struct CCreatedCoder +{ + CMyComPtr Coder; + CMyComPtr Coder2; + + bool IsExternal; + bool IsFilter; // = true, if Coder was created from filter + UInt32 NumStreams; + + // CCreatedCoder(): IsExternal(false), IsFilter(false), NumStreams(1) {} +}; + + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned codecIndex, bool encode, + CMyComPtr &filter, + CCreatedCoder &cod); + +HRESULT CreateCoder_Index( + DECL_EXTERNAL_CODECS_LOC_VARS + unsigned index, bool encode, + CCreatedCoder &cod); + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &filter, + CCreatedCoder &cod); + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CCreatedCoder &cod); + +HRESULT CreateCoder_Id( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &coder); + +HRESULT CreateFilter( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, bool encode, + CMyComPtr &filter); + +HRESULT CreateHasher( + DECL_EXTERNAL_CODECS_LOC_VARS + CMethodId methodId, + AString &name, + CMyComPtr &hasher); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FilePathAutoRename.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.cpp --- p7zip-rar-16.02/CPP/7zip/Common/FilePathAutoRename.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.cpp 2024-01-23 15:00:00.000000000 +0000 @@ -1,51 +1,46 @@ -// FilePathAutoRename.cpp - -#include "StdAfx.h" - -#include "../../Common/Defs.h" -#include "../../Common/IntToString.h" - -#include "../../Windows/FileFind.h" - -#include "FilePathAutoRename.h" - -using namespace NWindows; - -static bool MakeAutoName(const FString &name, - const FString &extension, UInt32 value, FString &path) -{ - char temp[16]; - ConvertUInt32ToString(value, temp); - path = name; - path.AddAscii(temp); - path += extension; - return NFile::NFind::DoesFileOrDirExist(path); -} - -bool AutoRenamePath(FString &path) -{ - int dotPos = path.ReverseFind_Dot(); - int slashPos = path.ReverseFind_PathSepar(); - - FString name = path; - FString extension; - if (dotPos > slashPos + 1) - { - name.DeleteFrom(dotPos); - extension = path.Ptr(dotPos); - } - name += FTEXT('_'); - - FString temp; - - UInt32 left = 1, right = ((UInt32)1 << 30); - while (left != right) - { - UInt32 mid = (left + right) / 2; - if (MakeAutoName(name, extension, mid, temp)) - left = mid + 1; - else - right = mid; - } - return !MakeAutoName(name, extension, right, path); -} +// FilePathAutoRename.cpp + +#include "StdAfx.h" + +#include "../../Windows/FileFind.h" + +#include "FilePathAutoRename.h" + +using namespace NWindows; + +static bool MakeAutoName(const FString &name, + const FString &extension, UInt32 value, FString &path) +{ + path = name; + path.Add_UInt32(value); + path += extension; + return NFile::NFind::DoesFileOrDirExist(path); +} + +bool AutoRenamePath(FString &path) +{ + const int dotPos = path.ReverseFind_Dot(); + const int slashPos = path.ReverseFind_PathSepar(); + + FString name = path; + FString extension; + if (dotPos > slashPos + 1) + { + name.DeleteFrom((unsigned)dotPos); + extension = path.Ptr((unsigned)dotPos); + } + name.Add_Char('_'); + + FString temp; + + UInt32 left = 1, right = (UInt32)1 << 30; + while (left != right) + { + const UInt32 mid = (left + right) / 2; + if (MakeAutoName(name, extension, mid, temp)) + left = mid + 1; + else + right = mid; + } + return !MakeAutoName(name, extension, right, path); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FilePathAutoRename.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.h --- p7zip-rar-16.02/CPP/7zip/Common/FilePathAutoRename.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilePathAutoRename.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// FilePathAutoRename.h - -#ifndef __FILE_PATH_AUTO_RENAME_H -#define __FILE_PATH_AUTO_RENAME_H - -#include "../../Common/MyString.h" - -bool AutoRenamePath(FString &fullProcessedPath); - -#endif +// FilePathAutoRename.h + +#ifndef ZIP7_INC_FILE_PATH_AUTO_RENAME_H +#define ZIP7_INC_FILE_PATH_AUTO_RENAME_H + +#include "../../Common/MyString.h" + +bool AutoRenamePath(FString &fullProcessedPath); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FileStreams.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.cpp --- p7zip-rar-16.02/CPP/7zip/Common/FileStreams.cpp 2015-06-19 17:06:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,476 +1,923 @@ -// FileStreams.cpp - -#include "StdAfx.h" - -#ifndef _WIN32 -#include -#include -#include -#endif - -#ifdef SUPPORT_DEVICE_FILE -#include "../../../C/Alloc.h" -#include "../../Common/Defs.h" -#endif - -#include "FileStreams.h" - -static inline HRESULT ConvertBoolToHRESULT(bool result) -{ - #ifdef _WIN32 - if (result) - return S_OK; - DWORD lastError = ::GetLastError(); - if (lastError == 0) - return E_FAIL; - return HRESULT_FROM_WIN32(lastError); - #else - return result ? S_OK: E_FAIL; - #endif -} - - -static const UInt32 kClusterSize = 1 << 18; -CInFileStream::CInFileStream(bool b): - #ifdef SUPPORT_DEVICE_FILE - VirtPos(0), - PhyPos(0), - Buf(0), - BufSize(0), - #endif - SupportHardLinks(false), - Callback(NULL), - CallbackRef(0) -{ - _ignoreSymbolicLink = b; -} - -CInFileStream::~CInFileStream() -{ - #ifdef SUPPORT_DEVICE_FILE - MidFree(Buf); - #endif - - if (Callback) - Callback->InFileStream_On_Destroy(CallbackRef); -} - -STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - #ifdef USE_WIN_FILE - - #ifdef SUPPORT_DEVICE_FILE - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (File.IsDeviceFile) - { - if (File.SizeDefined) - { - if (VirtPos >= File.Size) - return VirtPos == File.Size ? S_OK : E_FAIL; - UInt64 rem = File.Size - VirtPos; - if (size > rem) - size = (UInt32)rem; - } - for (;;) - { - const UInt32 mask = kClusterSize - 1; - const UInt64 mask2 = ~(UInt64)mask; - UInt64 alignedPos = VirtPos & mask2; - if (BufSize > 0 && BufStartPos == alignedPos) - { - UInt32 pos = (UInt32)VirtPos & mask; - if (pos >= BufSize) - return S_OK; - UInt32 rem = MyMin(BufSize - pos, size); - memcpy(data, Buf + pos, rem); - VirtPos += rem; - if (processedSize) - *processedSize += rem; - return S_OK; - } - - bool useBuf = false; - if ((VirtPos & mask) != 0 || ((ptrdiff_t)data & mask) != 0 ) - useBuf = true; - else - { - UInt64 end = VirtPos + size; - if ((end & mask) != 0) - { - end &= mask2; - if (end <= VirtPos) - useBuf = true; - else - size = (UInt32)(end - VirtPos); - } - } - if (!useBuf) - break; - if (alignedPos != PhyPos) - { - UInt64 realNewPosition; - bool result = File.Seek(alignedPos, FILE_BEGIN, realNewPosition); - if (!result) - return ConvertBoolToHRESULT(result); - PhyPos = realNewPosition; - } - - BufStartPos = alignedPos; - UInt32 readSize = kClusterSize; - if (File.SizeDefined) - readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize); - - if (!Buf) - { - Buf = (Byte *)MidAlloc(kClusterSize); - if (!Buf) - return E_OUTOFMEMORY; - } - bool result = File.Read1(Buf, readSize, BufSize); - if (!result) - return ConvertBoolToHRESULT(result); - - if (BufSize == 0) - return S_OK; - PhyPos += BufSize; - } - - if (VirtPos != PhyPos) - { - UInt64 realNewPosition; - bool result = File.Seek(VirtPos, FILE_BEGIN, realNewPosition); - if (!result) - return ConvertBoolToHRESULT(result); - PhyPos = VirtPos = realNewPosition; - } - } - #endif - - UInt32 realProcessedSize; - bool result = File.ReadPart(data, size, realProcessedSize); - if (processedSize) - *processedSize = realProcessedSize; - - #ifdef SUPPORT_DEVICE_FILE - VirtPos += realProcessedSize; - PhyPos += realProcessedSize; - #endif - - if (result) - return S_OK; - - { - DWORD error = ::GetLastError(); - - if (Callback) - return Callback->InFileStream_On_Error(CallbackRef, error); - if (error == 0) - return E_FAIL; - - return HRESULT_FROM_WIN32(error); - } - - #else - - if (processedSize) - *processedSize = 0; - ssize_t res = File.Read(data, (size_t)size); - if (res == -1) - { - if (Callback) - return Callback->InFileStream_On_Error(CallbackRef, E_FAIL); - return E_FAIL; - } - if (processedSize) - *processedSize = (UInt32)res; - return S_OK; - - #endif -} - -#ifdef UNDER_CE -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - size_t s2 = fread(data, 1, size, stdin); - int error = ferror(stdin); - if (processedSize) - *processedSize = s2; - if (s2 <= size && error == 0) - return S_OK; - return E_FAIL; -} -#else -STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - #ifdef _WIN32 - - DWORD realProcessedSize; - UInt32 sizeTemp = (1 << 20); - if (sizeTemp > size) - sizeTemp = size; - BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL); - if (processedSize) - *processedSize = realProcessedSize; - if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) - return S_OK; - return ConvertBoolToHRESULT(res != FALSE); - - #else - - if (processedSize) - *processedSize = 0; - ssize_t res; - do - { - res = read(0, data, (size_t)size); - } - while (res < 0 && (errno == EINTR)); - if (res == -1) - return E_FAIL; - if (processedSize) - *processedSize = (UInt32)res; - return S_OK; - - #endif -} - -#endif - -STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - - #ifdef USE_WIN_FILE - - #ifdef SUPPORT_DEVICE_FILE - if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) - { - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += VirtPos; break; - case STREAM_SEEK_END: offset += File.Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - VirtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; - } - #endif - - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); - - #ifdef SUPPORT_DEVICE_FILE - PhyPos = VirtPos = realNewPosition; - #endif - - if (newPosition) - *newPosition = realNewPosition; - return ConvertBoolToHRESULT(result); - - #else - - off_t res = File.Seek((off_t)offset, seekOrigin); - if (res == -1) - return E_FAIL; - if (newPosition) - *newPosition = (UInt64)res; - return S_OK; - - #endif -} - -STDMETHODIMP CInFileStream::GetSize(UInt64 *size) -{ - return ConvertBoolToHRESULT(File.GetLength(*size)); -} - -#if 0 // #ifdef USE_WIN_FILE - -STDMETHODIMP CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) -{ - BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) - { - if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; - if (cTime) *cTime = info.ftCreationTime; - if (aTime) *aTime = info.ftLastAccessTime; - if (mTime) *mTime = info.ftLastWriteTime; - if (attrib) *attrib = info.dwFileAttributes; - return S_OK; - } - return GetLastError(); -} - -STDMETHODIMP CInFileStream::GetProps2(CStreamFileProps *props) -{ - BY_HANDLE_FILE_INFORMATION info; - if (File.GetFileInformation(&info)) - { - props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; - props->VolID = info.dwVolumeSerialNumber; - props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; - props->FileID_High = 0; - props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; - props->Attrib = info.dwFileAttributes; - props->CTime = info.ftCreationTime; - props->ATime = info.ftLastAccessTime; - props->MTime = info.ftLastWriteTime; - return S_OK; - } - return GetLastError(); -} - -#endif - -////////////////////////// -// COutFileStream - -HRESULT COutFileStream::Close() -{ - return ConvertBoolToHRESULT(File.Close()); -} - -STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - #ifdef USE_WIN_FILE - - UInt32 realProcessedSize; - bool result = File.Write(data, size, realProcessedSize); - ProcessedSize += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return ConvertBoolToHRESULT(result); - - #else - - if (processedSize) - *processedSize = 0; - ssize_t res = File.Write(data, (size_t)size); - if (res == -1) - return E_FAIL; - if (processedSize) - *processedSize = (UInt32)res; - ProcessedSize += res; - return S_OK; - - #endif -} - -STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - - #ifdef USE_WIN_FILE - - UInt64 realNewPosition; - bool result = File.Seek(offset, seekOrigin, realNewPosition); - if (newPosition) - *newPosition = realNewPosition; - return ConvertBoolToHRESULT(result); - - #else - - off_t res = File.Seek((off_t)offset, seekOrigin); - if (res == -1) - return E_FAIL; - if (newPosition) - *newPosition = (UInt64)res; - return S_OK; - - #endif -} - -STDMETHODIMP COutFileStream::SetSize(UInt64 newSize) -{ - #ifdef USE_WIN_FILE - - UInt64 currentPos; - if (!File.Seek(0, FILE_CURRENT, currentPos)) - return E_FAIL; - bool result = File.SetLength(newSize); - UInt64 currentPos2; - result = result && File.Seek(currentPos, currentPos2); - return result ? S_OK : E_FAIL; - - #else - - return E_FAIL; - - #endif -} - -HRESULT COutFileStream::GetSize(UInt64 *size) -{ - return ConvertBoolToHRESULT(File.GetLength(*size)); -} - -#ifdef UNDER_CE - -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - size_t s2 = fwrite(data, 1, size, stdout); - if (processedSize) - *processedSize = s2; - return (s2 == size) ? S_OK : E_FAIL; -} - -#else - -STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - #ifdef _WIN32 - - UInt32 realProcessedSize; - BOOL res = TRUE; - if (size > 0) - { - // Seems that Windows doesn't like big amounts writing to stdout. - // So we limit portions by 32KB. - UInt32 sizeTemp = (1 << 15); - if (sizeTemp > size) - sizeTemp = size; - res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), - data, sizeTemp, (DWORD *)&realProcessedSize, NULL); - _size += realProcessedSize; - size -= realProcessedSize; - data = (const void *)((const Byte *)data + realProcessedSize); - if (processedSize) - *processedSize += realProcessedSize; - } - return ConvertBoolToHRESULT(res != FALSE); - - #else - - ssize_t res; - - do - { - res = write(1, data, (size_t)size); - } - while (res < 0 && (errno == EINTR)); - - if (res == -1) - return E_FAIL; - - _size += (size_t)res; - if (processedSize) - *processedSize = (UInt32)res; - return S_OK; - - #endif -} - -#endif +// FileStreams.cpp + +#include "StdAfx.h" + +// #include + +#ifndef _WIN32 +#include +#include +#include +#include +#include + +/* +inclusion of by is deprecated since glibc 2.25. +Since glibc 2.3.3, macros have been aliases for three GNU-specific +functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor() + +Warning in GCC: +In the GNU C Library, "major" is defined by . +For historical compatibility, it is currently defined by + as well, but we plan to remove this soon. +To use "major", include directly. +If you did not intend to use a system-defined macro "major", +you should undefine it after including +*/ +// for major()/minor(): +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#else +#include +#endif + +#endif // _WIN32 + +#include "../../Windows/FileFind.h" + +#ifdef Z7_DEVICE_FILE +#include "../../../C/Alloc.h" +#include "../../Common/Defs.h" +#endif + +#include "../PropID.h" + +#include "FileStreams.h" + +static inline HRESULT GetLastError_HRESULT() +{ + DWORD lastError = ::GetLastError(); + if (lastError == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(lastError); +} + +static inline HRESULT ConvertBoolToHRESULT(bool result) +{ + if (result) + return S_OK; + return GetLastError_HRESULT(); +} + + +#ifdef Z7_DEVICE_FILE +static const UInt32 kClusterSize = 1 << 18; +#endif + +CInFileStream::CInFileStream(): + #ifdef Z7_DEVICE_FILE + VirtPos(0), + PhyPos(0), + Buf(NULL), + BufSize(0), + #endif + #ifndef _WIN32 + _uid(0), + _gid(0), + StoreOwnerId(false), + StoreOwnerName(false), + #endif + _info_WasLoaded(false), + SupportHardLinks(false), + Callback(NULL), + CallbackRef(0) +{ +} + +CInFileStream::~CInFileStream() +{ + #ifdef Z7_DEVICE_FILE + MidFree(Buf); + #endif + + if (Callback) + Callback->InFileStream_On_Destroy(this, CallbackRef); +} + +Z7_COM7F_IMF(CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + // printf("\nCInFileStream::Read size=%d, VirtPos=%8d\n", (unsigned)size, (int)VirtPos); + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + + #ifdef Z7_DEVICE_FILE + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (File.IsDeviceFile) + { + if (File.SizeDefined) + { + if (VirtPos >= File.Size) + return VirtPos == File.Size ? S_OK : E_FAIL; + const UInt64 rem = File.Size - VirtPos; + if (size > rem) + size = (UInt32)rem; + } + for (;;) + { + const UInt32 mask = kClusterSize - 1; + const UInt64 mask2 = ~(UInt64)mask; + const UInt64 alignedPos = VirtPos & mask2; + if (BufSize > 0 && BufStartPos == alignedPos) + { + const UInt32 pos = (UInt32)VirtPos & mask; + if (pos >= BufSize) + return S_OK; + const UInt32 rem = MyMin(BufSize - pos, size); + memcpy(data, Buf + pos, rem); + VirtPos += rem; + if (processedSize) + *processedSize += rem; + return S_OK; + } + + bool useBuf = false; + if ((VirtPos & mask) != 0 || ((size_t)(ptrdiff_t)data & mask) != 0 ) + useBuf = true; + else + { + UInt64 end = VirtPos + size; + if ((end & mask) != 0) + { + end &= mask2; + if (end <= VirtPos) + useBuf = true; + else + size = (UInt32)(end - VirtPos); + } + } + if (!useBuf) + break; + if (alignedPos != PhyPos) + { + UInt64 realNewPosition; + const bool result = File.Seek((Int64)alignedPos, FILE_BEGIN, realNewPosition); + if (!result) + return ConvertBoolToHRESULT(result); + PhyPos = realNewPosition; + } + + BufStartPos = alignedPos; + UInt32 readSize = kClusterSize; + if (File.SizeDefined) + readSize = (UInt32)MyMin(File.Size - PhyPos, (UInt64)kClusterSize); + + if (!Buf) + { + Buf = (Byte *)MidAlloc(kClusterSize); + if (!Buf) + return E_OUTOFMEMORY; + } + const bool result = File.Read1(Buf, readSize, BufSize); + if (!result) + return ConvertBoolToHRESULT(result); + + if (BufSize == 0) + return S_OK; + PhyPos += BufSize; + } + + if (VirtPos != PhyPos) + { + UInt64 realNewPosition; + bool result = File.Seek((Int64)VirtPos, FILE_BEGIN, realNewPosition); + if (!result) + return ConvertBoolToHRESULT(result); + PhyPos = VirtPos = realNewPosition; + } + } + #endif + + UInt32 realProcessedSize; + const bool result = File.ReadPart(data, size, realProcessedSize); + if (processedSize) + *processedSize = realProcessedSize; + + #ifdef Z7_DEVICE_FILE + VirtPos += realProcessedSize; + PhyPos += realProcessedSize; + #endif + + if (result) + return S_OK; + + #else // Z7_FILE_STREAMS_USE_WIN_FILE + + if (processedSize) + *processedSize = 0; + const ssize_t res = File.read_part(data, (size_t)size); + if (res != -1) + { + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + } + #endif // Z7_FILE_STREAMS_USE_WIN_FILE + + { + const DWORD error = ::GetLastError(); +#if 0 + if (File.IsStdStream && error == ERROR_BROKEN_PIPE) + return S_OK; // end of stream +#endif + if (Callback) + return Callback->InFileStream_On_Error(CallbackRef, error); + if (error == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(error); + } +} + +#ifdef UNDER_CE +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t s2 = fread(data, 1, size, stdin); + int error = ferror(stdin); + if (processedSize) + *processedSize = s2; + if (s2 <= size && error == 0) + return S_OK; + return E_FAIL; +} +#else +Z7_COM7F_IMF(CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + // printf("\nCStdInFileStream::Read size = %d\n", (unsigned)size); + #ifdef _WIN32 + + DWORD realProcessedSize; + UInt32 sizeTemp = (1 << 20); + if (sizeTemp > size) + sizeTemp = size; + /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL, + and it doesn't set LastError. */ + /* + SetLastError(0); + const HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (!h || h == INVALID_HANDLE_VALUE) + { + if (processedSize) + *processedSize = 0; + if (GetLastError() == 0) + SetLastError(ERROR_INVALID_HANDLE); + return GetLastError_noZero_HRESULT(); + } + */ + BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), data, sizeTemp, &realProcessedSize, NULL); + + /* + printf("\nCInFileStream::Read: size=%d, processed=%8d res=%d 4rror=%3d\n", + (unsigned)size, (int)realProcessedSize, + (int)res, GetLastError()); + */ + + if (processedSize) + *processedSize = realProcessedSize; + if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE) + return S_OK; + return ConvertBoolToHRESULT(res != FALSE); + + #else + + if (processedSize) + *processedSize = 0; + ssize_t res; + do + { + res = read(0, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + if (res == -1) + return GetLastError_HRESULT(); + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#endif + + +/* +bool CreateStdInStream(CMyComPtr &str) +{ +#if 0 + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec);; + if (!inStreamSpec->OpenStdIn()) + return false; + if (!inStreamSpec->File.IsStdPipeStream) + str = inStreamLoc.Detach(); + else +#endif + str = new CStdInFileStream; + return true; +} +*/ + +#if 0 +bool CInFileStream::OpenStdIn() +{ + _info_WasLoaded = false; + // Sleep(100); + bool res = File.AttachStdIn(); + if (!res) + return false; +#if 1 + CStreamFileProps props; + if (GetProps2(&props) != S_OK) + { + // we can ignore that error + return false; + } + // we can't use Size, because Size can be set for pipe streams for some value. + // Seek() sees only current chunk in pipe buffer. + // So Seek() can move across only current unread chunk. + // But after reading that chunk. it can't move position back. + // We need safe check that shows that we can use seek (non-pipe mode) + // Is it safe check that shows that pipe mode was used? + File.IsStdPipeStream = (props.VolID == 0); + // && FILETIME_IsZero(props.CTime) + // && FILETIME_IsZero(props.ATime) + // && FILETIME_IsZero(props.MTime); +#endif + // printf("\n######## pipe=%d", (unsigned)File.IsStdPipeStream); + return true; +} +#endif + + +Z7_COM7F_IMF(CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + /* + printf("\nCInFileStream::Seek seekOrigin=%d, offset=%8d, VirtPos=%8d\n", + (unsigned)seekOrigin, (int)offset, (int)VirtPos); + */ + if (seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile && (File.SizeDefined || seekOrigin != STREAM_SEEK_END)) + { + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += VirtPos; break; + case STREAM_SEEK_END: offset += File.Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + VirtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; + } + #endif + + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); + const HRESULT hres = ConvertBoolToHRESULT(result); + + /* 21.07: new File.Seek() in 21.07 already returns correct (realNewPosition) + in case of error. So we don't need additional code below */ + // if (!result) { realNewPosition = 0; File.GetPosition(realNewPosition); } + + #ifdef Z7_DEVICE_FILE + PhyPos = VirtPos = realNewPosition; + #endif + + if (newPosition) + *newPosition = realNewPosition; + + return hres; + + #else + + const off_t res = File.seek((off_t)offset, (int)seekOrigin); + if (res == -1) + { + const HRESULT hres = GetLastError_HRESULT(); + if (newPosition) + *newPosition = (UInt64)File.seekToCur(); + return hres; + } + if (newPosition) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +Z7_COM7F_IMF(CInFileStream::GetSize(UInt64 *size)) +{ + return ConvertBoolToHRESULT(File.GetLength(*size)); +} + +#ifdef Z7_FILE_STREAMS_USE_WIN_FILE + +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* + BY_HANDLE_FILE_INFORMATION info; + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ + { + if (size) *size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + if (cTime) *cTime = info.ftCreationTime; + if (aTime) *aTime = info.ftLastAccessTime; + if (mTime) *mTime = info.ftLastWriteTime; + if (attrib) *attrib = info.dwFileAttributes; + return S_OK; + } +} + +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const BY_HANDLE_FILE_INFORMATION &info = _info; + /* + BY_HANDLE_FILE_INFORMATION info; + if (!File.GetFileInformation(&info)) + return GetLastError_HRESULT(); + */ + { + props->Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + props->VolID = info.dwVolumeSerialNumber; + props->FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + props->FileID_High = 0; + props->NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; + props->Attrib = info.dwFileAttributes; + props->CTime = info.ftCreationTime; + props->ATime = info.ftLastAccessTime; + props->MTime = info.ftLastWriteTime; + return S_OK; + } +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + NWindows::NCOM::CPropVariant prop; + + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + switch (propID) + { + case kpidSize: + if (File.SizeDefined) + prop = File.Size; + break; + // case kpidAttrib: prop = (UInt32)0; break; + case kpidPosixAttrib: + { + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(0); + /* GNU TAR by default can't extract file with MY_LIN_S_IFBLK attribute + so we don't use MY_LIN_S_IFBLK here */ + // prop = (UInt32)(MY_LIN_S_IFBLK | 0600); // for debug + break; + } + /* + case kpidDeviceMajor: + prop = (UInt32)8; // id for SCSI type device (sda) + break; + case kpidDeviceMinor: + prop = (UInt32)0; + break; + */ + } + } + else + #endif + { + switch (propID) + { + case kpidSize: + { + const UInt64 size = (((UInt64)_info.nFileSizeHigh) << 32) + _info.nFileSizeLow; + prop = size; + break; + } + case kpidAttrib: prop = (UInt32)_info.dwFileAttributes; break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, _info.ftCreationTime); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, _info.ftLastAccessTime); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, _info.ftLastWriteTime); break; + case kpidPosixAttrib: + prop = (UInt32)NWindows::NFile::NFind::NAttributes:: + Get_PosixMode_From_WinAttrib(_info.dwFileAttributes); + // | (UInt32)(1 << 21); // for debug + break; + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + #ifdef Z7_DEVICE_FILE + if (File.IsDeviceFile) + { + memset(&_info, 0, sizeof(_info)); + if (File.SizeDefined) + { + _info.nFileSizeHigh = (DWORD)(File.Size >> 32); + _info.nFileSizeLow = (DWORD)(File.Size); + } + _info.nNumberOfLinks = 1; + _info_WasLoaded = true; + return S_OK; + } + #endif + _info_WasLoaded = File.GetFileInformation(&_info); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); +#ifdef _WIN32 +#if 0 + printf( + "\ndwFileAttributes = %8x" + "\nftCreationTime = %8x" + "\nftLastAccessTime = %8x" + "\nftLastWriteTime = %8x" + "\ndwVolumeSerialNumber = %8x" + "\nnFileSizeHigh = %8x" + "\nnFileSizeLow = %8x" + "\nnNumberOfLinks = %8x" + "\nnFileIndexHigh = %8x" + "\nnFileIndexLow = %8x \n", + (unsigned)_info.dwFileAttributes, + (unsigned)_info.ftCreationTime.dwHighDateTime, + (unsigned)_info.ftLastAccessTime.dwHighDateTime, + (unsigned)_info.ftLastWriteTime.dwHighDateTime, + (unsigned)_info.dwVolumeSerialNumber, + (unsigned)_info.nFileSizeHigh, + (unsigned)_info.nFileSizeLow, + (unsigned)_info.nNumberOfLinks, + (unsigned)_info.nFileIndexHigh, + (unsigned)_info.nFileIndexLow); +#endif +#endif + return S_OK; +} + + +#elif !defined(_WIN32) + +Z7_COM7F_IMF(CInFileStream::GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +{ + // printf("\nCInFileStream::GetProps VirtPos = %8d\n", (int)VirtPos); + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + if (size) *size = (UInt64)st.st_size; + if (cTime) FiTime_To_FILETIME (ST_CTIME(st), *cTime); + if (aTime) FiTime_To_FILETIME (ST_ATIME(st), *aTime); + if (mTime) FiTime_To_FILETIME (ST_MTIME(st), *mTime); + if (attrib) *attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + return S_OK; +} + +// #include + +Z7_COM7F_IMF(CInFileStream::GetProps2(CStreamFileProps *props)) +{ + // printf("\nCInFileStream::GetProps2 VirtPos = %8d\n", (int)VirtPos); + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + const struct stat &st = _info; + /* + struct stat st; + if (File.my_fstat(&st) != 0) + return GetLastError_HRESULT(); + */ + + props->Size = (UInt64)st.st_size; + /* + dev_t stat::st_dev: + GCC:Linux long unsigned int : __dev_t + Mac: int + */ + props->VolID = (UInt64)(Int64)st.st_dev; + props->FileID_Low = st.st_ino; + props->FileID_High = 0; + props->NumLinks = (UInt32)st.st_nlink; // we reduce to UInt32 from (nlink_t) that is (unsigned long) + props->Attrib = NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + + FiTime_To_FILETIME (ST_CTIME(st), props->CTime); + FiTime_To_FILETIME (ST_ATIME(st), props->ATime); + FiTime_To_FILETIME (ST_MTIME(st), props->MTime); + + /* + printf("\nGetProps2() NumLinks=%d = st_dev=%d st_ino = %d\n" + , (unsigned)(props->NumLinks) + , (unsigned)(st.st_dev) + , (unsigned)(st.st_ino) + ); + */ + + return S_OK; +} + +Z7_COM7F_IMF(CInFileStream::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + // printf("\nCInFileStream::GetProperty VirtPos = %8d propID = %3d\n", (int)VirtPos, propID); + if (!_info_WasLoaded) + { + RINOK(ReloadProps()) + } + + if (!_info_WasLoaded) + return S_OK; + + const struct stat &st = _info; + + NWindows::NCOM::CPropVariant prop; + { + switch (propID) + { + case kpidSize: prop = (UInt64)st.st_size; break; + case kpidAttrib: + prop = (UInt32)NWindows::NFile::NFind::Get_WinAttribPosix_From_PosixMode(st.st_mode); + break; + case kpidCTime: PropVariant_SetFrom_FiTime(prop, ST_CTIME(st)); break; + case kpidATime: PropVariant_SetFrom_FiTime(prop, ST_ATIME(st)); break; + case kpidMTime: PropVariant_SetFrom_FiTime(prop, ST_MTIME(st)); break; + case kpidPosixAttrib: prop = (UInt32)st.st_mode; break; + + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + + case kpidDeviceMajor: + { + // printf("\nst.st_rdev = %d\n", st.st_rdev); + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(major(st.st_rdev)); // + 1000); + // prop = (UInt32)12345678; // for debug + break; + } + + case kpidDeviceMinor: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt32)(minor(st.st_rdev)); // + 100); + // prop = (UInt32)(st.st_rdev); // for debug + // printf("\nst.st_rdev = %d\n", st.st_rdev); + // prop = (UInt32)123456789; // for debug + break; + + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + + /* + case kpidDevice: + if (S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode)) + prop = (UInt64)(st.st_rdev); + break; + */ + + case kpidUserId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_uid; + break; + } + case kpidGroupId: + { + if (StoreOwnerId) + prop = (UInt32)st.st_gid; + break; + } + case kpidUser: + { + if (StoreOwnerName) + { + const uid_t uid = st.st_uid; + { + if (!OwnerName.IsEmpty() && _uid == uid) + prop = OwnerName; + else + { + const passwd *pw = getpwuid(uid); + if (pw) + { + // we can use utf-8 here. + // prop = pw->pw_name; + } + } + } + } + break; + } + case kpidGroup: + { + if (StoreOwnerName) + { + const uid_t gid = st.st_gid; + { + if (!OwnerGroup.IsEmpty() && _gid == gid) + prop = OwnerGroup; + else + { + const group *gr = getgrgid(gid); + if (gr) + { + // we can use utf-8 here. + // prop = gr->gr_name; + } + } + } + } + break; + } + default: break; + } + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStream::ReloadProps()) +{ + _info_WasLoaded = (File.my_fstat(&_info) == 0); + if (!_info_WasLoaded) + return GetLastError_HRESULT(); + return S_OK; +} + +#endif + + + + +////////////////////////// +// COutFileStream + +HRESULT COutFileStream::Close() +{ + return ConvertBoolToHRESULT(File.Close()); +} + +Z7_COM7F_IMF(COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + + UInt32 realProcessedSize; + const bool result = File.Write(data, size, realProcessedSize); + ProcessedSize += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return ConvertBoolToHRESULT(result); + + #else + + if (processedSize) + *processedSize = 0; + size_t realProcessedSize; + const ssize_t res = File.write_full(data, (size_t)size, realProcessedSize); + ProcessedSize += realProcessedSize; + if (processedSize) + *processedSize = (UInt32)realProcessedSize; + if (res == -1) + return GetLastError_HRESULT(); + return S_OK; + + #endif +} + +Z7_COM7F_IMF(COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + + UInt64 realNewPosition = 0; + const bool result = File.Seek(offset, seekOrigin, realNewPosition); + if (newPosition) + *newPosition = realNewPosition; + return ConvertBoolToHRESULT(result); + + #else + + const off_t res = File.seek((off_t)offset, (int)seekOrigin); + if (res == -1) + return GetLastError_HRESULT(); + if (newPosition) + *newPosition = (UInt64)res; + return S_OK; + + #endif +} + +Z7_COM7F_IMF(COutFileStream::SetSize(UInt64 newSize)) +{ + return ConvertBoolToHRESULT(File.SetLength_KeepPosition(newSize)); +} + +HRESULT COutFileStream::GetSize(UInt64 *size) +{ + return ConvertBoolToHRESULT(File.GetLength(*size)); +} + +#ifdef UNDER_CE + +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t s2 = fwrite(data, 1, size, stdout); + if (processedSize) + *processedSize = s2; + return (s2 == size) ? S_OK : E_FAIL; +} + +#else + +Z7_COM7F_IMF(CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + #ifdef _WIN32 + + UInt32 realProcessedSize; + BOOL res = TRUE; + if (size > 0) + { + // Seems that Windows doesn't like big amounts writing to stdout. + // So we limit portions by 32KB. + UInt32 sizeTemp = (1 << 15); + if (sizeTemp > size) + sizeTemp = size; + res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), + data, sizeTemp, (DWORD *)&realProcessedSize, NULL); + _size += realProcessedSize; + size -= realProcessedSize; + data = (const void *)((const Byte *)data + realProcessedSize); + if (processedSize) + *processedSize += realProcessedSize; + } + return ConvertBoolToHRESULT(res != FALSE); + + #else + + ssize_t res; + + do + { + res = write(1, data, (size_t)size); + } + while (res < 0 && (errno == EINTR)); + + if (res == -1) + return GetLastError_HRESULT(); + + _size += (size_t)res; + if (processedSize) + *processedSize = (UInt32)res; + return S_OK; + + #endif +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FileStreams.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.h --- p7zip-rar-16.02/CPP/7zip/Common/FileStreams.h 2015-10-03 18:41:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FileStreams.h 2024-03-28 13:00:00.000000000 +0000 @@ -1,171 +1,205 @@ -// FileStreams.h - -#ifndef __FILE_STREAMS_H -#define __FILE_STREAMS_H - -#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE) -#define USE_WIN_FILE -#endif - -#include "../../Common/MyString.h" - -#ifdef USE_WIN_FILE -#include "../../Windows/FileIO.h" -#else -#include "../../Common/C_FileIO.h" -#endif - -#include "../../Common/MyCom.h" - -#include "../IStream.h" - -#if 1 // FIXME #ifdef _WIN32 -typedef UINT_PTR My_UINT_PTR; -#else -typedef UINT My_UINT_PTR; -#endif - -struct IInFileStream_Callback -{ - virtual HRESULT InFileStream_On_Error(My_UINT_PTR val, DWORD error) = 0; - virtual void InFileStream_On_Destroy(My_UINT_PTR val) = 0; -}; - -class CInFileStream: - public IInStream, - public IStreamGetSize, - #if 0 // #ifdef USE_WIN_FILE - public IStreamGetProps, - public IStreamGetProps2, - #endif - public CMyUnknownImp -{ - bool _ignoreSymbolicLink; -public: - #ifdef USE_WIN_FILE - NWindows::NFile::NIO::CInFile File; - - #ifdef SUPPORT_DEVICE_FILE - UInt64 VirtPos; - UInt64 PhyPos; - UInt64 BufStartPos; - Byte *Buf; - UInt32 BufSize; - #endif - - #else - NC::NFile::NIO::CInFile File; - #endif - - bool SupportHardLinks; - - IInFileStream_Callback *Callback; - My_UINT_PTR CallbackRef; - - virtual ~CInFileStream(); - - CInFileStream(bool b=false); - - bool Open(CFSTR fileName) - { - #ifdef USE_WIN_FILE - return File.Open(fileName,_ignoreSymbolicLink); - #else - return File.Open(fileName); - #endif - } - - bool OpenShared(CFSTR fileName, bool shareForWrite) - { - return this->Open(fileName); // return File.OpenShared(fileName, shareForWrite); - } - - MY_QUERYINTERFACE_BEGIN2(IInStream) - MY_QUERYINTERFACE_ENTRY(IStreamGetSize) - #if 0 // #ifdef USE_WIN_FILE - MY_QUERYINTERFACE_ENTRY(IStreamGetProps) - MY_QUERYINTERFACE_ENTRY(IStreamGetProps2) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - STDMETHOD(GetSize)(UInt64 *size); - #if 0 // #ifdef USE_WIN_FILE - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib); - STDMETHOD(GetProps2)(CStreamFileProps *props); - #endif -}; - -class CStdInFileStream: - public ISequentialInStream, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP - - virtual ~CStdInFileStream() {} - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -class COutFileStream: - public IOutStream, - public CMyUnknownImp -{ -public: - #ifdef USE_WIN_FILE - NWindows::NFile::NIO::COutFile File; - #else - NC::NFile::NIO::COutFile File; - #endif - virtual ~COutFileStream() {} - bool Create(CFSTR fileName, bool createAlways) - { - ProcessedSize = 0; - return File.Create(fileName, createAlways); - } - bool Open(CFSTR fileName, DWORD creationDisposition) - { - ProcessedSize = 0; - return File.Open(fileName, creationDisposition); - } - - HRESULT Close(); - - UInt64 ProcessedSize; - - #ifdef USE_WIN_FILE - bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) - { - return File.SetTime(cTime, aTime, mTime); - } - bool SetMTime(const FILETIME *mTime) { return File.SetMTime(mTime); } - #endif - - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); - - HRESULT GetSize(UInt64 *size); -}; - -class CStdOutFileStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - UInt64 _size; -public: - MY_UNKNOWN_IMP - - UInt64 GetSize() const { return _size; } - CStdOutFileStream(): _size(0) {} - virtual ~CStdOutFileStream() {} - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -#endif +// FileStreams.h + +#ifndef ZIP7_INC_FILE_STREAMS_H +#define ZIP7_INC_FILE_STREAMS_H + +#ifdef _WIN32 +#define Z7_FILE_STREAMS_USE_WIN_FILE +#endif + +#include "../../Common/MyCom.h" +#include "../../Common/MyString.h" + +#include "../../Windows/FileIO.h" + +#include "../IStream.h" + +#include "UniqBlocks.h" + + +class CInFileStream; + +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IInFileStream_Callback) +{ + virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error) = 0; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) = 0; +}; +Z7_PURE_INTERFACES_END + + +/* +Z7_CLASS_IMP_COM_5( + CInFileStream + , IInStream + , IStreamGetSize + , IStreamGetProps + , IStreamGetProps2 + , IStreamGetProp +) +*/ +Z7_class_final(CInFileStream) : + public IInStream, + public IStreamGetSize, + public IStreamGetProps, + public IStreamGetProps2, + public IStreamGetProp, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_6( + IInStream, + ISequentialInStream, + IStreamGetSize, + IStreamGetProps, + IStreamGetProps2, + IStreamGetProp) + + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(IInStream) +public: + Z7_IFACE_COM7_IMP(IStreamGetSize) +private: + Z7_IFACE_COM7_IMP(IStreamGetProps) +public: + Z7_IFACE_COM7_IMP(IStreamGetProps2) + Z7_IFACE_COM7_IMP(IStreamGetProp) + +private: + NWindows::NFile::NIO::CInFile File; +public: + + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + + #ifdef Z7_DEVICE_FILE + UInt64 VirtPos; + UInt64 PhyPos; + UInt64 BufStartPos; + Byte *Buf; + UInt32 BufSize; + #endif + + #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; + + CInFileStream(); + ~CInFileStream(); + + void Set_PreserveATime(bool v) + { + File.PreserveATime = v; + } + + bool GetLength(UInt64 &length) const throw() + { + return File.GetLength(length); + } + +#if 0 + bool OpenStdIn(); +#endif + + 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); + } +}; + +// bool CreateStdInStream(CMyComPtr &str); + +Z7_CLASS_IMP_NOQIB_1( + CStdInFileStream + , ISequentialInStream +) +}; + + +Z7_CLASS_IMP_COM_1( + COutFileStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + + NWindows::NFile::NIO::COutFile File; + + bool Create_NEW(CFSTR fileName) + { + ProcessedSize = 0; + return File.Create_NEW(fileName); + } + + bool Create_ALWAYS(CFSTR fileName) + { + ProcessedSize = 0; + return File.Create_ALWAYS(fileName); + } + + bool Open_EXISTING(CFSTR fileName) + { + ProcessedSize = 0; + return File.Open_EXISTING(fileName); + } + + bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways) + { + ProcessedSize = 0; + return File.Create_ALWAYS_or_Open_ALWAYS(fileName, createAlways); + } + + HRESULT Close(); + + UInt64 ProcessedSize; + + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) + { + return File.SetTime(cTime, aTime, mTime); + } + bool SetMTime(const CFiTime *mTime) { return File.SetMTime(mTime); } + + bool SeekToBegin_bool() + { + #ifdef Z7_FILE_STREAMS_USE_WIN_FILE + return File.SeekToBegin(); + #else + return File.seekToBegin() == 0; + #endif + } + + HRESULT GetSize(UInt64 *size); +}; + + +Z7_CLASS_IMP_NOQIB_1( + CStdOutFileStream + , ISequentialOutStream +) + UInt64 _size; +public: + UInt64 GetSize() const { return _size; } + CStdOutFileStream(): _size(0) {} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FilterCoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.cpp --- p7zip-rar-16.02/CPP/7zip/Common/FilterCoder.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.cpp 2023-03-18 13:00:00.000000000 +0000 @@ -1,418 +1,577 @@ -// FilterCoder.cpp - -#include "StdAfx.h" - -#include "../../Common/Defs.h" - -#include "FilterCoder.h" -#include "StreamUtils.h" - -/* - AES filters need 16-bytes alignment for HARDWARE-AES instructions. - So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block. - - AES-CBC filters need data size aligned for 16-bytes. - So the encoder can add zeros to the end of original stream. - - Some filters (BCJ and others) don't process data at the end of stream in some cases. - So the encoder and decoder write such last bytes without change. -*/ - - -static const UInt32 kBufSize = 1 << 20; - -STDMETHODIMP CFilterCoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CFilterCoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } - -HRESULT CFilterCoder::Alloc() -{ - UInt32 size = MyMin(_inBufSize, _outBufSize); - /* minimal bufSize is 16 bytes for AES and IA64 filter. - bufSize for AES must be aligned for 16 bytes. - We use (1 << 12) min size to support future aligned filters. */ - const UInt32 kMinSize = 1 << 12; - size &= ~(UInt32)(kMinSize - 1); - if (size < kMinSize) - size = kMinSize; - if (!_buf || _bufSize != size) - { - AllocAlignedMask(size, 16 - 1); - if (!_buf) - return E_OUTOFMEMORY; - _bufSize = size; - } - return S_OK; -} - -HRESULT CFilterCoder::Init_and_Alloc() -{ - RINOK(Filter->Init()); - return Alloc(); -} - -CFilterCoder::CFilterCoder(bool encodeMode): - _bufSize(0), - _inBufSize(kBufSize), - _outBufSize(kBufSize), - _encodeMode(encodeMode), - _outSizeIsDefined(false), - _outSize(0), - _nowPos64(0) - {} - -CFilterCoder::~CFilterCoder() -{ -} - -STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - RINOK(Init_and_Alloc()); - - UInt64 nowPos64 = 0; - bool inputFinished = false; - UInt32 pos = 0; - - while (!outSize || nowPos64 < *outSize) - { - UInt32 endPos = pos; - - if (!inputFinished) - { - size_t processedSize = _bufSize - pos; - RINOK(ReadStream(inStream, _buf + pos, &processedSize)); - endPos = pos + (UInt32)processedSize; - inputFinished = (endPos != _bufSize); - } - - pos = Filter->Filter(_buf, endPos); - - if (pos > endPos) - { - // AES - if (!inputFinished || pos > _bufSize) - return E_FAIL; - if (!_encodeMode) - return S_FALSE; - - do - _buf[endPos] = 0; - while (++endPos != pos); - - if (pos != Filter->Filter(_buf, pos)) - return E_FAIL; - } - - if (endPos == 0) - return S_OK; - - UInt32 size = (pos != 0 ? pos : endPos); - if (outSize) - { - UInt64 remSize = *outSize - nowPos64; - if (size > remSize) - size = (UInt32)remSize; - } - - RINOK(WriteStream(outStream, _buf, size)); - nowPos64 += size; - - if (pos == 0) - return S_OK; - - if (progress) - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - - UInt32 i = 0; - while (pos < endPos) - _buf[i++] = _buf[pos++]; - pos = i; - } - - return S_OK; -} - - - -// ---------- Write to Filter ---------- - -STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream) -{ - _outStream = outStream; - return S_OK; -} - -STDMETHODIMP CFilterCoder::ReleaseOutStream() -{ - _outStream.Release(); - return S_OK; -} - -HRESULT CFilterCoder::Flush2() -{ - while (_convSize != 0) - { - UInt32 num = _convSize; - if (_outSizeIsDefined) - { - UInt64 rem = _outSize - _nowPos64; - if (num > rem) - num = (UInt32)rem; - if (num == 0) - return k_My_HRESULT_WritingWasCut; - } - - UInt32 processed = 0; - HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); - if (processed == 0) - return res != S_OK ? res : E_FAIL; - - _convPos += processed; - _convSize -= processed; - _nowPos64 += processed; - RINOK(res); - } - - if (_convPos != 0) - { - UInt32 num = _bufPos - _convPos; - for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; - _bufPos = num; - _convPos = 0; - } - - return S_OK; -} - -STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - RINOK(Flush2()); - - // _convSize is 0 - // _convPos is 0 - // _bufPos is small - - if (_bufPos != _bufSize) - { - UInt32 num = MyMin(size, _bufSize - _bufPos); - memcpy(_buf + _bufPos, data, num); - size -= num; - data = (const Byte *)data + num; - if (processedSize) - *processedSize += num; - _bufPos += num; - if (_bufPos != _bufSize) - continue; - } - - // _bufPos == _bufSize - _convSize = Filter->Filter(_buf, _bufPos); - - if (_convSize == 0) - break; - if (_convSize > _bufPos) - { - // that case is not possible. - _convSize = 0; - return E_FAIL; - } - } - - return S_OK; -} - -STDMETHODIMP CFilterCoder::OutStreamFinish() -{ - for (;;) - { - RINOK(Flush2()); - if (_bufPos == 0) - break; - _convSize = Filter->Filter(_buf, _bufPos); - if (_convSize == 0) - _convSize = _bufPos; - else if (_convSize > _bufPos) - { - // AES - if (_convSize > _bufSize) - { - _convSize = 0; - return E_FAIL; - } - if (!_encodeMode) - { - _convSize = 0; - return S_FALSE; - } - for (; _bufPos < _convSize; _bufPos++) - _buf[_bufPos] = 0; - _convSize = Filter->Filter(_buf, _bufPos); - if (_convSize != _bufPos) - return E_FAIL; - } - } - - CMyComPtr finish; - _outStream.QueryInterface(IID_IOutStreamFinish, &finish); - if (finish) - return finish->OutStreamFinish(); - return S_OK; -} - -// ---------- Init functions ---------- - -STDMETHODIMP CFilterCoder::InitEncoder() -{ - InitSpecVars(); - return Init_and_Alloc(); -} - -HRESULT CFilterCoder::Init_NoSubFilterInit() -{ - InitSpecVars(); - return Alloc(); -} - -STDMETHODIMP CFilterCoder::SetOutStreamSize(const UInt64 *outSize) -{ - InitSpecVars(); - if (outSize) - { - _outSize = *outSize; - _outSizeIsDefined = true; - } - return Init_and_Alloc(); -} - -// ---------- Read from Filter ---------- - -STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream) -{ - _inStream = inStream; - return S_OK; -} - -STDMETHODIMP CFilterCoder::ReleaseInStream() -{ - _inStream.Release(); - return S_OK; -} - - -STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - if (_convSize != 0) - { - if (size > _convSize) - size = _convSize; - if (_outSizeIsDefined) - { - UInt64 rem = _outSize - _nowPos64; - if (size > rem) - size = (UInt32)rem; - } - memcpy(data, _buf + _convPos, size); - _convPos += size; - _convSize -= size; - _nowPos64 += size; - if (processedSize) - *processedSize = size; - break; - } - - if (_convPos != 0) - { - UInt32 num = _bufPos - _convPos; - for (UInt32 i = 0; i < num; i++) - _buf[i] = _buf[_convPos + i]; - _bufPos = num; - _convPos = 0; - } - - { - size_t readSize = _bufSize - _bufPos; - HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); - _bufPos += (UInt32)readSize; - RINOK(res); - } - - _convSize = Filter->Filter(_buf, _bufPos); - - if (_convSize == 0) - { - if (_bufPos == 0) - break; - // BCJ - _convSize = _bufPos; - continue; - } - - if (_convSize > _bufPos) - { - // AES - if (_convSize > _bufSize) - return E_FAIL; - if (!_encodeMode) - return S_FALSE; - - do - _buf[_bufPos] = 0; - while (++_bufPos != _convSize); - - _convSize = Filter->Filter(_buf, _convSize); - if (_convSize != _bufPos) - return E_FAIL; - } - } - - return S_OK; -} - - -#ifndef _NO_CRYPTO - -STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size) - { return _SetPassword->CryptoSetPassword(data, size); } - -STDMETHODIMP CFilterCoder::SetKey(const Byte *data, UInt32 size) - { return _CryptoProperties->SetKey(data, size); } - -STDMETHODIMP CFilterCoder::SetInitVector(const Byte *data, UInt32 size) - { return _CryptoProperties->SetInitVector(data, size); } - -#endif - - -#ifndef EXTRACT_ONLY - -STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties) - { return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } - -STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream) - { return _WriteCoderProperties->WriteCoderProperties(outStream); } - -/* -STDMETHODIMP CFilterCoder::ResetSalt() - { return _CryptoResetSalt->ResetSalt(); } -*/ - -STDMETHODIMP CFilterCoder::ResetInitVector() - { return _CryptoResetInitVector->ResetInitVector(); } - -#endif - - -STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { return _SetDecoderProperties2->SetDecoderProperties2(data, size); } +// FilterCoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../Common/Defs.h" + +#include "FilterCoder.h" +#include "StreamUtils.h" + +#ifdef _WIN32 + #define alignedMidBuffer_Alloc g_MidAlloc +#else + #define alignedMidBuffer_Alloc g_AlignedAlloc +#endif + +CAlignedMidBuffer::~CAlignedMidBuffer() +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); +} + +void CAlignedMidBuffer::AllocAligned(size_t size) +{ + ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf); + _buf = (Byte *)ISzAlloc_Alloc(&alignedMidBuffer_Alloc, size); +} + +/* + AES filters need 16-bytes alignment for HARDWARE-AES instructions. + So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block. + + AES-CBC filters need data size aligned for 16-bytes. + So the encoder can add zeros to the end of original stream. + + Some filters (BCJ and others) don't process data at the end of stream in some cases. + So the encoder and decoder write such last bytes without change. + + Most filters process all data, if we send aligned size to filter. + But BCJ filter can process up 4 bytes less than sent size. + And ARMT filter can process 2 bytes less than sent size. +*/ + + +static const UInt32 kBufSize = 1 << 21; + +Z7_COM7F_IMF(CFilterCoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CFilterCoder::SetOutBufSize(UInt32 , UInt32 size)) { _outBufSize = size; return S_OK; } + +HRESULT CFilterCoder::Alloc() +{ + UInt32 size = MyMin(_inBufSize, _outBufSize); + /* minimal bufSize is 16 bytes for AES and IA64 filter. + bufSize for AES must be aligned for 16 bytes. + We use (1 << 12) min size to support future aligned filters. */ + const UInt32 kMinSize = 1 << 12; + size &= ~(UInt32)(kMinSize - 1); + if (size < kMinSize) + size = kMinSize; + // size = (1 << 12); // + 117; // for debug + if (!_buf || _bufSize != size) + { + AllocAligned(size); + if (!_buf) + return E_OUTOFMEMORY; + _bufSize = size; + } + return S_OK; +} + +HRESULT CFilterCoder::Init_and_Alloc() +{ + RINOK(Filter->Init()) + return Alloc(); +} + +CFilterCoder::CFilterCoder(bool encodeMode): + _bufSize(0), + _inBufSize(kBufSize), + _outBufSize(kBufSize), + _encodeMode(encodeMode), + _outSize_Defined(false), + _outSize(0), + _nowPos64(0) + {} + + +Z7_COM7F_IMF(CFilterCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + RINOK(Init_and_Alloc()) + + /* + It's expected that BCJ/ARMT filter can process up to 4 bytes less + than sent data size. For such BCJ/ARMT cases with non-filtered data we: + - write some filtered data to output stream + - move non-written data (filtered and non-filtered data) to start of buffer + - read more new data from input stream to position after end of non-filtered data + - call Filter() for concatenated data in buffer. + + For all cases, even for cases with partial filtering (BCJ/ARMT), + we try to keep real/virtual alignment for all operations + (memmove, Read(), Filter(), Write()). + We use (kAlignSize=64) alignmnent that is larger than (16-bytes) + required for AES filter alignment. + + AES-CBC uses 16-bytes blocks, that is simple case for processing here, + if we call Filter() for aligned size for all calls except of last call (last block). + And now there are no filters that use blocks with non-power2 size, + but we try to support such non-power2 filters too here at Code(). + */ + + UInt64 prev = 0; + UInt64 nowPos64 = 0; + bool inputFinished = false; + UInt32 readPos = 0; + UInt32 filterPos = 0; + + while (!outSize || nowPos64 < *outSize) + { + HRESULT hres = S_OK; + if (!inputFinished) + { + size_t processedSize = _bufSize - readPos; + /* for AES filters we need at least max(16, kAlignSize) bytes in buffer. + But we try to read full buffer to reduce the number of Filter() and Write() calls. + */ + hres = ReadStream(inStream, _buf + readPos, &processedSize); + readPos += (UInt32)processedSize; + inputFinished = (readPos != _bufSize); + if (hres != S_OK) + { + // do we need to stop encoding after reading error? + // if (_encodeMode) return hres; + inputFinished = true; + } + } + + if (readPos == 0) + return hres; + + /* we set (needMoreInput = true), if it's block-filter (like AES-CBC) + that needs more data for current block filtering: + We read full input buffer with Read(), and _bufSize is aligned, + So the possible cases when we set (needMoreInput = true) are: + 1) decode : filter needs more data after the end of input stream. + another cases are possible for non-power2-block-filter, + because buffer size is not aligned for filter_non_power2_block_size: + 2) decode/encode : filter needs more data from non-finished input stream + 3) encode : filter needs more space for zeros after the end of input stream + */ + bool needMoreInput = false; + + while (readPos != filterPos) + { + /* Filter() is allowed to process part of data. + Here we use the loop to filter as max as possible. + when we call Filter(data, size): + if (size < 16), AES-CTR filter uses internal 16-byte buffer. + new (since v23.00) AES-CTR filter allows (size < 16) for non-last block, + but it will work less efficiently than calls with aligned (size). + We still support old (before v23.00) AES-CTR filters here. + We have aligned (size) for AES-CTR, if it's not last block. + We have aligned (readPos) for any filter, if (!inputFinished). + We also meet the requirements for (data) pointer in Filter() call: + { + (virtual_stream_offset % aligment_size) == (data_ptr % aligment_size) + (aligment_size == 2^N) + (aligment_size >= 16) + } + */ + const UInt32 cur = Filter->Filter(_buf + filterPos, readPos - filterPos); + if (cur == 0) + break; + const UInt32 f = filterPos + cur; + if (cur > readPos - filterPos) + { + // AES-CBC + if (hres != S_OK) + break; + + if (!_encodeMode + || cur > _bufSize - filterPos + || !inputFinished) + { + /* (cur > _bufSize - filterPos) is unexpected for AES filter, if _bufSize is multiply of 16. + But we support this case, if some future filter will use block with non-power2-size. + */ + needMoreInput = true; + break; + } + + /* (_encodeMode && inputFinished). + We add zero bytes as pad in current block after the end of read data. */ + Byte *buf = _buf; + do + buf[readPos] = 0; + while (++readPos != f); + // (readPos) now is (size_of_real_input_data + size_of_zero_pad) + if (cur != Filter->Filter(buf + filterPos, cur)) + return E_FAIL; + } + filterPos = f; + } + + UInt32 size = filterPos; + if (hres == S_OK) + { + /* If we need more Read() or Filter() calls, then we need to Write() + some data and move unwritten data to get additional space in buffer. + We try to keep alignment for data moves, Read(), Filter() and Write() calls. + */ + const UInt32 kAlignSize = 1 << 6; + const UInt32 alignedFiltered = filterPos & ~(kAlignSize - 1); + if (inputFinished) + { + if (!needMoreInput) + size = readPos; // for risc/bcj filters in last block we write data after filterPos. + else if (_encodeMode) + size = alignedFiltered; // for non-power2-block-encode-filter + } + else + size = alignedFiltered; + } + + { + UInt32 writeSize = size; + if (outSize) + { + const UInt64 rem = *outSize - nowPos64; + if (writeSize > rem) + writeSize = (UInt32)rem; + } + RINOK(WriteStream(outStream, _buf, writeSize)) + nowPos64 += writeSize; + } + + if (hres != S_OK) + return hres; + + if (inputFinished) + { + if (readPos == size) + return hres; + if (!_encodeMode) + { + // block-decode-filter (AES-CBS) has non-full last block + // we don't want unaligned data move for more iterations with this error case. + return S_FALSE; + } + } + + if (size == 0) + { + // it's unexpected that we have no any move in this iteration. + return E_FAIL; + } + // if (size != 0) + { + if (filterPos < size) + return E_FAIL; // filterPos = 0; else + filterPos -= size; + readPos -= size; + if (readPos != 0) + memmove(_buf, _buf + size, readPos); + } + // printf("\nnowPos64=%x, readPos=%x, filterPos=%x\n", (unsigned)nowPos64, (unsigned)readPos, (unsigned)filterPos); + + if (progress && (nowPos64 - prev) >= (1 << 22)) + { + prev = nowPos64; + RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)) + } + } + + return S_OK; +} + + + +// ---------- Write to Filter ---------- + +Z7_COM7F_IMF(CFilterCoder::SetOutStream(ISequentialOutStream *outStream)) +{ + _outStream = outStream; + return S_OK; +} + +Z7_COM7F_IMF(CFilterCoder::ReleaseOutStream()) +{ + _outStream.Release(); + return S_OK; +} + +HRESULT CFilterCoder::Flush2() +{ + while (_convSize != 0) + { + UInt32 num = _convSize; + if (_outSize_Defined) + { + const UInt64 rem = _outSize - _nowPos64; + if (num > rem) + num = (UInt32)rem; + if (num == 0) + return k_My_HRESULT_WritingWasCut; + } + + UInt32 processed = 0; + const HRESULT res = _outStream->Write(_buf + _convPos, num, &processed); + if (processed == 0) + return res != S_OK ? res : E_FAIL; + + _convPos += processed; + _convSize -= processed; + _nowPos64 += processed; + RINOK(res) + } + + const UInt32 convPos = _convPos; + if (convPos != 0) + { + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; + for (UInt32 i = 0; i < num; i++) + buf[i] = buf[convPos + i]; + _bufPos = num; + _convPos = 0; + } + + return S_OK; +} + +Z7_COM7F_IMF(CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + RINOK(Flush2()) + + // _convSize is 0 + // _convPos is 0 + // _bufPos is small + + if (_bufPos != _bufSize) + { + UInt32 num = MyMin(size, _bufSize - _bufPos); + memcpy(_buf + _bufPos, data, num); + size -= num; + data = (const Byte *)data + num; + if (processedSize) + *processedSize += num; + _bufPos += num; + if (_bufPos != _bufSize) + continue; + } + + // _bufPos == _bufSize + _convSize = Filter->Filter(_buf, _bufPos); + + if (_convSize == 0) + break; + if (_convSize > _bufPos) + { + // that case is not possible. + _convSize = 0; + return E_FAIL; + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CFilterCoder::OutStreamFinish()) +{ + for (;;) + { + RINOK(Flush2()) + if (_bufPos == 0) + break; + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; + UInt32 bufPos = _bufPos; + if (convSize == 0) + _convSize = bufPos; + else if (convSize > bufPos) + { + // AES + if (convSize > _bufSize) + { + _convSize = 0; + return E_FAIL; + } + if (!_encodeMode) + { + _convSize = 0; + return S_FALSE; + } + Byte *buf = _buf; + for (; bufPos < convSize; bufPos++) + buf[bufPos] = 0; + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, bufPos); + if (_convSize != _bufPos) + return E_FAIL; + } + } + + CMyComPtr finish; + _outStream.QueryInterface(IID_IOutStreamFinish, &finish); + if (finish) + return finish->OutStreamFinish(); + return S_OK; +} + +// ---------- Init functions ---------- + +Z7_COM7F_IMF(CFilterCoder::InitEncoder()) +{ + InitSpecVars(); + return Init_and_Alloc(); +} + +HRESULT CFilterCoder::Init_NoSubFilterInit() +{ + InitSpecVars(); + return Alloc(); +} + +Z7_COM7F_IMF(CFilterCoder::SetOutStreamSize(const UInt64 *outSize)) +{ + InitSpecVars(); + if (outSize) + { + _outSize = *outSize; + _outSize_Defined = true; + } + return Init_and_Alloc(); +} + +// ---------- Read from Filter ---------- + +Z7_COM7F_IMF(CFilterCoder::SetInStream(ISequentialInStream *inStream)) +{ + _inStream = inStream; + return S_OK; +} + +Z7_COM7F_IMF(CFilterCoder::ReleaseInStream()) +{ + _inStream.Release(); + return S_OK; +} + + +Z7_COM7F_IMF(CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + while (size != 0) + { + if (_convSize != 0) + { + if (size > _convSize) + size = _convSize; + if (_outSize_Defined) + { + const UInt64 rem = _outSize - _nowPos64; + if (size > rem) + size = (UInt32)rem; + } + memcpy(data, _buf + _convPos, size); + _convPos += size; + _convSize -= size; + _nowPos64 += size; + if (processedSize) + *processedSize = size; + break; + } + + const UInt32 convPos = _convPos; + if (convPos != 0) + { + const UInt32 num = _bufPos - convPos; + Byte *buf = _buf; + for (UInt32 i = 0; i < num; i++) + buf[i] = buf[convPos + i]; + _bufPos = num; + _convPos = 0; + } + + { + size_t readSize = _bufSize - _bufPos; + const HRESULT res = ReadStream(_inStream, _buf + _bufPos, &readSize); + _bufPos += (UInt32)readSize; + RINOK(res) + } + + const UInt32 convSize = Filter->Filter(_buf, _bufPos); + _convSize = convSize; + + UInt32 bufPos = _bufPos; + + if (convSize == 0) + { + if (bufPos == 0) + break; + // BCJ + _convSize = bufPos; + continue; + } + + if (convSize > bufPos) + { + // AES + if (convSize > _bufSize) + return E_FAIL; + if (!_encodeMode) + return S_FALSE; + Byte *buf = _buf; + do + buf[bufPos] = 0; + while (++bufPos != convSize); + _bufPos = bufPos; + _convSize = Filter->Filter(_buf, convSize); + if (_convSize != _bufPos) + return E_FAIL; + } + } + + return S_OK; +} + + +#ifndef Z7_NO_CRYPTO + +Z7_COM7F_IMF(CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)) + { return _setPassword->CryptoSetPassword(data, size); } + +Z7_COM7F_IMF(CFilterCoder::SetKey(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetKey(data, size); } + +Z7_COM7F_IMF(CFilterCoder::SetInitVector(const Byte *data, UInt32 size)) + { return _cryptoProperties->SetInitVector(data, size); } + +#endif + + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CFilterCoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderProperties->SetCoderProperties(propIDs, properties, numProperties); } + +Z7_COM7F_IMF(CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)) + { return _writeCoderProperties->WriteCoderProperties(outStream); } + +Z7_COM7F_IMF(CFilterCoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *properties, UInt32 numProperties)) + { return _setCoderPropertiesOpt->SetCoderPropertiesOpt(propIDs, properties, numProperties); } + +/* +Z7_COM7F_IMF(CFilterCoder::ResetSalt() + { return _cryptoResetSalt->ResetSalt(); } +*/ + +Z7_COM7F_IMF(CFilterCoder::ResetInitVector()) + { return _cryptoResetInitVector->ResetInitVector(); } + +#endif + + +Z7_COM7F_IMF(CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) + { return _setDecoderProperties2->SetDecoderProperties2(data, size); } diff -Nru p7zip-rar-16.02/CPP/7zip/Common/FilterCoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.h --- p7zip-rar-16.02/CPP/7zip/Common/FilterCoder.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/FilterCoder.h 2023-03-18 13:00:00.000000000 +0000 @@ -1,226 +1,201 @@ -// FilterCoder.h - -#ifndef __FILTER_CODER_H -#define __FILTER_CODER_H - -#include "../../../C/Alloc.h" - -#include "../../Common/MyCom.h" -#include "../ICoder.h" - -#ifndef _NO_CRYPTO -#include "../IPassword.h" -#endif - -#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ - { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ - *outObject = (void *)(i *)this; } - - -struct CAlignedMidBuffer -{ - #ifdef _WIN32 - - Byte *_buf; - - CAlignedMidBuffer(): _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_buf); } - - void AllocAlignedMask(size_t size, size_t) - { - ::MidFree(_buf); - _buf = (Byte *)::MidAlloc(size); - } - - #else - - Byte *_bufBase; - Byte *_buf; - - CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {} - ~CAlignedMidBuffer() { ::MidFree(_bufBase); } - - void AllocAlignedMask(size_t size, size_t alignMask) - { - ::MidFree(_bufBase); - _buf = NULL; - _bufBase = (Byte *)::MidAlloc(size + alignMask); - - if (_bufBase) - { - // _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - _buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - } - } - - #endif -}; - -class CFilterCoder: - public ICompressCoder, - - public ICompressSetOutStreamSize, - public ICompressInitEncoder, - - public ICompressSetInStream, - public ISequentialInStream, - - public ICompressSetOutStream, - public ISequentialOutStream, - public IOutStreamFinish, - - public ICompressSetBufSize, - - #ifndef _NO_CRYPTO - public ICryptoSetPassword, - public ICryptoProperties, - #endif - - #ifndef EXTRACT_ONLY - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - // public ICryptoResetSalt, - public ICryptoResetInitVector, - #endif - - public ICompressSetDecoderProperties2, - public CMyUnknownImp, - public CAlignedMidBuffer -{ - UInt32 _bufSize; - UInt32 _inBufSize; - UInt32 _outBufSize; - - bool _encodeMode; - bool _outSizeIsDefined; - UInt64 _outSize; - UInt64 _nowPos64; - - CMyComPtr _inStream; - CMyComPtr _outStream; - UInt32 _bufPos; - UInt32 _convPos; // current pos in buffer for converted data - UInt32 _convSize; // size of converted data starting from _convPos - - void InitSpecVars() - { - _bufPos = 0; - _convPos = 0; - _convSize = 0; - - _outSizeIsDefined = false; - _outSize = 0; - _nowPos64 = 0; - } - - HRESULT Alloc(); - HRESULT Init_and_Alloc(); - HRESULT Flush2(); - - #ifndef _NO_CRYPTO - CMyComPtr _SetPassword; - CMyComPtr _CryptoProperties; - #endif - - #ifndef EXTRACT_ONLY - CMyComPtr _SetCoderProperties; - CMyComPtr _WriteCoderProperties; - // CMyComPtr _CryptoResetSalt; - CMyComPtr _CryptoResetInitVector; - #endif - - CMyComPtr _SetDecoderProperties2; - -public: - CMyComPtr Filter; - - CFilterCoder(bool encodeMode); - ~CFilterCoder(); - - class C_InStream_Releaser - { - public: - CFilterCoder *FilterCoder; - C_InStream_Releaser(): FilterCoder(NULL) {} - ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } - }; - - class C_OutStream_Releaser - { - public: - CFilterCoder *FilterCoder; - C_OutStream_Releaser(): FilterCoder(NULL) {} - ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } - }; - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ICompressInitEncoder) - - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream) - MY_QUERYINTERFACE_ENTRY(ISequentialOutStream) - MY_QUERYINTERFACE_ENTRY(IOutStreamFinish) - - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _SetPassword) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoProperties, Filter, _CryptoProperties) - #endif - - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties) - MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _WriteCoderProperties) - // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt) - MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector) - #endif - - MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _SetDecoderProperties2) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(InitEncoder)(); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); - STDMETHOD(ReleaseOutStream)(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(OutStreamFinish)(); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - #ifndef _NO_CRYPTO - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); - #endif - - #ifndef EXTRACT_ONLY - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, - const PROPVARIANT *properties, UInt32 numProperties); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); - #endif - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - - - HRESULT Init_NoSubFilterInit(); -}; - -#endif +// FilterCoder.h + +#ifndef ZIP7_INC_FILTER_CODER_H +#define ZIP7_INC_FILTER_CODER_H + +#include "../../../C/Alloc.h" + +#include "../../Common/MyCom.h" +#include "../ICoder.h" + +#ifndef Z7_NO_CRYPTO +#include "../IPassword.h" +#endif + +#define Z7_COM_QI_ENTRY_AG(i, sub0, sub) else if (iid == IID_ ## i) \ + { if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \ + *outObject = (void *)(i *)this; } + + +struct CAlignedMidBuffer +{ + Byte *_buf; + + CAlignedMidBuffer(): _buf(NULL) {} + ~CAlignedMidBuffer(); + void AllocAligned(size_t size); +}; + + +class CFilterCoder Z7_final : + public ICompressCoder, + + public ICompressSetOutStreamSize, + public ICompressInitEncoder, + + public ICompressSetInStream, + public ISequentialInStream, + + public ICompressSetOutStream, + public ISequentialOutStream, + public IOutStreamFinish, + + public ICompressSetBufSize, + + #ifndef Z7_NO_CRYPTO + public ICryptoSetPassword, + public ICryptoProperties, + #endif + + #ifndef Z7_EXTRACT_ONLY + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, + // public ICryptoResetSalt, + public ICryptoResetInitVector, + #endif + + public ICompressSetDecoderProperties2, + public CMyUnknownImp, + public CAlignedMidBuffer +{ + UInt32 _bufSize; + UInt32 _inBufSize; + UInt32 _outBufSize; + + bool _encodeMode; + bool _outSize_Defined; + UInt64 _outSize; + UInt64 _nowPos64; + + CMyComPtr _inStream; + CMyComPtr _outStream; + UInt32 _bufPos; + UInt32 _convPos; // current pos in buffer for converted data + UInt32 _convSize; // size of converted data starting from _convPos + + void InitSpecVars() + { + _bufPos = 0; + _convPos = 0; + _convSize = 0; + + _outSize_Defined = false; + _outSize = 0; + _nowPos64 = 0; + } + + HRESULT Alloc(); + HRESULT Init_and_Alloc(); + HRESULT Flush2(); + + #ifndef Z7_NO_CRYPTO + CMyComPtr _setPassword; + CMyComPtr _cryptoProperties; + #endif + + #ifndef Z7_EXTRACT_ONLY + CMyComPtr _setCoderProperties; + CMyComPtr _writeCoderProperties; + CMyComPtr _setCoderPropertiesOpt; + // CMyComPtr _cryptoResetSalt; + CMyComPtr _cryptoResetInitVector; + #endif + + CMyComPtr _setDecoderProperties2; + +public: + CMyComPtr Filter; + + CFilterCoder(bool encodeMode); + + struct C_InStream_Releaser + { + CFilterCoder *FilterCoder; + C_InStream_Releaser(): FilterCoder(NULL) {} + ~C_InStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); } + }; + + struct C_OutStream_Releaser + { + CFilterCoder *FilterCoder; + C_OutStream_Releaser(): FilterCoder(NULL) {} + ~C_OutStream_Releaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); } + }; + + struct C_Filter_Releaser + { + CFilterCoder *FilterCoder; + C_Filter_Releaser(): FilterCoder(NULL) {} + ~C_Filter_Releaser() { if (FilterCoder) FilterCoder->Filter.Release(); } + }; + +private: + Z7_COM_QI_BEGIN2(ICompressCoder) + + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ICompressInitEncoder) + + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ISequentialInStream) + + Z7_COM_QI_ENTRY(ICompressSetOutStream) + Z7_COM_QI_ENTRY(ISequentialOutStream) + Z7_COM_QI_ENTRY(IOutStreamFinish) + + Z7_COM_QI_ENTRY(ICompressSetBufSize) + + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword) + Z7_COM_QI_ENTRY_AG(ICryptoProperties, Filter, _cryptoProperties) + #endif + + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY_AG(ICompressSetCoderProperties, Filter, _setCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties) + Z7_COM_QI_ENTRY_AG(ICompressSetCoderPropertiesOpt, Filter, _setCoderPropertiesOpt) + // Z7_COM_QI_ENTRY_AG(ICryptoResetSalt, Filter, _cryptoResetSalt) + Z7_COM_QI_ENTRY_AG(ICryptoResetInitVector, Filter, _cryptoResetInitVector) + #endif + + Z7_COM_QI_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties2) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + +public: + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressInitEncoder) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) +public: + Z7_IFACE_COM7_IMP(ICompressSetOutStream) +private: + Z7_IFACE_COM7_IMP(ISequentialOutStream) +public: + Z7_IFACE_COM7_IMP(IOutStreamFinish) +private: + + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoSetPassword) + Z7_IFACE_COM7_IMP(ICryptoProperties) + #endif + + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) + #endif + +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + + HRESULT Init_NoSubFilterInit(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/InBuffer.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.cpp --- p7zip-rar-16.02/CPP/7zip/Common/InBuffer.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.cpp 2023-12-24 13:00:00.000000000 +0000 @@ -1,135 +1,182 @@ -// InBuffer.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "InBuffer.h" - -CInBufferBase::CInBufferBase() throw(): - _buf(0), - _bufLim(0), - _bufBase(0), - _stream(0), - _processedSize(0), - _bufSize(0), - _wasFinished(false), - NumExtraBytes(0) -{} - -bool CInBuffer::Create(size_t bufSize) throw() -{ - const unsigned kMinBlockSize = 1; - if (bufSize < kMinBlockSize) - bufSize = kMinBlockSize; - if (_bufBase != 0 && _bufSize == bufSize) - return true; - Free(); - _bufSize = bufSize; - _bufBase = (Byte *)::MidAlloc(bufSize); - return (_bufBase != 0); -} - -void CInBuffer::Free() throw() -{ - ::MidFree(_bufBase); - _bufBase = 0; -} - -void CInBufferBase::Init() throw() -{ - _processedSize = 0; - _buf = _bufBase; - _bufLim = _buf; - _wasFinished = false; - #ifdef _NO_EXCEPTIONS - ErrorCode = S_OK; - #endif - NumExtraBytes = 0; -} - -bool CInBufferBase::ReadBlock() -{ - #ifdef _NO_EXCEPTIONS - if (ErrorCode != S_OK) - return false; - #endif - if (_wasFinished) - return false; - _processedSize += (_buf - _bufBase); - _buf = _bufBase; - _bufLim = _bufBase; - UInt32 processed; - // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) - HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); - #ifdef _NO_EXCEPTIONS - ErrorCode = result; - #else - if (result != S_OK) - throw CInBufferException(result); - #endif - _bufLim = _buf + processed; - _wasFinished = (processed == 0); - return !_wasFinished; -} - -bool CInBufferBase::ReadByte_FromNewBlock(Byte &b) -{ - if (!ReadBlock()) - { - NumExtraBytes++; - b = 0xFF; - return false; - } - b = *_buf++; - return true; -} - -Byte CInBufferBase::ReadByte_FromNewBlock() -{ - if (!ReadBlock()) - { - NumExtraBytes++; - return 0xFF; - } - return *_buf++; -} - -size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) -{ - if ((size_t)(_bufLim - _buf) >= size) - { - const Byte *src = _buf; - for (size_t i = 0; i < size; i++) - buf[i] = src[i]; - _buf += size; - return size; - } - for (size_t i = 0; i < size; i++) - { - if (_buf >= _bufLim) - if (!ReadBlock()) - return i; - buf[i] = *_buf++; - } - return size; -} - -size_t CInBufferBase::Skip(size_t size) -{ - size_t processed = 0; - for (;;) - { - size_t rem = (_bufLim - _buf); - if (rem >= size) - { - _buf += size; - return processed + size; - } - _buf += rem; - processed += rem; - size -= rem; - if (!ReadBlock()) - return processed; - } -} +// InBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "InBuffer.h" + +CInBufferBase::CInBufferBase() throw(): + _buf(NULL), + _bufLim(NULL), + _bufBase(NULL), + _stream(NULL), + _processedSize(0), + _bufSize(0), + _wasFinished(false), + NumExtraBytes(0) +{} + +bool CInBuffer::Create(size_t bufSize) throw() +{ + const unsigned kMinBlockSize = 1; + if (bufSize < kMinBlockSize) + bufSize = kMinBlockSize; + if (_bufBase != NULL && _bufSize == bufSize) + return true; + Free(); + _bufSize = bufSize; + _bufBase = (Byte *)::MidAlloc(bufSize); + return (_bufBase != NULL); +} + +void CInBuffer::Free() throw() +{ + ::MidFree(_bufBase); + _bufBase = NULL; +} + +void CInBufferBase::Init() throw() +{ + _processedSize = 0; + _buf = _bufBase; + _bufLim = _buf; + _wasFinished = false; + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = S_OK; + #endif + NumExtraBytes = 0; +} + +bool CInBufferBase::ReadBlock() +{ + #ifdef Z7_NO_EXCEPTIONS + if (ErrorCode != S_OK) + return false; + #endif + if (_wasFinished) + return false; + _processedSize += (size_t)(_buf - _bufBase); + _buf = _bufBase; + _bufLim = _bufBase; + UInt32 processed; + // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) + const HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw CInBufferException(result); + #endif + _bufLim = _buf + processed; + _wasFinished = (processed == 0); + return !_wasFinished; +} + +bool CInBufferBase::ReadByte_FromNewBlock(Byte &b) +{ + if (!ReadBlock()) + { + // 22.00: we don't increment (NumExtraBytes) here + // NumExtraBytes++; + b = 0xFF; + return false; + } + b = *_buf++; + return true; +} + +Byte CInBufferBase::ReadByte_FromNewBlock() +{ + if (!ReadBlock()) + { + NumExtraBytes++; + return 0xFF; + } + return *_buf++; +} + +size_t CInBufferBase::ReadBytesPart(Byte *buf, size_t size) +{ + if (size == 0) + return 0; + size_t rem = (size_t)(_bufLim - _buf); + if (rem == 0) + { + if (!ReadBlock()) + return 0; + rem = (size_t)(_bufLim - _buf); + } + if (size > rem) + size = rem; + memcpy(buf, _buf, size); + _buf += size; + return size; +} + +size_t CInBufferBase::ReadBytes(Byte *buf, size_t size) +{ + size_t num = 0; + for (;;) + { + const size_t rem = (size_t)(_bufLim - _buf); + if (size <= rem) + { + if (size != 0) + { + memcpy(buf, _buf, size); + _buf += size; + num += size; + } + return num; + } + if (rem != 0) + { + memcpy(buf, _buf, rem); + _buf += rem; + buf += rem; + num += rem; + size -= rem; + } + if (!ReadBlock()) + return num; + } + + /* + if ((size_t)(_bufLim - _buf) >= size) + { + const Byte *src = _buf; + for (size_t i = 0; i < size; i++) + buf[i] = src[i]; + _buf += size; + return size; + } + for (size_t i = 0; i < size; i++) + { + if (_buf >= _bufLim) + if (!ReadBlock()) + return i; + buf[i] = *_buf++; + } + return size; + */ +} + +size_t CInBufferBase::Skip(size_t size) +{ + size_t processed = 0; + for (;;) + { + const size_t rem = (size_t)(_bufLim - _buf); + if (rem >= size) + { + _buf += size; + return processed + size; + } + _buf += rem; + processed += rem; + size -= rem; + if (!ReadBlock()) + return processed; + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/InBuffer.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.h --- p7zip-rar-16.02/CPP/7zip/Common/InBuffer.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InBuffer.h 2025-02-20 08:00:00.000000000 +0000 @@ -1,90 +1,121 @@ -// InBuffer.h - -#ifndef __IN_BUFFER_H -#define __IN_BUFFER_H - -#include "../../Common/MyException.h" -#include "../IStream.h" - -#ifndef _NO_EXCEPTIONS -struct CInBufferException: public CSystemException -{ - CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} -}; -#endif - -class CInBufferBase -{ -protected: - Byte *_buf; - Byte *_bufLim; - Byte *_bufBase; - - ISequentialInStream *_stream; - UInt64 _processedSize; - size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger - // only up to 32-bits values now are supported! - bool _wasFinished; - - bool ReadBlock(); - bool ReadByte_FromNewBlock(Byte &b); - Byte ReadByte_FromNewBlock(); - -public: - #ifdef _NO_EXCEPTIONS - HRESULT ErrorCode; - #endif - UInt32 NumExtraBytes; - - CInBufferBase() throw(); - - UInt64 GetStreamSize() const { return _processedSize + (_buf - _bufBase); } - UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (_buf - _bufBase); } - bool WasFinished() const { return _wasFinished; } - - void SetStream(ISequentialInStream *stream) { _stream = stream; } - - void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos) - { - _bufBase = buf; - _bufSize = bufSize; - _processedSize = 0; - _buf = buf + pos; - _bufLim = buf + end; - _wasFinished = false; - #ifdef _NO_EXCEPTIONS - ErrorCode = S_OK; - #endif - NumExtraBytes = 0; - } - - void Init() throw(); - - bool ReadByte(Byte &b) - { - if (_buf >= _bufLim) - return ReadByte_FromNewBlock(b); - b = *_buf++; - return true; - } - - Byte ReadByte() - { - if (_buf >= _bufLim) - return ReadByte_FromNewBlock(); - return *_buf++; - } - - size_t ReadBytes(Byte *buf, size_t size); - size_t Skip(size_t size); -}; - -class CInBuffer: public CInBufferBase -{ -public: - ~CInBuffer() { Free(); } - bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported! - void Free() throw(); -}; - -#endif +// InBuffer.h + +#ifndef ZIP7_INC_IN_BUFFER_H +#define ZIP7_INC_IN_BUFFER_H + +#include "../../Common/MyException.h" +#include "../IStream.h" + +#ifndef Z7_NO_EXCEPTIONS +struct CInBufferException: public CSystemException +{ + CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class CInBufferBase +{ +protected: + Byte *_buf; + Byte *_bufLim; + Byte *_bufBase; + + ISequentialInStream *_stream; + UInt64 _processedSize; + size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger + // only up to 32-bits values now are supported! + bool _wasFinished; + + bool ReadBlock(); + bool ReadByte_FromNewBlock(Byte &b); + Byte ReadByte_FromNewBlock(); + +public: + #ifdef Z7_NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + UInt32 NumExtraBytes; + + CInBufferBase() throw(); + + // the size of portion of data in real stream that was already read from this object + // it doesn't include unused data in buffer + // it doesn't include virtual Extra bytes after the end of real stream data + UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); } + + // the size of virtual data that was read from this object + // it doesn't include unused data in buffers + // it includes any virtual Extra bytes after the end of real data + UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); } + + bool WasFinished() const { return _wasFinished; } + + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void ClearStreamPtr() { _stream = NULL; } + + void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos) + { + _bufBase = buf; + _bufSize = bufSize; + _processedSize = 0; + _buf = buf + pos; + _bufLim = buf + end; + _wasFinished = false; + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = S_OK; + #endif + NumExtraBytes = 0; + } + + void Init() throw(); + + Z7_FORCE_INLINE + bool ReadByte(Byte &b) + { + if (_buf >= _bufLim) + return ReadByte_FromNewBlock(b); + b = *_buf++; + return true; + } + + Z7_FORCE_INLINE + bool ReadByte_FromBuf(Byte &b) + { + if (_buf >= _bufLim) + return false; + b = *_buf++; + return true; + } + + Z7_FORCE_INLINE + Byte ReadByte() + { + if (_buf >= _bufLim) + return ReadByte_FromNewBlock(); + return *_buf++; + } + + size_t ReadBytesPart(Byte *buf, size_t size); + size_t ReadBytes(Byte *buf, size_t size); + const Byte *Lookahead(size_t &rem) + { + rem = (size_t)(_bufLim - _buf); + if (!rem) + { + ReadBlock(); + rem = (size_t)(_bufLim - _buf); + } + return _buf; + } + size_t Skip(size_t size); +}; + +class CInBuffer: public CInBufferBase +{ +public: + ~CInBuffer() { Free(); } + bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported! + void Free() throw(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/InOutTempBuffer.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.cpp --- p7zip-rar-16.02/CPP/7zip/Common/InOutTempBuffer.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.cpp 2022-12-19 22:00:00.000000000 +0000 @@ -1,127 +1,237 @@ -// InOutTempBuffer.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" - -#include "../../Common/Defs.h" - -#include "InOutTempBuffer.h" -#include "StreamUtils.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static const size_t kTempBufSize = (1 << 20); - -static CFSTR kTempFilePrefixString = FTEXT("7zt"); - -CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { } - -void CInOutTempBuffer::Create() -{ - if (!_buf) - _buf = new Byte[kTempBufSize]; -} - -CInOutTempBuffer::~CInOutTempBuffer() -{ - delete []_buf; -} - -void CInOutTempBuffer::InitWriting() -{ - _bufPos = 0; - _tempFileCreated = false; - _size = 0; - _crc = CRC_INIT_VAL; -} - -bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size) -{ - if (size == 0) - return true; - if (!_tempFileCreated) - { - if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) - return false; - _tempFileCreated = true; - } - UInt32 processed; - if (!_outFile.Write(data, size, processed)) - return false; - _crc = CrcUpdate(_crc, data, processed); - _size += processed; - return (processed == size); -} - -bool CInOutTempBuffer::Write(const void *data, UInt32 size) -{ - if (size == 0) - return true; - size_t cur = kTempBufSize - _bufPos; - if (cur != 0) - { - if (cur > size) - cur = size; - memcpy(_buf + _bufPos, data, cur); - _crc = CrcUpdate(_crc, data, cur); - _bufPos += cur; - _size += cur; - size -= (UInt32)cur; - data = ((const Byte *)data) + cur; - } - return WriteToFile(data, size); -} - -HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) -{ - if (!_outFile.Close()) - return E_FAIL; - - UInt64 size = 0; - UInt32 crc = CRC_INIT_VAL; - - if (_bufPos != 0) - { - RINOK(WriteStream(stream, _buf, _bufPos)); - crc = CrcUpdate(crc, _buf, _bufPos); - size += _bufPos; - } - - if (_tempFileCreated) - { - NIO::CInFile inFile; - if (!inFile.Open(_tempFile.GetPath())) - return E_FAIL; - while (size < _size) - { - UInt32 processed; - if (!inFile.ReadPart(_buf, kTempBufSize, processed)) - return E_FAIL; - if (processed == 0) - break; - RINOK(WriteStream(stream, _buf, processed)); - crc = CrcUpdate(crc, _buf, processed); - size += processed; - } - } - - return (_crc == crc && size == _size) ? S_OK : E_FAIL; -} - -/* -STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed) -{ - if (!_buf->Write(data, size)) - { - if (processed) - *processed = 0; - return E_FAIL; - } - if (processed) - *processed = size; - return S_OK; -} -*/ +// InOutTempBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "InOutTempBuffer.h" + +#include "StreamUtils.h" + +#ifdef USE_InOutTempBuffer_FILE + +#include "../../../C/7zCrc.h" + +#define kTempFilePrefixString FTEXT("7zt") +/* + Total buffer size limit, if we use temp file scheme: + 32-bit: 16 MiB = 1 MiB * 16 buffers + 64-bit: 4 GiB = 1 MiB * 4096 buffers +*/ +static const size_t kNumBufsMax = (size_t)1 << (sizeof(size_t) * 2 - 4); + +#endif + +static const size_t kBufSize = (size_t)1 << 20; + + +CInOutTempBuffer::CInOutTempBuffer(): + _size(0), + _bufs(NULL), + _numBufs(0), + _numFilled(0) +{ + #ifdef USE_InOutTempBuffer_FILE + _tempFile_Created = false; + _useMemOnly = false; + _crc = CRC_INIT_VAL; + #endif +} + +CInOutTempBuffer::~CInOutTempBuffer() +{ + for (size_t i = 0; i < _numBufs; i++) + MyFree(_bufs[i]); + MyFree(_bufs); +} + + +void *CInOutTempBuffer::GetBuf(size_t index) +{ + if (index >= _numBufs) + { + const size_t num = (_numBufs == 0 ? 16 : _numBufs * 2); + void **p = (void **)MyRealloc(_bufs, num * sizeof(void *)); + if (!p) + return NULL; + _bufs = p; + memset(p + _numBufs, 0, (num - _numBufs) * sizeof(void *)); + _numBufs = num; + } + + void *buf = _bufs[index]; + if (!buf) + { + buf = MyAlloc(kBufSize); + if (buf) + _bufs[index] = buf; + } + return buf; +} + + +HRESULT CInOutTempBuffer::Write_HRESULT(const void *data, UInt32 size) +{ + if (size == 0) + return S_OK; + + #ifdef USE_InOutTempBuffer_FILE + if (!_tempFile_Created) + #endif + for (;;) // loop for additional attemp to allocate memory after file creation error + { + #ifdef USE_InOutTempBuffer_FILE + bool allocError = false; + #endif + + for (;;) // loop for writing to buffers + { + const size_t index = (size_t)(_size / kBufSize); + + #ifdef USE_InOutTempBuffer_FILE + if (index >= kNumBufsMax && !_useMemOnly) + break; + #endif + + void *buf = GetBuf(index); + if (!buf) + { + #ifdef USE_InOutTempBuffer_FILE + if (!_useMemOnly) + { + allocError = true; + break; + } + #endif + return E_OUTOFMEMORY; + } + + const size_t offset = (size_t)(_size) & (kBufSize - 1); + size_t cur = kBufSize - offset; + if (cur > size) + cur = size; + memcpy((Byte *)buf + offset, data, cur); + _size += cur; + if (index >= _numFilled) + _numFilled = index + 1; + data = (const void *)((const Byte *)data + cur); + size -= (UInt32)cur; + if (size == 0) + return S_OK; + } + + #ifdef USE_InOutTempBuffer_FILE + #ifndef _WIN32 + _outFile.mode_for_Create = 0600; // only owner will have the rights to access this file + #endif + if (_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile)) + { + _tempFile_Created = true; + break; + } + _useMemOnly = true; + if (allocError) + return GetLastError_noZero_HRESULT(); + #endif + } + + #ifdef USE_InOutTempBuffer_FILE + if (!_outFile.WriteFull(data, size)) + return GetLastError_noZero_HRESULT(); + _crc = CrcUpdate(_crc, data, size); + _size += size; + return S_OK; + #endif +} + + +HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) +{ + UInt64 rem = _size; + // if (rem == 0) return S_OK; + + const size_t numFilled = _numFilled; + _numFilled = 0; + + for (size_t i = 0; i < numFilled; i++) + { + if (rem == 0) + return E_FAIL; + size_t cur = kBufSize; + if (cur > rem) + cur = (size_t)rem; + RINOK(WriteStream(stream, _bufs[i], cur)) + rem -= cur; + #ifdef USE_InOutTempBuffer_FILE + // we will use _bufs[0] later for writing from temp file + if (i != 0 || !_tempFile_Created) + #endif + { + MyFree(_bufs[i]); + _bufs[i] = NULL; + } + } + + + #ifdef USE_InOutTempBuffer_FILE + + if (rem == 0) + return _tempFile_Created ? E_FAIL : S_OK; + + if (!_tempFile_Created) + return E_FAIL; + + if (!_outFile.Close()) + return GetLastError_noZero_HRESULT(); + + HRESULT hres; + void *buf = GetBuf(0); // index + if (!buf) + hres = E_OUTOFMEMORY; + else + { + NWindows::NFile::NIO::CInFile inFile; + if (!inFile.Open(_tempFile.GetPath())) + hres = GetLastError_noZero_HRESULT(); + else + { + UInt32 crc = CRC_INIT_VAL; + for (;;) + { + size_t processed; + if (!inFile.ReadFull(buf, kBufSize, processed)) + { + hres = GetLastError_noZero_HRESULT(); + break; + } + if (processed == 0) + { + // we compare crc without CRC_GET_DIGEST + hres = (_crc == crc ? S_OK : E_FAIL); + break; + } + size_t n = processed; + if (n > rem) + n = (size_t)rem; + hres = WriteStream(stream, buf, n); + if (hres != S_OK) + break; + crc = CrcUpdate(crc, buf, n); + rem -= n; + if (n != processed) + { + hres = E_FAIL; + break; + } + } + } + } + + // _tempFile.DisableDeleting(); // for debug + _tempFile.Remove(); + RINOK(hres) + + #endif + + return rem == 0 ? S_OK : E_FAIL; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/InOutTempBuffer.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.h --- p7zip-rar-16.02/CPP/7zip/Common/InOutTempBuffer.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/InOutTempBuffer.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,48 +1,45 @@ -// InOutTempBuffer.h - -#ifndef __IN_OUT_TEMP_BUFFER_H -#define __IN_OUT_TEMP_BUFFER_H - -#include "../../Common/MyCom.h" -#include "../../Windows/FileDir.h" - -#include "../IStream.h" - -class CInOutTempBuffer -{ - NWindows::NFile::NDir::CTempFile _tempFile; - NWindows::NFile::NIO::COutFile _outFile; - Byte *_buf; - size_t _bufPos; - UInt64 _size; - UInt32 _crc; - bool _tempFileCreated; - - bool WriteToFile(const void *data, UInt32 size); -public: - CInOutTempBuffer(); - ~CInOutTempBuffer(); - void Create(); - - void InitWriting(); - bool Write(const void *data, UInt32 size); - - HRESULT WriteToStream(ISequentialOutStream *stream); - UInt64 GetDataSize() const { return _size; } -}; - -/* -class CSequentialOutTempBufferImp: - public ISequentialOutStream, - public CMyUnknownImp -{ - CInOutTempBuffer *_buf; -public: - void Init(CInOutTempBuffer *buffer) { _buf = buffer; } - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; -*/ - -#endif +// InOutTempBuffer.h + +#ifndef ZIP7_INC_IN_OUT_TEMP_BUFFER_H +#define ZIP7_INC_IN_OUT_TEMP_BUFFER_H + +// #ifdef _WIN32 +#define USE_InOutTempBuffer_FILE +// #endif + +#ifdef USE_InOutTempBuffer_FILE +#include "../../Windows/FileDir.h" +#endif + +#include "../IStream.h" + +class CInOutTempBuffer +{ + UInt64 _size; + void **_bufs; + size_t _numBufs; + size_t _numFilled; + + #ifdef USE_InOutTempBuffer_FILE + + bool _tempFile_Created; + bool _useMemOnly; + UInt32 _crc; + // COutFile object must be declared after CTempFile object for correct destructor order + NWindows::NFile::NDir::CTempFile _tempFile; + NWindows::NFile::NIO::COutFile _outFile; + + #endif + + void *GetBuf(size_t index); + + Z7_CLASS_NO_COPY(CInOutTempBuffer) +public: + CInOutTempBuffer(); + ~CInOutTempBuffer(); + HRESULT Write_HRESULT(const void *data, UInt32 size); + HRESULT WriteToStream(ISequentialOutStream *stream); + UInt64 GetDataSize() const { return _size; } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/LimitedStreams.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.cpp --- p7zip-rar-16.02/CPP/7zip/Common/LimitedStreams.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -1,367 +1,393 @@ -// LimitedStreams.cpp - -#include "StdAfx.h" - -#include - -#include "LimitedStreams.h" - -STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize = 0; - { - const UInt64 rem = _size - _pos; - if (size > rem) - size = (UInt32)rem; - } - HRESULT result = S_OK; - if (size != 0) - { - result = _stream->Read(data, size, &realProcessedSize); - _pos += realProcessedSize; - if (realProcessedSize == 0) - _wasFinished = true; - } - if (processedSize) - *processedSize = realProcessedSize; - return result; -} - -STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= _size) - { - // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. - return S_OK; - // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF - } - { - const UInt64 rem = _size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - UInt64 newPos = _startOffset + _virtPos; - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - HRESULT res = _stream->Read(data, size, &size); - if (processedSize) - *processedSize = size; - _physPos += size; - _virtPos += size; - return res; -} - -STDMETHODIMP CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += _size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return S_OK; -} - -HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream) -{ - *resStream = 0; - CLimitedInStream *streamSpec = new CLimitedInStream; - CMyComPtr streamTemp = streamSpec; - streamSpec->SetStream(inStream); - RINOK(streamSpec->InitAndSeek(pos, size)); - streamSpec->SeekToStart(); - *resStream = streamTemp.Detach(); - return S_OK; -} - -STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Size) - return S_OK; - { - UInt64 rem = Size - _virtPos; - if (size > rem) - size = (UInt32)rem; - } - if (size == 0) - return S_OK; - - if (_curRem == 0) - { - const UInt32 blockSize = (UInt32)1 << BlockSizeLog; - const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog); - const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); - const UInt32 phyBlock = Vector[virtBlock]; - - UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock; - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - - _curRem = blockSize - offsetInBlock; - - for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) - _curRem += (UInt32)1 << BlockSizeLog; - } - - if (size > _curRem) - size = _curRem; - HRESULT res = Stream->Read(data, size, &size); - if (processedSize) - *processedSize = size; - _physPos += size; - _virtPos += size; - _curRem -= size; - return res; -} - -STDMETHODIMP CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - if (_virtPos != (UInt64)offset) - _curRem = 0; - _virtPos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - - -STDMETHODIMP CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= Extents.Back().Virt) - return S_OK; - if (size == 0) - return S_OK; - - unsigned left = 0, right = Extents.Size() - 1; - for (;;) - { - unsigned mid = (left + right) / 2; - if (mid == left) - break; - if (_virtPos < Extents[mid].Virt) - right = mid; - else - left = mid; - } - - const CSeekExtent &extent = Extents[left]; - UInt64 phyPos = extent.Phy + (_virtPos - extent.Virt); - if (_needStartSeek || _phyPos != phyPos) - { - _needStartSeek = false; - _phyPos = phyPos; - RINOK(SeekToPhys()); - } - - UInt64 rem = Extents[left + 1].Virt - _virtPos; - if (size > rem) - size = (UInt32)rem; - - HRESULT res = Stream->Read(data, size, &size); - _phyPos += size; - _virtPos += size; - if (processedSize) - *processedSize = size; - return res; -} - -STDMETHODIMP CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += Extents.Back().Virt; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return S_OK; -} - - -STDMETHODIMP CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (processedSize) - *processedSize = 0; - if (size > _size) - { - if (_size == 0) - { - _overflow = true; - if (!_overflowIsAllowed) - return E_FAIL; - if (processedSize) - *processedSize = size; - return S_OK; - } - size = (UInt32)_size; - } - if (_stream) - result = _stream->Write(data, size, &size); - _size -= size; - if (processedSize) - *processedSize = size; - return result; -} - - -STDMETHODIMP CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 cur; - HRESULT res = Stream->Read(data, size, &cur); - if (processedSize) - *processedSize = cur; - _virtPos += cur; - return res; -} - -STDMETHODIMP CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: - { - UInt64 pos = 0; - RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)); - if (pos < Offset) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = pos - Offset; - if (newPosition) - *newPosition = _virtPos; - return S_OK; - } - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); -} - -STDMETHODIMP CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (_virtPos >= _size) - { - // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. - return S_OK; - // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF - } - UInt64 rem = _size - _virtPos; - if (rem < size) - size = (UInt32)rem; - - UInt64 newPos = _startOffset + _virtPos; - UInt64 offsetInCache = newPos - _cachePhyPos; - HRESULT res = S_OK; - if (newPos >= _cachePhyPos && - offsetInCache <= _cacheSize && - size <= _cacheSize - (size_t)offsetInCache) - { - if (size != 0) - memcpy(data, _cache + (size_t)offsetInCache, size); - } - else - { - if (newPos != _physPos) - { - _physPos = newPos; - RINOK(SeekToPhys()); - } - res = _stream->Read(data, size, &size); - _physPos += size; - } - if (processedSize) - *processedSize = size; - _virtPos += size; - return res; -} - -STDMETHODIMP CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += _size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return S_OK; -} - -STDMETHODIMP CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 cur; - HRESULT res = Stream->Write(data, size, &cur); - if (processedSize) - *processedSize = cur; - _virtPos += cur; - if (_virtSize < _virtPos) - _virtSize = _virtPos; - return res; -} - -STDMETHODIMP CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _virtPos; break; - case STREAM_SEEK_END: offset += _virtSize; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _virtPos = offset; - if (newPosition) - *newPosition = _virtPos; - return Stream->Seek(Offset + _virtPos, STREAM_SEEK_SET, NULL); -} - -STDMETHODIMP CTailOutStream::SetSize(UInt64 newSize) -{ - _virtSize = newSize; - return Stream->SetSize(Offset + newSize); -} +// LimitedStreams.cpp + +#include "StdAfx.h" + +#include + +#include "LimitedStreams.h" + +Z7_COM7F_IMF(CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize = 0; + { + const UInt64 rem = _size - _pos; + if (size > rem) + size = (UInt32)rem; + } + HRESULT result = S_OK; + if (size != 0) + { + result = _stream->Read(data, size, &realProcessedSize); + _pos += realProcessedSize; + if (realProcessedSize == 0) + _wasFinished = true; + } + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +Z7_COM7F_IMF(CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= _size) + { + // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. + return S_OK; + // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF + } + { + const UInt64 rem = _size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + UInt64 newPos = _startOffset + _virtPos; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + HRESULT res = _stream->Read(data, size, &size); + if (processedSize) + *processedSize = size; + _physPos += size; + _virtPos += size; + return res; +} + +Z7_COM7F_IMF(CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return S_OK; +} + +HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream) +{ + *resStream = NULL; + CLimitedInStream *streamSpec = new CLimitedInStream; + CMyComPtr streamTemp = streamSpec; + streamSpec->SetStream(inStream); + RINOK(streamSpec->InitAndSeek(pos, size)) + streamSpec->SeekToStart(); + *resStream = streamTemp.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= Size) + return S_OK; + { + UInt64 rem = Size - _virtPos; + if (size > rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + if (_curRem == 0) + { + const UInt32 blockSize = (UInt32)1 << BlockSizeLog; + const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog); + const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1); + const UInt32 phyBlock = Vector[virtBlock]; + + UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock; + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + + _curRem = blockSize - offsetInBlock; + + for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++) + _curRem += (UInt32)1 << BlockSizeLog; + } + + if (size > _curRem) + size = _curRem; + HRESULT res = Stream->Read(data, size, &size); + if (processedSize) + *processedSize = size; + _physPos += size; + _virtPos += size; + _curRem -= size; + return res; +} + +Z7_COM7F_IMF(CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (_virtPos != (UInt64)offset) + _curRem = 0; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +Z7_COM7F_IMF(CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + const UInt64 virt = _virtPos; + if (virt >= Extents.Back().Virt) + return S_OK; + if (size == 0) + return S_OK; + + unsigned left = _prevExtentIndex; + if (virt < Extents[left].Virt || + virt >= Extents[left + 1].Virt) + { + 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 UInt64 rem = Extents[left + 1].Virt - virt; + if (size > rem) + size = (UInt32)rem; + } + + const CSeekExtent &extent = Extents[left]; + + if (extent.Is_ZeroFill()) + { + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + { + const UInt64 phy = extent.Phy + (virt - extent.Virt); + if (_phyPos != phy) + { + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error + RINOK(InStream_SeekSet(Stream, phy)) + _phyPos = phy; + } + } + + const HRESULT res = Stream->Read(data, size, &size); + _virtPos += size; + if (res == S_OK) + _phyPos += size; + else + _phyPos = (UInt64)0 - 1; // we don't trust seek_pos in case of error + if (processedSize) + *processedSize = size; + return res; +} + + +Z7_COM7F_IMF(CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += Extents.Back().Virt; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return S_OK; +} + + +Z7_COM7F_IMF(CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (processedSize) + *processedSize = 0; + if (size > _size) + { + if (_size == 0) + { + _overflow = true; + if (!_overflowIsAllowed) + return E_FAIL; + if (processedSize) + *processedSize = size; + return S_OK; + } + size = (UInt32)_size; + } + if (_stream) + result = _stream->Write(data, size, &size); + _size -= size; + if (processedSize) + *processedSize = size; + return result; +} + + +Z7_COM7F_IMF(CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 cur; + HRESULT res = Stream->Read(data, size, &cur); + if (processedSize) + *processedSize = cur; + _virtPos += cur; + return res; +} + +Z7_COM7F_IMF(CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: + { + UInt64 pos = 0; + RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos)) + if (pos < Offset) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = pos - Offset; + if (newPosition) + *newPosition = _virtPos; + return S_OK; + } + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return InStream_SeekSet(Stream, Offset + _virtPos); +} + +Z7_COM7F_IMF(CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= _size) + { + // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case. + return S_OK; + // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF + } + UInt64 rem = _size - _virtPos; + if (rem < size) + size = (UInt32)rem; + + UInt64 newPos = _startOffset + _virtPos; + UInt64 offsetInCache = newPos - _cachePhyPos; + HRESULT res = S_OK; + if (newPos >= _cachePhyPos && + offsetInCache <= _cacheSize && + size <= _cacheSize - (size_t)offsetInCache) + { + if (size != 0) + memcpy(data, _cache + (size_t)offsetInCache, size); + } + else + { + if (newPos != _physPos) + { + _physPos = newPos; + RINOK(SeekToPhys()) + } + res = _stream->Read(data, size, &size); + _physPos += size; + } + if (processedSize) + *processedSize = size; + _virtPos += size; + return res; +} + +Z7_COM7F_IMF(CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return S_OK; +} + +Z7_COM7F_IMF(CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 cur; + HRESULT res = Stream->Write(data, size, &cur); + if (processedSize) + *processedSize = cur; + _virtPos += cur; + if (_virtSize < _virtPos) + _virtSize = _virtPos; + return res; +} + +Z7_COM7F_IMF(CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _virtSize; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = (UInt64)offset; + if (newPosition) + *newPosition = _virtPos; + return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL); +} + +Z7_COM7F_IMF(CTailOutStream::SetSize(UInt64 newSize)) +{ + _virtSize = newSize; + return Stream->SetSize(Offset + newSize); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/LimitedStreams.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.h --- p7zip-rar-16.02/CPP/7zip/Common/LimitedStreams.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LimitedStreams.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,252 +1,221 @@ -// LimitedStreams.h - -#ifndef __LIMITED_STREAMS_H -#define __LIMITED_STREAMS_H - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyVector.h" -#include "../IStream.h" - -class CLimitedSequentialInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - UInt64 _pos; - bool _wasFinished; -public: - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(UInt64 streamSize) - { - _size = streamSize; - _pos = 0; - _wasFinished = false; - } - - MY_UNKNOWN_IMP1(ISequentialInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - UInt64 GetSize() const { return _pos; } - UInt64 GetRem() const { return _size - _pos; } - bool WasFinished() const { return _wasFinished; } -}; - -class CLimitedInStream: - public IInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _virtPos; - UInt64 _physPos; - UInt64 _size; - UInt64 _startOffset; - - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } -public: - void SetStream(IInStream *stream) { _stream = stream; } - HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) - { - _startOffset = startOffset; - _physPos = startOffset; - _virtPos = 0; - _size = size; - return SeekToPhys(); - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } -}; - -HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); - -class CClusterInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - UInt64 _physPos; - UInt32 _curRem; -public: - unsigned BlockSizeLog; - UInt64 Size; - CMyComPtr Stream; - CRecordVector Vector; - UInt64 StartOffset; - - HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } - - HRESULT InitAndSeek() - { - _curRem = 0; - _virtPos = 0; - _physPos = StartOffset; - if (Vector.Size() > 0) - { - _physPos = StartOffset + (Vector[0] << BlockSizeLog); - return SeekToPhys(); - } - return S_OK; - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -struct CSeekExtent -{ - UInt64 Phy; - UInt64 Virt; -}; - -class CExtentsStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _phyPos; - UInt64 _virtPos; - bool _needStartSeek; - - HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); } - -public: - CMyComPtr Stream; - CRecordVector Extents; - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - void ReleaseStream() { Stream.Release(); } - - void Init() - { - _virtPos = 0; - _phyPos = 0; - _needStartSeek = true; - } -}; - -class CLimitedSequentialOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - bool _overflow; - bool _overflowIsAllowed; -public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(UInt64 size, bool overflowIsAllowed = false) - { - _size = size; - _overflow = false; - _overflowIsAllowed = overflowIsAllowed; - } - bool IsFinishedOK() const { return (_size == 0 && !_overflow); } - UInt64 GetRem() const { return _size; } -}; - - -class CTailInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _virtPos; -public: - CMyComPtr Stream; - UInt64 Offset; - - void Init() - { - _virtPos = 0; - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); } -}; - -class CLimitedCachedInStream: - public IInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _virtPos; - UInt64 _physPos; - UInt64 _size; - UInt64 _startOffset; - - const Byte *_cache; - size_t _cacheSize; - size_t _cachePhyPos; - - - HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } -public: - CByteBuffer Buffer; - - void SetStream(IInStream *stream) { _stream = stream; } - void SetCache(size_t cacheSize, size_t cachePos) - { - _cache = Buffer; - _cacheSize = cacheSize; - _cachePhyPos = cachePos; - } - - HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) - { - _startOffset = startOffset; - _physPos = startOffset; - _virtPos = 0; - _size = size; - return SeekToPhys(); - } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - - HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } -}; - -class CTailOutStream: - public IOutStream, - public CMyUnknownImp -{ - UInt64 _virtPos; - UInt64 _virtSize; -public: - CMyComPtr Stream; - UInt64 Offset; - - virtual ~CTailOutStream() {} - - MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) - - void Init() - { - _virtPos = 0; - _virtSize = 0; - } - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); -}; - -#endif +// LimitedStreams.h + +#ifndef ZIP7_INC_LIMITED_STREAMS_H +#define ZIP7_INC_LIMITED_STREAMS_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" +#include "../IStream.h" + +#include "StreamUtils.h" + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialInStream + , ISequentialInStream +) + CMyComPtr _stream; + UInt64 _size; + UInt64 _pos; + bool _wasFinished; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(UInt64 streamSize) + { + _size = streamSize; + _pos = 0; + _wasFinished = false; + } + UInt64 GetSize() const { return _pos; } + UInt64 GetRem() const { return _size - _pos; } + bool WasFinished() const { return _wasFinished; } +}; + + +Z7_CLASS_IMP_IInStream( + CLimitedInStream +) + CMyComPtr _stream; + UInt64 _virtPos; + UInt64 _physPos; + UInt64 _size; + UInt64 _startOffset; + + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } +public: + void SetStream(IInStream *stream) { _stream = stream; } + HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) + { + _startOffset = startOffset; + _physPos = startOffset; + _virtPos = 0; + _size = size; + return SeekToPhys(); + } + HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } +}; + +HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); + + +Z7_CLASS_IMP_IInStream( + CClusterInStream +) + UInt64 _virtPos; + UInt64 _physPos; + UInt32 _curRem; +public: + unsigned BlockSizeLog; + UInt64 Size; + CMyComPtr Stream; + CRecordVector Vector; + UInt64 StartOffset; + + HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); } + + HRESULT InitAndSeek() + { + _curRem = 0; + _virtPos = 0; + _physPos = StartOffset; + if (Vector.Size() > 0) + { + _physPos = StartOffset + (Vector[0] << BlockSizeLog); + return SeekToPhys(); + } + return S_OK; + } +}; + + + +const UInt64 k_SeekExtent_Phy_Type_ZeroFill = (UInt64)(Int64)-1; + +struct CSeekExtent +{ + UInt64 Virt; + UInt64 Phy; + + void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; } + bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; } +}; + + +Z7_CLASS_IMP_IInStream( + CExtentsStream +) + UInt64 _virtPos; + UInt64 _phyPos; + unsigned _prevExtentIndex; +public: + CMyComPtr Stream; + CRecordVector Extents; + + void ReleaseStream() { Stream.Release(); } + void Init() + { + _virtPos = 0; + _phyPos = (UInt64)0 - 1; // we need Seek() for Stream + _prevExtentIndex = 0; + } +}; + + + +Z7_CLASS_IMP_COM_1( + CLimitedSequentialOutStream + , ISequentialOutStream +) + CMyComPtr _stream; + UInt64 _size; + bool _overflow; + bool _overflowIsAllowed; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(UInt64 size, bool overflowIsAllowed = false) + { + _size = size; + _overflow = false; + _overflowIsAllowed = overflowIsAllowed; + } + bool IsFinishedOK() const { return (_size == 0 && !_overflow); } + UInt64 GetRem() const { return _size; } +}; + + +Z7_CLASS_IMP_IInStream( + CTailInStream +) + UInt64 _virtPos; +public: + CMyComPtr Stream; + UInt64 Offset; + + void Init() + { + _virtPos = 0; + } + HRESULT SeekToStart() { return InStream_SeekSet(Stream, Offset); } +}; + + +Z7_CLASS_IMP_IInStream( + CLimitedCachedInStream +) + CMyComPtr _stream; + UInt64 _virtPos; + UInt64 _physPos; + UInt64 _size; + UInt64 _startOffset; + + const Byte *_cache; + size_t _cacheSize; + size_t _cachePhyPos; + + HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); } +public: + CByteBuffer Buffer; + + void SetStream(IInStream *stream) { _stream = stream; } + void SetCache(size_t cacheSize, size_t cachePos) + { + _cache = Buffer; + _cacheSize = cacheSize; + _cachePhyPos = cachePos; + } + + HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) + { + _startOffset = startOffset; + _physPos = startOffset; + _virtPos = 0; + _size = size; + return SeekToPhys(); + } + + HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } +}; + + +class CTailOutStream Z7_final : + public IOutStream, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(ISequentialOutStream, IOutStream) + + UInt64 _virtPos; + UInt64 _virtSize; +public: + CMyComPtr Stream; + UInt64 Offset; + + void Init() + { + _virtPos = 0; + _virtSize = 0; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/LockedStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.cpp --- p7zip-rar-16.02/CPP/7zip/Common/LockedStream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.cpp 2015-02-18 15:15:32.000000000 +0000 @@ -0,0 +1,3 @@ +// LockedStream.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Common/LockedStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.h --- p7zip-rar-16.02/CPP/7zip/Common/LockedStream.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/LockedStream.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// LockedStream.h + +#ifndef ZIP7_INC_LOCKED_STREAM_H +#define ZIP7_INC_LOCKED_STREAM_H + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MemBlocks.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.cpp --- p7zip-rar-16.02/CPP/7zip/Common/MemBlocks.cpp 2015-10-03 09:39:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.cpp 2023-09-07 16:00:00.000000000 +0000 @@ -1,183 +1,215 @@ -// MemBlocks.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "MemBlocks.h" -#include "StreamUtils.h" - -bool CMemBlockManager::AllocateSpace(size_t numBlocks) -{ - FreeSpace(); - if (_blockSize < sizeof(void *) || numBlocks < 1) - return false; - size_t totalSize = numBlocks * _blockSize; - if (totalSize / _blockSize != numBlocks) - return false; - _data = ::MidAlloc(totalSize); - if (_data == 0) - return false; - Byte *p = (Byte *)_data; - for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize) - *(Byte **)p = (p + _blockSize); - *(Byte **)p = 0; - _headFree = _data; - return true; -} - -void CMemBlockManager::FreeSpace() -{ - ::MidFree(_data); - _data = 0; - _headFree= 0; -} - -void *CMemBlockManager::AllocateBlock() -{ - if (_headFree == 0) - return 0; - void *p = _headFree; - _headFree = *(void **)_headFree; - return p; -} - -void CMemBlockManager::FreeBlock(void *p) -{ - if (p == 0) - return; - *(void **)p = _headFree; - _headFree = p; -} - - -HRes CMemBlockManagerMt::AllocateSpace(NWindows::NSynchronization::CSynchro *sync ,size_t numBlocks, size_t numNoLockBlocks) -{ - if (numNoLockBlocks > numBlocks) - return E_INVALIDARG; - if (!CMemBlockManager::AllocateSpace(numBlocks)) - return E_OUTOFMEMORY; - size_t numLockBlocks = numBlocks - numNoLockBlocks; - Semaphore.Close(); - return Semaphore.Create(sync,(LONG)numLockBlocks, (LONG)numLockBlocks); -} - -HRes CMemBlockManagerMt::AllocateSpaceAlways(NWindows::NSynchronization::CSynchro *sync, size_t desiredNumberOfBlocks, size_t numNoLockBlocks) -{ - if (numNoLockBlocks > desiredNumberOfBlocks) - return E_INVALIDARG; - for (;;) - { - if (AllocateSpace(sync,desiredNumberOfBlocks, numNoLockBlocks) == 0) - return 0; - if (desiredNumberOfBlocks == numNoLockBlocks) - return E_OUTOFMEMORY; - desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1); - } -} - -void CMemBlockManagerMt::FreeSpace() -{ - Semaphore.Close(); - CMemBlockManager::FreeSpace(); -} - -void *CMemBlockManagerMt::AllocateBlock() -{ - // Semaphore.Lock(); - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - return CMemBlockManager::AllocateBlock(); -} - -void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode) -{ - if (p == 0) - return; - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - CMemBlockManager::FreeBlock(p); - } - if (lockMode) - Semaphore.Release(); -} - -void CMemBlocks::Free(CMemBlockManagerMt *manager) -{ - while (Blocks.Size() > 0) - { - manager->FreeBlock(Blocks.Back()); - Blocks.DeleteBack(); - } - TotalSize = 0; -} - -void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager) -{ - Free(manager); - Blocks.ClearAndFree(); -} - -HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const -{ - UInt64 totalSize = TotalSize; - for (unsigned blockIndex = 0; totalSize > 0; blockIndex++) - { - UInt32 curSize = (UInt32)blockSize; - if (totalSize < curSize) - curSize = (UInt32)totalSize; - if (blockIndex >= Blocks.Size()) - return E_FAIL; - RINOK(WriteStream(outStream, Blocks[blockIndex], curSize)); - totalSize -= curSize; - } - return S_OK; -} - - -void CMemLockBlocks::FreeBlock(int index, CMemBlockManagerMt *memManager) -{ - memManager->FreeBlock(Blocks[index], LockMode); - Blocks[index] = 0; -} - -void CMemLockBlocks::Free(CMemBlockManagerMt *memManager) -{ - while (Blocks.Size() > 0) - { - FreeBlock(Blocks.Size() - 1, memManager); - Blocks.DeleteBack(); - } - TotalSize = 0; -} - -HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager) -{ - if (LockMode) - { - if (Blocks.Size() > 0) - { - RINOK(memManager->ReleaseLockedBlocks(Blocks.Size())); - } - LockMode = false; - } - return 0; -} - -void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager) -{ - blocks.Free(memManager); - blocks.LockMode = LockMode; - UInt64 totalSize = 0; - size_t blockSize = memManager->GetBlockSize(); - FOR_VECTOR (i, Blocks) - { - if (totalSize < TotalSize) - blocks.Blocks.Add(Blocks[i]); - else - FreeBlock(i, memManager); - Blocks[i] = 0; - totalSize += blockSize; - } - blocks.TotalSize = TotalSize; - Free(memManager); -} +// MemBlocks.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "MemBlocks.h" +#include "StreamUtils.h" + +bool CMemBlockManager::AllocateSpace_bool(size_t numBlocks) +{ + FreeSpace(); + if (numBlocks == 0) + { + return true; + // return false; + } + if (_blockSize < sizeof(void *)) + return false; + const size_t totalSize = numBlocks * _blockSize; + if (totalSize / _blockSize != numBlocks) + return false; + _data = ::MidAlloc(totalSize); + if (!_data) + return false; + Byte *p = (Byte *)_data; + for (size_t i = 0; i + 1 < numBlocks; i++, p += _blockSize) + *(Byte **)(void *)p = (p + _blockSize); + *(Byte **)(void *)p = NULL; + _headFree = _data; + return true; +} + +void CMemBlockManager::FreeSpace() +{ + ::MidFree(_data); + _data = NULL; + _headFree= NULL; +} + +void *CMemBlockManager::AllocateBlock() +{ + void *p = _headFree; + if (p) + _headFree = *(void **)p; + return p; +} + +void CMemBlockManager::FreeBlock(void *p) +{ + if (!p) + return; + *(void **)p = _headFree; + _headFree = p; +} + + +// #include + +HRESULT CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks) +{ + if (numNoLockBlocks > numBlocks) + return E_INVALIDARG; + const size_t numLockBlocks = numBlocks - numNoLockBlocks; + UInt32 maxCount = (UInt32)numLockBlocks; + if (maxCount != numLockBlocks) + return E_OUTOFMEMORY; + if (!CMemBlockManager::AllocateSpace_bool(numBlocks)) + return E_OUTOFMEMORY; + // we need (maxCount = 1), if we want to create non-use empty Semaphore + if (maxCount == 0) + maxCount = 1; + + // printf("\n Synchro.Create() \n"); + WRes wres; + #ifndef _WIN32 + Semaphore.Close(); + wres = Synchro.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + wres = Semaphore.Create(&Synchro, (UInt32)numLockBlocks, maxCount); + #else + wres = Semaphore.OptCreateInit((UInt32)numLockBlocks, maxCount); + #endif + + return HRESULT_FROM_WIN32(wres); +} + + +HRESULT CMemBlockManagerMt::AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks) +{ + // desiredNumberOfBlocks = 0; // for debug + if (numNoLockBlocks > desiredNumberOfBlocks) + return E_INVALIDARG; + for (;;) + { + // if (desiredNumberOfBlocks == 0) return E_OUTOFMEMORY; + const HRESULT hres = AllocateSpace(desiredNumberOfBlocks, numNoLockBlocks); + if (hres != E_OUTOFMEMORY) + return hres; + if (desiredNumberOfBlocks == numNoLockBlocks) + return E_OUTOFMEMORY; + desiredNumberOfBlocks = numNoLockBlocks + ((desiredNumberOfBlocks - numNoLockBlocks) >> 1); + } +} + +void CMemBlockManagerMt::FreeSpace() +{ + Semaphore.Close(); + CMemBlockManager::FreeSpace(); +} + +void *CMemBlockManagerMt::AllocateBlock() +{ + // Semaphore.Lock(); + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return CMemBlockManager::AllocateBlock(); +} + +void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode) +{ + if (!p) + return; + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CMemBlockManager::FreeBlock(p); + } + if (lockMode) + Semaphore.Release(); +} + + + +void CMemBlocks::Free(CMemBlockManagerMt *manager) +{ + while (Blocks.Size() > 0) + { + manager->FreeBlock(Blocks.Back()); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +void CMemBlocks::FreeOpt(CMemBlockManagerMt *manager) +{ + Free(manager); + Blocks.ClearAndFree(); +} + +HRESULT CMemBlocks::WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const +{ + UInt64 totalSize = TotalSize; + for (unsigned blockIndex = 0; totalSize > 0; blockIndex++) + { + size_t curSize = blockSize; + if (curSize > totalSize) + curSize = (size_t)totalSize; + if (blockIndex >= Blocks.Size()) + return E_FAIL; + RINOK(WriteStream(outStream, Blocks[blockIndex], curSize)) + totalSize -= curSize; + } + return S_OK; +} + + +void CMemLockBlocks::FreeBlock(unsigned index, CMemBlockManagerMt *memManager) +{ + memManager->FreeBlock(Blocks[index], LockMode); + Blocks[index] = NULL; +} + +void CMemLockBlocks::Free(CMemBlockManagerMt *memManager) +{ + while (Blocks.Size() > 0) + { + FreeBlock(Blocks.Size() - 1, memManager); + Blocks.DeleteBack(); + } + TotalSize = 0; +} + +/* +HRes CMemLockBlocks::SwitchToNoLockMode(CMemBlockManagerMt *memManager) +{ + if (LockMode) + { + if (Blocks.Size() > 0) + { + RINOK(memManager->ReleaseLockedBlocks(Blocks.Size())); + } + LockMode = false; + } + return 0; +} +*/ + +void CMemLockBlocks::Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager) +{ + blocks.Free(memManager); + blocks.LockMode = LockMode; + UInt64 totalSize = 0; + const size_t blockSize = memManager->GetBlockSize(); + FOR_VECTOR (i, Blocks) + { + if (totalSize < TotalSize) + blocks.Blocks.Add(Blocks[i]); + else + FreeBlock(i, memManager); + Blocks[i] = NULL; + totalSize += blockSize; + } + blocks.TotalSize = TotalSize; + Free(memManager); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MemBlocks.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.h --- p7zip-rar-16.02/CPP/7zip/Common/MemBlocks.h 2014-12-22 11:34:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MemBlocks.h 2023-09-06 10:00:00.000000000 +0000 @@ -1,71 +1,72 @@ -// MemBlocks.h - -#ifndef __MEM_BLOCKS_H -#define __MEM_BLOCKS_H - -#include "../../Common/MyVector.h" - -#include "../../Windows/Synchronization.h" - -#include "../IStream.h" - -class CMemBlockManager -{ - void *_data; - size_t _blockSize; - void *_headFree; -public: - CMemBlockManager(size_t blockSize = (1 << 20)): _data(0), _blockSize(blockSize), _headFree(0) {} - ~CMemBlockManager() { FreeSpace(); } - - bool AllocateSpace(size_t numBlocks); - void FreeSpace(); - size_t GetBlockSize() const { return _blockSize; } - void *AllocateBlock(); - void FreeBlock(void *p); -}; - - -class CMemBlockManagerMt: public CMemBlockManager -{ - NWindows::NSynchronization::CCriticalSection _criticalSection; -public: - NWindows::NSynchronization::CSemaphoreWFMO Semaphore; - - CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {} - ~CMemBlockManagerMt() { FreeSpace(); } - - HRes AllocateSpace(NWindows::NSynchronization::CSynchro *sync ,size_t numBlocks, size_t numNoLockBlocks = 0); - HRes AllocateSpaceAlways(NWindows::NSynchronization::CSynchro *sync, size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); - void FreeSpace(); - void *AllocateBlock(); - void FreeBlock(void *p, bool lockMode = true); - HRes ReleaseLockedBlocks(int number) { return Semaphore.Release(number); } -}; - - -class CMemBlocks -{ - void Free(CMemBlockManagerMt *manager); -public: - CRecordVector Blocks; - UInt64 TotalSize; - - CMemBlocks(): TotalSize(0) {} - - void FreeOpt(CMemBlockManagerMt *manager); - HRESULT WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const; -}; - -struct CMemLockBlocks: public CMemBlocks -{ - bool LockMode; - - CMemLockBlocks(): LockMode(true) {}; - void Free(CMemBlockManagerMt *memManager); - void FreeBlock(int index, CMemBlockManagerMt *memManager); - HRes SwitchToNoLockMode(CMemBlockManagerMt *memManager); - void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager); -}; - -#endif +// MemBlocks.h + +#ifndef ZIP7_INC_MEM_BLOCKS_H +#define ZIP7_INC_MEM_BLOCKS_H + +#include "../../Common/MyVector.h" + +#include "../../Windows/Synchronization.h" + +#include "../IStream.h" + +class CMemBlockManager +{ + void *_data; + size_t _blockSize; + void *_headFree; +public: + CMemBlockManager(size_t blockSize = (1 << 20)): _data(NULL), _blockSize(blockSize), _headFree(NULL) {} + ~CMemBlockManager() { FreeSpace(); } + + bool AllocateSpace_bool(size_t numBlocks); + void FreeSpace(); + size_t GetBlockSize() const { return _blockSize; } + void *AllocateBlock(); + void FreeBlock(void *p); +}; + + +class CMemBlockManagerMt: public CMemBlockManager +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + SYNC_OBJ_DECL(Synchro) + NWindows::NSynchronization::CSemaphore_WFMO Semaphore; + + CMemBlockManagerMt(size_t blockSize = (1 << 20)): CMemBlockManager(blockSize) {} + ~CMemBlockManagerMt() { FreeSpace(); } + + HRESULT AllocateSpace(size_t numBlocks, size_t numNoLockBlocks); + HRESULT AllocateSpaceAlways(size_t desiredNumberOfBlocks, size_t numNoLockBlocks = 0); + void FreeSpace(); + void *AllocateBlock(); + void FreeBlock(void *p, bool lockMode = true); + // WRes ReleaseLockedBlocks_WRes(unsigned number) { return Semaphore.Release(number); } +}; + + +class CMemBlocks +{ + void Free(CMemBlockManagerMt *manager); +public: + CRecordVector Blocks; + UInt64 TotalSize; + + CMemBlocks(): TotalSize(0) {} + + void FreeOpt(CMemBlockManagerMt *manager); + HRESULT WriteToStream(size_t blockSize, ISequentialOutStream *outStream) const; +}; + +struct CMemLockBlocks: public CMemBlocks +{ + bool LockMode; + + CMemLockBlocks(): LockMode(true) {} + void Free(CMemBlockManagerMt *memManager); + void FreeBlock(unsigned index, CMemBlockManagerMt *memManager); + // HRESULT SwitchToNoLockMode(CMemBlockManagerMt *memManager); + void Detach(CMemLockBlocks &blocks, CMemBlockManagerMt *memManager); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MethodId.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.cpp --- p7zip-rar-16.02/CPP/7zip/Common/MethodId.cpp 2011-05-08 18:29:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.cpp 2011-01-25 11:01:32.000000000 +0000 @@ -1,3 +1,3 @@ -// MethodId.cpp - -#include "StdAfx.h" +// MethodId.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MethodId.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.h --- p7zip-rar-16.02/CPP/7zip/Common/MethodId.h 2014-12-21 14:29:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodId.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// MethodId.h - -#ifndef __7Z_METHOD_ID_H -#define __7Z_METHOD_ID_H - -#include "../../Common/MyTypes.h" - -typedef UInt64 CMethodId; - -#endif +// MethodId.h + +#ifndef ZIP7_INC_7Z_METHOD_ID_H +#define ZIP7_INC_7Z_METHOD_ID_H + +#include "../../Common/MyTypes.h" + +typedef UInt64 CMethodId; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MethodProps.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.cpp --- p7zip-rar-16.02/CPP/7zip/Common/MethodProps.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.cpp 2025-06-28 09:00:00.000000000 +0000 @@ -1,458 +1,765 @@ -// MethodProps.cpp - -#include "StdAfx.h" - -#include "../../Common/StringToInt.h" - -#include "MethodProps.h" - -using namespace NWindows; - -bool StringToBool(const UString &s, bool &res) -{ - if (s.IsEmpty() || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) - { - res = true; - return true; - } - if ((s[0] == '-' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "OFF")) - { - res = false; - return true; - } - return false; -} - -HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest) -{ - switch (prop.vt) - { - case VT_EMPTY: dest = true; return S_OK; - case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK; - case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG; - } - return E_INVALIDARG; -} - -unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number) -{ - const wchar_t *start = srcString; - const wchar_t *end; - number = ConvertStringToUInt32(start, &end); - return (unsigned)(end - start); -} - -HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) -{ - // =VT_UI4 - // =VT_EMPTY - // {stringUInt32}=VT_EMPTY - - if (prop.vt == VT_UI4) - { - if (!name.IsEmpty()) - return E_INVALIDARG; - resValue = prop.ulVal; - return S_OK; - } - if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - if (name.IsEmpty()) - return S_OK; - UInt32 v; - if (ParseStringToUInt32(name, v) != name.Len()) - return E_INVALIDARG; - resValue = v; - return S_OK; -} - -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) -{ - if (name.IsEmpty()) - { - switch (prop.vt) - { - case VT_UI4: - numThreads = prop.ulVal; - break; - default: - { - bool val; - RINOK(PROPVARIANT_to_bool(prop, val)); - numThreads = (val ? defaultNumThreads : 1); - break; - } - } - return S_OK; - } - if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - return ParsePropToUInt32(name, prop, numThreads); -} - - -static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) -{ - const wchar_t *end; - UInt32 number = ConvertStringToUInt32(s, &end); - unsigned numDigits = (unsigned)(end - s); - if (numDigits == 0 || s.Len() > numDigits + 1) - return E_INVALIDARG; - - if (s.Len() == numDigits) - { - if (number >= 64) - return E_INVALIDARG; - if (number < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)number); - else - destProp = (UInt64)((UInt64)1 << (unsigned)number); - return S_OK; - } - - unsigned numBits; - - switch (MyCharLower_Ascii(s[numDigits])) - { - case 'b': destProp = number; return S_OK; - case 'k': numBits = 10; break; - case 'm': numBits = 20; break; - case 'g': numBits = 30; break; - default: return E_INVALIDARG; - } - - if (number < ((UInt32)1 << (32 - numBits))) - destProp = (UInt32)(number << numBits); - else - destProp = (UInt64)((UInt64)number << numBits); - - return S_OK; -} - - -static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) -{ - if (prop.vt == VT_UI4) - { - UInt32 v = prop.ulVal; - if (v >= 64) - return E_INVALIDARG; - if (v < 32) - destProp = (UInt32)((UInt32)1 << (unsigned)v); - else - destProp = (UInt64)((UInt64)1 << (unsigned)v); - return S_OK; - } - if (prop.vt == VT_BSTR) - return StringToDictSize(prop.bstrVal, destProp); - return E_INVALIDARG; -} - - -void CProps::AddProp32(PROPID propid, UInt32 level) -{ - CProp &prop = Props.AddNew(); - prop.IsOptional = true; - prop.Id = propid; - prop.Value = (UInt32)level; -} - -class CCoderProps -{ - PROPID *_propIDs; - NCOM::CPropVariant *_props; - unsigned _numProps; - unsigned _numPropsMax; -public: - CCoderProps(unsigned numPropsMax) - { - _numPropsMax = numPropsMax; - _numProps = 0; - _propIDs = new PROPID[numPropsMax]; - _props = new NCOM::CPropVariant[numPropsMax]; - } - ~CCoderProps() - { - delete []_propIDs; - delete []_props; - } - void AddProp(const CProp &prop); - HRESULT SetProps(ICompressSetCoderProperties *setCoderProperties) - { - return setCoderProperties->SetCoderProperties(_propIDs, _props, _numProps); - } -}; - -void CCoderProps::AddProp(const CProp &prop) -{ - if (_numProps >= _numPropsMax) - throw 1; - _propIDs[_numProps] = prop.Id; - _props[_numProps] = prop.Value; - _numProps++; -} - -HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const -{ - CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0)); - FOR_VECTOR (i, Props) - coderProps.AddProp(Props[i]); - if (dataSizeReduce) - { - CProp prop; - prop.Id = NCoderPropID::kReduceSize; - prop.Value = *dataSizeReduce; - coderProps.AddProp(prop); - } - return coderProps.SetProps(scp); -} - - -int CMethodProps::FindProp(PROPID id) const -{ - for (int i = Props.Size() - 1; i >= 0; i--) - if (Props[i].Id == id) - return i; - return -1; -} - -int CMethodProps::GetLevel() const -{ - int i = FindProp(NCoderPropID::kLevel); - if (i < 0) - return 5; - if (Props[i].Value.vt != VT_UI4) - return 9; - UInt32 level = Props[i].Value.ulVal; - return level > 9 ? 9 : (int)level; -} - -struct CNameToPropID -{ - VARTYPE VarType; - const char *Name; -}; - -static const CNameToPropID g_NameToPropID[] = -{ - { VT_UI4, "" }, - { VT_UI4, "d" }, - { VT_UI4, "mem" }, - { VT_UI4, "o" }, - { VT_UI4, "c" }, - { VT_UI4, "pb" }, - { VT_UI4, "lc" }, - { VT_UI4, "lp" }, - { VT_UI4, "fb" }, - { VT_BSTR, "mf" }, - { VT_UI4, "mc" }, - { VT_UI4, "pass" }, - { VT_UI4, "a" }, - { VT_UI4, "mt" }, - { VT_BOOL, "eos" }, - { VT_UI4, "x" }, - { VT_UI4, "reduceSize" } -}; - -static int FindPropIdExact(const UString &name) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_NameToPropID); i++) - if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name)) - return i; - return -1; -} - -static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::CPropVariant &destProp) -{ - if (varType == srcProp.vt) - { - destProp = srcProp; - return true; - } - if (varType == VT_BOOL) - { - bool res; - if (PROPVARIANT_to_bool(srcProp, res) != S_OK) - return false; - destProp = res; - return true; - } - if (srcProp.vt == VT_EMPTY) - { - destProp = srcProp; - return true; - } - return false; -} - -static void SplitParams(const UString &srcString, UStringVector &subStrings) -{ - subStrings.Clear(); - UString s; - unsigned len = srcString.Len(); - if (len == 0) - return; - for (unsigned i = 0; i < len; i++) - { - wchar_t c = srcString[i]; - if (c == L':') - { - subStrings.Add(s); - s.Empty(); - } - else - s += c; - } - subStrings.Add(s); -} - -static void SplitParam(const UString ¶m, UString &name, UString &value) -{ - int eqPos = param.Find(L'='); - if (eqPos >= 0) - { - name.SetFrom(param, eqPos); - value = param.Ptr(eqPos + 1); - return; - } - unsigned i; - for (i = 0; i < param.Len(); i++) - { - wchar_t c = param[i]; - if (c >= L'0' && c <= L'9') - break; - } - name.SetFrom(param, i); - value = param.Ptr(i); -} - -static bool IsLogSizeProp(PROPID propid) -{ - switch (propid) - { - case NCoderPropID::kDictionarySize: - case NCoderPropID::kUsedMemorySize: - case NCoderPropID::kBlockSize: - case NCoderPropID::kReduceSize: - return true; - } - return false; -} - -HRESULT CMethodProps::SetParam(const UString &name, const UString &value) -{ - int index = FindPropIdExact(name); - if (index < 0) - return E_INVALIDARG; - const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; - CProp prop; - prop.Id = index; - - if (IsLogSizeProp(prop.Id)) - { - RINOK(StringToDictSize(value, prop.Value)); - } - else - { - NCOM::CPropVariant propValue; - if (nameToPropID.VarType == VT_BSTR) - propValue = value; - else if (nameToPropID.VarType == VT_BOOL) - { - bool res; - if (!StringToBool(value, res)) - return E_INVALIDARG; - propValue = res; - } - else if (!value.IsEmpty()) - { - UInt32 number; - if (ParseStringToUInt32(value, number) == value.Len()) - propValue = number; - else - propValue = value; - } - if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value)) - return E_INVALIDARG; - } - Props.Add(prop); - return S_OK; -} - -HRESULT CMethodProps::ParseParamsFromString(const UString &srcString) -{ - UStringVector params; - SplitParams(srcString, params); - FOR_VECTOR (i, params) - { - const UString ¶m = params[i]; - UString name, value; - SplitParam(param, name, value); - RINOK(SetParam(name, value)); - } - return S_OK; -} - -HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value) -{ - if (realName.Len() == 0) - { - // [empty]=method - return E_INVALIDARG; - } - if (value.vt == VT_EMPTY) - { - // {realName}=[empty] - UString name, valueStr; - SplitParam(realName, name, valueStr); - return SetParam(name, valueStr); - } - - // {realName}=value - int index = FindPropIdExact(realName); - if (index < 0) - return E_INVALIDARG; - const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; - CProp prop; - prop.Id = index; - - if (IsLogSizeProp(prop.Id)) - { - RINOK(PROPVARIANT_to_DictSize(value, prop.Value)); - } - else - { - if (!ConvertProperty(value, nameToPropID.VarType, prop.Value)) - return E_INVALIDARG; - } - Props.Add(prop); - return S_OK; -} - -HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) -{ - MethodName.Empty(); - int splitPos = s.Find(L':'); - { - UString temp = s; - if (splitPos >= 0) - temp.DeleteFrom(splitPos); - if (!temp.IsAscii()) - return E_INVALIDARG; - MethodName.SetFromWStr_if_Ascii(temp); - } - if (splitPos < 0) - return S_OK; - PropsString = s.Ptr(splitPos + 1); - return ParseParamsFromString(PropsString); -} - -HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value) -{ - if (!realName.IsEmpty() && !StringsAreEqualNoCase_Ascii(realName, "m")) - return ParseParamsFromPROPVARIANT(realName, value); - // -m{N}=method - if (value.vt != VT_BSTR) - return E_INVALIDARG; - return ParseMethodFromString(value.bstrVal); -} +// MethodProps.cpp + +#include "StdAfx.h" + +#include "../../Common/StringToInt.h" + +#include "MethodProps.h" + +using namespace NWindows; + +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents) +{ + // if (percents == 0) return 0; + const UInt64 q = percents / 100; + const UInt32 r = (UInt32)(percents % 100); + UInt64 res = 0; + + if (q != 0) + { + if (val > (UInt64)(Int64)-1 / q) + return (UInt64)(Int64)-1; + res = val * q; + } + + if (r != 0) + { + UInt64 v2; + if (val <= (UInt64)(Int64)-1 / r) + v2 = val * r / 100; + else + v2 = val / 100 * r; + res += v2; + if (res < v2) + return (UInt64)(Int64)-1; + } + + return res; +} + + +bool StringToBool(const wchar_t *s, bool &res) +{ + if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) + { + res = true; + return true; + } + if ((s[0] == '-' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "OFF")) + { + res = false; + return true; + } + return false; +} + +HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest) +{ + switch (prop.vt) + { + case VT_EMPTY: dest = true; return S_OK; + case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK; + case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG; + default: break; + } + return E_INVALIDARG; +} + +unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + number = ConvertStringToUInt32(start, &end); + return (unsigned)(end - start); +} + +static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + number = ConvertStringToUInt64(start, &end); + return (unsigned)(end - start); +} + +HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + // =VT_UI4 + // =VT_EMPTY : it doesn't change (resValue), and returns S_OK + // {stringUInt32}=VT_EMPTY + + if (prop.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + resValue = prop.ulVal; + return S_OK; + } + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + if (name.IsEmpty()) + return S_OK; + UInt32 v; + if (ParseStringToUInt32(name, v) != name.Len()) + return E_INVALIDARG; + resValue = v; + return S_OK; +} + + + +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force) +{ + force = false; + UString s; + if (name.IsEmpty()) + { + if (prop.vt == VT_UI4) + { + numThreads = prop.ulVal; + force = true; + return S_OK; + } + bool val; + HRESULT res = PROPVARIANT_to_bool(prop, val); + if (res == S_OK) + { + if (!val) + { + numThreads = 1; + force = true; + } + // force = true; for debug + // "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads + return S_OK; + } + if (prop.vt != VT_BSTR) + return res; + s.SetFromBstr(prop.bstrVal); + if (s.IsEmpty()) + return E_INVALIDARG; + } + else + { + if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + s = name; + } + + s.MakeLower_Ascii(); + const wchar_t *start = s; + UInt32 v = numThreads; + + /* we force up, if threads number specified + only `d` will force it down */ + bool force_loc = true; + for (;;) + { + const wchar_t c = *start; + if (!c) + break; + if (c == 'd') + { + force_loc = false; // force down + start++; + continue; + } + if (c == 'u') + { + force_loc = true; // force up + start++; + continue; + } + bool isPercent = false; + if (c == 'p') + { + isPercent = true; + start++; + } + const wchar_t *end; + v = ConvertStringToUInt32(start, &end); + if (end == start) + return E_INVALIDARG; + if (isPercent) + v = numThreads * v / 100; + start = end; + } + + numThreads = v; + force = force_loc; + return S_OK; +} + + + +static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp) +{ + if (number >= 64) + return E_INVALIDARG; + UInt32 val32; + if (number < 32) + val32 = (UInt32)1 << (unsigned)number; + /* + else if (number == 32 && reduce_4GB_to_32bits) + val32 = (UInt32)(Int32)-1; + */ + else + { + destProp = (UInt64)((UInt64)1 << (unsigned)number); + return S_OK; + } + destProp = (UInt32)val32; + return S_OK; +} + + +static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) +{ + /* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1). + to fit the value to UInt32 for clients that do not support 64-bit values */ + + const wchar_t *end; + const UInt64 number = ConvertStringToUInt64(s, &end); + const unsigned numDigits = (unsigned)(end - s.Ptr()); + if (numDigits == 0 || s.Len() > numDigits + 1) + return E_INVALIDARG; + + if (s.Len() == numDigits) + return SetLogSizeProp(number, destProp); + + unsigned numBits; + + switch (MyCharLower_Ascii(s[numDigits])) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + default: return E_INVALIDARG; + } + + const UInt64 range4g = ((UInt64)1 << (32 - numBits)); + if (number < range4g) + destProp = (UInt32)((UInt32)number << numBits); + /* + else if (number == range4g && reduce_4GB_to_32bits) + destProp = (UInt32)(Int32)-1; + */ + else if (numBits == 0) + destProp = (UInt64)number; + else if (number >= ((UInt64)1 << (64 - numBits))) + return E_INVALIDARG; + else + destProp = (UInt64)((UInt64)number << numBits); + return S_OK; +} + + +static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) +{ + if (prop.vt == VT_UI4) + return SetLogSizeProp(prop.ulVal, destProp); + + if (prop.vt == VT_BSTR) + { + UString s; + s = prop.bstrVal; + return StringToDictSize(s, destProp); + } + return E_INVALIDARG; +} + + +void CProps::AddProp32(PROPID propid, UInt32 val) +{ + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = propid; + prop.Value = (UInt32)val; +} + +void CProps::AddPropBool(PROPID propid, bool val) +{ + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = propid; + prop.Value = val; +} + +class CCoderProps +{ + PROPID *_propIDs; + NCOM::CPropVariant *_props; + unsigned _numProps; + unsigned _numPropsMax; +public: + CCoderProps(unsigned numPropsMax): + _propIDs(NULL), + _props(NULL), + _numProps(0), + _numPropsMax(numPropsMax) + { + _propIDs = new PROPID[numPropsMax]; + _props = new NCOM::CPropVariant[numPropsMax]; + } + ~CCoderProps() + { + delete []_propIDs; + delete []_props; + } + void AddProp(const CProp &prop); + HRESULT SetProps(ICompressSetCoderProperties *setCoderProperties) + { + return setCoderProperties->SetCoderProperties(_propIDs, _props, _numProps); + } +}; + +void CCoderProps::AddProp(const CProp &prop) +{ + if (_numProps >= _numPropsMax) + throw 1; + _propIDs[_numProps] = prop.Id; + _props[_numProps] = prop.Value; + _numProps++; +} + +HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const +{ + return SetCoderProps_DSReduce_Aff(scp, dataSizeReduce, NULL, NULL, NULL); +} + +HRESULT CProps::SetCoderProps_DSReduce_Aff( + ICompressSetCoderProperties *scp, + const UInt64 *dataSizeReduce, + const UInt64 *affinity, + const UInt32 *affinityGroup, + const UInt64 *affinityInGroup) const +{ + CCoderProps coderProps(Props.Size() + + (dataSizeReduce ? 1 : 0) + + (affinity ? 1 : 0) + + (affinityGroup ? 1 : 0) + + (affinityInGroup ? 1 : 0) + ); + FOR_VECTOR (i, Props) + coderProps.AddProp(Props[i]); + if (dataSizeReduce) + { + CProp prop; + prop.Id = NCoderPropID::kReduceSize; + prop.Value = *dataSizeReduce; + coderProps.AddProp(prop); + } + if (affinity) + { + CProp prop; + prop.Id = NCoderPropID::kAffinity; + prop.Value = *affinity; + coderProps.AddProp(prop); + } + if (affinityGroup) + { + CProp prop; + prop.Id = NCoderPropID::kThreadGroup; + prop.Value = *affinityGroup; + coderProps.AddProp(prop); + } + if (affinityInGroup) + { + CProp prop; + prop.Id = NCoderPropID::kAffinityInGroup; + prop.Value = *affinityInGroup; + coderProps.AddProp(prop); + } + return coderProps.SetProps(scp); +} + + +int CMethodProps::FindProp(PROPID id) const +{ + for (unsigned i = Props.Size(); i != 0;) + if (Props[--i].Id == id) + return (int)i; + return -1; +} + +unsigned CMethodProps::GetLevel() const +{ + int i = FindProp(NCoderPropID::kLevel); + if (i < 0) + return 5; + if (Props[(unsigned)i].Value.vt != VT_UI4) + return 9; + UInt32 level = Props[(unsigned)i].Value.ulVal; + return level > 9 ? 9 : (unsigned)level; +} + +struct CNameToPropID +{ + VARTYPE VarType; + const char *Name; +}; + + +// the following are related to NCoderPropID::EEnum values +// NCoderPropID::k_NUM_DEFINED +static const CNameToPropID g_NameToPropID[] = +{ + { VT_UI4, "" }, + { VT_UI4, "d" }, + { VT_UI4, "mem" }, + { VT_UI4, "o" }, + { VT_UI8, "c" }, + { VT_UI4, "pb" }, + { VT_UI4, "lc" }, + { VT_UI4, "lp" }, + { VT_UI4, "fb" }, + { VT_BSTR, "mf" }, + { VT_UI4, "mc" }, + { VT_UI4, "pass" }, + { VT_UI4, "a" }, + { VT_UI4, "mt" }, + { VT_BOOL, "eos" }, + { VT_UI4, "x" }, + { VT_UI8, "reduce" }, + { VT_UI8, "expect" }, + { VT_UI8, "cc" }, // "cc" in v23, "b" in v22.01 + { VT_UI4, "check" }, + { VT_BSTR, "filter" }, + { VT_UI8, "memuse" }, + { VT_UI8, "aff" }, + { VT_UI4, "offset" }, + { VT_UI4, "zhb" } + /* + , { VT_UI4, "tgn" }, // kNumThreadGroups + , { VT_UI4, "tgi" }, // kThreadGroup + , { VT_UI8, "tga" }, // kAffinityInGroup + */ + /* + , + // { VT_UI4, "zhc" }, + // { VT_UI4, "zhd" }, + // { VT_UI4, "zcb" }, + { VT_UI4, "dc" }, + { VT_UI4, "zx" }, + { VT_UI4, "zf" }, + { VT_UI4, "zmml" }, + { VT_UI4, "zov" }, + { VT_BOOL, "zmfr" }, + { VT_BOOL, "zle" }, // long enable + // { VT_UI4, "zldb" }, + { VT_UI4, "zld" }, + { VT_UI4, "zlhb" }, + { VT_UI4, "zlmml" }, + { VT_UI4, "zlbb" }, + { VT_UI4, "zlhrb" }, + { VT_BOOL, "zwus" }, + { VT_BOOL, "zshp" }, + { VT_BOOL, "zshs" }, + { VT_BOOL, "zshe" }, + { VT_BOOL, "zshg" }, + { VT_UI4, "zpsm" } + */ + // { VT_UI4, "mcb" }, // mc log version + // { VT_UI4, "ztlen" }, // fb ? +}; + +/* +#if defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 200410L) || (defined(_MSC_VER) && _MSC_VER >= 1600) + +#if (defined(__cplusplus) && __cplusplus < 201103L) \ + && defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wc11-extensions" +#endif + static_assert(Z7_ARRAY_SIZE(g_NameToPropID) == NCoderPropID::k_NUM_DEFINED, + "g_NameToPropID doesn't match NCoderPropID enum"); +#endif +*/ + +static int FindPropIdExact(const UString &name) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NameToPropID); i++) + if (StringsAreEqualNoCase_Ascii(name, g_NameToPropID[i].Name)) + return (int)i; + return -1; +} + +static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::CPropVariant &destProp) +{ + if (varType == srcProp.vt) + { + destProp = srcProp; + return true; + } + + if (varType == VT_UI8 && srcProp.vt == VT_UI4) + { + destProp = (UInt64)srcProp.ulVal; + return true; + } + + if (varType == VT_BOOL) + { + bool res; + if (PROPVARIANT_to_bool(srcProp, res) != S_OK) + return false; + destProp = res; + return true; + } + if (srcProp.vt == VT_EMPTY) + { + destProp = srcProp; + return true; + } + return false; +} + +static void SplitParams(const UString &srcString, UStringVector &subStrings) +{ + subStrings.Clear(); + UString s; + unsigned len = srcString.Len(); + if (len == 0) + return; + for (unsigned i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L':') + { + subStrings.Add(s); + s.Empty(); + } + else + s += c; + } + subStrings.Add(s); +} + +static void SplitParam(const UString ¶m, UString &name, UString &value) +{ + int eqPos = param.Find(L'='); + if (eqPos >= 0) + { + name.SetFrom(param, (unsigned)eqPos); + value = param.Ptr((unsigned)(eqPos + 1)); + return; + } + unsigned i; + for (i = 0; i < param.Len(); i++) + { + wchar_t c = param[i]; + if (c >= L'0' && c <= L'9') + break; + } + name.SetFrom(param, i); + value = param.Ptr(i); +} + +static bool IsLogSizeProp(PROPID propid) +{ + switch (propid) + { + case NCoderPropID::kDictionarySize: + case NCoderPropID::kUsedMemorySize: + case NCoderPropID::kBlockSize: + case NCoderPropID::kBlockSize2: + /* + case NCoderPropID::kChainSize: + case NCoderPropID::kLdmWindowSize: + */ + // case NCoderPropID::kReduceSize: + return true; + default: break; + } + return false; +} + +HRESULT CMethodProps::SetParam(const UString &name, const UString &value) +{ + int index = FindPropIdExact(name); + if (index < 0) + { + // 'b' was used as NCoderPropID::kBlockSize2 before v23 + if (!name.IsEqualTo_Ascii_NoCase("b") || value.Find(L':') >= 0) + return E_INVALIDARG; + index = NCoderPropID::kBlockSize2; + } + const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; + CProp prop; + prop.Id = (unsigned)index; + + if (IsLogSizeProp(prop.Id)) + { + RINOK(StringToDictSize(value, prop.Value)) + } + else + { + NCOM::CPropVariant propValue; + if (nameToPropID.VarType == VT_BSTR) + propValue = value; + else if (nameToPropID.VarType == VT_BOOL) + { + bool res; + if (!StringToBool(value, res)) + return E_INVALIDARG; + propValue = res; + } + else if (!value.IsEmpty()) + { + if (nameToPropID.VarType == VT_UI4) + { + UInt32 number; + if (ParseStringToUInt32(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } + else if (nameToPropID.VarType == VT_UI8) + { + UInt64 number; + if (ParseStringToUInt64(value, number) == value.Len()) + propValue = number; + else + propValue = value; + } + else + propValue = value; + } + if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value)) + return E_INVALIDARG; + } + Props.Add(prop); + return S_OK; +} + +HRESULT CMethodProps::ParseParamsFromString(const UString &srcString) +{ + UStringVector params; + SplitParams(srcString, params); + FOR_VECTOR (i, params) + { + const UString ¶m = params[i]; + UString name, value; + SplitParam(param, name, value); + RINOK(SetParam(name, value)) + } + return S_OK; +} + +HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value) +{ + if (realName.Len() == 0) + { + // [empty]=method + return E_INVALIDARG; + } + if (value.vt == VT_EMPTY) + { + // {realName}=[empty] + UString name, valueStr; + SplitParam(realName, name, valueStr); + return SetParam(name, valueStr); + } + + // {realName}=value + const int index = FindPropIdExact(realName); + if (index < 0) + return E_INVALIDARG; + const CNameToPropID &nameToPropID = g_NameToPropID[(unsigned)index]; + CProp prop; + prop.Id = (unsigned)index; + + if (IsLogSizeProp(prop.Id)) + { + RINOK(PROPVARIANT_to_DictSize(value, prop.Value)) + } + else + { + if (!ConvertProperty(value, nameToPropID.VarType, prop.Value)) + return E_INVALIDARG; + } + Props.Add(prop); + return S_OK; +} + + +static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads) +{ + UInt32 hs = dict - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + if (hs >= (1 << 24)) + hs >>= 1; + hs |= (1 << 16) - 1; + // if (numHashBytes >= 5) + if (!isBt) + hs |= (256 << 10) - 1; + hs++; + UInt64 size1 = (UInt64)hs * 4; + size1 += (UInt64)dict * 4; + if (isBt) + size1 += (UInt64)dict * 4; + size1 += (2 << 20); + + if (numThreads > 1 && isBt) + size1 += (2 << 20) + (4 << 20); + return size1; +} + +static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; + +UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const +{ + const UInt64 dicSize = Get_Lzma_DicSize(); + const bool isBt = Get_Lzma_MatchFinder_IsBt(); + const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize); + const UInt32 numThreads = Get_Lzma_NumThreads(); + UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads); + + if (addSlidingWindowSize) + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict32 + (1 << 16) + + (numThreads > 1 ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + size += blockSize; + } + return size; +} + + + + +HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) +{ + MethodName.Empty(); + int splitPos = s.Find(L':'); + { + UString temp = s; + if (splitPos >= 0) + temp.DeleteFrom((unsigned)splitPos); + if (!temp.IsAscii()) + return E_INVALIDARG; + MethodName.SetFromWStr_if_Ascii(temp); + } + if (splitPos < 0) + return S_OK; + PropsString = s.Ptr((unsigned)(splitPos + 1)); + return ParseParamsFromString(PropsString); +} + +HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value) +{ + if (!realName.IsEmpty() && !StringsAreEqualNoCase_Ascii(realName, "m")) + return ParseParamsFromPROPVARIANT(realName, value); + // -m{N}=method + if (value.vt != VT_BSTR) + return E_INVALIDARG; + UString s; + s = value.bstrVal; + return ParseMethodFromString(s); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MethodProps.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.h --- p7zip-rar-16.02/CPP/7zip/Common/MethodProps.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MethodProps.h 2025-06-28 09:00:00.000000000 +0000 @@ -1,194 +1,349 @@ -// MethodProps.h - -#ifndef __7Z_METHOD_PROPS_H -#define __7Z_METHOD_PROPS_H - -#include "../../Common/MyString.h" - -#include "../../Windows/PropVariant.h" - -#include "../ICoder.h" - -bool StringToBool(const UString &s, bool &res); -HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest); -unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number); -HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); - -HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); - -struct CProp -{ - PROPID Id; - bool IsOptional; - NWindows::NCOM::CPropVariant Value; - CProp(): IsOptional(false) {} -}; - -struct CProps -{ - CObjectVector Props; - - void Clear() { Props.Clear(); } - - bool AreThereNonOptionalProps() const - { - FOR_VECTOR (i, Props) - if (!Props[i].IsOptional) - return true; - return false; - } - - void AddProp32(PROPID propid, UInt32 level); - - void AddProp_Ascii(PROPID propid, const char *s) - { - CProp &prop = Props.AddNew(); - prop.IsOptional = true; - prop.Id = propid; - prop.Value = s; - } - - HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const; -}; - -class CMethodProps: public CProps -{ - HRESULT SetParam(const UString &name, const UString &value); -public: - int GetLevel() const; - int Get_NumThreads() const - { - int i = FindProp(NCoderPropID::kNumThreads); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return (int)Props[i].Value.ulVal; - return -1; - } - - bool Get_DicSize(UInt32 &res) const - { - res = 0; - int i = FindProp(NCoderPropID::kDictionarySize); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - { - res = Props[i].Value.ulVal; - return true; - } - return false; - } - - int FindProp(PROPID id) const; - - UInt32 Get_Lzma_Algo() const - { - int i = FindProp(NCoderPropID::kAlgorithm); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - return GetLevel() >= 5 ? 1 : 0; - } - - UInt32 Get_Lzma_DicSize() const - { - int i = FindProp(NCoderPropID::kDictionarySize); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)); - } - - bool Are_Lzma_Model_Props_Defined() const - { - if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true; - if (FindProp(NCoderPropID::kLitContextBits) >= 0) return true; - if (FindProp(NCoderPropID::kLitPosBits) >= 0) return true; - return false; - } - - UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const - { - fixedNumber = false; - int numThreads = Get_NumThreads(); - if (numThreads >= 0) - { - fixedNumber = true; - return numThreads < 2 ? 1 : 2; - } - return Get_Lzma_Algo() == 0 ? 1 : 2; - } - - UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const - { - fixedNumber = false; - int numThreads = Get_NumThreads(); - if (numThreads >= 0) - { - fixedNumber = true; - if (numThreads < 1) return 1; - if (numThreads > 64) return 64; - return numThreads; - } - return 1; - } - - UInt32 Get_BZip2_BlockSize() const - { - int i = FindProp(NCoderPropID::kDictionarySize); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - { - UInt32 blockSize = Props[i].Value.ulVal; - const UInt32 kDicSizeMin = 100000; - const UInt32 kDicSizeMax = 900000; - if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; - if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; - return blockSize; - } - int level = GetLevel(); - return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); - } - - UInt32 Get_Ppmd_MemSize() const - { - int i = FindProp(NCoderPropID::kUsedMemorySize); - if (i >= 0) - if (Props[i].Value.vt == VT_UI4) - return Props[i].Value.ulVal; - int level = GetLevel(); - return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19)); - } - - void AddProp_Level(UInt32 level) - { - AddProp32(NCoderPropID::kLevel, level); - } - - void AddProp_NumThreads(UInt32 numThreads) - { - AddProp32(NCoderPropID::kNumThreads, numThreads); - } - - HRESULT ParseParamsFromString(const UString &srcString); - HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); -}; - -class COneMethodInfo: public CMethodProps -{ -public: - AString MethodName; - UString PropsString; - - void Clear() - { - CMethodProps::Clear(); - MethodName.Empty(); - PropsString.Empty(); - } - bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); } - HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); - HRESULT ParseMethodFromString(const UString &s); -}; - -#endif +// MethodProps.h + +#ifndef ZIP7_INC_7Z_METHOD_PROPS_H +#define ZIP7_INC_7Z_METHOD_PROPS_H + +#include "../../Common/MyString.h" +#include "../../Common/Defs.h" + +#include "../../Windows/Defs.h" + +#include "../../Windows/PropVariant.h" + +#include "../ICoder.h" + +// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads); + +inline UInt64 Calc_From_Val_Percents_Less100(UInt64 val, UInt64 percents) +{ + if (percents == 0) + return 0; + if (val <= (UInt64)(Int64)-1 / percents) + return val * percents / 100; + return val / 100 * percents; +} + +UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents); + +bool StringToBool(const wchar_t *s, bool &res); +HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest); +unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number); + +/* +if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK. + So you must set (resValue) for default value before calling */ +HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); + +/* input: (numThreads = the_number_of_processors) */ +HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force); + +inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads) +{ + bool forced = false; + numThreads = numCPUs; + return ParseMtProp2(name, prop, numThreads, forced); +} + + +struct CProp +{ + PROPID Id; + bool IsOptional; + NWindows::NCOM::CPropVariant Value; + CProp(): IsOptional(false) {} +}; + +struct CProps +{ + CObjectVector Props; + + void Clear() { Props.Clear(); } + + bool AreThereNonOptionalProps() const + { + FOR_VECTOR (i, Props) + if (!Props[i].IsOptional) + return true; + return false; + } + + void AddProp32(PROPID propid, UInt32 val); + + void AddPropBool(PROPID propid, bool val); + + void AddProp_Ascii(PROPID propid, const char *s) + { + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = propid; + prop.Value = s; + } + + HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const; + HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, + const UInt64 *dataSizeReduce, + const UInt64 *affinity, + const UInt32 *affinityGroup, + const UInt64 *affinityInGroup) const; +}; + +class CMethodProps: public CProps +{ + HRESULT SetParam(const UString &name, const UString &value); +public: + unsigned GetLevel() const; + int Get_NumThreads() const + { + const int i = FindProp(NCoderPropID::kNumThreads); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return (int)val.ulVal; + } + return -1; + } + + bool Get_DicSize(UInt64 &res) const + { + res = 0; + const int i = FindProp(NCoderPropID::kDictionarySize); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + { + res = val.ulVal; + return true; + } + if (val.vt == VT_UI8) + { + res = val.uhVal.QuadPart; + return true; + } + } + return false; + } + + int FindProp(PROPID id) const; + + UInt32 Get_Lzma_Algo() const + { + const int i = FindProp(NCoderPropID::kAlgorithm); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + } + return GetLevel() >= 5 ? 1 : 0; + } + + UInt64 Get_Lzma_DicSize() const + { + UInt64 v; + if (Get_DicSize(v)) + return v; + const unsigned level = GetLevel(); + const UInt32 dictSize = level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); + return dictSize; + } + + bool Get_Lzma_MatchFinder_IsBt() const + { + const int i = FindProp(NCoderPropID::kMatchFinder); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BSTR) + return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc" + } + return GetLevel() >= 5; + } + + bool Get_Lzma_Eos() const + { + const int i = FindProp(NCoderPropID::kEndMarker); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_BOOL) + return VARIANT_BOOLToBool(val.boolVal); + } + return false; + } + + bool Are_Lzma_Model_Props_Defined() const + { + if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true; + if (FindProp(NCoderPropID::kLitContextBits) >= 0) return true; + if (FindProp(NCoderPropID::kLitPosBits) >= 0) return true; + return false; + } + + UInt32 Get_Lzma_NumThreads() const + { + if (Get_Lzma_Algo() == 0) + return 1; + int numThreads = Get_NumThreads(); + if (numThreads >= 0) + return numThreads < 2 ? 1 : 2; + return 2; + } + + UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const; + + /* returns -1, if numThreads is unknown */ + int Get_Xz_NumThreads(UInt32 &lzmaThreads) const + { + lzmaThreads = 1; + int numThreads = Get_NumThreads(); + if (numThreads >= 0 && numThreads <= 1) + return 1; + if (Get_Lzma_Algo() != 0) + lzmaThreads = 2; + return numThreads; + } + + UInt64 GetProp_BlockSize(PROPID id) const + { + const int i = FindProp(id); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) { return val.ulVal; } + if (val.vt == VT_UI8) { return val.uhVal.QuadPart; } + } + return 0; + } + + UInt64 Get_Xz_BlockSize() const + { + { + UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize); + UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2); + UInt64 minSize = MyMin(blockSize1, blockSize2); + if (minSize != 0) + return minSize; + UInt64 maxSize = MyMax(blockSize1, blockSize2); + if (maxSize != 0) + return maxSize; + } + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt64 dictSize = Get_Lzma_DicSize(); + /* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */ + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + return blockSize; + } + + + UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const + { + fixedNumber = false; + int numThreads = Get_NumThreads(); + if (numThreads >= 0) + { + fixedNumber = true; + if (numThreads < 1) return 1; + const unsigned kNumBZip2ThreadsMax = 64; + if ((unsigned)numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax; + return (unsigned)numThreads; + } + return 1; + } + + UInt32 Get_BZip2_BlockSize() const + { + const int i = FindProp(NCoderPropID::kDictionarySize); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + { + UInt32 blockSize = val.ulVal; + const UInt32 kDicSizeMin = 100000; + const UInt32 kDicSizeMax = 900000; + if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; + if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; + return blockSize; + } + } + const unsigned level = GetLevel(); + return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); + } + + UInt64 Get_Ppmd_MemSize() const + { + const int i = FindProp(NCoderPropID::kUsedMemorySize); + if (i >= 0) + { + const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; + if (val.vt == VT_UI4) + return val.ulVal; + if (val.vt == VT_UI8) + return val.uhVal.QuadPart; + } + const unsigned level = GetLevel(); + const UInt32 mem = (UInt32)1 << (level + 19); + return mem; + } + + void AddProp_Level(UInt32 level) + { + AddProp32(NCoderPropID::kLevel, level); + } + + void AddProp_NumThreads(UInt32 numThreads) + { + AddProp32(NCoderPropID::kNumThreads, numThreads); + } + + void AddProp_EndMarker_if_NotFound(bool eos) + { + if (FindProp(NCoderPropID::kEndMarker) < 0) + AddPropBool(NCoderPropID::kEndMarker, eos); + } + + void AddProp_BlockSize2(UInt64 blockSize2) + { + if (FindProp(NCoderPropID::kBlockSize2) < 0) + { + CProp &prop = Props.AddNew(); + prop.IsOptional = true; + prop.Id = NCoderPropID::kBlockSize2; + prop.Value = blockSize2; + } + } + + HRESULT ParseParamsFromString(const UString &srcString); + HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); +}; + +class COneMethodInfo: public CMethodProps +{ +public: + AString MethodName; + UString PropsString; + + void Clear() + { + CMethodProps::Clear(); + MethodName.Empty(); + PropsString.Empty(); + } + bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); } + HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); + HRESULT ParseMethodFromString(const UString &s); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MultiOutStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.cpp --- p7zip-rar-16.02/CPP/7zip/Common/MultiOutStream.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.cpp 2023-09-05 07:00:00.000000000 +0000 @@ -0,0 +1,855 @@ +// MultiOutStream.cpp + +#include "StdAfx.h" + +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include + #define PRF(x) x; +#else + #define PRF(x) +#endif + +#include "../../Common/ComTry.h" + +#include "../../Windows/FileDir.h" +#include "../../Windows/FileFind.h" +#include "../../Windows/System.h" + +#include "MultiOutStream.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const unsigned k_NumVols_MAX = k_VectorSizeMax - 1; + // 2; // for debug + +/* +#define UPDATE_HRES(hres, x) \ + { const HRESULT res2 = (x); if (hres == SZ_OK) hres = res2; } +*/ + +HRESULT CMultiOutStream::Destruct() +{ + COM_TRY_BEGIN + HRESULT hres = S_OK; + HRESULT hres3 = S_OK; + + while (!Streams.IsEmpty()) + { + try + { + HRESULT hres2; + if (NeedDelete) + { + /* we could call OptReOpen_and_SetSize() to test that we try to delete correct file, + but we cannot guarantee that (RealSize) will be correct after Write() or another failures. + And we still want to delete files even for such cases. + So we don't check for OptReOpen_and_SetSize() here: */ + // if (OptReOpen_and_SetSize(Streams.Size() - 1, 0) == S_OK) + hres2 = CloseStream_and_DeleteFile(Streams.Size() - 1); + } + else + { + hres2 = CloseStream(Streams.Size() - 1); + } + if (hres == S_OK) + hres = hres2; + } + catch(...) + { + hres3 = E_OUTOFMEMORY; + } + + { + /* Stream was released in CloseStream_*() above already, and it was removed from linked list + it's some unexpected case, if Stream is still attached here. + So the following code is optional: */ + CVolStream &s = Streams.Back(); + if (s.Stream) + { + if (hres3 == S_OK) + hres3 = E_FAIL; + s.Stream.Detach(); + /* it will be not failure, even if we call RemoveFromLinkedList() + twice for same CVolStream in this Destruct() function */ + RemoveFromLinkedList(Streams.Size() - 1); + } + } + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + + if (hres == S_OK) + hres = hres3; + if (hres == S_OK && NumListItems != 0) + hres = E_FAIL; + return hres; + COM_TRY_END +} + + +CMultiOutStream::~CMultiOutStream() +{ + // we try to avoid exception in destructors + Destruct(); +} + + +void CMultiOutStream::Init(const CRecordVector &sizes) +{ + Streams.Clear(); + InitLinkedList(); + Sizes = sizes; + NeedDelete = true; + MTime_Defined = false; + FinalVol_WasReopen = false; + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + _absLimit = (UInt64)(Int64)-1; + + _restrict_Begin = 0; + _restrict_End = (UInt64)(Int64)-1; + _restrict_Global = 0; + + UInt64 sum = 0; + unsigned i = 0; + for (i = 0; i < Sizes.Size(); i++) + { + if (i >= k_NumVols_MAX) + { + _absLimit = sum; + break; + } + const UInt64 size = Sizes[i]; + const UInt64 next = sum + size; + if (next < sum) + break; + sum = next; + } + + // if (Sizes.IsEmpty()) throw "no volume sizes"; + const UInt64 size = Sizes.Back(); + if (size == 0) + throw "zero size last volume"; + + if (i == Sizes.Size()) + if ((_absLimit - sum) / size >= (k_NumVols_MAX - i)) + _absLimit = sum + (k_NumVols_MAX - i) * size; +} + + +/* IsRestricted(): + we must call only if volume is full (s.RealSize==VolSize) or finished. + the function doesn't use VolSize and it uses s.RealSize instead. + it returns true : if stream is restricted, and we can't close that stream + it returns false : if there is no restriction, and we can close that stream + Note: (RealSize == 0) (empty volume) on restriction bounds are supposed as non-restricted +*/ +bool CMultiOutStream::IsRestricted(const CVolStream &s) const +{ + if (s.Start < _restrict_Global) + return true; + if (_restrict_Begin == _restrict_End) + return false; + if (_restrict_Begin <= s.Start) + return _restrict_End > s.Start; + return _restrict_Begin < s.Start + s.RealSize; +} + +/* +// this function check also _length and volSize +bool CMultiOutStream::IsRestricted_for_Close(unsigned index) const +{ + const CVolStream &s = Streams[index]; + if (_length <= s.Start) // we don't close streams after the end, because we still can write them later + return true; + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + return IsRestricted_Empty(s); + if (_length - s.Start < volSize) + return true; + return IsRestricted(s); +} +*/ + +FString CMultiOutStream::GetFilePath(unsigned index) +{ + FString name; + name.Add_UInt32((UInt32)(index + 1)); + while (name.Len() < 3) + name.InsertAtFront(FTEXT('0')); + name.Insert(0, Prefix); + return name; +} + + +// we close stream, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream(unsigned index) +{ + CVolStream &s = Streams[index]; + if (s.Stream) + { + RINOK(s.StreamSpec->Close()) + // the following two commands must be called together: + s.Stream.Release(); + RemoveFromLinkedList(index); + } + return S_OK; +} + + +// we close stream and delete file, but we still keep item in Streams[] vector +HRESULT CMultiOutStream::CloseStream_and_DeleteFile(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_AndDelete \n", index)) + RINOK(CloseStream(index)) + FString path = GetFilePath(index); + path += Streams[index].Postfix; + // we can checki that file exist + // if (NFind::DoesFileExist_Raw(path)) + if (!DeleteFileAlways(path)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + + +HRESULT CMultiOutStream::CloseStream_and_FinalRename(unsigned index) +{ + PRF(printf("\n====== %u, CloseStream_and_FinalRename \n", index)) + CVolStream &s = Streams[index]; + // HRESULT res = S_OK; + bool mtime_WasSet = false; + if (MTime_Defined && s.Stream) + { + if (s.StreamSpec->SetMTime(&MTime)) + mtime_WasSet = true; + // else res = GetLastError_noZero_HRESULT(); + } + + RINOK(CloseStream(index)) + if (s.Postfix.IsEmpty()) // if Postfix is empty, the path is already final + return S_OK; + const FString path = GetFilePath(index); + FString tempPath = path; + tempPath += s.Postfix; + + if (MTime_Defined && !mtime_WasSet) + { + if (!SetDirTime(tempPath, NULL, NULL, &MTime)) + { + // res = GetLastError_noZero_HRESULT(); + } + } + if (!MyMoveFile(tempPath, path)) + return GetLastError_noZero_HRESULT(); + /* we clear CVolStream::Postfix. So we will not use Temp path + anymore for this stream, and we will work only with final path */ + s.Postfix.Empty(); + // we can ignore set_mtime error or we can return it + return S_OK; + // return res; +} + + +HRESULT CMultiOutStream::PrepareToOpenNew() +{ + PRF(printf("PrepareToOpenNew NumListItems =%u, NumOpenFiles_AllowedMax = %u \n", NumListItems, NumOpenFiles_AllowedMax)) + + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + /* when we create zip archive: in most cases we need only starting + data of restricted region for rewriting zip's local header. + So here we close latest created volume (from Head), and we try to + keep oldest volumes that will be used for header rewriting later. */ + const int index = Head; + if (index == -1) + return E_FAIL; + PRF(printf("\n== %u, PrepareToOpenNew::CloseStream, NumListItems =%u \n", index, NumListItems)) + /* we don't expect non-restricted stream here in normal cases (if _restrict_Global was not changed). + if there was non-restricted stream, it should be closed before */ + // if (!IsRestricted_for_Close(index)) return CloseStream_and_FinalRename(index); + return CloseStream((unsigned)index); +} + + +HRESULT CMultiOutStream::CreateNewStream(UInt64 newSize) +{ + PRF(printf("\n== %u, CreateNewStream, size =%u \n", Streams.Size(), (unsigned)newSize)) + + if (Streams.Size() >= k_NumVols_MAX) + return E_INVALIDARG; // E_OUTOFMEMORY + + RINOK(PrepareToOpenNew()) + CVolStream s; + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + const FString path = GetFilePath(Streams.Size()); + + if (NFind::DoesFileExist_Raw(path)) + return HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + if (!CreateTempFile2(path, false, s.Postfix, &s.StreamSpec->File)) + return GetLastError_noZero_HRESULT(); + + s.Start = GetGlobalOffset_for_NewStream(); + s.Pos = 0; + s.RealSize = 0; + + const unsigned index = Streams.Add(s); + InsertToLinkedList(index); + + if (newSize != 0) + return s.SetSize2(newSize); + return S_OK; +} + + +HRESULT CMultiOutStream::CreateStreams_If_Required(unsigned streamIndex) +{ + // UInt64 lastStreamSize = 0; + for (;;) + { + const unsigned numStreamsBefore = Streams.Size(); + if (streamIndex < numStreamsBefore) + return S_OK; + UInt64 newSize; + if (streamIndex == numStreamsBefore) + { + // it's final volume that will be used for real writing. + /* SetSize(_offsetPos) is not required, + because the file Size will be set later by calling Seek() with Write() */ + newSize = 0; // lastStreamSize; + } + else + { + // it's intermediate volume. So we need full volume size + newSize = GetVolSize_for_Stream(numStreamsBefore); + } + + RINOK(CreateNewStream(newSize)) + + // optional check + if (numStreamsBefore + 1 != Streams.Size()) return E_FAIL; + + if (streamIndex != numStreamsBefore) + { + // it's intermediate volume. So we can close it, if it's non-restricted + bool isRestricted; + { + const CVolStream &s = Streams[numStreamsBefore]; + if (newSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + } + if (!isRestricted) + { + RINOK(CloseStream_and_FinalRename(numStreamsBefore)) + } + } + } +} + + +HRESULT CMultiOutStream::ReOpenStream(unsigned streamIndex) +{ + PRF(printf("\n====== %u, ReOpenStream \n", streamIndex)) + RINOK(PrepareToOpenNew()) + CVolStream &s = Streams[streamIndex]; + + FString path = GetFilePath(streamIndex); + path += s.Postfix; + + s.StreamSpec = new COutFileStream; + s.Stream = s.StreamSpec; + s.Pos = 0; + + HRESULT hres; + if (s.StreamSpec->Open_EXISTING(path)) + { + if (s.Postfix.IsEmpty()) + { + /* it's unexpected case that we open finished volume. + It can mean that the code for restriction is incorrect */ + FinalVol_WasReopen = true; + } + UInt64 realSize = 0; + hres = s.StreamSpec->GetSize(&realSize); + if (hres == S_OK) + { + if (realSize == s.RealSize) + { + PRF(printf("\n ReOpenStream OK realSize = %u\n", (unsigned)realSize)) + InsertToLinkedList(streamIndex); + return S_OK; + } + // file size was changed between Close() and ReOpen() + // we must release Stream to be consistent with linked list + hres = E_FAIL; + } + } + else + hres = GetLastError_noZero_HRESULT(); + s.Stream.Release(); + s.StreamSpec = NULL; + return hres; +} + + +/* Sets size of stream, if new size is not equal to old size (RealSize). + If stream was closed and size change is required, it reopens the stream. */ + +HRESULT CMultiOutStream::OptReOpen_and_SetSize(unsigned index, UInt64 size) +{ + CVolStream &s = Streams[index]; + if (size == s.RealSize) + return S_OK; + if (!s.Stream) + { + RINOK(ReOpenStream(index)) + } + PRF(printf("\n== %u, OptReOpen_and_SetSize, size =%u RealSize = %u\n", index, (unsigned)size, (unsigned)s.RealSize)) + // comment it to debug tail after data + return s.SetSize2(size); +} + + +/* +call Normalize_finalMode(false), if _length was changed. + for all streams starting after _length: + - it sets zero size + - it still keeps file open + Note: after _length reducing with CMultiOutStream::SetSize() we can + have very big number of empty streams at the end of Streams[] list. + And Normalize_finalMode() will runs all these empty streams of Streams[] vector. + So it can be ineffective, if we call Normalize_finalMode() many + times after big reducing of (_length). + +call Normalize_finalMode(true) to set final presentations of all streams + for all streams starting after _length: + - it sets zero size + - it removes file + - it removes CVolStream object from Streams[] vector + +Note: we don't remove zero sized first volume, if (_length == 0) +*/ + +HRESULT CMultiOutStream::Normalize_finalMode(bool finalMode) +{ + PRF(printf("\n== Normalize_finalMode: _length =%d \n", (unsigned)_length)) + + unsigned i = Streams.Size(); + + UInt64 offset = 0; + + /* At first we normalize (reduce or increase) the sizes of all existing + streams in Streams[] that can be affected by changed _length. + And we remove tailing zero-size streams, if (finalMode == true) */ + while (i != 0) + { + offset = Streams[--i].Start; // it's last item in Streams[] + // we don't want to remove first volume + if (offset < _length || i == 0) + { + const UInt64 volSize = GetVolSize_for_Stream(i); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(OptReOpen_and_SetSize(i, size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize + offset += volSize; + // _length > offset + break; + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, size)); + } + + /* we Set Size of stream to zero even for (finalMode==true), although + that stream will be deleted in next commands */ + // UPDATE_HRES(res, OptReOpen_and_SetSize(i, 0)); + RINOK(OptReOpen_and_SetSize(i, 0)) + if (finalMode) + { + RINOK(CloseStream_and_DeleteFile(i)) + /* CVolStream::Stream was released above already, and it was + removed from linked list. So we don't need to update linked list + structure, when we delete last item in Streams[] */ + Streams.DeleteBack(); + // Delete_LastStream_Records(); + } + } + + /* now we create new zero-filled streams to cover all data up to _length */ + + if (_length == 0) + return S_OK; + + // (offset) is start offset of next stream after existing Streams[] + + for (;;) + { + // _length > offset + const UInt64 volSize = GetVolSize_for_Stream(Streams.Size()); + UInt64 size = _length - offset; // (size != 0) here + if (size > volSize) + size = volSize; + RINOK(CreateNewStream(size)) + if (_length - offset <= volSize) + return S_OK; + // _length - offset > volSize) + offset += volSize; + // _length > offset + } +} + + +HRESULT CMultiOutStream::FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes) +{ + // at first we remove unused zero-sized streams after _length + HRESULT res = Normalize_finalMode(true); + numTotalVolumesRes = Streams.Size(); + FOR_VECTOR (i, Streams) + { + const HRESULT res2 = CloseStream_and_FinalRename(i); + if (res == S_OK) + res = res2; + } + if (NumListItems != 0 && res == S_OK) + res = E_FAIL; + return res; +} + + +bool CMultiOutStream::SetMTime_Final(const CFiTime &mTime) +{ + // we will set mtime only if new value differs from previous + if (!FinalVol_WasReopen && MTime_Defined && Compare_FiTime(&MTime, &mTime) == 0) + return true; + bool res = true; + FOR_VECTOR (i, Streams) + { + CVolStream &s = Streams[i]; + if (s.Stream) + { + if (!s.StreamSpec->SetMTime(&mTime)) + res = false; + } + else + { + if (!SetDirTime(GetFilePath(i), NULL, NULL, &mTime)) + res = false; + } + } + return res; +} + + +Z7_COM7F_IMF(CMultiOutStream::SetSize(UInt64 newSize)) +{ + COM_TRY_BEGIN + if ((Int64)newSize < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if (newSize > _absLimit) + { + /* big seek value was sent to SetSize() or to Seek()+Write(). + It can mean one of two situations: + 1) some incorrect code called it with big seek value. + 2) volume size was small, and we have too big number of volumes + */ + /* in Windows SetEndOfFile() can return: + ERROR_NEGATIVE_SEEK: for >= (1 << 63) + ERROR_INVALID_PARAMETER: for > (16 TiB - 64 KiB) + ERROR_DISK_FULL: for <= (16 TiB - 64 KiB) + */ + // return E_FAIL; + // return E_OUTOFMEMORY; + return E_INVALIDARG; + } + + if (newSize > _length) + { + // we don't expect such case. So we just define global restriction */ + _restrict_Global = newSize; + } + else if (newSize < _restrict_Global) + _restrict_Global = newSize; + + PRF(printf("\n== CMultiOutStream::SetSize, size =%u \n", (unsigned)newSize)) + + _length = newSize; + return Normalize_finalMode(false); + + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + COM_TRY_BEGIN + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + PRF(printf("\n -- CMultiOutStream::Write() : _absPos = %6u, size =%6u \n", + (unsigned)_absPos, (unsigned)size)) + + if (_absPos > _length) + { + // it create data only up to _absPos. + // but we still can need additional new streams, if _absPos at range of volume + RINOK(SetSize(_absPos)) + } + + while (size != 0) + { + UInt64 volSize; + { + if (_streamIndex < Sizes.Size() - 1) + { + volSize = Sizes[_streamIndex]; + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + } + else + { + volSize = Sizes[Sizes.Size() - 1]; + if (_offsetPos >= volSize) + { + const UInt64 v = _offsetPos / volSize; + if (v >= ((UInt32)(Int32)-1) - _streamIndex) + return E_INVALIDARG; + // throw 202208; + _streamIndex += (unsigned)v; + _offsetPos -= (unsigned)v * volSize; + } + if (_streamIndex >= k_NumVols_MAX) + return E_INVALIDARG; + } + } + + // (_offsetPos < volSize) here + + /* we can need to create one or more streams here, + vol_size for some streams is allowed to be 0. + Also we close some new created streams, if they are non-restricted */ + // file Size will be set later by calling Seek() with Write() + + /* the case (_absPos > _length) was processed above with SetSize(_absPos), + so here it's expected. that we can create optional zero-size streams and then _streamIndex */ + RINOK(CreateStreams_If_Required(_streamIndex)) + + CVolStream &s = Streams[_streamIndex]; + + PRF(printf("\n%d, == Write : Pos = %u, RealSize = %u size =%u \n", + _streamIndex, (unsigned)s.Pos, (unsigned)s.RealSize, size)) + + if (!s.Stream) + { + RINOK(ReOpenStream(_streamIndex)) + } + if (_offsetPos != s.Pos) + { + RINOK(s.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)) + s.Pos = _offsetPos; + } + + UInt32 curSize = size; + { + const UInt64 rem = volSize - _offsetPos; + if (curSize > rem) + curSize = (UInt32)rem; + } + // curSize != 0 + UInt32 realProcessed = 0; + + HRESULT hres = s.Stream->Write(data, curSize, &realProcessed); + + data = (const void *)((const Byte *)data + realProcessed); + size -= realProcessed; + s.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_length < _absPos) + _length = _absPos; + if (s.RealSize < _offsetPos) + s.RealSize = _offsetPos; + if (processedSize) + *processedSize += realProcessed; + + if (s.Pos == volSize) + { + bool isRestricted; + if (volSize == 0) + isRestricted = IsRestricted_Empty(s); + else + isRestricted = IsRestricted(s); + if (!isRestricted) + { + const HRESULT res2 = CloseStream_and_FinalRename(_streamIndex); + if (hres == S_OK) + hres = res2; + } + _streamIndex++; + _offsetPos = 0; + } + + RINOK(hres) + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + // break; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CMultiOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + PRF(printf("\n-- CMultiOutStream::Seek seekOrigin=%u Seek =%u\n", seekOrigin, (unsigned)offset)) + + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _absPos; break; + case STREAM_SEEK_END: offset += _length; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + if ((UInt64)offset != _absPos) + { + _absPos = (UInt64)offset; + _offsetPos = (UInt64)offset; + _streamIndex = 0; + } + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + + +// result value will be saturated to (UInt32)(Int32)-1 + +unsigned CMultiOutStream::GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const +{ + const unsigned last = Sizes.Size() - 1; + for (unsigned i = 0; i < last; i++) + { + const UInt64 size = Sizes[i]; + if (offset < size) + { + relOffset = offset; + return i; + } + offset -= size; + } + const UInt64 size = Sizes[last]; + const UInt64 v = offset / size; + if (v >= ((UInt32)(Int32)-1) - last) + return (unsigned)(int)-1; // saturation + relOffset = offset - (unsigned)v * size; + return last + (unsigned)(v); +} + + +Z7_COM7F_IMF(CMultiOutStream::SetRestriction(UInt64 begin, UInt64 end)) +{ + COM_TRY_BEGIN + + // begin = end = 0; // for debug + + PRF(printf("\n==================== CMultiOutStream::SetRestriction %u, %u\n", (unsigned)begin, (unsigned)end)) + if (begin > end) + { + // these value are FAILED values. + return E_FAIL; + // return E_INVALIDARG; + /* + // or we can ignore error with 3 ways: no change, non-restricted, saturation: + end = begin; // non-restricted + end = (UInt64)(Int64)-1; // saturation: + return S_OK; + */ + } + UInt64 b = _restrict_Begin; + UInt64 e = _restrict_End; + _restrict_Begin = begin; + _restrict_End = end; + + if (b == e) // if there were no restriction before + return S_OK; // no work to derestrict now. + + /* [b, e) is previous restricted region. So all volumes that + intersect that [b, e) region are candidats for derestriction */ + + if (begin != end) // if there is new non-empty restricted region + { + /* Now we will try to reduce or change (b) and (e) bounds + to reduce main loop that checks volumes for derestriction. + We still use one big derestriction region in main loop, although + in some cases we could have two smaller derestriction regions. + Also usually restriction region cannot move back from previous start position, + so (b <= begin) is expected here for normal cases */ + if (b == begin) // if same low bounds + b = end; // we need to derestrict only after the end of new restricted region + if (e == end) // if same high bounds + e = begin; // we need to derestrict only before the begin of new restricted region + } + + if (b > e) // || b == (UInt64)(Int64)-1 + return S_OK; + + /* Here we close finished volumes that are not restricted anymore. + We close (low number) volumes at first. */ + + UInt64 offset; + unsigned index = GetStreamIndex_for_Offset(b, offset); + + for (; index < Streams.Size(); index++) + { + { + const CVolStream &s = Streams[index]; + if (_length <= s.Start) + break; // we don't close streams after _length + // (_length > s.Start) + const UInt64 volSize = GetVolSize_for_Stream(index); + if (volSize == 0) + { + if (e < s.Start) + break; + // we don't close empty stream, if next byte [s.Start, s.Start] is restricted + if (IsRestricted_Empty(s)) + continue; + } + else + { + if (e <= s.Start) + break; + // we don't close non full streams + if (_length - s.Start < volSize) + break; + // (volSize == s.RealSize) is expected here. So no need to check it + // if (volSize != s.RealSize) break; + if (IsRestricted(s)) + continue; + } + } + RINOK(CloseStream_and_FinalRename(index)) + } + + return S_OK; + COM_TRY_END +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/MultiOutStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.h --- p7zip-rar-16.02/CPP/7zip/Common/MultiOutStream.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/MultiOutStream.h 2023-04-05 17:00:00.000000000 +0000 @@ -0,0 +1,160 @@ +// MultiOutStream.h + +#ifndef ZIP7_INC_MULTI_OUT_STREAM_H +#define ZIP7_INC_MULTI_OUT_STREAM_H + +#include "FileStreams.h" + +Z7_CLASS_IMP_COM_2( + CMultiOutStream + , IOutStream + , IStreamSetRestriction +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + Z7_CLASS_NO_COPY(CMultiOutStream) + + struct CVolStream + { + COutFileStream *StreamSpec; + CMyComPtr Stream; + UInt64 Start; // start pos of current Stream in global stream + UInt64 Pos; // pos in current Stream + UInt64 RealSize; + int Next; // next older + int Prev; // prev newer + AString Postfix; + + HRESULT SetSize2(UInt64 size) + { + const HRESULT res = Stream->SetSize(size); + if (res == SZ_OK) + RealSize = size; + return res; + } + }; + + unsigned _streamIndex; // (_streamIndex >= Stream.Size()) is allowed in some internal code + UInt64 _offsetPos; // offset relative to Streams[_streamIndex] volume. (_offsetPos >= volSize is allowed) + UInt64 _absPos; + UInt64 _length; // virtual Length + UInt64 _absLimit; + + CObjectVector Streams; + CRecordVector Sizes; + + UInt64 _restrict_Begin; + UInt64 _restrict_End; + UInt64 _restrict_Global; + + unsigned NumOpenFiles_AllowedMax; + + // ----- Double Linked List ----- + + unsigned NumListItems; + int Head; // newest + int Tail; // oldest + + void InitLinkedList() + { + Head = -1; + Tail = -1; + NumListItems = 0; + } + + void InsertToLinkedList(unsigned index) + { + { + CVolStream &node = Streams[index]; + node.Next = Head; + node.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; + } + + void RemoveFromLinkedList(unsigned index) + { + CVolStream &s = Streams[index]; + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; + } + + /* + void Delete_LastStream_Records() + { + if (Streams.Back().Stream) + RemoveFromLinkedList(Streams.Size() - 1); + Streams.DeleteBack(); + } + */ + + UInt64 GetVolSize_for_Stream(unsigned i) const + { + const unsigned last = Sizes.Size() - 1; + return Sizes[i < last ? i : last]; + } + UInt64 GetGlobalOffset_for_NewStream() const + { + return Streams.Size() == 0 ? 0: + Streams.Back().Start + + GetVolSize_for_Stream(Streams.Size() - 1); + } + unsigned GetStreamIndex_for_Offset(UInt64 offset, UInt64 &relOffset) const; + bool IsRestricted(const CVolStream &s) const; + bool IsRestricted_Empty(const CVolStream &s) const + { + // (s) must be stream that has (VolSize == 0). + // we treat empty stream as restricted, if next byte is restricted. + if (s.Start < _restrict_Global) + return true; + return + (_restrict_Begin != _restrict_End) + && (_restrict_Begin <= s.Start) + && (_restrict_Begin == s.Start || _restrict_End > s.Start); + } + // bool IsRestricted_for_Close(unsigned index) const; + FString GetFilePath(unsigned index); + + HRESULT CloseStream(unsigned index); + HRESULT CloseStream_and_DeleteFile(unsigned index); + HRESULT CloseStream_and_FinalRename(unsigned index); + + HRESULT PrepareToOpenNew(); + HRESULT CreateNewStream(UInt64 newSize); + HRESULT CreateStreams_If_Required(unsigned streamIndex); + HRESULT ReOpenStream(unsigned streamIndex); + HRESULT OptReOpen_and_SetSize(unsigned index, UInt64 size); + + HRESULT Normalize_finalMode(bool finalMode); +public: + FString Prefix; + CFiTime MTime; + bool MTime_Defined; + bool FinalVol_WasReopen; + bool NeedDelete; + + CMultiOutStream() {} + ~CMultiOutStream(); + void Init(const CRecordVector &sizes); + bool SetMTime_Final(const CFiTime &mTime); + UInt64 GetSize() const { return _length; } + /* it makes final flushing, closes open files and renames to final name if required + but it still keeps Streams array of all closed files. + So we still can delete all files later, if required */ + HRESULT FinalFlush_and_CloseFiles(unsigned &numTotalVolumesRes); + // Destruct object without exceptions + HRESULT Destruct(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OffsetStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.cpp --- p7zip-rar-16.02/CPP/7zip/Common/OffsetStream.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,39 +1,37 @@ -// OffsetStream.cpp - -#include "StdAfx.h" - -#include "../../Common/Defs.h" - -#include "OffsetStream.h" - -HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) -{ - _offset = offset; - _stream = stream; - return _stream->Seek(offset, STREAM_SEEK_SET, NULL); -} - -STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - return _stream->Write(data, size, processedSize); -} - -STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - UInt64 absoluteNewPosition; - if (seekOrigin == STREAM_SEEK_SET) - { - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - offset += _offset; - } - HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); - if (newPosition) - *newPosition = absoluteNewPosition - _offset; - return result; -} - -STDMETHODIMP COffsetOutStream::SetSize(UInt64 newSize) -{ - return _stream->SetSize(_offset + newSize); -} +// OffsetStream.cpp + +#include "StdAfx.h" + +#include "OffsetStream.h" + +HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) +{ + _offset = offset; + _stream = stream; + return _stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); +} + +Z7_COM7F_IMF(COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + return _stream->Write(data, size, processedSize); +} + +Z7_COM7F_IMF(COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (seekOrigin == STREAM_SEEK_SET) + { + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + offset += _offset; + } + UInt64 absoluteNewPosition = 0; // =0 for gcc-10 + const HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); + if (newPosition) + *newPosition = absoluteNewPosition - _offset; + return result; +} + +Z7_COM7F_IMF(COffsetOutStream::SetSize(UInt64 newSize)) +{ + return _stream->SetSize(_offset + newSize); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OffsetStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.h --- p7zip-rar-16.02/CPP/7zip/Common/OffsetStream.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OffsetStream.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,26 +1,22 @@ -// OffsetStream.h - -#ifndef __OFFSET_STREAM_H -#define __OFFSET_STREAM_H - -#include "../../Common/MyCom.h" - -#include "../IStream.h" - -class COffsetOutStream: - public IOutStream, - public CMyUnknownImp -{ - UInt64 _offset; - CMyComPtr _stream; -public: - HRESULT Init(IOutStream *stream, UInt64 offset); - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); -}; - -#endif +// OffsetStream.h + +#ifndef ZIP7_INC_OFFSET_STREAM_H +#define ZIP7_INC_OFFSET_STREAM_H + +#include "../../Common/MyCom.h" + +#include "../IStream.h" + +Z7_CLASS_IMP_NOQIB_1( + COffsetOutStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + CMyComPtr _stream; + UInt64 _offset; +public: + HRESULT Init(IOutStream *stream, UInt64 offset); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OutBuffer.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.cpp --- p7zip-rar-16.02/CPP/7zip/Common/OutBuffer.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,111 +1,111 @@ -// OutBuffer.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "OutBuffer.h" - -bool COutBuffer::Create(UInt32 bufSize) throw() -{ - const UInt32 kMinBlockSize = 1; - if (bufSize < kMinBlockSize) - bufSize = kMinBlockSize; - if (_buf != 0 && _bufSize == bufSize) - return true; - Free(); - _bufSize = bufSize; - _buf = (Byte *)::MidAlloc(bufSize); - return (_buf != 0); -} - -void COutBuffer::Free() throw() -{ - ::MidFree(_buf); - _buf = 0; -} - -void COutBuffer::Init() throw() -{ - _streamPos = 0; - _limitPos = _bufSize; - _pos = 0; - _processedSize = 0; - _overDict = false; - #ifdef _NO_EXCEPTIONS - ErrorCode = S_OK; - #endif -} - -UInt64 COutBuffer::GetProcessedSize() const throw() -{ - UInt64 res = _processedSize + _pos - _streamPos; - if (_streamPos > _pos) - res += _bufSize; - return res; -} - - -HRESULT COutBuffer::FlushPart() throw() -{ - // _streamPos < _bufSize - UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); - HRESULT result = S_OK; - #ifdef _NO_EXCEPTIONS - result = ErrorCode; - #endif - if (_buf2 != 0) - { - memcpy(_buf2, _buf + _streamPos, size); - _buf2 += size; - } - - if (_stream != 0 - #ifdef _NO_EXCEPTIONS - && (ErrorCode == S_OK) - #endif - ) - { - UInt32 processedSize = 0; - result = _stream->Write(_buf + _streamPos, size, &processedSize); - size = processedSize; - } - _streamPos += size; - if (_streamPos == _bufSize) - _streamPos = 0; - if (_pos == _bufSize) - { - _overDict = true; - _pos = 0; - } - _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize; - _processedSize += size; - return result; -} - -HRESULT COutBuffer::Flush() throw() -{ - #ifdef _NO_EXCEPTIONS - if (ErrorCode != S_OK) - return ErrorCode; - #endif - - while (_streamPos != _pos) - { - HRESULT result = FlushPart(); - if (result != S_OK) - return result; - } - return S_OK; -} - -void COutBuffer::FlushWithCheck() -{ - HRESULT result = Flush(); - #ifdef _NO_EXCEPTIONS - ErrorCode = result; - #else - if (result != S_OK) - throw COutBufferException(result); - #endif -} +// OutBuffer.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "OutBuffer.h" + +bool COutBuffer::Create(UInt32 bufSize) throw() +{ + const UInt32 kMinBlockSize = 1; + if (bufSize < kMinBlockSize) + bufSize = kMinBlockSize; + if (_buf && _bufSize == bufSize) + return true; + Free(); + _bufSize = bufSize; + _buf = (Byte *)::MidAlloc(bufSize); + return (_buf != NULL); +} + +void COutBuffer::Free() throw() +{ + ::MidFree(_buf); + _buf = NULL; +} + +void COutBuffer::Init() throw() +{ + _streamPos = 0; + _limitPos = _bufSize; + _pos = 0; + _processedSize = 0; + _overDict = false; + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} + +UInt64 COutBuffer::GetProcessedSize() const throw() +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufSize; + return res; +} + + +HRESULT COutBuffer::FlushPart() throw() +{ + // _streamPos < _bufSize + UInt32 size = (_streamPos >= _pos) ? (_bufSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef Z7_NO_EXCEPTIONS + result = ErrorCode; + #endif + if (_buf2) + { + memcpy(_buf2, _buf + _streamPos, size); + _buf2 += size; + } + + if (_stream + #ifdef Z7_NO_EXCEPTIONS + && (ErrorCode == S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buf + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + if (_streamPos == _bufSize) + _streamPos = 0; + if (_pos == _bufSize) + { + _overDict = true; + _pos = 0; + } + _limitPos = (_streamPos > _pos) ? _streamPos : _bufSize; + _processedSize += size; + return result; +} + +HRESULT COutBuffer::Flush() throw() +{ + #ifdef Z7_NO_EXCEPTIONS + if (ErrorCode != S_OK) + return ErrorCode; + #endif + + while (_streamPos != _pos) + { + const HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + const HRESULT result = Flush(); + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = result; + #else + if (result != S_OK) + throw COutBufferException(result); + #endif +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OutBuffer.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.h --- p7zip-rar-16.02/CPP/7zip/Common/OutBuffer.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutBuffer.h 2025-02-23 14:00:00.000000000 +0000 @@ -1,63 +1,133 @@ -// OutBuffer.h - -#ifndef __OUT_BUFFER_H -#define __OUT_BUFFER_H - -#include "../IStream.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyException.h" - -#ifndef _NO_EXCEPTIONS -struct COutBufferException: public CSystemException -{ - COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} -}; -#endif - -class COutBuffer -{ -protected: - Byte *_buf; - UInt32 _pos; - UInt32 _limitPos; - UInt32 _streamPos; - UInt32 _bufSize; - ISequentialOutStream *_stream; - UInt64 _processedSize; - Byte *_buf2; - bool _overDict; - - HRESULT FlushPart() throw(); -public: - #ifdef _NO_EXCEPTIONS - HRESULT ErrorCode; - #endif - - COutBuffer(): _buf(0), _pos(0), _stream(0), _buf2(0) {} - ~COutBuffer() { Free(); } - - bool Create(UInt32 bufSize) throw(); - void Free() throw(); - - void SetMemStream(Byte *buf) { _buf2 = buf; } - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void Init() throw(); - HRESULT Flush() throw(); - void FlushWithCheck(); - - void WriteByte(Byte b) - { - _buf[_pos++] = b; - if (_pos == _limitPos) - FlushWithCheck(); - } - void WriteBytes(const void *data, size_t size) - { - for (size_t i = 0; i < size; i++) - WriteByte(((const Byte *)data)[i]); - } - - UInt64 GetProcessedSize() const throw(); -}; - -#endif +// OutBuffer.h + +#ifndef ZIP7_INC_OUT_BUFFER_H +#define ZIP7_INC_OUT_BUFFER_H + +#include "../IStream.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyException.h" + +#ifndef Z7_NO_EXCEPTIONS +struct COutBufferException: public CSystemException +{ + COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} +}; +#endif + +class COutBuffer +{ +protected: + Byte *_buf; + UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; + UInt32 _bufSize; + ISequentialOutStream *_stream; + UInt64 _processedSize; + Byte *_buf2; + bool _overDict; + + HRESULT FlushPart() throw(); +public: + #ifdef Z7_NO_EXCEPTIONS + HRESULT ErrorCode; + #endif + + COutBuffer(): _buf(NULL), _pos(0), _stream(NULL), _buf2(NULL) {} + ~COutBuffer() { Free(); } + + bool Create(UInt32 bufSize) throw(); + void Free() throw(); + + void SetMemStream(Byte *buf) { _buf2 = buf; } + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init() throw(); + HRESULT Flush() throw(); + void FlushWithCheck(); + + Z7_FORCE_INLINE + void WriteByte(Byte b) + { + UInt32 pos = _pos; + _buf[pos] = b; + pos++; + _pos = pos; + if (pos == _limitPos) + FlushWithCheck(); + } + + void WriteBytes(const void *data, size_t size) + { + while (size) + { + UInt32 pos = _pos; + size_t cur = (size_t)(_limitPos - pos); + if (cur >= size) + cur = size; + size -= cur; + Byte *dest = _buf + pos; + pos += (UInt32)cur; + _pos = pos; +#if 0 + memcpy(dest, data, cur); + data = (const void *)((const Byte *)data + cur); +#else + const Byte * const lim = (const Byte *)data + cur; + do + { + *dest++ = *(const Byte *)data; + data = (const void *)((const Byte *)data + 1); + } + while (data != lim); +#endif + if (pos == _limitPos) + FlushWithCheck(); + } + } + + Byte *GetOutBuffer(size_t &avail) + { + const UInt32 pos = _pos; + avail = (size_t)(_limitPos - pos); + return _buf + pos; + } + + void SkipWrittenBytes(size_t num) + { + const UInt32 pos = _pos; + const UInt32 rem = _limitPos - pos; + if (rem > num) + { + _pos = pos + (UInt32)num; + return; + } + // (rem <= num) + // the caller must not call it with (rem < num) + // so (rem == num) + _pos = _limitPos; + FlushWithCheck(); + } + /* + void WriteBytesBig(const void *data, size_t size) + { + while (size) + { + UInt32 pos = _pos; + UInt32 rem = _limitPos - pos; + if (rem > size) + { + _pos = pos + size; + memcpy(_buf + pos, data, size); + return; + } + memcpy(_buf + pos, data, rem); + _pos = pos + rem; + FlushWithCheck(); + } + } + */ + + UInt64 GetProcessedSize() const throw(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OutMemStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.cpp --- p7zip-rar-16.02/CPP/7zip/Common/OutMemStream.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,142 +1,158 @@ -// OutMemStream.cpp - -#include "StdAfx.h" - -#include "OutMemStream.h" - -void COutMemStream::Free() -{ - Blocks.Free(_memManager); - Blocks.LockMode = true; -} - -void COutMemStream::Init() -{ - WriteToRealStreamEvent.Reset(); - _unlockEventWasSent = false; - _realStreamMode = false; - Free(); - _curBlockPos = 0; - _curBlockIndex = 0; -} - -void COutMemStream::DetachData(CMemLockBlocks &blocks) -{ - Blocks.Detach(blocks, _memManager); - Free(); -} - - -HRESULT COutMemStream::WriteToRealStream() -{ - RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); - Blocks.Free(_memManager); - return S_OK; -} - -STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (_realStreamMode) - return OutSeqStream->Write(data, size, processedSize); - if (processedSize != 0) - *processedSize = 0; - while (size != 0) - { - if (_curBlockIndex < Blocks.Blocks.Size()) - { - Byte *p = (Byte *)Blocks.Blocks[_curBlockIndex] + _curBlockPos; - size_t curSize = _memManager->GetBlockSize() - _curBlockPos; - if (size < curSize) - curSize = size; - memcpy(p, data, curSize); - if (processedSize != 0) - *processedSize += (UInt32)curSize; - data = (const void *)((const Byte *)data + curSize); - size -= (UInt32)curSize; - _curBlockPos += curSize; - - UInt64 pos64 = GetPos(); - if (pos64 > Blocks.TotalSize) - Blocks.TotalSize = pos64; - if (_curBlockPos == _memManager->GetBlockSize()) - { - _curBlockIndex++; - _curBlockPos = 0; - } - continue; - } - HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore }; - DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE); - switch (waitResult) - { - case (WAIT_OBJECT_0 + 0): - return StopWriteResult; - case (WAIT_OBJECT_0 + 1): - { - _realStreamMode = true; - RINOK(WriteToRealStream()); - UInt32 processedSize2; - HRESULT res = OutSeqStream->Write(data, size, &processedSize2); - if (processedSize != 0) - *processedSize += processedSize2; - return res; - } - /* - case (WAIT_OBJECT_0 + 2): - { - // it has bug: no write. - if (!Blocks.SwitchToNoLockMode(_memManager)) - return E_FAIL; - break; - } - */ - case (WAIT_OBJECT_0 + 2): - break; - default: - return E_FAIL; - } - Blocks.Blocks.Add(_memManager->AllocateBlock()); - if (Blocks.Blocks.Back() == 0) - return E_FAIL; - } - return S_OK; -} - -STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (_realStreamMode) - { - if (!OutStream) - return E_FAIL; - return OutStream->Seek(offset, seekOrigin, newPosition); - } - if (seekOrigin == STREAM_SEEK_CUR) - { - if (offset != 0) - return E_NOTIMPL; - } - else if (seekOrigin == STREAM_SEEK_SET) - { - if (offset != 0) - return E_NOTIMPL; - _curBlockIndex = 0; - _curBlockPos = 0; - } - else - return E_NOTIMPL; - if (newPosition) - *newPosition = GetPos(); - return S_OK; -} - -STDMETHODIMP COutMemStream::SetSize(UInt64 newSize) -{ - if (_realStreamMode) - { - if (!OutStream) - return E_FAIL; - return OutStream->SetSize(newSize); - } - Blocks.TotalSize = newSize; - return S_OK; -} +// OutMemStream.cpp + +#include "StdAfx.h" + +// #include + +#include "OutMemStream.h" + +void COutMemStream::Free() +{ + Blocks.Free(_memManager); + Blocks.LockMode = true; +} + +void COutMemStream::Init() +{ + WriteToRealStreamEvent.Reset(); + _unlockEventWasSent = false; + _realStreamMode = false; + Free(); + _curBlockPos = 0; + _curBlockIndex = 0; +} + +void COutMemStream::DetachData(CMemLockBlocks &blocks) +{ + Blocks.Detach(blocks, _memManager); + Free(); +} + + +HRESULT COutMemStream::WriteToRealStream() +{ + RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)) + Blocks.Free(_memManager); + return S_OK; +} + + +Z7_COM7F_IMF(COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (_realStreamMode) + return OutSeqStream->Write(data, size, processedSize); + if (processedSize) + *processedSize = 0; + while (size != 0) + { + if (_curBlockIndex < Blocks.Blocks.Size()) + { + Byte *p = (Byte *)Blocks.Blocks[_curBlockIndex] + _curBlockPos; + size_t curSize = _memManager->GetBlockSize() - _curBlockPos; + if (size < curSize) + curSize = size; + memcpy(p, data, curSize); + if (processedSize) + *processedSize += (UInt32)curSize; + data = (const void *)((const Byte *)data + curSize); + size -= (UInt32)curSize; + _curBlockPos += curSize; + + const UInt64 pos64 = GetPos(); + if (pos64 > Blocks.TotalSize) + Blocks.TotalSize = pos64; + if (_curBlockPos == _memManager->GetBlockSize()) + { + _curBlockIndex++; + _curBlockPos = 0; + } + continue; + } + + const NWindows::NSynchronization::CHandle_WFMO events[3] = + { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore }; + const DWORD waitResult = NWindows::NSynchronization::WaitForMultiObj_Any_Infinite( + ((Blocks.LockMode /* && _memManager->Semaphore.IsCreated() */) ? 3 : 2), events); + + // printf("\n 1- outMemStream %d\n", waitResult - WAIT_OBJECT_0); + + switch (waitResult) + { + case (WAIT_OBJECT_0 + 0): + return StopWriteResult; + case (WAIT_OBJECT_0 + 1): + { + _realStreamMode = true; + RINOK(WriteToRealStream()) + UInt32 processedSize2; + const HRESULT res = OutSeqStream->Write(data, size, &processedSize2); + if (processedSize) + *processedSize += processedSize2; + return res; + } + case (WAIT_OBJECT_0 + 2): + { + // it has bug: no write. + /* + if (!Blocks.SwitchToNoLockMode(_memManager)) + return E_FAIL; + */ + break; + } + default: + { + if (waitResult == WAIT_FAILED) + { + const DWORD res = ::GetLastError(); + if (res != 0) + return HRESULT_FROM_WIN32(res); + } + return E_FAIL; + } + } + void *p = _memManager->AllocateBlock(); + if (!p) + return E_FAIL; + Blocks.Blocks.Add(p); + } + return S_OK; +} + +Z7_COM7F_IMF(COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->Seek(offset, seekOrigin, newPosition); + } + if (seekOrigin == STREAM_SEEK_CUR) + { + if (offset != 0) + return E_NOTIMPL; + } + else if (seekOrigin == STREAM_SEEK_SET) + { + if (offset != 0) + return E_NOTIMPL; + _curBlockIndex = 0; + _curBlockPos = 0; + } + else + return E_NOTIMPL; + if (newPosition) + *newPosition = GetPos(); + return S_OK; +} + +Z7_COM7F_IMF(COutMemStream::SetSize(UInt64 newSize)) +{ + if (_realStreamMode) + { + if (!OutStream) + return E_FAIL; + return OutStream->SetSize(newSize); + } + Blocks.TotalSize = newSize; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/OutMemStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.h --- p7zip-rar-16.02/CPP/7zip/Common/OutMemStream.h 2015-01-05 20:54:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/OutMemStream.h 2023-09-06 10:00:00.000000000 +0000 @@ -1,97 +1,104 @@ -// OutMemStream.h - -#ifndef __OUT_MEM_STREAM_H -#define __OUT_MEM_STREAM_H - -#include "../../Common/MyCom.h" - -#include "MemBlocks.h" - -class COutMemStream: - public IOutStream, - public CMyUnknownImp -{ - CMemBlockManagerMt *_memManager; - unsigned _curBlockIndex; - size_t _curBlockPos; - bool _realStreamMode; - - bool _unlockEventWasSent; - NWindows::NSynchronization::CAutoResetEventWFMO StopWritingEvent; - NWindows::NSynchronization::CAutoResetEventWFMO WriteToRealStreamEvent; - // NWindows::NSynchronization::CAutoResetEvent NoLockEvent; - - HRESULT StopWriteResult; - CMemLockBlocks Blocks; - - UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } - - CMyComPtr OutSeqStream; - CMyComPtr OutStream; - -public: - - HRes CreateEvents(NWindows::NSynchronization::CSynchro *sync) - { - RINOK(StopWritingEvent.CreateIfNotCreated(sync)); - return WriteToRealStreamEvent.CreateIfNotCreated(sync); - } - - void SetOutStream(IOutStream *outStream) - { - OutStream = outStream; - OutSeqStream = outStream; - } - - void SetSeqOutStream(ISequentialOutStream *outStream) - { - OutStream = NULL; - OutSeqStream = outStream; - } - - void ReleaseOutStream() - { - OutStream.Release(); - OutSeqStream.Release(); - } - - COutMemStream(CMemBlockManagerMt *memManager): _memManager(memManager) { } - - ~COutMemStream() { Free(); } - void Free(); - - void Init(); - HRESULT WriteToRealStream(); - - void DetachData(CMemLockBlocks &blocks); - - bool WasUnlockEventSent() const { return _unlockEventWasSent; } - - void SetRealStreamMode() - { - _unlockEventWasSent = true; - WriteToRealStreamEvent.Set(); - } - - /* - void SetNoLockMode() - { - _unlockEventWasSent = true; - NoLockEvent.Set(); - } - */ - - void StopWriting(HRESULT res) - { - StopWriteResult = res; - StopWritingEvent.Set(); - } - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); -}; - -#endif +// OutMemStream.h + +#ifndef ZIP7_INC_OUT_MEM_STREAM_H +#define ZIP7_INC_OUT_MEM_STREAM_H + +#include "../../Common/MyCom.h" + +#include "MemBlocks.h" + +Z7_CLASS_IMP_NOQIB_1( + COutMemStream + , IOutStream +) + Z7_IFACE_COM7_IMP(ISequentialOutStream) + + CMemBlockManagerMt *_memManager; + size_t _curBlockPos; + unsigned _curBlockIndex; + bool _realStreamMode; + + bool _unlockEventWasSent; + NWindows::NSynchronization::CAutoResetEvent_WFMO StopWritingEvent; + NWindows::NSynchronization::CAutoResetEvent_WFMO WriteToRealStreamEvent; + // NWindows::NSynchronization::CAutoResetEvent NoLockEvent; + + HRESULT StopWriteResult; + CMemLockBlocks Blocks; + + CMyComPtr OutSeqStream; + CMyComPtr OutStream; + + UInt64 GetPos() const { return (UInt64)_curBlockIndex * _memManager->GetBlockSize() + _curBlockPos; } + +public: + + HRESULT CreateEvents(SYNC_PARAM_DECL(synchro)) + { + WRes wres = StopWritingEvent.CreateIfNotCreated_Reset(SYNC_WFMO(synchro)); + if (wres == 0) + wres = WriteToRealStreamEvent.CreateIfNotCreated_Reset(SYNC_WFMO(synchro)); + return HRESULT_FROM_WIN32(wres); + } + + void SetOutStream(IOutStream *outStream) + { + OutStream = outStream; + OutSeqStream = outStream; + } + + void SetSeqOutStream(ISequentialOutStream *outStream) + { + OutStream = NULL; + OutSeqStream = outStream; + } + + void ReleaseOutStream() + { + OutStream.Release(); + OutSeqStream.Release(); + } + + COutMemStream(CMemBlockManagerMt *memManager): + _memManager(memManager) + { + /* + #ifndef _WIN32 + StopWritingEvent._sync = + WriteToRealStreamEvent._sync = &memManager->Synchro; + #endif + */ + } + + ~COutMemStream() { Free(); } + void Free(); + + void Init(); + HRESULT WriteToRealStream(); + + void DetachData(CMemLockBlocks &blocks); + + bool WasUnlockEventSent() const { return _unlockEventWasSent; } + + void SetRealStreamMode() + { + _unlockEventWasSent = true; + WriteToRealStreamEvent.Set(); + } + + /* + void SetNoLockMode() + { + _unlockEventWasSent = true; + NoLockEvent.Set(); + } + */ + + void StopWriting(HRESULT res) + { + StopWriteResult = res; + StopWritingEvent.Set(); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/ProgressMt.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.cpp --- p7zip-rar-16.02/CPP/7zip/Common/ProgressMt.cpp 2008-08-05 09:48:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,53 +1,53 @@ -// ProgressMt.h - -#include "StdAfx.h" - -#include "ProgressMt.h" - -void CMtCompressProgressMixer::Init(int numItems, ICompressProgressInfo *progress) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - InSizes.Clear(); - OutSizes.Clear(); - for (int i = 0; i < numItems; i++) - { - InSizes.Add(0); - OutSizes.Add(0); - } - TotalInSize = 0; - TotalOutSize = 0; - _progress = progress; -} - -void CMtCompressProgressMixer::Reinit(int index) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - InSizes[index] = 0; - OutSizes[index] = 0; -} - -HRESULT CMtCompressProgressMixer::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); - if (inSize != 0) - { - UInt64 diff = *inSize - InSizes[index]; - InSizes[index] = *inSize; - TotalInSize += diff; - } - if (outSize != 0) - { - UInt64 diff = *outSize - OutSizes[index]; - OutSizes[index] = *outSize; - TotalOutSize += diff; - } - if (_progress) - return _progress->SetRatioInfo(&TotalInSize, &TotalOutSize); - return S_OK; -} - - -STDMETHODIMP CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - return _progress->SetRatioInfo(_index, inSize, outSize); -} +// ProgressMt.h + +#include "StdAfx.h" + +#include "ProgressMt.h" + +void CMtCompressProgressMixer::Init(unsigned numItems, ICompressProgressInfo *progress) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes.Clear(); + OutSizes.Clear(); + for (unsigned i = 0; i < numItems; i++) + { + InSizes.Add(0); + OutSizes.Add(0); + } + TotalInSize = 0; + TotalOutSize = 0; + _progress = progress; +} + +void CMtCompressProgressMixer::Reinit(unsigned index) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + InSizes[index] = 0; + OutSizes[index] = 0; +} + +HRESULT CMtCompressProgressMixer::SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize) +{ + NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection); + if (inSize) + { + const UInt64 diff = *inSize - InSizes[index]; + InSizes[index] = *inSize; + TotalInSize += diff; + } + if (outSize) + { + const UInt64 diff = *outSize - OutSizes[index]; + OutSizes[index] = *outSize; + TotalOutSize += diff; + } + if (_progress) + return _progress->SetRatioInfo(&TotalInSize, &TotalOutSize); + return S_OK; +} + + +Z7_COM7F_IMF(CMtCompressProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + return _progress->SetRatioInfo(_index, inSize, outSize); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/ProgressMt.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.h --- p7zip-rar-16.02/CPP/7zip/Common/ProgressMt.h 2008-08-14 09:11:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressMt.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,46 +1,43 @@ -// ProgressMt.h - -#ifndef __PROGRESSMT_H -#define __PROGRESSMT_H - -#include "../../Common/MyCom.h" -#include "../../Common/MyVector.h" -#include "../../Windows/Synchronization.h" - -#include "../ICoder.h" -#include "../IProgress.h" - -class CMtCompressProgressMixer -{ - CMyComPtr _progress; - CRecordVector InSizes; - CRecordVector OutSizes; - UInt64 TotalInSize; - UInt64 TotalOutSize; -public: - NWindows::NSynchronization::CCriticalSection CriticalSection; - void Init(int numItems, ICompressProgressInfo *progress); - void Reinit(int index); - HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize); -}; - -class CMtCompressProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMtCompressProgressMixer *_progress; - int _index; -public: - void Init(CMtCompressProgressMixer *progress, int index) - { - _progress = progress; - _index = index; - } - void Reinit() { _progress->Reinit(_index); } - - MY_UNKNOWN_IMP - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -#endif +// ProgressMt.h + +#ifndef ZIP7_INC_PROGRESSMT_H +#define ZIP7_INC_PROGRESSMT_H + +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" +#include "../../Windows/Synchronization.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +class CMtCompressProgressMixer +{ + CMyComPtr _progress; + CRecordVector InSizes; + CRecordVector OutSizes; + UInt64 TotalInSize; + UInt64 TotalOutSize; +public: + NWindows::NSynchronization::CCriticalSection CriticalSection; + void Init(unsigned numItems, ICompressProgressInfo *progress); + void Reinit(unsigned index); + HRESULT SetRatioInfo(unsigned index, const UInt64 *inSize, const UInt64 *outSize); +}; + + +Z7_CLASS_IMP_NOQIB_1( + CMtCompressProgress + , ICompressProgressInfo +) + unsigned _index; + CMtCompressProgressMixer *_progress; +public: + void Init(CMtCompressProgressMixer *progress, unsigned index) + { + _progress = progress; + _index = index; + } + void Reinit() { _progress->Reinit(_index); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/ProgressUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.cpp --- p7zip-rar-16.02/CPP/7zip/Common/ProgressUtils.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,51 +1,51 @@ -// ProgressUtils.cpp - -#include "StdAfx.h" - -#include "ProgressUtils.h" - -CLocalProgress::CLocalProgress(): - ProgressOffset(0), - InSize(0), - OutSize(0), - SendRatio(true), - SendProgress(true) - {} - -void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) -{ - _ratioProgress.Release(); - _progress = progress; - _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress); - _inSizeIsMain = inSizeIsMain; -} - -STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - UInt64 inSize2 = InSize; - UInt64 outSize2 = OutSize; - - if (inSize) - inSize2 += (*inSize); - if (outSize) - outSize2 += (*outSize); - - if (SendRatio && _ratioProgress) - { - RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)); - } - - if (SendProgress) - { - inSize2 += ProgressOffset; - outSize2 += ProgressOffset; - return _progress->SetCompleted(_inSizeIsMain ? &inSize2 : &outSize2); - } - - return S_OK; -} - -HRESULT CLocalProgress::SetCur() -{ - return SetRatioInfo(NULL, NULL); -} +// ProgressUtils.cpp + +#include "StdAfx.h" + +#include "ProgressUtils.h" + +CLocalProgress::CLocalProgress(): + SendRatio(true), + SendProgress(true), + ProgressOffset(0), + InSize(0), + OutSize(0) + {} + +void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain) +{ + _ratioProgress.Release(); + _progress = progress; + _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress); + _inSizeIsMain = inSizeIsMain; +} + +Z7_COM7F_IMF(CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + UInt64 inSize2 = InSize; + UInt64 outSize2 = OutSize; + + if (inSize) + inSize2 += (*inSize); + if (outSize) + outSize2 += (*outSize); + + if (SendRatio && _ratioProgress) + { + RINOK(_ratioProgress->SetRatioInfo(&inSize2, &outSize2)) + } + + if (SendProgress) + { + inSize2 += ProgressOffset; + outSize2 += ProgressOffset; + return _progress->SetCompleted(_inSizeIsMain ? &inSize2 : &outSize2); + } + + return S_OK; +} + +HRESULT CLocalProgress::SetCur() +{ + return SetRatioInfo(NULL, NULL); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/ProgressUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.h --- p7zip-rar-16.02/CPP/7zip/Common/ProgressUtils.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/ProgressUtils.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,35 +1,33 @@ -// ProgressUtils.h - -#ifndef __PROGRESS_UTILS_H -#define __PROGRESS_UTILS_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" -#include "../IProgress.h" - -class CLocalProgress: - public ICompressProgressInfo, - public CMyUnknownImp -{ - CMyComPtr _progress; - CMyComPtr _ratioProgress; - bool _inSizeIsMain; -public: - UInt64 ProgressOffset; - UInt64 InSize; - UInt64 OutSize; - bool SendRatio; - bool SendProgress; - - CLocalProgress(); - - void Init(IProgress *progress, bool inSizeIsMain); - HRESULT SetCur(); - - MY_UNKNOWN_IMP1(ICompressProgressInfo) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -#endif +// ProgressUtils.h + +#ifndef ZIP7_INC_PROGRESS_UTILS_H +#define ZIP7_INC_PROGRESS_UTILS_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IProgress.h" + +Z7_CLASS_IMP_COM_1( + CLocalProgress + , ICompressProgressInfo +) +public: + bool SendRatio; + bool SendProgress; +private: + bool _inSizeIsMain; + CMyComPtr _progress; + CMyComPtr _ratioProgress; +public: + UInt64 ProgressOffset; + UInt64 InSize; + UInt64 OutSize; + + CLocalProgress(); + + void Init(IProgress *progress, bool inSizeIsMain); + HRESULT SetCur(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/PropId.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/PropId.cpp --- p7zip-rar-16.02/CPP/7zip/Common/PropId.cpp 2015-09-01 18:04:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/PropId.cpp 2022-11-05 14:00:00.000000000 +0000 @@ -1,108 +1,117 @@ -// PropId.cpp - -#include "StdAfx.h" - -#include "../../Common/MyWindows.h" - -#include "../PropID.h" - -// VARTYPE -const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] = -{ - VT_EMPTY, - VT_UI4, - VT_UI4, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_BOOL, - VT_UI8, - VT_UI8, - VT_UI4, - VT_FILETIME, - VT_FILETIME, - VT_FILETIME, - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_UI4, - VT_UI4, - VT_BSTR, - VT_BOOL, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_UI8, - VT_BSTR, - VT_UI8, - VT_BSTR, - VT_UI8, - VT_UI8, - VT_BSTR, // or VT_UI8 kpidUnpackVer - VT_UI4, // or VT_UI8 kpidVolume - VT_BOOL, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI4, - VT_BOOL, - VT_BOOL, - VT_BSTR, - VT_UI8, - VT_UI8, - VT_UI4, // kpidChecksum - VT_BSTR, - VT_UI8, - VT_BSTR, // or VT_UI8 kpidId - VT_BSTR, - VT_BSTR, - VT_UI4, - VT_UI4, - VT_BSTR, - VT_BSTR, - VT_UI8, - VT_UI8, - VT_UI4, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_BSTR, // kpidNtSecure - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_BSTR, // SHA-1 - VT_BSTR, // SHA-256 - VT_BSTR, - VT_UI8, - VT_UI4, - VT_UI4, - VT_BSTR, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI8, - VT_UI8, - VT_BSTR, - VT_BSTR, - VT_BSTR, - VT_BOOL, - VT_BOOL, - VT_BOOL, - VT_UI8, - VT_UI8, - VT_BSTR, // kpidNtReparse - VT_BSTR, - VT_UI8, - VT_UI8, - VT_BOOL, - VT_BSTR, - VT_BSTR -}; +// PropId.cpp + +#include "StdAfx.h" + +#include "../../Common/MyWindows.h" + +#include "../PropID.h" + +// VARTYPE +const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED] = +{ + VT_EMPTY, + VT_UI4, + VT_UI4, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BOOL, + VT_UI8, + VT_UI8, + VT_UI4, + VT_FILETIME, + VT_FILETIME, + VT_FILETIME, + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_UI4, + VT_UI4, + VT_BSTR, + VT_BOOL, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_UI8, + VT_BSTR, + VT_UI8, + VT_BSTR, + VT_UI8, + VT_UI8, + VT_BSTR, // or VT_UI8 kpidUnpackVer + VT_UI4, // or VT_UI8 kpidVolume + VT_BOOL, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI4, + VT_BOOL, + VT_BOOL, + VT_BSTR, + VT_UI8, + VT_UI8, + VT_UI4, // kpidChecksum + VT_BSTR, + VT_UI8, + VT_BSTR, // or VT_UI8 kpidId + VT_BSTR, + VT_BSTR, + VT_UI4, + VT_UI4, + VT_BSTR, + VT_BSTR, + VT_UI8, + VT_UI8, + VT_UI4, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BSTR, // kpidNtSecure + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_BSTR, // SHA-1 + VT_BSTR, // SHA-256 + VT_BSTR, + VT_UI8, + VT_UI4, + VT_UI4, + VT_BSTR, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI8, + VT_UI8, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BOOL, + VT_BOOL, + VT_BOOL, + VT_UI8, + VT_UI8, + VT_BSTR, // kpidNtReparse + VT_BSTR, + VT_UI8, + VT_UI8, + VT_BOOL, + VT_BSTR, + VT_BSTR, + VT_BSTR, + VT_BOOL, + VT_FILETIME, // kpidChangeTime + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4, + VT_UI4 // kpidDevMinor +}; diff -Nru p7zip-rar-16.02/CPP/7zip/Common/RegisterArc.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterArc.h --- p7zip-rar-16.02/CPP/7zip/Common/RegisterArc.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterArc.h 2023-03-06 16:00:00.000000000 +0000 @@ -1,78 +1,80 @@ -// RegisterArc.h - -#ifndef __REGISTER_ARC_H -#define __REGISTER_ARC_H - -#include "../Archive/IArchive.h" - -struct CArcInfo -{ - UInt16 Flags; - Byte Id; - Byte SignatureSize; - UInt16 SignatureOffset; - - const Byte *Signature; - const char *Name; - const char *Ext; - const char *AddExt; - - Func_CreateInArchive CreateInArchive; - Func_CreateOutArchive CreateOutArchive; - Func_IsArc IsArc; - - bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; } -}; - -void RegisterArc(const CArcInfo *arcInfo) throw(); - - -#define IMP_CreateArcIn_2(c) \ - static IInArchive *CreateArc() { return new c; } - -#define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler()) - -#ifdef EXTRACT_ONLY - #define IMP_CreateArcOut - #define CreateArcOut NULL -#else - #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler(); } -#endif - -#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, crIn, crOut, isArc) \ - static const CArcInfo g_ArcInfo = { flags, id, sigSize, offs, sig, n, e, ae, crIn, crOut, isArc } ; \ - -#define REGISTER_ARC_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) \ - 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) - -#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) - -#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) - -#define REGISTER_ARC_I_NO_SIG(n, e, ae, id, offs, flags, isArc) \ - 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) \ - IMP_CreateArcIn \ - IMP_CreateArcOut \ - REGISTER_ARC_R(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) - -#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, isArc) \ - IMP_CreateArcIn \ - IMP_CreateArcOut \ - REGISTER_ARC_V(n, e, ae, id, ARRAY_SIZE(sig), sig, offs, flags, CreateArc, CreateArcOut, isArc) \ - struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \ - static CRegisterArcDecSig g_RegisterArc; - -#endif +// RegisterArc.h + +#ifndef ZIP7_INC_REGISTER_ARC_H +#define ZIP7_INC_REGISTER_ARC_H + +#include "../Archive/IArchive.h" + +struct CArcInfo +{ + UInt32 Flags; + Byte Id; + Byte SignatureSize; + UInt16 SignatureOffset; + + const Byte *Signature; + const char *Name; + const char *Ext; + const char *AddExt; + + UInt32 TimeFlags; + + Func_CreateInArchive CreateInArchive; + Func_CreateOutArchive CreateOutArchive; + Func_IsArc IsArc; + + bool IsMultiSignature() const { return (Flags & NArcInfoFlags::kMultiSignature) != 0; } +}; + +void RegisterArc(const CArcInfo *arcInfo) throw(); + + +#define IMP_CreateArcIn_2(c) \ + static IInArchive *CreateArc() { return new c; } + +#define IMP_CreateArcIn IMP_CreateArcIn_2(CHandler()) + +#ifdef Z7_EXTRACT_ONLY + #define IMP_CreateArcOut + #define CreateArcOut NULL +#else + #define IMP_CreateArcOut static IOutArchive *CreateArcOut() { return new CHandler(); } +#endif + +#define REGISTER_ARC_V(n, e, ae, id, sigSize, sig, offs, flags, 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, 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, Z7_ARRAY_SIZE(sig), sig, offs, flags, 0, CreateArc, NULL, isArc) + +#define REGISTER_ARC_I_CLS_NO_SIG(cls, n, e, ae, id, offs, flags, isArc) \ + IMP_CreateArcIn_2(cls) \ + REGISTER_ARC_R(n, e, ae, id, 0, NULL, offs, flags, 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) + +#define REGISTER_ARC_I_NO_SIG(n, e, ae, id, offs, flags, isArc) \ + 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, tf, isArc) \ + IMP_CreateArcIn \ + IMP_CreateArcOut \ + REGISTER_ARC_R(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) + +#define REGISTER_ARC_IO_DECREMENT_SIG(n, e, ae, id, sig, offs, flags, tf, isArc) \ + IMP_CreateArcIn \ + IMP_CreateArcOut \ + REGISTER_ARC_V(n, e, ae, id, Z7_ARRAY_SIZE(sig), sig, offs, flags, tf, CreateArc, CreateArcOut, isArc) \ + struct CRegisterArcDecSig { CRegisterArcDecSig() { sig[0]--; RegisterArc(&g_ArcInfo); }}; \ + static CRegisterArcDecSig g_RegisterArc; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/RegisterCodec.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterCodec.h --- p7zip-rar-16.02/CPP/7zip/Common/RegisterCodec.h 2015-06-20 10:01:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/RegisterCodec.h 2023-03-06 16:00:00.000000000 +0000 @@ -1,106 +1,106 @@ -// RegisterCodec.h - -#ifndef __REGISTER_CODEC_H -#define __REGISTER_CODEC_H - -#include "../Common/MethodId.h" - -#include "../ICoder.h" - -typedef void * (*CreateCodecP)(); - -struct CCodecInfo -{ - CreateCodecP CreateDecoder; - CreateCodecP CreateEncoder; - CMethodId Id; - const char *Name; - UInt32 NumStreams; - bool IsFilter; -}; - -void RegisterCodec(const CCodecInfo *codecInfo) throw(); - - -#define REGISTER_CODEC_CREATE_2(name, cls, i) static void *name() { return (void *)(i *)(new cls); } -#define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder) - -#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x -#define REGISTER_CODEC_VAR static const CCodecInfo g_CodecInfo = - -#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \ - REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \ - static REGISTER_CODEC_NAME(x) g_RegisterCodec; - - -#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x -#define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] = - -#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \ - REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < ARRAY_SIZE(g_CodecsInfo); i++) \ - RegisterCodec(&g_CodecsInfo[i]); }}; \ - static REGISTER_CODECS_NAME(x) g_RegisterCodecs; - - -#define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ - { crDec, crEnc, id, name, 1, false }; \ - REGISTER_CODEC(x) - - -#ifdef EXTRACT_ONLY - #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ - REGISTER_CODEC_CREATE(CreateDec, clsDec) \ - REGISTER_CODEC_2(x, CreateDec, NULL, id, name) -#else - #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ - REGISTER_CODEC_CREATE(CreateDec, clsDec) \ - REGISTER_CODEC_CREATE(CreateEnc, clsEnc) \ - REGISTER_CODEC_2(x, CreateDec, CreateEnc, id, name) -#endif - - - -#define REGISTER_FILTER_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressFilter) - -#define REGISTER_FILTER_ITEM(crDec, crEnc, id, name) \ - { crDec, crEnc, id, name, 1, true } - -#define REGISTER_FILTER(x, crDec, crEnc, id, name) \ - REGISTER_CODEC_VAR \ - REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \ - REGISTER_CODEC(x) - -#ifdef EXTRACT_ONLY - #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER(x, CreateDec, NULL, id, name) -#else - #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ - REGISTER_FILTER_CREATE(CreateDec, clsDec) \ - REGISTER_FILTER_CREATE(CreateEnc, clsEnc) \ - REGISTER_FILTER(x, CreateDec, CreateEnc, id, name) -#endif - - - -struct CHasherInfo -{ - IHasher * (*CreateHasher)(); - CMethodId Id; - const char *Name; - UInt32 DigestSize; -}; - -void RegisterHasher(const CHasherInfo *hasher) throw(); - -#define REGISTER_HASHER_NAME(x) CRegHasher_ ## x - -#define REGISTER_HASHER(cls, id, name, size) \ - STDMETHODIMP_(UInt32) cls::GetDigestSize() throw() { return size; } \ - static IHasher *CreateHasherSpec() { return new cls(); } \ - static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ - struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ - static REGISTER_HASHER_NAME(cls) g_RegisterHasher; - -#endif +// RegisterCodec.h + +#ifndef ZIP7_INC_REGISTER_CODEC_H +#define ZIP7_INC_REGISTER_CODEC_H + +#include "../Common/MethodId.h" + +#include "../ICoder.h" + +typedef void * (*CreateCodecP)(); + +struct CCodecInfo +{ + CreateCodecP CreateDecoder; + CreateCodecP CreateEncoder; + CMethodId Id; + const char *Name; + UInt32 NumStreams; + bool IsFilter; +}; + +void RegisterCodec(const CCodecInfo *codecInfo) throw(); + + +#define REGISTER_CODEC_CREATE_2(name, cls, i) static void *name() { return (void *)(i *)(new cls); } +#define REGISTER_CODEC_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressCoder) + +#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x +#define REGISTER_CODEC_VAR(x) static const CCodecInfo g_CodecInfo_ ## x = + +#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \ + REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo_ ## x); }}; \ + static REGISTER_CODEC_NAME(x) g_RegisterCodec_ ## x; + + +#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x +#define REGISTER_CODECS_VAR static const CCodecInfo g_CodecsInfo[] = + +#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \ + REGISTER_CODECS_NAME(x)() { for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_CodecsInfo); i++) \ + RegisterCodec(&g_CodecsInfo[i]); }}; \ + static REGISTER_CODECS_NAME(x) g_RegisterCodecs; + + +#define REGISTER_CODEC_2(x, crDec, crEnc, id, name) \ + REGISTER_CODEC_VAR(x) \ + { crDec, crEnc, id, name, 1, false }; \ + REGISTER_CODEC(x) + + +#ifdef Z7_EXTRACT_ONLY + #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ + REGISTER_CODEC_CREATE(CreateDec, clsDec) \ + REGISTER_CODEC_2(x, CreateDec, NULL, id, name) +#else + #define REGISTER_CODEC_E(x, clsDec, clsEnc, id, name) \ + REGISTER_CODEC_CREATE(CreateDec, clsDec) \ + REGISTER_CODEC_CREATE(CreateEnc, clsEnc) \ + REGISTER_CODEC_2(x, CreateDec, CreateEnc, id, name) +#endif + + + +#define REGISTER_FILTER_CREATE(name, cls) REGISTER_CODEC_CREATE_2(name, cls, ICompressFilter) + +#define REGISTER_FILTER_ITEM(crDec, crEnc, id, name) \ + { crDec, crEnc, id, name, 1, true } + +#define REGISTER_FILTER(x, crDec, crEnc, id, name) \ + REGISTER_CODEC_VAR(x) \ + REGISTER_FILTER_ITEM(crDec, crEnc, id, name); \ + REGISTER_CODEC(x) + +#ifdef Z7_EXTRACT_ONLY + #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER(x, x ## _CreateDec, NULL, id, name) +#else + #define REGISTER_FILTER_E(x, clsDec, clsEnc, id, name) \ + REGISTER_FILTER_CREATE(x ## _CreateDec, clsDec) \ + REGISTER_FILTER_CREATE(x ## _CreateEnc, clsEnc) \ + REGISTER_FILTER(x, x ## _CreateDec, x ## _CreateEnc, id, name) +#endif + + + +struct CHasherInfo +{ + IHasher * (*CreateHasher)(); + CMethodId Id; + const char *Name; + UInt32 DigestSize; +}; + +void RegisterHasher(const CHasherInfo *hasher) throw(); + +#define REGISTER_HASHER_NAME(x) CRegHasher_ ## x + +#define REGISTER_HASHER(cls, id, name, size) \ + Z7_COM7F_IMF2(UInt32, cls::GetDigestSize()) { return size; } \ + static IHasher *CreateHasherSpec() { return new cls(); } \ + static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ + struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ + static REGISTER_HASHER_NAME(cls) g_RegisterHasher; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Common/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamBinder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.cpp --- p7zip-rar-16.02/CPP/7zip/Common/StreamBinder.cpp 2015-09-19 17:52:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,157 +1,151 @@ -// StreamBinder.cpp - -#include "StdAfx.h" - -#include "../../Common/MyCom.h" - -#include "StreamBinder.h" - -class CBinderInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - CStreamBinder *_binder; -public: - MY_UNKNOWN_IMP1(ISequentialInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - ~CBinderInStream() { _binder->CloseRead(); } - CBinderInStream(CStreamBinder *binder): _binder(binder) {} -}; - -STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) - { return _binder->Read(data, size, processedSize); } - -class CBinderOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - CStreamBinder *_binder; -public: - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - ~CBinderOutStream() { _binder->CloseWrite(); } - CBinderOutStream(CStreamBinder *binder): _binder(binder) {} -}; - -STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) - { return _binder->Write(data, size, processedSize); } - - - -WRes CStreamBinder::CreateEvents() -{ - _synchroFor_canWrite_Event_and_readingWasClosed_Event.Create(); - RINOK(_canWrite_Event.Create(&_synchroFor_canWrite_Event_and_readingWasClosed_Event)); - RINOK(_canRead_Event.Create()); - return _readingWasClosed_Event.Create(&_synchroFor_canWrite_Event_and_readingWasClosed_Event); -} - -void CStreamBinder::ReInit() -{ - _canWrite_Event.Reset(); - _canRead_Event.Reset(); - _readingWasClosed_Event.Reset(); - - // _readingWasClosed = false; - _readingWasClosed2 = false; - - _waitWrite = true; - _bufSize = 0; - _buf = NULL; - ProcessedSize = 0; - // WritingWasCut = false; -} - - -void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream) -{ - // _readingWasClosed = false; - _readingWasClosed2 = false; - - _waitWrite = true; - _bufSize = 0; - _buf = NULL; - ProcessedSize = 0; - // WritingWasCut = false; - - CBinderInStream *inStreamSpec = new CBinderInStream(this); - CMyComPtr inStreamLoc(inStreamSpec); - *inStream = inStreamLoc.Detach(); - - CBinderOutStream *outStreamSpec = new CBinderOutStream(this); - CMyComPtr outStreamLoc(outStreamSpec); - *outStream = outStreamLoc.Detach(); -} - -// (_canRead_Event && _bufSize == 0) means that stream is finished. - -HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size != 0) - { - if (_waitWrite) - { - RINOK(_canRead_Event.Lock()); - _waitWrite = false; - } - if (size > _bufSize) - size = _bufSize; - if (size != 0) - { - memcpy(data, _buf, size); - _buf = ((const Byte *)_buf) + size; - ProcessedSize += size; - if (processedSize) - *processedSize = size; - _bufSize -= size; - if (_bufSize == 0) - { - _waitWrite = true; - _canRead_Event.Reset(); - _canWrite_Event.Set(); - } - } - } - return S_OK; -} - -HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - - if (!_readingWasClosed2) - { - _buf = data; - _bufSize = size; - _canRead_Event.Set(); - - /* - _canWrite_Event.Lock(); - if (_readingWasClosed) - _readingWasClosed2 = true; - */ - - HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event }; - DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); - if (waitResult >= WAIT_OBJECT_0 + 2) - return E_FAIL; - - size -= _bufSize; - if (size != 0) - { - if (processedSize) - *processedSize = size; - return S_OK; - } - // if (waitResult == WAIT_OBJECT_0 + 1) - _readingWasClosed2 = true; - } - - // WritingWasCut = true; - return k_My_HRESULT_WritingWasCut; -} +// StreamBinder.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" + +#include "StreamBinder.h" + +Z7_CLASS_IMP_COM_1( + CBinderInStream + , ISequentialInStream +) + CStreamBinder *_binder; +public: + ~CBinderInStream() { _binder->CloseRead_CallOnce(); } + CBinderInStream(CStreamBinder *binder): _binder(binder) {} +}; + +Z7_COM7F_IMF(CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) + { return _binder->Read(data, size, processedSize); } + + +Z7_CLASS_IMP_COM_1( + CBinderOutStream + , ISequentialOutStream +) + CStreamBinder *_binder; +public: + ~CBinderOutStream() { _binder->CloseWrite(); } + CBinderOutStream(CStreamBinder *binder): _binder(binder) {} +}; + +Z7_COM7F_IMF(CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) + { return _binder->Write(data, size, processedSize); } + + +static HRESULT Event_Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event) +{ + const WRes wres = event.CreateIfNotCreated_Reset(); + return HRESULT_FROM_WIN32(wres); +} + +HRESULT CStreamBinder::Create_ReInit() +{ + RINOK(Event_Create_or_Reset(_canRead_Event)) + // RINOK(Event_Create_or_Reset(_canWrite_Event)) + + // _canWrite_Semaphore.Close(); + // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() + _canWrite_Semaphore.OptCreateInit(0, 3); + + // _readingWasClosed = false; + _readingWasClosed2 = false; + + _waitWrite = true; + _bufSize = 0; + _buf = NULL; + ProcessedSize = 0; + // WritingWasCut = false; + return S_OK; +} + + +void CStreamBinder::CreateStreams2(CMyComPtr &inStream, CMyComPtr &outStream) +{ + inStream = new CBinderInStream(this); + outStream = new CBinderOutStream(this); +} + +// (_canRead_Event && _bufSize == 0) means that stream is finished. + +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size != 0) + { + if (_waitWrite) + { + WRes wres = _canRead_Event.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + _waitWrite = false; + } + if (size > _bufSize) + size = _bufSize; + if (size != 0) + { + memcpy(data, _buf, size); + _buf = ((const Byte *)_buf) + size; + ProcessedSize += size; + if (processedSize) + *processedSize = size; + _bufSize -= size; + + /* + if (_bufSize == 0), then we have read whole buffer + we have two ways here: + - if we check (_bufSize == 0) here, we unlock Write only after full data Reading - it reduces the number of syncs + - if we don't check (_bufSize == 0) here, we unlock Write after partial data Reading + */ + if (_bufSize == 0) + { + _waitWrite = true; + // _canWrite_Event.Set(); + _canWrite_Semaphore.Release(); + } + } + } + return S_OK; +} + + +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + if (!_readingWasClosed2) + { + _buf = data; + _bufSize = size; + _canRead_Event.Set(); + + /* + _canWrite_Event.Lock(); + if (_readingWasClosed) + _readingWasClosed2 = true; + */ + + _canWrite_Semaphore.Lock(); + + // _bufSize : is remain size that was not read + size -= _bufSize; + + // size : is size of data that was read + if (size != 0) + { + // if some data was read, then we report that size and return + if (processedSize) + *processedSize = size; + return S_OK; + } + _readingWasClosed2 = true; + } + + // WritingWasCut = true; + return k_My_HRESULT_WritingWasCut; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamBinder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.h --- p7zip-rar-16.02/CPP/7zip/Common/StreamBinder.h 2015-09-19 17:52:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamBinder.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,61 +1,78 @@ -// StreamBinder.h - -#ifndef __STREAM_BINDER_H -#define __STREAM_BINDER_H - -#include "../../Windows/Synchronization.h" - -#include "../IStream.h" - -/* -We don't use probably UNSAFE version: -reader thread: - _canWrite_Event.Set(); - _readingWasClosed = true - _canWrite_Event.Set(); -writer thread: - _canWrite_Event.Wait() - if (_readingWasClosed) -Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set? -*/ - -class CStreamBinder -{ - NWindows::NSynchronization::CSynchro _synchroFor_canWrite_Event_and_readingWasClosed_Event; - NWindows::NSynchronization::CAutoResetEventWFMO _canWrite_Event; - NWindows::NSynchronization::CManualResetEvent _canRead_Event; - NWindows::NSynchronization::CManualResetEventWFMO _readingWasClosed_Event; - - // bool _readingWasClosed; - bool _readingWasClosed2; - // bool WritingWasCut; - bool _waitWrite; - UInt32 _bufSize; - const void *_buf; -public: - UInt64 ProcessedSize; - - WRes CreateEvents(); - void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); - - void ReInit(); - - HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); - HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); - - void CloseRead() - { - _readingWasClosed_Event.Set(); - // _readingWasClosed = true; - // _canWrite_Event.Set(); - } - - void CloseWrite() - { - _buf = NULL; - _bufSize = 0; - _canRead_Event.Set(); - } -}; - -#endif +// StreamBinder.h + +#ifndef ZIP7_INC_STREAM_BINDER_H +#define ZIP7_INC_STREAM_BINDER_H + +#include "../../Windows/Synchronization.h" + +#include "../IStream.h" + +/* +We can use one from two code versions here: with Event or with Semaphore to unlock Writer thread +The difference for cases where Reading must be closed before Writing closing + +1) Event Version: _canWrite_Event + We call _canWrite_Event.Set() without waiting _canRead_Event in CloseRead() function. + The writer thread can get (_readingWasClosed) status in one from two iterations. + It's ambiguity of processing flow. But probably it's SAFE to use, if Event functions provide memory barriers. + reader thread: + _canWrite_Event.Set(); + _readingWasClosed = true; + _canWrite_Event.Set(); + writer thread: + _canWrite_Event.Wait() + if (_readingWasClosed) + +2) Semaphore Version: _canWrite_Semaphore + writer thread always will detect closing of reading in latest iteration after all data processing iterations +*/ + +class CStreamBinder +{ + NWindows::NSynchronization::CAutoResetEvent _canRead_Event; + // NWindows::NSynchronization::CAutoResetEvent _canWrite_Event; + NWindows::NSynchronization::CSemaphore _canWrite_Semaphore; + + // bool _readingWasClosed; // set it in reader thread and check it in write thread + bool _readingWasClosed2; // use it in writer thread + // bool WritingWasCut; + bool _waitWrite; // use it in reader thread + UInt32 _bufSize; + const void *_buf; +public: + UInt64 ProcessedSize; // the size that was read by reader thread + + void CreateStreams2(CMyComPtr &inStream, CMyComPtr &outStream); + + HRESULT Create_ReInit(); + + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); + + void CloseRead_CallOnce() + { + // call it only once: for example, in destructor + + /* + _readingWasClosed = true; + _canWrite_Event.Set(); + */ + + /* + We must relase Semaphore only once !!! + we must release at least 2 items of Semaphore: + one item to unlock partial Write(), if Read() have read some items + then additional item to stop writing (_bufSize will be 0) + */ + _canWrite_Semaphore.Release(2); + } + + void CloseWrite() + { + _buf = NULL; + _bufSize = 0; + _canRead_Event.Set(); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamObjects.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.cpp --- p7zip-rar-16.02/CPP/7zip/Common/StreamObjects.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.cpp 2023-04-05 14:00:00.000000000 +0000 @@ -1,285 +1,290 @@ -// StreamObjects.cpp - -#include "StdAfx.h" - -#include - -#include "../../../C/Alloc.h" - -#include "StreamObjects.h" - -STDMETHODIMP CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (_pos >= Buf.Size()) - return S_OK; - size_t rem = Buf.Size() - (size_t)_pos; - if (rem > size) - rem = (size_t)size; - memcpy(data, (const Byte *)Buf + (size_t)_pos, rem); - _pos += rem; - if (processedSize) - *processedSize = (UInt32)rem; - return S_OK; -} - -STDMETHODIMP CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _pos; break; - case STREAM_SEEK_END: offset += Buf.Size(); break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - -STDMETHODIMP CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (_pos >= _size) - return S_OK; - size_t rem = _size - (size_t)_pos; - if (rem > size) - rem = (size_t)size; - memcpy(data, _data + (size_t)_pos, rem); - _pos += rem; - if (processedSize) - *processedSize = (UInt32)rem; - return S_OK; -} - -STDMETHODIMP CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _pos; break; - case STREAM_SEEK_END: offset += _size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} - -void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream) -{ - *stream = NULL; - CBufInStream *inStreamSpec = new CBufInStream; - CMyComPtr streamTemp = inStreamSpec; - inStreamSpec->Init((const Byte *)data, size, ref); - *stream = streamTemp.Detach(); -} - -void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream) -{ - *stream = NULL; - CBufferInStream *inStreamSpec = new CBufferInStream; - CMyComPtr streamTemp = inStreamSpec; - inStreamSpec->Buf.CopyFrom((const Byte *)data, size); - inStreamSpec->Init(); - *stream = streamTemp.Detach(); -} - -void CByteDynBuffer::Free() throw() -{ - free(_buf); - _buf = 0; - _capacity = 0; -} - -bool CByteDynBuffer::EnsureCapacity(size_t cap) throw() -{ - if (cap <= _capacity) - return true; - size_t delta; - if (_capacity > 64) - delta = _capacity / 4; - else if (_capacity > 8) - delta = 16; - else - delta = 4; - cap = MyMax(_capacity + delta, cap); - Byte *buf = (Byte *)realloc(_buf, cap); - if (!buf) - return false; - _buf = buf; - _capacity = cap; - return true; -} - -Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize) -{ - addSize += _size; - if (addSize < _size) - return NULL; - if (!_buffer.EnsureCapacity(addSize)) - return NULL; - return (Byte *)_buffer + _size; -} - -void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const -{ - dest.CopyFrom((const Byte *)_buffer, _size); -} - -STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - Byte *buf = GetBufPtrForWriting(size); - if (!buf) - return E_OUTOFMEMORY; - memcpy(buf, data, size); - UpdateSize(size); - if (processedSize) - *processedSize = size; - return S_OK; -} - -STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - size_t rem = _size - _pos; - if (rem > size) - rem = (size_t)size; - if (rem != 0) - { - memcpy(_buffer + _pos, data, rem); - _pos += rem; - } - if (processedSize) - *processedSize = (UInt32)rem; - return (rem != 0 || size == 0) ? S_OK : E_FAIL; -} - -STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->Write(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return result; -} - -static const UInt64 kEmptyTag = (UInt64)(Int64)-1; - -void CCachedInStream::Free() throw() -{ - MyFree(_tags); - _tags = 0; - MidFree(_data); - _data = 0; -} - -bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw() -{ - unsigned sizeLog = blockSizeLog + numBlocksLog; - if (sizeLog >= sizeof(size_t) * 8) - return false; - size_t dataSize = (size_t)1 << sizeLog; - if (_data == 0 || dataSize != _dataSize) - { - MidFree(_data); - _data = (Byte *)MidAlloc(dataSize); - if (_data == 0) - return false; - _dataSize = dataSize; - } - if (_tags == 0 || numBlocksLog != _numBlocksLog) - { - MyFree(_tags); - _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog); - if (_tags == 0) - return false; - _numBlocksLog = numBlocksLog; - } - _blockSizeLog = blockSizeLog; - return true; -} - -void CCachedInStream::Init(UInt64 size) throw() -{ - _size = size; - _pos = 0; - size_t numBlocks = (size_t)1 << _numBlocksLog; - for (size_t i = 0; i < numBlocks; i++) - _tags[i] = kEmptyTag; -} - -STDMETHODIMP CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (_pos >= _size) - return S_OK; - - { - UInt64 rem = _size - _pos; - if (size > rem) - size = (UInt32)rem; - } - - while (size != 0) - { - UInt64 cacheTag = _pos >> _blockSizeLog; - size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); - Byte *p = _data + (cacheIndex << _blockSizeLog); - if (_tags[cacheIndex] != cacheTag) - { - UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); - size_t blockSize = (size_t)1 << _blockSizeLog; - if (blockSize > remInBlock) - blockSize = (size_t)remInBlock; - RINOK(ReadBlock(cacheTag, p, blockSize)); - _tags[cacheIndex] = cacheTag; - } - size_t offset = (size_t)_pos & (((size_t)1 << _blockSizeLog) - 1); - UInt32 cur = (UInt32)MyMin(((size_t)1 << _blockSizeLog) - offset, (size_t)size); - memcpy(data, p + offset, cur); - if (processedSize) - *processedSize += cur; - data = (void *)((const Byte *)data + cur); - _pos += cur; - size -= cur; - } - - return S_OK; -} - -STDMETHODIMP CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - switch (seekOrigin) - { - case STREAM_SEEK_SET: break; - case STREAM_SEEK_CUR: offset += _pos; break; - case STREAM_SEEK_END: offset += _size; break; - default: return STG_E_INVALIDFUNCTION; - } - if (offset < 0) - return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; - _pos = offset; - if (newPosition) - *newPosition = offset; - return S_OK; -} +// StreamObjects.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "StreamObjects.h" + +Z7_COM7F_IMF(CBufferInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= Buf.Size()) + return S_OK; + size_t rem = Buf.Size() - (size_t)_pos; + if (rem > size) + rem = (size_t)size; + memcpy(data, (const Byte *)Buf + (size_t)_pos, rem); + _pos += rem; + if (processedSize) + *processedSize = (UInt32)rem; + return S_OK; +} + +Z7_COM7F_IMF(CBufferInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _pos; break; + case STREAM_SEEK_END: offset += Buf.Size(); break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _pos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + +Z7_COM7F_IMF(CBufInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= _size) + return S_OK; + size_t rem = _size - (size_t)_pos; + if (rem > size) + rem = (size_t)size; + memcpy(data, _data + (size_t)_pos, rem); + _pos += rem; + if (processedSize) + *processedSize = (UInt32)rem; + return S_OK; +} + +Z7_COM7F_IMF(CBufInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _pos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _pos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} + +void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream) +{ + *stream = NULL; + CBufInStream *inStreamSpec = new CBufInStream; + CMyComPtr streamTemp = inStreamSpec; + inStreamSpec->Init((const Byte *)data, size, ref); + *stream = streamTemp.Detach(); +} + +void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream) +{ + *stream = NULL; + CBufferInStream *inStreamSpec = new CBufferInStream; + CMyComPtr streamTemp = inStreamSpec; + inStreamSpec->Buf.CopyFrom((const Byte *)data, size); + inStreamSpec->Init(); + *stream = streamTemp.Detach(); +} + +void CByteDynBuffer::Free() throw() +{ + MyFree(_buf); + _buf = NULL; + _capacity = 0; +} + +bool CByteDynBuffer::EnsureCapacity(size_t cap) throw() +{ + if (cap <= _capacity) + return true; + const size_t cap2 = _capacity + _capacity / 4; + if (cap < cap2) + cap = cap2; + Byte *buf = (Byte *)MyRealloc(_buf, cap); + if (!buf) + return false; + _buf = buf; + _capacity = cap; + return true; +} + +Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize) +{ + addSize += _size; + if (addSize < _size) + return NULL; + if (!_buffer.EnsureCapacity(addSize)) + return NULL; + return (Byte *)_buffer + _size; +} + +void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const +{ + dest.CopyFrom((const Byte *)_buffer, _size); +} + +Z7_COM7F_IMF(CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + Byte *buf = GetBufPtrForWriting(size); + if (!buf) + return E_OUTOFMEMORY; + memcpy(buf, data, size); + UpdateSize(size); + if (processedSize) + *processedSize = size; + return S_OK; +} + +Z7_COM7F_IMF(CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t rem = _size - _pos; + if (rem > size) + rem = (size_t)size; + if (rem != 0) + { + memcpy(_buffer + _pos, data, rem); + _pos += rem; + } + if (processedSize) + *processedSize = (UInt32)rem; + return (rem != 0 || size == 0) ? S_OK : E_FAIL; +} + +Z7_COM7F_IMF(CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize; + HRESULT result = _stream->Write(data, size, &realProcessedSize); + _size += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return result; +} + +static const UInt64 kEmptyTag = (UInt64)(Int64)-1; + +void CCachedInStream::Free() throw() +{ + MyFree(_tags); + _tags = NULL; + MidFree(_data); + _data = NULL; +} + +bool CCachedInStream::Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw() +{ + unsigned sizeLog = blockSizeLog + numBlocksLog; + if (sizeLog >= sizeof(size_t) * 8) + return false; + size_t dataSize = (size_t)1 << sizeLog; + if (!_data || dataSize != _dataSize) + { + MidFree(_data); + _data = (Byte *)MidAlloc(dataSize); + if (!_data) + return false; + _dataSize = dataSize; + } + if (!_tags || numBlocksLog != _numBlocksLog) + { + MyFree(_tags); + _tags = (UInt64 *)MyAlloc(sizeof(UInt64) << numBlocksLog); + if (!_tags) + return false; + _numBlocksLog = numBlocksLog; + } + _blockSizeLog = blockSizeLog; + return true; +} + +void CCachedInStream::Init(UInt64 size) throw() +{ + _size = size; + _pos = 0; + const size_t numBlocks = (size_t)1 << _numBlocksLog; + for (size_t i = 0; i < numBlocks; i++) + _tags[i] = kEmptyTag; +} + +Z7_COM7F_IMF(CCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_pos >= _size) + return S_OK; + + { + const UInt64 rem = _size - _pos; + if (size > rem) + size = (UInt32)rem; + } + + while (size != 0) + { + const UInt64 cacheTag = _pos >> _blockSizeLog; + const size_t cacheIndex = (size_t)cacheTag & (((size_t)1 << _numBlocksLog) - 1); + Byte *p = _data + (cacheIndex << _blockSizeLog); + + if (_tags[cacheIndex] != cacheTag) + { + _tags[cacheIndex] = kEmptyTag; + const UInt64 remInBlock = _size - (cacheTag << _blockSizeLog); + size_t blockSize = (size_t)1 << _blockSizeLog; + if (blockSize > remInBlock) + blockSize = (size_t)remInBlock; + + RINOK(ReadBlock(cacheTag, p, blockSize)) + + _tags[cacheIndex] = cacheTag; + } + + const size_t kBlockSize = (size_t)1 << _blockSizeLog; + const size_t offset = (size_t)_pos & (kBlockSize - 1); + UInt32 cur = size; + const size_t rem = kBlockSize - offset; + if (cur > rem) + cur = (UInt32)rem; + + memcpy(data, p + offset, cur); + + if (processedSize) + *processedSize += cur; + data = (void *)((const Byte *)data + cur); + _pos += cur; + size -= cur; + } + + return S_OK; +} + + +Z7_COM7F_IMF(CCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _pos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _pos = (UInt64)offset; + if (newPosition) + *newPosition = (UInt64)offset; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamObjects.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.h --- p7zip-rar-16.02/CPP/7zip/Common/StreamObjects.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamObjects.h 2023-04-05 14:00:00.000000000 +0000 @@ -1,157 +1,146 @@ -// StreamObjects.h - -#ifndef __STREAM_OBJECTS_H -#define __STREAM_OBJECTS_H - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyVector.h" - -#include "../IStream.h" - -class CBufferInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 _pos; -public: - CByteBuffer Buf; - void Init() { _pos = 0; } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -struct CReferenceBuf: - public IUnknown, - public CMyUnknownImp -{ - CByteBuffer Buf; - MY_UNKNOWN_IMP -}; - -class CBufInStream: - public IInStream, - public CMyUnknownImp -{ - const Byte *_data; - UInt64 _pos; - size_t _size; - CMyComPtr _ref; -public: - void Init(const Byte *data, size_t size, IUnknown *ref = 0) - { - _data = data; - _size = size; - _pos = 0; - _ref = ref; - } - void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream); -void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream); -inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream) - { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); } - -class CByteDynBuffer -{ - size_t _capacity; - Byte *_buf; -public: - CByteDynBuffer(): _capacity(0), _buf(0) {}; - // there is no copy constructor. So don't copy this object. - ~CByteDynBuffer() { Free(); } - void Free() throw(); - size_t GetCapacity() const { return _capacity; } - operator Byte*() const { return _buf; } - operator const Byte*() const { return _buf; } - bool EnsureCapacity(size_t capacity) throw(); -}; - -class CDynBufSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - CByteDynBuffer _buffer; - size_t _size; -public: - CDynBufSeqOutStream(): _size(0) {} - void Init() { _size = 0; } - size_t GetSize() const { return _size; } - const Byte *GetBuffer() const { return _buffer; } - void CopyToBuffer(CByteBuffer &dest) const; - Byte *GetBufPtrForWriting(size_t addSize); - void UpdateSize(size_t addSize) { _size += addSize; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -class CBufPtrSeqOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ - Byte *_buffer; - size_t _size; - size_t _pos; -public: - void Init(Byte *buffer, size_t size) - { - _buffer = buffer; - _pos = 0; - _size = size; - } - size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -class CSequentialOutStreamSizeCount: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; -public: - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void Init() { _size = 0; } - UInt64 GetSize() const { return _size; } - - MY_UNKNOWN_IMP1(ISequentialOutStream) - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -class CCachedInStream: - public IInStream, - public CMyUnknownImp -{ - UInt64 *_tags; - Byte *_data; - size_t _dataSize; - unsigned _blockSizeLog; - unsigned _numBlocksLog; - UInt64 _size; - UInt64 _pos; -protected: - virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; -public: - CCachedInStream(): _tags(0), _data(0) {} - virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (release calls it) !!! - void Free() throw(); - bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); - void Init(UInt64 size) throw(); - - MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); -}; - -#endif +// StreamObjects.h + +#ifndef ZIP7_INC_STREAM_OBJECTS_H +#define ZIP7_INC_STREAM_OBJECTS_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" + +#include "../IStream.h" + +Z7_CLASS_IMP_IInStream( + CBufferInStream +) + UInt64 _pos; +public: + CByteBuffer Buf; + void Init() { _pos = 0; } +}; + + +Z7_CLASS_IMP_COM_0( + CReferenceBuf +) +public: + CByteBuffer Buf; +}; + + +Z7_CLASS_IMP_IInStream( + CBufInStream +) + const Byte *_data; + UInt64 _pos; + size_t _size; + CMyComPtr _ref; +public: + void Init(const Byte *data, size_t size, IUnknown *ref = NULL) + { + _data = data; + _size = size; + _pos = 0; + _ref = ref; + } + void Init(CReferenceBuf *ref) { Init(ref->Buf, ref->Buf.Size(), ref); } + + // Seek() is allowed here. So reading order could be changed + bool WasFinished() const { return _pos == _size; } +}; + + +void Create_BufInStream_WithReference(const void *data, size_t size, IUnknown *ref, ISequentialInStream **stream); +void Create_BufInStream_WithNewBuffer(const void *data, size_t size, ISequentialInStream **stream); +inline void Create_BufInStream_WithNewBuffer(const CByteBuffer &buf, ISequentialInStream **stream) + { Create_BufInStream_WithNewBuffer(buf, buf.Size(), stream); } + + +class CByteDynBuffer Z7_final +{ + size_t _capacity; + Byte *_buf; + Z7_CLASS_NO_COPY(CByteDynBuffer) +public: + CByteDynBuffer(): _capacity(0), _buf(NULL) {} + // there is no copy constructor. So don't copy this object. + ~CByteDynBuffer() { Free(); } + void Free() throw(); + size_t GetCapacity() const { return _capacity; } + operator Byte*() const { return _buf; } + operator const Byte*() const { return _buf; } + bool EnsureCapacity(size_t capacity) throw(); +}; + + +Z7_CLASS_IMP_COM_1( + CDynBufSeqOutStream + , ISequentialOutStream +) + CByteDynBuffer _buffer; + size_t _size; +public: + CDynBufSeqOutStream(): _size(0) {} + void Init() { _size = 0; } + size_t GetSize() const { return _size; } + const Byte *GetBuffer() const { return _buffer; } + void CopyToBuffer(CByteBuffer &dest) const; + Byte *GetBufPtrForWriting(size_t addSize); + void UpdateSize(size_t addSize) { _size += addSize; } +}; + + +Z7_CLASS_IMP_COM_1( + CBufPtrSeqOutStream + , ISequentialOutStream +) + Byte *_buffer; + size_t _size; + size_t _pos; +public: + void Init(Byte *buffer, size_t size) + { + _buffer = buffer; + _pos = 0; + _size = size; + } + size_t GetPos() const { return _pos; } +}; + + +Z7_CLASS_IMP_COM_1( + CSequentialOutStreamSizeCount + , ISequentialOutStream +) + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void Init() { _size = 0; } + UInt64 GetSize() const { return _size; } +}; + + +class CCachedInStream: + public IInStream, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) + + UInt64 *_tags; + Byte *_data; + size_t _dataSize; + unsigned _blockSizeLog; + unsigned _numBlocksLog; + UInt64 _size; + UInt64 _pos; +protected: + virtual HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize) = 0; +public: + CCachedInStream(): _tags(NULL), _data(NULL) {} + virtual ~CCachedInStream() { Free(); } // the destructor must be virtual (Release() calls it) !!! + void Free() throw(); + bool Alloc(unsigned blockSizeLog, unsigned numBlocksLog) throw(); + void Init(UInt64 size) throw(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.cpp --- p7zip-rar-16.02/CPP/7zip/Common/StreamUtils.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.cpp 2023-03-26 18:00:00.000000000 +0000 @@ -1,56 +1,101 @@ -// StreamUtils.cpp - -#include "StdAfx.h" - -#include "StreamUtils.h" - -static const UInt32 kBlockSize = ((UInt32)1 << 31); - -HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() -{ - size_t size = *processedSize; - *processedSize = 0; - while (size != 0) - { - UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; - UInt32 processedSizeLoc; - HRESULT res = stream->Read(data, curSize, &processedSizeLoc); - *processedSize += processedSizeLoc; - data = (void *)((Byte *)data + processedSizeLoc); - size -= processedSizeLoc; - RINOK(res); - if (processedSizeLoc == 0) - return S_OK; - } - return S_OK; -} - -HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw() -{ - size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); - return (size == processedSize) ? S_OK : S_FALSE; -} - -HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw() -{ - size_t processedSize = size; - RINOK(ReadStream(stream, data, &processedSize)); - return (size == processedSize) ? S_OK : E_FAIL; -} - -HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw() -{ - while (size != 0) - { - UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; - UInt32 processedSizeLoc; - HRESULT res = stream->Write(data, curSize, &processedSizeLoc); - data = (const void *)((const Byte *)data + processedSizeLoc); - size -= processedSizeLoc; - RINOK(res); - if (processedSizeLoc == 0) - return E_FAIL; - } - return S_OK; -} +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" + +#include "StreamUtils.h" + +static const UInt32 kBlockSize = ((UInt32)1 << 31); + + +HRESULT InStream_SeekToBegin(IInStream *stream) throw() +{ + return InStream_SeekSet(stream, 0); +} + + +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw() +{ +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekToBegin(stream); + return hres != S_OK ? hres : hres2; +} + + +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw() +{ + RINOK(InStream_GetPos(stream, curPosRes)) +#ifdef _WIN32 + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, stream) + if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK) + return S_OK; + } +#endif + const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes); + const HRESULT hres2 = InStream_SeekSet(stream, curPosRes); + return hres != S_OK ? hres : hres2; +} + + + +HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw() +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, curSize, &processedSizeLoc); + *processedSize += processedSizeLoc; + data = (void *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res) + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw() +{ + size_t processedSize = size; + RINOK(ReadStream(stream, data, &processedSize)) + return (size == processedSize) ? S_OK : S_FALSE; +} + +HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw() +{ + size_t processedSize = size; + RINOK(ReadStream(stream, data, &processedSize)) + return (size == processedSize) ? S_OK : E_FAIL; +} + +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw() +{ + while (size != 0) + { + UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize; + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, curSize, &processedSizeLoc); + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res) + if (processedSizeLoc == 0) + return E_FAIL; + } + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/StreamUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.h --- p7zip-rar-16.02/CPP/7zip/Common/StreamUtils.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/StreamUtils.h 2023-01-19 09:00:00.000000000 +0000 @@ -1,13 +1,31 @@ -// StreamUtils.h - -#ifndef __STREAM_UTILS_H -#define __STREAM_UTILS_H - -#include "../IStream.h" - -HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw(); -HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw(); -HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw(); -HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw(); - -#endif +// StreamUtils.h + +#ifndef ZIP7_INC_STREAM_UTILS_H +#define ZIP7_INC_STREAM_UTILS_H + +#include "../IStream.h" + +inline HRESULT InStream_SeekSet(IInStream *stream, UInt64 offset) throw() + { return stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL); } +inline HRESULT InStream_GetPos(IInStream *stream, UInt64 &curPosRes) throw() + { return stream->Seek(0, STREAM_SEEK_CUR, &curPosRes); } +inline HRESULT InStream_GetSize_SeekToEnd(IInStream *stream, UInt64 &sizeRes) throw() + { return stream->Seek(0, STREAM_SEEK_END, &sizeRes); } + +HRESULT InStream_SeekToBegin(IInStream *stream) throw(); +HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &size) throw(); +HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw(); + +inline HRESULT InStream_GetSize_SeekToBegin(IInStream *stream, UInt64 &sizeRes) throw() +{ + RINOK(InStream_SeekToBegin(stream)) + return InStream_AtBegin_GetSize(stream, sizeRes); +} + + +HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *size) throw(); +HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw(); +HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw(); +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw(); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/UniqBlocks.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.cpp --- p7zip-rar-16.02/CPP/7zip/Common/UniqBlocks.cpp 2015-09-01 18:04:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.cpp 2022-01-08 17:00:00.000000000 +0000 @@ -1,57 +1,57 @@ -// UniqBlocks.cpp - -#include "StdAfx.h" - -#include - -#include "UniqBlocks.h" - -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 CByteBuffer &buf = Bufs[index]; - size_t sizeMid = buf.Size(); - if (size < sizeMid) - right = mid; - else if (size > sizeMid) - left = mid + 1; - else - { - if (size == 0) - return index; - int cmp = memcmp(data, buf, size); - if (cmp == 0) - return index; - if (cmp < 0) - right = mid; - else - left = mid + 1; - } - } - unsigned index = Bufs.Size(); - Sorted.Insert(left, index); - Bufs.AddNew().CopyFrom(data, size); - return index; -} - -UInt64 CUniqBlocks::GetTotalSizeInBytes() const -{ - UInt64 size = 0; - FOR_VECTOR (i, Bufs) - size += Bufs[i].Size(); - return size; -} - -void CUniqBlocks::GetReverseMap() -{ - unsigned num = Sorted.Size(); - BufIndexToSortedIndex.ClearAndSetSize(num); - unsigned *p = &BufIndexToSortedIndex[0]; - const unsigned *sorted = &Sorted[0]; - for (unsigned i = 0; i < num; i++) - p[sorted[i]] = i; -} +// UniqBlocks.cpp + +#include "StdAfx.h" + +#include + +#include "UniqBlocks.h" + +unsigned CUniqBlocks::AddUniq(const Byte *data, size_t size) +{ + unsigned left = 0, right = Sorted.Size(); + while (left != right) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned index = Sorted[mid]; + const CByteBuffer &buf = Bufs[index]; + const size_t sizeMid = buf.Size(); + if (size < sizeMid) + right = mid; + else if (size > sizeMid) + left = mid + 1; + else + { + if (size == 0) + return index; + const int cmp = memcmp(data, buf, size); + if (cmp == 0) + return index; + if (cmp < 0) + right = mid; + else + left = mid + 1; + } + } + unsigned index = Bufs.Size(); + Sorted.Insert(left, index); + Bufs.AddNew().CopyFrom(data, size); + return index; +} + +UInt64 CUniqBlocks::GetTotalSizeInBytes() const +{ + UInt64 size = 0; + FOR_VECTOR (i, Bufs) + size += Bufs[i].Size(); + return size; +} + +void CUniqBlocks::GetReverseMap() +{ + unsigned num = Sorted.Size(); + BufIndexToSortedIndex.ClearAndSetSize(num); + unsigned *p = &BufIndexToSortedIndex[0]; + const unsigned *sorted = &Sorted[0]; + for (unsigned i = 0; i < num; i++) + p[sorted[i]] = i; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/UniqBlocks.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.h --- p7zip-rar-16.02/CPP/7zip/Common/UniqBlocks.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/UniqBlocks.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,26 +1,41 @@ -// UniqBlocks.h - -#ifndef __UNIQ_BLOCKS_H -#define __UNIQ_BLOCKS_H - -#include "../../Common/MyTypes.h" -#include "../../Common/MyBuffer.h" -#include "../../Common/MyVector.h" - -struct CUniqBlocks -{ - CObjectVector Bufs; - CUIntVector Sorted; - CUIntVector BufIndexToSortedIndex; - - unsigned AddUniq(const Byte *data, size_t size); - UInt64 GetTotalSizeInBytes() const; - void GetReverseMap(); - - bool IsOnlyEmpty() const - { - return (Bufs.Size() == 0 || Bufs.Size() == 1 && Bufs[0].Size() == 0); - } -}; - -#endif +// UniqBlocks.h + +#ifndef ZIP7_INC_UNIQ_BLOCKS_H +#define ZIP7_INC_UNIQ_BLOCKS_H + +#include "../../Common/MyBuffer.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 +{ + CObjectVector Bufs; + CUIntVector Sorted; + CUIntVector BufIndexToSortedIndex; + + unsigned AddUniq(const Byte *data, size_t size); + UInt64 GetTotalSizeInBytes() const; + void GetReverseMap(); + + bool IsOnlyEmpty() const + { + return (Bufs.Size() == 0 || (Bufs.Size() == 1 && Bufs[0].Size() == 0)); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Common/VirtThread.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.cpp --- p7zip-rar-16.02/CPP/7zip/Common/VirtThread.cpp 2011-05-08 18:29:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.cpp 2023-03-21 07:00:00.000000000 +0000 @@ -1,48 +1,47 @@ -// VirtThread.cpp - -#include "StdAfx.h" - -#include "VirtThread.h" - -static THREAD_FUNC_DECL CoderThread(void *p) -{ - for (;;) - { - CVirtThread *t = (CVirtThread *)p; - t->StartEvent.Lock(); - if (t->Exit) - return 0; - t->Execute(); - t->FinishedEvent.Set(); - } -} - -WRes CVirtThread::Create() -{ - RINOK(StartEvent.CreateIfNotCreated()); - RINOK(FinishedEvent.CreateIfNotCreated()); - StartEvent.Reset(); - FinishedEvent.Reset(); - Exit = false; - if (Thread.IsCreated()) - return S_OK; - return Thread.Create(CoderThread, this); -} - -void CVirtThread::Start() -{ - Exit = false; - StartEvent.Set(); -} - -void CVirtThread::WaitThreadFinish() -{ - Exit = true; - if (StartEvent.IsCreated()) - StartEvent.Set(); - if (Thread.IsCreated()) - { - Thread.Wait(); - Thread.Close(); - } -} +// VirtThread.cpp + +#include "StdAfx.h" + +#include "VirtThread.h" + +static THREAD_FUNC_DECL CoderThread(void *p) +{ + for (;;) + { + CVirtThread *t = (CVirtThread *)p; + t->StartEvent.Lock(); + if (t->Exit) + return THREAD_FUNC_RET_ZERO; + t->Execute(); + t->FinishedEvent.Set(); + } +} + +WRes CVirtThread::Create() +{ + RINOK_WRes(StartEvent.CreateIfNotCreated_Reset()) + RINOK_WRes(FinishedEvent.CreateIfNotCreated_Reset()) + // StartEvent.Reset(); + // FinishedEvent.Reset(); + Exit = false; + if (Thread.IsCreated()) + return S_OK; + return Thread.Create(CoderThread, this); +} + +WRes CVirtThread::Start() +{ + Exit = false; + return StartEvent.Set(); +} + +void CVirtThread::WaitThreadFinish() +{ + Exit = true; + if (StartEvent.IsCreated()) + StartEvent.Set(); + if (Thread.IsCreated()) + { + Thread.Wait_Close(); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/Common/VirtThread.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.h --- p7zip-rar-16.02/CPP/7zip/Common/VirtThread.h 2011-05-08 18:29:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Common/VirtThread.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,24 +1,24 @@ -// VirtThread.h - -#ifndef __VIRT_THREAD_H -#define __VIRT_THREAD_H - -#include "../../Windows/Synchronization.h" -#include "../../Windows/Thread.h" - -struct CVirtThread -{ - NWindows::NSynchronization::CAutoResetEvent StartEvent; - NWindows::NSynchronization::CAutoResetEvent FinishedEvent; - NWindows::CThread Thread; - bool Exit; - - ~CVirtThread() { WaitThreadFinish(); } - void WaitThreadFinish(); // call it in destructor of child class ! - WRes Create(); - void Start(); - virtual void Execute() = 0; - void WaitExecuteFinish() { FinishedEvent.Lock(); } -}; - -#endif +// VirtThread.h + +#ifndef ZIP7_INC_VIRT_THREAD_H +#define ZIP7_INC_VIRT_THREAD_H + +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" + +struct CVirtThread +{ + NWindows::NSynchronization::CAutoResetEvent StartEvent; + NWindows::NSynchronization::CAutoResetEvent FinishedEvent; + NWindows::CThread Thread; + bool Exit; + + virtual ~CVirtThread() { WaitThreadFinish(); } + void WaitThreadFinish(); // call it in destructor of child class ! + WRes Create(); + WRes Start(); + virtual void Execute() = 0; + WRes WaitExecuteFinish() { return FinishedEvent.Lock(); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Const.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Const.h --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Const.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Const.h 2024-12-17 11:00:00.000000000 +0000 @@ -1,55 +1,71 @@ -// Compress/BZip2Const.h - -#ifndef __COMPRESS_BZIP2_CONST_H -#define __COMPRESS_BZIP2_CONST_H - -namespace NCompress { -namespace NBZip2 { - -const Byte kArSig0 = 'B'; -const Byte kArSig1 = 'Z'; -const Byte kArSig2 = 'h'; -const Byte kArSig3 = '0'; - -const Byte kFinSig0 = 0x17; -const Byte kFinSig1 = 0x72; -const Byte kFinSig2 = 0x45; -const Byte kFinSig3 = 0x38; -const Byte kFinSig4 = 0x50; -const Byte kFinSig5 = 0x90; - -const Byte kBlockSig0 = 0x31; -const Byte kBlockSig1 = 0x41; -const Byte kBlockSig2 = 0x59; -const Byte kBlockSig3 = 0x26; -const Byte kBlockSig4 = 0x53; -const Byte kBlockSig5 = 0x59; - -const unsigned kNumOrigBits = 24; - -const unsigned kNumTablesBits = 3; -const unsigned kNumTablesMin = 2; -const unsigned kNumTablesMax = 6; - -const unsigned kNumLevelsBits = 5; - -const unsigned kMaxHuffmanLen = 20; // Check it - -const unsigned kMaxAlphaSize = 258; - -const unsigned kGroupSize = 50; - -const unsigned kBlockSizeMultMin = 1; -const unsigned kBlockSizeMultMax = 9; - -const UInt32 kBlockSizeStep = 100000; -const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; - -const unsigned kNumSelectorsBits = 15; -const UInt32 kNumSelectorsMax = (2 + (kBlockSizeMax / kGroupSize)); - -const unsigned kRleModeRepSize = 4; - -}} - -#endif +// Compress/BZip2Const.h + +#ifndef ZIP7_INC_COMPRESS_BZIP2_CONST_H +#define ZIP7_INC_COMPRESS_BZIP2_CONST_H + +namespace NCompress { +namespace NBZip2 { + +const Byte kArSig0 = 'B'; +const Byte kArSig1 = 'Z'; +const Byte kArSig2 = 'h'; +const Byte kArSig3 = '0'; + +const Byte kFinSig0 = 0x17; +const Byte kFinSig1 = 0x72; +const Byte kFinSig2 = 0x45; +const Byte kFinSig3 = 0x38; +const Byte kFinSig4 = 0x50; +const Byte kFinSig5 = 0x90; + +const Byte kBlockSig0 = 0x31; +const Byte kBlockSig1 = 0x41; +const Byte kBlockSig2 = 0x59; +const Byte kBlockSig3 = 0x26; +const Byte kBlockSig4 = 0x53; +const Byte kBlockSig5 = 0x59; + +const unsigned kNumOrigBits = 24; + +const unsigned kNumTablesBits = 3; +const unsigned kNumTablesMin = 2; +const unsigned kNumTablesMax = 6; + +const unsigned kNumLevelsBits = 5; + +const unsigned kMaxHuffmanLen = 20; // Check it + +const unsigned kMaxAlphaSize = 258; + +const unsigned kGroupSize = 50; + +const unsigned kBlockSizeMultMin = 1; +const unsigned kBlockSizeMultMax = 9; + +const UInt32 kBlockSizeStep = 100000; +const UInt32 kBlockSizeMax = kBlockSizeMultMax * kBlockSizeStep; + +const unsigned kNumSelectorsBits = 15; +const unsigned kNumSelectorsMax = 2 + kBlockSizeMax / kGroupSize; + +const unsigned kRleModeRepSize = 4; + +/* +The number of selectors stored in bzip2 block: +(numSelectors <= 18001) - must work with any decoder. +(numSelectors == 18002) - works with bzip2 1.0.6 decoder and all derived decoders. +(numSelectors > 18002) + lbzip2 2.5: encoder can write up to (18001 + 7) selectors. + + 7-Zip before 19.03: decoder doesn't support it. + 7-Zip 19.03: decoder allows 8 additional selector records for lbzip2 compatibility. + + bzip2 1.0.6: decoder can overflow selector[18002] arrays. But there are another + arrays after selector arrays. So the compiled code works. + bzip2 1.0.7: decoder doesn't support it. + bzip2 1.0.8: decoder allows additional selector records for lbzip2 compatibility. +*/ + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Crc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Crc.cpp 2009-02-07 17:06:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.cpp 2023-11-12 15:00:00.000000000 +0000 @@ -1,26 +1,28 @@ -// BZip2Crc.cpp - -#include "StdAfx.h" - -#include "BZip2Crc.h" - -UInt32 CBZip2Crc::Table[256]; - -static const UInt32 kBZip2CrcPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ - -void CBZip2Crc::InitTable() -{ - for (UInt32 i = 0; i < 256; i++) - { - UInt32 r = (i << 24); - for (int j = 8; j > 0; j--) - r = (r & 0x80000000) ? ((r << 1) ^ kBZip2CrcPoly) : (r << 1); - Table[i] = r; - } -} - -class CBZip2CrcTableInit -{ -public: - CBZip2CrcTableInit() { CBZip2Crc::InitTable(); } -} g_BZip2CrcTableInit; +// BZip2Crc.cpp + +#include "StdAfx.h" + +#include "BZip2Crc.h" + +MY_ALIGN(64) +UInt32 CBZip2Crc::Table[256]; + +static const UInt32 kBZip2CrcPoly = 0x04c11db7; /* AUTODIN II, Ethernet, & FDDI */ + +void CBZip2Crc::InitTable() +{ + for (UInt32 i = 0; i < 256; i++) + { + UInt32 r = i << 24; + for (unsigned j = 0; j < 8; j++) + r = (r << 1) ^ (kBZip2CrcPoly & ((UInt32)0 - (r >> 31))); + Table[i] = r; + } +} + +static +class CBZip2CrcTableInit +{ +public: + CBZip2CrcTableInit() { CBZip2Crc::InitTable(); } +} g_BZip2CrcTableInit; diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Crc.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.h --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Crc.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Crc.h 2023-03-28 10:00:00.000000000 +0000 @@ -1,31 +1,31 @@ -// BZip2Crc.h - -#ifndef __BZIP2_CRC_H -#define __BZIP2_CRC_H - -#include "../../Common/MyTypes.h" - -class CBZip2Crc -{ - UInt32 _value; - static UInt32 Table[256]; -public: - static void InitTable(); - CBZip2Crc(): _value(0xFFFFFFFF) {}; - void Init() { _value = 0xFFFFFFFF; } - void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } - void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } - UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } -}; - -class CBZip2CombinedCrc -{ - UInt32 _value; -public: - CBZip2CombinedCrc(): _value(0){}; - void Init() { _value = 0; } - void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } - UInt32 GetDigest() const { return _value ; } -}; - -#endif +// BZip2Crc.h + +#ifndef ZIP7_INC_BZIP2_CRC_H +#define ZIP7_INC_BZIP2_CRC_H + +#include "../../Common/MyTypes.h" + +class CBZip2Crc +{ + UInt32 _value; + static UInt32 Table[256]; +public: + static void InitTable(); + CBZip2Crc(UInt32 initVal = 0xFFFFFFFF): _value(initVal) {} + void Init(UInt32 initVal = 0xFFFFFFFF) { _value = initVal; } + void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + void UpdateByte(unsigned b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } + UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } +}; + +class CBZip2CombinedCrc +{ + UInt32 _value; +public: + CBZip2CombinedCrc(): _value(0) {} + void Init() { _value = 0; } + void Update(UInt32 v) { _value = ((_value << 1) | (_value >> 31)) ^ v; } + UInt32 GetDigest() const { return _value ; } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Decoder.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -1,994 +1,1777 @@ -// BZip2Decoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "BZip2Decoder.h" -#include "Mtf8.h" - -namespace NCompress { -namespace NBZip2 { - -#undef NO_INLINE -#define NO_INLINE - -static const UInt32 kNumThreadsMax = 4; - -static const UInt32 kBufferSize = (1 << 17); - -static const UInt16 kRandNums[512] = { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 -}; - -bool CState::Alloc() -{ - if (!Counters) - Counters = (UInt32 *)::BigAlloc((256 + kBlockSizeMax) * sizeof(UInt32)); - return (Counters != 0); -} - -void CState::Free() -{ - ::BigFree(Counters); - Counters = 0; -} - -Byte CDecoder::ReadByte() { return (Byte)Base.ReadBits(8); } - -UInt32 CBase::ReadBits(unsigned numBits) { return BitDecoder.ReadBits(numBits); } -unsigned CBase::ReadBit() { return (unsigned)BitDecoder.ReadBits(1); } - -HRESULT CBase::ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props) -{ - NumBlocks++; - - if (props->randMode) - props->randMode = ReadBit() ? true : false; - props->origPtr = ReadBits(kNumOrigBits); - - // in original code it compares OrigPtr to (UInt32)(10 + blockSizeMax)) : why ? - if (props->origPtr >= blockSizeMax) - return S_FALSE; - - CMtf8Decoder mtf; - mtf.StartInit(); - - unsigned numInUse = 0; - { - Byte inUse16[16]; - unsigned i; - for (i = 0; i < 16; i++) - inUse16[i] = (Byte)ReadBit(); - for (i = 0; i < 256; i++) - if (inUse16[i >> 4]) - { - if (ReadBit()) - mtf.Add(numInUse++, (Byte)i); - } - if (numInUse == 0) - return S_FALSE; - // mtf.Init(numInUse); - } - unsigned alphaSize = numInUse + 2; - - unsigned numTables = ReadBits(kNumTablesBits); - if (numTables < kNumTablesMin || numTables > kNumTablesMax) - return S_FALSE; - - UInt32 numSelectors = ReadBits(kNumSelectorsBits); - if (numSelectors < 1 || numSelectors > kNumSelectorsMax) - return S_FALSE; - - { - Byte mtfPos[kNumTablesMax]; - unsigned t = 0; - do - mtfPos[t] = (Byte)t; - while (++t < numTables); - UInt32 i = 0; - do - { - unsigned j = 0; - while (ReadBit()) - if (++j >= numTables) - return S_FALSE; - Byte tmp = mtfPos[j]; - for (;j > 0; j--) - mtfPos[j] = mtfPos[j - 1]; - m_Selectors[i] = mtfPos[0] = tmp; - } - while (++i < numSelectors); - } - - unsigned t = 0; - do - { - Byte lens[kMaxAlphaSize]; - unsigned len = (unsigned)ReadBits(kNumLevelsBits); - unsigned i; - for (i = 0; i < alphaSize; i++) - { - for (;;) - { - if (len < 1 || len > kMaxHuffmanLen) - return S_FALSE; - if (!ReadBit()) - break; - len++; - len -= (ReadBit() << 1); - } - lens[i] = (Byte)len; - } - for (; i < kMaxAlphaSize; i++) - lens[i] = 0; - if (!m_HuffmanDecoders[t].Build(lens)) - return S_FALSE; - } - while (++t < numTables); - - { - for (unsigned i = 0; i < 256; i++) - charCounters[i] = 0; - } - - UInt32 blockSize = 0; - { - UInt32 groupIndex = 0; - UInt32 groupSize = 0; - CHuffmanDecoder *huffmanDecoder = 0; - unsigned runPower = 0; - UInt32 runCounter = 0; - - for (;;) - { - if (groupSize == 0) - { - if (groupIndex >= numSelectors) - return S_FALSE; - groupSize = kGroupSize; - huffmanDecoder = &m_HuffmanDecoders[m_Selectors[groupIndex++]]; - } - groupSize--; - - if (BitDecoder.ExtraBitsWereRead_Fast()) - break; - - UInt32 nextSym = huffmanDecoder->Decode(&BitDecoder); - - if (nextSym < 2) - { - runCounter += ((UInt32)(nextSym + 1) << runPower++); - if (blockSizeMax - blockSize < runCounter) - return S_FALSE; - continue; - } - if (runCounter != 0) - { - UInt32 b = (UInt32)mtf.GetHead(); - charCounters[b] += runCounter; - do - charCounters[256 + blockSize++] = b; - while (--runCounter != 0); - runPower = 0; - } - if (nextSym <= (UInt32)numInUse) - { - UInt32 b = (UInt32)mtf.GetAndMove((unsigned)nextSym - 1); - if (blockSize >= blockSizeMax) - return S_FALSE; - charCounters[b]++; - charCounters[256 + blockSize++] = b; - } - else if (nextSym == (UInt32)numInUse + 1) - break; - else - return S_FALSE; - } - - if (BitDecoder.ExtraBitsWereRead()) - return S_FALSE; - } - props->blockSize = blockSize; - return (props->origPtr < props->blockSize) ? S_OK : S_FALSE; -} - -static void NO_INLINE DecodeBlock1(UInt32 *charCounters, UInt32 blockSize) -{ - { - UInt32 sum = 0; - for (UInt32 i = 0; i < 256; i++) - { - sum += charCounters[i]; - charCounters[i] = sum - charCounters[i]; - } - } - - UInt32 *tt = charCounters + 256; - // Compute the T^(-1) vector - UInt32 i = 0; - do - tt[charCounters[tt[i] & 0xFF]++] |= (i << 8); - while (++i < blockSize); -} - -static UInt32 NO_INLINE DecodeBlock2(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) -{ - CBZip2Crc crc; - - // it's for speed optimization: prefetch & prevByte_init; - UInt32 tPos = tt[tt[OrigPtr] >> 8]; - unsigned prevByte = (unsigned)(tPos & 0xFF); - - unsigned numReps = 0; - - do - { - unsigned b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - - if (numReps == kRleModeRepSize) - { - for (; b > 0; b--) - { - crc.UpdateByte(prevByte); - m_OutStream.WriteByte((Byte)prevByte); - } - numReps = 0; - continue; - } - if (b != prevByte) - numReps = 0; - numReps++; - prevByte = b; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - - /* - prevByte = b; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - for (; --blockSize != 0;) - { - b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - if (b != prevByte) - { - prevByte = b; - continue; - } - if (--blockSize == 0) - break; - - b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - if (b != prevByte) - { - prevByte = b; - continue; - } - if (--blockSize == 0) - break; - - b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - if (b != prevByte) - { - prevByte = b; - continue; - } - --blockSize; - break; - } - if (blockSize == 0) - break; - - b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - - for (; b > 0; b--) - { - crc.UpdateByte(prevByte); - m_OutStream.WriteByte((Byte)prevByte); - } - */ - } - while (--blockSize != 0); - return crc.GetDigest(); -} - -static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UInt32 OrigPtr, COutBuffer &m_OutStream) -{ - CBZip2Crc crc; - - UInt32 randIndex = 1; - UInt32 randToGo = kRandNums[0] - 2; - - unsigned numReps = 0; - - // it's for speed optimization: prefetch & prevByte_init; - UInt32 tPos = tt[tt[OrigPtr] >> 8]; - unsigned prevByte = (unsigned)(tPos & 0xFF); - - do - { - unsigned b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - - { - if (randToGo == 0) - { - b ^= 1; - randToGo = kRandNums[randIndex++]; - randIndex &= 0x1FF; - } - randToGo--; - } - - if (numReps == kRleModeRepSize) - { - for (; b > 0; b--) - { - crc.UpdateByte(prevByte); - m_OutStream.WriteByte((Byte)prevByte); - } - numReps = 0; - continue; - } - if (b != prevByte) - numReps = 0; - numReps++; - prevByte = b; - crc.UpdateByte(b); - m_OutStream.WriteByte((Byte)b); - } - while (--blockSize != 0); - return crc.GetDigest(); -} - -static UInt32 NO_INLINE DecodeBlock(const CBlockProps &props, UInt32 *tt, COutBuffer &m_OutStream) -{ - if (props.randMode) - return DecodeBlock2Rand(tt, props.blockSize, props.origPtr, m_OutStream); - else - return DecodeBlock2 (tt, props.blockSize, props.origPtr, m_OutStream); -} - -CDecoder::CDecoder() -{ - #ifndef _7ZIP_ST - m_States = 0; - m_NumThreadsPrev = 0; - NumThreads = 1; - #endif - _needInStreamInit = true; -} - -#ifndef _7ZIP_ST - -CDecoder::~CDecoder() -{ - Free(); -} - -#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; } - -HRESULT CDecoder::Create() -{ - RINOK_THREAD(CanProcessEvent.CreateIfNotCreated()); - RINOK_THREAD(CanStartWaitingEvent.CreateIfNotCreated()); - if (m_States != 0 && m_NumThreadsPrev == NumThreads) - return S_OK; - Free(); - MtMode = (NumThreads > 1); - m_NumThreadsPrev = NumThreads; - try - { - m_States = new CState[NumThreads]; - if (!m_States) - return E_OUTOFMEMORY; - } - catch(...) { return E_OUTOFMEMORY; } - for (UInt32 t = 0; t < NumThreads; t++) - { - CState &ti = m_States[t]; - ti.Decoder = this; - if (MtMode) - { - HRESULT res = ti.Create(); - if (res != S_OK) - { - NumThreads = t; - Free(); - return res; - } - } - } - return S_OK; -} - -void CDecoder::Free() -{ - if (!m_States) - return; - CloseThreads = true; - CanProcessEvent.Set(); - for (UInt32 t = 0; t < NumThreads; t++) - { - CState &s = m_States[t]; - if (MtMode) - s.Thread.Wait(); - s.Free(); - } - delete []m_States; - m_States = 0; -} - -#endif - -bool IsEndSig(const Byte *p) throw() -{ - return - p[0] == kFinSig0 && - p[1] == kFinSig1 && - p[2] == kFinSig2 && - p[3] == kFinSig3 && - p[4] == kFinSig4 && - p[5] == kFinSig5; -} - -bool IsBlockSig(const Byte *p) throw() -{ - return - p[0] == kBlockSig0 && - p[1] == kBlockSig1 && - p[2] == kBlockSig2 && - p[3] == kBlockSig3 && - p[4] == kBlockSig4 && - p[5] == kBlockSig5; -} - -HRESULT CDecoder::ReadSignature(UInt32 &crc) -{ - BzWasFinished = false; - crc = 0; - - Byte s[10]; - unsigned i; - for (i = 0; i < 10; i++) - s[i] = ReadByte(); - - if (Base.BitDecoder.ExtraBitsWereRead()) - return S_FALSE; - - UInt32 v = 0; - for (i = 0; i < 4; i++) - { - v <<= 8; - v |= s[6 + i]; - } - - crc = v; - - if (IsBlockSig(s)) - { - IsBz = true; - CombinedCrc.Update(crc); - return S_OK; - } - - if (!IsEndSig(s)) - return S_FALSE; - - IsBz = true; - BzWasFinished = true; - if (crc != CombinedCrc.GetDigest()) - { - CrcError = true; - return S_FALSE; - } - return S_OK; -} - -HRESULT CDecoder::DecodeFile(ICompressProgressInfo *progress) -{ - Progress = progress; - #ifndef _7ZIP_ST - RINOK(Create()); - for (UInt32 t = 0; t < NumThreads; t++) - { - CState &s = m_States[t]; - if (!s.Alloc()) - return E_OUTOFMEMORY; - if (MtMode) - { - RINOK(s.StreamWasFinishedEvent.Reset()); - RINOK(s.WaitingWasStartedEvent.Reset()); - RINOK(s.CanWriteEvent.Reset()); - } - } - #else - if (!m_States[0].Alloc()) - return E_OUTOFMEMORY; - #endif - - IsBz = false; - - /* - if (Base.BitDecoder.ExtraBitsWereRead()) - return E_FAIL; - */ - - Byte s[4]; - unsigned i; - for (i = 0; i < 4; i++) - s[i] = ReadByte(); - if (Base.BitDecoder.ExtraBitsWereRead()) - return S_FALSE; - - if (s[0] != kArSig0 || - s[1] != kArSig1 || - s[2] != kArSig2 || - s[3] <= kArSig3 || - s[3] > kArSig3 + kBlockSizeMultMax) - return S_FALSE; - - UInt32 dicSize = (UInt32)(s[3] - kArSig3) * kBlockSizeStep; - - CombinedCrc.Init(); - #ifndef _7ZIP_ST - if (MtMode) - { - NextBlockIndex = 0; - StreamWasFinished1 = StreamWasFinished2 = false; - CloseThreads = false; - CanStartWaitingEvent.Reset(); - m_States[0].CanWriteEvent.Set(); - BlockSizeMax = dicSize; - Result1 = Result2 = S_OK; - CanProcessEvent.Set(); - UInt32 t; - for (t = 0; t < NumThreads; t++) - m_States[t].StreamWasFinishedEvent.Lock(); - CanProcessEvent.Reset(); - CanStartWaitingEvent.Set(); - for (t = 0; t < NumThreads; t++) - m_States[t].WaitingWasStartedEvent.Lock(); - CanStartWaitingEvent.Reset(); - RINOK(Result2); - RINOK(Result1); - } - else - #endif - { - CState &state = m_States[0]; - for (;;) - { - RINOK(SetRatioProgress(Base.BitDecoder.GetProcessedSize())); - UInt32 crc; - RINOK(ReadSignature(crc)); - if (BzWasFinished) - return S_OK; - - CBlockProps props; - props.randMode = true; - RINOK(Base.ReadBlock(state.Counters, dicSize, &props)); - DecodeBlock1(state.Counters, props.blockSize); - if (DecodeBlock(props, state.Counters + 256, m_OutStream) != crc) - { - CrcError = true; - return S_FALSE; - } - } - } - return SetRatioProgress(Base.BitDecoder.GetProcessedSize()); -} - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - ICompressProgressInfo *progress) -{ - IsBz = false; - BzWasFinished = false; - CrcError = false; - - try - { - - if (!Base.BitDecoder.Create(kBufferSize)) - return E_OUTOFMEMORY; - if (!m_OutStream.Create(kBufferSize)) - return E_OUTOFMEMORY; - - if (inStream) - Base.BitDecoder.SetStream(inStream); - - CDecoderFlusher flusher(this); - - if (_needInStreamInit) - { - Base.BitDecoder.Init(); - _needInStreamInit = false; - } - _inStart = Base.BitDecoder.GetProcessedSize(); - - Base.BitDecoder.AlignToByte(); - - m_OutStream.SetStream(outStream); - m_OutStream.Init(); - - RINOK(DecodeFile(progress)); - flusher.NeedFlush = false; - return Flush(); - - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - _needInStreamInit = true; - return CodeReal(inStream, outStream, progress); -} - -HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - return CodeReal(NULL, outStream, progress); -} - -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) -{ - Base.InStreamRef = inStream; - Base.BitDecoder.SetStream(inStream); - return S_OK; -} - -STDMETHODIMP CDecoder::ReleaseInStream() -{ - Base.InStreamRef.Release(); - return S_OK; -} - -#ifndef _7ZIP_ST - -static THREAD_FUNC_DECL MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; } - -HRESULT CState::Create() -{ - RINOK_THREAD(StreamWasFinishedEvent.CreateIfNotCreated()); - RINOK_THREAD(WaitingWasStartedEvent.CreateIfNotCreated()); - RINOK_THREAD(CanWriteEvent.CreateIfNotCreated()); - RINOK_THREAD(Thread.Create(MFThread, this)); - return S_OK; -} - -void CState::FinishStream() -{ - Decoder->StreamWasFinished1 = true; - StreamWasFinishedEvent.Set(); - Decoder->CS.Leave(); - Decoder->CanStartWaitingEvent.Lock(); - WaitingWasStartedEvent.Set(); -} - -void CState::ThreadFunc() -{ - for (;;) - { - Decoder->CanProcessEvent.Lock(); - Decoder->CS.Enter(); - if (Decoder->CloseThreads) - { - Decoder->CS.Leave(); - return; - } - if (Decoder->StreamWasFinished1) - { - FinishStream(); - continue; - } - HRESULT res = S_OK; - - UInt32 blockIndex = Decoder->NextBlockIndex; - UInt32 nextBlockIndex = blockIndex + 1; - if (nextBlockIndex == Decoder->NumThreads) - nextBlockIndex = 0; - Decoder->NextBlockIndex = nextBlockIndex; - UInt32 crc; - UInt64 packSize = 0; - CBlockProps props; - - try - { - res = Decoder->ReadSignature(crc); - if (res != S_OK) - { - Decoder->Result1 = res; - FinishStream(); - continue; - } - if (Decoder->BzWasFinished) - { - Decoder->Result1 = res; - FinishStream(); - continue; - } - - props.randMode = true; - res = Decoder->Base.ReadBlock(Counters, Decoder->BlockSizeMax, &props); - if (res != S_OK) - { - Decoder->Result1 = res; - FinishStream(); - continue; - } - packSize = Decoder->Base.BitDecoder.GetProcessedSize(); - } - catch(const CInBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; } - catch(...) { res = E_FAIL; } - if (res != S_OK) - { - Decoder->Result1 = res; - FinishStream(); - continue; - } - - Decoder->CS.Leave(); - - DecodeBlock1(Counters, props.blockSize); - - bool needFinish = true; - try - { - Decoder->m_States[blockIndex].CanWriteEvent.Lock(); - needFinish = Decoder->StreamWasFinished2; - if (!needFinish) - { - if (DecodeBlock(props, Counters + 256, Decoder->m_OutStream) == crc) - res = Decoder->SetRatioProgress(packSize); - else - res = S_FALSE; - } - } - catch(const COutBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; } - catch(...) { res = E_FAIL; } - if (res != S_OK) - { - Decoder->Result2 = res; - Decoder->StreamWasFinished2 = true; - } - Decoder->m_States[nextBlockIndex].CanWriteEvent.Set(); - if (res != S_OK || needFinish) - { - StreamWasFinishedEvent.Set(); - Decoder->CanStartWaitingEvent.Lock(); - WaitingWasStartedEvent.Set(); - } - } -} - -STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads) -{ - NumThreads = numThreads; - if (NumThreads < 1) - NumThreads = 1; - if (NumThreads > kNumThreadsMax) - NumThreads = kNumThreadsMax; - return S_OK; -} - -#endif - -HRESULT CDecoder::SetRatioProgress(UInt64 packSize) -{ - if (!Progress) - return S_OK; - packSize -= _inStart; - UInt64 unpackSize = m_OutStream.GetProcessedSize(); - return Progress->SetRatioInfo(&packSize, &unpackSize); -} - - -// ---------- NSIS ---------- - -enum -{ - NSIS_STATE_INIT, - NSIS_STATE_NEW_BLOCK, - NSIS_STATE_DATA, - NSIS_STATE_FINISHED, - NSIS_STATE_ERROR -}; - -STDMETHODIMP CNsisDecoder::SetInStream(ISequentialInStream *inStream) -{ - Base.InStreamRef = inStream; - Base.BitDecoder.SetStream(inStream); - return S_OK; -} -STDMETHODIMP CNsisDecoder::ReleaseInStream() -{ - Base.InStreamRef.Release(); - return S_OK; -} - -STDMETHODIMP CNsisDecoder::SetOutStreamSize(const UInt64 * /* outSize */) -{ - _nsisState = NSIS_STATE_INIT; - return S_OK; -} - -STDMETHODIMP CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - try { - - *processedSize = 0; - if (_nsisState == NSIS_STATE_FINISHED) - return S_OK; - if (_nsisState == NSIS_STATE_ERROR) - return S_FALSE; - if (size == 0) - return S_OK; - - CState &state = m_State; - - if (_nsisState == NSIS_STATE_INIT) - { - if (!Base.BitDecoder.Create(kBufferSize)) - return E_OUTOFMEMORY; - if (!state.Alloc()) - return E_OUTOFMEMORY; - Base.BitDecoder.Init(); - _nsisState = NSIS_STATE_NEW_BLOCK; - } - - if (_nsisState == NSIS_STATE_NEW_BLOCK) - { - Byte b = (Byte)Base.ReadBits(8); - if (b == kFinSig0) - { - _nsisState = NSIS_STATE_FINISHED; - return S_OK; - } - if (b != kBlockSig0) - { - _nsisState = NSIS_STATE_ERROR; - return S_FALSE; - } - CBlockProps props; - props.randMode = false; - RINOK(Base.ReadBlock(state.Counters, 9 * kBlockSizeStep, &props)); - _blockSize = props.blockSize; - DecodeBlock1(state.Counters, props.blockSize); - const UInt32 *tt = state.Counters + 256; - _tPos = tt[tt[props.origPtr] >> 8]; - _prevByte = (unsigned)(_tPos & 0xFF); - _numReps = 0; - _repRem = 0; - _nsisState = NSIS_STATE_DATA; - } - - UInt32 tPos = _tPos; - unsigned prevByte = _prevByte; - unsigned numReps = _numReps; - UInt32 blockSize = _blockSize; - const UInt32 *tt = state.Counters + 256; - - while (_repRem) - { - _repRem--; - *(Byte *)data = (Byte)prevByte; - data = (Byte *)data + 1; - (*processedSize)++; - if (--size == 0) - return S_OK; - } - - if (blockSize == 0) - { - _nsisState = NSIS_STATE_NEW_BLOCK; - return S_OK; - } - - do - { - unsigned b = (unsigned)(tPos & 0xFF); - tPos = tt[tPos >> 8]; - blockSize--; - - if (numReps == kRleModeRepSize) - { - numReps = 0; - while (b) - { - b--; - *(Byte *)data = (Byte)prevByte; - data = (Byte *)data + 1; - (*processedSize)++; - if (--size == 0) - break; - } - _repRem = b; - continue; - } - if (b != prevByte) - numReps = 0; - numReps++; - prevByte = b; - *(Byte *)data = (Byte)b; - data = (Byte *)data + 1; - (*processedSize)++; - size--; - } - while (size && blockSize); - _tPos = tPos; - _prevByte = prevByte; - _numReps = numReps; - _blockSize = blockSize; - return S_OK; - - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}} +// BZip2Decoder.cpp + +#include "StdAfx.h" + +// #include "CopyCoder.h" + +/* +#include +#include "../../../C/CpuTicks.h" +*/ +#define TICKS_START +#define TICKS_UPDATE(n) + + +/* +#define PRIN(s) printf(s "\n"); fflush(stdout); +#define PRIN_VAL(s, val) printf(s " = %u \n", val); fflush(stdout); +*/ + +#define PRIN(s) +#define PRIN_VAL(s, val) + + +#include "../../../C/Alloc.h" + +#include "../Common/StreamUtils.h" + +#include "BZip2Decoder.h" + + +namespace NCompress { +namespace NBZip2 { + +// #undef NO_INLINE +#define NO_INLINE Z7_NO_INLINE + +#define BZIP2_BYTE_MODE + + +static const UInt32 kInBufSize = (UInt32)1 << 17; +static const size_t kOutBufSize = (size_t)1 << 20; + +static const UInt32 kProgressStep = (UInt32)1 << 16; + +MY_ALIGN(64) +static const UInt16 kRandNums[512] = { + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, + 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, + 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, + 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, + 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, + 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, + 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, + 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, + 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, + 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, + 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, + 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, + 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, + 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, + 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, + 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, + 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, + 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, + 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, + 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, + 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, + 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, + 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, + 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, + 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, + 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, + 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, + 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, + 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, + 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, + 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, + 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, + 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, + 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, + 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 +}; + + + +enum EState +{ + STATE_STREAM_SIGNATURE, + STATE_BLOCK_SIGNATURE, + + STATE_BLOCK_START, + STATE_ORIG_BITS, + STATE_IN_USE, + STATE_IN_USE2, + STATE_NUM_TABLES, + STATE_NUM_SELECTORS, + STATE_SELECTORS, + STATE_LEVELS, + + STATE_BLOCK_SYMBOLS, + + STATE_STREAM_FINISHED +}; + + +#define UPDATE_VAL_2(val, num_bits) { \ + val |= (UInt32)(*_buf) << (24 - num_bits); \ + num_bits += 8; \ + _buf++; \ +} + +#define UPDATE_VAL UPDATE_VAL_2(VAL, NUM_BITS) + +#define READ_BITS(res, num) { \ + while (_numBits < num) { \ + if (_buf == _lim) return SZ_OK; \ + UPDATE_VAL_2(_value, _numBits) } \ + res = _value >> (32 - num); \ + _value <<= num; \ + _numBits -= num; \ +} + +#define READ_BITS_8(res, num) { \ + if (_numBits < num) { \ + if (_buf == _lim) return SZ_OK; \ + UPDATE_VAL_2(_value, _numBits) } \ + res = _value >> (32 - num); \ + _value <<= num; \ + _numBits -= num; \ +} + +#define READ_BIT(res) READ_BITS_8(res, 1) + + + +#define VAL _value2 +// #define NUM_BITS _numBits2 +#define NUM_BITS _numBits +#define BLOCK_SIZE blockSize2 +#define RUN_COUNTER runCounter2 + +#define LOAD_LOCAL \ + UInt32 VAL = this->_value; \ + /* unsigned NUM_BITS = this->_numBits; */ \ + UInt32 BLOCK_SIZE = this->blockSize; \ + UInt32 RUN_COUNTER = this->runCounter; \ + +#define SAVE_LOCAL \ + this->_value = VAL; \ + /* this->_numBits = NUM_BITS; */ \ + this->blockSize = BLOCK_SIZE; \ + this->runCounter = RUN_COUNTER; \ + + + +SRes CBitDecoder::ReadByte(int &b) +{ + b = -1; + READ_BITS_8(b, 8) + return SZ_OK; +} + + +NO_INLINE +SRes CBase::ReadStreamSignature2() +{ + for (;;) + { + unsigned b; + READ_BITS_8(b, 8) + + if ( (state2 == 0 && b != kArSig0) + || (state2 == 1 && b != kArSig1) + || (state2 == 2 && b != kArSig2) + || (state2 == 3 && (b <= kArSig3 || b > kArSig3 + kBlockSizeMultMax))) + return SZ_ERROR_DATA; + state2++; + + if (state2 == 4) + { + blockSizeMax = (UInt32)(b - kArSig3) * kBlockSizeStep; + CombinedCrc.Init(); + state = STATE_BLOCK_SIGNATURE; + state2 = 0; + return SZ_OK; + } + } +} + + +bool IsEndSig(const Byte *p) throw() +{ + return + p[0] == kFinSig0 && + p[1] == kFinSig1 && + p[2] == kFinSig2 && + p[3] == kFinSig3 && + p[4] == kFinSig4 && + p[5] == kFinSig5; +} + +bool IsBlockSig(const Byte *p) throw() +{ + return + p[0] == kBlockSig0 && + p[1] == kBlockSig1 && + p[2] == kBlockSig2 && + p[3] == kBlockSig3 && + p[4] == kBlockSig4 && + p[5] == kBlockSig5; +} + + +NO_INLINE +SRes CBase::ReadBlockSignature2() +{ + while (state2 < 10) + { + unsigned b; + READ_BITS_8(b, 8) + temp[state2] = (Byte)b; + state2++; + } + + crc = 0; + for (unsigned i = 0; i < 4; i++) + { + crc <<= 8; + crc |= temp[6 + i]; + } + + if (IsBlockSig(temp)) + { + if (!IsBz) + NumStreams++; + NumBlocks++; + IsBz = true; + CombinedCrc.Update(crc); + state = STATE_BLOCK_START; + return SZ_OK; + } + + if (!IsEndSig(temp)) + return SZ_ERROR_DATA; + + if (!IsBz) + NumStreams++; + IsBz = true; + + if (_value != 0) + MinorError = true; + + AlignToByte(); + + state = STATE_STREAM_FINISHED; + if (crc != CombinedCrc.GetDigest()) + { + StreamCrcError = true; + return SZ_ERROR_DATA; + } + return SZ_OK; +} + + +NO_INLINE +SRes CBase::ReadBlock2() +{ + if (state != STATE_BLOCK_SYMBOLS) { + PRIN("ReadBlock2") + + if (state == STATE_BLOCK_START) + { + if (Props.randMode) + { + READ_BIT(Props.randMode) + } + state = STATE_ORIG_BITS; + // g_Tick = GetCpuTicks(); + } + + if (state == STATE_ORIG_BITS) + { + READ_BITS(Props.origPtr, kNumOrigBits) + if (Props.origPtr >= blockSizeMax) + return SZ_ERROR_DATA; + state = STATE_IN_USE; + } + + // why original code compares origPtr to (UInt32)(10 + blockSizeMax)) ? + + if (state == STATE_IN_USE) + { + READ_BITS(state2, 16) + state = STATE_IN_USE2; + state3 = 0; + numInUse = 0; + mtf.StartInit(); + } + + if (state == STATE_IN_USE2) + { + for (; state3 < 256; state3++) + if (state2 & ((UInt32)0x8000 >> (state3 >> 4))) + { + unsigned b; + READ_BIT(b) + if (b) + mtf.Add(numInUse++, (Byte)state3); + } + if (numInUse == 0) + return SZ_ERROR_DATA; + state = STATE_NUM_TABLES; + } + + + if (state == STATE_NUM_TABLES) + { + READ_BITS_8(numTables, kNumTablesBits) + state = STATE_NUM_SELECTORS; + if (numTables < kNumTablesMin || numTables > kNumTablesMax) + return SZ_ERROR_DATA; + } + + if (state == STATE_NUM_SELECTORS) + { + READ_BITS(numSelectors, kNumSelectorsBits) + state = STATE_SELECTORS; + state2 = 0x543210; + state3 = 0; + state4 = 0; + // lbzip2 can write small number of additional selectors, + // 20.01: we allow big number of selectors here like bzip2-1.0.8 + if (numSelectors == 0 + // || numSelectors > kNumSelectorsMax_Decoder + ) + return SZ_ERROR_DATA; + } + + if (state == STATE_SELECTORS) + { + const unsigned kMtfBits = 4; + const UInt32 kMtfMask = (1 << kMtfBits) - 1; + do + { + for (;;) + { + unsigned b; + READ_BIT(b) + if (!b) + break; + if (++state4 >= numTables) + return SZ_ERROR_DATA; + } + const UInt32 tmp = (state2 >> (kMtfBits * state4)) & kMtfMask; + const UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1; + state4 = 0; + state2 = ((state2 << kMtfBits) & mask) | (state2 & ~mask) | tmp; + // 20.01: here we keep compatibility with bzip2-1.0.8 decoder: + if (state3 < kNumSelectorsMax) + selectors[state3] = (Byte)tmp; + } + while (++state3 < numSelectors); + + // we allowed additional dummy selector records filled above to support lbzip2's archives. + // but we still don't allow to use these additional dummy selectors in the code bellow + // bzip2 1.0.8 decoder also has similar restriction. + + if (numSelectors > kNumSelectorsMax) + numSelectors = kNumSelectorsMax; + + state = STATE_LEVELS; + state2 = 0; + state3 = 0; + } + + if (state == STATE_LEVELS) + { + do + { + if (state3 == 0) + { + READ_BITS_8(state3, kNumLevelsBits) + state4 = 0; + state5 = 0; + } + const unsigned alphaSize = numInUse + 2; + for (; state4 < alphaSize; state4++) + { + for (;;) + { + if (state3 < 1 || state3 > kMaxHuffmanLen) + return SZ_ERROR_DATA; + + if (state5 == 0) + { + unsigned b; + READ_BIT(b) + if (!b) + break; + } + + state5 = 1; + unsigned b; + READ_BIT(b) + + state5 = 0; + state3++; + state3 -= (b << 1); + } + lens[state4] = (Byte)state3; + state5 = 0; + } + + // 19.03: we use non-full Build() to support lbzip2 archives. + // lbzip2 2.5 can produce dummy tree, where lens[i] = kMaxHuffmanLen + for (unsigned i = state4; i < kMaxAlphaSize; i++) + lens[i] = 0; + if (!huffs[state2].Build(lens)) // k_BuildMode_Partial + return SZ_ERROR_DATA; + state3 = 0; + } + while (++state2 < numTables); + + { + UInt32 *counters = this->Counters; + for (unsigned i = 0; i < 256; i++) + counters[i] = 0; + } + + state = STATE_BLOCK_SYMBOLS; + + groupIndex = 0; + groupSize = kGroupSize; + runPower = 0; + runCounter = 0; + blockSize = 0; + } + + if (state != STATE_BLOCK_SYMBOLS) + return SZ_ERROR_DATA; + + // g_Ticks[3] += GetCpuTicks() - g_Tick; + + } + + { + LOAD_LOCAL + const CHuffmanDecoder *huf = &huffs[selectors[groupIndex]]; + + for (;;) + { + if (groupSize == 0) + { + if (++groupIndex >= numSelectors) + return SZ_ERROR_DATA; + huf = &huffs[selectors[groupIndex]]; + groupSize = kGroupSize; + } + + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL + if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL }}} + + unsigned sym; + + #define MOV_POS(bs, len) \ + { \ + if (NUM_BITS < len) \ + { \ + SAVE_LOCAL \ + return SZ_OK; \ + } \ + VAL <<= len; \ + NUM_BITS -= (unsigned)len; \ + } + + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kMaxHuffmanLen, kNumTableBits, + VAL, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, + { return SZ_ERROR_DATA; }, + MOV_POS, {}, bs) + + groupSize--; + + if (sym < 2) + { + RUN_COUNTER += (UInt32)(sym + 1) << runPower; + runPower++; + if (blockSizeMax - BLOCK_SIZE < RUN_COUNTER) + return SZ_ERROR_DATA; + continue; + } + + UInt32 *counters = this->Counters; + if (RUN_COUNTER != 0) + { + UInt32 b = (UInt32)(mtf.Buf[0] & 0xFF); + counters[b] += RUN_COUNTER; + runPower = 0; + #ifdef BZIP2_BYTE_MODE + Byte *dest = (Byte *)(&counters[256 + kBlockSizeMax]) + BLOCK_SIZE; + const Byte *limit = dest + RUN_COUNTER; + BLOCK_SIZE += RUN_COUNTER; + RUN_COUNTER = 0; + do + { + dest[0] = (Byte)b; + dest[1] = (Byte)b; + dest[2] = (Byte)b; + dest[3] = (Byte)b; + dest += 4; + } + while (dest < limit); + #else + UInt32 *dest = &counters[256 + BLOCK_SIZE]; + const UInt32 *limit = dest + RUN_COUNTER; + BLOCK_SIZE += RUN_COUNTER; + RUN_COUNTER = 0; + do + { + dest[0] = b; + dest[1] = b; + dest[2] = b; + dest[3] = b; + dest += 4; + } + while (dest < limit); + #endif + } + + sym -= 1; + if (sym < numInUse) + { + if (BLOCK_SIZE >= blockSizeMax) + return SZ_ERROR_DATA; + + // UInt32 b = (UInt32)mtf.GetAndMove((unsigned)sym); + + const unsigned lim = sym >> Z7_MTF_MOVS; + const unsigned pos = (sym & Z7_MTF_MASK) << 3; + CMtfVar next = mtf.Buf[lim]; + CMtfVar prev = (next >> pos) & 0xFF; + + #ifdef BZIP2_BYTE_MODE + ((Byte *)(counters + 256 + kBlockSizeMax))[BLOCK_SIZE++] = (Byte)prev; + #else + (counters + 256)[BLOCK_SIZE++] = (UInt32)prev; + #endif + counters[prev]++; + + CMtfVar *m = mtf.Buf; + CMtfVar *mLim = m + lim; + if (lim != 0) + { + do + { + CMtfVar n0 = *m; + *m = (n0 << 8) | prev; + prev = (n0 >> (Z7_MTF_MASK << 3)); + } + while (++m != mLim); + } + + CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); + *mLim = (next & ~mask) | (((next << 8) | prev) & mask); + continue; + } + + if (sym != numInUse) + return SZ_ERROR_DATA; + break; + } + + // we write additional item that will be read in DecodeBlock1 for prefetching + #ifdef BZIP2_BYTE_MODE + ((Byte *)(Counters + 256 + kBlockSizeMax))[BLOCK_SIZE] = 0; + #else + (counters + 256)[BLOCK_SIZE] = 0; + #endif + + SAVE_LOCAL + Props.blockSize = blockSize; + state = STATE_BLOCK_SIGNATURE; + state2 = 0; + + PRIN_VAL("origPtr", Props.origPtr); + PRIN_VAL("blockSize", Props.blockSize); + + return (Props.origPtr < Props.blockSize) ? SZ_OK : SZ_ERROR_DATA; + } +} + + +NO_INLINE +static void DecodeBlock1(UInt32 *counters, UInt32 blockSize) +{ + { + UInt32 sum = 0; + for (UInt32 i = 0; i < 256; i++) + { + const UInt32 v = counters[i]; + counters[i] = sum; + sum += v; + } + } + + UInt32 *tt = counters + 256; + // Compute the T^(-1) vector + + // blockSize--; + + #ifdef BZIP2_BYTE_MODE + + unsigned c = ((const Byte *)(tt + kBlockSizeMax))[0]; + + for (UInt32 i = 0; i < blockSize; i++) + { + unsigned c1 = c; + const UInt32 pos = counters[c]; + c = ((const Byte *)(tt + kBlockSizeMax))[(size_t)i + 1]; + counters[c1] = pos + 1; + tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos]; + } + + /* + // last iteration without next character prefetching + { + const UInt32 pos = counters[c]; + counters[c] = pos + 1; + tt[pos] = (blockSize << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos]; + } + */ + + #else + + unsigned c = (unsigned)(tt[0] & 0xFF); + + for (UInt32 i = 0; i < blockSize; i++) + { + unsigned c1 = c; + const UInt32 pos = counters[c]; + c = (unsigned)(tt[(size_t)i + 1] & 0xFF); + counters[c1] = pos + 1; + tt[pos] |= (i << 8); + } + + /* + { + const UInt32 pos = counters[c]; + counters[c] = pos + 1; + tt[pos] |= (blockSize << 8); + } + */ + + #endif + + + /* + for (UInt32 i = 0; i < blockSize; i++) + { + #ifdef BZIP2_BYTE_MODE + const unsigned c = ((const Byte *)(tt + kBlockSizeMax))[i]; + const UInt32 pos = counters[c]++; + tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos]; + #else + const unsigned c = (unsigned)(tt[i] & 0xFF); + const UInt32 pos = counters[c]++; + tt[pos] |= (i << 8); + #endif + } + */ +} + + +void CSpecState::Init(UInt32 origPtr, unsigned randMode) throw() +{ + _tPos = _tt[_tt[origPtr] >> 8]; + _prevByte = (unsigned)(_tPos & 0xFF); + _reps = 0; + _randIndex = 0; + _randToGo = -1; + if (randMode) + { + _randIndex = 1; + _randToGo = kRandNums[0] - 2; + } + _crc.Init(); +} + + + +NO_INLINE +Byte * CSpecState::Decode(Byte *data, size_t size) throw() +{ + if (size == 0) + return data; + + unsigned prevByte = _prevByte; + int reps = _reps; + CBZip2Crc crc = _crc; + const Byte *lim = data + size; + + while (reps > 0) + { + reps--; + *data++ = (Byte)prevByte; + crc.UpdateByte(prevByte); + if (data == lim) + break; + } + + UInt32 tPos = _tPos; + UInt32 blockSize = _blockSize; + const UInt32 *tt = _tt; + + if (data != lim && blockSize) + + for (;;) + { + unsigned b = (unsigned)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + blockSize--; + + if (_randToGo >= 0) + { + if (_randToGo == 0) + { + b ^= 1; + _randToGo = kRandNums[_randIndex]; + _randIndex++; + _randIndex &= 0x1FF; + } + _randToGo--; + } + + if (reps != -(int)kRleModeRepSize) + { + if (b != prevByte) + reps = 0; + reps--; + prevByte = b; + *data++ = (Byte)b; + crc.UpdateByte(b); + if (data == lim || blockSize == 0) + break; + continue; + } + + reps = (int)b; + while (reps) + { + reps--; + *data++ = (Byte)prevByte; + crc.UpdateByte(prevByte); + if (data == lim) + break; + } + if (data == lim) + break; + if (blockSize == 0) + break; + } + + if (blockSize == 1 && reps == -(int)kRleModeRepSize) + { + unsigned b = (unsigned)(tPos & 0xFF); + tPos = tt[tPos >> 8]; + blockSize--; + + if (_randToGo >= 0) + { + if (_randToGo == 0) + { + b ^= 1; + _randToGo = kRandNums[_randIndex]; + _randIndex++; + _randIndex &= 0x1FF; + } + _randToGo--; + } + + reps = (int)b; + } + + _tPos = tPos; + _prevByte = prevByte; + _reps = reps; + _crc = crc; + _blockSize = blockSize; + + return data; +} + + +HRESULT CDecoder::Flush() +{ + if (_writeRes == S_OK) + { + _writeRes = WriteStream(_outStream, _outBuf, _outPos); + _outWritten += _outPos; + _outPos = 0; + } + return _writeRes; +} + + +NO_INLINE +HRESULT CDecoder::DecodeBlock(const CBlockProps &props) +{ + _calcedBlockCrc = 0; + _blockFinished = false; + + CSpecState block; + + block._blockSize = props.blockSize; + block._tt = _counters + 256; + + block.Init(props.origPtr, props.randMode); + + for (;;) + { + Byte *data = _outBuf + _outPos; + size_t size = kOutBufSize - _outPos; + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outPosTotal; + if (size >= rem) + { + size = (size_t)rem; + if (size == 0) + return FinishMode ? S_FALSE : S_OK; + } + } + + TICKS_START + const size_t processed = (size_t)(block.Decode(data, size) - data); + TICKS_UPDATE(2) + + _outPosTotal += processed; + _outPos += processed; + + if (processed >= size) + { + RINOK(Flush()) + } + + if (block.Finished()) + { + _blockFinished = true; + _calcedBlockCrc = block._crc.GetDigest(); + return S_OK; + } + } +} + + +CDecoder::CDecoder(): + _outBuf(NULL), + FinishMode(false), + _outSizeDefined(false), + _counters(NULL), + _inBuf(NULL), + _inProcessed(0) +{ + #ifndef Z7_ST + MtMode = false; + NeedWaitScout = false; + // ScoutRes = S_OK; + #endif +} + + +CDecoder::~CDecoder() +{ + PRIN("\n~CDecoder()"); + + #ifndef Z7_ST + + if (Thread.IsCreated()) + { + WaitScout(); + + _block.StopScout = true; + + PRIN("\nScoutEvent.Set()"); + ScoutEvent.Set(); + + PRIN("\nThread.Wait()()"); + Thread.Wait_Close(); + PRIN("\n after Thread.Wait()()"); + + // if (ScoutRes != S_OK) throw ScoutRes; + } + + #endif + + BigFree(_counters); + MidFree(_outBuf); + MidFree(_inBuf); +} + + +HRESULT CDecoder::ReadInput() +{ + if (Base._buf != Base._lim || _inputFinished || _inputRes != S_OK) + return _inputRes; + + _inProcessed += (size_t)(Base._buf - _inBuf); + Base._buf = _inBuf; + Base._lim = _inBuf; + UInt32 size = 0; + _inputRes = Base.InStream->Read(_inBuf, kInBufSize, &size); + _inputFinished = (size == 0); + Base._lim = _inBuf + size; + return _inputRes; +} + + +void CDecoder::StartNewStream() +{ + Base.state = STATE_STREAM_SIGNATURE; + Base.state2 = 0; + Base.IsBz = false; +} + + +HRESULT CDecoder::ReadStreamSignature() +{ + for (;;) + { + RINOK(ReadInput()) + SRes res = Base.ReadStreamSignature2(); + if (res != SZ_OK) + return S_FALSE; + if (Base.state == STATE_BLOCK_SIGNATURE) + return S_OK; + if (_inputFinished) + { + Base.NeedMoreInput = true; + return S_FALSE; + } + } +} + + +HRESULT CDecoder::StartRead() +{ + StartNewStream(); + return ReadStreamSignature(); +} + + +HRESULT CDecoder::ReadBlockSignature() +{ + for (;;) + { + RINOK(ReadInput()) + + SRes res = Base.ReadBlockSignature2(); + + if (Base.state == STATE_STREAM_FINISHED) + Base.FinishedPackSize = GetInputProcessedSize(); + if (res != SZ_OK) + return S_FALSE; + if (Base.state != STATE_BLOCK_SIGNATURE) + return S_OK; + if (_inputFinished) + { + Base.NeedMoreInput = true; + return S_FALSE; + } + } +} + + +HRESULT CDecoder::ReadBlock() +{ + for (;;) + { + RINOK(ReadInput()) + + SRes res = Base.ReadBlock2(); + + if (res != SZ_OK) + return S_FALSE; + if (Base.state == STATE_BLOCK_SIGNATURE) + return S_OK; + if (_inputFinished) + { + Base.NeedMoreInput = true; + return S_FALSE; + } + } +} + + + +HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress) +{ + { + #ifndef Z7_ST + _block.StopScout = false; + #endif + } + + RINOK(StartRead()) + + UInt64 inPrev = 0; + UInt64 outPrev = 0; + + { + #ifndef Z7_ST + CWaitScout_Releaser waitScout_Releaser(this); + + bool useMt = false; + #endif + + bool wasFinished = false; + + UInt32 crc = 0; + UInt32 nextCrc = 0; + HRESULT nextRes = S_OK; + + UInt64 packPos = 0; + + CBlockProps props; + + props.blockSize = 0; + + for (;;) + { + if (progress) + { + const UInt64 outCur = GetOutProcessedSize(); + if (packPos - inPrev >= kProgressStep || outCur - outPrev >= kProgressStep) + { + RINOK(progress->SetRatioInfo(&packPos, &outCur)) + inPrev = packPos; + outPrev = outCur; + } + } + + if (props.blockSize == 0) + if (wasFinished || nextRes != S_OK) + return nextRes; + + if ( + #ifndef Z7_ST + !useMt && + #endif + !wasFinished && Base.state == STATE_BLOCK_SIGNATURE) + { + nextRes = ReadBlockSignature(); + nextCrc = Base.crc; + packPos = GetInputProcessedSize(); + + wasFinished = true; + + if (nextRes != S_OK) + continue; + + if (Base.state == STATE_STREAM_FINISHED) + { + if (!Base.DecodeAllStreams) + { + wasFinished = true; + continue; + } + + nextRes = StartRead(); + + if (Base.NeedMoreInput) + { + if (Base.state2 == 0) + Base.NeedMoreInput = false; + wasFinished = true; + nextRes = S_OK; + continue; + } + + if (nextRes != S_OK) + continue; + + wasFinished = false; + continue; + } + + wasFinished = false; + + #ifndef Z7_ST + if (MtMode) + if (props.blockSize != 0) + { + // we start multithreading, if next block is big enough. + const UInt32 k_Mt_BlockSize_Threshold = (1 << 12); // (1 << 13) + if (props.blockSize > k_Mt_BlockSize_Threshold) + { + if (!Thread.IsCreated()) + { + PRIN("=== MT_MODE"); + RINOK(CreateThread()) + } + useMt = true; + } + } + #endif + } + + if (props.blockSize == 0) + { + crc = nextCrc; + + #ifndef Z7_ST + if (useMt) + { + PRIN("DecoderEvent.Lock()"); + { + WRes wres = DecoderEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + NeedWaitScout = false; + PRIN("-- DecoderEvent.Lock()"); + props = _block.Props; + nextCrc = _block.NextCrc; + if (_block.Crc_Defined) + crc = _block.Crc; + packPos = _block.PackPos; + wasFinished = _block.WasFinished; + RINOK(_block.Res) + } + else + #endif + { + if (Base.state != STATE_BLOCK_START) + return E_FAIL; + + TICKS_START + Base.Props.randMode = 1; + RINOK(ReadBlock()) + TICKS_UPDATE(0) + + props = Base.Props; + continue; + } + } + + if (props.blockSize != 0) + { + TICKS_START + DecodeBlock1(_counters, props.blockSize); + TICKS_UPDATE(1) + } + + #ifndef Z7_ST + if (useMt && !wasFinished) + { + /* + if (props.blockSize == 0) + { + // this codes switches back to single-threadMode + useMt = false; + PRIN("=== ST_MODE"); + continue; + } + */ + + PRIN("ScoutEvent.Set()"); + { + WRes wres = ScoutEvent.Set(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + NeedWaitScout = true; + } + #endif + + if (props.blockSize == 0) + continue; + + RINOK(DecodeBlock(props)) + + if (!_blockFinished) + return nextRes; + + props.blockSize = 0; + if (_calcedBlockCrc != crc) + { + BlockCrcError = true; + return S_FALSE; + } + } + } +} + + + + +bool CDecoder::CreateInputBufer() +{ + if (!_inBuf) + { + _inBuf = (Byte *)MidAlloc(kInBufSize); + if (!_inBuf) + return false; + Base._buf = _inBuf; + Base._lim = _inBuf; + } + if (!_counters) + { + const size_t size = (256 + kBlockSizeMax) * sizeof(UInt32) + #ifdef BZIP2_BYTE_MODE + + kBlockSizeMax + #endif + + 256; + _counters = (UInt32 *)::BigAlloc(size); + if (!_counters) + return false; + Base.Counters = _counters; + } + return true; +} + + +void CDecoder::InitOutSize(const UInt64 *outSize) +{ + _outPosTotal = 0; + + _outSizeDefined = false; + _outSize = 0; + if (outSize) + { + _outSize = *outSize; + _outSizeDefined = true; + } + + BlockCrcError = false; + + Base.InitNumStreams2(); +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + /* + { + RINOK(SetInStream(inStream)); + RINOK(SetOutStreamSize(outSize)); + + RINOK(CopyStream(this, outStream, progress)); + return ReleaseInStream(); + } + */ + + _inputFinished = false; + _inputRes = S_OK; + _writeRes = S_OK; + + try { + + InitOutSize(outSize); + + // we can request data from InputBuffer after Code(). + // so we init InputBuffer before any function return. + + InitInputBuffer(); + + if (!CreateInputBufer()) + return E_OUTOFMEMORY; + + if (!_outBuf) + { + _outBuf = (Byte *)MidAlloc(kOutBufSize); + if (!_outBuf) + return E_OUTOFMEMORY; + } + + Base.InStream = inStream; + + // InitInputBuffer(); + + _outStream = outStream; + _outWritten = 0; + _outPos = 0; + + HRESULT res = DecodeStreams(progress); + + Flush(); + + Base.InStream = NULL; + _outStream = NULL; + + /* + if (res == S_OK) + if (FinishMode && inSize && *inSize != GetInputProcessedSize()) + res = S_FALSE; + */ + + if (res != S_OK) + return res; + + } catch(...) { return E_FAIL; } + + return _writeRes; +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishMode = (finishMode != 0); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = GetInStreamSize(); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +{ + Base.AlignToByte(); + UInt32 i; + for (i = 0; i < size; i++) + { + int b; + Base.ReadByte(b); + if (b < 0) + break; + ((Byte *)data)[i] = (Byte)b; + } + if (processedSize) + *processedSize = i; + return S_OK; +} + + +#ifndef Z7_ST + +#define PRIN_MT(s) PRIN(" " s) + +// #define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; } + +static THREAD_FUNC_DECL RunScout2(void *p) { ((CDecoder *)p)->RunScout(); return 0; } + +HRESULT CDecoder::CreateThread() +{ + WRes wres = DecoderEvent.CreateIfNotCreated_Reset(); + if (wres == 0) { wres = ScoutEvent.CreateIfNotCreated_Reset(); + if (wres == 0) { wres = Thread.Create(RunScout2, this); }} + return HRESULT_FROM_WIN32(wres); +} + +void CDecoder::RunScout() +{ + for (;;) + { + { + PRIN_MT("ScoutEvent.Lock()") + WRes wres = ScoutEvent.Lock(); + PRIN_MT("-- ScoutEvent.Lock()") + if (wres != 0) + { + // ScoutRes = wres; + return; + } + } + + CBlock &block = _block; + + if (block.StopScout) + { + // ScoutRes = S_OK; + return; + } + + block.Res = S_OK; + block.WasFinished = false; + + HRESULT res = S_OK; + + try + { + UInt64 packPos = GetInputProcessedSize(); + + block.Props.blockSize = 0; + block.Crc_Defined = false; + // block.NextCrc_Defined = false; + block.NextCrc = 0; + + for (;;) + { + if (Base.state == STATE_BLOCK_SIGNATURE) + { + res = ReadBlockSignature(); + + if (res != S_OK) + break; + + if (block.Props.blockSize == 0) + { + block.Crc = Base.crc; + block.Crc_Defined = true; + } + else + { + block.NextCrc = Base.crc; + // block.NextCrc_Defined = true; + } + + continue; + } + + if (Base.state == STATE_BLOCK_START) + { + if (block.Props.blockSize != 0) + break; + + Base.Props.randMode = 1; + + res = ReadBlock(); + + PRIN_MT("-- Base.ReadBlock") + if (res != S_OK) + break; + block.Props = Base.Props; + continue; + } + + if (Base.state == STATE_STREAM_FINISHED) + { + if (!Base.DecodeAllStreams) + { + block.WasFinished = true; + break; + } + + res = StartRead(); + + if (Base.NeedMoreInput) + { + if (Base.state2 == 0) + Base.NeedMoreInput = false; + block.WasFinished = true; + res = S_OK; + break; + } + + if (res != S_OK) + break; + + if (GetInputProcessedSize() - packPos > 0) // kProgressStep + break; + continue; + } + + // throw 1; + res = E_FAIL; + break; + } + } + + catch (...) { res = E_FAIL; } + + if (res != S_OK) + { + PRIN_MT("error") + block.Res = res; + block.WasFinished = true; + } + + block.PackPos = GetInputProcessedSize(); + PRIN_MT("DecoderEvent.Set()") + WRes wres = DecoderEvent.Set(); + if (wres != 0) + { + // ScoutRes = wres; + return; + } + } +} + + +Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads)) +{ + MtMode = (numThreads > 1); + + #ifndef BZIP2_BYTE_MODE + MtMode = false; + #endif + + // MtMode = false; + return S_OK; +} + +#endif + + + +#ifndef Z7_NO_READ_FROM_CODER + + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) +{ + Base.InStreamRef = inStream; + Base.InStream = inStream; + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) +{ + Base.InStreamRef.Release(); + Base.InStream = NULL; + return S_OK; +} + + + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + InitOutSize(outSize); + + InitInputBuffer(); + + if (!CreateInputBufer()) + return E_OUTOFMEMORY; + + // InitInputBuffer(); + + StartNewStream(); + + _blockFinished = true; + + ErrorResult = S_OK; + + _inputFinished = false; + _inputRes = S_OK; + + return S_OK; +} + + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + *processedSize = 0; + + try { + + if (ErrorResult != S_OK) + return ErrorResult; + + for (;;) + { + if (Base.state == STATE_STREAM_FINISHED) + { + if (!Base.DecodeAllStreams) + return ErrorResult; + StartNewStream(); + continue; + } + + if (Base.state == STATE_STREAM_SIGNATURE) + { + ErrorResult = ReadStreamSignature(); + + if (Base.NeedMoreInput) + if (Base.state2 == 0 && Base.NumStreams != 0) + { + Base.NeedMoreInput = false; + ErrorResult = S_OK; + return S_OK; + } + if (ErrorResult != S_OK) + return ErrorResult; + continue; + } + + if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE) + { + ErrorResult = ReadBlockSignature(); + + if (ErrorResult != S_OK) + return ErrorResult; + + continue; + } + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outPosTotal; + if (size >= rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + if (_blockFinished) + { + if (Base.state != STATE_BLOCK_START) + { + ErrorResult = E_FAIL; + return ErrorResult; + } + + Base.Props.randMode = 1; + ErrorResult = ReadBlock(); + + if (ErrorResult != S_OK) + return ErrorResult; + + DecodeBlock1(_counters, Base.Props.blockSize); + + _spec._blockSize = Base.Props.blockSize; + _spec._tt = _counters + 256; + _spec.Init(Base.Props.origPtr, Base.Props.randMode); + + _blockFinished = false; + } + + { + Byte *ptr = _spec.Decode((Byte *)data, size); + + const UInt32 processed = (UInt32)(ptr - (Byte *)data); + data = ptr; + size -= processed; + (*processedSize) += processed; + _outPosTotal += processed; + + if (_spec.Finished()) + { + _blockFinished = true; + if (Base.crc != _spec._crc.GetDigest()) + { + BlockCrcError = true; + ErrorResult = S_FALSE; + return ErrorResult; + } + } + } + } + + } catch(...) { ErrorResult = S_FALSE; return S_FALSE; } +} + + + +// ---------- NSIS ---------- + +Z7_COM7F_IMF(CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + *processedSize = 0; + + try { + + if (ErrorResult != S_OK) + return ErrorResult; + + if (Base.state == STATE_STREAM_FINISHED) + return S_OK; + + if (Base.state == STATE_STREAM_SIGNATURE) + { + Base.blockSizeMax = 9 * kBlockSizeStep; + Base.state = STATE_BLOCK_SIGNATURE; + // Base.state2 = 0; + } + + for (;;) + { + if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE) + { + ErrorResult = ReadInput(); + if (ErrorResult != S_OK) + return ErrorResult; + + int b; + Base.ReadByte(b); + if (b < 0) + { + ErrorResult = S_FALSE; + return ErrorResult; + } + + if (b == kFinSig0) + { + /* + if (!Base.AreRemainByteBitsEmpty()) + ErrorResult = S_FALSE; + */ + Base.state = STATE_STREAM_FINISHED; + return ErrorResult; + } + + if (b != kBlockSig0) + { + ErrorResult = S_FALSE; + return ErrorResult; + } + + Base.state = STATE_BLOCK_START; + } + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outPosTotal; + if (size >= rem) + size = (UInt32)rem; + } + if (size == 0) + return S_OK; + + if (_blockFinished) + { + if (Base.state != STATE_BLOCK_START) + { + ErrorResult = E_FAIL; + return ErrorResult; + } + + Base.Props.randMode = 0; + ErrorResult = ReadBlock(); + + if (ErrorResult != S_OK) + return ErrorResult; + + DecodeBlock1(_counters, Base.Props.blockSize); + + _spec._blockSize = Base.Props.blockSize; + _spec._tt = _counters + 256; + _spec.Init(Base.Props.origPtr, Base.Props.randMode); + + _blockFinished = false; + } + + { + Byte *ptr = _spec.Decode((Byte *)data, size); + + const UInt32 processed = (UInt32)(ptr - (Byte *)data); + data = ptr; + size -= processed; + (*processedSize) += processed; + _outPosTotal += processed; + + if (_spec.Finished()) + _blockFinished = true; + } + } + + } catch(...) { ErrorResult = S_FALSE; return S_FALSE; } +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Decoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Decoder.h 2024-01-01 16:00:00.000000000 +0000 @@ -1,238 +1,388 @@ -// Compress/BZip2Decoder.h - -#ifndef __COMPRESS_BZIP2_DECODER_H -#define __COMPRESS_BZIP2_DECODER_H - -#include "../../Common/MyCom.h" - -#ifndef _7ZIP_ST -#include "../../Windows/Synchronization.h" -#include "../../Windows/Thread.h" -#endif - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" -#include "../Common/OutBuffer.h" - -#include "BitmDecoder.h" -#include "BZip2Const.h" -#include "BZip2Crc.h" -#include "HuffmanDecoder.h" - -namespace NCompress { -namespace NBZip2 { - -bool IsEndSig(const Byte *p) throw(); -bool IsBlockSig(const Byte *p) throw(); - -typedef NCompress::NHuffman::CDecoder CHuffmanDecoder; - -class CDecoder; - -struct CState -{ - UInt32 *Counters; - - #ifndef _7ZIP_ST - - CDecoder *Decoder; - NWindows::CThread Thread; - bool m_OptimizeNumTables; - - NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; - NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; - - // it's not member of this thread. We just need one event per thread - NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; - - Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. - - HRESULT Create(); - void FinishStream(); - void ThreadFunc(); - - #endif - - CState(): Counters(0) {} - ~CState() { Free(); } - bool Alloc(); - void Free(); -}; - -struct CBlockProps -{ - UInt32 blockSize; - UInt32 origPtr; - bool randMode; - - CBlockProps(): blockSize(0), origPtr(0), randMode(false) {} -}; - -struct CBase -{ - CMyComPtr InStreamRef; - NBitm::CDecoder BitDecoder; - -private: - Byte m_Selectors[kNumSelectorsMax]; - CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; - -public: - UInt64 NumBlocks; - - CBase(): NumBlocks(0) {} - UInt32 ReadBits(unsigned numBits); - unsigned ReadBit(); - void InitNumBlocks() { NumBlocks = 0; } - - /* - ReadBlock() props->randMode: - in: need read randMode bit, - out: randMode status - */ - HRESULT ReadBlock(UInt32 *charCounters, UInt32 blockSizeMax, CBlockProps *props); -}; - -class CDecoder : - public ICompressCoder, - #ifndef _7ZIP_ST - public ICompressSetCoderMt, - #endif - public CMyUnknownImp -{ -public: - COutBuffer m_OutStream; - Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. - - CBase Base; - - UInt64 _inStart; - -private: - - bool _needInStreamInit; - - Byte ReadByte(); - - HRESULT DecodeFile(ICompressProgressInfo *progress); - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); - - class CDecoderFlusher - { - CDecoder *_decoder; - public: - bool NeedFlush; - CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} - ~CDecoderFlusher() - { - if (NeedFlush) - _decoder->Flush(); - } - }; - -public: - CBZip2CombinedCrc CombinedCrc; - ICompressProgressInfo *Progress; - - #ifndef _7ZIP_ST - CState *m_States; - UInt32 m_NumThreadsPrev; - - NWindows::NSynchronization::CManualResetEvent CanProcessEvent; - NWindows::NSynchronization::CCriticalSection CS; - UInt32 NumThreads; - bool MtMode; - UInt32 NextBlockIndex; - bool CloseThreads; - bool StreamWasFinished1; - bool StreamWasFinished2; - NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; - - HRESULT Result1; - HRESULT Result2; - - UInt32 BlockSizeMax; - - ~CDecoder(); - HRESULT Create(); - void Free(); - - #else - CState m_States[1]; - #endif - - bool IsBz; - bool BzWasFinished; // bzip stream was finished with end signature - bool CrcError; // it can CRC error of block or CRC error of whole stream. - - CDecoder(); - - HRESULT SetRatioProgress(UInt64 packSize); - HRESULT ReadSignature(UInt32 &crc); - - HRESULT Flush() { return m_OutStream.Flush(); } - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - #endif - - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - - HRESULT CodeResume(ISequentialOutStream *outStream, ICompressProgressInfo *progress); - - UInt64 GetStreamSize() const { return Base.BitDecoder.GetStreamSize(); } - UInt64 GetInputProcessedSize() const { return Base.BitDecoder.GetProcessedSize(); } - - void InitNumBlocks() { Base.InitNumBlocks(); } - UInt64 GetNumBlocks() const { return Base.NumBlocks; } - - #ifndef _7ZIP_ST - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - #endif -}; - - -class CNsisDecoder : - public ISequentialInStream, - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public CMyUnknownImp -{ - CBase Base; - - CState m_State; - - int _nsisState; - UInt32 _tPos; - unsigned _prevByte; - unsigned _repRem; - unsigned _numReps; - UInt32 _blockSize; - -public: - - MY_QUERYINTERFACE_BEGIN2(ISequentialInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); -}; - -}} - -#endif +// Compress/BZip2Decoder.h + +#ifndef ZIP7_INC_COMPRESS_BZIP2_DECODER_H +#define ZIP7_INC_COMPRESS_BZIP2_DECODER_H + +#include "../../Common/MyCom.h" + +// #define Z7_NO_READ_FROM_CODER +// #define Z7_ST + +#ifndef Z7_ST +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" +#endif + +#include "../ICoder.h" + +#include "BZip2Const.h" +#include "BZip2Crc.h" +#include "HuffmanDecoder.h" +#include "Mtf8.h" + +namespace NCompress { +namespace NBZip2 { + +bool IsEndSig(const Byte *p) throw(); +bool IsBlockSig(const Byte *p) throw(); + +const unsigned kNumTableBits = 9; + +typedef NHuffman::CDecoder CHuffmanDecoder; + + +struct CBlockProps +{ + UInt32 blockSize; + UInt32 origPtr; + unsigned randMode; + + CBlockProps(): blockSize(0), origPtr(0), randMode(0) {} +}; + + +struct CBitDecoder +{ + unsigned _numBits; + UInt32 _value; + const Byte *_buf; + const Byte *_lim; + + void InitBitDecoder() + { + _numBits = 0; + _value = 0; + } + + void AlignToByte() + { + unsigned bits = _numBits & 7; + _numBits -= bits; + _value <<= bits; + } + + /* + bool AreRemainByteBitsEmpty() const + { + unsigned bits = _numBits & 7; + if (bits != 0) + return (_value >> (32 - bits)) == 0; + return true; + } + */ + + SRes ReadByte(int &b); + + CBitDecoder(): + _buf(NULL), + _lim(NULL) + { + InitBitDecoder(); + } +}; + + +// 19.03: we allow additional 8 selectors to support files created by lbzip2. +const UInt32 kNumSelectorsMax_Decoder = kNumSelectorsMax + 8; + +struct CBase: public CBitDecoder +{ + unsigned numInUse; + UInt32 groupIndex; + UInt32 groupSize; + unsigned runPower; + UInt32 runCounter; + UInt32 blockSize; + + UInt32 *Counters; + UInt32 blockSizeMax; + + unsigned state; + UInt32 state2; + unsigned state3; + unsigned state4; + unsigned state5; + unsigned numTables; + UInt32 numSelectors; + + CBlockProps Props; + +private: + CMtf8Decoder mtf; + Byte selectors[kNumSelectorsMax_Decoder]; + CHuffmanDecoder huffs[kNumTablesMax]; + + Byte lens[kMaxAlphaSize]; + + Byte temp[10]; + +public: + UInt32 crc; + CBZip2CombinedCrc CombinedCrc; + + bool IsBz; + bool StreamCrcError; + bool MinorError; + bool NeedMoreInput; + + bool DecodeAllStreams; + + UInt64 NumStreams; + UInt64 NumBlocks; + UInt64 FinishedPackSize; + + ISequentialInStream *InStream; + + #ifndef Z7_NO_READ_FROM_CODER + CMyComPtr InStreamRef; + #endif + + CBase(): + StreamCrcError(false), + MinorError(false), + NeedMoreInput(false), + + DecodeAllStreams(false), + + NumStreams(0), + NumBlocks(0), + FinishedPackSize(0) + {} + + void InitNumStreams2() + { + StreamCrcError = false; + MinorError = false; + NeedMoreInput = 0; + NumStreams = 0; + NumBlocks = 0; + FinishedPackSize = 0; + } + + SRes ReadStreamSignature2(); + SRes ReadBlockSignature2(); + + /* ReadBlock2() : Props->randMode: + in: need read randMode bit + out: randMode status */ + SRes ReadBlock2(); +}; + + +class CSpecState +{ + UInt32 _tPos; + unsigned _prevByte; + int _reps; + +public: + CBZip2Crc _crc; + UInt32 _blockSize; + UInt32 *_tt; + + int _randToGo; + unsigned _randIndex; + + void Init(UInt32 origPtr, unsigned randMode) throw(); + + bool Finished() const { return _reps <= 0 && _blockSize == 0; } + + Byte *Decode(Byte *data, size_t size) throw(); +}; + + + + +class CDecoder: + public ICompressCoder, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressReadUnusedFromInBuf, +#ifndef Z7_NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, +#endif +#ifndef Z7_ST + public ICompressSetCoderMt, +#endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) +#ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) +#endif +#ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP_NONFINAL(ISequentialInStream) +#endif +public: +#ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) +#endif + +private: + Byte *_outBuf; + size_t _outPos; + UInt64 _outWritten; + ISequentialOutStream *_outStream; + HRESULT _writeRes; + +protected: + HRESULT ErrorResult; // for ISequentialInStream::Read mode only + +public: + + UInt32 _calcedBlockCrc; + bool _blockFinished; + bool BlockCrcError; + + bool FinishMode; + bool _outSizeDefined; + UInt64 _outSize; + UInt64 _outPosTotal; + + CSpecState _spec; + UInt32 *_counters; + + #ifndef Z7_ST + + struct CBlock + { + bool StopScout; + + bool WasFinished; + bool Crc_Defined; + // bool NextCrc_Defined; + + UInt32 Crc; + UInt32 NextCrc; + HRESULT Res; + UInt64 PackPos; + + CBlockProps Props; + }; + + CBlock _block; + + bool NeedWaitScout; + bool MtMode; + + NWindows::CThread Thread; + NWindows::NSynchronization::CAutoResetEvent DecoderEvent; + NWindows::NSynchronization::CAutoResetEvent ScoutEvent; + // HRESULT ScoutRes; + + Byte MtPad[1 << 7]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + + + void RunScout(); + + void WaitScout() + { + if (NeedWaitScout) + { + DecoderEvent.Lock(); + NeedWaitScout = false; + } + } + + class CWaitScout_Releaser + { + CDecoder *_decoder; + public: + CWaitScout_Releaser(CDecoder *decoder): _decoder(decoder) {} + ~CWaitScout_Releaser() { _decoder->WaitScout(); } + }; + + HRESULT CreateThread(); + + #endif + + Byte *_inBuf; + UInt64 _inProcessed; + bool _inputFinished; + HRESULT _inputRes; + + CBase Base; + + bool GetCrcError() const { return BlockCrcError || Base.StreamCrcError; } + + void InitOutSize(const UInt64 *outSize); + + bool CreateInputBufer(); + + void InitInputBuffer() + { + // We use InitInputBuffer() before stream init. + // So don't read from stream here + _inProcessed = 0; + Base._buf = _inBuf; + Base._lim = _inBuf; + Base.InitBitDecoder(); + } + + UInt64 GetInputProcessedSize() const + { + // for NSIS case : we need also look the number of bits in bitDecoder + return _inProcessed + (size_t)(Base._buf - _inBuf); + } + + UInt64 GetInStreamSize() const + { + return _inProcessed + (size_t)(Base._buf - _inBuf) - (Base._numBits >> 3); + } + + UInt64 GetOutProcessedSize() const { return _outWritten + _outPos; } + + HRESULT ReadInput(); + + void StartNewStream(); + + HRESULT ReadStreamSignature(); + HRESULT StartRead(); + + HRESULT ReadBlockSignature(); + HRESULT ReadBlock(); + + HRESULT Flush(); + HRESULT DecodeBlock(const CBlockProps &props); + HRESULT DecodeStreams(ICompressProgressInfo *progress); + + UInt64 GetNumStreams() const { return Base.NumStreams; } + UInt64 GetNumBlocks() const { return Base.NumBlocks; } + + CDecoder(); + virtual ~CDecoder(); +}; + + + +#ifndef Z7_NO_READ_FROM_CODER + +class CNsisDecoder Z7_final: public CDecoder +{ + Z7_IFACE_COM7_IMP(ISequentialInStream) +}; + +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Encoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Encoder.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.cpp 2025-06-30 15:00:00.000000000 +0000 @@ -1,890 +1,1121 @@ -// BZip2Encoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/BwtSort.h" -#include "../../../C/HuffEnc.h" - -#include "BZip2Crc.h" -#include "BZip2Encoder.h" -#include "Mtf8.h" - -namespace NCompress { -namespace NBZip2 { - -const unsigned kMaxHuffmanLenForEncoding = 16; // it must be < kMaxHuffmanLen = 20 - -static const UInt32 kBufferSize = (1 << 17); -static const unsigned kNumHuffPasses = 4; - -bool CThreadInfo::Alloc() -{ - if (m_BlockSorterIndex == 0) - { - m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32)); - if (m_BlockSorterIndex == 0) - return false; - } - - if (m_Block == 0) - { - m_Block = (Byte *)::MidAlloc(kBlockSizeMax * 5 + kBlockSizeMax / 10 + (20 << 10)); - if (m_Block == 0) - return false; - m_MtfArray = m_Block + kBlockSizeMax; - m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2; - } - return true; -} - -void CThreadInfo::Free() -{ - ::BigFree(m_BlockSorterIndex); - m_BlockSorterIndex = 0; - ::MidFree(m_Block); - m_Block = 0; -} - -#ifndef _7ZIP_ST - -static THREAD_FUNC_DECL MFThread(void *threadCoderInfo) -{ - return ((CThreadInfo *)threadCoderInfo)->ThreadFunc(); -} - -#define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; } - -HRESULT CThreadInfo::Create() -{ - RINOK_THREAD(StreamWasFinishedEvent.Create()); - RINOK_THREAD(WaitingWasStartedEvent.Create()); - RINOK_THREAD(CanWriteEvent.Create()); - RINOK_THREAD(Thread.Create(MFThread, this)); - return S_OK; -} - -void CThreadInfo::FinishStream(bool needLeave) -{ - Encoder->StreamWasFinished = true; - StreamWasFinishedEvent.Set(); - if (needLeave) - Encoder->CS.Leave(); - Encoder->CanStartWaitingEvent.Lock(); - WaitingWasStartedEvent.Set(); -} - -DWORD CThreadInfo::ThreadFunc() -{ - for (;;) - { - Encoder->CanProcessEvent.Lock(); - Encoder->CS.Enter(); - if (Encoder->CloseThreads) - { - Encoder->CS.Leave(); - return 0; - } - if (Encoder->StreamWasFinished) - { - FinishStream(true); - continue; - } - HRESULT res = S_OK; - bool needLeave = true; - try - { - UInt32 blockSize = Encoder->ReadRleBlock(m_Block); - m_PackSize = Encoder->m_InStream.GetProcessedSize(); - m_BlockIndex = Encoder->NextBlockIndex; - if (++Encoder->NextBlockIndex == Encoder->NumThreads) - Encoder->NextBlockIndex = 0; - if (blockSize == 0) - { - FinishStream(true); - continue; - } - Encoder->CS.Leave(); - needLeave = false; - res = EncodeBlock3(blockSize); - } - catch(const CInBufferException &e) { res = e.ErrorCode; } - catch(const COutBufferException &e) { res = e.ErrorCode; } - catch(...) { res = E_FAIL; } - if (res != S_OK) - { - Encoder->Result = res; - FinishStream(needLeave); - continue; - } - } -} - -#endif - -void CEncProps::Normalize(int level) -{ - if (level < 0) level = 5; - if (level > 9) level = 9; - - if (NumPasses == (UInt32)(Int32)-1) - NumPasses = (level >= 9 ? 7 : (level >= 7 ? 2 : 1)); - if (NumPasses < 1) NumPasses = 1; - if (NumPasses > kNumPassesMax) NumPasses = kNumPassesMax; - - if (BlockSizeMult == (UInt32)(Int32)-1) - BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); - if (BlockSizeMult < kBlockSizeMultMin) BlockSizeMult = kBlockSizeMultMin; - if (BlockSizeMult > kBlockSizeMultMax) BlockSizeMult = kBlockSizeMultMax; -} - -CEncoder::CEncoder() -{ - _props.Normalize(-1); - - #ifndef _7ZIP_ST - ThreadsInfo = 0; - m_NumThreadsPrev = 0; - NumThreads = 1; - #endif -} - -#ifndef _7ZIP_ST -CEncoder::~CEncoder() -{ - Free(); -} - -HRESULT CEncoder::Create() -{ - RINOK_THREAD(CanProcessEvent.CreateIfNotCreated()); - RINOK_THREAD(CanStartWaitingEvent.CreateIfNotCreated()); - if (ThreadsInfo != 0 && m_NumThreadsPrev == NumThreads) - return S_OK; - try - { - Free(); - MtMode = (NumThreads > 1); - m_NumThreadsPrev = NumThreads; - ThreadsInfo = new CThreadInfo[NumThreads]; - if (ThreadsInfo == 0) - return E_OUTOFMEMORY; - } - catch(...) { return E_OUTOFMEMORY; } - for (UInt32 t = 0; t < NumThreads; t++) - { - CThreadInfo &ti = ThreadsInfo[t]; - ti.Encoder = this; - if (MtMode) - { - HRESULT res = ti.Create(); - if (res != S_OK) - { - NumThreads = t; - Free(); - return res; - } - } - } - return S_OK; -} - -void CEncoder::Free() -{ - if (!ThreadsInfo) - return; - CloseThreads = true; - CanProcessEvent.Set(); - for (UInt32 t = 0; t < NumThreads; t++) - { - CThreadInfo &ti = ThreadsInfo[t]; - if (MtMode) - ti.Thread.Wait(); - ti.Free(); - } - delete []ThreadsInfo; - ThreadsInfo = 0; -} -#endif - -UInt32 CEncoder::ReadRleBlock(Byte *buffer) -{ - UInt32 i = 0; - Byte prevByte; - if (m_InStream.ReadByte(prevByte)) - { - UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1; - unsigned numReps = 1; - buffer[i++] = prevByte; - while (i < blockSize) // "- 1" to support RLE - { - Byte b; - if (!m_InStream.ReadByte(b)) - break; - if (b != prevByte) - { - if (numReps >= kRleModeRepSize) - buffer[i++] = (Byte)(numReps - kRleModeRepSize); - buffer[i++] = b; - numReps = 1; - prevByte = b; - continue; - } - numReps++; - if (numReps <= kRleModeRepSize) - buffer[i++] = b; - else if (numReps == kRleModeRepSize + 255) - { - buffer[i++] = (Byte)(numReps - kRleModeRepSize); - numReps = 0; - } - } - // it's to support original BZip2 decoder - if (numReps >= kRleModeRepSize) - buffer[i++] = (Byte)(numReps - kRleModeRepSize); - } - return i; -} - -void CThreadInfo::WriteBits2(UInt32 value, unsigned numBits) { m_OutStreamCurrent->WriteBits(value, numBits); } -void CThreadInfo::WriteByte2(Byte b) { WriteBits2(b, 8); } -void CThreadInfo::WriteBit2(Byte v) { WriteBits2(v, 1); } -void CThreadInfo::WriteCrc2(UInt32 v) -{ - for (unsigned i = 0; i < 4; i++) - WriteByte2(((Byte)(v >> (24 - i * 8)))); -} - -void CEncoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } -void CEncoder::WriteByte(Byte b) { WriteBits(b, 8); } -// void CEncoder::WriteBit(Byte v) { WriteBits(v, 1); } -void CEncoder::WriteCrc(UInt32 v) -{ - for (unsigned i = 0; i < 4; i++) - WriteByte(((Byte)(v >> (24 - i * 8)))); -} - - -// blockSize > 0 -void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) -{ - WriteBit2(0); // Randomised = false - - { - UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); - // if (m_BlockSorterIndex[origPtr] != 0) throw 1; - m_BlockSorterIndex[origPtr] = blockSize; - WriteBits2(origPtr, kNumOrigBits); - } - - CMtf8Encoder mtf; - unsigned numInUse = 0; - { - Byte inUse[256]; - Byte inUse16[16]; - UInt32 i; - for (i = 0; i < 256; i++) - inUse[i] = 0; - for (i = 0; i < 16; i++) - inUse16[i] = 0; - for (i = 0; i < blockSize; i++) - inUse[block[i]] = 1; - for (i = 0; i < 256; i++) - if (inUse[i]) - { - inUse16[i >> 4] = 1; - mtf.Buf[numInUse++] = (Byte)i; - } - for (i = 0; i < 16; i++) - WriteBit2(inUse16[i]); - for (i = 0; i < 256; i++) - if (inUse16[i >> 4]) - WriteBit2(inUse[i]); - } - unsigned alphaSize = numInUse + 2; - - Byte *mtfs = m_MtfArray; - UInt32 mtfArraySize = 0; - UInt32 symbolCounts[kMaxAlphaSize]; - { - for (unsigned i = 0; i < kMaxAlphaSize; i++) - symbolCounts[i] = 0; - } - - { - UInt32 rleSize = 0; - UInt32 i = 0; - const UInt32 *bsIndex = m_BlockSorterIndex; - block--; - do - { - unsigned pos = mtf.FindAndMove(block[bsIndex[i]]); - if (pos == 0) - rleSize++; - else - { - while (rleSize != 0) - { - rleSize--; - mtfs[mtfArraySize++] = (Byte)(rleSize & 1); - symbolCounts[rleSize & 1]++; - rleSize >>= 1; - } - if (pos >= 0xFE) - { - mtfs[mtfArraySize++] = 0xFF; - mtfs[mtfArraySize++] = (Byte)(pos - 0xFE); - } - else - mtfs[mtfArraySize++] = (Byte)(pos + 1); - symbolCounts[pos + 1]++; - } - } - while (++i < blockSize); - - while (rleSize != 0) - { - rleSize--; - mtfs[mtfArraySize++] = (Byte)(rleSize & 1); - symbolCounts[rleSize & 1]++; - rleSize >>= 1; - } - - if (alphaSize < 256) - mtfs[mtfArraySize++] = (Byte)(alphaSize - 1); - else - { - mtfs[mtfArraySize++] = 0xFF; - mtfs[mtfArraySize++] = (Byte)(alphaSize - 256); - } - symbolCounts[alphaSize - 1]++; - } - - UInt32 numSymbols = 0; - { - for (unsigned i = 0; i < kMaxAlphaSize; i++) - numSymbols += symbolCounts[i]; - } - - unsigned bestNumTables = kNumTablesMin; - UInt32 bestPrice = 0xFFFFFFFF; - UInt32 startPos = m_OutStreamCurrent->GetPos(); - Byte startCurByte = m_OutStreamCurrent->GetCurByte(); - for (unsigned nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) - { - unsigned numTables; - - if (m_OptimizeNumTables) - { - m_OutStreamCurrent->SetPos(startPos); - m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); - if (nt <= kNumTablesMax) - numTables = nt; - else - numTables = bestNumTables; - } - else - { - if (numSymbols < 200) numTables = 2; - else if (numSymbols < 600) numTables = 3; - else if (numSymbols < 1200) numTables = 4; - else if (numSymbols < 2400) numTables = 5; - else numTables = 6; - } - - WriteBits2(numTables, kNumTablesBits); - - UInt32 numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; - WriteBits2(numSelectors, kNumSelectorsBits); - - { - UInt32 remFreq = numSymbols; - unsigned gs = 0; - unsigned t = numTables; - do - { - UInt32 tFreq = remFreq / t; - unsigned ge = gs; - UInt32 aFreq = 0; - while (aFreq < tFreq) // && ge < alphaSize) - aFreq += symbolCounts[ge++]; - - if (ge > gs + 1 && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) - aFreq -= symbolCounts[--ge]; - - Byte *lens = Lens[t - 1]; - unsigned i = 0; - do - lens[i] = (Byte)((i >= gs && i < ge) ? 0 : 1); - while (++i < alphaSize); - gs = ge; - remFreq -= aFreq; - } - while (--t != 0); - } - - - for (unsigned pass = 0; pass < kNumHuffPasses; pass++) - { - { - unsigned t = 0; - do - memset(Freqs[t], 0, sizeof(Freqs[t])); - while (++t < numTables); - } - - { - UInt32 mtfPos = 0; - UInt32 g = 0; - do - { - UInt32 symbols[kGroupSize]; - unsigned i = 0; - do - { - UInt32 symbol = mtfs[mtfPos++]; - if (symbol >= 0xFF) - symbol += mtfs[mtfPos++]; - symbols[i] = symbol; - } - while (++i < kGroupSize && mtfPos < mtfArraySize); - - UInt32 bestPrice2 = 0xFFFFFFFF; - unsigned t = 0; - do - { - const Byte *lens = Lens[t]; - UInt32 price = 0; - unsigned j = 0; - do - price += lens[symbols[j]]; - while (++j < i); - if (price < bestPrice2) - { - m_Selectors[g] = (Byte)t; - bestPrice2 = price; - } - } - while (++t < numTables); - UInt32 *freqs = Freqs[m_Selectors[g++]]; - unsigned j = 0; - do - freqs[symbols[j]]++; - while (++j < i); - } - while (mtfPos < mtfArraySize); - } - - unsigned t = 0; - do - { - UInt32 *freqs = Freqs[t]; - unsigned i = 0; - do - if (freqs[i] == 0) - freqs[i] = 1; - while (++i < alphaSize); - Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, kMaxHuffmanLenForEncoding); - } - while (++t < numTables); - } - - { - Byte mtfSel[kNumTablesMax]; - { - unsigned t = 0; - do - mtfSel[t] = (Byte)t; - while (++t < numTables); - } - - UInt32 i = 0; - do - { - Byte sel = m_Selectors[i]; - unsigned pos; - for (pos = 0; mtfSel[pos] != sel; pos++) - WriteBit2(1); - WriteBit2(0); - for (; pos > 0; pos--) - mtfSel[pos] = mtfSel[pos - 1]; - mtfSel[0] = sel; - } - while (++i < numSelectors); - } - - { - unsigned t = 0; - do - { - const Byte *lens = Lens[t]; - UInt32 len = lens[0]; - WriteBits2(len, kNumLevelsBits); - unsigned i = 0; - do - { - UInt32 level = lens[i]; - while (len != level) - { - WriteBit2(1); - if (len < level) - { - WriteBit2(0); - len++; - } - else - { - WriteBit2(1); - len--; - } - } - WriteBit2(0); - } - while (++i < alphaSize); - } - while (++t < numTables); - } - - { - UInt32 groupSize = 0; - UInt32 groupIndex = 0; - const Byte *lens = 0; - const UInt32 *codes = 0; - UInt32 mtfPos = 0; - do - { - UInt32 symbol = mtfs[mtfPos++]; - if (symbol >= 0xFF) - symbol += mtfs[mtfPos++]; - if (groupSize == 0) - { - groupSize = kGroupSize; - unsigned t = m_Selectors[groupIndex++]; - lens = Lens[t]; - codes = Codes[t]; - } - groupSize--; - m_OutStreamCurrent->WriteBits(codes[symbol], lens[symbol]); - } - while (mtfPos < mtfArraySize); - } - - if (!m_OptimizeNumTables) - break; - UInt32 price = m_OutStreamCurrent->GetPos() - startPos; - if (price <= bestPrice) - { - if (nt == kNumTablesMax) - break; - bestPrice = price; - bestNumTables = nt; - } - } -} - -// blockSize > 0 -UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize) -{ - WriteByte2(kBlockSig0); - WriteByte2(kBlockSig1); - WriteByte2(kBlockSig2); - WriteByte2(kBlockSig3); - WriteByte2(kBlockSig4); - WriteByte2(kBlockSig5); - - CBZip2Crc crc; - unsigned numReps = 0; - Byte prevByte = block[0]; - UInt32 i = 0; - do - { - Byte b = block[i]; - if (numReps == kRleModeRepSize) - { - for (; b > 0; b--) - crc.UpdateByte(prevByte); - numReps = 0; - continue; - } - if (prevByte == b) - numReps++; - else - { - numReps = 1; - prevByte = b; - } - crc.UpdateByte(b); - } - while (++i < blockSize); - UInt32 crcRes = crc.GetDigest(); - WriteCrc2(crcRes); - EncodeBlock(block, blockSize); - return crcRes; -} - -void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses) -{ - UInt32 numCrcs = m_NumCrcs; - bool needCompare = false; - - UInt32 startBytePos = m_OutStreamCurrent->GetBytePos(); - UInt32 startPos = m_OutStreamCurrent->GetPos(); - Byte startCurByte = m_OutStreamCurrent->GetCurByte(); - Byte endCurByte = 0; - UInt32 endPos = 0; - if (numPasses > 1 && blockSize >= (1 << 10)) - { - UInt32 blockSize0 = blockSize / 2; - for (;(block[blockSize0] == block[blockSize0 - 1] || - block[blockSize0 - 1] == block[blockSize0 - 2]) && - blockSize0 < blockSize; blockSize0++); - if (blockSize0 < blockSize) - { - EncodeBlock2(block, blockSize0, numPasses - 1); - EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1); - endPos = m_OutStreamCurrent->GetPos(); - endCurByte = m_OutStreamCurrent->GetCurByte(); - if ((endPos & 7) > 0) - WriteBits2(0, 8 - (endPos & 7)); - m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte); - needCompare = true; - } - } - - UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos(); - UInt32 startPos2 = m_OutStreamCurrent->GetPos(); - UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); - UInt32 endPos2 = m_OutStreamCurrent->GetPos(); - - if (needCompare) - { - UInt32 size2 = endPos2 - startPos2; - if (size2 < endPos - startPos) - { - UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2; - Byte *buffer = m_OutStreamCurrent->GetStream(); - for (UInt32 i = 0; i < numBytes; i++) - buffer[startBytePos + i] = buffer[startBytePos2 + i]; - m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2); - m_NumCrcs = numCrcs; - m_CRCs[m_NumCrcs++] = crcVal; - } - else - { - m_OutStreamCurrent->SetPos(endPos); - m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte); - } - } - else - { - m_NumCrcs = numCrcs; - m_CRCs[m_NumCrcs++] = crcVal; - } -} - -HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize) -{ - CMsbfEncoderTemp outStreamTemp; - outStreamTemp.SetStream(m_TempArray); - outStreamTemp.Init(); - m_OutStreamCurrent = &outStreamTemp; - - m_NumCrcs = 0; - - EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses); - - #ifndef _7ZIP_ST - if (Encoder->MtMode) - Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock(); - #endif - for (UInt32 i = 0; i < m_NumCrcs; i++) - Encoder->CombinedCrc.Update(m_CRCs[i]); - Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte()); - HRESULT res = S_OK; - #ifndef _7ZIP_ST - if (Encoder->MtMode) - { - UInt32 blockIndex = m_BlockIndex + 1; - if (blockIndex == Encoder->NumThreads) - blockIndex = 0; - - if (Encoder->Progress) - { - UInt64 unpackSize = Encoder->m_OutStream.GetProcessedSize(); - res = Encoder->Progress->SetRatioInfo(&m_PackSize, &unpackSize); - } - - Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set(); - } - #endif - return res; -} - -void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte) -{ - UInt32 bytesSize = (sizeInBits >> 3); - for (UInt32 i = 0; i < bytesSize; i++) - m_OutStream.WriteBits(data[i], 8); - WriteBits(lastByte, (sizeInBits & 7)); -} - - -HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - #ifndef _7ZIP_ST - Progress = progress; - RINOK(Create()); - for (UInt32 t = 0; t < NumThreads; t++) - #endif - { - #ifndef _7ZIP_ST - CThreadInfo &ti = ThreadsInfo[t]; - if (MtMode) - { - RINOK(ti.StreamWasFinishedEvent.Reset()); - RINOK(ti.WaitingWasStartedEvent.Reset()); - RINOK(ti.CanWriteEvent.Reset()); - } - #else - CThreadInfo &ti = ThreadsInfo; - ti.Encoder = this; - #endif - - ti.m_OptimizeNumTables = _props.DoOptimizeNumTables(); - - if (!ti.Alloc()) - return E_OUTOFMEMORY; - } - - - if (!m_InStream.Create(kBufferSize)) - return E_OUTOFMEMORY; - if (!m_OutStream.Create(kBufferSize)) - return E_OUTOFMEMORY; - - - m_InStream.SetStream(inStream); - m_InStream.Init(); - - m_OutStream.SetStream(outStream); - m_OutStream.Init(); - - CombinedCrc.Init(); - #ifndef _7ZIP_ST - NextBlockIndex = 0; - StreamWasFinished = false; - CloseThreads = false; - CanStartWaitingEvent.Reset(); - #endif - - WriteByte(kArSig0); - WriteByte(kArSig1); - WriteByte(kArSig2); - WriteByte((Byte)(kArSig3 + _props.BlockSizeMult)); - - #ifndef _7ZIP_ST - - if (MtMode) - { - ThreadsInfo[0].CanWriteEvent.Set(); - Result = S_OK; - CanProcessEvent.Set(); - UInt32 t; - for (t = 0; t < NumThreads; t++) - ThreadsInfo[t].StreamWasFinishedEvent.Lock(); - CanProcessEvent.Reset(); - CanStartWaitingEvent.Set(); - for (t = 0; t < NumThreads; t++) - ThreadsInfo[t].WaitingWasStartedEvent.Lock(); - CanStartWaitingEvent.Reset(); - RINOK(Result); - } - else - #endif - { - for (;;) - { - CThreadInfo &ti = - #ifndef _7ZIP_ST - ThreadsInfo[0]; - #else - ThreadsInfo; - #endif - UInt32 blockSize = ReadRleBlock(ti.m_Block); - if (blockSize == 0) - break; - RINOK(ti.EncodeBlock3(blockSize)); - if (progress) - { - UInt64 packSize = m_InStream.GetProcessedSize(); - UInt64 unpackSize = m_OutStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &unpackSize)); - } - } - } - WriteByte(kFinSig0); - WriteByte(kFinSig1); - WriteByte(kFinSig2); - WriteByte(kFinSig3); - WriteByte(kFinSig4); - WriteByte(kFinSig5); - - WriteCrc(CombinedCrc.GetDigest()); - return Flush(); -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - int level = -1; - CEncProps props; - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) - continue; - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; - switch (propID) - { - case NCoderPropID::kNumPasses: props.NumPasses = v; break; - case NCoderPropID::kDictionarySize: props.BlockSizeMult = v / kBlockSizeStep; break; - case NCoderPropID::kLevel: level = v; break; - case NCoderPropID::kNumThreads: - { - #ifndef _7ZIP_ST - SetNumberOfThreads(v); - #endif - break; - } - default: return E_INVALIDARG; - } - } - props.Normalize(level); - _props = props; - return S_OK; -} - -#ifndef _7ZIP_ST -STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads) -{ - const UInt32 kNumThreadsMax = 64; - if (numThreads < 1) numThreads = 1; - if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax; - NumThreads = numThreads; - return S_OK; -} -#endif - -}} +// BZip2Encoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/BwtSort.h" +#include "../../../C/HuffEnc.h" + +#include "BZip2Encoder.h" + +namespace NCompress { +namespace NBZip2 { + +#define HUFFMAN_LEN 16 +#if HUFFMAN_LEN > Z7_HUFFMAN_LEN_MAX + #error Stop_Compiling_Bad_HUFFMAN_LEN_BZip2Encoder +#endif + +static const size_t kBufferSize = 1 << 17; +static const unsigned kNumHuffPasses = 4; + + +bool CThreadInfo::Alloc() +{ + if (!m_BlockSorterIndex) + { + m_BlockSorterIndex = (UInt32 *)::BigAlloc(BLOCK_SORT_BUF_SIZE(kBlockSizeMax) * sizeof(UInt32)); + if (!m_BlockSorterIndex) + return false; + } + + if (!m_Block_Base) + { + const unsigned kPadSize = 1 << 7; // we need at least 1 byte backward padding, becuase we use (m_Block - 1) pointer; + m_Block_Base = (Byte *)::MidAlloc(kBlockSizeMax * 5 + + kBlockSizeMax / 10 + (20 << 10) + + kPadSize); + if (!m_Block_Base) + return false; + m_Block = m_Block_Base + kPadSize; + m_MtfArray = m_Block + kBlockSizeMax; + m_TempArray = m_MtfArray + kBlockSizeMax * 2 + 2; + } + return true; +} + +void CThreadInfo::Free() +{ + ::BigFree(m_BlockSorterIndex); + m_BlockSorterIndex = NULL; + ::MidFree(m_Block_Base); + m_Block_Base = NULL; +} + +#ifndef Z7_ST + +static THREAD_FUNC_DECL MFThread(void *threadCoderInfo) +{ + return ((CThreadInfo *)threadCoderInfo)->ThreadFunc(); +} + +HRESULT CThreadInfo::Create() +{ + WRes wres = StreamWasFinishedEvent.Create(); + if (wres == 0) { wres = WaitingWasStartedEvent.Create(); + if (wres == 0) { wres = CanWriteEvent.Create(); + if (wres == 0) + { +#ifdef _WIN32 + if (Encoder->_props.NumThreadGroups != 0) + { + const UInt32 group = ThreadNextGroup_GetNext(&Encoder->ThreadNextGroup); + wres = Thread.Create_With_Group(MFThread, this, group, 0); // affinity + } + else +#endif + if (Encoder->_props.Affinity != 0) + wres = Thread.Create_With_Affinity(MFThread, this, (CAffinityMask)Encoder->_props.Affinity); + else + wres = Thread.Create(MFThread, this); + }}} + return HRESULT_FROM_WIN32(wres); +} + +void CThreadInfo::FinishStream(bool needLeave) +{ + Encoder->StreamWasFinished = true; + StreamWasFinishedEvent.Set(); + if (needLeave) + Encoder->CS.Leave(); + Encoder->CanStartWaitingEvent.Lock(); + WaitingWasStartedEvent.Set(); +} + +THREAD_FUNC_RET_TYPE CThreadInfo::ThreadFunc() +{ + for (;;) + { + Encoder->CanProcessEvent.Lock(); + Encoder->CS.Enter(); + if (Encoder->CloseThreads) + { + Encoder->CS.Leave(); + return 0; + } + if (Encoder->StreamWasFinished) + { + FinishStream(true); + continue; + } + HRESULT res = S_OK; + bool needLeave = true; + try + { + 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; + if (blockSize == 0) + { + FinishStream(true); + continue; + } + Encoder->CS.Leave(); + needLeave = false; + res = EncodeBlock3(blockSize); + } + catch(const CInBufferException &e) { res = e.ErrorCode; } + catch(const COutBufferException &e) { res = e.ErrorCode; } + catch(...) { res = E_FAIL; } + if (res != S_OK) + { + Encoder->Result = res; + FinishStream(needLeave); + continue; + } + } +} + +#endif + +void CEncProps::Normalize(int level) +{ + if (level < 0) level = 5; + if (level > 9) level = 9; + + if (NumPasses == (UInt32)(Int32)-1) + NumPasses = (level >= 9 ? 7 : (level >= 7 ? 2 : 1)); + if (NumPasses < 1) NumPasses = 1; + if (NumPasses > kNumPassesMax) NumPasses = kNumPassesMax; + + if (BlockSizeMult == (UInt32)(Int32)-1) + BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? (unsigned)level * 2 - 1: 1)); + if (BlockSizeMult < kBlockSizeMultMin) BlockSizeMult = kBlockSizeMultMin; + if (BlockSizeMult > kBlockSizeMultMax) BlockSizeMult = kBlockSizeMultMax; +} + +CEncoder::CEncoder() +{ + _props.Normalize(-1); + + #ifndef Z7_ST + ThreadsInfo = NULL; + m_NumThreadsPrev = 0; + NumThreads = 1; + #endif +} + +#ifndef Z7_ST +CEncoder::~CEncoder() +{ + Free(); +} + +HRESULT CEncoder::Create() +{ + { + WRes wres = CanProcessEvent.CreateIfNotCreated_Reset(); + if (wres == 0) { wres = CanStartWaitingEvent.CreateIfNotCreated_Reset(); } + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + + if (ThreadsInfo && m_NumThreadsPrev == NumThreads) + return S_OK; + try + { + Free(); + MtMode = (NumThreads > 1); + m_NumThreadsPrev = NumThreads; + ThreadsInfo = new CThreadInfo[NumThreads]; + if (!ThreadsInfo) + return E_OUTOFMEMORY; + } + catch(...) { return E_OUTOFMEMORY; } + for (UInt32 t = 0; t < NumThreads; t++) + { + CThreadInfo &ti = ThreadsInfo[t]; + ti.Encoder = this; + if (MtMode) + { + HRESULT res = ti.Create(); + if (res != S_OK) + { + NumThreads = t; + Free(); + return res; + } + } + } + return S_OK; +} + +void CEncoder::Free() +{ + if (!ThreadsInfo) + return; + CloseThreads = true; + CanProcessEvent.Set(); + for (UInt32 t = 0; t < NumThreads; t++) + { + CThreadInfo &ti = ThreadsInfo[t]; + if (MtMode) + ti.Thread.Wait_Close(); + ti.Free(); + } + delete []ThreadsInfo; + ThreadsInfo = NULL; +} +#endif + +struct CRleEncoder +{ + const Byte *_src; + const Byte *_srcLim; + Byte *_dest; + const Byte *_destLim; + Byte _prevByte; + unsigned _numReps; + + void Encode(); +}; + +Z7_NO_INLINE +void CRleEncoder::Encode() +{ + const Byte *src = _src; + const Byte * const srcLim = _srcLim; + Byte *dest = _dest; + const Byte * const destLim = _destLim; + Byte prev = _prevByte; + unsigned numReps = _numReps; + // (dest < destLim) + // src = srcLim; // for debug + while (dest < destLim) + { + if (src == srcLim) + break; + const Byte b = *src++; + if (b != prev) + { + if (numReps >= kRleModeRepSize) + *dest++ = (Byte)(numReps - kRleModeRepSize); + *dest++ = b; + numReps = 1; + prev = b; + /* + { // speed optimization code: + if (dest >= destLim || src == srcLim) + break; + const Byte b2 = *src++; + *dest++ = b2; + numReps += (prev == b2); + prev = b2; + } + */ + continue; + } + numReps++; + if (numReps <= kRleModeRepSize) + *dest++ = b; + else if (numReps == kRleModeRepSize + 255) + { + *dest++ = (Byte)(numReps - kRleModeRepSize); + numReps = 0; + } + } + _src = src; + _dest = dest; + _prevByte = prev; + _numReps = numReps; + // (dest <= destLim + 1) +} + + +// out: return value is blockSize: size of data filled in buffer[]: +// (returned_blockSize <= _props.BlockSizeMult * kBlockSizeStep) +UInt32 CEncoder::ReadRleBlock(Byte *buffer) +{ + CRleEncoder rle; + UInt32 i = 0; + if (m_InStream.ReadByte(rle._prevByte)) + { + NumBlocks++; + const UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1; // -1 for RLE + rle._destLim = buffer + blockSize; + rle._numReps = 1; + buffer[i++] = rle._prevByte; + while (i < blockSize) + { + rle._dest = buffer + i; + size_t rem; + const Byte * const ptr = m_InStream.Lookahead(rem); + if (rem == 0) + break; + rle._src = ptr; + rle._srcLim = ptr + rem; + rle.Encode(); + m_InStream.Skip((size_t)(rle._src - ptr)); + i = (UInt32)(size_t)(rle._dest - buffer); + // (i <= blockSize + 1) + } + const int n = (int)rle._numReps - (int)kRleModeRepSize; + if (n >= 0) + buffer[i++] = (Byte)n; + } + return i; +} + + + +Z7_NO_INLINE +void CThreadInfo::WriteBits2(UInt32 value, unsigned numBits) + { m_OutStreamCurrent.WriteBits(value, numBits); } +/* +Z7_NO_INLINE +void CThreadInfo::WriteByte2(unsigned b) + { m_OutStreamCurrent.WriteByte(b); } +*/ +// void CEncoder::WriteBits(UInt32 value, unsigned numBits) { m_OutStream.WriteBits(value, numBits); } +Z7_NO_INLINE +void CEncoder::WriteByte(Byte b) { m_OutStream.WriteByte(b); } + + +#define WRITE_BITS_UPDATE(value, numBits) \ +{ \ + numBits -= _bitPos; \ + const UInt32 hi = value >> numBits; \ + *_buf++ = (Byte)(_curByte | hi); \ + value -= hi << numBits; \ + _bitPos = 8; \ + _curByte = 0; \ +} + +#if HUFFMAN_LEN > 16 + +#define WRITE_BITS_HUFF(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + while (numBits >= _bitPos) { \ + WRITE_BITS_UPDATE(value, numBits) \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#else // HUFFMAN_LEN <= 16 + +// numBits2 <= 16 is supported +#define WRITE_BITS_HUFF(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + if (numBits >= _bitPos) \ + { \ + WRITE_BITS_UPDATE(value, numBits) \ + if (numBits >= _bitPos) \ + { \ + numBits -= _bitPos; \ + const UInt32 hi = value >> numBits; \ + *_buf++ = (Byte)hi; \ + value -= hi << numBits; \ + } \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#endif + +#define WRITE_BITS_8(value2, numBits2) \ +{ \ + UInt32 value = value2; \ + unsigned numBits = numBits2; \ + if (numBits >= _bitPos) \ + { \ + WRITE_BITS_UPDATE(value, numBits) \ + } \ + _bitPos -= numBits; \ + _curByte |= (value << _bitPos); \ +} + +#define WRITE_BIT_PRE \ + { _bitPos--; } + +#define WRITE_BIT_POST \ +{ \ + if (_bitPos == 0) \ + { \ + *_buf++ = (Byte)_curByte; \ + _curByte = 0; \ + _bitPos = 8; \ + } \ +} + +#define WRITE_BIT_0 \ +{ \ + WRITE_BIT_PRE \ + WRITE_BIT_POST \ +} + +#define WRITE_BIT_1 \ +{ \ + WRITE_BIT_PRE \ + _curByte |= 1u << _bitPos; \ + WRITE_BIT_POST \ +} + + +// blockSize > 0 +void CThreadInfo::EncodeBlock(const Byte *block, UInt32 blockSize) +{ + // WriteBit2(0); // Randomised = false + { + const UInt32 origPtr = BlockSort(m_BlockSorterIndex, block, blockSize); + // if (m_BlockSorterIndex[origPtr] != 0) throw 1; + m_BlockSorterIndex[origPtr] = blockSize; + WriteBits2(origPtr, kNumOrigBits + 1); // + 1 for additional high bit flag (Randomised = false) + } + Byte mtfBuf[256]; + // memset(mtfBuf, 0, sizeof(mtfBuf)); // to disable MSVC warning + unsigned numInUse; + { + Byte inUse[256]; + Byte inUse16[16]; + unsigned i; + for (i = 0; i < 256; i++) + inUse[i] = 0; + for (i = 0; i < 16; i++) + inUse16[i] = 0; + { + const Byte * cur = block; + block = block + (size_t)blockSize - 1; + if (cur != block) + { + do + { + const unsigned b0 = cur[0]; + const unsigned b1 = cur[1]; + cur += 2; + inUse[b0] = 1; + inUse[b1] = 1; + } + while (cur < block); + } + if (cur == block) + inUse[cur[0]] = 1; + block -= blockSize; // block pointer is (original_block - 1) + } + numInUse = 0; + for (i = 0; i < 256; i++) + if (inUse[i]) + { + inUse16[i >> 4] = 1; + mtfBuf[numInUse++] = (Byte)i; + } + for (i = 0; i < 16; i++) + WriteBit2(inUse16[i]); + for (i = 0; i < 256; i++) + if (inUse16[i >> 4]) + WriteBit2(inUse[i]); + } + const unsigned alphaSize = numInUse + 2; + + UInt32 symbolCounts[kMaxAlphaSize]; + { + for (unsigned i = 0; i < kMaxAlphaSize; i++) + symbolCounts[i] = 0; + symbolCounts[(size_t)alphaSize - 1] = 1; + } + + Byte *mtfs = m_MtfArray; + { + const UInt32 *bsIndex = m_BlockSorterIndex; + const UInt32 *bsIndex_rle = bsIndex; + const UInt32 * const bsIndex_end = bsIndex + blockSize; + // block--; // backward fix + // block pointer is (original_block - 1) + do + { + const Byte v = block[*bsIndex++]; + Byte a = mtfBuf[0]; + if (v != a) + { + mtfBuf[0] = v; + { + UInt32 rleSize = (UInt32)(size_t)(bsIndex - bsIndex_rle) - 1; + bsIndex_rle = bsIndex; + while (rleSize) + { + const unsigned sym = (unsigned)(--rleSize & 1); + *mtfs++ = (Byte)sym; + symbolCounts[sym]++; + rleSize >>= 1; + } + } + unsigned pos1 = 2; // = real_pos + 1 + Byte b; + b = mtfBuf[1]; mtfBuf[1] = a; if (v != b) + { a = mtfBuf[2]; mtfBuf[2] = b; if (v == a) pos1 = 3; + else { b = mtfBuf[3]; mtfBuf[3] = a; if (v == b) pos1 = 4; + else + { + Byte *m = mtfBuf + 7; + for (;;) + { + a = m[-3]; m[-3] = b; if (v == a) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 2)); break; } + b = m[-2]; m[-2] = a; if (v == b) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 1)); break; } + a = m[-1]; m[-1] = b; if (v == a) { pos1 = (unsigned)(size_t)(m - (mtfBuf )); break; } + b = m[ 0]; m[ 0] = a; m += 4; if (v == b) { pos1 = (unsigned)(size_t)(m - (mtfBuf + 3)); break; } + } + }}} + symbolCounts[pos1]++; + if (pos1 >= 0xff) + { + *mtfs++ = 0xff; + // pos1 -= 0xff; + pos1++; // we need only low byte + } + *mtfs++ = (Byte)pos1; + } + } + while (bsIndex < bsIndex_end); + + UInt32 rleSize = (UInt32)(size_t)(bsIndex - bsIndex_rle); + while (rleSize) + { + const unsigned sym = (unsigned)(--rleSize & 1); + *mtfs++ = (Byte)sym; + symbolCounts[sym]++; + rleSize >>= 1; + } + + unsigned d = alphaSize - 1; + if (alphaSize >= 256) + { + *mtfs++ = 0xff; + d = alphaSize; // (-256) + } + *mtfs++ = (Byte)d; + } + + const Byte * const mtf_lim = mtfs; + + UInt32 numSymbols = 0; + { + for (unsigned i = 0; i < kMaxAlphaSize; i++) + numSymbols += symbolCounts[i]; + } + + unsigned bestNumTables = kNumTablesMin; + UInt32 bestPrice = 0xFFFFFFFF; + const UInt32 startPos = m_OutStreamCurrent.GetPos(); + const unsigned startCurByte = m_OutStreamCurrent.GetCurByte(); + for (unsigned nt = kNumTablesMin; nt <= kNumTablesMax + 1; nt++) + { + unsigned numTables; + + if (m_OptimizeNumTables) + { + m_OutStreamCurrent.SetPos(startPos); + m_OutStreamCurrent.SetCurState(startPos & 7, startCurByte); + numTables = (nt <= kNumTablesMax ? nt : bestNumTables); + } + else + { + if (numSymbols < 200) numTables = 2; + else if (numSymbols < 600) numTables = 3; + else if (numSymbols < 1200) numTables = 4; + else if (numSymbols < 2400) numTables = 5; + else numTables = 6; + } + + WriteBits2(numTables, kNumTablesBits); + const unsigned numSelectors = (numSymbols + kGroupSize - 1) / kGroupSize; + WriteBits2((UInt32)numSelectors, kNumSelectorsBits); + + { + UInt32 remFreq = numSymbols; + unsigned gs = 0; + unsigned t = numTables; + do + { + UInt32 tFreq = remFreq / t; + unsigned ge = gs; + UInt32 aFreq = 0; + while (aFreq < tFreq) // && ge < alphaSize) + aFreq += symbolCounts[ge++]; + + if (ge > gs + 1 && t != numTables && t != 1 && (((numTables - t) & 1) == 1)) + aFreq -= symbolCounts[--ge]; + + Byte *lens = Lens[(size_t)t - 1]; + unsigned i = 0; + do + lens[i] = (Byte)((i >= gs && i < ge) ? 0 : 1); + while (++i < alphaSize); + gs = ge; + remFreq -= aFreq; + } + while (--t != 0); + } + + + for (unsigned pass = 0; pass < kNumHuffPasses; pass++) + { + memset(Freqs, 0, sizeof(Freqs[0]) * numTables); + // memset(Freqs, 0, sizeof(Freqs)); + { + mtfs = m_MtfArray; + UInt32 g = 0; + do + { + unsigned symbols[kGroupSize]; + unsigned i = 0; + do + { + UInt32 symbol = *mtfs++; + if (symbol >= 0xFF) + symbol += *mtfs++; + symbols[i] = symbol; + } + while (++i < kGroupSize && mtfs < mtf_lim); + + UInt32 bestPrice2 = 0xFFFFFFFF; + unsigned t = 0; + do + { + const Byte *lens = Lens[t]; + UInt32 price = 0; + unsigned j = 0; + do + price += lens[symbols[j]]; + while (++j < i); + if (price < bestPrice2) + { + m_Selectors[g] = (Byte)t; + bestPrice2 = price; + } + } + while (++t < numTables); + UInt32 *freqs = Freqs[m_Selectors[g++]]; + unsigned j = 0; + do + freqs[symbols[j]]++; + while (++j < i); + } + while (mtfs < mtf_lim); + } + + unsigned t = 0; + do + { + UInt32 *freqs = Freqs[t]; + unsigned i = 0; + do + if (freqs[i] == 0) + freqs[i] = 1; + while (++i < alphaSize); + Huffman_Generate(freqs, Codes[t], Lens[t], kMaxAlphaSize, HUFFMAN_LEN); + } + while (++t < numTables); + } + + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled + Byte *_buf; + { + Byte mtfSel[kNumTablesMax]; + { + unsigned t = 0; + do + mtfSel[t] = (Byte)t; + while (++t < numTables); + } + + _bitPos = m_OutStreamCurrent._bitPos; + _curByte = m_OutStreamCurrent._curByte; + _buf = m_OutStreamCurrent._buf; + // stream.Init_from_Global(m_OutStreamCurrent); + + const Byte *selectors = m_Selectors; + const Byte * const selectors_lim = selectors + numSelectors; + Byte prev = 0; // mtfSel[0]; + do + { + const Byte sel = *selectors++; + if (prev != sel) + { + Byte *mtfSel_cur = &mtfSel[1]; + for (;;) + { + WRITE_BIT_1 + const Byte next = *mtfSel_cur; + *mtfSel_cur++ = prev; + prev = next; + if (next == sel) + break; + } + // mtfSel[0] = sel; + } + WRITE_BIT_0 + } + while (selectors != selectors_lim); + } + { + unsigned t = 0; + do + { + const Byte *lens = Lens[t]; + unsigned len = lens[0]; + WRITE_BITS_8(len, kNumLevelsBits) + unsigned i = 0; + do + { + const unsigned level = lens[i]; + while (len != level) + { + WRITE_BIT_1 + if (len < level) + { + len++; + WRITE_BIT_0 + } + else + { + len--; + WRITE_BIT_1 + } + } + WRITE_BIT_0 + } + while (++i < alphaSize); + } + while (++t < numTables); + } + { + UInt32 groupSize = 1; + const Byte *selectors = m_Selectors; + const Byte *lens = NULL; + const UInt32 *codes = NULL; + mtfs = m_MtfArray; + do + { + unsigned symbol = *mtfs++; + if (symbol >= 0xFF) + symbol += *mtfs++; + if (--groupSize == 0) + { + groupSize = kGroupSize; + const unsigned t = *selectors++; + lens = Lens[t]; + codes = Codes[t]; + } + WRITE_BITS_HUFF(codes[symbol], lens[symbol]) + } + while (mtfs < mtf_lim); + } + // Restore_from_Local: + m_OutStreamCurrent._bitPos = _bitPos; + m_OutStreamCurrent._curByte = _curByte; + m_OutStreamCurrent._buf = _buf; + + if (!m_OptimizeNumTables) + break; + const UInt32 price = m_OutStreamCurrent.GetPos() - startPos; + if (price <= bestPrice) + { + if (nt == kNumTablesMax) + break; + bestPrice = price; + bestNumTables = nt; + } + } +} + + +// blockSize > 0 +UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize) +{ + WriteByte2(kBlockSig0); + WriteByte2(kBlockSig1); + WriteByte2(kBlockSig2); + WriteByte2(kBlockSig3); + WriteByte2(kBlockSig4); + WriteByte2(kBlockSig5); + + CBZip2Crc crc; + const Byte * const lim = block + blockSize; + unsigned b = *block++; + crc.UpdateByte(b); + for (;;) + { + const unsigned prev = b; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue; + if (block >= lim) { break; } b = *block++; if (b) do crc.UpdateByte(prev); while (--b); + if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); + } + const UInt32 crcRes = crc.GetDigest(); + for (int i = 24; i >= 0; i -= 8) + WriteByte2((Byte)(crcRes >> i)); + EncodeBlock(lim - blockSize, blockSize); + return crcRes; +} + + +void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses) +{ + const UInt32 numCrcs = m_NumCrcs; + + const UInt32 startBytePos = m_OutStreamCurrent.GetBytePos(); + const UInt32 startPos = m_OutStreamCurrent.GetPos(); + const unsigned startCurByte = m_OutStreamCurrent.GetCurByte(); + unsigned endCurByte = 0; + UInt32 endPos = 0; // 0 means no no additional passes + if (numPasses > 1 && blockSize >= (1 << 10)) + { + UInt32 bs0 = blockSize / 2; + for (; bs0 < blockSize && + (block[ bs0 ] == + block[(size_t)bs0 - 1] || + block[(size_t)bs0 - 1] == + block[(size_t)bs0 - 2]); + bs0++) + {} + + if (bs0 < blockSize) + { + EncodeBlock2(block, bs0, numPasses - 1); + EncodeBlock2(block + bs0, blockSize - bs0, numPasses - 1); + endPos = m_OutStreamCurrent.GetPos(); + endCurByte = m_OutStreamCurrent.GetCurByte(); + // we prepare next byte as identical byte to starting byte for main encoding attempt: + if (endPos & 7) + WriteBits2(0, 8 - (endPos & 7)); + m_OutStreamCurrent.SetCurState((startPos & 7), startCurByte); + } + } + + const UInt32 startBytePos2 = m_OutStreamCurrent.GetBytePos(); + const UInt32 startPos2 = m_OutStreamCurrent.GetPos(); + const UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize); + + if (endPos) + { + const UInt32 size2 = m_OutStreamCurrent.GetPos() - startPos2; + if (size2 >= endPos - startPos) + { + m_OutStreamCurrent.SetPos(endPos); + m_OutStreamCurrent.SetCurState((endPos & 7), endCurByte); + return; + } + const UInt32 numBytes = m_OutStreamCurrent.GetBytePos() - startBytePos2; + Byte * const buffer = m_OutStreamCurrent.GetStream(); + memmove(buffer + startBytePos, buffer + startBytePos2, numBytes); + m_OutStreamCurrent.SetPos(startPos + size2); + // we don't call m_OutStreamCurrent.SetCurState() here because + // m_OutStreamCurrent._curByte is correct already + } + m_CRCs[numCrcs] = crcVal; + m_NumCrcs = numCrcs + 1; +} + + +HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize) +{ + CMsbfEncoderTemp &outStreamTemp = m_OutStreamCurrent; + outStreamTemp.SetStream(m_TempArray); + outStreamTemp.Init(); + m_NumCrcs = 0; + + EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses); + +#ifndef Z7_ST + if (Encoder->MtMode) + Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock(); +#endif + + for (UInt32 i = 0; i < m_NumCrcs; i++) + Encoder->CombinedCrc.Update(m_CRCs[i]); + Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetNonFlushedByteBits()); + HRESULT res = S_OK; + +#ifndef Z7_ST + if (Encoder->MtMode) + { + UInt32 blockIndex = m_BlockIndex + 1; + if (blockIndex == Encoder->NumThreads) + blockIndex = 0; + if (Encoder->Progress) + { + const UInt64 packSize = Encoder->m_OutStream.GetProcessedSize(); + res = Encoder->Progress->SetRatioInfo(&m_UnpackSize, &packSize); + } + Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set(); + } +#endif + return res; +} + +void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, unsigned lastByteBits) +{ + m_OutStream.WriteBytes(data, sizeInBits >> 3); + sizeInBits &= 7; + if (sizeInBits) + m_OutStream.WriteBits(lastByteBits, sizeInBits); +} + + +HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) +{ + ThreadNextGroup_Init(&ThreadNextGroup, _props.NumThreadGroups, 0); // startGroup + + NumBlocks = 0; + #ifndef Z7_ST + Progress = progress; + RINOK(Create()) + for (UInt32 t = 0; t < NumThreads; t++) + #endif + { + #ifndef Z7_ST + CThreadInfo &ti = ThreadsInfo[t]; + if (MtMode) + { + WRes wres = ti.StreamWasFinishedEvent.Reset(); + if (wres == 0) { wres = ti.WaitingWasStartedEvent.Reset(); + if (wres == 0) { wres = ti.CanWriteEvent.Reset(); }} + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + #else + CThreadInfo &ti = ThreadsInfo; + ti.Encoder = this; + #endif + + ti.m_OptimizeNumTables = _props.DoOptimizeNumTables(); + + if (!ti.Alloc()) + return E_OUTOFMEMORY; + } + + + if (!m_InStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(kBufferSize)) + return E_OUTOFMEMORY; + + + m_InStream.SetStream(inStream); + m_InStream.Init(); + + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + CombinedCrc.Init(); + #ifndef Z7_ST + NextBlockIndex = 0; + StreamWasFinished = false; + CloseThreads = false; + CanStartWaitingEvent.Reset(); + #endif + + WriteByte(kArSig0); + WriteByte(kArSig1); + WriteByte(kArSig2); + WriteByte((Byte)(kArSig3 + _props.BlockSizeMult)); + + #ifndef Z7_ST + + if (MtMode) + { + ThreadsInfo[0].CanWriteEvent.Set(); + Result = S_OK; + CanProcessEvent.Set(); + UInt32 t; + for (t = 0; t < NumThreads; t++) + ThreadsInfo[t].StreamWasFinishedEvent.Lock(); + CanProcessEvent.Reset(); + CanStartWaitingEvent.Set(); + for (t = 0; t < NumThreads; t++) + ThreadsInfo[t].WaitingWasStartedEvent.Lock(); + CanStartWaitingEvent.Reset(); + RINOK(Result) + } + else + #endif + { + for (;;) + { + CThreadInfo &ti = + #ifndef Z7_ST + ThreadsInfo[0]; + #else + ThreadsInfo; + #endif + const UInt32 blockSize = ReadRleBlock(ti.m_Block); + if (blockSize == 0) + break; + RINOK(ti.EncodeBlock3(blockSize)) + if (progress) + { + const UInt64 unpackSize = m_InStream.GetProcessedSize(); + const UInt64 packSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&unpackSize, &packSize)) + } + } + } + WriteByte(kFinSig0); + WriteByte(kFinSig1); + WriteByte(kFinSig2); + WriteByte(kFinSig3); + WriteByte(kFinSig4); + WriteByte(kFinSig5); + { + const UInt32 v = CombinedCrc.GetDigest(); + for (int i = 24; i >= 0; i -= 8) + WriteByte((Byte)(v >> i)); + } + RINOK(Flush()) + if (!m_InStream.WasFinished()) + return E_FAIL; + return S_OK; +} + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + int level = -1; + CEncProps props; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + + if (propID == NCoderPropID::kAffinity) + { + if (prop.vt != VT_UI8) + return E_INVALIDARG; + props.Affinity = prop.uhVal.QuadPart; + continue; + } + + if (propID == NCoderPropID::kNumThreadGroups) + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + props.NumThreadGroups = (UInt32)prop.ulVal; + continue; + } + + if (propID >= NCoderPropID::kReduceSize) + continue; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + const UInt32 v = (UInt32)prop.ulVal; + switch (propID) + { + case NCoderPropID::kNumPasses: props.NumPasses = v; break; + case NCoderPropID::kDictionarySize: props.BlockSizeMult = v / kBlockSizeStep; break; + case NCoderPropID::kLevel: level = (int)v; break; + case NCoderPropID::kNumThreads: + { + #ifndef Z7_ST + SetNumberOfThreads(v); + #endif + break; + } + default: return E_INVALIDARG; + } + } + props.Normalize(level); + _props = props; + return S_OK; +} + +#ifndef Z7_ST +Z7_COM7F_IMF(CEncoder::SetNumberOfThreads(UInt32 numThreads)) +{ + const UInt32 kNumThreadsMax = 64; + if (numThreads < 1) numThreads = 1; + if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax; + NumThreads = numThreads; + return S_OK; +} +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Encoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Encoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Encoder.h 2025-02-28 06:00:00.000000000 +0000 @@ -1,239 +1,273 @@ -// BZip2Encoder.h - -#ifndef __COMPRESS_BZIP2_ENCODER_H -#define __COMPRESS_BZIP2_ENCODER_H - -#include "../../Common/Defs.h" -#include "../../Common/MyCom.h" - -#ifndef _7ZIP_ST -#include "../../Windows/Synchronization.h" -#include "../../Windows/Thread.h" -#endif - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" -#include "../Common/OutBuffer.h" - -#include "BitmEncoder.h" -#include "BZip2Const.h" -#include "BZip2Crc.h" - -namespace NCompress { -namespace NBZip2 { - -class CMsbfEncoderTemp -{ - UInt32 _pos; - unsigned _bitPos; - Byte _curByte; - Byte *_buf; -public: - void SetStream(Byte *buf) { _buf = buf; } - Byte *GetStream() const { return _buf; } - - void Init() - { - _pos = 0; - _bitPos = 8; - _curByte = 0; - } - - void Flush() - { - if (_bitPos < 8) - WriteBits(0, _bitPos); - } - - void WriteBits(UInt32 value, unsigned numBits) - { - while (numBits > 0) - { - unsigned numNewBits = MyMin(numBits, _bitPos); - numBits -= numNewBits; - - _curByte <<= numNewBits; - UInt32 newBits = value >> numBits; - _curByte |= Byte(newBits); - value -= (newBits << numBits); - - _bitPos -= numNewBits; - - if (_bitPos == 0) - { - _buf[_pos++] = _curByte; - _bitPos = 8; - } - } - } - - UInt32 GetBytePos() const { return _pos ; } - UInt32 GetPos() const { return _pos * 8 + (8 - _bitPos); } - Byte GetCurByte() const { return _curByte; } - void SetPos(UInt32 bitPos) - { - _pos = bitPos >> 3; - _bitPos = 8 - ((unsigned)bitPos & 7); - } - void SetCurState(unsigned bitPos, Byte curByte) - { - _bitPos = 8 - bitPos; - _curByte = curByte; - } -}; - -class CEncoder; - -const unsigned kNumPassesMax = 10; - -class CThreadInfo -{ -public: - Byte *m_Block; -private: - Byte *m_MtfArray; - Byte *m_TempArray; - UInt32 *m_BlockSorterIndex; - - CMsbfEncoderTemp *m_OutStreamCurrent; - - Byte Lens[kNumTablesMax][kMaxAlphaSize]; - UInt32 Freqs[kNumTablesMax][kMaxAlphaSize]; - UInt32 Codes[kNumTablesMax][kMaxAlphaSize]; - - Byte m_Selectors[kNumSelectorsMax]; - - UInt32 m_CRCs[1 << kNumPassesMax]; - UInt32 m_NumCrcs; - - UInt32 m_BlockIndex; - - void WriteBits2(UInt32 value, unsigned numBits); - void WriteByte2(Byte b); - void WriteBit2(Byte v); - void WriteCrc2(UInt32 v); - - void EncodeBlock(const Byte *block, UInt32 blockSize); - UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize); - void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses); -public: - bool m_OptimizeNumTables; - CEncoder *Encoder; - #ifndef _7ZIP_ST - NWindows::CThread Thread; - - NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; - NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; - - // it's not member of this thread. We just need one event per thread - NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; - - UInt64 m_PackSize; - - Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. - HRESULT Create(); - void FinishStream(bool needLeave); - DWORD ThreadFunc(); - #endif - - CThreadInfo(): m_BlockSorterIndex(0), m_Block(0) {} - ~CThreadInfo() { Free(); } - bool Alloc(); - void Free(); - - HRESULT EncodeBlock3(UInt32 blockSize); -}; - -struct CEncProps -{ - UInt32 BlockSizeMult; - UInt32 NumPasses; - - CEncProps() - { - BlockSizeMult = (UInt32)(Int32)-1; - NumPasses = (UInt32)(Int32)-1; - } - void Normalize(int level); - bool DoOptimizeNumTables() const { return NumPasses > 1; } -}; - -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - #ifndef _7ZIP_ST - public ICompressSetCoderMt, - #endif - public CMyUnknownImp -{ - UInt32 m_NumThreadsPrev; -public: - CInBuffer m_InStream; - Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. - CBitmEncoder m_OutStream; - CEncProps _props; - CBZip2CombinedCrc CombinedCrc; - - #ifndef _7ZIP_ST - CThreadInfo *ThreadsInfo; - NWindows::NSynchronization::CManualResetEvent CanProcessEvent; - NWindows::NSynchronization::CCriticalSection CS; - UInt32 NumThreads; - bool MtMode; - UInt32 NextBlockIndex; - - bool CloseThreads; - bool StreamWasFinished; - NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; - - HRESULT Result; - ICompressProgressInfo *Progress; - #else - CThreadInfo ThreadsInfo; - #endif - - UInt32 ReadRleBlock(Byte *buf); - void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte); - - void WriteBits(UInt32 value, unsigned numBits); - void WriteByte(Byte b); - // void WriteBit(Byte v); - void WriteCrc(UInt32 v); - - #ifndef _7ZIP_ST - HRESULT Create(); - void Free(); - #endif - -public: - CEncoder(); - #ifndef _7ZIP_ST - ~CEncoder(); - #endif - - HRESULT Flush() { return m_OutStream.Flush(); } - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - #ifndef _7ZIP_ST - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) - #endif - MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - #ifndef _7ZIP_ST - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads); - #endif -}; - -}} - -#endif +// BZip2Encoder.h + +#ifndef ZIP7_INC_COMPRESS_BZIP2_ENCODER_H +#define ZIP7_INC_COMPRESS_BZIP2_ENCODER_H + +#include "../../Common/MyCom.h" + +#ifndef Z7_ST +#include "../../Windows/Synchronization.h" +#include "../../Windows/Thread.h" +#endif + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +#include "BitmEncoder.h" +#include "BZip2Const.h" +#include "BZip2Crc.h" + +namespace NCompress { +namespace NBZip2 { + +const unsigned kNumPassesMax = 10; + +struct CMsbfEncoderTemp +{ + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled + Byte *_buf; + Byte *_buf_base; + void SetStream(Byte *buf) { _buf_base = _buf = buf; } + Byte *GetStream() const { return _buf_base; } + + void Init() + { + _bitPos = 8; + _curByte = 0; + _buf = _buf_base; + } + + // required condition: (value >> numBits) == 0 + // numBits == 0 is allowed + void WriteBits(UInt32 value, unsigned numBits) + { + do + { + unsigned bp = _bitPos; + unsigned curByte = _curByte; + if (numBits < bp) + { + bp -= numBits; + _curByte = curByte | (value << bp); + _bitPos = bp; + return; + } + numBits -= bp; + const UInt32 hi = value >> numBits; + value -= (hi << numBits); + Byte *buf = _buf; + _bitPos = 8; + _curByte = 0; + *buf++ = (Byte)(curByte | hi); + _buf = buf; + } + while (numBits); + } + + void WriteBit(unsigned value) + { + const unsigned bp = _bitPos - 1; + const unsigned curByte = _curByte | (value << bp); + _curByte = curByte; + _bitPos = bp; + if (bp == 0) + { + *_buf++ = (Byte)curByte; + _curByte = 0; + _bitPos = 8; + } + } + + void WriteByte(unsigned b) + { + const unsigned bp = _bitPos; + const unsigned a = _curByte | (b >> (8 - bp)); + _curByte = b << bp; + Byte *buf = _buf; + *buf++ = (Byte)a; + _buf = buf; + } + + UInt32 GetBytePos() const { return (UInt32)(size_t)(_buf - _buf_base); } + UInt32 GetPos() const { return GetBytePos() * 8 + 8 - _bitPos; } + unsigned GetCurByte() const { return _curByte; } + unsigned GetNonFlushedByteBits() const { return _curByte >> _bitPos; } + void SetPos(UInt32 bitPos) + { + _buf = _buf_base + (bitPos >> 3); + _bitPos = 8 - ((unsigned)bitPos & 7); + } + void SetCurState(unsigned bitPos, unsigned curByte) + { + _bitPos = 8 - bitPos; + _curByte = curByte; + } +}; + + +class CEncoder; + +class CThreadInfo +{ +private: + CMsbfEncoderTemp m_OutStreamCurrent; +public: + CEncoder *Encoder; + Byte *m_Block; +private: + Byte *m_MtfArray; + Byte *m_TempArray; + UInt32 *m_BlockSorterIndex; + +public: + bool m_OptimizeNumTables; + UInt32 m_NumCrcs; + UInt32 m_BlockIndex; + UInt64 m_UnpackSize; + + Byte *m_Block_Base; + + Byte Lens[kNumTablesMax][kMaxAlphaSize]; + UInt32 Freqs[kNumTablesMax][kMaxAlphaSize]; + UInt32 Codes[kNumTablesMax][kMaxAlphaSize]; + + Byte m_Selectors[kNumSelectorsMax]; + + UInt32 m_CRCs[1 << kNumPassesMax]; + + void WriteBits2(UInt32 value, unsigned numBits); + void WriteByte2(unsigned b) { WriteBits2(b, 8); } + void WriteBit2(unsigned v) { m_OutStreamCurrent.WriteBit(v); } + + void EncodeBlock(const Byte *block, UInt32 blockSize); + UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize); + void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses); +public: +#ifndef Z7_ST + NWindows::CThread Thread; + + NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent; + NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent; + + // it's not member of this thread. We just need one event per thread + NWindows::NSynchronization::CAutoResetEvent CanWriteEvent; + +public: + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + HRESULT Create(); + void FinishStream(bool needLeave); + THREAD_FUNC_RET_TYPE ThreadFunc(); +#endif + + CThreadInfo(): m_BlockSorterIndex(NULL), m_Block_Base(NULL) {} + ~CThreadInfo() { Free(); } + bool Alloc(); + void Free(); + + HRESULT EncodeBlock3(UInt32 blockSize); +}; + + +struct CEncProps +{ + UInt32 BlockSizeMult; + UInt32 NumPasses; + UInt32 NumThreadGroups; + UInt64 Affinity; + + CEncProps() + { + BlockSizeMult = (UInt32)(Int32)-1; + NumPasses = (UInt32)(Int32)-1; + NumThreadGroups = 0; + Affinity = 0; + } + void Normalize(int level); + bool DoOptimizeNumTables() const { return NumPasses > 1; } +}; + +class CEncoder Z7_final: + public ICompressCoder, + public ICompressSetCoderProperties, + #ifndef Z7_ST + public ICompressSetCoderMt, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetCoderProperties) + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + #endif + + #ifndef Z7_ST + UInt32 m_NumThreadsPrev; + #endif +public: + CInBuffer m_InStream; + #ifndef Z7_ST + Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size. + #endif + CBitmEncoder m_OutStream; + CEncProps _props; + CBZip2CombinedCrc CombinedCrc; + + #ifndef Z7_ST + CThreadInfo *ThreadsInfo; + NWindows::NSynchronization::CManualResetEvent CanProcessEvent; + NWindows::NSynchronization::CCriticalSection CS; + UInt32 NumThreads; + bool MtMode; + UInt32 NextBlockIndex; + + bool CloseThreads; + bool StreamWasFinished; + NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent; + CThreadNextGroup ThreadNextGroup; + + HRESULT Result; + ICompressProgressInfo *Progress; + #else + CThreadInfo ThreadsInfo; + #endif + + UInt64 NumBlocks; + + UInt64 GetInProcessedSize() const { return m_InStream.GetProcessedSize(); } + + UInt32 ReadRleBlock(Byte *buf); + void WriteBytes(const Byte *data, UInt32 sizeInBits, unsigned lastByteBits); + void WriteByte(Byte b); + + #ifndef Z7_ST + HRESULT Create(); + void Free(); + #endif + +public: + CEncoder(); + #ifndef Z7_ST + ~CEncoder(); + #endif + + HRESULT Flush() { return m_OutStream.Flush(); } + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BZip2Register.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Register.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BZip2Register.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BZip2Register.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -1,25 +1,25 @@ -// BZip2Register.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "BZip2Decoder.h" -#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) -#include "BZip2Encoder.h" -#endif - -namespace NCompress { -namespace NBZip2 { - -REGISTER_CODEC_CREATE(CreateDec, CDecoder) - -#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) -REGISTER_CODEC_CREATE(CreateEnc, CEncoder) -#else -#define CreateEnc NULL -#endif - -REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2") - -}} +// BZip2Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BZip2Decoder.h" +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_BZIP2_EXTRACT_ONLY) +#include "BZip2Encoder.h" +#endif + +namespace NCompress { +namespace NBZip2 { + +REGISTER_CODEC_CREATE(CreateDec, CDecoder) + +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_BZIP2_EXTRACT_ONLY) +REGISTER_CODEC_CREATE(CreateEnc, CEncoder) +#else +#define CreateEnc NULL +#endif + +REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Coder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Coder.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.cpp 2023-12-21 11:00:00.000000000 +0000 @@ -1,658 +1,867 @@ -// Bcj2Coder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/StreamUtils.h" - -#include "Bcj2Coder.h" - -namespace NCompress { -namespace NBcj2 { - -CBaseCoder::CBaseCoder() -{ - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) - { - _bufs[i] = NULL; - _bufsCurSizes[i] = 0; - _bufsNewSizes[i] = (1 << 18); - } -} - -CBaseCoder::~CBaseCoder() -{ - for (int i = 0; i < BCJ2_NUM_STREAMS + 1; i++) - ::MidFree(_bufs[i]); -} - -HRESULT CBaseCoder::Alloc(bool allocForOrig) -{ - unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; - for (unsigned i = 0; i < num; i++) - { - UInt32 newSize = _bufsNewSizes[i]; - const UInt32 kMinBufSize = 1; - if (newSize < kMinBufSize) - newSize = kMinBufSize; - if (!_bufs[i] || newSize != _bufsCurSizes[i]) - { - if (_bufs[i]) - { - ::MidFree(_bufs[i]); - _bufs[i] = 0; - } - _bufsCurSizes[i] = 0; - Byte *buf = (Byte *)::MidAlloc(newSize); - _bufs[i] = buf; - if (!buf) - return E_OUTOFMEMORY; - _bufsCurSizes[i] = newSize; - } - } - return S_OK; -} - - - -#ifndef EXTRACT_ONLY - -CEncoder::CEncoder(): _relatLim(BCJ2_RELAT_LIMIT) {} -CEncoder::~CEncoder() {} - -STDMETHODIMP CEncoder::SetInBufSize(UInt32, UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } -STDMETHODIMP CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) -{ - UInt32 relatLim = BCJ2_RELAT_LIMIT; - - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) - continue; - switch (propID) - { - /* - case NCoderPropID::kDefaultProp: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = prop.ulVal; - if (v > 31) - return E_INVALIDARG; - relatLim = (UInt32)1 << v; - break; - } - */ - case NCoderPropID::kDictionarySize: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - relatLim = prop.ulVal; - if (relatLim > ((UInt32)1 << 31)) - return E_INVALIDARG; - break; - } - - case NCoderPropID::kNumThreads: - continue; - case NCoderPropID::kLevel: - continue; - - default: return E_INVALIDARG; - } - } - - _relatLim = relatLim; - - return S_OK; -} - - -HRESULT CEncoder::CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams, - ICompressProgressInfo *progress) -{ - if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS) - return E_INVALIDARG; - - RINOK(Alloc()); - - UInt32 fileSize_for_Conv = 0; - if (inSizes && inSizes[0]) - { - UInt64 inSize = *inSizes[0]; - if (inSize <= BCJ2_FileSize_MAX) - fileSize_for_Conv = (UInt32)inSize; - } - - CMyComPtr getSubStreamSize; - inStreams[0]->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize); - - CBcj2Enc enc; - - enc.src = _bufs[BCJ2_NUM_STREAMS]; - enc.srcLim = enc.src; - - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - { - enc.bufs[i] = _bufs[i]; - enc.lims[i] = _bufs[i] + _bufsCurSizes[i]; - } - } - - size_t numBytes_in_ReadBuf = 0; - UInt64 prevProgress = 0; - UInt64 totalStreamRead = 0; // size read from InputStream - UInt64 currentInPos = 0; // data that was processed, it doesn't include data in input buffer and data in enc.temp - UInt64 outSizeRc = 0; - - Bcj2Enc_Init(&enc); - - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - - enc.relatLimit = _relatLim; - - enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - bool needSubSize = false; - UInt64 subStreamIndex = 0; - UInt64 subStreamStartPos = 0; - bool readWasFinished = false; - - for (;;) - { - if (needSubSize && getSubStreamSize) - { - enc.fileIp = 0; - enc.fileSize = fileSize_for_Conv; - enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; - - for (;;) - { - UInt64 subStreamSize = 0; - HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize); - needSubSize = false; - - if (result == S_OK) - { - UInt64 newEndPos = subStreamStartPos + subStreamSize; - - bool isAccurateEnd = (newEndPos < totalStreamRead || - (newEndPos <= totalStreamRead && readWasFinished)); - - if (newEndPos <= currentInPos && isAccurateEnd) - { - subStreamStartPos = newEndPos; - subStreamIndex++; - continue; - } - - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - - if (isAccurateEnd) - { - // data in enc.temp is possible here - size_t rem = (size_t)(totalStreamRead - newEndPos); - - /* Pos_of(enc.src) <= old newEndPos <= newEndPos - in another case, it's fail in some code */ - if ((size_t)(enc.srcLim - enc.src) < rem) - return E_FAIL; - - enc.srcLim -= rem; - enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; - } - - if (subStreamSize <= BCJ2_FileSize_MAX) - { - enc.fileIp = enc.ip + (UInt32)(subStreamStartPos - currentInPos); - enc.fileSize = (UInt32)subStreamSize; - } - break; - } - - if (result == S_FALSE) - break; - if (result == E_NOTIMPL) - { - getSubStreamSize.Release(); - break; - } - return result; - } - } - - if (readWasFinished && totalStreamRead - currentInPos == Bcj2Enc_Get_InputData_Size(&enc)) - enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM; - - Bcj2Enc_Encode(&enc); - - currentInPos = totalStreamRead - numBytes_in_ReadBuf + (enc.src - _bufs[BCJ2_NUM_STREAMS]) - enc.tempPos; - - if (Bcj2Enc_IsFinished(&enc)) - break; - - if (enc.state < BCJ2_NUM_STREAMS) - { - size_t curSize = enc.bufs[enc.state] - _bufs[enc.state]; - // printf("Write stream = %2d %6d\n", enc.state, curSize); - RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)); - if (enc.state == BCJ2_STREAM_RC) - outSizeRc += curSize; - - enc.bufs[enc.state] = _bufs[enc.state]; - enc.lims[enc.state] = _bufs[enc.state] + _bufsCurSizes[enc.state]; - } - else if (enc.state != BCJ2_ENC_STATE_ORIG) - return E_FAIL; - else - { - needSubSize = true; - - if (numBytes_in_ReadBuf != (size_t)(enc.src - _bufs[BCJ2_NUM_STREAMS])) - { - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - continue; - } - - if (readWasFinished) - continue; - - numBytes_in_ReadBuf = 0; - enc.src = _bufs[BCJ2_NUM_STREAMS]; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS]; - - UInt32 curSize = _bufsCurSizes[BCJ2_NUM_STREAMS]; - RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)); - - // printf("Read %6d bytes\n", curSize); - if (curSize == 0) - { - readWasFinished = true; - continue; - } - - numBytes_in_ReadBuf = curSize; - totalStreamRead += numBytes_in_ReadBuf; - enc.srcLim = _bufs[BCJ2_NUM_STREAMS] + numBytes_in_ReadBuf; - } - - if (progress && currentInPos - prevProgress >= (1 << 20)) - { - UInt64 outSize2 = currentInPos + outSizeRc + enc.bufs[BCJ2_STREAM_RC] - enc.bufs[BCJ2_STREAM_RC]; - prevProgress = currentInPos; - // printf("progress %8d, %8d\n", (int)inSize2, (int)outSize2); - RINOK(progress->SetRatioInfo(¤tInPos, &outSize2)); - } - } - - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - { - RINOK(WriteStream(outStreams[i], _bufs[i], enc.bufs[i] - _bufs[i])); - } - - // if (currentInPos != subStreamStartPos + subStreamSize) return E_FAIL; - - return S_OK; -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) -{ - try - { - return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); - } - catch(...) { return E_FAIL; } -} - -#endif - - - - - - -STDMETHODIMP CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size) { _bufsNewSizes[streamIndex] = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _bufsNewSizes[BCJ2_NUM_STREAMS] = size; return S_OK; } - -CDecoder::CDecoder(): _finishMode(false), _outSizeDefined(false), _outSize(0) -{} - -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) -{ - _finishMode = (finishMode != 0); - return S_OK; -} - -void CDecoder::InitCommon() -{ - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - dec.lims[i] = dec.bufs[i] = _bufs[i]; - } - - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - { - _extraReadSizes[i] = 0; - _inStreamsProcessed[i] = 0; - _readRes[i] = S_OK; - } - } - - Bcj2Dec_Init(&dec); -} - -HRESULT CDecoder::Code(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) -{ - if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1) - return E_INVALIDARG; - - RINOK(Alloc()); - - InitCommon(); - - dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS]; - - UInt64 outSizeProcessed = 0; - UInt64 prevProgress = 0; - - HRESULT res = S_OK; - - for (;;) - { - if (Bcj2Dec_Decode(&dec) != SZ_OK) - return S_FALSE; - - if (dec.state < BCJ2_NUM_STREAMS) - { - size_t totalRead = _extraReadSizes[dec.state]; - { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) - { - res = _readRes[dec.state]; - break; - } - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - /* - we want to call Read even even if size is 0 - if (inSizes && inSizes[dec.state]) - { - UInt64 rem = *inSizes[dec.state] - _inStreamsProcessed[dec.state]; - if (curSize > rem) - curSize = (UInt32)rem; - } - */ - - HRESULT res2 = inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (_readRes[dec.state] != S_OK) - res = _readRes[dec.state]; - - if (totalRead == 0) - break; - - // res == S_OK; - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - res = (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - break; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; - } - else // if (dec.state <= BCJ2_STATE_ORIG) - { - size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; - if (curSize != 0) - { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); - } - dec.dest = _bufs[BCJ2_NUM_STREAMS]; - { - size_t rem = _bufsCurSizes[BCJ2_NUM_STREAMS]; - if (outSizes && outSizes[0]) - { - UInt64 outSize = *outSizes[0] - outSizeProcessed; - if (rem > outSize) - rem = (size_t)outSize; - } - dec.destLim = dec.dest + rem; - if (rem == 0) - break; - } - } - - if (progress) - { - UInt64 outSize2 = outSizeProcessed + (dec.dest - _bufs[BCJ2_NUM_STREAMS]); - if (outSize2 - prevProgress >= (1 << 22)) - { - UInt64 inSize2 = outSize2 + _inStreamsProcessed[BCJ2_STREAM_RC] - (dec.lims[BCJ2_STREAM_RC] - dec.bufs[BCJ2_STREAM_RC]); - RINOK(progress->SetRatioInfo(&inSize2, &outSize2)); - prevProgress = outSize2; - } - } - } - - size_t curSize = dec.dest - _bufs[BCJ2_NUM_STREAMS]; - if (curSize != 0) - { - outSizeProcessed += curSize; - RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)); - } - - if (res != S_OK) - return res; - - if (_finishMode) - { - if (!Bcj2Dec_IsFinished(&dec)) - return S_FALSE; - - // we still allow the cases when input streams are larger than required for decoding. - // so the case (dec.state == BCJ2_STATE_ORIG) is also allowed, if MAIN stream is larger than required. - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) - return S_FALSE; - - if (inSizes) - { - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - { - size_t rem = dec.lims[i] - dec.bufs[i] + _extraReadSizes[i]; - /* - if (rem != 0) - return S_FALSE; - */ - if (inSizes[i] && *inSizes[i] != _inStreamsProcessed[i] - rem) - return S_FALSE; - } - } - } - - return S_OK; -} - -STDMETHODIMP CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream) -{ - _inStreams[streamIndex] = inStream; - return S_OK; -} - -STDMETHODIMP CDecoder::ReleaseInStream2(UInt32 streamIndex) -{ - _inStreams[streamIndex].Release(); - return S_OK; -} - -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) -{ - _outSizeDefined = (outSize != NULL); - _outSize = 0; - if (_outSizeDefined) - _outSize = *outSize; - - _outSize_Processed = 0; - - HRESULT res = Alloc(false); - - InitCommon(); - dec.destLim = dec.dest = NULL; - - return res; -} - - -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - - if (size == 0) - return S_OK; - - UInt32 totalProcessed = 0; - - if (_outSizeDefined) - { - UInt64 rem = _outSize - _outSize_Processed; - if (size > rem) - size = (UInt32)rem; - } - dec.dest = (Byte *)data; - dec.destLim = (const Byte *)data + size; - - HRESULT res = S_OK; - - for (;;) - { - SRes sres = Bcj2Dec_Decode(&dec); - if (sres != SZ_OK) - return S_FALSE; - - { - UInt32 curSize = (UInt32)(dec.dest - (Byte *)data); - if (curSize != 0) - { - totalProcessed += curSize; - if (processedSize) - *processedSize = totalProcessed; - data = (void *)((Byte *)data + curSize); - size -= curSize; - _outSize_Processed += curSize; - } - } - - if (dec.state >= BCJ2_NUM_STREAMS) - break; - - { - size_t totalRead = _extraReadSizes[dec.state]; - { - Byte *buf = _bufs[dec.state]; - for (size_t i = 0; i < totalRead; i++) - buf[i] = dec.bufs[dec.state][i]; - dec.lims[dec.state] = - dec.bufs[dec.state] = buf; - } - - if (_readRes[dec.state] != S_OK) - return _readRes[dec.state]; - - do - { - UInt32 curSize = _bufsCurSizes[dec.state] - (UInt32)totalRead; - HRESULT res2 = _inStreams[dec.state]->Read(_bufs[dec.state] + totalRead, curSize, &curSize); - _readRes[dec.state] = res2; - if (curSize == 0) - break; - _inStreamsProcessed[dec.state] += curSize; - totalRead += curSize; - if (res2 != S_OK) - break; - } - while (totalRead < 4 && BCJ2_IS_32BIT_STREAM(dec.state)); - - if (totalRead == 0) - { - if (totalProcessed == 0) - res = _readRes[dec.state]; - break; - } - - if (BCJ2_IS_32BIT_STREAM(dec.state)) - { - unsigned extraSize = ((unsigned)totalRead & 3); - _extraReadSizes[dec.state] = extraSize; - if (totalRead < 4) - { - if (totalProcessed != 0) - return S_OK; - return (_readRes[dec.state] != S_OK) ? _readRes[dec.state] : S_FALSE; - } - totalRead -= extraSize; - } - - dec.lims[dec.state] = _bufs[dec.state] + totalRead; - } - } - - if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed) - { - if (!Bcj2Dec_IsFinished(&dec)) - return S_FALSE; - - if (dec.state != BCJ2_STREAM_MAIN && - dec.state != BCJ2_DEC_STATE_ORIG) - return S_FALSE; - - /* - for (int i = 0; i < BCJ2_NUM_STREAMS; i++) - if (dec.bufs[i] != dec.lims[i] || _extraReadSizes[i] != 0) - return S_FALSE; - */ - } - - return res; -} - -}} +// Bcj2Coder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" + +#include "../Common/StreamUtils.h" + +#include "Bcj2Coder.h" + +namespace NCompress { +namespace NBcj2 { + +CBaseCoder::CBaseCoder() +{ + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + { + _bufs[i] = NULL; + _bufsSizes[i] = 0; + _bufsSizes_New[i] = (1 << 18); + } +} + +CBaseCoder::~CBaseCoder() +{ + for (unsigned i = 0; i < BCJ2_NUM_STREAMS + 1; i++) + ::MidFree(_bufs[i]); +} + +HRESULT CBaseCoder::Alloc(bool allocForOrig) +{ + const unsigned num = allocForOrig ? BCJ2_NUM_STREAMS + 1 : BCJ2_NUM_STREAMS; + for (unsigned i = 0; i < num; i++) + { + UInt32 size = _bufsSizes_New[i]; + /* buffer sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP streams + must be aligned for 4 */ + size &= ~(UInt32)3; + const UInt32 kMinBufSize = 4; + if (size < kMinBufSize) + size = kMinBufSize; + // size = 4 * 100; // for debug + // if (BCJ2_IS_32BIT_STREAM(i) == 1) size = 4 * 1; // for debug + if (!_bufs[i] || size != _bufsSizes[i]) + { + if (_bufs[i]) + { + ::MidFree(_bufs[i]); + _bufs[i] = NULL; + } + _bufsSizes[i] = 0; + Byte *buf = (Byte *)::MidAlloc(size); + if (!buf) + return E_OUTOFMEMORY; + _bufs[i] = buf; + _bufsSizes[i] = size; + } + } + return S_OK; +} + + + +#ifndef Z7_EXTRACT_ONLY + +CEncoder::CEncoder(): + _relatLim(BCJ2_ENC_RELAT_LIMIT_DEFAULT) + // , _excludeRangeBits(BCJ2_RELAT_EXCLUDE_NUM_BITS) + {} +CEncoder::~CEncoder() {} + +Z7_COM7F_IMF(CEncoder::SetInBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } +Z7_COM7F_IMF(CEncoder::SetOutBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + UInt32 relatLim = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // UInt32 excludeRangeBits = BCJ2_RELAT_EXCLUDE_NUM_BITS; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = props[i]; + const PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize + // && propID != NCoderPropID::kHashBits + ) + continue; + switch (propID) + { + /* + case NCoderPropID::kDefaultProp: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = prop.ulVal; + if (v > 31) + return E_INVALIDARG; + relatLim = (UInt32)1 << v; + break; + } + case NCoderPropID::kHashBits: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = prop.ulVal; + if (v > 31) + return E_INVALIDARG; + excludeRangeBits = v; + break; + } + */ + case NCoderPropID::kDictionarySize: + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + relatLim = prop.ulVal; + if (relatLim > BCJ2_ENC_RELAT_LIMIT_MAX) + return E_INVALIDARG; + break; + } + case NCoderPropID::kNumThreads: + case NCoderPropID::kLevel: + continue; + default: return E_INVALIDARG; + } + } + _relatLim = relatLim; + // _excludeRangeBits = excludeRangeBits; + return S_OK; +} + + +HRESULT CEncoder::CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const * /* outSizes */, UInt32 numOutStreams, + ICompressProgressInfo *progress) +{ + if (numInStreams != 1 || numOutStreams != BCJ2_NUM_STREAMS) + return E_INVALIDARG; + + RINOK(Alloc()) + + CBcj2Enc_ip_unsigned fileSize_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; + if (inSizes && inSizes[0]) + { + const UInt64 inSize = *inSizes[0]; + #ifdef BCJ2_ENC_FileSize_MAX + if (inSize <= BCJ2_ENC_FileSize_MAX) + #endif + fileSize_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(inSize); + } + + Z7_DECL_CMyComPtr_QI_FROM(ICompressGetSubStreamSize, getSubStreamSize, inStreams[0]) + + CBcj2Enc enc; + enc.src = _bufs[BCJ2_NUM_STREAMS]; + enc.srcLim = enc.src; + { + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) + { + enc.bufs[i] = _bufs[i]; + enc.lims[i] = _bufs[i] + _bufsSizes[i]; + } + } + Bcj2Enc_Init(&enc); + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; + enc.relatLimit = _relatLim; + // enc.relatExcludeBits = _excludeRangeBits; + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + + // Varibales that correspond processed data in input stream: + UInt64 inPos_without_Temp = 0; // it doesn't include data in enc.temp[] + UInt64 inPos_with_Temp = 0; // it includes data in enc.temp[] + + UInt64 prevProgress = 0; + UInt64 totalRead = 0; // size read from input stream + UInt64 outSizeRc = 0; + UInt64 subStream_Index = 0; + UInt64 subStream_StartPos = 0; // global start offset of subStreams[subStream_Index] + UInt64 subStream_Size = 0; + const Byte *srcLim_Read = _bufs[BCJ2_NUM_STREAMS]; + bool readWasFinished = false; + bool isAccurate = false; + bool wasUnknownSize = false; + + for (;;) + { + if (readWasFinished && enc.srcLim == srcLim_Read) + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_STREAM; + + // for debug: + // for (int y=0;y<100;y++) { CBcj2Enc enc2 = enc; Bcj2Enc_Encode(&enc2); } + + Bcj2Enc_Encode(&enc); + + inPos_with_Temp = totalRead - (size_t)(srcLim_Read - enc.src); + inPos_without_Temp = inPos_with_Temp - Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); + + // if (inPos_without_Temp != enc.ip64) return E_FAIL; + + if (Bcj2Enc_IsFinished(&enc)) + break; + + if (enc.state < BCJ2_NUM_STREAMS) + { + if (enc.bufs[enc.state] != enc.lims[enc.state]) + return E_FAIL; + const size_t curSize = (size_t)(enc.bufs[enc.state] - _bufs[enc.state]); + // printf("Write stream = %2d %6d\n", enc.state, curSize); + RINOK(WriteStream(outStreams[enc.state], _bufs[enc.state], curSize)) + if (enc.state == BCJ2_STREAM_RC) + outSizeRc += curSize; + enc.bufs[enc.state] = _bufs[enc.state]; + enc.lims[enc.state] = _bufs[enc.state] + _bufsSizes[enc.state]; + } + else + { + if (enc.state != BCJ2_ENC_STATE_ORIG) + return E_FAIL; + // (enc.state == BCJ2_ENC_STATE_ORIG) + if (enc.src != enc.srcLim) + return E_FAIL; + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE + && Bcj2Enc_Get_AvailInputSize_in_Temp(&enc) != 0) + return E_FAIL; + + if (enc.src == srcLim_Read) + { + if (readWasFinished) + return E_FAIL; + UInt32 curSize = _bufsSizes[BCJ2_NUM_STREAMS]; + RINOK(inStreams[0]->Read(_bufs[BCJ2_NUM_STREAMS], curSize, &curSize)) + // printf("Read %6u bytes\n", curSize); + if (curSize == 0) + readWasFinished = true; + totalRead += curSize; + enc.src = _bufs[BCJ2_NUM_STREAMS]; + srcLim_Read = _bufs[BCJ2_NUM_STREAMS] + curSize; + } + enc.srcLim = srcLim_Read; + + if (getSubStreamSize) + { + /* we set base default conversions options that will be used, + if subStream related options will be not OK */ + enc.fileIp64 = 0; + enc.fileSize64_minus1 = fileSize_minus1; + for (;;) + { + UInt64 nextPos; + if (isAccurate) + nextPos = subStream_StartPos + subStream_Size; + else + { + const HRESULT hres = getSubStreamSize->GetSubStreamSize(subStream_Index, &subStream_Size); + if (hres != S_OK) + { + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* if sub-stream size is unknown, we use default settings. + We still can recover to normal mode for next sub-stream, + if GetSubStreamSize() will return S_OK, when current + sub-stream will be finished. + */ + if (hres == S_FALSE) + { + wasUnknownSize = true; + break; + } + if (hres == E_NOTIMPL) + { + getSubStreamSize.Release(); + break; + } + return hres; + } + // printf("GetSubStreamSize %6u : %6u \n", (unsigned)subStream_Index, (unsigned)subStream_Size); + nextPos = subStream_StartPos + subStream_Size; + if ((Int64)subStream_Size == -1) + { + /* it's not expected, but (-1) can mean unknown size. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + wasUnknownSize = true; + break; + } + if (nextPos < subStream_StartPos) + return E_FAIL; + isAccurate = + (nextPos < totalRead + || (nextPos <= totalRead && readWasFinished)); + } + + /* (nextPos) is estimated end position of current sub_stream. + But only (totalRead) and (readWasFinished) values + can confirm that this estimated end position is accurate. + That end position is accurate, if it can't be changed in + further calls of GetSubStreamSize() */ + + /* (nextPos < inPos_with_Temp) is unexpected case here, that we + can get if from some incorrect ICompressGetSubStreamSize object, + where new GetSubStreamSize() call returns smaller size than + confirmed by Read() size from previous GetSubStreamSize() call. + */ + if (nextPos < inPos_with_Temp) + { + if (wasUnknownSize) + { + /* that case can be complicated for recovering. + so we disable sub-streams requesting. */ + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + getSubStreamSize.Release(); + break; + } + return E_FAIL; // to stop after failure + } + + if (nextPos <= inPos_with_Temp) + { + // (nextPos == inPos_with_Temp) + /* CBcj2Enc encoder requires to finish each [non-empty] block (sub-stream) + with BCJ2_ENC_FINISH_MODE_END_BLOCK + or with BCJ2_ENC_FINISH_MODE_END_STREAM for last block: + And we send data of new block to CBcj2Enc, only if previous block was finished. + So we switch to next sub-stream if after Bcj2Enc_Encode() call we have + && (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + && (nextPos == inPos_with_Temp) + && (enc.state == BCJ2_ENC_STATE_ORIG) + */ + if (enc.finishMode != BCJ2_ENC_FINISH_MODE_CONTINUE) + { + /* subStream_StartPos is increased only here. + (subStream_StartPos == inPos_with_Temp) : at start + (subStream_StartPos <= inPos_with_Temp) : will be later + */ + subStream_StartPos = nextPos; + subStream_Size = 0; + wasUnknownSize = false; + subStream_Index++; + isAccurate = false; + // we don't change finishMode here + continue; + } + } + + enc.finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + /* for (!isAccurate) case: + (totalRead <= real_end_of_subStream) + so we can use BCJ2_ENC_FINISH_MODE_CONTINUE up to (totalRead) + // we don't change settings at the end of substream, if settings were unknown, + */ + + /* if (wasUnknownSize) then we can't trust size of that sub-stream. + so we use default settings instead */ + if (!wasUnknownSize) + #ifdef BCJ2_ENC_FileSize_MAX + if (subStream_Size <= BCJ2_ENC_FileSize_MAX) + #endif + { + enc.fileIp64 = + (CBcj2Enc_ip_unsigned)( + (CBcj2Enc_ip_signed)enc.ip64 + + (CBcj2Enc_ip_signed)(subStream_StartPos - inPos_without_Temp)); + Bcj2Enc_SET_FileSize(&enc, subStream_Size) + } + + if (isAccurate) + { + /* (real_end_of_subStream == nextPos <= totalRead) + So we can use BCJ2_ENC_FINISH_MODE_END_BLOCK up to (nextPos). */ + const size_t rem = (size_t)(totalRead - nextPos); + if ((size_t)(enc.srcLim - enc.src) < rem) + return E_FAIL; + enc.srcLim -= rem; + enc.finishMode = BCJ2_ENC_FINISH_MODE_END_BLOCK; + } + + break; + } // for() loop + } // getSubStreamSize + } + + if (progress && inPos_without_Temp - prevProgress >= (1 << 22)) + { + prevProgress = inPos_without_Temp; + const UInt64 outSize2 = inPos_without_Temp + outSizeRc + + (size_t)(enc.bufs[BCJ2_STREAM_RC] - _bufs[BCJ2_STREAM_RC]); + // printf("progress %8u, %8u\n", (unsigned)inSize2, (unsigned)outSize2); + RINOK(progress->SetRatioInfo(&inPos_without_Temp, &outSize2)) + } + } + + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) + { + RINOK(WriteStream(outStreams[i], _bufs[i], (size_t)(enc.bufs[i] - _bufs[i]))) + } + // if (inPos_without_Temp != subStream_StartPos + subStream_Size) return E_FAIL; + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, + ICompressProgressInfo *progress)) +{ + try + { + return CodeReal(inStreams, inSizes, numInStreams, outStreams, outSizes,numOutStreams, progress); + } + catch(...) { return E_FAIL; } +} + +#endif + + + + + + +CDecoder::CDecoder(): + _finishMode(false) +#ifndef Z7_NO_READ_FROM_CODER + , _outSizeDefined(false) + , _outSize(0) + , _outSize_Processed(0) +#endif +{} + +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 streamIndex, UInt32 size)) + { _bufsSizes_New[streamIndex] = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32, UInt32 size)) + { _bufsSizes_New[BCJ2_NUM_STREAMS] = size; return S_OK; } + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + _finishMode = (finishMode != 0); + return S_OK; +} + +void CBaseDecoder::InitCommon() +{ + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) + { + dec.lims[i] = dec.bufs[i] = _bufs[i]; + _readRes[i] = S_OK; + _extraSizes[i] = 0; + _readSizes[i] = 0; + } + Bcj2Dec_Init(&dec); +} + + +/* call ReadInStream() only after Bcj2Dec_Decode(). + input requirement: + (dec.state < BCJ2_NUM_STREAMS) +*/ +void CBaseDecoder::ReadInStream(ISequentialInStream *inStream) +{ + const unsigned state = dec.state; + UInt32 total; + { + Byte *buf = _bufs[state]; + const Byte *cur = dec.bufs[state]; + // if (cur != dec.lims[state]) throw 1; // unexpected case + dec.lims[state] = + dec.bufs[state] = buf; + total = (UInt32)_extraSizes[state]; + for (UInt32 i = 0; i < total; i++) + buf[i] = cur[i]; + } + + if (_readRes[state] != S_OK) + return; + + do + { + UInt32 curSize = _bufsSizes[state] - total; + // if (state == 0) curSize = 0; // for debug + // curSize = 7; // for debug + /* even if we have reached provided inSizes[state] limit, + we call Read() with (curSize != 0), because + we want the called handler of stream->Read() could + execute required Init/Flushing code even for empty stream. + In another way we could call Read() with (curSize == 0) for + finished streams, but some Read() handlers can ignore Read(size=0) calls. + */ + const HRESULT hres = inStream->Read(_bufs[state] + total, curSize, &curSize); + _readRes[state] = hres; + if (curSize == 0) + break; + _readSizes[state] += curSize; + total += curSize; + if (hres != S_OK) + break; + } + while (total < 4 && BCJ2_IS_32BIT_STREAM(state)); + + /* we exit from decoding loop here, if we can't + provide new data for input stream. + Usually it's normal exit after full stream decoding. */ + if (total == 0) + return; + + if (BCJ2_IS_32BIT_STREAM(state)) + { + const unsigned extra = (unsigned)total & 3; + _extraSizes[state] = extra; + if (total < 4) + { + if (_readRes[state] == S_OK) + _readRes[state] = S_FALSE; // actually it's stream error. So maybe we need another error code. + return; + } + total -= (UInt32)extra; + } + + dec.lims[state] += total; // = _bufs[state] + total; +} + + +Z7_COM7F_IMF(CDecoder::Code( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, + ICompressProgressInfo *progress)) +{ + if (numInStreams != BCJ2_NUM_STREAMS || numOutStreams != 1) + return E_INVALIDARG; + + RINOK(Alloc()) + InitCommon(); + + dec.destLim = dec.dest = _bufs[BCJ2_NUM_STREAMS]; + + UInt64 outSizeWritten = 0; + UInt64 prevProgress = 0; + + HRESULT hres_Crit = S_OK; // critical hres status (mostly from input stream reading) + HRESULT hres_Weak = S_OK; // first non-critical error code from input stream reading + + for (;;) + { + if (Bcj2Dec_Decode(&dec) != SZ_OK) + { + /* it's possible only at start (first 5 bytes in RC stream) */ + hres_Crit = S_FALSE; + break; + } + if (dec.state < BCJ2_NUM_STREAMS) + { + ReadInStream(inStreams[dec.state]); + const unsigned state = dec.state; + const HRESULT hres = _readRes[state]; + if (dec.lims[state] == _bufs[state]) + { + // we break decoding, if there are no new data in input stream + hres_Crit = hres; + break; + } + if (hres != S_OK && hres_Weak == S_OK) + hres_Weak = hres; + } + else // (BCJ2_DEC_STATE_ORIG_0 <= state <= BCJ2_STATE_ORIG) + { + { + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } + } + { + UInt32 rem = _bufsSizes[BCJ2_NUM_STREAMS]; + if (outSizes && outSizes[0]) + { + const UInt64 outSize = *outSizes[0] - outSizeWritten; + if (rem > outSize) + rem = (UInt32)outSize; + } + dec.dest = _bufs[BCJ2_NUM_STREAMS]; + dec.destLim = dec.dest + rem; + /* we exit from decoding loop here, + if (outSizes[0]) limit for output stream was reached */ + if (rem == 0) + break; + } + } + + if (progress) + { + // here we don't count additional data in dec.temp (up to 4 bytes for output stream) + const UInt64 processed = outSizeWritten + (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (processed - prevProgress >= (1 << 24)) + { + prevProgress = processed; + const UInt64 inSize = processed + + _readSizes[BCJ2_STREAM_RC] - (size_t)( + dec.lims[BCJ2_STREAM_RC] - + dec.bufs[BCJ2_STREAM_RC]); + RINOK(progress->SetRatioInfo(&inSize, &prevProgress)) + } + } + } + + { + const size_t curSize = (size_t)(dec.dest - _bufs[BCJ2_NUM_STREAMS]); + if (curSize != 0) + { + outSizeWritten += curSize; + RINOK(WriteStream(outStreams[0], _bufs[BCJ2_NUM_STREAMS], curSize)) + } + } + + if (hres_Crit == S_OK) hres_Crit = hres_Weak; + if (hres_Crit != S_OK) return hres_Crit; + + if (_finishMode) + { + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) + return S_FALSE; + + /* here we support two correct ways to finish full stream decoding + with one of the following conditions: + - the end of input stream MAIN was reached + - the end of output stream ORIG was reached + Currently 7-Zip/7z code ends with (state == BCJ2_STREAM_MAIN), + because the sizes of MAIN and ORIG streams are known and these + sizes are stored in 7z archive headers. + And Bcj2Dec_Decode() exits with (state == BCJ2_STREAM_MAIN), + if both MAIN and ORIG streams have reached buffers limits. + But if the size of MAIN stream is not known or if the + size of MAIN stream includes some padding after payload data, + then we still can correctly finish decoding with + (state == BCJ2_DEC_STATE_ORIG), if we know the exact size + of output ORIG stream. + */ + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + + /* the caller also will know written size. + So the following check is optional: */ + if (outSizes && outSizes[0] && *outSizes[0] != outSizeWritten) + return S_FALSE; + + if (inSizes) + { + for (unsigned i = 0; i < BCJ2_NUM_STREAMS; i++) + { + /* if (inSizes[i]) is defined, we do full check for processed stream size. */ + if (inSizes[i] && *inSizes[i] != GetProcessedSize_ForInStream(i)) + return S_FALSE; + } + } + + /* v23.02: we call Read(0) for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP streams, + if there were no Read() calls for such stream. + So the handlers of these input streams objects can do + Init/Flushing even for case when stream is empty: + */ + for (unsigned i = BCJ2_STREAM_CALL; i < BCJ2_STREAM_CALL + 2; i++) + { + if (_readSizes[i]) + continue; + Byte b; + UInt32 processed; + RINOK(inStreams[i]->Read(&b, 0, &processed)) + } + } + + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +{ + *value = GetProcessedSize_ForInStream(streamIndex); + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) +{ + _inStreams[streamIndex] = inStream; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::ReleaseInStream2(UInt32 streamIndex)) +{ + _inStreams[streamIndex].Release(); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + _outSizeDefined = (outSize != NULL); + _outSize = 0; + if (_outSizeDefined) + _outSize = *outSize; + _outSize_Processed = 0; + + const HRESULT res = Alloc(false); // allocForOrig + InitCommon(); + dec.destLim = dec.dest = NULL; + return res; +} + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + /* Note the case: + The output (ORIG) stream can be empty. + But BCJ2_STREAM_RC stream always is not empty. + And we want to support full data processing for all streams. + We disable check (size == 0) here. + So if the caller calls this CDecoder::Read() with (size == 0), + we execute required Init/Flushing code in this CDecoder object. + Also this CDecoder::Read() function will call Read() for input streams. + So the handlers of input streams objects also can do Init/Flushing. + */ + // if (size == 0) return S_OK; // disabled to allow (size == 0) processing + + UInt32 totalProcessed = 0; + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outSize_Processed; + if (size > rem) + size = (UInt32)rem; + } + dec.dest = (Byte *)data; + dec.destLim = (const Byte *)data + size; + + HRESULT res = S_OK; + + for (;;) + { + if (Bcj2Dec_Decode(&dec) != SZ_OK) + return S_FALSE; // this error can be only at start of stream + { + const UInt32 curSize = (UInt32)(size_t)(dec.dest - (Byte *)data); + if (curSize != 0) + { + data = (void *)((Byte *)data + curSize); + size -= curSize; + _outSize_Processed += curSize; + totalProcessed += curSize; + if (processedSize) + *processedSize = totalProcessed; + } + } + if (dec.state >= BCJ2_NUM_STREAMS) + break; + ReadInStream(_inStreams[dec.state]); + if (dec.lims[dec.state] == _bufs[dec.state]) + { + /* we break decoding, if there are no new data in input stream. + and we ignore error code, if some data were written to output buffer. */ + if (totalProcessed == 0) + res = _readRes[dec.state]; + break; + } + } + + if (res == S_OK) + if (_finishMode && _outSizeDefined && _outSize == _outSize_Processed) + { + if (!Bcj2Dec_IsMaybeFinished_code(&dec)) + return S_FALSE; + if (dec.state != BCJ2_STREAM_MAIN) + if (dec.state != BCJ2_DEC_STATE_ORIG) + return S_FALSE; + } + + return res; +} + +#endif + +}} + + +/* +extern "C" +{ +extern UInt32 bcj2_stats[256 + 2][2]; +} + +static class CBcj2Stat +{ +public: + ~CBcj2Stat() + { + printf("\nBCJ2 stat:"); + unsigned sums[2] = { 0, 0 }; + int i; + for (i = 2; i < 256 + 2; i++) + { + sums[0] += bcj2_stats[i][0]; + sums[1] += bcj2_stats[i][1]; + } + const unsigned sums2 = sums[0] + sums[1]; + for (int vi = 0; vi < 256 + 3; vi++) + { + printf("\n"); + UInt32 n0, n1; + if (vi < 4) + printf("\n"); + + if (vi < 2) + i = vi; + else if (vi == 2) + i = -1; + else + i = vi - 1; + + if (i < 0) + { + n0 = sums[0]; + n1 = sums[1]; + printf("calls :"); + } + else + { + if (i == 0) + printf("jcc :"); + else if (i == 1) + printf("jump :"); + else + printf("call %02x :", i - 2); + n0 = bcj2_stats[i][0]; + n1 = bcj2_stats[i][1]; + } + + const UInt32 sum = n0 + n1; + printf(" %10u", sum); + + #define PRINT_PERC(val, sum) \ + { UInt32 _sum = sum; if (_sum == 0) _sum = 1; \ + printf(" %7.3f %%", (double)((double)val * (double)100 / (double)_sum )); } + + if (i >= 2 || i < 0) + { + PRINT_PERC(sum, sums2); + } + else + printf("%10s", ""); + + printf(" :%10u", n0); + PRINT_PERC(n0, sum); + + printf(" :%10u", n1); + PRINT_PERC(n1, sum); + } + printf("\n\n"); + fflush(stdout); + } +} g_CBcjStat; +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Coder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Coder.h 2016-05-20 08:20:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Coder.h 2023-02-22 11:00:00.000000000 +0000 @@ -1,117 +1,127 @@ -// Bcj2Coder.h - -#ifndef __COMPRESS_BCJ2_CODER_H -#define __COMPRESS_BCJ2_CODER_H - -#include "../../../C/Bcj2.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NBcj2 { - -class CBaseCoder -{ -protected: - Byte *_bufs[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsCurSizes[BCJ2_NUM_STREAMS + 1]; - UInt32 _bufsNewSizes[BCJ2_NUM_STREAMS + 1]; - - HRESULT Alloc(bool allocForOrig = true); -public: - CBaseCoder(); - ~CBaseCoder(); -}; - - -#ifndef EXTRACT_ONLY - -class CEncoder: - public ICompressCoder2, - public ICompressSetCoderProperties, - public ICompressSetBufSize, - public CMyUnknownImp, - public CBaseCoder -{ - UInt32 _relatLim; - - HRESULT CodeReal(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - -public: - MY_UNKNOWN_IMP3(ICompressCoder2, ICompressSetCoderProperties, ICompressSetBufSize) - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - CEncoder(); - ~CEncoder(); -}; - -#endif - -class CDecoder: - public ICompressCoder2, - public ICompressSetFinishMode, - public ICompressSetInStream2, - public ISequentialInStream, - public ICompressSetOutStreamSize, - public ICompressSetBufSize, - public CMyUnknownImp, - public CBaseCoder -{ - unsigned _extraReadSizes[BCJ2_NUM_STREAMS]; - UInt64 _inStreamsProcessed[BCJ2_NUM_STREAMS]; - HRESULT _readRes[BCJ2_NUM_STREAMS]; - CMyComPtr _inStreams[BCJ2_NUM_STREAMS]; - - bool _finishMode; - bool _outSizeDefined; - UInt64 _outSize; - UInt64 _outSize_Processed; - CBcj2Dec dec; - - void InitCommon(); - // HRESULT ReadSpec(); - -public: - MY_UNKNOWN_IMP6( - ICompressCoder2, - ICompressSetFinishMode, - ICompressSetInStream2, - ISequentialInStream, - ICompressSetOutStreamSize, - ICompressSetBufSize - ); - - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex); - - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - CDecoder(); -}; - -}} - -#endif +// Bcj2Coder.h + +#ifndef ZIP7_INC_COMPRESS_BCJ2_CODER_H +#define ZIP7_INC_COMPRESS_BCJ2_CODER_H + +#include "../../../C/Bcj2.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NBcj2 { + +class CBaseCoder +{ +protected: + Byte *_bufs[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes[BCJ2_NUM_STREAMS + 1]; + UInt32 _bufsSizes_New[BCJ2_NUM_STREAMS + 1]; + + HRESULT Alloc(bool allocForOrig = true); +public: + CBaseCoder(); + ~CBaseCoder(); +}; + + +#ifndef Z7_EXTRACT_ONLY + +class CEncoder Z7_final: + public ICompressCoder2, + public ICompressSetCoderProperties, + public ICompressSetBufSize, + public CMyUnknownImp, + public CBaseCoder +{ + Z7_IFACES_IMP_UNK_3( + ICompressCoder2, + ICompressSetCoderProperties, + ICompressSetBufSize) + + UInt32 _relatLim; + // UInt32 _excludeRangeBits; + + HRESULT CodeReal( + ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, + ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, + ICompressProgressInfo *progress); +public: + CEncoder(); + ~CEncoder(); +}; + +#endif + + + +class CBaseDecoder: public CBaseCoder +{ +protected: + HRESULT _readRes[BCJ2_NUM_STREAMS]; + unsigned _extraSizes[BCJ2_NUM_STREAMS]; + UInt64 _readSizes[BCJ2_NUM_STREAMS]; + + CBcj2Dec dec; + + UInt64 GetProcessedSize_ForInStream(unsigned i) const + { + return _readSizes[i] - ((size_t)(dec.lims[i] - dec.bufs[i]) + _extraSizes[i]); + } + void InitCommon(); + void ReadInStream(ISequentialInStream *inStream); +}; + + +class CDecoder Z7_final: + public ICompressCoder2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize2, + public ICompressSetBufSize, +#ifndef Z7_NO_READ_FROM_CODER + public ICompressSetInStream2, + public ICompressSetOutStreamSize, + public ISequentialInStream, +#endif + public CMyUnknownImp, + public CBaseDecoder +{ + Z7_COM_QI_BEGIN2(ICompressCoder2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize2) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream2) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize2) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetInStream2) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ISequentialInStream) +#endif + + bool _finishMode; + +#ifndef Z7_NO_READ_FROM_CODER + bool _outSizeDefined; + UInt64 _outSize; + UInt64 _outSize_Processed; + CMyComPtr _inStreams[BCJ2_NUM_STREAMS]; +#endif + +public: + CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Register.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Register.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Bcj2Register.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Bcj2Register.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,24 +1,24 @@ -// Bcj2Register.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "Bcj2Coder.h" - -namespace NCompress { -namespace NBcj2 { - -REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2) -#ifndef EXTRACT_ONLY -REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2) -#else -#define CreateCodecOut NULL -#endif - -REGISTER_CODEC_VAR - { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; - -REGISTER_CODEC(BCJ2) - -}} +// Bcj2Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "Bcj2Coder.h" + +namespace NCompress { +namespace NBcj2 { + +REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2) +#ifndef Z7_EXTRACT_ONLY +REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2) +#else +#define CreateCodecOut NULL +#endif + +REGISTER_CODEC_VAR(BCJ2) + { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; + +REGISTER_CODEC(BCJ2) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BcjCoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BcjCoder.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.cpp 2023-03-27 18:00:00.000000000 +0000 @@ -1,24 +1,24 @@ -// BcjCoder.cpp - -#include "StdAfx.h" - -#include "BcjCoder.h" - -namespace NCompress { -namespace NBcj { - -STDMETHODIMP CCoder::Init() -{ - _bufferPos = 0; - x86_Convert_Init(_prevMask); - return S_OK; -} - -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) -{ - UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); - _bufferPos += processed; - return processed; -} - -}} +// BcjCoder.cpp + +#include "StdAfx.h" + +#include "BcjCoder.h" + +namespace NCompress { +namespace NBcj { + +Z7_COM7F_IMF(CCoder2::Init()) +{ + _pc = 0; + _state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CCoder2::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(_convFunc(data, size, _pc, &_state) - data); + _pc += processed; + return processed; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BcjCoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BcjCoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjCoder.h 2023-03-01 12:00:00.000000000 +0000 @@ -1,31 +1,37 @@ -// BcjCoder.h - -#ifndef __COMPRESS_BCJ_CODER_H -#define __COMPRESS_BCJ_CODER_H - -#include "../../../C/Bra.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NBcj { - -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - UInt32 _prevMask; - int _encode; -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) - - CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } -}; - -}} - -#endif +// BcjCoder.h + +#ifndef ZIP7_INC_COMPRESS_BCJ_CODER_H +#define ZIP7_INC_COMPRESS_BCJ_CODER_H + +#include "../../../C/Bra.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NBcj { + +/* CCoder in old versions used another constructor parameter CCoder(int encode). + And some code called it as CCoder(0). + We have changed constructor parameter type. + So we have changed the name of class also to CCoder2. */ + +Z7_CLASS_IMP_COM_1( + CCoder2 + , ICompressFilter +) + UInt32 _pc; + UInt32 _state; + z7_Func_BranchConvSt _convFunc; +public: + CCoder2(z7_Func_BranchConvSt convFunc): + _pc(0), + _state(Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL), + _convFunc(convFunc) + {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BcjRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BcjRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BcjRegister.cpp 2023-02-20 11:00:00.000000000 +0000 @@ -1,17 +1,17 @@ -// BcjRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "BcjCoder.h" - -namespace NCompress { -namespace NBcj { - -REGISTER_FILTER_E(BCJ, - CCoder(false), - CCoder(true), - 0x3030103, "BCJ") - -}} +// BcjRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BcjCoder.h" + +namespace NCompress { +namespace NBcj { + +REGISTER_FILTER_E(BCJ, + CCoder2(z7_BranchConvSt_X86_Dec), + CCoder2(z7_BranchConvSt_X86_Enc), + 0x3030103, "BCJ") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BitlDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BitlDecoder.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.cpp 2023-12-24 13:00:00.000000000 +0000 @@ -1,24 +1,32 @@ -// BitlDecoder.cpp - -#include "StdAfx.h" - -#include "BitlDecoder.h" - -namespace NBitl { - -Byte kInvertTable[256]; - -struct CInverterTableInitializer -{ - CInverterTableInitializer() - { - for (unsigned i = 0; i < 256; i++) - { - unsigned x = ((i & 0x55) << 1) | ((i & 0xAA) >> 1); - x = ((x & 0x33) << 2) | ((x & 0xCC) >> 2); - kInvertTable[i] = (Byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4)); - } - } -} g_InverterTableInitializer; - -} +// BitlDecoder.cpp + +#include "StdAfx.h" + +#include "BitlDecoder.h" + +namespace NBitl { + +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) + +MY_ALIGN(64) +Byte kReverseTable[256]; + +static +struct CReverseerTableInitializer +{ + CReverseerTableInitializer() + { + for (unsigned i = 0; i < 256; i++) + { + unsigned + x = ((i & 0x55) << 1) | ((i >> 1) & 0x55); + x = ((x & 0x33) << 2) | ((x >> 2) & 0x33); + kReverseTable[i] = (Byte)((x << 4) | (x >> 4)); + } + } +} g_ReverseerTableInitializer; + +#elif 0 +unsigned ReverseBits8test(unsigned i) { return ReverseBits8(i); } +#endif +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BitlDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BitlDecoder.h 2014-12-22 12:58:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlDecoder.h 2023-12-25 11:00:00.000000000 +0000 @@ -1,138 +1,225 @@ -// BitlDecoder.h -- the Least Significant Bit of byte is First - -#ifndef __BITL_DECODER_H -#define __BITL_DECODER_H - -#include "../IStream.h" - -namespace NBitl { - -const unsigned kNumBigValueBits = 8 * 4; -const unsigned kNumValueBytes = 3; -const unsigned kNumValueBits = 8 * kNumValueBytes; - -const UInt32 kMask = (1 << kNumValueBits) - 1; - -extern Byte kInvertTable[256]; - -/* TInByte must support "Extra Bytes" (bytes that can be read after the end of stream - TInByte::ReadByte() returns 0xFF after the end of stream - TInByte::NumExtraBytes contains the number "Extra Bytes" - - Bitl decoder can read up to 4 bytes ahead to internal buffer. */ - -template -class CBaseDecoder -{ -protected: - unsigned _bitPos; - UInt32 _value; - TInByte _stream; -public: - bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } - void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream); } - void Init() - { - _stream.Init(); - _bitPos = kNumBigValueBits; - _value = 0; - } - - UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } - UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } - - bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; } - - void Normalize() - { - for (; _bitPos >= 8; _bitPos -= 8) - _value = ((UInt32)_stream.ReadByte() << (kNumBigValueBits - _bitPos)) | _value; - } - - UInt32 ReadBits(unsigned numBits) - { - Normalize(); - UInt32 res = _value & ((1 << numBits) - 1); - _bitPos += numBits; - _value >>= numBits; - return res; - } - - bool ExtraBitsWereRead() const - { - return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); - } - - bool ExtraBitsWereRead_Fast() const - { - // full version is not inlined in vc6. - // return _stream.NumExtraBytes != 0 && (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); - - // (_stream.NumExtraBytes > 4) is fast overread detection. It's possible that - // it doesn't return true, if small number of extra bits were read. - return (_stream.NumExtraBytes > 4); - } - - // it must be fixed !!! with extra bits - // UInt32 GetNumExtraBytes() const { return _stream.NumExtraBytes; } -}; - -template -class CDecoder: public CBaseDecoder -{ - UInt32 _normalValue; - -public: - void Init() - { - CBaseDecoder::Init(); - _normalValue = 0; - } - - void Normalize() - { - for (; this->_bitPos >= 8; this->_bitPos -= 8) - { - Byte b = this->_stream.ReadByte(); - _normalValue = ((UInt32)b << (kNumBigValueBits - this->_bitPos)) | _normalValue; - this->_value = (this->_value << 8) | kInvertTable[b]; - } - } - - UInt32 GetValue(unsigned numBits) - { - Normalize(); - return ((this->_value >> (8 - this->_bitPos)) & kMask) >> (kNumValueBits - numBits); - } - - void MovePos(unsigned numBits) - { - this->_bitPos += numBits; - _normalValue >>= numBits; - } - - UInt32 ReadBits(unsigned numBits) - { - Normalize(); - UInt32 res = _normalValue & ((1 << numBits) - 1); - MovePos(numBits); - return res; - } - - void AlignToByte() { MovePos((32 - this->_bitPos) & 7); } - - Byte ReadDirectByte() { return this->_stream.ReadByte(); } - - Byte ReadAlignedByte() - { - if (this->_bitPos == kNumBigValueBits) - return this->_stream.ReadByte(); - Byte b = (Byte)(_normalValue & 0xFF); - MovePos(8); - return b; - } -}; - -} - -#endif +// BitlDecoder.h -- the Least Significant Bit of byte is First + +#ifndef ZIP7_INC_BITL_DECODER_H +#define ZIP7_INC_BITL_DECODER_H + +#include "../../../C/CpuArch.h" + +#include "../IStream.h" + +namespace NBitl { + +const unsigned kNumBigValueBits = 8 * 4; +const unsigned kNumValueBytes = 3; +const unsigned kNumValueBits = 8 * kNumValueBytes; +const UInt32 kMask = (1 << kNumValueBits) - 1; + +#if !defined(Z7_BITL_USE_REVERSE_BITS_TABLE) +#if 1 && defined(MY_CPU_ARM_OR_ARM64) \ + && (defined(MY_CPU_ARM64) || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) \ + && (defined(__GNUC__) && (__GNUC__ >= 4) \ + || defined(__clang__) && (__clang_major__ >= 4)) + #define Z7_BITL_USE_REVERSE_BITS_INSTRUCTION +#elif 1 + #define Z7_BITL_USE_REVERSE_BITS_TABLE +#endif +#endif + +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) +extern Byte kReverseTable[256]; +#endif + +inline unsigned ReverseBits8(unsigned i) +{ +#if defined(Z7_BITL_USE_REVERSE_BITS_TABLE) + return kReverseTable[i]; +#elif defined(Z7_BITL_USE_REVERSE_BITS_INSTRUCTION) + // rbit is available in ARMv6T2 and above + asm ("rbit " +#if defined(MY_CPU_ARM) + "%0,%0" // it uses default register size, + // but we need 32-bit register here. + // we must use it only if default register size is 32-bit. + // it will work incorrectly for ARM64. +#else + "%w0,%w0" // it uses 32-bit registers in ARM64. + // compiler for (MY_CPU_ARM) can't compile it. +#endif + : "+r" (i)); + return i >> 24; +#else + unsigned + x = ((i & 0x55) << 1) | ((i >> 1) & 0x55); + x = ((x & 0x33) << 2) | ((x >> 2) & 0x33); + return ((x & 0x0f) << 4) | (x >> 4); +#endif +} + + +/* TInByte must support "Extra Bytes" (bytes that can be read after the end of stream + TInByte::ReadByte() returns 0xFF after the end of stream + TInByte::NumExtraBytes contains the number "Extra Bytes" + + Bitl decoder can read up to 4 bytes ahead to internal buffer. */ + +template +class CBaseDecoder +{ +protected: + unsigned _bitPos; + UInt32 _value; + TInByte _stream; +public: + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream); } + void ClearStreamPtr() { _stream.ClearStreamPtr(); } + void Init() + { + _stream.Init(); + _bitPos = kNumBigValueBits; + _value = 0; + } + + // the size of portion data in real stream that was already read from this object. + // it doesn't include unused data in BitStream object buffer (up to 4 bytes) + // it doesn't include unused data in TInByte buffers + // it doesn't include virtual Extra bytes after the end of real stream data + UInt64 GetStreamSize() const + { + return ExtraBitsWereRead() ? + _stream.GetStreamSize(): + GetProcessedSize(); + } + + // the size of virtual data that was read from this object. + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } + + bool ThereAreDataInBitsBuffer() const { return this->_bitPos != kNumBigValueBits; } + + Z7_FORCE_INLINE + void Normalize() + { + for (; _bitPos >= 8; _bitPos -= 8) + _value = ((UInt32)_stream.ReadByte() << (kNumBigValueBits - _bitPos)) | _value; + } + + Z7_FORCE_INLINE + UInt32 ReadBits(unsigned numBits) + { + Normalize(); + UInt32 res = _value & ((1 << numBits) - 1); + _bitPos += numBits; + _value >>= numBits; + return res; + } + + bool ExtraBitsWereRead() const + { + return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + } + + bool ExtraBitsWereRead_Fast() const + { + // full version is not inlined in vc6. + // return _stream.NumExtraBytes != 0 && (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + + // (_stream.NumExtraBytes > 4) is fast overread detection. It's possible that + // it doesn't return true, if small number of extra bits were read. + return (_stream.NumExtraBytes > 4); + } + + // it must be fixed !!! with extra bits + // UInt32 GetNumExtraBytes() const { return _stream.NumExtraBytes; } +}; + +template +class CDecoder: public CBaseDecoder +{ + UInt32 _normalValue; + +public: + void Init() + { + CBaseDecoder::Init(); + _normalValue = 0; + } + + Z7_FORCE_INLINE + void Normalize() + { + for (; this->_bitPos >= 8; this->_bitPos -= 8) + { + const unsigned b = this->_stream.ReadByte(); + _normalValue = ((UInt32)b << (kNumBigValueBits - this->_bitPos)) | _normalValue; + this->_value = (this->_value << 8) | ReverseBits8(b); + } + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) + { + Normalize(); + return ((this->_value >> (8 - this->_bitPos)) & kMask) >> (kNumValueBits - numBits); + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() + { + Normalize(); + return this->_value << this->_bitPos; + } + + Z7_FORCE_INLINE + void MovePos(size_t numBits) + { + this->_bitPos += (unsigned)numBits; + _normalValue >>= numBits; + } + + Z7_FORCE_INLINE + UInt32 ReadBits(unsigned numBits) + { + Normalize(); + UInt32 res = _normalValue & ((1 << numBits) - 1); + MovePos(numBits); + return res; + } + + void AlignToByte() { MovePos((32 - this->_bitPos) & 7); } + + Z7_FORCE_INLINE + Byte ReadDirectByte() { return this->_stream.ReadByte(); } + + Z7_FORCE_INLINE + size_t ReadDirectBytesPart(Byte *buf, size_t size) { return this->_stream.ReadBytesPart(buf, size); } + + Z7_FORCE_INLINE + Byte ReadAlignedByte() + { + if (this->_bitPos == kNumBigValueBits) + return this->_stream.ReadByte(); + Byte b = (Byte)(_normalValue & 0xFF); + MovePos(8); + return b; + } + + // call it only if the object is aligned for byte. + Z7_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); + MovePos(8); + return true; + } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BitlEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BitlEncoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitlEncoder.h 2025-03-13 13:00:00.000000000 +0000 @@ -1,56 +1,57 @@ -// BitlEncoder.h -- the Least Significant Bit of byte is First - -#ifndef __BITL_ENCODER_H -#define __BITL_ENCODER_H - -#include "../Common/OutBuffer.h" - -class CBitlEncoder -{ - COutBuffer _stream; - unsigned _bitPos; - Byte _curByte; -public: - bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } - void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream); } - // unsigned GetBitPosition() const { return (8 - _bitPos); } - UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } - void Init() - { - _stream.Init(); - _bitPos = 8; - _curByte = 0; - } - HRESULT Flush() - { - FlushByte(); - return _stream.Flush(); - } - void FlushByte() - { - if (_bitPos < 8) - _stream.WriteByte(_curByte); - _bitPos = 8; - _curByte = 0; - } - void WriteBits(UInt32 value, unsigned numBits) - { - while (numBits > 0) - { - if (numBits < _bitPos) - { - _curByte |= (value & ((1 << numBits) - 1)) << (8 - _bitPos); - _bitPos -= numBits; - return; - } - numBits -= _bitPos; - _stream.WriteByte((Byte)(_curByte | (value << (8 - _bitPos)))); - value >>= _bitPos; - _bitPos = 8; - _curByte = 0; - } - } - void WriteByte(Byte b) { _stream.WriteByte(b);} -}; - -#endif +// BitlEncoder.h -- the Least Significant Bit of byte is First + +#ifndef ZIP7_INC_BITL_ENCODER_H +#define ZIP7_INC_BITL_ENCODER_H + +#include "../Common/OutBuffer.h" + +class CBitlEncoder +{ + COutBuffer _stream; + unsigned _bitPos; + Byte _curByte; +public: + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream); } + // unsigned GetBitPosition() const { return (8 - _bitPos); } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } + void Init() + { + _stream.Init(); + _bitPos = 8; + _curByte = 0; + } + HRESULT Flush() + { + FlushByte(); + return _stream.Flush(); + } + void FlushByte() + { + if (_bitPos < 8) + _stream.WriteByte(_curByte); + _bitPos = 8; + _curByte = 0; + } + Z7_FORCE_INLINE + void WriteBits(UInt32 value, unsigned numBits) + { + while (numBits > 0) + { + if (numBits < _bitPos) + { + _curByte |= (Byte)((value & ((1 << numBits) - 1)) << (8 - _bitPos)); + _bitPos -= numBits; + return; + } + numBits -= _bitPos; + _stream.WriteByte((Byte)(_curByte | (value << (8 - _bitPos)))); + value >>= _bitPos; + _bitPos = 8; + _curByte = 0; + } + } + void WriteByte(Byte b) { _stream.WriteByte(b);} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BitmDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BitmDecoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmDecoder.h 2023-12-25 11:00:00.000000000 +0000 @@ -1,95 +1,106 @@ -// BitmDecoder.h -- the Most Significant Bit of byte is First - -#ifndef __BITM_DECODER_H -#define __BITM_DECODER_H - -#include "../IStream.h" - -namespace NBitm { - -const unsigned kNumBigValueBits = 8 * 4; -const unsigned kNumValueBytes = 3; -const unsigned kNumValueBits = 8 * kNumValueBytes; - -const UInt32 kMask = (1 << kNumValueBits) - 1; - -// _bitPos - the number of free bits (high bits in _value) -// (kNumBigValueBits - _bitPos) = (32 - _bitPos) == the number of ready to read bits (low bits of _value) - -template -class CDecoder -{ - unsigned _bitPos; - UInt32 _value; - TInByte _stream; -public: - bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } - void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream);} - - void Init() - { - _stream.Init(); - _bitPos = kNumBigValueBits; - _value = 0; - Normalize(); - } - - UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } - UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } - - bool ExtraBitsWereRead() const - { - return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); - } - - bool ExtraBitsWereRead_Fast() const - { - return (_stream.NumExtraBytes > 4); - } - - void Normalize() - { - for (; _bitPos >= 8; _bitPos -= 8) - _value = (_value << 8) | _stream.ReadByte(); - } - - UInt32 GetValue(unsigned numBits) const - { - // return (_value << _bitPos) >> (kNumBigValueBits - numBits); - return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits); - } - - void MovePos(unsigned numBits) - { - _bitPos += numBits; - Normalize(); - } - - UInt32 ReadBits(unsigned numBits) - { - UInt32 res = GetValue(numBits); - MovePos(numBits); - return res; - } - - /* - unsigned ReadBit() - { - UInt32 res = ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - 1); - if (++_bitPos >= 8) - { - _value = (_value << 8) | _stream.ReadByte(); - _bitPos -= 8; - } - return (unsigned)res; - } - */ - - void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } - - UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); } -}; - -} - -#endif +// BitmDecoder.h -- the Most Significant Bit of byte is First + +#ifndef ZIP7_INC_BITM_DECODER_H +#define ZIP7_INC_BITM_DECODER_H + +#include "../IStream.h" + +namespace NBitm { + +const unsigned kNumBigValueBits = 8 * 4; +const unsigned kNumValueBytes = 3; +const unsigned kNumValueBits = 8 * kNumValueBytes; + +const UInt32 kMask = (1 << kNumValueBits) - 1; + +// _bitPos - the number of free bits (high bits in _value) +// (kNumBigValueBits - _bitPos) = (32 - _bitPos) == the number of ready to read bits (low bits of _value) + +template +class CDecoder +{ + unsigned _bitPos; + UInt32 _value; + TInByte _stream; +public: + bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream);} + + void Init() + { + _stream.Init(); + _bitPos = kNumBigValueBits; + _value = 0; + Normalize(); + } + + UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } + + bool ExtraBitsWereRead() const + { + return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); + } + + bool ExtraBitsWereRead_Fast() const + { + return (_stream.NumExtraBytes > 4); + } + + Z7_FORCE_INLINE + void Normalize() + { + for (; _bitPos >= 8; _bitPos -= 8) + _value = (_value << 8) | _stream.ReadByte(); + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) const + { + // return (_value << _bitPos) >> (kNumBigValueBits - numBits); + return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits); + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() const + { + return this->_value << this->_bitPos; + } + + Z7_FORCE_INLINE + void MovePos(unsigned numBits) + { + _bitPos += numBits; + Normalize(); + } + + Z7_FORCE_INLINE + UInt32 ReadBits(unsigned numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } + + /* + unsigned ReadBit() + { + UInt32 res = ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - 1); + if (++_bitPos >= 8) + { + _value = (_value << 8) | _stream.ReadByte(); + _bitPos -= 8; + } + return (unsigned)res; + } + */ + + void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } + + Z7_FORCE_INLINE + UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BitmEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/BitmEncoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BitmEncoder.h 2025-02-28 06:00:00.000000000 +0000 @@ -1,49 +1,90 @@ -// BitmEncoder.h -- the Most Significant Bit of byte is First - -#ifndef __BITM_ENCODER_H -#define __BITM_ENCODER_H - -#include "../IStream.h" - -template -class CBitmEncoder -{ - unsigned _bitPos; - Byte _curByte; - TOutByte _stream; -public: - bool Create(UInt32 bufferSize) { return _stream.Create(bufferSize); } - void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream);} - UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } - void Init() - { - _stream.Init(); - _bitPos = 8; - _curByte = 0; - } - HRESULT Flush() - { - if (_bitPos < 8) - WriteBits(0, _bitPos); - return _stream.Flush(); - } - void WriteBits(UInt32 value, unsigned numBits) - { - while (numBits > 0) - { - if (numBits < _bitPos) - { - _curByte |= ((Byte)value << (_bitPos -= numBits)); - return; - } - numBits -= _bitPos; - UInt32 newBits = (value >> numBits); - value -= (newBits << numBits); - _stream.WriteByte((Byte)(_curByte | newBits)); - _bitPos = 8; - _curByte = 0; - } - } -}; - -#endif +// BitmEncoder.h -- the Most Significant Bit of byte is First + +#ifndef ZIP7_INC_BITM_ENCODER_H +#define ZIP7_INC_BITM_ENCODER_H + +#include "../IStream.h" + +template +class CBitmEncoder +{ + unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte + unsigned _curByte; // low (_bitPos) bits are zeros + // high (8 - _bitPos) bits are filled + TOutByte _stream; +public: + bool Create(UInt32 bufferSize) { return _stream.Create(bufferSize); } + void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream);} + UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); } + void Init() + { + _stream.Init(); + _bitPos = 8; + _curByte = 0; + } + HRESULT Flush() + { + if (_bitPos < 8) + { + _stream.WriteByte((Byte)_curByte); + _bitPos = 8; + _curByte = 0; + } + return _stream.Flush(); + } + + // required condition: (value >> numBits) == 0 + // numBits == 0 is allowed + void WriteBits(UInt32 value, unsigned numBits) + { + do + { + unsigned bp = _bitPos; + unsigned curByte = _curByte; + if (numBits < bp) + { + bp -= numBits; + _curByte = curByte | (value << bp); + _bitPos = bp; + return; + } + numBits -= bp; + const UInt32 hi = (value >> numBits); + value -= (hi << numBits); + _stream.WriteByte((Byte)(curByte | hi)); + _bitPos = 8; + _curByte = 0; + } + while (numBits); + } + void WriteByte(unsigned b) + { + const unsigned bp = _bitPos; + const unsigned a = _curByte | (b >> (8 - bp)); + _curByte = b << bp; + _stream.WriteByte((Byte)a); + } + + void WriteBytes(const Byte *data, size_t num) + { + const unsigned bp = _bitPos; +#if 1 // 1 for optional speed-optimized code branch + if (bp == 8) + { + _stream.WriteBytes(data, num); + return; + } +#endif + unsigned c = _curByte; + const unsigned bp_rev = 8 - bp; + for (size_t i = 0; i < num; i++) + { + const unsigned b = data[i]; + _stream.WriteByte((Byte)(c | (b >> bp_rev))); + c = b << bp; + } + _curByte = c; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BranchMisc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BranchMisc.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.cpp 2024-02-17 10:00:00.000000000 +0000 @@ -1,23 +1,106 @@ -// BranchMisc.cpp - -#include "StdAfx.h" - -#include "BranchMisc.h" - -namespace NCompress { -namespace NBranch { - -STDMETHODIMP CCoder::Init() -{ - _bufferPos = 0; - return S_OK; -} - -STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size) -{ - UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); - _bufferPos += processed; - return processed; -} - -}} +// BranchMisc.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "BranchMisc.h" + +namespace NCompress { +namespace NBranch { + +Z7_COM7F_IMF(CCoder::Init()) +{ + _pc = 0; + return S_OK; +} + + +Z7_COM7F_IMF2(UInt32, CCoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + + +#ifndef Z7_EXTRACT_ONLY + +Z7_COM7F_IMF(CEncoder::Init()) +{ + _pc = _pc_Init; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + UInt32 pc = 0; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kDefaultProp || + propID == NCoderPropID::kBranchOffset) + { + const PROPVARIANT &prop = props[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + pc = prop.ulVal; + if (pc & _alignment) + return E_INVALIDARG; + } + } + _pc_Init = pc; + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + if (_pc_Init == 0) + return S_OK; + UInt32 buf32[1]; + SetUi32(buf32, _pc_Init) + return WriteStream(outStream, buf32, 4); +} + +#endif + + +Z7_COM7F_IMF(CDecoder::Init()) +{ + _pc = _pc_Init; + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + const UInt32 processed = (UInt32)(size_t)(BraFunc(data, size, _pc) - data); + _pc += processed; + return processed; +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) +{ + UInt32 val = 0; + if (size != 0) + { + if (size != 4) + return E_NOTIMPL; + val = GetUi32(props); + if (val & _alignment) + return E_NOTIMPL; + } + _pc_Init = val; + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BranchMisc.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.h --- p7zip-rar-16.02/CPP/7zip/Compress/BranchMisc.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchMisc.h 2024-01-26 11:00:00.000000000 +0000 @@ -1,35 +1,59 @@ -// BranchMisc.h - -#ifndef __COMPRESS_BRANCH_MISC_H -#define __COMPRESS_BRANCH_MISC_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -EXTERN_C_BEGIN - -typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding); - -EXTERN_C_END - -namespace NCompress { -namespace NBranch { - -class CCoder: - public ICompressFilter, - public CMyUnknownImp -{ - UInt32 _bufferPos; - int _encode; - Func_Bra BraFunc; -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) - - CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} -}; - -}} - -#endif +// BranchMisc.h + +#ifndef ZIP7_INC_COMPRESS_BRANCH_MISC_H +#define ZIP7_INC_COMPRESS_BRANCH_MISC_H +#include "../../../C/Bra.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NBranch { + +Z7_CLASS_IMP_COM_1( + CCoder + , ICompressFilter +) + UInt32 _pc; + z7_Func_BranchConv BraFunc; +public: + CCoder(z7_Func_BranchConv bra): _pc(0), BraFunc(bra) {} +}; + +#ifndef Z7_EXTRACT_ONLY + +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressFilter + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) + UInt32 _pc; + UInt32 _pc_Init; + UInt32 _alignment; + z7_Func_BranchConv BraFunc; +public: + CEncoder(z7_Func_BranchConv bra, UInt32 alignment): + _pc(0), _pc_Init(0), _alignment(alignment), BraFunc(bra) {} +}; + +#endif + +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressFilter + , ICompressSetDecoderProperties2 +) + UInt32 _pc; + UInt32 _pc_Init; + UInt32 _alignment; + z7_Func_BranchConv BraFunc; +public: + CDecoder(z7_Func_BranchConv bra, UInt32 alignment): + _pc(0), _pc_Init(0), _alignment(alignment), BraFunc(bra) {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/BranchRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/BranchRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/BranchRegister.cpp 2024-02-07 17:00:00.000000000 +0000 @@ -1,41 +1,58 @@ -// BranchRegister.cpp - -#include "StdAfx.h" - -#include "../../../C/Bra.h" - -#include "../Common/RegisterCodec.h" - -#include "BranchMisc.h" - -namespace NCompress { -namespace NBranch { - -#define CREATE_BRA(n) \ - REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \ - REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \ - -CREATE_BRA(PPC) -CREATE_BRA(IA64) -CREATE_BRA(ARM) -CREATE_BRA(ARMT) -CREATE_BRA(SPARC) - -#define METHOD_ITEM(n, id, name) \ - REGISTER_FILTER_ITEM( \ - CreateBra_Decoder_ ## n, \ - CreateBra_Encoder_ ## n, \ - 0x3030000 + id, name) - -REGISTER_CODECS_VAR -{ - METHOD_ITEM(PPC, 0x205, "PPC"), - METHOD_ITEM(IA64, 0x401, "IA64"), - METHOD_ITEM(ARM, 0x501, "ARM"), - METHOD_ITEM(ARMT, 0x701, "ARMT"), - METHOD_ITEM(SPARC, 0x805, "SPARC") -}; - -REGISTER_CODECS(Branch) - -}} +// BranchRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "BranchMisc.h" + +namespace NCompress { +namespace NBranch { + +#ifdef Z7_EXTRACT_ONLY +#define GET_CREATE_FUNC(x) NULL +#define CREATE_BRA_E(n) +#else +#define GET_CREATE_FUNC(x) x +#define CREATE_BRA_E(n) \ + REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(Z7_BRANCH_CONV_ENC_2(n))) +#endif + +#define CREATE_BRA(n) \ + REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(Z7_BRANCH_CONV_DEC_2(n))) \ + CREATE_BRA_E(n) + +CREATE_BRA(BranchConv_PPC) +CREATE_BRA(BranchConv_IA64) +CREATE_BRA(BranchConv_ARM) +CREATE_BRA(BranchConv_ARMT) +CREATE_BRA(BranchConv_SPARC) + +#define METHOD_ITEM(n, id, name) \ + REGISTER_FILTER_ITEM( \ + CreateBra_Decoder_ ## n, GET_CREATE_FUNC( \ + CreateBra_Encoder_ ## n), \ + 0x3030000 + id, name) + +REGISTER_CODECS_VAR +{ + METHOD_ITEM(BranchConv_PPC, 0x205, "PPC"), + METHOD_ITEM(BranchConv_IA64, 0x401, "IA64"), + METHOD_ITEM(BranchConv_ARM, 0x501, "ARM"), + METHOD_ITEM(BranchConv_ARMT, 0x701, "ARMT"), + METHOD_ITEM(BranchConv_SPARC, 0x805, "SPARC") +}; + +REGISTER_CODECS(Branch) + + +#define REGISTER_FILTER_E_BRANCH(id, n, name, alignment) \ + REGISTER_FILTER_E(n, \ + CDecoder(Z7_BRANCH_CONV_DEC(n), alignment), \ + CEncoder(Z7_BRANCH_CONV_ENC(n), alignment), \ + id, name) + +REGISTER_FILTER_E_BRANCH(0xa, ARM64, "ARM64", 3) +REGISTER_FILTER_E_BRANCH(0xb, RISCV, "RISCV", 1) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ByteSwap.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ByteSwap.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ByteSwap.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ByteSwap.cpp 2023-03-15 10:00:00.000000000 +0000 @@ -1,92 +1,91 @@ -// ByteSwap.cpp - -#include "StdAfx.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/RegisterCodec.h" - -namespace NCompress { -namespace NByteSwap { - -class CByteSwap2: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; - -class CByteSwap4: - public ICompressFilter, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICompressFilter); - INTERFACE_ICompressFilter(;) -}; - -STDMETHODIMP CByteSwap2::Init() { return S_OK; } - -STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size) -{ - const UInt32 kStep = 2; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do - { - Byte b0 = data[0]; - data[0] = data[1]; - data[1] = b0; - data += kStep; - } - while (data != end); - - return size; -} - -STDMETHODIMP CByteSwap4::Init() { return S_OK; } - -STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size) -{ - const UInt32 kStep = 4; - if (size < kStep) - return 0; - size &= ~(kStep - 1); - - const Byte *end = data + (size_t)size; - - do - { - Byte b0 = data[0]; - Byte b1 = data[1]; - data[0] = data[3]; - data[1] = data[2]; - data[2] = b1; - data[3] = b0; - data += kStep; - } - while (data != end); - - return size; -} - -REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2()) -REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4()) - -REGISTER_CODECS_VAR -{ - REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"), - REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4") -}; - -REGISTER_CODECS(ByteSwap) - -}} +// ByteSwap.cpp + +#include "StdAfx.h" + +#include "../../../C/SwapBytes.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/RegisterCodec.h" + +namespace NCompress { +namespace NByteSwap { + +Z7_CLASS_IMP_COM_1(CByteSwap2, ICompressFilter) }; +Z7_CLASS_IMP_COM_1(CByteSwap4, ICompressFilter) }; + +Z7_COM7F_IMF(CByteSwap2::Init()) { return S_OK; } + +Z7_COM7F_IMF2(UInt32, CByteSwap2::Filter(Byte *data, UInt32 size)) +{ + const UInt32 kMask = 2 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) + { + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + data[0] = data[1]; + data[1] = b0; + data += kStep; + } + while (data != end); + } + else + */ + z7_SwapBytes2((UInt16 *)(void *)data, size >> 1); + return size; +} + + +Z7_COM7F_IMF(CByteSwap4::Init()) { return S_OK; } + +Z7_COM7F_IMF2(UInt32, CByteSwap4::Filter(Byte *data, UInt32 size)) +{ + const UInt32 kMask = 4 - 1; + size &= ~kMask; + /* + if ((unsigned)(ptrdiff_t)data & kMask) + { + if (size == 0) + return 0; + const Byte *end = data + (size_t)size; + do + { + const Byte b0 = data[0]; + const Byte b1 = data[1]; + data[0] = data[3]; + data[1] = data[2]; + data[2] = b1; + data[3] = b0; + data += kStep; + } + while (data != end); + } + else + */ + z7_SwapBytes4((UInt32 *)(void *)data, size >> 2); + return size; +} + +static struct C_SwapBytesPrepare { C_SwapBytesPrepare() { z7_SwapBytesPrepare(); } } g_SwapBytesPrepare; + + +REGISTER_FILTER_CREATE(CreateFilter2, CByteSwap2()) +REGISTER_FILTER_CREATE(CreateFilter4, CByteSwap4()) + +REGISTER_CODECS_VAR +{ + REGISTER_FILTER_ITEM(CreateFilter2, CreateFilter2, 0x20302, "Swap2"), + REGISTER_FILTER_ITEM(CreateFilter4, CreateFilter4, 0x20304, "Swap4"), +}; + +REGISTER_CODECS(ByteSwap) + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Codec.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Codec.def --- p7zip-rar-16.02/CPP/7zip/Compress/Codec.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Codec.def 2023-04-03 11:00:00.000000000 +0000 @@ -0,0 +1,7 @@ +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE + CreateDecoder PRIVATE + CreateEncoder PRIVATE + GetModuleProp PRIVATE diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/CodecExports.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CodecExports.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/CodecExports.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CodecExports.cpp 2023-04-08 11:00:00.000000000 +0000 @@ -1,344 +1,378 @@ -// CodecExports.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../../Common/ComTry.h" -#include "../../Common/MyCom.h" - -#include "../../Windows/Defs.h" - -#include "../ICoder.h" - -#include "../Common/RegisterCodec.h" - -extern unsigned g_NumCodecs; -extern const CCodecInfo *g_Codecs[]; - -extern unsigned g_NumHashers; -extern const CHasherInfo *g_Hashers[]; - -static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() -{ - UINT len = (UINT)strlen(s); - BSTR dest = ::SysAllocStringLen(NULL, len); - if (dest) - { - for (UINT i = 0; i <= len; i++) - dest[i] = (Byte)s[i]; - prop->bstrVal = dest; - prop->vt = VT_BSTR; - } -} - -static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) throw() -{ - if ((value->bstrVal = ::SysAllocStringByteLen((const char *)&guid, sizeof(guid))) != NULL) - value->vt = VT_BSTR; - return S_OK; -} - -static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) throw() -{ - GUID clsId; - clsId.Data1 = k_7zip_GUID_Data1; - clsId.Data2 = k_7zip_GUID_Data2; - clsId.Data3 = typeId; - SetUi64(clsId.Data4, id); - return SetPropGUID(clsId, value); -} - -static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, bool &encode, int &index) throw() -{ - index = -1; - if (clsid->Data1 != k_7zip_GUID_Data1 || - clsid->Data2 != k_7zip_GUID_Data2) - return S_OK; - - encode = true; - - if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false; - else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK; - - UInt64 id = GetUi64(clsid->Data4); - - for (unsigned i = 0; i < g_NumCodecs; i++) - { - const CCodecInfo &codec = *g_Codecs[i]; - - if (id != codec.Id - || (encode ? !codec.CreateEncoder : !codec.CreateDecoder) - || (isFilter ? !codec.IsFilter : codec.IsFilter)) - continue; - - if (codec.NumStreams == 1 ? isCoder2 : !isCoder2) - return E_NOINTERFACE; - - index = i; - return S_OK; - } - - return S_OK; -} - -static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder) -{ - COM_TRY_BEGIN - - const CCodecInfo &codec = *g_Codecs[index]; - - void *c; - if (encode) - c = codec.CreateEncoder(); - else - c = codec.CreateDecoder(); - - if (c) - { - IUnknown *unk; - if (codec.IsFilter) - unk = (IUnknown *)(ICompressFilter *)c; - else if (codec.NumStreams != 1) - unk = (IUnknown *)(ICompressCoder2 *)c; - else - unk = (IUnknown *)(ICompressCoder *)c; - unk->AddRef(); - *coder = c; - } - return S_OK; - - COM_TRY_END -} - -static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) -{ - *outObject = NULL; - - const CCodecInfo &codec = *g_Codecs[index]; - - if (encode ? !codec.CreateEncoder : !codec.CreateDecoder) - return CLASS_E_CLASSNOTAVAILABLE; - - if (codec.IsFilter) - { - if (*iid != IID_ICompressFilter) return E_NOINTERFACE; - } - else if (codec.NumStreams != 1) - { - if (*iid != IID_ICompressCoder2) return E_NOINTERFACE; - } - else - { - if (*iid != IID_ICompressCoder) return E_NOINTERFACE; - } - - return CreateCoderMain(index, encode, outObject); -} - -STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject) -{ - return CreateCoder2(false, index, iid, outObject); -} - -STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject) -{ - return CreateCoder2(true, index, iid, outObject); -} - -STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) -{ - *outObject = NULL; - - bool isFilter = false; - bool isCoder2 = false; - bool isCoder = (*iid == IID_ICompressCoder) != 0; - if (!isCoder) - { - isFilter = (*iid == IID_ICompressFilter) != 0; - if (!isFilter) - { - isCoder2 = (*iid == IID_ICompressCoder2) != 0; - if (!isCoder2) - return E_NOINTERFACE; - } - } - - bool encode; - int codecIndex; - HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); - if (res != S_OK) - return res; - if (codecIndex < 0) - return CLASS_E_CLASSNOTAVAILABLE; - - return CreateCoderMain(codecIndex, encode, outObject); -} - -STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) -{ - ::VariantClear((VARIANTARG *)value); - const CCodecInfo &codec = *g_Codecs[codecIndex]; - switch (propID) - { - case NMethodPropID::kID: - value->uhVal.QuadPart = (UInt64)codec.Id; - value->vt = VT_UI8; - break; - case NMethodPropID::kName: - SetPropFromAscii(codec.Name, value); - break; - case NMethodPropID::kDecoder: - if (codec.CreateDecoder) - return MethodToClassID(k_7zip_GUID_Data3_Decoder, codec.Id, value); - break; - case NMethodPropID::kEncoder: - if (codec.CreateEncoder) - return MethodToClassID(k_7zip_GUID_Data3_Encoder, codec.Id, value); - break; - case NMethodPropID::kDecoderIsAssigned: - value->vt = VT_BOOL; - value->boolVal = BoolToVARIANT_BOOL(codec.CreateDecoder != NULL); - break; - case NMethodPropID::kEncoderIsAssigned: - value->vt = VT_BOOL; - value->boolVal = BoolToVARIANT_BOOL(codec.CreateEncoder != NULL); - break; - case NMethodPropID::kPackStreams: - if (codec.NumStreams != 1) - { - value->vt = VT_UI4; - value->ulVal = (ULONG)codec.NumStreams; - } - break; - /* - case NMethodPropID::kIsFilter: - // if (codec.IsFilter) - { - value->vt = VT_BOOL; - value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter); - } - break; - */ - /* - case NMethodPropID::kDecoderFlags: - { - value->vt = VT_UI4; - value->ulVal = (ULONG)codec.DecoderFlags; - } - break; - case NMethodPropID::kEncoderFlags: - { - value->vt = VT_UI4; - value->ulVal = (ULONG)codec.EncoderFlags; - } - break; - */ - } - return S_OK; -} - -STDAPI GetNumberOfMethods(UINT32 *numCodecs) -{ - *numCodecs = g_NumCodecs; - return S_OK; -} - - -// ---------- Hashers ---------- - -static int FindHasherClassId(const GUID *clsid) throw() -{ - if (clsid->Data1 != k_7zip_GUID_Data1 || - clsid->Data2 != k_7zip_GUID_Data2 || - clsid->Data3 != k_7zip_GUID_Data3_Hasher) - return -1; - UInt64 id = GetUi64(clsid->Data4); - for (unsigned i = 0; i < g_NumCodecs; i++) - if (id == g_Hashers[i]->Id) - return i; - return -1; -} - -static HRESULT CreateHasher2(UInt32 index, IHasher **hasher) -{ - COM_TRY_BEGIN - *hasher = g_Hashers[index]->CreateHasher(); - if (*hasher) - (*hasher)->AddRef(); - return S_OK; - COM_TRY_END -} - -STDAPI CreateHasher(const GUID *clsid, IHasher **outObject) -{ - COM_TRY_BEGIN - *outObject = 0; - int index = FindHasherClassId(clsid); - if (index < 0) - return CLASS_E_CLASSNOTAVAILABLE; - return CreateHasher2(index, outObject); - COM_TRY_END -} - -STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) -{ - ::VariantClear((VARIANTARG *)value); - const CHasherInfo &codec = *g_Hashers[codecIndex]; - switch (propID) - { - case NMethodPropID::kID: - value->uhVal.QuadPart = (UInt64)codec.Id; - value->vt = VT_UI8; - break; - case NMethodPropID::kName: - SetPropFromAscii(codec.Name, value); - break; - case NMethodPropID::kEncoder: - if (codec.CreateHasher) - return MethodToClassID(k_7zip_GUID_Data3_Hasher, codec.Id, value); - break; - case NMethodPropID::kDigestSize: - value->ulVal = (ULONG)codec.DigestSize; - value->vt = VT_UI4; - break; - } - return S_OK; -} - -class CHashers: - public IHashers, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IHashers) - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); -}; - -STDAPI GetHashers(IHashers **hashers) -{ - COM_TRY_BEGIN - *hashers = new CHashers; - if (*hashers) - (*hashers)->AddRef(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP_(UInt32) CHashers::GetNumHashers() -{ - return g_NumHashers; -} - -STDMETHODIMP CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - return ::GetHasherProp(index, propID, value); -} - -STDMETHODIMP CHashers::CreateHasher(UInt32 index, IHasher **hasher) -{ - return ::CreateHasher2(index, hasher); -} +// CodecExports.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/7zVersion.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyCom.h" + +#include "../../Windows/Defs.h" +#include "../../Windows/PropVariant.h" + +#include "../ICoder.h" + +#include "../Common/RegisterCodec.h" + +extern unsigned g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +extern unsigned g_NumHashers; +extern const CHasherInfo *g_Hashers[]; + +static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() +{ + const UINT len = (UINT)strlen(s); + BSTR dest = ::SysAllocStringLen(NULL, len); + if (dest) + { + for (UINT i = 0; i <= len; i++) + dest[i] = (Byte)s[i]; + prop->bstrVal = dest; + prop->vt = VT_BSTR; + } +} + +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) throw() +{ + if ((value->bstrVal = ::SysAllocStringByteLen((const char *)&guid, sizeof(guid))) != NULL) + value->vt = VT_BSTR; + return S_OK; +} + +static HRESULT MethodToClassID(UInt16 typeId, CMethodId id, PROPVARIANT *value) throw() +{ + GUID clsId; + clsId.Data1 = k_7zip_GUID_Data1; + clsId.Data2 = k_7zip_GUID_Data2; + clsId.Data3 = typeId; + SetUi64(clsId.Data4, id) + return SetPropGUID(clsId, value); +} + +static HRESULT FindCodecClassId(const GUID *clsid, bool isCoder2, bool isFilter, bool &encode, int &index) throw() +{ + index = -1; + if (clsid->Data1 != k_7zip_GUID_Data1 || + clsid->Data2 != k_7zip_GUID_Data2) + return S_OK; + + encode = true; + + if (clsid->Data3 == k_7zip_GUID_Data3_Decoder) encode = false; + else if (clsid->Data3 != k_7zip_GUID_Data3_Encoder) return S_OK; + + const UInt64 id = GetUi64(clsid->Data4); + + for (unsigned i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &codec = *g_Codecs[i]; + + if (id != codec.Id + || (encode ? !codec.CreateEncoder : !codec.CreateDecoder) + || (isFilter ? !codec.IsFilter : codec.IsFilter)) + continue; + + if (codec.NumStreams == 1 ? isCoder2 : !isCoder2) + return E_NOINTERFACE; + + index = (int)i; + return S_OK; + } + + return S_OK; +} + +/* +#ifdef __GNUC__ +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wduplicated-branches" +#endif +#endif +*/ + +static HRESULT CreateCoderMain(unsigned index, bool encode, void **coder) +{ + COM_TRY_BEGIN + + const CCodecInfo &codec = *g_Codecs[index]; + + void *c; + if (encode) + c = codec.CreateEncoder(); + else + c = codec.CreateDecoder(); + + if (c) + { + IUnknown *unk; + unk = (IUnknown *)c; + /* + if (codec.IsFilter) + unk = (IUnknown *)(ICompressFilter *)c; + else if (codec.NumStreams != 1) + unk = (IUnknown *)(ICompressCoder2 *)c; + else + unk = (IUnknown *)(ICompressCoder *)c; + */ + unk->AddRef(); + *coder = c; + } + return S_OK; + + COM_TRY_END +} + +static HRESULT CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) +{ + *outObject = NULL; + + const CCodecInfo &codec = *g_Codecs[index]; + + if (encode ? !codec.CreateEncoder : !codec.CreateDecoder) + return CLASS_E_CLASSNOTAVAILABLE; + + if (codec.IsFilter) + { + if (*iid != IID_ICompressFilter) return E_NOINTERFACE; + } + else if (codec.NumStreams != 1) + { + if (*iid != IID_ICompressCoder2) return E_NOINTERFACE; + } + else + { + if (*iid != IID_ICompressCoder) return E_NOINTERFACE; + } + + return CreateCoderMain(index, encode, outObject); +} + + +STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject); +STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject) +{ + return CreateCoder2(false, index, iid, outObject); +} + + +STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject); +STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject) +{ + return CreateCoder2(true, index, iid, outObject); +} + + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) +{ + *outObject = NULL; + + bool isFilter = false; + bool isCoder2 = false; + const bool isCoder = (*iid == IID_ICompressCoder) != 0; + if (!isCoder) + { + isFilter = (*iid == IID_ICompressFilter) != 0; + if (!isFilter) + { + isCoder2 = (*iid == IID_ICompressCoder2) != 0; + if (!isCoder2) + return E_NOINTERFACE; + } + } + + bool encode; + int codecIndex; + const HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); + if (res != S_OK) + return res; + if (codecIndex < 0) + return CLASS_E_CLASSNOTAVAILABLE; + + return CreateCoderMain((unsigned)codecIndex, encode, outObject); +} + + +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + const CCodecInfo &codec = *g_Codecs[codecIndex]; + switch (propID) + { + case NMethodPropID::kID: + value->uhVal.QuadPart = (UInt64)codec.Id; + value->vt = VT_UI8; + break; + case NMethodPropID::kName: + SetPropFromAscii(codec.Name, value); + break; + case NMethodPropID::kDecoder: + if (codec.CreateDecoder) + return MethodToClassID(k_7zip_GUID_Data3_Decoder, codec.Id, value); + break; + case NMethodPropID::kEncoder: + if (codec.CreateEncoder) + return MethodToClassID(k_7zip_GUID_Data3_Encoder, codec.Id, value); + break; + case NMethodPropID::kDecoderIsAssigned: + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.CreateDecoder != NULL); + break; + case NMethodPropID::kEncoderIsAssigned: + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.CreateEncoder != NULL); + break; + case NMethodPropID::kPackStreams: + if (codec.NumStreams != 1) + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.NumStreams; + } + break; + case NMethodPropID::kIsFilter: + { + value->vt = VT_BOOL; + value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter); + } + break; + /* + case NMethodPropID::kDecoderFlags: + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.DecoderFlags; + } + break; + case NMethodPropID::kEncoderFlags: + { + value->vt = VT_UI4; + value->ulVal = (ULONG)codec.EncoderFlags; + } + break; + */ + } + return S_OK; +} + + +STDAPI GetNumberOfMethods(UInt32 *numCodecs); +STDAPI GetNumberOfMethods(UInt32 *numCodecs) +{ + *numCodecs = g_NumCodecs; + return S_OK; +} + + +// ---------- Hashers ---------- + +static int FindHasherClassId(const GUID *clsid) throw() +{ + if (clsid->Data1 != k_7zip_GUID_Data1 || + clsid->Data2 != k_7zip_GUID_Data2 || + clsid->Data3 != k_7zip_GUID_Data3_Hasher) + return -1; + const UInt64 id = GetUi64(clsid->Data4); + for (unsigned i = 0; i < g_NumCodecs; i++) + if (id == g_Hashers[i]->Id) + return (int)i; + return -1; +} + +static HRESULT CreateHasher2(UInt32 index, IHasher **hasher) +{ + COM_TRY_BEGIN + *hasher = g_Hashers[index]->CreateHasher(); + if (*hasher) + (*hasher)->AddRef(); + return S_OK; + COM_TRY_END +} + +STDAPI CreateHasher(const GUID *clsid, IHasher **outObject); +STDAPI CreateHasher(const GUID *clsid, IHasher **outObject) +{ + COM_TRY_BEGIN + *outObject = NULL; + const int index = FindHasherClassId(clsid); + if (index < 0) + return CLASS_E_CLASSNOTAVAILABLE; + return CreateHasher2((UInt32)(unsigned)index, outObject); + COM_TRY_END +} + +STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); +STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + const CHasherInfo &codec = *g_Hashers[codecIndex]; + switch (propID) + { + case NMethodPropID::kID: + value->uhVal.QuadPart = (UInt64)codec.Id; + value->vt = VT_UI8; + break; + case NMethodPropID::kName: + SetPropFromAscii(codec.Name, value); + break; + case NMethodPropID::kEncoder: + if (codec.CreateHasher) + return MethodToClassID(k_7zip_GUID_Data3_Hasher, codec.Id, value); + break; + case NMethodPropID::kDigestSize: + value->ulVal = (ULONG)codec.DigestSize; + value->vt = VT_UI4; + break; + } + return S_OK; +} + +Z7_CLASS_IMP_COM_1(CHashers, IHashers) }; + +STDAPI GetHashers(IHashers **hashers); +STDAPI GetHashers(IHashers **hashers) +{ + COM_TRY_BEGIN + *hashers = new CHashers; + if (*hashers) + (*hashers)->AddRef(); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF2(UInt32, CHashers::GetNumHashers()) +{ + return g_NumHashers; +} + +Z7_COM7F_IMF(CHashers::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + return ::GetHasherProp(index, propID, value); +} + +Z7_COM7F_IMF(CHashers::CreateHasher(UInt32 index, IHasher **hasher)) +{ + return ::CreateHasher2(index, hasher); +} + + +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value); +STDAPI GetModuleProp(PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((VARIANTARG *)value); + switch (propID) + { + case NModulePropID::kInterfaceType: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule); + break; + } + case NModulePropID::kVersion: + { + NWindows::NCOM::PropVarEm_Set_UInt32(value, (MY_VER_MAJOR << 16) | MY_VER_MINOR); + break; + } + } + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/CopyCoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/CopyCoder.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.cpp 2023-02-01 10:00:00.000000000 +0000 @@ -1,115 +1,153 @@ -// Compress/CopyCoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "CopyCoder.h" - -namespace NCompress { - -static const UInt32 kBufSize = 1 << 17; - -CCopyCoder::~CCopyCoder() -{ - ::MidFree(_buf); -} - -STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (!_buf) - { - _buf = (Byte *)::MidAlloc(kBufSize); - if (!_buf) - return E_OUTOFMEMORY; - } - - TotalSize = 0; - - for (;;) - { - UInt32 size = kBufSize; - if (outSize && size > *outSize - TotalSize) - size = (UInt32)(*outSize - TotalSize); - if (size == 0) - return S_OK; - - HRESULT readRes = inStream->Read(_buf, size, &size); - - if (size == 0) - return readRes; - - if (outStream) - { - UInt32 pos = 0; - do - { - UInt32 curSize = size - pos; - HRESULT res = outStream->Write(_buf + pos, curSize, &curSize); - pos += curSize; - TotalSize += curSize; - RINOK(res); - if (curSize == 0) - return E_FAIL; - } - while (pos < size); - } - else - TotalSize += size; - - RINOK(readRes); - - if (progress) - { - RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)); - } - } -} - -STDMETHODIMP CCopyCoder::SetInStream(ISequentialInStream *inStream) -{ - _inStream = inStream; - TotalSize = 0; - return S_OK; -} - -STDMETHODIMP CCopyCoder::ReleaseInStream() -{ - _inStream.Release(); - return S_OK; -} - -STDMETHODIMP CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize = 0; - HRESULT res = _inStream->Read(data, size, &realProcessedSize); - TotalSize += realProcessedSize; - if (processedSize) - *processedSize = realProcessedSize; - return res; -} - -STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value) -{ - *value = TotalSize; - return S_OK; -} - -HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - CMyComPtr copyCoder = new CCopyCoder; - return copyCoder->Code(inStream, outStream, NULL, NULL, progress); -} - -HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress) -{ - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr copyCoder = copyCoderSpec; - RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)); - return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; -} - -} +// Compress/CopyCoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "CopyCoder.h" + +namespace NCompress { + +static const UInt32 kBufSize = 1 << 17; + +CCopyCoder::~CCopyCoder() +{ + ::MidFree(_buf); +} + +Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, + ICompressProgressInfo *progress)) +{ + if (!_buf) + { + _buf = (Byte *)::MidAlloc(kBufSize); + if (!_buf) + return E_OUTOFMEMORY; + } + + TotalSize = 0; + + for (;;) + { + UInt32 size = kBufSize; + if (outSize) + { + const UInt64 rem = *outSize - TotalSize; + if (size > rem) + { + size = (UInt32)rem; + if (size == 0) + { + /* if we enable the following check, + we will make one call of Read(_buf, 0) for empty stream */ + // if (TotalSize != 0) + return S_OK; + } + } + } + + HRESULT readRes; + { + UInt32 pos = 0; + do + { + const UInt32 curSize = size - pos; + UInt32 processed = 0; + readRes = inStream->Read(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + if (readRes != S_OK || processed == 0) + break; + } + while (pos < kBufSize); + size = pos; + } + + if (size == 0) + return readRes; + + if (outStream) + { + UInt32 pos = 0; + do + { + const UInt32 curSize = size - pos; + UInt32 processed = 0; + const HRESULT res = outStream->Write(_buf + pos, curSize, &processed); + if (processed > curSize) + return E_FAIL; // internal code failure + pos += processed; + TotalSize += processed; + RINOK(res) + if (processed == 0) + return E_FAIL; + } + while (pos < size); + } + else + TotalSize += size; + + RINOK(readRes) + + if (size != kBufSize) + return S_OK; + + if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0) + { + RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize)) + } + } +} + +Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream)) +{ + _inStream = inStream; + TotalSize = 0; + return S_OK; +} + +Z7_COM7F_IMF(CCopyCoder::ReleaseInStream()) +{ + _inStream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + UInt32 realProcessedSize = 0; + HRESULT res = _inStream->Read(data, size, &realProcessedSize); + TotalSize += realProcessedSize; + if (processedSize) + *processedSize = realProcessedSize; + return res; +} + +Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = TotalSize; + return S_OK; +} + +HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) +{ + CMyComPtr copyCoder = new CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, progress); +} + +HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress) +{ + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; + CMyComPtr copyCoder = copyCoderSpec; + RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress)) + return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/CopyCoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/CopyCoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyCoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,46 +1,34 @@ -// Compress/CopyCoder.h - -#ifndef __COMPRESS_COPY_CODER_H -#define __COMPRESS_COPY_CODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { - -class CCopyCoder: - public ICompressCoder, - public ICompressSetInStream, - public ISequentialInStream, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp -{ - Byte *_buf; - CMyComPtr _inStream; -public: - UInt64 TotalSize; - - CCopyCoder(): _buf(0), TotalSize(0) {}; - ~CCopyCoder(); - - MY_UNKNOWN_IMP4( - ICompressCoder, - ICompressSetInStream, - ISequentialInStream, - ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); -}; - -HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); -HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress); - -} - -#endif +// Compress/CopyCoder.h + +#ifndef ZIP7_INC_COMPRESS_COPY_CODER_H +#define ZIP7_INC_COMPRESS_COPY_CODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { + +Z7_CLASS_IMP_COM_5( + CCopyCoder + , ICompressCoder + , ICompressSetInStream + , ISequentialInStream + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + Byte *_buf; + CMyComPtr _inStream; +public: + UInt64 TotalSize; + + CCopyCoder(): _buf(NULL), TotalSize(0) {} + ~CCopyCoder(); +}; + +HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); +HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/CopyRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/CopyRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/CopyRegister.cpp 2016-04-25 10:04:47.000000000 +0000 @@ -1,15 +1,15 @@ -// CopyRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "CopyCoder.h" - -namespace NCompress { - -REGISTER_CODEC_CREATE(CreateCodec, CCopyCoder()) - -REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy") - -} +// CopyRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "CopyCoder.h" + +namespace NCompress { + +REGISTER_CODEC_CREATE(CreateCodec, CCopyCoder()) + +REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy") + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Deflate64Register.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Deflate64Register.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Deflate64Register.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Deflate64Register.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -1,26 +1,25 @@ -// Deflate64Register.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "DeflateDecoder.h" - -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) -#include "DeflateEncoder.h" -#endif - -namespace NCompress { -namespace NDeflate { - -REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder64()) - -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) -REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder64()) -#else -#define CreateEnc NULL -#endif - -REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64") - -}} +// Deflate64Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "DeflateDecoder.h" +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) +#include "DeflateEncoder.h" +#endif + +namespace NCompress { +namespace NDeflate { + +REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder64()) + +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) +REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder64()) +#else +#define CreateEnc NULL +#endif + +REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateConst.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateConst.h --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateConst.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateConst.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,131 +1,131 @@ -// DeflateConst.h - -#ifndef __DEFLATE_CONST_H -#define __DEFLATE_CONST_H - -namespace NCompress { -namespace NDeflate { - -const unsigned kNumHuffmanBits = 15; - -const UInt32 kHistorySize32 = (1 << 15); -const UInt32 kHistorySize64 = (1 << 16); - -const unsigned kDistTableSize32 = 30; -const unsigned kDistTableSize64 = 32; - -const unsigned kNumLenSymbols32 = 256; -const unsigned kNumLenSymbols64 = 255; // don't change it. It must be <= 255. -const unsigned kNumLenSymbolsMax = kNumLenSymbols32; - -const unsigned kNumLenSlots = 29; - -const unsigned kFixedDistTableSize = 32; -const unsigned kFixedLenTableSize = 31; - -const unsigned kSymbolEndOfBlock = 0x100; -const unsigned kSymbolMatch = kSymbolEndOfBlock + 1; - -const unsigned kMainTableSize = kSymbolMatch + kNumLenSlots; -const unsigned kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; - -const unsigned kLevelTableSize = 19; - -const unsigned kTableDirectLevels = 16; -const unsigned kTableLevelRepNumber = kTableDirectLevels; -const unsigned kTableLevel0Number = kTableLevelRepNumber + 1; -const unsigned kTableLevel0Number2 = kTableLevel0Number + 1; - -const unsigned kLevelMask = 0xF; - -const Byte kLenStart32[kFixedLenTableSize] = - {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255, 0, 0}; -const Byte kLenStart64[kFixedLenTableSize] = - {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0, 0, 0}; - -const Byte kLenDirectBits32[kFixedLenTableSize] = - {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0}; -const Byte kLenDirectBits64[kFixedLenTableSize] = - {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0}; - -const UInt32 kDistStart[kDistTableSize64] = - {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768, - 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152}; -const Byte kDistDirectBits[kDistTableSize64] = - {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14}; - -const Byte kLevelDirectBits[3] = {2, 3, 7}; - -const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -const unsigned kMatchMinLen = 3; -const unsigned kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; // 256 + 2 -const unsigned kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; // 255 + 2 -const unsigned kMatchMaxLen = kMatchMaxLen32; - -const unsigned kFinalBlockFieldSize = 1; - -namespace NFinalBlockField -{ - enum - { - kNotFinalBlock = 0, - kFinalBlock = 1 - }; -} - -const unsigned kBlockTypeFieldSize = 2; - -namespace NBlockType -{ - enum - { - kStored = 0, - kFixedHuffman = 1, - kDynamicHuffman = 2 - }; -} - -const unsigned kNumLenCodesFieldSize = 5; -const unsigned kNumDistCodesFieldSize = 5; -const unsigned kNumLevelCodesFieldSize = 4; - -const unsigned kNumLitLenCodesMin = 257; -const unsigned kNumDistCodesMin = 1; -const unsigned kNumLevelCodesMin = 4; - -const unsigned kLevelFieldSize = 3; - -const unsigned kStoredBlockLengthFieldSize = 16; - -struct CLevels -{ - Byte litLenLevels[kFixedMainTableSize]; - Byte distLevels[kFixedDistTableSize]; - - void SubClear() - { - unsigned i; - for (i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) - litLenLevels[i] = 0; - for (i = 0; i < kFixedDistTableSize; i++) - distLevels[i] = 0; - } - - void SetFixedLevels() - { - unsigned i = 0; - - for (; i < 144; i++) litLenLevels[i] = 8; - for (; i < 256; i++) litLenLevels[i] = 9; - for (; i < 280; i++) litLenLevels[i] = 7; - for (; i < 288; i++) litLenLevels[i] = 8; - - for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize - distLevels[i] = 5; - } -}; - -}} - -#endif +// DeflateConst.h + +#ifndef ZIP7_INC_DEFLATE_CONST_H +#define ZIP7_INC_DEFLATE_CONST_H + +namespace NCompress { +namespace NDeflate { + +const unsigned kNumHuffmanBits = 15; + +const UInt32 kHistorySize32 = (1 << 15); +const UInt32 kHistorySize64 = (1 << 16); + +const unsigned kDistTableSize32 = 30; +const unsigned kDistTableSize64 = 32; + +const unsigned kNumLenSymbols32 = 256; +const unsigned kNumLenSymbols64 = 255; // don't change it. It must be <= 255. +const unsigned kNumLenSymbolsMax = kNumLenSymbols32; + +const unsigned kNumLenSlots = 29; + +const unsigned kFixedDistTableSize = 32; +const unsigned kFixedLenTableSize = 31; + +const unsigned kSymbolEndOfBlock = 0x100; +const unsigned kSymbolMatch = kSymbolEndOfBlock + 1; + +const unsigned kMainTableSize = kSymbolMatch + kNumLenSlots; +const unsigned kFixedMainTableSize = kSymbolMatch + kFixedLenTableSize; + +const unsigned kLevelTableSize = 19; + +const unsigned kTableDirectLevels = 16; +const unsigned kTableLevelRepNumber = kTableDirectLevels; +const unsigned kTableLevel0Number = kTableLevelRepNumber + 1; +const unsigned kTableLevel0Number2 = kTableLevel0Number + 1; + +const unsigned kLevelMask = 0xF; + +const Byte kLenStart32[kFixedLenTableSize] = + {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255, 0, 0}; +const Byte kLenStart64[kFixedLenTableSize] = + {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0, 0, 0}; + +const Byte kLenDirectBits32[kFixedLenTableSize] = + {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0}; +const Byte kLenDirectBits64[kFixedLenTableSize] = + {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, 0, 0}; + +const UInt32 kDistStart[kDistTableSize64] = + {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768, + 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152}; +const Byte kDistDirectBits[kDistTableSize64] = + {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14}; + +const Byte kLevelDirectBits[3] = {2, 3, 7}; + +const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +const unsigned kMatchMinLen = 3; +const unsigned kMatchMaxLen32 = kNumLenSymbols32 + kMatchMinLen - 1; // 256 + 2 +const unsigned kMatchMaxLen64 = kNumLenSymbols64 + kMatchMinLen - 1; // 255 + 2 +const unsigned kMatchMaxLen = kMatchMaxLen32; + +const unsigned kFinalBlockFieldSize = 1; + +namespace NFinalBlockField +{ + enum + { + kNotFinalBlock = 0, + kFinalBlock = 1 + }; +} + +const unsigned kBlockTypeFieldSize = 2; + +namespace NBlockType +{ + enum + { + kStored = 0, + kFixedHuffman = 1, + kDynamicHuffman = 2 + }; +} + +const unsigned kNumLenCodesFieldSize = 5; +const unsigned kNumDistCodesFieldSize = 5; +const unsigned kNumLevelCodesFieldSize = 4; + +const unsigned kNumLitLenCodesMin = 257; +const unsigned kNumDistCodesMin = 1; +const unsigned kNumLevelCodesMin = 4; + +const unsigned kLevelFieldSize = 3; + +const unsigned kStoredBlockLengthFieldSize = 16; + +struct CLevels +{ + Byte litLenLevels[kFixedMainTableSize]; + Byte distLevels[kFixedDistTableSize]; + + void SubClear() + { + unsigned i; + for (i = kNumLitLenCodesMin; i < kFixedMainTableSize; i++) + litLenLevels[i] = 0; + for (i = 0; i < kFixedDistTableSize; i++) + distLevels[i] = 0; + } + + void SetFixedLevels() + { + unsigned i = 0; + + for (; i < 144; i++) litLenLevels[i] = 8; + for (; i < 256; i++) litLenLevels[i] = 9; + for (; i < 280; i++) litLenLevels[i] = 7; + for (; i < 288; i++) litLenLevels[i] = 8; + + for (i = 0; i < kFixedDistTableSize; i++) // test it: InfoZip only uses kDistTableSize + distLevels[i] = 5; + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateDecoder.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.cpp 2025-03-04 12:00:00.000000000 +0000 @@ -1,417 +1,566 @@ -// DeflateDecoder.cpp - -#include "StdAfx.h" - -#include "DeflateDecoder.h" - -namespace NCompress { -namespace NDeflate { -namespace NDecoder { - -CCoder::CCoder(bool deflate64Mode, bool deflateNSIS): - _deflate64Mode(deflate64Mode), - _deflateNSIS(deflateNSIS), - _keepHistory(false), - _needFinishInput(false), - _needInitInStream(true), - ZlibMode(false) {} - -UInt32 CCoder::ReadBits(unsigned numBits) -{ - return m_InBitStream.ReadBits(numBits); -} - -Byte CCoder::ReadAlignedByte() -{ - return m_InBitStream.ReadAlignedByte(); -} - -bool CCoder::DecodeLevels(Byte *levels, unsigned numSymbols) -{ - unsigned i = 0; - - do - { - UInt32 sym = m_LevelDecoder.Decode(&m_InBitStream); - if (sym < kTableDirectLevels) - levels[i++] = (Byte)sym; - else - { - if (sym >= kLevelTableSize) - return false; - - unsigned num; - unsigned numBits; - Byte symbol; - - if (sym == kTableLevelRepNumber) - { - if (i == 0) - return false; - numBits = 2; - num = 0; - symbol = levels[i - 1]; - } - else - { - sym -= kTableLevel0Number; - sym <<= 2; - numBits = 3 + (unsigned)sym; - num = ((unsigned)sym << 1); - symbol = 0; - } - - num += i + 3 + ReadBits(numBits); - if (num > numSymbols) - return false; - do - levels[i++] = symbol; - while (i < num); - } - } - while (i < numSymbols); - - return true; -} - -#define RIF(x) { if (!(x)) return false; } - -bool CCoder::ReadTables(void) -{ - m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); - if (m_InBitStream.ExtraBitsWereRead()) - return false; - UInt32 blockType = ReadBits(kBlockTypeFieldSize); - if (blockType > NBlockType::kDynamicHuffman) - return false; - if (m_InBitStream.ExtraBitsWereRead()) - return false; - - if (blockType == NBlockType::kStored) - { - m_StoredMode = true; - m_InBitStream.AlignToByte(); - m_StoredBlockSize = ReadAligned_UInt16(); // ReadBits(kStoredBlockLengthFieldSize) - if (_deflateNSIS) - return true; - return (m_StoredBlockSize == (UInt16)~ReadAligned_UInt16()); - } - - m_StoredMode = false; - - CLevels levels; - if (blockType == NBlockType::kFixedHuffman) - { - levels.SetFixedLevels(); - _numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32; - } - else - { - unsigned numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; - _numDistLevels = ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; - unsigned numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; - - if (!_deflate64Mode) - if (_numDistLevels > kDistTableSize32) - return false; - - Byte levelLevels[kLevelTableSize]; - for (unsigned i = 0; i < kLevelTableSize; i++) - { - unsigned position = kCodeLengthAlphabetOrder[i]; - if (i < numLevelCodes) - levelLevels[position] = (Byte)ReadBits(kLevelFieldSize); - else - levelLevels[position] = 0; - } - - if (m_InBitStream.ExtraBitsWereRead()) - return false; - - RIF(m_LevelDecoder.Build(levelLevels)); - - Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; - if (!DecodeLevels(tmpLevels, numLitLenLevels + _numDistLevels)) - return false; - - if (m_InBitStream.ExtraBitsWereRead()) - return false; - - levels.SubClear(); - memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); - memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels); - } - RIF(m_MainDecoder.Build(levels.litLenLevels)); - return m_DistDecoder.Build(levels.distLevels); -} - -HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream) -{ - if (_remainLen == kLenIdFinished) - return S_OK; - if (_remainLen == kLenIdNeedInit) - { - if (!_keepHistory) - if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) - return E_OUTOFMEMORY; - RINOK(InitInStream(_needInitInStream)); - m_OutWindowStream.Init(_keepHistory); - m_FinalBlock = false; - _remainLen = 0; - _needReadTable = true; - } - - while (_remainLen > 0 && curSize > 0) - { - _remainLen--; - Byte b = m_OutWindowStream.GetByte(_rep0); - m_OutWindowStream.PutByte(b); - curSize--; - } - - while (curSize > 0 || finishInputStream) - { - if (m_InBitStream.ExtraBitsWereRead()) - return S_FALSE; - - if (_needReadTable) - { - if (m_FinalBlock) - { - _remainLen = kLenIdFinished; - break; - } - if (!ReadTables()) - return S_FALSE; - if (m_InBitStream.ExtraBitsWereRead()) - return S_FALSE; - _needReadTable = false; - } - - if (m_StoredMode) - { - if (finishInputStream && curSize == 0 && m_StoredBlockSize != 0) - return S_FALSE; - /* NSIS version contains some bits in bitl bits buffer. - So we must read some first bytes via ReadAlignedByte */ - for (; m_StoredBlockSize > 0 && curSize > 0 && m_InBitStream.ThereAreDataInBitsBuffer(); m_StoredBlockSize--, curSize--) - m_OutWindowStream.PutByte(ReadAlignedByte()); - for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) - m_OutWindowStream.PutByte(m_InBitStream.ReadDirectByte()); - _needReadTable = (m_StoredBlockSize == 0); - continue; - } - - while (curSize > 0) - { - if (m_InBitStream.ExtraBitsWereRead_Fast()) - return S_FALSE; - - UInt32 sym = m_MainDecoder.Decode(&m_InBitStream); - - if (sym < 0x100) - { - m_OutWindowStream.PutByte((Byte)sym); - curSize--; - continue; - } - else if (sym == kSymbolEndOfBlock) - { - _needReadTable = true; - break; - } - else if (sym < kMainTableSize) - { - sym -= kSymbolMatch; - UInt32 len; - { - unsigned numBits; - if (_deflate64Mode) - { - len = kLenStart64[sym]; - numBits = kLenDirectBits64[sym]; - } - else - { - len = kLenStart32[sym]; - numBits = kLenDirectBits32[sym]; - } - len += kMatchMinLen + m_InBitStream.ReadBits(numBits); - } - UInt32 locLen = len; - if (locLen > curSize) - locLen = (UInt32)curSize; - sym = m_DistDecoder.Decode(&m_InBitStream); - if (sym >= _numDistLevels) - return S_FALSE; - UInt32 distance = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); - if (!m_OutWindowStream.CopyBlock(distance, locLen)) - return S_FALSE; - curSize -= locLen; - len -= locLen; - if (len != 0) - { - _remainLen = (Int32)len; - _rep0 = distance; - break; - } - } - else - return S_FALSE; - } - - if (finishInputStream && curSize == 0) - { - if (m_MainDecoder.Decode(&m_InBitStream) != kSymbolEndOfBlock) - return S_FALSE; - _needReadTable = true; - } - } - - if (m_InBitStream.ExtraBitsWereRead()) - return S_FALSE; - - return S_OK; -} - - -#ifdef _NO_EXCEPTIONS - -#define DEFLATE_TRY_BEGIN -#define DEFLATE_TRY_END(res) - -#else - -#define DEFLATE_TRY_BEGIN try { -#define DEFLATE_TRY_END(res) } \ - catch(const CInBufferException &e) { res = e.ErrorCode; } \ - catch(const CLzOutWindowException &e) { res = e.ErrorCode; } \ - catch(...) { res = S_FALSE; } - -#endif - - -HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, - const UInt64 *outSize, ICompressProgressInfo *progress) -{ - HRESULT res; - DEFLATE_TRY_BEGIN - m_OutWindowStream.SetStream(outStream); - CCoderReleaser flusher(this); - - const UInt64 inStart = _needInitInStream ? 0 : m_InBitStream.GetProcessedSize(); - const UInt64 start = m_OutWindowStream.GetProcessedSize(); - - for (;;) - { - UInt32 curSize = 1 << 18; - bool finishInputStream = false; - if (outSize) - { - const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start); - if (curSize >= rem) - { - curSize = (UInt32)rem; - if (ZlibMode || _needFinishInput) - finishInputStream = true; - } - } - if (!finishInputStream && curSize == 0) - break; - RINOK(CodeSpec(curSize, finishInputStream)); - if (_remainLen == kLenIdFinished) - break; - if (progress) - { - const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart; - const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; - RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); - } - } - - if (_remainLen == kLenIdFinished && ZlibMode) - { - m_InBitStream.AlignToByte(); - for (unsigned i = 0; i < 4; i++) - ZlibFooter[i] = ReadAlignedByte(); - } - - flusher.NeedFlush = false; - res = Flush(); - if (res == S_OK && _remainLen != kLenIdNeedInit && InputEofError()) - return S_FALSE; - DEFLATE_TRY_END(res) - return res; -} - -HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - SetInStream(inStream); - SetOutStreamSize(outSize); - HRESULT res = CodeReal(outStream, outSize, progress); - ReleaseInStream(); - return res; -} - -STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) -{ - if (!value) - return E_INVALIDARG; - *value = m_InBitStream.GetProcessedSize(); - return S_OK; -} - -STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) -{ - m_InStreamRef = inStream; - m_InBitStream.SetStream(inStream); - return S_OK; -} - -STDMETHODIMP CCoder::ReleaseInStream() -{ - m_InStreamRef.Release(); - return S_OK; -} - -STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */) -{ - _remainLen = kLenIdNeedInit; - _needInitInStream = true; - m_OutWindowStream.Init(_keepHistory); - return S_OK; -} - -#ifndef NO_READ_FROM_CODER - -STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT res; - DEFLATE_TRY_BEGIN - if (processedSize) - *processedSize = 0; - const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - m_OutWindowStream.SetMemStream((Byte *)data); - res = CodeSpec(size, false); - if (res == S_OK) - { - res = Flush(); - if (processedSize) - *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); - } - DEFLATE_TRY_END(res) - m_OutWindowStream.SetMemStream(NULL); - return res; -} - -#endif - -STDMETHODIMP CCoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - _remainLen = kLenIdNeedInit; - m_OutWindowStream.Init(_keepHistory); - return CodeReal(outStream, outSize, progress); -} - -}}} +// DeflateDecoder.cpp + +#include "StdAfx.h" + +#include "DeflateDecoder.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +CCoder::CCoder(bool deflate64Mode): + _deflateNSIS(false), + _deflate64Mode(deflate64Mode), + _keepHistory(false), + _needFinishInput(false), + _needInitInStream(true), + _outSizeDefined(false), + _outStartPos(0) + {} + +UInt32 CCoder::ReadBits(unsigned numBits) +{ + return m_InBitStream.ReadBits(numBits); +} + +Byte CCoder::ReadAlignedByte() +{ + return m_InBitStream.ReadAlignedByte(); +} + +bool CCoder::DecodeLevels(Byte *levels, unsigned numSymbols) +{ + unsigned i = 0; + + do + { + unsigned sym = m_LevelDecoder.Decode(&m_InBitStream); + if (sym < kTableDirectLevels) + levels[i++] = (Byte)sym; + else + { + if (sym >= kLevelTableSize) + return false; + + unsigned num; + unsigned numBits; + Byte symbol; + + if (sym == kTableLevelRepNumber) + { + if (i == 0) + return false; + numBits = 2; + num = 0; + symbol = levels[(size_t)i - 1]; + } + else + { + sym -= kTableLevel0Number; + sym <<= 2; + numBits = 3 + (unsigned)sym; + num = ((unsigned)sym << 1); + symbol = 0; + } + + num += i + 3 + ReadBits(numBits); + if (num > numSymbols) + return false; + do + levels[i++] = symbol; + while (i < num); + } + } + while (i < numSymbols); + + return true; +} + +#define RIF(x) { if (!(x)) return false; } + +bool CCoder::ReadTables(void) +{ + m_FinalBlock = (ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); + if (m_InBitStream.ExtraBitsWereRead()) + return false; + const UInt32 blockType = ReadBits(kBlockTypeFieldSize); + if (blockType > NBlockType::kDynamicHuffman) + return false; + if (m_InBitStream.ExtraBitsWereRead()) + return false; + + if (blockType == NBlockType::kStored) + { + m_StoredMode = true; + m_InBitStream.AlignToByte(); + m_StoredBlockSize = ReadAligned_UInt16(); // ReadBits(kStoredBlockLengthFieldSize) + if (_deflateNSIS) + return true; + return (m_StoredBlockSize == (UInt16)~ReadAligned_UInt16()); + } + + m_StoredMode = false; + + CLevels levels; + if (blockType == NBlockType::kFixedHuffman) + { + levels.SetFixedLevels(); + _numDistLevels = _deflate64Mode ? kDistTableSize64 : kDistTableSize32; + } + else + { + const unsigned numLitLenLevels = ReadBits(kNumLenCodesFieldSize) + kNumLitLenCodesMin; + _numDistLevels = (unsigned)ReadBits(kNumDistCodesFieldSize) + kNumDistCodesMin; + const unsigned numLevelCodes = ReadBits(kNumLevelCodesFieldSize) + kNumLevelCodesMin; + + if (!_deflate64Mode) + if (_numDistLevels > kDistTableSize32) + return false; + + const unsigned kLevelTableSize_aligned4 = kLevelTableSize + 1; + Byte levelLevels[kLevelTableSize_aligned4]; + memset (levelLevels, 0, sizeof(levelLevels)); + unsigned i = 0; + do + levelLevels[kCodeLengthAlphabetOrder[i++]] = (Byte)ReadBits(kLevelFieldSize); + while (i != numLevelCodes); + + if (m_InBitStream.ExtraBitsWereRead()) + return false; + + RIF(m_LevelDecoder.Build(levelLevels, false)) // full + + Byte tmpLevels[kFixedMainTableSize + kFixedDistTableSize]; + if (!DecodeLevels(tmpLevels, numLitLenLevels + _numDistLevels)) + return false; + + if (m_InBitStream.ExtraBitsWereRead()) + return false; + + levels.SubClear(); + memcpy(levels.litLenLevels, tmpLevels, numLitLenLevels); + memcpy(levels.distLevels, tmpLevels + numLitLenLevels, _numDistLevels); + } + RIF(m_MainDecoder.Build(levels.litLenLevels)) + return m_DistDecoder.Build(levels.distLevels); +} + + +HRESULT CCoder::InitInStream(bool needInit) +{ + if (needInit) + { + // for HDD-Windows: + // (1 << 15) - best for reading only prefetch + // (1 << 22) - best for real reading / writing + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + m_InBitStream.Init(); + _needInitInStream = false; + } + return S_OK; +} + + +HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit) +{ + if (_remainLen == kLenIdFinished) + return S_OK; + + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) + return E_OUTOFMEMORY; + RINOK(InitInStream(_needInitInStream)) + m_OutWindowStream.Init(_keepHistory); + + m_FinalBlock = false; + _remainLen = 0; + _needReadTable = true; + } + + // _remainLen >= 0 + while (_remainLen && curSize) + { + _remainLen--; + const Byte b = m_OutWindowStream.GetByte(_rep0); + m_OutWindowStream.PutByte(b); + curSize--; + } + + UInt64 inputStart = 0; + if (inputProgressLimit != 0) + inputStart = m_InBitStream.GetProcessedSize(); + + while (curSize || finishInputStream) + { + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; + + if (_needReadTable) + { + if (m_FinalBlock) + { + _remainLen = kLenIdFinished; + break; + } + + if (inputProgressLimit != 0) + if (m_InBitStream.GetProcessedSize() - inputStart >= inputProgressLimit) + return S_OK; + + if (!ReadTables()) + return S_FALSE; + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; + _needReadTable = false; + } + + if (m_StoredMode) + { + if (finishInputStream && curSize == 0 && m_StoredBlockSize != 0) + return S_FALSE; + /* NSIS version contains some bits in bitl bits buffer. + So we must read some first bytes via ReadAlignedByte */ + UInt32 num = m_StoredBlockSize; + if (num > curSize) + num = curSize; + m_StoredBlockSize -= num; + curSize -= num; + for (; num && m_InBitStream.ThereAreDataInBitsBuffer(); num--) + m_OutWindowStream.PutByte(ReadAlignedByte()); + if (num) + { +#if 1 + // fast code + do + { + size_t a; + Byte *buf = m_OutWindowStream.GetOutBuffer(a); + // a != 0 + if (a > num) + a = num; + // a != 0 + a = m_InBitStream.ReadDirectBytesPart(buf, a); + if (a == 0) + return S_FALSE; + m_OutWindowStream.SkipWrittenBytes(a); + num -= (UInt32)a; + } + while (num); +#else + // slow code: + do + m_OutWindowStream.PutByte(m_InBitStream.ReadDirectByte()); + while (--num); +#endif + } + _needReadTable = (m_StoredBlockSize == 0); + continue; + } + + while (curSize) + { + if (m_InBitStream.ExtraBitsWereRead_Fast()) + return S_FALSE; + unsigned sym; +#if 0 + sym = m_MainDecoder.Decode(&m_InBitStream); +#else + Z7_HUFF_DECODE_CHECK(sym, &m_MainDecoder, kNumHuffmanBits, kNumTableBits_Main, &m_InBitStream, { return S_FALSE; }) +#endif + + if (sym < 0x100) + { + m_OutWindowStream.PutByte((Byte)sym); + curSize--; + continue; + } + if (sym == kSymbolEndOfBlock) + { + _needReadTable = true; + break; + } +#if 0 + if (sym >= kMainTableSize) + return S_FALSE; +#endif + { + sym -= kSymbolMatch; + UInt32 len; + { + unsigned numBits; + if (_deflate64Mode) + { + len = kLenStart64[sym]; + numBits = kLenDirectBits64[sym]; + } + else + { + len = kLenStart32[sym]; + numBits = kLenDirectBits32[sym]; + } + len += kMatchMinLen + m_InBitStream.ReadBits(numBits); + } + +#if 0 + sym = m_DistDecoder.Decode(&m_InBitStream); + if (sym >= _numDistLevels) + return S_FALSE; +#else + Z7_HUFF_DECODE_CHECK(sym, &m_DistDecoder, kNumHuffmanBits, kNumTableBits_Dist, &m_InBitStream, { return S_FALSE; }) +#endif + +#if 1 + sym = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); +#else + if (sym >= 4) + { + // sym &= 31; + const unsigned numDirectBits = (sym - 2) >> 1; + sym = (2u | (sym & 1)) << numDirectBits; + sym += m_InBitStream.ReadBits(numDirectBits); + } +#endif + UInt32 locLen = len; + if (locLen > curSize) + locLen = (UInt32)curSize; + if (!m_OutWindowStream.CopyBlock(sym, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (Int32)len; + _rep0 = sym; + break; + } + } + } + + if (finishInputStream && curSize == 0) + { + if (m_MainDecoder.Decode(&m_InBitStream) != kSymbolEndOfBlock) + return S_FALSE; + _needReadTable = true; + } + } + + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; + + return S_OK; +} + + +#ifdef Z7_NO_EXCEPTIONS + +#define DEFLATE_TRY_BEGIN +#define DEFLATE_TRY_END(res) + +#else + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END(res) } \ + catch(const CSystemException &e) { res = e.ErrorCode; } \ + catch(...) { res = S_FALSE; } + + // catch(const CInBufferException &e) { res = e.ErrorCode; } + // catch(const CLzOutWindowException &e) { res = e.ErrorCode; } + +#endif + + +HRESULT CCoder::CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress) +{ + HRESULT res; + + DEFLATE_TRY_BEGIN + + m_OutWindowStream.SetStream(outStream); + CCoderReleaser flusher(this); + + const UInt64 inStart = _needInitInStream ? 0 : m_InBitStream.GetProcessedSize(); + + for (;;) + { + const UInt32 kInputProgressLimit = 1 << 21; + UInt32 curSize = 1 << 20; + bool finishInputStream = false; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - GetOutProcessedCur(); + if (curSize >= rem) + { + curSize = (UInt32)rem; + if (_needFinishInput) + finishInputStream = true; + else if (curSize == 0) + break; + } + } + + RINOK(CodeSpec(curSize, finishInputStream, progress ? kInputProgressLimit : 0)) + + if (_remainLen == kLenIdFinished) + break; + + if (progress) + { + const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart; + const UInt64 nowPos64 = GetOutProcessedCur(); + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)) + } + } + + flusher.NeedFlush = false; + res = Flush(); + if (res == S_OK && _remainLen != kLenIdNeedInit && InputEofError()) + return S_FALSE; + + DEFLATE_TRY_END(res) + + return res; +} + + +Z7_COM7F_IMF(CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + SetInStream(inStream); + SetOutStreamSize(outSize); + const HRESULT res = CodeReal(outStream, progress); + ReleaseInStream(); + /* + if (res == S_OK) + if (_needFinishInput && inSize && *inSize != m_InBitStream.GetProcessedSize()) + res = S_FALSE; + */ + return res; +} + + +Z7_COM7F_IMF(CCoder::SetFinishMode(UInt32 finishMode)) +{ + Set_NeedFinishInput(finishMode != 0); + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = m_InBitStream.GetStreamSize(); + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +{ + AlignToByte(); + UInt32 i = 0; + { + for (i = 0; i < size; i++) + { + if (!m_InBitStream.ReadAlignedByte_FromBuf(((Byte *)data)[i])) + break; + } + } + if (processedSize) + *processedSize = i; + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::SetInStream(ISequentialInStream *inStream)) +{ + m_InStreamRef = inStream; + m_InBitStream.SetStream(inStream); + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::ReleaseInStream()) +{ + m_InStreamRef.Release(); + m_InBitStream.ClearStreamPtr(); + return S_OK; +} + + +void CCoder::SetOutStreamSizeResume(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + _outSize = 0; + if (_outSizeDefined) + _outSize = *outSize; + m_OutWindowStream.Init(_keepHistory); + _outStartPos = m_OutWindowStream.GetProcessedSize(); + _remainLen = kLenIdNeedInit; +} + + +Z7_COM7F_IMF(CCoder::SetOutStreamSize(const UInt64 *outSize)) +{ + /* + 18.06: + We want to support GetInputProcessedSize() before CCoder::Read() + So we call m_InBitStream.Init() even before buffer allocations + m_InBitStream.Init() just sets variables to default values + But later we will call m_InBitStream.Init() again with real buffer pointers + */ + m_InBitStream.Init(); + _needInitInStream = true; + SetOutStreamSizeResume(outSize); + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + const UInt64 outPos = GetOutProcessedCur(); + + bool finishInputStream = false; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - outPos; + if (size >= rem) + { + size = (UInt32)rem; + if (_needFinishInput) + finishInputStream = true; + } + } + if (!finishInputStream && size == 0) + return S_OK; + + HRESULT res; + DEFLATE_TRY_BEGIN + m_OutWindowStream.SetMemStream((Byte *)data); + res = CodeSpec(size, finishInputStream); + DEFLATE_TRY_END(res) + { + const HRESULT res2 = Flush(); + if (res2 != S_OK) + res = res2; + } + if (processedSize) + *processedSize = (UInt32)(GetOutProcessedCur() - outPos); + m_OutWindowStream.SetMemStream(NULL); + return res; +} + +#endif + + +HRESULT CCoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + SetOutStreamSizeResume(outSize); + return CodeReal(outStream, progress); +} + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateDecoder.h 2016-05-18 17:31:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateDecoder.h 2024-01-06 19:00:00.000000000 +0000 @@ -1,155 +1,154 @@ -// DeflateDecoder.h - -#ifndef __DEFLATE_DECODER_H -#define __DEFLATE_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitlDecoder.h" -#include "DeflateConst.h" -#include "HuffmanDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NDeflate { -namespace NDecoder { - -const int kLenIdFinished = -1; -const int kLenIdNeedInit = -2; - -class CCoder: - public ICompressCoder, - public ICompressGetInStreamProcessedSize, - #ifndef NO_READ_FROM_CODER - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public ISequentialInStream, - #endif - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - CMyComPtr m_InStreamRef; - NBitl::CDecoder m_InBitStream; - NCompress::NHuffman::CDecoder m_MainDecoder; - NCompress::NHuffman::CDecoder m_DistDecoder; - NCompress::NHuffman::CDecoder7b m_LevelDecoder; - - UInt32 m_StoredBlockSize; - - UInt32 _numDistLevels; - bool m_FinalBlock; - bool m_StoredMode; - - bool _deflateNSIS; - bool _deflate64Mode; - bool _keepHistory; - bool _needFinishInput; - - bool _needInitInStream; - bool _needReadTable; - Int32 _remainLen; - UInt32 _rep0; - - UInt32 ReadBits(unsigned numBits); - - bool DecodeLevels(Byte *levels, unsigned numSymbols); - bool ReadTables(); - - HRESULT Flush() { return m_OutWindowStream.Flush(); } - class CCoderReleaser - { - CCoder *_coder; - public: - bool NeedFlush; - CCoderReleaser(CCoder *coder): _coder(coder), NeedFlush(true) {} - ~CCoderReleaser() - { - if (NeedFlush) - _coder->Flush(); - } - }; - friend class CCoderReleaser; - - HRESULT CodeSpec(UInt32 curSize, bool finishInputStream); -public: - bool ZlibMode; - Byte ZlibFooter[4]; - - CCoder(bool deflate64Mode, bool deflateNSIS = false); - virtual ~CCoder() {}; - - void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } - void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; } - - bool IsFinished() const { return _remainLen == kLenIdFinished;; } - bool IsFinalBlock() const { return m_FinalBlock; } - - HRESULT CodeReal(ISequentialOutStream *outStream, - const UInt64 *outSize, ICompressProgressInfo *progress); - - #ifndef NO_READ_FROM_CODER - MY_UNKNOWN_IMP5( - ICompressCoder, - ICompressGetInStreamProcessedSize, - ICompressSetInStream, - ICompressSetOutStreamSize, - ISequentialInStream - ) - #else - MY_UNKNOWN_IMP2( - ICompressCoder, - ICompressGetInStreamProcessedSize) - #endif - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif - - STDMETHOD(CodeResume)(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); - - HRESULT InitInStream(bool needInit) - { - if (!m_InBitStream.Create(1 << 17)) - return E_OUTOFMEMORY; - if (needInit) - { - m_InBitStream.Init(); - _needInitInStream = false; - } - return S_OK; - } - - void AlignToByte() { m_InBitStream.AlignToByte(); } - Byte ReadAlignedByte(); - UInt32 ReadAligned_UInt16() // aligned for Byte range - { - UInt32 v = m_InBitStream.ReadAlignedByte(); - return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8); - } - bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); } - - UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); } - UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); } - - // IGetInStreamProcessedSize - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); -}; - -class CCOMCoder : public CCoder { public: CCOMCoder(): CCoder(false) {} }; -class CNsisCOMCoder : public CCoder { public: CNsisCOMCoder(): CCoder(false, true) {} }; -class CCOMCoder64 : public CCoder { public: CCOMCoder64(): CCoder(true) {} }; - -}}} - -#endif +// DeflateDecoder.h + +#ifndef ZIP7_INC_DEFLATE_DECODER_H +#define ZIP7_INC_DEFLATE_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitlDecoder.h" +#include "DeflateConst.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NDeflate { +namespace NDecoder { + +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +const unsigned kNumTableBits_Main = 10; +const unsigned kNumTableBits_Dist = 6; + +class CCoder: + public ICompressCoder, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressReadUnusedFromInBuf, + public ICompressSetInStream, + public ICompressSetOutStreamSize, +#ifndef Z7_NO_READ_FROM_CODER + public ISequentialInStream, +#endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ISequentialInStream) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) +public: + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) +#ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ISequentialInStream) +#endif + + CLzOutWindow m_OutWindowStream; + NBitl::CDecoder m_InBitStream; + NCompress::NHuffman::CDecoder m_MainDecoder; + NCompress::NHuffman::CDecoder256 m_DistDecoder; + NCompress::NHuffman::CDecoder7b m_LevelDecoder; + + UInt32 m_StoredBlockSize; + + unsigned _numDistLevels; + bool m_FinalBlock; + bool m_StoredMode; + + bool _deflateNSIS; + bool _deflate64Mode; + bool _keepHistory; + bool _needFinishInput; + + bool _needInitInStream; + bool _needReadTable; + Int32 _remainLen; + UInt32 _rep0; + + bool _outSizeDefined; + CMyComPtr m_InStreamRef; + UInt64 _outSize; + UInt64 _outStartPos; + + void SetOutStreamSizeResume(const UInt64 *outSize); + UInt64 GetOutProcessedCur() const { return m_OutWindowStream.GetProcessedSize() - _outStartPos; } + + UInt32 ReadBits(unsigned numBits); + + bool DecodeLevels(Byte *levels, unsigned numSymbols); + bool ReadTables(); + + HRESULT Flush() { return m_OutWindowStream.Flush(); } + class CCoderReleaser + { + CCoder *_coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): _coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + _coder->Flush(); + } + }; + friend class CCoderReleaser; + + HRESULT CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit = 0); +public: + + CCoder(bool deflate64Mode); + virtual ~CCoder() {} + + void SetNsisMode(bool nsisMode) { _deflateNSIS = nsisMode; } + + void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; } + + bool IsFinished() const { return _remainLen == kLenIdFinished; } + bool IsFinalBlock() const { return m_FinalBlock; } + + HRESULT CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress); + +public: + HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); + HRESULT InitInStream(bool needInit); + + void AlignToByte() { m_InBitStream.AlignToByte(); } + Byte ReadAlignedByte(); + UInt32 ReadAligned_UInt16() // aligned for Byte range + { + const UInt32 v = m_InBitStream.ReadAlignedByte(); + return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8); + } + bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); } + + // size of used real data from input stream + UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); } + + // size of virtual input stream processed + UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); } +}; + +class CCOMCoder : public CCoder { public: CCOMCoder(): CCoder(false) {} }; +class CCOMCoder64 : public CCoder { public: CCOMCoder64(): CCoder(true) {} }; + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateEncoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateEncoder.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.cpp 2025-01-13 13:00:00.000000000 +0000 @@ -1,1003 +1,1045 @@ -// DeflateEncoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/HuffEnc.h" - -#include "../../Common/ComTry.h" - -#include "DeflateEncoder.h" - -#undef NO_INLINE - -#ifdef _MSC_VER -#define NO_INLINE MY_NO_INLINE -#else -#define NO_INLINE -#endif - -namespace NCompress { -namespace NDeflate { -namespace NEncoder { - -static const unsigned kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. -static const UInt32 kNumTables = (1 << kNumDivPassesMax); - -static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio. -static const UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. -static const UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. - -static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32)) -static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32)) -static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16); -static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize - - kMatchMaxLen - kNumOpts; - -static const unsigned kMaxCodeBitLength = 11; -static const unsigned kMaxLevelBitLength = 7; - -static const Byte kNoLiteralStatPrice = 11; -static const Byte kNoLenStatPrice = 11; -static const Byte kNoPosStatPrice = 6; - -static Byte g_LenSlots[kNumLenSymbolsMax]; -static Byte g_FastPos[1 << 9]; - -class CFastPosInit -{ -public: - CFastPosInit() - { - unsigned i; - for (i = 0; i < kNumLenSlots; i++) - { - unsigned c = kLenStart32[i]; - unsigned j = 1 << kLenDirectBits32[i]; - for (unsigned k = 0; k < j; k++, c++) - g_LenSlots[c] = (Byte)i; - } - - const unsigned kFastSlots = 18; - unsigned c = 0; - for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) - { - UInt32 k = (1 << kDistDirectBits[slotFast]); - for (UInt32 j = 0; j < k; j++, c++) - g_FastPos[c] = slotFast; - } - } -}; - -static CFastPosInit g_FastPosInit; - - -inline UInt32 GetPosSlot(UInt32 pos) -{ - if (pos < 0x200) - return g_FastPos[pos]; - return g_FastPos[pos >> 8] + 16; -} - -void CEncProps::Normalize() -{ - int level = Level; - if (level < 0) level = 5; - Level = level; - if (algo < 0) algo = (level < 5 ? 0 : 1); - if (fb < 0) fb = (level < 7 ? 32 : (level < 9 ? 64 : 128)); - if (btMode < 0) btMode = (algo == 0 ? 0 : 1); - if (mc == 0) mc = (16 + (fb >> 1)); - if (numPasses == (UInt32)(Int32)-1) numPasses = (level < 7 ? 1 : (level < 9 ? 3 : 10)); -} - -void CCoder::SetProps(const CEncProps *props2) -{ - CEncProps props = *props2; - props.Normalize(); - - m_MatchFinderCycles = props.mc; - { - unsigned fb = props.fb; - if (fb < kMatchMinLen) - fb = kMatchMinLen; - if (fb > m_MatchMaxLen) - fb = m_MatchMaxLen; - m_NumFastBytes = fb; - } - _fastMode = (props.algo == 0); - _btMode = (props.btMode != 0); - - m_NumDivPasses = props.numPasses; - if (m_NumDivPasses == 0) - m_NumDivPasses = 1; - if (m_NumDivPasses == 1) - m_NumPasses = 1; - else if (m_NumDivPasses <= kNumDivPassesMax) - m_NumPasses = 2; - else - { - m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax); - m_NumDivPasses = kNumDivPassesMax; - } -} - -CCoder::CCoder(bool deflate64Mode): - m_Deflate64Mode(deflate64Mode), - m_OnePosMatchesMemory(0), - m_DistanceMemory(0), - m_Created(false), - m_Values(0), - m_Tables(0) -{ - m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32; - m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32; - m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32; - m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32; - { - CEncProps props; - SetProps(&props); - } - MatchFinder_Construct(&_lzInWindow); -} - -HRESULT CCoder::Create() -{ - // COM_TRY_BEGIN - if (m_Values == 0) - { - m_Values = (CCodeValue *)MyAlloc((kMaxUncompressedBlockSize) * sizeof(CCodeValue)); - if (m_Values == 0) - return E_OUTOFMEMORY; - } - if (m_Tables == 0) - { - m_Tables = (CTables *)MyAlloc((kNumTables) * sizeof(CTables)); - if (m_Tables == 0) - return E_OUTOFMEMORY; - } - - if (m_IsMultiPass) - { - if (m_OnePosMatchesMemory == 0) - { - m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16)); - if (m_OnePosMatchesMemory == 0) - return E_OUTOFMEMORY; - } - } - else - { - if (m_DistanceMemory == 0) - { - m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16)); - if (m_DistanceMemory == 0) - return E_OUTOFMEMORY; - m_MatchDistances = m_DistanceMemory; - } - } - - if (!m_Created) - { - _lzInWindow.btMode = (Byte)(_btMode ? 1 : 0); - _lzInWindow.numHashBytes = 3; - if (!MatchFinder_Create(&_lzInWindow, - m_Deflate64Mode ? kHistorySize64 : kHistorySize32, - kNumOpts + kMaxUncompressedBlockSize, - m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_Alloc)) - return E_OUTOFMEMORY; - if (!m_OutStream.Create(1 << 20)) - return E_OUTOFMEMORY; - } - if (m_MatchFinderCycles != 0) - _lzInWindow.cutValue = m_MatchFinderCycles; - m_Created = true; - return S_OK; - // COM_TRY_END -} - -HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - CEncProps props; - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) - continue; - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; - switch (propID) - { - case NCoderPropID::kNumPasses: props.numPasses = v; break; - case NCoderPropID::kNumFastBytes: props.fb = v; break; - case NCoderPropID::kMatchFinderCycles: props.mc = v; break; - case NCoderPropID::kAlgorithm: props.algo = v; break; - case NCoderPropID::kLevel: props.Level = v; break; - case NCoderPropID::kNumThreads: break; - default: return E_INVALIDARG; - } - } - SetProps(&props); - return S_OK; -} - -void CCoder::Free() -{ - ::MidFree(m_OnePosMatchesMemory); m_OnePosMatchesMemory = 0; - ::MyFree(m_DistanceMemory); m_DistanceMemory = 0; - ::MyFree(m_Values); m_Values = 0; - ::MyFree(m_Tables); m_Tables = 0; -} - -CCoder::~CCoder() -{ - Free(); - MatchFinder_Free(&_lzInWindow, &g_Alloc); -} - -NO_INLINE void CCoder::GetMatches() -{ - if (m_IsMultiPass) - { - m_MatchDistances = m_OnePosMatchesMemory + m_Pos; - if (m_SecondPass) - { - m_Pos += *m_MatchDistances + 1; - return; - } - } - - UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; - - UInt32 numPairs = (_btMode) ? - Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp): - Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp); - - *m_MatchDistances = (UInt16)numPairs; - - if (numPairs > 0) - { - UInt32 i; - for (i = 0; i < numPairs; i += 2) - { - m_MatchDistances[i + 1] = (UInt16)distanceTmp[i]; - m_MatchDistances[i + 2] = (UInt16)distanceTmp[i + 1]; - } - UInt32 len = distanceTmp[numPairs - 2]; - if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen) - { - UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1; - const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1; - const Byte *pby2 = pby - (distanceTmp[numPairs - 1] + 1); - if (numAvail > m_MatchMaxLen) - numAvail = m_MatchMaxLen; - for (; len < numAvail && pby[len] == pby2[len]; len++); - m_MatchDistances[i - 1] = (UInt16)len; - } - } - if (m_IsMultiPass) - m_Pos += numPairs + 1; - if (!m_SecondPass) - m_AdditionalOffset++; -} - -void CCoder::MovePos(UInt32 num) -{ - if (!m_SecondPass && num > 0) - { - if (_btMode) - Bt3Zip_MatchFinder_Skip(&_lzInWindow, num); - else - Hc3Zip_MatchFinder_Skip(&_lzInWindow, num); - m_AdditionalOffset += num; - } -} - -static const UInt32 kIfinityPrice = 0xFFFFFFF; - -NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) -{ - m_OptimumEndIndex = cur; - UInt32 posMem = m_Optimum[cur].PosPrev; - UInt16 backMem = m_Optimum[cur].BackPrev; - do - { - UInt32 posPrev = posMem; - UInt16 backCur = backMem; - backMem = m_Optimum[posPrev].BackPrev; - posMem = m_Optimum[posPrev].PosPrev; - m_Optimum[posPrev].BackPrev = backCur; - m_Optimum[posPrev].PosPrev = (UInt16)cur; - cur = posPrev; - } - while (cur > 0); - backRes = m_Optimum[0].BackPrev; - m_OptimumCurrentIndex = m_Optimum[0].PosPrev; - return m_OptimumCurrentIndex; -} - -NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) -{ - if (m_OptimumEndIndex != m_OptimumCurrentIndex) - { - UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; - backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev; - m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev; - return len; - } - m_OptimumCurrentIndex = m_OptimumEndIndex = 0; - - GetMatches(); - - UInt32 lenEnd; - { - const UInt32 numDistancePairs = m_MatchDistances[0]; - if (numDistancePairs == 0) - return 1; - const UInt16 *matchDistances = m_MatchDistances + 1; - lenEnd = matchDistances[numDistancePairs - 2]; - - if (lenEnd > m_NumFastBytes) - { - backRes = matchDistances[numDistancePairs - 1]; - MovePos(lenEnd - 1); - return lenEnd; - } - - m_Optimum[1].Price = m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset)]; - m_Optimum[1].PosPrev = 0; - - m_Optimum[2].Price = kIfinityPrice; - m_Optimum[2].PosPrev = 1; - - UInt32 offs = 0; - - for (UInt32 i = kMatchMinLen; i <= lenEnd; i++) - { - UInt32 distance = matchDistances[offs + 1]; - m_Optimum[i].PosPrev = 0; - m_Optimum[i].BackPrev = (UInt16)distance; - m_Optimum[i].Price = m_LenPrices[i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)]; - if (i == matchDistances[offs]) - offs += 2; - } - } - - UInt32 cur = 0; - - for (;;) - { - ++cur; - if (cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit) - return Backward(backRes, cur); - GetMatches(); - const UInt16 *matchDistances = m_MatchDistances + 1; - const UInt32 numDistancePairs = m_MatchDistances[0]; - UInt32 newLen = 0; - if (numDistancePairs != 0) - { - newLen = matchDistances[numDistancePairs - 2]; - if (newLen > m_NumFastBytes) - { - UInt32 len = Backward(backRes, cur); - m_Optimum[cur].BackPrev = matchDistances[numDistancePairs - 1]; - m_OptimumEndIndex = cur + newLen; - m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex; - MovePos(newLen - 1); - return len; - } - } - UInt32 curPrice = m_Optimum[cur].Price; - { - const UInt32 curAnd1Price = curPrice + m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) + cur - m_AdditionalOffset)]; - COptimal &optimum = m_Optimum[cur + 1]; - if (curAnd1Price < optimum.Price) - { - optimum.Price = curAnd1Price; - optimum.PosPrev = (UInt16)cur; - } - } - if (numDistancePairs == 0) - continue; - while (lenEnd < cur + newLen) - m_Optimum[++lenEnd].Price = kIfinityPrice; - UInt32 offs = 0; - UInt32 distance = matchDistances[offs + 1]; - curPrice += m_PosPrices[GetPosSlot(distance)]; - for (UInt32 lenTest = kMatchMinLen; ; lenTest++) - { - UInt32 curAndLenPrice = curPrice + m_LenPrices[lenTest - kMatchMinLen]; - COptimal &optimum = m_Optimum[cur + lenTest]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = (UInt16)cur; - optimum.BackPrev = (UInt16)distance; - } - if (lenTest == matchDistances[offs]) - { - offs += 2; - if (offs == numDistancePairs) - break; - curPrice -= m_PosPrices[GetPosSlot(distance)]; - distance = matchDistances[offs + 1]; - curPrice += m_PosPrices[GetPosSlot(distance)]; - } - } - } -} - -UInt32 CCoder::GetOptimalFast(UInt32 &backRes) -{ - GetMatches(); - UInt32 numDistancePairs = m_MatchDistances[0]; - if (numDistancePairs == 0) - return 1; - UInt32 lenMain = m_MatchDistances[numDistancePairs - 1]; - backRes = m_MatchDistances[numDistancePairs]; - MovePos(lenMain - 1); - return lenMain; -} - -void CTables::InitStructures() -{ - UInt32 i; - for (i = 0; i < 256; i++) - litLenLevels[i] = 8; - litLenLevels[i++] = 13; - for (;i < kFixedMainTableSize; i++) - litLenLevels[i] = 5; - for (i = 0; i < kFixedDistTableSize; i++) - distLevels[i] = 5; -} - -NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs) -{ - unsigned prevLen = 0xFF; - unsigned nextLen = levels[0]; - unsigned count = 0; - unsigned maxCount = 7; - unsigned minCount = 4; - - if (nextLen == 0) - { - maxCount = 138; - minCount = 3; - } - - for (unsigned n = 0; n < numLevels; n++) - { - unsigned curLen = nextLen; - nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; - count++; - if (count < maxCount && curLen == nextLen) - continue; - - if (count < minCount) - freqs[curLen] += (UInt32)count; - else if (curLen != 0) - { - if (curLen != prevLen) - { - freqs[curLen]++; - count--; - } - freqs[kTableLevelRepNumber]++; - } - else if (count <= 10) - freqs[kTableLevel0Number]++; - else - freqs[kTableLevel0Number2]++; - - count = 0; - prevLen = curLen; - - if (nextLen == 0) - { - maxCount = 138; - minCount = 3; - } - else if (curLen == nextLen) - { - maxCount = 6; - minCount = 3; - } - else - { - maxCount = 7; - minCount = 4; - } - } -} - -NO_INLINE void CCoder::WriteBits(UInt32 value, unsigned numBits) -{ - m_OutStream.WriteBits(value, numBits); -} - -#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i]) -#define WRITE_HF(i) WriteBits(codes[i], lens[i]) - -NO_INLINE void CCoder::LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes) -{ - unsigned prevLen = 0xFF; - unsigned nextLen = levels[0]; - unsigned count = 0; - unsigned maxCount = 7; - unsigned minCount = 4; - - if (nextLen == 0) - { - maxCount = 138; - minCount = 3; - } - - for (unsigned n = 0; n < numLevels; n++) - { - unsigned curLen = nextLen; - nextLen = (n < numLevels - 1) ? levels[n + 1] : 0xFF; - count++; - if (count < maxCount && curLen == nextLen) - continue; - - if (count < minCount) - for (unsigned i = 0; i < count; i++) - WRITE_HF(curLen); - else if (curLen != 0) - { - if (curLen != prevLen) - { - WRITE_HF(curLen); - count--; - } - WRITE_HF(kTableLevelRepNumber); - WriteBits(count - 3, 2); - } - else if (count <= 10) - { - WRITE_HF(kTableLevel0Number); - WriteBits(count - 3, 3); - } - else - { - WRITE_HF(kTableLevel0Number2); - WriteBits(count - 11, 7); - } - - count = 0; - prevLen = curLen; - - if (nextLen == 0) - { - maxCount = 138; - minCount = 3; - } - else if (curLen == nextLen) - { - maxCount = 6; - minCount = 3; - } - else - { - maxCount = 7; - minCount = 4; - } - } -} - -NO_INLINE void CCoder::MakeTables(unsigned maxHuffLen) -{ - Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, maxHuffLen); - Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, maxHuffLen); -} - -NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num) -{ - UInt32 price = 0; - UInt32 i; - for (i = 0; i < num; i++) - price += lens[i] * freqs[i]; - return price; -} - -NO_INLINE UInt32 Huffman_GetPrice_Spec(const UInt32 *freqs, const Byte *lens, UInt32 num, const Byte *extraBits, UInt32 extraBase) -{ - return Huffman_GetPrice(freqs, lens, num) + - Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase); -} - -NO_INLINE UInt32 CCoder::GetLzBlockPrice() const -{ - return - Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) + - Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, kDistTableSize64, kDistDirectBits, 0); -} - -NO_INLINE void CCoder::TryBlock() -{ - memset(mainFreqs, 0, sizeof(mainFreqs)); - memset(distFreqs, 0, sizeof(distFreqs)); - - m_ValueIndex = 0; - UInt32 blockSize = BlockSizeRes; - BlockSizeRes = 0; - for (;;) - { - if (m_OptimumCurrentIndex == m_OptimumEndIndex) - { - if (m_Pos >= kMatchArrayLimit || BlockSizeRes >= blockSize || !m_SecondPass && - ((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize)) - break; - } - UInt32 pos; - UInt32 len; - if (_fastMode) - len = GetOptimalFast(pos); - else - len = GetOptimal(pos); - CCodeValue &codeValue = m_Values[m_ValueIndex++]; - if (len >= kMatchMinLen) - { - UInt32 newLen = len - kMatchMinLen; - codeValue.Len = (UInt16)newLen; - mainFreqs[kSymbolMatch + g_LenSlots[newLen]]++; - codeValue.Pos = (UInt16)pos; - distFreqs[GetPosSlot(pos)]++; - } - else - { - Byte b = *(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset); - mainFreqs[b]++; - codeValue.SetAsLiteral(); - codeValue.Pos = b; - } - m_AdditionalOffset -= len; - BlockSizeRes += len; - } - mainFreqs[kSymbolEndOfBlock]++; - m_AdditionalOffset += BlockSizeRes; - m_SecondPass = true; -} - -NO_INLINE void CCoder::SetPrices(const CLevels &levels) -{ - if (_fastMode) - return; - UInt32 i; - for (i = 0; i < 256; i++) - { - Byte price = levels.litLenLevels[i]; - m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice); - } - - for (i = 0; i < m_NumLenCombinations; i++) - { - UInt32 slot = g_LenSlots[i]; - Byte price = levels.litLenLevels[kSymbolMatch + slot]; - m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]); - } - - for (i = 0; i < kDistTableSize64; i++) - { - Byte price = levels.distLevels[i]; - m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]); - } -} - -NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num) -{ - for (UInt32 i = 0; i < num; i++) - { - UInt32 x = codes[i]; - x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1); - x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2); - x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4); - codes[i] = (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - lens[i]); - } -} - -NO_INLINE void CCoder::WriteBlock() -{ - Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize); - Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64); - - for (UInt32 i = 0; i < m_ValueIndex; i++) - { - const CCodeValue &codeValue = m_Values[i]; - if (codeValue.IsLiteral()) - WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, codeValue.Pos); - else - { - UInt32 len = codeValue.Len; - UInt32 lenSlot = g_LenSlots[len]; - WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot); - m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]); - UInt32 dist = codeValue.Pos; - UInt32 posSlot = GetPosSlot(dist); - WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot); - m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]); - } - } - WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); -} - -static UInt32 GetStorePrice(UInt32 blockSize, unsigned bitPosition) -{ - UInt32 price = 0; - do - { - UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7; - unsigned numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; - UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; - price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8; - bitPosition = 0; - blockSize -= curBlockSize; - } - while (blockSize != 0); - return price; -} - -void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock) -{ - do - { - UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; - blockSize -= curBlockSize; - WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); - WriteBits(NBlockType::kStored, kBlockTypeFieldSize); - m_OutStream.FlushByte(); - WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize); - WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize); - const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset; - for (UInt32 i = 0; i < curBlockSize; i++) - m_OutStream.WriteByte(data[i]); - additionalOffset -= curBlockSize; - } - while (blockSize != 0); -} - -NO_INLINE UInt32 CCoder::TryDynBlock(unsigned tableIndex, UInt32 numPasses) -{ - CTables &t = m_Tables[tableIndex]; - BlockSizeRes = t.BlockSizeRes; - UInt32 posTemp = t.m_Pos; - SetPrices(t); - - for (UInt32 p = 0; p < numPasses; p++) - { - m_Pos = posTemp; - TryBlock(); - unsigned numHuffBits = - (m_ValueIndex > 18000 ? 12 : - (m_ValueIndex > 7000 ? 11 : - (m_ValueIndex > 2000 ? 10 : 9))); - MakeTables(numHuffBits); - SetPrices(m_NewLevels); - } - - (CLevels &)t = m_NewLevels; - - m_NumLitLenLevels = kMainTableSize; - while (m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[m_NumLitLenLevels - 1] == 0) - m_NumLitLenLevels--; - - m_NumDistLevels = kDistTableSize64; - while (m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[m_NumDistLevels - 1] == 0) - m_NumDistLevels--; - - UInt32 levelFreqs[kLevelTableSize]; - memset(levelFreqs, 0, sizeof(levelFreqs)); - - LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs); - LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs); - - Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength); - - m_NumLevelCodes = kNumLevelCodesMin; - for (UInt32 i = 0; i < kLevelTableSize; i++) - { - Byte level = levelLens[kCodeLengthAlphabetOrder[i]]; - if (level > 0 && i >= m_NumLevelCodes) - m_NumLevelCodes = i + 1; - m_LevelLevels[i] = level; - } - - return GetLzBlockPrice() + - Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) + - kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize + - m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize; -} - -NO_INLINE UInt32 CCoder::TryFixedBlock(unsigned tableIndex) -{ - CTables &t = m_Tables[tableIndex]; - BlockSizeRes = t.BlockSizeRes; - m_Pos = t.m_Pos; - m_NewLevels.SetFixedLevels(); - SetPrices(m_NewLevels); - TryBlock(); - return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice(); -} - -NO_INLINE UInt32 CCoder::GetBlockPrice(unsigned tableIndex, unsigned numDivPasses) -{ - CTables &t = m_Tables[tableIndex]; - t.StaticMode = false; - UInt32 price = TryDynBlock(tableIndex, m_NumPasses); - t.BlockSizeRes = BlockSizeRes; - UInt32 numValues = m_ValueIndex; - UInt32 posTemp = m_Pos; - UInt32 additionalOffsetEnd = m_AdditionalOffset; - - if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax) - { - const UInt32 fixedPrice = TryFixedBlock(tableIndex); - t.StaticMode = (fixedPrice < price); - if (t.StaticMode) - price = fixedPrice; - } - - const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition - t.StoreMode = (storePrice <= price); - if (t.StoreMode) - price = storePrice; - - t.UseSubBlocks = false; - - if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin) - { - CTables &t0 = m_Tables[(tableIndex << 1)]; - (CLevels &)t0 = t; - t0.BlockSizeRes = t.BlockSizeRes >> 1; - t0.m_Pos = t.m_Pos; - UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1); - - UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes; - if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin) - { - CTables &t1 = m_Tables[(tableIndex << 1) + 1]; - (CLevels &)t1 = t; - t1.BlockSizeRes = blockSize2; - t1.m_Pos = m_Pos; - m_AdditionalOffset -= t0.BlockSizeRes; - subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1); - t.UseSubBlocks = (subPrice < price); - if (t.UseSubBlocks) - price = subPrice; - } - } - - m_AdditionalOffset = additionalOffsetEnd; - m_Pos = posTemp; - return price; -} - -void CCoder::CodeBlock(unsigned tableIndex, bool finalBlock) -{ - CTables &t = m_Tables[tableIndex]; - if (t.UseSubBlocks) - { - CodeBlock((tableIndex << 1), false); - CodeBlock((tableIndex << 1) + 1, finalBlock); - } - else - { - if (t.StoreMode) - WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock); - else - { - WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); - if (t.StaticMode) - { - WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize); - TryFixedBlock(tableIndex); - unsigned i; - const unsigned kMaxStaticHuffLen = 9; - for (i = 0; i < kFixedMainTableSize; i++) - mainFreqs[i] = (UInt32)1 << (kMaxStaticHuffLen - m_NewLevels.litLenLevels[i]); - for (i = 0; i < kFixedDistTableSize; i++) - distFreqs[i] = (UInt32)1 << (kMaxStaticHuffLen - m_NewLevels.distLevels[i]); - MakeTables(kMaxStaticHuffLen); - } - else - { - if (m_NumDivPasses > 1 || m_CheckStatic) - TryDynBlock(tableIndex, 1); - WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize); - WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize); - WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize); - WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize); - - for (UInt32 i = 0; i < m_NumLevelCodes; i++) - WriteBits(m_LevelLevels[i], kLevelFieldSize); - - Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize); - LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes); - LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes); - } - WriteBlock(); - } - m_AdditionalOffset -= t.BlockSizeRes; - } -} - -SRes Read(void *object, void *data, size_t *size) -{ - const UInt32 kStepSize = (UInt32)1 << 31; - UInt32 curSize = ((*size < kStepSize) ? (UInt32)*size : kStepSize); - HRESULT res = ((CSeqInStream *)object)->RealStream->Read(data, curSize, &curSize); - *size = curSize; - return (SRes)res; -} - -HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */ , const UInt64 * /* outSize */ , ICompressProgressInfo *progress) -{ - m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1); - m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1)); - - RINOK(Create()); - - m_ValueBlockSize = (7 << 10) + (1 << 12) * m_NumDivPasses; - - UInt64 nowPos = 0; - - _seqInStream.RealStream = inStream; - _seqInStream.SeqInStream.Read = Read; - _lzInWindow.stream = &_seqInStream.SeqInStream; - - MatchFinder_Init(&_lzInWindow); - m_OutStream.SetStream(outStream); - m_OutStream.Init(); - - m_OptimumEndIndex = m_OptimumCurrentIndex = 0; - - CTables &t = m_Tables[1]; - t.m_Pos = 0; - t.InitStructures(); - - m_AdditionalOffset = 0; - do - { - t.BlockSizeRes = kBlockUncompressedSizeThreshold; - m_SecondPass = false; - GetBlockPrice(1, m_NumDivPasses); - CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0); - nowPos += m_Tables[1].BlockSizeRes; - if (progress != NULL) - { - UInt64 packSize = m_OutStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&nowPos, &packSize)); - } - } - while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0); - if (_lzInWindow.result != SZ_OK) - return _lzInWindow.result; - return m_OutStream.Flush(); -} - -HRESULT CCoder::BaseCode(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } -} - -STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) - { return BaseCode(inStream, outStream, inSize, outSize, progress); } - -STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) - { return BaseSetEncoderProperties2(propIDs, props, numProps); } - -STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) - { return BaseCode(inStream, outStream, inSize, outSize, progress); } - -STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) - { return BaseSetEncoderProperties2(propIDs, props, numProps); } - -}}} +// DeflateEncoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/HuffEnc.h" + +#include "../../Common/ComTry.h" + +#include "../Common/CWrappers.h" + +#include "DeflateEncoder.h" + +#undef NO_INLINE + +#ifdef _MSC_VER +#define NO_INLINE Z7_NO_INLINE +#else +#define NO_INLINE +#endif + +#define MAX_HUF_LEN_12 12 + +namespace NCompress { +namespace NDeflate { +namespace NEncoder { + +static const unsigned k_CodeValue_Len_Is_Literal_Flag = 1u << 15; + +static const unsigned kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio. +static const unsigned kNumTables = 1u << kNumDivPassesMax; + +static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio. +static const UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. +static const UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio. + +static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32)) +static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32)) +static const UInt32 kMatchArrayLimit = kMatchArraySize - kMatchMaxLen * 4 * sizeof(UInt16); +static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize - + kMatchMaxLen - kNumOpts; + +// static const unsigned kMaxCodeBitLength = 11; +static const unsigned kMaxLevelBitLength = 7; + +static const Byte kNoLiteralStatPrice = 11; +static const Byte kNoLenStatPrice = 11; +static const Byte kNoPosStatPrice = 6; + +MY_ALIGN(64) +static Byte g_LenSlots[kNumLenSymbolsMax]; + +#define kNumLogBits 9 // do not change it +MY_ALIGN(64) +static Byte g_FastPos[1 << kNumLogBits]; + +class CFastPosInit +{ +public: + CFastPosInit() + { + unsigned i; + for (i = 0; i < kNumLenSlots; i++) + { + unsigned c = kLenStart32[i]; + const unsigned j = 1u << kLenDirectBits32[i]; + for (unsigned k = 0; k < j; k++, c++) + g_LenSlots[c] = (Byte)i; + } + + const unsigned kFastSlots = kNumLogBits * 2; + unsigned c = 0; + for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) + { + const unsigned k = 1u << kDistDirectBits[slotFast]; + for (unsigned j = 0; j < k; j++, c++) + g_FastPos[c] = slotFast; + } + } +}; + +static CFastPosInit g_FastPosInit; + +inline unsigned GetPosSlot(UInt32 pos) +{ + /* + if (pos < 0x200) + return g_FastPos[pos]; + return g_FastPos[pos >> 8] + 16; + */ + // const unsigned zz = (pos < ((UInt32)1 << (kNumLogBits))) ? 0 : 8; + /* + const unsigned zz = (kNumLogBits - 1) & + ((UInt32)0 - (((((UInt32)1 << kNumLogBits) - 1) - pos) >> 31)); + */ + const unsigned zz = (kNumLogBits - 1) & + (((((UInt32)1 << kNumLogBits) - 1) - pos) >> (31 - 3)); + return g_FastPos[pos >> zz] + (zz * 2); +} + + +void CEncProps::Normalize() +{ + int level = Level; + if (level < 0) level = 5; + Level = level; + if (algo < 0) algo = (level < 5 ? 0 : 1); + if (fb < 0) fb = (level < 7 ? 32 : (level < 9 ? 64 : 128)); + if (btMode < 0) btMode = (algo == 0 ? 0 : 1); + if (mc == 0) mc = (16 + ((unsigned)fb >> 1)); + if (numPasses == (UInt32)(Int32)-1) numPasses = (level < 7 ? 1 : (level < 9 ? 3 : 10)); +} + +void CCoder::SetProps(const CEncProps *props2) +{ + CEncProps props = *props2; + props.Normalize(); + + m_MatchFinderCycles = props.mc; + { + unsigned fb = (unsigned)props.fb; + if (fb < kMatchMinLen) + fb = kMatchMinLen; + if (fb > m_MatchMaxLen) + fb = m_MatchMaxLen; + m_NumFastBytes = fb; + } + _fastMode = (props.algo == 0); + _btMode = (props.btMode != 0); + + m_NumDivPasses = props.numPasses; + if (m_NumDivPasses == 0) + m_NumDivPasses = 1; + if (m_NumDivPasses == 1) + m_NumPasses = 1; + else if (m_NumDivPasses <= kNumDivPassesMax) + m_NumPasses = 2; + else + { + m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax); + m_NumDivPasses = kNumDivPassesMax; + } +} + +CCoder::CCoder(bool deflate64Mode): + m_Values(NULL), + m_OnePosMatchesMemory(NULL), + m_DistanceMemory(NULL), + m_Created(false), + m_Deflate64Mode(deflate64Mode), + m_Tables(NULL) +{ + m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32; + m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32; + m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32; + m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32; + { + CEncProps props; + SetProps(&props); + } + MatchFinder_Construct(&_lzInWindow); +} + +HRESULT CCoder::Create() +{ + // COM_TRY_BEGIN + if (!m_Values) + { + m_Values = (CCodeValue *)MyAlloc(kMaxUncompressedBlockSize * sizeof(CCodeValue)); + if (!m_Values) + return E_OUTOFMEMORY; + } + if (!m_Tables) + { + m_Tables = (CTables *)MyAlloc(kNumTables * sizeof(CTables)); + if (!m_Tables) + return E_OUTOFMEMORY; + } + + if (m_IsMultiPass) + { + if (!m_OnePosMatchesMemory) + { + m_OnePosMatchesMemory = (UInt16 *)::MidAlloc(kMatchArraySize * sizeof(UInt16)); + if (!m_OnePosMatchesMemory) + return E_OUTOFMEMORY; + } + } + else + { + if (!m_DistanceMemory) + { + m_DistanceMemory = (UInt16 *)MyAlloc((kMatchMaxLen + 2) * 2 * sizeof(UInt16)); + if (!m_DistanceMemory) + return E_OUTOFMEMORY; + m_MatchDistances = m_DistanceMemory; + } + } + + if (!m_Created) + { + _lzInWindow.btMode = (Byte)(_btMode ? 1 : 0); + _lzInWindow.numHashBytes = 3; + _lzInWindow.numHashBytes_Min = 3; + if (!MatchFinder_Create(&_lzInWindow, + m_Deflate64Mode ? kHistorySize64 : kHistorySize32, + kNumOpts + kMaxUncompressedBlockSize, + m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes, &g_AlignedAlloc)) + return E_OUTOFMEMORY; + if (!m_OutStream.Create(1 << 20)) + return E_OUTOFMEMORY; + } + if (m_MatchFinderCycles != 0) + _lzInWindow.cutValue = m_MatchFinderCycles; + m_Created = true; + return S_OK; + // COM_TRY_END +} + +HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) +{ + CEncProps props; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize) + continue; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + UInt32 v = (UInt32)prop.ulVal; + switch (propID) + { + case NCoderPropID::kNumPasses: props.numPasses = v; break; + case NCoderPropID::kNumFastBytes: props.fb = (int)v; break; + case NCoderPropID::kMatchFinderCycles: props.mc = v; break; + case NCoderPropID::kAlgorithm: props.algo = (int)v; break; + case NCoderPropID::kLevel: props.Level = (int)v; break; + case NCoderPropID::kNumThreads: break; + default: return E_INVALIDARG; + } + } + SetProps(&props); + return S_OK; +} + +void CCoder::Free() +{ + ::MidFree(m_OnePosMatchesMemory); m_OnePosMatchesMemory = NULL; + ::MyFree(m_DistanceMemory); m_DistanceMemory = NULL; + ::MyFree(m_Values); m_Values = NULL; + ::MyFree(m_Tables); m_Tables = NULL; +} + +CCoder::~CCoder() +{ + Free(); + MatchFinder_Free(&_lzInWindow, &g_AlignedAlloc); +} + +NO_INLINE void CCoder::GetMatches() +{ + if (m_IsMultiPass) + { + m_MatchDistances = m_OnePosMatchesMemory + m_Pos; + if (m_SecondPass) + { + m_Pos += *m_MatchDistances + 1; + return; + } + } + + UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; + + const size_t numPairs = (size_t)((_btMode ? + Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp): + Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp)) - distanceTmp); + + UInt16 *matchDistances = m_MatchDistances; + *matchDistances++ = (UInt16)numPairs; + + if (numPairs != 0) + { + size_t i; + for (i = 0; i < numPairs; i += 2) + { + matchDistances[0] = (UInt16)distanceTmp[i]; + matchDistances[1] = (UInt16)distanceTmp[(size_t)i + 1]; + matchDistances += 2; + } + UInt32 len = distanceTmp[(size_t)numPairs - 2]; + if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen) + { + UInt32 numAvail = Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) + 1; + const Byte *pby = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - 1; + const Byte *pby2 = pby - (distanceTmp[(size_t)numPairs - 1] + 1); + if (numAvail > m_MatchMaxLen) + numAvail = m_MatchMaxLen; + for (; len < numAvail && pby[len] == pby2[len]; len++); + matchDistances[-2] = (UInt16)len; + } + } + if (m_IsMultiPass) + m_Pos += (UInt32)numPairs + 1; + if (!m_SecondPass) + m_AdditionalOffset++; +} + +void CCoder::MovePos(UInt32 num) +{ + if (!m_SecondPass && num > 0) + { + if (_btMode) + Bt3Zip_MatchFinder_Skip(&_lzInWindow, num); + else + Hc3Zip_MatchFinder_Skip(&_lzInWindow, num); + m_AdditionalOffset += num; + } +} + +static const UInt32 kIfinityPrice = 0xFFFFFFF; + +NO_INLINE UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur) +{ + m_OptimumEndIndex = cur; + UInt32 posMem = m_Optimum[cur].PosPrev; + UInt16 backMem = m_Optimum[cur].BackPrev; + do + { + UInt32 posPrev = posMem; + UInt16 backCur = backMem; + backMem = m_Optimum[posPrev].BackPrev; + posMem = m_Optimum[posPrev].PosPrev; + m_Optimum[posPrev].BackPrev = backCur; + m_Optimum[posPrev].PosPrev = (UInt16)cur; + cur = posPrev; + } + while (cur > 0); + backRes = m_Optimum[0].BackPrev; + m_OptimumCurrentIndex = m_Optimum[0].PosPrev; + return m_OptimumCurrentIndex; +} + +NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes) +{ + if (m_OptimumEndIndex != m_OptimumCurrentIndex) + { + UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex; + backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev; + m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev; + return len; + } + m_OptimumCurrentIndex = m_OptimumEndIndex = 0; + + GetMatches(); + + UInt32 lenEnd; + { + const UInt32 numDistancePairs = m_MatchDistances[0]; + if (numDistancePairs == 0) + return 1; + const UInt16 *matchDistances = m_MatchDistances + 1; + lenEnd = matchDistances[(size_t)numDistancePairs - 2]; + + if (lenEnd > m_NumFastBytes) + { + backRes = matchDistances[(size_t)numDistancePairs - 1]; + MovePos(lenEnd - 1); + return lenEnd; + } + + m_Optimum[1].Price = m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset)]; + m_Optimum[1].PosPrev = 0; + + m_Optimum[2].Price = kIfinityPrice; + m_Optimum[2].PosPrev = 1; + + UInt32 offs = 0; + + for (UInt32 i = kMatchMinLen; i <= lenEnd; i++) + { + UInt32 distance = matchDistances[(size_t)offs + 1]; + m_Optimum[i].PosPrev = 0; + m_Optimum[i].BackPrev = (UInt16)distance; + m_Optimum[i].Price = m_LenPrices[(size_t)i - kMatchMinLen] + m_PosPrices[GetPosSlot(distance)]; + if (i == matchDistances[offs]) + offs += 2; + } + } + + UInt32 cur = 0; + + for (;;) + { + ++cur; + if (cur == lenEnd || cur == kNumOptsBase || m_Pos >= kMatchArrayLimit) + return Backward(backRes, cur); + GetMatches(); + const UInt16 *matchDistances = m_MatchDistances + 1; + const UInt32 numDistancePairs = m_MatchDistances[0]; + UInt32 newLen = 0; + if (numDistancePairs != 0) + { + newLen = matchDistances[(size_t)numDistancePairs - 2]; + if (newLen > m_NumFastBytes) + { + UInt32 len = Backward(backRes, cur); + m_Optimum[cur].BackPrev = matchDistances[(size_t)numDistancePairs - 1]; + m_OptimumEndIndex = cur + newLen; + m_Optimum[cur].PosPrev = (UInt16)m_OptimumEndIndex; + MovePos(newLen - 1); + return len; + } + } + UInt32 curPrice = m_Optimum[cur].Price; + { + const UInt32 curAnd1Price = curPrice + m_LiteralPrices[*(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) + cur - m_AdditionalOffset)]; + COptimal &optimum = m_Optimum[(size_t)cur + 1]; + if (curAnd1Price < optimum.Price) + { + optimum.Price = curAnd1Price; + optimum.PosPrev = (UInt16)cur; + } + } + if (numDistancePairs == 0) + continue; + while (lenEnd < cur + newLen) + m_Optimum[++lenEnd].Price = kIfinityPrice; + UInt32 offs = 0; + UInt32 distance = matchDistances[(size_t)offs + 1]; + curPrice += m_PosPrices[GetPosSlot(distance)]; + for (UInt32 lenTest = kMatchMinLen; ; lenTest++) + { + UInt32 curAndLenPrice = curPrice + m_LenPrices[(size_t)lenTest - kMatchMinLen]; + COptimal &optimum = m_Optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = (UInt16)cur; + optimum.BackPrev = (UInt16)distance; + } + if (lenTest == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + curPrice -= m_PosPrices[GetPosSlot(distance)]; + distance = matchDistances[(size_t)offs + 1]; + curPrice += m_PosPrices[GetPosSlot(distance)]; + } + } + } +} + +UInt32 CCoder::GetOptimalFast(UInt32 &backRes) +{ + GetMatches(); + UInt32 numDistancePairs = m_MatchDistances[0]; + if (numDistancePairs == 0) + return 1; + UInt32 lenMain = m_MatchDistances[(size_t)numDistancePairs - 1]; + backRes = m_MatchDistances[numDistancePairs]; + MovePos(lenMain - 1); + return lenMain; +} + +void CTables::InitStructures() +{ + UInt32 i; + for (i = 0; i < 256; i++) + litLenLevels[i] = 8; + litLenLevels[i++] = 13; + for (;i < kFixedMainTableSize; i++) + litLenLevels[i] = 5; + for (i = 0; i < kFixedDistTableSize; i++) + distLevels[i] = 5; +} + +NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs) +{ + unsigned prevLen = 0xFF; + unsigned nextLen = levels[0]; + unsigned count = 0; + unsigned maxCount = 7; + unsigned minCount = 4; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + + for (unsigned n = 0; n < numLevels; n++) + { + unsigned curLen = nextLen; + nextLen = (n < numLevels - 1) ? levels[(size_t)n + 1] : 0xFF; + count++; + if (count < maxCount && curLen == nextLen) + continue; + + if (count < minCount) + freqs[curLen] += (UInt32)count; + else if (curLen != 0) + { + if (curLen != prevLen) + { + freqs[curLen]++; + count--; + } + freqs[kTableLevelRepNumber]++; + } + else if (count <= 10) + freqs[kTableLevel0Number]++; + else + freqs[kTableLevel0Number2]++; + + count = 0; + prevLen = curLen; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + else if (curLen == nextLen) + { + maxCount = 6; + minCount = 3; + } + else + { + maxCount = 7; + minCount = 4; + } + } +} + +NO_INLINE void CCoder::WriteBits(UInt32 value, unsigned numBits) +{ + m_OutStream.WriteBits(value, numBits); +} + +#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i]) +#define WRITE_HF2_NO_INLINE(codes, lens, i) WriteBits(codes[i], lens[i]) +#define WRITE_HF(i) WriteBits(codes[i], lens[i]) + +NO_INLINE void CCoder::LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes) +{ + unsigned prevLen = 0xFF; + unsigned nextLen = levels[0]; + unsigned count = 0; + unsigned maxCount = 7; + unsigned minCount = 4; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + + for (unsigned n = 0; n < numLevels; n++) + { + unsigned curLen = nextLen; + nextLen = (n < numLevels - 1) ? levels[(size_t)n + 1] : 0xFF; + count++; + if (count < maxCount && curLen == nextLen) + continue; + + if (count < minCount) + for (unsigned i = 0; i < count; i++) + WRITE_HF(curLen); + else if (curLen != 0) + { + if (curLen != prevLen) + { + WRITE_HF(curLen); + count--; + } + WRITE_HF(kTableLevelRepNumber); + WriteBits(count - 3, 2); + } + else if (count <= 10) + { + WRITE_HF(kTableLevel0Number); + WriteBits(count - 3, 3); + } + else + { + WRITE_HF(kTableLevel0Number2); + WriteBits(count - 11, 7); + } + + count = 0; + prevLen = curLen; + + if (nextLen == 0) + { + maxCount = 138; + minCount = 3; + } + else if (curLen == nextLen) + { + maxCount = 6; + minCount = 3; + } + else + { + maxCount = 7; + minCount = 4; + } + } +} + +NO_INLINE void CCoder::MakeTables(unsigned maxHuffLen) +{ + Huffman_Generate(mainFreqs, mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize, maxHuffLen); + Huffman_Generate(distFreqs, distCodes, m_NewLevels.distLevels, kDistTableSize64, maxHuffLen); +} + +static NO_INLINE UInt32 Huffman_GetPrice(const UInt32 *freqs, const Byte *lens, UInt32 num) +{ + UInt32 price = 0; + UInt32 i; + for (i = 0; i < num; i++) + price += lens[i] * freqs[i]; + return price; +} + +static NO_INLINE UInt32 Huffman_GetPrice_Spec( + const UInt32 *freqs, const Byte *lens, UInt32 num, + const Byte *extraBits, UInt32 extraBase) +{ + return + Huffman_GetPrice(freqs, lens, num) + + Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase); +} + +NO_INLINE UInt32 CCoder::GetLzBlockPrice() const +{ + return + Huffman_GetPrice_Spec(mainFreqs, m_NewLevels.litLenLevels, + kFixedMainTableSize, m_LenDirectBits, kSymbolMatch) + + Huffman_GetPrice_Spec(distFreqs, m_NewLevels.distLevels, + kDistTableSize64, kDistDirectBits, 0); +} + +NO_INLINE void CCoder::TryBlock() +{ + memset(mainFreqs, 0, sizeof(mainFreqs)); + memset(distFreqs, 0, sizeof(distFreqs)); + + m_ValueIndex = 0; + UInt32 blockSize = BlockSizeRes; + BlockSizeRes = 0; + for (;;) + { + if (m_OptimumCurrentIndex == m_OptimumEndIndex) + { + if (m_Pos >= kMatchArrayLimit + || BlockSizeRes >= blockSize + || (!m_SecondPass && ((Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0) || m_ValueIndex >= m_ValueBlockSize))) + break; + } + UInt32 pos; + UInt32 len; + if (_fastMode) + len = GetOptimalFast(pos); + else + len = GetOptimal(pos); + CCodeValue &codeValue = m_Values[m_ValueIndex++]; + if (len >= kMatchMinLen) + { + const UInt32 newLen = len - kMatchMinLen; + codeValue.Len = (UInt16)newLen; + mainFreqs[kSymbolMatch + (size_t)g_LenSlots[newLen]]++; + codeValue.Pos = (UInt16)pos; + distFreqs[GetPosSlot(pos)]++; + } + else + { + const unsigned b = *(Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow) - m_AdditionalOffset); + mainFreqs[b]++; + codeValue.Len = k_CodeValue_Len_Is_Literal_Flag; + codeValue.Pos = (UInt16)b; + } + m_AdditionalOffset -= len; + BlockSizeRes += len; + } + mainFreqs[kSymbolEndOfBlock]++; + m_AdditionalOffset += BlockSizeRes; + m_SecondPass = true; +} + +NO_INLINE void CCoder::SetPrices(const CLevels &levels) +{ + if (_fastMode) + return; + UInt32 i; + for (i = 0; i < 256; i++) + { + Byte price = levels.litLenLevels[i]; + m_LiteralPrices[i] = ((price != 0) ? price : kNoLiteralStatPrice); + } + + for (i = 0; i < m_NumLenCombinations; i++) + { + UInt32 slot = g_LenSlots[i]; + Byte price = levels.litLenLevels[kSymbolMatch + (size_t)slot]; + m_LenPrices[i] = (Byte)(((price != 0) ? price : kNoLenStatPrice) + m_LenDirectBits[slot]); + } + + for (i = 0; i < kDistTableSize64; i++) + { + Byte price = levels.distLevels[i]; + m_PosPrices[i] = (Byte)(((price != 0) ? price: kNoPosStatPrice) + kDistDirectBits[i]); + } +} + +#if MAX_HUF_LEN_12 > 12 +// Huffman_ReverseBits() now supports 12-bits values only. +#error Stop_Compiling_Bad_MAX_HUF_LEN_12 +#endif +static NO_INLINE void Huffman_ReverseBits(UInt32 *codes, const Byte *lens, UInt32 num) +{ + const Byte * const lens_lim = lens + num; + do + { + // we should change constants, if lens[*] can be larger than 12. + UInt32 x = *codes; + x = ((x & (0x555 )) << 2) + (x & (0xAAA )); + x = ((x & (0x333 << 1)) << 4) | (x & (0xCCC << 1)); + x = ((x & (0xF0F << 3)) << 8) | (x & (0x0F0 << 3)); + // we can use (x) instead of (x & (0xFF << 7)), if we support garabage data after (*lens) bits. + *codes++ = (((x & (0xFF << 7)) << 16) | x) >> (*lens ^ 31); + } + while (++lens != lens_lim); +} + +NO_INLINE void CCoder::WriteBlock() +{ + Huffman_ReverseBits(mainCodes, m_NewLevels.litLenLevels, kFixedMainTableSize); + Huffman_ReverseBits(distCodes, m_NewLevels.distLevels, kDistTableSize64); + + CCodeValue *values = m_Values; + const CCodeValue * const values_lim = values + m_ValueIndex; + + if (values != values_lim) + do + { + const UInt32 len = values->Len; + const UInt32 dist = values->Pos; + if (len == k_CodeValue_Len_Is_Literal_Flag) + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, dist); + else + { + const unsigned lenSlot = g_LenSlots[len]; + WRITE_HF2(mainCodes, m_NewLevels.litLenLevels, kSymbolMatch + lenSlot); + m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]); + const unsigned posSlot = GetPosSlot(dist); + WRITE_HF2(distCodes, m_NewLevels.distLevels, posSlot); + m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]); + } + } + while (++values != values_lim); + WRITE_HF2_NO_INLINE(mainCodes, m_NewLevels.litLenLevels, kSymbolEndOfBlock); +} + +static UInt32 GetStorePrice(UInt32 blockSize, unsigned bitPosition) +{ + UInt32 price = 0; + do + { + UInt32 nextBitPosition = (bitPosition + kFinalBlockFieldSize + kBlockTypeFieldSize) & 7; + unsigned numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0; + UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; + price += kFinalBlockFieldSize + kBlockTypeFieldSize + numBitsForAlign + (2 + 2) * 8 + curBlockSize * 8; + bitPosition = 0; + blockSize -= curBlockSize; + } + while (blockSize != 0); + return price; +} + +void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock) +{ + do + { + UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1; + blockSize -= curBlockSize; + WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); + WriteBits(NBlockType::kStored, kBlockTypeFieldSize); + m_OutStream.FlushByte(); + WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize); + WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize); + const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset; + for (UInt32 i = 0; i < curBlockSize; i++) + m_OutStream.WriteByte(data[i]); + additionalOffset -= curBlockSize; + } + while (blockSize != 0); +} + +NO_INLINE UInt32 CCoder::TryDynBlock(unsigned tableIndex, UInt32 numPasses) +{ + CTables &t = m_Tables[tableIndex]; + BlockSizeRes = t.BlockSizeRes; + UInt32 posTemp = t.m_Pos; + SetPrices(t); + + for (UInt32 p = 0; p < numPasses; p++) + { + m_Pos = posTemp; + TryBlock(); + const unsigned numHuffBits = + m_ValueIndex > 18000 ? MAX_HUF_LEN_12 : + m_ValueIndex > 7000 ? 11 : + m_ValueIndex > 2000 ? 10 : 9; + MakeTables(numHuffBits); + SetPrices(m_NewLevels); + } + + (CLevels &)t = m_NewLevels; + + m_NumLitLenLevels = kMainTableSize; + while (m_NumLitLenLevels > kNumLitLenCodesMin && m_NewLevels.litLenLevels[(size_t)m_NumLitLenLevels - 1] == 0) + m_NumLitLenLevels--; + + m_NumDistLevels = kDistTableSize64; + while (m_NumDistLevels > kNumDistCodesMin && m_NewLevels.distLevels[(size_t)m_NumDistLevels - 1] == 0) + m_NumDistLevels--; + + UInt32 levelFreqs[kLevelTableSize]; + memset(levelFreqs, 0, sizeof(levelFreqs)); + + LevelTableDummy(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelFreqs); + LevelTableDummy(m_NewLevels.distLevels, m_NumDistLevels, levelFreqs); + + Huffman_Generate(levelFreqs, levelCodes, levelLens, kLevelTableSize, kMaxLevelBitLength); + + m_NumLevelCodes = kNumLevelCodesMin; + for (UInt32 i = 0; i < kLevelTableSize; i++) + { + Byte level = levelLens[kCodeLengthAlphabetOrder[i]]; + if (level > 0 && i >= m_NumLevelCodes) + m_NumLevelCodes = i + 1; + m_LevelLevels[i] = level; + } + + return GetLzBlockPrice() + + Huffman_GetPrice_Spec(levelFreqs, levelLens, kLevelTableSize, kLevelDirectBits, kTableDirectLevels) + + kNumLenCodesFieldSize + kNumDistCodesFieldSize + kNumLevelCodesFieldSize + + m_NumLevelCodes * kLevelFieldSize + kFinalBlockFieldSize + kBlockTypeFieldSize; +} + +NO_INLINE UInt32 CCoder::TryFixedBlock(unsigned tableIndex) +{ + CTables &t = m_Tables[tableIndex]; + BlockSizeRes = t.BlockSizeRes; + m_Pos = t.m_Pos; + m_NewLevels.SetFixedLevels(); + SetPrices(m_NewLevels); + TryBlock(); + return kFinalBlockFieldSize + kBlockTypeFieldSize + GetLzBlockPrice(); +} + +NO_INLINE UInt32 CCoder::GetBlockPrice(unsigned tableIndex, unsigned numDivPasses) +{ + CTables &t = m_Tables[tableIndex]; + t.StaticMode = false; + UInt32 price = TryDynBlock(tableIndex, m_NumPasses); + t.BlockSizeRes = BlockSizeRes; + UInt32 numValues = m_ValueIndex; + UInt32 posTemp = m_Pos; + UInt32 additionalOffsetEnd = m_AdditionalOffset; + + if (m_CheckStatic && m_ValueIndex <= kFixedHuffmanCodeBlockSizeMax) + { + const UInt32 fixedPrice = TryFixedBlock(tableIndex); + t.StaticMode = (fixedPrice < price); + if (t.StaticMode) + price = fixedPrice; + } + + const UInt32 storePrice = GetStorePrice(BlockSizeRes, 0); // bitPosition + t.StoreMode = (storePrice <= price); + if (t.StoreMode) + price = storePrice; + + t.UseSubBlocks = false; + + if (numDivPasses > 1 && numValues >= kDivideCodeBlockSizeMin) + { + CTables &t0 = m_Tables[(tableIndex << 1)]; + (CLevels &)t0 = t; + t0.BlockSizeRes = t.BlockSizeRes >> 1; + t0.m_Pos = t.m_Pos; + UInt32 subPrice = GetBlockPrice((tableIndex << 1), numDivPasses - 1); + + UInt32 blockSize2 = t.BlockSizeRes - t0.BlockSizeRes; + if (t0.BlockSizeRes >= kDivideBlockSizeMin && blockSize2 >= kDivideBlockSizeMin) + { + CTables &t1 = m_Tables[(tableIndex << 1) + 1]; + (CLevels &)t1 = t; + t1.BlockSizeRes = blockSize2; + t1.m_Pos = m_Pos; + m_AdditionalOffset -= t0.BlockSizeRes; + subPrice += GetBlockPrice((tableIndex << 1) + 1, numDivPasses - 1); + t.UseSubBlocks = (subPrice < price); + if (t.UseSubBlocks) + price = subPrice; + } + } + + m_AdditionalOffset = additionalOffsetEnd; + m_Pos = posTemp; + return price; +} + +void CCoder::CodeBlock(unsigned tableIndex, bool finalBlock) +{ + CTables &t = m_Tables[tableIndex]; + if (t.UseSubBlocks) + { + CodeBlock((tableIndex << 1), false); + CodeBlock((tableIndex << 1) + 1, finalBlock); + } + else + { + if (t.StoreMode) + WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock); + else + { + WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize); + if (t.StaticMode) + { + WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize); + TryFixedBlock(tableIndex); + unsigned i; + const unsigned kMaxStaticHuffLen = 9; + for (i = 0; i < kFixedMainTableSize; i++) + mainFreqs[i] = (UInt32)1 << (kMaxStaticHuffLen - m_NewLevels.litLenLevels[i]); + for (i = 0; i < kFixedDistTableSize; i++) + distFreqs[i] = (UInt32)1 << (kMaxStaticHuffLen - m_NewLevels.distLevels[i]); + MakeTables(kMaxStaticHuffLen); + } + else + { + if (m_NumDivPasses > 1 || m_CheckStatic) + TryDynBlock(tableIndex, 1); + WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize); + WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize); + WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize); + WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize); + + for (UInt32 i = 0; i < m_NumLevelCodes; i++) + WriteBits(m_LevelLevels[i], kLevelFieldSize); + + Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize); + LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes); + LevelTableCode(m_NewLevels.distLevels, m_NumDistLevels, levelLens, levelCodes); + } + WriteBlock(); + } + m_AdditionalOffset -= t.BlockSizeRes; + } +} + + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */ , const UInt64 * /* outSize */ , ICompressProgressInfo *progress) +{ + m_CheckStatic = (m_NumPasses != 1 || m_NumDivPasses != 1); + m_IsMultiPass = (m_CheckStatic || (m_NumPasses != 1 || m_NumDivPasses != 1)); + + /* we can set stream mode before MatchFinder_Create + if default MatchFinder mode was not STREAM_MODE) */ + // MatchFinder_SET_STREAM_MODE(&_lzInWindow); + + CSeqInStreamWrap _seqInStream; + _seqInStream.Init(inStream); + MatchFinder_SET_STREAM(&_lzInWindow, &_seqInStream.vt) + + RINOK(Create()) + + m_ValueBlockSize = (7 << 10) + (1 << 12) * m_NumDivPasses; + + UInt64 nowPos = 0; + + MatchFinder_Init(&_lzInWindow); + m_OutStream.SetStream(outStream); + m_OutStream.Init(); + + m_OptimumEndIndex = m_OptimumCurrentIndex = 0; + + CTables &t = m_Tables[1]; + t.m_Pos = 0; + t.InitStructures(); + + m_AdditionalOffset = 0; + do + { + t.BlockSizeRes = kBlockUncompressedSizeThreshold; + m_SecondPass = false; + GetBlockPrice(1, m_NumDivPasses); + CodeBlock(1, Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) == 0); + nowPos += m_Tables[1].BlockSizeRes; + if (progress != NULL) + { + UInt64 packSize = m_OutStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&nowPos, &packSize)) + } + } + while (Inline_MatchFinder_GetNumAvailableBytes(&_lzInWindow) != 0); + + if (_seqInStream.Res != S_OK) + return _seqInStream.Res; + + if (_lzInWindow.result != SZ_OK) + return SResToHRESULT(_lzInWindow.result); + return m_OutStream.Flush(); +} + +HRESULT CCoder::BaseCode(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return E_FAIL; } +} + +Z7_COM7F_IMF(CCOMCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) + { return BaseCode(inStream, outStream, inSize, outSize, progress); } + +Z7_COM7F_IMF(CCOMCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) + { return BaseSetEncoderProperties2(propIDs, props, numProps); } + +Z7_COM7F_IMF(CCOMCoder64::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) + { return BaseCode(inStream, outStream, inSize, outSize, progress); } + +Z7_COM7F_IMF(CCOMCoder64::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) + { return BaseSetEncoderProperties2(propIDs, props, numProps); } + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateEncoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,216 +1,203 @@ -// DeflateEncoder.h - -#ifndef __DEFLATE_ENCODER_H -#define __DEFLATE_ENCODER_H - -#include "../../../C/LzFind.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "BitlEncoder.h" -#include "DeflateConst.h" - -namespace NCompress { -namespace NDeflate { -namespace NEncoder { - -struct CCodeValue -{ - UInt16 Len; - UInt16 Pos; - void SetAsLiteral() { Len = (1 << 15); } - bool IsLiteral() const { return (Len >= (1 << 15)); } -}; - -struct COptimal -{ - UInt32 Price; - UInt16 PosPrev; - UInt16 BackPrev; -}; - -const UInt32 kNumOptsBase = 1 << 12; -const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen; - -class CCoder; - -struct CTables: public CLevels -{ - bool UseSubBlocks; - bool StoreMode; - bool StaticMode; - UInt32 BlockSizeRes; - UInt32 m_Pos; - void InitStructures(); -}; - -typedef struct _CSeqInStream -{ - ISeqInStream SeqInStream; - ISequentialInStream *RealStream; -} CSeqInStream; - -struct CEncProps -{ - int Level; - int algo; - int fb; - int btMode; - UInt32 mc; - UInt32 numPasses; - - CEncProps() - { - Level = -1; - mc = 0; - algo = fb = btMode = -1; - numPasses = (UInt32)(Int32)-1; - } - void Normalize(); -}; - -class CCoder -{ - CMatchFinder _lzInWindow; - CBitlEncoder m_OutStream; - - CSeqInStream _seqInStream; - -public: - CCodeValue *m_Values; - - UInt16 *m_MatchDistances; - UInt32 m_NumFastBytes; - bool _fastMode; - bool _btMode; - - UInt16 *m_OnePosMatchesMemory; - UInt16 *m_DistanceMemory; - - UInt32 m_Pos; - - unsigned m_NumPasses; - unsigned m_NumDivPasses; - bool m_CheckStatic; - bool m_IsMultiPass; - UInt32 m_ValueBlockSize; - - UInt32 m_NumLenCombinations; - UInt32 m_MatchMaxLen; - const Byte *m_LenStart; - const Byte *m_LenDirectBits; - - bool m_Created; - bool m_Deflate64Mode; - - Byte m_LevelLevels[kLevelTableSize]; - unsigned m_NumLitLenLevels; - unsigned m_NumDistLevels; - UInt32 m_NumLevelCodes; - UInt32 m_ValueIndex; - - bool m_SecondPass; - UInt32 m_AdditionalOffset; - - UInt32 m_OptimumEndIndex; - UInt32 m_OptimumCurrentIndex; - - Byte m_LiteralPrices[256]; - Byte m_LenPrices[kNumLenSymbolsMax]; - Byte m_PosPrices[kDistTableSize64]; - - CLevels m_NewLevels; - UInt32 mainFreqs[kFixedMainTableSize]; - UInt32 distFreqs[kDistTableSize64]; - UInt32 mainCodes[kFixedMainTableSize]; - UInt32 distCodes[kDistTableSize64]; - UInt32 levelCodes[kLevelTableSize]; - Byte levelLens[kLevelTableSize]; - - UInt32 BlockSizeRes; - - CTables *m_Tables; - COptimal m_Optimum[kNumOpts]; - - UInt32 m_MatchFinderCycles; - - void GetMatches(); - void MovePos(UInt32 num); - UInt32 Backward(UInt32 &backRes, UInt32 cur); - UInt32 GetOptimal(UInt32 &backRes); - UInt32 GetOptimalFast(UInt32 &backRes); - - void LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs); - - void WriteBits(UInt32 value, unsigned numBits); - void LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes); - - void MakeTables(unsigned maxHuffLen); - UInt32 GetLzBlockPrice() const; - void TryBlock(); - UInt32 TryDynBlock(unsigned tableIndex, UInt32 numPasses); - - UInt32 TryFixedBlock(unsigned tableIndex); - - void SetPrices(const CLevels &levels); - void WriteBlock(); - - HRESULT Create(); - void Free(); - - void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock); - void WriteTables(bool writeMode, bool finalBlock); - - void WriteBlockData(bool writeMode, bool finalBlock); - - UInt32 GetBlockPrice(unsigned tableIndex, unsigned numDivPasses); - void CodeBlock(unsigned tableIndex, bool finalBlock); - - void SetProps(const CEncProps *props2); -public: - CCoder(bool deflate64Mode = false); - ~CCoder(); - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - HRESULT BaseCode(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); -}; - - -class CCOMCoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public CMyUnknownImp, - public CCoder -{ -public: - MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties) - CCOMCoder(): CCoder(false) {}; - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); -}; - -class CCOMCoder64 : - public ICompressCoder, - public ICompressSetCoderProperties, - public CMyUnknownImp, - public CCoder -{ -public: - MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties) - CCOMCoder64(): CCoder(true) {}; - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); -}; - -}}} - -#endif +// DeflateEncoder.h + +#ifndef ZIP7_INC_DEFLATE_ENCODER_H +#define ZIP7_INC_DEFLATE_ENCODER_H + +#include "../../../C/LzFind.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "BitlEncoder.h" +#include "DeflateConst.h" + +namespace NCompress { +namespace NDeflate { +namespace NEncoder { + +struct CCodeValue +{ + UInt16 Len; + UInt16 Pos; + void SetAsLiteral() { Len = (1 << 15); } + bool IsLiteral() const { return (Len >= (1 << 15)); } +}; + +struct COptimal +{ + UInt32 Price; + UInt16 PosPrev; + UInt16 BackPrev; +}; + +const UInt32 kNumOptsBase = 1 << 12; +const UInt32 kNumOpts = kNumOptsBase + kMatchMaxLen; + +class CCoder; + +struct CTables: public CLevels +{ + bool UseSubBlocks; + bool StoreMode; + bool StaticMode; + UInt32 BlockSizeRes; + UInt32 m_Pos; + void InitStructures(); +}; + + +struct CEncProps +{ + int Level; + int algo; + int fb; + int btMode; + UInt32 mc; + UInt32 numPasses; + + CEncProps() + { + Level = -1; + mc = 0; + algo = fb = btMode = -1; + numPasses = (UInt32)(Int32)-1; + } + void Normalize(); +}; + +class CCoder +{ + CMatchFinder _lzInWindow; + CBitlEncoder m_OutStream; + +public: + CCodeValue *m_Values; + + UInt16 *m_MatchDistances; + UInt32 m_NumFastBytes; + bool _fastMode; + bool _btMode; + + UInt16 *m_OnePosMatchesMemory; + UInt16 *m_DistanceMemory; + + UInt32 m_Pos; + + unsigned m_NumPasses; + unsigned m_NumDivPasses; + bool m_CheckStatic; + bool m_IsMultiPass; + UInt32 m_ValueBlockSize; + + UInt32 m_NumLenCombinations; + UInt32 m_MatchMaxLen; + const Byte *m_LenStart; + const Byte *m_LenDirectBits; + + bool m_Created; + bool m_Deflate64Mode; + + Byte m_LevelLevels[kLevelTableSize]; + unsigned m_NumLitLenLevels; + unsigned m_NumDistLevels; + UInt32 m_NumLevelCodes; + UInt32 m_ValueIndex; + + bool m_SecondPass; + UInt32 m_AdditionalOffset; + + UInt32 m_OptimumEndIndex; + UInt32 m_OptimumCurrentIndex; + + Byte m_LiteralPrices[256]; + Byte m_LenPrices[kNumLenSymbolsMax]; + Byte m_PosPrices[kDistTableSize64]; + + CLevels m_NewLevels; + UInt32 mainFreqs[kFixedMainTableSize]; + UInt32 distFreqs[kDistTableSize64]; + UInt32 mainCodes[kFixedMainTableSize]; + UInt32 distCodes[kDistTableSize64]; + UInt32 levelCodes[kLevelTableSize]; + Byte levelLens[kLevelTableSize]; + + UInt32 BlockSizeRes; + + CTables *m_Tables; + COptimal m_Optimum[kNumOpts]; + + UInt32 m_MatchFinderCycles; + + void GetMatches(); + void MovePos(UInt32 num); + UInt32 Backward(UInt32 &backRes, UInt32 cur); + UInt32 GetOptimal(UInt32 &backRes); + UInt32 GetOptimalFast(UInt32 &backRes); + + void LevelTableDummy(const Byte *levels, unsigned numLevels, UInt32 *freqs); + + void WriteBits(UInt32 value, unsigned numBits); + void LevelTableCode(const Byte *levels, unsigned numLevels, const Byte *lens, const UInt32 *codes); + + void MakeTables(unsigned maxHuffLen); + UInt32 GetLzBlockPrice() const; + void TryBlock(); + UInt32 TryDynBlock(unsigned tableIndex, UInt32 numPasses); + + UInt32 TryFixedBlock(unsigned tableIndex); + + void SetPrices(const CLevels &levels); + void WriteBlock(); + + HRESULT Create(); + void Free(); + + void WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool finalBlock); + void WriteTables(bool writeMode, bool finalBlock); + + void WriteBlockData(bool writeMode, bool finalBlock); + + UInt32 GetBlockPrice(unsigned tableIndex, unsigned numDivPasses); + void CodeBlock(unsigned tableIndex, bool finalBlock); + + void SetProps(const CEncProps *props2); +public: + CCoder(bool deflate64Mode = false); + ~CCoder(); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + HRESULT BaseCode(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); +}; + + +class CCOMCoder Z7_final: + public ICompressCoder, + public ICompressSetCoderProperties, + public CMyUnknownImp, + public CCoder +{ + Z7_IFACES_IMP_UNK_2(ICompressCoder, ICompressSetCoderProperties) +public: + CCOMCoder(): CCoder(false) {} +}; + +class CCOMCoder64 Z7_final: + public ICompressCoder, + public ICompressSetCoderProperties, + public CMyUnknownImp, + public CCoder +{ + Z7_IFACES_IMP_UNK_2(ICompressCoder, ICompressSetCoderProperties) +public: + CCOMCoder64(): CCoder(true) {} +}; + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeflateRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DeflateRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeflateRegister.cpp 2023-03-28 10:00:00.000000000 +0000 @@ -1,25 +1,25 @@ -// DeflateRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "DeflateDecoder.h" -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) -#include "DeflateEncoder.h" -#endif - -namespace NCompress { -namespace NDeflate { - -REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder) - -#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) -REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder) -#else -#define CreateEnc NULL -#endif - -REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate") - -}} +// DeflateRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "DeflateDecoder.h" +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) +#include "DeflateEncoder.h" +#endif + +namespace NCompress { +namespace NDeflate { + +REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder) + +#if !defined(Z7_EXTRACT_ONLY) && !defined(Z7_DEFLATE_EXTRACT_ONLY) +REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder) +#else +#define CreateEnc NULL +#endif + +REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DeltaFilter.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeltaFilter.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DeltaFilter.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DeltaFilter.cpp 2024-01-01 18:00:00.000000000 +0000 @@ -1,128 +1,126 @@ -// DeltaFilter.cpp - -#include "StdAfx.h" - -#include "../../../C/Delta.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/RegisterCodec.h" - -namespace NCompress { -namespace NDelta { - -struct CDelta -{ - unsigned _delta; - Byte _state[DELTA_STATE_SIZE]; - - CDelta(): _delta(1) {} - void DeltaInit() { Delta_Init(_state); } -}; - - -#ifndef EXTRACT_ONLY - -class CEncoder: - public ICompressFilter, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - CDelta, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); -}; - -STDMETHODIMP CEncoder::Init() -{ - DeltaInit(); - return S_OK; -} - -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) -{ - Delta_Encode(_state, _delta, data, size); - return size; -} - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) -{ - UInt32 delta = _delta; - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = props[i]; - PROPID propID = propIDs[i]; - if (propID >= NCoderPropID::kReduceSize) - continue; - if (prop.vt != VT_UI4) - return E_INVALIDARG; - switch (propID) - { - case NCoderPropID::kDefaultProp: - delta = (UInt32)prop.ulVal; - if (delta < 1 || delta > 256) - return E_INVALIDARG; - break; - case NCoderPropID::kNumThreads: break; - case NCoderPropID::kLevel: break; - default: return E_INVALIDARG; - } - } - _delta = delta; - return S_OK; -} - -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) -{ - Byte prop = (Byte)(_delta - 1); - return outStream->Write(&prop, 1, NULL); -} - -#endif - - -class CDecoder: - public ICompressFilter, - public ICompressSetDecoderProperties2, - CDelta, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2) - INTERFACE_ICompressFilter(;) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); -}; - -STDMETHODIMP CDecoder::Init() -{ - DeltaInit(); - return S_OK; -} - -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) -{ - Delta_Decode(_state, _delta, data, size); - return size; -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) -{ - if (size != 1) - return E_INVALIDARG; - _delta = (unsigned)props[0] + 1; - return S_OK; -} - - -REGISTER_FILTER_E(Delta, - CDecoder(), - CEncoder(), - 3, "Delta") - -}} +// DeltaFilter.cpp + +#include "StdAfx.h" + +#include "../../../C/Delta.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/RegisterCodec.h" + +namespace NCompress { +namespace NDelta { + +struct CDelta +{ + unsigned _delta; + Byte _state[DELTA_STATE_SIZE]; + + CDelta(): _delta(1) {} + void DeltaInit() { Delta_Init(_state); } +}; + + +#ifndef Z7_EXTRACT_ONLY + +class CEncoder Z7_final: + public ICompressFilter, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public CMyUnknownImp, + CDelta +{ + Z7_IFACES_IMP_UNK_3( + ICompressFilter, + ICompressSetCoderProperties, + ICompressWriteCoderProperties) +}; + +Z7_COM7F_IMF(CEncoder::Init()) +{ + DeltaInit(); + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) +{ + Delta_Encode(_state, _delta, data, size); + return size; +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +{ + unsigned delta = _delta; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = props[i]; + const PROPID propID = propIDs[i]; + if (propID >= NCoderPropID::kReduceSize) + continue; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + switch (propID) + { + case NCoderPropID::kDefaultProp: + if (prop.ulVal < 1 || prop.ulVal > 256) + return E_INVALIDARG; + delta = prop.ulVal; + break; + case NCoderPropID::kNumThreads: break; + case NCoderPropID::kLevel: break; + default: return E_INVALIDARG; + } + } + _delta = delta; + return S_OK; +} + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + const Byte prop = (Byte)(_delta - 1); + return outStream->Write(&prop, 1, NULL); +} + +#endif + + +class CDecoder Z7_final: + public ICompressFilter, + public ICompressSetDecoderProperties2, + public CMyUnknownImp, + CDelta +{ + Z7_IFACES_IMP_UNK_2( + ICompressFilter, + ICompressSetDecoderProperties2) +}; + +Z7_COM7F_IMF(CDecoder::Init()) +{ + DeltaInit(); + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + Delta_Decode(_state, _delta, data, size); + return size; +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) +{ + if (size != 1) + return E_INVALIDARG; + _delta = (unsigned)props[0] + 1; + return S_OK; +} + + +REGISTER_FILTER_E(Delta, + CDecoder(), + CEncoder(), + 3, "Delta") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DllExports2Compress.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExports2Compress.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DllExports2Compress.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExports2Compress.cpp 2024-05-22 10:00:00.000000000 +0000 @@ -1,28 +1,38 @@ -// DllExports2Compress.cpp - -#include "StdAfx.h" - -#include "../../Common/MyInitGuid.h" - -#include "../ICoder.h" - -#include "../Common/RegisterCodec.h" - -extern "C" -BOOL WINAPI DllMain( - #ifdef UNDER_CE - HANDLE - #else - HINSTANCE - #endif - /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) -{ - return TRUE; -} - -STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); - -STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) -{ - return CreateCoder(clsid, iid, outObject); -} +// DllExports2Compress.cpp + +#include "StdAfx.h" + +#include "../../Common/MyInitGuid.h" + +#include "../ICoder.h" + +#include "../Common/RegisterCodec.h" + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + return CreateCoder(clsid, iid, outObject); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/DllExportsCompress.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExportsCompress.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/DllExportsCompress.cpp 2015-06-21 08:09:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/DllExportsCompress.cpp 2021-03-06 09:45:36.000000000 +0000 @@ -1,48 +1,59 @@ -// DllExportsCompress.cpp - -#include "StdAfx.h" - -#include "../../Common/MyInitGuid.h" - -#include "../ICoder.h" - -#include "../Common/RegisterCodec.h" - -static const unsigned kNumCodecsMax = 48; -unsigned g_NumCodecs = 0; -const CCodecInfo *g_Codecs[kNumCodecsMax]; -void RegisterCodec(const CCodecInfo *codecInfo) throw() -{ - if (g_NumCodecs < kNumCodecsMax) - g_Codecs[g_NumCodecs++] = codecInfo; -} - -static const unsigned kNumHashersMax = 16; -unsigned g_NumHashers = 0; -const CHasherInfo *g_Hashers[kNumHashersMax]; -void RegisterHasher(const CHasherInfo *hashInfo) throw() -{ - if (g_NumHashers < kNumHashersMax) - g_Hashers[g_NumHashers++] = hashInfo; -} - -#ifdef _WIN32 -extern "C" -BOOL WINAPI DllMain( - #ifdef UNDER_CE - HANDLE - #else - HINSTANCE - #endif - , DWORD /* dwReason */, LPVOID /*lpReserved*/) -{ - return TRUE; -} -#endif - -STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); - -STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) -{ - return CreateCoder(clsid, iid, outObject); -} +// DllExportsCompress.cpp + +#include "StdAfx.h" + +#include "../../Common/MyInitGuid.h" + +#include "../ICoder.h" + +#include "../Common/RegisterCodec.h" + +static const unsigned kNumCodecsMax = 48; +unsigned g_NumCodecs = 0; +const CCodecInfo *g_Codecs[kNumCodecsMax]; +void RegisterCodec(const CCodecInfo *codecInfo) throw() +{ + if (g_NumCodecs < kNumCodecsMax) + g_Codecs[g_NumCodecs++] = codecInfo; +} + +static const unsigned kNumHashersMax = 16; +unsigned g_NumHashers = 0; +const CHasherInfo *g_Hashers[kNumHashersMax]; +void RegisterHasher(const CHasherInfo *hashInfo) throw() +{ + if (g_NumHashers < kNumHashersMax) + g_Hashers[g_NumHashers++] = hashInfo; +} + +#ifdef _WIN32 + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + , DWORD /* dwReason */, LPVOID /*lpReserved*/); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + , DWORD /* dwReason */, LPVOID /*lpReserved*/) +{ + return TRUE; +} +#endif + +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject); + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject); +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + return CreateCoder(clsid, iid, outObject); +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/HuffmanDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/HuffmanDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/HuffmanDecoder.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/HuffmanDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,260 +1,527 @@ -// Compress/HuffmanDecoder.h - -#ifndef __COMPRESS_HUFFMAN_DECODER_H -#define __COMPRESS_HUFFMAN_DECODER_H - -#include "../../Common/MyTypes.h" - -namespace NCompress { -namespace NHuffman { - -template -class CDecoder -{ - UInt32 _limits[kNumBitsMax + 2]; - UInt32 _poses[kNumBitsMax + 1]; - UInt16 _lens[1 << kNumTableBits]; - UInt16 _symbols[m_NumSymbols]; -public: - - bool Build(const Byte *lens) throw() - { - UInt32 lenCounts[kNumBitsMax + 1]; - UInt32 tmpPoses[kNumBitsMax + 1]; - - unsigned i; - for (i = 0; i <= kNumBitsMax; i++) - lenCounts[i] = 0; - - UInt32 sym; - - for (sym = 0; sym < m_NumSymbols; sym++) - lenCounts[lens[sym]]++; - - lenCounts[0] = 0; - _poses[0] = 0; - _limits[0] = 0; - UInt32 startPos = 0; - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - - for (i = 1; i <= kNumBitsMax; i++) - { - startPos += lenCounts[i] << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; - _limits[i] = startPos; - _poses[i] = _poses[i - 1] + lenCounts[i - 1]; - tmpPoses[i] = _poses[i]; - } - - _limits[kNumBitsMax + 1] = kMaxValue; - - for (sym = 0; sym < m_NumSymbols; sym++) - { - unsigned len = lens[sym]; - if (len == 0) - continue; - - unsigned offset = tmpPoses[len]; - _symbols[offset] = (UInt16)sym; - tmpPoses[len] = offset + 1; - - if (len <= kNumTableBits) - { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumTableBits - len); - UInt16 val = (UInt16)((sym << 4) | len); - UInt16 *dest = _lens + (_limits[len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; - } - } - - return true; - } - - bool BuildFull(const Byte *lens, UInt32 numSymbols = m_NumSymbols) throw() - { - UInt32 lenCounts[kNumBitsMax + 1]; - UInt32 tmpPoses[kNumBitsMax + 1]; - - unsigned i; - for (i = 0; i <= kNumBitsMax; i++) - lenCounts[i] = 0; - - UInt32 sym; - - for (sym = 0; sym < numSymbols; sym++) - lenCounts[lens[sym]]++; - - lenCounts[0] = 0; - _poses[0] = 0; - _limits[0] = 0; - UInt32 startPos = 0; - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - - for (i = 1; i <= kNumBitsMax; i++) - { - startPos += lenCounts[i] << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; - _limits[i] = startPos; - _poses[i] = _poses[i - 1] + lenCounts[i - 1]; - tmpPoses[i] = _poses[i]; - } - - _limits[kNumBitsMax + 1] = kMaxValue; - - for (sym = 0; sym < numSymbols; sym++) - { - unsigned len = lens[sym]; - if (len == 0) - continue; - - unsigned offset = tmpPoses[len]; - _symbols[offset] = (UInt16)sym; - tmpPoses[len] = offset + 1; - - if (len <= kNumTableBits) - { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumTableBits - len); - UInt16 val = (UInt16)((sym << 4) | len); - UInt16 *dest = _lens + (_limits[len - 1] >> (kNumBitsMax - kNumTableBits)) + (offset << (kNumTableBits - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; - } - } - - return startPos == kMaxValue; - } - - template - UInt32 Decode(TBitDecoder *bitStream) const throw() - { - UInt32 val = bitStream->GetValue(kNumBitsMax); - - if (val < _limits[kNumTableBits]) - { - UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)]; - bitStream->MovePos((unsigned)(pair & 0xF)); - return pair >> 4; - } - - unsigned numBits; - for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++); - - if (numBits > kNumBitsMax) - return 0xFFFFFFFF; - - bitStream->MovePos(numBits); - UInt32 index = _poses[numBits] + ((val - _limits[numBits - 1]) >> (kNumBitsMax - numBits)); - return _symbols[index]; - } - - template - UInt32 DecodeFull(TBitDecoder *bitStream) const throw() - { - UInt32 val = bitStream->GetValue(kNumBitsMax); - - if (val < _limits[kNumTableBits]) - { - UInt32 pair = _lens[val >> (kNumBitsMax - kNumTableBits)]; - bitStream->MovePos((unsigned)(pair & 0xF)); - return pair >> 4; - } - - unsigned numBits; - for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++); - - bitStream->MovePos(numBits); - UInt32 index = _poses[numBits] + ((val - _limits[numBits - 1]) >> (kNumBitsMax - numBits)); - return _symbols[index]; - } -}; - - - -template -class CDecoder7b -{ - Byte _lens[1 << 7]; -public: - - bool Build(const Byte *lens) throw() - { - const unsigned kNumBitsMax = 7; - - UInt32 lenCounts[kNumBitsMax + 1]; - UInt32 tmpPoses[kNumBitsMax + 1]; - UInt32 _poses[kNumBitsMax + 1]; - UInt32 _limits[kNumBitsMax + 1]; - - unsigned i; - for (i = 0; i <= kNumBitsMax; i++) - lenCounts[i] = 0; - - UInt32 sym; - - for (sym = 0; sym < m_NumSymbols; sym++) - lenCounts[lens[sym]]++; - - lenCounts[0] = 0; - _poses[0] = 0; - _limits[0] = 0; - UInt32 startPos = 0; - const UInt32 kMaxValue = (UInt32)1 << kNumBitsMax; - - for (i = 1; i <= kNumBitsMax; i++) - { - startPos += lenCounts[i] << (kNumBitsMax - i); - if (startPos > kMaxValue) - return false; - _limits[i] = startPos; - _poses[i] = _poses[i - 1] + lenCounts[i - 1]; - tmpPoses[i] = _poses[i]; - } - - for (sym = 0; sym < m_NumSymbols; sym++) - { - unsigned len = lens[sym]; - if (len == 0) - continue; - - unsigned offset = tmpPoses[len]; - tmpPoses[len] = offset + 1; - - { - offset -= _poses[len]; - UInt32 num = (UInt32)1 << (kNumBitsMax - len); - Byte val = (Byte)((sym << 3) | len); - Byte *dest = _lens + (_limits[len - 1]) + (offset << (kNumBitsMax - len)); - for (UInt32 k = 0; k < num; k++) - dest[k] = val; - } - } - - { - UInt32 limit = _limits[kNumBitsMax]; - UInt32 num = ((UInt32)1 << kNumBitsMax) - limit; - Byte *dest = _lens + limit; - for (UInt32 k = 0; k < num; k++) - dest[k] = (Byte)(0x1F << 3); - } - - return true; - } - - template - UInt32 Decode(TBitDecoder *bitStream) const throw() - { - UInt32 val = bitStream->GetValue(7); - UInt32 pair = _lens[val]; - bitStream->MovePos((unsigned)(pair & 0x7)); - return pair >> 3; - } -}; - -}} - -#endif +// Compress/HuffmanDecoder.h + +#ifndef ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H +#define ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H + +#include "../../../C/CpuArch.h" +#include "../../Common/MyTypes.h" + +namespace NCompress { +namespace NHuffman { + +// const unsigned kNumTableBits_Default = 9; + +#if 0 || 0 && defined(MY_CPU_64BIT) +// for debug or optimization: +// 64-BIT limit array can be faster for some compilers. +// for debug or optimization: +#define Z7_HUFF_USE_64BIT_LIMIT +#else +// sizet value variable allows to eliminate some move operation in some compilers. +// for debug or optimization: +// #define Z7_HUFF_USE_SIZET_VALUE +#endif + +// v0 must normalized to (32 bits) : (v0 < ((UInt64)1 << 32)) + +#ifdef Z7_HUFF_USE_64BIT_LIMIT + typedef UInt64 CLimitInt; + typedef UInt64 CValueInt; + // all _limits[*] are normalized and limited by ((UInt64)1 << 32). + // we don't use (v1) in this branch + #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) 32 + #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \ + ((NCompress::NHuffman::CLimitInt)v0 >= (huf)->_limits[0]) + #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits) (v0) + #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits) ((v0) >> (32 - kNumTableBits)) + #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1) +#else + typedef UInt32 CLimitInt; + typedef + #ifdef Z7_HUFF_USE_SIZET_VALUE + size_t + #else + UInt32 + #endif + CValueInt; + // v1 must be precalculated from v0 in this branch + // _limits[0] and (v1) are normalized and limited by (1 << kNumTableBits). + // _limits[non_0] are normalized and limited by (1 << kNumBitsMax). + #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) (kNumBitsMax) + #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \ + ((NCompress::NHuffman::CLimitInt)v1 >= (huf)->_limits[0]) + #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits) ((v0) >> (32 - kNumBitsMax)) + #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits) (v1) + #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1) const UInt32 v1 = ((v0) >> (32 - kNumTableBits)); +#endif + + +enum enum_BuildMode +{ + k_BuildMode_Partial = 0, + k_BuildMode_Full = 1, + k_BuildMode_Full_or_Empty = 2 +}; + + +template +struct CDecoderBase +{ + CLimitInt _limits[kNumBitsMax + 2 - kNumTableBits]; + UInt32 _poses[kNumBitsMax - kNumTableBits]; // unsigned +union +{ + // if defined(MY_CPU_64BIT), we need 64-bit alignment for _symbols. + // if !defined(MY_CPU_64BIT), we need 32-bit alignment for _symbols + // but we provide alignment for _lens. + // _symbols also will be aligned, if _lens are aligned + #if defined(MY_CPU_64BIT) + UInt64 + #else + UInt32 + #endif + _pad_align[m_NumSymbols < (1u << sizeof(symType) * 8) ? 1 : -1]; + /* if symType is Byte, we use 16-bytes padding to avoid cache + bank conflict between _lens and _symbols: */ + Byte _lens[(1 << kNumTableBits) + (sizeof(symType) == 1 ? 16 : 0)]; +} _u; + symType _symbols[(1 << kNumTableBits) + m_NumSymbols - (kNumTableBits + 1)]; + + /* + Z7_FORCE_INLINE + bool IsFull() const + { + return _limits[kNumBitsMax - kNumTableBits] == + (CLimitInt)1u << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax); + } + Z7_FORCE_INLINE + bool IsEmpty() const + { + return _limits[kNumBitsMax - kNumTableBits] == 0; + } + Z7_FORCE_INLINE + bool Is_Full_or_Empty() const + { + return 0 == (_limits[kNumBitsMax - kNumTableBits] & + ~((CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax))); + } + */ + + Z7_FORCE_INLINE + bool Build(const Byte *lens, enum_BuildMode buidMode = k_BuildMode_Partial) throw() + { + unsigned counts[kNumBitsMax + 1]; + size_t i; + for (i = 0; i <= kNumBitsMax; i++) + counts[i] = 0; + for (i = 0; i < m_NumSymbols; i++) + counts[lens[i]]++; + + UInt32 sum = 0; + for (i = 1; i <= kNumTableBits; i++) + { + sum <<= 1; + sum += counts[i]; + } + + CLimitInt startPos = (CLimitInt)sum; + _limits[0] = + #ifdef Z7_HUFF_USE_64BIT_LIMIT + startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - kNumTableBits); + #else + startPos; + #endif + + for (i = kNumTableBits + 1; i <= kNumBitsMax; i++) + { + startPos <<= 1; + _poses[i - (kNumTableBits + 1)] = (UInt32)(startPos - sum); + const unsigned cnt = counts[i]; + counts[i] = sum; + sum += cnt; + startPos += cnt; + _limits[i - kNumTableBits] = startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - i); + } + + _limits[kNumBitsMax + 1 - kNumTableBits] = + (CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax); + + if (buidMode == k_BuildMode_Partial) + { + if (startPos > (1u << kNumBitsMax)) return false; + } + else + { + if (buidMode != k_BuildMode_Full && startPos == 0) return true; + if (startPos != (1u << kNumBitsMax)) return false; + } + size_t sum2 = 0; + for (i = 1; i <= kNumTableBits; i++) + { + const unsigned cnt = counts[i] << (kNumTableBits - i); + counts[i] = (unsigned)sum2 >> (kNumTableBits - i); + memset(_u._lens + sum2, (int)i, cnt); + sum2 += cnt; + } + +#ifdef MY_CPU_64BIT + symType4 + // UInt64 // for symType = UInt16 + // UInt32 // for symType = Byte +#else + UInt32 +#endif + v = 0; + for (i = 0; i < m_NumSymbols; i++, + v += + 1 + + ( (UInt32)1 << (sizeof(symType) * 8 * 1)) + // 0x00010001 // for symType = UInt16 + // 0x00000101 // for symType = Byte +#ifdef MY_CPU_64BIT + + ((symType4)1 << (sizeof(symType) * 8 * 2)) + + ((symType4)1 << (sizeof(symType) * 8 * 3)) + // 0x0001000100010001 // for symType = UInt16 + // 0x0000000001010101 // for symType = Byte +#endif + ) + { + const unsigned len = lens[i]; + if (len == 0) + continue; + const size_t offset = counts[len]; + counts[len] = (unsigned)offset + 1; + if (len >= kNumTableBits) + _symbols[offset] = (symType)v; + else + { + Byte *s2 = (Byte *)(void *)_symbols + (offset << + (kNumTableBits + sizeof(symType) / 2 - len)); + Byte *lim = s2 + ((size_t)1 << + (kNumTableBits + sizeof(symType) / 2 - len)); + if (len >= kNumTableBits - 2) + { + *(symType2 *)(void *)(s2 ) = (symType2)v; + *(symType2 *)(void *)(lim - sizeof(symType) * 2) = (symType2)v; + } + else + { +#ifdef MY_CPU_64BIT + symType4 *s = (symType4 *)(void *)s2; + do + { + s[0] = v; s[1] = v; s += 2; + } + while (s != (const symType4 *)(const void *)lim); +#else + symType2 *s = (symType2 *)(void *)s2; + do + { + s[0] = (symType2)v; s[1] = (symType2)v; s += 2; + s[0] = (symType2)v; s[1] = (symType2)v; s += 2; + } + while (s != (const symType2 *)(const void *)lim); +#endif + } + } + } + return true; + } + + +#define Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES(_numBits_, kNumBitsMax, error_op) if (_numBits_ > kNumBitsMax) { error_op } +#define Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO( _numBits_, kNumBitsMax, error_op) + + +#define Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_limits, \ + check_op, error_op, _numBits_) \ +{ \ + const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \ + _numBits_ = kNumTableBits + 1; \ + if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \ + do { _numBits_++; } \ + while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \ + check_op(_numBits_, kNumBitsMax, error_op) \ + sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \ + - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \ +} + +/* + Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_limits, \ + check_op, error_op, _numBits_) \ + +*/ + +#define Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + get_val_for_table, get_val_for_limits, \ + check_op, error_op, move_pos_op, after_op, bs) \ +{ \ + if (Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1)) \ + { \ + const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \ + size_t _numBits_ = kNumTableBits + 1; \ + if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \ + do { _numBits_++; } \ + while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \ + check_op(_numBits_, kNumBitsMax, error_op) \ + sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \ + - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \ + move_pos_op(bs, _numBits_); \ + } \ + else \ + { \ + const size_t _val = get_val_for_table(v0, v1, kNumBitsMax, kNumTableBits); \ + const size_t _numBits_ = (huf)->_u._lens[_val]; \ + sym = (huf)->_symbols[_val]; \ + move_pos_op(bs, _numBits_); \ + } \ + after_op \ +} + +#define Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + check_op, error_op, move_pos_op, after_op, bs) \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS, \ + check_op, error_op, move_pos_op, after_op, bs) \ + + +#define Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, \ + check_op, error_op, move_pos_op, after_op, bs) \ +{ \ + Z7_HUFF_PRECALC_V1(kNumTableBits, v0, _v1_temp) \ + Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, _v1_temp, \ + check_op, error_op, move_pos_op, after_op, bs) \ +} + +#if 0 || defined(Z7_HUFF_USE_64BIT_LIMIT) +// this branch uses bitStream->GetValue_InHigh32bits(). +#define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, \ + check_op, error_op, move_pos_op) \ +{ \ + const UInt32 v0 = (bitStream)->GetValue_InHigh32bits(); \ + Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1); \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS, \ + check_op, error_op, move_pos_op, {}, bitStream) \ +} +#else +/* +this branch uses bitStream->GetValue(). +So we use SIMPLE versions for v0, v1 calculation: + v0 is normalized for kNumBitsMax + v1 is normalized for kNumTableBits +*/ +#define Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE(v0, v1, kNumBitsMax, kNumTableBits) v0 +#define Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE( v0, v1, kNumBitsMax, kNumTableBits) v1 +#define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, move_pos_op) \ +{ \ + const UInt32 v0 = (bitStream)->GetValue(kNumBitsMax); \ + const UInt32 v1 = v0 >> (kNumBitsMax - kNumTableBits); \ + Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \ + v0, v1, \ + Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE, \ + Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE, \ + check_op, error_op, move_pos_op, {}, bitStream) \ +} +#endif + +#define Z7_HUFF_bitStream_MovePos(bitStream, numBits) (bitStream)->MovePos((unsigned)(numBits)) + +#define Z7_HUFF_DECODE_1(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \ + Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \ + Z7_HUFF_bitStream_MovePos) + +// MovePosCheck + +#define Z7_HUFF_DECODE_2(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \ + Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \ + Z7_HUFF_bitStream_MovePos) + +// MovePosCheck + +#define Z7_HUFF_DECODE_CHECK(sym, huf, kNumBitsMax, kNumTableBits, bitStream, error_op) \ + Z7_HUFF_DECODE_1( sym, huf, kNumBitsMax, kNumTableBits, bitStream, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, error_op) + + template + Z7_FORCE_INLINE + bool Decode2(TBitDecoder *bitStream, unsigned &sym) const + { + Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream, + { return false; } + ) + return true; + } + + template + Z7_FORCE_INLINE + bool Decode_SymCheck_MovePosCheck(TBitDecoder *bitStream, unsigned &sym) const + { + Z7_HUFF_DECODE_0(sym, this, kNumBitsMax, kNumTableBits, bitStream, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, + { return false; }, + { return (bitStream)->MovePosCheck; } + ) + } + + template + Z7_FORCE_INLINE + unsigned Decode(TBitDecoder *bitStream) const + { + unsigned sym; + Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream, + { return (unsigned)(int)(Int32)0xffffffff; } + ) + return sym; + } + + + template + Z7_FORCE_INLINE + unsigned DecodeFull(TBitDecoder *bitStream) const + { + /* + const UInt32 val = bitStream->GetValue(kNumBitsMax); + if (val < _limits[kNumTableBits]) + { + const unsigned pair = _u._lens[(size_t)(val >> (kNumBitsMax - kNumTableBits))]; + bitStream->MovePos(pair & kPairLenMask); + return pair >> kNumPairLenBits; + } + + unsigned numBits; + for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++); + + bitStream->MovePos(numBits); + return _symbols[_poses[numBits] + (unsigned) + ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits))]; + */ + unsigned sym; + Z7_HUFF_DECODE_2(sym, this, kNumBitsMax, kNumTableBits, bitStream, + Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {} + ) + return sym; + } +}; + + +template +struct CDecoder: public CDecoderBase + {}; + +template +struct CDecoder256: public CDecoderBase + {}; + + +template +class CDecoder7b +{ +public: + Byte _lens[1 << 7]; + + bool Build(const Byte *lens, bool full) throw() + { + const unsigned kNumBitsMax = 7; + + unsigned counts[kNumBitsMax + 1]; + unsigned _poses[kNumBitsMax + 1]; + unsigned _limits[kNumBitsMax + 1]; + unsigned i; + for (i = 0; i <= kNumBitsMax; i++) + counts[i] = 0; + for (i = 0; i < numSymbols; i++) + counts[lens[i]]++; + + _limits[0] = 0; + const unsigned kMaxValue = 1u << kNumBitsMax; + unsigned startPos = 0; + unsigned sum = 0; + + for (i = 1; i <= kNumBitsMax; i++) + { + const unsigned cnt = counts[i]; + startPos += cnt << (kNumBitsMax - i); + _limits[i] = startPos; + counts[i] = sum; + _poses[i] = sum; + sum += cnt; + } + + counts[0] = sum; + _poses[0] = sum; + + if (full) + { + if (startPos != kMaxValue) + return false; + } + else + { + if (startPos > kMaxValue) + return false; + } + + + for (i = 0; i < numSymbols; i++) + { + const unsigned len = lens[i]; + if (len == 0) + continue; + const unsigned offset = counts[len]++; + { + Byte *dest = _lens + _limits[(size_t)len - 1] + + ((offset - _poses[len]) << (kNumBitsMax - len)); + const unsigned num = (unsigned)1 << (kNumBitsMax - len); + const unsigned val = (i << 3) + len; + for (unsigned k = 0; k < num; k++) + dest[k] = (Byte)val; + } + } + + if (!full) + { + const unsigned limit = _limits[kNumBitsMax]; + const unsigned num = ((unsigned)1 << kNumBitsMax) - limit; + Byte *dest = _lens + limit; + for (unsigned k = 0; k < num; k++) + dest[k] = (Byte) + // (0x1f << 3); + ((0x1f << 3) + 0x7); + } + + return true; + } + +#define Z7_HUFF_DECODER_7B_DECODE(dest, huf, get_val, move_pos, bs) \ + { \ + const unsigned pair = huf->_lens[(size_t)get_val(7)]; \ + const unsigned numBits = pair & 0x7; \ + move_pos(bs, numBits); \ + dest = pair >> 3; \ + } + + template + unsigned Decode(TBitDecoder *bitStream) const + { + const unsigned pair = _lens[(size_t)bitStream->GetValue(7)]; + bitStream->MovePos(pair & 0x7); + return pair >> 3; + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ImplodeDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ImplodeDecoder.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.cpp 2023-12-22 11:00:00.000000000 +0000 @@ -1,224 +1,250 @@ -// ImplodeDecoder.cpp - -#include "StdAfx.h" - -#include "../../Common/Defs.h" - -#include "ImplodeDecoder.h" - -namespace NCompress { -namespace NImplode { -namespace NDecoder { - -class CException -{ -public: - enum ECauseType - { - kData - } m_Cause; - CException(ECauseType cause): m_Cause(cause) {} -}; - -static const int kNumDistanceLowDirectBitsForBigDict = 7; -static const int kNumDistanceLowDirectBitsForSmallDict = 6; - -static const int kNumBitsInByte = 8; - -// static const int kLevelStructuresNumberFieldSize = kNumBitsInByte; -static const int kLevelStructuresNumberAdditionalValue = 1; - -static const int kNumLevelStructureLevelBits = 4; -static const int kLevelStructureLevelAdditionalValue = 1; - -static const int kNumLevelStructureRepNumberBits = 4; -static const int kLevelStructureRepNumberAdditionalValue = 1; - - -static const int kLiteralTableSize = (1 << kNumBitsInByte); -static const int kDistanceTableSize = 64; -static const int kLengthTableSize = 64; - -static const UInt32 kHistorySize = - (1 << MyMax(kNumDistanceLowDirectBitsForBigDict, - kNumDistanceLowDirectBitsForSmallDict)) * - kDistanceTableSize; // = 8 KB; - -static const int kNumAdditionalLengthBits = 8; - -static const UInt32 kMatchMinLenWhenLiteralsOn = 3; -static const UInt32 kMatchMinLenWhenLiteralsOff = 2; - -static const UInt32 kMatchMinLenMax = MyMax(kMatchMinLenWhenLiteralsOn, - kMatchMinLenWhenLiteralsOff); // 3 - -// static const UInt32 kMatchMaxLenMax = kMatchMinLenMax + (kLengthTableSize - 1) + (1 << kNumAdditionalLengthBits) - 1; // or 2 - -enum -{ - kMatchId = 0, - kLiteralId = 1 -}; - - -CCoder::CCoder(): - m_LiteralDecoder(kLiteralTableSize), - m_LengthDecoder(kLengthTableSize), - m_DistanceDecoder(kDistanceTableSize) -{ -} - -/* -void CCoder::ReleaseStreams() -{ - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); -} -*/ - -bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, - Byte *levels, int numLevelItems) -{ - int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + - kLevelStructuresNumberAdditionalValue; - int currentIndex = 0; - for (int i = 0; i < numCodedStructures; i++) - { - int level = m_InBitStream.ReadBits(kNumLevelStructureLevelBits) + - kLevelStructureLevelAdditionalValue; - int rep = m_InBitStream.ReadBits(kNumLevelStructureRepNumberBits) + - kLevelStructureRepNumberAdditionalValue; - if (currentIndex + rep > numLevelItems) - throw CException(CException::kData); - for (int j = 0; j < rep; j++) - levels[currentIndex++] = (Byte)level; - } - if (currentIndex != numLevelItems) - return false; - return decoder.SetCodeLengths(levels); -} - - -bool CCoder::ReadTables(void) -{ - if (m_LiteralsOn) - { - Byte literalLevels[kLiteralTableSize]; - if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize)) - return false; - } - - Byte lengthLevels[kLengthTableSize]; - if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize)) - return false; - - Byte distanceLevels[kDistanceTableSize]; - return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); -} - -/* -class CCoderReleaser -{ - CCoder *m_Coder; -public: - CCoderReleaser(CCoder *coder): m_Coder(coder) {} - ~CCoderReleaser() { m_Coder->ReleaseStreams(); } -}; -*/ - -HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (outSize == NULL) - return E_INVALIDARG; - UInt64 pos = 0, unPackSize = *outSize; - - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - // CCoderReleaser coderReleaser(this); - - if (!ReadTables()) - return S_FALSE; - - while (pos < unPackSize) - { - if (progress != NULL && pos % (1 << 16) == 0) - { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - } - if (m_InBitStream.ReadBits(1) == kMatchId) // match - { - UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); - UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream); - if (distance >= kDistanceTableSize) - return S_FALSE; - distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits; - UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); - if (lengthSymbol >= kLengthTableSize) - return S_FALSE; - UInt32 length = lengthSymbol + m_MinMatchLength; - if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 - length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); - while (distance >= pos && length > 0) - { - m_OutWindowStream.PutByte(0); - pos++; - length--; - } - if (length > 0) - m_OutWindowStream.CopyBlock(distance, length); - pos += length; - } - else - { - Byte b; - if (m_LiteralsOn) - { - UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream); - if (temp >= kLiteralTableSize) - return S_FALSE; - b = (Byte)temp; - } - else - b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte); - m_OutWindowStream.PutByte(b); - pos++; - } - } - if (pos > unPackSize) - return S_FALSE; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -STDMETHODIMP CCoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size < 1) - return E_INVALIDARG; - Byte flag = data[0]; - m_BigDictionaryOn = ((flag & 2) != 0); - m_NumDistanceLowDirectBits = m_BigDictionaryOn ? - kNumDistanceLowDirectBitsForBigDict: - kNumDistanceLowDirectBitsForSmallDict; - m_LiteralsOn = ((flag & 4) != 0); - m_MinMatchLength = m_LiteralsOn ? - kMatchMinLenWhenLiteralsOn : - kMatchMinLenWhenLiteralsOff; - return S_OK; -} - -}}} +// ImplodeDecoder.cpp + +#include "StdAfx.h" + +#include "../../Common/Defs.h" + +#include "ImplodeDecoder.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +bool CHuffmanDecoder::Build(const Byte *lens, unsigned numSymbols) throw() +{ + unsigned counts[kNumHuffmanBits + 1]; + unsigned i; + for (i = 0; i <= kNumHuffmanBits; i++) + counts[i] = 0; + for (i = 0; i < numSymbols; i++) + counts[lens[i]]++; + + const UInt32 kMaxValue = (UInt32)1 << kNumHuffmanBits; + // _limits[0] = kMaxValue; + UInt32 startPos = kMaxValue; + unsigned sum = 0; + + for (i = 1; i <= kNumHuffmanBits; i++) + { + const unsigned cnt = counts[i]; + const UInt32 range = (UInt32)cnt << (kNumHuffmanBits - i); + if (startPos < range) + return false; + startPos -= range; + _limits[i] = startPos; + _poses[i] = sum; + sum += cnt; + counts[i] = sum; + } + // counts[0] += sum; + if (startPos != 0) + return false; + for (i = 0; i < numSymbols; i++) + { + const unsigned len = lens[i]; + if (len != 0) + _symbols[--counts[len]] = (Byte)i; + } + return true; +} + + +unsigned CHuffmanDecoder::Decode(CInBit *inStream) const throw() +{ + const UInt32 val = inStream->GetValue(kNumHuffmanBits); + size_t numBits; + for (numBits = 1; val < _limits[numBits]; numBits++); + const unsigned sym = _symbols[_poses[numBits] + + (unsigned)((val - _limits[numBits]) >> (kNumHuffmanBits - numBits))]; + inStream->MovePos(numBits); + return sym; +} + + + +static const unsigned kNumLenDirectBits = 8; + +static const unsigned kNumDistDirectBitsSmall = 6; +static const unsigned kNumDistDirectBitsBig = 7; + +static const unsigned kLitTableSize = (1 << 8); +static const unsigned kDistTableSize = 64; +static const unsigned kLenTableSize = 64; + +static const UInt32 kHistorySize = (1 << kNumDistDirectBitsBig) * kDistTableSize; // 8 KB + + +CCoder::CCoder(): + _flags(0), + _fullStreamMode(false) +{} + + +bool CCoder::BuildHuff(CHuffmanDecoder &decoder, unsigned numSymbols) +{ + Byte levels[kMaxHuffTableSize]; + unsigned numRecords = (unsigned)_inBitStream.ReadAlignedByte() + 1; + unsigned index = 0; + do + { + const unsigned b = (unsigned)_inBitStream.ReadAlignedByte(); + const unsigned level = (b & 0xF) + 1; + const unsigned rep = ((unsigned)b >> 4) + 1; + if (index + rep > numSymbols) + return false; + for (unsigned j = 0; j < rep; j++) + levels[index++] = (Byte)level; + } + while (--numRecords); + + if (index != numSymbols) + return false; + return decoder.Build(levels, numSymbols); +} + + +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (!_inBitStream.Create(1 << 18)) + return E_OUTOFMEMORY; + if (!_outWindowStream.Create(kHistorySize << 1)) // 16 KB + return E_OUTOFMEMORY; + if (!outSize) + return E_INVALIDARG; + + _outWindowStream.SetStream(outStream); + _outWindowStream.Init(false); + _inBitStream.SetStream(inStream); + _inBitStream.Init(); + + const unsigned numDistDirectBits = (_flags & 2) ? + kNumDistDirectBitsBig: + kNumDistDirectBitsSmall; + const bool literalsOn = ((_flags & 4) != 0); + const UInt32 minMatchLen = (literalsOn ? 3 : 2); + + if (literalsOn) + if (!BuildHuff(_litDecoder, kLitTableSize)) + return S_FALSE; + if (!BuildHuff(_lenDecoder, kLenTableSize)) + return S_FALSE; + if (!BuildHuff(_distDecoder, kDistTableSize)) + return S_FALSE; + + UInt64 prevProgress = 0; + bool moreOut = false; + UInt64 pos = 0, unPackSize = *outSize; + + while (pos < unPackSize) + { + if (pos - prevProgress >= (1u << 18) && progress) + { + prevProgress = pos; + const UInt64 packSize = _inBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) + } + + if (_inBitStream.ReadBits(1) != 0) + { + Byte b; + if (literalsOn) + { + const unsigned sym = _litDecoder.Decode(&_inBitStream); + // if (sym >= kLitTableSize) break; + b = (Byte)sym; + } + else + b = (Byte)_inBitStream.ReadBits(8); + _outWindowStream.PutByte(b); + pos++; + } + else + { + const UInt32 lowDistBits = _inBitStream.ReadBits(numDistDirectBits); + UInt32 dist = (UInt32)_distDecoder.Decode(&_inBitStream); + // if (dist >= kDistTableSize) break; + dist = (dist << numDistDirectBits) + lowDistBits; + unsigned len = _lenDecoder.Decode(&_inBitStream); + // if (len >= kLenTableSize) break; + if (len == kLenTableSize - 1) + len += _inBitStream.ReadBits(kNumLenDirectBits); + len += minMatchLen; + { + const UInt64 limit = unPackSize - pos; + // limit != 0 + if (len > limit) + { + moreOut = true; + len = (UInt32)limit; + } + } + do + { + // len != 0 + if (dist < pos) + { + _outWindowStream.CopyBlock(dist, len); + pos += len; + break; + } + _outWindowStream.PutByte(0); + pos++; + } + while (--len); + } + } + + HRESULT res = _outWindowStream.Flush(); + + if (res == S_OK) + { + if (_fullStreamMode) + { + if (moreOut) + res = S_FALSE; + if (inSize && *inSize != _inBitStream.GetProcessedSize()) + res = S_FALSE; + } + if (pos != unPackSize) + res = S_FALSE; + } + + return res; +} + + +Z7_COM7F_IMF(CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + // catch(const CInBufferException &e) { return e.ErrorCode; } + // catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(const CSystemException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + + +Z7_COM7F_IMF(CCoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size == 0) + return E_NOTIMPL; + _flags = data[0]; + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::SetFinishMode(UInt32 finishMode)) +{ + _fullStreamMode = (finishMode != 0); + return S_OK; +} + + +Z7_COM7F_IMF(CCoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inBitStream.GetProcessedSize(); + return S_OK; +} + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ImplodeDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ImplodeDecoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeDecoder.h 2023-12-22 11:00:00.000000000 +0000 @@ -1,56 +1,61 @@ -// ImplodeDecoder.h - -#ifndef __COMPRESS_IMPLODE_DECODER_H -#define __COMPRESS_IMPLODE_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "ImplodeHuffmanDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NImplode { -namespace NDecoder { - -class CCoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - NBitl::CDecoder m_InBitStream; - - NImplode::NHuffman::CDecoder m_LiteralDecoder; - NImplode::NHuffman::CDecoder m_LengthDecoder; - NImplode::NHuffman::CDecoder m_DistanceDecoder; - - bool m_BigDictionaryOn; - bool m_LiteralsOn; - - int m_NumDistanceLowDirectBits; - UInt32 m_MinMatchLength; - - bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems); - bool ReadTables(); - void DeCodeLevelTable(Byte *newLevels, int numLevels); -public: - CCoder(); - - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - - // void ReleaseStreams(); - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); -}; - -}}} - -#endif +// ImplodeDecoder.h + +#ifndef ZIP7_INC_COMPRESS_IMPLODE_DECODER_H +#define ZIP7_INC_COMPRESS_IMPLODE_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitlDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NImplode { +namespace NDecoder { + +typedef NBitl::CDecoder CInBit; + +const unsigned kNumHuffmanBits = 16; +const unsigned kMaxHuffTableSize = 1 << 8; + +class CHuffmanDecoder +{ + UInt32 _limits[kNumHuffmanBits + 1]; + UInt32 _poses[kNumHuffmanBits + 1]; + Byte _symbols[kMaxHuffTableSize]; +public: + bool Build(const Byte *lens, unsigned numSymbols) throw(); + unsigned Decode(CInBit *inStream) const throw(); +}; + + +Z7_CLASS_IMP_NOQIB_4( + CCoder + , ICompressCoder + , ICompressSetDecoderProperties2 + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + Byte _flags; + bool _fullStreamMode; + + CLzOutWindow _outWindowStream; + CInBit _inBitStream; + + CHuffmanDecoder _litDecoder; + CHuffmanDecoder _lenDecoder; + CHuffmanDecoder _distDecoder; + + bool BuildHuff(CHuffmanDecoder &table, unsigned numSymbols); + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); +public: + CCoder(); +}; + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp 2017-04-25 10:46:31.000000000 +0000 @@ -1,89 +1,3 @@ -// ImplodeHuffmanDecoder.cpp - -#include "StdAfx.h" - -#include "ImplodeHuffmanDecoder.h" - -namespace NCompress { -namespace NImplode { -namespace NHuffman { - -CDecoder::CDecoder(UInt32 numSymbols): - m_NumSymbols(numSymbols) -{ - m_Symbols = new UInt32[m_NumSymbols]; -} - -CDecoder::~CDecoder() -{ - delete []m_Symbols; -} - -bool CDecoder::SetCodeLengths(const Byte *codeLengths) -{ - // unsigned lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; - unsigned lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; - unsigned i; - for (i = 0; i <= kNumBitsInLongestCode; i++) - lenCounts[i] = 0; - UInt32 symbolIndex; - for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) - lenCounts[codeLengths[symbolIndex]]++; - // lenCounts[0] = 0; - - // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0; - m_Limitits[kNumBitsInLongestCode + 1] = 0; - m_Positions[kNumBitsInLongestCode + 1] = 0; - lenCounts[kNumBitsInLongestCode + 1] = 0; - - - UInt32 startPos = 0; - static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); - - for (i = kNumBitsInLongestCode; i > 0; i--) - { - startPos += lenCounts[i] << (kNumBitsInLongestCode - i); - if (startPos > kMaxValue) - return false; - m_Limitits[i] = startPos; - m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1]; - tmpPositions[i] = m_Positions[i] + lenCounts[i]; - - } - - // if _ZIP_MODE do not throw exception for trees containing only one node - // #ifndef _ZIP_MODE - if (startPos != kMaxValue) - return false; - // #endif - - for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) - if (codeLengths[symbolIndex] != 0) - m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex; - return true; -} - -UInt32 CDecoder::DecodeSymbol(CInBit *inStream) -{ - UInt32 numBits = 0; - UInt32 value = inStream->GetValue(kNumBitsInLongestCode); - unsigned i; - for (i = kNumBitsInLongestCode; i > 0; i--) - { - if (value < m_Limitits[i]) - { - numBits = i; - break; - } - } - if (i == 0) - return 0xFFFFFFFF; - inStream->MovePos(numBits); - UInt32 index = m_Positions[numBits] + - ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits)); - if (index >= m_NumSymbols) - return 0xFFFFFFFF; - return m_Symbols[index]; -} - -}}} +// ImplodeHuffmanDecoder.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ImplodeHuffmanDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ImplodeHuffmanDecoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ImplodeHuffmanDecoder.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,34 +1,6 @@ -// ImplodeHuffmanDecoder.h - -#ifndef __IMPLODE_HUFFMAN_DECODER_H -#define __IMPLODE_HUFFMAN_DECODER_H - -#include "../Common/InBuffer.h" - -#include "BitlDecoder.h" - -namespace NCompress { -namespace NImplode { -namespace NHuffman { - -const unsigned kNumBitsInLongestCode = 16; - -typedef NBitl::CDecoder CInBit; - -class CDecoder -{ - UInt32 m_Limitits[kNumBitsInLongestCode + 2]; // m_Limitits[i] = value limit for symbols with length = i - UInt32 m_Positions[kNumBitsInLongestCode + 2]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i - UInt32 m_NumSymbols; // number of symbols in m_Symbols - UInt32 *m_Symbols; // symbols: at first with len=1 then 2, ... 15. -public: - CDecoder(UInt32 numSymbols); - ~CDecoder(); - - bool SetCodeLengths(const Byte *codeLengths); - UInt32 DecodeSymbol(CInBit *inStream); -}; - -}}} - -#endif +// ImplodeHuffmanDecoder.h + +#ifndef ZIP7_INC_IMPLODE_HUFFMAN_DECODER_H +#define ZIP7_INC_IMPLODE_HUFFMAN_DECODER_H + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzOutWindow.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzOutWindow.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.cpp 2023-03-28 11:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// LzOutWindow.cpp - -#include "StdAfx.h" - -#include "LzOutWindow.h" - -void CLzOutWindow::Init(bool solid) throw() -{ - if (!solid) - COutBuffer::Init(); - #ifdef _NO_EXCEPTIONS - ErrorCode = S_OK; - #endif -} +// LzOutWindow.cpp + +#include "StdAfx.h" + +#include "LzOutWindow.h" + +void CLzOutWindow::Init(bool solid) throw() +{ + if (!solid) + COutBuffer::Init(); + #ifdef Z7_NO_EXCEPTIONS + ErrorCode = S_OK; + #endif +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzOutWindow.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzOutWindow.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzOutWindow.h 2023-03-28 11:00:00.000000000 +0000 @@ -1,69 +1,102 @@ -// LzOutWindow.h - -#ifndef __LZ_OUT_WINDOW_H -#define __LZ_OUT_WINDOW_H - -#include "../Common/OutBuffer.h" - -#ifndef _NO_EXCEPTIONS -typedef COutBufferException CLzOutWindowException; -#endif - -class CLzOutWindow: public COutBuffer -{ -public: - void Init(bool solid = false) throw(); - - // distance >= 0, len > 0, - bool CopyBlock(UInt32 distance, UInt32 len) - { - UInt32 pos = _pos - distance - 1; - if (distance >= _pos) - { - if (!_overDict || distance >= _bufSize) - return false; - pos += _bufSize; - } - if (_limitPos - _pos > len && _bufSize - pos > len) - { - const Byte *src = _buf + pos; - Byte *dest = _buf + _pos; - _pos += len; - do - *dest++ = *src++; - while (--len != 0); - } - else do - { - UInt32 pos2; - if (pos == _bufSize) - pos = 0; - pos2 = _pos; - _buf[pos2++] = _buf[pos++]; - _pos = pos2; - if (pos2 == _limitPos) - FlushWithCheck(); - } - while (--len != 0); - return true; - } - - void PutByte(Byte b) - { - UInt32 pos = _pos; - _buf[pos++] = b; - _pos = pos; - if (pos == _limitPos) - FlushWithCheck(); - } - - Byte GetByte(UInt32 distance) const - { - UInt32 pos = _pos - distance - 1; - if (distance >= _pos) - pos += _bufSize; - return _buf[pos]; - } -}; - -#endif +// LzOutWindow.h + +#ifndef ZIP7_INC_LZ_OUT_WINDOW_H +#define ZIP7_INC_LZ_OUT_WINDOW_H + +#include "../Common/OutBuffer.h" + +#ifndef Z7_NO_EXCEPTIONS +typedef COutBufferException CLzOutWindowException; +#endif + +class CLzOutWindow: public COutBuffer +{ +public: + void Init(bool solid = false) throw(); + + // distance >= 0, len > 0, + bool CopyBlock(UInt32 distance, UInt32 len) + { + UInt32 pos = _pos - distance - 1; + if (distance >= _pos) + { + if (!_overDict || distance >= _bufSize) + return false; + pos += _bufSize; + } + if (_limitPos - _pos > len && _bufSize - pos > len) + { + const Byte *src = _buf + pos; + Byte *dest = _buf + _pos; + _pos += len; + do + *dest++ = *src++; + while (--len != 0); + } + else do + { + UInt32 pos2; + if (pos == _bufSize) + pos = 0; + pos2 = _pos; + _buf[pos2++] = _buf[pos++]; + _pos = pos2; + if (pos2 == _limitPos) + FlushWithCheck(); + } + while (--len != 0); + return true; + } + + void PutByte(Byte b) + { + UInt32 pos = _pos; + _buf[pos++] = b; + _pos = pos; + if (pos == _limitPos) + FlushWithCheck(); + } + + void PutBytes(const Byte *data, UInt32 size) + { + if (size == 0) + return; + UInt32 pos = _pos; + Byte *buf = _buf; + buf[pos++] = *data++; + size--; + for (;;) + { + UInt32 limitPos = _limitPos; + UInt32 rem = limitPos - pos; + if (rem == 0) + { + _pos = pos; + FlushWithCheck(); + pos = _pos; + continue; + } + + if (size == 0) + break; + + if (rem > size) + rem = size; + size -= rem; + do + buf[pos++] = *data++; + while (--rem); + } + _pos = pos; + } + + Byte GetByte(UInt32 distance) const + { + UInt32 pos = _pos - distance - 1; + if (distance >= _pos) + pos += _bufSize; + return _buf[pos]; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzfseDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzfseDecoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.cpp 2024-01-01 10:00:00.000000000 +0000 @@ -0,0 +1,950 @@ +// LzfseDecoder.cpp + +/* +This code implements LZFSE data decompressing. +The code from "LZFSE compression library" was used. + +2018 : Igor Pavlov : BSD 3-clause License : the code in this file +2015-2017 : Apple Inc : BSD 3-clause License : original "LZFSE compression library" code + +The code in the "LZFSE compression library" is licensed under the "BSD 3-clause License": +---- +Copyright (c) 2015-2016, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +---- +*/ + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#include "../../../C/CpuArch.h" + +#include "LzfseDecoder.h" + +namespace NCompress { +namespace NLzfse { + +static const Byte kSignature_LZFSE_V1 = 0x31; // '1' +static const Byte kSignature_LZFSE_V2 = 0x32; // '2' + + +HRESULT CDecoder::GetUInt32(UInt32 &val) +{ + Byte b[4]; + for (unsigned i = 0; i < 4; i++) + if (!m_InStream.ReadByte(b[i])) + return S_FALSE; + val = GetUi32(b); + return S_OK; +} + + + +HRESULT CDecoder::DecodeUncompressed(UInt32 unpackSize) +{ + PRF(printf("\nUncompressed %7u\n", unpackSize)); + + const unsigned kBufSize = 1 << 8; + Byte buf[kBufSize]; + for (;;) + { + if (unpackSize == 0) + return S_OK; + UInt32 cur = unpackSize; + if (cur > kBufSize) + cur = kBufSize; + const UInt32 cur2 = (UInt32)m_InStream.ReadBytes(buf, cur); + m_OutWindowStream.PutBytes(buf, cur2); + if (cur != cur2) + return S_FALSE; + } +} + + + +HRESULT CDecoder::DecodeLzvn(UInt32 unpackSize, UInt32 packSize) +{ + PRF(printf("\nLZVN 0x%07x 0x%07x\n", unpackSize, packSize)); + + UInt32 D = 0; + + for (;;) + { + if (packSize == 0) + return S_FALSE; + Byte b; + if (!m_InStream.ReadByte(b)) + return S_FALSE; + packSize--; + + UInt32 M; + UInt32 L; + + if (b >= 0xE0) + { + /* + large L - 11100000 LLLLLLLL + small L - 1110LLLL + + large Rep - 11110000 MMMMMMMM + small Rep - 1111MMMM + */ + + M = b & 0xF; + if (M == 0) + { + if (packSize == 0) + return S_FALSE; + Byte b1; + if (!m_InStream.ReadByte(b1)) + return S_FALSE; + packSize--; + M = (UInt32)b1 + 16; + } + L = 0; + if ((b & 0x10) == 0) + { + // Literals only + L = M; + M = 0; + } + } + + // ERROR codes + else if ((b & 0xF0) == 0x70) // 0111xxxx + return S_FALSE; + else if ((b & 0xF0) == 0xD0) // 1101xxxx + return S_FALSE; + + else + { + if ((b & 0xE0) == 0xA0) + { + // medium - 101LLMMM DDDDDDMM DDDDDDDD + if (packSize < 2) + return S_FALSE; + Byte b1; + if (!m_InStream.ReadByte(b1)) + return S_FALSE; + packSize--; + + Byte b2; + if (!m_InStream.ReadByte(b2)) + return S_FALSE; + packSize--; + L = (((UInt32)b >> 3) & 3); + M = (((UInt32)b & 7) << 2) + (b1 & 3); + D = ((UInt32)b1 >> 2) + ((UInt32)b2 << 6); + } + else + { + L = (UInt32)b >> 6; + M = ((UInt32)b >> 3) & 7; + if ((b & 0x7) == 6) + { + // REP - LLMMM110 + if (L == 0) + { + // spec + if (M == 0) + break; // EOS + if (M <= 2) + continue; // NOP + return S_FALSE; // UNDEFINED + } + } + else + { + if (packSize == 0) + return S_FALSE; + Byte b1; + if (!m_InStream.ReadByte(b1)) + return S_FALSE; + packSize--; + + // large - LLMMM111 DDDDDDDD DDDDDDDD + // small - LLMMMDDD DDDDDDDD + D = ((UInt32)b & 7); + if (D == 7) + { + if (packSize == 0) + return S_FALSE; + Byte b2; + if (!m_InStream.ReadByte(b2)) + return S_FALSE; + packSize--; + D = b2; + } + D = (D << 8) + b1; + } + } + + M += 3; + } + { + for (unsigned i = 0; i < L; i++) + { + if (packSize == 0 || unpackSize == 0) + return S_FALSE; + Byte b1; + if (!m_InStream.ReadByte(b1)) + return S_FALSE; + packSize--; + m_OutWindowStream.PutByte(b1); + unpackSize--; + } + } + + if (M != 0) + { + if (unpackSize == 0 || D == 0) + return S_FALSE; + unsigned cur = M; + if (cur > unpackSize) + cur = (unsigned)unpackSize; + if (!m_OutWindowStream.CopyBlock(D - 1, cur)) + return S_FALSE; + unpackSize -= cur; + if (cur != M) + return S_FALSE; + } + } + + if (unpackSize != 0) + return S_FALSE; + + // LZVN encoder writes 7 additional zero bytes + if (packSize < 7) + return S_FALSE; + for (unsigned i = 0; i < 7; i++) + { + Byte b; + if (!m_InStream.ReadByte(b)) + return S_FALSE; + if (b != 0) + return S_FALSE; + } + packSize -= 7; + if (packSize) + { + PRF(printf("packSize after unused = %u\n", packSize)); + // if (packSize <= 0x100) { Byte buf[0x100]; m_InStream.ReadBytes(buf, packSize); } + /* Lzvn block that is used in HFS can contain junk data + (at least 256 bytes) after payload data. Why? + We ignore that junk data, if it's HFS (LzvnMode) mode. */ + if (!LzvnMode) + return S_FALSE; + } + return S_OK; +} + + + +// ---------- LZFSE ---------- + +#define MATCHES_PER_BLOCK 10000 +#define LITERALS_PER_BLOCK (4 * MATCHES_PER_BLOCK) + +#define NUM_L_SYMBOLS 20 +#define NUM_M_SYMBOLS 20 +#define NUM_D_SYMBOLS 64 +#define NUM_LIT_SYMBOLS 256 + +#define NUM_SYMBOLS ( \ + NUM_L_SYMBOLS + \ + NUM_M_SYMBOLS + \ + NUM_D_SYMBOLS + \ + NUM_LIT_SYMBOLS) + +#define NUM_L_STATES (1 << 6) +#define NUM_M_STATES (1 << 6) +#define NUM_D_STATES (1 << 8) +#define NUM_LIT_STATES (1 << 10) + + +typedef UInt32 CFseState; + + +static UInt32 SumFreqs(const UInt16 *freqs, unsigned num) +{ + UInt32 sum = 0; + for (unsigned i = 0; i < num; i++) + sum += (UInt32)freqs[i]; + return sum; +} + + +static Z7_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask) +{ + for (unsigned i = 0;;) + { + if (val & mask) + return i; + i++; + mask >>= 1; + } +} + + +static Z7_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table) +{ + for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++) + { + unsigned f = freqs[i]; + if (f == 0) + continue; + + // 0 < f <= numStates + // 0 <= k <= numStatesLog + // numStates <= (f<> k) - f; + + /* + CEntry + { + Byte k; + Byte symbol; + UInt16 delta; + }; + */ + + UInt32 e = ((UInt32)i << 8) + k; + k += 16; + UInt32 d = e + ((UInt32)f << k) - ((UInt32)NUM_LIT_STATES << 16); + UInt32 step = (UInt32)1 << k; + + unsigned j = 0; + do + { + *table++ = d; + d += step; + } + while (++j < j0); + + e--; + step >>= 1; + + for (j = j0; j < f; j++) + { + *table++ = e; + e += step; + } + } +} + + +typedef struct +{ + Byte totalBits; + Byte extraBits; + UInt16 delta; + UInt32 vbase; +} CExtraEntry; + + +static void InitExtraDecoderTable(unsigned numStates, + unsigned numSymbols, + const UInt16 *freqs, + const Byte *vbits, + CExtraEntry *table) +{ + UInt32 vbase = 0; + + for (unsigned i = 0; i < numSymbols; i++) + { + unsigned f = freqs[i]; + unsigned extraBits = vbits[i]; + + if (f != 0) + { + unsigned k = CountZeroBits(f, numStates); + unsigned j0 = ((2 * numStates) >> k) - f; + + unsigned j = 0; + do + { + CExtraEntry *e = table++; + e->totalBits = (Byte)(k + extraBits); + e->extraBits = (Byte)extraBits; + e->delta = (UInt16)(((f + j) << k) - numStates); + e->vbase = vbase; + } + while (++j < j0); + + f -= j0; + k--; + + for (j = 0; j < f; j++) + { + CExtraEntry *e = table++; + e->totalBits = (Byte)(k + extraBits); + e->extraBits = (Byte)extraBits; + e->delta = (UInt16)(j << k); + e->vbase = vbase; + } + } + + vbase += ((UInt32)1 << extraBits); + } +} + + +static const Byte k_L_extra[NUM_L_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 8 +}; + +static const Byte k_M_extra[NUM_M_SYMBOLS] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11 +}; + +static const Byte k_D_extra[NUM_D_SYMBOLS] = +{ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15 +}; + + + +// ---------- CBitStream ---------- + +typedef struct +{ + UInt32 accum; + unsigned numBits; // [0, 31] - Number of valid bits in (accum), other bits are 0 +} CBitStream; + + +static Z7_FORCE_INLINE int FseInStream_Init(CBitStream *s, + int n, // [-7, 0], (-n == number_of_unused_bits) in last byte + const Byte **pbuf) +{ + *pbuf -= 4; + s->accum = GetUi32(*pbuf); + if (n) + { + s->numBits = (unsigned)(n + 32); + if ((s->accum >> s->numBits) != 0) + return -1; // ERROR, encoder should have zeroed the upper bits + } + else + { + *pbuf += 1; + s->accum >>= 8; + s->numBits = 24; + } + return 0; // OK +} + + +// 0 <= numBits < 32 +#define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1)) + +#define FseInStream_FLUSH \ + { const unsigned nbits = (31 - in.numBits) & (unsigned)-8; \ + if (nbits) { \ + buf -= (nbits >> 3); \ + if (buf < buf_check) return S_FALSE; \ + UInt32 v = GetUi32(buf); \ + in.accum = (in.accum << nbits) | mask31(v, nbits); \ + in.numBits += nbits; }} + + + +static Z7_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits) +{ + s->numBits -= numBits; + const UInt32 v = s->accum >> s->numBits; + s->accum = mask31(s->accum, s->numBits); + return v; +} + + +#define DECODE_LIT(dest, pstate) { \ + UInt32 e = lit_decoder[pstate]; \ + pstate = (CFseState)((e >> 16) + BitStream_Pull(&in, e & 0xff)); \ + dest = (Byte)(e >> 8); } + + +static Z7_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate, + const CExtraEntry *table, + CBitStream *s) +{ + const CExtraEntry *e = &table[*pstate]; + UInt32 v = BitStream_Pull(s, e->totalBits); + unsigned extraBits = e->extraBits; + *pstate = (CFseState)(e->delta + (v >> extraBits)); + return e->vbase + mask31(v, extraBits); +} + + +#define freqs_L (freqs) +#define freqs_M (freqs_L + NUM_L_SYMBOLS) +#define freqs_D (freqs_M + NUM_M_SYMBOLS) +#define freqs_LIT (freqs_D + NUM_D_SYMBOLS) + +#define GET_BITS_64(v, offset, num, dest) dest = (UInt32) ((v >> (offset)) & ((1 << (num)) - 1)); +#define GET_BITS_64_Int32(v, offset, num, dest) dest = (Int32)((v >> (offset)) & ((1 << (num)) - 1)); +#define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1)); + + +HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version) +{ + PRF(printf("\nLZFSE-%d %7u", version - '0', unpackSize)); + + UInt32 numLiterals; + UInt32 litPayloadSize; + Int32 literal_bits; + + UInt32 lit_state_0; + UInt32 lit_state_1; + UInt32 lit_state_2; + UInt32 lit_state_3; + + UInt32 numMatches; + UInt32 lmdPayloadSize; + Int32 lmd_bits; + + CFseState l_state; + CFseState m_state; + CFseState d_state; + + UInt16 freqs[NUM_SYMBOLS]; + + if (version == kSignature_LZFSE_V1) + { + return E_NOTIMPL; + // we need examples to test LZFSE-V1 code + /* + const unsigned k_v1_SubHeaderSize = 7 * 4 + 7 * 2; + const unsigned k_v1_HeaderSize = k_v1_SubHeaderSize + NUM_SYMBOLS * 2; + _buffer.AllocAtLeast(k_v1_HeaderSize); + if (m_InStream.ReadBytes(_buffer, k_v1_HeaderSize) != k_v1_HeaderSize) + return S_FALSE; + + const Byte *buf = _buffer; + #define GET_32(offs, dest) dest = GetUi32(buf + offs) + #define GET_16(offs, dest) dest = GetUi16(buf + offs) + + UInt32 payload_bytes; + GET_32(0, payload_bytes); + GET_32(4, numLiterals); + GET_32(8, numMatches); + GET_32(12, litPayloadSize); + GET_32(16, lmdPayloadSize); + if (litPayloadSize > (1 << 20) || lmdPayloadSize > (1 << 20)) + return S_FALSE; + GET_32(20, literal_bits); + if (literal_bits < -7 || literal_bits > 0) + return S_FALSE; + + GET_16(24, lit_state_0); + GET_16(26, lit_state_1); + GET_16(28, lit_state_2); + GET_16(30, lit_state_3); + + GET_32(32, lmd_bits); + if (lmd_bits < -7 || lmd_bits > 0) + return S_FALSE; + + GET_16(36, l_state); + GET_16(38, m_state); + GET_16(40, d_state); + + for (unsigned i = 0; i < NUM_SYMBOLS; i++) + freqs[i] = GetUi16(buf + k_v1_SubHeaderSize + i * 2); + */ + } + else + { + UInt32 headerSize; + { + const unsigned kPreHeaderSize = 4 * 2; // signature and upackSize + const unsigned kHeaderSize = 8 * 3; + Byte temp[kHeaderSize]; + if (m_InStream.ReadBytes(temp, kHeaderSize) != kHeaderSize) + return S_FALSE; + + UInt64 v; + + v = GetUi64(temp); + GET_BITS_64(v, 0, 20, numLiterals) + GET_BITS_64(v, 20, 20, litPayloadSize) + GET_BITS_64(v, 40, 20, numMatches) + GET_BITS_64_Int32(v, 60, 3 + 1, literal_bits) // (NumberOfUsedBits - 1) + literal_bits -= 7; // (-NumberOfUnusedBits) + if (literal_bits > 0) + return S_FALSE; + // GET_BITS_64(v, 63, 1, unused); + + v = GetUi64(temp + 8); + GET_BITS_64(v, 0, 10, lit_state_0) + GET_BITS_64(v, 10, 10, lit_state_1) + GET_BITS_64(v, 20, 10, lit_state_2) + GET_BITS_64(v, 30, 10, lit_state_3) + GET_BITS_64(v, 40, 20, lmdPayloadSize) + GET_BITS_64_Int32(v, 60, 3 + 1, lmd_bits) + lmd_bits -= 7; + if (lmd_bits > 0) + return S_FALSE; + // GET_BITS_64(v, 63, 1, unused) + + UInt32 v32 = GetUi32(temp + 20); + // (total header size in bytes; this does not + // correspond to a field in the uncompressed header version, + // but is required; we wouldn't know the size of the + // compresssed header otherwise. + GET_BITS_32(v32, 0, 10, l_state) + GET_BITS_32(v32, 10, 10, m_state) + GET_BITS_32(v32, 20, 10 + 2, d_state) + // GET_BITS_64(v, 62, 2, unused) + + headerSize = GetUi32(temp + 16); + if (headerSize <= kPreHeaderSize + kHeaderSize) + return S_FALSE; + headerSize -= kPreHeaderSize + kHeaderSize; + } + + // no freqs case is not allowed ? + // memset(freqs, 0, sizeof(freqs)); + // if (headerSize != 0) + { + static const Byte numBitsTable[32] = + { + 2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14, + 2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14 + }; + + static const Byte valueTable[32] = + { + 0, 2, 1, 4, 0, 3, 1, 8, 0, 2, 1, 5, 0, 3, 1, 24, + 0, 2, 1, 6, 0, 3, 1, 8, 0, 2, 1, 7, 0, 3, 1, 24 + }; + + UInt32 accum = 0; + unsigned numBits = 0; + + for (unsigned i = 0; i < NUM_SYMBOLS; i++) + { + while (numBits <= 14 && headerSize != 0) + { + Byte b; + if (!m_InStream.ReadByte(b)) + return S_FALSE; + accum |= (UInt32)b << numBits; + numBits += 8; + headerSize--; + } + + unsigned b = (unsigned)accum & 31; + unsigned n = numBitsTable[b]; + if (numBits < n) + return S_FALSE; + numBits -= n; + UInt32 f = valueTable[b]; + if (n >= 8) + f += ((accum >> 4) & (0x3ff >> (14 - n))); + accum >>= n; + freqs[i] = (UInt16)f; + } + + if (numBits >= 8 || headerSize != 0) + return S_FALSE; + } + } + + PRF(printf(" Literals=%6u Matches=%6u", numLiterals, numMatches)); + + if (numLiterals > LITERALS_PER_BLOCK + || (numLiterals & 3) != 0 + || numMatches > MATCHES_PER_BLOCK + || lit_state_0 >= NUM_LIT_STATES + || lit_state_1 >= NUM_LIT_STATES + || lit_state_2 >= NUM_LIT_STATES + || lit_state_3 >= NUM_LIT_STATES + || l_state >= NUM_L_STATES + || m_state >= NUM_M_STATES + || d_state >= NUM_D_STATES) + return S_FALSE; + + // only full table is allowed ? + if ( SumFreqs(freqs_L, NUM_L_SYMBOLS) != NUM_L_STATES + || SumFreqs(freqs_M, NUM_M_SYMBOLS) != NUM_M_STATES + || SumFreqs(freqs_D, NUM_D_SYMBOLS) != NUM_D_STATES + || SumFreqs(freqs_LIT, NUM_LIT_SYMBOLS) != NUM_LIT_STATES) + return S_FALSE; + + + const unsigned kPad = 16; + + // ---------- Decode literals ---------- + + { + _literals.AllocAtLeast(LITERALS_PER_BLOCK + 16); + _buffer.AllocAtLeast(kPad + litPayloadSize); + memset(_buffer, 0, kPad); + + if (m_InStream.ReadBytes(_buffer + kPad, litPayloadSize) != litPayloadSize) + return S_FALSE; + + UInt32 lit_decoder[NUM_LIT_STATES]; + InitLitTable(freqs_LIT, lit_decoder); + + const Byte *buf_start = _buffer + kPad; + const Byte *buf_check = buf_start - 4; + const Byte *buf = buf_start + litPayloadSize; + CBitStream in; + if (FseInStream_Init(&in, literal_bits, &buf) != 0) + return S_FALSE; + + Byte *lit = _literals; + const Byte *lit_limit = lit + numLiterals; + for (; lit < lit_limit; lit += 4) + { + FseInStream_FLUSH + DECODE_LIT (lit[0], lit_state_0) + DECODE_LIT (lit[1], lit_state_1) + FseInStream_FLUSH + DECODE_LIT (lit[2], lit_state_2) + DECODE_LIT (lit[3], lit_state_3) + } + + if ((buf_start - buf) * 8 != (int)in.numBits) + return S_FALSE; + } + + + // ---------- Decode LMD ---------- + + _buffer.AllocAtLeast(kPad + lmdPayloadSize); + memset(_buffer, 0, kPad); + if (m_InStream.ReadBytes(_buffer + kPad, lmdPayloadSize) != lmdPayloadSize) + return S_FALSE; + + CExtraEntry l_decoder[NUM_L_STATES]; + CExtraEntry m_decoder[NUM_M_STATES]; + CExtraEntry d_decoder[NUM_D_STATES]; + + InitExtraDecoderTable(NUM_L_STATES, NUM_L_SYMBOLS, freqs_L, k_L_extra, l_decoder); + InitExtraDecoderTable(NUM_M_STATES, NUM_M_SYMBOLS, freqs_M, k_M_extra, m_decoder); + InitExtraDecoderTable(NUM_D_STATES, NUM_D_SYMBOLS, freqs_D, k_D_extra, d_decoder); + + const Byte *buf_start = _buffer + kPad; + const Byte *buf_check = buf_start - 4; + const Byte *buf = buf_start + lmdPayloadSize; + CBitStream in; + if (FseInStream_Init(&in, lmd_bits, &buf)) + return S_FALSE; + + const Byte *lit = _literals; + const Byte *lit_limit = lit + numLiterals; + + UInt32 D = 0; + + for (;;) + { + if (numMatches == 0) + break; + numMatches--; + + FseInStream_FLUSH + + unsigned L = (unsigned)FseDecodeExtra(&l_state, l_decoder, &in); + + FseInStream_FLUSH + + unsigned M = (unsigned)FseDecodeExtra(&m_state, m_decoder, &in); + + FseInStream_FLUSH + + { + UInt32 new_D = FseDecodeExtra(&d_state, d_decoder, &in); + if (new_D) + D = new_D; + } + + if (L != 0) + { + if (L > (size_t)(lit_limit - lit)) + return S_FALSE; + unsigned cur = L; + if (cur > unpackSize) + cur = (unsigned)unpackSize; + m_OutWindowStream.PutBytes(lit, cur); + unpackSize -= cur; + lit += cur; + if (cur != L) + return S_FALSE; + } + + if (M != 0) + { + if (unpackSize == 0 || D == 0) + return S_FALSE; + unsigned cur = M; + if (cur > unpackSize) + cur = (unsigned)unpackSize; + if (!m_OutWindowStream.CopyBlock(D - 1, cur)) + return S_FALSE; + unpackSize -= cur; + if (cur != M) + return S_FALSE; + } + } + + if (unpackSize != 0) + return S_FALSE; + + // LZFSE encoder writes 8 additional zero bytes before LMD payload + // We test it: + if ((size_t)(buf - buf_start) * 8 + in.numBits != 64) + return S_FALSE; + if (GetUi64(buf_start) != 0) + return S_FALSE; + + return S_OK; +} + + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize)); + + const UInt32 kLzfseDictSize = 1 << 18; + if (!m_OutWindowStream.Create(kLzfseDictSize)) + return E_OUTOFMEMORY; + if (!m_InStream.Create(1 << 18)) + return E_OUTOFMEMORY; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(false); + m_InStream.SetStream(inStream); + m_InStream.Init(); + + CCoderReleaser coderReleaser(this); + + UInt64 prevOut = 0; + UInt64 prevIn = 0; + + if (LzvnMode) + { + if (!outSize || !inSize) + return E_NOTIMPL; + const UInt64 unpackSize = *outSize; + const UInt64 packSize = *inSize; + if (unpackSize > (UInt32)(Int32)-1 + || packSize > (UInt32)(Int32)-1) + return S_FALSE; + RINOK(DecodeLzvn((UInt32)unpackSize, (UInt32)packSize)) + } + else + for (;;) + { + const UInt64 pos = m_OutWindowStream.GetProcessedSize(); + const UInt64 packPos = m_InStream.GetProcessedSize(); + + if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22))) + { + RINOK(progress->SetRatioInfo(&packPos, &pos)) + prevIn = packPos; + prevOut = pos; + } + + UInt32 v; + RINOK(GetUInt32(v)) + if ((v & 0xFFFFFF) != 0x787662) // bvx + return S_FALSE; + v >>= 24; + + if (v == 0x24) // '$', end of stream + break; + + UInt32 unpackSize; + RINOK(GetUInt32(unpackSize)) + + UInt32 cur = unpackSize; + if (outSize) + { + const UInt64 rem = *outSize - pos; + if (cur > rem) + cur = (UInt32)rem; + } + unpackSize -= cur; + + HRESULT res; + if (v == kSignature_LZFSE_V1 || v == kSignature_LZFSE_V2) + res = DecodeLzfse(cur, (Byte)v); + else if (v == 0x6E) // 'n' + { + UInt32 packSize; + res = GetUInt32(packSize); + if (res == S_OK) + res = DecodeLzvn(cur, packSize); + } + else if (v == 0x2D) // '-' + res = DecodeUncompressed(cur); + else + return E_NOTIMPL; + + if (res != S_OK) + return res; + + if (unpackSize != 0) + return S_FALSE; + } + + coderReleaser.NeedFlush = false; + HRESULT res = m_OutWindowStream.Flush(); + if (res == S_OK) + if ((!LzvnMode && inSize && *inSize != m_InStream.GetProcessedSize()) + || (outSize && *outSize != m_OutWindowStream.GetProcessedSize())) + res = S_FALSE; + return res; +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return E_OUTOFMEMORY; } + // catch(...) { return S_FALSE; } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzfseDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzfseDecoder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzfseDecoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -0,0 +1,63 @@ +// LzfseDecoder.h + +#ifndef ZIP7_INC_LZFSE_DECODER_H +#define ZIP7_INC_LZFSE_DECODER_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "LzOutWindow.h" + +namespace NCompress { +namespace NLzfse { + +Z7_CLASS_IMP_NOQIB_1( + CDecoder + , ICompressCoder +) + CLzOutWindow m_OutWindowStream; + CInBuffer m_InStream; + CByteBuffer _literals; + CByteBuffer _buffer; + + class CCoderReleaser + { + CDecoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CDecoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + } + }; + friend class CCoderReleaser; + + HRESULT GetUInt32(UInt32 &val); + + HRESULT DecodeUncompressed(UInt32 unpackSize); + HRESULT DecodeLzvn(UInt32 unpackSize, UInt32 packSize); + HRESULT DecodeLzfse(UInt32 unpackSize, Byte version); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); +public: + bool LzvnMode; + + CDecoder(): + LzvnMode(false) + {} + + // sizes are checked in Code() + // UInt64 GetInputProcessedSize() const { return m_InStream.GetProcessedSize(); } + // UInt64 GetOutputProcessedSize() const { return m_OutWindowStream.GetProcessedSize(); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzhDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzhDecoder.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -1,250 +1,220 @@ -// LzhDecoder.cpp - -#include "StdAfx.h" - -#include "LzhDecoder.h" - -namespace NCompress{ -namespace NLzh { -namespace NDecoder { - -static const UInt32 kWindowSizeMin = 1 << 16; - -static bool CheckCodeLens(const Byte *lens, unsigned num) -{ - UInt32 sum = 0; - for (unsigned i = 0; i < num; i++) - { - unsigned len = lens[i]; - if (len != 0) - sum += ((UInt32)1 << (NUM_CODE_BITS - len)); - } - return sum == ((UInt32)1 << NUM_CODE_BITS); -} - -bool CCoder::ReadTP(unsigned num, unsigned numBits, int spec) -{ - _symbolT = -1; - - UInt32 n = _inBitStream.ReadBits(numBits); - if (n == 0) - { - _symbolT = _inBitStream.ReadBits(numBits); - return ((unsigned)_symbolT < num); - } - - if (n > num) - return false; - - { - Byte lens[NPT]; - unsigned i; - for (i = 0; i < NPT; i++) - lens[i] = 0; - - i = 0; - - do - { - UInt32 val = _inBitStream.GetValue(16); - unsigned c = val >> 13; - - if (c == 7) - { - UInt32 mask = 1 << 12; - while (mask & val) - { - mask >>= 1; - c++; - } - if (c > 16) - return false; - } - - _inBitStream.MovePos(c < 7 ? 3 : c - 3); - lens[i++] = (Byte)c; - - if (i == (unsigned)spec) - i += _inBitStream.ReadBits(2); - } - while (i < n); - - if (!CheckCodeLens(lens, NPT)) - return false; - return _decoderT.Build(lens); - } -} - -static const unsigned NUM_C_BITS = 9; - -bool CCoder::ReadC() -{ - _symbolC = -1; - - unsigned n = _inBitStream.ReadBits(NUM_C_BITS); - - if (n == 0) - { - _symbolC = _inBitStream.ReadBits(NUM_C_BITS); - return ((unsigned)_symbolC < NC); - } - - if (n > NC) - return false; - - { - Byte lens[NC]; - - unsigned i = 0; - - do - { - UInt32 c = (unsigned)_symbolT; - if (_symbolT < 0) - c = _decoderT.Decode(&_inBitStream); - - if (c <= 2) - { - if (c == 0) - c = 1; - else if (c == 1) - c = _inBitStream.ReadBits(4) + 3; - else - c = _inBitStream.ReadBits(NUM_C_BITS) + 20; - - if (i + c > n) - return false; - - do - lens[i++] = 0; - while (--c); - } - else - lens[i++] = (Byte)(c - 2); - } - while (i < n); - - while (i < NC) - lens[i++] = 0; - - if (!CheckCodeLens(lens, NC)) - return false; - return _decoderC.Build(lens); - } -} - -HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress) -{ - unsigned pbit = (DictSize <= (1 << 14) ? 4 : 5); - - UInt32 blockSize = 0; - - while (rem != 0) - { - if (blockSize == 0) - { - if (_inBitStream.ExtraBitsWereRead()) - return S_FALSE; - - if (progress) - { - UInt64 packSize = _inBitStream.GetProcessedSize(); - UInt64 pos = _outWindow.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - } - - blockSize = _inBitStream.ReadBits(16); - if (blockSize == 0) - return S_FALSE; - - if (!ReadTP(NT, 5, 3)) - return S_FALSE; - if (!ReadC()) - return S_FALSE; - if (!ReadTP(NP, pbit, -1)) - return S_FALSE; - } - - blockSize--; - - UInt32 number = (unsigned)_symbolC; - if (_symbolC < 0) - number = _decoderC.Decode(&_inBitStream); - - if (number < 256) - { - _outWindow.PutByte((Byte)number); - rem--; - } - else - { - UInt32 len = number - 256 + kMatchMinLen; - - UInt32 dist = (unsigned)_symbolT; - if (_symbolT < 0) - dist = _decoderT.Decode(&_inBitStream); - - if (dist > 1) - { - dist--; - dist = ((UInt32)1 << dist) + _inBitStream.ReadBits((unsigned)dist); - } - - if (dist >= DictSize) - return S_FALSE; - - if (len > rem) - len = (UInt32)rem; - - if (!_outWindow.CopyBlock(dist, len)) - return S_FALSE; - rem -= len; - } - } - - if (FinishMode) - { - if (blockSize != 0) - return S_FALSE; - if (_inBitStream.ReadAlignBits() != 0) - return S_FALSE; - } - - if (_inBitStream.ExtraBitsWereRead()) - return S_FALSE; - - return S_OK; -} - - -STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try - { - if (!outSize) - return E_INVALIDARG; - - if (!_outWindow.Create(DictSize > kWindowSizeMin ? DictSize : kWindowSizeMin)) - return E_OUTOFMEMORY; - if (!_inBitStream.Create(1 << 17)) - return E_OUTOFMEMORY; - - _outWindow.SetStream(outStream); - _outWindow.Init(false); - _inBitStream.SetStream(inStream); - _inBitStream.Init(); - - CCoderReleaser coderReleaser(this); - - RINOK(CodeReal(*outSize, progress)); - - coderReleaser.Disable(); - return _outWindow.Flush(); - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}}} +// LzhDecoder.cpp + +#include "StdAfx.h" + +#include "LzhDecoder.h" + +namespace NCompress{ +namespace NLzh { +namespace NDecoder { + +static const UInt32 kWindowSizeMin = 1 << 16; + +bool CCoder::ReadTP(unsigned num, unsigned numBits, int spec) +{ + _symbolT = -1; + + const unsigned n = (unsigned)_inBitStream.ReadBits(numBits); + if (n == 0) + { + const unsigned s = (unsigned)_inBitStream.ReadBits(numBits); + _symbolT = (int)s; + return (s < num); + } + if (n > num) + return false; + + { + Byte lens[NPT]; + unsigned i; + for (i = 0; i < NPT; i++) + lens[i] = 0; + i = 0; + do + { + unsigned val = (unsigned)_inBitStream.GetValue(16); + unsigned c = val >> 13; + unsigned mov = 3; + if (c == 7) + { + while (val & (1 << 12)) + { + val += val; + c++; + } + if (c > 16) + return false; + mov = c - 3; + } + lens[i++] = (Byte)c; + _inBitStream.MovePos(mov); + if ((int)i == spec) + i += _inBitStream.ReadBits(2); + } + while (i < n); + + return _decoderT.Build(lens, NHuffman::k_BuildMode_Full); + } +} + +static const unsigned NUM_C_BITS = 9; + +bool CCoder::ReadC() +{ + _symbolC = -1; + + const unsigned n = (unsigned)_inBitStream.ReadBits(NUM_C_BITS); + if (n == 0) + { + const unsigned s = (unsigned)_inBitStream.ReadBits(NUM_C_BITS); + _symbolC = (int)s; + return (s < NC); + } + if (n > NC) + return false; + + { + Byte lens[NC]; + unsigned i = 0; + do + { + unsigned c = (unsigned)_symbolT; + if (_symbolT < 0) + c = _decoderT.DecodeFull(&_inBitStream); + + if (c <= 2) + { + if (c == 0) + c = 1; + else if (c == 1) + c = _inBitStream.ReadBits(4) + 3; + else + c = _inBitStream.ReadBits(NUM_C_BITS) + 20; + + if (i + c > n) + return false; + + do + lens[i++] = 0; + while (--c); + } + else + lens[i++] = (Byte)(c - 2); + } + while (i < n); + + while (i < NC) lens[i++] = 0; + return _decoderC.Build(lens, /* n, */ NHuffman::k_BuildMode_Full); + } +} + +HRESULT CCoder::CodeReal(UInt32 rem, ICompressProgressInfo *progress) +{ + UInt32 blockSize = 0; + + while (rem != 0) + { + if (blockSize == 0) + { + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + if (progress) + { + const UInt64 packSize = _inBitStream.GetProcessedSize(); + const UInt64 pos = _outWindow.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) + } + + blockSize = _inBitStream.ReadBits(16); + if (blockSize == 0) + return S_FALSE; + + if (!ReadTP(NT, 5, 3)) + return S_FALSE; + if (!ReadC()) + return S_FALSE; + const unsigned pbit = (DictSize <= (1 << 14) ? 4 : 5); + if (!ReadTP(NP, pbit, -1)) + return S_FALSE; + } + + blockSize--; + + unsigned number = (unsigned)_symbolC; + if (_symbolC < 0) + number = _decoderC.DecodeFull(&_inBitStream); + + if (number < 256) + { + _outWindow.PutByte((Byte)number); + rem--; + } + else + { + const unsigned len = number - 256 + kMatchMinLen; + + UInt32 dist = (UInt32)(unsigned)_symbolT; + if (_symbolT < 0) + dist = (UInt32)_decoderT.DecodeFull(&_inBitStream); + + if (dist > 1) + { + dist--; + dist = ((UInt32)1 << dist) + _inBitStream.ReadBits((unsigned)dist); + } + + if (dist >= DictSize) + return S_FALSE; + + if (len > rem) + { + // if (FinishMode) + return S_FALSE; + // len = (unsigned)rem; + } + + if (!_outWindow.CopyBlock(dist, len)) + return S_FALSE; + rem -= len; + } + } + + // if (FinishMode) + { + if (blockSize != 0) + return S_FALSE; + if (_inBitStream.ReadAlignBits() != 0) + return S_FALSE; + } + if (_inBitStream.ExtraBitsWereRead()) + return S_FALSE; + return S_OK; +} + + +HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt32 outSize, ICompressProgressInfo *progress) +{ + try + { + if (!_outWindow.Create(DictSize > kWindowSizeMin ? DictSize : kWindowSizeMin)) + return E_OUTOFMEMORY; + if (!_inBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + _outWindow.SetStream(outStream); + _outWindow.Init(false); + _inBitStream.SetStream(inStream); + _inBitStream.Init(); + { + CCoderReleaser coderReleaser(this); + RINOK(CodeReal(outSize, progress)) + coderReleaser.Disable(); + } + return _outWindow.Flush(); + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzhDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzhDecoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzhDecoder.h 2024-01-07 09:00:00.000000000 +0000 @@ -1,74 +1,68 @@ -// LzhDecoder.h - -#ifndef __COMPRESS_LZH_DECODER_H -#define __COMPRESS_LZH_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "HuffmanDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NLzh { -namespace NDecoder { - -const unsigned kMatchMinLen = 3; -const unsigned kMatchMaxLen = 256; -const unsigned NC = (256 + kMatchMaxLen - kMatchMinLen + 1); -const unsigned NUM_CODE_BITS = 16; -const unsigned NUM_DIC_BITS_MAX = 25; -const unsigned NT = (NUM_CODE_BITS + 3); -const unsigned NP = (NUM_DIC_BITS_MAX + 1); -const unsigned NPT = NP; // Max(NT, NP) - -class CCoder: - public ICompressCoder, - public CMyUnknownImp -{ - CLzOutWindow _outWindow; - NBitm::CDecoder _inBitStream; - - int _symbolT; - int _symbolC; - - NHuffman::CDecoder _decoderT; - NHuffman::CDecoder _decoderC; - - class CCoderReleaser - { - CCoder *_coder; - public: - CCoderReleaser(CCoder *coder): _coder(coder) {} - void Disable() { _coder = NULL; } - ~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); } - }; - friend class CCoderReleaser; - - bool ReadTP(unsigned num, unsigned numBits, int spec); - bool ReadC(); - - HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress); -public: - MY_UNKNOWN_IMP - - UInt32 DictSize; - bool FinishMode; - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - void SetDictSize(unsigned dictSize) { DictSize = dictSize; } - - CCoder(): DictSize(1 << 16), FinishMode(false) {} - - UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } -}; - -}}} - -#endif +// LzhDecoder.h + +#ifndef ZIP7_INC_COMPRESS_LZH_DECODER_H +#define ZIP7_INC_COMPRESS_LZH_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NLzh { +namespace NDecoder { + +const unsigned kMatchMinLen = 3; +const unsigned kMatchMaxLen = 256; +const unsigned NC = 256 + kMatchMaxLen - kMatchMinLen + 1; +const unsigned NUM_CODE_BITS = 16; +const unsigned NUM_DIC_BITS_MAX = 25; +const unsigned NT = NUM_CODE_BITS + 3; +const unsigned NP = NUM_DIC_BITS_MAX + 1; +const unsigned NPT = NP; // Max(NT, NP) + +class CCoder +{ + CLzOutWindow _outWindow; + NBitm::CDecoder _inBitStream; + + int _symbolT; + int _symbolC; + UInt32 DictSize; + // bool FinishMode; + + NHuffman::CDecoder256 _decoderT; + NHuffman::CDecoder _decoderC; + + class CCoderReleaser + { + CCoder *_coder; + public: + CCoderReleaser(CCoder *coder): _coder(coder) {} + void Disable() { _coder = NULL; } + ~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); } + }; + friend class CCoderReleaser; + + bool ReadTP(unsigned num, unsigned numBits, int spec); + bool ReadC(); + + HRESULT CodeReal(UInt32 outSize, ICompressProgressInfo *progress); +public: + CCoder(): DictSize(1 << 16) + // , FinishMode(true) + {} + void SetDictSize(UInt32 dictSize) { DictSize = dictSize; } + UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); } + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + UInt32 outSize, ICompressProgressInfo *progress); +}; + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/LICENSE p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LICENSE --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/LICENSE 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LICENSE 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2009-2015 Richard Geldreich, Jr. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/LzhamRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LzhamRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/LzhamRegister.cpp 2015-12-03 06:36:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/LzhamRegister.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,783 +0,0 @@ -// LzhamRegister.cpp -// Portions of this module are from 7-zip, by Igor Pavlov, which you can download here: -// http://www.7-zip.org/ - -//#include "StdAfx.h" - -#ifndef _WIN32 -#define WINAPI /* */ -#endif - -#include "lzham_core.h" // for LZHAM_64BIT_POINTERS - -#include "C/Alloc.h" - -//#include "../Common/RegisterCodec.h" -#include "Common/Common.h" -#include "Common/MyCom.h" -#include "7zip/ICoder.h" -#include "7zip/Common/StreamUtils.h" -#include "7zip/Common/RegisterCodec.h" -#include "Windows/System.h" - -#include "lzham_static_lib.h" - -#if 0 -#include -#define LZHAMCODEC_DEBUG_OUTPUT 1 -#endif - -#define LZHAM_PROPS_VER (Byte)(LZHAM_DLL_VERSION) - -namespace NCompress -{ - namespace NLzham - { - struct CProps - { - CProps() { clear(); } - - void clear() - { - memset(this, 0, sizeof(*this)); - _ver = LZHAM_PROPS_VER; - _dict_size = 0; - _level = LZHAM_COMP_LEVEL_UBER; - _flags = 0; - } - - Byte _ver; - Byte _dict_size; - Byte _level; - Byte _flags; - Byte _reserved[1]; - }; - - class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public ICompressSetBufSize, -#ifndef NO_READ_FROM_CODER - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public ISequentialInStream, -#endif - public CMyUnknownImp - { - CMyComPtr _inStream; - Byte *_inBuf; - Byte *_outBuf; - UInt32 _inPos; - UInt32 _inSize; - - lzham_decompress_state_ptr _state; - - CProps _props; - bool _propsWereSet; - - bool _outSizeDefined; - UInt64 _outSize; - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - - UInt32 _inBufSizeAllocated; - UInt32 _outBufSizeAllocated; - UInt32 _inBufSize; - UInt32 _outBufSize; - - HRESULT CreateBuffers(); - HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); - - HRESULT SetOutStreamSizeResume(const UInt64 *outSize); - HRESULT CreateDecompressor(); - - public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) -#ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) -#endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - -#ifndef NO_READ_FROM_CODER - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); - UInt64 GetInputProcessedSize() const { return _inSizeProcessed; } - -#endif - - CDecoder(); - virtual ~CDecoder(); - }; - - CDecoder::CDecoder(): _inBuf(0), _outBuf(0), _propsWereSet(false), _outSizeDefined(false), - _inBufSize(1 << 22), - _outBufSize(1 << 22), - _state(NULL), - _inBufSizeAllocated(0), - _outBufSizeAllocated(0), - _inSizeProcessed(0), - _outSizeProcessed(0) - { - _inSizeProcessed = 0; - _inPos = _inSize = 0; - } - - CDecoder::~CDecoder() - { - lzham_decompress_deinit(_state); - MyFree(_inBuf); - MyFree(_outBuf); - } - - STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) - { - _inBufSize = size; - return S_OK; - } - - STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) - { - _outBufSize = size; - return S_OK; - } - - HRESULT CDecoder::CreateBuffers() - { - if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated) - { - MyFree(_inBuf); - _inBuf = (Byte *)MyAlloc(_inBufSize); - if (_inBuf == 0) - return E_OUTOFMEMORY; - _inBufSizeAllocated = _inBufSize; - } - - if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated) - { - MyFree(_outBuf); - _outBuf = (Byte *)MyAlloc(_outBufSize); - if (_outBuf == 0) - return E_OUTOFMEMORY; - _outBufSizeAllocated = _outBufSize; - } - - return S_OK; - } - - STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) - { - CProps *pProps = (CProps*)prop; - - if (size != sizeof(CProps)) - return E_FAIL; - - if (pProps->_ver != LZHAM_PROPS_VER) - return E_FAIL; - - memcpy(&_props, pProps, sizeof(CProps)); - - _propsWereSet = true; - - return CreateBuffers(); - } - - HRESULT CDecoder::CreateDecompressor() - { - if (!_propsWereSet) - return E_FAIL; - - lzham_decompress_params params; - memset(¶ms, 0, sizeof(params)); - params.m_struct_size = sizeof(lzham_decompress_params); - params.m_decompress_flags = 0; - params.m_dict_size_log2 = _props._dict_size ? _props._dict_size : 26; - - _state = lzham_decompress_reinit(_state, ¶ms); - if (!_state) - return E_FAIL; - - return S_OK; - } - - HRESULT CDecoder::SetOutStreamSizeResume(const UInt64 *outSize) - { - _outSizeDefined = (outSize != NULL); - if (_outSizeDefined) - _outSize = *outSize; - _outSizeProcessed = 0; - - RINOK(CreateDecompressor()); - - return S_OK; - } - - STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) - { - _inSizeProcessed = 0; - _inPos = _inSize = 0; - RINOK(SetOutStreamSizeResume(outSize)); - return S_OK; - } - - HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) - { - if (_inBuf == 0 || !_propsWereSet) - return S_FALSE; - - if (!_state) - { - if (CreateDecompressor() != S_OK) - return E_FAIL; - } - - UInt64 startInProgress = _inSizeProcessed; - - for (;;) - { - bool eofFlag = false; - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - if (!_inSize) - eofFlag = true; - } - - lzham_uint8 *pIn_bytes = _inBuf + _inPos; - size_t num_in_bytes = _inSize - _inPos; - lzham_uint8* pOut_bytes = _outBuf; - size_t out_num_bytes = _outBufSize; - if (_outSizeDefined) - { - UInt64 out_remaining = _outSize - _outSizeProcessed; - if (out_num_bytes > out_remaining) - out_num_bytes = static_cast(out_remaining); - } - - lzham_decompress_status_t status = lzham_decompress(_state, pIn_bytes, &num_in_bytes, pOut_bytes, &out_num_bytes, eofFlag); - - if (num_in_bytes) - { - _inPos += (UInt32)num_in_bytes; - _inSizeProcessed += (UInt32)num_in_bytes; - } - - if (out_num_bytes) - { - _outSizeProcessed += out_num_bytes; - - RINOK(WriteStream(outStream, _outBuf, out_num_bytes)); - } - - if (status >= LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE) - return S_FALSE; - - if (status == LZHAM_DECOMP_STATUS_SUCCESS) - break; - - UInt64 inSize = _inSizeProcessed - startInProgress; - if (progress) - { - RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed)); - } - } - - return S_OK; - } - - STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * inSize, const UInt64 *outSize, ICompressProgressInfo *progress) - { - if (_inBuf == 0) - return E_INVALIDARG; - SetOutStreamSize(outSize); - return CodeSpec(inStream, outStream, progress); - } - -#ifndef NO_READ_FROM_CODER - STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) - { - _inStream = inStream; - return S_OK; - } - - STDMETHODIMP CDecoder::ReleaseInStream() - { - _inStream.Release(); - return S_OK; - } - - STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) - { - if (_inBuf == 0 || !_propsWereSet) - return S_FALSE; - - if (!_state) - { - if (CreateDecompressor() != S_OK) - return E_FAIL; - } - - if (processedSize) - *processedSize = 0; - - while (size != 0) - { - bool eofFlag = false; - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - if (!_inSize) - eofFlag = true; - } - - lzham_uint8 *pIn_bytes = _inBuf + _inPos; - size_t num_in_bytes = _inSize - _inPos; - lzham_uint8* pOut_bytes = (lzham_uint8*)data; - size_t out_num_bytes = size; - - lzham_decompress_status_t status = lzham_decompress(_state, pIn_bytes, &num_in_bytes, pOut_bytes, &out_num_bytes, eofFlag); - - if (num_in_bytes) - { - _inPos += (UInt32)num_in_bytes; - _inSizeProcessed += num_in_bytes; - } - - if (out_num_bytes) - { - _outSizeProcessed += out_num_bytes; - size -= (UInt32)out_num_bytes; - if (processedSize) - *processedSize += (UInt32)out_num_bytes; - } - - if (status >= LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE) - return S_FALSE; - - if (status == LZHAM_DECOMP_STATUS_SUCCESS) - break; - } - - return S_OK; - } - - HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) - { - RINOK(SetOutStreamSizeResume(outSize)); - return CodeSpec(_inStream, outStream, progress); - } -#endif - - } // namespace NLzham -} // namespace NCompress - -static void *CreateCodec() -{ - return (void *)(ICompressCoder *)(new NCompress::NLzham::CDecoder); -} - -#ifndef EXTRACT_ONLY - -namespace NCompress -{ - namespace NLzham - { - class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp - { - lzham_compress_state_ptr _state; - CProps _props; - bool _dictSizeSet; - int _num_threads; - - Byte *_inBuf; - Byte *_outBuf; - UInt32 _inPos; - UInt32 _inSize; - - UInt32 _inBufSizeAllocated; - UInt32 _outBufSizeAllocated; - UInt32 _inBufSize; - UInt32 _outBufSize; - - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - - HRESULT CreateCompressor(); - HRESULT CreateBuffers(); - - public: - MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - - CEncoder(); - virtual ~CEncoder(); - }; - - CEncoder::CEncoder() : - _state(NULL), - _dictSizeSet(false), - _num_threads(-1), - _inBuf(NULL), - _outBuf(NULL), - _inPos(0), - _inSize(0), - _inBufSizeAllocated(0), - _outBufSizeAllocated(0), - _inBufSize(1 << 22), - _outBufSize(1 << 22), - _inSizeProcessed(0), - _outSizeProcessed(0) - { - } - - CEncoder::~CEncoder() - { - lzham_compress_deinit(_state); - MyFree(_inBuf); - MyFree(_outBuf); - } - - STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) - { - _props.clear(); - - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - switch (propID) - { - //case NCoderPropID::kEndMarker: - // if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break; - case NCoderPropID::kAlgorithm: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - - bool val = (UInt32)prop.ulVal != 0; - - if (prop.boolVal) - _props._flags |= LZHAM_COMP_FLAG_DETERMINISTIC_PARSING; - else - _props._flags &= ~LZHAM_COMP_FLAG_DETERMINISTIC_PARSING; - -#if LZHAMCODEC_DEBUG_OUTPUT - printf("Algorithm: %u\n", prop.ulVal); -#endif - - break; - } - case NCoderPropID::kNumThreads: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - _num_threads = prop.ulVal; - -#if LZHAMCODEC_DEBUG_OUTPUT - printf("Num threads: %u\n", _num_threads); -#endif - break; - } - case NCoderPropID::kDictionarySize: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - lzham_uint32 bits = 15; - while ((1U << bits) < prop.ulVal) - bits++; -#if LZHAM_64BIT_POINTERS - if (bits > LZHAM_MAX_DICT_SIZE_LOG2_X64) -#else - if (bits > LZHAM_MAX_DICT_SIZE_LOG2_X86) -#endif - { - return E_INVALIDARG; - } - - _props._dict_size = bits; - -#if LZHAMCODEC_DEBUG_OUTPUT - printf("Dict size: %u\n", bits); -#endif - - break; - } - case NCoderPropID::kLevel: - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - - switch (prop.ulVal) - { - case 0: - _props._level = 0; if (!_props._dict_size) _props._dict_size = 18; - break; - case 1: - _props._level = 0; if (!_props._dict_size) _props._dict_size = 20; - break; - case 2: - _props._level = 1; if (!_props._dict_size) _props._dict_size = 21; - break; - case 3: - _props._level = 2; if (!_props._dict_size) _props._dict_size = 21; - break; - case 4: - _props._level = 2; if (!_props._dict_size) _props._dict_size = 22; - break; - case 5: - _props._level = 3; if (!_props._dict_size) _props._dict_size = 22; - break; - case 6: - _props._level = 3; if (!_props._dict_size) _props._dict_size = 23; - break; - case 7: - _props._level = 4; if (!_props._dict_size) _props._dict_size = 25; - break; - case 8: - _props._level = 4; if (!_props._dict_size) _props._dict_size = 26; - break; - case 9: - _props._level = 4; if (!_props._dict_size) _props._dict_size = 26; - _props._flags |= LZHAM_COMP_FLAG_EXTREME_PARSING; - break; - default: - return E_INVALIDARG; - } - -#if LZHAMCODEC_DEBUG_OUTPUT - printf("Level: %u\n", prop.ulVal); -#endif - break; - } - default: - { - //RINOK(SetLzmaProp(propID, prop, props)); - break; - } - } - } - - return S_OK; - } - - STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) - { - return WriteStream(outStream, &_props, sizeof(_props)); - } - - HRESULT CEncoder::CreateBuffers() - { - if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated) - { - MyFree(_inBuf); - _inBuf = (Byte *)MyAlloc(_inBufSize); - if (_inBuf == 0) - return E_OUTOFMEMORY; - _inBufSizeAllocated = _inBufSize; - } - - if (_outBuf == 0 || _outBufSize != _outBufSizeAllocated) - { - MyFree(_outBuf); - _outBuf = (Byte *)MyAlloc(_outBufSize); - if (_outBuf == 0) - return E_OUTOFMEMORY; - _outBufSizeAllocated = _outBufSize; - } - - return S_OK; - } - - HRESULT CEncoder::CreateCompressor() - { - if (_state) - lzham_compress_deinit(_state); - - lzham_compress_params params; - memset(¶ms, 0, sizeof(params)); - params.m_struct_size = sizeof(lzham_compress_params); - -#if 0 - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - - if (_num_threads < 0) - { - if (system_info.dwNumberOfProcessors > 1) - params.m_max_helper_threads = system_info.dwNumberOfProcessors - 1; - } - else if (_num_threads > 1) - { - params.m_max_helper_threads = _num_threads - 1; - } - - if (system_info.dwNumberOfProcessors > 1) - { - if (params.m_max_helper_threads > ((int)system_info.dwNumberOfProcessors - 1)) - params.m_max_helper_threads = system_info.dwNumberOfProcessors - 1; - } -#else - UInt32 numCPUs = 1; - #ifndef _7ZIP_ST - numCPUs = NWindows::NSystem::GetNumberOfProcessors(); - #endif - if (_num_threads < 0) - { - if (numCPUs > 1) - params.m_max_helper_threads = numCPUs - 1; - } - else if (_num_threads > 1) - { - params.m_max_helper_threads = _num_threads - 1; - } - - if (numCPUs > 1) - { - if (params.m_max_helper_threads > ((int)numCPUs - 1)) - params.m_max_helper_threads = numCPUs - 1; - } - -#endif - - if (params.m_max_helper_threads > LZHAM_MAX_HELPER_THREADS) - params.m_max_helper_threads = LZHAM_MAX_HELPER_THREADS; - - params.m_dict_size_log2 = _props._dict_size ? _props._dict_size : 26; - - if (params.m_dict_size_log2 < LZHAM_MIN_DICT_SIZE_LOG2) - params.m_dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2; - else - { -#if LZHAM_64BIT_POINTERS - if (params.m_dict_size_log2 > LZHAM_MAX_DICT_SIZE_LOG2_X64) - params.m_dict_size_log2 = LZHAM_MAX_DICT_SIZE_LOG2_X64; -#else - if (params.m_dict_size_log2 > LZHAM_MAX_DICT_SIZE_LOG2_X86) - params.m_dict_size_log2 = LZHAM_MAX_DICT_SIZE_LOG2_X86; -#endif - } - - params.m_compress_flags = (lzham_compress_flags)_props._flags; - - params.m_level = (lzham_compress_level)_props._level; - -#if LZHAMCODEC_DEBUG_OUTPUT - printf("lzham_compress_params:\nmax_helper_threads: %u, dict_size_log2: %u, level: %u, deterministic_parsing: %u, extreme_parsing: %u\n", - params.m_max_helper_threads, params.m_dict_size_log2, params.m_level, (_props._flags & LZHAM_COMP_FLAG_DETERMINISTIC_PARSING) != 0, (_props._flags & LZHAM_COMP_FLAG_EXTREME_PARSING) != 0); -#endif - - _state = lzham_compress_init(¶ms); - if (!_state) - return S_FALSE; - - return S_OK; - } - - STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) - { - RINOK(CreateCompressor()); - - RINOK(CreateBuffers()); - - UInt64 startInProgress = _inSizeProcessed; - UInt64 startOutProgress = _outSizeProcessed; - - for (;;) - { - bool eofFlag = false; - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - if (!_inSize) - eofFlag = true; - } - - lzham_uint8 *pIn_bytes = _inBuf + _inPos; - size_t num_in_bytes = _inSize - _inPos; - lzham_uint8* pOut_bytes = _outBuf; - size_t out_num_bytes = _outBufSize; - - lzham_compress_status_t status = lzham_compress(_state, pIn_bytes, &num_in_bytes, pOut_bytes, &out_num_bytes, eofFlag); - - if (num_in_bytes) - { - _inPos += (UInt32)num_in_bytes; - _inSizeProcessed += (UInt32)num_in_bytes; - } - - if (out_num_bytes) - { - _outSizeProcessed += out_num_bytes; - - RINOK(WriteStream(outStream, _outBuf, out_num_bytes)); - } - - if (status >= LZHAM_COMP_STATUS_FIRST_FAILURE_CODE) - return S_FALSE; - - if (status == LZHAM_COMP_STATUS_SUCCESS) - break; - - UInt64 inSize = _inSizeProcessed - startInProgress; - UInt64 outSize = _outSizeProcessed - startOutProgress; - if (progress) - { - RINOK(progress->SetRatioInfo(&inSize, &outSize)); - } - } - - return S_OK; - } - } -} - -static void *CreateCodecOut() -{ - return (void *)(ICompressCoder *)(new NCompress::NLzham::CEncoder); -} -#else -#define CreateCodecOut 0 -#endif - -static CCodecInfo g_CodecsInfo[1] = -{ - CreateCodec, - CreateCodecOut, - 0x4F71001, - "LZHAM", - 1, - false -}; - -REGISTER_CODECS(LZHAM) diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/README.md p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/README.md --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/README.md 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/README.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -LZHAM - Lossless Data Compression Codec -============= - -

Copyright (c) 2009-2015 Richard Geldreich, Jr. - richgel99@gmail.com - MIT License

- -

Note: This is the unstable/experimental LZHAM repo, currently at v1.1. The stable repo (v1.0) is here: https://github.com/richgel999/lzham_codec

- -

LZHAM is a lossless data compression codec written in C/C++ (specifically C++03), with a compression ratio similar to LZMA but with 1.5x-8x faster decompression speed. It officially supports Linux x86/x64, Windows x86/x64, -OSX, and iOS, with Android support on the way.

- -

Some slightly out of date API documentation is here (I'll be migrating this to github): https://code.google.com/p/lzham/wiki/API_Docs

- -

Introduction

- -

LZHAM is a lossless (LZ based) data compression codec optimized for particularly fast decompression at very high compression ratios with a zlib compatible API. -It's been developed over a period of 3 years and alpha versions have already shipped in many products. (The alpha is here: https://code.google.com/p/lzham/) -LZHAM's decompressor is slower than zlib's, but generally much faster than LZMA's, with a compression ratio that is typically within a few percent of LZMA's and sometimes better.

- -

LZHAM's compressor is intended for offline use, but it is tested alongside the decompressor on mobile devices and is usable on the faster settings.

- -

LZHAM's decompressor currently has a higher cost to initialize than LZMA, so the threshold where LZHAM is typically faster vs. LZMA decompression is between 1000-13,000 of -*compressed* output bytes, depending on the platform. It is not a good small block compressor: it likes large (10KB-15KB minimum) blocks.

- -

LZHAM has simple support for patch files (delta compression), but this is a side benefit of its design, not its primary use case. Internally it supports LZ matches up -to ~64KB and very large dictionaries (up to .5 GB).

- -

LZHAM may be valuable to you if you compress data offline and distribute it to many customers, care about read/download times, and decompression speed/low CPU+power use -are important to you.

- -

I've been profiling LZHAM vs. LZMA and publishing the results on my blog: http://richg42.blogspot.com

- -

Some independent benchmarks of the previous alpha versions: http://heartofcomp.altervista.org/MOC/MOCADE.htm, http://mattmahoney.net/dc/text.html

- -

LZHAM has been integrated into the 7zip archiver (command line and GUI) as a custom codec plugin: http://richg42.blogspot.com/2015/11/lzham-custom-codec-plugin-for-7-zip.html

- -

10GB Benchmark Results

- -Results with [7zip-LZHAM 9.38 32-bit](http://richg42.blogspot.com/2015/02/7zip-938-custom-codec-plugin-for-lzham.html) (64MB dictionary) on [Matt Mahoney's 10GB benchmark](http://mattmahoney.net/dc/10gb.html): - -``` -LZHAM (-mx=8): 3,577,047,629 Archive Test Time: 70.652 secs -LZHAM (-mx=9): 3,573,782,721 Archive Test Time: 71.292 secs -LZMA (-mx=9): 3,560,052,414 Archive Test Time: 223.050 secs -7z .ZIP : 4,681,291,655 Archive Test Time: 73.304 secs (unzip v6 x64 test time: 61.074 secs) -``` - -

Most Common Question: So how does it compare to other libs like LZ4?

- -There is no single compression algorithm that perfectly suites all use cases and practical constraints. LZ4 and LZHAM are tools which lie at completely opposite ends of the spectrum: - -* LZ4: A symmetrical codec with very fast compression and decompression but very low ratios. Its compression ratio is typically less than even zlib's (which uses a 21+ year old algorithm). -LZ4 does a good job of trading off a large amount of compression ratio for very fast overall throughput. -Usage example: Reading LZMA/LZHAM/etc. compressed data from the network and decompressing it, then caching this data locally on disk using LZ4 to reduce disk usage and decrease future loading times. - -* LZHAM: A very asymmetrical codec with slow compression speed, but with a very competitive (LZMA-like) compression ratio and reasonably fast decompression speeds (slower than zlib, but faster than LZMA). -LZHAM trades off a lot of compression throughput for very high ratios and higher decompression throughput relative to other codecs in its ratio class (which is LZMA, which runs circles around LZ4's ratio). -Usage example: Compress your product's data once on a build server, distribute it to end users over a slow media like the internet, then decompress it on the end user's device. - -

How Much Memory Does It Need?

- -For decompression it's easy to compute: -* Buffered mode: decomp_mem = dict_size + ~34KB for work tables -* Unbuffered mode: decomp_mem = ~34KB - -I'll be honest here, the compressor is currently an angry beast when it comes to memory. The amount needed depends mostly on the compression level and dict. size. It's *approximately* (max_probes=128 at level -m4): -comp_mem = min(512 * 1024, dict_size / 8) * max_probes * 6 + dict_size * 9 + 22020096 - -Compression mem usage examples from Windows lzhamtest_x64 (note the equation is pretty off for small dictionary sizes): -* 32KB: 11MB -* 128KB: 21MB -* 512KB: 63MB -* 1MB: 118MB -* 8MB: 478MB -* 64MB: 982MB -* 128MB: 1558MB -* 256MB: 2710MB -* 512MB: 5014MB - -

Compressed Bitstream Compatibility

- -

v1.0's bitstream format is now locked in place, so any future v1.x releases will be backwards/forward compatible with compressed files -written with v1.0. The only thing that could change this are critical bugfixes.

- -

Note LZHAM v1.x bitstreams are NOT backwards compatible with any of the previous alpha versions on Google Code.

- -

Platforms/Compiler Support

- -LZHAM currently officially supports x86/x64 Linux, iOS, OSX, FreeBSD, and Windows x86/x64. At one time the codec compiled and ran fine on Xbox 360 (PPC, big endian). Android support is coming next. -It should be easy to retarget by modifying the macros in lzham_core.h.

- -

LZHAM has optional support for multithreaded compression. It supports gcc built-ins or MSVC intrinsics for atomic ops. For threading, it supports OSX -specific Pthreads, generic Pthreads, or Windows API's.

- -

For compilers, I've tested with gcc, clang, and MSVC 2008, 2010, and 2013. In previous alphas I also compiled with TDM-GCC x64.

- -

API

- -LZHAM supports streaming or memory to memory compression/decompression. See include/lzham.h. LZHAM can be linked statically or dynamically, just study the -headers and the lzhamtest project. -On Linux/OSX, it's only been tested with static linking so far. - -LZHAM also supports a usable subset of the zlib API with extensions, either include/zlib.h or #define LZHAM_DEFINE_ZLIB_API and use include/lzham.h. - -

Usage Tips

- -* Always try to use the smallest dictionary size that makes sense for the file or block you are compressing, i.e. don't use a 128MB dictionary for a 15KB file. The codec -doesn't automatically choose for you because in streaming scenarios it has no idea how large the file or block will be. -* The larger the dictionary, the more RAM is required during compression and decompression. I would avoid using more than 8-16MB dictionaries on iOS. -* For faster decompression, prefer "unbuffered" decompression mode vs. buffered decompression (avoids a dictionary alloc and extra memcpy()'s), and disable adler-32 checking. Also, use the built-in LZHAM API's, not the -zlib-style API's for fastest decompression. -* Experiment with the "m_table_update_rate" compression/decompression parameter. This setting trades off a small amount of ratio for faster decompression. -Note the m_table_update_rate decompression parameter MUST match the setting used during compression (same for the dictionary size). It's up to you to store this info somehow. -* Avoid using LZHAM on small *compressed* blocks, where small is 1KB-10KB compressed bytes depending on the platform. LZHAM's decompressor is only faster than LZMA's beyond the small block threshold. -Optimizing LZHAM's decompressor to reduce its startup time relative to LZMA is a high priority. -* For best compression (I've seen up to ~4% better), enable the compressor's "extreme" parser, which is much slower but finds cheaper paths through a much denser parse graph. -Note the extreme parser can greatly slow down on files containing large amounts of repeated data/strings, but it is guaranteed to finish. -* The compressor's m_level parameter can make a big impact on compression speed. Level 0 (LZHAM_COMP_LEVEL_FASTEST) uses a much simpler greedy parser, and the other levels use -near-optimal parsing with different heuristic settings. -* Check out the compressor/decompressor reinit() API's, which are useful if you'll be compressing or decompressing many times. Using the reinit() API's is a lot cheaper than fully -initializing/deinitializing the entire codec every time. -* LZHAM's compressor is no speed demon. It's usually slower than LZMA's, sometimes by a wide (~2x slower or so) margin. In "extreme" parsing mode, it can be many times slower. -This codec was designed with offline compression in mind. -* One significant difference between LZMA and LZHAM is how uncompressible files are handled. LZMA usually expands uncompressible files, and its decompressor can bog down and run extremely -slowly on uncompressible data. LZHAM internally detects when each 512KB block is uncompressible and stores these blocks as uncompressed bytes instead. -LZHAM's literal decoding is significantly faster than LZMA's, so the more plain literals in the output stream, the faster LZHAM's decompressor runs vs. LZMA's. -* General advice (applies to LZMA and other codecs too): If you are compressing large amounts of serialized game assets, sort the serialized data by asset type and compress the whole thing as a single large "solid" block of data. -Don't compress each individual asset, this will kill your ratio and have a higher decompression startup cost. If you need random access, consider compressing the assets lumped -together into groups of a few hundred kilobytes (or whatever) each. -* LZHAM is a raw codec. It doesn't include any sort of preprocessing: EXE rel to abs jump transformation, audio predictors, etc. That's up to you -to do, before compression. - -

Codec Test App

- -lzhamtest_x86/x64 is a simple command line test program that uses the LZHAM codec to compress/decompress single files. -lzhamtest is not intended as a file archiver or end user tool, it's just a simple testbed. - --- Usage examples: - -- Compress single file "source_filename" to "compressed_filename": - lzhamtest_x64 c source_filename compressed_filename - -- Decompress single file "compressed_filename" to "decompressed_filename": - lzhamtest_x64 d compressed_filename decompressed_filename - -- Compress single file "source_filename" to "compressed_filename", then verify the compressed file decompresses properly to the source file: - lzhamtest_x64 -v c source_filename compressed_filename - -- Recursively compress all files under specified directory and verify that each file decompresses properly: - lzhamtest_x64 -v a c:\source_path - --- Options - -- Set dictionary size used during compressed to 1MB (2^20): - lzhamtest_x64 -d20 c source_filename compressed_filename - -Valid dictionary sizes are [15,26] for x86, and [15,29] for x64. (See LZHAM_MIN_DICT_SIZE_LOG2, etc. defines in include/lzham.h.) -The x86 version defaults to 64MB (26), and the x64 version defaults to 256MB (28). I wouldn't recommend setting the dictionary size to -512MB unless your machine has more than 4GB of physical memory. - -- Set compression level to fastest: - lzhamtest_x64 -m0 c source_filename compressed_filename - -- Set compression level to uber (the default): - lzhamtest_x64 -m4 c source_filename compressed_filename - -- For best possible compression, use -d29 to enable the largest dictionary size (512MB) and the -x option which enables more rigorous (but ~4X slower!) parsing: - lzhamtest_x64 -d29 -x -m4 c source_filename compressed_filename - -See lzhamtest_x86/x64.exe's help text for more command line parameters. - -

Compiling LZHAM

- -- Linux: Use "cmake ." then "make". The cmake script only supports Linux at the moment. (Sorry, working on build systems is a drag.) -- OSX/iOS: Use the included XCode project. (NOTE: I haven't merged this over yet. It's coming!) -- Windows: Use the included VS 2010 project - -IMPORTANT: With clang or gcc compile LZHAM with "No strict aliasing" ENABLED: -fno-strict-aliasing - -I DO NOT test or develop the codec with strict aliasing: -* https://lkml.org/lkml/2003/2/26/158 -* http://stackoverflow.com/questions/2958633/gcc-strict-aliasing-and-horror-stories - -It might work fine, I don't know yet. This is usually not a problem with MSVC, which defaults to strict aliasing being off. - -

ANSI C/C++

- -LZHAM supports compiling as plain vanilla ANSI C/C++. To see how the codec configures itself check out lzham_core.h and search for "LZHAM_ANSI_CPLUSPLUS". -All platform specific stuff (unaligned loads, threading, atomic ops, etc.) should be disabled when this macro is defined. Note, the compressor doesn't use threads -or atomic operations when built this way so it's going to be pretty slow. (The compressor was built from the ground up to be threaded.) - -

Known Problems

- -

LZHAM's decompressor is like a drag racer that needs time to get up to speed. LZHAM is not intended or optimized to be used on "small" blocks of data (less -than ~10,000 bytes of *compressed* data on desktops, or around 1,000-5,000 on iOS). If your usage case involves calling the codec over and over with tiny blocks -then LZMA, LZ4, Deflate, etc. are probably better choices.

- -

The decompressor still takes too long to init vs. LZMA. On iOS the cost is not that bad, but on desktop the cost is high. I have reduced the startup cost vs. the -alpha but there's still work to do.

- -

The compressor is slower than I would like, and doesn't scale as well as it could. I added a reinit() method to make it initialize faster, but it's not a speed demon. -My focus has been on ratio and decompression speed.

- -

I use tabs=3 spaces, but I think some actual tabs got in the code. I need to run the sources through ClangFormat or whatever.

- -

Special Thanks

- -

Thanks to everyone at the http://encode.ru forums. I read these forums as a lurker before working on LZHAM, and I studied every LZ related -post I could get my hands on. Especially anything related to LZ optimal parsing, which still seems like a black art. LZHAM was my way of -learning how to implement optimal parsing (and you can see this if you study the progress I made in the early alphas on Google Code).

- -

Also, thanks to Igor Pavlov, the original creator of LZMA and 7zip, for advancing the start of the art in LZ compression.

diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,803 +0,0 @@ -// File: lzham.h - Copyright (c) 2009-2012 Richard Geldreich, Jr. -// LZHAM uses the MIT License. See Copyright Notice and license at the end of this file. -// -// This is the main header file, includable from C or C++ files, which defines all the publically available API's, structs, and types used by the LZHAM codec. -// -// Notes: -// -// As of LZHAM alpha8, there are now two sets of API's: -// - The first (oldest) API directly exposes all of the codec's functionality. See lzham_compress_init(), lzham_decompress_init(), etc. This API has the lowest overhead -// and is the most tested. -// - The new API implements the most useful/popular subset of the zlib API, but doesn't expose all of the codec's functionality yet. See the lzham_z* functions. -// This functionality is provided because most users of compression libraries are already very familiar with the nuts and bolts of the zlib API. -// For the most common zlib usage cases LZHAM is an almost drop-in replacement for zlib. To make switching from zlib even easier, you can define the LZHAM_DEFINE_ZLIB_API macro, -// which causes this header to #define most zlib symbols to their LZHAM equivalents. -// Note that LZHAM does not actually implement the deflate/inflate algorithm, so it cannot decompress streams created by standard zlib yet (and of course, zlib cannot decompress -// streams created by LZHAM). Internally, this API is mostly implemented via the older low-level LZHAM API. - -#ifndef __LZHAM_H__ -#define __LZHAM_H__ - -#ifdef _MSC_VER -#pragma once -#endif - -#include - -// Upper byte = major version -// Lower byte = minor version -#define LZHAM_DLL_VERSION 0x1011 - -#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) - #define LZHAM_64BIT 1 -#endif - -#if defined(_MSC_VER) - #define LZHAM_CDECL __cdecl -#else - #define LZHAM_CDECL -#endif - -#ifdef LZHAM_EXPORTS - #define LZHAM_DLL_EXPORT __declspec(dllexport) -#else - #define LZHAM_DLL_EXPORT -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - typedef unsigned char lzham_uint8; - typedef signed int lzham_int32; - typedef unsigned int lzham_uint32; - typedef unsigned int lzham_bool; - - // Returns DLL version (LZHAM_DLL_VERSION). - LZHAM_DLL_EXPORT lzham_uint32 LZHAM_CDECL lzham_get_version(void); - - // User provided memory allocation - - // Custom allocation function must return pointers with LZHAM_MIN_ALLOC_ALIGNMENT (or better). - #define LZHAM_MIN_ALLOC_ALIGNMENT sizeof(size_t) * 2 - - typedef void* (LZHAM_CDECL *lzham_realloc_func)(void* p, size_t size, size_t* pActual_size, lzham_bool movable, void* pUser_data); - typedef size_t (LZHAM_CDECL *lzham_msize_func)(void* p, void* pUser_data); - - // Call this function to force LZHAM to use custom memory malloc(), realloc(), free() and msize functions. - LZHAM_DLL_EXPORT void LZHAM_CDECL lzham_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data); - - // lzham_flush_t must map directly to the zlib-style API flush types (LZHAM_Z_NO_FLUSH, etc.) - typedef enum - { - LZHAM_NO_FLUSH = 0, - LZHAM_SYNC_FLUSH = 2, - LZHAM_FULL_FLUSH = 3, - LZHAM_FINISH = 4, - LZHAM_TABLE_FLUSH = 10 - } lzham_flush_t; - - // Compression (keep in sync with g_num_lzx_position_slots[]) - #define LZHAM_MIN_DICT_SIZE_LOG2 15 - #define LZHAM_MAX_DICT_SIZE_LOG2_X86 26 - #define LZHAM_MAX_DICT_SIZE_LOG2_X64 29 - - #define LZHAM_MAX_HELPER_THREADS 64 - - typedef enum - { - LZHAM_COMP_STATUS_NOT_FINISHED = 0, - LZHAM_COMP_STATUS_NEEDS_MORE_INPUT, - LZHAM_COMP_STATUS_HAS_MORE_OUTPUT, - - // All the following enums must indicate failure/success. - - LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE, - LZHAM_COMP_STATUS_SUCCESS = LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE, - - LZHAM_COMP_STATUS_FIRST_FAILURE_CODE, - LZHAM_COMP_STATUS_FAILED = LZHAM_COMP_STATUS_FIRST_FAILURE_CODE, - LZHAM_COMP_STATUS_FAILED_INITIALIZING, - LZHAM_COMP_STATUS_INVALID_PARAMETER, - LZHAM_COMP_STATUS_OUTPUT_BUF_TOO_SMALL, - - LZHAM_COMP_STATUS_FORCE_DWORD = 0xFFFFFFFF - } lzham_compress_status_t; - - typedef enum - { - LZHAM_COMP_LEVEL_FASTEST = 0, - LZHAM_COMP_LEVEL_FASTER, - LZHAM_COMP_LEVEL_DEFAULT, - LZHAM_COMP_LEVEL_BETTER, - LZHAM_COMP_LEVEL_UBER, - - LZHAM_TOTAL_COMP_LEVELS, - - LZHAM_COMP_LEVEL_FORCE_DWORD = 0xFFFFFFFF - } lzham_compress_level; - - // Streaming compression - typedef void *lzham_compress_state_ptr; - - typedef enum - { - LZHAM_COMP_FLAG_EXTREME_PARSING = 2, // Improves ratio by allowing the compressor's parse graph to grow "higher" (up to 4 parent nodes per output node), but is much slower. - LZHAM_COMP_FLAG_DETERMINISTIC_PARSING = 4, // Guarantees that the compressed output will always be the same given the same input and parameters (no variation between runs due to kernel threading scheduling). - - // If enabled, the compressor is free to use any optimizations which could lower the decompression rate (such - // as adaptively resetting the Huffman table update rate to maximum frequency, which is costly for the decompressor). - LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO = 16, - - LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM = 32, - - LZHAM_COMP_FLAG_FORCE_SINGLE_THREADED_PARSING = 64, - - LZHAM_COMP_FLAG_USE_LOW_MEMORY_MATCH_FINDER = 128, - - } lzham_compress_flags; - - typedef enum - { - LZHAM_INSANELY_SLOW_TABLE_UPDATE_RATE = 1, // 1=insanely slow decompression, here for reference, use 2! - LZHAM_SLOWEST_TABLE_UPDATE_RATE = 2, - LZHAM_DEFAULT_TABLE_UPDATE_RATE = 8, - LZHAM_FASTEST_TABLE_UPDATE_RATE = 20 - } lzham_table_update_rate; - - #define LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MIN (2) - - // LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MAX can be increased by the user (if you recompile lzham), I've tried up to 64. - #define LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MAX (8) - - #define LZHAM_MIN_FAST_BYTES (8) - #define LZHAM_MAX_FAST_BYTES (258) - - // Compression parameters struct. - // IMPORTANT: The values of m_dict_size_log2, m_table_update_rate, m_table_max_update_interval, and m_table_update_interval_slow_rate MUST - // match during compression and decompression. The codec does not verify these values for you, if you don't use the same settings during - // decompression it will fail (usually with a LZHAM_DECOMP_STATUS_FAILED_BAD_CODE error). - // The seed buffer's contents and size must match the seed buffer used during decompression. - typedef struct - { - lzham_uint32 m_struct_size; // set to sizeof(lzham_compress_params) - lzham_uint32 m_dict_size_log2; // set to the log2(dictionary_size), must range between [LZHAM_MIN_DICT_SIZE_LOG2, LZHAM_MAX_DICT_SIZE_LOG2_X86] for x86 LZHAM_MAX_DICT_SIZE_LOG2_X64 for x64 - lzham_compress_level m_level; // set to LZHAM_COMP_LEVEL_FASTEST, etc. - lzham_uint32 m_table_update_rate; // Controls tradeoff between ratio and decompression throughput. 0=default, or [1,LZHAM_MAX_TABLE_UPDATE_RATE], higher=faster but lower ratio. - lzham_int32 m_max_helper_threads; // max # of additional "helper" threads to create, must range between [-1,LZHAM_MAX_HELPER_THREADS], where -1=max practical - lzham_uint32 m_compress_flags; // optional compression flags (see lzham_compress_flags enum) - lzham_uint32 m_num_seed_bytes; // for delta compression (optional) - number of seed bytes pointed to by m_pSeed_bytes - const void *m_pSeed_bytes; // for delta compression (optional) - pointer to seed bytes buffer, must be at least m_num_seed_bytes long - - // Advanced settings - set to 0 if you don't care. - // m_table_max_update_interval/m_table_update_interval_slow_rate override m_table_update_rate and allow finer control over the table update settings. - // If either are non-zero they will override whatever m_table_update_rate is set to. Just leave them 0 unless you are specifically customizing them for your data. - - // def=0, typical range 12-128 (LZHAM_DEFAULT_TABLE_UPDATE_RATE=64), controls the max interval between table updates, higher=longer max interval (faster decode/lower ratio). Was 16 in prev. releases. - lzham_uint32 m_table_max_update_interval; - // def=0, 32 or higher (LZHAM_DEFAULT_TABLE_UPDATE_RATE=64), scaled by 32, controls the slowing of the update update freq, higher=more rapid slowing (faster decode/lower ratio). Was 40 in prev. releases. - lzham_uint32 m_table_update_interval_slow_rate; - - // If non-zero, must range between LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MIN and LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MAX. - // Field added in version 0x1011 - lzham_uint32 m_extreme_parsing_max_best_arrivals; - - // If non-zero, must range between LZHAM_MIN_FAST_BYTES-LZHAM_MAX_FAST_BYTES. - // If this is 0, the compressor will either use a fast_bytes setting controlled by m_level, or a for extreme parsing a fixed setting of LZHAM_EXTREME_PARSING_FAST_BYTES (96). - // Field added in version 0x1011 - lzham_uint32 m_fast_bytes; - - } lzham_compress_params; - - // Initializes a compressor. Returns a pointer to the compressor's internal state, or NULL on failure. - // pParams cannot be NULL. Be sure to initialize the pParams->m_struct_size member to sizeof(lzham_compress_params) (along with the other members to reasonable values) before calling this function. - // TODO: With large dictionaries this function could take a while (due to memory allocation). I need to add a reinit() API for compression (decompression already has one). - LZHAM_DLL_EXPORT lzham_compress_state_ptr LZHAM_CDECL lzham_compress_init(const lzham_compress_params *pParams); - - LZHAM_DLL_EXPORT lzham_compress_state_ptr LZHAM_CDECL lzham_compress_reinit(lzham_compress_state_ptr pState); - - // Deinitializes a compressor, releasing all allocated memory. - // returns adler32 of source data (valid only on success). - LZHAM_DLL_EXPORT lzham_uint32 LZHAM_CDECL lzham_compress_deinit(lzham_compress_state_ptr pState); - - // Compresses an arbitrarily sized block of data, writing as much available compressed data as possible to the output buffer. - // This method may be called as many times as needed, but for best perf. try not to call it with tiny buffers. - // pState - Pointer to internal compression state, created by lzham_compress_init. - // pIn_buf, pIn_buf_size - Pointer to input data buffer, and pointer to a size_t containing the number of bytes available in this buffer. - // On return, *pIn_buf_size will be set to the number of bytes read from the buffer. - // pOut_buf, pOut_buf_size - Pointer to the output data buffer, and a pointer to a size_t containing the max number of bytes that can be written to this buffer. - // On return, *pOut_buf_size will be set to the number of bytes written to this buffer. - // no_more_input_bytes_flag - Set to true to indicate that no more input bytes are available to compress (EOF). Once you call this function with this param set to true, it must stay set to true in all future calls. - // - // Normal return status codes: - // LZHAM_COMP_STATUS_NOT_FINISHED - Compression can continue, but the compressor needs more input, or it needs more room in the output buffer. - // LZHAM_COMP_STATUS_NEEDS_MORE_INPUT - Compression can contintue, but the compressor has no more output, and has no input but we're not at EOF. Supply more input to continue. - // Success/failure return status codes: - // LZHAM_COMP_STATUS_SUCCESS - Compression has completed successfully. - // LZHAM_COMP_STATUS_FAILED, LZHAM_COMP_STATUS_FAILED_INITIALIZING, LZHAM_COMP_STATUS_INVALID_PARAMETER - Something went wrong. - LZHAM_DLL_EXPORT lzham_compress_status_t LZHAM_CDECL lzham_compress( - lzham_compress_state_ptr pState, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag); - - LZHAM_DLL_EXPORT lzham_compress_status_t LZHAM_CDECL lzham_compress2( - lzham_compress_state_ptr pState, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_flush_t flush_type); - - // Single function call compression interface. - // Same return codes as lzham_compress, except this function can also return LZHAM_COMP_STATUS_OUTPUT_BUF_TOO_SMALL. - LZHAM_DLL_EXPORT lzham_compress_status_t LZHAM_CDECL lzham_compress_memory( - const lzham_compress_params *pParams, - lzham_uint8* pDst_buf, - size_t *pDst_len, - const lzham_uint8* pSrc_buf, - size_t src_len, - lzham_uint32 *pAdler32); - - // Decompression - typedef enum - { - // LZHAM_DECOMP_STATUS_NOT_FINISHED indicates that the decompressor is flushing its internal buffer to the caller's output buffer. - // There may be more bytes available to decompress on the next call, but there is no guarantee. - LZHAM_DECOMP_STATUS_NOT_FINISHED = 0, - - // LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT indicates that the decompressor is trying to flush its internal buffer to the caller's output buffer, - // but the caller hasn't provided any space to copy this data to the caller's output buffer. Call the lzham_decompress() again with a non-empty sized output buffer. - LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT, - - // LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT indicates that the decompressor has consumed all input bytes, has not encountered an "end of stream" code, - // and the caller hasn't set no_more_input_bytes_flag to true, so it's expecting more input to proceed. - LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT, - - // All the following enums always (and MUST) indicate failure/success. - LZHAM_DECOMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE, - - // LZHAM_DECOMP_STATUS_SUCCESS indicates decompression has successfully completed. - LZHAM_DECOMP_STATUS_SUCCESS = LZHAM_DECOMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE, - - // The remaining status codes indicate a failure of some sort. Most failures are unrecoverable. TODO: Document which codes are recoverable. - LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE, - - LZHAM_DECOMP_STATUS_FAILED_INITIALIZING = LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE, - LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL, - LZHAM_DECOMP_STATUS_FAILED_EXPECTED_MORE_RAW_BYTES, - LZHAM_DECOMP_STATUS_FAILED_BAD_CODE, - LZHAM_DECOMP_STATUS_FAILED_ADLER32, - LZHAM_DECOMP_STATUS_FAILED_BAD_RAW_BLOCK, - LZHAM_DECOMP_STATUS_FAILED_BAD_COMP_BLOCK_SYNC_CHECK, - LZHAM_DECOMP_STATUS_FAILED_BAD_ZLIB_HEADER, - LZHAM_DECOMP_STATUS_FAILED_NEED_SEED_BYTES, - LZHAM_DECOMP_STATUS_FAILED_BAD_SEED_BYTES, - LZHAM_DECOMP_STATUS_FAILED_BAD_SYNC_BLOCK, - LZHAM_DECOMP_STATUS_INVALID_PARAMETER, - } lzham_decompress_status_t; - - typedef void *lzham_decompress_state_ptr; - - typedef enum - { - LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED = 1, - LZHAM_DECOMP_FLAG_COMPUTE_ADLER32 = 2, - LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM = 4, - } lzham_decompress_flags; - - // Decompression parameters structure. - // Notes: - // m_dict_size_log2 MUST match the value used during compression! - // If m_num_seed_bytes != 0, LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED must not be set (i.e. static "seed" dictionaries are not compatible with unbuffered decompression). - // The seed buffer's contents and size must match the seed buffer used during compression. - // m_table_update_rate (or m_table_max_update_interval/m_table_update_interval_slow_rate) MUST match the values used for compression! - typedef struct - { - lzham_uint32 m_struct_size; // set to sizeof(lzham_decompress_params) - lzham_uint32 m_dict_size_log2; // set to the log2(dictionary_size), must range between [LZHAM_MIN_DICT_SIZE_LOG2, LZHAM_MAX_DICT_SIZE_LOG2_X86] for x86 LZHAM_MAX_DICT_SIZE_LOG2_X64 for x64 - lzham_uint32 m_table_update_rate; // Controls tradeoff between ratio and decompression throughput. 0=default, or [1,LZHAM_MAX_TABLE_UPDATE_RATE], higher=faster but lower ratio. - lzham_uint32 m_decompress_flags; // optional decompression flags (see lzham_decompress_flags enum) - lzham_uint32 m_num_seed_bytes; // for delta compression (optional) - number of seed bytes pointed to by m_pSeed_bytes - const void *m_pSeed_bytes; // for delta compression (optional) - pointer to seed bytes buffer, must be at least m_num_seed_bytes long - - // Advanced settings - set to 0 if you don't care. - // m_table_max_update_interval/m_table_update_interval_slow_rate override m_table_update_rate and allow finer control over the table update settings. - // If either are non-zero they will override whatever m_table_update_rate is set to. Just leave them 0 unless you are specifically customizing them for your data. - - // def=0, typical range 12-128 (LZHAM_DEFAULT_TABLE_UPDATE_RATE=64), controls the max interval between table updates, higher=longer max interval (faster decode/lower ratio). Was 16 in prev. releases. - lzham_uint32 m_table_max_update_interval; - // def=0, 32 or higher (LZHAM_DEFAULT_TABLE_UPDATE_RATE=64), scaled by 32, controls the slowing of the update update freq, higher=more rapid slowing (faster decode/lower ratio). Was 40 in prev. releases. - lzham_uint32 m_table_update_interval_slow_rate; - - } lzham_decompress_params; - - // Initializes a decompressor. - // pParams cannot be NULL. Be sure to initialize the pParams->m_struct_size member to sizeof(lzham_decompress_params) (along with the other members to reasonable values) before calling this function. - // Note: With large dictionaries this function could take a while (due to memory allocation). To serially decompress multiple streams, it's faster to init a compressor once and - // reuse it using by calling lzham_decompress_reinit(). - LZHAM_DLL_EXPORT lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_init(const lzham_decompress_params *pParams); - - // Quickly re-initializes the decompressor to its initial state given an already allocated/initialized state (doesn't do any memory alloc unless necessary). - LZHAM_DLL_EXPORT lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_reinit(lzham_decompress_state_ptr pState, const lzham_decompress_params *pParams); - - // Deinitializes a decompressor. - // returns adler32 of decompressed data if compute_adler32 was true, otherwise it returns the adler32 from the compressed stream. - LZHAM_DLL_EXPORT lzham_uint32 LZHAM_CDECL lzham_decompress_deinit(lzham_decompress_state_ptr pState); - - // Decompresses an arbitrarily sized block of compressed data, writing as much available decompressed data as possible to the output buffer. - // This method is implemented as a coroutine so it may be called as many times as needed. However, for best perf. try not to call it with tiny buffers. - // pState - Pointer to internal decompression state, originally created by lzham_decompress_init. - // pIn_buf, pIn_buf_size - Pointer to input data buffer, and pointer to a size_t containing the number of bytes available in this buffer. - // On return, *pIn_buf_size will be set to the number of bytes read from the buffer. - // pOut_buf, pOut_buf_size - Pointer to the output data buffer, and a pointer to a size_t containing the max number of bytes that can be written to this buffer. - // On return, *pOut_buf_size will be set to the number of bytes written to this buffer. - // no_more_input_bytes_flag - Set to true to indicate that no more input bytes are available to compress (EOF). Once you call this function with this param set to true, it must stay set to true in all future calls. - // Notes: - // In unbuffered mode, the output buffer MUST be large enough to hold the entire decompressed stream. Otherwise, you'll receive the - // LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL error (which is currently unrecoverable during unbuffered decompression). - // In buffered mode, if the output buffer's size is 0 bytes, the caller is indicating that no more output bytes are expected from the - // decompressor. In this case, if the decompressor actually has more bytes you'll receive the LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT - // error (which is recoverable in the buffered case - just call lzham_decompress() again with a non-zero size output buffer). - LZHAM_DLL_EXPORT lzham_decompress_status_t LZHAM_CDECL lzham_decompress( - lzham_decompress_state_ptr pState, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag); - - // Single function call interface. - LZHAM_DLL_EXPORT lzham_decompress_status_t LZHAM_CDECL lzham_decompress_memory( - const lzham_decompress_params *pParams, - lzham_uint8* pDst_buf, - size_t *pDst_len, - const lzham_uint8* pSrc_buf, - size_t src_len, - lzham_uint32 *pAdler32); - - // ------------------- zlib-style API Definitions. - - // Important note: LZHAM doesn't internally support the Deflate algorithm, but for API compatibility the "Deflate" and "Inflate" names are retained here. - - typedef unsigned long lzham_z_ulong; - - // Heap allocation callbacks. - // Note that lzham_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. - typedef void *(*lzham_z_alloc_func)(void *opaque, size_t items, size_t size); - typedef void (*lzham_z_free_func)(void *opaque, void *address); - typedef void *(*lzham_z_realloc_func)(void *opaque, void *address, size_t items, size_t size); - - #define LZHAM_Z_ADLER32_INIT (1) - // lzham_adler32() returns the initial adler-32 value to use when called with ptr==NULL. - LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len); - - #define LZHAM_Z_CRC32_INIT (0) - // lzham_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. - LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_crc32(lzham_z_ulong crc, const unsigned char *ptr, size_t buf_len); - - // Compression strategies. - enum - { - LZHAM_Z_DEFAULT_STRATEGY = 0, - LZHAM_Z_FILTERED = 1, - LZHAM_Z_HUFFMAN_ONLY = 2, - LZHAM_Z_RLE = 3, - LZHAM_Z_FIXED = 4 - }; - - // Method - #define LZHAM_Z_DEFLATED 8 - #define LZHAM_Z_LZHAM 14 - - #define LZHAM_Z_VERSION "10.8.1" - #define LZHAM_Z_VERNUM 0xA810 - #define LZHAM_Z_VER_MAJOR 10 - #define LZHAM_Z_VER_MINOR 8 - #define LZHAM_Z_VER_REVISION 1 - #define LZHAM_Z_VER_SUBREVISION 0 - - // Flush values. - // For compression, you typically only need to use LZHAM_NO_FLUSH and LZHAM_FINISH. - // LZHAM_Z_SYNC_FLUSH and LZHAM_Z_FULL_FLUSH during compression forces compression of all buffered input. - // - // For decompression, you typically only need to use LZHAM_Z_SYNC_FLUSH or LZHAM_Z_FINISH. - // LZHAM_Z_FINISH during decompression guarantees that the output buffer is large enough to hold all remaining data to decompress. - // See http://www.bolet.org/~pornin/deflate-flush.html - // Must directly map to lzham_flush_t - enum - { - LZHAM_Z_NO_FLUSH = 0, // compression/decompression - LZHAM_Z_PARTIAL_FLUSH = 1, // compression/decompression, same as LZHAM_Z_SYNC_FLUSH - LZHAM_Z_SYNC_FLUSH = 2, // compression/decompression, when compressing: flush current block (if any), always outputs sync block (aligns output to byte boundary, a 0xFFFF0000 marker will appear in the output stream) - LZHAM_Z_FULL_FLUSH = 3, // compression/decompression, when compressing: same as LZHAM_Z_SYNC_FLUSH but also forces a full state flush (LZ dictionary, all symbol statistics) - LZHAM_Z_FINISH = 4, // compression/decompression - LZHAM_Z_BLOCK = 5, // not supported - LZHAM_Z_TABLE_FLUSH = 10 // compression only, resets all symbol table update rates to maximum frequency (LZHAM extension) - }; - - // Return status codes. LZHAM_Z_PARAM_ERROR is non-standard. - enum - { - LZHAM_Z_OK = 0, - LZHAM_Z_STREAM_END = 1, - LZHAM_Z_NEED_DICT = 2, - LZHAM_Z_ERRNO = -1, - LZHAM_Z_STREAM_ERROR = -2, - LZHAM_Z_DATA_ERROR = -3, - LZHAM_Z_MEM_ERROR = -4, - LZHAM_Z_BUF_ERROR = -5, - LZHAM_Z_VERSION_ERROR = -6, - LZHAM_Z_PARAM_ERROR = -10000 - }; - - // Compression levels. - enum - { - LZHAM_Z_NO_COMPRESSION = 0, - LZHAM_Z_BEST_SPEED = 1, - LZHAM_Z_BEST_COMPRESSION = 9, - LZHAM_Z_UBER_COMPRESSION = 10, // uber = best with extreme parsing (can be very slow) - LZHAM_Z_DEFAULT_COMPRESSION = -1 - }; - - // Window bits - // Important note: The zlib-style API's default to 32KB dictionary for API compatibility. For improved compression, be sure to call deflateInit2/inflateInit2 and specify larger custom window_bits values! - // If changing the calling code isn't practical, unremark LZHAM_Z_API_FORCE_WINDOW_BITS. - #define LZHAM_Z_DEFAULT_WINDOW_BITS 15 - - // Define LZHAM_Z_API_FORCE_WINDOW_BITS to force the entire library to use a constant value for window_bits (helps with porting) in all zlib API's. - // TODO: Might be useful to provide an API to control this at runtime. - //#define LZHAM_Z_API_FORCE_WINDOW_BITS 23 - - // Data types - #define LZHAM_Z_BINARY 0 - #define LZHAM_Z_TEXT 1 - #define LZHAM_Z_ASCII 1 - #define LZHAM_Z_UNKNOWN 2 - - struct lzham_z_internal_state; - - // Compression/decompression stream struct. - typedef struct - { - const unsigned char *next_in; // pointer to next byte to read - unsigned int avail_in; // number of bytes available at next_in - lzham_z_ulong total_in; // total number of bytes consumed so far - - unsigned char *next_out; // pointer to next byte to write - unsigned int avail_out; // number of bytes that can be written to next_out - lzham_z_ulong total_out; // total number of bytes produced so far - - char *msg; // error msg (unused) - struct lzham_z_internal_state *state; // internal state, allocated by zalloc/zfree - - // LZHAM does not support per-stream heap callbacks. Use lzham_set_memory_callbacks() instead. - // These members are ignored - they are here for backwards compatibility with zlib. - lzham_z_alloc_func zalloc; // optional heap allocation function (defaults to malloc) - lzham_z_free_func zfree; // optional heap free function (defaults to free) - void *opaque; // heap alloc function user pointer - - int data_type; // data_type (unused) - lzham_z_ulong adler; // adler32 of the source or uncompressed data - lzham_z_ulong reserved; // not used - } lzham_z_stream; - - typedef lzham_z_stream *lzham_z_streamp; - - LZHAM_DLL_EXPORT const char *lzham_z_version(void); - - // lzham_deflateInit() initializes a compressor with default options: - // Parameters: - // pStream must point to an initialized lzham_stream struct. - // level must be between [LZHAM_NO_COMPRESSION, LZHAM_BEST_COMPRESSION]. - // level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. - // Return values: - // LZHAM_OK on success. - // LZHAM_STREAM_ERROR if the stream is bogus. - // LZHAM_PARAM_ERROR if the input parameters are bogus. - // LZHAM_MEM_ERROR on out of memory. - LZHAM_DLL_EXPORT int lzham_z_deflateInit(lzham_z_streamp pStream, int level); - - // lzham_deflateInit2() is like lzham_deflate(), except with more control: - // Additional parameters: - // method must be LZHAM_Z_DEFLATED or LZHAM_Z_LZHAM (LZHAM_Z_DEFLATED will be internally converted to LZHAM_Z_LZHAM with a windowsize of LZHAM_Z_DEFAULT_WINDOW_BITS) - // window_bits must be LZHAM_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -LZHAM_Z_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) - // mem_level must be between [1, 9] (it's checked but ignored by lzham) - LZHAM_DLL_EXPORT int lzham_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); - - // Quickly resets a compressor without having to reallocate anything. Same as calling lzham_z_deflateEnd() followed by lzham_z_deflateInit()/lzham_z_deflateInit2(). - LZHAM_DLL_EXPORT int lzham_z_deflateReset(lzham_z_streamp pStream); - - // lzham_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. - // Parameters: - // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. - // flush may be LZHAM_Z_NO_FLUSH, LZHAM_Z_PARTIAL_FLUSH/LZHAM_Z_SYNC_FLUSH, LZHAM_Z_FULL_FLUSH, or LZHAM_Z_FINISH. - // Return values: - // LZHAM_Z_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). - // LZHAM_Z_STREAM_END if all input has been consumed and all output bytes have been written. Don't call lzham_z_deflate() on the stream anymore. - // LZHAM_Z_STREAM_ERROR if the stream is bogus. - // LZHAM_Z_PARAM_ERROR if one of the parameters is invalid. - // LZHAM_Z_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) - LZHAM_DLL_EXPORT int lzham_z_deflate(lzham_z_streamp pStream, int flush); - - // lzham_deflateEnd() deinitializes a compressor: - // Return values: - // LZHAM_Z_OK on success. - // LZHAM_Z_STREAM_ERROR if the stream is bogus. - LZHAM_DLL_EXPORT int lzham_z_deflateEnd(lzham_z_streamp pStream); - - // lzham_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by lzham_z_deflate(), assuming flush is set to only LZHAM_Z_NO_FLUSH or LZHAM_Z_FINISH. - LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len); - - // Single-call compression functions lzham_z_compress() and lzham_z_compress2(): - // Returns LZHAM_Z_OK on success, or one of the error codes from lzham_z_deflate() on failure. - LZHAM_DLL_EXPORT int lzham_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - LZHAM_DLL_EXPORT int lzham_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level); - - // lzham_z_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling lzham_z_compress(). - LZHAM_DLL_EXPORT lzham_z_ulong lzham_z_compressBound(lzham_z_ulong source_len); - - // Initializes a decompressor. - LZHAM_DLL_EXPORT int lzham_z_inflateInit(lzham_z_streamp pStream); - - // lzham_z_inflateInit2() is like lzham_z_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: - // window_bits must be LZHAM_Z_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -LZHAM_Z_DEFAULT_WINDOW_BITS (raw stream with no zlib header/footer). - LZHAM_DLL_EXPORT int lzham_z_inflateInit2(lzham_z_streamp pStream, int window_bits); - - LZHAM_DLL_EXPORT int lzham_z_inflateReset(lzham_z_streamp pStream); - - // Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. - // Parameters: - // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. - // flush may be LZHAM_Z_NO_FLUSH, LZHAM_Z_SYNC_FLUSH, or LZHAM_Z_FINISH. - // On the first call, if flush is LZHAM_Z_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). - // LZHAM_Z_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. - // Return values: - // LZHAM_Z_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. - // LZHAM_Z_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. - // LZHAM_Z_STREAM_ERROR if the stream is bogus. - // LZHAM_Z_DATA_ERROR if the deflate stream is invalid. - // LZHAM_Z_PARAM_ERROR if one of the parameters is invalid. - // LZHAM_Z_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call lzham_inflate() again - // with more input data, or with more room in the output buffer (except when using single call decompression, described above). - LZHAM_DLL_EXPORT int lzham_z_inflate(lzham_z_streamp pStream, int flush); - - // Deinitializes a decompressor. - LZHAM_DLL_EXPORT int lzham_z_inflateEnd(lzham_z_streamp pStream); - - // Single-call decompression. - // Returns LZHAM_OK on success, or one of the error codes from lzham_inflate() on failure. - LZHAM_DLL_EXPORT int lzham_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - - // Returns a string description of the specified error code, or NULL if the error code is invalid. - LZHAM_DLL_EXPORT const char *lzham_z_error(int err); - - // Redefine zlib-compatible names to lzham equivalents, so lzham can be used as a more or less drop-in replacement for the subset of zlib that lzham supports. - // Define LZHAM_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. - #ifdef LZHAM_DEFINE_ZLIB_API - typedef unsigned char Byte; - typedef unsigned int uInt; - typedef lzham_z_ulong uLong; - typedef Byte Bytef; - typedef uInt uIntf; - typedef char charf; - typedef int intf; - typedef void *voidpf; - typedef uLong uLongf; - typedef void *voidp; - typedef void *const voidpc; - #define Z_NULL 0 - #define Z_NO_FLUSH LZHAM_Z_NO_FLUSH - #define Z_PARTIAL_FLUSH LZHAM_Z_PARTIAL_FLUSH - #define Z_SYNC_FLUSH LZHAM_Z_SYNC_FLUSH - #define Z_FULL_FLUSH LZHAM_Z_FULL_FLUSH - #define Z_FINISH LZHAM_Z_FINISH - #define Z_BLOCK LZHAM_Z_BLOCK - #define Z_OK LZHAM_Z_OK - #define Z_STREAM_END LZHAM_Z_STREAM_END - #define Z_NEED_DICT LZHAM_Z_NEED_DICT - #define Z_ERRNO LZHAM_Z_ERRNO - #define Z_STREAM_ERROR LZHAM_Z_STREAM_ERROR - #define Z_DATA_ERROR LZHAM_Z_DATA_ERROR - #define Z_MEM_ERROR LZHAM_Z_MEM_ERROR - #define Z_BUF_ERROR LZHAM_Z_BUF_ERROR - #define Z_VERSION_ERROR LZHAM_Z_VERSION_ERROR - #define Z_PARAM_ERROR LZHAM_Z_PARAM_ERROR - #define Z_NO_COMPRESSION LZHAM_Z_NO_COMPRESSION - #define Z_BEST_SPEED LZHAM_Z_BEST_SPEED - #define Z_BEST_COMPRESSION LZHAM_Z_BEST_COMPRESSION - #define Z_DEFAULT_COMPRESSION LZHAM_Z_DEFAULT_COMPRESSION - #define Z_DEFAULT_STRATEGY LZHAM_Z_DEFAULT_STRATEGY - #define Z_FILTERED LZHAM_Z_FILTERED - #define Z_HUFFMAN_ONLY LZHAM_Z_HUFFMAN_ONLY - #define Z_RLE LZHAM_Z_RLE - #define Z_FIXED LZHAM_Z_FIXED - #define Z_DEFLATED LZHAM_Z_DEFLATED - #define Z_DEFAULT_WINDOW_BITS LZHAM_Z_DEFAULT_WINDOW_BITS - #define alloc_func lzham_z_alloc_func - #define free_func lzham_z_free_func - #define internal_state lzham_z_internal_state - #define z_stream lzham_z_stream - #define deflateInit lzham_z_deflateInit - #define deflateInit2 lzham_z_deflateInit2 - #define deflateReset lzham_z_deflateReset - #define deflate lzham_z_deflate - #define deflateEnd lzham_z_deflateEnd - #define deflateBound lzham_z_deflateBound - #define compress lzham_z_compress - #define compress2 lzham_z_compress2 - #define compressBound lzham_z_compressBound - #define inflateInit lzham_z_inflateInit - #define inflateInit2 lzham_z_inflateInit2 - #define inflateReset lzham_z_inflateReset - #define inflate lzham_z_inflate - #define inflateEnd lzham_z_inflateEnd - #define uncompress lzham_z_uncompress - #define crc32 lzham_z_crc32 - #define adler32 lzham_z_adler32 - #define MAX_WBITS 26 - #define MAX_MEM_LEVEL 9 - #define zError lzham_z_error - #define ZLIB_VERSION LZHAM_Z_VERSION - #define ZLIB_VERNUM LZHAM_Z_VERNUM - #define ZLIB_VER_MAJOR LZHAM_Z_VER_MAJOR - #define ZLIB_VER_MINOR LZHAM_Z_VER_MINOR - #define ZLIB_VER_REVISION LZHAM_Z_VER_REVISION - #define ZLIB_VER_SUBREVISION LZHAM_Z_VER_SUBREVISION - #define zlibVersion lzham_z_version - #define zlib_version lzham_z_version() - #define Z_BINARY LZHAM_Z_BINARY - #define Z_TEXT LZHAM_Z_TEST - #define Z_ASCII LZHAM_Z_ASCII - #define Z_UNKNOWN LZHAM_Z_UNKNOWN - #endif // #ifdef LZHAM_DEFINE_ZLIB_API - - // Exported function typedefs, to simplify loading the LZHAM DLL dynamically. - typedef lzham_uint32 (LZHAM_CDECL *lzham_get_version_func)(void); - typedef void (LZHAM_CDECL *lzham_set_memory_callbacks_func)(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data); - - typedef lzham_compress_state_ptr (LZHAM_CDECL *lzham_compress_init_func)(const lzham_compress_params *pParams); - typedef lzham_compress_state_ptr (LZHAM_CDECL *lzham_compress_reinit_func)(lzham_compress_state_ptr pState); - typedef lzham_uint32 (LZHAM_CDECL *lzham_compress_deinit_func)(lzham_compress_state_ptr pState); - typedef lzham_compress_status_t (LZHAM_CDECL *lzham_compress_func)(lzham_compress_state_ptr pState, const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, lzham_uint8 *pOut_buf, size_t *pOut_buf_size, lzham_bool no_more_input_bytes_flag); - typedef lzham_compress_status_t (LZHAM_CDECL *lzham_compress2_func)(lzham_compress_state_ptr pState, const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, lzham_uint8 *pOut_buf, size_t *pOut_buf_size, lzham_flush_t flush_type); - typedef lzham_compress_status_t (LZHAM_CDECL *lzham_compress_memory_func)(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); - - typedef lzham_decompress_state_ptr (LZHAM_CDECL *lzham_decompress_init_func)(const lzham_decompress_params *pParams); - typedef lzham_decompress_state_ptr (LZHAM_CDECL *lzham_decompress_reinit_func)(lzham_compress_state_ptr pState, const lzham_decompress_params *pParams); - typedef lzham_uint32 (LZHAM_CDECL *lzham_decompress_deinit_func)(lzham_decompress_state_ptr pState); - typedef lzham_decompress_status_t (LZHAM_CDECL *lzham_decompress_func)(lzham_decompress_state_ptr pState, const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, lzham_uint8 *pOut_buf, size_t *pOut_buf_size, lzham_bool no_more_input_bytes_flag); - typedef lzham_decompress_status_t (LZHAM_CDECL *lzham_decompress_memory_func)(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); - - typedef const char *(LZHAM_CDECL *lzham_z_version_func)(void); - typedef int (LZHAM_CDECL *lzham_z_deflateInit_func)(lzham_z_streamp pStream, int level); - typedef int (LZHAM_CDECL *lzham_z_deflateInit2_func)(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); - typedef int (LZHAM_CDECL *lzham_z_deflateReset_func)(lzham_z_streamp pStream); - typedef int (LZHAM_CDECL *lzham_z_deflate_func)(lzham_z_streamp pStream, int flush); - typedef int (LZHAM_CDECL *lzham_z_deflateEnd_func)(lzham_z_streamp pStream); - typedef lzham_z_ulong (LZHAM_CDECL *lzham_z_deflateBound_func)(lzham_z_streamp pStream, lzham_z_ulong source_len); - typedef int (LZHAM_CDECL *lzham_z_compress_func)(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - typedef int (LZHAM_CDECL *lzham_z_compress2_func)(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level); - typedef lzham_z_ulong (LZHAM_CDECL *lzham_z_compressBound_func)(lzham_z_ulong source_len); - typedef int (LZHAM_CDECL *lzham_z_inflateInit_func)(lzham_z_streamp pStream); - typedef int (LZHAM_CDECL *lzham_z_inflateInit2_func)(lzham_z_streamp pStream, int window_bits); - typedef int (LZHAM_CDECL *lzham_z_inflateReset_func)(lzham_z_streamp pStream); - typedef int (LZHAM_CDECL *lzham_z_inflate_func)(lzham_z_streamp pStream, int flush); - typedef int (LZHAM_CDECL *lzham_z_inflateEnd_func)(lzham_z_streamp pStream); - typedef int (LZHAM_CDECL *lzham_z_uncompress_func)(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - typedef const char *(LZHAM_CDECL *lzham_z_error_func)(int err); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -// This optional interface is used by the dynamic/static link helpers defined in lzham_dynamic_lib.h and lzham_static_lib.h. -// It allows code to always call LZHAM the same way, independent of how it was linked into the app (statically or dynamically). -class ilzham -{ - ilzham(const ilzham &other); - ilzham& operator= (const ilzham &rhs); - -public: - ilzham() { clear(); } - - virtual ~ilzham() { } - virtual bool load() = 0; - virtual void unload() = 0; - virtual bool is_loaded() = 0; - - void clear() - { - this->lzham_get_version = NULL; - this->lzham_set_memory_callbacks = NULL; - - this->lzham_compress_init = NULL; - this->lzham_compress_reinit = NULL; - this->lzham_compress_deinit = NULL; - this->lzham_compress = NULL; - this->lzham_compress2 = NULL; - this->lzham_compress_memory = NULL; - - this->lzham_decompress_init = NULL; - this->lzham_decompress_reinit = NULL; - this->lzham_decompress_deinit = NULL; - this->lzham_decompress = NULL; - this->lzham_decompress_memory = NULL; - - this->lzham_z_version = NULL; - this->lzham_z_deflateInit = NULL; - this->lzham_z_deflateInit2 = NULL; - this->lzham_z_deflateReset = NULL; - this->lzham_z_deflate = NULL; - this->lzham_z_deflateEnd = NULL; - this->lzham_z_deflateBound = NULL; - this->lzham_z_compress = NULL; - this->lzham_z_compress2 = NULL; - this->lzham_z_compressBound = NULL; - this->lzham_z_inflateInit = NULL; - this->lzham_z_inflateInit2 = NULL; - this->lzham_z_inflate = NULL; - this->lzham_z_inflateEnd = NULL; - this->lzham_z_inflateReset = NULL; - this->lzham_z_uncompress = NULL; - this->lzham_z_error = NULL; - } - - lzham_get_version_func lzham_get_version; - lzham_set_memory_callbacks_func lzham_set_memory_callbacks; - - lzham_compress_init_func lzham_compress_init; - lzham_compress_reinit_func lzham_compress_reinit; - lzham_compress_deinit_func lzham_compress_deinit; - lzham_compress_func lzham_compress; - lzham_compress2_func lzham_compress2; - lzham_compress_memory_func lzham_compress_memory; - - lzham_decompress_init_func lzham_decompress_init; - lzham_decompress_reinit_func lzham_decompress_reinit; - lzham_decompress_deinit_func lzham_decompress_deinit; - lzham_decompress_func lzham_decompress; - lzham_decompress_memory_func lzham_decompress_memory; - - lzham_z_version_func lzham_z_version; - lzham_z_deflateInit_func lzham_z_deflateInit; - lzham_z_deflateInit2_func lzham_z_deflateInit2; - lzham_z_deflateReset_func lzham_z_deflateReset; - lzham_z_deflate_func lzham_z_deflate; - lzham_z_deflateEnd_func lzham_z_deflateEnd; - lzham_z_deflateBound_func lzham_z_deflateBound; - lzham_z_compress_func lzham_z_compress; - lzham_z_compress2_func lzham_z_compress2; - lzham_z_compressBound_func lzham_z_compressBound; - lzham_z_inflateInit_func lzham_z_inflateInit; - lzham_z_inflateInit2_func lzham_z_inflateInit2; - lzham_z_inflateReset_func lzham_z_inflateReset; - lzham_z_inflate_func lzham_z_inflate; - lzham_z_inflateEnd_func lzham_z_inflateEnd; - lzham_z_uncompress_func lzham_z_uncompress; - lzham_z_error_func lzham_z_error; -}; -#endif // #ifdef __cplusplus - -#endif // #ifndef __LZHAM_H__ - -// Copyright (c) 2009-2012 Richard Geldreich, Jr. -// -// LZHAM uses the MIT License: -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_dynamic_lib.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_dynamic_lib.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_dynamic_lib.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_dynamic_lib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -#pragma once - -#define LZHAM_DYNAMIC_LIB 1 -#include "lzham.h" - -#ifdef _XBOX - #define LZHAM_DLL_FILENAME "lzham_x360.dll" - #define LZHAM_DEBUG_DLL_FILENAME "lzham_x360D.dll" -#else - // FIXME: This stuff should probably be moved to another header. - #if LZHAM_64BIT - #define LZHAM_DLL_FILENAME "lzham_x64.dll" - #define LZHAM_DEBUG_DLL_FILENAME "lzham_x64D.dll" - #else - #define LZHAM_DLL_FILENAME "lzham_x86.dll" - #define LZHAM_DEBUG_DLL_FILENAME "lzham_x86D.dll" - #endif -#endif - -#ifdef __cplusplus -// Simple helper class that demonstrates how to dynamically load the LZHAM DLL. -// The load() method loads the DLL, then initializes the member function pointers in ilzham by calling GetProcAddress() on all exported API's defined in lzham_exports.inc. -class lzham_dll_loader : public ilzham -{ - lzham_dll_loader(const lzham_dll_loader &other); - lzham_dll_loader& operator= (const lzham_dll_loader &rhs); - -public: - lzham_dll_loader() : ilzham(), m_handle(NULL), m_win32_error(S_OK) - { - } - - virtual ~lzham_dll_loader() - { - unload(); - } - - enum - { - cErrorMissingExport = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x201), - cErrorUnsupportedDLLVersion = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x202), - }; - - // Assumes LZHAM DLL is in the same path as the executable. -#if defined(_XBOX) || defined(_MSC_VER) - static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll) - { -#ifdef _XBOX - char *buf = "D:\\unused.xex"; -#else - char buf[MAX_PATH]; - GetModuleFileNameA(NULL, buf, sizeof(buf)); -#endif - char drive_buf[_MAX_DRIVE], dir_buf[_MAX_DIR], filename_buf[_MAX_FNAME], ext_buf[_MAX_EXT]; - _splitpath_s(buf, drive_buf, _MAX_DRIVE, dir_buf, _MAX_DIR, NULL, 0, NULL, 0); - _splitpath_s(debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME, NULL, 0, NULL, 0, filename_buf, _MAX_FNAME, ext_buf, _MAX_EXT); - _makepath_s(pModulePath, size_in_chars, drive_buf, dir_buf, filename_buf, ext_buf); - } -#else - static void create_module_path(char *pModulePath, int size_in_chars, bool debug_dll) - { - strcpy(pModulePath, debug_dll ? LZHAM_DEBUG_DLL_FILENAME : LZHAM_DLL_FILENAME); - } -#endif - - virtual bool load() - { - HRESULT hres = load(NULL); - return S_OK == hres; - } - - HRESULT load(const char* pModulePath) - { - unload(); - - char buf[MAX_PATH]; - if (!pModulePath) - { - create_module_path(buf, sizeof(buf), false); - pModulePath = buf; - } - - m_win32_error = S_OK; - - m_handle = LoadLibraryA(pModulePath); - if (NULL == m_handle) - { - m_win32_error = HRESULT_FROM_WIN32(GetLastError()); - return m_win32_error; - } - - struct - { - const char* pName; - void** pFunc_ptr; - } - funcs[] = - { -#define LZHAM_DLL_FUNC_NAME(x) { #x, (void**)&x }, -#include "lzham_exports.inc" -#undef LZHAM_DLL_FUNC_NAME - }; - - const int cNumFuncs = sizeof(funcs) / sizeof(funcs[0]); - - for (int i = 0; i < cNumFuncs; i++) - { -#ifdef _XBOX - if ((*funcs[i].pFunc_ptr = GetProcAddress(m_handle, (LPCSTR)(i + 1))) == NULL) -#else - if ((*funcs[i].pFunc_ptr = (void*)GetProcAddress(m_handle, funcs[i].pName)) == NULL) -#endif - { - unload(); - - m_win32_error = cErrorMissingExport; - return m_win32_error; - } - } - - int dll_ver = lzham_get_version(); - - // Ensure DLL's major version is the expected version. - if ((dll_ver >> 8U) != (LZHAM_DLL_VERSION >> 8U)) - { - unload(); - - m_win32_error = cErrorUnsupportedDLLVersion; - return m_win32_error; - } - - return S_OK; - } - - virtual void unload() - { - if (m_handle) - { - FreeLibrary(m_handle); - m_handle = NULL; - } - - clear(); - - m_win32_error = S_OK; - } - - virtual bool is_loaded() { return m_handle != NULL; } - - HRESULT get_last_win32_error() { return m_win32_error; } - -private: - HMODULE m_handle; - HRESULT m_win32_error; -}; -#endif // #ifdef __cplusplus diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_exports.inc p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_exports.inc --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_exports.inc 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_exports.inc 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// Note: The order here must match the ordinal declarations in lzhamdll.def! -LZHAM_DLL_FUNC_NAME(lzham_get_version) -LZHAM_DLL_FUNC_NAME(lzham_set_memory_callbacks) -LZHAM_DLL_FUNC_NAME(lzham_compress_init) -LZHAM_DLL_FUNC_NAME(lzham_compress_reinit) -LZHAM_DLL_FUNC_NAME(lzham_compress) -LZHAM_DLL_FUNC_NAME(lzham_compress2) -LZHAM_DLL_FUNC_NAME(lzham_compress_deinit) -LZHAM_DLL_FUNC_NAME(lzham_compress_memory) -LZHAM_DLL_FUNC_NAME(lzham_decompress_init) -LZHAM_DLL_FUNC_NAME(lzham_decompress) -LZHAM_DLL_FUNC_NAME(lzham_decompress_deinit) -LZHAM_DLL_FUNC_NAME(lzham_decompress_memory) -LZHAM_DLL_FUNC_NAME(lzham_decompress_reinit) -LZHAM_DLL_FUNC_NAME(lzham_z_version) -LZHAM_DLL_FUNC_NAME(lzham_z_deflateInit) -LZHAM_DLL_FUNC_NAME(lzham_z_deflateInit2) -LZHAM_DLL_FUNC_NAME(lzham_z_deflateReset) -LZHAM_DLL_FUNC_NAME(lzham_z_deflate) -LZHAM_DLL_FUNC_NAME(lzham_z_deflateEnd) -LZHAM_DLL_FUNC_NAME(lzham_z_deflateBound) -LZHAM_DLL_FUNC_NAME(lzham_z_compress) -LZHAM_DLL_FUNC_NAME(lzham_z_compress2) -LZHAM_DLL_FUNC_NAME(lzham_z_compressBound) -LZHAM_DLL_FUNC_NAME(lzham_z_inflateInit) -LZHAM_DLL_FUNC_NAME(lzham_z_inflateInit2) -LZHAM_DLL_FUNC_NAME(lzham_z_inflateReset) -LZHAM_DLL_FUNC_NAME(lzham_z_inflate) -LZHAM_DLL_FUNC_NAME(lzham_z_inflateEnd) -LZHAM_DLL_FUNC_NAME(lzham_z_uncompress) -LZHAM_DLL_FUNC_NAME(lzham_z_error) diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_static_lib.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_static_lib.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/lzham_static_lib.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/lzham_static_lib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -#pragma once - -#define LZHAM_STATIC_LIB 1 -#include "lzham.h" - -#ifdef __cplusplus -// Like lzham_dynamic_lib, except it sets the function pointer members to point directly to the C functions in lzhamlib -class lzham_static_lib : public ilzham -{ - lzham_static_lib(const lzham_static_lib &other); - lzham_static_lib& operator= (const lzham_static_lib &rhs); - -public: - lzham_static_lib() : ilzham() { } - - virtual ~lzham_static_lib() { } - - virtual bool load() - { - this->lzham_get_version = ::lzham_get_version; - this->lzham_set_memory_callbacks = ::lzham_set_memory_callbacks; - this->lzham_compress_init = ::lzham_compress_init; - this->lzham_compress_deinit = ::lzham_compress_deinit; - this->lzham_compress = ::lzham_compress; - this->lzham_compress2 = ::lzham_compress2; - this->lzham_compress_reinit = ::lzham_compress_reinit; - this->lzham_compress_memory = ::lzham_compress_memory; - this->lzham_decompress_init = ::lzham_decompress_init; - this->lzham_decompress_reinit = ::lzham_decompress_reinit; - this->lzham_decompress_deinit = ::lzham_decompress_deinit; - this->lzham_decompress = ::lzham_decompress; - this->lzham_decompress_memory = ::lzham_decompress_memory; - - this->lzham_z_version = ::lzham_z_version; - this->lzham_z_deflateInit = ::lzham_z_deflateInit; - this->lzham_z_deflateInit2 = ::lzham_z_deflateInit2; - this->lzham_z_deflateReset = ::lzham_z_deflateReset; - this->lzham_z_deflate = ::lzham_z_deflate; - this->lzham_z_deflateEnd = ::lzham_z_deflateEnd; - this->lzham_z_deflateBound = ::lzham_z_deflateBound; - this->lzham_z_compress = ::lzham_z_compress; - this->lzham_z_compress2 = ::lzham_z_compress2; - this->lzham_z_compressBound = ::lzham_z_compressBound; - this->lzham_z_inflateInit = ::lzham_z_inflateInit; - this->lzham_z_inflateInit2 = ::lzham_z_inflateInit2; - this->lzham_z_inflate = ::lzham_z_inflate; - this->lzham_z_inflateEnd = ::lzham_z_inflateEnd; - this->lzham_z_inflateReset = ::lzham_z_inflateReset; - this->lzham_z_uncompress = ::lzham_z_uncompress; - this->lzham_z_error = ::lzham_z_error; - - return true; - } - - virtual void unload() { clear(); } - - virtual bool is_loaded() { return lzham_get_version != NULL; } -}; -#endif // __cplusplus diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/zlib.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/zlib.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/include/zlib.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/include/zlib.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#define LZHAM_DEFINE_ZLIB_API -#include "lzham.h" \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/CMakeLists.txt 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -PROJECT(lzhamcomp) -cmake_minimum_required(VERSION 2.8) -option(BUILD_X64 "build 64-bit" TRUE) - -message("Initial BUILD_X64=${BUILD_X64}") -message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") - -if( NOT CMAKE_BUILD_TYPE ) - set( CMAKE_BUILD_TYPE Release ) -endif( NOT CMAKE_BUILD_TYPE ) - -message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) - -if (BUILD_X64) - message("Building 64-bit") -else() - message("Building 32-bit") -endif(BUILD_X64) - -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") - -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") - -set(SRC_LIST - lzham_lzbase.cpp - lzham_lzbase.h - lzham_lzcomp.cpp - lzham_lzcomp_internal.cpp - lzham_lzcomp_internal.h - lzham_lzcomp_state.cpp - lzham_match_accel.cpp - lzham_match_accel.h - lzham_null_threading.h - lzham_pthreads_threading.cpp - lzham_pthreads_threading.h - lzham_threading.h) - -if (WIN32) - list (APPEND SRC_LIST lzham_win32_threading.cpp) -endif () - -# -fno-strict-aliasing is *required* to compile LZHAM -set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") - -if (NOT BUILD_X64) - set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") -endif() - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") - -include_directories( - ${PROJECT_SOURCE_DIR}/../lzhamdecomp - ${PROJECT_SOURCE_DIR}/../include) - -#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) - -add_library(${PROJECT_NAME} ${SRC_LIST}) -target_link_libraries(${PROJECT_NAME} lzhamdecomp pthread) -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin) diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_comp.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_comp.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_comp.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_comp.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -// File: lzham_comp.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham.h" - -namespace lzham -{ - lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_init(const lzham_compress_params *pParams); - - lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_reinit(lzham_compress_state_ptr p); - - lzham_uint32 LZHAM_CDECL lzham_lib_compress_deinit(lzham_compress_state_ptr p); - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag); - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress2( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_flush_t flush_type); - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); - - int lzham_lib_z_deflateInit(lzham_z_streamp pStream, int level); - int lzham_lib_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); - int lzham_lib_z_deflateReset(lzham_z_streamp pStream); - int lzham_lib_z_deflate(lzham_z_streamp pStream, int flush); - int lzham_lib_z_deflateEnd(lzham_z_streamp pStream); - lzham_z_ulong lzham_lib_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len); - int lzham_lib_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level); - int lzham_lib_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - lzham_z_ulong lzham_lib_z_compressBound(lzham_z_ulong source_len); - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -// File: lzham_lzbase.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_lzbase.h" - -namespace lzham -{ - uint8 CLZBase::m_slot_tab0[4096] = - { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23 - }; - - uint8 CLZBase::m_slot_tab1[512] = - { - 0, 0, 24, 25, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39 - }; - - uint8 CLZBase::m_slot_tab2[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47 - }; - - void CLZBase::init_slot_tabs() - { -#if 0 - for (uint i = 0; i < m_num_lzx_slots; i++) - { - //printf("%u: 0x%08X - 0x%08X, %u\n", i, m_lzx_position_base[i], m_lzx_position_base[i] + (1 << m_lzx_position_extra_bits[i]) - 1, m_lzx_position_extra_bits[i]); - - uint lo = m_lzx_position_base[i]; - uint hi = lo + m_lzx_position_extra_mask[i]; - - uint8* pTab; - uint shift; - uint n; LZHAM_NOTE_UNUSED(n); - - if (hi < 0x1000) - { - pTab = m_slot_tab0; - shift = 0; - n = sizeof(m_slot_tab0); - } - else if (hi < 0x100000) - { - pTab = m_slot_tab1; - shift = 11; - n = sizeof(m_slot_tab1); - } - else if (hi < 0x1000000) - { - pTab = m_slot_tab2; - shift = 16; - n = sizeof(m_slot_tab2); - } - else - break; - - lo >>= shift; - hi >>= shift; - - LZHAM_ASSERT(hi < n); - memset(pTab + lo, (uint8)i, hi - lo + 1); - } - - for (uint i = 0; i < 256; i++) - { - printf("%u, ", m_slot_tab2[i]); - if ((i & 31) == 31) printf("\n"); - } -#endif - -#ifdef LZHAM_BUILD_DEBUG - uint slot, ofs; - for (uint i = 1; i < m_num_lzx_slots; i++) - { - compute_lzx_position_slot(m_lzx_position_base[i], slot, ofs); - LZHAM_ASSERT(slot == i); - - compute_lzx_position_slot(m_lzx_position_base[i] + m_lzx_position_extra_mask[i], slot, ofs); - LZHAM_ASSERT(slot == i); - } - - for (uint i = 1; i <= (m_dict_size-1); i += 512U*1024U) - { - compute_lzx_position_slot(i, slot, ofs); - LZHAM_ASSERT(i == m_lzx_position_base[slot] + ofs); - } - - compute_lzx_position_slot(m_dict_size - 1, slot, ofs); - LZHAM_ASSERT((m_dict_size - 1) == m_lzx_position_base[slot] + ofs); -#endif - } - -} //namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// File: lzham_lzbase.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#include "lzham_lzdecompbase.h" - -//#define LZHAM_LZVERIFY -//#define LZHAM_DISABLE_RAW_BLOCKS - -namespace lzham -{ - - struct CLZBase : CLZDecompBase - { - static uint8 m_slot_tab0[4096]; - static uint8 m_slot_tab1[512]; - static uint8 m_slot_tab2[256]; - - void init_slot_tabs(); - - inline void compute_lzx_position_slot(uint dist, uint& slot, uint& ofs) - { - uint s; - if (dist < 0x1000) - s = m_slot_tab0[dist]; - else if (dist < 0x100000) - s = m_slot_tab1[dist >> 11]; - else if (dist < 0x1000000) - s = m_slot_tab2[dist >> 16]; - else if (dist < 0x2000000) - s = 48 + ((dist - 0x1000000) >> 23); - else if (dist < 0x4000000) - s = 50 + ((dist - 0x2000000) >> 24); - else - s = 52 + ((dist - 0x4000000) >> 25); - - ofs = (dist - m_lzx_position_base[s]) & m_lzx_position_extra_mask[s]; - slot = s; - - LZHAM_ASSERT(s < m_num_lzx_slots); - LZHAM_ASSERT((m_lzx_position_base[slot] + ofs) == dist); - LZHAM_ASSERT(ofs < (1U << m_lzx_position_extra_bits[slot])); - } - }; - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,750 +0,0 @@ -// File: lzham_lzcomp.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham.h" -#include "lzham_comp.h" -#include "lzham_lzcomp_internal.h" - -using namespace lzham; - -namespace lzham -{ - struct lzham_compress_state - { - lzham_compress_state(lzham_malloc_context malloc_context) : - m_tp(malloc_context), - m_malloc_context(malloc_context), - m_compressor(malloc_context) - { - } - - // task_pool requires 8 or 16 alignment - task_pool m_tp; - - lzham_malloc_context m_malloc_context; - - lzcompressor m_compressor; - - uint m_dict_size_log2; - - const uint8 *m_pIn_buf; - size_t *m_pIn_buf_size; - uint8 *m_pOut_buf; - size_t *m_pOut_buf_size; - - size_t m_comp_data_ofs; - - bool m_finished_compression; - - lzham_compress_params m_params; - - lzham_compress_status_t m_status; - }; - - static lzham_compress_status_t create_internal_init_params(lzcompressor::init_params &internal_params, const lzham_compress_params *pParams) - { - if ((pParams->m_dict_size_log2 < CLZBase::cMinDictSizeLog2) || (pParams->m_dict_size_log2 > CLZBase::cMaxDictSizeLog2)) - { - LZHAM_LOG_ERROR(6000); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if (pParams->m_extreme_parsing_max_best_arrivals > cMaxParseNodeStates) - { - LZHAM_LOG_ERROR(6001); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if (pParams->m_extreme_parsing_max_best_arrivals <= 1) - internal_params.m_extreme_parsing_max_best_arrivals = cDefaultMaxParseNodeStates; - else - internal_params.m_extreme_parsing_max_best_arrivals = pParams->m_extreme_parsing_max_best_arrivals; - - if (pParams->m_fast_bytes > 0) - internal_params.m_fast_bytes_override = math::clamp(pParams->m_fast_bytes, LZHAM_MIN_FAST_BYTES, LZHAM_MAX_FAST_BYTES); - - internal_params.m_dict_size_log2 = pParams->m_dict_size_log2; - - if (pParams->m_max_helper_threads < 0) - internal_params.m_max_helper_threads = lzham_get_max_helper_threads(); - else - internal_params.m_max_helper_threads = pParams->m_max_helper_threads; - internal_params.m_max_helper_threads = LZHAM_MIN(LZHAM_MAX_HELPER_THREADS, internal_params.m_max_helper_threads); - - internal_params.m_lzham_compress_flags = pParams->m_compress_flags; - - if (pParams->m_num_seed_bytes) - { - if ((!pParams->m_pSeed_bytes) || (pParams->m_num_seed_bytes > (1U << pParams->m_dict_size_log2))) - { - LZHAM_LOG_ERROR(6002); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - internal_params.m_num_seed_bytes = pParams->m_num_seed_bytes; - internal_params.m_pSeed_bytes = pParams->m_pSeed_bytes; - } - - switch (pParams->m_level) - { - case LZHAM_COMP_LEVEL_FASTEST: internal_params.m_compression_level = cCompressionLevelFastest; break; - case LZHAM_COMP_LEVEL_FASTER: internal_params.m_compression_level = cCompressionLevelFaster; break; - case LZHAM_COMP_LEVEL_DEFAULT: internal_params.m_compression_level = cCompressionLevelDefault; break; - case LZHAM_COMP_LEVEL_BETTER: internal_params.m_compression_level = cCompressionLevelBetter; break; - case LZHAM_COMP_LEVEL_UBER: internal_params.m_compression_level = cCompressionLevelUber; break; - default: - LZHAM_LOG_ERROR(6003); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - }; - - if (pParams->m_table_max_update_interval || pParams->m_table_update_interval_slow_rate) - { - internal_params.m_table_max_update_interval = pParams->m_table_max_update_interval; - internal_params.m_table_update_interval_slow_rate = pParams->m_table_update_interval_slow_rate; - } - else - { - uint rate = pParams->m_table_update_rate; - if (!rate) - rate = LZHAM_DEFAULT_TABLE_UPDATE_RATE; - rate = math::clamp(rate, 1, LZHAM_FASTEST_TABLE_UPDATE_RATE) - 1; - internal_params.m_table_max_update_interval = g_table_update_settings[rate].m_max_update_interval; - internal_params.m_table_update_interval_slow_rate = g_table_update_settings[rate].m_slow_rate; - } - - return LZHAM_COMP_STATUS_SUCCESS; - } - - lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_init(const lzham_compress_params *pParams) - { - if ((!pParams) || (pParams->m_struct_size != sizeof(lzham_compress_params))) - { - LZHAM_LOG_ERROR(6004); - return NULL; - } - - if ((pParams->m_dict_size_log2 < CLZBase::cMinDictSizeLog2) || (pParams->m_dict_size_log2 > CLZBase::cMaxDictSizeLog2)) - { - LZHAM_LOG_ERROR(6005); - return NULL; - } - - lzcompressor::init_params internal_params; - lzham_compress_status_t status = create_internal_init_params(internal_params, pParams); - if (status != LZHAM_COMP_STATUS_SUCCESS) - { - LZHAM_LOG_ERROR(6006); - return NULL; - } - - lzham_malloc_context malloc_context = lzham_create_malloc_context(0); - - lzham_compress_state *pState = lzham_new(malloc_context, malloc_context); - if (!pState) - { - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6007); - return NULL; - } - - pState->m_params = *pParams; - - pState->m_pIn_buf = NULL; - pState->m_pIn_buf_size = NULL; - pState->m_pOut_buf = NULL; - pState->m_pOut_buf_size = NULL; - pState->m_status = LZHAM_COMP_STATUS_NOT_FINISHED; - pState->m_comp_data_ofs = 0; - pState->m_finished_compression = false; - - if (internal_params.m_max_helper_threads) - { - if (!pState->m_tp.init(internal_params.m_max_helper_threads)) - { - lzham_delete(malloc_context, pState); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6008); - return NULL; - } - if (pState->m_tp.get_num_threads() >= internal_params.m_max_helper_threads) - { - internal_params.m_pTask_pool = &pState->m_tp; - } - else - { - internal_params.m_max_helper_threads = 0; - } - } - - if (!pState->m_compressor.init(internal_params)) - { - lzham_delete(malloc_context, pState); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6009); - return NULL; - } - - return pState; - } - - lzham_compress_state_ptr LZHAM_CDECL lzham_lib_compress_reinit(lzham_compress_state_ptr p) - { - lzham_compress_state *pState = static_cast(p); - if (pState) - { - if (!pState->m_compressor.reset()) - { - LZHAM_LOG_ERROR(6010); - return NULL; - } - - pState->m_pIn_buf = NULL; - pState->m_pIn_buf_size = NULL; - pState->m_pOut_buf = NULL; - pState->m_pOut_buf_size = NULL; - pState->m_status = LZHAM_COMP_STATUS_NOT_FINISHED; - pState->m_comp_data_ofs = 0; - pState->m_finished_compression = false; - } - - return pState; - } - - lzham_uint32 LZHAM_CDECL lzham_lib_compress_deinit(lzham_compress_state_ptr p) - { - lzham_compress_state *pState = static_cast(p); - if (!pState) - { - LZHAM_LOG_ERROR(6011); - return 0; - } - - uint32 adler32 = pState->m_compressor.get_src_adler32(); - - lzham_malloc_context malloc_context = pState->m_malloc_context; - - lzham_delete(malloc_context, pState); - lzham_destroy_malloc_context(malloc_context); - - return adler32; - } - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag) - { - return lzham_lib_compress2(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag ? LZHAM_FINISH : LZHAM_NO_FLUSH); - } - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress2( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_flush_t flush_type) - { - lzham_compress_state *pState = static_cast(p); - - if ((!pState) || (!pState->m_params.m_dict_size_log2) || (pState->m_status >= LZHAM_COMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE) || (!pIn_buf_size) || (!pOut_buf_size)) - { - LZHAM_LOG_ERROR(6012); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if ((*pIn_buf_size) && (!pIn_buf)) - { - LZHAM_LOG_ERROR(6013); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if ((!*pOut_buf_size) || (!pOut_buf)) - { - LZHAM_LOG_ERROR(6014); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - byte_vec &comp_data = pState->m_compressor.get_compressed_data(); - size_t num_bytes_written_to_out_buf = 0; - if (pState->m_comp_data_ofs < comp_data.size()) - { - size_t n = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size); - - memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, n); - - pState->m_comp_data_ofs += n; - - const bool has_no_more_output = (pState->m_comp_data_ofs >= comp_data.size()); - if (has_no_more_output) - { - pOut_buf += n; - *pOut_buf_size -= n; - num_bytes_written_to_out_buf += n; - } - else - { - *pIn_buf_size = 0; - *pOut_buf_size = n; - pState->m_status = LZHAM_COMP_STATUS_HAS_MORE_OUTPUT; - return pState->m_status; - } - } - - comp_data.try_resize(0); - pState->m_comp_data_ofs = 0; - - if (pState->m_finished_compression) - { - if ((*pIn_buf_size) || (flush_type != LZHAM_FINISH)) - { - pState->m_status = LZHAM_COMP_STATUS_INVALID_PARAMETER; - LZHAM_LOG_ERROR(6015); - return pState->m_status; - } - - *pIn_buf_size = 0; - *pOut_buf_size = num_bytes_written_to_out_buf; - - pState->m_status = LZHAM_COMP_STATUS_SUCCESS; - return pState->m_status; - } - - const size_t cMaxBytesToPutPerIteration = 4*1024*1024; - size_t bytes_to_put = LZHAM_MIN(cMaxBytesToPutPerIteration, *pIn_buf_size); - const bool consumed_entire_input_buf = (bytes_to_put == *pIn_buf_size); - - if (bytes_to_put) - { - if (!pState->m_compressor.put_bytes(pIn_buf, (uint)bytes_to_put)) - { - *pIn_buf_size = 0; - *pOut_buf_size = num_bytes_written_to_out_buf; - pState->m_status = LZHAM_COMP_STATUS_FAILED; - LZHAM_LOG_ERROR(6016); - return pState->m_status; - } - } - - if ((consumed_entire_input_buf) && (flush_type != LZHAM_NO_FLUSH)) - { - if ((flush_type == LZHAM_SYNC_FLUSH) || (flush_type == LZHAM_FULL_FLUSH) || (flush_type == LZHAM_TABLE_FLUSH)) - { - if (!pState->m_compressor.flush(flush_type)) - { - *pIn_buf_size = 0; - *pOut_buf_size = num_bytes_written_to_out_buf; - pState->m_status = LZHAM_COMP_STATUS_FAILED; - LZHAM_LOG_ERROR(6017); - return pState->m_status; - } - } - else if (!pState->m_finished_compression) - { - if (!pState->m_compressor.put_bytes(NULL, 0)) - { - *pIn_buf_size = 0; - *pOut_buf_size = num_bytes_written_to_out_buf; - pState->m_status = LZHAM_COMP_STATUS_FAILED; - LZHAM_LOG_ERROR(6018); - return pState->m_status; - } - pState->m_finished_compression = true; - } - } - - size_t num_comp_bytes_to_output = LZHAM_MIN(comp_data.size() - pState->m_comp_data_ofs, *pOut_buf_size); - if (num_comp_bytes_to_output) - { - memcpy(pOut_buf, comp_data.get_ptr() + pState->m_comp_data_ofs, num_comp_bytes_to_output); - - pState->m_comp_data_ofs += num_comp_bytes_to_output; - } - - *pIn_buf_size = bytes_to_put; - *pOut_buf_size = num_bytes_written_to_out_buf + num_comp_bytes_to_output; - - const bool has_no_more_output = (pState->m_comp_data_ofs >= comp_data.size()); - if ((has_no_more_output) && (flush_type == LZHAM_FINISH) && (pState->m_finished_compression)) - pState->m_status = LZHAM_COMP_STATUS_SUCCESS; - else if ((has_no_more_output) && (consumed_entire_input_buf) && (flush_type == LZHAM_NO_FLUSH)) - pState->m_status = LZHAM_COMP_STATUS_NEEDS_MORE_INPUT; - else - pState->m_status = has_no_more_output ? LZHAM_COMP_STATUS_NOT_FINISHED : LZHAM_COMP_STATUS_HAS_MORE_OUTPUT; - - return pState->m_status; - } - - lzham_compress_status_t LZHAM_CDECL lzham_lib_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) - { - if ((!pParams) || (!pDst_len)) - { - LZHAM_LOG_ERROR(6019); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if (src_len) - { - if (!pSrc_buf) - { - LZHAM_LOG_ERROR(6020); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - } - - if (sizeof(size_t) > sizeof(uint32)) - { - if (src_len > cUINT32_MAX) - { - LZHAM_LOG_ERROR(6021); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - } - - lzcompressor::init_params internal_params; - lzham_compress_status_t status = create_internal_init_params(internal_params, pParams); - if (status != LZHAM_COMP_STATUS_SUCCESS) - { - LZHAM_LOG_ERROR(6022); - return status; - } - - lzham_malloc_context malloc_context = lzham_create_malloc_context(0); - - task_pool *pTP = NULL; - if (internal_params.m_max_helper_threads) - { - pTP = lzham_new(malloc_context, malloc_context); - if (!pTP->init(internal_params.m_max_helper_threads)) - { - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6023); - return LZHAM_COMP_STATUS_FAILED_INITIALIZING; - } - - internal_params.m_pTask_pool = pTP; - } - - lzcompressor *pCompressor = lzham_new(malloc_context, malloc_context); - if (!pCompressor) - { - lzham_delete(malloc_context, pTP); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6024); - return LZHAM_COMP_STATUS_FAILED_INITIALIZING; - } - - if (!pCompressor->init(internal_params)) - { - lzham_delete(malloc_context, pTP); - lzham_delete(malloc_context, pCompressor); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6025); - return LZHAM_COMP_STATUS_INVALID_PARAMETER; - } - - if (src_len) - { - if (!pCompressor->put_bytes(pSrc_buf, static_cast(src_len))) - { - *pDst_len = 0; - lzham_delete(malloc_context, pTP); - lzham_delete(malloc_context, pCompressor); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6026); - return LZHAM_COMP_STATUS_FAILED; - } - } - - if (!pCompressor->put_bytes(NULL, 0)) - { - *pDst_len = 0; - lzham_delete(malloc_context, pTP); - lzham_delete(malloc_context, pCompressor); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6027); - return LZHAM_COMP_STATUS_FAILED; - } - - const byte_vec &comp_data = pCompressor->get_compressed_data(); - - size_t dst_buf_size = *pDst_len; - *pDst_len = comp_data.size(); - - if (pAdler32) - *pAdler32 = pCompressor->get_src_adler32(); - - if (comp_data.size() > dst_buf_size) - { - lzham_delete(malloc_context, pTP); - lzham_delete(malloc_context, pCompressor); - lzham_destroy_malloc_context(malloc_context); - LZHAM_LOG_ERROR(6028); - return LZHAM_COMP_STATUS_OUTPUT_BUF_TOO_SMALL; - } - - memcpy(pDst_buf, comp_data.get_ptr(), comp_data.size()); - - lzham_delete(malloc_context, pTP); - lzham_delete(malloc_context, pCompressor); - lzham_destroy_malloc_context(malloc_context); - return LZHAM_COMP_STATUS_SUCCESS; - } - - // ----------------- zlib-style API's - - int lzham_lib_z_deflateInit(lzham_z_streamp pStream, int level) - { - return lzham_lib_z_deflateInit2(pStream, level, LZHAM_Z_LZHAM, LZHAM_Z_DEFAULT_WINDOW_BITS, 9, LZHAM_Z_DEFAULT_STRATEGY); - } - - int lzham_lib_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) - { - LZHAM_NOTE_UNUSED(strategy); - - if (!pStream) - { - LZHAM_LOG_ERROR(6029); - return LZHAM_Z_STREAM_ERROR; - } - if ((mem_level < 1) || (mem_level > 9)) - { - LZHAM_LOG_ERROR(6030); - return LZHAM_Z_PARAM_ERROR; - } - if ((method != LZHAM_Z_DEFLATED) && (method != LZHAM_Z_LZHAM)) - { - LZHAM_LOG_ERROR(6031); - return LZHAM_Z_PARAM_ERROR; - } - - if (level == LZHAM_Z_DEFAULT_COMPRESSION) - level = 9; - - if (method == LZHAM_Z_DEFLATED) - { - // Force Deflate to LZHAM with default window_bits. - method = LZHAM_Z_LZHAM; - window_bits = LZHAM_Z_DEFAULT_WINDOW_BITS; - } - -#ifdef LZHAM_Z_API_FORCE_WINDOW_BITS - window_bits = LZHAM_Z_API_FORCE_WINDOW_BITS; -#endif - - int max_window_bits = LZHAM_64BIT_POINTERS ? LZHAM_MAX_DICT_SIZE_LOG2_X64 : LZHAM_MAX_DICT_SIZE_LOG2_X86; - if ((labs(window_bits) < LZHAM_MIN_DICT_SIZE_LOG2) || (labs(window_bits) > max_window_bits)) - { - LZHAM_LOG_ERROR(6032); - return LZHAM_Z_PARAM_ERROR; - } - - lzham_compress_params comp_params; - - utils::zero_object(comp_params); - comp_params.m_struct_size = sizeof(lzham_compress_params); - - comp_params.m_level = LZHAM_COMP_LEVEL_UBER; - if (level <= 1) - comp_params.m_level = LZHAM_COMP_LEVEL_FASTEST; - else if (level <= 3) - comp_params.m_level = LZHAM_COMP_LEVEL_FASTER; - else if (level <= 5) - comp_params.m_level = LZHAM_COMP_LEVEL_DEFAULT; - else if (level <= 7) - comp_params.m_level = LZHAM_COMP_LEVEL_BETTER; - - if (level == 10) - comp_params.m_compress_flags |= LZHAM_COMP_FLAG_EXTREME_PARSING; - - // Use all CPU's. TODO: This is not always the best idea depending on the dictionary size and the # of bytes to compress. - comp_params.m_max_helper_threads = -1; - - comp_params.m_dict_size_log2 = static_cast(labs(window_bits)); - - if (window_bits > 0) - comp_params.m_compress_flags |= LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM; - - pStream->data_type = 0; - pStream->adler = LZHAM_Z_ADLER32_INIT; - pStream->msg = NULL; - pStream->reserved = 0; - pStream->total_in = 0; - pStream->total_out = 0; - - lzham_compress_state_ptr pComp = lzham_lib_compress_init(&comp_params); - if (!pComp) - { - LZHAM_LOG_ERROR(6033); - return LZHAM_Z_PARAM_ERROR; - } - - pStream->state = (struct lzham_z_internal_state *)pComp; - - return LZHAM_Z_OK; - } - - int lzham_lib_z_deflateReset(lzham_z_streamp pStream) - { - if (!pStream) - { - LZHAM_LOG_ERROR(6034); - return LZHAM_Z_STREAM_ERROR; - } - - lzham_compress_state_ptr pComp = (lzham_compress_state_ptr)pStream->state; - if (!pComp) - { - LZHAM_LOG_ERROR(6035); - return LZHAM_Z_STREAM_ERROR; - } - - pComp = lzham_lib_compress_reinit(pComp); - if (!pComp) - { - LZHAM_LOG_ERROR(6036); - return LZHAM_Z_STREAM_ERROR; - } - - pStream->state = (struct lzham_z_internal_state *)pComp; - - return LZHAM_Z_OK; - } - - int lzham_lib_z_deflate(lzham_z_streamp pStream, int flush) - { - if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > LZHAM_Z_FINISH) || (!pStream->next_out)) - { - LZHAM_LOG_ERROR(6037); - return LZHAM_Z_STREAM_ERROR; - } - - if (!pStream->avail_out) - { - LZHAM_LOG_ERROR(6038); - return LZHAM_Z_BUF_ERROR; - } - - if (flush == LZHAM_Z_PARTIAL_FLUSH) - flush = LZHAM_Z_SYNC_FLUSH; - - int lzham_status = LZHAM_Z_OK; - lzham_z_ulong orig_total_in = pStream->total_in, orig_total_out = pStream->total_out; - for ( ; ; ) - { - size_t in_bytes = pStream->avail_in, out_bytes = pStream->avail_out; - - lzham_compress_state_ptr pComp = (lzham_compress_state_ptr)pStream->state; - lzham_compress_state *pState = static_cast(pComp); - - lzham_compress_status_t status = lzham_lib_compress2( - pComp, - pStream->next_in, &in_bytes, - pStream->next_out, &out_bytes, - (lzham_flush_t)flush); - - pStream->next_in += (uint)in_bytes; - pStream->avail_in -= (uint)in_bytes; - pStream->total_in += (uint)in_bytes; - - pStream->next_out += (uint)out_bytes; - pStream->avail_out -= (uint)out_bytes; - pStream->total_out += (uint)out_bytes; - - pStream->adler = pState->m_compressor.get_src_adler32(); - - if (status >= LZHAM_COMP_STATUS_FIRST_FAILURE_CODE) - { - lzham_status = LZHAM_Z_STREAM_ERROR; - LZHAM_LOG_ERROR(6039); - break; - } - else if (status == LZHAM_COMP_STATUS_SUCCESS) - { - lzham_status = LZHAM_Z_STREAM_END; - break; - } - else if (!pStream->avail_out) - break; - else if ((!pStream->avail_in) && (flush != LZHAM_Z_FINISH)) - { - if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) - break; - LZHAM_LOG_ERROR(6040); - return LZHAM_Z_BUF_ERROR; // Can't make forward progress without some input. - } - } - return lzham_status; - } - - int lzham_lib_z_deflateEnd(lzham_z_streamp pStream) - { - if (!pStream) - { - LZHAM_LOG_ERROR(6041); - return LZHAM_Z_STREAM_ERROR; - } - - lzham_compress_state_ptr pComp = (lzham_compress_state_ptr)pStream->state; - if (pComp) - { - pStream->adler = lzham_lib_compress_deinit(pComp); - - pStream->state = NULL; - } - - return LZHAM_Z_OK; - } - - lzham_z_ulong lzham_lib_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len) - { - LZHAM_NOTE_UNUSED(pStream); - return 64 + source_len + ((source_len + 4095) / 4096) * 4; - } - - int lzham_lib_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level) - { - int status; - lzham_z_stream stream; - memset(&stream, 0, sizeof(stream)); - - // In case lzham_z_ulong is 64-bits (argh I hate longs). - if ((source_len | *pDest_len) > 0xFFFFFFFFU) - { - LZHAM_LOG_ERROR(6042); - return LZHAM_Z_PARAM_ERROR; - } - - stream.next_in = pSource; - stream.avail_in = (uint)source_len; - stream.next_out = pDest; - stream.avail_out = (uint)*pDest_len; - - status = lzham_lib_z_deflateInit(&stream, level); - if (status != LZHAM_Z_OK) - { - LZHAM_LOG_ERROR(6043); - return status; - } - - status = lzham_lib_z_deflate(&stream, LZHAM_Z_FINISH); - if (status != LZHAM_Z_STREAM_END) - { - lzham_lib_z_deflateEnd(&stream); - return (status == LZHAM_Z_OK) ? LZHAM_Z_BUF_ERROR : status; - } - - *pDest_len = stream.total_out; - return lzham_lib_z_deflateEnd(&stream); - } - - int lzham_lib_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) - { - return lzham_lib_z_compress2(pDest, pDest_len, pSource, source_len, (int)LZHAM_Z_DEFAULT_COMPRESSION); - } - - lzham_z_ulong lzham_lib_z_compressBound(lzham_z_ulong source_len) - { - return lzham_lib_z_deflateBound(NULL, source_len); - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,2240 +0,0 @@ -// File: lzham_lzcomp_internal.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_lzcomp_internal.h" -#include "lzham_checksum.h" -#include "lzham_timer.h" -#include "lzham_lzbase.h" -#include - -// Update and print high-level coding statistics if set to 1. -// TODO: Add match distance coding statistics. -#define LZHAM_UPDATE_STATS 0 - -// Only parse on the main thread, for easier debugging. -#define LZHAM_FORCE_SINGLE_THREADED_PARSING 0 - -// Verify all computed match costs against the generic/slow state::get_cost() method. -#define LZHAM_VERIFY_MATCH_COSTS 0 - -// Set to 1 to force all blocks to be uncompressed (raw). -#define LZHAM_FORCE_ALL_RAW_BLOCKS 0 - -#define LZHAM_EXTREME_PARSING_FAST_BYTES 96 - -namespace lzham -{ - static comp_settings s_level_settings[cCompressionLevelCount] = - { - // cCompressionLevelFastest - { - 8, // m_fast_bytes - 1, // m_match_accel_max_matches_per_probe - 2, // m_match_accel_max_probes - }, - // cCompressionLevelFaster - { - 24, // m_fast_bytes - 6, // m_match_accel_max_matches_per_probe - 12, // m_match_accel_max_probes - }, - // cCompressionLevelDefault - { - 32, // m_fast_bytes - UINT_MAX, // m_match_accel_max_matches_per_probe - 16, // m_match_accel_max_probes - }, - // cCompressionLevelBetter - { - 48, // m_fast_bytes - UINT_MAX, // m_match_accel_max_matches_per_probe - 32, // m_match_accel_max_probes - }, - // cCompressionLevelUber - { - 64, // m_fast_bytes - UINT_MAX, // m_match_accel_max_matches_per_probe - cMatchAccelMaxSupportedProbes, // m_match_accel_max_probes - } - }; - - lzcompressor::lzcompressor(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_src_size(-1), - m_src_adler32(0), - m_accel(malloc_context), - m_codec(malloc_context), - m_block_buf(malloc_context), - m_comp_buf(malloc_context), - m_step(0), - m_block_start_dict_ofs(0), - m_block_index(0), - m_finished(false), - m_use_task_pool(false), - m_use_extreme_parsing(false), - m_start_of_block_state(malloc_context), - m_state(malloc_context), - m_fast_bytes(128), - m_num_parse_threads(0) - { - LZHAM_VERIFY( ((uint32_ptr)this & (LZHAM_GET_ALIGNMENT(lzcompressor) - 1)) == 0); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_parse_thread_state); i++) - m_parse_thread_state[i].set_malloc_context(malloc_context); - } - - bool lzcompressor::init_seed_bytes() - { - uint cur_seed_ofs = 0; - - while (cur_seed_ofs < m_params.m_num_seed_bytes) - { - uint total_bytes_remaining = m_params.m_num_seed_bytes - cur_seed_ofs; - uint num_bytes_to_add = math::minimum(total_bytes_remaining, m_params.m_block_size); - - if (!m_accel.add_bytes_begin(num_bytes_to_add, static_cast(m_params.m_pSeed_bytes) + cur_seed_ofs)) - { - LZHAM_LOG_ERROR(7000); - return false; - } - m_accel.add_bytes_end(); - - m_accel.advance_bytes(num_bytes_to_add); - - cur_seed_ofs += num_bytes_to_add; - } - - return true; - } - - bool lzcompressor::raw_parse_thread_state::init(lzcompressor& lzcomp, const lzcompressor::init_params ¶ms) - { - if (!m_state.init(lzcomp, params.m_table_max_update_interval, params.m_table_update_interval_slow_rate)) - return false; - - if (lzcomp.m_use_extreme_parsing) - { - for (uint j = 0; j < LZHAM_ARRAY_SIZE(m_nodes); j++) - m_nodes[j].clear(); - } - else - { - node_state *pNodes = reinterpret_cast(m_nodes); - - memset(pNodes, 0xFF, (1 + cMaxParseGraphNodes) * sizeof(node_state)); - } - - return true; - } - - bool lzcompressor::init(const init_params& params) - { - clear(); - - if ((params.m_dict_size_log2 < CLZBase::cMinDictSizeLog2) || (params.m_dict_size_log2 > CLZBase::cMaxDictSizeLog2)) - { - LZHAM_LOG_ERROR(7001); - return false; - } - - if ((params.m_compression_level < 0) || (params.m_compression_level > cCompressionLevelCount)) - { - LZHAM_LOG_ERROR(7002); - return false; - } - - m_params = params; - m_use_task_pool = (m_params.m_pTask_pool) && (m_params.m_pTask_pool->get_num_threads() != 0) && (m_params.m_max_helper_threads > 0); - - m_use_extreme_parsing = ((m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_EXTREME_PARSING) && (m_params.m_compression_level == cCompressionLevelUber)); - - if (!m_use_task_pool) - m_params.m_max_helper_threads = 0; - - m_settings = s_level_settings[params.m_compression_level]; - - m_fast_bytes = m_use_extreme_parsing ? LZHAM_EXTREME_PARSING_FAST_BYTES : m_settings.m_fast_bytes; - if (m_params.m_fast_bytes_override) - { - m_fast_bytes = math::clamp(m_params.m_fast_bytes_override, 8, CLZBase::cMaxMatchLen + 1); - } - - const uint dict_size = 1U << m_params.m_dict_size_log2; - - if (params.m_num_seed_bytes) - { - if (!params.m_pSeed_bytes) - { - LZHAM_LOG_ERROR(7003); - return false; - } - if (params.m_num_seed_bytes > dict_size) - { - LZHAM_LOG_ERROR(7004); - return false; - } - } - - uint max_block_size = dict_size / 8; - if (m_params.m_block_size > max_block_size) - { - m_params.m_block_size = max_block_size; - } - - m_num_parse_threads = 1; - -#if !LZHAM_FORCE_SINGLE_THREADED_PARSING - if ((m_params.m_max_helper_threads > 0) && ((m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_FORCE_SINGLE_THREADED_PARSING) == 0)) - { - LZHAM_ASSUME(cMaxParseThreads >= 4); - - if (m_params.m_block_size < 16384) - m_num_parse_threads = LZHAM_MIN(cMaxParseThreads, m_params.m_max_helper_threads + 1); - else if ((m_params.m_max_helper_threads <= 5) || (m_params.m_compression_level == cCompressionLevelFastest)) - m_num_parse_threads = 1; - else - m_num_parse_threads = m_use_extreme_parsing ? 4 : 2; - } -#endif - - int num_parse_jobs = m_num_parse_threads - 1; - uint match_accel_helper_threads = LZHAM_MAX(0, (int)m_params.m_max_helper_threads - num_parse_jobs); - match_accel_helper_threads = LZHAM_MIN(match_accel_helper_threads, cMatchAccelMaxSupportedThreads); - - LZHAM_ASSERT(m_num_parse_threads >= 1); - LZHAM_ASSERT(m_num_parse_threads <= cMaxParseThreads); - - if (!m_use_task_pool) - { - LZHAM_ASSERT(!match_accel_helper_threads && (m_num_parse_threads == 1)); - } - else - { - LZHAM_ASSERT((match_accel_helper_threads + (m_num_parse_threads - 1)) <= m_params.m_max_helper_threads); - } - - uint accel_flags = 0; - if (m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_DETERMINISTIC_PARSING) - accel_flags |= search_accelerator::cFlagDeterministic; - - if (m_params.m_compression_level > cCompressionLevelFastest) - { - if ((m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_USE_LOW_MEMORY_MATCH_FINDER) == 0) - accel_flags |= search_accelerator::cFlagHash24; - - accel_flags |= search_accelerator::cFlagLen2Matches; - } - - if (!m_accel.init(this, params.m_pTask_pool, match_accel_helper_threads, dict_size, m_settings.m_match_accel_max_matches_per_probe, false, m_settings.m_match_accel_max_probes, accel_flags)) - { - LZHAM_LOG_ERROR(7005); - return false; - } - - init_position_slots(params.m_dict_size_log2); - init_slot_tabs(); - - if (!m_state.init(*this, m_params.m_table_max_update_interval, m_params.m_table_update_interval_slow_rate)) - { - LZHAM_LOG_ERROR(7006); - return false; - } - - if (!m_block_buf.try_reserve(m_params.m_block_size)) - { - LZHAM_LOG_ERROR(7007); - return false; - } - - if (!m_comp_buf.try_reserve(m_params.m_block_size*2)) - { - LZHAM_LOG_ERROR(7008); - return false; - } - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_parse_thread_state); i++) - { - if (!m_parse_thread_state[i].init(*this, m_params)) - { - LZHAM_LOG_ERROR(7009); - return false; - } - } - - if (params.m_num_seed_bytes) - { - if (!init_seed_bytes()) - { - LZHAM_LOG_ERROR(7010); - return false; - } - } - - if (!send_zlib_header()) - { - LZHAM_LOG_ERROR(7011); - return false; - } - - m_src_size = 0; - - return true; - } - - // See http://www.gzip.org/zlib/rfc-zlib.html - // Method is set to 14 (LZHAM) and CINFO is (window_size - 15). - bool lzcompressor::send_zlib_header() - { - if ((m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_WRITE_ZLIB_STREAM) == 0) - return true; - - // set CM (method) and CINFO (dictionary size) fields - int cmf = LZHAM_Z_LZHAM | ((m_params.m_dict_size_log2 - 15) << 4); - - // set FLEVEL by mapping LZHAM's compression level to zlib's - int flg = 0; - switch (m_params.m_compression_level) - { - case LZHAM_COMP_LEVEL_FASTEST: - { - flg = 0 << 6; - break; - } - case LZHAM_COMP_LEVEL_FASTER: - { - flg = 1 << 6; - break; - } - case LZHAM_COMP_LEVEL_DEFAULT: - case LZHAM_COMP_LEVEL_BETTER: - { - flg = 2 << 6; - break; - } - default: - { - flg = 3 << 6; - break; - } - } - - // set FDICT flag - if (m_params.m_pSeed_bytes) - flg |= 32; - - int check = ((cmf << 8) + flg) % 31; - if (check) - flg += (31 - check); - - LZHAM_ASSERT(0 == (((cmf << 8) + flg) % 31)); - if (!m_comp_buf.try_push_back(static_cast(cmf))) - return false; - if (!m_comp_buf.try_push_back(static_cast(flg))) - return false; - - if (m_params.m_pSeed_bytes) - { - // send adler32 of DICT - uint dict_adler32 = adler32(m_params.m_pSeed_bytes, m_params.m_num_seed_bytes); - for (uint i = 0; i < 4; i++) - { - if (!m_comp_buf.try_push_back(static_cast(dict_adler32 >> 24))) - return false; - dict_adler32 <<= 8; - } - } - - return true; - } - - void lzcompressor::clear() - { - m_codec.clear(); - m_src_size = -1; - m_src_adler32 = cInitAdler32; - m_block_buf.clear(); - m_comp_buf.clear(); - - m_step = 0; - m_finished = false; - m_use_task_pool = false; - m_use_extreme_parsing = false; - m_block_start_dict_ofs = 0; - m_block_index = 0; - m_state.clear(); - m_num_parse_threads = 0; - m_fast_bytes = 128; - - for (uint i = 0; i < cMaxParseThreads; i++) - { - parse_thread_state &parse_state = m_parse_thread_state[i]; - parse_state.m_state.clear(); - - for (uint j = 0; j <= cMaxParseGraphNodes; j++) - parse_state.m_nodes[j].clear(); - - parse_state.m_start_ofs = 0; - parse_state.m_bytes_to_match = 0; - parse_state.m_best_decisions.clear(); - parse_state.m_issue_reset_state_partial = false; - parse_state.m_emit_decisions_backwards = false; - parse_state.m_failed = false; - parse_state.m_parse_early_out_thresh = UINT_MAX; - parse_state.m_bytes_actually_parsed = 0; - } - } - - bool lzcompressor::reset() - { - if (m_src_size < 0) - return false; - - m_accel.reset(); - m_codec.reset(); - m_stats.clear(); - m_src_size = 0; - m_src_adler32 = cInitAdler32; - m_block_buf.try_resize(0); - m_comp_buf.try_resize(0); - - m_step = 0; - m_finished = false; - m_block_start_dict_ofs = 0; - m_block_index = 0; - m_state.reset(); - - if (m_params.m_num_seed_bytes) - { - if (!init_seed_bytes()) - { - LZHAM_LOG_ERROR(7012); - return false; - } - } - - return send_zlib_header(); - } - - bool lzcompressor::code_decision(lzdecision lzdec, uint& cur_ofs, uint& bytes_to_match) - { -#ifdef LZHAM_LZDEBUG - if (!m_codec.encode_bits(CLZBase::cLZHAMDebugSyncMarkerValue, CLZBase::cLZHAMDebugSyncMarkerBits)) return false; - if (!m_codec.encode_bits(lzdec.is_match(), 1)) return false; - if (!m_codec.encode_bits(lzdec.get_len(), 17)) return false; - if (!m_codec.encode_bits(m_state.m_cur_state, 4)) return false; -#endif - -#ifdef LZHAM_LZVERIFY - if (lzdec.is_match()) - { - uint match_dist = lzdec.get_match_dist(m_state); - - LZHAM_VERIFY(m_accel[cur_ofs] == m_accel[(cur_ofs - match_dist) & (m_accel.get_max_dict_size() - 1)]); - } -#endif - - const uint len = lzdec.get_len(); - - if (!m_state.encode(m_codec, *this, m_accel, lzdec)) - { - LZHAM_LOG_ERROR(7013); - return false; - } - - cur_ofs += len; - LZHAM_ASSERT(bytes_to_match >= len); - bytes_to_match -= len; - - //m_accel.advance_bytes(len); - - m_step++; - - return true; - } - - bool lzcompressor::send_sync_block(lzham_flush_t flush_type) - { - m_codec.reset(); - - if (!m_codec.start_encoding(128)) - { - LZHAM_LOG_ERROR(7014); - return false; - } - -#ifdef LZHAM_LZDEBUG - if (!m_codec.encode_bits(166, 12)) - { - LZHAM_LOG_ERROR(7015); - return false; - } -#endif - - if (!m_codec.encode_bits(cSyncBlock, cBlockHeaderBits)) - { - LZHAM_LOG_ERROR(7016); - return false; - } - - int flush_code = 0; - switch (flush_type) - { - case LZHAM_FULL_FLUSH: - flush_code = 2; - break; - case LZHAM_TABLE_FLUSH: - flush_code = 1; - break; - case LZHAM_SYNC_FLUSH: - flush_code = 3; - break; - case LZHAM_NO_FLUSH: - case LZHAM_FINISH: - flush_code = 0; - break; - } - if (!m_codec.encode_bits(flush_code, cBlockFlushTypeBits)) - { - LZHAM_LOG_ERROR(7017); - return false; - } - - if (!m_codec.encode_align_to_byte()) - { - LZHAM_LOG_ERROR(7018); - return false; - } - if (!m_codec.encode_bits(0x0000, 16)) - { - LZHAM_LOG_ERROR(7019); - return false; - } - if (!m_codec.encode_bits(0xFFFF, 16)) - { - LZHAM_LOG_ERROR(7020); - return false; - } - if (!m_codec.stop_encoding(true)) - { - LZHAM_LOG_ERROR(7021); - return false; - } - if (!m_comp_buf.append(m_codec.get_encoding_buf())) - { - LZHAM_LOG_ERROR(7022); - return false; - } - - m_block_index++; - return true; - } - - bool lzcompressor::flush(lzham_flush_t flush_type) - { - LZHAM_ASSERT(!m_finished); - if (m_finished) - { - LZHAM_LOG_ERROR(7023); - return false; - } - - bool status = true; - if (m_block_buf.size()) - { - status = compress_block(m_block_buf.get_ptr(), m_block_buf.size()); - - m_block_buf.try_resize(0); - } - - if (status) - { - status = send_sync_block(flush_type); - - if (LZHAM_FULL_FLUSH == flush_type) - { - m_accel.flush(); - m_state.reset(); - } - } - - lzham_flush_buffered_printf(); - - return status; - } - - bool lzcompressor::put_bytes(const void* pBuf, uint buf_len) - { - LZHAM_ASSERT(!m_finished); - if (m_finished) - { - LZHAM_LOG_ERROR(7024); - return false; - } - - bool status = true; - - if (!pBuf) - { - // Last block - flush whatever's left and send the final block. - if (m_block_buf.size()) - { - status = compress_block(m_block_buf.get_ptr(), m_block_buf.size()); - - m_block_buf.try_resize(0); - } - - if (status) - { - if (!send_final_block()) - { - status = false; - LZHAM_LOG_ERROR(7025); - } - } - - m_finished = true; - } - else - { - // Compress blocks. - const uint8 *pSrcBuf = static_cast(pBuf); - uint num_src_bytes_remaining = buf_len; - - while (num_src_bytes_remaining) - { - const uint num_bytes_to_copy = LZHAM_MIN(num_src_bytes_remaining, m_params.m_block_size - m_block_buf.size()); - - if (num_bytes_to_copy == m_params.m_block_size) - { - LZHAM_ASSERT(!m_block_buf.size()); - - // Full-block available - compress in-place. - status = compress_block(pSrcBuf, num_bytes_to_copy); - } - else - { - // Less than a full block available - append to already accumulated bytes. - if (!m_block_buf.append(static_cast(pSrcBuf), num_bytes_to_copy)) - { - LZHAM_LOG_ERROR(7026); - return false; - } - - LZHAM_ASSERT(m_block_buf.size() <= m_params.m_block_size); - - if (m_block_buf.size() == m_params.m_block_size) - { - status = compress_block(m_block_buf.get_ptr(), m_block_buf.size()); - - m_block_buf.try_resize(0); - } - } - - if (!status) - { - LZHAM_LOG_ERROR(7027); - return false; - } - - pSrcBuf += num_bytes_to_copy; - num_src_bytes_remaining -= num_bytes_to_copy; - } - } - - lzham_flush_buffered_printf(); - - return status; - } - - bool lzcompressor::send_final_block() - { - if (!m_codec.start_encoding(16)) - { - LZHAM_LOG_ERROR(7028); - return false; - } - -#ifdef LZHAM_LZDEBUG - if (!m_codec.encode_bits(166, 12)) - { - LZHAM_LOG_ERROR(7029); - return false; - } -#endif - - if (!m_block_index) - { - if (!send_configuration()) - { - LZHAM_LOG_ERROR(7030); - return false; - } - } - - if (!m_codec.encode_bits(cEOFBlock, cBlockHeaderBits)) - { - LZHAM_LOG_ERROR(7031); - return false; - } - - if (!m_codec.encode_align_to_byte()) - { - LZHAM_LOG_ERROR(7032); - return false; - } - - if (!m_codec.encode_bits(m_src_adler32, 32)) - { - LZHAM_LOG_ERROR(7033); - return false; - } - - if (!m_codec.stop_encoding(true)) - { - LZHAM_LOG_ERROR(7034); - return false; - } - - if (m_comp_buf.empty()) - { - m_comp_buf.swap(m_codec.get_encoding_buf()); - } - else - { - if (!m_comp_buf.append(m_codec.get_encoding_buf())) - { - LZHAM_LOG_ERROR(7035); - return false; - } - } - - m_block_index++; - -#if LZHAM_UPDATE_STATS - m_stats.print(); -#endif - - return true; - } - - bool lzcompressor::send_configuration() - { - // TODO: Currently unused. - //if (!m_codec.encode_bits(m_settings.m_fast_adaptive_huffman_updating, 1)) - // return false; - //if (!m_codec.encode_bits(0, 1)) - // return false; - - return true; - } - - void lzcompressor::node::add_state( - int parent_index, int parent_state_index, - const lzdecision &lzdec, const state &parent_state, - bit_cost_t total_cost, - uint total_complexity, uint max_parse_node_states) - { - state_base trial_state; - parent_state.save_partial_state(trial_state); - trial_state.partial_advance(lzdec); - - for (int i = m_num_node_states - 1; i >= 0; i--) - { - node_state &cur_node_state = m_node_states[i]; - if (cur_node_state.m_saved_state == trial_state) - { - if ( (total_cost < cur_node_state.m_total_cost) || - ((total_cost == cur_node_state.m_total_cost) && (total_complexity < cur_node_state.m_total_complexity)) ) - { - cur_node_state.m_parent_index = static_cast(parent_index); - cur_node_state.m_parent_state_index = static_cast(parent_state_index); - cur_node_state.m_lzdec = lzdec; - cur_node_state.m_total_cost = total_cost; - cur_node_state.m_total_complexity = total_complexity; - - while (i > 0) - { - if ((m_node_states[i].m_total_cost < m_node_states[i - 1].m_total_cost) || - ((m_node_states[i].m_total_cost == m_node_states[i - 1].m_total_cost) && (m_node_states[i].m_total_complexity < m_node_states[i - 1].m_total_complexity))) - { - std::swap(m_node_states[i], m_node_states[i - 1]); - i--; - } - else - break; - } - } - - return; - } - } - - int insert_index; - for (insert_index = m_num_node_states; insert_index > 0; insert_index--) - { - node_state &cur_node_state = m_node_states[insert_index - 1]; - - if ( (total_cost > cur_node_state.m_total_cost) || - ((total_cost == cur_node_state.m_total_cost) && (total_complexity >= cur_node_state.m_total_complexity)) ) - { - break; - } - } - - if (insert_index == static_cast(max_parse_node_states)) - return; - - uint num_behind = m_num_node_states - insert_index; - uint num_to_move = (m_num_node_states < max_parse_node_states) ? num_behind : (num_behind - 1); - if (num_to_move) - { - LZHAM_ASSERT((insert_index + 1 + num_to_move) <= max_parse_node_states); - memmove(&m_node_states[insert_index + 1], &m_node_states[insert_index], sizeof(node_state) * num_to_move); - } - - node_state *pNew_node_state = &m_node_states[insert_index]; - pNew_node_state->m_parent_index = static_cast(parent_index); - pNew_node_state->m_parent_state_index = static_cast(parent_state_index); - pNew_node_state->m_lzdec = lzdec; - pNew_node_state->m_total_cost = total_cost; - pNew_node_state->m_total_complexity = total_complexity; - pNew_node_state->m_saved_state = trial_state; - - m_num_node_states = LZHAM_MIN(m_num_node_states + 1, static_cast(max_parse_node_states)); - -#ifdef LZHAM_LZVERIFY - for (uint i = 0; i < (m_num_node_states - 1); ++i) - { - node_state &a = m_node_states[i]; - node_state &b = m_node_states[i + 1]; - LZHAM_VERIFY( - (a.m_total_cost < b.m_total_cost) || - ((a.m_total_cost == b.m_total_cost) && (a.m_total_complexity <= b.m_total_complexity)) ); - } -#endif - } - - // The "extreme" parser tracks the best cMaxParseNodeStates (default 4) candidate LZ decisions per lookahead character. - // This allows the compressor to make locally suboptimal decisions that ultimately result in a better parse. - // It assumes the input statistics are locally stationary over the input block to parse. - bool lzcompressor::extreme_parse(parse_thread_state &parse_state) - { - LZHAM_ASSERT(parse_state.m_bytes_to_match <= cMaxParseGraphNodes); - - parse_state.m_failed = false; - parse_state.m_emit_decisions_backwards = true; - - node *pNodes = parse_state.m_nodes; - -#ifdef LZHAM_BUILD_DEBUG - for (uint i = 0; i < (cMaxParseGraphNodes + 1); i++) - { - LZHAM_ASSERT(pNodes[i].m_num_node_states == 0); - } -#endif - - state &approx_state = *parse_state.m_pState; - - pNodes[0].m_num_node_states = 1; - node_state &first_node_state = pNodes[0].m_node_states[0]; - approx_state.save_partial_state(first_node_state.m_saved_state); - first_node_state.m_parent_index = -1; - first_node_state.m_parent_state_index = -1; - first_node_state.m_total_cost = 0; - first_node_state.m_total_complexity = 0; - - const uint bytes_to_parse = parse_state.m_bytes_to_match; - - const uint lookahead_start_ofs = m_accel.get_lookahead_pos() & m_accel.get_max_dict_size_mask(); - - uint cur_dict_ofs = parse_state.m_start_ofs; - uint cur_lookahead_ofs = cur_dict_ofs - lookahead_start_ofs; - uint cur_node_index = 0; - - enum { cMaxFullMatches = cMatchAccelMaxSupportedProbes }; - uint match_lens[cMaxFullMatches]; - uint match_distances[cMaxFullMatches]; - - bit_cost_t lzdec_bitcosts[cMaxMatchLen + 1]; - - node prev_lit_node; - prev_lit_node.clear(); - - node *pMax_node_in_graph = &pNodes[0]; - - while (cur_node_index < bytes_to_parse) - { - node* pCur_node = &pNodes[cur_node_index]; - - if ((cur_node_index >= parse_state.m_parse_early_out_thresh) && (pCur_node == pMax_node_in_graph)) - { - // If the best path *must* pass through this node, and we're far enough along, and we're parsing using a single thread, then exit so we can move all our state forward. - if (pCur_node->m_num_node_states == 1) - break; - } - - const uint max_admissable_match_len = LZHAM_MIN(static_cast(CLZBase::cMaxMatchLen), bytes_to_parse - cur_node_index); - const uint find_dict_size = m_accel.get_cur_dict_size() + cur_lookahead_ofs; - - const uint lit_pred0 = approx_state.get_pred_char(m_accel, cur_dict_ofs, 1); - - const uint8* pLookahead = &m_accel.m_dict[cur_dict_ofs]; - - // full matches - uint max_full_match_len = 0; - uint num_full_matches = 0; - uint len2_match_dist = 0; - - if (max_admissable_match_len >= CLZBase::cMinMatchLen) - { - const dict_match* pMatches = m_accel.find_matches(cur_lookahead_ofs); - if (pMatches) - { - for ( ; ; ) - { - uint match_len = pMatches->get_len(); - LZHAM_ASSERT((pMatches->get_dist() > 0) && (pMatches->get_dist() <= m_dict_size)); - match_len = LZHAM_MIN(match_len, max_admissable_match_len); - - if (match_len > max_full_match_len) - { - max_full_match_len = match_len; - - match_lens[num_full_matches] = match_len; - match_distances[num_full_matches] = pMatches->get_dist(); - num_full_matches++; - } - - if (pMatches->is_last()) - break; - pMatches++; - } - } - - len2_match_dist = m_accel.get_len2_match(cur_lookahead_ofs); - } - - uint ahead_bytes = 1; - for (uint cur_node_state_index = 0; cur_node_state_index < pCur_node->m_num_node_states; cur_node_state_index++) - { - node_state &cur_node_state = pCur_node->m_node_states[cur_node_state_index]; - - if (cur_node_index) - { - LZHAM_ASSERT(cur_node_state.m_parent_index >= 0); - - approx_state.restore_partial_state(cur_node_state.m_saved_state); - } - - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(approx_state.m_cur_state); - - const bit_cost_t cur_node_total_cost = cur_node_state.m_total_cost; - const uint cur_node_total_complexity = cur_node_state.m_total_complexity; - - // rep matches - uint match_hist_max_len = 0; - uint match_hist_min_match_len = 1; - for (uint rep_match_index = 0; rep_match_index < cMatchHistSize; rep_match_index++) - { - uint hist_match_len = 0; - - uint dist = approx_state.m_match_hist[rep_match_index]; - if (dist <= find_dict_size) - { - const uint comp_pos = static_cast((m_accel.m_lookahead_pos + cur_lookahead_ofs - dist) & m_accel.m_max_dict_size_mask); - const uint8* pComp = &m_accel.m_dict[comp_pos]; - - for (hist_match_len = 0; hist_match_len < max_admissable_match_len; hist_match_len++) - if (pComp[hist_match_len] != pLookahead[hist_match_len]) - break; - } - - if (hist_match_len >= match_hist_min_match_len) - { - match_hist_max_len = math::maximum(match_hist_max_len, hist_match_len); - - approx_state.get_rep_match_costs(cur_dict_ofs, lzdec_bitcosts, rep_match_index, match_hist_min_match_len, hist_match_len, is_match_model_index); - - uint rep_match_total_complexity = cur_node_total_complexity + (cRep0Complexity + rep_match_index); - for (uint l = match_hist_min_match_len; l <= hist_match_len; l++) - { -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, l, -((int)rep_match_index + 1)); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lzdec_bitcosts[l]); - } -#endif - node& dst_node = pCur_node[l]; - - bit_cost_t rep_match_total_cost = cur_node_total_cost + lzdec_bitcosts[l]; - - dst_node.add_state(cur_node_index, cur_node_state_index, lzdecision(cur_dict_ofs, l, -((int)rep_match_index + 1)), approx_state, rep_match_total_cost, rep_match_total_complexity, parse_state.m_max_parse_node_states); - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &dst_node); - } - } - - match_hist_min_match_len = CLZBase::cMinMatchLen; - } - - if (match_hist_max_len >= m_fast_bytes) - { - ahead_bytes = match_hist_max_len; - break; - } - - uint min_truncate_match_len = match_hist_max_len; - - // nearest len2 match - if (len2_match_dist) - { - lzdecision lzdec(cur_dict_ofs, 2, len2_match_dist); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, lzdec); - pCur_node[2].add_state(cur_node_index, cur_node_state_index, lzdec, approx_state, cur_node_total_cost + actual_cost, cur_node_total_complexity + cShortMatchComplexity, parse_state.m_max_parse_node_states); - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &pCur_node[2]); - - min_truncate_match_len = LZHAM_MAX(min_truncate_match_len, 2); - } - - // full matches - if (max_full_match_len > min_truncate_match_len) - { - uint prev_max_match_len = LZHAM_MAX(1, min_truncate_match_len); - for (uint full_match_index = 0; full_match_index < num_full_matches; full_match_index++) - { - uint end_len = match_lens[full_match_index]; - if (end_len <= min_truncate_match_len) - continue; - - uint start_len = prev_max_match_len + 1; - uint match_dist = match_distances[full_match_index]; - - LZHAM_ASSERT(start_len <= end_len); - - approx_state.get_full_match_costs(*this, cur_dict_ofs, lzdec_bitcosts, match_dist, start_len, end_len, is_match_model_index); - - for (uint l = start_len; l <= end_len; l++) - { - uint match_complexity = (l >= cLongMatchComplexityLenThresh) ? cLongMatchComplexity : cShortMatchComplexity; - -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, l, match_dist); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lzdec_bitcosts[l]); - } -#endif - node& dst_node = pCur_node[l]; - - bit_cost_t match_total_cost = cur_node_total_cost + lzdec_bitcosts[l]; - uint match_total_complexity = cur_node_total_complexity + match_complexity; - - dst_node.add_state( cur_node_index, cur_node_state_index, lzdecision(cur_dict_ofs, l, match_dist), approx_state, match_total_cost, match_total_complexity, parse_state.m_max_parse_node_states); - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &dst_node); - } - - prev_max_match_len = end_len; - } - - if (max_full_match_len >= m_fast_bytes) - { - ahead_bytes = max_full_match_len; - break; - } - } - - // literal - bit_cost_t lit_cost = approx_state.get_lit_cost(*this, m_accel, cur_dict_ofs, lit_pred0, is_match_model_index); - bit_cost_t lit_total_cost = cur_node_total_cost + lit_cost; - uint lit_total_complexity = cur_node_total_complexity + cLitComplexity; -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, 0, 0); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lit_cost); - } -#endif - - pCur_node[1].add_state(cur_node_index, cur_node_state_index, lzdecision(cur_dict_ofs, 0, 0), approx_state, lit_total_cost, lit_total_complexity, parse_state.m_max_parse_node_states); - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &pCur_node[1]); - - } // cur_node_state_index - - cur_dict_ofs += ahead_bytes; - cur_lookahead_ofs += ahead_bytes; - cur_node_index += ahead_bytes; - } - - LZHAM_ASSERT(static_cast(cur_node_index) == (pMax_node_in_graph - pNodes)); - uint bytes_actually_parsed = cur_node_index; - - // Now get the optimal decisions by starting from the goal node. - // m_best_decisions is filled backwards. - if (!parse_state.m_best_decisions.try_reserve(bytes_actually_parsed)) - { - parse_state.m_failed = true; - - for (uint i = 0; i <= bytes_actually_parsed; i++) - pNodes[i].clear(); - - LZHAM_LOG_ERROR(7036); - - return false; - } - - bit_cost_t lowest_final_cost = cBitCostMax; //math::cNearlyInfinite; - int node_state_index = 0; - node_state *pLast_node_states = pNodes[bytes_actually_parsed].m_node_states; - for (uint i = 0; i < pNodes[bytes_actually_parsed].m_num_node_states; i++) - { - if (pLast_node_states[i].m_total_cost < lowest_final_cost) - { - lowest_final_cost = pLast_node_states[i].m_total_cost; - node_state_index = i; - } - } - - int node_index = bytes_actually_parsed; - lzdecision *pDst_dec = parse_state.m_best_decisions.get_ptr(); - do - { - LZHAM_ASSERT((node_index >= 0) && (node_index <= (int)cMaxParseGraphNodes)); - - node& cur_node = pNodes[node_index]; - const node_state &cur_node_state = cur_node.m_node_states[node_state_index]; - - *pDst_dec++ = cur_node_state.m_lzdec; - - node_index = cur_node_state.m_parent_index; - node_state_index = cur_node_state.m_parent_state_index; - - } while (node_index > 0); - - parse_state.m_best_decisions.try_resize_no_construct(static_cast(pDst_dec - parse_state.m_best_decisions.get_ptr())); - parse_state.m_bytes_actually_parsed = bytes_actually_parsed; - - for (uint i = 0; i <= bytes_actually_parsed; i++) - pNodes[i].clear(); - - return true; - } - - // Parsing notes: - // The regular "optimal" parser only tracks the single cheapest candidate LZ decision per lookahead character. - // This function finds the shortest path through an extremely dense node graph using a streamlined/simplified Dijkstra's algorithm with some coding heuristics. - // Graph edges are LZ "decisions", cost is measured in fractional bits needed to code each graph edge, and graph nodes are lookahead characters. - // There is no need to track visited/unvisted nodes, or find the next cheapest unvisted node in each iteration. The search always proceeds sequentially, visiting each lookahead character in turn from left/right. - // The major CPU expense of this function is the complexity of LZ decision cost evaluation, so a lot of implementation effort is spent here reducing this overhead. - // To simplify the problem, it assumes the input statistics are locally stationary over the input block to parse. (Otherwise, it would need to store, track, and update - // unique symbol statistics for each lookahead character, which would be very costly.) - // This function always sequentially pushes "forward" the unvisited node horizon. This horizon frequently collapses to a single node, which guarantees that the shortest path through the - // graph must pass through this node. LZMA tracks cumulative bitprices relative to this node, while LZHAM currently always tracks cumulative bitprices relative to the first node in the lookahead buffer. - // In very early versions of LZHAM the parse was much more understandable (straight Dijkstra with almost no bit price optimizations or coding heuristics). - bool lzcompressor::optimal_parse(parse_thread_state &parse_state) - { - LZHAM_ASSERT(parse_state.m_bytes_to_match <= cMaxParseGraphNodes); - - parse_state.m_failed = false; - parse_state.m_emit_decisions_backwards = true; - - node_state *pNodes = reinterpret_cast(parse_state.m_nodes); - pNodes[0].m_parent_index = -1; - pNodes[0].m_total_cost = 0; - pNodes[0].m_total_complexity = 0; - -#ifdef LZHAM_BUILD_DEBUG - for (uint i = 1; i < (cMaxParseGraphNodes + 1); i++) - { - LZHAM_ASSERT(pNodes[i].m_total_cost == cUINT64_MAX); - LZHAM_ASSERT(pNodes[i].m_total_complexity == UINT_MAX); - LZHAM_ASSERT(pNodes[i].m_parent_index == -1); - } -#endif - - state &approx_state = *parse_state.m_pState; - - const uint bytes_to_parse = parse_state.m_bytes_to_match; - - const uint lookahead_start_ofs = m_accel.get_lookahead_pos() & m_accel.get_max_dict_size_mask(); - - uint cur_dict_ofs = parse_state.m_start_ofs; - uint cur_lookahead_ofs = cur_dict_ofs - lookahead_start_ofs; - uint cur_node_index = 0; - - enum { cMaxFullMatches = cMatchAccelMaxSupportedProbes }; - uint match_lens[cMaxFullMatches]; - uint match_distances[cMaxFullMatches]; - - bit_cost_t lzdec_bitcosts[cMaxMatchLen + 1]; - - node_state *pMax_node_in_graph = &pNodes[0]; - - while (cur_node_index < bytes_to_parse) - { - node_state* pCur_node = &pNodes[cur_node_index]; - - if ((cur_node_index >= parse_state.m_parse_early_out_thresh) && (pCur_node == pMax_node_in_graph)) - { - // If the best path *must* pass through this node, and we're far enough along, and we're parsing using a single thread, then exit so we can move all our state forward. - break; - } - - const uint max_admissable_match_len = LZHAM_MIN(static_cast(CLZBase::cMaxMatchLen), bytes_to_parse - cur_node_index); - const uint find_dict_size = m_accel.m_cur_dict_size + cur_lookahead_ofs; - - if (cur_node_index) - { - LZHAM_ASSERT(pCur_node->m_parent_index >= 0); - - // Move to this node's state using the lowest cost LZ decision found. - approx_state.restore_partial_state(pCur_node->m_saved_state); - approx_state.partial_advance(pCur_node->m_lzdec); - } - - const bit_cost_t cur_node_total_cost = pCur_node->m_total_cost; - // This assert includes a fudge factor - make sure we don't overflow our scaled costs. - LZHAM_ASSERT((cBitCostMax - cur_node_total_cost) > (cBitCostScale * 64)); - const uint cur_node_total_complexity = pCur_node->m_total_complexity; - - const uint lit_pred0 = approx_state.get_pred_char(m_accel, cur_dict_ofs, 1); - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(approx_state.m_cur_state); - - const uint8* pLookahead = &m_accel.m_dict[cur_dict_ofs]; - - // rep matches - uint match_hist_max_len = 0; - uint match_hist_min_match_len = 1; - for (uint rep_match_index = 0; rep_match_index < cMatchHistSize; rep_match_index++) - { - uint hist_match_len = 0; - - uint dist = approx_state.m_match_hist[rep_match_index]; - if (dist <= find_dict_size) - { - const uint comp_pos = static_cast((m_accel.m_lookahead_pos + cur_lookahead_ofs - dist) & m_accel.m_max_dict_size_mask); - const uint8* pComp = &m_accel.m_dict[comp_pos]; - - for (hist_match_len = 0; hist_match_len < max_admissable_match_len; hist_match_len++) - if (pComp[hist_match_len] != pLookahead[hist_match_len]) - break; - } - - if (hist_match_len >= match_hist_min_match_len) - { - match_hist_max_len = math::maximum(match_hist_max_len, hist_match_len); - - approx_state.get_rep_match_costs(cur_dict_ofs, lzdec_bitcosts, rep_match_index, match_hist_min_match_len, hist_match_len, is_match_model_index); - - uint rep_match_total_complexity = cur_node_total_complexity + (cRep0Complexity + rep_match_index); - for (uint l = match_hist_min_match_len; l <= hist_match_len; l++) - { -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, l, -((int)rep_match_index + 1)); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lzdec_bitcosts[l]); - } -#endif - node_state& dst_node = pCur_node[l]; - - bit_cost_t rep_match_total_cost = cur_node_total_cost + lzdec_bitcosts[l]; - - if ((rep_match_total_cost > dst_node.m_total_cost) || ((rep_match_total_cost == dst_node.m_total_cost) && (rep_match_total_complexity >= dst_node.m_total_complexity))) - continue; - - dst_node.m_total_cost = rep_match_total_cost; - dst_node.m_total_complexity = rep_match_total_complexity; - dst_node.m_parent_index = (uint16)cur_node_index; - approx_state.save_partial_state(dst_node.m_saved_state); - dst_node.m_lzdec.init(cur_dict_ofs, l, -((int)rep_match_index + 1)); - dst_node.m_lzdec.m_len = l; - - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &dst_node); - } - } - - match_hist_min_match_len = CLZBase::cMinMatchLen; - } - - uint max_match_len = match_hist_max_len; - - if (max_match_len >= m_fast_bytes) - { - cur_dict_ofs += max_match_len; - cur_lookahead_ofs += max_match_len; - cur_node_index += max_match_len; - continue; - } - - // full matches - if (max_admissable_match_len >= CLZBase::cMinMatchLen) - { - uint num_full_matches = 0; - - if (match_hist_max_len < 2) - { - // Get the nearest len2 match if we didn't find a rep len2. - uint len2_match_dist = m_accel.get_len2_match(cur_lookahead_ofs); - if (len2_match_dist) - { - bit_cost_t cost = approx_state.get_len2_match_cost(*this, cur_dict_ofs, len2_match_dist, is_match_model_index); - -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, 2, len2_match_dist); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == cost); - } -#endif - - node_state& dst_node = pCur_node[2]; - - bit_cost_t match_total_cost = cur_node_total_cost + cost; - uint match_total_complexity = cur_node_total_complexity + cShortMatchComplexity; - - if ((match_total_cost < dst_node.m_total_cost) || ((match_total_cost == dst_node.m_total_cost) && (match_total_complexity < dst_node.m_total_complexity))) - { - dst_node.m_total_cost = match_total_cost; - dst_node.m_total_complexity = match_total_complexity; - dst_node.m_parent_index = (uint16)cur_node_index; - approx_state.save_partial_state(dst_node.m_saved_state); - dst_node.m_lzdec.init(cur_dict_ofs, 2, len2_match_dist); - - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &dst_node); - } - - max_match_len = 2; - } - } - - const uint min_truncate_match_len = max_match_len; - - // Now get all full matches: the nearest matches at each match length. (Actually, we don't - // always get the nearest match. The match finder favors those matches which have the lowest value - // in the nibble of each match distance, all other things being equal, to help exploit how the lowest - // nibble of match distances is separately coded.) - const dict_match* pMatches = m_accel.find_matches(cur_lookahead_ofs); - if (pMatches) - { - for ( ; ; ) - { - uint match_len = pMatches->get_len(); - LZHAM_ASSERT((pMatches->get_dist() > 0) && (pMatches->get_dist() <= m_dict_size)); - match_len = LZHAM_MIN(match_len, max_admissable_match_len); - - if (match_len > max_match_len) - { - max_match_len = match_len; - - match_lens[num_full_matches] = match_len; - match_distances[num_full_matches] = pMatches->get_dist(); - num_full_matches++; - } - - if (pMatches->is_last()) - break; - pMatches++; - } - } - - if (num_full_matches) - { - uint prev_max_match_len = LZHAM_MAX(1, min_truncate_match_len); - for (uint full_match_index = 0; full_match_index < num_full_matches; full_match_index++) - { - uint start_len = prev_max_match_len + 1; - uint end_len = match_lens[full_match_index]; - uint match_dist = match_distances[full_match_index]; - - LZHAM_ASSERT(start_len <= end_len); - - approx_state.get_full_match_costs(*this, cur_dict_ofs, lzdec_bitcosts, match_dist, start_len, end_len, is_match_model_index); - - for (uint l = start_len; l <= end_len; l++) - { - uint match_complexity = (l >= cLongMatchComplexityLenThresh) ? cLongMatchComplexity : cShortMatchComplexity; - -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, l, match_dist); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lzdec_bitcosts[l]); - } -#endif - node_state& dst_node = pCur_node[l]; - - bit_cost_t match_total_cost = cur_node_total_cost + lzdec_bitcosts[l]; - uint match_total_complexity = cur_node_total_complexity + match_complexity; - - if ((match_total_cost > dst_node.m_total_cost) || ((match_total_cost == dst_node.m_total_cost) && (match_total_complexity >= dst_node.m_total_complexity))) - continue; - - dst_node.m_total_cost = match_total_cost; - dst_node.m_total_complexity = match_total_complexity; - dst_node.m_parent_index = (uint16)cur_node_index; - approx_state.save_partial_state(dst_node.m_saved_state); - dst_node.m_lzdec.init(cur_dict_ofs, l, match_dist); - - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &dst_node); - } - - prev_max_match_len = end_len; - } - } - } - - if (max_match_len >= m_fast_bytes) - { - cur_dict_ofs += max_match_len; - cur_lookahead_ofs += max_match_len; - cur_node_index += max_match_len; - continue; - } - - // literal - bit_cost_t lit_cost = approx_state.get_lit_cost(*this, m_accel, cur_dict_ofs, lit_pred0, is_match_model_index); - bit_cost_t lit_total_cost = cur_node_total_cost + lit_cost; - uint lit_total_complexity = cur_node_total_complexity + cLitComplexity; -#if LZHAM_VERIFY_MATCH_COSTS - { - lzdecision actual_dec(cur_dict_ofs, 0, 0); - bit_cost_t actual_cost = approx_state.get_cost(*this, m_accel, actual_dec); - LZHAM_ASSERT(actual_cost == lit_cost); - } -#endif - if ((lit_total_cost < pCur_node[1].m_total_cost) || ((lit_total_cost == pCur_node[1].m_total_cost) && (lit_total_complexity < pCur_node[1].m_total_complexity))) - { - pCur_node[1].m_total_cost = lit_total_cost; - pCur_node[1].m_total_complexity = lit_total_complexity; - pCur_node[1].m_parent_index = (int16)cur_node_index; - approx_state.save_partial_state(pCur_node[1].m_saved_state); - pCur_node[1].m_lzdec.init(cur_dict_ofs, 0, 0); - - pMax_node_in_graph = LZHAM_MAX(pMax_node_in_graph, &pCur_node[1]); - } - - cur_dict_ofs++; - cur_lookahead_ofs++; - cur_node_index++; - - } // graph search - - LZHAM_ASSERT(static_cast(cur_node_index) == (pMax_node_in_graph - pNodes)); - uint bytes_actually_parsed = cur_node_index; - - // Now get the optimal decisions by starting from the goal node. - // m_best_decisions is filled backwards. - if (!parse_state.m_best_decisions.try_reserve(bytes_actually_parsed)) - { - parse_state.m_failed = true; - - memset(pNodes, 0xFF, (pMax_node_in_graph - pNodes + 1) * sizeof(node_state)); - - LZHAM_LOG_ERROR(7037); - - return false; - } - - int node_index = bytes_actually_parsed; - lzdecision *pDst_dec = parse_state.m_best_decisions.get_ptr(); - do - { - LZHAM_ASSERT((node_index >= 0) && (node_index <= (int)cMaxParseGraphNodes)); - node_state& cur_node = pNodes[node_index]; - - *pDst_dec++ = cur_node.m_lzdec; - - node_index = cur_node.m_parent_index; - - } while (node_index > 0); - - parse_state.m_best_decisions.try_resize_no_construct(static_cast(pDst_dec - parse_state.m_best_decisions.get_ptr())); - - parse_state.m_bytes_actually_parsed = bytes_actually_parsed; - - memset(pNodes, 0xFF, (pMax_node_in_graph - pNodes + 1) * sizeof(node_state)); - - return true; - } - - void lzcompressor::parse_job_callback(uint64 data, void* pData_ptr) - { - const uint parse_job_index = (uint)data; - parse_thread_state &parse_state = m_parse_thread_state[parse_job_index]; - - scoped_perf_section parse_job_timer(cVarArgs, "parse_job_callback %u", parse_job_index); - - LZHAM_NOTE_UNUSED(pData_ptr); - - if (m_use_extreme_parsing) - extreme_parse(parse_state); - else - optimal_parse(parse_state); - - if (parse_state.m_use_semaphore) - { - parse_state.m_finished.release(); - } - } - - // ofs is the absolute dictionary offset, must be >= the lookahead offset. - // TODO: Doesn't find len2 matches - int lzcompressor::enumerate_lz_decisions(uint ofs, const state& cur_state, lzham::vector& decisions, uint min_match_len, uint max_match_len) - { - LZHAM_ASSERT(min_match_len >= 1); - - uint start_ofs = m_accel.get_lookahead_pos() & m_accel.get_max_dict_size_mask(); - LZHAM_ASSERT(ofs >= start_ofs); - const uint lookahead_ofs = ofs - start_ofs; - - uint largest_index = 0; - uint largest_len; - bit_cost_t largest_cost; - - if (min_match_len <= 1) - { - if (!decisions.try_resize(1)) - { - LZHAM_LOG_ERROR(7038); - return -1; - } - - lzpriced_decision& lit_dec = decisions[0]; - lit_dec.init(ofs, 0, 0, 0); - lit_dec.m_cost = cur_state.get_cost(*this, m_accel, lit_dec); - largest_cost = lit_dec.m_cost; - - largest_len = 1; - } - else - { - if (!decisions.try_resize(0)) - { - LZHAM_LOG_ERROR(7039); - return -1; - } - - largest_len = 0; - largest_cost = cBitCostMax; - } - - uint match_hist_max_len = 0; - - // Add rep matches. - for (uint i = 0; i < cMatchHistSize; i++) - { - uint hist_match_len = m_accel.get_match_len(lookahead_ofs, cur_state.m_match_hist[i], max_match_len); - if (hist_match_len < min_match_len) - continue; - - if ( ((hist_match_len == 1) && (i == 0)) || (hist_match_len >= CLZBase::cMinMatchLen) ) - { - match_hist_max_len = math::maximum(match_hist_max_len, hist_match_len); - - lzpriced_decision dec(ofs, hist_match_len, -((int)i + 1)); - dec.m_cost = cur_state.get_cost(*this, m_accel, dec); - - if (!decisions.try_push_back(dec)) - { - LZHAM_LOG_ERROR(7040); - return -1; - } - - if ( (hist_match_len > largest_len) || ((hist_match_len == largest_len) && (dec.m_cost < largest_cost)) ) - { - largest_index = decisions.size() - 1; - largest_len = hist_match_len; - largest_cost = dec.m_cost; - } - } - } - - // Now add full matches. - if ((max_match_len >= CLZBase::cMinMatchLen) && (match_hist_max_len < m_fast_bytes)) - { - const dict_match* pMatches = m_accel.find_matches(lookahead_ofs); - - if (pMatches) - { - for ( ; ; ) - { - uint match_len = math::minimum(pMatches->get_len(), max_match_len); - LZHAM_ASSERT((pMatches->get_dist() > 0) && (pMatches->get_dist() <= m_dict_size)); - - // Full matches are very likely to be more expensive than rep matches of the same length, so don't bother evaluating them. - if ((match_len >= min_match_len) && (match_len > match_hist_max_len)) - { - if ((max_match_len > CLZBase::cMaxMatchLen) && (match_len == CLZBase::cMaxMatchLen)) - { - match_len = m_accel.get_match_len(lookahead_ofs, pMatches->get_dist(), max_match_len, CLZBase::cMaxMatchLen); - } - - lzpriced_decision dec(ofs, match_len, pMatches->get_dist()); - dec.m_cost = cur_state.get_cost(*this, m_accel, dec); - - if (!decisions.try_push_back(dec)) - { - LZHAM_LOG_ERROR(7041); - return -1; - } - - if ( (match_len > largest_len) || ((match_len == largest_len) && (dec.get_cost() < largest_cost)) ) - { - largest_index = decisions.size() - 1; - largest_len = match_len; - largest_cost = dec.get_cost(); - } - } - if (pMatches->is_last()) - break; - pMatches++; - } - } - } - - return largest_index; - } - - bool lzcompressor::greedy_parse(parse_thread_state &parse_state) - { - parse_state.m_failed = true; - parse_state.m_emit_decisions_backwards = false; - - const uint bytes_to_parse = parse_state.m_bytes_to_match; - - const uint lookahead_start_ofs = m_accel.get_lookahead_pos() & m_accel.get_max_dict_size_mask(); - - uint cur_dict_ofs = parse_state.m_start_ofs; - uint cur_lookahead_ofs = cur_dict_ofs - lookahead_start_ofs; - uint cur_ofs = 0; - - state &approx_state = *parse_state.m_pState; - - lzham::vector &decisions = parse_state.m_temp_decisions; - - if (!decisions.try_reserve(384)) - { - LZHAM_LOG_ERROR(7042); - return false; - } - - if (!parse_state.m_best_decisions.try_resize(0)) - { - LZHAM_LOG_ERROR(7043); - return false; - } - - while (cur_ofs < bytes_to_parse) - { - const uint max_admissable_match_len = LZHAM_MIN(static_cast(CLZBase::cMaxHugeMatchLen), bytes_to_parse - cur_ofs); - - int largest_dec_index = enumerate_lz_decisions(cur_dict_ofs, approx_state, decisions, 1, max_admissable_match_len); - if (largest_dec_index < 0) - { - LZHAM_LOG_ERROR(7044); - return false; - } - - const lzpriced_decision &dec = decisions[largest_dec_index]; - - if (!parse_state.m_best_decisions.try_push_back(dec)) - { - LZHAM_LOG_ERROR(7045); - return false; - } - - approx_state.partial_advance(dec); - - uint match_len = dec.get_len(); - LZHAM_ASSERT(match_len <= max_admissable_match_len); - cur_dict_ofs += match_len; - cur_lookahead_ofs += match_len; - cur_ofs += match_len; - - if (parse_state.m_best_decisions.size() >= parse_state.m_max_greedy_decisions) - { - parse_state.m_greedy_parse_total_bytes_coded = cur_ofs; - parse_state.m_bytes_actually_parsed = cur_ofs; - parse_state.m_greedy_parse_gave_up = true; - return false; - } - } - - parse_state.m_greedy_parse_total_bytes_coded = cur_ofs; - - LZHAM_ASSERT(cur_ofs == bytes_to_parse); - - parse_state.m_failed = false; - parse_state.m_bytes_actually_parsed = parse_state.m_bytes_to_match; - - return true; - } - - bool lzcompressor::compress_block(const void* pBuf, uint buf_len) - { - uint cur_ofs = 0; - uint bytes_remaining = buf_len; - while (bytes_remaining) - { - uint bytes_to_compress = math::minimum(m_accel.get_max_add_bytes(), bytes_remaining); - if (!compress_block_internal(static_cast(pBuf) + cur_ofs, bytes_to_compress)) - { - LZHAM_LOG_ERROR(7046); - return false; - } - - cur_ofs += bytes_to_compress; - bytes_remaining -= bytes_to_compress; - } - return true; - } - - bool lzcompressor::compress_block_internal(const void* pBuf, uint buf_len) - { - scoped_perf_section compress_block_timer(cVarArgs, "****** compress_block %u", m_block_index); - - LZHAM_ASSERT(pBuf); - LZHAM_ASSERT(buf_len <= m_params.m_block_size); - - LZHAM_ASSERT(m_src_size >= 0); - if (m_src_size < 0) - return false; - - m_src_size += buf_len; - - // Important: Don't do any expensive work until after add_bytes_begin() is called, to increase parallelism. - if (!m_accel.add_bytes_begin(buf_len, static_cast(pBuf))) - { - LZHAM_LOG_ERROR(7047); - return false; - } - - bool computed_adler32 = false; - - m_start_of_block_state = m_state; - - m_block_start_dict_ofs = m_accel.get_lookahead_pos() & (m_accel.get_max_dict_size() - 1); - - uint cur_dict_ofs = m_block_start_dict_ofs; - - uint bytes_to_match = buf_len; - - if (!m_codec.start_encoding((buf_len * 9) / 8)) - { - LZHAM_LOG_ERROR(7048); - return false; - } - - if (!m_block_index) - { - if (!send_configuration()) - { - LZHAM_LOG_ERROR(7049); - return false; - } - } - -#ifdef LZHAM_LZDEBUG - m_codec.encode_bits(166, 12); -#endif - - if (!m_codec.encode_bits(cCompBlock, cBlockHeaderBits)) - { - LZHAM_LOG_ERROR(7050); - return false; - } - - if (!m_codec.encode_arith_init()) - { - LZHAM_LOG_ERROR(7051); - return false; - } - - m_state.start_of_block(m_accel, cur_dict_ofs, m_block_index); - - bool emit_reset_update_rate_command = false; - - if (m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_TRADEOFF_DECOMPRESSION_RATE_FOR_COMP_RATIO) - { - emit_reset_update_rate_command = true; - - m_state.reset_update_rate(); - } - - // TODO: We could also issue a full huff/arith table reset (code 2), and see if that actually improves the block's compression. - m_codec.encode_bits(emit_reset_update_rate_command ? 1 : 0, cBlockFlushTypeBits); - - //coding_stats initial_stats(m_stats); - - uint initial_step = m_step; - - while (bytes_to_match) - { - const uint cAvgAcceptableGreedyMatchLen = 384; - if ((m_params.m_pSeed_bytes) && (bytes_to_match >= cAvgAcceptableGreedyMatchLen)) - { - parse_thread_state &greedy_parse_state = m_parse_thread_state[cMaxParseThreads]; - - greedy_parse_state.m_pState = &greedy_parse_state.m_state; - greedy_parse_state.m_state = m_state; - greedy_parse_state.m_state.m_cur_ofs = cur_dict_ofs; - - greedy_parse_state.m_issue_reset_state_partial = false; - greedy_parse_state.m_start_ofs = cur_dict_ofs; - greedy_parse_state.m_bytes_to_match = LZHAM_MIN(bytes_to_match, static_cast(CLZBase::cMaxHugeMatchLen)); - - greedy_parse_state.m_max_greedy_decisions = LZHAM_MAX((bytes_to_match / cAvgAcceptableGreedyMatchLen), 2); - greedy_parse_state.m_greedy_parse_gave_up = false; - greedy_parse_state.m_greedy_parse_total_bytes_coded = 0; - - greedy_parse_state.m_parse_early_out_thresh = UINT_MAX; - greedy_parse_state.m_bytes_actually_parsed = 0; - - greedy_parse_state.m_use_semaphore = false; - - if (!greedy_parse(greedy_parse_state)) - { - if (!greedy_parse_state.m_greedy_parse_gave_up) - { - LZHAM_LOG_ERROR(7052); - return false; - } - } - - uint num_greedy_decisions_to_code = 0; - - const lzham::vector &best_decisions = greedy_parse_state.m_best_decisions; - - if (!greedy_parse_state.m_greedy_parse_gave_up) - num_greedy_decisions_to_code = best_decisions.size(); - else - { - uint num_small_decisions = 0; - uint total_match_len = 0; - uint max_match_len = 0; - - uint i; - for (i = 0; i < best_decisions.size(); i++) - { - const lzdecision &dec = best_decisions[i]; - if (dec.get_len() <= CLZBase::cMaxMatchLen) - { - num_small_decisions++; - if (num_small_decisions > 16) - break; - } - - total_match_len += dec.get_len(); - max_match_len = LZHAM_MAX(max_match_len, dec.get_len()); - } - - if (max_match_len > CLZBase::cMaxMatchLen) - { - if ((total_match_len / i) >= cAvgAcceptableGreedyMatchLen) - { - num_greedy_decisions_to_code = i; - } - } - } - - if (num_greedy_decisions_to_code) - { - for (uint i = 0; i < num_greedy_decisions_to_code; i++) - { - LZHAM_ASSERT(best_decisions[i].m_pos == (int)cur_dict_ofs); - //LZHAM_ASSERT(i >= 0); - LZHAM_ASSERT(i < best_decisions.size()); - -#if LZHAM_UPDATE_STATS - bit_cost_t cost = m_state.get_cost(*this, m_accel, best_decisions[i]); - m_stats.update(best_decisions[i], m_state, m_accel, cost); -#endif - - if (!code_decision(best_decisions[i], cur_dict_ofs, bytes_to_match)) - { - LZHAM_LOG_ERROR(7053); - return false; - } - - m_accel.advance_bytes(best_decisions[i].get_len()); - } - - if ((!greedy_parse_state.m_greedy_parse_gave_up) || (!bytes_to_match)) - { - if (!computed_adler32) - { - computed_adler32 = true; - - scoped_perf_section add_bytes_timer("adler32"); - m_src_adler32 = adler32(pBuf, buf_len, m_src_adler32); - } - - continue; - } - } - } - - uint num_parse_jobs = LZHAM_MIN(m_num_parse_threads, (bytes_to_match + cMaxParseGraphNodes - 1) / cMaxParseGraphNodes); - if ((m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_DETERMINISTIC_PARSING) == 0) - { - if (m_use_task_pool && m_accel.get_max_helper_threads()) - { - // Increase the number of active parse jobs as the match finder finishes up to keep CPU utilization up. - num_parse_jobs += m_accel.get_num_completed_helper_threads(); - num_parse_jobs = LZHAM_MIN(num_parse_jobs, cMaxParseThreads); - } - } - - // Don't bother threading if the remaining bytes to parse is too small. - if ((bytes_to_match < 1536) || (m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_FORCE_SINGLE_THREADED_PARSING)) - num_parse_jobs = 1; - - // Update the coding statistics more frequently near the beginning of streams. - if ((!m_block_index) && ((cur_dict_ofs - m_block_start_dict_ofs) < cMaxParseGraphNodes * 4)) - num_parse_jobs = 1; - - uint parse_thread_start_ofs = cur_dict_ofs; - uint parse_thread_total_size = LZHAM_MIN(bytes_to_match, cMaxParseGraphNodes * num_parse_jobs); - - uint parse_thread_remaining = parse_thread_total_size; - - state_base saved_state; - if (num_parse_jobs == 1) - m_state.save_partial_state(saved_state); - - for (uint parse_thread_index = 0; parse_thread_index < num_parse_jobs; parse_thread_index++) - { - parse_thread_state &parse_thread = m_parse_thread_state[parse_thread_index]; - - if (num_parse_jobs == 1) - { - parse_thread.m_pState = &m_state; - } - else - { - parse_thread.m_pState = &parse_thread.m_state; - parse_thread.m_state = m_state; - } - - parse_thread.m_pState->m_cur_ofs = parse_thread_start_ofs; - - if (parse_thread_index > 0) - { - parse_thread.m_pState->reset_state_partial(); - parse_thread.m_issue_reset_state_partial = true; - } - else - { - parse_thread.m_issue_reset_state_partial = false; - } - - parse_thread.m_start_ofs = parse_thread_start_ofs; - if (parse_thread_index == (num_parse_jobs - 1)) - parse_thread.m_bytes_to_match = parse_thread_remaining; - else - parse_thread.m_bytes_to_match = parse_thread_total_size / num_parse_jobs; - - parse_thread.m_bytes_to_match = LZHAM_MIN(parse_thread.m_bytes_to_match, cMaxParseGraphNodes); - LZHAM_ASSERT(parse_thread.m_bytes_to_match > 0); - - parse_thread.m_max_parse_node_states = m_params.m_extreme_parsing_max_best_arrivals; - parse_thread.m_max_greedy_decisions = UINT_MAX; - parse_thread.m_greedy_parse_gave_up = false; - - parse_thread.m_parse_early_out_thresh = UINT_MAX; - parse_thread.m_bytes_actually_parsed = 0; - - parse_thread.m_use_semaphore = ((m_use_task_pool) && (num_parse_jobs > 1)) && (parse_thread_index > 0); - - if ((m_params.m_compression_level == cCompressionLevelUber) && (num_parse_jobs == 1)) - { - // Allow the parsers to exit early if they encounter a graph bottleneck, so we can move the coding statistics forward before parsing again. - parse_thread.m_parse_early_out_thresh = (m_params.m_lzham_compress_flags & LZHAM_COMP_FLAG_EXTREME_PARSING) ? 16 : 64; - } - - parse_thread_start_ofs += parse_thread.m_bytes_to_match; - parse_thread_remaining -= parse_thread.m_bytes_to_match; - } - - { - scoped_perf_section parse_timer("parsing"); - - if ((m_use_task_pool) && (num_parse_jobs > 1)) - { - { - scoped_perf_section queue_task_timer("queuing parse tasks"); - - if (!m_params.m_pTask_pool->queue_multiple_object_tasks(this, &lzcompressor::parse_job_callback, 1, num_parse_jobs - 1)) - return false; - } - - parse_job_callback(0, NULL); - } - else - { - for (uint parse_thread_index = 0; parse_thread_index < num_parse_jobs; parse_thread_index++) - { - parse_job_callback(parse_thread_index, NULL); - } - } - } - - if (num_parse_jobs == 1) - m_state.restore_partial_state(saved_state); - - if (!computed_adler32) - { - computed_adler32 = true; - - scoped_perf_section add_bytes_timer("adler32"); - m_src_adler32 = adler32(pBuf, buf_len, m_src_adler32); - } - -#define LZHAM_RELEASE_SEMAPHORES for (uint pti = 1; pti < num_parse_jobs; pti++) if (m_parse_thread_state[pti].m_use_semaphore) { m_parse_thread_state[pti].m_finished.wait(); m_parse_thread_state[pti].m_use_semaphore = false; } - - { - scoped_perf_section coding_timer("coding"); - - uint total_bytes_parsed = 0; - - for (uint parse_thread_index = 0; parse_thread_index < num_parse_jobs; parse_thread_index++) - { - parse_thread_state &parse_thread = m_parse_thread_state[parse_thread_index]; - - if (parse_thread.m_use_semaphore) - { - scoped_perf_section sect(cVarArgs, "Waiting for parser %u", parse_thread_index); - m_parse_thread_state[parse_thread_index].m_finished.wait(); - m_parse_thread_state[parse_thread_index].m_use_semaphore = false; - } - - if (parse_thread.m_failed) - { - LZHAM_RELEASE_SEMAPHORES - LZHAM_LOG_ERROR(7054); - return false; - } - - const lzham::vector &best_decisions = parse_thread.m_best_decisions; - - if (parse_thread.m_issue_reset_state_partial) - { - if (!m_state.encode_reset_state_partial(m_codec, m_accel, cur_dict_ofs)) - { - LZHAM_RELEASE_SEMAPHORES - LZHAM_LOG_ERROR(7055); - return false; - } - m_step++; - } - - if (best_decisions.size()) - { - int i = 0; - int end_dec_index = static_cast(best_decisions.size()) - 1; - int dec_step = 1; - if (parse_thread.m_emit_decisions_backwards) - { - i = static_cast(best_decisions.size()) - 1; - end_dec_index = 0; - dec_step = -1; - LZHAM_ASSERT(best_decisions.back().m_pos == (int)parse_thread.m_start_ofs); - } - else - { - LZHAM_ASSERT(best_decisions.front().m_pos == (int)parse_thread.m_start_ofs); - } - - // Loop rearranged to avoid bad x64 codegen problem with MSVC2008. - for ( ; ; ) - { - LZHAM_ASSERT(best_decisions[i].m_pos == (int)cur_dict_ofs); - LZHAM_ASSERT(i >= 0); - LZHAM_ASSERT(i < (int)best_decisions.size()); - -#if LZHAM_UPDATE_STATS - bit_cost_t cost = m_state.get_cost(*this, m_accel, best_decisions[i]); - m_stats.update(best_decisions[i], m_state, m_accel, cost); - //m_state.print(m_codec, *this, m_accel, best_decisions[i]); -#endif - - if (!code_decision(best_decisions[i], cur_dict_ofs, bytes_to_match)) - { - LZHAM_RELEASE_SEMAPHORES - LZHAM_LOG_ERROR(7056); - return false; - } - - total_bytes_parsed += best_decisions[i].get_len(); - - if (i == end_dec_index) - break; - i += dec_step; - } - - LZHAM_NOTE_UNUSED(i); - } - - LZHAM_ASSERT(cur_dict_ofs == parse_thread.m_start_ofs + parse_thread.m_bytes_actually_parsed); - - } // parse_thread_index - - m_accel.advance_bytes(total_bytes_parsed); - - } // coding - - } // while (bytes_to_match) - - { - scoped_perf_section add_bytes_timer("add_bytes_end"); - m_accel.add_bytes_end(); - } - - if (!m_state.encode_eob(m_codec, m_accel, cur_dict_ofs)) - { - LZHAM_LOG_ERROR(7057); - return false; - } - -#ifdef LZHAM_LZDEBUG - if (!m_codec.encode_bits(366, 12)) - { - LZHAM_LOG_ERROR(7058); - return false; - } -#endif - - { - scoped_perf_section stop_encoding_timer("stop_encoding"); - if (!m_codec.stop_encoding(true)) - { - LZHAM_LOG_ERROR(7059); - return false; - } - } - - // Coded the entire block - now see if it makes more sense to just send a raw/uncompressed block. - - uint compressed_size = m_codec.get_encoding_buf().size(); - LZHAM_NOTE_UNUSED(compressed_size); - - //bool used_raw_block = false; - -#if !LZHAM_FORCE_ALL_RAW_BLOCKS - #if (defined(LZHAM_DISABLE_RAW_BLOCKS) || defined(LZHAM_LZDEBUG)) - if (0) - #else - // TODO: Allow the user to control this threshold, i.e. if less than 1% then just store uncompressed. - if (compressed_size >= buf_len) - #endif -#endif - { - // Failed to compress the block, so go back to our original state and just code a raw block. - m_state = m_start_of_block_state; - m_step = initial_step; - //m_stats = initial_stats; - - m_codec.reset(); - - if (!m_codec.start_encoding(buf_len + 16)) - { - LZHAM_LOG_ERROR(7060); - return false; - } - - if (!m_block_index) - { - if (!send_configuration()) - { - LZHAM_LOG_ERROR(7061); - return false; - } - } - -#ifdef LZHAM_LZDEBUG - if (!m_codec.encode_bits(166, 12)) - { - LZHAM_LOG_ERROR(7062); - return false; - } -#endif - - if (!m_codec.encode_bits(cRawBlock, cBlockHeaderBits)) - { - LZHAM_LOG_ERROR(7063); - return false; - } - - LZHAM_ASSERT(buf_len <= 0x1000000); - if (!m_codec.encode_bits(buf_len - 1, 24)) - { - LZHAM_LOG_ERROR(7064); - return false; - } - - // Write buf len check bits, to help increase the probability of detecting corrupted data more early. - uint buf_len0 = (buf_len - 1) & 0xFF; - uint buf_len1 = ((buf_len - 1) >> 8) & 0xFF; - uint buf_len2 = ((buf_len - 1) >> 16) & 0xFF; - if (!m_codec.encode_bits((buf_len0 ^ buf_len1) ^ buf_len2, 8)) - { - LZHAM_LOG_ERROR(7065); - return false; - } - - if (!m_codec.encode_align_to_byte()) - { - LZHAM_LOG_ERROR(7066); - return false; - } - - const uint8* pSrc = m_accel.get_ptr(m_block_start_dict_ofs); - - for (uint i = 0; i < buf_len; i++) - { - if (!m_codec.encode_bits(*pSrc++, 8)) - { - LZHAM_LOG_ERROR(7067); - return false; - } - } - - if (!m_codec.stop_encoding(true)) - { - LZHAM_LOG_ERROR(7068); - return false; - } - - //used_raw_block = true; - emit_reset_update_rate_command = false; - } - - { - scoped_perf_section append_timer("append"); - - if (m_comp_buf.empty()) - { - m_comp_buf.swap(m_codec.get_encoding_buf()); - } - else - { - if (!m_comp_buf.append(m_codec.get_encoding_buf())) - { - LZHAM_LOG_ERROR(7069); - return false; - } - } - } - -#if LZHAM_UPDATE_STATS - LZHAM_VERIFY(m_stats.m_total_bytes == m_src_size); - if (emit_reset_update_rate_command) - m_stats.m_total_update_rate_resets++; -#endif - - m_block_index++; - - return true; - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,503 +0,0 @@ -// File: lzham_lzcomp_internal.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham_match_accel.h" -#include "lzham_symbol_codec.h" -#include "lzham_lzbase.h" - -namespace lzham -{ - typedef lzham::vector byte_vec; - - const uint cMaxParseGraphNodes = 3072; - const uint cMaxParseThreads = 8; - - const uint cMaxParseNodeStates = LZHAM_EXTREME_PARSING_MAX_BEST_ARRIVALS_MAX; - const uint cDefaultMaxParseNodeStates = 4; - - enum compression_level - { - cCompressionLevelFastest, - cCompressionLevelFaster, - cCompressionLevelDefault, - cCompressionLevelBetter, - cCompressionLevelUber, - - cCompressionLevelCount - }; - - struct comp_settings - { - uint m_fast_bytes; - uint m_match_accel_max_matches_per_probe; - uint m_match_accel_max_probes; - }; - - class lzcompressor : public CLZBase - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(lzcompressor); - - public: - lzcompressor(lzham_malloc_context malloc_context); - - struct init_params - { - enum - { - cMinDictSizeLog2 = CLZBase::cMinDictSizeLog2, - cMaxDictSizeLog2 = CLZBase::cMaxDictSizeLog2, - cDefaultBlockSize = 1024U*512U - }; - - init_params() : - m_pTask_pool(NULL), - m_max_helper_threads(0), - m_compression_level(cCompressionLevelDefault), - m_dict_size_log2(22), - m_block_size(cDefaultBlockSize), - m_lzham_compress_flags(0), - m_pSeed_bytes(0), - m_num_seed_bytes(0), - m_table_max_update_interval(0), - m_table_update_interval_slow_rate(0), - m_extreme_parsing_max_best_arrivals(cDefaultMaxParseNodeStates), - m_fast_bytes_override(0) - { - } - - task_pool* m_pTask_pool; - uint m_max_helper_threads; - - compression_level m_compression_level; - uint m_dict_size_log2; - - uint m_block_size; - - uint m_lzham_compress_flags; - - const void *m_pSeed_bytes; - uint m_num_seed_bytes; - - uint m_table_max_update_interval; - uint m_table_update_interval_slow_rate; - - uint m_extreme_parsing_max_best_arrivals; - uint m_fast_bytes_override; - }; - - bool init(const init_params& params); - void clear(); - - // sync, or sync+dictionary flush - bool flush(lzham_flush_t flush_type); - - bool reset(); - - bool put_bytes(const void* pBuf, uint buf_len); - - const byte_vec& get_compressed_data() const { return m_comp_buf; } - byte_vec& get_compressed_data() { return m_comp_buf; } - - uint32 get_src_adler32() const { return m_src_adler32; } - - private: - lzham_malloc_context m_malloc_context; - - class state; - - enum - { - cLitComplexity = 1, - cRep0Complexity = 2, - cRep3Complexity = 5, - - cLongMatchComplexity = 6, - cLongMatchComplexityLenThresh = 9, - - cShortMatchComplexity = 7 - }; - - struct lzdecision - { - int m_pos; // dict position where decision was evaluated - int m_len; // 0 if literal, 1+ if match - int m_dist; // <0 if match rep, else >=1 is match dist - - inline lzdecision() { } - inline lzdecision(int pos, int len, int dist) : m_pos(pos), m_len(len), m_dist(dist) { } - - inline void init(int pos, int len, int dist) { m_pos = pos; m_len = len; m_dist = dist; } - - inline bool is_lit() const { return !m_len; } - inline bool is_match() const { return m_len > 0; } // may be a rep or full match - inline bool is_full_match() const { return (m_len > 0) && (m_dist >= 1); } - inline uint get_len() const { return math::maximum(m_len, 1); } - inline bool is_rep() const { return m_dist < 0; } - inline bool is_rep0() const { return m_dist == -1; } - - uint get_match_dist(const state& s) const; - - inline uint get_complexity() const - { - if (is_lit()) - return cLitComplexity; - else if (is_rep()) - { - LZHAM_ASSUME(cRep0Complexity == 2); - return 1 + -m_dist; // 2, 3, 4, or 5 - } - else if (get_len() >= cLongMatchComplexityLenThresh) - return cLongMatchComplexity; - else - return cShortMatchComplexity; - } - - inline uint get_min_codable_len() const - { - if (is_lit() || is_rep0()) - return 1; - else - return CLZBase::cMinMatchLen; - } - }; - - struct lzpriced_decision : lzdecision - { - lzpriced_decision() { } - - inline lzpriced_decision(int pos, int len, int dist) : lzdecision(pos, len, dist) { } - inline lzpriced_decision(int pos, int len, int dist, bit_cost_t cost) : lzdecision(pos, len, dist), m_cost(cost) { } - - inline void init(int pos, int len, int dist, bit_cost_t cost) { lzdecision::init(pos, len, dist); m_cost = cost; } - - inline bit_cost_t get_cost() const { return m_cost; } - - bit_cost_t m_cost; - }; - - struct state_base - { - uint m_cur_ofs; - uint m_cur_state; - uint m_match_hist[CLZBase::cMatchHistSize]; - - inline bool operator== (const state_base &rhs) const - { - if (m_cur_state != rhs.m_cur_state) - return false; - for (uint i = 0; i < CLZBase::cMatchHistSize; i++) - if (m_match_hist[i] != rhs.m_match_hist[i]) - return false; - return true; - } - - void partial_advance(const lzdecision& lzdec); - - inline void save_partial_state(state_base& dst) const - { - dst.m_cur_ofs = m_cur_ofs; - dst.m_cur_state = m_cur_state; - memcpy(dst.m_match_hist, m_match_hist, sizeof(m_match_hist)); - } - - inline void restore_partial_state(const state_base& src) - { - m_cur_ofs = src.m_cur_ofs; - m_cur_state = src.m_cur_state; - memcpy(m_match_hist, src.m_match_hist, sizeof(m_match_hist)); - } - }; - - class state : public state_base - { - public: - state(lzham_malloc_context malloc_context = NULL); - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - void set_malloc_context(lzham_malloc_context context) - { - m_malloc_context = context; - - m_lit_table.set_malloc_context(m_malloc_context); - m_delta_lit_table.set_malloc_context(m_malloc_context); - m_main_table.set_malloc_context(m_malloc_context); - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].set_malloc_context(m_malloc_context); - m_large_len_table[i].set_malloc_context(m_malloc_context); - } - m_dist_lsb_table.set_malloc_context(m_malloc_context); - } - - void clear(); - - bool init(CLZBase& lzbase, uint table_max_update_interval, uint table_update_interval_slow_rate); - void reset(); - - bit_cost_t get_cost(CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec) const; - bit_cost_t get_len2_match_cost(CLZBase& lzbase, uint dict_pos, uint len2_match_dist, uint is_match_model_index); - bit_cost_t get_lit_cost(CLZBase& lzbase, const search_accelerator& dict, uint dict_pos, uint lit_pred0, uint is_match_model_index) const; - - // Returns actual cost. - void get_rep_match_costs(uint dict_pos, bit_cost_t *pBitcosts, uint match_hist_index, int min_len, int max_len, uint is_match_model_index) const; - void get_full_match_costs(CLZBase& lzbase, uint dict_pos, bit_cost_t *pBitcosts, uint match_dist, int min_len, int max_len, uint is_match_model_index) const; - - bit_cost_t update_stats(CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec); - - bool advance(CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec); - bool encode(symbol_codec& codec, CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec); - - void print(symbol_codec& codec, CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec); - - bool encode_eob(symbol_codec& codec, const search_accelerator& dict, uint dict_pos); - bool encode_reset_state_partial(symbol_codec& codec, const search_accelerator& dict, uint dict_pos); - - void update_match_hist(uint match_dist); - int find_match_dist(uint match_hist) const; - - void reset_state_partial(); - void start_of_block(const search_accelerator& dict, uint cur_ofs, uint block_index); - - void reset_update_rate(); - void reset_tables(); - - uint get_pred_char(const search_accelerator& dict, int pos, int backward_ofs) const; - - inline bool will_reference_last_match(const lzdecision& lzdec) const - { - return (!lzdec.is_match()) && (m_cur_state >= CLZBase::cNumLitStates); - } - - lzham_malloc_context m_malloc_context; - - uint m_block_start_dict_ofs; - - adaptive_bit_model m_is_match_model[CLZBase::cNumStates]; - - adaptive_bit_model m_is_rep_model[CLZBase::cNumStates]; - adaptive_bit_model m_is_rep0_model[CLZBase::cNumStates]; - adaptive_bit_model m_is_rep0_single_byte_model[CLZBase::cNumStates]; - adaptive_bit_model m_is_rep1_model[CLZBase::cNumStates]; - adaptive_bit_model m_is_rep2_model[CLZBase::cNumStates]; - - quasi_adaptive_huffman_data_model m_lit_table; - quasi_adaptive_huffman_data_model m_delta_lit_table; - - quasi_adaptive_huffman_data_model m_main_table; - quasi_adaptive_huffman_data_model m_rep_len_table[2]; - quasi_adaptive_huffman_data_model m_large_len_table[2]; - quasi_adaptive_huffman_data_model m_dist_lsb_table; - }; - - class tracked_stat - { - public: - tracked_stat() { clear(); } - - void clear() { m_num = 0; m_total = 0.0f; m_total2 = 0.0f; m_min_val = 9e+99; m_max_val = -9e+99; } - - void update(double val) { m_num++; m_total += val; m_total2 += val * val; m_min_val = LZHAM_MIN(m_min_val, val); m_max_val = LZHAM_MAX(m_max_val, val); } - - tracked_stat &operator += (double val) { update(val); return *this; } - operator double() const { return m_total; } - - uint64 get_number_of_values() { return m_num; } - uint32 get_number_of_values32() { return static_cast(LZHAM_MIN(UINT_MAX, m_num)); } - double get_total() const { return m_total; } - double get_average() const { return m_num ? m_total / m_num : 0.0f; }; - double get_std_dev() const { return m_num ? sqrt( m_num * m_total2 - m_total * m_total ) / m_num: 0.0f; } - double get_min_val() const { return m_num ? m_min_val : 0.0f; } - double get_max_val() const { return m_num ? m_max_val : 0.0f; } - - private: - uint64 m_num; - double m_total; - double m_total2; - double m_min_val; - double m_max_val; - }; - - struct coding_stats - { - coding_stats() { clear(); } - - void clear(); - - void update(const lzdecision& lzdec, const state& cur_state, const search_accelerator& dict, bit_cost_t cost); - void print(); - - uint m_total_bytes; - uint m_total_contexts; - double m_total_cost; - - tracked_stat m_context_stats; - - double m_total_match_bits_cost; - double m_worst_match_bits_cost; - double m_total_is_match0_bits_cost; - double m_total_is_match1_bits_cost; - - uint m_total_truncated_matches; - uint m_match_truncation_len_hist[CLZBase::cMaxMatchLen + 1]; - uint m_match_truncation_hist[CLZBase::cMaxMatchLen + 1]; - uint m_match_type_truncation_hist[CLZBase::cNumStates][5]; - uint m_match_type_was_not_truncated_hist[CLZBase::cNumStates][5]; - - uint m_total_nonmatches; - uint m_total_matches; - - tracked_stat m_lit_stats; - tracked_stat m_delta_lit_stats; - - tracked_stat m_rep_stats[CLZBase::cMatchHistSize]; - tracked_stat m_rep0_len1_stats; - tracked_stat m_rep0_len2_plus_stats; - - tracked_stat m_full_match_stats[cMaxMatchLen + 1]; - - uint m_total_far_len2_matches; - uint m_total_near_len2_matches; - - uint m_total_update_rate_resets; - - uint m_max_len2_dist; - }; - - init_params m_params; - comp_settings m_settings; - - int64 m_src_size; - uint32 m_src_adler32; - - search_accelerator m_accel; - - symbol_codec m_codec; - - coding_stats m_stats; - - byte_vec m_block_buf; - byte_vec m_comp_buf; - - uint m_step; - - uint m_block_start_dict_ofs; - - uint m_block_index; - - bool m_finished; - bool m_use_task_pool; - bool m_use_extreme_parsing; - - struct node_state - { - LZHAM_FORCE_INLINE void clear() - { - m_total_cost = cBitCostMax; //math::cNearlyInfinite; - m_total_complexity = UINT_MAX; - } - - // the lzdecision that led from parent to this node_state - lzdecision m_lzdec; - - // This is either the state of the parent node (optimal parsing), or the state of the child node (extreme parsing). - state::state_base m_saved_state; - - // Total cost to arrive at this node state. - bit_cost_t m_total_cost; - uint m_total_complexity; - - // Parent node index. - int16 m_parent_index; - - // Parent node state index (only valid when extreme parsing). - int8 m_parent_state_index; - }; - - struct node - { - LZHAM_FORCE_INLINE void clear() - { - m_num_node_states = 0; - } - - uint m_num_node_states; - - node_state m_node_states[cMaxParseNodeStates]; - - void add_state(int parent_index, int parent_state_index, const lzdecision &lzdec, const state &parent_state, bit_cost_t total_cost, uint total_complexity, uint max_parse_node_states); - }; - - state m_start_of_block_state; // state at start of block - - state m_state; // main thread's current coding state - - struct raw_parse_thread_state - { - uint m_start_ofs; - uint m_bytes_to_match; - - state m_state; - state *m_pState; - - node m_nodes[cMaxParseGraphNodes + 1]; - - lzham::vector m_best_decisions; - bool m_emit_decisions_backwards; - - lzham::vector m_temp_decisions; - - uint m_max_parse_node_states; - uint m_max_greedy_decisions; - uint m_greedy_parse_total_bytes_coded; - - uint m_parse_early_out_thresh; - uint m_bytes_actually_parsed; - - bool m_greedy_parse_gave_up; - - bool m_issue_reset_state_partial; - bool m_failed; - bool m_use_semaphore; - - semaphore m_finished; - - bool init(lzcompressor& lzcomp, const lzcompressor::init_params ¶ms); - - void set_malloc_context(lzham_malloc_context malloc_context) - { - m_state.set_malloc_context(malloc_context); - m_best_decisions.set_malloc_context(malloc_context); - m_temp_decisions.set_malloc_context(malloc_context); - } - }; - - struct parse_thread_state : raw_parse_thread_state - { - uint8 m_unused_alignment_array[128 - (sizeof(raw_parse_thread_state) & 127)]; - }; - - uint m_fast_bytes; - - uint m_num_parse_threads; - parse_thread_state m_parse_thread_state[cMaxParseThreads + 1]; // +1 extra for the greedy parser thread (only used for delta compression) - - bool send_zlib_header(); - bool init_seed_bytes(); - bool send_final_block(); - bool send_configuration(); - bool extreme_parse(parse_thread_state &parse_state); - bool optimal_parse(parse_thread_state &parse_state); - int enumerate_lz_decisions(uint ofs, const state& cur_state, lzham::vector& decisions, uint min_match_len, uint max_match_len); - bool greedy_parse(parse_thread_state &parse_state); - void parse_job_callback(uint64 data, void* pData_ptr); - bool compress_block(const void* pBuf, uint buf_len); - bool compress_block_internal(const void* pBuf, uint buf_len); - bool code_decision(lzdecision lzdec, uint& cur_ofs, uint& bytes_to_match); - bool send_sync_block(lzham_flush_t flush_type); - }; - -} // namespace lzham - - - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1684 +0,0 @@ -// File: lzham_lzcomp_state.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_lzcomp_internal.h" - -namespace lzham -{ - static uint get_huge_match_code_len(uint len) - { - LZHAM_ASSERT((len > CLZBase::cMaxMatchLen) && (len <= CLZBase::cMaxHugeMatchLen)); - len -= (CLZBase::cMaxMatchLen + 1); - - if (len < 256) - return 1 + 8; - else if (len < (256 + 1024)) - return 2 + 10; - else if (len < (256 + 1024 + 4096)) - return 3 + 12; - else - return 3 + 16; - } - - static uint get_huge_match_code_bits(uint len) - { - LZHAM_ASSERT((len > CLZBase::cMaxMatchLen) && (len <= CLZBase::cMaxHugeMatchLen)); - len -= (CLZBase::cMaxMatchLen + 1); - - uint c; - if (len < 256) - c = len; - else if (len < (256 + 1024)) - { - uint r = (len - 256); - LZHAM_ASSERT(r <= 1023); - c = r | (2 << 10); - } - else if (len < (256 + 1024 + 4096)) - { - uint r = (len - (256 + 1024)); - LZHAM_ASSERT(r <= 4095); - c = r | (6 << 12); - } - else - { - uint r = (len - (256 + 1024 + 4096)); - LZHAM_ASSERT(r <= 65535); - c = r | (7 << 16); - } - - return c; - } - - uint lzcompressor::lzdecision::get_match_dist(const state& cur_state) const - { - if (!is_match()) - return 0; - else if (is_rep()) - { - int index = -m_dist - 1; - LZHAM_ASSERT(index < CLZBase::cMatchHistSize); - return cur_state.m_match_hist[index]; - } - else - return m_dist; - } - - lzcompressor::state::state(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_lit_table(malloc_context), - m_delta_lit_table(malloc_context), - m_main_table(malloc_context), - m_dist_lsb_table(malloc_context) - { - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].set_malloc_context(malloc_context); - m_large_len_table[i].set_malloc_context(malloc_context); - } - - m_cur_ofs = 0; - m_cur_state = 0; - m_block_start_dict_ofs = 0; - - m_match_hist[0] = 1; - m_match_hist[1] = 1; - m_match_hist[2] = 1; - m_match_hist[3] = 1; - } - - void lzcompressor::state::clear() - { - m_cur_ofs = 0; - m_cur_state = 0; - m_block_start_dict_ofs = 0; - - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].clear(); - m_large_len_table[i].clear(); - } - m_main_table.clear(); - m_dist_lsb_table.clear(); - - m_lit_table.clear(); - m_delta_lit_table.clear(); - - m_match_hist[0] = 1; - m_match_hist[1] = 1; - m_match_hist[2] = 1; - m_match_hist[3] = 1; - } - - void lzcompressor::state::reset() - { - m_cur_ofs = 0; - m_cur_state = 0; - m_block_start_dict_ofs = 0; - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_match_model); i++) - m_is_match_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep_model); i++) - m_is_rep_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep0_model); i++) - m_is_rep0_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep0_single_byte_model); i++) - m_is_rep0_single_byte_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep1_model); i++) - m_is_rep1_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep2_model); i++) - m_is_rep2_model[i].clear(); - - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].reset(); - m_large_len_table[i].reset(); - } - m_main_table.reset(); - m_dist_lsb_table.reset(); - - m_lit_table.reset(); - m_delta_lit_table.reset(); - - m_match_hist[0] = 1; - m_match_hist[1] = 1; - m_match_hist[2] = 1; - m_match_hist[3] = 1; - } - - bool lzcompressor::state::init(CLZBase& lzbase, uint table_max_update_interval, uint table_update_interval_slow_rate) - { - m_cur_ofs = 0; - m_cur_state = 0; - - if (!m_rep_len_table[0].init2(m_malloc_context, true, CLZBase::cNumHugeMatchCodes + (CLZBase::cMaxMatchLen - CLZBase::cMinMatchLen + 1), table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8000); - return false; - } - if (!m_rep_len_table[1].assign(m_rep_len_table[0])) - { - LZHAM_LOG_ERROR(8001); - return false; - } - - if (!m_large_len_table[0].init2(m_malloc_context, true, CLZBase::cNumHugeMatchCodes + CLZBase::cLZXNumSecondaryLengths, table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8002); - return false; - } - if (!m_large_len_table[1].assign(m_large_len_table[0])) - { - LZHAM_LOG_ERROR(8003); - return false; - } - - if (!m_main_table.init2(m_malloc_context, true, CLZBase::cLZXNumSpecialLengths + (lzbase.m_num_lzx_slots - CLZBase::cLZXLowestUsableMatchSlot) * 8, table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8004); - return false; - } - if (!m_dist_lsb_table.init2(m_malloc_context, true, 16, table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8005); - return false; - } - - if (!m_lit_table.init2(m_malloc_context, true, 256, table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8006); - return false; - } - - if (!m_delta_lit_table.init2(m_malloc_context, true, 256, table_max_update_interval, table_update_interval_slow_rate, NULL)) - { - LZHAM_LOG_ERROR(8007); - return false; - } - - m_match_hist[0] = 1; - m_match_hist[1] = 1; - m_match_hist[2] = 1; - m_match_hist[3] = 1; - - return true; - } - - void lzcompressor::state_base::partial_advance(const lzdecision& lzdec) - { - if (lzdec.m_len == 0) - { - if (m_cur_state < 4) m_cur_state = 0; else if (m_cur_state < 10) m_cur_state -= 3; else m_cur_state -= 6; - } - else - { - if (lzdec.m_dist < 0) - { - int match_hist_index = -lzdec.m_dist - 1; - - if (!match_hist_index) - { - if (lzdec.m_len == 1) - { - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 9 : 11; - } - else - { - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - if (match_hist_index == 1) - { - std::swap(m_match_hist[0], m_match_hist[1]); - } - else if (match_hist_index == 2) - { - int dist = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - else - { - LZHAM_ASSERT(match_hist_index == 3); - - int dist = m_match_hist[3]; - m_match_hist[3] = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - // full - LZHAM_ASSUME(CLZBase::cMatchHistSize == 4); - m_match_hist[3] = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = lzdec.m_dist; - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? CLZBase::cNumLitStates : CLZBase::cNumLitStates + 3; - } - } - - m_cur_ofs = lzdec.m_pos + lzdec.get_len(); - } - - uint lzcompressor::state::get_pred_char(const search_accelerator& dict, int pos, int backward_ofs) const - { - LZHAM_ASSERT(pos >= (int)m_block_start_dict_ofs); - int limit = pos - m_block_start_dict_ofs; - if (backward_ofs > limit) - return 0; - return dict[pos - backward_ofs]; - } - - bit_cost_t lzcompressor::state::get_cost(CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec) const - { - //const uint lit_pred0 = get_pred_char(dict, lzdec.m_pos, 1); - - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - LZHAM_ASSERT(is_match_model_index < LZHAM_ARRAY_SIZE(m_is_match_model)); - bit_cost_t cost = m_is_match_model[is_match_model_index].get_cost(lzdec.is_match()); - - if (!lzdec.is_match()) - { - const uint lit = dict[lzdec.m_pos]; - - if (m_cur_state < CLZBase::cNumLitStates) - { - // literal - cost += m_lit_table.get_cost(lit); - } - else - { - // delta literal - const uint rep_lit0 = dict[(lzdec.m_pos - m_match_hist[0]) & dict.m_max_dict_size_mask]; - - uint delta_lit = rep_lit0 ^ lit; - - cost += m_delta_lit_table.get_cost(delta_lit); - } - } - else - { - // match - if (lzdec.m_dist < 0) - { - // rep match - cost += m_is_rep_model[m_cur_state].get_cost(1); - - int match_hist_index = -lzdec.m_dist - 1; - - if (!match_hist_index) - { - // rep0 match - cost += m_is_rep0_model[m_cur_state].get_cost(1); - - if (lzdec.m_len == 1) - { - // single byte rep0 - cost += m_is_rep0_single_byte_model[m_cur_state].get_cost(1); - } - else - { - // normal rep0 - cost += m_is_rep0_single_byte_model[m_cur_state].get_cost(0); - - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - cost += get_huge_match_code_len(lzdec.m_len) + m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen); - } - else - { - cost += m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost(lzdec.m_len - CLZBase::cMinMatchLen); - } - } - } - else - { - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - cost += get_huge_match_code_len(lzdec.m_len) + m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen); - } - else - { - cost += m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost(lzdec.m_len - CLZBase::cMinMatchLen); - } - - // rep1-rep3 match - cost += m_is_rep0_model[m_cur_state].get_cost(0); - - if (match_hist_index == 1) - { - // rep1 - cost += m_is_rep1_model[m_cur_state].get_cost(1); - } - else - { - cost += m_is_rep1_model[m_cur_state].get_cost(0); - - if (match_hist_index == 2) - { - // rep2 - cost += m_is_rep2_model[m_cur_state].get_cost(1); - } - else - { - LZHAM_ASSERT(match_hist_index == 3); - // rep3 - cost += m_is_rep2_model[m_cur_state].get_cost(0); - } - } - } - } - else - { - cost += m_is_rep_model[m_cur_state].get_cost(0); - - LZHAM_ASSERT(lzdec.m_len >= CLZBase::cMinMatchLen); - - // full match - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(lzdec.m_dist, match_slot, match_extra); - - uint match_low_sym = 0; - if (lzdec.m_len >= 9) - { - match_low_sym = 7; - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - cost += get_huge_match_code_len(lzdec.m_len) + m_large_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost((CLZBase::cMaxMatchLen + 1) - 9); - } - else - { - cost += m_large_len_table[m_cur_state >= CLZBase::cNumLitStates].get_cost(lzdec.m_len - 9); - } - } - else - match_low_sym = lzdec.m_len - 2; - - uint match_high_sym = 0; - - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - uint main_sym = match_low_sym | (match_high_sym << 3); - - cost += m_main_table.get_cost(CLZBase::cLZXNumSpecialLengths + main_sym); - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - if (num_extra_bits < 3) - cost += convert_to_scaled_bitcost(num_extra_bits); - else - { - if (num_extra_bits > 4) - cost += convert_to_scaled_bitcost(num_extra_bits - 4); - - cost += m_dist_lsb_table.get_cost(match_extra & 15); - } - } - } - - return cost; - } - - bit_cost_t lzcompressor::state::get_len2_match_cost(CLZBase& lzbase, uint dict_pos, uint len2_match_dist, uint is_match_model_index) - { - LZHAM_NOTE_UNUSED(dict_pos); - - bit_cost_t cost = m_is_match_model[is_match_model_index].get_cost(1); - - cost += m_is_rep_model[m_cur_state].get_cost(0); - - // full match - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(len2_match_dist, match_slot, match_extra); - - const uint match_len = 2; - uint match_low_sym = match_len - 2; - - uint match_high_sym = 0; - - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - uint main_sym = match_low_sym | (match_high_sym << 3); - - cost += m_main_table.get_cost(CLZBase::cLZXNumSpecialLengths + main_sym); - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - if (num_extra_bits < 3) - cost += convert_to_scaled_bitcost(num_extra_bits); - else - { - if (num_extra_bits > 4) - cost += convert_to_scaled_bitcost(num_extra_bits - 4); - - cost += m_dist_lsb_table.get_cost(match_extra & 15); - } - - return cost; - } - - bit_cost_t lzcompressor::state::get_lit_cost(CLZBase& lzbase, const search_accelerator& dict, uint dict_pos, uint lit_pred0, uint is_match_model_index) const - { - LZHAM_NOTE_UNUSED(lzbase); - LZHAM_NOTE_UNUSED(lit_pred0); - - bit_cost_t cost = m_is_match_model[is_match_model_index].get_cost(0); - - const uint lit = dict[dict_pos]; - - if (m_cur_state < CLZBase::cNumLitStates) - { - // literal - cost += m_lit_table.get_cost(lit); - } - else - { - // delta literal - const uint rep_lit0 = dict[(dict_pos - m_match_hist[0]) & dict.m_max_dict_size_mask]; - - uint delta_lit = rep_lit0 ^ lit; - - cost += m_delta_lit_table.get_cost(delta_lit); - } - - return cost; - } - - void lzcompressor::state::get_rep_match_costs(uint dict_pos, bit_cost_t *pBitcosts, uint match_hist_index, int min_len, int max_len, uint is_match_model_index) const - { - LZHAM_NOTE_UNUSED(dict_pos); - // match - const quasi_adaptive_huffman_data_model &rep_len_table = m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates]; - - bit_cost_t base_cost = m_is_match_model[is_match_model_index].get_cost(1); - - base_cost += m_is_rep_model[m_cur_state].get_cost(1); - - if (!match_hist_index) - { - // rep0 match - base_cost += m_is_rep0_model[m_cur_state].get_cost(1); - } - else - { - // rep1-rep3 matches - base_cost += m_is_rep0_model[m_cur_state].get_cost(0); - - if (match_hist_index == 1) - { - // rep1 - base_cost += m_is_rep1_model[m_cur_state].get_cost(1); - } - else - { - base_cost += m_is_rep1_model[m_cur_state].get_cost(0); - - if (match_hist_index == 2) - { - // rep2 - base_cost += m_is_rep2_model[m_cur_state].get_cost(1); - } - else - { - // rep3 - base_cost += m_is_rep2_model[m_cur_state].get_cost(0); - } - } - } - - // rep match - if (!match_hist_index) - { - if (min_len == 1) - { - // single byte rep0 - pBitcosts[1] = base_cost + m_is_rep0_single_byte_model[m_cur_state].get_cost(1); - min_len++; - } - - bit_cost_t rep0_match_base_cost = base_cost + m_is_rep0_single_byte_model[m_cur_state].get_cost(0); - for (int match_len = min_len; match_len <= max_len; match_len++) - { - // normal rep0 - if (match_len > CLZBase::cMaxMatchLen) - { - pBitcosts[match_len] = get_huge_match_code_len(match_len) + rep0_match_base_cost + rep_len_table.get_cost((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen); - } - else - { - pBitcosts[match_len] = rep0_match_base_cost + rep_len_table.get_cost(match_len - CLZBase::cMinMatchLen); - } - } - } - else - { - for (int match_len = min_len; match_len <= max_len; match_len++) - { - if (match_len > CLZBase::cMaxMatchLen) - { - pBitcosts[match_len] = get_huge_match_code_len(match_len) + base_cost + rep_len_table.get_cost((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen); - } - else - { - pBitcosts[match_len] = base_cost + rep_len_table.get_cost(match_len - CLZBase::cMinMatchLen); - } - } - } - } - - void lzcompressor::state::get_full_match_costs(CLZBase& lzbase, uint dict_pos, bit_cost_t *pBitcosts, uint match_dist, int min_len, int max_len, uint is_match_model_index) const - { - LZHAM_NOTE_UNUSED(dict_pos); - LZHAM_ASSERT(min_len >= CLZBase::cMinMatchLen); - - bit_cost_t cost = m_is_match_model[is_match_model_index].get_cost(1); - - cost += m_is_rep_model[m_cur_state].get_cost(0); - - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(match_dist, match_slot, match_extra); - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - - if (num_extra_bits < 3) - cost += convert_to_scaled_bitcost(num_extra_bits); - else - { - if (num_extra_bits > 4) - cost += convert_to_scaled_bitcost(num_extra_bits - 4); - - cost += m_dist_lsb_table.get_cost(match_extra & 15); - } - - uint match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - const quasi_adaptive_huffman_data_model &large_len_table = m_large_len_table[m_cur_state >= CLZBase::cNumLitStates]; - - for (int match_len = min_len; match_len <= max_len; match_len++) - { - bit_cost_t len_cost = cost; - - uint match_low_sym = 0; - if (match_len >= 9) - { - match_low_sym = 7; - if (match_len > CLZBase::cMaxMatchLen) - { - len_cost += get_huge_match_code_len(match_len) + large_len_table.get_cost((CLZBase::cMaxMatchLen + 1) - 9); - } - else - { - len_cost += large_len_table.get_cost(match_len - 9); - } - } - else - match_low_sym = match_len - 2; - - uint main_sym = match_low_sym | (match_high_sym << 3); - - pBitcosts[match_len] = len_cost + m_main_table.get_cost(CLZBase::cLZXNumSpecialLengths + main_sym); - } - } - - bool lzcompressor::state::advance(CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec) - { - //const uint lit_pred0 = get_pred_char(dict, lzdec.m_pos, 1); - - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - m_is_match_model[is_match_model_index].update(lzdec.is_match()); - - if (!lzdec.is_match()) - { - const uint lit = dict[lzdec.m_pos]; - - if (m_cur_state < CLZBase::cNumLitStates) - { - // literal - if (!m_lit_table.update_sym(lit)) - { - LZHAM_LOG_ERROR(8008); - return false; - } - } - else - { - // delta literal - const uint rep_lit0 = dict[(lzdec.m_pos - m_match_hist[0]) & dict.m_max_dict_size_mask]; - - uint delta_lit = rep_lit0 ^ lit; - - if (!m_delta_lit_table.update_sym(delta_lit)) - { - LZHAM_LOG_ERROR(8009); - return false; - } - } - - if (m_cur_state < 4) m_cur_state = 0; else if (m_cur_state < 10) m_cur_state -= 3; else m_cur_state -= 6; - } - else - { - // match - if (lzdec.m_dist < 0) - { - // rep match - m_is_rep_model[m_cur_state].update(1); - - int match_hist_index = -lzdec.m_dist - 1; - - if (!match_hist_index) - { - // rep0 match - m_is_rep0_model[m_cur_state].update(1); - - if (lzdec.m_len == 1) - { - // single byte rep0 - m_is_rep0_single_byte_model[m_cur_state].update(1); - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 9 : 11; - } - else - { - // normal rep0 - m_is_rep0_single_byte_model[m_cur_state].update(0); - - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen)) - { - LZHAM_LOG_ERROR(8010); - return false; - } - } - else - { - if (!m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym(lzdec.m_len - CLZBase::cMinMatchLen)) - { - LZHAM_LOG_ERROR(8011); - return false; - } - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - // rep1-rep3 match - m_is_rep0_model[m_cur_state].update(0); - - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen)) - { - LZHAM_LOG_ERROR(8012); - return false; - } - } - else - { - if (!m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym(lzdec.m_len - CLZBase::cMinMatchLen)) - { - LZHAM_LOG_ERROR(8013); - return false; - } - } - - if (match_hist_index == 1) - { - // rep1 - m_is_rep1_model[m_cur_state].update(1); - - std::swap(m_match_hist[0], m_match_hist[1]); - } - else - { - m_is_rep1_model[m_cur_state].update(0); - - if (match_hist_index == 2) - { - // rep2 - m_is_rep2_model[m_cur_state].update(1); - - int dist = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - else - { - // rep3 - m_is_rep2_model[m_cur_state].update(0); - - int dist = m_match_hist[3]; - m_match_hist[3] = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - m_is_rep_model[m_cur_state].update(0); - - LZHAM_ASSERT(lzdec.m_len >= CLZBase::cMinMatchLen); - - // full match - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(lzdec.m_dist, match_slot, match_extra); - - uint match_low_sym = 0; - int large_len_sym = -1; - if (lzdec.m_len >= 9) - { - match_low_sym = 7; - - large_len_sym = lzdec.m_len - 9; - } - else - match_low_sym = lzdec.m_len - 2; - - uint match_high_sym = 0; - - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - uint main_sym = match_low_sym | (match_high_sym << 3); - - if (!m_main_table.update_sym(CLZBase::cLZXNumSpecialLengths + main_sym)) - { - LZHAM_LOG_ERROR(8014); - return false; - } - - if (large_len_sym >= 0) - { - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!m_large_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym((CLZBase::cMaxMatchLen + 1) - 9)) - { - LZHAM_LOG_ERROR(8015); - return false; - } - } - else - { - if (!m_large_len_table[m_cur_state >= CLZBase::cNumLitStates].update_sym(large_len_sym)) - { - LZHAM_LOG_ERROR(8016); - return false; - } - } - } - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - if (num_extra_bits >= 3) - { - if (!m_dist_lsb_table.update_sym(match_extra & 15)) - { - LZHAM_LOG_ERROR(8017); - return false; - } - } - - update_match_hist(lzdec.m_dist); - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? CLZBase::cNumLitStates : CLZBase::cNumLitStates + 3; - } - } - - m_cur_ofs = lzdec.m_pos + lzdec.get_len(); - return true; - } - - bool lzcompressor::state::encode(symbol_codec& codec, CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec) - { - //const uint lit_pred0 = get_pred_char(dict, lzdec.m_pos, 1); - - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - if (!codec.encode(lzdec.is_match(), m_is_match_model[is_match_model_index])) - { - LZHAM_LOG_ERROR(8018); - return false; - } - - if (!lzdec.is_match()) - { - const uint lit = dict[lzdec.m_pos]; - -#ifdef LZHAM_LZDEBUG - if (!codec.encode_bits(lit, 8)) - { - LZHAM_LOG_ERROR(8019); - return false; - } -#endif - - if (m_cur_state < CLZBase::cNumLitStates) - { - // literal - if (!codec.encode(lit, m_lit_table)) - { - LZHAM_LOG_ERROR(8020); - return false; - } - } - else - { - // delta literal - const uint rep_lit0 = dict[(lzdec.m_pos - m_match_hist[0]) & dict.m_max_dict_size_mask]; - - uint delta_lit = rep_lit0 ^ lit; - -#ifdef LZHAM_LZDEBUG - if (!codec.encode_bits(rep_lit0, 8)) - { - LZHAM_LOG_ERROR(8021); - return false; - } -#endif - - if (!codec.encode(delta_lit, m_delta_lit_table)) - { - LZHAM_LOG_ERROR(8022); - return false; - } - } - - if (m_cur_state < 4) m_cur_state = 0; else if (m_cur_state < 10) m_cur_state -= 3; else m_cur_state -= 6; - } - else - { - // match - if (lzdec.m_dist < 0) - { - // rep match - if (!codec.encode(1, m_is_rep_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8023); - return false; - } - - int match_hist_index = -lzdec.m_dist - 1; - - if (!match_hist_index) - { - // rep0 match - if (!codec.encode(1, m_is_rep0_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8024); - return false; - } - - if (lzdec.m_len == 1) - { - // single byte rep0 - if (!codec.encode(1, m_is_rep0_single_byte_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8025); - return false; - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 9 : 11; - } - else - { - // normal rep0 - if (!codec.encode(0, m_is_rep0_single_byte_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8026); - return false; - } - - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!codec.encode((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen, m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8027); - return false; - } - if (!codec.encode_bits(get_huge_match_code_bits(lzdec.m_len), get_huge_match_code_len(lzdec.m_len))) - { - LZHAM_LOG_ERROR(8028); - return false; - } - } - else - { - if (!codec.encode(lzdec.m_len - CLZBase::cMinMatchLen, m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8029); - return false; - } - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - // rep1-rep3 match - if (!codec.encode(0, m_is_rep0_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8030); - return false; - } - - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!codec.encode((CLZBase::cMaxMatchLen + 1) - CLZBase::cMinMatchLen, m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8031); - return false; - } - if (!codec.encode_bits(get_huge_match_code_bits(lzdec.m_len), get_huge_match_code_len(lzdec.m_len))) - { - LZHAM_LOG_ERROR(8032); - return false; - } - } - else - { - if (!codec.encode(lzdec.m_len - CLZBase::cMinMatchLen, m_rep_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8033); - return false; - } - } - - if (match_hist_index == 1) - { - // rep1 - if (!codec.encode(1, m_is_rep1_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8034); - return false; - } - - std::swap(m_match_hist[0], m_match_hist[1]); - } - else - { - if (!codec.encode(0, m_is_rep1_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8035); - return false; - } - - if (match_hist_index == 2) - { - // rep2 - if (!codec.encode(1, m_is_rep2_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8036); - return false; - } - - int dist = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - else - { - // rep3 - if (!codec.encode(0, m_is_rep2_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8037); - return false; - } - - int dist = m_match_hist[3]; - m_match_hist[3] = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = dist; - } - } - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? 8 : 11; - } - } - else - { - if (!codec.encode(0, m_is_rep_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8038); - return false; - } - - LZHAM_ASSERT(lzdec.m_len >= CLZBase::cMinMatchLen); - - // full match - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(lzdec.m_dist, match_slot, match_extra); - - uint match_low_sym = 0; - int large_len_sym = -1; - if (lzdec.m_len >= 9) - { - match_low_sym = 7; - - large_len_sym = lzdec.m_len - 9; - } - else - match_low_sym = lzdec.m_len - 2; - - uint match_high_sym = 0; - - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - uint main_sym = match_low_sym | (match_high_sym << 3); - - if (!codec.encode(CLZBase::cLZXNumSpecialLengths + main_sym, m_main_table)) - { - LZHAM_LOG_ERROR(8039); - return false; - } - - if (large_len_sym >= 0) - { - if (lzdec.m_len > CLZBase::cMaxMatchLen) - { - if (!codec.encode((CLZBase::cMaxMatchLen + 1) - 9, m_large_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8040); - return false; - } - if (!codec.encode_bits(get_huge_match_code_bits(lzdec.m_len), get_huge_match_code_len(lzdec.m_len))) - { - LZHAM_LOG_ERROR(8041); - return false; - } - } - else - { - if (!codec.encode(large_len_sym, m_large_len_table[m_cur_state >= CLZBase::cNumLitStates])) - { - LZHAM_LOG_ERROR(8042); - return false; - } - } - } - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - if (num_extra_bits < 3) - { - if (!codec.encode_bits(match_extra, num_extra_bits)) - { - LZHAM_LOG_ERROR(8043); - return false; - } - } - else - { - if (num_extra_bits > 4) - { - if (!codec.encode_bits((match_extra >> 4), num_extra_bits - 4)) - { - LZHAM_LOG_ERROR(8044); - return false; - } - } - - if (!codec.encode(match_extra & 15, m_dist_lsb_table)) - { - LZHAM_LOG_ERROR(8045); - return false; - } - } - - update_match_hist(lzdec.m_dist); - - m_cur_state = (m_cur_state < CLZBase::cNumLitStates) ? CLZBase::cNumLitStates : CLZBase::cNumLitStates + 3; - } - -#ifdef LZHAM_LZDEBUG - if (!codec.encode_bits(m_match_hist[0], 29)) - { - LZHAM_LOG_ERROR(8046); - return false; - } -#endif - } - - m_cur_ofs = lzdec.m_pos + lzdec.get_len(); - return true; - } - - void lzcompressor::state::print(symbol_codec& codec, CLZBase& lzbase, const search_accelerator& dict, const lzdecision& lzdec) - { - LZHAM_NOTE_UNUSED(codec), LZHAM_NOTE_UNUSED(lzbase), LZHAM_NOTE_UNUSED(dict); - - const uint lit_pred0 = get_pred_char(dict, lzdec.m_pos, 1); - - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - - printf(" pos: %u, state: %u, match_pred: %u, is_match_model_index: %u, is_match: %u, cost: %f\n", - lzdec.m_pos, - m_cur_state, - lit_pred0, is_match_model_index, lzdec.is_match(), get_cost(lzbase, dict, lzdec) / (float)cBitCostScale); - - if (!lzdec.is_match()) - { - const uint lit = dict[lzdec.m_pos]; - - if (m_cur_state < CLZBase::cNumLitStates) - { - printf("---Regular lit: %u '%c'\n", - lit, ((lit >= 32) && (lit <= 127)) ? lit : '.'); - } - else - { - // delta literal - const uint rep_lit0 = dict[(lzdec.m_pos - m_match_hist[0]) & dict.m_max_dict_size_mask]; - - uint delta_lit = rep_lit0 ^ lit; - - printf("***Delta lit: %u '%c', Mismatch: %u '%c', Delta: 0x%02X\n", - lit, ((lit >= 32) && (lit <= 127)) ? lit : '.', - rep_lit0, ((rep_lit0 >= 32) && (rep_lit0 <= 127)) ? rep_lit0 : '.', - delta_lit); - } - } - else - { - uint actual_match_len = dict.get_match_len(0, lzdec.get_match_dist(*this), CLZBase::cMaxMatchLen); - LZHAM_ASSERT(actual_match_len >= lzdec.get_len()); - - // match - if (lzdec.m_dist < 0) - { - int match_hist_index = -lzdec.m_dist - 1; - - if (!match_hist_index) - { - if (lzdec.m_len == 1) - { - printf("!!!Rep 0 len1\n"); - } - else - { - printf("!!!Rep 0 full len %u\n", lzdec.m_len); - } - } - else - { - printf("!!!Rep %u full len %u\n", match_hist_index, lzdec.m_len); - } - } - else - { - LZHAM_ASSERT(lzdec.m_len >= CLZBase::cMinMatchLen); - - // full match - uint match_slot, match_extra; - lzbase.compute_lzx_position_slot(lzdec.m_dist, match_slot, match_extra); - - uint match_low_sym = 0; LZHAM_NOTE_UNUSED(match_low_sym); - int large_len_sym = -1; LZHAM_NOTE_UNUSED(large_len_sym); - if (lzdec.m_len >= 9) - { - match_low_sym = 7; - - large_len_sym = lzdec.m_len - 9; - } - else - match_low_sym = lzdec.m_len - 2; - - uint match_high_sym = 0; LZHAM_NOTE_UNUSED(match_high_sym); - - LZHAM_ASSERT(match_slot >= CLZBase::cLZXLowestUsableMatchSlot && (match_slot < lzbase.m_num_lzx_slots)); - match_high_sym = match_slot - CLZBase::cLZXLowestUsableMatchSlot; - - //uint main_sym = match_low_sym | (match_high_sym << 3); - - uint num_extra_bits = lzbase.m_lzx_position_extra_bits[match_slot]; - printf("^^^Full match Len %u Dist %u, Slot %u, ExtraBits: %u", lzdec.m_len, lzdec.m_dist, match_slot, num_extra_bits); - - if (num_extra_bits < 3) - { - } - else - { - printf(" (Low 4 bits: %u vs. %u)", lzdec.m_dist & 15, match_extra & 15); - } - printf("\n"); - } - - if (actual_match_len > lzdec.get_len()) - { - printf(" TRUNCATED match, actual len is %u, shortened by %u\n", actual_match_len, actual_match_len - lzdec.get_len()); - } - } - } - - bool lzcompressor::state::encode_eob(symbol_codec& codec, const search_accelerator& dict, uint dict_pos) - { - LZHAM_NOTE_UNUSED(dict); - LZHAM_NOTE_UNUSED(dict_pos); - -#ifdef LZHAM_LZDEBUG - if (!codec.encode_bits(CLZBase::cLZHAMDebugSyncMarkerValue, CLZBase::cLZHAMDebugSyncMarkerBits)) - { - LZHAM_LOG_ERROR(8047); - return false; - } - if (!codec.encode_bits(1, 1)) - { - LZHAM_LOG_ERROR(8048); - return false; - } - if (!codec.encode_bits(0, 17)) - { - LZHAM_LOG_ERROR(8049); - return false; - } - if (!codec.encode_bits(m_cur_state, 4)) - { - LZHAM_LOG_ERROR(8050); - return false; - } -#endif - - //const uint match_pred = get_pred_char(dict, dict_pos, 1); - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - if (!codec.encode(1, m_is_match_model[is_match_model_index])) - { - LZHAM_LOG_ERROR(8051); - return false; - } - - // full match - if (!codec.encode(0, m_is_rep_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8052); - return false; - } - - return codec.encode(CLZBase::cLZXSpecialCodeEndOfBlockCode, m_main_table); - } - - bool lzcompressor::state::encode_reset_state_partial(symbol_codec& codec, const search_accelerator& dict, uint dict_pos) - { - LZHAM_NOTE_UNUSED(dict); - LZHAM_NOTE_UNUSED(dict_pos); - -#ifdef LZHAM_LZDEBUG - if (!codec.encode_bits(CLZBase::cLZHAMDebugSyncMarkerValue, CLZBase::cLZHAMDebugSyncMarkerBits)) - { - LZHAM_LOG_ERROR(8053); - return false; - } - if (!codec.encode_bits(1, 1)) - { - LZHAM_LOG_ERROR(8054); - return false; - } - if (!codec.encode_bits(0, 17)) - { - LZHAM_LOG_ERROR(8055); - return false; - } - if (!codec.encode_bits(m_cur_state, 4)) - { - LZHAM_LOG_ERROR(8056); - return false; - } -#endif - - //const uint match_pred = get_pred_char(dict, dict_pos, 1); - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(m_cur_state); - if (!codec.encode(1, m_is_match_model[is_match_model_index])) - { - LZHAM_LOG_ERROR(8057); - return false; - } - - // full match - if (!codec.encode(0, m_is_rep_model[m_cur_state])) - { - LZHAM_LOG_ERROR(8058); - return false; - } - - if (!codec.encode(CLZBase::cLZXSpecialCodePartialStateReset, m_main_table)) - { - LZHAM_LOG_ERROR(8059); - return false; - } - - reset_state_partial(); - return true; - } - - void lzcompressor::state::update_match_hist(uint match_dist) - { - LZHAM_ASSUME(CLZBase::cMatchHistSize == 4); - m_match_hist[3] = m_match_hist[2]; - m_match_hist[2] = m_match_hist[1]; - m_match_hist[1] = m_match_hist[0]; - m_match_hist[0] = match_dist; - } - - int lzcompressor::state::find_match_dist(uint match_dist) const - { - for (uint match_hist_index = 0; match_hist_index < CLZBase::cMatchHistSize; match_hist_index++) - if (match_dist == m_match_hist[match_hist_index]) - return match_hist_index; - - return -1; - } - - void lzcompressor::state::reset_state_partial() - { - LZHAM_ASSUME(CLZBase::cMatchHistSize == 4); - m_match_hist[0] = 1; - m_match_hist[1] = 1; - m_match_hist[2] = 1; - m_match_hist[3] = 1; - m_cur_state = 0; - } - - void lzcompressor::state::start_of_block(const search_accelerator& dict, uint cur_ofs, uint block_index) - { - LZHAM_NOTE_UNUSED(dict), LZHAM_NOTE_UNUSED(block_index); - - reset_state_partial(); - - m_cur_ofs = cur_ofs; - m_block_start_dict_ofs = cur_ofs; - } - - void lzcompressor::state::reset_update_rate() - { - m_lit_table.reset_update_rate(); - m_delta_lit_table.reset_update_rate(); - - m_main_table.reset_update_rate(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_rep_len_table); i++) - m_rep_len_table[i].reset_update_rate(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_large_len_table); i++) - m_large_len_table[i].reset_update_rate(); - - m_dist_lsb_table.reset_update_rate(); - } - - void lzcompressor::state::reset_tables() - { - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_match_model); i++) - m_is_match_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep_model); i++) - m_is_rep_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep0_model); i++) - m_is_rep0_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep0_single_byte_model); i++) - m_is_rep0_single_byte_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep1_model); i++) - m_is_rep1_model[i].clear(); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_rep2_model); i++) - m_is_rep2_model[i].clear(); - - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].reset(); - m_large_len_table[i].reset(); - } - m_main_table.reset(); - m_dist_lsb_table.reset(); - - m_lit_table.reset(); - m_delta_lit_table.reset(); - } - - void lzcompressor::coding_stats::clear() - { - m_total_bytes = 0; - m_total_contexts = 0; - m_total_match_bits_cost = 0; - m_worst_match_bits_cost = 0; - m_total_is_match0_bits_cost = 0; - m_total_is_match1_bits_cost = 0; - m_context_stats.clear(); - - m_total_nonmatches = 0; - m_total_matches = 0; - m_total_cost = 0.0f; - - m_lit_stats.clear(); - m_delta_lit_stats.clear(); - - m_rep0_len1_stats.clear(); - for (uint i = 0; i < CLZBase::cMatchHistSize; i++) - m_rep_stats[i].clear(); - m_rep0_len1_stats.clear(); - m_rep0_len2_plus_stats.clear(); - - for (uint i = 0; i <= CLZBase::cMaxMatchLen; i++) - m_full_match_stats[i].clear(); - - m_total_far_len2_matches = 0; - m_total_near_len2_matches = 0; - - m_total_truncated_matches = 0; - utils::zero_object(m_match_truncation_len_hist); - utils::zero_object(m_match_truncation_hist); - utils::zero_object(m_match_type_truncation_hist); - utils::zero_object(m_match_type_was_not_truncated_hist); - - m_total_update_rate_resets = 0; - - m_max_len2_dist = 0; - } - - void lzcompressor::coding_stats::print() - { - if (!m_total_contexts) - return; - - printf("-----------\n"); - printf("Coding statistics:\n"); - printf("Total update rate resets: %u\n", m_total_update_rate_resets); - printf("Total Bytes: %u, Total Contexts: %u, Total Cost: %f bits (%f bytes)\nContext ave cost: %f StdDev: %f Min: %f Max: %f\n", m_total_bytes, m_total_contexts, m_total_cost, m_total_cost / 8.0f, m_context_stats.get_average(), m_context_stats.get_std_dev(), m_context_stats.get_min_val(), m_context_stats.get_max_val()); - printf("Ave bytes per context: %f\n", m_total_bytes / (float)m_total_contexts); - - printf("IsMatch:\n"); - printf(" Total: %u, Cost: %f (%f bytes), Ave. Cost: %f, Worst Cost: %f\n", - m_total_contexts, m_total_match_bits_cost, m_total_match_bits_cost / 8.0f, m_total_match_bits_cost / math::maximum(1, m_total_contexts), m_worst_match_bits_cost); - - printf(" IsMatch(0): %u, Cost: %f (%f bytes), Ave. Cost: %f\n", - m_total_nonmatches, m_total_is_match0_bits_cost, m_total_is_match0_bits_cost / 8.0f, m_total_is_match0_bits_cost / math::maximum(1, m_total_nonmatches)); - - printf(" IsMatch(1): %u, Cost: %f (%f bytes), Ave. Cost: %f\n", - m_total_matches, m_total_is_match1_bits_cost, m_total_is_match1_bits_cost / 8.0f, m_total_is_match1_bits_cost / math::maximum(1, m_total_matches)); - - printf("Literal stats:\n"); - printf(" Count: %u, Cost: %f (%f bytes), Ave: %f StdDev: %f Min: %f Max: %f\n", m_lit_stats.get_number_of_values32(), m_lit_stats.get_total(), m_lit_stats.get_total() / 8.0f, m_lit_stats.get_average(), m_lit_stats.get_std_dev(), m_lit_stats.get_min_val(), m_lit_stats.get_max_val()); - - printf("Delta literal stats:\n"); - printf(" Count: %u, Cost: %f (%f bytes), Ave: %f StdDev: %f Min: %f Max: %f\n", m_delta_lit_stats.get_number_of_values32(), m_delta_lit_stats.get_total(), m_delta_lit_stats.get_total() / 8.0f, m_delta_lit_stats.get_average(), m_delta_lit_stats.get_std_dev(), m_delta_lit_stats.get_min_val(), m_delta_lit_stats.get_max_val()); - - printf("Rep0 Len1 stats:\n"); - printf(" Count: %u, Cost: %f (%f bytes), Ave. Cost: %f StdDev: %f Min: %f Max: %f\n", m_rep0_len1_stats.get_number_of_values32(), m_rep0_len1_stats.get_total(), m_rep0_len1_stats.get_total() / 8.0f, m_rep0_len1_stats.get_average(), m_rep0_len1_stats.get_std_dev(), m_rep0_len1_stats.get_min_val(), m_rep0_len1_stats.get_max_val()); - - printf("Rep0 Len2+ stats:\n"); - printf(" Count: %u, Cost: %f (%f bytes), Ave. Cost: %f StdDev: %f Min: %f Max: %f\n", m_rep0_len2_plus_stats.get_number_of_values32(), m_rep0_len2_plus_stats.get_total(), m_rep0_len2_plus_stats.get_total() / 8.0f, m_rep0_len2_plus_stats.get_average(), m_rep0_len2_plus_stats.get_std_dev(), m_rep0_len2_plus_stats.get_min_val(), m_rep0_len2_plus_stats.get_max_val()); - - for (uint i = 0; i < CLZBase::cMatchHistSize; i++) - { - printf("Rep %u stats:\n", i); - printf(" Count: %u, Cost: %f (%f bytes), Ave. Cost: %f StdDev: %f Min: %f Max: %f\n", m_rep_stats[i].get_number_of_values32(), m_rep_stats[i].get_total(), m_rep_stats[i].get_total() / 8.0f, m_rep_stats[i].get_average(), m_rep_stats[i].get_std_dev(), m_rep_stats[i].get_min_val(), m_rep_stats[i].get_max_val()); - } - - for (uint i = CLZBase::cMinMatchLen; i <= CLZBase::cMaxMatchLen; i++) - { - printf("Match %u: Total: %u, Cost: %f (%f bytes), Ave: %f StdDev: %f Min: %f Max: %f\n", i, - m_full_match_stats[i].get_number_of_values32(), m_full_match_stats[i].get_total(), m_full_match_stats[i].get_total() / 8.0f, - m_full_match_stats[i].get_average(), m_full_match_stats[i].get_std_dev(), m_full_match_stats[i].get_min_val(), m_full_match_stats[i].get_max_val()); - } - - printf("Total near len2 matches: %u, total far len2 matches: %u\n", m_total_near_len2_matches, m_total_far_len2_matches); - printf("Total matches: %u, truncated matches: %u\n", m_total_matches, m_total_truncated_matches); - printf("Max full match len2 distance: %u\n", m_max_len2_dist); - -#if 0 - printf("Size of truncation histogram:\n"); - for (uint i = 0; i <= CLZBase::cMaxMatchLen; i++) - { - printf("%05u ", m_match_truncation_len_hist[i]); - if ((i & 15) == 15) printf("\n"); - } - printf("\n"); - - printf("Number of truncations per encoded match length histogram:\n"); - for (uint i = 0; i <= CLZBase::cMaxMatchLen; i++) - { - printf("%05u ", m_match_truncation_hist[i]); - if ((i & 15) == 15) printf("\n"); - } - printf("\n"); - - for (uint s = 0; s < CLZBase::cNumStates; s++) - { - printf("-- Match type truncation hist for state %u:\n", s); - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_match_type_truncation_hist[s]); i++) - { - printf("%u truncated (%3.1f%%), %u not truncated\n", m_match_type_truncation_hist[s][i], 100.0f * (float)m_match_type_truncation_hist[s][i] / (m_match_type_truncation_hist[s][i] + m_match_type_was_not_truncated_hist[s][i]), m_match_type_was_not_truncated_hist[s][i]); - } - } -#endif - } - - void lzcompressor::coding_stats::update(const lzdecision& lzdec, const state& cur_state, const search_accelerator& dict, bit_cost_t cost) - { - m_total_bytes += lzdec.get_len(); - m_total_contexts++; - - float cost_in_bits = cost / (float)cBitCostScale; - LZHAM_ASSERT(cost_in_bits > 0.0f); - m_total_cost += cost_in_bits; - - m_context_stats.update(cost_in_bits); - - //uint match_pred = cur_state.get_pred_char(dict, lzdec.m_pos, 1); - uint is_match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(cur_state.m_cur_state); - - if (lzdec.m_len == 0) - { - float match_bit_cost = cur_state.m_is_match_model[is_match_model_index].get_cost(0) / (float)cBitCostScale; - - m_total_is_match0_bits_cost += match_bit_cost; - m_total_match_bits_cost += match_bit_cost; - m_worst_match_bits_cost = math::maximum(m_worst_match_bits_cost, static_cast(match_bit_cost)); - m_total_nonmatches++; - - if (cur_state.m_cur_state < CLZBase::cNumLitStates) - { - m_lit_stats.update(cost_in_bits); - } - else - { - m_delta_lit_stats.update(cost_in_bits); - } - } - else if (lzdec.m_len <= CLZBase::cMaxMatchLen) - { - const uint match_len = lzdec.get_len(); - - { - uint match_dist = lzdec.get_match_dist(cur_state); - - uint cur_lookahead_size = dict.get_lookahead_size(); - - uint actual_match_len = dict.get_match_len(0, match_dist, LZHAM_MIN(cur_lookahead_size, static_cast(CLZBase::cMaxMatchLen))); - LZHAM_VERIFY(match_len <= actual_match_len); - - m_total_truncated_matches += match_len < actual_match_len; - m_match_truncation_len_hist[math::maximum(0, actual_match_len - match_len)]++; - - uint type_index = 4; - if (!lzdec.is_full_match()) - { - LZHAM_ASSUME(CLZBase::cMatchHistSize == 4); - type_index = -lzdec.m_dist - 1; - } - - if (actual_match_len > match_len) - { - m_match_truncation_hist[match_len]++; - - m_match_type_truncation_hist[cur_state.m_cur_state][type_index]++; - } - else - { - m_match_type_was_not_truncated_hist[cur_state.m_cur_state][type_index]++; - } - } - - float match_bit_cost = cur_state.m_is_match_model[is_match_model_index].get_cost(1) / (float)cBitCostScale; - m_total_is_match1_bits_cost += match_bit_cost; - m_total_match_bits_cost += match_bit_cost; - m_worst_match_bits_cost = math::maximum(m_worst_match_bits_cost, static_cast(match_bit_cost)); - m_total_matches++; - - if (lzdec.m_dist < 0) - { - // rep match - int match_hist_index = -lzdec.m_dist - 1; - LZHAM_ASSERT(match_hist_index < CLZBase::cMatchHistSize); - - m_rep_stats[match_hist_index].update(cost_in_bits); - - if (!match_hist_index) - { - // rep0 match - if (lzdec.m_len == 1) - { - m_rep0_len1_stats.update(cost_in_bits); - } - else - { - m_rep0_len2_plus_stats.update(cost_in_bits); - } - } - } - else - { - m_full_match_stats[math::minimum(cMaxMatchLen, match_len)].update(cost_in_bits); - - if (match_len == 2) - { - if (lzdec.m_dist <= 512) - m_total_near_len2_matches++; - else - m_total_far_len2_matches++; - - m_max_len2_dist = LZHAM_MAX((int)m_max_len2_dist, lzdec.m_dist); - } - } - } - else - { - // TODO: Handle huge matches. - } - } -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,947 +0,0 @@ -// File: lzham_match_accel.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_match_accel.h" -#include "lzham_timer.h" - -static const int cHashSize24 = 0x1000000; -static const int cHashSize16 = 0x10000; - -namespace lzham -{ - static inline uint32 hash2_to_12(uint c0, uint c1) { return c0 ^ (c1 << 4); } - - #define LZHAM_HASH3_16(c0, c1, c2) ((((uint)c0) | (((uint)c1) << 8U)) ^ (((uint)c2) << 4U)) - #define LZHAM_HASH3_24(c0, c1, c2) (((uint)c0) | (((uint)c1) << 8U) | (((uint)c2) << 16U)) - - search_accelerator::search_accelerator(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_pLZBase(NULL), - m_pTask_pool(NULL), - m_max_helper_threads(0), - m_max_dict_size(0), - m_max_dict_size_mask(0), - m_lookahead_pos(0), - m_lookahead_size(0), - m_cur_dict_size(0), - m_dict(malloc_context), - m_hash(malloc_context), - m_nodes(malloc_context), - m_matches(malloc_context), - m_match_refs(malloc_context), - m_digram_hash(malloc_context), - m_digram_next(malloc_context), - m_fill_lookahead_pos(0), - m_fill_lookahead_size(0), - m_fill_dict_size(0), - m_max_probes(0), - m_max_matches(0), - m_all_matches(false), - m_deterministic(false), - m_len2_matches(false), - m_hash24(false), - m_next_match_ref(0), - m_num_completed_helper_threads(0) - { - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_thread_dict_offsets); i++) - m_thread_dict_offsets[i].set_malloc_context(malloc_context); - } - - bool search_accelerator::init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes, uint flags) - { - LZHAM_ASSERT(pLZBase); - LZHAM_ASSERT(max_dict_size && math::is_power_of_2(max_dict_size)); - LZHAM_ASSERT(max_probes); - - m_max_probes = LZHAM_MIN(cMatchAccelMaxSupportedProbes, max_probes); - - m_deterministic = (flags & cFlagDeterministic) != 0; - m_len2_matches = (flags & cFlagLen2Matches) != 0; - m_hash24 = (flags & cFlagHash24) != 0; - - m_pLZBase = pLZBase; - m_pTask_pool = max_helper_threads ? pPool : NULL; - m_max_helper_threads = m_pTask_pool ? max_helper_threads : 0; - m_max_matches = LZHAM_MIN(m_max_probes, max_matches); - m_all_matches = all_matches; - - m_max_dict_size = max_dict_size; - m_max_dict_size_mask = m_max_dict_size - 1; - m_cur_dict_size = 0; - m_lookahead_size = 0; - m_lookahead_pos = 0; - m_fill_lookahead_pos = 0; - m_fill_lookahead_size = 0; - m_fill_dict_size = 0; - m_num_completed_helper_threads = 0; - - if (!m_dict.try_resize_no_construct(max_dict_size + LZHAM_MIN(m_max_dict_size, static_cast(CLZBase::cMaxHugeMatchLen)))) - { - LZHAM_LOG_ERROR(9000); - return false; - } - - if (!m_hash.try_resize_no_construct(m_hash24 ? cHashSize24 : cHashSize16)) - { - LZHAM_LOG_ERROR(9001); - return false; - } - - memset(m_hash.get_ptr(), 0, m_hash.size_in_bytes()); - - if (!m_nodes.try_resize_no_construct(max_dict_size)) - { - LZHAM_LOG_ERROR(9002); - return false; - } - - for (uint i = 0; i < max_helper_threads; i++) - { - if (!m_thread_dict_offsets[i].try_reserve(256 * 1024)) - { - LZHAM_LOG_ERROR(9003); - return false; - } - } - - // Shouldn't be necessary - //if (m_deterministic) - // memset(m_nodes.get_ptr(), 0, m_nodes.size_in_bytes()); - - return true; - } - - void search_accelerator::reset() - { - m_cur_dict_size = 0; - m_lookahead_size = 0; - m_lookahead_pos = 0; - m_fill_lookahead_pos = 0; - m_fill_lookahead_size = 0; - m_fill_dict_size = 0; - m_num_completed_helper_threads = 0; - - // Clearing the hash tables is only necessary for determinism (otherwise, it's possible the matches returned after a reset will depend on the data processes before the reset). - if (m_hash.size()) - memset(m_hash.get_ptr(), 0, m_hash.size_in_bytes()); - - if (m_digram_hash.size()) - memset(m_digram_hash.get_ptr(), 0, m_digram_hash.size_in_bytes()); - - // Shouldn't be necessary - //if (m_deterministic) - // memset(m_nodes.get_ptr(), 0, m_nodes.size_in_bytes()); - } - - void search_accelerator::flush() - { - m_cur_dict_size = 0; - } - - uint search_accelerator::get_max_add_bytes() const - { - uint add_pos = static_cast(m_lookahead_pos & (m_max_dict_size - 1)); - return m_max_dict_size - add_pos; - } - - static uint8 g_hamming_dist[256] = - { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - }; - - void search_accelerator::find_all_matches_callback_st(uint64 data, void* pData_ptr) - { - scoped_perf_section find_all_matches_timer("find_all_matches_callback_st"); - - LZHAM_NOTE_UNUSED(data); - LZHAM_NOTE_UNUSED(pData_ptr); - - dict_match temp_matches[cMatchAccelMaxSupportedProbes * 2]; - - uint fill_lookahead_pos = m_fill_lookahead_pos; - uint fill_dict_size = m_fill_dict_size; - uint fill_lookahead_size = m_fill_lookahead_size; - - uint c0 = 0, c1 = 0; - if (fill_lookahead_size >= 2) - { - c0 = m_dict[fill_lookahead_pos & m_max_dict_size_mask]; - c1 = m_dict[(fill_lookahead_pos & m_max_dict_size_mask) + 1]; - } - - const uint8* pDict = m_dict.get_ptr(); - - while (fill_lookahead_size >= 3) - { - uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask; - - uint c2 = pDict[insert_pos + 2]; - - uint h; - if (m_hash24) - h = LZHAM_HASH3_24(c0, c1, c2); - else - h = LZHAM_HASH3_16(c0, c1, c2); - - c0 = c1; - c1 = c2; - - dict_match *pDstMatch = temp_matches; - - uint cur_pos = m_hash[h]; - m_hash[h] = static_cast(fill_lookahead_pos); - - uint *pLeft = &m_nodes[insert_pos].m_left; - uint *pRight = &m_nodes[insert_pos].m_right; - - const uint max_match_len = LZHAM_MIN(static_cast(CLZBase::cMaxMatchLen), fill_lookahead_size); - uint best_match_len = 2; - - const uint8* pIns = &pDict[insert_pos]; - - uint n = m_max_probes; - for ( ; ; ) - { - uint delta_pos = fill_lookahead_pos - cur_pos; - if ((n-- == 0) || (!delta_pos) || (delta_pos >= fill_dict_size)) - { - *pLeft = 0; - *pRight = 0; - break; - } - - uint pos = cur_pos & m_max_dict_size_mask; - - // Unfortunately, the initial compare match_len must be 0 because of the way we hash and truncate matches at the end of each block. - uint match_len = 0; - const uint8* pComp = &pDict[pos]; - -#if LZHAM_PLATFORM_X360 || (LZHAM_USE_UNALIGNED_INT_LOADS == 0) || LZHAM_BIG_ENDIAN_CPU - for ( ; match_len < max_match_len; match_len++) - if (pComp[match_len] != pIns[match_len]) - break; -#else - // Compare a qword at a time for a bit more efficiency. - uint64 x = *reinterpret_cast(pComp); - uint64 y = *reinterpret_cast(pIns); - if ((max_match_len >= 8) && (x == y)) - { - const uint64* pComp_cur = reinterpret_cast(pComp) + 1; - const uint64* pIns_cur = reinterpret_cast(pIns) + 1; - - const uint64* pComp_end = reinterpret_cast(pComp + max_match_len - 7); - while (pComp_cur < pComp_end) - { - if (*pComp_cur != *pIns_cur) - break; - ++pComp_cur; - ++pIns_cur; - } - - uint alt_match_len = static_cast(reinterpret_cast(pComp_cur) - reinterpret_cast(pComp)); - for ( ; alt_match_len < max_match_len; alt_match_len++) - if (pComp[alt_match_len] != pIns[alt_match_len]) - break; - - match_len = alt_match_len; - } - else - { - if ((uint32)x == (uint32)y) - { - x >>= 32; - y >>= 32; - match_len += 4; - } - - if ((uint16)x == (uint16)y) - { - x >>= 16; - y >>= 16; - match_len += 2; - } - - if ((uint8)x == (uint8)y) - match_len++; - - match_len = math::minimum(match_len, max_match_len); - } -#endif - -#ifdef LZVERIFY - uint check_match_len; - for (check_match_len = 0; check_match_len < max_match_len; check_match_len++) - if (pComp[check_match_len] != pIns[check_match_len]) - break; - LZHAM_VERIFY(match_len == check_match_len); -#endif - - node *pNode = &m_nodes[pos]; - - if (match_len > best_match_len) - { - pDstMatch->m_len = static_cast(match_len - CLZBase::cMinMatchLen); - pDstMatch->m_dist = delta_pos; - pDstMatch++; - - best_match_len = match_len; - - if (match_len == max_match_len) - { - *pLeft = pNode->m_left; - *pRight = pNode->m_right; - break; - } - } - else if (m_all_matches) - { - pDstMatch->m_len = static_cast(match_len - CLZBase::cMinMatchLen); - pDstMatch->m_dist = delta_pos; - pDstMatch++; - } - else if ((best_match_len > 2) && (best_match_len == match_len)) - { - uint bestMatchDist = pDstMatch[-1].m_dist; - uint compMatchDist = delta_pos; - - uint bestMatchSlot, bestMatchSlotOfs; - m_pLZBase->compute_lzx_position_slot(bestMatchDist, bestMatchSlot, bestMatchSlotOfs); - - uint compMatchSlot, compMatchOfs; - m_pLZBase->compute_lzx_position_slot(compMatchDist, compMatchSlot, compMatchOfs); - - // If both matches uses the same match slot, choose the one with the offset containing the lowest nibble as these bits separately entropy coded. - // This could choose a match which is further away in the absolute sense, but closer in a coding sense. - if ( (compMatchSlot < bestMatchSlot) || - ((compMatchSlot >= 8) && (compMatchSlot == bestMatchSlot) && ((compMatchOfs & 15) < (bestMatchSlotOfs & 15))) ) - { - LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len); - pDstMatch[-1].m_dist = delta_pos; - } - else if ((match_len < max_match_len) && (compMatchSlot <= bestMatchSlot)) - { - // Choose the match which has lowest hamming distance in the mismatch byte for a tiny win on binary files. - // TODO: This competes against the prev. optimization. - uint desired_mismatch_byte = pIns[match_len]; - - uint cur_mismatch_byte = pDict[(insert_pos - bestMatchDist + match_len) & m_max_dict_size_mask]; - uint cur_mismatch_dist = g_hamming_dist[cur_mismatch_byte ^ desired_mismatch_byte]; - - uint new_mismatch_byte = pComp[match_len]; - uint new_mismatch_dist = g_hamming_dist[new_mismatch_byte ^ desired_mismatch_byte]; - if (new_mismatch_dist < cur_mismatch_dist) - { - LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len); - pDstMatch[-1].m_dist = delta_pos; - } - } - } - - uint new_pos; - if (pComp[match_len] < pIns[match_len]) - { - *pLeft = cur_pos; - pLeft = &pNode->m_right; - new_pos = pNode->m_right; - } - else - { - *pRight = cur_pos; - pRight = &pNode->m_left; - new_pos = pNode->m_left; - } - if (new_pos == cur_pos) - break; - cur_pos = new_pos; - } - - const uint num_matches = (uint)(pDstMatch - temp_matches); - - if (num_matches) - { - pDstMatch[-1].m_dist |= 0x80000000; - - const uint num_matches_to_write = LZHAM_MIN(num_matches, m_max_matches); - - const uint match_ref_ofs = m_next_match_ref; - - m_next_match_ref += num_matches_to_write; - - memcpy(&m_matches[match_ref_ofs], - temp_matches + (num_matches - num_matches_to_write), - sizeof(temp_matches[0]) * num_matches_to_write); - - m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)] = match_ref_ofs; - } - else - { - m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)] = -2; - } - - fill_lookahead_pos++; - fill_lookahead_size--; - fill_dict_size++; - } - - while (fill_lookahead_size) - { - uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask; - m_nodes[insert_pos].m_left = 0; - m_nodes[insert_pos].m_right = 0; - - m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)] = -2; - - fill_lookahead_pos++; - fill_lookahead_size--; - fill_dict_size++; - } - - m_num_completed_helper_threads++; - } - - void search_accelerator::find_all_matches_callback_mt(uint64 data, void* pData_ptr) - { - scoped_perf_section find_all_matches_timer(cVarArgs, "find_all_matches_callback_mt %u", (uint)data); - - LZHAM_NOTE_UNUSED(pData_ptr); - const uint thread_index = (uint)data; - - dict_match temp_matches[cMatchAccelMaxSupportedProbes * 2]; - - const uint8* pDict = m_dict.get_ptr(); - - const uint *pDict_ofsets = m_thread_dict_offsets[thread_index].get_ptr(); - const uint num_dict_offsets = m_thread_dict_offsets[thread_index].size(); - - for (uint i = 0; i < num_dict_offsets; i++) - { - uint lookahead_ofs = *pDict_ofsets++; - uint fill_lookahead_pos = m_fill_lookahead_pos + lookahead_ofs; - uint fill_dict_size = m_fill_dict_size + lookahead_ofs; - LZHAM_ASSERT(m_fill_lookahead_size > lookahead_ofs); - uint fill_lookahead_size = m_fill_lookahead_size - lookahead_ofs; - - const uint max_match_len = LZHAM_MIN(static_cast(CLZBase::cMaxMatchLen), fill_lookahead_size); - - uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask; - - uint c0 = pDict[insert_pos]; - uint c1 = pDict[insert_pos + 1]; - uint c2 = pDict[insert_pos + 2]; - - uint h; - if (m_hash24) - h = LZHAM_HASH3_24(c0, c1, c2); - else - h = LZHAM_HASH3_16(c0, c1, c2); - - dict_match* pDstMatch = temp_matches; - - uint cur_pos = m_hash[h]; - m_hash[h] = static_cast(fill_lookahead_pos); - - uint *pLeft = &m_nodes[insert_pos].m_left; - uint *pRight = &m_nodes[insert_pos].m_right; - - uint best_match_len = 2; - - const uint8* pIns = &pDict[insert_pos]; - - uint n = m_max_probes; - for ( ; ; ) - { - uint delta_pos = fill_lookahead_pos - cur_pos; - if ((n-- == 0) || (!delta_pos) || (delta_pos >= fill_dict_size)) - { - *pLeft = 0; - *pRight = 0; - break; - } - - uint pos = cur_pos & m_max_dict_size_mask; - - // Unfortunately, the initial compare match_len must be 0 because of the way we hash and truncate matches at the end of each block. - uint match_len = 0; - const uint8* pComp = &pDict[pos]; - -#if LZHAM_PLATFORM_X360 || (LZHAM_USE_UNALIGNED_INT_LOADS == 0) || LZHAM_BIG_ENDIAN_CPU - for ( ; match_len < max_match_len; match_len++) - if (pComp[match_len] != pIns[match_len]) - break; -#else - // Compare a qword at a time for a bit more efficiency. - uint64 x = *reinterpret_cast(pComp); - uint64 y = *reinterpret_cast(pIns); - if ((max_match_len >= 8) && (x == y)) - { - const uint64* pComp_cur = reinterpret_cast(pComp) + 1; - const uint64* pIns_cur = reinterpret_cast(pIns) + 1; - - const uint64* pComp_end = reinterpret_cast(pComp + max_match_len - 7); - while (pComp_cur < pComp_end) - { - if (*pComp_cur != *pIns_cur) - break; - ++pComp_cur; - ++pIns_cur; - } - - uint alt_match_len = static_cast(reinterpret_cast(pComp_cur) - reinterpret_cast(pComp)); - for ( ; alt_match_len < max_match_len; alt_match_len++) - if (pComp[alt_match_len] != pIns[alt_match_len]) - break; - - match_len = alt_match_len; - } - else - { - if ((uint32)x == (uint32)y) - { - x >>= 32; - y >>= 32; - match_len += 4; - } - - if ((uint16)x == (uint16)y) - { - x >>= 16; - y >>= 16; - match_len += 2; - } - - if ((uint8)x == (uint8)y) - match_len++; - - match_len = math::minimum(match_len, max_match_len); - } -#endif - -#ifdef LZVERIFY - uint check_match_len; - for (check_match_len = 0; check_match_len < max_match_len; check_match_len++) - if (pComp[check_match_len] != pIns[check_match_len]) - break; - LZHAM_VERIFY(match_len == check_match_len); -#endif - - node *pNode = &m_nodes[pos]; - - if (match_len > best_match_len) - { - pDstMatch->m_len = static_cast(match_len - CLZBase::cMinMatchLen); - pDstMatch->m_dist = delta_pos; - pDstMatch++; - - best_match_len = match_len; - - if (match_len == max_match_len) - { - *pLeft = pNode->m_left; - *pRight = pNode->m_right; - break; - } - } - else if (m_all_matches) - { - pDstMatch->m_len = static_cast(match_len - CLZBase::cMinMatchLen); - pDstMatch->m_dist = delta_pos; - pDstMatch++; - } - else if ((best_match_len > 2) && (best_match_len == match_len)) - { - uint bestMatchDist = pDstMatch[-1].m_dist; - uint compMatchDist = delta_pos; - - uint bestMatchSlot, bestMatchSlotOfs; - m_pLZBase->compute_lzx_position_slot(bestMatchDist, bestMatchSlot, bestMatchSlotOfs); - - uint compMatchSlot, compMatchOfs; - m_pLZBase->compute_lzx_position_slot(compMatchDist, compMatchSlot, compMatchOfs); - - // If both matches uses the same match slot, choose the one with the offset containing the lowest nibble as these bits separately entropy coded. - // This could choose a match which is further away in the absolute sense, but closer in a coding sense. - if ( (compMatchSlot < bestMatchSlot) || - ((compMatchSlot >= 8) && (compMatchSlot == bestMatchSlot) && ((compMatchOfs & 15) < (bestMatchSlotOfs & 15))) ) - { - LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len); - pDstMatch[-1].m_dist = delta_pos; - } - else if ((match_len < max_match_len) && (compMatchSlot <= bestMatchSlot)) - { - // Choose the match which has lowest hamming distance in the mismatch byte for a tiny win on binary files. - // TODO: This competes against the prev. optimization. - uint desired_mismatch_byte = pIns[match_len]; - - uint cur_mismatch_byte = pDict[(insert_pos - bestMatchDist + match_len) & m_max_dict_size_mask]; - uint cur_mismatch_dist = g_hamming_dist[cur_mismatch_byte ^ desired_mismatch_byte]; - - uint new_mismatch_byte = pComp[match_len]; - uint new_mismatch_dist = g_hamming_dist[new_mismatch_byte ^ desired_mismatch_byte]; - if (new_mismatch_dist < cur_mismatch_dist) - { - LZHAM_ASSERT((pDstMatch[-1].m_len + (uint)CLZBase::cMinMatchLen) == best_match_len); - pDstMatch[-1].m_dist = delta_pos; - } - } - } - - uint new_pos; - if (pComp[match_len] < pIns[match_len]) - { - *pLeft = cur_pos; - pLeft = &pNode->m_right; - new_pos = pNode->m_right; - } - else - { - *pRight = cur_pos; - pRight = &pNode->m_left; - new_pos = pNode->m_left; - } - if (new_pos == cur_pos) - break; - cur_pos = new_pos; - } - - const uint num_matches = (uint)(pDstMatch - temp_matches); - - if (num_matches) - { - pDstMatch[-1].m_dist |= 0x80000000; - - const uint num_matches_to_write = LZHAM_MIN(num_matches, m_max_matches); - - const uint match_ref_ofs = static_cast(atomic_exchange_add(&m_next_match_ref, num_matches_to_write)); - - memcpy(&m_matches[match_ref_ofs], - temp_matches + (num_matches - num_matches_to_write), - sizeof(temp_matches[0]) * num_matches_to_write); - - // FIXME: This is going to really hurt on platforms requiring export barriers. - LZHAM_MEMORY_EXPORT_BARRIER - - atomic_exchange32((atomic32_t*)&m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)], match_ref_ofs); - } - else - { - atomic_exchange32((atomic32_t*)&m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)], -2); - } - } - - atomic_increment32(&m_num_completed_helper_threads); - } - - bool search_accelerator::find_len2_matches() - { - if (!m_digram_hash.size()) - { - if (!m_digram_hash.try_resize(cDigramHashSize)) - { - LZHAM_LOG_ERROR(9004); - return false; - } - } - - if (m_digram_next.size() < m_lookahead_size) - { - if (!m_digram_next.try_resize(m_lookahead_size)) - { - LZHAM_LOG_ERROR(9005); - return false; - } - } - - uint lookahead_dict_pos = m_lookahead_pos & m_max_dict_size_mask; - - for (int lookahead_ofs = 0; lookahead_ofs < ((int)m_lookahead_size - 1); ++lookahead_ofs, ++lookahead_dict_pos) - { - uint c0 = m_dict[lookahead_dict_pos]; - uint c1 = m_dict[lookahead_dict_pos + 1]; - - uint h = hash2_to_12(c0, c1) & (cDigramHashSize - 1); - - m_digram_next[lookahead_ofs] = m_digram_hash[h]; - m_digram_hash[h] = m_lookahead_pos + lookahead_ofs; - } - - m_digram_next[m_lookahead_size - 1] = 0; - - return true; - } - - uint search_accelerator::get_len2_match(uint lookahead_ofs) - { - if ((m_fill_lookahead_size - lookahead_ofs) < 2) - return 0; - if (!m_digram_next.size()) - return 0; - - uint cur_pos = m_lookahead_pos + lookahead_ofs; - - uint next_match_pos = m_digram_next[cur_pos - m_fill_lookahead_pos]; - - uint match_dist = cur_pos - next_match_pos; - - if ((!match_dist) || (match_dist > CLZBase::cMaxLen2MatchDist) || (match_dist > (m_cur_dict_size + lookahead_ofs))) - return 0; - - const uint8* pCur = &m_dict[cur_pos & m_max_dict_size_mask]; - const uint8* pMatch = &m_dict[next_match_pos & m_max_dict_size_mask]; - - if ((pCur[0] == pMatch[0]) && (pCur[1] == pMatch[1])) - return match_dist; - - return 0; - } - - static inline uint32 bitmix32(uint32 a) - { - a -= (a << 6); - a ^= (a >> 17); - a -= (a << 9); - a ^= (a << 4); - a -= (a << 3); - a ^= (a << 10); - a ^= (a >> 15); - return a; - } - - bool search_accelerator::find_all_matches(uint num_bytes) - { - if (!m_matches.try_resize_no_construct(m_max_probes * num_bytes)) - { - LZHAM_LOG_ERROR(9006); - return false; - } - - if (!m_match_refs.try_resize_no_construct(num_bytes)) - { - LZHAM_LOG_ERROR(9007); - return false; - } - - memset(m_match_refs.get_ptr(), 0xFF, m_match_refs.size_in_bytes()); - - m_fill_lookahead_pos = m_lookahead_pos; - m_fill_lookahead_size = num_bytes; - m_fill_dict_size = m_cur_dict_size; - - m_next_match_ref = 0; - - if ((!m_pTask_pool) || (m_max_helper_threads < 1) || (num_bytes < 1024)) - { - find_all_matches_callback_st(0, NULL); - - m_num_completed_helper_threads = 0; - } - else - { - for (uint i = num_bytes - 2; i < num_bytes; i++) - { - uint fill_lookahead_pos = m_fill_lookahead_pos + i; - uint insert_pos = fill_lookahead_pos & m_max_dict_size_mask; - m_nodes[insert_pos].m_left = 0; - m_nodes[insert_pos].m_right = 0; - - m_match_refs[static_cast(fill_lookahead_pos - m_fill_lookahead_pos)] = -2; - } - - for (uint i = 0; i < m_max_helper_threads; i++) - m_thread_dict_offsets[i].try_resize(0); - - uint bytes_to_add = num_bytes - 2; - - scoped_perf_section sect(cVarArgs, "****** find_all_matches_prep %u", bytes_to_add); - - const uint8* pDict = &m_dict[m_lookahead_pos & m_max_dict_size_mask]; - - if (m_hash24) - { - uint t = (pDict[0] << 8) | (pDict[1] << 16); - - if (math::is_power_of_2(m_max_helper_threads)) - { - const uint bitmask = (m_max_helper_threads - 1); - for (uint i = 0; i < bytes_to_add; i++) - { - t = (t >> 8) | (pDict[2] << 16); - - LZHAM_ASSERT(t == LZHAM_HASH3_24(pDict[0], pDict[1], pDict[2])); - - uint thread_index = bitmix32(t) & bitmask; - - if (!m_thread_dict_offsets[thread_index].try_push_back(i)) - { - LZHAM_LOG_ERROR(9008); - return false; - } - - pDict++; - } - } - else - { - for (uint i = 0; i < bytes_to_add; i++) - { - t = (t >> 8) | (pDict[2] << 16); - - LZHAM_ASSERT(t == LZHAM_HASH3_24(pDict[0], pDict[1], pDict[2])); - - uint thread_index = bitmix32(t) % m_max_helper_threads; - - if (!m_thread_dict_offsets[thread_index].try_push_back(i)) - { - LZHAM_LOG_ERROR(9009); - return false; - } - - pDict++; - } - } - } - else - { - uint c0 = pDict[0]; - uint c1 = pDict[1]; - - for (uint i = 0; i < bytes_to_add; i++) - { - uint c2 = pDict[2]; - - uint t = LZHAM_HASH3_16(c0, c1, c2); - - c0 = c1; - c1 = c2; - - uint thread_index = bitmix32(t) % m_max_helper_threads; - - if (!m_thread_dict_offsets[thread_index].try_push_back(i)) - { - LZHAM_LOG_ERROR(9010); - return false; - } - - pDict++; - } - } - - m_num_completed_helper_threads = 0; - - if (!m_pTask_pool->queue_multiple_object_tasks(this, &search_accelerator::find_all_matches_callback_mt, 0, m_max_helper_threads)) - { - LZHAM_LOG_ERROR(9011); - return false; - } - } - - return m_len2_matches ? find_len2_matches() : true; - } - - bool search_accelerator::add_bytes_begin(uint num_bytes, const uint8* pBytes) - { - LZHAM_ASSERT(num_bytes <= m_max_dict_size); - LZHAM_ASSERT(!m_lookahead_size); - - uint add_pos = m_lookahead_pos & m_max_dict_size_mask; - LZHAM_ASSERT((add_pos + num_bytes) <= m_max_dict_size); - - memcpy(&m_dict[add_pos], pBytes, num_bytes); - - uint dict_bytes_to_mirror = LZHAM_MIN(static_cast(CLZBase::cMaxHugeMatchLen), m_max_dict_size); - if (add_pos < dict_bytes_to_mirror) - memcpy(&m_dict[m_max_dict_size], &m_dict[0], dict_bytes_to_mirror); - - m_lookahead_size = num_bytes; - - uint max_possible_dict_size = m_max_dict_size - num_bytes; - m_cur_dict_size = LZHAM_MIN(m_cur_dict_size, max_possible_dict_size); - - m_next_match_ref = 0; - - return find_all_matches(num_bytes); - } - - void search_accelerator::add_bytes_end() - { - if (m_pTask_pool) - { - m_pTask_pool->join(); - } - - LZHAM_ASSERT((uint)m_next_match_ref <= m_matches.size()); - } - - dict_match* search_accelerator::find_matches(uint lookahead_ofs, bool spin) - { - LZHAM_ASSERT(lookahead_ofs < m_lookahead_size); - - const uint match_ref_ofs = static_cast(m_lookahead_pos - m_fill_lookahead_pos + lookahead_ofs); - - int match_ref; - uint spin_count = 0; - - // This may spin until the match finder job(s) catch up to the caller's lookahead position. - for ( ; ; ) - { - match_ref = static_cast(m_match_refs[match_ref_ofs]); - if (match_ref == -2) - return NULL; - else if (match_ref != -1) - break; - - spin_count++; - const uint cMaxSpinCount = 1000; - if ((spin) && (spin_count < cMaxSpinCount)) - { - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - - LZHAM_MEMORY_IMPORT_BARRIER - } - else - { - scoped_perf_section sect("find_matches_sleep"); - - spin_count = cMaxSpinCount; - - lzham_sleep(1); - } - } - - LZHAM_MEMORY_IMPORT_BARRIER - - return &m_matches[match_ref]; - } - - void search_accelerator::advance_bytes(uint num_bytes) - { - LZHAM_ASSERT(num_bytes <= m_lookahead_size); - - m_lookahead_pos += num_bytes; - m_lookahead_size -= num_bytes; - - m_cur_dict_size += num_bytes; - LZHAM_ASSERT(m_cur_dict_size <= m_max_dict_size); - } -} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ -// File: lzham_match_accel.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham_lzbase.h" -#include "lzham_threading.h" - -namespace lzham -{ - const uint cMatchAccelMaxSupportedProbes = 128; - const uint cMatchAccelMaxSupportedThreads = 32; - - struct node - { - uint m_left; - uint m_right; - }; - - LZHAM_DEFINE_BITWISE_MOVABLE(node); - -#pragma pack(push, 1) - struct dict_match - { - uint m_dist; - uint16 m_len; - - inline uint get_dist() const { return m_dist & 0x7FFFFFFF; } - inline uint get_len() const { return m_len + 2; } - inline bool is_last() const { return (int)m_dist < 0; } - }; -#pragma pack(pop) - - LZHAM_DEFINE_BITWISE_MOVABLE(dict_match); - - class search_accelerator - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(search_accelerator); - - public: - search_accelerator(lzham_malloc_context malloc_context); - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - // If all_matches is true, the match finder returns all found matches with no filtering. - // Otherwise, the finder will tend to return lists of matches with mostly unique lengths. - // For each length, it will discard matches with worse distances (in the coding sense). - enum - { - cFlagDeterministic = 1, - cFlagLen2Matches = 2, - cFlagHash24 = 4 - }; - - bool init(CLZBase* pLZBase, task_pool* pPool, uint max_helper_threads, uint max_dict_size, uint max_matches, bool all_matches, uint max_probes, uint flags); - - void reset(); - void flush(); - - inline uint get_max_dict_size() const { return m_max_dict_size; } - inline uint get_max_dict_size_mask() const { return m_max_dict_size_mask; } - inline uint get_cur_dict_size() const { return m_cur_dict_size; } - - inline uint get_lookahead_pos() const { return m_lookahead_pos; } - inline uint get_lookahead_size() const { return m_lookahead_size; } - - inline uint get_char(int delta_pos) const { return m_dict[(m_lookahead_pos + delta_pos) & m_max_dict_size_mask]; } - inline uint get_char(uint cur_dict_pos, int delta_pos) const { return m_dict[(cur_dict_pos + delta_pos) & m_max_dict_size_mask]; } - inline const uint8* get_ptr(uint pos) const { return &m_dict[pos]; } - - uint get_max_helper_threads() const { return m_max_helper_threads; } - - inline uint operator[](uint pos) const { return m_dict[pos]; } - - uint get_max_add_bytes() const; - bool add_bytes_begin(uint num_bytes, const uint8* pBytes); - inline atomic32_t get_num_completed_helper_threads() const { return m_num_completed_helper_threads; } - void add_bytes_end(); - - // Returns the lookahead's raw position/size/dict_size at the time add_bytes_begin() is called. - inline uint get_fill_lookahead_pos() const { return m_fill_lookahead_pos; } - inline uint get_fill_lookahead_size() const { return m_fill_lookahead_size; } - inline uint get_fill_dict_size() const { return m_fill_dict_size; } - - uint get_len2_match(uint lookahead_ofs); - dict_match* find_matches(uint lookahead_ofs, bool spin = true); - - void advance_bytes(uint num_bytes); - - LZHAM_FORCE_INLINE uint get_match_len(uint lookahead_ofs, int dist, uint max_match_len, uint start_match_len = 0) const - { - LZHAM_ASSERT(lookahead_ofs < m_lookahead_size); - LZHAM_ASSERT(start_match_len <= max_match_len); - LZHAM_ASSERT(max_match_len <= (get_lookahead_size() - lookahead_ofs)); - - const int find_dict_size = m_cur_dict_size + lookahead_ofs; - if (dist > find_dict_size) - return 0; - - const uint comp_pos = static_cast((m_lookahead_pos + lookahead_ofs - dist) & m_max_dict_size_mask); - const uint lookahead_pos = (m_lookahead_pos + lookahead_ofs) & m_max_dict_size_mask; - - const uint8* pComp = &m_dict[comp_pos]; - const uint8* pLookahead = &m_dict[lookahead_pos]; - - uint match_len; - for (match_len = start_match_len; match_len < max_match_len; match_len++) - if (pComp[match_len] != pLookahead[match_len]) - break; - - return match_len; - } - - public: - lzham_malloc_context m_malloc_context; - - CLZBase* m_pLZBase; - task_pool* m_pTask_pool; - uint m_max_helper_threads; - - uint m_max_dict_size; - uint m_max_dict_size_mask; - - uint m_lookahead_pos; - uint m_lookahead_size; - - uint m_cur_dict_size; - - lzham::vector m_dict; - - lzham::vector m_hash; - lzham::vector m_nodes; - - lzham::vector m_matches; - lzham::vector m_match_refs; - - enum { cDigramHashSize = 4096 }; - lzham::vector m_digram_hash; - lzham::vector m_digram_next; - - lzham::vector m_thread_dict_offsets[cMatchAccelMaxSupportedThreads]; - - uint m_fill_lookahead_pos; - uint m_fill_lookahead_size; - uint m_fill_dict_size; - - uint m_max_probes; - uint m_max_matches; - - bool m_all_matches; - - bool m_deterministic; - bool m_len2_matches; - bool m_hash24; - - volatile atomic32_t m_next_match_ref; - - volatile atomic32_t m_num_completed_helper_threads; - - void find_all_matches_callback_st(uint64 data, void* pData_ptr); - void find_all_matches_callback_mt(uint64 data, void* pData_ptr); - bool find_all_matches(uint num_bytes); - bool find_len2_matches(); - }; - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_null_threading.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_null_threading.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_null_threading.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_null_threading.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -// File: lzham_task_pool_null.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - class semaphore - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore); - - public: - inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL) - { - (void)initialCount, (void)maximumCount, (void)pName; - } - - inline ~semaphore() - { - } - - inline void release(long releaseCount = 1, long *pPreviousCount = NULL) - { - (void)releaseCount, (void)pPreviousCount; - } - - inline bool wait(uint32 milliseconds = cUINT32_MAX) - { - (void)milliseconds; - return true; - } - }; - - class task_pool - { - public: - inline task_pool(lzham_malloc_context malloc_context) { -(void)malloc_context; } - inline task_pool(uint num_threads) { (void)num_threads; } - inline ~task_pool() { } - - inline bool init(uint num_threads) { (void)num_threads; return true; } - inline void deinit(); - - inline uint get_num_threads() const { return 0; } - inline uint get_num_outstanding_tasks() const { return 0; } - - // C-style task callback - typedef void (*task_callback_func)(uint64 data, void* pData_ptr); - inline bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL) - { - pFunc(data, pData_ptr); - return true; - } - - class executable_task - { - public: - virtual void execute_task(uint64 data, void* pData_ptr) = 0; - }; - - // It's the caller's responsibility to delete pObj within the execute_task() method, if needed! - inline bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL) - { - pObj->execute_task(data, pData_ptr); - return true; - } - - template - inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL) - { - (pObject->*pObject_method)(data, pData_ptr); - return true; - } - - template - inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL) - { - for (uint i = 0; i < num_tasks; i++) - { - (pObject->*pObject_method)(first_data + i, pData_ptr); - } - return true; - } - - void join() { } - }; - - inline void lzham_sleep(unsigned int milliseconds) - { - (void)milliseconds; - } - - inline uint lzham_get_max_helper_threads() - { - return 0; - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -// File: lzham_task_pool_pthreads.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_pthreads_threading.h" -#include "lzham_timer.h" - -#ifdef WIN32 -#include -#endif - -#if defined(__GNUC__) && !defined(__APPLE__) && !defined(__MINGW32__) && !defined(__FreeBSD__) -#include -#endif - -#if LZHAM_USE_PTHREADS_API - -#ifdef WIN32 -#pragma comment(lib, "../ext/libpthread/lib/pthreadVC2.lib") -#endif - -namespace lzham -{ - task_pool::task_pool(lzham_malloc_context malloc_context) : - m_task_stack(malloc_context), - m_num_threads(0), - m_tasks_available(0, 32767), - m_malloc_context(malloc_context), - m_num_outstanding_tasks(0), - m_exit_flag(false) - { - utils::zero_object(m_threads); - } - - task_pool::task_pool(lzham_malloc_context malloc_context, uint num_threads) : - m_task_stack(malloc_context), - m_num_threads(0), - m_tasks_available(0, 32767), - m_malloc_context(malloc_context), - m_num_outstanding_tasks(0), - m_exit_flag(false) - { - utils::zero_object(m_threads); - - bool status = init(num_threads); - LZHAM_VERIFY(status); - } - - task_pool::~task_pool() - { - deinit(); - } - - bool task_pool::init(uint num_threads) - { - LZHAM_ASSERT(num_threads <= cMaxThreads); - num_threads = math::minimum(num_threads, cMaxThreads); - - deinit(); - - bool succeeded = true; - - m_num_threads = 0; - while (m_num_threads < num_threads) - { - int status = pthread_create(&m_threads[m_num_threads], NULL, thread_func, this); - if (status) - { - succeeded = false; - break; - } - - m_num_threads++; - } - - if (!succeeded) - { - deinit(); - return false; - } - - return true; - } - - void task_pool::deinit() - { - if (m_num_threads) - { - join(); - - atomic_exchange32(&m_exit_flag, true); - - m_tasks_available.release(m_num_threads); - - for (uint i = 0; i < m_num_threads; i++) - pthread_join(m_threads[i], NULL); - - m_num_threads = 0; - - atomic_exchange32(&m_exit_flag, false); - } - - m_task_stack.clear(); - m_num_outstanding_tasks = 0; - } - - bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pFunc); - - task tsk; - tsk.m_callback = pFunc; - tsk.m_data = data; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = 0; - - if (!m_task_stack.try_push(tsk)) - return false; - - atomic_increment32(&m_num_outstanding_tasks); - - m_tasks_available.release(1); - - return true; - } - - // It's the object's responsibility to delete pObj within the execute_task() method, if needed! - bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pObj); - - task tsk; - tsk.m_pObj = pObj; - tsk.m_data = data; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = cTaskFlagObject; - - if (!m_task_stack.try_push(tsk)) - return false; - - atomic_increment32(&m_num_outstanding_tasks); - - m_tasks_available.release(1); - - return true; - } - - void task_pool::process_task(task& tsk) - { - if (tsk.m_flags & cTaskFlagObject) - tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr); - else - tsk.m_callback(tsk.m_data, tsk.m_pData_ptr); - - atomic_decrement32(&m_num_outstanding_tasks); - } - - void task_pool::join() - { - task tsk; - while (atomic_add32(&m_num_outstanding_tasks, 0) > 0) - { - if (m_task_stack.pop(tsk)) - { - process_task(tsk); - } - else - { - lzham_sleep(1); - } - } - } - - void * task_pool::thread_func(void *pContext) - { - task_pool* pPool = static_cast(pContext); - task tsk; - - for ( ; ; ) - { - if (!pPool->m_tasks_available.wait()) - break; - - if (pPool->m_exit_flag) - break; - - if (pPool->m_task_stack.pop(tsk)) - { - pPool->process_task(tsk); - } - } - - return NULL; - } - - uint lzham_get_max_helper_threads() - { -#if defined(__APPLE__) || defined(__FreeBSD__) - int num_procs = static_cast(sysconf(_SC_NPROCESSORS_ONLN)); - return (num_procs >= 1) ? (num_procs - 1) : 0; -#elif (1) - uint num_procs = get_nprocs(); - return num_procs ? (num_procs - 1) : 0; -#else - printf("TODO: lzham_get_max_helper_threads(): Implement system specific func to determine the max # of helper threads\n"); - // Just assume a dual-core machine. - return 1; -#endif - } - -} // namespace lzham - -#endif // LZHAM_USE_PTHREADS_API diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,535 +0,0 @@ -// File: lzham_task_pool_pthreads.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if LZHAM_USE_PTHREADS_API - -#if LZHAM_NO_ATOMICS -#error No atomic operations defined in lzham_platform.h! -#endif - -#ifdef __APPLE__ - #include -#endif - -#include -#include -#include -#include - -#define LZHAM_RND_CONG(jcong) (69069U * jcong + 1234567U) - -namespace lzham -{ - // semaphore - -#ifdef __APPLE__ - class semaphore - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore); - - public: - inline semaphore(long initialCount = 0, long maximumCount = 1) - { - LZHAM_NOTE_UNUSED(maximumCount); - LZHAM_ASSERT(maximumCount >= initialCount); - - for (uint tries = 0; tries < 16; tries++) - { - struct timeval tp; - struct timezone tzp; - gettimeofday(&tp, &tzp); - uint x = tp.tv_usec; - - // Argh this stinks. Try to choose a name that won't conflict with anything the calling process uses. - for (uint i = 0; i < sizeof(m_name) - 1; i++) - { - x = LZHAM_RND_CONG(x); - char c = 'A' + (static_cast(x ^ (x >> 20)) % 26); - m_name[i] = c; - } - m_name[sizeof(m_name) - 1] = '\0'; - - m_pSem = sem_open(m_name, O_CREAT | O_EXCL, S_IRWXU, initialCount); - if (m_pSem != SEM_FAILED) - break; - } - - if (m_pSem == SEM_FAILED) - { - LZHAM_FAIL("semaphore: sem_init() failed"); - } - } - - inline ~semaphore() - { - sem_close(m_pSem); - sem_unlink(m_name); - } - - inline void release(long releaseCount = 1) - { - LZHAM_ASSERT(releaseCount >= 1); - - int status = 0; -#ifdef WIN32 - if (1 == releaseCount) - status = sem_post(m_pSem); - else - status = sem_post_multiple(m_pSem, releaseCount); -#else - while (releaseCount > 0) - { - status = sem_post(m_pSem); - if (status) - break; - releaseCount--; - } -#endif - - if (status) - { - LZHAM_FAIL("semaphore: sem_post() or sem_post_multiple() failed"); - } - } - - inline bool wait() - { - int status = sem_wait(m_pSem); - - if (status) - { - if (errno != ETIMEDOUT) - { - LZHAM_FAIL("semaphore: sem_wait() or sem_timedwait() failed"); - } - return false; - } - - return true; - } - - private: - sem_t *m_pSem; - char m_name[16]; - }; -#else - class semaphore - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore); - - public: - inline semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL) - { - LZHAM_NOTE_UNUSED(maximumCount), LZHAM_NOTE_UNUSED(pName); - LZHAM_ASSERT(maximumCount >= initialCount); - if (sem_init(&m_sem, 0, initialCount)) - { - LZHAM_FAIL("semaphore: sem_init() failed"); - } - } - - inline ~semaphore() - { - sem_destroy(&m_sem); - } - - inline void release(long releaseCount = 1) - { - LZHAM_ASSERT(releaseCount >= 1); - - int status = 0; -#ifdef WIN32 - if (1 == releaseCount) - status = sem_post(&m_sem); - else - status = sem_post_multiple(&m_sem, releaseCount); -#else - while (releaseCount > 0) - { - status = sem_post(&m_sem); - if (status) - break; - releaseCount--; - } -#endif - - if (status) - { - LZHAM_FAIL("semaphore: sem_post() or sem_post_multiple() failed"); - } - } - - inline bool wait(uint32 milliseconds = cUINT32_MAX) - { - int status; - if (milliseconds == cUINT32_MAX) - { - status = sem_wait(&m_sem); - } - else - { - struct timespec interval; - interval.tv_sec = milliseconds / 1000; - interval.tv_nsec = (milliseconds % 1000) * 1000000L; - status = sem_timedwait(&m_sem, &interval); - } - - if (status) - { - if (errno != ETIMEDOUT) - { - LZHAM_FAIL("semaphore: sem_wait() or sem_timedwait() failed"); - } - return false; - } - - return true; - } - - private: - sem_t m_sem; - }; -#endif - - // spinlock - -#ifdef __APPLE__ - class spinlock - { - public: - inline spinlock() : m_lock(0) - { - } - - inline ~spinlock() - { - } - - inline void lock() - { - OSSpinLockLock(&m_lock); - } - - inline void unlock() - { - OSSpinLockUnlock(&m_lock); - } - - private: - - OSSpinLock m_lock; - }; -#else - class spinlock - { - public: - inline spinlock() - { - if (pthread_spin_init(&m_spinlock, 0)) - { - LZHAM_FAIL("spinlock: pthread_spin_init() failed"); - } - } - - inline ~spinlock() - { - pthread_spin_destroy(&m_spinlock); - } - - inline void lock() - { - if (pthread_spin_lock(&m_spinlock)) - { - LZHAM_FAIL("spinlock: pthread_spin_lock() failed"); - } - } - - inline void unlock() - { - if (pthread_spin_unlock(&m_spinlock)) - { - LZHAM_FAIL("spinlock: pthread_spin_unlock() failed"); - } - } - - private: - pthread_spinlock_t m_spinlock; - }; -#endif // __APPLE__ - - // Thread safe stack - - template - class tsstack - { - public: - inline tsstack(lzham_malloc_context malloc_context) : - m_top(0) - { - LZHAM_NOTE_UNUSED(malloc_context); - } - - inline ~tsstack() - { - } - - inline void clear() - { - m_spinlock.lock(); - m_top = 0; - m_spinlock.unlock(); - } - - inline bool try_push(const T& obj) - { - bool result = false; - m_spinlock.lock(); - if (m_top < (int)cMaxSize) - { - m_stack[m_top++] = obj; - result = true; - } - m_spinlock.unlock(); - return result; - } - - inline bool pop(T& obj) - { - bool result = false; - m_spinlock.lock(); - if (m_top > 0) - { - obj = m_stack[--m_top]; - result = true; - } - m_spinlock.unlock(); - return result; - } - - private: - spinlock m_spinlock; - T m_stack[cMaxSize]; - int m_top; - }; - - // Simple task pool - - class task_pool - { - public: - task_pool(lzham_malloc_context malloc_context); - task_pool(lzham_malloc_context malloc_context, uint num_threads); - ~task_pool(); - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - enum { cMaxThreads = LZHAM_MAX_HELPER_THREADS }; - bool init(uint num_threads); - void deinit(); - - inline uint get_num_threads() const { return m_num_threads; } - inline uint get_num_outstanding_tasks() const { return static_cast(m_num_outstanding_tasks); } - - // C-style task callback - typedef void (*task_callback_func)(uint64 data, void* pData_ptr); - bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL); - - class executable_task - { - public: - virtual void execute_task(uint64 data, void* pData_ptr) = 0; - }; - - // It's the caller's responsibility to delete pObj within the execute_task() method, if needed! - bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL); - - template - inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL); - - template - inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL); - - void join(); - - private: - struct task - { - inline task() : m_data(0), m_pData_ptr(NULL), m_pObj(NULL), m_flags(0) { } - - uint64 m_data; - void* m_pData_ptr; - - union - { - task_callback_func m_callback; - executable_task* m_pObj; - }; - - uint m_flags; - }; - - tsstack m_task_stack; - - uint m_num_threads; - pthread_t m_threads[cMaxThreads]; - - semaphore m_tasks_available; - - lzham_malloc_context m_malloc_context; - - enum task_flags - { - cTaskFlagObject = 1 - }; - - volatile atomic32_t m_num_outstanding_tasks; - volatile atomic32_t m_exit_flag; - - void process_task(task& tsk); - - static void* thread_func(void *pContext); - }; - - enum object_task_flags - { - cObjectTaskFlagDefault = 0, - cObjectTaskFlagDeleteAfterExecution = 1 - }; - - template - class object_task : public task_pool::executable_task - { - public: - object_task(lzham_malloc_context malloc_context, uint flags = cObjectTaskFlagDefault) : - m_malloc_context(malloc_context), - m_pObject(NULL), - m_pMethod(NULL), - m_flags(flags) - { - } - - typedef void (T::*object_method_ptr)(uint64 data, void* pData_ptr); - - object_task(lzham_malloc_context malloc_context, T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) : - m_malloc_context(malloc_context), - m_pObject(pObject), - m_pMethod(pMethod), - m_flags(flags) - { - LZHAM_ASSERT(pObject && pMethod); - } - - void init(lzham_malloc_context malloc_context, T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) - { - LZHAM_ASSERT(pObject && pMethod); - - m_malloc_context = malloc_context; - m_pObject = pObject; - m_pMethod = pMethod; - m_flags = flags; - } - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - T* get_object() const { return m_pObject; } - object_method_ptr get_method() const { return m_pMethod; } - - virtual void execute_task(uint64 data, void* pData_ptr) - { - (m_pObject->*m_pMethod)(data, pData_ptr); - - if (m_flags & cObjectTaskFlagDeleteAfterExecution) - lzham_delete(m_malloc_context, this); - } - - protected: - lzham_malloc_context m_malloc_context; - T* m_pObject; - - object_method_ptr m_pMethod; - - uint m_flags; - }; - - template - inline bool task_pool::queue_object_task(S* pObject, T pObject_method, uint64 data, void* pData_ptr) - { - object_task *pTask = lzham_new< object_task >(m_malloc_context, m_malloc_context, pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution); - if (!pTask) - return false; - return queue_task(pTask, data, pData_ptr); - } - - template - inline bool task_pool::queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pObject); - LZHAM_ASSERT(num_tasks); - if (!num_tasks) - return true; - - bool status = true; - - uint total_to_release = 0; - - for (int i = num_tasks - 1; i >= 0; --i) - { - task tsk; - - tsk.m_pObj = lzham_new< object_task >(m_malloc_context, m_malloc_context, pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution); - if (!tsk.m_pObj) - { - status = false; - break; - } - - tsk.m_data = first_data + i; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = cTaskFlagObject; - - if (!m_task_stack.try_push(tsk)) - { - status = false; - break; - } - - total_to_release++; - } - - if (total_to_release) - { - atomic_add32(&m_num_outstanding_tasks, total_to_release); - - m_tasks_available.release(total_to_release); - } - - return status; - } - - // Sleep - - inline void lzham_sleep(unsigned int milliseconds) - { -#ifdef WIN32 - struct timespec interval; - interval.tv_sec = milliseconds / 1000; - interval.tv_nsec = (milliseconds % 1000) * 1000000L; - pthread_delay_np(&interval); -#else - while (milliseconds) - { - int msecs_to_sleep = LZHAM_MIN(milliseconds, 1000); - usleep(msecs_to_sleep * 1000); - milliseconds -= msecs_to_sleep; - } -#endif - } - - // Returns number of helper threads we can add to the process on the current system (i.e. for a 4 CPU system this returns 3). - uint lzham_get_max_helper_threads(); - -} // namespace lzham - -#endif // LZHAM_USE_PTHREADS_API diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_threading.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_threading.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_threading.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_threading.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -// File: lzham_threading.h -// See Copyright Notice and license at the end of include/lzham.h - -#if LZHAM_USE_WIN32_API - #include "lzham_win32_threading.h" -#elif LZHAM_USE_PTHREADS_API - #include "lzham_pthreads_threading.h" -#else - #include "lzham_null_threading.h" -#endif - - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -// File: lzham_task_pool_win32.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_win32_threading.h" -#include "lzham_timer.h" -#include "lzham_lzcomp_internal.h" -#include - -#if LZHAM_USE_WIN32_API - -namespace lzham -{ - task_pool::task_pool(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_task_stack(malloc_context), - m_num_threads(0), - m_tasks_available(0, 32767), - m_num_outstanding_tasks(0), - m_exit_flag(false) - { - utils::zero_object(m_threads); - } - - task_pool::task_pool(lzham_malloc_context malloc_context, uint num_threads) : - m_malloc_context(malloc_context), - m_task_stack(malloc_context), - m_num_threads(0), - m_tasks_available(0, 32767), - m_num_outstanding_tasks(0), - m_exit_flag(false) - { - utils::zero_object(m_threads); - - bool status = init(num_threads); - LZHAM_VERIFY(status); - } - - task_pool::~task_pool() - { - deinit(); - } - - bool task_pool::init(uint num_threads) - { - LZHAM_ASSERT(num_threads <= cMaxThreads); - num_threads = math::minimum(num_threads, cMaxThreads); - - deinit(); - - bool succeeded = true; - - m_num_threads = 0; - while (m_num_threads < num_threads) - { - m_threads[m_num_threads] = (HANDLE)_beginthreadex(NULL, 32768, thread_func, this, 0, NULL); - LZHAM_ASSERT(m_threads[m_num_threads] != 0); - - if (!m_threads[m_num_threads]) - { - succeeded = false; - LZHAM_LOG_ERROR(10000); - break; - } - - m_num_threads++; - } - - if (!succeeded) - { - deinit(); - return false; - } - - return true; - } - - void task_pool::deinit() - { - if (m_num_threads) - { - join(); - - atomic_exchange32(&m_exit_flag, true); - - m_tasks_available.release(m_num_threads); - - for (uint i = 0; i < m_num_threads; i++) - { - if (m_threads[i]) - { - for ( ; ; ) - { - DWORD result = WaitForSingleObject(m_threads[i], 30000); - if ((result == WAIT_OBJECT_0) || (result == WAIT_ABANDONED)) - break; - } - - CloseHandle(m_threads[i]); - m_threads[i] = NULL; - } - } - - m_num_threads = 0; - - atomic_exchange32(&m_exit_flag, false); - } - - m_task_stack.clear(); - m_num_outstanding_tasks = 0; - } - - bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pFunc); - - task tsk; - tsk.m_callback = pFunc; - tsk.m_data = data; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = 0; - - if (!m_task_stack.try_push(tsk)) - { - LZHAM_LOG_ERROR(10001); - return false; - } - - atomic_increment32(&m_num_outstanding_tasks); - - m_tasks_available.release(1); - - return true; - } - - // It's the object's responsibility to delete pObj within the execute_task() method, if needed! - bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pObj); - - task tsk; - tsk.m_pObj = pObj; - tsk.m_data = data; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = cTaskFlagObject; - - if (!m_task_stack.try_push(tsk)) - { - LZHAM_LOG_ERROR(10002); - return false; - } - - atomic_increment32(&m_num_outstanding_tasks); - - m_tasks_available.release(1); - - return true; - } - - void task_pool::process_task(task& tsk) - { - if (tsk.m_flags & cTaskFlagObject) - tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr); - else - tsk.m_callback(tsk.m_data, tsk.m_pData_ptr); - - atomic_decrement32(&m_num_outstanding_tasks); - } - - void task_pool::join() - { - while (atomic_add32(&m_num_outstanding_tasks, 0) > 0) - { - task tsk; - if (m_task_stack.pop(tsk)) - { - process_task(tsk); - } - else - { - lzham_sleep(1); - } - } - } - - unsigned __stdcall task_pool::thread_func(void* pContext) - { - task_pool* pPool = static_cast(pContext); - - for ( ; ; ) - { - if (!pPool->m_tasks_available.wait()) - break; - - if (pPool->m_exit_flag) - break; - - task tsk; - if (pPool->m_task_stack.pop(tsk)) - { - pPool->process_task(tsk); - } - } - - _endthreadex(0); - return 0; - } - - static uint g_num_processors; - - uint lzham_get_max_helper_threads() - { - if (!g_num_processors) - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - g_num_processors = system_info.dwNumberOfProcessors; - } - - if (g_num_processors > 1) - { - // use all CPU's - return LZHAM_MIN((uint)task_pool::cMaxThreads, g_num_processors - 1); - } - - return 0; - } - -} // namespace lzham - -#endif // LZHAM_USE_WIN32_API diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzham_win32_threading.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,387 +0,0 @@ -// File: lzham_task_pool_win32.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if LZHAM_USE_WIN32_API - -#if LZHAM_NO_ATOMICS -#error No atomic operations defined in lzham_platform.h! -#endif - -namespace lzham -{ - class semaphore - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(semaphore); - - public: - semaphore(long initialCount = 0, long maximumCount = 1, const char* pName = NULL) - { - m_handle = CreateSemaphoreA(NULL, initialCount, maximumCount, pName); - if (NULL == m_handle) - { - LZHAM_LOG_ERROR(10004); - LZHAM_FAIL("semaphore: CreateSemaphore() failed"); - } - } - - ~semaphore() - { - if (m_handle) - { - CloseHandle(m_handle); - m_handle = NULL; - } - } - - inline HANDLE get_handle(void) const { return m_handle; } - - void release(long releaseCount = 1) - { - if (0 == ReleaseSemaphore(m_handle, releaseCount, NULL)) - { - LZHAM_LOG_ERROR(10005); - LZHAM_FAIL("semaphore: ReleaseSemaphore() failed"); - } - } - - bool wait(uint32 milliseconds = cUINT32_MAX) - { - LZHAM_ASSUME(INFINITE == cUINT32_MAX); - - DWORD result = WaitForSingleObject(m_handle, milliseconds); - - if (WAIT_FAILED == result) - { - LZHAM_LOG_ERROR(10003); - LZHAM_FAIL("semaphore: WaitForSingleObject() failed"); - } - - return WAIT_OBJECT_0 == result; - } - - private: - HANDLE m_handle; - }; - - template - class tsstack - { - public: - inline tsstack(lzham_malloc_context malloc_context, bool use_freelist = true) : - m_malloc_context(malloc_context), - m_use_freelist(use_freelist) - { - LZHAM_VERIFY(((ptr_bits_t)this & (LZHAM_GET_ALIGNMENT(tsstack) - 1)) == 0); - InitializeSListHead(&m_stack_head); - InitializeSListHead(&m_freelist_head); - } - - inline ~tsstack() - { - clear(); - } - - inline void clear() - { - for ( ; ; ) - { - node* pNode = (node*)InterlockedPopEntrySList(&m_stack_head); - if (!pNode) - break; - - LZHAM_MEMORY_IMPORT_BARRIER - - helpers::destruct(&pNode->m_obj); - - lzham_free(m_malloc_context, pNode); - } - - flush_freelist(); - } - - inline void flush_freelist() - { - if (!m_use_freelist) - return; - - for ( ; ; ) - { - node* pNode = (node*)InterlockedPopEntrySList(&m_freelist_head); - if (!pNode) - break; - - LZHAM_MEMORY_IMPORT_BARRIER - - lzham_free(m_malloc_context, pNode); - } - } - - inline bool try_push(const T& obj) - { - node* pNode = alloc_node(); - if (!pNode) - return false; - - helpers::construct(&pNode->m_obj, obj); - - LZHAM_MEMORY_EXPORT_BARRIER - - InterlockedPushEntrySList(&m_stack_head, &pNode->m_slist_entry); - - return true; - } - - inline bool pop(T& obj) - { - node* pNode = (node*)InterlockedPopEntrySList(&m_stack_head); - if (!pNode) - return false; - - LZHAM_MEMORY_IMPORT_BARRIER - - obj = pNode->m_obj; - - helpers::destruct(&pNode->m_obj); - - free_node(pNode); - - return true; - } - - private: - SLIST_HEADER m_stack_head; - SLIST_HEADER m_freelist_head; - - struct node - { - SLIST_ENTRY m_slist_entry; - T m_obj; - }; - - lzham_malloc_context m_malloc_context; - - bool m_use_freelist; - - inline node* alloc_node() - { - node* pNode = m_use_freelist ? (node*)InterlockedPopEntrySList(&m_freelist_head) : NULL; - - if (!pNode) - pNode = (node*)lzham_malloc(m_malloc_context, sizeof(node)); - - return pNode; - } - - inline void free_node(node* pNode) - { - if (m_use_freelist) - InterlockedPushEntrySList(&m_freelist_head, &pNode->m_slist_entry); - else - lzham_free(m_malloc_context, pNode); - } - }; - - class task_pool - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(task_pool); - - public: - task_pool(lzham_malloc_context malloc_context); - task_pool(lzham_malloc_context malloc_context, uint num_threads); - ~task_pool(); - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - enum { cMaxThreads = LZHAM_MAX_HELPER_THREADS }; - bool init(uint num_threads); - void deinit(); - - inline uint get_num_threads() const { return m_num_threads; } - inline uint get_num_outstanding_tasks() const { return m_num_outstanding_tasks; } - - // C-style task callback - typedef void (*task_callback_func)(uint64 data, void* pData_ptr); - bool queue_task(task_callback_func pFunc, uint64 data = 0, void* pData_ptr = NULL); - - class executable_task - { - public: - virtual void execute_task(uint64 data, void* pData_ptr) = 0; - }; - - // It's the caller's responsibility to delete pObj within the execute_task() method, if needed! - bool queue_task(executable_task* pObj, uint64 data = 0, void* pData_ptr = NULL); - - template - inline bool queue_object_task(S* pObject, T pObject_method, uint64 data = 0, void* pData_ptr = NULL); - - template - inline bool queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr = NULL); - - void join(); - - private: - struct task - { - //inline task() : m_data(0), m_pData_ptr(NULL), m_pObj(NULL), m_flags(0) { } - - uint64 m_data; - void* m_pData_ptr; - - union - { - task_callback_func m_callback; - executable_task* m_pObj; - }; - - uint m_flags; - }; - - lzham_malloc_context m_malloc_context; - - tsstack m_task_stack; - - uint m_num_threads; - HANDLE m_threads[cMaxThreads]; - - semaphore m_tasks_available; - - enum task_flags - { - cTaskFlagObject = 1 - }; - - volatile atomic32_t m_num_outstanding_tasks; - volatile atomic32_t m_exit_flag; - - void process_task(task& tsk); - - static unsigned __stdcall thread_func(void* pContext); - }; - - enum object_task_flags - { - cObjectTaskFlagDefault = 0, - cObjectTaskFlagDeleteAfterExecution = 1 - }; - - template - class object_task : public task_pool::executable_task - { - public: - object_task(lzham_malloc_context malloc_context, uint flags = cObjectTaskFlagDefault) : - m_malloc_context(malloc_context), - m_pObject(NULL), - m_pMethod(NULL), - m_flags(flags) - { - } - - typedef void (T::*object_method_ptr)(uint64 data, void* pData_ptr); - - object_task(lzham_malloc_context malloc_context, T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) : - m_malloc_context(malloc_context), - m_pObject(pObject), - m_pMethod(pMethod), - m_flags(flags) - { - LZHAM_ASSERT(pObject && pMethod); - } - - void init(lzham_malloc_context malloc_context, T* pObject, object_method_ptr pMethod, uint flags = cObjectTaskFlagDefault) - { - LZHAM_ASSERT(pObject && pMethod); - - m_malloc_context = malloc_context; - m_pObject = pObject; - m_pMethod = pMethod; - m_flags = flags; - } - - T* get_object() const { return m_pObject; } - object_method_ptr get_method() const { return m_pMethod; } - - virtual void execute_task(uint64 data, void* pData_ptr) - { - (m_pObject->*m_pMethod)(data, pData_ptr); - - if (m_flags & cObjectTaskFlagDeleteAfterExecution) - lzham_delete(m_malloc_context, this); - } - - protected: - lzham_malloc_context m_malloc_context; - T* m_pObject; - - object_method_ptr m_pMethod; - - uint m_flags; - }; - - template - inline bool task_pool::queue_object_task(S* pObject, T pObject_method, uint64 data, void* pData_ptr) - { - object_task *pTask = lzham_new< object_task >(m_malloc_context, m_malloc_context, pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution); - if (!pTask) - return false; - return queue_task(pTask, data, pData_ptr); - } - - template - inline bool task_pool::queue_multiple_object_tasks(S* pObject, T pObject_method, uint64 first_data, uint num_tasks, void* pData_ptr) - { - LZHAM_ASSERT(m_num_threads); - LZHAM_ASSERT(pObject); - LZHAM_ASSERT(num_tasks); - if (!num_tasks) - return true; - - bool status = true; - - uint total_to_release = 0; - - for (int i = num_tasks - 1; i >= 0; --i) - { - task tsk; - - tsk.m_pObj = lzham_new< object_task >(m_malloc_context, m_malloc_context, pObject, pObject_method, cObjectTaskFlagDeleteAfterExecution); - if (!tsk.m_pObj) - { - status = false; - break; - } - - tsk.m_data = first_data + i; - tsk.m_pData_ptr = pData_ptr; - tsk.m_flags = cTaskFlagObject; - - if (!m_task_stack.try_push(tsk)) - { - status = false; - break; - } - - total_to_release++; - } - - if (total_to_release) - { - atomic_add32(&m_num_outstanding_tasks, total_to_release); - - m_tasks_available.release(total_to_release); - } - - return status; - } - - inline void lzham_sleep(unsigned int milliseconds) - { - Sleep(milliseconds); - } - - uint lzham_get_max_helper_threads(); - -} // namespace lzham - -#endif // LZHAM_USE_WIN32_API diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzhamcomp.vcxproj p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzhamcomp.vcxproj --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamcomp/lzhamcomp.vcxproj 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamcomp/lzhamcomp.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {8DA0CD46-791D-48D7-AE92-728338501500} - lzhamcomp - Win32Proj - - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)lib\x86D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x86\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64\ - $(Platform)\$(Configuration)\ - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(ProjectName)_x64 - $(ProjectName)_x86 - $(ProjectName)_x86D - $(ProjectName)_x64D - - - - Disabled - ..\include;..\lzhamdecomp;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - EditAndContinue - - - $(OutDir)$(ProjectName)_x86D.lib - - - - - X64 - - - Disabled - ..\include;..\lzhamdecomp;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64D.lib - - - - - Full - AnySuitable - true - Speed - true - ..\include;..\lzhamdecomp;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - StreamingSIMDExtensions - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x86.lib - - - - - X64 - - - Full - AnySuitable - true - Speed - true - ..\include;..\lzhamdecomp;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/CMakeLists.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/CMakeLists.txt --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/CMakeLists.txt 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -PROJECT(lzhamdecomp) -cmake_minimum_required(VERSION 2.8) -option(BUILD_X64 "build 64-bit" TRUE) - -message("Initial BUILD_X64=${BUILD_X64}") -message("Initial CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") - -if( NOT CMAKE_BUILD_TYPE ) - set( CMAKE_BUILD_TYPE Release ) -endif( NOT CMAKE_BUILD_TYPE ) - -message( ${PROJECT_NAME} " build type: " ${CMAKE_BUILD_TYPE} ) - -if (BUILD_X64) - message("Building 64-bit") -else() - message("Building 32-bit") -endif(BUILD_X64) - -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -Wextra") - -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra -O3 -fomit-frame-pointer -fexpensive-optimizations") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -Wextra") - -set(SRC_LIST - ../include/lzham_dynamic_lib.h - ../include/lzham_static_lib.h - ../include/lzham.h - ../include/lzham_exports.inc - ../include/zlib.h - lzham_assert.cpp - lzham_assert.h - lzham_checksum.cpp - lzham_checksum.h - lzham_config.h - lzham_core.h - lzham_decomp.h - lzham_helpers.h - lzham_huffman_codes.cpp - lzham_huffman_codes.h - lzham_lzdecompbase.cpp - lzham_lzdecompbase.h - lzham_lzdecomp.cpp - lzham_math.h - lzham_mem.cpp - lzham_mem.h - lzham_platform.cpp - lzham_platform.h - lzham_prefix_coding.cpp - lzham_prefix_coding.h - lzham_symbol_codec.cpp - lzham_symbol_codec.h - lzham_timer.cpp - lzham_timer.h - lzham_traits.h - lzham_types.h - lzham_utils.h - lzham_vector.cpp - lzham_vector.h) - -# -fno-strict-aliasing is *required* to compile LZHAM -set(GCC_COMPILE_FLAGS "-fno-strict-aliasing -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64") - -if (NOT BUILD_X64) - set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -m32") -endif() - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_LINK_FLAGS}") - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GCC_COMPILE_FLAGS} -DNDEBUG") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COMPILE_FLAGS} -D_DEBUG") - -include_directories( - ${PROJECT_SOURCE_DIR}/../lzhamdecomp - ${PROJECT_SOURCE_DIR}/../include) - -#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin_linux) - -add_library(${PROJECT_NAME} ${SRC_LIST}) -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin) diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -// File: lzham_assert.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" - -static bool g_fail_exceptions; -static bool g_exit_on_failure = true; - -void lzham_enable_fail_exceptions(bool enabled) -{ - g_fail_exceptions = enabled; -} - -void lzham_assert(const char* pExp, const char* pFile, unsigned line) -{ - char buf[512]; - - sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp); - - lzham_output_debug_string(buf); - - printf("%s", buf); - - if (lzham_is_debugger_present()) - lzham_debug_break(); -} - -void lzham_fail(const char* pExp, const char* pFile, unsigned line) -{ - char buf[512]; - - sprintf_s(buf, sizeof(buf), "%s(%u): Failure: \"%s\"\n", pFile, line, pExp); - - lzham_output_debug_string(buf); - - printf("%s", buf); - - if (lzham_is_debugger_present()) - lzham_debug_break(); - -#if LZHAM_USE_WIN32_API - if (g_fail_exceptions) - RaiseException(LZHAM_FAIL_EXCEPTION_CODE, 0, 0, NULL); - else -#endif - if (g_exit_on_failure) - exit(EXIT_FAILURE); -} - -void lzham_trace(const char* pFmt, va_list args) -{ - if (lzham_is_debugger_present()) - { - char buf[512]; - vsprintf_s(buf, sizeof(buf), pFmt, args); - - lzham_output_debug_string(buf); - } -} - -void lzham_trace(const char* pFmt, ...) -{ - va_list args; - va_start(args, pFmt); - lzham_trace(pFmt, args); - va_end(args); -} - -#if LZHAM_ERROR_LOGGING -#if LZHAM_VERBOSE_ERROR_LOGGING -void lzham_log_error(const char *pFunc, const char *pFile, int line, const char *pMsg, int idx) -{ - fprintf(stderr, "\nlzham_log_error: %i %s file: %s line: %u func %s\n", idx, pMsg ? pMsg : "", pFile, line, pFunc); -} -#else -void lzham_log_error(int idx) -{ - fprintf(stderr, "\nlzham_log_error: %i\n", idx); -} -#endif -#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -// File: lzham_assert.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if LZHAM_ERROR_LOGGING - #if LZHAM_VERBOSE_ERROR_LOGGING - #define LZHAM_LOG_ERROR(idx) do { lzham_log_error(__FUNCTION__, __FILE__, __LINE__, "", idx); } while(0) - #else - #define LZHAM_LOG_ERROR(idx) do { lzham_log_error(idx); } while(0) - #endif -#else - #define LZHAM_LOG_ERROR(idx) -#endif - -#if LZHAM_ERROR_LOGGING - #if LZHAM_VERBOSE_ERROR_LOGGING - void lzham_log_error(const char *pFunc, const char *pFile, int line, const char *pMsg, int idx); - #else - void lzham_log_error(int idx); - #endif -#endif - -const unsigned int LZHAM_FAIL_EXCEPTION_CODE = 256U; -void lzham_enable_fail_exceptions(bool enabled); - -void lzham_assert(const char* pExp, const char* pFile, unsigned line); -void lzham_fail(const char* pExp, const char* pFile, unsigned line); - -#ifdef NDEBUG - #define LZHAM_ASSERT(x) ((void)0) -#else - #define LZHAM_ASSERT(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) ) - #define LZHAM_ASSERTS_ENABLED 1 -#endif - -#define LZHAM_VERIFY(_exp) (void)( (!!(_exp)) || (lzham_assert(#_exp, __FILE__, __LINE__), 0) ) - -#define LZHAM_FAIL(msg) do { lzham_fail(#msg, __FILE__, __LINE__); } while(0) - -#define LZHAM_ASSERT_OPEN_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x < h)) -#define LZHAM_ASSERT_CLOSED_RANGE(x, l, h) LZHAM_ASSERT((x >= l) && (x <= h)) - -void lzham_trace(const char* pFmt, va_list args); -void lzham_trace(const char* pFmt, ...); - -// Borrowed from boost libraries. -template struct assume_failure; -template <> struct assume_failure { enum { blah = 1 }; }; -template struct assume_try { }; - -#define LZHAM_JOINER_FINAL(a, b) a##b -#define LZHAM_JOINER(a, b) LZHAM_JOINER_FINAL(a, b) -#define LZHAM_JOIN(a, b) LZHAM_JOINER(a, b) -#if defined(__GNUC__) - #define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__) __attribute__((unused)) -#else - #define LZHAM_ASSUME(p) typedef assume_try < sizeof(assume_failure< (bool)(p) > ) > LZHAM_JOIN(assume_typedef, __COUNTER__) -#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -// File: lzham_checksum.cpp -#include "lzham_core.h" -#include "lzham_checksum.h" - -namespace lzham -{ - // Originally from the public domain stb.h header. - uint adler32(const void* pBuf, size_t buflen, uint adler32) - { - if (!pBuf) - return cInitAdler32; - - const uint8* buffer = static_cast(pBuf); - - const unsigned long ADLER_MOD = 65521; - unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; - size_t blocklen; - unsigned long i; - - blocklen = buflen % 5552; - while (buflen) - { - for (i=0; i + 7 < blocklen; i += 8) - { - s1 += buffer[0], s2 += s1; - s1 += buffer[1], s2 += s1; - s1 += buffer[2], s2 += s1; - s1 += buffer[3], s2 += s1; - s1 += buffer[4], s2 += s1; - s1 += buffer[5], s2 += s1; - s1 += buffer[6], s2 += s1; - s1 += buffer[7], s2 += s1; - - buffer += 8; - } - - for (; i < blocklen; ++i) - s1 += *buffer++, s2 += s1; - - s1 %= ADLER_MOD, s2 %= ADLER_MOD; - buflen -= blocklen; - blocklen = 5552; - } - return static_cast((s2 << 16) + s1); - } - - // Karl Malbrain's compact CRC-32, with pre and post conditioning. - // See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": - // http://www.geocities.com/malbrain/ - static const lzham_uint32 s_crc32[16] = - { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - - uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len) - { - if (!ptr) - return cInitCRC32; - - crc = ~crc; - while (buf_len--) - { - lzham_uint8 b = *ptr++; - crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)]; - crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)]; - } - return ~crc; - } - - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -// File: lzham_checksum.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - const uint cInitAdler32 = 1U; - uint adler32(const void* pBuf, size_t buflen, uint adler32 = cInitAdler32); - - const uint cInitCRC32 = 0U; - uint crc32(uint crc, const lzham_uint8 *ptr, size_t buf_len); - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_config.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_config.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_config.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -// File: lzham_config.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if defined(_DEBUG) || defined(DEBUG) - #define LZHAM_BUILD_DEBUG - - #ifndef DEBUG - #define DEBUG - #endif -#else - #define LZHAM_BUILD_RELEASE - - #ifndef NDEBUG - #define NDEBUG - #endif - - #ifdef DEBUG - #error DEBUG cannot be defined in LZHAM_BUILD_RELEASE - #endif -#endif - -// HACK HACK -#define LZHAM_BUFFERED_PRINTF 0 -#define LZHAM_PERF_SECTIONS 0 \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_core.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_core.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_core.h 2016-02-25 20:03:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_core.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -// File: lzham_core.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if defined(_MSC_VER) - #pragma warning (disable: 4127) // conditional expression is constant -#endif - -// If LZHAM_ERROR_LOGGING is 1, LZHAM will write a short internal error codes to stderr when something goes wrong. These codes can be very useful for postmortem debugging. -#ifndef LZHAM_ERROR_LOGGING - #define LZHAM_ERROR_LOGGING 0 -#endif - -// If LZHAM_VERBOSE_ERROR_LOGGING, LZHAM will also write the function, file and line # along with the error code to stderr. -#ifndef LZHAM_VERBOSE_ERROR_LOGGING - #define LZHAM_VERBOSE_ERROR_LOGGING 0 -#endif - -// Enable this when first porting to new platforms - disables all threading and atomic ops in compressor: -//#define LZHAM_ANSI_CPLUSPLUS 1 - -#if defined(__FreeBSD__) || defined(__NetBSD__) - // TODO: I compile and do minimal testing on FreeBSD v10.1 x86, but I haven't enabled threading there yet. (Should be easy because OSX is already supported with threading.) - #define LZHAM_ANSI_CPLUSPLUS 1 -#endif - -#if defined(__APPLE__) && defined(__MACH__) - // Apple OSX and iOS - #include -#endif - -#if defined(_XBOX) && !defined(LZHAM_ANSI_CPLUSPLUS) - // --- X360 - This hasn't been tested since early an alpha. - #include - #define _HAS_EXCEPTIONS 0 - #define NOMINMAX - - #define LZHAM_PLATFORM_X360 1 - #define LZHAM_USE_WIN32_API 1 - #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1 - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #define LZHAM_BIG_ENDIAN_CPU 1 - #define LZHAM_USE_UNALIGNED_INT_LOADS 1 - #define LZHAM_RESTRICT __restrict - #define LZHAM_FORCE_INLINE __forceinline - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 "I64i" - #define LZHAM_PRIu64 "I64u" - -#elif defined(WIN32) && !defined(LZHAM_ANSI_CPLUSPLUS) - // --- Windows: MSVC or MinGW, x86 or x64, Win32 API's for threading and Win32 Interlocked API's or GCC built-ins for atomic ops. - #ifdef NDEBUG - // Ensure checked iterators are disabled. - #define _SECURE_SCL 0 - #define _HAS_ITERATOR_DEBUGGING 0 - #endif - #ifndef _DLL - // If we're using the DLL form of the run-time libs, we're also going to be enabling exceptions because we'll be building CLR apps. - // Otherwise, we disable exceptions for a small speed boost. - #define _HAS_EXCEPTIONS 0 - #endif - #define NOMINMAX - - #ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x500 - #endif - - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - - #include - - #define LZHAM_USE_WIN32_API 1 - - #if defined(__MINGW32__) || defined(__MINGW64__) - #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 - #else - #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 1 - #endif - - #define LZHAM_PLATFORM_PC 1 - - #ifdef _WIN64 - #define LZHAM_PLATFORM_PC_X64 1 - #define LZHAM_64BIT_POINTERS 1 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #else - #define LZHAM_PLATFORM_PC_X86 1 - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #endif - - #define LZHAM_USE_UNALIGNED_INT_LOADS 1 - #define LZHAM_RESTRICT __restrict - #define LZHAM_FORCE_INLINE __forceinline - - #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) - #define LZHAM_USE_MSVC_INTRINSICS 1 - #endif - - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 "I64i" - #define LZHAM_PRIu64 "I64u" - -#elif defined(__APPLE__) && !defined(LZHAM_ANSI_CPLUSPLUS) - // --- Apple: iOS or OSX - #if (TARGET_IPHONE_SIMULATOR == 1) || (TARGET_OS_IPHONE == 1) - #define LZHAM_PLATFORM_PC 0 - - #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) - #define LZHAM_PLATFORM_PC_X64 0 - #define LZHAM_64BIT_POINTERS 1 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #else - #define LZHAM_PLATFORM_PC_X86 0 - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 - #endif - - #define LZHAM_USE_UNALIGNED_INT_LOADS 0 - - #if __BIG_ENDIAN__ - #define LZHAM_BIG_ENDIAN_CPU 1 - #else - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #endif - - #define LZHAM_USE_PTHREADS_API 1 - #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 - - #define LZHAM_RESTRICT - - #if defined(__clang__) - #define LZHAM_FORCE_INLINE inline - #else - #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) - #endif - - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 PRIi64 - #define LZHAM_PRIu64 PRIu64 - - #elif (TARGET_OS_MAC == 1) - #define LZHAM_PLATFORM_PC 1 - - #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) - #define LZHAM_PLATFORM_PC_X64 1 - #define LZHAM_64BIT_POINTERS 1 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #else - #define LZHAM_PLATFORM_PC_X86 1 - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 - #endif - - #define LZHAM_USE_UNALIGNED_INT_LOADS 1 - - #if __BIG_ENDIAN__ - #define LZHAM_BIG_ENDIAN_CPU 1 - #else - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #endif - - #define LZHAM_USE_PTHREADS_API 1 - #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 - - #define LZHAM_RESTRICT - - #if defined(__clang__) - #define LZHAM_FORCE_INLINE inline - #else - #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) - #endif - - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 PRIi64 - #define LZHAM_PRIu64 PRIu64 - #elif - #error TODO: Unknown Apple target - #endif - -#elif (defined(__linux__) || defined(__CYGWIN__) ) && (defined(__i386__) || defined(__x86_64__)) && !defined(LZHAM_ANSI_CPLUSPLUS) - // --- Generic GCC/clang path for x86/x64, clang or GCC, Linux, OSX, FreeBSD or NetBSD, pthreads for threading, GCC built-ins for atomic ops. - #define LZHAM_PLATFORM_PC 1 - - #if defined(_LP64) || defined(__LP64__) || defined(__x86_64__) - // 64-bit build assumes pointers are always 64-bit - #define LZHAM_PLATFORM_PC_X64 1 - #define LZHAM_64BIT_POINTERS 1 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #else - #define LZHAM_PLATFORM_PC_X86 1 - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 - #endif - - #define LZHAM_USE_UNALIGNED_INT_LOADS 1 - - #if __BIG_ENDIAN__ - #define LZHAM_BIG_ENDIAN_CPU 1 - #else - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #endif - - #define LZHAM_USE_PTHREADS_API 1 - #define LZHAM_USE_GCC_ATOMIC_BUILTINS 1 - - #define LZHAM_RESTRICT - - #if defined(__clang__) - #define LZHAM_FORCE_INLINE inline - #else - #define LZHAM_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__)) - #endif - - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 PRIi64 - #define LZHAM_PRIu64 PRIu64 -#else - -#ifndef _MSC_VER - #warning Building as vanilla ANSI-C/C++, multi-threaded compression is disabled! Please configure lzhamdecomp/lzham_core.h. -#endif - - // --- Vanilla ANSI-C/C++ - // No threading support, unaligned loads are NOT okay, no atomic ops. - #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) - #define LZHAM_64BIT_POINTERS 1 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 1 - #else - #define LZHAM_64BIT_POINTERS 0 - #define LZHAM_CPU_HAS_64BIT_REGISTERS 0 - #endif - - #define LZHAM_USE_UNALIGNED_INT_LOADS 0 - - #if __BIG_ENDIAN__ - #define LZHAM_BIG_ENDIAN_CPU 1 - #else - #define LZHAM_LITTLE_ENDIAN_CPU 1 - #endif - - #define LZHAM_USE_GCC_ATOMIC_BUILTINS 0 - #define LZHAM_USE_WIN32_ATOMIC_FUNCTIONS 0 - - #define LZHAM_RESTRICT - #define LZHAM_FORCE_INLINE inline - - #define LZHAM_NOTE_UNUSED(x) (void)x - - #define LZHAM_PRIi64 PRIi64 - #define LZHAM_PRIu64 PRIu64 -#endif - -#if LZHAM_LITTLE_ENDIAN_CPU - const bool c_lzham_little_endian_platform = true; -#else - const bool c_lzham_little_endian_platform = false; -#endif - -const bool c_lzham_big_endian_platform = !c_lzham_little_endian_platform; - -#include -#include -#include -#if !defined(__APPLE__) && !defined(__FreeBSD__) -#include -#endif -#include -#include -#include -#include -#include - -#ifndef _MSC_VER - #ifndef __STDC_FORMAT_MACROS - #define __STDC_FORMAT_MACROS - #endif - // Needed for PRIi64 and PRIu64 - #include -#endif - -#include "lzham.h" -#include "lzham_config.h" -#include "lzham_types.h" -#include "lzham_assert.h" -#include "lzham_platform.h" - -#include "lzham_helpers.h" -#include "lzham_traits.h" -#include "lzham_mem.h" -#include "lzham_math.h" -#include "lzham_utils.h" -#include "lzham_vector.h" diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_decomp.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_decomp.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_decomp.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_decomp.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// File: lzham_decomp.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham.h" - -namespace lzham -{ - void LZHAM_CDECL lzham_lib_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data); - - lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_init(const lzham_decompress_params *pParams); - - lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_reinit(lzham_decompress_state_ptr pState, const lzham_decompress_params *pParams); - - lzham_uint32 LZHAM_CDECL lzham_lib_decompress_deinit(lzham_decompress_state_ptr pState); - - lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress( - lzham_decompress_state_ptr pState, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag); - - lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress_memory(const lzham_decompress_params *pParams, - lzham_uint8* pDst_buf, size_t *pDst_len, - const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32); - - int LZHAM_CDECL lzham_lib_z_inflateInit2(lzham_z_streamp pStream, int window_bits); - int LZHAM_CDECL lzham_lib_z_inflateInit(lzham_z_streamp pStream); - int LZHAM_CDECL lzham_lib_z_inflateReset(lzham_z_streamp pStream); - int LZHAM_CDECL lzham_lib_z_inflate(lzham_z_streamp pStream, int flush); - int LZHAM_CDECL lzham_lib_z_inflateEnd(lzham_z_streamp pStream); - int LZHAM_CDECL lzham_lib_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len); - - const char * LZHAM_CDECL lzham_lib_z_error(int err); - lzham_z_ulong lzham_lib_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len); - lzham_z_ulong LZHAM_CDECL lzham_lib_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len); - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_helpers.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_helpers.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_helpers.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_helpers.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -// File: lzham_helpers.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#define LZHAM_NO_COPY_OR_ASSIGNMENT_OP(c) c(const c&); c& operator= (const c&); - -namespace lzham -{ - namespace helpers - { - template struct rel_ops - { - friend inline bool operator!=(const T& x, const T& y) { return (!(x == y)); } - friend inline bool operator> (const T& x, const T& y) { return (y < x); } - friend inline bool operator<=(const T& x, const T& y) { return (!(y < x)); } - friend inline bool operator>=(const T& x, const T& y) { return (!(x < y)); } - }; - - template - inline T* construct(T* p) - { - return new (static_cast(p)) T; - } - - template - inline T* construct(T* p, const U& init) - { - return new (static_cast(p)) T(init); - } - - template - inline void construct_array(T* p, uint n); - - template - inline void construct_array(T* p, uint n, const U& init) - { - T* q = p + n; - for ( ; p != q; ++p) - new (static_cast(p)) T(init); - } - - template - inline void destruct(T* p) - { - LZHAM_NOTE_UNUSED(p); - p->~T(); - } - - template - inline void destruct_array(T* p, uint n); - - } // namespace helpers - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,286 +0,0 @@ -// File: huffman_codes.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_huffman_codes.h" - -namespace lzham -{ - void code_size_histogram::init(uint num_syms, const uint8* pCodesizes) - { - const uint8 *p = pCodesizes; - - for (uint i = num_syms >> 2; i; --i) - { - uint a = p[0]; - uint b = p[1]; - uint c = p[2]; - uint d = p[3]; - m_num_codes[a]++; - m_num_codes[b]++; - m_num_codes[c]++; - m_num_codes[d]++; - p += 4; - } - - for (uint i = num_syms & 3; i; --i) - m_num_codes[*p++]++; - - LZHAM_ASSERT(static_cast(p - pCodesizes) == num_syms); - } - - struct sym_freq - { - uint m_freq; - uint16 m_left; - uint16 m_right; - - inline bool operator< (const sym_freq& other) const - { - return m_freq > other.m_freq; - } - }; - - static inline sym_freq* radix_sort_syms(uint num_syms, sym_freq* syms0, sym_freq* syms1) - { - const uint cMaxPasses = 2; - uint hist[256 * cMaxPasses]; - - memset(hist, 0, sizeof(hist[0]) * 256 * cMaxPasses); - - { - sym_freq* p = syms0; - sym_freq* q = syms0 + (num_syms >> 1) * 2; - - for ( ; p != q; p += 2) - { - const uint freq0 = p[0].m_freq; - const uint freq1 = p[1].m_freq; - - hist[ freq0 & 0xFF]++; - hist[256 + ((freq0 >> 8) & 0xFF)]++; - - hist[ freq1 & 0xFF]++; - hist[256 + ((freq1 >> 8) & 0xFF)]++; - } - - if (num_syms & 1) - { - const uint freq = p->m_freq; - - hist[ freq & 0xFF]++; - hist[256 + ((freq >> 8) & 0xFF)]++; - } - } - - sym_freq* pCur_syms = syms0; - sym_freq* pNew_syms = syms1; - - const uint total_passes = (hist[256] == num_syms) ? 1 : cMaxPasses; - - for (uint pass = 0; pass < total_passes; pass++) - { - const uint* pHist = &hist[pass << 8]; - - uint offsets[256]; - - uint cur_ofs = 0; - for (uint i = 0; i < 256; i += 2) - { - offsets[i] = cur_ofs; - cur_ofs += pHist[i]; - - offsets[i+1] = cur_ofs; - cur_ofs += pHist[i+1]; - } - - const uint pass_shift = pass << 3; - - sym_freq* p = pCur_syms; - sym_freq* q = pCur_syms + (num_syms >> 1) * 2; - - for ( ; p != q; p += 2) - { - uint c0 = p[0].m_freq; - uint c1 = p[1].m_freq; - - if (pass) - { - c0 >>= 8; - c1 >>= 8; - } - - c0 &= 0xFF; - c1 &= 0xFF; - - if (c0 == c1) - { - uint dst_offset0 = offsets[c0]; - - offsets[c0] = dst_offset0 + 2; - - pNew_syms[dst_offset0] = p[0]; - pNew_syms[dst_offset0 + 1] = p[1]; - } - else - { - uint dst_offset0 = offsets[c0]++; - uint dst_offset1 = offsets[c1]++; - - pNew_syms[dst_offset0] = p[0]; - pNew_syms[dst_offset1] = p[1]; - } - } - - if (num_syms & 1) - { - uint c = ((p->m_freq) >> pass_shift) & 0xFF; - - uint dst_offset = offsets[c]; - offsets[c] = dst_offset + 1; - - pNew_syms[dst_offset] = *p; - } - - sym_freq* t = pCur_syms; - pCur_syms = pNew_syms; - pNew_syms = t; - } - -#if LZHAM_ASSERTS_ENABLED - uint prev_freq = 0; - for (uint i = 0; i < num_syms; i++) - { - LZHAM_ASSERT(!(pCur_syms[i].m_freq < prev_freq)); - prev_freq = pCur_syms[i].m_freq; - } -#endif - - return pCur_syms; - } - - struct huffman_work_tables - { - enum { cMaxInternalNodes = cHuffmanMaxSupportedSyms }; - - sym_freq syms0[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes]; - sym_freq syms1[cHuffmanMaxSupportedSyms + 1 + cMaxInternalNodes]; - -#if !USE_CALCULATE_MINIMUM_REDUNDANCY - uint16 queue[cMaxInternalNodes]; -#endif - }; - - uint get_generate_huffman_codes_table_size() - { - return sizeof(huffman_work_tables); - } - - // calculate_minimum_redundancy() written by Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk November 1996. - static void calculate_minimum_redundancy(int A[], int n) - { - int root; /* next root node to be used */ - int leaf; /* next leaf to be used */ - int next; /* next value to be assigned */ - int avbl; /* number of available nodes */ - int used; /* number of internal nodes */ - int dpth; /* current depth of leaves */ - - /* check for pathological cases */ - if (n==0) { return; } - if (n==1) { A[0] = 0; return; } - - /* first pass, left to right, setting parent pointers */ - A[0] += A[1]; root = 0; leaf = 2; - for (next=1; next < n-1; next++) { - /* select first item for a pairing */ - if (leaf>=n || A[root]=n || (root=0; next--) - A[next] = A[A[next]]+1; - - /* third pass, right to left, setting leaf depths */ - avbl = 1; used = dpth = 0; root = n-2; next = n-1; - while (avbl>0) { - while (root>=0 && A[root]==dpth) { - used++; root--; - } - while (avbl>used) { - A[next--] = dpth; avbl--; - } - avbl = 2*used; dpth++; used = 0; - } - } - - bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret, code_size_histogram &code_size_hist) - { - if ((!num_syms) || (num_syms > cHuffmanMaxSupportedSyms)) - return false; - - huffman_work_tables& state = *static_cast(pContext);; - - uint max_freq = 0; - uint total_freq = 0; - - uint num_used_syms = 0; - for (uint i = 0; i < num_syms; i++) - { - uint freq = pFreq[i]; - - if (!freq) - pCodesizes[i] = 0; - else - { - total_freq += freq; - max_freq = math::maximum(max_freq, freq); - - sym_freq& sf = state.syms0[num_used_syms]; - sf.m_left = (uint16)i; - sf.m_right = cUINT16_MAX; - sf.m_freq = freq; - num_used_syms++; - } - } - - total_freq_ret = total_freq; - - if (num_used_syms == 1) - { - pCodesizes[state.syms0[0].m_left] = 1; - return true; - } - - sym_freq* syms = radix_sort_syms(num_used_syms, state.syms0, state.syms1); - - int x[cHuffmanMaxSupportedSyms]; - for (uint i = 0; i < num_used_syms; i++) - x[i] = syms[i].m_freq; - - calculate_minimum_redundancy(x, num_used_syms); - - uint max_len = 0; - for (uint i = 0; i < num_used_syms; i++) - { - uint len = x[i]; - max_len = math::maximum(len, max_len); - code_size_hist.m_num_codes[LZHAM_MIN(len, (uint)code_size_histogram::cMaxUnlimitedHuffCodeSize)]++; - pCodesizes[syms[i].m_left] = static_cast(len); - } - max_code_size = max_len; - - return true; - } - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// File: lzham_huffman_codes.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - //const uint cHuffmanMaxSupportedSyms = 600; - const uint cHuffmanMaxSupportedSyms = 1024; - - const uint cMaxExpectedHuffCodeSize = 16; - - struct code_size_histogram - { - enum { cMaxUnlimitedHuffCodeSize = 32 }; - uint m_num_codes[cMaxUnlimitedHuffCodeSize + 1]; - - void clear() { utils::zero_object(m_num_codes); } - - void init(uint num_syms, const uint8* pCodesizes); - - inline void init(uint code_size0, uint total_syms0, uint code_size1, uint total_syms1) - { - m_num_codes[code_size0] += total_syms0; - m_num_codes[code_size1] += total_syms1; - } - }; - - uint get_generate_huffman_codes_table_size(); - - bool generate_huffman_codes(void* pContext, uint num_syms, const uint16* pFreq, uint8* pCodesizes, uint& max_code_size, uint& total_freq_ret, code_size_histogram &code_size_hist); - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1586 +0,0 @@ -// File: lzham_lzdecomp.cpp -// See Copyright Notice and license at the end of include/lzham.h -// -// See "Coroutines in C": -// http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html -// Also see "Protothreads - Lightweight, Stackless Threads in C": -// http://www.sics.se/~adam/pt/ -#include "lzham_core.h" -#include "lzham_decomp.h" -#include "lzham_symbol_codec.h" -#include "lzham_checksum.h" -#include "lzham_lzdecompbase.h" - -using namespace lzham; - -// We currently only really need ~35K, adding a few K as a fudge factor. -#define LZHAM_DECOMP_MEMORY_ARENA_SIZE (38*1024) - -namespace lzham -{ - static const uint8 s_literal_next_state[24] = - { - 0, 0, 0, 0, 1, 2, 3, // 0-6: literal states - 4, 5, 6, 4, 5, // 7-11: match states - 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 // 12-23: unused - }; - - static const uint s_huge_match_base_len[4] = { CLZDecompBase::cMaxMatchLen + 1, CLZDecompBase::cMaxMatchLen + 1 + 256, CLZDecompBase::cMaxMatchLen + 1 + 256 + 1024, CLZDecompBase::cMaxMatchLen + 1 + 256 + 1024 + 4096 }; - static const uint8 s_huge_match_code_len[4] = { 8, 10, 12, 16 }; - - struct lzham_decompressor - { - lzham_decompressor(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_codec(malloc_context), - m_lit_table(malloc_context), - m_delta_lit_table(malloc_context), - m_main_table(malloc_context), - m_dist_lsb_table(malloc_context) - { - for (uint i = 0; i < 2; i++) - { - m_rep_len_table[i].set_malloc_context(malloc_context); - m_large_len_table[i].set_malloc_context(malloc_context); - } - } - - void init(); - - template lzham_decompress_status_t decompress(); - - void reset_huff_tables(); - void reset_arith_tables(); - void reset_all_tables(); - void reset_huffman_table_update_rates(); - - lzham_malloc_context m_malloc_context; - - int m_state; - - CLZDecompBase m_lzBase; - symbol_codec m_codec; - - uint32 m_raw_decomp_buf_size; - uint8 *m_pRaw_decomp_buf; - uint8 *m_pDecomp_buf; - uint32 m_decomp_adler32; - - const uint8 *m_pIn_buf; - size_t *m_pIn_buf_size; - uint8 *m_pOut_buf; - size_t *m_pOut_buf_size; - bool m_no_more_input_bytes_flag; - - uint8 *m_pOrig_out_buf; - size_t m_orig_out_buf_size; - - lzham_decompress_params m_params; - - lzham_decompress_status_t m_status; - - quasi_adaptive_huffman_data_model m_lit_table; - quasi_adaptive_huffman_data_model m_delta_lit_table; - quasi_adaptive_huffman_data_model m_main_table; - quasi_adaptive_huffman_data_model m_rep_len_table[2]; - quasi_adaptive_huffman_data_model m_large_len_table[2]; - quasi_adaptive_huffman_data_model m_dist_lsb_table; - - adaptive_bit_model m_is_match_model[CLZDecompBase::cNumStates]; - adaptive_bit_model m_is_rep_model[CLZDecompBase::cNumStates]; - adaptive_bit_model m_is_rep0_model[CLZDecompBase::cNumStates]; - adaptive_bit_model m_is_rep0_single_byte_model[CLZDecompBase::cNumStates]; - adaptive_bit_model m_is_rep1_model[CLZDecompBase::cNumStates]; - adaptive_bit_model m_is_rep2_model[CLZDecompBase::cNumStates]; - - uint m_dst_ofs; - uint m_dst_highwater_ofs; - - uint m_step; - uint m_block_step; - uint m_initial_step; - - uint m_block_index; - - int m_match_hist0; - int m_match_hist1; - int m_match_hist2; - int m_match_hist3; - uint m_cur_state; - - uint m_start_block_dst_ofs; - - uint m_block_type; - - const uint8 *m_pFlush_src; - size_t m_flush_num_bytes_remaining; - size_t m_flush_n; - - uint m_seed_bytes_to_ignore_when_flushing; - - uint m_file_src_file_adler32; - - uint m_rep_lit0; - uint m_match_len; - uint m_match_slot; - uint m_extra_bits; - uint m_num_extra_bits; - - uint m_src_ofs; - const uint8* m_pCopy_src; - uint m_num_raw_bytes_remaining; - - uint m_debug_is_match; - uint m_debug_match_len; - uint m_debug_match_dist; - uint m_debug_lit; - - lzham_decompress_status_t m_z_last_status; - uint m_z_first_call; - uint m_z_has_flushed; - uint m_z_cmf; - uint m_z_flg; - uint m_z_dict_adler32; - - uint m_tmp; - }; - - // Ordinarily I dislike macros like this, but in this case I think using them makes the decompression function easier to follow. - - // Coroutine helpers. - #define LZHAM_CR_INITIAL_STATE 0 - #define LZHAM_CR_BEGIN(state) switch( state ) { case LZHAM_CR_INITIAL_STATE: - #define LZHAM_CR_RETURN(state, result) do { state = __LINE__; return (result); case __LINE__:; } while (0) - #define LZHAM_CR_FINISH } - - // Helpers to save/restore local variables (hopefully CPU registers) to memory. - #define LZHAM_RESTORE_STATE LZHAM_RESTORE_LOCAL_STATE \ - match_hist0 = m_match_hist0; match_hist1 = m_match_hist1; match_hist2 = m_match_hist2; match_hist3 = m_match_hist3; \ - cur_state = m_cur_state; dst_ofs = m_dst_ofs; - - #define LZHAM_SAVE_STATE LZHAM_SAVE_LOCAL_STATE \ - m_match_hist0 = match_hist0; m_match_hist1 = match_hist1; m_match_hist2 = match_hist2; m_match_hist3 = match_hist3; \ - m_cur_state = cur_state; m_dst_ofs = dst_ofs; - - // Helper that coroutine returns to the caller with a request for more input bytes. - #define LZHAM_DECODE_NEEDS_BYTES \ - LZHAM_SAVE_STATE \ - for ( ; ; ) \ - { \ - *m_pIn_buf_size = static_cast(m_codec.decode_get_bytes_consumed()); \ - *m_pOut_buf_size = 0; \ - LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT); \ - m_codec.decode_set_input_buffer(m_pIn_buf, *m_pIn_buf_size, m_pIn_buf, m_no_more_input_bytes_flag); \ - if ((m_codec.m_decode_buf_eof) || (m_codec.m_decode_buf_size)) break; \ - } \ - LZHAM_RESTORE_STATE - - #if LZHAM_PLATFORM_X360 - #define LZHAM_BULK_MEMCPY XMemCpy - #define LZHAM_MEMCPY memcpy - #else - #define LZHAM_BULK_MEMCPY memcpy - #define LZHAM_MEMCPY memcpy - #endif - - // Flush the output buffer/dictionary by doing a coroutine return to the caller. - // Buffered mode only. - #define LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dict_ofs) \ - LZHAM_SAVE_STATE \ - m_pFlush_src = m_pDecomp_buf + m_seed_bytes_to_ignore_when_flushing + m_dst_highwater_ofs; \ - m_flush_num_bytes_remaining = dict_ofs - m_seed_bytes_to_ignore_when_flushing - m_dst_highwater_ofs; \ - m_seed_bytes_to_ignore_when_flushing = 0; \ - m_dst_highwater_ofs = dict_ofs & dict_size_mask; \ - while (m_flush_num_bytes_remaining) \ - { \ - m_flush_n = LZHAM_MIN(m_flush_num_bytes_remaining, *m_pOut_buf_size); \ - if (0 == (m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_COMPUTE_ADLER32)) \ - { \ - LZHAM_BULK_MEMCPY(m_pOut_buf, m_pFlush_src, m_flush_n); \ - } \ - else \ - { \ - size_t copy_ofs = 0; \ - while (copy_ofs < m_flush_n) \ - { \ - const uint cBytesToMemCpyPerIteration = 8192U; \ - size_t bytes_to_copy = LZHAM_MIN((size_t)(m_flush_n - copy_ofs), cBytesToMemCpyPerIteration); \ - LZHAM_MEMCPY(m_pOut_buf + copy_ofs, m_pFlush_src + copy_ofs, bytes_to_copy); \ - m_decomp_adler32 = adler32(m_pFlush_src + copy_ofs, bytes_to_copy, m_decomp_adler32); \ - copy_ofs += bytes_to_copy; \ - } \ - } \ - *m_pIn_buf_size = static_cast(m_codec.decode_get_bytes_consumed()); \ - *m_pOut_buf_size = m_flush_n; \ - LZHAM_CR_RETURN(m_state, m_flush_n ? LZHAM_DECOMP_STATUS_NOT_FINISHED : LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT); \ - m_codec.decode_set_input_buffer(m_pIn_buf, *m_pIn_buf_size, m_pIn_buf, m_no_more_input_bytes_flag); \ - m_pFlush_src += m_flush_n; \ - m_flush_num_bytes_remaining -= m_flush_n; \ - } \ - LZHAM_RESTORE_STATE - - #define LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, result, model) LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) - - //------------------------------------------------------------------------------------------------------------------ - void lzham_decompressor::init() - { - m_lzBase.init_position_slots(m_params.m_dict_size_log2); - -#ifdef LZHAM_LZDEBUG - if (m_pDecomp_buf) - memset(m_pDecomp_buf, 0xCE, 1U << m_params.m_dict_size_log2); -#endif - - m_state = LZHAM_CR_INITIAL_STATE; - m_step = 0; - m_block_step = 0; - m_block_index = 0; - m_initial_step = 0; - - m_dst_ofs = 0; - m_dst_highwater_ofs = 0; - - m_pIn_buf = NULL; - m_pIn_buf_size = NULL; - m_pOut_buf = NULL; - m_pOut_buf_size = NULL; - m_no_more_input_bytes_flag = false; - m_status = LZHAM_DECOMP_STATUS_NOT_FINISHED; - m_pOrig_out_buf = NULL; - m_orig_out_buf_size = 0; - m_decomp_adler32 = cInitAdler32; - m_seed_bytes_to_ignore_when_flushing = 0; - - m_z_last_status = LZHAM_DECOMP_STATUS_NOT_FINISHED; - m_z_first_call = 1; - m_z_has_flushed = 0; - m_z_cmf = 0; - m_z_flg = 0; - m_z_dict_adler32 = 0; - - m_tmp = 0; - - m_match_hist0 = 0; - m_match_hist1 = 0; - m_match_hist2 = 0; - m_match_hist3 = 0; - m_cur_state = 0; - - m_start_block_dst_ofs = 0; - m_block_type = 0; - m_flush_num_bytes_remaining = 0; - m_flush_n = 0; - m_file_src_file_adler32 = 0; - m_rep_lit0 = 0; - m_match_len = 0; - m_match_slot = 0; - m_extra_bits = 0; - m_num_extra_bits = 0; - m_src_ofs = 0; - m_pCopy_src = NULL; - m_num_raw_bytes_remaining = 0; - - m_codec.clear(); - } - - void lzham_decompressor::reset_huff_tables() - { - m_lit_table.reset(); - m_delta_lit_table.reset(); - - m_main_table.reset(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_rep_len_table); i++) - m_rep_len_table[i].reset(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_large_len_table); i++) - m_large_len_table[i].reset(); - - m_dist_lsb_table.reset(); - } - - void lzham_decompressor::reset_arith_tables() - { - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_is_match_model); i++) - m_is_match_model[i].clear(); - - for (uint i = 0; i < CLZDecompBase::cNumStates; i++) - { - m_is_rep_model[i].clear(); - m_is_rep0_model[i].clear(); - m_is_rep0_single_byte_model[i].clear(); - m_is_rep1_model[i].clear(); - m_is_rep2_model[i].clear(); - } - } - - void lzham_decompressor::reset_all_tables() - { - reset_huff_tables(); - - reset_arith_tables(); - } - - void lzham_decompressor::reset_huffman_table_update_rates() - { - m_lit_table.reset_update_rate(); - m_delta_lit_table.reset_update_rate(); - - m_main_table.reset_update_rate(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_rep_len_table); i++) - m_rep_len_table[i].reset_update_rate(); - - for (uint i = 0; i < LZHAM_ARRAY_SIZE(m_large_len_table); i++) - m_large_len_table[i].reset_update_rate(); - - m_dist_lsb_table.reset_update_rate(); - } - - //------------------------------------------------------------------------------------------------------------------ - // Decompression method. Implemented as a coroutine so it can be paused and resumed to support streaming. - //------------------------------------------------------------------------------------------------------------------ - template - lzham_decompress_status_t lzham_decompressor::decompress() - { - // Important: This function is a coroutine. ANY locals variables that need to be preserved across coroutine - // returns must be either be a member variable, or a local which is saved/restored to a member variable at - // the right times. (This makes this function difficult to follow and freaking ugly due to the macros of doom - but hey it works.) - // The most often used variables are in locals so the compiler hopefully puts them into CPU registers. - symbol_codec &codec = m_codec; - const uint dict_size = 1U << m_params.m_dict_size_log2; - const uint dict_size_mask = unbuffered ? UINT_MAX : (dict_size - 1); - - int match_hist0 = 0, match_hist1 = 0, match_hist2 = 0, match_hist3 = 0; - uint cur_state = 0, dst_ofs = 0; - - const size_t out_buf_size = *m_pOut_buf_size; - - uint8* pDst = unbuffered ? reinterpret_cast(m_pOut_buf) : reinterpret_cast(m_pDecomp_buf); - uint8* pDst_end = unbuffered ? (reinterpret_cast(m_pOut_buf) + out_buf_size) : (reinterpret_cast(m_pDecomp_buf) + dict_size); - - LZHAM_SYMBOL_CODEC_DECODE_DECLARE(codec); - -#define LZHAM_SAVE_LOCAL_STATE -#define LZHAM_RESTORE_LOCAL_STATE - - // Important: Do not use any switch() statements below here. - LZHAM_CR_BEGIN(m_state) - - if ((!unbuffered) && (m_params.m_num_seed_bytes)) - { - LZHAM_BULK_MEMCPY(pDst, m_params.m_pSeed_bytes, m_params.m_num_seed_bytes); - dst_ofs += m_params.m_num_seed_bytes; - if (dst_ofs >= dict_size) - dst_ofs = 0; - else - m_seed_bytes_to_ignore_when_flushing = dst_ofs; - } - - if (!m_codec.start_decoding(m_pIn_buf, *m_pIn_buf_size, m_no_more_input_bytes_flag, NULL, NULL)) - { - LZHAM_LOG_ERROR(1020); - return LZHAM_DECOMP_STATUS_FAILED_INITIALIZING; - } - - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - - { - if (m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM) - { - uint check; - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_z_cmf, 8); - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_z_flg, 8); - check = ((m_z_cmf << 8) + m_z_flg) % 31; - if ((check != 0) || ((m_z_cmf & 15) != LZHAM_Z_LZHAM)) - { - LZHAM_LOG_ERROR(1021); - return LZHAM_DECOMP_STATUS_FAILED_BAD_ZLIB_HEADER; - } - if (m_z_flg & 32) - { - if ((!m_params.m_pSeed_bytes) || (unbuffered)) - { - LZHAM_LOG_ERROR(1022); - return LZHAM_DECOMP_STATUS_FAILED_NEED_SEED_BYTES; - } - m_z_dict_adler32 = 0; - for (m_tmp = 0; m_tmp < 4; ++m_tmp) - { - uint n; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, n, 8); - m_z_dict_adler32 = (m_z_dict_adler32 << 8) | n; - } - if (adler32(m_params.m_pSeed_bytes, m_params.m_num_seed_bytes) != m_z_dict_adler32) - { - LZHAM_LOG_ERROR(1023); - return LZHAM_DECOMP_STATUS_FAILED_BAD_SEED_BYTES; - } - } - } - - { - // Was written by lzcompressor::send_configuration(). - //uint tmp; - //LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, tmp, 2); - } - - uint max_update_interval = m_params.m_table_max_update_interval, update_interval_slow_rate = m_params.m_table_update_interval_slow_rate; - if (!max_update_interval && !update_interval_slow_rate) - { - uint rate = m_params.m_table_update_rate; - if (!rate) - rate = LZHAM_DEFAULT_TABLE_UPDATE_RATE; - rate = math::clamp(rate, 1, LZHAM_FASTEST_TABLE_UPDATE_RATE) - 1; - max_update_interval = g_table_update_settings[rate].m_max_update_interval; - update_interval_slow_rate = g_table_update_settings[rate].m_slow_rate; - } - - bool succeeded = m_lit_table.init2(m_malloc_context, false, 256, max_update_interval, update_interval_slow_rate, NULL); - succeeded = succeeded && m_delta_lit_table.assign(m_lit_table); - - succeeded = succeeded && m_main_table.init2(m_malloc_context, false, CLZDecompBase::cLZXNumSpecialLengths + (m_lzBase.m_num_lzx_slots - CLZDecompBase::cLZXLowestUsableMatchSlot) * 8, max_update_interval, update_interval_slow_rate, NULL); - - succeeded = succeeded && m_rep_len_table[0].init2(m_malloc_context, false, CLZDecompBase::cNumHugeMatchCodes + (CLZDecompBase::cMaxMatchLen - CLZDecompBase::cMinMatchLen + 1), max_update_interval, update_interval_slow_rate, NULL); - succeeded = succeeded && m_rep_len_table[1].assign(m_rep_len_table[0]); - - succeeded = succeeded && m_large_len_table[0].init2(m_malloc_context, false, CLZDecompBase::cNumHugeMatchCodes + CLZDecompBase::cLZXNumSecondaryLengths, max_update_interval, update_interval_slow_rate, NULL); - succeeded = succeeded && m_large_len_table[1].assign(m_large_len_table[0]); - - succeeded = succeeded && m_dist_lsb_table.init2(m_malloc_context, false, 16, max_update_interval, update_interval_slow_rate, NULL); - if (!succeeded) - { - LZHAM_LOG_ERROR(1024); - return LZHAM_DECOMP_STATUS_FAILED_INITIALIZING; - } - } - - // Output block loop. - do - { -#ifdef LZHAM_LZDEBUG - uint outer_sync_marker; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, k, 12); - LZHAM_VERIFY(outer_sync_marker == 166); -#endif - - // Decode block type. - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_block_type, CLZDecompBase::cBlockHeaderBits); - - if (m_block_type == CLZDecompBase::cSyncBlock) - { - // Sync block - // Reset either the symbol table update rates, or all statistics, then force a coroutine return to give the caller a chance to handle the output right now. - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_tmp, CLZDecompBase::cBlockFlushTypeBits); - - // See lzcompressor::send_sync_block() (TODO: make these an enum) - if (m_tmp == 1) - reset_huffman_table_update_rates(); - else if (m_tmp == 2) - reset_all_tables(); - - LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec); - - uint n; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, n, 16); - if (n != 0) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1025); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_BAD_SYNC_BLOCK); } - } - - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, n, 16); - if (n != 0xFFFF) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1026); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_BAD_SYNC_BLOCK); } - } - - // See lzcompressor::send_sync_block() (TODO: make these an enum) - if ((m_tmp == 2) || (m_tmp == 3)) - { - // It's a sync or full flush, so immediately give caller whatever output we have. Also gives the caller a chance to reposition the input stream ptr somewhere else before continuing. - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - - if ((!unbuffered) && (dst_ofs)) - { - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dst_ofs); - } - else - { - if (unbuffered) - { - LZHAM_ASSERT(dst_ofs >= m_dst_highwater_ofs); - } - else - { - LZHAM_ASSERT(!m_dst_highwater_ofs); - } - - // unbuffered, or dst_ofs==0 - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = dst_ofs - m_dst_highwater_ofs; - - // Partial/sync flushes in unbuffered mode details: - // We assume the caller doesn't move the output buffer between calls AND the pointer to the output buffer input parameter won't change between calls (i.e. - // it *always* points to the beginning of the decompressed stream). The caller will need to track the current output buffer offset. - m_dst_highwater_ofs = dst_ofs; - - LZHAM_SAVE_STATE - LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_NOT_FINISHED); - LZHAM_RESTORE_STATE - - m_codec.decode_set_input_buffer(m_pIn_buf, *m_pIn_buf_size, m_pIn_buf, m_no_more_input_bytes_flag); - } - - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - } - } - else if (m_block_type == CLZDecompBase::cRawBlock) - { - // Raw block handling is complex because we ultimately want to (safely) handle as many bytes as possible using a small number of memcpy()'s. - uint num_raw_bytes_remaining; - num_raw_bytes_remaining = 0; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_num_raw_bytes_remaining = num_raw_bytes_remaining; -#define LZHAM_RESTORE_LOCAL_STATE num_raw_bytes_remaining = m_num_raw_bytes_remaining; - - // Determine how large this raw block is. - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, num_raw_bytes_remaining, 24); - - // Get and verify raw block length check bits. - uint num_raw_bytes_check_bits; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, num_raw_bytes_check_bits, 8); - uint raw_bytes_remaining0, raw_bytes_remaining1, raw_bytes_remaining2; - raw_bytes_remaining0 = num_raw_bytes_remaining & 0xFF; - raw_bytes_remaining1 = (num_raw_bytes_remaining >> 8) & 0xFF; - raw_bytes_remaining2 = (num_raw_bytes_remaining >> 16) & 0xFF; - if (num_raw_bytes_check_bits != ((raw_bytes_remaining0 ^ raw_bytes_remaining1) ^ raw_bytes_remaining2)) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1027); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_BAD_RAW_BLOCK); } - } - - num_raw_bytes_remaining++; - - // Discard any partial bytes from the bit buffer (align up to the next byte). - LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec); - - // Flush any full bytes from the bit buffer. - do - { - int b; - LZHAM_SYMBOL_CODEC_DECODE_REMOVE_BYTE_FROM_BIT_BUF(codec, b); - if (b < 0) - break; - - if ((unbuffered) && (dst_ofs >= out_buf_size)) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1028); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL); } - } - - pDst[dst_ofs++] = static_cast(b); - - if ((!unbuffered) && (dst_ofs > dict_size_mask)) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dict_size); - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - dst_ofs = 0; - } - - num_raw_bytes_remaining--; - } while (num_raw_bytes_remaining); - - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - - // Now handle the bulk of the raw data with memcpy(). - while (num_raw_bytes_remaining) - { - uint64 in_buf_ofs, in_buf_remaining; - in_buf_ofs = codec.decode_get_bytes_consumed(); - in_buf_remaining = *m_pIn_buf_size - in_buf_ofs; - - while (!in_buf_remaining) - { - // We need more bytes from the caller. - *m_pIn_buf_size = static_cast(in_buf_ofs); - *m_pOut_buf_size = 0; - - if (m_no_more_input_bytes_flag) - { - for ( ; ; ) { LZHAM_LOG_ERROR(1029); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_EXPECTED_MORE_RAW_BYTES); } - } - - LZHAM_SAVE_STATE - LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT); - LZHAM_RESTORE_STATE - - m_codec.decode_set_input_buffer(m_pIn_buf, *m_pIn_buf_size, m_pIn_buf, m_no_more_input_bytes_flag); - - in_buf_ofs = 0; - in_buf_remaining = *m_pIn_buf_size; - } - - // Determine how many bytes we can safely memcpy() in a single call. - uint num_bytes_to_copy; - num_bytes_to_copy = static_cast(LZHAM_MIN(num_raw_bytes_remaining, in_buf_remaining)); - if (!unbuffered) - num_bytes_to_copy = LZHAM_MIN(num_bytes_to_copy, dict_size - dst_ofs); - - if ((unbuffered) && ((dst_ofs + num_bytes_to_copy) > out_buf_size)) - { - // Output buffer is not large enough. - *m_pIn_buf_size = static_cast(in_buf_ofs); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1030); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL); } - } - - // Copy the raw bytes. - LZHAM_BULK_MEMCPY(pDst + dst_ofs, m_pIn_buf + in_buf_ofs, num_bytes_to_copy); - - in_buf_ofs += num_bytes_to_copy; - num_raw_bytes_remaining -= num_bytes_to_copy; - - codec.decode_set_input_buffer(m_pIn_buf, *m_pIn_buf_size, m_pIn_buf + in_buf_ofs, m_no_more_input_bytes_flag); - - dst_ofs += num_bytes_to_copy; - - if ((!unbuffered) && (dst_ofs > dict_size_mask)) - { - LZHAM_ASSERT(dst_ofs == dict_size); - - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dict_size); - - dst_ofs = 0; - } - } - - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE -#define LZHAM_RESTORE_LOCAL_STATE - } - else if (m_block_type == CLZDecompBase::cCompBlock) - { - LZHAM_SYMBOL_CODEC_DECODE_ARITH_START(codec) - - match_hist0 = 1; - match_hist1 = 1; - match_hist2 = 1; - match_hist3 = 1; - cur_state = 0; - - m_start_block_dst_ofs = dst_ofs; - - { - uint block_flush_type; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, block_flush_type, CLZDecompBase::cBlockFlushTypeBits); - if (block_flush_type == 1) - reset_huffman_table_update_rates(); - else if (block_flush_type == 2) - reset_all_tables(); - } - -#ifdef LZHAM_LZDEBUG - m_initial_step = m_step; - m_block_step = 0; - for ( ; ; m_step++, m_block_step++) -#else - for ( ; ; ) -#endif - { -#ifdef LZHAM_LZDEBUG - uint sync_marker; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, x, CLZDecompBase::cLZHAMDebugSyncMarkerBits); - LZHAM_VERIFY(sync_marker == CLZDecompBase::cLZHAMDebugSyncMarkerValue); - - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_debug_is_match, 1); - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_debug_match_len, 17); - - uint debug_cur_state; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, debug_cur_state, 4); - LZHAM_VERIFY(cur_state == debug_cur_state); -#endif - - // Read "is match" bit. - uint match_model_index; - match_model_index = LZHAM_IS_MATCH_MODEL_INDEX(cur_state); - LZHAM_ASSERT(match_model_index < LZHAM_ARRAY_SIZE(m_is_match_model)); - - uint is_match_bit; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_match_bit, m_is_match_model[match_model_index]); - -#ifdef LZHAM_LZDEBUG - LZHAM_VERIFY(is_match_bit == m_debug_is_match); -#endif - - if (LZHAM_BUILTIN_EXPECT(!is_match_bit, 0)) - { - // Handle literal. - -#ifdef LZHAM_LZDEBUG - LZHAM_VERIFY(m_debug_match_len == 1); -#endif - -#ifdef LZHAM_LZDEBUG - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_debug_lit, 8); -#endif - - if ((unbuffered) && (LZHAM_BUILTIN_EXPECT(dst_ofs >= out_buf_size, 0))) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_LOG_ERROR(1031); LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_DEST_BUF_TOO_SMALL); } - } - - if (LZHAM_BUILTIN_EXPECT(cur_state < CLZDecompBase::cNumLitStates, 1)) - { - // Regular literal - uint r; LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, r, m_lit_table); - pDst[dst_ofs] = static_cast(r); - -#ifdef LZHAM_LZDEBUG - LZHAM_VERIFY(pDst[dst_ofs] == m_debug_lit); -#endif - } - else - { - // Delta literal - uint match_hist0_ofs, rep_lit0; - - // Determine delta literal's partial context. - match_hist0_ofs = dst_ofs - match_hist0; - rep_lit0 = pDst[match_hist0_ofs & dict_size_mask]; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_rep_lit0 = rep_lit0; -#define LZHAM_RESTORE_LOCAL_STATE rep_lit0 = m_rep_lit0; - -#ifdef LZHAM_LZDEBUG - uint debug_rep_lit0; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, debug_rep_lit0, 8); - LZHAM_VERIFY(debug_rep_lit0 == rep_lit0); -#endif - - uint r; LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, r, m_delta_lit_table); - r ^= rep_lit0; - pDst[dst_ofs] = static_cast(r); - -#ifdef LZHAM_LZDEBUG - LZHAM_VERIFY(pDst[dst_ofs] == m_debug_lit); -#endif - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE -#define LZHAM_RESTORE_LOCAL_STATE - } - - cur_state = s_literal_next_state[cur_state]; - - dst_ofs++; - if ((!unbuffered) && (LZHAM_BUILTIN_EXPECT(dst_ofs > dict_size_mask, 0))) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dict_size); - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - dst_ofs = 0; - } - } - else - { - // Handle match. - uint match_len; - match_len = 1; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; - - // Determine if match is a rep_match, and if so what type. - uint is_rep; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_rep, m_is_rep_model[cur_state]); - if (LZHAM_BUILTIN_EXPECT(is_rep, 1)) - { - uint is_rep0; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_rep0, m_is_rep0_model[cur_state]); - if (LZHAM_BUILTIN_EXPECT(is_rep0, 1)) - { - uint is_rep0_len1; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_rep0_len1, m_is_rep0_single_byte_model[cur_state]); - if (LZHAM_BUILTIN_EXPECT(is_rep0_len1, 1)) - { - cur_state = (cur_state < CLZDecompBase::cNumLitStates) ? 9 : 11; - } - else - { - LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, match_len, m_rep_len_table[cur_state >= CLZDecompBase::cNumLitStates]); - match_len += CLZDecompBase::cMinMatchLen; - - if (match_len == (CLZDecompBase::cMaxMatchLen + 1)) - { - // Decode "huge" match length. - match_len = 0; - do - { - uint b; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, b, 1); - if (!b) - break; - match_len++; - } while (match_len < 3); - uint k; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, k, s_huge_match_code_len[match_len]); - match_len = s_huge_match_base_len[match_len] + k; - } - - cur_state = (cur_state < CLZDecompBase::cNumLitStates) ? 8 : 11; - } - } - else - { - LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, match_len, m_rep_len_table[cur_state >= CLZDecompBase::cNumLitStates]); - match_len += CLZDecompBase::cMinMatchLen; - - if (match_len == (CLZDecompBase::cMaxMatchLen + 1)) - { - // Decode "huge" match length. - match_len = 0; - do - { - uint b; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, b, 1); - if (!b) - break; - match_len++; - } while (match_len < 3); - uint k; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, k, s_huge_match_code_len[match_len]); - match_len = s_huge_match_base_len[match_len] + k; - } - - uint is_rep1; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_rep1, m_is_rep1_model[cur_state]); - if (LZHAM_BUILTIN_EXPECT(is_rep1, 1)) - { - uint temp = match_hist1; - match_hist1 = match_hist0; - match_hist0 = temp; - } - else - { - uint is_rep2; LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, is_rep2, m_is_rep2_model[cur_state]); - - if (LZHAM_BUILTIN_EXPECT(is_rep2, 1)) - { - // rep2 - uint temp = match_hist2; - match_hist2 = match_hist1; - match_hist1 = match_hist0; - match_hist0 = temp; - } - else - { - // rep3 - uint temp = match_hist3; - match_hist3 = match_hist2; - match_hist2 = match_hist1; - match_hist1 = match_hist0; - match_hist0 = temp; - } - } - - cur_state = (cur_state < CLZDecompBase::cNumLitStates) ? 8 : 11; - } - } - else - { - // Handle normal/full match. - uint sym; LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, sym, m_main_table); - sym -= CLZDecompBase::cLZXNumSpecialLengths; - - if (LZHAM_BUILTIN_EXPECT(static_cast(sym) < 0, 0)) - { - // Handle special symbols. - if (static_cast(sym) == (CLZDecompBase::cLZXSpecialCodeEndOfBlockCode - CLZDecompBase::cLZXNumSpecialLengths)) - break; - else - { - // Must be cLZXSpecialCodePartialStateReset. - match_hist0 = 1; - match_hist1 = 1; - match_hist2 = 1; - match_hist3 = 1; - cur_state = 0; - continue; - } - } - - // Low 3 bits of symbol = match length category, higher bits = distance category. - match_len = (sym & 7) + 2; - - uint match_slot; - match_slot = (sym >> 3) + CLZDecompBase::cLZXLowestUsableMatchSlot; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; m_match_slot = match_slot; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; match_slot = m_match_slot; - - if (LZHAM_BUILTIN_EXPECT(match_len == 9, 0)) - { - // Match is >= 9 bytes, decode the actual length. - uint e; LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, e, m_large_len_table[cur_state >= CLZDecompBase::cNumLitStates]); - match_len += e; - - if (match_len == (CLZDecompBase::cMaxMatchLen + 1)) - { - // Decode "huge" match length. - match_len = 0; - do - { - uint b; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, b, 1); - if (!b) - break; - match_len++; - } while (match_len < 3); - uint k; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, k, s_huge_match_code_len[match_len]); - match_len = s_huge_match_base_len[match_len] + k; - } - } - - uint num_extra_bits; - num_extra_bits = m_lzBase.m_lzx_position_extra_bits[match_slot]; - - uint extra_bits; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; m_match_slot = match_slot; m_num_extra_bits = num_extra_bits; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; match_slot = m_match_slot; num_extra_bits = m_num_extra_bits; - - if (LZHAM_BUILTIN_EXPECT(num_extra_bits < 3, 0)) - { - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, extra_bits, num_extra_bits); - } - else - { - extra_bits = 0; - if (LZHAM_BUILTIN_EXPECT(num_extra_bits > 4, 1)) - { - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, extra_bits, num_extra_bits - 4); - extra_bits <<= 4; - } - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; m_match_slot = match_slot; m_extra_bits = extra_bits; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; match_slot = m_match_slot; extra_bits = m_extra_bits; - - uint j; LZHAM_DECOMPRESS_DECODE_ADAPTIVE_SYMBOL(codec, j, m_dist_lsb_table); - extra_bits += j; - } - - match_hist3 = match_hist2; - match_hist2 = match_hist1; - match_hist1 = match_hist0; - match_hist0 = m_lzBase.m_lzx_position_base[match_slot] + extra_bits; - - cur_state = (cur_state < CLZDecompBase::cNumLitStates) ? CLZDecompBase::cNumLitStates : CLZDecompBase::cNumLitStates + 3; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; - } - - // We have the match's length and distance, now do the copy. - -#ifdef LZHAM_LZDEBUG - LZHAM_VERIFY(match_len == m_debug_match_len); - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_debug_match_dist, 25); - uint d; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, d, 4); - m_debug_match_dist = (m_debug_match_dist << 4) | d; - LZHAM_VERIFY((uint)match_hist0 == m_debug_match_dist); -#endif - if ( (unbuffered) && LZHAM_BUILTIN_EXPECT((((size_t)match_hist0 > dst_ofs) || ((dst_ofs + match_len) > out_buf_size)), 0) ) - { - LZHAM_LOG_ERROR(1032); - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - *m_pIn_buf_size = static_cast(codec.decode_get_bytes_consumed()); - *m_pOut_buf_size = 0; - for ( ; ; ) { LZHAM_CR_RETURN(m_state, LZHAM_DECOMP_STATUS_FAILED_BAD_CODE); } - } - - uint src_ofs; - const uint8* pCopy_src; - src_ofs = (dst_ofs - match_hist0) & dict_size_mask; - pCopy_src = pDst + src_ofs; - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE m_match_len = match_len; m_src_ofs = src_ofs; m_pCopy_src = pCopy_src; -#define LZHAM_RESTORE_LOCAL_STATE match_len = m_match_len; src_ofs = m_src_ofs; pCopy_src = m_pCopy_src; - - if ( (!unbuffered) && LZHAM_BUILTIN_EXPECT( ((LZHAM_MAX(src_ofs, dst_ofs) + match_len) > dict_size_mask), 0) ) - { - // Match source or destination wraps around the end of the dictionary to the beginning, so handle the copy one byte at a time. - do - { - pDst[dst_ofs++] = *pCopy_src++; - - if (LZHAM_BUILTIN_EXPECT(pCopy_src == pDst_end, 0)) - pCopy_src = pDst; - - if (LZHAM_BUILTIN_EXPECT(dst_ofs > dict_size_mask, 0)) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dict_size); - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - dst_ofs = 0; - } - - match_len--; - } while (LZHAM_BUILTIN_EXPECT(match_len > 0, 1)); - } - else - { - uint8* pCopy_dst = pDst + dst_ofs; - if (LZHAM_BUILTIN_EXPECT(match_hist0 == 1, 0)) - { - // Handle byte runs. - uint8 c = *pCopy_src; - if (LZHAM_BUILTIN_EXPECT(match_len < 8, 1)) - { - for (int i = match_len; i > 0; i--) - *pCopy_dst++ = c; - } - else - { - memset(pCopy_dst, c, match_len); - } - } - else - { - // Handle matches of length 2 or higher. - if (LZHAM_BUILTIN_EXPECT(((match_len < 8) || ((int)match_len > match_hist0)), 1)) - { - for (int i = match_len; i > 0; i--) - *pCopy_dst++ = *pCopy_src++; - } - else - { - LZHAM_MEMCPY(pCopy_dst, pCopy_src, match_len); - } - } - dst_ofs += match_len; - } - } // lit or match - -#undef LZHAM_SAVE_LOCAL_STATE -#undef LZHAM_RESTORE_LOCAL_STATE -#define LZHAM_SAVE_LOCAL_STATE -#define LZHAM_RESTORE_LOCAL_STATE - } // for ( ; ; ) - -#ifdef LZHAM_LZDEBUG - uint end_sync_marker; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, end_sync_marker, 12); - LZHAM_VERIFY(end_sync_marker == 366); -#endif - LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec); - } - else if (m_block_type == CLZDecompBase::cEOFBlock) - { - // Received EOF. - m_status = LZHAM_DECOMP_STATUS_SUCCESS; - } - else - { - LZHAM_LOG_ERROR(1033); - // This block type is currently undefined. - m_status = LZHAM_DECOMP_STATUS_FAILED_BAD_CODE; - } - - m_block_index++; - - } while (m_status == LZHAM_DECOMP_STATUS_NOT_FINISHED); - - if ((!unbuffered) && (dst_ofs)) - { - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - LZHAM_FLUSH_DICT_TO_OUTPUT_BUFFER(dst_ofs); - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec); - } - - if (m_status == LZHAM_DECOMP_STATUS_SUCCESS) - { - LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec); - - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, m_file_src_file_adler32, 16); - uint l; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, l, 16); - m_file_src_file_adler32 = (m_file_src_file_adler32 << 16) | l; - - if (m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_COMPUTE_ADLER32) - { - if (unbuffered) - { - m_decomp_adler32 = adler32(pDst, dst_ofs, cInitAdler32); - } - - if (m_file_src_file_adler32 != m_decomp_adler32) - { - LZHAM_LOG_ERROR(1034); - m_status = LZHAM_DECOMP_STATUS_FAILED_ADLER32; - } - } - else - { - m_decomp_adler32 = m_file_src_file_adler32; - } - } - - LZHAM_SYMBOL_CODEC_DECODE_END(codec); - - *m_pIn_buf_size = static_cast(codec.stop_decoding()); - *m_pOut_buf_size = unbuffered ? (dst_ofs - m_dst_highwater_ofs) : 0; - m_dst_highwater_ofs = dst_ofs; - - LZHAM_CR_RETURN(m_state, m_status); - - for ( ; ; ) - { - *m_pIn_buf_size = 0; - *m_pOut_buf_size = 0; - LZHAM_CR_RETURN(m_state, m_status); - } - - LZHAM_CR_FINISH - - return m_status; - } - - static bool check_params(const lzham_decompress_params *pParams) - { - if ((!pParams) || (pParams->m_struct_size != sizeof(lzham_decompress_params))) - { - LZHAM_LOG_ERROR(1000); - return false; - } - - if ((pParams->m_dict_size_log2 < CLZDecompBase::cMinDictSizeLog2) || (pParams->m_dict_size_log2 > CLZDecompBase::cMaxDictSizeLog2)) - { - LZHAM_LOG_ERROR(1001); - return false; - } - - if (pParams->m_num_seed_bytes) - { - if (((pParams->m_decompress_flags & LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED) != 0) || (!pParams->m_pSeed_bytes)) - { - LZHAM_LOG_ERROR(1002); - return false; - } - if (pParams->m_num_seed_bytes > (1U << pParams->m_dict_size_log2)) - { - LZHAM_LOG_ERROR(1003); - return false; - } - } - return true; - } - - lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_init(const lzham_decompress_params *pParams) - { - LZHAM_ASSUME(CLZDecompBase::cMinDictSizeLog2 == LZHAM_MIN_DICT_SIZE_LOG2); - LZHAM_ASSUME(CLZDecompBase::cMaxDictSizeLog2 == LZHAM_MAX_DICT_SIZE_LOG2_X64); - - if (!check_params(pParams)) - return NULL; - - lzham_malloc_context malloc_context = lzham_create_malloc_context(LZHAM_DECOMP_MEMORY_ARENA_SIZE); - - lzham_decompressor *pState = lzham_new(malloc_context, malloc_context); - if (!pState) - { - lzham_destroy_malloc_context(malloc_context); - return NULL; - } - - pState->m_params = *pParams; - - if (pState->m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED) - { - pState->m_pRaw_decomp_buf = NULL; - pState->m_raw_decomp_buf_size = 0; - pState->m_pDecomp_buf = NULL; - } - else - { - uint32 decomp_buf_size = 1U << pState->m_params.m_dict_size_log2; - pState->m_pRaw_decomp_buf = static_cast(lzham_malloc(malloc_context, decomp_buf_size + 15)); - if (!pState->m_pRaw_decomp_buf) - { - lzham_delete(malloc_context, pState); - lzham_destroy_malloc_context(malloc_context); - return NULL; - } - pState->m_raw_decomp_buf_size = decomp_buf_size; - pState->m_pDecomp_buf = math::align_up_pointer(pState->m_pRaw_decomp_buf, 16); - } - - pState->init(); - - return pState; - } - - lzham_decompress_state_ptr LZHAM_CDECL lzham_lib_decompress_reinit(lzham_decompress_state_ptr p, const lzham_decompress_params *pParams) - { - if (!p) - return lzham_lib_decompress_init(pParams); - - lzham_decompressor *pState = static_cast(p); - - if (!check_params(pParams)) - return NULL; - - if (pState->m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED) - { - lzham_free(pState->m_malloc_context, pState->m_pRaw_decomp_buf); - pState->m_pRaw_decomp_buf = NULL; - pState->m_raw_decomp_buf_size = 0; - pState->m_pDecomp_buf = NULL; - } - else - { - uint32 new_dict_size = 1U << pState->m_params.m_dict_size_log2; - if ((!pState->m_pRaw_decomp_buf) || (pState->m_raw_decomp_buf_size < new_dict_size)) - { - uint8 *pNew_dict = static_cast(lzham_realloc(pState->m_malloc_context, pState->m_pRaw_decomp_buf, new_dict_size + 15)); - if (!pNew_dict) - return NULL; - pState->m_pRaw_decomp_buf = pNew_dict; - pState->m_raw_decomp_buf_size = new_dict_size; - pState->m_pDecomp_buf = math::align_up_pointer(pState->m_pRaw_decomp_buf, 16); - } - } - - pState->m_params = *pParams; - - pState->init(); - - pState->reset_arith_tables(); - return pState; - } - - uint32 LZHAM_CDECL lzham_lib_decompress_deinit(lzham_decompress_state_ptr p) - { - lzham_decompressor *pState = static_cast(p); - if (!pState) - return 0; - - uint32 adler32 = pState->m_decomp_adler32; - - lzham_malloc_context malloc_context = pState->m_malloc_context; - - lzham_free(malloc_context, pState->m_pRaw_decomp_buf); - lzham_delete(malloc_context, pState); - lzham_destroy_malloc_context(malloc_context); - - return adler32; - } - - lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress( - lzham_decompress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag) - { - lzham_decompressor *pState = static_cast(p); - - if ((!pState) || (!pState->m_params.m_dict_size_log2) || (!pIn_buf_size) || (!pOut_buf_size)) - { - return LZHAM_DECOMP_STATUS_INVALID_PARAMETER; - } - - if ((*pIn_buf_size) && (!pIn_buf)) - { - return LZHAM_DECOMP_STATUS_INVALID_PARAMETER; - } - - if ((*pOut_buf_size) && (!pOut_buf)) - { - return LZHAM_DECOMP_STATUS_INVALID_PARAMETER; - } - - pState->m_pIn_buf = pIn_buf; - pState->m_pIn_buf_size = pIn_buf_size; - pState->m_pOut_buf = pOut_buf; - pState->m_pOut_buf_size = pOut_buf_size; - pState->m_no_more_input_bytes_flag = (no_more_input_bytes_flag != 0); - - if (pState->m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED) - { - if (!pState->m_pOrig_out_buf) - { - pState->m_pOrig_out_buf = pOut_buf; - pState->m_orig_out_buf_size = *pOut_buf_size; - } - else - { - // In unbuffered mode, the caller is not allowed to move the output buffer and the output pointer MUST always point to the beginning of the output buffer. - // Also, the output buffer size must indicate the full size of the output buffer. The decompressor will track the current output offset, and during partial/sync - // flushes it'll report how many bytes it has written since the call. - if ((pState->m_pOrig_out_buf != pOut_buf) || (pState->m_orig_out_buf_size != *pOut_buf_size)) - { - return LZHAM_DECOMP_STATUS_INVALID_PARAMETER; - } - } - } - - lzham_decompress_status_t status; - - if (pState->m_params.m_decompress_flags & LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED) - status = pState->decompress(); - else - status = pState->decompress(); - - return status; - } - - lzham_decompress_status_t LZHAM_CDECL lzham_lib_decompress_memory(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) - { - if (!pParams) - return LZHAM_DECOMP_STATUS_INVALID_PARAMETER; - - lzham_decompress_params params(*pParams); - params.m_decompress_flags |= LZHAM_DECOMP_FLAG_OUTPUT_UNBUFFERED; - - lzham_decompress_state_ptr pState = lzham_lib_decompress_init(¶ms); - if (!pState) - return LZHAM_DECOMP_STATUS_FAILED_INITIALIZING; - - lzham_decompress_status_t status = lzham_lib_decompress(pState, pSrc_buf, &src_len, pDst_buf, pDst_len, true); - - uint32 adler32 = lzham_lib_decompress_deinit(pState); - if (pAdler32) - *pAdler32 = adler32; - - return status; - } - - // ----------------- zlib-style API's - - int LZHAM_CDECL lzham_lib_z_inflateInit(lzham_z_streamp pStream) - { - return lzham_lib_z_inflateInit2(pStream, LZHAM_Z_DEFAULT_WINDOW_BITS); - } - - int LZHAM_CDECL lzham_lib_z_inflateInit2(lzham_z_streamp pStream, int window_bits) - { - if (!pStream) - return LZHAM_Z_STREAM_ERROR; - -#ifdef LZHAM_Z_API_FORCE_WINDOW_BITS - window_bits = LZHAM_Z_API_FORCE_WINDOW_BITS; -#endif - - int max_window_bits = LZHAM_64BIT_POINTERS ? LZHAM_MAX_DICT_SIZE_LOG2_X64 : LZHAM_MAX_DICT_SIZE_LOG2_X86; - if (labs(window_bits) > max_window_bits) - return LZHAM_Z_PARAM_ERROR; - - if (labs(window_bits) < LZHAM_MIN_DICT_SIZE_LOG2) - window_bits = (window_bits < 0) ? -LZHAM_MIN_DICT_SIZE_LOG2 : LZHAM_MIN_DICT_SIZE_LOG2; - - lzham_decompress_params params; - utils::zero_object(params); - params.m_struct_size = sizeof(lzham_decompress_params); - params.m_dict_size_log2 = static_cast(labs(window_bits)); - - params.m_decompress_flags = LZHAM_DECOMP_FLAG_COMPUTE_ADLER32; - if (window_bits > 0) - params.m_decompress_flags |= LZHAM_DECOMP_FLAG_READ_ZLIB_STREAM; - - lzham_decompress_state_ptr pState = lzham_lib_decompress_init(¶ms); - if (!pState) - return LZHAM_Z_MEM_ERROR; - pStream->state = static_cast(pState); - - pStream->data_type = 0; - pStream->adler = LZHAM_Z_ADLER32_INIT; - pStream->msg = NULL; - pStream->total_in = 0; - pStream->total_out = 0; - pStream->reserved = 0; - - return LZHAM_Z_OK; - } - - int LZHAM_CDECL lzham_lib_z_inflateReset(lzham_z_streamp pStream) - { - if ((!pStream) || (!pStream->state)) - return LZHAM_Z_STREAM_ERROR; - - lzham_decompress_state_ptr pState = static_cast(pStream->state); - lzham_decompressor *pDecomp = static_cast(pState); - - lzham_decompress_params params(pDecomp->m_params); - - if (!lzham_lib_decompress_reinit(pState, ¶ms)) - return LZHAM_Z_STREAM_ERROR; - - return LZHAM_Z_OK; - } - - int LZHAM_CDECL lzham_lib_z_inflate(lzham_z_streamp pStream, int flush) - { - if ((!pStream) || (!pStream->state)) - return LZHAM_Z_STREAM_ERROR; - - if ((flush == LZHAM_Z_PARTIAL_FLUSH) || (flush == LZHAM_Z_FULL_FLUSH)) - flush = LZHAM_Z_SYNC_FLUSH; - if (flush) - { - if ((flush != LZHAM_Z_SYNC_FLUSH) && (flush != LZHAM_Z_FINISH)) - return LZHAM_Z_STREAM_ERROR; - } - - size_t orig_avail_in = pStream->avail_in; - - lzham_decompress_state_ptr pState = static_cast(pStream->state); - lzham_decompressor *pDecomp = static_cast(pState); - if (pDecomp->m_z_last_status >= LZHAM_DECOMP_STATUS_FIRST_SUCCESS_OR_FAILURE_CODE) - return LZHAM_Z_DATA_ERROR; - - if (pDecomp->m_z_has_flushed && (flush != LZHAM_Z_FINISH)) - return LZHAM_Z_STREAM_ERROR; - pDecomp->m_z_has_flushed |= (flush == LZHAM_Z_FINISH); - - lzham_decompress_status_t status; - for ( ; ; ) - { - size_t in_bytes = pStream->avail_in; - size_t out_bytes = pStream->avail_out; - lzham_bool no_more_input_bytes_flag = (flush == LZHAM_Z_FINISH); - status = lzham_lib_decompress(pState, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, no_more_input_bytes_flag); - - pDecomp->m_z_last_status = status; - - pStream->next_in += (uint)in_bytes; - pStream->avail_in -= (uint)in_bytes; - pStream->total_in += (uint)in_bytes; - pStream->adler = pDecomp->m_decomp_adler32; - - pStream->next_out += (uint)out_bytes; - pStream->avail_out -= (uint)out_bytes; - pStream->total_out += (uint)out_bytes; - - if (status >= LZHAM_DECOMP_STATUS_FIRST_FAILURE_CODE) - { - if (status == LZHAM_DECOMP_STATUS_FAILED_NEED_SEED_BYTES) - return LZHAM_Z_NEED_DICT; - else - return LZHAM_Z_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). - } - - if ((status == LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) - return LZHAM_Z_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input, or by setting flush to LZHAM_Z_FINISH. - else if (flush == LZHAM_Z_FINISH) - { - // Caller has indicated that all remaining input was at next_in, and all remaining output will fit entirely in next_out. - // (The output buffer at next_out MUST be large to hold the remaining uncompressed data when flush==LZHAM_Z_FINISH). - if (status == LZHAM_DECOMP_STATUS_SUCCESS) - return LZHAM_Z_STREAM_END; - // If status is LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT, there must be at least 1 more byte on the way but the caller to lzham_decompress() supplied an empty output buffer. - // Something is wrong because the caller's output buffer should be large enough to hold the entire decompressed stream when flush==LZHAM_Z_FINISH. - else if (status == LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT) - return LZHAM_Z_BUF_ERROR; - } - else if ((status == LZHAM_DECOMP_STATUS_SUCCESS) || (!pStream->avail_in) || (!pStream->avail_out)) - break; - } - - return (status == LZHAM_DECOMP_STATUS_SUCCESS) ? LZHAM_Z_STREAM_END : LZHAM_Z_OK; - } - - int LZHAM_CDECL lzham_lib_z_inflateEnd(lzham_z_streamp pStream) - { - if (!pStream) - return LZHAM_Z_STREAM_ERROR; - - lzham_decompress_state_ptr pState = static_cast(pStream->state); - if (pState) - { - pStream->adler = lzham_lib_decompress_deinit(pState); - pStream->state = NULL; - } - - return LZHAM_Z_OK; - } - - int LZHAM_CDECL lzham_lib_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) - { - lzham_z_stream stream; - int status; - memset(&stream, 0, sizeof(stream)); - - // In case lzham_z_ulong is 64-bits (argh I hate longs). - if ((source_len | *pDest_len) > 0xFFFFFFFFU) - return LZHAM_Z_PARAM_ERROR; - - stream.next_in = pSource; - stream.avail_in = (uint)source_len; - stream.next_out = pDest; - stream.avail_out = (uint)*pDest_len; - - status = lzham_lib_z_inflateInit(&stream); - if (status != LZHAM_Z_OK) - return status; - - status = lzham_lib_z_inflate(&stream, LZHAM_Z_FINISH); - if (status != LZHAM_Z_STREAM_END) - { - lzham_lib_z_inflateEnd(&stream); - return ((status == LZHAM_Z_BUF_ERROR) && (!stream.avail_in)) ? LZHAM_Z_DATA_ERROR : status; - } - *pDest_len = stream.total_out; - - return lzham_lib_z_inflateEnd(&stream); - } - - const char * LZHAM_CDECL lzham_lib_z_error(int err) - { - static struct - { - int m_err; - const char *m_pDesc; - } - s_error_descs[] = - { - { LZHAM_Z_OK, "" }, - { LZHAM_Z_STREAM_END, "stream end" }, - { LZHAM_Z_NEED_DICT, "need dictionary" }, - { LZHAM_Z_ERRNO, "file error" }, - { LZHAM_Z_STREAM_ERROR, "stream error" }, - { LZHAM_Z_DATA_ERROR, "data error" }, - { LZHAM_Z_MEM_ERROR, "out of memory" }, - { LZHAM_Z_BUF_ERROR, "buf error" }, - { LZHAM_Z_VERSION_ERROR, "version error" }, - { LZHAM_Z_PARAM_ERROR, "parameter error" } - }; - for (uint i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) - if (s_error_descs[i].m_err == err) - return s_error_descs[i].m_pDesc; - return NULL; - } - - lzham_z_ulong lzham_lib_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len) - { - return adler32(ptr, buf_len, static_cast(adler)); - } - - lzham_z_ulong LZHAM_CDECL lzham_lib_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len) - { - return crc32(static_cast(crc), ptr, buf_len); - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -// File: lzham_lzdecompbase.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_lzdecompbase.h" - -namespace lzham -{ - // Keep in sync with LZHAM_DEFAULT_ADAPT_RATE, and LZHAM_DEFAULT_TABLE_UPDATE_RATE, etc. - table_update_settings g_table_update_settings[] = - { - { 4, 32 }, // crazy slow! - { 5, 33 }, - { 6, 34 }, - { 7, 35 }, - { 8, 36 }, - - { 16, 48 }, - { 32, 72 }, - { 64, 64 }, // codec's internal default - { 98, 80 }, - { 128, 96 }, - - { 192, 112 }, - { 256, 128 }, - { 512, 128+16*2 }, - { 1024, 128+16*4 }, - { 2048, 128+16*6 }, - - { 2048, 128+16*8 }, - { 2048, 128+16*10 }, - { 2048, 128+16*12 }, - { 2048, 128+16*14 }, - { 2048, 128+16*16 } - }; - - uint CLZDecompBase::m_lzx_position_base[CLZDecompBase::cLZXMaxPositionSlots] = - { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x6, 0x8, 0xC, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0xC0, - 0x100, 0x180, 0x200, 0x300, 0x400, 0x600, 0x800, 0xC00, 0x1000, 0x1800, 0x2000, 0x3000, 0x4000, 0x6000, 0x8000, 0xC000, - 0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000, 0xC0000, 0x100000, 0x180000, 0x200000, 0x300000, 0x400000, 0x600000, 0x800000, 0xC00000, - 0x1000000, 0x1800000, 0x2000000, 0x3000000, 0x4000000, 0x6000000, 0x8000000, 0xA000000, 0xC000000, 0xE000000, 0x10000000, 0x12000000, 0x14000000, 0x16000000, 0x18000000, 0x1A000000, - 0x1C000000, 0x1E000000, 0x20000000, 0x22000000, 0x24000000, 0x26000000, 0x28000000, 0x2A000000, 0x2C000000, 0x2E000000, 0x30000000, 0x32000000, 0x34000000, 0x36000000, 0x38000000, 0x3A000000, - 0x3C000000, 0x3E000000, 0x40000000, 0x42000000, 0x44000000, 0x46000000, 0x48000000, 0x4A000000, 0x4C000000, 0x4E000000, 0x50000000, 0x52000000, 0x54000000, 0x56000000, 0x58000000, 0x5A000000, - 0x5C000000, 0x5E000000, 0x60000000, 0x62000000, 0x64000000, 0x66000000, 0x68000000, 0x6A000000, 0x6C000000, 0x6E000000, 0x70000000, 0x72000000, 0x74000000, 0x76000000, 0x78000000, 0x7A000000, - 0x7C000000, 0x7E000000, 0x80000000, 0x82000000, 0x84000000, 0x86000000, 0x88000000, 0x8A000000, 0x8C000000, 0x8E000000, 0x90000000, 0x92000000, 0x94000000, 0x96000000, 0x98000000, 0x9A000000, - }; - - uint CLZDecompBase::m_lzx_position_extra_mask[CLZDecompBase::cLZXMaxPositionSlots] = - { - 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x3, 0x7, 0x7, 0xF, 0xF, 0x1F, 0x1F, 0x3F, 0x3F, - 0x7F, 0x7F, 0xFF, 0xFF, 0x1FF, 0x1FF, 0x3FF, 0x3FF, 0x7FF, 0x7FF, 0xFFF, 0xFFF, 0x1FFF, 0x1FFF, 0x3FFF, 0x3FFF, - 0x7FFF, 0x7FFF, 0xFFFF, 0xFFFF, 0x1FFFF, 0x1FFFF, 0x3FFFF, 0x3FFFF, 0x7FFFF, 0x7FFFF, 0xFFFFF, 0xFFFFF, 0x1FFFFF, 0x1FFFFF, 0x3FFFFF, 0x3FFFFF, - 0x7FFFFF, 0x7FFFFF, 0xFFFFFF, 0xFFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, - 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, - 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, - 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, - 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF - }; - - uint8 CLZDecompBase::m_lzx_position_extra_bits[CLZDecompBase::cLZXMaxPositionSlots] = - { - 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, - 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xA, 0xA, 0xB, 0xB, 0xC, 0xC, 0xD, 0xD, 0xE, 0xE, - 0xF, 0xF, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, - 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, - 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, - 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, - 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, - 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 - }; - - static const uint8 g_num_lzx_position_slots[] = { 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 58, 66 }; - - void CLZDecompBase::init_position_slots(uint dict_size_log2) - { - LZHAM_ASSERT(dict_size_log2 >= LZHAM_MIN_DICT_SIZE_LOG2); - LZHAM_ASSERT(dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64); - LZHAM_ASSERT((sizeof(g_table_update_settings) / sizeof(g_table_update_settings[0])) == LZHAM_FASTEST_TABLE_UPDATE_RATE); - - //for (dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2; dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64; dict_size_log2++) { - - m_dict_size_log2 = dict_size_log2; - m_dict_size = 1U << dict_size_log2; - m_num_lzx_slots = g_num_lzx_position_slots[dict_size_log2 - LZHAM_MIN_DICT_SIZE_LOG2]; - -#if 0 - int i, j; - for (i = 0, j = 0; i < cLZXMaxPositionSlots; i += 2) - { - m_lzx_position_extra_bits[i] = (uint8)j; - m_lzx_position_extra_bits[i + 1] = (uint8)j; - - if ((i != 0) && (j < 25)) - j++; - } - - for (i = 0, j = 0; i < cLZXMaxPositionSlots; i++) - { - m_lzx_position_base[i] = j; - m_lzx_position_extra_mask[i] = (1 << m_lzx_position_extra_bits[i]) - 1; - j += (1 << m_lzx_position_extra_bits[i]); - } - - for (uint i = 0; i < cLZXMaxPositionSlots; i++) - { - printf("0x%X, ", m_lzx_position_base[i]); - if ((i & 15) == 15) printf("\n"); - } -#endif - -#if 0 - m_num_lzx_slots = 0; - - const uint largest_dist = m_dict_size - 1; - for (i = 0; i < cLZXMaxPositionSlots; i++) - { - if ( (largest_dist >= m_lzx_position_base[i]) && - (largest_dist < (m_lzx_position_base[i] + (1 << m_lzx_position_extra_bits[i])) ) ) - { - m_num_lzx_slots = i + 1; - break; - } - } - - LZHAM_VERIFY(m_num_lzx_slots); -#endif - - //printf("%u, ", m_num_lzx_slots); } - } - -} //namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -// File: lzham_lzdecompbase.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -//#define LZHAM_LZDEBUG - -#define LZHAM_IS_MATCH_MODEL_INDEX(cur_state) (cur_state) - -namespace lzham -{ - struct table_update_settings - { - uint16 m_max_update_interval; - uint16 m_slow_rate; - }; - extern table_update_settings g_table_update_settings[]; - - struct CLZDecompBase - { - enum - { - cMinMatchLen = 2U, - cMaxMatchLen = 257U, - - cMaxHugeMatchLen = 65536, - - cMinDictSizeLog2 = 15, - cMaxDictSizeLog2 = 29, - - cMatchHistSize = 4, - cMaxLen2MatchDist = 2047 - }; - - enum - { - cLZXNumSecondaryLengths = 249, - - cNumHugeMatchCodes = 1, - cMaxHugeMatchCodeBits = 16, - - cLZXNumSpecialLengths = 2, - - cLZXLowestUsableMatchSlot = 1, - cLZXMaxPositionSlots = 128 - }; - - enum - { - cLZXSpecialCodeEndOfBlockCode = 0, - cLZXSpecialCodePartialStateReset = 1 - }; - - enum - { - cLZHAMDebugSyncMarkerValue = 666, - cLZHAMDebugSyncMarkerBits = 12 - }; - - enum - { - cBlockHeaderBits = 2, - cBlockCheckBits = 4, - cBlockFlushTypeBits = 2, - - cSyncBlock = 0, - cCompBlock = 1, - cRawBlock = 2, - cEOFBlock = 3 - }; - - enum - { - cNumStates = 12, - cNumLitStates = 7, - }; - - uint m_dict_size_log2; - uint m_dict_size; - - uint m_num_lzx_slots; - - static uint m_lzx_position_base[cLZXMaxPositionSlots]; - static uint m_lzx_position_extra_mask[cLZXMaxPositionSlots]; - static uint8 m_lzx_position_extra_bits[cLZXMaxPositionSlots]; - - void init_position_slots(uint dict_size_log2); - }; - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_math.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_math.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_math.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_math.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -// File: lzham_math.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__) - #include - #if defined(_MSC_VER) - #pragma intrinsic(_BitScanReverse) - #endif -#endif - -namespace lzham -{ - namespace math - { - // Yes I know these should probably be pass by ref, not val: - // http://www.stepanovpapers.com/notes.pdf - // Just don't use them on non-simple (non built-in) types! - template inline T minimum(T a, T b) { return (a < b) ? a : b; } - - template inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); } - - template inline T maximum(T a, T b) { return (a > b) ? a : b; } - - template inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); } - - template inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); } - - inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); } - inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); } - - template inline T align_up_pointer(T p, uint alignment) - { - LZHAM_ASSERT(is_power_of_2(alignment)); - ptr_bits_t q = reinterpret_cast(p); - q = (q + alignment - 1) & (~((uint_ptr)alignment - 1)); - return reinterpret_cast(q); - } - - // From "Hackers Delight" - // val remains unchanged if it is already a power of 2. - inline uint32 next_pow2(uint32 val) - { - val--; - val |= val >> 16; - val |= val >> 8; - val |= val >> 4; - val |= val >> 2; - val |= val >> 1; - return val + 1; - } - - // val remains unchanged if it is already a power of 2. - inline uint64 next_pow2(uint64 val) - { - val--; - val |= val >> 32; - val |= val >> 16; - val |= val >> 8; - val |= val >> 4; - val |= val >> 2; - val |= val >> 1; - return val + 1; - } - - inline uint floor_log2i(uint v) - { - uint l = 0; - while (v > 1U) - { - v >>= 1; - l++; - } - return l; - } - - inline uint ceil_log2i(uint v) - { - uint l = floor_log2i(v); - if ((l != cIntBits) && (v > (1U << l))) - l++; - return l; - } - - // Returns the total number of bits needed to encode v. - inline uint total_bits(uint v) - { - unsigned long l = 0; -#if defined(__MINGW32__) - if (v) - { - l = 32 -__builtin_clz(v); - } -#elif defined(LZHAM_USE_MSVC_INTRINSICS) - if (_BitScanReverse(&l, v)) - { - l++; - } - else - { - l = 0; - } -#else - while (v > 0U) - { - v >>= 1; - l++; - } -#endif - return static_cast(l); - } - - inline uint compute_mask_size(uint x) - { - uint l = 0; - while (x) - { - x &= (x - 1); - l++; - } - return l; - } - - inline uint compute_mask_shift(uint x) - { - if (!x) - return 0; - - uint l = 0; - while ((x & 1) == 0) - { - x >>= 1; - l++; - } - - return l; - } - - } - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,463 +0,0 @@ -// File: lzham_mem.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" - -#ifdef __APPLE__ - #include -#elif defined(__FreeBSD__) || defined(__NetBSD__) - #include - #if defined(__FreeBSD__) - #define malloc(size) aligned_alloc((LZHAM_MIN_ALLOC_ALIGNMENT), (size)) - #endif -#else - #include -#endif - -using namespace lzham; - -// Purposely less than 2^15, the min dictionary size. -#define LZHAM_MAX_ARENA_ALLOC_SIZE 32767 - -#define LZHAM_MEM_STATS 0 - -#ifndef LZHAM_USE_WIN32_API - #ifdef _MSC_VER - // LZHAM currently needs _msize/malloc_size/malloc_usable_size to function, so it can't be 100% ANSI C++. - #elif defined(__APPLE__) - #define _msize malloc_size - #else - #define _msize malloc_usable_size - #endif -#endif - -namespace lzham -{ - #if LZHAM_64BIT_POINTERS - const uint64 MAX_POSSIBLE_BLOCK_SIZE = 0x400000000ULL; - #else - const uint32 MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U; - #endif - - class simple_spinlock - { - volatile atomic32_t m_lock; - - public: - simple_spinlock() : m_lock(0) { } - - ~simple_spinlock() { } - - void lock() - { - for ( ; ; ) - { - if (atomic_compare_exchange32(&m_lock, 1, 0) == 0) - break; - } - - LZHAM_MEMORY_IMPORT_BARRIER; - } - - void unlock() - { - LZHAM_MEMORY_EXPORT_BARRIER; - - atomic_decrement32(&m_lock); - } - }; - - static void* lzham_default_realloc(void* p, size_t size, size_t* pActual_size, lzham_bool movable, void* pUser_data) - { - LZHAM_NOTE_UNUSED(pUser_data); - - void* p_new; - - if (!p) - { - p_new = malloc(size); - LZHAM_ASSERT( (reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 ); - - if (pActual_size) - *pActual_size = p_new ? _msize(p_new) : 0; - } - else if (!size) - { - free(p); - p_new = NULL; - - if (pActual_size) - *pActual_size = 0; - } - else - { - void* p_final_block = p; -#ifdef WIN32 - p_new = _expand(p, size); -#else - p_new = NULL; -#endif - - if (p_new) - { - LZHAM_ASSERT( (reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 ); - p_final_block = p_new; - } - else if (movable) - { - p_new = realloc(p, size); - - if (p_new) - { - LZHAM_ASSERT( (reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 ); - p_final_block = p_new; - } - } - - if (pActual_size) - *pActual_size = _msize(p_final_block); - } - - return p_new; - } - - static size_t lzham_default_msize(void* p, void* pUser_data) - { - LZHAM_NOTE_UNUSED(pUser_data); - return p ? _msize(p) : 0; - } - - static lzham_realloc_func g_pRealloc = lzham_default_realloc; - static lzham_msize_func g_pMSize = lzham_default_msize; - static void* g_pUser_data; - - void LZHAM_CDECL lzham_lib_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data) - { - if ((!pRealloc) || (!pMSize)) - { - g_pRealloc = lzham_default_realloc; - g_pMSize = lzham_default_msize; - g_pUser_data = NULL; - } - else - { - g_pRealloc = pRealloc; - g_pMSize = pMSize; - g_pUser_data = pUser_data; - } - } - - static inline void lzham_mem_error(lzham_malloc_context context, const char* p_msg) - { - LZHAM_NOTE_UNUSED(context); - lzham_assert(p_msg, __FILE__, __LINE__); - - LZHAM_LOG_ERROR(2000); - } - - struct malloc_context - { - enum { cSig = 0x5749ABCD }; - uint m_sig; - - uint m_arena_size; - - simple_spinlock m_lock; - - int64 m_total_blocks; - int64 m_cur_allocated; - int64 m_max_blocks; - int64 m_max_allocated; - - uint m_arena_ofs; - - uint8 m_arena[1]; - - void init(uint arena_size) - { - m_sig = cSig; - - m_arena_size = arena_size; - m_arena_ofs = 0; - - m_total_blocks = 0; - m_cur_allocated = 0; - m_max_blocks = 0; - m_max_allocated = 0; - - if (arena_size) - { - uint alignment_mask = (LZHAM_MIN_ALLOC_ALIGNMENT - 1); - m_arena_ofs = (LZHAM_MIN_ALLOC_ALIGNMENT - (reinterpret_cast(m_arena) & alignment_mask)) & alignment_mask; - } - } - - void lock() { m_lock.lock(); } - void unlock() { m_lock.unlock(); } - - bool ptr_is_in_arena(void *p) const - { - if ((p < m_arena) || (p >= (m_arena + m_arena_size))) - return false; - return true; - } - - // Important: only the decompressor uses an arena, and it's only single threaded, so this DOES NOT take the context lock. - void *arena_alloc(size_t size) - { - if ((!m_arena_size) || (size > LZHAM_MAX_ARENA_ALLOC_SIZE)) - return NULL; - - uint arena_remaining = m_arena_size - m_arena_ofs; - - size_t total_needed = (size + LZHAM_MIN_ALLOC_ALIGNMENT + (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) & ~(LZHAM_MIN_ALLOC_ALIGNMENT - 1); - if (arena_remaining < total_needed) - return NULL; - - void *p = m_arena + (m_arena_ofs + LZHAM_MIN_ALLOC_ALIGNMENT); - static_cast(p)[-1] = static_cast(size); - - m_arena_ofs += static_cast(total_needed); - - return p; - } - - uint arena_msize(const void *p) const - { - return static_cast(p)[-1]; - } - -#if LZHAM_MEM_STATS - void update_total_allocated(int block_delta, int64 byte_delta) - { - lock(); - - m_total_blocks += block_delta; - m_cur_allocated += byte_delta; - m_max_blocks = math::maximum(m_max_blocks, m_total_blocks); - m_max_allocated = math::maximum(m_max_allocated, m_cur_allocated); - - unlock(); - } -#endif // LZHAM_MEM_STATS - }; - - lzham_malloc_context lzham_create_malloc_context(uint arena_size) - { - malloc_context *p = static_cast((*g_pRealloc)(NULL, (sizeof(malloc_context) - 1) + arena_size + LZHAM_MIN_ALLOC_ALIGNMENT, NULL, true, g_pUser_data)); - helpers::construct(p); - p->init(arena_size); - return p; - } - - void lzham_destroy_malloc_context(lzham_malloc_context context) - { - LZHAM_ASSERT(context); - if (context) - { - malloc_context *p = static_cast(context); - LZHAM_VERIFY(p->m_sig == malloc_context::cSig); - - lzham_print_mem_stats(p); - - helpers::destruct(p); - p->m_sig = 0xDEADDEAD; - - (*g_pRealloc)(p, 0, NULL, true, g_pUser_data); - } - } - - void* lzham_malloc(lzham_malloc_context context, size_t size, size_t* pActual_size) - { - LZHAM_VERIFY(context); - - size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U); - if (!size) - size = sizeof(uint32); - - if (size > MAX_POSSIBLE_BLOCK_SIZE) - { - lzham_mem_error(context, "lzham_malloc: size too big"); - return NULL; - } - - size_t actual_size = size; - uint8* p_new; - - malloc_context *pContext = static_cast(context); - - LZHAM_VERIFY(pContext->m_sig == malloc_context::cSig); - - p_new = static_cast(pContext->arena_alloc(size)); - if (!p_new) - { - p_new = static_cast((*g_pRealloc)(NULL, size, &actual_size, true, g_pUser_data)); - } - - if (pActual_size) - *pActual_size = actual_size; - - if ((!p_new) || (actual_size < size)) - { - lzham_mem_error(context, "lzham_malloc: out of memory"); - return NULL; - } - - LZHAM_ASSERT((reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0); - -#if LZHAM_MEM_STATS - pContext->update_total_allocated(1, static_cast(actual_size)); -#endif - - return p_new; - } - - void* lzham_realloc(lzham_malloc_context context, void* p, size_t size, size_t* pActual_size, bool movable) - { - LZHAM_VERIFY(context); - - if ((ptr_bits_t)p & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) - { - lzham_mem_error(context, "lzham_realloc: bad ptr"); - return NULL; - } - - if (size > MAX_POSSIBLE_BLOCK_SIZE) - { - lzham_mem_error(context, "lzham_malloc: size too big"); - return NULL; - } - -#if LZHAM_MEM_STATS - size_t cur_size = p ? (*g_pMSize)(p, g_pUser_data) : 0; -#endif - - size_t actual_size = size; - void *p_new; - - malloc_context *pContext = static_cast(context); - - LZHAM_VERIFY(pContext->m_sig == malloc_context::cSig); - - if (pContext->ptr_is_in_arena(p)) - { - if (!movable) - return NULL; - - uint prev_size = pContext->arena_msize(p); - if (size <= prev_size) - { - p_new = p; - } - else - { - p_new = static_cast(pContext->arena_alloc(size)); - if (!p_new) - { - p_new = (*g_pRealloc)(NULL, size, &actual_size, true, g_pUser_data); - } - - memcpy(p_new, p, prev_size); - } - } - else - { - p_new = NULL; - - if (!p) - p_new = static_cast(pContext->arena_alloc(size)); - - if (!p_new) - p_new = (*g_pRealloc)(p, size, &actual_size, movable, g_pUser_data); - } - - if (pActual_size) - *pActual_size = actual_size; - - LZHAM_ASSERT((reinterpret_cast(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0); - -#if LZHAM_MEM_STATS - int num_new_blocks = 0; - if (p) - { - if (!p_new) - num_new_blocks = -1; - } - else if (p_new) - { - num_new_blocks = 1; - } - pContext->update_total_allocated(num_new_blocks, static_cast(actual_size) - static_cast(cur_size)); -#endif - - return p_new; - } - - void lzham_free(lzham_malloc_context context, void* p) - { - if (!p) - return; - - LZHAM_VERIFY(context); - - if (reinterpret_cast(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) - { - lzham_mem_error(context, "lzham_free: bad ptr"); - return; - } - - malloc_context *pContext = static_cast(context); - - LZHAM_VERIFY(pContext->m_sig == malloc_context::cSig); - -#if LZHAM_MEM_STATS - size_t cur_size = lzham_msize(context, p); - pContext->update_total_allocated(-1, -static_cast(cur_size)); -#endif - - if (!pContext->ptr_is_in_arena(p)) - { - (*g_pRealloc)(p, 0, NULL, true, g_pUser_data); - } - } - - size_t lzham_msize(lzham_malloc_context context, void* p) - { - if (!p) - return 0; - - if (reinterpret_cast(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) - { - lzham_mem_error(context, "lzham_msize: bad ptr"); - return 0; - } - - malloc_context *pContext = static_cast(context); - LZHAM_VERIFY(pContext->m_sig == malloc_context::cSig); - - if (pContext->ptr_is_in_arena(p)) - { - return pContext->arena_msize(p); - } - else - { - return (*g_pMSize)(p, g_pUser_data); - } - } - - void lzham_print_mem_stats(lzham_malloc_context context) - { - LZHAM_VERIFY(context); - -#if LZHAM_MEM_STATS - malloc_context *pContext = static_cast(context); - - LZHAM_VERIFY(pContext->m_sig == malloc_context::cSig); - - printf("Current blocks: %u, allocated: %" LZHAM_PRIu64 ", max ever allocated: %" LZHAM_PRIi64 "\n", pContext->m_total_blocks, (int64)pContext->m_cur_allocated, (int64)pContext->m_max_allocated); - printf("Max used arena: %u\n", pContext->m_arena_ofs); - printf("Max blocks: %" LZHAM_PRIu64 "\n", pContext->m_max_blocks); -#endif - } - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -// File: lzham_mem.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - typedef void *lzham_malloc_context; - - lzham_malloc_context lzham_create_malloc_context(uint arena_size); - void lzham_destroy_malloc_context(lzham_malloc_context context); - - void* lzham_malloc(lzham_malloc_context context, size_t size, size_t* pActual_size = NULL); - void* lzham_realloc(lzham_malloc_context context, void* p, size_t size, size_t* pActual_size = NULL, bool movable = true); - void lzham_free(lzham_malloc_context context, void* p); - size_t lzham_msize(lzham_malloc_context context, void* p); - - template - inline T* lzham_new(lzham_malloc_context context) - { - T* p = static_cast(lzham_malloc(context, sizeof(T))); - if (!p) return NULL; - if (LZHAM_IS_SCALAR_TYPE(T)) - return p; - return helpers::construct(p); - } - - template - inline T* lzham_new(lzham_malloc_context context, const A& init0) - { - T* p = static_cast(lzham_malloc(context, sizeof(T))); - if (!p) return NULL; - return new (static_cast(p)) T(init0); - } - - template - inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1) - { - T* p = static_cast(lzham_malloc(context, sizeof(T))); - if (!p) return NULL; - return new (static_cast(p)) T(init0, init1); - } - - template - inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1, const C& init2) - { - T* p = static_cast(lzham_malloc(context, sizeof(T))); - if (!p) return NULL; - return new (static_cast(p)) T(init0, init1, init2); - } - - template - inline T* lzham_new(lzham_malloc_context context, const A& init0, const B& init1, const C& init2, const D& init3) - { - T* p = static_cast(lzham_malloc(context, sizeof(T))); - if (!p) return NULL; - return new (static_cast(p)) T(init0, init1, init2, init3); - } - - template - inline T* lzham_new_array(lzham_malloc_context context, uint32 num) - { - if (!num) num = 1; - - uint8* q = static_cast(lzham_malloc(context, LZHAM_MIN_ALLOC_ALIGNMENT + sizeof(T) * num)); - if (!q) - return NULL; - - T* p = reinterpret_cast(q + LZHAM_MIN_ALLOC_ALIGNMENT); - - reinterpret_cast(p)[-1] = num; - reinterpret_cast(p)[-2] = ~num; - - if (!LZHAM_IS_SCALAR_TYPE(T)) - { - helpers::construct_array(p, num); - } - return p; - } - - template - inline void lzham_delete(lzham_malloc_context context, T* p) - { - if (p) - { - if (!LZHAM_IS_SCALAR_TYPE(T)) - { - helpers::destruct(p); - } - lzham_free(context, p); - } - } - - template - inline void lzham_delete_array(lzham_malloc_context context, T* p) - { - if (p) - { - const uint32 num = reinterpret_cast(p)[-1]; - const uint32 num_check = reinterpret_cast(p)[-2]; - LZHAM_ASSERT(num && (num == ~num_check)); - if (num == ~num_check) - { - if (!LZHAM_IS_SCALAR_TYPE(T)) - { - helpers::destruct_array(p, num); - } - - lzham_free(context, reinterpret_cast(p) - LZHAM_MIN_ALLOC_ALIGNMENT); - } - } - } - - void lzham_print_mem_stats(lzham_malloc_context context); - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,159 +0,0 @@ -// File: platform.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_timer.h" -#include - -#if LZHAM_PLATFORM_X360 -#include -#endif - -#define LZHAM_FORCE_DEBUGGER_PRESENT 0 - -#ifndef _MSC_VER -int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) -{ - if (!sizeOfBuffer) - return 0; - - va_list args; - va_start(args, format); - int c = vsnprintf(buffer, sizeOfBuffer, format, args); - va_end(args); - - buffer[sizeOfBuffer - 1] = '\0'; - - if (c < 0) - return static_cast(sizeOfBuffer - 1); - - return LZHAM_MIN(c, (int)sizeOfBuffer - 1); -} -int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args) -{ - if (!sizeOfBuffer) - return 0; - - int c = vsnprintf(buffer, sizeOfBuffer, format, args); - - buffer[sizeOfBuffer - 1] = '\0'; - - if (c < 0) - return static_cast(sizeOfBuffer - 1); - - return LZHAM_MIN(c, (int)sizeOfBuffer - 1); -} -#endif // __GNUC__ - -bool lzham_is_debugger_present(void) -{ -#if LZHAM_PLATFORM_X360 - return DmIsDebuggerPresent() != 0; -#elif LZHAM_USE_WIN32_API - return IsDebuggerPresent() != 0; -#elif LZHAM_FORCE_DEBUGGER_PRESENT - return true; -#else - return false; -#endif -} - -void lzham_debug_break(void) -{ -#if LZHAM_USE_WIN32_API - DebugBreak(); -#elif (TARGET_OS_MAC == 1) && (TARGET_IPHONE_SIMULATOR == 0) && (TARGET_OS_IPHONE == 0) -// __asm {int 3} -// __asm("int $3") - assert(0); -#else - assert(0); -#endif -} - -void lzham_output_debug_string(const char* p) -{ - LZHAM_NOTE_UNUSED(p); -#if LZHAM_USE_WIN32_API - OutputDebugStringA(p); -#else - fputs(p, stderr); -#endif -} - -#if LZHAM_BUFFERED_PRINTF -#include -// This stuff was a quick hack only intended for debugging/development. -namespace lzham -{ - struct buffered_str - { - enum { cBufSize = 256 }; - char m_buf[cBufSize]; - }; - - static std::vector g_buffered_strings; - static volatile long g_buffered_string_locked; - - static void lock_buffered_strings() - { - while (atomic_exchange32(&g_buffered_string_locked, 1) == 1) - { - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - lzham_yield_processor(); - } - - LZHAM_MEMORY_IMPORT_BARRIER - } - - static void unlock_buffered_strings() - { - LZHAM_MEMORY_EXPORT_BARRIER - - atomic_exchange32(&g_buffered_string_locked, 0); - } - - void lzham_buffered_printf(const char *format, ...) - { - format; - - char buf[lzham::buffered_str::cBufSize]; - - va_list args; - va_start(args, format); - vsnprintf_s(buf, sizeof(buf), sizeof(buf), format, args); - va_end(args); - - buf[sizeof(buf) - 1] = '\0'; - - lzham::lock_buffered_strings(); - - if (!lzham::g_buffered_strings.capacity()) - { - lzham::g_buffered_strings.reserve(2048); - } - - lzham::g_buffered_strings.resize(lzham::g_buffered_strings.size() + 1); - memcpy(lzham::g_buffered_strings.back().m_buf, buf, sizeof(buf)); - - lzham::unlock_buffered_strings(); - } - - void lzham_flush_buffered_printf() - { - lzham::lock_buffered_strings(); - - for (lzham::uint i = 0; i < lzham::g_buffered_strings.size(); i++) - { - printf("%s", lzham::g_buffered_strings[i].m_buf); - } - - lzham::g_buffered_strings.resize(0); - - lzham::unlock_buffered_strings(); - } - -} // namespace lzham -#endif - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,284 +0,0 @@ -// File: lzham_platform.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -bool lzham_is_debugger_present(void); -void lzham_debug_break(void); -void lzham_output_debug_string(const char* p); - -// actually in lzham_assert.cpp -void lzham_assert(const char* pExp, const char* pFile, unsigned line); -void lzham_fail(const char* pExp, const char* pFile, unsigned line); - -#ifdef WIN32 - #define LZHAM_BREAKPOINT DebuggerBreak(); - #define LZHAM_BUILTIN_EXPECT(c, v) c -#elif defined(__GNUC__) - #define LZHAM_BREAKPOINT asm("int $3"); - #define LZHAM_BUILTIN_EXPECT(c, v) __builtin_expect(c, v) -#else - #define LZHAM_BREAKPOINT - #define LZHAM_BUILTIN_EXPECT(c, v) c -#endif - -#if defined(__GNUC__) && LZHAM_PLATFORM_PC -extern __inline__ __attribute__((__always_inline__,__gnu_inline__)) void lzham_yield_processor() -{ - __asm__ __volatile__("pause"); -} -#elif LZHAM_PLATFORM_X360 -#define lzham_yield_processor() \ - YieldProcessor(); \ - __asm { or r0, r0, r0 } \ - YieldProcessor(); \ - __asm { or r1, r1, r1 } \ - YieldProcessor(); \ - __asm { or r0, r0, r0 } \ - YieldProcessor(); \ - __asm { or r1, r1, r1 } \ - YieldProcessor(); \ - __asm { or r0, r0, r0 } \ - YieldProcessor(); \ - __asm { or r1, r1, r1 } \ - YieldProcessor(); \ - __asm { or r0, r0, r0 } \ - YieldProcessor(); \ - __asm { or r1, r1, r1 } -#else -LZHAM_FORCE_INLINE void lzham_yield_processor() -{ -#if LZHAM_USE_MSVC_INTRINSICS - #if LZHAM_PLATFORM_PC_X64 - _mm_pause(); - #else - YieldProcessor(); - #endif -#else - // No implementation -#endif -} -#endif - -#ifndef _MSC_VER - int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...); - int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args); -#endif - -#if LZHAM_PLATFORM_X360 - #define LZHAM_MEMORY_EXPORT_BARRIER MemoryBarrier(); -#else - // Barriers shouldn't be necessary on x86/x64. - // TODO: Should use __sync_synchronize() on other platforms that support GCC. - #define LZHAM_MEMORY_EXPORT_BARRIER -#endif - -#if LZHAM_PLATFORM_X360 - #define LZHAM_MEMORY_IMPORT_BARRIER MemoryBarrier(); -#else - // Barriers shouldn't be necessary on x86/x64. - // TODO: Should use __sync_synchronize() on other platforms that support GCC. - #define LZHAM_MEMORY_IMPORT_BARRIER -#endif - -// Note: It's very important that LZHAM_READ_BIG_ENDIAN_UINT32() is fast on the target platform. -// This is used to read every DWORD from the input stream. - -#if LZHAM_USE_UNALIGNED_INT_LOADS - #if LZHAM_BIG_ENDIAN_CPU - #define LZHAM_READ_BIG_ENDIAN_UINT32(p) *reinterpret_cast(p) - #else - #if defined(LZHAM_USE_MSVC_INTRINSICS) - #define LZHAM_READ_BIG_ENDIAN_UINT32(p) _byteswap_ulong(*reinterpret_cast(p)) - #elif defined(__GNUC__) - #define LZHAM_READ_BIG_ENDIAN_UINT32(p) __builtin_bswap32(*reinterpret_cast(p)) - #else - #define LZHAM_READ_BIG_ENDIAN_UINT32(p) utils::swap32(*reinterpret_cast(p)) - #endif - #endif -#else - #define LZHAM_READ_BIG_ENDIAN_UINT32(p) ((reinterpret_cast(p)[0] << 24) | (reinterpret_cast(p)[1] << 16) | (reinterpret_cast(p)[2] << 8) | (reinterpret_cast(p)[3])) -#endif - -#if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS - extern "C" __int64 _InterlockedCompareExchange64(__int64 volatile * Destination, __int64 Exchange, __int64 Comperand); - #if defined(_MSC_VER) - #pragma intrinsic(_InterlockedCompareExchange64) - #endif -#endif // LZHAM_USE_WIN32_ATOMIC_FUNCTIONS - -namespace lzham -{ -#if LZHAM_USE_WIN32_ATOMIC_FUNCTIONS - typedef LONG atomic32_t; - typedef LONGLONG atomic64_t; - - // Returns the original value. - inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedCompareExchange(pDest, exchange, comparand); - } - - // Returns the original value. - inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 7) == 0); - return _InterlockedCompareExchange64(pDest, exchange, comparand); - } - - // Returns the resulting incremented value. - inline atomic32_t atomic_increment32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedIncrement(pDest); - } - - // Returns the resulting decremented value. - inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedDecrement(pDest); - } - - // Returns the original value. - inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedExchange(pDest, val); - } - - // Returns the resulting value. - inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedExchangeAdd(pDest, val) + val; - } - - // Returns the original value. - inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return InterlockedExchangeAdd(pDest, val); - } -#elif LZHAM_USE_GCC_ATOMIC_BUILTINS - typedef long atomic32_t; - typedef long long atomic64_t; - - // Returns the original value. - inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_val_compare_and_swap(pDest, comparand, exchange); - } - - // Returns the original value. - inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 7) == 0); - return __sync_val_compare_and_swap(pDest, comparand, exchange); - } - - // Returns the resulting incremented value. - inline atomic32_t atomic_increment32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_add_and_fetch(pDest, 1); - } - - // Returns the resulting decremented value. - inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_sub_and_fetch(pDest, 1); - } - - // Returns the original value. - inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_lock_test_and_set(pDest, val); - } - - // Returns the resulting value. - inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_add_and_fetch(pDest, val); - } - - // Returns the original value. - inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return __sync_fetch_and_add(pDest, val); - } -#else - #define LZHAM_NO_ATOMICS 1 - - // Atomic ops not supported - but try to do something reasonable. Assumes no threading at all. - typedef long atomic32_t; - typedef long long atomic64_t; - - inline atomic32_t atomic_compare_exchange32(atomic32_t volatile *pDest, atomic32_t exchange, atomic32_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - atomic32_t cur = *pDest; - if (cur == comparand) - *pDest = exchange; - return cur; - } - - inline atomic64_t atomic_compare_exchange64(atomic64_t volatile *pDest, atomic64_t exchange, atomic64_t comparand) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 7) == 0); - atomic64_t cur = *pDest; - if (cur == comparand) - *pDest = exchange; - return cur; - } - - inline atomic32_t atomic_increment32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return (*pDest += 1); - } - - inline atomic32_t atomic_decrement32(atomic32_t volatile *pDest) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return (*pDest -= 1); - } - - inline atomic32_t atomic_exchange32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - atomic32_t cur = *pDest; - *pDest = val; - return cur; - } - - inline atomic32_t atomic_add32(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - return (*pDest += val); - } - - inline atomic32_t atomic_exchange_add(atomic32_t volatile *pDest, atomic32_t val) - { - LZHAM_ASSERT((reinterpret_cast(pDest) & 3) == 0); - atomic32_t cur = *pDest; - *pDest += val; - return cur; - } - -#endif - -#if LZHAM_BUFFERED_PRINTF - void lzham_buffered_printf(const char *format, ...); - void lzham_flush_buffered_printf(); -#else - inline void lzham_buffered_printf(const char *format, ...) { (void)format; } - inline void lzham_flush_buffered_printf() { } -#endif - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,431 +0,0 @@ -// File: lzham_prefix_coding.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_prefix_coding.h" - -#ifdef LZHAM_BUILD_DEBUG - //#define TEST_DECODER_TABLES -#endif - -namespace lzham -{ - namespace prefix_coding - { - bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size) - { - const uint cMaxEverCodeSize = 34; - - if ((!num_syms) || (num_syms > cMaxSupportedSyms) || (max_code_size < 1) || (max_code_size > cMaxEverCodeSize)) - { - LZHAM_LOG_ERROR(3000); - return false; - } - - uint num_codes[cMaxEverCodeSize + 1]; - utils::zero_object(num_codes); - - bool should_limit = false; - - for (uint i = 0; i < num_syms; i++) - { - uint c = pCodesizes[i]; - - LZHAM_ASSERT(c <= cMaxEverCodeSize); - - num_codes[c]++; - if (c > max_code_size) - should_limit = true; - } - - if (!should_limit) - return true; - - uint ofs = 0; - uint next_sorted_ofs[cMaxEverCodeSize + 1]; - for (uint i = 1; i <= cMaxEverCodeSize; i++) - { - next_sorted_ofs[i] = ofs; - ofs += num_codes[i]; - } - - if ((ofs < 2) || (ofs > cMaxSupportedSyms)) - return true; - - if (ofs > (1U << max_code_size)) - { - LZHAM_LOG_ERROR(3001); - return false; - } - - for (uint i = max_code_size + 1; i <= cMaxEverCodeSize; i++) - num_codes[max_code_size] += num_codes[i]; - - // Technique of adjusting tree to enforce maximum code size from LHArc. - // (If you remember what LHArc was, you've been doing this for a LONG time.) - - uint total = 0; - for (uint i = max_code_size; i; --i) - total += (num_codes[i] << (max_code_size - i)); - - if (total == (1U << max_code_size)) - return true; - - do - { - num_codes[max_code_size]--; - - uint i; - for (i = max_code_size - 1; i; --i) - { - if (!num_codes[i]) - continue; - num_codes[i]--; - num_codes[i + 1] += 2; - break; - } - if (!i) - { - LZHAM_LOG_ERROR(3002); - return false; - } - - total--; - } while (total != (1U << max_code_size)); - - uint8 new_codesizes[cMaxSupportedSyms]; - uint8* p = new_codesizes; - for (uint i = 1; i <= max_code_size; i++) - { - uint n = num_codes[i]; - if (n) - { - memset(p, i, n); - p += n; - } - } - - for (uint i = 0; i < num_syms; i++) - { - const uint c = pCodesizes[i]; - if (c) - { - uint next_ofs = next_sorted_ofs[c]; - next_sorted_ofs[c] = next_ofs + 1; - - pCodesizes[i] = static_cast(new_codesizes[next_ofs]); - } - } - - return true; - } - - bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes) - { - uint num_codes[cMaxExpectedHuffCodeSize + 1]; - utils::zero_object(num_codes); - - for (uint i = 0; i < num_syms; i++) - { - uint c = pCodesizes[i]; - LZHAM_ASSERT(c <= cMaxExpectedHuffCodeSize); - num_codes[c]++; - } - - uint code = 0; - - uint next_code[cMaxExpectedHuffCodeSize + 1]; - next_code[0] = 0; - - for (uint i = 1; i <= cMaxExpectedHuffCodeSize; i++) - { - next_code[i] = code; - - code = (code + num_codes[i]) << 1; - } - - if (code != (1 << (cMaxExpectedHuffCodeSize + 1))) - { - uint t = 0; - for (uint i = 1; i <= cMaxExpectedHuffCodeSize; i++) - { - t += num_codes[i]; - if (t > 1) - { - LZHAM_LOG_ERROR(3003); - return false; - } - } - } - - for (uint i = 0; i < num_syms; i++) - { - uint c = pCodesizes[i]; - - LZHAM_ASSERT(!c || (next_code[c] <= cUINT16_MAX)); - - pCodes[i] = static_cast(next_code[c]++); - - LZHAM_ASSERT(!c || (math::total_bits(pCodes[i]) <= pCodesizes[i])); - } - - return true; - } - - static const uint16 g_uint16_sequence[cMaxSupportedSyms] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, - 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, - 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, - 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, - 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, - 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, - 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, - 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, - 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, - 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, - 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, - 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, - 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, - 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, - 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, - 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, - 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, - 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023 - }; - - bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits, const code_size_histogram &code_size_histo, bool sym_freq_all_ones) - { - uint min_codes[cMaxExpectedHuffCodeSize]; - - if ((!num_syms) || (table_bits > cMaxTableBits)) - { - LZHAM_LOG_ERROR(3004); - return false; - } - - pTables->m_num_syms = num_syms; - - uint sorted_positions[cMaxExpectedHuffCodeSize + 1]; - - uint next_code = 0; - - uint total_used_syms = 0; - uint max_code_size = 0; - uint min_code_size = UINT_MAX; - for (uint i = 1; i <= cMaxExpectedHuffCodeSize; i++) - { - const uint n = code_size_histo.m_num_codes[i]; - - if (!n) - pTables->m_max_codes[i - 1] = 0;//UINT_MAX; - else - { - min_code_size = math::minimum(min_code_size, i); - max_code_size = math::maximum(max_code_size, i); - - min_codes[i - 1] = next_code; - - pTables->m_max_codes[i - 1] = next_code + n - 1; - pTables->m_max_codes[i - 1] = 1 + ((pTables->m_max_codes[i - 1] << (16 - i)) | ((1 << (16 - i)) - 1)); - - pTables->m_val_ptrs[i - 1] = total_used_syms; - - sorted_positions[i] = total_used_syms; - - next_code += n; - total_used_syms += n; - } - - next_code <<= 1; - } - - pTables->m_total_used_syms = total_used_syms; - - if (total_used_syms > pTables->m_cur_sorted_symbol_order_size) - { - pTables->m_cur_sorted_symbol_order_size = total_used_syms; - - if (!math::is_power_of_2(total_used_syms)) - pTables->m_cur_sorted_symbol_order_size = math::minimum(num_syms, math::next_pow2(total_used_syms)); - - if (pTables->m_sorted_symbol_order) - { - lzham_delete_array(pTables->m_malloc_context, pTables->m_sorted_symbol_order); - pTables->m_sorted_symbol_order = NULL; - } - - pTables->m_sorted_symbol_order = lzham_new_array(pTables->m_malloc_context, pTables->m_cur_sorted_symbol_order_size); - if (!pTables->m_sorted_symbol_order) - { - LZHAM_LOG_ERROR(3005); - return false; - } - } - - pTables->m_min_code_size = static_cast(min_code_size); - pTables->m_max_code_size = static_cast(max_code_size); - - if (sym_freq_all_ones) - { - if (min_code_size == max_code_size) - { - memcpy(pTables->m_sorted_symbol_order, g_uint16_sequence, num_syms * sizeof(uint16)); - } - else - { - LZHAM_ASSERT((min_code_size + 1) == max_code_size); - LZHAM_ASSERT(pCodesizes[0] == max_code_size); - LZHAM_ASSERT(pCodesizes[code_size_histo.m_num_codes[max_code_size]] == min_code_size); - - memcpy(pTables->m_sorted_symbol_order + sorted_positions[max_code_size], g_uint16_sequence, code_size_histo.m_num_codes[max_code_size] * sizeof(uint16)); - - memcpy(pTables->m_sorted_symbol_order + sorted_positions[min_code_size], g_uint16_sequence + code_size_histo.m_num_codes[max_code_size], code_size_histo.m_num_codes[min_code_size] * sizeof(uint16)); - } - -#ifdef LZHAM_BUILD_DEBUG - for (uint i = 0; i < num_syms; i++) - { - uint c = pCodesizes[i]; - LZHAM_ASSERT(code_size_histo.m_num_codes[c]); - - uint sorted_pos = sorted_positions[c]++; - - LZHAM_ASSERT(sorted_pos < total_used_syms); - - LZHAM_ASSERT(pTables->m_sorted_symbol_order[sorted_pos] == i); - } -#endif - } - else - { - for (uint i = 0; i < num_syms; i++) - { - uint c = pCodesizes[i]; - LZHAM_ASSERT(code_size_histo.m_num_codes[c]); - - uint sorted_pos = sorted_positions[c]++; - - LZHAM_ASSERT(sorted_pos < total_used_syms); - - pTables->m_sorted_symbol_order[sorted_pos] = static_cast(i); - } - } - - if (table_bits <= pTables->m_min_code_size) - table_bits = 0; - pTables->m_table_bits = table_bits; - - if (table_bits) - { - uint table_size = 1 << table_bits; - if (table_size > pTables->m_cur_lookup_size) - { - pTables->m_cur_lookup_size = table_size; - - if (pTables->m_lookup) - { - lzham_delete_array(pTables->m_malloc_context, pTables->m_lookup); - pTables->m_lookup = NULL; - } - - pTables->m_lookup = lzham_new_array(pTables->m_malloc_context, table_size); - if (!pTables->m_lookup) - { - LZHAM_LOG_ERROR(3006); - return false; - } - } - - memset(pTables->m_lookup, 0xFF, static_cast(sizeof(pTables->m_lookup[0])) * (1UL << table_bits)); - - for (uint codesize = 1; codesize <= table_bits; codesize++) - { - if (!code_size_histo.m_num_codes[codesize]) - continue; - - const uint fillsize = table_bits - codesize; - const uint fillnum = 1 << fillsize; - - const uint min_code = min_codes[codesize - 1]; - const uint max_code = pTables->get_unshifted_max_code(codesize); - const uint val_ptr = pTables->m_val_ptrs[codesize - 1]; - - for (uint code = min_code; code <= max_code; code++) - { - const uint sym_index = pTables->m_sorted_symbol_order[ val_ptr + code - min_code ]; - LZHAM_ASSERT( pCodesizes[sym_index] == codesize ); - - for (uint j = 0; j < fillnum; j++) - { - const uint t = j + (code << fillsize); - - LZHAM_ASSERT(t < (1U << table_bits)); - - LZHAM_ASSERT(pTables->m_lookup[t] == cUINT32_MAX); - - pTables->m_lookup[t] = sym_index | (codesize << 16U); - } - } - } - } - - for (uint i = 0; i < cMaxExpectedHuffCodeSize; i++) - pTables->m_val_ptrs[i] -= min_codes[i]; - - pTables->m_table_max_code = 0; - pTables->m_decode_start_code_size = pTables->m_min_code_size; - - if (table_bits) - { - uint i; - for (i = table_bits; i >= 1; i--) - { - if (code_size_histo.m_num_codes[i]) - { - pTables->m_table_max_code = pTables->m_max_codes[i - 1]; - break; - } - } - if (i >= 1) - { - pTables->m_decode_start_code_size = table_bits + 1; - for (i = table_bits + 1; i <= max_code_size; i++) - { - if (code_size_histo.m_num_codes[i]) - { - pTables->m_decode_start_code_size = i; - break; - } - } - } - } - - // sentinels - pTables->m_max_codes[cMaxExpectedHuffCodeSize] = UINT_MAX; - pTables->m_val_ptrs[cMaxExpectedHuffCodeSize] = 0xFFFFF; - - pTables->m_table_shift = 32 - pTables->m_table_bits; - - return true; - } - - } // namespace prefix_codig - -} // namespace lzham - - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -// File: lzham_prefix_coding.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham_huffman_codes.h" - -namespace lzham -{ - namespace prefix_coding - { - const uint cMaxSupportedSyms = 1024; - - // This value can be tuned for a specific CPU. - const uint cMaxTableBits = 11; - - bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size); - - bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes); - - class decoder_tables - { - public: - inline decoder_tables(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) - { - } - - inline decoder_tables(const decoder_tables& other) : - m_malloc_context(other.m_malloc_context), - m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL) - { - *this = other; - } - - inline decoder_tables& operator= (const decoder_tables& rhs) - { - assign(rhs); - return *this; - } - - inline bool assign(const decoder_tables& rhs) - { - if (this == &rhs) - return true; - - if (m_malloc_context != rhs.m_malloc_context) - { - clear(); - - m_malloc_context = rhs.m_malloc_context; - } - - uint32* pCur_lookup = m_lookup; - uint16* pCur_sorted_symbol_order = m_sorted_symbol_order; - - memcpy(this, &rhs, sizeof(*this)); - - if ((pCur_lookup) && (pCur_sorted_symbol_order) && (rhs.m_cur_lookup_size == m_cur_lookup_size) && (rhs.m_cur_sorted_symbol_order_size == m_cur_sorted_symbol_order_size)) - { - m_lookup = pCur_lookup; - m_sorted_symbol_order = pCur_sorted_symbol_order; - - memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size); - memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size); - } - else - { - lzham_delete_array(m_malloc_context, pCur_lookup); - m_lookup = NULL; - - if (rhs.m_lookup) - { - m_lookup = lzham_new_array(m_malloc_context, m_cur_lookup_size); - if (!m_lookup) - return false; - memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size); - } - - lzham_delete_array(m_malloc_context, pCur_sorted_symbol_order); - m_sorted_symbol_order = NULL; - - if (rhs.m_sorted_symbol_order) - { - m_sorted_symbol_order = lzham_new_array(m_malloc_context, m_cur_sorted_symbol_order_size); - if (!m_sorted_symbol_order) - return false; - memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size); - } - } - - return true; - } - - inline void clear() - { - if (m_lookup) - { - lzham_delete_array(m_malloc_context, m_lookup); - m_lookup = 0; - m_cur_lookup_size = 0; - } - - if (m_sorted_symbol_order) - { - lzham_delete_array(m_malloc_context, m_sorted_symbol_order); - m_sorted_symbol_order = NULL; - m_cur_sorted_symbol_order_size = 0; - } - } - - inline ~decoder_tables() - { - if (m_lookup) - lzham_delete_array(m_malloc_context, m_lookup); - - if (m_sorted_symbol_order) - lzham_delete_array(m_malloc_context, m_sorted_symbol_order); - } - - // DO NOT use any complex classes here - it is bitwise copied. - - lzham_malloc_context m_malloc_context; - - uint m_num_syms; - uint m_total_used_syms; - uint m_table_bits; - uint m_table_shift; - uint m_table_max_code; - uint m_decode_start_code_size; - - uint8 m_min_code_size; - uint8 m_max_code_size; - - uint m_max_codes[cMaxExpectedHuffCodeSize + 1]; - int m_val_ptrs[cMaxExpectedHuffCodeSize + 1]; - - uint m_cur_lookup_size; - uint32* m_lookup; - - uint m_cur_sorted_symbol_order_size; - uint16* m_sorted_symbol_order; - - inline uint get_unshifted_max_code(uint len) const - { - LZHAM_ASSERT( (len >= 1) && (len <= cMaxExpectedHuffCodeSize) ); - uint k = m_max_codes[len - 1]; - if (!k) - return UINT_MAX; - return (k - 1) >> (16 - len); - } - }; - - bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits, const code_size_histogram &code_size_histo, bool sym_freq_all_ones); - - } // namespace prefix_coding - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1527 +0,0 @@ -// File: lzham_symbol_codec.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_symbol_codec.h" -#include "lzham_huffman_codes.h" - -// Was 16 in previous versions. -#define LZHAM_DEFAULT_MAX_UPDATE_INTERVAL 64 - -// Was 40 in previous versions -// Keep in sync with default setting in g_table_update_settings[] -#define LZHAM_DEFAULT_ADAPT_RATE 64U - -namespace lzham -{ - // Using a fixed table to convert from scaled probability to scaled bits for determinism across compilers/run-time libs/platforms. - uint32 g_prob_cost[cSymbolCodecArithProbScale] = - { - 0x0,0xB000000,0xA000000,0x96A3FE6,0x9000000,0x8AD961F,0x86A3FE6,0x8315130,0x8000000,0x7D47FCC,0x7AD961F, - 0x78A62B0,0x76A3FE6,0x74CAFFC,0x7315130,0x717D605,0x7000000,0x6E99C09,0x6D47FCC,0x6C087D3,0x6AD961F,0x69B9116, - 0x68A62B0,0x679F7D8,0x66A3FE6,0x65B2C3E,0x64CAFFC,0x63EBFB1,0x6315130,0x6245B5C,0x617D605,0x60BB9CA,0x6000000, - 0x5F4A296,0x5E99C09,0x5DEE74F,0x5D47FCC,0x5CA6144,0x5C087D3,0x5B6EFE1,0x5AD961F,0x5A47779,0x59B9116,0x592E050, - 0x58A62B0,0x58215EA,0x579F7D8,0x5720677,0x56A3FE6,0x562A260,0x55B2C3E,0x553DBEF,0x54CAFFC,0x545A701,0x53EBFB1, - 0x537F8CF,0x5315130,0x52AC7B8,0x5245B5C,0x51E0B1B,0x517D605,0x511BB33,0x50BB9CA,0x505D0FC,0x5000000,0x4FA461A, - 0x4F4A296,0x4EF14C7,0x4E99C09,0x4E437BE,0x4DEE74F,0x4D9AA2C,0x4D47FCC,0x4CF67A8,0x4CA6144,0x4C56C23,0x4C087D3, - 0x4BBB3E1,0x4B6EFE1,0x4B23B6D,0x4AD961F,0x4A8FF97,0x4A47779,0x49FFD6A,0x49B9116,0x4973228,0x492E050,0x48E9B41, - 0x48A62B0,0x4863655,0x48215EA,0x47E012C,0x479F7D8,0x475F9B0,0x4720677,0x46E1DF1,0x46A3FE6,0x4666C1D,0x462A260, - 0x45EE27C,0x45B2C3E,0x4577F74,0x453DBEF,0x4504180,0x44CAFFC,0x4492735,0x445A701,0x4422F38,0x43EBFB1,0x43B5846, - 0x437F8CF,0x434A129,0x4315130,0x42E08C0,0x42AC7B8,0x4278DF7,0x4245B5C,0x4212FC7,0x41E0B1B,0x41AED39,0x417D605, - 0x414C561,0x411BB33,0x40EB75F,0x40BB9CA,0x408C25C,0x405D0FC,0x402E58F,0x4000000,0x3FD2036,0x3FA461A,0x3F77197, - 0x3F4A296,0x3F1D903,0x3EF14C7,0x3EC55D0,0x3E99C09,0x3E6E75F,0x3E437BE,0x3E18D14,0x3DEE74F,0x3DC465D,0x3D9AA2C, - 0x3D712AC,0x3D47FCC,0x3D1F17A,0x3CF67A8,0x3CCE246,0x3CA6144,0x3C7E492,0x3C56C23,0x3C2F7E8,0x3C087D3,0x3BE1BD5, - 0x3BBB3E1,0x3B94FE9,0x3B6EFE1,0x3B493BC,0x3B23B6D,0x3AFE6E7,0x3AD961F,0x3AB4908,0x3A8FF97,0x3A6B9C0,0x3A47779, - 0x3A238B5,0x39FFD6A,0x39DC58E,0x39B9116,0x3995FF7,0x3973228,0x395079E,0x392E050,0x390BC34,0x38E9B41,0x38C7D6E, - 0x38A62B0,0x3884B01,0x3863655,0x38424A6,0x38215EA,0x3800A1A,0x37E012C,0x37BFB18,0x379F7D8,0x377F762,0x375F9B0, - 0x373FEBA,0x3720677,0x37010E1,0x36E1DF1,0x36C2DA0,0x36A3FE6,0x36854BC,0x3666C1D,0x3648600,0x362A260,0x360C136, - 0x35EE27C,0x35D062B,0x35B2C3E,0x35954AD,0x3577F74,0x355AC8C,0x353DBEF,0x3520D98,0x3504180,0x34E77A4,0x34CAFFC, - 0x34AEA83,0x3492735,0x347660B,0x345A701,0x343EA12,0x3422F38,0x340766F,0x33EBFB1,0x33D0AFA,0x33B5846,0x339A78E, - 0x337F8CF,0x3364C05,0x334A129,0x332F839,0x3315130,0x32FAC09,0x32E08C0,0x32C6751,0x32AC7B8,0x32929F1,0x3278DF7, - 0x325F3C6,0x3245B5C,0x322C4B2,0x3212FC7,0x31F9C96,0x31E0B1B,0x31C7B53,0x31AED39,0x31960CB,0x317D605,0x3164CE2, - 0x314C561,0x3133F7D,0x311BB33,0x310387F,0x30EB75F,0x30D37CE,0x30BB9CA,0x30A3D50,0x308C25C,0x30748EC,0x305D0FC, - 0x3045A88,0x302E58F,0x301720E,0x3000000,0x2FE8F64,0x2FD2036,0x2FBB274,0x2FA461A,0x2F8DB27,0x2F77197,0x2F60968, - 0x2F4A296,0x2F33D20,0x2F1D903,0x2F0763B,0x2EF14C7,0x2EDB4A5,0x2EC55D0,0x2EAF848,0x2E99C09,0x2E84111,0x2E6E75F, - 0x2E58EEE,0x2E437BE,0x2E2E1CB,0x2E18D14,0x2E03996,0x2DEE74F,0x2DD963D,0x2DC465D,0x2DAF7AD,0x2D9AA2C,0x2D85DD7, - 0x2D712AC,0x2D5C8A9,0x2D47FCC,0x2D33812,0x2D1F17A,0x2D0AC02,0x2CF67A8,0x2CE246A,0x2CCE246,0x2CBA13A,0x2CA6144, - 0x2C92262,0x2C7E492,0x2C6A7D4,0x2C56C23,0x2C43180,0x2C2F7E8,0x2C1BF5A,0x2C087D3,0x2BF5151,0x2BE1BD5,0x2BCE75A, - 0x2BBB3E1,0x2BA8166,0x2B94FE9,0x2B81F68,0x2B6EFE1,0x2B5C153,0x2B493BC,0x2B3671A,0x2B23B6D,0x2B110B1,0x2AFE6E7, - 0x2AEBE0C,0x2AD961F,0x2AC6F1E,0x2AB4908,0x2AA23DC,0x2A8FF97,0x2A7DC39,0x2A6B9C0,0x2A5982B,0x2A47779,0x2A357A7, - 0x2A238B5,0x2A11AA1,0x29FFD6A,0x29EE10F,0x29DC58E,0x29CAAE6,0x29B9116,0x29A781C,0x2995FF7,0x29848A6,0x2973228, - 0x2961C7B,0x295079E,0x293F390,0x292E050,0x291CDDD,0x290BC34,0x28FAB56,0x28E9B41,0x28D8BF4,0x28C7D6E,0x28B6FAD, - 0x28A62B0,0x2895677,0x2884B01,0x287404B,0x2863655,0x2852D1F,0x28424A6,0x2831CEA,0x28215EA,0x2810FA5,0x2800A1A, - 0x27F0547,0x27E012C,0x27CFDC7,0x27BFB18,0x27AF91E,0x279F7D8,0x278F744,0x277F762,0x276F831,0x275F9B0,0x274FBDE, - 0x273FEBA,0x2730242,0x2720677,0x2710B57,0x27010E1,0x26F1715,0x26E1DF1,0x26D2575,0x26C2DA0,0x26B3670,0x26A3FE6, - 0x26949FF,0x26854BC,0x267601C,0x2666C1D,0x26578BE,0x2648600,0x26393E1,0x262A260,0x261B17D,0x260C136,0x25FD18C, - 0x25EE27C,0x25DF407,0x25D062B,0x25C18E8,0x25B2C3E,0x25A402A,0x25954AD,0x25869C6,0x2577F74,0x25695B6,0x255AC8C, - 0x254C3F4,0x253DBEF,0x252F47B,0x2520D98,0x2512744,0x2504180,0x24F5C4B,0x24E77A4,0x24D9389,0x24CAFFC,0x24BCCFA, - 0x24AEA83,0x24A0897,0x2492735,0x248465C,0x247660B,0x2468643,0x245A701,0x244C847,0x243EA12,0x2430C63,0x2422F38, - 0x2415292,0x240766F,0x23F9ACF,0x23EBFB1,0x23DE515,0x23D0AFA,0x23C3160,0x23B5846,0x23A7FAB,0x239A78E,0x238CFF0, - 0x237F8CF,0x237222C,0x2364C05,0x2357659,0x234A129,0x233CC74,0x232F839,0x2322478,0x2315130,0x2307E61,0x22FAC09, - 0x22EDA29,0x22E08C0,0x22D37CE,0x22C6751,0x22B974A,0x22AC7B8,0x229F89B,0x22929F1,0x2285BBA,0x2278DF7,0x226C0A6, - 0x225F3C6,0x2252758,0x2245B5C,0x2238FCF,0x222C4B2,0x221FA05,0x2212FC7,0x22065F7,0x21F9C96,0x21ED3A2,0x21E0B1B, - 0x21D4301,0x21C7B53,0x21BB410,0x21AED39,0x21A26CD,0x21960CB,0x2189B33,0x217D605,0x217113F,0x2164CE2,0x21588EE, - 0x214C561,0x214023B,0x2133F7D,0x2127D25,0x211BB33,0x210F9A6,0x210387F,0x20F77BD,0x20EB75F,0x20DF765,0x20D37CE, - 0x20C789B,0x20BB9CA,0x20AFB5C,0x20A3D50,0x2097FA6,0x208C25C,0x2080574,0x20748EC,0x2068CC4,0x205D0FC,0x2051593, - 0x2045A88,0x2039FDD,0x202E58F,0x2022BA0,0x201720E,0x200B8D8,0x2000000,0x1FF4784,0x1FE8F64,0x1FDD79F,0x1FD2036, - 0x1FC6928,0x1FBB274,0x1FAFC1A,0x1FA461A,0x1F99074,0x1F8DB27,0x1F82633,0x1F77197,0x1F6BD53,0x1F60968,0x1F555D3, - 0x1F4A296,0x1F3EFB0,0x1F33D20,0x1F28AE6,0x1F1D903,0x1F12774,0x1F0763B,0x1EFC557,0x1EF14C7,0x1EE648C,0x1EDB4A5, - 0x1ED0511,0x1EC55D0,0x1EBA6E3,0x1EAF848,0x1EA49FF,0x1E99C09,0x1E8EE64,0x1E84111,0x1E79410,0x1E6E75F,0x1E63AFE, - 0x1E58EEE,0x1E4E32E,0x1E437BE,0x1E38C9D,0x1E2E1CB,0x1E23748,0x1E18D14,0x1E0E32E,0x1E03996,0x1DF904C,0x1DEE74F, - 0x1DE3E9F,0x1DD963D,0x1DCEE27,0x1DC465D,0x1DB9EDF,0x1DAF7AD,0x1DA50C7,0x1D9AA2C,0x1D903DC,0x1D85DD7,0x1D7B81C, - 0x1D712AC,0x1D66D86,0x1D5C8A9,0x1D52416,0x1D47FCC,0x1D3DBCA,0x1D33812,0x1D294A2,0x1D1F17A,0x1D14E9B,0x1D0AC02, - 0x1D009B2,0x1CF67A8,0x1CEC5E6,0x1CE246A,0x1CD8335,0x1CCE246,0x1CC419D,0x1CBA13A,0x1CB011C,0x1CA6144,0x1C9C1B0, - 0x1C92262,0x1C88358,0x1C7E492,0x1C74611,0x1C6A7D4,0x1C609DA,0x1C56C23,0x1C4CEB0,0x1C43180,0x1C39493,0x1C2F7E8, - 0x1C25B80,0x1C1BF5A,0x1C12375,0x1C087D3,0x1BFEC71,0x1BF5151,0x1BEB673,0x1BE1BD5,0x1BD8177,0x1BCE75A,0x1BC4D7D, - 0x1BBB3E1,0x1BB1A84,0x1BA8166,0x1B9E888,0x1B94FE9,0x1B8B789,0x1B81F68,0x1B78786,0x1B6EFE1,0x1B6587B,0x1B5C153, - 0x1B52A69,0x1B493BC,0x1B3FD4D,0x1B3671A,0x1B2D125,0x1B23B6D,0x1B1A5F1,0x1B110B1,0x1B07BAE,0x1AFE6E7,0x1AF525C, - 0x1AEBE0C,0x1AE29F8,0x1AD961F,0x1AD0281,0x1AC6F1E,0x1ABDBF6,0x1AB4908,0x1AAB655,0x1AA23DC,0x1A9919C,0x1A8FF97, - 0x1A86DCB,0x1A7DC39,0x1A74AE0,0x1A6B9C0,0x1A628DA,0x1A5982B,0x1A507B6,0x1A47779,0x1A3E774,0x1A357A7,0x1A2C812, - 0x1A238B5,0x1A1A98F,0x1A11AA1,0x1A08BEA,0x19FFD6A,0x19F6F21,0x19EE10F,0x19E5333,0x19DC58E,0x19D381F,0x19CAAE6, - 0x19C1DE3,0x19B9116,0x19B047E,0x19A781C,0x199EBEF,0x1995FF7,0x198D434,0x19848A6,0x197BD4D,0x1973228,0x196A737, - 0x1961C7B,0x19591F3,0x195079E,0x1947D7D,0x193F390,0x19369D7,0x192E050,0x19256FD,0x191CDDD,0x19144EF,0x190BC34, - 0x19033AC,0x18FAB56,0x18F2333,0x18E9B41,0x18E1382,0x18D8BF4,0x18D0498,0x18C7D6E,0x18BF675,0x18B6FAD,0x18AE916, - 0x18A62B0,0x189DC7C,0x1895677,0x188D0A4,0x1884B01,0x187C58E,0x187404B,0x186BB38,0x1863655,0x185B1A2,0x1852D1F, - 0x184A8CB,0x18424A6,0x183A0B1,0x1831CEA,0x1829953,0x18215EA,0x18192B0,0x1810FA5,0x1808CC8,0x1800A1A,0x17F8799, - 0x17F0547,0x17E8322,0x17E012C,0x17D7F63,0x17CFDC7,0x17C7C59,0x17BFB18,0x17B7A05,0x17AF91E,0x17A7865,0x179F7D8, - 0x1797778,0x178F744,0x178773D,0x177F762,0x17777B4,0x176F831,0x17678DB,0x175F9B0,0x1757AB1,0x174FBDE,0x1747D36, - 0x173FEBA,0x1738068,0x1730242,0x1728447,0x1720677,0x17188D2,0x1710B57,0x1708E07,0x17010E1,0x16F93E6,0x16F1715, - 0x16E9A6E,0x16E1DF1,0x16DA19E,0x16D2575,0x16CA976,0x16C2DA0,0x16BB1F3,0x16B3670,0x16ABB16,0x16A3FE6,0x169C4DE, - 0x16949FF,0x168CF49,0x16854BC,0x167DA58,0x167601C,0x166E608,0x1666C1D,0x165F25A,0x16578BE,0x164FF4B,0x1648600, - 0x1640CDD,0x16393E1,0x1631B0D,0x162A260,0x16229DB,0x161B17D,0x1613946,0x160C136,0x160494D,0x15FD18C,0x15F59F0, - 0x15EE27C,0x15E6B2E,0x15DF407,0x15D7D06,0x15D062B,0x15C8F77,0x15C18E8,0x15BA280,0x15B2C3E,0x15AB621,0x15A402A, - 0x159CA59,0x15954AD,0x158DF27,0x15869C6,0x157F48A,0x1577F74,0x1570A82,0x15695B6,0x156210E,0x155AC8C,0x155382E, - 0x154C3F4,0x1544FDF,0x153DBEF,0x1536823,0x152F47B,0x15280F7,0x1520D98,0x1519A5C,0x1512744,0x150B450,0x1504180, - 0x14FCED4,0x14F5C4B,0x14EE9E6,0x14E77A4,0x14E0585,0x14D9389,0x14D21B1,0x14CAFFC,0x14C3E69,0x14BCCFA,0x14B5BAD, - 0x14AEA83,0x14A797C,0x14A0897,0x14997D5,0x1492735,0x148B6B7,0x148465C,0x147D622,0x147660B,0x146F616,0x1468643, - 0x1461691,0x145A701,0x1453793,0x144C847,0x144591C,0x143EA12,0x1437B2A,0x1430C63,0x1429DBD,0x1422F38,0x141C0D5, - 0x1415292,0x140E470,0x140766F,0x140088F,0x13F9ACF,0x13F2D30,0x13EBFB1,0x13E5253,0x13DE515,0x13D77F8,0x13D0AFA, - 0x13C9E1D,0x13C3160,0x13BC4C3,0x13B5846,0x13AEBE8,0x13A7FAB,0x13A138D,0x139A78E,0x1393BAF,0x138CFF0,0x1386450, - 0x137F8CF,0x1378D6E,0x137222C,0x136B709,0x1364C05,0x135E11F,0x1357659,0x1350BB2,0x134A129,0x13436C0,0x133CC74, - 0x1336248,0x132F839,0x1328E4A,0x1322478,0x131BAC5,0x1315130,0x130E7B9,0x1307E61,0x1301526,0x12FAC09,0x12F430A, - 0x12EDA29,0x12E7166,0x12E08C0,0x12DA038,0x12D37CE,0x12CCF81,0x12C6751,0x12BFF3F,0x12B974A,0x12B2F73,0x12AC7B8, - 0x12A601B,0x129F89B,0x1299137,0x12929F1,0x128C2C7,0x1285BBA,0x127F4CA,0x1278DF7,0x1272740,0x126C0A6,0x1265A28, - 0x125F3C6,0x1258D81,0x1252758,0x124C14C,0x1245B5C,0x123F587,0x1238FCF,0x1232A33,0x122C4B2,0x1225F4E,0x121FA05, - 0x12194D8,0x1212FC7,0x120CAD1,0x12065F7,0x1200139,0x11F9C96,0x11F380E,0x11ED3A2,0x11E6F51,0x11E0B1B,0x11DA700, - 0x11D4301,0x11CDF1C,0x11C7B53,0x11C17A4,0x11BB410,0x11B5097,0x11AED39,0x11A89F6,0x11A26CD,0x119C3BF,0x11960CB, - 0x118FDF2,0x1189B33,0x118388F,0x117D605,0x1177395,0x117113F,0x116AF04,0x1164CE2,0x115EADB,0x11588EE,0x115271A, - 0x114C561,0x11463C1,0x114023B,0x113A0CF,0x1133F7D,0x112DE44,0x1127D25,0x1121C1F,0x111BB33,0x1115A60,0x110F9A6, - 0x1109906,0x110387F,0x10FD811,0x10F77BD,0x10F1781,0x10EB75F,0x10E5755,0x10DF765,0x10D978D,0x10D37CE,0x10CD828, - 0x10C789B,0x10C1926,0x10BB9CA,0x10B5A87,0x10AFB5C,0x10A9C4A,0x10A3D50,0x109DE6F,0x1097FA6,0x10920F5,0x108C25C, - 0x10863DC,0x1080574,0x107A724,0x10748EC,0x106EACC,0x1068CC4,0x1062ED4,0x105D0FC,0x105733B,0x1051593,0x104B802, - 0x1045A88,0x103FD27,0x1039FDD,0x10342AA,0x102E58F,0x102888C,0x1022BA0,0x101CECB,0x101720E,0x1011567,0x100B8D8, - 0x1005C61,0x1000000,0xFFA3B6,0xFF4784,0xFEEB68,0xFE8F64,0xFE3376,0xFDD79F,0xFD7BDF,0xFD2036,0xFCC4A3, - 0xFC6928,0xFC0DC2,0xFBB274,0xFB573C,0xFAFC1A,0xFAA10F,0xFA461A,0xF9EB3C,0xF99074,0xF935C2,0xF8DB27, - 0xF880A2,0xF82633,0xF7CBDA,0xF77197,0xF7176A,0xF6BD53,0xF66353,0xF60968,0xF5AF93,0xF555D3,0xF4FC2A, - 0xF4A296,0xF44918,0xF3EFB0,0xF3965D,0xF33D20,0xF2E3F9,0xF28AE6,0xF231EA,0xF1D903,0xF18031,0xF12774, - 0xF0CECD,0xF0763B,0xF01DBF,0xEFC557,0xEF6D05,0xEF14C7,0xEEBC9F,0xEE648C,0xEE0C8E,0xEDB4A5,0xED5CD0, - 0xED0511,0xECAD66,0xEC55D0,0xEBFE4F,0xEBA6E3,0xEB4F8B,0xEAF848,0xEAA119,0xEA49FF,0xE9F2FA,0xE99C09, - 0xE9452D,0xE8EE64,0xE897B1,0xE84111,0xE7EA86,0xE79410,0xE73DAD,0xE6E75F,0xE69124,0xE63AFE,0xE5E4EC, - 0xE58EEE,0xE53904,0xE4E32E,0xE48D6C,0xE437BE,0xE3E223,0xE38C9D,0xE3372A,0xE2E1CB,0xE28C80,0xE23748, - 0xE1E224,0xE18D14,0xE13817,0xE0E32E,0xE08E58,0xE03996,0xDFE4E7,0xDF904C,0xDF3BC4,0xDEE74F,0xDE92ED, - 0xDE3E9F,0xDDEA64,0xDD963D,0xDD4228,0xDCEE27,0xDC9A38,0xDC465D,0xDBF295,0xDB9EDF,0xDB4B3D,0xDAF7AD, - 0xDAA431,0xDA50C7,0xD9FD70,0xD9AA2C,0xD956FB,0xD903DC,0xD8B0D0,0xD85DD7,0xD80AF1,0xD7B81C,0xD7655B, - 0xD712AC,0xD6C010,0xD66D86,0xD61B0E,0xD5C8A9,0xD57656,0xD52416,0xD4D1E7,0xD47FCC,0xD42DC2,0xD3DBCA, - 0xD389E5,0xD33812,0xD2E651,0xD294A2,0xD24305,0xD1F17A,0xD1A001,0xD14E9B,0xD0FD46,0xD0AC02,0xD05AD1, - 0xD009B2,0xCFB8A4,0xCF67A8,0xCF16BE,0xCEC5E6,0xCE751F,0xCE246A,0xCDD3C7,0xCD8335,0xCD32B5,0xCCE246, - 0xCC91E9,0xCC419D,0xCBF163,0xCBA13A,0xCB5122,0xCB011C,0xCAB127,0xCA6144,0xCA1171,0xC9C1B0,0xC97200, - 0xC92262,0xC8D2D4,0xC88358,0xC833ED,0xC7E492,0xC79549,0xC74611,0xC6F6EA,0xC6A7D4,0xC658CE,0xC609DA, - 0xC5BAF6,0xC56C23,0xC51D61,0xC4CEB0,0xC48010,0xC43180,0xC3E301,0xC39493,0xC34635,0xC2F7E8,0xC2A9AC, - 0xC25B80,0xC20D64,0xC1BF5A,0xC1715F,0xC12375,0xC0D59C,0xC087D3,0xC03A1A,0xBFEC71,0xBF9ED9,0xBF5151, - 0xBF03DA,0xBEB673,0xBE691B,0xBE1BD5,0xBDCE9E,0xBD8177,0xBD3461,0xBCE75A,0xBC9A64,0xBC4D7D,0xBC00A7, - 0xBBB3E1,0xBB672A,0xBB1A84,0xBACDED,0xBA8166,0xBA34EF,0xB9E888,0xB99C31,0xB94FE9,0xB903B1,0xB8B789, - 0xB86B71,0xB81F68,0xB7D36F,0xB78786,0xB73BAC,0xB6EFE1,0xB6A427,0xB6587B,0xB60CDF,0xB5C153,0xB575D6, - 0xB52A69,0xB4DF0B,0xB493BC,0xB4487D,0xB3FD4D,0xB3B22C,0xB3671A,0xB31C18,0xB2D125,0xB28641,0xB23B6D, - 0xB1F0A7,0xB1A5F1,0xB15B4A,0xB110B1,0xB0C628,0xB07BAE,0xB03143,0xAFE6E7,0xAF9C9A,0xAF525C,0xAF082C, - 0xAEBE0C,0xAE73FA,0xAE29F8,0xADE004,0xAD961F,0xAD4C49,0xAD0281,0xACB8C8,0xAC6F1E,0xAC2583,0xABDBF6, - 0xAB9278,0xAB4908,0xAAFFA7,0xAAB655,0xAA6D11,0xAA23DC,0xA9DAB5,0xA9919C,0xA94893,0xA8FF97,0xA8B6AA, - 0xA86DCB,0xA824FB,0xA7DC39,0xA79386,0xA74AE0,0xA70249,0xA6B9C0,0xA67146,0xA628DA,0xA5E07B,0xA5982B, - 0xA54FEA,0xA507B6,0xA4BF90,0xA47779,0xA42F6F,0xA3E774,0xA39F87,0xA357A7,0xA30FD6,0xA2C812,0xA2805D, - 0xA238B5,0xA1F11B,0xA1A98F,0xA16211,0xA11AA1,0xA0D33F,0xA08BEA,0xA044A4,0x9FFD6A,0x9FB63F,0x9F6F21, - 0x9F2811,0x9EE10F,0x9E9A1B,0x9E5333,0x9E0C5A,0x9DC58E,0x9D7ED0,0x9D381F,0x9CF17C,0x9CAAE6,0x9C645E, - 0x9C1DE3,0x9BD776,0x9B9116,0x9B4AC3,0x9B047E,0x9ABE46,0x9A781C,0x9A31FF,0x99EBEF,0x99A5EC,0x995FF7, - 0x991A0F,0x98D434,0x988E67,0x9848A6,0x9802F3,0x97BD4D,0x9777B4,0x973228,0x96ECA9,0x96A737,0x9661D3, - 0x961C7B,0x95D730,0x9591F3,0x954CC2,0x95079E,0x94C287,0x947D7D,0x943880,0x93F390,0x93AEAD,0x9369D7, - 0x93250D,0x92E050,0x929BA0,0x9256FD,0x921266,0x91CDDD,0x91895F,0x9144EF,0x91008B,0x90BC34,0x9077EA, - 0x9033AC,0x8FEF7B,0x8FAB56,0x8F673E,0x8F2333,0x8EDF34,0x8E9B41,0x8E575B,0x8E1382,0x8DCFB5,0x8D8BF4, - 0x8D4840,0x8D0498,0x8CC0FD,0x8C7D6E,0x8C39EB,0x8BF675,0x8BB30B,0x8B6FAD,0x8B2C5B,0x8AE916,0x8AA5DD, - 0x8A62B0,0x8A1F90,0x89DC7C,0x899973,0x895677,0x891388,0x88D0A4,0x888DCC,0x884B01,0x880841,0x87C58E, - 0x8782E6,0x87404B,0x86FDBC,0x86BB38,0x8678C1,0x863655,0x85F3F6,0x85B1A2,0x856F5B,0x852D1F,0x84EAEF, - 0x84A8CB,0x8466B3,0x8424A6,0x83E2A6,0x83A0B1,0x835EC8,0x831CEA,0x82DB19,0x829953,0x825799,0x8215EA, - 0x81D448,0x8192B0,0x815125,0x810FA5,0x80CE31,0x808CC8,0x804B6B,0x800A1A,0x7FC8D4,0x7F8799,0x7F466A, - 0x7F0547,0x7EC42F,0x7E8322,0x7E4221,0x7E012C,0x7DC041,0x7D7F63,0x7D3E8F,0x7CFDC7,0x7CBD0B,0x7C7C59, - 0x7C3BB3,0x7BFB18,0x7BBA89,0x7B7A05,0x7B398C,0x7AF91E,0x7AB8BC,0x7A7865,0x7A3819,0x79F7D8,0x79B7A2, - 0x797778,0x793759,0x78F744,0x78B73B,0x78773D,0x78374A,0x77F762,0x77B786,0x7777B4,0x7737ED,0x76F831, - 0x76B881,0x7678DB,0x763940,0x75F9B0,0x75BA2B,0x757AB1,0x753B42,0x74FBDE,0x74BC84,0x747D36,0x743DF2, - 0x73FEBA,0x73BF8C,0x738068,0x734150,0x730242,0x72C33F,0x728447,0x72455A,0x720677,0x71C79F,0x7188D2, - 0x714A0F,0x710B57,0x70CCAA,0x708E07,0x704F6F,0x7010E1,0x6FD25E,0x6F93E6,0x6F5578,0x6F1715,0x6ED8BC, - 0x6E9A6E,0x6E5C2B,0x6E1DF1,0x6DDFC3,0x6DA19E,0x6D6385,0x6D2575,0x6CE770,0x6CA976,0x6C6B86,0x6C2DA0, - 0x6BEFC4,0x6BB1F3,0x6B742D,0x6B3670,0x6AF8BE,0x6ABB16,0x6A7D79,0x6A3FE6,0x6A025D,0x69C4DE,0x69876A, - 0x6949FF,0x690C9F,0x68CF49,0x6891FE,0x6854BC,0x681785,0x67DA58,0x679D35,0x67601C,0x67230D,0x66E608, - 0x66A90D,0x666C1D,0x662F36,0x65F25A,0x65B587,0x6578BE,0x653C00,0x64FF4B,0x64C2A1,0x648600,0x644969, - 0x640CDD,0x63D05A,0x6393E1,0x635772,0x631B0D,0x62DEB2,0x62A260,0x626619,0x6229DB,0x61EDA7,0x61B17D, - 0x61755D,0x613946,0x60FD39,0x60C136,0x60853D,0x60494D,0x600D68,0x5FD18C,0x5F95B9,0x5F59F0,0x5F1E31, - 0x5EE27C,0x5EA6D0,0x5E6B2E,0x5E2F96,0x5DF407,0x5DB882,0x5D7D06,0x5D4194,0x5D062B,0x5CCACC,0x5C8F77, - 0x5C542B,0x5C18E8,0x5BDDAF,0x5BA280,0x5B675A,0x5B2C3E,0x5AF12B,0x5AB621,0x5A7B21,0x5A402A,0x5A053D, - 0x59CA59,0x598F7E,0x5954AD,0x5919E5,0x58DF27,0x58A472,0x5869C6,0x582F23,0x57F48A,0x57B9FA,0x577F74, - 0x5744F6,0x570A82,0x56D018,0x5695B6,0x565B5E,0x56210E,0x55E6C8,0x55AC8C,0x557258,0x55382E,0x54FE0C, - 0x54C3F4,0x5489E5,0x544FDF,0x5415E2,0x53DBEF,0x53A204,0x536823,0x532E4A,0x52F47B,0x52BAB5,0x5280F7, - 0x524743,0x520D98,0x51D3F5,0x519A5C,0x5160CC,0x512744,0x50EDC6,0x50B450,0x507AE4,0x504180,0x500826, - 0x4FCED4,0x4F958B,0x4F5C4B,0x4F2314,0x4EE9E6,0x4EB0C0,0x4E77A4,0x4E3E90,0x4E0585,0x4DCC83,0x4D9389, - 0x4D5A99,0x4D21B1,0x4CE8D2,0x4CAFFC,0x4C772E,0x4C3E69,0x4C05AD,0x4BCCFA,0x4B944F,0x4B5BAD,0x4B2314, - 0x4AEA83,0x4AB1FB,0x4A797C,0x4A4105,0x4A0897,0x49D031,0x4997D5,0x495F80,0x492735,0x48EEF2,0x48B6B7, - 0x487E85,0x48465C,0x480E3B,0x47D622,0x479E13,0x47660B,0x472E0C,0x46F616,0x46BE28,0x468643,0x464E66, - 0x461691,0x45DEC5,0x45A701,0x456F46,0x453793,0x44FFE9,0x44C847,0x4490AD,0x44591C,0x442193,0x43EA12, - 0x43B29A,0x437B2A,0x4343C2,0x430C63,0x42D50C,0x429DBD,0x426676,0x422F38,0x41F802,0x41C0D5,0x4189AF, - 0x415292,0x411B7D,0x40E470,0x40AD6B,0x40766F,0x403F7B,0x40088F,0x3FD1AB,0x3F9ACF,0x3F63FB,0x3F2D30, - 0x3EF66D,0x3EBFB1,0x3E88FE,0x3E5253,0x3E1BB0,0x3DE515,0x3DAE83,0x3D77F8,0x3D4175,0x3D0AFA,0x3CD488, - 0x3C9E1D,0x3C67BB,0x3C3160,0x3BFB0E,0x3BC4C3,0x3B8E80,0x3B5846,0x3B2213,0x3AEBE8,0x3AB5C5,0x3A7FAB, - 0x3A4998,0x3A138D,0x39DD89,0x39A78E,0x39719B,0x393BAF,0x3905CC,0x38CFF0,0x389A1C,0x386450,0x382E8C, - 0x37F8CF,0x37C31B,0x378D6E,0x3757C9,0x37222C,0x36EC96,0x36B709,0x368183,0x364C05,0x36168E,0x35E11F, - 0x35ABB9,0x357659,0x354102,0x350BB2,0x34D66A,0x34A129,0x346BF1,0x3436C0,0x340196,0x33CC74,0x33975A, - 0x336248,0x332D3D,0x32F839,0x32C33E,0x328E4A,0x32595D,0x322478,0x31EF9B,0x31BAC5,0x3185F7,0x315130, - 0x311C71,0x30E7B9,0x30B309,0x307E61,0x3049C0,0x301526,0x2FE094,0x2FAC09,0x2F7786,0x2F430A,0x2F0E96, - 0x2EDA29,0x2EA5C4,0x2E7166,0x2E3D0F,0x2E08C0,0x2DD479,0x2DA038,0x2D6BFF,0x2D37CE,0x2D03A4,0x2CCF81, - 0x2C9B66,0x2C6751,0x2C3345,0x2BFF3F,0x2BCB41,0x2B974A,0x2B635B,0x2B2F73,0x2AFB92,0x2AC7B8,0x2A93E6, - 0x2A601B,0x2A2C57,0x29F89B,0x29C4E5,0x299137,0x295D90,0x2929F1,0x28F658,0x28C2C7,0x288F3D,0x285BBA, - 0x28283F,0x27F4CA,0x27C15D,0x278DF7,0x275A98,0x272740,0x26F3EF,0x26C0A6,0x268D63,0x265A28,0x2626F4, - 0x25F3C6,0x25C0A0,0x258D81,0x255A69,0x252758,0x24F44F,0x24C14C,0x248E50,0x245B5C,0x24286E,0x23F587, - 0x23C2A8,0x238FCF,0x235CFD,0x232A33,0x22F76F,0x22C4B2,0x2291FD,0x225F4E,0x222CA6,0x21FA05,0x21C76B, - 0x2194D8,0x21624C,0x212FC7,0x20FD49,0x20CAD1,0x209861,0x2065F7,0x203395,0x200139,0x1FCEE4,0x1F9C96, - 0x1F6A4F,0x1F380E,0x1F05D5,0x1ED3A2,0x1EA176,0x1E6F51,0x1E3D32,0x1E0B1B,0x1DD90A,0x1DA700,0x1D74FD, - 0x1D4301,0x1D110B,0x1CDF1C,0x1CAD34,0x1C7B53,0x1C4978,0x1C17A4,0x1BE5D7,0x1BB410,0x1B8250,0x1B5097, - 0x1B1EE5,0x1AED39,0x1ABB94,0x1A89F6,0x1A585E,0x1A26CD,0x19F542,0x19C3BF,0x199241,0x1960CB,0x192F5B, - 0x18FDF2,0x18CC8F,0x189B33,0x1869DE,0x18388F,0x180746,0x17D605,0x17A4C9,0x177395,0x174267,0x17113F, - 0x16E01E,0x16AF04,0x167DF0,0x164CE2,0x161BDC,0x15EADB,0x15B9E1,0x1588EE,0x155801,0x15271A,0x14F63A, - 0x14C561,0x14948E,0x1463C1,0x1432FB,0x14023B,0x13D182,0x13A0CF,0x137023,0x133F7D,0x130EDD,0x12DE44, - 0x12ADB1,0x127D25,0x124C9F,0x121C1F,0x11EBA6,0x11BB33,0x118AC6,0x115A60,0x112A00,0x10F9A6,0x10C953, - 0x109906,0x1068BF,0x10387F,0x100845,0xFD811,0xFA7E4,0xF77BD,0xF479C,0xF1781,0xEE76D,0xEB75F, - 0xE8757,0xE5755,0xE275A,0xDF765,0xDC776,0xD978D,0xD67AA,0xD37CE,0xD07F8,0xCD828,0xCA85E, - 0xC789B,0xC48DD,0xC1926,0xBE975,0xBB9CA,0xB8A26,0xB5A87,0xB2AEF,0xAFB5C,0xACBD0,0xA9C4A, - 0xA6CCA,0xA3D50,0xA0DDC,0x9DE6F,0x9AF07,0x97FA6,0x9504A,0x920F5,0x8F1A6,0x8C25C,0x89319, - 0x863DC,0x834A5,0x80574,0x7D649,0x7A724,0x77805,0x748EC,0x719D9,0x6EACC,0x6BBC5,0x68CC4, - 0x65DC9,0x62ED4,0x5FFE5,0x5D0FC,0x5A218,0x5733B,0x54464,0x51593,0x4E6C7,0x4B802,0x48942, - 0x45A88,0x42BD5,0x3FD27,0x3CE7F,0x39FDD,0x37141,0x342AA,0x3141A,0x2E58F,0x2B70B,0x2888C, - 0x25A13,0x22BA0,0x1FD33,0x1CECB,0x1A069,0x1720E,0x143B8,0x11567,0xE71D,0xB8D8,0x8A9A, - 0x5C61,0x2E2D - }; - -#define LZHAM_CREATE_PROB_COST_TABLE 0 - -#if LZHAM_CREATE_PROB_COST_TABLE - class arith_prob_cost_initializer - { - public: - arith_prob_cost_initializer() - { - const double cInvLn2 = 1.4426950408889634073599246810019; // 1.0/ln(2) - - for (uint i = 0; i < cSymbolCodecArithProbScale; i++) - { - double flBits = i ? (-log(i * (1.0 / cSymbolCodecArithProbScale)) * cInvLn2) : 0; - g_prob_cost[i] = static_cast(floor(.5f + flBits * cBitCostScale)); - printf("0x%X,", g_prob_cost[i]); - if ((i % 11) == 10) printf("\n"); - } - printf("\n"); - } - }; - static arith_prob_cost_initializer g_prob_cost_initializer; -#endif - - quasi_adaptive_huffman_data_model::quasi_adaptive_huffman_data_model(lzham_malloc_context malloc_context, bool encoding, uint total_syms, uint max_update_interval, uint adapt_rate) : - m_malloc_context(malloc_context), - m_initial_sym_freq(malloc_context), - m_sym_freq(malloc_context), - m_codes(malloc_context), - m_code_sizes(malloc_context), - m_pDecode_tables(NULL), - m_total_syms(0), - m_max_cycle(0), - m_update_cycle(0), - m_symbols_until_update(0), - m_total_count(0), - m_decoder_table_bits(0), - m_max_update_interval(static_cast(max_update_interval)), - m_adapt_rate(static_cast(adapt_rate)), - m_encoding(encoding) - { - if (total_syms) - { - init2(malloc_context, encoding, total_syms, max_update_interval, adapt_rate, NULL); - } - } - - quasi_adaptive_huffman_data_model::quasi_adaptive_huffman_data_model(const quasi_adaptive_huffman_data_model& other) : - m_malloc_context(other.m_malloc_context), - m_initial_sym_freq(other.m_malloc_context), - m_sym_freq(other.m_malloc_context), - m_codes(other.m_malloc_context), - m_code_sizes(other.m_malloc_context), - m_pDecode_tables(NULL), - m_total_syms(0), - m_max_cycle(0), - m_update_cycle(0), - m_symbols_until_update(0), - m_total_count(0), - m_decoder_table_bits(0), - m_max_update_interval(0), - m_adapt_rate(0), - m_encoding(false) - { - *this = other; - } - - quasi_adaptive_huffman_data_model::~quasi_adaptive_huffman_data_model() - { - if (m_pDecode_tables) - lzham_delete(m_malloc_context, m_pDecode_tables); - } - - bool quasi_adaptive_huffman_data_model::assign(const quasi_adaptive_huffman_data_model& rhs) - { - if (this == &rhs) - return true; - - if (m_malloc_context != rhs.m_malloc_context) - { - clear(); - - m_malloc_context = rhs.m_malloc_context; - - m_initial_sym_freq.set_malloc_context(m_malloc_context); - m_sym_freq.set_malloc_context(m_malloc_context); - m_codes.set_malloc_context(m_malloc_context); - m_code_sizes.set_malloc_context(m_malloc_context); - } - - m_total_syms = rhs.m_total_syms; - - m_max_cycle = rhs.m_max_cycle; - m_update_cycle = rhs.m_update_cycle; - m_symbols_until_update = rhs.m_symbols_until_update; - - m_total_count = rhs.m_total_count; - - m_sym_freq = rhs.m_sym_freq; - m_initial_sym_freq = rhs.m_initial_sym_freq; - - m_codes = rhs.m_codes; - m_code_sizes = rhs.m_code_sizes; - - if (rhs.m_pDecode_tables) - { - if (m_pDecode_tables) - { - if (!m_pDecode_tables->assign(*rhs.m_pDecode_tables)) - { - clear(); - return false; - } - } - else - { - m_pDecode_tables = lzham_new(m_malloc_context, *rhs.m_pDecode_tables); - if (!m_pDecode_tables) - { - clear(); - LZHAM_LOG_ERROR(4000); - return false; - } - } - } - else if (m_pDecode_tables) - { - lzham_delete(m_malloc_context, m_pDecode_tables); - m_pDecode_tables = NULL; - } - - m_decoder_table_bits = rhs.m_decoder_table_bits; - m_encoding = rhs.m_encoding; - m_max_update_interval = rhs.m_max_update_interval; - m_adapt_rate = rhs.m_adapt_rate; - - return true; - } - - quasi_adaptive_huffman_data_model& quasi_adaptive_huffman_data_model::operator= (const quasi_adaptive_huffman_data_model& rhs) - { - assign(rhs); - return *this; - } - - void quasi_adaptive_huffman_data_model::clear() - { - m_sym_freq.clear(); - m_initial_sym_freq.clear(); - m_codes.clear(); - m_code_sizes.clear(); - - m_max_cycle = 0; - m_total_syms = 0; - m_update_cycle = 0; - m_symbols_until_update = 0; - m_decoder_table_bits = 0; - m_total_count = 0; - - if (m_pDecode_tables) - { - lzham_delete(m_malloc_context, m_pDecode_tables); - m_pDecode_tables = NULL; - } - - m_max_update_interval = 0; - m_adapt_rate = 0; - } - - bool quasi_adaptive_huffman_data_model::init2(lzham_malloc_context malloc_context, bool encoding, uint total_syms, uint max_update_interval, uint adapt_rate, const uint16 *pInitial_sym_freq) - { - LZHAM_ASSERT(max_update_interval <= 0xFFFF); - LZHAM_ASSERT(adapt_rate <= 0xFFFF); - - if (malloc_context != m_malloc_context) - { - clear(); - - m_malloc_context = malloc_context; - - m_initial_sym_freq.set_malloc_context(m_malloc_context); - m_sym_freq.set_malloc_context(m_malloc_context); - m_codes.set_malloc_context(m_malloc_context); - m_code_sizes.set_malloc_context(m_malloc_context); - } - - m_encoding = encoding; - m_max_update_interval = static_cast(max_update_interval); - m_adapt_rate = static_cast(adapt_rate); - m_symbols_until_update = 0; - - if (!m_sym_freq.try_resize(total_syms)) - { - clear(); - LZHAM_LOG_ERROR(4001); - return false; - } - - if (pInitial_sym_freq) - { - if (!m_initial_sym_freq.try_resize(total_syms)) - { - clear(); - LZHAM_LOG_ERROR(4002); - return false; - } - memcpy(m_initial_sym_freq.begin(), pInitial_sym_freq, total_syms * m_initial_sym_freq.size_in_bytes()); - } - - if (!m_code_sizes.try_resize(total_syms)) - { - clear(); - LZHAM_LOG_ERROR(4003); - return false; - } - - m_total_syms = total_syms; - - uint max_table_bits = 0; - - if (m_total_syms <= 8) - max_table_bits = 4; - else - max_table_bits = 1 + math::ceil_log2i(m_total_syms); - - m_decoder_table_bits = static_cast(math::minimum(max_table_bits, prefix_coding::cMaxTableBits)); - - if (m_encoding) - { - lzham_delete(m_malloc_context, m_pDecode_tables); - m_pDecode_tables = NULL; - - if (!m_codes.try_resize(total_syms)) - { - clear(); - LZHAM_LOG_ERROR(4004); - return false; - } - } - else if (!m_pDecode_tables) - { - m_pDecode_tables = lzham_new(m_malloc_context, m_malloc_context); - if (!m_pDecode_tables) - { - clear(); - LZHAM_LOG_ERROR(4005); - return false; - } - } - - m_max_cycle = (LZHAM_MAX(24, m_total_syms) + 6) * (m_max_update_interval ? m_max_update_interval : LZHAM_DEFAULT_MAX_UPDATE_INTERVAL); - - m_max_cycle = LZHAM_MIN(m_max_cycle, 32767); - - reset(); - - return true; - } - - bool quasi_adaptive_huffman_data_model::reset() - { - if (!m_total_syms) - return true; - - bool sym_freq_all_ones = false; - - if (m_initial_sym_freq.size()) - { - m_update_cycle = 0; - for (uint i = 0; i < m_total_syms; i++) - { - uint sym_freq = m_initial_sym_freq[i]; - m_sym_freq[i] = static_cast(sym_freq); - - // Slam m_update_cycle to a specific value so update_tables() sets m_total_count to the proper value - m_update_cycle += sym_freq; - } - } - else - { -#if LZHAM_LITTLE_ENDIAN_CPU - // &m_sym_freq[0] should be aligned to at least 8 bytes due to LZHAM_MIN_ALLOC_ALIGNMENT - uint64 x = 0x0001000100010001ULL; - x = (x << 32U) | x; - - uint64 *p = reinterpret_cast(&m_sym_freq[0]); - - for (uint64 *q = p + ((m_total_syms >> 3) * 2); p != q; p += 2) - { - p[0] = x; - p[1] = x; - } - - uint16 *r = reinterpret_cast(p); - for (uint i = (m_total_syms & 7); i; --i) - *r++ = 1; - -#ifdef LZHAM_BUILD_DEBUG - for (uint i = 0; i < m_total_syms; i++) - { - LZHAM_ASSERT(m_sym_freq[i] == 1); - } -#endif - -#else - for (uint i = 0; i < m_total_syms; i++) - m_sym_freq[i] = 1; -#endif - - // Slam m_update_cycle to a specific value so update_tables() sets m_total_count to the proper value - m_update_cycle = m_total_syms; - - sym_freq_all_ones = true; - } - - m_total_count = 0; - m_symbols_until_update = 0; - - if (!update_tables(LZHAM_MIN(m_max_cycle, 16), sym_freq_all_ones)) // this was 8 in the alphas - { - LZHAM_LOG_ERROR(4006); - return false; - } - - return true; - } - - void quasi_adaptive_huffman_data_model::rescale() - { - uint total_freq = 0; - - for (uint i = 0; i < m_total_syms; i++) - { - uint freq = (m_sym_freq[i] + 1) >> 1; - total_freq += freq; - m_sym_freq[i] = static_cast(freq); - } - - m_total_count = total_freq; - } - - void quasi_adaptive_huffman_data_model::reset_update_rate() - { - m_total_count += (m_update_cycle - m_symbols_until_update); - -#ifdef LZHAM_BUILD_DEBUG - uint actual_total = 0; - for (uint i = 0; i < m_sym_freq.size(); i++) - actual_total += m_sym_freq[i]; - LZHAM_ASSERT(actual_total == m_total_count); -#endif - - if (m_total_count > m_total_syms) - rescale(); - - m_symbols_until_update = m_update_cycle = LZHAM_MIN(8, m_update_cycle); - } - - bool quasi_adaptive_huffman_data_model::update_tables(int force_update_cycle, bool sym_freq_all_ones) - { - LZHAM_ASSERT(!m_symbols_until_update); - m_total_count += m_update_cycle; - LZHAM_ASSERT(m_total_count <= 65535); - - while (m_total_count >= 32768) - rescale(); - - uint max_code_size = 0; - - code_size_histogram code_size_hist; - code_size_hist.clear(); - - if ((sym_freq_all_ones) && (m_total_syms >= 2)) - { - // Shortcut building the Huffman codes if we know all the sym freqs are 1. - uint base_code_size = math::floor_log2i(m_total_syms); - uint num_left = m_total_syms - (1 << base_code_size); - num_left *= 2; - if (num_left > m_total_syms) - num_left = m_total_syms; - - memset(&m_code_sizes[0], base_code_size + 1, num_left); - memset(&m_code_sizes[num_left], base_code_size, m_total_syms - num_left); - - code_size_hist.init(base_code_size, m_total_syms - num_left, base_code_size + 1, num_left); - - max_code_size = base_code_size + (num_left ? 1 : 0); - } - - bool status = false; - if (!max_code_size) - { - uint table_size = get_generate_huffman_codes_table_size(); - void *pTables = alloca(table_size); - - uint total_freq = 0; - status = generate_huffman_codes(pTables, m_total_syms, &m_sym_freq[0], &m_code_sizes[0], max_code_size, total_freq, code_size_hist); - LZHAM_ASSERT(status); - LZHAM_ASSERT(total_freq == m_total_count); - if ((!status) || (total_freq != m_total_count)) - { - LZHAM_LOG_ERROR(4007); - return false; - } - - if (max_code_size > cMaxExpectedHuffCodeSize) - { - status = prefix_coding::limit_max_code_size(m_total_syms, &m_code_sizes[0], cMaxExpectedHuffCodeSize); - LZHAM_ASSERT(status); - if (!status) - { - LZHAM_LOG_ERROR(4008); - return false; - } - - code_size_hist.clear(); - code_size_hist.init(m_total_syms, &m_code_sizes[0]); - - for (max_code_size = cMaxExpectedHuffCodeSize; max_code_size >= 1; max_code_size--) - if (code_size_hist.m_num_codes[max_code_size]) - break; - } - } - -#ifdef LZHAM_BUILD_DEBUG -{ - uint check_max_code_size = 0; - uint check_total_syms[cMaxExpectedHuffCodeSize + 1]; - utils::zero_object(check_total_syms); - for (uint i = 0; i < m_total_syms; i++) - { - uint code_size = m_code_sizes[i]; - check_max_code_size = math::maximum(check_max_code_size, code_size); - check_total_syms[code_size]++; - } - LZHAM_ASSERT(max_code_size == check_max_code_size); - for (uint i = 0; i < (cMaxExpectedHuffCodeSize + 1); i++) - { - LZHAM_ASSERT(code_size_hist.m_num_codes[i] == check_total_syms[i]); - } -} -#endif - - if (force_update_cycle >= 0) - m_symbols_until_update = m_update_cycle = force_update_cycle; - else - { - m_update_cycle = (31U + m_update_cycle * LZHAM_MAX(32U, (m_adapt_rate ? m_adapt_rate : LZHAM_DEFAULT_ADAPT_RATE))) >> 5U; - - if (m_update_cycle > m_max_cycle) - m_update_cycle = m_max_cycle; - - m_symbols_until_update = m_update_cycle; - } - - if (m_encoding) - status = prefix_coding::generate_codes(m_total_syms, &m_code_sizes[0], &m_codes[0]); - else - { - uint actual_table_bits = m_decoder_table_bits; - - // Try to see if using the accel table is actually worth the trouble of constructing it. - uint cost_to_use_table = (1 << actual_table_bits) + 64; - uint cost_to_not_use_table = m_symbols_until_update * math::floor_log2i(m_total_syms); - if (cost_to_not_use_table <= cost_to_use_table) - actual_table_bits = 0; - - status = prefix_coding::generate_decoder_tables(m_total_syms, &m_code_sizes[0], m_pDecode_tables, actual_table_bits, code_size_hist, sym_freq_all_ones); - } - - LZHAM_ASSERT(status); - if (!status) - { - LZHAM_LOG_ERROR(4009); - return false; - } - - return true; - } - - bool quasi_adaptive_huffman_data_model::update_sym(uint sym) - { - uint freq = m_sym_freq[sym]; - freq++; - m_sym_freq[sym] = static_cast(freq); - - LZHAM_ASSERT(freq <= cUINT16_MAX); - - if (--m_symbols_until_update == 0) - { - if (!update_tables()) - { - LZHAM_LOG_ERROR(4010); - return false; - } - } - - return true; - } - - adaptive_bit_model::adaptive_bit_model(float prob0) - { - set_probability_0(prob0); - } - - adaptive_bit_model::adaptive_bit_model(const adaptive_bit_model& other) : - m_bit_0_prob(other.m_bit_0_prob) - { - } - - void adaptive_bit_model::set_probability_0(float prob0) - { - m_bit_0_prob = static_cast(math::clamp((uint)(prob0 * cSymbolCodecArithProbScale), 1, cSymbolCodecArithProbScale - 1)); - } - - symbol_codec::symbol_codec(lzham_malloc_context malloc_context) : - m_malloc_context(malloc_context), - m_output_buf(malloc_context), - m_arith_output_buf(malloc_context), - m_output_syms(malloc_context) - { - clear(); - } - - void symbol_codec::reset() - { - m_pDecode_buf = NULL; - m_pDecode_buf_next = NULL; - m_pDecode_buf_end = NULL; - m_decode_buf_size = 0; - - m_bit_buf = 0; - m_bit_count = 0; - m_total_model_updates = 0; - m_mode = cNull; - m_total_bits_written = 0; - - m_arith_base = 0; - m_arith_value = 0; - m_arith_length = 0; - m_arith_total_bits = 0; - - m_output_buf.try_resize(0); - m_arith_output_buf.try_resize(0); - m_output_syms.try_resize(0); - - m_pDecode_need_bytes_func = NULL; - m_pDecode_private_data = NULL; - m_pSaved_huff_model = NULL; - m_pSaved_model = NULL; - m_saved_node_index = 0; - } - - void symbol_codec::clear() - { - reset(); - - m_output_buf.clear(); - m_arith_output_buf.clear(); - m_output_syms.clear(); - } - - bool symbol_codec::start_encoding(uint expected_file_size) - { - m_mode = cEncoding; - - m_total_model_updates = 0; - m_total_bits_written = 0; - - if (!put_bits_init(expected_file_size)) - return false; - - m_output_syms.try_resize(0); - - arith_start_encoding(); - - return true; - } - - bool symbol_codec::encode_bits(uint bits, uint num_bits) - { - LZHAM_ASSERT(m_mode == cEncoding); - - if (!num_bits) - return true; - - LZHAM_ASSERT((num_bits == 32) || (bits <= ((1U << num_bits) - 1))); - - if (num_bits > 16) - { - if (!record_put_bits(bits >> 16, num_bits - 16)) - { - LZHAM_LOG_ERROR(4011); - return false; - } - if (!record_put_bits(bits & 0xFFFF, 16)) - { - LZHAM_LOG_ERROR(4012); - return false; - } - } - else - { - if (!record_put_bits(bits, num_bits)) - { - LZHAM_LOG_ERROR(4013); - return false; - } - } - return true; - } - - bool symbol_codec::encode_arith_init() - { - LZHAM_ASSERT(m_mode == cEncoding); - - output_symbol sym; - sym.m_bits = 0; - sym.m_num_bits = output_symbol::cArithInit; - sym.m_arith_prob0 = 0; - if (!m_output_syms.try_push_back(sym)) - { - LZHAM_LOG_ERROR(4014); - return false; - } - - return true; - } - - bool symbol_codec::encode_align_to_byte() - { - LZHAM_ASSERT(m_mode == cEncoding); - - output_symbol sym; - sym.m_bits = 0; - sym.m_num_bits = output_symbol::cAlignToByteSym; - sym.m_arith_prob0 = 0; - if (!m_output_syms.try_push_back(sym)) - { - LZHAM_LOG_ERROR(4015); - return false; - } - - return true; - } - - bool symbol_codec::encode(uint sym, quasi_adaptive_huffman_data_model& model) - { - LZHAM_ASSERT(m_mode == cEncoding); - LZHAM_ASSERT(model.m_encoding); - - if (!record_put_bits(model.m_codes[sym], model.m_code_sizes[sym])) - { - LZHAM_LOG_ERROR(4016); - return false; - } - - uint freq = model.m_sym_freq[sym]; - freq++; - model.m_sym_freq[sym] = static_cast(freq); - - LZHAM_ASSERT(freq <= cUINT16_MAX); - - if (--model.m_symbols_until_update == 0) - { - m_total_model_updates++; - if (!model.update_tables()) - { - LZHAM_LOG_ERROR(4018); - return false; - } - } - return true; - } - - void symbol_codec::arith_propagate_carry() - { - int index = m_arith_output_buf.size() - 1; - while (index >= 0) - { - uint c = m_arith_output_buf[index]; - - if (c == 0xFF) - m_arith_output_buf[index] = 0; - else - { - m_arith_output_buf[index]++; - break; - } - - index--; - } - } - - bool symbol_codec::arith_renorm_enc_interval() - { - do - { - if (!m_arith_output_buf.try_push_back((m_arith_base >> 24) & 0xFF)) - return false; - m_total_bits_written += 8; - - m_arith_base <<= 8; - } while ((m_arith_length <<= 8) < cSymbolCodecArithMinLen); - return true; - } - - void symbol_codec::arith_start_encoding() - { - m_arith_output_buf.try_resize(0); - - m_arith_base = 0; - m_arith_value = 0; - m_arith_length = cSymbolCodecArithMaxLen; - m_arith_total_bits = 0; - } - - bool symbol_codec::encode(uint bit, adaptive_bit_model& model, bool update_model) - { - LZHAM_ASSERT(m_mode == cEncoding); - - m_arith_total_bits++; - - output_symbol sym; - sym.m_bits = bit; - sym.m_num_bits = -1; - sym.m_arith_prob0 = model.m_bit_0_prob; - if (!m_output_syms.try_push_back(sym)) - { - LZHAM_LOG_ERROR(4019); - return false; - } - - uint x = model.m_bit_0_prob * (m_arith_length >> cSymbolCodecArithProbBits); - - if (!bit) - { - if (update_model) - model.m_bit_0_prob += ((cSymbolCodecArithProbScale - model.m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); - - m_arith_length = x; - } - else - { - if (update_model) - model.m_bit_0_prob -= (model.m_bit_0_prob >> cSymbolCodecArithProbMoveBits); - - uint orig_base = m_arith_base; - m_arith_base += x; - m_arith_length -= x; - if (orig_base > m_arith_base) - arith_propagate_carry(); - } - - if (m_arith_length < cSymbolCodecArithMinLen) - { - if (!arith_renorm_enc_interval()) - { - LZHAM_LOG_ERROR(4020); - return false; - } - } - - return true; - } - - bool symbol_codec::arith_stop_encoding() - { - uint orig_base = m_arith_base; - - if (m_arith_length > 2 * cSymbolCodecArithMinLen) - { - m_arith_base += cSymbolCodecArithMinLen; - m_arith_length = (cSymbolCodecArithMinLen >> 1); - } - else - { - m_arith_base += (cSymbolCodecArithMinLen >> 1); - m_arith_length = (cSymbolCodecArithMinLen >> 9); - } - - if (orig_base > m_arith_base) - arith_propagate_carry(); - - if (!arith_renorm_enc_interval()) - { - LZHAM_LOG_ERROR(4021); - return false; - } - - while (m_arith_output_buf.size() < 4) - { - if (!m_arith_output_buf.try_push_back(0)) - { - LZHAM_LOG_ERROR(4022); - return false; - } - m_total_bits_written += 8; - } - return true; - } - - bool symbol_codec::stop_encoding(bool support_arith) - { - LZHAM_ASSERT(m_mode == cEncoding); - - if (support_arith) - { - if (!arith_stop_encoding()) - return false; - } - - if (!assemble_output_buf()) - return false; - - m_mode = cNull; - return true; - } - - bool symbol_codec::record_put_bits(uint bits, uint num_bits) - { - LZHAM_ASSERT(m_mode == cEncoding); - - LZHAM_ASSERT(num_bits <= 25); - LZHAM_ASSERT(m_bit_count >= 25); - - if (!num_bits) - return true; - - m_total_bits_written += num_bits; - - output_symbol sym; - sym.m_bits = bits; - sym.m_num_bits = (uint16)num_bits; - sym.m_arith_prob0 = 0; - if (!m_output_syms.try_push_back(sym)) - { - LZHAM_LOG_ERROR(4023); - return false; - } - - return true; - } - - bool symbol_codec::put_bits_init(uint expected_size) - { - m_bit_buf = 0; - m_bit_count = cBitBufSize; - - m_output_buf.try_resize(0); - if (!m_output_buf.try_reserve(expected_size)) - { - LZHAM_LOG_ERROR(4024); - return false; - } - - return true; - } - - bool symbol_codec::put_bits(uint bits, uint num_bits) - { - LZHAM_ASSERT(num_bits <= 25); - LZHAM_ASSERT(m_bit_count >= 25); - - if (!num_bits) - return true; - - m_bit_count -= num_bits; - m_bit_buf |= (static_cast(bits) << m_bit_count); - - m_total_bits_written += num_bits; - - while (m_bit_count <= (cBitBufSize - 8)) - { - if (!m_output_buf.try_push_back(static_cast(m_bit_buf >> (cBitBufSize - 8)))) - return false; - - m_bit_buf <<= 8; - m_bit_count += 8; - } - - return true; - } - - bool symbol_codec::put_bits_align_to_byte() - { - uint num_bits_in = cBitBufSize - m_bit_count; - if (num_bits_in & 7) - { - if (!put_bits(0, 8 - (num_bits_in & 7))) - { - LZHAM_LOG_ERROR(4025); - return false; - } - } - return true; - } - - bool symbol_codec::flush_bits() - { - return put_bits(0, 7); // to ensure the last bits are flushed - } - - bool symbol_codec::assemble_output_buf() - { - m_total_bits_written = 0; - - uint arith_buf_ofs = 0; - - // Intermix the final Arithmetic, Huffman, or plain bits to a single combined bitstream. - // All bits from each source must be output in exactly the same order that the decompressor will read them. - for (uint sym_index = 0; sym_index < m_output_syms.size(); sym_index++) - { - const output_symbol& sym = m_output_syms[sym_index]; - - if (sym.m_num_bits == output_symbol::cAlignToByteSym) - { - if (!put_bits_align_to_byte()) - { - LZHAM_LOG_ERROR(4026); - return false; - } - } - else if (sym.m_num_bits == output_symbol::cArithInit) - { - LZHAM_ASSERT(m_arith_output_buf.size()); - - if (m_arith_output_buf.size()) - { - m_arith_length = cSymbolCodecArithMaxLen; - m_arith_value = 0; - for (uint i = 0; i < 4; i++) - { - const uint c = m_arith_output_buf[arith_buf_ofs++]; - m_arith_value = (m_arith_value << 8) | c; - if (!put_bits(c, 8)) - { - LZHAM_LOG_ERROR(4027); - return false; - } - } - } - } - else if (sym.m_num_bits == output_symbol::cArithSym) - { - // This renorm logic must match the logic used in the arithmetic decoder. - if (m_arith_length < cSymbolCodecArithMinLen) - { - do - { - const uint c = (arith_buf_ofs < m_arith_output_buf.size()) ? m_arith_output_buf[arith_buf_ofs++] : 0; - if (!put_bits(c, 8)) - { - LZHAM_LOG_ERROR(4028); - return false; - } - m_arith_value = (m_arith_value << 8) | c; - } while ((m_arith_length <<= 8) < cSymbolCodecArithMinLen); - } - - uint x = sym.m_arith_prob0 * (m_arith_length >> cSymbolCodecArithProbBits); - uint bit = (m_arith_value >= x); - - if (bit == 0) - { - m_arith_length = x; - } - else - { - m_arith_value -= x; - m_arith_length -= x; - } - - LZHAM_VERIFY(bit == sym.m_bits); - } - else - { - // Huffman or plain bits - if (!put_bits(sym.m_bits, sym.m_num_bits)) - { - LZHAM_LOG_ERROR(4029); - return false; - } - } - } - - return flush_bits(); - } - - //------------------------------------------------------------------------------------------------------------------ - // Decoding - //------------------------------------------------------------------------------------------------------------------ - - bool symbol_codec::start_decoding(const uint8* pBuf, size_t buf_size, bool eof_flag, need_bytes_func_ptr pNeed_bytes_func, void *pPrivate_data) - { - if (!buf_size) - { - LZHAM_LOG_ERROR(4030); - return false; - } - - m_total_model_updates = 0; - - m_pDecode_buf = pBuf; - m_pDecode_buf_next = pBuf; - m_decode_buf_size = buf_size; - m_pDecode_buf_end = pBuf + buf_size; - - m_pDecode_need_bytes_func = pNeed_bytes_func; - m_pDecode_private_data = pPrivate_data; - m_decode_buf_eof = eof_flag; - - m_bit_buf = 0; - m_bit_count = 0; - - m_mode = cDecoding; - - return true; - } - - uint symbol_codec::decode_bits(uint num_bits) - { - LZHAM_ASSERT(m_mode == cDecoding); - - if (!num_bits) - return 0; - - if (num_bits > 16) - { - uint a = get_bits(num_bits - 16); - uint b = get_bits(16); - - return (a << 16) | b; - } - else - return get_bits(num_bits); - } - - void symbol_codec::decode_remove_bits(uint num_bits) - { - LZHAM_ASSERT(m_mode == cDecoding); - - while (num_bits > 16) - { - remove_bits(16); - num_bits -= 16; - } - - remove_bits(num_bits); - } - - uint symbol_codec::decode_peek_bits(uint num_bits) - { - LZHAM_ASSERT(m_mode == cDecoding); - LZHAM_ASSERT(num_bits <= 25); - - if (!num_bits) - return 0; - - while (m_bit_count < (int)num_bits) - { - uint c = 0; - if (m_pDecode_buf_next == m_pDecode_buf_end) - { - if (!m_decode_buf_eof) - { - m_pDecode_need_bytes_func(m_pDecode_buf_next - m_pDecode_buf, m_pDecode_private_data, m_pDecode_buf, m_decode_buf_size, m_decode_buf_eof); - m_pDecode_buf_end = m_pDecode_buf + m_decode_buf_size; - m_pDecode_buf_next = m_pDecode_buf; - if (m_pDecode_buf_next < m_pDecode_buf_end) c = *m_pDecode_buf_next++; - } - } - else - c = *m_pDecode_buf_next++; - - m_bit_count += 8; - LZHAM_ASSERT(m_bit_count <= cBitBufSize); - - m_bit_buf |= (static_cast(c) << (cBitBufSize - m_bit_count)); - } - - return static_cast(m_bit_buf >> (cBitBufSize - num_bits)); - } - - uint symbol_codec::decode(quasi_adaptive_huffman_data_model& model) - { - LZHAM_ASSERT(m_mode == cDecoding); - LZHAM_ASSERT(!model.m_encoding); - - const prefix_coding::decoder_tables* pTables = model.m_pDecode_tables; - - while (m_bit_count < (cBitBufSize - 8)) - { - uint c = 0; - if (m_pDecode_buf_next == m_pDecode_buf_end) - { - if (!m_decode_buf_eof) - { - m_pDecode_need_bytes_func(m_pDecode_buf_next - m_pDecode_buf, m_pDecode_private_data, m_pDecode_buf, m_decode_buf_size, m_decode_buf_eof); - m_pDecode_buf_end = m_pDecode_buf + m_decode_buf_size; - m_pDecode_buf_next = m_pDecode_buf; - if (m_pDecode_buf_next < m_pDecode_buf_end) c = *m_pDecode_buf_next++; - } - } - else - c = *m_pDecode_buf_next++; - - m_bit_count += 8; - m_bit_buf |= (static_cast(c) << (cBitBufSize - m_bit_count)); - } - - uint k = static_cast((m_bit_buf >> (cBitBufSize - 16)) + 1); - uint sym, len; - - if (k <= pTables->m_table_max_code) - { - uint32 t = pTables->m_lookup[m_bit_buf >> (cBitBufSize - pTables->m_table_bits)]; - - LZHAM_ASSERT(t != cUINT32_MAX); - sym = t & cUINT16_MAX; - len = t >> 16; - - LZHAM_ASSERT(model.m_code_sizes[sym] == len); - } - else - { - len = pTables->m_decode_start_code_size; - - for ( ; ; ) - { - if (k <= pTables->m_max_codes[len - 1]) - break; - len++; - } - - int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast((m_bit_buf >> (cBitBufSize - len))); - - if (((uint)val_ptr >= model.m_total_syms)) - { - // corrupted stream, or a bug - LZHAM_ASSERT(0); - LZHAM_LOG_ERROR(4031); - return 0; - } - - sym = pTables->m_sorted_symbol_order[val_ptr]; - } - - m_bit_buf <<= len; - m_bit_count -= len; - - uint freq = model.m_sym_freq[sym]; - freq++; - model.m_sym_freq[sym] = static_cast(freq); - - LZHAM_ASSERT(freq <= cUINT16_MAX); - - if (--model.m_symbols_until_update == 0) - { - m_total_model_updates++; - model.update_tables(); - } - - return sym; - } - - uint64 symbol_codec::stop_decoding() - { - LZHAM_ASSERT(m_mode == cDecoding); - - uint64 n = m_pDecode_buf_next - m_pDecode_buf; - - m_mode = cNull; - - return n; - } - - uint symbol_codec::get_bits(uint num_bits) - { - LZHAM_ASSERT(num_bits <= 25); - - if (!num_bits) - return 0; - - while (m_bit_count < (int)num_bits) - { - uint c = 0; - if (m_pDecode_buf_next == m_pDecode_buf_end) - { - if (!m_decode_buf_eof) - { - m_pDecode_need_bytes_func(m_pDecode_buf_next - m_pDecode_buf, m_pDecode_private_data, m_pDecode_buf, m_decode_buf_size, m_decode_buf_eof); - m_pDecode_buf_end = m_pDecode_buf + m_decode_buf_size; - m_pDecode_buf_next = m_pDecode_buf; - if (m_pDecode_buf_next < m_pDecode_buf_end) c = *m_pDecode_buf_next++; - } - } - else - c = *m_pDecode_buf_next++; - - m_bit_count += 8; - LZHAM_ASSERT(m_bit_count <= cBitBufSize); - - m_bit_buf |= (static_cast(c) << (cBitBufSize - m_bit_count)); - } - - uint result = static_cast(m_bit_buf >> (cBitBufSize - num_bits)); - - m_bit_buf <<= num_bits; - m_bit_count -= num_bits; - - return result; - } - - void symbol_codec::remove_bits(uint num_bits) - { - LZHAM_ASSERT(num_bits <= 25); - - if (!num_bits) - return; - - while (m_bit_count < (int)num_bits) - { - uint c = 0; - if (m_pDecode_buf_next == m_pDecode_buf_end) - { - if (!m_decode_buf_eof) - { - m_pDecode_need_bytes_func(m_pDecode_buf_next - m_pDecode_buf, m_pDecode_private_data, m_pDecode_buf, m_decode_buf_size, m_decode_buf_eof); - m_pDecode_buf_end = m_pDecode_buf + m_decode_buf_size; - m_pDecode_buf_next = m_pDecode_buf; - if (m_pDecode_buf_next < m_pDecode_buf_end) c = *m_pDecode_buf_next++; - } - } - else - c = *m_pDecode_buf_next++; - - m_bit_count += 8; - LZHAM_ASSERT(m_bit_count <= cBitBufSize); - - m_bit_buf |= (static_cast(c) << (cBitBufSize - m_bit_count)); - } - - m_bit_buf <<= num_bits; - m_bit_count -= num_bits; - } - - void symbol_codec::decode_align_to_byte() - { - LZHAM_ASSERT(m_mode == cDecoding); - - if (m_bit_count & 7) - { - remove_bits(m_bit_count & 7); - } - } - - int symbol_codec::decode_remove_byte_from_bit_buf() - { - if (m_bit_count < 8) - return -1; - int result = static_cast(m_bit_buf >> (cBitBufSize - 8)); - m_bit_buf <<= 8; - m_bit_count -= 8; - return result; - } - - uint symbol_codec::decode(adaptive_bit_model& model, bool update_model) - { - while (m_arith_length < cSymbolCodecArithMinLen) - { - uint c = get_bits(8); - m_arith_value = (m_arith_value << 8) | c; - m_arith_length <<= 8; - } - - uint x = model.m_bit_0_prob * (m_arith_length >> cSymbolCodecArithProbBits); - uint bit = (m_arith_value >= x); - - if (!bit) - { - if (update_model) - model.m_bit_0_prob += ((cSymbolCodecArithProbScale - model.m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); - - m_arith_length = x; - } - else - { - if (update_model) - model.m_bit_0_prob -= (model.m_bit_0_prob >> cSymbolCodecArithProbMoveBits); - m_arith_value -= x; - m_arith_length -= x; - } - - return bit; - } - - void symbol_codec::start_arith_decoding() - { - LZHAM_ASSERT(m_mode == cDecoding); - - m_arith_length = cSymbolCodecArithMaxLen; - m_arith_value = 0; - - m_arith_value = (get_bits(8) << 24); - m_arith_value |= (get_bits(8) << 16); - m_arith_value |= (get_bits(8) << 8); - m_arith_value |= get_bits(8); - } - - void symbol_codec::decode_need_bytes() - { - if (!m_decode_buf_eof) - { - m_pDecode_need_bytes_func(m_pDecode_buf_next - m_pDecode_buf, m_pDecode_private_data, m_pDecode_buf, m_decode_buf_size, m_decode_buf_eof); - m_pDecode_buf_end = m_pDecode_buf + m_decode_buf_size; - m_pDecode_buf_next = m_pDecode_buf; - } - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,494 +0,0 @@ -// File: lzham_symbol_codec.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once -#include "lzham_prefix_coding.h" - -namespace lzham -{ - class symbol_codec; - - const uint cSymbolCodecArithMinLen = 0x01000000U; - const uint cSymbolCodecArithMaxLen = 0xFFFFFFFFU; - - const uint cSymbolCodecArithProbBits = 11; - const uint cSymbolCodecArithProbScale = 1 << cSymbolCodecArithProbBits; - const uint cSymbolCodecArithProbHalfScale = 1 << (cSymbolCodecArithProbBits - 1); - const uint cSymbolCodecArithProbMoveBits = 5; - - typedef uint64 bit_cost_t; - const uint32 cBitCostScaleShift = 24; - const uint32 cBitCostScale = (1U << cBitCostScaleShift); - const bit_cost_t cBitCostMax = cUINT64_MAX; - - inline bit_cost_t convert_to_scaled_bitcost(uint bits) { LZHAM_ASSERT(bits <= 255); uint32 scaled_bits = bits << cBitCostScaleShift; return static_cast(scaled_bits); } - - extern uint32 g_prob_cost[cSymbolCodecArithProbScale]; - - class quasi_adaptive_huffman_data_model - { - public: - quasi_adaptive_huffman_data_model(lzham_malloc_context malloc_context = NULL, bool encoding = false, uint total_syms = 0, uint max_update_interval = 0, uint adapt_rate = 0); - quasi_adaptive_huffman_data_model(const quasi_adaptive_huffman_data_model& other); - ~quasi_adaptive_huffman_data_model(); - - bool assign(const quasi_adaptive_huffman_data_model& rhs); - quasi_adaptive_huffman_data_model& operator= (const quasi_adaptive_huffman_data_model& rhs); - - void clear(); - - void set_malloc_context(lzham_malloc_context malloc_context) - { - m_malloc_context = malloc_context; - m_initial_sym_freq.set_malloc_context(malloc_context); - m_sym_freq.set_malloc_context(malloc_context); - m_codes.set_malloc_context(malloc_context); - m_code_sizes.set_malloc_context(malloc_context); - } - - lzham_malloc_context get_malloc_context() const { return m_malloc_context; } - - bool init2(lzham_malloc_context context, bool encoding, uint total_syms, uint max_update_interval, uint adapt_rate, const uint16 *pInitial_sym_freq); - bool reset(); - - inline uint get_total_syms() const { return m_total_syms; } - - void rescale(); - void reset_update_rate(); - - bool update_sym(uint sym); - - inline bit_cost_t get_cost(uint sym) const { return convert_to_scaled_bitcost(m_code_sizes[sym]); } - - public: - lzham_malloc_context m_malloc_context; - lzham::vector m_initial_sym_freq; - - lzham::vector m_sym_freq; - - lzham::vector m_codes; - lzham::vector m_code_sizes; - - prefix_coding::decoder_tables* m_pDecode_tables; - - uint m_total_syms; - - uint m_max_cycle; - uint m_update_cycle; - uint m_symbols_until_update; - - uint m_total_count; - - uint8 m_decoder_table_bits; - uint16 m_max_update_interval; // def=16, typical range 12-128, controls the max interval between table updates, higher=longer max interval (faster decode/lower ratio) - uint16 m_adapt_rate; // def=10, 8 or higher, scaled by 8, controls the slowing of the update update freq, higher=more rapid slowing (faster decode/lower ratio) - bool m_encoding; - - bool update_tables(int force_update_cycle = -1, bool sym_freq_all_ones = false); - - friend class symbol_codec; - }; - - class adaptive_bit_model - { - public: - inline adaptive_bit_model() { clear(); } - adaptive_bit_model(float prob0); - adaptive_bit_model(const adaptive_bit_model& other); - - inline adaptive_bit_model& operator= (const adaptive_bit_model& rhs) { m_bit_0_prob = rhs.m_bit_0_prob; return *this; } - - inline void clear() { m_bit_0_prob = 1U << (cSymbolCodecArithProbBits - 1); } - - void set_probability_0(float prob0); - - inline void update(uint bit) - { - if (!bit) - m_bit_0_prob += ((cSymbolCodecArithProbScale - m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); - else - m_bit_0_prob -= (m_bit_0_prob >> cSymbolCodecArithProbMoveBits); - LZHAM_ASSERT(m_bit_0_prob >= 1); - LZHAM_ASSERT(m_bit_0_prob < cSymbolCodecArithProbScale); - } - - inline bit_cost_t get_cost(uint bit) const { return g_prob_cost[bit ? (cSymbolCodecArithProbScale - m_bit_0_prob) : m_bit_0_prob]; } - - public: - uint16 m_bit_0_prob; - - friend class symbol_codec; - }; - -#if LZHAM_CPU_HAS_64BIT_REGISTERS - #define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 1 -#else - #define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 0 -#endif - - class symbol_codec - { - LZHAM_NO_COPY_OR_ASSIGNMENT_OP(symbol_codec); - - public: - symbol_codec(lzham_malloc_context malloc_context); - - void reset(); - - // clear() is like reset(), except it also frees all memory. - void clear(); - - // Encoding - bool start_encoding(uint expected_file_size); - bool encode_bits(uint bits, uint num_bits); - bool encode_arith_init(); - bool encode_align_to_byte(); - bool encode(uint sym, quasi_adaptive_huffman_data_model& model); - bool encode(uint bit, adaptive_bit_model& model, bool update_model = true); - - inline uint encode_get_total_bits_written() const { return m_total_bits_written; } - - bool stop_encoding(bool support_arith); - - const lzham::vector& get_encoding_buf() const { return m_output_buf; } - lzham::vector& get_encoding_buf() { return m_output_buf; } - - // Decoding - - typedef void (*need_bytes_func_ptr)(size_t num_bytes_consumed, void *pPrivate_data, const uint8* &pBuf, size_t &buf_size, bool &eof_flag); - - bool start_decoding(const uint8* pBuf, size_t buf_size, bool eof_flag = true, need_bytes_func_ptr pNeed_bytes_func = NULL, void *pPrivate_data = NULL); - - inline void decode_set_input_buffer(const uint8* pBuf, size_t buf_size, const uint8* pBuf_next, bool eof_flag) - { - m_pDecode_buf = pBuf; - m_pDecode_buf_next = pBuf_next; - m_decode_buf_size = buf_size; - m_pDecode_buf_end = pBuf + buf_size; - m_decode_buf_eof = eof_flag; - } - inline uint64 decode_get_bytes_consumed() const { return m_pDecode_buf_next - m_pDecode_buf; } - inline uint64 decode_get_bits_remaining() const { return ((m_pDecode_buf_end - m_pDecode_buf_next) << 3) + m_bit_count; } - - void start_arith_decoding(); - uint decode_bits(uint num_bits); - uint decode_peek_bits(uint num_bits); - void decode_remove_bits(uint num_bits); - void decode_align_to_byte(); - int decode_remove_byte_from_bit_buf(); - uint decode(quasi_adaptive_huffman_data_model& model); - uint decode(adaptive_bit_model& model, bool update_model = true); - uint64 stop_decoding(); - - uint get_total_model_updates() const { return m_total_model_updates; } - - public: - lzham_malloc_context m_malloc_context; - - const uint8* m_pDecode_buf; - const uint8* m_pDecode_buf_next; - const uint8* m_pDecode_buf_end; - size_t m_decode_buf_size; - bool m_decode_buf_eof; - - need_bytes_func_ptr m_pDecode_need_bytes_func; - void* m_pDecode_private_data; - -#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER - typedef uint64 bit_buf_t; - enum { cBitBufSize = 64 }; -#else - typedef uint32 bit_buf_t; - enum { cBitBufSize = 32 }; -#endif - - bit_buf_t m_bit_buf; - int m_bit_count; - - uint m_total_model_updates; - - lzham::vector m_output_buf; - lzham::vector m_arith_output_buf; - - struct output_symbol - { - uint m_bits; - - enum - { - cArithSym = -1, - cAlignToByteSym = -2, - cArithInit = -3 - }; - int16 m_num_bits; - - uint16 m_arith_prob0; - }; - lzham::vector m_output_syms; - - uint m_total_bits_written; - - uint m_arith_base; - uint m_arith_value; - uint m_arith_length; - uint m_arith_total_bits; - - quasi_adaptive_huffman_data_model* m_pSaved_huff_model; - void* m_pSaved_model; - uint m_saved_node_index; - - bool put_bits_init(uint expected_size); - bool record_put_bits(uint bits, uint num_bits); - - void arith_propagate_carry(); - bool arith_renorm_enc_interval(); - void arith_start_encoding(); - bool arith_stop_encoding(); - - bool put_bits(uint bits, uint num_bits); - bool put_bits_align_to_byte(); - bool flush_bits(); - bool assemble_output_buf(); - - uint get_bits(uint num_bits); - void remove_bits(uint num_bits); - - void decode_need_bytes(); - - enum - { - cNull, - cEncoding, - cDecoding - } m_mode; - }; - -// Optional macros for faster decompression. These macros implement the symbol_codec class's decode functionality. -// This is hard to debug (and just plain ugly), but using these macros eliminate function calls, and they place the most important -// member variables on the stack so they're hopefully put in registers (avoiding horrible load hit stores on some CPU's). -// The user must define the LZHAM_DECODE_NEEDS_BYTES macro, which is invoked when the decode buffer is exhausted. - -#define LZHAM_SYMBOL_CODEC_DECODE_DECLARE(codec) \ - uint arith_value = 0; \ - uint arith_length = 0; \ - symbol_codec::bit_buf_t bit_buf = 0; \ - int bit_count = 0; \ - const uint8* pDecode_buf_next = NULL; - -#define LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \ - arith_value = codec.m_arith_value; \ - arith_length = codec.m_arith_length; \ - bit_buf = codec.m_bit_buf; \ - bit_count = codec.m_bit_count; \ - pDecode_buf_next = codec.m_pDecode_buf_next; - -#define LZHAM_SYMBOL_CODEC_DECODE_END(codec) \ - codec.m_arith_value = arith_value; \ - codec.m_arith_length = arith_length; \ - codec.m_bit_buf = bit_buf; \ - codec.m_bit_count = bit_count; \ - codec.m_pDecode_buf_next = pDecode_buf_next; - -// The user must declare the LZHAM_DECODE_NEEDS_BYTES macro. - -#define LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, result, num_bits) \ -{ \ - while (LZHAM_BUILTIN_EXPECT(bit_count < (int)(num_bits), 0)) \ - { \ - uint r; \ - if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \ - { \ - if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \ - { \ - LZHAM_SYMBOL_CODEC_DECODE_END(codec) \ - LZHAM_DECODE_NEEDS_BYTES \ - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \ - } \ - r = 0; \ - if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) r = *pDecode_buf_next++; \ - } \ - else \ - r = *pDecode_buf_next++; \ - bit_count += 8; \ - bit_buf |= (static_cast(r) << (symbol_codec::cBitBufSize - bit_count)); \ - } \ - result = (num_bits) ? static_cast(bit_buf >> (symbol_codec::cBitBufSize - (num_bits))) : 0; \ - bit_buf <<= (num_bits); \ - bit_count -= (num_bits); \ -} - -#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, result, model) \ -{ \ - adaptive_bit_model *pModel; \ - pModel = &model; \ - while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \ - { \ - uint c; codec.m_pSaved_model = pModel; \ - LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \ - pModel = static_cast(codec.m_pSaved_model); \ - arith_value = (arith_value << 8) | c; \ - arith_length <<= 8; \ - } \ - uint x = pModel->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \ - result = (arith_value >= x); \ - if (!result) \ - { \ - pModel->m_bit_0_prob += ((cSymbolCodecArithProbScale - pModel->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \ - arith_length = x; \ - } \ - else \ - { \ - pModel->m_bit_0_prob -= (pModel->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \ - arith_value -= x; \ - arith_length -= x; \ - } \ -} - -#if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER -#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \ -{ \ - quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \ - pModel = &model; pTables = model.m_pDecode_tables; \ - if (LZHAM_BUILTIN_EXPECT(bit_count < 24, 0)) \ - { \ - uint c; \ - pDecode_buf_next += sizeof(uint32); \ - if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next >= codec.m_pDecode_buf_end, 0)) \ - { \ - pDecode_buf_next -= sizeof(uint32); \ - while (bit_count < 24) \ - { \ - if (!codec.m_decode_buf_eof) \ - { \ - codec.m_pSaved_huff_model = pModel; \ - LZHAM_SYMBOL_CODEC_DECODE_END(codec) \ - LZHAM_DECODE_NEEDS_BYTES \ - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \ - pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \ - } \ - c = 0; if (pDecode_buf_next < codec.m_pDecode_buf_end) c = *pDecode_buf_next++; \ - bit_count += 8; \ - bit_buf |= (static_cast(c) << (symbol_codec::cBitBufSize - bit_count)); \ - } \ - } \ - else \ - { \ - c = LZHAM_READ_BIG_ENDIAN_UINT32(pDecode_buf_next - sizeof(uint32)); \ - bit_count += 32; \ - bit_buf |= (static_cast(c) << (symbol_codec::cBitBufSize - bit_count)); \ - } \ - } \ - uint k = static_cast((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \ - uint len; \ - if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \ - { \ - uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \ - result = t & cUINT16_MAX; \ - len = t >> 16; \ - } \ - else \ - { \ - len = pTables->m_decode_start_code_size; \ - for ( ; ; ) \ - { \ - if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \ - break; \ - len++; \ - } \ - int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast(bit_buf >> (symbol_codec::cBitBufSize - len)); \ - if (((uint)val_ptr >= pModel->m_total_syms)) val_ptr = 0; \ - result = pTables->m_sorted_symbol_order[val_ptr]; \ - } \ - bit_buf <<= len; \ - bit_count -= len; \ - uint freq = pModel->m_sym_freq[result]; \ - freq++; \ - pModel->m_sym_freq[result] = static_cast(freq); \ - LZHAM_ASSERT(freq <= cUINT16_MAX); \ - if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \ - { \ - pModel->update_tables(); \ - } \ -} -#else -#define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \ -{ \ - quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \ - pModel = &model; pTables = model.m_pDecode_tables; \ - while (LZHAM_BUILTIN_EXPECT(bit_count < (symbol_codec::cBitBufSize - 8), 1)) \ - { \ - uint c; \ - if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \ - { \ - if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \ - { \ - codec.m_pSaved_huff_model = pModel; \ - LZHAM_SYMBOL_CODEC_DECODE_END(codec) \ - LZHAM_DECODE_NEEDS_BYTES \ - LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \ - pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \ - } \ - c = 0; if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) c = *pDecode_buf_next++; \ - } \ - else \ - c = *pDecode_buf_next++; \ - bit_count += 8; \ - bit_buf |= (static_cast(c) << (symbol_codec::cBitBufSize - bit_count)); \ - } \ - uint k = static_cast((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \ - uint len; \ - if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \ - { \ - uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \ - result = t & cUINT16_MAX; \ - len = t >> 16; \ - } \ - else \ - { \ - len = pTables->m_decode_start_code_size; \ - for ( ; ; ) \ - { \ - if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \ - break; \ - len++; \ - } \ - int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast(bit_buf >> (symbol_codec::cBitBufSize - len)); \ - if (LZHAM_BUILTIN_EXPECT(((uint)val_ptr >= pModel->m_total_syms), 0)) val_ptr = 0; \ - result = pTables->m_sorted_symbol_order[val_ptr]; \ - } \ - bit_buf <<= len; \ - bit_count -= len; \ - uint freq = pModel->m_sym_freq[result]; \ - freq++; \ - pModel->m_sym_freq[result] = static_cast(freq); \ - LZHAM_ASSERT(freq <= cUINT16_MAX); \ - if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \ - { \ - pModel->update_tables(); \ - } \ -} -#endif - -#define LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec) if (bit_count & 7) { int dummy_result; LZHAM_NOTE_UNUSED(dummy_result); LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, dummy_result, bit_count & 7); } - -#define LZHAM_SYMBOL_CODEC_DECODE_REMOVE_BYTE_FROM_BIT_BUF(codec, result) \ -{ \ - result = -1; \ - if (bit_count >= 8) \ - { \ - result = static_cast(bit_buf >> (symbol_codec::cBitBufSize - 8)); \ - bit_buf <<= 8; \ - bit_count -= 8; \ - } \ -} - -#define LZHAM_SYMBOL_CODEC_DECODE_ARITH_START(codec) \ -{ \ - for ( arith_value = 0, arith_length = 0; arith_length < 4; ++arith_length ) \ - { \ - uint val; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, val, 8); \ - arith_value = (arith_value << 8) | val; \ - } \ - arith_length = cSymbolCodecArithMaxLen; \ -} - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -// File: lzham_timer.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_timer.h" - -#ifndef LZHAM_USE_WIN32_API - #include -#endif - -namespace lzham -{ - unsigned long long lzham_timer::g_init_ticks; - unsigned long long lzham_timer::g_freq; - double lzham_timer::g_inv_freq; - - #if LZHAM_USE_WIN32_API - inline void query_counter(timer_ticks *pTicks) - { - QueryPerformanceCounter(reinterpret_cast(pTicks)); - } - inline void query_counter_frequency(timer_ticks *pTicks) - { - QueryPerformanceFrequency(reinterpret_cast(pTicks)); - } - #else - inline void query_counter(timer_ticks *pTicks) - { - *pTicks = clock(); - } - inline void query_counter_frequency(timer_ticks *pTicks) - { - *pTicks = CLOCKS_PER_SEC; - } - #endif - - lzham_timer::lzham_timer() : - m_start_time(0), - m_stop_time(0), - m_started(false), - m_stopped(false) - { - if (!g_inv_freq) - init(); - } - - lzham_timer::lzham_timer(timer_ticks start_ticks) - { - if (!g_inv_freq) - init(); - - m_start_time = start_ticks; - - m_started = true; - m_stopped = false; - } - - void lzham_timer::start(timer_ticks start_ticks) - { - m_start_time = start_ticks; - - m_started = true; - m_stopped = false; - } - - void lzham_timer::start() - { - query_counter(&m_start_time); - - m_started = true; - m_stopped = false; - } - - void lzham_timer::stop() - { - LZHAM_ASSERT(m_started); - - query_counter(&m_stop_time); - - m_stopped = true; - } - - double lzham_timer::get_elapsed_secs() const - { - LZHAM_ASSERT(m_started); - if (!m_started) - return 0; - - timer_ticks stop_time = m_stop_time; - if (!m_stopped) - query_counter(&stop_time); - - timer_ticks delta = stop_time - m_start_time; - return delta * g_inv_freq; - } - - timer_ticks lzham_timer::get_elapsed_us() const - { - LZHAM_ASSERT(m_started); - if (!m_started) - return 0; - - timer_ticks stop_time = m_stop_time; - if (!m_stopped) - query_counter(&stop_time); - - timer_ticks delta = stop_time - m_start_time; - return (delta * 1000000ULL + (g_freq >> 1U)) / g_freq; - } - - void lzham_timer::init() - { - if (!g_inv_freq) - { - query_counter_frequency(&g_freq); - g_inv_freq = 1.0f / g_freq; - - query_counter(&g_init_ticks); - } - } - - timer_ticks lzham_timer::get_init_ticks() - { - if (!g_inv_freq) - init(); - - return g_init_ticks; - } - - timer_ticks lzham_timer::get_ticks() - { - if (!g_inv_freq) - init(); - - timer_ticks ticks; - query_counter(&ticks); - return ticks - g_init_ticks; - } - - double lzham_timer::ticks_to_secs(timer_ticks ticks) - { - if (!g_inv_freq) - init(); - - return ticks * g_inv_freq; - } - -} // namespace lzham \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -// File: lzham_timer.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - typedef unsigned long long timer_ticks; - - class lzham_timer - { - public: - lzham_timer(); - lzham_timer(timer_ticks start_ticks); - - void start(); - void start(timer_ticks start_ticks); - - void stop(); - - double get_elapsed_secs() const; - inline double get_elapsed_ms() const { return get_elapsed_secs() * 1000.0f; } - timer_ticks get_elapsed_us() const; - - static void init(); - static inline timer_ticks get_ticks_per_sec() { return g_freq; } - static timer_ticks get_init_ticks(); - static timer_ticks get_ticks(); - static double ticks_to_secs(timer_ticks ticks); - static inline double ticks_to_ms(timer_ticks ticks) { return ticks_to_secs(ticks) * 1000.0f; } - static inline double get_secs() { return ticks_to_secs(get_ticks()); } - static inline double get_ms() { return ticks_to_ms(get_ticks()); } - - private: - static timer_ticks g_init_ticks; - static timer_ticks g_freq; - static double g_inv_freq; - - timer_ticks m_start_time; - timer_ticks m_stop_time; - - bool m_started : 1; - bool m_stopped : 1; - }; - - enum var_args_t { cVarArgs }; - -#if LZHAM_PERF_SECTIONS - class scoped_perf_section - { - public: - inline scoped_perf_section() : - m_start_ticks(lzham_timer::get_ticks()) - { - m_name[0] = '?'; - m_name[1] = '\0'; - } - - inline scoped_perf_section(const char *pName) : - m_start_ticks(lzham_timer::get_ticks()) - { - strcpy_s(m_name, pName); - - lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name); - } - - inline scoped_perf_section(var_args_t, const char *pName, ...) : - m_start_ticks(lzham_timer::get_ticks()) - { - va_list args; - va_start(args, pName); - vsprintf_s(m_name, sizeof(m_name), pName, args); - va_end(args); - - lzham_buffered_printf("Thread: 0x%08X, BEGIN Time: %3.3fms, %s\n", GetCurrentThreadId(), lzham_timer::ticks_to_ms(m_start_ticks), m_name); - } - - inline ~scoped_perf_section() - { - double end_ms = lzham_timer::get_ms(); - double start_ms = lzham_timer::ticks_to_ms(m_start_ticks); - - lzham_buffered_printf("Thread: 0x%08X, END Time: %3.3fms, %s, Total: %3.3fms\n", GetCurrentThreadId(), end_ms, m_name, end_ms - start_ms); - } - - private: - char m_name[64]; - timer_ticks m_start_ticks; - }; -#else - class scoped_perf_section - { - public: - inline scoped_perf_section() { } - inline scoped_perf_section(const char *pName) { (void)pName; } - inline scoped_perf_section(var_args_t, const char *pName, ...) { (void)pName; } - }; -#endif // LZHAM_PERF_SECTIONS - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_traits.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_traits.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_traits.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_traits.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -// File: lzham_traits.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - template - struct scalar_type - { - enum { cFlag = false }; - static inline void construct(T* p) { helpers::construct(p); } - static inline void construct(T* p, const T& init) { helpers::construct(p, init); } - static inline void construct_array(T* p, uint n) { helpers::construct_array(p, n); } - static inline void destruct(T* p) { helpers::destruct(p); } - static inline void destruct_array(T* p, uint n) { helpers::destruct_array(p, n); } - }; - - template struct scalar_type - { - enum { cFlag = true }; - static inline void construct(T** p) { memset(p, 0, sizeof(T*)); } - static inline void construct(T** p, T* init) { *p = init; } - static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); } - static inline void destruct(T** p) { LZHAM_NOTE_UNUSED(p); } - static inline void destruct_array(T** p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } - }; - -#define LZHAM_DEFINE_BUILT_IN_TYPE(X) \ - template<> struct scalar_type { \ - enum { cFlag = true }; \ - static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \ - static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \ - static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \ - static inline void destruct(X* p) { LZHAM_NOTE_UNUSED(p); } \ - static inline void destruct_array(X* p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } }; - - LZHAM_DEFINE_BUILT_IN_TYPE(bool) - LZHAM_DEFINE_BUILT_IN_TYPE(char) - LZHAM_DEFINE_BUILT_IN_TYPE(unsigned char) - LZHAM_DEFINE_BUILT_IN_TYPE(short) - LZHAM_DEFINE_BUILT_IN_TYPE(unsigned short) - LZHAM_DEFINE_BUILT_IN_TYPE(int) - LZHAM_DEFINE_BUILT_IN_TYPE(unsigned int) - LZHAM_DEFINE_BUILT_IN_TYPE(long) - LZHAM_DEFINE_BUILT_IN_TYPE(unsigned long) - LZHAM_DEFINE_BUILT_IN_TYPE(float) - LZHAM_DEFINE_BUILT_IN_TYPE(double) - LZHAM_DEFINE_BUILT_IN_TYPE(long double) - #if defined(WIN32) - LZHAM_DEFINE_BUILT_IN_TYPE(__int64) - LZHAM_DEFINE_BUILT_IN_TYPE(unsigned __int64) - #endif - -#undef LZHAM_DEFINE_BUILT_IN_TYPE - -// See: http://erdani.org/publications/cuj-2004-06.pdf - - template - struct bitwise_movable { enum { cFlag = false }; }; - -// Defines type Q as bitwise movable. -#define LZHAM_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable { enum { cFlag = true }; }; - - template - struct bitwise_copyable { enum { cFlag = false }; }; - - // Defines type Q as bitwise copyable. -#define LZHAM_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable { enum { cFlag = true }; }; - -#if (defined(__APPLE__) && (TARGET_OS_MAC != 1)) || defined(__NetBSD__) - #define LZHAM_IS_POD(T) std::is_pod::value -#else - #define LZHAM_IS_POD(T) __is_pod(T) -#endif - -#define LZHAM_IS_SCALAR_TYPE(T) (scalar_type::cFlag) - -#define LZHAM_IS_BITWISE_COPYABLE(T) ((scalar_type::cFlag) || (bitwise_copyable::cFlag) || LZHAM_IS_POD(T)) - -#define LZHAM_IS_BITWISE_MOVABLE(T) (LZHAM_IS_BITWISE_COPYABLE(T) || (bitwise_movable::cFlag)) - -#define LZHAM_HAS_DESTRUCTOR(T) ((!scalar_type::cFlag) && (!LZHAM_IS_POD(T))) - - // From yasli_traits.h: - // Credit goes to Boost; - // also found in the C++ Templates book by Vandevoorde and Josuttis - - typedef char (&yes_t)[1]; - typedef char (&no_t)[2]; - - template yes_t class_test(int U::*); - template no_t class_test(...); - - template struct is_class - { - enum { value = (sizeof(class_test(0)) == sizeof(yes_t)) }; - }; - - template struct is_pointer - { - enum { value = false }; - }; - - template struct is_pointer - { - enum { value = true }; - }; - - LZHAM_DEFINE_BITWISE_COPYABLE(empty_type); - LZHAM_DEFINE_BITWISE_MOVABLE(empty_type); - - namespace helpers - { - template - inline void construct_array(T* p, uint n) - { - if (LZHAM_IS_SCALAR_TYPE(T)) - { - memset(p, 0, sizeof(T) * n); - } - else - { - T* q = p + n; - for ( ; p != q; ++p) - new (static_cast(p)) T; - } - } - - template - inline void destruct_array(T* p, uint n) - { - if ( LZHAM_HAS_DESTRUCTOR(T) ) - { - T* q = p + n; - for ( ; p != q; ++p) - p->~T(); - } - } - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_types.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_types.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_types.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_types.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -// File: types.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - typedef unsigned char uint8; - typedef signed char int8; - typedef unsigned char uint8; - typedef unsigned short uint16; - typedef signed short int16; - typedef unsigned int uint32; - typedef uint32 uint; - typedef signed int int32; - - #ifdef _MSC_VER - typedef unsigned __int64 uint64; - typedef signed __int64 int64; - #else - typedef unsigned long long uint64; - typedef long long int64; - #endif - - const uint8 cUINT8_MIN = 0; - const uint8 cUINT8_MAX = 0xFFU; - const uint16 cUINT16_MIN = 0; - const uint16 cUINT16_MAX = 0xFFFFU; - const uint32 cUINT32_MIN = 0; - const uint32 cUINT32_MAX = 0xFFFFFFFFU; - const uint64 cUINT64_MIN = 0; - const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64; - - const int8 cINT8_MIN = -128; - const int8 cINT8_MAX = 127; - const int16 cINT16_MIN = -32768; - const int16 cINT16_MAX = 32767; - const int32 cINT32_MIN = (-2147483647 - 1); - const int32 cINT32_MAX = 2147483647; - const int64 cINT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1); - const int64 cINT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; //9223372036854775807i64; - -#if LZHAM_64BIT_POINTERS - typedef uint64 uint_ptr; - typedef uint64 uint32_ptr; - typedef int64 signed_size_t; - typedef uint64 ptr_bits_t; -#else - typedef unsigned int uint_ptr; - typedef unsigned int uint32_ptr; - typedef signed int signed_size_t; - typedef uint32 ptr_bits_t; -#endif - - enum - { - cInvalidIndex = -1 - }; - - const uint cIntBits = sizeof(uint) * CHAR_BIT; - - template struct int_traits { enum { cMin = INT_MIN, cMax = INT_MAX, cSigned = true }; }; - template<> struct int_traits { enum { cMin = cINT8_MIN, cMax = cINT8_MAX, cSigned = true }; }; - template<> struct int_traits { enum { cMin = cINT16_MIN, cMax = cINT16_MAX, cSigned = true }; }; - template<> struct int_traits { enum { cMin = cINT32_MIN, cMax = cINT32_MAX, cSigned = true }; }; - - template<> struct int_traits { enum { cMin = 0, cMax = UINT_MAX, cSigned = false }; }; - template<> struct int_traits { enum { cMin = 0, cMax = cUINT8_MAX, cSigned = false }; }; - template<> struct int_traits { enum { cMin = 0, cMax = cUINT16_MAX, cSigned = false }; }; - - struct empty_type { }; - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_utils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_utils.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_utils.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_utils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -// File: lzham_utils.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -#define LZHAM_GET_ALIGNMENT(v) ((!sizeof(v)) ? 1 : (__alignof(v) ? __alignof(v) : sizeof(uint32))) - -#define LZHAM_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define LZHAM_MAX(a, b) (((a) < (b)) ? (b) : (a)) - -template T decay_array_to_subtype(T (&a)[N]); -#define LZHAM_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X))) - -namespace lzham -{ - namespace utils - { - template inline void swap(T& l, T& r) - { - T temp(l); - l = r; - r = temp; - } - - template inline void zero_object(T& obj) - { - memset(&obj, 0, sizeof(obj)); - } - - static inline uint32 swap32(uint32 x) { return ((x << 24U) | ((x << 8U) & 0x00FF0000U) | ((x >> 8U) & 0x0000FF00U) | (x >> 24U)); } - - inline uint count_leading_zeros16(uint v) - { - LZHAM_ASSERT(v < 0x10000); - - uint temp; - uint n = 16; - - temp = v >> 8; - if (temp) { n -= 8; v = temp; } - - temp = v >> 4; - if (temp) { n -= 4; v = temp; } - - temp = v >> 2; - if (temp) { n -= 2; v = temp; } - - temp = v >> 1; - if (temp) { n -= 1; v = temp; } - - if (v & 1) n--; - - return n; - } - - } // namespace utils - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -// File: lzham_vector.cpp -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_vector.h" - -namespace lzham -{ - bool elemental_vector::increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pMover, bool nofail) - { - LZHAM_ASSERT(m_size <= m_capacity); - -#if LZHAM_64BIT_POINTERS - LZHAM_ASSUME(sizeof(void*) == sizeof(uint64)); - LZHAM_ASSERT(min_new_capacity < (0x400000000ULL / element_size)); -#else - LZHAM_ASSUME(sizeof(void*) == sizeof(uint32)); - LZHAM_ASSERT(min_new_capacity < (0x7FFF0000U / element_size)); -#endif - - if (m_capacity >= min_new_capacity) - return true; - - // new_capacity must be 64-bit when compiling on x64. - size_t new_capacity = (size_t)min_new_capacity; - if ((grow_hint) && (!math::is_power_of_2(static_cast(new_capacity)))) - new_capacity = static_cast(math::next_pow2(static_cast(new_capacity))); - - LZHAM_ASSERT(new_capacity && (new_capacity > m_capacity)); - - const size_t desired_size = element_size * new_capacity; - size_t actual_size; - if (!pMover) - { - void* new_p = lzham_realloc(m_malloc_context, m_p, desired_size, &actual_size, true); - if (!new_p) - { - if (nofail) - { - LZHAM_LOG_ERROR(5000); - return false; - } - - char buf[256]; - sprintf_s(buf, sizeof(buf), "vector: lzham_realloc() failed allocating %u bytes", desired_size); - LZHAM_FAIL(buf); - } - m_p = new_p; - } - else - { - void* new_p = lzham_malloc(m_malloc_context, desired_size, &actual_size); - if (!new_p) - { - if (nofail) - { - LZHAM_LOG_ERROR(5001); - return false; - } - - LZHAM_LOG_ERROR(5002); - - char buf[256]; - sprintf_s(buf, sizeof(buf), "vector: lzham_malloc() failed allocating %u bytes", desired_size); - LZHAM_FAIL(buf); - } - - (*pMover)(new_p, m_p, m_size); - - if (m_p) - lzham_free(m_malloc_context, m_p); - - m_p = new_p; - } - - if (actual_size > desired_size) - m_capacity = static_cast(actual_size / element_size); - else - m_capacity = static_cast(new_capacity); - - return true; - } - -} // namespace lzham diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.h 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,628 +0,0 @@ -// File: lzham_vector.h -// See Copyright Notice and license at the end of include/lzham.h -#pragma once - -namespace lzham -{ - struct elemental_vector - { - void* m_p; - uint m_size; - uint m_capacity; - lzham_malloc_context m_malloc_context; - - typedef void (*object_mover)(void* pDst, void* pSrc, uint num); - - bool increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pRelocate, bool nofail); - }; - - template - class vector : public helpers::rel_ops< vector > - { - public: - typedef T* iterator; - typedef const T* const_iterator; - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - - inline vector(lzham_malloc_context context = NULL) : - m_p(NULL), - m_size(0), - m_capacity(0), - m_malloc_context(context) - { - } - - inline vector(lzham_malloc_context context, uint n, const T& init) : - m_p(NULL), - m_size(0), - m_capacity(0), - m_malloc_context(context) - { - increase_capacity(n, false); - helpers::construct_array(m_p, n, init); - m_size = n; - } - - inline vector(const vector& other) : - m_p(NULL), - m_size(0), - m_capacity(0), - m_malloc_context(other.m_malloc_context) - { - increase_capacity(other.m_size, false); - - m_size = other.m_size; - - if (LZHAM_IS_BITWISE_COPYABLE(T)) - memcpy(m_p, other.m_p, m_size * sizeof(T)); - else - { - T* pDst = m_p; - const T* pSrc = other.m_p; - for (uint i = m_size; i > 0; i--) - helpers::construct(pDst++, *pSrc++); - } - } - -#if 0 - inline explicit vector(lzham_malloc_context context, uint size) : - m_p(NULL), - m_size(0), - m_capacity(0), - m_malloc_context(context) - { - try_resize(size); - } -#endif - - inline ~vector() - { - if (m_p) - { - scalar_type::destruct_array(m_p, m_size); - lzham_free(m_malloc_context, m_p); - } - } - - lzham_malloc_context get_malloc_context() const - { - return m_malloc_context; - } - - void set_malloc_context(lzham_malloc_context context) - { - clear(); - m_malloc_context = context; - } - - inline vector& operator= (const vector& other) - { - if (this == &other) - return *this; - - if (m_capacity >= other.m_size) - try_resize(0); - else - { - clear(); - if (!increase_capacity(other.m_size, false)) - { - LZHAM_LOG_ERROR(5008); - LZHAM_FAIL("lzham::vector operator=: Out of memory!"); - return *this; - } - } - - if (LZHAM_IS_BITWISE_COPYABLE(T)) - memcpy(m_p, other.m_p, other.m_size * sizeof(T)); - else - { - T* pDst = m_p; - const T* pSrc = other.m_p; - for (uint i = other.m_size; i > 0; i--) - helpers::construct(pDst++, *pSrc++); - } - - m_size = other.m_size; - - return *this; - } - - inline const T* begin() const { return m_p; } - T* begin() { return m_p; } - - inline const T* end() const { return m_p + m_size; } - T* end() { return m_p + m_size; } - - inline bool empty() const { return !m_size; } - inline uint size() const { return m_size; } - inline uint size_in_bytes() const { return m_size * sizeof(T); } - inline uint capacity() const { return m_capacity; } - - // operator[] will assert on out of range indices, but in final builds there is (and will never be) any range checking on this method. - inline const T& operator[] (uint i) const { LZHAM_ASSERT(i < m_size); return m_p[i]; } - inline T& operator[] (uint i) { LZHAM_ASSERT(i < m_size); return m_p[i]; } - - // at() always includes range checking, even in final builds, unlike operator []. - // The first element is returned if the index is out of range. - inline const T& at(uint i) const { LZHAM_ASSERT(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } - inline T& at(uint i) { LZHAM_ASSERT(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } - - inline const T& front() const { LZHAM_ASSERT(m_size); return m_p[0]; } - inline T& front() { LZHAM_ASSERT(m_size); return m_p[0]; } - - inline const T& back() const { LZHAM_ASSERT(m_size); return m_p[m_size - 1]; } - inline T& back() { LZHAM_ASSERT(m_size); return m_p[m_size - 1]; } - - inline const T* get_ptr() const { return m_p; } - inline T* get_ptr() { return m_p; } - - inline void clear() - { - if (m_p) - { - scalar_type::destruct_array(m_p, m_size); - lzham_free(m_malloc_context, m_p); - m_p = NULL; - m_size = 0; - m_capacity = 0; - } - } - - inline void clear_no_destruction() - { - if (m_p) - { - lzham_free(m_malloc_context, m_p); - m_p = NULL; - m_size = 0; - m_capacity = 0; - } - } - - inline bool try_reserve(uint new_capacity) - { - return increase_capacity(new_capacity, true, true); - } - - inline bool try_resize(uint new_size, bool grow_hint = false) - { - if (m_size != new_size) - { - if (new_size < m_size) - scalar_type::destruct_array(m_p + new_size, m_size - new_size); - else - { - if (new_size > m_capacity) - { - if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true)) - { - LZHAM_LOG_ERROR(5004); - return false; - } - } - - scalar_type::construct_array(m_p + m_size, new_size - m_size); - } - - m_size = new_size; - } - - return true; - } - - inline bool try_resize_no_construct(uint new_size, bool grow_hint = false) - { - if (new_size > m_capacity) - { - if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true)) - { - LZHAM_LOG_ERROR(5005); - return false; - } - } - - m_size = new_size; - - return true; - } - - inline T* try_enlarge(uint i) - { - uint cur_size = m_size; - if (!try_resize(cur_size + i, true)) - { - LZHAM_LOG_ERROR(5006); - return NULL; - } - return get_ptr() + cur_size; - } - - inline bool try_push_back(const T& obj) - { - LZHAM_ASSERT(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size))); - - if (m_size >= m_capacity) - { - if (!increase_capacity(m_size + 1, true, true)) - { - LZHAM_LOG_ERROR(5007); - return false; - } - } - - scalar_type::construct(m_p + m_size, obj); - m_size++; - - return true; - } - - inline void pop_back() - { - LZHAM_ASSERT(m_size); - - if (m_size) - { - m_size--; - scalar_type::destruct(&m_p[m_size]); - } - } - - inline bool insert(uint index, const T* p, uint n) - { - LZHAM_ASSERT(index <= m_size); - if (!n) - return true; - - const uint orig_size = m_size; - if (!try_resize(m_size + n, true)) - return false; - - const uint num_to_move = orig_size - index; - if (num_to_move) - { - if (LZHAM_IS_BITWISE_COPYABLE(T)) - memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move); - else - { - const T* pSrc = m_p + orig_size - 1; - T* pDst = const_cast(pSrc) + n; - - for (uint i = 0; i < num_to_move; i++) - { - LZHAM_ASSERT((pDst - m_p) < (int)m_size); - *pDst-- = *pSrc--; - } - } - } - - T* pDst = m_p + index; - - if (LZHAM_IS_BITWISE_COPYABLE(T)) - memcpy(pDst, p, sizeof(T) * n); - else - { - for (uint i = 0; i < n; i++) - { - LZHAM_ASSERT((pDst - m_p) < (int)m_size); - *pDst++ = *p++; - } - } - - return true; - } - - // push_front() isn't going to be very fast - it's only here for usability. - inline bool try_push_front(const T& obj) - { - return insert(0, &obj, 1); - } - - bool append(const vector& other) - { - if (other.m_size) - return insert(m_size, &other[0], other.m_size); - return true; - } - - bool append(const T* p, uint n) - { - if (n) - return insert(m_size, p, n); - return true; - } - - inline void erase(uint start, uint n) - { - LZHAM_ASSERT((start + n) <= m_size); - if ((start + n) > m_size) - return; - - if (!n) - return; - - const uint num_to_move = m_size - (start + n); - - T* pDst = m_p + start; - - const T* pSrc = m_p + start + n; - - if (LZHAM_IS_BITWISE_COPYABLE(T)) - memmove(pDst, pSrc, num_to_move * sizeof(T)); - else - { - T* pDst_end = pDst + num_to_move; - - while (pDst != pDst_end) - *pDst++ = *pSrc++; - - scalar_type::destruct_array(pDst_end, n); - } - - m_size -= n; - } - - inline void erase(uint index) - { - erase(index, 1); - } - - inline void erase(T* p) - { - LZHAM_ASSERT((p >= m_p) && (p < (m_p + m_size))); - erase(static_cast(p - m_p)); - } - - void erase_unordered(uint index) - { - LZHAM_ASSERT(index < m_size); - - if ((index + 1) < m_size) - (*this)[index] = back(); - - pop_back(); - } - - inline bool operator== (const vector& rhs) const - { - if (m_size != rhs.m_size) - return false; - else if (m_size) - { - if (scalar_type::cFlag) - return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0; - else - { - const T* pSrc = m_p; - const T* pDst = rhs.m_p; - for (uint i = m_size; i; i--) - if (!(*pSrc++ == *pDst++)) - return false; - } - } - - return true; - } - - inline bool operator< (const vector& rhs) const - { - const uint min_size = math::minimum(m_size, rhs.m_size); - - const T* pSrc = m_p; - const T* pSrc_end = m_p + min_size; - const T* pDst = rhs.m_p; - - while ((pSrc < pSrc_end) && (*pSrc == *pDst)) - { - pSrc++; - pDst++; - } - - if (pSrc < pSrc_end) - return *pSrc < *pDst; - - return m_size < rhs.m_size; - } - - inline void swap(vector& other) - { - utils::swap(m_p, other.m_p); - utils::swap(m_size, other.m_size); - utils::swap(m_capacity, other.m_capacity); - } - - inline void sort() - { - std::sort(begin(), end()); - } - - inline void unique() - { - if (!empty()) - { - sort(); - - resize(std::unique(begin(), end()) - begin()); - } - } - - inline void reverse() - { - uint j = m_size >> 1; - for (uint i = 0; i < j; i++) - utils::swap(m_p[i], m_p[m_size - 1 - i]); - } - - inline int find(const T& key) const - { - const T* p = m_p; - const T* p_end = m_p + m_size; - - uint index = 0; - - while (p != p_end) - { - if (key == *p) - return index; - - p++; - index++; - } - - return cInvalidIndex; - } - - inline int find_sorted(const T& key) const - { - if (m_size) - { - // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice. - int i = ((m_size + 1) >> 1) - 1; - int m = m_size; - - for ( ; ; ) - { - LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size); - const T* pKey_i = m_p + i; - int cmp = key < *pKey_i; - if ((!cmp) && (key == *pKey_i)) return i; - m >>= 1; - if (!m) break; - cmp = -cmp; - i += (((m + 1) >> 1) ^ cmp) - cmp; - if (i < 0) - break; - - LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size); - pKey_i = m_p + i; - cmp = key < *pKey_i; - if ((!cmp) && (key == *pKey_i)) return i; - m >>= 1; - if (!m) break; - cmp = -cmp; - i += (((m + 1) >> 1) ^ cmp) - cmp; - if (i < 0) - break; - } - } - - return cInvalidIndex; - } - - template - inline int find_sorted(const T& key, Q less_than) const - { - if (m_size) - { - // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice. - int i = ((m_size + 1) >> 1) - 1; - int m = m_size; - - for ( ; ; ) - { - LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size); - const T* pKey_i = m_p + i; - int cmp = less_than(key, *pKey_i); - if ((!cmp) && (!less_than(*pKey_i, key))) return i; - m >>= 1; - if (!m) break; - cmp = -cmp; - i += (((m + 1) >> 1) ^ cmp) - cmp; - if (i < 0) - break; - - LZHAM_ASSERT_OPEN_RANGE(i, 0, (int)m_size); - pKey_i = m_p + i; - cmp = less_than(key, *pKey_i); - if ((!cmp) && (!less_than(*pKey_i, key))) return i; - m >>= 1; - if (!m) break; - cmp = -cmp; - i += (((m + 1) >> 1) ^ cmp) - cmp; - if (i < 0) - break; - } - } - - return cInvalidIndex; - } - - inline uint count_occurences(const T& key) const - { - uint c = 0; - - const T* p = m_p; - const T* p_end = m_p + m_size; - - while (p != p_end) - { - if (key == *p) - c++; - - p++; - } - - return c; - } - - inline void set_all(const T& o) - { - if ((sizeof(T) == 1) && (scalar_type::cFlag)) - memset(m_p, *reinterpret_cast(&o), m_size); - else - { - T* pDst = m_p; - T* pDst_end = pDst + m_size; - while (pDst != pDst_end) - *pDst++ = o; - } - } - - private: - T* m_p; - uint m_size; - uint m_capacity; - lzham_malloc_context m_malloc_context; - - template struct is_vector { enum { cFlag = false }; }; - template struct is_vector< vector > { enum { cFlag = true }; }; - - static void object_mover(void* pDst_void, void* pSrc_void, uint num) - { - T* pSrc = static_cast(pSrc_void); - T* const pSrc_end = pSrc + num; - T* pDst = static_cast(pDst_void); - - while (pSrc != pSrc_end) - { - new (static_cast(pDst)) T(*pSrc); - pSrc->~T(); - pSrc++; - pDst++; - } - } - - inline bool increase_capacity(uint min_new_capacity, bool grow_hint, bool nofail = false) - { - return reinterpret_cast(this)->increase_capacity( - min_new_capacity, grow_hint, sizeof(T), - (LZHAM_IS_BITWISE_MOVABLE(T) || (is_vector::cFlag)) ? NULL : object_mover, nofail); - } - }; - - template struct bitwise_movable< vector > { enum { cFlag = true }; }; - - extern void vector_test(); - - template - inline void swap(vector& a, vector& b) - { - a.swap(b); - } - -} // namespace lzham - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzhamdecomp.vcxproj p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzhamdecomp.vcxproj --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamdecomp/lzhamdecomp.vcxproj 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamdecomp/lzhamdecomp.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {8DA0CD32-701D-48D7-AE92-728338501500} - lzhamdecomp - Win32Proj - - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)lib\x86D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x86\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64\ - $(Platform)\$(Configuration)\ - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(ProjectName)_x64 - $(ProjectName)_x64D - $(ProjectName)_x86 - $(ProjectName)_x86D - - - - Disabled - ..\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - EditAndContinue - - - $(OutDir)$(ProjectName)_x86D.lib - - - - - X64 - - - Disabled - ..\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64D.lib - - - - - Full - AnySuitable - true - Speed - true - ..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - StreamingSIMDExtensions - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x86.lib - - - - - X64 - - - Full - AnySuitable - true - Speed - true - ..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -// File: lzham_lib.cpp - Static library entrypoints. -// See Copyright Notice and license at the end of include/lzham.h -#include "lzham_core.h" -#include "lzham_decomp.h" -#include "lzham_comp.h" - -extern "C" lzham_uint32 LZHAM_CDECL lzham_get_version(void) -{ - return LZHAM_DLL_VERSION; -} - -extern "C" void LZHAM_CDECL lzham_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data) -{ - lzham::lzham_lib_set_memory_callbacks(pRealloc, pMSize, pUser_data); -} - -extern "C" lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_init(const lzham_decompress_params *pParams) -{ - return lzham::lzham_lib_decompress_init(pParams); -} - -extern "C" lzham_decompress_state_ptr LZHAM_CDECL lzham_decompress_reinit(lzham_decompress_state_ptr p, const lzham_decompress_params *pParams) -{ - return lzham::lzham_lib_decompress_reinit(p, pParams); -} - -extern "C" lzham_uint32 LZHAM_CDECL lzham_decompress_deinit(lzham_decompress_state_ptr p) -{ - return lzham::lzham_lib_decompress_deinit(p); -} - -extern "C" lzham_decompress_status_t LZHAM_CDECL lzham_decompress( - lzham_decompress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag) -{ - return lzham::lzham_lib_decompress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); -} - -extern "C" lzham_decompress_status_t LZHAM_CDECL lzham_decompress_memory(const lzham_decompress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) -{ - return lzham::lzham_lib_decompress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); -} - -extern "C" lzham_compress_state_ptr LZHAM_CDECL lzham_compress_init(const lzham_compress_params *pParams) -{ - return lzham::lzham_lib_compress_init(pParams); -} - -extern "C" lzham_compress_state_ptr LZHAM_CDECL lzham_compress_reinit(lzham_compress_state_ptr p) -{ - return lzham::lzham_lib_compress_reinit(p); -} - -extern "C" lzham_uint32 LZHAM_CDECL lzham_compress_deinit(lzham_compress_state_ptr p) -{ - return lzham::lzham_lib_compress_deinit(p); -} - -extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_bool no_more_input_bytes_flag) -{ - return lzham::lzham_lib_compress(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, no_more_input_bytes_flag); -} - -extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress2( - lzham_compress_state_ptr p, - const lzham_uint8 *pIn_buf, size_t *pIn_buf_size, - lzham_uint8 *pOut_buf, size_t *pOut_buf_size, - lzham_flush_t flush_type) -{ - return lzham::lzham_lib_compress2(p, pIn_buf, pIn_buf_size, pOut_buf, pOut_buf_size, flush_type); -} - -extern "C" lzham_compress_status_t LZHAM_CDECL lzham_compress_memory(const lzham_compress_params *pParams, lzham_uint8* pDst_buf, size_t *pDst_len, const lzham_uint8* pSrc_buf, size_t src_len, lzham_uint32 *pAdler32) -{ - return lzham::lzham_lib_compress_memory(pParams, pDst_buf, pDst_len, pSrc_buf, src_len, pAdler32); -} - -// ----------------- zlib-style API's - -extern "C" const char * LZHAM_CDECL lzham_z_version(void) -{ - return LZHAM_Z_VERSION; -} - -extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_adler32(lzham_z_ulong adler, const unsigned char *ptr, size_t buf_len) -{ - return lzham::lzham_lib_z_adler32(adler, ptr, buf_len); -} - -extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_crc32(lzham_z_ulong crc, const lzham_uint8 *ptr, size_t buf_len) -{ - return lzham::lzham_lib_z_crc32(crc, ptr, buf_len); -} - -extern "C" int LZHAM_CDECL lzham_z_deflateInit(lzham_z_streamp pStream, int level) -{ - return lzham::lzham_lib_z_deflateInit(pStream, level); -} - -extern "C" int LZHAM_CDECL lzham_z_deflateInit2(lzham_z_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) -{ - return lzham::lzham_lib_z_deflateInit2(pStream, level, method, window_bits, mem_level, strategy); -} - -extern "C" int LZHAM_CDECL lzham_z_deflateReset(lzham_z_streamp pStream) -{ - return lzham::lzham_lib_z_deflateReset(pStream); -} - -extern "C" int LZHAM_CDECL lzham_z_deflate(lzham_z_streamp pStream, int flush) -{ - return lzham::lzham_lib_z_deflate(pStream, flush); -} - -extern "C" int LZHAM_CDECL lzham_z_deflateEnd(lzham_z_streamp pStream) -{ - return lzham::lzham_lib_z_deflateEnd(pStream); -} - -extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_deflateBound(lzham_z_streamp pStream, lzham_z_ulong source_len) -{ - return lzham::lzham_lib_z_deflateBound(pStream, source_len); -} - -extern "C" int LZHAM_CDECL lzham_z_compress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) -{ - return lzham::lzham_lib_z_compress(pDest, pDest_len, pSource, source_len); -} - -extern "C" int LZHAM_CDECL lzham_z_compress2(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len, int level) -{ - return lzham::lzham_lib_z_compress2(pDest, pDest_len, pSource, source_len, level); -} - -extern "C" lzham_z_ulong LZHAM_CDECL lzham_z_compressBound(lzham_z_ulong source_len) -{ - return lzham::lzham_lib_z_compressBound(source_len); -} - -extern "C" int LZHAM_CDECL lzham_z_inflateInit(lzham_z_streamp pStream) -{ - return lzham::lzham_lib_z_inflateInit(pStream); -} - -extern "C" int LZHAM_CDECL lzham_z_inflateInit2(lzham_z_streamp pStream, int window_bits) -{ - return lzham::lzham_lib_z_inflateInit2(pStream, window_bits); -} - -extern "C" int LZHAM_CDECL lzham_z_inflateReset(lzham_z_streamp pStream) -{ - return lzham::lzham_lib_z_inflateReset(pStream); -} - -extern "C" int LZHAM_CDECL lzham_z_inflate(lzham_z_streamp pStream, int flush) -{ - return lzham::lzham_lib_z_inflate(pStream, flush); -} - -extern "C" int LZHAM_CDECL lzham_z_inflateEnd(lzham_z_streamp pStream) -{ - return lzham::lzham_lib_z_inflateEnd(pStream); -} - -extern "C" int LZHAM_CDECL lzham_z_uncompress(unsigned char *pDest, lzham_z_ulong *pDest_len, const unsigned char *pSource, lzham_z_ulong source_len) -{ - return lzham::lzham_lib_z_uncompress(pDest, pDest_len, pSource, source_len); -} - -extern "C" const char * LZHAM_CDECL lzham_z_error(int err) -{ - return lzham::lzham_lib_z_error(err); -} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamlib/lzhamlib.vcxproj p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzhamlib.vcxproj --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/lzhamlib/lzhamlib.vcxproj 2015-11-21 17:07:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/lzhamlib/lzhamlib.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {83A2F0B5-1D02-4A13-B579-714F60E31774} - lzhamlib - Win32Proj - - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - StaticLibrary - Unicode - true - v100 - - - StaticLibrary - Unicode - v100 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)lib\x86D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x86\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64D\ - $(Platform)\$(Configuration)\ - $(SolutionDir)lib\x64\ - $(Platform)\$(Configuration)\ - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(ProjectName)_x64 - $(ProjectName)_x86 - $(ProjectName)_x64D - $(ProjectName)_x86D - - - - Disabled - ..\include;..\lzhamdecomp;..\lzhamcomp;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - EditAndContinue - - - $(OutDir)$(ProjectName)_x86D.lib - - - - - Full - AnySuitable - true - Speed - true - ..\include;..\lzhamdecomp;..\lzhamcomp;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - StreamingSIMDExtensions - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x86.lib - - - - - X64 - - - Disabled - ..\include;..\lzhamdecomp;..\lzhamcomp;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64D.lib - - - - - X64 - - - Full - AnySuitable - true - Speed - true - ..\include;..\lzhamdecomp;..\lzhamcomp;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - - - MultiThreaded - false - true - Fast - - - Level4 - ProgramDatabase - - - $(OutDir)$(ProjectName)_x64.lib - - - - - - - - - \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/makefile 2016-03-10 20:20:29.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - -TARGET_FLAGS=$(CC_SHARED) -DRegisterCodec=DllRegisterCodec -Iinclude -Ilzhamdecomp -Ilzhamcomp -I../../../../ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LOCAL_LINK=$(LINK_SHARED) -LIBS=$(LOCAL_LIBS) - -include ../../../../makefile.glb diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzham/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile.list --- p7zip-rar-16.02/CPP/7zip/Compress/Lzham/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzham/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/Codecs/Lzham.so - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../../CPP/7zip/Compress/Lzham/LzhamRegister.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp \ - -SRCS_C=\ - ../../../../C/Alloc.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -CodecExports.o : ../../../../CPP/7zip/Compress/CodecExports.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CodecExports.cpp -DllExportsCompress.o : ../../../../CPP/7zip/Compress/DllExportsCompress.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DllExportsCompress.cpp -LzhamRegister.o : ../../../../CPP/7zip/Compress/Lzham/LzhamRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/LzhamRegister.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -lzham_lzbase.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp -lzham_lzcomp.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp -lzham_lzcomp_internal.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp -lzham_lzcomp_state.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp -lzham_match_accel.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp -lzham_pthreads_threading.o : ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp -lzham_assert.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp -lzham_checksum.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp -lzham_huffman_codes.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp -lzham_lzdecomp.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp -lzham_lzdecompbase.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp -lzham_mem.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp -lzham_platform.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp -lzham_prefix_coding.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp -lzham_symbol_codec.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp -lzham_timer.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp -lzham_vector.o : ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp -lzham_lib.o : ../../../../CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp - -OBJS=\ - Alloc.o \ - StreamUtils.o \ - CodecExports.o \ - DllExportsCompress.o \ - LzhamRegister.o \ - MyWindows.o \ - System.o \ - lzham_lzbase.o \ - lzham_lzcomp.o \ - lzham_lzcomp_internal.o \ - lzham_lzcomp_state.o \ - lzham_match_accel.o \ - lzham_pthreads_threading.o \ - lzham_assert.o \ - lzham_checksum.o \ - lzham_huffman_codes.o \ - lzham_lzdecomp.o \ - lzham_lzdecompbase.o \ - lzham_mem.o \ - lzham_platform.o \ - lzham_prefix_coding.o \ - lzham_symbol_codec.o \ - lzham_timer.o \ - lzham_vector.o \ - lzham_lib.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Decoder.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.cpp 2023-03-28 11:00:00.000000000 +0000 @@ -1,266 +1,267 @@ -// Lzma2Decoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/StreamUtils.h" - -#include "Lzma2Decoder.h" - -static HRESULT SResToHRESULT(SRes res) -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - // case SZ_ERROR_PROGRESS: return E_ABORT; - case SZ_ERROR_DATA: return S_FALSE; - } - return E_FAIL; -} - -namespace NCompress { -namespace NLzma2 { - -CDecoder::CDecoder(): - _inBuf(NULL), - _inBufSize(0), - _inBufSizeNew(1 << 20), - _outStepSize(1 << 22), - _outSizeDefined(false), - _finishMode(false) -{ - Lzma2Dec_Construct(&_state); -} - -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSizeNew = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outStepSize = size; return S_OK; } - -CDecoder::~CDecoder() -{ - Lzma2Dec_Free(&_state, &g_Alloc); - MidFree(_inBuf); -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) -{ - if (size != 1) - return E_NOTIMPL; - - RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc))); - if (!_inBuf || _inBufSize != _inBufSizeNew) - { - MidFree(_inBuf); - _inBufSize = 0; - _inBuf = (Byte *)MidAlloc(_inBufSizeNew); - if (!_inBuf) - return E_OUTOFMEMORY; - _inBufSize = _inBufSizeNew; - } - - return S_OK; -} - -STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; } -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } - -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) -{ - _outSizeDefined = (outSize != NULL); - _outSize = 0; - if (_outSizeDefined) - _outSize = *outSize; - - Lzma2Dec_Init(&_state); - - _inPos = _inSize = 0; - _inSizeProcessed = _outSizeProcessed = 0; - return S_OK; -} - -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) -{ - _finishMode = (finishMode != 0); - return S_OK; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, - const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (!_inBuf) - return S_FALSE; - SetOutStreamSize(outSize); - - UInt32 step = _outStepSize; - const UInt32 kOutStepSize_Min = 1 << 12; - if (step < kOutStepSize_Min) - step = kOutStepSize_Min; - - SizeT wrPos = _state.decoder.dicPos; - - SizeT next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; - - HRESULT hres = S_OK; - - for (;;) - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - hres = inStream->Read(_inBuf, _inBufSize, &_inSize); - if (hres != S_OK) - break; - } - - SizeT dicPos = _state.decoder.dicPos; - SizeT curSize = next - dicPos; - - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (curSize >= rem) - { - curSize = (SizeT)rem; - if (_finishMode) - finishMode = LZMA_FINISH_END; - } - } - - SizeT inSizeProcessed = _inSize - _inPos; - ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); - - _inPos += (UInt32)inSizeProcessed; - _inSizeProcessed += inSizeProcessed; - SizeT outSizeProcessed = _state.decoder.dicPos - dicPos; - _outSizeProcessed += outSizeProcessed; - - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0 - || status == LZMA_STATUS_FINISHED_WITH_MARK); - bool outFinished = (_outSizeDefined && _outSizeProcessed >= _outSize); - - if (res != 0 - || _state.decoder.dicPos >= next - || finished - || outFinished) - { - HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); - - if (_state.decoder.dicPos == _state.decoder.dicBufSize) - _state.decoder.dicPos = 0; - - wrPos = _state.decoder.dicPos; - - next = (_state.decoder.dicBufSize - _state.decoder.dicPos < step) ? - _state.decoder.dicBufSize : - _state.decoder.dicPos + step; - - if (res != 0) - return S_FALSE; - RINOK(res2); - - if (finished) - { - if (status == LZMA_STATUS_FINISHED_WITH_MARK) - { - if (_finishMode && inSize && *inSize != _inSizeProcessed) - return S_FALSE; - if (finishMode == LZMA_FINISH_END && !outFinished) - return S_FALSE; - return S_OK; - } - return (finishMode == LZMA_FINISH_END) ? S_FALSE : S_OK; - } - - if (outFinished && finishMode == LZMA_FINISH_ANY) - return S_OK; - } - - if (progress) - { - RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed)); - } - } - - HRESULT res2 = WriteStream(outStream, _state.decoder.dic + wrPos, _state.decoder.dicPos - wrPos); - if (hres != S_OK) - return hres; - return res2; -} - -#ifndef NO_READ_FROM_CODER - -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 totalProcessed = 0; - - if (processedSize) - *processedSize = 0; - - for (;;) - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSize, &_inSize)); - } - { - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem <= size) - { - size = (UInt32)rem; - if (_finishMode) - finishMode = LZMA_FINISH_END; - } - } - - SizeT outProcessed = size; - SizeT inProcessed = _inSize - _inPos; - - ELzmaStatus status; - SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, finishMode, &status); - - _inPos += (UInt32)inProcessed; - _inSizeProcessed += inProcessed; - _outSizeProcessed += outProcessed; - size -= (UInt32)outProcessed; - data = (Byte *)data + outProcessed; - - totalProcessed += (UInt32)outProcessed; - if (processedSize) - *processedSize = totalProcessed; - - if (res != SZ_OK) - { - if (totalProcessed != 0) - return S_OK; - return SResToHRESULT(res); - } - - if (inProcessed == 0 && outProcessed == 0) - return S_OK; - if (status == LZMA_STATUS_FINISHED_WITH_MARK) - return S_OK; - if (outProcessed != 0) - { - if (finishMode != LZMA_FINISH_END || _outSize != _outSizeProcessed) - return S_OK; - } - } - } -} - -#endif - -}} +// Lzma2Decoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" +// #include "../../../C/CpuTicks.h" + +#include "../Common/StreamUtils.h" + +#include "Lzma2Decoder.h" + +namespace NCompress { +namespace NLzma2 { + +CDecoder::CDecoder(): + _dec(NULL) + , _inProcessed(0) + , _prop(0xFF) + , _finishMode(false) + , _inBufSize(1 << 20) + , _outStep(1 << 20) + #ifndef Z7_ST + , _tryMt(1) + , _numThreads(1) + , _memUsage((UInt64)(sizeof(size_t)) << 28) + #endif +{} + +CDecoder::~CDecoder() +{ + if (_dec) + Lzma2DecMt_Destroy(_dec); +} + +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) { _outStep = size; return S_OK; } + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) +{ + if (size != 1) + return E_NOTIMPL; + if (prop[0] > 40) + return E_NOTIMPL; + _prop = prop[0]; + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + _finishMode = (finishMode != 0); + return S_OK; +} + + + +#ifndef Z7_ST + +static UInt64 Get_ExpectedBlockSize_From_Dict(UInt32 dictSize) +{ + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + return blockSize; +} + +#define LZMA2_DIC_SIZE_FROM_PROP_FULL(p) ((p) == 40 ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))) + +#endif + +#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes; + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + _inProcessed = 0; + + if (!_dec) + { + _dec = Lzma2DecMt_Create( + // &g_AlignedAlloc, + &g_Alloc, + &g_MidAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } + + CLzma2DecMtProps props; + Lzma2DecMtProps_Init(&props); + + props.inBufSize_ST = _inBufSize; + props.outStep_ST = _outStep; + + #ifndef Z7_ST + { + props.numThreads = 1; + UInt32 numThreads = _numThreads; + + if (_tryMt && numThreads >= 1) + { + const UInt64 useLimit = _memUsage; + const UInt32 dictSize = LZMA2_DIC_SIZE_FROM_PROP_FULL(_prop); + const UInt64 expectedBlockSize64 = Get_ExpectedBlockSize_From_Dict(dictSize); + const size_t expectedBlockSize = (size_t)expectedBlockSize64; + const size_t inBlockMax = expectedBlockSize + expectedBlockSize / 16; + if (expectedBlockSize == expectedBlockSize64 && inBlockMax >= expectedBlockSize) + { + props.outBlockMax = expectedBlockSize; + props.inBlockMax = inBlockMax; + const size_t kOverheadSize = props.inBufSize_MT + (1 << 16); + const UInt64 okThreads = useLimit / (props.outBlockMax + props.inBlockMax + kOverheadSize); + if (numThreads > okThreads) + numThreads = (UInt32)okThreads; + if (numThreads == 0) + numThreads = 1; + props.numThreads = numThreads; + } + } + } + #endif + + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res; + + UInt64 inProcessed = 0; + int isMT = False; + + #ifndef Z7_ST + isMT = _tryMt; + #endif + + // UInt64 cpuTicks = GetCpuTicks(); + + res = Lzma2DecMt_Decode(_dec, _prop, &props, + &outWrap.vt, outSize, _finishMode, + &inWrap.vt, + &inProcessed, + &isMT, + progress ? &progressWrap.vt : NULL); + + /* + cpuTicks = GetCpuTicks() - cpuTicks; + printf("\n ticks = %10I64u\n", cpuTicks / 1000000); + */ + + + #ifndef Z7_ST + /* we reset _tryMt, only if p->props.numThreads was changed */ + if (props.numThreads > 1) + _tryMt = isMT; + #endif + + _inProcessed = inProcessed; + + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ) + + if (res == SZ_OK && _finishMode) + { + if (inSize && *inSize != inProcessed) + res = SZ_ERROR_DATA; + if (outSize && *outSize != outWrap.Processed) + res = SZ_ERROR_DATA; + } + + return SResToHRESULT(res); +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + +#ifndef Z7_ST + +Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads)) +{ + _numThreads = numThreads; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetMemLimit(UInt64 memUsage)) +{ + _memUsage = memUsage; + return S_OK; +} + +#endif + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + CLzma2DecMtProps props; + Lzma2DecMtProps_Init(&props); + props.inBufSize_ST = _inBufSize; + props.outStep_ST = _outStep; + + _inProcessed = 0; + + if (!_dec) + { + _dec = Lzma2DecMt_Create(&g_AlignedAlloc, &g_MidAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } + + _inWrap.Init(_inStream); + + const SRes res = Lzma2DecMt_Init(_dec, _prop, &props, outSize, _finishMode, &_inWrap.vt); + + if (res != SZ_OK) + return SResToHRESULT(res); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + size_t size2 = size; + UInt64 inProcessed = 0; + + const SRes res = Lzma2DecMt_Read(_dec, (Byte *)data, &size2, &inProcessed); + + _inProcessed += inProcessed; + if (processedSize) + *processedSize = (UInt32)size2; + if (res != SZ_OK) + return SResToHRESULT(res); + return S_OK; +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Decoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Decoder.h 2023-02-01 10:00:00.000000000 +0000 @@ -1,88 +1,87 @@ -// Lzma2Decoder.h - -#ifndef __LZMA2_DECODER_H -#define __LZMA2_DECODER_H - -#include "../../../C/Lzma2Dec.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NLzma2 { - -class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public ICompressSetFinishMode, - public ICompressGetInStreamProcessedSize, - public ICompressSetBufSize, - #ifndef NO_READ_FROM_CODER - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public ISequentialInStream, - #endif - public CMyUnknownImp -{ - CMyComPtr _inStream; - Byte *_inBuf; - UInt32 _inPos; - UInt32 _inSize; - - bool _finishMode; - bool _outSizeDefined; - UInt64 _outSize; - - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - - UInt32 _inBufSize; - UInt32 _inBufSizeNew; - UInt32 _outStepSize; - - CLzma2Dec _state; -public: - - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - - STDMETHOD(SetFinishMode)(UInt32 finishMode); - - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); - - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif - - CDecoder(); - virtual ~CDecoder(); - -}; - -}} - -#endif +// Lzma2Decoder.h + +#ifndef ZIP7_INC_LZMA2_DECODER_H +#define ZIP7_INC_LZMA2_DECODER_H + +#include "../../../C/Lzma2DecMt.h" + +#include "../Common/CWrappers.h" + +namespace NCompress { +namespace NLzma2 { + +class CDecoder Z7_final: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressSetBufSize, + #ifndef Z7_NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + #ifndef Z7_ST + public ICompressSetCoderMt, + public ICompressSetMemLimit, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #endif + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + + CLzma2DecMtHandle _dec; + UInt64 _inProcessed; + Byte _prop; + int _finishMode; + UInt32 _inBufSize; + UInt32 _outStep; + + #ifndef Z7_ST + int _tryMt; + UInt32 _numThreads; + UInt64 _memUsage; + #endif + + #ifndef Z7_NO_READ_FROM_CODER + CMyComPtr _inStream; + CSeqInStreamWrap _inWrap; + #endif + +public: + CDecoder(); + ~CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Encoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Encoder.cpp 2015-10-17 14:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.cpp 2025-06-28 12:00:00.000000000 +0000 @@ -1,99 +1,134 @@ -// Lzma2Encoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/CWrappers.h" -#include "../Common/StreamUtils.h" - -#include "Lzma2Encoder.h" - -namespace NCompress { - -namespace NLzma { - -HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); - -} - -namespace NLzma2 { - -CEncoder::CEncoder() -{ - _encoder = 0; - _encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc); - if (_encoder == 0) - throw 1; -} - -CEncoder::~CEncoder() -{ - if (_encoder != 0) - Lzma2Enc_Destroy(_encoder); -} - -HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) -{ - switch (propID) - { - case NCoderPropID::kBlockSize: - { - if (prop.vt == VT_UI4) - lzma2Props.blockSize = prop.ulVal; - else if (prop.vt == VT_UI8) - { - size_t v = (size_t)prop.uhVal.QuadPart; - if (v != prop.uhVal.QuadPart) - return E_INVALIDARG; - lzma2Props.blockSize = v; - } - else - return E_INVALIDARG; - break; - } - case NCoderPropID::kNumThreads: - if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break; - default: - RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)); - } - return S_OK; -} - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) -{ - CLzma2EncProps lzma2Props; - Lzma2EncProps_Init(&lzma2Props); - - for (UInt32 i = 0; i < numProps; i++) - { - RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)); - } - return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); -} - -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) -{ - Byte prop = Lzma2Enc_WriteProperties(_encoder); - return WriteStream(outStream, &prop, 1); -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - CSeqInStreamWrap inWrap(inStream); - CSeqOutStreamWrap outWrap(outStream); - CCompressProgressWrap progressWrap(progress); - - SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL); - if (res == SZ_ERROR_READ && inWrap.Res != S_OK) - return inWrap.Res; - if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) - return outWrap.Res; - if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) - return progressWrap.Res; - return SResToHRESULT(res); -} - -}} +// Lzma2Encoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "Lzma2Encoder.h" + +namespace NCompress { + +namespace NLzma { + +HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); + +} + +namespace NLzma2 { + +CEncoder::CEncoder() +{ + _encoder = NULL; + _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc); + if (!_encoder) + throw 1; +} + +CEncoder::~CEncoder() +{ + if (_encoder) + Lzma2Enc_Destroy(_encoder); +} + + +HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); +HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props) +{ + switch (propID) + { + case NCoderPropID::kBlockSize: + { + if (prop.vt == VT_UI4) + lzma2Props.blockSize = prop.ulVal; + else if (prop.vt == VT_UI8) + lzma2Props.blockSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + break; + } + case NCoderPropID::kNumThreads: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + lzma2Props.numTotalThreads = (int)prop.ulVal; + break; + case NCoderPropID::kNumThreadGroups: + if (prop.vt != VT_UI4) + return E_INVALIDARG; + // 16-bit value supported by Windows + if (prop.ulVal >= (1u << 16)) + return E_INVALIDARG; + lzma2Props.numThreadGroups = (unsigned)prop.ulVal; + break; + default: + RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps)) + } + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + CLzma2EncProps lzma2Props; + Lzma2EncProps_Init(&lzma2Props); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props)) + } + return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props)); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + const Byte prop = Lzma2Enc_WriteProperties(_encoder); + return WriteStream(outStream, &prop, 1); +} + + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = Lzma2Enc_Encode2(_encoder, + &outWrap.vt, NULL, NULL, + &inWrap.vt, NULL, 0, + progress ? &progressWrap.vt : NULL); + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + + return SResToHRESULT(res); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Encoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Encoder.h 2016-05-18 17:31:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Encoder.h 2023-03-28 11:00:00.000000000 +0000 @@ -1,36 +1,30 @@ -// Lzma2Encoder.h - -#ifndef __LZMA2_ENCODER_H -#define __LZMA2_ENCODER_H - -#include "../../../C/Lzma2Enc.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NLzma2 { - -class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ - CLzma2EncHandle _encoder; -public: - MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - - CEncoder(); - virtual ~CEncoder(); -}; - -}} - -#endif +// Lzma2Encoder.h + +#ifndef ZIP7_INC_LZMA2_ENCODER_H +#define ZIP7_INC_LZMA2_ENCODER_H + +#include "../../../C/Lzma2Enc.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NLzma2 { + +Z7_CLASS_IMP_COM_4( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties + , ICompressSetCoderPropertiesOpt +) + CLzma2EncHandle _encoder; +public: + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Register.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Register.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Lzma2Register.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzma2Register.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,22 +1,22 @@ -// Lzma2Register.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "Lzma2Decoder.h" - -#ifndef EXTRACT_ONLY -#include "Lzma2Encoder.h" -#endif - -namespace NCompress { -namespace NLzma2 { - -REGISTER_CODEC_E(LZMA2, - CDecoder(), - CEncoder(), - 0x21, - "LZMA2") - -}} +// Lzma2Register.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "Lzma2Decoder.h" + +#ifndef Z7_EXTRACT_ONLY +#include "Lzma2Encoder.h" +#endif + +namespace NCompress { +namespace NLzma2 { + +REGISTER_CODEC_E(LZMA2, + CDecoder(), + CEncoder(), + 0x21, + "LZMA2") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmaDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzmaDecoder.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,268 +1,350 @@ -// LzmaDecoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/StreamUtils.h" - -#include "LzmaDecoder.h" - -static HRESULT SResToHRESULT(SRes res) -{ - switch (res) - { - case SZ_OK: return S_OK; - case SZ_ERROR_MEM: return E_OUTOFMEMORY; - case SZ_ERROR_PARAM: return E_INVALIDARG; - case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; - case SZ_ERROR_DATA: return S_FALSE; - } - return E_FAIL; -} - -namespace NCompress { -namespace NLzma { - -CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), - _inBufSize(1 << 20), - _outBufSize(1 << 22), - FinishStream(false), - NeedMoreInput(false) -{ - _inSizeProcessed = 0; - _inPos = _inSize = 0; - LzmaDec_Construct(&_state); -} - -CDecoder::~CDecoder() -{ - LzmaDec_Free(&_state, &g_Alloc); - MyFree(_inBuf); -} - -STDMETHODIMP CDecoder::SetInBufSize(UInt32 , UInt32 size) { _inBufSize = size; return S_OK; } -STDMETHODIMP CDecoder::SetOutBufSize(UInt32 , UInt32 size) { _outBufSize = size; return S_OK; } - -HRESULT CDecoder::CreateInputBuffer() -{ - if (_inBuf == 0 || _inBufSize != _inBufSizeAllocated) - { - MyFree(_inBuf); - _inBuf = (Byte *)MyAlloc(_inBufSize); - if (_inBuf == 0) - return E_OUTOFMEMORY; - _inBufSizeAllocated = _inBufSize; - } - return S_OK; -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size) -{ - RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc))); - _propsWereSet = true; - return CreateInputBuffer(); -} - -void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize) -{ - _outSizeDefined = (outSize != NULL); - if (_outSizeDefined) - _outSize = *outSize; - _outSizeProcessed = 0; - _wrPos = 0; - LzmaDec_Init(&_state); -} - -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) -{ - _inSizeProcessed = 0; - _inPos = _inSize = 0; - NeedMoreInput = false; - SetOutStreamSizeResume(outSize); - return S_OK; -} - -STDMETHODIMP CDecoder::SetFinishMode(UInt32 finishMode) -{ - FinishStream = (finishMode != 0); - return S_OK; -} - -HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - if (_inBuf == 0 || !_propsWereSet) - return S_FALSE; - - UInt64 startInProgress = _inSizeProcessed; - - SizeT next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); - for (;;) - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - } - - SizeT dicPos = _state.dicPos; - SizeT curSize = next - dicPos; - - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem <= curSize) - { - curSize = (SizeT)rem; - if (FinishStream) - finishMode = LZMA_FINISH_END; - } - } - - SizeT inSizeProcessed = _inSize - _inPos; - ELzmaStatus status; - SRes res = LzmaDec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status); - - _inPos += (UInt32)inSizeProcessed; - _inSizeProcessed += inSizeProcessed; - SizeT outSizeProcessed = _state.dicPos - dicPos; - _outSizeProcessed += outSizeProcessed; - - bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0); - bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize); - - if (res != 0 || _state.dicPos == next || finished || stopDecoding) - { - HRESULT res2 = WriteStream(outStream, _state.dic + _wrPos, _state.dicPos - _wrPos); - - _wrPos = _state.dicPos; - if (_state.dicPos == _state.dicBufSize) - { - _state.dicPos = 0; - _wrPos = 0; - } - next = (_state.dicBufSize - _state.dicPos < _outBufSize) ? _state.dicBufSize : (_state.dicPos + _outBufSize); - - if (res != 0) - return S_FALSE; - RINOK(res2); - if (stopDecoding) - { - if (status == LZMA_STATUS_NEEDS_MORE_INPUT) - NeedMoreInput = true; - if (FinishStream && - status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - return S_FALSE; - return S_OK; - } - if (finished) - { - if (status == LZMA_STATUS_NEEDS_MORE_INPUT) - NeedMoreInput = true; - return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE); - } - } - if (progress) - { - UInt64 inSize = _inSizeProcessed - startInProgress; - RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed)); - } - } -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (_inBuf == 0) - return E_INVALIDARG; - SetOutStreamSize(outSize); - return CodeSpec(inStream, outStream, progress); -} - -#ifndef NO_READ_FROM_CODER - -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; } -STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; } - -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - do - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - } - { - SizeT inProcessed = _inSize - _inPos; - - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _outSizeProcessed; - if (rem < size) - size = (UInt32)rem; - } - - SizeT outProcessed = size; - ELzmaStatus status; - SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, - _inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status); - _inPos += (UInt32)inProcessed; - _inSizeProcessed += inProcessed; - _outSizeProcessed += outProcessed; - size -= (UInt32)outProcessed; - data = (Byte *)data + outProcessed; - if (processedSize) - *processedSize += (UInt32)outProcessed; - RINOK(SResToHRESULT(res)); - if (inProcessed == 0 && outProcessed == 0) - return S_OK; - } - } - while (size != 0); - return S_OK; -} - -HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - SetOutStreamSizeResume(outSize); - return CodeSpec(_inStream, outStream, progress); -} - -HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize) -{ - RINOK(CreateInputBuffer()); - if (processedSize) - *processedSize = 0; - while (size > 0) - { - if (_inPos == _inSize) - { - _inPos = _inSize = 0; - RINOK(_inStream->Read(_inBuf, _inBufSizeAllocated, &_inSize)); - if (_inSize == 0) - break; - } - { - UInt32 curSize = _inSize - _inPos; - if (curSize > size) - curSize = size; - memcpy(data, _inBuf + _inPos, curSize); - _inPos += curSize; - _inSizeProcessed += curSize; - size -= curSize; - data = (Byte *)data + curSize; - if (processedSize) - *processedSize += curSize; - } - } - return S_OK; -} - -#endif - -}} +// LzmaDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/StreamUtils.h" + +#include "LzmaDecoder.h" + +static HRESULT SResToHRESULT(SRes res) +{ + switch (res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_PARAM: return E_INVALIDARG; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + case SZ_ERROR_DATA: return S_FALSE; + default: break; + } + return E_FAIL; +} + +namespace NCompress { +namespace NLzma { + +CDecoder::CDecoder(): + FinishStream(false), + _propsWereSet(false), + _outSizeDefined(false), + _outStep(1 << 20), + _inBufSize(0), + _inBufSizeNew(1 << 20), + _lzmaStatus(LZMA_STATUS_NOT_SPECIFIED), + _inBuf(NULL) +{ + _inProcessed = 0; + _inPos = _inLim = 0; + + /* + AlignOffsetAlloc_CreateVTable(&_alloc); + _alloc.numAlignBits = 7; + _alloc.offset = 0; + */ + LzmaDec_CONSTRUCT(&_state) +} + +CDecoder::~CDecoder() +{ + LzmaDec_Free(&_state, &g_AlignedAlloc); // &_alloc.vt + MyFree(_inBuf); +} + +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) + { _inBufSizeNew = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) + { _outStep = size; return S_OK; } + +HRESULT CDecoder::CreateInputBuffer() +{ + if (!_inBuf || _inBufSizeNew != _inBufSize) + { + MyFree(_inBuf); + _inBufSize = 0; + _inBuf = (Byte *)MyAlloc(_inBufSizeNew); + if (!_inBuf) + return E_OUTOFMEMORY; + _inBufSize = _inBufSizeNew; + } + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)) +{ + RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_AlignedAlloc))) // &_alloc.vt + _propsWereSet = true; + return CreateInputBuffer(); +} + + +void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize) +{ + _outSizeDefined = (outSize != NULL); + _outSize = 0; + if (_outSizeDefined) + _outSize = *outSize; + _outProcessed = 0; + _lzmaStatus = LZMA_STATUS_NOT_SPECIFIED; + + LzmaDec_Init(&_state); +} + + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + _inProcessed = 0; + _inPos = _inLim = 0; + SetOutStreamSizeResume(outSize); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishStream = (finishMode != 0); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + +HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress) +{ + if (!_inBuf || !_propsWereSet) + return S_FALSE; + + const UInt64 startInProgress = _inProcessed; + SizeT wrPos = _state.dicPos; + HRESULT readRes = S_OK; + + for (;;) + { + if (_inPos == _inLim && readRes == S_OK) + { + _inPos = _inLim = 0; + readRes = inStream->Read(_inBuf, _inBufSize, &_inLim); + } + + const SizeT dicPos = _state.dicPos; + SizeT size; + { + SizeT next = _state.dicBufSize; + if (next - wrPos > _outStep) + next = wrPos + _outStep; + size = next - dicPos; + } + + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) + { + size = (SizeT)rem; + if (FinishStream) + finishMode = LZMA_FINISH_END; + } + } + + SizeT inProcessed = _inLim - _inPos; + ELzmaStatus status; + + const SRes res = LzmaDec_DecodeToDic(&_state, dicPos + size, _inBuf + _inPos, &inProcessed, finishMode, &status); + + _lzmaStatus = status; + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + const SizeT outProcessed = _state.dicPos - dicPos; + _outProcessed += outProcessed; + + // we check for LZMA_STATUS_NEEDS_MORE_INPUT to allow RangeCoder initialization, if (_outSizeDefined && _outSize == 0) + const bool outFinished = (_outSizeDefined && _outProcessed >= _outSize); + + const bool needStop = (res != 0 + || (inProcessed == 0 && outProcessed == 0) + || status == LZMA_STATUS_FINISHED_WITH_MARK + || (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT)); + + if (needStop || outProcessed >= size) + { + const HRESULT res2 = WriteStream(outStream, _state.dic + wrPos, _state.dicPos - wrPos); + + if (_state.dicPos == _state.dicBufSize) + _state.dicPos = 0; + wrPos = _state.dicPos; + + RINOK(res2) + + if (needStop) + { + if (res != 0) + { + // return SResToHRESULT(res); + return S_FALSE; + } + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (FinishStream) + if (_outSizeDefined && _outSize != _outProcessed) + return S_FALSE; + return readRes; + } + + if (outFinished && status != LZMA_STATUS_NEEDS_MORE_INPUT) + if (!FinishStream || status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return readRes; + + return S_FALSE; + } + } + + if (progress) + { + const UInt64 inSize = _inProcessed - startInProgress; + RINOK(progress->SetRatioInfo(&inSize, &_outProcessed)) + } + } +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + if (!_inBuf) + return E_INVALIDARG; + SetOutStreamSize(outSize); + HRESULT res = CodeSpec(inStream, outStream, progress); + if (res == S_OK) + if (FinishStream && inSize && *inSize != _inProcessed) + res = S_FALSE; + return res; +} + + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outProcessed; + if (size >= rem) + { + size = (UInt32)rem; + if (FinishStream) + finishMode = LZMA_FINISH_END; + } + } + + HRESULT readRes = S_OK; + + for (;;) + { + if (_inPos == _inLim && readRes == S_OK) + { + _inPos = _inLim = 0; + readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); + } + + SizeT inProcessed = _inLim - _inPos; + SizeT outProcessed = size; + ELzmaStatus status; + + const SRes res = LzmaDec_DecodeToBuf(&_state, (Byte *)data, &outProcessed, + _inBuf + _inPos, &inProcessed, finishMode, &status); + + _lzmaStatus = status; + _inPos += (UInt32)inProcessed; + _inProcessed += inProcessed; + _outProcessed += outProcessed; + size -= (UInt32)outProcessed; + data = (Byte *)data + outProcessed; + if (processedSize) + *processedSize += (UInt32)outProcessed; + + if (res != 0) + return S_FALSE; + + /* + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return readRes; + + if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (FinishStream + && _outSizeDefined && _outProcessed >= _outSize + && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + return S_FALSE; + return readRes; + } + */ + + if (inProcessed == 0 && outProcessed == 0) + return readRes; + } +} + + +HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + SetOutStreamSizeResume(outSize); + return CodeSpec(_inStream, outStream, progress); +} + + +HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize) +{ + RINOK(CreateInputBuffer()) + + if (processedSize) + *processedSize = 0; + + HRESULT readRes = S_OK; + + while (size != 0) + { + if (_inPos == _inLim) + { + _inPos = _inLim = 0; + if (readRes == S_OK) + readRes = _inStream->Read(_inBuf, _inBufSize, &_inLim); + if (_inLim == 0) + break; + } + + UInt32 cur = _inLim - _inPos; + if (cur > size) + cur = size; + memcpy(data, _inBuf + _inPos, cur); + _inPos += cur; + _inProcessed += cur; + size -= cur; + data = (Byte *)data + cur; + if (processedSize) + *processedSize += cur; + } + + return readRes; +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmaDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzmaDecoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaDecoder.h 2023-03-28 12:00:00.000000000 +0000 @@ -1,91 +1,113 @@ -// LzmaDecoder.h - -#ifndef __LZMA_DECODER_H -#define __LZMA_DECODER_H - -#include "../../../C/LzmaDec.h" - -#include "../../Common/MyCom.h" -#include "../ICoder.h" - -namespace NCompress { -namespace NLzma { - -class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public ICompressSetFinishMode, - public ICompressSetBufSize, - #ifndef NO_READ_FROM_CODER - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public ISequentialInStream, - #endif - public CMyUnknownImp -{ - CMyComPtr _inStream; - Byte *_inBuf; - UInt32 _inPos; - UInt32 _inSize; - CLzmaDec _state; - bool _propsWereSet; - bool _outSizeDefined; - UInt64 _outSize; - UInt64 _inSizeProcessed; - UInt64 _outSizeProcessed; - - UInt32 _inBufSizeAllocated; - UInt32 _inBufSize; - UInt32 _outBufSize; - SizeT _wrPos; - - HRESULT CreateInputBuffer(); - HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); - void SetOutStreamSizeResume(const UInt64 *outSize); - -public: - MY_QUERYINTERFACE_BEGIN2(ICompressCoder) - MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2) - MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode) - MY_QUERYINTERFACE_ENTRY(ICompressSetBufSize) - #ifndef NO_READ_FROM_CODER - MY_QUERYINTERFACE_ENTRY(ICompressSetInStream) - MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize) - MY_QUERYINTERFACE_ENTRY(ISequentialInStream) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetFinishMode)(UInt32 finishMode); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size); - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size); - - #ifndef NO_READ_FROM_CODER - - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); - HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize); - UInt64 GetInputProcessedSize() const { return _inSizeProcessed; } - - #endif - - bool FinishStream; // set it before decoding, if you need to decode full LZMA stream - - bool NeedMoreInput; // it's set by decoder, if it needs more input data to decode stream - - CDecoder(); - virtual ~CDecoder(); - - UInt64 GetOutputProcessedSize() const { return _outSizeProcessed; } -}; - -}} - -#endif +// LzmaDecoder.h + +#ifndef ZIP7_INC_LZMA_DECODER_H +#define ZIP7_INC_LZMA_DECODER_H + +// #include "../../../C/Alloc.h" +#include "../../../C/LzmaDec.h" + +#include "../../Common/MyCom.h" +#include "../ICoder.h" + +namespace NCompress { +namespace NLzma { + +class CDecoder Z7_final: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressSetBufSize, + #ifndef Z7_NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) +public: + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +private: + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + // Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + + #ifndef Z7_NO_READ_FROM_CODER +public: + Z7_IFACE_COM7_IMP(ICompressSetInStream) +private: + Z7_IFACE_COM7_IMP(ISequentialInStream) + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif + +public: + bool FinishStream; // set it before decoding, if you need to decode full LZMA stream +private: + bool _propsWereSet; + bool _outSizeDefined; + + UInt32 _outStep; + UInt32 _inBufSize; + UInt32 _inBufSizeNew; + + ELzmaStatus _lzmaStatus; + UInt32 _inPos; + UInt32 _inLim; + Byte *_inBuf; + + UInt64 _outSize; + UInt64 _inProcessed; + UInt64 _outProcessed; + + // CAlignOffsetAlloc _alloc; + + CLzmaDec _state; + + HRESULT CreateInputBuffer(); + HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress); + void SetOutStreamSizeResume(const UInt64 *outSize); + + #ifndef Z7_NO_READ_FROM_CODER +private: + CMyComPtr _inStream; +public: + HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); + HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize); + #endif + +public: + CDecoder(); + ~CDecoder(); + + UInt64 GetInputProcessedSize() const { return _inProcessed; } + UInt64 GetOutputProcessedSize() const { return _outProcessed; } + bool NeedsMoreInput() const { return _lzmaStatus == LZMA_STATUS_NEEDS_MORE_INPUT; } + bool CheckFinishStatus(bool withEndMark) const + { + return _lzmaStatus == (withEndMark ? + LZMA_STATUS_FINISHED_WITH_MARK : + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmaEncoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzmaEncoder.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.cpp 2024-12-19 08:00:00.000000000 +0000 @@ -1,152 +1,374 @@ -// LzmaEncoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/CWrappers.h" -#include "../Common/StreamUtils.h" - -#include "LzmaEncoder.h" - -namespace NCompress { -namespace NLzma { - -CEncoder::CEncoder() -{ - _encoder = NULL; - _encoder = LzmaEnc_Create(&g_Alloc); - if (!_encoder) - throw 1; -} - -CEncoder::~CEncoder() -{ - if (_encoder) - LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); -} - -static inline wchar_t GetUpperChar(wchar_t c) -{ - if (c >= 'a' && c <= 'z') - c -= 0x20; - return c; -} - -static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) -{ - wchar_t c = GetUpperChar(*s++); - if (c == L'H') - { - if (GetUpperChar(*s++) != L'C') - return 0; - int numHashBytesLoc = (int)(*s++ - L'0'); - if (numHashBytesLoc < 4 || numHashBytesLoc > 4) - return 0; - if (*s != 0) - return 0; - *btMode = 0; - *numHashBytes = numHashBytesLoc; - return 1; - } - - if (c != L'B') - return 0; - if (GetUpperChar(*s++) != L'T') - return 0; - int numHashBytesLoc = (int)(*s++ - L'0'); - if (numHashBytesLoc < 2 || numHashBytesLoc > 4) - return 0; - if (*s != 0) - return 0; - *btMode = 1; - *numHashBytes = numHashBytesLoc; - return 1; -} - -#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break; - -HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) -{ - if (propID == NCoderPropID::kMatchFinder) - { - if (prop.vt != VT_BSTR) - return E_INVALIDARG; - return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG; - } - if (propID > NCoderPropID::kReduceSize) - return S_OK; - if (propID == NCoderPropID::kReduceSize) - { - if (prop.vt == VT_UI8) - ep.reduceSize = prop.uhVal.QuadPart; - return S_OK; - } - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = prop.ulVal; - switch (propID) - { - case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break; - SET_PROP_32(kLevel, level) - SET_PROP_32(kNumFastBytes, fb) - SET_PROP_32(kMatchFinderCycles, mc) - SET_PROP_32(kAlgorithm, algo) - SET_PROP_32(kDictionarySize, dictSize) - SET_PROP_32(kPosStateBits, pb) - SET_PROP_32(kLitPosBits, lp) - SET_PROP_32(kLitContextBits, lc) - SET_PROP_32(kNumThreads, numThreads) - default: return E_INVALIDARG; - } - return S_OK; -} - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, - const PROPVARIANT *coderProps, UInt32 numProps) -{ - CLzmaEncProps props; - LzmaEncProps_Init(&props); - - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - switch (propID) - { - case NCoderPropID::kEndMarker: - if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break; - default: - RINOK(SetLzmaProp(propID, prop, props)); - } - } - return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props)); -} - -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) -{ - Byte props[LZMA_PROPS_SIZE]; - size_t size = LZMA_PROPS_SIZE; - RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)); - return WriteStream(outStream, props, size); -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - CSeqInStreamWrap inWrap(inStream); - CSeqOutStreamWrap outWrap(outStream); - CCompressProgressWrap progressWrap(progress); - - SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc); - _inputProcessed = inWrap.Processed; - if (res == SZ_ERROR_READ && inWrap.Res != S_OK) - return inWrap.Res; - if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) - return outWrap.Res; - if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) - return progressWrap.Res; - return SResToHRESULT(res); -} - -}} +// LzmaEncoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "LzmaEncoder.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 + +#endif + +namespace NCompress { +namespace NLzma { + +CEncoder::CEncoder() +{ + _encoder = NULL; + _encoder = LzmaEnc_Create(&g_AlignedAlloc); + if (!_encoder) + throw 1; +} + +CEncoder::~CEncoder() +{ + if (_encoder) + LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc); +} + +static inline wchar_t GetLowCharFast(wchar_t c) +{ + return c |= 0x20; +} + +static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) +{ + const wchar_t c = GetLowCharFast(*s++); + if (c == 'h') + { + if (GetLowCharFast(*s++) != 'c') + return 0; + const int num = (int)(*s++ - L'0'); + if (num < 4 || num > 5) + return 0; + if (*s != 0) + return 0; + *btMode = 0; + *numHashBytes = num; + return 1; + } + + if (c != 'b') + return 0; + { + if (GetLowCharFast(*s++) != 't') + return 0; + const int num = (int)(*s++ - L'0'); + if (num < 2 || num > 5) + return 0; + if (*s != 0) + return 0; + *btMode = 1; + *numHashBytes = num; + return 1; + } +} + +#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = (int)v; break; +#define SET_PROP_32U(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break; + +HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep); +HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) +{ + if (propID == NCoderPropID::kMatchFinder) + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG; + } + + if (propID == NCoderPropID::kAffinity) + { + if (prop.vt == VT_UI8) + ep.affinity = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kAffinityInGroup) + { + if (prop.vt == VT_UI8) + ep.affinityInGroup = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kThreadGroup) + { + if (prop.vt == VT_UI4) + ep.affinityGroup = (Int32)(UInt32)prop.ulVal; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kHashBits) + { + if (prop.vt == VT_UI4) + ep.numHashOutBits = prop.ulVal; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID > NCoderPropID::kReduceSize) + return S_OK; + + if (propID == NCoderPropID::kReduceSize) + { + if (prop.vt == VT_UI8) + ep.reduceSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kDictionarySize) + { + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit VT_UI8 for dictionary and (dict == 4 GiB) + const UInt64 v = prop.uhVal.QuadPart; + if (v > ((UInt64)1 << 32)) + return E_INVALIDARG; + UInt32 dict; + if (v == ((UInt64)1 << 32)) + dict = (UInt32)(Int32)-1; + else + dict = (UInt32)v; + ep.dictSize = dict; + return S_OK; + } + } + + if (prop.vt != VT_UI4) + return E_INVALIDARG; + const UInt32 v = prop.ulVal; + switch (propID) + { + case NCoderPropID::kDefaultProp: + if (v > 32) + return E_INVALIDARG; + ep.dictSize = (v == 32) ? (UInt32)(Int32)-1 : (UInt32)1 << (unsigned)v; + break; + SET_PROP_32(kLevel, level) + SET_PROP_32(kNumFastBytes, fb) + SET_PROP_32U(kMatchFinderCycles, mc) + SET_PROP_32(kAlgorithm, algo) + SET_PROP_32U(kDictionarySize, dictSize) + SET_PROP_32(kPosStateBits, pb) + SET_PROP_32(kLitPosBits, lp) + SET_PROP_32(kLitContextBits, lc) + SET_PROP_32(kNumThreads, numThreads) + default: return E_INVALIDARG; + } + return S_OK; +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + CLzmaEncProps props; + LzmaEncProps_Init(&props); + + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + switch (propID) + { + case NCoderPropID::kEndMarker: + if (prop.vt != VT_BOOL) + return E_INVALIDARG; + props.writeEndMark = (prop.boolVal != VARIANT_FALSE); + break; + default: + RINOK(SetLzmaProp(propID, prop, props)) + } + } + return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props)); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + Byte props[LZMA_PROPS_SIZE]; + SizeT size = LZMA_PROPS_SIZE; + RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)) + return WriteStream(outStream, props, size); +} + + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + + + +#ifdef LOG_LZMA_THREADS + +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') +{ + char temp[64]; + char *p = temp + 32; + ConvertUInt64ToString(val, p); + unsigned len = (unsigned)strlen(p); + for (; len < numDigits; len++) + *--p = c; + printf("%s", p); +} + +static void PrintTime(const char *s, UInt64 val, UInt64 total) +{ + printf(" %s :", s); + const UInt32 kFreq = 10000000; + UInt64 sec = val / kFreq; + PrintNum(sec, 6); + printf(" ."); + UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); + PrintNum(ms, 3, '0'); + + while (val > ((UInt64)1 << 56)) + { + val >>= 1; + total >>= 1; + } + + UInt64 percent = 0; + if (total != 0) + percent = val * 100 / total; + printf(" ="); + PrintNum(percent, 4); + printf("%%"); +} + + +struct CBaseStat +{ + UInt64 kernelTime, userTime; + + BOOL Get(HANDLE thread, const CBaseStat *prevStat) + { + FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; + BOOL res = GetThreadTimes(thread + , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT); + if (res) + { + kernelTime = GetTime64(kernelTimeFT); + userTime = GetTime64(userTimeFT); + if (prevStat) + { + kernelTime -= prevStat->kernelTime; + userTime -= prevStat->userTime; + } + } + return res; + } +}; + + +static void PrintStat(HANDLE thread, UInt64 totalTime, const CBaseStat *prevStat) +{ + CBaseStat newStat; + if (!newStat.Get(thread, prevStat)) + return; + + PrintTime("K", newStat.kernelTime, totalTime); + + const UInt64 processTime = newStat.kernelTime + newStat.userTime; + + PrintTime("U", newStat.userTime, totalTime); + PrintTime("S", processTime, totalTime); + printf("\n"); + // PrintTime("G ", totalTime, totalTime); +} + +#endif + + + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + #ifdef LOG_LZMA_THREADS + + FILETIME startTimeFT; + NWindows::NTime::GetCurUtcFileTime(startTimeFT); + UInt64 totalTime = GetTime64(startTimeFT); + CBaseStat oldStat; + if (!oldStat.Get(GetCurrentThread(), NULL)) + return E_FAIL; + + #endif + + + SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, + progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc); + + _inputProcessed = inWrap.Processed; + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + + + #ifdef LOG_LZMA_THREADS + + NWindows::NTime::GetCurUtcFileTime(startTimeFT); + totalTime = GetTime64(startTimeFT) - totalTime; + HANDLE lz_threads[2]; + LzmaEnc_GetLzThreads(_encoder, lz_threads); + printf("\n"); + printf("Main: "); PrintStat(GetCurrentThread(), totalTime, &oldStat); + printf("Hash: "); PrintStat(lz_threads[0], totalTime, NULL); + printf("BinT: "); PrintStat(lz_threads[1], totalTime, NULL); + // PrintTime("Total: ", totalTime, totalTime); + printf("\n"); + + #endif + + return SResToHRESULT(res); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmaEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzmaEncoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaEncoder.h 2023-03-28 13:00:00.000000000 +0000 @@ -1,38 +1,45 @@ -// LzmaEncoder.h - -#ifndef __LZMA_ENCODER_H -#define __LZMA_ENCODER_H - -#include "../../../C/LzmaEnc.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NLzma { - -class CEncoder: - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ - CLzmaEncHandle _encoder; - UInt64 _inputProcessed; -public: - MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - - CEncoder(); - virtual ~CEncoder(); - UInt64 GetInputProcessedSize() const { return _inputProcessed; } -}; - -}} - -#endif +// LzmaEncoder.h + +#ifndef ZIP7_INC_LZMA_ENCODER_H +#define ZIP7_INC_LZMA_ENCODER_H + +#include "../../../C/LzmaEnc.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NLzma { + +class CEncoder Z7_final: + public ICompressCoder, + public ICompressSetCoderProperties, + public ICompressWriteCoderProperties, + public ICompressSetCoderPropertiesOpt, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_4( + ICompressCoder, + ICompressSetCoderProperties, + ICompressWriteCoderProperties, + ICompressSetCoderPropertiesOpt) + Z7_IFACE_COM7_IMP(ICompressCoder) +public: + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + Z7_IFACE_COM7_IMP(ICompressSetCoderPropertiesOpt) + + CLzmaEncHandle _encoder; + UInt64 _inputProcessed; + + CEncoder(); + ~CEncoder(); + + UInt64 GetInputProcessedSize() const { return _inputProcessed; } + bool IsWriteEndMark() const { return LzmaEnc_IsWriteEndMark(_encoder) != 0; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmaRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzmaRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmaRegister.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,22 +1,22 @@ -// LzmaRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "LzmaDecoder.h" - -#ifndef EXTRACT_ONLY -#include "LzmaEncoder.h" -#endif - -namespace NCompress { -namespace NLzma { - -REGISTER_CODEC_E(LZMA, - CDecoder(), - CEncoder(), - 0x30101, - "LZMA") - -}} +// LzmaRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "LzmaDecoder.h" + +#ifndef Z7_EXTRACT_ONLY +#include "LzmaEncoder.h" +#endif + +namespace NCompress { +namespace NLzma { + +REGISTER_CODEC_E(LZMA, + CDecoder(), + CEncoder(), + 0x30101, + "LZMA") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmsDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzmsDecoder.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.cpp 2024-06-17 12:00:00.000000000 +0000 @@ -1,576 +1,619 @@ -// LzmsDecoder.cpp -// The code is based on LZMS description from wimlib code - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "LzmsDecoder.h" - -namespace NCompress { -namespace NLzms { - -static UInt32 g_PosBases[k_NumPosSyms /* + 1 */]; - -static Byte g_PosDirectBits[k_NumPosSyms]; - -static const Byte k_PosRuns[31] = -{ - 8, 0, 9, 7, 10, 15, 15, 20, 20, 30, 33, 40, 42, 45, 60, 73, - 80, 85, 95, 105, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 -}; - -static UInt32 g_LenBases[k_NumLenSyms]; - -static const Byte k_LenDirectBits[k_NumLenSyms] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, - 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 6, - 7, 8, 9, 10, 16, 30, -}; - -static struct CInit -{ - CInit() - { - { - unsigned sum = 0; - for (unsigned i = 0; i < sizeof(k_PosRuns); i++) - { - unsigned t = k_PosRuns[i]; - for (unsigned y = 0; y < t; y++) - g_PosDirectBits[sum + y] = (Byte)i; - sum += t; - } - } - { - UInt32 sum = 1; - for (unsigned i = 0; i < k_NumPosSyms; i++) - { - g_PosBases[i] = sum; - sum += (UInt32)1 << g_PosDirectBits[i]; - } - // g_PosBases[k_NumPosSyms] = sum; - } - { - UInt32 sum = 1; - for (unsigned i = 0; i < k_NumLenSyms; i++) - { - g_LenBases[i] = sum; - sum += (UInt32)1 << k_LenDirectBits[i]; - } - } - } -} g_Init; - -static unsigned GetNumPosSlots(size_t size) -{ - if (size < 2) - return 0; - - size--; - - if (size >= g_PosBases[k_NumPosSyms - 1]) - return k_NumPosSyms; - unsigned left = 0; - unsigned right = k_NumPosSyms; - for (;;) - { - unsigned m = (left + right) / 2; - if (left == m) - return m + 1; - if (size >= g_PosBases[m]) - left = m; - else - right = m; - } -} - - -static const Int32 k_x86_WindowSize = 65535; -static const Int32 k_x86_TransOffset = 1023; - -static const size_t k_x86_HistorySize = (1 << 16); - -static void x86_Filter(Byte *data, UInt32 size, Int32 *history) -{ - if (size <= 17) - return; - - Byte isCode[256]; - memset(isCode, 0, 256); - isCode[0x48] = 1; - isCode[0x4C] = 1; - isCode[0xE8] = 1; - isCode[0xE9] = 1; - isCode[0xF0] = 1; - isCode[0xFF] = 1; - - { - for (size_t i = 0; i < k_x86_HistorySize; i++) - history[i] = -(Int32)k_x86_WindowSize - 1; - } - - size -= 16; - const unsigned kSave = 6; - const Byte savedByte = data[size + kSave]; - data[size + kSave] = 0xE8; - Int32 last_x86_pos = -k_x86_TransOffset - 1; - - // first byte is ignored - Int32 i = 0; - - for (;;) - { - const Byte *p = data + (UInt32)i; - - for (;;) - { - if (isCode[*(++p)]) break; - if (isCode[*(++p)]) break; - } - - i = (Int32)(p - data); - if ((UInt32)i >= size) - break; - - UInt32 codeLen; - - Int32 maxTransOffset = k_x86_TransOffset; - - Byte b = p[0]; - - if (b == 0x48) - { - if (p[1] == 0x8B) - { - if ((p[2] & 0xF7) != 0x5) - continue; - // MOV RAX / RCX, [RIP + disp32] - } - else if (p[1] == 0x8D) // LEA - { - if ((p[2] & 0x7) != 0x5) - continue; - // LEA R**, [] - } - else - continue; - codeLen = 3; - } - else if (b == 0x4C) - { - if (p[1] != 0x8D || (p[2] & 0x7) != 0x5) - continue; - // LEA R*, [] - codeLen = 3; - } - else if (b == 0xE8) - { - // CALL - codeLen = 1; - maxTransOffset /= 2; - } - else if (b == 0xE9) - { - // JUMP - i += 4; - continue; - } - else if (b == 0xF0) - { - if (p[1] != 0x83 || p[2] != 0x05) - continue; - // LOCK ADD [RIP + disp32], imm8 - // LOCK ADD [disp32], imm8 - codeLen = 3; - } - else - // if (b == 0xFF) - { - if (p[1] != 0x15) - continue; - // CALL [RIP + disp32]; - // CALL [disp32]; - codeLen = 2; - } - - Int32 *target; - { - const Byte *p2 = p + codeLen; - UInt32 n = GetUi32(p2); - if (i - last_x86_pos <= maxTransOffset) - { - n -= i; - SetUi32(p2, n); - } - target = history + (((UInt32)i + n) & 0xFFFF); - } - - i += codeLen + sizeof(UInt32) - 1; - - if (i - *target <= k_x86_WindowSize) - last_x86_pos = i; - *target = i; - } - - data[size + kSave] = savedByte; -} - - - -static const int kLenIdNeedInit = -2; - -CDecoder::CDecoder(): - _x86_history(NULL) -{ -} - -CDecoder::~CDecoder() -{ - ::MidFree(_x86_history); -} - -#define RIF(x) { if (!(x)) return false; } - -#define LIMIT_CHECK if (_bs._buf < _rc.cur) return S_FALSE; -// #define LIMIT_CHECK - -#define READ_BITS_CHECK(numDirectBits) \ - if (_bs._buf < _rc.cur) return S_FALSE; \ - if ((size_t)(_bs._buf - _rc.cur) < (numDirectBits >> 3)) return S_FALSE; - - -#define HUFF_DEC(sym, pp) \ - sym = pp.DecodeFull(&_bs); \ - pp.Freqs[sym]++; \ - if (--pp.RebuildRem == 0) pp.Rebuild(); - - -HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t outSize) -{ - // size_t inSizeT = (size_t)(inSize); - // Byte *_win; - // size_t _pos; - _pos = 0; - - CBitDecoder _bs; - CRangeDecoder _rc; - - if (inSize < 8 || (inSize & 1) != 0) - return S_FALSE; - _rc.Init(in, inSize); - if (_rc.code >= _rc.range) - return S_FALSE; - _bs.Init(in, inSize); - - { - { - { - for (unsigned i = 0 ; i < k_NumReps + 1; i++) - _reps[i] = i + 1; - } - - { - for (unsigned i = 0 ; i < k_NumReps + 1; i++) - _deltaReps[i] = i + 1; - } - - mainState = 0; - matchState = 0; - - { for (size_t i = 0; i < k_NumMainProbs; i++) mainProbs[i].Init(); } - { for (size_t i = 0; i < k_NumMatchProbs; i++) matchProbs[i].Init(); } - - { - for (size_t k = 0; k < k_NumReps; k++) - { - lzRepStates[k] = 0; - for (size_t i = 0; i < k_NumRepProbs; i++) - lzRepProbs[k][i].Init(); - } - } - { - for (size_t k = 0; k < k_NumReps; k++) - { - deltaRepStates[k] = 0; - for (size_t i = 0; i < k_NumRepProbs; i++) - deltaRepProbs[k][i].Init(); - } - } - - m_LitDecoder.Init(); - m_LenDecoder.Init(); - m_PowerDecoder.Init(); - unsigned numPosSyms = GetNumPosSlots(outSize); - if (numPosSyms < 2) - numPosSyms = 2; - m_PosDecoder.Init(numPosSyms); - m_DeltaDecoder.Init(numPosSyms); - } - } - - { - unsigned prevType = 0; - - while (_pos < outSize) - { - if (_rc.Decode(&mainState, k_NumMainProbs, mainProbs) == 0) - { - UInt32 number; - HUFF_DEC(number, m_LitDecoder); - LIMIT_CHECK - _win[_pos++] = (Byte)number; - prevType = 0; - } - else if (_rc.Decode(&matchState, k_NumMatchProbs, matchProbs) == 0) - { - UInt32 distance; - - if (_rc.Decode(&lzRepStates[0], k_NumRepProbs, lzRepProbs[0]) == 0) - { - UInt32 number; - HUFF_DEC(number, m_PosDecoder); - LIMIT_CHECK - - unsigned numDirectBits = g_PosDirectBits[number]; - distance = g_PosBases[number]; - READ_BITS_CHECK(numDirectBits); - distance += _bs.ReadBits32(numDirectBits); - // LIMIT_CHECK - _reps[3] = _reps[2]; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - else - { - if (_rc.Decode(&lzRepStates[1], k_NumRepProbs, lzRepProbs[1]) == 0) - { - if (prevType != 1) - distance = _reps[0]; - else - { - distance = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - } - else if (_rc.Decode(&lzRepStates[2], k_NumRepProbs, lzRepProbs[2]) == 0) - { - if (prevType != 1) - { - distance = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - else - { - distance = _reps[2]; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - } - else - { - if (prevType != 1) - { - distance = _reps[2]; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - else - { - distance = _reps[3]; - _reps[3] = _reps[2]; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = distance; - } - } - } - - UInt32 lenSlot; - HUFF_DEC(lenSlot, m_LenDecoder); - LIMIT_CHECK - - UInt32 len = g_LenBases[lenSlot]; - { - unsigned numDirectBits = k_LenDirectBits[lenSlot]; - READ_BITS_CHECK(numDirectBits); - len += _bs.ReadBits32(numDirectBits); - } - // LIMIT_CHECK - - if (len > outSize - _pos) - return S_FALSE; - - if (distance > _pos) - return S_FALSE; - - Byte *dest = _win + _pos; - const Byte *src = dest - distance; - _pos += len; - do - *dest++ = *src++; - while (--len); - - prevType = 1; - } - else - { - UInt64 distance; - - UInt32 power; - UInt32 distance32; - - if (_rc.Decode(&deltaRepStates[0], k_NumRepProbs, deltaRepProbs[0]) == 0) - { - HUFF_DEC(power, m_PowerDecoder); - LIMIT_CHECK - - UInt32 number; - HUFF_DEC(number, m_DeltaDecoder); - LIMIT_CHECK - - unsigned numDirectBits = g_PosDirectBits[number]; - distance32 = g_PosBases[number]; - READ_BITS_CHECK(numDirectBits); - distance32 += _bs.ReadBits32(numDirectBits); - // LIMIT_CHECK - - distance = ((UInt64)power << 32) | distance32; - - _deltaReps[3] = _deltaReps[2]; - _deltaReps[2] = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - else - { - if (_rc.Decode(&deltaRepStates[1], k_NumRepProbs, deltaRepProbs[1]) == 0) - { - if (prevType != 2) - distance = _deltaReps[0]; - else - { - distance = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - } - else if (_rc.Decode(&deltaRepStates[2], k_NumRepProbs, deltaRepProbs[2]) == 0) - { - if (prevType != 2) - { - distance = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - else - { - distance = _deltaReps[2]; - _deltaReps[2] = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - } - else - { - if (prevType != 2) - { - distance = _deltaReps[2]; - _deltaReps[2] = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - else - { - distance = _deltaReps[3]; - _deltaReps[3] = _deltaReps[2]; - _deltaReps[2] = _deltaReps[1]; - _deltaReps[1] = _deltaReps[0]; - _deltaReps[0] = distance; - } - } - distance32 = (UInt32)_deltaReps[0] & 0xFFFFFFFF; - power = (UInt32)(_deltaReps[0] >> 32); - } - - UInt32 dist = (distance32 << power); - - UInt32 lenSlot; - HUFF_DEC(lenSlot, m_LenDecoder); - LIMIT_CHECK - - UInt32 len = g_LenBases[lenSlot]; - { - unsigned numDirectBits = k_LenDirectBits[lenSlot]; - READ_BITS_CHECK(numDirectBits); - len += _bs.ReadBits32(numDirectBits); - } - // LIMIT_CHECK - - if (len > outSize - _pos) - return S_FALSE; - - if (dist > _pos) - return S_FALSE; - size_t span = (size_t)1 << power; - Byte *dest = _win + _pos - span; - const Byte *src = dest - dist; - _pos += len; - do - { - *(dest + span) = (Byte)(*(dest) + *(src + span) - *(src)); - src++; - dest++; - } - while (--len); - - prevType = 2; - } - } - } - - _rc.Normalize(); - if (_rc.code != 0) - return S_FALSE; - if (_rc.cur > _bs._buf || - _rc.cur == _bs._buf && _bs._bitPos != 0) - return S_FALSE; - - /* - int delta = (int)(_bs._buf - _rc.cur); - if (_bs._bitPos != 0) - delta--; - if ((delta & 1)) - delta--; - printf("%d ", delta); - */ - - return S_OK; -} - -HRESULT CDecoder::Code(const Byte *in, size_t inSize, Byte *out, size_t outSize) -{ - if (!_x86_history) - { - _x86_history = (Int32 *)::MidAlloc(sizeof(Int32) * k_x86_HistorySize); - if (!_x86_history) - return E_OUTOFMEMORY; - } - HRESULT res; - // try - { - res = CodeReal(in, inSize, out, outSize); - } - // catch (...) { res = S_FALSE; } - x86_Filter(out, (UInt32)_pos, _x86_history); - return res; -} - -}} +// LzmsDecoder.cpp +// The code is based on LZMS description from wimlib code + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "LzmsDecoder.h" + +namespace NCompress { +namespace NLzms { + +class CBitDecoder +{ +public: + const Byte *_buf; + unsigned _bitPos; + + void Init(const Byte *buf, size_t size) throw() + { + _buf = buf + size; + _bitPos = 0; + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) const + { + UInt32 v = + ((UInt32)_buf[-1] << 16) | + ((UInt32)_buf[-2] << 8) | + (UInt32)_buf[-3]; + v >>= 24 - numBits - _bitPos; + return v & ((1u << numBits) - 1); + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() + { + return GetUi32(_buf - 4) << _bitPos; + } + + void MovePos(unsigned numBits) + { + _bitPos += numBits; + _buf -= (_bitPos >> 3); + _bitPos &= 7; + } + + UInt32 ReadBits32(unsigned numBits) + { + UInt32 mask = (((UInt32)1 << numBits) - 1); + numBits += _bitPos; + const Byte *buf = _buf; + UInt32 v = GetUi32(buf - 4); + if (numBits > 32) + { + v <<= (numBits - 32); + v |= (UInt32)buf[-5] >> (40 - numBits); + } + else + v >>= (32 - numBits); + _buf = buf - (numBits >> 3); + _bitPos = numBits & 7; + return v & mask; + } +}; + +static UInt32 g_PosBases[k_NumPosSyms /* + 1 */]; + +static Byte g_PosDirectBits[k_NumPosSyms]; + +static const Byte k_PosRuns[31] = +{ + 8, 0, 9, 7, 10, 15, 15, 20, 20, 30, 33, 40, 42, 45, 60, 73, + 80, 85, 95, 105, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +static UInt32 g_LenBases[k_NumLenSyms]; + +static const Byte k_LenDirectBits[k_NumLenSyms] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 6, + 7, 8, 9, 10, 16, 30, +}; + +static struct CInit +{ + CInit() + { + { + unsigned sum = 0; + for (unsigned i = 0; i < sizeof(k_PosRuns); i++) + { + unsigned t = k_PosRuns[i]; + for (unsigned y = 0; y < t; y++) + g_PosDirectBits[sum + y] = (Byte)i; + sum += t; + } + } + { + UInt32 sum = 1; + for (unsigned i = 0; i < k_NumPosSyms; i++) + { + g_PosBases[i] = sum; + sum += (UInt32)1 << g_PosDirectBits[i]; + } + // g_PosBases[k_NumPosSyms] = sum; + } + { + UInt32 sum = 1; + for (unsigned i = 0; i < k_NumLenSyms; i++) + { + g_LenBases[i] = sum; + sum += (UInt32)1 << k_LenDirectBits[i]; + } + } + } +} g_Init; + +static unsigned GetNumPosSlots(size_t size) +{ + if (size < 2) + return 0; + + size--; + + if (size >= g_PosBases[k_NumPosSyms - 1]) + return k_NumPosSyms; + unsigned left = 0; + unsigned right = k_NumPosSyms; + for (;;) + { + const unsigned m = (left + right) / 2; + if (left == m) + return m + 1; + if (size >= g_PosBases[m]) + left = m; + else + right = m; + } +} + + +static const Int32 k_x86_WindowSize = 65535; +static const Int32 k_x86_TransOffset = 1023; + +static const size_t k_x86_HistorySize = 1 << 16; + +static void x86_Filter(Byte *data, UInt32 size, Int32 *history) +{ + if (size <= 17) + return; + + Byte isCode[256]; + memset(isCode, 0, 256); + isCode[0x48] = 1; + isCode[0x4C] = 1; + isCode[0xE8] = 1; + isCode[0xE9] = 1; + isCode[0xF0] = 1; + isCode[0xFF] = 1; + + { + for (size_t i = 0; i < k_x86_HistorySize; i++) + history[i] = -(Int32)k_x86_WindowSize - 1; + } + + size -= 16; + const unsigned kSave = 6; + const Byte savedByte = data[(size_t)size + kSave]; + data[(size_t)size + kSave] = 0xE8; + Int32 last_x86_pos = -k_x86_TransOffset - 1; + + // first byte is ignored + Int32 i = 0; + + for (;;) + { + Byte *p = data + (UInt32)i; + + for (;;) + { + if (isCode[*(++p)]) break; + if (isCode[*(++p)]) break; + } + + i = (Int32)(p - data); + if ((UInt32)i >= size) + break; + + UInt32 codeLen; + + Int32 maxTransOffset = k_x86_TransOffset; + + const Byte b = p[0]; + + if ((b & 0x80) == 0) // REX (0x48 or 0x4c) + { + const unsigned b2 = p[2] - 0x5; // [RIP + disp32] + if (b2 & 0x7) + continue; + if (p[1] != 0x8d) // LEA + { + if (p[1] != 0x8b || b != 0x48 || (b2 & 0xf7)) + continue; + // MOV RAX / RCX, [RIP + disp32] + } + codeLen = 3; + } + else if (b == 0xE8) + { + // CALL + codeLen = 1; + maxTransOffset /= 2; + } + else if (b == 0xE9) + { + // JUMP + i += 4; + continue; + } + else if (b == 0xF0) + { + if (p[1] != 0x83 || p[2] != 0x05) + continue; + // LOCK ADD [RIP + disp32], imm8 + // LOCK ADD [disp32], imm8 + codeLen = 3; + } + else + // if (b == 0xFF) + { + if (p[1] != 0x15) + continue; + // CALL [RIP + disp32]; + // CALL [disp32]; + codeLen = 2; + } + + Int32 *target; + { + Byte *p2 = p + codeLen; + UInt32 n = GetUi32(p2); + if (i - last_x86_pos <= maxTransOffset) + { + n = (UInt32)((Int32)n - i); + SetUi32(p2, n) + } + target = history + (((UInt32)i + n) & 0xFFFF); + } + + i += (Int32)(codeLen + sizeof(UInt32) - 1); + + if (i - *target <= k_x86_WindowSize) + last_x86_pos = i; + *target = i; + } + + data[(size_t)size + kSave] = savedByte; +} + + + +// static const int kLenIdNeedInit = -2; + +CDecoder::CDecoder(): + _x86_history(NULL) +{ +} + +CDecoder::~CDecoder() +{ + ::MidFree(_x86_history); +} + +// #define RIF(x) { if (!(x)) return false; } + +#define LIMIT_CHECK if (_bs._buf < _rc.cur) return S_FALSE; +// #define LIMIT_CHECK + +#define READ_BITS_CHECK(numDirectBits) \ + if (_bs._buf < _rc.cur) return S_FALSE; \ + if ((size_t)(_bs._buf - _rc.cur) < (numDirectBits >> 3)) return S_FALSE; + + +#define HUFF_DEC(sym, pp) \ + sym = pp.DecodeFull(&_bs); \ + pp.Freqs[sym]++; \ + if (--pp.RebuildRem == 0) pp.Rebuild(); + + +HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t outSize) +{ + // size_t inSizeT = (size_t)(inSize); + // Byte *_win; + // size_t _pos; + _pos = 0; + + CBitDecoder _bs; + CRangeDecoder _rc; + + if (inSize < 8 || (inSize & 1) != 0) + return S_FALSE; + _rc.Init(in, inSize); + if (_rc.code >= _rc.range) + return S_FALSE; + _bs.Init(in, inSize); + + { + { + { + for (unsigned i = 0 ; i < k_NumReps + 1; i++) + _reps[i] = i + 1; + } + + { + for (unsigned i = 0 ; i < k_NumReps + 1; i++) + _deltaReps[i] = i + 1; + } + + mainState = 0; + matchState = 0; + + { for (size_t i = 0; i < k_NumMainProbs; i++) mainProbs[i].Init(); } + { for (size_t i = 0; i < k_NumMatchProbs; i++) matchProbs[i].Init(); } + + { + for (size_t k = 0; k < k_NumReps; k++) + { + lzRepStates[k] = 0; + for (size_t i = 0; i < k_NumRepProbs; i++) + lzRepProbs[k][i].Init(); + } + } + { + for (size_t k = 0; k < k_NumReps; k++) + { + deltaRepStates[k] = 0; + for (size_t i = 0; i < k_NumRepProbs; i++) + deltaRepProbs[k][i].Init(); + } + } + + m_LitDecoder.Init(); + m_LenDecoder.Init(); + m_PowerDecoder.Init(); + unsigned numPosSyms = GetNumPosSlots(outSize); + if (numPosSyms < 2) + numPosSyms = 2; + m_PosDecoder.Init(numPosSyms); + m_DeltaDecoder.Init(numPosSyms); + } + } + + { + unsigned prevType = 0; + + while (_pos < outSize) + { + if (_rc.Decode(&mainState, k_NumMainProbs, mainProbs) == 0) + { + unsigned number; + HUFF_DEC(number, m_LitDecoder) + LIMIT_CHECK + _win[_pos++] = (Byte)number; + prevType = 0; + } + else if (_rc.Decode(&matchState, k_NumMatchProbs, matchProbs) == 0) + { + UInt32 distance; + + if (_rc.Decode(&lzRepStates[0], k_NumRepProbs, lzRepProbs[0]) == 0) + { + unsigned number; + HUFF_DEC(number, m_PosDecoder) + LIMIT_CHECK + + const unsigned numDirectBits = g_PosDirectBits[number]; + distance = g_PosBases[number]; + READ_BITS_CHECK(numDirectBits) + distance += _bs.ReadBits32(numDirectBits); + // LIMIT_CHECK + _reps[3] = _reps[2]; + _reps[2] = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + else + { + if (_rc.Decode(&lzRepStates[1], k_NumRepProbs, lzRepProbs[1]) == 0) + { + if (prevType != 1) + distance = _reps[0]; + else + { + distance = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + } + else if (_rc.Decode(&lzRepStates[2], k_NumRepProbs, lzRepProbs[2]) == 0) + { + if (prevType != 1) + { + distance = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + else + { + distance = _reps[2]; + _reps[2] = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + } + else + { + if (prevType != 1) + { + distance = _reps[2]; + _reps[2] = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + else + { + distance = _reps[3]; + _reps[3] = _reps[2]; + _reps[2] = _reps[1]; + _reps[1] = _reps[0]; + _reps[0] = distance; + } + } + } + + unsigned lenSlot; + HUFF_DEC(lenSlot, m_LenDecoder) + LIMIT_CHECK + + UInt32 len = g_LenBases[lenSlot]; + { + const unsigned numDirectBits = k_LenDirectBits[lenSlot]; + READ_BITS_CHECK(numDirectBits) + len += _bs.ReadBits32(numDirectBits); + } + // LIMIT_CHECK + + if (len > outSize - _pos) + return S_FALSE; + + if (distance > _pos) + return S_FALSE; + + Byte *dest = _win + _pos; + const Byte *src = dest - distance; + _pos += len; + do + *dest++ = *src++; + while (--len); + + prevType = 1; + } + else + { + UInt64 distance; + + unsigned power; + UInt32 distance32; + + if (_rc.Decode(&deltaRepStates[0], k_NumRepProbs, deltaRepProbs[0]) == 0) + { + HUFF_DEC(power, m_PowerDecoder) + LIMIT_CHECK + + unsigned number; + HUFF_DEC(number, m_DeltaDecoder) + LIMIT_CHECK + + const unsigned numDirectBits = g_PosDirectBits[number]; + distance32 = g_PosBases[number]; + READ_BITS_CHECK(numDirectBits) + distance32 += _bs.ReadBits32(numDirectBits); + // LIMIT_CHECK + + distance = ((UInt64)power << 32) | distance32; + + _deltaReps[3] = _deltaReps[2]; + _deltaReps[2] = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + else + { + if (_rc.Decode(&deltaRepStates[1], k_NumRepProbs, deltaRepProbs[1]) == 0) + { + if (prevType != 2) + distance = _deltaReps[0]; + else + { + distance = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + } + else if (_rc.Decode(&deltaRepStates[2], k_NumRepProbs, deltaRepProbs[2]) == 0) + { + if (prevType != 2) + { + distance = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + else + { + distance = _deltaReps[2]; + _deltaReps[2] = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + } + else + { + if (prevType != 2) + { + distance = _deltaReps[2]; + _deltaReps[2] = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + else + { + distance = _deltaReps[3]; + _deltaReps[3] = _deltaReps[2]; + _deltaReps[2] = _deltaReps[1]; + _deltaReps[1] = _deltaReps[0]; + _deltaReps[0] = distance; + } + } + distance32 = (UInt32)_deltaReps[0] & 0xFFFFFFFF; + power = (UInt32)(_deltaReps[0] >> 32); + } + + const UInt32 dist = (distance32 << power); + + unsigned lenSlot; + HUFF_DEC(lenSlot, m_LenDecoder) + LIMIT_CHECK + + UInt32 len = g_LenBases[lenSlot]; + { + const unsigned numDirectBits = k_LenDirectBits[lenSlot]; + READ_BITS_CHECK(numDirectBits) + len += _bs.ReadBits32(numDirectBits); + } + // LIMIT_CHECK + + if (len > outSize - _pos) + return S_FALSE; + + size_t span = (size_t)1 << power; + if ((UInt64)dist + span > _pos) + return S_FALSE; + Byte *dest = _win + _pos - span; + const Byte *src = dest - dist; + _pos += len; + do + { + *(dest + span) = (Byte)(*(dest) + *(src + span) - *(src)); + src++; + dest++; + } + while (--len); + + prevType = 2; + } + } + } + + _rc.Normalize(); + if (_rc.code != 0) + return S_FALSE; + if (_rc.cur > _bs._buf + || (_rc.cur == _bs._buf && _bs._bitPos != 0)) + return S_FALSE; + + /* + int delta = (int)(_bs._buf - _rc.cur); + if (_bs._bitPos != 0) + delta--; + if ((delta & 1)) + delta--; + printf("%d ", delta); + */ + + return S_OK; +} + +HRESULT CDecoder::Code(const Byte *in, size_t inSize, Byte *out, size_t outSize) +{ + if (!_x86_history) + { + _x86_history = (Int32 *)::MidAlloc(sizeof(Int32) * k_x86_HistorySize); + if (!_x86_history) + return E_OUTOFMEMORY; + } + HRESULT res; + // try + { + res = CodeReal(in, inSize, out, outSize); + } + // catch (...) { res = S_FALSE; } + x86_Filter(out, (UInt32)_pos, _x86_history); + return res; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzmsDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzmsDecoder.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzmsDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,271 +1,209 @@ -// LzmsDecoder.h -// The code is based on LZMS description from wimlib code - -#ifndef __LZMS_DECODER_H -#define __LZMS_DECODER_H - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#define PRF(x) x -#else -// #define PRF(x) -#endif - -#include "../../../C/CpuArch.h" -#include "../../../C/HuffEnc.h" - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "HuffmanDecoder.h" - -namespace NCompress { -namespace NLzms { - -class CBitDecoder -{ -public: - const Byte *_buf; - unsigned _bitPos; - - void Init(const Byte *buf, size_t size) throw() - { - _buf = buf + size; - _bitPos = 0; - } - - UInt32 GetValue(unsigned numBits) const - { - UInt32 v = ((UInt32)_buf[-1] << 16) | ((UInt32)_buf[-2] << 8) | (UInt32)_buf[-3]; - v >>= (24 - numBits - _bitPos); - return v & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - _bitPos += numBits; - _buf -= (_bitPos >> 3); - _bitPos &= 7; - } - - UInt32 ReadBits32(unsigned numBits) - { - UInt32 mask = (((UInt32)1 << numBits) - 1); - numBits += _bitPos; - const Byte *buf = _buf; - UInt32 v = GetUi32(buf - 4); - if (numBits > 32) - { - v <<= (numBits - 32); - v |= (UInt32)buf[-5] >> (40 - numBits); - } - else - v >>= (32 - numBits); - _buf = buf - (numBits >> 3); - _bitPos = numBits & 7; - return v & mask; - } -}; - - -const unsigned k_NumLitSyms = 256; -const unsigned k_NumLenSyms = 54; -const unsigned k_NumPosSyms = 799; -const unsigned k_NumPowerSyms = 8; - -const unsigned k_NumProbBits = 6; -const unsigned k_ProbLimit = 1 << k_NumProbBits; -const unsigned k_InitialProb = 48; -const UInt32 k_InitialHist = 0x55555555; - -const unsigned k_NumReps = 3; - -const unsigned k_NumMainProbs = 16; -const unsigned k_NumMatchProbs = 32; -const unsigned k_NumRepProbs = 64; - -const unsigned k_NumHuffmanBits = 15; - -template -class CHuffDecoder: public NCompress::NHuffman::CDecoder -{ -public: - UInt32 RebuildRem; - UInt32 NumSyms; - UInt32 Freqs[m_NumSyms]; - - void Generate() throw() - { - UInt32 vals[m_NumSyms]; - Byte levels[m_NumSyms]; - - // We need to check that our algorithm is OK, when optimal Huffman tree uses more than 15 levels !!! - Huffman_Generate(Freqs, vals, levels, NumSyms, k_NumHuffmanBits); - - /* - for (UInt32 i = NumSyms; i < m_NumSyms; i++) - levels[i] = 0; - */ - this->BuildFull(levels, NumSyms); - } - - void Rebuild() throw() - { - Generate(); - RebuildRem = m_RebuildFreq; - UInt32 num = NumSyms; - for (UInt32 i = 0; i < num; i++) - Freqs[i] = (Freqs[i] >> 1) + 1; - } - -public: - void Init(UInt32 numSyms = m_NumSyms) throw() - { - RebuildRem = m_RebuildFreq; - NumSyms = numSyms; - for (UInt32 i = 0; i < numSyms; i++) - Freqs[i] = 1; - // for (; i < m_NumSyms; i++) Freqs[i] = 0; - Generate(); - } -}; - - -struct CProbEntry -{ - UInt32 Prob; - UInt64 Hist; - - void Init() - { - Prob = k_InitialProb; - Hist = k_InitialHist; - } - - UInt32 GetProb() const throw() - { - UInt32 prob = Prob; - if (prob == 0) - prob = 1; - else if (prob == k_ProbLimit) - prob = k_ProbLimit - 1; - return prob; - } - - void Update(unsigned bit) throw() - { - Prob += (Int32)(Hist >> (k_ProbLimit - 1)) - (Int32)bit; - Hist = (Hist << 1) | bit; - } -}; - - -struct CRangeDecoder -{ - UInt32 range; - UInt32 code; - const Byte *cur; - // const Byte *end; - - void Init(const Byte *data, size_t /* size */) throw() - { - range = 0xFFFFFFFF; - code = (((UInt32)GetUi16(data)) << 16) | GetUi16(data + 2); - cur = data + 4; - // end = data + size; - } - - void Normalize() - { - if (range <= 0xFFFF) - { - range <<= 16; - code <<= 16; - // if (cur >= end) throw 1; - code |= GetUi16(cur); - cur += 2; - } - } - - unsigned Decode(UInt32 *state, UInt32 numStates, struct CProbEntry *probs) - { - UInt32 st = *state; - CProbEntry *entry = &probs[st]; - st = (st << 1) & (numStates - 1); - - UInt32 prob = entry->GetProb(); - - if (range <= 0xFFFF) - { - range <<= 16; - code <<= 16; - // if (cur >= end) throw 1; - code |= GetUi16(cur); - cur += 2; - } - - UInt32 bound = (range >> k_NumProbBits) * prob; - - if (code < bound) - { - range = bound; - *state = st; - entry->Update(0); - return 0; - } - else - { - range -= bound; - code -= bound; - *state = st | 1; - entry->Update(1); - return 1; - } - } -}; - - -class CDecoder -{ - // CRangeDecoder _rc; - // CBitDecoder _bs; - size_t _pos; - - UInt32 _reps[k_NumReps + 1]; - UInt64 _deltaReps[k_NumReps + 1]; - - UInt32 mainState; - UInt32 matchState; - UInt32 lzRepStates[k_NumReps]; - UInt32 deltaRepStates[k_NumReps]; - - struct CProbEntry mainProbs[k_NumMainProbs]; - struct CProbEntry matchProbs[k_NumMatchProbs]; - - struct CProbEntry lzRepProbs[k_NumReps][k_NumRepProbs]; - struct CProbEntry deltaRepProbs[k_NumReps][k_NumRepProbs]; - - CHuffDecoder m_LitDecoder; - CHuffDecoder m_PosDecoder; - CHuffDecoder m_LenDecoder; - CHuffDecoder m_PowerDecoder; - CHuffDecoder m_DeltaDecoder; - - Int32 *_x86_history; - - HRESULT CodeReal(const Byte *in, size_t inSize, Byte *out, size_t outSize); -public: - CDecoder(); - ~CDecoder(); - - HRESULT Code(const Byte *in, size_t inSize, Byte *out, size_t outSize); - const size_t GetUnpackSize() const { return _pos; } -}; - -}} - -#endif +// LzmsDecoder.h +// The code is based on LZMS description from wimlib code + +#ifndef ZIP7_INC_LZMS_DECODER_H +#define ZIP7_INC_LZMS_DECODER_H + +#include "../../../C/CpuArch.h" +#include "../../../C/HuffEnc.h" + +#include "HuffmanDecoder.h" + +namespace NCompress { +namespace NLzms { + +const unsigned k_NumLitSyms = 256; +const unsigned k_NumLenSyms = 54; +const unsigned k_NumPosSyms = 799; +const unsigned k_NumPowerSyms = 8; + +const unsigned k_NumProbBits = 6; +const unsigned k_ProbLimit = 1 << k_NumProbBits; +const unsigned k_InitialProb = 48; +const UInt32 k_InitialHist = 0x55555555; + +const unsigned k_NumReps = 3; + +const unsigned k_NumMainProbs = 16; +const unsigned k_NumMatchProbs = 32; +const unsigned k_NumRepProbs = 64; + +const unsigned k_NumHuffmanBits = 15; + +template +class CHuffDecoder: public NCompress::NHuffman::CDecoder +{ +public: + UInt32 RebuildRem; + UInt32 NumSyms; + UInt32 Freqs[m_NumSyms]; + + void Generate() throw() + { + UInt32 vals[m_NumSyms]; + Byte levels[m_NumSyms]; + + // We need to check that our algorithm is OK, when optimal Huffman tree uses more than 15 levels !!! + Huffman_Generate(Freqs, vals, levels, NumSyms, k_NumHuffmanBits); + + for (UInt32 i = NumSyms; i < m_NumSyms; i++) + levels[i] = 0; + + this->Build(levels, /* NumSyms, */ NHuffman::k_BuildMode_Full); + } + + void Rebuild() throw() + { + Generate(); + RebuildRem = m_RebuildFreq; + const UInt32 num = NumSyms; + for (UInt32 i = 0; i < num; i++) + Freqs[i] = (Freqs[i] >> 1) + 1; + } + +public: + void Init(UInt32 numSyms = m_NumSyms) throw() + { + RebuildRem = m_RebuildFreq; + NumSyms = numSyms; + for (UInt32 i = 0; i < numSyms; i++) + Freqs[i] = 1; + // for (; i < m_NumSyms; i++) Freqs[i] = 0; + Generate(); + } +}; + + +struct CProbEntry +{ + UInt32 Prob; + UInt64 Hist; + + void Init() + { + Prob = k_InitialProb; + Hist = k_InitialHist; + } + + UInt32 GetProb() const throw() + { + UInt32 prob = Prob; + if (prob == 0) + prob = 1; + else if (prob == k_ProbLimit) + prob = k_ProbLimit - 1; + return prob; + } + + void Update(unsigned bit) throw() + { + Prob += (UInt32)((Int32)(Hist >> (k_ProbLimit - 1)) - (Int32)bit); + Hist = (Hist << 1) | bit; + } +}; + + +struct CRangeDecoder +{ + UInt32 range; + UInt32 code; + const Byte *cur; + // const Byte *end; + + void Init(const Byte *data, size_t /* size */) throw() + { + range = 0xFFFFFFFF; + code = (((UInt32)GetUi16(data)) << 16) | GetUi16(data + 2); + cur = data + 4; + // end = data + size; + } + + void Normalize() + { + if (range <= 0xFFFF) + { + range <<= 16; + code <<= 16; + // if (cur >= end) throw 1; + code |= GetUi16(cur); + cur += 2; + } + } + + unsigned Decode(UInt32 *state, UInt32 numStates, struct CProbEntry *probs) + { + UInt32 st = *state; + CProbEntry *entry = &probs[st]; + st = (st << 1) & (numStates - 1); + + const UInt32 prob = entry->GetProb(); + + if (range <= 0xFFFF) + { + range <<= 16; + code <<= 16; + // if (cur >= end) throw 1; + code |= GetUi16(cur); + cur += 2; + } + + const UInt32 bound = (range >> k_NumProbBits) * prob; + + if (code < bound) + { + range = bound; + *state = st; + entry->Update(0); + return 0; + } + else + { + range -= bound; + code -= bound; + *state = st | 1; + entry->Update(1); + return 1; + } + } +}; + + +class CDecoder +{ + // CRangeDecoder _rc; + size_t _pos; + + UInt32 _reps[k_NumReps + 1]; + UInt64 _deltaReps[k_NumReps + 1]; + + UInt32 mainState; + UInt32 matchState; + UInt32 lzRepStates[k_NumReps]; + UInt32 deltaRepStates[k_NumReps]; + + struct CProbEntry mainProbs[k_NumMainProbs]; + struct CProbEntry matchProbs[k_NumMatchProbs]; + + struct CProbEntry lzRepProbs[k_NumReps][k_NumRepProbs]; + struct CProbEntry deltaRepProbs[k_NumReps][k_NumRepProbs]; + + CHuffDecoder m_LitDecoder; + CHuffDecoder m_PosDecoder; + CHuffDecoder m_LenDecoder; + CHuffDecoder m_PowerDecoder; + CHuffDecoder m_DeltaDecoder; + + Int32 *_x86_history; + + HRESULT CodeReal(const Byte *in, size_t inSize, Byte *out, size_t outSize); +public: + CDecoder(); + ~CDecoder(); + + HRESULT Code(const Byte *in, size_t inSize, Byte *out, size_t outSize); + size_t GetUnpackSize() const { return _pos; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Lzx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzx.h --- p7zip-rar-16.02/CPP/7zip/Compress/Lzx.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Lzx.h 2023-09-17 08:00:00.000000000 +0000 @@ -1,57 +1,61 @@ -// Lzx.h - -#ifndef __COMPRESS_LZX_H -#define __COMPRESS_LZX_H - -namespace NCompress { -namespace NLzx { - -const unsigned kBlockType_NumBits = 3; -const unsigned kBlockType_Verbatim = 1; -const unsigned kBlockType_Aligned = 2; -const unsigned kBlockType_Uncompressed = 3; - -const unsigned kNumHuffmanBits = 16; -const unsigned kNumReps = 3; - -const unsigned kNumLenSlots = 8; -const unsigned kMatchMinLen = 2; -const unsigned kNumLenSymbols = 249; -const unsigned kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; - -const unsigned kNumAlignLevelBits = 3; -const unsigned kNumAlignBits = 3; -const unsigned kAlignTableSize = 1 << kNumAlignBits; - -const unsigned kNumPosSlots = 50; -const unsigned kNumPosLenSlots = kNumPosSlots * kNumLenSlots; - -const unsigned kMainTableSize = 256 + kNumPosLenSlots; -const unsigned kLevelTableSize = 20; -const unsigned kMaxTableSize = kMainTableSize; - -const unsigned kNumLevelBits = 4; - -const unsigned kLevelSym_Zero1 = 17; -const unsigned kLevelSym_Zero2 = 18; -const unsigned kLevelSym_Same = 19; - -const unsigned kLevelSym_Zero1_Start = 4; -const unsigned kLevelSym_Zero1_NumBits = 4; - -const unsigned kLevelSym_Zero2_Start = kLevelSym_Zero1_Start + (1 << kLevelSym_Zero1_NumBits); -const unsigned kLevelSym_Zero2_NumBits = 5; - -const unsigned kLevelSym_Same_NumBits = 1; -const unsigned kLevelSym_Same_Start = 4; - -const unsigned kNumDictBits_Min = 15; -const unsigned kNumDictBits_Max = 21; -const UInt32 kDictSize_Max = (UInt32)1 << kNumDictBits_Max; - -const unsigned kNumLinearPosSlotBits = 17; -const unsigned kNumPowerPosSlots = 38; - -}} - -#endif +// Lzx.h + +#ifndef ZIP7_INC_COMPRESS_LZX_H +#define ZIP7_INC_COMPRESS_LZX_H + +#include "../../Common/MyTypes.h" + +namespace NCompress { +namespace NLzx { + +const unsigned kBlockType_NumBits = 3; +const unsigned kBlockType_Verbatim = 1; +const unsigned kBlockType_Aligned = 2; +const unsigned kBlockType_Uncompressed = 3; + +const unsigned kNumHuffmanBits = 16; +const unsigned kNumReps = 3; + +const unsigned kNumLenSlots = 8; +const unsigned kMatchMinLen = 2; +const unsigned kNumLenSymbols = 249; +const unsigned kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; + +const unsigned kNumAlignLevelBits = 3; +const unsigned kNumAlignBits = 3; +const unsigned kAlignTableSize = 1 << kNumAlignBits; + +const unsigned kNumPosSlots = 50; +const unsigned kNumPosLenSlots = kNumPosSlots * kNumLenSlots; + +const unsigned kMainTableSize = 256 + kNumPosLenSlots; +const unsigned kLevelTableSize = 20; +const unsigned kMaxTableSize = kMainTableSize; + +const unsigned kNumLevelBits = 4; + +const unsigned kLevelSym_Zero1 = 17; +const unsigned kLevelSym_Zero2 = 18; +const unsigned kLevelSym_Same = 19; + +const unsigned kLevelSym_Zero1_Start = 4; +const unsigned kLevelSym_Zero1_NumBits = 4; + +const unsigned kLevelSym_Zero2_Start = kLevelSym_Zero1_Start + (1 << kLevelSym_Zero1_NumBits); +const unsigned kLevelSym_Zero2_NumBits = 5; + +const unsigned kLevelSym_Same_NumBits = 1; +const unsigned kLevelSym_Same_Start = 4; + +const unsigned kNumDictBits_Min = 15; +const unsigned kNumDictBits_Max = 21; +const UInt32 kDictSize_Max = (UInt32)1 << kNumDictBits_Max; + +const unsigned kNumLinearPosSlotBits = 17; +// const unsigned kNumPowerPosSlots = 38; +// const unsigned kNumPowerPosSlots = (kNumLinearPosSlotBits + 1) * 2; // non-including two first linear slots. +const unsigned kNumPowerPosSlots = (kNumLinearPosSlotBits + 2) * 2; // including two first linear slots. + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzxDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/LzxDecoder.cpp 2015-09-22 18:01:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.cpp 2024-01-07 16:00:00.000000000 +0000 @@ -1,529 +1,1517 @@ -// LzxDecoder.cpp - -#include "StdAfx.h" - -#include - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#define PRF(x) x -#else -#define PRF(x) -#endif - -#include "../../../C/Alloc.h" - -#include "LzxDecoder.h" - -namespace NCompress { -namespace NLzx { - -static void x86_Filter(Byte *data, UInt32 size, UInt32 processedSize, UInt32 translationSize) -{ - const UInt32 kResidue = 10; - if (size <= kResidue) - return; - size -= kResidue; - - Byte save = data[size + 4]; - data[size + 4] = 0xE8; - - for (UInt32 i = 0;;) - { - const Byte *p = data + i; - for (;;) - { - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; - if (*p++ == 0xE8) break; - } - - i = (UInt32)(p - data); - - if (i > size) - break; - { - Int32 v = GetUi32(p); - Int32 pos = (Int32)((Int32)1 - (Int32)(processedSize + i)); - i += 4; - if (v >= pos && v < (Int32)translationSize) - { - v += (v >= 0 ? pos : translationSize); - SetUi32(p, v); - } - } - } - - data[size + 4] = save; -} - - -CDecoder::CDecoder(bool wimMode): - _win(NULL), - _keepHistory(false), - _skipByte(false), - _wimMode(wimMode), - _numDictBits(15), - _unpackBlockSize(0), - _x86_buf(NULL), - _x86_translationSize(0), - KeepHistoryForNext(true), - NeedAlloc(true), - _unpackedData(NULL) -{ -} - -CDecoder::~CDecoder() -{ - if (NeedAlloc) - ::MidFree(_win); - ::MidFree(_x86_buf); -} - -HRESULT CDecoder::Flush() -{ - if (_x86_translationSize != 0) - { - Byte *destData = _win + _writePos; - UInt32 curSize = _pos - _writePos; - if (KeepHistoryForNext) - { - if (!_x86_buf) - { - // we must change it to support another chunk sizes - const size_t kChunkSize = (size_t)1 << 15; - if (curSize > kChunkSize) - return E_NOTIMPL; - _x86_buf = (Byte *)::MidAlloc(kChunkSize); - if (!_x86_buf) - return E_OUTOFMEMORY; - } - memcpy(_x86_buf, destData, curSize); - _unpackedData = _x86_buf; - destData = _x86_buf; - } - x86_Filter(destData, (UInt32)curSize, _x86_processedSize, _x86_translationSize); - _x86_processedSize += (UInt32)curSize; - if (_x86_processedSize >= ((UInt32)1 << 30)) - _x86_translationSize = 0; - } - - return S_OK; -} - - -UInt32 CDecoder::ReadBits(unsigned numBits) { return _bitStream.ReadBitsSmall(numBits); } - -#define RIF(x) { if (!(x)) return false; } - -bool CDecoder::ReadTable(Byte *levels, unsigned numSymbols) -{ - { - Byte levels2[kLevelTableSize]; - for (unsigned i = 0; i < kLevelTableSize; i++) - levels2[i] = (Byte)ReadBits(kNumLevelBits); - RIF(_levelDecoder.Build(levels2)); - } - - unsigned i = 0; - do - { - UInt32 sym = _levelDecoder.Decode(&_bitStream); - if (sym <= kNumHuffmanBits) - { - int delta = (int)levels[i] - (int)sym; - delta += (delta < 0) ? (kNumHuffmanBits + 1) : 0; - levels[i++] = (Byte)delta; - continue; - } - - unsigned num; - Byte symbol; - - if (sym < kLevelSym_Same) - { - sym -= kLevelSym_Zero1; - num = kLevelSym_Zero1_Start + ((unsigned)sym << kLevelSym_Zero1_NumBits) + - (unsigned)ReadBits(kLevelSym_Zero1_NumBits + sym); - symbol = 0; - } - else if (sym == kLevelSym_Same) - { - num = kLevelSym_Same_Start + (unsigned)ReadBits(kLevelSym_Same_NumBits); - sym = _levelDecoder.Decode(&_bitStream); - if (sym > kNumHuffmanBits) - return false; - int delta = (int)levels[i] - (int)sym; - delta += (delta < 0) ? (kNumHuffmanBits + 1) : 0; - symbol = (Byte)delta; - } - else - return false; - - unsigned limit = i + num; - if (limit > numSymbols) - return false; - - do - levels[i++] = symbol; - while (i < limit); - } - while (i < numSymbols); - - return true; -} - - -bool CDecoder::ReadTables(void) -{ - { - if (_skipByte) - { - if (_bitStream.DirectReadByte() != 0) - return false; - } - - _bitStream.NormalizeBig(); - - unsigned blockType = (unsigned)ReadBits(kBlockType_NumBits); - if (blockType > kBlockType_Uncompressed) - return false; - - _unpackBlockSize = (1 << 15); - if (!_wimMode || ReadBits(1) == 0) - { - _unpackBlockSize = ReadBits(16); - // wimlib supports chunks larger than 32KB (unsupported my MS wim). - if (!_wimMode || _numDictBits >= 16) - { - _unpackBlockSize <<= 8; - _unpackBlockSize |= ReadBits(8); - } - } - - PRF(printf("\nBlockSize = %6d %s ", _unpackBlockSize, (_pos & 1) ? "@@@" : " ")); - - _isUncompressedBlock = (blockType == kBlockType_Uncompressed); - - _skipByte = false; - - if (_isUncompressedBlock) - { - _skipByte = ((_unpackBlockSize & 1) != 0); - - PRF(printf(" UncompressedBlock ")); - if (_unpackBlockSize & 1) - { - PRF(printf(" ######### ")); - } - - if (!_bitStream.PrepareUncompressed()) - return false; - if (_bitStream.GetRem() < kNumReps * 4) - return false; - - for (unsigned i = 0; i < kNumReps; i++) - { - UInt32 rep = _bitStream.ReadUInt32(); - if (rep > _winSize) - return false; - _reps[i] = rep; - } - - return true; - } - - _numAlignBits = 64; - - if (blockType == kBlockType_Aligned) - { - Byte levels[kAlignTableSize]; - _numAlignBits = kNumAlignBits; - for (unsigned i = 0; i < kAlignTableSize; i++) - levels[i] = (Byte)ReadBits(kNumAlignLevelBits); - RIF(_alignDecoder.Build(levels)); - } - } - - RIF(ReadTable(_mainLevels, 256)); - RIF(ReadTable(_mainLevels + 256, _numPosLenSlots)); - unsigned end = 256 + _numPosLenSlots; - memset(_mainLevels + end, 0, kMainTableSize - end); - RIF(_mainDecoder.Build(_mainLevels)); - RIF(ReadTable(_lenLevels, kNumLenSymbols)); - return _lenDecoder.Build(_lenLevels); -} - - -HRESULT CDecoder::CodeSpec(UInt32 curSize) -{ - if (!_keepHistory || !_isUncompressedBlock) - _bitStream.NormalizeBig(); - - if (!_keepHistory) - { - _skipByte = false; - _unpackBlockSize = 0; - - memset(_mainLevels, 0, kMainTableSize); - memset(_lenLevels, 0, kNumLenSymbols); - - { - _x86_translationSize = 12000000; - if (!_wimMode) - { - _x86_translationSize = 0; - if (ReadBits(1) != 0) - { - UInt32 v = ReadBits(16) << 16; - v |= ReadBits(16); - _x86_translationSize = v; - } - } - - _x86_processedSize = 0; - } - - _reps[0] = 1; - _reps[1] = 1; - _reps[2] = 1; - } - - while (curSize > 0) - { - if (_bitStream.WasExtraReadError_Fast()) - return S_FALSE; - - if (_unpackBlockSize == 0) - { - if (!ReadTables()) - return S_FALSE; - continue; - } - - UInt32 next = _unpackBlockSize; - if (next > curSize) - next = curSize; - - if (_isUncompressedBlock) - { - size_t rem = _bitStream.GetRem(); - if (rem == 0) - return S_FALSE; - if (next > rem) - next = (UInt32)rem; - _bitStream.CopyTo(_win + _pos, next); - _pos += next; - curSize -= next; - _unpackBlockSize -= next; - - /* we don't know where skipByte can be placed, if it's end of chunk: - 1) in current chunk - there are such cab archives, if chunk is last - 2) in next chunk - are there such archives ? */ - - if (_skipByte - && _unpackBlockSize == 0 - && curSize == 0 - && _bitStream.IsOneDirectByteLeft()) - { - _skipByte = false; - if (_bitStream.DirectReadByte() != 0) - return S_FALSE; - } - - continue; - } - - curSize -= next; - _unpackBlockSize -= next; - - Byte *win = _win; - - while (next > 0) - { - if (_bitStream.WasExtraReadError_Fast()) - return S_FALSE; - - UInt32 sym = _mainDecoder.Decode(&_bitStream); - - if (sym < 256) - { - win[_pos++] = (Byte)sym; - next--; - continue; - } - { - sym -= 256; - if (sym >= _numPosLenSlots) - return S_FALSE; - UInt32 posSlot = sym / kNumLenSlots; - UInt32 lenSlot = sym % kNumLenSlots; - UInt32 len = kMatchMinLen + lenSlot; - - if (lenSlot == kNumLenSlots - 1) - { - UInt32 lenTemp = _lenDecoder.Decode(&_bitStream); - if (lenTemp >= kNumLenSymbols) - return S_FALSE; - len = kMatchMinLen + kNumLenSlots - 1 + lenTemp; - } - - UInt32 dist; - - if (posSlot < kNumReps) - { - dist = _reps[posSlot]; - _reps[posSlot] = _reps[0]; - _reps[0] = dist; - } - else - { - unsigned numDirectBits; - - if (posSlot < kNumPowerPosSlots) - { - numDirectBits = (unsigned)(posSlot >> 1) - 1; - dist = ((2 | (posSlot & 1)) << numDirectBits); - } - else - { - numDirectBits = kNumLinearPosSlotBits; - dist = ((posSlot - 0x22) << kNumLinearPosSlotBits); - } - - if (numDirectBits >= _numAlignBits) - { - dist += (_bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits); - UInt32 alignTemp = _alignDecoder.Decode(&_bitStream); - if (alignTemp >= kAlignTableSize) - return S_FALSE; - dist += alignTemp; - } - else - dist += _bitStream.ReadBitsBig(numDirectBits); - - dist -= kNumReps - 1; - _reps[2] = _reps[1]; - _reps[1] = _reps[0]; - _reps[0] = dist; - } - - if (len > next) - return S_FALSE; - - if (dist > _pos && !_overDict) - return S_FALSE; - - Byte *dest = win + _pos; - const UInt32 mask = (_winSize - 1); - UInt32 srcPos = (_pos - dist) & mask; - - next -= len; - - if (len > _winSize - srcPos) - { - _pos += len; - do - { - *dest++ = win[srcPos++]; - srcPos &= mask; - } - while (--len); - } - else - { - ptrdiff_t src = (ptrdiff_t)srcPos - (ptrdiff_t)_pos; - _pos += len; - const Byte *lim = dest + len; - *(dest) = *(dest + src); - dest++; - do - *(dest) = *(dest + src); - while (++dest != lim); - } - } - } - } - - if (!_bitStream.WasFinishedOK()) - return S_FALSE; - - return S_OK; -} - - -HRESULT CDecoder::Code(const Byte *inData, size_t inSize, UInt32 outSize) -{ - if (!_keepHistory) - { - _pos = 0; - _overDict = false; - } - else if (_pos == _winSize) - { - _pos = 0; - _overDict = true; - } - - _writePos = _pos; - _unpackedData = _win + _pos; - - if (outSize > _winSize - _pos) - return S_FALSE; - - PRF(printf("\ninSize = %d", inSize)); - if ((inSize & 1) != 0) - { - PRF(printf(" ---------")); - } - - if (inSize < 1) - return S_FALSE; - - _bitStream.Init(inData, inSize); - - HRESULT res = CodeSpec(outSize); - HRESULT res2 = Flush(); - return (res == S_OK ? res2 : res); -} - - -HRESULT CDecoder::SetParams2(unsigned numDictBits) -{ - _numDictBits = numDictBits; - if (numDictBits < kNumDictBits_Min || numDictBits > kNumDictBits_Max) - return E_INVALIDARG; - unsigned numPosSlots = (numDictBits < 20) ? - numDictBits * 2 : - 34 + ((unsigned)1 << (numDictBits - 17)); - _numPosLenSlots = numPosSlots * kNumLenSlots; - return S_OK; -} - - -HRESULT CDecoder::SetParams_and_Alloc(unsigned numDictBits) -{ - RINOK(SetParams2(numDictBits)); - - UInt32 newWinSize = (UInt32)1 << numDictBits; - - if (NeedAlloc) - { - if (!_win || newWinSize != _winSize) - { - ::MidFree(_win); - _winSize = 0; - _win = (Byte *)::MidAlloc(newWinSize); - if (!_win) - return E_OUTOFMEMORY; - } - } - - _winSize = (UInt32)newWinSize; - return S_OK; -} - -}} +// LzxDecoder.cpp + +#include "StdAfx.h" + +#include +// #include + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +#include "../../../C/Alloc.h" +#include "../../../C/RotateDefs.h" +#include "../../../C/CpuArch.h" + +#include "LzxDecoder.h" + + +#ifdef MY_CPU_X86_OR_AMD64 +#if defined(MY_CPU_AMD64) \ + || defined(__SSE2__) \ + || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || 0 && defined(_MSC_VER) && (_MSC_VER >= 1400) // set (1 &&) for debug + +#if defined(__clang__) && (__clang_major__ >= 2) \ + || defined(__GNUC__) && (__GNUC__ >= 4) \ + || defined(_MSC_VER) && (_MSC_VER >= 1400) +#define Z7_LZX_X86_FILTER_USE_SSE2 +#endif +#endif +#endif + + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2 +// #ifdef MY_CPU_X86_OR_AMD64 +#include // SSE2 +// #endif + #if defined(__clang__) || defined(__GNUC__) + typedef int ctz_type; + #define MY_CTZ(dest, mask) dest = __builtin_ctz((UInt32)(mask)) + #else // #if defined(_MSC_VER) + #if (_MSC_VER >= 1600) + // #include + #endif + typedef unsigned long ctz_type; + #define MY_CTZ(dest, mask) _BitScanForward(&dest, (mask)); + #endif // _MSC_VER +#endif + +// when window buffer is filled, we must wrap position to zero, +// and we want to wrap at same points where original-lzx must wrap. +// But the wrapping is possible in point where chunk is finished. +// Usually (chunk_size == 32KB), but (chunk_size != 32KB) also is allowed. +// So we don't use additional buffer space over required (winSize). +// And we can't use large overwrite after (len) in CopyLzMatch(). +// But we are allowed to write 3 bytes after (len), because +// (delta <= _winSize - 3). + +// #define k_Lz_OverwriteSize 0 // for debug : to disable overwrite +#define k_Lz_OverwriteSize 3 // = kNumReps +#if k_Lz_OverwriteSize > 0 +// (k_Lz_OutBufSize_Add >= k_Lz_OverwriteSize) is required +// we use value 4 to simplify memset() code. +#define k_Lz_OutBufSize_Add (k_Lz_OverwriteSize + 1) // == 4 +#else +#define k_Lz_OutBufSize_Add 0 +#endif + +// (len != 0) +// (0 < delta <= _winSize - 3) +Z7_FORCE_INLINE +void CopyLzMatch(Byte *dest, const Byte *src, UInt32 len, UInt32 delta) +{ + if (delta >= 4) + { +#if k_Lz_OverwriteSize >= 3 + // optimized code with overwrite to reduce the number of branches + #ifdef MY_CPU_LE_UNALIGN + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + #else + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; + #endif + len--; + src++; + dest++; + { +#else + // no overwrite in out buffer + dest[0] = src[0]; + { + const unsigned m = (unsigned)len & 1; + src += m; + dest += m; + } + if (len &= ~(unsigned)1) + { + dest[0] = src[0]; + dest[1] = src[1]; +#endif + // len == 0 is allowed here + { + const unsigned m = (unsigned)len & 3; + src += m; + dest += m; + } + if (len &= ~(unsigned)3) + { +#ifdef MY_CPU_LE_UNALIGN + #if 1 + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + { + const unsigned m = (unsigned)len & 7; + dest += m; + src += m; + } + if (len &= ~(unsigned)7) + do + { + *(UInt32 *)(void *)(dest ) = *(const UInt32 *)(const void *)(src); + *(UInt32 *)(void *)(dest + 4) = *(const UInt32 *)(const void *)(src + 4); + src += 8; + dest += 8; + } + while (len -= 8); + #else + // gcc-11 -O3 for x64 generates incorrect code here + do + { + *(UInt32 *)(void *)(dest) = *(const UInt32 *)(const void *)(src); + src += 4; + dest += 4; + } + while (len -= 4); + #endif +#else + do + { + const Byte b0 = src[0]; + const Byte b1 = src[1]; + dest[0] = b0; + dest[1] = b1; + const Byte b2 = src[2]; + const Byte b3 = src[3]; + dest[2] = b2; + dest[3] = b3; + src += 4; + dest += 4; + } + while (len -= 4); +#endif + } + } + } + else // (delta < 4) + { + const unsigned b0 = *src; + *dest = (Byte)b0; + if (len >= 2) + { + if (delta < 2) + { + dest += (unsigned)len & 1; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += (unsigned)len & 2; + if (len &= ~(unsigned)3) + { +#ifdef MY_CPU_LE_UNALIGN + #ifdef MY_CPU_64BIT + const UInt64 a = (UInt64)b0 * 0x101010101010101; + *(UInt32 *)(void *)dest = (UInt32)a; + dest += (unsigned)len & 7; + if (len &= ~(unsigned)7) + { + // *(UInt64 *)(void *)dest = a; + // dest += 8; + // len -= 8; + // if (len) + { + // const ptrdiff_t delta = (ptrdiff_t)dest & 7; + // dest -= delta; + do + { + *(UInt64 *)(void *)dest = a; + dest += 8; + } + while (len -= 8); + // dest += delta - 8; + // *(UInt64 *)(void *)dest = a; + } + } + #else + const UInt32 a = (UInt32)b0 * 0x1010101; + do + { + *(UInt32 *)(void *)dest = a; + dest += 4; + } + while (len -= 4); + #endif +#else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest[2] = (Byte)b0; + dest[3] = (Byte)b0; + dest += 4; + } + while (len -= 4); +#endif + } + } + else if (delta == 2) + { + const unsigned m = (unsigned)len & 1; + len &= ~(unsigned)1; + src += m; + dest += m; + { + const Byte a0 = src[0]; + const Byte a1 = src[1]; + do + { + dest[0] = a0; + dest[1] = a1; + dest += 2; + } + while (len -= 2); + } + } + else /* if (delta == 3) */ + { + const unsigned b1 = src[1]; + dest[1] = (Byte)b1; + if (len -= 2) + { + const unsigned b2 = src[2]; + dest += 2; + do + { + dest[0] = (Byte)b2; if (--len == 0) break; + dest[1] = (Byte)b0; if (--len == 0) break; + dest[2] = (Byte)b1; + dest += 3; + } + while (--len); + } + } + } + } +} + +// #define Z7_LZX_SHOW_STAT +#ifdef Z7_LZX_SHOW_STAT +#include +#endif + +namespace NCompress { +namespace NLzx { + +// #define Z7_LZX_SHOW_STAT +#ifdef Z7_LZX_SHOW_STAT +static UInt32 g_stats_Num_x86[3]; +static UInt32 g_stats_NumTables; +static UInt32 g_stats_NumLits; +static UInt32 g_stats_NumAlign; +static UInt32 g_stats_main[kMainTableSize]; +static UInt32 g_stats_len[kNumLenSymbols]; +static UInt32 g_stats_main_levels[kNumHuffmanBits + 1]; +static UInt32 g_stats_len_levels[kNumHuffmanBits + 1]; +#define UPDATE_STAT(a) a +static void PrintVal(UInt32 v) +{ + printf("\n : %9u", v); +} +static void PrintStat(const char *name, const UInt32 *a, size_t num) +{ + printf("\n\n==== %s:", name); + UInt32 sum = 0; + size_t i; + for (i = 0; i < num; i++) + sum += a[i]; + PrintVal(sum); + if (sum != 0) + { + for (i = 0; i < num; i++) + { + if (i % 8 == 0) + printf("\n"); + printf("\n%3x : %9u : %5.2f", (unsigned)i, (unsigned)a[i], (double)a[i] * 100 / sum); + } + } + printf("\n"); +} + +static struct CStat +{ + ~CStat() + { + PrintStat("x86_filter", g_stats_Num_x86, Z7_ARRAY_SIZE(g_stats_Num_x86)); + printf("\nTables:"); PrintVal(g_stats_NumTables); + printf("\nLits:"); PrintVal(g_stats_NumLits); + printf("\nAlign:"); PrintVal(g_stats_NumAlign); + PrintStat("Main", g_stats_main, Z7_ARRAY_SIZE(g_stats_main)); + PrintStat("Len", g_stats_len, Z7_ARRAY_SIZE(g_stats_len)); + PrintStat("Main Levels", g_stats_main_levels, Z7_ARRAY_SIZE(g_stats_main_levels)); + PrintStat("Len Levels", g_stats_len_levels, Z7_ARRAY_SIZE(g_stats_len_levels)); + } +} g_stat; +#else +#define UPDATE_STAT(a) +#endif + + + +/* +3 p015 : ivb- : or r32,r32 / add r32,r32 +4 p0156 : hsw+ +5 p0156b: adl+ +2 p0_5 : ivb- : shl r32,i8 +2 p0__6 : hsw+ +1 p5 : ivb- : jb +2 p0__6 : hsw+ +2 p0_5 : wsm- : SSE2 : pcmpeqb : _mm_cmpeq_epi8 +2 p_15 : snb-bdw +2 p01 : skl+ +1 p0 : SSE2 : pmovmskb : _mm_movemask_epi8 +*/ +/* + v24.00: the code was fixed for more compatibility with original-ms-cab-decoder. + for ((Int32)translationSize >= 0) : LZX specification shows the code with signed Int32. + for ((Int32)translationSize < 0) : no specification for that case, but we support that case. + We suppose our code now is compatible with original-ms-cab-decoder. + + Starting byte of data stream (real_pos == 0) is special corner case, + where we don't need any conversion (as in original-ms-cab-decoder). + Our optimization: we use unsigned (UInt32 pos) (pos = -1 - real_pos). + So (pos) is always negative: ((Int32)pos < 0). + It allows us to use simple comparison (v > pos) instead of more complex comparisons. +*/ +// (p) will point 5 bytes after 0xe8 byte: +// pos == -1 - (p - 5 - data_start) == 4 + data_start - p +// (FILTER_PROCESSED_SIZE_DELTA == 4) is optimized value for better speed in some compilers: +#define FILTER_PROCESSED_SIZE_DELTA 4 + +#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_OR_ARM64) + // optimized branch: + // size_t must be at least 32-bit for this branch. + #if 1 // use 1 for simpler code + // use integer (low 32 bits of pointer) instead of pointer + #define X86_FILTER_PREPARE processedSize4 = (UInt32)(size_t)(ptrdiff_t)data + \ + (UInt32)(4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = processedSize4 - (UInt32)(size_t)(ptrdiff_t)p; + #else + // note: (dataStart) pointer can point out of array ranges: + #define X86_FILTER_PREPARE const Byte *dataStart = data + \ + (4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = (UInt32)(size_t)(dataStart - p); + #endif +#else + // non-optimized branch for unusual platforms (16-bit size_t or unusual size_t): + #define X86_FILTER_PREPARE processedSize4 = \ + (UInt32)(4 - FILTER_PROCESSED_SIZE_DELTA) - processedSize4; + #define X86_FILTER_CALC_pos(p) const UInt32 pos = processedSize4 - (UInt32)(size_t)(p - data); +#endif + +#define X86_TRANSLATE_PRE(p) \ + UInt32 v = GetUi32((p) - 4); + +#define X86_TRANSLATE_POST(p) \ + { \ + X86_FILTER_CALC_pos(p) \ + if (v < translationSize) { \ + UPDATE_STAT(g_stats_Num_x86[0]++;) \ + v += pos + 1; \ + SetUi32((p) - 4, v) \ + } \ + else if (v > pos) { \ + UPDATE_STAT(g_stats_Num_x86[1]++;) \ + v += translationSize; \ + SetUi32((p) - 4, v) \ + } else { UPDATE_STAT(g_stats_Num_x86[2]++;) } \ + } + + +/* + if ( defined(Z7_LZX_X86_FILTER_USE_SSE2) + && defined(Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED)) + the function can read up to aligned_for_32_up_from(size) bytes in (data). +*/ +// processedSize < (1 << 30) +Z7_NO_INLINE +static void x86_Filter4(Byte *data, size_t size, UInt32 processedSize4, UInt32 translationSize) +{ + const size_t kResidue = 10; + if (size <= kResidue) + return; + Byte * const lim = data + size - kResidue + 4; + const Byte save = lim[0]; + lim[0] = 0xe8; + X86_FILTER_PREPARE + Byte *p = data; + +#define FILTER_RETURN_IF_LIM(_p_) if (_p_ > lim) { lim[0] = save; return; } + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2 + +// sse2-aligned/sse2-unaligned provide same speed on real data. +// but the code is smaller for sse2-unaligned version. +// for debug : define it to get alternative version with aligned 128-bit reads: +// #define Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + +#define FILTER_MASK_INT UInt32 +#define FILTER_NUM_VECTORS_IN_CHUNK 2 +#define FILTER_CHUNK_BYTES_OFFSET (16 * FILTER_NUM_VECTORS_IN_CHUNK - 5) + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + // aligned version doesn't uses additional space if buf size is aligned for 32 + #define k_Filter_OutBufSize_Add 0 + #define k_Filter_OutBufSize_AlignMask (16 * FILTER_NUM_VECTORS_IN_CHUNK - 1) + #define FILTER_LOAD_128(p) _mm_load_si128 ((const __m128i *)(const void *)(p)) +#else + #define k_Filter_OutBufSize_Add (16 * FILTER_NUM_VECTORS_IN_CHUNK) + #define k_Filter_OutBufSize_AlignMask 0 + #define FILTER_LOAD_128(p) _mm_loadu_si128((const __m128i *)(const void *)(p)) +#endif + +#define GET_E8_MASK(dest, dest1, p) \ +{ \ + __m128i v0 = FILTER_LOAD_128(p); \ + __m128i v1 = FILTER_LOAD_128(p + 16); \ + p += 16 * FILTER_NUM_VECTORS_IN_CHUNK; \ + v0 = _mm_cmpeq_epi8(v0, k_e8_Vector); \ + v1 = _mm_cmpeq_epi8(v1, k_e8_Vector); \ + dest = (unsigned)_mm_movemask_epi8(v0); \ + dest1 = (unsigned)_mm_movemask_epi8(v1); \ +} + + const __m128i k_e8_Vector = _mm_set1_epi32((Int32)(UInt32)0xe8e8e8e8); + for (;;) + { + // for debug: define it for smaller code: + // #define Z7_LZX_X86_FILTER_CALC_IN_LOOP + // without Z7_LZX_X86_FILTER_CALC_IN_LOOP, we can get faster and simpler loop + FILTER_MASK_INT mask; + { + FILTER_MASK_INT mask1; + do + { + GET_E8_MASK(mask, mask1, p) + #ifndef Z7_LZX_X86_FILTER_CALC_IN_LOOP + mask += mask1; + #else + mask |= mask1 << 16; + #endif + } + while (!mask); + + #ifndef Z7_LZX_X86_FILTER_CALC_IN_LOOP + mask -= mask1; + mask |= mask1 << 16; + #endif + } + +#ifdef Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + for (;;) + { + ctz_type index; + typedef + #ifdef MY_CPU_64BIT + UInt64 + #else + UInt32 + #endif + SUPER_MASK_INT; + SUPER_MASK_INT superMask; + { + MY_CTZ(index, mask); + Byte *p2 = p - FILTER_CHUNK_BYTES_OFFSET + (unsigned)index; + X86_TRANSLATE_PRE(p2) + superMask = ~(SUPER_MASK_INT)0x1f << index; + FILTER_RETURN_IF_LIM(p2) + X86_TRANSLATE_POST(p2) + mask &= (UInt32)superMask; + } + if (mask) + continue; + if (index <= FILTER_CHUNK_BYTES_OFFSET) + break; + { + FILTER_MASK_INT mask1; + GET_E8_MASK(mask, mask1, p) + mask &= + #ifdef MY_CPU_64BIT + (UInt32)(superMask >> 32); + #else + ((FILTER_MASK_INT)0 - 1) << ((int)index - FILTER_CHUNK_BYTES_OFFSET); + #endif + mask |= mask1 << 16; + } + if (!mask) + break; + } +#else // ! Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + { + // we use simplest version without loop: + // for (;;) + { + ctz_type index; + MY_CTZ(index, mask); + /* + printf("\np=%p, mask=%8x, index = %2d, p + index = %x\n", + (p - 16 * FILTER_NUM_VECTORS_IN_CHUNK), (unsigned)mask, + (unsigned)index, (unsigned)((unsigned)(ptrdiff_t)(p - 16 * FILTER_NUM_VECTORS_IN_CHUNK) + index)); + */ + p += (size_t)(unsigned)index - FILTER_CHUNK_BYTES_OFFSET; + FILTER_RETURN_IF_LIM(p) + // mask &= ~(FILTER_MASK_INT)0x1f << index; mask >>= index; + X86_TRANSLATE_PRE(p) + X86_TRANSLATE_POST(p) + // if (!mask) break; // p += 16 * FILTER_NUM_VECTORS_IN_CHUNK; + } + } +#endif // ! Z7_LZX_X86_FILTER_USE_SSE2_ALIGNED + } + +#else // ! Z7_LZX_X86_FILTER_USE_SSE2 + +#define k_Filter_OutBufSize_Add 0 +#define k_Filter_OutBufSize_AlignMask 0 + + + for (;;) + { + for (;;) + { + if (p[0] == 0xe8) { p += 5; break; } + if (p[1] == 0xe8) { p += 6; break; } + if (p[2] == 0xe8) { p += 7; break; } + p += 4; + if (p[-1] == 0xe8) { p += 4; break; } + } + FILTER_RETURN_IF_LIM(p) + X86_TRANSLATE_PRE(p) + X86_TRANSLATE_POST(p) + } + +#endif // ! Z7_LZX_X86_FILTER_USE_SSE2 +} + + +CDecoder::CDecoder() throw(): + _win(NULL), + _isUncompressedBlock(false), + _skipByte(false), + _keepHistory(false), + _keepHistoryForNext(true), + _needAlloc(true), + _wimMode(false), + _numDictBits(15), + _unpackBlockSize(0), + _x86_translationSize(0), + _x86_buf(NULL), + _unpackedData(NULL) +{ + { + // it's better to get empty virtual entries, if mispredicted value can be used: + memset(_reps, 0, kPosSlotOffset * sizeof(_reps[0])); + memset(_extra, 0, kPosSlotOffset); +#define SET_NUM_BITS(i) i // #define NUM_BITS_DELTA 31 + _extra[kPosSlotOffset + 0] = SET_NUM_BITS(0); + _extra[kPosSlotOffset + 1] = SET_NUM_BITS(0); + // reps[0] = 0 - (kNumReps - 1); + // reps[1] = 1 - (kNumReps - 1); + UInt32 a = 2 - (kNumReps - 1); + UInt32 delta = 1; + unsigned i; + for (i = 0; i < kNumLinearPosSlotBits; i++) + { + _extra[(size_t)i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _extra[(size_t)i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _reps [(size_t)i * 2 + 2 + kPosSlotOffset] = a; a += delta; + _reps [(size_t)i * 2 + 3 + kPosSlotOffset] = a; a += delta; + delta += delta; + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + { + _extra[(size_t)i + kPosSlotOffset] = SET_NUM_BITS(kNumLinearPosSlotBits); + _reps [(size_t)i + kPosSlotOffset] = a; + a += (UInt32)1 << kNumLinearPosSlotBits; + } + } +} + +CDecoder::~CDecoder() throw() +{ + if (_needAlloc) + // BigFree + z7_AlignedFree + (_win); + z7_AlignedFree(_x86_buf); +} + +HRESULT CDecoder::Flush() throw() +{ + // UInt32 t = _x86_processedSize; for (int y = 0; y < 50; y++) { _x86_processedSize = t; // benchmark: (branch predicted) + if (_x86_translationSize != 0) + { + Byte *destData = _win + _writePos; + const UInt32 curSize = _pos - _writePos; + if (_keepHistoryForNext) + { + const size_t kChunkSize = (size_t)1 << 15; + if (curSize > kChunkSize) + return E_NOTIMPL; + if (!_x86_buf) + { + // (kChunkSize % 32 == 0) is required in some cases, because + // the filter can read data by 32-bytes chunks in some cases. + // if (chunk_size > (1 << 15)) is possible, then we must the code: + const size_t kAllocSize = kChunkSize + k_Filter_OutBufSize_Add; + _x86_buf = (Byte *)z7_AlignedAlloc(kAllocSize); + if (!_x86_buf) + return E_OUTOFMEMORY; + #if 0 != k_Filter_OutBufSize_Add || \ + 0 != k_Filter_OutBufSize_AlignMask + // x86_Filter4() can read after curSize. + // So we set all data to zero to prevent reading of uninitialized data: + memset(_x86_buf, 0, kAllocSize); // optional + #endif + } + // for (int yy = 0; yy < 1; yy++) // for debug + memcpy(_x86_buf, destData, curSize); + _unpackedData = _x86_buf; + destData = _x86_buf; + } + else + { + // x86_Filter4() can overread after (curSize), + // so we can do memset() after (curSize): + // k_Filter_OutBufSize_AlignMask also can be used + // if (!_overDict) memset(destData + curSize, 0, k_Filter_OutBufSize_Add); + } + x86_Filter4(destData, curSize, _x86_processedSize - FILTER_PROCESSED_SIZE_DELTA, _x86_translationSize); + _x86_processedSize += (UInt32)curSize; + if (_x86_processedSize >= ((UInt32)1 << 30)) + _x86_translationSize = 0; + } + // } + return S_OK; +} + + + +// (NUM_DELTA_BYTES == 2) reduces the code in main loop. +#if 1 + #define NUM_DELTA_BYTES 2 +#else + #define NUM_DELTA_BYTES 0 +#endif + +#define NUM_DELTA_BIT_OFFSET_BITS (NUM_DELTA_BYTES * 8) + +#if NUM_DELTA_BIT_OFFSET_BITS > 0 + #define DECODE_ERROR_CODE 0 + #define IS_OVERFLOW_bitOffset(bo) ((bo) >= 0) + // ( >= 0) comparison after bitOffset change gives simpler commands than ( > 0) comparison +#else + #define DECODE_ERROR_CODE 1 + #define IS_OVERFLOW_bitOffset(bo) ((bo) > 0) +#endif + +// (numBits != 0) +#define GET_VAL_BASE(numBits) (_value >> (32 - (numBits))) + +#define Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, check_op, error_op) \ + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huff, kNumHuffmanBits, kNumTableBits, \ + _value, check_op, error_op, move_pos_op, NORMALIZE, bs) + +#define Z7_LZX_HUFF_DECODE_CHECK_YES(sym, huff, kNumTableBits, move_pos_op) \ + Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, { return DECODE_ERROR_CODE; }) + +#define Z7_LZX_HUFF_DECODE_CHECK_NO( sym, huff, kNumTableBits, move_pos_op) \ + Z7_LZX_HUFF_DECODE( sym, huff, kNumTableBits, move_pos_op, \ + Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {}) + +#define NORMALIZE \ +{ \ + const Byte *ptr = _buf + (_bitOffset >> 4) * 2; \ + /* _value = (((UInt32)GetUi16(ptr) << 16) | GetUi16(ptr + 2)) << (_bitOffset & 15); */ \ + const UInt32 v = GetUi32(ptr); \ + _value = rotlFixed (v, ((int)_bitOffset & 15) + 16); \ +} + +#define MOVE_POS(bs, numBits) \ +{ \ + _bitOffset += numBits; \ +} + +#define MOVE_POS_STAT(bs, numBits) \ +{ \ + UPDATE_STAT(g_stats_len_levels[numBits]++;) \ + MOVE_POS(bs, numBits); \ +} + +#define MOVE_POS_CHECK(bs, numBits) \ +{ \ + if (IS_OVERFLOW_bitOffset(_bitOffset += numBits)) return DECODE_ERROR_CODE; \ +} + +#define MOVE_POS_CHECK_STAT(bs, numBits) \ +{ \ + UPDATE_STAT(g_stats_main_levels[numBits]++;) \ + MOVE_POS_CHECK(bs, numBits) \ +} + + +// (numBits == 0) is supported + +#ifdef Z7_HUFF_USE_64BIT_LIMIT + +#define MACRO_ReadBitsBig_pre(numBits) \ +{ \ + _bitOffset += (numBits); \ + _value >>= 32 - (numBits); \ +} + +#else + +#define MACRO_ReadBitsBig_pre(numBits) \ +{ \ + _bitOffset += (numBits); \ + _value = (UInt32)((UInt32)_value >> 1 >> (31 ^ (numBits))); \ +} + +#endif + + +#define MACRO_ReadBitsBig_add(dest) \ + { dest += (UInt32)_value; } + +#define MACRO_ReadBitsBig_add3(dest) \ + { dest += (UInt32)(_value) << 3; } + + +// (numBits != 0) +#define MACRO_ReadBits_NonZero(val, numBits) \ +{ \ + val = (UInt32)(_value >> (32 - (numBits))); \ + MOVE_POS(bs, numBits); \ + NORMALIZE \ +} + + +struct CBitDecoder +{ + ptrdiff_t _bitOffset; + const Byte *_buf; + + Z7_FORCE_INLINE + UInt32 GetVal() const + { + const Byte *ptr = _buf + (_bitOffset >> 4) * 2; + const UInt32 v = GetUi32(ptr); + return rotlFixed (v, ((int)_bitOffset & 15) + 16); + } + + Z7_FORCE_INLINE + bool IsOverRead() const + { + return _bitOffset > (int)(0 - NUM_DELTA_BIT_OFFSET_BITS); + } + + + Z7_FORCE_INLINE + bool WasBitStreamFinishedOK() const + { + // we check that all 0-15 unused bits are zeros: + if (_bitOffset == 0 - NUM_DELTA_BIT_OFFSET_BITS) + return true; + if ((_bitOffset + NUM_DELTA_BIT_OFFSET_BITS + 15) & ~(ptrdiff_t)15) + return false; + const Byte *ptr = _buf - NUM_DELTA_BYTES - 2; + if ((UInt16)(GetUi16(ptr) << (_bitOffset & 15))) + return false; + return true; + } + + // (numBits != 0) + Z7_FORCE_INLINE + UInt32 ReadBits_NonZero(unsigned numBits) throw() + { + const UInt32 val = GetVal() >> (32 - numBits); + _bitOffset += numBits; + return val; + } +}; + + +class CBitByteDecoder: public CBitDecoder +{ + size_t _size; +public: + + Z7_FORCE_INLINE + void Init_ByteMode(const Byte *data, size_t size) + { + _buf = data; + _size = size; + } + + Z7_FORCE_INLINE + void Init_BitMode(const Byte *data, size_t size) + { + _size = size & 1; + size &= ~(size_t)1; + _buf = data + size + NUM_DELTA_BYTES; + _bitOffset = 0 - (ptrdiff_t)(size * 8) - NUM_DELTA_BIT_OFFSET_BITS; + } + + Z7_FORCE_INLINE + void Switch_To_BitMode() + { + Init_BitMode(_buf, _size); + } + + Z7_FORCE_INLINE + bool Switch_To_ByteMode() + { + /* here we check that unused bits in high 16-bits word are zeros. + If high word is full (all 16-bits are unused), + we check that all 16-bits are zeros. + So we check and skip (1-16 bits) unused bits */ + if ((GetVal() >> (16 + (_bitOffset & 15))) != 0) + return false; + _bitOffset += 16; + _bitOffset &= ~(ptrdiff_t)15; + if (_bitOffset > 0 - NUM_DELTA_BIT_OFFSET_BITS) + return false; + const ptrdiff_t delta = _bitOffset >> 3; + _size = (size_t)((ptrdiff_t)(_size) - delta - NUM_DELTA_BYTES); + _buf += delta; + // _bitOffset = 0; // optional + return true; + } + + Z7_FORCE_INLINE + size_t GetRem() const { return _size; } + + Z7_FORCE_INLINE + UInt32 ReadUInt32() + { + const Byte *ptr = _buf; + const UInt32 v = GetUi32(ptr); + _buf += 4; + _size -= 4; + return v; + } + + Z7_FORCE_INLINE + void CopyTo(Byte *dest, size_t size) + { + memcpy(dest, _buf, size); + _buf += size; + _size -= size; + } + + Z7_FORCE_INLINE + bool IsOneDirectByteLeft() const + { + return GetRem() == 1; + } + + Z7_FORCE_INLINE + Byte DirectReadByte() + { + _size--; + return *_buf++; + } +}; + + +// numBits != 0 +// Z7_FORCE_INLINE +Z7_NO_INLINE +static +UInt32 ReadBits(CBitDecoder &_bitStream, unsigned numBits) +{ + return _bitStream.ReadBits_NonZero(numBits); +} + +#define RIF(x) { if (!(x)) return false; } + + +/* +MSVC compiler adds extra move operation, + if we access array with 32-bit index + array[calc_index_32_bit(32-bit_var)] + where calc_index_32_bit operations are: ((unsigned)a>>cnt), &, ^, | + clang is also affected for ((unsigned)a>>cnt) in byte array. +*/ + +// it can overread input buffer for 7-17 bytes. +// (levels != levelsEnd) +Z7_NO_INLINE +static ptrdiff_t ReadTable(ptrdiff_t _bitOffset, const Byte *_buf, Byte *levels, const Byte *levelsEnd) +{ + const unsigned kNumTableBits_Level = 7; + NHuffman::CDecoder256 _levelDecoder; + NHuffman::CValueInt _value; + // optional check to reduce size of overread zone: + if (_bitOffset > (int)0 - (int)NUM_DELTA_BIT_OFFSET_BITS - (int)(kLevelTableSize * kNumLevelBits)) + return DECODE_ERROR_CODE; + NORMALIZE + { + Byte levels2[kLevelTableSize / 4 * 4]; + for (size_t i = 0; i < kLevelTableSize / 4 * 4; i += 4) + { + UInt32 val; + MACRO_ReadBits_NonZero(val, kNumLevelBits * 4) + levels2[i + 0] = (Byte)((val >> (3 * kNumLevelBits))); + levels2[i + 1] = (Byte)((val >> (2 * kNumLevelBits)) & ((1u << kNumLevelBits) - 1)); + levels2[i + 2] = (Byte)((Byte)val >> (1 * kNumLevelBits)); + levels2[i + 3] = (Byte)((val) & ((1u << kNumLevelBits) - 1)); + } + RIF(_levelDecoder.Build(levels2, NHuffman::k_BuildMode_Full)) + } + + do + { + unsigned sym; + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, &_levelDecoder, kNumTableBits_Level, MOVE_POS_CHECK) + // Z7_HUFF_DECODE_CHECK(sym, &_levelDecoder, kNumHuffmanBits, kNumTableBits_Level, &bitStream, return false) + // sym = _levelDecoder.Decode(&bitStream); + // if (!_levelDecoder.Decode_SymCheck_MovePosCheck(&bitStream, sym)) return false; + + if (sym <= kNumHuffmanBits) + { + int delta = (int)*levels - (int)sym; + delta += delta < 0 ? kNumHuffmanBits + 1 : 0; + *levels++ = (Byte)delta; + continue; + } + + unsigned num; + int symbol; + + if (sym < kLevelSym_Same) + { + // sym -= kLevelSym_Zero1; + MACRO_ReadBits_NonZero(num, kLevelSym_Zero1_NumBits + (sym - kLevelSym_Zero1)) + num += (sym << kLevelSym_Zero1_NumBits) - (kLevelSym_Zero1 << kLevelSym_Zero1_NumBits) + kLevelSym_Zero1_Start; + symbol = 0; + } + // else if (sym != kLevelSym_Same) return DECODE_ERROR_CODE; + else // (sym == kLevelSym_Same) + { + MACRO_ReadBits_NonZero(num, kLevelSym_Same_NumBits) + num += kLevelSym_Same_Start; + // + (unsigned)bitStream.ReadBitsSmall(kLevelSym_Same_NumBits); + // Z7_HUFF_DECODE_CHECK(sym, &_levelDecoder, kNumHuffmanBits, kNumTableBits_Level, &bitStream, return DECODE_ERROR_CODE) + // if (!_levelDecoder.Decode2(&bitStream, sym)) return DECODE_ERROR_CODE; + // sym = _levelDecoder.Decode(&bitStream); + + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, &_levelDecoder, kNumTableBits_Level, MOVE_POS) + + if (sym > kNumHuffmanBits) return DECODE_ERROR_CODE; + symbol = *levels - (int)sym; + symbol += symbol < 0 ? kNumHuffmanBits + 1 : 0; + } + + if (num > (size_t)(levelsEnd - levels)) + return false; + const Byte *limit = levels + num; + do + *levels++ = (Byte)symbol; + while (levels != limit); + } + while (levels != levelsEnd); + + return _bitOffset; +} + + +static const unsigned kPosSlotDelta = 256 / kNumLenSlots - kPosSlotOffset; + + +#define READ_TABLE(_bitStream, levels, levelsEnd) \ +{ \ + _bitStream._bitOffset = ReadTable(_bitStream._bitOffset, _bitStream._buf, levels, levelsEnd); \ + if (_bitStream.IsOverRead()) return false; \ +} + +// can over-read input buffer for less than 32 bytes +bool CDecoder::ReadTables(CBitByteDecoder &_bitStream) throw() +{ + UPDATE_STAT(g_stats_NumTables++;) + { + const unsigned blockType = (unsigned)ReadBits(_bitStream, kBlockType_NumBits); + // if (blockType > kBlockType_Uncompressed || blockType == 0) + if ((unsigned)(blockType - 1) > kBlockType_Uncompressed - 1) + return false; + _unpackBlockSize = 1u << 15; + if (!_wimMode || ReadBits(_bitStream, 1) == 0) + { + _unpackBlockSize = ReadBits(_bitStream, 16); + // wimlib supports chunks larger than 32KB (unsupported my MS wim). + if (!_wimMode || _numDictBits >= 16) + { + _unpackBlockSize <<= 8; + _unpackBlockSize |= ReadBits(_bitStream, 8); + } + } + + PRF(printf("\nBlockSize = %6d %s ", _unpackBlockSize, (_pos & 1) ? "@@@" : " ")); + + _isUncompressedBlock = (blockType == kBlockType_Uncompressed); + _skipByte = false; + + if (_isUncompressedBlock) + { + _skipByte = ((_unpackBlockSize & 1) != 0); + // printf("\n UncompressedBlock %d", _unpackBlockSize); + PRF(printf(" UncompressedBlock ");) + // if (_unpackBlockSize & 1) { PRF(printf(" ######### ")); } + if (!_bitStream.Switch_To_ByteMode()) + return false; + if (_bitStream.GetRem() < kNumReps * 4) + return false; + for (unsigned i = 0; i < kNumReps; i++) + { + const UInt32 rep = _bitStream.ReadUInt32(); + // here we allow only such values for (rep) that can be set also by LZ code: + if (rep == 0 || rep > _winSize - kNumReps) + return false; + _reps[(size_t)i + kPosSlotOffset] = rep; + } + // printf("\n"); + return true; + } + + // _numAlignBits = 64; + // const UInt32 k_numAlignBits_PosSlots_MAX = 64 + kPosSlotDelta; + // _numAlignBits_PosSlots = k_numAlignBits_PosSlots_MAX; + const UInt32 k_numAlignBits_Dist_MAX = (UInt32)(Int32)-1; + _numAlignBits_Dist = k_numAlignBits_Dist_MAX; + if (blockType == kBlockType_Aligned) + { + Byte levels[kAlignTableSize]; + // unsigned not0 = 0; + unsigned not3 = 0; + for (unsigned i = 0; i < kAlignTableSize; i++) + { + const unsigned val = ReadBits(_bitStream, kNumAlignLevelBits); + levels[i] = (Byte)val; + // not0 |= val; + not3 |= (val ^ 3); + } + // static unsigned number = 0, all = 0; all++; + // if (!not0) return false; // Build(true) will test this case + if (not3) + { + // _numAlignBits_PosSlots = (kNumAlignBits + 1) * 2 + kPosSlotDelta; + // _numAlignBits = kNumAlignBits; + _numAlignBits_Dist = (1u << (kNumAlignBits + 1)) - (kNumReps - 1); + RIF(_alignDecoder.Build(levels, true)) // full + } + // else { number++; if (number % 4 == 0) printf("\nnumber= %u : %u%%", number, number * 100 / all); } + } + // if (_numAlignBits_PosSlots == k_numAlignBits_PosSlots_MAX) + if (_numAlignBits_Dist == k_numAlignBits_Dist_MAX) + { + size_t i; + for (i = 3; i < kNumLinearPosSlotBits; i++) + { + _extra[i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + _extra[i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i)); + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + _extra[i + kPosSlotOffset] = (Byte)SET_NUM_BITS(kNumLinearPosSlotBits); + } + else + { + size_t i; + for (i = 3; i < kNumLinearPosSlotBits; i++) + { + _extra[i * 2 + 2 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i) - 3); + _extra[i * 2 + 3 + kPosSlotOffset] = (Byte)(SET_NUM_BITS(i) - 3); + } + for (i = kNumLinearPosSlotBits * 2 + 2; i < kNumPosSlots; i++) + _extra[i + kPosSlotOffset] = (Byte)(SET_NUM_BITS(kNumLinearPosSlotBits) - 3); + } + } + + READ_TABLE(_bitStream, _mainLevels, _mainLevels + 256) + READ_TABLE(_bitStream, _mainLevels + 256, _mainLevels + 256 + _numPosLenSlots) + const unsigned end = 256 + _numPosLenSlots; + memset(_mainLevels + end, 0, kMainTableSize - end); + // #define NUM_CYC 1 + // unsigned j; for (j = 0; j < NUM_CYC; j++) + RIF(_mainDecoder.Build(_mainLevels, NHuffman::k_BuildMode_Full)) + // if (kNumLenSymols_Big_Start) + memset(_lenLevels, 0, kNumLenSymols_Big_Start); + READ_TABLE(_bitStream, + _lenLevels + kNumLenSymols_Big_Start, + _lenLevels + kNumLenSymols_Big_Start + kNumLenSymbols) + // for (j = 0; j < NUM_CYC; j++) + RIF(_lenDecoder.Build(_lenLevels, NHuffman::k_BuildMode_Full_or_Empty)) + return true; +} + + + +static ptrdiff_t CodeLz(CDecoder *dec, size_t next, ptrdiff_t _bitOffset, const Byte *_buf) throw() +{ + { + Byte *const win = dec->_win; + const UInt32 winSize = dec->_winSize; + Byte *pos = win + dec->_pos; + const Byte * const posEnd = pos + next; + NHuffman::CValueInt _value; + + NORMALIZE + +#if 1 + #define HUFF_DEC_PREFIX dec-> +#else + const NHuffman::CDecoder _mainDecoder = dec->_mainDecoder; + const NHuffman::CDecoder256 _lenDecoder = dec->_lenDecoder; + const NHuffman::CDecoder7b _alignDecoder = dec->_alignDecoder; + #define HUFF_DEC_PREFIX +#endif + + do + { + unsigned sym; + // printf("\npos = %6u", pos - win); + { + const NHuffman::CDecoder + *mainDecoder = & HUFF_DEC_PREFIX _mainDecoder; + Z7_LZX_HUFF_DECODE_CHECK_NO(sym, mainDecoder, kNumTableBits_Main, MOVE_POS_CHECK_STAT) + } + // if (!_mainDecoder.Decode_SymCheck_MovePosCheck(&bitStream, sym)) return DECODE_ERROR_CODE; + // sym = _mainDecoder.Decode(&bitStream); + // if (bitStream.WasExtraReadError_Fast()) return DECODE_ERROR_CODE; + + // printf(" sym = %3x", sym); + UPDATE_STAT(g_stats_main[sym]++;) + + if (sym < 256) + { + UPDATE_STAT(g_stats_NumLits++;) + *pos++ = (Byte)sym; + } + else + { + // sym -= 256; + // if (sym >= _numPosLenSlots) return DECODE_ERROR_CODE; + const unsigned posSlot = sym / kNumLenSlots; + unsigned len = sym % kNumLenSlots + kMatchMinLen; + if (len == kNumLenSlots - 1 + kMatchMinLen) + { + const NHuffman::CDecoder256 + *lenDecoder = & HUFF_DEC_PREFIX _lenDecoder; + Z7_LZX_HUFF_DECODE_CHECK_YES(len, lenDecoder, kNumTableBits_Len, MOVE_POS_STAT) + // if (!_lenDecoder.Decode2(&bitStream, len)) return DECODE_ERROR_CODE; + // len = _lenDecoder.Decode(&bitStream); + // if (len >= kNumLenSymbols) return DECODE_ERROR_CODE; + UPDATE_STAT(g_stats_len[len - kNumLenSymols_Big_Start]++;) + len += kNumLenSlots - 1 + kMatchMinLen - kNumLenSymols_Big_Start; + } + /* + if ((next -= len) < 0) + return DECODE_ERROR_CODE; + */ + UInt32 dist; + + dist = dec->_reps[(size_t)posSlot - kPosSlotDelta]; + if (posSlot < kNumReps + 256 / kNumLenSlots) + { + // if (posSlot != kNumReps + kPosSlotDelta) + // if (posSlot - (kNumReps + kPosSlotDelta + 1) < 2) + dec->_reps[(size_t)posSlot - kPosSlotDelta] = dec->_reps[kPosSlotOffset]; + /* + if (posSlot != kPosSlotDelta) + { + UInt32 temp = dist; + if (posSlot == kPosSlotDelta + 1) + { + dist = reps[1]; + reps[1] = temp; + } + else + { + dist = reps[2]; + reps[2] = temp; + } + // dist = reps[(size_t)(posSlot) - kPosSlotDelta]; + // reps[(size_t)(posSlot) - kPosSlotDelta] = reps[0]; + // reps[(size_t)(posSlot) - kPosSlotDelta] = temp; + } + */ + } + else // if (posSlot != kNumReps + kPosSlotDelta) + { + unsigned numDirectBits; +#if 0 + if (posSlot < kNumPowerPosSlots + kPosSlotDelta) + { + numDirectBits = (posSlot - 2 - kPosSlotDelta) >> 1; + dist = (UInt32)(2 | (posSlot & 1)) << numDirectBits; + } + else + { + numDirectBits = kNumLinearPosSlotBits; + dist = (UInt32)(posSlot - 0x22 - kPosSlotDelta) << kNumLinearPosSlotBits; + } + dist -= kNumReps - 1; +#else + numDirectBits = dec->_extra[(size_t)posSlot - kPosSlotDelta]; + // dist = reps[(size_t)(posSlot) - kPosSlotDelta]; +#endif + dec->_reps[kPosSlotOffset + 2] = + dec->_reps[kPosSlotOffset + 1]; + dec->_reps[kPosSlotOffset + 1] = + dec->_reps[kPosSlotOffset + 0]; + + // dist += val; dist += bitStream.ReadBitsBig(numDirectBits); + // if (posSlot >= _numAlignBits_PosSlots) + // if (numDirectBits >= _numAlignBits) + // if (val >= _numAlignBits_Dist) + // UInt32 val; MACRO_ReadBitsBig(val , numDirectBits) + // dist += val; + // dist += (UInt32)((UInt32)_value >> 1 >> (/* 31 ^ */ (numDirectBits))); + // MOVE_POS((numDirectBits ^ 31)) + MACRO_ReadBitsBig_pre(numDirectBits) + // dist += (UInt32)_value; + if (dist >= dec->_numAlignBits_Dist) + { + // if (numDirectBits != _numAlignBits) + { + // UInt32 val; + // dist -= (UInt32)_value; + MACRO_ReadBitsBig_add3(dist) + NORMALIZE + // dist += (val << kNumAlignBits); + // dist += bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits; + } + { + // const unsigned alignTemp = _alignDecoder.Decode(&bitStream); + const NHuffman::CDecoder7b *alignDecoder = & HUFF_DEC_PREFIX _alignDecoder; + unsigned alignTemp; + UPDATE_STAT(g_stats_NumAlign++;) + Z7_HUFF_DECODER_7B_DECODE(alignTemp, alignDecoder, GET_VAL_BASE, MOVE_POS, bs) + // NORMALIZE + // if (alignTemp >= kAlignTableSize) return DECODE_ERROR_CODE; + dist += alignTemp; + } + } + else + { + { + MACRO_ReadBitsBig_add(dist) + // dist += bitStream.ReadBitsSmall(numDirectBits - kNumAlignBits) << kNumAlignBits; + } + } + NORMALIZE + /* + else + { + UInt32 val; + MACRO_ReadBitsBig(val, numDirectBits) + dist += val; + // dist += bitStream.ReadBitsBig(numDirectBits); + } + */ + } + dec->_reps[kPosSlotOffset + 0] = dist; + + Byte *dest = pos; + if (len > (size_t)(posEnd - pos)) + return DECODE_ERROR_CODE; + Int32 srcPos = (Int32)(pos - win); + pos += len; + srcPos -= (Int32)dist; + if (srcPos < 0) // fast version + { + if (!dec->_overDict) + return DECODE_ERROR_CODE; + srcPos &= winSize - 1; + UInt32 rem = winSize - (UInt32)srcPos; + if (len > rem) + { + len -= rem; + const Byte *src = win + (UInt32)srcPos; + do + *dest++ = *src++; + while (--rem); + srcPos = 0; + } + } + CopyLzMatch(dest, win + (UInt32)srcPos, len, dist); + } + } + while (pos != posEnd); + + return _bitOffset; + } +} + + + + +// inSize != 0 +// outSize != 0 ??? +HRESULT CDecoder::CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) throw() +{ + // ((inSize & 1) != 0) case is possible, if current call will be finished with Uncompressed Block. + CBitByteDecoder _bitStream; + if (_keepHistory && _isUncompressedBlock) + _bitStream.Init_ByteMode(inData, inSize); + else + _bitStream.Init_BitMode(inData, inSize); + + if (!_keepHistory) + { + _isUncompressedBlock = false; + _skipByte = false; + _unpackBlockSize = 0; + memset(_mainLevels, 0, sizeof(_mainLevels)); + memset(_lenLevels, 0, sizeof(_lenLevels)); + { + _x86_translationSize = 12000000; + if (!_wimMode) + { + _x86_translationSize = 0; + if (ReadBits(_bitStream, 1) != 0) + { + UInt32 v = ReadBits(_bitStream, 16) << 16; + v |= ReadBits(_bitStream, 16); + _x86_translationSize = v; + } + } + _x86_processedSize = 0; + } + _reps[0 + kPosSlotOffset] = 1; + _reps[1 + kPosSlotOffset] = 1; + _reps[2 + kPosSlotOffset] = 1; + } + + while (outSize) + { + /* + // check it for bit mode only: + if (_bitStream.WasExtraReadError_Fast()) + return S_FALSE; + */ + if (_unpackBlockSize == 0) + { + if (_skipByte) + { + if (_bitStream.GetRem() < 1) + return S_FALSE; + if (_bitStream.DirectReadByte() != 0) + return S_FALSE; + } + if (_isUncompressedBlock) + _bitStream.Switch_To_BitMode(); + if (!ReadTables(_bitStream)) + return S_FALSE; + continue; + } + + // _unpackBlockSize != 0 + UInt32 next = _unpackBlockSize; + if (next > outSize) + next = outSize; + // next != 0 + + // PRF(printf("\nnext = %d", (unsigned)next);) + + if (_isUncompressedBlock) + { + if (_bitStream.GetRem() < next) + return S_FALSE; + _bitStream.CopyTo(_win + _pos, next); + _pos += next; + _unpackBlockSize -= next; + } + else + { + _unpackBlockSize -= next; + _bitStream._bitOffset = CodeLz(this, next, _bitStream._bitOffset, _bitStream._buf); + if (_bitStream.IsOverRead()) + return S_FALSE; + _pos += next; + } + outSize -= next; + } + + // outSize == 0 + + if (_isUncompressedBlock) + { + /* we don't know where skipByte can be placed, if it's end of chunk: + 1) in current chunk - there are such cab archives, if chunk is last + 2) in next chunk - are there such archives ? */ + if (_unpackBlockSize == 0 + && _skipByte + // && outSize == 0 + && _bitStream.IsOneDirectByteLeft()) + { + _skipByte = false; + if (_bitStream.DirectReadByte() != 0) + return S_FALSE; + } + } + + if (_bitStream.GetRem() != 0) + return S_FALSE; + if (!_isUncompressedBlock) + if (!_bitStream.WasBitStreamFinishedOK()) + return S_FALSE; + return S_OK; +} + + +#if k_Filter_OutBufSize_Add > k_Lz_OutBufSize_Add + #define k_OutBufSize_Add k_Filter_OutBufSize_Add +#else + #define k_OutBufSize_Add k_Lz_OutBufSize_Add +#endif + +HRESULT CDecoder::Code_WithExceedReadWrite(const Byte *inData, size_t inSize, UInt32 outSize) throw() +{ + if (!_keepHistory) + { + _pos = 0; + _overDict = false; + } + else if (_pos == _winSize) + { + _pos = 0; + _overDict = true; +#if k_OutBufSize_Add > 0 + // data after (_winSize) can be used, because we can use overwrite. + // memset(_win + _winSize, 0, k_OutBufSize_Add); +#endif + } + _writePos = _pos; + _unpackedData = _win + _pos; + + if (outSize > _winSize - _pos) + return S_FALSE; + + PRF(printf("\ninSize = %d", (unsigned)inSize);) + PRF(if ((inSize & 1) != 0) printf("---------");) + + if (inSize == 0) + return S_FALSE; + const HRESULT res = CodeSpec(inData, inSize, outSize); + const HRESULT res2 = Flush(); + return (res == S_OK ? res2 : res); +} + + +HRESULT CDecoder::SetParams2(unsigned numDictBits) throw() +{ + if (numDictBits < kNumDictBits_Min || + numDictBits > kNumDictBits_Max) + return E_INVALIDARG; + _numDictBits = (Byte)numDictBits; + const unsigned numPosSlots2 = (numDictBits < 20) ? + numDictBits : 17 + (1u << (numDictBits - 18)); + _numPosLenSlots = numPosSlots2 * (kNumLenSlots * 2); + return S_OK; +} + + +HRESULT CDecoder::Set_DictBits_and_Alloc(unsigned numDictBits) throw() +{ + RINOK(SetParams2(numDictBits)) + const UInt32 newWinSize = (UInt32)1 << numDictBits; + if (_needAlloc) + { + if (!_win || newWinSize != _winSize) + { + // BigFree + z7_AlignedFree + (_win); + _winSize = 0; + const size_t alloc_size = newWinSize + k_OutBufSize_Add; + _win = (Byte *) + // BigAlloc + z7_AlignedAlloc + (alloc_size); + if (!_win) + return E_OUTOFMEMORY; + // optional: + memset(_win, 0, alloc_size); + } + } + _winSize = newWinSize; + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/LzxDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/LzxDecoder.h 2016-05-20 08:20:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/LzxDecoder.h 2024-01-07 16:00:00.000000000 +0000 @@ -1,246 +1,106 @@ -// LzxDecoder.h - -#ifndef __LZX_DECODER_H -#define __LZX_DECODER_H - -#include "../../../C/CpuArch.h" - -#include "../../Common/MyCom.h" - -#include "HuffmanDecoder.h" -#include "Lzx.h" - -namespace NCompress { -namespace NLzx { - -class CBitDecoder -{ - unsigned _bitPos; - UInt32 _value; - const Byte *_buf; - const Byte *_bufLim; - UInt32 _extraSize; -public: - - void Init(const Byte *data, size_t size) - { - _buf = data; - _bufLim = data + size - 1; - _bitPos = 0; - _extraSize = 0; - } - - size_t GetRem() const { return _bufLim + 1 - _buf; } - bool WasExtraReadError_Fast() const { return _extraSize > 4; } - - bool WasFinishedOK() const - { - if (_buf != _bufLim + 1) - return false; - if ((_bitPos >> 4) * 2 != _extraSize) - return false; - unsigned numBits = _bitPos & 15; - return (((_value >> (_bitPos - numBits)) & (((UInt32)1 << numBits) - 1)) == 0); - } - - void NormalizeSmall() - { - if (_bitPos <= 16) - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - } - - void NormalizeBig() - { - if (_bitPos <= 16) - { - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - if (_bitPos <= 16) - { - UInt32 val; - if (_buf >= _bufLim) - { - val = 0xFFFF; - _extraSize += 2; - } - else - { - val = GetUi16(_buf); - _buf += 2; - } - _value = (_value << 16) | val; - _bitPos += 16; - } - } - } - - UInt32 GetValue(unsigned numBits) const - { - return (_value >> (_bitPos - numBits)) & (((UInt32)1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - _bitPos -= numBits; - NormalizeSmall(); - } - - UInt32 ReadBitsSmall(unsigned numBits) - { - _bitPos -= numBits; - UInt32 val = (_value >> _bitPos) & (((UInt32)1 << numBits) - 1); - NormalizeSmall(); - return val; - } - - UInt32 ReadBitsBig(unsigned numBits) - { - _bitPos -= numBits; - UInt32 val = (_value >> _bitPos) & (((UInt32)1 << numBits) - 1); - NormalizeBig(); - return val; - } - - bool PrepareUncompressed() - { - if (_extraSize != 0) - return false; - unsigned numBits = _bitPos - 16; - if (((_value >> 16) & (((UInt32)1 << numBits) - 1)) != 0) - return false; - _buf -= 2; - _bitPos = 0; - return true; - } - - UInt32 ReadUInt32() - { - UInt32 v = GetUi32(_buf); - _buf += 4; - return v; - } - - void CopyTo(Byte *dest, size_t size) - { - memcpy(dest, _buf, size); - _buf += size; - } - - bool IsOneDirectByteLeft() const { return _buf == _bufLim && _extraSize == 0; } - - Byte DirectReadByte() - { - if (_buf > _bufLim) - { - _extraSize++; - return 0xFF; - } - return *_buf++; - } -}; - - -class CDecoder: - public IUnknown, - public CMyUnknownImp -{ - CBitDecoder _bitStream; - Byte *_win; - UInt32 _pos; - UInt32 _winSize; - - bool _overDict; - bool _isUncompressedBlock; - bool _skipByte; - unsigned _numAlignBits; - - UInt32 _reps[kNumReps]; - UInt32 _numPosLenSlots; - UInt32 _unpackBlockSize; - -public: - bool KeepHistoryForNext; - bool NeedAlloc; -private: - bool _keepHistory; - bool _wimMode; - unsigned _numDictBits; - UInt32 _writePos; - - Byte *_x86_buf; - UInt32 _x86_translationSize; - UInt32 _x86_processedSize; - - Byte *_unpackedData; - - NHuffman::CDecoder _mainDecoder; - NHuffman::CDecoder _lenDecoder; - NHuffman::CDecoder7b _alignDecoder; - NHuffman::CDecoder _levelDecoder; - - Byte _mainLevels[kMainTableSize]; - Byte _lenLevels[kNumLenSymbols]; - - HRESULT Flush(); - - UInt32 ReadBits(unsigned numBits); - bool ReadTable(Byte *levels, unsigned numSymbols); - bool ReadTables(); - - HRESULT CodeSpec(UInt32 size); - HRESULT SetParams2(unsigned numDictBits); -public: - CDecoder(bool wimMode = false); - ~CDecoder(); - - MY_UNKNOWN_IMP - - HRESULT SetExternalWindow(Byte *win, unsigned numDictBits) - { - NeedAlloc = false; - _win = win; - _winSize = (UInt32)1 << numDictBits; - return SetParams2(numDictBits); - } - - void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } - - HRESULT SetParams_and_Alloc(unsigned numDictBits); - - HRESULT Code(const Byte *inData, size_t inSize, UInt32 outSize); - - bool WasBlockFinished() const { return _unpackBlockSize == 0; } - const Byte *GetUnpackData() const { return _unpackedData; } - const UInt32 GetUnpackSize() const { return _pos - _writePos; } -}; - -}} - -#endif +// LzxDecoder.h + +#ifndef ZIP7_INC_LZX_DECODER_H +#define ZIP7_INC_LZX_DECODER_H + +#include "HuffmanDecoder.h" +#include "Lzx.h" + +namespace NCompress { +namespace NLzx { + +const unsigned kAdditionalOutputBufSize = 32 * 2; + +const unsigned kNumTableBits_Main = 11; +const unsigned kNumTableBits_Len = 8; + +// if (kNumLenSymols_Big <= 256) we can use NHuffman::CDecoder256 +// if (kNumLenSymols_Big > 256) we must use NHuffman::CDecoder +// const unsigned kNumLenSymols_Big_Start = kNumLenSlots - 1 + kMatchMinLen; // 8 - 1 + 2 +const unsigned kNumLenSymols_Big_Start = 0; +// const unsigned kNumLenSymols_Big_Start = 0; +const unsigned kNumLenSymols_Big = kNumLenSymols_Big_Start + kNumLenSymbols; + +#if 1 + // for smallest structure size: + const unsigned kPosSlotOffset = 0; +#else + // use virtual entries for mispredicted branches: + const unsigned kPosSlotOffset = 256 / kNumLenSlots; +#endif + +class CBitByteDecoder; + +class CDecoder +{ +public: + UInt32 _pos; + UInt32 _winSize; + Byte *_win; + + bool _overDict; + bool _isUncompressedBlock; + bool _skipByte; + bool _keepHistory; + bool _keepHistoryForNext; + bool _needAlloc; + bool _wimMode; + Byte _numDictBits; + + // unsigned _numAlignBits_PosSlots; + // unsigned _numAlignBits; + UInt32 _numAlignBits_Dist; +private: + unsigned _numPosLenSlots; + UInt32 _unpackBlockSize; + + UInt32 _writePos; + + UInt32 _x86_translationSize; + UInt32 _x86_processedSize; + Byte *_x86_buf; + + Byte *_unpackedData; +public: + Byte _extra[kPosSlotOffset + kNumPosSlots]; + UInt32 _reps[kPosSlotOffset + kNumPosSlots]; + + NHuffman::CDecoder _mainDecoder; + NHuffman::CDecoder256 _lenDecoder; + NHuffman::CDecoder7b _alignDecoder; +private: + Byte _mainLevels[kMainTableSize]; + Byte _lenLevels[kNumLenSymols_Big]; + + HRESULT Flush() throw(); + bool ReadTables(CBitByteDecoder &_bitStream) throw(); + + HRESULT CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) throw(); + HRESULT SetParams2(unsigned numDictBits) throw(); +public: + CDecoder() throw(); + ~CDecoder() throw(); + + void Set_WimMode(bool wimMode) { _wimMode = wimMode; } + void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; } + void Set_KeepHistoryForNext(bool keepHistoryForNext) { _keepHistoryForNext = keepHistoryForNext; } + + HRESULT Set_ExternalWindow_DictBits(Byte *win, unsigned numDictBits) + { + _needAlloc = false; + _win = win; + _winSize = (UInt32)1 << numDictBits; + return SetParams2(numDictBits); + } + HRESULT Set_DictBits_and_Alloc(unsigned numDictBits) throw(); + + HRESULT Code_WithExceedReadWrite(const Byte *inData, size_t inSize, UInt32 outSize) throw(); + + bool WasBlockFinished() const { return _unpackBlockSize == 0; } + const Byte *GetUnpackData() const { return _unpackedData; } + UInt32 GetUnpackSize() const { return _pos - _writePos; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Mtf8.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Mtf8.h --- p7zip-rar-16.02/CPP/7zip/Compress/Mtf8.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Mtf8.h 2024-12-17 18:00:00.000000000 +0000 @@ -1,191 +1,225 @@ -// Mtf8.h - -#ifndef __COMPRESS_MTF8_H -#define __COMPRESS_MTF8_H - -#include "../../../C/CpuArch.h" - -namespace NCompress { - -struct CMtf8Encoder -{ - Byte Buf[256]; - - unsigned FindAndMove(Byte v) - { - unsigned pos; - for (pos = 0; Buf[pos] != v; pos++); - unsigned resPos = pos; - for (; pos >= 8; pos -= 8) - { - Buf[pos] = Buf[pos - 1]; - Buf[pos - 1] = Buf[pos - 2]; - Buf[pos - 2] = Buf[pos - 3]; - Buf[pos - 3] = Buf[pos - 4]; - Buf[pos - 4] = Buf[pos - 5]; - Buf[pos - 5] = Buf[pos - 6]; - Buf[pos - 6] = Buf[pos - 7]; - Buf[pos - 7] = Buf[pos - 8]; - } - for (; pos != 0; pos--) - Buf[pos] = Buf[pos - 1]; - Buf[0] = v; - return resPos; - } -}; - -/* -struct CMtf8Decoder -{ - Byte Buf[256]; - - void Init(int) {}; - Byte GetHead() const { return Buf[0]; } - Byte GetAndMove(int pos) - { - Byte res = Buf[pos]; - for (; pos >= 8; pos -= 8) - { - Buf[pos] = Buf[pos - 1]; - Buf[pos - 1] = Buf[pos - 2]; - Buf[pos - 2] = Buf[pos - 3]; - Buf[pos - 3] = Buf[pos - 4]; - Buf[pos - 4] = Buf[pos - 5]; - Buf[pos - 5] = Buf[pos - 6]; - Buf[pos - 6] = Buf[pos - 7]; - Buf[pos - 7] = Buf[pos - 8]; - } - for (; pos > 0; pos--) - Buf[pos] = Buf[pos - 1]; - Buf[0] = res; - return res; - } -}; -*/ - -#ifdef MY_CPU_64BIT -typedef UInt64 CMtfVar; -#define MTF_MOVS 3 -#else -typedef UInt32 CMtfVar; -#define MTF_MOVS 2 -#endif - -#define MTF_MASK ((1 << MTF_MOVS) - 1) - - -struct CMtf8Decoder -{ - CMtfVar Buf[256 >> MTF_MOVS]; - - void StartInit() { memset(Buf, 0, sizeof(Buf)); } - void Add(unsigned pos, Byte val) { Buf[pos >> MTF_MOVS] |= ((CMtfVar)val << ((pos & MTF_MASK) << 3)); } - Byte GetHead() const { return (Byte)Buf[0]; } - Byte GetAndMove(unsigned pos) - { - UInt32 lim = ((UInt32)pos >> MTF_MOVS); - pos = (pos & MTF_MASK) << 3; - CMtfVar prev = (Buf[lim] >> pos) & 0xFF; - - UInt32 i = 0; - if ((lim & 1) != 0) - { - CMtfVar next = Buf[0]; - Buf[0] = (next << 8) | prev; - prev = (next >> (MTF_MASK << 3)); - i = 1; - lim -= 1; - } - for (; i < lim; i += 2) - { - CMtfVar n0 = Buf[i]; - CMtfVar n1 = Buf[i + 1]; - Buf[i ] = (n0 << 8) | prev; - Buf[i + 1] = (n1 << 8) | (n0 >> (MTF_MASK << 3)); - prev = (n1 >> (MTF_MASK << 3)); - } - CMtfVar next = Buf[i]; - CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); - Buf[i] = (next & ~mask) | (((next << 8) | prev) & mask); - return (Byte)Buf[0]; - } -}; - -/* -const int kSmallSize = 64; -class CMtf8Decoder -{ - Byte SmallBuffer[kSmallSize]; - int SmallSize; - Byte Counts[16]; - int Size; -public: - Byte Buf[256]; - - Byte GetHead() const - { - if (SmallSize > 0) - return SmallBuffer[kSmallSize - SmallSize]; - return Buf[0]; - } - - void Init(int size) - { - Size = size; - SmallSize = 0; - for (int i = 0; i < 16; i++) - { - Counts[i] = ((size >= 16) ? 16 : size); - size -= Counts[i]; - } - } - - Byte GetAndMove(int pos) - { - if (pos < SmallSize) - { - Byte *p = SmallBuffer + kSmallSize - SmallSize; - Byte res = p[pos]; - for (; pos > 0; pos--) - p[pos] = p[pos - 1]; - SmallBuffer[kSmallSize - SmallSize] = res; - return res; - } - if (SmallSize == kSmallSize) - { - int i = Size - 1; - int g = 16; - do - { - g--; - int offset = (g << 4); - for (int t = Counts[g] - 1; t >= 0; t--, i--) - Buf[i] = Buf[offset + t]; - } - while (g != 0); - - for (i = kSmallSize - 1; i >= 0; i--) - Buf[i] = SmallBuffer[i]; - Init(Size); - } - pos -= SmallSize; - int g; - for (g = 0; pos >= Counts[g]; g++) - pos -= Counts[g]; - int offset = (g << 4); - Byte res = Buf[offset + pos]; - for (pos; pos < 16 - 1; pos++) - Buf[offset + pos] = Buf[offset + pos + 1]; - - SmallSize++; - SmallBuffer[kSmallSize - SmallSize] = res; - - Counts[g]--; - return res; - } -}; -*/ - -} - -#endif +// Mtf8.h + +#ifndef ZIP7_INC_COMPRESS_MTF8_H +#define ZIP7_INC_COMPRESS_MTF8_H + +#include "../../../C/CpuArch.h" + +namespace NCompress { + +struct CMtf8Encoder +{ + Byte Buf[256]; + + unsigned FindAndMove(Byte v) throw() + { +#if 1 + Byte b = Buf[0]; + if (v == b) + return 0; + Buf[0] = v; + for (unsigned pos = 0;;) + { + Byte a; + a = Buf[++pos]; Buf[pos] = b; if (v == a) return pos; + b = Buf[++pos]; Buf[pos] = a; if (v == b) return pos; + } +#else + size_t pos; + for (pos = 0; Buf[pos] != v; pos++); + const unsigned resPos = (unsigned)pos; + for (; pos >= 8; pos -= 8) + { + Buf[pos] = Buf[pos - 1]; + Buf[pos - 1] = Buf[pos - 2]; + Buf[pos - 2] = Buf[pos - 3]; + Buf[pos - 3] = Buf[pos - 4]; + Buf[pos - 4] = Buf[pos - 5]; + Buf[pos - 5] = Buf[pos - 6]; + Buf[pos - 6] = Buf[pos - 7]; + Buf[pos - 7] = Buf[pos - 8]; + } + for (; pos != 0; pos--) + Buf[pos] = Buf[pos - 1]; + Buf[0] = v; + return resPos; +#endif + } +}; + +/* +struct CMtf8Decoder +{ + Byte Buf[256]; + + void StartInit() { memset(Buf, 0, sizeof(Buf)); } + void Add(unsigned pos, Byte val) { Buf[pos] = val; } + Byte GetHead() const { return Buf[0]; } + Byte GetAndMove(unsigned pos) + { + Byte res = Buf[pos]; + for (; pos >= 8; pos -= 8) + { + Buf[pos] = Buf[pos - 1]; + Buf[pos - 1] = Buf[pos - 2]; + Buf[pos - 2] = Buf[pos - 3]; + Buf[pos - 3] = Buf[pos - 4]; + Buf[pos - 4] = Buf[pos - 5]; + Buf[pos - 5] = Buf[pos - 6]; + Buf[pos - 6] = Buf[pos - 7]; + Buf[pos - 7] = Buf[pos - 8]; + } + for (; pos > 0; pos--) + Buf[pos] = Buf[pos - 1]; + Buf[0] = res; + return res; + } +}; +*/ + +#ifdef MY_CPU_64BIT + typedef UInt64 CMtfVar; + #define Z7_MTF_MOVS 3 +#else + typedef UInt32 CMtfVar; + #define Z7_MTF_MOVS 2 +#endif + +#define Z7_MTF_MASK ((1 << Z7_MTF_MOVS) - 1) + + +struct CMtf8Decoder +{ + CMtfVar Buf[256 >> Z7_MTF_MOVS]; + + void StartInit() { memset(Buf, 0, sizeof(Buf)); } + void Add(unsigned pos, Byte val) { Buf[pos >> Z7_MTF_MOVS] |= ((CMtfVar)val << ((pos & Z7_MTF_MASK) << 3)); } + Byte GetHead() const { return (Byte)Buf[0]; } + + Z7_FORCE_INLINE + Byte GetAndMove(unsigned pos) throw() + { + const UInt32 lim = ((UInt32)pos >> Z7_MTF_MOVS); + pos = (pos & Z7_MTF_MASK) << 3; + CMtfVar prev = (Buf[lim] >> pos) & 0xFF; + + UInt32 i = 0; + + + /* + if ((lim & 1) != 0) + { + CMtfVar next = Buf[0]; + Buf[0] = (next << 8) | prev; + prev = (next >> (Z7_MTF_MASK << 3)); + i = 1; + lim -= 1; + } + for (; i < lim; i += 2) + { + CMtfVar n0 = Buf[i]; + CMtfVar n1 = Buf[i + 1]; + Buf[i ] = (n0 << 8) | prev; + Buf[i + 1] = (n1 << 8) | (n0 >> (Z7_MTF_MASK << 3)); + prev = (n1 >> (Z7_MTF_MASK << 3)); + } + */ + + for (; i < lim; i++) + { + const CMtfVar n0 = Buf[i]; + Buf[i ] = (n0 << 8) | prev; + prev = (n0 >> (Z7_MTF_MASK << 3)); + } + + + const CMtfVar next = Buf[i]; + const CMtfVar mask = (((CMtfVar)0x100 << pos) - 1); + Buf[i] = (next & ~mask) | (((next << 8) | prev) & mask); + return (Byte)Buf[0]; + } +}; + +/* +const int kSmallSize = 64; +class CMtf8Decoder +{ + Byte SmallBuffer[kSmallSize]; + int SmallSize; + int Counts[16]; + int Size; +public: + Byte Buf[256]; + + Byte GetHead() const + { + if (SmallSize > 0) + return SmallBuffer[kSmallSize - SmallSize]; + return Buf[0]; + } + + void Init(int size) + { + Size = size; + SmallSize = 0; + for (int i = 0; i < 16; i++) + { + Counts[i] = ((size >= 16) ? 16 : size); + size -= Counts[i]; + } + } + + void Add(unsigned pos, Byte val) + { + Buf[pos] = val; + } + + Byte GetAndMove(int pos) + { + if (pos < SmallSize) + { + Byte *p = SmallBuffer + kSmallSize - SmallSize; + Byte res = p[pos]; + for (; pos > 0; pos--) + p[pos] = p[pos - 1]; + SmallBuffer[kSmallSize - SmallSize] = res; + return res; + } + if (SmallSize == kSmallSize) + { + int i = Size - 1; + int g = 16; + do + { + g--; + int offset = (g << 4); + for (int t = Counts[g] - 1; t >= 0; t--, i--) + Buf[i] = Buf[offset + t]; + } + while (g != 0); + + for (i = kSmallSize - 1; i >= 0; i--) + Buf[i] = SmallBuffer[i]; + Init(Size); + } + pos -= SmallSize; + int g; + for (g = 0; pos >= Counts[g]; g++) + pos -= Counts[g]; + int offset = (g << 4); + Byte res = Buf[offset + pos]; + for (pos; pos < 16 - 1; pos++) + Buf[offset + pos] = Buf[offset + pos + 1]; + + SmallSize++; + SmallBuffer[kSmallSize - SmallSize] = res; + + Counts[g]--; + return res; + } +}; +*/ + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdDecoder.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,163 +1,219 @@ -// PpmdDecoder.cpp -// 2009-03-11 : Igor Pavlov : Public domain - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" - -#include "../Common/StreamUtils.h" - -#include "PpmdDecoder.h" - -namespace NCompress { -namespace NPpmd { - -static const UInt32 kBufSize = (1 << 20); - -enum -{ - kStatus_NeedInit, - kStatus_Normal, - kStatus_Finished, - kStatus_Error -}; - -CDecoder::~CDecoder() -{ - ::MidFree(_outBuf); - Ppmd7_Free(&_ppmd, &g_BigAlloc); -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) -{ - if (size < 5) - return E_INVALIDARG; - _order = props[0]; - UInt32 memSize = GetUi32(props + 1); - if (_order < PPMD7_MIN_ORDER || - _order > PPMD7_MAX_ORDER || - memSize < PPMD7_MIN_MEM_SIZE || - memSize > PPMD7_MAX_MEM_SIZE) - return E_NOTIMPL; - if (!_inStream.Alloc(1 << 20)) - return E_OUTOFMEMORY; - if (!Ppmd7_Alloc(&_ppmd, memSize, &g_BigAlloc)) - return E_OUTOFMEMORY; - return S_OK; -} - -HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) -{ - switch (_status) - { - case kStatus_Finished: return S_OK; - case kStatus_Error: return S_FALSE; - case kStatus_NeedInit: - _inStream.Init(); - if (!Ppmd7z_RangeDec_Init(&_rangeDec)) - { - _status = kStatus_Error; - return S_FALSE; - } - _status = kStatus_Normal; - Ppmd7_Init(&_ppmd, _order); - break; - } - if (_outSizeDefined) - { - const UInt64 rem = _outSize - _processedSize; - if (size > rem) - size = (UInt32)rem; - } - - UInt32 i; - int sym = 0; - for (i = 0; i != size; i++) - { - sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p); - if (_inStream.Extra || sym < 0) - break; - memStream[i] = (Byte)sym; - } - - _processedSize += i; - if (_inStream.Extra) - { - _status = kStatus_Error; - return _inStream.Res; - } - if (sym < 0) - _status = (sym < -1) ? kStatus_Error : kStatus_Finished; - return S_OK; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (!_outBuf) - { - _outBuf = (Byte *)::MidAlloc(kBufSize); - if (!_outBuf) - return E_OUTOFMEMORY; - } - - _inStream.Stream = inStream; - SetOutStreamSize(outSize); - - do - { - const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec(_outBuf, kBufSize); - size_t processed = (size_t)(_processedSize - startPos); - RINOK(WriteStream(outStream, _outBuf, processed)); - RINOK(res); - if (_status == kStatus_Finished) - break; - if (progress) - { - UInt64 inSize = _inStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); - } - } - while (!_outSizeDefined || _processedSize < _outSize); - return S_OK; -} - -STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) -{ - _outSizeDefined = (outSize != NULL); - if (_outSizeDefined) - _outSize = *outSize; - _processedSize = 0; - _status = kStatus_NeedInit; - return S_OK; -} - -#ifndef NO_READ_FROM_CODER - -STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) -{ - InSeqStream = inStream; - _inStream.Stream = inStream; - return S_OK; -} - -STDMETHODIMP CDecoder::ReleaseInStream() -{ - InSeqStream.Release(); - return S_OK; -} - -STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - const UInt64 startPos = _processedSize; - HRESULT res = CodeSpec((Byte *)data, size); - if (processedSize) - *processedSize = (UInt32)(_processedSize - startPos); - return res; -} - -#endif - -}} +// PpmdDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "PpmdDecoder.h" + +namespace NCompress { +namespace NPpmd { + +static const UInt32 kBufSize = (1 << 16); + +enum +{ + kStatus_NeedInit, + kStatus_Normal, + kStatus_Finished_With_Mark, + kStatus_Error +}; + +CDecoder::~CDecoder() +{ + ::MidFree(_outBuf); + Ppmd7_Free(&_ppmd, &g_BigAlloc); +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)) +{ + if (size < 5) + return E_INVALIDARG; + _order = props[0]; + const UInt32 memSize = GetUi32(props + 1); + if (_order < PPMD7_MIN_ORDER || + _order > PPMD7_MAX_ORDER || + memSize < PPMD7_MIN_MEM_SIZE || + memSize > PPMD7_MAX_MEM_SIZE) + return E_NOTIMPL; + if (!_inStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + if (!Ppmd7_Alloc(&_ppmd, memSize, &g_BigAlloc)) + return E_OUTOFMEMORY; + return S_OK; +} + +#define MY_rangeDec _ppmd.rc.dec + +#define CHECK_EXTRA_ERROR \ + if (_inStream.Extra) { \ + _status = kStatus_Error; \ + return (_res = (_inStream.Res != SZ_OK ? _inStream.Res: S_FALSE)); } + + +HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) +{ + if (_res != S_OK) + return _res; + + switch (_status) + { + case kStatus_Finished_With_Mark: return S_OK; + case kStatus_Error: return S_FALSE; + case kStatus_NeedInit: + _inStream.Init(); + if (!Ppmd7z_RangeDec_Init(&MY_rangeDec)) + { + _status = kStatus_Error; + return (_res = S_FALSE); + } + CHECK_EXTRA_ERROR + _status = kStatus_Normal; + Ppmd7_Init(&_ppmd, _order); + break; + default: break; + } + + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _processedSize; + if (size > rem) + size = (UInt32)rem; + } + + int sym = 0; + { + Byte *buf = memStream; + const Byte *lim = buf + size; + for (; buf != lim; buf++) + { + sym = Ppmd7z_DecodeSymbol(&_ppmd); + if (_inStream.Extra || sym < 0) + break; + *buf = (Byte)sym; + } + /* + buf = Ppmd7z_DecodeSymbols(&_ppmd, buf, lim); + sym = _ppmd.LastSymbol; + */ + _processedSize += (size_t)(buf - memStream); + } + + CHECK_EXTRA_ERROR + + if (sym >= 0) + { + if (!FinishStream + || !_outSizeDefined + || _outSize != _processedSize + || MY_rangeDec.Code == 0) + return S_OK; + /* + // We can decode additional End Marker here: + sym = Ppmd7z_DecodeSymbol(&_ppmd); + CHECK_EXTRA_ERROR + */ + } + + if (sym != PPMD7_SYM_END || MY_rangeDec.Code != 0) + { + _status = kStatus_Error; + return (_res = S_FALSE); + } + + _status = kStatus_Finished_With_Mark; + return S_OK; +} + + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + if (!_outBuf) + { + _outBuf = (Byte *)::MidAlloc(kBufSize); + if (!_outBuf) + return E_OUTOFMEMORY; + } + + _inStream.Stream = inStream; + SetOutStreamSize(outSize); + + do + { + const UInt64 startPos = _processedSize; + const HRESULT res = CodeSpec(_outBuf, kBufSize); + const size_t processed = (size_t)(_processedSize - startPos); + RINOK(WriteStream(outStream, _outBuf, processed)) + RINOK(res) + if (_status == kStatus_Finished_With_Mark) + break; + if (progress) + { + const UInt64 inProcessed = _inStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&inProcessed, &_processedSize)) + } + } + while (!_outSizeDefined || _processedSize < _outSize); + + if (FinishStream && inSize && *inSize != _inStream.GetProcessed()) + return S_FALSE; + + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + _outSizeDefined = (outSize != NULL); + if (_outSizeDefined) + _outSize = *outSize; + _processedSize = 0; + _status = kStatus_NeedInit; + _res = SZ_OK; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishStream = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inStream.GetProcessed(); + return S_OK; +} + +#ifndef Z7_NO_READ_FROM_CODER + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) +{ + InSeqStream = inStream; + _inStream.Stream = inStream; + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) +{ + InSeqStream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + const UInt64 startPos = _processedSize; + const HRESULT res = CodeSpec((Byte *)data, size); + if (processedSize) + *processedSize = (UInt32)(_processedSize - startPos); + return res; +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdDecoder.h 2010-03-16 19:08:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdDecoder.h 2023-03-28 13:00:00.000000000 +0000 @@ -1,78 +1,87 @@ -// PpmdDecoder.h -// 2009-03-11 : Igor Pavlov : Public domain - -#ifndef __COMPRESS_PPMD_DECODER_H -#define __COMPRESS_PPMD_DECODER_H - -#include "../../../C/Ppmd7.h" - -#include "../../Common/MyCom.h" - -#include "../Common/CWrappers.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NPpmd { - -class CDecoder : - public ICompressCoder, - public ICompressSetDecoderProperties2, - #ifndef NO_READ_FROM_CODER - public ICompressSetInStream, - public ICompressSetOutStreamSize, - public ISequentialInStream, - #endif - public CMyUnknownImp -{ - Byte *_outBuf; - CPpmd7z_RangeDec _rangeDec; - CByteInBufWrap _inStream; - CPpmd7 _ppmd; - - Byte _order; - bool _outSizeDefined; - int _status; - UInt64 _outSize; - UInt64 _processedSize; - - HRESULT CodeSpec(Byte *memStream, UInt32 size); - -public: - - #ifndef NO_READ_FROM_CODER - CMyComPtr InSeqStream; - MY_UNKNOWN_IMP4( - ICompressSetDecoderProperties2, - ICompressSetInStream, - ICompressSetOutStreamSize, - ISequentialInStream) - #else - MY_UNKNOWN_IMP1( - ICompressSetDecoderProperties2) - #endif - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); - - #ifndef NO_READ_FROM_CODER - STDMETHOD(SetInStream)(ISequentialInStream *inStream); - STDMETHOD(ReleaseInStream)(); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - #endif - - CDecoder(): _outBuf(NULL), _outSizeDefined(false) - { - Ppmd7z_RangeDec_CreateVTable(&_rangeDec); - _rangeDec.Stream = &_inStream.p; - Ppmd7_Construct(&_ppmd); - } - - ~CDecoder(); -}; - -}} - -#endif +// PpmdDecoder.h + +#ifndef ZIP7_INC_COMPRESS_PPMD_DECODER_H +#define ZIP7_INC_COMPRESS_PPMD_DECODER_H + +#include "../../../C/Ppmd7.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/CWrappers.h" + +namespace NCompress { +namespace NPpmd { + +class CDecoder Z7_final: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + #ifndef Z7_NO_READ_FROM_CODER + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_NO_READ_FROM_CODER + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #else + Z7_COM7F_IMF(SetOutStreamSize(const UInt64 *outSize)); + #endif + + Byte *_outBuf; + CByteInBufWrap _inStream; + CPpmd7 _ppmd; + + Byte _order; + bool FinishStream; + bool _outSizeDefined; + HRESULT _res; + int _status; + UInt64 _outSize; + UInt64 _processedSize; + + HRESULT CodeSpec(Byte *memStream, UInt32 size); + +public: + + #ifndef Z7_NO_READ_FROM_CODER + CMyComPtr InSeqStream; + #endif + + CDecoder(): + _outBuf(NULL), + FinishStream(false), + _outSizeDefined(false) + { + Ppmd7_Construct(&_ppmd); + _ppmd.rc.dec.Stream = &_inStream.vt; + } + + ~CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdEncoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdEncoder.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.cpp 2023-03-28 13:00:00.000000000 +0000 @@ -1,152 +1,193 @@ -// PpmdEncoder.cpp - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" - -#include "../Common/StreamUtils.h" - -#include "PpmdEncoder.h" - -namespace NCompress { -namespace NPpmd { - -static const UInt32 kBufSize = (1 << 20); - -static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 }; - -void CEncProps::Normalize(int level) -{ - if (level < 0) level = 5; - if (level > 9) level = 9; - if (MemSize == (UInt32)(Int32)-1) - MemSize = level >= 9 ? ((UInt32)192 << 20) : ((UInt32)1 << (level + 19)); - const unsigned kMult = 16; - if (MemSize / kMult > ReduceSize) - { - for (unsigned i = 16; i <= 31; i++) - { - UInt32 m = (UInt32)1 << i; - if (ReduceSize <= m / kMult) - { - if (MemSize > m) - MemSize = m; - break; - } - } - } - if (Order == -1) Order = kOrders[(unsigned)level]; -} - -CEncoder::CEncoder(): - _inBuf(NULL) -{ - _props.Normalize(-1); - _rangeEnc.Stream = &_outStream.p; - Ppmd7_Construct(&_ppmd); -} - -CEncoder::~CEncoder() -{ - ::MidFree(_inBuf); - Ppmd7_Free(&_ppmd, &g_BigAlloc); -} - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - int level = -1; - CEncProps props; - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - if (propID > NCoderPropID::kReduceSize) - continue; - if (propID == NCoderPropID::kReduceSize) - { - if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1) - props.ReduceSize = (UInt32)prop.uhVal.QuadPart; - continue; - } - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; - switch (propID) - { - case NCoderPropID::kUsedMemorySize: - if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0) - return E_INVALIDARG; - props.MemSize = v; - break; - case NCoderPropID::kOrder: - if (v < 2 || v > 32) - return E_INVALIDARG; - props.Order = (Byte)v; - break; - case NCoderPropID::kNumThreads: break; - case NCoderPropID::kLevel: level = (int)v; break; - default: return E_INVALIDARG; - } - } - props.Normalize(level); - _props = props; - return S_OK; -} - -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) -{ - const UInt32 kPropSize = 5; - Byte props[kPropSize]; - props[0] = (Byte)_props.Order; - SetUi32(props + 1, _props.MemSize); - return WriteStream(outStream, props, kPropSize); -} - -HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - if (!_inBuf) - { - _inBuf = (Byte *)::MidAlloc(kBufSize); - if (!_inBuf) - return E_OUTOFMEMORY; - } - if (!_outStream.Alloc(1 << 20)) - return E_OUTOFMEMORY; - if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc)) - return E_OUTOFMEMORY; - - _outStream.Stream = outStream; - _outStream.Init(); - - Ppmd7z_RangeEnc_Init(&_rangeEnc); - Ppmd7_Init(&_ppmd, _props.Order); - - UInt64 processed = 0; - for (;;) - { - UInt32 size; - RINOK(inStream->Read(_inBuf, kBufSize, &size)); - if (size == 0) - { - // We don't write EndMark in PPMD-7z. - // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1); - Ppmd7z_RangeEnc_FlushData(&_rangeEnc); - return _outStream.Flush(); - } - for (UInt32 i = 0; i < size; i++) - { - Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]); - RINOK(_outStream.Res); - } - processed += size; - if (progress) - { - UInt64 outSize = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outSize)); - } - } -} - -}} +// PpmdEncoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/StreamUtils.h" + +#include "PpmdEncoder.h" + +namespace NCompress { +namespace NPpmd { + +static const UInt32 kBufSize = (1 << 20); + +static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 }; + +void CEncProps::Normalize(int level) +{ + if (level < 0) level = 5; + if (level > 9) level = 9; + if (MemSize == (UInt32)(Int32)-1) + MemSize = (UInt32)1 << (level + 19); + const unsigned kMult = 16; + if (MemSize / kMult > ReduceSize) + { + for (unsigned i = 16; i < 32; i++) + { + UInt32 m = (UInt32)1 << i; + if (ReduceSize <= m / kMult) + { + if (MemSize > m) + MemSize = m; + break; + } + } + } + if (Order == -1) Order = kOrders[(unsigned)level]; +} + +CEncoder::CEncoder(): + _inBuf(NULL) +{ + _props.Normalize(-1); + Ppmd7_Construct(&_ppmd); + _ppmd.rc.enc.Stream = &_outStream.vt; +} + +CEncoder::~CEncoder() +{ + ::MidFree(_inBuf); + Ppmd7_Free(&_ppmd, &g_BigAlloc); +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + int level = -1; + CEncProps props; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID > NCoderPropID::kReduceSize) + continue; + if (propID == NCoderPropID::kReduceSize) + { + if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1) + props.ReduceSize = (UInt32)prop.uhVal.QuadPart; + continue; + } + + if (propID == NCoderPropID::kUsedMemorySize) + { + // here we have selected (4 GiB - 1 KiB) as replacement for (4 GiB) MEM_SIZE. + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + UInt32 v; + if (prop.vt == VT_UI8) + { + // 21.03 : we support 64-bit values (for 4 GiB value) + const UInt64 v64 = prop.uhVal.QuadPart; + if (v64 > ((UInt64)1 << 32)) + return E_INVALIDARG; + if (v64 == ((UInt64)1 << 32)) + v = kPpmd_Default_4g; + else + v = (UInt32)v64; + } + else if (prop.vt == VT_UI4) + v = (UInt32)prop.ulVal; + else + return E_INVALIDARG; + if (v > PPMD7_MAX_MEM_SIZE) + v = kPpmd_Default_4g; + + /* here we restrict MEM_SIZE for Encoder. + It's for better performance of encoding and decoding. + The Decoder still supports more MEM_SIZE values. */ + if (v < ((UInt32)1 << 16) || (v & 3) != 0) + return E_INVALIDARG; + // if (v < PPMD7_MIN_MEM_SIZE) return E_INVALIDARG; // (1 << 11) + /* + Supported MEM_SIZE range : + [ (1 << 11) , 0xFFFFFFFF - 12 * 3 ] - current 7-Zip's Ppmd7 constants + [ 1824 , 0xFFFFFFFF ] - real limits of Ppmd7 code + */ + props.MemSize = v; + continue; + } + + if (prop.vt != VT_UI4) + return E_INVALIDARG; + const UInt32 v = (UInt32)prop.ulVal; + switch (propID) + { + case NCoderPropID::kOrder: + if (v < 2 || v > 32) + return E_INVALIDARG; + props.Order = (Byte)v; + break; + case NCoderPropID::kNumThreads: break; + case NCoderPropID::kLevel: level = (int)v; break; + default: return E_INVALIDARG; + } + } + props.Normalize(level); + _props = props; + return S_OK; +} + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + const UInt32 kPropSize = 5; + Byte props[kPropSize]; + props[0] = (Byte)_props.Order; + SetUi32(props + 1, _props.MemSize) + return WriteStream(outStream, props, kPropSize); +} + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + if (!_inBuf) + { + _inBuf = (Byte *)::MidAlloc(kBufSize); + if (!_inBuf) + return E_OUTOFMEMORY; + } + if (!_outStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc)) + return E_OUTOFMEMORY; + + _outStream.Stream = outStream; + _outStream.Init(); + + Ppmd7z_Init_RangeEnc(&_ppmd); + Ppmd7_Init(&_ppmd, (unsigned)_props.Order); + + UInt64 processed = 0; + for (;;) + { + UInt32 size; + RINOK(inStream->Read(_inBuf, kBufSize, &size)) + if (size == 0) + { + // We don't write EndMark in PPMD-7z. + // Ppmd7z_EncodeSymbol(&_ppmd, -1); + Ppmd7z_Flush_RangeEnc(&_ppmd); + return _outStream.Flush(); + } + const Byte *buf = _inBuf; + const Byte *lim = buf + size; + /* + for (; buf < lim; buf++) + { + Ppmd7z_EncodeSymbol(&_ppmd, *buf); + RINOK(_outStream.Res); + } + */ + + Ppmd7z_EncodeSymbols(&_ppmd, buf, lim); + RINOK(_outStream.Res) + + processed += size; + if (progress) + { + const UInt64 outSize = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outSize)) + } + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdEncoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,58 +1,49 @@ -// PpmdEncoder.h - -#ifndef __COMPRESS_PPMD_ENCODER_H -#define __COMPRESS_PPMD_ENCODER_H - -#include "../../../C/Ppmd7.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/CWrappers.h" - -namespace NCompress { -namespace NPpmd { - -struct CEncProps -{ - UInt32 MemSize; - UInt32 ReduceSize; - int Order; - - CEncProps() - { - MemSize = (UInt32)(Int32)-1; - ReduceSize = (UInt32)(Int32)-1; - Order = -1; - } - void Normalize(int level); -}; - -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public ICompressWriteCoderProperties, - public CMyUnknownImp -{ - Byte *_inBuf; - CByteOutBufWrap _outStream; - CPpmd7z_RangeEnc _rangeEnc; - CPpmd7 _ppmd; - CEncProps _props; -public: - MY_UNKNOWN_IMP3( - ICompressCoder, - ICompressSetCoderProperties, - ICompressWriteCoderProperties) - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - CEncoder(); - ~CEncoder(); -}; - -}} - -#endif +// PpmdEncoder.h + +#ifndef ZIP7_INC_COMPRESS_PPMD_ENCODER_H +#define ZIP7_INC_COMPRESS_PPMD_ENCODER_H + +#include "../../../C/Ppmd7.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/CWrappers.h" + +namespace NCompress { +namespace NPpmd { + +struct CEncProps +{ + UInt32 MemSize; + UInt32 ReduceSize; + int Order; + + CEncProps() + { + MemSize = (UInt32)(Int32)-1; + ReduceSize = (UInt32)(Int32)-1; + Order = -1; + } + void Normalize(int level); +}; + +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressWriteCoderProperties +) + Byte *_inBuf; + CByteOutBufWrap _outStream; + CPpmd7 _ppmd; + CEncProps _props; +public: + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdRegister.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,22 +1,22 @@ -// PpmdRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "PpmdDecoder.h" - -#ifndef EXTRACT_ONLY -#include "PpmdEncoder.h" -#endif - -namespace NCompress { -namespace NPpmd { - -REGISTER_CODEC_E(PPMD, - CDecoder(), - CEncoder(), - 0x30401, - "PPMD") - -}} +// PpmdRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "PpmdDecoder.h" + +#ifndef Z7_EXTRACT_ONLY +#include "PpmdEncoder.h" +#endif + +namespace NCompress { +namespace NPpmd { + +REGISTER_CODEC_E(PPMD, + CDecoder(), + CEncoder(), + 0x30401, + "PPMD") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdZip.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdZip.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.cpp 2023-12-20 13:00:00.000000000 +0000 @@ -1,259 +1,309 @@ -// PpmdZip.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../Common/RegisterCodec.h" -#include "../Common/StreamUtils.h" - -#include "PpmdZip.h" - -namespace NCompress { -namespace NPpmdZip { - -CDecoder::CDecoder(bool fullFileMode): - _fullFileMode(fullFileMode) -{ - _ppmd.Stream.In = &_inStream.p; - Ppmd8_Construct(&_ppmd); -} - -CDecoder::~CDecoder() -{ - Ppmd8_Free(&_ppmd, &g_BigAlloc); -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (!_outStream.Alloc()) - return E_OUTOFMEMORY; - if (!_inStream.Alloc(1 << 20)) - return E_OUTOFMEMORY; - - _inStream.Stream = inStream; - _inStream.Init(); - - { - Byte buf[2]; - for (int i = 0; i < 2; i++) - buf[i] = _inStream.ReadByte(); - if (_inStream.Extra) - return S_FALSE; - - UInt32 val = GetUi16(buf); - UInt32 order = (val & 0xF) + 1; - UInt32 mem = ((val >> 4) & 0xFF) + 1; - UInt32 restor = (val >> 12); - if (order < 2 || restor > 2) - return S_FALSE; - - #ifndef PPMD8_FREEZE_SUPPORT - if (restor == 2) - return E_NOTIMPL; - #endif - - if (!Ppmd8_Alloc(&_ppmd, mem << 20, &g_BigAlloc)) - return E_OUTOFMEMORY; - - if (!Ppmd8_RangeDec_Init(&_ppmd)) - return S_FALSE; - Ppmd8_Init(&_ppmd, order, restor); - } - - bool wasFinished = false; - UInt64 processedSize = 0; - while (!outSize || processedSize < *outSize) - { - size_t size = kBufSize; - if (outSize != NULL) - { - const UInt64 rem = *outSize - processedSize; - if (size > rem) - size = (size_t)rem; - } - Byte *data = _outStream.Buf; - size_t i = 0; - int sym = 0; - do - { - sym = Ppmd8_DecodeSymbol(&_ppmd); - if (_inStream.Extra || sym < 0) - break; - data[i] = (Byte)sym; - } - while (++i != size); - processedSize += i; - - RINOK(WriteStream(outStream, _outStream.Buf, i)); - - RINOK(_inStream.Res); - if (_inStream.Extra) - return S_FALSE; - - if (sym < 0) - { - if (sym != -1) - return S_FALSE; - wasFinished = true; - break; - } - if (progress) - { - UInt64 inSize = _inStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&inSize, &processedSize)); - } - } - RINOK(_inStream.Res); - if (_fullFileMode) - { - if (!wasFinished) - { - int res = Ppmd8_DecodeSymbol(&_ppmd); - RINOK(_inStream.Res); - if (_inStream.Extra || res != -1) - return S_FALSE; - } - if (!Ppmd8_RangeDec_IsFinishedOK(&_ppmd)) - return S_FALSE; - } - return S_OK; -} - - -// ---------- Encoder ---------- - -void CEncProps::Normalize(int level) -{ - if (level < 0) level = 5; - if (level == 0) level = 1; - if (level > 9) level = 9; - if (MemSizeMB == (UInt32)(Int32)-1) - MemSizeMB = (1 << ((level > 8 ? 8 : level) - 1)); - const unsigned kMult = 16; - if ((MemSizeMB << 20) / kMult > ReduceSize) - { - for (UInt32 m = (1 << 20); m <= (1 << 28); m <<= 1) - { - if (ReduceSize <= m / kMult) - { - m >>= 20; - if (MemSizeMB > m) - MemSizeMB = m; - break; - } - } - } - if (Order == -1) Order = 3 + level; - if (Restor == -1) - Restor = level < 7 ? - PPMD8_RESTORE_METHOD_RESTART : - PPMD8_RESTORE_METHOD_CUT_OFF; -} - -CEncoder::~CEncoder() -{ - Ppmd8_Free(&_ppmd, &g_BigAlloc); -} - -STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - int level = -1; - CEncProps props; - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - PROPID propID = propIDs[i]; - if (propID > NCoderPropID::kReduceSize) - continue; - if (propID == NCoderPropID::kReduceSize) - { - if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1) - props.ReduceSize = (UInt32)prop.uhVal.QuadPart; - continue; - } - if (prop.vt != VT_UI4) - return E_INVALIDARG; - UInt32 v = (UInt32)prop.ulVal; - switch (propID) - { - case NCoderPropID::kUsedMemorySize: - if (v < (1 << 20) || v > (1 << 28)) - return E_INVALIDARG; - props.MemSizeMB = v >> 20; - break; - case NCoderPropID::kOrder: - if (v < PPMD8_MIN_ORDER || v > PPMD8_MAX_ORDER) - return E_INVALIDARG; - props.Order = (Byte)v; - break; - case NCoderPropID::kNumThreads: break; - case NCoderPropID::kLevel: level = (int)v; break; - case NCoderPropID::kAlgorithm: - if (v > 1) - return E_INVALIDARG; - props.Restor = v; - break; - default: return E_INVALIDARG; - } - } - props.Normalize(level); - _props = props; - return S_OK; -} - -CEncoder::CEncoder() -{ - _props.Normalize(-1); - _ppmd.Stream.Out = &_outStream.p; - Ppmd8_Construct(&_ppmd); -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - if (!_inStream.Alloc()) - return E_OUTOFMEMORY; - if (!_outStream.Alloc(1 << 20)) - return E_OUTOFMEMORY; - if (!Ppmd8_Alloc(&_ppmd, _props.MemSizeMB << 20, &g_BigAlloc)) - return E_OUTOFMEMORY; - - _outStream.Stream = outStream; - _outStream.Init(); - - Ppmd8_RangeEnc_Init(&_ppmd); - Ppmd8_Init(&_ppmd, _props.Order, _props.Restor); - - UInt32 val = (UInt32)((_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + (_props.Restor << 12)); - _outStream.WriteByte((Byte)(val & 0xFF)); - _outStream.WriteByte((Byte)(val >> 8)); - RINOK(_outStream.Res); - - UInt64 processed = 0; - for (;;) - { - UInt32 size; - RINOK(inStream->Read(_inStream.Buf, kBufSize, &size)); - if (size == 0) - { - Ppmd8_EncodeSymbol(&_ppmd, -1); - Ppmd8_RangeEnc_FlushData(&_ppmd); - return _outStream.Flush(); - } - for (UInt32 i = 0; i < size; i++) - { - Ppmd8_EncodeSymbol(&_ppmd, _inStream.Buf[i]); - RINOK(_outStream.Res); - } - processed += size; - if (progress != NULL) - { - UInt64 outSize = _outStream.GetProcessed(); - RINOK(progress->SetRatioInfo(&processed, &outSize)); - } - } -} - -}} +// PpmdZip.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/RegisterCodec.h" +#include "../Common/StreamUtils.h" + +#include "PpmdZip.h" + +namespace NCompress { +namespace NPpmdZip { + +static const UInt32 kBufSize = 1 << 20; + +bool CBuf::Alloc() +{ + if (!Buf) + Buf = (Byte *)::MidAlloc(kBufSize); + return (Buf != NULL); +} + +CDecoder::CDecoder(bool fullFileMode): + _fullFileMode(fullFileMode) +{ + Ppmd8_Construct(&_ppmd); + _ppmd.Stream.In = &_inStream.vt; +} + +CDecoder::~CDecoder() +{ + Ppmd8_Free(&_ppmd, &g_BigAlloc); +} + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + // try { + + if (!_outStream.Alloc()) + return E_OUTOFMEMORY; + if (!_inStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + + _inStream.Stream = inStream; + _inStream.Init(); + + { + Byte buf[2]; + for (int i = 0; i < 2; i++) + buf[i] = _inStream.ReadByte(); + if (_inStream.Extra) + return S_FALSE; + + const UInt32 val = GetUi16(buf); + const unsigned order = (val & 0xF) + 1; + const UInt32 mem = ((val >> 4) & 0xFF) + 1; + const unsigned restor = (val >> 12); + if (order < 2 || restor > 2) + return S_FALSE; + + #ifndef PPMD8_FREEZE_SUPPORT + if (restor == 2) + return E_NOTIMPL; + #endif + + if (!Ppmd8_Alloc(&_ppmd, mem << 20, &g_BigAlloc)) + return E_OUTOFMEMORY; + + if (!Ppmd8_Init_RangeDec(&_ppmd)) + return S_FALSE; + Ppmd8_Init(&_ppmd, order, restor); + } + + bool wasFinished = false; + UInt64 processedSize = 0; + + for (;;) + { + size_t size = kBufSize; + if (outSize) + { + const UInt64 rem = *outSize - processedSize; + if (size > rem) + { + size = (size_t)rem; + if (size == 0) + break; + } + } + + int sym; + Byte *buf = _outStream.Buf; + const Byte *lim = buf + size; + + do + { + sym = Ppmd8_DecodeSymbol(&_ppmd); + if (_inStream.Extra || sym < 0) + break; + *buf++ = (Byte)sym; + } + while (buf != lim); + + const size_t cur = (size_t)(buf - _outStream.Buf); + processedSize += cur; + + RINOK(WriteStream(outStream, _outStream.Buf, cur)) + + RINOK(_inStream.Res) + if (_inStream.Extra) + return S_FALSE; + + if (sym < 0) + { + if (sym != -1) + return S_FALSE; + wasFinished = true; + break; + } + + if (progress) + { + const UInt64 inProccessed = _inStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&inProccessed, &processedSize)) + } + } + + RINOK(_inStream.Res) + + if (_fullFileMode) + { + if (!wasFinished) + { + const int res = Ppmd8_DecodeSymbol(&_ppmd); + RINOK(_inStream.Res) + if (_inStream.Extra || res != -1) + return S_FALSE; + } + if (!Ppmd8_RangeDec_IsFinishedOK(&_ppmd)) + return S_FALSE; + + if (inSize && *inSize != _inStream.GetProcessed()) + return S_FALSE; + } + + return S_OK; + + // } catch (...) { return E_FAIL; } +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + _fullFileMode = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inStream.GetProcessed(); + return S_OK; +} + + + +// ---------- Encoder ---------- + +void CEncProps::Normalize(int level) +{ + if (level < 0) level = 5; + if (level == 0) level = 1; + if (level > 9) level = 9; + if (MemSizeMB == (UInt32)(Int32)-1) + MemSizeMB = 1 << (level - 1); + const unsigned kMult = 16; + for (UInt32 m = 1; m < MemSizeMB; m <<= 1) + if (ReduceSize <= (m << 20) / kMult) + { + MemSizeMB = m; + break; + } + if (Order == -1) Order = 3 + level; + if (Restor == -1) + Restor = level < 7 ? + PPMD8_RESTORE_METHOD_RESTART : + PPMD8_RESTORE_METHOD_CUT_OFF; +} + +CEncoder::~CEncoder() +{ + Ppmd8_Free(&_ppmd, &g_BigAlloc); +} + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + int level = -1; + CEncProps props; + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID > NCoderPropID::kReduceSize) + continue; + if (propID == NCoderPropID::kReduceSize) + { + props.ReduceSize = (UInt32)(Int32)-1; + if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1) + props.ReduceSize = (UInt32)prop.uhVal.QuadPart; + continue; + } + if (prop.vt != VT_UI4) + return E_INVALIDARG; + const UInt32 v = (UInt32)prop.ulVal; + switch (propID) + { + case NCoderPropID::kUsedMemorySize: + if (v < (1 << 20) || v > (1 << 28)) + return E_INVALIDARG; + props.MemSizeMB = v >> 20; + break; + case NCoderPropID::kOrder: + if (v < PPMD8_MIN_ORDER || v > PPMD8_MAX_ORDER) + return E_INVALIDARG; + props.Order = (Byte)v; + break; + case NCoderPropID::kNumThreads: break; + case NCoderPropID::kLevel: level = (int)v; break; + case NCoderPropID::kAlgorithm: + if (v >= PPMD8_RESTORE_METHOD_UNSUPPPORTED) + return E_INVALIDARG; + props.Restor = (int)v; + break; + default: return E_INVALIDARG; + } + } + props.Normalize(level); + _props = props; + return S_OK; +} + +CEncoder::CEncoder() +{ + _props.Normalize(-1); + _ppmd.Stream.Out = &_outStream.vt; + Ppmd8_Construct(&_ppmd); +} + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + if (!_inStream.Alloc()) + return E_OUTOFMEMORY; + if (!_outStream.Alloc(1 << 20)) + return E_OUTOFMEMORY; + if (!Ppmd8_Alloc(&_ppmd, _props.MemSizeMB << 20, &g_BigAlloc)) + return E_OUTOFMEMORY; + + _outStream.Stream = outStream; + _outStream.Init(); + + Ppmd8_Init_RangeEnc(&_ppmd) + Ppmd8_Init(&_ppmd, (unsigned)_props.Order, (unsigned)_props.Restor); + + { + const unsigned val = + ((unsigned)_props.Order - 1) + + (((unsigned)_props.MemSizeMB - 1) << 4) + + ((unsigned)_props.Restor << 12); + _outStream.WriteByte((Byte)(val & 0xFF)); + _outStream.WriteByte((Byte)(val >> 8)); + } + RINOK(_outStream.Res) + + UInt64 processed = 0; + for (;;) + { + UInt32 size; + RINOK(inStream->Read(_inStream.Buf, kBufSize, &size)) + if (size == 0) + { + Ppmd8_EncodeSymbol(&_ppmd, -1); + Ppmd8_Flush_RangeEnc(&_ppmd); + return _outStream.Flush(); + } + + processed += size; + const Byte *buf = _inStream.Buf; + const Byte *lim = buf + size; + do + { + Ppmd8_EncodeSymbol(&_ppmd, *buf); + if (_outStream.Res != S_OK) + break; + } + while (++buf != lim); + + RINOK(_outStream.Res) + + if (progress) + { + const UInt64 outProccessed = _outStream.GetProcessed(); + RINOK(progress->SetRatioInfo(&processed, &outProccessed)) + } + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/PpmdZip.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.h --- p7zip-rar-16.02/CPP/7zip/Compress/PpmdZip.h 2011-05-08 18:29:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/PpmdZip.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,87 +1,78 @@ -// PpmdZip.h - -#ifndef __COMPRESS_PPMD_ZIP_H -#define __COMPRESS_PPMD_ZIP_H - -#include "../../../C/Alloc.h" -#include "../../../C/Ppmd8.h" - -#include "../../Common/MyCom.h" - -#include "../Common/CWrappers.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NPpmdZip { - -static const UInt32 kBufSize = (1 << 20); - -struct CBuf -{ - Byte *Buf; - - CBuf(): Buf(0) {} - ~CBuf() { ::MidFree(Buf); } - bool Alloc() - { - if (!Buf) - Buf = (Byte *)::MidAlloc(kBufSize); - return (Buf != 0); - } -}; - -class CDecoder : - public ICompressCoder, - public CMyUnknownImp -{ - CByteInBufWrap _inStream; - CBuf _outStream; - CPpmd8 _ppmd; - bool _fullFileMode; -public: - MY_UNKNOWN_IMP - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - CDecoder(bool fullFileMode); - ~CDecoder(); -}; - -struct CEncProps -{ - UInt32 MemSizeMB; - UInt32 ReduceSize; - int Order; - int Restor; - - CEncProps() - { - MemSizeMB = (UInt32)(Int32)-1; - ReduceSize = (UInt32)(Int32)-1; - Order = -1; - Restor = -1; - } - void Normalize(int level); -}; - -class CEncoder : - public ICompressCoder, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ - CByteOutBufWrap _outStream; - CBuf _inStream; - CPpmd8 _ppmd; - CEncProps _props; -public: - MY_UNKNOWN_IMP1(ICompressSetCoderProperties) - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); - CEncoder(); - ~CEncoder(); -}; - -}} - -#endif +// PpmdZip.h + +#ifndef ZIP7_INC_COMPRESS_PPMD_ZIP_H +#define ZIP7_INC_COMPRESS_PPMD_ZIP_H + +#include "../../../C/Alloc.h" +#include "../../../C/Ppmd8.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/CWrappers.h" + +namespace NCompress { +namespace NPpmdZip { + +struct CBuf +{ + Byte *Buf; + + CBuf(): Buf(NULL) {} + ~CBuf() { ::MidFree(Buf); } + bool Alloc(); +}; + + +Z7_CLASS_IMP_NOQIB_3( + CDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + bool _fullFileMode; + CByteInBufWrap _inStream; + CBuf _outStream; + CPpmd8 _ppmd; +public: + CDecoder(bool fullFileMode = true); + ~CDecoder(); +}; + + +struct CEncProps +{ + UInt32 MemSizeMB; + UInt32 ReduceSize; + int Order; + int Restor; + + CEncProps() + { + MemSizeMB = (UInt32)(Int32)-1; + ReduceSize = (UInt32)(Int32)-1; + Order = -1; + Restor = -1; + } + void Normalize(int level); +}; + + +Z7_CLASS_IMP_NOQIB_2( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties +) + CByteOutBufWrap _outStream; + CBuf _inStream; + CPpmd8 _ppmd; + CEncProps _props; +public: + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/QuantumDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/QuantumDecoder.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.cpp 2024-02-24 15:00:00.000000000 +0000 @@ -1,195 +1,355 @@ -// QuantumDecoder.cpp - -#include "StdAfx.h" - -#include "../../Common/Defs.h" - -#include "QuantumDecoder.h" - -namespace NCompress { -namespace NQuantum { - -static const unsigned kNumLenSymbols = 27; -static const unsigned kMatchMinLen = 3; -static const unsigned kNumSimplePosSlots = 4; -static const unsigned kNumSimpleLenSlots = 6; - -static const UInt16 kUpdateStep = 8; -static const UInt16 kFreqSumMax = 3800; -static const unsigned kReorderCountStart = 4; -static const unsigned kReorderCount = 50; - -void CModelDecoder::Init(unsigned numItems) -{ - NumItems = numItems; - ReorderCount = kReorderCountStart; - for (unsigned i = 0; i < numItems; i++) - { - Freqs[i] = (UInt16)(numItems - i); - Vals[i] = (Byte)i; - } - Freqs[numItems] = 0; -} - -unsigned CModelDecoder::Decode(CRangeDecoder *rc) -{ - UInt32 threshold = rc->GetThreshold(Freqs[0]); - unsigned i; - for (i = 1; Freqs[i] > threshold; i++); - - rc->Decode(Freqs[i], Freqs[i - 1], Freqs[0]); - unsigned res = Vals[--i]; - - do - Freqs[i] += kUpdateStep; - while (i--); - - if (Freqs[0] > kFreqSumMax) - { - if (--ReorderCount == 0) - { - ReorderCount = kReorderCount; - for (i = 0; i < NumItems; i++) - Freqs[i] = (UInt16)(((Freqs[i] - Freqs[i + 1]) + 1) >> 1); - for (i = 0; i < NumItems - 1; i++) - for (unsigned j = i + 1; j < NumItems; j++) - if (Freqs[i] < Freqs[j]) - { - UInt16 tmpFreq = Freqs[i]; - Byte tmpVal = Vals[i]; - Freqs[i] = Freqs[j]; - Vals[i] = Vals[j]; - Freqs[j] = tmpFreq; - Vals[j] = tmpVal; - } - - do - Freqs[i] = (UInt16)(Freqs[i] + Freqs[i + 1]); - while (i--); - } - else - { - i = NumItems - 1; - do - { - Freqs[i] >>= 1; - if (Freqs[i] <= Freqs[i + 1]) - Freqs[i] = (UInt16)(Freqs[i + 1] + 1); - } - while (i--); - } - } - - return res; -} - - -void CDecoder::Init() -{ - m_Selector.Init(kNumSelectors); - unsigned i; - for (i = 0; i < kNumLitSelectors; i++) - m_Literals[i].Init(kNumLitSymbols); - unsigned numItems = (_numDictBits == 0 ? 1 : (_numDictBits << 1)); - const unsigned kNumPosSymbolsMax[kNumMatchSelectors] = { 24, 36, 42 }; - for (i = 0; i < kNumMatchSelectors; i++) - m_PosSlot[i].Init(MyMin(numItems, kNumPosSymbolsMax[i])); - m_LenSlot.Init(kNumLenSymbols); -} - - -HRESULT CDecoder::CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize) -{ - if (inSize < 2) - return S_FALSE; - - CRangeDecoder rc; - rc.Stream.SetStreamAndInit(inData, inSize); - rc.Init(); - - while (outSize != 0) - { - if (rc.Stream.WasExtraRead()) - return S_FALSE; - - unsigned selector = m_Selector.Decode(&rc); - - if (selector < kNumLitSelectors) - { - Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&rc)); - _outWindow.PutByte(b); - outSize--; - } - else - { - selector -= kNumLitSelectors; - unsigned len = selector + kMatchMinLen; - - if (selector == 2) - { - unsigned lenSlot = m_LenSlot.Decode(&rc); - if (lenSlot >= kNumSimpleLenSlots) - { - lenSlot -= 2; - unsigned numDirectBits = (unsigned)(lenSlot >> 2); - len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; - if (numDirectBits < 6) - len += rc.Stream.ReadBits(numDirectBits); - } - else - len += lenSlot; - } - - UInt32 dist = m_PosSlot[selector].Decode(&rc); - - if (dist >= kNumSimplePosSlots) - { - unsigned numDirectBits = (unsigned)((dist >> 1) - 1); - dist = ((2 | (dist & 1)) << numDirectBits) + rc.Stream.ReadBits(numDirectBits); - } - - unsigned locLen = len; - if (len > outSize) - locLen = (unsigned)outSize; - if (!_outWindow.CopyBlock(dist, locLen)) - return S_FALSE; - outSize -= locLen; - len -= locLen; - if (len != 0) - return S_FALSE; - } - } - - return rc.Finish() ? S_OK : S_FALSE; -} - -HRESULT CDecoder::Code(const Byte *inData, size_t inSize, - ISequentialOutStream *outStream, UInt32 outSize, - bool keepHistory) -{ - try - { - _outWindow.SetStream(outStream); - _outWindow.Init(keepHistory); - if (!keepHistory) - Init(); - - HRESULT res = CodeSpec(inData, inSize, outSize); - HRESULT res2 = _outWindow.Flush(); - return res != S_OK ? res : res2; - } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -HRESULT CDecoder::SetParams(unsigned numDictBits) -{ - if (numDictBits > 21) - return E_INVALIDARG; - _numDictBits = numDictBits; - if (!_outWindow.Create((UInt32)1 << _numDictBits)) - return E_OUTOFMEMORY; - return S_OK; -} - -}} +// QuantumDecoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/Defs.h" + +#include "QuantumDecoder.h" + +namespace NCompress { +namespace NQuantum { + +static const unsigned kNumLenSymbols = 27; +static const unsigned kMatchMinLen = 3; +static const unsigned kNumSimpleLenSlots = 6; + +static const unsigned kUpdateStep = 8; +static const unsigned kFreqSumMax = 3800; +static const unsigned kReorderCount_Start = 4; +static const unsigned kReorderCount = 50; + + +class CRangeDecoder +{ + UInt32 Low; + UInt32 Range; + UInt32 Code; + + unsigned _bitOffset; + const Byte *_buf; + const Byte *_bufLim; + +public: + + Z7_FORCE_INLINE + void Init(const Byte *inData, size_t inSize) + { + Code = ((UInt32)*inData << 8) | inData[1]; + _buf = inData + 2; + _bufLim = inData + inSize; + _bitOffset = 0; + Low = 0; + Range = 0x10000; + } + + Z7_FORCE_INLINE + bool WasExtraRead() const + { + return _buf > _bufLim; + } + + Z7_FORCE_INLINE + UInt32 ReadBits(unsigned numBits) // numBits > 0 + { + unsigned bitOffset = _bitOffset; + const Byte *buf = _buf; + const UInt32 res = GetBe32(buf) << bitOffset; + bitOffset += numBits; + _buf = buf + (bitOffset >> 3); + _bitOffset = bitOffset & 7; + return res >> (32 - numBits); + } + + // ---------- Range Decoder functions ---------- + + Z7_FORCE_INLINE + bool Finish() + { + const unsigned numBits = 2 + ((16 - 2 - _bitOffset) & 7); + if (ReadBits(numBits) != 0) + return false; + return _buf == _bufLim; + } + + Z7_FORCE_INLINE + UInt32 GetThreshold(UInt32 total) const + { + return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; + } + + Z7_FORCE_INLINE + void Decode(UInt32 start, UInt32 end, UInt32 total) + { + // UInt32 hi = ~(Low + end * Range / total - 1); + UInt32 hi = 0 - (Low + end * Range / total); + const UInt32 offset = start * Range / total; + UInt32 lo = Low + offset; + Code -= offset; + UInt32 numBits = 0; + lo ^= hi; + while (lo & (1u << 15)) + { + lo <<= 1; + hi <<= 1; + numBits++; + } + lo ^= hi; + UInt32 an = lo & hi; + while (an & (1u << 14)) + { + an <<= 1; + lo <<= 1; + hi <<= 1; + numBits++; + } + Low = lo; + Range = ((~hi - lo) & 0xffff) + 1; + if (numBits) + Code = (Code << numBits) + ReadBits(numBits); + } +}; + + +// Z7_FORCE_INLINE +Z7_NO_INLINE +unsigned CModelDecoder::Decode(CRangeDecoder *rc) +// Z7_NO_INLINE void CModelDecoder::Normalize() +{ + if (Freqs[0] > kFreqSumMax) + { + if (--ReorderCount == 0) + { + ReorderCount = kReorderCount; + { + unsigned i = NumItems; + unsigned next = 0; + UInt16 *freqs = &Freqs[i]; + do + { + const unsigned freq = *--freqs; + *freqs = (UInt16)((freq - next + 1) >> 1); + next = freq; + } + while (--i); + } + { + for (unsigned i = 0; i < NumItems - 1; i++) + { + UInt16 freq = Freqs[i]; + for (unsigned k = i + 1; k < NumItems; k++) + if (freq < Freqs[k]) + { + const UInt16 freq2 = Freqs[k]; + Freqs[k] = freq; + Freqs[i] = freq2; + freq = freq2; + const Byte val = Vals[i]; + Vals[i] = Vals[k]; + Vals[k] = val; + } + } + } + unsigned i = NumItems; + unsigned freq = 0; + UInt16 *freqs = &Freqs[i]; + do + { + freq += *--freqs; + *freqs = (UInt16)freq; + } + while (--i); + } + else + { + unsigned i = NumItems; + unsigned next = 1; + UInt16 *freqs = &Freqs[i]; + do + { + unsigned freq = *--freqs >> 1; + if (freq < next) + freq = next; + *freqs = (UInt16)freq; + next = freq + 1; + } + while (--i); + } + } + unsigned res; + { + const unsigned freq0 = Freqs[0]; + Freqs[0] = (UInt16)(freq0 + kUpdateStep); + const unsigned threshold = rc->GetThreshold(freq0); + UInt16 *freqs = &Freqs[1]; + unsigned freq = *freqs; + while (freq > threshold) + { + *freqs++ = (UInt16)(freq + kUpdateStep); + freq = *freqs; + } + res = Vals[freqs - Freqs - 1]; + rc->Decode(freq, freqs[-1] - kUpdateStep, freq0); + } + return res; +} + + +Z7_NO_INLINE +void CModelDecoder::Init(unsigned numItems, unsigned startVal) +{ + NumItems = numItems; + ReorderCount = kReorderCount_Start; + UInt16 *freqs = Freqs; + freqs[numItems] = 0; + Byte *vals = Vals; + do + { + *freqs++ = (UInt16)numItems; + *vals++ = (Byte)startVal; + startVal++; + } + while (--numItems); +} + + +HRESULT CDecoder::Code(const Byte *inData, size_t inSize, UInt32 outSize, bool keepHistory) +{ + if (inSize < 2) + return S_FALSE; + if (!keepHistory) + { + _winPos = 0; + m_Selector.Init(kNumSelectors, 0); + unsigned i; + for (i = 0; i < kNumLitSelectors; i++) + m_Literals[i].Init(kNumLitSymbols, i * kNumLitSymbols); + const unsigned numItems = (_numDictBits == 0 ? 1 : (_numDictBits << 1)); + // const unsigned kNumPosSymbolsMax[kNumMatchSelectors] = { 24, 36, 42 }; + for (i = 0; i < kNumMatchSelectors; i++) + { + const unsigned num = 24 + i * 6 + ((i + 1) & 2) * 3; + m_PosSlot[i].Init(MyMin(numItems, num), 0); + } + m_LenSlot.Init(kNumLenSymbols, kMatchMinLen + kNumMatchSelectors - 1); + } + + CRangeDecoder rc; + rc.Init(inData, inSize); + const UInt32 winSize = _winSize; + Byte *pos; + { + UInt32 winPos = _winPos; + if (winPos == winSize) + { + winPos = 0; + _winPos = winPos; + _overWin = true; + } + if (outSize > winSize - winPos) + return S_FALSE; + pos = _win + winPos; + } + + while (outSize != 0) + { + if (rc.WasExtraRead()) + return S_FALSE; + + const unsigned selector = m_Selector.Decode(&rc); + + if (selector < kNumLitSelectors) + { + const unsigned b = m_Literals[selector].Decode(&rc); + *pos++ = (Byte)b; + --outSize; + // if (--outSize == 0) break; + } + else + { + unsigned len = selector - kNumLitSelectors + kMatchMinLen; + + if (selector == kNumLitSelectors + kNumMatchSelectors - 1) + { + len = m_LenSlot.Decode(&rc); + if (len >= kNumSimpleLenSlots + kMatchMinLen + kNumMatchSelectors - 1) + { + len -= kNumSimpleLenSlots - 4 + kMatchMinLen + kNumMatchSelectors - 1; + const unsigned numDirectBits = (unsigned)(len >> 2); + len = ((4 | (len & 3)) << numDirectBits) - (4 << 1) + + kNumSimpleLenSlots + + kMatchMinLen + kNumMatchSelectors - 1; + if (numDirectBits < 6) + len += rc.ReadBits(numDirectBits); + } + } + + UInt32 dist = m_PosSlot[(size_t)selector - kNumLitSelectors].Decode(&rc); + + if (dist >= 4) + { + const unsigned numDirectBits = (unsigned)((dist >> 1) - 1); + dist = ((2 | (dist & 1)) << numDirectBits) + rc.ReadBits(numDirectBits); + } + + if ((Int32)(outSize -= len) < 0) + return S_FALSE; + + ptrdiff_t srcPos = (ptrdiff_t)(Int32)((pos - _win) - (ptrdiff_t)dist - 1); + if (srcPos < 0) + { + if (!_overWin) + return S_FALSE; + UInt32 rem = (UInt32)-srcPos; + srcPos += winSize; + if (rem < len) + { + const Byte *src = _win + srcPos; + len -= rem; + do + *pos++ = *src++; + while (--rem); + srcPos = 0; + } + } + const Byte *src = _win + srcPos; + do + *pos++ = *src++; + while (--len); + // if (outSize == 0) break; + } + } + + _winPos = (UInt32)(size_t)(pos - _win); + return rc.Finish() ? S_OK : S_FALSE; +} + + +HRESULT CDecoder::SetParams(unsigned numDictBits) +{ + if (numDictBits > 21) + return E_INVALIDARG; + _numDictBits = numDictBits; + _winPos = 0; + _overWin = false; + + if (numDictBits < 15) + numDictBits = 15; + _winSize = (UInt32)1 << numDictBits; + if (!_win || _winSize > _winSize_allocated) + { + MidFree(_win); + _win = NULL; + _win = (Byte *)MidAlloc(_winSize); + if (!_win) + return E_OUTOFMEMORY; + _winSize_allocated = _winSize; + } + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/QuantumDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/QuantumDecoder.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/QuantumDecoder.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,175 +1,60 @@ -// QuantumDecoder.h - -#ifndef __COMPRESS_QUANTUM_DECODER_H -#define __COMPRESS_QUANTUM_DECODER_H - -#include "../../Common/MyCom.h" - -#include "LzOutWindow.h" - -namespace NCompress { -namespace NQuantum { - -class CBitDecoder -{ - UInt32 Value; - bool _extra; - const Byte *_buf; - const Byte *_bufLim; -public: - void SetStreamAndInit(const Byte *inData, size_t inSize) - { - _buf = inData; - _bufLim = inData + inSize; - Value = 0x10000; - _extra = false; - } - - bool WasExtraRead() const { return _extra; } - - bool WasFinishedOK() const - { - return !_extra && _buf == _bufLim; - } - - UInt32 ReadBit() - { - if (Value >= 0x10000) - { - Byte b; - if (_buf >= _bufLim) - { - b = 0xFF; - _extra = true; - } - else - b = *_buf++; - Value = 0x100 | b; - } - UInt32 res = (Value >> 7) & 1; - Value <<= 1; - return res; - } - - UInt32 ReadStart16Bits() - { - // we use check for extra read in another code. - UInt32 val = ((UInt32)*_buf << 8) | _buf[1]; - _buf += 2; - return val; - } - - UInt32 ReadBits(unsigned numBits) // numBits > 0 - { - UInt32 res = 0; - do - res = (res << 1) | ReadBit(); - while (--numBits); - return res; - } -}; - - -class CRangeDecoder -{ - UInt32 Low; - UInt32 Range; - UInt32 Code; -public: - CBitDecoder Stream; - - void Init() - { - Low = 0; - Range = 0x10000; - Code = Stream.ReadStart16Bits(); - } - - bool Finish() - { - // do all streams use these two bits at end? - if (Stream.ReadBit() != 0) return false; - if (Stream.ReadBit() != 0) return false; - return Stream.WasFinishedOK(); - } - - UInt32 GetThreshold(UInt32 total) const - { - return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; - } - - void Decode(UInt32 start, UInt32 end, UInt32 total) - { - UInt32 high = Low + end * Range / total - 1; - UInt32 offset = start * Range / total; - Code -= offset; - Low += offset; - for (;;) - { - if ((Low & 0x8000) != (high & 0x8000)) - { - if ((Low & 0x4000) == 0 || (high & 0x4000) != 0) - break; - Low &= 0x3FFF; - high |= 0x4000; - } - Low = (Low << 1) & 0xFFFF; - high = ((high << 1) | 1) & 0xFFFF; - Code = ((Code << 1) | Stream.ReadBit()); - } - Range = high - Low + 1; - } -}; - - -const unsigned kNumLitSelectorBits = 2; -const unsigned kNumLitSelectors = (1 << kNumLitSelectorBits); -const unsigned kNumLitSymbols = 1 << (8 - kNumLitSelectorBits); -const unsigned kNumMatchSelectors = 3; -const unsigned kNumSelectors = kNumLitSelectors + kNumMatchSelectors; -const unsigned kNumSymbolsMax = kNumLitSymbols; // 64 - - -class CModelDecoder -{ - unsigned NumItems; - unsigned ReorderCount; - UInt16 Freqs[kNumSymbolsMax + 1]; - Byte Vals[kNumSymbolsMax]; -public: - void Init(unsigned numItems); - unsigned Decode(CRangeDecoder *rc); -}; - - -class CDecoder: - public IUnknown, - public CMyUnknownImp -{ - CLzOutWindow _outWindow; - unsigned _numDictBits; - - CModelDecoder m_Selector; - CModelDecoder m_Literals[kNumLitSelectors]; - CModelDecoder m_PosSlot[kNumMatchSelectors]; - CModelDecoder m_LenSlot; - - void Init(); - HRESULT CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize); -public: - - MY_UNKNOWN_IMP - - HRESULT Code(const Byte *inData, size_t inSize, - ISequentialOutStream *outStream, UInt32 outSize, - bool keepHistory); - - HRESULT SetParams(unsigned numDictBits); - - CDecoder(): _numDictBits(0) {} - virtual ~CDecoder() {} -}; - -}} - -#endif +// QuantumDecoder.h + +#ifndef ZIP7_INC_COMPRESS_QUANTUM_DECODER_H +#define ZIP7_INC_COMPRESS_QUANTUM_DECODER_H + +#include "../../Common/MyTypes.h" + +namespace NCompress { +namespace NQuantum { + +const unsigned kNumLitSelectorBits = 2; +const unsigned kNumLitSelectors = 1 << kNumLitSelectorBits; +const unsigned kNumLitSymbols = 1 << (8 - kNumLitSelectorBits); +const unsigned kNumMatchSelectors = 3; +const unsigned kNumSelectors = kNumLitSelectors + kNumMatchSelectors; +const unsigned kNumSymbolsMax = kNumLitSymbols; // 64 + +class CRangeDecoder; + +class CModelDecoder +{ + unsigned NumItems; + unsigned ReorderCount; + Byte Vals[kNumSymbolsMax]; + UInt16 Freqs[kNumSymbolsMax + 1]; +public: + Byte _pad[64 - 10]; // for structure size alignment + + void Init(unsigned numItems, unsigned startVal); + unsigned Decode(CRangeDecoder *rc); +}; + + +class CDecoder +{ + UInt32 _winSize; + UInt32 _winPos; + UInt32 _winSize_allocated; + bool _overWin; + Byte *_win; + unsigned _numDictBits; + + CModelDecoder m_Selector; + CModelDecoder m_Literals[kNumLitSelectors]; + CModelDecoder m_PosSlot[kNumMatchSelectors]; + CModelDecoder m_LenSlot; + + void Init(); + HRESULT CodeSpec(const Byte *inData, size_t inSize, UInt32 outSize); +public: + HRESULT Code(const Byte *inData, size_t inSize, UInt32 outSize, bool keepHistory); + HRESULT SetParams(unsigned numDictBits); + + CDecoder(): _win(NULL), _numDictBits(0) {} + const Byte * GetDataPtr() const { return _win + _winPos; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile --- p7zip-rar-16.02/CPP/7zip/Compress/Rar/makefile 2016-03-10 20:20:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ - -TARGET_FLAGS=$(CC_SHARED) -DRegisterCodec=DllRegisterCodec - -MY_WINDOWS= - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LOCAL_LINK=$(LINK_SHARED) -LIBS=$(LOCAL_LIBS) - -COMPRESS_OBJS = \ - CodecExports.o \ - DllExportsCompress.o \ - -RAR29_OPT_OBJS = \ - LzOutWindow.o \ - Rar1Decoder.o \ - Rar2Decoder.o \ - Rar3Decoder.o \ - Rar3Vm.o \ - RarCodecsRegister.o \ - -COMMON_OBJS = \ - CRC.o \ - MyVector.o \ - -P7ZIP_COMMON_OBJS = \ - InBuffer.o \ - OutBuffer.o \ - StreamUtils.o \ - -C_OBJS = \ - Alloc.o \ - CpuArch.o \ - -OBJS = \ -MyWindows.o \ -Ppmd7.o \ -Ppmd7Dec.o \ -$(COMPRESS_OBJS) \ -$(RAR29_OPT_OBJS) \ -$(COMMON_OBJS) \ -$(P7ZIP_COMMON_OBJS) \ -$(C_OBJS) \ -7zCrc.o $(OBJ_CRC32) \ - -include ../../../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile.list --- p7zip-rar-16.02/CPP/7zip/Compress/Rar/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/Codecs/Rar.so - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Rar1Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar3Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar3Vm.cpp \ - ../../../../CPP/7zip/Compress/Rar5Decoder.cpp \ - ../../../../CPP/7zip/Compress/RarCodecsRegister.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Ppmd7.o : ../../../../C/Ppmd7.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7.c -Ppmd7Dec.o : ../../../../C/Ppmd7Dec.c - $(CC) $(CFLAGS) ../../../../C/Ppmd7Dec.c -InBuffer.o : ../../../../CPP/7zip/Common/InBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/InBuffer.cpp -OutBuffer.o : ../../../../CPP/7zip/Common/OutBuffer.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/OutBuffer.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -CodecExports.o : ../../../../CPP/7zip/Compress/CodecExports.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CodecExports.cpp -DllExportsCompress.o : ../../../../CPP/7zip/Compress/DllExportsCompress.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/DllExportsCompress.cpp -LzOutWindow.o : ../../../../CPP/7zip/Compress/LzOutWindow.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/LzOutWindow.cpp -Rar1Decoder.o : ../../../../CPP/7zip/Compress/Rar1Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Rar1Decoder.cpp -Rar2Decoder.o : ../../../../CPP/7zip/Compress/Rar2Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Rar2Decoder.cpp -Rar3Decoder.o : ../../../../CPP/7zip/Compress/Rar3Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Rar3Decoder.cpp -Rar3Vm.o : ../../../../CPP/7zip/Compress/Rar3Vm.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Rar3Vm.cpp -Rar5Decoder.o : ../../../../CPP/7zip/Compress/Rar5Decoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/Rar5Decoder.cpp -RarCodecsRegister.o : ../../../../CPP/7zip/Compress/RarCodecsRegister.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/RarCodecsRegister.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Alloc.o \ - CpuArch.o \ - Ppmd7.o \ - Ppmd7Dec.o \ - InBuffer.o \ - OutBuffer.o \ - StreamUtils.o \ - CodecExports.o \ - DllExportsCompress.o \ - LzOutWindow.o \ - Rar1Decoder.o \ - Rar2Decoder.o \ - Rar3Decoder.o \ - Rar3Vm.o \ - Rar5Decoder.o \ - RarCodecsRegister.o \ - CRC.o \ - MyVector.o \ - MyWindows.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar1Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Rar1Decoder.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.cpp 2023-03-28 14:00:00.000000000 +0000 @@ -1,493 +1,518 @@ -// Rar1Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#include "StdAfx.h" - -#include "Rar1Decoder.h" - -namespace NCompress { -namespace NRar1 { - -static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; -static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; -static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; -static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; -static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0}; -static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0}; -static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0}; - -static const UInt32 kHistorySize = (1 << 16); - -/* -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() { m_Coder->ReleaseStreams(); } -}; -*/ - -CDecoder::CDecoder(): m_IsSolid(false) { } - -void CDecoder::InitStructures() -{ - for (int i = 0; i < kNumRepDists; i++) - m_RepDists[i] = 0; - m_RepDistPtr = 0; - LastLength = 0; - LastDist = 0; -} - -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } - -HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) -{ - if (len == 0) - return S_FALSE; - m_UnpackSize -= len; - return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; -} - - -UInt32 CDecoder::DecodeNum(const UInt32 *posTab) -{ - UInt32 startPos = 2; - UInt32 num = m_InBitStream.GetValue(12); - for (;;) - { - UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos); - if (num < cur) - break; - startPos++; - num -= cur; - } - m_InBitStream.MovePos(startPos); - return((num >> (12 - startPos)) + posTab[startPos]); -} - -static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; -static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; -static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; -static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; -static const UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; -static const UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; - -HRESULT CDecoder::ShortLZ() -{ - UInt32 len, saveLen, dist; - int distancePlace; - const Byte *kShortLen; - const UInt32 *kShortXor; - NumHuf = 0; - - if (LCount == 2) - { - if (ReadBits(1)) - return CopyBlock(LastDist, LastLength); - LCount = 0; - } - - UInt32 bitField = m_InBitStream.GetValue(8); - - if (AvrLn1 < 37) - { - kShortLen = Buf60 ? kShortLen1a : kShortLen1; - kShortXor = kShortXor1; - } - else - { - kShortLen = Buf60 ? kShortLen2a : kShortLen2; - kShortXor = kShortXor2; - } - - for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++); - m_InBitStream.MovePos(kShortLen[len]); - - if (len >= 9) - { - if (len == 9) - { - LCount++; - return CopyBlock(LastDist, LastLength); - } - if (len == 14) - { - LCount = 0; - len = DecodeNum(PosL2) + 5; - dist = 0x8000 + ReadBits(15) - 1; - LastLength = len; - LastDist = dist; - return CopyBlock(dist, len); - } - - LCount = 0; - saveLen = len; - dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; - len = DecodeNum(PosL1) + 2; - if (len == 0x101 && saveLen == 10) - { - Buf60 ^= 1; - return S_OK; - } - if (dist >= 256) - len++; - if (dist >= MaxDist3 - 1) - len++; - } - else - { - LCount = 0; - AvrLn1 += len; - AvrLn1 -= AvrLn1 >> 4; - - distancePlace = DecodeNum(PosHf2) & 0xff; - dist = ChSetA[(unsigned)distancePlace]; - if (--distancePlace != -1) - { - PlaceA[dist]--; - UInt32 lastDistance = ChSetA[(unsigned)distancePlace]; - PlaceA[lastDistance]++; - ChSetA[(unsigned)distancePlace + 1] = lastDistance; - ChSetA[(unsigned)distancePlace] = dist; - } - len += 2; - } - - m_RepDists[m_RepDistPtr++] = dist; - m_RepDistPtr &= 3; - LastLength = len; - LastDist = dist; - return CopyBlock(dist, len); -} - - -HRESULT CDecoder::LongLZ() -{ - UInt32 len; - UInt32 dist; - UInt32 distancePlace, newDistancePlace; - UInt32 oldAvr2, oldAvr3; - - NumHuf = 0; - Nlzb += 16; - if (Nlzb > 0xff) - { - Nlzb = 0x90; - Nhfb >>= 1; - } - oldAvr2=AvrLn2; - - if (AvrLn2 >= 122) - len = DecodeNum(PosL2); - else if (AvrLn2 >= 64) - len = DecodeNum(PosL1); - else - { - UInt32 bitField = m_InBitStream.GetValue(16); - if (bitField < 0x100) - { - len = bitField; - m_InBitStream.MovePos(16); - } - else - { - for (len = 0; ((bitField << len) & 0x8000) == 0; len++) - ; - m_InBitStream.MovePos(len + 1); - } - } - - AvrLn2 += len; - AvrLn2 -= AvrLn2 >> 5; - - if (AvrPlcB > 0x28ff) - distancePlace = DecodeNum(PosHf2); - else if (AvrPlcB > 0x6ff) - distancePlace = DecodeNum(PosHf1); - else - distancePlace = DecodeNum(PosHf0); - - AvrPlcB += distancePlace; - AvrPlcB -= AvrPlcB >> 8; - - for (;;) - { - dist = ChSetB[distancePlace & 0xff]; - newDistancePlace = NToPlB[dist++ & 0xff]++; - if (!(dist & 0xff)) - CorrHuff(ChSetB,NToPlB); - else - break; - } - - ChSetB[distancePlace] = ChSetB[newDistancePlace]; - ChSetB[newDistancePlace] = dist; - - dist = ((dist & 0xff00) >> 1) | ReadBits(7); - - oldAvr3 = AvrLn3; - - if (len != 1 && len != 4) - if (len == 0 && dist <= MaxDist3) - { - AvrLn3++; - AvrLn3 -= AvrLn3 >> 8; - } - else - if (AvrLn3 > 0) - AvrLn3--; - - len += 3; - - if (dist >= MaxDist3) - len++; - if (dist <= 256) - len += 8; - - if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40) - MaxDist3 = 0x7f00; - else - MaxDist3 = 0x2001; - - m_RepDists[m_RepDistPtr++] = --dist; - m_RepDistPtr &= 3; - LastLength = len; - LastDist = dist; - - return CopyBlock(dist, len); -} - - -HRESULT CDecoder::HuffDecode() -{ - UInt32 curByte, newBytePlace; - UInt32 len; - UInt32 dist; - int bytePlace; - - if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); - else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); - else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); - else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); - else bytePlace = DecodeNum(PosHf0); - - if (StMode) - { - if (--bytePlace == -1) - { - if (ReadBits(1)) - { - NumHuf = StMode = 0; - return S_OK; - } - else - { - len = (ReadBits(1)) ? 4 : 3; - dist = DecodeNum(PosHf2); - dist = (dist << 5) | ReadBits(5); - return CopyBlock(dist - 1, len); - } - } - } - else if (NumHuf++ >= 16 && FlagsCnt == 0) - StMode = 1; - - bytePlace &= 0xff; - AvrPlc += bytePlace; - AvrPlc -= AvrPlc >> 8; - Nhfb+=16; - - if (Nhfb > 0xff) - { - Nhfb=0x90; - Nlzb >>= 1; - } - - m_UnpackSize --; - m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); - - for (;;) - { - curByte = ChSet[bytePlace]; - newBytePlace = NToPl[curByte++ & 0xff]++; - if ((curByte & 0xff) > 0xa1) - CorrHuff(ChSet, NToPl); - else - break; - } - - ChSet[bytePlace] = ChSet[newBytePlace]; - ChSet[newBytePlace] = curByte; - return S_OK; -} - - -void CDecoder::GetFlagsBuf() -{ - UInt32 flags, newFlagsPlace; - UInt32 flagsPlace = DecodeNum(PosHf2); - - for (;;) - { - flags = ChSetC[flagsPlace]; - FlagBuf = flags >> 8; - newFlagsPlace = NToPlC[flags++ & 0xff]++; - if ((flags & 0xff) != 0) - break; - CorrHuff(ChSetC, NToPlC); - } - - ChSetC[flagsPlace] = ChSetC[newFlagsPlace]; - ChSetC[newFlagsPlace] = flags; -} - -void CDecoder::InitData() -{ - if (!m_IsSolid) - { - AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; - AvrPlc = 0x3500; - MaxDist3 = 0x2001; - Nhfb = Nlzb = 0x80; - } - FlagsCnt = 0; - FlagBuf = 0; - StMode = 0; - LCount = 0; -} - -void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) -{ - int i; - for (i = 7; i >= 0; i--) - for (int j = 0; j < 32; j++, CharSet++) - *CharSet = (*CharSet & ~0xff) | i; - memset(NumToPlace, 0, sizeof(NToPl)); - for (i = 6; i >= 0; i--) - NumToPlace[i] = (7 - i) * 32; -} - -void CDecoder::InitHuff() -{ - for (UInt32 i = 0; i < 256; i++) - { - Place[i] = PlaceA[i] = PlaceB[i] = i; - PlaceC[i] = (~i + 1) & 0xff; - ChSet[i] = ChSetB[i] = i << 8; - ChSetA[i] = i; - ChSetC[i] = ((~i + 1) & 0xff) << 8; - } - memset(NToPl, 0, sizeof(NToPl)); - memset(NToPlB, 0, sizeof(NToPlB)); - memset(NToPlC, 0, sizeof(NToPlC)); - CorrHuff(ChSetB, NToPlB); -} - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) -{ - if (inSize == NULL || outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_UnpackSize = (Int64)*outSize; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - // CCoderReleaser coderReleaser(this); - InitData(); - if (!m_IsSolid) - { - InitStructures(); - InitHuff(); - } - if (m_UnpackSize > 0) - { - GetFlagsBuf(); - FlagsCnt = 8; - } - - while (m_UnpackSize > 0) - { - if (StMode) - { - RINOK(HuffDecode()); - continue; - } - - if (--FlagsCnt < 0) - { - GetFlagsBuf(); - FlagsCnt=7; - } - - if (FlagBuf & 0x80) - { - FlagBuf <<= 1; - if (Nlzb > Nhfb) - { - RINOK(LongLZ()); - } - else - { - RINOK(HuffDecode()); - } - } - else - { - FlagBuf <<= 1; - if (--FlagsCnt < 0) - { - GetFlagsBuf(); - FlagsCnt = 7; - } - if (FlagBuf & 0x80) - { - FlagBuf <<= 1; - if (Nlzb > Nhfb) - { - RINOK(HuffDecode()); - } - else - { - RINOK(LongLZ()); - } - } - else - { - FlagBuf <<= 1; - RINOK(ShortLZ()); - } - } - } - if (m_UnpackSize < 0) - return S_FALSE; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size < 1) - return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); - return S_OK; -} - -}} +// Rar1Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#include "Rar1Decoder.h" + +namespace NCompress { +namespace NRar1 { + +static const unsigned kNumBits = 12; + +static const Byte kShortLen1[16 * 3] = +{ + 0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0,0, + 1,3,4,4,5,6,7,8,8,4,4,5,6,6,0,0, + 1,4,4,4,5,6,7,8,8,4,4,5,6,6,4,0 +}; + +static const Byte kShortLen2[16 * 3] = +{ + 0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0,0, + 2,3,3,3,4,4,5,6,6,4,4,5,6,6,0,0, + 2,3,3,4,4,4,5,6,6,4,4,5,6,6,4,0 +}; + +static const Byte PosL1[kNumBits + 1] = { 0,0,2,1,2,2,4,5,4,4,8,0,224 }; +static const Byte PosL2[kNumBits + 1] = { 0,0,0,5,2,2,4,5,4,4,8,2,220 }; + +static const Byte PosHf0[kNumBits + 1] = { 0,0,0,0,8,8,8,9,0,0,0,0,224 }; +static const Byte PosHf1[kNumBits + 1] = { 0,0,0,0,0,4,40,16,16,4,0,47,130 }; +static const Byte PosHf2[kNumBits + 1] = { 0,0,0,0,0,2,5,46,64,116,24,0,0 }; +static const Byte PosHf3[kNumBits + 1] = { 0,0,0,0,0,0,2,14,202,33,6,0,0 }; +static const Byte PosHf4[kNumBits + 1] = { 0,0,0,0,0,0,0,0,255,2,0,0,0 }; + +static const UInt32 kHistorySize = (1 << 16); + +CDecoder::CDecoder(): + _isSolid(false), + _solidAllowed(false) + {} + +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } + +HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) +{ + if (len == 0) + return S_FALSE; + if (m_UnpackSize < len) + return S_FALSE; + m_UnpackSize -= len; + return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; +} + + +UInt32 CDecoder::DecodeNum(const Byte *numTab) +{ + /* + { + // we can check that tables are correct + UInt32 sum = 0; + for (unsigned i = 0; i <= kNumBits; i++) + sum += ((UInt32)numTab[i] << (kNumBits - i)); + if (sum != (1 << kNumBits)) + throw 111; + } + */ + + UInt32 val = m_InBitStream.GetValue(kNumBits); + UInt32 sum = 0; + unsigned i = 2; + + for (;;) + { + const UInt32 num = numTab[i]; + const UInt32 cur = num << (kNumBits - i); + if (val < cur) + break; + i++; + val -= cur; + sum += num; + } + m_InBitStream.MovePos(i); + return ((val >> (kNumBits - i)) + sum); +} + + +HRESULT CDecoder::ShortLZ() +{ + NumHuf = 0; + + if (LCount == 2) + { + if (ReadBits(1)) + return CopyBlock(LastDist, LastLength); + LCount = 0; + } + + UInt32 bitField = m_InBitStream.GetValue(8); + + UInt32 len, dist; + { + const Byte *xors = (AvrLn1 < 37) ? kShortLen1 : kShortLen2; + const Byte *lens = xors + 16 + Buf60; + for (len = 0; ((bitField ^ xors[len]) >> (8 - lens[len])) != 0; len++); + m_InBitStream.MovePos(lens[len]); + } + + if (len >= 9) + { + if (len == 9) + { + LCount++; + return CopyBlock(LastDist, LastLength); + } + + LCount = 0; + + if (len == 14) + { + len = DecodeNum(PosL2) + 5; + dist = 0x8000 + ReadBits(15) - 1; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); + } + + const UInt32 saveLen = len; + dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; + + len = DecodeNum(PosL1); + + if (len == 0xff && saveLen == 10) + { + Buf60 ^= 16; + return S_OK; + } + if (dist >= 256) + { + len++; + if (dist >= MaxDist3 - 1) + len++; + } + } + else + { + LCount = 0; + AvrLn1 += len; + AvrLn1 -= AvrLn1 >> 4; + + unsigned distancePlace = DecodeNum(PosHf2) & 0xff; + + dist = ChSetA[distancePlace]; + + if (distancePlace != 0) + { + PlaceA[dist]--; + UInt32 lastDistance = ChSetA[(size_t)distancePlace - 1]; + PlaceA[lastDistance]++; + ChSetA[distancePlace] = lastDistance; + ChSetA[(size_t)distancePlace - 1] = dist; + } + } + + m_RepDists[m_RepDistPtr++] = dist; + m_RepDistPtr &= 3; + len += 2; + LastLength = len; + LastDist = dist; + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::LongLZ() +{ + UInt32 len; + UInt32 dist; + UInt32 distancePlace, newDistancePlace; + UInt32 oldAvr2, oldAvr3; + + NumHuf = 0; + Nlzb += 16; + if (Nlzb > 0xff) + { + Nlzb = 0x90; + Nhfb >>= 1; + } + oldAvr2 = AvrLn2; + + if (AvrLn2 >= 64) + len = DecodeNum(AvrLn2 < 122 ? PosL1 : PosL2); + else + { + UInt32 bitField = m_InBitStream.GetValue(16); + if (bitField < 0x100) + { + len = bitField; + m_InBitStream.MovePos(16); + } + else + { + for (len = 0; ((bitField << len) & 0x8000) == 0; len++); + + m_InBitStream.MovePos(len + 1); + } + } + + AvrLn2 += len; + AvrLn2 -= AvrLn2 >> 5; + + { + const Byte *tab; + if (AvrPlcB >= 0x2900) tab = PosHf2; + else if (AvrPlcB >= 0x0700) tab = PosHf1; + else tab = PosHf0; + distancePlace = DecodeNum(tab); // [0, 256] + } + + AvrPlcB += distancePlace; + AvrPlcB -= AvrPlcB >> 8; + + distancePlace &= 0xff; + + for (;;) + { + dist = ChSetB[distancePlace]; + newDistancePlace = NToPlB[dist++ & 0xff]++; + if (dist & 0xff) + break; + CorrHuff(ChSetB,NToPlB); + } + + ChSetB[distancePlace] = ChSetB[newDistancePlace]; + ChSetB[newDistancePlace] = dist; + + dist = ((dist & 0xff00) >> 1) | ReadBits(7); + + oldAvr3 = AvrLn3; + + if (len != 1 && len != 4) + { + if (len == 0 && dist <= MaxDist3) + { + AvrLn3++; + AvrLn3 -= AvrLn3 >> 8; + } + else if (AvrLn3 > 0) + AvrLn3--; + } + + len += 3; + + if (dist >= MaxDist3) + len++; + if (dist <= 256) + len += 8; + + if (oldAvr3 > 0xb0 || (AvrPlc >= 0x2a00 && oldAvr2 < 0x40)) + MaxDist3 = 0x7f00; + else + MaxDist3 = 0x2001; + + m_RepDists[m_RepDistPtr++] = --dist; + m_RepDistPtr &= 3; + LastLength = len; + LastDist = dist; + + return CopyBlock(dist, len); +} + + +HRESULT CDecoder::HuffDecode() +{ + UInt32 curByte, newBytePlace; + UInt32 len; + UInt32 dist; + unsigned bytePlace; + { + const Byte *tab; + + if (AvrPlc >= 0x7600) tab = PosHf4; + else if (AvrPlc >= 0x5e00) tab = PosHf3; + else if (AvrPlc >= 0x3600) tab = PosHf2; + else if (AvrPlc >= 0x0e00) tab = PosHf1; + else tab = PosHf0; + + bytePlace = DecodeNum(tab); // [0, 256] + } + + if (StMode) + { + if (bytePlace == 0) + { + if (ReadBits(1)) + { + NumHuf = 0; + StMode = false; + return S_OK; + } + len = ReadBits(1) + 3; + dist = DecodeNum(PosHf2); + dist = (dist << 5) | ReadBits(5); + if (dist == 0) + return S_FALSE; + return CopyBlock(dist - 1, len); + } + bytePlace--; // bytePlace is [0, 255] + } + else if (NumHuf++ >= 16 && FlagsCnt == 0) + StMode = true; + + bytePlace &= 0xff; + AvrPlc += bytePlace; + AvrPlc -= AvrPlc >> 8; + Nhfb += 16; + + if (Nhfb > 0xff) + { + Nhfb = 0x90; + Nlzb >>= 1; + } + + m_UnpackSize--; + m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); + + for (;;) + { + curByte = ChSet[bytePlace]; + newBytePlace = NToPl[curByte++ & 0xff]++; + if ((curByte & 0xff) <= 0xa1) + break; + CorrHuff(ChSet, NToPl); + } + + ChSet[bytePlace] = ChSet[newBytePlace]; + ChSet[newBytePlace] = curByte; + return S_OK; +} + + +void CDecoder::GetFlagsBuf() +{ + UInt32 flags, newFlagsPlace; + const UInt32 flagsPlace = DecodeNum(PosHf2); // [0, 256] + + if (flagsPlace >= Z7_ARRAY_SIZE(ChSetC)) + return; + + for (;;) + { + flags = ChSetC[flagsPlace]; + FlagBuf = flags >> 8; + newFlagsPlace = NToPlC[flags++ & 0xff]++; + if ((flags & 0xff) != 0) + break; + CorrHuff(ChSetC, NToPlC); + } + + ChSetC[flagsPlace] = ChSetC[newFlagsPlace]; + ChSetC[newFlagsPlace] = flags; +} + + +void CDecoder::CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace) +{ + int i; + for (i = 7; i >= 0; i--) + for (unsigned j = 0; j < 32; j++, CharSet++) + *CharSet = (*CharSet & ~(UInt32)0xff) | (unsigned)i; + memset(NumToPlace, 0, sizeof(NToPl)); + for (i = 6; i >= 0; i--) + NumToPlace[i] = (7 - (unsigned)i) * 32; +} + + + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) +{ + if (!inSize || !outSize) + return E_INVALIDARG; + + if (_isSolid && !_solidAllowed) + return S_FALSE; + + _solidAllowed = false; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_UnpackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(_isSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + // InitData + + FlagsCnt = 0; + FlagBuf = 0; + StMode = false; + LCount = 0; + + if (!_isSolid) + { + AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; + AvrPlc = 0x3500; + MaxDist3 = 0x2001; + Nhfb = Nlzb = 0x80; + + { + // InitStructures + for (unsigned i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + LastLength = 0; + LastDist = 0; + } + + // InitHuff + + for (UInt32 i = 0; i < 256; i++) + { + Place[i] = PlaceA[i] = PlaceB[i] = i; + UInt32 c = (~i + 1) & 0xff; + PlaceC[i] = c; + ChSet[i] = ChSetB[i] = i << 8; + ChSetA[i] = i; + ChSetC[i] = c << 8; + } + memset(NToPl, 0, sizeof(NToPl)); + memset(NToPlB, 0, sizeof(NToPlB)); + memset(NToPlC, 0, sizeof(NToPlC)); + CorrHuff(ChSetB, NToPlB); + } + + if (m_UnpackSize > 0) + { + GetFlagsBuf(); + FlagsCnt = 8; + } + + while (m_UnpackSize != 0) + { + if (!StMode) + { + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt = 7; + } + + if (FlagBuf & 0x80) + { + FlagBuf <<= 1; + if (Nlzb > Nhfb) + { + RINOK(LongLZ()) + continue; + } + } + else + { + FlagBuf <<= 1; + + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt = 7; + } + + if ((FlagBuf & 0x80) == 0) + { + FlagBuf <<= 1; + RINOK(ShortLZ()) + continue; + } + + FlagBuf <<= 1; + + if (Nlzb <= Nhfb) + { + RINOK(LongLZ()) + continue; + } + } + } + + RINOK(HuffDecode()) + } + + _solidAllowed = true; + return m_OutWindowStream.Flush(); +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size < 1) + return E_INVALIDARG; + _isSolid = ((data[0] & 1) != 0); + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar1Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Rar1Decoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar1Decoder.h 2024-01-01 18:00:00.000000000 +0000 @@ -1,90 +1,70 @@ -// Rar1Decoder.h -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#ifndef __COMPRESS_RAR1_DECODER_H -#define __COMPRESS_RAR1_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "HuffmanDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NRar1 { - -const UInt32 kNumRepDists = 4; - -typedef NBitm::CDecoder CBitDecoder; - -class CDecoder : - public ICompressCoder, - public ICompressSetDecoderProperties2, - public CMyUnknownImp -{ -public: - CLzOutWindow m_OutWindowStream; - CBitDecoder m_InBitStream; - - UInt32 m_RepDists[kNumRepDists]; - UInt32 m_RepDistPtr; - - UInt32 LastDist; - UInt32 LastLength; - - Int64 m_UnpackSize; - bool m_IsSolid; - - UInt32 ReadBits(int numBits); - HRESULT CopyBlock(UInt32 distance, UInt32 len); - - UInt32 DecodeNum(const UInt32 *posTab); - HRESULT ShortLZ(); - HRESULT LongLZ(); - HRESULT HuffDecode(); - void GetFlagsBuf(); - void InitData(); - void InitHuff(); - void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); - void OldUnpWriteBuf(); - - UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; - UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256]; - UInt32 NToPl[256],NToPlB[256],NToPlC[256]; - UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; - int Buf60,NumHuf,StMode,LCount,FlagsCnt; - UInt32 Nhfb,Nlzb,MaxDist3; - - void InitStructures(); - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - -public: - CDecoder(); - - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - */ - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - -}; - -}} - -#endif +// Rar1Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef ZIP7_INC_COMPRESS_RAR1_DECODER_H +#define ZIP7_INC_COMPRESS_RAR1_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NRar1 { + +const unsigned kNumRepDists = 4; + +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressCoder + , ICompressSetDecoderProperties2 +) + bool _isSolid; + bool _solidAllowed; + bool StMode; + + CLzOutWindow m_OutWindowStream; + NBitm::CDecoder m_InBitStream; + + UInt64 m_UnpackSize; + + UInt32 LastDist; + UInt32 LastLength; + + UInt32 m_RepDistPtr; + UInt32 m_RepDists[kNumRepDists]; + + int FlagsCnt; + UInt32 FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3; + unsigned Buf60, NumHuf, LCount; + UInt32 Nhfb, Nlzb, MaxDist3; + + UInt32 ChSet[256], ChSetA[256], ChSetB[256], ChSetC[256]; + UInt32 Place[256], PlaceA[256], PlaceB[256], PlaceC[256]; + UInt32 NToPl[256], NToPlB[256], NToPlC[256]; + + UInt32 ReadBits(unsigned numBits); + HRESULT CopyBlock(UInt32 distance, UInt32 len); + UInt32 DecodeNum(const Byte *numTab); + HRESULT ShortLZ(); + HRESULT LongLZ(); + HRESULT HuffDecode(); + void GetFlagsBuf(); + void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace); + void OldUnpWriteBuf(); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + +public: + CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar2Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Rar2Decoder.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.cpp 2024-01-07 11:00:00.000000000 +0000 @@ -1,401 +1,472 @@ -// Rar2Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#include "StdAfx.h" - -#include "Rar2Decoder.h" - -namespace NCompress { -namespace NRar2 { - -namespace NMultimedia { - -Byte CFilter::Decode(int &channelDelta, Byte deltaByte) -{ - D4 = D3; - D3 = D2; - D2 = LastDelta - D1; - D1 = LastDelta; - int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); - - Byte realValue = (Byte)(predictedValue - deltaByte); - - { - int i = ((int)(signed char)deltaByte) << 3; - - Dif[0] += abs(i); - Dif[1] += abs(i - D1); - Dif[2] += abs(i + D1); - Dif[3] += abs(i - D2); - Dif[4] += abs(i + D2); - Dif[5] += abs(i - D3); - Dif[6] += abs(i + D3); - Dif[7] += abs(i - D4); - Dif[8] += abs(i + D4); - Dif[9] += abs(i - channelDelta); - Dif[10] += abs(i + channelDelta); - } - - channelDelta = LastDelta = (signed char)(realValue - LastChar); - LastChar = realValue; - - if (((++ByteCount) & 0x1F) == 0) - { - UInt32 minDif = Dif[0]; - UInt32 numMinDif = 0; - Dif[0] = 0; - - for (unsigned i = 1; i < ARRAY_SIZE(Dif); i++) - { - if (Dif[i] < minDif) - { - minDif = Dif[i]; - numMinDif = i; - } - Dif[i] = 0; - } - - switch (numMinDif) - { - case 1: if (K1 >= -16) K1--; break; - case 2: if (K1 < 16) K1++; break; - case 3: if (K2 >= -16) K2--; break; - case 4: if (K2 < 16) K2++; break; - case 5: if (K3 >= -16) K3--; break; - case 6: if (K3 < 16) K3++; break; - case 7: if (K4 >= -16) K4--; break; - case 8: if (K4 < 16) K4++; break; - case 9: if (K5 >= -16) K5--; break; - case 10:if (K5 < 16) K5++; break; - } - } - - return realValue; -} -} - -static const UInt32 kHistorySize = 1 << 20; - -static const UInt32 kWindowReservSize = (1 << 22) + 256; - -CDecoder::CDecoder(): - m_IsSolid(false) -{ -} - -void CDecoder::InitStructures() -{ - m_MmFilter.Init(); - for (unsigned i = 0; i < kNumRepDists; i++) - m_RepDists[i] = 0; - m_RepDistPtr = 0; - m_LastLength = 0; - memset(m_LastLevels, 0, kMaxTableSize); -} - -UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } - -#define RIF(x) { if (!(x)) return false; } - -bool CDecoder::ReadTables(void) -{ - Byte levelLevels[kLevelTableSize]; - Byte newLevels[kMaxTableSize]; - m_AudioMode = (ReadBits(1) == 1); - - if (ReadBits(1) == 0) - memset(m_LastLevels, 0, kMaxTableSize); - - unsigned numLevels; - - if (m_AudioMode) - { - m_NumChannels = ReadBits(2) + 1; - if (m_MmFilter.CurrentChannel >= m_NumChannels) - m_MmFilter.CurrentChannel = 0; - numLevels = m_NumChannels * kMMTableSize; - } - else - numLevels = kHeapTablesSizesSum; - - unsigned i; - for (i = 0; i < kLevelTableSize; i++) - levelLevels[i] = (Byte)ReadBits(4); - RIF(m_LevelDecoder.Build(levelLevels)); - - i = 0; - - while (i < numLevels) - { - UInt32 sym = m_LevelDecoder.Decode(&m_InBitStream); - if (sym < kTableDirectLevels) - { - newLevels[i] = (Byte)((sym + m_LastLevels[i]) & kLevelMask); - i++; - } - else - { - if (sym == kTableLevelRepNumber) - { - unsigned t = ReadBits(2) + 3; - for (unsigned reps = t; reps > 0 && i < numLevels; reps--, i++) - newLevels[i] = newLevels[i - 1]; - } - else - { - unsigned num; - if (sym == kTableLevel0Number) - num = ReadBits(3) + 3; - else if (sym == kTableLevel0Number2) - num = ReadBits(7) + 11; - else - return false; - for (; num > 0 && i < numLevels; num--) - newLevels[i++] = 0; - } - } - } - - if (m_AudioMode) - for (i = 0; i < m_NumChannels; i++) - { - RIF(m_MMDecoders[i].Build(&newLevels[i * kMMTableSize])); - } - else - { - RIF(m_MainDecoder.Build(&newLevels[0])); - RIF(m_DistDecoder.Build(&newLevels[kMainTableSize])); - RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize])); - } - - memcpy(m_LastLevels, newLevels, kMaxTableSize); - return true; -} - -bool CDecoder::ReadLastTables() -{ - // it differs a little from pure RAR sources; - // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; - // + 2 works for: return 0xFF; in CInBuffer::ReadByte. - if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; - // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; - if (m_AudioMode) - { - UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream); - if (symbol == 256) - return ReadTables(); - if (symbol >= kMMTableSize) - return false; - } - else - { - UInt32 sym = m_MainDecoder.Decode(&m_InBitStream); - if (sym == kReadTableNumber) - return ReadTables(); - if (sym >= kMainTableSize) - return false; - } - return true; -} - -/* -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() - { - m_Coder->ReleaseStreams(); - } -}; -*/ - -bool CDecoder::DecodeMm(UInt32 pos) -{ - while (pos-- > 0) - { - UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream); - if (symbol == 256) - return true; - if (symbol >= kMMTableSize) - return false; - /* - Byte byPredict = m_Predictor.Predict(); - Byte byReal = (Byte)(byPredict - (Byte)symbol); - m_Predictor.Update(byReal, byPredict); - */ - Byte byReal = m_MmFilter.Decode((Byte)symbol); - m_OutWindowStream.PutByte(byReal); - if (++m_MmFilter.CurrentChannel == m_NumChannels) - m_MmFilter.CurrentChannel = 0; - } - return true; -} - -bool CDecoder::DecodeLz(Int32 pos) -{ - while (pos > 0) - { - UInt32 sym = m_MainDecoder.Decode(&m_InBitStream); - UInt32 length, distance; - if (sym < 256) - { - m_OutWindowStream.PutByte(Byte(sym)); - pos--; - continue; - } - else if (sym >= kMatchNumber) - { - sym -= kMatchNumber; - length = kNormalMatchMinLen + UInt32(kLenStart[sym]) + - m_InBitStream.ReadBits(kLenDirectBits[sym]); - sym = m_DistDecoder.Decode(&m_InBitStream); - if (sym >= kDistTableSize) - return false; - distance = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); - if (distance >= kDistLimit3) - { - length += 2 - ((distance - kDistLimit4) >> 31); - // length++; - // if (distance >= kDistLimit4) - // length++; - } - } - else if (sym == kRepBothNumber) - { - length = m_LastLength; - if (length == 0) - return false; - distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; - } - else if (sym < kLen2Number) - { - distance = m_RepDists[(m_RepDistPtr - (sym - kRepNumber + 1)) & 3]; - sym = m_LenDecoder.Decode(&m_InBitStream); - if (sym >= kLenTableSize) - return false; - length = 2 + kLenStart[sym] + m_InBitStream.ReadBits(kLenDirectBits[sym]); - if (distance >= kDistLimit2) - { - length++; - if (distance >= kDistLimit3) - { - length += 2 - ((distance - kDistLimit4) >> 31); - // length++; - // if (distance >= kDistLimit4) - // length++; - } - } - } - else if (sym < kReadTableNumber) - { - sym -= kLen2Number; - distance = kLen2DistStarts[sym] + - m_InBitStream.ReadBits(kLen2DistDirectBits[sym]); - length = 2; - } - else if (sym == kReadTableNumber) - return true; - else - return false; - m_RepDists[m_RepDistPtr++ & 3] = distance; - m_LastLength = length; - if (!m_OutWindowStream.CopyBlock(distance, length)) - return false; - pos -= length; - } - return true; -} - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - if (inSize == NULL || outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_PackSize = *inSize; - - UInt64 pos = 0, unPackSize = *outSize; - - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - // CCoderReleaser coderReleaser(this); - if (!m_IsSolid) - { - InitStructures(); - if (unPackSize == 0) - { - if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; - if (!ReadTables()) - return S_FALSE; - return S_OK; - } - if (!ReadTables()) - return S_FALSE; - } - - UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - while (pos < unPackSize) - { - UInt32 blockSize = 1 << 20; - if (blockSize > unPackSize - pos) - blockSize = (UInt32)(unPackSize - pos); - UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize(); - if (m_AudioMode) - { - if (!DecodeMm(blockSize)) - return S_FALSE; - } - else - { - if (!DecodeLz((Int32)blockSize)) - return S_FALSE; - } - UInt64 globalPos = m_OutWindowStream.GetProcessedSize(); - pos = globalPos - blockStartPos; - if (pos < blockSize) - if (!ReadTables()) - return S_FALSE; - pos = globalPos - startPos; - if (progress != 0) - { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - } - } - if (pos > unPackSize) - return S_FALSE; - - if (!ReadLastTables()) - return S_FALSE; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size < 1) - return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); - return S_OK; -} - -}} +// Rar2Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#include + +#include "Rar2Decoder.h" + +namespace NCompress { +namespace NRar2 { + +namespace NMultimedia { + +#define my_abs(x) (unsigned)abs(x) + +Byte CFilter::Decode(int &channelDelta, Byte deltaByte) +{ + D4 = D3; + D3 = D2; + D2 = LastDelta - D1; + D1 = LastDelta; + const int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); + + const Byte realValue = (Byte)(predictedValue - deltaByte); + + { + const int i = ((int)(signed char)deltaByte) << 3; + + Dif[0] += my_abs(i); + Dif[1] += my_abs(i - D1); + Dif[2] += my_abs(i + D1); + Dif[3] += my_abs(i - D2); + Dif[4] += my_abs(i + D2); + Dif[5] += my_abs(i - D3); + Dif[6] += my_abs(i + D3); + Dif[7] += my_abs(i - D4); + Dif[8] += my_abs(i + D4); + Dif[9] += my_abs(i - channelDelta); + Dif[10] += my_abs(i + channelDelta); + } + + channelDelta = LastDelta = (signed char)(realValue - LastChar); + LastChar = realValue; + + if (((++ByteCount) & 0x1F) == 0) + { + UInt32 minDif = Dif[0]; + UInt32 numMinDif = 0; + Dif[0] = 0; + + for (unsigned i = 1; i < Z7_ARRAY_SIZE(Dif); i++) + { + if (Dif[i] < minDif) + { + minDif = Dif[i]; + numMinDif = i; + } + Dif[i] = 0; + } + + switch (numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + case 7: if (K4 >= -16) K4--; break; + case 8: if (K4 < 16) K4++; break; + case 9: if (K5 >= -16) K5--; break; + case 10:if (K5 < 16) K5++; break; + } + } + + return realValue; +} +} + +static const UInt32 kHistorySize = 1 << 20; + +// static const UInt32 kWindowReservSize = (1 << 22) + 256; + +CDecoder::CDecoder(): + _isSolid(false), + _solidAllowed(false), + m_TablesOK(false) +{ +} + +void CDecoder::InitStructures() +{ + m_MmFilter.Init(); + for (unsigned i = 0; i < kNumReps; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + m_LastLength = 0; + memset(m_LastLevels, 0, kMaxTableSize); +} + +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numBits); } + +#define RIF(x) { if (!(x)) return false; } + +static const unsigned kRepBothNumber = 256; +static const unsigned kRepNumber = kRepBothNumber + 1; +static const unsigned kLen2Number = kRepNumber + kNumReps; +static const unsigned kReadTableNumber = kLen2Number + kNumLen2Symbols; +static const unsigned kMatchNumber = kReadTableNumber + 1; + +// static const unsigned kDistTableStart = kMainTableSize; +// static const unsigned kLenTableStart = kDistTableStart + kDistTableSize; + +static const UInt32 kDistStart [kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; +static const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; + +static const Byte kLen2DistStarts [kNumLen2Symbols]={0,4,8,16,32,64,128,192}; +static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6}; + +static const UInt32 kDistLimit2 = 0x101 - 1; +static const UInt32 kDistLimit3 = 0x2000 - 1; +static const UInt32 kDistLimit4 = 0x40000 - 1; + +// static const UInt32 kMatchMaxLen = 255 + 2; +// static const UInt32 kMatchMaxLenMax = 255 + 5; + + +bool CDecoder::ReadTables(void) +{ + m_TablesOK = false; + + const unsigned kLevelTableSize = 19; + Byte levelLevels[kLevelTableSize]; + Byte lens[kMaxTableSize]; + + m_AudioMode = (ReadBits(1) == 1); + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kMaxTableSize); + + unsigned numLevels; + + if (m_AudioMode) + { + m_NumChannels = ReadBits(2) + 1; + if (m_MmFilter.CurrentChannel >= m_NumChannels) + m_MmFilter.CurrentChannel = 0; + numLevels = m_NumChannels * k_MM_TableSize; + } + else + numLevels = kHeapTablesSizesSum; + + unsigned i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = (Byte)ReadBits(4); + NHuffman::CDecoder256 m_LevelDecoder; + RIF(m_LevelDecoder.Build(levelLevels, NHuffman::k_BuildMode_Full)) + + i = 0; + do + { + const unsigned sym = m_LevelDecoder.DecodeFull(&m_InBitStream); + if (sym < 16) + { + lens[i] = (Byte)((sym + m_LastLevels[i]) & 15); + i++; + } +#if 0 + else if (sym >= kLevelTableSize) + return false; +#endif + else + { + unsigned num; + Byte v; + if (sym == 16) + { + if (i == 0) + return false; + num = ReadBits(2) + 3; + v = lens[(size_t)i - 1]; + } + else + { + num = (sym - 17) * 4; + num += num + 3 + ReadBits(3 + num); + v = 0; + } + num += i; + if (num > numLevels) + { + // return false; + num = numLevels; // original unRAR + } + do + lens[i++] = v; + while (i < num); + } + } + while (i < numLevels); + + if (m_InBitStream.ExtraBitsWereRead()) + return false; + + if (m_AudioMode) + for (i = 0; i < m_NumChannels; i++) + { + RIF(m_MMDecoders[i].Build(&lens[(size_t)i * k_MM_TableSize])) + } + else + { + RIF(m_MainDecoder.Build(&lens[0])) + RIF(m_DistDecoder.Build(&lens[kMainTableSize])) + RIF(m_LenDecoder.Build(&lens[kMainTableSize + kDistTableSize])) + } + + memcpy(m_LastLevels, lens, kMaxTableSize); + + m_TablesOK = true; + return true; +} + + +bool CDecoder::ReadLastTables() +{ + // it differs a little from pure RAR sources; + // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; + // + 2 works for: return 0xFF; in CInBuffer::ReadByte. + if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; + // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + { + if (m_AudioMode) + { + const unsigned symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream); + if (symbol == 256) + return ReadTables(); + if (symbol >= k_MM_TableSize) + return false; + } + else + { + const unsigned sym = m_MainDecoder.Decode(&m_InBitStream); + if (sym == kReadTableNumber) + return ReadTables(); + if (sym >= kMainTableSize) + return false; + } + } + return true; +} + + +bool CDecoder::DecodeMm(UInt32 pos) +{ + while (pos-- != 0) + { + const unsigned symbol = m_MMDecoders[m_MmFilter.CurrentChannel].Decode(&m_InBitStream); + if (m_InBitStream.ExtraBitsWereRead()) + return false; + if (symbol >= 256) + return symbol == 256; + /* + Byte byPredict = m_Predictor.Predict(); + Byte byReal = (Byte)(byPredict - (Byte)symbol); + m_Predictor.Update(byReal, byPredict); + */ + const Byte byReal = m_MmFilter.Decode((Byte)symbol); + m_OutWindowStream.PutByte(byReal); + if (++m_MmFilter.CurrentChannel == m_NumChannels) + m_MmFilter.CurrentChannel = 0; + } + return true; +} + + +typedef unsigned CLenType; + +static inline CLenType SlotToLen(CBitDecoder &_bitStream, CLenType slot) +{ + const unsigned numBits = ((unsigned)slot >> 2) - 1; + return ((4 | (slot & 3)) << numBits) + (CLenType)_bitStream.ReadBits(numBits); +} + +bool CDecoder::DecodeLz(Int32 pos) +{ + while (pos > 0) + { + unsigned sym = m_MainDecoder.Decode(&m_InBitStream); + if (m_InBitStream.ExtraBitsWereRead()) + return false; + UInt32 len, distance; + if (sym < 256) + { + m_OutWindowStream.PutByte(Byte(sym)); + pos--; + continue; + } + else if (sym >= kMatchNumber) + { + if (sym >= kMainTableSize) + return false; + len = sym - kMatchNumber; + if (len >= 8) + len = SlotToLen(m_InBitStream, len); + len += 3; + + sym = m_DistDecoder.Decode(&m_InBitStream); + if (sym >= kDistTableSize) + return false; + distance = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); + if (distance >= kDistLimit3) + { + len += 2 - ((distance - kDistLimit4) >> 31); + // len++; + // if (distance >= kDistLimit4) + // len++; + } + } + else if (sym == kRepBothNumber) + { + len = m_LastLength; + if (len == 0) + return false; + distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; + } + else if (sym < kLen2Number) + { + distance = m_RepDists[(m_RepDistPtr - (sym - kRepNumber + 1)) & 3]; + len = m_LenDecoder.Decode(&m_InBitStream); + if (len >= kLenTableSize) + return false; + if (len >= 8) + len = SlotToLen(m_InBitStream, len); + len += 2; + + if (distance >= kDistLimit2) + { + len++; + if (distance >= kDistLimit3) + { + len += 2 - ((distance - kDistLimit4) >> 31); + // len++; + // if (distance >= kDistLimit4) + // len++; + } + } + } + else if (sym < kReadTableNumber) + { + sym -= kLen2Number; + distance = kLen2DistStarts[sym] + + m_InBitStream.ReadBits(kLen2DistDirectBits[sym]); + len = 2; + } + else // (sym == kReadTableNumber) + return true; + + m_RepDists[m_RepDistPtr++ & 3] = distance; + m_LastLength = len; + if (!m_OutWindowStream.CopyBlock(distance, len)) + return false; + pos -= len; + } + return true; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + if (!inSize || !outSize) + return E_INVALIDARG; + + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_PackSize = *inSize; + + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(_isSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + // CCoderReleaser coderReleaser(this); + if (!_isSolid) + { + InitStructures(); + if (unPackSize == 0) + { + if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (!ReadTables()) + return S_FALSE; + _solidAllowed = true; + return S_OK; + } + ReadTables(); + } + + if (!m_TablesOK) + return S_FALSE; + + const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + while (pos < unPackSize) + { + UInt32 blockSize = 1 << 20; + if (blockSize > unPackSize - pos) + blockSize = (UInt32)(unPackSize - pos); + UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize(); + if (m_AudioMode) + { + if (!DecodeMm(blockSize)) + return S_FALSE; + } + else + { + if (!DecodeLz((Int32)blockSize)) + return S_FALSE; + } + + if (m_InBitStream.ExtraBitsWereRead()) + return S_FALSE; + + const UInt64 globalPos = m_OutWindowStream.GetProcessedSize(); + pos = globalPos - blockStartPos; + if (pos < blockSize) + if (!ReadTables()) + return S_FALSE; + pos = globalPos - startPos; + if (progress) + { + const UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)) + } + } + if (pos > unPackSize) + return S_FALSE; + + if (!ReadLastTables()) + return S_FALSE; + + _solidAllowed = true; + + return m_OutWindowStream.Flush(); +} + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLzOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size < 1) + return E_INVALIDARG; + _isSolid = ((data[0] & 1) != 0); + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar2Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Rar2Decoder.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar2Decoder.h 2024-01-07 10:00:00.000000000 +0000 @@ -1,176 +1,111 @@ -// Rar2Decoder.h -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#ifndef __COMPRESS_RAR2_DECODER_H -#define __COMPRESS_RAR2_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "HuffmanDecoder.h" -#include "LzOutWindow.h" - -namespace NCompress { -namespace NRar2 { - -const unsigned kNumRepDists = 4; -const unsigned kDistTableSize = 48; - -const unsigned kMMTableSize = 256 + 1; - -const UInt32 kMainTableSize = 298; -const UInt32 kLenTableSize = 28; - -const UInt32 kDistTableStart = kMainTableSize; -const UInt32 kLenTableStart = kDistTableStart + kDistTableSize; - -const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; - -const UInt32 kLevelTableSize = 19; - -const UInt32 kMMTablesSizesSum = kMMTableSize * 4; - -const UInt32 kMaxTableSize = kMMTablesSizesSum; - -const UInt32 kTableDirectLevels = 16; -const UInt32 kTableLevelRepNumber = kTableDirectLevels; -const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; - -const UInt32 kLevelMask = 0xF; - - -const UInt32 kRepBothNumber = 256; -const UInt32 kRepNumber = kRepBothNumber + 1; -const UInt32 kLen2Number = kRepNumber + 4; - -const UInt32 kLen2NumNumbers = 8; -const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; -const UInt32 kMatchNumber = kReadTableNumber + 1; - -const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; -const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; - -const UInt32 kDistStart [kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; -const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; - -const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; - -const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192}; -const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6}; - -const UInt32 kDistLimit2 = 0x101 - 1; -const UInt32 kDistLimit3 = 0x2000 - 1; -const UInt32 kDistLimit4 = 0x40000 - 1; - -const UInt32 kMatchMaxLen = 255 + 2; -const UInt32 kMatchMaxLenMax = 255 + 5; -const UInt32 kNormalMatchMinLen = 3; - -namespace NMultimedia { - -struct CFilter -{ - int K1,K2,K3,K4,K5; - int D1,D2,D3,D4; - int LastDelta; - UInt32 Dif[11]; - UInt32 ByteCount; - int LastChar; - - Byte Decode(int &channelDelta, Byte delta); - - void Init() { memset(this, 0, sizeof(*this)); } - -}; - -const unsigned kNumChanelsMax = 4; - -class CFilter2 -{ -public: - CFilter m_Filters[kNumChanelsMax]; - int m_ChannelDelta; - unsigned CurrentChannel; - - void Init() { memset(this, 0, sizeof(*this)); } - Byte Decode(Byte delta) - { - return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta); - } - -}; - -} - -typedef NBitm::CDecoder CBitDecoder; - -const unsigned kNumHuffmanBits = 15; - -class CDecoder : - public ICompressCoder, - public ICompressSetDecoderProperties2, - public CMyUnknownImp -{ - CLzOutWindow m_OutWindowStream; - CBitDecoder m_InBitStream; - NHuffman::CDecoder m_MainDecoder; - NHuffman::CDecoder m_DistDecoder; - NHuffman::CDecoder m_LenDecoder; - NHuffman::CDecoder m_MMDecoders[NMultimedia::kNumChanelsMax]; - NHuffman::CDecoder m_LevelDecoder; - - bool m_AudioMode; - - NMultimedia::CFilter2 m_MmFilter; - unsigned m_NumChannels; - - UInt32 m_RepDists[kNumRepDists]; - UInt32 m_RepDistPtr; - - UInt32 m_LastLength; - - Byte m_LastLevels[kMaxTableSize]; - - UInt64 m_PackSize; - bool m_IsSolid; - - void InitStructures(); - UInt32 ReadBits(unsigned numBits); - bool ReadTables(); - bool ReadLastTables(); - - bool DecodeMm(UInt32 pos); - bool DecodeLz(Int32 pos); - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - -public: - CDecoder(); - - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - - /* - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - */ - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - -}; - -}} - -#endif +// Rar2Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef ZIP7_INC_COMPRESS_RAR2_DECODER_H +#define ZIP7_INC_COMPRESS_RAR2_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NRar2 { + +const unsigned kNumReps = 4; +const unsigned kDistTableSize = 48; +const unsigned kNumLen2Symbols = 8; +const unsigned kLenTableSize = 28; +const unsigned kMainTableSize = 256 + 2 + kNumReps + kNumLen2Symbols + kLenTableSize; +const unsigned kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; +const unsigned k_MM_TableSize = 256 + 1; +const unsigned k_MM_NumChanelsMax = 4; +const unsigned k_MM_TablesSizesSum = k_MM_TableSize * k_MM_NumChanelsMax; +const unsigned kMaxTableSize = k_MM_TablesSizesSum; + +namespace NMultimedia { + +struct CFilter +{ + int K1,K2,K3,K4,K5; + int D1,D2,D3,D4; + int LastDelta; + UInt32 Dif[11]; + UInt32 ByteCount; + int LastChar; + + void Init() { memset(this, 0, sizeof(*this)); } + Byte Decode(int &channelDelta, Byte delta); +}; + +struct CFilter2 +{ + CFilter m_Filters[k_MM_NumChanelsMax]; + int m_ChannelDelta; + unsigned CurrentChannel; + + void Init() { memset(this, 0, sizeof(*this)); } + Byte Decode(Byte delta) + { + return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta); + } +}; + +} + +typedef NBitm::CDecoder CBitDecoder; + +const unsigned kNumHufBits = 15; + +Z7_CLASS_IMP_NOQIB_2( + CDecoder + , ICompressCoder + , ICompressSetDecoderProperties2 +) + bool _isSolid; + bool _solidAllowed; + bool m_TablesOK; + bool m_AudioMode; + + CLzOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + + UInt32 m_RepDistPtr; + UInt32 m_RepDists[kNumReps]; + UInt32 m_LastLength; + unsigned m_NumChannels; + + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder256 m_DistDecoder; + NHuffman::CDecoder256 m_LenDecoder; + NHuffman::CDecoder m_MMDecoders[k_MM_NumChanelsMax]; + + UInt64 m_PackSize; + + NMultimedia::CFilter2 m_MmFilter; + Byte m_LastLevels[kMaxTableSize]; + + void InitStructures(); + UInt32 ReadBits(unsigned numBits); + bool ReadTables(); + bool ReadLastTables(); + + bool DecodeMm(UInt32 pos); + bool DecodeLz(Int32 pos); + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + +public: + CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar3Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Rar3Decoder.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.cpp 2024-01-07 11:00:00.000000000 +0000 @@ -1,918 +1,939 @@ -// Rar3Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#include "StdAfx.h" - -#include "../../../C/Alloc.h" - -#include "../Common/StreamUtils.h" - -#include "Rar3Decoder.h" - -namespace NCompress { -namespace NRar3 { - -static const UInt32 kNumAlignReps = 15; - -static const UInt32 kSymbolReadTable = 256; -static const UInt32 kSymbolRep = 259; -static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps; - -static const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; -static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; - -static const Byte kDistDirectBits[kDistTableSize] = - {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 18,18,18,18,18,18,18,18,18,18,18,18}; - -static const Byte kLevelDirectBits[kLevelTableSize] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -static const Byte kLen2DistStarts[kNumLen2Symbols]={0,4,8,16,32,64,128,192}; -static const Byte kLen2DistDirectBits[kNumLen2Symbols]={2,2,3, 4, 5, 6, 6, 6}; - -static const UInt32 kDistLimit3 = 0x2000 - 2; -static const UInt32 kDistLimit4 = 0x40000 - 2; - -static const UInt32 kNormalMatchMinLen = 3; - -static const UInt32 kVmDataSizeMax = 1 << 16; -static const UInt32 kVmCodeSizeMax = 1 << 16; - -extern "C" { - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - return p->Code / (p->Range /= total); -} - -static void Range_Decode(void *pp, UInt32 start, UInt32 size) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - start *= p->Range; - p->Low += start; - p->Code -= start; - p->Range *= size; - p->Normalize(); -} - -static UInt32 Range_DecodeBit(void *pp, UInt32 size0) -{ - CRangeDecoder *p = (CRangeDecoder *)pp; - if (p->Code / (p->Range >>= 14) < size0) - { - Range_Decode(p, 0, size0); - return 0; - } - else - { - Range_Decode(p, size0, (1 << 14) - size0); - return 1; - } -} - -} - -CRangeDecoder::CRangeDecoder() -{ - s.GetThreshold = Range_GetThreshold; - s.Decode = Range_Decode; - s.DecodeBit = Range_DecodeBit; -} - -CDecoder::CDecoder(): - _window(0), - _winPos(0), - _wrPtr(0), - _lzSize(0), - _writtenFileSize(0), - _vmData(0), - _vmCode(0), - m_IsSolid(false) -{ - Ppmd7_Construct(&_ppmd); -} - -CDecoder::~CDecoder() -{ - InitFilters(); - ::MidFree(_vmData); - ::MidFree(_window); - Ppmd7_Free(&_ppmd, &g_BigAlloc); -} - -HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) -{ - return WriteStream(_outStream, data, size); -} - -HRESULT CDecoder::WriteData(const Byte *data, UInt32 size) -{ - HRESULT res = S_OK; - if (_writtenFileSize < _unpackSize) - { - UInt32 curSize = size; - UInt64 remain = _unpackSize - _writtenFileSize; - if (remain < curSize) - curSize = (UInt32)remain; - res = WriteDataToStream(data, curSize); - } - _writtenFileSize += size; - return res; -} - -HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr) -{ - if (startPtr <= endPtr) - return WriteData(_window + startPtr, endPtr - startPtr); - RINOK(WriteData(_window + startPtr, kWindowSize - startPtr)); - return WriteData(_window, endPtr); -} - -void CDecoder::ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef) -{ - CTempFilter *tempFilter = _tempFilters[tempFilterIndex]; - tempFilter->InitR[6] = (UInt32)_writtenFileSize; - NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize); - NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32)); - CFilter *filter = _filters[tempFilter->FilterIndex]; - if (!filter->IsSupported) - _unsupportedFilter = true; - _vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData); - delete tempFilter; - _tempFilters[tempFilterIndex] = 0; -} - -HRESULT CDecoder::WriteBuf() -{ - UInt32 writtenBorder = _wrPtr; - UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask; - FOR_VECTOR (i, _tempFilters) - { - CTempFilter *filter = _tempFilters[i]; - if (!filter) - continue; - if (filter->NextWindow) - { - filter->NextWindow = false; - continue; - } - UInt32 blockStart = filter->BlockStart; - UInt32 blockSize = filter->BlockSize; - if (((blockStart - writtenBorder) & kWindowMask) < writeSize) - { - if (writtenBorder != blockStart) - { - RINOK(WriteArea(writtenBorder, blockStart)); - writtenBorder = blockStart; - writeSize = (_winPos - writtenBorder) & kWindowMask; - } - if (blockSize <= writeSize) - { - UInt32 blockEnd = (blockStart + blockSize) & kWindowMask; - if (blockStart < blockEnd || blockEnd == 0) - _vm.SetMemory(0, _window + blockStart, blockSize); - else - { - UInt32 tailSize = kWindowSize - blockStart; - _vm.SetMemory(0, _window + blockStart, tailSize); - _vm.SetMemory(tailSize, _window, blockEnd); - } - NVm::CBlockRef outBlockRef; - ExecuteFilter(i, outBlockRef); - while (i + 1 < _tempFilters.Size()) - { - CTempFilter *nextFilter = _tempFilters[i + 1]; - if (!nextFilter - || nextFilter->BlockStart != blockStart - || nextFilter->BlockSize != outBlockRef.Size - || nextFilter->NextWindow) - break; - _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); - ExecuteFilter(++i, outBlockRef); - } - WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); - _writtenFileSize += outBlockRef.Size; - writtenBorder = blockEnd; - writeSize = (_winPos - writtenBorder) & kWindowMask; - } - else - { - for (unsigned j = i; j < _tempFilters.Size(); j++) - { - CTempFilter *filter2 = _tempFilters[j]; - if (filter2 && filter2->NextWindow) - filter2->NextWindow = false; - } - _wrPtr = writtenBorder; - return S_OK; // check it - } - } - } - - _wrPtr = _winPos; - return WriteArea(writtenBorder, _winPos); -} - -void CDecoder::InitFilters() -{ - _lastFilter = 0; - unsigned i; - for (i = 0; i < _tempFilters.Size(); i++) - delete _tempFilters[i]; - _tempFilters.Clear(); - for (i = 0; i < _filters.Size(); i++) - delete _filters[i]; - _filters.Clear(); -} - -static const unsigned MAX_UNPACK_FILTERS = 8192; - -bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) -{ - CMemBitDecoder inp; - inp.Init(_vmData, codeSize); - - UInt32 filterIndex; - - if (firstByte & 0x80) - { - filterIndex = inp.ReadEncodedUInt32(); - if (filterIndex == 0) - InitFilters(); - else - filterIndex--; - } - else - filterIndex = _lastFilter; - - if (filterIndex > (UInt32)_filters.Size()) - return false; - _lastFilter = filterIndex; - bool newFilter = (filterIndex == (UInt32)_filters.Size()); - - CFilter *filter; - if (newFilter) - { - // check if too many filters - if (filterIndex > MAX_UNPACK_FILTERS) - return false; - filter = new CFilter; - _filters.Add(filter); - } - else - { - filter = _filters[filterIndex]; - filter->ExecCount++; - } - - unsigned numEmptyItems = 0; - { - FOR_VECTOR (i, _tempFilters) - { - _tempFilters[i - numEmptyItems] = _tempFilters[i]; - if (!_tempFilters[i]) - numEmptyItems++; - if (numEmptyItems != 0) - _tempFilters[i] = NULL; - } - } - if (numEmptyItems == 0) - { - _tempFilters.Add(NULL); - numEmptyItems = 1; - } - CTempFilter *tempFilter = new CTempFilter; - _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter; - tempFilter->FilterIndex = filterIndex; - - UInt32 blockStart = inp.ReadEncodedUInt32(); - if (firstByte & 0x40) - blockStart += 258; - tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask; - if (firstByte & 0x20) - filter->BlockSize = inp.ReadEncodedUInt32(); - tempFilter->BlockSize = filter->BlockSize; - tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart; - - memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR)); - tempFilter->InitR[3] = NVm::kGlobalOffset; - tempFilter->InitR[4] = tempFilter->BlockSize; - tempFilter->InitR[5] = filter->ExecCount; - if (firstByte & 0x10) - { - UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs); - for (unsigned i = 0; i < NVm::kNumGpRegs; i++) - if (initMask & (1 << i)) - tempFilter->InitR[i] = inp.ReadEncodedUInt32(); - } - - bool isOK = true; - if (newFilter) - { - UInt32 vmCodeSize = inp.ReadEncodedUInt32(); - if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0) - return false; - for (UInt32 i = 0; i < vmCodeSize; i++) - _vmCode[i] = (Byte)inp.ReadBits(8); - isOK = filter->PrepareProgram(_vmCode, vmCodeSize); - } - - { - Byte *globalData = &tempFilter->GlobalData[0]; - for (unsigned i = 0; i < NVm::kNumGpRegs; i++) - NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]); - NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize); - NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why? - NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], filter->ExecCount); - } - - if (firstByte & 8) - { - UInt32 dataSize = inp.ReadEncodedUInt32(); - if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize) - return false; - CRecordVector &globalData = tempFilter->GlobalData; - unsigned requiredSize = (unsigned)(dataSize + NVm::kFixedGlobalSize); - if (globalData.Size() < requiredSize) - globalData.ChangeSize_KeepData(requiredSize); - Byte *dest = &globalData[NVm::kFixedGlobalSize]; - for (UInt32 i = 0; i < dataSize; i++) - dest[i] = (Byte)inp.ReadBits(8); - } - - return isOK; -} - -bool CDecoder::ReadVmCodeLZ() -{ - UInt32 firstByte = ReadBits(8); - UInt32 length = (firstByte & 7) + 1; - if (length == 7) - length = ReadBits(8) + 7; - else if (length == 8) - length = ReadBits(16); - if (length > kVmDataSizeMax) - return false; - for (UInt32 i = 0; i < length; i++) - _vmData[i] = (Byte)ReadBits(8); - return AddVmCode(firstByte, length); -} - -bool CDecoder::ReadVmCodePPM() -{ - int firstByte = DecodePpmSymbol(); - if (firstByte < 0) - return false; - UInt32 length = (firstByte & 7) + 1; - if (length == 7) - { - int b1 = DecodePpmSymbol(); - if (b1 < 0) - return false; - length = b1 + 7; - } - else if (length == 8) - { - int b1 = DecodePpmSymbol(); - if (b1 < 0) - return false; - int b2 = DecodePpmSymbol(); - if (b2 < 0) - return false; - length = b1 * 256 + b2; - } - if (length > kVmDataSizeMax) - return false; - if (InputEofError_Fast()) - return false; - for (UInt32 i = 0; i < length; i++) - { - int b = DecodePpmSymbol(); - if (b < 0) - return false; - _vmData[i] = (Byte)b; - } - return AddVmCode(firstByte, length); -} - -#define RIF(x) { if (!(x)) return S_FALSE; } - -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.BitDecoder.ReadBits(numBits); } - -// ---------- PPM ---------- - -HRESULT CDecoder::InitPPM() -{ - unsigned maxOrder = (unsigned)ReadBits(7); - - bool reset = ((maxOrder & 0x20) != 0); - int maxMB = 0; - if (reset) - maxMB = (Byte)ReadBits(8); - else - { - if (PpmError || !Ppmd7_WasAllocated(&_ppmd)) - return S_FALSE; - } - if (maxOrder & 0x40) - PpmEscChar = (Byte)ReadBits(8); - m_InBitStream.InitRangeCoder(); - /* - if (m_InBitStream.m_BitPos != 0) - return S_FALSE; - */ - if (reset) - { - PpmError = true; - maxOrder = (maxOrder & 0x1F) + 1; - if (maxOrder > 16) - maxOrder = 16 + (maxOrder - 16) * 3; - if (maxOrder == 1) - { - Ppmd7_Free(&_ppmd, &g_BigAlloc); - return S_FALSE; - } - if (!Ppmd7_Alloc(&_ppmd, (maxMB + 1) << 20, &g_BigAlloc)) - return E_OUTOFMEMORY; - Ppmd7_Init(&_ppmd, maxOrder); - PpmError = false; - } - return S_OK; -} - -int CDecoder::DecodePpmSymbol() { return Ppmd7_DecodeSymbol(&_ppmd, &m_InBitStream.s); } - -HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) -{ - keepDecompressing = false; - if (PpmError) - return S_FALSE; - do - { - if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) - { - RINOK(WriteBuf()); - if (_writtenFileSize > _unpackSize) - { - keepDecompressing = false; - return S_OK; - } - } - if (InputEofError_Fast()) - return false; - int c = DecodePpmSymbol(); - if (c < 0) - { - PpmError = true; - return S_FALSE; - } - if (c == PpmEscChar) - { - int nextCh = DecodePpmSymbol(); - if (nextCh < 0) - { - PpmError = true; - return S_FALSE; - } - if (nextCh == 0) - return ReadTables(keepDecompressing); - if (nextCh == 2 || nextCh == -1) - return S_OK; - if (nextCh == 3) - { - if (!ReadVmCodePPM()) - { - PpmError = true; - return S_FALSE; - } - continue; - } - if (nextCh == 4 || nextCh == 5) - { - UInt32 distance = 0; - UInt32 length = 4; - if (nextCh == 4) - { - for (int i = 0; i < 3; i++) - { - int c2 = DecodePpmSymbol(); - if (c2 < 0) - { - PpmError = true; - return S_FALSE; - } - distance = (distance << 8) + (Byte)c2; - } - distance++; - length += 28; - } - int c2 = DecodePpmSymbol(); - if (c2 < 0) - { - PpmError = true; - return S_FALSE; - } - length += c2; - if (distance >= _lzSize) - return S_FALSE; - CopyBlock(distance, length); - num -= (Int32)length; - continue; - } - } - PutByte((Byte)c); - num--; - } - while (num >= 0); - keepDecompressing = true; - return S_OK; -} - -// ---------- LZ ---------- - -HRESULT CDecoder::ReadTables(bool &keepDecompressing) -{ - keepDecompressing = true; - m_InBitStream.BitDecoder.AlignToByte(); - if (ReadBits(1) != 0) - { - _lzMode = false; - return InitPPM(); - } - - _lzMode = true; - PrevAlignBits = 0; - PrevAlignCount = 0; - - Byte levelLevels[kLevelTableSize]; - Byte newLevels[kTablesSizesSum]; - - if (ReadBits(1) == 0) - memset(m_LastLevels, 0, kTablesSizesSum); - - int i; - for (i = 0; i < kLevelTableSize; i++) - { - UInt32 length = ReadBits(4); - if (length == 15) - { - UInt32 zeroCount = ReadBits(4); - if (zeroCount != 0) - { - zeroCount += 2; - while (zeroCount-- > 0 && i < kLevelTableSize) - levelLevels[i++]=0; - i--; - continue; - } - } - levelLevels[i] = (Byte)length; - } - RIF(m_LevelDecoder.Build(levelLevels)); - i = 0; - while (i < kTablesSizesSum) - { - UInt32 sym = m_LevelDecoder.Decode(&m_InBitStream.BitDecoder); - if (sym < 16) - { - newLevels[i] = Byte((sym + m_LastLevels[i]) & 15); - i++; - } - else if (sym > kLevelTableSize) - return S_FALSE; - else - { - int num; - if (((sym - 16) & 1) == 0) - num = ReadBits(3) + 3; - else - num = ReadBits(7) + 11; - if (sym < 18) - { - if (i == 0) - return S_FALSE; - for (; num > 0 && i < kTablesSizesSum; num--, i++) - newLevels[i] = newLevels[i - 1]; - } - else - { - for (; num > 0 && i < kTablesSizesSum; num--) - newLevels[i++] = 0; - } - } - } - TablesRead = true; - - // original code has check here: - /* - if (InAddr > ReadTop) - { - keepDecompressing = false; - return true; - } - */ - - RIF(m_MainDecoder.Build(&newLevels[0])); - RIF(m_DistDecoder.Build(&newLevels[kMainTableSize])); - RIF(m_AlignDecoder.Build(&newLevels[kMainTableSize + kDistTableSize])); - RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); - - memcpy(m_LastLevels, newLevels, kTablesSizesSum); - return S_OK; -} - -/* -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() - { - m_Coder->ReleaseStreams(); - } -}; -*/ - -HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing) -{ - if (ReadBits(1) != 0) - { - // old file - TablesRead = false; - return ReadTables(keepDecompressing); - } - // new file - keepDecompressing = false; - TablesRead = (ReadBits(1) == 0); - return S_OK; -} - -UInt32 kDistStart[kDistTableSize]; - -class CDistInit -{ -public: - CDistInit() { Init(); } - void Init() - { - UInt32 start = 0; - for (UInt32 i = 0; i < kDistTableSize; i++) - { - kDistStart[i] = start; - start += (1 << kDistDirectBits[i]); - } - } -} g_DistInit; - -HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) -{ - UInt32 rep0 = _reps[0]; - UInt32 rep1 = _reps[1]; - UInt32 rep2 = _reps[2]; - UInt32 rep3 = _reps[3]; - UInt32 length = _lastLength; - for (;;) - { - if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) - { - RINOK(WriteBuf()); - if (_writtenFileSize > _unpackSize) - { - keepDecompressing = false; - return S_OK; - } - } - - if (InputEofError_Fast()) - return S_FALSE; - - UInt32 sym = m_MainDecoder.Decode(&m_InBitStream.BitDecoder); - if (sym < 256) - { - PutByte((Byte)sym); - continue; - } - else if (sym == kSymbolReadTable) - { - RINOK(ReadEndOfBlock(keepDecompressing)); - break; - } - else if (sym == 257) - { - if (!ReadVmCodeLZ()) - return S_FALSE; - continue; - } - else if (sym == 258) - { - if (length == 0) - return S_FALSE; - } - else if (sym < kSymbolRep + 4) - { - if (sym != kSymbolRep) - { - UInt32 distance; - if (sym == kSymbolRep + 1) - distance = rep1; - else - { - if (sym == kSymbolRep + 2) - distance = rep2; - else - { - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - - const UInt32 sym2 = m_LenDecoder.Decode(&m_InBitStream.BitDecoder); - if (sym2 >= kLenTableSize) - return S_FALSE; - length = 2 + kLenStart[sym2] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[sym2]); - } - else - { - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - if (sym < 271) - { - sym -= 263; - rep0 = kLen2DistStarts[sym] + m_InBitStream.BitDecoder.ReadBits(kLen2DistDirectBits[sym]); - length = 2; - } - else if (sym < 299) - { - sym -= 271; - length = kNormalMatchMinLen + (UInt32)kLenStart[sym] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[sym]); - const UInt32 sym2 = m_DistDecoder.Decode(&m_InBitStream.BitDecoder); - if (sym2 >= kDistTableSize) - return S_FALSE; - rep0 = kDistStart[sym2]; - int numBits = kDistDirectBits[sym2]; - if (sym2 >= (kNumAlignBits * 2) + 2) - { - if (numBits > kNumAlignBits) - rep0 += (m_InBitStream.BitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); - if (PrevAlignCount > 0) - { - PrevAlignCount--; - rep0 += PrevAlignBits; - } - else - { - const UInt32 sym3 = m_AlignDecoder.Decode(&m_InBitStream.BitDecoder); - if (sym3 < (1 << kNumAlignBits)) - { - rep0 += sym3; - PrevAlignBits = sym3; - } - else if (sym3 == (1 << kNumAlignBits)) - { - PrevAlignCount = kNumAlignReps; - rep0 += PrevAlignBits; - } - else - return S_FALSE; - } - } - else - rep0 += m_InBitStream.BitDecoder.ReadBits(numBits); - length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31); - } - else - return S_FALSE; - } - if (rep0 >= _lzSize) - return S_FALSE; - CopyBlock(rep0, length); - } - _reps[0] = rep0; - _reps[1] = rep1; - _reps[2] = rep2; - _reps[3] = rep3; - _lastLength = length; - - return S_OK; -} - -HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) -{ - _writtenFileSize = 0; - _unsupportedFilter = false; - if (!m_IsSolid) - { - _lzSize = 0; - _winPos = 0; - _wrPtr = 0; - for (int i = 0; i < kNumReps; i++) - _reps[i] = 0; - _lastLength = 0; - memset(m_LastLevels, 0, kTablesSizesSum); - TablesRead = false; - PpmEscChar = 2; - PpmError = true; - InitFilters(); - } - if (!m_IsSolid || !TablesRead) - { - bool keepDecompressing; - RINOK(ReadTables(keepDecompressing)); - if (!keepDecompressing) - return S_OK; - } - - for (;;) - { - bool keepDecompressing; - if (_lzMode) - { - RINOK(DecodeLZ(keepDecompressing)) - } - else - { - RINOK(DecodePPM(1 << 18, keepDecompressing)) - } - - if (InputEofError()) - return S_FALSE; - - UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); - if (!keepDecompressing) - break; - } - RINOK(WriteBuf()); - UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); - if (_writtenFileSize < _unpackSize) - return S_FALSE; - - if (_unsupportedFilter) - return E_NOTIMPL; - - return S_OK; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try - { - if (!inSize) - return E_INVALIDARG; - - if (!_vmData) - { - _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); - if (!_vmData) - return E_OUTOFMEMORY; - _vmCode = _vmData + kVmDataSizeMax; - } - - if (!_window) - { - _window = (Byte *)::MidAlloc(kWindowSize); - if (!_window) - return E_OUTOFMEMORY; - } - if (!m_InBitStream.BitDecoder.Create(1 << 20)) - return E_OUTOFMEMORY; - if (!_vm.Create()) - return E_OUTOFMEMORY; - - - m_InBitStream.BitDecoder.SetStream(inStream); - m_InBitStream.BitDecoder.Init(); - _outStream = outStream; - - // CCoderReleaser coderReleaser(this); - _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; - return CodeReal(progress); - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } - // CNewException is possible here. But probably CNewException is caused - // by error in data stream. -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size < 1) - return E_INVALIDARG; - m_IsSolid = ((data[0] & 1) != 0); - return S_OK; -} - -}} +// Rar3Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/StreamUtils.h" + +#include "Rar3Decoder.h" + +namespace NCompress { +namespace NRar3 { + +static const UInt32 kNumAlignReps = 15; + +static const unsigned kSymbolReadTable = 256; +static const unsigned kSymbolRep = 259; + +static const Byte kDistDirectBits[kDistTableSize] = + {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 18,18,18,18,18,18,18,18,18,18,18,18}; + +static const Byte kLen2DistStarts[kNumLen2Symbols] = {0,4,8,16,32,64,128,192}; +static const Byte kLen2DistDirectBits[kNumLen2Symbols] = {2,2,3, 4, 5, 6, 6, 6}; + +static const UInt32 kDistLimit3 = 0x2000 - 2; +static const UInt32 kDistLimit4 = 0x40000 - 2; + +static const UInt32 kNormalMatchMinLen = 3; + +static const UInt32 kVmDataSizeMax = 1 << 16; +static const UInt32 kVmCodeSizeMax = 1 << 16; + +extern "C" { + +static Byte Wrap_ReadByte(IByteInPtr pp) throw() +{ + CByteIn *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteIn, IByteIn_obj); + return p->BitDecoder.Stream.ReadByte(); +} + +static Byte Wrap_ReadBits8(IByteInPtr pp) throw() +{ + CByteIn *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteIn, IByteIn_obj); + return (Byte)p->BitDecoder.ReadByteFromAligned(); +} + +} + + +CDecoder::CDecoder(): + _isSolid(false), + _solidAllowed(false), + _window(NULL), + _winPos(0), + _wrPtr(0), + _lzSize(0), + _writtenFileSize(0), + _vmData(NULL), + _vmCode(NULL) +{ + Ppmd7_Construct(&_ppmd); + + UInt32 start = 0; + for (UInt32 i = 0; i < kDistTableSize; i++) + { + kDistStart[i] = start; + start += ((UInt32)1 << kDistDirectBits[i]); + } +} + +CDecoder::~CDecoder() +{ + InitFilters(); + ::MidFree(_vmData); + ::MidFree(_window); + Ppmd7_Free(&_ppmd, &g_BigAlloc); +} + +HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) +{ + return WriteStream(_outStream, data, size); +} + +HRESULT CDecoder::WriteData(const Byte *data, UInt32 size) +{ + HRESULT res = S_OK; + if (_writtenFileSize < _unpackSize) + { + UInt32 curSize = size; + UInt64 remain = _unpackSize - _writtenFileSize; + if (remain < curSize) + curSize = (UInt32)remain; + res = WriteDataToStream(data, curSize); + } + _writtenFileSize += size; + return res; +} + +HRESULT CDecoder::WriteArea(UInt32 startPtr, UInt32 endPtr) +{ + if (startPtr <= endPtr) + return WriteData(_window + startPtr, endPtr - startPtr); + RINOK(WriteData(_window + startPtr, kWindowSize - startPtr)) + return WriteData(_window, endPtr); +} + +void CDecoder::ExecuteFilter(unsigned tempFilterIndex, NVm::CBlockRef &outBlockRef) +{ + CTempFilter *tempFilter = _tempFilters[tempFilterIndex]; + tempFilter->InitR[6] = (UInt32)_writtenFileSize; + NVm::SetValue32(&tempFilter->GlobalData[0x24], (UInt32)_writtenFileSize); + NVm::SetValue32(&tempFilter->GlobalData[0x28], (UInt32)(_writtenFileSize >> 32)); + CFilter *filter = _filters[tempFilter->FilterIndex]; + if (!filter->IsSupported) + _unsupportedFilter = true; + if (!_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData)) + _unsupportedFilter = true; + delete tempFilter; + _tempFilters[tempFilterIndex] = NULL; + _numEmptyTempFilters++; +} + +HRESULT CDecoder::WriteBuf() +{ + UInt32 writtenBorder = _wrPtr; + UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask; + FOR_VECTOR (i, _tempFilters) + { + CTempFilter *filter = _tempFilters[i]; + if (!filter) + continue; + if (filter->NextWindow) + { + filter->NextWindow = false; + continue; + } + UInt32 blockStart = filter->BlockStart; + UInt32 blockSize = filter->BlockSize; + if (((blockStart - writtenBorder) & kWindowMask) < writeSize) + { + if (writtenBorder != blockStart) + { + RINOK(WriteArea(writtenBorder, blockStart)) + writtenBorder = blockStart; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + if (blockSize <= writeSize) + { + UInt32 blockEnd = (blockStart + blockSize) & kWindowMask; + if (blockStart < blockEnd || blockEnd == 0) + _vm.SetMemory(0, _window + blockStart, blockSize); + else + { + UInt32 tailSize = kWindowSize - blockStart; + _vm.SetMemory(0, _window + blockStart, tailSize); + _vm.SetMemory(tailSize, _window, blockEnd); + } + NVm::CBlockRef outBlockRef; + ExecuteFilter(i, outBlockRef); + while (i + 1 < _tempFilters.Size()) + { + CTempFilter *nextFilter = _tempFilters[i + 1]; + if (!nextFilter + || nextFilter->BlockStart != blockStart + || nextFilter->BlockSize != outBlockRef.Size + || nextFilter->NextWindow) + break; + _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + ExecuteFilter(++i, outBlockRef); + } + WriteDataToStream(_vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); + _writtenFileSize += outBlockRef.Size; + writtenBorder = blockEnd; + writeSize = (_winPos - writtenBorder) & kWindowMask; + } + else + { + for (unsigned j = i; j < _tempFilters.Size(); j++) + { + CTempFilter *filter2 = _tempFilters[j]; + if (filter2 && filter2->NextWindow) + filter2->NextWindow = false; + } + _wrPtr = writtenBorder; + return S_OK; // check it + } + } + } + + _wrPtr = _winPos; + return WriteArea(writtenBorder, _winPos); +} + +void CDecoder::InitFilters() +{ + _lastFilter = 0; + _numEmptyTempFilters = 0; + unsigned i; + for (i = 0; i < _tempFilters.Size(); i++) + delete _tempFilters[i]; + _tempFilters.Clear(); + for (i = 0; i < _filters.Size(); i++) + delete _filters[i]; + _filters.Clear(); +} + +static const unsigned MAX_UNPACK_FILTERS = 8192; + +bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) +{ + CMemBitDecoder inp; + inp.Init(_vmData, codeSize); + + UInt32 filterIndex; + + if (firstByte & 0x80) + { + filterIndex = inp.ReadEncodedUInt32(); + if (filterIndex == 0) + InitFilters(); + else + filterIndex--; + } + else + filterIndex = _lastFilter; + + if (filterIndex > (UInt32)_filters.Size()) + return false; + _lastFilter = filterIndex; + bool newFilter = (filterIndex == (UInt32)_filters.Size()); + + CFilter *filter; + if (newFilter) + { + // check if too many filters + if (filterIndex > MAX_UNPACK_FILTERS) + return false; + filter = new CFilter; + _filters.Add(filter); + } + else + { + filter = _filters[filterIndex]; + filter->ExecCount++; + } + + if (_numEmptyTempFilters != 0) + { + const unsigned num = _tempFilters.Size(); + CTempFilter **tempFilters = _tempFilters.NonConstData(); + + unsigned w = 0; + for (unsigned i = 0; i < num; i++) + { + CTempFilter *tf = tempFilters[i]; + if (tf) + tempFilters[w++] = tf; + } + + _tempFilters.DeleteFrom(w); + _numEmptyTempFilters = 0; + } + + if (_tempFilters.Size() > MAX_UNPACK_FILTERS) + return false; + CTempFilter *tempFilter = new CTempFilter; + _tempFilters.Add(tempFilter); + tempFilter->FilterIndex = filterIndex; + + UInt32 blockStart = inp.ReadEncodedUInt32(); + if (firstByte & 0x40) + blockStart += 258; + tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask; + if (firstByte & 0x20) + filter->BlockSize = inp.ReadEncodedUInt32(); + tempFilter->BlockSize = filter->BlockSize; + tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart; + + memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR)); + tempFilter->InitR[3] = NVm::kGlobalOffset; + tempFilter->InitR[4] = tempFilter->BlockSize; + tempFilter->InitR[5] = filter->ExecCount; + if (firstByte & 0x10) + { + UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs); + for (unsigned i = 0; i < NVm::kNumGpRegs; i++) + if (initMask & (1 << i)) + tempFilter->InitR[i] = inp.ReadEncodedUInt32(); + } + + bool isOK = true; + if (newFilter) + { + UInt32 vmCodeSize = inp.ReadEncodedUInt32(); + if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0) + return false; + for (UInt32 i = 0; i < vmCodeSize; i++) + _vmCode[i] = (Byte)inp.ReadBits(8); + isOK = filter->PrepareProgram(_vmCode, vmCodeSize); + } + + { + Byte *globalData = &tempFilter->GlobalData[0]; + for (unsigned i = 0; i < NVm::kNumGpRegs; i++) + NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize); + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why? + NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], filter->ExecCount); + } + + if (firstByte & 8) + { + UInt32 dataSize = inp.ReadEncodedUInt32(); + if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize) + return false; + CRecordVector &globalData = tempFilter->GlobalData; + unsigned requiredSize = (unsigned)(dataSize + NVm::kFixedGlobalSize); + if (globalData.Size() < requiredSize) + globalData.ChangeSize_KeepData(requiredSize); + Byte *dest = &globalData[NVm::kFixedGlobalSize]; + for (UInt32 i = 0; i < dataSize; i++) + dest[i] = (Byte)inp.ReadBits(8); + } + + return isOK; +} + +bool CDecoder::ReadVmCodeLZ() +{ + UInt32 firstByte = ReadBits(8); + UInt32 len = (firstByte & 7) + 1; + if (len == 7) + len = ReadBits(8) + 7; + else if (len == 8) + len = ReadBits(16); + if (len > kVmDataSizeMax) + return false; + for (UInt32 i = 0; i < len; i++) + _vmData[i] = (Byte)ReadBits(8); + return AddVmCode(firstByte, len); +} + + +// int CDecoder::DecodePpmSymbol() { return Ppmd7a_DecodeSymbol(&_ppmd); } +#define DecodePpmSymbol() Ppmd7a_DecodeSymbol(&_ppmd) + + +bool CDecoder::ReadVmCodePPM() +{ + const int firstByte = DecodePpmSymbol(); + if (firstByte < 0) + return false; + UInt32 len = (firstByte & 7) + 1; + if (len == 7) + { + const int b1 = DecodePpmSymbol(); + if (b1 < 0) + return false; + len = (unsigned)b1 + 7; + } + else if (len == 8) + { + const int b1 = DecodePpmSymbol(); + if (b1 < 0) + return false; + const int b2 = DecodePpmSymbol(); + if (b2 < 0) + return false; + len = (unsigned)b1 * 256 + (unsigned)b2; + } + if (len > kVmDataSizeMax) + return false; + if (InputEofError_Fast()) + return false; + for (UInt32 i = 0; i < len; i++) + { + const int b = DecodePpmSymbol(); + if (b < 0) + return false; + _vmData[i] = (Byte)b; + } + return AddVmCode((unsigned)firstByte, len); +} + +#define RIF(x) { if (!(x)) return S_FALSE; } + +UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.BitDecoder.ReadBits(numBits); } + +// ---------- PPM ---------- + +HRESULT CDecoder::InitPPM() +{ + unsigned maxOrder = (unsigned)ReadBits(7); + + const bool reset = ((maxOrder & 0x20) != 0); + UInt32 maxMB = 0; + if (reset) + maxMB = (Byte)Wrap_ReadBits8(&m_InBitStream.IByteIn_obj); + else + { + if (PpmError || !Ppmd7_WasAllocated(&_ppmd)) + return S_FALSE; + } + if (maxOrder & 0x40) + PpmEscChar = (Byte)Wrap_ReadBits8(&m_InBitStream.IByteIn_obj); + + _ppmd.rc.dec.Stream = &m_InBitStream.IByteIn_obj; + m_InBitStream.IByteIn_obj.Read = Wrap_ReadBits8; + + Ppmd7a_RangeDec_Init(&_ppmd.rc.dec); + + m_InBitStream.IByteIn_obj.Read = Wrap_ReadByte; + + if (reset) + { + PpmError = true; + maxOrder = (maxOrder & 0x1F) + 1; + if (maxOrder > 16) + maxOrder = 16 + (maxOrder - 16) * 3; + if (maxOrder == 1) + { + Ppmd7_Free(&_ppmd, &g_BigAlloc); + return S_FALSE; + } + if (!Ppmd7_Alloc(&_ppmd, (maxMB + 1) << 20, &g_BigAlloc)) + return E_OUTOFMEMORY; + Ppmd7_Init(&_ppmd, maxOrder); + PpmError = false; + } + return S_OK; +} + + +HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing) +{ + keepDecompressing = false; + if (PpmError) + return S_FALSE; + do + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()) + if (_writtenFileSize > _unpackSize) + { + keepDecompressing = false; + return S_OK; + } + } + if (InputEofError_Fast()) + return false; + const int c = DecodePpmSymbol(); + if (c < 0) + { + PpmError = true; + return S_FALSE; + } + if (c == PpmEscChar) + { + const int nextCh = DecodePpmSymbol(); + if (nextCh < 0) + { + PpmError = true; + return S_FALSE; + } + if (nextCh == 0) + return ReadTables(keepDecompressing); + if (nextCh == 2 || nextCh == -1) + return S_OK; + if (nextCh == 3) + { + if (!ReadVmCodePPM()) + { + PpmError = true; + return S_FALSE; + } + continue; + } + if (nextCh == 4 || nextCh == 5) + { + UInt32 dist = 0; + UInt32 len = 4; + if (nextCh == 4) + { + for (int i = 0; i < 3; i++) + { + const int c2 = DecodePpmSymbol(); + if (c2 < 0) + { + PpmError = true; + return S_FALSE; + } + dist = (dist << 8) + (Byte)c2; + } + dist++; + len += 28; + } + const int c2 = DecodePpmSymbol(); + if (c2 < 0) + { + PpmError = true; + return S_FALSE; + } + len += (unsigned)c2; + if (dist >= _lzSize) + return S_FALSE; + CopyBlock(dist, len); + num -= (Int32)len; + continue; + } + } + PutByte((Byte)c); + num--; + } + while (num >= 0); + keepDecompressing = true; + return S_OK; +} + +// ---------- LZ ---------- + +HRESULT CDecoder::ReadTables(bool &keepDecompressing) +{ + keepDecompressing = true; + m_InBitStream.BitDecoder.AlignToByte(); + if (ReadBits(1) != 0) + { + _lzMode = false; + return InitPPM(); + } + + TablesRead = false; + TablesOK = false; + + _lzMode = true; + PrevAlignBits = 0; + PrevAlignCount = 0; + + const unsigned kLevelTableSize = 20; + Byte levelLevels[kLevelTableSize]; + Byte lens[kTablesSizesSum]; + + if (ReadBits(1) == 0) + memset(m_LastLevels, 0, kTablesSizesSum); + + unsigned i; + + for (i = 0; i < kLevelTableSize; i++) + { + const UInt32 len = ReadBits(4); + if (len == 15) + { + UInt32 zeroCount = ReadBits(4); + if (zeroCount != 0) + { + zeroCount += 2; + while (zeroCount-- > 0 && i < kLevelTableSize) + levelLevels[i++]=0; + i--; + continue; + } + } + levelLevels[i] = (Byte)len; + } + + NHuffman::CDecoder256 m_LevelDecoder; + RIF(m_LevelDecoder.Build(levelLevels, NHuffman::k_BuildMode_Full)) + + i = 0; + + do + { + const unsigned sym = m_LevelDecoder.DecodeFull(&m_InBitStream.BitDecoder); + if (sym < 16) + { + lens[i] = Byte((sym + m_LastLevels[i]) & 15); + i++; + } +#if 0 + else if (sym > kLevelTableSize) + return S_FALSE; +#endif + else + { + unsigned num = ((sym /* - 16 */) & 1) * 4; + num += num + 3 + (unsigned)ReadBits(num + 3); + num += i; + if (num > kTablesSizesSum) + num = kTablesSizesSum; + Byte v = 0; + if (sym < 16 + 2) + { + if (i == 0) + return S_FALSE; + v = lens[(size_t)i - 1]; + } + do + lens[i++] = v; + while (i < num); + } + } + while (i < kTablesSizesSum); + + if (InputEofError()) + return S_FALSE; + + TablesRead = true; + + // original code has check here: + /* + if (InAddr > ReadTop) + { + keepDecompressing = false; + return true; + } + */ + + RIF(m_MainDecoder.Build(&lens[0])) + RIF(m_DistDecoder.Build(&lens[kMainTableSize])) + RIF(m_AlignDecoder.Build(&lens[kMainTableSize + kDistTableSize])) + RIF(m_LenDecoder.Build(&lens[kMainTableSize + kDistTableSize + kAlignTableSize])) + + memcpy(m_LastLevels, lens, kTablesSizesSum); + + TablesOK = true; + + return S_OK; +} + +/* +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + m_Coder->ReleaseStreams(); + } +}; +*/ + +HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing) +{ + if (ReadBits(1) == 0) + { + // new file + keepDecompressing = false; + TablesRead = (ReadBits(1) == 0); + return S_OK; + } + TablesRead = false; + return ReadTables(keepDecompressing); +} + + +HRESULT CDecoder::DecodeLZ(bool &keepDecompressing) +{ + UInt32 rep0 = _reps[0]; + UInt32 rep1 = _reps[1]; + UInt32 rep2 = _reps[2]; + UInt32 rep3 = _reps[3]; + UInt32 len = _lastLength; + for (;;) + { + if (((_wrPtr - _winPos) & kWindowMask) < 260 && _wrPtr != _winPos) + { + RINOK(WriteBuf()) + if (_writtenFileSize > _unpackSize) + { + keepDecompressing = false; + return S_OK; + } + } + + if (InputEofError_Fast()) + return S_FALSE; + + unsigned sym = m_MainDecoder.Decode(&m_InBitStream.BitDecoder); + if (sym < 256) + { + PutByte((Byte)sym); + continue; + } + else if (sym == kSymbolReadTable) + { + RINOK(ReadEndOfBlock(keepDecompressing)) + break; + } + else if (sym == 257) + { + if (!ReadVmCodeLZ()) + return S_FALSE; + continue; + } + else if (sym == 258) + { + if (len == 0) + return S_FALSE; + } + else if (sym < kSymbolRep + 4) + { + if (sym != kSymbolRep) + { + UInt32 dist; + if (sym == kSymbolRep + 1) + dist = rep1; + else + { + if (sym == kSymbolRep + 2) + dist = rep2; + else + { + dist = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = dist; + } + + const unsigned sym2 = m_LenDecoder.Decode(&m_InBitStream.BitDecoder); + if (sym2 >= kLenTableSize) + return S_FALSE; + len = 2 + sym2; + if (sym2 >= 8) + { + const unsigned num = (sym2 >> 2) - 1; + len = 2 + (UInt32)((4 + (sym2 & 3)) << num) + m_InBitStream.BitDecoder.ReadBits_upto8(num); + } + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + if (sym < 271) + { + sym -= 263; + rep0 = kLen2DistStarts[sym] + m_InBitStream.BitDecoder.ReadBits_upto8(kLen2DistDirectBits[sym]); + len = 2; + } + else if (sym < 299) + { + sym -= 271; + len = kNormalMatchMinLen + sym; + if (sym >= 8) + { + const unsigned num = (sym >> 2) - 1; + len = kNormalMatchMinLen + (UInt32)((4 + (sym & 3)) << num) + m_InBitStream.BitDecoder.ReadBits_upto8(num); + } + const unsigned sym2 = m_DistDecoder.Decode(&m_InBitStream.BitDecoder); + if (sym2 >= kDistTableSize) + return S_FALSE; + rep0 = kDistStart[sym2]; + unsigned numBits = kDistDirectBits[sym2]; + if (sym2 >= (kNumAlignBits * 2) + 2) + { + if (numBits > kNumAlignBits) + rep0 += (m_InBitStream.BitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits); + if (PrevAlignCount > 0) + { + PrevAlignCount--; + rep0 += PrevAlignBits; + } + else + { + const unsigned sym3 = m_AlignDecoder.Decode(&m_InBitStream.BitDecoder); + if (sym3 < (1 << kNumAlignBits)) + { + rep0 += sym3; + PrevAlignBits = sym3; + } + else if (sym3 == (1 << kNumAlignBits)) + { + PrevAlignCount = kNumAlignReps; + rep0 += PrevAlignBits; + } + else + return S_FALSE; + } + } + else + rep0 += m_InBitStream.BitDecoder.ReadBits_upto8(numBits); + len += ((UInt32)(kDistLimit4 - rep0) >> 31) + ((UInt32)(kDistLimit3 - rep0) >> 31); + } + else + return S_FALSE; + } + if (rep0 >= _lzSize) + return S_FALSE; + CopyBlock(rep0, len); + } + _reps[0] = rep0; + _reps[1] = rep1; + _reps[2] = rep2; + _reps[3] = rep3; + _lastLength = len; + + return S_OK; +} + + +HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) +{ + _writtenFileSize = 0; + _unsupportedFilter = false; + + if (!_isSolid) + { + _lzSize = 0; + _winPos = 0; + _wrPtr = 0; + for (unsigned i = 0; i < kNumReps; i++) + _reps[i] = 0; + _lastLength = 0; + memset(m_LastLevels, 0, kTablesSizesSum); + TablesRead = false; + PpmEscChar = 2; + PpmError = true; + InitFilters(); + // _errorMode = false; + } + + /* + if (_errorMode) + return S_FALSE; + */ + + if (!_isSolid || !TablesRead) + { + bool keepDecompressing; + RINOK(ReadTables(keepDecompressing)) + if (!keepDecompressing) + { + _solidAllowed = true; + return S_OK; + } + } + + for (;;) + { + bool keepDecompressing; + if (_lzMode) + { + if (!TablesOK) + return S_FALSE; + RINOK(DecodeLZ(keepDecompressing)) + } + else + { + RINOK(DecodePPM(1 << 18, keepDecompressing)) + } + + if (InputEofError()) + return S_FALSE; + + const UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)) + if (!keepDecompressing) + break; + } + + _solidAllowed = true; + + RINOK(WriteBuf()) + const UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)) + if (_writtenFileSize < _unpackSize) + return S_FALSE; + + if (_unsupportedFilter) + return E_NOTIMPL; + + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try + { + if (!inSize) + return E_INVALIDARG; + + if (_isSolid && !_solidAllowed) + return S_FALSE; + _solidAllowed = false; + + if (!_vmData) + { + _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); + if (!_vmData) + return E_OUTOFMEMORY; + _vmCode = _vmData + kVmDataSizeMax; + } + + if (!_window) + { + _window = (Byte *)::MidAlloc(kWindowSize); + if (!_window) + return E_OUTOFMEMORY; + } + if (!m_InBitStream.BitDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_vm.Create()) + return E_OUTOFMEMORY; + + + m_InBitStream.BitDecoder.SetStream(inStream); + m_InBitStream.BitDecoder.Init(); + _outStream = outStream; + + // CCoderReleaser coderReleaser(this); + _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; + return CodeReal(progress); + } + catch(const CInBufferException &e) { /* _errorMode = true; */ return e.ErrorCode; } + catch(...) { /* _errorMode = true; */ return S_FALSE; } + // CNewException is possible here. But probably CNewException is caused + // by error in data stream. +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size < 1) + return E_INVALIDARG; + _isSolid = ((data[0] & 1) != 0); + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar3Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Rar3Decoder.h 2015-10-03 08:49:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Decoder.h 2024-01-07 10:00:00.000000000 +0000 @@ -1,282 +1,283 @@ -// Rar3Decoder.h -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#ifndef __COMPRESS_RAR3_DECODER_H -#define __COMPRESS_RAR3_DECODER_H - -#include "../../../C/Ppmd7.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -#include "../Common/InBuffer.h" - -#include "BitmDecoder.h" -#include "HuffmanDecoder.h" -#include "Rar3Vm.h" - -namespace NCompress { -namespace NRar3 { - -const UInt32 kWindowSize = 1 << 22; -const UInt32 kWindowMask = (kWindowSize - 1); - -const UInt32 kNumReps = 4; -const UInt32 kNumLen2Symbols = 8; -const UInt32 kLenTableSize = 28; -const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize; -const UInt32 kDistTableSize = 60; - -const int kNumAlignBits = 4; -const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1; - -const UInt32 kLevelTableSize = 20; - -const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; - -class CBitDecoder -{ - UInt32 _value; - unsigned _bitPos; -public: - CInBuffer Stream; - - bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } - void SetStream(ISequentialInStream *inStream) { Stream.SetStream(inStream);} - - void Init() - { - Stream.Init(); - _bitPos = 0; - _value = 0; - } - - bool ExtraBitsWereRead() const - { - return (Stream.NumExtraBytes > 4 || _bitPos < (Stream.NumExtraBytes << 3)); - } - - UInt64 GetProcessedSize() const { return Stream.GetProcessedSize() - (_bitPos >> 3); } - - void AlignToByte() - { - _bitPos &= ~(unsigned)7; - _value = _value & ((1 << _bitPos) - 1); - } - - UInt32 GetValue(unsigned numBits) - { - if (_bitPos < numBits) - { - _bitPos += 8; - _value = (_value << 8) | Stream.ReadByte(); - if (_bitPos < numBits) - { - _bitPos += 8; - _value = (_value << 8) | Stream.ReadByte(); - } - } - return _value >> (_bitPos - numBits); - } - - void MovePos(unsigned numBits) - { - _bitPos -= numBits; - _value = _value & ((1 << _bitPos) - 1); - } - - UInt32 ReadBits(unsigned numBits) - { - UInt32 res = GetValue(numBits); - MovePos(numBits); - return res; - } -}; - -const UInt32 kTopValue = (1 << 24); -const UInt32 kBot = (1 << 15); - -struct CRangeDecoder -{ - IPpmd7_RangeDec s; - UInt32 Range; - UInt32 Code; - UInt32 Low; - CBitDecoder BitDecoder; - SRes Res; - -public: - void InitRangeCoder() - { - Code = 0; - Low = 0; - Range = 0xFFFFFFFF; - for (int i = 0; i < 4; i++) - Code = (Code << 8) | BitDecoder.ReadBits(8); - } - - void Normalize() - { - while ((Low ^ (Low + Range)) < kTopValue || - Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) - { - Code = (Code << 8) | BitDecoder.Stream.ReadByte(); - Range <<= 8; - Low <<= 8; - } - } - - CRangeDecoder(); -}; - -struct CFilter: public NVm::CProgram -{ - CRecordVector GlobalData; - UInt32 BlockStart; - UInt32 BlockSize; - UInt32 ExecCount; - - CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} -}; - -struct CTempFilter: public NVm::CProgramInitState -{ - UInt32 BlockStart; - UInt32 BlockSize; - bool NextWindow; - - UInt32 FilterIndex; - - CTempFilter() - { - // all filters must contain at least FixedGlobal block - AllocateEmptyFixedGlobal(); - } -}; - -const int kNumHuffmanBits = 15; - -class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public CMyUnknownImp -{ - CRangeDecoder m_InBitStream; - Byte *_window; - UInt32 _winPos; - UInt32 _wrPtr; - UInt64 _lzSize; - UInt64 _unpackSize; - UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written - ISequentialOutStream *_outStream; - NHuffman::CDecoder m_MainDecoder; - NHuffman::CDecoder m_DistDecoder; - NHuffman::CDecoder m_AlignDecoder; - NHuffman::CDecoder m_LenDecoder; - NHuffman::CDecoder m_LevelDecoder; - - UInt32 _reps[kNumReps]; - UInt32 _lastLength; - - Byte m_LastLevels[kTablesSizesSum]; - - Byte *_vmData; - Byte *_vmCode; - NVm::CVm _vm; - CRecordVector _filters; - CRecordVector _tempFilters; - UInt32 _lastFilter; - - bool m_IsSolid; - - bool _lzMode; - bool _unsupportedFilter; - - UInt32 PrevAlignBits; - UInt32 PrevAlignCount; - - bool TablesRead; - - CPpmd7 _ppmd; - int PpmEscChar; - bool PpmError; - - HRESULT WriteDataToStream(const Byte *data, UInt32 size); - HRESULT WriteData(const Byte *data, UInt32 size); - HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr); - void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef); - HRESULT WriteBuf(); - - void InitFilters(); - bool AddVmCode(UInt32 firstByte, UInt32 codeSize); - bool ReadVmCodeLZ(); - bool ReadVmCodePPM(); - - UInt32 ReadBits(int numBits); - - HRESULT InitPPM(); - int DecodePpmSymbol(); - HRESULT DecodePPM(Int32 num, bool &keepDecompressing); - - HRESULT ReadTables(bool &keepDecompressing); - HRESULT ReadEndOfBlock(bool &keepDecompressing); - HRESULT DecodeLZ(bool &keepDecompressing); - HRESULT CodeReal(ICompressProgressInfo *progress); - - bool InputEofError() const { return m_InBitStream.BitDecoder.ExtraBitsWereRead(); } - bool InputEofError_Fast() const { return (m_InBitStream.BitDecoder.Stream.NumExtraBytes > 2); } - -public: - CDecoder(); - ~CDecoder(); - - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - - void CopyBlock(UInt32 distance, UInt32 len) - { - _lzSize += len; - UInt32 pos = (_winPos - distance - 1) & kWindowMask; - Byte *window = _window; - UInt32 winPos = _winPos; - if (kWindowSize - winPos > len && kWindowSize - pos > len) - { - const Byte *src = window + pos; - Byte *dest = window + winPos; - _winPos += len; - do - *dest++ = *src++; - while (--len != 0); - return; - } - do - { - window[winPos] = window[pos]; - winPos = (winPos + 1) & kWindowMask; - pos = (pos + 1) & kWindowMask; - } - while (--len != 0); - _winPos = winPos; - } - - void PutByte(Byte b) - { - _window[_winPos] = b; - _winPos = (_winPos + 1) & kWindowMask; - _lzSize++; - } - - -}; - -}} - -#endif +// Rar3Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +/* This code uses Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ + +#ifndef ZIP7_INC_COMPRESS_RAR3_DECODER_H +#define ZIP7_INC_COMPRESS_RAR3_DECODER_H + +#include "../../../C/Ppmd7.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "Rar3Vm.h" + +namespace NCompress { +namespace NRar3 { + +const unsigned kNumHuffmanBits = 15; + +const UInt32 kWindowSize = 1 << 22; +const UInt32 kWindowMask = kWindowSize - 1; + +const unsigned kNumReps = 4; +const unsigned kNumLen2Symbols = 8; +const unsigned kLenTableSize = 28; +const unsigned kMainTableSize = 256 + 3 + kNumReps + kNumLen2Symbols + kLenTableSize; +const unsigned kDistTableSize = 60; + +const unsigned kNumAlignBits = 4; +const unsigned kAlignTableSize = (1 << kNumAlignBits) + 1; + +const unsigned kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; + +class CBitDecoder +{ + UInt32 _value; + unsigned _bitPos; +public: + CInBuffer Stream; + + bool Create(UInt32 bufSize) { return Stream.Create(bufSize); } + void SetStream(ISequentialInStream *inStream) { Stream.SetStream(inStream);} + + void Init() + { + Stream.Init(); + _bitPos = 0; + _value = 0; + } + + bool ExtraBitsWereRead() const + { + return (Stream.NumExtraBytes > 4 || _bitPos < (Stream.NumExtraBytes << 3)); + } + + UInt64 GetProcessedSize() const { return Stream.GetProcessedSize() - (_bitPos >> 3); } + + void AlignToByte() + { + _bitPos &= ~(unsigned)7; + _value = _value & ((1 << _bitPos) - 1); + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) + { + if (_bitPos < numBits) + { + _bitPos += 8; + _value = (_value << 8) | Stream.ReadByte(); + if (_bitPos < numBits) + { + _bitPos += 8; + _value = (_value << 8) | Stream.ReadByte(); + } + } + return _value >> (_bitPos - numBits); + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() + { + return GetValue(kNumHuffmanBits) << (32 - kNumHuffmanBits); + } + + + Z7_FORCE_INLINE + void MovePos(unsigned numBits) + { + _bitPos -= numBits; + _value = _value & ((1 << _bitPos) - 1); + } + + UInt32 ReadBits(unsigned numBits) + { + const UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } + + UInt32 ReadBits_upto8(unsigned numBits) + { + if (_bitPos < numBits) + { + _bitPos += 8; + _value = (_value << 8) | Stream.ReadByte(); + } + _bitPos -= numBits; + const UInt32 res = _value >> _bitPos; + _value = _value & ((1 << _bitPos) - 1); + return res; + } + + Byte ReadByteFromAligned() + { + if (_bitPos == 0) + return Stream.ReadByte(); + const unsigned bitsPos = _bitPos - 8; + const Byte b = (Byte)(_value >> bitsPos); + _value = _value & ((1 << bitsPos) - 1); + _bitPos = bitsPos; + return b; + } +}; + + +struct CByteIn +{ + IByteIn IByteIn_obj; + CBitDecoder BitDecoder; +}; + + +struct CFilter: public NVm::CProgram +{ + CRecordVector GlobalData; + UInt32 BlockStart; + UInt32 BlockSize; + UInt32 ExecCount; + + CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} +}; + +struct CTempFilter: public NVm::CProgramInitState +{ + UInt32 BlockStart; + UInt32 BlockSize; + bool NextWindow; + + UInt32 FilterIndex; + + CTempFilter() + { + // all filters must contain at least FixedGlobal block + AllocateEmptyFixedGlobal(); + } +}; + + +Z7_CLASS_IMP_NOQIB_2( + CDecoder + , ICompressCoder + , ICompressSetDecoderProperties2 +) + bool _isSolid; + bool _solidAllowed; + // bool _errorMode; + + bool _lzMode; + bool _unsupportedFilter; + + CByteIn m_InBitStream; + Byte *_window; + UInt32 _winPos; + UInt32 _wrPtr; + UInt64 _lzSize; + UInt64 _unpackSize; + UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written + ISequentialOutStream *_outStream; + + NHuffman::CDecoder m_MainDecoder; + UInt32 kDistStart[kDistTableSize]; + NHuffman::CDecoder256 m_DistDecoder; + NHuffman::CDecoder256 m_AlignDecoder; + NHuffman::CDecoder256 m_LenDecoder; + + UInt32 _reps[kNumReps]; + UInt32 _lastLength; + + Byte m_LastLevels[kTablesSizesSum]; + + Byte *_vmData; + Byte *_vmCode; + NVm::CVm _vm; + CRecordVector _filters; + CRecordVector _tempFilters; + unsigned _numEmptyTempFilters; + UInt32 _lastFilter; + + UInt32 PrevAlignBits; + UInt32 PrevAlignCount; + + bool TablesRead; + bool TablesOK; + bool PpmError; + + int PpmEscChar; + CPpmd7 _ppmd; + + HRESULT WriteDataToStream(const Byte *data, UInt32 size); + HRESULT WriteData(const Byte *data, UInt32 size); + HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr); + void ExecuteFilter(unsigned tempFilterIndex, NVm::CBlockRef &outBlockRef); + HRESULT WriteBuf(); + + void InitFilters(); + bool AddVmCode(UInt32 firstByte, UInt32 codeSize); + bool ReadVmCodeLZ(); + bool ReadVmCodePPM(); + + UInt32 ReadBits(unsigned numBits); + + HRESULT InitPPM(); + // int DecodePpmSymbol(); + HRESULT DecodePPM(Int32 num, bool &keepDecompressing); + + HRESULT ReadTables(bool &keepDecompressing); + HRESULT ReadEndOfBlock(bool &keepDecompressing); + HRESULT DecodeLZ(bool &keepDecompressing); + HRESULT CodeReal(ICompressProgressInfo *progress); + + bool InputEofError() const { return m_InBitStream.BitDecoder.ExtraBitsWereRead(); } + bool InputEofError_Fast() const { return (m_InBitStream.BitDecoder.Stream.NumExtraBytes > 2); } + + void CopyBlock(UInt32 dist, UInt32 len) + { + _lzSize += len; + UInt32 pos = (_winPos - dist - 1) & kWindowMask; + Byte *window = _window; + UInt32 winPos = _winPos; + if (kWindowSize - winPos > len && kWindowSize - pos > len) + { + const Byte *src = window + pos; + Byte *dest = window + winPos; + _winPos += len; + do + *dest++ = *src++; + while (--len != 0); + return; + } + do + { + window[winPos] = window[pos]; + winPos = (winPos + 1) & kWindowMask; + pos = (pos + 1) & kWindowMask; + } + while (--len != 0); + _winPos = winPos; + } + + void PutByte(Byte b) + { + const UInt32 wp = _winPos; + _window[wp] = b; + _winPos = (wp + 1) & kWindowMask; + _lzSize++; + } + +public: + CDecoder(); + ~CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar3Vm.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Rar3Vm.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.cpp 2023-09-05 21:00:00.000000000 +0000 @@ -1,1126 +1,1153 @@ -// Rar3Vm.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -/* -Note: - Due to performance considerations Rar VM may set Flags C incorrectly - for some operands (SHL x, 0, ... ). - Check implementation of concrete VM command - to see if it sets flags right. -*/ - -#include "StdAfx.h" - -#include - -#include "../../../C/7zCrc.h" -#include "../../../C/Alloc.h" - -#include "../../Common/Defs.h" - -#include "Rar3Vm.h" - -namespace NCompress { -namespace NRar3 { - -UInt32 CMemBitDecoder::ReadBits(unsigned numBits) -{ - UInt32 res = 0; - for (;;) - { - unsigned b = _bitPos < _bitSize ? (unsigned)_data[_bitPos >> 3] : 0; - unsigned avail = (unsigned)(8 - (_bitPos & 7)); - if (numBits <= avail) - { - _bitPos += numBits; - return res | (b >> (avail - numBits)) & ((1 << numBits) - 1); - } - numBits -= avail; - res |= (UInt32)(b & ((1 << avail) - 1)) << numBits; - _bitPos += avail; - } -} - -UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); } - -UInt32 CMemBitDecoder::ReadEncodedUInt32() -{ - unsigned v = (unsigned)ReadBits(2); - UInt32 res = ReadBits(4 << v); - if (v == 1 && res < 16) - res = 0xFFFFFF00 | (res << 4) | ReadBits(4); - return res; -} - -namespace NVm { - -static const UInt32 kStackRegIndex = kNumRegs - 1; - -#ifdef RARVM_VM_ENABLE - -static const UInt32 FLAG_C = 1; -static const UInt32 FLAG_Z = 2; -static const UInt32 FLAG_S = 0x80000000; - -static const Byte CF_OP0 = 0; -static const Byte CF_OP1 = 1; -static const Byte CF_OP2 = 2; -static const Byte CF_OPMASK = 3; -static const Byte CF_BYTEMODE = 4; -static const Byte CF_JUMP = 8; -static const Byte CF_PROC = 16; -static const Byte CF_USEFLAGS = 32; -static const Byte CF_CHFLAGS = 64; - -static const Byte kCmdFlags[]= -{ - /* CMD_MOV */ CF_OP2 | CF_BYTEMODE, - /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_ADD */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_SUB */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_JZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JNZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_INC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_DEC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_JMP */ CF_OP1 | CF_JUMP, - /* CMD_XOR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_AND */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_OR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_TEST */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_JS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JNS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JB */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JBE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JA */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_JAE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, - /* CMD_PUSH */ CF_OP1, - /* CMD_POP */ CF_OP1, - /* CMD_CALL */ CF_OP1 | CF_PROC, - /* CMD_RET */ CF_OP0 | CF_PROC, - /* CMD_NOT */ CF_OP1 | CF_BYTEMODE, - /* CMD_SHL */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_SHR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_SAR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_NEG */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, - /* CMD_PUSHA */ CF_OP0, - /* CMD_POPA */ CF_OP0, - /* CMD_PUSHF */ CF_OP0 | CF_USEFLAGS, - /* CMD_POPF */ CF_OP0 | CF_CHFLAGS, - /* CMD_MOVZX */ CF_OP2, - /* CMD_MOVSX */ CF_OP2, - /* CMD_XCHG */ CF_OP2 | CF_BYTEMODE, - /* CMD_MUL */ CF_OP2 | CF_BYTEMODE, - /* CMD_DIV */ CF_OP2 | CF_BYTEMODE, - /* CMD_ADC */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , - /* CMD_SBB */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , - /* CMD_PRINT */ CF_OP0 -}; - -#endif - - -CVm::CVm(): Mem(NULL) {} - -bool CVm::Create() -{ - if (!Mem) - Mem = (Byte *)::MyAlloc(kSpaceSize + 4); - return (Mem != NULL); -} - -CVm::~CVm() -{ - ::MyFree(Mem); -} - -// CVm::Execute can change CProgram object: it clears progarm if VM returns error. - -bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, - CBlockRef &outBlockRef, CRecordVector &outGlobalData) -{ - memcpy(R, initState->InitR, sizeof(initState->InitR)); - R[kStackRegIndex] = kSpaceSize; - R[kNumRegs] = 0; - Flags = 0; - - UInt32 globalSize = MyMin((UInt32)initState->GlobalData.Size(), kGlobalSize); - if (globalSize != 0) - memcpy(Mem + kGlobalOffset, &initState->GlobalData[0], globalSize); - UInt32 staticSize = MyMin((UInt32)prg->StaticData.Size(), kGlobalSize - globalSize); - if (staticSize != 0) - memcpy(Mem + kGlobalOffset + globalSize, &prg->StaticData[0], staticSize); - - bool res = true; - - #ifdef RARVM_STANDARD_FILTERS - if (prg->StandardFilterIndex >= 0) - ExecuteStandardFilter(prg->StandardFilterIndex); - else - #endif - { - #ifdef RARVM_VM_ENABLE - res = ExecuteCode(prg); - if (!res) - { - prg->Commands.Clear(); - prg->Commands.Add(CCommand()); - prg->Commands.Back().OpCode = CMD_RET; - } - #else - res = false; - #endif - } - - UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask; - UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask; - if (newBlockPos + newBlockSize >= kSpaceSize) - newBlockPos = newBlockSize = 0; - outBlockRef.Offset = newBlockPos; - outBlockRef.Size = newBlockSize; - - outGlobalData.Clear(); - UInt32 dataSize = GetFixedGlobalValue32(NGlobalOffset::kGlobalMemOutSize); - dataSize = MyMin(dataSize, kGlobalSize - kFixedGlobalSize); - if (dataSize != 0) - { - dataSize += kFixedGlobalSize; - outGlobalData.ClearAndSetSize(dataSize); - memcpy(&outGlobalData[0], Mem + kGlobalOffset, dataSize); - } - - return res; -} - -#ifdef RARVM_VM_ENABLE - -#define SET_IP(IP) \ - if ((IP) >= numCommands) return true; \ - if (--maxOpCount <= 0) return false; \ - cmd = commands + (IP); - -#define GET_FLAG_S_B(res) (((res) & 0x80) ? FLAG_S : 0) -#define SET_IP_OP1 { UInt32 val = GetOperand32(&cmd->Op1); SET_IP(val); } -#define FLAGS_UPDATE_SZ Flags = res == 0 ? FLAG_Z : res & FLAG_S -#define FLAGS_UPDATE_SZ_B Flags = (res & 0xFF) == 0 ? FLAG_Z : GET_FLAG_S_B(res) - -UInt32 CVm::GetOperand32(const COperand *op) const -{ - switch (op->Type) - { - case OP_TYPE_REG: return R[op->Data]; - case OP_TYPE_REGMEM: return GetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask]); - default: return op->Data; - } -} - -void CVm::SetOperand32(const COperand *op, UInt32 val) -{ - switch (op->Type) - { - case OP_TYPE_REG: R[op->Data] = val; return; - case OP_TYPE_REGMEM: SetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask], val); return; - } -} - -Byte CVm::GetOperand8(const COperand *op) const -{ - switch (op->Type) - { - case OP_TYPE_REG: return (Byte)R[op->Data]; - case OP_TYPE_REGMEM: return Mem[(op->Base + R[op->Data]) & kSpaceMask];; - default: return (Byte)op->Data; - } -} - -void CVm::SetOperand8(const COperand *op, Byte val) -{ - switch (op->Type) - { - case OP_TYPE_REG: R[op->Data] = (R[op->Data] & 0xFFFFFF00) | val; return; - case OP_TYPE_REGMEM: Mem[(op->Base + R[op->Data]) & kSpaceMask] = val; return; - } -} - -UInt32 CVm::GetOperand(bool byteMode, const COperand *op) const -{ - if (byteMode) - return GetOperand8(op); - return GetOperand32(op); -} - -void CVm::SetOperand(bool byteMode, const COperand *op, UInt32 val) -{ - if (byteMode) - SetOperand8(op, (Byte)(val & 0xFF)); - else - SetOperand32(op, val); -} - -bool CVm::ExecuteCode(const CProgram *prg) -{ - Int32 maxOpCount = 25000000; - const CCommand *commands = &prg->Commands[0]; - const CCommand *cmd = commands; - UInt32 numCommands = prg->Commands.Size(); - if (numCommands == 0) - return false; - - for (;;) - { - switch (cmd->OpCode) - { - case CMD_MOV: - SetOperand32(&cmd->Op1, GetOperand32(&cmd->Op2)); - break; - case CMD_MOVB: - SetOperand8(&cmd->Op1, GetOperand8(&cmd->Op2)); - break; - case CMD_CMP: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - UInt32 res = v1 - GetOperand32(&cmd->Op2); - Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); - } - break; - case CMD_CMPB: - { - Byte v1 = GetOperand8(&cmd->Op1); - Byte res = (Byte)((v1 - GetOperand8(&cmd->Op2)) & 0xFF); - Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res); - } - break; - case CMD_ADD: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - UInt32 res = v1 + GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - Flags = (res < v1) | (res == 0 ? FLAG_Z : (res & FLAG_S)); - } - break; - case CMD_ADDB: - { - Byte v1 = GetOperand8(&cmd->Op1); - Byte res = (Byte)((v1 + GetOperand8(&cmd->Op2)) & 0xFF); - SetOperand8(&cmd->Op1, (Byte)res); - Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)); - } - break; - case CMD_ADC: - { - UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); - UInt32 FC = (Flags & FLAG_C); - UInt32 res = v1 + GetOperand(cmd->ByteMode, &cmd->Op2) + FC; - if (cmd->ByteMode) - res &= 0xFF; - SetOperand(cmd->ByteMode, &cmd->Op1, res); - Flags = (res < v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); - } - break; - case CMD_SUB: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - UInt32 res = v1 - GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); - } - break; - case CMD_SUBB: - { - UInt32 v1 = GetOperand8(&cmd->Op1); - UInt32 res = v1 - GetOperand8(&cmd->Op2); - SetOperand8(&cmd->Op1, (Byte)res); - Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); - } - break; - case CMD_SBB: - { - UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); - UInt32 FC = (Flags & FLAG_C); - UInt32 res = v1 - GetOperand(cmd->ByteMode, &cmd->Op2) - FC; - // Flags = res == 0 ? FLAG_Z : (res > v1 || res == v1 && FC) | (res & FLAG_S); - if (cmd->ByteMode) - res &= 0xFF; - SetOperand(cmd->ByteMode, &cmd->Op1, res); - Flags = (res > v1 || res == v1 && FC) | (res == 0 ? FLAG_Z : (res & FLAG_S)); - } - break; - case CMD_INC: - { - UInt32 res = GetOperand32(&cmd->Op1) + 1; - SetOperand32(&cmd->Op1, res); - FLAGS_UPDATE_SZ; - } - break; - case CMD_INCB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) + 1); - SetOperand8(&cmd->Op1, res);; - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_DEC: - { - UInt32 res = GetOperand32(&cmd->Op1) - 1; - SetOperand32(&cmd->Op1, res); - FLAGS_UPDATE_SZ; - } - break; - case CMD_DECB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) - 1); - SetOperand8(&cmd->Op1, res);; - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_XOR: - { - UInt32 res = GetOperand32(&cmd->Op1) ^ GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - FLAGS_UPDATE_SZ; - } - break; - case CMD_XORB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2)); - SetOperand8(&cmd->Op1, res); - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_AND: - { - UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - FLAGS_UPDATE_SZ; - } - break; - case CMD_ANDB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); - SetOperand8(&cmd->Op1, res); - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_OR: - { - UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - FLAGS_UPDATE_SZ; - } - break; - case CMD_ORB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2)); - SetOperand8(&cmd->Op1, res); - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_TEST: - { - UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); - FLAGS_UPDATE_SZ; - } - break; - case CMD_TESTB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); - FLAGS_UPDATE_SZ_B; - } - break; - case CMD_NOT: - SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1)); - break; - case CMD_NEG: - { - UInt32 res = 0 - GetOperand32(&cmd->Op1); - SetOperand32(&cmd->Op1, res); - Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S); - } - break; - case CMD_NEGB: - { - Byte res = (Byte)(0 - GetOperand8(&cmd->Op1)); - SetOperand8(&cmd->Op1, res); - Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res); - } - break; - - case CMD_SHL: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - int v2 = (int)GetOperand32(&cmd->Op2); - UInt32 res = v1 << v2; - SetOperand32(&cmd->Op1, res); - Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0); - } - break; - case CMD_SHLB: - { - Byte v1 = GetOperand8(&cmd->Op1); - int v2 = (int)GetOperand8(&cmd->Op2); - Byte res = (Byte)(v1 << v2); - SetOperand8(&cmd->Op1, res); - Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0); - } - break; - case CMD_SHR: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - int v2 = (int)GetOperand32(&cmd->Op2); - UInt32 res = v1 >> v2; - SetOperand32(&cmd->Op1, res); - Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); - } - break; - case CMD_SHRB: - { - Byte v1 = GetOperand8(&cmd->Op1); - int v2 = (int)GetOperand8(&cmd->Op2); - Byte res = (Byte)(v1 >> v2); - SetOperand8(&cmd->Op1, res); - Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); - } - break; - case CMD_SAR: - { - UInt32 v1 = GetOperand32(&cmd->Op1); - int v2 = (int)GetOperand32(&cmd->Op2); - UInt32 res = UInt32(((Int32)v1) >> v2); - SetOperand32(&cmd->Op1, res); - Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); - } - break; - case CMD_SARB: - { - Byte v1 = GetOperand8(&cmd->Op1); - int v2 = (int)GetOperand8(&cmd->Op2); - Byte res = (Byte)(((signed char)v1) >> v2); - SetOperand8(&cmd->Op1, res); - Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); - } - break; - - case CMD_JMP: - SET_IP_OP1; - continue; - case CMD_JZ: - if ((Flags & FLAG_Z) != 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JNZ: - if ((Flags & FLAG_Z) == 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JS: - if ((Flags & FLAG_S) != 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JNS: - if ((Flags & FLAG_S) == 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JB: - if ((Flags & FLAG_C) != 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JBE: - if ((Flags & (FLAG_C | FLAG_Z)) != 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JA: - if ((Flags & (FLAG_C | FLAG_Z)) == 0) - { - SET_IP_OP1; - continue; - } - break; - case CMD_JAE: - if ((Flags & FLAG_C) == 0) - { - SET_IP_OP1; - continue; - } - break; - - case CMD_PUSH: - R[kStackRegIndex] -= 4; - SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1)); - break; - case CMD_POP: - SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask])); - R[kStackRegIndex] += 4; - break; - case CMD_CALL: - R[kStackRegIndex] -= 4; - SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1)); - SET_IP_OP1; - continue; - - case CMD_PUSHA: - { - for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4) - SetValue32(&Mem[SP & kSpaceMask], R[i]); - R[kStackRegIndex] -= kNumRegs * 4; - } - break; - case CMD_POPA: - { - for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4) - R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]); - } - break; - case CMD_PUSHF: - R[kStackRegIndex] -= 4; - SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags); - break; - case CMD_POPF: - Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); - R[kStackRegIndex] += 4; - break; - - case CMD_MOVZX: - SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2)); - break; - case CMD_MOVSX: - SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2)); - break; - case CMD_XCHG: - { - UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); - SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2)); - SetOperand(cmd->ByteMode, &cmd->Op2, v1); - } - break; - case CMD_MUL: - { - UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2); - SetOperand32(&cmd->Op1, res); - } - break; - case CMD_MULB: - { - Byte res = (Byte)(GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2)); - SetOperand8(&cmd->Op1, res); - } - break; - case CMD_DIV: - { - UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2); - if (divider != 0) - { - UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider; - SetOperand(cmd->ByteMode, &cmd->Op1, res); - } - } - break; - - case CMD_RET: - { - if (R[kStackRegIndex] >= kSpaceSize) - return true; - UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); - SET_IP(ip); - R[kStackRegIndex] += 4; - continue; - } - case CMD_PRINT: - break; - } - cmd++; - --maxOpCount; - } -} - -////////////////////////////////////////////////////// -// Read program - -static void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) -{ - if (inp.ReadBit()) - { - op.Type = OP_TYPE_REG; - op.Data = inp.ReadBits(kNumRegBits); - } - else if (inp.ReadBit() == 0) - { - op.Type = OP_TYPE_INT; - if (byteMode) - op.Data = inp.ReadBits(8); - else - op.Data = inp.ReadEncodedUInt32(); - } - else - { - op.Type = OP_TYPE_REGMEM; - if (inp.ReadBit() == 0) - { - op.Data = inp.ReadBits(kNumRegBits); - op.Base = 0; - } - else - { - if (inp.ReadBit() == 0) - op.Data = inp.ReadBits(kNumRegBits); - else - op.Data = kNumRegs; - op.Base = inp.ReadEncodedUInt32(); - } - } -} - -void CProgram::ReadProgram(const Byte *code, UInt32 codeSize) -{ - CMemBitDecoder inp; - inp.Init(code, codeSize); - - StaticData.Clear(); - - if (inp.ReadBit()) - { - UInt32 dataSize = inp.ReadEncodedUInt32() + 1; - for (UInt32 i = 0; inp.Avail() && i < dataSize; i++) - StaticData.Add((Byte)inp.ReadBits(8)); - } - - while (inp.Avail()) - { - Commands.Add(CCommand()); - CCommand *cmd = &Commands.Back(); - - if (inp.ReadBit() == 0) - cmd->OpCode = (ECommand)inp.ReadBits(3); - else - cmd->OpCode = (ECommand)(8 + inp.ReadBits(5)); - - if (kCmdFlags[(unsigned)cmd->OpCode] & CF_BYTEMODE) - cmd->ByteMode = (inp.ReadBit()) ? true : false; - else - cmd->ByteMode = 0; - - int opNum = (kCmdFlags[(unsigned)cmd->OpCode] & CF_OPMASK); - - if (opNum > 0) - { - DecodeArg(inp, cmd->Op1, cmd->ByteMode); - if (opNum == 2) - DecodeArg(inp, cmd->Op2, cmd->ByteMode); - else - { - if (cmd->Op1.Type == OP_TYPE_INT && (kCmdFlags[(unsigned)cmd->OpCode] & (CF_JUMP | CF_PROC))) - { - int dist = cmd->Op1.Data; - if (dist >= 256) - dist -= 256; - else - { - if (dist >= 136) - dist -= 264; - else if (dist >= 16) - dist -= 8; - else if (dist >= 8) - dist -= 16; - dist += Commands.Size() - 1; - } - cmd->Op1.Data = dist; - } - } - } - - if (cmd->ByteMode) - { - switch (cmd->OpCode) - { - case CMD_MOV: cmd->OpCode = CMD_MOVB; break; - case CMD_CMP: cmd->OpCode = CMD_CMPB; break; - case CMD_ADD: cmd->OpCode = CMD_ADDB; break; - case CMD_SUB: cmd->OpCode = CMD_SUBB; break; - case CMD_INC: cmd->OpCode = CMD_INCB; break; - case CMD_DEC: cmd->OpCode = CMD_DECB; break; - case CMD_XOR: cmd->OpCode = CMD_XORB; break; - case CMD_AND: cmd->OpCode = CMD_ANDB; break; - case CMD_OR: cmd->OpCode = CMD_ORB; break; - case CMD_TEST: cmd->OpCode = CMD_TESTB; break; - case CMD_NEG: cmd->OpCode = CMD_NEGB; break; - case CMD_SHL: cmd->OpCode = CMD_SHLB; break; - case CMD_SHR: cmd->OpCode = CMD_SHRB; break; - case CMD_SAR: cmd->OpCode = CMD_SARB; break; - case CMD_MUL: cmd->OpCode = CMD_MULB; break; - } - } - } -} - -#endif - - -#ifdef RARVM_STANDARD_FILTERS - -enum EStandardFilter -{ - SF_E8, - SF_E8E9, - SF_ITANIUM, - SF_RGB, - SF_AUDIO, - SF_DELTA - // SF_UPCASE -}; - -static const struct CStandardFilterSignature -{ - UInt32 Length; - UInt32 CRC; - EStandardFilter Type; -} -kStdFilters[]= -{ - { 53, 0xad576887, SF_E8 }, - { 57, 0x3cd7e57e, SF_E8E9 }, - { 120, 0x3769893f, SF_ITANIUM }, - { 29, 0x0e06077d, SF_DELTA }, - { 149, 0x1c2c5dc8, SF_RGB }, - { 216, 0xbc85e701, SF_AUDIO } - // { 40, 0x46b9c560, SF_UPCASE } -}; - -static int FindStandardFilter(const Byte *code, UInt32 codeSize) -{ - UInt32 crc = CrcCalc(code, codeSize); - for (unsigned i = 0; i < ARRAY_SIZE(kStdFilters); i++) - { - const CStandardFilterSignature &sfs = kStdFilters[i]; - if (sfs.CRC == crc && sfs.Length == codeSize) - return i; - } - return -1; -} - -#endif - - -bool CProgram::PrepareProgram(const Byte *code, UInt32 codeSize) -{ - IsSupported = false; - - #ifdef RARVM_VM_ENABLE - Commands.Clear(); - #endif - - #ifdef RARVM_STANDARD_FILTERS - StandardFilterIndex = -1; - #endif - - bool isOK = false; - - Byte xorSum = 0; - for (UInt32 i = 0; i < codeSize; i++) - xorSum ^= code[i]; - - if (xorSum == 0 && codeSize != 0) - { - IsSupported = true; - isOK = true; - #ifdef RARVM_STANDARD_FILTERS - StandardFilterIndex = FindStandardFilter(code, codeSize); - if (StandardFilterIndex >= 0) - return true; - #endif - - #ifdef RARVM_VM_ENABLE - ReadProgram(code + 1, codeSize - 1); - #else - IsSupported = false; - #endif - } - - #ifdef RARVM_VM_ENABLE - Commands.Add(CCommand()); - Commands.Back().OpCode = CMD_RET; - #endif - - return isOK; -} - -void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize) -{ - if (pos < kSpaceSize && data != Mem + pos) - memmove(Mem + pos, data, MyMin(dataSize, kSpaceSize - pos)); -} - -#ifdef RARVM_STANDARD_FILTERS - -static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9) -{ - if (dataSize <= 4) - return; - dataSize -= 4; - const UInt32 kFileSize = 0x1000000; - Byte cmpMask = (Byte)(e9 ? 0xFE : 0xFF); - for (UInt32 curPos = 0; curPos < dataSize;) - { - curPos++; - if (((*data++) & cmpMask) == 0xE8) - { - UInt32 offset = curPos + fileOffset; - UInt32 addr = (Int32)GetValue32(data); - if (addr < kFileSize) - SetValue32(data, addr - offset); - else if ((Int32)addr < 0 && (Int32)(addr + offset) >= 0) - SetValue32(data, addr + kFileSize); - data += 4; - curPos += 4; - } - } -} - -static inline UInt32 ItaniumGetOpType(const Byte *data, unsigned bitPos) -{ - return (data[bitPos >> 3] >> (bitPos & 7)) & 0xF; -} - -static const Byte kCmdMasks[16] = {4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; - -static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) -{ - UInt32 curPos = 0; - fileOffset >>= 4; - while (curPos < dataSize - 21) - { - int b = (data[0] & 0x1F) - 0x10; - if (b >= 0) - { - Byte cmdMask = kCmdMasks[b]; - if (cmdMask != 0) - for (unsigned i = 0; i < 3; i++) - if (cmdMask & (1 << i)) - { - unsigned startPos = i * 41 + 18; - if (ItaniumGetOpType(data, startPos + 24) == 5) - { - const UInt32 kMask = 0xFFFFF; - Byte *p = data + (startPos >> 3); - UInt32 bitField = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); - unsigned inBit = (startPos & 7); - UInt32 offset = (bitField >> inBit) & kMask; - UInt32 andMask = ~(kMask << inBit); - bitField = ((offset - fileOffset) & kMask) << inBit; - for (unsigned j = 0; j < 3; j++) - { - p[j] &= andMask; - p[j] |= bitField; - andMask >>= 8; - bitField >>= 8; - } - } - } - } - data += 16; - curPos += 16; - fileOffset++; - } -} - -static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels) -{ - UInt32 srcPos = 0; - UInt32 border = dataSize * 2; - for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) - { - Byte prevByte = 0; - for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels) - data[destPos] = (prevByte = (Byte)(prevByte - data[srcPos++])); - } -} - -static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR) -{ - Byte *destData = srcData + dataSize; - const UInt32 numChannels = 3; - for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) - { - Byte prevByte = 0; - - for (UInt32 i = curChannel; i < dataSize; i+= numChannels) - { - unsigned int predicted; - if (i < width) - predicted = prevByte; - else - { - unsigned int upperLeftByte = destData[i - width]; - unsigned int upperByte = destData[i - width + 3]; - predicted = prevByte + upperByte - upperLeftByte; - int pa = abs((int)(predicted - prevByte)); - int pb = abs((int)(predicted - upperByte)); - int pc = abs((int)(predicted - upperLeftByte)); - if (pa <= pb && pa <= pc) - predicted = prevByte; - else - if (pb <= pc) - predicted = upperByte; - else - predicted = upperLeftByte; - } - destData[i] = prevByte = (Byte)(predicted - *(srcData++)); - } - } - if (dataSize < 3) - return; - for (UInt32 i = posR, border = dataSize - 2; i < border; i += 3) - { - Byte g = destData[i + 1]; - destData[i ] = (Byte)(destData[i ] + g); - destData[i + 2] = (Byte)(destData[i + 2] + g); - } -} - -static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels) -{ - Byte *destData = srcData + dataSize; - for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) - { - UInt32 prevByte = 0, prevDelta = 0, dif[7]; - Int32 D1 = 0, D2 = 0, D3; - Int32 K1 = 0, K2 = 0, K3 = 0; - memset(dif, 0, sizeof(dif)); - - for (UInt32 i = curChannel, byteCount = 0; i < dataSize; i += numChannels, byteCount++) - { - D3 = D2; - D2 = prevDelta - D1; - D1 = prevDelta; - - UInt32 predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3; - predicted = (predicted >> 3) & 0xFF; - - UInt32 curByte = *(srcData++); - - predicted -= curByte; - destData[i] = (Byte)predicted; - prevDelta = (UInt32)(Int32)(signed char)(predicted - prevByte); - prevByte = predicted; - - Int32 D = ((Int32)(signed char)curByte) << 3; - - dif[0] += abs(D); - dif[1] += abs(D - D1); - dif[2] += abs(D + D1); - dif[3] += abs(D - D2); - dif[4] += abs(D + D2); - dif[5] += abs(D - D3); - dif[6] += abs(D + D3); - - if ((byteCount & 0x1F) == 0) - { - UInt32 minDif = dif[0], numMinDif = 0; - dif[0] = 0; - for (unsigned j = 1; j < ARRAY_SIZE(dif); j++) - { - if (dif[j] < minDif) - { - minDif = dif[j]; - numMinDif = j; - } - dif[j] = 0; - } - switch (numMinDif) - { - case 1: if (K1 >= -16) K1--; break; - case 2: if (K1 < 16) K1++; break; - case 3: if (K2 >= -16) K2--; break; - case 4: if (K2 < 16) K2++; break; - case 5: if (K3 >= -16) K3--; break; - case 6: if (K3 < 16) K3++; break; - } - } - } - } -} - -/* -static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize) -{ - UInt32 srcPos = 0, destPos = dataSize; - while (srcPos < dataSize) - { - Byte curByte = data[srcPos++]; - if (curByte == 2 && (curByte = data[srcPos++]) != 2) - curByte -= 32; - data[destPos++] = curByte; - } - return destPos - dataSize; -} -*/ - -void CVm::ExecuteStandardFilter(unsigned filterIndex) -{ - UInt32 dataSize = R[4]; - if (dataSize >= kGlobalOffset) - return; - EStandardFilter filterType = kStdFilters[filterIndex].Type; - - switch (filterType) - { - case SF_E8: - case SF_E8E9: - E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9)); - break; - case SF_ITANIUM: - ItaniumDecode(Mem, dataSize, R[6]); - break; - case SF_DELTA: - if (dataSize >= kGlobalOffset / 2) - break; - SetBlockPos(dataSize); - DeltaDecode(Mem, dataSize, R[0]); - break; - case SF_RGB: - if (dataSize >= kGlobalOffset / 2) - break; - { - UInt32 width = R[0]; - if (width <= 3) - break; - SetBlockPos(dataSize); - RgbDecode(Mem, dataSize, width, R[1]); - } - break; - case SF_AUDIO: - if (dataSize >= kGlobalOffset / 2) - break; - SetBlockPos(dataSize); - AudioDecode(Mem, dataSize, R[0]); - break; - /* - case SF_UPCASE: - if (dataSize >= kGlobalOffset / 2) - break; - UInt32 destSize = UpCaseDecode(Mem, dataSize); - SetBlockSize(destSize); - SetBlockPos(dataSize); - break; - */ - } -} - -#endif - -}}} +// Rar3Vm.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +/* +Note: + Due to performance considerations Rar VM may set Flags C incorrectly + for some operands (SHL x, 0, ... ). + Check implementation of concrete VM command + to see if it sets flags right. +*/ + +#include "StdAfx.h" + +#include + +#include "../../../C/7zCrc.h" +#include "../../../C/Alloc.h" + +#include "../../Common/Defs.h" + +#include "Rar3Vm.h" + +namespace NCompress { +namespace NRar3 { + +UInt32 CMemBitDecoder::ReadBits(unsigned numBits) +{ + UInt32 res = 0; + for (;;) + { + const unsigned b = _bitPos < _bitSize ? (unsigned)_data[_bitPos >> 3] : 0; + const unsigned avail = (unsigned)(8 - (_bitPos & 7)); + if (numBits <= avail) + { + _bitPos += numBits; + return res | ((b >> (avail - numBits)) & ((1 << numBits) - 1)); + } + numBits -= avail; + res |= (UInt32)(b & ((1 << avail) - 1)) << numBits; + _bitPos += avail; + } +} + +UInt32 CMemBitDecoder::ReadBit() { return ReadBits(1); } + +UInt32 CMemBitDecoder::ReadEncodedUInt32() +{ + const unsigned v = (unsigned)ReadBits(2); + UInt32 res = ReadBits(4u << v); + if (v == 1 && res < 16) + res = 0xFFFFFF00 | (res << 4) | ReadBits(4); + return res; +} + +namespace NVm { + +static const UInt32 kStackRegIndex = kNumRegs - 1; + +#ifdef Z7_RARVM_VM_ENABLE + +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) \ + || defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30000) +// enumeration values not explicitly handled in switch +#pragma GCC diagnostic ignored "-Wswitch-enum" +#endif + +static const UInt32 FLAG_C = 1; +static const UInt32 FLAG_Z = 2; +static const UInt32 FLAG_S = 0x80000000; + +static const Byte CF_OP0 = 0; +static const Byte CF_OP1 = 1; +static const Byte CF_OP2 = 2; +static const Byte CF_OPMASK = 3; +static const Byte CF_BYTEMODE = 4; +static const Byte CF_JUMP = 8; +static const Byte CF_PROC = 16; +static const Byte CF_USEFLAGS = 32; +static const Byte CF_CHFLAGS = 64; + +static const Byte kCmdFlags[]= +{ + /* CMD_MOV */ CF_OP2 | CF_BYTEMODE, + /* CMD_CMP */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_ADD */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SUB */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNZ */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_INC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_DEC */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JMP */ CF_OP1 | CF_JUMP, + /* CMD_XOR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_AND */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_OR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_TEST */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_JS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JNS */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JB */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JBE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JA */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_JAE */ CF_OP1 | CF_JUMP | CF_USEFLAGS, + /* CMD_PUSH */ CF_OP1, + /* CMD_POP */ CF_OP1, + /* CMD_CALL */ CF_OP1 | CF_PROC, + /* CMD_RET */ CF_OP0 | CF_PROC, + /* CMD_NOT */ CF_OP1 | CF_BYTEMODE, + /* CMD_SHL */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SHR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_SAR */ CF_OP2 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_NEG */ CF_OP1 | CF_BYTEMODE | CF_CHFLAGS, + /* CMD_PUSHA */ CF_OP0, + /* CMD_POPA */ CF_OP0, + /* CMD_PUSHF */ CF_OP0 | CF_USEFLAGS, + /* CMD_POPF */ CF_OP0 | CF_CHFLAGS, + /* CMD_MOVZX */ CF_OP2, + /* CMD_MOVSX */ CF_OP2, + /* CMD_XCHG */ CF_OP2 | CF_BYTEMODE, + /* CMD_MUL */ CF_OP2 | CF_BYTEMODE, + /* CMD_DIV */ CF_OP2 | CF_BYTEMODE, + /* CMD_ADC */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_SBB */ CF_OP2 | CF_BYTEMODE | CF_USEFLAGS | CF_CHFLAGS , + /* CMD_PRINT */ CF_OP0 +}; + +#endif + + +CVm::CVm(): Mem(NULL) {} + +bool CVm::Create() +{ + if (!Mem) + Mem = (Byte *)::MyAlloc(kSpaceSize + 4); + return (Mem != NULL); +} + +CVm::~CVm() +{ + ::MyFree(Mem); +} + +// CVm::Execute can change CProgram object: it clears progarm if VM returns error. + +bool CVm::Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData) +{ + memcpy(R, initState->InitR, sizeof(initState->InitR)); + R[kStackRegIndex] = kSpaceSize; + R[kNumRegs] = 0; + Flags = 0; + + const UInt32 globalSize = MyMin((UInt32)initState->GlobalData.Size(), kGlobalSize); + if (globalSize != 0) + memcpy(Mem + kGlobalOffset, &initState->GlobalData[0], globalSize); + UInt32 staticSize = MyMin((UInt32)prg->StaticData.Size(), kGlobalSize - globalSize); + if (staticSize != 0) + memcpy(Mem + kGlobalOffset + globalSize, &prg->StaticData[0], staticSize); + + bool res = true; + + #ifdef Z7_RARVM_STANDARD_FILTERS + if (prg->StandardFilterIndex >= 0) + res = ExecuteStandardFilter((unsigned)prg->StandardFilterIndex); + else + #endif + { + #ifdef Z7_RARVM_VM_ENABLE + res = ExecuteCode(prg); + if (!res) + { + prg->Commands.Clear(); + prg->Commands.Add(CCommand()); + prg->Commands.Back().OpCode = CMD_RET; + } + #else + res = false; + #endif + } + + UInt32 newBlockPos = GetFixedGlobalValue32(NGlobalOffset::kBlockPos) & kSpaceMask; + UInt32 newBlockSize = GetFixedGlobalValue32(NGlobalOffset::kBlockSize) & kSpaceMask; + if (newBlockPos + newBlockSize >= kSpaceSize) + newBlockPos = newBlockSize = 0; + outBlockRef.Offset = newBlockPos; + outBlockRef.Size = newBlockSize; + + outGlobalData.Clear(); + UInt32 dataSize = GetFixedGlobalValue32(NGlobalOffset::kGlobalMemOutSize); + dataSize = MyMin(dataSize, kGlobalSize - kFixedGlobalSize); + if (dataSize != 0) + { + dataSize += kFixedGlobalSize; + outGlobalData.ClearAndSetSize(dataSize); + memcpy(&outGlobalData[0], Mem + kGlobalOffset, dataSize); + } + + return res; +} + +#ifdef Z7_RARVM_VM_ENABLE + +#define SET_IP(IP) \ + if ((IP) >= numCommands) return true; \ + if (--maxOpCount <= 0) return false; \ + cmd = commands + (IP); + +#define GET_FLAG_S_B(res) (((res) & 0x80) ? FLAG_S : 0) +#define SET_IP_OP1 { const UInt32 val = GetOperand32(&cmd->Op1); SET_IP(val) } +#define FLAGS_UPDATE_SZ Flags = res == 0 ? FLAG_Z : res & FLAG_S +#define FLAGS_UPDATE_SZ_B Flags = (res & 0xFF) == 0 ? FLAG_Z : GET_FLAG_S_B(res) + +UInt32 CVm::GetOperand32(const COperand *op) const +{ + switch (op->Type) + { + case OP_TYPE_REG: return R[op->Data]; + case OP_TYPE_REGMEM: return GetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask]); + default: return op->Data; + } +} + +void CVm::SetOperand32(const COperand *op, UInt32 val) +{ + switch (op->Type) + { + case OP_TYPE_REG: R[op->Data] = val; return; + case OP_TYPE_REGMEM: SetValue32(&Mem[(op->Base + R[op->Data]) & kSpaceMask], val); return; + default: break; + } +} + +Byte CVm::GetOperand8(const COperand *op) const +{ + switch (op->Type) + { + case OP_TYPE_REG: return (Byte)R[op->Data]; + case OP_TYPE_REGMEM: return Mem[(op->Base + R[op->Data]) & kSpaceMask]; + default: return (Byte)op->Data; + } +} + +void CVm::SetOperand8(const COperand *op, Byte val) +{ + switch (op->Type) + { + case OP_TYPE_REG: R[op->Data] = (R[op->Data] & 0xFFFFFF00) | val; return; + case OP_TYPE_REGMEM: Mem[(op->Base + R[op->Data]) & kSpaceMask] = val; return; + default: break; + } +} + +UInt32 CVm::GetOperand(bool byteMode, const COperand *op) const +{ + if (byteMode) + return GetOperand8(op); + return GetOperand32(op); +} + +void CVm::SetOperand(bool byteMode, const COperand *op, UInt32 val) +{ + if (byteMode) + SetOperand8(op, (Byte)(val & 0xFF)); + else + SetOperand32(op, val); +} + +bool CVm::ExecuteCode(const CProgram *prg) +{ + Int32 maxOpCount = 25000000; + const CCommand *commands = &prg->Commands[0]; + const CCommand *cmd = commands; + const UInt32 numCommands = prg->Commands.Size(); + if (numCommands == 0) + return false; + + for (;;) + { + switch (cmd->OpCode) + { + case CMD_MOV: + SetOperand32(&cmd->Op1, GetOperand32(&cmd->Op2)); + break; + case CMD_MOVB: + SetOperand8(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_CMP: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const UInt32 res = v1 - GetOperand32(&cmd->Op2); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_CMPB: + { + const Byte v1 = GetOperand8(&cmd->Op1); + const Byte res = (Byte)((v1 - GetOperand8(&cmd->Op2)) & 0xFF); + Flags = res == 0 ? FLAG_Z : (res > v1) | GET_FLAG_S_B(res); + } + break; + case CMD_ADD: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const UInt32 res = v1 + GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_ADDB: + { + const Byte v1 = GetOperand8(&cmd->Op1); + const Byte res = (Byte)((v1 + GetOperand8(&cmd->Op2)) & 0xFF); + SetOperand8(&cmd->Op1, (Byte)res); + Flags = (res < v1) | (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)); + } + break; + case CMD_ADC: + { + const UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + const UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 + GetOperand(cmd->ByteMode, &cmd->Op2) + FC; + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res < v1 || (res == v1 && FC)) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_SUB: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const UInt32 res = v1 - GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SUBB: + { + const UInt32 v1 = GetOperand8(&cmd->Op1); + const UInt32 res = v1 - GetOperand8(&cmd->Op2); + SetOperand8(&cmd->Op1, (Byte)res); + Flags = res == 0 ? FLAG_Z : (res > v1) | (res & FLAG_S); + } + break; + case CMD_SBB: + { + const UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + const UInt32 FC = (Flags & FLAG_C); + UInt32 res = v1 - GetOperand(cmd->ByteMode, &cmd->Op2) - FC; + // Flags = res == 0 ? FLAG_Z : (res > v1 || res == v1 && FC) | (res & FLAG_S); + if (cmd->ByteMode) + res &= 0xFF; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + Flags = (res > v1 || (res == v1 && FC)) | (res == 0 ? FLAG_Z : (res & FLAG_S)); + } + break; + case CMD_INC: + { + const UInt32 res = GetOperand32(&cmd->Op1) + 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_INCB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) + 1); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_DEC: + { + const UInt32 res = GetOperand32(&cmd->Op1) - 1; + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_DECB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) - 1); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_XOR: + { + const UInt32 res = GetOperand32(&cmd->Op1) ^ GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_XORB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) ^ GetOperand8(&cmd->Op2)); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_AND: + { + const UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ANDB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_OR: + { + const UInt32 res = GetOperand32(&cmd->Op1) | GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + FLAGS_UPDATE_SZ; + } + break; + case CMD_ORB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) | GetOperand8(&cmd->Op2)); + SetOperand8(&cmd->Op1, res); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_TEST: + { + const UInt32 res = GetOperand32(&cmd->Op1) & GetOperand32(&cmd->Op2); + FLAGS_UPDATE_SZ; + } + break; + case CMD_TESTB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) & GetOperand8(&cmd->Op2)); + FLAGS_UPDATE_SZ_B; + } + break; + case CMD_NOT: + SetOperand(cmd->ByteMode, &cmd->Op1, ~GetOperand(cmd->ByteMode, &cmd->Op1)); + break; + case CMD_NEG: + { + const UInt32 res = 0 - GetOperand32(&cmd->Op1); + SetOperand32(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | (res & FLAG_S); + } + break; + case CMD_NEGB: + { + const Byte res = (Byte)(0 - GetOperand8(&cmd->Op1)); + SetOperand8(&cmd->Op1, res); + Flags = res == 0 ? FLAG_Z : FLAG_C | GET_FLAG_S_B(res); + } + break; + + case CMD_SHL: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const int v2 = (int)GetOperand32(&cmd->Op2); + const UInt32 res = v1 << v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 << (v2 - 1)) & 0x80000000 ? FLAG_C : 0); + } + break; + case CMD_SHLB: + { + const Byte v1 = GetOperand8(&cmd->Op1); + const int v2 = (int)GetOperand8(&cmd->Op2); + const Byte res = (Byte)(v1 << v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 << (v2 - 1)) & 0x80 ? FLAG_C : 0); + } + break; + case CMD_SHR: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const int v2 = (int)GetOperand32(&cmd->Op2); + const UInt32 res = v1 >> v2; + SetOperand32(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SHRB: + { + const Byte v1 = GetOperand8(&cmd->Op1); + const int v2 = (int)GetOperand8(&cmd->Op2); + const Byte res = (Byte)(v1 >> v2); + SetOperand8(&cmd->Op1, res); + Flags = (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SAR: + { + const UInt32 v1 = GetOperand32(&cmd->Op1); + const int v2 = (int)GetOperand32(&cmd->Op2); + const UInt32 res = UInt32(((Int32)v1) >> v2); + SetOperand32(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : (res & FLAG_S)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + case CMD_SARB: + { + const Byte v1 = GetOperand8(&cmd->Op1); + const int v2 = (int)GetOperand8(&cmd->Op2); + const Byte res = (Byte)(((signed char)v1) >> v2); + SetOperand8(&cmd->Op1, res); + Flags= (res == 0 ? FLAG_Z : GET_FLAG_S_B(res)) | ((v1 >> (v2 - 1)) & FLAG_C); + } + break; + + case CMD_JMP: + SET_IP_OP1 + continue; + case CMD_JZ: + if ((Flags & FLAG_Z) != 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JNZ: + if ((Flags & FLAG_Z) == 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JS: + if ((Flags & FLAG_S) != 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JNS: + if ((Flags & FLAG_S) == 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JB: + if ((Flags & FLAG_C) != 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JBE: + if ((Flags & (FLAG_C | FLAG_Z)) != 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JA: + if ((Flags & (FLAG_C | FLAG_Z)) == 0) + { + SET_IP_OP1 + continue; + } + break; + case CMD_JAE: + if ((Flags & FLAG_C) == 0) + { + SET_IP_OP1 + continue; + } + break; + + case CMD_PUSH: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], GetOperand32(&cmd->Op1)); + break; + case CMD_POP: + SetOperand32(&cmd->Op1, GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask])); + R[kStackRegIndex] += 4; + break; + case CMD_CALL: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex] & kSpaceMask], (UInt32)(cmd - commands + 1)); + SET_IP_OP1 + continue; + + case CMD_PUSHA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex] - 4; i < kNumRegs; i++, SP -= 4) + SetValue32(&Mem[SP & kSpaceMask], R[i]); + R[kStackRegIndex] -= kNumRegs * 4; + } + break; + case CMD_POPA: + { + for (UInt32 i = 0, SP = R[kStackRegIndex]; i < kNumRegs; i++, SP += 4) + R[kStackRegIndex - i] = GetValue32(&Mem[SP & kSpaceMask]); + } + break; + case CMD_PUSHF: + R[kStackRegIndex] -= 4; + SetValue32(&Mem[R[kStackRegIndex]&kSpaceMask], Flags); + break; + case CMD_POPF: + Flags = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + R[kStackRegIndex] += 4; + break; + + case CMD_MOVZX: + SetOperand32(&cmd->Op1, GetOperand8(&cmd->Op2)); + break; + case CMD_MOVSX: + SetOperand32(&cmd->Op1, (UInt32)(Int32)(signed char)GetOperand8(&cmd->Op2)); + break; + case CMD_XCHG: + { + const UInt32 v1 = GetOperand(cmd->ByteMode, &cmd->Op1); + SetOperand(cmd->ByteMode, &cmd->Op1, GetOperand(cmd->ByteMode, &cmd->Op2)); + SetOperand(cmd->ByteMode, &cmd->Op2, v1); + } + break; + case CMD_MUL: + { + const UInt32 res = GetOperand32(&cmd->Op1) * GetOperand32(&cmd->Op2); + SetOperand32(&cmd->Op1, res); + } + break; + case CMD_MULB: + { + const Byte res = (Byte)(GetOperand8(&cmd->Op1) * GetOperand8(&cmd->Op2)); + SetOperand8(&cmd->Op1, res); + } + break; + case CMD_DIV: + { + const UInt32 divider = GetOperand(cmd->ByteMode, &cmd->Op2); + if (divider != 0) + { + const UInt32 res = GetOperand(cmd->ByteMode, &cmd->Op1) / divider; + SetOperand(cmd->ByteMode, &cmd->Op1, res); + } + } + break; + + case CMD_RET: + { + if (R[kStackRegIndex] >= kSpaceSize) + return true; + const UInt32 ip = GetValue32(&Mem[R[kStackRegIndex] & kSpaceMask]); + SET_IP(ip) + R[kStackRegIndex] += 4; + continue; + } + case CMD_PRINT: + break; + } + cmd++; + --maxOpCount; + } +} + +////////////////////////////////////////////////////// +// Read program + +static void DecodeArg(CMemBitDecoder &inp, COperand &op, bool byteMode) +{ + if (inp.ReadBit()) + { + op.Type = OP_TYPE_REG; + op.Data = inp.ReadBits(kNumRegBits); + } + else if (inp.ReadBit() == 0) + { + op.Type = OP_TYPE_INT; + if (byteMode) + op.Data = inp.ReadBits(8); + else + op.Data = inp.ReadEncodedUInt32(); + } + else + { + op.Type = OP_TYPE_REGMEM; + if (inp.ReadBit() == 0) + { + op.Data = inp.ReadBits(kNumRegBits); + op.Base = 0; + } + else + { + if (inp.ReadBit() == 0) + op.Data = inp.ReadBits(kNumRegBits); + else + op.Data = kNumRegs; + op.Base = inp.ReadEncodedUInt32(); + } + } +} + +void CProgram::ReadProgram(const Byte *code, UInt32 codeSize) +{ + CMemBitDecoder inp; + inp.Init(code, codeSize); + + StaticData.Clear(); + + if (inp.ReadBit()) + { + const UInt32 dataSize = inp.ReadEncodedUInt32() + 1; + for (UInt32 i = 0; inp.Avail() && i < dataSize; i++) + StaticData.Add((Byte)inp.ReadBits(8)); + } + + while (inp.Avail()) + { + Commands.Add(CCommand()); + CCommand *cmd = &Commands.Back(); + + unsigned opCode; + if (inp.ReadBit() == 0) + opCode = inp.ReadBits(3); + else + opCode = 8 + inp.ReadBits(5); + cmd->OpCode = (ECommand)opCode; + const unsigned cmdFlags = kCmdFlags[opCode]; + if (cmdFlags & CF_BYTEMODE) + cmd->ByteMode = (inp.ReadBit()) ? true : false; + else + cmd->ByteMode = 0; + + const unsigned opNum = (cmdFlags & CF_OPMASK); + + if (opNum) + { + DecodeArg(inp, cmd->Op1, cmd->ByteMode); + if (opNum == 2) + DecodeArg(inp, cmd->Op2, cmd->ByteMode); + else + { + if (cmd->Op1.Type == OP_TYPE_INT && (cmdFlags & (CF_JUMP | CF_PROC))) + { + Int32 dist = (Int32)cmd->Op1.Data; + if (dist >= 256) + dist -= 256; + else + { + if (dist >= 136) + dist -= 264; + else if (dist >= 16) + dist -= 8; + else if (dist >= 8) + dist -= 16; + dist += Commands.Size() - 1; + } + cmd->Op1.Data = (UInt32)dist; + } + } + } + + if (cmd->ByteMode) + { + switch (cmd->OpCode) + { + case CMD_MOV: cmd->OpCode = CMD_MOVB; break; + case CMD_CMP: cmd->OpCode = CMD_CMPB; break; + case CMD_ADD: cmd->OpCode = CMD_ADDB; break; + case CMD_SUB: cmd->OpCode = CMD_SUBB; break; + case CMD_INC: cmd->OpCode = CMD_INCB; break; + case CMD_DEC: cmd->OpCode = CMD_DECB; break; + case CMD_XOR: cmd->OpCode = CMD_XORB; break; + case CMD_AND: cmd->OpCode = CMD_ANDB; break; + case CMD_OR: cmd->OpCode = CMD_ORB; break; + case CMD_TEST: cmd->OpCode = CMD_TESTB; break; + case CMD_NEG: cmd->OpCode = CMD_NEGB; break; + case CMD_SHL: cmd->OpCode = CMD_SHLB; break; + case CMD_SHR: cmd->OpCode = CMD_SHRB; break; + case CMD_SAR: cmd->OpCode = CMD_SARB; break; + case CMD_MUL: cmd->OpCode = CMD_MULB; break; + default: break; + } + } + } +} + +#endif + + +#ifdef Z7_RARVM_STANDARD_FILTERS + +enum EStandardFilter +{ + SF_E8, + SF_E8E9, + SF_ITANIUM, + SF_RGB, + SF_AUDIO, + SF_DELTA + // SF_UPCASE +}; + +static const struct CStandardFilterSignature +{ + UInt32 Length; + UInt32 CRC; + EStandardFilter Type; +} +kStdFilters[]= +{ + { 53, 0xad576887, SF_E8 }, + { 57, 0x3cd7e57e, SF_E8E9 }, + { 120, 0x3769893f, SF_ITANIUM }, + { 29, 0x0e06077d, SF_DELTA }, + { 149, 0x1c2c5dc8, SF_RGB }, + { 216, 0xbc85e701, SF_AUDIO } + // { 40, 0x46b9c560, SF_UPCASE } +}; + +static int FindStandardFilter(const Byte *code, UInt32 codeSize) +{ + // return -1; // for debug VM execution + const UInt32 crc = CrcCalc(code, codeSize); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kStdFilters); i++) + { + const CStandardFilterSignature &sfs = kStdFilters[i]; + if (sfs.CRC == crc && sfs.Length == codeSize) + return (int)i; + } + return -1; +} + +#endif + + +bool CProgram::PrepareProgram(const Byte *code, UInt32 codeSize) +{ + IsSupported = false; + + #ifdef Z7_RARVM_VM_ENABLE + Commands.Clear(); + #endif + + #ifdef Z7_RARVM_STANDARD_FILTERS + StandardFilterIndex = -1; + #endif + + bool isOK = false; + + Byte xorSum = 0; + for (UInt32 i = 0; i < codeSize; i++) + xorSum ^= code[i]; + + if (xorSum == 0 && codeSize != 0) + { + IsSupported = true; + isOK = true; + #ifdef Z7_RARVM_STANDARD_FILTERS + StandardFilterIndex = FindStandardFilter(code, codeSize); + if (StandardFilterIndex >= 0) + return true; + #endif + + #ifdef Z7_RARVM_VM_ENABLE + ReadProgram(code + 1, codeSize - 1); + #else + IsSupported = false; + #endif + } + + #ifdef Z7_RARVM_VM_ENABLE + Commands.Add(CCommand()); + Commands.Back().OpCode = CMD_RET; + #endif + + return isOK; +} + +void CVm::SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize) +{ + if (pos < kSpaceSize && data != Mem + pos) + memmove(Mem + pos, data, MyMin(dataSize, kSpaceSize - pos)); +} + +#ifdef Z7_RARVM_STANDARD_FILTERS + +static void E8E9Decode(Byte *data, UInt32 dataSize, UInt32 fileOffset, bool e9) +{ + if (dataSize <= 4) + return; + dataSize -= 4; + const UInt32 kFileSize = 0x1000000; + const Byte cmpMask = (Byte)(e9 ? 0xFE : 0xFF); + for (UInt32 curPos = 0; curPos < dataSize;) + { + curPos++; + if (((*data++) & cmpMask) == 0xE8) + { + UInt32 offset = curPos + fileOffset; + UInt32 addr = GetValue32(data); + if (addr < kFileSize) + SetValue32(data, addr - offset); + else if ((addr & 0x80000000) != 0 && ((addr + offset) & 0x80000000) == 0) + SetValue32(data, addr + kFileSize); + data += 4; + curPos += 4; + } + } +} + + +static void ItaniumDecode(Byte *data, UInt32 dataSize, UInt32 fileOffset) +{ + if (dataSize <= 21) + return; + fileOffset >>= 4; + dataSize -= 21; + dataSize += 15; + dataSize >>= 4; + dataSize += fileOffset; + do + { + unsigned m = ((UInt32)0x334B0000 >> (data[0] & 0x1E)) & 3; + if (m) + { + m++; + do + { + Byte *p = data + ((size_t)m * 5 - 8); + if (((p[3] >> m) & 15) == 5) + { + const UInt32 kMask = 0xFFFFF; + // UInt32 raw = ((UInt32)p[0]) | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16); + UInt32 raw = GetUi32(p); + UInt32 v = raw >> m; + v -= fileOffset; + v &= kMask; + raw &= ~(kMask << m); + raw |= (v << m); + // p[0] = (Byte)raw; p[1] = (Byte)(raw >> 8); p[2] = (Byte)(raw >> 16); + SetUi32(p, raw) + } + } + while (++m <= 4); + } + data += 16; + } + while (++fileOffset != dataSize); +} + + +static void DeltaDecode(Byte *data, UInt32 dataSize, UInt32 numChannels) +{ + UInt32 srcPos = 0; + const UInt32 border = dataSize * 2; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + Byte prevByte = 0; + for (UInt32 destPos = dataSize + curChannel; destPos < border; destPos += numChannels) + data[destPos] = (prevByte = (Byte)(prevByte - data[srcPos++])); + } +} + +static void RgbDecode(Byte *srcData, UInt32 dataSize, UInt32 width, UInt32 posR) +{ + Byte *destData = srcData + dataSize; + const UInt32 kNumChannels = 3; + + for (UInt32 curChannel = 0; curChannel < kNumChannels; curChannel++) + { + Byte prevByte = 0; + + for (UInt32 i = curChannel; i < dataSize; i += kNumChannels) + { + unsigned predicted; + if (i < width) + predicted = prevByte; + else + { + const unsigned upperLeftByte = destData[i - width]; + const unsigned upperByte = destData[i - width + 3]; + predicted = prevByte + upperByte - upperLeftByte; + const int pa = abs((int)(predicted - prevByte)); + const int pb = abs((int)(predicted - upperByte)); + const int pc = abs((int)(predicted - upperLeftByte)); + if (pa <= pb && pa <= pc) + predicted = prevByte; + else + if (pb <= pc) + predicted = upperByte; + else + predicted = upperLeftByte; + } + destData[i] = prevByte = (Byte)(predicted - *(srcData++)); + } + } + if (dataSize < 3) + return; + const UInt32 border = dataSize - 2; + for (UInt32 i = posR; i < border; i += 3) + { + const Byte g = destData[i + 1]; + destData[i ] = (Byte)(destData[i ] + g); + destData[i + 2] = (Byte)(destData[i + 2] + g); + } +} + +#define my_abs(x) (unsigned)abs(x) + +static void AudioDecode(Byte *srcData, UInt32 dataSize, UInt32 numChannels) +{ + Byte *destData = srcData + dataSize; + for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) + { + UInt32 prevByte = 0, prevDelta = 0, dif[7]; + Int32 D1 = 0, D2 = 0, D3; + Int32 K1 = 0, K2 = 0, K3 = 0; + memset(dif, 0, sizeof(dif)); + + for (UInt32 i = curChannel, byteCount = 0; i < dataSize; i += numChannels, byteCount++) + { + D3 = D2; + D2 = (Int32)prevDelta - D1; + D1 = (Int32)prevDelta; + + UInt32 predicted = (UInt32)((Int32)(8 * prevByte) + K1 * D1 + K2 * D2 + K3 * D3); + predicted = (predicted >> 3) & 0xFF; + + const UInt32 curByte = *(srcData++); + + predicted -= curByte; + destData[i] = (Byte)predicted; + prevDelta = (UInt32)(Int32)(signed char)(predicted - prevByte); + prevByte = predicted; + + const Int32 D = ((Int32)(signed char)curByte) << 3; + + dif[0] += my_abs(D); + dif[1] += my_abs(D - D1); + dif[2] += my_abs(D + D1); + dif[3] += my_abs(D - D2); + dif[4] += my_abs(D + D2); + dif[5] += my_abs(D - D3); + dif[6] += my_abs(D + D3); + + if ((byteCount & 0x1F) == 0) + { + UInt32 minDif = dif[0], numMinDif = 0; + dif[0] = 0; + for (unsigned j = 1; j < Z7_ARRAY_SIZE(dif); j++) + { + if (dif[j] < minDif) + { + minDif = dif[j]; + numMinDif = j; + } + dif[j] = 0; + } + switch (numMinDif) + { + case 1: if (K1 >= -16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2 >= -16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3 >= -16) K3--; break; + case 6: if (K3 < 16) K3++; break; + } + } + } + } +} + +/* +static UInt32 UpCaseDecode(Byte *data, UInt32 dataSize) +{ + UInt32 srcPos = 0, destPos = dataSize; + while (srcPos < dataSize) + { + Byte curByte = data[srcPos++]; + if (curByte == 2 && (curByte = data[srcPos++]) != 2) + curByte -= 32; + data[destPos++] = curByte; + } + return destPos - dataSize; +} +*/ + +bool CVm::ExecuteStandardFilter(unsigned filterIndex) +{ + const UInt32 dataSize = R[4]; + if (dataSize >= kGlobalOffset) + return false; + EStandardFilter filterType = kStdFilters[filterIndex].Type; + + switch (filterType) + { + case SF_E8: + case SF_E8E9: + E8E9Decode(Mem, dataSize, R[6], (filterType == SF_E8E9)); + break; + + case SF_ITANIUM: + ItaniumDecode(Mem, dataSize, R[6]); + break; + + case SF_DELTA: + { + if (dataSize >= kGlobalOffset / 2) + return false; + const UInt32 numChannels = R[0]; + if (numChannels == 0 || numChannels > 1024) // unrar 5.5.5 + return false; + SetBlockPos(dataSize); + DeltaDecode(Mem, dataSize, numChannels); + break; + } + + case SF_RGB: + { + if (dataSize >= kGlobalOffset / 2 || dataSize < 3) // unrar 5.5.5 + return false; + const UInt32 width = R[0]; + const UInt32 posR = R[1]; + if (width < 3 || width - 3 > dataSize || posR > 2) // unrar 5.5.5 + return false; + SetBlockPos(dataSize); + RgbDecode(Mem, dataSize, width, posR); + break; + } + + case SF_AUDIO: + { + if (dataSize >= kGlobalOffset / 2) + return false; + const UInt32 numChannels = R[0]; + if (numChannels == 0 || numChannels > 128) // unrar 5.5.5 + return false; + SetBlockPos(dataSize); + AudioDecode(Mem, dataSize, numChannels); + break; + } + + /* + case SF_UPCASE: + if (dataSize >= kGlobalOffset / 2) + return false; + UInt32 destSize = UpCaseDecode(Mem, dataSize); + SetBlockSize(destSize); + SetBlockPos(dataSize); + break; + */ + } + return true; +} + +#endif + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar3Vm.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.h --- p7zip-rar-16.02/CPP/7zip/Compress/Rar3Vm.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar3Vm.h 2023-03-28 18:00:00.000000000 +0000 @@ -1,195 +1,195 @@ -// Rar3Vm.h -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#ifndef __COMPRESS_RAR3_VM_H -#define __COMPRESS_RAR3_VM_H - -#include "../../../C/CpuArch.h" - -#include "../../Common/MyVector.h" - -#define RARVM_STANDARD_FILTERS -// #define RARVM_VM_ENABLE - -namespace NCompress { -namespace NRar3 { - -class CMemBitDecoder -{ - const Byte *_data; - UInt32 _bitSize; - UInt32 _bitPos; -public: - void Init(const Byte *data, UInt32 byteSize) - { - _data = data; - _bitSize = (byteSize << 3); - _bitPos = 0; - } - UInt32 ReadBits(unsigned numBits); - UInt32 ReadBit(); - bool Avail() const { return (_bitPos < _bitSize); } - - UInt32 ReadEncodedUInt32(); -}; - -namespace NVm { - -inline UInt32 GetValue32(const void *addr) { return GetUi32(addr); } -inline void SetValue32(void *addr, UInt32 value) { SetUi32(addr, value); } - -const unsigned kNumRegBits = 3; -const UInt32 kNumRegs = 1 << kNumRegBits; -const UInt32 kNumGpRegs = kNumRegs - 1; - -const UInt32 kSpaceSize = 0x40000; -const UInt32 kSpaceMask = kSpaceSize - 1; -const UInt32 kGlobalOffset = 0x3C000; -const UInt32 kGlobalSize = 0x2000; -const UInt32 kFixedGlobalSize = 64; - -namespace NGlobalOffset -{ - const UInt32 kBlockSize = 0x1C; - const UInt32 kBlockPos = 0x20; - const UInt32 kExecCount = 0x2C; - const UInt32 kGlobalMemOutSize = 0x30; -} - - -#ifdef RARVM_VM_ENABLE - -enum ECommand -{ - CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC, - CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB, - CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT, - CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF, - CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT, - - CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB, - CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB, - CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB -}; - -enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE}; - -// Addr in COperand object can link (point) to CVm object!!! - -struct COperand -{ - EOpType Type; - UInt32 Data; - UInt32 Base; - COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {} -}; - -struct CCommand -{ - ECommand OpCode; - bool ByteMode; - COperand Op1, Op2; -}; - -#endif - - -struct CBlockRef -{ - UInt32 Offset; - UInt32 Size; -}; - - -class CProgram -{ - #ifdef RARVM_VM_ENABLE - void ReadProgram(const Byte *code, UInt32 codeSize); -public: - CRecordVector Commands; - #endif - -public: - #ifdef RARVM_STANDARD_FILTERS - int StandardFilterIndex; - #endif - - bool IsSupported; - CRecordVector StaticData; - - bool PrepareProgram(const Byte *code, UInt32 codeSize); -}; - - -struct CProgramInitState -{ - UInt32 InitR[kNumGpRegs]; - CRecordVector GlobalData; - - void AllocateEmptyFixedGlobal() - { - GlobalData.ClearAndSetSize(NVm::kFixedGlobalSize); - memset(&GlobalData[0], 0, NVm::kFixedGlobalSize); - } -}; - - -class CVm -{ - static UInt32 GetValue(bool byteMode, const void *addr) - { - if (byteMode) - return(*(const Byte *)addr); - else - return GetUi32(addr); - } - - static void SetValue(bool byteMode, void *addr, UInt32 value) - { - if (byteMode) - *(Byte *)addr = (Byte)value; - else - SetUi32(addr, value); - } - - UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); } - - void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); } - void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); } -public: - static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); } - -private: - - #ifdef RARVM_VM_ENABLE - UInt32 GetOperand32(const COperand *op) const; - void SetOperand32(const COperand *op, UInt32 val); - Byte GetOperand8(const COperand *op) const; - void SetOperand8(const COperand *op, Byte val); - UInt32 GetOperand(bool byteMode, const COperand *op) const; - void SetOperand(bool byteMode, const COperand *op, UInt32 val); - bool ExecuteCode(const CProgram *prg); - #endif - - #ifdef RARVM_STANDARD_FILTERS - void ExecuteStandardFilter(unsigned filterIndex); - #endif - - Byte *Mem; - UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization) - UInt32 Flags; - -public: - CVm(); - ~CVm(); - bool Create(); - void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize); - bool Execute(CProgram *prg, const CProgramInitState *initState, - CBlockRef &outBlockRef, CRecordVector &outGlobalData); - const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; } -}; - -#endif - -}}} +// Rar3Vm.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef ZIP7_INC_COMPRESS_RAR3_VM_H +#define ZIP7_INC_COMPRESS_RAR3_VM_H + +#include "../../../C/CpuArch.h" + +#include "../../Common/MyVector.h" + +#define Z7_RARVM_STANDARD_FILTERS +// #define Z7_RARVM_VM_ENABLE + +namespace NCompress { +namespace NRar3 { + +class CMemBitDecoder +{ + const Byte *_data; + UInt32 _bitSize; + UInt32 _bitPos; +public: + void Init(const Byte *data, UInt32 byteSize) + { + _data = data; + _bitSize = (byteSize << 3); + _bitPos = 0; + } + UInt32 ReadBits(unsigned numBits); + UInt32 ReadBit(); + bool Avail() const { return (_bitPos < _bitSize); } + + UInt32 ReadEncodedUInt32(); +}; + +namespace NVm { + +inline UInt32 GetValue32(const void *addr) { return GetUi32(addr); } +inline void SetValue32(void *addr, UInt32 value) { SetUi32(addr, value) } + +const unsigned kNumRegBits = 3; +const UInt32 kNumRegs = 1 << kNumRegBits; +const UInt32 kNumGpRegs = kNumRegs - 1; + +const UInt32 kSpaceSize = 0x40000; +const UInt32 kSpaceMask = kSpaceSize - 1; +const UInt32 kGlobalOffset = 0x3C000; +const UInt32 kGlobalSize = 0x2000; +const UInt32 kFixedGlobalSize = 64; + +namespace NGlobalOffset +{ + const UInt32 kBlockSize = 0x1C; + const UInt32 kBlockPos = 0x20; + const UInt32 kExecCount = 0x2C; + const UInt32 kGlobalMemOutSize = 0x30; +} + + +#ifdef Z7_RARVM_VM_ENABLE + +enum ECommand +{ + CMD_MOV, CMD_CMP, CMD_ADD, CMD_SUB, CMD_JZ, CMD_JNZ, CMD_INC, CMD_DEC, + CMD_JMP, CMD_XOR, CMD_AND, CMD_OR, CMD_TEST, CMD_JS, CMD_JNS, CMD_JB, + CMD_JBE, CMD_JA, CMD_JAE, CMD_PUSH, CMD_POP, CMD_CALL, CMD_RET, CMD_NOT, + CMD_SHL, CMD_SHR, CMD_SAR, CMD_NEG, CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF, + CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL, CMD_DIV, CMD_ADC, CMD_SBB, CMD_PRINT, + + CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB, + CMD_XORB, CMD_ANDB, CMD_ORB, CMD_TESTB,CMD_NEGB, + CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB +}; + +enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE}; + +// Addr in COperand object can link (point) to CVm object!!! + +struct COperand +{ + EOpType Type; + UInt32 Data; + UInt32 Base; + COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {} +}; + +struct CCommand +{ + ECommand OpCode; + bool ByteMode; + COperand Op1, Op2; +}; + +#endif + + +struct CBlockRef +{ + UInt32 Offset; + UInt32 Size; +}; + + +class CProgram +{ + #ifdef Z7_RARVM_VM_ENABLE + void ReadProgram(const Byte *code, UInt32 codeSize); +public: + CRecordVector Commands; + #endif + +public: + #ifdef Z7_RARVM_STANDARD_FILTERS + int StandardFilterIndex; + #endif + + bool IsSupported; + CRecordVector StaticData; + + bool PrepareProgram(const Byte *code, UInt32 codeSize); +}; + + +struct CProgramInitState +{ + UInt32 InitR[kNumGpRegs]; + CRecordVector GlobalData; + + void AllocateEmptyFixedGlobal() + { + GlobalData.ClearAndSetSize(NVm::kFixedGlobalSize); + memset(&GlobalData[0], 0, NVm::kFixedGlobalSize); + } +}; + + +class CVm +{ + static UInt32 GetValue(bool byteMode, const void *addr) + { + if (byteMode) + return(*(const Byte *)addr); + else + return GetUi32(addr); + } + + static void SetValue(bool byteMode, void *addr, UInt32 value) + { + if (byteMode) + *(Byte *)addr = (Byte)value; + else + SetUi32(addr, value) + } + + UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); } + + void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); } + void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); } +public: + static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); } + +private: + + #ifdef Z7_RARVM_VM_ENABLE + UInt32 GetOperand32(const COperand *op) const; + void SetOperand32(const COperand *op, UInt32 val); + Byte GetOperand8(const COperand *op) const; + void SetOperand8(const COperand *op, Byte val); + UInt32 GetOperand(bool byteMode, const COperand *op) const; + void SetOperand(bool byteMode, const COperand *op, UInt32 val); + bool ExecuteCode(const CProgram *prg); + #endif + + #ifdef Z7_RARVM_STANDARD_FILTERS + bool ExecuteStandardFilter(unsigned filterIndex); + #endif + + Byte *Mem; + UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization) + UInt32 Flags; + +public: + CVm(); + ~CVm(); + bool Create(); + void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize); + bool Execute(CProgram *prg, const CProgramInitState *initState, + CBlockRef &outBlockRef, CRecordVector &outGlobalData); + const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; } +}; + +#endif + +}}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar5Decoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/Rar5Decoder.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.cpp 2025-06-20 11:00:00.000000000 +0000 @@ -1,961 +1,2060 @@ -// Rar5Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#include "StdAfx.h" - -// #include - -#include "../Common/StreamUtils.h" - -#include "Rar5Decoder.h" - -namespace NCompress { -namespace NRar5 { - -static const size_t kInputBufSize = 1 << 20; - -void CBitDecoder::Prepare2() throw() -{ - const unsigned kSize = 16; - if (_buf > _bufLim) - return; - - size_t rem = _bufLim - _buf; - if (rem != 0) - memmove(_bufBase, _buf, rem); - - _bufLim = _bufBase + rem; - _processedSize += (_buf - _bufBase); - _buf = _bufBase; - - if (!_wasFinished) - { - UInt32 processed = (UInt32)(kInputBufSize - rem); - _hres = _stream->Read(_bufLim, (UInt32)processed, &processed); - _bufLim += processed; - _wasFinished = (processed == 0); - if (_hres != S_OK) - { - _wasFinished = true; - // throw CInBufferException(result); - } - } - - rem = _bufLim - _buf; - _bufCheck = _buf; - if (rem < kSize) - memset(_bufLim, 0xFF, kSize - rem); - else - _bufCheck = _bufLim - kSize; - - SetCheck2(); -} - - -enum FilterType -{ - FILTER_DELTA = 0, - FILTER_E8, - FILTER_E8E9, - FILTER_ARM -}; - -static const size_t kWriteStep = (size_t)1 << 22; - -CDecoder::CDecoder(): - _window(NULL), - _winPos(0), - _winSizeAllocated(0), - _lzSize(0), - _lzEnd(0), - _writtenFileSize(0), - _dictSizeLog(0), - _isSolid(false), - _wasInit(false), - _inputBuf(NULL) -{ -} - -CDecoder::~CDecoder() -{ - ::MidFree(_window); - ::MidFree(_inputBuf); -} - -HRESULT CDecoder::WriteData(const Byte *data, size_t size) -{ - HRESULT res = S_OK; - if (!_unpackSize_Defined || _writtenFileSize < _unpackSize) - { - size_t cur = size; - if (_unpackSize_Defined) - { - UInt64 rem = _unpackSize - _writtenFileSize; - if (cur > rem) - cur = (size_t)rem; - } - res = WriteStream(_outStream, data, cur); - if (res != S_OK) - _writeError = true; - } - _writtenFileSize += size; - return res; -} - -HRESULT CDecoder::ExecuteFilter(const CFilter &f) -{ - bool useDest = false; - - Byte *data = _filterSrc; - UInt32 dataSize = f.Size; - - // printf("\nType = %d offset = %9d size = %5d", f.Type, (unsigned)(f.Start - _lzFileStart), dataSize); - - switch (f.Type) - { - case FILTER_E8: - case FILTER_E8E9: - { - // printf(" FILTER_E8"); - if (dataSize > 4) - { - dataSize -= 4; - UInt32 fileOffset = (UInt32)(f.Start - _lzFileStart); - - const UInt32 kFileSize = (UInt32)1 << 24; - Byte cmpMask = (Byte)(f.Type == FILTER_E8 ? 0xFF : 0xFE); - - for (UInt32 curPos = 0; curPos < dataSize;) - { - curPos++; - if (((*data++) & cmpMask) == 0xE8) - { - UInt32 offset = (curPos + fileOffset) & (kFileSize - 1); - UInt32 addr = GetUi32(data); - - if (addr < kFileSize) - { - SetUi32(data, addr - offset); - } - else if (addr > ((UInt32)0xFFFFFFFF - offset)) // (addr > ~(offset)) - { - SetUi32(data, addr + kFileSize); - } - - data += 4; - curPos += 4; - } - } - } - break; - } - - case FILTER_ARM: - { - if (dataSize >= 4) - { - dataSize -= 4; - UInt32 fileOffset = (UInt32)(f.Start - _lzFileStart); - - for (UInt32 curPos = 0; curPos <= dataSize; curPos += 4) - { - Byte *d = data + curPos; - if (d[3] == 0xEB) - { - UInt32 offset = d[0] | ((UInt32)d[1] << 8) | ((UInt32)d[2] << 16); - offset -= (fileOffset + curPos) >> 2; - d[0] = (Byte)offset; - d[1] = (Byte)(offset >> 8); - d[2] = (Byte)(offset >> 16); - } - } - } - break; - } - - case FILTER_DELTA: - { - // printf(" channels = %d", f.Channels); - _filterDst.AllocAtLeast(dataSize); - if (!_filterDst.IsAllocated()) - return E_OUTOFMEMORY; - - Byte *dest = _filterDst; - UInt32 numChannels = f.Channels; - - for (UInt32 curChannel = 0; curChannel < numChannels; curChannel++) - { - Byte prevByte = 0; - for (UInt32 destPos = curChannel; destPos < dataSize; destPos += numChannels) - dest[destPos] = (prevByte = (Byte)(prevByte - *data++)); - } - useDest = true; - break; - } - - default: - _unsupportedFilter = true; - } - - return WriteData(useDest ? - (const Byte *)_filterDst : - (const Byte *)_filterSrc, - f.Size); -} - - -HRESULT CDecoder::WriteBuf() -{ - DeleteUnusedFilters(); - - for (unsigned i = 0; i < _filters.Size();) - { - const CFilter &f = _filters[i]; - - UInt64 blockStart = f.Start; - - size_t lzAvail = (size_t)(_lzSize - _lzWritten); - if (lzAvail == 0) - break; - - if (blockStart > _lzWritten) - { - UInt64 rem = blockStart - _lzWritten; - size_t size = lzAvail; - if (size > rem) - size = (size_t)rem; - if (size != 0) - { - RINOK(WriteData(_window + _winPos - lzAvail, size)); - _lzWritten += size; - } - continue; - } - - UInt32 blockSize = f.Size; - size_t offset = (size_t)(_lzWritten - blockStart); - if (offset == 0) - { - _filterSrc.AllocAtLeast(blockSize); - if (!_filterSrc.IsAllocated()) - return E_OUTOFMEMORY; - } - - size_t blockRem = (size_t)blockSize - offset; - size_t size = lzAvail; - if (size > blockRem) - size = blockRem; - memcpy(_filterSrc + offset, _window + _winPos - lzAvail, size); - _lzWritten += size; - offset += size; - if (offset != blockSize) - return S_OK; - - _numUnusedFilters = ++i; - RINOK(ExecuteFilter(f)); - } - - DeleteUnusedFilters(); - - if (!_filters.IsEmpty()) - return S_OK; - - size_t lzAvail = (size_t)(_lzSize - _lzWritten); - RINOK(WriteData(_window + _winPos - lzAvail, lzAvail)); - _lzWritten += lzAvail; - return S_OK; -} - - -static UInt32 ReadUInt32(CBitDecoder &bi) -{ - unsigned numBytes = bi.ReadBits9fix(2) + 1; - UInt32 v = 0; - for (unsigned i = 0; i < numBytes; i++) - v += ((UInt32)bi.ReadBits9fix(8) << (i * 8)); - return v; -} - - -static const unsigned MAX_UNPACK_FILTERS = 8192; - -HRESULT CDecoder::AddFilter(CBitDecoder &_bitStream) -{ - DeleteUnusedFilters(); - - if (_filters.Size() >= MAX_UNPACK_FILTERS) - { - RINOK(WriteBuf()); - DeleteUnusedFilters(); - if (_filters.Size() >= MAX_UNPACK_FILTERS) - { - _unsupportedFilter = true; - InitFilters(); - } - } - - _bitStream.Prepare(); - - CFilter f; - UInt32 blockStart = ReadUInt32(_bitStream); - f.Size = ReadUInt32(_bitStream); - - // if (f.Size > ((UInt32)1 << 16)) _unsupportedFilter = true; - - f.Type = (Byte)_bitStream.ReadBits9fix(3); - f.Channels = 0; - if (f.Type == FILTER_DELTA) - f.Channels = (Byte)(_bitStream.ReadBits9fix(5) + 1); - f.Start = _lzSize + blockStart; - - if (f.Start < _filterEnd) - _unsupportedFilter = true; - else - { - _filterEnd = f.Start + f.Size; - if (f.Size != 0) - _filters.Add(f); - } - - return S_OK; -} - - -#define RIF(x) { if (!(x)) return S_FALSE; } - -HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream) -{ - if (_progress) - { - UInt64 packSize = _bitStream.GetProcessedSize(); - RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize)); - } - - _bitStream.AlignToByte(); - _bitStream.Prepare(); - - unsigned flags = _bitStream.ReadByteInAligned(); - unsigned checkSum = _bitStream.ReadByteInAligned(); - checkSum ^= flags; - - UInt32 blockSize; - { - unsigned num = (flags >> 3) & 3; - if (num == 3) - return S_FALSE; - blockSize = _bitStream.ReadByteInAligned(); - if (num > 0) - { - blockSize += (UInt32)_bitStream.ReadByteInAligned() << 8; - if (num > 1) - blockSize += (UInt32)_bitStream.ReadByteInAligned() << 16; - } - } - - checkSum ^= blockSize ^ (blockSize >> 8) ^ (blockSize >> 16); - if ((Byte)checkSum != 0x5A) - return S_FALSE; - - unsigned blockSizeBits7 = (flags & 7) + 1; - - if (blockSize == 0 && blockSizeBits7 != 8) - return S_FALSE; - - blockSize += (blockSizeBits7 >> 3); - blockSize--; - - _bitStream._blockEndBits7 = (Byte)(blockSizeBits7 & 7); - _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize; - - _bitStream.SetCheck2(); - - _isLastBlock = ((flags & 0x40) != 0); - - if ((flags & 0x80) == 0) - { - if (!_tableWasFilled && blockSize != 0) - return S_FALSE; - return S_OK; - } - - _tableWasFilled = false; - - { - Byte lens2[kLevelTableSize]; - - for (unsigned i = 0; i < kLevelTableSize;) - { - _bitStream.Prepare(); - unsigned len = (unsigned)_bitStream.ReadBits9fix(4); - if (len == 15) - { - unsigned num = (unsigned)_bitStream.ReadBits9fix(4); - if (num != 0) - { - num += 2; - num += i; - if (num > kLevelTableSize) - num = kLevelTableSize; - do - lens2[i++] = 0; - while (i < num); - continue; - } - } - lens2[i++] = (Byte)len; - } - - if (_bitStream.IsBlockOverRead()) - return S_FALSE; - - RIF(m_LevelDecoder.Build(lens2)); - } - - Byte lens[kTablesSizesSum]; - unsigned i = 0; - - while (i < kTablesSizesSum) - { - if (_bitStream._buf >= _bitStream._bufCheck2) - { - if (_bitStream._buf >= _bitStream._bufCheck) - _bitStream.Prepare(); - if (_bitStream.IsBlockOverRead()) - return S_FALSE; - } - - UInt32 sym = m_LevelDecoder.Decode(&_bitStream); - - if (sym < 16) - lens[i++] = (Byte)sym; - else if (sym > kLevelTableSize) - return S_FALSE; - else - { - sym -= 16; - unsigned sh = ((sym & 1) << 2); - unsigned num = (unsigned)_bitStream.ReadBits9(3 + sh) + 3 + (sh << 1); - - num += i; - if (num > kTablesSizesSum) - num = kTablesSizesSum; - - if (sym < 2) - { - if (i == 0) - { - // return S_FALSE; - continue; // original unRAR - } - Byte v = lens[i - 1]; - do - lens[i++] = v; - while (i < num); - } - else - { - do - lens[i++] = 0; - while (i < num); - } - } - } - - if (_bitStream.IsBlockOverRead()) - return S_FALSE; - if (_bitStream.InputEofError()) - return S_FALSE; - - RIF(m_MainDecoder.Build(&lens[0])); - RIF(m_DistDecoder.Build(&lens[kMainTableSize])); - RIF(m_AlignDecoder.Build(&lens[kMainTableSize + kDistTableSize])); - RIF(m_LenDecoder.Build(&lens[kMainTableSize + kDistTableSize + kAlignTableSize])); - - _useAlignBits = false; - // _useAlignBits = true; - for (i = 0; i < kAlignTableSize; i++) - if (lens[kMainTableSize + kDistTableSize + i] != kNumAlignBits) - { - _useAlignBits = true; - break; - } - - _tableWasFilled = true; - return S_OK; -} - - -static inline unsigned SlotToLen(CBitDecoder &_bitStream, unsigned slot) -{ - if (slot < 8) - return slot + 2; - unsigned numBits = (slot >> 2) - 1; - return 2 + ((4 | (slot & 3)) << numBits) + _bitStream.ReadBits9(numBits); -} - - -static const UInt32 kSymbolRep = 258; -// static const unsigned kMaxMatchLen = 0x1001 + 3; - -HRESULT CDecoder::DecodeLZ() -{ - CBitDecoder _bitStream; - _bitStream._stream = _inStream; - _bitStream._bufBase = _inputBuf; - _bitStream.Init(); - - UInt32 rep0 = _reps[0]; - - UInt32 remLen = 0; - - size_t limit; - { - size_t rem = _winSize - _winPos; - if (rem > kWriteStep) - rem = kWriteStep; - limit = _winPos + rem; - } - - for (;;) - { - if (_winPos >= limit) - { - RINOK(WriteBuf()); - if (_unpackSize_Defined && _writtenFileSize > _unpackSize) - break; // return S_FALSE; - - { - size_t rem = _winSize - _winPos; - - if (rem == 0) - { - _winPos = 0; - rem = _winSize; - } - if (rem > kWriteStep) - rem = kWriteStep; - limit = _winPos + rem; - } - - if (remLen != 0) - { - size_t winPos = _winPos; - size_t winMask = _winMask; - size_t pos = (winPos - (size_t)rep0 - 1) & winMask; - - Byte *win = _window; - do - { - if (winPos >= limit) - break; - win[winPos] = win[pos]; - winPos++; - pos = (pos + 1) & winMask; - } - while (--remLen != 0); - - _lzSize += winPos - _winPos; - _winPos = winPos; - continue; - } - } - - if (_bitStream._buf >= _bitStream._bufCheck2) - { - if (_bitStream.InputEofError()) - break; // return S_FALSE; - if (_bitStream._buf >= _bitStream._bufCheck) - _bitStream.Prepare2(); - - UInt64 processed = _bitStream.GetProcessedSize_Round(); - if (processed >= _bitStream._blockEnd) - { - if (processed > _bitStream._blockEnd) - break; // return S_FALSE; - { - unsigned bits7 = _bitStream.GetProcessedBits7(); - if (bits7 > _bitStream._blockEndBits7) - break; // return S_FALSE; - if (bits7 == _bitStream._blockEndBits7) - { - if (_isLastBlock) - { - _reps[0] = rep0; - - if (_bitStream.InputEofError()) - break; - - /* - // packSize can be 15 bytes larger for encrypted archive - if (_packSize_Defined && _packSize < _bitStream.GetProcessedSize()) - break; - */ - - return _bitStream._hres; - // break; - } - RINOK(ReadTables(_bitStream)); - continue; - } - } - } - } - - UInt32 sym = m_MainDecoder.Decode(&_bitStream); - - if (sym < 256) - { - size_t winPos = _winPos; - _window[winPos] = (Byte)sym; - _winPos = winPos + 1; - _lzSize++; - continue; - } - - UInt32 len; - - if (sym < kSymbolRep + kNumReps) - { - if (sym >= kSymbolRep) - { - if (sym != kSymbolRep) - { - UInt32 dist; - if (sym == kSymbolRep + 1) - dist = _reps[1]; - else - { - if (sym == kSymbolRep + 2) - dist = _reps[2]; - else - { - dist = _reps[3]; - _reps[3] = _reps[2]; - } - _reps[2] = _reps[1]; - } - _reps[1] = rep0; - rep0 = dist; - } - - const UInt32 sym2 = m_LenDecoder.Decode(&_bitStream); - if (sym2 >= kLenTableSize) - break; // return S_FALSE; - len = SlotToLen(_bitStream, sym2); - } - else - { - if (sym == 256) - { - RINOK(AddFilter(_bitStream)); - continue; - } - else // if (sym == 257) - { - len = _lastLen; - // if (len = 0), we ignore that symbol, like original unRAR code, but it can mean error in stream. - // if (len == 0) return S_FALSE; - if (len == 0) - continue; - } - } - } - else if (sym >= kMainTableSize) - break; // return S_FALSE; - else - { - _reps[3] = _reps[2]; - _reps[2] = _reps[1]; - _reps[1] = rep0; - len = SlotToLen(_bitStream, sym - (kSymbolRep + kNumReps)); - - rep0 = m_DistDecoder.Decode(&_bitStream); - - if (rep0 >= 4) - { - if (rep0 >= _numCorrectDistSymbols) - break; // return S_FALSE; - unsigned numBits = (rep0 >> 1) - 1; - rep0 = (2 | (rep0 & 1)) << numBits; - - if (numBits < kNumAlignBits) - rep0 += _bitStream.ReadBits9(numBits); - else - { - len += (numBits >= 7); - len += (numBits >= 12); - len += (numBits >= 17); - - if (_useAlignBits) - { - // if (numBits > kNumAlignBits) - rep0 += (_bitStream.ReadBits32(numBits - kNumAlignBits) << kNumAlignBits); - UInt32 a = m_AlignDecoder.Decode(&_bitStream); - if (a >= kAlignTableSize) - break; // return S_FALSE; - rep0 += a; - } - else - rep0 += _bitStream.ReadBits32(numBits); - } - } - } - - _lastLen = len; - - if (rep0 >= _lzSize) - _lzError = true; - - { - UInt32 lenCur = len; - size_t winPos = _winPos; - size_t pos = (winPos - (size_t)rep0 - 1) & _winMask; - { - size_t rem = limit - winPos; - // size_t rem = _winSize - winPos; - - if (lenCur > rem) - { - lenCur = (UInt32)rem; - remLen = len - lenCur; - } - } - - Byte *win = _window; - _lzSize += lenCur; - _winPos = winPos + lenCur; - if (_winSize - pos >= lenCur) - { - const Byte *src = win + pos; - Byte *dest = win + winPos; - do - *dest++ = *src++; - while (--lenCur != 0); - } - else - { - do - { - win[winPos] = win[pos]; - winPos++; - pos = (pos + 1) & _winMask; - } - while (--lenCur != 0); - } - } - } - - if (_bitStream._hres != S_OK) - return _bitStream._hres; - - return S_FALSE; -} - - -HRESULT CDecoder::CodeReal() -{ - _unsupportedFilter = false; - _lzError = false; - _writeError = false; - - if (!_isSolid || !_wasInit) - { - size_t clearSize = _winSize; - if (_lzSize < _winSize) - clearSize = (size_t)_lzSize; - memset(_window, 0, clearSize); - - _wasInit = true; - _lzSize = 0; - _lzWritten = 0; - _winPos = 0; - - for (unsigned i = 0; i < kNumReps; i++) - _reps[i] = (UInt32)0 - 1; - - _lastLen = 0; - _tableWasFilled = false; - } - - _isLastBlock = false; - - InitFilters(); - - _filterEnd = 0; - _writtenFileSize = 0; - - _lzFileStart = _lzSize; - _lzWritten = _lzSize; - - HRESULT res = DecodeLZ(); - - HRESULT res2 = S_OK; - if (!_writeError && res != E_OUTOFMEMORY) - res2 = WriteBuf(); - - /* - if (res == S_OK) - if (InputEofError()) - res = S_FALSE; - */ - - if (res == S_OK) - res = res2; - - if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) - return S_FALSE; - return res; -} - - -// Original unRAR claims that maximum possible filter block size is (1 << 16) now, -// and (1 << 17) is minimum win size required to support filter. -// Original unRAR uses (1 << 18) for "extra safety and possible filter area size expansion" -// We can use any win size. - -static const unsigned kWinSize_Log_Min = 17; - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try - { - if (_dictSizeLog >= sizeof(size_t) * 8) - return E_NOTIMPL; - - if (!_isSolid) - _lzEnd = 0; - else - { - if (_lzSize < _lzEnd) - { - if (_window) - { - UInt64 rem = _lzEnd - _lzSize; - if (rem >= _winSize) - memset(_window, 0, _winSize); - else - { - size_t pos = (size_t)_lzSize & _winSize; - size_t rem2 = _winSize - pos; - if (rem2 > rem) - rem2 = (size_t)rem; - memset(_window + pos, 0, rem2); - rem -= rem2; - memset(_window, 0, (size_t)rem); - } - } - _lzEnd &= ((((UInt64)1) << 33) - 1); - _lzSize = _lzEnd; - _winPos = (size_t)(_lzSize & _winSize); - } - _lzEnd = _lzSize; - } - - size_t newSize; - { - unsigned newSizeLog = _dictSizeLog; - if (newSizeLog < kWinSize_Log_Min) - newSizeLog = kWinSize_Log_Min; - newSize = (size_t)1 << newSizeLog; - _numCorrectDistSymbols = newSizeLog * 2; - } - - if (!_window || _winSize != newSize) - { - if (!_isSolid && newSize > _winSizeAllocated) - { - ::MidFree(_window); - _window = NULL; - _winSizeAllocated = 0; - } - - Byte *win = _window; - if (!_window || newSize > _winSizeAllocated) - { - win = (Byte *)::MidAlloc(newSize); - if (!win) - return E_OUTOFMEMORY; - _winSizeAllocated = newSize; - memset(win, 0, newSize); - } - - if (_isSolid && _window) - { - // original unRAR claims: - // "Archiving code guarantees that win size does not grow in the same solid stream", - // but the original unRAR decoder still supports such grow case. - - Byte *winOld = _window; - size_t oldSize = _winSize; - size_t newMask = newSize - 1; - size_t oldMask = _winSize - 1; - size_t winPos = _winPos; - for (size_t i = 1; i < oldSize; i++) // i < oldSize) ? - win[(winPos - i) & newMask] = winOld[(winPos - i) & oldMask]; - ::MidFree(_window); - } - - _window = win; - _winSize = newSize; - } - - _winMask = _winSize - 1; - - if (!_inputBuf) - { - _inputBuf = (Byte *)::MidAlloc(kInputBufSize); - if (!_inputBuf) - return E_OUTOFMEMORY; - } - - _inStream = inStream; - _outStream = outStream; - - /* - _packSize = 0; - _packSize_Defined = (inSize != NULL); - if (_packSize_Defined) - _packSize = *inSize; - */ - - _unpackSize = 0; - _unpackSize_Defined = (outSize != NULL); - if (_unpackSize_Defined) - _unpackSize = *outSize; - - if ((Int64)_unpackSize >= 0) - _lzEnd += _unpackSize; - else - _lzEnd = 0; - - _progress = progress; - - HRESULT res = CodeReal(); - - if (res != S_OK) - return res; - if (_lzError) - return S_FALSE; - if (_unsupportedFilter) - return E_NOTIMPL; - return S_OK; - } - // catch(const CInBufferException &e) { return e.ErrorCode; } - // catch(...) { return S_FALSE; } - catch(...) { return E_OUTOFMEMORY; } - // CNewException is possible here. But probably CNewException is caused - // by error in data stream. -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size != 2) - return E_NOTIMPL; - _dictSizeLog = (Byte)((data[0] & 0xF) + 17); - _isSolid = ((data[1] & 1) != 0); - return S_OK; -} - -}} +// Rar5Decoder.cpp +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#include "StdAfx.h" + +#define DICT_SIZE_MAX ((UInt64)1 << DICT_SIZE_BITS_MAX) + +// #include // SSE2 +// #endif + +#include "../../../C/CpuArch.h" +#if 0 +#include "../../../C/Bra.h" +#endif + +#if defined(MY_CPU_ARM64) +#include +#endif + +// #define Z7_RAR5_SHOW_STAT +// #include +#ifdef Z7_RAR5_SHOW_STAT +#include +#endif + +#include "../Common/StreamUtils.h" + +#include "Rar5Decoder.h" + +/* +Note: original-unrar claims that encoder has limitation for Distance: + (Distance <= MaxWinSize - MAX_INC_LZ_MATCH) + MAX_INC_LZ_MATCH = 0x1001 + 3; +*/ + +#define LZ_ERROR_TYPE_NO 0 +#define LZ_ERROR_TYPE_HEADER 1 +// #define LZ_ERROR_TYPE_SYM 1 +#define LZ_ERROR_TYPE_DIST 2 + +static +void My_ZeroMemory(void *p, size_t size) +{ + #if defined(MY_CPU_AMD64) && !defined(_M_ARM64EC) \ + && defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL <= 1400) + // __stosq((UInt64 *)(void *)win, 0, size / 8); + /* + printf("\n__stosb \n"); + #define STEP_BIG (1 << 28) + for (size_t i = 0; i < ((UInt64)1 << 50); i += STEP_BIG) + { + printf("\n__stosb end %p\n", (void *)i); + __stosb((Byte *)p + i, 0, STEP_BIG); + } + */ + // __stosb((Byte *)p, 0, 0); + __stosb((Byte *)p, 0, size); + #else + // SecureZeroMemory (win, STEP); + // ZeroMemory(win, STEP); + // memset(win, 0, STEP); + memset(p, 0, size); + #endif +} + + + +#ifdef MY_CPU_LE_UNALIGN + #define Z7_RAR5_DEC_USE_UNALIGNED_COPY +#endif + +#ifdef Z7_RAR5_DEC_USE_UNALIGNED_COPY + + #define COPY_CHUNK_SIZE 16 + + #define COPY_CHUNK_4_2(dest, src) \ + { \ + ((UInt32 *)(void *)dest)[0] = ((const UInt32 *)(const void *)src)[0]; \ + ((UInt32 *)(void *)dest)[1] = ((const UInt32 *)(const void *)src)[1]; \ + src += 4 * 2; \ + dest += 4 * 2; \ + } + + /* sse2 doesn't help here in GCC and CLANG. + so we disabled sse2 here */ +#if 0 + #if defined(MY_CPU_AMD64) + #define Z7_RAR5_DEC_USE_SSE2 + #elif defined(MY_CPU_X86) + #if defined(_MSC_VER) && _MSC_VER >= 1300 && defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || defined(__SSE2__) \ + // || 1 == 1 // for debug only + #define Z7_RAR5_DEC_USE_SSE2 + #endif + #endif +#endif + + #if defined(MY_CPU_ARM64) + + #define COPY_OFFSET_MIN 16 + #define COPY_CHUNK1(dest, src) \ + { \ + vst1q_u8((uint8_t *)(void *)dest, \ + vld1q_u8((const uint8_t *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(Z7_RAR5_DEC_USE_SSE2) + #include // sse2 + #define COPY_OFFSET_MIN 16 + + #define COPY_CHUNK1(dest, src) \ + { \ + _mm_storeu_si128((__m128i *)(void *)dest, \ + _mm_loadu_si128((const __m128i *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(MY_CPU_64BIT) + #define COPY_OFFSET_MIN 8 + + #define COPY_CHUNK(dest, src) \ + { \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + src += 8 * 1; dest += 8 * 1; \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + src += 8 * 1; dest += 8 * 1; \ + } + + #else + #define COPY_OFFSET_MIN 4 + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_4_2(dest, src); \ + COPY_CHUNK_4_2(dest, src); \ + } + + #endif +#endif + + +#ifndef COPY_CHUNK_SIZE + #define COPY_OFFSET_MIN 4 + #define COPY_CHUNK_SIZE 8 + #define COPY_CHUNK_2(dest, src) \ + { \ + const Byte a0 = src[0]; \ + const Byte a1 = src[1]; \ + dest[0] = a0; \ + dest[1] = a1; \ + src += 2; \ + dest += 2; \ + } + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + } +#endif + + +#define COPY_CHUNKS \ +{ \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do { COPY_CHUNK(dest, src) } \ + while (dest < lim); \ +} + +namespace NCompress { +namespace NRar5 { + +typedef +#if 1 + unsigned +#else + size_t +#endif + CLenType; + +// (len != 0) +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch(size_t offset, Byte *dest, const Byte *src, const Byte *lim) +{ + { + // (COPY_OFFSET_MIN >= 4) + if (offset >= COPY_OFFSET_MIN) + { + COPY_CHUNKS + // return; + } + else + #if (COPY_OFFSET_MIN > 4) + #if COPY_CHUNK_SIZE < 8 + #error Stop_Compiling_Bad_COPY_CHUNK_SIZE + #endif + if (offset >= 4) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + COPY_CHUNK_4_2(dest, src) + #if COPY_CHUNK_SIZE < 16 + if (dest >= lim) break; + #endif + COPY_CHUNK_4_2(dest, src) + } + while (dest < lim); + // return; + } + else + #endif + { + // (offset < 4) + const unsigned b0 = src[0]; + if (offset < 2) + { + #if defined(Z7_RAR5_DEC_USE_UNALIGNED_COPY) && (COPY_CHUNK_SIZE == 16) + #if defined(MY_CPU_64BIT) + { + const UInt64 v64 = (UInt64)b0 * 0x0101010101010101; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + ((UInt64 *)(void *)dest)[0] = v64; + ((UInt64 *)(void *)dest)[1] = v64; + dest += 16; + } + while (dest < lim); + } + #else + { + UInt32 v = b0; + v |= v << 8; + v |= v << 16; + do + { + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + } + while (dest < lim); + } + #endif + #else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + } + while (dest < lim); + #endif + } + else if (offset == 2) + { + const Byte b1 = src[1]; + { + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest += 2; + } + while (dest < lim); + } + } + else // (offset == 3) + { + const Byte b1 = src[1]; + const Byte b2 = src[2]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest[2] = b2; + dest += 3; + } + while (dest < lim); + } + } + } +} + +static const size_t kInputBufSize = 1 << 20; +static const UInt32 k_Filter_BlockSize_MAX = 1 << 22; +static const unsigned k_Filter_AfterPad_Size = 64; + +#ifdef Z7_RAR5_SHOW_STAT +static const unsigned kNumStats1 = 10; +static const unsigned kNumStats2 = (1 << 12) + 16; +static UInt32 g_stats1[kNumStats1]; +static UInt32 g_stats2[kNumStats1][kNumStats2]; +#endif + +#if 1 +MY_ALIGN(32) +// DICT_SIZE_BITS_MAX-1 are required +static const Byte k_LenPlusTable[DICT_SIZE_BITS_MAX] = + { 0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }; +#endif + + + +class CBitDecoder +{ +public: + const Byte *_buf; + const Byte *_bufCheck_Block; // min(ptr for _blockEnd, _bufCheck) + unsigned _bitPos; // = [0 ... 7] + bool _wasFinished; + bool _minorError; + unsigned _blockEndBits7; // = [0 ... 7] : the number of additional bits in (_blockEnd) poisition. + HRESULT _hres; + const Byte *_bufCheck; // relaxed limit (16 bytes before real end of input data in buffer) + Byte *_bufLim; // end if input data + Byte *_bufBase; + ISequentialInStream *_stream; + + UInt64 _processedSize; + UInt64 _blockEnd; // absolute end of current block + // but it doesn't include additional _blockEndBits7 [0 ... 7] bits + + Z7_FORCE_INLINE + void CopyFrom(const CBitDecoder &a) + { + _buf = a._buf; + _bufCheck_Block = a._bufCheck_Block; + _bitPos = a._bitPos; + _wasFinished = a._wasFinished; + _blockEndBits7 = a._blockEndBits7; + _bufCheck = a._bufCheck; + _bufLim = a._bufLim; + _bufBase = a._bufBase; + + _processedSize = a._processedSize; + _blockEnd = a._blockEnd; + } + + Z7_FORCE_INLINE + void RestoreFrom2(const CBitDecoder &a) + { + _buf = a._buf; + _bitPos = a._bitPos; + } + + Z7_FORCE_INLINE + void SetCheck_forBlock() + { + _bufCheck_Block = _bufCheck; + if (_bufCheck > _buf) + { + const UInt64 processed = GetProcessedSize_Round(); + if (_blockEnd < processed) + _bufCheck_Block = _buf; + else + { + const UInt64 delta = _blockEnd - processed; + if ((size_t)(_bufCheck - _buf) > delta) + _bufCheck_Block = _buf + (size_t)delta; + } + } + } + + Z7_FORCE_INLINE + bool IsBlockOverRead() const + { + const UInt64 v = GetProcessedSize_Round(); + if (v < _blockEnd) return false; + if (v > _blockEnd) return true; + return _bitPos > _blockEndBits7; + } + + /* + CBitDecoder() throw(): + _buf(0), + _bufLim(0), + _bufBase(0), + _stream(0), + _processedSize(0), + _wasFinished(false) + {} + */ + + Z7_FORCE_INLINE + void Init() throw() + { + _blockEnd = 0; + _blockEndBits7 = 0; + + _bitPos = 0; + _processedSize = 0; + _buf = _bufBase; + _bufLim = _bufBase; + _bufCheck = _buf; + _bufCheck_Block = _buf; + _wasFinished = false; + _minorError = false; + } + + void Prepare2() throw(); + + Z7_FORCE_INLINE + void Prepare() throw() + { + if (_buf >= _bufCheck) + Prepare2(); + } + + Z7_FORCE_INLINE + bool ExtraBitsWereRead() const + { + return _buf >= _bufLim && (_buf > _bufLim || _bitPos != 0); + } + + Z7_FORCE_INLINE bool InputEofError() const { return ExtraBitsWereRead(); } + + Z7_FORCE_INLINE unsigned GetProcessedBits7() const { return _bitPos; } + Z7_FORCE_INLINE UInt64 GetProcessedSize_Round() const { return _processedSize + (size_t)(_buf - _bufBase); } + Z7_FORCE_INLINE UInt64 GetProcessedSize() const { return _processedSize + (size_t)(_buf - _bufBase) + ((_bitPos + 7) >> 3); } + + Z7_FORCE_INLINE + void AlignToByte() + { + if (_bitPos != 0) + { +#if 1 + // optional check of unused bits for strict checking: + // original-unrar doesn't check it: + const unsigned b = (unsigned)*_buf << _bitPos; + if (b & 0xff) + _minorError = true; +#endif + _buf++; + _bitPos = 0; + } + // _buf += (_bitPos + 7) >> 3; + // _bitPos = 0; + } + + Z7_FORCE_INLINE + Byte ReadByte_InAligned() + { + return *_buf++; + } + + Z7_FORCE_INLINE + UInt32 GetValue(unsigned numBits) const + { + // 0 < numBits <= 17 : supported values +#if defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE_UNALIGN) + UInt32 v = GetBe32(_buf); +#if 1 + return (v >> (32 - numBits - _bitPos)) & ((1u << numBits) - 1); +#else + return (v << _bitPos) >> (32 - numBits); +#endif +#else + UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2]; + v >>= 24 - numBits - _bitPos; + return v & ((1 << numBits) - 1); +#endif + } + + Z7_FORCE_INLINE + UInt32 GetValue_InHigh32bits() const + { + // 0 < numBits <= 17 : supported vales +#if defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE_UNALIGN) + return GetBe32(_buf) << _bitPos; +#else + const UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2]; + return v << (_bitPos + 8); +#endif + } + + + Z7_FORCE_INLINE + void MovePos(unsigned numBits) + { + numBits += _bitPos; + _buf += numBits >> 3; + _bitPos = numBits & 7; + } + + + Z7_FORCE_INLINE + UInt32 ReadBits9(unsigned numBits) + { + const Byte *buf = _buf; + UInt32 v = ((UInt32)buf[0] << 8) | (UInt32)buf[1]; + v &= (UInt32)0xFFFF >> _bitPos; + numBits += _bitPos; + v >>= 16 - numBits; + _buf = buf + (numBits >> 3); + _bitPos = numBits & 7; + return v; + } + + Z7_FORCE_INLINE + UInt32 ReadBits_9fix(unsigned numBits) + { + const Byte *buf = _buf; + UInt32 v = ((UInt32)buf[0] << 8) | (UInt32)buf[1]; + const UInt32 mask = (1u << numBits) - 1; + numBits += _bitPos; + v >>= 16 - numBits; + _buf = buf + (numBits >> 3); + _bitPos = numBits & 7; + return v & mask; + } + +#if 1 && defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 8) +#define Z7_RAR5_USE_64BIT +#endif + +#ifdef Z7_RAR5_USE_64BIT +#define MAX_DICT_LOG (sizeof(size_t) / 8 * 5 + 31) +#else +#define MAX_DICT_LOG 31 +#endif + +#ifdef Z7_RAR5_USE_64BIT + + Z7_FORCE_INLINE + size_t ReadBits_Big(unsigned numBits, UInt64 v) + { + const UInt64 mask = ((UInt64)1 << numBits) - 1; + numBits += _bitPos; + const Byte *buf = _buf; + // UInt64 v = GetBe64(buf); + v >>= 64 - numBits; + _buf = buf + (numBits >> 3); + _bitPos = numBits & 7; + return (size_t)(v & mask); + } + #define ReadBits_Big25 ReadBits_Big + +#else + + // (numBits <= 25) for 32-bit mode + Z7_FORCE_INLINE + size_t ReadBits_Big25(unsigned numBits, UInt32 v) + { + const UInt32 mask = ((UInt32)1 << numBits) - 1; + numBits += _bitPos; + v >>= 32 - numBits; + _buf += numBits >> 3; + _bitPos = numBits & 7; + return v & mask; + } + + // numBits != 0 + Z7_FORCE_INLINE + size_t ReadBits_Big(unsigned numBits, UInt32 v) + { + const Byte *buf = _buf; + // UInt32 v = GetBe32(buf); +#if 0 + const UInt32 mask = ((UInt32)1 << numBits) - 1; + numBits += _bitPos; + if (numBits > 32) + { + v <<= numBits - 32; + v |= (UInt32)buf[4] >> (40 - numBits); + } + else + v >>= 32 - numBits; + _buf = buf + (numBits >> 3); + _bitPos = numBits & 7; + return v & mask; +#else + v <<= _bitPos; + v |= (UInt32)buf[4] >> (8 - _bitPos); + v >>= 32 - numBits; + numBits += _bitPos; + _buf = buf + (numBits >> 3); + _bitPos = numBits & 7; + return v; +#endif + } +#endif +}; + + +static const unsigned kLookaheadSize = 16; +static const unsigned kInputBufferPadZone = kLookaheadSize; + +Z7_NO_INLINE +void CBitDecoder::Prepare2() throw() +{ + if (_buf > _bufLim) + return; + + size_t rem = (size_t)(_bufLim - _buf); + if (rem != 0) + memmove(_bufBase, _buf, rem); + + _bufLim = _bufBase + rem; + _processedSize += (size_t)(_buf - _bufBase); + _buf = _bufBase; + + // we do not look ahead more than 16 bytes before limit checks. + + if (!_wasFinished) + { + while (rem <= kLookaheadSize) + { + UInt32 processed = (UInt32)(kInputBufSize - rem); + // processed = 33; // for debug + _hres = _stream->Read(_bufLim, processed, &processed); + _bufLim += processed; + rem += processed; + if (processed == 0 || _hres != S_OK) + { + _wasFinished = true; + // if (_hres != S_OK) throw CInBufferException(result); + break; + } + } + } + + // we always fill pad zone here. + // so we don't need to call Prepare2() if (_wasFinished == true) + memset(_bufLim, 0xFF, kLookaheadSize); + + if (rem < kLookaheadSize) + { + _bufCheck = _buf; + // memset(_bufLim, 0xFF, kLookaheadSize - rem); + } + else + _bufCheck = _bufLim - kLookaheadSize; + + SetCheck_forBlock(); +} + + +enum FilterType +{ + FILTER_DELTA = 0, + FILTER_E8, + FILTER_E8E9, + FILTER_ARM +}; + +static const size_t kWriteStep = (size_t)1 << 18; + // (size_t)1 << 22; // original-unrar + +// Original unRAR claims that maximum possible filter block size is (1 << 16) now, +// and (1 << 17) is minimum win size required to support filter. +// Original unRAR uses (1u << 18) for "extra safety and possible filter area size expansion" +// We can use any win size, but we use same (1u << 18) for compatibility +// with WinRar + +// static const unsigned kWinSize_Log_Min = 17; +static const size_t kWinSize_Min = 1u << 18; + +CDecoder::CDecoder(): + _isSolid(false), + _is_v7(false), + _wasInit(false), + // _dictSizeLog(0), + _dictSize(kWinSize_Min), + _window(NULL), + _winPos(0), + _winSize(0), + _dictSize_forCheck(0), + _lzSize(0), + _lzEnd(0), + _writtenFileSize(0), + _filters(NULL), + _winSize_Allocated(0), + _inputBuf(NULL) +{ +#if 1 + memcpy(m_LenPlusTable, k_LenPlusTable, sizeof(k_LenPlusTable)); +#endif + // printf("\nsizeof(CDecoder) == %d\n", sizeof(CDecoder)); +} + +CDecoder::~CDecoder() +{ +#ifdef Z7_RAR5_SHOW_STAT + printf("\n%4d :", 0); + for (unsigned k = 0; k < kNumStats1; k++) + printf(" %8u", (unsigned)g_stats1[k]); + printf("\n"); + for (unsigned i = 0; i < kNumStats2; i++) + { + printf("\n%4d :", i); + for (unsigned k = 0; k < kNumStats1; k++) + printf(" %8u", (unsigned)g_stats2[k][i]); + } + printf("\n"); +#endif + +#define Z7_RAR_FREE_WINDOW ::BigFree(_window); + + Z7_RAR_FREE_WINDOW + z7_AlignedFree(_inputBuf); + z7_AlignedFree(_filters); +} + +Z7_NO_INLINE +void CDecoder::DeleteUnusedFilters() +{ + if (_numUnusedFilters != 0) + { + // printf("\nDeleteUnusedFilters _numFilters = %6u\n", _numFilters); + const unsigned n = _numFilters - _numUnusedFilters; + _numFilters = n; + memmove(_filters, _filters + _numUnusedFilters, n * sizeof(CFilter)); + _numUnusedFilters = 0; + } +} + + +Z7_NO_INLINE +HRESULT CDecoder::WriteData(const Byte *data, size_t size) +{ + HRESULT res = S_OK; + if (!_unpackSize_Defined || _writtenFileSize < _unpackSize) + { + size_t cur = size; + if (_unpackSize_Defined) + { + const UInt64 rem = _unpackSize - _writtenFileSize; + if (cur > rem) + cur = (size_t)rem; + } + res = WriteStream(_outStream, data, cur); + if (res != S_OK) + _writeError = true; + } + _writtenFileSize += size; + return res; +} + + +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT(lim_back) pc -= (UInt32)(SizeT)data; +#define BR_PC_GET (pc + (UInt32)(SizeT)data) +#else +#define BR_PC_INIT(lim_back) pc += (UInt32)dataSize - (lim_back); +#define BR_PC_GET (pc - (UInt32)(SizeT)(data_lim - data)) +#endif + +#ifdef MY_CPU_LE_UNALIGN +#define Z7_RAR5_FILTER_USE_LE_UNALIGN +#endif + +#ifdef Z7_RAR5_FILTER_USE_LE_UNALIGN +#define RAR_E8_FILT(mask) \ +{ \ + for (;;) \ + { UInt32 v; \ + do { \ + v = GetUi32(data) ^ (UInt32)0xe8e8e8e8; \ + data += 4; \ + if ((v & ((UInt32)(mask) << (8 * 0))) == 0) { data -= 3; break; } \ + if ((v & ((UInt32)(mask) << (8 * 1))) == 0) { data -= 2; break; } \ + if ((v & ((UInt32)(mask) << (8 * 2))) == 0) { data -= 1; break; } } \ + while((v & ((UInt32)(mask) << (8 * 3)))); \ + if (data > data_lim) break; \ + const UInt32 offset = BR_PC_GET & (kFileSize - 1); \ + const UInt32 addr = GetUi32(data); \ + data += 4; \ + if (addr < kFileSize) \ + SetUi32(data - 4, addr - offset) \ + else if (addr > ~offset) /* if (addr > ((UInt32)0xFFFFFFFF - offset)) */ \ + SetUi32(data - 4, addr + kFileSize) \ + } \ +} +#else +#define RAR_E8_FILT(get_byte) \ +{ \ + for (;;) \ + { \ + if ((get_byte) != 0xe8) \ + if ((get_byte) != 0xe8) \ + if ((get_byte) != 0xe8) \ + if ((get_byte) != 0xe8) \ + continue; \ + { if (data > data_lim) break; \ + const UInt32 offset = BR_PC_GET & (kFileSize - 1); \ + const UInt32 addr = GetUi32(data); \ + data += 4; \ + if (addr < kFileSize) \ + SetUi32(data - 4, addr - offset) \ + else if (addr > ~offset) /* if (addr > ((UInt32)0xFFFFFFFF - offset)) */ \ + SetUi32(data - 4, addr + kFileSize) \ + } \ + } \ +} +#endif + +HRESULT CDecoder::ExecuteFilter(const CFilter &f) +{ + Byte *data = _filterSrc; + UInt32 dataSize = f.Size; + // printf("\nType = %d offset = %9d size = %5d", f.Type, (unsigned)(f.Start - _lzFileStart), dataSize); + + if (f.Type == FILTER_DELTA) + { + // static unsigned g1 = 0, g2 = 0; g1 += dataSize; + // if (g2++ % 100 == 0) printf("DELTA num %8u, size %8u MiB, channels = %2u curSize=%8u\n", g2, (g1 >> 20), f.Channels, dataSize); + _filterDst.AllocAtLeast_max((size_t)dataSize, k_Filter_BlockSize_MAX); + if (!_filterDst.IsAllocated()) + return E_OUTOFMEMORY; + + Byte *dest = _filterDst; + const unsigned numChannels = f.Channels; + unsigned curChannel = 0; + do + { + Byte prevByte = 0; + Byte *dest2 = dest + curChannel; + const Byte *dest_lim = dest + dataSize; + for (; dest2 < dest_lim; dest2 += numChannels) + *dest2 = (prevByte = (Byte)(prevByte - *data++)); + } + while (++curChannel != numChannels); + // return WriteData(dest, dataSize); + data = dest; + } + else if (f.Type < FILTER_ARM) + { + // FILTER_E8 or FILTER_E8E9 + if (dataSize > 4) + { + UInt32 pc = (UInt32)(f.Start - _lzFileStart); + const UInt32 kFileSize = (UInt32)1 << 24; + const Byte *data_lim = data + dataSize - 4; + BR_PC_INIT(4) // because (data_lim) was moved back for 4 bytes + data[dataSize] = 0xe8; + if (f.Type == FILTER_E8) + { + // static unsigned g1 = 0; g1 += dataSize; printf("\n FILTER_E8 %u", (g1 >> 20)); +#ifdef Z7_RAR5_FILTER_USE_LE_UNALIGN + RAR_E8_FILT (0xff) +#else + RAR_E8_FILT (*data++) +#endif + } + else + { + // static unsigned g1 = 0; g1 += dataSize; printf("\n FILTER_E8_E9 %u", (g1 >> 20)); +#ifdef Z7_RAR5_FILTER_USE_LE_UNALIGN + RAR_E8_FILT (0xfe) +#else + RAR_E8_FILT (*data++ & 0xfe) +#endif + } + } + data = _filterSrc; + } + else if (f.Type == FILTER_ARM) + { + UInt32 pc = (UInt32)(f.Start - _lzFileStart); +#if 0 + // z7_BranchConv_ARM_Dec expects that (fileOffset & 3) == 0; + // but even if (fileOffset & 3) then current code + // in z7_BranchConv_ARM_Dec works same way as unrar's code still. + z7_BranchConv_ARM_Dec(data, dataSize, pc - 8); +#else + dataSize &= ~(UInt32)3; + if (dataSize) + { + Byte *data_lim = data + dataSize; + data_lim[3] = 0xeb; + BR_PC_INIT(0) + pc -= 4; // because (data) will point to next instruction + for (;;) // do + { + data += 4; + if (data[-1] != 0xeb) + continue; + if (data > data_lim) + break; + { + UInt32 v = GetUi32a(data - 4) - (BR_PC_GET >> 2); + v &= 0x00ffffff; + v |= 0xeb000000; + SetUi32a(data - 4, v) + } + } + } +#endif + data = _filterSrc; + } + else + { + _unsupportedFilter = true; + My_ZeroMemory(data, dataSize); + // return S_OK; // unrar + } + // return WriteData(_filterSrc, (size_t)f.Size); + return WriteData(data, (size_t)f.Size); +} + + +HRESULT CDecoder::WriteBuf() +{ + DeleteUnusedFilters(); + const UInt64 lzSize = _lzSize + _winPos; + + for (unsigned i = 0; i < _numFilters;) + { + const size_t lzAvail = (size_t)(lzSize - _lzWritten); + if (lzAvail == 0) + break; + // (lzAvail != 0) + const CFilter &f = _filters[i]; + const UInt64 blockStart = f.Start; + if (blockStart > _lzWritten) + { + const UInt64 rem = blockStart - _lzWritten; + // (rem != 0) + size_t size = lzAvail; + if (size > rem) + size = (size_t)rem; + // (size != 0) + RINOK(WriteData(_window + _winPos - lzAvail, size)) + _lzWritten += size; + continue; + } + + // (blockStart <= _lzWritten) + const UInt32 blockSize = f.Size; + size_t offset = (size_t)(_lzWritten - blockStart); + if (offset == 0) + { + _filterSrc.AllocAtLeast_max( + (size_t)blockSize + k_Filter_AfterPad_Size, + k_Filter_BlockSize_MAX + k_Filter_AfterPad_Size); + if (!_filterSrc.IsAllocated()) + return E_OUTOFMEMORY; + } + + const size_t blockRem = (size_t)blockSize - offset; + size_t size = lzAvail; + if (size > blockRem) + size = blockRem; + memcpy(_filterSrc + offset, _window + _winPos - lzAvail, size); + _lzWritten += size; + offset += size; + if (offset != blockSize) + return S_OK; + + _numUnusedFilters = ++i; + RINOK(ExecuteFilter(f)) + } + + DeleteUnusedFilters(); + if (_numFilters) + return S_OK; + const size_t lzAvail = (size_t)(lzSize - _lzWritten); + RINOK(WriteData(_window + _winPos - lzAvail, lzAvail)) + _lzWritten += lzAvail; + return S_OK; +} + + +Z7_NO_INLINE +static UInt32 ReadUInt32(CBitDecoder &bi) +{ + const unsigned numBits = (unsigned)bi.ReadBits_9fix(2) * 8 + 8; + UInt32 v = 0; + unsigned i = 0; + do + { + v += (UInt32)bi.ReadBits_9fix(8) << i; + i += 8; + } + while (i != numBits); + return v; +} + + +static const unsigned MAX_UNPACK_FILTERS = 8192; + +HRESULT CDecoder::AddFilter(CBitDecoder &_bitStream) +{ + DeleteUnusedFilters(); + + if (_numFilters >= MAX_UNPACK_FILTERS) + { + RINOK(WriteBuf()) + DeleteUnusedFilters(); + if (_numFilters >= MAX_UNPACK_FILTERS) + { + _unsupportedFilter = true; + InitFilters(); + } + } + + _bitStream.Prepare(); + + CFilter f; + const UInt32 blockStart = ReadUInt32(_bitStream); + f.Size = ReadUInt32(_bitStream); + + if (f.Size > k_Filter_BlockSize_MAX) + { + _unsupportedFilter = true; + f.Size = 0; // unrar 5.5.5 + } + + f.Type = (Byte)_bitStream.ReadBits_9fix(3); + f.Channels = 0; + if (f.Type == FILTER_DELTA) + f.Channels = (Byte)(_bitStream.ReadBits_9fix(5) + 1); + f.Start = _lzSize + _winPos + blockStart; + +#if 0 + static unsigned z_cnt = 0; if (z_cnt++ % 100 == 0) + printf ("\nFilter %7u : %4u : %8p, st=%8x, size=%8x, type=%u ch=%2u", + z_cnt, (unsigned)_filters.Size(), (void *)(size_t)(_lzSize + _winPos), + (unsigned)blockStart, (unsigned)f.Size, (unsigned)f.Type, (unsigned)f.Channels); +#endif + + if (f.Start < _filterEnd) + _unsupportedFilter = true; + else + { + _filterEnd = f.Start + f.Size; + if (f.Size != 0) + { + if (!_filters) + { + _filters = (CFilter *)z7_AlignedAlloc(MAX_UNPACK_FILTERS * sizeof(CFilter)); + if (!_filters) + return E_OUTOFMEMORY; + } + // printf("\n_numFilters = %6u\n", _numFilters); + const unsigned i = _numFilters++; + _filters[i] = f; + } + } + + return S_OK; +} + + +#define RIF(x) { if (!(x)) return S_FALSE; } + +#if 1 +#define PRINT_CNT(name, skip) +#else +#define PRINT_CNT(name, skip) \ + { static unsigned g_cnt = 0; if (g_cnt++ % skip == 0) printf("\n%16s: %8u", name, g_cnt); } +#endif + +HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream) +{ + if (_progress) + { + const UInt64 packSize = _bitStream.GetProcessedSize(); + if (packSize - _progress_Pack >= (1u << 24) + || _writtenFileSize - _progress_Unpack >= (1u << 26)) + { + _progress_Pack = packSize; + _progress_Unpack = _writtenFileSize; + RINOK(_progress->SetRatioInfo(&_progress_Pack, &_writtenFileSize)) + } + // printf("\ntable read pos=%p packSize=%p _writtenFileSize = %p\n", (size_t)_winPos, (size_t)packSize, (size_t)_writtenFileSize); + } + + // _bitStream is aligned already + _bitStream.Prepare(); + { + const unsigned flags = _bitStream.ReadByte_InAligned(); + /* ((flags & 20) == 0) in all rar archives now, + but (flags & 20) flag can be used as some decoding hint in future versions of original rar. + So we ignore that bit here. */ + unsigned checkSum = _bitStream.ReadByte_InAligned(); + checkSum ^= flags; + const unsigned num = (flags >> 3) & 3; + if (num >= 3) + return S_FALSE; + UInt32 blockSize = _bitStream.ReadByte_InAligned(); + checkSum ^= blockSize; + if (num != 0) + { + { + const unsigned b = _bitStream.ReadByte_InAligned(); + checkSum ^= b; + blockSize += (UInt32)b << 8; + } + if (num > 1) + { + const unsigned b = _bitStream.ReadByte_InAligned(); + checkSum ^= b; + blockSize += (UInt32)b << 16; + } + } + if (checkSum != 0x5A) + return S_FALSE; + unsigned blockSizeBits7 = (flags & 7) + 1; + blockSize += (UInt32)(blockSizeBits7 >> 3); + if (blockSize == 0) + { + // it's error in data stream + // but original-unrar ignores that error + _bitStream._minorError = true; +#if 1 + // we ignore that error as original-unrar: + blockSizeBits7 = 0; + blockSize = 1; +#else + // we can stop decoding: + return S_FALSE; +#endif + } + blockSize--; + blockSizeBits7 &= 7; + PRINT_CNT("Blocks", 100) + /* + { + static unsigned g_prev = 0; + static unsigned g_cnt = 0; + unsigned proc = unsigned(_winPos); + if (g_cnt++ % 100 == 0) printf(" c_size = %8u ", blockSize); + if (g_cnt++ % 100 == 1) printf(" unp_size = %8u", proc - g_prev); + g_prev = proc; + } + */ + _bitStream._blockEndBits7 = blockSizeBits7; + _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize; + _bitStream.SetCheck_forBlock(); + _isLastBlock = ((flags & 0x40) != 0); + if ((flags & 0x80) == 0) + { + if (!_tableWasFilled) + // if (blockSize != 0 || blockSizeBits7 != 0) + if (blockSize + blockSizeBits7 != 0) + return S_FALSE; + return S_OK; + } + _tableWasFilled = false; + } + + PRINT_CNT("Tables", 100); + + const unsigned kLevelTableSize = 20; + const unsigned k_NumHufTableBits_Level = 6; + NHuffman::CDecoder256 m_LevelDecoder; + const unsigned kTablesSizesSum_MAX = kMainTableSize + kDistTableSize_MAX + kAlignTableSize + kLenTableSize; + Byte lens[kTablesSizesSum_MAX]; + { + // (kLevelTableSize + 16 < kTablesSizesSum). So we use lens[] array for (Level) table + // Byte lens2[kLevelTableSize + 16]; + unsigned i = 0; + do + { + if (_bitStream._buf >= _bitStream._bufCheck_Block) + { + _bitStream.Prepare(); + if (_bitStream.IsBlockOverRead()) + return S_FALSE; + } + const unsigned len = (unsigned)_bitStream.ReadBits_9fix(4); + if (len == 15) + { + unsigned num = (unsigned)_bitStream.ReadBits_9fix(4); + if (num != 0) + { + num += 2; + num += i; + // we are allowed to overwrite to lens[] for extra 16 bytes after kLevelTableSize +#if 0 + if (num > kLevelTableSize) + { + // we ignore this error as original-unrar + num = kLevelTableSize; + // return S_FALSE; + } +#endif + do + lens[i++] = 0; + while (i < num); + continue; + } + } + lens[i++] = (Byte)len; + } + while (i < kLevelTableSize); + if (_bitStream.IsBlockOverRead()) + return S_FALSE; + RIF(m_LevelDecoder.Build(lens, NHuffman::k_BuildMode_Full)) + } + + unsigned i = 0; + const unsigned tableSize = _is_v7 ? + kTablesSizesSum_MAX : + kTablesSizesSum_MAX - kExtraDistSymbols_v7; + do + { + if (_bitStream._buf >= _bitStream._bufCheck_Block) + { + // if (_bitStream._buf >= _bitStream._bufCheck) + _bitStream.Prepare(); + if (_bitStream.IsBlockOverRead()) + return S_FALSE; + } + const unsigned sym = m_LevelDecoder.DecodeFull(&_bitStream); + if (sym < 16) + lens[i++] = (Byte)sym; +#if 0 + else if (sym > kLevelTableSize) + return S_FALSE; +#endif + else + { + unsigned num = ((sym /* - 16 */) & 1) * 4; + num += num + 3 + (unsigned)_bitStream.ReadBits9(num + 3); + num += i; + if (num > tableSize) + { + // we ignore this error as original-unrar + num = tableSize; + // return S_FALSE; + } + unsigned v = 0; + if (sym < 16 + 2) + { + if (i == 0) + return S_FALSE; + v = lens[(size_t)i - 1]; + } + do + lens[i++] = (Byte)v; + while (i < num); + } + } + while (i < tableSize); + + if (_bitStream.IsBlockOverRead()) + return S_FALSE; + if (_bitStream.InputEofError()) + return S_FALSE; + + /* We suppose that original-rar encoder can create only two cases for Huffman: + 1) Empty Huffman tree (if num_used_symbols == 0) + 2) Full Huffman tree (if num_used_symbols != 0) + Usually the block contains at least one symbol for m_MainDecoder. + So original-rar-encoder creates full Huffman tree for m_MainDecoder. + But we suppose that (num_used_symbols == 0) is possible for m_MainDecoder, + because file must be finished with (_isLastBlock) flag, + even if there are no symbols in m_MainDecoder. + So we use k_BuildMode_Full_or_Empty for m_MainDecoder. + */ + const NHuffman::enum_BuildMode buildMode = NHuffman:: + k_BuildMode_Full_or_Empty; // strict check + // k_BuildMode_Partial; // non-strict check (ignore errors) + + RIF(m_MainDecoder.Build(&lens[0], buildMode)) + if (!_is_v7) + { +#if 1 + /* we use this manual loop to avoid compiler BUG. + GCC 4.9.2 compiler has BUG with overlapping memmove() to right in local array. */ + Byte *dest = lens + kMainTableSize + kDistTableSize_v6 + + kAlignTableSize + kLenTableSize - 1; + unsigned num = kAlignTableSize + kLenTableSize; + do + { + dest[kExtraDistSymbols_v7] = dest[0]; + dest--; + } + while (--num); +#else + memmove(lens + kMainTableSize + kDistTableSize_v6 + kExtraDistSymbols_v7, + lens + kMainTableSize + kDistTableSize_v6, + kAlignTableSize + kLenTableSize); +#endif + memset(lens + kMainTableSize + kDistTableSize_v6, 0, kExtraDistSymbols_v7); + } + + RIF(m_DistDecoder.Build(&lens[kMainTableSize], buildMode)) + RIF( m_LenDecoder.Build(&lens[kMainTableSize + + kDistTableSize_MAX + kAlignTableSize], buildMode)) + + _useAlignBits = false; + for (i = 0; i < kAlignTableSize; i++) + if (lens[kMainTableSize + kDistTableSize_MAX + (size_t)i] != kNumAlignBits) + { + RIF(m_AlignDecoder.Build(&lens[kMainTableSize + kDistTableSize_MAX], buildMode)) + _useAlignBits = true; + break; + } + + _tableWasFilled = true; + return S_OK; +} + +static inline CLenType SlotToLen(CBitDecoder &_bitStream, CLenType slot) +{ + const unsigned numBits = ((unsigned)slot >> 2) - 1; + return ((4 | (slot & 3)) << numBits) + (CLenType)_bitStream.ReadBits9(numBits); +} + + +static const unsigned kSymbolRep = 258; +static const unsigned kMaxMatchLen = 0x1001 + 3; + +enum enum_exit_type +{ + Z7_RAR_EXIT_TYPE_NONE, + Z7_RAR_EXIT_TYPE_ADD_FILTER +}; + + +#define LZ_RESTORE \ +{ \ + _reps[0] = rep0; \ + _winPos = (size_t)(winPos - _window); \ + _buf_Res = _bitStream._buf; \ + _bitPos_Res = _bitStream._bitPos; \ +} + +#define LZ_LOOP_BREAK_OK { break; } +// #define LZ_LOOP_BREAK_ERROR { _lzError = LZ_ERROR_TYPE_SYM; break; } +// #define LZ_LOOP_BREAK_ERROR { LZ_RESTORE; return S_FALSE; } +#define LZ_LOOP_BREAK_ERROR { goto decode_error; } +// goto decode_error; } +// #define LZ_LOOP_BREAK_ERROR { break; } + +#define Z7_RAR_HUFF_DECODE_CHECK_break(sym, huf, kNumTableBits, bitStream) \ + Z7_HUFF_DECODE_CHECK(sym, huf, kNumHufBits, kNumTableBits, bitStream, { LZ_LOOP_BREAK_ERROR }) + + +/* + DecodeLZ2() will stop decoding if it reaches limit when (_winPos >= _limit) + at return: + (_winPos < _limit + kMaxMatchLen) + also it can write up to (COPY_CHUNK_SIZE - 1) additional junk bytes after (_winPos). +*/ +HRESULT CDecoder::DecodeLZ2(const CBitDecoder &bitStream) throw() +{ +#if 0 + Byte k_LenPlusTable_LOC[DICT_SIZE_BITS_MAX]; + memcpy(k_LenPlusTable_LOC, k_LenPlusTable, sizeof(k_LenPlusTable)); +#endif + + PRINT_CNT("DecodeLZ2", 2000); + + CBitDecoder _bitStream; + _bitStream.CopyFrom(bitStream); + // _bitStream._stream = _inStream; + // _bitStream._bufBase = _inputBuf; + // _bitStream.Init(); + + // _reps[*] can be larger than _winSize, if _winSize was reduced in solid stream. + size_t rep0 = _reps[0]; + // size_t rep1 = _reps[1]; + // Byte *win = _window; + Byte *winPos = _window + _winPos; + const Byte *limit = _window + _limit; + _exitType = Z7_RAR_EXIT_TYPE_NONE; + + for (;;) + { + if (winPos >= limit) + LZ_LOOP_BREAK_OK + // (winPos < limit) + if (_bitStream._buf >= _bitStream._bufCheck_Block) + { + if (_bitStream.InputEofError()) + LZ_LOOP_BREAK_OK + if (_bitStream._buf >= _bitStream._bufCheck) + { + if (!_bitStream._wasFinished) + LZ_LOOP_BREAK_OK + // _bitStream._wasFinished == true + // we don't need Prepare() here, because all data was read + // and PadZone (16 bytes) after data was filled. + } + const UInt64 processed = _bitStream.GetProcessedSize_Round(); + // some cases are error, but the caller will process such error cases. + if (processed >= _bitStream._blockEnd && + (processed > _bitStream._blockEnd + || _bitStream.GetProcessedBits7() >= _bitStream._blockEndBits7)) + LZ_LOOP_BREAK_OK + // that check is not required, but it can help, if there is BUG in another code + if (!_tableWasFilled) + LZ_LOOP_BREAK_ERROR + } + +#if 0 + const unsigned sym = m_MainDecoder.Decode(&_bitStream); +#else + unsigned sym; + Z7_RAR_HUFF_DECODE_CHECK_break(sym, &m_MainDecoder, k_NumHufTableBits_Main, &_bitStream) +#endif + + if (sym < 256) + { + *winPos++ = (Byte)sym; + // _lzSize++; + continue; + } + + CLenType len; + + if (sym < kSymbolRep + kNumReps) + { + if (sym >= kSymbolRep) + { + if (sym != kSymbolRep) + { + size_t dist = _reps[1]; + _reps[1] = rep0; + rep0 = dist; + if (sym >= kSymbolRep + 2) + { + #if 1 + rep0 = _reps[(size_t)sym - kSymbolRep]; + _reps[(size_t)sym - kSymbolRep] = _reps[2]; + _reps[2] = dist; + #else + if (sym != kSymbolRep + 2) + { + rep0 = _reps[3]; + _reps[3] = _reps[2]; + _reps[2] = dist; + } + else + { + rep0 = _reps[2]; + _reps[2] = dist; + } + #endif + } + } +#if 0 + len = m_LenDecoder.Decode(&_bitStream); + if (len >= kLenTableSize) + LZ_LOOP_BREAK_ERROR +#else + Z7_RAR_HUFF_DECODE_CHECK_break(len, &m_LenDecoder, k_NumHufTableBits_Len, &_bitStream) +#endif + if (len >= 8) + len = SlotToLen(_bitStream, len); + len += 2; + // _lastLen = (UInt32)len; + } + else if (sym != 256) + { + len = (CLenType)_lastLen; + if (len == 0) + { + // we ignore (_lastLen == 0) case, like original-unrar. + // that case can mean error in stream. + // lzError = true; + // return S_FALSE; + continue; + } + } + else + { + _exitType = Z7_RAR_EXIT_TYPE_ADD_FILTER; + LZ_LOOP_BREAK_OK + } + } +#if 0 + else if (sym >= kMainTableSize) + LZ_LOOP_BREAK_ERROR +#endif + else + { + _reps[3] = _reps[2]; + _reps[2] = _reps[1]; + _reps[1] = rep0; + len = sym - (kSymbolRep + kNumReps); + if (len >= 8) + len = SlotToLen(_bitStream, len); + len += 2; + // _lastLen = (UInt32)len; + +#if 0 + rep0 = (UInt32)m_DistDecoder.Decode(&_bitStream); +#else + Z7_RAR_HUFF_DECODE_CHECK_break(rep0, &m_DistDecoder, k_NumHufTableBits_Dist, &_bitStream) +#endif + + if (rep0 >= 4) + { +#if 0 + if (rep0 >= kDistTableSize_MAX) + LZ_LOOP_BREAK_ERROR +#endif + const unsigned numBits = ((unsigned)rep0 - 2) >> 1; + rep0 = (2 | (rep0 & 1)) << numBits; + + const Byte *buf = _bitStream._buf; +#ifdef Z7_RAR5_USE_64BIT + const UInt64 v = GetBe64(buf); +#else + const UInt32 v = GetBe32(buf); +#endif + + // _lastLen = (UInt32)len; + if (numBits < kNumAlignBits) + { + rep0 += // _bitStream.ReadBits9(numBits); + _bitStream.ReadBits_Big25(numBits, v); + } + else + { + #if !defined(MY_CPU_AMD64) + len += k_LenPlusTable[numBits]; + #elif 0 + len += k_LenPlusTable_LOC[numBits]; + #elif 1 + len += m_LenPlusTable[numBits]; + #elif 1 && defined(MY_CPU_64BIT) && defined(MY_CPU_AMD64) + // len += (unsigned)((UInt64)0xfffffffeaa554000 >> (numBits * 2)) & 3; + len += (unsigned)((UInt64)0xfffffffffeaa5540 >> (numBits * 2 - 8)) & 3; + #elif 1 + len += 3; + len -= (unsigned)(numBits - 7) >> (sizeof(unsigned) * 8 - 1); + len -= (unsigned)(numBits - 12) >> (sizeof(unsigned) * 8 - 1); + len -= (unsigned)(numBits - 17) >> (sizeof(unsigned) * 8 - 1); + #elif 1 + len += 3; + len -= (0x155aabf >> (numBits - 4) >> (numBits - 4)) & 3; + #elif 1 + len += (numBits >= 7); + len += (numBits >= 12); + len += (numBits >= 17); + #endif + // _lastLen = (UInt32)len; + if (_useAlignBits) + { + // if (numBits > kNumAlignBits) + rep0 += (_bitStream.ReadBits_Big25(numBits - kNumAlignBits, v) << kNumAlignBits); +#if 0 + const unsigned a = m_AlignDecoder.Decode(&_bitStream); + if (a >= kAlignTableSize) + LZ_LOOP_BREAK_ERROR +#else + unsigned a; + Z7_RAR_HUFF_DECODE_CHECK_break(a, &m_AlignDecoder, k_NumHufTableBits_Align, &_bitStream) +#endif + rep0 += a; + } + else + rep0 += _bitStream.ReadBits_Big(numBits, v); +#ifndef Z7_RAR5_USE_64BIT + if (numBits >= 30) // we don't want 32-bit overflow case + rep0 = (size_t)0 - 1 - 1; +#endif + } + } + rep0++; + } + + { + _lastLen = (UInt32)len; + // len != 0 + +#ifdef Z7_RAR5_SHOW_STAT + { + size_t index = rep0; + if (index >= kNumStats1) + index = kNumStats1 - 1; + g_stats1[index]++; + g_stats2[index][len]++; + } +#endif + + Byte *dest = winPos; + winPos += len; + if (rep0 <= _dictSize_forCheck) + { + const Byte *src; + const size_t winPos_temp = (size_t)(dest - _window); + if (rep0 > winPos_temp) + { + if (_lzSize == 0) + goto error_dist; + size_t back = rep0 - winPos_temp; + // STAT_INC(g_NumOver) + src = dest + (_winSize - rep0); + if (back < len) + { + // len -= (CLenType)back; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + *dest++ = *src++; + while (--back); + src = dest - rep0; + } + } + else + src = dest - rep0; + CopyMatch(rep0, dest, src, winPos); + continue; + } + +error_dist: + // LZ_LOOP_BREAK_ERROR; + _lzError = LZ_ERROR_TYPE_DIST; + do + *dest++ = 0; + while (dest < winPos); + continue; + } + } + + LZ_RESTORE + return S_OK; + +#if 1 +decode_error: + /* + if (_bitStream._hres != S_OK) + return _bitStream._hres; + */ + LZ_RESTORE + return S_FALSE; +#endif +} + + + +/* +input conditions: + _winPos < _winSize +return: + _winPos < _winSize is expected, if (return_res == S_OK) + _winPos >= _winSize is possible in (return_res != S_OK) +*/ +HRESULT CDecoder::DecodeLZ() +{ + CBitDecoder _bitStream; + _bitStream._stream = _inStream; + _bitStream._bufBase = _inputBuf; + _bitStream.Init(); + + // _reps[*] can be larger than _winSize, if _winSize was reduced in solid stream. + size_t winPos = _winPos; + Byte *win = _window; + size_t limit; + { + size_t rem = _winSize - winPos; + if (rem > kWriteStep) + rem = kWriteStep; + limit = winPos + rem; + } + + for (;;) + { + if (winPos >= limit) + { + _winPos = winPos < _winSize ? winPos : _winSize; + // _winPos == min(winPos, _winSize) + // we will not write data after _winSize + RINOK(WriteBuf()) + if (_unpackSize_Defined && _writtenFileSize > _unpackSize) + break; // return S_FALSE; + const size_t wp = _winPos; + size_t rem = _winSize - wp; + if (rem == 0) + { + _lzSize += wp; + winPos -= wp; + // (winPos < kMaxMatchLen < _winSize) + // so memmove is not required here + if (winPos) + memcpy(win, win + _winSize, winPos); + limit = _winSize; + if (limit >= kWriteStep) + { + limit = kWriteStep; + continue; + } + rem = _winSize - winPos; + } + if (rem > kWriteStep) + rem = kWriteStep; + limit = winPos + rem; + continue; + } + + // (winPos < limit) + + if (_bitStream._buf >= _bitStream._bufCheck_Block) + { + _winPos = winPos; + if (_bitStream.InputEofError()) + break; // return S_FALSE; + _bitStream.Prepare(); + + const UInt64 processed = _bitStream.GetProcessedSize_Round(); + if (processed >= _bitStream._blockEnd) + { + if (processed > _bitStream._blockEnd) + break; // return S_FALSE; + { + const unsigned bits7 = _bitStream.GetProcessedBits7(); + if (bits7 >= _bitStream._blockEndBits7) + { + if (bits7 > _bitStream._blockEndBits7) + { +#if 1 + // we ignore thar error as original unrar + _bitStream._minorError = true; +#else + break; // return S_FALSE; +#endif + } + _bitStream.AlignToByte(); + // if (!_bitStream.AlignToByte()) break; + if (_isLastBlock) + { + if (_bitStream.InputEofError()) + break; + /* + // packSize can be 15 bytes larger for encrypted archive + if (_packSize_Defined && _packSize < _bitStream.GetProcessedSize()) + break; + */ + if (_bitStream._minorError) + return S_FALSE; + return _bitStream._hres; + // break; + } + RINOK(ReadTables(_bitStream)) + continue; + } + } + } + + // end of block was not reached. + // so we must decode more symbols + // that check is not required, but it can help, if there is BUG in another code + if (!_tableWasFilled) + break; // return S_FALSE; + } + + _limit = limit; + _winPos = winPos; + RINOK(DecodeLZ2(_bitStream)) + _bitStream._buf = _buf_Res; + _bitStream._bitPos = _bitPos_Res; + + winPos = _winPos; + if (_exitType == Z7_RAR_EXIT_TYPE_ADD_FILTER) + { + RINOK(AddFilter(_bitStream)) + continue; + } + } + + _winPos = winPos; + + if (_bitStream._hres != S_OK) + return _bitStream._hres; + + return S_FALSE; +} + + + +HRESULT CDecoder::CodeReal() +{ + _unsupportedFilter = false; + _writeError = false; + /* + if (!_isSolid || !_wasInit) + { + _wasInit = true; + // _lzSize = 0; + _lzWritten = 0; + _winPos = 0; + for (unsigned i = 0; i < kNumReps; i++) + _reps[i] = (size_t)0 - 1; + _lastLen = 0; + _tableWasFilled = false; + } + */ + _isLastBlock = false; + + InitFilters(); + + _filterEnd = 0; + _writtenFileSize = 0; + const UInt64 lzSize = _lzSize + _winPos; + _lzFileStart = lzSize; + _lzWritten = lzSize; + + HRESULT res = DecodeLZ(); + + HRESULT res2 = S_OK; + if (!_writeError && res != E_OUTOFMEMORY) + res2 = WriteBuf(); + /* + if (res == S_OK) + if (InputEofError()) + res = S_FALSE; + */ + if (res == S_OK) + { + // _solidAllowed = true; + res = res2; + } + if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) + return S_FALSE; + return res; +} + + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + _lzError = LZ_ERROR_TYPE_NO; +/* + if file is soild, but decoding of previous file was not finished, + we still try to decode new file. + We need correct huffman table at starting block. + And rar encoder probably writes huffman table at start block, if file is big. + So we have good chance to get correct huffman table in some file after corruption. + Also we try to recover window by filling zeros, if previous file + was decoded to smaller size than required. + But if filling size is big, we do full reset of window instead. +*/ + #define Z7_RAR_RECOVER_SOLID_LIMIT (1 << 20) + // #define Z7_RAR_RECOVER_SOLID_LIMIT 0 // do not fill zeros + { + // if (_winPos > 100) _winPos -= 100; // for debug: corruption + const UInt64 lzSize = _lzSize + _winPos; +/* + if previous file was decoded with error or for some another cases, then + (lzSize > _lzEnd) is possible + (_winPos > _winSize) is possible + (_winPos < _winSize + kMaxMatchLen) +*/ + if (!_window + || !_isSolid + || !_wasInit + || (lzSize < _lzEnd +#if Z7_RAR_RECOVER_SOLID_LIMIT != 0 + && lzSize + Z7_RAR_RECOVER_SOLID_LIMIT < _lzEnd +#endif + )) + { + if (_isSolid) + _lzError = LZ_ERROR_TYPE_HEADER; + _lzSize = 0; + // _lzEnd = 0; // it will be set later + // _lzWritten = 0; // it will be set later + _winPos = 0; + for (unsigned i = 0; i < kNumReps; i++) + _reps[i] = (size_t)0 - 1; + _lastLen = 0; + _tableWasFilled = false; + _wasInit = true; + } + else + { + const size_t ws = _winSize; + if (_winPos >= ws) + { + // we must normalize (_winPos) and data in _window, + _winPos -= ws; + _lzSize += ws; + // (_winPos < kMaxMatchLen < _winSize) + // if (_window) + memcpy(_window, _window + ws, _winPos); // memmove is not required here + } + +#if Z7_RAR_RECOVER_SOLID_LIMIT != 0 + if (lzSize < _lzEnd) + { +#if 0 + return S_FALSE; +#else + // we can report that recovering was made: + // _lzError = LZ_ERROR_TYPE_HEADER; + // We write zeros to area after corruption: + // if (_window) + { + UInt64 rem = _lzEnd - lzSize; + if (rem >= ws) + { + My_ZeroMemory(_window, ws); + _lzSize = ws; + _winPos = 0; + } + else + { + // rem < _winSize + // _winPos <= ws + const size_t cur = ws - _winPos; + if (cur <= rem) + { + rem -= cur; + My_ZeroMemory(_window + _winPos, cur); + _lzSize = ws; + _winPos = 0; + } + My_ZeroMemory(_window + _winPos, (size_t)rem); + _winPos += (size_t)rem; + } + } + // else return S_FALSE; +#endif + } + } +#endif + } + + // _winPos < _winSize + // we don't want _lzSize overflow + if (_lzSize >= DICT_SIZE_MAX) + _lzSize = DICT_SIZE_MAX; + _lzEnd = _lzSize + _winPos; + // _lzSize <= DICT_SIZE_MAX + // _lzEnd < DICT_SIZE_MAX + _winSize + + size_t newSize = _dictSize; + if (newSize < kWinSize_Min) + newSize = kWinSize_Min; + + _unpackSize = 0; + _unpackSize_Defined = (outSize != NULL); + if (_unpackSize_Defined) + _unpackSize = *outSize; + + if ((Int64)_unpackSize >= 0) + _lzEnd += _unpackSize; // known end after current file + else + _lzEnd = 0; // unknown end + + if (_isSolid && _window) + { + // If dictionary was decreased in solid, we use old dictionary. + if (newSize > _dictSize_forCheck) + { + // If dictionary was increased in solid, we don't want grow. + return S_FALSE; // E_OUTOFMEMORY + } + // (newSize <= _dictSize_forCheck) + } + else + { + // !_isSolid || !_window + _dictSize_forCheck = newSize; + { + size_t newSize_small = newSize; + const size_t k_Win_AlignSize = 1u << 18; + /* here we add (1 << 7) instead of (COPY_CHUNK_SIZE - 1), because + we want to get same (_winSize) for different COPY_CHUNK_SIZE values. */ + // newSize += (COPY_CHUNK_SIZE - 1) + (k_Win_AlignSize - 1); // for debug : we can get smallest (_winSize) + newSize += (1 << 7) + k_Win_AlignSize; + newSize &= ~(size_t)(k_Win_AlignSize - 1); + if (newSize < newSize_small) + return E_OUTOFMEMORY; + } + // (!_isSolid || !_window) + const size_t allocSize = newSize + kMaxMatchLen + 64; + if (allocSize < newSize) + return E_OUTOFMEMORY; + if (!_window || allocSize > _winSize_Allocated) + { + Z7_RAR_FREE_WINDOW + _window = NULL; + _winSize_Allocated = 0; + Byte *win = (Byte *)::BigAlloc(allocSize); + if (!win) + return E_OUTOFMEMORY; + _window = win; + _winSize_Allocated = allocSize; + } + _winSize = newSize; + } + + if (!_inputBuf) + { + _inputBuf = (Byte *)z7_AlignedAlloc(kInputBufSize + kInputBufferPadZone); + if (!_inputBuf) + return E_OUTOFMEMORY; + } + + _inStream = inStream; + _outStream = outStream; + _progress = progress; + _progress_Pack = 0; + _progress_Unpack = 0; + + const HRESULT res = CodeReal(); + + if (res != S_OK) + return res; + // _lzError = LZ_ERROR_TYPE_HEADER; // for debug + if (_lzError) + return S_FALSE; + if (_unsupportedFilter) + return E_NOTIMPL; + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size != 2) + return E_INVALIDARG; + const unsigned pow = data[0]; + const unsigned b1 = data[1]; + const unsigned frac = b1 >> 3; + // unsigned pow = 15 + 8; + // unsigned frac = 1; + if (pow + ((frac + 31) >> 5) > MAX_DICT_LOG - 17) + // if (frac + (pow << 8) >= ((8 * 2 + 7) << 5) + 8 / 8) + return E_NOTIMPL; + _dictSize = (size_t)(frac + 32) << (pow + 12); + _isSolid = (b1 & 1) != 0; + _is_v7 = (b1 & 2) != 0; + // printf("\ndict size = %p\n", (void *)(size_t)_dictSize); + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/Rar5Decoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/Rar5Decoder.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/Rar5Decoder.h 2024-01-07 10:00:00.000000000 +0000 @@ -1,335 +1,132 @@ -// Rar5Decoder.h -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#ifndef __COMPRESS_RAR5_DECODER_H -#define __COMPRESS_RAR5_DECODER_H - -#include "../../../C/Alloc.h" -#include "../../../C/CpuArch.h" - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyException.h" -#include "../../Common/MyVector.h" - -#include "../ICoder.h" - -#include "HuffmanDecoder.h" - -namespace NCompress { -namespace NRar5 { - -class CMidBuffer -{ - Byte *_data; - size_t _size; - - CLASS_NO_COPY(CMidBuffer) - -public: - CMidBuffer(): _data(NULL), _size(0) {}; - ~CMidBuffer() { ::MidFree(_data); } - - bool IsAllocated() const { return _data != NULL; } - operator Byte *() { return _data; } - operator const Byte *() const { return _data; } - size_t Size() const { return _size; } - - void AllocAtLeast(size_t size) - { - if (size > _size) - { - const size_t kMinSize = (1 << 16); - if (size < kMinSize) - size = kMinSize; - ::MidFree(_data); - _data = (Byte *)::MidAlloc(size); - _size = size; - } - } -}; - -/* -struct CInBufferException: public CSystemException -{ - CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} -}; -*/ - -class CBitDecoder -{ -public: - const Byte *_buf; - unsigned _bitPos; - bool _wasFinished; - Byte _blockEndBits7; - const Byte *_bufCheck2; - const Byte *_bufCheck; - Byte *_bufLim; - Byte *_bufBase; - - UInt64 _processedSize; - UInt64 _blockEnd; - - ISequentialInStream *_stream; - HRESULT _hres; - - void SetCheck2() - { - _bufCheck2 = _bufCheck; - if (_bufCheck > _buf) - { - UInt64 processed = GetProcessedSize_Round(); - if (_blockEnd < processed) - _bufCheck2 = _buf; - else - { - UInt64 delta = _blockEnd - processed; - if ((size_t)(_bufCheck - _buf) > delta) - _bufCheck2 = _buf + (size_t)delta; - } - } - } - - bool IsBlockOverRead() const - { - UInt64 v = GetProcessedSize_Round(); - if (v < _blockEnd) - return false; - if (v > _blockEnd) - return true; - return _bitPos > _blockEndBits7; - } - - /* - CBitDecoder() throw(): - _buf(0), - _bufLim(0), - _bufBase(0), - _stream(0), - _processedSize(0), - _wasFinished(false) - {} - */ - - void Init() throw() - { - _blockEnd = 0; - _blockEndBits7 = 0; - - _bitPos = 0; - _processedSize = 0; - _buf = _bufBase; - _bufLim = _bufBase; - _bufCheck = _buf; - _bufCheck2 = _buf; - _wasFinished = false; - } - - void Prepare2() throw(); - - void Prepare() throw() - { - if (_buf >= _bufCheck) - Prepare2(); - } - - bool ExtraBitsWereRead() const - { - return _buf >= _bufLim && (_buf > _bufLim || _bitPos != 0); - } - - bool InputEofError() const { return ExtraBitsWereRead(); } - - unsigned GetProcessedBits7() const { return _bitPos; } - UInt64 GetProcessedSize_Round() const { return _processedSize + (_buf - _bufBase); } - UInt64 GetProcessedSize() const { return _processedSize + (_buf - _bufBase) + ((_bitPos + 7) >> 3); } - - void AlignToByte() - { - _buf += (_bitPos + 7) >> 3; - _bitPos = 0; - } - - Byte ReadByteInAligned() - { - return *_buf++; - } - - UInt32 GetValue(unsigned numBits) - { - UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) | (UInt32)_buf[2]; - v >>= (24 - numBits - _bitPos); - return v & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - _bitPos += numBits; - _buf += (_bitPos >> 3); - _bitPos &= 7; - } - - UInt32 ReadBits9(unsigned numBits) - { - const Byte *buf = _buf; - UInt32 v = ((UInt32)buf[0] << 8) | (UInt32)buf[1]; - v &= ((UInt32)0xFFFF >> _bitPos); - numBits += _bitPos; - v >>= (16 - numBits); - _buf = buf + (numBits >> 3); - _bitPos = numBits & 7; - return v; - } - - UInt32 ReadBits9fix(unsigned numBits) - { - const Byte *buf = _buf; - UInt32 v = ((UInt32)buf[0] << 8) | (UInt32)buf[1]; - UInt32 mask = ((1 << numBits) - 1); - numBits += _bitPos; - v >>= (16 - numBits); - _buf = buf + (numBits >> 3); - _bitPos = numBits & 7; - return v & mask; - } - - UInt32 ReadBits32(unsigned numBits) - { - UInt32 mask = ((1 << numBits) - 1); - numBits += _bitPos; - const Byte *buf = _buf; - UInt32 v = GetBe32(buf); - if (numBits > 32) - { - v <<= (numBits - 32); - v |= (UInt32)buf[4] >> (40 - numBits); - } - else - v >>= (32 - numBits); - _buf = buf + (numBits >> 3); - _bitPos = numBits & 7; - return v & mask; - } -}; - - -struct CFilter -{ - Byte Type; - Byte Channels; - UInt32 Size; - UInt64 Start; -}; - - -const unsigned kNumReps = 4; -const unsigned kLenTableSize = 11 * 4; -const unsigned kMainTableSize = 256 + 1 + 1 + kNumReps + kLenTableSize; -const unsigned kDistTableSize = 64; -const unsigned kNumAlignBits = 4; -const unsigned kAlignTableSize = (1 << kNumAlignBits); -const unsigned kLevelTableSize = 20; -const unsigned kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; - -const unsigned kNumHuffmanBits = 15; - -class CDecoder: - public ICompressCoder, - public ICompressSetDecoderProperties2, - public CMyUnknownImp -{ - bool _useAlignBits; - bool _isLastBlock; - bool _unpackSize_Defined; - // bool _packSize_Defined; - - bool _unsupportedFilter; - bool _lzError; - bool _writeError; - - // CBitDecoder _bitStream; - Byte *_window; - size_t _winPos; - size_t _winSize; - size_t _winMask; - - UInt64 _lzSize; - - unsigned _numCorrectDistSymbols; - unsigned _numUnusedFilters; - - UInt64 _lzWritten; - UInt64 _lzFileStart; - UInt64 _unpackSize; - // UInt64 _packSize; - UInt64 _lzEnd; - UInt64 _writtenFileSize; - size_t _winSizeAllocated; - - Byte _dictSizeLog; - bool _tableWasFilled; - bool _isSolid; - bool _wasInit; - - UInt32 _reps[kNumReps]; - UInt32 _lastLen; - - UInt64 _filterEnd; - CMidBuffer _filterSrc; - CMidBuffer _filterDst; - - CRecordVector _filters; - - ISequentialInStream *_inStream; - ISequentialOutStream *_outStream; - ICompressProgressInfo *_progress; - Byte *_inputBuf; - - NHuffman::CDecoder m_MainDecoder; - NHuffman::CDecoder m_DistDecoder; - NHuffman::CDecoder m_AlignDecoder; - NHuffman::CDecoder m_LenDecoder; - NHuffman::CDecoder m_LevelDecoder; - - - void InitFilters() - { - _numUnusedFilters = 0; - _filters.Clear(); - } - - void DeleteUnusedFilters() - { - if (_numUnusedFilters != 0) - { - _filters.DeleteFrontal(_numUnusedFilters); - _numUnusedFilters = 0; - } - } - - HRESULT WriteData(const Byte *data, size_t size); - HRESULT ExecuteFilter(const CFilter &f); - HRESULT WriteBuf(); - HRESULT AddFilter(CBitDecoder &_bitStream); - - HRESULT ReadTables(CBitDecoder &_bitStream); - HRESULT DecodeLZ(); - HRESULT CodeReal(); - -public: - CDecoder(); - ~CDecoder(); - - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); -}; - -}} - -#endif +// Rar5Decoder.h +// According to unRAR license, this code may not be used to develop +// a program that creates RAR archives + +#ifndef ZIP7_INC_COMPRESS_RAR5_DECODER_H +#define ZIP7_INC_COMPRESS_RAR5_DECODER_H + +#include "../../Common/MyBuffer2.h" +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "HuffmanDecoder.h" + +namespace NCompress { +namespace NRar5 { + +class CBitDecoder; + +struct CFilter +{ + Byte Type; + Byte Channels; + UInt32 Size; + UInt64 Start; +}; + + +const unsigned kNumReps = 4; +const unsigned kLenTableSize = 11 * 4; +const unsigned kMainTableSize = 256 + 1 + 1 + kNumReps + kLenTableSize; +const unsigned kExtraDistSymbols_v7 = 16; +const unsigned kDistTableSize_v6 = 64; +const unsigned kDistTableSize_MAX = 64 + kExtraDistSymbols_v7; +const unsigned kNumAlignBits = 4; +const unsigned kAlignTableSize = 1 << kNumAlignBits; + +const unsigned kNumHufBits = 15; + +const unsigned k_NumHufTableBits_Main = 10; +const unsigned k_NumHufTableBits_Dist = 7; +const unsigned k_NumHufTableBits_Len = 7; +const unsigned k_NumHufTableBits_Align = 6; + +const unsigned DICT_SIZE_BITS_MAX = 40; + +Z7_CLASS_IMP_NOQIB_2( + CDecoder + , ICompressCoder + , ICompressSetDecoderProperties2 +) + bool _useAlignBits; + bool _isLastBlock; + bool _unpackSize_Defined; + // bool _packSize_Defined; + + bool _unsupportedFilter; + Byte _lzError; + bool _writeError; + + bool _isSolid; + // bool _solidAllowed; + bool _is_v7; + bool _tableWasFilled; + bool _wasInit; + + Byte _exitType; + + // Byte _dictSizeLog; + size_t _dictSize; + Byte *_window; + size_t _winPos; + size_t _winSize; + size_t _dictSize_forCheck; + size_t _limit; + const Byte *_buf_Res; + UInt64 _lzSize; + size_t _reps[kNumReps]; + unsigned _bitPos_Res; + UInt32 _lastLen; + + // unsigned _numCorrectDistSymbols; + unsigned _numUnusedFilters; + unsigned _numFilters; + + UInt64 _lzWritten; + UInt64 _lzFileStart; + UInt64 _unpackSize; + // UInt64 _packSize; + UInt64 _lzEnd; + UInt64 _writtenFileSize; + UInt64 _filterEnd; + UInt64 _progress_Pack; + UInt64 _progress_Unpack; + CAlignedBuffer _filterSrc; + CAlignedBuffer _filterDst; + + CFilter *_filters; + size_t _winSize_Allocated; + ISequentialInStream *_inStream; + ISequentialOutStream *_outStream; + ICompressProgressInfo *_progress; + Byte *_inputBuf; + + NHuffman::CDecoder m_MainDecoder; + NHuffman::CDecoder256 m_DistDecoder; + NHuffman::CDecoder256 m_AlignDecoder; + NHuffman::CDecoder256 m_LenDecoder; + Byte m_LenPlusTable[DICT_SIZE_BITS_MAX]; + + void InitFilters() + { + _numUnusedFilters = 0; + _numFilters = 0; + } + void DeleteUnusedFilters(); + HRESULT WriteData(const Byte *data, size_t size); + HRESULT ExecuteFilter(const CFilter &f); + HRESULT WriteBuf(); + HRESULT AddFilter(CBitDecoder &_bitStream); + HRESULT ReadTables(CBitDecoder &_bitStream); + HRESULT DecodeLZ2(const CBitDecoder &_bitStream) throw(); + HRESULT DecodeLZ(); + HRESULT CodeReal(); +public: + CDecoder(); + ~CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/RarCodecsRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/RarCodecsRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/RarCodecsRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/RarCodecsRegister.cpp 2016-04-25 10:21:14.000000000 +0000 @@ -1,33 +1,33 @@ -// RarCodecsRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "Rar1Decoder.h" -#include "Rar2Decoder.h" -#include "Rar3Decoder.h" -#include "Rar5Decoder.h" - -namespace NCompress { - -#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NRar ## x::CDecoder()) - -CREATE_CODEC(1) -CREATE_CODEC(2) -CREATE_CODEC(3) -CREATE_CODEC(5) - -#define RAR_CODEC(x, name) { CreateCodec ## x, NULL, 0x40300 + x, "Rar" name, 1, false } - -REGISTER_CODECS_VAR -{ - RAR_CODEC(1, "1"), - RAR_CODEC(2, "2"), - RAR_CODEC(3, "3"), - RAR_CODEC(5, "5"), -}; - -REGISTER_CODECS(Rar) - -} +// RarCodecsRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "Rar1Decoder.h" +#include "Rar2Decoder.h" +#include "Rar3Decoder.h" +#include "Rar5Decoder.h" + +namespace NCompress { + +#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NRar ## x::CDecoder()) + +CREATE_CODEC(1) +CREATE_CODEC(2) +CREATE_CODEC(3) +CREATE_CODEC(5) + +#define RAR_CODEC(x, name) { CreateCodec ## x, NULL, 0x40300 + x, "Rar" name, 1, false } + +REGISTER_CODECS_VAR +{ + RAR_CODEC(1, "1"), + RAR_CODEC(2, "2"), + RAR_CODEC(3, "3"), + RAR_CODEC(5, "5"), +}; + +REGISTER_CODECS(Rar) + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ShrinkDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ShrinkDecoder.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.cpp 2023-01-28 17:00:00.000000000 +0000 @@ -1,160 +1,244 @@ -// ShrinkDecoder.cpp - - -#include "StdAfx.h" - -#include - -#include "../../../C/Alloc.h" - -#include "../Common/InBuffer.h" -#include "../Common/OutBuffer.h" - -#include "BitlDecoder.h" -#include "ShrinkDecoder.h" - -namespace NCompress { -namespace NShrink { - -static const UInt32 kBufferSize = (1 << 18); -static const unsigned kNumMinBits = 9; - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - NBitl::CBaseDecoder inBuffer; - COutBuffer outBuffer; - - if (!inBuffer.Create(kBufferSize)) - return E_OUTOFMEMORY; - inBuffer.SetStream(inStream); - inBuffer.Init(); - - if (!outBuffer.Create(kBufferSize)) - return E_OUTOFMEMORY; - outBuffer.SetStream(outStream); - outBuffer.Init(); - - { - unsigned i; - for (i = 0; i < 257; i++) - _parents[i] = (UInt16)i; - for (; i < kNumItems; i++) - _parents[i] = kNumItems; - for (i = 0; i < kNumItems; i++) - _suffixes[i] = 0; - } - - UInt64 prevPos = 0; - unsigned numBits = kNumMinBits; - unsigned head = 257; - int lastSym = -1; - Byte lastChar2 = 0; - - for (;;) - { - UInt32 sym = inBuffer.ReadBits(numBits); - - if (inBuffer.ExtraBitsWereRead()) - break; - - if (sym == 256) - { - sym = inBuffer.ReadBits(numBits); - if (sym == 1) - { - if (numBits >= kNumMaxBits) - return S_FALSE; - numBits++; - continue; - } - if (sym != 2) - return S_FALSE; - { - unsigned i; - for (i = 257; i < kNumItems; i++) - _stack[i] = 0; - for (i = 257; i < kNumItems; i++) - { - unsigned par = _parents[i]; - if (par != kNumItems) - _stack[par] = 1; - } - for (i = 257; i < kNumItems; i++) - if (_stack[i] == 0) - _parents[i] = kNumItems; - - head = 257; - - continue; - } - } - - bool needPrev = false; - if (head < kNumItems && lastSym >= 0) - { - while (head < kNumItems && _parents[head] != kNumItems) - head++; - if (head < kNumItems) - { - if (head == (unsigned)lastSym) - { - // we need to fix the code for that case - // _parents[head] is not allowed to link to itself - return E_NOTIMPL; - } - needPrev = true; - _parents[head] = (UInt16)lastSym; - _suffixes[head] = (Byte)lastChar2; - head++; - } - } - - if (_parents[sym] == kNumItems) - return S_FALSE; - - lastSym = sym; - unsigned cur = sym; - unsigned i = 0; - - while (cur >= 256) - { - _stack[i++] = _suffixes[cur]; - cur = _parents[cur]; - } - - _stack[i++] = (Byte)cur; - lastChar2 = (Byte)cur; - - if (needPrev) - _suffixes[head - 1] = (Byte)cur; - - do - outBuffer.WriteByte(_stack[--i]); - while (i); - - if (progress) - { - const UInt64 nowPos = outBuffer.GetProcessedSize(); - if (nowPos - prevPos >= (1 << 18)) - { - prevPos = nowPos; - const UInt64 packSize = inBuffer.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &nowPos)); - } - } - } - - return outBuffer.Flush(); -} - -STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -}} +// ShrinkDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +#include "BitlDecoder.h" +#include "ShrinkDecoder.h" + +namespace NCompress { +namespace NShrink { + +static const UInt32 kEmpty = 256; // kNumItems; +static const UInt32 kBufferSize = (1 << 18); +static const unsigned kNumMinBits = 9; + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) +{ + NBitl::CBaseDecoder inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + + inBuffer.SetStream(inStream); + inBuffer.Init(); + + outBuffer.SetStream(outStream); + outBuffer.Init(); + + { + for (unsigned i = 0; i < kNumItems; i++) + _parents[i] = kEmpty; + } + + UInt64 outPrev = 0, inPrev = 0; + unsigned numBits = kNumMinBits; + unsigned head = 257; + int lastSym = -1; + Byte lastChar = 0; + bool moreOut = false; + + HRESULT res = S_FALSE; + + for (;;) + { + _inProcessed = inBuffer.GetProcessedSize(); + const UInt64 nowPos = outBuffer.GetProcessedSize(); + + bool eofCheck = false; + + if (outSize && nowPos >= *outSize) + { + if (!_fullStreamMode || moreOut) + { + res = S_OK; + break; + } + eofCheck = true; + // Is specSym(=256) allowed after end of stream ? + // Do we need to read it here ? + } + + if (progress) + { + if (nowPos - outPrev >= (1 << 20) || _inProcessed - inPrev >= (1 << 20)) + { + outPrev = nowPos; + inPrev = _inProcessed; + res = progress->SetRatioInfo(&_inProcessed, &nowPos); + if (res != SZ_OK) + { + // break; + return res; + } + } + } + + UInt32 sym = inBuffer.ReadBits(numBits); + + if (inBuffer.ExtraBitsWereRead()) + { + res = S_OK; + break; + } + + if (sym == 256) + { + sym = inBuffer.ReadBits(numBits); + + if (inBuffer.ExtraBitsWereRead()) + break; + + if (sym == 1) + { + if (numBits >= kNumMaxBits) + break; + numBits++; + continue; + } + if (sym != 2) + { + break; + // continue; // info-zip just ignores such code + } + { + /* + ---------- Free leaf nodes ---------- + Note : that code can mark _parents[lastSym] as free, and next + inserted node will be Orphan in that case. + */ + + unsigned i; + for (i = 256; i < kNumItems; i++) + _stack[i] = 0; + for (i = 257; i < kNumItems; i++) + { + unsigned par = _parents[i]; + if (par != kEmpty) + _stack[par] = 1; + } + for (i = 257; i < kNumItems; i++) + if (_stack[i] == 0) + _parents[i] = kEmpty; + head = 257; + continue; + } + } + + if (eofCheck) + { + // It's can be error case. + // That error can be detected later in (*inSize != _inProcessed) check. + res = S_OK; + break; + } + + bool needPrev = false; + if (head < kNumItems && lastSym >= 0) + { + while (head < kNumItems && _parents[head] != kEmpty) + head++; + if (head < kNumItems) + { + /* + if (head == lastSym), it updates Orphan to self-linked Orphan and creates two problems: + 1) we must check _stack[i++] overflow in code that walks tree nodes. + 2) self-linked node can not be removed. So such self-linked nodes can occupy all _parents items. + */ + needPrev = true; + _parents[head] = (UInt16)lastSym; + _suffixes[head] = (Byte)lastChar; + head++; + } + } + + lastSym = (int)sym; + unsigned cur = sym; + unsigned i = 0; + + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + // don't change that code: + // Orphan Check and self-linked Orphan check (_stack overflow check); + if (cur == kEmpty || i >= kNumItems) + break; + } + + if (cur == kEmpty || i >= kNumItems) + break; + + _stack[i++] = (Byte)cur; + lastChar = (Byte)cur; + + if (needPrev) + _suffixes[(size_t)head - 1] = (Byte)cur; + + if (outSize) + { + const UInt64 limit = *outSize - nowPos; + if (i > limit) + { + moreOut = true; + i = (unsigned)limit; + } + } + + do + outBuffer.WriteByte(_stack[--i]); + while (i); + } + + RINOK(outBuffer.Flush()) + + if (res == S_OK) + if (_fullStreamMode) + { + if (moreOut) + res = S_FALSE; + const UInt64 nowPos = outBuffer.GetProcessedSize(); + if (outSize && *outSize != nowPos) + res = S_FALSE; + if (inSize && *inSize != _inProcessed) + res = S_FALSE; + } + + return res; +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + // catch(const CInBufferException &e) { return e.ErrorCode; } + // catch(const COutBufferException &e) { return e.ErrorCode; } + catch(const CSystemException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + _fullStreamMode = (finishMode != 0); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ShrinkDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ShrinkDecoder.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ShrinkDecoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,36 +1,35 @@ -// ShrinkDecoder.h - -#ifndef __COMPRESS_SHRINK_DECODER_H -#define __COMPRESS_SHRINK_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NShrink { - -const unsigned kNumMaxBits = 13; -const unsigned kNumItems = 1 << kNumMaxBits; - -class CDecoder : - public ICompressCoder, - public CMyUnknownImp -{ - UInt16 _parents[kNumItems]; - Byte _suffixes[kNumItems]; - Byte _stack[kNumItems]; - -public: - MY_UNKNOWN_IMP - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); -}; - -}} - -#endif +// ShrinkDecoder.h + +#ifndef ZIP7_INC_COMPRESS_SHRINK_DECODER_H +#define ZIP7_INC_COMPRESS_SHRINK_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NShrink { + +const unsigned kNumMaxBits = 13; +const unsigned kNumItems = 1 << kNumMaxBits; + +Z7_CLASS_IMP_NOQIB_3( + CDecoder + , ICompressCoder + , ICompressSetFinishMode + , ICompressGetInStreamProcessedSize +) + bool _fullStreamMode; + UInt64 _inProcessed; + + UInt16 _parents[kNumItems]; + Byte _suffixes[kNumItems]; + Byte _stack[kNumItems]; + + HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Compress/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XpressDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/XpressDecoder.cpp 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.cpp 2024-01-05 08:00:00.000000000 +0000 @@ -1,129 +1,399 @@ -// XpressDecoder.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/CpuArch.h" - -#include "HuffmanDecoder.h" - -namespace NCompress { -namespace NXpress { - -struct CBitStream -{ - UInt32 Value; - unsigned BitPos; - - UInt32 GetValue(unsigned numBits) const - { - return (Value >> (BitPos - numBits)) & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) - { - BitPos -= numBits; - } -}; - -#define BIT_STREAM_NORMALIZE \ - if (bs.BitPos < 16) { \ - if (in >= lim) return S_FALSE; \ - bs.Value = (bs.Value << 16) | GetUi16(in); \ - in += 2; bs.BitPos += 16; } - -const unsigned kNumHuffBits = 15; -const unsigned kNumLenSlots = 16; -const unsigned kNumPosSlots = 16; -const unsigned kNumSyms = 256 + kNumPosSlots * kNumLenSlots; - -HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) -{ - NCompress::NHuffman::CDecoder huff; - - if (inSize < kNumSyms / 2 + 4) - return S_FALSE; - { - Byte levels[kNumSyms]; - for (unsigned i = 0; i < kNumSyms / 2; i++) - { - Byte b = in[i]; - levels[i * 2] = (Byte)(b & 0xF); - levels[i * 2 + 1] = (Byte)(b >> 4); - } - if (!huff.BuildFull(levels)) - return S_FALSE; - } - - - CBitStream bs; - - const Byte *lim = in + inSize - 1; - - in += kNumSyms / 2; - bs.Value = (GetUi16(in) << 16) | GetUi16(in + 2); - in += 4; - bs.BitPos = 32; - - size_t pos = 0; - - for (;;) - { - // printf("\n%d", pos); - UInt32 sym = huff.DecodeFull(&bs); - // printf(" sym = %d", sym); - BIT_STREAM_NORMALIZE - - if (pos >= outSize) - return (sym == 256 && in == lim + 1) ? S_OK : S_FALSE; - - if (sym < 256) - out[pos++] = (Byte)sym; - else - { - sym -= 256; - UInt32 dist = sym / kNumLenSlots; - UInt32 len = sym & (kNumLenSlots - 1); - - if (len == kNumLenSlots - 1) - { - if (in > lim) - return S_FALSE; - len = *in++; - if (len == 0xFF) - { - if (in >= lim) - return S_FALSE; - len = GetUi16(in); - in += 2; - } - else - len += kNumLenSlots - 1; - } - - bs.BitPos -= dist; - dist = (UInt32)1 << dist; - dist += ((bs.Value >> bs.BitPos) & (dist - 1)); - - BIT_STREAM_NORMALIZE - - if (len > outSize - pos) - return S_FALSE; - if (dist > pos) - return S_FALSE; - - Byte *dest = out + pos; - const Byte *src = dest - dist; - pos += len + 3; - len += 1; - *dest++ = *src++; - *dest++ = *src++; - do - *dest++ = *src++; - while (--len); - } - } -} - -}} +// XpressDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/RotateDefs.h" + +#include "HuffmanDecoder.h" +#include "XpressDecoder.h" + +#ifdef MY_CPU_LE_UNALIGN + #define Z7_XPRESS_DEC_USE_UNALIGNED_COPY +#endif + +#ifdef Z7_XPRESS_DEC_USE_UNALIGNED_COPY + + #define COPY_CHUNK_SIZE 16 + + #define COPY_CHUNK_4_2(dest, src) \ + { \ + ((UInt32 *)(void *)dest)[0] = ((const UInt32 *)(const void *)src)[0]; \ + ((UInt32 *)(void *)dest)[1] = ((const UInt32 *)(const void *)src)[1]; \ + src += 4 * 2; \ + dest += 4 * 2; \ + } + + /* sse2 doesn't help here in GCC and CLANG. + so we disabled sse2 here */ +#if 0 + #if defined(MY_CPU_AMD64) + #define Z7_XPRESS_DEC_USE_SSE2 + #elif defined(MY_CPU_X86) + #if defined(_MSC_VER) && _MSC_VER >= 1300 && defined(_M_IX86_FP) && (_M_IX86_FP >= 2) \ + || defined(__SSE2__) \ + // || 1 == 1 // for debug only + #define Z7_XPRESS_DEC_USE_SSE2 + #endif + #endif +#endif + + #if defined(MY_CPU_ARM64) + #include + #define COPY_OFFSET_MIN 16 + #define COPY_CHUNK1(dest, src) \ + { \ + vst1q_u8((uint8_t *)(void *)dest, \ + vld1q_u8((const uint8_t *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= dest_lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(Z7_XPRESS_DEC_USE_SSE2) + #include // sse2 + #define COPY_OFFSET_MIN 16 + + #define COPY_CHUNK1(dest, src) \ + { \ + _mm_storeu_si128((__m128i *)(void *)dest, \ + _mm_loadu_si128((const __m128i *)(const void *)src)); \ + src += 16; \ + dest += 16; \ + } + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK1(dest, src) \ + if (dest >= dest_lim) break; \ + COPY_CHUNK1(dest, src) \ + } + + #elif defined(MY_CPU_64BIT) + #define COPY_OFFSET_MIN 8 + + #define COPY_CHUNK(dest, src) \ + { \ + ((UInt64 *)(void *)dest)[0] = ((const UInt64 *)(const void *)src)[0]; \ + ((UInt64 *)(void *)dest)[1] = ((const UInt64 *)(const void *)src)[1]; \ + src += 8 * 2; \ + dest += 8 * 2; \ + } + + #else + #define COPY_OFFSET_MIN 4 + + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_4_2(dest, src); \ + COPY_CHUNK_4_2(dest, src); \ + } + + #endif +#endif + + +#ifndef COPY_CHUNK_SIZE + #define COPY_OFFSET_MIN 4 + #define COPY_CHUNK_SIZE 8 + #define COPY_CHUNK_2(dest, src) \ + { \ + const Byte a0 = src[0]; \ + const Byte a1 = src[1]; \ + dest[0] = a0; \ + dest[1] = a1; \ + src += 2; \ + dest += 2; \ + } + #define COPY_CHUNK(dest, src) \ + { \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + COPY_CHUNK_2(dest, src) \ + } +#endif + + +#define COPY_CHUNKS \ +{ \ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + do { COPY_CHUNK(dest, src) } \ + while (dest < dest_lim); \ +} + + +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch_1(Byte *dest, const Byte *dest_lim) +{ + const unsigned b0 = dest[-1]; + { +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) && (COPY_CHUNK_SIZE == 16) + #if defined(MY_CPU_64BIT) + { + const UInt64 v64 = (UInt64)b0 * 0x0101010101010101; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + ((UInt64 *)(void *)dest)[0] = v64; + ((UInt64 *)(void *)dest)[1] = v64; + dest += 16; + } + while (dest < dest_lim); + } + #else + { + UInt32 v = b0; + v |= v << 8; + v |= v << 16; + do + { + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + ((UInt32 *)(void *)dest)[0] = v; + ((UInt32 *)(void *)dest)[1] = v; + dest += 8; + } + while (dest < dest_lim); + } + #endif +#else + do + { + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + dest[0] = (Byte)b0; + dest[1] = (Byte)b0; + dest += 2; + } + while (dest < dest_lim); +#endif + } +} + + +// (offset != 1) +static +Z7_FORCE_INLINE +// Z7_ATTRIB_NO_VECTOR +void CopyMatch_Non1(Byte *dest, size_t offset, const Byte *dest_lim) +{ + const Byte *src = dest - offset; + { + // (COPY_OFFSET_MIN >= 4) + if (offset >= COPY_OFFSET_MIN) + { + COPY_CHUNKS + // return; + } + else +#if (COPY_OFFSET_MIN > 4) + #if COPY_CHUNK_SIZE < 8 + #error Stop_Compiling_Bad_COPY_CHUNK_SIZE + #endif + if (offset >= 4) + { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + COPY_CHUNK_4_2(dest, src) + #if COPY_CHUNK_SIZE != 16 + if (dest >= dest_lim) break; + #endif + COPY_CHUNK_4_2(dest, src) + } + while (dest < dest_lim); + // return; + } + else +#endif + { + // (offset < 4) + if (offset == 2) + { +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) + UInt32 w0 = GetUi16(src); + w0 += w0 << 16; + do + { + SetUi32(dest, w0) + dest += 4; + } + while (dest < dest_lim); +#else + const unsigned b0 = src[0]; + const Byte b1 = src[1]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest += 2; + } + while (dest < dest_lim); +#endif + } + else // (offset == 3) + { + const unsigned b0 = src[0]; +#if defined(Z7_XPRESS_DEC_USE_UNALIGNED_COPY) + const unsigned w1 = GetUi16(src + 1); + do + { + dest[0] = (Byte)b0; + SetUi16(dest + 1, (UInt16)w1) + dest += 3; + } + while (dest < dest_lim); +#else + const Byte b1 = src[1]; + const Byte b2 = src[2]; + do + { + dest[0] = (Byte)b0; + dest[1] = b1; + dest[2] = b2; + dest += 3; + } + while (dest < dest_lim); +#endif + } + } + } +} + + +namespace NCompress { +namespace NXpress { + +#define BIT_STREAM_NORMALIZE \ + if (BitPos > 16) { \ + if (in >= lim) return S_FALSE; \ + BitPos -= 16; \ + Value |= (UInt32)GetUi16(in) << BitPos; \ + in += 2; } + +#define MOVE_POS(bs, numBits) \ + BitPos += (unsigned)numBits; \ + Value <<= numBits; \ + + +static const unsigned kNumHuffBits = 15; +static const unsigned kNumTableBits = 10; +static const unsigned kNumLenBits = 4; +static const unsigned kLenMask = (1 << kNumLenBits) - 1; +static const unsigned kNumPosSlots = 16; +static const unsigned kNumSyms = 256 + (kNumPosSlots << kNumLenBits); + +HRESULT Decode_WithExceedWrite(const Byte *in, size_t inSize, Byte *out, size_t outSize) +{ + NCompress::NHuffman::CDecoder huff; + + if (inSize < kNumSyms / 2 + 4) + return S_FALSE; + { + Byte levels[kNumSyms]; + for (unsigned i = 0; i < kNumSyms / 2; i++) + { + const unsigned b = in[i]; + levels[(size_t)i * 2 ] = (Byte)(b & 0xf); + levels[(size_t)i * 2 + 1] = (Byte)(b >> 4); + } + if (!huff.Build(levels, NHuffman::k_BuildMode_Full)) + return S_FALSE; + } + + UInt32 Value; + unsigned BitPos; // how many bits in (Value) were processed + + const Byte *lim = in + inSize - 1; // points to last byte + in += kNumSyms / 2; +#ifdef MY_CPU_LE_UNALIGN + Value = GetUi32(in); + Value = rotlFixed(Value, 16); +#else + Value = ((UInt32)GetUi16(in) << 16) | GetUi16(in + 2); +#endif + + in += 4; + BitPos = 0; + Byte *dest = out; + const Byte *outLim = out + outSize; + + for (;;) + { + unsigned sym; + Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, &huff, kNumHuffBits, kNumTableBits, + Value, Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {}, MOVE_POS, {}, bs) + // 0 < BitPos <= 31 + BIT_STREAM_NORMALIZE + // 0 < BitPos <= 16 + + if (dest >= outLim) + return (sym == 256 && Value == 0 && in == lim + 1) ? S_OK : S_FALSE; + + if (sym < 256) + *dest++ = (Byte)sym; + else + { + const unsigned distBits = (unsigned)(Byte)sym >> kNumLenBits; // (sym - 256) >> kNumLenBits; + UInt32 len = (UInt32)(sym & kLenMask); + + if (len == kLenMask) + { + if (in > lim) + return S_FALSE; + // here we read input bytes in out-of-order related to main input stream (bits in Value): + len = *in++; + if (len == 0xff) + { + if (in >= lim) + return S_FALSE; + len = GetUi16(in); + in += 2; + } + else + len += kLenMask; + } + + len += 3; + if (len > (size_t)(outLim - dest)) + return S_FALSE; + + if (distBits == 0) + { + // d == 1 + if (dest == out) + return S_FALSE; + Byte *destTemp = dest; + dest += len; + CopyMatch_1(destTemp, dest); + } + else + { + unsigned d = (unsigned)(Value >> (32 - distBits)); + MOVE_POS(bs, distBits) + d += 1u << distBits; + // 0 < BitPos <= 31 + BIT_STREAM_NORMALIZE + // 0 < BitPos <= 16 + if (d > (size_t)(dest - out)) + return S_FALSE; + Byte *destTemp = dest; + dest += len; + CopyMatch_Non1(destTemp, d, dest); + } + } + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XpressDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/XpressDecoder.h 2015-09-17 19:02:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XpressDecoder.h 2024-01-01 10:00:00.000000000 +0000 @@ -1,13 +1,18 @@ -// XpressDecoder.h - -#ifndef __XPRESS_DECODER_H -#define __XPRESS_DECODER_H - -namespace NCompress { -namespace NXpress { - -HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize); - -}} - -#endif +// XpressDecoder.h + +#ifndef ZIP7_INC_XPRESS_DECODER_H +#define ZIP7_INC_XPRESS_DECODER_H + +#include "../../Common/MyTypes.h" + +namespace NCompress { +namespace NXpress { + +// (out) buffer size must be larger than (outSize) for the following value: +const unsigned kAdditionalOutputBufSize = 32; + +HRESULT Decode_WithExceedWrite(const Byte *in, size_t inSize, Byte *out, size_t outSize); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XzDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/XzDecoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -0,0 +1,151 @@ +// XzDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" + +#include "XzDecoder.h" + +namespace NCompress { +namespace NXz { + +#define RET_IF_WRAP_ERROR_CONFIRMED(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK && sRes == sResErrorCode) return wrapRes; + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +static HRESULT SResToHRESULT_Code(SRes res) throw() +{ + if (res < 0) + return res; + switch (res) + { + case SZ_OK: return S_OK; + case SZ_ERROR_MEM: return E_OUTOFMEMORY; + case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL; + default: break; + } + return S_FALSE; +} + + +HRESULT CDecoder::Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, + const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *progress) +{ + MainDecodeSRes = SZ_OK; + MainDecodeSRes_wasUsed = false; + XzStatInfo_Clear(&Stat); + + if (!xz) + { + xz = XzDecMt_Create(&g_Alloc, &g_MidAlloc); + if (!xz) + return E_OUTOFMEMORY; + } + + CXzDecMtProps props; + XzDecMtProps_Init(&props); + + int isMT = False; + + #ifndef Z7_ST + { + props.numThreads = 1; + const UInt32 numThreads = _numThreads; + + if (_tryMt && numThreads > 1) + { + size_t memUsage = (size_t)_memUsage; + if (memUsage != _memUsage) + memUsage = (size_t)0 - 1; + props.memUseMax = memUsage; + isMT = (numThreads > 1); + } + + props.numThreads = numThreads; + } + #endif + + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(seqInStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = XzDecMt_Decode(xz, + &props, + outSizeLimit, finishStream, + &outWrap.vt, + &inWrap.vt, + &Stat, + &isMT, + progress ? &progressWrap.vt : NULL); + + MainDecodeSRes = res; + + #ifndef Z7_ST + // _tryMt = isMT; + #endif + + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + RET_IF_WRAP_ERROR_CONFIRMED(inWrap.Res, res, SZ_ERROR_READ) + + // return E_OUTOFMEMORY; // for debug check + + MainDecodeSRes_wasUsed = true; + + if (res == SZ_OK && finishStream) + { + /* + if (inSize && *inSize != Stat.PhySize) + res = SZ_ERROR_DATA; + */ + if (outSizeLimit && *outSizeLimit != outWrap.Processed) + res = SZ_ERROR_DATA; + } + + return SResToHRESULT_Code(res); +} + + +Z7_COM7F_IMF(CComDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + return Decode(inStream, outStream, outSize, _finishStream, progress); +} + +Z7_COM7F_IMF(CComDecoder::SetFinishMode(UInt32 finishMode)) +{ + _finishStream = (finishMode != 0); + return S_OK; +} + +Z7_COM7F_IMF(CComDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = Stat.InSize; + return S_OK; +} + +#ifndef Z7_ST + +Z7_COM7F_IMF(CComDecoder::SetNumberOfThreads(UInt32 numThreads)) +{ + _numThreads = numThreads; + return S_OK; +} + +Z7_COM7F_IMF(CComDecoder::SetMemLimit(UInt64 memUsage)) +{ + _memUsage = memUsage; + return S_OK; +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XzDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/XzDecoder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzDecoder.h 2023-02-01 10:00:00.000000000 +0000 @@ -0,0 +1,86 @@ +// XzDecoder.h + +#ifndef ZIP7_INC_XZ_DECODER_H +#define ZIP7_INC_XZ_DECODER_H + +#include "../../../C/Xz.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NXz { + +struct CDecoder +{ + CXzDecMtHandle xz; + int _tryMt; + UInt32 _numThreads; + UInt64 _memUsage; + + SRes MainDecodeSRes; // it's not HRESULT + bool MainDecodeSRes_wasUsed; + CXzStatInfo Stat; + + CDecoder(): + xz(NULL), + _tryMt(True), + _numThreads(1), + _memUsage((UInt64)(sizeof(size_t)) << 28), + MainDecodeSRes(SZ_OK), + MainDecodeSRes_wasUsed(false) + {} + + ~CDecoder() + { + if (xz) + XzDecMt_Destroy(xz); + } + + /* Decode() can return S_OK, if there is data after good xz streams, and that data is not new xz stream. + check also (Stat.DataAfterEnd) flag */ + + HRESULT Decode(ISequentialInStream *seqInStream, ISequentialOutStream *outStream, + const UInt64 *outSizeLimit, bool finishStream, ICompressProgressInfo *compressProgress); +}; + + +class CComDecoder Z7_final: + public ICompressCoder, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + #ifndef Z7_ST + public ICompressSetCoderMt, + public ICompressSetMemLimit, + #endif + public CMyUnknownImp, + public CDecoder +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_COM_QI_ENTRY(ICompressSetCoderMt) + Z7_COM_QI_ENTRY(ICompressSetMemLimit) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + #ifndef Z7_ST + Z7_IFACE_COM7_IMP(ICompressSetCoderMt) + Z7_IFACE_COM7_IMP(ICompressSetMemLimit) + #endif + + bool _finishStream; + +public: + CComDecoder(): _finishStream(false) {} +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XzEncoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/XzEncoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.cpp 2024-01-01 18:00:00.000000000 +0000 @@ -0,0 +1,243 @@ +// XzEncoder.cpp + +#include "StdAfx.h" + +#include "../../../C/Alloc.h" + +#include "../../Common/MyString.h" +#include "../../Common/StringToInt.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "XzEncoder.h" + +namespace NCompress { + +namespace NLzma2 { +HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props); +} + +namespace NXz { + +void CEncoder::InitCoderProps() +{ + XzProps_Init(&xzProps); +} + +CEncoder::CEncoder() +{ + XzProps_Init(&xzProps); + _encoder = NULL; + _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc); + if (!_encoder) + throw 1; +} + +CEncoder::~CEncoder() +{ + if (_encoder) + XzEnc_Destroy(_encoder); +} + + +struct CMethodNamePair +{ + UInt32 Id; + const char *Name; +}; + +static const CMethodNamePair g_NamePairs[] = +{ + { XZ_ID_Delta, "Delta" }, + { XZ_ID_X86, "BCJ" }, + { XZ_ID_PPC, "PPC" }, + { XZ_ID_IA64, "IA64" }, + { XZ_ID_ARM, "ARM" }, + { XZ_ID_ARMT, "ARMT" }, + { XZ_ID_SPARC, "SPARC" } + // { XZ_ID_LZMA2, "LZMA2" } +}; + +static int FilterIdFromName(const wchar_t *name) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++) + { + const CMethodNamePair &pair = g_NamePairs[i]; + if (StringsAreEqualNoCase_Ascii(name, pair.Name)) + return (int)pair.Id; + } + return -1; +} + + +HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes) +{ + unsigned id; + switch (checkSizeInBytes) + { + case 0: id = XZ_CHECK_NO; break; + case 4: id = XZ_CHECK_CRC32; break; + case 8: id = XZ_CHECK_CRC64; break; + case 32: id = XZ_CHECK_SHA256; break; + default: return E_INVALIDARG; + } + xzProps.checkId = id; + return S_OK; +} + + +HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop) +{ + if (propID == NCoderPropID::kNumThreads) + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + xzProps.numTotalThreads = (int)(prop.ulVal); + return S_OK; + } + + if (propID == NCoderPropID::kCheckSize) + { + if (prop.vt != VT_UI4) + return E_INVALIDARG; + return SetCheckSize(prop.ulVal); + } + + if (propID == NCoderPropID::kBlockSize2) + { + if (prop.vt == VT_UI4) + xzProps.blockSize = prop.ulVal; + else if (prop.vt == VT_UI8) + xzProps.blockSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kReduceSize) + { + if (prop.vt == VT_UI8) + xzProps.reduceSize = prop.uhVal.QuadPart; + else + return E_INVALIDARG; + return S_OK; + } + + if (propID == NCoderPropID::kFilter) + { + if (prop.vt == VT_UI4) + { + const UInt32 id32 = prop.ulVal; + if (id32 == XZ_ID_Delta) + return E_INVALIDARG; + xzProps.filterProps.id = prop.ulVal; + } + else + { + if (prop.vt != VT_BSTR) + return E_INVALIDARG; + + const wchar_t *name = prop.bstrVal; + const wchar_t *end; + + UInt32 id32 = ConvertStringToUInt32(name, &end); + + if (end != name) + name = end; + else + { + if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta")) + { + name += 5; // strlen("Delta"); + id32 = XZ_ID_Delta; + } + else + { + const int filterId = FilterIdFromName(prop.bstrVal); + if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */) + return E_INVALIDARG; + id32 = (UInt32)(unsigned)filterId; + } + } + + if (id32 == XZ_ID_Delta) + { + const wchar_t c = *name; + if (c != '-' && c != ':') + return E_INVALIDARG; + name++; + const UInt32 delta = ConvertStringToUInt32(name, &end); + if (end == name || *end != 0 || delta == 0 || delta > 256) + return E_INVALIDARG; + xzProps.filterProps.delta = delta; + } + + xzProps.filterProps.id = id32; + } + + return S_OK; + } + + return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + XzProps_Init(&xzProps); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetCoderProp(propIDs[i], coderProps[i])) + } + + return S_OK; + // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps)); +} + + +Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs, + const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + const PROPVARIANT &prop = coderProps[i]; + const PROPID propID = propIDs[i]; + if (propID == NCoderPropID::kExpectedDataSize) + if (prop.vt == VT_UI8) + XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart); + } + return S_OK; +} + + +#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \ + if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes; + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + CSeqInStreamWrap inWrap; + CSeqOutStreamWrap outWrap; + CCompressProgressWrap progressWrap; + + inWrap.Init(inStream); + outWrap.Init(outStream); + progressWrap.Init(progress); + + SRes res = XzEnc_SetProps(_encoder, &xzProps); + if (res == SZ_OK) + res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL); + + // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL); + + RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ) + RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE) + RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS) + + return SResToHRESULT(res); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/XzEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/XzEncoder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/XzEncoder.h 2023-03-28 18:00:00.000000000 +0000 @@ -0,0 +1,35 @@ +// XzEncoder.h + +#ifndef ZIP7_INC_XZ_ENCODER_H +#define ZIP7_INC_XZ_ENCODER_H + +#include "../../../C/XzEnc.h" + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NXz { + +Z7_CLASS_IMP_COM_3( + CEncoder + , ICompressCoder + , ICompressSetCoderProperties + , ICompressSetCoderPropertiesOpt +) + CXzEncHandle _encoder; +public: + CXzProps xzProps; + + void InitCoderProps(); + HRESULT SetCheckSize(UInt32 checkSizeInBytes); + HRESULT SetCoderProp(PROPID propID, const PROPVARIANT &prop); + + CEncoder(); + ~CEncoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ZDecoder.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.cpp 2023-12-19 17:00:00.000000000 +0000 @@ -1,237 +1,235 @@ -// ZDecoder.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../C/Alloc.h" - -#include "../Common/InBuffer.h" -#include "../Common/OutBuffer.h" - -#include "ZDecoder.h" - -namespace NCompress { -namespace NZ { - -static const UInt32 kBufferSize = (1 << 20); -static const Byte kNumBitsMask = 0x1F; -static const Byte kBlockModeMask = 0x80; -static const unsigned kNumMinBits = 9; -static const unsigned kNumMaxBits = 16; - -void CDecoder::Free() -{ - MyFree(_parents); _parents = 0; - MyFree(_suffixes); _suffixes = 0; - MyFree(_stack); _stack = 0; -} - -CDecoder::~CDecoder() { Free(); } - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - CInBuffer inBuffer; - COutBuffer outBuffer; - - PackSize = 0; - - if (!inBuffer.Create(kBufferSize)) - return E_OUTOFMEMORY; - inBuffer.SetStream(inStream); - inBuffer.Init(); - - if (!outBuffer.Create(kBufferSize)) - return E_OUTOFMEMORY; - outBuffer.SetStream(outStream); - outBuffer.Init(); - - Byte buf[kNumMaxBits + 4]; - { - if (inBuffer.ReadBytes(buf, 3) < 3) - return S_FALSE; - if (buf[0] != 0x1F || buf[1] != 0x9D) - return S_FALSE;; - } - Byte prop = buf[2]; - - if ((prop & 0x60) != 0) - return S_FALSE; - unsigned maxbits = prop & kNumBitsMask; - if (maxbits < kNumMinBits || maxbits > kNumMaxBits) - return S_FALSE; - UInt32 numItems = 1 << maxbits; - // Speed optimization: blockSymbol can contain unused velue. - - if (maxbits != _numMaxBits || _parents == 0 || _suffixes == 0 || _stack == 0) - { - Free(); - _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); if (_parents == 0) return E_OUTOFMEMORY; - _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (_suffixes == 0) return E_OUTOFMEMORY; - _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (_stack == 0) return E_OUTOFMEMORY; - _numMaxBits = maxbits; - } - - UInt64 prevPos = 0; - UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); - unsigned numBits = kNumMinBits; - UInt32 head = (blockSymbol == 256) ? 257 : 256; - bool needPrev = false; - unsigned bitPos = 0; - unsigned numBufBits = 0; - - _parents[256] = 0; // virus protection - _suffixes[256] = 0; - HRESULT res = S_OK; - - for (;;) - { - if (numBufBits == bitPos) - { - numBufBits = (unsigned)inBuffer.ReadBytes(buf, numBits) * 8; - bitPos = 0; - UInt64 nowPos = outBuffer.GetProcessedSize(); - if (progress && nowPos - prevPos >= (1 << 13)) - { - prevPos = nowPos; - UInt64 packSize = inBuffer.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &nowPos)); - } - } - unsigned bytePos = bitPos >> 3; - UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16); - symbol >>= (bitPos & 7); - symbol &= (1 << numBits) - 1; - bitPos += numBits; - if (bitPos > numBufBits) - break; - if (symbol >= head) - { - res = S_FALSE; - break; - } - if (symbol == blockSymbol) - { - numBufBits = bitPos = 0; - numBits = kNumMinBits; - head = 257; - needPrev = false; - continue; - } - UInt32 cur = symbol; - unsigned i = 0; - while (cur >= 256) - { - _stack[i++] = _suffixes[cur]; - cur = _parents[cur]; - } - _stack[i++] = (Byte)cur; - if (needPrev) - { - _suffixes[head - 1] = (Byte)cur; - if (symbol == head - 1) - _stack[0] = (Byte)cur; - } - do - outBuffer.WriteByte((_stack[--i])); - while (i > 0); - if (head < numItems) - { - needPrev = true; - _parents[head++] = (UInt16)symbol; - if (head > ((UInt32)1 << numBits)) - { - if (numBits < maxbits) - { - numBufBits = bitPos = 0; - numBits++; - } - } - } - else - needPrev = false; - } - PackSize = inBuffer.GetProcessedSize(); - HRESULT res2 = outBuffer.Flush(); - return (res == S_OK) ? res2 : res; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -bool CheckStream(const Byte *data, size_t size) -{ - if (size < 3) - return false; - if (data[0] != 0x1F || data[1] != 0x9D) - return false; - Byte prop = data[2]; - if ((prop & 0x60) != 0) - return false; - unsigned maxbits = prop & kNumBitsMask; - if (maxbits < kNumMinBits || maxbits > kNumMaxBits) - return false; - UInt32 numItems = 1 << maxbits; - UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); - unsigned numBits = kNumMinBits; - UInt32 head = (blockSymbol == 256) ? 257 : 256; - unsigned bitPos = 0; - unsigned numBufBits = 0; - Byte buf[kNumMaxBits + 4]; - data += 3; - size -= 3; - // printf("\n\n"); - for (;;) - { - if (numBufBits == bitPos) - { - unsigned num = (numBits < size) ? numBits : (unsigned)size; - memcpy(buf, data, num); - data += num; - size -= num; - numBufBits = num * 8; - bitPos = 0; - } - unsigned bytePos = bitPos >> 3; - UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16); - symbol >>= (bitPos & 7); - symbol &= (1 << numBits) - 1; - bitPos += numBits; - if (bitPos > numBufBits) - { - // printf(" OK", symbol); - return true; - } - // printf("%3X ", symbol); - if (symbol >= head) - return false; - if (symbol == blockSymbol) - { - numBufBits = bitPos = 0; - numBits = kNumMinBits; - head = 257; - continue; - } - if (head < numItems) - { - head++; - if (head > ((UInt32)1 << numBits)) - { - if (numBits < maxbits) - { - numBufBits = bitPos = 0; - numBits++; - } - } - } - } -} - -}} +// ZDecoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" + +#include "../Common/InBuffer.h" +#include "../Common/OutBuffer.h" + +#include "ZDecoder.h" + +namespace NCompress { +namespace NZ { + +static const size_t kBufferSize = 1 << 20; +static const Byte kNumBitsMask = 0x1F; +static const Byte kBlockModeMask = 0x80; +static const unsigned kNumMinBits = 9; +static const unsigned kNumMaxBits = 16; + +void CDecoder::Free() +{ + MyFree(_parents); _parents = NULL; + MyFree(_suffixes); _suffixes = NULL; + MyFree(_stack); _stack = NULL; +} + +CDecoder::~CDecoder() { Free(); } + +HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + ICompressProgressInfo *progress) +{ + try { + // PackSize = 0; + + CInBuffer inBuffer; + COutBuffer outBuffer; + + if (!inBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + inBuffer.SetStream(inStream); + inBuffer.Init(); + + if (!outBuffer.Create(kBufferSize)) + return E_OUTOFMEMORY; + outBuffer.SetStream(outStream); + outBuffer.Init(); + + Byte buf[kNumMaxBits + 4]; + { + if (inBuffer.ReadBytes(buf, 3) < 3) + return S_FALSE; + if (buf[0] != 0x1F || buf[1] != 0x9D) + return S_FALSE; + } + const Byte prop = buf[2]; + + if ((prop & 0x60) != 0) + return S_FALSE; + const unsigned maxbits = prop & kNumBitsMask; + if (maxbits < kNumMinBits || maxbits > kNumMaxBits) + return S_FALSE; + const UInt32 numItems = (UInt32)1 << maxbits; + // Speed optimization: blockSymbol can contain unused velue. + + if (maxbits != _numMaxBits || !_parents || !_suffixes || !_stack) + { + Free(); + _parents = (UInt16 *)MyAlloc(numItems * sizeof(UInt16)); if (!_parents) return E_OUTOFMEMORY; + _suffixes = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (!_suffixes) return E_OUTOFMEMORY; + _stack = (Byte *)MyAlloc(numItems * sizeof(Byte)); if (!_stack) return E_OUTOFMEMORY; + _numMaxBits = maxbits; + } + + UInt64 prevPos = 0; + const UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + unsigned numBits = kNumMinBits; + UInt32 head = (blockSymbol == 256) ? 257 : 256; + bool needPrev = false; + unsigned bitPos = 0; + unsigned numBufBits = 0; + + _parents[256] = 0; // virus protection + _suffixes[256] = 0; + HRESULT res = S_OK; + + for (;;) + { + if (numBufBits == bitPos) + { + numBufBits = (unsigned)inBuffer.ReadBytes(buf, numBits) * 8; + bitPos = 0; + const UInt64 nowPos = outBuffer.GetProcessedSize(); + if (progress && nowPos - prevPos >= (1 << 13)) + { + prevPos = nowPos; + const UInt64 packSize = inBuffer.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &nowPos)) + } + } + const unsigned bytePos = bitPos >> 3; + UInt32 symbol = buf[bytePos] | ((UInt32)buf[(size_t)bytePos + 1] << 8) | ((UInt32)buf[(size_t)bytePos + 2] << 16); + symbol >>= (bitPos & 7); + symbol &= ((UInt32)1 << numBits) - 1; + bitPos += numBits; + if (bitPos > numBufBits) + break; + if (symbol >= head) + { + res = S_FALSE; + break; + } + if (symbol == blockSymbol) + { + numBufBits = bitPos = 0; + numBits = kNumMinBits; + head = 257; + needPrev = false; + continue; + } + UInt32 cur = symbol; + unsigned i = 0; + while (cur >= 256) + { + _stack[i++] = _suffixes[cur]; + cur = _parents[cur]; + } + _stack[i++] = (Byte)cur; + if (needPrev) + { + _suffixes[(size_t)head - 1] = (Byte)cur; + if (symbol == head - 1) + _stack[0] = (Byte)cur; + } + do + outBuffer.WriteByte((_stack[--i])); + while (i > 0); + if (head < numItems) + { + needPrev = true; + _parents[head++] = (UInt16)symbol; + if (head > ((UInt32)1 << numBits)) + { + if (numBits < maxbits) + { + numBufBits = bitPos = 0; + numBits++; + } + } + } + else + needPrev = false; + } + // PackSize = inBuffer.GetProcessedSize(); + const HRESULT res2 = outBuffer.Flush(); + return (res == S_OK) ? res2 : res; + + } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const COutBufferException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + + +bool CheckStream(const Byte *data, size_t size) +{ + if (size < 3) + return false; + if (data[0] != 0x1F || data[1] != 0x9D) + return false; + const Byte prop = data[2]; + if ((prop & 0x60) != 0) + return false; + const unsigned maxbits = prop & kNumBitsMask; + if (maxbits < kNumMinBits || maxbits > kNumMaxBits) + return false; + const UInt32 numItems = (UInt32)1 << maxbits; + const UInt32 blockSymbol = ((prop & kBlockModeMask) != 0) ? 256 : ((UInt32)1 << kNumMaxBits); + unsigned numBits = kNumMinBits; + UInt32 head = (blockSymbol == 256) ? 257 : 256; + unsigned bitPos = 0; + unsigned numBufBits = 0; + Byte buf[kNumMaxBits + 4]; + data += 3; + size -= 3; + // printf("\n\n"); + for (;;) + { + if (numBufBits == bitPos) + { + const unsigned num = (numBits < size) ? numBits : (unsigned)size; + memcpy(buf, data, num); + data += num; + size -= num; + numBufBits = num * 8; + bitPos = 0; + } + const unsigned bytePos = bitPos >> 3; + UInt32 symbol = buf[bytePos] | ((UInt32)buf[bytePos + 1] << 8) | ((UInt32)buf[bytePos + 2] << 16); + symbol >>= (bitPos & 7); + symbol &= ((UInt32)1 << numBits) - 1; + bitPos += numBits; + if (bitPos > numBufBits) + { + // printf(" OK", symbol); + return true; + } + // printf("%3X ", symbol); + if (symbol >= head) + return false; + if (symbol == blockSymbol) + { + numBufBits = bitPos = 0; + numBits = kNumMinBits; + head = 257; + continue; + } + if (head < numItems) + { + head++; + if (head > ((UInt32)1 << numBits)) + { + if (numBits < maxbits) + { + numBufBits = bitPos = 0; + numBits++; + } + } + } + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ZDecoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZDecoder.h 2023-12-19 17:00:00.000000000 +0000 @@ -1,54 +1,47 @@ -// ZDecoder.h - -#ifndef __COMPRESS_Z_DECODER_H -#define __COMPRESS_Z_DECODER_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCompress { -namespace NZ { - -// Z decoder decodes Z data stream, including 3 bytes of header. - -class CDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - UInt16 *_parents; - Byte *_suffixes; - Byte *_stack; - unsigned _numMaxBits; - -public: - CDecoder(): _parents(0), _suffixes(0), _stack(0), /* _prop(0), */ _numMaxBits(0) {}; - ~CDecoder(); - void Free(); - UInt64 PackSize; - - MY_UNKNOWN_IMP1(ICompressCoder) - - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); -}; - -/* - There is no end_of_payload_marker in Z stream. - Z decoder stops decoding, if it reaches end of input stream. - - CheckStream function: - (size) must be at least 3 bytes (size of Z header). - if (size) is larger than size of real Z stream in (data), CheckStream can return false. -*/ - -const unsigned kRecommendedCheckSize = 64; - -bool CheckStream(const Byte *data, size_t size); - -}} - -#endif +// ZDecoder.h + +#ifndef ZIP7_INC_COMPRESS_Z_DECODER_H +#define ZIP7_INC_COMPRESS_Z_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCompress { +namespace NZ { + +// Z decoder decodes Z data stream, including 3 bytes of header. + +class CDecoder +{ + UInt16 *_parents; + Byte *_suffixes; + Byte *_stack; + unsigned _numMaxBits; + +public: + CDecoder(): _parents(NULL), _suffixes(NULL), _stack(NULL), /* _prop(0), */ _numMaxBits(0) {} + ~CDecoder(); + void Free(); + // UInt64 PackSize; + + HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + ICompressProgressInfo *progress); +}; + +/* + There is no end_of_payload_marker in Z stream. + Z decoder stops decoding, if it reaches end of input stream. + + CheckStream function: + (size) must be at least 3 bytes (size of Z header). + if (size) is larger than size of real Z stream in (data), CheckStream can return false. +*/ + +const unsigned kRecommendedCheckSize = 64; + +bool CheckStream(const Byte *data, size_t size); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZlibDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ZlibDecoder.cpp 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.cpp 2023-12-20 13:00:00.000000000 +0000 @@ -1,92 +1,136 @@ -// ZlibDecoder.cpp - -#include "StdAfx.h" - -#include "../Common/StreamUtils.h" - -#include "ZlibDecoder.h" - -namespace NCompress { -namespace NZlib { - -#define DEFLATE_TRY_BEGIN try { -#define DEFLATE_TRY_END } catch(...) { return S_FALSE; } - -#define ADLER_MOD 65521 -#define ADLER_LOOP_MAX 5550 - -UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size) -{ - UInt32 a = adler & 0xFFFF; - UInt32 b = (adler >> 16) & 0xFFFF; - while (size > 0) - { - unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size; - unsigned i; - for (i = 0; i < curSize; i++) - { - a += buf[i]; - b += a; - } - buf += curSize; - size -= curSize; - a %= ADLER_MOD; - b %= ADLER_MOD; - } - return (b << 16) + a; -} - -STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - _adler = Adler32_Update(_adler, (const Byte *)data, size); - _size += size; - if (processedSize) - *processedSize = size; - return result; -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - DEFLATE_TRY_BEGIN - if (!AdlerStream) - AdlerStream = AdlerSpec = new COutStreamWithAdler; - if (!DeflateDecoder) - { - DeflateDecoderSpec = new NDeflate::NDecoder::CCOMCoder; - DeflateDecoderSpec->ZlibMode = true; - DeflateDecoder = DeflateDecoderSpec; - } - - if (inSize && *inSize < 2) - return S_FALSE; - Byte buf[2]; - RINOK(ReadStream_FALSE(inStream, buf, 2)); - if (!IsZlib(buf)) - return S_FALSE; - - AdlerSpec->SetStream(outStream); - AdlerSpec->Init(); - - UInt64 inSize2 = 0; - if (inSize) - inSize2 = *inSize - 2; - - HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize ? &inSize2 : NULL, outSize, progress); - AdlerSpec->ReleaseStream(); - - if (res == S_OK) - { - const Byte *p = DeflateDecoderSpec->ZlibFooter; - UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3]; - if (adler != AdlerSpec->GetAdler()) - return S_FALSE; - } - return res; - DEFLATE_TRY_END -} - -}} +// ZlibDecoder.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "ZlibDecoder.h" + +namespace NCompress { +namespace NZlib { + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } catch(...) { return S_FALSE; } + +#define ADLER_MOD 65521 +#define ADLER_LOOP_MAX 5550 + +UInt32 Adler32_Update(UInt32 adler, const Byte *data, size_t size); +UInt32 Adler32_Update(UInt32 adler, const Byte *data, size_t size) +{ + if (size == 0) + return adler; + UInt32 a = adler & 0xffff; + UInt32 b = adler >> 16; + do + { + size_t cur = size; + if (cur > ADLER_LOOP_MAX) + cur = ADLER_LOOP_MAX; + size -= cur; + const Byte *lim = data + cur; + if (cur >= 4) + { + lim -= 4 - 1; + do + { + a += data[0]; b += a; + a += data[1]; b += a; + a += data[2]; b += a; + a += data[3]; b += a; + data += 4; + } + while (data < lim); + lim += 4 - 1; + } + if (data != lim) { a += *data++; b += a; + if (data != lim) { a += *data++; b += a; + if (data != lim) { a += *data++; b += a; }}} + a %= ADLER_MOD; + b %= ADLER_MOD; + } + while (size); + return (b << 16) + a; +} + +Z7_COM7F_IMF(COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + _adler = Adler32_Update(_adler, (const Byte *)data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + DEFLATE_TRY_BEGIN + _inputProcessedSize_Additional = 0; + AdlerStream.Create_if_Empty(); + DeflateDecoder.Create_if_Empty(); + DeflateDecoder->Set_NeedFinishInput(true); + + if (inSize && *inSize < 2) + return S_FALSE; + { + Byte buf[2]; + RINOK(ReadStream_FALSE(inStream, buf, 2)) + if (!IsZlib(buf)) + return S_FALSE; + } + _inputProcessedSize_Additional = 2; + AdlerStream->SetStream(outStream); + AdlerStream->Init(); + // NDeflate::NDecoder::Code() ignores inSize + /* + UInt64 inSize2 = 0; + if (inSize) + inSize2 = *inSize - 2; + */ + const HRESULT res = DeflateDecoder.Interface()->Code(inStream, AdlerStream, + /* inSize ? &inSize2 : */ NULL, outSize, progress); + AdlerStream->ReleaseStream(); + + if (res == S_OK) + { + UInt32 footer32[1]; + UInt32 processedSize; + RINOK(DeflateDecoder->ReadUnusedFromInBuf(footer32, 4, &processedSize)) + if (processedSize != 4) + { + size_t processedSize2 = 4 - processedSize; + RINOK(ReadStream(inStream, (Byte *)(void *)footer32 + processedSize, &processedSize2)) + _inputProcessedSize_Additional += (Int32)processedSize2; + processedSize += (UInt32)processedSize2; + } + + if (processedSize == 4) + { + const UInt32 adler = GetBe32a(footer32); + if (adler != AdlerStream->GetAdler()) + return S_FALSE; // adler error + } + else if (!IsAdlerOptional) + return S_FALSE; // unexpeced end of stream (can't read adler) + else + { + // IsAdlerOptional == true + if (processedSize != 0) + { + // we exclude adler bytes from processed size: + _inputProcessedSize_Additional -= (Int32)processedSize; + return S_FALSE; + } + } + } + return res; + DEFLATE_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZlibDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ZlibDecoder.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibDecoder.h 2023-12-20 13:00:00.000000000 +0000 @@ -1,79 +1,78 @@ -// ZlibDecoder.h - -#ifndef __ZLIB_DECODER_H -#define __ZLIB_DECODER_H - -#include "DeflateDecoder.h" - -namespace NCompress { -namespace NZlib { - -const UInt32 ADLER_INIT_VAL = 1; - -class COutStreamWithAdler: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt32 _adler; - UInt64 _size; -public: - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init() { _adler = ADLER_INIT_VAL; _size = 0; } - UInt32 GetAdler() const { return _adler; } - UInt64 GetSize() const { return _size; } -}; - -class CDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - COutStreamWithAdler *AdlerSpec; - CMyComPtr AdlerStream; - - NCompress::NDeflate::NDecoder::CCOMCoder *DeflateDecoderSpec; - CMyComPtr DeflateDecoder; -public: - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - - UInt64 GetInputProcessedSize() const { return DeflateDecoderSpec->GetInputProcessedSize() + 2; } - UInt64 GetOutputProcessedSize() const { return AdlerSpec->GetSize(); } - - MY_UNKNOWN_IMP -}; - -static bool inline IsZlib(const Byte *p) -{ - if ((p[0] & 0xF) != 8) // method - return false; - if (((unsigned)p[0] >> 4) > 7) // logar_window_size minus 8. - return false; - if ((p[1] & 0x20) != 0) // dictPresent - return false; - if ((((UInt32)p[0] << 8) + p[1]) % 31 != 0) - return false; - return true; -} - -// IsZlib_3bytes checks 2 bytes of zlib header and starting byte of Deflate stream - -static bool inline IsZlib_3bytes(const Byte *p) -{ - if (!IsZlib(p)) - return false; - unsigned val = p[2]; - unsigned blockType = (val >> 1) & 0x3; - if (blockType == 3) // unsupported block type for deflate - return false; - if (blockType == NCompress::NDeflate::NBlockType::kStored && (val >> 3) != 0) - return false; - return true; -} - -}} - -#endif +// ZlibDecoder.h + +#ifndef ZIP7_INC_ZLIB_DECODER_H +#define ZIP7_INC_ZLIB_DECODER_H + +#include "DeflateDecoder.h" + +namespace NCompress { +namespace NZlib { + +const UInt32 ADLER_INIT_VAL = 1; + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithAdler + , ISequentialOutStream +) + UInt32 _adler; + CMyComPtr _stream; + UInt64 _size; +public: + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _adler = ADLER_INIT_VAL; _size = 0; } + UInt32 GetAdler() const { return _adler; } + UInt64 GetSize() const { return _size; } +}; + +Z7_CLASS_IMP_NOQIB_1( + CDecoder + , ICompressCoder +) + CMyComPtr2 AdlerStream; + CMyComPtr2 DeflateDecoder; + Int32 _inputProcessedSize_Additional; +public: + bool IsAdlerOptional; + + CDecoder(): IsAdlerOptional(false) {} + UInt64 GetInputProcessedSize() const + { + return (UInt64)( + (Int64)DeflateDecoder->GetInputProcessedSize() + + (Int64)_inputProcessedSize_Additional); + } + UInt64 GetOutputProcessedSize() const { return AdlerStream->GetSize(); } +}; + +static bool inline IsZlib(const Byte *p) +{ + if ((p[0] & 0xF) != 8) // method + return false; + if (((unsigned)p[0] >> 4) > 7) // logar_window_size minus 8. + return false; + if ((p[1] & 0x20) != 0) // dictPresent + return false; + if ((((UInt32)p[0] << 8) + p[1]) % 31 != 0) + return false; + return true; +} + +// IsZlib_3bytes checks 2 bytes of zlib header and starting byte of Deflate stream + +static bool inline IsZlib_3bytes(const Byte *p) +{ + if (!IsZlib(p)) + return false; + const unsigned val = p[2]; + const unsigned blockType = (val >> 1) & 0x3; + if (blockType == 3) // unsupported block type for deflate + return false; + if (blockType == NCompress::NDeflate::NBlockType::kStored && (val >> 3) != 0) + return false; + return true; +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZlibEncoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ZlibEncoder.cpp 2009-12-21 16:23:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.cpp 2023-03-28 19:00:00.000000000 +0000 @@ -1,61 +1,61 @@ -// ZlibEncoder.cpp - -#include "StdAfx.h" - -#include "../Common/StreamUtils.h" - -#include "ZlibEncoder.h" - -namespace NCompress { -namespace NZlib { - -#define DEFLATE_TRY_BEGIN try { -#define DEFLATE_TRY_END } catch(...) { return S_FALSE; } - -UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size); - -STDMETHODIMP CInStreamWithAdler::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = _stream->Read(data, size, &size); - _adler = Adler32_Update(_adler, (const Byte *)data, size); - _size += size; - if (processedSize != NULL) - *processedSize = size; - return result; -} - -void CEncoder::Create() -{ - if (!DeflateEncoder) - DeflateEncoder = DeflateEncoderSpec = new NDeflate::NEncoder::CCOMCoder; -} - -STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 * /* outSize */, ICompressProgressInfo *progress) -{ - DEFLATE_TRY_BEGIN - if (!AdlerStream) - AdlerStream = AdlerSpec = new CInStreamWithAdler; - Create(); - - { - Byte buf[2] = { 0x78, 0xDA }; - RINOK(WriteStream(outStream, buf, 2)); - } - - AdlerSpec->SetStream(inStream); - AdlerSpec->Init(); - HRESULT res = DeflateEncoder->Code(AdlerStream, outStream, inSize, NULL, progress); - AdlerSpec->ReleaseStream(); - - RINOK(res); - - { - UInt32 a = AdlerSpec->GetAdler(); - Byte buf[4] = { (Byte)(a >> 24), (Byte)(a >> 16), (Byte)(a >> 8), (Byte)(a) }; - return WriteStream(outStream, buf, 4); - } - DEFLATE_TRY_END -} - -}} +// ZlibEncoder.cpp + +#include "StdAfx.h" + +#include "../Common/StreamUtils.h" + +#include "ZlibEncoder.h" + +namespace NCompress { +namespace NZlib { + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } catch(...) { return S_FALSE; } + +UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size); + +Z7_COM7F_IMF(CInStreamWithAdler::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + const HRESULT result = _stream->Read(data, size, &size); + _adler = Adler32_Update(_adler, (const Byte *)data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +void CEncoder::Create() +{ + if (!DeflateEncoder) + DeflateEncoder = DeflateEncoderSpec = new NDeflate::NEncoder::CCOMCoder; +} + +Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 * /* outSize */, ICompressProgressInfo *progress)) +{ + DEFLATE_TRY_BEGIN + if (!AdlerStream) + AdlerStream = AdlerSpec = new CInStreamWithAdler; + Create(); + + { + Byte buf[2] = { 0x78, 0xDA }; + RINOK(WriteStream(outStream, buf, 2)) + } + + AdlerSpec->SetStream(inStream); + AdlerSpec->Init(); + const HRESULT res = DeflateEncoder->Code(AdlerStream, outStream, inSize, NULL, progress); + AdlerSpec->ReleaseStream(); + + RINOK(res) + + { + const UInt32 a = AdlerSpec->GetAdler(); + const Byte buf[4] = { (Byte)(a >> 24), (Byte)(a >> 16), (Byte)(a >> 8), (Byte)(a) }; + return WriteStream(outStream, buf, 4); + } + DEFLATE_TRY_END +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZlibEncoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ZlibEncoder.h 2009-12-21 16:23:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZlibEncoder.h 2023-01-31 17:00:00.000000000 +0000 @@ -1,48 +1,42 @@ -// ZlibEncoder.h - -#ifndef __ZLIB_ENCODER_H -#define __ZLIB_ENCODER_H - -#include "DeflateEncoder.h" - -namespace NCompress { -namespace NZlib { - -class CInStreamWithAdler: - public ISequentialInStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt32 _adler; - UInt64 _size; -public: - MY_UNKNOWN_IMP - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init() { _adler = 1; _size = 0; } // ADLER_INIT_VAL - UInt32 GetAdler() const { return _adler; } - UInt64 GetSize() const { return _size; } -}; - -class CEncoder: - public ICompressCoder, - public CMyUnknownImp -{ - CInStreamWithAdler *AdlerSpec; - CMyComPtr AdlerStream; - CMyComPtr DeflateEncoder; -public: - NCompress::NDeflate::NEncoder::CCOMCoder *DeflateEncoderSpec; - - void Create(); - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - UInt64 GetInputProcessedSize() const { return AdlerSpec->GetSize(); } - - MY_UNKNOWN_IMP -}; - -}} - -#endif +// ZlibEncoder.h + +#ifndef ZIP7_INC_ZLIB_ENCODER_H +#define ZIP7_INC_ZLIB_ENCODER_H + +#include "DeflateEncoder.h" + +namespace NCompress { +namespace NZlib { + +Z7_CLASS_IMP_NOQIB_1( + CInStreamWithAdler + , ISequentialInStream +) + CMyComPtr _stream; + UInt32 _adler; + UInt64 _size; +public: + void SetStream(ISequentialInStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init() { _adler = 1; _size = 0; } // ADLER_INIT_VAL + UInt32 GetAdler() const { return _adler; } + UInt64 GetSize() const { return _size; } +}; + +Z7_CLASS_IMP_NOQIB_1( + CEncoder + , ICompressCoder +) + CInStreamWithAdler *AdlerSpec; + CMyComPtr AdlerStream; + CMyComPtr DeflateEncoder; +public: + NCompress::NDeflate::NEncoder::CCOMCoder *DeflateEncoderSpec; + + void Create(); + UInt64 GetInputProcessedSize() const { return AdlerSpec->GetSize(); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZstdDecoder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.cpp --- p7zip-rar-16.02/CPP/7zip/Compress/ZstdDecoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.cpp 2023-08-15 14:00:00.000000000 +0000 @@ -0,0 +1,437 @@ +// ZstdDecoder.cpp + +#include "StdAfx.h" + +// #include + +#include "../../../C/Alloc.h" + +#include "../Common/CWrappers.h" +#include "../Common/StreamUtils.h" + +#include "ZstdDecoder.h" + +namespace NCompress { +namespace NZstd { + +static const size_t k_Zstd_BlockSizeMax = 1 << 17; +/* + we set _outStepMask as (k_Zstd_BlockSizeMax - 1), because: + - cycSize in zstd decoder for isCyclicMode is aligned for (1 << 17) only. + So some write sizes will be multiple of ((1 << 17) * n). + - Also it can be optimal to flush data after each block decoding. +*/ + +CDecoder::CDecoder(): + _outStepMask(k_Zstd_BlockSizeMax - 1) // must be = (1 << x) - 1 + , _dec(NULL) + , _inProcessed(0) + , _inBufSize(1u << 19) // larger value will reduce the number of memcpy() calls in CZstdDec code + , _inBuf(NULL) + , FinishMode(false) + , DisableHash(False) + // , DisableHash(True) // for debug : fast decoding without hash calculation +{ + // ZstdDecInfo_Clear(&ResInfo); +} + +CDecoder::~CDecoder() +{ + if (_dec) + ZstdDec_Destroy(_dec); + MidFree(_inBuf); +} + + +Z7_COM7F_IMF(CDecoder::SetInBufSize(UInt32 , UInt32 size)) + { _inBufSize = size; return S_OK; } +Z7_COM7F_IMF(CDecoder::SetOutBufSize(UInt32 , UInt32 size)) +{ + // we round it down: + size >>= 1; + size |= size >> (1 << 0); + size |= size >> (1 << 1); + size |= size >> (1 << 2); + size |= size >> (1 << 3); + size |= size >> (1 << 4); + _outStepMask = size; // it's (1 << x) - 1 now + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte * /* prop */, UInt32 /* size */)) +{ + // if (size != 3 && size != 5) return E_NOTIMPL; + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode)) +{ + FinishMode = (finishMode != 0); + // FinishMode = false; // for debug + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t cur = ZstdDec_ReadUnusedFromInBuf(_dec, _afterDecoding_tempPos, data, size); + _afterDecoding_tempPos += cur; + size -= (UInt32)cur; + if (size) + { + const size_t rem = _state.inLim - _state.inPos; + if (size > rem) + size = (UInt32)rem; + if (size) + { + memcpy((Byte *)data + cur, _state.inBuf + _state.inPos, size); + _state.inPos += size; + cur += size; + } + } + *processedSize = (UInt32)cur; + return S_OK; +} + + + +HRESULT CDecoder::Prepare(const UInt64 *outSize) +{ + _inProcessed = 0; + _afterDecoding_tempPos = 0; + ZstdDecState_Clear(&_state); + ZstdDecInfo_CLEAR(&ResInfo) + // _state.outStep = _outStepMask + 1; // must be = (1 << x) + _state.disableHash = DisableHash; + if (outSize) + { + _state.outSize_Defined = True; + _state.outSize = *outSize; + // _state.outSize = 0; // for debug + } + if (!_dec) + { + _dec = ZstdDec_Create(&g_AlignedAlloc, &g_BigAlloc); + if (!_dec) + return E_OUTOFMEMORY; + } + if (!_inBuf || _inBufSize != _inBufSize_Allocated) + { + MidFree(_inBuf); + _inBuf = NULL; + _inBufSize_Allocated = 0; + _inBuf = (Byte *)MidAlloc(_inBufSize); + if (!_inBuf) + return E_OUTOFMEMORY; + _inBufSize_Allocated = _inBufSize; + } + _state.inBuf = _inBuf; + ZstdDec_Init(_dec); + return S_OK; +} + + +Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)) +{ + RINOK(Prepare(outSize)) + + UInt64 inPrev = 0; + UInt64 outPrev = 0; + UInt64 writtenSize = 0; + bool readWasFinished = false; + SRes sres = SZ_OK; + HRESULT hres = S_OK; + HRESULT hres_Read = S_OK; + + for (;;) + { + if (_state.inPos == _state.inLim && !readWasFinished) + { + _state.inPos = 0; + _state.inLim = _inBufSize; + hres_Read = ReadStream(inStream, _inBuf, &_state.inLim); + // _state.inLim -= 5; readWasFinished = True; // for debug + if (_state.inLim != _inBufSize || hres_Read != S_OK) + { + // hres_Read = 99; // for debug + readWasFinished = True; + } + } + { + const size_t inPos_Start = _state.inPos; + sres = ZstdDec_Decode(_dec, &_state); + _inProcessed += _state.inPos - inPos_Start; + } + /* + if (_state.status == ZSTD_STATUS_FINISHED_FRAME) + printf("\nfinished frame pos=%8x, checksum=%08x\n", (unsigned)_state.outProcessed, (unsigned)_state.info.checksum); + */ + const bool needStop = (sres != SZ_OK) + || _state.status == ZSTD_STATUS_OUT_REACHED + || (outSize && *outSize < _state.outProcessed) + || (readWasFinished && _state.inPos == _state.inLim + && ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(&_state)); + + size_t size = _state.winPos - _state.wrPos; // full write size + if (size) + { + if (!needStop) + { + // we try to flush on aligned positions, if possible + size = _state.needWrite_Size; // minimal required write size + const size_t alignedPos = _state.winPos & ~(size_t)_outStepMask; + if (alignedPos > _state.wrPos) + { + const size_t size2 = alignedPos - _state.wrPos; // optimized aligned size + if (size < size2) + size = size2; + } + } + if (size) + { + { + size_t curSize = size; + if (outSize) + { + const UInt64 rem = *outSize - writtenSize; + if (curSize > rem) + curSize = (size_t)rem; + } + if (curSize) + { + // printf("Write wrPos=%8x, size=%8x\n", (unsigned)_state.wrPos, (unsigned)size); + hres = WriteStream(outStream, _state.win + _state.wrPos, curSize); + if (hres != S_OK) + break; + writtenSize += curSize; // it's real size of data that was written to stream + } + } + _state.wrPos += size; // virtual written size, that will be reported to CZstdDec + // _state.needWrite_Size = 0; // optional + } + } + + if (needStop) + break; + if (progress) + if (_inProcessed - inPrev >= (1 << 27) + || _state.outProcessed - outPrev >= (1 << 28)) + { + inPrev = _inProcessed; + outPrev = _state.outProcessed; + RINOK(progress->SetRatioInfo(&inPrev, &outPrev)) + } + } + + if (hres == S_OK) + { + ZstdDec_GetResInfo(_dec, &_state, sres, &ResInfo); + sres = ResInfo.decode_SRes; + /* now (ResInfo.decode_SRes) can contain 2 extra error codes: + - SZ_ERROR_NO_ARCHIVE : if no frames + - SZ_ERROR_INPUT_EOF : if ZSTD_STATUS_NEEDS_MORE_INPUT + */ + _inProcessed -= ResInfo.extraSize; + if (hres_Read != S_OK && _state.inLim == _state.inPos && readWasFinished) + { + /* if (there is stream reading error, + and decoding was stopped because of end of input stream), + then we use reading error as main error code */ + if (sres == SZ_OK || + sres == SZ_ERROR_INPUT_EOF || + sres == SZ_ERROR_NO_ARCHIVE) + hres = hres_Read; + } + if (sres == SZ_ERROR_INPUT_EOF && !FinishMode) + { + /* SZ_ERROR_INPUT_EOF case is allowed case for (!FinishMode) mode. + So we restore SZ_OK result for that case: */ + ResInfo.decode_SRes = sres = SZ_OK; + } + if (hres == S_OK) + { + hres = SResToHRESULT(sres); + if (hres == S_OK && FinishMode) + { + if ((inSize && *inSize != _inProcessed) + || ResInfo.is_NonFinishedFrame + || (outSize && (*outSize != writtenSize || writtenSize != _state.outProcessed))) + hres = S_FALSE; + } + } + } + return hres; +} + + +Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value)) +{ + *value = _inProcessed; + return S_OK; +} + + +#ifndef Z7_NO_READ_FROM_CODER_ZSTD + +Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize)) +{ + _inProcessed = 0; + _hres_Read = S_OK; + _hres_Decode = S_OK; + _writtenSize = 0; + _readWasFinished = false; + _wasFinished = false; + return Prepare(outSize); +} + + +Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream)) + { _inStream = inStream; return S_OK; } +Z7_COM7F_IMF(CDecoder::ReleaseInStream()) + { _inStream.Release(); return S_OK; } + + +// if SetInStream() mode: the caller must call GetFinishResult() after full decoding +// to check that there decoding was finished correctly + +HRESULT CDecoder::GetFinishResult() +{ + if (_state.winPos != _state.wrPos || !_wasFinished) + return FinishMode ? S_FALSE : S_OK; + // _state.winPos == _state.wrPos + // _wasFinished == true + if (FinishMode && _hres_Decode == S_OK && _state.outSize_Defined && _state.outSize != _writtenSize) + _hres_Decode = S_FALSE; + return _hres_Decode; +} + + +Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + + for (;;) + { + if (_state.outSize_Defined) + { + // _writtenSize <= _state.outSize + const UInt64 rem = _state.outSize - _writtenSize; + if (size > rem) + size = (UInt32)rem; + } + { + size_t cur = _state.winPos - _state.wrPos; + if (cur) + { + // _state.winPos != _state.wrPos; + // so there is some decoded data that was not written still + if (size == 0) + { + // if (FinishMode) and we are not allowed to write more, then it's data error + if (FinishMode && _state.outSize_Defined && _state.outSize == _writtenSize) + return S_FALSE; + return S_OK; + } + if (cur > size) + cur = (size_t)size; + // cur != 0 + memcpy(data, _state.win + _state.wrPos, cur); + _state.wrPos += cur; + _writtenSize += cur; + data = (void *)((Byte *)data + cur); + if (processedSize) + *processedSize += (UInt32)cur; + size -= (UInt32)cur; + continue; + } + } + + // _state.winPos == _state.wrPos + if (_wasFinished) + { + if (_hres_Decode == S_OK && FinishMode + && _state.outSize_Defined && _state.outSize != _writtenSize) + _hres_Decode = S_FALSE; + return _hres_Decode; + } + + // _wasFinished == false + if (size == 0 && _state.outSize_Defined && _state.outSize != _state.outProcessed) + { + /* size == 0 : so the caller don't need more data now. + _state.outSize > _state.outProcessed : so more data will be requested + later by caller for full processing. + So we exit without ZstdDec_Decode() call, because we don't want + ZstdDec_Decode() to start new block decoding + */ + return S_OK; + } + // size != 0 || !_state.outSize_Defined || _state.outSize == _state.outProcessed) + + if (_state.inPos == _state.inLim && !_readWasFinished) + { + _state.inPos = 0; + _state.inLim = _inBufSize; + _hres_Read = ReadStream(_inStream, _inBuf, &_state.inLim); + if (_state.inLim != _inBufSize || _hres_Read != S_OK) + { + // _hres_Read = 99; // for debug + _readWasFinished = True; + } + } + + SRes sres; + { + const SizeT inPos_Start = _state.inPos; + sres = ZstdDec_Decode(_dec, &_state); + _inProcessed += _state.inPos - inPos_Start; + } + + const bool inFinished = (_state.inPos == _state.inLim) && _readWasFinished; + + _wasFinished = (sres != SZ_OK) + || _state.status == ZSTD_STATUS_OUT_REACHED + || (_state.outSize_Defined && _state.outSize < _state.outProcessed) + || (inFinished + && ZstdDecState_DOES_NEED_MORE_INPUT_OR_FINISHED_FRAME(&_state)); + + if (!_wasFinished) + continue; + + // _wasFinished == true + /* (_state.winPos != _state.wrPos) is possible here. + So we still can have some data to flush, + but we must all result variables . + */ + HRESULT hres = S_OK; + ZstdDec_GetResInfo(_dec, &_state, sres, &ResInfo); + sres = ResInfo.decode_SRes; + _inProcessed -= ResInfo.extraSize; + if (_hres_Read != S_OK && inFinished) + { + if (sres == SZ_OK || + sres == SZ_ERROR_INPUT_EOF || + sres == SZ_ERROR_NO_ARCHIVE) + hres = _hres_Read; + } + if (sres == SZ_ERROR_INPUT_EOF && !FinishMode) + ResInfo.decode_SRes = sres = SZ_OK; + if (hres == S_OK) + { + hres = SResToHRESULT(sres); + if (hres == S_OK && FinishMode) + if (!inFinished + || ResInfo.is_NonFinishedFrame + || (_state.outSize_Defined && _state.outSize != _state.outProcessed)) + hres = S_FALSE; + } + _hres_Decode = hres; + } +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/ZstdDecoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.h --- p7zip-rar-16.02/CPP/7zip/Compress/ZstdDecoder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/ZstdDecoder.h 2023-08-15 10:00:00.000000000 +0000 @@ -0,0 +1,98 @@ +// ZstdDecoder.h + +#ifndef ZIP7_INC_ZSTD_DECODER_H +#define ZIP7_INC_ZSTD_DECODER_H + +#include "../../../C/ZstdDec.h" + +#include "../../Common/MyCom.h" +#include "../ICoder.h" + +namespace NCompress { +namespace NZstd { + +#ifdef Z7_NO_READ_FROM_CODER +#define Z7_NO_READ_FROM_CODER_ZSTD +#endif + +#ifndef Z7_NO_READ_FROM_CODER_ZSTD +// #define Z7_NO_READ_FROM_CODER_ZSTD +#endif + +class CDecoder Z7_final: + public ICompressCoder, + public ICompressSetDecoderProperties2, + public ICompressSetFinishMode, + public ICompressGetInStreamProcessedSize, + public ICompressReadUnusedFromInBuf, + public ICompressSetBufSize, + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressCoder) + Z7_COM_QI_ENTRY(ICompressSetDecoderProperties2) + Z7_COM_QI_ENTRY(ICompressSetFinishMode) + Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize) + Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf) + Z7_COM_QI_ENTRY(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + Z7_COM_QI_ENTRY(ICompressSetInStream) + Z7_COM_QI_ENTRY(ICompressSetOutStreamSize) + Z7_COM_QI_ENTRY(ISequentialInStream) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressCoder) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetFinishMode) + Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize) + Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf) + Z7_IFACE_COM7_IMP(ICompressSetBufSize) + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize) + Z7_IFACE_COM7_IMP(ICompressSetInStream) + Z7_IFACE_COM7_IMP(ISequentialInStream) + #endif + + HRESULT Prepare(const UInt64 *outSize); + + UInt32 _outStepMask; + CZstdDecHandle _dec; +public: + UInt64 _inProcessed; + CZstdDecState _state; + +private: + UInt32 _inBufSize; + UInt32 _inBufSize_Allocated; + Byte *_inBuf; + size_t _afterDecoding_tempPos; + + #ifndef Z7_NO_READ_FROM_CODER_ZSTD + CMyComPtr _inStream; + HRESULT _hres_Read; + HRESULT _hres_Decode; + UInt64 _writtenSize; + bool _readWasFinished; + bool _wasFinished; + #endif + +public: + bool FinishMode; + Byte DisableHash; + CZstdDecResInfo ResInfo; + + HRESULT GetFinishResult(); + + CDecoder(); + ~CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Compress/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/makefile --- p7zip-rar-16.02/CPP/7zip/Compress/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Compress/makefile 2009-08-14 13:19:37.000000000 +0000 @@ -0,0 +1,7 @@ +DIRS = \ + LZMA_Alone\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/Crc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc.mak --- p7zip-rar-16.02/CPP/7zip/Crc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc.mak 2023-11-09 07:00:00.000000000 +0000 @@ -0,0 +1,8 @@ +C_OBJS = $(C_OBJS) \ + $O\7zCrc.obj +!IF defined(USE_NO_ASM) || defined(USE_C_CRC) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ +!ELSE +ASM_OBJS = $(ASM_OBJS) \ +!ENDIF + $O\7zCrcOpt.obj diff -Nru p7zip-rar-16.02/CPP/7zip/Crc64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc64.mak --- p7zip-rar-16.02/CPP/7zip/Crc64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crc64.mak 2023-11-11 20:00:00.000000000 +0000 @@ -0,0 +1,8 @@ +C_OBJS = $(C_OBJS) \ + $O\XzCrc64.obj +!IF defined(USE_NO_ASM) || defined(USE_C_CRC64) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ +!ELSE +ASM_OBJS = $(ASM_OBJS) \ +!ENDIF + $O\XzCrc64Opt.obj diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/7zAes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/7zAes.cpp 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.cpp 2023-11-29 18:00:00.000000000 +0000 @@ -1,280 +1,315 @@ -// 7zAes.cpp - -#include "StdAfx.h" - -#include "../../../C/Sha256.h" - -#include "../../Common/ComTry.h" - -#ifndef _7ZIP_ST -#include "../../Windows/Synchronization.h" -#endif - -#include "../Common/StreamUtils.h" - -#include "7zAes.h" -#include "MyAes.h" - -#ifndef EXTRACT_ONLY -#include "RandGen.h" -#endif - -namespace NCrypto { -namespace N7z { - -static const unsigned k_NumCyclesPower_Supported_MAX = 24; - -bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const -{ - if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) - return false; - for (unsigned i = 0; i < SaltSize; i++) - if (Salt[i] != a.Salt[i]) - return false; - return (Password == a.Password); -} - -void CKeyInfo::CalcKey() -{ - if (NumCyclesPower == 0x3F) - { - unsigned pos; - for (pos = 0; pos < SaltSize; pos++) - Key[pos] = Salt[pos]; - for (unsigned i = 0; i < Password.Size() && pos < kKeySize; i++) - Key[pos++] = Password[i]; - for (; pos < kKeySize; pos++) - Key[pos] = 0; - } - else - { - size_t bufSize = 8 + SaltSize + Password.Size(); - CObjArray buf(bufSize); - memcpy(buf, Salt, SaltSize); - memcpy(buf + SaltSize, Password, Password.Size()); - - CSha256 sha; - Sha256_Init(&sha); - - Byte *ctr = buf + SaltSize + Password.Size(); - - for (unsigned i = 0; i < 8; i++) - ctr[i] = 0; - - UInt64 numRounds = (UInt64)1 << NumCyclesPower; - - do - { - Sha256_Update(&sha, buf, bufSize); - for (unsigned i = 0; i < 8; i++) - if (++(ctr[i]) != 0) - break; - } - while (--numRounds != 0); - - Sha256_Final(&sha, Key); - } -} - -bool CKeyInfoCache::GetKey(CKeyInfo &key) -{ - FOR_VECTOR (i, Keys) - { - const CKeyInfo &cached = Keys[i]; - if (key.IsEqualTo(cached)) - { - for (unsigned j = 0; j < kKeySize; j++) - key.Key[j] = cached.Key[j]; - if (i != 0) - Keys.MoveToFront(i); - return true; - } - } - return false; -} - -void CKeyInfoCache::FindAndAdd(const CKeyInfo &key) -{ - FOR_VECTOR (i, Keys) - { - const CKeyInfo &cached = Keys[i]; - if (key.IsEqualTo(cached)) - { - if (i != 0) - Keys.MoveToFront(i); - return; - } - } - Add(key); -} - -void CKeyInfoCache::Add(const CKeyInfo &key) -{ - if (Keys.Size() >= Size) - Keys.DeleteBack(); - Keys.Insert(0, key); -} - -static CKeyInfoCache g_GlobalKeyCache(32); - -#ifndef _7ZIP_ST - static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; - #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); -#else - #define MT_LOCK -#endif - -CBase::CBase(): - _cachedKeys(16), - _ivSize(0) -{ - for (unsigned i = 0; i < sizeof(_iv); i++) - _iv[i] = 0; -} - -void CBase::PrepareKey() -{ - // BCJ2 threads use same password. So we use long lock. - MT_LOCK - - bool finded = false; - if (!_cachedKeys.GetKey(_key)) - { - finded = g_GlobalKeyCache.GetKey(_key); - if (!finded) - _key.CalcKey(); - _cachedKeys.Add(_key); - } - if (!finded) - g_GlobalKeyCache.FindAndAdd(_key); -} - -#ifndef EXTRACT_ONLY - -/* -STDMETHODIMP CEncoder::ResetSalt() -{ - _key.SaltSize = 4; - g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); - return S_OK; -} -*/ - -STDMETHODIMP CEncoder::ResetInitVector() -{ - for (unsigned i = 0; i < sizeof(_iv); i++) - _iv[i] = 0; - _ivSize = 8; - g_RandomGenerator.Generate(_iv, _ivSize); - return S_OK; -} - -STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) -{ - Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)]; - unsigned propsSize = 1; - - props[0] = (Byte)(_key.NumCyclesPower - | (_key.SaltSize == 0 ? 0 : (1 << 7)) - | (_ivSize == 0 ? 0 : (1 << 6))); - - if (_key.SaltSize != 0 || _ivSize != 0) - { - props[1] = (Byte)( - ((_key.SaltSize == 0 ? 0 : _key.SaltSize - 1) << 4) - | (_ivSize == 0 ? 0 : _ivSize - 1)); - memcpy(props + 2, _key.Salt, _key.SaltSize); - propsSize = 2 + _key.SaltSize; - memcpy(props + propsSize, _iv, _ivSize); - propsSize += _ivSize; - } - - return WriteStream(outStream, props, propsSize); -} - -CEncoder::CEncoder() -{ - // _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); - // _key.NumCyclesPower = 0x3F; - _key.NumCyclesPower = 19; - _aesFilter = new CAesCbcEncoder(kKeySize); -} - -#endif - -CDecoder::CDecoder() -{ - _aesFilter = new CAesCbcDecoder(kKeySize); -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - _key.ClearProps(); - - _ivSize = 0; - unsigned i; - for (i = 0; i < sizeof(_iv); i++) - _iv[i] = 0; - - if (size == 0) - return S_OK; - - Byte b0 = data[0]; - - _key.NumCyclesPower = b0 & 0x3F; - if ((b0 & 0xC0) == 0) - return size == 1 ? S_OK : E_INVALIDARG; - - if (size <= 1) - return E_INVALIDARG; - - Byte b1 = data[1]; - - unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4); - unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F); - - if (size != 2 + saltSize + ivSize) - return E_INVALIDARG; - _key.SaltSize = saltSize; - data += 2; - for (i = 0; i < saltSize; i++) - _key.Salt[i] = *data++; - for (i = 0; i < ivSize; i++) - _iv[i] = *data++; - return (_key.NumCyclesPower <= k_NumCyclesPower_Supported_MAX - || _key.NumCyclesPower == 0x3F) ? S_OK : E_NOTIMPL; -} - - -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - COM_TRY_BEGIN - - _key.Password.CopyFrom(data, (size_t)size); - return S_OK; - - COM_TRY_END -} - -STDMETHODIMP CBaseCoder::Init() -{ - COM_TRY_BEGIN - - PrepareKey(); - CMyComPtr cp; - RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); - if (!cp) - return E_FAIL; - RINOK(cp->SetKey(_key.Key, kKeySize)); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); - return _aesFilter->Init(); - - COM_TRY_END -} - -STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) -{ - return _aesFilter->Filter(data, size); -} - -}} +// 7zAes.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/Sha256.h" + +#include "../../Common/ComTry.h" +#include "../../Common/MyBuffer2.h" + +#ifndef Z7_ST +#include "../../Windows/Synchronization.h" +#endif + +#include "../Common/StreamUtils.h" + +#include "7zAes.h" +#include "MyAes.h" + +#ifndef Z7_EXTRACT_ONLY +#include "RandGen.h" +#endif + +namespace NCrypto { +namespace N7z { + +static const unsigned k_NumCyclesPower_Supported_MAX = 24; + +bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const +{ + if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) + return false; + for (unsigned i = 0; i < SaltSize; i++) + if (Salt[i] != a.Salt[i]) + return false; + return (Password == a.Password); +} + +void CKeyInfo::CalcKey() +{ + if (NumCyclesPower == 0x3F) + { + unsigned pos; + for (pos = 0; pos < SaltSize; pos++) + Key[pos] = Salt[pos]; + for (unsigned i = 0; i < Password.Size() && pos < kKeySize; i++) + Key[pos++] = Password[i]; + for (; pos < kKeySize; pos++) + Key[pos] = 0; + } + else + { + const unsigned kUnrPow = 6; + const UInt32 numUnroll = (UInt32)1 << (NumCyclesPower <= kUnrPow ? (unsigned)NumCyclesPower : kUnrPow); + + const size_t bufSize = 8 + SaltSize + Password.Size(); + const size_t unrollSize = bufSize * numUnroll; + + // MY_ALIGN (16) + // CSha256 sha; + const size_t shaAllocSize = sizeof(CSha256) + unrollSize + bufSize * 2; + CAlignedBuffer1 sha(shaAllocSize); + Byte *buf = sha + sizeof(CSha256); + + memcpy(buf, Salt, SaltSize); + memcpy(buf + SaltSize, Password, Password.Size()); + memset(buf + bufSize - 8, 0, 8); + + Sha256_Init((CSha256 *)(void *)(Byte *)sha); + + { + { + Byte *dest = buf; + for (UInt32 i = 1; i < numUnroll; i++) + { + dest += bufSize; + memcpy(dest, buf, bufSize); + } + } + + const UInt32 numRounds = (UInt32)1 << NumCyclesPower; + UInt32 r = 0; + do + { + Byte *dest = buf + bufSize - 8; + UInt32 i = r; + r += numUnroll; + do + { + SetUi32(dest, i) i++; dest += bufSize; + // SetUi32(dest, i) i++; dest += bufSize; + } + while (i < r); + Sha256_Update((CSha256 *)(void *)(Byte *)sha, buf, unrollSize); + } + while (r < numRounds); + } + /* + UInt64 numRounds = (UInt64)1 << NumCyclesPower; + + do + { + Sha256_Update((CSha256 *)(Byte *)sha, buf, bufSize); + for (unsigned i = 0; i < 8; i++) + if (++(ctr[i]) != 0) + break; + } + while (--numRounds != 0); + */ + + Sha256_Final((CSha256 *)(void *)(Byte *)sha, Key); + memset(sha, 0, shaAllocSize); + } +} + +bool CKeyInfoCache::GetKey(CKeyInfo &key) +{ + FOR_VECTOR (i, Keys) + { + const CKeyInfo &cached = Keys[i]; + if (key.IsEqualTo(cached)) + { + for (unsigned j = 0; j < kKeySize; j++) + key.Key[j] = cached.Key[j]; + if (i != 0) + Keys.MoveToFront(i); + return true; + } + } + return false; +} + +void CKeyInfoCache::FindAndAdd(const CKeyInfo &key) +{ + FOR_VECTOR (i, Keys) + { + const CKeyInfo &cached = Keys[i]; + if (key.IsEqualTo(cached)) + { + if (i != 0) + Keys.MoveToFront(i); + return; + } + } + Add(key); +} + +void CKeyInfoCache::Add(const CKeyInfo &key) +{ + if (Keys.Size() >= Size) + Keys.DeleteBack(); + Keys.Insert(0, key); +} + +static CKeyInfoCache g_GlobalKeyCache(32); + +#ifndef Z7_ST + static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; + #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); +#else + #define MT_LOCK +#endif + +CBase::CBase(): + _cachedKeys(16), + _ivSize(0) +{ + for (unsigned i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; +} + +void CBase::PrepareKey() +{ + // BCJ2 threads use same password. So we use long lock. + MT_LOCK + + bool finded = false; + if (!_cachedKeys.GetKey(_key)) + { + finded = g_GlobalKeyCache.GetKey(_key); + if (!finded) + _key.CalcKey(); + _cachedKeys.Add(_key); + } + if (!finded) + g_GlobalKeyCache.FindAndAdd(_key); +} + +#ifndef Z7_EXTRACT_ONLY + +/* +Z7_COM7F_IMF(CEncoder::ResetSalt()) +{ + _key.SaltSize = 4; + g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); + return S_OK; +} +*/ + +Z7_COM7F_IMF(CEncoder::ResetInitVector()) +{ + for (unsigned i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; + _ivSize = 16; + MY_RAND_GEN(_iv, _ivSize); + return S_OK; +} + +Z7_COM7F_IMF(CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)) +{ + Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)]; + unsigned propsSize = 1; + + props[0] = (Byte)(_key.NumCyclesPower + | (_key.SaltSize == 0 ? 0 : (1 << 7)) + | (_ivSize == 0 ? 0 : (1 << 6))); + + if (_key.SaltSize != 0 || _ivSize != 0) + { + props[1] = (Byte)( + ((_key.SaltSize == 0 ? 0 : _key.SaltSize - 1) << 4) + | (_ivSize == 0 ? 0 : _ivSize - 1)); + memcpy(props + 2, _key.Salt, _key.SaltSize); + propsSize = 2 + _key.SaltSize; + memcpy(props + propsSize, _iv, _ivSize); + propsSize += _ivSize; + } + + return WriteStream(outStream, props, propsSize); +} + +CEncoder::CEncoder() +{ + // _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); + // _key.NumCyclesPower = 0x3F; + _key.NumCyclesPower = 19; + _aesFilter = new CAesCbcEncoder(kKeySize); +} + +#endif + +CDecoder::CDecoder() +{ + _aesFilter = new CAesCbcDecoder(kKeySize); +} + +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + _key.ClearProps(); + + _ivSize = 0; + unsigned i; + for (i = 0; i < sizeof(_iv); i++) + _iv[i] = 0; + + if (size == 0) + return S_OK; + + const unsigned b0 = data[0]; + _key.NumCyclesPower = b0 & 0x3F; + if ((b0 & 0xC0) == 0) + return size == 1 ? S_OK : E_INVALIDARG; + if (size <= 1) + return E_INVALIDARG; + + const unsigned b1 = data[1]; + const unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4); + const unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F); + + if (size != 2 + saltSize + ivSize) + return E_INVALIDARG; + _key.SaltSize = saltSize; + data += 2; + for (i = 0; i < saltSize; i++) + _key.Salt[i] = *data++; + for (i = 0; i < ivSize; i++) + _iv[i] = *data++; + return (_key.NumCyclesPower <= k_NumCyclesPower_Supported_MAX + || _key.NumCyclesPower == 0x3F) ? S_OK : E_NOTIMPL; +} + + +Z7_COM7F_IMF(CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)) +{ + COM_TRY_BEGIN + + _key.Password.Wipe(); + _key.Password.CopyFrom(data, (size_t)size); + return S_OK; + + COM_TRY_END +} + +Z7_COM7F_IMF(CBaseCoder::Init()) +{ + COM_TRY_BEGIN + + PrepareKey(); + CMyComPtr cp; + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)) + if (!cp) + return E_FAIL; + RINOK(cp->SetKey(_key.Key, kKeySize)) + RINOK(cp->SetInitVector(_iv, sizeof(_iv))) + return _aesFilter->Init(); + + COM_TRY_END +} + +Z7_COM7F_IMF2(UInt32, CBaseCoder::Filter(Byte *data, UInt32 size)) +{ + return _aesFilter->Filter(data, size); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/7zAes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.h --- p7zip-rar-16.02/CPP/7zip/Crypto/7zAes.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAes.h 2023-05-04 17:00:00.000000000 +0000 @@ -1,118 +1,130 @@ -// 7zAes.h - -#ifndef __CRYPTO_7Z_AES_H -#define __CRYPTO_7Z_AES_H - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" -#include "../../Common/MyVector.h" - -#include "../ICoder.h" -#include "../IPassword.h" - -namespace NCrypto { -namespace N7z { - -const unsigned kKeySize = 32; -const unsigned kSaltSizeMax = 16; -const unsigned kIvSizeMax = 16; // AES_BLOCK_SIZE; - -class CKeyInfo -{ -public: - unsigned NumCyclesPower; - unsigned SaltSize; - Byte Salt[kSaltSizeMax]; - CByteBuffer Password; - Byte Key[kKeySize]; - - bool IsEqualTo(const CKeyInfo &a) const; - void CalcKey(); - - CKeyInfo() { ClearProps(); } - void ClearProps() - { - NumCyclesPower = 0; - SaltSize = 0; - for (unsigned i = 0; i < sizeof(Salt); i++) - Salt[i] = 0; - } -}; - -class CKeyInfoCache -{ - unsigned Size; - CObjectVector Keys; -public: - CKeyInfoCache(unsigned size): Size(size) {} - bool GetKey(CKeyInfo &key); - void Add(const CKeyInfo &key); - void FindAndAdd(const CKeyInfo &key); -}; - -class CBase -{ - CKeyInfoCache _cachedKeys; -protected: - CKeyInfo _key; - Byte _iv[kIvSizeMax]; - unsigned _ivSize; - - void PrepareKey(); - CBase(); -}; - -class CBaseCoder: - public ICompressFilter, - public ICryptoSetPassword, - public CMyUnknownImp, - public CBase -{ -protected: - CMyComPtr _aesFilter; - -public: - INTERFACE_ICompressFilter(;) - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); -}; - -#ifndef EXTRACT_ONLY - -class CEncoder: - public CBaseCoder, - public ICompressWriteCoderProperties, - // public ICryptoResetSalt, - public ICryptoResetInitVector -{ -public: - MY_UNKNOWN_IMP4( - ICompressFilter, - ICryptoSetPassword, - ICompressWriteCoderProperties, - // ICryptoResetSalt, - ICryptoResetInitVector) - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); - // STDMETHOD(ResetSalt)(); - STDMETHOD(ResetInitVector)(); - CEncoder(); -}; - -#endif - -class CDecoder: - public CBaseCoder, - public ICompressSetDecoderProperties2 -{ -public: - MY_UNKNOWN_IMP3( - ICompressFilter, - ICryptoSetPassword, - ICompressSetDecoderProperties2) - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - CDecoder(); -}; - -}} - -#endif +// 7zAes.h + +#ifndef ZIP7_INC_CRYPTO_7Z_AES_H +#define ZIP7_INC_CRYPTO_7Z_AES_H + +#include "../../Common/MyBuffer.h" +#include "../../Common/MyCom.h" +#include "../../Common/MyVector.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace N7z { + +const unsigned kKeySize = 32; +const unsigned kSaltSizeMax = 16; +const unsigned kIvSizeMax = 16; // AES_BLOCK_SIZE; + +class CKeyInfo +{ +public: + unsigned NumCyclesPower; + unsigned SaltSize; + Byte Salt[kSaltSizeMax]; + CByteBuffer Password; + Byte Key[kKeySize]; + + bool IsEqualTo(const CKeyInfo &a) const; + void CalcKey(); + + CKeyInfo() { ClearProps(); } + void ClearProps() + { + NumCyclesPower = 0; + SaltSize = 0; + for (unsigned i = 0; i < sizeof(Salt); i++) + Salt[i] = 0; + } + + void Wipe() + { + Password.Wipe(); + NumCyclesPower = 0; + SaltSize = 0; + Z7_memset_0_ARRAY(Salt); + Z7_memset_0_ARRAY(Key); + } + +#ifdef Z7_CPP_IS_SUPPORTED_default + CKeyInfo(const CKeyInfo &) = default; +#endif + ~CKeyInfo() { Wipe(); } +}; + +class CKeyInfoCache +{ + unsigned Size; + CObjectVector Keys; +public: + CKeyInfoCache(unsigned size): Size(size) {} + bool GetKey(CKeyInfo &key); + void Add(const CKeyInfo &key); + void FindAndAdd(const CKeyInfo &key); +}; + +class CBase +{ + CKeyInfoCache _cachedKeys; +protected: + CKeyInfo _key; + Byte _iv[kIvSizeMax]; + unsigned _ivSize; + + void PrepareKey(); + CBase(); +}; + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp, + public CBase +{ + Z7_IFACE_COM7_IMP(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoSetPassword) +protected: + virtual ~CBaseCoder() {} + CMyComPtr _aesFilter; +}; + +#ifndef Z7_EXTRACT_ONLY + +class CEncoder Z7_final: + public CBaseCoder, + public ICompressWriteCoderProperties, + // public ICryptoResetSalt, + public ICryptoResetInitVector +{ + Z7_COM_UNKNOWN_IMP_4( + ICompressFilter, + ICryptoSetPassword, + ICompressWriteCoderProperties, + // ICryptoResetSalt, + ICryptoResetInitVector) + Z7_IFACE_COM7_IMP(ICompressWriteCoderProperties) + // Z7_IFACE_COM7_IMP(ICryptoResetSalt) + Z7_IFACE_COM7_IMP(ICryptoResetInitVector) +public: + CEncoder(); +}; + +#endif + +class CDecoder Z7_final: + public CBaseCoder, + public ICompressSetDecoderProperties2 +{ + Z7_COM_UNKNOWN_IMP_3( + ICompressFilter, + ICryptoSetPassword, + ICompressSetDecoderProperties2) + Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) +public: + CDecoder(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/7zAesRegister.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAesRegister.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/7zAesRegister.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/7zAesRegister.cpp 2022-12-19 22:00:00.000000000 +0000 @@ -1,17 +1,17 @@ -// 7zAesRegister.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "7zAes.h" - -namespace NCrypto { -namespace N7z { - -REGISTER_FILTER_E(7zAES, - CDecoder(), - CEncoder(), - 0x6F10701, "7zAES") - -}} +// 7zAesRegister.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "7zAes.h" + +namespace NCrypto { +namespace N7z { + +REGISTER_FILTER_E(SzAES, + CDecoder, + CEncoder, + 0x6F10701, "7zAES") + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Codec.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Codec.def --- p7zip-rar-16.02/CPP/7zip/Crypto/Codec.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Codec.def 2005-07-24 16:40:16.000000000 +0000 @@ -0,0 +1,4 @@ +EXPORTS + CreateObject PRIVATE + GetNumberOfMethods PRIVATE + GetMethodProperty PRIVATE diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha1.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha1.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -1,120 +1,94 @@ -// HmacSha1.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "HmacSha1.h" - -namespace NCrypto { -namespace NSha1 { - -void CHmac::SetKey(const Byte *key, size_t keySize) -{ - Byte keyTemp[kBlockSize]; - size_t i; - - for (i = 0; i < kBlockSize; i++) - keyTemp[i] = 0; - - if (keySize > kBlockSize) - { - _sha.Init(); - _sha.Update(key, keySize); - _sha.Final(keyTemp); - } - else - for (i = 0; i < keySize; i++) - keyTemp[i] = key[i]; - - for (i = 0; i < kBlockSize; i++) - keyTemp[i] ^= 0x36; - - _sha.Init(); - _sha.Update(keyTemp, kBlockSize); - - for (i = 0; i < kBlockSize; i++) - keyTemp[i] ^= 0x36 ^ 0x5C; - - _sha2.Init(); - _sha2.Update(keyTemp, kBlockSize); -} - -void CHmac::Final(Byte *mac, size_t macSize) -{ - Byte digest[kDigestSize]; - _sha.Final(digest); - _sha2.Update(digest, kDigestSize); - _sha2.Final(digest); - for (size_t i = 0; i < macSize; i++) - mac[i] = digest[i]; -} - - -void CHmac32::SetKey(const Byte *key, size_t keySize) -{ - UInt32 keyTemp[kNumBlockWords]; - size_t i; - - for (i = 0; i < kNumBlockWords; i++) - keyTemp[i] = 0; - - if (keySize > kBlockSize) - { - CContext sha; - sha.Init(); - sha.Update(key, keySize); - Byte digest[kDigestSize]; - sha.Final(digest); - - for (i = 0 ; i < kNumDigestWords; i++) - keyTemp[i] = GetBe32(digest + i * 4 + 0); - } - else - for (i = 0; i < keySize; i++) - keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3))); - - for (i = 0; i < kNumBlockWords; i++) - keyTemp[i] ^= 0x36363636; - - _sha.Init(); - _sha.Update(keyTemp, kNumBlockWords); - - for (i = 0; i < kNumBlockWords; i++) - keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C; - - _sha2.Init(); - _sha2.Update(keyTemp, kNumBlockWords); -} - -void CHmac32::Final(UInt32 *mac, size_t macSize) -{ - UInt32 digest[kNumDigestWords]; - _sha.Final(digest); - _sha2.Update(digest, kNumDigestWords); - _sha2.Final(digest); - for (size_t i = 0; i < macSize; i++) - mac[i] = digest[i]; -} - -void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration) -{ - UInt32 block[kNumBlockWords]; - UInt32 block2[kNumBlockWords]; - - _sha.PrepareBlock(block, kNumDigestWords); - _sha2.PrepareBlock(block2, kNumDigestWords); - - for (unsigned s = 0; s < kNumDigestWords; s++) - block[s] = mac[s]; - - for (UInt32 i = 0; i < numIteration; i++) - { - _sha.GetBlockDigest(block, block2); - _sha2.GetBlockDigest(block2, block); - for (unsigned s = 0; s < kNumDigestWords; s++) - mac[s] ^= block[s]; - } -} - -}} +// HmacSha1.cpp + +#include "StdAfx.h" + +#include + +#include "../../../C/CpuArch.h" + +#include "HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void CHmac::SetKey(const Byte *key, size_t keySize) +{ + MY_ALIGN (16) + UInt32 temp[SHA1_NUM_BLOCK_WORDS]; + size_t i; + + for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) + temp[i] = 0; + + if (keySize > kBlockSize) + { + _sha.Init(); + _sha.Update(key, keySize); + _sha.Final((Byte *)temp); + } + else + memcpy(temp, key, keySize); + + for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) + temp[i] ^= 0x36363636; + + _sha.Init(); + _sha.Update((const Byte *)temp, kBlockSize); + + for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) + temp[i] ^= 0x36363636 ^ 0x5C5C5C5C; + + _sha2.Init(); + _sha2.Update((const Byte *)temp, kBlockSize); +} + + +void CHmac::Final(Byte *mac) +{ + _sha.Final(mac); + _sha2.Update(mac, kDigestSize); + _sha2.Final(mac); +} + + +void CHmac::GetLoopXorDigest1(void *mac, UInt32 numIteration) +{ + MY_ALIGN (16) UInt32 block [SHA1_NUM_BLOCK_WORDS]; + MY_ALIGN (16) UInt32 block2[SHA1_NUM_BLOCK_WORDS]; + MY_ALIGN (16) UInt32 mac2 [SHA1_NUM_BLOCK_WORDS]; + + _sha. PrepareBlock((Byte *)block, SHA1_DIGEST_SIZE); + _sha2.PrepareBlock((Byte *)block2, SHA1_DIGEST_SIZE); + + block[0] = ((const UInt32 *)mac)[0]; + block[1] = ((const UInt32 *)mac)[1]; + block[2] = ((const UInt32 *)mac)[2]; + block[3] = ((const UInt32 *)mac)[3]; + block[4] = ((const UInt32 *)mac)[4]; + + mac2[0] = block[0]; + mac2[1] = block[1]; + mac2[2] = block[2]; + mac2[3] = block[3]; + mac2[4] = block[4]; + + for (UInt32 i = 0; i < numIteration; i++) + { + _sha. GetBlockDigest((const Byte *)block, (Byte *)block2); + _sha2.GetBlockDigest((const Byte *)block2, (Byte *)block); + + mac2[0] ^= block[0]; + mac2[1] ^= block[1]; + mac2[2] ^= block[2]; + mac2[3] ^= block[3]; + mac2[4] ^= block[4]; + } + + ((UInt32 *)mac)[0] = mac2[0]; + ((UInt32 *)mac)[1] = mac2[1]; + ((UInt32 *)mac)[2] = mac2[2]; + ((UInt32 *)mac)[3] = mac2[3]; + ((UInt32 *)mac)[4] = mac2[4]; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha1.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.h --- p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha1.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha1.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,39 +1,31 @@ -// HmacSha1.h -// Implements HMAC-SHA-1 (RFC2104, FIPS-198) - -#ifndef __CRYPTO_HMAC_SHA1_H -#define __CRYPTO_HMAC_SHA1_H - -#include "Sha1Cls.h" - -namespace NCrypto { -namespace NSha1 { - -// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize); - -class CHmac -{ - CContext _sha; - CContext _sha2; -public: - void SetKey(const Byte *key, size_t keySize); - void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); } - void Final(Byte *mac, size_t macSize = kDigestSize); -}; - -class CHmac32 -{ - CContext32 _sha; - CContext32 _sha2; -public: - void SetKey(const Byte *key, size_t keySize); - void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); } - void Final(UInt32 *mac, size_t macSize = kNumDigestWords); - - // It'sa for hmac function. in,out: mac[kNumDigestWords]. - void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration); -}; - -}} - -#endif +// HmacSha1.h +// Implements HMAC-SHA-1 (RFC2104, FIPS-198) + +#ifndef ZIP7_INC_CRYPTO_HMAC_SHA1_H +#define ZIP7_INC_CRYPTO_HMAC_SHA1_H + +#include "Sha1Cls.h" + +namespace NCrypto { +namespace NSha1 { + +// Use: SetKey(key, keySize); for () Update(data, size); FinalFull(mac); + +class CHmac +{ + CContext _sha; + CContext _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); } + + // Final() : mac is recommended to be aligned for 4 bytes + // GetLoopXorDigest1() : mac is required to be aligned for 4 bytes + // The caller can use: UInt32 mac[NSha1::kNumDigestWords] and typecast to (Byte *) and (void *); + void Final(Byte *mac); + void GetLoopXorDigest1(void *mac, UInt32 numIteration); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha256.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha256.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -1,62 +1,53 @@ -// HmacSha256.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "HmacSha256.h" - -namespace NCrypto { -namespace NSha256 { - -static const unsigned kBlockSize = 64; - -void CHmac::SetKey(const Byte *key, size_t keySize) -{ - Byte temp[kBlockSize]; - size_t i; - - for (i = 0; i < kBlockSize; i++) - temp[i] = 0; - - if (keySize > kBlockSize) - { - Sha256_Init(&_sha); - Sha256_Update(&_sha, key, keySize); - Sha256_Final(&_sha, temp); - } - else - for (i = 0; i < keySize; i++) - temp[i] = key[i]; - - for (i = 0; i < kBlockSize; i++) - temp[i] ^= 0x36; - - Sha256_Init(&_sha); - Sha256_Update(&_sha, temp, kBlockSize); - - for (i = 0; i < kBlockSize; i++) - temp[i] ^= 0x36 ^ 0x5C; - - Sha256_Init(&_sha2); - Sha256_Update(&_sha2, temp, kBlockSize); -} - -void CHmac::Final(Byte *mac) -{ - Sha256_Final(&_sha, mac); - Sha256_Update(&_sha2, mac, SHA256_DIGEST_SIZE); - Sha256_Final(&_sha2, mac); -} - -/* -void CHmac::Final(Byte *mac, size_t macSize) -{ - Byte digest[SHA256_DIGEST_SIZE]; - Final(digest); - for (size_t i = 0; i < macSize; i++) - mac[i] = digest[i]; -} -*/ - -}} +// HmacSha256.cpp + +#include "StdAfx.h" + +#include + +#include "../../../C/CpuArch.h" + +#include "HmacSha256.h" + +namespace NCrypto { +namespace NSha256 { + +void CHmac::SetKey(const Byte *key, size_t keySize) +{ + MY_ALIGN (16) + UInt32 temp[SHA256_NUM_BLOCK_WORDS]; + size_t i; + + for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++) + temp[i] = 0; + + if (keySize > kBlockSize) + { + Sha256_Init(&_sha); + Sha256_Update(&_sha, key, keySize); + Sha256_Final(&_sha, (Byte *)temp); + } + else + memcpy(temp, key, keySize); + + for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++) + temp[i] ^= 0x36363636; + + Sha256_Init(&_sha); + Sha256_Update(&_sha, (const Byte *)temp, kBlockSize); + + for (i = 0; i < SHA256_NUM_BLOCK_WORDS; i++) + temp[i] ^= 0x36363636 ^ 0x5C5C5C5C; + + Sha256_Init(&_sha2); + Sha256_Update(&_sha2, (const Byte *)temp, kBlockSize); +} + + +void CHmac::Final(Byte *mac) +{ + Sha256_Final(&_sha, mac); + Sha256_Update(&_sha2, mac, SHA256_DIGEST_SIZE); + Sha256_Final(&_sha2, mac); +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha256.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.h --- p7zip-rar-16.02/CPP/7zip/Crypto/HmacSha256.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/HmacSha256.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,27 +1,27 @@ -// HmacSha256.h -// Implements HMAC-SHA-256 (RFC2104, FIPS-198) - -#ifndef __CRYPTO_HMAC_SHA256_H -#define __CRYPTO_HMAC_SHA256_H - -#include "../../../C/Sha256.h" - -namespace NCrypto { -namespace NSha256 { - -const unsigned kDigestSize = SHA256_DIGEST_SIZE; - -class CHmac -{ - CSha256 _sha; - CSha256 _sha2; -public: - void SetKey(const Byte *key, size_t keySize); - void Update(const Byte *data, size_t dataSize) { Sha256_Update(&_sha, data, dataSize); } - void Final(Byte *mac); - // void Final(Byte *mac, size_t macSize); -}; - -}} - -#endif +// HmacSha256.h +// Implements HMAC-SHA-256 (RFC2104, FIPS-198) + +#ifndef ZIP7_INC_CRYPTO_HMAC_SHA256_H +#define ZIP7_INC_CRYPTO_HMAC_SHA256_H + +#include "../../../C/Sha256.h" + +namespace NCrypto { +namespace NSha256 { + +const unsigned kBlockSize = SHA256_BLOCK_SIZE; +const unsigned kDigestSize = SHA256_DIGEST_SIZE; + +class CHmac +{ + CSha256 _sha; + CSha256 _sha2; +public: + void SetKey(const Byte *key, size_t keySize); + void Update(const Byte *data, size_t dataSize) { Sha256_Update(&_sha, data, dataSize); } + void Final(Byte *mac); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/MyAes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/MyAes.cpp 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.cpp 2024-12-10 08:00:00.000000000 +0000 @@ -1,114 +1,277 @@ -// Crypto/MyAes.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "MyAes.h" - -namespace NCrypto { - -static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; - -CAesCbcCoder::CAesCbcCoder(bool encodeMode, unsigned keySize): - _keySize(keySize), - _keyIsSet(false), - _encodeMode(encodeMode) -{ - _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); - memset(_iv, 0, AES_BLOCK_SIZE); - SetFunctions(0); -} - -STDMETHODIMP CAesCbcCoder::Init() -{ - AesCbc_Init(_aes + _offset, _iv); - return _keyIsSet ? S_OK : E_FAIL; -} - -STDMETHODIMP_(UInt32) CAesCbcCoder::Filter(Byte *data, UInt32 size) -{ - if (!_keyIsSet) - return 0; - if (size == 0) - return 0; - if (size < AES_BLOCK_SIZE) - return AES_BLOCK_SIZE; - size >>= 4; - _codeFunc(_aes + _offset, data, size); - return size << 4; -} - -STDMETHODIMP CAesCbcCoder::SetKey(const Byte *data, UInt32 size) -{ - if ((size & 0x7) != 0 || size < 16 || size > 32) - return E_INVALIDARG; - if (_keySize != 0 && size != _keySize) - return E_INVALIDARG; - AES_SET_KEY_FUNC setKeyFunc = _encodeMode ? Aes_SetKey_Enc : Aes_SetKey_Dec; - setKeyFunc(_aes + _offset + 4, data, size); - _keyIsSet = true; - return S_OK; -} - -STDMETHODIMP CAesCbcCoder::SetInitVector(const Byte *data, UInt32 size) -{ - if (size != AES_BLOCK_SIZE) - return E_INVALIDARG; - memcpy(_iv, data, size); - CAesCbcCoder::Init(); // don't call virtual function here !!! - return S_OK; -} - -EXTERN_C_BEGIN - -void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); - -void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); -void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); - -EXTERN_C_END - -bool CAesCbcCoder::SetFunctions(UInt32 algo) -{ - _codeFunc = _encodeMode ? - g_AesCbc_Encode : - g_AesCbc_Decode; - if (algo == 1) - { - _codeFunc = _encodeMode ? - AesCbc_Encode: - AesCbc_Decode; - } - if (algo == 2) - { - #ifdef MY_CPU_X86_OR_AMD64 - #ifdef _7ZIP_ASM - if (g_AesCbc_Encode != AesCbc_Encode_Intel) - #endif - #endif - return false; - } - return true; -} - -STDMETHODIMP CAesCbcCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - if (propIDs[i] == NCoderPropID::kDefaultProp) - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - if (!SetFunctions(prop.ulVal)) - return E_NOTIMPL; - } - } - return S_OK; -} - -} +// Crypto/MyAes.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "MyAes.h" + +namespace NCrypto { + +static struct CAesTabInit { CAesTabInit() { AesGenTables();} } g_AesTabInit; + +CAesCoder::CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ): + _keyIsSet(false), + // _encodeMode(encodeMode), + // _ctrMode(ctrMode), + _keySize(keySize), + // _ctrPos(0), // _ctrPos =0 will be set in Init() + _aes(AES_NUM_IVMRK_WORDS * 4 + AES_BLOCK_SIZE * 2) +{ + // _offset = ((0 - (unsigned)(ptrdiff_t)_aes) & 0xF) / sizeof(UInt32); + memset(_iv, 0, AES_BLOCK_SIZE); + /* + // we can use the following code to test 32-bit overflow case for AES-CTR + for (unsigned i = 0; i < 16; i++) _iv[i] = (Byte)(i + 1); + _iv[0] = 0xFE; _iv[1] = _iv[2] = _iv[3] = 0xFF; + */ +} + +Z7_COM7F_IMF(CAesCoder::Init()) +{ + _ctrPos = 0; + AesCbc_Init(Aes(), _iv); + return _keyIsSet ? S_OK : E_NOTIMPL; // E_FAIL +} + +Z7_COM7F_IMF2(UInt32, CAesCoder::Filter(Byte *data, UInt32 size)) +{ + if (!_keyIsSet) + return 0; + if (size < AES_BLOCK_SIZE) + { + if (size == 0) + return 0; + return AES_BLOCK_SIZE; + } + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data, size); + return size << 4; +} + + +Z7_COM7F_IMF(CAesCoder::SetKey(const Byte *data, UInt32 size)) +{ + if ((size & 0x7) != 0 || size < 16 || size > 32) + return E_INVALIDARG; + if (_keySize != 0 && size != _keySize) + return E_INVALIDARG; + _setKeyFunc(Aes() + 4, data, size); + _keyIsSet = true; + return S_OK; +} + +Z7_COM7F_IMF(CAesCoder::SetInitVector(const Byte *data, UInt32 size)) +{ + if (size != AES_BLOCK_SIZE) + return E_INVALIDARG; + memcpy(_iv, data, size); + /* we allow SetInitVector() call before SetKey() call. + so we ignore possible error in Init() here */ + CAesCoder::Init(); // don't call virtual function here !!! + return S_OK; +} + + +#ifndef Z7_SFX + +/* +Z7_COM7F_IMF(CAesCtrCoder::Init()) +{ + _ctrPos = 0; + return CAesCoder::Init(); +} +*/ + +Z7_COM7F_IMF2(UInt32, CAesCtrCoder::Filter(Byte *data, UInt32 size)) +{ + if (!_keyIsSet) + return 0; + if (size == 0) + return 0; + + if (_ctrPos != 0) + { + /* Optimized caller will not call here */ + const Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + unsigned num = 0; + for (unsigned i = _ctrPos; i != AES_BLOCK_SIZE; i++) + { + if (num == size) + { + _ctrPos = i; + return num; + } + data[num++] ^= ctr[i]; + } + _ctrPos = 0; + /* if (num < size) { + we can filter more data with _codeFunc(). + But it's supposed that the caller can work correctly, + even if we do only partial filtering here. + So we filter data only for current 16-byte block. } + */ + /* + size -= num; + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data + num, size); + return num + (size << 4); + */ + return num; + } + + if (size < AES_BLOCK_SIZE) + { + /* The good optimized caller can call here only in last Filter() call. + But we support also non-optimized callers, + where another Filter() calls are allowed after this call. + */ + Byte *ctr = (Byte *)(Aes() + AES_NUM_IVMRK_WORDS); + memset(ctr, 0, AES_BLOCK_SIZE); + memcpy(ctr, data, size); + _codeFunc(Aes(), ctr, 1); + memcpy(data, ctr, size); + _ctrPos = size; + return size; + } + + size >>= 4; + // (data) must be aligned for 16-bytes here + _codeFunc(Aes(), data, size); + return size << 4; +} + +#endif // Z7_SFX + + +#ifndef Z7_EXTRACT_ONLY + +#ifdef MY_CPU_X86_OR_AMD64 + + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) + #define USE_HW_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_HW_VAES + #endif + #endif + #elif defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) + #define USE_HW_AES + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_HW_VAES + #endif + #elif defined(_MSC_VER) + #define USE_HW_AES + #define USE_HW_VAES + #endif + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__ARM_FEATURE_AES) \ + || defined(__ARM_FEATURE_CRYPTO) + #define USE_HW_AES + #else + #if defined(MY_CPU_ARM64) \ + || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \ + || defined(Z7_MSC_VER_ORIGINAL) + #if defined(__ARM_FP) && \ + ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \ + || defined(__GNUC__) && (__GNUC__ >= 6) \ + ) \ + || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910) + #if defined(MY_CPU_ARM64) \ + || !defined(Z7_CLANG_VERSION) \ + || defined(__ARM_NEON) && \ + (Z7_CLANG_VERSION < 170000 || \ + Z7_CLANG_VERSION > 170001) + #define USE_HW_AES + #endif + #endif + #endif + #endif +#endif + +#ifdef USE_HW_AES +// #pragma message("=== MyAES.c USE_HW_AES === ") + + #define SET_AES_FUNC_2(f2) \ + if (algo == 2) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW) \ + { f = f2; } + #ifdef USE_HW_VAES + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) \ + if (algo == 3) if (g_Aes_SupportedFunctions_Flags & k_Aes_SupportedFunctions_HW_256) \ + { f = f3; } + #else // USE_HW_VAES + #define SET_AES_FUNC_23(f2, f3) \ + SET_AES_FUNC_2(f2) + #endif // USE_HW_VAES +#else // USE_HW_AES + #define SET_AES_FUNC_23(f2, f3) +#endif // USE_HW_AES + +#define SET_AES_FUNCS(c, f0, f1, f2, f3) \ + bool c::SetFunctions(UInt32 algo) { \ + _codeFunc = f0; if (algo < 1) return true; \ + AES_CODE_FUNC f = NULL; \ + if (algo == 1) { f = f1; } \ + SET_AES_FUNC_23(f2, f3) \ + if (f) { _codeFunc = f; return true; } \ + return false; } + + + +#ifndef Z7_SFX +SET_AES_FUNCS( + CAesCtrCoder, + g_AesCtr_Code, + AesCtr_Code, + AesCtr_Code_HW, + AesCtr_Code_HW_256) +#endif + +SET_AES_FUNCS( + CAesCbcEncoder, + g_AesCbc_Encode, + AesCbc_Encode, + AesCbc_Encode_HW, + AesCbc_Encode_HW) + +SET_AES_FUNCS( + CAesCbcDecoder, + g_AesCbc_Decode, + AesCbc_Decode, + AesCbc_Decode_HW, + AesCbc_Decode_HW_256) + +Z7_COM7F_IMF(CAesCoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + UInt32 algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 3) + return E_NOTIMPL; + algo = prop.ulVal; + } + } + if (!SetFunctions(algo)) + return E_NOTIMPL; + return S_OK; +} + +#endif // Z7_EXTRACT_ONLY + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/MyAes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.h --- p7zip-rar-16.02/CPP/7zip/Crypto/MyAes.h 2016-05-18 17:30:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -1,55 +1,122 @@ -// Crypto/MyAes.h - -#ifndef __CRYPTO_MY_AES_H -#define __CRYPTO_MY_AES_H - -#include "../../../C/Aes.h" - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCrypto { - -class CAesCbcCoder: - public ICompressFilter, - public ICryptoProperties, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ - AES_CODE_FUNC _codeFunc; - unsigned _offset; - unsigned _keySize; - bool _keyIsSet; - bool _encodeMode; - UInt32 _aes[AES_NUM_IVMRK_WORDS + 3]; - Byte _iv[AES_BLOCK_SIZE]; - - bool SetFunctions(UInt32 algo); - -public: - CAesCbcCoder(bool encodeMode, unsigned keySize); - - MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties) - - INTERFACE_ICompressFilter(;) - - STDMETHOD(SetKey)(const Byte *data, UInt32 size); - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size); - - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); -}; - -struct CAesCbcEncoder: public CAesCbcCoder -{ - CAesCbcEncoder(unsigned keySize = 0): CAesCbcCoder(true, keySize) {} -}; - -struct CAesCbcDecoder: public CAesCbcCoder -{ - CAesCbcDecoder(unsigned keySize = 0): CAesCbcCoder(false, keySize) {} -}; - -} - -#endif +// Crypto/MyAes.h + +#ifndef ZIP7_INC_CRYPTO_MY_AES_H +#define ZIP7_INC_CRYPTO_MY_AES_H + +#include "../../../C/Aes.h" + +#include "../../Common/MyBuffer2.h" +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCrypto { + +#ifdef Z7_EXTRACT_ONLY +#define Z7_IFACEN_IAesCoderSetFunctions(x) +#else +#define Z7_IFACEN_IAesCoderSetFunctions(x) \ + virtual bool SetFunctions(UInt32 algo) x +#endif + + +class CAesCoder: + public ICompressFilter, + public ICryptoProperties, + #ifndef Z7_EXTRACT_ONLY + public ICompressSetCoderProperties, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(ICompressFilter) + Z7_COM_QI_ENTRY(ICryptoProperties) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(ICompressSetCoderProperties) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + +public: + Z7_IFACE_COM7_IMP_NONFINAL(ICompressFilter) + Z7_IFACE_COM7_IMP(ICryptoProperties) +private: + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ICompressSetCoderProperties) + #endif + +protected: + bool _keyIsSet; + // bool _encodeMode; + // bool _ctrMode; + // unsigned _offset; + unsigned _keySize; + unsigned _ctrPos; // we need _ctrPos here for Init() / SetInitVector() + AES_CODE_FUNC _codeFunc; + AES_SET_KEY_FUNC _setKeyFunc; +private: + // UInt32 _aes[AES_NUM_IVMRK_WORDS + 3]; + CAlignedBuffer1 _aes; + + Byte _iv[AES_BLOCK_SIZE]; + + // UInt32 *Aes() { return _aes + _offset; } +protected: + UInt32 *Aes() { return (UInt32 *)(void *)(Byte *)_aes; } + + Z7_IFACE_PURE(IAesCoderSetFunctions) + +public: + CAesCoder( + // bool encodeMode, + unsigned keySize + // , bool ctrMode + ); + virtual ~CAesCoder() {} // we need virtual destructor for derived classes + void SetKeySize(unsigned size) { _keySize = size; } +}; + + +#ifndef Z7_EXTRACT_ONLY +struct CAesCbcEncoder: public CAesCoder +{ + CAesCbcEncoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCbc_Encode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) +}; +#endif + +struct CAesCbcDecoder: public CAesCoder +{ + CAesCbcDecoder(unsigned keySize = 0): CAesCoder(keySize) + { + _setKeyFunc = Aes_SetKey_Dec; + _codeFunc = g_AesCbc_Decode; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) +}; + +#ifndef Z7_SFX +struct CAesCtrCoder: public CAesCoder +{ +private: + // unsigned _ctrPos; + // Z7_IFACE_COM7_IMP(ICompressFilter) + // Z7_COM7F_IMP(Init()) + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + CAesCtrCoder(unsigned keySize = 0): CAesCoder(keySize) + { + _ctrPos = 0; + _setKeyFunc = Aes_SetKey_Enc; + _codeFunc = g_AesCtr_Code; + } + Z7_IFACE_IMP(IAesCoderSetFunctions) +}; +#endif + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/MyAesReg.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAesReg.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/MyAesReg.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/MyAesReg.cpp 2023-04-02 10:00:00.000000000 +0000 @@ -1,16 +1,29 @@ -// MyAesReg.cpp - -#include "StdAfx.h" - -#include "../Common/RegisterCodec.h" - -#include "MyAes.h" - -namespace NCrypto { - -REGISTER_FILTER_E(AES256CBC, - CAesCbcDecoder(32), - CAesCbcEncoder(32), - 0x6F00181, "AES256CBC") - -} +// MyAesReg.cpp + +#include "StdAfx.h" + +#include "../Common/RegisterCodec.h" + +#include "MyAes.h" + +namespace NCrypto { + +#ifndef Z7_SFX + +#define REGISTER_AES_2(name, nameString, keySize) \ + REGISTER_FILTER_E(name, \ + CAesCbcDecoder(keySize), \ + CAesCbcEncoder(keySize), \ + 0x6F00100 | ((keySize - 16) * 8) | (/* isCtr */ 0 ? 4 : 1), \ + nameString) \ + +#define REGISTER_AES(name, nameString) \ + /* REGISTER_AES_2(AES128 ## name, "AES128" nameString, 16) */ \ + /* REGISTER_AES_2(AES192 ## name, "AES192" nameString, 24) */ \ + REGISTER_AES_2(AES256 ## name, "AES256" nameString, 32) \ + +REGISTER_AES(CBC, "CBC") + +#endif + +} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp 2023-03-22 19:00:00.000000000 +0000 @@ -1,97 +1,48 @@ -// Pbkdf2HmacSha1.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "HmacSha1.h" - -namespace NCrypto { -namespace NSha1 { - -void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, - const Byte *salt, size_t saltSize, - UInt32 numIterations, - Byte *key, size_t keySize) -{ - CHmac baseCtx; - baseCtx.SetKey(pwd, pwdSize); - - for (UInt32 i = 1; keySize != 0; i++) - { - CHmac ctx = baseCtx; - ctx.Update(salt, saltSize); - - Byte u[kDigestSize]; - SetBe32(u, i); - - ctx.Update(u, 4); - ctx.Final(u, kDigestSize); - - const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize; - unsigned s; - for (s = 0; s < curSize; s++) - key[s] = u[s]; - - for (UInt32 j = numIterations; j > 1; j--) - { - ctx = baseCtx; - ctx.Update(u, kDigestSize); - ctx.Final(u, kDigestSize); - for (s = 0; s < curSize; s++) - key[s] ^= u[s]; - } - - key += curSize; - keySize -= curSize; - } -} - -void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, - const UInt32 *salt, size_t saltSize, - UInt32 numIterations, - UInt32 *key, size_t keySize) -{ - CHmac32 baseCtx; - baseCtx.SetKey(pwd, pwdSize); - - for (UInt32 i = 1; keySize != 0; i++) - { - CHmac32 ctx = baseCtx; - ctx.Update(salt, saltSize); - - UInt32 u[kNumDigestWords]; - u[0] = i; - - ctx.Update(u, 1); - ctx.Final(u, kNumDigestWords); - - // Speed-optimized code start - ctx = baseCtx; - ctx.GetLoopXorDigest(u, numIterations - 1); - // Speed-optimized code end - - const unsigned curSize = (keySize < kNumDigestWords) ? (unsigned)keySize : kNumDigestWords; - unsigned s; - for (s = 0; s < curSize; s++) - key[s] = u[s]; - - /* - // Default code start - for (UInt32 j = numIterations; j > 1; j--) - { - ctx = baseCtx; - ctx.Update(u, kNumDigestWords); - ctx.Final(u, kNumDigestWords); - for (s = 0; s < curSize; s++) - key[s] ^= u[s]; - } - // Default code end - */ - - key += curSize; - keySize -= curSize; - } -} - -}} +// Pbkdf2HmacSha1.cpp + +#include "StdAfx.h" + +#include + +#include "../../../C/CpuArch.h" + +#include "HmacSha1.h" +#include "Pbkdf2HmacSha1.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, + const Byte *salt, size_t saltSize, + UInt32 numIterations, + Byte *key, size_t keySize) +{ + MY_ALIGN (16) + CHmac baseCtx; + baseCtx.SetKey(pwd, pwdSize); + + for (UInt32 i = 1; keySize != 0; i++) + { + MY_ALIGN (16) + CHmac ctx; + ctx = baseCtx; + ctx.Update(salt, saltSize); + + MY_ALIGN (16) + UInt32 u[kNumDigestWords]; + SetBe32(u, i) + + ctx.Update((const Byte *)u, 4); + ctx.Final((Byte *)u); + + ctx = baseCtx; + ctx.GetLoopXorDigest1((void *)u, numIterations - 1); + + const unsigned curSize = (keySize < kDigestSize) ? (unsigned)keySize : kDigestSize; + memcpy(key, (const Byte *)u, curSize); + key += curSize; + keySize -= curSize; + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Pbkdf2HmacSha1.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.h --- p7zip-rar-16.02/CPP/7zip/Crypto/Pbkdf2HmacSha1.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Pbkdf2HmacSha1.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,22 +1,19 @@ -// Pbkdf2HmacSha1.h -// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1 - -#ifndef __CRYPTO_PBKDF2_HMAC_SHA1_H -#define __CRYPTO_PBKDF2_HMAC_SHA1_H - -#include - -#include "../../Common/MyTypes.h" - -namespace NCrypto { -namespace NSha1 { - -void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, - UInt32 numIterations, Byte *key, size_t keySize); - -void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, - UInt32 numIterations, UInt32 *key, size_t keySize); - -}} - -#endif +// Pbkdf2HmacSha1.h +// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1 + +#ifndef ZIP7_INC_CRYPTO_PBKDF2_HMAC_SHA1_H +#define ZIP7_INC_CRYPTO_PBKDF2_HMAC_SHA1_H + +#include + +#include "../../Common/MyTypes.h" + +namespace NCrypto { +namespace NSha1 { + +void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, + UInt32 numIterations, Byte *key, size_t keySize); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/RandGen.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/RandGen.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.cpp 2023-03-24 20:10:00.000000000 +0000 @@ -1,122 +1,241 @@ -// RandGen.cpp - -#include "StdAfx.h" - -#ifndef _7ZIP_ST -#include "../../Windows/Synchronization.h" -#endif - -#include "RandGen.h" - -#ifndef _WIN32 -#include -#define USE_POSIX_TIME -#define USE_POSIX_TIME2 -#endif - -#ifdef USE_POSIX_TIME -#include -#ifdef USE_POSIX_TIME2 -#include -#endif -#endif - -// This is not very good random number generator. -// Please use it only for salt. -// First generated data block depends from timer and processID. -// Other generated data blocks depend from previous state -// Maybe it's possible to restore original timer value from generated value. - -#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x)); - -void CRandomGenerator::Init() -{ - CSha256 hash; - Sha256_Init(&hash); - - #ifdef _WIN32 - DWORD w = ::GetCurrentProcessId(); - HASH_UPD(w); - w = ::GetCurrentThreadId(); - HASH_UPD(w); - #else - pid_t pid = getpid(); - HASH_UPD(pid); - pid = getppid(); - HASH_UPD(pid); - #endif - - for (unsigned i = 0; i < - #ifdef _DEBUG - 2; - #else - 1000; - #endif - i++) - { - #ifdef _WIN32 - LARGE_INTEGER v; - if (::QueryPerformanceCounter(&v)) - HASH_UPD(v.QuadPart); - #endif - - #ifdef USE_POSIX_TIME - #ifdef USE_POSIX_TIME2 - timeval v; - if (gettimeofday(&v, 0) == 0) - { - HASH_UPD(v.tv_sec); - HASH_UPD(v.tv_usec); - } - #endif - time_t v2 = time(NULL); - HASH_UPD(v2); - #endif - - DWORD tickCount = ::GetTickCount(); - HASH_UPD(tickCount); - - for (unsigned j = 0; j < 100; j++) - { - Sha256_Final(&hash, _buff); - Sha256_Init(&hash); - Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); - } - } - Sha256_Final(&hash, _buff); - _needInit = false; -} - -#ifndef _7ZIP_ST - static NWindows::NSynchronization::CCriticalSection g_CriticalSection; - #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); -#else - #define MT_LOCK -#endif - -void CRandomGenerator::Generate(Byte *data, unsigned size) -{ - MT_LOCK - - if (_needInit) - Init(); - while (size != 0) - { - CSha256 hash; - - Sha256_Init(&hash); - Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); - Sha256_Final(&hash, _buff); - - Sha256_Init(&hash); - UInt32 salt = 0xF672ABD1; - HASH_UPD(salt); - Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); - Byte buff[SHA256_DIGEST_SIZE]; - Sha256_Final(&hash, buff); - for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--) - *data++ = buff[i]; - } -} - -CRandomGenerator g_RandomGenerator; +// RandGen.cpp + +#include "StdAfx.h" + +#include "RandGen.h" + +#ifndef USE_STATIC_SYSTEM_RAND + +#ifndef Z7_ST +#include "../../Windows/Synchronization.h" +#endif + + +#ifdef _WIN32 + +#ifdef _WIN64 +#define USE_STATIC_RtlGenRandom +#endif + +#ifdef USE_STATIC_RtlGenRandom + +// #include + +EXTERN_C_BEGIN +#ifndef RtlGenRandom + #define RtlGenRandom SystemFunction036 + BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +#endif +EXTERN_C_END + +#else +EXTERN_C_BEGIN +typedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength); +EXTERN_C_END +#endif + + +#else +#include +#include +#include +#include +#define USE_POSIX_TIME +#define USE_POSIX_TIME2 +#endif + +#ifdef USE_POSIX_TIME +#include +#ifdef USE_POSIX_TIME2 +#include +#endif +#endif + +// The seed and first generated data block depend from processID, +// theadID, timer and system random generator, if available. +// Other generated data blocks depend from previous state + +#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x)); + +void CRandomGenerator::Init() +{ + MY_ALIGN (16) + CSha256 hash; + Sha256_Init(&hash); + + unsigned numIterations = 1000; + + { + #ifndef UNDER_CE + const unsigned kNumIterations_Small = 100; + const unsigned kBufSize = 32; + MY_ALIGN (16) + Byte buf[kBufSize]; + #endif + + #ifdef _WIN32 + + DWORD w = ::GetCurrentProcessId(); + HASH_UPD(w) + w = ::GetCurrentThreadId(); + HASH_UPD(w) + + #ifdef UNDER_CE + /* + if (CeGenRandom(kBufSize, buf)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + */ + #elif defined(USE_STATIC_RtlGenRandom) + if (RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + #else + { + const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); + if (hModule) + { + // SystemFunction036() is real name of RtlGenRandom() function + const + Func_RtlGenRandom + my_RtlGenRandom = Z7_GET_PROC_ADDRESS( + Func_RtlGenRandom, hModule, "SystemFunction036"); + if (my_RtlGenRandom) + { + if (my_RtlGenRandom(buf, kBufSize)) + { + numIterations = kNumIterations_Small; + Sha256_Update(&hash, buf, kBufSize); + } + } + ::FreeLibrary(hModule); + } + } + #endif + + #else + + pid_t pid = getpid(); + HASH_UPD(pid) + pid = getppid(); + HASH_UPD(pid) + + { + int f = open("/dev/urandom", O_RDONLY); + unsigned numBytes = kBufSize; + if (f >= 0) + { + do + { + ssize_t n = read(f, buf, numBytes); + if (n <= 0) + break; + Sha256_Update(&hash, buf, (size_t)n); + numBytes -= (unsigned)n; + } + while (numBytes); + close(f); + if (numBytes == 0) + numIterations = kNumIterations_Small; + } + } + /* + { + int n = getrandom(buf, kBufSize, 0); + if (n > 0) + { + Sha256_Update(&hash, buf, n); + if (n == kBufSize) + numIterations = kNumIterations_Small; + } + } + */ + + #endif + } + + #ifdef _DEBUG + numIterations = 2; + #endif + + do + { + #ifdef _WIN32 + LARGE_INTEGER v; + if (::QueryPerformanceCounter(&v)) + HASH_UPD(v.QuadPart) + #endif + + #ifdef USE_POSIX_TIME + #ifdef USE_POSIX_TIME2 + timeval v; + if (gettimeofday(&v, NULL) == 0) + { + HASH_UPD(v.tv_sec) + HASH_UPD(v.tv_usec) + } + #endif + const time_t v2 = time(NULL); + HASH_UPD(v2) + #endif + + #ifdef _WIN32 + const DWORD tickCount = ::GetTickCount(); + HASH_UPD(tickCount) + #endif + + for (unsigned j = 0; j < 100; j++) + { + Sha256_Final(&hash, _buff); + Sha256_Init(&hash); + Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); + } + } + while (--numIterations); + + Sha256_Final(&hash, _buff); + _needInit = false; +} + +#ifndef Z7_ST + static NWindows::NSynchronization::CCriticalSection g_CriticalSection; + #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else + #define MT_LOCK +#endif + +void CRandomGenerator::Generate(Byte *data, unsigned size) +{ + MT_LOCK + + if (_needInit) + Init(); + while (size != 0) + { + MY_ALIGN (16) + CSha256 hash; + + Sha256_Init(&hash); + Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); + Sha256_Final(&hash, _buff); + + Sha256_Init(&hash); + UInt32 salt = 0xF672ABD1; + HASH_UPD(salt) + Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); + MY_ALIGN (16) + Byte buff[SHA256_DIGEST_SIZE]; + Sha256_Final(&hash, buff); + for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--) + *data++ = buff[i]; + } +} + +MY_ALIGN (16) +CRandomGenerator g_RandomGenerator; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/RandGen.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.h --- p7zip-rar-16.02/CPP/7zip/Crypto/RandGen.h 2011-05-08 18:29:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RandGen.h 2023-04-11 18:00:00.000000000 +0000 @@ -1,21 +1,41 @@ -// RandGen.h - -#ifndef __CRYPTO_RAND_GEN_H -#define __CRYPTO_RAND_GEN_H - -#include "../../../C/Sha256.h" - -class CRandomGenerator -{ - Byte _buff[SHA256_DIGEST_SIZE]; - bool _needInit; - - void Init(); -public: - CRandomGenerator(): _needInit(true) {}; - void Generate(Byte *data, unsigned size); -}; - -extern CRandomGenerator g_RandomGenerator; - -#endif +// RandGen.h + +#ifndef ZIP7_INC_CRYPTO_RAND_GEN_H +#define ZIP7_INC_CRYPTO_RAND_GEN_H + +#include "../../../C/Sha256.h" + +#ifdef _WIN64 +// #define USE_STATIC_SYSTEM_RAND +#endif + +#ifdef USE_STATIC_SYSTEM_RAND + +#ifdef _WIN32 +#include +#define MY_RAND_GEN(data, size) RtlGenRandom(data, size) +#else +#define MY_RAND_GEN(data, size) getrandom(data, size, 0) +#endif + +#else + +class CRandomGenerator +{ + Byte _buff[SHA256_DIGEST_SIZE]; + bool _needInit; + + void Init(); +public: + CRandomGenerator(): _needInit(true) {} + void Generate(Byte *data, unsigned size); +}; + +MY_ALIGN (16) +extern CRandomGenerator g_RandomGenerator; + +#define MY_RAND_GEN(data, size) g_RandomGenerator.Generate(data, size) + +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Rar20Crypto.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/Rar20Crypto.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.cpp 2023-03-07 07:00:00.000000000 +0000 @@ -1,130 +1,130 @@ -// Crypto/Rar20Crypto.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/CpuArch.h" -#include "../../../C/RotateDefs.h" - -#include "Rar20Crypto.h" - -namespace NCrypto { -namespace NRar2 { - -static const unsigned kNumRounds = 32; - -static const Byte g_InitSubstTable[256] = { - 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, - 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, - 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, - 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, - 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, - 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, - 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, - 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, - 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, - 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, - 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, - 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, - 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, - 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, - 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, - 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 -}; - -void CData::UpdateKeys(const Byte *data) -{ - for (unsigned i = 0; i < 16; i += 4) - for (unsigned j = 0; j < 4; j++) - Keys[j] ^= g_CrcTable[data[i + j]]; -} - -static inline void Swap(Byte &b1, Byte &b2) -{ - Byte b = b1; - b1 = b2; - b2 = b; -} - -void CData::SetPassword(const Byte *data, unsigned size) -{ - Keys[0] = 0xD3A3B879L; - Keys[1] = 0x3F6D12F7L; - Keys[2] = 0x7515A235L; - Keys[3] = 0xA4E7F123L; - - Byte psw[128]; - memset(psw, 0, sizeof(psw)); - if (size != 0) - { - if (size >= sizeof(psw)) - size = sizeof(psw) - 1; - memcpy(psw, data, size); - } - - memcpy(SubstTable, g_InitSubstTable, sizeof(SubstTable)); - - for (unsigned j = 0; j < 256; j++) - for (unsigned i = 0; i < size; i += 2) - { - unsigned n1 = (Byte)g_CrcTable[(psw[i] - j) & 0xFF]; - unsigned n2 = (Byte)g_CrcTable[(psw[i + 1] + j) & 0xFF]; - for (unsigned k = 1; (n1 & 0xFF) != n2; n1++, k++) - Swap(SubstTable[n1 & 0xFF], SubstTable[(n1 + i + k) & 0xFF]); - } - - for (unsigned i = 0; i < size; i += 16) - EncryptBlock(psw + i); -} - -void CData::CryptBlock(Byte *buf, bool encrypt) -{ - Byte inBuf[16]; - UInt32 A, B, C, D; - - A = GetUi32(buf + 0) ^ Keys[0]; - B = GetUi32(buf + 4) ^ Keys[1]; - C = GetUi32(buf + 8) ^ Keys[2]; - D = GetUi32(buf + 12) ^ Keys[3]; - - if (!encrypt) - memcpy(inBuf, buf, sizeof(inBuf)); - - for (unsigned i = 0; i < kNumRounds; i++) - { - UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3]; - UInt32 TA = A ^ SubstLong((C + rotlFixed(D, 11)) ^ key); - UInt32 TB = B ^ SubstLong((D ^ rotlFixed(C, 17)) + key); - A = C; C = TA; - B = D; D = TB; - } - - SetUi32(buf + 0, C ^ Keys[0]); - SetUi32(buf + 4, D ^ Keys[1]); - SetUi32(buf + 8, A ^ Keys[2]); - SetUi32(buf + 12, B ^ Keys[3]); - - UpdateKeys(encrypt ? buf : inBuf); -} - -STDMETHODIMP CDecoder::Init() -{ - return S_OK; -} - -static const UInt32 kBlockSize = 16; - -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) -{ - if (size == 0) - return 0; - if (size < kBlockSize) - return kBlockSize; - size -= kBlockSize; - UInt32 i; - for (i = 0; i <= size; i += kBlockSize) - DecryptBlock(data + i); - return i; -} - -}} +// Crypto/Rar20Crypto.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" +#include "../../../C/RotateDefs.h" + +#include "Rar20Crypto.h" + +namespace NCrypto { +namespace NRar2 { + +static const unsigned kNumRounds = 32; + +static const Byte g_InitSubstTable[256] = { + 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, + 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, + 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, + 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, + 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, + 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, + 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, + 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, + 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, + 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, + 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, + 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, + 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, + 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, + 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, + 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 +}; + +void CData::UpdateKeys(const Byte *data) +{ + for (unsigned i = 0; i < 16; i += 4) + for (unsigned j = 0; j < 4; j++) + Keys[j] ^= g_CrcTable[data[i + j]]; +} + +static inline void Swap(Byte &b1, Byte &b2) +{ + Byte b = b1; + b1 = b2; + b2 = b; +} + +void CData::SetPassword(const Byte *data, unsigned size) +{ + Keys[0] = 0xD3A3B879L; + Keys[1] = 0x3F6D12F7L; + Keys[2] = 0x7515A235L; + Keys[3] = 0xA4E7F123L; + + Byte psw[128]; + Z7_memset_0_ARRAY(psw); + if (size != 0) + { + if (size >= sizeof(psw)) + size = sizeof(psw) - 1; + memcpy(psw, data, size); + } + + memcpy(SubstTable, g_InitSubstTable, sizeof(SubstTable)); + + for (unsigned j = 0; j < 256; j++) + for (unsigned i = 0; i < size; i += 2) + { + unsigned n1 = (Byte)g_CrcTable[(psw[i] - j) & 0xFF]; + unsigned n2 = (Byte)g_CrcTable[(psw[(size_t)i + 1] + j) & 0xFF]; + for (unsigned k = 1; (n1 & 0xFF) != n2; n1++, k++) + Swap(SubstTable[n1 & 0xFF], SubstTable[(n1 + i + k) & 0xFF]); + } + + for (unsigned i = 0; i < size; i += 16) + EncryptBlock(psw + i); +} + +void CData::CryptBlock(Byte *buf, bool encrypt) +{ + Byte inBuf[16]; + UInt32 A, B, C, D; + + A = GetUi32(buf + 0) ^ Keys[0]; + B = GetUi32(buf + 4) ^ Keys[1]; + C = GetUi32(buf + 8) ^ Keys[2]; + D = GetUi32(buf + 12) ^ Keys[3]; + + if (!encrypt) + memcpy(inBuf, buf, sizeof(inBuf)); + + for (unsigned i = 0; i < kNumRounds; i++) + { + UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3]; + UInt32 TA = A ^ SubstLong((C + rotlFixed(D, 11)) ^ key); + UInt32 TB = B ^ SubstLong((D ^ rotlFixed(C, 17)) + key); + A = C; C = TA; + B = D; D = TB; + } + + SetUi32(buf + 0, C ^ Keys[0]) + SetUi32(buf + 4, D ^ Keys[1]) + SetUi32(buf + 8, A ^ Keys[2]) + SetUi32(buf + 12, B ^ Keys[3]) + + UpdateKeys(encrypt ? buf : inBuf); +} + +Z7_COM7F_IMF(CDecoder::Init()) +{ + return S_OK; +} + +static const UInt32 kBlockSize = 16; + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + if (size == 0) + return 0; + if (size < kBlockSize) + return kBlockSize; + size -= kBlockSize; + UInt32 i; + for (i = 0; i <= size; i += kBlockSize) + DecryptBlock(data + i); + return i; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Rar20Crypto.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.h --- p7zip-rar-16.02/CPP/7zip/Crypto/Rar20Crypto.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar20Crypto.h 2023-03-07 07:00:00.000000000 +0000 @@ -1,48 +1,54 @@ -// Crypto/Rar20Crypto.h - -#ifndef __CRYPTO_RAR20_CRYPTO_H -#define __CRYPTO_RAR20_CRYPTO_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" - -namespace NCrypto { -namespace NRar2 { - -/* ICompressFilter::Init() does nothing for this filter. - Call SetPassword() to initialize filter. */ - -class CData -{ - Byte SubstTable[256]; - UInt32 Keys[4]; - - UInt32 SubstLong(UInt32 t) const - { - return (UInt32)SubstTable[(unsigned)t & 255] - | ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8) - | ((UInt32)SubstTable[(unsigned)(t >> 16) & 255] << 16) - | ((UInt32)SubstTable[(unsigned)(t >> 24) & 255] << 24); - } - void UpdateKeys(const Byte *data); - void CryptBlock(Byte *buf, bool encrypt); -public: - void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } - void DecryptBlock(Byte *buf) { CryptBlock(buf, false); } - void SetPassword(const Byte *password, unsigned passwordLen); -}; - -class CDecoder: - public ICompressFilter, - public CMyUnknownImp, - public CData -{ -public: - MY_UNKNOWN_IMP - INTERFACE_ICompressFilter(;) -}; - -}} - -#endif +// Crypto/Rar20Crypto.h + +#ifndef ZIP7_INC_CRYPTO_RAR20_CRYPTO_H +#define ZIP7_INC_CRYPTO_RAR20_CRYPTO_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +namespace NCrypto { +namespace NRar2 { + +/* ICompressFilter::Init() does nothing for this filter. + Call SetPassword() to initialize filter. */ + +class CData +{ + Byte SubstTable[256]; + UInt32 Keys[4]; + + UInt32 SubstLong(UInt32 t) const + { + return (UInt32)SubstTable[(unsigned)t & 255] + | ((UInt32)SubstTable[(unsigned)(t >> 8) & 255] << 8) + | ((UInt32)SubstTable[(unsigned)(t >> 16) & 255] << 16) + | ((UInt32)SubstTable[(unsigned)(t >> 24) ] << 24); + } + void UpdateKeys(const Byte *data); + void CryptBlock(Byte *buf, bool encrypt); +public: + ~CData() { Wipe(); } + void Wipe() + { + Z7_memset_0_ARRAY(SubstTable); + Z7_memset_0_ARRAY(Keys); + } + + void EncryptBlock(Byte *buf) { CryptBlock(buf, true); } + void DecryptBlock(Byte *buf) { CryptBlock(buf, false); } + void SetPassword(const Byte *password, unsigned passwordLen); +}; + +class CDecoder Z7_final: + public ICompressFilter, + public CMyUnknownImp, + public CData +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ICompressFilter) +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Rar5Aes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/Rar5Aes.cpp 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.cpp 2024-11-19 09:00:00.000000000 +0000 @@ -1,257 +1,272 @@ -// Crypto/Rar5Aes.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#ifndef _7ZIP_ST -#include "../../Windows/Synchronization.h" -#endif - -#include "Rar5Aes.h" - -namespace NCrypto { -namespace NRar5 { - -static const unsigned kNumIterationsLog_Max = 24; - -static const unsigned kPswCheckCsumSize = 4; -static const unsigned kCheckSize = kPswCheckSize + kPswCheckCsumSize; - -CKey::CKey(): - _needCalc(true), - _numIterationsLog(0) -{ - for (unsigned i = 0; i < sizeof(_salt); i++) - _salt[i] = 0; -} - -CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} - -static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) -{ - unsigned i; - *val = 0; - - for (i = 0; i < maxSize;) - { - Byte b = p[i]; - if (i < 10) - *val |= (UInt64)(b & 0x7F) << (7 * i++); - if ((b & 0x80) == 0) - return i; - } - return 0; -} - -HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV, bool isService) -{ - UInt64 Version; - - unsigned num = ReadVarInt(p, size, &Version); - if (num == 0) - return E_NOTIMPL; - p += num; - size -= num; - - if (Version != 0) - return E_NOTIMPL; - - num = ReadVarInt(p, size, &Flags); - if (num == 0) - return E_NOTIMPL; - p += num; - size -= num; - - bool isCheck = IsThereCheck(); - if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize : 0)) - return E_NOTIMPL; - - if (_numIterationsLog != p[0]) - { - _numIterationsLog = p[0]; - _needCalc = true; - } - - p++; - - if (memcmp(_salt, p, kSaltSize) != 0) - { - memcpy(_salt, p, kSaltSize); - _needCalc = true; - } - - p += kSaltSize; - - if (includeIV) - { - memcpy(_iv, p, AES_BLOCK_SIZE); - p += AES_BLOCK_SIZE; - } - - _canCheck = true; - - if (isCheck) - { - memcpy(_check, p, kPswCheckSize); - CSha256 sha; - Byte digest[SHA256_DIGEST_SIZE]; - Sha256_Init(&sha); - Sha256_Update(&sha, _check, kPswCheckSize); - Sha256_Final(&sha, digest); - _canCheck = (memcmp(digest, p + kPswCheckSize, kPswCheckCsumSize) == 0); - if (_canCheck && isService) - { - // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros. - // so we disable password checking for such bad records. - _canCheck = false; - for (unsigned i = 0; i < kPswCheckSize; i++) - if (p[i] != 0) - { - _canCheck = true; - break; - } - } - } - - return (_numIterationsLog <= kNumIterationsLog_Max ? S_OK : E_NOTIMPL); -} - - -void CDecoder::SetPassword(const Byte *data, size_t size) -{ - if (size != _password.Size() || memcmp(data, _password, size) != 0) - { - _needCalc = true; - _password.CopyFrom(data, size); - } -} - - -STDMETHODIMP CDecoder::Init() -{ - CalcKey_and_CheckPassword(); - RINOK(SetKey(_key, kAesKeySize)); - RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)); - return CAesCbcCoder::Init(); -} - - -UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const -{ - NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); - Byte v[4]; - SetUi32(v, crc); - ctx.Update(v, 4); - Byte h[NSha256::kDigestSize]; - ctx.Final(h); - crc = 0; - for (unsigned i = 0; i < NSha256::kDigestSize; i++) - crc ^= (UInt32)h[i] << ((i & 3) * 8); - return crc; -}; - - -void CDecoder::Hmac_Convert_32Bytes(Byte *data) const -{ - NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); - ctx.Update(data, NSha256::kDigestSize); - ctx.Final(data); -}; - - -#ifndef _7ZIP_ST - static CKey g_Key; - static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; - #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); -#else - #define MT_LOCK -#endif - -bool CDecoder::CalcKey_and_CheckPassword() -{ - if (_needCalc) - { - { - MT_LOCK - if (!g_Key._needCalc && IsKeyEqualTo(g_Key)) - { - CopyCalcedKeysFrom(g_Key); - _needCalc = false; - } - } - - if (_needCalc) - { - Byte pswCheck[SHA256_DIGEST_SIZE]; - - { - // Pbkdf HMAC-SHA-256 - - NSha256::CHmac baseCtx; - baseCtx.SetKey(_password, _password.Size()); - - NSha256::CHmac ctx = baseCtx; - ctx.Update(_salt, sizeof(_salt)); - - Byte u[NSha256::kDigestSize]; - Byte key[NSha256::kDigestSize]; - - u[0] = 0; - u[1] = 0; - u[2] = 0; - u[3] = 1; - - ctx.Update(u, 4); - ctx.Final(u); - - memcpy(key, u, NSha256::kDigestSize); - - UInt32 numIterations = ((UInt32)1 << _numIterationsLog) - 1; - - for (unsigned i = 0; i < 3; i++) - { - UInt32 j = numIterations; - - for (; j != 0; j--) - { - ctx = baseCtx; - ctx.Update(u, NSha256::kDigestSize); - ctx.Final(u); - for (unsigned s = 0; s < NSha256::kDigestSize; s++) - key[s] ^= u[s]; - } - - // RAR uses additional iterations for additional keys - memcpy((i == 0 ? _key : (i == 1 ? _hashKey : pswCheck)), key, NSha256::kDigestSize); - numIterations = 16; - } - } - - { - unsigned i; - - for (i = 0; i < kPswCheckSize; i++) - _check_Calced[i] = pswCheck[i]; - - for (i = kPswCheckSize; i < SHA256_DIGEST_SIZE; i++) - _check_Calced[i & (kPswCheckSize - 1)] ^= pswCheck[i]; - } - - _needCalc = false; - - { - MT_LOCK - g_Key = *this; - } - } - } - - if (IsThereCheck() && _canCheck) - return (memcmp(_check_Calced, _check, kPswCheckSize) == 0); - return true; -} - -}} +// Crypto/Rar5Aes.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#ifndef Z7_ST +#include "../../Windows/Synchronization.h" +#endif + +#include "HmacSha256.h" +#include "Rar5Aes.h" + +#define MY_ALIGN_FOR_SHA256 MY_ALIGN(16) + +namespace NCrypto { +namespace NRar5 { + +static const unsigned kNumIterationsLog_Max = 24; +static const unsigned kPswCheckCsumSize32 = 1; +static const unsigned kCheckSize32 = kPswCheckSize32 + kPswCheckCsumSize32; + +CKey::CKey(): + _needCalc(true), + _numIterationsLog(0) +{ + for (unsigned i = 0; i < sizeof(_salt); i++) + _salt[i] = 0; +} + +CKey::~CKey() +{ + Wipe(); +} + +void CKey::Wipe() +{ + _password.Wipe(); + Z7_memset_0_ARRAY(_salt); + // Z7_memset_0_ARRAY(_key32); + // Z7_memset_0_ARRAY(_check_Calced32); + // Z7_memset_0_ARRAY(_hashKey32); + CKeyBase::Wipe(); +} + +CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} + +static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) +{ + *val = 0; + for (unsigned i = 0; i < maxSize && i < 10;) + { + const Byte b = p[i]; + *val |= (UInt64)(b & 0x7F) << (7 * i); + i++; + if ((b & 0x80) == 0) + return i; + } + return 0; +} + +HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV, bool isService) +{ + UInt64 Version; + + unsigned num = ReadVarInt(p, size, &Version); + if (num == 0) + return E_NOTIMPL; + p += num; + size -= num; + + if (Version != 0) + return E_NOTIMPL; + + num = ReadVarInt(p, size, &Flags); + if (num == 0) + return E_NOTIMPL; + p += num; + size -= num; + + bool isCheck = IsThereCheck(); + if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize32 * 4 : 0)) + return E_NOTIMPL; + + if (_numIterationsLog != p[0]) + { + _numIterationsLog = p[0]; + _needCalc = true; + } + + p++; + + if (memcmp(_salt, p, kSaltSize) != 0) + { + memcpy(_salt, p, kSaltSize); + _needCalc = true; + } + + p += kSaltSize; + + if (includeIV) + { + memcpy(_iv, p, AES_BLOCK_SIZE); + p += AES_BLOCK_SIZE; + } + + _canCheck = true; + + if (isCheck) + { + memcpy(_check32, p, sizeof(_check32)); + MY_ALIGN_FOR_SHA256 + CSha256 sha; + MY_ALIGN_FOR_SHA256 + Byte digest[SHA256_DIGEST_SIZE]; + Sha256_Init(&sha); + Sha256_Update(&sha, (const Byte *)_check32, sizeof(_check32)); + Sha256_Final(&sha, digest); + _canCheck = (memcmp(digest, p + sizeof(_check32), kPswCheckCsumSize32 * 4) == 0); + if (_canCheck && isService) + { + // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros. + // so we disable password checking for such bad records. + _canCheck = false; + for (unsigned i = 0; i < kPswCheckSize32 * 4; i++) + if (p[i] != 0) + { + _canCheck = true; + break; + } + } + } + + return (_numIterationsLog <= kNumIterationsLog_Max ? S_OK : E_NOTIMPL); +} + + +void CDecoder::SetPassword(const Byte *data, size_t size) +{ + if (size != _password.Size() || memcmp(data, _password, size) != 0) + { + _needCalc = true; + _password.Wipe(); + _password.CopyFrom(data, size); + } +} + + +Z7_COM7F_IMF(CDecoder::Init()) +{ + CalcKey_and_CheckPassword(); + RINOK(SetKey((const Byte *)_key32, kAesKeySize)) + RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) + return CAesCoder::Init(); +} + + +UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const +{ + MY_ALIGN_FOR_SHA256 + NSha256::CHmac ctx; + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); + UInt32 v; + SetUi32a(&v, crc) + ctx.Update((const Byte *)&v, 4); + MY_ALIGN_FOR_SHA256 + UInt32 h[SHA256_NUM_DIGEST_WORDS]; + ctx.Final((Byte *)h); + crc = 0; + for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++) + crc ^= (UInt32)GetUi32a(h + i); + return crc; +} + + +void CDecoder::Hmac_Convert_32Bytes(Byte *data) const +{ + MY_ALIGN_FOR_SHA256 + NSha256::CHmac ctx; + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); + ctx.Update(data, NSha256::kDigestSize); + ctx.Final(data); +} + + +static CKey g_Key; + +#ifndef Z7_ST + static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; + #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); +#else + #define MT_LOCK +#endif + +bool CDecoder::CalcKey_and_CheckPassword() +{ + if (_needCalc) + { + { + MT_LOCK + if (!g_Key._needCalc && IsKeyEqualTo(g_Key)) + { + CopyCalcedKeysFrom(g_Key); + _needCalc = false; + } + } + + if (_needCalc) + { + MY_ALIGN_FOR_SHA256 + UInt32 pswCheck[SHA256_NUM_DIGEST_WORDS]; + { + // Pbkdf HMAC-SHA-256 + MY_ALIGN_FOR_SHA256 + NSha256::CHmac baseCtx; + baseCtx.SetKey(_password, _password.Size()); + MY_ALIGN_FOR_SHA256 + NSha256::CHmac ctx; + ctx = baseCtx; + ctx.Update(_salt, sizeof(_salt)); + + MY_ALIGN_FOR_SHA256 + UInt32 u[SHA256_NUM_DIGEST_WORDS]; + MY_ALIGN_FOR_SHA256 + UInt32 key[SHA256_NUM_DIGEST_WORDS]; + + // u[0] = 0; + // u[1] = 0; + // u[2] = 0; + // u[3] = 1; + SetUi32a(u, 0x1000000) + + ctx.Update((const Byte *)(const void *)u, 4); + ctx.Final((Byte *)(void *)u); + + memcpy(key, u, NSha256::kDigestSize); + + UInt32 numIterations = ((UInt32)1 << _numIterationsLog) - 1; + + for (unsigned i = 0; i < 3; i++) + { + for (; numIterations != 0; numIterations--) + { + ctx = baseCtx; + ctx.Update((const Byte *)(const void *)u, NSha256::kDigestSize); + ctx.Final((Byte *)(void *)u); + for (unsigned s = 0; s < Z7_ARRAY_SIZE(u); s++) + key[s] ^= u[s]; + } + + // RAR uses additional iterations for additional keys + memcpy(i == 0 ? _key32 : i == 1 ? _hashKey32 : pswCheck, + key, NSha256::kDigestSize); + numIterations = 16; + } + } + _check_Calced32[0] = pswCheck[0] ^ pswCheck[2] ^ pswCheck[4] ^ pswCheck[6]; + _check_Calced32[1] = pswCheck[1] ^ pswCheck[3] ^ pswCheck[5] ^ pswCheck[7]; + _needCalc = false; + { + MT_LOCK + g_Key = *this; + } + } + } + + if (IsThereCheck() && _canCheck) + return memcmp(_check_Calced32, _check32, sizeof(_check32)) == 0; + return true; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Rar5Aes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.h --- p7zip-rar-16.02/CPP/7zip/Crypto/Rar5Aes.h 2015-09-01 18:04:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Rar5Aes.h 2024-11-19 10:00:00.000000000 +0000 @@ -1,84 +1,97 @@ -// Crypto/Rar5Aes.h - -#ifndef __CRYPTO_RAR5_AES_H -#define __CRYPTO_RAR5_AES_H - -#include "../../../C/Aes.h" - -#include "../../Common/MyBuffer.h" - -#include "HmacSha256.h" -#include "MyAes.h" - -namespace NCrypto { -namespace NRar5 { - -const unsigned kSaltSize = 16; -const unsigned kPswCheckSize = 8; -const unsigned kAesKeySize = 32; - -namespace NCryptoFlags -{ - const unsigned kPswCheck = 1 << 0; - const unsigned kUseMAC = 1 << 1; -} - -struct CKey -{ - bool _needCalc; - - unsigned _numIterationsLog; - Byte _salt[kSaltSize]; - CByteBuffer _password; - - Byte _key[kAesKeySize]; - Byte _check_Calced[kPswCheckSize]; - Byte _hashKey[SHA256_DIGEST_SIZE]; - - void CopyCalcedKeysFrom(const CKey &k) - { - memcpy(_key, k._key, sizeof(_key)); - memcpy(_check_Calced, k._check_Calced, sizeof(_check_Calced)); - memcpy(_hashKey, k._hashKey, sizeof(_hashKey)); - } - - bool IsKeyEqualTo(const CKey &key) - { - return (_numIterationsLog == key._numIterationsLog - && memcmp(_salt, key._salt, sizeof(_salt)) == 0 - && _password == key._password); - } - - CKey(); -}; - - -class CDecoder: - public CAesCbcDecoder, - public CKey -{ - Byte _check[kPswCheckSize]; - bool _canCheck; - UInt64 Flags; - - bool IsThereCheck() const { return ((Flags & NCryptoFlags::kPswCheck) != 0); } -public: - Byte _iv[AES_BLOCK_SIZE]; - - CDecoder(); - - STDMETHOD(Init)(); - - void SetPassword(const Byte *data, size_t size); - HRESULT SetDecoderProps(const Byte *data, unsigned size, bool includeIV, bool isService); - - bool CalcKey_and_CheckPassword(); - - bool UseMAC() const { return (Flags & NCryptoFlags::kUseMAC) != 0; } - UInt32 Hmac_Convert_Crc32(UInt32 crc) const; - void Hmac_Convert_32Bytes(Byte *data) const; -}; - -}} - -#endif +// Crypto/Rar5Aes.h + +#ifndef ZIP7_INC_CRYPTO_RAR5_AES_H +#define ZIP7_INC_CRYPTO_RAR5_AES_H + +#include "../../../C/Sha256.h" + +#include "../../Common/MyBuffer.h" + +#include "MyAes.h" + +namespace NCrypto { +namespace NRar5 { + +const unsigned kSaltSize = 16; +const unsigned kPswCheckSize32 = 2; +const unsigned kAesKeySize = 32; + +namespace NCryptoFlags +{ + const unsigned kPswCheck = 1 << 0; + const unsigned kUseMAC = 1 << 1; +} + +struct CKeyBase +{ +protected: + UInt32 _key32[kAesKeySize / 4]; + UInt32 _hashKey32[SHA256_NUM_DIGEST_WORDS]; + UInt32 _check_Calced32[kPswCheckSize32]; + + void Wipe() + { + memset(this, 0, sizeof(*this)); + } + + void CopyCalcedKeysFrom(const CKeyBase &k) + { + *this = k; + } +}; + +struct CKey: public CKeyBase +{ + CByteBuffer _password; + bool _needCalc; + unsigned _numIterationsLog; + Byte _salt[kSaltSize]; + + bool IsKeyEqualTo(const CKey &key) + { + return _numIterationsLog == key._numIterationsLog + && memcmp(_salt, key._salt, sizeof(_salt)) == 0 + && _password == key._password; + } + + CKey(); + ~CKey(); + + void Wipe(); + +#ifdef Z7_CPP_IS_SUPPORTED_default + // CKey(const CKey &) = default; + CKey& operator =(const CKey &) = default; +#endif +}; + + +class CDecoder Z7_final: + public CAesCbcDecoder, + public CKey +{ + UInt32 _check32[kPswCheckSize32]; + bool _canCheck; + UInt64 Flags; + + bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; } +public: + Byte _iv[AES_BLOCK_SIZE]; + + CDecoder(); + + Z7_COM7F_IMP(Init()) + + void SetPassword(const Byte *data, size_t size); + HRESULT SetDecoderProps(const Byte *data, unsigned size, bool includeIV, bool isService); + + bool CalcKey_and_CheckPassword(); + + bool UseMAC() const { return (Flags & NCryptoFlags::kUseMAC) != 0; } + UInt32 Hmac_Convert_Crc32(UInt32 crc) const; + void Hmac_Convert_32Bytes(Byte *data) const; +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/RarAes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/RarAes.cpp 2016-06-11 08:08:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.cpp 2024-11-18 18:00:00.000000000 +0000 @@ -1,133 +1,202 @@ -// Crypto/RarAes.cpp - -#include "StdAfx.h" - -#include "RarAes.h" -#include "Sha1Cls.h" - -namespace NCrypto { -namespace NRar3 { - -CDecoder::CDecoder(): - CAesCbcDecoder(kAesKeySize), - _thereIsSalt(false), - _needCalc(true) - // _rar350Mode(false) -{ - for (unsigned i = 0; i < sizeof(_salt); i++) - _salt[i] = 0; -} - -HRESULT CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - bool prev = _thereIsSalt; - _thereIsSalt = false; - if (size == 0) - { - if (!_needCalc && prev) - _needCalc = true; - return S_OK; - } - if (size < 8) - return E_INVALIDARG; - _thereIsSalt = true; - bool same = false; - if (_thereIsSalt == prev) - { - same = true; - if (_thereIsSalt) - { - for (unsigned i = 0; i < sizeof(_salt); i++) - if (_salt[i] != data[i]) - { - same = false; - break; - } - } - } - for (unsigned i = 0; i < sizeof(_salt); i++) - _salt[i] = data[i]; - if (!_needCalc && !same) - _needCalc = true; - return S_OK; -} - -static const unsigned kPasswordLen_Bytes_MAX = 127 * 2; - -void CDecoder::SetPassword(const Byte *data, unsigned size) -{ - if (size > kPasswordLen_Bytes_MAX) - size = kPasswordLen_Bytes_MAX; - bool same = false; - if (size == _password.Size()) - { - same = true; - for (UInt32 i = 0; i < size; i++) - if (data[i] != _password[i]) - { - same = false; - break; - } - } - if (!_needCalc && !same) - _needCalc = true; - _password.CopyFrom(data, (size_t)size); -} - -STDMETHODIMP CDecoder::Init() -{ - CalcKey(); - RINOK(SetKey(_key, kAesKeySize)); - RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)); - return CAesCbcCoder::Init(); -} - -void CDecoder::CalcKey() -{ - if (!_needCalc) - return; - - const unsigned kSaltSize = 8; - - Byte buf[kPasswordLen_Bytes_MAX + kSaltSize]; - - if (_password.Size() != 0) - memcpy(buf, _password, _password.Size()); - - size_t rawSize = _password.Size(); - - if (_thereIsSalt) - { - memcpy(buf + rawSize, _salt, kSaltSize); - rawSize += kSaltSize; - } - - NSha1::CContext sha; - sha.Init(); - - Byte digest[NSha1::kDigestSize]; - // rar reverts hash for sha. - const UInt32 kNumRounds = ((UInt32)1 << 18); - UInt32 i; - for (i = 0; i < kNumRounds; i++) - { - sha.UpdateRar(buf, rawSize /* , _rar350Mode */); - Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; - sha.UpdateRar(pswNum, 3 /* , _rar350Mode */); - if (i % (kNumRounds / 16) == 0) - { - NSha1::CContext shaTemp = sha; - shaTemp.Final(digest); - _iv[i / (kNumRounds / 16)] = (Byte)digest[4 * 4 + 3]; - } - } - - sha.Final(digest); - for (i = 0; i < 4; i++) - for (unsigned j = 0; j < 4; j++) - _key[i * 4 + j] = (digest[i * 4 + 3 - j]); - - _needCalc = false; -} - -}} +// Crypto/RarAes.cpp + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" +#include "../../../C/RotateDefs.h" + +#include "RarAes.h" +#include "Sha1Cls.h" + +namespace NCrypto { +namespace NRar3 { + +CDecoder::CDecoder(): + CAesCbcDecoder(kAesKeySize), + _thereIsSalt(false), + _needCalc(true) + // _rar350Mode(false) +{ + for (unsigned i = 0; i < sizeof(_salt); i++) + _salt[i] = 0; +} + +HRESULT CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + bool prev = _thereIsSalt; + _thereIsSalt = false; + if (size == 0) + { + if (!_needCalc && prev) + _needCalc = true; + return S_OK; + } + if (size < 8) + return E_INVALIDARG; + _thereIsSalt = true; + bool same = false; + if (_thereIsSalt == prev) + { + same = true; + if (_thereIsSalt) + { + for (unsigned i = 0; i < sizeof(_salt); i++) + if (_salt[i] != data[i]) + { + same = false; + break; + } + } + } + for (unsigned i = 0; i < sizeof(_salt); i++) + _salt[i] = data[i]; + if (!_needCalc && !same) + _needCalc = true; + return S_OK; +} + +static const unsigned kPasswordLen_Bytes_MAX = 127 * 2; + +void CDecoder::SetPassword(const Byte *data, unsigned size) +{ + if (size > kPasswordLen_Bytes_MAX) + size = kPasswordLen_Bytes_MAX; + bool same = false; + if (size == _password.Size()) + { + same = true; + for (UInt32 i = 0; i < size; i++) + if (data[i] != _password[i]) + { + same = false; + break; + } + } + if (!_needCalc && !same) + _needCalc = true; + _password.Wipe(); + _password.CopyFrom(data, (size_t)size); +} + +Z7_COM7F_IMF(CDecoder::Init()) +{ + CalcKey(); + RINOK(SetKey(_key, kAesKeySize)) + RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) + return CAesCoder::Init(); +} + + +// if (password_size_in_bytes + SaltSize > 64), +// the original rar code updates password_with_salt buffer +// with some generated data from SHA1 code. + +// #define RAR_SHA1_REDUCE + +#ifdef RAR_SHA1_REDUCE + #define kNumW 16 + #define WW(i) W[(i)&15] +#else + #define kNumW 80 + #define WW(i) W[i] +#endif + +static void UpdatePswDataSha1(Byte *data) +{ + UInt32 W[kNumW]; + size_t i; + + for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) + W[i] = GetBe32(data + i * 4); + + for (i = 16; i < 80; i++) + { + const UInt32 t = WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16); + WW(i) = rotlFixed(t, 1); + } + + for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) + { + SetUi32(data + i * 4, W[kNumW - SHA1_NUM_BLOCK_WORDS + i]) + } +} + + +void CDecoder::CalcKey() +{ + if (!_needCalc) + return; + + const unsigned kSaltSize = 8; + + MY_ALIGN (16) + Byte buf[kPasswordLen_Bytes_MAX + kSaltSize]; + + if (_password.Size() != 0) + memcpy(buf, _password, _password.Size()); + + size_t rawSize = _password.Size(); + + if (_thereIsSalt) + { + memcpy(buf + rawSize, _salt, kSaltSize); + rawSize += kSaltSize; + } + + MY_ALIGN (16) + NSha1::CContext sha; + sha.Init(); + + MY_ALIGN (16) + Byte digest[NSha1::kDigestSize]; + // rar reverts hash for sha. + const UInt32 kNumRounds = (UInt32)1 << 18; + UInt32 pos = 0; + UInt32 i; + for (i = 0; i < kNumRounds; i++) + { + sha.Update(buf, rawSize); + // if (_rar350Mode) + { + const UInt32 kBlockSize = 64; + const UInt32 endPos = (pos + (UInt32)rawSize) & ~(kBlockSize - 1); + if (endPos > pos + kBlockSize) + { + UInt32 curPos = pos & ~(kBlockSize - 1); + curPos += kBlockSize; + do + { + UpdatePswDataSha1(buf + (curPos - pos)); + curPos += kBlockSize; + } + while (curPos != endPos); + } + } + pos += (UInt32)rawSize; +#if 1 + UInt32 pswNum; + SetUi32a(&pswNum, i) + sha.Update((const Byte *)&pswNum, 3); +#else + Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; + sha.Update(pswNum, 3); +#endif + pos += 3; + if (i % (kNumRounds / 16) == 0) + { + MY_ALIGN (16) + NSha1::CContext shaTemp = sha; + shaTemp.Final(digest); + _iv[i / (kNumRounds / 16)] = (Byte)digest[4 * 4 + 3]; + } + } + + sha.Final(digest); + for (i = 0; i < 4; i++) + for (unsigned j = 0; j < 4; j++) + _key[i * 4 + j] = (digest[i * 4 + 3 - j]); + + _needCalc = false; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/RarAes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.h --- p7zip-rar-16.02/CPP/7zip/Crypto/RarAes.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/RarAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -1,52 +1,54 @@ -// Crypto/RarAes.h - -#ifndef __CRYPTO_RAR_AES_H -#define __CRYPTO_RAR_AES_H - -#include "../../../C/Aes.h" - -#include "../../Common/MyBuffer.h" - -#include "../IPassword.h" - -#include "MyAes.h" - -namespace NCrypto { -namespace NRar3 { - -const unsigned kAesKeySize = 16; - -class CDecoder: - public CAesCbcDecoder - // public ICompressSetDecoderProperties2, - // public ICryptoSetPassword -{ - Byte _salt[8]; - bool _thereIsSalt; - bool _needCalc; - // bool _rar350Mode; - - CByteBuffer _password; - - Byte _key[kAesKeySize]; - Byte _iv[AES_BLOCK_SIZE]; - - void CalcKey(); -public: - /* - MY_UNKNOWN_IMP1( - ICryptoSetPassword - // ICompressSetDecoderProperties2 - */ - STDMETHOD(Init)(); - - void SetPassword(const Byte *data, unsigned size); - HRESULT SetDecoderProperties2(const Byte *data, UInt32 size); - - CDecoder(); - // void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } -}; - -}} - -#endif +// Crypto/RarAes.h + +#ifndef ZIP7_INC_CRYPTO_RAR_AES_H +#define ZIP7_INC_CRYPTO_RAR_AES_H + +#include "../../../C/Aes.h" + +#include "../../Common/MyBuffer.h" + +#include "../IPassword.h" + +#include "MyAes.h" + +namespace NCrypto { +namespace NRar3 { + +const unsigned kAesKeySize = 16; + +class CDecoder Z7_final: + public CAesCbcDecoder +{ + Byte _salt[8]; + bool _thereIsSalt; + bool _needCalc; + // bool _rar350Mode; + + CByteBuffer _password; + + Byte _key[kAesKeySize]; + Byte _iv[AES_BLOCK_SIZE]; + + void CalcKey(); +public: + Z7_COM7F_IMP(Init()) + + void SetPassword(const Byte *data, unsigned size); + HRESULT SetDecoderProperties2(const Byte *data, UInt32 size); + + CDecoder(); + + ~CDecoder() Z7_DESTRUCTOR_override { Wipe(); } + void Wipe() + { + _password.Wipe(); + Z7_memset_0_ARRAY(_salt); + Z7_memset_0_ARRAY(_key); + Z7_memset_0_ARRAY(_iv); + } + // void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/Sha1Cls.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Sha1Cls.h --- p7zip-rar-16.02/CPP/7zip/Crypto/Sha1Cls.h 2016-06-11 08:08:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/Sha1Cls.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,51 +1,37 @@ -// Crypto/Sha1.h - -#ifndef __CRYPTO_SHA1_H -#define __CRYPTO_SHA1_H - -#include "../../../C/Sha1.h" - -namespace NCrypto { -namespace NSha1 { - -const unsigned kNumBlockWords = SHA1_NUM_BLOCK_WORDS; -const unsigned kNumDigestWords = SHA1_NUM_DIGEST_WORDS; - -const unsigned kBlockSize = SHA1_BLOCK_SIZE; -const unsigned kDigestSize = SHA1_DIGEST_SIZE; - -class CContextBase -{ -protected: - CSha1 _s; - -public: - void Init() throw() { Sha1_Init(&_s); } - void GetBlockDigest(const UInt32 *blockData, UInt32 *destDigest) throw() { Sha1_GetBlockDigest(&_s, blockData, destDigest); } -}; - -class CContext: public CContextBase -{ -public: - void Update(const Byte *data, size_t size) throw() { Sha1_Update(&_s, data, size); } - void UpdateRar(Byte *data, size_t size /* , bool rar350Mode */) throw() { Sha1_Update_Rar(&_s, data, size /* , rar350Mode ? 1 : 0 */); } - void Final(Byte *digest) throw() { Sha1_Final(&_s, digest); } -}; - -class CContext32: public CContextBase -{ -public: - void Update(const UInt32 *data, size_t size) throw() { Sha1_32_Update(&_s, data, size); } - void Final(UInt32 *digest) throw() { Sha1_32_Final(&_s, digest); } - - /* PrepareBlock can be used only when size <= 13. size in Words - _buffer must be empty (_count & 0xF) == 0) */ - void PrepareBlock(UInt32 *block, unsigned size) const throw() - { - Sha1_32_PrepareBlock(&_s, block, size); - } -}; - -}} - -#endif +// Crypto/Sha1Cls.h + +#ifndef ZIP7_INC_CRYPTO_SHA1_CLS_H +#define ZIP7_INC_CRYPTO_SHA1_CLS_H + +#include "../../../C/Sha1.h" + +namespace NCrypto { +namespace NSha1 { + +const unsigned kNumBlockWords = SHA1_NUM_BLOCK_WORDS; +const unsigned kNumDigestWords = SHA1_NUM_DIGEST_WORDS; + +const unsigned kBlockSize = SHA1_BLOCK_SIZE; +const unsigned kDigestSize = SHA1_DIGEST_SIZE; + +class CContext +{ + CSha1 _s; + +public: + void Init() throw() { Sha1_Init(&_s); } + void Update(const Byte *data, size_t size) throw() { Sha1_Update(&_s, data, size); } + void Final(Byte *digest) throw() { Sha1_Final(&_s, digest); } + void PrepareBlock(Byte *block, unsigned size) const throw() + { + Sha1_PrepareBlock(&_s, block, size); + } + void GetBlockDigest(const Byte *blockData, Byte *destDigest) const throw() + { + Sha1_GetBlockDigest(&_s, blockData, destDigest); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/Crypto/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/WzAes.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/WzAes.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.cpp 2023-04-02 10:00:00.000000000 +0000 @@ -1,235 +1,231 @@ -// Crypto/WzAes.cpp -/* -This code implements Brian Gladman's scheme -specified in "A Password Based File Encryption Utility". - -Note: you must include MyAes.cpp to project to initialize AES tables -*/ - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "../Common/StreamUtils.h" - -#include "Pbkdf2HmacSha1.h" -#include "RandGen.h" -#include "WzAes.h" - -// define it if you don't want to use speed-optimized version of NSha1::Pbkdf2Hmac -// #define _NO_WZAES_OPTIMIZATIONS - -namespace NCrypto { -namespace NWzAes { - -const unsigned kAesKeySizeMax = 32; - -static const UInt32 kNumKeyGenIterations = 1000; - -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - if (size > kPasswordSizeMax) - return E_INVALIDARG; - _key.Password.CopyFrom(data, (size_t)size); - return S_OK; -} - -void CBaseCoder::Init2() -{ - const unsigned dkSizeMax32 = (2 * kAesKeySizeMax + kPwdVerifSize + 3) / 4; - Byte dk[dkSizeMax32 * 4]; - - const unsigned keySize = _key.GetKeySize(); - const unsigned dkSize = 2 * keySize + kPwdVerifSize; - - // for (unsigned ii = 0; ii < 1000; ii++) - { - #ifdef _NO_WZAES_OPTIMIZATIONS - - NSha1::Pbkdf2Hmac( - _key.Password, _key.Password.Size(), - _key.Salt, _key.GetSaltSize(), - kNumKeyGenIterations, - dk, dkSize); - - #else - - UInt32 dk32[dkSizeMax32]; - const unsigned dkSize32 = (dkSize + 3) / 4; - UInt32 salt[kSaltSizeMax / 4]; - unsigned numSaltWords = _key.GetNumSaltWords(); - - for (unsigned i = 0; i < numSaltWords; i++) - { - const Byte *src = _key.Salt + i * 4; - salt[i] = GetBe32(src); - } - - NSha1::Pbkdf2Hmac32( - _key.Password, _key.Password.Size(), - salt, numSaltWords, - kNumKeyGenIterations, - dk32, dkSize32); - - /* - for (unsigned j = 0; j < dkSize; j++) - dk[j] = (Byte)(dk32[j / 4] >> (24 - 8 * (j & 3))); - */ - for (unsigned j = 0; j < dkSize32; j++) - SetBe32(dk + j * 4, dk32[j]); - - #endif - } - - _hmac.SetKey(dk + keySize, keySize); - memcpy(_key.PwdVerifComputed, dk + 2 * keySize, kPwdVerifSize); - - Aes_SetKey_Enc(_aes.aes + _aes.offset + 8, dk, keySize); - AesCtr2_Init(&_aes); -} - -STDMETHODIMP CBaseCoder::Init() -{ - return S_OK; -} - -HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) -{ - unsigned saltSize = _key.GetSaltSize(); - g_RandomGenerator.Generate(_key.Salt, saltSize); - Init2(); - RINOK(WriteStream(outStream, _key.Salt, saltSize)); - return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifSize); -} - -HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream) -{ - Byte mac[kMacSize]; - _hmac.Final(mac, kMacSize); - return WriteStream(outStream, mac, kMacSize); -} - -/* -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size != 1) - return E_INVALIDARG; - _key.Init(); - return SetKeyMode(data[0]) ? S_OK : E_INVALIDARG; -} -*/ - -HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) -{ - unsigned saltSize = _key.GetSaltSize(); - unsigned extraSize = saltSize + kPwdVerifSize; - Byte temp[kSaltSizeMax + kPwdVerifSize]; - RINOK(ReadStream_FAIL(inStream, temp, extraSize)); - unsigned i; - for (i = 0; i < saltSize; i++) - _key.Salt[i] = temp[i]; - for (i = 0; i < kPwdVerifSize; i++) - _pwdVerifFromArchive[i] = temp[saltSize + i]; - return S_OK; -} - -static inline bool CompareArrays(const Byte *p1, const Byte *p2, unsigned size) -{ - for (unsigned i = 0; i < size; i++) - if (p1[i] != p2[i]) - return false; - return true; -} - -bool CDecoder::Init_and_CheckPassword() -{ - Init2(); - return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifSize); -} - -HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK) -{ - isOK = false; - Byte mac1[kMacSize]; - RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)); - Byte mac2[kMacSize]; - _hmac.Final(mac2, kMacSize); - isOK = CompareArrays(mac1, mac2, kMacSize); - return S_OK; -} - -CAesCtr2::CAesCtr2() -{ - offset = ((0 - (unsigned)(ptrdiff_t)aes) & 0xF) / sizeof(UInt32); -} - -void AesCtr2_Init(CAesCtr2 *p) -{ - UInt32 *ctr = p->aes + p->offset + 4; - unsigned i; - for (i = 0; i < 4; i++) - ctr[i] = 0; - p->pos = AES_BLOCK_SIZE; -} - -/* (size != 16 * N) is allowed only for last call */ - -void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size) -{ - unsigned pos = p->pos; - UInt32 *buf32 = p->aes + p->offset; - if (size == 0) - return; - - if (pos != AES_BLOCK_SIZE) - { - const Byte *buf = (const Byte *)buf32; - do - *data++ ^= buf[pos++]; - while (--size != 0 && pos != AES_BLOCK_SIZE); - } - - if (size >= 16) - { - SizeT size2 = size >> 4; - g_AesCtr_Code(buf32 + 4, data, size2); - size2 <<= 4; - data += size2; - size -= size2; - pos = AES_BLOCK_SIZE; - } - - if (size != 0) - { - unsigned j; - const Byte *buf; - for (j = 0; j < 4; j++) - buf32[j] = 0; - g_AesCtr_Code(buf32 + 4, (Byte *)buf32, 1); - buf = (const Byte *)buf32; - pos = 0; - do - *data++ ^= buf[pos++]; - while (--size != 0); - } - - p->pos = pos; -} - -/* (size != 16 * N) is allowed only for last Filter() call */ - -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) -{ - AesCtr2_Code(&_aes, data, size); - _hmac.Update(data, size); - return size; -} - -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) -{ - _hmac.Update(data, size); - AesCtr2_Code(&_aes, data, size); - return size; -} - -}} +// Crypto/WzAes.cpp +/* +This code implements Brian Gladman's scheme +specified in "A Password Based File Encryption Utility". + +Note: you must include MyAes.cpp to project to initialize AES tables +*/ + +#include "StdAfx.h" + +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "Pbkdf2HmacSha1.h" +#include "RandGen.h" +#include "WzAes.h" + +namespace NCrypto { +namespace NWzAes { + +const unsigned kAesKeySizeMax = 32; + +static const UInt32 kNumKeyGenIterations = 1000; + +Z7_COM7F_IMF(CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)) +{ + if (size > kPasswordSizeMax) + return E_INVALIDARG; + _key.Password.Wipe(); + _key.Password.CopyFrom(data, (size_t)size); + return S_OK; +} + +void CBaseCoder::Init2() +{ + _hmacOverCalc = 0; + const unsigned dkSizeMax32 = (2 * kAesKeySizeMax + kPwdVerifSize + 3) / 4; + Byte dk[dkSizeMax32 * 4]; + + const unsigned keySize = _key.GetKeySize(); + const unsigned dkSize = 2 * keySize + ((kPwdVerifSize + 3) & ~(unsigned)3); + + // for (unsigned ii = 0; ii < 1000; ii++) + { + NSha1::Pbkdf2Hmac( + _key.Password, _key.Password.Size(), + _key.Salt, _key.GetSaltSize(), + kNumKeyGenIterations, + dk, dkSize); + } + + Hmac()->SetKey(dk + keySize, keySize); + memcpy(_key.PwdVerifComputed, dk + 2 * keySize, kPwdVerifSize); + + // Aes_SetKey_Enc(_aes.Aes() + 8, dk, keySize); + // AesCtr2_Init(&_aes); + _aesCoderSpec->SetKeySize(keySize); + if (_aesCoderSpec->SetKey(dk, keySize) != S_OK) throw 2; + if (_aesCoderSpec->Init() != S_OK) throw 3; +} + +Z7_COM7F_IMF(CBaseCoder::Init()) +{ + return S_OK; +} + +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) +{ + unsigned saltSize = _key.GetSaltSize(); + MY_RAND_GEN(_key.Salt, saltSize); + Init2(); + RINOK(WriteStream(outStream, _key.Salt, saltSize)) + return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifSize); +} + +HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream) +{ + MY_ALIGN (16) + UInt32 mac[NSha1::kNumDigestWords]; + Hmac()->Final((Byte *)mac); + return WriteStream(outStream, mac, kMacSize); +} + +/* +Z7_COM7F_IMF(CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)) +{ + if (size != 1) + return E_INVALIDARG; + _key.Init(); + return SetKeyMode(data[0]) ? S_OK : E_INVALIDARG; +} +*/ + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + const unsigned saltSize = _key.GetSaltSize(); + const unsigned extraSize = saltSize + kPwdVerifSize; + Byte temp[kSaltSizeMax + kPwdVerifSize]; + RINOK(ReadStream_FAIL(inStream, temp, extraSize)) + unsigned i; + for (i = 0; i < saltSize; i++) + _key.Salt[i] = temp[i]; + for (i = 0; i < kPwdVerifSize; i++) + _pwdVerifFromArchive[i] = temp[saltSize + i]; + return S_OK; +} + +static inline bool CompareArrays(const Byte *p1, const Byte *p2, unsigned size) +{ + for (unsigned i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} + +bool CDecoder::Init_and_CheckPassword() +{ + Init2(); + return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifSize); +} + +HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK) +{ + isOK = false; + MY_ALIGN (16) + Byte mac1[kMacSize]; + RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)) + MY_ALIGN (16) + UInt32 mac2[NSha1::kNumDigestWords]; + Hmac()->Final((Byte *)mac2); + isOK = CompareArrays(mac1, (const Byte *)mac2, kMacSize); + if (_hmacOverCalc) + isOK = false; + return S_OK; +} + +/* + +CAesCtr2::CAesCtr2(): + aes((4 + AES_NUM_IVMRK_WORDS) * 4) +{ + // offset = ((0 - (unsigned)(ptrdiff_t)aes) & 0xF) / sizeof(UInt32); + // first 16 bytes are buffer for last block data. + // so the ivAES is aligned for (Align + 16). +} + +void AesCtr2_Init(CAesCtr2 *p) +{ + UInt32 *ctr = p->Aes() + 4; + unsigned i; + for (i = 0; i < 4; i++) + ctr[i] = 0; + p->pos = AES_BLOCK_SIZE; +} + +// (size != 16 * N) is allowed only for last call + +void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size) +{ + unsigned pos = p->pos; + UInt32 *buf32 = p->Aes(); + if (size == 0) + return; + + if (pos != AES_BLOCK_SIZE) + { + const Byte *buf = (const Byte *)buf32; + do + *data++ ^= buf[pos++]; + while (--size != 0 && pos != AES_BLOCK_SIZE); + } + + // (size == 0 || pos == AES_BLOCK_SIZE) + + if (size >= 16) + { + SizeT size2 = size >> 4; + g_AesCtr_Code(buf32 + 4, data, size2); + size2 <<= 4; + data += size2; + size -= size2; + // (pos == AES_BLOCK_SIZE) + } + + // (size < 16) + + if (size != 0) + { + unsigned j; + const Byte *buf; + for (j = 0; j < 4; j++) + buf32[j] = 0; + g_AesCtr_Code(buf32 + 4, (Byte *)buf32, 1); + buf = (const Byte *)buf32; + pos = 0; + do + *data++ ^= buf[pos++]; + while (--size != 0); + } + + p->pos = pos; +} +*/ + +/* (size != 16 * N) is allowed only for last Filter() call */ + +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) +{ + // AesCtr2_Code(&_aes, data, size); + size = _aesCoder->Filter(data, size); + Hmac()->Update(data, size); + return size; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + if (size >= 16) + size &= ~(UInt32)15; + if (_hmacOverCalc < size) + { + Hmac()->Update(data + _hmacOverCalc, size - _hmacOverCalc); + _hmacOverCalc = size; + } + // AesCtr2_Code(&_aes, data, size); + size = _aesCoder->Filter(data, size); + _hmacOverCalc -= size; + return size; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/WzAes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.h --- p7zip-rar-16.02/CPP/7zip/Crypto/WzAes.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/WzAes.h 2023-04-02 10:00:00.000000000 +0000 @@ -1,135 +1,161 @@ -// Crypto/WzAes.h -/* -This code implements Brian Gladman's scheme -specified in "A Password Based File Encryption Utility": - - AES encryption (128,192,256-bit) in Counter (CTR) mode. - - HMAC-SHA1 authentication for encrypted data (10 bytes) - - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and - Salt (saltSize = aesKeySize / 2). - - 2 bytes contain Password Verifier's Code -*/ - -#ifndef __CRYPTO_WZ_AES_H -#define __CRYPTO_WZ_AES_H - -#include "../../../C/Aes.h" - -#include "../../Common/MyBuffer.h" -#include "../../Common/MyCom.h" - -#include "../ICoder.h" -#include "../IPassword.h" - -#include "HmacSha1.h" - -namespace NCrypto { -namespace NWzAes { - -/* ICompressFilter::Init() does nothing for this filter. - - Call to init: - Encoder: - CryptoSetPassword(); - WriteHeader(); - Decoder: - [CryptoSetPassword();] - ReadHeader(); - [CryptoSetPassword();] Init_and_CheckPassword(); - [CryptoSetPassword();] Init_and_CheckPassword(); -*/ - -const UInt32 kPasswordSizeMax = 99; // 128; - -const unsigned kSaltSizeMax = 16; -const unsigned kPwdVerifSize = 2; -const unsigned kMacSize = 10; - -enum EKeySizeMode -{ - kKeySizeMode_AES128 = 1, - kKeySizeMode_AES192 = 2, - kKeySizeMode_AES256 = 3 -}; - -struct CKeyInfo -{ - EKeySizeMode KeySizeMode; - Byte Salt[kSaltSizeMax]; - Byte PwdVerifComputed[kPwdVerifSize]; - - CByteBuffer Password; - - unsigned GetKeySize() const { return (8 * KeySizeMode + 8); } - unsigned GetSaltSize() const { return (4 * KeySizeMode + 4); } - unsigned GetNumSaltWords() const { return (KeySizeMode + 1); } - - CKeyInfo(): KeySizeMode(kKeySizeMode_AES256) {} -}; - -struct CAesCtr2 -{ - unsigned pos; - unsigned offset; - UInt32 aes[4 + AES_NUM_IVMRK_WORDS + 3]; - CAesCtr2(); -}; - -void AesCtr2_Init(CAesCtr2 *p); -void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size); - -class CBaseCoder: - public ICompressFilter, - public ICryptoSetPassword, - public CMyUnknownImp -{ -protected: - CKeyInfo _key; - NSha1::CHmac _hmac; - CAesCtr2 _aes; - - void Init2(); -public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) - - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); - - STDMETHOD(Init)(); - - unsigned GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifSize; } - unsigned GetAddPackSize() const { return GetHeaderSize() + kMacSize; } - - bool SetKeyMode(unsigned mode) - { - if (mode < kKeySizeMode_AES128 || mode > kKeySizeMode_AES256) - return false; - _key.KeySizeMode = (EKeySizeMode)mode; - return true; - } -}; - -class CEncoder: - public CBaseCoder -{ -public: - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - HRESULT WriteHeader(ISequentialOutStream *outStream); - HRESULT WriteFooter(ISequentialOutStream *outStream); -}; - -class CDecoder: - public CBaseCoder - // public ICompressSetDecoderProperties2 -{ - Byte _pwdVerifFromArchive[kPwdVerifSize]; -public: - // ICompressSetDecoderProperties2 - // STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - HRESULT ReadHeader(ISequentialInStream *inStream); - bool Init_and_CheckPassword(); - HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK); -}; - -}} - -#endif +// Crypto/WzAes.h +/* +This code implements Brian Gladman's scheme +specified in "A Password Based File Encryption Utility": + - AES encryption (128,192,256-bit) in Counter (CTR) mode. + - HMAC-SHA1 authentication for encrypted data (10 bytes) + - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and + Salt (saltSize = aesKeySize / 2). + - 2 bytes contain Password Verifier's Code +*/ + +#ifndef ZIP7_INC_CRYPTO_WZ_AES_H +#define ZIP7_INC_CRYPTO_WZ_AES_H + +#include "../../Common/MyBuffer.h" + +#include "../IPassword.h" + +#include "HmacSha1.h" +#include "MyAes.h" + +namespace NCrypto { +namespace NWzAes { + +/* ICompressFilter::Init() does nothing for this filter. + + Call to init: + Encoder: + CryptoSetPassword(); + WriteHeader(); + Decoder: + [CryptoSetPassword();] + ReadHeader(); + [CryptoSetPassword();] Init_and_CheckPassword(); + [CryptoSetPassword();] Init_and_CheckPassword(); +*/ + +const UInt32 kPasswordSizeMax = 99; // 128; + +const unsigned kSaltSizeMax = 16; +const unsigned kPwdVerifSize = 2; +const unsigned kMacSize = 10; + +enum EKeySizeMode +{ + kKeySizeMode_AES128 = 1, + kKeySizeMode_AES192 = 2, + kKeySizeMode_AES256 = 3 +}; + +struct CKeyInfo +{ + EKeySizeMode KeySizeMode; + Byte Salt[kSaltSizeMax]; + Byte PwdVerifComputed[kPwdVerifSize]; + + CByteBuffer Password; + + unsigned GetKeySize() const { return (8 * KeySizeMode + 8); } + unsigned GetSaltSize() const { return (4 * KeySizeMode + 4); } + unsigned GetNumSaltWords() const { return (KeySizeMode + 1); } + + CKeyInfo(): KeySizeMode(kKeySizeMode_AES256) {} + + void Wipe() + { + Password.Wipe(); + Z7_memset_0_ARRAY(Salt); + Z7_memset_0_ARRAY(PwdVerifComputed); + } + + ~CKeyInfo() { Wipe(); } +}; + +/* +struct CAesCtr2 +{ + unsigned pos; + CAlignedBuffer aes; + UInt32 *Aes() { return (UInt32 *)(Byte *)aes; } + + // unsigned offset; + // UInt32 aes[4 + AES_NUM_IVMRK_WORDS + 3]; + // UInt32 *Aes() { return aes + offset; } + CAesCtr2(); +}; + +void AesCtr2_Init(CAesCtr2 *p); +void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size); +*/ + +class CBaseCoder: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1(ICryptoSetPassword) + Z7_COM7F_IMP(Init()) +public: + Z7_IFACE_COM7_IMP(ICryptoSetPassword) +protected: + CKeyInfo _key; + + // NSha1::CHmac _hmac; + // NSha1::CHmac *Hmac() { return &_hmac; } + CAlignedBuffer1 _hmacBuf; + UInt32 _hmacOverCalc; + + NSha1::CHmac *Hmac() { return (NSha1::CHmac *)(void *)(Byte *)_hmacBuf; } + + // CAesCtr2 _aes; + CAesCoder *_aesCoderSpec; + CMyComPtr _aesCoder; + CBaseCoder(): + _hmacBuf(sizeof(NSha1::CHmac)) + { + _aesCoderSpec = new CAesCtrCoder(32); + _aesCoder = _aesCoderSpec; + } + + void Init2(); +public: + unsigned GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifSize; } + unsigned GetAddPackSize() const { return GetHeaderSize() + kMacSize; } + + bool SetKeyMode(unsigned mode) + { + if (mode < kKeySizeMode_AES128 || mode > kKeySizeMode_AES256) + return false; + _key.KeySizeMode = (EKeySizeMode)mode; + return true; + } + + virtual ~CBaseCoder() {} +}; + +class CEncoder Z7_final: + public CBaseCoder +{ + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + HRESULT WriteHeader(ISequentialOutStream *outStream); + HRESULT WriteFooter(ISequentialOutStream *outStream); +}; + +class CDecoder Z7_final: + public CBaseCoder + // public ICompressSetDecoderProperties2 +{ + Byte _pwdVerifFromArchive[kPwdVerifSize]; + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + // Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2) + HRESULT ReadHeader(ISequentialInStream *inStream); + bool Init_and_CheckPassword(); + HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/ZipCrypto.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/ZipCrypto.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.cpp 2023-02-01 09:00:00.000000000 +0000 @@ -1,114 +1,114 @@ -// Crypto/ZipCrypto.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" - -#include "../Common/StreamUtils.h" - -#include "RandGen.h" -#include "ZipCrypto.h" - -namespace NCrypto { -namespace NZip { - -#define UPDATE_KEYS(b) { \ - key0 = CRC_UPDATE_BYTE(key0, b); \ - key1 = (key1 + (key0 & 0xFF)) * 0x8088405 + 1; \ - key2 = CRC_UPDATE_BYTE(key2, (Byte)(key1 >> 24)); } \ - -#define DECRYPT_BYTE_1 UInt32 temp = key2 | 2; -#define DECRYPT_BYTE_2 ((Byte)((temp * (temp ^ 1)) >> 8)) - -STDMETHODIMP CCipher::CryptoSetPassword(const Byte *data, UInt32 size) -{ - UInt32 key0 = 0x12345678; - UInt32 key1 = 0x23456789; - UInt32 key2 = 0x34567890; - - for (UInt32 i = 0; i < size; i++) - UPDATE_KEYS(data[i]); - - KeyMem0 = key0; - KeyMem1 = key1; - KeyMem2 = key2; - - return S_OK; -} - -STDMETHODIMP CCipher::Init() -{ - return S_OK; -} - -HRESULT CEncoder::WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc) -{ - Byte h[kHeaderSize]; - - /* PKZIP before 2.0 used 2 byte CRC check. - PKZIP 2.0+ used 1 byte CRC check. It's more secure. - We also use 1 byte CRC. */ - - g_RandomGenerator.Generate(h, kHeaderSize - 1); - // h[kHeaderSize - 2] = (Byte)(crc); - h[kHeaderSize - 1] = (Byte)(crc >> 8); - - RestoreKeys(); - Filter(h, kHeaderSize); - return WriteStream(outStream, h, kHeaderSize); -} - -STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) -{ - UInt32 key0 = this->Key0; - UInt32 key1 = this->Key1; - UInt32 key2 = this->Key2; - - for (UInt32 i = 0; i < size; i++) - { - Byte b = data[i]; - DECRYPT_BYTE_1 - data[i] = (Byte)(b ^ DECRYPT_BYTE_2); - UPDATE_KEYS(b); - } - - this->Key0 = key0; - this->Key1 = key1; - this->Key2 = key2; - - return size; -} - -HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) -{ - return ReadStream_FAIL(inStream, _header, kHeaderSize); -} - -void CDecoder::Init_BeforeDecode() -{ - RestoreKeys(); - Filter(_header, kHeaderSize); -} - -STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) -{ - UInt32 key0 = this->Key0; - UInt32 key1 = this->Key1; - UInt32 key2 = this->Key2; - - for (UInt32 i = 0; i < size; i++) - { - DECRYPT_BYTE_1 - Byte b = (Byte)(data[i] ^ DECRYPT_BYTE_2); - UPDATE_KEYS(b); - data[i] = b; - } - - this->Key0 = key0; - this->Key1 = key1; - this->Key2 = key2; - - return size; -} - -}} +// Crypto/ZipCrypto.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" + +#include "../Common/StreamUtils.h" + +#include "RandGen.h" +#include "ZipCrypto.h" + +namespace NCrypto { +namespace NZip { + +#define UPDATE_KEYS(b) { \ + key0 = CRC_UPDATE_BYTE(key0, b); \ + key1 = (key1 + (key0 & 0xFF)) * 0x8088405 + 1; \ + key2 = CRC_UPDATE_BYTE(key2, (Byte)(key1 >> 24)); } \ + +#define DECRYPT_BYTE_1 UInt32 temp = key2 | 2; +#define DECRYPT_BYTE_2 ((Byte)((temp * (temp ^ 1)) >> 8)) + +Z7_COM7F_IMF(CCipher::CryptoSetPassword(const Byte *data, UInt32 size)) +{ + UInt32 key0 = 0x12345678; + UInt32 key1 = 0x23456789; + UInt32 key2 = 0x34567890; + + for (UInt32 i = 0; i < size; i++) + UPDATE_KEYS(data[i]) + + KeyMem0 = key0; + KeyMem1 = key1; + KeyMem2 = key2; + + return S_OK; +} + +Z7_COM7F_IMF(CCipher::Init()) +{ + return S_OK; +} + +HRESULT CEncoder::WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc) +{ + Byte h[kHeaderSize]; + + /* PKZIP before 2.0 used 2 byte CRC check. + PKZIP 2.0+ used 1 byte CRC check. It's more secure. + We also use 1 byte CRC. */ + + MY_RAND_GEN(h, kHeaderSize - 1); + // h[kHeaderSize - 2] = (Byte)(crc); + h[kHeaderSize - 1] = (Byte)(crc >> 8); + + RestoreKeys(); + Filter(h, kHeaderSize); + return WriteStream(outStream, h, kHeaderSize); +} + +Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size)) +{ + UInt32 key0 = this->Key0; + UInt32 key1 = this->Key1; + UInt32 key2 = this->Key2; + + for (UInt32 i = 0; i < size; i++) + { + Byte b = data[i]; + DECRYPT_BYTE_1 + data[i] = (Byte)(b ^ DECRYPT_BYTE_2); + UPDATE_KEYS(b) + } + + this->Key0 = key0; + this->Key1 = key1; + this->Key2 = key2; + + return size; +} + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) +{ + return ReadStream_FAIL(inStream, _header, kHeaderSize); +} + +void CDecoder::Init_BeforeDecode() +{ + RestoreKeys(); + Filter(_header, kHeaderSize); +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + UInt32 key0 = this->Key0; + UInt32 key1 = this->Key1; + UInt32 key2 = this->Key2; + + for (UInt32 i = 0; i < size; i++) + { + DECRYPT_BYTE_1 + Byte b = (Byte)(data[i] ^ DECRYPT_BYTE_2); + UPDATE_KEYS(b) + data[i] = b; + } + + this->Key0 = key0; + this->Key1 = key1; + this->Key2 = key2; + + return size; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/ZipCrypto.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.h --- p7zip-rar-16.02/CPP/7zip/Crypto/ZipCrypto.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipCrypto.h 2023-02-01 15:00:00.000000000 +0000 @@ -1,73 +1,80 @@ -// Crypto/ZipCrypto.h - -#ifndef __CRYPTO_ZIP_CRYPTO_H -#define __CRYPTO_ZIP_CRYPTO_H - -#include "../../Common/MyCom.h" - -#include "../ICoder.h" -#include "../IPassword.h" - -namespace NCrypto { -namespace NZip { - -const unsigned kHeaderSize = 12; - -/* ICompressFilter::Init() does nothing for this filter. - Call to init: - Encoder: - CryptoSetPassword(); - WriteHeader(); - Decoder: - [CryptoSetPassword();] - ReadHeader(); - [CryptoSetPassword();] Init_and_GetCrcByte(); - [CryptoSetPassword();] Init_and_GetCrcByte(); -*/ - -class CCipher: - public ICompressFilter, - public ICryptoSetPassword, - public CMyUnknownImp -{ -protected: - UInt32 Key0; - UInt32 Key1; - UInt32 Key2; - - UInt32 KeyMem0; - UInt32 KeyMem1; - UInt32 KeyMem2; - - void RestoreKeys() - { - Key0 = KeyMem0; - Key1 = KeyMem1; - Key2 = KeyMem2; - } - -public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) - STDMETHOD(Init)(); - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); -}; - -class CEncoder: public CCipher -{ -public: - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - HRESULT WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc); -}; - -class CDecoder: public CCipher -{ -public: - Byte _header[kHeaderSize]; - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size); - HRESULT ReadHeader(ISequentialInStream *inStream); - void Init_BeforeDecode(); -}; - -}} - -#endif +// Crypto/ZipCrypto.h + +#ifndef ZIP7_INC_CRYPTO_ZIP_CRYPTO_H +#define ZIP7_INC_CRYPTO_ZIP_CRYPTO_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" +#include "../IPassword.h" + +namespace NCrypto { +namespace NZip { + +const unsigned kHeaderSize = 12; + +/* ICompressFilter::Init() does nothing for this filter. + Call to init: + Encoder: + CryptoSetPassword(); + WriteHeader(); + Decoder: + [CryptoSetPassword();] + ReadHeader(); + [CryptoSetPassword();] Init_and_GetCrcByte(); + [CryptoSetPassword();] Init_and_GetCrcByte(); +*/ + +class CCipher: + public ICompressFilter, + public ICryptoSetPassword, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1(ICryptoSetPassword) + Z7_COM7F_IMP(Init()) +public: + Z7_IFACE_COM7_IMP(ICryptoSetPassword) +protected: + UInt32 Key0; + UInt32 Key1; + UInt32 Key2; + + UInt32 KeyMem0; + UInt32 KeyMem1; + UInt32 KeyMem2; + + void RestoreKeys() + { + Key0 = KeyMem0; + Key1 = KeyMem1; + Key2 = KeyMem2; + } + +public: + virtual ~CCipher() + { + Key0 = KeyMem0 = + Key1 = KeyMem1 = + Key2 = KeyMem2 = 0; + } +}; + +class CEncoder Z7_final: public CCipher +{ + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + HRESULT WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc); +}; + +class CDecoder Z7_final: public CCipher +{ + Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size)) +public: + Byte _header[kHeaderSize]; + HRESULT ReadHeader(ISequentialInStream *inStream); + void Init_BeforeDecode(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/ZipStrong.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.cpp --- p7zip-rar-16.02/CPP/7zip/Crypto/ZipStrong.cpp 2016-05-20 08:20:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.cpp 2024-11-19 10:00:00.000000000 +0000 @@ -1,226 +1,265 @@ -// Crypto/ZipStrong.cpp - -#include "StdAfx.h" - -#include "../../../C/7zCrc.h" -#include "../../../C/CpuArch.h" - -#include "../Common/StreamUtils.h" - -#include "Sha1Cls.h" -#include "ZipStrong.h" - -namespace NCrypto { -namespace NZipStrong { - -static const UInt16 kAES128 = 0x660E; - -// DeriveKey* function is similar to CryptDeriveKey() from Windows. -// But MSDN tells that we need such scheme only if -// "the required key length is longer than the hash value" -// but ZipStrong uses it always. - -static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) -{ - Byte buf[64]; - memset(buf, c, 64); - for (unsigned i = 0; i < NSha1::kDigestSize; i++) - buf[i] ^= digest[i]; - NSha1::CContext sha; - sha.Init(); - sha.Update(buf, 64); - sha.Final(dest); -} - -static void DeriveKey(NSha1::CContext &sha, Byte *key) -{ - Byte digest[NSha1::kDigestSize]; - sha.Final(digest); - Byte temp[NSha1::kDigestSize * 2]; - DeriveKey2(digest, 0x36, temp); - DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); - memcpy(key, temp, 32); -} - -void CKeyInfo::SetPassword(const Byte *data, UInt32 size) -{ - NSha1::CContext sha; - sha.Init(); - sha.Update(data, size); - DeriveKey(sha, MasterKey); -} - -STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) -{ - _key.SetPassword(data, size); - return S_OK; -} - -STDMETHODIMP CBaseCoder::Init() -{ - return S_OK; -} - -HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize) -{ - Byte temp[4]; - RINOK(ReadStream_FALSE(inStream, temp, 2)); - _ivSize = GetUi16(temp); - if (_ivSize == 0) - { - memset(_iv, 0, 16); - SetUi32(_iv + 0, crc); - SetUi64(_iv + 4, unpackSize); - _ivSize = 12; - } - else if (_ivSize == 16) - { - RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)); - } - else - return E_NOTIMPL; - RINOK(ReadStream_FALSE(inStream, temp, 4)); - _remSize = GetUi32(temp); - const UInt32 kAlign = 16; - if (_remSize < 16 || _remSize > (1 << 18)) - return E_NOTIMPL; - if (_remSize + kAlign > _buf.Size()) - { - _buf.Alloc(_remSize + kAlign); - _bufAligned = (Byte *)((ptrdiff_t)((Byte *)_buf + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1)); - } - return ReadStream_FALSE(inStream, _bufAligned, _remSize); -} - -HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) -{ - passwOK = false; - if (_remSize < 16) - return E_NOTIMPL; - Byte *p = _bufAligned; - UInt16 format = GetUi16(p); - if (format != 3) - return E_NOTIMPL; - UInt16 algId = GetUi16(p + 2); - if (algId < kAES128) - return E_NOTIMPL; - algId -= kAES128; - if (algId > 2) - return E_NOTIMPL; - UInt16 bitLen = GetUi16(p + 4); - UInt16 flags = GetUi16(p + 6); - if (algId * 64 + 128 != bitLen) - return E_NOTIMPL; - _key.KeySize = 16 + algId * 8; - bool cert = ((flags & 2) != 0); - - if ((flags & 0x4000) != 0) - { - // Use 3DES - return E_NOTIMPL; - } - - if (cert) - { - return E_NOTIMPL; - } - else - { - if ((flags & 1) == 0) - return E_NOTIMPL; - } - - UInt32 rdSize = GetUi16(p + 8); - - if (rdSize + 16 > _remSize) - return E_NOTIMPL; - - /* - if (cert) - { - // how to filter rd, if ((rdSize & 0xF) != 0) ? - if ((rdSize & 0x7) != 0) - return E_NOTIMPL; - } - else - */ - { - if ((rdSize & 0xF) != 0) - return E_NOTIMPL; - } - - memmove(p, p + 10, rdSize); - const Byte *p2 = p + rdSize + 10; - UInt32 reserved = GetUi32(p2); - p2 += 4; - - /* - if (cert) - { - UInt32 numRecipients = reserved; - - if (numRecipients == 0) - return E_NOTIMPL; - - { - UInt32 hashAlg = GetUi16(p2); - hashAlg = hashAlg; - UInt32 hashSize = GetUi16(p2 + 2); - hashSize = hashSize; - p2 += 4; - - reserved = reserved; - // return E_NOTIMPL; - - for (unsigned r = 0; r < numRecipients; r++) - { - UInt32 specSize = GetUi16(p2); - p2 += 2; - p2 += specSize; - } - } - } - else - */ - { - if (reserved != 0) - return E_NOTIMPL; - } - - UInt32 validSize = GetUi16(p2); - p2 += 2; - const size_t validOffset = p2 - p; - if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize) - return E_NOTIMPL; - - { - RINOK(SetKey(_key.MasterKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - RINOK(Init()); - Filter(p, rdSize); - } - - Byte fileKey[32]; - NSha1::CContext sha; - sha.Init(); - sha.Update(_iv, _ivSize); - sha.Update(p, rdSize - 16); // we don't use last 16 bytes (PAD bytes) - DeriveKey(sha, fileKey); - - RINOK(SetKey(fileKey, _key.KeySize)); - RINOK(SetInitVector(_iv, 16)); - Init(); - - memmove(p, p + validOffset, validSize); - Filter(p, validSize); - - if (validSize < 4) - return E_NOTIMPL; - validSize -= 4; - if (GetUi32(p + validSize) != CrcCalc(p, validSize)) - return S_OK; - passwOK = true; - return S_OK; -} - -}} +// Crypto/ZipStrong.cpp + +#include "StdAfx.h" + +#include "../../../C/7zCrc.h" +#include "../../../C/CpuArch.h" + +#include "../Common/StreamUtils.h" + +#include "Sha1Cls.h" +#include "ZipStrong.h" + +namespace NCrypto { +namespace NZipStrong { + +static const UInt16 kAES128 = 0x660E; + +/* + DeriveKey() function is similar to CryptDeriveKey() from Windows. + New version of MSDN contains the following condition in CryptDeriveKey() description: + "If the hash is not a member of the SHA-2 family and the required key is for either 3DES or AES". + Now we support ZipStrong for AES only. And it uses SHA1. + Our DeriveKey() code is equal to CryptDeriveKey() in Windows for such conditions: (SHA1 + AES). + if (method != AES && method != 3DES), probably we need another code. +*/ + +static void DeriveKey2(const UInt32 *digest32, Byte c, UInt32 *dest32) +{ + const unsigned kBufSize = 64; + MY_ALIGN (16) + UInt32 buf32[kBufSize / 4]; + memset(buf32, c, kBufSize); + for (unsigned i = 0; i < NSha1::kNumDigestWords; i++) + buf32[i] ^= digest32[i]; + MY_ALIGN (16) + NSha1::CContext sha; + sha.Init(); + sha.Update((const Byte *)buf32, kBufSize); + sha.Final((Byte *)dest32); +} + +static void DeriveKey(NSha1::CContext &sha, Byte *key) +{ + MY_ALIGN (16) + UInt32 digest32[NSha1::kNumDigestWords]; + sha.Final((Byte *)digest32); + MY_ALIGN (16) + UInt32 temp32[NSha1::kNumDigestWords * 2]; + DeriveKey2(digest32, 0x36, temp32); + DeriveKey2(digest32, 0x5C, temp32 + NSha1::kNumDigestWords); + memcpy(key, temp32, 32); +} + +void CKeyInfo::SetPassword(const Byte *data, UInt32 size) +{ + MY_ALIGN (16) + NSha1::CContext sha; + sha.Init(); + sha.Update(data, size); + DeriveKey(sha, MasterKey); +} + + + +CDecoder::CDecoder() +{ + CAesCbcDecoder *d = new CAesCbcDecoder(); + _cbcDecoder = d; + _aesFilter = d; +} + +Z7_COM7F_IMF(CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)) +{ + _key.SetPassword(data, size); + return S_OK; +} + +Z7_COM7F_IMF(CDecoder::Init()) +{ + return S_OK; +} + +Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size)) +{ + return _aesFilter->Filter(data, size); +} + + +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize) +{ + Byte temp[4]; + RINOK(ReadStream_FALSE(inStream, temp, 2)) + _ivSize = GetUi16(temp); + if (_ivSize == 0) + { + memset(_iv, 0, 16); + SetUi32(_iv + 0, crc) + SetUi64(_iv + 4, unpackSize) + _ivSize = 12; + } + else if (_ivSize == 16) + { + RINOK(ReadStream_FALSE(inStream, _iv, _ivSize)) + } + else + return E_NOTIMPL; + RINOK(ReadStream_FALSE(inStream, temp, 4)) + _remSize = GetUi32(temp); + // const UInt32 kAlign = 16; + if (_remSize < 16 || _remSize > (1 << 18)) + return E_NOTIMPL; + if (_remSize > _bufAligned.Size()) + { + _bufAligned.AllocAtLeast(_remSize); + if (!(Byte *)_bufAligned) + return E_OUTOFMEMORY; + } + return ReadStream_FALSE(inStream, _bufAligned, _remSize); +} + +HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) +{ + passwOK = false; + if (_remSize < 16) + return E_NOTIMPL; + Byte * const p = _bufAligned; + const unsigned format = GetUi16a(p); + if (format != 3) + return E_NOTIMPL; + unsigned algId = GetUi16a(p + 2); + if (algId < kAES128) + return E_NOTIMPL; + algId -= kAES128; + if (algId > 2) + return E_NOTIMPL; + const unsigned bitLen = GetUi16a(p + 4); + const unsigned flags = GetUi16a(p + 6); + if (algId * 64 + 128 != bitLen) + return E_NOTIMPL; + _key.KeySize = 16 + algId * 8; + const bool cert = ((flags & 2) != 0); + + if (flags & 0x4000) + { + // Use 3DES for rd data + return E_NOTIMPL; + } + + if (cert) + { + return E_NOTIMPL; + } + else + { + if ((flags & 1) == 0) + return E_NOTIMPL; + } + + UInt32 rdSize = GetUi16a(p + 8); + + if (rdSize + 16 > _remSize) + return E_NOTIMPL; + + const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd + + /* + if (cert) + { + if ((rdSize & 0x7) != 0) + return E_NOTIMPL; + } + else + */ + { + // PKCS7 padding + if (rdSize < kPadSize) + return E_NOTIMPL; + if (rdSize & (kPadSize - 1)) + return E_NOTIMPL; + } + + memmove(p, p + 10, rdSize); + const Byte *p2 = p + rdSize + 10; + UInt32 reserved = GetUi32(p2); + p2 += 4; + + /* + if (cert) + { + UInt32 numRecipients = reserved; + + if (numRecipients == 0) + return E_NOTIMPL; + + { + UInt32 hashAlg = GetUi16(p2); + hashAlg = hashAlg; + UInt32 hashSize = GetUi16(p2 + 2); + hashSize = hashSize; + p2 += 4; + + reserved = reserved; + // return E_NOTIMPL; + + for (unsigned r = 0; r < numRecipients; r++) + { + UInt32 specSize = GetUi16(p2); + p2 += 2; + p2 += specSize; + } + } + } + else + */ + { + if (reserved != 0) + return E_NOTIMPL; + } + + UInt32 validSize = GetUi16(p2); + p2 += 2; + const size_t validOffset = (size_t)(p2 - p); + if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize) + return E_NOTIMPL; + + { + RINOK(_cbcDecoder->SetKey(_key.MasterKey, _key.KeySize)) + RINOK(_cbcDecoder->SetInitVector(_iv, 16)) + // SetInitVector() calls also Init() + RINOK(_cbcDecoder->Init()) // it's optional + Filter(p, rdSize); + + rdSize -= kPadSize; + for (unsigned i = 0; i < kPadSize; i++) + if (p[(size_t)rdSize + i] != kPadSize) + return S_OK; // passwOK = false; + } + + MY_ALIGN (16) + Byte fileKey[32]; + MY_ALIGN (16) + NSha1::CContext sha; + sha.Init(); + sha.Update(_iv, _ivSize); + sha.Update(p, rdSize); + DeriveKey(sha, fileKey); + + RINOK(_cbcDecoder->SetKey(fileKey, _key.KeySize)) + RINOK(_cbcDecoder->SetInitVector(_iv, 16)) + // SetInitVector() calls also Init() + RINOK(_cbcDecoder->Init()) // it's optional + + memmove(p, p + validOffset, validSize); + Filter(p, validSize); + + if (validSize < 4) + return E_NOTIMPL; + validSize -= 4; + if (GetUi32(p + validSize) != CrcCalc(p, validSize)) + return S_OK; + passwOK = true; + return S_OK; +} + +}} diff -Nru p7zip-rar-16.02/CPP/7zip/Crypto/ZipStrong.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.h --- p7zip-rar-16.02/CPP/7zip/Crypto/ZipStrong.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Crypto/ZipStrong.h 2023-04-02 11:00:00.000000000 +0000 @@ -1,58 +1,73 @@ -// Crypto/ZipStrong.h - -#ifndef __CRYPTO_ZIP_STRONG_H -#define __CRYPTO_ZIP_STRONG_H - -#include "../../Common/MyBuffer.h" - -#include "../IPassword.h" - -#include "MyAes.h" - -namespace NCrypto { -namespace NZipStrong { - -/* ICompressFilter::Init() does nothing for this filter. - Call to init: - Decoder: - [CryptoSetPassword();] - ReadHeader(); - [CryptoSetPassword();] Init_and_CheckPassword(); - [CryptoSetPassword();] Init_and_CheckPassword(); -*/ - -struct CKeyInfo -{ - Byte MasterKey[32]; - UInt32 KeySize; - - void SetPassword(const Byte *data, UInt32 size); -}; - -class CBaseCoder: - public CAesCbcDecoder, - public ICryptoSetPassword -{ -protected: - CKeyInfo _key; - CByteBuffer _buf; - Byte *_bufAligned; -public: - STDMETHOD(Init)(); - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size); -}; - -class CDecoder: public CBaseCoder -{ - UInt32 _ivSize; - Byte _iv[16]; - UInt32 _remSize; -public: - MY_UNKNOWN_IMP1(ICryptoSetPassword) - HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize); - HRESULT Init_and_CheckPassword(bool &passwOK); -}; - -}} - -#endif +// Crypto/ZipStrong.h + +#ifndef ZIP7_INC_CRYPTO_ZIP_STRONG_H +#define ZIP7_INC_CRYPTO_ZIP_STRONG_H + +#include "../../Common/MyBuffer2.h" + +#include "../IPassword.h" + +#include "MyAes.h" + +namespace NCrypto { +namespace NZipStrong { + +/* ICompressFilter::Init() does nothing for this filter. + Call to init: + Decoder: + [CryptoSetPassword();] + ReadHeader(); + [CryptoSetPassword();] Init_and_CheckPassword(); + [CryptoSetPassword();] Init_and_CheckPassword(); +*/ + +struct CKeyInfo +{ + Byte MasterKey[32]; + UInt32 KeySize; + + void SetPassword(const Byte *data, UInt32 size); + + void Wipe() + { + Z7_memset_0_ARRAY(MasterKey); + } +}; + + +const unsigned kAesPadAllign = AES_BLOCK_SIZE; + +Z7_CLASS_IMP_COM_2( + CDecoder + , ICompressFilter + , ICryptoSetPassword +) + CAesCbcDecoder *_cbcDecoder; + CMyComPtr _aesFilter; + CKeyInfo _key; + CAlignedBuffer _bufAligned; + + UInt32 _ivSize; + Byte _iv[16]; + UInt32 _remSize; +public: + HRESULT ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize); + HRESULT Init_and_CheckPassword(bool &passwOK); + UInt32 GetPadSize(UInt32 packSize32) const + { + // Padding is to align to blockSize of cipher. + // Change it, if is not AES + return kAesPadAllign - (packSize32 & (kAesPadAllign - 1)); + } + CDecoder(); + ~CDecoder() { Wipe(); } + void Wipe() + { + Z7_memset_0_ARRAY(_iv); + _key.Wipe(); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/GuiCommon.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/GuiCommon.rc --- p7zip-rar-16.02/CPP/7zip/GuiCommon.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/GuiCommon.rc 2024-11-13 18:00:00.000000000 +0000 @@ -0,0 +1,119 @@ +#include + +// #include +// #include + +// for Windows CE: +#include + + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#undef m +#undef bxs +#undef bys +#undef bxsDots +#undef y +#undef xc +#undef yc +#undef xs +#undef ys +#undef bx +#undef bx1 +#undef bx2 +#undef bx3 +#undef by +#undef by1 +#undef by2 +#undef by3 +#undef gSpace +#undef gSize +#undef marg2 +#undef marg3 + +#undef MY_DIALOG +#undef MY_RESIZE_DIALOG +#undef MY_PAGE + +#define m 8 +#define bxs 64 +#define bys 16 +#define bxsDots 20 + +#define xs (xc + m + m) +#define ys (yc + m + m) + +#define bx1 (xs - m - bxs) +#define bx2 (bx1 - m - bxs) +#define bx3 (bx2 - m - bxs) +#define bx bx1 + +#define by1 (ys - m - bys) +#define by2 (by1 - m - bys) +#define by by1 + + +#define MY_MODAL_DIALOG_STYLE STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +#define MY_MODAL_RESIZE_DIALOG_STYLE MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX | WS_THICKFRAME + +#define MY_PAGE_STYLE STYLE WS_CHILD | WS_DISABLED | WS_CAPTION + +#define MY_FONT FONT 8, "MS Shell Dlg" + +#define MY_MODAL_DIALOG_POSTFIX 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT + +#define SMALL_PAGE_SIZE_X 120 + +// #define MY_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +// #define MY_RESIZE_DIALOG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +#define MY_PAGE_POSTFIX 0, 0, xs, ys MY_PAGE_STYLE MY_FONT +#define MY_PAGE DIALOG MY_PAGE_POSTFIX + +#define OK_CANCEL \ + DEFPUSHBUTTON "OK", IDOK, bx2, by, bxs, bys \ + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + +#define CONTINUE_CANCEL \ + DEFPUSHBUTTON "Continue",IDCONTINUE, bx2, by, bxs, bys \ + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + +#define MY_BUTTON__CLOSE \ + DEFPUSHBUTTON "&Close", IDCLOSE, bx1, by, bxs, bys + + +#define MY_COMBO CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +#define MY_COMBO_SORTED MY_COMBO | CBS_SORT +#define MY_COMBO_WITH_EDIT CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + +#define MY_CHECKBOX "Button", BS_AUTOCHECKBOX | WS_TABSTOP + +#define cboxColonSize 18 +#define colonString ":" + +#define MY_CONTROL_CHECKBOX(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_CHECKBOX, _x,_y,_xsize,10 +#define MY_CONTROL_CHECKBOX_2LINES(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_CHECKBOX | BS_MULTILINE, _x,_y,_xsize,16 +#define MY_CONTROL_CHECKBOX_COLON(_id,_x,_y) MY_CONTROL_CHECKBOX( colonString, _id, _x,_y,cboxColonSize) + +#define MY_AUTORADIOBUTTON "Button", BS_AUTORADIOBUTTON +#define MY_AUTORADIOBUTTON_GROUP MY_AUTORADIOBUTTON | WS_GROUP + +#define MY_CONTROL_AUTORADIOBUTTON(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_AUTORADIOBUTTON, _x,_y,_xsize,10 +#define MY_CONTROL_AUTORADIOBUTTON_GROUP(_text,_id,_x,_y,_xsize) CONTROL _text, _id, MY_AUTORADIOBUTTON_GROUP, _x,_y,_xsize,10 + +#define MY_TEXT_NOPREFIX 8, SS_NOPREFIX + + +// WS_EX_CLIENTEDGE +#define MY_CONTROL_EDIT_WITH_SPIN(_id_edit, _id_spin, _text, _x, _y, _xSize) \ + EDITTEXT _id_edit, _x, _y, _xSize, 12, ES_CENTER | ES_NUMBER | ES_AUTOHSCROLL \ + CONTROL _text, _id_spin, L"msctls_updown32", \ + UDS_SETBUDDYINT \ + | UDS_ALIGNRIGHT \ + | UDS_AUTOBUDDY \ + | UDS_ARROWKEYS \ + | UDS_NOTHOUSANDS, \ + _x + _xSize, _y, 8, 12 // these values are unused + + +#define OPTIONS_PAGE_XC_SIZE 300 +#define OPTIONS_PAGE_YC_SIZE 280 diff -Nru p7zip-rar-16.02/CPP/7zip/Guid.txt p7zip-rar-16.02+really25.00+ds/CPP/7zip/Guid.txt --- p7zip-rar-16.02/CPP/7zip/Guid.txt 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Guid.txt 2024-10-18 08:00:00.000000000 +0000 @@ -1,216 +1,243 @@ -{23170F69-40C1-278A-0000-00yy00xx0000} - -00 IProgress.h - - 05 IProgress - // 050002 IProgress2 - -01 IFolderArchive.h - - // 05 IArchiveFolder // old - // 06 IInFolderArchive // old - 07 IFileExtractCallback.h::IFolderArchiveExtractCallback - 08 IFileExtractCallback.h::IFolderArchiveExtractCallback2 - // 0A IOutFolderArchive - 0B IFolderArchiveUpdateCallback - 0C Agent.h::IArchiveFolderInternal - 0D IArchiveFolder - 0E IInFolderArchive - 0F IOutFolderArchive - 10 IFolderArchiveUpdateCallback2 - 11 IFolderScanProgress - - 20 IFileExtractCallback.h::IGetProp - 30 IFileExtractCallback.h::IFolderExtractToStreamCallback - -03 IStream.h - - 01 ISequentialInStream - 02 ISequentialOutStream - 03 IInStream - 04 IOutStream - 06 IStreamGetSize - 07 IOutStreamFinish - 08 IStreamGetProps - 09 IStreamGetProps2 - - -04 ICoder.h - - 04 ICompressProgressInfo - 05 ICompressCoder - 18 ICompressCoder2 - 20 ICompressSetCoderProperties - 21 ICompressSetDecoderProperties // - 22 ICompressSetDecoderProperties2 - 23 ICompressWriteCoderProperties - 24 ICompressGetInStreamProcessedSize - 25 ICompressSetCoderMt - 26 ICompressSetFinishMode - - 30 ICompressGetSubStreamSize - 31 ICompressSetInStream - 32 ICompressSetOutStream -// 33 ICompressSetInStreamSize - 34 ICompressSetOutStreamSize - 35 ICompressSetBufSize - 36 ICompressInitEncoder - 37 ICompressSetInStream2 -// 38 ICompressSetOutStream2 -// 39 SetInStreamSize2 -// 3A SetOutStreamSize2 - - 40 ICompressFilter - 60 ICompressCodecsInfo - 61 ISetCompressCodecsInfo - 80 ICryptoProperties - 88 ICryptoResetSalt - 8C ICryptoResetInitVector - 90 ICryptoSetPassword - A0 ICryptoSetCRC - C0 IHasher - C1 IHashers - - -05 IPassword.h - - 10 ICryptoGetTextPassword - 11 ICryptoGetTextPassword2 - - -06 IArchive.h - - 03 ISetProperties - 04 IArchiveKeepModeForNextOpen - 05 IArchiveAllowTail - - 10 IArchiveOpenCallback - - 20 IArchiveExtractCallback - 21 IArchiveExtractCallbackMessage - - 30 IArchiveOpenVolumeCallback - 40 IInArchiveGetStream - 50 IArchiveOpenSetSubArchiveName - 60 IInArchive - 61 IArchiveOpenSeq - 70 IArchiveGetRawProps - 71 IArchiveGetRootProps - - 80 IArchiveUpdateCallback - 82 IArchiveUpdateCallback2 - 83 IArchiveUpdateCallbackFile - - A0 IOutArchive - - - -08 IFolder.h - - 00 IFolderFolder - 01 IEnumProperties - 02 IFolderGetTypeID - 03 IFolderGetPath - 04 IFolderWasChanged - 05 // IFolderReload - 06 // IFolderOperations old - 07 IFolderGetSystemIconIndex - 08 IFolderGetItemFullSize - 09 IFolderClone - 0A IFolderSetFlatMode - 0B IFolderOperationsExtractCallback - 0C // - 0D // - 0E IFolderProperties - 0F - 10 IFolderArcProps - 11 IGetFolderArcProps - 12 // IFolderOperations - 13 IFolderOperations - 14 IFolderCalcItemFullSize - 15 IFolderCompare - 16 IFolderGetItemName - 17 IFolderAltStreams - - -09 IFolder.h :: FOLDER_MANAGER_INTERFACE - - 00 - 04 // old IFolderManager - 05 IFolderManager - - -// 0A PluginInterface.h - 00 IInitContextMenu - 01 IPluginOptionsCallback - 02 IPluginOptions - - -Handler GUIDs: - -{23170F69-40C1-278A-1000-000110xx0000} - - 01 Zip - 02 BZip2 - 03 Rar - 04 Arj - 05 Z - 06 Lzh - 07 7z - 08 Cab - 09 Nsis - 0A lzma - 0B lzma86 - 0C xz - 0D ppmd - - C7 Ext - C8 VMDK - C9 VDI - CA Qcow - CB GPT - CC Rar5 - CD IHex - CE Hxs - CF TE - D0 UEFIc - D1 UEFIs - D2 SquashFS - D3 CramFS - D4 APM - D5 Mslz - D6 Flv - D7 Swf - D8 Swfc - D9 Ntfs - DA Fat - DB Mbr - DC Vhd - DD Pe - DE Elf - DF Mach-O - E0 Udf - E1 Xar - E2 Mub - E3 Hfs - E4 Dmg - E5 Compound - E6 Wim - E7 Iso - E8 - E9 Chm - EA Split - EB Rpm - EC Deb - ED Cpio - EE Tar - EF GZip - -{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu - -// {23170F69-40C1-278A-1000-000100030000} // CAgentArchiveHandler -// {23170F69-40C1-278B- old codecs clsids -// {23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions - -{23170F69-40C1-2790-id} Codec Decoders -{23170F69-40C1-2791-id} Codec Encoders -{23170F69-40C1-2792-id} Hashers +{23170F69-40C1-278A-0000-00yy00xx0000} + +00 IProgress.h + + 05 IProgress + // 050002 IProgress2 + +01 IFolderArchive.h + + // 05 IArchiveFolder // old + // 06 IInFolderArchive // old + 07 IFileExtractCallback.h::IFolderArchiveExtractCallback + 08 IFileExtractCallback.h::IFolderArchiveExtractCallback2 + // 0A IOutFolderArchive + 0B IFolderArchiveUpdateCallback + 0C Agent.h::IArchiveFolderInternal + 0D IArchiveFolder + 0E IInFolderArchive + 0F IOutFolderArchive + 10 IFolderArchiveUpdateCallback2 + 11 IFolderScanProgress + 12 IFolderSetZoneIdMode + 13 IFolderSetZoneIdFile + 14 IFolderArchiveUpdateCallback_MoveArc + + 20 IFileExtractCallback.h::IGetProp + 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old) + 31 IFileExtractCallback.h::IFolderExtractToStreamCallback (new 21.04) + +03 IStream.h + + 01 ISequentialInStream + 02 ISequentialOutStream + 03 IInStream + 04 IOutStream + + 06 IStreamGetSize + 07 IOutStreamFinish + 08 IStreamGetProps + 09 IStreamGetProps2 + 0A IStreamGetProp + + 10 IStreamSetRestriction + + +04 ICoder.h + + 04 ICompressProgressInfo + 05 ICompressCoder + 18 ICompressCoder2 + 1F ICompressSetCoderPropertiesOpt + 20 ICompressSetCoderProperties + 21 ICompressSetDecoderProperties // + 22 ICompressSetDecoderProperties2 + 23 ICompressWriteCoderProperties + 24 ICompressGetInStreamProcessedSize + 25 ICompressSetCoderMt + 26 ICompressSetFinishMode + 27 ICompressGetInStreamProcessedSize2 + 28 ICompressSetMemLimit + 29 ICompressReadUnusedFromInBuf + + 30 ICompressGetSubStreamSize + 31 ICompressSetInStream + 32 ICompressSetOutStream +// 33 ICompressSetInStreamSize + 34 ICompressSetOutStreamSize + 35 ICompressSetBufSize + 36 ICompressInitEncoder + 37 ICompressSetInStream2 +// 38 ICompressSetOutStream2 +// 39 SetInStreamSize2 +// 3A SetOutStreamSize2 + + 40 ICompressFilter + 60 ICompressCodecsInfo + 61 ISetCompressCodecsInfo + 80 ICryptoProperties + 88 ICryptoResetSalt + 8C ICryptoResetInitVector + 90 ICryptoSetPassword + A0 ICryptoSetCRC + C0 IHasher + C1 IHashers + + +05 IPassword.h + + 10 ICryptoGetTextPassword + 11 ICryptoGetTextPassword2 + + +06 IArchive.h + + 03 ISetProperties + 04 IArchiveKeepModeForNextOpen + 05 IArchiveAllowTail + + 09 IArchiveRequestMemoryUseCallback + + 10 IArchiveOpenCallback + + 20 IArchiveExtractCallback + 21 IArchiveExtractCallbackMessage (deprecated in v23) + 22 IArchiveExtractCallbackMessage2 (new in v23) + + 30 IArchiveOpenVolumeCallback + 40 IInArchiveGetStream + 50 IArchiveOpenSetSubArchiveName + 60 IInArchive + 61 IArchiveOpenSeq + 70 IArchiveGetRawProps + 71 IArchiveGetRootProps + + 80 IArchiveUpdateCallback + 82 IArchiveUpdateCallback2 + 83 IArchiveUpdateCallbackFile + 84 IArchiveGetDiskProperty + 85 IArchiveUpdateCallbackArcProp (Reserved) + + + A0 IOutArchive + + + +08 IFolder.h + + 00 IFolderFolder + 01 IEnumProperties + 02 IFolderGetTypeID + 03 IFolderGetPath + 04 IFolderWasChanged + 05 // IFolderReload + 06 // IFolderOperations old + 07 IFolderGetSystemIconIndex + 08 IFolderGetItemFullSize + 09 IFolderClone + 0A IFolderSetFlatMode + 0B IFolderOperationsExtractCallback + 0C // + 0D // + 0E IFolderProperties + 0F + 10 IFolderArcProps + 11 IGetFolderArcProps + 12 // IFolderOperations + 13 IFolderOperations + 14 IFolderCalcItemFullSize + 15 IFolderCompare + 16 IFolderGetItemName + 17 IFolderAltStreams + + +09 IFolder.h :: FOLDER_MANAGER_INTERFACE + + 00 - 04 // old IFolderManager + 05 IFolderManager + + +// 0A PluginInterface.h + 00 IInitContextMenu + 01 IPluginOptionsCallback + 02 IPluginOptions + + +Handler GUIDs: + +{23170F69-40C1-278A-1000-000110xx0000} + + 01 Zip + 02 BZip2 + 03 Rar + 04 Arj + 05 Z + 06 Lzh + 07 7z + 08 Cab + 09 Nsis + 0A lzma + 0B lzma86 + 0C xz + 0D ppmd + 0E zstd + + BF LVM + C0 AVB + C1 LP + C2 Sparse + C3 APFS + C4 Vhdx + C5 Base64 + C6 COFF + C7 Ext + C8 VMDK + C9 VDI + CA Qcow + CB GPT + CC Rar5 + CD IHex + CE Hxs + CF TE + D0 UEFIc + D1 UEFIs + D2 SquashFS + D3 CramFS + D4 APM + D5 Mslz + D6 Flv + D7 Swf + D8 Swfc + D9 Ntfs + DA Fat + DB Mbr + DC Vhd + DD Pe + DE Elf + DF Mach-O + E0 Udf + E1 Xar + E2 Mub + E3 Hfs + E4 Dmg + E5 Compound + E6 Wim + E7 Iso + E8 + E9 Chm + EA Split + EB Rpm + EC Deb + ED Cpio + EE Tar + EF GZip + +{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu + +// {23170F69-40C1-278A-1000-000100030000} // CAgentArchiveHandler +// {23170F69-40C1-278B- old codecs clsids +// {23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions + +{23170F69-40C1-2790-id} Codec Decoders +{23170F69-40C1-2791-id} Codec Encoders +{23170F69-40C1-2792-id} Hashers diff -Nru p7zip-rar-16.02/CPP/7zip/ICoder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/ICoder.h --- p7zip-rar-16.02/CPP/7zip/ICoder.h 2015-06-20 06:51:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/ICoder.h 2024-12-14 19:00:00.000000000 +0000 @@ -1,371 +1,480 @@ -// ICoder.h - -#ifndef __ICODER_H -#define __ICODER_H - -#include "IStream.h" - -#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x) - -CODER_INTERFACE(ICompressProgressInfo, 0x04) -{ - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; - - /* (inSize) can be NULL, if unknown - (outSize) can be NULL, if unknown - - returns: - S_OK - E_ABORT : Break by user - another error codes - */ -}; - -CODER_INTERFACE(ICompressCoder, 0x05) -{ - STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) PURE; -}; - -CODER_INTERFACE(ICompressCoder2, 0x18) -{ - STDMETHOD(Code)(ISequentialInStream * const *inStreams, const UInt64 * const *inSizes, UInt32 numInStreams, - ISequentialOutStream * const *outStreams, const UInt64 * const *outSizes, UInt32 numOutStreams, - ICompressProgressInfo *progress) PURE; -}; - -/* - ICompressCoder::Code - ICompressCoder2::Code - - returns: - S_OK : OK - S_FALSE : data error (for decoders) - E_OUTOFMEMORY : memory allocation error - another error code : some error. For example, it can be error code received from inStream or outStream function. - - Parameters: - (inStream != NULL) - (outStream != NULL) - - if (inSize != NULL) - { - Encoders in 7-Zip ignore (inSize). - Decoder can use (*inSize) to check that stream was decoded correctly. - Some decoder in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) - } - - If it's required to limit the reading from input stream (inStream), it can - be done with ISequentialInStream implementation. - - if (outSize != NULL) - { - Encoders in 7-Zip ignore (outSize). - Decoder unpacks no more than (*outSize) bytes. - } - - (progress == NULL) is allowed. - - - Decoding with Code() function - ----------------------------- - - You can request some interfaces before decoding - - ICompressSetDecoderProperties2 - - ICompressSetFinishMode - - If you need to decode full stream: - { - 1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1); - 2) call the Code() function with specified (inSize) and (outSize), if these sizes are known. - } - - If you need to decode only part of stream: - { - 1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0); - 2) Call the Code() function with specified (inSize = NULL) and specified (outSize). - } - - Encoding with Code() function - ----------------------------- - - You can request some interfaces : - - ICompressSetCoderProperties - use it before encoding to set properties - - ICompressWriteCoderProperties - use it before or after encoding to request encoded properties. - - ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1) - The rules are similar to ICompressCoder rules -*/ - - -namespace NCoderPropID -{ - enum EEnum - { - kDefaultProp = 0, - kDictionarySize, - kUsedMemorySize, - kOrder, - kBlockSize, - kPosStateBits, - kLitContextBits, - kLitPosBits, - kNumFastBytes, - kMatchFinder, - kMatchFinderCycles, - kNumPasses, - kAlgorithm, - kNumThreads, - kEndMarker, - kLevel, - kReduceSize // estimated size of data that will be compressed. Encoder can use this value to reduce dictionary size. - }; -} - -CODER_INTERFACE(ICompressSetCoderProperties, 0x20) -{ - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) PURE; -}; - -/* -CODER_INTERFACE(ICompressSetCoderProperties, 0x21) -{ - STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; -}; -*/ - -CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) -{ - /* returns: - S_OK - E_NOTIMP : unsupported properties - E_INVALIDARG : incorrect (or unsupported) properties - E_OUTOFMEMORY : memory allocation error - */ - STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) -{ - STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream) PURE; -}; - -CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) -{ - STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; -}; - -CODER_INTERFACE(ICompressSetCoderMt, 0x25) -{ - STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE; -}; - -CODER_INTERFACE(ICompressSetFinishMode, 0x26) -{ - STDMETHOD(SetFinishMode)(UInt32 finishMode) PURE; - - /* finishMode: - 0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined. - 1 : full decoding. The stream must be finished at the end of decoding. */ -}; - - -CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) -{ - STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; - - /* returns: - S_OK : (*value) contains the size or estimated size (can be incorrect size) - S_FALSE : size is undefined - E_NOTIMP : the feature is not implemented - - Let's (read_size) is size of data that was already read by ISequentialInStream::Read(). - The caller should call GetSubStreamSize() after each Read() and check sizes: - if (start_of_subStream + *value < read_size) - { - // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream: - start_of_subStream += *value; - subStream++; - } - */ -}; - -CODER_INTERFACE(ICompressSetInStream, 0x31) -{ - STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream)() PURE; -}; - -CODER_INTERFACE(ICompressSetOutStream, 0x32) -{ - STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream)() PURE; -}; - -/* -CODER_INTERFACE(ICompressSetInStreamSize, 0x33) -{ - STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; -}; -*/ - -CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) -{ - STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; - - /* That function initializes decoder structures. - Call this function only for stream version of decoder. - if (outSize == NULL), then output size is unknown - if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */ -}; - -CODER_INTERFACE(ICompressSetBufSize, 0x35) -{ - STDMETHOD(SetInBufSize)(UInt32 streamIndex, UInt32 size) PURE; - STDMETHOD(SetOutBufSize)(UInt32 streamIndex, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICompressInitEncoder, 0x36) -{ - STDMETHOD(InitEncoder)() PURE; - - /* That function initializes encoder structures. - Call this function only for stream version of encoder. */ -}; - -CODER_INTERFACE(ICompressSetInStream2, 0x37) -{ - STDMETHOD(SetInStream2)(UInt32 streamIndex, ISequentialInStream *inStream) PURE; - STDMETHOD(ReleaseInStream2)(UInt32 streamIndex) PURE; -}; - -/* -CODER_INTERFACE(ICompressSetOutStream2, 0x38) -{ - STDMETHOD(SetOutStream2)(UInt32 streamIndex, ISequentialOutStream *outStream) PURE; - STDMETHOD(ReleaseOutStream2)(UInt32 streamIndex) PURE; -}; - -CODER_INTERFACE(ICompressSetInStreamSize2, 0x39) -{ - STDMETHOD(SetInStreamSize2)(UInt32 streamIndex, const UInt64 *inSize) PURE; -}; -*/ - - -/* - ICompressFilter - Filter() converts as most as possible bytes - returns: (outSize): - if (outSize <= size) : Filter have converted outSize bytes - if (outSize > size) : Filter have not converted anything. - and it needs at least outSize bytes to convert one block - (it's for crypto block algorithms). -*/ - -#define INTERFACE_ICompressFilter(x) \ - STDMETHOD(Init)() x; \ - STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) x; \ - -CODER_INTERFACE(ICompressFilter, 0x40) -{ - INTERFACE_ICompressFilter(PURE); -}; - - -CODER_INTERFACE(ICompressCodecsInfo, 0x60) -{ - STDMETHOD(GetNumMethods)(UInt32 *numMethods) PURE; - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE; - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE; -}; - -CODER_INTERFACE(ISetCompressCodecsInfo, 0x61) -{ - STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE; -}; - -CODER_INTERFACE(ICryptoProperties, 0x80) -{ - STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; - STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; -}; - -/* -CODER_INTERFACE(ICryptoResetSalt, 0x88) -{ - STDMETHOD(ResetSalt)() PURE; -}; -*/ - -CODER_INTERFACE(ICryptoResetInitVector, 0x8C) -{ - STDMETHOD(ResetInitVector)() PURE; - - /* Call ResetInitVector() only for encoding. - Call ResetInitVector() before encoding and before WriteCoderProperties(). - Crypto encoder can create random IV in that function. */ -}; - -CODER_INTERFACE(ICryptoSetPassword, 0x90) -{ - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; -}; - -CODER_INTERFACE(ICryptoSetCRC, 0xA0) -{ - STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; -}; - - -namespace NMethodPropID -{ - enum EEnum - { - kID, - kName, - kDecoder, - kEncoder, - kPackStreams, - kUnpackStreams, - kDescription, - kDecoderIsAssigned, - kEncoderIsAssigned, - kDigestSize - }; -} - - -#define INTERFACE_IHasher(x) \ - STDMETHOD_(void, Init)() throw() x; \ - STDMETHOD_(void, Update)(const void *data, UInt32 size) throw() x; \ - STDMETHOD_(void, Final)(Byte *digest) throw() x; \ - STDMETHOD_(UInt32, GetDigestSize)() throw() x; \ - -CODER_INTERFACE(IHasher, 0xC0) -{ - INTERFACE_IHasher(PURE) -}; - -CODER_INTERFACE(IHashers, 0xC1) -{ - STDMETHOD_(UInt32, GetNumHashers)() PURE; - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher) PURE; -}; - -extern "C" -{ - typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods); - typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject); - typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject); - - typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers); - - typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo); -} - -#endif +// ICoder.h + +#ifndef ZIP7_INC_ICODER_H +#define ZIP7_INC_ICODER_H + +#include "IStream.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_CODER(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 4, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACEM_ICompressProgressInfo(x) \ + x(SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressProgressInfo, 0x04) + /* + SetRatioInfo() + (inSize) can be NULL, if unknown + (outSize) can be NULL, if unknown + returns: + S_OK + E_ABORT : Break by user + another error codes + */ + +#define Z7_IFACEM_ICompressCoder(x) \ + x(Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, \ + const UInt64 *inSize, const UInt64 *outSize, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder, 0x05) + +#define Z7_IFACEM_ICompressCoder2(x) \ + x(Code(ISequentialInStream * const *inStreams, const UInt64 *const *inSizes, UInt32 numInStreams, \ + ISequentialOutStream *const *outStreams, const UInt64 *const *outSizes, UInt32 numOutStreams, \ + ICompressProgressInfo *progress)) +Z7_IFACE_CONSTR_CODER(ICompressCoder2, 0x18) + +/* + ICompressCoder::Code + ICompressCoder2::Code + + returns: + S_OK : OK + S_FALSE : data error (for decoders) + E_OUTOFMEMORY : memory allocation error + E_NOTIMPL : unsupported encoding method (for decoders) + another error code : some error. For example, it can be error code received from inStream or outStream function. + + Parameters: + (inStream != NULL) + (outStream != NULL) + + if (inSize != NULL) + { + Encoders in 7-Zip ignore (inSize). + Decoder can use (*inSize) to check that stream was decoded correctly. + Some decoders in 7-Zip check it, if (full_decoding mode was set via ICompressSetFinishMode) + } + + If it's required to limit the reading from input stream (inStream), it can + be done with ISequentialInStream implementation. + + if (outSize != NULL) + { + Encoders in 7-Zip ignore (outSize). + Decoder unpacks no more than (*outSize) bytes. + } + + (progress == NULL) is allowed. + + + Decoding with Code() function + ----------------------------- + + You can request some interfaces before decoding + - ICompressSetDecoderProperties2 + - ICompressSetFinishMode + + If you need to decode full stream: + { + 1) try to set full_decoding mode with ICompressSetFinishMode::SetFinishMode(1); + 2) call the Code() function with specified (inSize) and (outSize), if these sizes are known. + } + + If you need to decode only part of stream: + { + 1) try to set partial_decoding mode with ICompressSetFinishMode::SetFinishMode(0); + 2) Call the Code() function with specified (inSize = NULL) and specified (outSize). + } + + Encoding with Code() function + ----------------------------- + + You can request some interfaces : + - ICompressSetCoderProperties - use it before encoding to set properties + - ICompressWriteCoderProperties - use it before or after encoding to request encoded properties. + + ICompressCoder2 is used when (numInStreams != 1 || numOutStreams != 1) + The rules are similar to ICompressCoder rules +*/ + + +namespace NCoderPropID +{ + enum EEnum + { + kDefaultProp = 0, + kDictionarySize, // VT_UI4 + kUsedMemorySize, // VT_UI4 + kOrder, // VT_UI4 + kBlockSize, // VT_UI4 or VT_UI8 + kPosStateBits, // VT_UI4 + kLitContextBits, // VT_UI4 + kLitPosBits, // VT_UI4 + kNumFastBytes, // VT_UI4 + kMatchFinder, // VT_BSTR + kMatchFinderCycles, // VT_UI4 + kNumPasses, // VT_UI4 + kAlgorithm, // VT_UI4 + kNumThreads, // VT_UI4 + kEndMarker, // VT_BOOL + kLevel, // VT_UI4 + kReduceSize, // VT_UI8 : it's estimated size of largest data stream that will be compressed + // encoder can use this value to reduce dictionary size and allocate data buffers + + kExpectedDataSize, // VT_UI8 : for ICompressSetCoderPropertiesOpt : + // it's estimated size of current data stream + // real data size can differ from that size + // encoder can use this value to optimize encoder initialization + + kBlockSize2, // VT_UI4 or VT_UI8 + kCheckSize, // VT_UI4 : size of digest in bytes + kFilter, // VT_BSTR + kMemUse, // VT_UI8 + kAffinity, // VT_UI8 + kBranchOffset, // VT_UI4 + kHashBits, // VT_UI4 + kNumThreadGroups, // VT_UI4 + kThreadGroup, // VT_UI4 + kAffinityInGroup, // VT_UI8 + /* + // kHash3Bits, // VT_UI4 + // kHash2Bits, // VT_UI4 + // kChainBits, // VT_UI4 + kChainSize, // VT_UI4 + kNativeLevel, // VT_UI4 + kFast, // VT_UI4 + kMinMatch, // VT_UI4 The minimum slen is 3 and the maximum is 7. + kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6) + kRowMatchFinder, // VT_BOOL + kLdmEnable, // VT_BOOL + // kLdmWindowSizeLog, // VT_UI4 + kLdmWindowSize, // VT_UI4 + kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20). + kLdmMinMatchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64). + kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3). + kLdmHashRateLog, // VT_UI4 The default value is wlog - ldmhlog. + kWriteUnpackSizeFlag, // VT_BOOL + kUsePledged, // VT_BOOL + kUseSizeHintPledgedForSmall, // VT_BOOL + kUseSizeHintForEach, // VT_BOOL + kUseSizeHintGlobal, // VT_BOOL + kParamSelectMode, // VT_UI4 + // kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26 + // kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999. + */ + k_NUM_DEFINED + }; +} + +#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \ + x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F) + + +#define Z7_IFACEM_ICompressSetCoderProperties(x) \ + x(SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderProperties, 0x20) + +/* +#define Z7_IFACEM_ICompressSetDecoderProperties(x) \ + x(SetDecoderProperties(ISequentialInStream *inStream)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties, 0x21) +*/ + +#define Z7_IFACEM_ICompressSetDecoderProperties2(x) \ + x(SetDecoderProperties2(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressSetDecoderProperties2, 0x22) + /* returns: + S_OK + E_NOTIMP : unsupported properties + E_INVALIDARG : incorrect (or unsupported) properties + E_OUTOFMEMORY : memory allocation error + */ + + +#define Z7_IFACEM_ICompressWriteCoderProperties(x) \ + x(WriteCoderProperties(ISequentialOutStream *outStream)) +Z7_IFACE_CONSTR_CODER(ICompressWriteCoderProperties, 0x23) + +#define Z7_IFACEM_ICompressGetInStreamProcessedSize(x) \ + x(GetInStreamProcessedSize(UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize, 0x24) + +#define Z7_IFACEM_ICompressSetCoderMt(x) \ + x(SetNumberOfThreads(UInt32 numThreads)) +Z7_IFACE_CONSTR_CODER(ICompressSetCoderMt, 0x25) + +#define Z7_IFACEM_ICompressSetFinishMode(x) \ + x(SetFinishMode(UInt32 finishMode)) +Z7_IFACE_CONSTR_CODER(ICompressSetFinishMode, 0x26) + /* finishMode: + 0 : partial decoding is allowed. It's default mode for ICompressCoder::Code(), if (outSize) is defined. + 1 : full decoding. The stream must be finished at the end of decoding. */ + +#define Z7_IFACEM_ICompressGetInStreamProcessedSize2(x) \ + x(GetInStreamProcessedSize2(UInt32 streamIndex, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetInStreamProcessedSize2, 0x27) + +#define Z7_IFACEM_ICompressSetMemLimit(x) \ + x(SetMemLimit(UInt64 memUsage)) +Z7_IFACE_CONSTR_CODER(ICompressSetMemLimit, 0x28) + + +/* + ICompressReadUnusedFromInBuf is supported by ICoder object + call ReadUnusedFromInBuf() after ICoder::Code(inStream, ...). + ICoder::Code(inStream, ...) decodes data, and the ICoder object is allowed + to read from inStream to internal buffers more data than minimal data required for decoding. + So we can call ReadUnusedFromInBuf() from same ICoder object to read unused input + data from the internal buffer. + in ReadUnusedFromInBuf(): the Coder is not allowed to use (ISequentialInStream *inStream) object, that was sent to ICoder::Code(). +*/ +#define Z7_IFACEM_ICompressReadUnusedFromInBuf(x) \ + x(ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_CODER(ICompressReadUnusedFromInBuf, 0x29) + + +#define Z7_IFACEM_ICompressGetSubStreamSize(x) \ + x(GetSubStreamSize(UInt64 subStream, UInt64 *value)) +Z7_IFACE_CONSTR_CODER(ICompressGetSubStreamSize, 0x30) + /* returns: + S_OK : (*value) contains the size or estimated size (can be incorrect size) + S_FALSE : size is undefined + E_NOTIMP : the feature is not implemented + Let's (read_size) is size of data that was already read by ISequentialInStream::Read(). + The caller should call GetSubStreamSize() after each Read() and check sizes: + if (start_of_subStream + *value < read_size) + { + // (*value) is correct, and it's allowed to call GetSubStreamSize() for next subStream: + start_of_subStream += *value; + subStream++; + } + */ + +#define Z7_IFACEM_ICompressSetInStream(x) \ + x(SetInStream(ISequentialInStream *inStream)) \ + x(ReleaseInStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream, 0x31) + +#define Z7_IFACEM_ICompressSetOutStream(x) \ + x(SetOutStream(ISequentialOutStream *outStream)) \ + x(ReleaseOutStream()) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream, 0x32) + +/* +#define Z7_IFACEM_ICompressSetInStreamSize(x) \ + x(SetInStreamSize(const UInt64 *inSize)) \ +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize, 0x33) +*/ + +#define Z7_IFACEM_ICompressSetOutStreamSize(x) \ + x(SetOutStreamSize(const UInt64 *outSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStreamSize, 0x34) + /* That function initializes decoder structures. + Call this function only for stream version of decoder. + if (outSize == NULL), then output size is unknown + if (outSize != NULL), then the decoder must stop decoding after (*outSize) bytes. */ + +#define Z7_IFACEM_ICompressSetBufSize(x) \ + x(SetInBufSize(UInt32 streamIndex, UInt32 size)) \ + x(SetOutBufSize(UInt32 streamIndex, UInt32 size)) + +Z7_IFACE_CONSTR_CODER(ICompressSetBufSize, 0x35) + +#define Z7_IFACEM_ICompressInitEncoder(x) \ + x(InitEncoder()) +Z7_IFACE_CONSTR_CODER(ICompressInitEncoder, 0x36) + /* That function initializes encoder structures. + Call this function only for stream version of encoder. */ + +#define Z7_IFACEM_ICompressSetInStream2(x) \ + x(SetInStream2(UInt32 streamIndex, ISequentialInStream *inStream)) \ + x(ReleaseInStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStream2, 0x37) + +/* +#define Z7_IFACEM_ICompressSetOutStream2(x) \ + x(SetOutStream2(UInt32 streamIndex, ISequentialOutStream *outStream)) + x(ReleaseOutStream2(UInt32 streamIndex)) +Z7_IFACE_CONSTR_CODER(ICompressSetOutStream2, 0x38) + +#define Z7_IFACEM_ICompressSetInStreamSize2(x) \ + x(SetInStreamSize2(UInt32 streamIndex, const UInt64 *inSize)) +Z7_IFACE_CONSTR_CODER(ICompressSetInStreamSize2, 0x39) +*/ + +/* +#define Z7_IFACEM_ICompressInSubStreams(x) \ + x(GetNextInSubStream(UInt64 *streamIndexRes, ISequentialInStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressInSubStreams, 0x3A) + +#define Z7_IFACEM_ICompressOutSubStreams(x) \ + x(GetNextOutSubStream(UInt64 *streamIndexRes, ISequentialOutStream **stream)) +Z7_IFACE_CONSTR_CODER(ICompressOutSubStreams, 0x3B) +*/ + +/* + ICompressFilter + Filter(Byte *data, UInt32 size) + (size) + converts as most as possible bytes required for fast processing. + Some filters have (smallest_fast_block). + For example, (smallest_fast_block == 16) for AES CBC/CTR filters. + If data stream is not finished, caller must call Filter() for larger block: + where (size >= smallest_fast_block). + if (size >= smallest_fast_block) + { + The filter can leave some bytes at the end of data without conversion: + if there are data alignment reasons or speed reasons. + The caller can read additional data from stream and call Filter() again. + } + If data stream was finished, caller can call Filter() for (size < smallest_fast_block) + + (data) parameter: + Some filters require alignment for any Filter() call: + 1) (stream_offset % alignment_size) == (data % alignment_size) + 2) (alignment_size == 2^N) + where (stream_offset) - is the number of bytes that were already filtered before. + The callers of Filter() are required to meet these requirements. + (alignment_size) can be different: + 16 : for AES filters + 4 or 2 : for some branch convert filters + 1 : for another filters + (alignment_size >= 16) is enough for all current filters of 7-Zip. + But the caller can use larger (alignment_size). + Recommended alignment for (data) of Filter() call is (alignment_size == 64). + Also it's recommended to use aligned value for (size): + (size % alignment_size == 0), + if it's not last call of Filter() for current stream. + + returns: (outSize): + if (outSize == 0) : Filter have not converted anything. + So the caller can stop processing, if data stream was finished. + if (outSize <= size) : Filter have converted outSize bytes + if (outSize > size) : Filter have not converted anything. + and it needs at least outSize bytes to convert one block + (it's for crypto block algorithms). +*/ + +#define Z7_IFACEM_ICompressFilter(x) \ + x(Init()) \ + x##2(UInt32, Filter(Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICompressFilter, 0x40) + + +#define Z7_IFACEM_ICompressCodecsInfo(x) \ + x(GetNumMethods(UInt32 *numMethods)) \ + x(GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateDecoder(UInt32 index, const GUID *iid, void* *coder)) \ + x(CreateEncoder(UInt32 index, const GUID *iid, void* *coder)) +Z7_IFACE_CONSTR_CODER(ICompressCodecsInfo, 0x60) + +#define Z7_IFACEM_ISetCompressCodecsInfo(x) \ + x(SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo)) +Z7_IFACE_CONSTR_CODER(ISetCompressCodecsInfo, 0x61) + +#define Z7_IFACEM_ICryptoProperties(x) \ + x(SetKey(const Byte *data, UInt32 size)) \ + x(SetInitVector(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoProperties, 0x80) + +/* + x(ResetSalt()) +Z7_IFACE_CONSTR_CODER(ICryptoResetSalt, 0x88) +*/ + +#define Z7_IFACEM_ICryptoResetInitVector(x) \ + x(ResetInitVector()) +Z7_IFACE_CONSTR_CODER(ICryptoResetInitVector, 0x8C) + /* Call ResetInitVector() only for encoding. + Call ResetInitVector() before encoding and before WriteCoderProperties(). + Crypto encoder can create random IV in that function. */ + +#define Z7_IFACEM_ICryptoSetPassword(x) \ + x(CryptoSetPassword(const Byte *data, UInt32 size)) +Z7_IFACE_CONSTR_CODER(ICryptoSetPassword, 0x90) + +#define Z7_IFACEM_ICryptoSetCRC(x) \ + x(CryptoSetCRC(UInt32 crc)) +Z7_IFACE_CONSTR_CODER(ICryptoSetCRC, 0xA0) + + +namespace NMethodPropID +{ + enum EEnum + { + kID, + kName, + kDecoder, + kEncoder, + kPackStreams, + kUnpackStreams, + kDescription, + kDecoderIsAssigned, + kEncoderIsAssigned, + kDigestSize, + kIsFilter + }; +} + +namespace NModuleInterfaceType +{ + /* + virtual destructor in IUnknown: + - no : 7-Zip (Windows) + - no : 7-Zip (Linux) (v23) in default mode + - yes : p7zip + - yes : 7-Zip (Linux) before v23 + - yes : 7-Zip (Linux) (v23), if Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN is defined + */ + const UInt32 k_IUnknown_VirtDestructor_No = 0; + const UInt32 k_IUnknown_VirtDestructor_Yes = 1; + const UInt32 k_IUnknown_VirtDestructor_ThisModule = + #if !defined(_WIN32) && defined(Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN) + k_IUnknown_VirtDestructor_Yes; + #else + k_IUnknown_VirtDestructor_No; + #endif +} + +namespace NModulePropID +{ + enum EEnum + { + kInterfaceType, // VT_UI4 + kVersion // VT_UI4 + }; +} + + +#define Z7_IFACEM_IHasher(x) \ + x##2(void, Init()) \ + x##2(void, Update(const void *data, UInt32 size)) \ + x##2(void, Final(Byte *digest)) \ + x##2(UInt32, GetDigestSize()) +Z7_IFACE_CONSTR_CODER(IHasher, 0xC0) + +#define Z7_IFACEM_IHashers(x) \ + x##2(UInt32, GetNumHashers()) \ + x(GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) \ + x(CreateHasher(UInt32 index, IHasher **hasher)) +Z7_IFACE_CONSTR_CODER(IHashers, 0xC1) + +extern "C" +{ + typedef HRESULT (WINAPI *Func_GetNumberOfMethods)(UInt32 *numMethods); + typedef HRESULT (WINAPI *Func_GetMethodProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + typedef HRESULT (WINAPI *Func_CreateDecoder)(UInt32 index, const GUID *iid, void **outObject); + typedef HRESULT (WINAPI *Func_CreateEncoder)(UInt32 index, const GUID *iid, void **outObject); + + typedef HRESULT (WINAPI *Func_GetHashers)(IHashers **hashers); + + typedef HRESULT (WINAPI *Func_SetCodecs)(ICompressCodecsInfo *compressCodecsInfo); + typedef HRESULT (WINAPI *Func_GetModuleProp)(PROPID propID, PROPVARIANT *value); +} + +Z7_PURE_INTERFACES_END +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/IDecl.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/IDecl.h --- p7zip-rar-16.02/CPP/7zip/IDecl.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/IDecl.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,28 +1,76 @@ -// IDecl.h - -#ifndef __IDECL_H -#define __IDECL_H - -#include "../Common/MyUnknown.h" - -#define k_7zip_GUID_Data1 0x23170F69 -#define k_7zip_GUID_Data2 0x40C1 - -#define k_7zip_GUID_Data3_Common 0x278A - -#define k_7zip_GUID_Data3_Decoder 0x2790 -#define k_7zip_GUID_Data3_Encoder 0x2791 -#define k_7zip_GUID_Data3_Hasher 0x2792 - - -#define DECL_INTERFACE_SUB(i, base, groupId, subId) \ - DEFINE_GUID(IID_ ## i, \ - k_7zip_GUID_Data1, \ - k_7zip_GUID_Data2, \ - k_7zip_GUID_Data3_Common, \ - 0, 0, 0, (groupId), 0, (subId), 0, 0); \ - struct i: public base - -#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId) - -#endif +// IDecl.h + +#ifndef ZIP7_INC_IDECL_H +#define ZIP7_INC_IDECL_H + +#include "../Common/Common0.h" +#include "../Common/MyUnknown.h" + +#define k_7zip_GUID_Data1 0x23170F69 +#define k_7zip_GUID_Data2 0x40C1 + +#define k_7zip_GUID_Data3_Common 0x278A + +#define k_7zip_GUID_Data3_Decoder 0x2790 +#define k_7zip_GUID_Data3_Encoder 0x2791 +#define k_7zip_GUID_Data3_Hasher 0x2792 + +#define Z7_DECL_IFACE_7ZIP_SUB(i, _base, groupId, subId) \ + Z7_DEFINE_GUID(IID_ ## i, \ + k_7zip_GUID_Data1, \ + k_7zip_GUID_Data2, \ + k_7zip_GUID_Data3_Common, \ + 0, 0, 0, (groupId), 0, (subId), 0, 0); \ + struct Z7_DECLSPEC_NOVTABLE i: public _base + +#define Z7_DECL_IFACE_7ZIP(i, groupId, subId) \ + Z7_DECL_IFACE_7ZIP_SUB(i, IUnknown, groupId, subId) + + +#ifdef COM_DECLSPEC_NOTHROW +#define Z7_COMWF_B COM_DECLSPEC_NOTHROW STDMETHODIMP +#define Z7_COMWF_B_(t) COM_DECLSPEC_NOTHROW STDMETHODIMP_(t) +#else +#define Z7_COMWF_B STDMETHODIMP +#define Z7_COMWF_B_(t) STDMETHODIMP_(t) +#endif + +#if defined(_MSC_VER) && !defined(COM_DECLSPEC_NOTHROW) +#define Z7_COM7F_B __declspec(nothrow) STDMETHODIMP +#define Z7_COM7F_B_(t) __declspec(nothrow) STDMETHODIMP_(t) +#else +#define Z7_COM7F_B Z7_COMWF_B +#define Z7_COM7F_B_(t) Z7_COMWF_B_(t) +#endif + +// #define Z7_COM7F_E Z7_noexcept +#define Z7_COM7F_E throw() +#define Z7_COM7F_EO Z7_COM7F_E Z7_override +#define Z7_COM7F_EOF Z7_COM7F_EO Z7_final +#define Z7_COM7F_IMF(f) Z7_COM7F_B f Z7_COM7F_E +#define Z7_COM7F_IMF2(t, f) Z7_COM7F_B_(t) f Z7_COM7F_E + +#define Z7_COM7F_PURE(f) virtual Z7_COM7F_IMF(f) =0; +#define Z7_COM7F_PURE2(t, f) virtual Z7_COM7F_IMF2(t, f) =0; +#define Z7_COM7F_IMP(f) Z7_COM7F_IMF(f) Z7_override Z7_final; +#define Z7_COM7F_IMP2(t, f) Z7_COM7F_IMF2(t, f) Z7_override Z7_final; +#define Z7_COM7F_IMP_NONFINAL(f) Z7_COM7F_IMF(f) Z7_override; +#define Z7_COM7F_IMP_NONFINAL2(t, f) Z7_COM7F_IMF2(t, f) Z7_override; + +#define Z7_IFACE_PURE(name) Z7_IFACEN_ ## name(=0;) +#define Z7_IFACE_IMP(name) Z7_IFACEN_ ## name(Z7_override Z7_final;) + +#define Z7_IFACE_COM7_PURE(name) Z7_IFACEM_ ## name(Z7_COM7F_PURE) +#define Z7_IFACE_COM7_IMP(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP) +#define Z7_IFACE_COM7_IMP_NONFINAL(name) Z7_IFACEM_ ## name(Z7_COM7F_IMP_NONFINAL) + + +#define Z7_IFACE_DECL_PURE(name) \ + DECLARE_INTERFACE(name) \ + { Z7_IFACE_PURE(name) }; + +#define Z7_IFACE_DECL_PURE_(name, baseiface) \ + DECLARE_INTERFACE_(name, baseiface) \ + { Z7_IFACE_PURE(name) }; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/IPassword.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/IPassword.h --- p7zip-rar-16.02/CPP/7zip/IPassword.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/IPassword.h 2023-03-24 11:00:00.000000000 +0000 @@ -1,23 +1,54 @@ -// IPassword.h - -#ifndef __IPASSWORD_H -#define __IPASSWORD_H - -#include "../Common/MyTypes.h" -#include "../Common/MyUnknown.h" - -#include "IDecl.h" - -#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x) - -PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) -{ - STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; -}; - -PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) -{ - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; -}; - -#endif +// IPassword.h + +#ifndef ZIP7_INC_IPASSWORD_H +#define ZIP7_INC_IPASSWORD_H + +#include "../Common/MyTypes.h" + +#include "IDecl.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_PASSWORD(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 5, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +/* +How to use output parameter (BSTR *password): + +in: The caller is required to set BSTR value as NULL (no string). + The callee (in 7-Zip code) ignores the input value stored in BSTR variable, + +out: The callee rewrites BSTR variable (*password) with new allocated string pointer. + The caller must free BSTR string with function SysFreeString(); +*/ + +#define Z7_IFACEM_ICryptoGetTextPassword(x) \ + x(CryptoGetTextPassword(BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword, 0x10) + + +/* +CryptoGetTextPassword2() +in: + The caller is required to set BSTR value as NULL (no string). + The caller is not required to set (*passwordIsDefined) value. + +out: + Return code: != S_OK : error code + Return code: S_OK : success + + if (*passwordIsDefined == 1), the variable (*password) contains password string + + if (*passwordIsDefined == 0), the password is not defined, + but the callee still could set (*password) to some allocated string, for example, as empty string. + + The caller must free BSTR string with function SysFreeString() +*/ + +#define Z7_IFACEM_ICryptoGetTextPassword2(x) \ + x(CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +Z7_IFACE_CONSTR_PASSWORD(ICryptoGetTextPassword2, 0x11) + +Z7_PURE_INTERFACES_END +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/IProgress.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/IProgress.h --- p7zip-rar-16.02/CPP/7zip/IProgress.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/IProgress.h 2023-02-01 18:00:00.000000000 +0000 @@ -1,19 +1,20 @@ -// IProgress.h - -#ifndef __IPROGRESS_H -#define __IPROGRESS_H - -#include "../Common/MyTypes.h" - -#include "IDecl.h" - -#define INTERFACE_IProgress(x) \ - STDMETHOD(SetTotal)(UInt64 total) x; \ - STDMETHOD(SetCompleted)(const UInt64 *completeValue) x; \ - -DECL_INTERFACE(IProgress, 0, 5) -{ - INTERFACE_IProgress(PURE) -}; - -#endif +// IProgress.h + +#ifndef ZIP7_INC_IPROGRESS_H +#define ZIP7_INC_IPROGRESS_H + +#include "../Common/MyTypes.h" + +#include "IDecl.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEM_IProgress(x) \ + x(SetTotal(UInt64 total)) \ + x(SetCompleted(const UInt64 *completeValue)) \ + +Z7_DECL_IFACE_7ZIP(IProgress, 0, 5) + { Z7_IFACE_COM7_PURE(IProgress) }; + +Z7_PURE_INTERFACES_END +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/IStream.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/IStream.h --- p7zip-rar-16.02/CPP/7zip/IStream.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/IStream.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,127 +1,210 @@ -// IStream.h - -#ifndef __ISTREAM_H -#define __ISTREAM_H - -#include "../Common/MyTypes.h" -#include "../Common/MyWindows.h" - -#include "IDecl.h" - -#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x) -#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) - -STREAM_INTERFACE(ISequentialInStream, 0x01) -{ - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* - The requirement for caller: (processedSize != NULL). - The callee can allow (processedSize == NULL) for compatibility reasons. - - if (size == 0), this function returns S_OK and (*processedSize) is set to 0. - - if (size != 0) - { - Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size), - where (avail_size) is the size of remaining bytes in stream. - If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0). - You must call Read() in loop, if you need to read exact amount of data. - } - - If seek pointer before Read() call was changed to position past the end of stream: - if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0. - - ERROR CASES: - If the function returns error code, then (*processedSize) is size of - data written to (data) buffer (it can be data before error or data with errors). - The recommended way for callee to work with reading errors: - 1) write part of data before error to (data) buffer and return S_OK. - 2) return error code for further calls of Read(). - */ -}; - -STREAM_INTERFACE(ISequentialOutStream, 0x02) -{ - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; - - /* - The requirement for caller: (processedSize != NULL). - The callee can allow (processedSize == NULL) for compatibility reasons. - - if (size != 0) - { - Partial write is allowed: (*processedSize <= size), - but this function must write at least 1 byte: (*processedSize > 0). - You must call Write() in loop, if you need to write exact amount of data. - } - - ERROR CASES: - If the function returns error code, then (*processedSize) is size of - data written from (data) buffer. - */ -}; - -#ifdef __HRESULT_FROM_WIN32 -#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) -#else -#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) -#endif - -/* Seek() Function - If you seek before the beginning of the stream, Seek() function returns error code: - Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK). - or STG_E_INVALIDFUNCTION - - It is allowed to seek past the end of the stream. - - - if Seek() returns error, then the value of *newPosition is undefined. -*/ - -STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; -}; - -STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) -{ - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; - STDMETHOD(SetSize)(UInt64 newSize) PURE; -}; - -STREAM_INTERFACE(IStreamGetSize, 0x06) -{ - STDMETHOD(GetSize)(UInt64 *size) PURE; -}; - -STREAM_INTERFACE(IOutStreamFinish, 0x07) -{ - STDMETHOD(OutStreamFinish)() PURE; -}; - - -STREAM_INTERFACE(IStreamGetProps, 0x08) -{ - STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE; -}; - -struct CStreamFileProps -{ - UInt64 Size; - UInt64 VolID; - UInt64 FileID_Low; - UInt64 FileID_High; - UInt32 NumLinks; - UInt32 Attrib; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; -}; - -STREAM_INTERFACE(IStreamGetProps2, 0x09) -{ - STDMETHOD(GetProps2)(CStreamFileProps *props) PURE; -}; - -#endif +// IStream.h + +#ifndef ZIP7_INC_ISTREAM_H +#define ZIP7_INC_ISTREAM_H + +#include "../Common/Common0.h" +#include "../Common/MyTypes.h" +#include "../Common/MyWindows.h" + +#include "IDecl.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_STREAM(i, n) \ + Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n) + + +/* +ISequentialInStream::Read() + The requirement for caller: (processedSize != NULL). + The callee can allow (processedSize == NULL) for compatibility reasons. + + if (size == 0), this function returns S_OK and (*processedSize) is set to 0. + + if (size != 0) + { + Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size), + where (avail_size) is the size of remaining bytes in stream. + If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0). + You must call Read() in loop, if you need to read exact amount of data. + } + + If seek pointer before Read() call was changed to position past the end of stream: + if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0. + + ERROR CASES: + If the function returns error code, then (*processedSize) is size of + data written to (data) buffer (it can be data before error or data with errors). + The recommended way for callee to work with reading errors: + 1) write part of data before error to (data) buffer and return S_OK. + 2) return error code for further calls of Read(). +*/ +#define Z7_IFACEM_ISequentialInStream(x) \ + x(Read(void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01) + + +/* +ISequentialOutStream::Write() + The requirement for caller: (processedSize != NULL). + The callee can allow (processedSize == NULL) for compatibility reasons. + + if (size != 0) + { + Partial write is allowed: (*processedSize <= size), + but this function must write at least 1 byte: (*processedSize > 0). + You must call Write() in loop, if you need to write exact amount of data. + } + + ERROR CASES: + If the function returns error code, then (*processedSize) is size of + data written from (data) buffer. +*/ +#define Z7_IFACEM_ISequentialOutStream(x) \ + x(Write(const void *data, UInt32 size, UInt32 *processedSize)) +Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02) + + +#ifdef _WIN32 + +#ifdef __HRESULT_FROM_WIN32 +#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) +#else +#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) +#endif + +#else + +#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY_E_ERROR_NEGATIVE_SEEK + +#endif + + +/* +IInStream::Seek() / IOutStream::Seek() + If you seek to position before the beginning of the stream, + Seek() function returns error code: + Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK). + or STG_E_INVALIDFUNCTION + It is allowed to seek past the end of the stream. + if Seek() returns error, then the value of *newPosition is undefined. +*/ + +#define Z7_IFACEM_IInStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03) + +#define Z7_IFACEM_IOutStream(x) \ + x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \ + x(SetSize(UInt64 newSize)) +Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04) + +#define Z7_IFACEM_IStreamGetSize(x) \ + x(GetSize(UInt64 *size)) +Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06) + +#define Z7_IFACEM_IOutStreamFinish(x) \ + x(OutStreamFinish()) +Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07) + +#define Z7_IFACEM_IStreamGetProps(x) \ + x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08) + + +struct CStreamFileProps +{ + UInt64 Size; + UInt64 VolID; + UInt64 FileID_Low; + UInt64 FileID_High; + UInt32 NumLinks; + UInt32 Attrib; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; +}; + + +#define Z7_IFACEM_IStreamGetProps2(x) \ + x(GetProps2(CStreamFileProps *props)) +Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09) + +#define Z7_IFACEM_IStreamGetProp(x) \ + x(GetProperty(PROPID propID, PROPVARIANT *value)) \ + x(ReloadProps()) +Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a) + + +/* +IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end) + + It sets region of data in output stream that is restricted. + For restricted region it's expected (or allowed) + that the caller can write to same region with different calls of Write()/SetSize(). + Another regions of output stream will be supposed as non-restricted: + - The callee usually doesn't flush the data in restricted region. + - The callee usually can flush data from non-restricted region after writing. + +Actual restiction rules depend also from current stream position. +It's recommended to call SetRestriction() just before the Write() call. +So the callee can optimize writing and flushing, if that Write() +operation is not restricted. + +Note: Each new call of SetRestriction() sets new restictions, +so previous restrction calls has no effect anymore. + +inputs: + + (begin > end) is not allowed, and returns E_FAIL; + + if (begin == end) + { + No restriction. + The caller will call Write() in sequential order. + After SetRestriction(begin, begin), but before next call of SetRestriction() + { + Additional condition: + it's expected that current stream seek position is equal to stream size. + The callee can make final flushing for any data before current stream seek position. + For each Write(size) call: + The callee can make final flushing for that new written data. + } + The pair of values (begin == 0 && end == 0) is recommended to remove write restriction. + } + + if (begin < end) + { + it means that callee must NOT flush any data in region [begin, end). + The caller is allowed to Seek() to that region and rewrite the + data in that restriction region. + if (end == (UInt64)(Int64)-1) + { + there is no upper bound for restricted region. + So non-restricted region will be [0, begin) in that case + } + } + + returns: + - if (begin > end) it return ERROR code (E_FAIL) + - S_OK : if no errors. + - Also the call of SetRestriction() can initiate the flushing of already written data. + So it can return the result of that flushing. + + Note: IOutStream::SetSize() also can change the data. + So it's not expected the call + IOutStream::SetSize() to region that was written before as unrestricted. +*/ + +#define Z7_IFACEM_IStreamSetRestriction(x) \ + x(SetRestriction(UInt64 begin, UInt64 end)) \ + +Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10) + +Z7_PURE_INTERFACES_END +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/LzFindOpt.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzFindOpt.mak --- p7zip-rar-16.02/CPP/7zip/LzFindOpt.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzFindOpt.mak 2021-06-09 07:41:41.000000000 +0000 @@ -0,0 +1,7 @@ +!IF defined(USE_C_LZFINDOPT) || "$(PLATFORM)" != "x64" +C_OBJS = $(C_OBJS) \ + $O\LzFindOpt.obj +!ELSE +ASM_OBJS = $(ASM_OBJS) \ + $O\LzFindOpt.obj +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/LzmaDec.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec.mak --- p7zip-rar-16.02/CPP/7zip/LzmaDec.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec.mak 2024-02-29 08:00:00.000000000 +0000 @@ -0,0 +1,7 @@ +!IF "$(PLATFORM)" == "x64" || ("$(PLATFORM)" == "arm64" && !defined(NO_ASM_GNU)) +!IFNDEF NO_ASM +CFLAGS_C_SPEC = -DZ7_LZMA_DEC_OPT +ASM_OBJS = $(ASM_OBJS) \ + $O\LzmaDecOpt.obj +!ENDIF +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/LzmaDec_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec_gcc.mak --- p7zip-rar-16.02/CPP/7zip/LzmaDec_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/LzmaDec_gcc.mak 2021-03-24 19:54:33.000000000 +0000 @@ -0,0 +1,14 @@ +ifdef USE_ASM +ifdef IS_X64 +USE_LZMA_DEC_ASM=1 +endif +ifdef IS_ARM64 +USE_LZMA_DEC_ASM=1 +endif +endif + +ifdef USE_LZMA_DEC_ASM + +LZMA_DEC_OPT_OBJS= $O/LzmaDecOpt.o + +endif diff -Nru p7zip-rar-16.02/CPP/7zip/MyVersion.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersion.h --- p7zip-rar-16.02/CPP/7zip/MyVersion.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersion.h 2015-06-09 08:42:47.000000000 +0000 @@ -1,2 +1,2 @@ -#define USE_COPYRIGHT_CR -#include "../../C/7zVersion.h" +#define USE_COPYRIGHT_CR +#include "../../C/7zVersion.h" diff -Nru p7zip-rar-16.02/CPP/7zip/MyVersionInfo.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersionInfo.rc --- p7zip-rar-16.02/CPP/7zip/MyVersionInfo.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/MyVersionInfo.rc 2023-02-21 13:00:00.000000000 +0000 @@ -0,0 +1,2 @@ +#include "MyVersion.h" +#include "../../C/7zVersion.rc" diff -Nru p7zip-rar-16.02/CPP/7zip/PREMAKE/generate.sh p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/generate.sh --- p7zip-rar-16.02/CPP/7zip/PREMAKE/generate.sh 2014-12-29 15:22:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/generate.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#!/bin/sh - -set -x - -doit() -{ - rm -fr P7ZIP.$1 - mkdir P7ZIP.$1 - cd P7ZIP.$1 - cp ../premake4.lua premake4.lua - premake4 $1 - cd .. -} - -doit codeblocks -doit codelite -doit gmake - diff -Nru p7zip-rar-16.02/CPP/7zip/PREMAKE/premake4.lua p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/premake4.lua --- p7zip-rar-16.02/CPP/7zip/PREMAKE/premake4.lua 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/PREMAKE/premake4.lua 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ - --- WARNING : automatically generated by utils/generate.py -solution "p7zip" - configurations { "Debug", "Release" } - --- includes for all projects - includedirs { - "../../../myWindows", - "../../../", - "../../../include_windows", - } - - configuration "Debug" - defines { "DEBUG", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" } - flags { "Symbols" } - - configuration "Release" - defines { "NDEBUG", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" } - flags { "Optimize" } - - project "all_c_code" - kind "StaticLib" - language "C" - files { - "../../../../C/7zCrc.c", - "../../../../C/7zCrcOpt.c", - "../../../../C/7zStream.c", - "../../../../C/Aes.c", - "../../../../C/Alloc.c", - "../../../../C/Bcj2.c", - "../../../../C/Bcj2Enc.c", - "../../../../C/Bra.c", - "../../../../C/Bra86.c", - "../../../../C/BraIA64.c", - "../../../../C/BwtSort.c", - "../../../../C/CpuArch.c", - "../../../../C/Delta.c", - "../../../../C/HuffEnc.c", - "../../../../C/LzFind.c", - "../../../../C/LzFindMt.c", - "../../../../C/Lzma2Dec.c", - "../../../../C/Lzma2Enc.c", - "../../../../C/LzmaDec.c", - "../../../../C/LzmaEnc.c", - "../../../../C/MtCoder.c", - "../../../../C/Ppmd7.c", - "../../../../C/Ppmd7Dec.c", - "../../../../C/Ppmd7Enc.c", - "../../../../C/Ppmd8.c", - "../../../../C/Ppmd8Dec.c", - "../../../../C/Ppmd8Enc.c", - "../../../../C/Sha1.c", - "../../../../C/Sha256.c", - "../../../../C/Sort.c", - "../../../../C/Threads.c", - "../../../../C/Xz.c", - "../../../../C/XzCrc64.c", - "../../../../C/XzCrc64Opt.c", - "../../../../C/XzDec.c", - "../../../../C/XzEnc.c", - "../../../../C/XzIn.c", - } - ---------------------------------- - project "7za" - kind "ConsoleApp" - language "C++" - files { - "../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp", - "../../../../CPP/7zip/Archive/7z/7zDecode.cpp", - "../../../../CPP/7zip/Archive/7z/7zEncode.cpp", - "../../../../CPP/7zip/Archive/7z/7zExtract.cpp", - "../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp", - "../../../../CPP/7zip/Archive/7z/7zHandler.cpp", - "../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp", - "../../../../CPP/7zip/Archive/7z/7zHeader.cpp", - "../../../../CPP/7zip/Archive/7z/7zIn.cpp", - "../../../../CPP/7zip/Archive/7z/7zOut.cpp", - "../../../../CPP/7zip/Archive/7z/7zProperties.cpp", - "../../../../CPP/7zip/Archive/7z/7zRegister.cpp", - "../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp", - "../../../../CPP/7zip/Archive/7z/7zUpdate.cpp", - "../../../../CPP/7zip/Archive/Bz2Handler.cpp", - "../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp", - "../../../../CPP/7zip/Archive/Cab/CabHandler.cpp", - "../../../../CPP/7zip/Archive/Cab/CabHeader.cpp", - "../../../../CPP/7zip/Archive/Cab/CabIn.cpp", - "../../../../CPP/7zip/Archive/Cab/CabRegister.cpp", - "../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp", - "../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp", - "../../../../CPP/7zip/Archive/Common/FindSignature.cpp", - "../../../../CPP/7zip/Archive/Common/HandlerOut.cpp", - "../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp", - "../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp", - "../../../../CPP/7zip/Archive/Common/MultiStream.cpp", - "../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp", - "../../../../CPP/7zip/Archive/Common/ParseProperties.cpp", - "../../../../CPP/7zip/Archive/DeflateProps.cpp", - "../../../../CPP/7zip/Archive/GzHandler.cpp", - "../../../../CPP/7zip/Archive/LzmaHandler.cpp", - "../../../../CPP/7zip/Archive/PpmdHandler.cpp", - "../../../../CPP/7zip/Archive/SplitHandler.cpp", - "../../../../CPP/7zip/Archive/Tar/TarHandler.cpp", - "../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp", - "../../../../CPP/7zip/Archive/Tar/TarHeader.cpp", - "../../../../CPP/7zip/Archive/Tar/TarIn.cpp", - "../../../../CPP/7zip/Archive/Tar/TarOut.cpp", - "../../../../CPP/7zip/Archive/Tar/TarRegister.cpp", - "../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp", - "../../../../CPP/7zip/Archive/XzHandler.cpp", - "../../../../CPP/7zip/Archive/ZHandler.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipIn.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipItem.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipOut.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp", - "../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp", - "../../../../CPP/7zip/Common/CWrappers.cpp", - "../../../../CPP/7zip/Common/CreateCoder.cpp", - "../../../../CPP/7zip/Common/FilePathAutoRename.cpp", - "../../../../CPP/7zip/Common/FileStreams.cpp", - "../../../../CPP/7zip/Common/FilterCoder.cpp", - "../../../../CPP/7zip/Common/InBuffer.cpp", - "../../../../CPP/7zip/Common/InOutTempBuffer.cpp", - "../../../../CPP/7zip/Common/LimitedStreams.cpp", - "../../../../CPP/7zip/Common/MemBlocks.cpp", - "../../../../CPP/7zip/Common/MethodId.cpp", - "../../../../CPP/7zip/Common/MethodProps.cpp", - "../../../../CPP/7zip/Common/OffsetStream.cpp", - "../../../../CPP/7zip/Common/OutBuffer.cpp", - "../../../../CPP/7zip/Common/OutMemStream.cpp", - "../../../../CPP/7zip/Common/ProgressMt.cpp", - "../../../../CPP/7zip/Common/ProgressUtils.cpp", - "../../../../CPP/7zip/Common/PropId.cpp", - "../../../../CPP/7zip/Common/StreamBinder.cpp", - "../../../../CPP/7zip/Common/StreamObjects.cpp", - "../../../../CPP/7zip/Common/StreamUtils.cpp", - "../../../../CPP/7zip/Common/UniqBlocks.cpp", - "../../../../CPP/7zip/Common/VirtThread.cpp", - "../../../../CPP/7zip/Compress/BZip2Crc.cpp", - "../../../../CPP/7zip/Compress/BZip2Decoder.cpp", - "../../../../CPP/7zip/Compress/BZip2Encoder.cpp", - "../../../../CPP/7zip/Compress/BZip2Register.cpp", - "../../../../CPP/7zip/Compress/Bcj2Coder.cpp", - "../../../../CPP/7zip/Compress/Bcj2Register.cpp", - "../../../../CPP/7zip/Compress/BcjCoder.cpp", - "../../../../CPP/7zip/Compress/BcjRegister.cpp", - "../../../../CPP/7zip/Compress/BitlDecoder.cpp", - "../../../../CPP/7zip/Compress/BranchMisc.cpp", - "../../../../CPP/7zip/Compress/BranchRegister.cpp", - "../../../../CPP/7zip/Compress/ByteSwap.cpp", - "../../../../CPP/7zip/Compress/CopyCoder.cpp", - "../../../../CPP/7zip/Compress/CopyRegister.cpp", - "../../../../CPP/7zip/Compress/Deflate64Register.cpp", - "../../../../CPP/7zip/Compress/DeflateDecoder.cpp", - "../../../../CPP/7zip/Compress/DeflateEncoder.cpp", - "../../../../CPP/7zip/Compress/DeflateRegister.cpp", - "../../../../CPP/7zip/Compress/DeltaFilter.cpp", - "../../../../CPP/7zip/Compress/ImplodeDecoder.cpp", - "../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp", - "../../../../CPP/7zip/Compress/LzOutWindow.cpp", - "../../../../CPP/7zip/Compress/Lzma2Decoder.cpp", - "../../../../CPP/7zip/Compress/Lzma2Encoder.cpp", - "../../../../CPP/7zip/Compress/Lzma2Register.cpp", - "../../../../CPP/7zip/Compress/LzmaDecoder.cpp", - "../../../../CPP/7zip/Compress/LzmaEncoder.cpp", - "../../../../CPP/7zip/Compress/LzmaRegister.cpp", - "../../../../CPP/7zip/Compress/LzxDecoder.cpp", - "../../../../CPP/7zip/Compress/PpmdDecoder.cpp", - "../../../../CPP/7zip/Compress/PpmdEncoder.cpp", - "../../../../CPP/7zip/Compress/PpmdRegister.cpp", - "../../../../CPP/7zip/Compress/PpmdZip.cpp", - "../../../../CPP/7zip/Compress/QuantumDecoder.cpp", - "../../../../CPP/7zip/Compress/ShrinkDecoder.cpp", - "../../../../CPP/7zip/Compress/ZDecoder.cpp", - "../../../../CPP/7zip/Crypto/7zAes.cpp", - "../../../../CPP/7zip/Crypto/7zAesRegister.cpp", - "../../../../CPP/7zip/Crypto/HmacSha1.cpp", - "../../../../CPP/7zip/Crypto/MyAes.cpp", - "../../../../CPP/7zip/Crypto/MyAesReg.cpp", - "../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp", - "../../../../CPP/7zip/Crypto/RandGen.cpp", - "../../../../CPP/7zip/Crypto/WzAes.cpp", - "../../../../CPP/7zip/Crypto/ZipCrypto.cpp", - "../../../../CPP/7zip/Crypto/ZipStrong.cpp", - "../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp", - "../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp", - "../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp", - "../../../../CPP/7zip/UI/Common/Bench.cpp", - "../../../../CPP/7zip/UI/Common/DefaultName.cpp", - "../../../../CPP/7zip/UI/Common/EnumDirItems.cpp", - "../../../../CPP/7zip/UI/Common/Extract.cpp", - "../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp", - "../../../../CPP/7zip/UI/Common/HashCalc.cpp", - "../../../../CPP/7zip/UI/Common/LoadCodecs.cpp", - "../../../../CPP/7zip/UI/Common/OpenArchive.cpp", - "../../../../CPP/7zip/UI/Common/PropIDUtils.cpp", - "../../../../CPP/7zip/UI/Common/SetProperties.cpp", - "../../../../CPP/7zip/UI/Common/SortUtils.cpp", - "../../../../CPP/7zip/UI/Common/TempFiles.cpp", - "../../../../CPP/7zip/UI/Common/Update.cpp", - "../../../../CPP/7zip/UI/Common/UpdateAction.cpp", - "../../../../CPP/7zip/UI/Common/UpdateCallback.cpp", - "../../../../CPP/7zip/UI/Common/UpdatePair.cpp", - "../../../../CPP/7zip/UI/Common/UpdateProduce.cpp", - "../../../../CPP/7zip/UI/Console/BenchCon.cpp", - "../../../../CPP/7zip/UI/Console/ConsoleClose.cpp", - "../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp", - "../../../../CPP/7zip/UI/Console/HashCon.cpp", - "../../../../CPP/7zip/UI/Console/List.cpp", - "../../../../CPP/7zip/UI/Console/Main.cpp", - "../../../../CPP/7zip/UI/Console/MainAr.cpp", - "../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp", - "../../../../CPP/7zip/UI/Console/PercentPrinter.cpp", - "../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp", - "../../../../CPP/7zip/UI/Console/UserInputUtils.cpp", - "../../../../CPP/Common/CRC.cpp", - "../../../../CPP/Common/CommandLineParser.cpp", - "../../../../CPP/Common/CrcReg.cpp", - "../../../../CPP/Common/IntToString.cpp", - "../../../../CPP/Common/ListFileUtils.cpp", - "../../../../CPP/Common/MyString.cpp", - "../../../../CPP/Common/MyVector.cpp", - "../../../../CPP/Common/MyWindows.cpp", - "../../../../CPP/Common/Sha1Reg.cpp", - "../../../../CPP/Common/Sha256Reg.cpp", - "../../../../CPP/Common/StdInStream.cpp", - "../../../../CPP/Common/StdOutStream.cpp", - "../../../../CPP/Common/StringConvert.cpp", - "../../../../CPP/Common/StringToInt.cpp", - "../../../../CPP/Common/UTFConvert.cpp", - "../../../../CPP/Common/Wildcard.cpp", - "../../../../CPP/Common/XzCrc64Reg.cpp", - "../../../../CPP/Windows/ErrorMsg.cpp", - "../../../../CPP/Windows/FileDir.cpp", - "../../../../CPP/Windows/FileFind.cpp", - "../../../../CPP/Windows/FileIO.cpp", - "../../../../CPP/Windows/FileName.cpp", - "../../../../CPP/Windows/PropVariant.cpp", - "../../../../CPP/Windows/PropVariantConv.cpp", - "../../../../CPP/Windows/Synchronization.cpp", - "../../../../CPP/Windows/System.cpp", - "../../../../CPP/Windows/TimeUtils.cpp", - "../../../../CPP/myWindows/myAddExeFlag.cpp", - "../../../../CPP/myWindows/mySplitCommandLine.cpp", - "../../../../CPP/myWindows/wine_date_and_time.cpp", - - } - - configuration "linux" - links { "all_c_code", "pthread" } diff -Nru p7zip-rar-16.02/CPP/7zip/PropID.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/PropID.h --- p7zip-rar-16.02/CPP/7zip/PropID.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/PropID.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,127 +1,178 @@ -// PropID.h - -#ifndef __7ZIP_PROP_ID_H -#define __7ZIP_PROP_ID_H - -#include "../Common/MyTypes.h" - -enum -{ - kpidNoProperty = 0, - kpidMainSubfile, - kpidHandlerItemIndex, - kpidPath, - kpidName, - kpidExtension, - kpidIsDir, - kpidSize, - kpidPackSize, - kpidAttrib, - kpidCTime, - kpidATime, - kpidMTime, - kpidSolid, - kpidCommented, - kpidEncrypted, - kpidSplitBefore, - kpidSplitAfter, - kpidDictionarySize, - kpidCRC, - kpidType, - kpidIsAnti, - kpidMethod, - kpidHostOS, - kpidFileSystem, - kpidUser, - kpidGroup, - kpidBlock, - kpidComment, - kpidPosition, - kpidPrefix, - kpidNumSubDirs, - kpidNumSubFiles, - kpidUnpackVer, - kpidVolume, - kpidIsVolume, - kpidOffset, - kpidLinks, - kpidNumBlocks, - kpidNumVolumes, - kpidTimeType, - kpidBit64, - kpidBigEndian, - kpidCpu, - kpidPhySize, - kpidHeadersSize, - kpidChecksum, - kpidCharacts, - kpidVa, - kpidId, - kpidShortName, - kpidCreatorApp, - kpidSectorSize, - kpidPosixAttrib, - kpidSymLink, - kpidError, - kpidTotalSize, - kpidFreeSpace, - kpidClusterSize, - kpidVolumeName, - kpidLocalName, - kpidProvider, - kpidNtSecure, - kpidIsAltStream, - kpidIsAux, - kpidIsDeleted, - kpidIsTree, - kpidSha1, - kpidSha256, - kpidErrorType, - kpidNumErrors, - kpidErrorFlags, - kpidWarningFlags, - kpidWarning, - kpidNumStreams, - kpidNumAltStreams, - kpidAltStreamsSize, - kpidVirtualSize, - kpidUnpackSize, - kpidTotalPhySize, - kpidVolumeIndex, - kpidSubType, - kpidShortComment, - kpidCodePage, - kpidIsNotArcType, - kpidPhySizeCantBeDetected, - kpidZerosTailIsAllowed, - kpidTailSize, - kpidEmbeddedStubSize, - kpidNtReparse, - kpidHardLink, - kpidINode, - kpidStreamId, - kpidReadOnly, - kpidOutName, - kpidCopyLink, - - kpid_NUM_DEFINED, - - kpidUserDefined = 0x10000 -}; - -extern const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED]; // VARTYPE - -const UInt32 kpv_ErrorFlags_IsNotArc = 1 << 0; -const UInt32 kpv_ErrorFlags_HeadersError = 1 << 1; -const UInt32 kpv_ErrorFlags_EncryptedHeadersError = 1 << 2; -const UInt32 kpv_ErrorFlags_UnavailableStart = 1 << 3; -const UInt32 kpv_ErrorFlags_UnconfirmedStart = 1 << 4; -const UInt32 kpv_ErrorFlags_UnexpectedEnd = 1 << 5; -const UInt32 kpv_ErrorFlags_DataAfterEnd = 1 << 6; -const UInt32 kpv_ErrorFlags_UnsupportedMethod = 1 << 7; -const UInt32 kpv_ErrorFlags_UnsupportedFeature = 1 << 8; -const UInt32 kpv_ErrorFlags_DataError = 1 << 9; -const UInt32 kpv_ErrorFlags_CrcError = 1 << 10; -// const UInt32 kpv_ErrorFlags_Unsupported = 1 << 11; - -#endif +// PropID.h + +#ifndef ZIP7_INC_7ZIP_PROP_ID_H +#define ZIP7_INC_7ZIP_PROP_ID_H + +#include "../Common/MyTypes.h" + +enum +{ + kpidNoProperty = 0, + kpidMainSubfile, + kpidHandlerItemIndex, + kpidPath, + kpidName, + kpidExtension, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidAttrib, + kpidCTime, + kpidATime, + kpidMTime, + kpidSolid, + kpidCommented, + kpidEncrypted, + kpidSplitBefore, + kpidSplitAfter, + kpidDictionarySize, + kpidCRC, + kpidType, + kpidIsAnti, + kpidMethod, + kpidHostOS, + kpidFileSystem, + kpidUser, + kpidGroup, + kpidBlock, + kpidComment, + kpidPosition, + kpidPrefix, + kpidNumSubDirs, + kpidNumSubFiles, + kpidUnpackVer, + kpidVolume, + kpidIsVolume, + kpidOffset, + kpidLinks, + kpidNumBlocks, + kpidNumVolumes, + kpidTimeType, + kpidBit64, + kpidBigEndian, + kpidCpu, + kpidPhySize, + kpidHeadersSize, + kpidChecksum, + kpidCharacts, + kpidVa, + kpidId, + kpidShortName, + kpidCreatorApp, + kpidSectorSize, + kpidPosixAttrib, + kpidSymLink, + kpidError, + kpidTotalSize, + kpidFreeSpace, + kpidClusterSize, + kpidVolumeName, + kpidLocalName, + kpidProvider, + kpidNtSecure, + kpidIsAltStream, + kpidIsAux, + kpidIsDeleted, + kpidIsTree, + kpidSha1, + kpidSha256, + kpidErrorType, + kpidNumErrors, + kpidErrorFlags, + kpidWarningFlags, + kpidWarning, + kpidNumStreams, + kpidNumAltStreams, + kpidAltStreamsSize, + kpidVirtualSize, + kpidUnpackSize, + kpidTotalPhySize, + kpidVolumeIndex, + kpidSubType, + kpidShortComment, + kpidCodePage, + kpidIsNotArcType, + kpidPhySizeCantBeDetected, + kpidZerosTailIsAllowed, + kpidTailSize, + kpidEmbeddedStubSize, + kpidNtReparse, + kpidHardLink, + kpidINode, + kpidStreamId, + kpidReadOnly, + kpidOutName, + kpidCopyLink, + kpidArcFileName, + kpidIsHash, + kpidChangeTime, + kpidUserId, + kpidGroupId, + kpidDeviceMajor, + kpidDeviceMinor, + kpidDevMajor, + kpidDevMinor, + + kpid_NUM_DEFINED, + + kpidUserDefined = 0x10000 +}; + +extern const Byte k7z_PROPID_To_VARTYPE[kpid_NUM_DEFINED]; // VARTYPE + +const UInt32 kpv_ErrorFlags_IsNotArc = 1 << 0; +const UInt32 kpv_ErrorFlags_HeadersError = 1 << 1; +const UInt32 kpv_ErrorFlags_EncryptedHeadersError = 1 << 2; +const UInt32 kpv_ErrorFlags_UnavailableStart = 1 << 3; +const UInt32 kpv_ErrorFlags_UnconfirmedStart = 1 << 4; +const UInt32 kpv_ErrorFlags_UnexpectedEnd = 1 << 5; +const UInt32 kpv_ErrorFlags_DataAfterEnd = 1 << 6; +const UInt32 kpv_ErrorFlags_UnsupportedMethod = 1 << 7; +const UInt32 kpv_ErrorFlags_UnsupportedFeature = 1 << 8; +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 -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.cpp --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.cpp 2011-07-10 17:54:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ - -#include - -#include "Q7SortFilerProxyModel.h" - -//! [0] -Q7SortFilerProxyModel::Q7SortFilerProxyModel(QObject *parent) - : QSortFilterProxyModel(parent) -{ -} - -/* -void Q7SortFilerProxyModel::setFilterMinimumDate(const QDate &date) -{ - minDate = date; - invalidateFilter(); -} - -void Q7SortFilerProxyModel::setFilterMaximumDate(const QDate &date) -{ - maxDate = date; - invalidateFilter(); -} -*/ - -bool Q7SortFilerProxyModel::filterAcceptsRow(int sourceRow, - const QModelIndex &sourceParent) const -{ - /* - QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); - QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent); - QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent); - - return (sourceModel()->data(index0).toString().contains(filterRegExp()) - || sourceModel()->data(index1).toString().contains(filterRegExp())) - && dateInRange(sourceModel()->data(index2).toDate()); - */ - return true; -} - -/* -bool Q7SortFilerProxyModel::lessThan(const QModelIndex &left, - const QModelIndex &right) const -{ - QVariant leftData = sourceModel()->data(left); - QVariant rightData = sourceModel()->data(right); - - - if (leftData.type() == QVariant::DateTime) { - return leftData.toDateTime() < rightData.toDateTime(); - } else { - QRegExp *emailPattern = new QRegExp("([\\w\\.]*@[\\w\\.]*)"); - - QString leftString = leftData.toString(); - if(left.column() == 1 && emailPattern->indexIn(leftString) != -1) - leftString = emailPattern->cap(1); - - QString rightString = rightData.toString(); - if(right.column() == 1 && emailPattern->indexIn(rightString) != -1) - rightString = emailPattern->cap(1); - - return QString::localeAwareCompare(leftString, rightString) < 0; - } -} -*/ - -/* -bool Q7SortFilerProxyModel::dateInRange(const QDate &date) const -{ - return (!minDate.isValid() || date > minDate) - && (!maxDate.isValid() || date < maxDate); -} -*/ diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.h --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.h 2011-07-10 17:54:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7SortFilerProxyModel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -#ifndef Q7SORTFILTERPROXYMODEL_H -#define Q7SORTFILTERPROXYMODEL_H - -#include -#include - -class Q7SortFilerProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - Q7SortFilerProxyModel(QObject *parent = 0); - -/* - QDate filterMinimumDate() const { return minDate; } - void setFilterMinimumDate(const QDate &date); - - QDate filterMaximumDate() const { return maxDate; } - void setFilterMaximumDate(const QDate &date); -*/ -protected: - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; - // bool lessThan(const QModelIndex &left, const QModelIndex &right) const; - -private: - /* - bool dateInRange(const QDate &date) const; - - QDate minDate; - QDate maxDate; - */ -}; - -#endif diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7Zip.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7Zip.pro --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/Q7Zip.pro 2015-10-07 09:35:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/Q7Zip.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2011-07-10T18:45:42 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = Q7Zip -TEMPLATE = app - - -SOURCES += main.cpp\ - q7filemanager.cpp \ - Q7SortFilerProxyModel.cpp - -HEADERS += q7filemanager.h \ - Q7SortFilerProxyModel.h - -INCLUDEPATH += ../../../ -INCLUDEPATH += ../../../include_windows - -#INCLUDEPATH += ../../../myWindows -#INCLUDEPATH += ../../../ -#INCLUDEPATH += ../../../include_windows -#INCLUDEPATH += ../FileManager - -#DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT ENV_UNIX BREAK_HANDLER UNICODE _UNICODE -#DEFINES += -DLANG -DNEW_FOLDER_INTERFACE -DEXTERNAL_CODECS - -DEFINES += UNICODE _UNICODE UNIX_USE_WIN_FILE - -LIBS += -L../util7zip -lutil7zip diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/main.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/main.cpp --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/main.cpp 2015-10-07 09:47:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ - -#include - -#include - -#include - -#include "q7filemanager.h" - -#include "Common/MyString.h" - -extern int utilZip_init(void); -extern int utilZip_setPath(const wchar_t *path); -extern int utilZip_GetNumberOfItems(); -extern UString utilZip_GetItemName(int ind); - -void logMsg(const QString & text); - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - - Q7FileManager w; - - // w.setSourceModel(createMailModel(&w)); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) - QString path = QDir::homePath(); -#else - QString path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); -#endif - w.setDir(path); - - - utilZip_init(); - - std::wstring wstr = path.toStdWString (); - const wchar_t * wpath = wstr.c_str(); - utilZip_setPath(wpath); - - int nb = utilZip_GetNumberOfItems(); - - logMsg(QString("nb=%1").arg(nb)); - - for(int i = 0 ;i < nb ; i++) - { - UString ustr = utilZip_GetItemName(i); - - QString str = QString::fromWCharArray((const wchar_t *)ustr); - - logMsg(QString("%1 : \"%2\"").arg(i).arg(str)); - } - - - w.show(); - - return a.exec(); -} diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.cpp --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.cpp 2015-10-07 09:49:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,212 +0,0 @@ -#include "q7filemanager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include - -#include "Q7SortFilerProxyModel.h" - -static QPlainTextEdit * gbl_logMsg; - -void logMsg(const QString & text) -{ - gbl_logMsg->appendPlainText(text); -} - -static QStandardItemModel *createEmptyModel(QObject *parent) -{ - QStandardItemModel *model = new QStandardItemModel(0, 7, parent); - - model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); - model->setHeaderData(1, Qt::Horizontal, QObject::tr("Size")); - model->setHeaderData(2, Qt::Horizontal, QObject::tr("Modified")); - model->setHeaderData(3, Qt::Horizontal, QObject::tr("Created")); - model->setHeaderData(4, Qt::Horizontal, QObject::tr("Accessed")); - model->setHeaderData(5, Qt::Horizontal, QObject::tr("Attributes")); - model->setHeaderData(6, Qt::Horizontal, QObject::tr("Packed Size")); - // model->setHeaderData(7, Qt::Horizontal, QObject::tr("Comment")); - - return model; -} - -Q7FileManager::Q7FileManager(QWidget *parent) - : QMainWindow(parent) -{ - this->setWindowTitle(tr("Q7zip")); - - QWidget * centralWidget = new QWidget; - QVBoxLayout * layout = new QVBoxLayout(centralWidget); - - m_listView = new QTreeView(); - m_logMsg = new QPlainTextEdit; - m_logMsg->setReadOnly(true); - gbl_logMsg = m_logMsg; - - - ////////////////////// - - m_listView_proxyModel = new Q7SortFilerProxyModel(this); - m_listView_proxyModel->setDynamicSortFilter(true); - - m_listView = new QTreeView; - m_listView->setRootIsDecorated(false); - m_listView->setAlternatingRowColors(true); - m_listView->setModel(m_listView_proxyModel); - m_listView->setSortingEnabled(m_listView_proxyModel); - m_listView->sortByColumn(0, Qt::AscendingOrder); - - connect(m_listView,SIGNAL(doubleClicked(QModelIndex)) , this, SLOT(item_doubleClicked(QModelIndex))); - - layout->addWidget( buildLineEdit() ); - layout->addWidget(m_listView); - layout->addWidget(m_logMsg); - - - setCentralWidget(centralWidget); - - - m_dirModel = createEmptyModel(this); - this->setSourceModel( m_dirModel ); - - resize(800,600); - - logMsg("line1"); - logMsg("Ok"); -} - -QWidget * Q7FileManager::buildLineEdit() -{ - QWidget * w = new QWidget; - QHBoxLayout * layout = new QHBoxLayout(w); - - m_btnParent = new QPushButton(tr("Up")); - connect(m_btnParent,SIGNAL(clicked()),this,SLOT(on_Parent())); - - m_pathEdit = new QLineEdit(); - - layout->addWidget(m_btnParent); - layout->addWidget(m_pathEdit); - - - return w; -} - -void Q7FileManager::on_Parent() -{ - QDir dir(m_dirPath); - - dir.cdUp(); - this->setDir(dir.absolutePath()); -} - -void Q7FileManager::item_doubleClicked(const QModelIndex & ind) -{ - // FIXME : how to have the column 0 ? - - - QModelIndex ind2 = m_listView_proxyModel->mapToSource(ind); - - // QStandardItem * item = m_dirModel->itemFromIndex(ind2); // ->text(); - - QStandardItem * item = m_dirModel->item(ind2.row(),0); - - if (item) - { - QString name = item->text(); // items.value(0).toString(); - QFileInfo fi( m_dirPath, name ); - if (fi.isDir()) - { - logMsg(tr(" DIR : %1").arg(name)); - this->setDir(fi.absoluteFilePath()); - } - else - { - QUrl url("file://"+fi.absoluteFilePath(),QUrl::TolerantMode); - - bool bret = QDesktopServices::openUrl(url); - logMsg(tr(" FILE : %1 => %2").arg(name).arg(bret)); - } - } -} - -void Q7FileManager::setDir(const QString & dirPath) -{ - m_dirPath = dirPath; - m_pathEdit->setText(m_dirPath); - - - // FIXME - clear - m_dirModel = createEmptyModel(this); - - - QDir dir(dirPath); - dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot); // QDir::NoSymLinks - // dir.setSorting(QDir::Size | QDir::Reversed); - - QFileInfoList list = dir.entryInfoList(); - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - - - m_dirModel->insertRow(0); - /* - QStyle * style = this->style(); - if (fileInfo.isDir()) - { - QIcon icon = style->standardIcon ( QStyle::SP_DirIcon ); - m_dirModel->setItem(0, 0, new QStandardItem ( icon, fileInfo.fileName() )); - } - else - { - QIcon icon = style->standardIcon ( QStyle::SP_FileIcon ); - m_dirModel->setItem(0, 0, new QStandardItem ( icon, fileInfo.fileName() )); - } - */ - QStandardItem * item = new QStandardItem ( QFileIconProvider().icon(fileInfo) , fileInfo.fileName() ); - item->setEditable(false); - m_dirModel->setItem(0, 0, item); - - m_dirModel->setData(m_dirModel->index(0, 1), fileInfo.size()); - m_dirModel->item(0,1)->setEditable(false); - - m_dirModel->setData(m_dirModel->index(0, 2), fileInfo.lastModified()); - m_dirModel->item(0,2)->setEditable(false); - - m_dirModel->setData(m_dirModel->index(0, 3), fileInfo.created()); - m_dirModel->item(0,3)->setEditable(false); - - m_dirModel->setData(m_dirModel->index(0, 4), fileInfo.lastRead()); - m_dirModel->item(0,4)->setEditable(false); - - if (fileInfo.isDir()) m_dirModel->setData(m_dirModel->index(0, 5), "drw-r-----"); // FIXME - else m_dirModel->setData(m_dirModel->index(0, 5), "-rw-r-----"); // FIXME - m_dirModel->item(0,5)->setEditable(false); - - m_dirModel->setData(m_dirModel->index(0, 6), fileInfo.size()); // FIXME - m_dirModel->item(0,6)->setEditable(false); - } - - // FIXME - m_listView_proxyModel->setSourceModel(m_dirModel); -} - -void Q7FileManager::setSourceModel(QAbstractItemModel *model) -{ - m_listView_proxyModel->setSourceModel(model); -} - -Q7FileManager::~Q7FileManager() -{ - -} diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.h --- p7zip-rar-16.02/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.h 2015-10-07 09:16:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/Q7Zip/q7filemanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -#ifndef Q7FILEMANAGER_H -#define Q7FILEMANAGER_H - -#include - -QT_BEGIN_NAMESPACE -class QAbstractItemModel; -class QCheckBox; -class QComboBox; -class QDateEdit; -class QGroupBox; -class QLabel; -class QLineEdit; -class QTreeView; -class QTextEdit; -class QPushButton; -class QPlainTextEdit; -class QStandardItemModel; -class QModelIndex; -QT_END_NAMESPACE - -class Q7SortFilerProxyModel; - -class Q7FileManager : public QMainWindow -{ - Q_OBJECT - -public: - Q7FileManager(QWidget *parent = 0); - ~Q7FileManager(); - - void setSourceModel(QAbstractItemModel *model); - - void setDir(const QString & dirPath); - -private: - - QWidget * buildLineEdit(); - - QPushButton * m_btnParent; - - QString m_dirPath; - QLineEdit* m_pathEdit; - - Q7SortFilerProxyModel *m_listView_proxyModel; - QTreeView * m_listView; - QStandardItemModel * m_dirModel; - - QPlainTextEdit * m_logMsg; - -private slots: - void on_Parent(); - void item_doubleClicked(const QModelIndex & ind); -}; - -#endif // Q7FILEMANAGER_H diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/all.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/all.pro --- p7zip-rar-16.02/CPP/7zip/Q7Zip/all.pro 2011-07-10 20:31:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/all.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = util7zip Q7Zip -Q7Zip.depends = util7zip diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/util7zip/util7zip.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.cpp --- p7zip-rar-16.02/CPP/7zip/Q7Zip/util7zip/util7zip.cpp 2015-10-07 09:44:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,465 +0,0 @@ - - -#include "StdAfx.h" - -// #include "../../../../C/Alloc.h" - -#include -#include -#include - -#include "Common/MyWindows.h" -#include "Common/MyTypes.h" -typedef long LONG_PTR; // FIXME 64 bits ? -typedef LONG_PTR LRESULT; -// typedef long DWORD_PTR; // FIXME 64 bits ? -#include "Common/MyCom.h" -//#include "Windows/DLL.h" -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -// #include "Windows/Synchronization.h" -#include "Windows/PropVariant.h" -#include "Common/Wildcard.h" -#include "Windows/FileName.h" - -#include "FSDrives.h" -#include "RootFolder.h" - -#include "../../PropID.h" - -#include "IFolder.h" - - -// #include "Common/MyInitGuid.h" - - -using namespace NWindows; -using namespace NFile; -using namespace NFind; - -struct CTempFileInfo -{ - UInt32 FileIndex; // index of file in folder - UString RelPath; // Relative path of file from Folder - FString FolderPath; - FString FilePath; - NWindows::NFile::NFind::CFileInfo FileInfo; - bool NeedDelete; - - CTempFileInfo(): FileIndex((UInt32)(Int32)-1), NeedDelete(false) {} - void DeleteDirAndFile() const - { - if (NeedDelete) - { - NWindows::NFile::NDir::DeleteFileAlways(FilePath); - NWindows::NFile::NDir::RemoveDir(FolderPath); - } - } - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const - { - return newFileInfo.Size != FileInfo.Size || - CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0; - } -}; - -struct CFolderLink: public CTempFileInfo -{ - // NWindows::NDLL::CLibrary Library; - CMyComPtr ParentFolder; - bool UsePassword; - UString Password; - bool IsVirtual; - - UString VirtualPath; - CFolderLink(): UsePassword(false), IsVirtual(false) {} - - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const - { - return IsVirtual || CTempFileInfo::WasChanged(newFileInfo); - } - -}; - -UString GetFolderPath(IFolderFolder *folder) -{ - NWindows::NCOM::CPropVariant prop; - if (folder->GetFolderProperty(kpidPath, &prop) == S_OK) - if (prop.vt == VT_BSTR) - return (wchar_t *)prop.bstrVal; - return UString(); -} - -class Utils7zip -{ - - - // - CObjectVector _parentFolders; -// NWindows::NDLL::CLibrary _library; - CMyComPtr _folder; - -public: - Utils7zip(); - - void CloseOpenFolders(); - HRESULT BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted); - - HRESULT OpenParentArchiveFolder(); - - void SetToRootFolder(); - - void LoadFullPath(); - - int LoadItems(); - - int GetNumberOfItems(); - - UString GetItemName(int ind); - - UString _currentFolderPrefix; -}; - -Utils7zip::Utils7zip() -{ - -} - - -void Utils7zip::SetToRootFolder() -{ - _folder.Release(); - // _library.Free(); - CRootFolder *rootFolderSpec = new CRootFolder; - _folder = rootFolderSpec; - rootFolderSpec->Init(); -} - -void Utils7zip::CloseOpenFolders() -{ - while (_parentFolders.Size() > 0) - { - _folder.Release(); - // FIXME _library.Free(); - _folder = _parentFolders.Back().ParentFolder; - // FIXME _library.Attach(_parentFolders.Back().Library.Detach()); - if (_parentFolders.Size() > 1) - OpenParentArchiveFolder(); - _parentFolders.DeleteBack(); - } - // _flatMode = _flatModeForDisk; - _folder.Release(); - // _library.Free(); -} - - -HRESULT Utils7zip::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted) -{ - archiveIsOpened = false; - encrypted = false; - // CDisableTimerProcessing disableTimerProcessing1(*this); - - printf("CPanel::BindToPath(%ls)\n",(const wchar_t *)fullPath); - - if (_parentFolders.Size() > 0) - { - const UString &virtPath = _parentFolders.Back().VirtualPath; - if (fullPath.Left(virtPath.Len()) == virtPath) - { - for (;;) - { - CMyComPtr newFolder; - HRESULT res = _folder->BindToParentFolder(&newFolder); - if (!newFolder || res != S_OK) - break; - _folder = newFolder; - } - UStringVector parts; - SplitPathToParts(fullPath.Ptr(virtPath.Len()), parts); - for (int i = 0; i < parts.Size(); i++) - { - const UString &s = parts[i]; - if ((i == 0 || i == parts.Size() - 1) && s.IsEmpty()) - continue; - CMyComPtr newFolder; - HRESULT res = _folder->BindToFolder(s, &newFolder); - if (!newFolder || res != S_OK) - break; - _folder = newFolder; - } - return S_OK; - } - } - - CloseOpenFolders(); - UString sysPath = fullPath; - CFileInfo fileInfo; - UStringVector reducedParts; - while (!sysPath.IsEmpty()) - { - if (fileInfo.Find(us2fs(sysPath))) - break; - int pos = sysPath.ReverseFind(WCHAR_PATH_SEPARATOR); - if (pos < 0) - sysPath.Empty(); - else - { - if (reducedParts.Size() > 0 || pos < sysPath.Len() - 1) - reducedParts.Add(sysPath.Ptr(pos + 1)); - sysPath = sysPath.Left(pos); - } - } - SetToRootFolder(); - CMyComPtr newFolder; - if (sysPath.IsEmpty()) - { - if (_folder->BindToFolder(fullPath, &newFolder) == S_OK) - _folder = newFolder; - } - else if (fileInfo.IsDir()) - { - NName::NormalizeDirPathPrefix(sysPath); - if (_folder->BindToFolder(sysPath, &newFolder) == S_OK) - _folder = newFolder; - } - else - { - FString dirPrefix, fileName; - NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); - if (_folder->BindToFolder(fs2us(dirPrefix), &newFolder) == S_OK) - { - _folder = newFolder; - LoadFullPath(); - { - HRESULT res = S_FALSE; // FIXME OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted); - if (res != S_FALSE) - { - RINOK(res); - } - /* - if (res == E_ABORT) - return res; - */ - if (res == S_OK) - { - archiveIsOpened = true; - for (int i = reducedParts.Size() - 1; i >= 0; i--) - { - CMyComPtr newFolder; - _folder->BindToFolder(reducedParts[i], &newFolder); - if (!newFolder) - break; - _folder = newFolder; - } - } - } - } - } - return S_OK; -} - -void Utils7zip::LoadFullPath() -{ - _currentFolderPrefix.Empty(); - for (int i = 0; i < _parentFolders.Size(); i++) - { - const CFolderLink &folderLink = _parentFolders[i]; - _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder); - _currentFolderPrefix += folderLink.RelPath; - _currentFolderPrefix += WCHAR_PATH_SEPARATOR; - } - if (_folder) - _currentFolderPrefix += GetFolderPath(_folder); -} - -HRESULT Utils7zip::OpenParentArchiveFolder() -{ - // CDisableTimerProcessing disableTimerProcessing1(*this); - if (_parentFolders.Size() < 2) - return S_OK; - const CFolderLink &folderLinkPrev = _parentFolders[_parentFolders.Size() - 2]; - const CFolderLink &folderLink = _parentFolders.Back(); - NFind::CFileInfo newFileInfo; - if (newFileInfo.Find(folderLink.FilePath)) - { -/* FIXME - if (folderLink.WasChanged(newFileInfo)) - { - UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, 0x03020280, folderLink.RelPath); - if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) - { - if (OnOpenItemChanged(folderLink.FileIndex, folderLink.FilePath, - folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK) - { - ::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE, - 0x03020281, fs2us(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP); - return S_OK; - } - } - } -*/ - } - folderLink.DeleteDirAndFile(); - return S_OK; -} - -int Utils7zip::LoadItems() -{ - return _folder->LoadItems(); -} - -int Utils7zip::GetNumberOfItems() -{ - UInt32 numItems; - _folder->GetNumberOfItems(&numItems); - - return numItems; -} - -UString Utils7zip::GetItemName(int itemIndex) -{ - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) - throw 2723400; - if (prop.vt != VT_BSTR) - throw 2723401; - return prop.bstrVal; -} - - -static Utils7zip * gbl_utils7zip; - -extern int global_use_utf16_conversion; - -int utilZip_init(void) -{ - // FIXME - global_use_utf16_conversion = 1; - - // set the program's current locale from the user's environment variables - // setlocale(LC_ALL,""); - - gbl_utils7zip = new Utils7zip; - - return 0; -} - -int utilZip_setPathSuite(const wchar_t *path) -{ - bool archiveIsOpened, encrypted; - RINOK(gbl_utils7zip->BindToPath(path, UString(), archiveIsOpened, encrypted)); -/* - CMyComPtr folderSetFlatMode; - _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); - if (folderSetFlatMode) - folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); -*/ - RINOK(gbl_utils7zip->LoadItems()); -// RINOK(InitColumns()); - - // OutputDebugString(TEXT("Start Dir\n")); - /* - UInt32 numItems; - _folder->GetNumberOfItems(&numItems); - - for(UInt32 itemIndex=0; itemIndex < ; itemIndex++) - { - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) - throw 2723400; - if (prop.vt != VT_BSTR) - throw 2723401; - UString name = prop.bstrVal; - } - */ -} - -int utilZip_setPath(const wchar_t *path) -{ - return utilZip_setPathSuite(path); -} - -int utilZip_GetNumberOfItems() -{ - return gbl_utils7zip->GetNumberOfItems(); -} - - -UString utilZip_GetItemName(int ind) -{ - return gbl_utils7zip->GetItemName(ind); -} - - -// FIXME -UString LangString(UINT resourceID, UInt32 langID) -{ - return UString(); // FIXME -} - -DWORD_PTR GetRealIconIndex(LPCTSTR path, DWORD attrib, int &iconIndex) -{ - // FIXME - iconIndex = -1; - return -1; -} - -namespace NFsFolder { - - // FIXME - bool wxw_CopyFile(LPCWSTR existingFile, LPCWSTR newFile, bool overwrite) - { - return false; // FIXME wxCopyFile(wxString(existingFile), wxString(newFile), overwrite); - } -} - -int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2) -{ - for (;;) - { - wchar_t c1 = *s1; - wchar_t c2 = *s2; - if ((c1 >= '0' && c1 <= '9') && - (c2 >= '0' && c2 <= '9')) - { - for (; *s1 == '0'; s1++); - for (; *s2 == '0'; s2++); - size_t len1 = 0; - size_t len2 = 0; - for (; (s1[len1] >= '0' && s1[len1] <= '9'); len1++); - for (; (s2[len2] >= '0' && s2[len2] <= '9'); len2++); - if (len1 < len2) return -1; - if (len1 > len2) return 1; - for (; len1 > 0; s1++, s2++, len1--) - { - if (*s1 == *s2) continue; - return (*s1 < *s2) ? -1 : 1; - } - c1 = *s1; - c2 = *s2; - } - s1++; - s2++; - if (c1 != c2) - { - // Probably we need to change the order for special characters like in Explorer. - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); - if (u1 < u2) return -1; - if (u1 > u2) return 1; - } - if (c1 == 0) return 0; - } -} - - -UString LangString(UInt32 langID) -{ - /* FIXME - const wchar_t *s = g_Lang.Get(langID); - if (s) - return s; - */ - return L"FIXME"; // MyLoadString(langID); -} - - diff -Nru p7zip-rar-16.02/CPP/7zip/Q7Zip/util7zip/util7zip.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.pro --- p7zip-rar-16.02/CPP/7zip/Q7Zip/util7zip/util7zip.pro 2015-10-07 09:39:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Q7Zip/util7zip/util7zip.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ - -QT += core gui - -TARGET = util7zip - -TEMPLATE = lib - -CONFIG = staticlib -SOURCES += util7zip.cpp \ -../../../myWindows/wine_date_and_time.cpp \ - ../../../Common/MyString.cpp \ - ../../../Common/MyVector.cpp \ - ../../../Common/IntToString.cpp \ - ../../../Common/NewHandler.cpp \ - ../../../Common/StringConvert.cpp \ - ../../../Common/StringToInt.cpp \ - ../../../Common/UTFConvert.cpp \ - ../../../Common/Wildcard.cpp \ - ../../../Common/MyWindows.cpp \ - ../../../Windows/ErrorMsg.cpp \ - ../../../Windows/FileDir.cpp \ - ../../../Windows/FileFind.cpp \ - ../../../Windows/FileIO.cpp \ - ../../../Windows/FileName.cpp \ - ../../../Windows/PropVariant.cpp \ -../../Common/PropId.cpp \ -../../UI/FileManager/RootFolder.cpp \ -../../UI/FileManager/FSDrives.cpp \ -../../UI/FileManager/FSFolder.cpp \ -../../UI/FileManager/FSFolderCopy.cpp \ -../../UI/FileManager/TextPairs.cpp \ -../../UI/FileManager/ClassDefs.cpp \ - ../../../../C/Alloc.c \ - ../../../../C/Threads.c \ - -# ../../UI/FileManager/LangUtils.cpp \ - - - -INCLUDEPATH += ../../../myWindows -INCLUDEPATH += ../../../ -INCLUDEPATH += ../../../include_windows -INCLUDEPATH += ../../UI/FileManager - -#DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT -DEFINES += UNICODE _UNICODE UNIX_USE_WIN_FILE -DEFINES += LANG NEW_FOLDER_INTERFACE EXTERNAL_CODECS - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/7z_/7z_.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7z_/7z_.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/7z_/7z_.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7z_/7z_.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = 7z - -CONFIG += console -CONFIG -= app_bundle -TEMPLATE = app - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../myWindows \ - ../../../ \ - ../../../include_windows \ - -DEFINES += EXTERNAL_CODECS -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Threads.c \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/7za/7za.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7za/7za.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/7za/7za.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7za/7za.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,251 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = 7za - -CONFIG += console -CONFIG -= app_bundle -TEMPLATE = app - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../myWindows \ - ../../../ \ - ../../../include_windows \ - -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/7zr/7zr.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7zr/7zr.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/7zr/7zr.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/7zr/7zr.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = 7zr - -CONFIG += console -CONFIG -= app_bundle -TEMPLATE = app - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../myWindows \ - ../../../ \ - ../../../include_windows \ - -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += _NO_CRYPTO -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Sha256.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = 7z - -CONFIG += dll -TEMPLATE = lib - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../myWindows \ - ../../../ \ - ../../../include_windows \ - -DEFINES += EXTERNAL_CODECS -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/7zBuf2.c \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Blake2s.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/ApmHandler.cpp \ - ../../../../CPP/7zip/Archive/ArHandler.cpp \ - ../../../../CPP/7zip/Archive/ArchiveExports.cpp \ - ../../../../CPP/7zip/Archive/ArjHandler.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmIn.cpp \ - ../../../../CPP/7zip/Archive/ComHandler.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/CpioHandler.cpp \ - ../../../../CPP/7zip/Archive/CramfsHandler.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/DllExports2.cpp \ - ../../../../CPP/7zip/Archive/DmgHandler.cpp \ - ../../../../CPP/7zip/Archive/ElfHandler.cpp \ - ../../../../CPP/7zip/Archive/ExtHandler.cpp \ - ../../../../CPP/7zip/Archive/FatHandler.cpp \ - ../../../../CPP/7zip/Archive/FlvHandler.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/GptHandler.cpp \ - ../../../../CPP/7zip/Archive/HandlerCont.cpp \ - ../../../../CPP/7zip/Archive/HfsHandler.cpp \ - ../../../../CPP/7zip/Archive/IhexHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoIn.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp \ - ../../../../CPP/7zip/Archive/LzhHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/MachoHandler.cpp \ - ../../../../CPP/7zip/Archive/MbrHandler.cpp \ - ../../../../CPP/7zip/Archive/MslzHandler.cpp \ - ../../../../CPP/7zip/Archive/MubHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp \ - ../../../../CPP/7zip/Archive/NtfsHandler.cpp \ - ../../../../CPP/7zip/Archive/PeHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/QcowHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/RarHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp \ - ../../../../CPP/7zip/Archive/RpmHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/SquashfsHandler.cpp \ - ../../../../CPP/7zip/Archive/SwfHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfIn.cpp \ - ../../../../CPP/7zip/Archive/UefiHandler.cpp \ - ../../../../CPP/7zip/Archive/VdiHandler.cpp \ - ../../../../CPP/7zip/Archive/VhdHandler.cpp \ - ../../../../CPP/7zip/Archive/VmdkHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimIn.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimRegister.cpp \ - ../../../../CPP/7zip/Archive/XarHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/LzhDecoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzmsDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Compress/XpressDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibEncoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha256.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/Rar20Crypto.cpp \ - ../../../../CPP/7zip/Crypto/Rar5Aes.cpp \ - ../../../../CPP/7zip/Crypto/RarAes.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/DynLimBuf.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyMap.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/MyXml.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantUtils.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/Lzham/Lzham.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Lzham/Lzham.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/Lzham/Lzham.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Lzham/Lzham.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = Lzham - -CONFIG += dll -TEMPLATE = lib - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../../CPP/7zip/Compress/Lzham/include \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp \ - ../../../myWindows \ - ../../../ \ - ../../../../ \ - ../../../include_windows \ - -DEFINES += EXTERNAL_CODECS -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/Alloc.c \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../../CPP/7zip/Compress/Lzham/LzhamRegister.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/Rar/Rar.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Rar/Rar.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/Rar/Rar.pro 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/Rar/Rar.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ - -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = Rar - -CONFIG += dll -TEMPLATE = lib - -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -INCLUDEPATH = \ - ../../../myWindows \ - ../../../ \ - ../../../include_windows \ - -DEFINES += EXTERNAL_CODECS -DEFINES += _FILE_OFFSET_BITS=64 -DEFINES += _LARGEFILE_SOURCE -DEFINES += _REENTRANT -DEFINES += ENV_UNIX -DEFINES += BREAK_HANDLER -DEFINES += UNICODE -DEFINES += _UNICODE -DEFINES += UNIX_USE_WIN_FILE - -SOURCES += \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Rar1Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar3Decoder.cpp \ - ../../../../CPP/7zip/Compress/Rar3Vm.cpp \ - ../../../../CPP/7zip/Compress/Rar5Decoder.cpp \ - ../../../../CPP/7zip/Compress/RarCodecsRegister.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/all.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/all.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/all.pro 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/all.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - -TEMPLATE = subdirs -SUBDIRS = 7za \ - 7zr \ - 7z_ \ - Format7zFree \ - Rar \ - Lzham \ - test_lib - diff -Nru p7zip-rar-16.02/CPP/7zip/QMAKE/test_lib/test_lib.pro p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/test_lib/test_lib.pro --- p7zip-rar-16.02/CPP/7zip/QMAKE/test_lib/test_lib.pro 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/QMAKE/test_lib/test_lib.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ - -QT -= core \ - gui -TARGET = test_lib -CONFIG += console -CONFIG -= app_bundle -TEMPLATE = app - -SOURCES += \ - ../../../myWindows/wine_date_and_time.cpp \ - ../../../myWindows/myAddExeFlag.cpp \ - ../../../myWindows/mySplitCommandLine.cpp \ - ../../../myWindows/wine_GetXXXDefaultLangID.cpp \ - ../../../myWindows/test_lib.cpp \ - ../../../Common/MyString.cpp \ - ../../../Common/MyWindows.cpp \ - ../../../Common/MyVector.cpp \ - ../../../../C/CpuArch.c \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c - - -INCLUDEPATH = ../../../myWindows \ - ../../../ \ - ../../../include_windows - -DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _REENTRANT ENV_UNIX BREAK_HANDLER UNICODE _UNICODE - -macx: LIBS += -framework CoreFoundation - diff -Nru p7zip-rar-16.02/CPP/7zip/Sha1.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha1.mak --- p7zip-rar-16.02/CPP/7zip/Sha1.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha1.mak 2021-03-09 08:04:37.000000000 +0000 @@ -0,0 +1,13 @@ +COMMON_OBJS = $(COMMON_OBJS) \ + $O\Sha1Prepare.obj + +C_OBJS = $(C_OBJS) \ + $O\Sha1.obj + +!IF defined(USE_C_SHA) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ + $O\Sha1Opt.obj +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +ASM_OBJS = $(ASM_OBJS) \ + $O\Sha1Opt.obj +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/Sha256.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha256.mak --- p7zip-rar-16.02/CPP/7zip/Sha256.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sha256.mak 2021-03-09 08:04:43.000000000 +0000 @@ -0,0 +1,13 @@ +COMMON_OBJS = $(COMMON_OBJS) \ + $O\Sha256Prepare.obj + +C_OBJS = $(C_OBJS) \ + $O\Sha256.obj + +!IF defined(USE_C_SHA) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ + $O\Sha256Opt.obj +!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +ASM_OBJS = $(ASM_OBJS) \ + $O\Sha256Opt.obj +!ENDIF diff -Nru p7zip-rar-16.02/CPP/7zip/Sort.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sort.mak --- p7zip-rar-16.02/CPP/7zip/Sort.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/Sort.mak 2025-07-02 08:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +!IF defined(USE_NO_ASM) || defined(USE_C_SORT) || "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" +C_OBJS = $(C_OBJS) \ +!ELSE +ASM_OBJS = $(ASM_OBJS) \ +!ENDIF + $O\Sort.obj diff -Nru p7zip-rar-16.02/CPP/7zip/SubBuild.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/SubBuild.mak --- p7zip-rar-16.02/CPP/7zip/SubBuild.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/SubBuild.mak 2005-07-30 13:20:28.000000000 +0000 @@ -0,0 +1,3 @@ + cd $(@D) + $(MAKE) -nologo $(TARGETS) + cd .. diff -Nru p7zip-rar-16.02/CPP/7zip/TEST/TestUI/TestUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/TestUI.cpp --- p7zip-rar-16.02/CPP/7zip/TEST/TestUI/TestUI.cpp 2014-12-29 19:51:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/TestUI.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,565 +0,0 @@ -// wxGUI.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#ifdef __WXMAC__ - -#define UInt32 max_UInt32 -#include -#undef UInt32 - -#endif - -#define static const -#include "../GUI/p7zip_32.xpm" -#undef static - -#undef ACTIVATE_DIALOG_TESTS - -#include "../../UI/FileManager/PasswordDialog.h" - -#include "Windows/Window.h" -#include "Windows/Control/DialogImpl.h" - -wxWindow * g_window=0; - -static pthread_t g_main_thread; - -bool is_main_thread(void) -{ - return ( g_main_thread == pthread_self() ); -} - -void verify_main_thread(void) -{ - if ( ! is_main_thread() ) - { - printf("verify_main_thread-wxGUI\n"); - abort(); - } -} - - -struct CIDLangPair -{ - int ControlID; - UInt32 LangID; -}; - - -void LangSetWindowText(HWND window, UInt32 langID) -{ - -} - -void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems) -{ - -} - - -void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems) -{ - -} - -#if 0 - -int Main1(int argc,TCHAR **argv); - -#include "Windows/Registry.h" -using namespace NWindows; -using namespace NRegistry; - - -#include "Common/StringConvert.h" -#include "Windows/FileDir.h" -#include "Windows/Synchronization.h" - -#include "ExtractRes.h" -#include "../Explorer/MyMessages.h" - -#include "ExtractGUI.h" -#include "UpdateGUI.h" -#include "BenchmarkDialog.h" -#include "../FileManager/RegistryUtils.h" - -using namespace NWindows; -using namespace NFile; - -////////////////////////////// TRIES /////////////////////////////////// - -#ifdef ACTIVATE_DIALOG_TESTS -static void ErrorMessage(const wchar_t *message) -{ - MessageBox(0,message, wxT("7-Zip GUI"),wxICON_ERROR); -} - -#include "../FileManager/PasswordDialog.h" -#include "../FileManager/MessagesDialog.h" -#include "../FileManager/OverwriteDialog.h" -#include "Windows/Thread.h" - -void testCMessagesDialog() -{ - UStringVector Messages; - - Messages.Add(L"message 1"); - Messages.Add(L"message 2"); - Messages.Add(L"message 3"); - Messages.Add(L"message 4"); - Messages.Add(L"message 5"); - Messages.Add(L"message 6"); - Messages.Add(L"message 7"); - Messages.Add(L"message 8"); - Messages.Add(L"message 9"); - - CMessagesDialog messagesDialog; - messagesDialog.Messages = &Messages; - int ret = messagesDialog.Create( 0 ); // ParentWindow - - if (ret == IDOK) myErrorMsg(wxT("CMessagesDialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("CMessagesDialog => IDCANCEL")); - else myErrorMsg(wxT("CMessagesDialog => ?")); - -} - -void testCOverwriteDialog() -{ -SYSTEMTIME systemTime; -GetSystemTime( &systemTime ); - - -const wchar_t *existName = L"existName"; -FILETIME data_existTime; -FILETIME *existTime = &data_existTime ; -UInt64 data_existSize = 1234; -UInt64 *existSize = &data_existSize; -const wchar_t *newName = L"newName"; -FILETIME data_newTime; -FILETIME *newTime = &data_newTime; -UInt64 data_newSize = 45678; -UInt64 *newSize = &data_newSize; -Int32 data_answer=0; -Int32 *answer = &data_answer; - -SystemTimeToFileTime( &systemTime , &data_existTime); -SystemTimeToFileTime( &systemTime , &data_newTime); - - COverwriteDialog dialog; - - dialog.OldFileInfo.Time = *existTime; - dialog.OldFileInfo.TimeIsDefined = true; // FIXME : look again at the sample ! - - dialog.OldFileInfo.SizeIsDefined = (existSize != NULL); - if (dialog.OldFileInfo.SizeIsDefined) - dialog.OldFileInfo.Size = *existSize; - dialog.OldFileInfo.Name = existName; - - if (newTime == 0) - dialog.NewFileInfo.TimeIsDefined = false; - else - { - dialog.NewFileInfo.TimeIsDefined = true; - dialog.NewFileInfo.Time = *newTime; - } - - dialog.NewFileInfo.SizeIsDefined = (newSize != NULL); - if (dialog.NewFileInfo.SizeIsDefined) - dialog.NewFileInfo.Size = *newSize; - dialog.NewFileInfo.Name = newName; - - /* - NOverwriteDialog::NResult::EEnum writeAnswer = - NOverwriteDialog::Execute(oldFileInfo, newFileInfo); - */ - INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z - - switch(writeAnswer) - { - case IDCANCEL: myErrorMsg(wxT("COverwriteDialog => IDCANCEL")); break; - case IDNO: myErrorMsg(wxT("COverwriteDialog => IDNO")); break; - case IDC_BUTTON_OVERWRITE_NO_TO_ALL: myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_NO_TO_ALL")); break; - case IDC_BUTTON_OVERWRITE_YES_TO_ALL:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_YES_TO_ALL")); break; - case IDC_BUTTON_OVERWRITE_AUTO_RENAME:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_AUTO_RENAME")); break; - case IDYES: myErrorMsg(wxT("COverwriteDialog => IDYES")); break; - default: myErrorMsg(wxT("COverwriteDialog => default")); break; - } -} - -struct CThreadProgressDialog -{ - CProgressDialog * ProgressDialog; - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadProgressDialog *)param)->Result = ((CThreadProgressDialog *)param)->Process(); - return 0; - } - HRESULT Result; - HRESULT Process() - { - Sleep(1000); - int total = 1000; - - ProgressDialog->ProgressSynch.SetTitleFileName(L"SetTitleFileName"); - ProgressDialog->ProgressSynch.SetNumFilesTotal(100); - ProgressDialog->ProgressSynch.SetNumFilesCur(1); - ProgressDialog->ProgressSynch.SetProgress(total, 0); - // ProgressDialog.ProgressSynch.SetRatioInfo(inSize, outSize); - // ProgressDialog.ProgressSynch.SetCurrentFileName(name); - - ProgressDialog->ProgressSynch.SetPos(total/10); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File1"); - Sleep(1000); - ProgressDialog->ProgressSynch.SetPos(total/2); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File2"); - Sleep(1000); - ProgressDialog->ProgressSynch.SetPos(total); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File3"); - Sleep(1000); - ProgressDialog->MyClose(); - return 0; - } -}; - -void testCProgressDialog() -{ - CProgressDialog ProgressDialog; - - CThreadProgressDialog benchmarker; - benchmarker.ProgressDialog = &ProgressDialog; - NWindows::CThread thread; - thread.Create(CThreadProgressDialog::MyThreadFunction, &benchmarker); - - // void StartProgressDialog(const UString &title) - int ret = ProgressDialog.Create(L"testCProgressDialog", 0); - - if (ret == IDOK) myErrorMsg(wxT("CProgressDialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("CProgressDialog => IDCANCEL")); - else myErrorMsg(wxT("CProgressDialog => ?")); - -} - -void testDialog(int num) -{ - NWindows::NControl::CModalDialog dialog; - - printf("Generic Dialog(%d)\n",num); - int ret = dialog.Create(num, 0); - if (ret == IDOK) myErrorMsg(wxT("Generic Dialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("Generic Dialog => IDCANCEL")); - else myErrorMsg(wxT("Generic Dialog => ?")); -} - -void testMessageBox() -{ - int ret = MessageBoxW(0, L"test yes/no/cancel", - L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL); - if (ret == IDYES) myErrorMsg(wxT("MessageBoxW => IDYES")); - else if (ret == IDNO) myErrorMsg(wxT("MessageBoxW => IDNO")); - else if (ret == IDCANCEL) myErrorMsg(wxT("MessageBoxW => IDCANCEL")); - else myErrorMsg(wxT("MessageBoxW => ?")); -} - -static void testRegistry() -{ - SaveRegLang(L"fr"); - - UString langFile; - ReadRegLang(langFile); - - printf("testRegistry : -%ls-\n",(const wchar_t *)langFile); -} - - -int Main2(int argc,TCHAR **argv); - -int Main3(int argc,wxChar **argv) -{ - testRegistry(); - - int num = -1; - - if (argc >=2 ) - { - num = argv[1][0] - L'0'; - } - printf("num=%d\n",num); - - - switch(num) - { - case 0: - { - TCHAR **argv2 = (TCHAR **)calloc(argc,sizeof(*argv)); - - argv2[0] = argv[0]; - for(int i = 2; i < argc; i++) argv2[i-1] = argv[i]; - - return Main2(argc-1,argv2); - } - // TODO Benchmark - // TODO CCompressDialog - // TODO CExtractDialog ? - case 1 : testCMessagesDialog(); break; - case 2 : testCOverwriteDialog(); break; - case 3 : testCPasswordDialog(); break; - case 4 : testCProgressDialog(); break; - case 5 : testMessageBox(); break; - case 9 : - if (argc >= 3) - { - AString str = GetAnsiString(argv[2]); - int num = atoi((const char*)str); - testDialog(num); - } - else - { - printf("usage : 7zG 9 \n"); - } - break; - default : - printf("usage : 7zG number\n"); - - }; - - return 0; -} - -#endif // ACTIVATE_DIALOG_TESTS - -////////////////////////////////// - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" // global_use_utf16_conversion - -void mySplitCommandLineW(int numArguments, TCHAR **arguments,UStringVector &parts) { - - parts.Clear(); - for(int ind=0;ind < numArguments; ind++) { - UString tmp = arguments[ind]; - // tmp.Trim(); " " is a valid filename ... - if (!tmp.IsEmpty()) { - parts.Add(tmp); -// DEBUG printf("ARG %d : '%ls'\n",ind,(const wchar_t *)tmp); - } - } -} - -#endif - -void myErrorMsg(const wchar_t *message) -{ - MessageBox(0,message, wxT("Message"),wxICON_ERROR); -} - - -void testCPasswordDialog() -{ - CPasswordDialog dialog; - - int ret = dialog.Create(0); - if (ret == IDOK) { - UString Password = dialog.Password; - UString msg = wxT("CPasswordDialog => IDOK password=\""); - msg += Password; - msg += wxT("\""); - myErrorMsg(msg); - } - else if (ret == IDCANCEL) myErrorMsg(wxT("CPasswordDialog => IDCANCEL")); - else myErrorMsg(wxT("CPasswordDialog => ?")); - -} - - -int Main3(int argc,wxChar **argv) -{ - testCPasswordDialog(); -/* - testRegistry(); - - int num = -1; - - if (argc >=2 ) - { - num = argv[1][0] - L'0'; - } - printf("num=%d\n",num); - - - switch(num) - { - case 0: - { - TCHAR **argv2 = (TCHAR **)calloc(argc,sizeof(*argv)); - - argv2[0] = argv[0]; - for(int i = 2; i < argc; i++) argv2[i-1] = argv[i]; - - return Main2(argc-1,argv2); - } - // TODO Benchmark - // TODO CCompressDialog - // TODO CExtractDialog ? - case 1 : testCMessagesDialog(); break; - case 2 : testCOverwriteDialog(); break; - case 3 : testCPasswordDialog(); break; - case 4 : testCProgressDialog(); break; - case 5 : testMessageBox(); break; - case 9 : - if (argc >= 3) - { - AString str = GetAnsiString(argv[2]); - int num = atoi((const char*)str); - testDialog(num); - } - else - { - printf("usage : 7zG 9 \n"); - } - break; - default : - printf("usage : 7zG number\n"); - - }; -*/ - return 0; -} - -// ---------------------------------------------------------------------------- -// private classes -// ---------------------------------------------------------------------------- - -// Define a new frame type -class MyFrame: public wxFrame -{ -public: - // ctor - MyFrame(wxFrame *frame, const wxString& title, int x, int y, int w, int h); - // virtual ~MyFrame(); - - // operations - void WriteText(const wxString& text) { m_txtctrl->WriteText(text); } - -protected: - // callbacks - void OnWorkerEvent(wxCommandEvent& event); -private: - // just some place to put our messages in - wxTextCtrl *m_txtctrl; - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent) - // EVT_IDLE(MyFrame::OnIdle) -END_EVENT_TABLE() - -// My frame constructor -MyFrame::MyFrame(wxFrame *frame, const wxString& title, - int x, int y, int w, int h) - : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)) -{ - this->SetIcon(wxICON(p7zip_32)); - -#if wxUSE_STATUSBAR - CreateStatusBar(2); -#endif // wxUSE_STATUSBAR - - m_txtctrl = new wxTextCtrl(this, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(0, 0), wxTE_MULTILINE | wxTE_READONLY); -} - -void myCreateHandle(int n); - -void MyFrame::OnWorkerEvent(wxCommandEvent& event) -{ - int n = event.GetInt(); - myCreateHandle(n); -} - - -// Define a new application type, each program should derive a class from wxApp -class MyApp : public wxApp -{ -public: - // override base class virtuals - // ---------------------------- - - // this one is called on application startup and is a good place for the app - // initialization (doing it here and not in the ctor allows to have an error - // return: if OnInit() returns false, the application terminates) - virtual bool OnInit(); -}; - -// Create a new application object: this macro will allow wxWidgets to create -// the application object during program execution (it's better than using a -// static object for many reasons) and also implements the accessor function -// wxGetApp() which will return the reference of the right type (i.e. MyApp and -// not wxApp) -IMPLEMENT_APP(MyApp) - -class MyThread : public wxThread -{ - int _argc; - TCHAR **_argv; -public: - MyThread(int argc,TCHAR **argv): wxThread(),_argc(argc), _argv(argv) {} - - // thread execution starts here - virtual void *Entry() - { - int ret = Main3(_argc,_argv); - exit(ret); - } -}; - -// 'Main program' equivalent: the program execution "starts" here -bool MyApp::OnInit() -{ - // don't parse the command-line options ! - // : if ( !wxApp::OnInit() ) return false; - -#ifdef __WXMAC__ -ProcessSerialNumber PSN; -GetCurrentProcess(&PSN); -TransformProcessType(&PSN,kProcessTransformToForegroundApplication); -#endif - -g_main_thread = pthread_self(); - - // DEBUG printf("MAIN Thread : 0x%lx\n",wxThread::GetCurrentId()); - - // Create the main frame window - MyFrame *frame = new MyFrame((wxFrame *)NULL, _T("7-zip Main Window"), 50, 50, 450, 340); - // Don't Show the frame ! - // frame->Show(true); - - g_window = frame; - - SetTopWindow(frame); - - MyThread *thread = new MyThread(wxApp::argc,wxApp::argv); - thread->Create(); // != wxTHREAD_NO_ERROR - thread->Run(); - - // success: wxApp::OnRun() will be called which will enter the main message - // loop and the application will run. If we returned false here, the - // application would exit immediately. - return true; -} - diff -Nru p7zip-rar-16.02/CPP/7zip/TEST/TestUI/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile --- p7zip-rar-16.02/CPP/7zip/TEST/TestUI/makefile 2015-10-03 20:16:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ - -TARGET_FLAGS=\ - -I. \ - `wx-config --unicode=yes --cxxflags` - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LIBS=`wx-config --unicode=yes --libs` $(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/7zip/TEST/TestUI/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile.list --- p7zip-rar-16.02/CPP/7zip/TEST/TestUI/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/TEST/TestUI/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/TestUI$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DLANG \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/TEST/TestUI/TestUI.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Windows/Control/Controls.cpp \ - ../../../../CPP/Windows/Control/Dialog.cpp \ - ../../../../CPP/Windows/Window.cpp \ - -SRCS_C=\ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -TestUI.o : ../../../../CPP/7zip/TEST/TestUI/TestUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/TEST/TestUI/TestUI.cpp -PasswordDialog.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp -PasswordDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -Controls.o : ../../../../CPP/Windows/Control/Controls.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Controls.cpp -Dialog.o : ../../../../CPP/Windows/Control/Dialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Dialog.cpp -Window.o : ../../../../CPP/Windows/Window.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Window.cpp - -OBJS=\ - Threads.o \ - TestUI.o \ - PasswordDialog.o \ - PasswordDialog_rc.o \ - MyString.o \ - MyWindows.o \ - Controls.o \ - Dialog.o \ - Window.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/Agent.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/Agent.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.cpp 2024-10-04 10:00:00.000000000 +0000 @@ -1,1868 +1,1968 @@ -// Agent.cpp - -#include "StdAfx.h" - -#include - -#include "../../../../C/Sort.h" - -#include "../../../Common/ComTry.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariantConv.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/Synchronization.h" -#endif - -#include "../Common/ArchiveExtractCallback.h" -#include "../FileManager/RegistryUtils.h" - -#include "Agent.h" - -using namespace NWindows; - -CCodecs *g_CodecsObj; - -#ifdef EXTERNAL_CODECS - CExternalCodecs g_ExternalCodecs; - CCodecs::CReleaser g_CodecsReleaser; -#else - CMyComPtr g_CodecsRef; -#endif - -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection g_CriticalSection; -#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); -#else -#define MT_LOCK -#endif - -void FreeGlobalCodecs() -{ - MT_LOCK - - #ifdef EXTERNAL_CODECS - if (g_CodecsObj) - { - g_CodecsObj->CloseLibs(); - } - g_CodecsReleaser.Set(NULL); - g_CodecsObj = NULL; - g_ExternalCodecs.ClearAndRelease(); - #else - g_CodecsRef.Release(); - #endif -} - -HRESULT LoadGlobalCodecs() -{ - MT_LOCK - - if (g_CodecsObj) - return S_OK; - - g_CodecsObj = new CCodecs; - - #ifdef EXTERNAL_CODECS - g_ExternalCodecs.GetCodecs = g_CodecsObj; - g_ExternalCodecs.GetHashers = g_CodecsObj; - g_CodecsReleaser.Set(g_CodecsObj); - #else - g_CodecsRef.Release(); - g_CodecsRef = g_CodecsObj; - #endif - - RINOK(g_CodecsObj->Load()); - if (g_CodecsObj->Formats.IsEmpty()) - { - FreeGlobalCodecs(); - return E_NOTIMPL; - } - - #ifdef EXTERNAL_CODECS - RINOK(g_ExternalCodecs.Load()); - #endif - - return S_OK; -} - -STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder) -{ - *agentFolder = this; - return S_OK; -} - -void CAgentFolder::LoadFolder(unsigned proxyDirIndex) -{ - CProxyItem item; - item.DirIndex = proxyDirIndex; - - if (_proxy2) - { - const CProxyDir2 &dir = _proxy2->Dirs[proxyDirIndex]; - FOR_VECTOR (i, dir.Items) - { - item.Index = i; - _items.Add(item); - const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; - if (file.DirIndex >= 0) - LoadFolder(file.DirIndex); - if (_loadAltStreams && file.AltDirIndex >= 0) - LoadFolder(file.AltDirIndex); - } - return; - } - - const CProxyDir &dir = _proxy->Dirs[proxyDirIndex]; - unsigned i; - for (i = 0; i < dir.SubDirs.Size(); i++) - { - item.Index = i; - _items.Add(item); - LoadFolder(dir.SubDirs[i]); - } - - unsigned start = dir.SubDirs.Size(); - for (i = 0; i < dir.SubFiles.Size(); i++) - { - item.Index = start + i; - _items.Add(item); - } -} - -STDMETHODIMP CAgentFolder::LoadItems() -{ - if (!_agentSpec->_archiveLink.IsOpen) - return E_FAIL; - _items.Clear(); - if (_flatMode) - { - LoadFolder(_proxyDirIndex); - if (_proxy2 && _loadAltStreams) - { - if (_proxyDirIndex == k_Proxy2_RootDirIndex) - LoadFolder(k_Proxy2_AltRootDirIndex); - } - } - return S_OK; -} - -STDMETHODIMP CAgentFolder::GetNumberOfItems(UInt32 *numItems) -{ - if (_flatMode) - *numItems = _items.Size(); - else if (_proxy2) - *numItems = _proxy2->Dirs[_proxyDirIndex].Items.Size(); - else - { - const CProxyDir *dir = &_proxy->Dirs[_proxyDirIndex]; - *numItems = dir->SubDirs.Size() + dir->SubFiles.Size(); - } - return S_OK; -} - -#define SET_realIndex_AND_dir \ - unsigned realIndex; const CProxyDir *dir; \ - if (_flatMode) { const CProxyItem &item = _items[index]; dir = &_proxy->Dirs[item.DirIndex]; realIndex = item.Index; } \ - else { dir = &_proxy->Dirs[_proxyDirIndex]; realIndex = index; } - -#define SET_realIndex_AND_dir_2 \ - unsigned realIndex; const CProxyDir2 *dir; \ - if (_flatMode) { const CProxyItem &item = _items[index]; dir = &_proxy2->Dirs[item.DirIndex]; realIndex = item.Index; } \ - else { dir = &_proxy2->Dirs[_proxyDirIndex]; realIndex = index; } - -UString CAgentFolder::GetName(UInt32 index) const -{ - if (_proxy2) - { - SET_realIndex_AND_dir_2 - return _proxy2->Files[dir->Items[realIndex]].Name; - } - SET_realIndex_AND_dir - if (realIndex < dir->SubDirs.Size()) - return _proxy->Dirs[dir->SubDirs[realIndex]].Name; - return _proxy->Files[dir->SubFiles[realIndex - dir->SubDirs.Size()]].Name; -} - -void CAgentFolder::GetPrefix(UInt32 index, UString &prefix) const -{ - if (!_flatMode) - { - prefix.Empty(); - return; - } - - const CProxyItem &item = _items[index]; - unsigned proxyIndex = item.DirIndex; - - if (_proxy2) - { - // that code is unused. 7-Zip gets prefix via GetItemPrefix() . - - unsigned len = 0; - while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs) - { - const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[proxyIndex].ArcIndex]; - len += file.NameLen + 1; - proxyIndex = (file.Parent < 0) ? 0 : _proxy2->Files[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]; - 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); - } - } - else - { - unsigned len = 0; - while (proxyIndex != _proxyDirIndex) - { - const CProxyDir *dir = &_proxy->Dirs[proxyIndex]; - len += dir->NameLen + 1; - proxyIndex = dir->ParentDir; - } - - wchar_t *p = prefix.GetBuf_SetEnd(len) + len; - proxyIndex = item.DirIndex; - while (proxyIndex != _proxyDirIndex) - { - const CProxyDir *dir = &_proxy->Dirs[proxyIndex]; - p--; - *p = WCHAR_PATH_SEPARATOR; - p -= dir->NameLen; - wmemcpy(p, dir->Name, dir->NameLen); - proxyIndex = dir->ParentDir; - } - } -} - -UString CAgentFolder::GetFullPrefix(UInt32 index) const -{ - int foldIndex = _proxyDirIndex; - - if (_flatMode) - foldIndex = _items[index].DirIndex; - - if (_proxy2) - return _proxy2->Dirs[foldIndex].PathPrefix; - else - return _proxy->GetDirPath_as_Prefix(foldIndex); -} - -STDMETHODIMP_(UInt64) CAgentFolder::GetItemSize(UInt32 index) -{ - unsigned arcIndex; - if (_proxy2) - { - SET_realIndex_AND_dir_2 - arcIndex = dir->Items[realIndex]; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - if (item.IsDir()) - { - const CProxyDir2 &itemFolder = _proxy2->Dirs[item.DirIndex]; - if (!_flatMode) - return itemFolder.Size; - } - } - else - { - SET_realIndex_AND_dir - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!_flatMode) - return item.Size; - if (!item.IsLeaf()) - return 0; - arcIndex = item.ArcIndex; - } - else - { - arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; - } - } - NCOM::CPropVariant prop; - _agentSpec->GetArchive()->GetProperty(arcIndex, kpidSize, &prop); - if (prop.vt == VT_UI8) - return prop.uhVal.QuadPart; - else - return 0; -} - -STDMETHODIMP CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - - if (propID == kpidPrefix) - { - if (_flatMode) - { - UString prefix; - GetPrefix(index, prefix); - prop = prefix; - } - } - else if (_proxy2) - { - SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - /* - if (propID == kpidNumAltStreams) - { - if (item.AltDirIndex >= 0) - prop = _proxy2->Dirs[item.AltDirIndex].Items.Size(); - } - else - */ - if (!item.IsDir()) - { - switch (propID) - { - case kpidIsDir: prop = false; break; - case kpidName: prop = item.Name; break; - default: return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); - } - } - else - { - const CProxyDir2 &itemFolder = _proxy2->Dirs[item.DirIndex]; - if (!_flatMode && propID == kpidSize) - prop = itemFolder.Size; - else if (!_flatMode && propID == kpidPackSize) - prop = itemFolder.PackSize; - else switch (propID) - { - case kpidIsDir: prop = true; break; - case kpidNumSubDirs: prop = itemFolder.NumSubDirs; break; - case kpidNumSubFiles: prop = itemFolder.NumSubFiles; break; - case kpidName: prop = item.Name; break; - case kpidCRC: - { - // if (itemFolder.IsLeaf) - if (!item.Ignore) - { - RINOK(_agentSpec->GetArchive()->GetProperty(arcIndex, propID, value)); - } - if (itemFolder.CrcIsDefined && value->vt == VT_EMPTY) - prop = itemFolder.Crc; - break; - } - default: - // if (itemFolder.IsLeaf) - if (!item.Ignore) - return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); - } - } - } - else - { - SET_realIndex_AND_dir - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!_flatMode && propID == kpidSize) - prop = item.Size; - else if (!_flatMode && propID == kpidPackSize) - prop = item.PackSize; - else - switch (propID) - { - case kpidIsDir: prop = true; break; - case kpidNumSubDirs: prop = item.NumSubDirs; break; - case kpidNumSubFiles: prop = item.NumSubFiles; break; - case kpidName: prop = item.Name; break; - case kpidCRC: - { - if (item.IsLeaf()) - { - RINOK(_agentSpec->GetArchive()->GetProperty(item.ArcIndex, propID, value)); - } - if (item.CrcIsDefined && value->vt == VT_EMPTY) - prop = item.Crc; - break; - } - default: - if (item.IsLeaf()) - return _agentSpec->GetArchive()->GetProperty(item.ArcIndex, propID, value); - } - } - else - { - unsigned arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; - switch (propID) - { - case kpidIsDir: prop = false; break; - case kpidName: prop = _proxy->Files[arcIndex].Name; break; - default: - return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); - } - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static UInt64 GetUInt64Prop(IInArchive *archive, UInt32 index, PROPID propID) -{ - NCOM::CPropVariant prop; - if (archive->GetProperty(index, propID, &prop) != S_OK) - throw 111233443; - UInt64 v = 0; - if (ConvertPropVariantToUInt64(prop, v)) - return v; - return 0; -} - -STDMETHODIMP CAgentFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len) -{ - if (_proxy2) - { - SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - *name = item.Name; - *len = item.NameLen; - return S_OK; - } - else - { - SET_realIndex_AND_dir - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; - *name = item.Name; - *len = item.NameLen; - return S_OK; - } - else - { - const CProxyFile &item = _proxy->Files[dir->SubFiles[realIndex - dir->SubDirs.Size()]]; - *name = item.Name; - *len = item.NameLen; - return S_OK; - } - } -} - -STDMETHODIMP CAgentFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len) -{ - *name = 0; - *len = 0; - if (!_flatMode) - return S_OK; - - if (_proxy2) - { - const CProxyItem &item = _items[index]; - const UString &s = _proxy2->Dirs[item.DirIndex].PathPrefix; - unsigned baseLen = _proxy2->Dirs[_proxyDirIndex].PathPrefix.Len(); - if (baseLen <= s.Len()) - { - *name = (const wchar_t *)s + baseLen; - *len = s.Len() - baseLen; - } - else - { - return E_FAIL; - // throw 111l; - } - } - return S_OK; -} - -static int CompareRawProps(IArchiveGetRawProps *rawProps, int arcIndex1, int arcIndex2, PROPID propID) -{ - // if (propID == kpidSha1) - if (rawProps) - { - const void *p1, *p2; - UInt32 size1, size2; - UInt32 propType1, propType2; - HRESULT res1 = rawProps->GetRawProp(arcIndex1, propID, &p1, &size1, &propType1); - HRESULT res2 = rawProps->GetRawProp(arcIndex2, propID, &p2, &size2, &propType2); - if (res1 == S_OK && res2 == S_OK) - { - for (UInt32 i = 0; i < size1 && i < size2; i++) - { - Byte b1 = ((const Byte *)p1)[i]; - Byte b2 = ((const Byte *)p2)[i]; - if (b1 < b2) return -1; - if (b1 > b2) return 1; - } - if (size1 < size2) return -1; - if (size1 > size2) return 1; - return 0; - } - } - return 0; -} - -// returns pointer to extension including '.' - -static const wchar_t *GetExtension(const wchar_t *name) -{ - for (const wchar_t *dotPtr = NULL;; name++) - { - wchar_t c = *name; - if (c == 0) - return dotPtr ? dotPtr : name; - if (c == '.') - dotPtr = name; - } -} - -int CAgentFolder::CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw) -{ - unsigned realIndex1, realIndex2; - const CProxyDir2 *dir1, *dir2; - - if (_flatMode) - { - const CProxyItem &item1 = _items[index1]; - const CProxyItem &item2 = _items[index2]; - dir1 = &_proxy2->Dirs[item1.DirIndex]; - dir2 = &_proxy2->Dirs[item2.DirIndex]; - realIndex1 = item1.Index; - realIndex2 = item2.Index; - } - else - { - dir2 = dir1 = &_proxy2->Dirs[_proxyDirIndex]; - realIndex1 = index1; - realIndex2 = index2; - } - - UInt32 arcIndex1; - UInt32 arcIndex2; - bool isDir1, isDir2; - arcIndex1 = dir1->Items[realIndex1]; - arcIndex2 = dir2->Items[realIndex2]; - const CProxyFile2 &prox1 = _proxy2->Files[arcIndex1]; - const CProxyFile2 &prox2 = _proxy2->Files[arcIndex2]; - - if (propID == kpidName) - { - return CompareFileNames_ForFolderList(prox1.Name, prox2.Name); - } - - if (propID == kpidPrefix) - { - if (!_flatMode) - return 0; - return CompareFileNames_ForFolderList( - _proxy2->Dirs[_items[index1].DirIndex].PathPrefix, - _proxy2->Dirs[_items[index2].DirIndex].PathPrefix); - } - - if (propID == kpidExtension) - { - return CompareFileNames_ForFolderList( - GetExtension(prox1.Name), - GetExtension(prox2.Name)); - } - - isDir1 = prox1.IsDir(); - isDir2 = prox2.IsDir(); - - if (propID == kpidIsDir) - { - if (isDir1 == isDir2) - return 0; - return isDir1 ? -1 : 1; - } - - const CProxyDir2 *proxFolder1 = NULL; - const CProxyDir2 *proxFolder2 = NULL; - if (isDir1) proxFolder1 = &_proxy2->Dirs[prox1.DirIndex]; - if (isDir2) proxFolder2 = &_proxy2->Dirs[prox2.DirIndex]; - - if (propID == kpidNumSubDirs) - { - UInt32 n1 = 0; - UInt32 n2 = 0; - if (isDir1) n1 = proxFolder1->NumSubDirs; - if (isDir2) n2 = proxFolder2->NumSubDirs; - return MyCompare(n1, n2); - } - - if (propID == kpidNumSubFiles) - { - UInt32 n1 = 0; - UInt32 n2 = 0; - if (isDir1) n1 = proxFolder1->NumSubFiles; - if (isDir2) n2 = proxFolder2->NumSubFiles; - return MyCompare(n1, n2); - } - - if (propID == kpidSize) - { - UInt64 n1, n2; - if (isDir1) - n1 = _flatMode ? 0 : proxFolder1->Size; - else - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidSize); - if (isDir2) - n2 = _flatMode ? 0 : proxFolder2->Size; - else - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidSize); - return MyCompare(n1, n2); - } - - if (propID == kpidPackSize) - { - UInt64 n1, n2; - if (isDir1) - n1 = _flatMode ? 0 : proxFolder1->PackSize; - else - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidPackSize); - if (isDir2) - n2 = _flatMode ? 0 : proxFolder2->PackSize; - else - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidPackSize); - return MyCompare(n1, n2); - } - - if (propID == kpidCRC) - { - UInt64 n1, n2; - if (!isDir1 || !prox1.Ignore) - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidCRC); - else - n1 = proxFolder1->Crc; - if (!isDir2 || !prox2.Ignore) - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidCRC); - else - n2 = proxFolder2->Crc; - return MyCompare(n1, n2); - } - - if (propIsRaw) - return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID); - - NCOM::CPropVariant prop1, prop2; - // Name must be first property - GetProperty(index1, propID, &prop1); - GetProperty(index2, propID, &prop2); - if (prop1.vt != prop2.vt) - { - return MyCompare(prop1.vt, prop2.vt); - } - if (prop1.vt == VT_BSTR) - { - return _wcsicmp(prop1.bstrVal, prop2.bstrVal); - } - return prop1.Compare(prop2); -} - -STDMETHODIMP_(Int32) CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw) -{ - try { - if (_proxy2) - return CompareItems2(index1, index2, propID, propIsRaw); - - unsigned realIndex1, realIndex2; - const CProxyDir *dir1, *dir2; - - if (_flatMode) - { - const CProxyItem &item1 = _items[index1]; - const CProxyItem &item2 = _items[index2]; - dir1 = &_proxy->Dirs[item1.DirIndex]; - dir2 = &_proxy->Dirs[item2.DirIndex]; - realIndex1 = item1.Index; - realIndex2 = item2.Index; - } - else - { - dir2 = dir1 = &_proxy->Dirs[_proxyDirIndex]; - realIndex1 = index1; - realIndex2 = index2; - } - - if (propID == kpidPrefix) - { - if (!_flatMode) - return 0; - UString prefix1, prefix2; - GetPrefix(index1, prefix1); - GetPrefix(index2, prefix2); - return CompareFileNames_ForFolderList(prefix1, prefix2); - } - - UInt32 arcIndex1; - UInt32 arcIndex2; - - const CProxyDir *proxFolder1 = NULL; - const CProxyDir *proxFolder2 = NULL; - - if (realIndex1 < dir1->SubDirs.Size()) - { - proxFolder1 = &_proxy->Dirs[dir1->SubDirs[realIndex1]]; - arcIndex1 = proxFolder1->ArcIndex; - } - else - arcIndex1 = dir1->SubFiles[realIndex1 - dir1->SubDirs.Size()]; - - if (realIndex2 < dir2->SubDirs.Size()) - { - proxFolder2 = &_proxy->Dirs[dir2->SubDirs[realIndex2]]; - arcIndex2 = proxFolder2->ArcIndex; - } - else - arcIndex2 = dir2->SubFiles[realIndex2 - dir2->SubDirs.Size()]; - - if (propID == kpidName) - return CompareFileNames_ForFolderList( - proxFolder1 ? proxFolder1->Name : _proxy->Files[arcIndex1].Name, - proxFolder2 ? proxFolder2->Name : _proxy->Files[arcIndex2].Name); - - if (propID == kpidExtension) - return CompareFileNames_ForFolderList( - GetExtension(proxFolder1 ? proxFolder1->Name : _proxy->Files[arcIndex1].Name), - GetExtension(proxFolder2 ? proxFolder2->Name : _proxy->Files[arcIndex2].Name)); - - if (propID == kpidIsDir) - { - if (proxFolder1) - return proxFolder2 ? 0 : -1; - return proxFolder2 ? 1 : 0; - } - - if (propID == kpidNumSubDirs) - { - UInt32 n1 = 0; - UInt32 n2 = 0; - if (proxFolder1) n1 = proxFolder1->NumSubDirs; - if (proxFolder2) n2 = proxFolder2->NumSubDirs; - return MyCompare(n1, n2); - } - - if (propID == kpidNumSubFiles) - { - UInt32 n1 = 0; - UInt32 n2 = 0; - if (proxFolder1) n1 = proxFolder1->NumSubFiles; - if (proxFolder2) n2 = proxFolder2->NumSubFiles; - return MyCompare(n1, n2); - } - - if (propID == kpidSize) - { - UInt64 n1, n2; - if (proxFolder1) - n1 = _flatMode ? 0 : proxFolder1->Size; - else - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidSize); - if (proxFolder2) - n2 = _flatMode ? 0 : proxFolder2->Size; - else - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidSize); - return MyCompare(n1, n2); - } - - if (propID == kpidPackSize) - { - UInt64 n1, n2; - if (proxFolder1) - n1 = _flatMode ? 0 : proxFolder1->PackSize; - else - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidPackSize); - if (proxFolder2) - n2 = _flatMode ? 0 : proxFolder2->PackSize; - else - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidPackSize); - return MyCompare(n1, n2); - } - - if (propID == kpidCRC) - { - UInt64 n1, n2; - if (proxFolder1 && !proxFolder1->IsLeaf()) - n1 = proxFolder1->Crc; - else - n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidCRC); - if (proxFolder2 && !proxFolder2->IsLeaf()) - n2 = proxFolder2->Crc; - else - n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidCRC); - return MyCompare(n1, n2); - } - - if (propIsRaw) - { - bool isVirt1 = (proxFolder1 && !proxFolder1->IsLeaf()); - bool isVirt2 = (proxFolder2 && !proxFolder2->IsLeaf()); - if (isVirt1) - return isVirt2 ? 0 : -1; - if (isVirt2) - return 1; - return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID); - } - - NCOM::CPropVariant prop1, prop2; - // Name must be first property - GetProperty(index1, propID, &prop1); - GetProperty(index2, propID, &prop2); - if (prop1.vt != prop2.vt) - { - return MyCompare(prop1.vt, prop2.vt); - } - if (prop1.vt == VT_BSTR) - { - return _wcsicmp(prop1.bstrVal, prop2.bstrVal); - } - return prop1.Compare(prop2); - - } catch(...) { return 0; } -} - -HRESULT CAgentFolder::BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder) -{ - /* - CMyComPtr parentFolder; - - if (_proxy2) - { - const CProxyDir2 &dir = _proxy2->Dirs[proxyDirIndex]; - int par = _proxy2->GetParentFolderOfFile(dir.ArcIndex); - if (par != (int)_proxyDirIndex) - { - RINOK(BindToFolder_Internal(par, &parentFolder)); - } - else - parentFolder = this; - } - else - { - const CProxyDir &dir = _proxy->Dirs[proxyDirIndex]; - if (dir.Parent != (int)_proxyDirIndex) - { - RINOK(BindToFolder_Internal(dir.Parent, &parentFolder)); - } - else - parentFolder = this; - } - */ - CAgentFolder *folderSpec = new CAgentFolder; - CMyComPtr agentFolder = folderSpec; - folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); - *resultFolder = agentFolder.Detach(); - return S_OK; -} - -STDMETHODIMP CAgentFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - if (_proxy2) - { - SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - if (!item.IsDir()) - return E_INVALIDARG; - return BindToFolder_Internal(item.DirIndex, resultFolder); - } - SET_realIndex_AND_dir - if (realIndex >= (UInt32)dir->SubDirs.Size()) - return E_INVALIDARG; - return BindToFolder_Internal(dir->SubDirs[realIndex], resultFolder); - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - if (_proxy2) - { - int index = _proxy2->FindItem(_proxyDirIndex, name, true); - if (index < 0) - return E_INVALIDARG; - return BindToFolder_Internal(_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder); - } - int index = _proxy->FindSubDir(_proxyDirIndex, name); - if (index < 0) - return E_INVALIDARG; - return BindToFolder_Internal(index, resultFolder); - COM_TRY_END -} - - - -// ---------- IFolderAltStreams ---------- - -HRESULT CAgentFolder::BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder) -{ - *resultFolder = NULL; - if (!_proxy2) - return S_OK; - - /* - CMyComPtr parentFolder; - - int par = _proxy2->GetParentFolderOfFile(_proxy2->Dirs[proxyDirIndex].ArcIndex); - if (par != (int)_proxyDirIndex) - { - RINOK(BindToFolder_Internal(par, &parentFolder)); - if (!parentFolder) - return S_OK; - } - else - parentFolder = this; - */ - - CAgentFolder *folderSpec = new CAgentFolder; - CMyComPtr agentFolder = folderSpec; - folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); - *resultFolder = agentFolder.Detach(); - return S_OK; -} - -STDMETHODIMP CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - - *resultFolder = NULL; - - if (!_proxy2) - return S_OK; - - if (_proxy2->IsAltDir(_proxyDirIndex)) - return S_OK; - - { - if (index == (UInt32)(Int32)-1) - { - unsigned altDirIndex; - // IFolderFolder *parentFolder; - - if (_proxyDirIndex == k_Proxy2_RootDirIndex) - { - altDirIndex = k_Proxy2_AltRootDirIndex; - // parentFolder = this; // we want to use Root dir as parent for alt root - } - else - { - unsigned arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - if (item.AltDirIndex < 0) - return S_OK; - altDirIndex = item.AltDirIndex; - // parentFolder = _parentFolder; - } - - CAgentFolder *folderSpec = new CAgentFolder; - CMyComPtr agentFolder = folderSpec; - folderSpec->Init(_proxy, _proxy2, altDirIndex, /* parentFolder, */ _agentSpec); - *resultFolder = agentFolder.Detach(); - return S_OK; - } - - SET_realIndex_AND_dir_2 - unsigned arcIndex = dir->Items[realIndex]; - const CProxyFile2 &item = _proxy2->Files[arcIndex]; - if (item.AltDirIndex < 0) - return S_OK; - return BindToAltStreams_Internal(item.AltDirIndex, resultFolder); - } - - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - - *resultFolder = NULL; - - if (!_proxy2) - return S_OK; - - if (_proxy2->IsAltDir(_proxyDirIndex)) - return S_OK; - - if (name[0] == 0) - return BindToAltStreams((UInt32)(Int32)-1, resultFolder); - - { - const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex]; - FOR_VECTOR (i, dir.Items) - { - const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; - if (file.AltDirIndex >= 0) - if (CompareFileNames(file.Name, name) == 0) - return BindToAltStreams_Internal(file.AltDirIndex, resultFolder); - } - return E_INVALIDARG; - } - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupported) -{ - *isSupported = BoolToInt(false); - - if (!_proxy2) - return S_OK; - - if (_proxy2->IsAltDir(_proxyDirIndex)) - return S_OK; - - unsigned arcIndex; - - if (index == (UInt32)(Int32)-1) - { - if (_proxyDirIndex == k_Proxy2_RootDirIndex) - { - *isSupported = BoolToInt(true); - return S_OK; - } - arcIndex = _proxy2->Dirs[_proxyDirIndex].ArcIndex; - } - else - { - SET_realIndex_AND_dir_2 - arcIndex = dir->Items[realIndex]; - } - - if (_proxy2->Files[arcIndex].AltDirIndex >= 0) - *isSupported = BoolToInt(true); - return S_OK; -} - - -STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - /* - CMyComPtr parentFolder = _parentFolder; - *resultFolder = parentFolder.Detach(); - */ - *resultFolder = NULL; - - unsigned proxyDirIndex; - - if (_proxy2) - { - if (_proxyDirIndex == k_Proxy2_RootDirIndex) - return S_OK; - if (_proxyDirIndex == k_Proxy2_AltRootDirIndex) - proxyDirIndex = k_Proxy2_RootDirIndex; - else - { - const CProxyDir2 &fold = _proxy2->Dirs[_proxyDirIndex]; - const CProxyFile2 &file = _proxy2->Files[fold.ArcIndex]; - int parentIndex = file.Parent; - if (parentIndex < 0) - proxyDirIndex = k_Proxy2_RootDirIndex; - else - proxyDirIndex = _proxy2->Files[parentIndex].DirIndex; - } - } - else - { - int parent = _proxy->Dirs[_proxyDirIndex].ParentDir; - if (parent < 0) - return S_OK; - proxyDirIndex = parent; - } - - CAgentFolder *folderSpec = new CAgentFolder; - CMyComPtr agentFolder = folderSpec; - folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); - *resultFolder = agentFolder.Detach(); - - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream) -{ - CMyComPtr getStream; - _agentSpec->GetArchive()->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); - if (!getStream) - return S_OK; - - UInt32 arcIndex; - if (_proxy2) - { - SET_realIndex_AND_dir_2 - arcIndex = dir->Items[realIndex]; - } - else - { - SET_realIndex_AND_dir - - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!item.IsLeaf()) - return S_OK; - arcIndex = item.ArcIndex; - } - else - arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; - } - return getStream->GetStream(arcIndex, stream); -} - -// static const unsigned k_FirstOptionalProp = 2; - -static const PROPID kProps[] = -{ - kpidNumSubDirs, - kpidNumSubFiles, - - // kpidNumAltStreams, - kpidPrefix -}; - -struct CArchiveItemPropertyTemp -{ - UString Name; - PROPID ID; - VARTYPE Type; -}; - -STDMETHODIMP CAgentFolder::GetNumberOfProperties(UInt32 *numProps) -{ - COM_TRY_BEGIN - RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProps)); - *numProps += ARRAY_SIZE(kProps); - if (!_flatMode) - (*numProps)--; - /* - if (!_agentSpec->ThereIsAltStreamProp) - (*numProps)--; - */ - /* - bool thereIsPathProp = _proxy2 ? - _agentSpec->_proxy2->ThereIsPathProp : - _agentSpec->_proxy->ThereIsPathProp; - */ - - // if there is kpidPath, we change kpidPath to kpidName - // if there is no kpidPath, we add kpidName. - if (!_agentSpec->ThereIsPathProp) - (*numProps)++; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) -{ - COM_TRY_BEGIN - UInt32 numProps; - _agentSpec->GetArchive()->GetNumberOfProperties(&numProps); - - /* - bool thereIsPathProp = _proxy2 ? - _agentSpec->_proxy2->ThereIsPathProp : - _agentSpec->_proxy->ThereIsPathProp; - */ - - if (!_agentSpec->ThereIsPathProp) - { - if (index == 0) - { - *propID = kpidName; - *varType = VT_BSTR; - *name = 0; - return S_OK; - } - index--; - } - - if (index < numProps) - { - RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); - if (*propID == kpidPath) - *propID = kpidName; - } - else - { - index -= numProps; - /* - if (index >= k_FirstOptionalProp) - { - if (!_agentSpec->ThereIsAltStreamProp) - index++; - } - */ - *propID = kProps[index]; - *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; - *name = 0; - } - return S_OK; - COM_TRY_END -} - -static const PROPID kFolderProps[] = -{ - kpidSize, - kpidPackSize, - kpidNumSubDirs, - kpidNumSubFiles, - kpidCRC -}; - -STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - - NWindows::NCOM::CPropVariant prop; - - if (propID == kpidReadOnly) - prop = _agentSpec->IsThereReadOnlyArc(); - else if (_proxy2) - { - const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex]; - if (propID == kpidName) - { - if (dir.ArcIndex >= 0) - prop = _proxy2->Files[dir.ArcIndex].Name; - } - else if (propID == kpidPath) - { - bool isAltStreamFolder = false; - prop = _proxy2->GetDirPath_as_Prefix(_proxyDirIndex, isAltStreamFolder); - } - else switch (propID) - { - case kpidSize: prop = dir.Size; break; - case kpidPackSize: prop = dir.PackSize; break; - case kpidNumSubDirs: prop = dir.NumSubDirs; break; - case kpidNumSubFiles: prop = dir.NumSubFiles; break; - // case kpidName: prop = dir.Name; break; - // case kpidPath: prop = _proxy2->GetFullPathPrefix(_proxyDirIndex); break; - case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break; - case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break; - } - - } - else - { - const CProxyDir &dir = _proxy->Dirs[_proxyDirIndex]; - switch (propID) - { - case kpidSize: prop = dir.Size; break; - case kpidPackSize: prop = dir.PackSize; break; - case kpidNumSubDirs: prop = dir.NumSubDirs; break; - case kpidNumSubFiles: prop = dir.NumSubFiles; break; - case kpidName: prop = dir.Name; break; - case kpidPath: prop = _proxy->GetDirPath_as_Prefix(_proxyDirIndex); break; - case kpidType: prop = UString(L"7-Zip.") + _agentSpec->ArchiveType; break; - case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProps) -{ - *numProps = ARRAY_SIZE(kFolderProps); - return S_OK; -} - -STDMETHODIMP CAgentFolder::GetFolderPropertyInfo IMP_IFolderFolder_GetProp(kFolderProps) - -STDMETHODIMP CAgentFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */) -{ - return E_FAIL; -} - - -STDMETHODIMP CAgentFolder::GetNumRawProps(UInt32 *numProps) -{ - IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); - if (rawProps) - return rawProps->GetNumRawProps(numProps); - *numProps = 0; - return S_OK; -} - -STDMETHODIMP CAgentFolder::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) -{ - IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); - if (rawProps) - return rawProps->GetRawPropInfo(index, name, propID); - return E_FAIL; -} - -STDMETHODIMP CAgentFolder::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); - if (rawProps) - { - unsigned arcIndex; - if (_proxy2) - { - SET_realIndex_AND_dir_2 - arcIndex = dir->Items[realIndex]; - } - else - { - SET_realIndex_AND_dir - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!item.IsLeaf()) - { - *data = NULL; - *dataSize = 0; - *propType = 0; - return S_OK; - } - arcIndex = item.ArcIndex; - } - else - arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; - } - return rawProps->GetRawProp(arcIndex, propID, data, dataSize, propType); - } - *data = NULL; - *dataSize = 0; - *propType = 0; - return S_OK; -} - -STDMETHODIMP CAgentFolder::GetFolderArcProps(IFolderArcProps **object) -{ - CMyComPtr temp = _agentSpec; - *object = temp.Detach(); - return S_OK; -} - -#ifdef NEW_FOLDER_INTERFACE - -STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode) -{ - _flatMode = IntToBool(flatMode); - return S_OK; -} - -#endif - -int CAgentFolder::GetRealIndex(unsigned index) const -{ - if (!_flatMode) - { - if (_proxy2) - return _proxy2->GetRealIndex(_proxyDirIndex, index); - else - return _proxy->GetRealIndex(_proxyDirIndex, index); - } - { - const CProxyItem &item = _items[index]; - if (_proxy2) - { - const CProxyDir2 *dir = &_proxy2->Dirs[item.DirIndex]; - return dir->Items[item.Index]; - } - else - { - const CProxyDir *dir = &_proxy->Dirs[item.DirIndex]; - unsigned realIndex = item.Index; - if (realIndex < dir->SubDirs.Size()) - { - const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!f.IsLeaf()) - return -1; - return f.ArcIndex; - } - return dir->SubFiles[realIndex - dir->SubDirs.Size()]; - } - } -} - -void CAgentFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const -{ - if (!_flatMode) - { - if (_proxy2) - _proxy2->GetRealIndices(_proxyDirIndex, indices, numItems, includeAltStreams, realIndices); - else - _proxy->GetRealIndices(_proxyDirIndex, indices, numItems, realIndices); - return; - } - - realIndices.Clear(); - - for (UInt32 i = 0; i < numItems; i++) - { - const CProxyItem &item = _items[indices[i]]; - if (_proxy2) - { - const CProxyDir2 *dir = &_proxy2->Dirs[item.DirIndex]; - _proxy2->AddRealIndices_of_ArcItem(dir->Items[item.Index], includeAltStreams, realIndices); - continue; - } - UInt32 arcIndex; - { - const CProxyDir *dir = &_proxy->Dirs[item.DirIndex]; - unsigned realIndex = item.Index; - if (realIndex < dir->SubDirs.Size()) - { - if (includeFolderSubItemsInFlatMode) - { - _proxy->AddRealIndices(dir->SubDirs[realIndex], realIndices); - continue; - } - const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; - if (!f.IsLeaf()) - continue; - arcIndex = f.ArcIndex; - } - else - arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; - } - realIndices.Add(arcIndex); - } - - HeapSort(&realIndices.Front(), realIndices.Size()); -} - -STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices, - UInt32 numItems, - Int32 includeAltStreams, - Int32 replaceAltStreamColon, - NExtract::NPathMode::EEnum pathMode, - NExtract::NOverwriteMode::EEnum overwriteMode, - const wchar_t *path, - Int32 testMode, - IFolderArchiveExtractCallback *extractCallback2) -{ - COM_TRY_BEGIN - CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; - CMyComPtr extractCallback = extractCallbackSpec; - UStringVector pathParts; - bool isAltStreamFolder = false; - if (_proxy2) - _proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder); - else - _proxy->GetDirPathParts(_proxyDirIndex, pathParts); - - /* - if (_flatMode) - pathMode = NExtract::NPathMode::kNoPathnames; - */ - - extractCallbackSpec->InitForMulti(false, pathMode, overwriteMode); - - if (extractCallback2) - extractCallback2->SetTotal(_agentSpec->GetArc().GetEstmatedPhySize()); - - FString pathU; - if (path) - { - pathU = us2fs(path); - if (!pathU.IsEmpty()) - { - NFile::NName::NormalizeDirPathPrefix(pathU); - NFile::NDir::CreateComplexDir(pathU); - } - } - - CExtractNtOptions extractNtOptions; - extractNtOptions.AltStreams.Val = IntToBool(includeAltStreams); // change it!!! - extractNtOptions.AltStreams.Def = true; - - extractNtOptions.ReplaceColonForAltStream = IntToBool(replaceAltStreamColon); - - extractCallbackSpec->Init( - extractNtOptions, - NULL, &_agentSpec->GetArc(), - extractCallback2, - false, // stdOutMode - IntToBool(testMode), - pathU, - pathParts, isAltStreamFolder, - (UInt64)(Int64)-1); - - if (_proxy2) - extractCallbackSpec->SetBaseParentFolderIndex(_proxy2->Dirs[_proxyDirIndex].ArcIndex); - - CUIntVector realIndices; - GetRealIndices(indices, numItems, IntToBool(includeAltStreams), - false, // includeFolderSubItemsInFlatMode - realIndices); // - - #ifdef SUPPORT_LINKS - - if (!testMode) - { - RINOK(extractCallbackSpec->PrepareHardLinks(&realIndices)); - } - - #endif - - HRESULT result = _agentSpec->GetArchive()->Extract(&realIndices.Front(), - realIndices.Size(), testMode, extractCallback); - if (result == S_OK) - result = extractCallbackSpec->SetDirsTimes(); - return result; - COM_TRY_END -} - -///////////////////////////////////////// -// CAgent - -CAgent::CAgent(): - _proxy(NULL), - _proxy2(NULL), - _isDeviceFile(false), - _updatePathPrefix_is_AltFolder(false) -{ -} - -CAgent::~CAgent() -{ - if (_proxy) - delete _proxy; - if (_proxy2) - delete _proxy2; -} - -bool CAgent::CanUpdate() const -{ - // FAR plugin uses empty agent to create new archive !!! - if (_archiveLink.Arcs.Size() == 0) - return true; - if (_isDeviceFile) - return false; - if (_archiveLink.Arcs.Size() != 1) - return false; - if (_archiveLink.Arcs[0].ErrorInfo.ThereIsTail) - return false; - return true; -} - -STDMETHODIMP CAgent::Open( - IInStream *inStream, - const wchar_t *filePath, - const wchar_t *arcFormat, - BSTR *archiveType, - IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - _archiveFilePath = filePath; - NFile::NFind::CFileInfo fi; - _isDeviceFile = false; - if (!inStream) - { - if (!fi.Find(us2fs(_archiveFilePath))) - return ::GetLastError(); - if (fi.IsDir()) - return E_FAIL; - _isDeviceFile = fi.IsDevice; - } - CArcInfoEx archiverInfo0, archiverInfo1; - - RINOK(LoadGlobalCodecs()); - - CObjectVector types; - if (!ParseOpenTypes(*g_CodecsObj, arcFormat, types)) - return S_FALSE; - - /* - CObjectVector optProps; - if (Read_ShowDeleted()) - { - COptionalOpenProperties &optPair = optProps.AddNew(); - optPair.FormatName = L"ntfs"; - // optPair.Props.AddNew().Name = L"LS"; - optPair.Props.AddNew().Name = L"LD"; - } - */ - - COpenOptions options; - options.props = NULL; - options.codecs = g_CodecsObj; - options.types = &types; - CIntVector exl; - options.excludedFormats = &exl; - options.stdInMode = false; - options.stream = inStream; - options.filePath = _archiveFilePath; - options.callback = openArchiveCallback; - - RINOK(_archiveLink.Open(options)); - - CArc &arc = _archiveLink.Arcs.Back(); - if (!inStream) - { - arc.MTimeDefined = !fi.IsDevice; - arc.MTime = fi.MTime; - } - - ArchiveType = GetTypeOfArc(arc); - if (archiveType) - { - RINOK(StringToBstr(ArchiveType, archiveType)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - if (_proxy2) - { - delete _proxy2; - _proxy2 = NULL; - } - if (_proxy) - { - delete _proxy; - _proxy = NULL; - } - - CObjectVector incl; - CIntVector exl; - - COpenOptions options; - options.props = NULL; - options.codecs = g_CodecsObj; - options.types = &incl; - options.excludedFormats = &exl; - options.stdInMode = false; - options.filePath = _archiveFilePath; - options.callback = openArchiveCallback; - - RINOK(_archiveLink.ReOpen(options)); - return ReadItems(); - COM_TRY_END -} - -STDMETHODIMP CAgent::Close() -{ - COM_TRY_BEGIN - return _archiveLink.Close(); - COM_TRY_END -} - -/* -STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) -{ - return _archive->EnumProperties(EnumProperties); -} -*/ - -HRESULT CAgent::ReadItems() -{ - if (_proxy || _proxy2) - return S_OK; - - const CArc &arc = GetArc(); - bool useProxy2 = (arc.GetRawProps && arc.IsTree); - - // useProxy2 = false; - - if (useProxy2) - _proxy2 = new CProxyArc2(); - else - _proxy = new CProxyArc(); - - { - ThereIsPathProp = false; - // ThereIsAltStreamProp = false; - UInt32 numProps; - arc.Archive->GetNumberOfProperties(&numProps); - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE varType; - RINOK(arc.Archive->GetPropertyInfo(i, &name, &propID, &varType)); - if (propID == kpidPath) - ThereIsPathProp = true; - /* - if (propID == kpidIsAltStream) - ThereIsAltStreamProp = true; - */ - } - } - - if (_proxy2) - return _proxy2->Load(GetArc(), NULL); - return _proxy->Load(GetArc(), NULL); -} - -STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder) -{ - COM_TRY_BEGIN - RINOK(ReadItems()); - CAgentFolder *folderSpec = new CAgentFolder; - CMyComPtr rootFolder = folderSpec; - folderSpec->Init(_proxy, _proxy2, k_Proxy_RootDirIndex, /* NULL, */ this); - *resultFolder = rootFolder.Detach(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgent::Extract( - NExtract::NPathMode::EEnum pathMode, - NExtract::NOverwriteMode::EEnum overwriteMode, - const wchar_t *path, - Int32 testMode, - IFolderArchiveExtractCallback *extractCallback2) -{ - COM_TRY_BEGIN - CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; - CMyComPtr extractCallback = extractCallbackSpec; - extractCallbackSpec->InitForMulti(false, pathMode, overwriteMode); - - CExtractNtOptions extractNtOptions; - extractNtOptions.AltStreams.Val = true; // change it!!! - extractNtOptions.AltStreams.Def = true; // change it!!! - extractNtOptions.ReplaceColonForAltStream = false; // change it!!! - - extractCallbackSpec->Init( - extractNtOptions, - NULL, &GetArc(), - extractCallback2, - false, // stdOutMode - IntToBool(testMode), - us2fs(path), - UStringVector(), false, - (UInt64)(Int64)-1); - - #ifdef SUPPORT_LINKS - - if (!testMode) - { - RINOK(extractCallbackSpec->PrepareHardLinks(NULL)); // NULL means all items - } - - #endif - - return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback); - COM_TRY_END -} - -STDMETHODIMP CAgent::GetNumberOfProperties(UInt32 *numProps) -{ - COM_TRY_BEGIN - return GetArchive()->GetNumberOfProperties(numProps); - COM_TRY_END -} - -STDMETHODIMP CAgent::GetPropertyInfo(UInt32 index, - BSTR *name, PROPID *propID, VARTYPE *varType) -{ - COM_TRY_BEGIN - RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)); - if (*propID == kpidPath) - *propID = kpidName; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgent::GetArcNumLevels(UInt32 *numLevels) -{ - *numLevels = _archiveLink.Arcs.Size(); - return S_OK; -} - -STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - if (level > (UInt32)_archiveLink.Arcs.Size()) - return E_INVALIDARG; - if (level == (UInt32)_archiveLink.Arcs.Size()) - { - switch (propID) - { - case kpidPath: - if (!_archiveLink.NonOpen_ArcPath.IsEmpty()) - prop = _archiveLink.NonOpen_ArcPath; - break; - case kpidErrorType: - if (_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - prop = g_CodecsObj->Formats[_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name; - break; - } - } - else - { - const CArc &arc = _archiveLink.Arcs[level]; - switch (propID) - { - case kpidType: prop = GetTypeOfArc(arc); break; - case kpidPath: prop = arc.Path; break; - case kpidErrorType: if (arc.ErrorInfo.ErrorFormatIndex >= 0) prop = g_CodecsObj->Formats[arc.ErrorInfo.ErrorFormatIndex].Name; break; - case kpidErrorFlags: - { - UInt32 flags = arc.ErrorInfo.GetErrorFlags(); - if (flags != 0) - prop = flags; - break; - } - case kpidWarningFlags: - { - UInt32 flags = arc.ErrorInfo.GetWarningFlags(); - if (flags != 0) - prop = flags; - break; - } - case kpidOffset: - { - Int64 v = arc.GetGlobalOffset(); - if (v != 0) - prop = v; - break; - } - case kpidTailSize: - { - if (arc.ErrorInfo.TailSize != 0) - prop = arc.ErrorInfo.TailSize; - break; - } - default: return arc.Archive->GetArchiveProperty(propID, value); - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CAgent::GetArcNumProps(UInt32 level, UInt32 *numProps) -{ - return _archiveLink.Arcs[level].Archive->GetNumberOfArchiveProperties(numProps); -} - -STDMETHODIMP CAgent::GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) -{ - return _archiveLink.Arcs[level].Archive->GetArchivePropertyInfo(index, name, propID, varType); -} - -// MainItemProperty -STDMETHODIMP CAgent::GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value) -{ - return _archiveLink.Arcs[level - 1].Archive->GetProperty(_archiveLink.Arcs[level].SubfileIndex, propID, value); -} - -STDMETHODIMP CAgent::GetArcNumProps2(UInt32 level, UInt32 *numProps) -{ - return _archiveLink.Arcs[level - 1].Archive->GetNumberOfProperties(numProps); -} - -STDMETHODIMP CAgent::GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) -{ - return _archiveLink.Arcs[level - 1].Archive->GetPropertyInfo(index, name, propID, varType); -} +// Agent.cpp + +#include "StdAfx.h" + +#include + +#include "../../../../C/Sort.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariantConv.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +#include "../Common/ArchiveExtractCallback.h" +#include "../FileManager/RegistryUtils.h" + +#include "Agent.h" + +using namespace NWindows; + +CCodecs *g_CodecsObj; + +static const bool k_keepEmptyDirPrefixes = + false; // 22.00 + // true; // 21.07 + +#ifdef Z7_EXTERNAL_CODECS + extern + CExternalCodecs g_ExternalCodecs; + CExternalCodecs g_ExternalCodecs; + extern + const CExternalCodecs *g_ExternalCodecs_Ptr; + const CExternalCodecs *g_ExternalCodecs_Ptr; + static CCodecs::CReleaser g_CodecsReleaser; +#else + extern + CMyComPtr g_CodecsRef; + CMyComPtr g_CodecsRef; +#endif + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + +void FreeGlobalCodecs() +{ + MT_LOCK + + #ifdef Z7_EXTERNAL_CODECS + if (g_CodecsObj) + { + g_CodecsObj->CloseLibs(); + } + g_CodecsReleaser.Set(NULL); + g_CodecsObj = NULL; + g_ExternalCodecs.ClearAndRelease(); + g_ExternalCodecs_Ptr = NULL; + #else + g_CodecsRef.Release(); + #endif +} + +HRESULT LoadGlobalCodecs() +{ + MT_LOCK + + if (g_CodecsObj) + return S_OK; + + g_CodecsObj = new CCodecs; + + #ifdef Z7_EXTERNAL_CODECS + g_ExternalCodecs.GetCodecs = g_CodecsObj; + g_ExternalCodecs.GetHashers = g_CodecsObj; + g_CodecsReleaser.Set(g_CodecsObj); + #else + g_CodecsRef.Release(); + g_CodecsRef = g_CodecsObj; + #endif + + RINOK(g_CodecsObj->Load()) + if (g_CodecsObj->Formats.IsEmpty()) + { + FreeGlobalCodecs(); + return E_NOTIMPL; + } + + Codecs_AddHashArcHandler(g_CodecsObj); + + #ifdef Z7_EXTERNAL_CODECS + RINOK(g_ExternalCodecs.Load()) + g_ExternalCodecs_Ptr = &g_ExternalCodecs; + #endif + + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)) +{ + *agentFolder = this; + return S_OK; +} + +void CAgentFolder::LoadFolder(unsigned proxyDirIndex) +{ + CProxyItem item; + item.DirIndex = proxyDirIndex; + + if (_proxy2) + { + const CProxyDir2 &dir = _proxy2->Dirs[proxyDirIndex]; + FOR_VECTOR (i, dir.Items) + { + item.Index = i; + _items.Add(item); + const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; + if (file.DirIndex != -1) + LoadFolder((unsigned)file.DirIndex); + if (_loadAltStreams && file.AltDirIndex != -1) + LoadFolder((unsigned)file.AltDirIndex); + } + return; + } + + const CProxyDir &dir = _proxy->Dirs[proxyDirIndex]; + unsigned i; + for (i = 0; i < dir.SubDirs.Size(); i++) + { + item.Index = i; + _items.Add(item); + LoadFolder(dir.SubDirs[i]); + } + + unsigned start = dir.SubDirs.Size(); + for (i = 0; i < dir.SubFiles.Size(); i++) + { + item.Index = start + i; + _items.Add(item); + } +} + +Z7_COM7F_IMF(CAgentFolder::LoadItems()) +{ + if (!_agentSpec->_archiveLink.IsOpen) + return E_FAIL; + _items.Clear(); + if (_flatMode) + { + LoadFolder(_proxyDirIndex); + if (_proxy2 && _loadAltStreams) + { + if (_proxyDirIndex == k_Proxy2_RootDirIndex) + LoadFolder(k_Proxy2_AltRootDirIndex); + } + } + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::GetNumberOfItems(UInt32 *numItems)) +{ + if (_flatMode) + *numItems = _items.Size(); + else if (_proxy2) + *numItems = _proxy2->Dirs[_proxyDirIndex].Items.Size(); + else + { + const CProxyDir *dir = &_proxy->Dirs[_proxyDirIndex]; + *numItems = dir->SubDirs.Size() + dir->SubFiles.Size(); + } + return S_OK; +} + +#define SET_realIndex_AND_dir \ + unsigned realIndex; const CProxyDir *dir; \ + if (_flatMode) { const CProxyItem &item = _items[index]; dir = &_proxy->Dirs[item.DirIndex]; realIndex = item.Index; } \ + else { dir = &_proxy->Dirs[_proxyDirIndex]; realIndex = index; } + +#define SET_realIndex_AND_dir_2 \ + unsigned realIndex; const CProxyDir2 *dir; \ + if (_flatMode) { const CProxyItem &item = _items[index]; dir = &_proxy2->Dirs[item.DirIndex]; realIndex = item.Index; } \ + else { dir = &_proxy2->Dirs[_proxyDirIndex]; realIndex = index; } + +UString CAgentFolder::GetName(UInt32 index) const +{ + if (_proxy2) + { + SET_realIndex_AND_dir_2 + return _proxy2->Files[dir->Items[realIndex]].Name; + } + SET_realIndex_AND_dir + if (realIndex < dir->SubDirs.Size()) + return _proxy->Dirs[dir->SubDirs[realIndex]].Name; + return _proxy->Files[dir->SubFiles[realIndex - dir->SubDirs.Size()]].Name; +} + +void CAgentFolder::GetPrefix(UInt32 index, UString &prefix) const +{ + if (!_flatMode) + { + prefix.Empty(); + return; + } + + const CProxyItem &item = _items[index]; + unsigned proxyIndex = item.DirIndex; + + if (_proxy2) + { + // that code is unused. 7-Zip gets prefix via GetItemPrefix() . + + unsigned len = 0; + while (proxyIndex != _proxyDirIndex && proxyIndex >= k_Proxy2_NumRootDirs) + { + const CProxyFile2 &file = _proxy2->Files[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex]; + len += file.NameLen + 1; + proxyIndex = (file.Parent == -1) ? 0 : (unsigned)_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[(unsigned)_proxy2->Dirs[proxyIndex].ArcIndex]; + p--; + *p = WCHAR_PATH_SEPARATOR; + p -= file.NameLen; + wmemcpy(p, file.Name, file.NameLen); + proxyIndex = (file.Parent == -1) ? 0 : (unsigned)_proxy2->Files[(unsigned)file.Parent].GetDirIndex(file.IsAltStream); + } + } + else + { + unsigned len = 0; + while (proxyIndex != _proxyDirIndex) + { + const CProxyDir *dir = &_proxy->Dirs[proxyIndex]; + len += dir->NameLen + 1; + proxyIndex = (unsigned)dir->ParentDir; + } + + wchar_t *p = prefix.GetBuf_SetEnd(len) + len; + proxyIndex = item.DirIndex; + while (proxyIndex != _proxyDirIndex) + { + const CProxyDir *dir = &_proxy->Dirs[proxyIndex]; + p--; + *p = WCHAR_PATH_SEPARATOR; + p -= dir->NameLen; + wmemcpy(p, dir->Name, dir->NameLen); + proxyIndex = (unsigned)dir->ParentDir; + } + } +} + +UString CAgentFolder::GetFullPrefix(UInt32 index) const +{ + unsigned foldIndex = _proxyDirIndex; + + if (_flatMode) + foldIndex = _items[index].DirIndex; + + if (_proxy2) + return _proxy2->Dirs[foldIndex].PathPrefix; + else + return _proxy->GetDirPath_as_Prefix(foldIndex); +} + +Z7_COM7F_IMF2(UInt64, CAgentFolder::GetItemSize(UInt32 index)) +{ + unsigned arcIndex; + if (_proxy2) + { + SET_realIndex_AND_dir_2 + arcIndex = dir->Items[realIndex]; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + if (item.IsDir()) + { + const CProxyDir2 &itemFolder = _proxy2->Dirs[item.DirIndex]; + if (!_flatMode) + return itemFolder.Size; + } + } + else + { + SET_realIndex_AND_dir + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!_flatMode) + return item.Size; + if (!item.IsLeaf()) + return 0; + arcIndex = (unsigned)item.ArcIndex; + } + else + { + arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; + } + } + NCOM::CPropVariant prop; + _agentSpec->GetArchive()->GetProperty(arcIndex, kpidSize, &prop); + if (prop.vt == VT_UI8) + return prop.uhVal.QuadPart; + else + return 0; +} + +Z7_COM7F_IMF(CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (propID == kpidPrefix) + { + if (_flatMode) + { + UString prefix; + GetPrefix(index, prefix); + prop = prefix; + } + } + else if (_proxy2) + { + SET_realIndex_AND_dir_2 + unsigned arcIndex = dir->Items[realIndex]; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + /* + if (propID == kpidNumAltStreams) + { + if (item.AltDirIndex != -1) + prop = _proxy2->Dirs[item.AltDirIndex].Items.Size(); + } + else + */ + if (!item.IsDir()) + { + switch (propID) + { + case kpidIsDir: prop = false; break; + case kpidName: prop = item.Name; break; + default: return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); + } + } + else + { + const CProxyDir2 &itemFolder = _proxy2->Dirs[item.DirIndex]; + if (!_flatMode && propID == kpidSize) + prop = itemFolder.Size; + else if (!_flatMode && propID == kpidPackSize) + prop = itemFolder.PackSize; + else switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidNumSubDirs: prop = itemFolder.NumSubDirs; break; + case kpidNumSubFiles: prop = itemFolder.NumSubFiles; break; + case kpidName: prop = item.Name; break; + case kpidCRC: + { + // if (itemFolder.IsLeaf) + if (!item.Ignore) + { + RINOK(_agentSpec->GetArchive()->GetProperty(arcIndex, propID, value)) + } + if (itemFolder.CrcIsDefined && value->vt == VT_EMPTY) + prop = itemFolder.Crc; + break; + } + default: + // if (itemFolder.IsLeaf) + if (!item.Ignore) + return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); + } + } + } + else + { + SET_realIndex_AND_dir + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!_flatMode && propID == kpidSize) + prop = item.Size; + else if (!_flatMode && propID == kpidPackSize) + prop = item.PackSize; + else + switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidNumSubDirs: prop = item.NumSubDirs; break; + case kpidNumSubFiles: prop = item.NumSubFiles; break; + case kpidName: prop = item.Name; break; + case kpidCRC: + { + if (item.IsLeaf()) + { + RINOK(_agentSpec->GetArchive()->GetProperty((unsigned)item.ArcIndex, propID, value)) + } + if (item.CrcIsDefined && value->vt == VT_EMPTY) + prop = item.Crc; + break; + } + default: + if (item.IsLeaf()) + return _agentSpec->GetArchive()->GetProperty((unsigned)item.ArcIndex, propID, value); + } + } + else + { + unsigned arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; + switch (propID) + { + case kpidIsDir: prop = false; break; + case kpidName: prop = _proxy->Files[arcIndex].Name; break; + default: + return _agentSpec->GetArchive()->GetProperty(arcIndex, propID, value); + } + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +static UInt64 GetUInt64Prop(IInArchive *archive, UInt32 index, PROPID propID) +{ + NCOM::CPropVariant prop; + if (archive->GetProperty(index, propID, &prop) != S_OK) + throw 111233443; + UInt64 v = 0; + if (ConvertPropVariantToUInt64(prop, v)) + return v; + return 0; +} + +Z7_COM7F_IMF(CAgentFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) +{ + if (_proxy2) + { + SET_realIndex_AND_dir_2 + unsigned arcIndex = dir->Items[realIndex]; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + *name = item.Name; + *len = item.NameLen; + return S_OK; + } + else + { + SET_realIndex_AND_dir + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; + *name = item.Name; + *len = item.NameLen; + return S_OK; + } + else + { + const CProxyFile &item = _proxy->Files[dir->SubFiles[realIndex - dir->SubDirs.Size()]]; + *name = item.Name; + *len = item.NameLen; + return S_OK; + } + } +} + +Z7_COM7F_IMF(CAgentFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len)) +{ + *name = NULL; + *len = 0; + if (!_flatMode) + return S_OK; + + if (_proxy2) + { + const CProxyItem &item = _items[index]; + const UString &s = _proxy2->Dirs[item.DirIndex].PathPrefix; + unsigned baseLen = _proxy2->Dirs[_proxyDirIndex].PathPrefix.Len(); + if (baseLen <= s.Len()) + { + *name = (const wchar_t *)s + baseLen; + *len = s.Len() - baseLen; + } + else + { + return E_FAIL; + // throw 111l; + } + } + return S_OK; +} + +static int CompareRawProps(IArchiveGetRawProps *rawProps, unsigned arcIndex1, unsigned arcIndex2, PROPID propID) +{ + // if (propID == kpidSha1) + if (rawProps) + { + const void *p1, *p2; + UInt32 size1, size2; + UInt32 propType1, propType2; + const HRESULT res1 = rawProps->GetRawProp(arcIndex1, propID, &p1, &size1, &propType1); + const HRESULT res2 = rawProps->GetRawProp(arcIndex2, propID, &p2, &size2, &propType2); + if (res1 == S_OK && res2 == S_OK) + { + for (UInt32 i = 0; i < size1 && i < size2; i++) + { + const Byte b1 = ((const Byte *)p1)[i]; + const Byte b2 = ((const Byte *)p2)[i]; + if (b1 < b2) return -1; + if (b1 > b2) return 1; + } + if (size1 < size2) return -1; + if (size1 > size2) return 1; + return 0; + } + } + return 0; +} + +// returns pointer to extension including '.' + +static const wchar_t *GetExtension(const wchar_t *name) +{ + for (const wchar_t *dotPtr = NULL;; name++) + { + wchar_t c = *name; + if (c == 0) + return dotPtr ? dotPtr : name; + if (c == '.') + dotPtr = name; + } +} + + +int CAgentFolder::CompareItems3(UInt32 index1, UInt32 index2, PROPID propID) +{ + NCOM::CPropVariant prop1, prop2; + // Name must be first property + GetProperty(index1, propID, &prop1); + GetProperty(index2, propID, &prop2); + if (prop1.vt != prop2.vt) + return MyCompare(prop1.vt, prop2.vt); + if (prop1.vt == VT_BSTR) + return MyStringCompareNoCase(prop1.bstrVal, prop2.bstrVal); + return prop1.Compare(prop2); +} + + +int CAgentFolder::CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw) +{ + unsigned realIndex1, realIndex2; + const CProxyDir2 *dir1, *dir2; + + if (_flatMode) + { + const CProxyItem &item1 = _items[index1]; + const CProxyItem &item2 = _items[index2]; + dir1 = &_proxy2->Dirs[item1.DirIndex]; + dir2 = &_proxy2->Dirs[item2.DirIndex]; + realIndex1 = item1.Index; + realIndex2 = item2.Index; + } + else + { + dir2 = dir1 = &_proxy2->Dirs[_proxyDirIndex]; + realIndex1 = index1; + realIndex2 = index2; + } + + UInt32 arcIndex1; + UInt32 arcIndex2; + bool isDir1, isDir2; + arcIndex1 = dir1->Items[realIndex1]; + arcIndex2 = dir2->Items[realIndex2]; + const CProxyFile2 &prox1 = _proxy2->Files[arcIndex1]; + const CProxyFile2 &prox2 = _proxy2->Files[arcIndex2]; + + if (propID == kpidName) + { + return CompareFileNames_ForFolderList(prox1.Name, prox2.Name); + } + + if (propID == kpidPrefix) + { + if (!_flatMode) + return 0; + return CompareFileNames_ForFolderList( + _proxy2->Dirs[_items[index1].DirIndex].PathPrefix, + _proxy2->Dirs[_items[index2].DirIndex].PathPrefix); + } + + if (propID == kpidExtension) + { + return CompareFileNames_ForFolderList( + GetExtension(prox1.Name), + GetExtension(prox2.Name)); + } + + isDir1 = prox1.IsDir(); + isDir2 = prox2.IsDir(); + + if (propID == kpidIsDir) + { + if (isDir1 == isDir2) + return 0; + return isDir1 ? -1 : 1; + } + + const CProxyDir2 *proxFolder1 = NULL; + const CProxyDir2 *proxFolder2 = NULL; + if (isDir1) proxFolder1 = &_proxy2->Dirs[prox1.DirIndex]; + if (isDir2) proxFolder2 = &_proxy2->Dirs[prox2.DirIndex]; + + if (propID == kpidNumSubDirs) + { + UInt32 n1 = 0; + UInt32 n2 = 0; + if (isDir1) n1 = proxFolder1->NumSubDirs; + if (isDir2) n2 = proxFolder2->NumSubDirs; + return MyCompare(n1, n2); + } + + if (propID == kpidNumSubFiles) + { + UInt32 n1 = 0; + UInt32 n2 = 0; + if (isDir1) n1 = proxFolder1->NumSubFiles; + if (isDir2) n2 = proxFolder2->NumSubFiles; + return MyCompare(n1, n2); + } + + if (propID == kpidSize) + { + UInt64 n1, n2; + if (isDir1) + n1 = _flatMode ? 0 : proxFolder1->Size; + else + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidSize); + if (isDir2) + n2 = _flatMode ? 0 : proxFolder2->Size; + else + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidSize); + return MyCompare(n1, n2); + } + + if (propID == kpidPackSize) + { + UInt64 n1, n2; + if (isDir1) + n1 = _flatMode ? 0 : proxFolder1->PackSize; + else + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidPackSize); + if (isDir2) + n2 = _flatMode ? 0 : proxFolder2->PackSize; + else + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidPackSize); + return MyCompare(n1, n2); + } + + if (propID == kpidCRC) + { + UInt64 n1, n2; + if (!isDir1 || !prox1.Ignore) + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidCRC); + else + n1 = proxFolder1->Crc; + if (!isDir2 || !prox2.Ignore) + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidCRC); + else + n2 = proxFolder2->Crc; + return MyCompare(n1, n2); + } + + if (propIsRaw) + return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID); + + return CompareItems3(index1, index2, propID); +} + + +Z7_COM7F_IMF2(Int32, CAgentFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw)) +{ + try { + if (_proxy2) + return CompareItems2(index1, index2, propID, propIsRaw); + + unsigned realIndex1, realIndex2; + const CProxyDir *dir1, *dir2; + + if (_flatMode) + { + const CProxyItem &item1 = _items[index1]; + const CProxyItem &item2 = _items[index2]; + dir1 = &_proxy->Dirs[item1.DirIndex]; + dir2 = &_proxy->Dirs[item2.DirIndex]; + realIndex1 = item1.Index; + realIndex2 = item2.Index; + } + else + { + dir2 = dir1 = &_proxy->Dirs[_proxyDirIndex]; + realIndex1 = index1; + realIndex2 = index2; + } + + if (propID == kpidPrefix) + { + if (!_flatMode) + return 0; + UString prefix1, prefix2; + GetPrefix(index1, prefix1); + GetPrefix(index2, prefix2); + return CompareFileNames_ForFolderList(prefix1, prefix2); + } + + UInt32 arcIndex1; + UInt32 arcIndex2; + + const CProxyDir *proxFolder1 = NULL; + const CProxyDir *proxFolder2 = NULL; + + if (realIndex1 < dir1->SubDirs.Size()) + { + proxFolder1 = &_proxy->Dirs[dir1->SubDirs[realIndex1]]; + arcIndex1 = (unsigned)proxFolder1->ArcIndex; + } + else + arcIndex1 = dir1->SubFiles[realIndex1 - dir1->SubDirs.Size()]; + + if (realIndex2 < dir2->SubDirs.Size()) + { + proxFolder2 = &_proxy->Dirs[dir2->SubDirs[realIndex2]]; + arcIndex2 = (unsigned)proxFolder2->ArcIndex; + } + else + arcIndex2 = dir2->SubFiles[realIndex2 - dir2->SubDirs.Size()]; + + if (propID == kpidName) + return CompareFileNames_ForFolderList( + proxFolder1 ? proxFolder1->Name : _proxy->Files[arcIndex1].Name, + proxFolder2 ? proxFolder2->Name : _proxy->Files[arcIndex2].Name); + + if (propID == kpidExtension) + return CompareFileNames_ForFolderList( + GetExtension(proxFolder1 ? proxFolder1->Name : _proxy->Files[arcIndex1].Name), + GetExtension(proxFolder2 ? proxFolder2->Name : _proxy->Files[arcIndex2].Name)); + + if (propID == kpidIsDir) + { + if (proxFolder1) + return proxFolder2 ? 0 : -1; + return proxFolder2 ? 1 : 0; + } + + if (propID == kpidNumSubDirs) + { + UInt32 n1 = 0; + UInt32 n2 = 0; + if (proxFolder1) n1 = proxFolder1->NumSubDirs; + if (proxFolder2) n2 = proxFolder2->NumSubDirs; + return MyCompare(n1, n2); + } + + if (propID == kpidNumSubFiles) + { + UInt32 n1 = 0; + UInt32 n2 = 0; + if (proxFolder1) n1 = proxFolder1->NumSubFiles; + if (proxFolder2) n2 = proxFolder2->NumSubFiles; + return MyCompare(n1, n2); + } + + if (propID == kpidSize) + { + UInt64 n1, n2; + if (proxFolder1) + n1 = _flatMode ? 0 : proxFolder1->Size; + else + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidSize); + if (proxFolder2) + n2 = _flatMode ? 0 : proxFolder2->Size; + else + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidSize); + return MyCompare(n1, n2); + } + + if (propID == kpidPackSize) + { + UInt64 n1, n2; + if (proxFolder1) + n1 = _flatMode ? 0 : proxFolder1->PackSize; + else + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidPackSize); + if (proxFolder2) + n2 = _flatMode ? 0 : proxFolder2->PackSize; + else + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidPackSize); + return MyCompare(n1, n2); + } + + if (propID == kpidCRC) + { + UInt64 n1, n2; + if (proxFolder1 && !proxFolder1->IsLeaf()) + n1 = proxFolder1->Crc; + else + n1 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex1, kpidCRC); + if (proxFolder2 && !proxFolder2->IsLeaf()) + n2 = proxFolder2->Crc; + else + n2 = GetUInt64Prop(_agentSpec->GetArchive(), arcIndex2, kpidCRC); + return MyCompare(n1, n2); + } + + if (propIsRaw) + { + bool isVirt1 = (proxFolder1 && !proxFolder1->IsLeaf()); + bool isVirt2 = (proxFolder2 && !proxFolder2->IsLeaf()); + if (isVirt1) + return isVirt2 ? 0 : -1; + if (isVirt2) + return 1; + return CompareRawProps(_agentSpec->_archiveLink.GetArchiveGetRawProps(), arcIndex1, arcIndex2, propID); + } + + return CompareItems3(index1, index2, propID); + + } catch(...) { return 0; } +} + + +HRESULT CAgentFolder::BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder) +{ + /* + CMyComPtr parentFolder; + + if (_proxy2) + { + const CProxyDir2 &dir = _proxy2->Dirs[proxyDirIndex]; + int par = _proxy2->GetParentFolderOfFile(dir.ArcIndex); + if (par != (int)_proxyDirIndex) + { + RINOK(BindToFolder_Internal(par, &parentFolder)); + } + else + parentFolder = this; + } + else + { + const CProxyDir &dir = _proxy->Dirs[proxyDirIndex]; + if (dir.Parent != (int)_proxyDirIndex) + { + RINOK(BindToFolder_Internal(dir.Parent, &parentFolder)); + } + else + parentFolder = this; + } + */ + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); + *resultFolder = agentFolder.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + if (_proxy2) + { + SET_realIndex_AND_dir_2 + const unsigned arcIndex = dir->Items[realIndex]; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + if (!item.IsDir()) + return E_INVALIDARG; + return BindToFolder_Internal((unsigned)item.DirIndex, resultFolder); + } + SET_realIndex_AND_dir + if (realIndex >= (UInt32)dir->SubDirs.Size()) + return E_INVALIDARG; + return BindToFolder_Internal(dir->SubDirs[realIndex], resultFolder); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + if (_proxy2) + { + const int index = _proxy2->FindItem(_proxyDirIndex, name, true); + if (index == -1) + return E_INVALIDARG; + return BindToFolder_Internal((unsigned)_proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]].DirIndex, resultFolder); + } + const int index = _proxy->FindSubDir(_proxyDirIndex, name); + if (index == -1) + return E_INVALIDARG; + return BindToFolder_Internal((unsigned)index, resultFolder); + COM_TRY_END +} + + + +// ---------- IFolderAltStreams ---------- + +HRESULT CAgentFolder::BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder) +{ + *resultFolder = NULL; + if (!_proxy2) + return S_OK; + + /* + CMyComPtr parentFolder; + + int par = _proxy2->GetParentFolderOfFile(_proxy2->Dirs[proxyDirIndex].ArcIndex); + if (par != (int)_proxyDirIndex) + { + RINOK(BindToFolder_Internal(par, &parentFolder)); + if (!parentFolder) + return S_OK; + } + else + parentFolder = this; + */ + + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); + *resultFolder = agentFolder.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::BindToAltStreams(UInt32 index, IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + + *resultFolder = NULL; + + if (!_proxy2) + return S_OK; + + if (_proxy2->IsAltDir(_proxyDirIndex)) + return S_OK; + + { + if (index == (UInt32)(Int32)-1) + { + unsigned altDirIndex; + // IFolderFolder *parentFolder; + + if (_proxyDirIndex == k_Proxy2_RootDirIndex) + { + altDirIndex = k_Proxy2_AltRootDirIndex; + // parentFolder = this; // we want to use Root dir as parent for alt root + } + else + { + const unsigned arcIndex = (unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + if (item.AltDirIndex == -1) + return S_OK; + altDirIndex = (unsigned)item.AltDirIndex; + // parentFolder = _parentFolder; + } + + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxy, _proxy2, altDirIndex, /* parentFolder, */ _agentSpec); + *resultFolder = agentFolder.Detach(); + return S_OK; + } + + SET_realIndex_AND_dir_2 + const unsigned arcIndex = dir->Items[realIndex]; + const CProxyFile2 &item = _proxy2->Files[arcIndex]; + if (item.AltDirIndex == -1) + return S_OK; + return BindToAltStreams_Internal((unsigned)item.AltDirIndex, resultFolder); + } + + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::BindToAltStreams(const wchar_t *name, IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + + *resultFolder = NULL; + + if (!_proxy2) + return S_OK; + + if (_proxy2->IsAltDir(_proxyDirIndex)) + return S_OK; + + if (name[0] == 0) + return BindToAltStreams((UInt32)(Int32)-1, resultFolder); + + { + const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex]; + FOR_VECTOR (i, dir.Items) + { + const CProxyFile2 &file = _proxy2->Files[dir.Items[i]]; + if (file.AltDirIndex != -1) + if (CompareFileNames(file.Name, name) == 0) + return BindToAltStreams_Internal((unsigned)file.AltDirIndex, resultFolder); + } + return E_INVALIDARG; + } + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::AreAltStreamsSupported(UInt32 index, Int32 *isSupported)) +{ + *isSupported = BoolToInt(false); + + if (!_proxy2) + return S_OK; + + if (_proxy2->IsAltDir(_proxyDirIndex)) + return S_OK; + + unsigned arcIndex; + + if (index == (UInt32)(Int32)-1) + { + if (_proxyDirIndex == k_Proxy2_RootDirIndex) + { + *isSupported = BoolToInt(true); + return S_OK; + } + arcIndex = (unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex; + } + else + { + SET_realIndex_AND_dir_2 + arcIndex = dir->Items[realIndex]; + } + + if (_proxy2->Files[arcIndex].AltDirIndex != -1) + *isSupported = BoolToInt(true); + return S_OK; +} + + +Z7_COM7F_IMF(CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + /* + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + */ + *resultFolder = NULL; + + unsigned proxyDirIndex; + + if (_proxy2) + { + if (_proxyDirIndex == k_Proxy2_RootDirIndex) + return S_OK; + if (_proxyDirIndex == k_Proxy2_AltRootDirIndex) + proxyDirIndex = k_Proxy2_RootDirIndex; + else + { + const CProxyDir2 &fold = _proxy2->Dirs[_proxyDirIndex]; + const CProxyFile2 &file = _proxy2->Files[(unsigned)fold.ArcIndex]; + const int parentIndex = file.Parent; + if (parentIndex == -1) + proxyDirIndex = k_Proxy2_RootDirIndex; + else + proxyDirIndex = (unsigned)_proxy2->Files[(unsigned)parentIndex].DirIndex; + } + } + else + { + const int parent = _proxy->Dirs[_proxyDirIndex].ParentDir; + if (parent == -1) + return S_OK; + proxyDirIndex = (unsigned)parent; + } + + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxy, _proxy2, proxyDirIndex, /* parentFolder, */ _agentSpec); + *resultFolder = agentFolder.Detach(); + + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + Z7_DECL_CMyComPtr_QI_FROM( + IInArchiveGetStream, + getStream, _agentSpec->GetArchive()) + if (!getStream) + return S_OK; + + UInt32 arcIndex; + if (_proxy2) + { + SET_realIndex_AND_dir_2 + arcIndex = dir->Items[realIndex]; + } + else + { + SET_realIndex_AND_dir + + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!item.IsLeaf()) + return S_OK; + arcIndex = (unsigned)item.ArcIndex; + } + else + arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; + } + return getStream->GetStream(arcIndex, stream); +} + +// static const unsigned k_FirstOptionalProp = 2; + +static const PROPID kProps[] = +{ + kpidNumSubDirs, + kpidNumSubFiles, + + // kpidNumAltStreams, + kpidPrefix +}; + +struct CArchiveItemPropertyTemp +{ + UString Name; + PROPID ID; + VARTYPE Type; +}; + +Z7_COM7F_IMF(CAgentFolder::GetNumberOfProperties(UInt32 *numProps)) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProps)) + *numProps += Z7_ARRAY_SIZE(kProps); + if (!_flatMode) + (*numProps)--; + /* + if (!_agentSpec->ThereIsAltStreamProp) + (*numProps)--; + */ + /* + bool thereIsPathProp = _proxy2 ? + _agentSpec->_proxy2->ThereIsPathProp : + _agentSpec->_proxy->ThereIsPathProp; + */ + + // if there is kpidPath, we change kpidPath to kpidName + // if there is no kpidPath, we add kpidName. + if (!_agentSpec->ThereIsPathProp) + (*numProps)++; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) +{ + COM_TRY_BEGIN + UInt32 numProps; + _agentSpec->GetArchive()->GetNumberOfProperties(&numProps); + + /* + bool thereIsPathProp = _proxy2 ? + _agentSpec->_proxy2->ThereIsPathProp : + _agentSpec->_proxy->ThereIsPathProp; + */ + + if (!_agentSpec->ThereIsPathProp) + { + if (index == 0) + { + *propID = kpidName; + *varType = VT_BSTR; + *name = NULL; + return S_OK; + } + index--; + } + + if (index < numProps) + { + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)) + if (*propID == kpidPath) + *propID = kpidName; + } + else + { + index -= numProps; + /* + if (index >= k_FirstOptionalProp) + { + if (!_agentSpec->ThereIsAltStreamProp) + index++; + } + */ + *propID = kProps[index]; + *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; + *name = NULL; + } + return S_OK; + COM_TRY_END +} + +static const PROPID kFolderProps[] = +{ + kpidSize, + kpidPackSize, + kpidNumSubDirs, + kpidNumSubFiles, + kpidCRC +}; + +Z7_COM7F_IMF(CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + + NWindows::NCOM::CPropVariant prop; + + if (propID == kpidReadOnly) + { + if (_agentSpec->Is_Attrib_ReadOnly()) + prop = true; + else + prop = _agentSpec->IsThere_ReadOnlyArc(); + } + else if (propID == kpidIsHash) + { + prop = _agentSpec->_isHashHandler; + } + else if (_proxy2) + { + const CProxyDir2 &dir = _proxy2->Dirs[_proxyDirIndex]; + if (propID == kpidName) + { + if (dir.ArcIndex != -1) + prop = _proxy2->Files[(unsigned)dir.ArcIndex].Name; + } + else if (propID == kpidPath) + { + bool isAltStreamFolder = false; + prop = _proxy2->GetDirPath_as_Prefix(_proxyDirIndex, isAltStreamFolder); + } + else switch (propID) + { + case kpidSize: prop = dir.Size; break; + case kpidPackSize: prop = dir.PackSize; break; + case kpidNumSubDirs: prop = dir.NumSubDirs; break; + case kpidNumSubFiles: prop = dir.NumSubFiles; break; + // case kpidName: prop = dir.Name; break; + // case kpidPath: prop = _proxy2->GetFullPathPrefix(_proxyDirIndex); break; + case kpidType: prop = UString("7-Zip.") + _agentSpec->ArchiveType; break; + case kpidCRC: if (dir.CrcIsDefined) { prop = dir.Crc; } break; + } + + } + else + { + const CProxyDir &dir = _proxy->Dirs[_proxyDirIndex]; + switch (propID) + { + case kpidSize: prop = dir.Size; break; + case kpidPackSize: prop = dir.PackSize; break; + case kpidNumSubDirs: prop = dir.NumSubDirs; break; + case kpidNumSubFiles: prop = dir.NumSubFiles; break; + case kpidName: prop = dir.Name; break; + case kpidPath: prop = _proxy->GetDirPath_as_Prefix(_proxyDirIndex); break; + case kpidType: prop = UString("7-Zip.") + _agentSpec->ArchiveType; break; + case kpidCRC: if (dir.CrcIsDefined) prop = dir.Crc; break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::GetNumberOfFolderProperties(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kFolderProps); + return S_OK; +} + +IMP_IFolderFolder_GetProp( + CAgentFolder::GetFolderPropertyInfo, + kFolderProps) + +Z7_COM7F_IMF(CAgentFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */)) +{ + return E_FAIL; +} + + +Z7_COM7F_IMF(CAgentFolder::GetNumRawProps(UInt32 *numProps)) +{ + IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); + if (rawProps) + return rawProps->GetNumRawProps(numProps); + *numProps = 0; + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); + if (rawProps) + return rawProps->GetRawPropInfo(index, name, propID); + return E_FAIL; +} + +Z7_COM7F_IMF(CAgentFolder::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + IArchiveGetRawProps *rawProps = _agentSpec->_archiveLink.GetArchiveGetRawProps(); + if (rawProps) + { + unsigned arcIndex; + if (_proxy2) + { + SET_realIndex_AND_dir_2 + arcIndex = dir->Items[realIndex]; + } + else + { + SET_realIndex_AND_dir + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &item = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!item.IsLeaf()) + { + *data = NULL; + *dataSize = 0; + *propType = 0; + return S_OK; + } + arcIndex = (unsigned)item.ArcIndex; + } + else + arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; + } + return rawProps->GetRawProp(arcIndex, propID, data, dataSize, propType); + } + *data = NULL; + *dataSize = 0; + *propType = 0; + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::GetFolderArcProps(IFolderArcProps **object)) +{ + CMyComPtr temp = _agentSpec; + *object = temp.Detach(); + return S_OK; +} + + +Z7_COM7F_IMF(CAgentFolder::SetFlatMode(Int32 flatMode)) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + + +int CAgentFolder::GetRealIndex(unsigned index) const +{ + if (!_flatMode) + { + if (_proxy2) + return (int)_proxy2->GetRealIndex(_proxyDirIndex, index); + else + return _proxy->GetRealIndex(_proxyDirIndex, index); + } + { + const CProxyItem &item = _items[index]; + if (_proxy2) + { + const CProxyDir2 *dir = &_proxy2->Dirs[item.DirIndex]; + return (int)dir->Items[item.Index]; + } + else + { + const CProxyDir *dir = &_proxy->Dirs[item.DirIndex]; + const unsigned realIndex = item.Index; + if (realIndex < dir->SubDirs.Size()) + { + const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!f.IsLeaf()) + return -1; + return f.ArcIndex; + } + return (int)dir->SubFiles[realIndex - dir->SubDirs.Size()]; + } + } +} + +void CAgentFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const +{ + if (!_flatMode) + { + if (_proxy2) + _proxy2->GetRealIndices(_proxyDirIndex, indices, numItems, includeAltStreams, realIndices); + else + _proxy->GetRealIndices(_proxyDirIndex, indices, numItems, realIndices); + return; + } + + realIndices.Clear(); + + for (UInt32 i = 0; i < numItems; i++) + { + const CProxyItem &item = _items[indices[i]]; + if (_proxy2) + { + const CProxyDir2 *dir = &_proxy2->Dirs[item.DirIndex]; + _proxy2->AddRealIndices_of_ArcItem(dir->Items[item.Index], includeAltStreams, realIndices); + continue; + } + UInt32 arcIndex; + { + const CProxyDir *dir = &_proxy->Dirs[item.DirIndex]; + unsigned realIndex = item.Index; + if (realIndex < dir->SubDirs.Size()) + { + if (includeFolderSubItemsInFlatMode) + { + _proxy->AddRealIndices(dir->SubDirs[realIndex], realIndices); + continue; + } + const CProxyDir &f = _proxy->Dirs[dir->SubDirs[realIndex]]; + if (!f.IsLeaf()) + continue; + arcIndex = (unsigned)f.ArcIndex; + } + else + arcIndex = dir->SubFiles[realIndex - dir->SubDirs.Size()]; + } + realIndices.Add(arcIndex); + } + + HeapSort(realIndices.NonConstData(), realIndices.Size()); +} + +Z7_COM7F_IMF(CAgentFolder::Extract(const UInt32 *indices, + UInt32 numItems, + Int32 includeAltStreams, + Int32 replaceAltStreamColon, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + Int32 testMode, + IFolderArchiveExtractCallback *extractCallback2)) +{ + COM_TRY_BEGIN + + if (!testMode && _agentSpec->_isHashHandler) + return E_NOTIMPL; + + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + UStringVector pathParts; + bool isAltStreamFolder = false; + if (_proxy2) + _proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder); + else + _proxy->GetDirPathParts(_proxyDirIndex, pathParts); + + /* + if (_flatMode) + pathMode = NExtract::NPathMode::kNoPathnames; + */ + + extractCallbackSpec->InitForMulti( + false, // multiArchives + pathMode, + overwriteMode, + _zoneMode, + k_keepEmptyDirPrefixes); + + if (extractCallback2) + extractCallback2->SetTotal(_agentSpec->GetArc().GetEstmatedPhySize()); + + FString pathU; + if (path) + { + pathU = us2fs(path); + if (!pathU.IsEmpty() + && !NFile::NName::IsAltStreamPrefixWithColon(path)) + { + NFile::NName::NormalizeDirPathPrefix(pathU); + NFile::NDir::CreateComplexDir(pathU); + } + } + + CExtractNtOptions extractNtOptions; + extractNtOptions.AltStreams.Val = IntToBool(includeAltStreams); // change it!!! + extractNtOptions.AltStreams.Def = true; + + 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); + if (_zoneBuf.Size() != 0) + extractCallbackSpec->ZoneBuf = _zoneBuf; + } + #endif + + extractCallbackSpec->Init( + extractNtOptions, + NULL, &_agentSpec->GetArc(), + extractCallback2, + false, // stdOutMode + IntToBool(testMode), + pathU, + pathParts, isAltStreamFolder, + (UInt64)(Int64)-1); + + if (_proxy2) + extractCallbackSpec->SetBaseParentFolderIndex((unsigned)_proxy2->Dirs[_proxyDirIndex].ArcIndex); + + // do we need another base folder for subfolders ? + extractCallbackSpec->DirPathPrefix_for_HashFiles = _agentSpec->_hashBaseFolderPrefix; + + CUIntVector realIndices; + GetRealIndices(indices, numItems, IntToBool(includeAltStreams), + false, // includeFolderSubItemsInFlatMode + realIndices); // + + #ifdef SUPPORT_LINKS + + if (!testMode) + { + RINOK(extractCallbackSpec->PrepareHardLinks(&realIndices)) + } + + #endif + + { + CArchiveExtractCallback_Closer ecsCloser(extractCallbackSpec); + + HRESULT res = _agentSpec->GetArchive()->Extract(realIndices.ConstData(), + realIndices.Size(), testMode, extractCallback); + + const HRESULT res2 = ecsCloser.Close(); + if (res == S_OK) + res = res2; + return res; + } + + COM_TRY_END +} + +///////////////////////////////////////// +// CAgent + +CAgent::CAgent(): + _proxy(NULL), + _proxy2(NULL), + _updatePathPrefix_is_AltFolder(false), + _isDeviceFile(false), + _isHashHandler(false) +{ +} + +CAgent::~CAgent() +{ + if (_proxy) + delete _proxy; + if (_proxy2) + delete _proxy2; +} + +bool CAgent::CanUpdate() const +{ + // FAR plugin uses empty agent to create new archive !!! + if (_archiveLink.Arcs.Size() == 0) + return true; + if (_isDeviceFile) + return false; + if (_archiveLink.Arcs.Size() != 1) + return false; + if (_archiveLink.Arcs[0].ErrorInfo.ThereIsTail) + return false; + return true; +} + +Z7_COM7F_IMF(CAgent::Open( + IInStream *inStream, + const wchar_t *filePath, + const wchar_t *arcFormat, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback)) +{ + COM_TRY_BEGIN + _archiveFilePath = filePath; + _hashBaseFolderPrefix.Empty(); + _attrib = 0; + _isDeviceFile = false; + _isHashHandler = false; + NFile::NFind::CFileInfo fi; + if (!inStream) + { + if (!fi.Find(us2fs(_archiveFilePath))) + return GetLastError_noZero_HRESULT(); + if (fi.IsDir()) + return E_FAIL; + _attrib = fi.Attrib; + _isDeviceFile = fi.IsDevice; + FString dirPrefix, fileName; + if (NFile::NDir::GetFullPathAndSplit(us2fs(_archiveFilePath), dirPrefix, fileName)) + { + NFile::NName::NormalizeDirPathPrefix(dirPrefix); + _hashBaseFolderPrefix = dirPrefix; + } + } + CArcInfoEx archiverInfo0, archiverInfo1; + + RINOK(LoadGlobalCodecs()) + + CObjectVector types; + if (!ParseOpenTypes(*g_CodecsObj, arcFormat, types)) + return S_FALSE; + + /* + CObjectVector optProps; + if (Read_ShowDeleted()) + { + COptionalOpenProperties &optPair = optProps.AddNew(); + optPair.FormatName = "ntfs"; + // optPair.Props.AddNew().Name = "LS"; + optPair.Props.AddNew().Name = "LD"; + } + */ + + COpenOptions options; + options.props = NULL; + options.codecs = g_CodecsObj; + options.types = &types; + CIntVector exl; + options.excludedFormats = &exl; + options.stdInMode = false; + options.stream = inStream; + options.filePath = _archiveFilePath; + options.callback = openArchiveCallback; + + HRESULT res = _archiveLink.Open(options); + + if (!_archiveLink.Arcs.IsEmpty()) + { + CArc &arc = _archiveLink.Arcs.Back(); + if (!inStream) + { + arc.MTime.Set_From_FiTime(fi.MTime); + arc.MTime.Def = !fi.IsDevice; + } + + ArchiveType = GetTypeOfArc(arc); + if (archiveType) + { + RINOK(StringToBstr(ArchiveType, archiveType)) + } + + if (arc.IsHashHandler(options)) + _isHashHandler = true; + } + + return res; + + COM_TRY_END +} + + +Z7_COM7F_IMF(CAgent::ReOpen(IArchiveOpenCallback *openArchiveCallback)) +{ + COM_TRY_BEGIN + if (_proxy2) + { + delete _proxy2; + _proxy2 = NULL; + } + if (_proxy) + { + delete _proxy; + _proxy = NULL; + } + + CObjectVector incl; + CIntVector exl; + + COpenOptions options; + options.props = NULL; + options.codecs = g_CodecsObj; + options.types = &incl; + options.excludedFormats = &exl; + options.stdInMode = false; + options.filePath = _archiveFilePath; + options.callback = openArchiveCallback; + + RINOK(_archiveLink.ReOpen(options)) + return ReadItems(); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::Close()) +{ + COM_TRY_BEGIN + return _archiveLink.Close(); + COM_TRY_END +} + +/* +Z7_COM7F_IMF(CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) +{ + return _archive->EnumProperties(EnumProperties); +} +*/ + +HRESULT CAgent::ReadItems() +{ + if (_proxy || _proxy2) + return S_OK; + + const CArc &arc = GetArc(); + bool useProxy2 = (arc.GetRawProps && arc.IsTree); + + // useProxy2 = false; + + if (useProxy2) + _proxy2 = new CProxyArc2(); + else + _proxy = new CProxyArc(); + + { + ThereIsPathProp = false; + // ThereIsAltStreamProp = false; + UInt32 numProps; + arc.Archive->GetNumberOfProperties(&numProps); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + RINOK(arc.Archive->GetPropertyInfo(i, &name, &propID, &varType)) + if (propID == kpidPath) + ThereIsPathProp = true; + /* + if (propID == kpidIsAltStream) + ThereIsAltStreamProp = true; + */ + } + } + + if (_proxy2) + return _proxy2->Load(GetArc(), NULL); + return _proxy->Load(GetArc(), NULL); +} + +Z7_COM7F_IMF(CAgent::BindToRootFolder(IFolderFolder **resultFolder)) +{ + COM_TRY_BEGIN + if (!_archiveLink.Arcs.IsEmpty()) + { + RINOK(ReadItems()) + } + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr rootFolder = folderSpec; + folderSpec->Init(_proxy, _proxy2, k_Proxy_RootDirIndex, /* NULL, */ this); + *resultFolder = rootFolder.Detach(); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::Extract( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + Int32 testMode, + IFolderArchiveExtractCallback *extractCallback2)) +{ + COM_TRY_BEGIN + + if (!testMode && _isHashHandler) + return E_NOTIMPL; + + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + extractCallbackSpec->InitForMulti( + false, // multiArchives + pathMode, + overwriteMode, + NExtract::NZoneIdMode::kNone, + k_keepEmptyDirPrefixes); + + CExtractNtOptions extractNtOptions; + extractNtOptions.AltStreams.Val = true; // change it!!! + extractNtOptions.AltStreams.Def = true; // change it!!! + extractNtOptions.ReplaceColonForAltStream = false; // change it!!! + + extractCallbackSpec->Init( + extractNtOptions, + NULL, &GetArc(), + extractCallback2, + false, // stdOutMode + IntToBool(testMode), + us2fs(path), + UStringVector(), false, + (UInt64)(Int64)-1); + + extractCallbackSpec->DirPathPrefix_for_HashFiles = _hashBaseFolderPrefix; + + #ifdef SUPPORT_LINKS + + if (!testMode) + { + RINOK(extractCallbackSpec->PrepareHardLinks(NULL)) // NULL means all items + } + + #endif + + return GetArchive()->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallback); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::GetNumberOfProperties(UInt32 *numProps)) +{ + COM_TRY_BEGIN + return GetArchive()->GetNumberOfProperties(numProps); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType)) +{ + COM_TRY_BEGIN + RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)) + if (*propID == kpidPath) + *propID = kpidName; + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::GetArcNumLevels(UInt32 *numLevels)) +{ + *numLevels = _archiveLink.Arcs.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + if (level > (UInt32)_archiveLink.Arcs.Size()) + return E_INVALIDARG; + if (level == (UInt32)_archiveLink.Arcs.Size()) + { + switch (propID) + { + case kpidPath: + if (!_archiveLink.NonOpen_ArcPath.IsEmpty()) + prop = _archiveLink.NonOpen_ArcPath; + break; + case kpidErrorType: + if (_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + prop = g_CodecsObj->Formats[_archiveLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name; + break; + case kpidErrorFlags: + { + UInt32 flags = _archiveLink.NonOpen_ErrorInfo.GetErrorFlags(); + if (flags != 0) + prop = flags; + break; + } + case kpidWarningFlags: + { + UInt32 flags = _archiveLink.NonOpen_ErrorInfo.GetWarningFlags(); + if (flags != 0) + prop = flags; + break; + } + } + } + else + { + const CArc &arc = _archiveLink.Arcs[level]; + switch (propID) + { + case kpidType: prop = GetTypeOfArc(arc); break; + case kpidPath: prop = arc.Path; break; + case kpidErrorType: + if (arc.ErrorInfo.ErrorFormatIndex >= 0) + prop = g_CodecsObj->Formats[arc.ErrorInfo.ErrorFormatIndex].Name; + break; + case kpidErrorFlags: + { + const UInt32 flags = arc.ErrorInfo.GetErrorFlags(); + if (flags != 0) + prop = flags; + break; + } + case kpidWarningFlags: + { + const UInt32 flags = arc.ErrorInfo.GetWarningFlags(); + if (flags != 0) + prop = flags; + break; + } + case kpidOffset: + { + const Int64 v = arc.GetGlobalOffset(); + if (v != 0) + prop.Set_Int64(v); + break; + } + case kpidTailSize: + { + if (arc.ErrorInfo.TailSize != 0) + prop = arc.ErrorInfo.TailSize; + break; + } + default: return arc.Archive->GetArchiveProperty(propID, value); + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAgent::GetArcNumProps(UInt32 level, UInt32 *numProps)) +{ + return _archiveLink.Arcs[level].Archive->GetNumberOfArchiveProperties(numProps); +} + +Z7_COM7F_IMF(CAgent::GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) +{ + return _archiveLink.Arcs[level].Archive->GetArchivePropertyInfo(index, name, propID, varType); +} + +// MainItemProperty +Z7_COM7F_IMF(CAgent::GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value)) +{ + return _archiveLink.Arcs[level - 1].Archive->GetProperty(_archiveLink.Arcs[level].SubfileIndex, propID, value); +} + +Z7_COM7F_IMF(CAgent::GetArcNumProps2(UInt32 level, UInt32 *numProps)) +{ + return _archiveLink.Arcs[level - 1].Archive->GetNumberOfProperties(numProps); +} + +Z7_COM7F_IMF(CAgent::GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) +{ + return _archiveLink.Arcs[level - 1].Archive->GetPropertyInfo(index, name, propID, varType); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/Agent.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.h --- p7zip-rar-16.02/CPP/7zip/UI/Agent/Agent.h 2015-09-17 19:02:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/Agent.h 2024-10-04 10:00:00.000000000 +0000 @@ -1,332 +1,358 @@ -// Agent/Agent.h - -#ifndef __AGENT_AGENT_H -#define __AGENT_AGENT_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/PropVariant.h" - -#include "../Common/OpenArchive.h" -#include "../Common/UpdateAction.h" - -#ifdef NEW_FOLDER_INTERFACE -#include "../FileManager/IFolder.h" -#include "../Common/LoadCodecs.h" -#endif - -#include "AgentProxy.h" -#include "IFolderArchive.h" - -extern CCodecs *g_CodecsObj; -HRESULT LoadGlobalCodecs(); -void FreeGlobalCodecs(); - -class CAgentFolder; - -DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC) -{ - STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE; -}; - -struct CProxyItem -{ - unsigned DirIndex; - unsigned Index; -}; - -class CAgent; - -enum AGENT_OP -{ - AGENT_OP_Uni, - AGENT_OP_Delete, - AGENT_OP_CreateFolder, - AGENT_OP_Rename, - AGENT_OP_CopyFromFile -}; - -class CAgentFolder: - public IFolderFolder, - public IFolderAltStreams, - public IFolderProperties, - public IArchiveGetRawProps, - public IGetFolderArcProps, - public IFolderCompare, - public IFolderGetItemName, - public IArchiveFolder, - public IArchiveFolderInternal, - public IInArchiveGetStream, - // public IFolderSetReplaceAltStreamCharsMode, -#ifdef NEW_FOLDER_INTERFACE - public IFolderOperations, - public IFolderSetFlatMode, -#endif - public CMyUnknownImp -{ - void LoadFolder(unsigned proxyDirIndex); -public: - - MY_QUERYINTERFACE_BEGIN2(IFolderFolder) - MY_QUERYINTERFACE_ENTRY(IFolderAltStreams) - MY_QUERYINTERFACE_ENTRY(IFolderProperties) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IGetFolderArcProps) - MY_QUERYINTERFACE_ENTRY(IFolderCompare) - MY_QUERYINTERFACE_ENTRY(IFolderGetItemName) - MY_QUERYINTERFACE_ENTRY(IArchiveFolder) - MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal) - MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream) - // MY_QUERYINTERFACE_ENTRY(IFolderSetReplaceAltStreamCharsMode) - #ifdef NEW_FOLDER_INTERFACE - MY_QUERYINTERFACE_ENTRY(IFolderOperations) - MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - HRESULT BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); - HRESULT BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); - int GetRealIndex(unsigned index) const; - void GetRealIndices(const UInt32 *indices, UInt32 numItems, - bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const; - - // INTERFACE_FolderSetReplaceAltStreamCharsMode(;) - - INTERFACE_FolderFolder(;) - INTERFACE_FolderAltStreams(;) - INTERFACE_FolderProperties(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IFolderGetItemName(;) - - STDMETHOD(GetFolderArcProps)(IFolderArcProps **object); - STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); - int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); - - // IArchiveFolder - INTERFACE_IArchiveFolder(;) - - STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder); - - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - - #ifdef NEW_FOLDER_INTERFACE - INTERFACE_FolderOperations(;) - - STDMETHOD(SetFlatMode)(Int32 flatMode); - #endif - - CAgentFolder(): - _proxyDirIndex(0), - _isAltStreamFolder(false), - _flatMode(false), - _loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now - /* , _replaceAltStreamCharsMode(0) */ - {} - - void Init(const CProxyArc *proxy, const CProxyArc2 *proxy2, - unsigned proxyDirIndex, - /* IFolderFolder *parentFolder, */ - CAgent *agent) - { - _proxy = proxy; - _proxy2 = proxy2; - _proxyDirIndex = proxyDirIndex; - _isAltStreamFolder = false; - if (_proxy2) - _isAltStreamFolder = _proxy2->IsAltDir(proxyDirIndex); - // _parentFolder = parentFolder; - _agent = (IInFolderArchive *)agent; - _agentSpec = agent; - } - - void GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder); - HRESULT CommonUpdateOperation( - AGENT_OP operation, - bool moveMode, - const wchar_t *newItemName, - const NUpdateArchive::CActionSet *actionSet, - const UInt32 *indices, UInt32 numItems, - IProgress *progress); - - - void GetPrefix(UInt32 index, UString &prefix) const; - UString GetName(UInt32 index) const; - UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive - -public: - const CProxyArc *_proxy; - const CProxyArc2 *_proxy2; - unsigned _proxyDirIndex; - bool _isAltStreamFolder; - // CMyComPtr _parentFolder; - CMyComPtr _agent; - CAgent *_agentSpec; - - CRecordVector _items; - bool _flatMode; - bool _loadAltStreams; // in Flat mode - // Int32 _replaceAltStreamCharsMode; -}; - -class CAgent: - public IInFolderArchive, - public IFolderArcProps, - #ifndef EXTRACT_ONLY - public IOutFolderArchive, - public ISetProperties, - #endif - public CMyUnknownImp -{ -public: - - MY_QUERYINTERFACE_BEGIN2(IInFolderArchive) - MY_QUERYINTERFACE_ENTRY(IFolderArcProps) - #ifndef EXTRACT_ONLY - MY_QUERYINTERFACE_ENTRY(IOutFolderArchive) - MY_QUERYINTERFACE_ENTRY(ISetProperties) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IInFolderArchive(;) - INTERFACE_IFolderArcProps(;) - - #ifndef EXTRACT_ONLY - INTERFACE_IOutFolderArchive(;) - - HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream, - unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback); - - HRESULT CreateFolder(ISequentialOutStream *outArchiveStream, - const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100); - - HRESULT RenameItem(ISequentialOutStream *outArchiveStream, - const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, - IFolderArchiveUpdateCallback *updateCallback100); - - HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream, - const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath, - IFolderArchiveUpdateCallback *updateCallback100); - - // ISetProperties - STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps); - #endif - - CAgent(); - ~CAgent(); -private: - HRESULT ReadItems(); -public: - CProxyArc *_proxy; - CProxyArc2 *_proxy2; - CArchiveLink _archiveLink; - - bool ThereIsPathProp; - // bool ThereIsAltStreamProp; - - UString ArchiveType; - - FStringVector _names; - FString _folderPrefix; - - bool _updatePathPrefix_is_AltFolder; - UString _updatePathPrefix; - CAgentFolder *_agentFolder; - - UString _archiveFilePath; - bool _isDeviceFile; - - #ifndef EXTRACT_ONLY - CObjectVector m_PropNames; - CObjectVector m_PropValues; - #endif - - const CArc &GetArc() const { return _archiveLink.Arcs.Back(); } - IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; } - bool CanUpdate() const; - - bool IsThereReadOnlyArc() const - { - FOR_VECTOR (i, _archiveLink.Arcs) - { - const CArc &arc = _archiveLink.Arcs[i]; - if (arc.FormatIndex < 0 - || arc.IsReadOnly - || !g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled) - return true; - } - return false; - } - - UString GetTypeOfArc(const CArc &arc) const - { - if (arc.FormatIndex < 0) - return L"Parser"; - return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex); - } - - UString GetErrorMessage() const - { - UString s; - for (int i = _archiveLink.Arcs.Size() - 1; i >= 0; i--) - { - const CArc &arc = _archiveLink.Arcs[i]; - - UString s2; - if (arc.ErrorInfo.ErrorFormatIndex >= 0) - { - if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex) - s2.AddAscii("Warning: The archive is open with offset"); - else - { - s2.AddAscii("Can not open the file as ["); - s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex); - s2.AddAscii("] archive"); - } - } - - if (!arc.ErrorInfo.ErrorMessage.IsEmpty()) - { - if (!s2.IsEmpty()) - s2.Add_LF(); - s2.AddAscii("\n["); - s2 += GetTypeOfArc(arc); - s2.AddAscii("]: "); - s2 += arc.ErrorInfo.ErrorMessage; - } - - if (!s2.IsEmpty()) - { - if (!s.IsEmpty()) - s.AddAscii("--------------------\n"); - s += arc.Path; - s.Add_LF(); - s += s2; - s.Add_LF(); - } - } - return s; - } - - void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); } - -}; - - -#ifdef NEW_FOLDER_INTERFACE - -class CArchiveFolderManager: - public IFolderManager, - public CMyUnknownImp -{ - void LoadFormats(); - int FindFormat(const UString &type); -public: - MY_UNKNOWN_IMP1(IFolderManager) - INTERFACE_IFolderManager(;) -}; - -#endif - -#endif +// Agent/Agent.h + +#ifndef ZIP7_INC_AGENT_AGENT_H +#define ZIP7_INC_AGENT_AGENT_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/PropVariant.h" + +#include "../Common/LoadCodecs.h" +#include "../Common/OpenArchive.h" +#include "../Common/UpdateAction.h" + +#include "../FileManager/IFolder.h" + +#include "AgentProxy.h" +#include "IFolderArchive.h" + +extern CCodecs *g_CodecsObj; +HRESULT LoadGlobalCodecs(); +void FreeGlobalCodecs(); + +class CAgentFolder; + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEM_IArchiveFolderInternal(x) \ + x(GetAgentFolder(CAgentFolder **agentFolder)) +Z7_IFACE_CONSTR_FOLDERARC(IArchiveFolderInternal, 0xC) + +Z7_PURE_INTERFACES_END + +struct CProxyItem +{ + unsigned DirIndex; + unsigned Index; +}; + +class CAgent; + +enum AGENT_OP +{ + AGENT_OP_Uni, + AGENT_OP_Delete, + AGENT_OP_CreateFolder, + AGENT_OP_Rename, + AGENT_OP_CopyFromFile, + AGENT_OP_Comment +}; + +class CAgentFolder Z7_final: + public IFolderFolder, + public IFolderAltStreams, + public IFolderProperties, + public IArchiveGetRawProps, + public IGetFolderArcProps, + public IFolderCompare, + public IFolderGetItemName, + public IArchiveFolder, + public IArchiveFolderInternal, + public IInArchiveGetStream, + public IFolderSetZoneIdMode, + public IFolderSetZoneIdFile, + public IFolderOperations, + public IFolderSetFlatMode, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IFolderFolder) + Z7_COM_QI_ENTRY(IFolderAltStreams) + Z7_COM_QI_ENTRY(IFolderProperties) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IGetFolderArcProps) + Z7_COM_QI_ENTRY(IFolderCompare) + Z7_COM_QI_ENTRY(IFolderGetItemName) + Z7_COM_QI_ENTRY(IArchiveFolder) + Z7_COM_QI_ENTRY(IArchiveFolderInternal) + Z7_COM_QI_ENTRY(IInArchiveGetStream) + Z7_COM_QI_ENTRY(IFolderSetZoneIdMode) + Z7_COM_QI_ENTRY(IFolderSetZoneIdFile) + Z7_COM_QI_ENTRY(IFolderOperations) + Z7_COM_QI_ENTRY(IFolderSetFlatMode) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IFolderFolder) + Z7_IFACE_COM7_IMP(IFolderAltStreams) + Z7_IFACE_COM7_IMP(IFolderProperties) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IGetFolderArcProps) + Z7_IFACE_COM7_IMP(IFolderCompare) + Z7_IFACE_COM7_IMP(IFolderGetItemName) + Z7_IFACE_COM7_IMP(IArchiveFolder) + Z7_IFACE_COM7_IMP(IArchiveFolderInternal) + Z7_IFACE_COM7_IMP(IInArchiveGetStream) + Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode) + Z7_IFACE_COM7_IMP(IFolderSetZoneIdFile) + Z7_IFACE_COM7_IMP(IFolderOperations) + Z7_IFACE_COM7_IMP(IFolderSetFlatMode) + + void LoadFolder(unsigned proxyDirIndex); +public: + HRESULT BindToFolder_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); + HRESULT BindToAltStreams_Internal(unsigned proxyDirIndex, IFolderFolder **resultFolder); + int GetRealIndex(unsigned index) const; + void GetRealIndices(const UInt32 *indices, UInt32 numItems, + bool includeAltStreams, bool includeFolderSubItemsInFlatMode, CUIntVector &realIndices) const; + + int CompareItems3(UInt32 index1, UInt32 index2, PROPID propID); + int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); + + CAgentFolder(): + _isAltStreamFolder(false), + _flatMode(false), + _loadAltStreams(false), // _loadAltStreams alt streams works in flat mode, but we don't use it now + _proxyDirIndex(0), + _zoneMode(NExtract::NZoneIdMode::kNone) + /* , _replaceAltStreamCharsMode(0) */ + {} + + void Init(const CProxyArc *proxy, const CProxyArc2 *proxy2, + unsigned proxyDirIndex, + /* IFolderFolder *parentFolder, */ + CAgent *agent) + { + _proxy = proxy; + _proxy2 = proxy2; + _proxyDirIndex = proxyDirIndex; + _isAltStreamFolder = false; + if (_proxy2) + _isAltStreamFolder = _proxy2->IsAltDir(proxyDirIndex); + // _parentFolder = parentFolder; + _agent = (IInFolderArchive *)agent; + _agentSpec = agent; + } + + void GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder); + HRESULT CommonUpdateOperation( + AGENT_OP operation, + bool moveMode, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UInt32 *indices, UInt32 numItems, + IProgress *progress); + + + void GetPrefix(UInt32 index, UString &prefix) const; + UString GetName(UInt32 index) const; + UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive + +public: + bool _isAltStreamFolder; + bool _flatMode; + bool _loadAltStreams; // in Flat mode + const CProxyArc *_proxy; + const CProxyArc2 *_proxy2; + unsigned _proxyDirIndex; + NExtract::NZoneIdMode::EEnum _zoneMode; + CByteBuffer _zoneBuf; + // Int32 _replaceAltStreamCharsMode; + // CMyComPtr _parentFolder; + CMyComPtr _agent; + CAgent *_agentSpec; + CRecordVector _items; +}; + + + +class CAgent Z7_final: + public IInFolderArchive, + public IFolderArcProps, + #ifndef Z7_EXTRACT_ONLY + public IOutFolderArchive, + public ISetProperties, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IInFolderArchive) + Z7_COM_QI_ENTRY(IFolderArcProps) + #ifndef Z7_EXTRACT_ONLY + Z7_COM_QI_ENTRY(IOutFolderArchive) + Z7_COM_QI_ENTRY(ISetProperties) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IInFolderArchive) + Z7_IFACE_COM7_IMP(IFolderArcProps) + + #ifndef Z7_EXTRACT_ONLY + Z7_IFACE_COM7_IMP(ISetProperties) + +public: + Z7_IFACE_COM7_IMP(IOutFolderArchive) + HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream, + unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback); + + HRESULT CreateFolder(ISequentialOutStream *outArchiveStream, + const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100); + + HRESULT RenameItem(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100); + + HRESULT CommentItem(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100); + + HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath, + IFolderArchiveUpdateCallback *updateCallback100); + #endif + +private: + HRESULT ReadItems(); + +public: + CProxyArc *_proxy; + CProxyArc2 *_proxy2; + CArchiveLink _archiveLink; + + UString ArchiveType; + + FStringVector _names; + FString _folderPrefix; // for new files from disk + + UString _updatePathPrefix; + CAgentFolder *_agentFolder; + + UString _archiveFilePath; // it can be path of non-existing file if file is virtual + + DWORD _attrib; + bool _updatePathPrefix_is_AltFolder; + bool ThereIsPathProp; + bool _isDeviceFile; + bool _isHashHandler; + + FString _hashBaseFolderPrefix; + + #ifndef Z7_EXTRACT_ONLY + CObjectVector m_PropNames; + CObjectVector m_PropValues; + #endif + + CAgent(); + ~CAgent(); + + const CArc &GetArc() const { return _archiveLink.Arcs.Back(); } + IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return NULL; return GetArc().Archive; } + bool CanUpdate() const; + + bool Is_Attrib_ReadOnly() const + { + return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY); + } + + bool IsThere_ReadOnlyArc() const + { + FOR_VECTOR (i, _archiveLink.Arcs) + { + const CArc &arc = _archiveLink.Arcs[i]; + if (arc.FormatIndex < 0 + || arc.IsReadOnly + || !g_CodecsObj->Formats[arc.FormatIndex].UpdateEnabled) + return true; + } + return false; + } + + UString GetTypeOfArc(const CArc &arc) const + { + if (arc.FormatIndex < 0) + return UString("Parser"); + return g_CodecsObj->GetFormatNamePtr(arc.FormatIndex); + } + + UString GetErrorMessage() const + { + UString s; + for (int i = (int)_archiveLink.Arcs.Size() - 1; i >= 0; i--) + { + const CArc &arc = _archiveLink.Arcs[i]; + + UString s2; + if (arc.ErrorInfo.ErrorFormatIndex >= 0) + { + if (arc.ErrorInfo.ErrorFormatIndex == arc.FormatIndex) + s2 += "Warning: The archive is open with offset"; + else + { + s2 += "Cannot open the file as ["; + s2 += g_CodecsObj->GetFormatNamePtr(arc.ErrorInfo.ErrorFormatIndex); + s2 += "] archive"; + } + } + + if (!arc.ErrorInfo.ErrorMessage.IsEmpty()) + { + if (!s2.IsEmpty()) + s2.Add_LF(); + s2 += "\n["; + s2 += GetTypeOfArc(arc); + s2 += "]: "; + s2 += arc.ErrorInfo.ErrorMessage; + } + + if (!s2.IsEmpty()) + { + if (!s.IsEmpty()) + s += "--------------------\n"; + s += arc.Path; + s.Add_LF(); + s += s2; + s.Add_LF(); + } + } + return s; + } + + void KeepModeForNextOpen() { _archiveLink.KeepModeForNextOpen(); } +}; + + +// #ifdef NEW_FOLDER_INTERFACE + +struct CCodecIcons +{ + struct CIconPair + { + UString Ext; + int IconIndex; + }; + CObjectVector IconPairs; + + // void Clear() { IconPairs.Clear(); } + void LoadIcons(HMODULE m); + bool FindIconIndex(const UString &ext, int &iconIndex) const; +}; + + +Z7_CLASS_IMP_COM_1( + CArchiveFolderManager + , IFolderManager +) + CObjectVector CodecIconsVector; + CCodecIcons InternalIcons; + bool WasLoaded; + + void LoadFormats(); + // int FindFormat(const UString &type); +public: + CArchiveFolderManager(): + WasLoaded(false) + {} +}; + +// #endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentOut.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentOut.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentOut.cpp 2024-01-23 20:00:00.000000000 +0000 @@ -1,660 +1,718 @@ -// AgentOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "../../Common/FileStreams.h" - -#include "Agent.h" -#include "UpdateCallbackAgent.h" - -using namespace NWindows; -using namespace NCOM; - -STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder) -{ - _updatePathPrefix.Empty(); - _updatePathPrefix_is_AltFolder = false; - _agentFolder = NULL; - - if (!folder) - return S_OK; - - { - CMyComPtr afi; - RINOK(folder->QueryInterface(IID_IArchiveFolderInternal, (void **)&afi)); - if (afi) - { - RINOK(afi->GetAgentFolder(&_agentFolder)); - } - if (!_agentFolder) - return E_FAIL; - } - - if (_proxy2) - _updatePathPrefix = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, _updatePathPrefix_is_AltFolder); - else - _updatePathPrefix = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex); - return S_OK; -} - -STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix, - const wchar_t * const *names, UInt32 numNames) -{ - _folderPrefix = us2fs(folderPrefix); - _names.ClearAndReserve(numNames); - for (UInt32 i = 0; i < numNames; i++) - _names.AddInReserved(us2fs(names[i])); - return S_OK; -} - -static HRESULT EnumerateArchiveItems(CAgent *agent, - const CProxyDir &item, - const UString &prefix, - CObjectVector &arcItems) -{ - unsigned i; - - for (i = 0; i < item.SubFiles.Size(); i++) - { - 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)); - ai.IsDir = false; - ai.Name = prefix + fileItem.Name; - ai.Censored = true; // test it - ai.IndexInServer = arcIndex; - arcItems.Add(ai); - } - - for (i = 0; i < item.SubDirs.Size(); i++) - { - const CProxyDir &dirItem = agent->_proxy->Dirs[item.SubDirs[i]]; - UString fullName = prefix + dirItem.Name; - if (dirItem.IsLeaf()) - { - CArcItem ai; - RINOK(agent->GetArc().GetItemMTime(dirItem.ArcIndex, ai.MTime, ai.MTimeDefined)); - ai.IsDir = true; - ai.SizeDefined = false; - ai.Name = fullName; - ai.Censored = true; // test it - ai.IndexInServer = dirItem.ArcIndex; - arcItems.Add(ai); - } - RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems)); - } - - return S_OK; -} - -static HRESULT EnumerateArchiveItems2(const CAgent *agent, - unsigned dirIndex, - const UString &prefix, - CObjectVector &arcItems) -{ - const CProxyDir2 &dir = agent->_proxy2->Dirs[dirIndex]; - FOR_VECTOR (i, dir.Items) - { - unsigned arcIndex = dir.Items[i]; - const CProxyFile2 &file = agent->_proxy2->Files[arcIndex]; - CArcItem ai; - ai.IndexInServer = arcIndex; - ai.Name = prefix + file.Name; - ai.Censored = true; // test it - RINOK(agent->GetArc().GetItemMTime(arcIndex, ai.MTime, ai.MTimeDefined)); - ai.IsDir = file.IsDir(); - ai.SizeDefined = false; - ai.IsAltStream = file.IsAltStream; - if (!ai.IsDir) - { - RINOK(agent->GetArc().GetItemSize(arcIndex, ai.Size, ai.SizeDefined)); - ai.IsDir = false; - } - arcItems.Add(ai); - - if (file.AltDirIndex >= 0) - { - RINOK(EnumerateArchiveItems2(agent, file.AltDirIndex, ai.Name + L':', arcItems)); - } - - if (ai.IsDir) - { - RINOK(EnumerateArchiveItems2(agent, file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems)); - } - } - return S_OK; -} - -struct CAgUpCallbackImp: public IUpdateProduceCallback -{ - const CObjectVector *_arcItems; - IFolderArchiveUpdateCallback *_callback; - - CAgUpCallbackImp(const CObjectVector *a, - IFolderArchiveUpdateCallback *callback): _arcItems(a), _callback(callback) {} - HRESULT ShowDeleteFile(unsigned arcIndex); -}; - -HRESULT CAgUpCallbackImp::ShowDeleteFile(unsigned arcIndex) -{ - return _callback->DeleteOperation((*_arcItems)[arcIndex].Name); -} - - -static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd) -{ - if (agent->_archiveLink.Arcs.IsEmpty()) - return; - const CArc &arc = agent->GetArc(); - upd->Arc = &arc; - upd->Archive = arc.Archive; -} - -struct CDirItemsCallback_AgentOut: public IDirItemsCallback -{ - CMyComPtr FolderScanProgress; - IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback; - HRESULT ErrorCode; - - CDirItemsCallback_AgentOut(): ErrorCode(S_OK), FolderArchiveUpdateCallback(NULL) {} - - HRESULT ScanError(const FString &name, DWORD systemError) - { - HRESULT hres = HRESULT_FROM_WIN32(systemError); - if (FolderArchiveUpdateCallback) - return FolderScanProgress->ScanError(fs2us(name), hres); - ErrorCode = hres; - return ErrorCode; - } - - HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) - { - if (FolderScanProgress) - return FolderScanProgress->ScanProgress(st.NumDirs, st.NumFiles + st.NumAltStreams, - st.GetTotalBytes(), fs2us(path), BoolToInt(isDir)); - - if (FolderArchiveUpdateCallback) - return FolderArchiveUpdateCallback->SetNumFiles(st.NumFiles); - - return S_OK; - } -}; - -STDMETHODIMP CAgent::DoOperation( - FStringVector *requestedPaths, - FStringVector *processedPaths, - CCodecs *codecs, - int formatIndex, - ISequentialOutStream *outArchiveStream, - const Byte *stateActions, - const wchar_t *sfxModule, - IFolderArchiveUpdateCallback *updateCallback100) -{ - if (!CanUpdate()) - return E_NOTIMPL; - - NUpdateArchive::CActionSet actionSet; - { - for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) - actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; - } - - CDirItemsCallback_AgentOut enumCallback; - if (updateCallback100) - { - enumCallback.FolderArchiveUpdateCallback = updateCallback100; - updateCallback100->QueryInterface(IID_IFolderScanProgress, (void **)&enumCallback.FolderScanProgress); - } - - CDirItems dirItems; - dirItems.Callback = &enumCallback; - - { - FString folderPrefix = _folderPrefix; - NFile::NName::NormalizeDirPathPrefix(folderPrefix); - - RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths)); - - if (_updatePathPrefix_is_AltFolder) - { - FOR_VECTOR(i, dirItems.Items) - { - CDirItem &item = dirItems.Items[i]; - if (item.IsDir()) - return E_NOTIMPL; - item.IsAltStream = true; - } - } - } - - CMyComPtr outArchive; - - if (GetArchive()) - { - RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); - } - else - { - if (formatIndex < 0) - return E_FAIL; - RINOK(codecs->CreateOutArchive(formatIndex, outArchive)); - - #ifdef EXTERNAL_CODECS - { - CMyComPtr setCompressCodecsInfo; - outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); - } - } - #endif - } - - NFileTimeType::EEnum fileTimeType; - UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); - - switch (value) - { - case NFileTimeType::kWindows: - case NFileTimeType::kDOS: - case NFileTimeType::kUnix: - fileTimeType = NFileTimeType::EEnum(value); - break; - default: - return E_FAIL; - } - - - CObjectVector arcItems; - if (GetArchive()) - { - RINOK(ReadItems()); - if (_proxy2) - { - RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems)); - RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems)); - } - else - { - RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems)); - } - } - - CRecordVector updatePairs2; - - { - CRecordVector updatePairs; - GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); - CAgUpCallbackImp upCallback(&arcItems, updateCallback100); - UpdateProduce(updatePairs, actionSet, updatePairs2, &upCallback); - } - - UInt32 numFiles = 0; - { - FOR_VECTOR (i, updatePairs2) - if (updatePairs2[i].NewData) - numFiles++; - } - - if (updateCallback100) - { - RINOK(updateCallback100->SetNumFiles(numFiles)); - } - - CUpdateCallbackAgent updateCallbackAgent; - updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec ); - - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->ArcItems = &arcItems; - updateCallbackSpec->UpdatePairs = &updatePairs2; - - SetInArchiveInterfaces(this, updateCallbackSpec); - - updateCallbackSpec->Callback = &updateCallbackAgent; - - CByteBuffer processedItems; - if (processedPaths) - { - unsigned num = dirItems.Items.Size(); - processedItems.Alloc(num); - for (unsigned i = 0; i < num; i++) - processedItems[i] = 0; - updateCallbackSpec->ProcessedItemsStatuses = processedItems; - } - - CMyComPtr setProperties; - if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) - { - if (m_PropNames.Size() == 0) - { - RINOK(setProperties->SetProperties(0, 0, 0)); - } - else - { - CRecordVector names; - FOR_VECTOR (i, m_PropNames) - names.Add((const wchar_t *)m_PropNames[i]); - - CPropVariant *propValues = new CPropVariant[m_PropValues.Size()]; - try - { - FOR_VECTOR (i, m_PropValues) - propValues[i] = m_PropValues[i]; - RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size())); - } - catch(...) - { - delete []propValues; - return E_FAIL; - } - delete []propValues; - } - } - m_PropNames.Clear(); - m_PropValues.Clear(); - - if (sfxModule != NULL) - { - CInFileStream *sfxStreamSpec = new CInFileStream; - CMyComPtr sfxStream(sfxStreamSpec); - if (!sfxStreamSpec->Open(us2fs(sfxModule))) - return E_FAIL; - // throw "Can't open sfx module"; - RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL)); - } - - HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback); - if (res == S_OK && processedPaths) - { - { - /* OutHandler for 7z archives doesn't report compression operation for empty files. - So we must include these files manually */ - FOR_VECTOR(i, updatePairs2) - { - const CUpdatePair2 &up = updatePairs2[i]; - if (up.DirIndex >= 0 && up.NewData) - { - const CDirItem &di = dirItems.Items[up.DirIndex]; - if (!di.IsDir() && di.Size == 0) - processedItems[up.DirIndex] = 1; - } - } - } - - FOR_VECTOR (i, dirItems.Items) - if (processedItems[i] != 0) - processedPaths->Add(dirItems.GetPhyPath(i)); - } - return res; -} - -STDMETHODIMP CAgent::DoOperation2( - FStringVector *requestedPaths, - FStringVector *processedPaths, - ISequentialOutStream *outArchiveStream, - const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100) -{ - return DoOperation(requestedPaths, processedPaths, g_CodecsObj, -1, outArchiveStream, stateActions, sfxModule, updateCallback100); -} - -HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream, - unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback) -{ - if (!CanUpdate()) - return E_NOTIMPL; - CMyComPtr outArchive; - RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); - return outArchive->UpdateItems(outArchiveStream, numUpdateItems, updateCallback); -} - -STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream, - const UInt32 *indices, UInt32 numItems, - IFolderArchiveUpdateCallback *updateCallback100) -{ - if (!CanUpdate()) - return E_NOTIMPL; - CRecordVector updatePairs; - CUpdateCallbackAgent updateCallbackAgent; - updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - CUIntVector realIndices; - _agentFolder->GetRealIndices(indices, numItems, - true, // includeAltStreams - false, // includeFolderSubItemsInFlatMode, we don't want to delete subItems in Flat Mode - realIndices); - unsigned curIndex = 0; - UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); - - UString deletePath; - - for (UInt32 i = 0; i < numItemsInArchive; i++) - { - if (curIndex < realIndices.Size()) - if (realIndices[curIndex] == i) - { - RINOK(GetArc().GetItemPath2(i, deletePath)); - RINOK(updateCallback100->DeleteOperation(deletePath)); - - curIndex++; - continue; - } - CUpdatePair2 up2; - up2.SetAs_NoChangeArcItem(i); - updatePairs.Add(up2); - } - updateCallbackSpec->UpdatePairs = &updatePairs; - - SetInArchiveInterfaces(this, updateCallbackSpec); - - updateCallbackSpec->Callback = &updateCallbackAgent; - return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); -} - -HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream, - const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100) -{ - if (!CanUpdate()) - return E_NOTIMPL; - CRecordVector updatePairs; - CDirItems dirItems; - CUpdateCallbackAgent updateCallbackAgent; - updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); - for (UInt32 i = 0; i < numItemsInArchive; i++) - { - CUpdatePair2 up2; - up2.SetAs_NoChangeArcItem(i); - updatePairs.Add(up2); - } - CUpdatePair2 up2; - up2.NewData = up2.NewProps = true; - up2.UseArcProps = false; - up2.DirIndex = 0; - - updatePairs.Add(up2); - - updatePairs.ReserveDown(); - - CDirItem di; - - di.Attrib = FILE_ATTRIBUTE_DIRECTORY; - di.Size = 0; - bool isAltStreamFolder = false; - if (_proxy2) - di.Name = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, isAltStreamFolder); - else - di.Name = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex); - di.Name += folderName; - - FILETIME ft; - NTime::GetCurUtcFileTime(ft); - di.CTime = di.ATime = di.MTime = ft; - - dirItems.Items.Add(di); - - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->UpdatePairs = &updatePairs; - - SetInArchiveInterfaces(this, updateCallbackSpec); - - return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); -} - - -HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream, - const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, - IFolderArchiveUpdateCallback *updateCallback100) -{ - if (!CanUpdate()) - return E_NOTIMPL; - if (numItems != 1) - return E_INVALIDARG; - if (!_archiveLink.IsOpen) - return E_FAIL; - CRecordVector updatePairs; - CUpdateCallbackAgent updateCallbackAgent; - updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - CUIntVector realIndices; - _agentFolder->GetRealIndices(indices, numItems, - true, // includeAltStreams - 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; - - UStringVector newNames; - - unsigned curIndex = 0; - UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); - - for (UInt32 i = 0; i < numItemsInArchive; i++) - { - CUpdatePair2 up2; - up2.SetAs_NoChangeArcItem(i); - if (curIndex < realIndices.Size()) - if (realIndices[curIndex] == i) - { - up2.NewProps = true; - RINOK(GetArc().IsItemAnti(i, up2.IsAnti)); // it must work without that line too. - - UString oldFullPath; - RINOK(GetArc().GetItemPath2(i, oldFullPath)); - - if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath)) - return E_INVALIDARG; - - up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len())); - up2.IsMainRenameItem = (mainRealIndex == (int)i); - curIndex++; - } - updatePairs.Add(up2); - } - - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->UpdatePairs = &updatePairs; - updateCallbackSpec->NewNames = &newNames; - - SetInArchiveInterfaces(this, updateCallbackSpec); - - return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); -} - -HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream, - const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath, - IFolderArchiveUpdateCallback *updateCallback100) -{ - if (!CanUpdate()) - return E_NOTIMPL; - CRecordVector updatePairs; - CDirItems dirItems; - CUpdateCallbackAgent updateCallbackAgent; - updateCallbackAgent.SetCallback(updateCallback100); - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - UInt32 realIndex; - { - CUIntVector realIndices; - _agentFolder->GetRealIndices(indices, numItems, - false, // includeAltStreams // we update only main stream of file - false, // includeFolderSubItemsInFlatMode - realIndices); - if (realIndices.Size() != 1) - return E_FAIL; - realIndex = realIndices[0]; - } - - { - FStringVector filePaths; - filePaths.Add(us2fs(diskFilePath)); - dirItems.EnumerateItems2(FString(), UString(), filePaths, NULL); - if (dirItems.Items.Size() != 1) - return E_FAIL; - } - - UInt32 numItemsInArchive; - RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); - for (UInt32 i = 0; i < numItemsInArchive; i++) - { - CUpdatePair2 up2; - up2.SetAs_NoChangeArcItem(i); - if (realIndex == i) - { - up2.DirIndex = 0; - up2.NewData = true; - up2.NewProps = true; - up2.UseArcProps = false; - } - updatePairs.Add(up2); - } - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->Callback = &updateCallbackAgent; - updateCallbackSpec->UpdatePairs = &updatePairs; - - SetInArchiveInterfaces(this, updateCallbackSpec); - - updateCallbackSpec->KeepOriginalItemNames = true; - return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); -} - -STDMETHODIMP CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) -{ - m_PropNames.Clear(); - m_PropValues.Clear(); - for (UInt32 i = 0; i < numProps; i++) - { - m_PropNames.Add(names[i]); - m_PropValues.Add(values[i]); - } - return S_OK; -} +// AgentOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../../Common/FileStreams.h" + +#include "../../Archive/Common/ItemNameUtils.h" + +#include "Agent.h" +#include "UpdateCallbackAgent.h" + +using namespace NWindows; +using namespace NCOM; + +Z7_COM7F_IMF(CAgent::SetFolder(IFolderFolder *folder)) +{ + _updatePathPrefix.Empty(); + _updatePathPrefix_is_AltFolder = false; + _agentFolder = NULL; + + if (!folder) + return S_OK; + + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveFolderInternal, + afi, folder) + if (afi) + { + RINOK(afi->GetAgentFolder(&_agentFolder)) + } + if (!_agentFolder) + return E_FAIL; + } + + if (_proxy2) + _updatePathPrefix = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, _updatePathPrefix_is_AltFolder); + else + _updatePathPrefix = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex); + return S_OK; +} + +Z7_COM7F_IMF(CAgent::SetFiles(const wchar_t *folderPrefix, + const wchar_t * const *names, UInt32 numNames)) +{ + _folderPrefix = us2fs(folderPrefix); + _names.ClearAndReserve(numNames); + for (UInt32 i = 0; i < numNames; i++) + _names.AddInReserved(us2fs(names[i])); + return S_OK; +} + +static HRESULT EnumerateArchiveItems(CAgent *agent, + const CProxyDir &item, + const UString &prefix, + CObjectVector &arcItems) +{ + unsigned i; + + for (i = 0; i < item.SubFiles.Size(); i++) + { + unsigned arcIndex = item.SubFiles[i]; + const CProxyFile &fileItem = agent->_proxy->Files[arcIndex]; + CArcItem ai; + 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 + ai.IndexInServer = arcIndex; + arcItems.Add(ai); + } + + for (i = 0; i < item.SubDirs.Size(); i++) + { + const CProxyDir &dirItem = agent->_proxy->Dirs[item.SubDirs[i]]; + UString fullName = prefix + dirItem.Name; + if (dirItem.IsLeaf()) + { + CArcItem ai; + RINOK(agent->GetArc().GetItem_MTime((unsigned)dirItem.ArcIndex, ai.MTime)) + ai.IsDir = true; + ai.Size_Defined = false; + ai.Name = fullName; + ai.Censored = true; // test it + ai.IndexInServer = (unsigned)dirItem.ArcIndex; + arcItems.Add(ai); + } + RINOK(EnumerateArchiveItems(agent, dirItem, fullName + WCHAR_PATH_SEPARATOR, arcItems)) + } + + return S_OK; +} + +static HRESULT EnumerateArchiveItems2(const CAgent *agent, + unsigned dirIndex, + const UString &prefix, + CObjectVector &arcItems) +{ + const CProxyDir2 &dir = agent->_proxy2->Dirs[dirIndex]; + FOR_VECTOR (i, dir.Items) + { + unsigned arcIndex = dir.Items[i]; + const CProxyFile2 &file = agent->_proxy2->Files[arcIndex]; + CArcItem ai; + ai.IndexInServer = arcIndex; + ai.Name = prefix + file.Name; + ai.Censored = true; // test it + RINOK(agent->GetArc().GetItem_MTime(arcIndex, ai.MTime)) + ai.IsDir = file.IsDir(); + ai.Size_Defined = false; + ai.IsAltStream = file.IsAltStream; + if (!ai.IsDir) + { + RINOK(agent->GetArc().GetItem_Size(arcIndex, ai.Size, ai.Size_Defined)) + ai.IsDir = false; + } + arcItems.Add(ai); + + if (file.AltDirIndex != -1) + { + RINOK(EnumerateArchiveItems2(agent, (unsigned)file.AltDirIndex, ai.Name + L':', arcItems)) + } + + if (ai.IsDir) + { + RINOK(EnumerateArchiveItems2(agent, (unsigned)file.DirIndex, ai.Name + WCHAR_PATH_SEPARATOR, arcItems)) + } + } + return S_OK; +} + +struct CAgUpCallbackImp Z7_final: public IUpdateProduceCallback +{ + const CObjectVector *_arcItems; + IFolderArchiveUpdateCallback *_callback; + + CAgUpCallbackImp(const CObjectVector *a, + IFolderArchiveUpdateCallback *callback): _arcItems(a), _callback(callback) {} + HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; +}; + +HRESULT CAgUpCallbackImp::ShowDeleteFile(unsigned arcIndex) +{ + return _callback->DeleteOperation((*_arcItems)[arcIndex].Name); +} + + +static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd) +{ + if (agent->_archiveLink.Arcs.IsEmpty()) + return; + const CArc &arc = agent->GetArc(); + upd->Arc = &arc; + upd->Archive = arc.Archive; + + upd->ArcFileName = ExtractFileNameFromPath(arc.Path); +} + +struct CDirItemsCallback_AgentOut Z7_final: public IDirItemsCallback +{ + CMyComPtr FolderScanProgress; + IFolderArchiveUpdateCallback *FolderArchiveUpdateCallback; + HRESULT ErrorCode; + + CDirItemsCallback_AgentOut(): FolderArchiveUpdateCallback(NULL), ErrorCode(S_OK) {} + + HRESULT ScanError(const FString &name, DWORD systemError) Z7_override + { + const HRESULT hres = HRESULT_FROM_WIN32(systemError); + if (FolderArchiveUpdateCallback) + return FolderScanProgress->ScanError(fs2us(name), hres); + ErrorCode = hres; + return ErrorCode; + } + + HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) Z7_override + { + if (FolderScanProgress) + return FolderScanProgress->ScanProgress(st.NumDirs, st.NumFiles + st.NumAltStreams, + st.GetTotalBytes(), fs2us(path), BoolToInt(isDir)); + if (FolderArchiveUpdateCallback) + return FolderArchiveUpdateCallback->SetNumFiles(st.NumFiles); + return S_OK; + } +}; + + +Z7_COM7F_IMF(CAgent::DoOperation( + FStringVector *requestedPaths, + FStringVector *processedPaths, + CCodecs *codecs, + int formatIndex, + ISequentialOutStream *outArchiveStream, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback100)) +{ + if (!CanUpdate()) + return E_NOTIMPL; + + NUpdateArchive::CActionSet actionSet; + { + for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; + } + + CDirItemsCallback_AgentOut enumCallback; + if (updateCallback100) + { + enumCallback.FolderArchiveUpdateCallback = updateCallback100; + updateCallback100->QueryInterface(IID_IFolderScanProgress, (void **)&enumCallback.FolderScanProgress); + } + + CDirItems dirItems; + dirItems.Callback = &enumCallback; + + { + FString folderPrefix = _folderPrefix; + if (!NFile::NName::IsAltStreamPrefixWithColon(fs2us(folderPrefix))) + NFile::NName::NormalizeDirPathPrefix(folderPrefix); + + RINOK(dirItems.EnumerateItems2(folderPrefix, _updatePathPrefix, _names, requestedPaths)) + + if (_updatePathPrefix_is_AltFolder) + { + FOR_VECTOR(i, dirItems.Items) + { + CDirItem &item = dirItems.Items[i]; + if (item.IsDir()) + return E_NOTIMPL; + item.IsAltStream = true; + } + } + } + + CMyComPtr outArchive; + + if (GetArchive()) + { + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)) + } + else + { + if (formatIndex < 0) + return E_FAIL; + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) + + #ifdef Z7_EXTERNAL_CODECS + { + CMyComPtr setCompressCodecsInfo; + outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) + } + } + #endif + } + + 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: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + { + return E_FAIL; + } + } + */ + + + CObjectVector arcItems; + if (GetArchive()) + { + RINOK(ReadItems()) + if (_proxy2) + { + RINOK(EnumerateArchiveItems2(this, k_Proxy2_RootDirIndex, L"", arcItems)) + RINOK(EnumerateArchiveItems2(this, k_Proxy2_AltRootDirIndex, L":", arcItems)) + } + else + { + RINOK(EnumerateArchiveItems(this, _proxy->Dirs[0], L"", arcItems)) + } + } + + CRecordVector updatePairs2; + + { + CRecordVector updatePairs; + GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); + CAgUpCallbackImp upCallback(&arcItems, updateCallback100); + UpdateProduce(updatePairs, actionSet, updatePairs2, &upCallback); + } + + UInt32 numFiles = 0; + { + FOR_VECTOR (i, updatePairs2) + if (updatePairs2[i].NewData) + numFiles++; + } + + if (updateCallback100) + { + RINOK(updateCallback100->SetNumFiles(numFiles)) + } + + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + updateCallback->DirItems = &dirItems; + updateCallback->ArcItems = &arcItems; + updateCallback->UpdatePairs = &updatePairs2; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + updateCallback->Callback = &updateCallbackAgent; + + CByteBuffer processedItems; + if (processedPaths) + { + unsigned num = dirItems.Items.Size(); + processedItems.Alloc(num); + for (unsigned i = 0; i < num; i++) + processedItems[i] = 0; + updateCallback->ProcessedItemsStatuses = processedItems; + } + + Z7_DECL_CMyComPtr_QI_FROM( + ISetProperties, + setProperties, outArchive) + if (setProperties) + { + if (m_PropNames.Size() == 0) + { + RINOK(setProperties->SetProperties(NULL, NULL, 0)) + } + else + { + CRecordVector names; + FOR_VECTOR (i, m_PropNames) + names.Add((const wchar_t *)m_PropNames[i]); + + CPropVariant *propValues = new CPropVariant[m_PropValues.Size()]; + try + { + FOR_VECTOR (i, m_PropValues) + propValues[i] = m_PropValues[i]; + RINOK(setProperties->SetProperties(names.ConstData(), propValues, names.Size())) + } + catch(...) + { + delete []propValues; + return E_FAIL; + } + delete []propValues; + } + } + m_PropNames.Clear(); + m_PropValues.Clear(); + + if (sfxModule != NULL) + { + CMyComPtr2_Create sfxStream; + if (!sfxStream->Open(us2fs(sfxModule))) + return E_FAIL; + // throw "Can't open sfx module"; + RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL)) + } + + const HRESULT res = outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(), updateCallback); + if (res == S_OK && processedPaths) + { + { + /* OutHandler for 7z archives doesn't report compression operation for empty files. + So we must include these files manually */ + FOR_VECTOR(i, updatePairs2) + { + const CUpdatePair2 &up = updatePairs2[i]; + if (up.DirIndex != -1 && up.NewData) + { + const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; + if (!di.IsDir() && di.Size == 0) + processedItems[(unsigned)up.DirIndex] = 1; + } + } + } + + FOR_VECTOR (i, dirItems.Items) + if (processedItems[i] != 0) + processedPaths->Add(dirItems.GetPhyPath(i)); + } + return res; +} + +Z7_COM7F_IMF(CAgent::DoOperation2( + FStringVector *requestedPaths, + FStringVector *processedPaths, + ISequentialOutStream *outArchiveStream, + const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100)) +{ + return DoOperation(requestedPaths, processedPaths, g_CodecsObj, -1, outArchiveStream, stateActions, sfxModule, updateCallback100); +} + +HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream, + unsigned numUpdateItems, IArchiveUpdateCallback *updateCallback) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CMyComPtr outArchive; + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)) + return outArchive->UpdateItems(outArchiveStream, numUpdateItems, updateCallback); +} + +Z7_COM7F_IMF(CAgent::DeleteItems(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, + IFolderArchiveUpdateCallback *updateCallback100)) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CRecordVector updatePairs; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, + true, // includeAltStreams + false, // includeFolderSubItemsInFlatMode, we don't want to delete subItems in Flat Mode + realIndices); + unsigned curIndex = 0; + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) + + UString deletePath; + + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + RINOK(GetArc().GetItem_Path2(i, deletePath)) + RINOK(updateCallback100->DeleteOperation(deletePath)) + + curIndex++; + continue; + } + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(i); + updatePairs.Add(up2); + } + updateCallback->UpdatePairs = &updatePairs; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + updateCallback->Callback = &updateCallbackAgent; + return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); +} + +HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream, + const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CRecordVector updatePairs; + CDirItems dirItems; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(i); + updatePairs.Add(up2); + } + CUpdatePair2 up2; + up2.NewData = up2.NewProps = true; + up2.UseArcProps = false; + up2.DirIndex = 0; + + updatePairs.Add(up2); + + updatePairs.ReserveDown(); + + CDirItem di; + + di.Attrib = FILE_ATTRIBUTE_DIRECTORY; + di.Size = 0; + bool isAltStreamFolder = false; + if (_proxy2) + di.Name = _proxy2->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex, isAltStreamFolder); + else + di.Name = _proxy->GetDirPath_as_Prefix(_agentFolder->_proxyDirIndex); + di.Name += folderName; + + FILETIME ft; + NTime::GetCurUtcFileTime(ft); + di.CTime = di.ATime = di.MTime = ft; + + dirItems.Items.Add(di); + + updateCallback->Callback = &updateCallbackAgent; + updateCallback->DirItems = &dirItems; + updateCallback->UpdatePairs = &updatePairs; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); +} + + +HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + if (numItems != 1) + return E_INVALIDARG; + if (!_archiveLink.IsOpen) + return E_FAIL; + CRecordVector updatePairs; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, + true, // includeAltStreams + true, // includeFolderSubItemsInFlatMode + realIndices); + + 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; + + unsigned curIndex = 0; + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) + + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(i); + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + up2.NewProps = true; + RINOK(GetArc().IsItem_Anti(i, up2.IsAnti)) // it must work without that line too. + + UString oldFullPath; + RINOK(GetArc().GetItem_Path2(i, oldFullPath)) + + if (!IsPath1PrefixedByPath2(oldFullPath, oldItemPath)) + return E_INVALIDARG; + + up2.NewNameIndex = (int)newNames.Add(newItemPath + oldFullPath.Ptr(oldItemPath.Len())); + up2.IsMainRenameItem = (mainRealIndex == (int)i); + curIndex++; + } + updatePairs.Add(up2); + } + + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; + updateCallback->NewNames = &newNames; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); +} + + +HRESULT CAgent::CommentItem(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + if (numItems != 1) + return E_INVALIDARG; + if (!_archiveLink.IsOpen) + return E_FAIL; + + CRecordVector updatePairs; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + const int mainRealIndex = _agentFolder->GetRealIndex(indices[0]); + + if (mainRealIndex < 0) + return E_NOTIMPL; + + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) + + UString newName = newItemName; + + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(i); + if ((int)i == mainRealIndex) + up2.NewProps = true; + updatePairs.Add(up2); + } + + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; + updateCallback->CommentIndex = mainRealIndex; + updateCallback->Comment = &newName; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); +} + + + +HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream, + const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CRecordVector updatePairs; + CDirItems dirItems; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.SetCallback(updateCallback100); + CMyComPtr2_Create updateCallback; + + UInt32 realIndex; + { + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, + false, // includeAltStreams // we update only main stream of file + false, // includeFolderSubItemsInFlatMode + realIndices); + if (realIndices.Size() != 1) + return E_FAIL; + realIndex = realIndices[0]; + } + + { + FStringVector filePaths; + filePaths.Add(us2fs(diskFilePath)); + dirItems.EnumerateItems2(FString(), UString(), filePaths, NULL); + if (dirItems.Items.Size() != 1) + return E_FAIL; + } + + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)) + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(i); + if (realIndex == i) + { + up2.DirIndex = 0; + up2.NewData = true; + up2.NewProps = true; + up2.UseArcProps = false; + } + updatePairs.Add(up2); + } + updateCallback->DirItems = &dirItems; + updateCallback->Callback = &updateCallbackAgent; + updateCallback->UpdatePairs = &updatePairs; + + SetInArchiveInterfaces(this, updateCallback.ClsPtr()); + + updateCallback->KeepOriginalItemNames = true; + return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback); +} + +Z7_COM7F_IMF(CAgent::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + m_PropNames.Clear(); + m_PropValues.Clear(); + for (UInt32 i = 0; i < numProps; i++) + { + m_PropNames.Add(names[i]); + m_PropValues.Add(values[i]); + } + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentProxy.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentProxy.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.cpp 2024-01-23 20:00:00.000000000 +0000 @@ -1,717 +1,752 @@ -// AgentProxy.cpp - -#include "StdAfx.h" - -// #include -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "../../../../C/Sort.h" -#include "../../../../C/CpuArch.h" - -#include "../../../Common/UTFConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "AgentProxy.h" - -using namespace NWindows; - -int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const -{ - const CRecordVector &subDirs = Dirs[dirIndex].SubDirs; - unsigned left = 0, right = subDirs.Size(); - for (;;) - { - if (left == right) - { - insertPos = left; - return -1; - } - unsigned mid = (left + right) / 2; - unsigned dirIndex2 = subDirs[mid]; - int compare = CompareFileNames(name, Dirs[dirIndex2].Name); - if (compare == 0) - return dirIndex2; - if (compare < 0) - right = mid; - else - left = mid + 1; - } -} - -int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const -{ - unsigned insertPos; - return FindSubDir(dirIndex, name, insertPos); -} - -unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name) -{ - unsigned insertPos; - int subDirIndex = FindSubDir(dirIndex, name, insertPos); - if (subDirIndex >= 0) - { - if (arcIndex >= 0) - { - CProxyDir &item = Dirs[subDirIndex]; - if (item.ArcIndex < 0) - item.ArcIndex = arcIndex; - } - return subDirIndex; - } - subDirIndex = Dirs.Size(); - Dirs[dirIndex].SubDirs.Insert(insertPos, subDirIndex); - CProxyDir &item = Dirs.AddNew(); - - item.NameLen = name.Len(); - item.Name = new wchar_t[item.NameLen + 1]; - MyStringCopy((wchar_t *)item.Name, name); - - item.ArcIndex = arcIndex; - item.ParentDir = dirIndex; - return subDirIndex; -} - -void CProxyDir::Clear() -{ - SubDirs.Clear(); - SubFiles.Clear(); -} - -void CProxyArc::GetDirPathParts(int dirIndex, UStringVector &pathParts) const -{ - pathParts.Clear(); - while (dirIndex >= 0) - { - const CProxyDir &dir = Dirs[dirIndex]; - dirIndex = dir.ParentDir; - if (dirIndex < 0) - break; - pathParts.Insert(0, dir.Name); - } -} - -UString CProxyArc::GetDirPath_as_Prefix(int dirIndex) const -{ - UString s; - while (dirIndex >= 0) - { - const CProxyDir &dir = Dirs[dirIndex]; - dirIndex = dir.ParentDir; - if (dirIndex < 0) - break; - s.InsertAtFront(WCHAR_PATH_SEPARATOR); - s.Insert(0, dir.Name); - } - return s; -} - -void CProxyArc::AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const -{ - const CProxyDir &dir = Dirs[dirIndex]; - if (dir.IsLeaf()) - realIndices.Add(dir.ArcIndex); - unsigned i; - for (i = 0; i < dir.SubDirs.Size(); i++) - AddRealIndices(dir.SubDirs[i], realIndices); - for (i = 0; i < dir.SubFiles.Size(); i++) - realIndices.Add(dir.SubFiles[i]); -} - -int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const -{ - const CProxyDir &dir = Dirs[dirIndex]; - unsigned numDirItems = dir.SubDirs.Size(); - if (index < numDirItems) - { - const CProxyDir &f = Dirs[dir.SubDirs[index]]; - if (f.IsLeaf()) - return f.ArcIndex; - return -1; - } - return dir.SubFiles[index - numDirItems]; -} - -void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const -{ - const CProxyDir &dir = Dirs[dirIndex]; - realIndices.Clear(); - for (UInt32 i = 0; i < numItems; i++) - { - UInt32 index = indices[i]; - unsigned numDirItems = dir.SubDirs.Size(); - if (index < numDirItems) - AddRealIndices(dir.SubDirs[index], realIndices); - else - realIndices.Add(dir.SubFiles[index - numDirItems]); - } - HeapSort(&realIndices.Front(), realIndices.Size()); -} - -/////////////////////////////////////////////// -// CProxyArc - -static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size) -{ - size = 0; - NCOM::CPropVariant prop; - if (archive->GetProperty(index, propID, &prop) != S_OK) - throw 20120228; - return ConvertPropVariantToUInt64(prop, size); -} - -void CProxyArc::CalculateSizes(unsigned dirIndex, IInArchive *archive) -{ - CProxyDir &dir = Dirs[dirIndex]; - dir.Size = dir.PackSize = 0; - dir.NumSubDirs = dir.SubDirs.Size(); - dir.NumSubFiles = dir.SubFiles.Size(); - dir.CrcIsDefined = true; - dir.Crc = 0; - - unsigned i; - - for (i = 0; i < dir.SubFiles.Size(); i++) - { - UInt32 index = (UInt32)dir.SubFiles[i]; - UInt64 size, packSize; - bool sizeDefined = GetSize(archive, index, kpidSize, size); - dir.Size += size; - GetSize(archive, index, kpidPackSize, packSize); - dir.PackSize += packSize; - { - NCOM::CPropVariant prop; - if (archive->GetProperty(index, kpidCRC, &prop) == S_OK) - { - if (prop.vt == VT_UI4) - dir.Crc += prop.ulVal; - else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined) - dir.CrcIsDefined = false; - } - else - dir.CrcIsDefined = false; - } - } - - for (i = 0; i < dir.SubDirs.Size(); i++) - { - unsigned subDirIndex = dir.SubDirs[i]; - CalculateSizes(subDirIndex, archive); - CProxyDir &f = Dirs[subDirIndex]; - dir.Size += f.Size; - dir.PackSize += f.PackSize; - dir.NumSubFiles += f.NumSubFiles; - dir.NumSubDirs += f.NumSubDirs; - dir.Crc += f.Crc; - if (!f.CrcIsDefined) - dir.CrcIsDefined = false; - } -} - -HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress) -{ - // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) { - - Files.Free(); - Dirs.Clear(); - - Dirs.AddNew(); - IInArchive *archive = arc.Archive; - - UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - - if (progress) - RINOK(progress->SetTotal(numItems)); - - Files.Alloc(numItems); - - UString path; - UString name; - NCOM::CPropVariant prop; - - for (UInt32 i = 0; i < numItems; i++) - { - if (progress && (i & 0xFFFF) == 0) - { - UInt64 currentItemIndex = i; - RINOK(progress->SetCompleted(¤tItemIndex)); - } - - const wchar_t *s = NULL; - unsigned len = 0; - bool isPtrName = false; - - #if defined(MY_CPU_LE) && defined(_WIN32) - // it works only if (sizeof(wchar_t) == 2) - if (arc.GetRawProps) - { - const void *p; - UInt32 size; - UInt32 propType; - if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK - && propType == NPropDataType::kUtf16z - && size > 2) - { - // is (size <= 2), it's empty name, and we call default arc.GetItemPath(); - len = size / 2 - 1; - s = (const wchar_t *)p; - isPtrName = true; - } - } - if (!s) - #endif - { - prop.Clear(); - RINOK(arc.Archive->GetProperty(i, kpidPath, &prop)); - if (prop.vt == VT_BSTR) - { - s = prop.bstrVal; - len = ::SysStringLen(prop.bstrVal); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - if (len == 0) - { - RINOK(arc.GetDefaultItemPath(i, path)); - len = path.Len(); - s = path; - } - - /* - RINOK(arc.GetItemPath(i, path)); - len = path.Len(); - s = path; - */ - } - - unsigned curItem = 0; - - /* - if (arc.Ask_Deleted) - { - bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)); - if (isDeleted) - curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]"); - } - */ - - unsigned namePos = 0; - - unsigned numLevels = 0; - - for (unsigned j = 0; j < len; j++) - { - wchar_t c = s[j]; - if (c == WCHAR_PATH_SEPARATOR || c == L'/') - { - const unsigned kLevelLimit = 1 << 10; - if (numLevels <= kLevelLimit) - { - if (numLevels == kLevelLimit) - name.SetFromAscii("[LONG_PATH]"); - else - name.SetFrom(s + namePos, j - namePos); - curItem = AddDir(curItem, -1, name); - } - namePos = j + 1; - numLevels++; - } - } - - /* - that code must be implemeted to hide alt streams in list. - if (arc.Ask_AltStreams) - { - bool isAltStream; - RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); - if (isAltStream) - { - - } - } - */ - - bool isDir; - RINOK(Archive_IsItem_Dir(archive, i, isDir)); - - CProxyFile &f = Files[i]; - - f.NameLen = len - namePos; - s += namePos; - - if (isPtrName) - f.Name = s; - else - { - f.Name = new wchar_t[f.NameLen + 1]; - f.NeedDeleteName = true; - MyStringCopy((wchar_t *)f.Name, s); - } - - if (isDir) - { - name = s; - AddDir(curItem, (int)i, name); - } - else - Dirs[curItem].SubFiles.Add(i); - } - - CalculateSizes(0, archive); - - // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s); - - return S_OK; -} - - - -// ---------- for Tree-mode archive ---------- - -void CProxyArc2::GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const -{ - pathParts.Clear(); - - isAltStreamDir = false; - - if (dirIndex == k_Proxy2_RootDirIndex) - return; - if (dirIndex == k_Proxy2_AltRootDirIndex) - { - isAltStreamDir = true; - return; - } - - while (dirIndex >= k_Proxy2_NumRootDirs) - { - const CProxyDir2 &dir = Dirs[dirIndex]; - const CProxyFile2 &file = Files[dir.ArcIndex]; - if (pathParts.IsEmpty() && dirIndex == file.AltDirIndex) - isAltStreamDir = true; - pathParts.Insert(0, file.Name); - int par = file.Parent; - if (par < 0) - break; - dirIndex = Files[par].DirIndex; - } -} - -bool CProxyArc2::IsAltDir(unsigned dirIndex) const -{ - if (dirIndex == k_Proxy2_RootDirIndex) - return false; - if (dirIndex == k_Proxy2_AltRootDirIndex) - return true; - const CProxyDir2 &dir = Dirs[dirIndex]; - const CProxyFile2 &file = Files[dir.ArcIndex]; - return ((int)dirIndex == file.AltDirIndex); -} - -UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const -{ - isAltStreamDir = false; - const CProxyDir2 &dir = Dirs[dirIndex]; - if (dirIndex == k_Proxy2_AltRootDirIndex) - isAltStreamDir = true; - else if (dirIndex >= k_Proxy2_NumRootDirs) - { - const CProxyFile2 &file = Files[dir.ArcIndex]; - isAltStreamDir = ((int)dirIndex == file.AltDirIndex); - } - return dir.PathPrefix; -} - -void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const -{ - realIndices.Add(arcIndex); - const CProxyFile2 &file = Files[arcIndex]; - if (file.DirIndex >= 0) - AddRealIndices_of_Dir(file.DirIndex, includeAltStreams, realIndices); - if (includeAltStreams && file.AltDirIndex >= 0) - AddRealIndices_of_Dir(file.AltDirIndex, includeAltStreams, realIndices); -} - -void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const -{ - const CRecordVector &subFiles = Dirs[dirIndex].Items; - FOR_VECTOR (i, subFiles) - { - AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices); - } -} - -unsigned CProxyArc2::GetRealIndex(unsigned dirIndex, unsigned index) const -{ - return Dirs[dirIndex].Items[index]; -} - -void CProxyArc2::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const -{ - const CProxyDir2 &dir = Dirs[dirIndex]; - realIndices.Clear(); - for (UInt32 i = 0; i < numItems; i++) - { - AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices); - } - HeapSort(&realIndices.Front(), realIndices.Size()); -} - -void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive) -{ - CProxyDir2 &dir = Dirs[dirIndex]; - dir.Size = dir.PackSize = 0; - dir.NumSubDirs = 0; // dir.SubDirs.Size(); - dir.NumSubFiles = 0; // dir.Files.Size(); - dir.CrcIsDefined = true; - dir.Crc = 0; - - FOR_VECTOR (i, dir.Items) - { - UInt32 index = dir.Items[i]; - UInt64 size, packSize; - bool sizeDefined = GetSize(archive, index, kpidSize, size); - dir.Size += size; - GetSize(archive, index, kpidPackSize, packSize); - dir.PackSize += packSize; - { - NCOM::CPropVariant prop; - if (archive->GetProperty(index, kpidCRC, &prop) == S_OK) - { - if (prop.vt == VT_UI4) - dir.Crc += prop.ulVal; - else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined) - dir.CrcIsDefined = false; - } - else - dir.CrcIsDefined = false; - } - - const CProxyFile2 &subFile = Files[index]; - if (subFile.DirIndex < 0) - { - dir.NumSubFiles++; - } - else - { - dir.NumSubDirs++; - CProxyDir2 &f = Dirs[subFile.DirIndex]; - f.PathPrefix = dir.PathPrefix + subFile.Name + WCHAR_PATH_SEPARATOR; - CalculateSizes(subFile.DirIndex, archive); - dir.Size += f.Size; - dir.PackSize += f.PackSize; - dir.NumSubFiles += f.NumSubFiles; - dir.NumSubDirs += f.NumSubDirs; - dir.Crc += f.Crc; - if (!f.CrcIsDefined) - dir.CrcIsDefined = false; - } - - if (subFile.AltDirIndex < 0) - { - // dir.NumSubFiles++; - } - else - { - // dir.NumSubDirs++; - CProxyDir2 &f = Dirs[subFile.AltDirIndex]; - f.PathPrefix = dir.PathPrefix + subFile.Name + L':'; - CalculateSizes(subFile.AltDirIndex, archive); - } - } -} - - -bool CProxyArc2::IsThere_SubDir(unsigned dirIndex, const UString &name) const -{ - const CRecordVector &subFiles = Dirs[dirIndex].Items; - FOR_VECTOR (i, subFiles) - { - const CProxyFile2 &file = Files[subFiles[i]]; - if (file.IsDir()) - if (CompareFileNames(name, file.Name) == 0) - return true; - } - return false; -} - -HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) -{ - if (!arc.GetRawProps) - return E_FAIL; - - // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) { - - Dirs.Clear(); - Files.Free(); - - IInArchive *archive = arc.Archive; - - UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - if (progress) - RINOK(progress->SetTotal(numItems)); - UString fileName; - - - { - // Dirs[0] - root dir - /* CProxyDir2 &dir = */ Dirs.AddNew(); - } - - { - // Dirs[1] - for alt streams of root dir - CProxyDir2 &dir = Dirs.AddNew(); - dir.PathPrefix = L':'; - } - - Files.Alloc(numItems); - - UString tempUString; - AString tempAString; - - UInt32 i; - for (i = 0; i < numItems; i++) - { - if (progress && (i & 0xFFFFF) == 0) - { - UInt64 currentItemIndex = i; - RINOK(progress->SetCompleted(¤tItemIndex)); - } - - CProxyFile2 &file = Files[i]; - - const void *p; - UInt32 size; - UInt32 propType; - RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType)); - - #ifdef MY_CPU_LE - if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) - { - file.Name = (const wchar_t *)p; - file.NameLen = 0; - if (size >= sizeof(wchar_t)) - file.NameLen = size / sizeof(wchar_t) - 1; - } - else - #endif - if (p && propType == NPropDataType::kUtf8z) - { - tempAString = (const char *)p; - ConvertUTF8ToUnicode(tempAString, tempUString); - file.NameLen = tempUString.Len(); - file.Name = new wchar_t[file.NameLen + 1]; - file.NeedDeleteName = true; - wmemcpy((wchar_t *)file.Name, tempUString.Ptr(), file.NameLen + 1); - } - else - { - NCOM::CPropVariant prop; - RINOK(arc.Archive->GetProperty(i, kpidName, &prop)); - const wchar_t *s; - if (prop.vt == VT_BSTR) - s = prop.bstrVal; - else if (prop.vt == VT_EMPTY) - s = L"[Content]"; - else - return E_FAIL; - file.NameLen = MyStringLen(s); - file.Name = new wchar_t[file.NameLen + 1]; - file.NeedDeleteName = true; - wmemcpy((wchar_t *)file.Name, s, file.NameLen + 1); - } - - UInt32 parent = (UInt32)(Int32)-1; - UInt32 parentType = 0; - RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType)); - file.Parent = (Int32)parent; - - if (arc.Ask_Deleted) - { - bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)); - if (isDeleted) - { - // continue; - // curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]"); - } - } - - bool isDir; - RINOK(Archive_IsItem_Dir(archive, i, isDir)); - - if (isDir) - { - file.DirIndex = Dirs.Size(); - CProxyDir2 &dir = Dirs.AddNew(); - dir.ArcIndex = i; - } - if (arc.Ask_AltStream) - RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream)); - } - - for (i = 0; i < numItems; i++) - { - CProxyFile2 &file = Files[i]; - int dirIndex; - - if (file.IsAltStream) - { - if (file.Parent < 0) - dirIndex = k_Proxy2_AltRootDirIndex; - else - { - int &folderIndex2 = Files[file.Parent].AltDirIndex; - if (folderIndex2 < 0) - { - folderIndex2 = Dirs.Size(); - CProxyDir2 &dir = Dirs.AddNew(); - dir.ArcIndex = file.Parent; - } - dirIndex = folderIndex2; - } - } - else - { - if (file.Parent < 0) - dirIndex = k_Proxy2_RootDirIndex; - else - { - dirIndex = Files[file.Parent].DirIndex; - if (dirIndex < 0) - return E_FAIL; - } - } - - Dirs[dirIndex].Items.Add(i); - } - - for (i = 0; i < k_Proxy2_NumRootDirs; i++) - CalculateSizes(i, archive); - - // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s); - - return S_OK; -} - -int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const -{ - const CProxyDir2 &dir = Dirs[dirIndex]; - FOR_VECTOR (i, dir.Items) - { - const CProxyFile2 &file = Files[dir.Items[i]]; - if (foldersOnly && file.DirIndex < 0) - continue; - if (CompareFileNames(file.Name, name) == 0) - return i; - } - return -1; -} +// AgentProxy.cpp + +#include "StdAfx.h" + +// #include +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "../../../../C/Sort.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/UTFConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../Archive/Common/ItemNameUtils.h" + +#include "AgentProxy.h" + +using namespace NWindows; + +int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const +{ + const CRecordVector &subDirs = Dirs[dirIndex].SubDirs; + unsigned left = 0, right = subDirs.Size(); + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + 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 (int)dirIndex2; + if (comp < 0) + right = mid; + else + left = mid + 1; + } +} + +int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const +{ + unsigned insertPos; + return FindSubDir(dirIndex, name, insertPos); +} + +static const wchar_t *AllocStringAndCopy(const wchar_t *s, size_t len) +{ + wchar_t *p = new wchar_t[len + 1]; + MyStringCopy(p, s); + return p; +} + +static const wchar_t *AllocStringAndCopy(const UString &s) +{ + return AllocStringAndCopy(s, s.Len()); +} + +unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name) +{ + unsigned insertPos; + int subDirIndex = FindSubDir(dirIndex, name, insertPos); + if (subDirIndex != -1) + { + if (arcIndex != -1) + { + CProxyDir &item = Dirs[(unsigned)subDirIndex]; + if (item.ArcIndex == -1) + item.ArcIndex = arcIndex; + } + return (unsigned)subDirIndex; + } + subDirIndex = (int)Dirs.Size(); + Dirs[dirIndex].SubDirs.Insert(insertPos, (unsigned)subDirIndex); + CProxyDir &item = Dirs.AddNew(); + + item.NameLen = name.Len(); + item.Name = AllocStringAndCopy(name); + + item.ArcIndex = arcIndex; + item.ParentDir = (int)dirIndex; + return (unsigned)subDirIndex; +} + +void CProxyDir::Clear() +{ + SubDirs.Clear(); + SubFiles.Clear(); +} + +void CProxyArc::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const +{ + pathParts.Clear(); + // while (dirIndex != -1) + for (;;) + { + const CProxyDir &dir = Dirs[dirIndex]; + dirIndex = (unsigned)dir.ParentDir; + if (dir.ParentDir == -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(unsigned dirIndex) const +{ + UString s; + // while (dirIndex != -1) + for (;;) + { + const CProxyDir &dir = Dirs[dirIndex]; + dirIndex = (unsigned)dir.ParentDir; + if (dir.ParentDir == -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; +} + +void CProxyArc::AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const +{ + const CProxyDir &dir = Dirs[dirIndex]; + if (dir.IsLeaf()) + realIndices.Add((unsigned)dir.ArcIndex); + unsigned i; + for (i = 0; i < dir.SubDirs.Size(); i++) + AddRealIndices(dir.SubDirs[i], realIndices); + for (i = 0; i < dir.SubFiles.Size(); i++) + realIndices.Add(dir.SubFiles[i]); +} + +int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const +{ + const CProxyDir &dir = Dirs[dirIndex]; + const unsigned numDirItems = dir.SubDirs.Size(); + if (index < numDirItems) + { + const CProxyDir &f = Dirs[dir.SubDirs[index]]; + if (f.IsLeaf()) + return f.ArcIndex; + return -1; + } + return (int)dir.SubFiles[index - numDirItems]; +} + +void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const +{ + const CProxyDir &dir = Dirs[dirIndex]; + realIndices.Clear(); + for (UInt32 i = 0; i < numItems; i++) + { + const UInt32 index = indices[i]; + const unsigned numDirItems = dir.SubDirs.Size(); + if (index < numDirItems) + AddRealIndices(dir.SubDirs[index], realIndices); + else + realIndices.Add(dir.SubFiles[index - numDirItems]); + } + HeapSort(realIndices.NonConstData(), realIndices.Size()); +} + +/////////////////////////////////////////////// +// CProxyArc + +static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size) +{ + size = 0; + NCOM::CPropVariant prop; + if (archive->GetProperty(index, propID, &prop) != S_OK) + throw 20120228; + return ConvertPropVariantToUInt64(prop, size); +} + +void CProxyArc::CalculateSizes(unsigned dirIndex, IInArchive *archive) +{ + CProxyDir &dir = Dirs[dirIndex]; + dir.Size = dir.PackSize = 0; + dir.NumSubDirs = dir.SubDirs.Size(); + dir.NumSubFiles = dir.SubFiles.Size(); + dir.CrcIsDefined = true; + dir.Crc = 0; + + unsigned i; + + for (i = 0; i < dir.SubFiles.Size(); i++) + { + const UInt32 index = (UInt32)dir.SubFiles[i]; + UInt64 size, packSize; + const bool sizeDefined = GetSize(archive, index, kpidSize, size); + dir.Size += size; + GetSize(archive, index, kpidPackSize, packSize); + dir.PackSize += packSize; + { + NCOM::CPropVariant prop; + if (archive->GetProperty(index, kpidCRC, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + dir.Crc += prop.ulVal; + else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined) + dir.CrcIsDefined = false; + } + else + dir.CrcIsDefined = false; + } + } + + for (i = 0; i < dir.SubDirs.Size(); i++) + { + unsigned subDirIndex = dir.SubDirs[i]; + CalculateSizes(subDirIndex, archive); + CProxyDir &f = Dirs[subDirIndex]; + dir.Size += f.Size; + dir.PackSize += f.PackSize; + dir.NumSubFiles += f.NumSubFiles; + dir.NumSubDirs += f.NumSubDirs; + dir.Crc += f.Crc; + if (!f.CrcIsDefined) + dir.CrcIsDefined = false; + } +} + +HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress) +{ + // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) { + + Files.Free(); + Dirs.Clear(); + + Dirs.AddNew(); + IInArchive *archive = arc.Archive; + + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)) + + if (progress) + RINOK(progress->SetTotal(numItems)) + + Files.Alloc(numItems); + + UString path; + UString name; + NCOM::CPropVariant prop; + + for (UInt32 i = 0; i < numItems; i++) + { + if (progress && (i & 0xFFFF) == 0) + { + const UInt64 currentItemIndex = i; + RINOK(progress->SetCompleted(¤tItemIndex)) + } + + const wchar_t *s = NULL; + unsigned len = 0; + bool isPtrName = false; + + #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) + if (arc.GetRawProps) + { + const void *p; + UInt32 size; + UInt32 propType; + if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK + && propType == NPropDataType::kUtf16z + && size > 2) + { + // is (size <= 2), it's empty name, and we call default arc.GetItemPath(); + len = size / 2 - 1; + s = (const wchar_t *)p; + isPtrName = true; + #if WCHAR_PATH_SEPARATOR != L'/' + separatorChar = L'/'; // 0 + #endif + } + } + if (!s) + #endif + { + prop.Clear(); + RINOK(arc.Archive->GetProperty(i, kpidPath, &prop)) + if (prop.vt == VT_BSTR) + { + s = prop.bstrVal; + len = ::SysStringLen(prop.bstrVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + if (len == 0) + { + RINOK(arc.GetItem_DefaultPath(i, path)) + len = path.Len(); + s = path; + } + + /* + RINOK(arc.GetItemPath(i, path)); + len = path.Len(); + s = path; + */ + } + + unsigned curItem = 0; + + /* + if (arc.Ask_Deleted) + { + bool isDeleted = false; + RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)); + if (isDeleted) + curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]"); + } + */ + + unsigned namePos = 0; + + unsigned numLevels = 0; + + for (unsigned j = 0; j < len; j++) + { + const wchar_t c = s[j]; + if (c == L'/' + #if WCHAR_PATH_SEPARATOR != L'/' + || (c == separatorChar) + #endif + ) + { + const unsigned kLevelLimit = 1 << 10; + if (numLevels <= kLevelLimit) + { + if (numLevels == kLevelLimit) + 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; + numLevels++; + } + } + + /* + that code must be implemeted to hide alt streams in list. + if (arc.Ask_AltStreams) + { + bool isAltStream; + RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); + if (isAltStream) + { + + } + } + */ + + bool isDir; + RINOK(Archive_IsItem_Dir(archive, i, isDir)) + + CProxyFile &f = Files[i]; + + f.NameLen = len - namePos; + s += namePos; + + if (isPtrName) + f.Name = s; + else + { + f.Name = AllocStringAndCopy(s, f.NameLen); + f.NeedDeleteName = true; + } + + 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 + Dirs[curItem].SubFiles.Add(i); + } + + CalculateSizes(0, archive); + + // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s); + + return S_OK; +} + + + +// ---------- for Tree-mode archive ---------- + +void CProxyArc2::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const +{ + pathParts.Clear(); + + isAltStreamDir = false; + + if (dirIndex == k_Proxy2_RootDirIndex) + return; + if (dirIndex == k_Proxy2_AltRootDirIndex) + { + isAltStreamDir = true; + return; + } + + while (dirIndex >= k_Proxy2_NumRootDirs) + { + const CProxyDir2 &dir = Dirs[dirIndex]; + const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex]; + if (pathParts.IsEmpty() && (int)dirIndex == file.AltDirIndex) + isAltStreamDir = true; + pathParts.Insert(0, file.Name); + const int par = file.Parent; + if (par == -1) + break; + dirIndex = (unsigned)Files[(unsigned)par].DirIndex; + // if ((int)dirIndex == -1) break; + } +} + +bool CProxyArc2::IsAltDir(unsigned dirIndex) const +{ + if (dirIndex == k_Proxy2_RootDirIndex) + return false; + if (dirIndex == k_Proxy2_AltRootDirIndex) + return true; + const CProxyDir2 &dir = Dirs[dirIndex]; + const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex]; + return ((int)dirIndex == file.AltDirIndex); +} + +UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const +{ + isAltStreamDir = false; + const CProxyDir2 &dir = Dirs[dirIndex]; + if (dirIndex == k_Proxy2_AltRootDirIndex) + isAltStreamDir = true; + else if (dirIndex >= k_Proxy2_NumRootDirs) + { + const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex]; + isAltStreamDir = ((int)dirIndex == file.AltDirIndex); + } + return dir.PathPrefix; +} + +void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const +{ + realIndices.Add(arcIndex); + const CProxyFile2 &file = Files[arcIndex]; + if (file.DirIndex != -1) + AddRealIndices_of_Dir((unsigned)file.DirIndex, includeAltStreams, realIndices); + if (includeAltStreams && file.AltDirIndex != -1) + AddRealIndices_of_Dir((unsigned)file.AltDirIndex, includeAltStreams, realIndices); +} + +void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const +{ + const CRecordVector &subFiles = Dirs[dirIndex].Items; + FOR_VECTOR (i, subFiles) + { + AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices); + } +} + +unsigned CProxyArc2::GetRealIndex(unsigned dirIndex, unsigned index) const +{ + return Dirs[dirIndex].Items[index]; +} + +void CProxyArc2::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const +{ + const CProxyDir2 &dir = Dirs[dirIndex]; + realIndices.Clear(); + for (UInt32 i = 0; i < numItems; i++) + { + AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices); + } + HeapSort(realIndices.NonConstData(), realIndices.Size()); +} + +void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive) +{ + CProxyDir2 &dir = Dirs[dirIndex]; + dir.Size = dir.PackSize = 0; + dir.NumSubDirs = 0; // dir.SubDirs.Size(); + dir.NumSubFiles = 0; // dir.Files.Size(); + dir.CrcIsDefined = true; + dir.Crc = 0; + + FOR_VECTOR (i, dir.Items) + { + UInt32 index = dir.Items[i]; + UInt64 size, packSize; + const bool sizeDefined = GetSize(archive, index, kpidSize, size); + dir.Size += size; + GetSize(archive, index, kpidPackSize, packSize); + dir.PackSize += packSize; + { + NCOM::CPropVariant prop; + if (archive->GetProperty(index, kpidCRC, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + dir.Crc += prop.ulVal; + else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined) + dir.CrcIsDefined = false; + } + else + dir.CrcIsDefined = false; + } + + const CProxyFile2 &subFile = Files[index]; + 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 + s + WCHAR_PATH_SEPARATOR; + CalculateSizes((unsigned)subFile.DirIndex, archive); + dir.Size += f.Size; + dir.PackSize += f.PackSize; + dir.NumSubFiles += f.NumSubFiles; + dir.NumSubDirs += f.NumSubDirs; + dir.Crc += f.Crc; + if (!f.CrcIsDefined) + dir.CrcIsDefined = false; + } + + if (subFile.AltDirIndex == -1) + { + // dir.NumSubFiles++; + } + else + { + // dir.NumSubDirs++; + CProxyDir2 &f = Dirs[subFile.AltDirIndex]; + f.PathPrefix = dir.PathPrefix + subFile.Name + L':'; + CalculateSizes((unsigned)subFile.AltDirIndex, archive); + } + } +} + + +bool CProxyArc2::IsThere_SubDir(unsigned dirIndex, const UString &name) const +{ + const CRecordVector &subFiles = Dirs[dirIndex].Items; + FOR_VECTOR (i, subFiles) + { + const CProxyFile2 &file = Files[subFiles[i]]; + if (file.IsDir()) + if (CompareFileNames(name, file.Name) == 0) + return true; + } + return false; +} + +HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) +{ + if (!arc.GetRawProps) + return E_FAIL; + + // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) { + + Dirs.Clear(); + Files.Free(); + + IInArchive *archive = arc.Archive; + + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)) + if (progress) + RINOK(progress->SetTotal(numItems)) + UString fileName; + + + { + // Dirs[0] - root dir + /* CProxyDir2 &dir = */ Dirs.AddNew(); + } + + { + // Dirs[1] - for alt streams of root dir + CProxyDir2 &dir = Dirs.AddNew(); + dir.PathPrefix = ':'; + } + + Files.Alloc(numItems); + + UString tempUString; + AString tempAString; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + if (progress && (i & 0xFFFFF) == 0) + { + UInt64 currentItemIndex = i; + RINOK(progress->SetCompleted(¤tItemIndex)) + } + + CProxyFile2 &file = Files[i]; + + const void *p; + UInt32 size; + UInt32 propType; + RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType)) + + #ifdef MY_CPU_LE + if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) + { + file.Name = (const wchar_t *)p; + file.NameLen = 0; + if (size >= sizeof(wchar_t)) + file.NameLen = size / sizeof(wchar_t) - 1; + } + else + #endif + if (p && propType == NPropDataType::kUtf8z) + { + tempAString = (const char *)p; + ConvertUTF8ToUnicode(tempAString, tempUString); + file.NameLen = tempUString.Len(); + file.Name = AllocStringAndCopy(tempUString); + file.NeedDeleteName = true; + } + else + { + NCOM::CPropVariant prop; + RINOK(arc.Archive->GetProperty(i, kpidName, &prop)) + const wchar_t *s; + if (prop.vt == VT_BSTR) + s = prop.bstrVal; + else if (prop.vt == VT_EMPTY) + s = L"[Content]"; + else + return E_FAIL; + file.NameLen = MyStringLen(s); + file.Name = AllocStringAndCopy(s, file.NameLen); + file.NeedDeleteName = true; + } + + UInt32 parent = (UInt32)(Int32)-1; + UInt32 parentType = 0; + RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType)) + file.Parent = (Int32)parent; + + if (arc.Ask_Deleted) + { + bool isDeleted = false; + RINOK(Archive_IsItem_Deleted(archive, i, isDeleted)) + if (isDeleted) + { + // continue; + // curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]"); + } + } + + bool isDir; + RINOK(Archive_IsItem_Dir(archive, i, isDir)) + + if (isDir) + { + file.DirIndex = (int)Dirs.Size(); + CProxyDir2 &dir = Dirs.AddNew(); + dir.ArcIndex = (int)i; + } + if (arc.Ask_AltStream) + RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream)) + } + + for (i = 0; i < numItems; i++) + { + CProxyFile2 &file = Files[i]; + int dirIndex; + + if (file.IsAltStream) + { + if (file.Parent == -1) + dirIndex = k_Proxy2_AltRootDirIndex; + else + { + int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex; + if (folderIndex2 == -1) + { + folderIndex2 = (int)Dirs.Size(); + CProxyDir2 &dir = Dirs.AddNew(); + dir.ArcIndex = file.Parent; + } + dirIndex = folderIndex2; + } + } + else + { + if (file.Parent == -1) + dirIndex = k_Proxy2_RootDirIndex; + else + { + dirIndex = Files[(unsigned)file.Parent].DirIndex; + if (dirIndex == -1) + return E_FAIL; + } + } + + Dirs[dirIndex].Items.Add(i); + } + + for (i = 0; i < k_Proxy2_NumRootDirs; i++) + CalculateSizes(i, archive); + + // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s); + + return S_OK; +} + +int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const +{ + const CProxyDir2 &dir = Dirs[dirIndex]; + FOR_VECTOR (i, dir.Items) + { + const CProxyFile2 &file = Files[dir.Items[i]]; + if (foldersOnly && file.DirIndex == -1) + continue; + if (CompareFileNames(file.Name, name) == 0) + return (int)i; + } + return -1; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentProxy.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.h --- p7zip-rar-16.02/CPP/7zip/UI/Agent/AgentProxy.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/AgentProxy.h 2023-01-19 15:00:00.000000000 +0000 @@ -1,162 +1,162 @@ -// AgentProxy.h - -#ifndef __AGENT_PROXY_H -#define __AGENT_PROXY_H - -#include "../Common/OpenArchive.h" - -struct CProxyFile -{ - const wchar_t *Name; - unsigned NameLen; - bool NeedDeleteName; - - CProxyFile(): Name(NULL), NameLen(0), NeedDeleteName(false) {} - ~CProxyFile() { if (NeedDeleteName) delete [](wchar_t *)Name; } -}; - -const unsigned k_Proxy_RootDirIndex = 0; - -struct CProxyDir -{ - const wchar_t *Name; - unsigned NameLen; - - int ArcIndex; // index in proxy->Files[] ; -1 if there is no item for that folder - int ParentDir; // index in proxy->Dirs[] ; -1 for root folder; ; - CRecordVector SubDirs; - CRecordVector SubFiles; - - UInt64 Size; - UInt64 PackSize; - UInt32 Crc; - UInt32 NumSubDirs; - UInt32 NumSubFiles; - bool CrcIsDefined; - - CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {}; - ~CProxyDir() { delete [](wchar_t *)Name; } - - void Clear(); - bool IsLeaf() const { return ArcIndex >= 0; } -}; - -class CProxyArc -{ - int FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const; - - void CalculateSizes(unsigned dirIndex, IInArchive *archive); - unsigned AddDir(unsigned dirIndex, int arcIndex, const UString &name); -public: - CObjectVector Dirs; // Dirs[0] - root - CObjArray Files; // all items from archive in same order - - // returns index in Dirs[], or -1, - int FindSubDir(unsigned dirIndex, const wchar_t *name) const; - - void GetDirPathParts(int dirIndex, UStringVector &pathParts) const; - // returns full path of Dirs[dirIndex], including back slash - UString GetDirPath_as_Prefix(int dirIndex) const; - - // AddRealIndices DOES ADD also item represented by dirIndex (if it's Leaf) - void AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const; - int GetRealIndex(unsigned dirIndex, unsigned index) const; - void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const; - - HRESULT Load(const CArc &arc, IProgress *progress); -}; - - -// ---------- for Tree-mode archive ---------- - -struct CProxyFile2 -{ - int DirIndex; // >= 0 for dir. (index in ProxyArchive2->Dirs) - int AltDirIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Dirs) - int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files) - const wchar_t *Name; - unsigned NameLen; - bool NeedDeleteName; - bool Ignore; - bool IsAltStream; - - int GetDirIndex(bool forAltStreams) const { return forAltStreams ? AltDirIndex : DirIndex; } - - bool IsDir() const { return DirIndex >= 0; } - CProxyFile2(): - DirIndex(-1), AltDirIndex(-1), Parent(-1), - Name(NULL), NameLen(0), - NeedDeleteName(false), - Ignore(false), - IsAltStream(false) - {} - ~CProxyFile2() - { - if (NeedDeleteName) - delete [](wchar_t *)Name; - } -}; - -struct CProxyDir2 -{ - int ArcIndex; // = -1 for root folders, index in proxy->Files[] - CRecordVector Items; - UString PathPrefix; - UInt64 Size; - UInt64 PackSize; - bool CrcIsDefined; - UInt32 Crc; - UInt32 NumSubDirs; - UInt32 NumSubFiles; - - CProxyDir2(): ArcIndex(-1) {}; - void AddFileSubItem(UInt32 index, const UString &name); - void Clear(); -}; - -const unsigned k_Proxy2_RootDirIndex = k_Proxy_RootDirIndex; -const unsigned k_Proxy2_AltRootDirIndex = 1; -const unsigned k_Proxy2_NumRootDirs = 2; - -class CProxyArc2 -{ - void CalculateSizes(unsigned dirIndex, IInArchive *archive); - // AddRealIndices_of_Dir DOES NOT ADD item itself represented by dirIndex - void AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const; -public: - CObjectVector Dirs; // Dirs[0] - root folder - // Dirs[1] - for alt streams of root dir - CObjArray Files; // all items from archive in same order - - bool IsThere_SubDir(unsigned dirIndex, const UString &name) const; - - void GetDirPathParts(int dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const; - UString GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const; - bool IsAltDir(unsigned dirIndex) const; - - // AddRealIndices_of_ArcItem DOES ADD item and subItems - void AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const; - unsigned GetRealIndex(unsigned dirIndex, unsigned index) const; - void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const; - - HRESULT Load(const CArc &arc, IProgress *progress); - - int GetParentDirOfFile(UInt32 arcIndex) const - { - const CProxyFile2 &file = Files[arcIndex]; - - if (file.Parent < 0) - return file.IsAltStream ? - k_Proxy2_AltRootDirIndex : - k_Proxy2_RootDirIndex; - - const CProxyFile2 &parentFile = Files[file.Parent]; - return file.IsAltStream ? - parentFile.AltDirIndex : - parentFile.DirIndex; - } - - int FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const; -}; - -#endif +// AgentProxy.h + +#ifndef ZIP7_INC_AGENT_PROXY_H +#define ZIP7_INC_AGENT_PROXY_H + +#include "../Common/OpenArchive.h" + +struct CProxyFile +{ + const wchar_t *Name; + unsigned NameLen; + bool NeedDeleteName; + + CProxyFile(): Name(NULL), NameLen(0), NeedDeleteName(false) {} + ~CProxyFile() { if (NeedDeleteName) delete [](wchar_t *)(void *)Name; } // delete [](wchar_t *)Name; +}; + +const unsigned k_Proxy_RootDirIndex = 0; + +struct CProxyDir +{ + const wchar_t *Name; + unsigned NameLen; + + int ArcIndex; // index in proxy->Files[] ; -1 if there is no item for that folder + int ParentDir; // index in proxy->Dirs[] ; -1 for root folder; ; + CRecordVector SubDirs; + CRecordVector SubFiles; + + UInt64 Size; + UInt64 PackSize; + UInt32 Crc; + UInt32 NumSubDirs; + UInt32 NumSubFiles; + bool CrcIsDefined; + + CProxyDir(): Name(NULL), NameLen(0), ParentDir(-1) {} + ~CProxyDir() { delete [](wchar_t *)(void *)Name; } + + void Clear(); + bool IsLeaf() const { return ArcIndex != -1; } +}; + +class CProxyArc +{ + int FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const; + + void CalculateSizes(unsigned dirIndex, IInArchive *archive); + unsigned AddDir(unsigned dirIndex, int arcIndex, const UString &name); +public: + CObjectVector Dirs; // Dirs[0] - root + CObjArray Files; // all items from archive in same order + + // returns index in Dirs[], or -1, + int FindSubDir(unsigned dirIndex, const wchar_t *name) const; + + void GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const; + // returns full path of Dirs[dirIndex], including back slash + UString GetDirPath_as_Prefix(unsigned dirIndex) const; + + // AddRealIndices DOES ADD also item represented by dirIndex (if it's Leaf) + void AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const; + int GetRealIndex(unsigned dirIndex, unsigned index) const; + void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const; + + HRESULT Load(const CArc &arc, IProgress *progress); +}; + + +// ---------- for Tree-mode archive ---------- + +struct CProxyFile2 +{ + int DirIndex; // >= 0 for dir. (index in ProxyArchive2->Dirs) + int AltDirIndex; // >= 0 if there are alt streams. (index in ProxyArchive2->Dirs) + int Parent; // >= 0 if there is parent. (index in archive and in ProxyArchive2->Files) + const wchar_t *Name; + unsigned NameLen; + bool NeedDeleteName; + bool Ignore; + bool IsAltStream; + + int GetDirIndex(bool forAltStreams) const { return forAltStreams ? AltDirIndex : DirIndex; } + + bool IsDir() const { return DirIndex != -1; } + CProxyFile2(): + DirIndex(-1), AltDirIndex(-1), Parent(-1), + Name(NULL), NameLen(0), + NeedDeleteName(false), + Ignore(false), + IsAltStream(false) + {} + ~CProxyFile2() + { + if (NeedDeleteName) + delete [](wchar_t *)(void *)Name; + } +}; + +struct CProxyDir2 +{ + int ArcIndex; // = -1 for root folders, index in proxy->Files[] + CRecordVector Items; + UString PathPrefix; + UInt64 Size; + UInt64 PackSize; + bool CrcIsDefined; + UInt32 Crc; + UInt32 NumSubDirs; + UInt32 NumSubFiles; + + CProxyDir2(): ArcIndex(-1) {} + void AddFileSubItem(UInt32 index, const UString &name); + void Clear(); +}; + +const unsigned k_Proxy2_RootDirIndex = k_Proxy_RootDirIndex; +const unsigned k_Proxy2_AltRootDirIndex = 1; +const unsigned k_Proxy2_NumRootDirs = 2; + +class CProxyArc2 +{ + void CalculateSizes(unsigned dirIndex, IInArchive *archive); + // AddRealIndices_of_Dir DOES NOT ADD item itself represented by dirIndex + void AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const; +public: + CObjectVector Dirs; // Dirs[0] - root folder + // Dirs[1] - for alt streams of root dir + CObjArray Files; // all items from archive in same order + + bool IsThere_SubDir(unsigned dirIndex, const UString &name) const; + + void GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const; + UString GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const; + bool IsAltDir(unsigned dirIndex) const; + + // AddRealIndices_of_ArcItem DOES ADD item and subItems + void AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const; + unsigned GetRealIndex(unsigned dirIndex, unsigned index) const; + void GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const; + + HRESULT Load(const CArc &arc, IProgress *progress); + + int GetParentDirOfFile(UInt32 arcIndex) const + { + const CProxyFile2 &file = Files[arcIndex]; + + if (file.Parent == -1) + return file.IsAltStream ? + k_Proxy2_AltRootDirIndex : + k_Proxy2_RootDirIndex; + + const CProxyFile2 &parentFile = Files[file.Parent]; + return file.IsAltStream ? + parentFile.AltDirIndex : + parentFile.DirIndex; + } + + int FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolder.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolder.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolder.cpp 2024-10-04 10:00:00.000000000 +0000 @@ -1,44 +1,57 @@ -// Agent/ArchiveFolder.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" - -#include "../Common/ArchiveExtractCallback.h" - -#include "Agent.h" - -/* -STDMETHODIMP CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCharsMode) -{ - _replaceAltStreamCharsMode = replaceAltStreamCharsMode; - return S_OK; -} -*/ - -STDMETHODIMP CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, - Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, - const wchar_t *path, IFolderOperationsExtractCallback *callback) -{ - if (moveMode) - return E_NOTIMPL; - COM_TRY_BEGIN - CMyComPtr extractCallback2; - { - CMyComPtr callbackWrap = callback; - RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)); - } - NExtract::NPathMode::EEnum pathMode; - if (!_flatMode) - pathMode = NExtract::NPathMode::kCurPaths; - else - pathMode = (_proxy2 && _loadAltStreams) ? - NExtract::NPathMode::kNoPathsAlt : - NExtract::NPathMode::kNoPaths; - - return Extract(indices, numItems, - includeAltStreams, replaceAltStreamCharsMode, - pathMode, NExtract::NOverwriteMode::kAsk, - path, BoolToInt(false), extractCallback2); - COM_TRY_END -} +// Agent/ArchiveFolder.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" + +#include "../Common/ArchiveExtractCallback.h" + +#include "Agent.h" + +/* +Z7_COM7F_IMF(CAgentFolder::SetReplaceAltStreamCharsMode(Int32 replaceAltStreamCharsMode)) +{ + _replaceAltStreamCharsMode = replaceAltStreamCharsMode; + return S_OK; +} +*/ + +Z7_COM7F_IMF(CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)) +{ + _zoneMode = zoneMode; + return S_OK; +} + +Z7_COM7F_IMF(CAgentFolder::SetZoneIdFile(const Byte *data, UInt32 size)) +{ + _zoneBuf.CopyFrom(data, size); + return S_OK; +} + + +Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, + Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, + const wchar_t *path, IFolderOperationsExtractCallback *callback)) +{ + if (moveMode) + return E_NOTIMPL; + COM_TRY_BEGIN + CMyComPtr extractCallback2; + { + CMyComPtr callbackWrap = callback; + RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)) + } + NExtract::NPathMode::EEnum pathMode; + if (!_flatMode) + pathMode = NExtract::NPathMode::kCurPaths; + else + pathMode = (_proxy2 && _loadAltStreams) ? + NExtract::NPathMode::kNoPathsAlt : + NExtract::NPathMode::kNoPaths; + + return Extract(indices, numItems, + includeAltStreams, replaceAltStreamCharsMode, + pathMode, NExtract::NOverwriteMode::kAsk, + path, BoolToInt(false), extractCallback2); + COM_TRY_END +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp 2015-06-20 17:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp 2023-04-01 14:00:00.000000000 +0000 @@ -1,142 +1,231 @@ -// Agent/ArchiveFolderOpen.cpp - -#include "StdAfx.h" - -#include "../../../Windows/DLL.h" - -#include "Agent.h" - -void CArchiveFolderManager::LoadFormats() -{ - LoadGlobalCodecs(); -} - -int CArchiveFolderManager::FindFormat(const UString &type) -{ - FOR_VECTOR (i, g_CodecsObj->Formats) - if (type.IsEqualTo_NoCase(g_CodecsObj->Formats[i].Name)) - return i; - return -1; -} - -STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream, - const wchar_t *filePath, const wchar_t *arcFormat, - IFolderFolder **resultFolder, IProgress *progress) -{ - CMyComPtr openArchiveCallback; - if (progress) - { - CMyComPtr progressWrapper = progress; - progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback); - } - CAgent *agent = new CAgent(); - CMyComPtr archive = agent; - RINOK(agent->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback)); - return agent->BindToRootFolder(resultFolder); -} - -/* -HRESULT CAgent::FolderReOpen( - IArchiveOpenCallback *openArchiveCallback) -{ - return ReOpenArchive(_archive, _archiveFilePath); -} -*/ - - -/* -STDMETHODIMP CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *extensions) -{ - *extensions = 0; - int formatIndex = FindFormat(type); - if (formatIndex < 0) - return E_INVALIDARG; - // Exts[0].Ext; - return StringToBstr(g_CodecsObj.Formats[formatIndex].GetAllExtensions(), extensions); -} -*/ - -static void AddIconExt(const CCodecIcons &lib, UString &dest) -{ - FOR_VECTOR (i, lib.IconPairs) - { - dest.Add_Space_if_NotEmpty(); - dest += lib.IconPairs[i].Ext; - } -} - -STDMETHODIMP CArchiveFolderManager::GetExtensions(BSTR *extensions) -{ - LoadFormats(); - *extensions = 0; - UString res; - - #ifdef EXTERNAL_CODECS - - FOR_VECTOR (i, g_CodecsObj->Libs) - AddIconExt(g_CodecsObj->Libs[i], res); - - #endif - - AddIconExt(g_CodecsObj->InternalIcons, res); - return StringToBstr(res, extensions); -} - -STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) -{ - *iconPath = 0; - *iconIndex = 0; -#ifdef _WIN32 - LoadFormats(); - - #ifdef EXTERNAL_CODECS - - FOR_VECTOR (i, g_CodecsObj->Libs) - { - const CCodecLib &lib = g_CodecsObj->Libs[i]; - int ii; - if (lib.FindIconIndex(ext, ii)) - { - *iconIndex = ii; - return StringToBstr(fs2us(lib.Path), iconPath); - } - } - - #endif - - int ii; - if (g_CodecsObj->InternalIcons.FindIconIndex(ext, ii)) - { - FString path; - if (NWindows::NDLL::MyGetModuleFileName(path)) - { - *iconIndex = ii; - return StringToBstr(fs2us(path), iconPath); - } - } -#endif - return S_OK; -} - -/* -STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types) -{ - LoadFormats(); - UString typesStrings; - FOR_VECTOR(i, g_CodecsObj.Formats) - { - const CArcInfoEx &ai = g_CodecsObj.Formats[i]; - if (ai.AssociateExts.Size() == 0) - continue; - if (i != 0) - typesStrings.Add_Space(); - typesStrings += ai.Name; - } - return StringToBstr(typesStrings, types); -} -STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * type, - const wchar_t * filePath, IProgress progress) -{ - return E_NOTIMPL; -} -*/ +// Agent/ArchiveFolderOpen.cpp + +#include "StdAfx.h" + +// #ifdef NEW_FOLDER_INTERFACE + +#include "../../../Common/StringToInt.h" +#include "../../../Windows/DLL.h" +#include "../../../Windows/ResourceString.h" + +#include "Agent.h" + +extern HINSTANCE g_hInstance; +static const UINT kIconTypesResId = 100; + +void CCodecIcons::LoadIcons(HMODULE m) +{ + IconPairs.Clear(); + UString iconTypes; + NWindows::MyLoadString(m, kIconTypesResId, iconTypes); + UStringVector pairs; + SplitString(iconTypes, pairs); + FOR_VECTOR (i, pairs) + { + const UString &s = pairs[i]; + int pos = s.Find(L':'); + CIconPair iconPair; + iconPair.IconIndex = -1; + if (pos < 0) + pos = (int)s.Len(); + else + { + const UString num = s.Ptr((unsigned)pos + 1); + if (!num.IsEmpty()) + { + const wchar_t *end; + iconPair.IconIndex = (int)ConvertStringToUInt32(num, &end); + if (*end != 0) + continue; + } + } + iconPair.Ext = s.Left((unsigned)pos); + IconPairs.Add(iconPair); + } +} + +bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const +{ + iconIndex = -1; + FOR_VECTOR (i, IconPairs) + { + const CIconPair &pair = IconPairs[i]; + if (ext.IsEqualTo_NoCase(pair.Ext)) + { + iconIndex = pair.IconIndex; + return true; + } + } + return false; +} + + +void CArchiveFolderManager::LoadFormats() +{ + if (WasLoaded) + return; + + LoadGlobalCodecs(); + + #ifdef Z7_EXTERNAL_CODECS + CodecIconsVector.Clear(); + FOR_VECTOR (i, g_CodecsObj->Libs) + { + CCodecIcons &ci = CodecIconsVector.AddNew(); + ci.LoadIcons(g_CodecsObj->Libs[i].Lib.Get_HMODULE()); + } + #endif + InternalIcons.LoadIcons(g_hInstance); + WasLoaded = true; +} + +/* +int CArchiveFolderManager::FindFormat(const UString &type) +{ + FOR_VECTOR (i, g_CodecsObj->Formats) + if (type.IsEqualTo_NoCase(g_CodecsObj->Formats[i].Name)) + return (int)i; + return -1; +} +*/ + +Z7_COM7F_IMF(CArchiveFolderManager::OpenFolderFile(IInStream *inStream, + const wchar_t *filePath, const wchar_t *arcFormat, + IFolderFolder **resultFolder, IProgress *progress)) +{ + CMyComPtr openArchiveCallback; + if (progress) + { + CMyComPtr progressWrapper = progress; + progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback); + } + CAgent *agent = new CAgent(); + CMyComPtr archive = agent; + + const HRESULT res = archive->Open(inStream, filePath, arcFormat, NULL, openArchiveCallback); + + if (res != S_OK) + { + if (res != S_FALSE) + return res; + /* 20.01: we create folder even for Non-Open cases, if there is NonOpen_ErrorInfo information. + So we can get error information from that IFolderFolder later. */ + if (!agent->_archiveLink.NonOpen_ErrorInfo.IsThereErrorOrWarning()) + return res; + } + + RINOK(archive->BindToRootFolder(resultFolder)) + return res; +} + +/* +HRESULT CAgent::FolderReOpen( + IArchiveOpenCallback *openArchiveCallback) +{ + return ReOpenArchive(_archive, _archiveFilePath); +} +*/ + + +/* +Z7_COM7F_IMF(CArchiveFolderManager::GetExtensions(const wchar_t *type, BSTR *extensions)) +{ + *extensions = 0; + int formatIndex = FindFormat(type); + if (formatIndex < 0) + return E_INVALIDARG; + // Exts[0].Ext; + return StringToBstr(g_CodecsObj.Formats[formatIndex].GetAllExtensions(), extensions); +} +*/ + +static void AddIconExt(const CCodecIcons &lib, UString &dest) +{ + FOR_VECTOR (i, lib.IconPairs) + { + dest.Add_Space_if_NotEmpty(); + dest += lib.IconPairs[i].Ext; + } +} + + +Z7_COM7F_IMF(CArchiveFolderManager::GetExtensions(BSTR *extensions)) +{ + *extensions = NULL; + LoadFormats(); + UString res; + + #ifdef Z7_EXTERNAL_CODECS + /* + FOR_VECTOR (i, g_CodecsObj->Libs) + AddIconExt(g_CodecsObj->Libs[i].CodecIcons, res); + */ + FOR_VECTOR (i, CodecIconsVector) + AddIconExt(CodecIconsVector[i], res); + #endif + + AddIconExt( + // g_CodecsObj-> + InternalIcons, res); + + return StringToBstr(res, extensions); +} + + +Z7_COM7F_IMF(CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex)) +{ + *iconPath = NULL; + *iconIndex = 0; + LoadFormats(); + + #ifdef Z7_EXTERNAL_CODECS + // FOR_VECTOR (i, g_CodecsObj->Libs) + FOR_VECTOR (i, CodecIconsVector) + { + int ii; + if (CodecIconsVector[i].FindIconIndex(ext, ii)) + { + const CCodecLib &lib = g_CodecsObj->Libs[i]; + *iconIndex = ii; + return StringToBstr(fs2us(lib.Path), iconPath); + } + } + #endif + + int ii; + if (InternalIcons.FindIconIndex(ext, ii)) + { + FString path; + if (NWindows::NDLL::MyGetModuleFileName(path)) + { + *iconIndex = ii; + return StringToBstr(fs2us(path), iconPath); + } + } + return S_OK; +} + +/* +Z7_COM7F_IMF(CArchiveFolderManager::GetTypes(BSTR *types)) +{ + LoadFormats(); + UString typesStrings; + FOR_VECTOR(i, g_CodecsObj.Formats) + { + const CArcInfoEx &ai = g_CodecsObj.Formats[i]; + if (ai.AssociateExts.Size() == 0) + continue; + if (i != 0) + typesStrings.Add_Space(); + typesStrings += ai.Name; + } + return StringToBstr(typesStrings, types); +} +Z7_COM7F_IMF(CArchiveFolderManager::CreateFolderFile(const wchar_t * type, + const wchar_t * filePath, IProgress progress)) +{ + return E_NOTIMPL; +} +*/ + +// #endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp 2024-10-19 07:00:00.000000000 +0000 @@ -1,366 +1,456 @@ -// ArchiveFolderOut.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" - -#include "../../../Windows/FileDir.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/LimitedStreams.h" - -#include "../../Compress/CopyCoder.h" - -#include "../Common/WorkDir.h" - -#include "Agent.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder) -{ - if (_proxy2) - _proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder); - else - _proxy->GetDirPathParts(_proxyDirIndex, pathParts); -} - -static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path) -{ - NFind::CFileInfo fileInfo; - FString pathPrefix = path + FCHAR_PATH_SEPARATOR; - { - NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK); - while (enumerator.Next(fileInfo)) - { - if (fileInfo.IsDir()) - if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name)) - return false; - } - } - /* - // we don't need clear readonly for folders - if (!SetFileAttrib(path, 0)) - return false; - */ - return RemoveDir(path); -} - - -HRESULT CAgentFolder::CommonUpdateOperation( - AGENT_OP operation, - bool moveMode, - const wchar_t *newItemName, - const NUpdateArchive::CActionSet *actionSet, - const UInt32 *indices, UInt32 numItems, - IProgress *progress) -{ - if (!_agentSpec->CanUpdate()) - return E_NOTIMPL; - - CMyComPtr updateCallback100; - if (progress) - progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100); - - try - { - - RINOK(_agentSpec->SetFolder(this)); - - // ---------- Save FolderItem ---------- - - UStringVector pathParts; - bool isAltStreamFolder = false; - GetPathParts(pathParts, isAltStreamFolder); - - FStringVector requestedPaths; - FStringVector processedPaths; - - CWorkDirTempFile tempFile; - RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath))); - { - CMyComPtr tailStream; - const CArc &arc = *_agentSpec->_archiveLink.GetArc(); - - if (arc.ArcStreamOffset == 0) - tailStream = tempFile.OutStream; - else - { - if (arc.Offset < 0) - return E_NOTIMPL; - RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL)); - CTailOutStream *tailStreamSpec = new CTailOutStream; - tailStream = tailStreamSpec; - tailStreamSpec->Stream = tempFile.OutStream; - tailStreamSpec->Offset = arc.ArcStreamOffset; - tailStreamSpec->Init(); - } - - HRESULT result; - - switch (operation) - { - case AGENT_OP_Delete: - result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100); - break; - case AGENT_OP_CreateFolder: - result = _agentSpec->CreateFolder(tailStream, newItemName, updateCallback100); - break; - case AGENT_OP_Rename: - result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100); - break; - case AGENT_OP_CopyFromFile: - result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100); - break; - case AGENT_OP_Uni: - { - Byte actionSetByte[NUpdateArchive::NPairState::kNumValues]; - for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) - actionSetByte[i] = (Byte)actionSet->StateActions[i]; - result = _agentSpec->DoOperation2( - moveMode ? &requestedPaths : NULL, - moveMode ? &processedPaths : NULL, - tailStream, actionSetByte, NULL, updateCallback100); - break; - } - default: - return E_FAIL; - } - - RINOK(result); - } - - _agentSpec->KeepModeForNextOpen(); - _agentSpec->Close(); - - // before 9.26: if there was error for MoveToOriginal archive was closed. - // now: we reopen archive after close - - // m_FolderItem = NULL; - - HRESULT res = tempFile.MoveToOriginal(true); - - // RINOK(res); - if (res == S_OK) - { - if (moveMode) - { - unsigned i; - for (i = 0; i < processedPaths.Size(); i++) - { - DeleteFileAlways(processedPaths[i]); - } - for (i = 0; i < requestedPaths.Size(); i++) - { - const FString &fs = requestedPaths[i]; - if (NFind::DoesDirExist(fs)) - DeleteEmptyFolderAndEmptySubFolders(fs); - } - } - } - - { - CMyComPtr openCallback; - if (updateCallback100) - updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback); - RINOK(_agentSpec->ReOpen(openCallback)); - } - - // CAgent::ReOpen() deletes _proxy and _proxy2 - _items.Clear(); - _proxy = NULL; - _proxy2 = NULL; - _proxyDirIndex = k_Proxy_RootDirIndex; - _isAltStreamFolder = false; - - - // ---------- Restore FolderItem ---------- - - CMyComPtr archiveFolder; - RINOK(_agentSpec->BindToRootFolder(&archiveFolder)); - - // CAgent::BindToRootFolder() changes _proxy and _proxy2 - _proxy = _agentSpec->_proxy; - _proxy2 = _agentSpec->_proxy2; - - if (_proxy) - { - FOR_VECTOR (i, pathParts) - { - int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]); - if (next < 0) - break; - _proxyDirIndex = next; - } - } - - if (_proxy2) - { - if (pathParts.IsEmpty() && isAltStreamFolder) - { - _proxyDirIndex = k_Proxy2_AltRootDirIndex; - } - else FOR_VECTOR (i, pathParts) - { - bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder); - int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly); - if (index < 0) - break; - - const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]]; - - if (dirOnly) - _proxyDirIndex = file.DirIndex; - else - { - if (file.AltDirIndex >= 0) - _proxyDirIndex = file.AltDirIndex; - break; - } - } - } - - /* - if (pathParts.IsEmpty() && isAltStreamFolder) - { - CMyComPtr folderAltStreams; - archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams); - if (folderAltStreams) - { - CMyComPtr newFolder; - folderAltStreams->BindToAltStreams((UInt32)(Int32)-1, &newFolder); - if (newFolder) - archiveFolder = newFolder; - } - } - - FOR_VECTOR (i, pathParts) - { - CMyComPtr newFolder; - - if (isAltStreamFolder && i == pathParts.Size() - 1) - { - CMyComPtr folderAltStreams; - archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams); - if (folderAltStreams) - folderAltStreams->BindToAltStreams(pathParts[i], &newFolder); - } - else - archiveFolder->BindToFolder(pathParts[i], &newFolder); - - if (!newFolder) - break; - archiveFolder = newFolder; - } - - CMyComPtr archiveFolderInternal; - RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); - CAgentFolder *agentFolder; - RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder)); - _proxyDirIndex = agentFolder->_proxyDirIndex; - // _parentFolder = agentFolder->_parentFolder; - */ - - if (_proxy2) - _isAltStreamFolder = _proxy2->IsAltDir(_proxyDirIndex); - - return res; - - } - catch(const UString &s) - { - if (updateCallback100) - { - UString s2 = L"Error: "; - s2 += s; - RINOK(updateCallback100->UpdateErrorMessage(s2)); - return E_FAIL; - } - throw; - } -} - - - -STDMETHODIMP CAgentFolder::CopyFrom(Int32 moveMode, - const wchar_t *fromFolderPath, // test it - const wchar_t * const *itemsPaths, - UInt32 numItems, - IProgress *progress) -{ - COM_TRY_BEGIN - { - RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems)); - return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL, - &NUpdateArchive::k_ActionSet_Add, - NULL, 0, progress); - } - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress) -{ - COM_TRY_BEGIN - CUIntVector indices; - indices.Add(destIndex); - { - return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath, - &NUpdateArchive::k_ActionSet_Add, - &indices.Front(), indices.Size(), progress); - } - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress) -{ - COM_TRY_BEGIN - return CommonUpdateOperation(AGENT_OP_Delete, false, NULL, - &NUpdateArchive::k_ActionSet_Delete, indices, numItems, progress); - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress) -{ - COM_TRY_BEGIN - - if (_isAltStreamFolder) - return E_NOTIMPL; - - if (_proxy2) - { - if (_proxy2->IsThere_SubDir(_proxyDirIndex, name)) - return ERROR_ALREADY_EXISTS; - } - else - { - if (_proxy->FindSubDir(_proxyDirIndex, name) >= 0) - return ERROR_ALREADY_EXISTS; - } - - return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, progress); - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress) -{ - COM_TRY_BEGIN - CUIntVector indices; - indices.Add(index); - return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL, - &indices.Front(), indices.Size(), progress); - COM_TRY_END -} - -STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CAgentFolder::SetProperty(UInt32 /* index */, PROPID /* propID */, - const PROPVARIANT * /* value */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} +// ArchiveFolderOut.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/FileDir.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/LimitedStreams.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/WorkDir.h" + +#include "Agent.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +void CAgentFolder::GetPathParts(UStringVector &pathParts, bool &isAltStreamFolder) +{ + if (_proxy2) + _proxy2->GetDirPathParts(_proxyDirIndex, pathParts, isAltStreamFolder); + else + _proxy->GetDirPathParts(_proxyDirIndex, pathParts); +} + +static bool Delete_EmptyFolder_And_EmptySubFolders(const FString &path) +{ + { + const FString pathPrefix = path + FCHAR_PATH_SEPARATOR; + CObjectVector names; + { + NFind::CDirEntry fileInfo; + NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(pathPrefix); + for (;;) + { + bool found; + if (!enumerator.Next(fileInfo, found)) + return false; + if (!found) + break; + if (fileInfo.IsDir()) + names.Add(fileInfo.Name); + } + } + bool res = true; + FOR_VECTOR (i, names) + { + if (!Delete_EmptyFolder_And_EmptySubFolders(pathPrefix + names[i])) + res = false; + } + if (!res) + return false; + } + // we clear read-only attrib to remove read-only dir + if (!SetFileAttrib(path, 0)) + return false; + return RemoveDir(path); +} + + + +struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final: + public ICopyFileProgress +{ + IFolderArchiveUpdateCallback_MoveArc *Callback; + HRESULT CallbackResult; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // we can ignore E_ABORT here, because we update archive, + // and we want to get correct archive after updating + if (res == E_ABORT) + res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_FolderCallback_MoveArc( + IFolderArchiveUpdateCallback_MoveArc *callback) : + Callback(callback), + CallbackResult(S_OK) + {} +}; + + +HRESULT CAgentFolder::CommonUpdateOperation( + AGENT_OP operation, + bool moveMode, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UInt32 *indices, UInt32 numItems, + IProgress *progress) +{ + if (moveMode && _agentSpec->_isHashHandler) + return E_NOTIMPL; + + if (!_agentSpec->CanUpdate()) + return E_NOTIMPL; + + CMyComPtr updateCallback100; + if (progress) + progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100); + + try + { + + RINOK(_agentSpec->SetFolder(this)) + + // ---------- Save FolderItem ---------- + + UStringVector pathParts; + bool isAltStreamFolder = false; + GetPathParts(pathParts, isAltStreamFolder); + + FStringVector requestedPaths; + FStringVector processedPaths; + + CWorkDirTempFile tempFile; + RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath))) + { + CMyComPtr tailStream; + const CArc &arc = *_agentSpec->_archiveLink.GetArc(); + + if (arc.ArcStreamOffset == 0) + tailStream = tempFile.OutStream; + else + { + if (arc.Offset < 0) + return E_NOTIMPL; + RINOK(arc.InStream->Seek(0, STREAM_SEEK_SET, NULL)) + RINOK(NCompress::CopyStream_ExactSize(arc.InStream, tempFile.OutStream, arc.ArcStreamOffset, NULL)) + CTailOutStream *tailStreamSpec = new CTailOutStream; + tailStream = tailStreamSpec; + tailStreamSpec->Stream = tempFile.OutStream; + tailStreamSpec->Offset = arc.ArcStreamOffset; + tailStreamSpec->Init(); + } + + HRESULT result; + + switch ((int)operation) + { + case AGENT_OP_Delete: + result = _agentSpec->DeleteItems(tailStream, indices, numItems, updateCallback100); + break; + case AGENT_OP_CreateFolder: + result = _agentSpec->CreateFolder(tailStream, newItemName, updateCallback100); + break; + case AGENT_OP_Rename: + result = _agentSpec->RenameItem(tailStream, indices, numItems, newItemName, updateCallback100); + break; + case AGENT_OP_Comment: + result = _agentSpec->CommentItem(tailStream, indices, numItems, newItemName, updateCallback100); + break; + case AGENT_OP_CopyFromFile: + result = _agentSpec->UpdateOneFile(tailStream, indices, numItems, newItemName, updateCallback100); + break; + case AGENT_OP_Uni: + { + Byte actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (unsigned i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = (Byte)actionSet->StateActions[i]; + result = _agentSpec->DoOperation2( + moveMode ? &requestedPaths : NULL, + moveMode ? &processedPaths : NULL, + tailStream, actionSetByte, NULL, updateCallback100); + break; + } + default: + return E_FAIL; + } + + RINOK(result) + } + + _agentSpec->KeepModeForNextOpen(); + _agent->Close(); + + // before 9.26: if there was error for MoveToOriginal archive was closed. + // now: we reopen archive after close + + // m_FolderItem = NULL; + _items.Clear(); + _proxyDirIndex = k_Proxy_RootDirIndex; + + CMyComPtr updateCallback_MoveArc; + if (progress) + progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc); + + HRESULT res; + if (updateCallback_MoveArc) + { + const FString &tempFilePath = tempFile.Get_TempFilePath(); + UInt64 totalSize = 0; + { + NFind::CFileInfo fi; + if (fi.Find(tempFilePath)) + totalSize = fi.Size; + } + RINOK(updateCallback_MoveArc->MoveArc_Start( + fs2us(tempFilePath), + fs2us(tempFile.Get_OriginalFilePath()), + totalSize, + 1)) // updateMode + + C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc); + res = tempFile.MoveToOriginal( + true, // deleteOriginal + &prox); + if (res == S_OK) + { + res = updateCallback_MoveArc->MoveArc_Finish(); + // we don't return after E_ABORT here, because + // we want to reopen new archive still. + } + else if (prox.CallbackResult != S_OK) + res = prox.CallbackResult; + + // if updating callback returned E_ABORT, + // then openCallback still can return E_ABORT also. + // So ReOpen() will return with E_ABORT. + // But we want to open archive still. + // And Before_ArcReopen() call will clear user break status in that case. + RINOK(updateCallback_MoveArc->Before_ArcReopen()) + } + else + res = tempFile.MoveToOriginal(true); // deleteOriginal + + // RINOK(res); + if (res == S_OK) + { + if (moveMode) + { + unsigned i; + for (i = 0; i < processedPaths.Size(); i++) + { + DeleteFileAlways(processedPaths[i]); + } + for (i = 0; i < requestedPaths.Size(); i++) + { + const FString &fs = requestedPaths[i]; + if (NFind::DoesDirExist(fs)) + Delete_EmptyFolder_And_EmptySubFolders(fs); + } + } + } + + { + CMyComPtr openCallback; + if (updateCallback100) + updateCallback100->QueryInterface(IID_IArchiveOpenCallback, (void **)&openCallback); + RINOK(_agent->ReOpen(openCallback)) + } + + // CAgent::ReOpen() deletes _proxy and _proxy2 + // _items.Clear(); + _proxy = NULL; + _proxy2 = NULL; + // _proxyDirIndex = k_Proxy_RootDirIndex; + _isAltStreamFolder = false; + + + // ---------- Restore FolderItem ---------- + + CMyComPtr archiveFolder; + RINOK(_agent->BindToRootFolder(&archiveFolder)) + + // CAgent::BindToRootFolder() changes _proxy and _proxy2 + _proxy = _agentSpec->_proxy; + _proxy2 = _agentSpec->_proxy2; + + if (_proxy) + { + FOR_VECTOR (i, pathParts) + { + const int next = _proxy->FindSubDir(_proxyDirIndex, pathParts[i]); + if (next == -1) + break; + _proxyDirIndex = (unsigned)next; + } + } + + if (_proxy2) + { + if (pathParts.IsEmpty() && isAltStreamFolder) + { + _proxyDirIndex = k_Proxy2_AltRootDirIndex; + } + else FOR_VECTOR (i, pathParts) + { + const bool dirOnly = (i + 1 < pathParts.Size() || !isAltStreamFolder); + const int index = _proxy2->FindItem(_proxyDirIndex, pathParts[i], dirOnly); + if (index == -1) + break; + + const CProxyFile2 &file = _proxy2->Files[_proxy2->Dirs[_proxyDirIndex].Items[index]]; + + if (dirOnly) + _proxyDirIndex = (unsigned)file.DirIndex; + else + { + if (file.AltDirIndex != -1) + _proxyDirIndex = (unsigned)file.AltDirIndex; + break; + } + } + } + + /* + if (pathParts.IsEmpty() && isAltStreamFolder) + { + CMyComPtr folderAltStreams; + archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams); + if (folderAltStreams) + { + CMyComPtr newFolder; + folderAltStreams->BindToAltStreams((UInt32)(Int32)-1, &newFolder); + if (newFolder) + archiveFolder = newFolder; + } + } + + FOR_VECTOR (i, pathParts) + { + CMyComPtr newFolder; + + if (isAltStreamFolder && i == pathParts.Size() - 1) + { + CMyComPtr folderAltStreams; + archiveFolder.QueryInterface(IID_IFolderAltStreams, &folderAltStreams); + if (folderAltStreams) + folderAltStreams->BindToAltStreams(pathParts[i], &newFolder); + } + else + archiveFolder->BindToFolder(pathParts[i], &newFolder); + + if (!newFolder) + break; + archiveFolder = newFolder; + } + + CMyComPtr archiveFolderInternal; + RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); + CAgentFolder *agentFolder; + RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder)); + _proxyDirIndex = agentFolder->_proxyDirIndex; + // _parentFolder = agentFolder->_parentFolder; + */ + + if (_proxy2) + _isAltStreamFolder = _proxy2->IsAltDir(_proxyDirIndex); + + return res; + + } + catch(const UString &s) + { + if (updateCallback100) + { + UString s2 ("Error: "); + s2 += s; + RINOK(updateCallback100->UpdateErrorMessage(s2)) + return E_FAIL; + } + throw; + } +} + + +Z7_COM7F_IMF(CAgentFolder::CopyFrom(Int32 moveMode, + const wchar_t *fromFolderPath, /* test it */ + const wchar_t * const *itemsPaths, + UInt32 numItems, + IProgress *progress)) +{ + COM_TRY_BEGIN + { + RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems)) + return CommonUpdateOperation(AGENT_OP_Uni, (moveMode != 0), NULL, + &NUpdateArchive::k_ActionSet_Add, + NULL, 0, progress); + } + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress *progress)) +{ + COM_TRY_BEGIN + return CommonUpdateOperation(AGENT_OP_CopyFromFile, false, itemPath, + &NUpdateArchive::k_ActionSet_Add, + &destIndex, 1, progress); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress)) +{ + COM_TRY_BEGIN + return CommonUpdateOperation(AGENT_OP_Delete, false, NULL, + &NUpdateArchive::k_ActionSet_Delete, indices, numItems, progress); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress)) +{ + COM_TRY_BEGIN + + if (_isAltStreamFolder) + return E_NOTIMPL; + + if (_proxy2) + { + if (_proxy2->IsThere_SubDir(_proxyDirIndex, name)) + return ERROR_ALREADY_EXISTS; + } + else + { + if (_proxy->FindSubDir(_proxyDirIndex, name) != -1) + return ERROR_ALREADY_EXISTS; + } + + return CommonUpdateOperation(AGENT_OP_CreateFolder, false, name, NULL, NULL, 0, progress); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)) +{ + COM_TRY_BEGIN + return CommonUpdateOperation(AGENT_OP_Rename, false, newName, NULL, + &index, 1, progress); + COM_TRY_END +} + +Z7_COM7F_IMF(CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CAgentFolder::SetProperty(UInt32 index, PROPID propID, + const PROPVARIANT *value, IProgress *progress)) +{ + COM_TRY_BEGIN + if (propID != kpidComment || value->vt != VT_BSTR) + return E_NOTIMPL; + if (!_agentSpec || !_agentSpec->GetTypeOfArc(_agentSpec->GetArc()).IsEqualTo_Ascii_NoCase("zip")) + return E_NOTIMPL; + + return CommonUpdateOperation(AGENT_OP_Comment, false, value->bstrVal, NULL, + &index, 1, progress); + COM_TRY_END +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/IFolderArchive.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/IFolderArchive.h --- p7zip-rar-16.02/CPP/7zip/UI/Agent/IFolderArchive.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/IFolderArchive.h 2024-10-18 08:00:00.000000000 +0000 @@ -1,119 +1,123 @@ -// IFolderArchive.h - -#ifndef __IFOLDER_ARCHIVE_H -#define __IFOLDER_ARCHIVE_H - -#include "../../../Common/MyString.h" - -#include "../../Archive/IArchive.h" -#include "../../UI/Common/LoadCodecs.h" -#include "../../UI/FileManager/IFolder.h" - -#include "../Common/ExtractMode.h" -#include "../Common/IFileExtractCallback.h" - -#define FOLDER_ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 0x01, x) -#define FOLDER_ARCHIVE_INTERFACE(i, x) FOLDER_ARCHIVE_INTERFACE_SUB(i, IUnknown, x) - -/* ---------- IArchiveFolder ---------- -IArchiveFolder is implemented by CAgentFolder (Agent/Agent.h) -IArchiveFolder is used by: - - FileManager/PanelCopy.cpp - CPanel::CopyTo(), if (options->testMode) - - FAR/PluginRead.cpp - CPlugin::ExtractFiles -*/ - -#define INTERFACE_IArchiveFolder(x) \ - STDMETHOD(Extract)(const UInt32 *indices, UInt32 numItems, \ - Int32 includeAltStreams, \ - Int32 replaceAltStreamCharsMode, \ - NExtract::NPathMode::EEnum pathMode, \ - NExtract::NOverwriteMode::EEnum overwriteMode, \ - const wchar_t *path, Int32 testMode, \ - IFolderArchiveExtractCallback *extractCallback2) x; \ - -FOLDER_ARCHIVE_INTERFACE(IArchiveFolder, 0x0D) -{ - INTERFACE_IArchiveFolder(PURE) -}; - - -/* ---------- IInFolderArchive ---------- -IInFolderArchive is implemented by CAgent (Agent/Agent.h) -IInFolderArchive Is used by FAR/Plugin -*/ - -#define INTERFACE_IInFolderArchive(x) \ - STDMETHOD(Open)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback) x; \ - STDMETHOD(ReOpen)(IArchiveOpenCallback *openArchiveCallback) x; \ - STDMETHOD(Close)() x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) x; \ - STDMETHOD(Extract)(NExtract::NPathMode::EEnum pathMode, \ - NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \ - Int32 testMode, IFolderArchiveExtractCallback *extractCallback2) x; \ - -FOLDER_ARCHIVE_INTERFACE(IInFolderArchive, 0x0E) -{ - INTERFACE_IInFolderArchive(PURE) -}; - -#define INTERFACE_IFolderArchiveUpdateCallback(x) \ - STDMETHOD(CompressOperation)(const wchar_t *name) x; \ - STDMETHOD(DeleteOperation)(const wchar_t *name) x; \ - STDMETHOD(OperationResult)(Int32 opRes) x; \ - STDMETHOD(UpdateErrorMessage)(const wchar_t *message) x; \ - STDMETHOD(SetNumFiles)(UInt64 numFiles) x; \ - -FOLDER_ARCHIVE_INTERFACE_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B) -{ - INTERFACE_IFolderArchiveUpdateCallback(PURE) -}; - -#define INTERFACE_IOutFolderArchive(x) \ - STDMETHOD(SetFolder)(IFolderFolder *folder) x; \ - STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t * const *names, UInt32 numNames) x; \ - STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, \ - const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(DoOperation)( \ - FStringVector *requestedPaths, \ - FStringVector *processedPaths, \ - CCodecs *codecs, int index, \ - ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ - IFolderArchiveUpdateCallback *updateCallback) x; \ - STDMETHOD(DoOperation2)( \ - FStringVector *requestedPaths, \ - FStringVector *processedPaths, \ - ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ - IFolderArchiveUpdateCallback *updateCallback) x; \ - -FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0F) -{ - INTERFACE_IOutFolderArchive(PURE) -}; - - -#define INTERFACE_IFolderArchiveUpdateCallback2(x) \ - STDMETHOD(OpenFileError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ReadingFileError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 isEncrypted, const wchar_t *path) x; \ - STDMETHOD(ReportUpdateOperation)(UInt32 notifyOp, const wchar_t *path, Int32 isDir) x; \ - -FOLDER_ARCHIVE_INTERFACE(IFolderArchiveUpdateCallback2, 0x10) -{ - INTERFACE_IFolderArchiveUpdateCallback2(PURE) -}; - - -#define INTERFACE_IFolderScanProgress(x) \ - STDMETHOD(ScanError)(const wchar_t *path, HRESULT errorCode) x; \ - STDMETHOD(ScanProgress)(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 isDir) x; \ - -FOLDER_ARCHIVE_INTERFACE(IFolderScanProgress, 0x11) -{ - INTERFACE_IFolderScanProgress(PURE) -}; - -#endif +// IFolderArchive.h + +#ifndef ZIP7_INC_IFOLDER_ARCHIVE_H +#define ZIP7_INC_IFOLDER_ARCHIVE_H + +#include "../../../Common/MyString.h" + +#include "../../Archive/IArchive.h" +#include "../../UI/Common/LoadCodecs.h" +#include "../../UI/FileManager/IFolder.h" + +#include "../Common/ExtractMode.h" +#include "../Common/IFileExtractCallback.h" + +Z7_PURE_INTERFACES_BEGIN + +/* ---------- IArchiveFolder ---------- +IArchiveFolder is implemented by CAgentFolder (Agent/Agent.h) +IArchiveFolder is used by: + - FileManager/PanelCopy.cpp + CPanel::CopyTo(), if (options->testMode) + - FAR/PluginRead.cpp + CPlugin::ExtractFiles +*/ + +#define Z7_IFACEM_IArchiveFolder(x) \ + x(Extract(const UInt32 *indices, UInt32 numItems, \ + Int32 includeAltStreams, \ + Int32 replaceAltStreamCharsMode, \ + NExtract::NPathMode::EEnum pathMode, \ + NExtract::NOverwriteMode::EEnum overwriteMode, \ + const wchar_t *path, Int32 testMode, \ + IFolderArchiveExtractCallback *extractCallback2)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IArchiveFolder, 0x0D) + + +/* ---------- IInFolderArchive ---------- +IInFolderArchive is implemented by CAgent (Agent/Agent.h) +IInFolderArchive Is used by FAR/Plugin +*/ + +#define Z7_IFACEM_IInFolderArchive(x) \ + x(Open(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, BSTR *archiveTypeRes, IArchiveOpenCallback *openArchiveCallback)) \ + x(ReOpen(IArchiveOpenCallback *openArchiveCallback)) \ + x(Close()) \ + x(GetNumberOfProperties(UInt32 *numProperties)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(BindToRootFolder(IFolderFolder **resultFolder)) \ + x(Extract(NExtract::NPathMode::EEnum pathMode, \ + NExtract::NOverwriteMode::EEnum overwriteMode, const wchar_t *path, \ + Int32 testMode, IFolderArchiveExtractCallback *extractCallback2)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IInFolderArchive, 0x0E) + +#define Z7_IFACEM_IFolderArchiveUpdateCallback(x) \ + x(CompressOperation(const wchar_t *name)) \ + x(DeleteOperation(const wchar_t *name)) \ + x(OperationResult(Int32 opRes)) \ + x(UpdateErrorMessage(const wchar_t *message)) \ + x(SetNumFiles(UInt64 numFiles)) \ + +Z7_IFACE_CONSTR_FOLDERARC_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B) + +#define Z7_IFACEM_IOutFolderArchive(x) \ + x(SetFolder(IFolderFolder *folder)) \ + x(SetFiles(const wchar_t *folderPrefix, const wchar_t * const *names, UInt32 numNames)) \ + x(DeleteItems(ISequentialOutStream *outArchiveStream, \ + const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback)) \ + x(DoOperation( \ + FStringVector *requestedPaths, \ + FStringVector *processedPaths, \ + CCodecs *codecs, int index, \ + ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ + IFolderArchiveUpdateCallback *updateCallback)) \ + x(DoOperation2( \ + FStringVector *requestedPaths, \ + FStringVector *processedPaths, \ + ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \ + IFolderArchiveUpdateCallback *updateCallback)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IOutFolderArchive, 0x0F) + + +#define Z7_IFACEM_IFolderArchiveUpdateCallback2(x) \ + x(OpenFileError(const wchar_t *path, HRESULT errorCode)) \ + x(ReadingFileError(const wchar_t *path, HRESULT errorCode)) \ + x(ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *path)) \ + x(ReportUpdateOperation(UInt32 notifyOp, const wchar_t *path, Int32 isDir)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback2, 0x10) + + +#define Z7_IFACEM_IFolderScanProgress(x) \ + x(ScanError(const wchar_t *path, HRESULT errorCode)) \ + x(ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 isDir)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderScanProgress, 0x11) + + +#define Z7_IFACEM_IFolderSetZoneIdMode(x) \ + x(SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12) + +#define Z7_IFACEM_IFolderSetZoneIdFile(x) \ + x(SetZoneIdFile(const Byte *data, UInt32 size)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdFile, 0x13) + + +// if the caller calls Before_ArcReopen(), the callee must +// clear user break status, because the caller want to open archive still. +#define Z7_IFACEM_IFolderArchiveUpdateCallback_MoveArc(x) \ + x(MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) \ + x(MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) \ + x(MoveArc_Finish()) \ + x(Before_ArcReopen()) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback_MoveArc, 0x14) + +Z7_PURE_INTERFACES_END +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Agent/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp 2023-04-01 14:00:00.000000000 +0000 @@ -1,208 +1,208 @@ -// UpdateCallbackAgent.h - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/ErrorMsg.h" - -#include "UpdateCallbackAgent.h" - -using namespace NWindows; - -void CUpdateCallbackAgent::SetCallback(IFolderArchiveUpdateCallback *callback) -{ - Callback = callback; - _compressProgress.Release(); - Callback2.Release(); - if (Callback) - { - Callback.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); - Callback.QueryInterface(IID_IFolderArchiveUpdateCallback2, &Callback2); - } -} - -HRESULT CUpdateCallbackAgent::SetNumItems(UInt64 numItems) -{ - if (Callback) - return Callback->SetNumFiles(numItems); - return S_OK; -} - - -HRESULT CUpdateCallbackAgent::WriteSfx(const wchar_t * /* name */, UInt64 /* size */) -{ - return S_OK; -} - - -HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size) -{ - if (Callback) - return Callback->SetTotal(size); - return S_OK; -} - -HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue) -{ - if (Callback) - return Callback->SetCompleted(completeValue); - return S_OK; -} - -HRESULT CUpdateCallbackAgent::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - if (_compressProgress) - return _compressProgress->SetRatioInfo(inSize, outSize); - return S_OK; -} - -HRESULT CUpdateCallbackAgent::CheckBreak() -{ - return S_OK; -} - -/* -HRESULT CUpdateCallbackAgent::Finalize() -{ - return S_OK; -} -*/ - -HRESULT CUpdateCallbackAgent::OpenFileError(const FString &path, DWORD systemError) -{ - HRESULT hres = HRESULT_FROM_WIN32(systemError); - // if (systemError == ERROR_SHARING_VIOLATION) - { - if (Callback2) - { - RINOK(Callback2->OpenFileError(fs2us(path), hres)); - return S_FALSE; - } - - if (Callback) - { - UString s = L"WARNING: "; - s += NError::MyFormatMessage(systemError); - s += L": "; - s += fs2us(path); - RINOK(Callback->UpdateErrorMessage(s)); - return S_FALSE; - } - } - // FailedFiles.Add(name); - return hres; -} - -HRESULT CUpdateCallbackAgent::ReadingFileError(const FString &path, DWORD systemError) -{ - HRESULT hres = HRESULT_FROM_WIN32(systemError); - - // if (systemError == ERROR_SHARING_VIOLATION) - { - if (Callback2) - { - RINOK(Callback2->ReadingFileError(fs2us(path), hres)); - } - else if (Callback) - { - UString s = L"ERROR: "; - s += NError::MyFormatMessage(systemError); - s += L": "; - s += fs2us(path); - RINOK(Callback->UpdateErrorMessage(s)); - } - } - // FailedFiles.Add(name); - return hres; -} - -HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool isDir, bool /* isAnti */, UInt32 mode) -{ - if (Callback2) - return Callback2->ReportUpdateOperation(mode, name, BoolToInt(isDir)); - if (Callback) - return Callback->CompressOperation(name); - return S_OK; -} - -HRESULT CUpdateCallbackAgent::SetOperationResult(Int32 operationResult) -{ - if (Callback) - return Callback->OperationResult(operationResult); - return S_OK; -} - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); - -HRESULT CUpdateCallbackAgent::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) -{ - if (Callback2) - { - return Callback2->ReportExtractResult(opRes, isEncrypted, name); - } - /* - if (mode != NArchive::NExtract::NOperationResult::kOK) - { - Int32 encrypted = 0; - UString s; - SetExtractErrorMessage(mode, encrypted, name, s); - // ProgressDialog->Sync.AddError_Message(s); - } - */ - return S_OK; -} - -HRESULT CUpdateCallbackAgent::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) -{ - if (Callback2) - { - return Callback2->ReportUpdateOperation(op, name, BoolToInt(isDir)); - } - return S_OK; -} - -/* -HRESULT CUpdateCallbackAgent::SetPassword(const UString & - #ifndef _NO_CRYPTO - password - #endif - ) -{ - #ifndef _NO_CRYPTO - PasswordIsDefined = true; - Password = password; - #endif - return S_OK; -} -*/ - -HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - *password = NULL; - *passwordIsDefined = BoolToInt(false); - if (!_cryptoGetTextPassword) - { - if (!Callback) - return S_OK; - Callback.QueryInterface(IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); - if (!_cryptoGetTextPassword) - return S_OK; - } - return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); -} - -HRESULT CUpdateCallbackAgent::CryptoGetTextPassword(BSTR *password) -{ - *password = NULL; - CMyComPtr getTextPassword; - Callback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); - if (!getTextPassword) - return E_NOTIMPL; - return getTextPassword->CryptoGetTextPassword(password); -} - -HRESULT CUpdateCallbackAgent::ShowDeleteFile(const wchar_t *name, bool /* isDir */) -{ - return Callback->DeleteOperation(name); -} +// UpdateCallbackAgent.h + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/ErrorMsg.h" + +#include "UpdateCallbackAgent.h" + +using namespace NWindows; + +void CUpdateCallbackAgent::SetCallback(IFolderArchiveUpdateCallback *callback) +{ + Callback = callback; + _compressProgress.Release(); + Callback2.Release(); + if (Callback) + { + Callback.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); + Callback.QueryInterface(IID_IFolderArchiveUpdateCallback2, &Callback2); + } +} + +HRESULT CUpdateCallbackAgent::SetNumItems(const CArcToDoStat &stat) +{ + if (Callback) + return Callback->SetNumFiles(stat.Get_NumDataItems_Total()); + return S_OK; +} + + +HRESULT CUpdateCallbackAgent::WriteSfx(const wchar_t * /* name */, UInt64 /* size */) +{ + return S_OK; +} + + +HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size) +{ + if (Callback) + return Callback->SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue) +{ + if (Callback) + return Callback->SetCompleted(completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + if (_compressProgress) + return _compressProgress->SetRatioInfo(inSize, outSize); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CheckBreak() +{ + return S_OK; +} + +/* +HRESULT CUpdateCallbackAgent::Finalize() +{ + return S_OK; +} +*/ + +HRESULT CUpdateCallbackAgent::OpenFileError(const FString &path, DWORD systemError) +{ + const HRESULT hres = HRESULT_FROM_WIN32(systemError); + // if (systemError == ERROR_SHARING_VIOLATION) + { + if (Callback2) + { + RINOK(Callback2->OpenFileError(fs2us(path), hres)) + return S_FALSE; + } + + if (Callback) + { + UString s ("WARNING: "); + s += NError::MyFormatMessage(systemError); + s += ": "; + s += fs2us(path); + RINOK(Callback->UpdateErrorMessage(s)) + return S_FALSE; + } + } + // FailedFiles.Add(name); + return hres; +} + +HRESULT CUpdateCallbackAgent::ReadingFileError(const FString &path, DWORD systemError) +{ + const HRESULT hres = HRESULT_FROM_WIN32(systemError); + + // if (systemError == ERROR_SHARING_VIOLATION) + { + if (Callback2) + { + RINOK(Callback2->ReadingFileError(fs2us(path), hres)) + } + else if (Callback) + { + UString s ("ERROR: "); + s += NError::MyFormatMessage(systemError); + s += ": "; + s += fs2us(path); + RINOK(Callback->UpdateErrorMessage(s)) + } + } + // FailedFiles.Add(name); + return hres; +} + +HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool isDir, bool /* isAnti */, UInt32 mode) +{ + if (Callback2) + return Callback2->ReportUpdateOperation(mode, name, BoolToInt(isDir)); + if (Callback) + return Callback->CompressOperation(name); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetOperationResult(Int32 operationResult) +{ + if (Callback) + return Callback->OperationResult(operationResult); + return S_OK; +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); + +HRESULT CUpdateCallbackAgent::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) +{ + if (Callback2) + { + return Callback2->ReportExtractResult(opRes, isEncrypted, name); + } + /* + if (mode != NArchive::NExtract::NOperationResult::kOK) + { + Int32 encrypted = 0; + UString s; + SetExtractErrorMessage(mode, encrypted, name, s); + // ProgressDialog->Sync.AddError_Message(s); + } + */ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) +{ + if (Callback2) + { + return Callback2->ReportUpdateOperation(op, name, BoolToInt(isDir)); + } + return S_OK; +} + +/* +HRESULT CUpdateCallbackAgent::SetPassword(const UString & + #ifndef Z7_NO_CRYPTO + password + #endif + ) +{ + #ifndef Z7_NO_CRYPTO + PasswordIsDefined = true; + Password = password; + #endif + return S_OK; +} +*/ + +HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + *password = NULL; + *passwordIsDefined = BoolToInt(false); + if (!_cryptoGetTextPassword) + { + if (!Callback) + return S_OK; + Callback.QueryInterface(IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); + if (!_cryptoGetTextPassword) + return S_OK; + } + return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); +} + +HRESULT CUpdateCallbackAgent::CryptoGetTextPassword(BSTR *password) +{ + *password = NULL; + CMyComPtr getTextPassword; + Callback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); + if (!getTextPassword) + return E_NOTIMPL; + return getTextPassword->CryptoGetTextPassword(password); +} + +HRESULT CUpdateCallbackAgent::ShowDeleteFile(const wchar_t *name, bool /* isDir */) +{ + return Callback->DeleteOperation(name); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Agent/UpdateCallbackAgent.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.h --- p7zip-rar-16.02/CPP/7zip/UI/Agent/UpdateCallbackAgent.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Agent/UpdateCallbackAgent.h 2023-01-28 20:00:00.000000000 +0000 @@ -1,22 +1,22 @@ -// UpdateCallbackAgent.h - -#ifndef __UPDATE_CALLBACK_AGENT_H -#define __UPDATE_CALLBACK_AGENT_H - -#include "../Common/UpdateCallback.h" - -#include "IFolderArchive.h" - -class CUpdateCallbackAgent: public IUpdateCallbackUI -{ - INTERFACE_IUpdateCallbackUI(;) - - CMyComPtr _cryptoGetTextPassword; - CMyComPtr Callback; - CMyComPtr Callback2; - CMyComPtr _compressProgress; -public: - void SetCallback(IFolderArchiveUpdateCallback *callback); -}; - -#endif +// UpdateCallbackAgent.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_AGENT_H +#define ZIP7_INC_UPDATE_CALLBACK_AGENT_H + +#include "../Common/UpdateCallback.h" + +#include "IFolderArchive.h" + +class CUpdateCallbackAgent Z7_final: public IUpdateCallbackUI +{ + Z7_IFACE_IMP(IUpdateCallbackUI) + + CMyComPtr _cryptoGetTextPassword; + CMyComPtr Callback; + CMyComPtr Callback2; + CMyComPtr _compressProgress; +public: + void SetCallback(IFolderArchiveUpdateCallback *callback); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.cpp 2015-11-09 15:36:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.cpp 2024-03-13 06:00:00.000000000 +0000 @@ -1,973 +1,1145 @@ -// Client7z.cpp - -#include "StdAfx.h" - -#include - -#include "../../../Common/MyWindows.h" - -#include "../../../Common/Defs.h" -#include "../../../Common/MyInitGuid.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/NtCheck.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../Common/FileStreams.h" - -#include "../../Archive/IArchive.h" - -#include "../../IPassword.h" -#include "../../../../C/7zVersion.h" - -#ifdef _WIN32 -HINSTANCE g_hInstance = 0; -#endif - -// Tou can find the list of all GUIDs in Guid.txt file. -// use another CLSIDs, if you want to support other formats (zip, rar, ...). -// {23170F69-40C1-278A-1000-000110070000} - -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 CLSID_Format CLSID_CFormat7z -// #define CLSID_Format CLSID_CFormatXz - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -#define kDllName "7z.dll" - -static const char *kCopyrightString = "\n7-Zip " MY_VERSION -" (" kDllName " client) " -MY_COPYRIGHT " " MY_DATE "\n"; - -static const char *kHelpString = -"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n" -"Examples:\n" -" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" -" Client7z.exe l archive.7z : List contents of archive.7z\n" -" Client7z.exe x archive.7z : eXtract files from archive.7z\n"; - - -static AString FStringToConsoleString(const FString &s) -{ - return GetOemString(fs2us(s)); -} - -static FString CmdStringToFString(const char *s) -{ - return us2fs(GetUnicodeString(s)); -} - -static void PrintString(const UString &s) -{ - printf("%s", (LPCSTR)GetOemString(s)); -} - -static void PrintString(const AString &s) -{ - printf("%s", (LPCSTR)s); -} - -static void PrintNewLine() -{ - PrintString("\n"); -} - -static void PrintStringLn(const AString &s) -{ - PrintString(s); - PrintNewLine(); -} - -static void PrintError(const char *message, const FString &name) -{ - printf("Error: %s", (LPCSTR)message); - PrintNewLine(); - PrintString(FStringToConsoleString(name)); - PrintNewLine(); -} - -static void PrintError(const AString &s) -{ - PrintNewLine(); - PrintString(s); - PrintNewLine(); -} - -static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) -{ - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); - if (prop.vt == VT_BOOL) - result = VARIANT_BOOLToBool(prop.boolVal); - else if (prop.vt == VT_EMPTY) - result = false; - else - return E_FAIL; - return S_OK; -} - -static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) -{ - return IsArchiveItemProp(archive, index, kpidIsDir, result); -} - - -static const wchar_t *kEmptyFileAlias = L"[Content]"; - - -////////////////////////////////////////////////////////////// -// Archive Open callback class - - -class CArchiveOpenCallback: - public IArchiveOpenCallback, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); - STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - bool PasswordIsDefined; - UString Password; - - CArchiveOpenCallback() : PasswordIsDefined(false) {} -}; - -STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) -{ - if (!PasswordIsDefined) - { - // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; - PrintError("Password is not defined"); - return E_ABORT; - } - return StringToBstr(Password, password); -} - - -////////////////////////////////////////////////////////////// -// Archive Extracting callback class - -static const char *kTestingString = "Testing "; -static const char *kExtractingString = "Extracting "; -static const char *kSkippingString = "Skipping "; - -static const char *kUnsupportedMethod = "Unsupported Method"; -static const char *kCRCFailed = "CRC Failed"; -static const char *kDataError = "Data Error"; -static const char *kUnavailableData = "Unavailable data"; -static const char *kUnexpectedEnd = "Unexpected end of data"; -static const char *kDataAfterEnd = "There are some data after the end of the payload data"; -static const char *kIsNotArc = "Is not archive"; -static const char *kHeadersError = "Headers Error"; - -class CArchiveExtractCallback: - public IArchiveExtractCallback, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(ICryptoGetTextPassword) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - // IArchiveExtractCallback - STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); - STDMETHOD(PrepareOperation)(Int32 askExtractMode); - STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); - -private: - CMyComPtr _archiveHandler; - FString _directoryPath; // Output directory - UString _filePath; // name inside arcvhive - FString _diskFilePath; // full path to file on disk - bool _extractMode; - struct CProcessedFileInfo - { - FILETIME MTime; - UInt32 Attrib; - bool isDir; - bool AttribDefined; - bool MTimeDefined; - } _processedFileInfo; - - COutFileStream *_outFileStreamSpec; - CMyComPtr _outFileStream; - - CObjectVector _delayedSymLinks; - -public: - void Init(IInArchive *archiveHandler, const FString &directoryPath); - - HRESULT SetFinalAttribs(); - - UInt64 NumErrors; - bool PasswordIsDefined; - UString Password; - - CArchiveExtractCallback() : PasswordIsDefined(false) {} -}; - -void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath) -{ - NumErrors = 0; - _archiveHandler = archiveHandler; - _directoryPath = directoryPath; - NName::NormalizeDirPathPrefix(_directoryPath); -} - -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, - ISequentialOutStream **outStream, Int32 askExtractMode) -{ - *outStream = 0; - _outFileStream.Release(); - - { - // Get Name - NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); - - UString fullPath; - if (prop.vt == VT_EMPTY) - fullPath = kEmptyFileAlias; - else - { - if (prop.vt != VT_BSTR) - return E_FAIL; - fullPath = prop.bstrVal; - } - _filePath = fullPath; - } - - if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) - return S_OK; - - { - // Get Attrib - NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)); - if (prop.vt == VT_EMPTY) - { - _processedFileInfo.Attrib = 0; - _processedFileInfo.AttribDefined = false; - } - else - { - if (prop.vt != VT_UI4) - return E_FAIL; - _processedFileInfo.Attrib = prop.ulVal; - _processedFileInfo.AttribDefined = true; - } - } - - RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir)); - - { - // 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; - break; - default: - return E_FAIL; - } - - } - { - // Get Size - NCOM::CPropVariant prop; - RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)); - UInt64 newFileSize; - /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize); - } - - - { - // Create folders for file - int slashPos = _filePath.ReverseFind_PathSepar(); - if (slashPos >= 0) - CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos))); - } - - FString fullProcessedPath = _directoryPath + us2fs(_filePath); - _diskFilePath = fullProcessedPath; - - if (_processedFileInfo.isDir) - { - CreateComplexDir(fullProcessedPath); - } - else - { - NFind::CFileInfo fi; - if (fi.Find(fullProcessedPath)) - { - if (!DeleteFileAlways(fullProcessedPath)) - { - PrintError("Can not delete output file", fullProcessedPath); - return E_ABORT; - } - } - - _outFileStreamSpec = new COutFileStream; - CMyComPtr outStreamLoc(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS)) - { - PrintError("Can not open output file", fullProcessedPath); - return E_ABORT; - } - _outFileStream = outStreamLoc; - *outStream = outStreamLoc.Detach(); - } - return S_OK; -} - -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) -{ - _extractMode = false; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; - }; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: PrintString(kExtractingString); break; - case NArchive::NExtract::NAskMode::kTest: PrintString(kTestingString); break; - case NArchive::NExtract::NAskMode::kSkip: PrintString(kSkippingString); break; - }; - PrintString(_filePath); - return S_OK; -} - -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) -{ - switch (operationResult) - { - case NArchive::NExtract::NOperationResult::kOK: - break; - default: - { - NumErrors++; - PrintString(" : "); - const char *s = NULL; - switch (operationResult) - { - case NArchive::NExtract::NOperationResult::kUnsupportedMethod: - s = kUnsupportedMethod; - break; - case NArchive::NExtract::NOperationResult::kCRCError: - s = kCRCFailed; - break; - case NArchive::NExtract::NOperationResult::kDataError: - s = kDataError; - break; - case NArchive::NExtract::NOperationResult::kUnavailable: - s = kUnavailableData; - break; - case NArchive::NExtract::NOperationResult::kUnexpectedEnd: - s = kUnexpectedEnd; - break; - case NArchive::NExtract::NOperationResult::kDataAfterEnd: - s = kDataAfterEnd; - break; - case NArchive::NExtract::NOperationResult::kIsNotArc: - s = kIsNotArc; - break; - case NArchive::NExtract::NOperationResult::kHeadersError: - s = kHeadersError; - break; - } - if (s) - { - PrintString("Error : "); - PrintString(s); - } - else - { - char temp[16]; - ConvertUInt32ToString(operationResult, temp); - PrintString("Error #"); - PrintString(temp); - } - } - } - - if (_outFileStream) - { - if (_processedFileInfo.MTimeDefined) - _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime); - RINOK(_outFileStreamSpec->Close()); - } - _outFileStream.Release(); - if (_extractMode && _processedFileInfo.AttribDefined) - SetFileAttrib(_diskFilePath, _processedFileInfo.Attrib, &_delayedSymLinks); - PrintNewLine(); - return S_OK; -} - -HRESULT CArchiveExtractCallback::SetFinalAttribs() -{ - HRESULT result = S_OK; - - for (int i = 0; i != _delayedSymLinks.Size(); ++i) - if (!_delayedSymLinks[i].Create()) - result = E_FAIL; - - _delayedSymLinks.Clear(); - - return result; -} - -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) -{ - if (!PasswordIsDefined) - { - // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; - PrintError("Password is not defined"); - return E_ABORT; - } - return StringToBstr(Password, password); -} - - - -////////////////////////////////////////////////////////////// -// Archive Creating callback class - -struct CDirItem -{ - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UString Name; - FString FullPath; - UInt32 Attrib; - - bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } -}; - -class CArchiveUpdateCallback: - public IArchiveUpdateCallback2, - public ICryptoGetTextPassword2, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) - - // IProgress - STDMETHOD(SetTotal)(UInt64 size); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - // IUpdateCallback2 - STDMETHOD(GetUpdateItemInfo)(UInt32 index, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); - STDMETHOD(SetOperationResult)(Int32 operationResult); - STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); - STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); - - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); - -public: - CRecordVector VolumesSizes; - UString VolName; - UString VolExt; - - FString DirPrefix; - const CObjectVector *DirItems; - - bool PasswordIsDefined; - UString Password; - bool AskPassword; - - bool m_NeedBeClosed; - - FStringVector FailedFiles; - CRecordVector FailedCodes; - - CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {}; - - ~CArchiveUpdateCallback() { Finilize(); } - HRESULT Finilize(); - - void Init(const CObjectVector *dirItems) - { - DirItems = dirItems; - m_NeedBeClosed = false; - FailedFiles.Clear(); - FailedCodes.Clear(); - } -}; - -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */) -{ - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, - Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) -{ - if (newData) - *newData = BoolToInt(true); - if (newProperties) - *newProperties = BoolToInt(true); - if (indexInArchive) - *indexInArchive = (UInt32)(Int32)-1; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - - if (propID == kpidIsAnti) - { - prop = false; - prop.Detach(value); - return S_OK; - } - - { - const CDirItem &dirItem = (*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; - } - } - prop.Detach(value); - return S_OK; -} - -HRESULT CArchiveUpdateCallback::Finilize() -{ - if (m_NeedBeClosed) - { - PrintNewLine(); - m_NeedBeClosed = false; - } - return S_OK; -} - -static void GetStream2(const wchar_t *name) -{ - PrintString("Compressing "); - if (name[0] == 0) - name = kEmptyFileAlias; - PrintString(name); -} - -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) -{ - RINOK(Finilize()); - - const CDirItem &dirItem = (*DirItems)[index]; - GetStream2(dirItem.Name); - - if (dirItem.isDir()) - return S_OK; - - { - CInFileStream *inStreamSpec = new CInFileStream; - CMyComPtr inStreamLoc(inStreamSpec); - FString path = DirPrefix + dirItem.FullPath; - if (!inStreamSpec->Open(path)) - { - DWORD sysError = ::GetLastError(); - FailedCodes.Add(sysError); - FailedFiles.Add(path); - // if (systemError == ERROR_SHARING_VIOLATION) - { - PrintNewLine(); - PrintError("WARNING: can't open file"); - // PrintString(NError::MyFormatMessageW(systemError)); - return S_FALSE; - } - // return sysError; - } - *inStream = inStreamLoc.Detach(); - } - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */) -{ - m_NeedBeClosed = true; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) -{ - if (VolumesSizes.Size() == 0) - return S_FALSE; - if (index >= (UInt32)VolumesSizes.Size()) - index = VolumesSizes.Size() - 1; - *size = VolumesSizes[index]; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) -{ - wchar_t temp[16]; - ConvertUInt32ToString(index + 1, temp); - UString res = temp; - while (res.Len() < 2) - res.InsertAtFront(L'0'); - UString fileName = VolName; - fileName += L'.'; - fileName += res; - fileName += VolExt; - COutFileStream *streamSpec = new COutFileStream; - CMyComPtr streamLoc(streamSpec); - if (!streamSpec->Create(us2fs(fileName), false)) - return ::GetLastError(); - *volumeStream = streamLoc.Detach(); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - if (!PasswordIsDefined) - { - if (AskPassword) - { - // You can ask real password here from user - // Password = GetPassword(OutStream); - // PasswordIsDefined = true; - PrintError("Password is not defined"); - return E_ABORT; - } - } - *passwordIsDefined = BoolToInt(PasswordIsDefined); - return StringToBstr(Password, password); -} - - -// Main function - -#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; - -int MY_CDECL main(int numArgs, const char *args[]) -{ - NT_CHECK - - PrintStringLn(kCopyrightString); - - if (numArgs < 3) - { - PrintStringLn(kHelpString); - return 1; - } - - NDLL::CLibrary lib; - if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName))) - { - PrintError("Can not load 7-zip library"); - return 1; - } - - Func_CreateObject createObjectFunc = (Func_CreateObject)lib.GetProc("CreateObject"); - if (!createObjectFunc) - { - PrintError("Can not get CreateObject"); - return 1; - } - - char c; - { - AString command = args[1]; - if (command.Len() != 1) - { - PrintError("incorrect command"); - return 1; - } - c = (char)MyCharLower_Ascii(command[0]); - } - - FString archiveName = CmdStringToFString(args[2]); - - if (c == 'a') - { - // create archive command - if (numArgs < 4) - { - PrintStringLn(kHelpString); - return 1; - } - CObjectVector dirItems; - { - int i; - for (i = 3; i < numArgs; i++) - { - CDirItem di; - FString name = CmdStringToFString(args[i]); - - NFind::CFileInfo fi; - if (!fi.Find(name)) - { - PrintError("Can't find file", name); - return 1; - } - - 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.FullPath = name; - dirItems.Add(di); - } - } - - COutFileStream *outFileStreamSpec = new COutFileStream; - CMyComPtr outFileStream = outFileStreamSpec; - if (!outFileStreamSpec->Create(archiveName, false)) - { - PrintError("can't create archive file"); - return 1; - } - - CMyComPtr outArchive; - if (createObjectFunc(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) - { - PrintError("Can not get class object"); - return 1; - } - - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - updateCallbackSpec->Init(&dirItems); - // updateCallbackSpec->PasswordIsDefined = true; - // updateCallbackSpec->Password = L"1"; - - /* - { - const wchar_t *names[] = - { - L"s", - L"x" - }; - const unsigned kNumProps = ARRAY_SIZE(names); - NCOM::CPropVariant values[kNumProps] = - { - false, // solid mode OFF - (UInt32)9 // compression level = 9 - ultra - }; - CMyComPtr setProperties; - outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties); - if (!setProperties) - { - PrintError("ISetProperties unsupported"); - return 1; - } - RINOK(setProperties->SetProperties(names, values, kNumProps)); - } - */ - - HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); - - updateCallbackSpec->Finilize(); - - if (result != S_OK) - { - PrintError("Update Error"); - return 1; - } - - FOR_VECTOR (i, updateCallbackSpec->FailedFiles) - { - PrintNewLine(); - PrintError("Error for file", updateCallbackSpec->FailedFiles[i]); - } - - if (updateCallbackSpec->FailedFiles.Size() != 0) - return 1; - } - else - { - if (numArgs != 3) - { - PrintStringLn(kHelpString); - return 1; - } - - bool listCommand; - - if (c == 'l') - listCommand = true; - else if (c == 'x') - listCommand = false; - else - { - PrintError("incorrect command"); - return 1; - } - - CMyComPtr archive; - if (createObjectFunc(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) - { - PrintError("Can not get class object"); - return 1; - } - - CInFileStream *fileSpec = new CInFileStream; - CMyComPtr file = fileSpec; - - if (!fileSpec->Open(archiveName)) - { - PrintError("Can not open archive file", archiveName); - return 1; - } - - { - CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; - CMyComPtr openCallback(openCallbackSpec); - openCallbackSpec->PasswordIsDefined = false; - // openCallbackSpec->PasswordIsDefined = true; - // openCallbackSpec->Password = L"1"; - - const UInt64 scanSize = 1 << 23; - if (archive->Open(file, &scanSize, openCallback) != S_OK) - { - PrintError("Can not open file as archive", archiveName); - return 1; - } - } - - if (listCommand) - { - // List command - UInt32 numItems = 0; - archive->GetNumberOfItems(&numItems); - for (UInt32 i = 0; i < numItems; i++) - { - { - // Get uncompressed size of file - NCOM::CPropVariant prop; - archive->GetProperty(i, kpidSize, &prop); - char s[32]; - ConvertPropVariantToShortString(prop, s); - PrintString(s); - PrintString(" "); - } - { - // Get name of file - NCOM::CPropVariant prop; - archive->GetProperty(i, kpidPath, &prop); - if (prop.vt == VT_BSTR) - PrintString(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - PrintString("ERROR!"); - } - PrintNewLine(); - } - } - else - { - // Extract command - CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; - CMyComPtr extractCallback(extractCallbackSpec); - extractCallbackSpec->Init(archive, FTEXT("")); // second parameter is output folder path - extractCallbackSpec->PasswordIsDefined = false; - // extractCallbackSpec->PasswordIsDefined = true; - // extractCallbackSpec->Password = L"1"; - - /* - const wchar_t *names[] = - { - L"mt", - L"mtf" - }; - const unsigned kNumProps = sizeof(names) / sizeof(names[0]); - NCOM::CPropVariant values[kNumProps] = - { - (UInt32)1, - false - }; - CMyComPtr setProperties; - archive->QueryInterface(IID_ISetProperties, (void **)&setProperties); - if (setProperties) - setProperties->SetProperties(names, values, kNumProps); - */ - - HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); - if (result == S_OK) - result = extractCallbackSpec->SetFinalAttribs(); - if (result != S_OK) - { - PrintError("Extract Error"); - return 1; - } - } - } - - return 0; -} +// Client7z.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/Defs.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../Common/FileStreams.h" + +#include "../../Archive/IArchive.h" + +#if 0 +// for password request functions: +#include "../../UI/Console/UserInputUtils.h" +#endif + +#include "../../IPassword.h" +#include "../../../../C/7zVersion.h" + +#ifdef _WIN32 +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; +#endif + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +// 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 DEFINE_GUID_ARC(name, id) Z7_DEFINE_GUID(name, \ + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, id, 0x00, 0x00); + +enum +{ + kId_Zip = 1, + kId_BZip2 = 2, + kId_7z = 7, + kId_Xz = 0xC, + kId_Tar = 0xEE, + kId_GZip = 0xEF +}; + +// use another id, if you want to support other formats (zip, Xz, ...). +// DEFINE_GUID_ARC (CLSID_Format, kId_Zip) +// DEFINE_GUID_ARC (CLSID_Format, kId_BZip2) +// DEFINE_GUID_ARC (CLSID_Format, kId_Xz) +// DEFINE_GUID_ARC (CLSID_Format, kId_Tar) +// DEFINE_GUID_ARC (CLSID_Format, kId_GZip) +DEFINE_GUID_ARC (CLSID_Format, kId_7z) + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +#ifdef _WIN32 +#define kDllName "7z.dll" +#else +#define kDllName "7z.so" +#endif + +static const char * const kCopyrightString = + "\n" + "7-Zip" + " (" kDllName " client)" + " " MY_VERSION + " : " MY_COPYRIGHT_DATE + "\n"; + +static const char * const kHelpString = +"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n" +"Examples:\n" +" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" +" 7zcl.exe l archive.7z : List contents of archive.7z\n" +" 7zcl.exe x archive.7z : eXtract files from archive.7z\n"; + + +static void Convert_UString_to_AString(const UString &s, AString &temp) +{ + int codePage = CP_OEMCP; + /* + int g_CodePage = -1; + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + */ + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); +} + +static FString CmdStringToFString(const char *s) +{ + return us2fs(GetUnicodeString(s)); +} + +static void Print(const char *s) +{ + fputs(s, stdout); +} + +static void Print(const AString &s) +{ + Print(s.Ptr()); +} + +static void Print(const UString &s) +{ + AString as; + Convert_UString_to_AString(s, as); + Print(as); +} + +static void Print(const wchar_t *s) +{ + Print(UString(s)); +} + +static void PrintNewLine() +{ + Print("\n"); +} + +static void PrintStringLn(const char *s) +{ + Print(s); + PrintNewLine(); +} + +static void PrintError(const char *message) +{ + Print("Error: "); + PrintNewLine(); + Print(message); + PrintNewLine(); +} + +static void PrintError(const char *message, const FString &name) +{ + PrintError(message); + Print(name); +} + + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)) + if (prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsDir, result); +} + + +static const wchar_t * const kEmptyFileAlias = L"[Content]"; + + +////////////////////////////////////////////////////////////// +// Archive Open callback class + + +class CArchiveOpenCallback Z7_final: + public IArchiveOpenCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(IArchiveOpenCallback, ICryptoGetTextPassword) +public: + + bool PasswordIsDefined; + UString Password; + + CArchiveOpenCallback() : PasswordIsDefined(false) {} +}; + +Z7_COM7F_IMF(CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)) +{ + if (!PasswordIsDefined) + { + // You can ask real password here from user +#if 0 + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else + PrintError("Password is not defined"); + return E_ABORT; +#endif + } + return StringToBstr(Password, password); +} + + + +static const char * const kIncorrectCommand = "incorrect command"; + +////////////////////////////////////////////////////////////// +// Archive Extracting callback class + +static const char * const kTestingString = "Testing "; +static const char * const kExtractingString = "Extracting "; +static const char * const kSkippingString = "Skipping "; +static const char * const kReadingString = "Reading "; + +static const char * const kUnsupportedMethod = "Unsupported Method"; +static const char * const kCRCFailed = "CRC Failed"; +static const char * const kDataError = "Data Error"; +static const char * const kUnavailableData = "Unavailable data"; +static const char * const kUnexpectedEnd = "Unexpected end of data"; +static const char * const kDataAfterEnd = "There are some data after the end of the payload data"; +static const char * const kIsNotArc = "Is not archive"; +static const char * const kHeadersError = "Headers Error"; + + +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 Z7_final: + public IArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(IArchiveExtractCallback, ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(IProgress) + + CMyComPtr _archiveHandler; + FString _directoryPath; // Output directory + UString _filePath; // name inside arcvhive + FString _diskFilePath; // full path to file on disk + bool _extractMode; + struct CProcessedFileInfo + { + CArcTime MTime; + UInt32 Attrib; + bool isDir; + bool Attrib_Defined; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + +public: + void Init(IInArchive *archiveHandler, const FString &directoryPath); + + UInt64 NumErrors; + bool PasswordIsDefined; + UString Password; + + CArchiveExtractCallback() : PasswordIsDefined(false) {} +}; + +void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath) +{ + NumErrors = 0; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NName::NormalizeDirPathPrefix(_directoryPath); +} + +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 /* size */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode)) +{ + *outStream = NULL; + _outFileStream.Release(); + + { + // Get Name + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)) + + UString fullPath; + if (prop.vt == VT_EMPTY) + fullPath = kEmptyFileAlias; + else + { + if (prop.vt != VT_BSTR) + return E_FAIL; + fullPath = prop.bstrVal; + } + _filePath = fullPath; + } + + if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) + return S_OK; + + { + // Get Attrib + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop)) + if (prop.vt == VT_EMPTY) + { + _processedFileInfo.Attrib = 0; + _processedFileInfo.Attrib_Defined = false; + } + else + { + if (prop.vt != VT_UI4) + return E_FAIL; + _processedFileInfo.Attrib = prop.ulVal; + _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)) + switch (prop.vt) + { + case VT_EMPTY: + // _processedFileInfo.MTime = _utcMTimeDefault; + break; + case VT_FILETIME: + _processedFileInfo.MTime.Set_From_Prop(prop); + break; + default: + return E_FAIL; + } + + } + { + // Get Size + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)) + UInt64 newFileSize; + /* bool newFileSizeDefined = */ ConvertPropVariantToUInt64(prop, newFileSize); + } + + + { + // Create folders for file + int slashPos = _filePath.ReverseFind_PathSepar(); + if (slashPos >= 0) + CreateComplexDir(_directoryPath + us2fs(_filePath.Left(slashPos))); + } + + FString fullProcessedPath = _directoryPath + us2fs(_filePath); + _diskFilePath = fullProcessedPath; + + if (_processedFileInfo.isDir) + { + CreateComplexDir(fullProcessedPath); + } + else + { + NFind::CFileInfo fi; + if (fi.Find(fullProcessedPath)) + { + if (!DeleteFileAlways(fullProcessedPath)) + { + PrintError("Cannot delete output file", fullProcessedPath); + return E_ABORT; + } + } + + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->Create_ALWAYS(fullProcessedPath)) + { + PrintError("Cannot open output file", fullProcessedPath); + return E_ABORT; + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + return S_OK; +} + +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) +{ + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; + } + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break; + case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break; + case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break; + case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break; + default: + Print("??? "); break; + } + Print(_filePath); + return S_OK; +} + +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 operationResult)) +{ + switch (operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumErrors++; + Print(" : "); + const char *s = NULL; + switch (operationResult) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + s = kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + s = kCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + s = kDataError; + break; + case NArchive::NExtract::NOperationResult::kUnavailable: + s = kUnavailableData; + break; + case NArchive::NExtract::NOperationResult::kUnexpectedEnd: + s = kUnexpectedEnd; + break; + case NArchive::NExtract::NOperationResult::kDataAfterEnd: + s = kDataAfterEnd; + break; + case NArchive::NExtract::NOperationResult::kIsNotArc: + s = kIsNotArc; + break; + case NArchive::NExtract::NOperationResult::kHeadersError: + s = kHeadersError; + break; + } + if (s) + { + Print("Error : "); + Print(s); + } + else + { + char temp[16]; + ConvertUInt32ToString((UInt32)operationResult, temp); + Print("Error #"); + Print(temp); + } + } + } + + if (_outFileStream) + { + if (_processedFileInfo.MTime.Def) + { + CFiTime ft; + _processedFileInfo.MTime.Write_To_FiTime(ft); + _outFileStreamSpec->SetMTime(&ft); + } + RINOK(_outFileStreamSpec->Close()) + } + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.Attrib_Defined) + SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib); + PrintNewLine(); + return S_OK; +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) +{ + if (!PasswordIsDefined) + { +#if 0 + // You can ask real password here from user + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else + PrintError("Password is not defined"); + return E_ABORT; +#endif + } + return StringToBstr(Password, password); +} + + + +////////////////////////////////////////////////////////////// +// Archive Creating callback class + +struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase +{ + UString Path_For_Handler; + FString FullPath; // for filesystem + + CDirItem(const NWindows::NFile::NFind::CFileInfo &fi): + CFileInfoBase(fi) + {} +}; + +class CArchiveUpdateCallback Z7_final: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) + +public: + CRecordVector VolumesSizes; + UString VolName; + UString VolExt; + + FString DirPrefix; + const CObjectVector *DirItems; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + bool m_NeedBeClosed; + + FStringVector FailedFiles; + CRecordVector FailedCodes; + + CArchiveUpdateCallback(): + DirItems(NULL), + PasswordIsDefined(false), + AskPassword(false) + {} + + ~CArchiveUpdateCallback() { Finilize(); } + HRESULT Finilize(); + + void Init(const CObjectVector *dirItems) + { + DirItems = dirItems; + m_NeedBeClosed = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + } +}; + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 /* size */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)) +{ + if (newData) + *newData = BoolToInt(true); + if (newProperties) + *newProperties = BoolToInt(true); + if (indexInArchive) + *indexInArchive = (UInt32)(Int32)-1; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + + if (propID == kpidIsAnti) + { + prop = false; + prop.Detach(value); + return S_OK; + } + + { + const CDirItem &di = (*DirItems)[index]; + switch (propID) + { + 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); + return S_OK; +} + +HRESULT CArchiveUpdateCallback::Finilize() +{ + if (m_NeedBeClosed) + { + PrintNewLine(); + m_NeedBeClosed = false; + } + return S_OK; +} + +static void GetStream2(const wchar_t *name) +{ + Print("Compressing "); + if (name[0] == 0) + name = kEmptyFileAlias; + Print(name); +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) +{ + RINOK(Finilize()) + + const CDirItem &dirItem = (*DirItems)[index]; + GetStream2(dirItem.Path_For_Handler); + + if (dirItem.IsDir()) + return S_OK; + + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + FString path = DirPrefix + dirItem.FullPath; + if (!inStreamSpec->Open(path)) + { + const DWORD sysError = ::GetLastError(); + FailedCodes.Add(HRESULT_FROM_WIN32(sysError)); + FailedFiles.Add(path); + // if (systemError == ERROR_SHARING_VIOLATION) + { + PrintNewLine(); + PrintError("WARNING: can't open file"); + // Print(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + // return sysError; + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)) +{ + m_NeedBeClosed = true; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) +{ + wchar_t temp[16]; + ConvertUInt32ToString(index + 1, temp); + UString res = temp; + while (res.Len() < 2) + res.InsertAtFront(L'0'); + UString fileName = VolName; + fileName.Add_Dot(); + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if (!streamSpec->Create_NEW(us2fs(fileName))) + return GetLastError_noZero_HRESULT(); + *volumeStream = streamLoc.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { +#if 0 + RINOK(GetPassword_HRESULT(&g_StdOut, Password)) + PasswordIsDefined = true; +#else + PrintError("Password is not defined"); + return E_ABORT; +#endif + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + return StringToBstr(Password, password); +} + + +// Main function + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; +#endif + +int Z7_CDECL main(int numArgs, const char *args[]) +{ + NT_CHECK + + #ifdef ENV_HAVE_LOCALE + MY_SetLocale(); + #endif + + PrintStringLn(kCopyrightString); + + if (numArgs < 2) + { + PrintStringLn(kHelpString); + return 0; + } + + FString dllPrefix; + + #ifdef _WIN32 + dllPrefix = NDLL::GetModuleDirPrefix(); + #else + { + AString s (args[0]); + int sep = s.ReverseFind_PathSepar(); + s.DeleteFrom(sep + 1); + dllPrefix = s; + } + #endif + + NDLL::CLibrary lib; + if (!lib.Load(dllPrefix + FTEXT(kDllName))) + { + PrintError("Cannot load 7-zip library"); + return 1; + } + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#ifdef _WIN32 +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + + Func_CreateObject + f_CreateObject = Z7_GET_PROC_ADDRESS( + Func_CreateObject, lib.Get_HMODULE(), + "CreateObject"); + if (!f_CreateObject) + { + PrintError("Cannot get CreateObject"); + return 1; + } + + char c = 0; + UString password; + bool passwordIsDefined = false; + CObjectVector params; + + for (int curCmd = 1; curCmd < numArgs; curCmd++) + { + AString a(args[curCmd]); + + if (!a.IsEmpty()) + { + if (a[0] == '-') + { + if (!passwordIsDefined && a[1] == 'p') + { + password = GetUnicodeString(a.Ptr(2)); + passwordIsDefined = true; + continue; + } + } + else + { + if (c) + { + params.Add(CmdStringToFString(a)); + continue; + } + if (a.Len() == 1) + { + c = (char)MyCharLower_Ascii(a[0]); + continue; + } + } + } + { + PrintError(kIncorrectCommand); + return 1; + } + } + + if (!c || params.Size() < 1) + { + PrintError(kIncorrectCommand); + return 1; + } + + const FString &archiveName = params[0]; + + if (c == 'a') + { + // create archive command + if (params.Size() < 2) + { + PrintError(kIncorrectCommand); + return 1; + } + CObjectVector dirItems; + { + unsigned i; + for (i = 1; i < params.Size(); i++) + { + const FString &name = params[i]; + + NFind::CFileInfo fi; + if (!fi.Find(name)) + { + PrintError("Can't find file", name); + return 1; + } + + CDirItem di(fi); + + di.Path_For_Handler = fs2us(name); + di.FullPath = name; + dirItems.Add(di); + } + } + + COutFileStream *outFileStreamSpec = new COutFileStream; + CMyComPtr outFileStream = outFileStreamSpec; + if (!outFileStreamSpec->Create_NEW(archiveName)) + { + PrintError("can't create archive file"); + return 1; + } + + CMyComPtr outArchive; + if (f_CreateObject(&CLSID_Format, &IID_IOutArchive, (void **)&outArchive) != S_OK) + { + PrintError("Cannot get class object"); + return 1; + } + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + updateCallbackSpec->Init(&dirItems); + updateCallbackSpec->PasswordIsDefined = passwordIsDefined; + updateCallbackSpec->Password = password; + + /* + { + const wchar_t *names[] = + { + L"m", + L"s", + L"x" + }; + const unsigned kNumProps = Z7_ARRAY_SIZE(names); + NCOM::CPropVariant values[kNumProps] = + { + L"lzma", + false, // solid mode OFF + (UInt32)9 // compression level = 9 - ultra + }; + CMyComPtr setProperties; + outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties); + if (!setProperties) + { + PrintError("ISetProperties unsupported"); + return 1; + } + if (setProperties->SetProperties(names, values, kNumProps) != S_OK) + { + PrintError("SetProperties() error"); + return 1; + } + } + */ + + HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); + + updateCallbackSpec->Finilize(); + + if (result != S_OK) + { + PrintError("Update Error"); + return 1; + } + + FOR_VECTOR (i, updateCallbackSpec->FailedFiles) + { + PrintNewLine(); + PrintError("Error for file", updateCallbackSpec->FailedFiles[i]); + } + + if (updateCallbackSpec->FailedFiles.Size() != 0) + return 1; + } + else + { + if (params.Size() != 1) + { + PrintError(kIncorrectCommand); + return 1; + } + + bool listCommand; + + if (c == 'l') + listCommand = true; + else if (c == 'x') + listCommand = false; + else + { + PrintError(kIncorrectCommand); + return 1; + } + + CMyComPtr archive; + if (f_CreateObject(&CLSID_Format, &IID_IInArchive, (void **)&archive) != S_OK) + { + PrintError("Cannot get class object"); + return 1; + } + + CInFileStream *fileSpec = new CInFileStream; + CMyComPtr file = fileSpec; + + if (!fileSpec->Open(archiveName)) + { + PrintError("Cannot open archive file", archiveName); + return 1; + } + + { + CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; + CMyComPtr openCallback(openCallbackSpec); + openCallbackSpec->PasswordIsDefined = passwordIsDefined; + openCallbackSpec->Password = password; + + const UInt64 scanSize = 1 << 23; + if (archive->Open(file, &scanSize, openCallback) != S_OK) + { + PrintError("Cannot open file as archive", archiveName); + return 1; + } + } + + if (listCommand) + { + // List command + UInt32 numItems = 0; + archive->GetNumberOfItems(&numItems); + for (UInt32 i = 0; i < numItems; i++) + { + { + // Get uncompressed size of file + NCOM::CPropVariant prop; + archive->GetProperty(i, kpidSize, &prop); + char s[64]; + ConvertPropVariantToShortString(prop, s); + Print(s); + Print(" "); + } + { + // Get name of file + NCOM::CPropVariant prop; + archive->GetProperty(i, kpidPath, &prop); + if (prop.vt == VT_BSTR) + Print(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + Print("ERROR!"); + } + PrintNewLine(); + } + } + else + { + // Extract command + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback(extractCallbackSpec); + extractCallbackSpec->Init(archive, FString()); // second parameter is output folder path + extractCallbackSpec->PasswordIsDefined = passwordIsDefined; + extractCallbackSpec->Password = password; + + /* + const wchar_t *names[] = + { + L"mt", + L"mtf" + }; + const unsigned kNumProps = sizeof(names) / sizeof(names[0]); + NCOM::CPropVariant values[kNumProps] = + { + (UInt32)1, + false + }; + CMyComPtr setProperties; + archive->QueryInterface(IID_ISetProperties, (void **)&setProperties); + if (setProperties) + { + if (setProperties->SetProperties(names, values, kNumProps) != S_OK) + { + PrintError("SetProperties() error"); + return 1; + } + } + */ + + HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback); + + if (result != S_OK) + { + PrintError("Extract Error"); + return 1; + } + } + } + + return 0; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsp --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsp 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,331 @@ +# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Client7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Client7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zcl.exe" + +!ELSEIF "$(CFG)" == "Client7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zcl.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Client7z - Win32 Release" +# Name "Client7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# End Group +# Begin Group "7zip" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Client7z.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsw --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/Client7z.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/Client7z.dsw 2002-08-13 14:27:16.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Client7z"=.\Client7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.cpp 2004-09-28 18:46:34.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile 2016-03-10 20:23:43.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile 2024-03-20 07:00:00.000000000 +0000 @@ -1,9 +1,29 @@ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb +PROG = 7zcl.exe +MY_CONSOLE = 1 + +CURRENT_OBJS = \ + $O\Client7z.obj \ + +COMMON_OBJS = \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FileStreams.obj \ + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.gcc 2024-11-29 11:00:00.000000000 +0000 @@ -0,0 +1,72 @@ +PROG = 7zcl +IS_NOT_STANDALONE = 1 + +# IS_X64 = 1 + + + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + + +ifdef IS_MINGW + +SYS_OBJS = \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + $O/TimeUtils.o \ + +endif + + +LOCAL_FLAGS = \ + + +CURRENT_OBJS = \ + $O/Client7z.o \ + +COMMON_OBJS = \ + $O/IntToString.o \ + $O/MyString.o \ + $O/MyVector.o \ + $O/NewHandler.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/DLL.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + +7ZIP_COMMON_OBJS = \ + $O/FileStreams.o \ + +C_OBJS = \ + $O/Alloc.o \ + +OBJS = \ + $(C_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(SYS_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(CURRENT_OBJS) \ + + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/Client7z$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/UI/Client7z/Client7z.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -Client7z.o : ../../../../CPP/7zip/UI/Client7z/Client7z.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Client7z/Client7z.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -DLL.o : ../../../../CPP/Windows/DLL.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/DLL.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - Threads.o \ - FileStreams.o \ - Client7z.o \ - IntToString.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - StringConvert.o \ - UTFConvert.o \ - Wildcard.o \ - DLL.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - wine_date_and_time.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Client7z/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/Client7z/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Client7z/resource.rc 2017-02-06 11:16:32.000000000 +0000 @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip client" , "7zcl") diff -Nru p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/ClientCodec.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/ClientCodec.cpp --- p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/ClientCodec.cpp 2008-08-05 09:48:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/ClientCodec.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -// Client7z.cpp - -#include "StdAfx.h" - -#ifdef _WIN32 -#include -#else -#include "Common/MyInitGuid.h" -#endif - -#include "Windows/DLL.h" -#include "../../ICoder.h" -#include "Windows/PropVariant.h" -#include "Common/MyCom.h" - -using namespace NWindows; - -class CFileIn : public ISequentialInStream, public CMyUnknownImp -{ - FILE *file_; - size_t pos_; - public: - MY_UNKNOWN_IMP - - CFileIn() : file_(0) , pos_(0) { } - ~CFileIn() { this->close(); } - - HRESULT open(const char *name) - { - file_ = fopen(name,"rb"); - if (file_) return S_OK; - return E_FAIL; - } - void close() - { - if (file_) fclose(file_); - file_ = 0; - pos_ = 0; - } - HRESULT Read(void *data, UInt32 size, UInt32 *processedSize) - { - if (file_) - { - size_t ret = fread (data, 1, size, file_); - *processedSize = ret; - pos_ += ret; - // TBD : if ret == 0, test for feof/ferror - return S_OK; - } - return E_FAIL; - } - size_t pos() { return pos_; } -}; - -class CFileOut : public ISequentialOutStream, public CMyUnknownImp -{ - FILE *file_; - size_t pos_; - public: - MY_UNKNOWN_IMP - - CFileOut() : file_(0) { } - ~CFileOut() { this->close(); } - - HRESULT open(const char *name) - { - file_ = fopen(name,"wb"); - if (file_) return S_OK; - return E_FAIL; - } - void close() - { - if (file_) fclose(file_); - file_ = 0; - } - HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize) - { - if (file_) - { - size_t ret = fwrite(data, 1, size, file_); - *processedSize = ret; - pos_ += ret; - // TBD : if ret == 0, test for feof/ferror - return S_OK; - } - return E_FAIL; - } - size_t pos() { return pos_; } -}; - -////////////////////////////////////////////////////////////////////////// -// Main function - -static const char *kHelpString = -"Usage: ClientCodec codec.so [c | d | i] [file_in file_out]\n" -"Examples:\n" -" ClientCodec LZMA.so i : info about the codec\n" -" ClientCodec LZMA.so e file_in file_out : encodes file_in to file_out\n" -" ClientCodec LZMA.so d file_in file_out : decodes file_in to file_out\n" -; - -typedef UINT32 (WINAPI * CreateObjectFunc)( - const GUID *clsID, - const GUID *interfaceID, - void **outObject); - -typedef UINT32 (WINAPI * GetNumberOfMethodsFunc)(UINT32 *numMethods); - -typedef UINT32 (WINAPI * GetMethodPropertyFunc)(UINT32 index, PROPID propID, PROPVARIANT *value); - -int main(int argc, char* argv[]) -{ - if ((argc != 3) && (argc != 5)) - { - printf(kHelpString); - return 1; - } - - if ((argc == 3) && (strcmp(argv[2],"i") != 0)) - { - printf(kHelpString); - return 1; - } - - NWindows::NDLL::CLibrary library; - if (!library.Load(argv[1])) - { - printf("Can not load library %s\n",argv[1]); - return 1; - } - CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject"); - if (createObjectFunc == 0) - { - printf("Can not get CreateObject\n"); - return 1; - } - - GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)library.GetProcAddress("GetNumberOfMethods"); - if (getNumberOfMethodsFunc == 0) - { - printf("Can not get GetNumberOfMethodsFunc\n"); - return 1; - } - - UINT32 numMethods = 0; - HRESULT res = getNumberOfMethodsFunc(&numMethods); - if (res != S_OK) - { - printf("Error in GetNumberOfMethods\n"); - return 1; - } - - GetMethodPropertyFunc getMethodPropertyFunc = (GetMethodPropertyFunc)library.GetProcAddress("GetMethodProperty"); - if (getMethodPropertyFunc == 0) - { - printf("Can not get GetMethodProperty\n"); - return 1; - } - - if (argv[2][0] == 'i') - { - printf("%s has %d method(s)\n",argv[1],(int)numMethods); - - for(UINT32 m = 0; m < numMethods ; m++) - { - printf("\tMethod %d :\n",(int)m); - NCOM::CPropVariant propVariant; - res = getMethodPropertyFunc(m,NMethodPropID::kName,&propVariant); - if (res == S_OK) - { - if (propVariant.vt == VT_BSTR) - { - printf("\t\tName : %ls\n",propVariant.bstrVal); // Unicode Name - } else { - printf("\t\tName : Error\n"); - } - } else { - printf("\t\tName : Unknown\n"); - } - res = getMethodPropertyFunc(m,NMethodPropID::kDecoder,&propVariant); - if ((res == S_OK) && (propVariant.vt == VT_BSTR)) printf("\t\tDecoder : YES\n"); - else printf("\t\tDecoder : NO\n"); - - res = getMethodPropertyFunc(m,NMethodPropID::kEncoder,&propVariant); - if ((res == S_OK) && (propVariant.vt == VT_BSTR)) printf("\t\tEncoder : YES\n"); - else printf("\t\tEncoder : NO\n"); - } - } - - int numMethod = 0; // TBD - - if (argv[2][0] == 'e') - { - NCOM::CPropVariant propVariant; - res = getMethodPropertyFunc(numMethod,NMethodPropID::kEncoder,&propVariant); - if ((res == S_OK) && (propVariant.vt == VT_BSTR)) - { - CMyComPtr outCoder; - if (createObjectFunc((const GUID *)propVariant.bstrVal, &IID_ICompressCoder, (void **)&outCoder) != S_OK) - { - printf("Can not get class object\n"); - return 1; - } - printf("Encoding : ...\n"); - - CMyComPtr inStream = new CFileIn; - res = inStream->open(argv[3]); - if (res != S_OK) - { - printf("cannot open %s\n",argv[3]); - return 1; - } - - CMyComPtr outStream = new CFileOut; - res = outStream->open(argv[4]); - if (res != S_OK) - { - printf("cannot open %s\n",argv[4]); - return 1; - } -{ - CMyComPtr setCoderProperties; - outCoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties); - if (setCoderProperties != NULL) - { - printf("IID_ICompressSetCoderProperties : Found\n"); - PROPID propID = NCoderPropID::kEndMarker; - NWindows::NCOM::CPropVariant value = true; - res = setCoderProperties->SetCoderProperties(&propID, &value, 1); - if (res = S_OK) printf("kEndMarker : ON\n"); - else printf("kEndMarker : KO KO\n"); - } - else - { - printf("IID_ICompressSetCoderProperties : NOT Found\n"); - } -} - -{ - CMyComPtr writeCoderProperties; - - outCoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties); - - if (writeCoderProperties != NULL) - { - UINT32 len = 5; // TBD - UInt32 processedSize; - outStream->Write(&len, sizeof(len), &processedSize); - - printf("IID_ICompressWriteCoderProperties : Found\n"); - size_t pos1 = outStream->pos(); - writeCoderProperties->WriteCoderProperties(outStream); - size_t pos2 = outStream->pos(); - printf("SizeOfProp : %d\n",(int)(pos2-pos1)); -/* - CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp; - CMyComPtr outStream(outStreamSpec); - outStreamSpec->Init(); - writeCoderProperties->WriteCoderProperties(outStream); - - size_t size = outStreamSpec->GetSize(); - - // encodingInfo.Properties.SetCapacity(size); - if (encodingInfo.AltCoders.Size() == 0) - encodingInfo.AltCoders.Add(CAltCoderInfo()); - CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front(); - altCoderInfo.Properties.SetCapacity(size); - - memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size); -*/ - } - else - { - printf("IID_ICompressWriteCoderProperties : NOT Found\n"); - UINT32 len = 0; - UInt32 processedSize; - outStream->Write(&len, sizeof(len), &processedSize); - } -} - - res = outCoder->Code(inStream,outStream,0,0,0); - inStream->close(); - outStream->close(); - - if (res == S_OK) - { - printf("Encoding : Done\n"); - } else { - printf("Encoding : Error\n"); - return 1; - } - } - else - { - printf("Encoder not available\n"); - return 1; - } - } - - if (argv[2][0] == 'd') - { - NCOM::CPropVariant propVariant; - res = getMethodPropertyFunc(numMethod,NMethodPropID::kDecoder,&propVariant); - if ((res == S_OK) && (propVariant.vt == VT_BSTR)) - { - CMyComPtr outCoder; - if (createObjectFunc((const GUID *)propVariant.bstrVal, &IID_ICompressCoder, (void **)&outCoder) != S_OK) - { - printf("Can not get class object\n"); - return 1; - } - printf("Decoding : ...\n"); - - CMyComPtr inStream = new CFileIn; - res = inStream->open(argv[3]); - if (res != S_OK) - { - printf("cannot open %s\n",argv[3]); - return 1; - } - - CMyComPtr outStream = new CFileOut; - res = outStream->open(argv[4]); - if (res != S_OK) - { - printf("cannot open %s\n",argv[4]); - return 1; - } -{ - UINT32 len = 0; - UInt32 processedSize; - inStream->Read(&len, sizeof(len), &processedSize); - - if (len > 0) - { - Byte props[256]; // TBD - inStream->Read(props, len, &processedSize); - - CMyComPtr setDecoderProperties; - outCoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); - if (setDecoderProperties) - { - setDecoderProperties->SetDecoderProperties2(props, len); - printf("IID_ICompressSetDecoderProperties2 : Found (%d)\n",(int)len); - } - } -} - - // FIXME UInt64 outSize = 10511; // res = outCoder->Code(inStream,outStream,0,&outSize,0); - res = outCoder->Code(inStream,outStream,0,0,0); - inStream->close(); - outStream->close(); - - if (res == S_OK) - { - printf("Decoding : Done\n"); - } else { - printf("Decoding : Error\n"); - return 1; - } - } - else - { - printf("Decoder not available\n"); - return 1; - } - } - - return 0; -} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile --- p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/makefile 2009-12-22 17:34:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -PROG=../../../../bin/ClientCodec - -LOCAL_FLAGS=-DUNICODE -D_UNICODE - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LIBS=$(LOCAL_LIBS_DLL) - -OBJS = \ -wine_date_and_time.o \ -MyWindows.o \ -ClientCodec.o \ -MyString.o \ -StringConvert.o \ -PropVariant.o \ -DLL.o - - - -.PHONY: test - -#CODER=../../../bin/Codecs/BZip2.so # OK - ICompressWriteCoderProperties : NOT Found -#CODER=../../../bin/Codecs/Copy.so # OK - ICompressWriteCoderProperties : NOT Found -#CODER=../../../bin/Codecs/Deflate.so # OK - ICompressWriteCoderProperties : NOT Found -CODER=../../../bin/Codecs/LZMA.so # OK - ICompressWriteCoderProperties=5 -#CODER=../../../bin/Codecs/PPMD.so # KO Encoder - ICompressWriteCoderProperties=5 - - -test : all - cp ClientCodec.cpp f1 - ../../../../bin/ClientCodec $(CODER) i - ../../../../bin/ClientCodec $(CODER) e f1 f2 - ../../../../bin/ClientCodec $(CODER) d f2 f3 - diff -q f1 f3 - -clean2: - rm -f f1 f2 f3 - -include ../../../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/ClientCodec/makefile.list 2009-02-09 20:06:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/ClientCodec/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -SRCS=\ -../../../myWindows/wine_date_and_time.cpp \ -../../../Common/MyWindows.cpp \ -../../../Common/MyString.cpp \ -../../../Common/StringConvert.cpp \ -../../../Windows/PropVariant.cpp \ -../../../Windows/DLL.cpp \ -./ClientCodec.cpp - -wine_date_and_time.o : ../../../myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../myWindows/wine_date_and_time.cpp -MyWindows.o : ../../../Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../Common/MyWindows.cpp -MyString.o : ../../../Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../Common/MyString.cpp -StringConvert.o : ../../../Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../Common/StringConvert.cpp -PropVariant.o : ../../../Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../Windows/PropVariant.cpp -DLL.o : ../../../Windows/DLL.cpp - $(CXX) $(CXXFLAGS) ../../../Windows/DLL.cpp -ClientCodec.o : ./ClientCodec.cpp - $(CXX) $(CXXFLAGS) ./ClientCodec.cpp - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveCommandLine.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 2016-05-18 17:49:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.cpp 2025-07-03 11:00:00.000000000 +0000 @@ -1,1370 +1,1799 @@ -// ArchiveCommandLine.cpp - -#include "StdAfx.h" -#undef printf -#undef sprintf - -#ifdef _WIN32 -#ifndef UNDER_CE -#include -#endif -#endif -#include - -#include "../../../Common/ListFileUtils.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#ifdef _WIN32 -#include "../../../Windows/FileMapping.h" -#include "../../../Windows/Synchronization.h" -#else -#include "myPrivate.h" -#endif - -#include "ArchiveCommandLine.h" -#include "EnumDirItems.h" -#include "SortUtils.h" -#include "Update.h" -#include "UpdateAction.h" - -extern bool g_CaseSensitive; - -#ifdef UNDER_CE - -#define MY_IS_TERMINAL(x) false; - -#else - -#if _MSC_VER >= 1400 -#define MY_isatty_fileno(x) _isatty(_fileno(x)) -#else -#define MY_isatty_fileno(x) isatty(fileno(x)) -#endif - -#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); - -#endif - -using namespace NCommandLineParser; -using namespace NWindows; -using namespace NFile; - -static bool StringToUInt32(const wchar_t *s, UInt32 &v) -{ - if (*s == 0) - return false; - const wchar_t *end; - v = ConvertStringToUInt32(s, &end); - return *end == 0; -} - -CArcCmdLineException::CArcCmdLineException(const char *a, const wchar_t *u) -{ - (*this) += MultiByteToUnicodeString(a); - if (u) - { - this->Add_LF(); - (*this) += u; - } -} - -int g_CodePage = -1; - -namespace NKey { -enum Enum -{ - kHelp1 = 0, - kHelp2, - kHelp3, - - kDisableHeaders, - kDisablePercents, - kShowTime, - kLogLevel, - - kOutStream, - kErrStream, - kPercentStream, - - kYes, - - kShowDialog, - kOverwrite, - - kArchiveType, - kExcludedArcType, - - kProperty, - kOutputDir, - kWorkingDir, - - kInclude, - kExclude, - kArInclude, - kArExclude, - kNoArName, - - kUpdate, - kVolume, - kRecursed, - - kAffinity, - kSfx, - kEmail, - kHash, - - kStdIn, - kStdOut, - - kLargePages, - kListfileCharSet, - kConsoleCharSet, - kTechMode, - - kUseLStat, - - kShareForWrite, - kCaseSensitive, - kArcNameMode, - - kDisableWildcardParsing, - kElimDup, - kFullPathMode, - - kHardLinks, - kSymLinks, - kNtSecurity, - kAltStreams, - kReplaceColonForAltStream, - kWriteToAltStreamIfColon, - - kDeleteAfterCompressing, - kSetArcMTime - - #ifndef _NO_CRYPTO - , kPassword - #endif -}; - -} - - -static const wchar_t kRecursedIDChar = 'r'; -static const char *kRecursedPostCharSet = "0-"; - -static const char *k_ArcNameMode_PostCharSet = "sea"; - -static const char *k_Stream_PostCharSet = "012"; - -static inline const EArcNameMode ParseArcNameMode(int postCharIndex) -{ - switch (postCharIndex) - { - case 1: return k_ArcNameMode_Exact; - case 2: return k_ArcNameMode_Add; - default: return k_ArcNameMode_Smart; - } -} - -namespace NRecursedPostCharIndex { - enum EEnum - { - kWildcardRecursionOnly = 0, - kNoRecursion = 1 - }; -} - -static const char kImmediateNameID = '!'; -static const char kMapNameID = '#'; -static const char kFileListID = '@'; - -static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be -static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be - -static const char *kOverwritePostCharSet = "asut"; - -static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = -{ - NExtract::NOverwriteMode::kOverwrite, - NExtract::NOverwriteMode::kSkip, - NExtract::NOverwriteMode::kRename, - NExtract::NOverwriteMode::kRenameExisting -}; - -static const CSwitchForm kSwitchForms[] = -{ - { "?" }, - { "h" }, - { "-help" }, - - { "ba" }, - { "bd" }, - { "bt" }, - { "bb", NSwitchType::kString, false, 0 }, - - { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, - { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, - { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, - - { "y" }, - - { "ad" }, - { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet}, - - { "t", NSwitchType::kString, false, 1 }, - { "stx", NSwitchType::kString, true, 1 }, - - { "m", NSwitchType::kString, true, 1 }, - { "o", NSwitchType::kString, false, 1 }, - { "w", NSwitchType::kString }, - - { "i", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "x", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ai", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "ax", NSwitchType::kString, true, kSomeCludePostStringMinSize}, - { "an" }, - - { "u", NSwitchType::kString, true, 1}, - { "v", NSwitchType::kString, true, 1}, - { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet }, - - { "stm", NSwitchType::kString }, - { "sfx", NSwitchType::kString }, - { "seml", NSwitchType::kString, false, 0}, - { "scrc", NSwitchType::kString, true, 0 }, - - { "si", NSwitchType::kString }, - { "so" }, - - { "slp", NSwitchType::kMinus }, - { "scs", NSwitchType::kString }, - { "scc", NSwitchType::kString }, - { "slt" }, - - { "l" }, - - { "ssw" }, - { "ssc", NSwitchType::kMinus }, - { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet }, - - { "spd" }, - { "spe", NSwitchType::kMinus }, - { "spf", NSwitchType::kString, false, 0 }, - - { "snh", NSwitchType::kMinus }, - { "snl", NSwitchType::kMinus }, - { "sni" }, - { "sns", NSwitchType::kMinus }, - { "snr" }, - { "snc" }, - - { "sdel" }, - { "stl" } - - #ifndef _NO_CRYPTO - , { "p", NSwitchType::kString } - #endif -}; - -static const wchar_t *kUniversalWildcard = L"*"; -static const unsigned kMinNonSwitchWords = 1; -static const unsigned kCommandIndex = 0; - -// static const char *kUserErrorMessage = "Incorrect command line"; -static const char *kCannotFindListFile = "Cannot find listfile"; -static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; -static const char *kTerminalOutError = "I won't write compressed data to a terminal"; -static const char *kSameTerminalError = "I won't write data and program's messages to same stream"; -static const char *kEmptyFilePath = "Empty file path"; -static const char *kCannotFindArchive = "Cannot find archive"; - -bool CArcCommand::IsFromExtractGroup() const -{ - switch (CommandType) - { - case NCommandType::kTest: - case NCommandType::kExtract: - case NCommandType::kExtractFull: - return true; - } - return false; -} - -NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const -{ - switch (CommandType) - { - case NCommandType::kTest: - case NCommandType::kExtractFull: - return NExtract::NPathMode::kFullPaths; - } - return NExtract::NPathMode::kNoPaths; -} - -bool CArcCommand::IsFromUpdateGroup() const -{ - switch (CommandType) - { - case NCommandType::kAdd: - case NCommandType::kUpdate: - case NCommandType::kDelete: - case NCommandType::kRename: - return true; - } - return false; -} - -static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) -{ - switch (index) - { - case NRecursedPostCharIndex::kWildcardRecursionOnly: - return NRecursedType::kWildcardOnlyRecursed; - case NRecursedPostCharIndex::kNoRecursion: - return NRecursedType::kNonRecursed; - default: - return NRecursedType::kRecursed; - } -} - -static const char *g_Commands = "audtexlbih"; - -static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command) -{ - UString s = commandString; - s.MakeLower_Ascii(); - if (s.Len() == 1) - { - if (s[0] > 0x7F) - return false; - int index = FindCharPosInString(g_Commands, (char)s[0]); - if (index < 0) - return false; - command.CommandType = (NCommandType::EEnum)index; - return true; - } - if (s.Len() == 2 && s[0] == 'r' && s[1] == 'n') - { - command.CommandType = (NCommandType::kRename); - return true; - } - return false; -} - -// ------------------------------------------------------------------ -// filenames functions - -static void AddNameToCensor(NWildcard::CCensor &censor, - const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching) -{ - bool recursed = false; - - switch (type) - { - case NRecursedType::kWildcardOnlyRecursed: - recursed = DoesNameContainWildcard(name); - break; - case NRecursedType::kRecursed: - recursed = true; - break; - } - censor.AddPreItem(include, name, recursed, wildcardMatching); -} - -static void AddRenamePair(CObjectVector *renamePairs, - const UString &oldName, const UString &newName, NRecursedType::EEnum type, - bool wildcardMatching) -{ - CRenamePair &pair = renamePairs->AddNew(); - pair.OldName = oldName; - pair.NewName = newName; - pair.RecursedType = type; - pair.WildcardParsing = wildcardMatching; - - if (!pair.Prepare()) - { - UString val; - val += pair.OldName; - val.Add_LF(); - val += pair.NewName; - val.Add_LF(); - if (type == NRecursedType::kRecursed) - val.AddAscii("-r"); - else if (type == NRecursedType::kRecursed) - val.AddAscii("-r0"); - throw CArcCmdLineException("Unsupported rename command:", val); - } -} - -static void AddToCensorFromListFile( - CObjectVector *renamePairs, - NWildcard::CCensor &censor, - LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, Int32 codePage) -{ - UStringVector names; - if (!NFind::DoesFileExist(us2fs(fileName))) - throw CArcCmdLineException(kCannotFindListFile, fileName); - if (!ReadNamesFromListFile(us2fs(fileName), names, codePage)) - throw CArcCmdLineException(kIncorrectListFile, fileName); - if (renamePairs) - { - if ((names.Size() & 1) != 0) - throw CArcCmdLineException(kIncorrectListFile, fileName); - for (unsigned i = 0; i < names.Size(); i += 2) - { - // change type !!!! - AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching); - } - } - else - FOR_VECTOR (i, names) - AddNameToCensor(censor, names[i], include, type, wildcardMatching); -} - -static void AddToCensorFromNonSwitchesStrings( - CObjectVector *renamePairs, - unsigned startIndex, - NWildcard::CCensor &censor, - const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, - bool wildcardMatching, - bool thereAreSwitchIncludes, Int32 codePage) -{ - if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes) - AddNameToCensor(censor, kUniversalWildcard, true, type, - true // wildcardMatching - ); - - int oldIndex = -1; - - for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++) - { - const UString &s = nonSwitchStrings[i]; - if (s.IsEmpty()) - throw CArcCmdLineException(kEmptyFilePath); - if (s[0] == kFileListID) - AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage); - else if (renamePairs) - { - if (oldIndex == -1) - oldIndex = i; - else - { - // NRecursedType::EEnum type is used for global wildcard (-i! switches) - AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching); - // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type); - oldIndex = -1; - } - } - else - AddNameToCensor(censor, s, true, type, wildcardMatching); - } - - if (oldIndex != -1) - { - throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[oldIndex]); - } -} - -#ifdef _WIN32 - -struct CEventSetEnd -{ - UString Name; - - CEventSetEnd(const wchar_t *name): Name(name) {} - ~CEventSetEnd() - { - NSynchronization::CManualResetEvent event; - if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(Name)) == 0) - event.Set(); - } -}; - -const char *k_IncorrectMapCommand = "Incorrect Map command"; - -static const char *ParseMapWithPaths( - NWildcard::CCensor &censor, - const UString &s2, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching) -{ - UString s = s2; - int pos = s.Find(L':'); - if (pos < 0) - return k_IncorrectMapCommand; - int pos2 = s.Find(L':', pos + 1); - if (pos2 < 0) - return k_IncorrectMapCommand; - - CEventSetEnd eventSetEnd((const wchar_t *)s + ((unsigned)pos2 + 1)); - s.DeleteFrom(pos2); - UInt32 size; - if (!StringToUInt32(s.Ptr(pos + 1), size) - || size < sizeof(wchar_t) - || size > ((UInt32)1 << 31) - || size % sizeof(wchar_t) != 0) - return "Unsupported Map data size"; - - s.DeleteFrom(pos); - CFileMapping map; - if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0) - return "Can not open mapping"; - LPVOID data = map.Map(FILE_MAP_READ, 0, size); - if (!data) - return "MapViewOfFile error"; - CFileUnmapper unmapper(data); - - UString name; - const wchar_t *p = (const wchar_t *)data; - if (*p != 0) // data format marker - return "Unsupported Map data"; - UInt32 numChars = size / sizeof(wchar_t); - for (UInt32 i = 1; i < numChars; i++) - { - wchar_t c = p[i]; - if (c == 0) - { - // MessageBoxW(0, name, L"7-Zip", 0); - AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching); - name.Empty(); - } - else - name += c; - } - if (!name.IsEmpty()) - return "Map data error"; - - return NULL; -} - -#endif - -static void AddSwitchWildcardsToCensor( - NWildcard::CCensor &censor, - const UStringVector &strings, bool include, - NRecursedType::EEnum commonRecursedType, - bool wildcardMatching, - Int32 codePage) -{ - const char *errorMessage = NULL; - unsigned i; - for (i = 0; i < strings.Size(); i++) - { - const UString &name = strings[i]; - NRecursedType::EEnum recursedType; - unsigned pos = 0; - - if (name.Len() < kSomeCludePostStringMinSize) - { - errorMessage = "Too short switch"; - break; - } - - if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar) - { - pos++; - wchar_t c = name[pos]; - int index = -1; - if (c <= 0x7F) - index = FindCharPosInString(kRecursedPostCharSet, (char)c); - recursedType = GetRecursedTypeFromIndex(index); - if (index >= 0) - pos++; - } - else - recursedType = commonRecursedType; - - if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize) - { - errorMessage = "Too short switch"; - break; - } - - UString tail = name.Ptr(pos + 1); - - if (name[pos] == kImmediateNameID) - AddNameToCensor(censor, tail, include, recursedType, wildcardMatching); - else if (name[pos] == kFileListID) - AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage); - #ifdef _WIN32 - else if (name[pos] == kMapNameID) - { - errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching); - if (errorMessage) - break; - } - #endif - else - { - errorMessage = "Incorrect wildcard type marker"; - break; - } - } - if (i != strings.Size()) - throw CArcCmdLineException(errorMessage, strings[i]); -} - -#ifdef _WIN32 - -// This code converts all short file names to long file names. - -static void ConvertToLongName(const UString &prefix, UString &name) -{ - if (name.IsEmpty() || DoesNameContainWildcard(name)) - return; - NFind::CFileInfo fi; - const FString path = us2fs(prefix + name); - #ifndef UNDER_CE - if (NFile::NName::IsDevicePath(path)) - return; - #endif - if (fi.Find(path)) - name = fs2us(fi.Name); -} - -static void ConvertToLongNames(const UString &prefix, CObjectVector &items) -{ - FOR_VECTOR (i, items) - { - NWildcard::CItem &item = items[i]; - if (item.Recursive || item.PathParts.Size() != 1) - continue; - if (prefix.IsEmpty() && item.IsDriveItem()) - continue; - ConvertToLongName(prefix, item.PathParts.Front()); - } -} - -static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) -{ - ConvertToLongNames(prefix, node.IncludeItems); - ConvertToLongNames(prefix, node.ExcludeItems); - unsigned i; - for (i = 0; i < node.SubNodes.Size(); i++) - { - UString &name = node.SubNodes[i].Name; - if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) - continue; - ConvertToLongName(prefix, name); - } - // mix folders with same name - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; - for (unsigned j = i + 1; j < node.SubNodes.Size();) - { - const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; - if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) - { - nextNode1.IncludeItems += nextNode2.IncludeItems; - nextNode1.ExcludeItems += nextNode2.ExcludeItems; - node.SubNodes.Delete(j); - } - else - j++; - } - } - for (i = 0; i < node.SubNodes.Size(); i++) - { - NWildcard::CCensorNode &nextNode = node.SubNodes[i]; - ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); - } -} - -void ConvertToLongNames(NWildcard::CCensor &censor) -{ - FOR_VECTOR (i, censor.Pairs) - { - NWildcard::CPair &pair = censor.Pairs[i]; - ConvertToLongNames(pair.Prefix, pair.Head); - } -} - -#endif - -/* -static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) -{ - switch (i) - { - case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; - case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; - case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; - case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; - } - throw 98111603; -} -*/ - -static const wchar_t *kUpdatePairStateIDSet = L"pqrxyzw"; -static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; - -static const unsigned kNumUpdatePairActions = 4; -static const char *kUpdateIgnoreItselfPostStringID = "-"; -static const wchar_t kUpdateNewArchivePostCharID = '!'; - - -static bool ParseUpdateCommandString2(const UString &command, - NUpdateArchive::CActionSet &actionSet, UString &postString) -{ - for (unsigned i = 0; i < command.Len();) - { - wchar_t c = MyCharLower_Ascii(command[i]); - int statePos = FindCharPosInString(kUpdatePairStateIDSet, c); - if (statePos < 0) - { - postString = command.Ptr(i); - return true; - } - i++; - if (i >= command.Len()) - return false; - c = command[i]; - if (c < '0' || c >= '0' + kNumUpdatePairActions) - return false; - unsigned actionPos = c - '0'; - actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos); - if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos) - return false; - i++; - } - postString.Empty(); - return true; -} - -static void ParseUpdateCommandString(CUpdateOptions &options, - const UStringVector &updatePostStrings, - const NUpdateArchive::CActionSet &defaultActionSet) -{ - const char *errorMessage = "incorrect update switch command"; - unsigned i; - for (i = 0; i < updatePostStrings.Size(); i++) - { - const UString &updateString = updatePostStrings[i]; - if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID)) - { - if (options.UpdateArchiveItself) - { - options.UpdateArchiveItself = false; - options.Commands.Delete(0); - } - } - else - { - NUpdateArchive::CActionSet actionSet = defaultActionSet; - - UString postString; - if (!ParseUpdateCommandString2(updateString, actionSet, postString)) - break; - if (postString.IsEmpty()) - { - if (options.UpdateArchiveItself) - options.Commands[0].ActionSet = actionSet; - } - else - { - if (postString[0] != kUpdateNewArchivePostCharID) - break; - CUpdateArchiveCommand uc; - UString archivePath = postString.Ptr(1); - if (archivePath.IsEmpty()) - break; - uc.UserArchivePath = archivePath; - uc.ActionSet = actionSet; - options.Commands.Add(uc); - } - } - } - if (i != updatePostStrings.Size()) - throw CArcCmdLineException(errorMessage, updatePostStrings[i]); -} - -bool ParseComplexSize(const wchar_t *s, UInt64 &result); - -static void SetAddCommandOptions( - NCommandType::EEnum commandType, - const CParser &parser, - CUpdateOptions &options) -{ - NUpdateArchive::CActionSet defaultActionSet; - switch (commandType) - { - case NCommandType::kAdd: - defaultActionSet = NUpdateArchive::k_ActionSet_Add; - break; - case NCommandType::kDelete: - defaultActionSet = NUpdateArchive::k_ActionSet_Delete; - break; - default: - defaultActionSet = NUpdateArchive::k_ActionSet_Update; - } - - options.UpdateArchiveItself = true; - - options.Commands.Clear(); - CUpdateArchiveCommand updateMainCommand; - updateMainCommand.ActionSet = defaultActionSet; - options.Commands.Add(updateMainCommand); - if (parser[NKey::kUpdate].ThereIs) - ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, - defaultActionSet); - if (parser[NKey::kWorkingDir].ThereIs) - { - const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; - if (postString.IsEmpty()) - NDir::MyGetTempPath(options.WorkingDir); - else - options.WorkingDir = us2fs(postString); - } - options.SfxMode = parser[NKey::kSfx].ThereIs; - if (options.SfxMode) - options.SfxModule = us2fs(parser[NKey::kSfx].PostStrings[0]); - - if (parser[NKey::kVolume].ThereIs) - { - const UStringVector &sv = parser[NKey::kVolume].PostStrings; - FOR_VECTOR (i, sv) - { - UInt64 size; - if (!ParseComplexSize(sv[i], size) || size == 0) - throw CArcCmdLineException("Incorrect volume size:", sv[i]); - options.VolumesSizes.Add(size); - } - } -} - -static void SetMethodOptions(const CParser &parser, CObjectVector &properties) -{ - if (parser[NKey::kProperty].ThereIs) - { - FOR_VECTOR (i, parser[NKey::kProperty].PostStrings) - { - CProperty prop; - prop.Name = parser[NKey::kProperty].PostStrings[i]; - int index = prop.Name.Find(L'='); - if (index >= 0) - { - prop.Value = prop.Name.Ptr(index + 1); - prop.Name.DeleteFrom(index); - } - properties.Add(prop); - } - } -} - -CArcCmdLineParser::CArcCmdLineParser(): parser(ARRAY_SIZE(kSwitchForms)) {} - -static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res) -{ - if (sw.ThereIs) - res = sw.PostCharIndex; -} - -void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, - CArcCmdLineOptions &options) -{ - if (!parser.ParseStrings(kSwitchForms, commandStrings)) - throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine); - - options.IsInTerminal = MY_IS_TERMINAL(stdin); - options.IsStdOutTerminal = MY_IS_TERMINAL(stdout); - options.IsStdErrTerminal = MY_IS_TERMINAL(stderr); - - options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; - - options.StdInMode = parser[NKey::kStdIn].ThereIs; - options.StdOutMode = parser[NKey::kStdOut].ThereIs; - options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; - options.TechMode = parser[NKey::kTechMode].ThereIs; - options.ShowTime = parser[NKey::kShowTime].ThereIs; - - if (parser[NKey::kDisablePercents].ThereIs - || options.StdOutMode - || !options.IsStdOutTerminal) - options.Number_for_Percents = k_OutStream_disabled; - - if (options.StdOutMode) - options.Number_for_Out = k_OutStream_disabled; - - SetStreamMode(parser[NKey::kOutStream], options.Number_for_Out); - SetStreamMode(parser[NKey::kErrStream], options.Number_for_Errors); - SetStreamMode(parser[NKey::kPercentStream], options.Number_for_Percents); - - if (parser[NKey::kLogLevel].ThereIs) - { - const UString &s = parser[NKey::kLogLevel].PostStrings[0]; - if (s.IsEmpty()) - options.LogLevel = 1; - else - { - UInt32 v; - if (!StringToUInt32(s, v)) - throw CArcCmdLineException("Unsupported switch postfix -bb", s); - options.LogLevel = (unsigned)v; - } - } - - if (parser[NKey::kCaseSensitive].ThereIs) - { - g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; - options.CaseSensitiveChange = true; - options.CaseSensitive = g_CaseSensitive; - } - - options.LargePages = false; - if (parser[NKey::kLargePages].ThereIs) - options.LargePages = !parser[NKey::kLargePages].WithMinus; - - - #ifndef UNDER_CE - - if (parser[NKey::kAffinity].ThereIs) - { - const UString &s = parser[NKey::kAffinity].PostStrings[0]; - if (!s.IsEmpty()) - { - UInt32 v = 0; - AString a; - a.SetFromWStr_if_Ascii(s); - if (!a.IsEmpty()) - { - const char *end; - v = ConvertHexStringToUInt32(a, &end); - if (*end != 0) - a.Empty(); - } - if (a.IsEmpty()) - throw CArcCmdLineException("Unsupported switch postfix -stm", s); - - #ifdef _WIN32 - SetProcessAffinityMask(GetCurrentProcess(), v); - #endif - } - } - - #endif -} - -struct CCodePagePair -{ - const char *Name; - Int32 CodePage; -}; - -static const unsigned kNumByteOnlyCodePages = 3; - -static const CCodePagePair g_CodePagePairs[] = -{ - { "utf-8", CP_UTF8 }, - { "win", CP_ACP }, - { "dos", CP_OEMCP }, - { "utf-16le", MY__CP_UTF16 }, - { "utf-16be", MY__CP_UTF16BE } -}; - -static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex, - bool byteOnlyCodePages, Int32 defaultVal) -{ - if (!parser[keyIndex].ThereIs) - return defaultVal; - - UString name = parser[keyIndex].PostStrings.Back(); - UInt32 v; - if (StringToUInt32(name, v)) - if (v < ((UInt32)1 << 16)) - return (Int32)v; - name.MakeLower_Ascii(); - unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : ARRAY_SIZE(g_CodePagePairs); - for (unsigned i = 0;; i++) - { - if (i == num) // to disable warnings from different compilers - throw CArcCmdLineException("Unsupported charset:", name); - const CCodePagePair &pair = g_CodePagePairs[i]; - if (name.IsEqualTo(pair.Name)) - return pair.CodePage; - } -} - -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode censorPathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback) -{ - FStringVector paths; - - { - CDirItems dirItems; - dirItems.Callback = callback; - { - HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); - st = dirItems.Stat; - RINOK(res); - } - - FOR_VECTOR (i, dirItems.Items) - { - const CDirItem &dirItem = dirItems.Items[i]; - if (!dirItem.IsDir()) - paths.Add(dirItems.GetPhyPath(i)); - } - } - - if (paths.Size() == 0) - throw CArcCmdLineException(kCannotFindArchive); - - UStringVector fullPaths; - - unsigned i; - - for (i = 0; i < paths.Size(); i++) - { - FString fullPath; - NFile::NDir::MyGetFullPathName(paths[i], fullPath); - fullPaths.Add(fs2us(fullPath)); - } - - CUIntVector indices; - SortFileNames(fullPaths, indices); - sortedPaths.ClearAndReserve(indices.Size()); - sortedFullPaths.ClearAndReserve(indices.Size()); - - for (i = 0; i < indices.Size(); i++) - { - unsigned index = indices[i]; - sortedPaths.AddInReserved(fs2us(paths[index])); - sortedFullPaths.AddInReserved(fullPaths[index]); - if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) - throw CArcCmdLineException("Duplicate archive path:", sortedFullPaths[i]); - } - - return S_OK; -} - -static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) -{ - bp.Def = parser[switchID].ThereIs; - if (bp.Def) - bp.Val = !parser[switchID].WithMinus; -} - -void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) -{ - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - unsigned numNonSwitchStrings = nonSwitchStrings.Size(); - if (numNonSwitchStrings < kMinNonSwitchWords) - throw CArcCmdLineException("The command must be specified"); - - if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) - throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]); - - if (parser[NKey::kHash].ThereIs) - options.HashMethods = parser[NKey::kHash].PostStrings; - - if (parser[NKey::kElimDup].ThereIs) - { - options.ExtractOptions.ElimDup.Def = true; - options.ExtractOptions.ElimDup.Val = !parser[NKey::kElimDup].WithMinus; - } - - NWildcard::ECensorPathMode censorPathMode = NWildcard::k_RelatPath; - bool fullPathMode = parser[NKey::kFullPathMode].ThereIs; - if (fullPathMode) - { - censorPathMode = NWildcard::k_AbsPath; - const UString &s = parser[NKey::kFullPathMode].PostStrings[0]; - if (!s.IsEmpty()) - { - if (s == L"2") - censorPathMode = NWildcard::k_FullPath; - else - throw CArcCmdLineException("Unsupported -spf:", s); - } - } - - NRecursedType::EEnum recursedType; - if (parser[NKey::kRecursed].ThereIs) - recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); - else - recursedType = NRecursedType::kNonRecursed; - - bool wildcardMatching = true; - if (parser[NKey::kDisableWildcardParsing].ThereIs) - wildcardMatching = false; - - g_CodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); - Int32 codePage = FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); - - bool thereAreSwitchIncludes = false; - - if (parser[NKey::kInclude].ThereIs) - { - thereAreSwitchIncludes = true; - AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage); - } - - if (parser[NKey::kExclude].ThereIs) - AddSwitchWildcardsToCensor(options.Censor, - parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage); - - unsigned curCommandIndex = kCommandIndex + 1; - bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs && - options.Command.CommandType != NCommandType::kBenchmark && - options.Command.CommandType != NCommandType::kInfo && - options.Command.CommandType != NCommandType::kHash; - - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); - bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; - bool isRename = options.Command.CommandType == NCommandType::kRename; - - if ((isExtractOrList || isRename) && options.StdInMode) - thereIsArchiveName = false; - - if (parser[NKey::kArcNameMode].ThereIs) - options.UpdateOptions.ArcNameMode = ParseArcNameMode(parser[NKey::kArcNameMode].PostCharIndex); - - if (thereIsArchiveName) - { - if (curCommandIndex >= numNonSwitchStrings) - throw CArcCmdLineException("Cannot find archive name"); - options.ArchiveName = nonSwitchStrings[curCommandIndex++]; - if (options.ArchiveName.IsEmpty()) - throw CArcCmdLineException("Archive name cannot by empty"); - #ifdef _WIN32 - // options.ArchiveName.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - } - - AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL, - curCommandIndex, options.Censor, - nonSwitchStrings, recursedType, wildcardMatching, - thereAreSwitchIncludes, codePage); - - options.YesToAll = parser[NKey::kYes].ThereIs; - -#ifdef ENV_HAVE_LSTAT - global_use_lstat = !parser[NKey::kUseLStat].ThereIs; -#endif - - #ifndef _NO_CRYPTO - options.PasswordEnabled = parser[NKey::kPassword].ThereIs; - if (options.PasswordEnabled) - options.Password = parser[NKey::kPassword].PostStrings[0]; - #endif - - options.ShowDialog = parser[NKey::kShowDialog].ThereIs; - - if (parser[NKey::kArchiveType].ThereIs) - options.ArcType = parser[NKey::kArchiveType].PostStrings[0]; - - options.ExcludedArcTypes = parser[NKey::kExcludedArcType].PostStrings; - - SetMethodOptions(parser, options.Properties); - - if (parser[NKey::kNtSecurity].ThereIs) options.NtSecurity.SetTrueTrue(); - - SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); - SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); - SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); - - if (isExtractOrList) - { - CExtractOptionsBase &eo = options.ExtractOptions; - - { - CExtractNtOptions &nt = eo.NtOptions; - nt.NtSecurity = options.NtSecurity; - - nt.AltStreams = options.AltStreams; - if (!options.AltStreams.Def) - nt.AltStreams.Val = true; - - nt.HardLinks = options.HardLinks; - if (!options.HardLinks.Def) - nt.HardLinks.Val = true; - - nt.SymLinks = options.SymLinks; - if (!options.SymLinks.Def) - nt.SymLinks.Val = true; - - nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; - nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; - } - - options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); - options.Censor.ExtendExclude(); - - // are there paths that look as non-relative (!Prefix.IsEmpty()) - if (!options.Censor.AllAreRelative()) - throw CArcCmdLineException("Cannot use absolute pathnames for this command"); - - NWildcard::CCensor &arcCensor = options.arcCensor; - - if (parser[NKey::kArInclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage); - if (parser[NKey::kArExclude].ThereIs) - AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage); - - if (thereIsArchiveName) - AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching); - - arcCensor.AddPathsToCensor(NWildcard::k_RelatPath); - - #ifdef _WIN32 - ConvertToLongNames(arcCensor); - #endif - - arcCensor.ExtendExclude(); - - if (options.StdInMode) - options.ArcName_for_StdInMode = parser[NKey::kStdIn].PostStrings.Front(); - - if (isExtractGroupCommand) - { - if (options.StdOutMode) - { - if ( - options.Number_for_Percents == k_OutStream_stdout - // || options.Number_for_Out == k_OutStream_stdout - // || options.Number_for_Errors == k_OutStream_stdout - || - ( - (options.IsStdOutTerminal && options.IsStdErrTerminal) - && - ( - options.Number_for_Percents != k_OutStream_disabled - // || options.Number_for_Out != k_OutStream_disabled - // || options.Number_for_Errors != k_OutStream_disabled - ) - ) - ) - throw CArcCmdLineException(kSameTerminalError); - } - - if (parser[NKey::kOutputDir].ThereIs) - { - eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); - NFile::NName::NormalizeDirPathPrefix(eo.OutputDir); - } - - eo.OverwriteMode = NExtract::NOverwriteMode::kAsk; - if (parser[NKey::kOverwrite].ThereIs) - { - eo.OverwriteMode = k_OverwriteModes[(unsigned)parser[NKey::kOverwrite].PostCharIndex]; - eo.OverwriteMode_Force = true; - } - else if (options.YesToAll) - { - eo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite; - eo.OverwriteMode_Force = true; - } - } - - eo.PathMode = options.Command.GetPathMode(); - if (censorPathMode == NWildcard::k_AbsPath) - { - eo.PathMode = NExtract::NPathMode::kAbsPaths; - eo.PathMode_Force = true; - } - else if (censorPathMode == NWildcard::k_FullPath) - { - eo.PathMode = NExtract::NPathMode::kFullPaths; - eo.PathMode_Force = true; - } - } - else if (options.Command.IsFromUpdateGroup()) - { - if (parser[NKey::kArInclude].ThereIs) - throw CArcCmdLineException("-ai switch is not supported for this command"); - - CUpdateOptions &updateOptions = options.UpdateOptions; - - SetAddCommandOptions(options.Command.CommandType, parser, updateOptions); - - updateOptions.MethodMode.Properties = options.Properties; - - if (parser[NKey::kShareForWrite].ThereIs) - updateOptions.OpenShareForWrite = true; - - updateOptions.PathMode = censorPathMode; - - updateOptions.AltStreams = options.AltStreams; - updateOptions.NtSecurity = options.NtSecurity; - updateOptions.HardLinks = options.HardLinks; - updateOptions.SymLinks = options.SymLinks; - - updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; - if (updateOptions.EMailMode) - { - updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front(); - if (updateOptions.EMailAddress.Len() > 0) - if (updateOptions.EMailAddress[0] == L'.') - { - updateOptions.EMailRemoveAfter = true; - updateOptions.EMailAddress.Delete(0); - } - } - - updateOptions.StdOutMode = options.StdOutMode; - updateOptions.StdInMode = options.StdInMode; - - updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs; - updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs; - - if (updateOptions.StdOutMode && updateOptions.EMailMode) - throw CArcCmdLineException("stdout mode and email mode cannot be combined"); - - if (updateOptions.StdOutMode) - { - if (options.IsStdOutTerminal) - throw CArcCmdLineException(kTerminalOutError); - - if (options.Number_for_Percents == k_OutStream_stdout - || options.Number_for_Out == k_OutStream_stdout - || options.Number_for_Errors == k_OutStream_stdout) - throw CArcCmdLineException(kSameTerminalError); - } - - if (updateOptions.StdInMode) - updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); - - if (options.Command.CommandType == NCommandType::kRename) - if (updateOptions.Commands.Size() != 1) - throw CArcCmdLineException("Only one archive can be created with rename command"); - } - else if (options.Command.CommandType == NCommandType::kBenchmark) - { - options.NumIterations = 1; - if (curCommandIndex < numNonSwitchStrings) - { - if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) - throw CArcCmdLineException("Incorrect Number of benmchmark iterations", nonSwitchStrings[curCommandIndex]); - curCommandIndex++; - } - } - else if (options.Command.CommandType == NCommandType::kHash) - { - options.Censor.AddPathsToCensor(censorPathMode); - options.Censor.ExtendExclude(); - - CHashOptions &hashOptions = options.HashOptions; - hashOptions.PathMode = censorPathMode; - hashOptions.Methods = options.HashMethods; - if (parser[NKey::kShareForWrite].ThereIs) - hashOptions.OpenShareForWrite = true; - hashOptions.StdInMode = options.StdInMode; - hashOptions.AltStreamsMode = options.AltStreams.Val; - } - else if (options.Command.CommandType == NCommandType::kInfo) - { - } - else - throw 20150919; -} +// ArchiveCommandLine.cpp + +#include "StdAfx.h" +#undef printf +#undef sprintf + +#ifdef _WIN32 +#ifndef UNDER_CE +#include +#endif +#else +// for isatty() +#include +#endif + +#include + +#ifdef Z7_LARGE_PAGES +#include "../../../../C/Alloc.h" +#endif + +#include "../../../Common/IntToString.h" +#include "../../../Common/ListFileUtils.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/System.h" +#ifdef _WIN32 +#include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" +#include "../../../Windows/Synchronization.h" +#endif + +#include "ArchiveCommandLine.h" +#include "EnumDirItems.h" +#include "Update.h" +#include "UpdateAction.h" + +extern bool g_CaseSensitive; +extern bool g_PathTrailReplaceMode; + +#ifdef Z7_LARGE_PAGES +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; +#endif + +/* +#ifdef ENV_HAVE_LSTAT +EXTERN_C_BEGIN +extern int global_use_lstat; +EXTERN_C_END +#endif +*/ + +#ifdef UNDER_CE + +#define MY_IS_TERMINAL(x) false; + +#else + +static bool MY_IS_TERMINAL(FILE *x) +{ +#ifdef _WIN32 + /* +crt/stdio.h: +typedef struct _iobuf FILE; +#define stdin (&_iob[0]) +#define stdout (&_iob[1]) +#define stderr (&_iob[2]) +*/ + // fprintf(stderr, "\nMY_IS_TERMINAL = %p", x); + const int fd = _fileno(x); + /* (fd) is 0, 1 or 2 in console program. + docs: If stdout or stderr is not associated with + an output stream (for example, in a Windows application + without a console window), the file descriptor returned is -2. + In previous versions, the file descriptor returned was -1. + */ + if (fd < 0) // is not associated with an output stream application (without a console window) + return false; + // fprintf(stderr, "\n\nstderr _fileno(%p) = %d", x, fd); + if (!_isatty(fd)) + return false; + // fprintf(stderr, "\nisatty_val = true"); + const HANDLE h = (HANDLE)_get_osfhandle(fd); + /* _get_osfhandle() returns intptr_t in new SDK, or long in MSVC6. + Also it can return (INVALID_HANDLE_VALUE). + docs: _get_osfhandle also returns the special value -2 when + the file descriptor is not associated with a stream + in old msvcrt.dll: it returns (-1) for incorrect value + */ + // fprintf(stderr, "\n_get_osfhandle() = %p", (void *)h); + if (h == NULL || h == INVALID_HANDLE_VALUE) + return false; + DWORD st; + // fprintf(stderr, "\nGetConsoleMode() = %u", (unsigned)GetConsoleMode(h, &st)); + return GetConsoleMode(h, &st) != 0; +#else + return isatty(fileno(x)) != 0; +#endif +} + +#endif + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NFile; + +static bool StringToUInt32(const wchar_t *s, UInt32 &v) +{ + if (*s == 0) + return false; + const wchar_t *end; + v = ConvertStringToUInt32(s, &end); + return *end == 0; +} + + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kHelp3, + + kDisableHeaders, + kDisablePercents, + kShowTime, + kLogLevel, + + kOutStream, + kErrStream, + kPercentStream, + + kYes, + + kShowDialog, + kOverwrite, + + kArchiveType, + kExcludedArcType, + + kProperty, + kOutputDir, + kWorkingDir, + + kInclude, + kExclude, + kArInclude, + kArExclude, + kNoArName, + + kUpdate, + kVolume, + kRecursed, + + kAffinity, + kSfx, + kEmail, + kHash, + // kHashGenFile, + kHashDir, + kExtractMemLimit, + + kStdIn, + kStdOut, + + kLargePages, + kListfileCharSet, + kConsoleCharSet, + kTechMode, + kListFields, + kListPathSlash, + kListTimestampUTC, + + kPreserveATime, + kShareForWrite, + kStopAfterOpenError, + kCaseSensitive, + kArcNameMode, + + kUseSlashMark, + kDisableWildcardParsing, + kElimDup, + kFullPathMode, + + kHardLinks, + kSymLinks_AllowDangerous, + kSymLinks, + kNtSecurity, + + kStoreOwnerId, + kStoreOwnerName, + + kZoneFile, + kAltStreams, + kReplaceColonForAltStream, + kWriteToAltStreamIfColon, + + kNameTrailReplace, + + kDeleteAfterCompressing, + kSetArcMTime + + #ifndef Z7_NO_CRYPTO + , kPassword + #endif +}; + +} + + +static const wchar_t kRecursedIDChar = 'r'; +static const char * const kRecursedPostCharSet = "0-"; + +static const char * const k_ArcNameMode_PostCharSet = "sea"; + +static const char * const k_Stream_PostCharSet = "012"; + +static inline EArcNameMode ParseArcNameMode(int postCharIndex) +{ + switch (postCharIndex) + { + case 1: return k_ArcNameMode_Exact; + case 2: return k_ArcNameMode_Add; + default: return k_ArcNameMode_Smart; + } +} + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildcardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +// static const char +#define kImmediateNameID '!' +#ifdef _WIN32 +#define kMapNameID '#' +#endif +#define kFileListID '@' + +static const Byte kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be +static const Byte kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be + +static const char * const kOverwritePostCharSet = "asut"; + +static const NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = +{ + NExtract::NOverwriteMode::kOverwrite, + NExtract::NOverwriteMode::kSkip, + NExtract::NOverwriteMode::kRename, + NExtract::NOverwriteMode::kRenameExisting +}; + + + +#define SWFRM_3(t, mu, mi) t, mu, mi, NULL + +#define SWFRM_1(t) SWFRM_3(t, false, 0) +#define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple) +#define SWFRM_MINUS SWFRM_1(NSwitchType::kMinus) +#define SWFRM_STRING SWFRM_1(NSwitchType::kString) + +#define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi) +#define SWFRM_STRING_MULT(mi) SWFRM_3(NSwitchType::kString, true, mi) + + +static const CSwitchForm kSwitchForms[] = +{ + { "?", SWFRM_SIMPLE }, + { "h", SWFRM_SIMPLE }, + { "-help", SWFRM_SIMPLE }, + + { "ba", SWFRM_SIMPLE }, + { "bd", SWFRM_SIMPLE }, + { "bt", SWFRM_SIMPLE }, + { "bb", SWFRM_STRING_SINGL(0) }, + + { "bso", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, + { "bse", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, + { "bsp", NSwitchType::kChar, false, 1, k_Stream_PostCharSet }, + + { "y", SWFRM_SIMPLE }, + + { "ad", SWFRM_SIMPLE }, + { "ao", NSwitchType::kChar, false, 1, kOverwritePostCharSet}, + + { "t", SWFRM_STRING_SINGL(1) }, + { "stx", SWFRM_STRING_MULT(1) }, + + { "m", SWFRM_STRING_MULT(1) }, + { "o", SWFRM_STRING_SINGL(1) }, + { "w", SWFRM_STRING }, + + { "i", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "x", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ai", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "ax", SWFRM_STRING_MULT(kSomeCludePostStringMinSize) }, + { "an", SWFRM_SIMPLE }, + + { "u", SWFRM_STRING_MULT(1) }, + { "v", SWFRM_STRING_MULT(1) }, + { "r", NSwitchType::kChar, false, 0, kRecursedPostCharSet }, + + { "stm", SWFRM_STRING }, + { "sfx", SWFRM_STRING }, + { "seml", SWFRM_STRING_SINGL(0) }, + { "scrc", SWFRM_STRING_MULT(0) }, + // { "scrf", SWFRM_STRING_SINGL(1) }, + { "shd", SWFRM_STRING_SINGL(1) }, + { "smemx", SWFRM_STRING }, + + { "si", SWFRM_STRING }, + { "so", SWFRM_SIMPLE }, + + { "slp", SWFRM_STRING }, + { "scs", SWFRM_STRING }, + { "scc", SWFRM_STRING }, + { "slt", SWFRM_SIMPLE }, + { "slf", SWFRM_STRING_SINGL(1) }, + { "slsl", SWFRM_MINUS }, + { "slmu", SWFRM_MINUS }, + + { "ssp", SWFRM_SIMPLE }, + { "ssw", SWFRM_SIMPLE }, + { "sse", SWFRM_SIMPLE }, + { "ssc", SWFRM_MINUS }, + { "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet }, + + { "spm", SWFRM_STRING_SINGL(0) }, + { "spd", SWFRM_SIMPLE }, + { "spe", SWFRM_MINUS }, + { "spf", SWFRM_STRING_SINGL(0) }, + + { "snh", SWFRM_MINUS }, + { "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 }, + + { "snt", SWFRM_MINUS }, + + { "sdel", SWFRM_SIMPLE }, + { "stl", SWFRM_SIMPLE } + + #ifndef Z7_NO_CRYPTO + , { "p", SWFRM_STRING } + #endif +}; + +static const char * const kUniversalWildcard = "*"; +static const unsigned kMinNonSwitchWords = 1; +static const unsigned kCommandIndex = 0; + +// static const char * const kUserErrorMessage = "Incorrect command line"; +// static const char * const kCannotFindListFile = "Cannot find listfile"; +static const char * const kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch."; +static const char * const kTerminalOutError = "I won't write compressed data to a terminal"; +static const char * const kSameTerminalError = "I won't write data and program's messages to same stream"; +static const char * const kEmptyFilePath = "Empty file path"; + +bool CArcCommand::IsFromExtractGroup() const +{ + switch ((int)CommandType) + { + case NCommandType::kTest: + case NCommandType::kExtract: + case NCommandType::kExtractFull: + return true; + default: + return false; + } +} + +NExtract::NPathMode::EEnum CArcCommand::GetPathMode() const +{ + switch ((int)CommandType) + { + case NCommandType::kTest: + case NCommandType::kExtractFull: + return NExtract::NPathMode::kFullPaths; + default: + return NExtract::NPathMode::kNoPaths; + } +} + +bool CArcCommand::IsFromUpdateGroup() const +{ + switch ((int)CommandType) + { + case NCommandType::kAdd: + case NCommandType::kUpdate: + case NCommandType::kDelete: + case NCommandType::kRename: + return true; + default: + return false; + } +} + +static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) +{ + switch (index) + { + case NRecursedPostCharIndex::kWildcardRecursionOnly: + return NRecursedType::kWildcardOnlyRecursed; + case NRecursedPostCharIndex::kNoRecursion: + return NRecursedType::kNonRecursed; + default: + return NRecursedType::kRecursed; + } +} + +static const char *g_Commands = "audtexlbih"; + +static bool ParseArchiveCommand(const UString &commandString, CArcCommand &command) +{ + UString s (commandString); + s.MakeLower_Ascii(); + if (s.Len() == 1) + { + if (s[0] > 0x7F) + return false; + int index = FindCharPosInString(g_Commands, (char)s[0]); + if (index < 0) + return false; + command.CommandType = (NCommandType::EEnum)index; + return true; + } + if (s.Len() == 2 && s[0] == 'r' && s[1] == 'n') + { + command.CommandType = (NCommandType::kRename); + return true; + } + return false; +} + +// ------------------------------------------------------------------ +// filenames functions + +struct CNameOption +{ + bool Include; + bool WildcardMatching; + Byte MarkMode; + NRecursedType::EEnum RecursedType; + + CNameOption(): + Include(true), + WildcardMatching(true), + MarkMode(NWildcard::kMark_FileOrDir), + RecursedType(NRecursedType::kNonRecursed) + {} +}; + + +static void AddNameToCensor(NWildcard::CCensor &censor, + const CNameOption &nop, const UString &name) +{ + bool recursed = false; + + switch ((int)nop.RecursedType) + { + case NRecursedType::kWildcardOnlyRecursed: + recursed = DoesNameContainWildcard(name); + break; + case NRecursedType::kRecursed: + recursed = true; + break; + default: + break; + } + + NWildcard::CCensorPathProps props; + props.Recursive = recursed; + props.WildcardMatching = nop.WildcardMatching; + props.MarkMode = nop.MarkMode; + censor.AddPreItem(nop.Include, name, props); +} + +#ifndef Z7_EXTRACT_ONLY +static void AddRenamePair(CObjectVector *renamePairs, + const UString &oldName, const UString &newName, NRecursedType::EEnum type, + bool wildcardMatching) +{ + CRenamePair &pair = renamePairs->AddNew(); + pair.OldName = oldName; + pair.NewName = newName; + pair.RecursedType = type; + pair.WildcardParsing = wildcardMatching; + + if (!pair.Prepare()) + { + UString val; + val += pair.OldName; + val.Add_LF(); + val += pair.NewName; + val.Add_LF(); + if (type == NRecursedType::kRecursed) + val += "-r"; + else if (type == NRecursedType::kWildcardOnlyRecursed) + val += "-r0"; + throw CArcCmdLineException("Unsupported rename command:", val); + } +} +#endif + +static void AddToCensorFromListFile( + CObjectVector *renamePairs, + NWildcard::CCensor &censor, + const CNameOption &nop, LPCWSTR fileName, UInt32 codePage) +{ + UStringVector names; + /* + if (!NFind::DoesFileExist_FollowLink(us2fs(fileName))) + throw CArcCmdLineException(kCannotFindListFile, fileName); + */ + DWORD lastError = 0; + if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError)) + { + if (lastError != 0) + { + UString m; + m = "The file operation error for listfile"; + m.Add_LF(); + m += NError::MyFormatMessage(lastError); + throw CArcCmdLineException(m, fileName); + } + throw CArcCmdLineException(kIncorrectListFile, fileName); + } + if (renamePairs) + { + #ifndef Z7_EXTRACT_ONLY + if ((names.Size() & 1) != 0) + throw CArcCmdLineException(kIncorrectListFile, fileName); + for (unsigned i = 0; i < names.Size(); i += 2) + { + // change type !!!! + AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching); + } + #else + throw "not implemented"; + #endif + } + else + FOR_VECTOR (i, names) + AddNameToCensor(censor, nop, names[i]); +} + +static void AddToCensorFromNonSwitchesStrings( + CObjectVector *renamePairs, + unsigned startIndex, + NWildcard::CCensor &censor, + const UStringVector &nonSwitchStrings, + int stopSwitchIndex, + const CNameOption &nop, + bool thereAreSwitchIncludes, UInt32 codePage) +{ + // another default + if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes) + { + /* for rename command: -i switch sets the mask for archive item reading. + if (thereAreSwitchIncludes), { we don't use UniversalWildcard. } + also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */ + // we use default fileds in (CNameOption) for UniversalWildcard. + CNameOption nop2; + // recursive mode is not important for UniversalWildcard (*) + // nop2.RecursedType = nop.RecursedType; // we don't need it + /* + nop2.RecursedType = NRecursedType::kNonRecursed; + nop2.Include = true; + nop2.WildcardMatching = true; + nop2.MarkMode = NWildcard::kMark_FileOrDir; + */ + AddNameToCensor(censor, nop2, UString(kUniversalWildcard)); + } + + int oldIndex = -1; + + if (stopSwitchIndex < 0) + stopSwitchIndex = (int)nonSwitchStrings.Size(); + + for (unsigned i = startIndex; i < nonSwitchStrings.Size(); i++) + { + const UString &s = nonSwitchStrings[i]; + if (s.IsEmpty()) + throw CArcCmdLineException(kEmptyFilePath); + if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID) + AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage); + else if (renamePairs) + { + #ifndef Z7_EXTRACT_ONLY + if (oldIndex == -1) + oldIndex = (int)i; + else + { + // NRecursedType::EEnum type is used for global wildcard (-i! switches) + AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching); + // AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type); + oldIndex = -1; + } + #else + throw "not implemented"; + #endif + } + else + AddNameToCensor(censor, nop, s); + } + + if (oldIndex != -1) + { + throw CArcCmdLineException("There is no second file name for rename pair:", nonSwitchStrings[(unsigned)oldIndex]); + } +} + +#ifdef _WIN32 + +struct CEventSetEnd +{ + UString Name; + + CEventSetEnd(const wchar_t *name): Name(name) {} + ~CEventSetEnd() + { + NSynchronization::CManualResetEvent event; + if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(Name)) == 0) + event.Set(); + } +}; + +static const char * const k_IncorrectMapCommand = "Incorrect Map command"; + +static const char *ParseMapWithPaths( + NWildcard::CCensor &censor, + const UString &s2, + const CNameOption &nop) +{ + UString s (s2); + const int pos = s.Find(L':'); + if (pos < 0) + return k_IncorrectMapCommand; + const int pos2 = s.Find(L':', (unsigned)(pos + 1)); + if (pos2 < 0) + return k_IncorrectMapCommand; + + CEventSetEnd eventSetEnd((const wchar_t *)s + (unsigned)(pos2 + 1)); + s.DeleteFrom((unsigned)pos2); + UInt32 size; + if (!StringToUInt32(s.Ptr((unsigned)(pos + 1)), size) + || size < sizeof(wchar_t) + || size > ((UInt32)1 << 31) + || size % sizeof(wchar_t) != 0) + return "Unsupported Map data size"; + + s.DeleteFrom((unsigned)pos); + CFileMapping map; + if (map.Open(FILE_MAP_READ, GetSystemString(s)) != 0) + return "Cannot open mapping"; + const LPVOID data = map.Map(FILE_MAP_READ, 0, size); + if (!data) + return "MapViewOfFile error"; + CFileUnmapper unmapper(data); + + UString name; + const wchar_t *p = (const wchar_t *)data; + if (*p != 0) // data format marker + return "Unsupported Map data"; + const UInt32 numChars = size / sizeof(wchar_t); + for (UInt32 i = 1; i < numChars; i++) + { + const wchar_t c = p[i]; + if (c == 0) + { + // MessageBoxW(0, name, L"7-Zip", 0); + AddNameToCensor(censor, nop, name); + name.Empty(); + } + else + name += c; + } + if (!name.IsEmpty()) + return "Map data error"; + + return NULL; +} + +#endif + +static void AddSwitchWildcardsToCensor( + NWildcard::CCensor &censor, + const UStringVector &strings, + const CNameOption &nop, + UInt32 codePage) +{ + const char *errorMessage = NULL; + unsigned i; + for (i = 0; i < strings.Size(); i++) + { + const UString &name = strings[i]; + unsigned pos = 0; + + if (name.Len() < kSomeCludePostStringMinSize) + { + errorMessage = "Too short switch"; + break; + } + + if (!nop.Include) + { + if (name.IsEqualTo_Ascii_NoCase("td")) + { + censor.ExcludeDirItems = true; + continue; + } + if (name.IsEqualTo_Ascii_NoCase("tf")) + { + censor.ExcludeFileItems = true; + continue; + } + } + + CNameOption nop2 = nop; + + bool type_WasUsed = false; + bool recursed_WasUsed = false; + bool matching_WasUsed = false; + bool error = false; + + for (;;) + { + wchar_t c = ::MyCharLower_Ascii(name[pos]); + if (c == kRecursedIDChar) + { + if (recursed_WasUsed) + { + error = true; + break; + } + recursed_WasUsed = true; + pos++; + c = name[pos]; + int index = -1; + if (c <= 0x7F) + index = FindCharPosInString(kRecursedPostCharSet, (char)c); + nop2.RecursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + { + pos++; + continue; + } + } + + if (c == 'w') + { + if (matching_WasUsed) + { + error = true; + break; + } + matching_WasUsed = true; + nop2.WildcardMatching = true; + pos++; + if (name[pos] == '-') + { + nop2.WildcardMatching = false; + pos++; + } + } + else if (c == 'm') + { + if (type_WasUsed) + { + error = true; + break; + } + type_WasUsed = true; + pos++; + nop2.MarkMode = NWildcard::kMark_StrictFile; + c = name[pos]; + if (c == '-') + { + nop2.MarkMode = NWildcard::kMark_FileOrDir; + pos++; + } + else if (c == '2') + { + nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + pos++; + } + } + else + break; + } + + if (error) + { + errorMessage = "inorrect switch"; + break; + } + + if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize) + { + errorMessage = "Too short switch"; + break; + } + + const UString tail = name.Ptr(pos + 1); + + const wchar_t c = name[pos]; + + if (c == kImmediateNameID) + AddNameToCensor(censor, nop2, tail); + else if (c == kFileListID) + AddToCensorFromListFile(NULL, censor, nop2, tail, codePage); + #ifdef _WIN32 + else if (c == kMapNameID) + { + errorMessage = ParseMapWithPaths(censor, tail, nop2); + if (errorMessage) + break; + } + #endif + else + { + errorMessage = "Incorrect wildcard type marker"; + break; + } + } + + if (i != strings.Size()) + throw CArcCmdLineException(errorMessage, strings[i]); +} + +/* +static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) +{ + switch (i) + { + case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; + case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; + case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; + case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; + } + throw 98111603; +} +*/ + +static const char * const kUpdatePairStateIDSet = "pqrxyzw"; +static const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; + +static const unsigned kNumUpdatePairActions = 4; +static const char * const kUpdateIgnoreItselfPostStringID = "-"; +static const wchar_t kUpdateNewArchivePostCharID = '!'; + + +static bool ParseUpdateCommandString2(const UString &command, + NUpdateArchive::CActionSet &actionSet, UString &postString) +{ + for (unsigned i = 0; i < command.Len();) + { + wchar_t c = MyCharLower_Ascii(command[i]); + int statePos = FindCharPosInString(kUpdatePairStateIDSet, (char)c); + if (c > 0x7F || statePos < 0) + { + postString = command.Ptr(i); + return true; + } + i++; + if (i >= command.Len()) + return false; + c = command[i]; + if (c < '0' || c >= (wchar_t)('0' + kNumUpdatePairActions)) + return false; + unsigned actionPos = (unsigned)(c - '0'); + actionSet.StateActions[(unsigned)statePos] = (NUpdateArchive::NPairAction::EEnum)(actionPos); + if (kUpdatePairStateNotSupportedActions[(unsigned)statePos] == (int)actionPos) + return false; + i++; + } + postString.Empty(); + return true; +} + +static void ParseUpdateCommandString(CUpdateOptions &options, + const UStringVector &updatePostStrings, + const NUpdateArchive::CActionSet &defaultActionSet) +{ + const char *errorMessage = "incorrect update switch command"; + unsigned i; + for (i = 0; i < updatePostStrings.Size(); i++) + { + const UString &updateString = updatePostStrings[i]; + if (updateString.IsEqualTo(kUpdateIgnoreItselfPostStringID)) + { + if (options.UpdateArchiveItself) + { + options.UpdateArchiveItself = false; + options.Commands.Delete(0); + } + } + else + { + NUpdateArchive::CActionSet actionSet = defaultActionSet; + + UString postString; + if (!ParseUpdateCommandString2(updateString, actionSet, postString)) + break; + if (postString.IsEmpty()) + { + if (options.UpdateArchiveItself) + options.Commands[0].ActionSet = actionSet; + } + else + { + if (postString[0] != kUpdateNewArchivePostCharID) + break; + CUpdateArchiveCommand uc; + UString archivePath = postString.Ptr(1); + if (archivePath.IsEmpty()) + break; + uc.UserArchivePath = archivePath; + uc.ActionSet = actionSet; + options.Commands.Add(uc); + } + } + } + if (i != updatePostStrings.Size()) + throw CArcCmdLineException(errorMessage, updatePostStrings[i]); +} + +bool ParseComplexSize(const wchar_t *s, UInt64 &result); + +static void SetAddCommandOptions( + NCommandType::EEnum commandType, + const CParser &parser, + CUpdateOptions &options) +{ + NUpdateArchive::CActionSet defaultActionSet; + switch ((int)commandType) + { + case NCommandType::kAdd: + defaultActionSet = NUpdateArchive::k_ActionSet_Add; + break; + case NCommandType::kDelete: + defaultActionSet = NUpdateArchive::k_ActionSet_Delete; + break; + default: + defaultActionSet = NUpdateArchive::k_ActionSet_Update; + } + + options.UpdateArchiveItself = true; + + options.Commands.Clear(); + CUpdateArchiveCommand updateMainCommand; + updateMainCommand.ActionSet = defaultActionSet; + options.Commands.Add(updateMainCommand); + if (parser[NKey::kUpdate].ThereIs) + ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, + defaultActionSet); + if (parser[NKey::kWorkingDir].ThereIs) + { + const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; + if (postString.IsEmpty()) + NDir::MyGetTempPath(options.WorkingDir); + else + options.WorkingDir = us2fs(postString); + } + options.SfxMode = parser[NKey::kSfx].ThereIs; + if (options.SfxMode) + options.SfxModule = us2fs(parser[NKey::kSfx].PostStrings[0]); + + if (parser[NKey::kVolume].ThereIs) + { + const UStringVector &sv = parser[NKey::kVolume].PostStrings; + FOR_VECTOR (i, sv) + { + UInt64 size; + if (!ParseComplexSize(sv[i], size)) + throw CArcCmdLineException("Incorrect volume size:", sv[i]); + if (i == sv.Size() - 1 && size == 0) + throw CArcCmdLineException("zero size last volume is not allowed"); + options.VolumesSizes.Add(size); + } + } +} + +static void SetMethodOptions(const CParser &parser, CObjectVector &properties) +{ + if (parser[NKey::kProperty].ThereIs) + { + FOR_VECTOR (i, parser[NKey::kProperty].PostStrings) + { + CProperty prop; + prop.Name = parser[NKey::kProperty].PostStrings[i]; + int index = prop.Name.Find(L'='); + if (index >= 0) + { + prop.Value = prop.Name.Ptr((unsigned)(index + 1)); + prop.Name.DeleteFrom((unsigned)index); + } + properties.Add(prop); + } + } +} + + +static inline void SetStreamMode(const CSwitchResult &sw, unsigned &res) +{ + if (sw.ThereIs) + res = (unsigned)sw.PostCharIndex; +} + + +#if defined(_WIN32) && !defined(UNDER_CE) +static void PrintHex(UString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} +#endif + + +void CArcCmdLineParser::Parse1(const UStringVector &commandStrings, + CArcCmdLineOptions &options) +{ + Parse1Log.Empty(); + if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings)) + throw CArcCmdLineException(parser.ErrorMessage, parser.ErrorLine); + + options.IsInTerminal = MY_IS_TERMINAL(stdin); + options.IsStdOutTerminal = MY_IS_TERMINAL(stdout); + options.IsStdErrTerminal = MY_IS_TERMINAL(stderr); + + options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; + options.YesToAll = parser[NKey::kYes].ThereIs; + + options.StdInMode = parser[NKey::kStdIn].ThereIs; + options.StdOutMode = parser[NKey::kStdOut].ThereIs; + options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + if (parser[NKey::kListFields].ThereIs) + { + const UString &s = parser[NKey::kListFields].PostStrings[0]; + options.ListFields = GetAnsiString(s); + } + if (parser[NKey::kListPathSlash].ThereIs) + { + options.ListPathSeparatorSlash.Val = !parser[NKey::kListPathSlash].WithMinus; + options.ListPathSeparatorSlash.Def = true; + } + if (parser[NKey::kListTimestampUTC].ThereIs) + g_Timestamp_Show_UTC = !parser[NKey::kListTimestampUTC].WithMinus; + options.TechMode = parser[NKey::kTechMode].ThereIs; + options.ShowTime = parser[NKey::kShowTime].ThereIs; + + if (parser[NKey::kDisablePercents].ThereIs) + options.DisablePercents = true; + + if (parser[NKey::kDisablePercents].ThereIs + || options.StdOutMode + || !options.IsStdOutTerminal) + options.Number_for_Percents = k_OutStream_disabled; + + if (options.StdOutMode) + options.Number_for_Out = k_OutStream_disabled; + + SetStreamMode(parser[NKey::kOutStream], options.Number_for_Out); + SetStreamMode(parser[NKey::kErrStream], options.Number_for_Errors); + SetStreamMode(parser[NKey::kPercentStream], options.Number_for_Percents); + + if (parser[NKey::kLogLevel].ThereIs) + { + const UString &s = parser[NKey::kLogLevel].PostStrings[0]; + if (s.IsEmpty()) + options.LogLevel = 1; + else + { + UInt32 v; + if (!StringToUInt32(s, v)) + throw CArcCmdLineException("Unsupported switch postfix -bb", s); + options.LogLevel = (unsigned)v; + } + } + + if (parser[NKey::kCaseSensitive].ThereIs) + { + options.CaseSensitive = + g_CaseSensitive = !parser[NKey::kCaseSensitive].WithMinus; + options.CaseSensitive_Change = true; + } + + + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_SymLink(); + #endif + + // options.LargePages = false; + + if (parser[NKey::kLargePages].ThereIs) + { + UInt32 slp = 0; + const UString &s = parser[NKey::kLargePages].PostStrings[0]; + if (s.IsEmpty()) + slp = 1; + else if (!s.IsEqualTo("-")) + { + if (!StringToUInt32(s, slp)) + throw CArcCmdLineException("Unsupported switch postfix for -slp", s); + } + + #ifdef Z7_LARGE_PAGES + if (slp > + #if defined(_WIN32) && !defined(UNDER_CE) + (unsigned)NSecurity::Get_LargePages_RiskLevel() + #else + 0 + #endif + ) + { + #ifdef _WIN32 // change it ! + SetLargePageSize(); + #endif + // note: this process also can inherit that Privilege from parent process + g_LargePagesMode = + #if defined(_WIN32) && !defined(UNDER_CE) + NSecurity::EnablePrivilege_LockMemory(); + #else + true; + #endif + } + #endif + } + + +#ifndef UNDER_CE + + if (parser[NKey::kAffinity].ThereIs) + { + const UString &s = parser[NKey::kAffinity].PostStrings[0]; + if (!s.IsEmpty()) + { + AString a; + a.SetFromWStr_if_Ascii(s); + Parse1Log += "Set process affinity mask: "; + + bool isError = false; + +#ifdef _WIN32 + + UInt64 v = 0; + { + const char *end; + v = ConvertHexStringToUInt64(a, &end); + if (*end != 0) + a.Empty(); + } + if (a.IsEmpty()) + isError = true; + else + { +#ifndef _WIN64 + if (v >= ((UInt64)1 << 32)) + throw CArcCmdLineException("unsupported value -stm", s); + else +#endif + { + PrintHex(Parse1Log, v); + if (!SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)v)) + { + const DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } + } + +#else // _WIN32 + + if (a.Len() != s.Len()) + isError = true; + else + { + Parse1Log += a; + NSystem::CProcessAffinity aff; + aff.CpuZero(); + unsigned cpu = 0; + unsigned i = a.Len(); + while (i) + { + unsigned v = (Byte)a[--i]; + Z7_PARSE_HEX_DIGIT(v, { isError = true; break; }) + for (unsigned mask = 1; mask != 1u << 4; mask <<= 1, cpu++) + if (v & mask) + aff.CpuSet(cpu); + } + if (!isError) + if (!aff.SetProcAffinity()) + { + const DWORD lastError = GetLastError(); + Parse1Log += " : ERROR : "; + Parse1Log += NError::MyFormatMessage(lastError); + } + } +#endif // _WIN32 + + if (isError) + throw CArcCmdLineException("Unsupported switch postfix -stm", s); + + Parse1Log.Add_LF(); + } + } + +#endif +} + + + +struct CCodePagePair +{ + const char *Name; + UInt32 CodePage; +}; + +static const unsigned kNumByteOnlyCodePages = 3; + +static const CCodePagePair g_CodePagePairs[] = +{ + { "utf-8", CP_UTF8 }, + { "win", CP_ACP }, + { "dos", CP_OEMCP }, + { "utf-16le", Z7_WIN_CP_UTF16 }, + { "utf-16be", Z7_WIN_CP_UTF16BE } +}; + +static Int32 FindCharset(const NCommandLineParser::CParser &parser, unsigned keyIndex, + bool byteOnlyCodePages, Int32 defaultVal) +{ + if (!parser[keyIndex].ThereIs) + return defaultVal; + + UString name (parser[keyIndex].PostStrings.Back()); + UInt32 v; + if (StringToUInt32(name, v)) + if (v < ((UInt32)1 << 16)) + return (Int32)v; + name.MakeLower_Ascii(); + const unsigned num = byteOnlyCodePages ? kNumByteOnlyCodePages : Z7_ARRAY_SIZE(g_CodePagePairs); + for (unsigned i = 0;; i++) + { + if (i == num) // to disable warnings from different compilers + throw CArcCmdLineException("Unsupported charset:", name); + const CCodePagePair &pair = g_CodePagePairs[i]; + if (name.IsEqualTo(pair.Name)) + return (Int32)pair.CodePage; + } +} + + +static void SetBoolPair(NCommandLineParser::CParser &parser, unsigned switchID, CBoolPair &bp) +{ + bp.Def = parser[switchID].ThereIs; + if (bp.Def) + bp.Val = !parser[switchID].WithMinus; +} + + +static bool ParseSizeString(const wchar_t *s, UInt64 &res) +{ + const wchar_t *end; + const UInt64 v = ConvertStringToUInt64(s, &end); + if (s == end) + return false; + const wchar_t c = *end; + + if (c == 0) + { + res = v; + return true; + } + if (end[1] != 0) + return false; + + unsigned numBits; + switch (MyCharLower_Ascii(c)) + { + case 'b': numBits = 0; break; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + const UInt64 val2 = v << numBits; + if ((val2 >> numBits) != v) + return false; + res = val2; + return true; +} + +void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) +{ + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + const unsigned numNonSwitchStrings = nonSwitchStrings.Size(); + if (numNonSwitchStrings < kMinNonSwitchWords) + throw CArcCmdLineException("The command must be specified"); + + if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) + throw CArcCmdLineException("Unsupported command:", nonSwitchStrings[kCommandIndex]); + + if (parser[NKey::kHash].ThereIs) + options.HashMethods = parser[NKey::kHash].PostStrings; + + /* + if (parser[NKey::kHashGenFile].ThereIs) + { + const UString &s = parser[NKey::kHashGenFile].PostStrings[0]; + for (unsigned i = 0 ; i < s.Len();) + { + const wchar_t c = s[i++]; + if (!options.HashOptions.ParseFlagCharOption(c, true)) + { + if (c != '=') + throw CArcCmdLineException("Unsupported hash mode switch:", s); + options.HashOptions.HashFilePath = s.Ptr(i); + break; + } + } + } + */ + + if (parser[NKey::kHashDir].ThereIs) + options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0]; + + if (parser[NKey::kExtractMemLimit].ThereIs) + { + const UString &s = parser[NKey::kExtractMemLimit].PostStrings[0]; + if (!ParseSizeString(s, options.ExtractOptions.NtOptions.MemLimit)) + throw CArcCmdLineException("Unsupported -smemx:", s); + } + + if (parser[NKey::kElimDup].ThereIs) + { + options.ExtractOptions.ElimDup.Def = true; + options.ExtractOptions.ElimDup.Val = !parser[NKey::kElimDup].WithMinus; + } + + NWildcard::ECensorPathMode censorPathMode = NWildcard::k_RelatPath; + bool fullPathMode = parser[NKey::kFullPathMode].ThereIs; + if (fullPathMode) + { + censorPathMode = NWildcard::k_AbsPath; + const UString &s = parser[NKey::kFullPathMode].PostStrings[0]; + if (!s.IsEmpty()) + { + if (s.IsEqualTo("2")) + censorPathMode = NWildcard::k_FullPath; + else + throw CArcCmdLineException("Unsupported -spf:", s); + } + } + + if (parser[NKey::kNameTrailReplace].ThereIs) + g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus; + + CNameOption nop; + + if (parser[NKey::kRecursed].ThereIs) + nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); + + if (parser[NKey::kDisableWildcardParsing].ThereIs) + nop.WildcardMatching = false; + + if (parser[NKey::kUseSlashMark].ThereIs) + { + const UString &s = parser[NKey::kUseSlashMark].PostStrings[0]; + if (s.IsEmpty()) + nop.MarkMode = NWildcard::kMark_StrictFile; + else if (s.IsEqualTo_Ascii_NoCase("-")) + nop.MarkMode = NWildcard::kMark_FileOrDir; + else if (s.IsEqualTo_Ascii_NoCase("2")) + nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard; + else + throw CArcCmdLineException("Unsupported -spm:", s); + } + + + options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1); + + const UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8); + + bool thereAreSwitchIncludes = false; + + if (parser[NKey::kInclude].ThereIs) + { + thereAreSwitchIncludes = true; + nop.Include = true; + AddSwitchWildcardsToCensor(options.Censor, + parser[NKey::kInclude].PostStrings, nop, codePage); + } + + if (parser[NKey::kExclude].ThereIs) + { + nop.Include = false; + AddSwitchWildcardsToCensor(options.Censor, + parser[NKey::kExclude].PostStrings, nop, codePage); + } + + unsigned curCommandIndex = kCommandIndex + 1; + bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs && + options.Command.CommandType != NCommandType::kBenchmark && + options.Command.CommandType != NCommandType::kInfo && + options.Command.CommandType != NCommandType::kHash; + + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList; + const bool isRename = options.Command.CommandType == NCommandType::kRename; + options.UpdateOptions.RenameMode = isRename; + + if ((isExtractOrList || isRename) && options.StdInMode) + thereIsArchiveName = false; + + if (parser[NKey::kArcNameMode].ThereIs) + options.UpdateOptions.ArcNameMode = ParseArcNameMode(parser[NKey::kArcNameMode].PostCharIndex); + + if (thereIsArchiveName) + { + if (curCommandIndex >= numNonSwitchStrings) + throw CArcCmdLineException("Cannot find archive name"); + options.ArchiveName = nonSwitchStrings[curCommandIndex++]; + if (options.ArchiveName.IsEmpty()) + throw CArcCmdLineException("Archive name cannot by empty"); + #ifdef _WIN32 + // options.ArchiveName.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + } + + nop.Include = true; + AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL, + curCommandIndex, options.Censor, + nonSwitchStrings, parser.StopSwitchIndex, + nop, + thereAreSwitchIncludes, codePage); + + #ifndef Z7_NO_CRYPTO + options.PasswordEnabled = parser[NKey::kPassword].ThereIs; + if (options.PasswordEnabled) + options.Password = parser[NKey::kPassword].PostStrings[0]; + #endif + + options.ShowDialog = parser[NKey::kShowDialog].ThereIs; + + if (parser[NKey::kArchiveType].ThereIs) + options.ArcType = parser[NKey::kArchiveType].PostStrings[0]; + + options.ExcludedArcTypes = parser[NKey::kExcludedArcType].PostStrings; + + SetMethodOptions(parser, options.Properties); + + if (parser[NKey::kNtSecurity].ThereIs) options.NtSecurity.SetTrueTrue(); + + SetBoolPair(parser, NKey::kAltStreams, options.AltStreams); + SetBoolPair(parser, NKey::kHardLinks, options.HardLinks); + SetBoolPair(parser, NKey::kSymLinks, options.SymLinks); + + SetBoolPair(parser, NKey::kStoreOwnerId, options.StoreOwnerId); + SetBoolPair(parser, NKey::kStoreOwnerName, options.StoreOwnerName); + + CBoolPair symLinks_AllowDangerous; + SetBoolPair(parser, NKey::kSymLinks_AllowDangerous, symLinks_AllowDangerous); + + + /* + bool supportSymLink = options.SymLinks.Val; + + if (!options.SymLinks.Def) + { + if (isExtractOrList) + supportSymLink = true; + else + supportSymLink = false; + } + + #ifdef ENV_HAVE_LSTAT + if (supportSymLink) + global_use_lstat = 1; + else + global_use_lstat = 0; + #endif + */ + + + if (isExtractOrList) + { + CExtractOptionsBase &eo = options.ExtractOptions; + + eo.ExcludeDirItems = options.Censor.ExcludeDirItems; + eo.ExcludeFileItems = options.Censor.ExcludeFileItems; + + { + CExtractNtOptions &nt = eo.NtOptions; + nt.NtSecurity = options.NtSecurity; + + nt.AltStreams = options.AltStreams; + if (!options.AltStreams.Def) + nt.AltStreams.Val = true; + + nt.HardLinks = options.HardLinks; + if (!options.HardLinks.Def) + nt.HardLinks.Val = true; + + nt.SymLinks = options.SymLinks; + if (!options.SymLinks.Def) + nt.SymLinks.Val = true; + + nt.SymLinks_AllowDangerous = symLinks_AllowDangerous; + + nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; + nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; + + nt.ExtractOwner = options.StoreOwnerId.Val; // StoreOwnerName + + if (parser[NKey::kPreserveATime].ThereIs) + nt.PreserveATime = true; + if (parser[NKey::kShareForWrite].ThereIs) + nt.OpenShareForWrite = true; + } + + if (parser[NKey::kZoneFile].ThereIs) + { + eo.ZoneMode = NExtract::NZoneIdMode::kAll; + const UString &s = parser[NKey::kZoneFile].PostStrings[0]; + if (!s.IsEmpty()) + { + if (s.IsEqualTo("0")) eo.ZoneMode = NExtract::NZoneIdMode::kNone; + else if (s.IsEqualTo("1")) eo.ZoneMode = NExtract::NZoneIdMode::kAll; + else if (s.IsEqualTo("2")) eo.ZoneMode = NExtract::NZoneIdMode::kOffice; + else + throw CArcCmdLineException("Unsupported -snz:", s); + } + } + + options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); + options.Censor.ExtendExclude(); + + // are there paths that look as non-relative (!Prefix.IsEmpty()) + if (!options.Censor.AllAreRelative()) + throw CArcCmdLineException("Cannot use absolute pathnames for this command"); + + NWildcard::CCensor &arcCensor = options.arcCensor; + + CNameOption nopArc; + // nopArc.RecursedType = NRecursedType::kNonRecursed; // default: we don't want recursing for archives, if -r specified + // is it OK, external switches can disable WildcardMatching and MarcMode for arc. + nopArc.WildcardMatching = nop.WildcardMatching; + nopArc.MarkMode = nop.MarkMode; + + if (parser[NKey::kArInclude].ThereIs) + { + nopArc.Include = true; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage); + } + if (parser[NKey::kArExclude].ThereIs) + { + nopArc.Include = false; + AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage); + } + + if (thereIsArchiveName) + { + nopArc.Include = true; + AddNameToCensor(arcCensor, nopArc, options.ArchiveName); + } + + arcCensor.AddPathsToCensor(NWildcard::k_RelatPath); + + #ifdef _WIN32 + ConvertToLongNames(arcCensor); + #endif + + arcCensor.ExtendExclude(); + + if (options.StdInMode) + options.ArcName_for_StdInMode = parser[NKey::kStdIn].PostStrings.Front(); + + if (isExtractGroupCommand) + { + if (options.StdOutMode) + { + if ( + options.Number_for_Percents == k_OutStream_stdout + // || options.Number_for_Out == k_OutStream_stdout + // || options.Number_for_Errors == k_OutStream_stdout + || + ( + (options.IsStdOutTerminal && options.IsStdErrTerminal) + && + ( + options.Number_for_Percents != k_OutStream_disabled + // || options.Number_for_Out != k_OutStream_disabled + // || options.Number_for_Errors != k_OutStream_disabled + ) + ) + ) + throw CArcCmdLineException(kSameTerminalError); + } + + if (parser[NKey::kOutputDir].ThereIs) + { + eo.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]); + #ifdef _WIN32 + NFile::NName::NormalizeDirSeparators(eo.OutputDir); + #endif + NFile::NName::NormalizeDirPathPrefix(eo.OutputDir); + } + + eo.OverwriteMode = NExtract::NOverwriteMode::kAsk; + if (parser[NKey::kOverwrite].ThereIs) + { + eo.OverwriteMode = k_OverwriteModes[(unsigned)parser[NKey::kOverwrite].PostCharIndex]; + eo.OverwriteMode_Force = true; + } + else if (options.YesToAll) + { + eo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite; + eo.OverwriteMode_Force = true; + } + } + + eo.PathMode = options.Command.GetPathMode(); + if (censorPathMode == NWildcard::k_AbsPath) + { + eo.PathMode = NExtract::NPathMode::kAbsPaths; + eo.PathMode_Force = true; + } + else if (censorPathMode == NWildcard::k_FullPath) + { + eo.PathMode = NExtract::NPathMode::kFullPaths; + eo.PathMode_Force = true; + } + } + else if (options.Command.IsFromUpdateGroup()) + { + if (parser[NKey::kArInclude].ThereIs) + throw CArcCmdLineException("-ai switch is not supported for this command"); + + CUpdateOptions &updateOptions = options.UpdateOptions; + + SetAddCommandOptions(options.Command.CommandType, parser, updateOptions); + + updateOptions.MethodMode.Properties = options.Properties; + + if (parser[NKey::kPreserveATime].ThereIs) + updateOptions.PreserveATime = true; + if (parser[NKey::kShareForWrite].ThereIs) + updateOptions.OpenShareForWrite = true; + if (parser[NKey::kStopAfterOpenError].ThereIs) + updateOptions.StopAfterOpenError = true; + + updateOptions.PathMode = censorPathMode; + + updateOptions.AltStreams = options.AltStreams; + 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) + { + updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front(); + if (updateOptions.EMailAddress.Len() > 0) + if (updateOptions.EMailAddress[0] == L'.') + { + updateOptions.EMailRemoveAfter = true; + updateOptions.EMailAddress.Delete(0); + } + } + + updateOptions.StdOutMode = options.StdOutMode; + updateOptions.StdInMode = options.StdInMode; + + updateOptions.DeleteAfterCompressing = parser[NKey::kDeleteAfterCompressing].ThereIs; + updateOptions.SetArcMTime = parser[NKey::kSetArcMTime].ThereIs; + + if (updateOptions.StdOutMode && updateOptions.EMailMode) + throw CArcCmdLineException("stdout mode and email mode cannot be combined"); + + if (updateOptions.StdOutMode) + { + if (options.IsStdOutTerminal) + throw CArcCmdLineException(kTerminalOutError); + + if (options.Number_for_Percents == k_OutStream_stdout + || options.Number_for_Out == k_OutStream_stdout + || options.Number_for_Errors == k_OutStream_stdout) + throw CArcCmdLineException(kSameTerminalError); + } + + if (updateOptions.StdInMode) + updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); + + if (options.Command.CommandType == NCommandType::kRename) + if (updateOptions.Commands.Size() != 1) + throw CArcCmdLineException("Only one archive can be created with rename command"); + } + else if (options.Command.CommandType == NCommandType::kBenchmark) + { + options.NumIterations = 1; + options.NumIterations_Defined = false; + if (curCommandIndex < numNonSwitchStrings) + { + if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) + throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]); + curCommandIndex++; + options.NumIterations_Defined = true; + } + } + else if (options.Command.CommandType == NCommandType::kHash) + { + options.Censor.AddPathsToCensor(censorPathMode); + options.Censor.ExtendExclude(); + + CHashOptions &hashOptions = options.HashOptions; + hashOptions.PathMode = censorPathMode; + hashOptions.Methods = options.HashMethods; + // hashOptions.HashFilePath = options.HashFilePath; + if (parser[NKey::kPreserveATime].ThereIs) + hashOptions.PreserveATime = true; + if (parser[NKey::kShareForWrite].ThereIs) + hashOptions.OpenShareForWrite = true; + hashOptions.StdInMode = options.StdInMode; + hashOptions.AltStreamsMode = options.AltStreams.Val; + hashOptions.SymLinks = options.SymLinks; + } + else if (options.Command.CommandType == NCommandType::kInfo) + { + } + else + throw 20150919; +} + + + +#ifndef _WIN32 + +static AString g_ModuleDirPrefix; + +void Set_ModuleDirPrefix_From_ProgArg0(const char *s); +void Set_ModuleDirPrefix_From_ProgArg0(const char *s) +{ + AString a (s); + int sep = a.ReverseFind_PathSepar(); + a.DeleteFrom((unsigned)(sep + 1)); + g_ModuleDirPrefix = a; +} + +namespace NWindows { +namespace NDLL { + +FString GetModuleDirPrefix(); +FString GetModuleDirPrefix() +{ + FString s; + + s = fas2fs(g_ModuleDirPrefix); + if (s.IsEmpty()) + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + /* + setenv("_7ZIP_HOME_DIR", "/test/", 0); + const char *home = getenv("_7ZIP_HOME_DIR"); + if (home) + s = home; + else + s = FTEXT(".") FSTRING_PATH_SEPARATOR; + return s; + */ +} + +}} + +#endif // ! _WIN32 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveCommandLine.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveCommandLine.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveCommandLine.h 2024-06-06 05:00:00.000000000 +0000 @@ -1,147 +1,170 @@ -// ArchiveCommandLine.h - -#ifndef __ARCHIVE_COMMAND_LINE_H -#define __ARCHIVE_COMMAND_LINE_H - -#include "../../../Common/CommandLineParser.h" -#include "../../../Common/Wildcard.h" - -#include "Extract.h" -#include "HashCalc.h" -#include "Update.h" - -struct CArcCmdLineException: public UString -{ - CArcCmdLineException(const char *a, const wchar_t *u = NULL); -}; - -namespace NCommandType { enum EEnum -{ - kAdd = 0, - kUpdate, - kDelete, - kTest, - kExtract, - kExtractFull, - kList, - kBenchmark, - kInfo, - kHash, - kRename -};} - -struct CArcCommand -{ - NCommandType::EEnum CommandType; - - bool IsFromExtractGroup() const; - bool IsFromUpdateGroup() const; - bool IsTestCommand() const { return CommandType == NCommandType::kTest; } - NExtract::NPathMode::EEnum GetPathMode() const; -}; - -enum -{ - k_OutStream_disabled = 0, - k_OutStream_stdout = 1, - k_OutStream_stderr = 2 -}; - -struct CArcCmdLineOptions -{ - bool HelpMode; - - bool LargePages; - bool CaseSensitiveChange; - bool CaseSensitive; - - bool IsInTerminal; - bool IsStdOutTerminal; - bool IsStdErrTerminal; - bool StdInMode; - bool StdOutMode; - bool EnableHeaders; - - bool YesToAll; - bool ShowDialog; - NWildcard::CCensor Censor; - - CArcCommand Command; - UString ArchiveName; - - #ifndef _NO_CRYPTO - bool PasswordEnabled; - UString Password; - #endif - - bool TechMode; - bool ShowTime; - - UStringVector HashMethods; - - bool AppendName; - // UStringVector ArchivePathsSorted; - // UStringVector ArchivePathsFullSorted; - NWildcard::CCensor arcCensor; - UString ArcName_for_StdInMode; - - CObjectVector Properties; - - CExtractOptionsBase ExtractOptions; - - CBoolPair NtSecurity; - CBoolPair AltStreams; - CBoolPair HardLinks; - CBoolPair SymLinks; - - CUpdateOptions UpdateOptions; - CHashOptions HashOptions; - UString ArcType; - UStringVector ExcludedArcTypes; - - unsigned Number_for_Out; - unsigned Number_for_Errors; - unsigned Number_for_Percents; - unsigned LogLevel; - - // bool IsOutAllowed() const { return Number_for_Out != k_OutStream_disabled; } - - // Benchmark - UInt32 NumIterations; - - CArcCmdLineOptions(): - LargePages(false), - CaseSensitiveChange(false), - CaseSensitive(false), - - StdInMode(false), - StdOutMode(false), - - Number_for_Out(k_OutStream_stdout), - Number_for_Errors(k_OutStream_stderr), - Number_for_Percents(k_OutStream_stdout), - - LogLevel(0) - { - }; -}; - -class CArcCmdLineParser -{ - NCommandLineParser::CParser parser; -public: - CArcCmdLineParser(); - void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options); - void Parse2(CArcCmdLineOptions &options); -}; - -HRESULT EnumerateDirItemsAndSort( - NWildcard::CCensor &censor, - NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, - UStringVector &sortedPaths, - UStringVector &sortedFullPaths, - CDirItemsStat &st, - IDirItemsCallback *callback); - -#endif +// ArchiveCommandLine.h + +#ifndef ZIP7_INC_ARCHIVE_COMMAND_LINE_H +#define ZIP7_INC_ARCHIVE_COMMAND_LINE_H + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/Wildcard.h" + +#include "EnumDirItems.h" + +#include "Extract.h" +#include "HashCalc.h" +#include "Update.h" + +typedef CMessagePathException CArcCmdLineException; + +namespace NCommandType { enum EEnum +{ + kAdd = 0, + kUpdate, + kDelete, + kTest, + kExtract, + kExtractFull, + kList, + kBenchmark, + kInfo, + kHash, + kRename +};} + +struct CArcCommand +{ + NCommandType::EEnum CommandType; + + bool IsFromExtractGroup() const; + bool IsFromUpdateGroup() const; + bool IsTestCommand() const { return CommandType == NCommandType::kTest; } + NExtract::NPathMode::EEnum GetPathMode() const; +}; + +enum +{ + k_OutStream_disabled = 0, + k_OutStream_stdout = 1, + k_OutStream_stderr = 2 +}; + +struct CArcCmdLineOptions +{ + bool HelpMode; + + // bool LargePages; + bool CaseSensitive_Change; + bool CaseSensitive; + + bool IsInTerminal; + bool IsStdOutTerminal; + bool IsStdErrTerminal; + bool StdInMode; + bool StdOutMode; + bool EnableHeaders; + bool DisablePercents; + + + bool YesToAll; + bool ShowDialog; + bool TechMode; + bool ShowTime; + CBoolPair ListPathSeparatorSlash; + + CBoolPair NtSecurity; + CBoolPair AltStreams; + CBoolPair HardLinks; + CBoolPair SymLinks; + + CBoolPair StoreOwnerId; + CBoolPair StoreOwnerName; + + AString ListFields; + + int ConsoleCodePage; + + NWildcard::CCensor Censor; + + CArcCommand Command; + UString ArchiveName; + + #ifndef Z7_NO_CRYPTO + bool PasswordEnabled; + UString Password; + #endif + + UStringVector HashMethods; + // UString HashFilePath; + + // bool AppendName; + // UStringVector ArchivePathsSorted; + // UStringVector ArchivePathsFullSorted; + NWildcard::CCensor arcCensor; + UString ArcName_for_StdInMode; + + CObjectVector Properties; + + CExtractOptionsBase ExtractOptions; + + CUpdateOptions UpdateOptions; + CHashOptions HashOptions; + UString ArcType; + UStringVector ExcludedArcTypes; + + unsigned Number_for_Out; + unsigned Number_for_Errors; + unsigned Number_for_Percents; + unsigned LogLevel; + + // bool IsOutAllowed() const { return Number_for_Out != k_OutStream_disabled; } + + // Benchmark + UInt32 NumIterations; + bool NumIterations_Defined; + + CArcCmdLineOptions(): + HelpMode(false), + // LargePages(false), + CaseSensitive_Change(false), + CaseSensitive(false), + + IsInTerminal(false), + IsStdOutTerminal(false), + IsStdErrTerminal(false), + + StdInMode(false), + StdOutMode(false), + + EnableHeaders(false), + DisablePercents(false), + + YesToAll(false), + ShowDialog(false), + TechMode(false), + ShowTime(false), + + ConsoleCodePage(-1), + + Number_for_Out(k_OutStream_stdout), + Number_for_Errors(k_OutStream_stderr), + Number_for_Percents(k_OutStream_stdout), + + LogLevel(0) + { + ListPathSeparatorSlash.Val = +#ifdef _WIN32 + false; +#else + true; +#endif + } +}; + +class CArcCmdLineParser +{ + NCommandLineParser::CParser parser; +public: + UString Parse1Log; + void Parse1(const UStringVector &commandStrings, CArcCmdLineOptions &options); + void Parse2(CArcCmdLineOptions &options); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2016-05-20 08:42:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2025-06-29 09:00:00.000000000 +0000 @@ -1,1643 +1,2827 @@ -// ArchiveExtractCallback.cpp - -#include "StdAfx.h" - -#undef sprintf -#undef printf - -#include "../../../../C/Alloc.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) -#define _USE_SECURITY_CODE -#include "../../../Windows/SecurityUtils.h" -#endif - -#include "../../Common/FilePathAutoRename.h" -// #include "../../Common/StreamUtils.h" - -#include "../Common/ExtractingFilePath.h" -#include "../Common/PropIDUtils.h" - -#include "ArchiveExtractCallback.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static const char *kCantAutoRename = "Can not create file with auto name"; -static const char *kCantRenameFile = "Can not rename existing file"; -static const char *kCantDeleteOutputFile = "Can not delete output file"; -static const char *kCantDeleteOutputDir = "Can not delete output folder"; - - -#ifndef _SFX - -STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - HRESULT result = S_OK; - if (_stream) - result = _stream->Write(data, size, &size); - if (_calculate) - _hash->Update(data, size); - _size += size; - if (processedSize) - *processedSize = size; - return result; -} - -#endif - -#ifdef _USE_SECURITY_CODE -bool InitLocalPrivileges() -{ - NSecurity::CAccessToken token; - if (!token.OpenProcessToken(GetCurrentProcess(), - TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES)) - return false; - - TOKEN_PRIVILEGES tp; - - tp.PrivilegeCount = 1; - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (!::LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid)) - return false; - if (!token.AdjustPrivileges(&tp)) - return false; - return (GetLastError() == ERROR_SUCCESS); -} -#endif - -#ifdef SUPPORT_LINKS - -int CHardLinkNode::Compare(const CHardLinkNode &a) const -{ - if (StreamId < a.StreamId) return -1; - if (StreamId > a.StreamId) return 1; - return MyCompare(INode, a.INode); -} - -static HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHardLinkNode &h, bool &defined) -{ - h.INode = 0; - h.StreamId = (UInt64)(Int64)-1; - defined = false; - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidINode, &prop)); - if (!ConvertPropVariantToUInt64(prop, h.INode)) - return S_OK; - } - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidStreamId, &prop)); - ConvertPropVariantToUInt64(prop, h.StreamId); - } - defined = true; - return S_OK; -} - - -HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector *realIndices) -{ - _hardLinks.Clear(); - - if (!_arc->Ask_INode) - return S_OK; - - IInArchive *archive = _arc->Archive; - CRecordVector &hardIDs = _hardLinks.IDs; - - { - UInt32 numItems; - if (realIndices) - numItems = realIndices->Size(); - else - { - RINOK(archive->GetNumberOfItems(&numItems)); - } - - for (UInt32 i = 0; i < numItems; i++) - { - CHardLinkNode h; - bool defined; - UInt32 realIndex = realIndices ? (*realIndices)[i] : i; - - RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)); - if (defined) - { - bool isAltStream = false; - RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)); - if (!isAltStream) - hardIDs.Add(h); - } - } - } - - hardIDs.Sort2(); - - { - // wee keep only items that have 2 or more items - unsigned k = 0; - unsigned numSame = 1; - for (unsigned i = 1; i < hardIDs.Size(); i++) - { - if (hardIDs[i].Compare(hardIDs[i - 1]) != 0) - numSame = 1; - else if (++numSame == 2) - { - if (i - 1 != k) - hardIDs[k] = hardIDs[i - 1]; - k++; - } - } - hardIDs.DeleteFrom(k); - } - - _hardLinks.PrepareLinks(); - return S_OK; -} - -#endif - -CArchiveExtractCallback::CArchiveExtractCallback(): - WriteCTime(true), - WriteATime(true), - WriteMTime(true), - _multiArchives(false) -{ - LocalProgressSpec = new CLocalProgress(); - _localProgress = LocalProgressSpec; - - #ifdef _USE_SECURITY_CODE - _saclEnabled = InitLocalPrivileges(); - #endif -} - -void CArchiveExtractCallback::Init( - const CExtractNtOptions &ntOptions, - const NWildcard::CCensorNode *wildcardCensor, - const CArc *arc, - IFolderArchiveExtractCallback *extractCallback2, - bool stdOutMode, bool testMode, - const FString &directoryPath, - const UStringVector &removePathParts, bool removePartsForAltStreams, - UInt64 packSize) -{ - _extractedFolderPaths.Clear(); - _extractedFolderIndices.Clear(); - - #ifdef SUPPORT_LINKS - _hardLinks.Clear(); - #endif - - #ifdef SUPPORT_ALT_STREAMS - _renamedFiles.Clear(); - #endif - - _ntOptions = ntOptions; - _wildcardCensor = wildcardCensor; - - _stdOutMode = stdOutMode; - _testMode = testMode; - - // _progressTotal = 0; - // _progressTotal_Defined = false; - - _packTotal = packSize; - _progressTotal = packSize; - _progressTotal_Defined = true; - - _extractCallback2 = extractCallback2; - _compressProgress.Release(); - _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); - _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage, &_callbackMessage); - _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); - - #ifndef _SFX - - _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); - if (ExtractToStreamCallback) - { - Int32 useStreams = 0; - if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK) - useStreams = 0; - if (useStreams == 0) - ExtractToStreamCallback.Release(); - } - - #endif - - LocalProgressSpec->Init(extractCallback2, true); - LocalProgressSpec->SendProgress = false; - - _removePathParts = removePathParts; - _removePartsForAltStreams = removePartsForAltStreams; - - #ifndef _SFX - _baseParentFolder = (UInt32)(Int32)-1; - _use_baseParentFolder_mode = false; - #endif - - _arc = arc; - _dirPathPrefix = directoryPath; - _dirPathPrefix_Full = directoryPath; - #if defined(_WIN32) && !defined(UNDER_CE) - if (!NName::IsAltPathPrefix(_dirPathPrefix)) - #endif - { - NName::NormalizeDirPathPrefix(_dirPathPrefix); - NDir::MyGetFullPathName(directoryPath, _dirPathPrefix_Full); - NName::NormalizeDirPathPrefix(_dirPathPrefix_Full); - } -} - -STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) -{ - COM_TRY_BEGIN - _progressTotal = size; - _progressTotal_Defined = true; - if (!_multiArchives && _extractCallback2) - return _extractCallback2->SetTotal(size); - return S_OK; - COM_TRY_END -} - -static void NormalizeVals(UInt64 &v1, UInt64 &v2) -{ - const UInt64 kMax = (UInt64)1 << 31; - while (v1 > kMax) - { - v1 >>= 1; - v2 >>= 1; - } -} - -static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal) -{ - NormalizeVals(packTotal, unpTotal); - NormalizeVals(unpCur, unpTotal); - if (unpTotal == 0) - unpTotal = 1; - return unpCur * packTotal / unpTotal; -} - -STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) -{ - COM_TRY_BEGIN - - if (!_extractCallback2) - return S_OK; - - UInt64 packCur; - if (_multiArchives) - { - packCur = LocalProgressSpec->InSize; - if (completeValue && _progressTotal_Defined) - packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal); - completeValue = &packCur; - } - return _extractCallback2->SetCompleted(completeValue); - - COM_TRY_END -} - -STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - COM_TRY_BEGIN - return _localProgress->SetRatioInfo(inSize, outSize); - COM_TRY_END -} - -void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath) -{ - bool isAbsPath = false; - - if (!dirPathParts.IsEmpty()) - { - const UString &s = dirPathParts[0]; - if (s.IsEmpty()) - isAbsPath = true; - #if defined(_WIN32) && !defined(UNDER_CE) - else - { - if (NName::IsDrivePath2(s)) - isAbsPath = true; - } - #endif - } - - if (_pathMode == NExtract::NPathMode::kAbsPaths && isAbsPath) - fullPath.Empty(); - else - fullPath = _dirPathPrefix; - - FOR_VECTOR (i, dirPathParts) - { - if (i != 0) - fullPath.Add_PathSepar(); - const UString &s = dirPathParts[i]; - fullPath += us2fs(s); - #if defined(_WIN32) && !defined(UNDER_CE) - if (_pathMode == NExtract::NPathMode::kAbsPaths) - if (i == 0 && s.Len() == 2 && NName::IsDrivePath2(s)) - continue; - #endif - CreateDir(fullPath); - } -} - -HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) -{ - filetimeIsDefined = false; - 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); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -HRESULT CArchiveExtractCallback::GetUnpackSize() -{ - return _arc->GetItemSize(_index, _curSize, _curSizeDefined); -} - -static void AddPathToMessage(UString &s, const FString &path) -{ - s.AddAscii(" : "); - s += fs2us(path); -} - -HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path) -{ - UString s; - s.AddAscii(message); - AddPathToMessage(s, path); - return _extractCallback2->MessageError(s); -} - -HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) -{ - DWORD errorCode = GetLastError(); - UString s; - s.AddAscii(message); - if (errorCode != 0) - { - s.AddAscii(" : "); - s += NError::MyFormatMessage(errorCode); - } - AddPathToMessage(s, path); - return _extractCallback2->MessageError(s); -} - -HRESULT CArchiveExtractCallback::SendMessageError2(const char *message, const FString &path1, const FString &path2) -{ - UString s; - s.AddAscii(message); - AddPathToMessage(s, path1); - AddPathToMessage(s, path2); - return _extractCallback2->MessageError(s); -} - -#ifndef _SFX - -STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value) -{ - /* - if (propID == kpidName) - { - COM_TRY_BEGIN - NCOM::CPropVariant prop = Name; - prop.Detach(value); - return S_OK; - COM_TRY_END - } - */ - return Arc->Archive->GetProperty(IndexInArc, propID, value); -} - -#endif - - -#ifdef SUPPORT_LINKS - -static UString GetDirPrefixOf(const UString &src) -{ - UString s = src; - if (!s.IsEmpty()) - { - if (IsPathSepar(s.Back())) - s.DeleteBack(); - int pos = s.ReverseFind_PathSepar(); - s.DeleteFrom(pos + 1); - } - return s; -} - -#endif - - -bool IsSafePath(const UString &path) -{ - if (NName::IsAbsolutePath(path)) - return false; - - UStringVector parts; - SplitPathToParts(path, parts); - unsigned level = 0; - - FOR_VECTOR (i, parts) - { - const UString &s = parts[i]; - if (s.IsEmpty()) - { - if (i == 0) - return false; - continue; - } - if (s == L".") - continue; - if (s == L"..") - { - if (level == 0) - return false; - level--; - } - else - level++; - } - - return level > 0; -} - - -bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include) -{ - bool found = false; - - if (node.CheckPathVect(item.PathParts, !item.MainIsDir, include)) - { - if (!include) - return true; - - #ifdef SUPPORT_ALT_STREAMS - if (!item.IsAltStream) - return true; - #endif - - found = true; - } - - #ifdef SUPPORT_ALT_STREAMS - - if (!item.IsAltStream) - return false; - - UStringVector pathParts2 = item.PathParts; - if (pathParts2.IsEmpty()) - pathParts2.AddNew(); - UString &back = pathParts2.Back(); - back += L':'; - back += item.AltStreamName; - bool include2; - - if (node.CheckPathVect(pathParts2, - true, // isFile, - include2)) - { - include = include2; - return true; - } - - #endif - - return found; -} - -bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item) -{ - bool include; - if (CensorNode_CheckPath2(node, item, include)) - return include; - return false; -} - -static FString MakePath_from_2_Parts(const FString &prefix, const FString &path) -{ - FString s = prefix; - #if defined(_WIN32) && !defined(UNDER_CE) - if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back())) - { - if (!NName::IsDriveRootPath_SuperAllowed(prefix)) - s.DeleteBack(); - } - #endif - s += path; - return s; -} - - -/* -#ifdef SUPPORT_LINKS - -struct CTempMidBuffer -{ - void *Buf; - - CTempMidBuffer(size_t size): Buf(NULL) { Buf = ::MidAlloc(size); } - ~CTempMidBuffer() { ::MidFree(Buf); } -}; - -HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream) -{ - const size_t kBufSize = 1 << 16; - CTempMidBuffer buf(kBufSize); - if (!buf.Buf) - return E_OUTOFMEMORY; - - NIO::CInFile inFile; - NIO::COutFile outFile; - - if (!inFile.Open(_CopyFile_Path)) - return SendMessageError_with_LastError("Open error", _CopyFile_Path); - - for (;;) - { - UInt32 num; - - if (!inFile.Read(buf.Buf, kBufSize, num)) - return SendMessageError_with_LastError("Read error", _CopyFile_Path); - - if (num == 0) - return S_OK; - - - RINOK(WriteStream(outStream, buf.Buf, num)); - } -} - -#endif -*/ - -STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) -{ - COM_TRY_BEGIN - - *outStream = NULL; - - #ifndef _SFX - if (_hashStream) - _hashStreamSpec->ReleaseStream(); - _hashStreamWasUsed = false; - #endif - - _outFileStream.Release(); - - _encrypted = false; - _position = 0; - _isSplit = false; - - _curSize = 0; - _curSizeDefined = false; - _index = index; - - _diskFilePath.Empty(); - - // _fi.Clear(); - - #ifdef SUPPORT_LINKS - // _CopyFile_Path.Empty(); - linkPath.Empty(); - #endif - - IInArchive *archive = _arc->Archive; - - #ifndef _SFX - _item._use_baseParentFolder_mode = _use_baseParentFolder_mode; - if (_use_baseParentFolder_mode) - { - _item._baseParentFolder = _baseParentFolder; - if (_pathMode == NExtract::NPathMode::kFullPaths || - _pathMode == NExtract::NPathMode::kAbsPaths) - _item._baseParentFolder = -1; - } - #endif - - #ifdef SUPPORT_ALT_STREAMS - _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon; - #endif - - RINOK(_arc->GetItem(index, _item)); - - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidPosition, &prop)); - if (prop.vt != VT_EMPTY) - { - if (prop.vt != VT_UI8) - return E_FAIL; - _position = prop.uhVal.QuadPart; - _isSplit = true; - } - } - - #ifdef SUPPORT_LINKS - - // bool isCopyLink = false; - bool isHardLink = false; - bool isJunction = false; - bool isRelative = false; - - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidHardLink, &prop)); - if (prop.vt == VT_BSTR) - { - isHardLink = true; - // isCopyLink = false; - isRelative = false; // RAR5, TAR: hard links are from root folder of archive - linkPath.SetFromBstr(prop.bstrVal); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - } - - /* - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidCopyLink, &prop)); - if (prop.vt == VT_BSTR) - { - isHardLink = false; - isCopyLink = true; - isRelative = false; // RAR5: copy links are from root folder of archive - linkPath.SetFromBstr(prop.bstrVal); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - } - */ - - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidSymLink, &prop)); - if (prop.vt == VT_BSTR) - { - isHardLink = false; - // isCopyLink = false; - isRelative = true; // RAR5, TAR: symbolic links can be relative - linkPath.SetFromBstr(prop.bstrVal); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - } - - - bool isOkReparse = false; - - if (linkPath.IsEmpty() && _arc->GetRawProps) - { - const void *data; - UInt32 dataSize; - UInt32 propType; - - _arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType); - - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - UString s; - CReparseAttr reparse; - isOkReparse = reparse.Parse((const Byte *)data, dataSize); - if (isOkReparse) - { - isHardLink = false; - // isCopyLink = false; - linkPath = reparse.GetPath(); - isJunction = reparse.IsMountPoint(); - isRelative = reparse.IsRelative(); - #ifndef _WIN32 - linkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); - #endif - } - } - } - - if (!linkPath.IsEmpty()) - { - #ifdef _WIN32 - linkPath.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - - // rar5 uses "\??\" prefix for absolute links - if (linkPath.IsPrefixedBy(WSTRING_PATH_SEPARATOR L"??" WSTRING_PATH_SEPARATOR)) - { - isRelative = false; - linkPath.DeleteFrontal(4); - } - - for (;;) - // while (NName::IsAbsolutePath(linkPath)) - { - unsigned n = NName::GetRootPrefixSize(linkPath); - if (n == 0) - break; - isRelative = false; - linkPath.DeleteFrontal(n); - } - } - - if (!linkPath.IsEmpty() && !isRelative && _removePathParts.Size() != 0) - { - UStringVector pathParts; - SplitPathToParts(linkPath, pathParts); - bool badPrefix = false; - FOR_VECTOR (i, _removePathParts) - { - if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0) - { - badPrefix = true; - break; - } - } - if (!badPrefix) - pathParts.DeleteFrontal(_removePathParts.Size()); - linkPath = MakePathFromParts(pathParts); - } - - #endif - - RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)); - - RINOK(GetUnpackSize()); - - #ifdef SUPPORT_ALT_STREAMS - - if (!_ntOptions.AltStreams.Val && _item.IsAltStream) - return S_OK; - - #endif - - - UStringVector &pathParts = _item.PathParts; - - if (_wildcardCensor) - { - if (!CensorNode_CheckPath(*_wildcardCensor, _item)) - return S_OK; - } - - #ifndef _SFX - if (_use_baseParentFolder_mode) - { - if (!pathParts.IsEmpty()) - { - unsigned numRemovePathParts = 0; - - #ifdef SUPPORT_ALT_STREAMS - if (_pathMode == NExtract::NPathMode::kNoPathsAlt && _item.IsAltStream) - numRemovePathParts = pathParts.Size(); - else - #endif - if (_pathMode == NExtract::NPathMode::kNoPaths || - _pathMode == NExtract::NPathMode::kNoPathsAlt) - numRemovePathParts = pathParts.Size() - 1; - pathParts.DeleteFrontal(numRemovePathParts); - } - } - else - #endif - { - if (pathParts.IsEmpty()) - { - if (_item.IsDir) - return S_OK; - /* - #ifdef SUPPORT_ALT_STREAMS - if (!_item.IsAltStream) - #endif - return E_FAIL; - */ - } - - unsigned numRemovePathParts = 0; - - switch (_pathMode) - { - case NExtract::NPathMode::kFullPaths: - case NExtract::NPathMode::kCurPaths: - { - if (_removePathParts.IsEmpty()) - break; - bool badPrefix = false; - - if (pathParts.Size() < _removePathParts.Size()) - badPrefix = true; - else - { - if (pathParts.Size() == _removePathParts.Size()) - { - if (_removePartsForAltStreams) - { - #ifdef SUPPORT_ALT_STREAMS - if (!_item.IsAltStream) - #endif - badPrefix = true; - } - else - { - if (!_item.MainIsDir) - badPrefix = true; - } - } - - if (!badPrefix) - FOR_VECTOR (i, _removePathParts) - { - if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0) - { - badPrefix = true; - break; - } - } - } - - if (badPrefix) - { - if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) - return E_FAIL; - } - else - numRemovePathParts = _removePathParts.Size(); - break; - } - - case NExtract::NPathMode::kNoPaths: - { - if (!pathParts.IsEmpty()) - numRemovePathParts = pathParts.Size() - 1; - break; - } - case NExtract::NPathMode::kNoPathsAlt: - { - #ifdef SUPPORT_ALT_STREAMS - if (_item.IsAltStream) - numRemovePathParts = pathParts.Size(); - else - #endif - if (!pathParts.IsEmpty()) - numRemovePathParts = pathParts.Size() - 1; - break; - } - /* - case NExtract::NPathMode::kFullPaths: - case NExtract::NPathMode::kAbsPaths: - break; - */ - } - - pathParts.DeleteFrontal(numRemovePathParts); - } - - #ifndef _SFX - - if (ExtractToStreamCallback) - { - if (!GetProp) - { - GetProp_Spec = new CGetProp; - GetProp = GetProp_Spec; - } - GetProp_Spec->Arc = _arc; - GetProp_Spec->IndexInArc = index; - UString name = MakePathFromParts(pathParts); - - #ifdef SUPPORT_ALT_STREAMS - if (_item.IsAltStream) - { - if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt)) - name += L':'; - name += _item.AltStreamName; - } - #endif - - return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp); - } - - #endif - - CMyComPtr outStreamLoc; - -if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) -{ - if (_stdOutMode) - { - outStreamLoc = new CStdOutFileStream; - } - else - { - { - NCOM::CPropVariant prop; - RINOK(archive->GetProperty(index, kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - { - _fi.Attrib = prop.ulVal; - _fi.AttribDefined = true; - } - else if (prop.vt == VT_EMPTY) - _fi.AttribDefined = false; - else - return E_FAIL; - } - - RINOK(GetTime(index, kpidCTime, _fi.CTime, _fi.CTimeDefined)); - RINOK(GetTime(index, kpidATime, _fi.ATime, _fi.ATimeDefined)); - RINOK(GetTime(index, kpidMTime, _fi.MTime, _fi.MTimeDefined)); - - bool isAnti = false; - RINOK(_arc->IsItemAnti(index, isAnti)); - - #ifdef SUPPORT_ALT_STREAMS - if (!_item.IsAltStream - || !pathParts.IsEmpty() - || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)) - #endif - Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, pathParts, _item.MainIsDir); - - #ifdef SUPPORT_ALT_STREAMS - - if (_item.IsAltStream) - { - UString s = _item.AltStreamName; - Correct_AltStream_Name(s); - bool needColon = true; - - if (pathParts.IsEmpty()) - { - pathParts.AddNew(); - if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt) - needColon = false; - } - else if (_pathMode == NExtract::NPathMode::kAbsPaths && - NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size()) - pathParts.AddNew(); - - UString &name = pathParts.Back(); - if (needColon) - name += (wchar_t)(_ntOptions.ReplaceColonForAltStream ? L'_' : L':'); - name += s; - } - - #endif - - UString processedPath = MakePathFromParts(pathParts); - - if (!isAnti) - { - if (!_item.IsDir) - { - if (!pathParts.IsEmpty()) - pathParts.DeleteBack(); - } - - if (!pathParts.IsEmpty()) - { - FString fullPathNew; - CreateComplexDirectory(pathParts, fullPathNew); - if (_item.IsDir) - { - _extractedFolderPaths.Add(fullPathNew); - _extractedFolderIndices.Add(index); - SetDirTime(fullPathNew, - (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, - (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, - (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - } - } - } - - - FString fullProcessedPath = us2fs(processedPath); - if (_pathMode != NExtract::NPathMode::kAbsPaths - || !NName::IsAbsolutePath(processedPath)) - { - fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath); - } - - #ifdef SUPPORT_ALT_STREAMS - - if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) - { - int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); - if (renIndex >= 0) - { - const CIndexToPathPair &pair = _renamedFiles[renIndex]; - fullProcessedPath = pair.Path; - fullProcessedPath += (FChar)':'; - UString s = _item.AltStreamName; - Correct_AltStream_Name(s); - fullProcessedPath += us2fs(s); - } - } - - #endif - - bool isRenamed = false; - - if (_item.IsDir) - { - _diskFilePath = fullProcessedPath; - if (isAnti) - RemoveDir(_diskFilePath); - #ifdef SUPPORT_LINKS - if (linkPath.IsEmpty()) - #endif - return S_OK; - } - else if (!_isSplit) - { - - // ----- Is file (not split) ----- - NFind::CFileInfo fileInfo; - if (fileInfo.Find(fullProcessedPath)) - { - switch (_overwriteMode) - { - case NExtract::NOverwriteMode::kSkip: - return S_OK; - case NExtract::NOverwriteMode::kAsk: - { - int slashPos = fullProcessedPath.ReverseFind_PathSepar(); - FString realFullProcessedPath = fullProcessedPath.Left(slashPos + 1) + fileInfo.Name; - - Int32 overwriteResult; - RINOK(_extractCallback2->AskOverwrite( - fs2us(realFullProcessedPath), &fileInfo.MTime, &fileInfo.Size, _item.Path, - _fi.MTimeDefined ? &_fi.MTime : NULL, - _curSizeDefined ? &_curSize : NULL, - &overwriteResult)) - - switch (overwriteResult) - { - case NOverwriteAnswer::kCancel: return E_ABORT; - case NOverwriteAnswer::kNo: return S_OK; - case NOverwriteAnswer::kNoToAll: _overwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; - case NOverwriteAnswer::kYes: break; - case NOverwriteAnswer::kYesToAll: _overwriteMode = NExtract::NOverwriteMode::kOverwrite; break; - case NOverwriteAnswer::kAutoRename: _overwriteMode = NExtract::NOverwriteMode::kRename; break; - default: - return E_FAIL; - } - } - } - if (_overwriteMode == NExtract::NOverwriteMode::kRename) - { - if (!AutoRenamePath(fullProcessedPath)) - { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); - return E_FAIL; - } - isRenamed = true; - } - else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting) - { - FString existPath = fullProcessedPath; - if (!AutoRenamePath(existPath)) - { - RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)); - return E_FAIL; - } - // MyMoveFile can raname folders. So it's OK to use it for folders too - if (!MyMoveFile(fullProcessedPath, existPath)) - { - RINOK(SendMessageError2(kCantRenameFile, existPath, fullProcessedPath)); - return E_FAIL; - } - } - else - { - if (fileInfo.IsDir()) - { - // do we need to delete all files in folder? - if (!RemoveDir(fullProcessedPath)) - { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)); - return S_OK; - } - } - else - { - bool needDelete = true; - if (needDelete) - { - if (!DeleteFileAlways(fullProcessedPath)) - { - RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)); - return S_OK; - // return E_FAIL; - } - } - } - } - } - else // not Find(fullProcessedPath) - { - // we need to clear READ-ONLY of parent before creating alt stream - #if defined(_WIN32) && !defined(UNDER_CE) - int colonPos = NName::FindAltStreamColon(fullProcessedPath); - if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) - { - FString parentFsPath = fullProcessedPath; - parentFsPath.DeleteFrom(colonPos); - NFind::CFileInfo parentFi; - if (parentFi.Find(parentFsPath)) - { - if (parentFi.IsReadOnly()) - SetFileAttrib(parentFsPath, parentFi.Attrib & ~FILE_ATTRIBUTE_READONLY); - } - } - #endif - } - // ----- END of code for Is file (not split) ----- - - } - _diskFilePath = fullProcessedPath; - - - if (!isAnti) - { - #ifdef SUPPORT_LINKS - - if (!linkPath.IsEmpty()) - { - #ifndef UNDER_CE - - UString relatPath; - if (isRelative) - relatPath = GetDirPrefixOf(_item.Path); - relatPath += linkPath; - - if (!IsSafePath(relatPath)) - { - RINOK(SendMessageError("Dangerous link path was ignored", us2fs(relatPath))); - } - else - { - FString existPath; - if (isHardLink /* || isCopyLink */ || !isRelative) - { - if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(relatPath), existPath)) - { - RINOK(SendMessageError("Incorrect path", us2fs(relatPath))); - } - } - else - { - existPath = us2fs(linkPath); - } - - if (!existPath.IsEmpty()) - { - if (isHardLink /* || isCopyLink */) - { - // if (isHardLink) - { - if (!MyCreateHardLink(fullProcessedPath, existPath)) - { - RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, existPath)); - // return S_OK; - } - } - /* - else - { - NFind::CFileInfo fi; - if (!fi.Find(existPath)) - { - RINOK(SendMessageError2("Can not find the file for copying", existPath, fullProcessedPath)); - } - else - { - if (_curSizeDefined && _curSize == fi.Size) - _CopyFile_Path = existPath; - else - { - RINOK(SendMessageError2("File size collision for file copying", existPath, fullProcessedPath)); - } - - // RINOK(MyCopyFile(existPath, fullProcessedPath)); - } - } - */ - } - else if (_ntOptions.SymLinks.Val) - { - // bool isSymLink = true; // = false for junction - if (_item.IsDir && !isRelative) - { - // if it's before Vista we use Junction Point - // isJunction = true; - // convertToAbs = true; - } - - CByteBuffer data; - if (FillLinkData(data, fs2us(existPath), !isJunction)) - { - CReparseAttr attr; - if (!attr.Parse(data, data.Size())) - { - RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path))); - // return E_FAIL; - } - else - if (!NFile::NIO::SetReparseData(fullProcessedPath, _item.IsDir, data, (DWORD)data.Size())) - { - RINOK(SendMessageError_with_LastError("Can not create symbolic link", fullProcessedPath)); - } - } - } - } - } - - #endif - } - - if (linkPath.IsEmpty() /* || !_CopyFile_Path.IsEmpty() */) - #endif // SUPPORT_LINKS - { - bool needWriteFile = true; - - #ifdef SUPPORT_LINKS - if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream) - { - CHardLinkNode h; - bool defined; - RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)); - if (defined) - { - { - int linkIndex = _hardLinks.IDs.FindInSorted2(h); - if (linkIndex >= 0) - { - FString &hl = _hardLinks.Links[linkIndex]; - if (hl.IsEmpty()) - hl = fullProcessedPath; - else - { - if (!MyCreateHardLink(fullProcessedPath, hl)) - { - RINOK(SendMessageError2("Can not create hard link", fullProcessedPath, hl)); - return S_OK; - } - needWriteFile = false; - } - } - } - } - } - #endif - - if (needWriteFile) - { - _outFileStreamSpec = new COutFileStream; - CMyComPtr outStreamLoc2(_outFileStreamSpec); - if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) - { - // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) - { - RINOK(SendMessageError_with_LastError("Can not open output file", fullProcessedPath)); - return S_OK; - } - } - - - #ifdef SUPPORT_ALT_STREAMS - if (isRenamed && !_item.IsAltStream) - { - CIndexToPathPair pair(index, fullProcessedPath); - unsigned oldSize = _renamedFiles.Size(); - unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair); - if (oldSize == _renamedFiles.Size()) - _renamedFiles[insertIndex].Path = fullProcessedPath; - } - #endif - - if (_isSplit) - { - RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); - } - - _outFileStream = outStreamLoc2; - } - } - } - - outStreamLoc = _outFileStream; - } -} - - #ifndef _SFX - - if (_hashStream) - { - if (askExtractMode == NArchive::NExtract::NAskMode::kExtract || - askExtractMode == NArchive::NExtract::NAskMode::kTest) - { - _hashStreamSpec->SetStream(outStreamLoc); - outStreamLoc = _hashStream; - _hashStreamSpec->Init(true); - _hashStreamWasUsed = true; - } - } - - #endif - - - if (outStreamLoc) - { - /* - #ifdef SUPPORT_LINKS - - if (!_CopyFile_Path.IsEmpty()) - { - RINOK(PrepareOperation(askExtractMode)); - RINOK(MyCopyFile(outStreamLoc)); - return SetOperationResult(NArchive::NExtract::NOperationResult::kOK); - } - - if (isCopyLink && _testMode) - return S_OK; - - #endif - */ - - *outStream = outStreamLoc.Detach(); - } - - return S_OK; - - COM_TRY_END -} - - -STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) -{ - COM_TRY_BEGIN - - #ifndef _SFX - if (ExtractToStreamCallback) - return ExtractToStreamCallback->PrepareOperation7(askExtractMode); - #endif - - _extractMode = false; - - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: - if (_testMode) - askExtractMode = NArchive::NExtract::NAskMode::kTest; - else - _extractMode = true; - break; - }; - - return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir), - askExtractMode, _isSplit ? &_position: 0); - - COM_TRY_END -} - - -STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) -{ - COM_TRY_BEGIN - - #ifndef _SFX - if (ExtractToStreamCallback) - return ExtractToStreamCallback->SetOperationResult7(opRes, BoolToInt(_encrypted)); - #endif - - #ifndef _SFX - - if (_hashStreamWasUsed) - { - _hashStreamSpec->_hash->Final(_item.IsDir, - #ifdef SUPPORT_ALT_STREAMS - _item.IsAltStream - #else - false - #endif - , _item.Path); - _curSize = _hashStreamSpec->GetSize(); - _curSizeDefined = true; - _hashStreamSpec->ReleaseStream(); - _hashStreamWasUsed = false; - } - - #endif - - if (_outFileStream) - { - _outFileStreamSpec->SetTime( - (WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL, - (WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL, - (WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - _curSize = _outFileStreamSpec->ProcessedSize; - _curSizeDefined = true; - RINOK(_outFileStreamSpec->Close()); - _outFileStream.Release(); - } - - #ifdef _USE_SECURITY_CODE - if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) - { - const void *data; - UInt32 dataSize; - UInt32 propType; - _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType); - if (dataSize != 0) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - if (CheckNtSecure((const Byte *)data, dataSize)) - { - SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION; - if (_saclEnabled) - securInfo |= SACL_SECURITY_INFORMATION; - ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)data); - } - } - } - #endif - - if (!_curSizeDefined) - GetUnpackSize(); - - if (_curSizeDefined) - { - #ifdef SUPPORT_ALT_STREAMS - if (_item.IsAltStream) - AltStreams_UnpackSize += _curSize; - else - #endif - UnpackSize += _curSize; - } - - if (_item.IsDir) - NumFolders++; - #ifdef SUPPORT_ALT_STREAMS - else if (_item.IsAltStream) - NumAltStreams++; - #endif - else - NumFiles++; - - if (!_stdOutMode && _extractMode && _fi.AttribDefined) - SetFileAttrib(_diskFilePath, _fi.Attrib, &_delayedSymLinks); - - RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))); - - return S_OK; - - COM_TRY_END -} - -STDMETHODIMP CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) -{ - if (_folderArchiveExtractCallback2) - { - bool isEncrypted = false; - wchar_t temp[16]; - UString s2; - const wchar_t *s = NULL; - - if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1) - { - CReadArcItem item; - RINOK(_arc->GetItem(index, item)); - s2 = item.Path; - s = s2; - RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)); - } - else - { - temp[0] = '#'; - ConvertUInt32ToString(index, temp + 1); - s = temp; - // if (indexType == NArchive::NEventIndexType::kBlockIndex) {} - } - - return _folderArchiveExtractCallback2->ReportExtractResult(opRes, isEncrypted, s); - } - - return S_OK; -} - - -STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - if (!_cryptoGetTextPassword) - { - RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, - &_cryptoGetTextPassword)); - } - return _cryptoGetTextPassword->CryptoGetTextPassword(password); - COM_TRY_END -} - - -struct CExtrRefSortPair -{ - unsigned Len; - unsigned Index; - - int Compare(const CExtrRefSortPair &a) const; -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -int CExtrRefSortPair::Compare(const CExtrRefSortPair &a) const -{ - RINOZ(-MyCompare(Len, a.Len)); - return MyCompare(Index, a.Index); -} - -static unsigned GetNumSlashes(const FChar *s) -{ - for (unsigned numSlashes = 0;;) - { - FChar c = *s++; - if (c == 0) - return numSlashes; - if (IS_PATH_SEPAR(c)) - numSlashes++; - } -} - -HRESULT CArchiveExtractCallback::SetDirsTimes() -{ - HRESULT result = S_OK; - CRecordVector pairs; - pairs.ClearAndSetSize(_extractedFolderPaths.Size()); - unsigned i; - - for (i = 0; i < _extractedFolderPaths.Size(); i++) - { - CExtrRefSortPair &pair = pairs[i]; - pair.Index = i; - pair.Len = GetNumSlashes(_extractedFolderPaths[i]); - } - - pairs.Sort2(); - - for (i = 0; i < pairs.Size(); i++) - { - int pairIndex = pairs[i].Index; - int index = _extractedFolderIndices[pairIndex]; - - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - - RINOK(GetTime(index, kpidCTime, CTime, CTimeDefined)); - RINOK(GetTime(index, kpidATime, ATime, ATimeDefined)); - RINOK(GetTime(index, kpidMTime, MTime, MTimeDefined)); - - // printf("\n%S", _extractedFolderPaths[pairIndex]); - SetDirTime(_extractedFolderPaths[pairIndex], - (WriteCTime && CTimeDefined) ? &CTime : NULL, - (WriteATime && ATimeDefined) ? &ATime : NULL, - (WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL)); - } - - for (int i = 0; i != _delayedSymLinks.Size(); ++i) - if (!_delayedSymLinks[i].Create()) - result = E_FAIL; - - _delayedSymLinks.Clear(); - - return result; -} +// ArchiveExtractCallback.cpp + +#include "StdAfx.h" + +#undef sprintf +#undef printf + +// #include + +#include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) +#define Z7_USE_SECURITY_CODE +#include "../../../Windows/SecurityUtils.h" +#endif + +#include "../../Common/FilePathAutoRename.h" +#include "../../Common/StreamUtils.h" + +#include "../../Archive/Common/ItemNameUtils.h" + +#include "../Common/ExtractingFilePath.h" +#include "../Common/PropIDUtils.h" + +#include "ArchiveExtractCallback.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const char * const kCantAutoRename = "Cannot create file with auto name"; +static const char * const kCantRenameFile = "Cannot rename existing file"; +static const char * const kCantDeleteOutputFile = "Cannot delete output file"; +static const char * const kCantDeleteOutputDir = "Cannot delete output folder"; +static const char * const kCantOpenOutFile = "Cannot open output file"; +#ifndef Z7_SFX +static const char * const kCantOpenInFile = "Cannot open input file"; +#endif +static const char * const kCantSetFileLen = "Cannot set length for output file"; +#ifdef SUPPORT_LINKS +static const char * const kCantCreateHardLink = "Cannot create hard link"; +static const char * const kCantCreateSymLink = "Cannot create symbolic link"; +#endif + +static const unsigned k_LinkDataSize_LIMIT = 1 << 12; + +#if WCHAR_PATH_SEPARATOR != L'/' + // we convert linux slashes to windows slashes for further processing. + // also we convert linux backslashes to BackslashReplacement character. + #define REPLACE_SLASHES_from_Linux_to_Sys(s) \ + { NArchive::NItemName::ReplaceToWinSlashes(s, true); } // useBackslashReplacement + // { s.Replace(L'/', WCHAR_PATH_SEPARATOR); } +#else + #define REPLACE_SLASHES_from_Linux_to_Sys(s) +#endif + + +#ifndef Z7_SFX + +Z7_COM7F_IMF(COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + HRESULT result = S_OK; + if (_stream) + result = _stream->Write(data, size, &size); + if (_calculate) + _hash->Update(data, size); + _size += size; + if (processedSize) + *processedSize = size; + return result; +} + +#endif // Z7_SFX + + +#ifdef Z7_USE_SECURITY_CODE +bool InitLocalPrivileges(); +bool InitLocalPrivileges() +{ + NSecurity::CAccessToken token; + if (!token.OpenProcessToken(GetCurrentProcess(), + TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES)) + return false; + + TOKEN_PRIVILEGES tp; + + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!::LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tp.Privileges[0].Luid)) + return false; + if (!token.AdjustPrivileges(&tp)) + return false; + return (GetLastError() == ERROR_SUCCESS); +} +#endif // Z7_USE_SECURITY_CODE + + + +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + +static const char * const kOfficeExtensions = + " doc dot wbk" + " docx docm dotx dotm docb wll wwl" + " xls xlt xlm" + " xlsx xlsm xltx xltm xlsb xla xlam" + " ppt pot pps ppa ppam" + " pptx pptm potx potm ppam ppsx ppsm sldx sldm" + " "; + +static bool FindExt2(const char *p, const UString &name) +{ + const int pathPos = name.ReverseFind_PathSepar(); + const int dotPos = name.ReverseFind_Dot(); + if (dotPos < 0 + || dotPos < pathPos + || dotPos == (int)name.Len() - 1) + return false; + + AString s; + for (unsigned pos = (unsigned)(dotPos + 1);; pos++) + { + const wchar_t c = name[pos]; + if (c <= 0) + break; + if (c >= 0x80) + return false; + s.Add_Char((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 char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier"; + +bool Is_ZoneId_StreamName(const wchar_t *s) +{ + return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1); +} + +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf) +{ + buf.Free(); + FString path (fileName); + path += k_ZoneId_StreamName_With_Colon_Prefix; + NIO::CInFile file; + if (!file.Open(path)) + return; + UInt64 fileSize; + if (!file.GetLength(fileSize)) + return; + if (fileSize == 0 || fileSize >= (1u << 15)) + return; + buf.Alloc((size_t)fileSize); + size_t processed; + if (file.ReadFull(buf, (size_t)fileSize, processed) && processed == fileSize) + return; + buf.Free(); +} + +bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf) +{ + FString path (fileName); + path += k_ZoneId_StreamName_With_Colon_Prefix; + NIO::COutFile file; + if (!file.Create_ALWAYS(path)) + return false; + return file.WriteFull(buf, buf.Size()); +} + +#endif + + +#ifdef SUPPORT_LINKS + +int CHardLinkNode::Compare(const CHardLinkNode &a) const +{ + if (StreamId < a.StreamId) return -1; + if (StreamId > a.StreamId) return 1; + return MyCompare(INode, a.INode); +} + +static HRESULT Archive_Get_HardLinkNode(IInArchive *archive, UInt32 index, CHardLinkNode &h, bool &defined) +{ + h.INode = 0; + h.StreamId = (UInt64)(Int64)-1; + defined = false; + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidINode, &prop)) + if (!ConvertPropVariantToUInt64(prop, h.INode)) + return S_OK; + } + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidStreamId, &prop)) + ConvertPropVariantToUInt64(prop, h.StreamId); + } + defined = true; + return S_OK; +} + + +HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector *realIndices) +{ + _hardLinks.Clear(); + + if (!_arc->Ask_INode) + return S_OK; + + IInArchive * const archive = _arc->Archive; + CRecordVector &hardIDs = _hardLinks.IDs; + + { + UInt32 numItems; + if (realIndices) + numItems = realIndices->Size(); + else + { + RINOK(archive->GetNumberOfItems(&numItems)) + } + + for (UInt32 i = 0; i < numItems; i++) + { + CHardLinkNode h; + bool defined; + const UInt32 realIndex = realIndices ? (*realIndices)[i] : i; + + RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined)) + if (defined) + { + bool isAltStream = false; + RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream)) + if (!isAltStream) + { + bool isDir = false; + RINOK(Archive_IsItem_Dir(archive, realIndex, isDir)) + if (!isDir) + hardIDs.Add(h); + } + } + } + } + + hardIDs.Sort2(); + + { + // we keep only items that have 2 or more items + unsigned k = 0; + unsigned numSame = 1; + for (unsigned i = 1; i < hardIDs.Size(); i++) + { + if (hardIDs[i].Compare(hardIDs[i - 1]) != 0) + numSame = 1; + else if (++numSame == 2) + { + if (i - 1 != k) + hardIDs[k] = hardIDs[i - 1]; + k++; + } + } + hardIDs.DeleteFrom(k); + } + + _hardLinks.PrepareLinks(); + return S_OK; +} + +#endif // SUPPORT_LINKS + + +CArchiveExtractCallback::CArchiveExtractCallback(): + // Write_CTime(true), + // Write_ATime(true), + // Write_MTime(true), + Is_elimPrefix_Mode(false), + _arc(NULL), + _multiArchives(false) +{ + #ifdef Z7_USE_SECURITY_CODE + _saclEnabled = InitLocalPrivileges(); + #endif +} + + +void CArchiveExtractCallback::InitBeforeNewArchive() +{ +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + ZoneBuf.Free(); +#endif +} + +void CArchiveExtractCallback::Init( + const CExtractNtOptions &ntOptions, + const NWildcard::CCensorNode *wildcardCensor, + const CArc *arc, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, bool testMode, + const FString &directoryPath, + const UStringVector &removePathParts, bool removePartsForAltStreams, + UInt64 packSize) +{ + ClearExtractedDirsInfo(); + _outFileStream.Release(); + _bufPtrSeqOutStream.Release(); + + #ifdef SUPPORT_LINKS + _hardLinks.Clear(); + #endif + + #ifdef SUPPORT_ALT_STREAMS + _renamedFiles.Clear(); + #endif + + _ntOptions = ntOptions; + _wildcardCensor = wildcardCensor; + _stdOutMode = stdOutMode; + _testMode = testMode; + _packTotal = packSize; + _progressTotal = packSize; + // _progressTotal = 0; + // _progressTotal_Defined = false; + // _progressTotal_Defined = true; + _extractCallback2 = extractCallback2; + /* + _compressProgress.Release(); + _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); + _callbackMessage.Release(); + _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage); + */ + _folderArchiveExtractCallback2.Release(); + _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); + + #ifndef Z7_SFX + + ExtractToStreamCallback.Release(); + _extractCallback2.QueryInterface(IID_IFolderExtractToStreamCallback, &ExtractToStreamCallback); + if (ExtractToStreamCallback) + { + Int32 useStreams = 0; + if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK) + useStreams = 0; + if (useStreams == 0) + ExtractToStreamCallback.Release(); + } + + #endif + + LocalProgressSpec->Init(extractCallback2, true); + LocalProgressSpec->SendProgress = false; + + _removePathParts = removePathParts; + _removePartsForAltStreams = removePartsForAltStreams; + + #ifndef Z7_SFX + _baseParentFolder = (UInt32)(Int32)-1; + _use_baseParentFolder_mode = false; + #endif + + _arc = arc; + _dirPathPrefix = directoryPath; + _dirPathPrefix_Full = directoryPath; + #if defined(_WIN32) && !defined(UNDER_CE) + if (!NName::IsAltPathPrefix(_dirPathPrefix)) + #endif + { + NName::NormalizeDirPathPrefix(_dirPathPrefix); + NDir::MyGetFullPathName(directoryPath, _dirPathPrefix_Full); + NName::NormalizeDirPathPrefix(_dirPathPrefix_Full); + } +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size)) +{ + COM_TRY_BEGIN + _progressTotal = size; + // _progressTotal_Defined = true; + if (!_multiArchives && _extractCallback2) + return _extractCallback2->SetTotal(size); + return S_OK; + COM_TRY_END +} + + +static void NormalizeVals(UInt64 &v1, UInt64 &v2) +{ + const UInt64 kMax = (UInt64)1 << 31; + while (v1 > kMax) + { + v1 >>= 1; + v2 >>= 1; + } +} + + +static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal) +{ + NormalizeVals(packTotal, unpTotal); + NormalizeVals(unpCur, unpTotal); + if (unpTotal == 0) + unpTotal = 1; + return unpCur * packTotal / unpTotal; +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)) +{ + COM_TRY_BEGIN + + if (!_extractCallback2) + return S_OK; + + UInt64 packCur; + if (_multiArchives) + { + packCur = LocalProgressSpec->InSize; + if (completeValue /* && _progressTotal_Defined */) + packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal); + completeValue = &packCur; + } + return _extractCallback2->SetCompleted(completeValue); + + COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + COM_TRY_BEGIN + return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize); + COM_TRY_END +} + + +void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath) +{ + // we use (_item.IsDir) in this function + + bool isAbsPath = false; + + if (!dirPathParts.IsEmpty()) + { + const UString &s = dirPathParts[0]; + if (s.IsEmpty()) + isAbsPath = true; + #if defined(_WIN32) && !defined(UNDER_CE) + else + { + if (NName::IsDrivePath2(s)) + isAbsPath = true; + } + #endif + } + + if (_pathMode == NExtract::NPathMode::kAbsPaths && isAbsPath) + fullPath.Empty(); + else + fullPath = _dirPathPrefix; + + FOR_VECTOR (i, dirPathParts) + { + if (i != 0) + fullPath.Add_PathSepar(); + const UString &s = dirPathParts[i]; + fullPath += us2fs(s); + + const bool isFinalDir = (i == dirPathParts.Size() - 1 && _item.IsDir); + + if (fullPath.IsEmpty()) + { + if (isFinalDir) + _itemFailure = true; + continue; + } + + #if defined(_WIN32) && !defined(UNDER_CE) + if (_pathMode == NExtract::NPathMode::kAbsPaths) + if (i == 0 && s.Len() == 2 && NName::IsDrivePath2(s)) + { + if (isFinalDir) + { + // we don't want to call SetAttrib() for root drive path + _itemFailure = true; + } + continue; + } + #endif + + HRESULT hres = S_OK; + if (!CreateDir(fullPath)) + hres = GetLastError_noZero_HRESULT(); + if (isFinalDir) + { + if (!NFile::NFind::DoesDirExist(fullPath)) + { + _itemFailure = true; + SendMessageError_with_Error(hres, "Cannot create folder", fullPath); + } + } + } +} + + +HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, CArcTime &ft) +{ + ft.Clear(); + NCOM::CPropVariant prop; + RINOK(_arc->Archive->GetProperty(index, propID, &prop)) + if (prop.vt == VT_FILETIME) + ft.Set_From_Prop(prop); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +HRESULT CArchiveExtractCallback::GetUnpackSize() +{ + return _arc->GetItem_Size(_index, _curSize, _curSize_Defined); +} + +static void AddPathToMessage(UString &s, const FString &path) +{ + s += " : "; + s += fs2us(path); +} + +HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path) +{ + UString s (message); + AddPathToMessage(s, path); + return _extractCallback2->MessageError(s); +} + + +HRESULT CArchiveExtractCallback::SendMessageError_with_Error(HRESULT errorCode, const char *message, const FString &path) +{ + UString s (message); + if (errorCode != S_OK) + { + s += " : "; + s += NError::MyFormatMessage(errorCode); + } + AddPathToMessage(s, path); + return _extractCallback2->MessageError(s); +} + +HRESULT CArchiveExtractCallback::SendMessageError_with_LastError(const char *message, const FString &path) +{ + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + return SendMessageError_with_Error(errorCode, message, path); +} + +HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2) +{ + UString s (message); + if (errorCode != 0) + { + s += " : "; + s += NError::MyFormatMessage(errorCode); + } + AddPathToMessage(s, path1); + AddPathToMessage(s, path2); + return _extractCallback2->MessageError(s); +} + +HRESULT CArchiveExtractCallback::SendMessageError2_with_LastError( + const char *message, const FString &path1, const FString &path2) +{ + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + return SendMessageError2(errorCode, message, path1, path2); +} + +#ifndef Z7_SFX + +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) +public: + UInt32 IndexInArc; + const CArc *Arc; + // UString BaseName; // relative path +}; + +Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) +{ + /* + if (propID == kpidBaseName) + { + COM_TRY_BEGIN + NCOM::CPropVariant prop = BaseName; + prop.Detach(value); + return S_OK; + COM_TRY_END + } + */ + return Arc->Archive->GetProperty(IndexInArc, propID, value); +} + +#endif // Z7_SFX + + +struct CLinkLevelsInfo +{ + bool IsAbsolute; + int LowLevel; + int FinalLevel; + + void Parse(const UString &path, bool isWSL); +}; + +void CLinkLevelsInfo::Parse(const UString &path, bool isWSL) +{ + IsAbsolute = isWSL ? + IS_PATH_SEPAR(path[0]) : + NName::IsAbsolutePath(path); + LowLevel = 0; + FinalLevel = 0; + + UStringVector parts; + SplitPathToParts(path, parts); + int level = 0; + + FOR_VECTOR (i, parts) + { + const UString &s = parts[i]; + if (s.IsEmpty()) + { + if (i == 0) + IsAbsolute = true; + continue; + } + if (s.IsEqualTo(".")) + continue; + if (s.IsEqualTo("..")) + { + level--; + if (LowLevel > level) + LowLevel = level; + } + else + level++; + } + + FinalLevel = level; +} + + +static bool IsSafePath(const UString &path, bool isWSL) +{ + CLinkLevelsInfo levelsInfo; + levelsInfo.Parse(path, isWSL); + return !levelsInfo.IsAbsolute + && levelsInfo.LowLevel >= 0 + && levelsInfo.FinalLevel > 0; +} + +bool IsSafePath(const UString &path); +bool IsSafePath(const UString &path) +{ + return IsSafePath(path, false); // isWSL +} + +bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); +bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include) +{ + bool found = false; + + // CheckPathVect() doesn't check path to Parent nodes + if (node.CheckPathVect(item.PathParts, !item.MainIsDir, include)) + { + if (!include) + return true; + + #ifdef SUPPORT_ALT_STREAMS + if (!item.IsAltStream) + return true; + #endif + + found = true; + } + + #ifdef SUPPORT_ALT_STREAMS + + if (!item.IsAltStream) + return false; + + UStringVector pathParts2 = item.PathParts; + if (pathParts2.IsEmpty()) + pathParts2.AddNew(); + UString &back = pathParts2.Back(); + back.Add_Colon(); + back += item.AltStreamName; + bool include2; + + if (node.CheckPathVect(pathParts2, + true, // isFile, + include2)) + { + include = include2; + return true; + } + + #endif // SUPPORT_ALT_STREAMS + + return found; +} + + +bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item) +{ + bool include; + if (CensorNode_CheckPath2(node, item, include)) + return include; + return false; +} + + +static FString MakePath_from_2_Parts(const FString &prefix, const FString &path) +{ + FString s (prefix); + #if defined(_WIN32) && !defined(UNDER_CE) + if (!path.IsEmpty() && path[0] == ':' && !prefix.IsEmpty() && IsPathSepar(prefix.Back())) + { + if (!NName::IsDriveRootPath_SuperAllowed(prefix)) + s.DeleteBack(); + } + #endif + s += path; + return s; +} + + + +#ifdef SUPPORT_LINKS + +/* +struct CTempMidBuffer +{ + void *Buf; + + CTempMidBuffer(size_t size): Buf(NULL) { Buf = ::MidAlloc(size); } + ~CTempMidBuffer() { ::MidFree(Buf); } +}; + +HRESULT CArchiveExtractCallback::MyCopyFile(ISequentialOutStream *outStream) +{ + const size_t kBufSize = 1 << 16; + CTempMidBuffer buf(kBufSize); + if (!buf.Buf) + return E_OUTOFMEMORY; + + NIO::CInFile inFile; + NIO::COutFile outFile; + + if (!inFile.Open(_copyFile_Path)) + return SendMessageError_with_LastError("Open error", _copyFile_Path); + + for (;;) + { + UInt32 num; + + if (!inFile.Read(buf.Buf, kBufSize, num)) + return SendMessageError_with_LastError("Read error", _copyFile_Path); + + if (num == 0) + return S_OK; + + + RINOK(WriteStream(outStream, buf.Buf, num)); + } +} +*/ + + +HRESULT CArchiveExtractCallback::ReadLink() +{ + IInArchive * const archive = _arc->Archive; + const UInt32 index = _index; + // _link.Clear(); // _link.Clear() was called already. + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidHardLink, &prop)) + if (prop.vt == VT_BSTR) + { + _link.LinkType = k_LinkType_HardLink; + _link.isRelative = false; // RAR5, TAR: hard links are from root folder of archive + _link.LinkPath.SetFromBstr(prop.bstrVal); + // 7-Zip 24-: tar handler returned original path (with linux slash in most case) + // 7-Zip 24-: rar5 handler returned path with system slash. + // 7-Zip 25+: tar/rar5 handlers return linux path in most cases. + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + /* + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidCopyLink, &prop)); + if (prop.vt == VT_BSTR) + { + _link.LinkType = k_LinkType_CopyLink; + _link.isRelative = false; // RAR5: copy links are from root folder of archive + _link.LinkPath.SetFromBstr(prop.bstrVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + */ + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidSymLink, &prop)) + if (prop.vt == VT_BSTR) + { + _link.LinkType = k_LinkType_PureSymLink; + _link.isRelative = true; // RAR5, TAR: symbolic links are relative by default + _link.LinkPath.SetFromBstr(prop.bstrVal); + // 7-Zip 24-: (tar, cpio, xar, ext, iso) handlers returned returned original path (with linux slash in most case) + // 7-Zip 24-: rar5 handler returned path with system slash. + // 7-Zip 25+: all handlers return linux path in most cases. + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + // linux path separator in (_link.LinkPath) is expected for most cases, + // if new handler code is used, and if data in archive is correct. + // NtReparse_Data = NULL; + // NtReparse_Size = 0; + if (!_link.LinkPath.IsEmpty()) + { + REPLACE_SLASHES_from_Linux_to_Sys(_link.LinkPath) + } + else if (_arc->GetRawProps) + { + const void *data; + UInt32 dataSize, propType; + if (_arc->GetRawProps->GetRawProp(_index, kpidNtReparse, &data, &dataSize, &propType) == S_OK + // && dataSize == 1234567 // for debug: unpacking without reparse + && dataSize) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + // 21.06: we need kpidNtReparse in linux for wim archives created in Windows + // NtReparse_Data = data; + // NtReparse_Size = dataSize; + // we ignore error code here, if there is failure of parsing: + _link.Parse_from_WindowsReparseData((const Byte *)data, dataSize); + } + } + + if (_link.LinkPath.IsEmpty()) + return S_OK; + // (_link.LinkPath) uses system path separator. + // windows: (_link.LinkPath) doesn't contain linux separator (slash). + { + // _link.LinkPath = "\\??\\r:\\1\\2"; // for debug + // rar5+ returns kpidSymLink absolute link path with "\??\" prefix. + // we normalize such prefix: + if (_link.LinkPath.IsPrefixedBy(STRING_PATH_SEPARATOR "??" STRING_PATH_SEPARATOR)) + { + _link.isRelative = false; + // we normalize prefix from "\??\" to "\\?\": + _link.LinkPath.ReplaceOneCharAtPos(1, WCHAR_PATH_SEPARATOR); + _link.isWindowsPath = true; + if (_link.LinkPath.IsPrefixedBy_Ascii_NoCase( + STRING_PATH_SEPARATOR + STRING_PATH_SEPARATOR "?" + STRING_PATH_SEPARATOR "UNC" + STRING_PATH_SEPARATOR)) + { + // we normalize prefix from "\\?\UNC\path" to "\\path": + _link.LinkPath.DeleteFrontal(6); + _link.LinkPath.ReplaceOneCharAtPos(0, WCHAR_PATH_SEPARATOR); + } + else + { + const unsigned k_prefix_Size = 4; + if (NName::IsDrivePath(_link.LinkPath.Ptr(k_prefix_Size))) + _link.LinkPath.DeleteFrontal(k_prefix_Size); + } + } + } + _link.Normalize_to_RelativeSafe(_removePathParts); + return S_OK; +} + +#endif // SUPPORT_LINKS + + +#ifndef _WIN32 + +static HRESULT GetOwner(IInArchive *archive, + UInt32 index, UInt32 pidName, UInt32 pidId, COwnerInfo &res) +{ + { + NWindows::NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, pidId, &prop)) + if (prop.vt == VT_UI4) + { + res.Id_Defined = true; + res.Id = prop.ulVal; + // 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 * const archive = _arc->Archive; + const UInt32 index = _index; + + _fi.Attrib_Defined = false; + + #ifndef _WIN32 + _fi.Owner.Clear(); + _fi.Group.Clear(); + #endif + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPosixAttrib, &prop)) + if (prop.vt == VT_UI4) + { + _fi.SetFromPosixAttrib(prop.ulVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + { + _fi.Attrib = prop.ulVal; + _fi.Attrib_Defined = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + RINOK(GetTime(index, kpidCTime, _fi.CTime)) + RINOK(GetTime(index, kpidATime, _fi.ATime)) + RINOK(GetTime(index, kpidMTime, _fi.MTime)) + + #ifndef _WIN32 + if (_ntOptions.ExtractOwner) + { + // SendMessageError_with_LastError("_ntOptions.ExtractOwner", _diskFilePath); + GetOwner(archive, index, kpidUser, kpidUserId, _fi.Owner); + GetOwner(archive, index, kpidGroup, kpidGroupId, _fi.Group); + } + #endif + + return S_OK; +} + + + +void CArchiveExtractCallback::CorrectPathParts() +{ + UStringVector &pathParts = _item.PathParts; + + #ifdef SUPPORT_ALT_STREAMS + if (!_item.IsAltStream + || !pathParts.IsEmpty() + || !(_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt)) + #endif + Correct_FsPath(_pathMode == NExtract::NPathMode::kAbsPaths, _keepAndReplaceEmptyDirPrefixes, pathParts, _item.MainIsDir); + + #ifdef SUPPORT_ALT_STREAMS + + if (_item.IsAltStream) + { + UString s (_item.AltStreamName); + Correct_AltStream_Name(s); + bool needColon = true; + + if (pathParts.IsEmpty()) + { + pathParts.AddNew(); + if (_removePartsForAltStreams || _pathMode == NExtract::NPathMode::kNoPathsAlt) + needColon = false; + } + #ifdef _WIN32 + else if (_pathMode == NExtract::NPathMode::kAbsPaths && + NWildcard::GetNumPrefixParts_if_DrivePath(pathParts) == pathParts.Size()) + pathParts.AddNew(); + #endif + + UString &name = pathParts.Back(); + if (needColon) + name.Add_Char((char)(_ntOptions.ReplaceColonForAltStream ? '_' : ':')); + name += s; + } + + #endif // SUPPORT_ALT_STREAMS +} + + +void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) +{ + pt.CTime_Defined = false; + pt.ATime_Defined = false; + pt.MTime_Defined = false; + + // if (Write_MTime) + { + if (_fi.MTime.Def) + { + _fi.MTime.Write_To_FiTime(pt.MTime); + pt.MTime_Defined = true; + } + else if (_arc->MTime.Def) + { + _arc->MTime.Write_To_FiTime(pt.MTime); + pt.MTime_Defined = true; + } + } + + if (/* Write_CTime && */ _fi.CTime.Def) + { + _fi.CTime.Write_To_FiTime(pt.CTime); + pt.CTime_Defined = true; + } + + if (/* Write_ATime && */ _fi.ATime.Def) + { + _fi.ATime.Write_To_FiTime(pt.ATime); + pt.ATime_Defined = true; + } +} + + +void CArchiveExtractCallback::CreateFolders() +{ + // 21.04 : we don't change original (_item.PathParts) here + UStringVector pathParts = _item.PathParts; + + // bool is_DirOp = false; + if (!pathParts.IsEmpty()) + { + /* v23: if we extract symlink, and we know that it links to dir: + Linux: we don't create dir item (symlink_from_path) here. + Windows: SetReparseData() will create dir item, if it doesn't exist, + but if we create dir item here, it's not problem. */ + if (!_item.IsDir + #ifdef SUPPORT_LINKS + #ifndef WIN32 + || !_link.LinkPath.IsEmpty() + #endif + #endif + ) + pathParts.DeleteBack(); + // else is_DirOp = true; + } + + if (pathParts.IsEmpty()) + { + /* if (_some_pathParts_wereRemoved && Is_elimPrefix_Mode), + then we can have empty pathParts() here for root folder. + v24.00: fixed: we set timestamps for such folder still. + */ + if (!_some_pathParts_wereRemoved || + !Is_elimPrefix_Mode) + return; + // return; // ignore empty paths case + } + /* + if (is_DirOp) + { + RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract)) + _op_WasReported = true; + } + */ + + FString fullPathNew; + CreateComplexDirectory(pathParts, fullPathNew); + + /* + if (is_DirOp) + { + RINOK(SetOperationResult( + // _itemFailure ? NArchive::NExtract::NOperationResult::kDataError : + NArchive::NExtract::NOperationResult::kOK + )) + } + */ + + if (!_item.IsDir) + return; + if (fullPathNew.IsEmpty()) + return; + + if (_itemFailure) + return; + + CDirPathTime pt; + GetFiTimesCAM(pt); + + if (pt.IsSomeTimeDefined()) + { + pt.Path = fullPathNew; + pt.SetDirTime(); + _extractedFolders.Add(pt); + } +} + + + +/* + CheckExistFile(fullProcessedPath) + it can change: fullProcessedPath, _isRenamed, _overwriteMode + (needExit = true) means that we must exit GetStream() even for S_OK result. +*/ + +HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool &needExit) +{ + needExit = true; // it was set already before + + NFind::CFileInfo fileInfo; + + if (fileInfo.Find(fullProcessedPath)) + { + if (_overwriteMode == NExtract::NOverwriteMode::kSkip) + return S_OK; + + if (_overwriteMode == NExtract::NOverwriteMode::kAsk) + { + const int slashPos = fullProcessedPath.ReverseFind_PathSepar(); + const FString realFullProcessedPath = fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name; + + /* (fileInfo) can be symbolic link. + we can show final file properties here. */ + + FILETIME ft1; + FiTime_To_FILETIME(fileInfo.MTime, ft1); + + Int32 overwriteResult; + RINOK(_extractCallback2->AskOverwrite( + fs2us(realFullProcessedPath), &ft1, &fileInfo.Size, _item.Path, + _fi.MTime.Def ? &_fi.MTime.FT : NULL, + _curSize_Defined ? &_curSize : NULL, + &overwriteResult)) + + switch (overwriteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + _overwriteMode = NExtract::NOverwriteMode::kSkip; + return S_OK; + + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kYesToAll: + _overwriteMode = NExtract::NOverwriteMode::kOverwrite; + break; + case NOverwriteAnswer::kAutoRename: + _overwriteMode = NExtract::NOverwriteMode::kRename; + break; + default: + return E_FAIL; + } + } // NExtract::NOverwriteMode::kAsk + + if (_overwriteMode == NExtract::NOverwriteMode::kRename) + { + if (!AutoRenamePath(fullProcessedPath)) + { + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) + return E_FAIL; + } + _isRenamed = true; + } + else if (_overwriteMode == NExtract::NOverwriteMode::kRenameExisting) + { + FString existPath (fullProcessedPath); + if (!AutoRenamePath(existPath)) + { + RINOK(SendMessageError(kCantAutoRename, fullProcessedPath)) + return E_FAIL; + } + // MyMoveFile can rename folders. So it's OK to use it for folders too + if (!MyMoveFile(fullProcessedPath, existPath)) + { + RINOK(SendMessageError2_with_LastError(kCantRenameFile, existPath, fullProcessedPath)) + return E_FAIL; + } + } + else // not Rename* + { + if (fileInfo.IsDir()) + { + // do we need to delete all files in folder? + if (!RemoveDir(fullProcessedPath)) + { + RINOK(SendMessageError_with_LastError(kCantDeleteOutputDir, fullProcessedPath)) + return S_OK; + } + } + else // fileInfo is not Dir + { + if (NFind::DoesFileExist_Raw(fullProcessedPath)) + if (!DeleteFileAlways(fullProcessedPath)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) // check it in linux + { + RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)) + return S_OK; + // return E_FAIL; + } + } // fileInfo is not Dir + } // not Rename* + } + else // not Find(fullProcessedPath) + { + #if defined(_WIN32) && !defined(UNDER_CE) + // we need to clear READ-ONLY of parent before creating alt stream + const int colonPos = NName::FindAltStreamColon(fullProcessedPath); + if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) + { + FString parentFsPath (fullProcessedPath); + parentFsPath.DeleteFrom((unsigned)colonPos); + NFind::CFileInfo parentFi; + if (parentFi.Find(parentFsPath)) + { + if (parentFi.IsReadOnly()) + { + _altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath; + _altStream_NeedRestore_AttribVal = parentFi.Attrib; + SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } + } + } + #endif // defined(_WIN32) && !defined(UNDER_CE) + } + + needExit = false; + return S_OK; +} + + + + + + +HRESULT CArchiveExtractCallback::GetExtractStream(CMyComPtr &outStreamLoc, bool &needExit) +{ + needExit = true; + + RINOK(Read_fi_Props()) + + #ifdef SUPPORT_LINKS + IInArchive * const archive = _arc->Archive; + #endif + + const UInt32 index = _index; + + bool isAnti = false; + RINOK(_arc->IsItem_Anti(index, isAnti)) + + CorrectPathParts(); + UString processedPath (MakePathFromParts(_item.PathParts)); + + if (!isAnti) + { + // 21.04: CreateFolders doesn't change (_item.PathParts) + CreateFolders(); + } + + FString fullProcessedPath (us2fs(processedPath)); + if (_pathMode != NExtract::NPathMode::kAbsPaths + || !NName::IsAbsolutePath(processedPath)) + { + fullProcessedPath = MakePath_from_2_Parts(_dirPathPrefix, fullProcessedPath); + } + + #ifdef SUPPORT_ALT_STREAMS + if (_item.IsAltStream && _item.ParentIndex != (UInt32)(Int32)-1) + { + const int renIndex = _renamedFiles.FindInSorted(CIndexToPathPair(_item.ParentIndex)); + if (renIndex != -1) + { + const CIndexToPathPair &pair = _renamedFiles[(unsigned)renIndex]; + fullProcessedPath = pair.Path; + fullProcessedPath.Add_Colon(); + UString s (_item.AltStreamName); + Correct_AltStream_Name(s); + fullProcessedPath += us2fs(s); + } + } + #endif // SUPPORT_ALT_STREAMS + + if (_item.IsDir) + { + _diskFilePath = fullProcessedPath; + if (isAnti) + RemoveDir(_diskFilePath); + #ifdef SUPPORT_LINKS + if (_link.LinkPath.IsEmpty()) + #endif + { + if (!isAnti) + SetAttrib(); + return S_OK; + } + } + else if (!_isSplit) + { + RINOK(CheckExistFile(fullProcessedPath, needExit)) + if (needExit) + return S_OK; + needExit = true; + } + + _diskFilePath = fullProcessedPath; + + + if (isAnti) + { + needExit = false; + return S_OK; + } + + // not anti + + #ifdef SUPPORT_LINKS + + if (!_link.LinkPath.IsEmpty()) + { + #ifndef UNDER_CE + { + bool linkWasSet = false; + RINOK(SetLink(fullProcessedPath, _link, linkWasSet)) + if (linkWasSet) + { + _isSymLinkCreated = _link.Is_AnySymLink(); + SetAttrib(); + // printf("\nlinkWasSet %s\n", GetAnsiString(_diskFilePath)); + } + } + #endif // UNDER_CE + + // if (_copyFile_Path.IsEmpty()) + { + needExit = false; + return S_OK; + } + } + + if (!_hardLinks.IDs.IsEmpty() && !_item.IsAltStream && !_item.IsDir) + { + CHardLinkNode h; + bool defined; + RINOK(Archive_Get_HardLinkNode(archive, index, h, defined)) + if (defined) + { + const int linkIndex = _hardLinks.IDs.FindInSorted2(h); + if (linkIndex != -1) + { + FString &hl = _hardLinks.Links[(unsigned)linkIndex]; + if (hl.IsEmpty()) + hl = fullProcessedPath; + else + { + if (!MyCreateHardLink(fullProcessedPath, hl)) + return SendMessageError2_with_LastError(kCantCreateHardLink, fullProcessedPath, hl); + // printf("\nHard linkWasSet Archive_Get_HardLinkNode %s\n", GetAnsiString(_diskFilePath)); + // _needSetAttrib = true; // do we need to set attribute ? + SetAttrib(); + needExit = false; + return S_OK; + } + } + } + } + + #endif // SUPPORT_LINKS + + + // ---------- CREATE WRITE FILE ----- + + _outFileStreamSpec = new COutFileStream; + CMyComPtr outFileStream_Loc(_outFileStreamSpec); + + if (!_outFileStreamSpec->Create_ALWAYS_or_Open_ALWAYS(fullProcessedPath, !_isSplit)) + { + // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) + { + RINOK(SendMessageError_with_LastError(kCantOpenOutFile, fullProcessedPath)) + return S_OK; + } + } + + _needSetAttrib = true; + + bool is_SymLink_in_Data = false; + + if (_curSize_Defined && _curSize && _curSize < k_LinkDataSize_LIMIT) + { + if (_fi.IsLinuxSymLink()) + { + is_SymLink_in_Data = true; + _is_SymLink_in_Data_Linux = true; + } + else if (_fi.IsReparse()) + { + is_SymLink_in_Data = true; + _is_SymLink_in_Data_Linux = false; + } + } + + if (is_SymLink_in_Data) + { + _outMemBuf.Alloc((size_t)_curSize); + _bufPtrSeqOutStream_Spec = new CBufPtrSeqOutStream; + _bufPtrSeqOutStream = _bufPtrSeqOutStream_Spec; + _bufPtrSeqOutStream_Spec->Init(_outMemBuf, _outMemBuf.Size()); + outStreamLoc = _bufPtrSeqOutStream; + } + else // not reparse + { + if (_ntOptions.PreAllocateOutFile && !_isSplit && _curSize_Defined && _curSize > (1 << 12)) + { + // UInt64 ticks = GetCpuTicks(); + _fileLength_that_WasSet = _curSize; + bool res = _outFileStreamSpec->File.SetLength(_curSize); + _fileLength_WasSet = res; + + // ticks = GetCpuTicks() - ticks; + // printf("\nticks = %10d\n", (unsigned)ticks); + if (!res) + { + RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath)) + } + + /* + _outFileStreamSpec->File.Close(); + ticks = GetCpuTicks() - ticks; + printf("\nticks = %10d\n", (unsigned)ticks); + return S_FALSE; + */ + + /* + File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow, + if we don't write any data. + File.SetLength() for remote share file (exFAT) can be slow in some cases, + and the Windows can return "network error" after 1 minute, + while remote file still can grow. + We need some way to detect such bad cases and disable PreAllocateOutFile mode. + */ + + res = _outFileStreamSpec->SeekToBegin_bool(); + if (!res) + { + RINOK(SendMessageError_with_LastError("Cannot seek to begin of file", fullProcessedPath)) + } + } // PreAllocateOutFile + + #ifdef SUPPORT_ALT_STREAMS + if (_isRenamed && !_item.IsAltStream) + { + CIndexToPathPair pair(index, fullProcessedPath); + unsigned oldSize = _renamedFiles.Size(); + unsigned insertIndex = _renamedFiles.AddToUniqueSorted(pair); + if (oldSize == _renamedFiles.Size()) + _renamedFiles[insertIndex].Path = fullProcessedPath; + } + #endif // SUPPORT_ALT_STREAMS + + if (_isSplit) + { + RINOK(outFileStream_Loc->Seek((Int64)_position, STREAM_SEEK_SET, NULL)) + } + outStreamLoc = outFileStream_Loc; + } // if not reparse + + _outFileStream = outFileStream_Loc; + + needExit = false; + return S_OK; +} + + + +HRESULT CArchiveExtractCallback::GetItem(UInt32 index) +{ + #ifndef Z7_SFX + _item._use_baseParentFolder_mode = _use_baseParentFolder_mode; + if (_use_baseParentFolder_mode) + { + _item._baseParentFolder = (int)_baseParentFolder; + if (_pathMode == NExtract::NPathMode::kFullPaths || + _pathMode == NExtract::NPathMode::kAbsPaths) + _item._baseParentFolder = -1; + } + #endif // Z7_SFX + + #ifdef SUPPORT_ALT_STREAMS + _item.WriteToAltStreamIfColon = _ntOptions.WriteToAltStreamIfColon; + #endif + + return _arc->GetItem(index, _item); +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)) +{ + COM_TRY_BEGIN + + *outStream = NULL; + + #ifndef Z7_SFX + if (_hashStream) + _hashStreamSpec->ReleaseStream(); + _hashStreamWasUsed = false; + #endif + + _outFileStream.Release(); + _bufPtrSeqOutStream.Release(); + + _encrypted = false; + _isSplit = false; + _curSize_Defined = false; + _fileLength_WasSet = false; + _isRenamed = false; + // _fi.Clear(); + _extractMode = false; + _is_SymLink_in_Data_Linux = false; + _needSetAttrib = false; + _isSymLinkCreated = false; + _itemFailure = false; + _some_pathParts_wereRemoved = false; + // _op_WasReported = false; + + _position = 0; + _curSize = 0; + _fileLength_that_WasSet = 0; + _index = index; + +#if defined(_WIN32) && !defined(UNDER_CE) + _altStream_NeedRestore_AttribVal = 0; + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); +#endif + + _diskFilePath.Empty(); + + #ifdef SUPPORT_LINKS + // _copyFile_Path.Empty(); + _link.Clear(); + #endif + + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + { + // askExtractMode = NArchive::NExtract::NAskMode::kTest; + } + else + _extractMode = true; + break; + default: break; + } + + + IInArchive * const archive = _arc->Archive; + + RINOK(GetItem(index)) + + { + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPosition, &prop)) + if (prop.vt != VT_EMPTY) + { + if (prop.vt != VT_UI8) + return E_FAIL; + _position = prop.uhVal.QuadPart; + _isSplit = true; + } + } + +#ifdef SUPPORT_LINKS + RINOK(ReadLink()) +#endif + + RINOK(Archive_GetItemBoolProp(archive, index, kpidEncrypted, _encrypted)) + + RINOK(GetUnpackSize()) + + #ifdef SUPPORT_ALT_STREAMS + if (!_ntOptions.AltStreams.Val && _item.IsAltStream) + return S_OK; + #endif // SUPPORT_ALT_STREAMS + + // we can change (_item.PathParts) in this function + UStringVector &pathParts = _item.PathParts; + + if (_wildcardCensor) + { + if (!CensorNode_CheckPath(*_wildcardCensor, _item)) + return S_OK; + } + +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract + && !_testMode + && _item.IsAltStream + && ZoneBuf.Size() != 0 + && Is_ZoneId_StreamName(_item.AltStreamName)) + if (ZoneMode != NExtract::NZoneIdMode::kOffice + || _item.PathParts.IsEmpty() + || FindExt2(kOfficeExtensions, _item.PathParts.Back())) + return S_OK; +#endif + + + #ifndef Z7_SFX + if (_use_baseParentFolder_mode) + { + if (!pathParts.IsEmpty()) + { + unsigned numRemovePathParts = 0; + + #ifdef SUPPORT_ALT_STREAMS + if (_pathMode == NExtract::NPathMode::kNoPathsAlt && _item.IsAltStream) + numRemovePathParts = pathParts.Size(); + else + #endif + if (_pathMode == NExtract::NPathMode::kNoPaths || + _pathMode == NExtract::NPathMode::kNoPathsAlt) + numRemovePathParts = pathParts.Size() - 1; + pathParts.DeleteFrontal(numRemovePathParts); + } + } + else + #endif // Z7_SFX + { + if (pathParts.IsEmpty()) + { + if (_item.IsDir) + return S_OK; + /* + #ifdef SUPPORT_ALT_STREAMS + if (!_item.IsAltStream) + #endif + return E_FAIL; + */ + } + + unsigned numRemovePathParts = 0; + + switch ((int)_pathMode) + { + case NExtract::NPathMode::kFullPaths: + case NExtract::NPathMode::kCurPaths: + { + if (_removePathParts.IsEmpty()) + break; + bool badPrefix = false; + + if (pathParts.Size() < _removePathParts.Size()) + badPrefix = true; + else + { + if (pathParts.Size() == _removePathParts.Size()) + { + if (_removePartsForAltStreams) + { + #ifdef SUPPORT_ALT_STREAMS + if (!_item.IsAltStream) + #endif + badPrefix = true; + } + else + { + if (!_item.MainIsDir) + badPrefix = true; + } + } + + if (!badPrefix) + FOR_VECTOR (i, _removePathParts) + { + if (CompareFileNames(_removePathParts[i], pathParts[i]) != 0) + { + badPrefix = true; + break; + } + } + } + + if (badPrefix) + { + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) + return E_FAIL; + } + else + { + numRemovePathParts = _removePathParts.Size(); + _some_pathParts_wereRemoved = true; + } + break; + } + + case NExtract::NPathMode::kNoPaths: + { + if (!pathParts.IsEmpty()) + numRemovePathParts = pathParts.Size() - 1; + break; + } + case NExtract::NPathMode::kNoPathsAlt: + { + #ifdef SUPPORT_ALT_STREAMS + if (_item.IsAltStream) + numRemovePathParts = pathParts.Size(); + else + #endif + if (!pathParts.IsEmpty()) + numRemovePathParts = pathParts.Size() - 1; + break; + } + case NExtract::NPathMode::kAbsPaths: + default: + break; + } + + pathParts.DeleteFrontal(numRemovePathParts); + } + + + #ifndef Z7_SFX + + if (ExtractToStreamCallback) + { + CMyComPtr2_Create GetProp; + GetProp->Arc = _arc; + GetProp->IndexInArc = index; + UString name (MakePathFromParts(pathParts)); + // GetProp->BaseName = name; + #ifdef SUPPORT_ALT_STREAMS + if (_item.IsAltStream) + { + if (!pathParts.IsEmpty() || (!_removePartsForAltStreams && _pathMode != NExtract::NPathMode::kNoPathsAlt)) + name.Add_Colon(); + name += _item.AltStreamName; + } + #endif + + return ExtractToStreamCallback->GetStream7(name, BoolToInt(_item.IsDir), outStream, askExtractMode, GetProp); + } + + #endif // Z7_SFX + + + CMyComPtr outStreamLoc; + + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) + { + if (_stdOutMode) + outStreamLoc = new CStdOutFileStream; + else + { + bool needExit = true; + RINOK(GetExtractStream(outStreamLoc, needExit)) + if (needExit) + return S_OK; + } + } + + #ifndef Z7_SFX + if (_hashStream) + { + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract || + askExtractMode == NArchive::NExtract::NAskMode::kTest) + { + _hashStreamSpec->SetStream(outStreamLoc); + outStreamLoc = _hashStream; + _hashStreamSpec->Init(true); + _hashStreamWasUsed = true; + } + } + #endif // Z7_SFX + + if (outStreamLoc) + { + /* + #ifdef SUPPORT_LINKS + if (!_copyFile_Path.IsEmpty()) + { + RINOK(PrepareOperation(askExtractMode)); + RINOK(MyCopyFile(outStreamLoc)); + return SetOperationResult(NArchive::NExtract::NOperationResult::kOK); + } + if (_link.isCopyLink && _testMode) + return S_OK; + #endif + */ + *outStream = outStreamLoc.Detach(); + } + + return S_OK; + + COM_TRY_END +} + + + + + + + + + + + +Z7_COM7F_IMF(CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)) +{ + COM_TRY_BEGIN + + #ifndef Z7_SFX + // if (!_op_WasReported) + if (ExtractToStreamCallback) + return ExtractToStreamCallback->PrepareOperation7(askExtractMode); + #endif + + _extractMode = false; + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + askExtractMode = NArchive::NExtract::NAskMode::kTest; + else + _extractMode = true; + break; + default: break; + } + + // if (_op_WasReported) return S_OK; + + return _extractCallback2->PrepareOperation(_item.Path, BoolToInt(_item.IsDir), + askExtractMode, _isSplit ? &_position: NULL); + + COM_TRY_END +} + + + + + +HRESULT CArchiveExtractCallback::CloseFile() +{ + if (!_outFileStream) + return S_OK; + + HRESULT hres = S_OK; + + const UInt64 processedSize = _outFileStreamSpec->ProcessedSize; + if (_fileLength_WasSet && _fileLength_that_WasSet > processedSize) + { + const bool res = _outFileStreamSpec->File.SetLength(processedSize); + _fileLength_WasSet = res; + if (!res) + { + const HRESULT hres2 = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path)); + if (hres == S_OK) + hres = hres2; + } + } + + _curSize = processedSize; + _curSize_Defined = true; + + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (ZoneBuf.Size() != 0 + && !_item.IsAltStream) + { + // if (NFind::DoesFileExist_Raw(tempFilePath)) + if (ZoneMode != NExtract::NZoneIdMode::kOffice || + FindExt2(kOfficeExtensions, fs2us(_diskFilePath))) + { + // we must write zone file before setting of timestamps + if (!WriteZoneFile_To_BaseFile(_diskFilePath, 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 + if (t.IsSomeTimeDefined()) + _outFileStreamSpec->SetTime( + t.CTime_Defined ? &t.CTime : NULL, + t.ATime_Defined ? &t.ATime : NULL, + t.MTime_Defined ? &t.MTime : NULL); + // #endif + + RINOK(_outFileStreamSpec->Close()) + _outFileStream.Release(); + +#if defined(_WIN32) && !defined(UNDER_CE) + if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty()) + { + SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal); + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); + } +#endif + + return hres; +} + + +#ifdef SUPPORT_LINKS + +/* +in: + link.LinkPath : must be relative (non-absolute) path in any case !!! + link.isRelative / target path that must stored as created link: + == false / _dirPathPrefix_Full + link.LinkPath + == true / link.LinkPath +*/ + +HRESULT CArchiveExtractCallback::SetLink( + const FString &fullProcessedPath_from, + const CLinkInfo &link, + bool &linkWasSet) +{ + linkWasSet = false; + if (link.LinkPath.IsEmpty()) + return S_OK; + if (!_ntOptions.SymLinks.Val && link.Is_AnySymLink()) + return S_OK; + { + UString path; + if (link.isRelative) + { + // _item.PathParts : parts that will be created in output folder. + // we want to get directory prefix of link item. + // so we remove file name (last non-empty part) from PathParts: + UStringVector v = _item.PathParts; + while (!v.IsEmpty()) + { + const unsigned len = v.Back().Len(); + v.DeleteBack(); + if (len) + break; + } + path = MakePathFromParts(v); + NName::NormalizeDirPathPrefix(path); + } + path += link.LinkPath; + /* + path is calculated virtual target path of link + path is relative to root folder of extracted items + if (!link.isRelative), then (path == link.LinkPath) + */ + if (!IsSafePath(path, link.Is_WSL())) + return SendMessageError2(0, // errorCode + "Dangerous link path was ignored", + us2fs(_item.Path), us2fs(link.LinkPath)); + } + + FString target; // target path that will be stored to link field + if (link.Is_HardLink() /* || link.IsCopyLink */ || !link.isRelative) + { + // isRelative == false + // all hard links and absolute symbolic links + // relatPath == link.LinkPath + // we get absolute link path for target: + if (!NName::GetFullPath(_dirPathPrefix_Full, us2fs(link.LinkPath), target)) + return SendMessageError("Incorrect link path", us2fs(link.LinkPath)); + // (target) is (_dirPathPrefix_Full + relatPath) + } + else + { + // link.isRelative == true + // relative symbolic links only + target = us2fs(link.LinkPath); + } + if (target.IsEmpty()) + return SendMessageError("Empty link", fullProcessedPath_from); + + if (link.Is_HardLink() /* || link.IsCopyLink */) + { + // if (link.isHardLink) + { + if (!MyCreateHardLink(fullProcessedPath_from, target)) + return SendMessageError2_with_LastError(kCantCreateHardLink, fullProcessedPath_from, target); + /* + RINOK(PrepareOperation(NArchive::NExtract::NAskMode::kExtract)) + _op_WasReported = true; + RINOK(SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) + */ + linkWasSet = true; + return S_OK; + } + /* + // IsCopyLink + { + NFind::CFileInfo fi; + if (!fi.Find(target)) + { + RINOK(SendMessageError2("Cannot find the file for copying", target, fullProcessedPath)); + } + else + { + if (_curSize_Defined && _curSize == fi.Size) + _copyFile_Path = target; + else + { + RINOK(SendMessageError2("File size collision for file copying", target, fullProcessedPath)); + } + // RINOK(MyCopyFile(target, fullProcessedPath)); + } + } + */ + } + + // is Symbolic link + + /* + if (_item.IsDir && !isRelative) + { + // Windows before Vista doesn't support symbolic links. + // we could convert such symbolic links to Junction Points + // isJunction = true; + } + */ + +#ifdef _WIN32 + const bool isDir = (_item.IsDir || link.LinkType == k_LinkType_Junction); +#endif + + if (!_ntOptions.SymLinks_AllowDangerous.Val && link.isRelative) + { + /* + We want to use additional check for links that can link to directory. + - linux: all symbolic links are files. + - windows: we can have file/directory symbolic link, + but file symbolic link works like directory link in windows. + So we use additional check for all relative links. + + We don't allow decreasing of final level of link. + So if some another extracted file will use this link, + then number of real path parts (after link redirection) cannot be + smaller than number of requested path parts from archive records. + + Now we check only (link.LinkPath) without (_item.PathParts). + */ + CLinkLevelsInfo levelsInfo; + levelsInfo.Parse(link.LinkPath, link.Is_WSL()); + if (levelsInfo.FinalLevel < 1 + // || levelsInfo.LowLevel < 0 // we allow negative temporary levels + || levelsInfo.IsAbsolute) + return SendMessageError2(0, // errorCode + "Dangerous symbolic link path was ignored", + us2fs(_item.Path), us2fs(link.LinkPath)); + } + + +#ifdef _WIN32 + CByteBuffer data; + // printf("\nFillLinkData(): %s\n", GetOemString(target).Ptr()); + if (link.Is_WSL()) + { + Convert_WinPath_to_WslLinuxPath(target, !link.isRelative); + FillLinkData_WslLink(data, fs2us(target)); + } + else + FillLinkData_WinLink(data, fs2us(target), link.LinkType != k_LinkType_Junction); + if (data.Size() == 0) + return SendMessageError("Cannot fill link data", us2fs(_item.Path)); + /* + if (NtReparse_Size != data.Size() || memcmp(NtReparse_Data, data, data.Size()) != 0) + SendMessageError("reconstructed Reparse is different", fs2us(target)); + */ + { + // we check that reparse data is correct, but we ignore attr.MinorError. + CReparseAttr attr; + if (!attr.Parse(data, data.Size())) + return SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)); + } + if (!NFile::NIO::SetReparseData(fullProcessedPath_from, isDir, data, (DWORD)data.Size())) +#else // ! _WIN32 + if (!NFile::NIO::SetSymLink(fullProcessedPath_from, target)) +#endif // ! _WIN32 + { + return SendMessageError_with_LastError(kCantCreateSymLink, fullProcessedPath_from); + } + linkWasSet = true; + return S_OK; +} + + + +bool CLinkInfo::Parse_from_WindowsReparseData(const Byte *data, size_t dataSize) +{ + CReparseAttr reparse; + if (!reparse.Parse(data, dataSize)) + return false; + // const AString s = GetAnsiString(LinkPath); + // printf("\nlinkPath: %s\n", s.Ptr()); + LinkPath = reparse.GetPath(); + if (reparse.IsSymLink_WSL()) + { + LinkType = k_LinkType_WSL; + isRelative = reparse.IsRelative_WSL(); // detected from LinkPath[0] + // LinkPath is original raw name converted to UString from AString + // Linux separator '/' is expected here. + REPLACE_SLASHES_from_Linux_to_Sys(LinkPath) + } + else + { + LinkType = reparse.IsMountPoint() ? k_LinkType_Junction : k_LinkType_PureSymLink; + isRelative = reparse.IsRelative_Win(); // detected by (Flags == Z7_WIN_SYMLINK_FLAG_RELATIVE) + isWindowsPath = true; + // LinkPath is original windows link path from raparse data with \??\ prefix removed. + // windows '\\' separator is expected here. + // linux '/' separator is not expected here. + // we translate both types of separators to system separator. + LinkPath.Replace( +#if WCHAR_PATH_SEPARATOR == L'\\' + L'/' +#else + L'\\' +#endif + , WCHAR_PATH_SEPARATOR); + } + // (LinkPath) uses system path separator. + // windows: (LinkPath) doesn't contain linux separator (slash). + return true; +} + + +bool CLinkInfo::Parse_from_LinuxData(const Byte *data, size_t dataSize) +{ + // Clear(); // *this object was cleared by constructor already. + LinkType = k_LinkType_PureSymLink; + AString utf; + if (dataSize >= k_LinkDataSize_LIMIT) + return false; + utf.SetFrom_CalcLen((const char *)data, (unsigned)dataSize); + UString u; + if (!ConvertUTF8ToUnicode(utf, u)) + return false; + if (u.IsEmpty()) + return false; + const wchar_t c = u[0]; + isRelative = (c != L'/'); + // linux path separator is expected + REPLACE_SLASHES_from_Linux_to_Sys(u) + LinkPath = u; + // (LinkPath) uses system path separator. + // windows: (LinkPath) doesn't contain linux separator (slash). + return true; +} + + +// in/out: (LinkPath) uses system path separator +// in/out: windows: (LinkPath) doesn't contain linux separator (slash). +// out: (LinkPath) is relative path, and LinkPath[0] is not path separator +// out: isRelative changed to false, if any prefix was removed. +// note: absolute windows links "c:\" to root will be reduced to empty string: +void CLinkInfo::Remove_AbsPathPrefixes() +{ + while (!LinkPath.IsEmpty()) + { + unsigned n = 0; + if (!Is_WSL()) + { + n = +#ifndef _WIN32 + isWindowsPath ? + NName::GetRootPrefixSize_WINDOWS(LinkPath) : +#endif + NName::GetRootPrefixSize(LinkPath); +/* + // "c:path" will be ignored later as "Dangerous absolute path" + // so check is not required + if (n == 0 +#ifndef _WIN32 + && isWindowsPath +#endif + && NName::IsDrivePath2(LinkPath)) + n = 2; +*/ + } + if (n == 0) + { + if (!IS_PATH_SEPAR(LinkPath[0])) + break; + n = 1; + } + isRelative = false; // (LinkPath) will be treated as relative to root folder of archive + LinkPath.DeleteFrontal(n); + } +} + + +/* + it removes redundant separators, if there are double separators, + but it keeps double separators at start of string //name/. + in/out: system path separator is used + windows: slash character (linux separator) is not treated as separator + windows: (path) doesn't contain linux separator (slash). +*/ +static void RemoveRedundantPathSeparators(UString &path) +{ + wchar_t *dest = path.GetBuf(); + const wchar_t * const start = dest; + const wchar_t *src = dest; + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + // if (IS_PATH_SEPAR(c)) // for Windows: we can change (/) to (\). + if (c == WCHAR_PATH_SEPARATOR) + { + if (dest - start >= 2 && dest[-1] == WCHAR_PATH_SEPARATOR) + continue; + // c = WCHAR_PATH_SEPARATOR; // for Windows: we can change (/) to (\). + } + *dest++ = c; + } + *dest = 0; + path.ReleaseBuf_SetLen((unsigned)(dest - path.Ptr())); +} + + +// in/out: (LinkPath) uses system path separator +// in/out: windows: (LinkPath) doesn't contain linux separator (slash). +// out: (LinkPath) is relative path, and LinkPath[0] is not path separator +void CLinkInfo::Normalize_to_RelativeSafe(UStringVector &removePathParts) +{ + // We WILL NOT WRITE original absolute link path from archive to filesystem. + // So here we remove all root prefixes from (LinkPath). + // If we see any absolute root prefix, then we suppose that this prefix is virtual prefix + // that shows that link is relative to root folder of archive + RemoveRedundantPathSeparators(LinkPath); + // LinkPath = "\\\\?\\r:test\\test2"; // for debug + Remove_AbsPathPrefixes(); + // (LinkPath) now is relative: + // if (isRelative == false), then (LinkPath) is relative to root folder of archive + // if (isRelative == true ), then (LinkPath) is relative to current item + if (LinkPath.IsEmpty() || isRelative || removePathParts.Size() == 0) + return; + + // if LinkPath is prefixed by _removePathParts, we remove these paths + UStringVector pathParts; + SplitPathToParts(LinkPath, pathParts); + bool badPrefix = false; + { + FOR_VECTOR (i, removePathParts) + { + if (i >= pathParts.Size() + || CompareFileNames(removePathParts[i], pathParts[i]) != 0) + { + badPrefix = true; + break; + } + } + } + if (!badPrefix) + pathParts.DeleteFrontal(removePathParts.Size()); + LinkPath = MakePathFromParts(pathParts); + Remove_AbsPathPrefixes(); +} + +#endif // SUPPORT_LINKS + + +HRESULT CArchiveExtractCallback::CloseReparseAndFile() +{ + HRESULT res = S_OK; + +#ifdef SUPPORT_LINKS + + size_t reparseSize = 0; + bool repraseMode = false; + bool needSetReparse = false; + CLinkInfo link; + + if (_bufPtrSeqOutStream) + { + repraseMode = true; + reparseSize = _bufPtrSeqOutStream_Spec->GetPos(); + if (_curSize_Defined && reparseSize == _outMemBuf.Size()) + { + /* + CReparseAttr reparse; + DWORD errorCode = 0; + needSetReparse = reparse.Parse(_outMemBuf, reparseSize, errorCode); + if (needSetReparse) + { + UString LinkPath = reparse.GetPath(); + #ifndef _WIN32 + LinkPath.Replace(L'\\', WCHAR_PATH_SEPARATOR); + #endif + } + */ + needSetReparse = _is_SymLink_in_Data_Linux ? + link.Parse_from_LinuxData(_outMemBuf, reparseSize) : + link.Parse_from_WindowsReparseData(_outMemBuf, reparseSize); + if (!needSetReparse) + res = SendMessageError_with_LastError("Incorrect reparse stream", us2fs(_item.Path)); + // (link.LinkPath) uses system path separator. + // windows: (link.LinkPath) doesn't contain linux separator (slash). + } + else + { + res = SendMessageError_with_LastError("Unknown reparse stream", us2fs(_item.Path)); + } + if (!needSetReparse && _outFileStream) + { + const HRESULT res2 = WriteStream(_outFileStream, _outMemBuf, reparseSize); + if (res == S_OK) + res = res2; + } + _bufPtrSeqOutStream.Release(); + } + +#endif // SUPPORT_LINKS + + const HRESULT res2 = CloseFile(); + if (res == S_OK) + res = res2; + RINOK(res) + +#ifdef SUPPORT_LINKS + if (repraseMode) + { + _curSize = reparseSize; + _curSize_Defined = true; + if (needSetReparse) + { + // in Linux : we must delete empty file before symbolic link creation + // in Windows : we can create symbolic link even without file deleting + if (!DeleteFileAlways(_diskFilePath)) + { + RINOK(SendMessageError_with_LastError("can't delete file", _diskFilePath)) + } + { + bool linkWasSet = false; + // link.LinkPath = "r:\\1\\2"; // for debug + // link.isJunction = true; // for debug + link.Normalize_to_RelativeSafe(_removePathParts); + RINOK(SetLink(_diskFilePath, link, linkWasSet)) + if (linkWasSet) + _isSymLinkCreated = true; // link.IsSymLink(); + else + _needSetAttrib = false; + } + } + } +#endif // SUPPORT_LINKS + return res; +} + + +void CArchiveExtractCallback::SetAttrib() +{ + #ifndef _WIN32 + // Linux now doesn't support permissions for symlinks + if (_isSymLinkCreated) + return; + #endif + + if (_itemFailure + || _diskFilePath.IsEmpty() + || _stdOutMode + || !_extractMode) + return; + + #ifndef _WIN32 + if (_fi.Owner.Id_Defined && + _fi.Group.Id_Defined) + { + if (my_chown(_diskFilePath, _fi.Owner.Id, _fi.Group.Id) != 0) + { + SendMessageError_with_LastError("Cannot set owner", _diskFilePath); + } + } + #endif + + if (_fi.Attrib_Defined) + { + // const AString s = GetAnsiString(_diskFilePath); + // printf("\nSetFileAttrib_PosixHighDetect: %s: hex:%x\n", s.Ptr(), _fi.Attrib); + bool res = SetFileAttrib_PosixHighDetect(_diskFilePath, _fi.Attrib); + if (!res) + { + // do we need error message here in Windows and in posix? + SendMessageError_with_LastError("Cannot set file attribute", _diskFilePath); + } + } +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::SetOperationResult(Int32 opRes)) +{ + COM_TRY_BEGIN + + // printf("\nCArchiveExtractCallback::SetOperationResult: %d %s\n", opRes, GetAnsiString(_diskFilePath)); + + #ifndef Z7_SFX + if (ExtractToStreamCallback) + { + GetUnpackSize(); + return ExtractToStreamCallback->SetOperationResult8(opRes, BoolToInt(_encrypted), _curSize); + } + #endif + + #ifndef Z7_SFX + + if (_hashStreamWasUsed) + { + _hashStreamSpec->_hash->Final(_item.IsDir, + #ifdef SUPPORT_ALT_STREAMS + _item.IsAltStream + #else + false + #endif + , _item.Path); + _curSize = _hashStreamSpec->GetSize(); + _curSize_Defined = true; + _hashStreamSpec->ReleaseStream(); + _hashStreamWasUsed = false; + } + + #endif // Z7_SFX + + RINOK(CloseReparseAndFile()) + + #ifdef Z7_USE_SECURITY_CODE + if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) + { + const void *data; + UInt32 dataSize; + UInt32 propType; + _arc->GetRawProps->GetRawProp(_index, kpidNtSecure, &data, &dataSize, &propType); + if (dataSize != 0) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + if (CheckNtSecure((const Byte *)data, dataSize)) + { + SECURITY_INFORMATION securInfo = DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION; + if (_saclEnabled) + securInfo |= SACL_SECURITY_INFORMATION; + ::SetFileSecurityW(fs2us(_diskFilePath), securInfo, (PSECURITY_DESCRIPTOR)(void *)(const Byte *)(data)); + } + } + } + #endif // Z7_USE_SECURITY_CODE + + if (!_curSize_Defined) + GetUnpackSize(); + + if (_curSize_Defined) + { + #ifdef SUPPORT_ALT_STREAMS + if (_item.IsAltStream) + AltStreams_UnpackSize += _curSize; + else + #endif + UnpackSize += _curSize; + } + + if (_item.IsDir) + NumFolders++; + #ifdef SUPPORT_ALT_STREAMS + else if (_item.IsAltStream) + NumAltStreams++; + #endif + else + NumFiles++; + + if (_needSetAttrib) + SetAttrib(); + + RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))) + + return S_OK; + + COM_TRY_END +} + + + +Z7_COM7F_IMF(CArchiveExtractCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +{ + if (_folderArchiveExtractCallback2) + { + bool isEncrypted = false; + UString s; + + if (indexType == NArchive::NEventIndexType::kInArcIndex && index != (UInt32)(Int32)-1) + { + CReadArcItem item; + RINOK(_arc->GetItem(index, item)) + s = item.Path; + RINOK(Archive_GetItemBoolProp(_arc->Archive, index, kpidEncrypted, isEncrypted)) + } + else + { + s = '#'; + s.Add_UInt32(index); + // if (indexType == NArchive::NEventIndexType::kBlockIndex) {} + } + + return _folderArchiveExtractCallback2->ReportExtractResult(opRes, isEncrypted, s); + } + + return S_OK; +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)) +{ + COM_TRY_BEGIN + if (!_cryptoGetTextPassword) + { + RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, + &_cryptoGetTextPassword)) + } + return _cryptoGetTextPassword->CryptoGetTextPassword(password); + COM_TRY_END +} + + +#ifndef Z7_SFX + +// ---------- HASH functions ---------- + +FString CArchiveExtractCallback::Hash_GetFullFilePath() +{ + // this function changes _item.PathParts. + CorrectPathParts(); + const UStringVector &pathParts = _item.PathParts; + const UString processedPath (MakePathFromParts(pathParts)); + FString fullProcessedPath (us2fs(processedPath)); + if (_pathMode != NExtract::NPathMode::kAbsPaths + || !NName::IsAbsolutePath(processedPath)) + { + fullProcessedPath = MakePath_from_2_Parts( + DirPathPrefix_for_HashFiles, + // _dirPathPrefix, + fullProcessedPath); + } + return fullProcessedPath; +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::GetDiskProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (propID == kpidSize) + { + RINOK(GetItem(index)) + const FString fullProcessedPath = Hash_GetFullFilePath(); + NFile::NFind::CFileInfo fi; + if (fi.Find_FollowLink(fullProcessedPath)) + if (!fi.IsDir()) + prop = (UInt64)fi.Size; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) +{ + COM_TRY_BEGIN + *inStream = NULL; + // if (index != _index) return E_FAIL; + if (mode != NUpdateNotifyOp::kHashRead) + return E_FAIL; + + RINOK(GetItem(index)) + const FString fullProcessedPath = Hash_GetFullFilePath(); + + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamRef = inStreamSpec; + inStreamSpec->Set_PreserveATime(_ntOptions.PreserveATime); + if (!inStreamSpec->OpenShared(fullProcessedPath, _ntOptions.OpenShareForWrite)) + { + RINOK(SendMessageError_with_LastError(kCantOpenInFile, fullProcessedPath)) + return S_OK; + } + *inStream = inStreamRef.Detach(); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::ReportOperation( + UInt32 /* indexType */, UInt32 /* index */, UInt32 /* op */)) +{ + // COM_TRY_BEGIN + return S_OK; + // COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveExtractCallback::RequestMemoryUse( + UInt32 flags, UInt32 indexType, UInt32 index, const wchar_t *path, + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +{ + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + const UInt64 memLimit = _ntOptions.MemLimit; + if (memLimit != (UInt64)(Int64)-1) + { + // we overwrite allowedSize + *allowedSize = memLimit; + if (requiredSize <= memLimit) + { + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; + return S_OK; + } + *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded; + if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc; + flags |= NRequestMemoryUseFlags::k_SLimit_Exceeded + | NRequestMemoryUseFlags::k_AllowedSize_WasForced; + } + } + + if (!_requestMemoryUseCallback) + { + _extractCallback2.QueryInterface(IID_IArchiveRequestMemoryUseCallback, + &_requestMemoryUseCallback); + if (!_requestMemoryUseCallback) + { + // keep default (answerFlags) from caller or (answerFlags) that was set in this function + return S_OK; + } + } + +#if 0 + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + if (requiredSize <= *allowedSize) + { + // it's expected, that *answerFlags was set to NRequestMemoryAnswerFlags::k_Allow already, + // because it's default answer for (requiredSize <= *allowedSize) case. + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; // optional code + } + else + { + // we clear *answerFlags, because we want to disable dafault "Allow", if it's set. + // *answerFlags = 0; + /* + NRequestMemoryAnswerFlags::k_SkipArc | + NRequestMemoryAnswerFlags::k_Limit_Exceeded; + */ + } +#endif + + UString s; + if (!path + && indexType == NArchive::NEventIndexType::kInArcIndex + && index != (UInt32)(Int32)-1 + && _arc) + { + RINOK(_arc->GetItem_Path(index, s)) + path = s.Ptr(); + } + + return _requestMemoryUseCallback->RequestMemoryUse( + flags, indexType, index, path, + requiredSize, allowedSize, answerFlags); +} + +#endif // Z7_SFX + + + +// ------------ After Extracting functions ------------ + +void CDirPathSortPair::SetNumSlashes(const FChar *s) +{ + for (unsigned numSlashes = 0;;) + { + FChar c = *s++; + if (c == 0) + { + Len = numSlashes; + return; + } + if (IS_PATH_SEPAR(c)) + numSlashes++; + } +} + + +bool CDirPathTime::SetDirTime() const +{ + return NDir::SetDirTime(Path, + CTime_Defined ? &CTime : NULL, + ATime_Defined ? &ATime : NULL, + MTime_Defined ? &MTime : NULL); +} + + +HRESULT CArchiveExtractCallback::SetDirsTimes() +{ + if (!_arc) + return S_OK; + + CRecordVector pairs; + pairs.ClearAndSetSize(_extractedFolders.Size()); + unsigned i; + + for (i = 0; i < _extractedFolders.Size(); i++) + { + CDirPathSortPair &pair = pairs[i]; + pair.Index = i; + pair.SetNumSlashes(_extractedFolders[i].Path); + } + + pairs.Sort2(); + + HRESULT res = S_OK; + + for (i = 0; i < pairs.Size(); i++) + { + const CDirPathTime &dpt = _extractedFolders[pairs[i].Index]; + if (!dpt.SetDirTime()) + { + // result = E_FAIL; + // do we need error message here in Windows and in posix? + // SendMessageError_with_LastError("Cannot set directory time", dpt.Path); + } + } + + /* + #ifndef _WIN32 + for (i = 0; i < _delayedSymLinks.Size(); i++) + { + const CDelayedSymLink &link = _delayedSymLinks[i]; + if (!link.Create()) + { + if (res == S_OK) + res = GetLastError_noZero_HRESULT(); + // res = E_FAIL; + // do we need error message here in Windows and in posix? + SendMessageError_with_LastError("Cannot create Symbolic Link", link._source); + } + } + #endif // _WIN32 + */ + + ClearExtractedDirsInfo(); + return res; +} + + +HRESULT CArchiveExtractCallback::CloseArc() +{ + HRESULT res = CloseReparseAndFile(); + const HRESULT res2 = SetDirsTimes(); + if (res == S_OK) + res = res2; + _arc = NULL; + return res; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveExtractCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveExtractCallback.h 2015-11-09 15:37:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveExtractCallback.h 2025-06-16 11:00:00.000000000 +0000 @@ -1,342 +1,594 @@ -// ArchiveExtractCallback.h - -#ifndef __ARCHIVE_EXTRACT_CALLBACK_H -#define __ARCHIVE_EXTRACT_CALLBACK_H - -#include "../../../Common/MyCom.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" - -#include "../../IPassword.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/ProgressUtils.h" - -#include "../../Archive/IArchive.h" - -#include "ExtractMode.h" -#include "IFileExtractCallback.h" -#include "OpenArchive.h" - -#include "HashCalc.h" - -#ifndef _SFX - -class COutStreamWithHash: - public ISequentialOutStream, - public CMyUnknownImp -{ - CMyComPtr _stream; - UInt64 _size; - bool _calculate; -public: - IHashCalc *_hash; - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - void SetStream(ISequentialOutStream *stream) { _stream = stream; } - void ReleaseStream() { _stream.Release(); } - void Init(bool calculate = true) - { - InitCRC(); - _size = 0; - _calculate = calculate; - } - void EnableCalc(bool calculate) { _calculate = calculate; } - void InitCRC() { _hash->InitForNewFile(); } - UInt64 GetSize() const { return _size; } -}; - -#endif - -struct CExtractNtOptions -{ - CBoolPair NtSecurity; - CBoolPair SymLinks; - CBoolPair HardLinks; - CBoolPair AltStreams; - bool ReplaceColonForAltStream; - bool WriteToAltStreamIfColon; - - CExtractNtOptions(): - ReplaceColonForAltStream(false), - WriteToAltStreamIfColon(false) - { - SymLinks.Val = true; - HardLinks.Val = true; - AltStreams.Val = true; - } -}; - -#ifndef _SFX - -class CGetProp: - public IGetProp, - public CMyUnknownImp -{ -public: - const CArc *Arc; - UInt32 IndexInArc; - // UString Name; // relative path - - MY_UNKNOWN_IMP1(IGetProp) - INTERFACE_IGetProp(;) -}; - -#endif - -#if 0 // FIXME #ifndef _SFX -#ifndef UNDER_CE - -#define SUPPORT_LINKS - -#endif -#endif - - -#ifdef SUPPORT_LINKS - -struct CHardLinkNode -{ - UInt64 StreamId; - UInt64 INode; - - int Compare(const CHardLinkNode &a) const; -}; - -class CHardLinks -{ -public: - CRecordVector IDs; - CObjectVector Links; - - void Clear() - { - IDs.Clear(); - Links.Clear(); - } - - void PrepareLinks() - { - while (Links.Size() < IDs.Size()) - Links.AddNew(); - } -}; - -#endif - -#ifdef SUPPORT_ALT_STREAMS - -struct CIndexToPathPair -{ - UInt32 Index; - FString Path; - - CIndexToPathPair(UInt32 index): Index(index) {} - CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {} - - int Compare(const CIndexToPathPair &pair) const - { - return MyCompare(Index, pair.Index); - } -}; - -#endif - -class CArchiveExtractCallback: - public IArchiveExtractCallback, - public IArchiveExtractCallbackMessage, - public ICryptoGetTextPassword, - public ICompressProgressInfo, - public CMyUnknownImp -{ - const CArc *_arc; - CExtractNtOptions _ntOptions; - - const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) - CMyComPtr _extractCallback2; - CMyComPtr _compressProgress; - CMyComPtr _cryptoGetTextPassword; - CMyComPtr _callbackMessage; - CMyComPtr _folderArchiveExtractCallback2; - - FString _dirPathPrefix; - FString _dirPathPrefix_Full; - NExtract::NPathMode::EEnum _pathMode; - NExtract::NOverwriteMode::EEnum _overwriteMode; - - #ifndef _SFX - - CMyComPtr ExtractToStreamCallback; - CGetProp *GetProp_Spec; - CMyComPtr GetProp; - - #endif - - CReadArcItem _item; - FString _diskFilePath; - UInt64 _position; - bool _isSplit; - - bool _extractMode; - - bool WriteCTime; - bool WriteATime; - bool WriteMTime; - - bool _encrypted; - - struct CProcessedFileInfo - { - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UInt32 Attrib; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool AttribDefined; - } _fi; - - UInt32 _index; - UInt64 _curSize; - bool _curSizeDefined; - COutFileStream *_outFileStreamSpec; - CMyComPtr _outFileStream; - - #ifndef _SFX - - COutStreamWithHash *_hashStreamSpec; - CMyComPtr _hashStream; - bool _hashStreamWasUsed; - - #endif - - bool _removePartsForAltStreams; - UStringVector _removePathParts; - - #ifndef _SFX - bool _use_baseParentFolder_mode; - UInt32 _baseParentFolder; - #endif - - bool _stdOutMode; - bool _testMode; - bool _multiArchives; - - CMyComPtr _localProgress; - UInt64 _packTotal; - - UInt64 _progressTotal; - bool _progressTotal_Defined; - - FStringVector _extractedFolderPaths; - CRecordVector _extractedFolderIndices; - - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(_SFX) - bool _saclEnabled; - #endif - - CObjectVector _delayedSymLinks; - - void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); - HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); - HRESULT GetUnpackSize(); - - HRESULT SendMessageError(const char *message, const FString &path); - HRESULT SendMessageError_with_LastError(const char *message, const FString &path); - HRESULT SendMessageError2(const char *message, const FString &path1, const FString &path2); - -public: - - CLocalProgress *LocalProgressSpec; - - UInt64 NumFolders; - UInt64 NumFiles; - UInt64 NumAltStreams; - UInt64 UnpackSize; - UInt64 AltStreams_UnpackSize; - - MY_UNKNOWN_IMP3(IArchiveExtractCallbackMessage, ICryptoGetTextPassword, ICompressProgressInfo) - - INTERFACE_IArchiveExtractCallback(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - CArchiveExtractCallback(); - - void InitForMulti(bool multiArchives, - NExtract::NPathMode::EEnum pathMode, - NExtract::NOverwriteMode::EEnum overwriteMode) - { - _multiArchives = multiArchives; - _pathMode = pathMode; - _overwriteMode = overwriteMode; - NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; - } - - #ifndef _SFX - - void SetHashMethods(IHashCalc *hash) - { - if (!hash) - return; - _hashStreamSpec = new COutStreamWithHash; - _hashStream = _hashStreamSpec; - _hashStreamSpec->_hash = hash; - } - - #endif - - void Init( - const CExtractNtOptions &ntOptions, - const NWildcard::CCensorNode *wildcardCensor, - const CArc *arc, - IFolderArchiveExtractCallback *extractCallback2, - bool stdOutMode, bool testMode, - const FString &directoryPath, - const UStringVector &removePathParts, bool removePartsForAltStreams, - UInt64 packSize); - - - #ifdef SUPPORT_LINKS - -private: - CHardLinks _hardLinks; - UString linkPath; - - // FString _CopyFile_Path; - // HRESULT MyCopyFile(ISequentialOutStream *outStream); - -public: - // call PrepareHardLinks() after Init() - HRESULT PrepareHardLinks(const CRecordVector *realIndices); // NULL means all items - - #endif - - - #ifdef SUPPORT_ALT_STREAMS - CObjectVector _renamedFiles; - #endif - - // call it after Init() - - #ifndef _SFX - void SetBaseParentFolderIndex(UInt32 indexInArc) - { - _baseParentFolder = indexInArc; - _use_baseParentFolder_mode = true; - } - #endif - - HRESULT SetDirsTimes(); -}; - -bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); - -#endif +// ArchiveExtractCallback.h + +#ifndef ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H +#define ZIP7_INC_ARCHIVE_EXTRACT_CALLBACK_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyLinux.h" +#include "../../../Common/Wildcard.h" + +#include "../../IPassword.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" + +#include "../../Archive/IArchive.h" + +#include "ExtractMode.h" +#include "IFileExtractCallback.h" +#include "OpenArchive.h" + +#include "HashCalc.h" + +#ifndef Z7_SFX + +Z7_CLASS_IMP_NOQIB_1( + COutStreamWithHash + , ISequentialOutStream +) + bool _calculate; + CMyComPtr _stream; + UInt64 _size; +public: + IHashCalc *_hash; + + void SetStream(ISequentialOutStream *stream) { _stream = stream; } + void ReleaseStream() { _stream.Release(); } + void Init(bool calculate = true) + { + InitCRC(); + _size = 0; + _calculate = calculate; + } + void EnableCalc(bool calculate) { _calculate = calculate; } + void InitCRC() { _hash->InitForNewFile(); } + UInt64 GetSize() const { return _size; } +}; + +#endif + +struct CExtractNtOptions +{ + CBoolPair NtSecurity; + CBoolPair SymLinks; + CBoolPair SymLinks_AllowDangerous; + CBoolPair HardLinks; + CBoolPair AltStreams; + bool ReplaceColonForAltStream; + bool WriteToAltStreamIfColon; + + bool ExtractOwner; + + bool PreAllocateOutFile; + + // used for hash arcs only, when we open external files + bool PreserveATime; + bool OpenShareForWrite; + + UInt64 MemLimit; + + CExtractNtOptions(): + ReplaceColonForAltStream(false), + WriteToAltStreamIfColon(false), + ExtractOwner(false), + PreserveATime(false), + OpenShareForWrite(false), + MemLimit((UInt64)(Int64)-1) + { + SymLinks.Val = true; + SymLinks_AllowDangerous.Val = false; + HardLinks.Val = true; + AltStreams.Val = true; + + PreAllocateOutFile = + #ifdef _WIN32 + true; + #else + false; + #endif + } +}; + + +#ifndef Z7_SFX +#ifndef UNDER_CE +#define SUPPORT_LINKS +#endif +#endif + + +#ifdef SUPPORT_LINKS + +struct CHardLinkNode +{ + UInt64 StreamId; + UInt64 INode; + + int Compare(const CHardLinkNode &a) const; +}; + +class CHardLinks +{ +public: + CRecordVector IDs; + CObjectVector Links; + + void Clear() + { + IDs.Clear(); + Links.Clear(); + } + + void PrepareLinks() + { + while (Links.Size() < IDs.Size()) + Links.AddNew(); + } +}; + +#endif + +#ifdef SUPPORT_ALT_STREAMS + +struct CIndexToPathPair +{ + UInt32 Index; + FString Path; + + CIndexToPathPair(UInt32 index): Index(index) {} + CIndexToPathPair(UInt32 index, const FString &path): Index(index), Path(path) {} + + int Compare(const CIndexToPathPair &pair) const + { + return MyCompare(Index, pair.Index); + } +}; + +#endif + + + +struct CFiTimesCAM +{ + CFiTime CTime; + CFiTime ATime; + CFiTime MTime; + + bool CTime_Defined; + bool ATime_Defined; + bool MTime_Defined; + + bool IsSomeTimeDefined() const + { + return + CTime_Defined | + ATime_Defined | + MTime_Defined; + } +}; + +struct CDirPathTime: public CFiTimesCAM +{ + FString Path; + + bool SetDirTime() const; +}; + + +#ifdef SUPPORT_LINKS + + +enum ELinkType +{ + k_LinkType_HardLink, + k_LinkType_PureSymLink, + k_LinkType_Junction, + k_LinkType_WSL + // , k_LinkType_CopyLink; +}; + + +struct CLinkInfo +{ + ELinkType LinkType; + bool isRelative; + // if (isRelative == false), then (LinkPath) is relative to root folder of archive + // if (isRelative == true ), then (LinkPath) is relative to current item + bool isWindowsPath; + UString LinkPath; + + bool Is_HardLink() const { return LinkType == k_LinkType_HardLink; } + bool Is_AnySymLink() const { return LinkType != k_LinkType_HardLink; } + + bool Is_WSL() const { return LinkType == k_LinkType_WSL; } + + CLinkInfo(): + LinkType(k_LinkType_PureSymLink), + isRelative(false), + isWindowsPath(false) + {} + + void Clear() + { + LinkType = k_LinkType_PureSymLink; + isRelative = false; + isWindowsPath = false; + LinkPath.Empty(); + } + + bool Parse_from_WindowsReparseData(const Byte *data, size_t dataSize); + bool Parse_from_LinuxData(const Byte *data, size_t dataSize); + void Normalize_to_RelativeSafe(UStringVector &removePathParts); +private: + void Remove_AbsPathPrefixes(); +}; + +#endif // SUPPORT_LINKS + + +#ifndef _WIN32 + +struct COwnerInfo +{ + bool Id_Defined; + UInt32 Id; + AString Name; + + void Clear() + { + Id_Defined = false; + Id = 0; + Name.Empty(); + } +}; + +#endif + + +class CArchiveExtractCallback Z7_final: + public IArchiveExtractCallback, + public IArchiveExtractCallbackMessage2, + public ICryptoGetTextPassword, + public ICompressProgressInfo, +#ifndef Z7_SFX + public IArchiveUpdateCallbackFile, + public IArchiveGetDiskProperty, + public IArchiveRequestMemoryUseCallback, +#endif + public CMyUnknownImp +{ + /* IArchiveExtractCallback, */ + Z7_COM_QI_BEGIN2(IArchiveExtractCallbackMessage2) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + Z7_COM_QI_ENTRY(ICompressProgressInfo) +#ifndef Z7_SFX + Z7_COM_QI_ENTRY(IArchiveUpdateCallbackFile) + Z7_COM_QI_ENTRY(IArchiveGetDiskProperty) + Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback) +#endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveExtractCallback) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) +#ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + Z7_IFACE_COM7_IMP(IArchiveGetDiskProperty) + Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) +#endif + + // bool Write_CTime; + // bool Write_ATime; + // bool Write_MTime; + bool _stdOutMode; + bool _testMode; + bool _removePartsForAltStreams; +public: + bool Is_elimPrefix_Mode; +private: + + const CArc *_arc; + CExtractNtOptions _ntOptions; + + bool _encrypted; + bool _isSplit; + bool _curSize_Defined; + bool _fileLength_WasSet; + + bool _isRenamed; + bool _extractMode; + bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX. + // _is_SymLink_in_Data_Linux is detected from Windows/Linux part of attributes of file. + bool _needSetAttrib; + bool _isSymLinkCreated; + bool _itemFailure; + bool _some_pathParts_wereRemoved; + + bool _multiArchives; + bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + bool _saclEnabled; +#endif + + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; + + CMyComPtr _extractCallback2; + const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) + // CMyComPtr _compressProgress; + // CMyComPtr _callbackMessage; + CMyComPtr _folderArchiveExtractCallback2; + CMyComPtr _cryptoGetTextPassword; + + FString _dirPathPrefix; + FString _dirPathPrefix_Full; + + #ifndef Z7_SFX + + CMyComPtr ExtractToStreamCallback; + CMyComPtr _requestMemoryUseCallback; + + #endif + + CReadArcItem _item; + FString _diskFilePath; + + struct CProcessedFileInfo + { + CArcTime CTime; + CArcTime ATime; + CArcTime MTime; + UInt32 Attrib; + bool Attrib_Defined; + + #ifndef _WIN32 + COwnerInfo Owner; + COwnerInfo Group; + #endif + + bool IsReparse() const + { + return (Attrib_Defined && (Attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0); + } + + bool IsLinuxSymLink() const + { + return (Attrib_Defined && MY_LIN_S_ISLNK(Attrib >> 16)); + } + + void SetFromPosixAttrib(UInt32 a) + { + // here we set only part of combined attribute required by SetFileAttrib() call + #ifdef _WIN32 + // Windows sets FILE_ATTRIBUTE_NORMAL, if we try to set 0 as attribute. + Attrib = MY_LIN_S_ISDIR(a) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + if ((a & 0222) == 0) // (& S_IWUSR) in p7zip + Attrib |= FILE_ATTRIBUTE_READONLY; + // 22.00 : we need type bits for (MY_LIN_S_IFLNK) for IsLinuxSymLink() + a &= MY_LIN_S_IFMT; + if (a == MY_LIN_S_IFLNK) + Attrib |= (a << 16); + #else + Attrib = (a << 16) | FILE_ATTRIBUTE_UNIX_EXTENSION; + #endif + Attrib_Defined = true; + } + } _fi; + + UInt64 _position; + UInt64 _curSize; + UInt64 _fileLength_that_WasSet; + UInt32 _index; + +// #ifdef SUPPORT_ALT_STREAMS +#if defined(_WIN32) && !defined(UNDER_CE) + DWORD _altStream_NeedRestore_AttribVal; + FString _altStream_NeedRestore_Attrib_for_parentFsPath; +#endif +// #endif + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + + CByteBuffer _outMemBuf; + CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec; + CMyComPtr _bufPtrSeqOutStream; + + #ifndef Z7_SFX + COutStreamWithHash *_hashStreamSpec; + CMyComPtr _hashStream; + bool _hashStreamWasUsed; + + bool _use_baseParentFolder_mode; + UInt32 _baseParentFolder; + #endif + + UStringVector _removePathParts; + + UInt64 _packTotal; + UInt64 _progressTotal; + // bool _progressTotal_Defined; + + CObjectVector _extractedFolders; + + #ifndef _WIN32 + // CObjectVector _delayedSymLinks; + #endif + + void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); + HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); + HRESULT GetUnpackSize(); + + FString Hash_GetFullFilePath(); + + void SetAttrib(); + +public: + HRESULT SendMessageError(const char *message, const FString &path); + HRESULT SendMessageError_with_Error(HRESULT errorCode, const char *message, const FString &path); + HRESULT SendMessageError_with_LastError(const char *message, const FString &path); + HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); + HRESULT SendMessageError2_with_LastError(const char *message, const FString &path1, const FString &path2); + +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + NExtract::NZoneIdMode::EEnum ZoneMode; + CByteBuffer ZoneBuf; +#endif + + CMyComPtr2_Create LocalProgressSpec; + + UInt64 NumFolders; + UInt64 NumFiles; + UInt64 NumAltStreams; + UInt64 UnpackSize; + UInt64 AltStreams_UnpackSize; + + FString DirPathPrefix_for_HashFiles; + + 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) && !defined(Z7_SFX) + ZoneMode = zoneMode; +#else + UNUSED_VAR(zoneMode) +#endif + _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; + NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; + } + + #ifndef Z7_SFX + + void SetHashMethods(IHashCalc *hash) + { + if (!hash) + return; + _hashStreamSpec = new COutStreamWithHash; + _hashStream = _hashStreamSpec; + _hashStreamSpec->_hash = hash; + } + + #endif + + void InitBeforeNewArchive(); + + void Init( + const CExtractNtOptions &ntOptions, + const NWildcard::CCensorNode *wildcardCensor, + const CArc *arc, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, bool testMode, + const FString &directoryPath, + const UStringVector &removePathParts, bool removePartsForAltStreams, + UInt64 packSize); + + + #ifdef SUPPORT_LINKS + +private: + CHardLinks _hardLinks; + CLinkInfo _link; + // const void *NtReparse_Data; + // UInt32 NtReparse_Size; + + // FString _copyFile_Path; + // HRESULT MyCopyFile(ISequentialOutStream *outStream); + HRESULT ReadLink(); + HRESULT SetLink( + const FString &fullProcessedPath_from, + const CLinkInfo &linkInfo, + bool &linkWasSet); + +public: + // call PrepareHardLinks() after Init() + HRESULT PrepareHardLinks(const CRecordVector *realIndices); // NULL means all items + + #endif + + + #ifdef SUPPORT_ALT_STREAMS + CObjectVector _renamedFiles; + #endif + + // call it after Init() + + #ifndef Z7_SFX + void SetBaseParentFolderIndex(UInt32 indexInArc) + { + _baseParentFolder = indexInArc; + _use_baseParentFolder_mode = true; + } + #endif + + HRESULT CloseArc(); + +private: + void ClearExtractedDirsInfo() + { + _extractedFolders.Clear(); + #ifndef _WIN32 + // _delayedSymLinks.Clear(); + #endif + } + + HRESULT Read_fi_Props(); + void CorrectPathParts(); + void GetFiTimesCAM(CFiTimesCAM &pt); + void CreateFolders(); + + HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit); + HRESULT GetExtractStream(CMyComPtr &outStreamLoc, bool &needExit); + HRESULT GetItem(UInt32 index); + + HRESULT CloseFile(); + HRESULT CloseReparseAndFile(); + HRESULT CloseReparseAndFile2(); + HRESULT SetDirsTimes(); +}; + + +struct CArchiveExtractCallback_Closer +{ + CArchiveExtractCallback *_ref; + + CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {} + + HRESULT Close() + { + HRESULT res = S_OK; + if (_ref) + { + res = _ref->CloseArc(); + _ref = NULL; + } + return res; + } + + ~CArchiveExtractCallback_Closer() + { + Close(); + } +}; + + +bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); + +bool Is_ZoneId_StreamName(const wchar_t *s); +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf); +bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveName.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveName.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,78 +1,176 @@ -// ArchiveName.cpp - -#include "StdAfx.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" - -#include "ExtractingFilePath.h" -#include "ArchiveName.h" - -using namespace NWindows; -using namespace NFile; - -UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName) -{ - FString resultName = fi.Name; - if (!fi.IsDir() && !keepName) - { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) - { - FString archiveName2 = resultName.Left(dotPos); - if (archiveName2.ReverseFind_Dot() < 0) - resultName = archiveName2; - } - } - return Get_Correct_FsFile_Name(fs2us(resultName)); -} - -static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepName) -{ - FString resultName = FTEXT("Archive"); - if (fromPrev) - { - FString dirPrefix; - if (NDir::GetOnlyDirPrefix(path, dirPrefix)) - { - if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) - { - #if defined(_WIN32) && !defined(UNDER_CE) - if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) - resultName = dirPrefix[dirPrefix.Len() - 3]; // only letter - else - #endif - { - dirPrefix.DeleteBack(); - NFind::CFileInfo fi; - if (fi.Find(dirPrefix)) - resultName = fi.Name; - } - } - } - } - else - { - NFind::CFileInfo fi; - if (fi.Find(path)) - { - resultName = fi.Name; - if (!fi.IsDir() && !keepName) - { - int dotPos = resultName.ReverseFind_Dot(); - if (dotPos > 0) - { - FString name2 = resultName.Left(dotPos); - if (name2.ReverseFind_Dot() < 0) - resultName = name2; - } - } - } - } - return resultName; -} - -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName) -{ - return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName))); -} +// ArchiveName.cpp + +#include "StdAfx.h" + +#include "../../../../C/Sort.h" + +#include "../../../Common/Wildcard.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" + +#include "ArchiveName.h" +#include "ExtractingFilePath.h" + +using namespace NWindows; +using namespace NFile; + + +static const char *g_ArcExts = + "7z" + "\0" "zip" + "\0" "tar" + "\0" "wim" + "\0"; + +static const char *g_HashExts = + "sha256" + "\0"; + + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NFind::CFileInfo *fi, + UString &baseName) +{ + bool keepName = isHash; + /* + if (paths.Size() == 1) + { + const UString &name = paths[0]; + if (name.Len() > 4) + if (CompareFileNames(name.RightPtr(4), L".tar") == 0) + keepName = true; + } + */ + + UString name ("Archive"); + NFind::CFileInfo fi3; + if (paths.Size() > 1) + fi = NULL; + if (!fi && paths.Size() != 0) + { + const UString &path = paths.Front(); + if (paths.Size() == 1) + { + if (fi3.Find(us2fs(path))) + fi = &fi3; + } + else + { + // we try to use name of parent folder + FString dirPrefix; + if (NDir::GetOnlyDirPrefix(us2fs(path), dirPrefix)) + { + if (!dirPrefix.IsEmpty() && IsPathSepar(dirPrefix.Back())) + { + #if defined(_WIN32) && !defined(UNDER_CE) + if (NName::IsDriveRootPath_SuperAllowed(dirPrefix)) + { + if (path != fs2us(dirPrefix)) + name = dirPrefix[dirPrefix.Len() - 3]; // only letter + } + else + #endif + { + dirPrefix.DeleteBack(); + if (!dirPrefix.IsEmpty()) + { + const int slash = dirPrefix.ReverseFind_PathSepar(); + if (slash >= 0 && slash != (int)dirPrefix.Len() - 1) + name = dirPrefix.Ptr(slash + 1); + else if (fi3.Find(dirPrefix)) + name = fs2us(fi3.Name); + } + } + } + } + } + } + + if (fi) + { + name = fs2us(fi->Name); + if (!fi->IsDir() && !keepName) + { + const int dotPos = name.Find(L'.'); + if (dotPos > 0 && name.Find(L'.', (unsigned)dotPos + 1) < 0) + name.DeleteFrom((unsigned)dotPos); + } + } + name = Get_Correct_FsFile_Name(name); + + CRecordVector ids; + bool simple_IsAllowed = true; + // for (int y = 0; y < 10000; y++) // for debug + { + // ids.Clear(); + UString n; + + FOR_VECTOR (i, paths) + { + const UString &a = paths[i]; + const int slash = a.ReverseFind_PathSepar(); + // if (name.Len() >= a.Len() - slash + 1) continue; + const wchar_t *s = a.Ptr(slash + 1); + if (!IsPath1PrefixedByPath2(s, name)) + continue; + s += name.Len(); + const char *exts = isHash ? g_HashExts : g_ArcExts; + + for (;;) + { + const char *ext = exts; + const unsigned len = MyStringLen(ext); + if (len == 0) + break; + exts += len + 1; + n = s; + if (n.Len() <= len) + continue; + if (!StringsAreEqualNoCase_Ascii(n.RightPtr(len), ext)) + continue; + n.DeleteFrom(n.Len() - len); + if (n.Back() != '.') + continue; + n.DeleteBack(); + if (n.IsEmpty()) + { + simple_IsAllowed = false; + break; + } + if (n.Len() < 2) + continue; + if (n[0] != '_') + continue; + const wchar_t *end; + const UInt32 v = ConvertStringToUInt32(n.Ptr(1), &end); + if (*end != 0) + continue; + ids.Add(v); + break; + } + } + } + + baseName = name; + if (!simple_IsAllowed) + { + HeapSort(ids.NonConstData(), ids.Size()); + UInt32 v = 2; + const unsigned num = ids.Size(); + for (unsigned i = 0; i < num; i++) + { + const UInt32 id = ids[i]; + if (id > v) + break; + if (id == v) + v = id + 1; + } + name.Add_Char('_'); + name.Add_UInt32(v); + } + return name; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveName.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveName.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveName.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,13 +1,16 @@ -// ArchiveName.h - -#ifndef __ARCHIVE_NAME_H -#define __ARCHIVE_NAME_H - -#include "../../../Common/MyString.h" - -#include "../../../Windows/FileFind.h" - -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName); -UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName); - -#endif +// ArchiveName.h + +#ifndef ZIP7_INC_ARCHIVE_NAME_H +#define ZIP7_INC_ARCHIVE_NAME_H + +#include "../../../Windows/FileFind.h" + +/* (fi != NULL) only if (paths.Size() == 1) */ + +UString CreateArchiveName( + const UStringVector &paths, + bool isHash, + const NWindows::NFile::NFind::CFileInfo *fi, + UString &baseName); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 2016-05-18 17:50:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp 2024-04-02 12:00:00.000000000 +0000 @@ -1,156 +1,398 @@ -// ArchiveOpenCallback.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" - -#include "../../Common/FileStreams.h" - -#include "ArchiveOpenCallback.h" - -using namespace NWindows; - -STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) -{ - COM_TRY_BEGIN - if (ReOpenCallback) - return ReOpenCallback->SetTotal(files, bytes); - if (!Callback) - return S_OK; - return Callback->Open_SetTotal(files, bytes); - COM_TRY_END -} - -STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) -{ - COM_TRY_BEGIN - if (ReOpenCallback) - return ReOpenCallback->SetCompleted(files, bytes); - if (!Callback) - return S_OK; - return Callback->Open_SetCompleted(files, bytes); - COM_TRY_END -} - -STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - if (_subArchiveMode) - switch (propID) - { - case kpidName: prop = _subArchiveName; break; - // case kpidSize: prop = _subArchiveSize; break; // we don't use it now - } - else - switch (propID) - { - case kpidName: prop = _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; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -struct CInFileStreamVol: public CInFileStream -{ - int FileNameIndex; - COpenCallbackImp *OpenCallbackImp; - CMyComPtr OpenCallbackRef; - - CInFileStreamVol() : CInFileStream(true) { } - - ~CInFileStreamVol() - { - if (OpenCallbackRef) - OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false; - } -}; - - -// from ArchiveExtractCallback.cpp -bool IsSafePath(const UString &path); - -STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) -{ - COM_TRY_BEGIN - *inStream = NULL; - - if (_subArchiveMode) - return S_FALSE; - if (Callback) - { - RINOK(Callback->Open_CheckBreak()); - } - - UString name2 = name; - - - #ifndef _SFX - - #ifdef _WIN32 - name2.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - - // if (!allowAbsVolPaths) - if (!IsSafePath(name2)) - return S_FALSE; - - #endif - - - FString fullPath; - if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath)) - return S_FALSE; - if (!_fileInfo.Find(fullPath,true)) - return S_FALSE; - if (_fileInfo.IsDir()) - return S_FALSE; - CInFileStreamVol *inFile = new CInFileStreamVol; - CMyComPtr inStreamTemp = inFile; - if (!inFile->Open(fullPath)) - { - DWORD lastError = ::GetLastError(); - if (lastError == 0) - return E_FAIL; - return HRESULT_FROM_WIN32(lastError); - } - - FileSizes.Add(_fileInfo.Size); - FileNames.Add(name2); - inFile->FileNameIndex = FileNames_WasUsed.Add(true); - inFile->OpenCallbackImp = this; - inFile->OpenCallbackRef = this; - // TotalSize += _fileInfo.Size; - *inStream = inStreamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -#ifndef _NO_CRYPTO -STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - if (ReOpenCallback) - { - CMyComPtr getTextPassword; - ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword); - if (getTextPassword) - return getTextPassword->CryptoGetTextPassword(password); - } - if (!Callback) - return E_NOTIMPL; - PasswordWasAsked = true; - return Callback->Open_CryptoGetTextPassword(password); - COM_TRY_END -} -#endif +// ArchiveOpenCallback.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/System.h" + +#include "../../Common/StreamUtils.h" + +#include "ArchiveOpenCallback.h" + +// #define DEBUG_VOLUMES + +#ifdef DEBUG_VOLUMES +#include +#endif + + +#ifdef DEBUG_VOLUMES + #define PRF(x) x +#else + #define PRF(x) +#endif + +using namespace NWindows; + +HRESULT COpenCallbackImp::Init2(const FString &folderPrefix, const FString &fileName) +{ + Volumes.Init(); + FileNames.Clear(); + FileNames_WasUsed.Clear(); + FileSizes.Clear(); + _subArchiveMode = false; + // TotalSize = 0; + PasswordWasAsked = false; + _folderPrefix = folderPrefix; + if (!_fileInfo.Find_FollowLink(_folderPrefix + fileName)) + { + // throw 20121118; + return GetLastError_noZero_HRESULT(); + } + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetSubArchiveName(const wchar_t *name)) +{ + _subArchiveMode = true; + _subArchiveName = name; + // TotalSize = 0; + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)) +{ + COM_TRY_BEGIN + if (ReOpenCallback) + return ReOpenCallback->SetTotal(files, bytes); + if (!Callback) + return S_OK; + return Callback->Open_SetTotal(files, bytes); + COM_TRY_END +} + +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)) +{ + COM_TRY_BEGIN + if (ReOpenCallback) + return ReOpenCallback->SetCompleted(files, bytes); + if (!Callback) + return S_OK; + return Callback->Open_SetCompleted(files, bytes); + COM_TRY_END +} + + +Z7_COM7F_IMF(COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + if (_subArchiveMode) + switch (propID) + { + case kpidName: prop = _subArchiveName; break; + // case kpidSize: prop = _subArchiveSize; break; // we don't use it now + default: break; + } + else + switch (propID) + { + case kpidName: prop = fs2us(_fileInfo.Name); break; + case kpidIsDir: prop = _fileInfo.IsDir(); break; + case kpidSize: prop = _fileInfo.Size; 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; + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +// ---------- CInFileStreamVol ---------- + +Z7_class_final(CInFileStreamVol): + public IInStream + , public IStreamGetSize + , public CMyUnknownImp +{ + Z7_IFACES_IMP_UNK_3( + IInStream, + ISequentialInStream, + IStreamGetSize) +public: + unsigned FileIndex; + COpenCallbackImp *OpenCallbackImp; + CMyComPtr OpenCallbackRef; + + HRESULT EnsureOpen() + { + return OpenCallbackImp->Volumes.EnsureOpen(FileIndex); + } + + ~CInFileStreamVol() + { + if (OpenCallbackRef) + OpenCallbackImp->AtCloseFile(FileIndex); + } +}; + + +void CMultiStreams::InsertToList(unsigned index) +{ + { + CSubStream &s = Streams[index]; + s.Next = Head; + s.Prev = -1; + } + if (Head != -1) + Streams[(unsigned)Head].Prev = (int)index; + else + { + // if (Tail != -1) throw 1; + Tail = (int)index; + } + Head = (int)index; + NumListItems++; +} + +// s must bee in List +void CMultiStreams::RemoveFromList(CSubStream &s) +{ + if (s.Next != -1) Streams[(unsigned)s.Next].Prev = s.Prev; else Tail = s.Prev; + if (s.Prev != -1) Streams[(unsigned)s.Prev].Next = s.Next; else Head = s.Next; + s.Next = -1; // optional + s.Prev = -1; // optional + NumListItems--; +} + +void CMultiStreams::CloseFile(unsigned index) +{ + CSubStream &s = Streams[index]; + if (s.Stream) + { + s.Stream.Release(); + RemoveFromList(s); + // s.InFile->Close(); + // s.IsOpen = false; + #ifdef DEBUG_VOLUMES + static int numClosing = 0; + numClosing++; + printf("\nCloseFile %u, total_closes = %u, num_open_files = %u\n", index, numClosing, NumListItems); + #endif + } +} + +void CMultiStreams::Init() +{ + Head = -1; + Tail = -1; + NumListItems = 0; + Streams.Clear(); +} + +CMultiStreams::CMultiStreams(): + Head(-1), + Tail(-1), + NumListItems(0) +{ + NumOpenFiles_AllowedMax = NSystem::Get_File_OPEN_MAX_Reduced_for_3_tasks(); + PRF(printf("\nNumOpenFiles_Limit = %u\n", NumOpenFiles_AllowedMax)); +} + + +HRESULT CMultiStreams::PrepareToOpenNew() +{ + if (NumListItems < NumOpenFiles_AllowedMax) + return S_OK; + if (Tail == -1) + return E_FAIL; + CMultiStreams::CSubStream &tailStream = Streams[(unsigned)Tail]; + RINOK(InStream_GetPos(tailStream.Stream, tailStream.LocalPos)) + CloseFile((unsigned)Tail); + return S_OK; +} + + +HRESULT CMultiStreams::EnsureOpen(unsigned index) +{ + CMultiStreams::CSubStream &s = Streams[index]; + if (s.Stream) + { + if ((int)index != Head) + { + RemoveFromList(s); + InsertToList(index); + } + } + else + { + RINOK(PrepareToOpenNew()) + { + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(s.Path)) + return GetLastError_noZero_HRESULT(); + s.FileSpec = inFile; + s.Stream = s.FileSpec; + InsertToList(index); + } + // s.IsOpen = true; + if (s.LocalPos != 0) + { + RINOK(s.Stream->Seek((Int64)s.LocalPos, STREAM_SEEK_SET, &s.LocalPos)) + } + #ifdef DEBUG_VOLUMES + static int numOpens = 0; + numOpens++; + printf("\n-- %u, ReOpen, total_reopens = %u, num_open_files = %u\n", index, numOpens, NumListItems); + #endif + } + return S_OK; +} + + +Z7_COM7F_IMF(CInFileStreamVol::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n== %u, Read =%u \n", FileIndex, size)); + return s.Stream->Read(data, size, processedSize); +} + +Z7_COM7F_IMF(CInFileStreamVol::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) +{ + // if (seekOrigin >= 3) return STG_E_INVALIDFUNCTION; + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + PRF(printf("\n-- %u, Seek seekOrigin=%u Seek =%u\n", FileIndex, seekOrigin, (unsigned)offset)); + return s.Stream->Seek(offset, seekOrigin, newPosition); +} + +Z7_COM7F_IMF(CInFileStreamVol::GetSize(UInt64 *size)) +{ + RINOK(EnsureOpen()) + CMultiStreams::CSubStream &s = OpenCallbackImp->Volumes.Streams[FileIndex]; + return s.FileSpec->GetSize(size); +} + + +// from ArchiveExtractCallback.cpp +bool IsSafePath(const UString &path); + +Z7_COM7F_IMF(COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)) +{ + COM_TRY_BEGIN + *inStream = NULL; + + if (_subArchiveMode) + return S_FALSE; + if (Callback) + { + RINOK(Callback->Open_CheckBreak()) + } + + UString name2 = name; + + + #ifndef Z7_SFX + + #ifdef _WIN32 + name2.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + + // if (!allowAbsVolPaths) + if (!IsSafePath(name2)) + return S_FALSE; + + #ifdef _WIN32 + /* WIN32 allows wildcards in Find() function + and doesn't allow wildcard in File.Open() + so we can work without the following wildcard check here */ + if (name2.Find(L'*') >= 0) + return S_FALSE; + { + unsigned startPos = 0; + if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\")) + startPos = 3; + if (name2.Find(L'?', startPos) >= 0) + return S_FALSE; + } + #endif + + #endif + + + FString fullPath; + if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath)) + return S_FALSE; + if (!_fileInfo.Find_FollowLink(fullPath)) + return S_FALSE; + if (_fileInfo.IsDir()) + return S_FALSE; + + CMultiStreams::CSubStream s; + + { + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return GetLastError_noZero_HRESULT(); + RINOK(Volumes.PrepareToOpenNew()) + s.FileSpec = inFile; + s.Stream = s.FileSpec; + s.Path = fullPath; + // s.Size = _fileInfo.Size; + // s.IsOpen = true; + } + + const unsigned fileIndex = Volumes.Streams.Add(s); + Volumes.InsertToList(fileIndex); + + FileSizes.Add(_fileInfo.Size); + FileNames.Add(name2); + FileNames_WasUsed.Add(true); + + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr inStreamTemp = inFile; + inFile->FileIndex = fileIndex; + inFile->OpenCallbackImp = this; + inFile->OpenCallbackRef = this; + // TotalSize += _fileInfo.Size; + *inStream = inStreamTemp.Detach(); + return S_OK; + COM_TRY_END +} + + +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(COpenCallbackImp::CryptoGetTextPassword(BSTR *password)) +{ + COM_TRY_BEGIN + if (ReOpenCallback) + { + Z7_DECL_CMyComPtr_QI_FROM( + ICryptoGetTextPassword, + getTextPassword, ReOpenCallback) + if (getTextPassword) + return getTextPassword->CryptoGetTextPassword(password); + } + if (!Callback) + return E_NOTIMPL; + PasswordWasAsked = true; + return Callback->Open_CryptoGetTextPassword(password); + COM_TRY_END +} +#endif + +// IProgress +Z7_COM7F_IMF(COpenCallbackImp::SetTotal(const UInt64 /* total */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(COpenCallbackImp::SetCompleted(const UInt64 * /* completed */)) +{ + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveOpenCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ArchiveOpenCallback.h 2015-09-07 19:44:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ArchiveOpenCallback.h 2024-03-12 18:00:00.000000000 +0000 @@ -1,112 +1,182 @@ -// ArchiveOpenCallback.h - -#ifndef __ARCHIVE_OPEN_CALLBACK_H -#define __ARCHIVE_OPEN_CALLBACK_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/FileFind.h" - -#ifndef _NO_CRYPTO -#include "../../IPassword.h" -#endif -#include "../../Archive/IArchive.h" - -#ifdef _NO_CRYPTO - -#define INTERFACE_IOpenCallbackUI_Crypto(x) - -#else - -#define INTERFACE_IOpenCallbackUI_Crypto(x) \ - virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x; \ - /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x; */ \ - /* virtual bool Open_WasPasswordAsked() x; */ \ - /* virtual void Open_Clear_PasswordWasAsked_Flag() x; */ \ - -#endif - -#define INTERFACE_IOpenCallbackUI(x) \ - virtual HRESULT Open_CheckBreak() x; \ - virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x; \ - virtual HRESULT Open_Finished() x; \ - INTERFACE_IOpenCallbackUI_Crypto(x) - -struct IOpenCallbackUI -{ - INTERFACE_IOpenCallbackUI(=0) -}; - -class COpenCallbackImp: - public IArchiveOpenCallback, - public IArchiveOpenVolumeCallback, - public IArchiveOpenSetSubArchiveName, - #ifndef _NO_CRYPTO - public ICryptoGetTextPassword, - #endif - public CMyUnknownImp -{ -public: - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenVolumeCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenSetSubArchiveName) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif - - STDMETHOD(SetSubArchiveName(const wchar_t *name)) - { - _subArchiveMode = true; - _subArchiveName = name; - // TotalSize = 0; - return S_OK; - } - -private: - FString _folderPrefix; - NWindows::NFile::NFind::CFileInfo _fileInfo; - bool _subArchiveMode; - UString _subArchiveName; - -public: - UStringVector FileNames; - CBoolVector FileNames_WasUsed; - CRecordVector FileSizes; - - bool PasswordWasAsked; - - IOpenCallbackUI *Callback; - CMyComPtr ReOpenCallback; - // UInt64 TotalSize; - - COpenCallbackImp(): Callback(NULL), _subArchiveMode(false) {} - - void Init(const FString &folderPrefix, const FString &fileName) - { - _folderPrefix = folderPrefix; - if (!_fileInfo.Find(_folderPrefix + fileName,true)) - throw 20121118; - FileNames.Clear(); - FileNames_WasUsed.Clear(); - FileSizes.Clear(); - _subArchiveMode = false; - // TotalSize = 0; - PasswordWasAsked = false; - } - - bool SetSecondFileInfo(CFSTR newName) - { - return _fileInfo.Find(newName) && !_fileInfo.IsDir(); - } -}; - -#endif +// ArchiveOpenCallback.h + +#ifndef ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H +#define ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/FileFind.h" + +#include "../../Common/FileStreams.h" + +#ifndef Z7_NO_CRYPTO +#include "../../IPassword.h" +#endif +#include "../../Archive/IArchive.h" + +Z7_PURE_INTERFACES_BEGIN + +#ifdef Z7_NO_CRYPTO + +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) + +#else + +#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) \ + virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x \ + /* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x */ \ + /* virtual bool Open_WasPasswordAsked() x */ \ + /* virtual void Open_Clear_PasswordWasAsked_Flag() x */ \ + +#endif + +#define Z7_IFACEN_IOpenCallbackUI(x) \ + virtual HRESULT Open_CheckBreak() x \ + virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x \ + virtual HRESULT Open_Finished() x \ + Z7_IFACEM_IOpenCallbackUI_Crypto(x) + +Z7_IFACE_DECL_PURE(IOpenCallbackUI) + +Z7_PURE_INTERFACES_END + + +class CMultiStreams Z7_final +{ +public: + struct CSubStream + { + CMyComPtr Stream; + CInFileStream *FileSpec; + FString Path; + // UInt64 Size; + UInt64 LocalPos; + int Next; // next older + int Prev; // prev newer + // bool IsOpen; + + CSubStream(): + FileSpec(NULL), + // Size(0), + LocalPos(0), + Next(-1), + Prev(-1) + // IsOpen(false) + {} + }; + + CObjectVector Streams; +private: + // we must use critical section here, if we want to access from different volumnes simultaneously + int Head; // newest + int Tail; // oldest + unsigned NumListItems; + unsigned NumOpenFiles_AllowedMax; +public: + + CMultiStreams(); + void Init(); + HRESULT PrepareToOpenNew(); + void InsertToList(unsigned index); + void RemoveFromList(CSubStream &s); + void CloseFile(unsigned index); + HRESULT EnsureOpen(unsigned index); +}; + + +/* + We need COpenCallbackImp class for multivolume processing. + Also we use it as proxy from COM interfaces (IArchiveOpenCallback) to internal (IOpenCallbackUI) interfaces. + If archive is multivolume: + COpenCallbackImp object will exist after Open stage. + COpenCallbackImp object will be deleted when last reference + from each volume object (CInFileStreamVol) will be closed (when archive will be closed). +*/ + +class COpenCallbackImp Z7_final: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + #ifndef Z7_NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public IProgress, // IProgress is used for 7zFM + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + Z7_COM_QI_ENTRY(IArchiveOpenSetSubArchiveName) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + // Z7_COM_QI_ENTRY(IProgress) // the code doesn't require it + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + Z7_IFACE_COM7_IMP(IProgress) +public: + Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName) +private: + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + + bool _subArchiveMode; + +public: + bool PasswordWasAsked; + UStringVector FileNames; + CBoolVector FileNames_WasUsed; + CRecordVector FileSizes; + + void AtCloseFile(unsigned fileIndex) + { + FileNames_WasUsed[fileIndex] = false; + Volumes.CloseFile(fileIndex); + } + + /* we have two ways to Callback from this object + 1) IArchiveOpenCallback * ReOpenCallback - for ReOpen function, when IOpenCallbackUI is not available + 2) IOpenCallbackUI *Callback - for usual callback + we can't transfer IOpenCallbackUI pointer via internal interface, + so we use ReOpenCallback to callback without IOpenCallbackUI. + */ + + /* we use Callback/ReOpenCallback only at Open stage. + So the CMyComPtr reference counter is not required, + and we don't want additional reference to unused object, + if COpenCallbackImp is not closed + */ + IArchiveOpenCallback *ReOpenCallback; + // CMyComPtr ReOpenCallback; + IOpenCallbackUI *Callback; + // CMyComPtr Callback_Ref; + +private: + FString _folderPrefix; + UString _subArchiveName; + NWindows::NFile::NFind::CFileInfo _fileInfo; + +public: + CMultiStreams Volumes; + + // UInt64 TotalSize; + + COpenCallbackImp(): + _subArchiveMode(false), + PasswordWasAsked(false), + ReOpenCallback(NULL), + Callback(NULL) {} + + HRESULT Init2(const FString &folderPrefix, const FString &fileName); + + bool SetSecondFileInfo(CFSTR newName) + { + return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir(); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Bench.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/Bench.cpp 2016-06-11 08:53:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.cpp 2025-06-30 16:00:00.000000000 +0000 @@ -1,3102 +1,5026 @@ -// Bench.cpp - -#include "StdAfx.h" - -#include - -#ifndef _WIN32 -#define USE_POSIX_TIME -#define USE_POSIX_TIME2 -#endif - -#ifdef USE_POSIX_TIME -#include -#ifdef USE_POSIX_TIME2 -#include -#endif -#endif - -#ifdef _WIN32 -#define USE_ALLOCA -#endif - -#ifdef USE_ALLOCA -#ifdef _WIN32 -#include -#else -#include -#endif -#endif - -#include "../../../../C/7zCrc.h" -#include "../../../../C/Alloc.h" -#include "../../../../C/CpuArch.h" - -#include "../../../Windows/System.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/Synchronization.h" -#include "../../../Windows/Thread.h" -#endif - -#if defined(_WIN32) || defined(UNIX_USE_WIN_FILE) -#define USE_WIN_FILE -#endif - -#ifdef USE_WIN_FILE -#include "../../../Windows/FileIO.h" -#endif - - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../Common/MethodProps.h" -#include "../../Common/StreamUtils.h" - -#include "Bench.h" - -using namespace NWindows; - -static const UInt32 k_LZMA = 0x030101; - -static const UInt64 kComplexInCommands = (UInt64)1 << - #ifdef UNDER_CE - 31; - #else - 34; - #endif - -static const UInt32 kComplexInSeconds = 4; - -static void SetComplexCommands(UInt32 complexInSeconds, - bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands) -{ - complexInCommands = kComplexInCommands; - const UInt64 kMinFreq = (UInt64)1000000 * 4; - const UInt64 kMaxFreq = (UInt64)1000000 * 20000; - if (cpuFreq < kMinFreq && !isSpecifiedFreq) - cpuFreq = kMinFreq; - if (cpuFreq < kMaxFreq || isSpecifiedFreq) - { - if (complexInSeconds != 0) - complexInCommands = complexInSeconds * cpuFreq; - else - complexInCommands = cpuFreq >> 2; - } -} - -static const unsigned kNumHashDictBits = 17; -static const UInt32 kFilterUnpackSize = (48 << 10); - -static const unsigned kOldLzmaDictBits = 30; - -static const UInt32 kAdditionalSize = (1 << 16); -static const UInt32 kCompressedAdditionalSize = (1 << 10); -static const UInt32 kMaxLzmaPropSize = 5; - -class CBaseRandomGenerator -{ - UInt32 A1; - UInt32 A2; -public: - CBaseRandomGenerator() { Init(); } - void Init() { A1 = 362436069; A2 = 521288629;} - UInt32 GetRnd() - { - return - ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) + - ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); - } -}; - - -static const unsigned kBufferAlignment = 1 << 4; - -struct CBenchBuffer -{ - size_t BufferSize; - - #ifdef _WIN32 - - Byte *Buffer; - - CBenchBuffer(): BufferSize(0), Buffer(NULL) {} - ~CBenchBuffer() { ::MidFree(Buffer); } - - void AllocAlignedMask(size_t size, size_t) - { - ::MidFree(Buffer); - BufferSize = 0; - Buffer = (Byte *)::MidAlloc(size); - if (Buffer) - BufferSize = size; - } - - #else - - Byte *Buffer; - Byte *_bufBase; - - CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){} - ~CBenchBuffer() { ::MidFree(_bufBase); } - - void AllocAlignedMask(size_t size, size_t alignMask) - { - ::MidFree(_bufBase); - Buffer = NULL; - BufferSize = 0; - _bufBase = (Byte *)::MidAlloc(size + alignMask); - - if (_bufBase) - { - // Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask); - Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask); - BufferSize = size; - } - } - - #endif - - bool Alloc(size_t size) - { - if (Buffer && BufferSize == size) - return true; - AllocAlignedMask(size, kBufferAlignment - 1); - return (Buffer != NULL || size == 0); - } -}; - - -class CBenchRandomGenerator: public CBenchBuffer -{ - static UInt32 GetVal(UInt32 &res, unsigned numBits) - { - UInt32 val = res & (((UInt32)1 << numBits) - 1); - res >>= numBits; - return val; - } - - static UInt32 GetLen(UInt32 &r) - { - UInt32 len = GetVal(r, 2); - return GetVal(r, 1 + len); - } - -public: - - void GenerateSimpleRandom(CBaseRandomGenerator *_RG_) - { - CBaseRandomGenerator rg = *_RG_; - const size_t bufSize = BufferSize; - Byte *buf = Buffer; - for (size_t i = 0; i < bufSize; i++) - buf[i] = (Byte)rg.GetRnd(); - *_RG_ = rg; - } - - void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_) - { - CBaseRandomGenerator rg = *_RG_; - UInt32 pos = 0; - UInt32 rep0 = 1; - const size_t bufSize = BufferSize; - Byte *buf = Buffer; - unsigned posBits = 1; - - while (pos < bufSize) - { - UInt32 r = rg.GetRnd(); - if (GetVal(r, 1) == 0 || pos < 1024) - buf[pos++] = (Byte)(r & 0xFF); - else - { - UInt32 len; - len = 1 + GetLen(r); - - if (GetVal(r, 3) != 0) - { - len += GetLen(r); - - while (((UInt32)1 << posBits) < pos) - posBits++; - - unsigned numBitsMax = dictBits; - if (numBitsMax > posBits) - numBitsMax = posBits; - - const unsigned kAddBits = 6; - unsigned numLogBits = 5; - if (numBitsMax <= (1 << 4) - 1 + kAddBits) - numLogBits = 4; - - for (;;) - { - UInt32 ppp = GetVal(r, numLogBits) + kAddBits; - r = rg.GetRnd(); - if (ppp > numBitsMax) - continue; - rep0 = GetVal(r, ppp); - if (rep0 < pos) - break; - r = rg.GetRnd(); - } - rep0++; - } - - { - UInt32 rem = (UInt32)bufSize - pos; - if (len > rem) - len = rem; - } - Byte *dest = buf + pos; - const Byte *src = dest - rep0; - pos += len; - for (UInt32 i = 0; i < len; i++) - *dest++ = *src++; - } - } - - *_RG_ = rg; - } -}; - - -class CBenchmarkInStream: - public ISequentialInStream, - public CMyUnknownImp -{ - const Byte *Data; - size_t Pos; - size_t Size; -public: - MY_UNKNOWN_IMP - void Init(const Byte *data, size_t size) - { - Data = data; - Size = size; - Pos = 0; - } - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - size_t remain = Size - Pos; - UInt32 kMaxBlockSize = (1 << 20); - if (size > kMaxBlockSize) - size = kMaxBlockSize; - if (size > remain) - size = (UInt32)remain; - for (UInt32 i = 0; i < size; i++) - ((Byte *)data)[i] = Data[Pos + i]; - Pos += size; - if (processedSize) - *processedSize = size; - return S_OK; -} - -class CBenchmarkOutStream: - public ISequentialOutStream, - public CBenchBuffer, - public CMyUnknownImp -{ - // bool _overflow; -public: - size_t Pos; - bool RealCopy; - bool CalcCrc; - UInt32 Crc; - - // CBenchmarkOutStream(): _overflow(false) {} - void Init(bool realCopy, bool calcCrc) - { - Crc = CRC_INIT_VAL; - RealCopy = realCopy; - CalcCrc = calcCrc; - // _overflow = false; - Pos = 0; - } - - // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - size_t curSize = BufferSize - Pos; - if (curSize > size) - curSize = size; - if (curSize != 0) - { - if (RealCopy) - memcpy(Buffer + Pos, data, curSize); - if (CalcCrc) - Crc = CrcUpdate(Crc, data, curSize); - Pos += curSize; - } - if (processedSize) - *processedSize = (UInt32)curSize; - if (curSize != size) - { - // _overflow = true; - return E_FAIL; - } - return S_OK; -} - -class CCrcOutStream: - public ISequentialOutStream, - public CMyUnknownImp -{ -public: - bool CalcCrc; - UInt32 Crc; - MY_UNKNOWN_IMP - - CCrcOutStream(): CalcCrc(true) {}; - void Init() { Crc = CRC_INIT_VAL; } - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (CalcCrc) - Crc = CrcUpdate(Crc, data, size); - if (processedSize) - *processedSize = size; - return S_OK; -} - -static UInt64 GetTimeCount() -{ - #ifdef USE_POSIX_TIME - #ifdef USE_POSIX_TIME2 - timeval v; - if (gettimeofday(&v, 0) == 0) - return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec; - return (UInt64)time(NULL) * 1000000; - #else - return time(NULL); - #endif - #else - /* - LARGE_INTEGER value; - if (::QueryPerformanceCounter(&value)) - return value.QuadPart; - */ - return GetTickCount(); - #endif -} - -static UInt64 GetFreq() -{ - #ifdef USE_POSIX_TIME - #ifdef USE_POSIX_TIME2 - return 1000000; - #else - return 1; - #endif - #else - /* - LARGE_INTEGER value; - if (::QueryPerformanceFrequency(&value)) - return value.QuadPart; - */ - return 1000; - #endif -} - -#ifdef USE_POSIX_TIME - -struct CUserTime -{ - UInt64 Sum; - clock_t Prev; - - void Init() - { - Prev = clock(); - Sum = 0; - } - - UInt64 GetUserTime() - { - clock_t v = clock(); - Sum += v - Prev; - Prev = v; - return Sum; - } -}; - -#else - -static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } -UInt64 GetWinUserTime() -{ - FILETIME creationTime, exitTime, kernelTime, userTime; - if ( - #ifdef UNDER_CE - ::GetThreadTimes(::GetCurrentThread() - #else - ::GetProcessTimes(::GetCurrentProcess() - #endif - , &creationTime, &exitTime, &kernelTime, &userTime) != 0) - return GetTime64(userTime) + GetTime64(kernelTime); - return (UInt64)GetTickCount() * 10000; -} - -struct CUserTime -{ - UInt64 StartTime; - - void Init() { StartTime = GetWinUserTime(); } - UInt64 GetUserTime() { return GetWinUserTime() - StartTime; } -}; - -#endif - -static UInt64 GetUserFreq() -{ - #ifdef USE_POSIX_TIME - return CLOCKS_PER_SEC; - #else - return 10000000; - #endif -} - -class CBenchProgressStatus -{ - #ifndef _7ZIP_ST - NSynchronization::CCriticalSection CS; - #endif -public: - HRESULT Res; - bool EncodeMode; - void SetResult(HRESULT res) - { - #ifndef _7ZIP_ST - NSynchronization::CCriticalSectionLock lock(CS); - #endif - Res = res; - } - HRESULT GetResult() - { - #ifndef _7ZIP_ST - NSynchronization::CCriticalSectionLock lock(CS); - #endif - return Res; - } -}; - -struct CBenchInfoCalc -{ - CBenchInfo BenchInfo; - CUserTime UserTime; - - void SetStartTime(); - void SetFinishTime(CBenchInfo &dest); -}; - -void CBenchInfoCalc::SetStartTime() -{ - BenchInfo.GlobalFreq = GetFreq(); - BenchInfo.UserFreq = GetUserFreq(); - BenchInfo.GlobalTime = ::GetTimeCount(); - BenchInfo.UserTime = 0; - UserTime.Init(); -} - -void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest) -{ - dest = BenchInfo; - dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime; - dest.UserTime = UserTime.GetUserTime(); -} - -class CBenchProgressInfo: - public ICompressProgressInfo, - public CMyUnknownImp, - public CBenchInfoCalc -{ -public: - CBenchProgressStatus *Status; - HRESULT Res; - IBenchCallback *Callback; - - CBenchProgressInfo(): Callback(0) {} - MY_UNKNOWN_IMP - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); -}; - -STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - HRESULT res = Status->GetResult(); - if (res != S_OK) - return res; - if (!Callback) - return res; - CBenchInfo info; - SetFinishTime(info); - if (Status->EncodeMode) - { - info.UnpackSize = BenchInfo.UnpackSize + *inSize; - info.PackSize = BenchInfo.PackSize + *outSize; - res = Callback->SetEncodeResult(info, false); - } - else - { - info.PackSize = BenchInfo.PackSize + *inSize; - info.UnpackSize = BenchInfo.UnpackSize + *outSize; - res = Callback->SetDecodeResult(info, false); - } - if (res != S_OK) - Status->SetResult(res); - return res; -} - -static const unsigned kSubBits = 8; - -static UInt32 GetLogSize(UInt32 size) -{ - for (unsigned i = kSubBits; i < 32; i++) - for (UInt32 j = 0; j < (1 << kSubBits); j++) - if (size <= (((UInt32)1) << i) + (j << (i - kSubBits))) - return (i << kSubBits) + j; - return (32 << kSubBits); -} - -static void NormalizeVals(UInt64 &v1, UInt64 &v2) -{ - while (v1 > 1000000) - { - v1 >>= 1; - v2 >>= 1; - } -} - -UInt64 CBenchInfo::GetUsage() const -{ - UInt64 userTime = UserTime; - UInt64 userFreq = UserFreq; - UInt64 globalTime = GlobalTime; - UInt64 globalFreq = GlobalFreq; - NormalizeVals(userTime, userFreq); - NormalizeVals(globalFreq, globalTime); - if (userFreq == 0) - userFreq = 1; - if (globalTime == 0) - globalTime = 1; - return userTime * globalFreq * 1000000 / userFreq / globalTime; -} - -UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const -{ - UInt64 userTime = UserTime; - UInt64 userFreq = UserFreq; - UInt64 globalTime = GlobalTime; - UInt64 globalFreq = GlobalFreq; - NormalizeVals(userFreq, userTime); - NormalizeVals(globalTime, globalFreq); - if (globalFreq == 0) - globalFreq = 1; - if (userTime == 0) - userTime = 1; - return userFreq * globalTime / globalFreq * rating / userTime; -} - -static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq) -{ - UInt64 elTime = elapsedTime; - NormalizeVals(freq, elTime); - if (elTime == 0) - elTime = 1; - return value * freq / elTime; -} - -UInt64 CBenchInfo::GetSpeed(UInt64 numCommands) const -{ - return MyMultDiv64(numCommands, GlobalTime, GlobalFreq); -} - -struct CBenchProps -{ - bool LzmaRatingMode; - - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; - - CBenchProps(): LzmaRatingMode(false) {} - void SetLzmaCompexity(); - - UInt64 GeComprCommands(UInt64 unpackSize) - { - return unpackSize * EncComplex; - } - - UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize) - { - return (packSize * DecComplexCompr + unpackSize * DecComplexUnc); - } - - UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); - UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); -}; - -void CBenchProps::SetLzmaCompexity() -{ - EncComplex = 1200; - DecComplexUnc = 4; - DecComplexCompr = 190; - LzmaRatingMode = true; -} - -UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) -{ - if (dictSize < (1 << kBenchMinDicLogSize)) - dictSize = (1 << kBenchMinDicLogSize); - UInt64 encComplex = EncComplex; - if (LzmaRatingMode) - { - UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits); - encComplex = 870 + ((t * t * 5) >> (2 * kSubBits)); - } - UInt64 numCommands = (UInt64)size * encComplex; - return MyMultDiv64(numCommands, elapsedTime, freq); -} - -UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) -{ - UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations; - return MyMultDiv64(numCommands, elapsedTime, freq); -} - -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) -{ - CBenchProps props; - props.SetLzmaCompexity(); - return props.GetCompressRating(dictSize, elapsedTime, freq, size); -} - -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) -{ - CBenchProps props; - props.SetLzmaCompexity(); - return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations); -} - -struct CEncoderInfo; - -struct CEncoderInfo -{ - #ifndef _7ZIP_ST - NWindows::CThread thread[2]; - UInt32 NumDecoderSubThreads; - #endif - CMyComPtr _encoder; - CMyComPtr _encoderFilter; - CBenchProgressInfo *progressInfoSpec[2]; - CMyComPtr progressInfo[2]; - UInt64 NumIterations; - - #ifdef USE_ALLOCA - size_t AllocaSize; - #endif - - Byte _key[32]; - Byte _iv[16]; - Byte _psw[16]; - bool CheckCrc_Enc; - bool CheckCrc_Dec; - - struct CDecoderInfo - { - CEncoderInfo *Encoder; - UInt32 DecoderIndex; - bool CallbackMode; - - #ifdef USE_ALLOCA - size_t AllocaSize; - #endif - }; - CDecoderInfo decodersInfo[2]; - - CMyComPtr _decoders[2]; - CMyComPtr _decoderFilter; - - HRESULT Results[2]; - CBenchmarkOutStream *outStreamSpec; - CMyComPtr outStream; - IBenchCallback *callback; - IBenchPrintCallback *printCallback; - UInt32 crc; - size_t kBufferSize; - size_t compressedSize; - const Byte *uncompressedDataPtr; - - const Byte *fileData; - CBenchRandomGenerator rg; - - CBenchBuffer rgCopy; // it must be 16-byte aligned !!! - CBenchmarkOutStream *propStreamSpec; - CMyComPtr propStream; - - // for decode - COneMethodInfo _method; - size_t _uncompressedDataSize; - - HRESULT Init( - const COneMethodInfo &method, - unsigned generateDictBits, - CBaseRandomGenerator *rg); - HRESULT Encode(); - HRESULT Decode(UInt32 decoderIndex); - - CEncoderInfo(): - fileData(NULL), - CheckCrc_Enc(true), - CheckCrc_Dec(true), - outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {} - - #ifndef _7ZIP_ST - - static THREAD_FUNC_DECL EncodeThreadFunction(void *param) - { - HRESULT res; - CEncoderInfo *encoder = (CEncoderInfo *)param; - try - { - #ifdef USE_ALLOCA - alloca(encoder->AllocaSize); - #endif - - res = encoder->Encode(); - encoder->Results[0] = res; - } - catch(...) - { - res = E_FAIL; - } - if (res != S_OK) - encoder->progressInfoSpec[0]->Status->SetResult(res); - return 0; - } - - static THREAD_FUNC_DECL DecodeThreadFunction(void *param) - { - CDecoderInfo *decoder = (CDecoderInfo *)param; - - #ifdef USE_ALLOCA - alloca(decoder->AllocaSize); - #endif - - CEncoderInfo *encoder = decoder->Encoder; - encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex); - return 0; - } - - HRESULT CreateEncoderThread() - { - return thread[0].Create(EncodeThreadFunction, this); - } - - HRESULT CreateDecoderThread(unsigned index, bool callbackMode - #ifdef USE_ALLOCA - , size_t allocaSize - #endif - ) - { - CDecoderInfo &decoder = decodersInfo[index]; - decoder.DecoderIndex = index; - decoder.Encoder = this; - - #ifdef USE_ALLOCA - decoder.AllocaSize = allocaSize; - #endif - - decoder.CallbackMode = callbackMode; - return thread[index].Create(DecodeThreadFunction, &decoder); - } - - #endif -}; - - -HRESULT CEncoderInfo::Init( - const COneMethodInfo &method, - unsigned generateDictBits, - CBaseRandomGenerator *rgLoc) -{ - // we need extra space, if input data is already compressed - const size_t kCompressedBufferSize = - kCompressedAdditionalSize + - kBufferSize + kBufferSize / 16; - // kBufferSize / 2; - - if (kCompressedBufferSize < kBufferSize) - return E_FAIL; - - uncompressedDataPtr = fileData; - - if (!fileData) - { - if (!rg.Alloc(kBufferSize)) - return E_OUTOFMEMORY; - - // DWORD ttt = GetTickCount(); - if (generateDictBits == 0) - rg.GenerateSimpleRandom(rgLoc); - else - rg.GenerateLz(generateDictBits, rgLoc); - // printf("\n%d\n ", GetTickCount() - ttt); - - crc = CrcCalc(rg.Buffer, rg.BufferSize); - uncompressedDataPtr = rg.Buffer; - } - - if (_encoderFilter) - { - if (!rgCopy.Alloc(kBufferSize)) - return E_OUTOFMEMORY; - } - - - outStreamSpec = new CBenchmarkOutStream; - outStream = outStreamSpec; - if (!outStreamSpec->Alloc(kCompressedBufferSize)) - return E_OUTOFMEMORY; - - propStreamSpec = 0; - if (!propStream) - { - propStreamSpec = new CBenchmarkOutStream; - propStream = propStreamSpec; - } - if (!propStreamSpec->Alloc(kMaxLzmaPropSize)) - return E_OUTOFMEMORY; - propStreamSpec->Init(true, false); - - - CMyComPtr coder; - if (_encoderFilter) - coder = _encoderFilter; - else - coder = _encoder; - { - CMyComPtr scp; - coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); - if (scp) - { - UInt64 reduceSize = kBufferSize; - RINOK(method.SetCoderProps(scp, &reduceSize)); - } - else - { - if (method.AreThereNonOptionalProps()) - return E_INVALIDARG; - } - - CMyComPtr writeCoderProps; - coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps); - if (writeCoderProps) - { - RINOK(writeCoderProps->WriteCoderProperties(propStream)); - } - - { - CMyComPtr sp; - coder.QueryInterface(IID_ICryptoSetPassword, &sp); - if (sp) - { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); - - // we must call encoding one time to calculate password key for key cache. - // it must be after WriteCoderProperties! - Byte temp[16]; - memset(temp, 0, sizeof(temp)); - - if (_encoderFilter) - { - _encoderFilter->Init(); - _encoderFilter->Filter(temp, sizeof(temp)); - } - else - { - CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; - CMyComPtr inStream = inStreamSpec; - inStreamSpec->Init(temp, sizeof(temp)); - - CCrcOutStream *crcStreamSpec = new CCrcOutStream; - CMyComPtr crcStream = crcStreamSpec; - crcStreamSpec->Init(); - - RINOK(_encoder->Code(inStream, crcStream, 0, 0, NULL)); - } - } - } - } - - return S_OK; -} - - -static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size) -{ - while (size != 0) - { - UInt32 cur = (UInt32)1 << 31; - if (cur > size) - cur = (UInt32)size; - UInt32 processed = filter->Filter(data, cur); - data += processed; - // if (processed > size) (in AES filter), we must fill last block with zeros. - // but it is not important for benchmark. So we just copy that data without filtering. - if (processed > size || processed == 0) - break; - size -= processed; - } -} - - -HRESULT CEncoderInfo::Encode() -{ - CBenchInfo &bi = progressInfoSpec[0]->BenchInfo; - bi.UnpackSize = 0; - bi.PackSize = 0; - CMyComPtr cp; - CMyComPtr coder; - if (_encoderFilter) - coder = _encoderFilter; - else - coder = _encoder; - coder.QueryInterface(IID_ICryptoProperties, &cp); - CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; - CMyComPtr inStream = inStreamSpec; - UInt64 prev = 0; - - UInt32 crcPrev = 0; - - if (cp) - { - RINOK(cp->SetKey(_key, sizeof(_key))); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); - } - - for (UInt64 i = 0; i < NumIterations; i++) - { - if (printCallback && bi.UnpackSize - prev > (1 << 20)) - { - RINOK(printCallback->CheckBreak()); - prev = bi.UnpackSize; - } - - bool isLast = (i == NumIterations - 1); - bool calcCrc = ((isLast || (i & 0x7F) == 0 || CheckCrc_Enc) && NumIterations != 1); - outStreamSpec->Init(isLast, calcCrc); - - if (_encoderFilter) - { - memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize); - _encoderFilter->Init(); - My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize); - RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize)); - } - else - { - inStreamSpec->Init(uncompressedDataPtr, kBufferSize); - RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])); - } - - // outStreamSpec->Print(); - - UInt32 crcNew = CRC_GET_DIGEST(outStreamSpec->Crc); - if (i == 0) - crcPrev = crcNew; - else if (calcCrc && crcPrev != crcNew) - return E_FAIL; - - compressedSize = outStreamSpec->Pos; - bi.UnpackSize += kBufferSize; - bi.PackSize += compressedSize; - } - - _encoder.Release(); - _encoderFilter.Release(); - return S_OK; -} - - -HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) -{ - CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; - CMyComPtr inStream = inStreamSpec; - CMyComPtr &decoder = _decoders[decoderIndex]; - CMyComPtr coder; - if (_decoderFilter) - { - if (decoderIndex != 0) - return E_FAIL; - coder = _decoderFilter; - } - else - coder = decoder; - - CMyComPtr setDecProps; - coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps); - if (!setDecProps && propStreamSpec->Pos != 0) - return E_FAIL; - - CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; - CMyComPtr crcOutStream = crcOutStreamSpec; - - CBenchProgressInfo *pi = progressInfoSpec[decoderIndex]; - pi->BenchInfo.UnpackSize = 0; - pi->BenchInfo.PackSize = 0; - - #ifndef _7ZIP_ST - { - CMyComPtr setCoderMt; - coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); - if (setCoderMt) - { - RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)); - } - } - #endif - - CMyComPtr scp; - coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); - if (scp) - { - UInt64 reduceSize = _uncompressedDataSize; - RINOK(_method.SetCoderProps(scp, &reduceSize)); - } - - CMyComPtr cp; - coder.QueryInterface(IID_ICryptoProperties, &cp); - - if (setDecProps) - { - RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos)); - } - - { - CMyComPtr sp; - coder.QueryInterface(IID_ICryptoSetPassword, &sp); - if (sp) - { - RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))); - } - } - - UInt64 prev = 0; - - if (cp) - { - RINOK(cp->SetKey(_key, sizeof(_key))); - RINOK(cp->SetInitVector(_iv, sizeof(_iv))); - } - - for (UInt64 i = 0; i < NumIterations; i++) - { - if (printCallback && pi->BenchInfo.UnpackSize - prev > (1 << 20)) - { - RINOK(printCallback->CheckBreak()); - prev = pi->BenchInfo.UnpackSize; - } - - inStreamSpec->Init(outStreamSpec->Buffer, compressedSize); - crcOutStreamSpec->Init(); - - UInt64 outSize = kBufferSize; - crcOutStreamSpec->CalcCrc = ((i & 0x7F) == 0 || CheckCrc_Dec); - - if (_decoderFilter) - { - if (compressedSize > rgCopy.BufferSize) - return E_FAIL; - memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize); - _decoderFilter->Init(); - My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize); - RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize)); - } - else - { - RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex])); - } - - if (crcOutStreamSpec->CalcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc) - return S_FALSE; - pi->BenchInfo.UnpackSize += kBufferSize; - pi->BenchInfo.PackSize += compressedSize; - } - - decoder.Release(); - _decoderFilter.Release(); - return S_OK; -} - - -static const UInt32 kNumThreadsMax = (1 << 12); - -struct CBenchEncoders -{ - CEncoderInfo *encoders; - CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; } - ~CBenchEncoders() { delete []encoders; } -}; - - -static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands) -{ - if (numCommands < (1 << 4)) - numCommands = (1 << 4); - UInt64 res = complexInCommands / numCommands; - return (res == 0 ? 1 : res); -} - - -static HRESULT MethodBench( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 complexInCommands, - bool - #ifndef _7ZIP_ST - oldLzmaBenchMode - #endif - , - UInt32 - #ifndef _7ZIP_ST - numThreads - #endif - , - const COneMethodInfo &method2, - size_t uncompressedDataSize, - const Byte *fileData, - unsigned generateDictBits, - - IBenchPrintCallback *printCallback, - IBenchCallback *callback, - CBenchProps *benchProps) -{ - COneMethodInfo method = method2; - UInt64 methodId; - UInt32 numStreams; - if (!FindMethod( - EXTERNAL_CODECS_LOC_VARS - method.MethodName, methodId, numStreams)) - return E_NOTIMPL; - if (numStreams != 1) - return E_INVALIDARG; - - UInt32 numEncoderThreads = 1; - UInt32 numSubDecoderThreads = 1; - - #ifndef _7ZIP_ST - numEncoderThreads = numThreads; - - if (oldLzmaBenchMode && methodId == k_LZMA) - { - bool fixedNumber; - UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber); - if (!fixedNumber && numThreads == 1) - method.AddProp_NumThreads(1); - if (numThreads > 1 && numLzmaThreads > 1) - { - numEncoderThreads = numThreads / 2; - numSubDecoderThreads = 2; - } - } - #endif - - CBenchEncoders encodersSpec(numEncoderThreads); - CEncoderInfo *encoders = encodersSpec.encoders; - - UInt32 i; - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - encoder.callback = (i == 0) ? callback : 0; - encoder.printCallback = printCallback; - - { - CCreatedCoder cod; - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, true, encoder._encoderFilter, cod)); - encoder._encoder = cod.Coder; - if (!encoder._encoder && !encoder._encoderFilter) - return E_NOTIMPL; - } - - encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30 ; - encoder.CheckCrc_Dec = (benchProps->DecComplexCompr + benchProps->DecComplexUnc) > 30 ; - - memset(encoder._iv, 0, sizeof(encoder._iv)); - memset(encoder._key, 0, sizeof(encoder._key)); - memset(encoder._psw, 0, sizeof(encoder._psw)); - - for (UInt32 j = 0; j < numSubDecoderThreads; j++) - { - CCreatedCoder cod; - CMyComPtr &decoder = encoder._decoders[j]; - RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)); - decoder = cod.Coder; - if (!encoder._decoderFilter && !decoder) - return E_NOTIMPL; - } - } - - CBaseRandomGenerator rg; - rg.Init(); - - UInt32 crc = 0; - if (fileData) - crc = CrcCalc(fileData, uncompressedDataSize); - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - encoder._method = method; - encoder._uncompressedDataSize = uncompressedDataSize; - encoder.kBufferSize = uncompressedDataSize; - encoder.fileData = fileData; - encoder.crc = crc; - - RINOK(encoders[i].Init(method, generateDictBits, &rg)); - } - - CBenchProgressStatus status; - status.Res = S_OK; - status.EncodeMode = true; - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands); - - for (int j = 0; j < 2; j++) - { - CBenchProgressInfo *spec = new CBenchProgressInfo; - encoder.progressInfoSpec[j] = spec; - encoder.progressInfo[j] = spec; - spec->Status = &status; - } - - if (i == 0) - { - CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; - bpi->Callback = callback; - bpi->BenchInfo.NumIterations = numEncoderThreads; - bpi->SetStartTime(); - } - - #ifndef _7ZIP_ST - if (numEncoderThreads > 1) - { - #ifdef USE_ALLOCA - encoder.AllocaSize = (i * 16 * 21) & 0x7FF; - #endif - - RINOK(encoder.CreateEncoderThread()) - } - else - #endif - { - RINOK(encoder.Encode()); - } - } - - #ifndef _7ZIP_ST - if (numEncoderThreads > 1) - for (i = 0; i < numEncoderThreads; i++) - encoders[i].thread[0].Wait(); - #endif - - RINOK(status.Res); - - CBenchInfo info; - - encoders[0].progressInfoSpec[0]->SetFinishTime(info); - info.UnpackSize = 0; - info.PackSize = 0; - info.NumIterations = encoders[0].NumIterations; - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - info.UnpackSize += encoder.kBufferSize; - info.PackSize += encoder.compressedSize; - } - - RINOK(callback->SetEncodeResult(info, true)); - - - status.Res = S_OK; - status.EncodeMode = false; - - UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads; - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - - if (i == 0) - { - encoder.NumIterations = GetNumIterations(benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize), complexInCommands); - CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; - bpi->Callback = callback; - bpi->BenchInfo.NumIterations = numDecoderThreads; - bpi->SetStartTime(); - } - else - encoder.NumIterations = encoders[0].NumIterations; - - #ifndef _7ZIP_ST - { - int numSubThreads = method.Get_NumThreads(); - encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : numSubThreads; - } - if (numDecoderThreads > 1) - { - for (UInt32 j = 0; j < numSubDecoderThreads; j++) - { - HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) - #ifdef USE_ALLOCA - , ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF - #endif - ); - RINOK(res); - } - } - else - #endif - { - RINOK(encoder.Decode(0)); - } - } - - #ifndef _7ZIP_ST - HRESULT res = S_OK; - if (numDecoderThreads > 1) - for (i = 0; i < numEncoderThreads; i++) - for (UInt32 j = 0; j < numSubDecoderThreads; j++) - { - CEncoderInfo &encoder = encoders[i]; - encoder.thread[j].Wait(); - if (encoder.Results[j] != S_OK) - res = encoder.Results[j]; - } - RINOK(res); - #endif - - RINOK(status.Res); - encoders[0].progressInfoSpec[0]->SetFinishTime(info); - - #ifndef _7ZIP_ST - #ifdef UNDER_CE - if (numDecoderThreads > 1) - for (i = 0; i < numEncoderThreads; i++) - for (UInt32 j = 0; j < numSubDecoderThreads; j++) - { - FILETIME creationTime, exitTime, kernelTime, userTime; - if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0) - info.UserTime += GetTime64(userTime) + GetTime64(kernelTime); - } - #endif - #endif - - info.UnpackSize = 0; - info.PackSize = 0; - info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations; - - for (i = 0; i < numEncoderThreads; i++) - { - CEncoderInfo &encoder = encoders[i]; - info.UnpackSize += encoder.kBufferSize; - info.PackSize += encoder.compressedSize; - } - - RINOK(callback->SetDecodeResult(info, false)); - RINOK(callback->SetDecodeResult(info, true)); - - return S_OK; -} - - -static inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary) -{ - UInt32 hs = dictionary - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; - if (hs > (1 << 24)) - hs >>= 1; - hs++; - return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + - (1 << 20) + (multiThread ? (6 << 20) : 0); -} - -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench) -{ - const UInt32 kBufferSize = dictionary; - const UInt32 kCompressedBufferSize = kBufferSize; // / 2; - bool lzmaMt = (totalBench || numThreads > 1); - UInt32 numBigThreads = numThreads; - if (!totalBench && lzmaMt) - numBigThreads /= 2; - return ((UInt64)kBufferSize + kCompressedBufferSize + - GetLZMAUsage(lzmaMt, dictionary) + (2 << 20)) * numBigThreads; -} - -static HRESULT CrcBig(const void *data, UInt32 size, UInt64 numIterations, - const UInt32 *checkSum, IHasher *hf, - IBenchPrintCallback *callback) -{ - Byte hash[64]; - UInt64 i; - for (i = 0; i < sizeof(hash); i++) - hash[i] = 0; - for (i = 0; i < numIterations; i++) - { - if (callback && (i & 0xFF) == 0) - { - RINOK(callback->CheckBreak()); - } - hf->Init(); - hf->Update(data, size); - hf->Final(hash); - UInt32 hashSize = hf->GetDigestSize(); - if (hashSize > sizeof(hash)) - return S_FALSE; - UInt32 sum = 0; - for (UInt32 j = 0; j < hashSize; j += 4) - sum ^= GetUi32(hash + j); - if (checkSum && sum != *checkSum) - { - return S_FALSE; - } - } - return S_OK; -} - -UInt32 g_BenchCpuFreqTemp = 1; - -#define YY1 sum += val; sum ^= val; -#define YY3 YY1 YY1 YY1 YY1 -#define YY5 YY3 YY3 YY3 YY3 -#define YY7 YY5 YY5 YY5 YY5 -static const UInt32 kNumFreqCommands = 128; - -EXTERN_C_BEGIN - -static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val) -{ - for (UInt32 i = 0; i < num; i++) - { - YY7 - } - return sum; -} - -EXTERN_C_END - - -#ifndef _7ZIP_ST - -struct CFreqInfo -{ - NWindows::CThread Thread; - IBenchPrintCallback *Callback; - HRESULT CallbackRes; - UInt32 ValRes; - UInt32 Size; - UInt64 NumIterations; - - void Wait() - { - Thread.Wait(); - Thread.Close(); - } -}; - -static THREAD_FUNC_DECL FreqThreadFunction(void *param) -{ - CFreqInfo *p = (CFreqInfo *)param; - - UInt32 sum = g_BenchCpuFreqTemp; - for (UInt64 k = p->NumIterations; k > 0; k--) - { - p->CallbackRes = p->Callback->CheckBreak(); - if (p->CallbackRes != S_OK) - return 0; - sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp); - } - p->ValRes = sum; - return 0; -} - -struct CFreqThreads -{ - CFreqInfo *Items; - UInt32 NumThreads; - - CFreqThreads(): Items(0), NumThreads(0) {} - void WaitAll() - { - for (UInt32 i = 0; i < NumThreads; i++) - Items[i].Wait(); - NumThreads = 0; - } - ~CFreqThreads() - { - WaitAll(); - delete []Items; - } -}; - -struct CCrcInfo -{ - NWindows::CThread Thread; - IBenchPrintCallback *Callback; - HRESULT CallbackRes; - - const Byte *Data; - UInt32 Size; - UInt64 NumIterations; - bool CheckSumDefined; - UInt32 CheckSum; - CMyComPtr Hasher; - HRESULT Res; - - #ifdef USE_ALLOCA - size_t AllocaSize; - #endif - - void Wait() - { - Thread.Wait(); - Thread.Close(); - } -}; - -static THREAD_FUNC_DECL CrcThreadFunction(void *param) -{ - CCrcInfo *p = (CCrcInfo *)param; - - #ifdef USE_ALLOCA - alloca(p->AllocaSize); - #endif - - p->Res = CrcBig(p->Data, p->Size, p->NumIterations, - p->CheckSumDefined ? &p->CheckSum : NULL, p->Hasher, - p->Callback); - return 0; -} - -struct CCrcThreads -{ - CCrcInfo *Items; - UInt32 NumThreads; - - CCrcThreads(): Items(0), NumThreads(0) {} - void WaitAll() - { - for (UInt32 i = 0; i < NumThreads; i++) - Items[i].Wait(); - NumThreads = 0; - } - ~CCrcThreads() - { - WaitAll(); - delete []Items; - } -}; - -#endif - -static UInt32 CrcCalc1(const Byte *buf, UInt32 size) -{ - UInt32 crc = CRC_INIT_VAL;; - for (UInt32 i = 0; i < size; i++) - crc = CRC_UPDATE_BYTE(crc, buf[i]); - return CRC_GET_DIGEST(crc); -} - -static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG) -{ - for (UInt32 i = 0; i < size; i++) - buf[i] = (Byte)RG.GetRnd(); -} - -static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG) -{ - RandGen(buf, size, RG); - return CrcCalc1(buf, size); -} - -bool CrcInternalTest() -{ - CBenchBuffer buffer; - const UInt32 kBufferSize0 = (1 << 8); - const UInt32 kBufferSize1 = (1 << 10); - const UInt32 kCheckSize = (1 << 5); - if (!buffer.Alloc(kBufferSize0 + kBufferSize1)) - return false; - Byte *buf = buffer.Buffer; - UInt32 i; - for (i = 0; i < kBufferSize0; i++) - buf[i] = (Byte)i; - UInt32 crc1 = CrcCalc1(buf, kBufferSize0); - if (crc1 != 0x29058C73) - return false; - CBaseRandomGenerator RG; - RandGen(buf + kBufferSize0, kBufferSize1, RG); - for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++) - for (UInt32 j = 0; j < kCheckSize; j++) - if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j)) - return false; - return true; -} - -struct CBenchMethod -{ - unsigned Weight; - unsigned DictBits; - UInt32 EncComplex; - UInt32 DecComplexCompr; - UInt32 DecComplexUnc; - const char *Name; -}; - -static const CBenchMethod g_Bench[] = -{ - { 40, 17, 357, 145, 20, "LZMA:x1" }, - { 80, 24, 1220, 145, 20, "LZMA:x5:mt1" }, - { 80, 24, 1220, 145, 20, "LZMA:x5:mt2" }, - - { 10, 16, 124, 40, 14, "Deflate:x1" }, - { 20, 16, 376, 40, 14, "Deflate:x5" }, - { 10, 16, 1082, 40, 14, "Deflate:x7" }, - { 10, 17, 422, 40, 14, "Deflate64:x5" }, - - { 10, 15, 590, 69, 69, "BZip2:x1" }, - { 20, 19, 815, 122, 122, "BZip2:x5" }, - { 10, 19, 815, 122, 122, "BZip2:x5:mt2" }, - { 10, 19, 2530, 122, 122, "BZip2:x7" }, - - { 10, 18, 1010, 0, 1150, "PPMD:x1" }, - { 10, 22, 1655, 0, 1830, "PPMD:x5" }, - - { 2, 0, 6, 0, 6, "Delta:4" }, - { 2, 0, 4, 0, 4, "BCJ" }, - - { 10, 0, 24, 0, 24, "AES256CBC:1" }, - { 2, 0, 8, 0, 2, "AES256CBC:2" } -}; - -struct CBenchHash -{ - unsigned Weight; - UInt32 Complex; - UInt32 CheckSum; - const char *Name; -}; - -static const CBenchHash g_Hash[] = -{ - { 1, 1820, 0x8F8FEDAB, "CRC32:1" }, - { 10, 558, 0x8F8FEDAB, "CRC32:4" }, - { 10, 339, 0x8F8FEDAB, "CRC32:8" }, - { 10, 512, 0xDF1C17CC, "CRC64" }, - { 10, 5100, 0x2D79FF2E, "SHA256" }, - { 10, 2340, 0x4C25132B, "SHA1" }, - { 2, 5500, 0xE084E913, "BLAKE2sp" } -}; - -struct CTotalBenchRes -{ - // UInt64 NumIterations1; // for Usage - UInt64 NumIterations2; // for Rating / RPU - - UInt64 Rating; - UInt64 Usage; - UInt64 RPU; - - void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; } - - void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) - { - Rating = (r1.Rating + r2.Rating); - Usage = (r1.Usage + r2.Usage); - RPU = (r1.RPU + r2.RPU); - // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); - NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); - } -}; - -static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) -{ - char s[128]; - unsigned startPos = (unsigned)sizeof(s) - 32; - memset(s, ' ', startPos); - ConvertUInt64ToString(value, s + startPos); - // if (withSpace) - { - startPos--; - size++; - } - unsigned len = (unsigned)strlen(s + startPos); - if (size > len) - { - startPos -= (size - len); - if (startPos < 0) - startPos = 0; - } - f.Print(s + startPos); -} - -static const unsigned kFieldSize_Name = 12; -static const unsigned kFieldSize_SmallName = 4; -static const unsigned kFieldSize_Speed = 9; -static const unsigned kFieldSize_Usage = 5; -static const unsigned kFieldSize_RU = 6; -static const unsigned kFieldSize_Rating = 6; -static const unsigned kFieldSize_EU = 5; -static const unsigned kFieldSize_Effec = 5; - -static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating; -static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec; - - -static void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size) -{ - PrintNumber(f, (rating + 500000) / 1000000, size); -} - - -static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size) -{ - PrintNumber(f, (val * 100 + divider / 2) / divider, size); -} - -static void PrintChars(IBenchPrintCallback &f, char c, unsigned size) -{ - char s[256]; - memset(s, (Byte)c, size); - s[size] = 0; - f.Print(s); -} - -static void PrintSpaces(IBenchPrintCallback &f, unsigned size) -{ - PrintChars(f, ' ', size); -} - -static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq) -{ - PrintNumber(f, (usage + 5000) / 10000, kFieldSize_Usage); - PrintRating(f, rpu, kFieldSize_RU); - PrintRating(f, rating, kFieldSize_Rating); - if (showFreq) - { - if (cpuFreq == 0) - PrintSpaces(f, kFieldSize_EUAndEffec); - else - { - UInt64 ddd = cpuFreq * usage / 100; - if (ddd == 0) - ddd = 1; - PrintPercents(f, (rating * 10000), ddd, kFieldSize_EU); - PrintPercents(f, rating, cpuFreq, kFieldSize_Effec); - } - } -} - -static void PrintResults(IBenchPrintCallback *f, - const CBenchInfo &info, - unsigned weight, - UInt64 rating, - bool showFreq, UInt64 cpuFreq, - CTotalBenchRes *res) -{ - UInt64 speed = info.GetSpeed(info.UnpackSize * info.NumIterations); - if (f) - { - if (speed != 0) - PrintNumber(*f, speed / 1024, kFieldSize_Speed); - else - PrintSpaces(*f, 1 + kFieldSize_Speed); - } - UInt64 usage = info.GetUsage(); - UInt64 rpu = info.GetRatingPerUsage(rating); - if (f) - { - PrintResults(*f, usage, rpu, rating, showFreq, cpuFreq); - } - - if (res) - { - // res->NumIterations1++; - res->NumIterations2 += weight; - res->RPU += (rpu * weight); - res->Rating += (rating * weight); - res->Usage += (usage * weight); - } -} - -static void PrintTotals(IBenchPrintCallback &f, bool showFreq, UInt64 cpuFreq, const CTotalBenchRes &res) -{ - PrintSpaces(f, 1 + kFieldSize_Speed); - // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1; - UInt64 numIterations2 = res.NumIterations2; if (numIterations2 == 0) numIterations2 = 1; - PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq); -} - -static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, - bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads) -{ - f.Print("RAM "); - f.Print(sizeString); - if (size_Defined) - PrintNumber(f, (size >> 20), 6); - else - f.Print(" ?"); - f.Print(" MB, # "); - f.Print(threadsString); - PrintNumber(f, numThreads, 3); - f.NewLine(); -} - -struct CBenchCallbackToPrint: public IBenchCallback -{ - CBenchProps BenchProps; - CTotalBenchRes EncodeRes; - CTotalBenchRes DecodeRes; - IBenchPrintCallback *_file; - UInt32 DictSize; - - bool Use2Columns; - unsigned NameFieldSize; - - bool ShowFreq; - UInt64 CpuFreq; - - unsigned EncodeWeight; - unsigned DecodeWeight; - - CBenchCallbackToPrint(): - Use2Columns(false), - NameFieldSize(0), - ShowFreq(false), - CpuFreq(0), - EncodeWeight(1), - DecodeWeight(1) - {} - - void Init() { EncodeRes.Init(); DecodeRes.Init(); } - void Print(const char *s); - void NewLine(); - - HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); - HRESULT SetEncodeResult(const CBenchInfo &info, bool final); - HRESULT SetDecodeResult(const CBenchInfo &info, bool final); -}; - -HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq) -{ - ShowFreq = showFreq; - CpuFreq = cpuFreq; - return S_OK; -} - -HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final) -{ - RINOK(_file->CheckBreak()); - if (final) - { - UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); - PrintResults(_file, info, - EncodeWeight, rating, - ShowFreq, CpuFreq, &EncodeRes); - if (!Use2Columns) - _file->NewLine(); - } - return S_OK; -} - -static const char *kSep = " | "; - -HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final) -{ - RINOK(_file->CheckBreak()); - if (final) - { - UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); - if (Use2Columns) - _file->Print(kSep); - else - PrintSpaces(*_file, NameFieldSize); - CBenchInfo info2 = info; - info2.UnpackSize *= info2.NumIterations; - info2.PackSize *= info2.NumIterations; - info2.NumIterations = 1; - PrintResults(_file, info2, - DecodeWeight, rating, - ShowFreq, CpuFreq, &DecodeRes); - } - return S_OK; -} - -void CBenchCallbackToPrint::Print(const char *s) -{ - _file->Print(s); -} - -void CBenchCallbackToPrint::NewLine() -{ - _file->NewLine(); -} - -void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size) -{ - f.Print(s); - int numSpaces = size - MyStringLen(s); - if (numSpaces > 0) - PrintSpaces(f, numSpaces); -} - -void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size) -{ - int numSpaces = size - MyStringLen(s); - if (numSpaces > 0) - PrintSpaces(f, numSpaces); - f.Print(s); -} - -static HRESULT TotalBench( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 complexInCommands, - UInt32 numThreads, - bool forceUnpackSize, - size_t unpackSize, - const Byte *fileData, - IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++) - { - const CBenchMethod &bench = g_Bench[i]; - PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); - callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; - callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; - callback->BenchProps.EncComplex = bench.EncComplex; - - COneMethodInfo method; - NCOM::CPropVariant propVariant; - propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); - - size_t unpackSize2 = unpackSize; - if (!forceUnpackSize && bench.DictBits == 0) - unpackSize2 = kFilterUnpackSize; - - callback->EncodeWeight = bench.Weight; - callback->DecodeWeight = bench.Weight; - - HRESULT res = MethodBench( - EXTERNAL_CODECS_LOC_VARS - complexInCommands, - false, numThreads, method, - unpackSize2, fileData, - bench.DictBits, - printCallback, callback, &callback->BenchProps); - - if (res == E_NOTIMPL) - { - // callback->Print(" ---"); - // we need additional empty line as line for decompression results - if (!callback->Use2Columns) - callback->NewLine(); - } - else - { - RINOK(res); - } - - callback->NewLine(); - } - return S_OK; -} - - -static HRESULT FreqBench( - UInt64 complexInCommands, - UInt32 numThreads, - IBenchPrintCallback *_file, - bool showFreq, - UInt64 specifiedFreq, - UInt64 &cpuFreq, - UInt32 &res) -{ - res = 0; - cpuFreq = 0; - - UInt32 bufferSize = 1 << 20; - UInt32 complexity = kNumFreqCommands; - if (numThreads == 0) - numThreads = 1; - - #ifdef _7ZIP_ST - numThreads = 1; - #endif - - UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize); - UInt64 numIterations = complexInCommands / complexity / bsize; - if (numIterations == 0) - numIterations = 1; - - CBenchInfoCalc progressInfoSpec; - - #ifndef _7ZIP_ST - CFreqThreads threads; - if (numThreads > 1) - { - threads.Items = new CFreqInfo[numThreads]; - UInt32 i; - for (i = 0; i < numThreads; i++) - { - CFreqInfo &info = threads.Items[i]; - info.Callback = _file; - info.CallbackRes = S_OK; - info.NumIterations = numIterations; - info.Size = bufferSize; - } - progressInfoSpec.SetStartTime(); - for (i = 0; i < numThreads; i++) - { - CFreqInfo &info = threads.Items[i]; - RINOK(info.Thread.Create(FreqThreadFunction, &info)); - threads.NumThreads++; - } - threads.WaitAll(); - for (i = 0; i < numThreads; i++) - { - RINOK(threads.Items[i].CallbackRes); - } - } - else - #endif - { - progressInfoSpec.SetStartTime(); - UInt32 sum = g_BenchCpuFreqTemp; - for (UInt64 k = numIterations; k > 0; k--) - { - RINOK(_file->CheckBreak()); - sum = CountCpuFreq(sum, bufferSize, g_BenchCpuFreqTemp); - } - res += sum; - } - - CBenchInfo info; - progressInfoSpec.SetFinishTime(info); - - info.UnpackSize = 0; - info.PackSize = 0; - info.NumIterations = 1; - - if (_file) - { - { - UInt64 numCommands = (UInt64)numIterations * bufferSize * numThreads * complexity; - UInt64 rating = info.GetSpeed(numCommands); - cpuFreq = rating / numThreads; - PrintResults(_file, info, - 0, // weight - rating, - showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : cpuFreq) : 0, NULL); - } - RINOK(_file->CheckBreak()); - } - - return S_OK; -} - - - -static HRESULT CrcBench( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 complexInCommands, - UInt32 numThreads, UInt32 bufferSize, - UInt64 &speed, - UInt32 complexity, unsigned benchWeight, - const UInt32 *checkSum, - const COneMethodInfo &method, - IBenchPrintCallback *_file, - CTotalBenchRes *encodeRes, - bool showFreq, UInt64 cpuFreq) -{ - if (numThreads == 0) - numThreads = 1; - - #ifdef _7ZIP_ST - numThreads = 1; - #endif - - AString methodName = method.MethodName; - // methodName.RemoveChar(L'-'); - CMethodId hashID; - if (!FindHashMethod( - EXTERNAL_CODECS_LOC_VARS - methodName, hashID)) - return E_NOTIMPL; - - CBenchBuffer buffer; - size_t totalSize = (size_t)bufferSize * numThreads; - if (totalSize / numThreads != bufferSize) - return E_OUTOFMEMORY; - if (!buffer.Alloc(totalSize)) - return E_OUTOFMEMORY; - - Byte *buf = buffer.Buffer; - CBaseRandomGenerator RG; - UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize); - UInt64 numIterations = complexInCommands * 256 / complexity / bsize; - if (numIterations == 0) - numIterations = 1; - - CBenchInfoCalc progressInfoSpec; - - #ifndef _7ZIP_ST - CCrcThreads threads; - if (numThreads > 1) - { - threads.Items = new CCrcInfo[numThreads]; - - UInt32 i; - for (i = 0; i < numThreads; i++) - { - CCrcInfo &info = threads.Items[i]; - AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, info.Hasher)); - if (!info.Hasher) - return E_NOTIMPL; - CMyComPtr scp; - info.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); - if (scp) - { - UInt64 reduceSize = 1; - RINOK(method.SetCoderProps(scp, &reduceSize)); - } - - Byte *data = buf + (size_t)bufferSize * i; - info.Callback = _file; - info.Data = data; - info.NumIterations = numIterations; - info.Size = bufferSize; - /* info.Crc = */ RandGenCrc(data, bufferSize, RG); - info.CheckSumDefined = false; - if (checkSum) - { - info.CheckSum = *checkSum; - info.CheckSumDefined = (checkSum && (i == 0)); - } - - #ifdef USE_ALLOCA - info.AllocaSize = (i * 16 * 21) & 0x7FF; - #endif - } - - progressInfoSpec.SetStartTime(); - - for (i = 0; i < numThreads; i++) - { - CCrcInfo &info = threads.Items[i]; - RINOK(info.Thread.Create(CrcThreadFunction, &info)); - threads.NumThreads++; - } - threads.WaitAll(); - for (i = 0; i < numThreads; i++) - { - RINOK(threads.Items[i].Res); - } - } - else - #endif - { - /* UInt32 crc = */ RandGenCrc(buf, bufferSize, RG); - progressInfoSpec.SetStartTime(); - CMyComPtr hasher; - AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)); - if (!hasher) - return E_NOTIMPL; - CMyComPtr scp; - hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); - if (scp) - { - UInt64 reduceSize = 1; - RINOK(method.SetCoderProps(scp, &reduceSize)); - } - RINOK(CrcBig(buf, bufferSize, numIterations, checkSum, hasher, _file)); - } - - CBenchInfo info; - progressInfoSpec.SetFinishTime(info); - - UInt64 unpSize = numIterations * bufferSize; - UInt64 unpSizeThreads = unpSize * numThreads; - info.UnpackSize = unpSizeThreads; - info.PackSize = unpSizeThreads; - info.NumIterations = 1; - - if (_file) - { - { - UInt64 numCommands = unpSizeThreads * complexity / 256; - UInt64 rating = info.GetSpeed(numCommands); - PrintResults(_file, info, - benchWeight, rating, - showFreq, cpuFreq, encodeRes); - } - RINOK(_file->CheckBreak()); - } - - speed = info.GetSpeed(unpSizeThreads); - - return S_OK; -} - -static HRESULT TotalBench_Hash( - DECL_EXTERNAL_CODECS_LOC_VARS - UInt64 complexInCommands, - UInt32 numThreads, UInt32 bufSize, - IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback, - CTotalBenchRes *encodeRes, - bool showFreq, UInt64 cpuFreq) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++) - { - const CBenchHash &bench = g_Hash[i]; - PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); - // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; - // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; - // callback->BenchProps.EncComplex = bench.EncComplex; - - COneMethodInfo method; - NCOM::CPropVariant propVariant; - propVariant = bench.Name; - RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)); - - UInt64 speed; - HRESULT res = CrcBench( - EXTERNAL_CODECS_LOC_VARS - complexInCommands, - numThreads, bufSize, - speed, - bench.Complex, bench.Weight, - &bench.CheckSum, method, - printCallback, encodeRes, showFreq, cpuFreq); - if (res == E_NOTIMPL) - { - // callback->Print(" ---"); - } - else - { - RINOK(res); - } - callback->NewLine(); - } - return S_OK; -} - -struct CTempValues -{ - UInt64 *Values; - CTempValues(UInt32 num) { Values = new UInt64[num]; } - ~CTempValues() { delete []Values; } -}; - -static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) -{ - const wchar_t *end; - UInt64 result = ConvertStringToUInt64(s, &end); - if (*end != 0 || s.IsEmpty()) - prop = s; - else if (result <= (UInt32)0xFFFFFFFF) - prop = (UInt32)result; - else - prop = result; -} - -static UInt32 GetNumThreadsNext(unsigned i, UInt32 numThreads) -{ - if (i < 2) - return i + 1; - i -= 1; - UInt32 num = (UInt32)(2 + (i & 1)) << (i >> 1); - return (num <= numThreads) ? num : numThreads; -} - -static bool AreSameMethodNames(const char *fullName, const char *shortName) -{ - for (;;) - { - char c2 = *shortName++; - if (c2 == 0) - return true; - char c1 = *fullName++; - if (MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) - return false; - } -} - - -#if defined(MY_CPU_X86_OR_AMD64) && defined(_7ZIP_ASM) - -static void PrintCpuChars(AString &s, UInt32 v) -{ - for (int j = 0; j < 4; j++) - { - Byte b = (Byte)(v & 0xFF); - v >>= 8; - if (b == 0) - break; - s += (char)b; - } -} - -static void x86cpuid_to_String(const Cx86cpuid &c, AString &s) -{ - s.Empty(); - - UInt32 maxFunc2 = 0; - UInt32 t[3]; - - MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]); - - bool fullNameIsAvail = (maxFunc2 >= 0x80000004); - - if (!fullNameIsAvail) - { - for (int i = 0; i < 3; i++) - PrintCpuChars(s, c.vendor[i]); - } - else - { - for (int i = 0; i < 3; i++) - { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000002 + i, &d[0], &d[1], &d[2], &d[3]); - for (int j = 0; j < 4; j++) - PrintCpuChars(s, d[j]); - } - } - - s.Add_Space_if_NotEmpty(); - { - char temp[32]; - ConvertUInt32ToHex(c.ver, temp); - s += '('; - s += temp; - s += ')'; - } -} - -#endif - - -void GetCpuName(AString &s) -{ - s.Empty(); - - #ifdef MY_CPU_X86_OR_AMD64 - { - #ifdef _7ZIP_ASM - Cx86cpuid cpuid; - if (x86cpuid_CheckAndRead(&cpuid)) - { - x86cpuid_to_String(cpuid, s); - return; - } - #endif - #ifdef MY_CPU_AMD64 - s = "x64"; - #else - s = "x86"; - #endif - } - #else - - #ifdef MY_CPU_LE - s = "LE"; - #elif defined(MY_CPU_BE) - s = "BE"; - #endif - - #endif -} - - -HRESULT Bench( - DECL_EXTERNAL_CODECS_LOC_VARS - IBenchPrintCallback *printCallback, - IBenchCallback *benchCallback, - const CObjectVector &props, - UInt32 numIterations, - bool multiDict) -{ - if (!CrcInternalTest()) - return S_FALSE; - - UInt32 numCPUs = 1; - UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; - - #ifndef _7ZIP_ST - numCPUs = NSystem::GetNumberOfProcessors(); - #endif - - bool ramSize_Defined = NSystem::GetRamSize(ramSize); - - UInt32 numThreadsSpecified = numCPUs; - - UInt32 testTime = kComplexInSeconds; - - UInt64 specifiedFreq = 0; - - bool multiThreadTests = false; - - COneMethodInfo method; - - CBenchBuffer fileDataBuffer; - - { - unsigned i; - for (i = 0; i < props.Size(); i++) - { - const CProperty &property = props[i]; - UString name = property.Name; - name.MakeLower_Ascii(); - - if (name.IsEqualTo("file")) - { - if (property.Value.IsEmpty()) - return E_INVALIDARG; - - #ifdef USE_WIN_FILE - - NFile::NIO::CInFile file; - if (!file.Open(us2fs(property.Value))) - return E_INVALIDARG; - UInt64 len; - if (!file.GetLength(len)) - return E_FAIL; - if (len >= ((UInt32)1 << 31) || len == 0) - return E_INVALIDARG; - if (!fileDataBuffer.Alloc((size_t)len)) - return E_OUTOFMEMORY; - UInt32 processedSize; - file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize); - if (processedSize != len) - return E_FAIL; - if (printCallback) - { - printCallback->Print("file size ="); - // printCallback->Print(GetOemString(property.Value)); - PrintNumber(*printCallback, len, 0); - printCallback->NewLine(); - } - continue; - - #else - - return E_NOTIMPL; - - #endif - } - - NCOM::CPropVariant propVariant; - if (!property.Value.IsEmpty()) - ParseNumberString(property.Value, propVariant); - - if (name.IsEqualTo("time")) - { - RINOK(ParsePropToUInt32(L"", propVariant, testTime)); - continue; - } - - if (name.IsEqualTo("freq")) - { - UInt32 freq32 = 0; - RINOK(ParsePropToUInt32(L"", propVariant, freq32)); - if (freq32 == 0) - return E_INVALIDARG; - specifiedFreq = (UInt64)freq32 * 1000000; - - if (printCallback) - { - printCallback->Print("freq="); - PrintNumber(*printCallback, freq32, 0); - printCallback->NewLine(); - } - - continue; - } - - if (name.IsPrefixedBy_Ascii_NoCase("mt")) - { - UString s = name.Ptr(2); - if (s == L"*") - { - multiThreadTests = true; - continue; - } - if (s.IsEmpty() && propVariant.vt == VT_BSTR) - { - if (wcscmp(propVariant.bstrVal, L"*") == 0) - { - multiThreadTests = true; - continue; - } - } - #ifndef _7ZIP_ST - RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)); - #endif - continue; - } - - RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); - } - } - - if (printCallback) - { - AString s; - GetCpuName(s); - printCallback->Print(s); - printCallback->NewLine(); - } - - if (printCallback) - { - printCallback->Print("CPU Freq:"); - } - - UInt64 complexInCommands = kComplexInCommands; - - if (printCallback /* || benchCallback */) - { - UInt64 numMilCommands = 1 << 6; - if (specifiedFreq != 0) - { - while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) - numMilCommands >>= 1; - } - - for (int jj = 0;; jj++) - { - if (printCallback) - RINOK(printCallback->CheckBreak()); - - UInt64 start = ::GetTimeCount(); - UInt32 sum = (UInt32)start; - sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp); - const UInt64 realDelta = ::GetTimeCount() - start; - start = realDelta; - if (start == 0) - start = 1; - UInt64 freq = GetFreq(); - // mips is constant in some compilers - const UInt64 mipsVal = numMilCommands * freq / start; - if (printCallback) - { - if (realDelta == 0) - { - printCallback->Print(" -"); - } - else - { - // PrintNumber(*printCallback, start, 0); - PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0)); - } - } - /* - if (benchCallback) - benchCallback->AddCpuFreq(mipsVal); - */ - - if (jj >= 3) - { - SetComplexCommands(testTime, false, mipsVal * 1000000, complexInCommands); - if (jj >= 8 || start >= freq) - break; - // break; // change it - numMilCommands <<= 1; - } - } - } - - if (printCallback) - { - printCallback->NewLine(); - printCallback->NewLine(); - PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs); - } - - if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax) - return E_INVALIDARG; - - UInt32 dict; - bool dictIsDefined = method.Get_DicSize(dict); - - if (method.MethodName.IsEmpty()) - method.MethodName = "LZMA"; - - if (benchCallback) - { - CBenchProps benchProps; - benchProps.SetLzmaCompexity(); - UInt32 dictSize = method.Get_Lzma_DicSize(); - UInt32 uncompressedDataSize = kAdditionalSize + dictSize; - return MethodBench( - EXTERNAL_CODECS_LOC_VARS - complexInCommands, - true, numThreadsSpecified, - method, - uncompressedDataSize, fileDataBuffer.Buffer, - kOldLzmaDictBits, printCallback, benchCallback, &benchProps); - } - - AString methodName = method.MethodName; - if (methodName.IsEqualTo_Ascii_NoCase("CRC")) - methodName = "crc32"; - method.MethodName = methodName; - CMethodId hashID; - - if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID)) - { - if (!printCallback) - return S_FALSE; - IBenchPrintCallback &f = *printCallback; - if (!dictIsDefined) - dict = (1 << 24); - - - // methhodName.RemoveChar(L'-'); - UInt32 complexity = 10000; - const UInt32 *checkSum = NULL; - { - for (unsigned i = 0; i < ARRAY_SIZE(g_Hash); i++) - { - const CBenchHash &h = g_Hash[i]; - AString s = h.Name; - AString hProp; - int propPos = s.Find(':'); - if (propPos >= 0) - { - hProp = s.Ptr(propPos + 1); - s.DeleteFrom(propPos); - } - - if (AreSameMethodNames(s, methodName)) - { - complexity = h.Complex; - checkSum = &h.CheckSum; - if (method.PropsString.IsEqualTo_Ascii_NoCase(hProp)) - break; - } - } - } - - f.NewLine(); - f.Print("Size"); - const unsigned kFieldSize_CrcSpeed = 6; - unsigned numThreadsTests = 0; - for (;;) - { - UInt32 t = GetNumThreadsNext(numThreadsTests, numThreadsSpecified); - PrintNumber(f, t, kFieldSize_CrcSpeed); - numThreadsTests++; - if (t >= numThreadsSpecified) - break; - } - f.NewLine(); - f.NewLine(); - CTempValues speedTotals(numThreadsTests); - { - for (unsigned ti = 0; ti < numThreadsTests; ti++) - speedTotals.Values[ti] = 0; - } - - UInt64 numSteps = 0; - for (UInt32 i = 0; i < numIterations; i++) - { - for (unsigned pow = 10; pow < 32; pow++) - { - UInt32 bufSize = (UInt32)1 << pow; - if (bufSize > dict) - break; - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos++] = ' '; - s[pos] = 0; - f.Print(s); - - for (unsigned ti = 0; ti < numThreadsTests; ti++) - { - RINOK(f.CheckBreak()); - UInt32 t = GetNumThreadsNext(ti, numThreadsSpecified); - UInt64 speed = 0; - RINOK(CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, - t, bufSize, speed, - complexity, - 1, // benchWeight, - (pow == kNumHashDictBits) ? checkSum : NULL, method, NULL, NULL, false, 0)); - PrintNumber(f, (speed >> 20), kFieldSize_CrcSpeed); - speedTotals.Values[ti] += speed; - } - f.NewLine(); - numSteps++; - } - } - if (numSteps != 0) - { - f.NewLine(); - f.Print("Avg:"); - for (unsigned ti = 0; ti < numThreadsTests; ti++) - { - PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), kFieldSize_CrcSpeed); - } - f.NewLine(); - } - return S_OK; - } - - bool use2Columns = false; - - bool totalBenchMode = (method.MethodName.IsEqualTo_Ascii_NoCase("*")); - bool onlyHashBench = false; - if (method.MethodName.IsEqualTo_Ascii_NoCase("hash")) - { - onlyHashBench = true; - totalBenchMode = true; - } - - // ---------- Threads loop ---------- - for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++) - { - - UInt32 numThreads = numThreadsSpecified; - - if (!multiThreadTests) - { - if (threadsPassIndex != 0) - break; - } - else - { - numThreads = 1; - if (threadsPassIndex != 0) - { - if (numCPUs < 2) - break; - numThreads = numCPUs; - if (threadsPassIndex == 1) - { - if (numCPUs >= 4) - numThreads = numCPUs / 2; - } - else if (numCPUs < 4) - break; - } - } - - CBenchCallbackToPrint callback; - callback.Init(); - callback._file = printCallback; - - IBenchPrintCallback &f = *printCallback; - - if (threadsPassIndex > 0) - { - f.NewLine(); - f.NewLine(); - } - - if (!dictIsDefined) - { - const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); - unsigned dicSizeLog = dicSizeLog_Main; - - #ifdef UNDER_CE - dicSizeLog = (UInt64)1 << 20; - #endif - - if (ramSize_Defined) - for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) - break; - - dict = (UInt32)1 << dicSizeLog; - - if (totalBenchMode && dicSizeLog != dicSizeLog_Main) - { - f.Print("Dictionary reduced to: "); - PrintNumber(f, dicSizeLog, 1); - f.NewLine(); - } - } - - PrintRequirements(f, "usage:", true, GetBenchMemoryUsage(numThreads, dict, totalBenchMode), "Benchmark threads: ", numThreads); - - f.NewLine(); - - if (totalBenchMode) - { - callback.NameFieldSize = kFieldSize_Name; - use2Columns = false; - } - else - { - callback.NameFieldSize = kFieldSize_SmallName; - use2Columns = true; - } - callback.Use2Columns = use2Columns; - - bool showFreq = false; - UInt64 cpuFreq = 0; - - if (totalBenchMode) - { - showFreq = true; - } - - unsigned fileldSize = kFieldSize_TotalSize; - if (showFreq) - fileldSize += kFieldSize_EUAndEffec; - - if (use2Columns) - { - PrintSpaces(f, callback.NameFieldSize); - PrintRight(f, "Compressing", fileldSize); - f.Print(kSep); - PrintRight(f, "Decompressing", fileldSize); - } - f.NewLine(); - PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize); - - int j; - - for (j = 0; j < 2; j++) - { - PrintRight(f, "Speed", kFieldSize_Speed + 1); - PrintRight(f, "Usage", kFieldSize_Usage + 1); - PrintRight(f, "R/U", kFieldSize_RU + 1); - PrintRight(f, "Rating", kFieldSize_Rating + 1); - if (showFreq) - { - PrintRight(f, "E/U", kFieldSize_EU + 1); - PrintRight(f, "Effec", kFieldSize_Effec + 1); - } - if (!use2Columns) - break; - if (j == 0) - f.Print(kSep); - } - - f.NewLine(); - PrintSpaces(f, callback.NameFieldSize); - - for (j = 0; j < 2; j++) - { - PrintRight(f, "KiB/s", kFieldSize_Speed + 1); - PrintRight(f, "%", kFieldSize_Usage + 1); - PrintRight(f, "MIPS", kFieldSize_RU + 1); - PrintRight(f, "MIPS", kFieldSize_Rating + 1); - if (showFreq) - { - PrintRight(f, "%", kFieldSize_EU + 1); - PrintRight(f, "%", kFieldSize_Effec + 1); - } - if (!use2Columns) - break; - if (j == 0) - f.Print(kSep); - } - - f.NewLine(); - f.NewLine(); - - if (specifiedFreq != 0) - cpuFreq = specifiedFreq; - - - if (totalBenchMode) - { - for (UInt32 i = 0; i < numIterations; i++) - { - if (i != 0) - printCallback->NewLine(); - HRESULT res; - - const unsigned kNumCpuTests = 3; - for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++) - { - PrintLeft(f, "CPU", kFieldSize_Name); - UInt32 resVal; - RINOK(FreqBench(complexInCommands, numThreads, printCallback, - (freqTest == kNumCpuTests - 1 || specifiedFreq != 0), // showFreq - specifiedFreq, - cpuFreq, resVal)); - callback.NewLine(); - - if (specifiedFreq != 0) - cpuFreq = specifiedFreq; - - if (freqTest == kNumCpuTests - 1) - SetComplexCommands(testTime, specifiedFreq != 0, cpuFreq, complexInCommands); - } - callback.NewLine(); - - callback.SetFreq(true, cpuFreq); - - if (!onlyHashBench) - { - res = TotalBench(EXTERNAL_CODECS_LOC_VARS - complexInCommands, numThreads, - dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize - fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict, - fileDataBuffer.Buffer, - printCallback, &callback); - RINOK(res); - } - - res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS complexInCommands, numThreads, - 1 << kNumHashDictBits, printCallback, &callback, &callback.EncodeRes, true, cpuFreq); - RINOK(res); - - callback.NewLine(); - { - PrintLeft(f, "CPU", kFieldSize_Name); - UInt32 resVal; - UInt64 cpuFreqLastTemp = cpuFreq; - RINOK(FreqBench(complexInCommands, numThreads, printCallback, - specifiedFreq != 0, // showFreq - specifiedFreq, - cpuFreqLastTemp, resVal)); - callback.NewLine(); - } - } - } - else - { - bool needSetComplexity = true; - if (!methodName.IsEqualTo_Ascii_NoCase("LZMA")) - { - for (unsigned i = 0; i < ARRAY_SIZE(g_Bench); i++) - { - const CBenchMethod &h = g_Bench[i]; - AString s = h.Name; - if (AreSameMethodNames(h.Name, methodName)) - { - callback.BenchProps.EncComplex = h.EncComplex; - callback.BenchProps.DecComplexCompr = h.DecComplexCompr; - callback.BenchProps.DecComplexUnc = h.DecComplexUnc;; - needSetComplexity = false; - break; - } - } - } - if (needSetComplexity) - callback.BenchProps.SetLzmaCompexity(); - - for (unsigned i = 0; i < numIterations; i++) - { - const unsigned kStartDicLog = 22; - unsigned pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog; - if (!multiDict) - pow = 31; - while (((UInt32)1 << pow) > dict && pow > 0) - pow--; - for (; ((UInt32)1 << pow) <= dict; pow++) - { - char s[16]; - ConvertUInt32ToString(pow, s); - unsigned pos = MyStringLen(s); - s[pos++] = ':'; - s[pos] = 0; - PrintLeft(f, s, kFieldSize_SmallName); - callback.DictSize = (UInt32)1 << pow; - - COneMethodInfo method2 = method; - - if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA")) - { - // We add dictionary size property. - // method2 can have two different dictionary size properties. - // And last property is main. - NCOM::CPropVariant propVariant = (UInt32)pow; - RINOK(method2.ParseMethodFromPROPVARIANT(L"d", propVariant)); - } - - size_t uncompressedDataSize; - if (fileDataBuffer.Buffer) - { - uncompressedDataSize = fileDataBuffer.BufferSize; - } - else - { - uncompressedDataSize = callback.DictSize; - if (uncompressedDataSize >= (1 << 18)) - uncompressedDataSize += kAdditionalSize; - } - - HRESULT res = MethodBench( - EXTERNAL_CODECS_LOC_VARS - complexInCommands, - true, numThreads, - method2, - uncompressedDataSize, fileDataBuffer.Buffer, - kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps); - f.NewLine(); - RINOK(res); - if (!multiDict) - break; - } - } - } - - PrintChars(f, '-', callback.NameFieldSize + fileldSize); - - if (use2Columns) - { - f.Print(kSep); - PrintChars(f, '-', fileldSize); - } - - f.NewLine(); - - if (use2Columns) - { - PrintLeft(f, "Avr:", callback.NameFieldSize); - PrintTotals(f, showFreq, cpuFreq, callback.EncodeRes); - f.Print(kSep); - PrintTotals(f, showFreq, cpuFreq, callback.DecodeRes); - f.NewLine(); - } - - PrintLeft(f, "Tot:", callback.NameFieldSize); - CTotalBenchRes midRes; - midRes.SetSum(callback.EncodeRes, callback.DecodeRes); - PrintTotals(f, showFreq, cpuFreq, midRes); - f.NewLine(); - - } - return S_OK; -} +// Bench.cpp + +#include "StdAfx.h" + +// #include + +#ifndef _WIN32 +#define USE_POSIX_TIME +#define USE_POSIX_TIME2 +#endif // _WIN32 + +#ifdef USE_POSIX_TIME +#include +#include +#ifdef USE_POSIX_TIME2 +#include +#include +#endif +#endif // USE_POSIX_TIME + +#ifdef _WIN32 +#define USE_ALLOCA +#endif + +#ifdef USE_ALLOCA +#ifdef _WIN32 +#include +#else +#include +#endif +#define BENCH_ALLOCA_VALUE(index) (((index) * 64 * 21) & 0x7FF) +#endif + +#include "../../../../C/7zCrc.h" +#include "../../../../C/RotateDefs.h" +#include "../../../../C/CpuArch.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Thread.h" +#endif + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/SystemInfo.h" + +#include "../../../Common/MyBuffer2.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/Wildcard.h" + +#include "../../Common/MethodProps.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "Bench.h" + +using namespace NWindows; + +#ifndef Z7_ST +static const UInt32 k_LZMA = 0x030101; +#endif + +static const UInt64 kComplexInCommands = (UInt64)1 << + #ifdef UNDER_CE + 31; + #else + 34; + #endif + +static const UInt32 kComplexInMs = 4000; + +static void SetComplexCommandsMs(UInt32 complexInMs, + bool isSpecifiedFreq, UInt64 cpuFreq, UInt64 &complexInCommands) +{ + complexInCommands = kComplexInCommands; + const UInt64 kMinFreq = (UInt64)1000000 * 4; + const UInt64 kMaxFreq = (UInt64)1000000 * 20000; + if (cpuFreq < kMinFreq && !isSpecifiedFreq) + cpuFreq = kMinFreq; + if (cpuFreq < kMaxFreq || isSpecifiedFreq) + { + if (complexInMs != 0) + complexInCommands = complexInMs * cpuFreq / 1000; + else + complexInCommands = cpuFreq >> 2; + } +} + +// const UInt64 kBenchmarkUsageMult = 1000000; // for debug +static const unsigned kBenchmarkUsageMultBits = 16; +static const UInt64 kBenchmarkUsageMult = 1 << kBenchmarkUsageMultBits; + +UInt64 Benchmark_GetUsage_Percents(UInt64 usage) +{ + return (100 * usage + kBenchmarkUsageMult / 2) / kBenchmarkUsageMult; +} + +static const unsigned kNumHashDictBits = 17; +static const UInt32 kFilterUnpackSize = (47 << 10); // + 5; // for test + +static const unsigned kOldLzmaDictBits = 32; + +// static const size_t kAdditionalSize = (size_t)1 << 32; // for debug +static const size_t kAdditionalSize = (size_t)1 << 16; +static const size_t kCompressedAdditionalSize = 1 << 10; + +static const UInt32 kMaxMethodPropSize = 1 << 6; + + +#define ALLOC_WITH_HRESULT(_buffer_, _size_) \ + { (_buffer_)->Alloc(_size_); \ + if (_size_ && !(_buffer_)->IsAllocated()) return E_OUTOFMEMORY; } + + +class CBaseRandomGenerator +{ + UInt32 A1; + UInt32 A2; + UInt32 Salt; +public: + CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); } + void Init() { A1 = 362436069; A2 = 521288629;} + Z7_FORCE_INLINE + UInt32 GetRnd() + { +#if 0 + // for debug: + return 0x0c080400; + // return 0; +#else + return Salt ^ + ( + ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) + + ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ) + ); +#endif + } +}; + + +static const size_t k_RandBuf_AlignMask = 4 - 1; + +Z7_NO_INLINE +static void RandGen_BufAfterPad(Byte *buf, size_t size) +{ + CBaseRandomGenerator RG; + for (size_t i = 0; i < size; i += 4) + { + const UInt32 v = RG.GetRnd(); + SetUi32a(buf + i, v) + } + /* + UInt32 v = RG.GetRnd(); + for (; i < size; i++) + { + buf[i] = (Byte)v; + v >>= 8; + } + */ +} + + +class CBenchRandomGenerator: public CMidAlignedBuffer +{ + static UInt32 GetVal(UInt32 &res, unsigned numBits) + { + const UInt32 val = res & (((UInt32)1 << numBits) - 1); + res >>= numBits; + return val; + } + + static UInt32 GetLen(UInt32 &r) + { + const unsigned len = (unsigned)GetVal(r, 2); + return GetVal(r, 1 + len); + } + +public: + + void GenerateSimpleRandom(UInt32 salt) + { + CBaseRandomGenerator rg(salt); + const size_t bufSize = Size(); + Byte *buf = (Byte *)*this; + for (size_t i = 0; i < bufSize; i++) + buf[i] = (Byte)rg.GetRnd(); + } + + void GenerateLz(unsigned dictBits, UInt32 salt) + { + CBaseRandomGenerator rg(salt); + size_t pos = 0; + size_t rep0 = 1; + const size_t bufSize = Size(); + Byte *buf = (Byte *)*this; + unsigned posBits = 1; + + // printf("\n dictBits = %d\n", (UInt32)dictBits); + // printf("\n bufSize = 0x%p\n", (const void *)bufSize); + + while (pos < bufSize) + { + /* + if (pos >= ((UInt32)1 << 31)) + printf(" %x\n", pos); + */ + UInt32 r = rg.GetRnd(); + if (GetVal(r, 1) == 0 || pos < 1024) + buf[pos++] = (Byte)(r & 0xFF); + else + { + UInt32 len; + len = 1 + GetLen(r); + + if (GetVal(r, 3) != 0) + { + len += GetLen(r); + + while (((size_t)1 << posBits) < pos) + posBits++; + + unsigned numBitsMax = dictBits; + if (numBitsMax > posBits) + numBitsMax = posBits; + + const unsigned kAddBits = 6; + unsigned numLogBits = 5; + if (numBitsMax <= (1 << 4) - 1 + kAddBits) + numLogBits = 4; + + for (;;) + { + const UInt32 ppp = GetVal(r, numLogBits) + kAddBits; + r = rg.GetRnd(); + if (ppp > numBitsMax) + continue; + // rep0 = GetVal(r, ppp); + rep0 = r & (((size_t)1 << ppp) - 1); + if (rep0 < pos) + break; + r = rg.GetRnd(); + } + rep0++; + } + + // len *= 300; // for debug + { + const size_t rem = bufSize - pos; + if (len > rem) + len = (UInt32)rem; + } + Byte *dest = buf + pos; + const Byte *src = dest - rep0; + pos += len; + for (UInt32 i = 0; i < len; i++) + *dest++ = *src++; + } + } + // printf("\n CRC = %x\n", CrcCalc(buf, bufSize)); + } +}; + + +Z7_CLASS_IMP_NOQIB_1( + CBenchmarkInStream + , ISequentialInStream +) + const Byte *Data; + size_t Pos; + size_t Size; +public: + void Init(const Byte *data, size_t size) + { + Data = data; + Size = size; + Pos = 0; + } + bool WasFinished() const { return Pos == Size; } +}; + +Z7_COM7F_IMF(CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)) +{ + const UInt32 kMaxBlockSize = (1 << 20); + if (size > kMaxBlockSize) + size = kMaxBlockSize; + const size_t remain = Size - Pos; + if (size > remain) + size = (UInt32)remain; + + if (size) + memcpy(data, Data + Pos, size); + + Pos += size; + if (processedSize) + *processedSize = size; + return S_OK; +} + + +class CBenchmarkOutStream Z7_final: + public ISequentialOutStream, + public CMyUnknownImp, + public CMidAlignedBuffer +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ISequentialOutStream) + // bool _overflow; +public: + size_t Pos; + bool RealCopy; + bool CalcCrc; + UInt32 Crc; + + // CBenchmarkOutStream(): _overflow(false) {} + void Init(bool realCopy, bool calcCrc) + { + Crc = CRC_INIT_VAL; + RealCopy = realCopy; + CalcCrc = calcCrc; + // _overflow = false; + Pos = 0; + } + + void InitCrc() + { + Crc = CRC_INIT_VAL; + } + + void Calc(const void *data, size_t size) + { + Crc = CrcUpdate(Crc, data, size); + } + + size_t GetPos() const { return Pos; } + + // void Print() { printf("\n%8d %8d\n", (unsigned)BufferSize, (unsigned)Pos); } +}; + +Z7_COM7F_IMF(CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + size_t curSize = Size() - Pos; + if (curSize > size) + curSize = size; + if (curSize != 0) + { + if (RealCopy) + memcpy(((Byte *)*this) + Pos, data, curSize); + if (CalcCrc) + Calc(data, curSize); + Pos += curSize; + } + if (processedSize) + *processedSize = (UInt32)curSize; + if (curSize != size) + { + // _overflow = true; + return E_FAIL; + } + return S_OK; +} + + +Z7_CLASS_IMP_NOQIB_1( + CCrcOutStream + , ISequentialOutStream +) +public: + bool CalcCrc; + UInt32 Crc; + UInt64 Pos; + + CCrcOutStream(): CalcCrc(true) {} + void Init() { Crc = CRC_INIT_VAL; Pos = 0; } + void Calc(const void *data, size_t size) + { + Crc = CrcUpdate(Crc, data, size); + } +}; + +Z7_COM7F_IMF(CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (CalcCrc) + Calc(data, size); + Pos += size; + if (processedSize) + *processedSize = size; + return S_OK; +} + +// #include "../../../../C/My_sys_time.h" + +static UInt64 GetTimeCount() +{ + #ifdef USE_POSIX_TIME + #ifdef USE_POSIX_TIME2 + timeval v; + if (gettimeofday(&v, NULL) == 0) + return (UInt64)(v.tv_sec) * 1000000 + (UInt64)v.tv_usec; + return (UInt64)time(NULL) * 1000000; + #else + return time(NULL); + #endif + #else + LARGE_INTEGER value; + if (::QueryPerformanceCounter(&value)) + return (UInt64)value.QuadPart; + return GetTickCount(); + #endif +} + +static UInt64 GetFreq() +{ + #ifdef USE_POSIX_TIME + #ifdef USE_POSIX_TIME2 + return 1000000; + #else + return 1; + #endif + #else + LARGE_INTEGER value; + if (::QueryPerformanceFrequency(&value)) + return (UInt64)value.QuadPart; + return 1000; + #endif +} + + +#ifdef USE_POSIX_TIME + +struct CUserTime +{ + UInt64 Sum; + clock_t Prev; + + void Init() + { + // Prev = clock(); + Sum = 0; + Prev = 0; + Update(); + Sum = 0; + } + + void Update() + { + tms t; + /* clock_t res = */ times(&t); + clock_t newVal = t.tms_utime + t.tms_stime; + Sum += (UInt64)(newVal - Prev); + Prev = newVal; + + /* + clock_t v = clock(); + if (v != -1) + { + Sum += v - Prev; + Prev = v; + } + */ + } + UInt64 GetUserTime() + { + Update(); + return Sum; + } +}; + +#else + + +struct CUserTime +{ + bool UseTick; + DWORD Prev_Tick; + UInt64 Prev; + UInt64 Sum; + + void Init() + { + UseTick = false; + Prev_Tick = 0; + Prev = 0; + Sum = 0; + Update(); + Sum = 0; + } + UInt64 GetUserTime() + { + Update(); + return Sum; + } + void Update(); +}; + +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +void CUserTime::Update() +{ + DWORD new_Tick = GetTickCount(); + FILETIME creationTime, exitTime, kernelTime, userTime; + if (!UseTick && + #ifdef UNDER_CE + ::GetThreadTimes(::GetCurrentThread() + #else + ::GetProcessTimes(::GetCurrentProcess() + #endif + , &creationTime, &exitTime, &kernelTime, &userTime)) + { + UInt64 newVal = GetTime64(userTime) + GetTime64(kernelTime); + Sum += newVal - Prev; + Prev = newVal; + } + else + { + UseTick = true; + Sum += (UInt64)(new_Tick - (DWORD)Prev_Tick) * 10000; + } + Prev_Tick = new_Tick; +} + + +#endif + +static UInt64 GetUserFreq() +{ + #ifdef USE_POSIX_TIME + // return CLOCKS_PER_SEC; + return (UInt64)sysconf(_SC_CLK_TCK); + #else + return 10000000; + #endif +} + +class CBenchProgressStatus Z7_final +{ + #ifndef Z7_ST + NSynchronization::CCriticalSection CS; + #endif +public: + HRESULT Res; + bool EncodeMode; + void SetResult(HRESULT res) + { + #ifndef Z7_ST + NSynchronization::CCriticalSectionLock lock(CS); + #endif + Res = res; + } + HRESULT GetResult() + { + #ifndef Z7_ST + NSynchronization::CCriticalSectionLock lock(CS); + #endif + return Res; + } +}; + +struct CBenchInfoCalc +{ + CBenchInfo BenchInfo; + CUserTime UserTime; + + void SetStartTime(); + void SetFinishTime(CBenchInfo &dest); +}; + +void CBenchInfoCalc::SetStartTime() +{ + BenchInfo.GlobalFreq = GetFreq(); + BenchInfo.UserFreq = GetUserFreq(); + BenchInfo.GlobalTime = ::GetTimeCount(); + BenchInfo.UserTime = 0; + UserTime.Init(); +} + +void CBenchInfoCalc::SetFinishTime(CBenchInfo &dest) +{ + dest = BenchInfo; + dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime; + dest.UserTime = UserTime.GetUserTime(); +} + +class CBenchProgressInfo Z7_final: + public ICompressProgressInfo, + public CMyUnknownImp, + public CBenchInfoCalc +{ + Z7_COM_UNKNOWN_IMP_0 + Z7_IFACE_COM7_IMP(ICompressProgressInfo) +public: + CBenchProgressStatus *Status; + IBenchCallback *Callback; + + CBenchProgressInfo(): Callback(NULL) {} +}; + + +Z7_COM7F_IMF(CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + HRESULT res = Status->GetResult(); + if (res != S_OK) + return res; + if (!Callback) + return res; + + /* + static UInt64 inSizePrev = 0; + static UInt64 outSizePrev = 0; + UInt64 delta1 = 0, delta2 = 0, val1 = 0, val2 = 0; + if (inSize) { val1 = *inSize; delta1 = val1 - inSizePrev; inSizePrev = val1; } + if (outSize) { val2 = *outSize; delta2 = val2 - outSizePrev; outSizePrev = val2; } + UInt64 percents = delta2 * 1000; + if (delta1 != 0) + percents /= delta1; + printf("=== %7d %7d %7d %7d ratio = %4d\n", + (unsigned)(val1 >> 10), (unsigned)(delta1 >> 10), + (unsigned)(val2 >> 10), (unsigned)(delta2 >> 10), + (unsigned)percents); + */ + + CBenchInfo info; + SetFinishTime(info); + if (Status->EncodeMode) + { + info.UnpackSize = BenchInfo.UnpackSize + *inSize; + info.PackSize = BenchInfo.PackSize + *outSize; + res = Callback->SetEncodeResult(info, false); + } + else + { + info.PackSize = BenchInfo.PackSize + *inSize; + info.UnpackSize = BenchInfo.UnpackSize + *outSize; + res = Callback->SetDecodeResult(info, false); + } + if (res != S_OK) + Status->SetResult(res); + return res; +} + +static const unsigned kSubBits = 8; + +static unsigned GetLogSize(UInt64 size) +{ + unsigned i = 0; + for (;;) + { + i++; size >>= 1; if (size == 0) break; + } + return i; +} + + +static UInt32 GetLogSize_Sub(UInt64 size) +{ + if (size <= 1) + return 0; + const unsigned i = GetLogSize(size) - 1; + UInt32 v; + if (i <= kSubBits) + v = (UInt32)(size) << (kSubBits - i); + else + v = (UInt32)(size >> (i - kSubBits)); + return ((UInt32)i << kSubBits) + (v & (((UInt32)1 << kSubBits) - 1)); +} + + +static UInt64 Get_UInt64_from_double(double v) +{ + const UInt64 kMaxVal = (UInt64)1 << 62; + if (v > (double)(Int64)kMaxVal) + return kMaxVal; + return (UInt64)v; +} + +static UInt64 MyMultDiv64(UInt64 m1, UInt64 m2, UInt64 d) +{ + if (d == 0) + d = 1; + const double v = + (double)(Int64)m1 * + (double)(Int64)m2 / + (double)(Int64)d; + return Get_UInt64_from_double(v); + /* + unsigned n1 = GetLogSize(m1); + unsigned n2 = GetLogSize(m2); + while (n1 + n2 > 64) + { + if (n1 >= n2) + { + m1 >>= 1; + n1--; + } + else + { + m2 >>= 1; + n2--; + } + d >>= 1; + } + + if (d == 0) + d = 1; + return m1 * m2 / d; + */ +} + + +UInt64 CBenchInfo::GetUsage() const +{ + UInt64 userTime = UserTime; + UInt64 userFreq = UserFreq; + UInt64 globalTime = GlobalTime; + UInt64 globalFreq = GlobalFreq; + + if (userFreq == 0) + userFreq = 1; + if (globalTime == 0) + globalTime = 1; + + const double v = + ((double)(Int64)userTime / (double)(Int64)userFreq) + * ((double)(Int64)globalFreq / (double)(Int64)globalTime) + * (double)(Int64)kBenchmarkUsageMult; + return Get_UInt64_from_double(v); + /* + return MyMultDiv64( + MyMultDiv64(kBenchmarkUsageMult, userTime, userFreq), + globalFreq, globalTime); + */ +} + + +UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const +{ + if (UserTime == 0) + { + return 0; + // userTime = 1; + } + UInt64 globalFreq = GlobalFreq; + if (globalFreq == 0) + globalFreq = 1; + + const double v = + ((double)(Int64)GlobalTime / (double)(Int64)globalFreq) + * ((double)(Int64)UserFreq / (double)(Int64)UserTime) + * (double)(Int64)rating; + return Get_UInt64_from_double(v); + /* + return MyMultDiv64( + MyMultDiv64(rating, UserFreq, UserTime), + GlobalTime, globalFreq); + */ +} + + +UInt64 CBenchInfo::GetSpeed(UInt64 numUnits) const +{ + return MyMultDiv64(numUnits, GlobalFreq, GlobalTime); +} + +static UInt64 GetNumCommands_from_Size_and_Complexity(UInt64 size, Int32 complexity) +{ + return complexity >= 0 ? + size * (UInt32)complexity : + size / (UInt32)(-complexity); +} + +struct CBenchProps +{ + bool LzmaRatingMode; + + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; + + unsigned KeySize; + + CBenchProps(): + LzmaRatingMode(false), + KeySize(0) + {} + + void SetLzmaCompexity(); + + UInt64 GetNumCommands_Enc(UInt64 unpackSize) const + { + const UInt32 kMinSize = 100; + if (unpackSize < kMinSize) + unpackSize = kMinSize; + return GetNumCommands_from_Size_and_Complexity(unpackSize, EncComplex); + } + + UInt64 GetNumCommands_Dec(UInt64 packSize, UInt64 unpackSize) const + { + return + GetNumCommands_from_Size_and_Complexity(packSize, DecComplexCompr) + + GetNumCommands_from_Size_and_Complexity(unpackSize, DecComplexUnc); + } + + UInt64 GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const; + UInt64 GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const; +}; + +void CBenchProps::SetLzmaCompexity() +{ + EncComplex = 1200; + DecComplexUnc = 4; + DecComplexCompr = 190; + LzmaRatingMode = true; +} + +UInt64 CBenchProps::GetRating_Enc(UInt64 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size) const +{ + if (dictSize < (1 << kBenchMinDicLogSize)) + dictSize = (1 << kBenchMinDicLogSize); + Int32 encComplex = EncComplex; + if (LzmaRatingMode) + { + /* + for (UInt64 uu = 0; uu < (UInt64)0xf << 60;) + { + unsigned rr = GetLogSize_Sub(uu); + printf("\n%16I64x , log = %4x", uu, rr); + uu += 1; + uu += uu / 50; + } + */ + // throw 1; + const UInt32 t = GetLogSize_Sub(dictSize) - (kBenchMinDicLogSize << kSubBits); + encComplex = 870 + ((t * t * 5) >> (2 * kSubBits)); + } + const UInt64 numCommands = GetNumCommands_from_Size_and_Complexity(size, encComplex); + return MyMultDiv64(numCommands, freq, elapsedTime); +} + +UInt64 CBenchProps::GetRating_Dec(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations) const +{ + const UInt64 numCommands = GetNumCommands_Dec(inSize, outSize) * numIterations; + return MyMultDiv64(numCommands, freq, elapsedTime); +} + + + +UInt64 CBenchInfo::GetRating_LzmaEnc(UInt64 dictSize) const +{ + CBenchProps props; + props.SetLzmaCompexity(); + return props.GetRating_Enc(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); +} + +UInt64 CBenchInfo::GetRating_LzmaDec() const +{ + CBenchProps props; + props.SetLzmaCompexity(); + return props.GetRating_Dec(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); +} + + +#ifndef Z7_ST + +#define NUM_CPU_LEVELS_MAX 3 + +struct CAffinityMode +{ + unsigned NumBundleThreads; + unsigned NumLevels; + unsigned NumCoreThreads; + unsigned NumCores; + // unsigned DivideNum; + +#ifdef _WIN32 + unsigned NumGroups; +#endif + + UInt32 Sizes[NUM_CPU_LEVELS_MAX]; + + void SetLevels(unsigned numCores, unsigned numCoreThreads); + DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const; + bool NeedAffinity() const { return NumBundleThreads != 0; } + +#ifdef _WIN32 + bool NeedGroupsMode() const { return NumGroups > 1; } +#endif + + WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const + { +#ifdef _WIN32 + if (NeedGroupsMode()) // we need fix for bundleIndex usage + return thread.Create_With_Group(startAddress, parameter, bundleIndex % NumGroups); +#endif + if (NeedAffinity()) + { + CCpuSet cpuSet; + GetAffinityMask(bundleIndex, &cpuSet); + return thread.Create_With_CpuSet(startAddress, parameter, &cpuSet); + } + return thread.Create(startAddress, parameter); + } + + CAffinityMode(): + NumBundleThreads(0), + NumLevels(0), + NumCoreThreads(1) +#ifdef _WIN32 + , NumGroups(0) +#endif + // DivideNum(1) + {} +}; + +void CAffinityMode::SetLevels(unsigned numCores, unsigned numCoreThreads) +{ + NumCores = numCores; + NumCoreThreads = numCoreThreads; + NumLevels = 0; + if (numCoreThreads == 0 || numCores == 0 || numCores % numCoreThreads != 0) + return; + UInt32 c = numCores / numCoreThreads; + UInt32 c2 = 1; + while ((c & 1) == 0) + { + c >>= 1; + c2 <<= 1; + } + if (c2 != 1) + Sizes[NumLevels++] = c2; + if (c != 1) + Sizes[NumLevels++] = c; + if (numCoreThreads != 1) + Sizes[NumLevels++] = numCoreThreads; + if (NumLevels == 0) + Sizes[NumLevels++] = 1; + + /* + printf("\n Cores:"); + for (unsigned i = 0; i < NumLevels; i++) + { + printf(" %d", Sizes[i]); + } + printf("\n"); + */ +} + + +DWORD_PTR CAffinityMode::GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const +{ + CpuSet_Zero(cpuSet); + + if (NumLevels == 0) + return 0; + + // printf("\n%2d", bundleIndex); + + /* + UInt32 low = 0; + if (DivideNum != 1) + { + low = bundleIndex % DivideNum; + bundleIndex /= DivideNum; + } + */ + + UInt32 numGroups = NumCores / NumBundleThreads; + UInt32 m = bundleIndex % numGroups; + UInt32 v = 0; + for (unsigned i = 0; i < NumLevels; i++) + { + UInt32 size = Sizes[i]; + while ((size & 1) == 0) + { + v *= 2; + v |= (m & 1); + m >>= 1; + size >>= 1; + } + v *= size; + v += m % size; + m /= size; + } + + // UInt32 nb = NumBundleThreads / DivideNum; + UInt32 nb = NumBundleThreads; + + DWORD_PTR mask = ((DWORD_PTR)1 << nb) - 1; + // v += low; + mask <<= v; + + // printf(" %2d %8x \n ", v, (unsigned)mask); + #ifdef _WIN32 + *cpuSet = mask; + #else + { + for (unsigned k = 0; k < nb; k++) + CpuSet_Set(cpuSet, v + k); + } + #endif + + return mask; +} + + +struct CBenchSyncCommon +{ + bool ExitMode; + NSynchronization::CManualResetEvent StartEvent; + + CBenchSyncCommon(): ExitMode(false) {} +}; + +#endif + + + +enum E_CheckCrcMode +{ + k_CheckCrcMode_Never = 0, + k_CheckCrcMode_Always = 1, + k_CheckCrcMode_FirstPass = 2 +}; + +class CEncoderInfo; + +class CEncoderInfo Z7_final +{ + Z7_CLASS_NO_COPY(CEncoderInfo) + +public: + + #ifndef Z7_ST + NWindows::CThread thread[2]; + NSynchronization::CManualResetEvent ReadyEvent; + UInt32 NumDecoderSubThreads; + CBenchSyncCommon *Common; + UInt32 EncoderIndex; + UInt32 NumEncoderInternalThreads; + CAffinityMode AffinityMode; + bool IsGlobalMtMode; // if more than one benchmark encoder threads + #endif + + CMyComPtr _encoder; + CMyComPtr _encoderFilter; + CBenchProgressInfo *progressInfoSpec[2]; + CMyComPtr progressInfo[2]; + UInt64 NumIterations; + + UInt32 Salt; + + #ifdef USE_ALLOCA + size_t AllocaSize; + #endif + + unsigned KeySize; + Byte _key[32]; + Byte _iv[16]; + + HRESULT Set_Key_and_IV(ICryptoProperties *cp) + { + RINOK(cp->SetKey(_key, KeySize)) + return cp->SetInitVector(_iv, sizeof(_iv)); + } + + Byte _psw[16]; + + bool CheckCrc_Enc; /* = 1, if we want to check packed data crcs after each pass + used for filter and usual coders */ + bool UseRealData_Enc; /* = 1, if we want to use only original data for each pass + used only for filter */ + E_CheckCrcMode CheckCrcMode_Dec; + + struct CDecoderInfo + { + CEncoderInfo *Encoder; + UInt32 DecoderIndex; + bool CallbackMode; + + #ifdef USE_ALLOCA + size_t AllocaSize; + #endif + }; + CDecoderInfo decodersInfo[2]; + + CMyComPtr _decoders[2]; + CMyComPtr _decoderFilter; + + HRESULT Results[2]; + CBenchmarkOutStream *outStreamSpec; + CMyComPtr outStream; + IBenchCallback *callback; + IBenchPrintCallback *printCallback; + UInt32 crc; + size_t kBufferSize; + size_t compressedSize; + const Byte *uncompressedDataPtr; + + const Byte *fileData; + CBenchRandomGenerator rg; + + CMidAlignedBuffer rgCopy; // it must be 16-byte aligned !!! + + // CBenchmarkOutStream *propStreamSpec; + Byte propsData[kMaxMethodPropSize]; + CBufPtrSeqOutStream *propStreamSpec; + CMyComPtr propStream; + + unsigned generateDictBits; + COneMethodInfo _method; + + // for decode + size_t _uncompressedDataSize; + + HRESULT Generate(); + HRESULT Encode(); + HRESULT Decode(UInt32 decoderIndex); + + CEncoderInfo(): + #ifndef Z7_ST + Common(NULL), + IsGlobalMtMode(true), + #endif + Salt(0), + KeySize(0), + CheckCrc_Enc(true), + UseRealData_Enc(true), + CheckCrcMode_Dec(k_CheckCrcMode_Always), + outStreamSpec(NULL), + callback(NULL), + printCallback(NULL), + fileData(NULL), + propStreamSpec(NULL) + {} + + #ifndef Z7_ST + + static THREAD_FUNC_DECL EncodeThreadFunction(void *param) + { + HRESULT res; + CEncoderInfo *encoder = (CEncoderInfo *)param; + try + { + #ifdef USE_ALLOCA + alloca(encoder->AllocaSize); + #endif + + res = encoder->Encode(); + } + catch(...) + { + res = E_FAIL; + } + encoder->Results[0] = res; + if (res != S_OK) + encoder->progressInfoSpec[0]->Status->SetResult(res); + encoder->ReadyEvent.Set(); + return THREAD_FUNC_RET_ZERO; + } + + static THREAD_FUNC_DECL DecodeThreadFunction(void *param) + { + CDecoderInfo *decoder = (CDecoderInfo *)param; + + #ifdef USE_ALLOCA + alloca(decoder->AllocaSize); + // printf("\nalloca=%d\n", (unsigned)decoder->AllocaSize); + #endif + + CEncoderInfo *encoder = decoder->Encoder; + encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex); + return THREAD_FUNC_RET_ZERO; + } + + HRESULT CreateEncoderThread() + { + WRes res = 0; + if (!ReadyEvent.IsCreated()) + res = ReadyEvent.Create(); + if (res == 0) + res = AffinityMode.CreateThread_WithAffinity(thread[0], EncodeThreadFunction, this, + EncoderIndex); + return HRESULT_FROM_WIN32(res); + } + + HRESULT CreateDecoderThread(unsigned index, bool callbackMode + #ifdef USE_ALLOCA + , size_t allocaSize + #endif + ) + { + CDecoderInfo &decoder = decodersInfo[index]; + decoder.DecoderIndex = index; + decoder.Encoder = this; + + #ifdef USE_ALLOCA + decoder.AllocaSize = allocaSize; + #endif + + decoder.CallbackMode = callbackMode; + + WRes res = AffinityMode.CreateThread_WithAffinity(thread[index], DecodeThreadFunction, &decoder, + // EncoderIndex * NumEncoderInternalThreads + index + EncoderIndex + ); + + return HRESULT_FROM_WIN32(res); + } + + #endif +}; + + + + +static size_t GetBenchCompressedSize(size_t bufferSize) +{ + return kCompressedAdditionalSize + bufferSize + bufferSize / 16; + // kBufferSize / 2; +} + + +HRESULT CEncoderInfo::Generate() +{ + const COneMethodInfo &method = _method; + + // we need extra space, if input data is already compressed + const size_t kCompressedBufferSize = _encoderFilter ? + kBufferSize : + GetBenchCompressedSize(kBufferSize); + + if (kCompressedBufferSize < kBufferSize) + return E_FAIL; + + uncompressedDataPtr = fileData; + if (fileData) + { + #if !defined(Z7_ST) + if (IsGlobalMtMode) + { + /* we copy the data to local buffer of thread to eliminate + using of shared buffer by different threads */ + ALLOC_WITH_HRESULT(&rg, kBufferSize) + memcpy((Byte *)rg, fileData, kBufferSize); + uncompressedDataPtr = (const Byte *)rg; + } + #endif + } + else + { + ALLOC_WITH_HRESULT(&rg, kBufferSize) + // DWORD ttt = GetTickCount(); + if (generateDictBits == 0) + rg.GenerateSimpleRandom(Salt); + else + { + if (generateDictBits >= sizeof(size_t) * 8 + && kBufferSize > ((size_t)1 << (sizeof(size_t) * 8 - 1))) + return E_INVALIDARG; + rg.GenerateLz(generateDictBits, Salt); + // return E_ABORT; // for debug + } + // printf("\n%d\n ", GetTickCount() - ttt); + + crc = CrcCalc((const Byte *)rg, rg.Size()); + uncompressedDataPtr = (const Byte *)rg; + } + + if (!outStream) + { + outStreamSpec = new CBenchmarkOutStream; + outStream = outStreamSpec; + } + + ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize) + + if (_encoderFilter) + { + /* we try to reduce the number of memcpy() in main encoding loop. + so we copy data to temp buffers here */ + ALLOC_WITH_HRESULT(&rgCopy, kBufferSize) + memcpy((Byte *)*outStreamSpec, uncompressedDataPtr, kBufferSize); + memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize); + } + + if (!propStream) + { + propStreamSpec = new CBufPtrSeqOutStream; // CBenchmarkOutStream; + propStream = propStreamSpec; + } + // ALLOC_WITH_HRESULT_2(propStreamSpec, kMaxMethodPropSize); + // propStreamSpec->Init(true, false); + propStreamSpec->Init(propsData, sizeof(propsData)); + + + CMyComPtr coder; + if (_encoderFilter) + coder = _encoderFilter; + else + coder = _encoder; + { + CMyComPtr scp; + coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); + if (scp) + { + const UInt64 reduceSize = kBufferSize; + /* in posix : new thread uses same affinity as parent thread, + so we don't need to send affinity to coder in posix */ + UInt64 affMask = 0; + UInt32 affinityGroup = (UInt32)(Int32)-1; + // UInt64 affinityInGroup = 0; +#if !defined(Z7_ST) && defined(_WIN32) + { + CCpuSet cpuSet; + if (AffinityMode.NeedGroupsMode()) // we need fix for affinityInGroup also + affinityGroup = EncoderIndex % AffinityMode.NumGroups; + else + affMask = AffinityMode.GetAffinityMask(EncoderIndex, &cpuSet); + } +#endif + // affMask <<= 3; // debug line: to test no affinity in coder + // affMask = 0; // for debug + // affinityGroup = 0; // for debug + // affinityInGroup = 1; // for debug + RINOK(method.SetCoderProps_DSReduce_Aff(scp, &reduceSize, + affMask != 0 ? &affMask : NULL, + affinityGroup != (UInt32)(Int32)-1 ? &affinityGroup : NULL, + /* affinityInGroup != 0 ? &affinityInGroup : */ NULL)) + } + else + { + if (method.AreThereNonOptionalProps()) + return E_INVALIDARG; + } + + CMyComPtr writeCoderProps; + coder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps); + if (writeCoderProps) + { + RINOK(writeCoderProps->WriteCoderProperties(propStream)) + } + + { + CMyComPtr sp; + coder.QueryInterface(IID_ICryptoSetPassword, &sp); + if (sp) + { + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) + + // we must call encoding one time to calculate password key for key cache. + // it must be after WriteCoderProperties! + Byte temp[16]; + memset(temp, 0, sizeof(temp)); + + if (_encoderFilter) + { + _encoderFilter->Init(); + _encoderFilter->Filter(temp, sizeof(temp)); + } + else + { + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + CMyComPtr inStream = inStreamSpec; + inStreamSpec->Init(temp, sizeof(temp)); + + CCrcOutStream *crcStreamSpec = new CCrcOutStream; + CMyComPtr crcStream = crcStreamSpec; + crcStreamSpec->Init(); + + RINOK(_encoder->Code(inStream, crcStream, NULL, NULL, NULL)) + } + } + } + } + + return S_OK; +} + + +static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size, UInt32 *crc) +{ + while (size != 0) + { + UInt32 cur = crc ? 1 << 17 : 1 << 24; + if (cur > size) + cur = (UInt32)size; + UInt32 processed = filter->Filter(data, cur); + /* if (processed > size) (in AES filter), we must fill last block with zeros. + but it is not important for benchmark. So we just copy that data without filtering. + if (processed == 0) then filter can't process more */ + if (processed > size || processed == 0) + processed = (UInt32)size; + if (crc) + *crc = CrcUpdate(*crc, data, processed); + data += processed; + size -= processed; + } +} + + +HRESULT CEncoderInfo::Encode() +{ + // printf("\nCEncoderInfo::Generate\n"); + + RINOK(Generate()) + + // printf("\n2222\n"); + + #ifndef Z7_ST + if (Common) + { + Results[0] = S_OK; + WRes wres = ReadyEvent.Set(); + if (wres == 0) + wres = Common->StartEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + if (Common->ExitMode) + return S_OK; + } + else + #endif + { + CBenchProgressInfo *bpi = progressInfoSpec[0]; + bpi->SetStartTime(); + } + + + CBenchInfo &bi = progressInfoSpec[0]->BenchInfo; + bi.UnpackSize = 0; + bi.PackSize = 0; + CMyComPtr cp; + CMyComPtr coder; + if (_encoderFilter) + coder = _encoderFilter; + else + coder = _encoder; + coder.QueryInterface(IID_ICryptoProperties, &cp); + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + CMyComPtr inStream = inStreamSpec; + + if (cp) + { + RINOK(Set_Key_and_IV(cp)) + } + + compressedSize = 0; + if (_encoderFilter) + compressedSize = kBufferSize; + + // CBenchmarkOutStream *outStreamSpec = this->outStreamSpec; + UInt64 prev = 0; + + const UInt32 mask = (CheckCrc_Enc ? 0 : 0xFFFF); + const bool useCrc = (mask < NumIterations); + bool crcPrev_defined = false; + UInt32 crcPrev = 0; + + bool useRealData_Enc = UseRealData_Enc; + bool data_Was_Changed = false; + if (useRealData_Enc) + { + /* we want memcpy() for each iteration including first iteration. + So results will be equal for different number of iterations */ + data_Was_Changed = true; + } + + const UInt64 numIterations = NumIterations; + UInt64 i = numIterations; + // printCallback->NewLine(); + + while (i != 0) + { + i--; + if (printCallback && bi.UnpackSize - prev >= (1 << 26)) + { + prev = bi.UnpackSize; + RINOK(printCallback->CheckBreak()) + } + + /* + CBenchInfo info; + progressInfoSpec[0]->SetStartTime(); + */ + + bool calcCrc = false; + if (useCrc) + calcCrc = (((UInt32)i & mask) == 0); + + if (_encoderFilter) + { + Byte *filterData = rgCopy; + if (i == numIterations - 1 || calcCrc || useRealData_Enc) + { + // printf("\nfilterData = (Byte *)*outStreamSpec;\n"); + filterData = (Byte *)*outStreamSpec; + if (data_Was_Changed) + { + // printf("\nmemcpy(filterData, uncompressedDataPtr\n"); + memcpy(filterData, uncompressedDataPtr, kBufferSize); + } + data_Was_Changed = true; + } + _encoderFilter->Init(); + if (calcCrc) + { + // printf("\nInitCrc\n"); + outStreamSpec->InitCrc(); + } + // printf("\nMy_FilterBench\n"); + My_FilterBench(_encoderFilter, filterData, kBufferSize, + calcCrc ? &outStreamSpec->Crc : NULL); + } + else + { + outStreamSpec->Init(true, calcCrc); // write real data for speed consistency at any number of iterations + inStreamSpec->Init(uncompressedDataPtr, kBufferSize); + RINOK(_encoder->Code(inStream, outStream, NULL, NULL, progressInfo[0])) + if (!inStreamSpec->WasFinished()) + return E_FAIL; + if (compressedSize != outStreamSpec->Pos) + { + if (compressedSize != 0) + return E_FAIL; + compressedSize = outStreamSpec->Pos; + } + } + + // outStreamSpec->Print(); + + if (calcCrc) + { + const UInt32 crc2 = CRC_GET_DIGEST(outStreamSpec->Crc); + if (crcPrev_defined && crcPrev != crc2) + return E_FAIL; + crcPrev = crc2; + crcPrev_defined = true; + } + + bi.UnpackSize += kBufferSize; + bi.PackSize += compressedSize; + + /* + { + progressInfoSpec[0]->SetFinishTime(info); + info.UnpackSize = 0; + info.PackSize = 0; + info.NumIterations = 1; + + info.UnpackSize = kBufferSize; + info.PackSize = compressedSize; + // printf("\n%7d\n", encoder.compressedSize); + + RINOK(callback->SetEncodeResult(info, true)) + printCallback->NewLine(); + } + */ + + } + + _encoder.Release(); + _encoderFilter.Release(); + return S_OK; +} + + +HRESULT CEncoderInfo::Decode(UInt32 decoderIndex) +{ + CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream; + CMyComPtr inStream = inStreamSpec; + CMyComPtr &decoder = _decoders[decoderIndex]; + CMyComPtr coder; + if (_decoderFilter) + { + if (decoderIndex != 0) + return E_FAIL; + coder = _decoderFilter; + } + else + coder = decoder; + + // printf("\ndecoderIndex = %d, stack = %p", decoderIndex, &coder); + + CMyComPtr setDecProps; + coder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps); + if (!setDecProps && propStreamSpec->GetPos() != 0) + return E_FAIL; + + CCrcOutStream *crcOutStreamSpec = new CCrcOutStream; + CMyComPtr crcOutStream = crcOutStreamSpec; + + CBenchProgressInfo *pi = progressInfoSpec[decoderIndex]; + pi->BenchInfo.UnpackSize = 0; + pi->BenchInfo.PackSize = 0; + + #ifndef Z7_ST + { + CMyComPtr setCoderMt; + coder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); + if (setCoderMt) + { + RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads)) + } + } + #endif + + CMyComPtr scp; + coder.QueryInterface(IID_ICompressSetCoderProperties, &scp); + if (scp) + { + const UInt64 reduceSize = _uncompressedDataSize; + RINOK(_method.SetCoderProps(scp, &reduceSize)) + } + + CMyComPtr cp; + coder.QueryInterface(IID_ICryptoProperties, &cp); + + if (setDecProps) + { + RINOK(setDecProps->SetDecoderProperties2( + /* (const Byte *)*propStreamSpec, */ + propsData, + (UInt32)propStreamSpec->GetPos())) + } + + { + CMyComPtr sp; + coder.QueryInterface(IID_ICryptoSetPassword, &sp); + if (sp) + { + RINOK(sp->CryptoSetPassword(_psw, sizeof(_psw))) + } + } + + UInt64 prev = 0; + + if (cp) + { + RINOK(Set_Key_and_IV(cp)) + } + + CMyComPtr setFinishMode; + + if (_decoderFilter) + { + if (compressedSize > rgCopy.Size()) + return E_FAIL; + } + else + { + decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode); + } + + const UInt64 numIterations = NumIterations; + const E_CheckCrcMode checkCrcMode = CheckCrcMode_Dec; + + for (UInt64 i = 0; i < numIterations; i++) + { + if (printCallback && pi->BenchInfo.UnpackSize - prev >= (1 << 26)) + { + RINOK(printCallback->CheckBreak()) + prev = pi->BenchInfo.UnpackSize; + } + + const UInt64 outSize = kBufferSize; + bool calcCrc = (checkCrcMode != k_CheckCrcMode_Never); + + crcOutStreamSpec->Init(); + + if (_decoderFilter) + { + Byte *filterData = (Byte *)*outStreamSpec; + if (calcCrc) + { + calcCrc = (i == 0); + if (checkCrcMode == k_CheckCrcMode_Always) + { + calcCrc = true; + memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize); + filterData = rgCopy; + } + } + _decoderFilter->Init(); + My_FilterBench(_decoderFilter, filterData, compressedSize, + calcCrc ? &crcOutStreamSpec->Crc : NULL); + } + else + { + crcOutStreamSpec->CalcCrc = calcCrc; + inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize); + + if (setFinishMode) + { + RINOK(setFinishMode->SetFinishMode(BoolToUInt(true))) + } + + RINOK(decoder->Code(inStream, crcOutStream, NULL, &outSize, progressInfo[decoderIndex])) + + if (setFinishMode) + { + if (!inStreamSpec->WasFinished()) + return S_FALSE; + + CMyComPtr getInStreamProcessedSize; + decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); + + if (getInStreamProcessedSize) + { + UInt64 processed; + RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)) + if (processed != compressedSize) + return S_FALSE; + } + } + + if (crcOutStreamSpec->Pos != outSize) + return S_FALSE; + } + + if (calcCrc && CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc) + return S_FALSE; + + pi->BenchInfo.UnpackSize += kBufferSize; + pi->BenchInfo.PackSize += compressedSize; + } + + decoder.Release(); + _decoderFilter.Release(); + return S_OK; +} + + +static const UInt32 kNumThreadsMax = (1 << 12); + +struct CBenchEncoders +{ + CEncoderInfo *encoders; + CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; } + ~CBenchEncoders() { delete []encoders; } +}; + + +static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands) +{ + if (numCommands < (1 << 4)) + numCommands = (1 << 4); + UInt64 res = complexInCommands / numCommands; + return (res == 0 ? 1 : res); +} + + + +#ifndef Z7_ST + +// ---------- CBenchThreadsFlusher ---------- + +struct CBenchThreadsFlusher +{ + CBenchEncoders *EncodersSpec; + CBenchSyncCommon Common; + unsigned NumThreads; + bool NeedClose; + + CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {} + + ~CBenchThreadsFlusher() + { + StartAndWait(true); + } + + WRes StartAndWait(bool exitMode = false); +}; + + +WRes CBenchThreadsFlusher::StartAndWait(bool exitMode) +{ + if (!NeedClose) + return 0; + + Common.ExitMode = exitMode; + WRes res = Common.StartEvent.Set(); + + for (unsigned i = 0; i < NumThreads; i++) + { + NWindows::CThread &t = EncodersSpec->encoders[i].thread[0]; + if (t.IsCreated()) + { + WRes res2 = t.Wait_Close(); + if (res == 0) + res = res2; + } + } + NeedClose = false; + return res; +} + +#endif // Z7_ST + + + +static void SetPseudoRand(Byte *data, size_t size, UInt32 startValue) +{ + for (size_t i = 0; i < size; i++) + { + data[i] = (Byte)startValue; + startValue++; + } +} + + + +static HRESULT MethodBench( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 complexInCommands, + #ifndef Z7_ST + bool oldLzmaBenchMode, + UInt32 numThreads, + const CAffinityMode *affinityMode, + #endif + const COneMethodInfo &method2, + size_t uncompressedDataSize, + const Byte *fileData, + unsigned generateDictBits, + + IBenchPrintCallback *printCallback, + IBenchCallback *callback, + CBenchProps *benchProps) +{ + COneMethodInfo method = method2; + UInt64 methodId; + UInt32 numStreams; + bool isFilter; + const int codecIndex = FindMethod_Index( + EXTERNAL_CODECS_LOC_VARS + method.MethodName, true, + methodId, numStreams, isFilter); + if (codecIndex < 0) + return E_NOTIMPL; + if (numStreams != 1) + return E_INVALIDARG; + + UInt32 numEncoderThreads = 1; + UInt32 numSubDecoderThreads = 1; + + #ifndef Z7_ST + numEncoderThreads = numThreads; + + if (oldLzmaBenchMode) + if (methodId == k_LZMA) + { + if (numThreads == 1 && method.Get_NumThreads() < 0) + method.AddProp_NumThreads(1); + const UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(); + if (numThreads > 1 && numLzmaThreads > 1) + { + numEncoderThreads = (numThreads + 1) / 2; // 20.03 + numSubDecoderThreads = 2; + } + } + + const bool mtEncMode = (numEncoderThreads > 1) || affinityMode->NeedAffinity(); + + #endif + + CBenchEncoders encodersSpec(numEncoderThreads); + CEncoderInfo *encoders = encodersSpec.encoders; + + UInt32 i; + + for (i = 0; i < numEncoderThreads; i++) + { + CEncoderInfo &encoder = encoders[i]; + encoder.callback = (i == 0) ? callback : NULL; + encoder.printCallback = printCallback; + + #ifndef Z7_ST + encoder.EncoderIndex = i; + encoder.NumEncoderInternalThreads = numSubDecoderThreads; + encoder.AffinityMode = *affinityMode; + + /* + if (numSubDecoderThreads > 1) + if (encoder.AffinityMode.NeedAffinity() + && encoder.AffinityMode.NumBundleThreads == 1) + { + // if old LZMA benchmark uses two threads in coder, we increase (NumBundleThreads) for old LZMA benchmark uses two threads instead of one + if (encoder.AffinityMode.NumBundleThreads * 2 <= encoder.AffinityMode.NumCores) + encoder.AffinityMode.NumBundleThreads *= 2; + } + */ + + #endif + + { + CCreatedCoder cod; + RINOK(CreateCoder_Index(EXTERNAL_CODECS_LOC_VARS (unsigned)codecIndex, true, encoder._encoderFilter, cod)) + encoder._encoder = cod.Coder; + if (!encoder._encoder && !encoder._encoderFilter) + return E_NOTIMPL; + } + + SetPseudoRand(encoder._iv, sizeof(encoder._iv), 17); + SetPseudoRand(encoder._key, sizeof(encoder._key), 51); + SetPseudoRand(encoder._psw, sizeof(encoder._psw), 123); + + for (UInt32 j = 0; j < numSubDecoderThreads; j++) + { + CCreatedCoder cod; + CMyComPtr &decoder = encoder._decoders[j]; + RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS methodId, false, encoder._decoderFilter, cod)) + decoder = cod.Coder; + if (!encoder._decoderFilter && !decoder) + return E_NOTIMPL; + } + + encoder.UseRealData_Enc = + encoder.CheckCrc_Enc = (benchProps->EncComplex) > 30; + + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + if (benchProps->DecComplexCompr + + benchProps->DecComplexUnc <= 30) + encoder.CheckCrcMode_Dec = + k_CheckCrcMode_FirstPass; // for filters + // k_CheckCrcMode_Never; // for debug + // k_CheckCrcMode_Always; // for debug + if (fileData) + { + encoder.UseRealData_Enc = true; + encoder.CheckCrcMode_Dec = k_CheckCrcMode_Always; + } + } + + UInt32 crc = 0; + if (fileData) + crc = CrcCalc(fileData, uncompressedDataSize); + + for (i = 0; i < numEncoderThreads; i++) + { + CEncoderInfo &encoder = encoders[i]; + encoder._method = method; + encoder.generateDictBits = generateDictBits; + encoder._uncompressedDataSize = uncompressedDataSize; + encoder.kBufferSize = uncompressedDataSize; + encoder.fileData = fileData; + encoder.crc = crc; + } + + CBenchProgressStatus status; + status.Res = S_OK; + status.EncodeMode = true; + + #ifndef Z7_ST + CBenchThreadsFlusher encoderFlusher; + if (mtEncMode) + { + WRes wres = encoderFlusher.Common.StartEvent.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + encoderFlusher.NumThreads = numEncoderThreads; + encoderFlusher.EncodersSpec = &encodersSpec; + encoderFlusher.NeedClose = true; + } + #endif + + for (i = 0; i < numEncoderThreads; i++) + { + CEncoderInfo &encoder = encoders[i]; + encoder.NumIterations = GetNumIterations(benchProps->GetNumCommands_Enc(uncompressedDataSize), complexInCommands); + // encoder.NumIterations = 3; + { +#if 0 + #define kCrcPoly 0xEDB88320 + UInt32 r = i; + unsigned num = numEncoderThreads < 256 ? 8 : 16; + do + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); + while (--num); + encoder.Salt = r; +#else + UInt32 salt0 = g_CrcTable[(Byte)i]; + UInt32 salt1 = g_CrcTable[(Byte)(i >> 8)]; + encoder.Salt = salt0 ^ (salt1 << 3); +#endif + } + + // (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread + // printf("\n encoder index = %d, Salt = %8x\n", i, encoder.Salt); + + encoder.KeySize = benchProps->KeySize; + + for (int j = 0; j < 2; j++) + { + CBenchProgressInfo *spec = new CBenchProgressInfo; + encoder.progressInfoSpec[j] = spec; + encoder.progressInfo[j] = spec; + spec->Status = &status; + } + + if (i == 0) + { + CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; + bpi->Callback = callback; + bpi->BenchInfo.NumIterations = numEncoderThreads; + } + + #ifndef Z7_ST + if (mtEncMode) + { + #ifdef USE_ALLOCA + encoder.AllocaSize = BENCH_ALLOCA_VALUE(i); + #endif + + encoder.Common = &encoderFlusher.Common; + encoder.IsGlobalMtMode = numEncoderThreads > 1; + RINOK(encoder.CreateEncoderThread()) + } + #endif + } + + if (printCallback) + { + RINOK(printCallback->CheckBreak()) + } + + #ifndef Z7_ST + if (mtEncMode) + { + for (i = 0; i < numEncoderThreads; i++) + { + CEncoderInfo &encoder = encoders[i]; + const WRes wres = encoder.ReadyEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(encoder.Results[0]) + } + + CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0]; + bpi->SetStartTime(); + + const WRes wres = encoderFlusher.StartAndWait(); + if (status.Res == 0 && wres != 0) + return HRESULT_FROM_WIN32(wres); + } + else + #endif + { + RINOK(encoders[0].Encode()) + } + + RINOK(status.Res) + + CBenchInfo info; + + encoders[0].progressInfoSpec[0]->SetFinishTime(info); + info.UnpackSize = 0; + info.PackSize = 0; + info.NumIterations = encoders[0].NumIterations; + + for (i = 0; i < numEncoderThreads; i++) + { + const CEncoderInfo &encoder = encoders[i]; + info.UnpackSize += encoder.kBufferSize; + info.PackSize += encoder.compressedSize; + // printf("\n%7d\n", encoder.compressedSize); + } + + RINOK(callback->SetEncodeResult(info, true)) + + + + + // ---------- Decode ---------- + + status.Res = S_OK; + status.EncodeMode = false; + + const UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads; + #ifndef Z7_ST + const bool mtDecoderMode = (numDecoderThreads > 1) || affinityMode->NeedAffinity(); + #endif + + for (i = 0; i < numEncoderThreads; i++) + { + CEncoderInfo &encoder = encoders[i]; + + /* + #ifndef Z7_ST + // encoder.affinityMode = *affinityMode; + if (encoder.NumEncoderInternalThreads != 1) + encoder.AffinityMode.DivideNum = encoder.NumEncoderInternalThreads; + #endif + */ + + + if (i == 0) + { + encoder.NumIterations = GetNumIterations( + benchProps->GetNumCommands_Dec( + encoder.compressedSize, + encoder.kBufferSize), + complexInCommands); + CBenchProgressInfo *bpi = encoder.progressInfoSpec[0]; + bpi->Callback = callback; + bpi->BenchInfo.NumIterations = numDecoderThreads; + bpi->SetStartTime(); + } + else + encoder.NumIterations = encoders[0].NumIterations; + + #ifndef Z7_ST + { + const int numSubThreads = method.Get_NumThreads(); + encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : (unsigned)numSubThreads; + } + if (mtDecoderMode) + { + for (UInt32 j = 0; j < numSubDecoderThreads; j++) + { + const HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0) + #ifdef USE_ALLOCA + , BENCH_ALLOCA_VALUE(i * numSubDecoderThreads + j) + #endif + ); + RINOK(res) + } + } + else + #endif + { + RINOK(encoder.Decode(0)) + } + } + + #ifndef Z7_ST + if (mtDecoderMode) + { + WRes wres = 0; + HRESULT res = S_OK; + for (i = 0; i < numEncoderThreads; i++) + for (UInt32 j = 0; j < numSubDecoderThreads; j++) + { + CEncoderInfo &encoder = encoders[i]; + const WRes wres2 = encoder.thread[j]. + // Wait(); // later we can get thread times from thread in UNDER_CE + Wait_Close(); + if (wres == 0 && wres2 != 0) + wres = wres2; + const HRESULT res2 = encoder.Results[j]; + if (res == 0 && res2 != 0) + res = res2; + } + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(res) + } + #endif // Z7_ST + + RINOK(status.Res) + encoders[0].progressInfoSpec[0]->SetFinishTime(info); + + /* + #ifndef Z7_ST + #ifdef UNDER_CE + if (mtDecoderMode) + for (i = 0; i < numEncoderThreads; i++) + for (UInt32 j = 0; j < numSubDecoderThreads; j++) + { + FILETIME creationTime, exitTime, kernelTime, userTime; + if (::GetThreadTimes(encoders[i].thread[j], &creationTime, &exitTime, &kernelTime, &userTime) != 0) + info.UserTime += GetTime64(userTime) + GetTime64(kernelTime); + } + #endif + #endif + */ + + info.UnpackSize = 0; + info.PackSize = 0; + info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations; + + for (i = 0; i < numEncoderThreads; i++) + { + const CEncoderInfo &encoder = encoders[i]; + info.UnpackSize += encoder.kBufferSize; + info.PackSize += encoder.compressedSize; + } + + // RINOK(callback->SetDecodeResult(info, false)) // why we called before 21.03 ?? + RINOK(callback->SetDecodeResult(info, true)) + + return S_OK; +} + + + +static inline UInt64 GetDictSizeFromLog(unsigned dictSizeLog) +{ + /* + if (dictSizeLog < 32) + return (UInt32)1 << dictSizeLog; + else + return (UInt32)(Int32)-1; + */ + return (UInt64)1 << dictSizeLog; +} + + +// it's limit of current LZMA implementation that can be changed later +#define kLzmaMaxDictSize ((UInt32)15 << 28) + +static inline UInt64 GetLZMAUsage(bool multiThread, int btMode, UInt64 dict) +{ + if (dict == 0) + dict = 1; + if (dict > kLzmaMaxDictSize) + dict = kLzmaMaxDictSize; + UInt32 hs = (UInt32)dict - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + hs >>= 1; + hs++; + hs += (1 << 16); + + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict + (1 << 16) + + (multiThread ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + + UInt64 son = (UInt64)dict; + if (btMode) + son *= 2; + const UInt64 v = (hs + son) * 4 + blockSize + + (1 << 20) + (multiThread ? (6 << 20) : 0); + + // printf("\nGetLZMAUsage = %d\n", (UInt32)(v >> 20)); + // printf("\nblockSize = %d\n", (UInt32)(blockSize >> 20)); + return v; +} + + +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench) +{ + const size_t kBufferSize = (size_t)dictionary + kAdditionalSize; + const UInt64 kCompressedBufferSize = GetBenchCompressedSize(kBufferSize); // / 2; + if (level < 0) + level = 5; + const int algo = (level < 5 ? 0 : 1); + const int btMode = (algo == 0 ? 0 : 1); + + UInt32 numBigThreads = numThreads; + const bool lzmaMt = (totalBench || (numThreads > 1 && btMode)); + if (btMode) + { + if (!totalBench && lzmaMt) + numBigThreads /= 2; + } + return ((UInt64)kBufferSize + kCompressedBufferSize + + GetLZMAUsage(lzmaMt, btMode, dictionary) + (2 << 20)) * numBigThreads; +} + +static UInt64 GetBenchMemoryUsage_Hash(UInt32 numThreads, UInt64 dictionary) +{ + // dictionary += (dictionary >> 9); // for page tables (virtual memory) + return (UInt64)(dictionary + (1 << 15)) * numThreads + (2 << 20); +} + + +// ---------- CRC and HASH ---------- + +struct CCrcInfo_Base +{ + CMidAlignedBuffer Buffer; + const Byte *Data; + size_t Size; + bool CreateLocalBuf; + UInt32 CheckSum_Res; + + CCrcInfo_Base(): CreateLocalBuf(true), CheckSum_Res(0) {} + + HRESULT Generate(const Byte *data, size_t size); + HRESULT CrcProcess(UInt64 numIterations, + const UInt32 *checkSum, IHasher *hf, + IBenchPrintCallback *callback); +}; + + +// for debug: define it to test hash calling with unaligned data +// #define Z7_BENCH_HASH_ALIGN_BUF_OFFSET 3 + +HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size) +{ + Size = size; + Data = data; + if (!data || CreateLocalBuf) + { + Byte *buf; + const size_t size2 = (size + k_RandBuf_AlignMask) & ~(size_t)k_RandBuf_AlignMask; + if (size2 < size) + return E_OUTOFMEMORY; +#ifdef Z7_BENCH_HASH_ALIGN_BUF_OFFSET + ALLOC_WITH_HRESULT(&Buffer, size2 + Z7_BENCH_HASH_ALIGN_BUF_OFFSET) + buf = Buffer + Z7_BENCH_HASH_ALIGN_BUF_OFFSET; +#else + ALLOC_WITH_HRESULT(&Buffer, size2) + buf = Buffer; +#endif + Data = buf; + if (!data) + RandGen_BufAfterPad(buf, size); + else if (size != 0) // (CreateLocalBuf == true) + memcpy(buf, data, size); + } + return S_OK; +} + + +#if 1 +#define HashUpdate(hf, data, size) hf->Update(data, size) +#else +// for debug: +static void HashUpdate(IHasher *hf, const void *data, UInt32 size) +{ + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 8; + // UInt32 size2 = size / 2; + if (size2 == 0) + size2 = 1; + hf->Update(data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +} +#endif + + +HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, + const UInt32 *checkSum, IHasher *hf, + IBenchPrintCallback *callback) +{ + MY_ALIGN(16) + UInt32 hash32[64 / 4]; + memset(hash32, 0, sizeof(hash32)); + + CheckSum_Res = 0; + + const UInt32 hashSize = hf->GetDigestSize(); + if (hashSize > sizeof(hash32)) + return S_FALSE; + + const Byte *buf = Data; + const size_t size = Size; + UInt32 checkSum_Prev = 0; + + UInt64 prev = 0; + UInt64 cur = 0; + + do + { + hf->Init(); + size_t pos = 0; + do + { + const size_t rem = size - pos; + const UInt32 kStep = ((UInt32)1 << 31); + const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep; + HashUpdate(hf, buf + pos, curSize); + pos += curSize; + } + while (pos != size); + + hf->Final((Byte *)(void *)hash32); + UInt32 sum = 0; + for (UInt32 j = 0; j < hashSize; j += 4) + { + sum = rotlFixed(sum, 11); + sum += GetUi32((const Byte *)(const void *)hash32 + j); + } + if (checkSum) + { + if (sum != *checkSum) + return S_FALSE; + } + else + { + checkSum_Prev = sum; + checkSum = &checkSum_Prev; + } + if (callback) + { + cur += size; + if (cur - prev >= ((UInt32)1 << 30)) + { + prev = cur; + RINOK(callback->CheckBreak()) + } + } + } + while (--numIterations); + + CheckSum_Res = checkSum_Prev; + return S_OK; +} + +extern +UInt32 g_BenchCpuFreqTemp; // we need non-static variavble to disable compiler optimization +UInt32 g_BenchCpuFreqTemp = 1; + +#define YY1 sum += val; sum ^= val; +#define YY3 YY1 YY1 YY1 YY1 +#define YY5 YY3 YY3 YY3 YY3 +#define YY7 YY5 YY5 YY5 YY5 +static const UInt32 kNumFreqCommands = 128; + +EXTERN_C_BEGIN + +static UInt32 CountCpuFreq(UInt32 sum, UInt32 num, UInt32 val) +{ + for (UInt32 i = 0; i < num; i++) + { + YY7 + } + return sum; +} + +EXTERN_C_END + + +#ifndef Z7_ST + +struct CBaseThreadInfo +{ + NWindows::CThread Thread; + IBenchPrintCallback *Callback; + HRESULT CallbackRes; + + WRes Wait_If_Created() + { + if (!Thread.IsCreated()) + return 0; + return Thread.Wait_Close(); + } +}; + +struct CFreqInfo: public CBaseThreadInfo +{ + UInt32 ValRes; + UInt32 Size; + UInt64 NumIterations; +}; + +static THREAD_FUNC_DECL FreqThreadFunction(void *param) +{ + CFreqInfo *p = (CFreqInfo *)param; + + UInt32 sum = g_BenchCpuFreqTemp; + for (UInt64 k = p->NumIterations; k > 0; k--) + { + if (p->Callback) + { + p->CallbackRes = p->Callback->CheckBreak(); + if (p->CallbackRes != S_OK) + break; + } + sum = CountCpuFreq(sum, p->Size, g_BenchCpuFreqTemp); + } + p->ValRes = sum; + return THREAD_FUNC_RET_ZERO; +} + +struct CFreqThreads +{ + CFreqInfo *Items; + UInt32 NumThreads; + + CFreqThreads(): Items(NULL), NumThreads(0) {} + + WRes WaitAll() + { + WRes wres = 0; + for (UInt32 i = 0; i < NumThreads; i++) + { + WRes wres2 = Items[i].Wait_If_Created(); + if (wres == 0 && wres2 != 0) + wres = wres2; + } + NumThreads = 0; + return wres; + } + + ~CFreqThreads() + { + WaitAll(); + delete []Items; + } +}; + + +static THREAD_FUNC_DECL CrcThreadFunction(void *param); + +struct CCrcInfo: public CBaseThreadInfo +{ + const Byte *Data; + size_t Size; + UInt64 NumIterations; + bool CheckSumDefined; + UInt32 CheckSum; + CMyComPtr Hasher; + HRESULT Res; + UInt32 CheckSum_Res; + + #ifndef Z7_ST + NSynchronization::CManualResetEvent ReadyEvent; + UInt32 ThreadIndex; + CBenchSyncCommon *Common; + CAffinityMode AffinityMode; + #endif + + // we want to call CCrcInfo_Base::Buffer.Free() in main thread. + // so we uses non-local CCrcInfo_Base. + CCrcInfo_Base crcib; + + HRESULT CreateThread() + { + WRes res = 0; + if (!ReadyEvent.IsCreated()) + res = ReadyEvent.Create(); + if (res == 0) + res = AffinityMode.CreateThread_WithAffinity(Thread, CrcThreadFunction, this, + ThreadIndex); + return HRESULT_FROM_WIN32(res); + } + + #ifdef USE_ALLOCA + size_t AllocaSize; + #endif + + void Process(); + + CCrcInfo(): Res(E_FAIL) {} +}; + +static const bool k_Crc_CreateLocalBuf_For_File = true; // for total BW test +// static const bool k_Crc_CreateLocalBuf_For_File = false; // for shared memory read test + +void CCrcInfo::Process() +{ + crcib.CreateLocalBuf = k_Crc_CreateLocalBuf_For_File; + // we can use additional Generate() passes to reduce some time effects for new page allocation + // for (unsigned y = 0; y < 10; y++) + Res = crcib.Generate(Data, Size); + + // if (Common) + { + WRes wres = ReadyEvent.Set(); + if (wres != 0) + { + if (Res == 0) + Res = HRESULT_FROM_WIN32(wres); + return; + } + if (Res != 0) + return; + + wres = Common->StartEvent.Lock(); + + if (wres != 0) + { + Res = HRESULT_FROM_WIN32(wres); + return; + } + if (Common->ExitMode) + return; + } + + Res = crcib.CrcProcess(NumIterations, + CheckSumDefined ? &CheckSum : NULL, Hasher, + Callback); + CheckSum_Res = crcib.CheckSum_Res; + /* + We don't want to include the time of slow CCrcInfo_Base::Buffer.Free() + to time of benchmark. So we don't free Buffer here + */ + // crcib.Buffer.Free(); +} + + +static THREAD_FUNC_DECL CrcThreadFunction(void *param) +{ + CCrcInfo *p = (CCrcInfo *)param; + + #ifdef USE_ALLOCA + alloca(p->AllocaSize); + #endif + p->Process(); + return THREAD_FUNC_RET_ZERO; +} + + +struct CCrcThreads +{ + CCrcInfo *Items; + unsigned NumThreads; + CBenchSyncCommon Common; + bool NeedClose; + + CCrcThreads(): Items(NULL), NumThreads(0), NeedClose(false) {} + + WRes StartAndWait(bool exitMode = false); + + ~CCrcThreads() + { + StartAndWait(true); + delete []Items; + } +}; + + +WRes CCrcThreads::StartAndWait(bool exitMode) +{ + if (!NeedClose) + return 0; + + Common.ExitMode = exitMode; + WRes wres = Common.StartEvent.Set(); + + for (unsigned i = 0; i < NumThreads; i++) + { + WRes wres2 = Items[i].Wait_If_Created(); + if (wres == 0 && wres2 != 0) + wres = wres2; + } + NumThreads = 0; + NeedClose = false; + return wres; +} + +#endif + + +/* +static UInt32 CrcCalc1(const Byte *buf, size_t size) +{ + UInt32 crc = CRC_INIT_VAL; + for (size_t i = 0; i < size; i++) + crc = CRC_UPDATE_BYTE(crc, buf[i]); + return CRC_GET_DIGEST(crc); +} +*/ + +/* +static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG) +{ + RandGen(buf, size, RG); + return CrcCalc1(buf, size); +} +*/ + +static bool CrcInternalTest() +{ + CAlignedBuffer buffer; + const size_t kBufSize = 1 << 11; + const size_t kCheckSize = 1 << 6; + buffer.Alloc(kBufSize); + if (!buffer.IsAllocated()) + return false; + Byte *buf = (Byte *)buffer; + RandGen_BufAfterPad(buf, kBufSize); + UInt32 sum = 0; + for (size_t i = 0; i < kBufSize - kCheckSize * 2; i += kCheckSize - 1) + for (size_t j = 0; j < kCheckSize; j++) + { + sum = rotlFixed(sum, 11); + sum += CrcCalc(buf + i + j, j); + } + return sum == 0x28462c7c; +} + +struct CBenchMethod +{ + unsigned Weight; + unsigned DictBits; + Int32 EncComplex; + Int32 DecComplexCompr; + Int32 DecComplexUnc; + const char *Name; + // unsigned KeySize; +}; + +// #define USE_SW_CMPLX + +#ifdef USE_SW_CMPLX +#define CMPLX(x) ((x) * 1000) +#else +#define CMPLX(x) (x) +#endif + +static const CBenchMethod g_Bench[] = +{ + // { 40, 17, 357, 145, 20, "LZMA:x1" }, + // { 20, 18, 360, 145, 20, "LZMA2:x1:mt2" }, + + { 20, 18, 360, 145, 20, "LZMA:x1" }, + { 20, 22, 600, 145, 20, "LZMA:x3" }, + + { 80, 24, 1220, 145, 20, "LZMA:x5:mt1" }, + { 80, 24, 1220, 145, 20, "LZMA:x5:mt2" }, + + { 10, 16, 124, 40, 14, "Deflate:x1" }, + { 20, 16, 376, 40, 14, "Deflate:x5" }, + { 10, 16, 1082, 40, 14, "Deflate:x7" }, + { 10, 17, 422, 40, 14, "Deflate64:x5" }, + + { 10, 15, 590, 69, 69, "BZip2:x1" }, + { 20, 19, 815, 122, 122, "BZip2:x5" }, + { 10, 19, 815, 122, 122, "BZip2:x5:mt2" }, + { 10, 19, 2530, 122, 122, "BZip2:x7" }, + + // { 10, 18, 1010, 0, 1150, "PPMDZip:x1" }, + { 10, 18, 1010, 0, 1150, "PPMD:x1" }, + // { 10, 22, 1655, 0, 1830, "PPMDZip:x5" }, + { 10, 22, 1655, 0, 1830, "PPMD:x5" }, + + // { 2, 0, -16, 0, -16, "Swap2" }, + { 2, 0, -16, 0, -16, "Swap4" }, + + // { 2, 0, 3, 0, 4, "Delta:1" }, + // { 2, 0, 3, 0, 4, "Delta:2" }, + // { 2, 0, 3, 0, 4, "Delta:3" }, + { 2, 0, 3, 0, 4, "Delta:4" }, + // { 2, 0, 3, 0, 4, "Delta:8" }, + // { 2, 0, 3, 0, 4, "Delta:32" }, + + { 2, 0, 2, 0, 2, "BCJ" }, + { 2, 0, 1, 0, 1, "ARM64" }, + { 2, 0, 1, 0, 1, "RISCV" }, + + // { 10, 0, 18, 0, 18, "AES128CBC:1" }, + // { 10, 0, 21, 0, 21, "AES192CBC:1" }, + { 10, 0, 24, 0, 24, "AES256CBC:1" }, + + // { 10, 0, 18, 0, 18, "AES128CTR:1" }, + // { 10, 0, 21, 0, 21, "AES192CTR:1" }, + // { 10, 0, 24, 0, 24, "AES256CTR:1" }, + // { 2, 0, CMPLX(6), 0, CMPLX(1), "AES128CBC:2" }, + // { 2, 0, CMPLX(7), 0, CMPLX(1), "AES192CBC:2" }, + { 2, 0, CMPLX(8), 0, CMPLX(1), "AES256CBC:2" }, + + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES128CTR:2" }, + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES192CTR:2" }, + // { 2, 0, CMPLX(1), 0, CMPLX(1), "AES256CTR:2" }, + + // { 1, 0, CMPLX(6), 0, -2, "AES128CBC:3" }, + // { 1, 0, CMPLX(7), 0, -2, "AES192CBC:3" }, + { 1, 0, CMPLX(8), 0, -2, "AES256CBC:3" } + + // { 1, 0, CMPLX(1), 0, -2, "AES128CTR:3" }, + // { 1, 0, CMPLX(1), 0, -2, "AES192CTR:3" }, + // { 1, 0, CMPLX(1), 0, -2, "AES256CTR:3" }, +}; + +struct CBenchHash +{ + unsigned Weight; + UInt32 Complex; + UInt32 CheckSum; + const char *Name; +}; + +// #define ARM_CRC_MUL 100 +#define ARM_CRC_MUL 1 + +#define k_Hash_Complex_Mult 256 + +static const CBenchHash g_Hash[] = +{ + { 20, 256, 0x21e207bb, "CRC32:12" } , + { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" }, + { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" }, + { 10, 256, 0x41b901d1, "CRC64" }, + { 5, 64, 0x43eac94f, "XXH64" }, + { 2, 2340, 0x3398a904, "MD5" }, + { 10, 2340, 0xff769021, "SHA1:1" }, + { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" }, + { 10, 5100, 0x7913ba03, "SHA256:1" }, + { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, + { 5, 3200, 0xe7aeb394, "SHA512:1" }, + { 2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" }, + // { 10, 3428, 0x1cc99b18, "SHAKE128" }, + // { 10, 4235, 0x74eaddc3, "SHAKE256" }, + // { 10, 4000, 0xdf3e6863, "SHA3-224" }, + { 5, 4200, 0xcecac10d, "SHA3-256" }, + // { 10, 5538, 0x4e5d9163, "SHA3-384" }, + // { 10, 8000, 0x96a58289, "SHA3-512" }, + { 2, 4096, 0x85189d02, "BLAKE2sp:1" }, + { 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast + { 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast +#if 0 + , { 2, 2048, 0x85189d02, "BLAKE2sp:4" } // sse2-way1 + , { 2, 1024, 0x85189d02, "BLAKE2sp:5" } // sse2-way2 + , { 2, 1024, 0x85189d02, "BLAKE2sp:6" } // avx2-way2 + , { 2, 1024, 0x85189d02, "BLAKE2sp:7" } // avx2-way4 +#endif +}; + +static void PrintNumber(IBenchPrintCallback &f, UInt64 value, unsigned size) +{ + char s[128]; + unsigned startPos = (unsigned)sizeof(s) - 32; + memset(s, ' ', startPos); + ConvertUInt64ToString(value, s + startPos); + // if (withSpace) + { + startPos--; + size++; + } + unsigned len = (unsigned)strlen(s + startPos); + if (size > len) + { + size -= len; + if (startPos < size) + startPos = 0; + else + startPos -= size; + } + f.Print(s + startPos); +} + +static const unsigned kFieldSize_Name = 12; +static const unsigned kFieldSize_SmallName = 4; +static const unsigned kFieldSize_Speed = 9; +static const unsigned kFieldSize_Usage = 5; +static const unsigned kFieldSize_RU = 6; +static const unsigned kFieldSize_Rating = 6; +static const unsigned kFieldSize_EU = 5; +static const unsigned kFieldSize_Effec = 5; +static const unsigned kFieldSize_CrcSpeed = 8; + + +static const unsigned kFieldSize_TotalSize = 4 + kFieldSize_Speed + kFieldSize_Usage + kFieldSize_RU + kFieldSize_Rating; +static const unsigned kFieldSize_EUAndEffec = 2 + kFieldSize_EU + kFieldSize_Effec; + + +static void PrintRating(IBenchPrintCallback &f, UInt64 rating, unsigned size) +{ + PrintNumber(f, (rating + 500000) / 1000000, size); +} + + +static void PrintPercents(IBenchPrintCallback &f, UInt64 val, UInt64 divider, unsigned size) +{ + UInt64 v = 0; + if (divider != 0) + v = (val * 100 + divider / 2) / divider; + PrintNumber(f, v, size); +} + +static void PrintChars(IBenchPrintCallback &f, char c, unsigned size) +{ + char s[256]; + memset(s, (Byte)c, size); + s[size] = 0; + f.Print(s); +} + +static void PrintSpaces(IBenchPrintCallback &f, unsigned size) +{ + PrintChars(f, ' ', size); +} + +static void PrintUsage(IBenchPrintCallback &f, UInt64 usage, unsigned size) +{ + PrintNumber(f, Benchmark_GetUsage_Percents(usage), size); +} + +static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating, bool showFreq, UInt64 cpuFreq) +{ + PrintUsage(f, usage, kFieldSize_Usage); + PrintRating(f, rpu, kFieldSize_RU); + PrintRating(f, rating, kFieldSize_Rating); + if (showFreq) + { + if (cpuFreq == 0) + PrintSpaces(f, kFieldSize_EUAndEffec); + else + { + PrintPercents(f, rating, cpuFreq * usage / kBenchmarkUsageMult, kFieldSize_EU); + PrintPercents(f, rating, cpuFreq, kFieldSize_Effec); + } + } +} + + +void CTotalBenchRes::Generate_From_BenchInfo(const CBenchInfo &info) +{ + Speed = info.GetUnpackSizeSpeed(); + Usage = info.GetUsage(); + RPU = info.GetRatingPerUsage(Rating); +} + +void CTotalBenchRes::Mult_For_Weight(unsigned weight) +{ + NumIterations2 *= weight; + RPU *= weight; + Rating *= weight; + Usage *= weight; + Speed *= weight; +} + +void CTotalBenchRes::Update_With_Res(const CTotalBenchRes &r) +{ + Rating += r.Rating; + Usage += r.Usage; + RPU += r.RPU; + Speed += r.Speed; + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 += r.NumIterations2; +} + +static void PrintResults(IBenchPrintCallback *f, + const CBenchInfo &info, + unsigned weight, + UInt64 rating, + bool showFreq, UInt64 cpuFreq, + CTotalBenchRes *res) +{ + CTotalBenchRes t; + t.Rating = rating; + t.NumIterations2 = 1; + t.Generate_From_BenchInfo(info); + + if (f) + { + if (t.Speed != 0) + PrintNumber(*f, t.Speed / 1024, kFieldSize_Speed); + else + PrintSpaces(*f, 1 + kFieldSize_Speed); + } + if (f) + { + PrintResults(*f, t.Usage, t.RPU, rating, showFreq, cpuFreq); + } + + if (res) + { + // res->NumIterations1++; + t.Mult_For_Weight(weight); + res->Update_With_Res(t); + } +} + +static void PrintTotals(IBenchPrintCallback &f, + bool showFreq, UInt64 cpuFreq, bool showSpeed, const CTotalBenchRes &res) +{ + const UInt64 numIterations2 = res.NumIterations2 ? res.NumIterations2 : 1; + const UInt64 speed = res.Speed / numIterations2; + if (showSpeed && speed != 0) + PrintNumber(f, speed / 1024, kFieldSize_Speed); + else + PrintSpaces(f, 1 + kFieldSize_Speed); + + // PrintSpaces(f, 1 + kFieldSize_Speed); + // UInt64 numIterations1 = res.NumIterations1; if (numIterations1 == 0) numIterations1 = 1; + PrintResults(f, res.Usage / numIterations2, res.RPU / numIterations2, res.Rating / numIterations2, showFreq, cpuFreq); +} + + +static void PrintHex(AString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} + +AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti) +{ + AString s; + // s.Add_UInt32(ti.numProcessThreads); + const unsigned numSysThreads = ti.GetNumSystemThreads(); + if (ti.GetNumProcessThreads() != numSysThreads) + { + // if (ti.numProcessThreads != ti.numSysThreads) + { + s += " / "; + s.Add_UInt32(numSysThreads); + } + s += " : "; + #ifdef _WIN32 + PrintHex(s, ti.processAffinityMask); + s += " / "; + PrintHex(s, ti.systemAffinityMask); + #else + unsigned i = (numSysThreads + 3) & ~(unsigned)3; + if (i == 0) + i = 4; + for (; i >= 4; ) + { + i -= 4; + unsigned val = 0; + for (unsigned k = 0; k < 4; k++) + { + const unsigned bit = (ti.IsCpuSet(i + k) ? 1 : 0); + val += (bit << k); + } + PrintHex(s, val); + } + #endif + } +#ifdef _WIN32 + if (ti.Groups.GroupSizes.Size() > 1 || + (ti.Groups.GroupSizes.Size() == 1 + && ti.Groups.NumThreadsTotal != numSysThreads)) + { + s += " : "; + s.Add_UInt32(ti.Groups.GroupSizes.Size()); + s += " groups : "; + if (ti.Groups.NumThreadsTotal == numSysThreads) + { + s.Add_UInt32(ti.Groups.NumThreadsTotal); + s += " c : "; + } + UInt32 minSize, maxSize; + ti.Groups.Get_GroupSize_Min_Max(minSize, maxSize); + if (minSize == maxSize) + { + s.Add_UInt32(ti.Groups.GroupSizes[0]); + s += " c/g"; + } + else + FOR_VECTOR (i, ti.Groups.GroupSizes) + { + if (i != 0) + s.Add_Char(' '); + s.Add_UInt32(ti.Groups.GroupSizes[i]); + } + } +#endif + return s; +} + + +#ifdef Z7_LARGE_PAGES + +#ifdef _WIN32 +extern bool g_LargePagesMode; +extern "C" +{ + extern SIZE_T g_LargePageSize; +} +#endif + +void Add_LargePages_String(AString &s) +{ + #ifdef _WIN32 + if (g_LargePagesMode || g_LargePageSize != 0) + { + s.Add_OptSpaced("(LP-"); + PrintSize_KMGT_Or_Hex(s, g_LargePageSize); + #ifdef MY_CPU_X86_OR_AMD64 + if (CPU_IsSupported_PageGB()) + s += "-1G"; + #endif + if (!g_LargePagesMode) + s += "-NA"; + s += ")"; + } + #else + s += ""; + #endif +} + +#endif + + + +static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, + bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads) +{ + f.Print("RAM "); + f.Print(sizeString); + if (size_Defined) + PrintNumber(f, (size >> 20), 6); + else + f.Print(" ?"); + f.Print(" MB"); + + #ifdef Z7_LARGE_PAGES + { + AString s; + Add_LargePages_String(s); + f.Print(s); + } + #endif + + f.Print(", # "); + f.Print(threadsString); + PrintNumber(f, numThreads, 3); +} + + + +struct CBenchCallbackToPrint Z7_final: public IBenchCallback +{ + bool NeedPrint; + bool Use2Columns; + bool ShowFreq; + unsigned NameFieldSize; + + unsigned EncodeWeight; + unsigned DecodeWeight; + + UInt64 CpuFreq; + UInt64 DictSize; + + IBenchPrintCallback *_file; + CBenchProps BenchProps; + CTotalBenchRes EncodeRes; + CTotalBenchRes DecodeRes; + + CBenchInfo BenchInfo_Results[2]; + + CBenchCallbackToPrint(): + NeedPrint(true), + Use2Columns(false), + ShowFreq(false), + NameFieldSize(0), + EncodeWeight(1), + DecodeWeight(1), + CpuFreq(0) + {} + + void Init() { EncodeRes.Init(); DecodeRes.Init(); } + void Print(const char *s); + void NewLine(); + + HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); + HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override; + HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override; +}; + +HRESULT CBenchCallbackToPrint::SetFreq(bool showFreq, UInt64 cpuFreq) +{ + ShowFreq = showFreq; + CpuFreq = cpuFreq; + return S_OK; +} + +HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final) +{ + RINOK(_file->CheckBreak()) + if (final) + BenchInfo_Results[0] = info; + if (final) + if (NeedPrint) + { + const UInt64 rating = BenchProps.GetRating_Enc(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize * info.NumIterations); + PrintResults(_file, info, + EncodeWeight, rating, + ShowFreq, CpuFreq, &EncodeRes); + if (!Use2Columns) + _file->NewLine(); + } + return S_OK; +} + +static const char * const kSep = " | "; + +HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final) +{ + RINOK(_file->CheckBreak()) + if (final) + BenchInfo_Results[1] = info; + if (final) + if (NeedPrint) + { + const UInt64 rating = BenchProps.GetRating_Dec(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations); + if (Use2Columns) + _file->Print(kSep); + else + PrintSpaces(*_file, NameFieldSize); + CBenchInfo info2 = info; + info2.UnpackSize *= info2.NumIterations; + info2.PackSize *= info2.NumIterations; + info2.NumIterations = 1; + PrintResults(_file, info2, + DecodeWeight, rating, + ShowFreq, CpuFreq, &DecodeRes); + } + return S_OK; +} + +void CBenchCallbackToPrint::Print(const char *s) +{ + _file->Print(s); +} + +void CBenchCallbackToPrint::NewLine() +{ + _file->NewLine(); +} + +static void PrintLeft(IBenchPrintCallback &f, const char *s, unsigned size) +{ + f.Print(s); + int numSpaces = (int)size - (int)MyStringLen(s); + if (numSpaces > 0) + PrintSpaces(f, (unsigned)numSpaces); +} + +static void PrintRight(IBenchPrintCallback &f, const char *s, unsigned size) +{ + int numSpaces = (int)size - (int)MyStringLen(s); + if (numSpaces > 0) + PrintSpaces(f, (unsigned)numSpaces); + f.Print(s); +} + + +static bool DoesWildcardMatchName_NoCase(const AString &mask, const char *name) +{ + UString wildc = GetUnicodeString(mask); + UString bname = GetUnicodeString(name); + wildc.MakeLower_Ascii(); + bname.MakeLower_Ascii(); + return DoesWildcardMatchName(wildc, bname); +} + + +static HRESULT TotalBench( + DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, + UInt64 complexInCommands, + #ifndef Z7_ST + UInt32 numThreads, + const CAffinityMode *affinityMode, + #endif + bool forceUnpackSize, + size_t unpackSize, + const Byte *fileData, + IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) + { + const CBenchMethod &bench = g_Bench[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; + PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); + { + unsigned keySize = 32; + if (IsString1PrefixedByString2(bench.Name, "AES128")) keySize = 16; + else if (IsString1PrefixedByString2(bench.Name, "AES192")) keySize = 24; + callback->BenchProps.KeySize = keySize; + } + callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; + callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; + callback->BenchProps.EncComplex = bench.EncComplex; + + COneMethodInfo method; + NCOM::CPropVariant propVariant; + propVariant = bench.Name; + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) + + size_t unpackSize2 = unpackSize; + if (!forceUnpackSize && bench.DictBits == 0) + unpackSize2 = kFilterUnpackSize; + + callback->EncodeWeight = bench.Weight; + callback->DecodeWeight = bench.Weight; + + const HRESULT res = MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + false, numThreads, affinityMode, + #endif + method, + unpackSize2, fileData, + bench.DictBits, + printCallback, callback, &callback->BenchProps); + + if (res == E_NOTIMPL) + { + // callback->Print(" ---"); + // we need additional empty line as line for decompression results + if (!callback->Use2Columns) + callback->NewLine(); + } + else + { + RINOK(res) + } + + callback->NewLine(); + } + return S_OK; +} + + +struct CFreqBench +{ + // in: + UInt64 complexInCommands; + UInt32 numThreads; + bool showFreq; + UInt64 specifiedFreq; + + // out: + UInt64 CpuFreqRes; + UInt64 UsageRes; + UInt32 res; + + CFreqBench() + {} + + HRESULT FreqBench(IBenchPrintCallback *_file + #ifndef Z7_ST + , const CAffinityMode *affinityMode + #endif + ); +}; + + +HRESULT CFreqBench::FreqBench(IBenchPrintCallback *_file + #ifndef Z7_ST + , const CAffinityMode *affinityMode + #endif + ) +{ + res = 0; + CpuFreqRes = 0; + UsageRes = 0; + + if (numThreads == 0) + numThreads = 1; + + #ifdef Z7_ST + numThreads = 1; + #endif + + const UInt32 complexity = kNumFreqCommands; + UInt64 numIterations = complexInCommands / complexity; + UInt32 numIterations2 = 1 << 30; + if (numIterations > numIterations2) + numIterations /= numIterations2; + else + { + numIterations2 = (UInt32)numIterations; + numIterations = 1; + } + + CBenchInfoCalc progressInfoSpec; + + #ifndef Z7_ST + + bool mtMode = (numThreads > 1) || affinityMode->NeedAffinity(); + + if (mtMode) + { + CFreqThreads threads; + threads.Items = new CFreqInfo[numThreads]; + UInt32 i; + for (i = 0; i < numThreads; i++) + { + CFreqInfo &info = threads.Items[i]; + info.Callback = _file; + info.CallbackRes = S_OK; + info.NumIterations = numIterations; + info.Size = numIterations2; + } + progressInfoSpec.SetStartTime(); + for (i = 0; i < numThreads; i++) + { + // Sleep(10); + CFreqInfo &info = threads.Items[i]; + WRes wres = affinityMode->CreateThread_WithAffinity(info.Thread, FreqThreadFunction, &info, i); + if (info.Thread.IsCreated()) + threads.NumThreads++; + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + } + WRes wres = threads.WaitAll(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + for (i = 0; i < numThreads; i++) + { + RINOK(threads.Items[i].CallbackRes) + } + } + else + #endif + { + progressInfoSpec.SetStartTime(); + UInt32 sum = g_BenchCpuFreqTemp; + UInt64 k = numIterations; + do + { + sum = CountCpuFreq(sum, numIterations2, g_BenchCpuFreqTemp); + if (_file) + { + RINOK(_file->CheckBreak()) + } + } + while (--k); + res += sum; + } + + if (res == 0x12345678) + if (_file) + { + RINOK(_file->CheckBreak()) + } + + CBenchInfo info; + progressInfoSpec.SetFinishTime(info); + + info.UnpackSize = 0; + info.PackSize = 0; + info.NumIterations = 1; + + const UInt64 numCommands = (UInt64)numIterations * numIterations2 * numThreads * complexity; + const UInt64 rating = info.GetSpeed(numCommands); + CpuFreqRes = rating / numThreads; + UsageRes = info.GetUsage(); + + if (_file) + { + PrintResults(_file, info, + 0, // weight + rating, + showFreq, showFreq ? (specifiedFreq != 0 ? specifiedFreq : CpuFreqRes) : 0, NULL); + RINOK(_file->CheckBreak()) + } + + return S_OK; +} + + + +static HRESULT CrcBench( + DECL_EXTERNAL_CODECS_LOC_VARS + UInt64 complexInCommands, + UInt32 numThreads, + const size_t bufferSize, + const Byte *fileData, + + UInt64 &speed, + UInt64 &usage, + + UInt32 complexity, unsigned benchWeight, + const UInt32 *checkSum, + const COneMethodInfo &method, + IBenchPrintCallback *_file, + #ifndef Z7_ST + const CAffinityMode *affinityMode, + #endif + bool showRating, + CTotalBenchRes *encodeRes, + bool showFreq, UInt64 cpuFreq) +{ + if (numThreads == 0) + numThreads = 1; + + #ifdef Z7_ST + numThreads = 1; + #endif + + const AString &methodName = method.MethodName; + // methodName.RemoveChar(L'-'); + CMethodId hashID; + if (!FindHashMethod( + EXTERNAL_CODECS_LOC_VARS + methodName, hashID)) + return E_NOTIMPL; + + /* + // if will generate random data in each thread, instead of global data + CMidAlignedBuffer buffer; + if (!fileData) + { + ALLOC_WITH_HRESULT(&buffer, bufferSize) + RandGen(buffer, bufferSize); + fileData = buffer; + } + */ + + const size_t bsize = (bufferSize == 0 ? 1 : bufferSize); + UInt64 numIterations = complexInCommands * k_Hash_Complex_Mult / complexity / bsize; + if (numIterations == 0) + numIterations = 1; + + CBenchInfoCalc progressInfoSpec; + CBenchInfo info; + + #ifndef Z7_ST + bool mtEncMode = (numThreads > 1) || affinityMode->NeedAffinity(); + + if (mtEncMode) + { + CCrcThreads threads; + threads.Items = new CCrcInfo[numThreads]; + { + WRes wres = threads.Common.StartEvent.Create(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + threads.NeedClose = true; + } + + UInt32 i; + for (i = 0; i < numThreads; i++) + { + CCrcInfo &ci = threads.Items[i]; + AString name; + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, ci.Hasher)) + if (!ci.Hasher) + return E_NOTIMPL; + CMyComPtr scp; + ci.Hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); + if (scp) + { + RINOK(method.SetCoderProps(scp)) + } + + ci.Callback = _file; + ci.Data = fileData; + ci.NumIterations = numIterations; + ci.Size = bufferSize; + ci.CheckSumDefined = false; + if (checkSum) + { + ci.CheckSum = *checkSum; + ci.CheckSumDefined = true; + } + + #ifdef USE_ALLOCA + ci.AllocaSize = BENCH_ALLOCA_VALUE(i); + #endif + } + + for (i = 0; i < numThreads; i++) + { + CCrcInfo &ci = threads.Items[i]; + ci.ThreadIndex = i; + ci.Common = &threads.Common; + ci.AffinityMode = *affinityMode; + HRESULT hres = ci.CreateThread(); + if (ci.Thread.IsCreated()) + threads.NumThreads++; + if (hres != 0) + return hres; + } + + for (i = 0; i < numThreads; i++) + { + CCrcInfo &ci = threads.Items[i]; + WRes wres = ci.ReadyEvent.Lock(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + RINOK(ci.Res) + } + + progressInfoSpec.SetStartTime(); + + WRes wres = threads.StartAndWait(); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + + progressInfoSpec.SetFinishTime(info); + + for (i = 0; i < numThreads; i++) + { + RINOK(threads.Items[i].Res) + if (i != 0) + if (threads.Items[i].CheckSum_Res != + threads.Items[i - 1].CheckSum_Res) + return S_FALSE; + } + } + else + #endif + { + CMyComPtr hasher; + AString name; + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS hashID, name, hasher)) + if (!hasher) + return E_NOTIMPL; + CMyComPtr scp; + hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); + if (scp) + { + RINOK(method.SetCoderProps(scp)) + } + CCrcInfo_Base crcib; + crcib.CreateLocalBuf = false; + RINOK(crcib.Generate(fileData, bufferSize)) + progressInfoSpec.SetStartTime(); + RINOK(crcib.CrcProcess(numIterations, checkSum, hasher, _file)) + progressInfoSpec.SetFinishTime(info); + } + + + UInt64 unpSize = numIterations * bufferSize; + UInt64 unpSizeThreads = unpSize * numThreads; + info.UnpackSize = unpSizeThreads; + info.PackSize = unpSizeThreads; + info.NumIterations = 1; + + if (_file) + { + if (showRating) + { + UInt64 unpSizeThreads2 = unpSizeThreads; + if (unpSizeThreads2 == 0) + unpSizeThreads2 = numIterations * 1 * numThreads; + const UInt64 numCommands = unpSizeThreads2 * complexity / 256; + const UInt64 rating = info.GetSpeed(numCommands); + PrintResults(_file, info, + benchWeight, rating, + showFreq, cpuFreq, encodeRes); + } + RINOK(_file->CheckBreak()) + } + + speed = info.GetSpeed(unpSizeThreads); + usage = info.GetUsage(); + + return S_OK; +} + + + +static HRESULT TotalBench_Hash( + DECL_EXTERNAL_CODECS_LOC_VARS + const COneMethodInfo &methodMask, + UInt64 complexInCommands, + UInt32 numThreads, + size_t bufSize, + const Byte *fileData, + IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback, + #ifndef Z7_ST + const CAffinityMode *affinityMode, + #endif + CTotalBenchRes *encodeRes, + bool showFreq, UInt64 cpuFreq) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) + { + const CBenchHash &bench = g_Hash[i]; + if (!DoesWildcardMatchName_NoCase(methodMask.MethodName, bench.Name)) + continue; + PrintLeft(*callback->_file, bench.Name, kFieldSize_Name); + // callback->BenchProps.DecComplexUnc = bench.DecComplexUnc; + // callback->BenchProps.DecComplexCompr = bench.DecComplexCompr; + // callback->BenchProps.EncComplex = bench.EncComplex; + + COneMethodInfo method; + NCOM::CPropVariant propVariant; + propVariant = bench.Name; + RINOK(method.ParseMethodFromPROPVARIANT(UString(), propVariant)) + + UInt64 speed, usage; + + const HRESULT res = CrcBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + numThreads, bufSize, fileData, + speed, usage, + bench.Complex, bench.Weight, + (!fileData && bufSize == (1 << kNumHashDictBits)) ? &bench.CheckSum : NULL, + method, + printCallback, + #ifndef Z7_ST + affinityMode, + #endif + true, // showRating + encodeRes, showFreq, cpuFreq); + if (res == E_NOTIMPL) + { + // callback->Print(" ---"); + } + else + { + RINOK(res) + } + callback->NewLine(); + } + return S_OK; +} + +struct CTempValues +{ + UInt64 *Values; + CTempValues(): Values(NULL) {} + void Alloc(UInt32 num) { Values = new UInt64[num]; } + ~CTempValues() { delete []Values; } +}; + +static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) +{ + const wchar_t *end; + UInt64 result = ConvertStringToUInt64(s, &end); + if (*end != 0 || s.IsEmpty()) + prop = s; + else if (result <= (UInt32)0xFFFFFFFF) + prop = (UInt32)result; + else + prop = result; +} + + +static bool AreSameMethodNames(const char *fullName, const char *shortName) +{ + return StringsAreEqualNoCase_Ascii(fullName, shortName); +} + + + + +static void Print_Usage_and_Threads(IBenchPrintCallback &f, UInt64 usage, UInt32 threads) +{ + PrintRequirements(f, "usage:", true, usage, "Benchmark threads: ", threads); +} + + +static void Print_Delimiter(IBenchPrintCallback &f) +{ + f.Print(" |"); +} + +static void Print_Pow(IBenchPrintCallback &f, unsigned pow) +{ + char s[16]; + ConvertUInt32ToString(pow, s); + unsigned pos = MyStringLen(s); + s[pos++] = ':'; + s[pos] = 0; + PrintLeft(f, s, kFieldSize_SmallName); // 4 +} + +static void Bench_BW_Print_Usage_Speed(IBenchPrintCallback &f, + UInt64 usage, UInt64 speed) +{ + PrintUsage(f, usage, kFieldSize_Usage); + PrintNumber(f, speed / 1000000, kFieldSize_CrcSpeed); +} + + +HRESULT Bench( + DECL_EXTERNAL_CODECS_LOC_VARS + IBenchPrintCallback *printCallback, + IBenchCallback *benchCallback, + const CObjectVector &props, + UInt32 numIterations, + bool multiDict, + IBenchFreqCallback *freqCallback) +{ + // for (int y = 0; y < 10000; y++) + if (!CrcInternalTest()) + return E_FAIL; + + UInt32 numCPUs = 1; + size_t ramSize = (size_t)sizeof(size_t) << 29; + + NSystem::CProcessAffinity threadsInfo; + threadsInfo.InitST(); + + #ifndef Z7_ST + + if (threadsInfo.Get() && threadsInfo.GetNumProcessThreads() != 0) + numCPUs = threadsInfo.GetNumProcessThreads(); + else + numCPUs = NSystem::GetNumberOfProcessors(); + + #endif + + // numCPUs = 24; + /* + { + DWORD_PTR mask = (1 << 0); + DWORD_PTR old = SetThreadAffinityMask(GetCurrentThread(), mask); + old = old; + DWORD_PTR old2 = SetThreadAffinityMask(GetCurrentThread(), mask); + old2 = old2; + return 0; + } + */ + + const bool ramSize_Defined = NSystem::GetRamSize(ramSize); + + UInt32 numThreadsSpecified = numCPUs; + bool needSetComplexity = false; + UInt32 testTimeMs = kComplexInMs; + UInt32 startDicLog = 22; + bool startDicLog_Defined = false; + UInt64 specifiedFreq = 0; + bool multiThreadTests = false; + UInt64 complexInCommands = kComplexInCommands; + UInt32 numThreads_Start = 1; + +#ifndef Z7_ST + CAffinityMode affinityMode; +#ifdef _WIN32 + if (threadsInfo.IsGroupMode && threadsInfo.Groups.GroupSizes.Size() > 1) + affinityMode.NumGroups = threadsInfo.Groups.GroupSizes.Size(); +#endif +#endif + + + COneMethodInfo method; + + CMidAlignedBuffer fileDataBuffer; + bool use_fileData = false; + bool isFixedDict = false; + + { + unsigned i; + + if (printCallback) + { + for (i = 0; i < props.Size(); i++) + { + const CProperty &property = props[i]; + printCallback->Print(" "); + printCallback->Print(GetAnsiString(property.Name)); + if (!property.Value.IsEmpty()) + { + printCallback->Print("="); + printCallback->Print(GetAnsiString(property.Value)); + } + } + if (!props.IsEmpty()) + printCallback->NewLine(); + } + + + for (i = 0; i < props.Size(); i++) + { + const CProperty &property = props[i]; + UString name (property.Name); + name.MakeLower_Ascii(); + + if (name.IsEqualTo("file")) + { + if (property.Value.IsEmpty()) + return E_INVALIDARG; + + NFile::NIO::CInFile file; + if (!file.Open(us2fs(property.Value))) + return GetLastError_noZero_HRESULT(); + size_t len; + { + UInt64 len64; + if (!file.GetLength(len64)) + return GetLastError_noZero_HRESULT(); + if (printCallback) + { + printCallback->Print("file size ="); + PrintNumber(*printCallback, len64, 0); + printCallback->NewLine(); + } + len = (size_t)len64; + if (len != len64) + return E_INVALIDARG; + } + + // (len == 0) is allowed. Also it's allowed if Alloc(0) returns NULL here + + ALLOC_WITH_HRESULT(&fileDataBuffer, len) + use_fileData = true; + + { + size_t processed; + if (!file.ReadFull((Byte *)fileDataBuffer, len, processed)) + return GetLastError_noZero_HRESULT(); + if (processed != len) + return E_FAIL; + } + continue; + } + + NCOM::CPropVariant propVariant; + if (!property.Value.IsEmpty()) + ParseNumberString(property.Value, propVariant); + + if (name.IsEqualTo("time")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) + needSetComplexity = true; + testTimeMs *= 1000; + continue; + } + + if (name.IsEqualTo("timems")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, testTimeMs)) + needSetComplexity = true; + continue; + } + + if (name.IsEqualTo("tic")) + { + UInt32 v; + RINOK(ParsePropToUInt32(UString(), propVariant, v)) + if (v >= 64) + return E_INVALIDARG; + complexInCommands = (UInt64)1 << v; + continue; + } + + const bool isCurrent_fixedDict = name.IsEqualTo("df"); + if (isCurrent_fixedDict) + isFixedDict = true; + if (isCurrent_fixedDict || name.IsEqualTo("ds")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, startDicLog)) + if (startDicLog > 32) + return E_INVALIDARG; + startDicLog_Defined = true; + continue; + } + + if (name.IsEqualTo("mts")) + { + RINOK(ParsePropToUInt32(UString(), propVariant, numThreads_Start)) + continue; + } + + if (name.IsEqualTo("af")) + { + UInt32 bundle; + RINOK(ParsePropToUInt32(UString(), propVariant, bundle)) + if (bundle > 0 && bundle < numCPUs) + { + #ifndef Z7_ST + affinityMode.SetLevels(numCPUs, 2); + affinityMode.NumBundleThreads = bundle; + #endif + } + continue; + } + + if (name.IsEqualTo("freq")) + { + UInt32 freq32 = 0; + RINOK(ParsePropToUInt32(UString(), propVariant, freq32)) + if (freq32 == 0) + return E_INVALIDARG; + specifiedFreq = (UInt64)freq32 * 1000000; + + if (printCallback) + { + printCallback->Print("freq="); + PrintNumber(*printCallback, freq32, 0); + printCallback->NewLine(); + } + + continue; + } + + if (name.IsPrefixedBy_Ascii_NoCase("mt")) + { + const UString s = name.Ptr(2); + if (s.IsEqualTo("*") + || (s.IsEmpty() + && propVariant.vt == VT_BSTR + && StringsAreEqual_Ascii(propVariant.bstrVal, "*"))) + { + multiThreadTests = true; + continue; + } + #ifndef Z7_ST + RINOK(ParseMtProp(s, propVariant, numCPUs, numThreadsSpecified)) + #endif + continue; + } + + RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)) + } + } + + if (printCallback) + { + AString s; + +#if 1 || !defined(Z7_MSC_VER_ORIGINAL) || (Z7_MSC_VER_ORIGINAL >= 1900) + s += "Compiler: "; + GetCompiler(s); + printCallback->Print(s); + printCallback->NewLine(); + s.Empty(); +#endif + + GetSystemInfoText(s); + printCallback->Print(s); + printCallback->NewLine(); + } + + if (printCallback) + { + printCallback->Print("1T CPU Freq (MHz):"); + } + + if (printCallback || freqCallback) + { + UInt64 numMilCommands = 1 << 6; + if (specifiedFreq != 0) + { + while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) + numMilCommands >>= 1; + } + + for (int jj = 0;; jj++) + { + if (printCallback) + RINOK(printCallback->CheckBreak()) + + UInt64 start = ::GetTimeCount(); + UInt32 sum = (UInt32)start; + sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp); + if (sum == 0xF1541213) + if (printCallback) + printCallback->Print(""); + const UInt64 realDelta = ::GetTimeCount() - start; + start = realDelta; + if (start == 0) + start = 1; + if (start > (UInt64)1 << 61) + start = 1; + const UInt64 freq = GetFreq(); + // mips is constant in some compilers + const UInt64 hzVal = MyMultDiv64(numMilCommands * 1000000, freq, start); + const UInt64 mipsVal = numMilCommands * freq / start; + if (printCallback) + { + if (realDelta == 0) + { + printCallback->Print(" -"); + } + else + { + // PrintNumber(*printCallback, start, 0); + PrintNumber(*printCallback, mipsVal, 5); + } + } + if (freqCallback) + { + RINOK(freqCallback->AddCpuFreq(1, hzVal, kBenchmarkUsageMult)) + } + + if (jj >= 1) + { + bool needStop = (numMilCommands >= (1 << + #ifdef _DEBUG + 7 + #else + 11 + #endif + )); + if (start >= freq * 16) + { + printCallback->Print(" (Cmplx)"); + if (!freqCallback) // we don't want complexity change for old gui lzma benchmark + { + needSetComplexity = true; + } + needStop = true; + } + if (needSetComplexity) + SetComplexCommandsMs(testTimeMs, false, mipsVal * 1000000, complexInCommands); + if (needStop) + break; + numMilCommands <<= 1; + } + } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(1)) + } + } + + if (printCallback || freqCallback) + for (unsigned test = 0; test < 3; test++) + { + if (numThreadsSpecified < 2) + { + // if (test == 1) + break; + } + if (test == 2 && numThreadsSpecified <= numCPUs) + break; + if (printCallback) + printCallback->NewLine(); + + /* it can show incorrect frequency for HT threads. */ + + UInt32 numThreads = numThreadsSpecified; + if (test < 2) + { + if (numThreads >= numCPUs) + numThreads = numCPUs; + if (test == 0) + numThreads /= 2; + } + if (numThreads < 1) + numThreads = 1; + + if (printCallback) + { + char s[128]; + ConvertUInt64ToString(numThreads, s); + printCallback->Print(s); + printCallback->Print("T CPU Freq (MHz):"); + } + UInt64 numMilCommands = 1 << + #ifdef _DEBUG + 7; + #else + 10; + #endif + + if (specifiedFreq != 0) + { + while (numMilCommands > 1 && specifiedFreq < (numMilCommands * 1000000)) + numMilCommands >>= 1; + } + + // for (int jj = 0;; jj++) + for (;;) + { + if (printCallback) + RINOK(printCallback->CheckBreak()) + + { + // PrintLeft(f, "CPU", kFieldSize_Name); + + // UInt32 resVal; + + CFreqBench fb; + fb.complexInCommands = numMilCommands * 1000000; + fb.numThreads = numThreads; + // showFreq; + // fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); + fb.showFreq = true; + fb.specifiedFreq = 1; + + const HRESULT res = fb.FreqBench(NULL /* printCallback */ + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) + + if (freqCallback) + { + RINOK(freqCallback->AddCpuFreq(numThreads, fb.CpuFreqRes, fb.UsageRes)) + } + + if (printCallback) + { + /* + if (realDelta == 0) + { + printCallback->Print(" -"); + } + else + */ + { + // PrintNumber(*printCallback, start, 0); + PrintUsage(*printCallback, fb.UsageRes, 3); + printCallback->Print("%"); + PrintNumber(*printCallback, fb.CpuFreqRes / 1000000, 0); + printCallback->Print(" "); + + // PrintNumber(*printCallback, fb.UsageRes, 5); + } + } + } + // if (jj >= 1) + { + const bool needStop = (numMilCommands >= (1 << + #ifdef _DEBUG + 7 + #else + 11 + #endif + )); + if (needStop) + break; + numMilCommands <<= 1; + } + } + if (freqCallback) + { + RINOK(freqCallback->FreqsFinished(numThreads)) + } + } + + + if (printCallback) + { + printCallback->NewLine(); + printCallback->NewLine(); + PrintRequirements(*printCallback, "size: ", ramSize_Defined, ramSize, "CPU hardware threads:", numCPUs); + printCallback->Print(GetProcessThreadsInfo(threadsInfo)); + printCallback->NewLine(); + } + + if (numThreadsSpecified < 1 || numThreadsSpecified > kNumThreadsMax) + return E_INVALIDARG; + + UInt64 dict = (UInt64)1 << startDicLog; + const bool dictIsDefined = (isFixedDict || method.Get_DicSize(dict)); + + const unsigned level = method.GetLevel(); + + AString &methodName = method.MethodName; + const AString original_MethodName = methodName; + if (methodName.IsEmpty()) + methodName = "LZMA"; + + if (benchCallback) + { + CBenchProps benchProps; + benchProps.SetLzmaCompexity(); + const UInt64 dictSize = method.Get_Lzma_DicSize(); + + size_t uncompressedDataSize; + if (use_fileData) + { + uncompressedDataSize = fileDataBuffer.Size(); + } + else + { + uncompressedDataSize = kAdditionalSize + (size_t)dictSize; + if (uncompressedDataSize < dictSize) + return E_INVALIDARG; + } + + return MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + true, numThreadsSpecified, + &affinityMode, + #endif + method, + uncompressedDataSize, (const Byte *)fileDataBuffer, + kOldLzmaDictBits, printCallback, benchCallback, &benchProps); + } + + if (methodName.IsEqualTo_Ascii_NoCase("CRC")) + methodName = "crc32"; + + CMethodId hashID; + const bool isHashMethod = FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, hashID); + int codecIndex = -1; + bool isFilter = false; + if (!isHashMethod) + { + UInt32 numStreams; + codecIndex = FindMethod_Index(EXTERNAL_CODECS_LOC_VARS original_MethodName, + true, // encode + hashID, numStreams, isFilter); + // we can allow non filter for BW tests + if (!isFilter) codecIndex = -1; + } + + CBenchCallbackToPrint callback; + callback.Init(); + callback._file = printCallback; + + if (isHashMethod || codecIndex != -1) + { + if (!printCallback) + return S_FALSE; + IBenchPrintCallback &f = *printCallback; + + UInt64 dict64 = dict; + if (!dictIsDefined) + dict64 = (1 << 27); + if (use_fileData) + { + if (!dictIsDefined) + dict64 = fileDataBuffer.Size(); + else if (dict64 > fileDataBuffer.Size()) + dict64 = fileDataBuffer.Size(); + } + + for (;;) + { + const int index = method.FindProp(NCoderPropID::kDictionarySize); + if (index < 0) + break; + method.Props.Delete((unsigned)index); + } + + // methodName.RemoveChar(L'-'); + Int32 complexity = 16 * k_Hash_Complex_Mult; // for unknown hash method + const UInt32 *checkSum = NULL; + int benchIndex = -1; + + if (isHashMethod) + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Hash); i++) + { + const CBenchHash &h = g_Hash[i]; + AString benchMethod (h.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) + { + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); + /* + bool isMainMethod = method.PropsString.IsEmpty(); + if (isMainMethod) + isMainMethod = !checkSum + || (benchMethod.IsEqualTo_Ascii_NoCase("crc32") && benchProps.IsEqualTo_Ascii_NoCase("8")); + if (sameProps || isMainMethod) + */ + { + complexity = (Int32)h.Complex; + checkSum = &h.CheckSum; + if (sameProps) + break; + /* + if property. is not specified, we use the complexity + for latest fastest method (crc32:64) + */ + } + } + } + // if (!checkSum) return E_NOTIMPL; + } + else + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) + { + const CBenchMethod &bench = g_Bench[i]; + AString benchMethod (bench.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) + { + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + const bool sameProps = method.PropsString.IsEqualTo_Ascii_NoCase(benchProps); + // bool isMainMethod = method.PropsString.IsEmpty(); + // if (sameProps || isMainMethod) + { + benchIndex = (int)i; + if (sameProps) + break; + } + } + } + // if (benchIndex < 0) return E_NOTIMPL; + } + + { + /* we count usage only for crc and filter. non-filters are not supported */ + UInt64 usage = (1 << 20); + UInt64 bufSize = dict64; + UInt32 numBlocks = isHashMethod ? 1 : 3; + if (use_fileData) + { + usage += fileDataBuffer.Size(); + if (bufSize > fileDataBuffer.Size()) + bufSize = fileDataBuffer.Size(); + if (isHashMethod) + { + numBlocks = 0; + #ifndef Z7_ST + if (numThreadsSpecified != 1) + numBlocks = (k_Crc_CreateLocalBuf_For_File ? 1 : 0); + #endif + } + } + usage += numThreadsSpecified * bufSize * numBlocks; + Print_Usage_and_Threads(f, usage, numThreadsSpecified); + } + + CUIntVector numThreadsVector; + { + unsigned nt = numThreads_Start; + for (;;) + { + if (nt > numThreadsSpecified) + break; + numThreadsVector.Add(nt); + const unsigned next = nt * 2; + const UInt32 ntHalf= numThreadsSpecified / 2; + if (ntHalf > nt && ntHalf < next) + numThreadsVector.Add(ntHalf); + if (numThreadsSpecified > nt && numThreadsSpecified < next) + numThreadsVector.Add(numThreadsSpecified); + nt = next; + } + } + + unsigned numColumns = isHashMethod ? 1 : 2; + CTempValues speedTotals; + CTempValues usageTotals; + { + const unsigned numItems = numThreadsVector.Size() * numColumns; + speedTotals.Alloc(numItems); + usageTotals.Alloc(numItems); + for (unsigned i = 0; i < numItems; i++) + { + speedTotals.Values[i] = 0; + usageTotals.Values[i] = 0; + } + } + + f.NewLine(); + for (unsigned line = 0; line < 3; line++) + { + f.NewLine(); + f.Print(line == 0 ? "THRD" : line == 1 ? " " : "Size"); + FOR_VECTOR (ti, numThreadsVector) + { + if (ti != 0) + Print_Delimiter(f); + if (line == 0) + { + PrintSpaces(f, (kFieldSize_CrcSpeed + kFieldSize_Usage + 2) * (numColumns - 1)); + PrintNumber(f, numThreadsVector[ti], 1 + kFieldSize_Usage + kFieldSize_CrcSpeed); + } + else + { + for (unsigned c = 0; c < numColumns; c++) + { + PrintRight(f, line == 1 ? "Usage" : "%", kFieldSize_Usage + 1); + PrintRight(f, line == 1 ? "BW" : "MB/s", kFieldSize_CrcSpeed + 1); + } + } + } + } + f.NewLine(); + + UInt64 numSteps = 0; + + // for (UInt32 iter = 0; iter < numIterations; iter++) + // { + unsigned pow = 10; // kNumHashDictBits + if (startDicLog_Defined) + pow = startDicLog; + + // #define NUM_SUB_BITS 2 + // pow <<= NUM_SUB_BITS; + for (;; pow++) + { + const UInt64 bufSize = (UInt64)1 << pow; + // UInt64 bufSize = (UInt64)1 << (pow >> NUM_SUB_BITS); + // bufSize += ((UInt64)pow & ((1 << NUM_SUB_BITS) - 1)) << ((pow >> NUM_SUB_BITS) - NUM_SUB_BITS); + + size_t dataSize = fileDataBuffer.Size(); + if (dataSize > bufSize || !use_fileData) + dataSize = (size_t)bufSize; + + for (UInt32 iter = 0; iter < numIterations; iter++) + { + Print_Pow(f, pow); + // PrintNumber(f, bufSize >> 10, 4); + + FOR_VECTOR (ti, numThreadsVector) + { + RINOK(f.CheckBreak()) + const UInt32 numThreads = numThreadsVector[ti]; + if (isHashMethod) + { + UInt64 speed = 0; + UInt64 usage = 0; + const HRESULT res = CrcBench(EXTERNAL_CODECS_LOC_VARS complexInCommands, + numThreads, + dataSize, (const Byte *)fileDataBuffer, + speed, usage, + (UInt32)complexity, + 1, // benchWeight, + (pow == kNumHashDictBits && !use_fileData) ? checkSum : NULL, + method, + &f, + #ifndef Z7_ST + &affinityMode, + #endif + false, // showRating + NULL, false, 0); + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + Bench_BW_Print_Usage_Speed(f, usage, speed); + speedTotals.Values[ti] += speed; + usageTotals.Values[ti] += usage; + } + else + { + { + unsigned keySize = 32; + if (IsString1PrefixedByString2(methodName, "AES128")) keySize = 16; + else if (IsString1PrefixedByString2(methodName, "AES192")) keySize = 24; + callback.BenchProps.KeySize = keySize; + } + + COneMethodInfo method2 = method; + unsigned bench_DictBits; + + if (benchIndex >= 0) + { + const CBenchMethod &bench = g_Bench[benchIndex]; + callback.BenchProps.EncComplex = bench.EncComplex; + callback.BenchProps.DecComplexUnc = bench.DecComplexUnc; + callback.BenchProps.DecComplexCompr = bench.DecComplexCompr; + bench_DictBits = bench.DictBits; + // bench_DictBits = kOldLzmaDictBits; = 32 default : for debug + } + else + { + bench_DictBits = kOldLzmaDictBits; // = 32 default + if (isFilter) + { + const unsigned k_UnknownCoderComplexity = 4; + callback.BenchProps.EncComplex = k_UnknownCoderComplexity; + callback.BenchProps.DecComplexUnc = k_UnknownCoderComplexity; + } + else + { + callback.BenchProps.EncComplex = 1 << 10; + callback.BenchProps.DecComplexUnc = 1 << 6; + } + callback.BenchProps.DecComplexCompr = 0; + } + callback.NeedPrint = false; + + if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA")) + { + const NCOM::CPropVariant propVariant = (UInt32)pow; + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) + } + + const HRESULT res = MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + false, // oldLzmaBenchMode + numThreadsVector[ti], + &affinityMode, + #endif + method2, + dataSize, (const Byte *)fileDataBuffer, + bench_DictBits, + printCallback, + &callback, + &callback.BenchProps); + RINOK(res) + + if (ti != 0) + Print_Delimiter(f); + + for (unsigned i = 0; i < 2; i++) + { + const CBenchInfo &bi = callback.BenchInfo_Results[i]; + const UInt64 usage = bi.GetUsage(); + const UInt64 speed = bi.GetUnpackSizeSpeed(); + usageTotals.Values[ti * 2 + i] += usage; + speedTotals.Values[ti * 2 + i] += speed; + Bench_BW_Print_Usage_Speed(f, usage, speed); + } + } + } + + f.NewLine(); + numSteps++; + } + if (dataSize >= dict64) + break; + } + + if (numSteps != 0) + { + f.Print("Avg:"); + for (unsigned ti = 0; ti < numThreadsVector.Size(); ti++) + { + if (ti != 0) + Print_Delimiter(f); + for (unsigned i = 0; i < numColumns; i++) + Bench_BW_Print_Usage_Speed(f, + usageTotals.Values[ti * numColumns + i] / numSteps, + speedTotals.Values[ti * numColumns + i] / numSteps); + } + f.NewLine(); + } + + return S_OK; + } + + bool use2Columns = false; + + bool totalBenchMode = false; + bool onlyHashBench = false; + if (methodName.IsEqualTo_Ascii_NoCase("hash")) + { + onlyHashBench = true; + methodName = "*"; + totalBenchMode = true; + } + else if (methodName.Find('*') >= 0) + totalBenchMode = true; + + // ---------- Threads loop ---------- + for (unsigned threadsPassIndex = 0; threadsPassIndex < 3; threadsPassIndex++) + { + + UInt32 numThreads = numThreadsSpecified; + + if (!multiThreadTests) + { + if (threadsPassIndex != 0) + break; + } + else + { + numThreads = 1; + if (threadsPassIndex != 0) + { + if (numCPUs < 2) + break; + numThreads = numCPUs; + if (threadsPassIndex == 1) + { + if (numCPUs >= 4) + numThreads = numCPUs / 2; + } + else if (numCPUs < 4) + break; + } + } + + IBenchPrintCallback &f = *printCallback; + + if (threadsPassIndex > 0) + { + f.NewLine(); + f.NewLine(); + } + + if (!dictIsDefined && !onlyHashBench) + { + // we use dicSizeLog and dicSizeLog_Main for data size. + // also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize. + const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); + unsigned dicSizeLog = dicSizeLog_Main; + + #ifdef UNDER_CE + dicSizeLog = (UInt64)1 << 20; + #endif + + if (ramSize_Defined) + for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) + if (GetBenchMemoryUsage(numThreads, (int)level, ((UInt64)1 << dicSizeLog), totalBenchMode) + (8 << 20) <= ramSize) + break; + + dict = (UInt64)1 << dicSizeLog; + + if (totalBenchMode && dicSizeLog != dicSizeLog_Main) + { + f.Print("Dictionary reduced to: "); + PrintNumber(f, dicSizeLog, 1); + f.NewLine(); + } + } + + Print_Usage_and_Threads(f, + onlyHashBench ? + GetBenchMemoryUsage_Hash(numThreads, dict) : + GetBenchMemoryUsage(numThreads, (int)level, dict, totalBenchMode), + numThreads); + + f.NewLine(); + + f.NewLine(); + + if (totalBenchMode) + { + callback.NameFieldSize = kFieldSize_Name; + use2Columns = false; + } + else + { + callback.NameFieldSize = kFieldSize_SmallName; + use2Columns = true; + } + callback.Use2Columns = use2Columns; + + bool showFreq = false; + UInt64 cpuFreq = 0; + + if (totalBenchMode) + { + showFreq = true; + } + + unsigned fileldSize = kFieldSize_TotalSize; + if (showFreq) + fileldSize += kFieldSize_EUAndEffec; + + if (use2Columns) + { + PrintSpaces(f, callback.NameFieldSize); + PrintRight(f, "Compressing", fileldSize); + f.Print(kSep); + PrintRight(f, "Decompressing", fileldSize); + } + f.NewLine(); + PrintLeft(f, totalBenchMode ? "Method" : "Dict", callback.NameFieldSize); + + int j; + + for (j = 0; j < 2; j++) + { + PrintRight(f, "Speed", kFieldSize_Speed + 1); + PrintRight(f, "Usage", kFieldSize_Usage + 1); + PrintRight(f, "R/U", kFieldSize_RU + 1); + PrintRight(f, "Rating", kFieldSize_Rating + 1); + if (showFreq) + { + PrintRight(f, "E/U", kFieldSize_EU + 1); + PrintRight(f, "Effec", kFieldSize_Effec + 1); + } + if (!use2Columns) + break; + if (j == 0) + f.Print(kSep); + } + + f.NewLine(); + PrintSpaces(f, callback.NameFieldSize); + + for (j = 0; j < 2; j++) + { + PrintRight(f, "KiB/s", kFieldSize_Speed + 1); + PrintRight(f, "%", kFieldSize_Usage + 1); + PrintRight(f, "MIPS", kFieldSize_RU + 1); + PrintRight(f, "MIPS", kFieldSize_Rating + 1); + if (showFreq) + { + PrintRight(f, "%", kFieldSize_EU + 1); + PrintRight(f, "%", kFieldSize_Effec + 1); + } + if (!use2Columns) + break; + if (j == 0) + f.Print(kSep); + } + + f.NewLine(); + f.NewLine(); + + if (specifiedFreq != 0) + cpuFreq = specifiedFreq; + + // bool showTotalSpeed = false; + + if (totalBenchMode) + { + for (UInt32 i = 0; i < numIterations; i++) + { + if (i != 0) + printCallback->NewLine(); + + const unsigned kNumCpuTests = 3; + for (unsigned freqTest = 0; freqTest < kNumCpuTests; freqTest++) + { + PrintLeft(f, "CPU", kFieldSize_Name); + + // UInt32 resVal; + + CFreqBench fb; + fb.complexInCommands = complexInCommands; + fb.numThreads = numThreads; + // showFreq; + fb.showFreq = (freqTest == kNumCpuTests - 1 || specifiedFreq != 0); + fb.specifiedFreq = specifiedFreq; + + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) + + cpuFreq = fb.CpuFreqRes; + callback.NewLine(); + + if (specifiedFreq != 0) + cpuFreq = specifiedFreq; + + if (testTimeMs >= 1000) + if (freqTest == kNumCpuTests - 1) + { + // SetComplexCommandsMs(testTimeMs, specifiedFreq != 0, cpuFreq, complexInCommands); + } + } + callback.NewLine(); + + // return S_OK; // change it + + callback.SetFreq(true, cpuFreq); + + if (!onlyHashBench) + { + size_t dataSize = (size_t)dict; + if (use_fileData) + { + dataSize = fileDataBuffer.Size(); + if (dictIsDefined && dataSize > dict) + dataSize = (size_t)dict; + } + + const HRESULT res = TotalBench(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + #ifndef Z7_ST + numThreads, + &affinityMode, + #endif + dictIsDefined || use_fileData, // forceUnpackSize + dataSize, + (const Byte *)fileDataBuffer, + printCallback, &callback); + RINOK(res) + } + + { + size_t dataSize = (size_t)1 << kNumHashDictBits; + if (dictIsDefined) + { + dataSize = (size_t)dict; + if (dataSize != dict) + return E_OUTOFMEMORY; + } + if (use_fileData) + { + dataSize = fileDataBuffer.Size(); + if (dictIsDefined && dataSize > dict) + dataSize = (size_t)dict; + } + + const HRESULT res = TotalBench_Hash(EXTERNAL_CODECS_LOC_VARS + method, complexInCommands, + numThreads, + dataSize, (const Byte *)fileDataBuffer, + printCallback, &callback, + #ifndef Z7_ST + &affinityMode, + #endif + &callback.EncodeRes, true, cpuFreq); + RINOK(res) + } + + callback.NewLine(); + { + PrintLeft(f, "CPU", kFieldSize_Name); + + CFreqBench fb; + fb.complexInCommands = complexInCommands; + fb.numThreads = numThreads; + // showFreq; + fb.showFreq = (specifiedFreq != 0); + fb.specifiedFreq = specifiedFreq; + + const HRESULT res = fb.FreqBench(printCallback + #ifndef Z7_ST + , &affinityMode + #endif + ); + RINOK(res) + callback.NewLine(); + } + } + } + else + { + needSetComplexity = true; + if (!methodName.IsEqualTo_Ascii_NoCase("LZMA")) + { + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(g_Bench); i++) + { + const CBenchMethod &h = g_Bench[i]; + AString benchMethod (h.Name); + AString benchProps; + const int propPos = benchMethod.Find(':'); + if (propPos >= 0) + { + benchProps = benchMethod.Ptr((unsigned)(propPos + 1)); + benchMethod.DeleteFrom((unsigned)propPos); + } + + if (AreSameMethodNames(benchMethod, methodName)) + { + if (benchProps.IsEmpty() + || (benchProps.IsEqualTo("x5") && method.PropsString.IsEmpty()) + || method.PropsString.IsPrefixedBy_Ascii_NoCase(benchProps)) + { + callback.BenchProps.EncComplex = h.EncComplex; + callback.BenchProps.DecComplexCompr = h.DecComplexCompr; + callback.BenchProps.DecComplexUnc = h.DecComplexUnc; + needSetComplexity = false; + break; + } + } + } + /* + if (i == Z7_ARRAY_SIZE(g_Bench)) + return E_NOTIMPL; + */ + } + if (needSetComplexity) + callback.BenchProps.SetLzmaCompexity(); + + if (startDicLog < kBenchMinDicLogSize) + startDicLog = kBenchMinDicLogSize; + + for (unsigned i = 0; i < numIterations; i++) + { + unsigned pow = (dict < GetDictSizeFromLog(startDicLog)) ? kBenchMinDicLogSize : (unsigned)startDicLog; + if (!multiDict) + pow = 32; + while (GetDictSizeFromLog(pow) > dict && pow > 0) + pow--; + for (; GetDictSizeFromLog(pow) <= dict; pow++) + { + Print_Pow(f, pow); + callback.DictSize = (UInt64)1 << pow; + + COneMethodInfo method2 = method; + + if (StringsAreEqualNoCase_Ascii(method2.MethodName, "LZMA")) + { + // We add dictionary size property. + // method2 can have two different dictionary size properties. + // And last property is main. + NCOM::CPropVariant propVariant = (UInt32)pow; + RINOK(method2.ParseMethodFromPROPVARIANT((UString)"d", propVariant)) + } + + size_t uncompressedDataSize; + if (use_fileData) + { + uncompressedDataSize = fileDataBuffer.Size(); + } + else + { + uncompressedDataSize = (size_t)callback.DictSize; + if (uncompressedDataSize != callback.DictSize) + return E_OUTOFMEMORY; + if (uncompressedDataSize >= (1 << 18)) + uncompressedDataSize += kAdditionalSize; + } + + const HRESULT res = MethodBench( + EXTERNAL_CODECS_LOC_VARS + complexInCommands, + #ifndef Z7_ST + true, numThreads, + &affinityMode, + #endif + method2, + uncompressedDataSize, (const Byte *)fileDataBuffer, + kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps); + f.NewLine(); + RINOK(res) + if (!multiDict) + break; + } + } + } + + PrintChars(f, '-', callback.NameFieldSize + fileldSize); + + if (use2Columns) + { + f.Print(kSep); + PrintChars(f, '-', fileldSize); + } + + f.NewLine(); + + if (use2Columns) + { + PrintLeft(f, "Avr:", callback.NameFieldSize); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.EncodeRes); + f.Print(kSep); + PrintTotals(f, showFreq, cpuFreq, !totalBenchMode, callback.DecodeRes); + f.NewLine(); + } + + PrintLeft(f, "Tot:", callback.NameFieldSize); + CTotalBenchRes midRes; + midRes = callback.EncodeRes; + midRes.Update_With_Res(callback.DecodeRes); + + // midRes.SetSum(callback.EncodeRes, callback.DecodeRes); + PrintTotals(f, showFreq, cpuFreq, false, midRes); + f.NewLine(); + + } + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Bench.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/Bench.h 2015-11-06 12:02:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Bench.h 2023-04-06 08:00:00.000000000 +0000 @@ -1,55 +1,121 @@ -// Bench.h - -#ifndef __7ZIP_BENCH_H -#define __7ZIP_BENCH_H - -#include "../../Common/CreateCoder.h" -#include "../../UI/Common/Property.h" - -struct CBenchInfo -{ - UInt64 GlobalTime; - UInt64 GlobalFreq; - UInt64 UserTime; - UInt64 UserFreq; - UInt64 UnpackSize; - UInt64 PackSize; - UInt64 NumIterations; - - CBenchInfo(): NumIterations(0) {} - UInt64 GetUsage() const; - UInt64 GetRatingPerUsage(UInt64 rating) const; - UInt64 GetSpeed(UInt64 numCommands) const; -}; - -struct IBenchCallback -{ - virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; - virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; - virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; -}; - -UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size); -UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations); - -const unsigned kBenchMinDicLogSize = 18; - -UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false); - -struct IBenchPrintCallback -{ - virtual void Print(const char *s) = 0; - virtual void NewLine() = 0; - virtual HRESULT CheckBreak() = 0; -}; - -HRESULT Bench( - DECL_EXTERNAL_CODECS_LOC_VARS - IBenchPrintCallback *printCallback, - IBenchCallback *benchCallback, - const CObjectVector &props, - UInt32 numIterations, - bool multiDict - ); - -#endif +// Bench.h + +#ifndef ZIP7_INC_7ZIP_BENCH_H +#define ZIP7_INC_7ZIP_BENCH_H + +#include "../../../Windows/System.h" + +#include "../../Common/CreateCoder.h" +#include "../../UI/Common/Property.h" + +UInt64 Benchmark_GetUsage_Percents(UInt64 usage); + +struct CBenchInfo +{ + UInt64 GlobalTime; + UInt64 GlobalFreq; + UInt64 UserTime; + UInt64 UserFreq; + UInt64 UnpackSize; + UInt64 PackSize; + UInt64 NumIterations; + + /* + during Code(): we track benchInfo only from one thread (theads with index[0]) + NumIterations means number of threads + UnpackSize and PackSize are total sizes of all iterations of current thread + after Code(): + NumIterations means the number of Iterations + UnpackSize and PackSize are total sizes of all threads + */ + + CBenchInfo(): NumIterations(0) {} + + UInt64 GetUsage() const; + UInt64 GetRatingPerUsage(UInt64 rating) const; + UInt64 GetSpeed(UInt64 numUnits) const; + UInt64 GetUnpackSizeSpeed() const { return GetSpeed(UnpackSize * NumIterations); } + + UInt64 Get_UnpackSize_Full() const { return UnpackSize * NumIterations; } + + UInt64 GetRating_LzmaEnc(UInt64 dictSize) const; + UInt64 GetRating_LzmaDec() const; +}; + + +struct CTotalBenchRes +{ + // UInt64 NumIterations1; // for Usage + UInt64 NumIterations2; // for Rating / RPU + + UInt64 Rating; + UInt64 Usage; + UInt64 RPU; + UInt64 Speed; + + void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; Speed = 0; } + + void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2) + { + Rating = (r1.Rating + r2.Rating); + Usage = (r1.Usage + r2.Usage); + RPU = (r1.RPU + r2.RPU); + Speed = (r1.Speed + r2.Speed); + // NumIterations1 = (r1.NumIterations1 + r2.NumIterations1); + NumIterations2 = (r1.NumIterations2 + r2.NumIterations2); + } + + void Generate_From_BenchInfo(const CBenchInfo &info); + void Mult_For_Weight(unsigned weight); + void Update_With_Res(const CTotalBenchRes &r); +}; + + +const unsigned kBenchMinDicLogSize = 18; + +UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench); + +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(IBenchCallback) +{ + // virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0; + virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0; + virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0; +}; + +DECLARE_INTERFACE(IBenchPrintCallback) +{ + virtual void Print(const char *s) = 0; + virtual void NewLine() = 0; + virtual HRESULT CheckBreak() = 0; +}; + +DECLARE_INTERFACE(IBenchFreqCallback) +{ + virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) = 0; + virtual HRESULT FreqsFinished(unsigned numThreads) = 0; +}; +Z7_PURE_INTERFACES_END + +HRESULT Bench( + DECL_EXTERNAL_CODECS_LOC_VARS + IBenchPrintCallback *printCallback, + IBenchCallback *benchCallback, + const CObjectVector &props, + UInt32 numIterations, + bool multiDict, + IBenchFreqCallback *freqCallback = NULL); + +AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti); + +void GetSysInfo(AString &s1, AString &s2); +void GetCpuName(AString &s); +void AddCpuFeatures(AString &s); + +#ifdef Z7_LARGE_PAGES +void Add_LargePages_String(AString &s); +#else +// #define Add_LargePages_String +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall.cpp 2015-07-14 20:16:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,413 +1,343 @@ -// CompressCall.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -#undef _WIN32 - -#include - -#include "../../../Common/IntToString.h" -#include "../../../Common/MyCom.h" -#include "../../../Common/Random.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileDir.h" -// #include "../../../Windows/FileMapping.h" -// #include "../../../Windows/ProcessUtils.h" -#include "../../../Windows/Synchronization.h" - -#include "../FileManager/RegistryUtils.h" - -#include "CompressCall.h" - -using namespace NWindows; - -#define MY_TRY_BEGIN try { - -#define MY_TRY_FINISH } \ - catch(...) { ErrorMessageHRESULT(E_FAIL); return E_FAIL; } - -#define MY_TRY_FINISH_VOID } \ - catch(...) { ErrorMessageHRESULT(E_FAIL); } - -#ifdef _WIN32 -static const char *k7zGui = "7zG.exe"; -#else -static const char *k7zGui = "7zG"; -#endif - -static const char *kShowDialogSwitch = " -ad"; -static const char *kEmailSwitch = " -seml."; -static const char *kIncludeSwitch = " -i"; -static const char *kArchiveTypeSwitch = " -t"; -static const char *kArcIncludeSwitches = " -an -ai"; -static const char *kHashIncludeSwitches = " -i"; -static const char *kStopSwitchParsing = " --"; -static const char *kLargePagesDisable = " -slp-"; - -extern HWND g_HWND; - -UString GetQuotedString(const UString &s) -{ - UString s2 = L'\"'; - s2 += s; - s2 += L'\"'; - return s2; -} - -static void ErrorMessage(LPCWSTR message) -{ - MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR | MB_OK); -} - -static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL) -{ - UString s2 = NError::MyFormatMessage(res); - if (s) - { - s2.Add_LF(); - s2 += s; - } - ErrorMessage(s2); -} - -static HRESULT Call7zGui(const UString ¶ms, - // LPCWSTR curDir, - bool waitFinish, - NSynchronization::CBaseEvent *event) -{ - UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix()); - imageName.AddAscii(k7zGui); - -#ifdef _WIN32 - CProcess process; - WRes res = process.Create(imageName, params, NULL); // curDir); - if (res != 0) - { - ErrorMessageHRESULT(res, imageName); - return res; - } - if (waitFinish) - process.Wait(); - else if (event != NULL) - { - HANDLE handles[] = { process, *event }; - ::WaitForMultipleObjects(ARRAY_SIZE(handles), handles, FALSE, INFINITE); - } -#else - printf("MyCreateProcess: waitFinish=%d event=%p\n",(unsigned)waitFinish,event); - printf("\timageName : %ls\n",(const wchar_t*)imageName); - printf("\tparams : %ls\n",(const wchar_t*)params); - // printf("\tcurDir : %ls\n",(const wchar_t*)curDir); - - wxString cmd; - cmd = (const wchar_t*)imageName; - cmd += L" "; - cmd += (const wchar_t*)params; - wxString memoCurDir = wxGetCwd(); - -/* - if (curDir) { // FIXME - wxSetWorkingDirectory(wxString(curDir)); - - - // under MacOSX, a bundle does not keep the current directory - // between 7zFM and 7zG ... - // So, try to use the environment variable P7ZIP_CURRENT_DIR - - char p7zip_current_dir[MAX_PATH]; - - AString aCurPath = GetAnsiString(curDir); - - const char *dir2 = nameWindowToUnix((const char *)aCurPath); - - snprintf(p7zip_current_dir,sizeof(p7zip_current_dir),"P7ZIP_CURRENT_DIR=%s/",dir2); - - p7zip_current_dir[sizeof(p7zip_current_dir)-1] = 0; - - putenv(p7zip_current_dir); - - printf("putenv(%s)\n",p7zip_current_dir); - - } -*/ - - printf("MyCreateProcess: cmd='%ls'\n",(const wchar_t *)cmd); - long pid = 0; - if (waitFinish) pid = wxExecute(cmd, wxEXEC_SYNC); // FIXME process never ends and stays zombie ... - else pid = wxExecute(cmd, wxEXEC_ASYNC); - -// if (curDir) wxSetWorkingDirectory(memoCurDir); - - - // FIXME if (pid == 0) return E_FAIL; -#endif - return S_OK; -} - -static void AddLagePagesSwitch(UString ¶ms) -{ - if (!ReadLockMemoryEnable()) - params.AddAscii(kLargePagesDisable); -} - -class CRandNameGenerator -{ - CRandom _random; -public: - CRandNameGenerator() { _random.Init(); } - void GenerateName(UString &s, const char *prefix) - { - s.AddAscii(prefix); - char temp[16]; - ConvertUInt32ToString((UInt32)(unsigned)_random.Generate(), temp); - s.AddAscii(temp); - } -}; - -#ifdef _WIN32 -static HRESULT CreateMap(const UStringVector &names, - CFileMapping &fileMapping, NSynchronization::CManualResetEvent &event, - UString ¶ms) -{ - size_t totalSize = 1; - { - FOR_VECTOR (i, names) - totalSize += (names[i].Len() + 1); - } - totalSize *= sizeof(wchar_t); - - CRandNameGenerator random; - - UString mappingName; - for (;;) - { - random.GenerateName(mappingName, "7zMap"); - - WRes res = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName)); - if (fileMapping.IsCreated() && res == 0) - break; - if (res != ERROR_ALREADY_EXISTS) - return res; - fileMapping.Close(); - } - - UString eventName; - for (;;) - { - random.GenerateName(eventName, "7zEvent"); - WRes res = event.CreateWithName(false, GetSystemString(eventName)); - if (event.IsCreated() && res == 0) - break; - if (res != ERROR_ALREADY_EXISTS) - return res; - event.Close(); - } - - params += L'#'; - params += mappingName; - params += L':'; - char temp[32]; - ConvertUInt64ToString(totalSize, temp); - params.AddAscii(temp); - - params += L':'; - params += eventName; - - LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize); - if (!data) - return E_FAIL; - CFileUnmapper unmapper(data); - { - wchar_t *cur = (wchar_t *)data; - *cur++ = 0; // it means wchar_t strings (UTF-16 in WIN32) - FOR_VECTOR (i, names) - { - const UString &s = names[i]; - unsigned len = s.Len() + 1; - wmemcpy(cur, (const wchar_t *)s, len); - cur += len; - } - } - return S_OK; -} -#endif - -HRESULT CompressFiles( - const UString &arcPathPrefix, - const UString &arcName, - const UString &arcType, - bool addExtension, - const UStringVector &names, - bool email, bool showDialog, bool waitFinish) -{ - MY_TRY_BEGIN - UString params = L'a'; - -#ifdef _WIN32 - CFileMapping fileMapping; - NSynchronization::CManualResetEvent event; - params.AddAscii(kIncludeSwitch); - RINOK(CreateMap(names, fileMapping, event, params)); -#else - NSynchronization::CManualResetEvent event; - char tempFile[256]; - static int count = 1000; - - sprintf(tempFile,"/tmp/7zCompress_%d_%d.tmp",(int)getpid(),count++); - - FILE * file = fopen(tempFile,"w"); - if (file) - { - for (int i = 0; i < names.Size(); i++) { - fprintf(file,"%ls\n",(const wchar_t *)names[i]); - printf(" TMP_%d : '%ls'\n",i,(const wchar_t *)names[i]); - } - - fclose(file); - } - params += L" -i@"; - params += GetUnicodeString(tempFile); -#endif - - if (!arcType.IsEmpty()) - { - params.AddAscii(kArchiveTypeSwitch); - params += arcType; - } - - if (email) - params.AddAscii(kEmailSwitch); - - if (showDialog) - params.AddAscii(kShowDialogSwitch); - - AddLagePagesSwitch(params); - - if (arcName.IsEmpty()) - params.AddAscii(" -an"); - - if (addExtension) - params.AddAscii(" -saa"); - else - params.AddAscii(" -sae"); - - params.AddAscii(kStopSwitchParsing); - params.Add_Space(); - - if (!arcName.IsEmpty()) - { - params += GetQuotedString( - // #ifdef UNDER_CE - arcPathPrefix + - // #endif - arcName); - } - - return Call7zGui(params, - // (arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix), - waitFinish, &event); - MY_TRY_FINISH -} - -static void ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms, bool isHash) -{ - AddLagePagesSwitch(params); - params.AddAscii(isHash ? kHashIncludeSwitches : kArcIncludeSwitches); -#ifdef _WIN32 - CFileMapping fileMapping; - NSynchronization::CManualResetEvent event; - HRESULT result = CreateMap(arcPaths, fileMapping, event, params); - if (result == S_OK) - result = Call7zGui(params, false, &event); - if (result != S_OK) - ErrorMessageHRESULT(result); -#else - HRESULT result = S_OK; - NSynchronization::CManualResetEvent event; - char tempFile[256]; - static int count = 1000; - - sprintf(tempFile,"/tmp/7zExtract_%d_%d.tmp",(int)getpid(),count++); - - FILE * file = fopen(tempFile,"w"); - if (file) - { - for (int i = 0; i < arcPaths.Size(); i++) { - fprintf(file,"%ls\n",(const wchar_t *)arcPaths[i]); - printf(" TMP_%d : '%ls'\n",i,(const wchar_t *)arcPaths[i]); - } - - fclose(file); - } - params += L"@"; - params += GetUnicodeString(tempFile); - printf("ExtractGroupCommand : -%ls-\n",(const wchar_t *)params); - if (result == S_OK) - result = Call7zGui(params, true, &event); // FIXME false => true - printf("ExtractGroupCommand : END\n"); - remove(tempFile); - if (result != S_OK) - ErrorMessageHRESULT(result); -#endif -} - -void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup) -{ - MY_TRY_BEGIN - UString params = L'x'; - if (!outFolder.IsEmpty()) - { - params.AddAscii(" -o"); - params += GetQuotedString(outFolder); - } - if (elimDup) - params.AddAscii(" -spe"); - if (showDialog) - params.AddAscii(kShowDialogSwitch); - ExtractGroupCommand(arcPaths, params, false); - MY_TRY_FINISH_VOID -} - -void TestArchives(const UStringVector &arcPaths) -{ - MY_TRY_BEGIN - UString params = L't'; - ExtractGroupCommand(arcPaths, params, false); - MY_TRY_FINISH_VOID -} - -void CalcChecksum(const UStringVector &paths, const UString &methodName) -{ - MY_TRY_BEGIN - UString params = L'h'; - if (!methodName.IsEmpty()) - { - params.AddAscii(" -scrc"); - params += methodName; - } - ExtractGroupCommand(paths, params, true); - MY_TRY_FINISH_VOID -} - -void Benchmark(bool totalMode) -{ - MY_TRY_BEGIN - HRESULT result = Call7zGui(totalMode ? L"b -mm=*" : L"b", false, NULL); - if (result != S_OK) - ErrorMessageHRESULT(result); - MY_TRY_FINISH_VOID -} +// CompressCall.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/IntToString.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/Random.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileMapping.h" +#include "../../../Windows/MemoryLock.h" +#include "../../../Windows/ProcessUtils.h" +#include "../../../Windows/Synchronization.h" + +#include "../FileManager/RegistryUtils.h" + +#include "CompressCall.h" + +using namespace NWindows; + +#define MY_TRY_BEGIN try { + +#define MY_TRY_FINISH } \ + catch(...) { ErrorMessageHRESULT(E_FAIL); return E_FAIL; } + +#define MY_TRY_FINISH_VOID } \ + catch(...) { ErrorMessageHRESULT(E_FAIL); } + +#define k7zGui "7zG.exe" + +// 21.07 : we can disable wildcard +// #define ISWITCH_NO_WILDCARD_POSTFIX "w-" +#define ISWITCH_NO_WILDCARD_POSTFIX + +#define kShowDialogSwitch " -ad" +#define kEmailSwitch " -seml." +#define kArchiveTypeSwitch " -t" +#define kIncludeSwitch " -i" ISWITCH_NO_WILDCARD_POSTFIX +#define kArcIncludeSwitches " -an -ai" ISWITCH_NO_WILDCARD_POSTFIX +#define kHashIncludeSwitches kIncludeSwitch +#define kStopSwitchParsing " --" + +extern HWND g_HWND; + +UString GetQuotedString(const UString &s) +{ + UString s2 ('\"'); + s2 += s; + s2.Add_Char('\"'); + return s2; +} + +static void ErrorMessage(LPCWSTR message) +{ + MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR | MB_OK); +} + +static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL) +{ + UString s2 = NError::MyFormatMessage(res); + if (s) + { + s2.Add_LF(); + s2 += s; + } + ErrorMessage(s2); +} + +static HRESULT Call7zGui(const UString ¶ms, + // LPCWSTR curDir, + bool waitFinish, + NSynchronization::CBaseEvent *event) +{ + UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix()); + imageName += k7zGui; + + CProcess process; + const WRes wres = process.Create(imageName, params, NULL); // curDir); + if (wres != 0) + { + const HRESULT hres = HRESULT_FROM_WIN32(wres); + ErrorMessageHRESULT(hres, imageName); + return hres; + } + if (waitFinish) + process.Wait(); + else if (event != NULL) + { + HANDLE handles[] = { process, *event }; + ::WaitForMultipleObjects(Z7_ARRAY_SIZE(handles), handles, FALSE, INFINITE); + } + return S_OK; +} + +static void AddLagePagesSwitch(UString ¶ms) +{ + if (ReadLockMemoryEnable()) + #ifndef UNDER_CE + if (NSecurity::Get_LargePages_RiskLevel() == 0) + #endif + params += " -slp"; +} + +class CRandNameGenerator +{ + CRandom _random; +public: + CRandNameGenerator() { _random.Init(); } + void GenerateName(UString &s, const char *prefix) + { + s += prefix; + s.Add_UInt32((UInt32)(unsigned)_random.Generate()); + } +}; + +static HRESULT CreateMap(const UStringVector &names, + CFileMapping &fileMapping, NSynchronization::CManualResetEvent &event, + UString ¶ms) +{ + size_t totalSize = 1; + { + FOR_VECTOR (i, names) + totalSize += (names[i].Len() + 1); + } + totalSize *= sizeof(wchar_t); + + CRandNameGenerator random; + + UString mappingName; + for (;;) + { + random.GenerateName(mappingName, "7zMap"); + const WRes wres = fileMapping.Create(PAGE_READWRITE, totalSize, GetSystemString(mappingName)); + if (fileMapping.IsCreated() && wres == 0) + break; + if (wres != ERROR_ALREADY_EXISTS) + return HRESULT_FROM_WIN32(wres); + fileMapping.Close(); + } + + UString eventName; + for (;;) + { + random.GenerateName(eventName, "7zEvent"); + const WRes wres = event.CreateWithName(false, GetSystemString(eventName)); + if (event.IsCreated() && wres == 0) + break; + if (wres != ERROR_ALREADY_EXISTS) + return HRESULT_FROM_WIN32(wres); + event.Close(); + } + + params.Add_Char('#'); + params += mappingName; + params.Add_Colon(); + char temp[32]; + ConvertUInt64ToString(totalSize, temp); + params += temp; + + params.Add_Colon(); + params += eventName; + + LPVOID data = fileMapping.Map(FILE_MAP_WRITE, 0, totalSize); + if (!data) + return E_FAIL; + CFileUnmapper unmapper(data); + { + wchar_t *cur = (wchar_t *)data; + *cur++ = 0; // it means wchar_t strings (UTF-16 in WIN32) + FOR_VECTOR (i, names) + { + const UString &s = names[i]; + const unsigned len = s.Len() + 1; + wmemcpy(cur, (const wchar_t *)s, len); + cur += len; + } + } + return S_OK; +} + +HRESULT CompressFiles( + const UString &arcPathPrefix, + const UString &arcName, + const UString &arcType, + bool addExtension, + const UStringVector &names, + bool email, bool showDialog, bool waitFinish) +{ + MY_TRY_BEGIN + UString params ('a'); + + CFileMapping fileMapping; + NSynchronization::CManualResetEvent event; + params += kIncludeSwitch; + RINOK(CreateMap(names, fileMapping, event, params)) + + if (!arcType.IsEmpty()) + { + params += kArchiveTypeSwitch; + params += arcType; + } + + if (email) + params += kEmailSwitch; + + if (showDialog) + params += kShowDialogSwitch; + + AddLagePagesSwitch(params); + + if (arcName.IsEmpty()) + params += " -an"; + + if (addExtension) + params += " -saa"; + else + params += " -sae"; + + params += kStopSwitchParsing; + params.Add_Space(); + + if (!arcName.IsEmpty()) + { + params += GetQuotedString( + // #ifdef UNDER_CE + arcPathPrefix + + // #endif + arcName); + } + + return Call7zGui(params, + // (arcPathPrefix.IsEmpty()? 0: (LPCWSTR)arcPathPrefix), + waitFinish, &event); + MY_TRY_FINISH +} + +static void ExtractGroupCommand(const UStringVector &arcPaths, UString ¶ms, bool isHash) +{ + AddLagePagesSwitch(params); + params += (isHash ? kHashIncludeSwitches : kArcIncludeSwitches); + CFileMapping fileMapping; + NSynchronization::CManualResetEvent event; + HRESULT result = CreateMap(arcPaths, fileMapping, event, params); + if (result == S_OK) + result = Call7zGui(params, false, &event); + if (result != S_OK) + ErrorMessageHRESULT(result); +} + +void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup, UInt32 writeZone) +{ + MY_TRY_BEGIN + UString params ('x'); + if (!outFolder.IsEmpty()) + { + params += " -o"; + params += GetQuotedString(outFolder); + } + if (elimDup) + params += " -spe"; + if (writeZone != (UInt32)(Int32)-1) + { + params += " -snz"; + params.Add_UInt32(writeZone); + } + if (showDialog) + params += kShowDialogSwitch; + ExtractGroupCommand(arcPaths, params, false); + MY_TRY_FINISH_VOID +} + + +void TestArchives(const UStringVector &arcPaths, bool hashMode) +{ + MY_TRY_BEGIN + UString params ('t'); + if (hashMode) + { + params += kArchiveTypeSwitch; + params += "hash"; + } + ExtractGroupCommand(arcPaths, params, false); + MY_TRY_FINISH_VOID +} + + +void CalcChecksum(const UStringVector &paths, + const UString &methodName, + const UString &arcPathPrefix, + const UString &arcFileName) +{ + MY_TRY_BEGIN + + if (!arcFileName.IsEmpty()) + { + CompressFiles( + arcPathPrefix, + arcFileName, + UString("hash"), + false, // addExtension, + paths, + false, // email, + false, // showDialog, + false // waitFinish + ); + return; + } + + UString params ('h'); + if (!methodName.IsEmpty()) + { + params += " -scrc"; + params += methodName; + /* + if (!arcFileName.IsEmpty()) + { + // not used alternate method of generating file + params += " -scrf="; + params += GetQuotedString(arcPathPrefix + arcFileName); + } + */ + } + ExtractGroupCommand(paths, params, true); + MY_TRY_FINISH_VOID +} + +void Benchmark(bool totalMode) +{ + MY_TRY_BEGIN + UString params ('b'); + if (totalMode) + params += " -mm=*"; + AddLagePagesSwitch(params); + const HRESULT result = Call7zGui(params, false, NULL); + if (result != S_OK) + ErrorMessageHRESULT(result); + MY_TRY_FINISH_VOID +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,23 +1,28 @@ -// CompressCall.h - -#ifndef __COMPRESS_CALL_H -#define __COMPRESS_CALL_H - -#include "../../../Common/MyString.h" - -UString GetQuotedString(const UString &s); - -HRESULT CompressFiles( - const UString &arcPathPrefix, - const UString &arcName, - const UString &arcType, - bool addExtension, - const UStringVector &names, - bool email, bool showDialog, bool waitFinish); - -void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog, bool elimDup); -void TestArchives(const UStringVector &arcPaths); -void CalcChecksum(const UStringVector &paths, const UString &methodName); -void Benchmark(bool totalMode); - -#endif +// CompressCall.h + +#ifndef ZIP7_INC_COMPRESS_CALL_H +#define ZIP7_INC_COMPRESS_CALL_H + +#include "../../../Common/MyString.h" + +UString GetQuotedString(const UString &s); + +HRESULT CompressFiles( + const UString &arcPathPrefix, + const UString &arcName, + const UString &arcType, + bool addExtension, + const UStringVector &names, + bool email, bool showDialog, bool waitFinish); + +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, + const UString &methodName, + const UString &arcPathPrefix, + const UString &arcFileName); + +void Benchmark(bool totalMode); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall2.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/CompressCall2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/CompressCall2.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -0,0 +1,327 @@ +// CompressCall2.cpp + +#include "StdAfx.h" + +#ifndef Z7_EXTERNAL_CODECS + +#include "../../../Common/MyException.h" + +#include "../../UI/Common/EnumDirItems.h" + +#include "../../UI/FileManager/LangUtils.h" + +#include "../../UI/GUI/BenchmarkDialog.h" +#include "../../UI/GUI/ExtractGUI.h" +#include "../../UI/GUI/UpdateGUI.h" +#include "../../UI/GUI/HashGUI.h" + +#include "../../UI/GUI/ExtractRes.h" + +#include "CompressCall.h" + +extern HWND g_HWND; + +#define MY_TRY_BEGIN HRESULT result; try { +#define MY_TRY_FINISH } \ + catch(CSystemException &e) { result = e.ErrorCode; } \ + catch(UString &s) { ErrorMessage(s); result = E_FAIL; } \ + catch(...) { result = E_FAIL; } \ + if (result != S_OK && result != E_ABORT) \ + ErrorMessageHRESULT(result); + +static void ThrowException_if_Error(HRESULT res) +{ + if (res != S_OK) + throw CSystemException(res); +} + +#ifdef Z7_EXTERNAL_CODECS + +#define CREATE_CODECS \ + CCodecs *codecs = new CCodecs; \ + CMyComPtr compressCodecsInfo = codecs; \ + ThrowException_if_Error(codecs->Load()); \ + Codecs_AddHashArcHandler(codecs); + +#define LOAD_EXTERNAL_CODECS \ + CExternalCodecs _externalCodecs; \ + _externalCodecs.GetCodecs = codecs; \ + _externalCodecs.GetHashers = codecs; \ + ThrowException_if_Error(_externalCodecs.Load()); + +#else + +#define CREATE_CODECS \ + CCodecs *codecs = new CCodecs; \ + CMyComPtr compressCodecsInfo = codecs; \ + ThrowException_if_Error(codecs->Load()); \ + Codecs_AddHashArcHandler(codecs); + +#define LOAD_EXTERNAL_CODECS + +#endif + + + + +UString GetQuotedString(const UString &s) +{ + UString s2 ('\"'); + s2 += s; + s2.Add_Char('\"'); + return s2; +} + +static void ErrorMessage(LPCWSTR message) +{ + MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR); +} + +static void ErrorMessageHRESULT(HRESULT res) +{ + ErrorMessage(HResultToMessage(res)); +} + +static void ErrorLangMessage(UINT resourceID) +{ + ErrorMessage(LangString(resourceID)); +} + +HRESULT CompressFiles( + const UString &arcPathPrefix, + const UString &arcName, + const UString &arcType, + bool addExtension, + const UStringVector &names, + bool email, bool showDialog, bool /* waitFinish */) +{ + MY_TRY_BEGIN + + CREATE_CODECS + + CUpdateCallbackGUI callback; + + callback.Init(); + + CUpdateOptions uo; + uo.EMailMode = email; + uo.SetActionCommand_Add(); + + uo.ArcNameMode = (addExtension ? k_ArcNameMode_Add : k_ArcNameMode_Exact); + + CObjectVector formatIndices; + if (!ParseOpenTypes(*codecs, arcType, formatIndices)) + { + ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); + return E_FAIL; + } + const UString arcPath = arcPathPrefix + arcName; + if (!uo.InitFormatIndex(codecs, formatIndices, arcPath) || + !uo.SetArcPath(codecs, arcPath)) + { + ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED); + return E_FAIL; + } + + NWildcard::CCensor censor; + FOR_VECTOR (i, names) + { + censor.AddPreItem_NoWildcard(names[i]); + } + + bool messageWasDisplayed = false; + + result = UpdateGUI(codecs, + formatIndices, arcPath, + censor, uo, showDialog, messageWasDisplayed, &callback, g_HWND); + + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return E_FAIL; + throw CSystemException(result); + } + if (callback.FailedFiles.Size() > 0) + { + if (!messageWasDisplayed) + throw CSystemException(E_FAIL); + return E_FAIL; + } + + MY_TRY_FINISH + return S_OK; +} + + +static HRESULT ExtractGroupCommand(const UStringVector &arcPaths, + bool showDialog, CExtractOptions &eo, const char *kType = NULL) +{ + MY_TRY_BEGIN + + CREATE_CODECS + + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + + ecs->Init(); + + // eo.CalcCrc = options.CalcCrc; + + UStringVector arcPathsSorted; + UStringVector arcFullPathsSorted; + { + NWildcard::CCensor arcCensor; + FOR_VECTOR (i, arcPaths) + { + arcCensor.AddPreItem_NoWildcard(arcPaths[i]); + } + arcCensor.AddPathsToCensor(NWildcard::k_RelatPath); + CDirItemsStat st; + EnumerateDirItemsAndSort(arcCensor, NWildcard::k_RelatPath, UString(), + arcPathsSorted, arcFullPathsSorted, + st, + NULL // &scan: change it!!!! + ); + } + + CObjectVector formatIndices; + if (kType) + { + if (!ParseOpenTypes(*codecs, UString(kType), formatIndices)) + { + throw CSystemException(E_INVALIDARG); + // ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); + // return E_INVALIDARG; + } + } + + NWildcard::CCensor censor; + { + censor.AddPreItem_Wildcard(); + } + + censor.AddPathsToCensor(NWildcard::k_RelatPath); + + bool messageWasDisplayed = false; + + ecs->MultiArcMode = (arcPathsSorted.Size() > 1); + + result = ExtractGUI(codecs, + formatIndices, CIntVector(), + arcPathsSorted, arcFullPathsSorted, + censor.Pairs.Front().Head, eo, NULL, showDialog, messageWasDisplayed, ecs, g_HWND); + + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return E_FAIL; + throw CSystemException(result); + } + return ecs->IsOK() ? S_OK : E_FAIL; + + MY_TRY_FINISH + return result; +} + +void ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, + bool showDialog, bool elimDup, UInt32 writeZone) +{ + 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) +{ + CExtractOptions eo; + eo.TestMode = true; + ExtractGroupCommand(arcPaths, + true, // showDialog + eo, + hashMode ? "hash" : NULL); +} + +void CalcChecksum(const UStringVector &paths, + const UString &methodName, + const UString &arcPathPrefix, + const UString &arcFileName) +{ + MY_TRY_BEGIN + + if (!arcFileName.IsEmpty()) + { + CompressFiles( + arcPathPrefix, + arcFileName, + UString("hash"), + false, // addExtension, + paths, + false, // email, + false, // showDialog, + false // waitFinish + ); + return; + } + + CREATE_CODECS + LOAD_EXTERNAL_CODECS + + NWildcard::CCensor censor; + FOR_VECTOR (i, paths) + { + censor.AddPreItem_NoWildcard(paths[i]); + } + + censor.AddPathsToCensor(NWildcard::k_RelatPath); + bool messageWasDisplayed = false; + + CHashOptions options; + options.Methods.Add(methodName); + + /* + if (!arcFileName.IsEmpty()) + options.HashFilePath = arcPathPrefix + arcFileName; + */ + + result = HashCalcGUI(EXTERNAL_CODECS_VARS_L censor, options, messageWasDisplayed); + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return; // E_FAIL; + throw CSystemException(result); + } + + MY_TRY_FINISH + return; // result; +} + +void Benchmark(bool totalMode) +{ + MY_TRY_BEGIN + + CREATE_CODECS + LOAD_EXTERNAL_CODECS + + CObjectVector props; + if (totalMode) + { + CProperty prop; + prop.Name = "m"; + prop.Value = "*"; + props.Add(prop); + } + result = Benchmark( + EXTERNAL_CODECS_VARS_L + props, + k_NumBenchIterations_Default, + g_HWND); + + MY_TRY_FINISH +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/DefaultName.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/DefaultName.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.cpp 2021-01-24 18:05:16.000000000 +0000 @@ -1,37 +1,37 @@ -// DefaultName.cpp - -#include "StdAfx.h" - -#include "DefaultName.h" - -static UString GetDefaultName3(const UString &fileName, - const UString &extension, const UString &addSubExtension) -{ - const unsigned extLen = extension.Len(); - const unsigned fileNameLen = fileName.Len(); - - if (fileNameLen > extLen + 1) - { - const unsigned dotPos = fileNameLen - (extLen + 1); - if (fileName[dotPos] == '.') - if (extension.IsEqualTo_NoCase(fileName.Ptr(dotPos + 1))) - return fileName.Left(dotPos) + addSubExtension; - } - - int dotPos = fileName.ReverseFind_Dot(); - if (dotPos > 0) - return fileName.Left(dotPos) + addSubExtension; - - if (addSubExtension.IsEmpty()) - return fileName + L'~'; - else - return fileName + addSubExtension; -} - -UString GetDefaultName2(const UString &fileName, - const UString &extension, const UString &addSubExtension) -{ - UString name = GetDefaultName3(fileName, extension, addSubExtension); - name.TrimRight(); - return name; -} +// DefaultName.cpp + +#include "StdAfx.h" + +#include "DefaultName.h" + +static UString GetDefaultName3(const UString &fileName, + const UString &extension, const UString &addSubExtension) +{ + const unsigned extLen = extension.Len(); + const unsigned fileNameLen = fileName.Len(); + + if (fileNameLen > extLen + 1) + { + const unsigned dotPos = fileNameLen - (extLen + 1); + if (fileName[dotPos] == '.') + if (extension.IsEqualTo_NoCase(fileName.Ptr(dotPos + 1))) + return fileName.Left(dotPos) + addSubExtension; + } + + int dotPos = fileName.ReverseFind_Dot(); + if (dotPos > 0) + return fileName.Left((unsigned)dotPos) + addSubExtension; + + if (addSubExtension.IsEmpty()) + return fileName + L'~'; + else + return fileName + addSubExtension; +} + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension) +{ + UString name = GetDefaultName3(fileName, extension, addSubExtension); + name.TrimRight(); + return name; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/DefaultName.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/DefaultName.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DefaultName.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,11 +1,11 @@ -// DefaultName.h - -#ifndef __DEFAULT_NAME_H -#define __DEFAULT_NAME_H - -#include "../../../Common/MyString.h" - -UString GetDefaultName2(const UString &fileName, - const UString &extension, const UString &addSubExtension); - -#endif +// DefaultName.h + +#ifndef ZIP7_INC_DEFAULT_NAME_H +#define ZIP7_INC_DEFAULT_NAME_H + +#include "../../../Common/MyString.h" + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/DirItem.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DirItem.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/DirItem.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/DirItem.h 2024-02-10 09:00:00.000000000 +0000 @@ -1,157 +1,407 @@ -// DirItem.h - -#ifndef __DIR_ITEM_H -#define __DIR_ITEM_H - -#include "../../../Common/MyString.h" - -#include "../../../Windows/FileFind.h" - -#include "../../Common/UniqBlocks.h" - -#include "../../Archive/IArchive.h" - -struct CDirItemsStat -{ - UInt64 NumDirs; - UInt64 NumFiles; - UInt64 NumAltStreams; - UInt64 FilesSize; - UInt64 AltStreamsSize; - - UInt64 NumErrors; - // UInt64 GetTotalItems() const { return NumDirs + NumFiles + NumAltStreams; } - - UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; } - - CDirItemsStat(): - NumDirs(0), - NumFiles(0), - NumAltStreams(0), - FilesSize(0), - AltStreamsSize(0), - NumErrors(0) - {} -}; - -#define INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT ScanError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x; \ - -struct IDirItemsCallback -{ - INTERFACE_IDirItemsCallback(=0) -}; - -struct CDirItem -{ - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UString Name; - - #if defined(_WIN32) && !defined(UNDER_CE) - // UString ShortName; - CByteBuffer ReparseData; - CByteBuffer ReparseData2; // fixed (reduced) absolute links - - bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } - #endif - - UInt32 Attrib; - 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 ; } -}; - -class CDirItems -{ - UStringVector Prefixes; - CIntVector PhyParents; - CIntVector LogParents; - - UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const; - - HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix); - -public: - CObjectVector Items; - - bool SymLinks; - - bool ScanAltStreams; - - CDirItemsStat Stat; - - #ifndef UNDER_CE - HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi, - const FString &phyPrefix); - #endif - - - #if defined(_WIN32) && !defined(UNDER_CE) - - CUniqBlocks SecureBlocks; - CByteBuffer TempSecureBuf; - bool _saclEnabled; - bool ReadSecure; - - HRESULT AddSecurityItem(const FString &path, int &secureIndex); - - #endif - - IDirItemsCallback *Callback; - - CDirItems(); - - void AddDirFileInfo(int phyParent, int logParent, int secureIndex, - const NWindows::NFile::NFind::CFileInfo &fi); - - HRESULT AddError(const FString &path, DWORD errorCode); - HRESULT AddError(const FString &path); - - HRESULT ScanProgress(const FString &path); - - // unsigned GetNumFolders() const { return Prefixes.Size(); } - FString GetPhyPath(unsigned index) const; - UString GetLogPath(unsigned index) const; - - unsigned AddPrefix(int phyParent, int logParent, const UString &prefix); - void DeleteLastPrefix(); - - HRESULT EnumerateItems2( - const FString &phyPrefix, - const UString &logPrefix, - const FStringVector &filePaths, - FStringVector *requestedPaths); - - #if defined(_WIN32) && !defined(UNDER_CE) - void FillFixedReparse(); - #endif - - void ReserveDown(); -}; - -struct CArcItem -{ - UInt64 Size; - FILETIME MTime; - UString Name; - bool IsDir; - bool IsAltStream; - bool SizeDefined; - bool MTimeDefined; - bool Censored; - UInt32 IndexInServer; - int TimeType; - - CArcItem(): IsDir(false), IsAltStream(false), SizeDefined(false), MTimeDefined(false), Censored(false), TimeType(-1) {} -}; - -#endif +// DirItem.h + +#ifndef ZIP7_INC_DIR_ITEM_H +#define ZIP7_INC_DIR_ITEM_H + +#ifdef _WIN32 +#include "../../../Common/MyLinux.h" +#endif + +#include "../../../Common/MyString.h" + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/UniqBlocks.h" + +#include "../../Archive/IArchive.h" + +struct CDirItemsStat +{ + UInt64 NumDirs; + UInt64 NumFiles; + UInt64 NumAltStreams; + UInt64 FilesSize; + UInt64 AltStreamsSize; + + UInt64 NumErrors; + + // UInt64 Get_NumItems() const { return NumDirs + NumFiles + NumAltStreams; } + UInt64 Get_NumDataItems() const { return NumFiles + NumAltStreams; } + UInt64 GetTotalBytes() const { return FilesSize + AltStreamsSize; } + + bool IsEmpty() const { return + 0 == NumDirs + && 0 == NumFiles + && 0 == NumAltStreams + && 0 == FilesSize + && 0 == AltStreamsSize + && 0 == NumErrors; } + + CDirItemsStat(): + NumDirs(0), + NumFiles(0), + NumAltStreams(0), + FilesSize(0), + AltStreamsSize(0), + NumErrors(0) + {} +}; + + +struct CDirItemsStat2: public CDirItemsStat +{ + UInt64 Anti_NumDirs; + UInt64 Anti_NumFiles; + UInt64 Anti_NumAltStreams; + + // UInt64 Get_NumItems() const { return Anti_NumDirs + Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumItems(); } + UInt64 Get_NumDataItems2() const { return Anti_NumFiles + Anti_NumAltStreams + CDirItemsStat::Get_NumDataItems(); } + + bool IsEmpty() const { return CDirItemsStat::IsEmpty() + && 0 == Anti_NumDirs + && 0 == Anti_NumFiles + && 0 == Anti_NumAltStreams; } + + CDirItemsStat2(): + Anti_NumDirs(0), + Anti_NumFiles(0), + Anti_NumAltStreams(0) + {} +}; + + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEN_IDirItemsCallback(x) \ + virtual HRESULT ScanError(const FString &path, DWORD systemError) x \ + virtual HRESULT ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) x \ + +Z7_IFACE_DECL_PURE(IDirItemsCallback) + +Z7_PURE_INTERFACES_END + + +struct CArcTime +{ + FILETIME FT; + UInt16 Prec; + Byte Ns100; + bool Def; + + CArcTime() + { + Clear(); + } + + void Clear() + { + FT.dwHighDateTime = FT.dwLowDateTime = 0; + Prec = 0; + Ns100 = 0; + Def = false; + } + + bool IsZero() const + { + return FT.dwLowDateTime == 0 && FT.dwHighDateTime == 0 && Ns100 == 0; + } + + int CompareWith(const CArcTime &a) const + { + const int res = CompareFileTime(&FT, &a.FT); + if (res != 0) + return res; + if (Ns100 < a.Ns100) return -1; + if (Ns100 > a.Ns100) return 1; + return 0; + } + + UInt64 Get_FILETIME_as_UInt64() const + { + return (((UInt64)FT.dwHighDateTime) << 32) + FT.dwLowDateTime; + } + + UInt32 Get_DosTime() const + { + FILETIME ft2 = FT; + if ((Prec == k_PropVar_TimePrec_Base + 8 || + Prec == k_PropVar_TimePrec_Base + 9) + && Ns100 != 0) + { + UInt64 u64 = Get_FILETIME_as_UInt64(); + // we round up even small (ns < 100ns) as FileTimeToDosTime() + if (u64 % 20000000 == 0) + { + u64++; + ft2.dwHighDateTime = (DWORD)(u64 >> 32); + ft2.dwHighDateTime = (DWORD)u64; + } + } + // FileTimeToDosTime() is expected to round up in Windows + UInt32 dosTime; + // we use simplified code with utctime->dos. + // do we need local time instead here? + NWindows::NTime::FileTime_To_DosTime(ft2, dosTime); + return dosTime; + } + + int GetNumDigits() const + { + if (Prec == k_PropVar_TimePrec_Unix || + Prec == k_PropVar_TimePrec_DOS) + return 0; + if (Prec == k_PropVar_TimePrec_HighPrec) + return 9; + if (Prec == k_PropVar_TimePrec_0) + return 7; + int digits = (int)Prec - (int)k_PropVar_TimePrec_Base; + if (digits < 0) + digits = 0; + return digits; + } + + void Write_To_FiTime(CFiTime &dest) const + { + #ifdef _WIN32 + dest = FT; + #else + if (FILETIME_To_timespec(FT, dest)) + if ((Prec == k_PropVar_TimePrec_Base + 8 || + Prec == k_PropVar_TimePrec_Base + 9) + && Ns100 != 0) + { + dest.tv_nsec += Ns100; + } + #endif + } + + // (Def) is not set + void Set_From_FILETIME(const FILETIME &ft) + { + FT = ft; + // Prec = k_PropVar_TimePrec_CompatNTFS; + Prec = k_PropVar_TimePrec_Base + 7; + Ns100 = 0; + } + + // (Def) is not set + // it set full form precision: k_PropVar_TimePrec_Base + numDigits + void Set_From_FiTime(const CFiTime &ts) + { + #ifdef _WIN32 + FT = ts; + Prec = k_PropVar_TimePrec_Base + 7; + // Prec = k_PropVar_TimePrec_Base; // for debug + // Prec = 0; // for debug + Ns100 = 0; + #else + unsigned ns100; + FiTime_To_FILETIME_ns100(ts, FT, ns100); + Ns100 = (Byte)ns100; + Prec = k_PropVar_TimePrec_Base + 9; + #endif + } + + void Set_From_Prop(const PROPVARIANT &prop) + { + FT = prop.filetime; + unsigned prec = 0; + unsigned ns100 = 0; + const unsigned prec_Temp = prop.wReserved1; + if (prec_Temp != 0 + && prec_Temp <= k_PropVar_TimePrec_1ns + && prop.wReserved3 == 0) + { + const unsigned ns100_Temp = prop.wReserved2; + if (ns100_Temp < 100) + { + ns100 = ns100_Temp; + prec = prec_Temp; + } + } + Prec = (UInt16)prec; + Ns100 = (Byte)ns100; + Def = true; + } +}; + + +struct CDirItem: public NWindows::NFile::NFind::CFileInfoBase +{ + UString Name; + + #ifndef UNDER_CE + CByteBuffer ReparseData; + + #ifdef _WIN32 + // UString ShortName; + CByteBuffer ReparseData2; // fixed (reduced) absolute links for WIM format + bool AreReparseData() const { return ReparseData.Size() != 0 || ReparseData2.Size() != 0; } + #else + bool AreReparseData() const { return ReparseData.Size() != 0; } + #endif // _WIN32 + + #endif // !UNDER_CE + + void Copy_From_FileInfoBase(const NWindows::NFile::NFind::CFileInfoBase &fi) + { + (NWindows::NFile::NFind::CFileInfoBase &)*this = fi; + } + + int PhyParent; + int LogParent; + int SecureIndex; + + #ifdef _WIN32 + #else + int OwnerNameIndex; + int OwnerGroupIndex; + #endif + + // bool Attrib_IsDefined; + + CDirItem(): + PhyParent(-1) + , LogParent(-1) + , SecureIndex(-1) + #ifdef _WIN32 + #else + , OwnerNameIndex(-1) + , OwnerGroupIndex(-1) + #endif + // , Attrib_IsDefined(true) + { + } + + + CDirItem(const NWindows::NFile::NFind::CFileInfo &fi, + int phyParent, int logParent, int secureIndex): + CFileInfoBase(fi) + , Name(fs2us(fi.Name)) + #if defined(_WIN32) && !defined(UNDER_CE) + // , ShortName(fs2us(fi.ShortName)) + #endif + , PhyParent(phyParent) + , LogParent(logParent) + , SecureIndex(secureIndex) + #ifdef _WIN32 + #else + , OwnerNameIndex(-1) + , OwnerGroupIndex(-1) + #endif + {} +}; + + + +class CDirItems +{ + UStringVector Prefixes; + CIntVector PhyParents; + CIntVector LogParents; + + UString GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const; + + HRESULT EnumerateDir(int phyParent, int logParent, const FString &phyPrefix); + +public: + CObjectVector Items; + + bool SymLinks; + bool ScanAltStreams; + bool ExcludeDirItems; + bool ExcludeFileItems; + bool ShareForWrite; + + /* it must be called after anotrher checks */ + bool CanIncludeItem(bool isDir) const + { + return isDir ? !ExcludeDirItems : !ExcludeFileItems; + } + + + CDirItemsStat Stat; + + #if !defined(UNDER_CE) + HRESULT SetLinkInfo(CDirItem &dirItem, const NWindows::NFile::NFind::CFileInfo &fi, + const FString &phyPrefix); + #endif + + #if defined(_WIN32) && !defined(UNDER_CE) + + CUniqBlocks SecureBlocks; + CByteBuffer TempSecureBuf; + bool _saclEnabled; + bool ReadSecure; + + HRESULT AddSecurityItem(const FString &path, int &secureIndex); + HRESULT FillFixedReparse(); + + #endif + + #ifndef _WIN32 + + C_UInt32_UString_Map OwnerNameMap; + C_UInt32_UString_Map OwnerGroupMap; + bool StoreOwnerName; + + HRESULT FillDeviceSizes(); + + #endif + + IDirItemsCallback *Callback; + + CDirItems(); + + void AddDirFileInfo(int phyParent, int logParent, int secureIndex, + const NWindows::NFile::NFind::CFileInfo &fi); + + HRESULT AddError(const FString &path, DWORD errorCode); + HRESULT AddError(const FString &path); + + HRESULT ScanProgress(const FString &path); + + // unsigned GetNumFolders() const { return Prefixes.Size(); } + FString GetPhyPath(unsigned index) const; + UString GetLogPath(unsigned index) const; + + unsigned AddPrefix(int phyParent, int logParent, const UString &prefix); + void DeleteLastPrefix(); + + // HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector &files); + HRESULT EnumerateOneDir(const FString &phyPrefix, CObjectVector &files); + + HRESULT EnumerateItems2( + const FString &phyPrefix, + const UString &logPrefix, + const FStringVector &filePaths, + FStringVector *requestedPaths); + + void ReserveDown(); +}; + + + + +struct CArcItem +{ + UInt64 Size; + 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 Size_Defined; + bool Censored; + UInt32 IndexInServer; + + CArcItem(): + IsDir(false), + IsAltStream(false), + Size_Defined(false), + Censored(false) + {} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/EnumDirItems.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/EnumDirItems.cpp 2015-09-07 19:39:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.cpp 2025-06-20 10:00:00.000000000 +0000 @@ -1,900 +1,1637 @@ -// EnumDirItems.cpp - -#include "StdAfx.h" - -#include - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileIO.h" -#include "../../../Windows/FileName.h" - -#if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE -#include "../../../Windows/SecurityUtils.h" -#endif - -#include "EnumDirItems.h" - -#define UNDER_CE 1 // FIXME - -using namespace NWindows; -using namespace NFile; -using namespace NName; - -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; - 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); - - if (fi.IsDir()) - Stat.NumDirs++; - else if (fi.IsAltStream) - { - Stat.NumAltStreams++; - Stat.AltStreamsSize += fi.Size; - } - else - { - Stat.NumFiles++; - Stat.FilesSize += fi.Size; - } -} - -HRESULT CDirItems::AddError(const FString &path, DWORD errorCode) -{ - Stat.NumErrors++; - if (Callback) - return Callback->ScanError(path, errorCode); - return S_OK; -} - -HRESULT CDirItems::AddError(const FString &path) -{ - return AddError(path, ::GetLastError()); -} - -static const unsigned kScanProgressStepMask = (1 << 12) - 1; - -HRESULT CDirItems::ScanProgress(const FString &dirPath) -{ - if (Callback) - return Callback->ScanProgress(Stat, dirPath, true); - return S_OK; -} - -UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const -{ - UString path; - unsigned len = name.Len(); - - int i; - for (i = index; i >= 0; i = parents[i]) - len += Prefixes[i].Len(); - - wchar_t *p = path.GetBuf_SetEnd(len) + len; - - p -= name.Len(); - wmemcpy(p, (const wchar_t *)name, name.Len()); - - for (i = index; i >= 0; i = parents[i]) - { - const UString &s = Prefixes[i]; - p -= s.Len(); - wmemcpy(p, (const wchar_t *)s, s.Len()); - } - - return path; -} - -FString CDirItems::GetPhyPath(unsigned index) const -{ - const CDirItem &di = Items[index]; - return us2fs(GetPrefixesPath(PhyParents, di.PhyParent, di.Name)); -} - -UString CDirItems::GetLogPath(unsigned index) const -{ - const CDirItem &di = Items[index]; - return GetPrefixesPath(LogParents, di.LogParent, di.Name); -} - -void CDirItems::ReserveDown() -{ - Prefixes.ReserveDown(); - PhyParents.ReserveDown(); - LogParents.ReserveDown(); - Items.ReserveDown(); -} - -unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix) -{ - PhyParents.Add(phyParent); - LogParents.Add(logParent); - return Prefixes.Add(prefix); -} - -void CDirItems::DeleteLastPrefix() -{ - PhyParents.DeleteBack(); - LogParents.DeleteBack(); - Prefixes.DeleteBack(); -} - -bool InitLocalPrivileges(); - -CDirItems::CDirItems(): - SymLinks(false), - ScanAltStreams(false) - #ifdef _USE_SECURITY_CODE - , ReadSecure(false) - #endif - , Callback(NULL) -{ - #ifdef _USE_SECURITY_CODE - _saclEnabled = InitLocalPrivileges(); - #endif -} - -#ifdef _USE_SECURITY_CODE - -HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) -{ - secureIndex = -1; - - SECURITY_INFORMATION securInfo = - DACL_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - OWNER_SECURITY_INFORMATION; - if (_saclEnabled) - securInfo |= SACL_SECURITY_INFORMATION; - - DWORD errorCode = 0; - DWORD secureSize; - - BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); - - if (res) - { - if (secureSize == 0) - return S_OK; - if (secureSize > TempSecureBuf.Size()) - errorCode = ERROR_INVALID_FUNCTION; - } - else - { - errorCode = GetLastError(); - if (errorCode == ERROR_INSUFFICIENT_BUFFER) - { - if (secureSize <= TempSecureBuf.Size()) - errorCode = ERROR_INVALID_FUNCTION; - else - { - TempSecureBuf.Alloc(secureSize); - res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); - if (res) - { - if (secureSize != TempSecureBuf.Size()) - errorCode = ERROR_INVALID_FUNCTION;; - } - else - errorCode = GetLastError(); - } - } - } - - if (res) - { - secureIndex = SecureBlocks.AddUniq(TempSecureBuf, secureSize); - return S_OK; - } - - if (errorCode == 0) - errorCode = ERROR_INVALID_FUNCTION; - return AddError(path, errorCode); -} - -#endif - -HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) -{ - RINOK(ScanProgress(phyPrefix)); - - NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK); - for (unsigned ttt = 0; ; ttt++) - { - NFind::CFileInfo fi; - bool found; - if (!enumerator.Next(fi, found)) - { - return AddError(phyPrefix); - } - if (!found) - return S_OK; - - int secureIndex = -1; - #ifdef _USE_SECURITY_CODE - if (ReadSecure) - { - RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)); - } - #endif - - AddDirFileInfo(phyParent, logParent, secureIndex, fi); - - if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) - { - RINOK(ScanProgress(phyPrefix)); - } - - if (fi.IsDir()) - { - const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; - unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2)); - RINOK(EnumerateDir(parent, parent, phyPrefix + name2)); - } - } -} - -HRESULT CDirItems::EnumerateItems2( - const FString &phyPrefix, - const UString &logPrefix, - const FStringVector &filePaths, - FStringVector *requestedPaths) -{ - int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix)); - int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix); - - FOR_VECTOR (i, filePaths) - { - const FString &filePath = filePaths[i]; - NFind::CFileInfo fi; - const FString phyPath = phyPrefix + filePath; - if (!fi.Find(phyPath)) - { - RINOK(AddError(phyPath)); - continue; - } - if (requestedPaths) - requestedPaths->Add(phyPath); - - int delimiter = filePath.ReverseFind_PathSepar(); - FString phyPrefixCur; - int phyParentCur = phyParent; - if (delimiter >= 0) - { - phyPrefixCur.SetFrom(filePath, delimiter + 1); - phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur)); - } - - int secureIndex = -1; - #ifdef _USE_SECURITY_CODE - if (ReadSecure) - { - RINOK(AddSecurityItem(phyPath, secureIndex)); - } - #endif - - AddDirFileInfo(phyParentCur, logParent, secureIndex, fi); - - if (fi.IsDir()) - { - const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; - unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); - RINOK(EnumerateDir(parent, parent, phyPrefix + phyPrefixCur + name2)); - } - } - - ReserveDown(); - return S_OK; -} - - - - - - -static HRESULT EnumerateDirItems( - const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, - CDirItems &dirItems, - bool enterToSubFolders); - -static HRESULT EnumerateDirItems_Spec( - const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &curFolderName, - const FString &phyPrefix, - const UStringVector &addArchivePrefix, - CDirItems &dirItems, - bool enterToSubFolders) -{ - const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR; - unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2)); - unsigned numItems = dirItems.Items.Size(); - HRESULT res = EnumerateDirItems( - curNode, parent, parent, phyPrefix + name2, - addArchivePrefix, dirItems, enterToSubFolders); - if (numItems == dirItems.Items.Size()) - dirItems.DeleteLastPrefix(); - return res; -} - -#ifndef UNDER_CE - -#ifdef _WIN32 - -static HRESULT EnumerateAltStreams( - const NFind::CFileInfo &fi, - const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &fullPath, - const UStringVector &addArchivePrefix, // prefix from curNode - CDirItems &dirItems) -{ - NFind::CStreamEnumerator enumerator(fullPath); - for (;;) - { - NFind::CStreamInfo si; - bool found; - if (!enumerator.Next(si, found)) - { - return dirItems.AddError(fullPath + FTEXT(":*")); // , (DWORD)E_FAIL - } - if (!found) - return S_OK; - if (si.IsMainStream()) - continue; - UStringVector addArchivePrefixNew = addArchivePrefix; - UString reducedName = si.GetReducedName(); - addArchivePrefixNew.Back() += reducedName; - if (curNode.CheckPathToRoot(false, addArchivePrefixNew, true)) - continue; - NFind::CFileInfo fi2 = fi; - fi2.Name += us2fs(reducedName); - fi2.Size = si.Size; - fi2.Attrib &= ~FILE_ATTRIBUTE_DIRECTORY; - fi2.IsAltStream = true; - dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2); - } -} - -#endif - -HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi, - const FString &phyPrefix) -{ - if (!SymLinks || !fi.HasReparsePoint()) - return S_OK; - const FString path = phyPrefix + fi.Name; - CByteBuffer &buf = dirItem.ReparseData; - if (NIO::GetReparseData(path, buf)) - { - CReparseAttr attr; - if (attr.Parse(buf, buf.Size())) - return S_OK; - } - DWORD res = ::GetLastError(); - buf.Free(); - return AddError(path , res); -} - -#endif - -static HRESULT EnumerateForItem( - NFind::CFileInfo &fi, - const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, // prefix from curNode - CDirItems &dirItems, - bool enterToSubFolders) -{ - const UString name = fs2us(fi.Name); - bool enterToSubFolders2 = enterToSubFolders; - UStringVector addArchivePrefixNew = addArchivePrefix; - addArchivePrefixNew.Add(name); - { - UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); - if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fi.IsDir())) - return S_OK; - } - int dirItemIndex = -1; - - if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fi.IsDir())) - { - int secureIndex = -1; - #ifdef _USE_SECURITY_CODE - if (dirItems.ReadSecure) - { - RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)); - } - #endif - - dirItemIndex = dirItems.Items.Size(); - dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); - if (fi.IsDir()) - enterToSubFolders2 = true; - } - - #ifndef UNDER_CE - if (dirItems.ScanAltStreams) - { - RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, - phyPrefix + fi.Name, - addArchivePrefixNew, dirItems)); - } - - if (dirItemIndex >= 0) - { - CDirItem &dirItem = dirItems.Items[dirItemIndex]; - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); - if (dirItem.ReparseData.Size() != 0) - return S_OK; - } - #endif - - if (!fi.IsDir()) - return S_OK; - - const NWildcard::CCensorNode *nextNode = 0; - if (addArchivePrefix.IsEmpty()) - { - int index = curNode.FindSubNode(name); - if (index >= 0) - nextNode = &curNode.SubNodes[index]; - } - if (!enterToSubFolders2 && nextNode == 0) - return S_OK; - - addArchivePrefixNew = addArchivePrefix; - if (nextNode == 0) - { - nextNode = &curNode; - addArchivePrefixNew.Add(name); - } - - return EnumerateDirItems_Spec( - *nextNode, phyParent, logParent, fi.Name, phyPrefix, - addArchivePrefixNew, - dirItems, - enterToSubFolders2); -} - - -static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode) -{ - FOR_VECTOR (i, curNode.IncludeItems) - { - const NWildcard::CItem &item = curNode.IncludeItems[i]; - if (item.Recursive || item.PathParts.Size() != 1) - return false; - const UString &name = item.PathParts.Front(); - /* - if (name.IsEmpty()) - return false; - */ - - /* Windows doesn't support file name with wildcard - But if another system supports file name with wildcard, - and wildcard mode is disabled, we can ignore wildcard in name */ - /* - if (!item.WildcardParsing) - continue; - */ - if (DoesNameContainWildcard(name)) - return false; - } - return true; -} - - -#if defined(_WIN32) && !defined(UNDER_CE) - -static bool IsVirtualFsFolder(const FString &prefix, const UString &name) -{ - UString s = fs2us(prefix); - s += name; - s.Add_PathSepar(); - return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0; -} - -#endif - -static HRESULT EnumerateDirItems( - const NWildcard::CCensorNode &curNode, - int phyParent, int logParent, const FString &phyPrefix, - const UStringVector &addArchivePrefix, // prefix from curNode - CDirItems &dirItems, - bool enterToSubFolders) -{ - if (!enterToSubFolders) - if (curNode.NeedCheckSubDirs()) - enterToSubFolders = true; - - RINOK(dirItems.ScanProgress(phyPrefix)); - - // try direct_names case at first - if (addArchivePrefix.IsEmpty() && !enterToSubFolders) - { - if (CanUseFsDirect(curNode)) - { - // all names are direct (no wildcards) - // so we don't need file_system's dir enumerator - CRecordVector needEnterVector; - unsigned i; - - for (i = 0; i < curNode.IncludeItems.Size(); i++) - { - const NWildcard::CItem &item = curNode.IncludeItems[i]; - const UString &name = item.PathParts.Front(); - FString fullPath = phyPrefix + us2fs(name); - - #if defined(_WIN32) && !defined(UNDER_CE) - bool needAltStreams = true; - #endif - - #ifdef _USE_SECURITY_CODE - bool needSecurity = true; - #endif - - if (phyPrefix.IsEmpty()) - { - if (!item.ForFile) - { - /* we don't like some names for alt streams inside archive: - ":sname" for "\" - "c:::sname" for "C:\" - So we ignore alt streams for these cases */ - if (name.IsEmpty()) - { - #if defined(_WIN32) && !defined(UNDER_CE) - needAltStreams = false; - #endif - - /* - // do we need to ignore security info for "\\" folder ? - #ifdef _USE_SECURITY_CODE - needSecurity = false; - #endif - */ - - fullPath = FCHAR_PATH_SEPARATOR; - } - #if defined(_WIN32) && !defined(UNDER_CE) - else if (item.IsDriveItem()) - { - needAltStreams = false; - fullPath.Add_PathSepar(); - } - #endif - } - } - - NFind::CFileInfo fi; - #if defined(_WIN32) && !defined(UNDER_CE) - if (IsVirtualFsFolder(phyPrefix, name)) - { - fi.SetAsDir(); - fi.Name = us2fs(name); - } - else - #endif - if (!fi.Find(fullPath,true)) - { - RINOK(dirItems.AddError(fullPath)); - continue; - } - - bool isDir = fi.IsDir(); - if (isDir && !item.ForDir || !isDir && !item.ForFile) - { - RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL)); - continue; - } - { - UStringVector pathParts; - pathParts.Add(fs2us(fi.Name)); - if (curNode.CheckPathToRoot(false, pathParts, !isDir)) - continue; - } - - int secureIndex = -1; - #ifdef _USE_SECURITY_CODE - if (needSecurity && dirItems.ReadSecure) - { - RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)); - } - #endif - - dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); - - #ifndef UNDER_CE - { - CDirItem &dirItem = dirItems.Items.Back(); - RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)); - if (dirItem.ReparseData.Size() != 0) - { - if (fi.IsAltStream) - dirItems.Stat.AltStreamsSize -= fi.Size; - else - dirItems.Stat.FilesSize -= fi.Size; - continue; - } - } - #endif - - - #ifndef UNDER_CE - if (needAltStreams && dirItems.ScanAltStreams) - { - UStringVector pathParts; - pathParts.Add(fs2us(fi.Name)); - RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, - fullPath, pathParts, dirItems)); - } - #endif - - if (!isDir) - continue; - - UStringVector addArchivePrefixNew; - const NWildcard::CCensorNode *nextNode = 0; - int index = curNode.FindSubNode(name); - if (index >= 0) - { - for (int t = needEnterVector.Size(); t <= index; t++) - needEnterVector.Add(true); - needEnterVector[index] = false; - nextNode = &curNode.SubNodes[index]; - } - else - { - nextNode = &curNode; - addArchivePrefixNew.Add(name); // don't change it to fi.Name. It's for shortnames support - } - - RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, - addArchivePrefixNew, dirItems, true)); - } - - for (i = 0; i < curNode.SubNodes.Size(); i++) - { - if (i < needEnterVector.Size()) - if (!needEnterVector[i]) - continue; - const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; - FString fullPath = phyPrefix + us2fs(nextNode.Name); - NFind::CFileInfo fi; - - if (phyPrefix.IsEmpty()) - { - { - if (nextNode.Name.IsEmpty()) - fullPath = FCHAR_PATH_SEPARATOR; - #ifdef _WIN32 - else if (NWildcard::IsDriveColonName(nextNode.Name)) - fullPath.Add_PathSepar(); - #endif - } - } - - // we don't want to call fi.Find() for root folder or virtual folder - if (phyPrefix.IsEmpty() && nextNode.Name.IsEmpty() - #if defined(_WIN32) && !defined(UNDER_CE) - || IsVirtualFsFolder(phyPrefix, nextNode.Name) - #endif - ) - { - fi.SetAsDir(); - fi.Name = us2fs(nextNode.Name); - } - else - { - if (!fi.Find(fullPath,true)) - { - if (!nextNode.AreThereIncludeItems()) - continue; - RINOK(dirItems.AddError(fullPath)); - continue; - } - - if (!fi.IsDir()) - { - RINOK(dirItems.AddError(fullPath, (DWORD)E_FAIL)); - continue; - } - } - - RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, - UStringVector(), dirItems, false)); - } - - return S_OK; - } - } - - #ifdef _WIN32 - #ifndef UNDER_CE - - // scan drives, if wildcard is "*:\" - - if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0) - { - unsigned i; - for (i = 0; i < curNode.IncludeItems.Size(); i++) - { - const NWildcard::CItem &item = curNode.IncludeItems[i]; - if (item.PathParts.Size() < 1) - break; - const UString &name = item.PathParts.Front(); - if (name.Len() != 2 || name[1] != ':') - break; - if (item.PathParts.Size() == 1) - if (item.ForFile || !item.ForDir) - break; - if (NWildcard::IsDriveColonName(name)) - continue; - if (name[0] != '*' && name[0] != '?') - break; - } - if (i == curNode.IncludeItems.Size()) - { - FStringVector driveStrings; - NFind::MyGetLogicalDriveStrings(driveStrings); - for (i = 0; i < driveStrings.Size(); i++) - { - FString driveName = driveStrings[i]; - if (driveName.Len() < 3 || driveName.Back() != '\\') - return E_FAIL; - driveName.DeleteBack(); - NFind::CFileInfo fi; - fi.SetAsDir(); - fi.Name = driveName; - - RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addArchivePrefix, dirItems, enterToSubFolders)); - } - return S_OK; - } - } - - #endif - #endif - - NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK); - for (unsigned ttt = 0; ; ttt++) - { - NFind::CFileInfo fi; - bool found; - if (!enumerator.Next(fi, found)) - { - RINOK(dirItems.AddError(phyPrefix)); - break; - } - if (!found) - break; - - if (dirItems.Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) - { - RINOK(dirItems.ScanProgress(phyPrefix)); - } - - RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, - addArchivePrefix, dirItems, enterToSubFolders)); - } - - return S_OK; -} - -HRESULT EnumerateItems( - const NWildcard::CCensor &censor, - const NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, - CDirItems &dirItems) -{ - FOR_VECTOR (i, censor.Pairs) - { - const NWildcard::CPair &pair = censor.Pairs[i]; - int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix); - int logParent = -1; - - if (pathMode == NWildcard::k_AbsPath) - logParent = phyParent; - else - { - if (!addPathPrefix.IsEmpty()) - logParent = dirItems.AddPrefix(-1, -1, addPathPrefix); - } - - RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(), - dirItems, - false // enterToSubFolders - )); - } - dirItems.ReserveDown(); - - #if defined(_WIN32) && !defined(UNDER_CE) - dirItems.FillFixedReparse(); - #endif - - return S_OK; -} - -#if defined(_WIN32) && !defined(UNDER_CE) - -void CDirItems::FillFixedReparse() -{ - /* imagex/WIM reduces absolute pathes in links (raparse data), - if we archive non root folder. We do same thing here */ - - if (!SymLinks) - return; - - FOR_VECTOR(i, Items) - { - CDirItem &item = Items[i]; - if (item.ReparseData.Size() == 0) - continue; - - CReparseAttr attr; - if (!attr.Parse(item.ReparseData, item.ReparseData.Size())) - continue; - if (attr.IsRelative()) - continue; - - const UString &link = attr.GetPath(); - if (!IsDrivePath(link)) - continue; - // maybe we need to support networks paths also ? - - FString fullPathF; - if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF)) - continue; - UString fullPath = fs2us(fullPathF); - const UString logPath = GetLogPath(i); - if (logPath.Len() >= fullPath.Len()) - continue; - if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0) - continue; - - const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len()); - if (!IsPathSepar(prefix.Back())) - continue; - - unsigned rootPrefixSize = GetRootPrefixSize(prefix); - if (rootPrefixSize == 0) - continue; - if (rootPrefixSize == prefix.Len()) - continue; // simple case: paths are from root - - if (link.Len() <= prefix.Len()) - continue; - - if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0) - continue; - - UString newLink = prefix.Left(rootPrefixSize); - newLink += link.Ptr(prefix.Len()); - - CByteBuffer data; - if (!FillLinkData(data, newLink, attr.IsSymLink())) - continue; - item.ReparseData2 = data; - } -} - -#endif +// EnumDirItems.cpp + +#include "StdAfx.h" + +#include +// #include + +#ifndef _WIN32 +#include +#include +#include "../../../Common/UTFConvert.h" +#endif + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" + +#if defined(_WIN32) && !defined(UNDER_CE) +#define Z7_USE_SECURITY_CODE +#include "../../../Windows/SecurityUtils.h" +#endif + +#include "EnumDirItems.h" +#include "SortUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + + +static bool FindFile_KeepDots(NFile::NFind::CFileInfo &fi, const FString &path, bool followLink) +{ + const bool res = fi.Find(path, followLink); + if (!res) + return res; + if (path.IsEmpty()) + return res; + // we keep name "." and "..", if it's without tail slash + const FChar *p = path.RightPtr(1); + if (*p != '.') + return res; + if (p != path.Ptr()) + { + FChar c = p[-1]; + if (!IS_PATH_SEPAR(c)) + { + if (c != '.') + return res; + p--; + if (p != path.Ptr()) + { + c = p[-1]; + if (!IS_PATH_SEPAR(c)) + return res; + } + } + } + fi.Name = p; + return res; +} + + +void CDirItems::AddDirFileInfo(int phyParent, int logParent, int secureIndex, + const NFind::CFileInfo &fi) +{ + /* + CDirItem di(fi); + di.PhyParent = phyParent; + di.LogParent = logParent; + di.SecureIndex = secureIndex; + 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++; + Stat.FilesSize += fi.Size; + } +} + +// (DWORD)E_FAIL +#define DI_DEFAULT_ERROR ERROR_INVALID_FUNCTION + +HRESULT CDirItems::AddError(const FString &path, DWORD errorCode) +{ + if (errorCode == 0) + errorCode = DI_DEFAULT_ERROR; + Stat.NumErrors++; + if (Callback) + return Callback->ScanError(path, errorCode); + return S_OK; +} + +HRESULT CDirItems::AddError(const FString &path) +{ + return AddError(path, ::GetLastError()); +} + +static const unsigned kScanProgressStepMask = (1 << 12) - 1; + +HRESULT CDirItems::ScanProgress(const FString &dirPath) +{ + if (Callback) + return Callback->ScanProgress(Stat, dirPath, true); + return S_OK; +} + +UString CDirItems::GetPrefixesPath(const CIntVector &parents, int index, const UString &name) const +{ + UString path; + unsigned len = name.Len(); + + int i; + for (i = index; i >= 0; i = parents[(unsigned)i]) + len += Prefixes[(unsigned)i].Len(); + + wchar_t *p = path.GetBuf_SetEnd(len) + len; + + p -= name.Len(); + wmemcpy(p, (const wchar_t *)name, name.Len()); + + for (i = index; i >= 0; i = parents[(unsigned)i]) + { + const UString &s = Prefixes[(unsigned)i]; + p -= s.Len(); + wmemcpy(p, (const wchar_t *)s, s.Len()); + } + + return path; +} + +FString CDirItems::GetPhyPath(unsigned index) const +{ + const CDirItem &di = Items[index]; + return us2fs(GetPrefixesPath(PhyParents, di.PhyParent, di.Name)); +} + +UString CDirItems::GetLogPath(unsigned index) const +{ + const CDirItem &di = Items[index]; + return GetPrefixesPath(LogParents, di.LogParent, di.Name); +} + +void CDirItems::ReserveDown() +{ + Prefixes.ReserveDown(); + PhyParents.ReserveDown(); + LogParents.ReserveDown(); + Items.ReserveDown(); +} + +unsigned CDirItems::AddPrefix(int phyParent, int logParent, const UString &prefix) +{ + PhyParents.Add(phyParent); + LogParents.Add(logParent); + return Prefixes.Add(prefix); +} + +void CDirItems::DeleteLastPrefix() +{ + PhyParents.DeleteBack(); + LogParents.DeleteBack(); + Prefixes.DeleteBack(); +} + +bool InitLocalPrivileges(); + +CDirItems::CDirItems(): + SymLinks(false), + ScanAltStreams(false) + , ExcludeDirItems(false) + , ExcludeFileItems(false) + , ShareForWrite(false) + #ifdef Z7_USE_SECURITY_CODE + , ReadSecure(false) + #endif + #ifndef _WIN32 + , StoreOwnerName(false) + #endif + , Callback(NULL) +{ + #ifdef Z7_USE_SECURITY_CODE + _saclEnabled = InitLocalPrivileges(); + #endif +} + + +#ifdef Z7_USE_SECURITY_CODE + +HRESULT CDirItems::AddSecurityItem(const FString &path, int &secureIndex) +{ + secureIndex = -1; + + SECURITY_INFORMATION securInfo = + DACL_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + OWNER_SECURITY_INFORMATION; + if (_saclEnabled) + securInfo |= SACL_SECURITY_INFORMATION; + + DWORD errorCode = 0; + DWORD secureSize; + + BOOL res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); + + if (res) + { + if (secureSize == 0) + return S_OK; + if (secureSize > TempSecureBuf.Size()) + errorCode = ERROR_INVALID_FUNCTION; + } + else + { + errorCode = GetLastError(); + if (errorCode == ERROR_INSUFFICIENT_BUFFER) + { + if (secureSize <= TempSecureBuf.Size()) + errorCode = ERROR_INVALID_FUNCTION; + else + { + TempSecureBuf.Alloc(secureSize); + res = ::GetFileSecurityW(fs2us(path), securInfo, (PSECURITY_DESCRIPTOR)(void *)(Byte *)TempSecureBuf, (DWORD)TempSecureBuf.Size(), &secureSize); + if (res) + { + if (secureSize != TempSecureBuf.Size()) + errorCode = ERROR_INVALID_FUNCTION; + } + else + errorCode = GetLastError(); + } + } + } + + if (res) + { + secureIndex = (int)SecureBlocks.AddUniq(TempSecureBuf, secureSize); + return S_OK; + } + + return AddError(path, errorCode); +} + +#endif // Z7_USE_SECURITY_CODE + + +HRESULT CDirItems::EnumerateOneDir(const FString &phyPrefix, CObjectVector &files) +{ + NFind::CEnumerator enumerator; + // printf("\n enumerator.SetDirPrefix(phyPrefix) \n"); + + enumerator.SetDirPrefix(phyPrefix); + + #ifdef _WIN32 + + NFind::CFileInfo fi; + + for (unsigned ttt = 0; ; ttt++) + { + bool found; + if (!enumerator.Next(fi, found)) + return AddError(phyPrefix); + if (!found) + return S_OK; + files.Add(fi); + if (Callback && (ttt & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(ScanProgress(phyPrefix)) + } + } + + #else // _WIN32 + + // enumerator.SolveLinks = !SymLinks; + + CObjectVector entries; + + for (;;) + { + bool found; + NFind::CDirEntry de; + if (!enumerator.Next(de, found)) + return AddError(phyPrefix); + if (!found) + break; + entries.Add(de); + } + + FOR_VECTOR(i, entries) + { + const NFind::CDirEntry &de = entries[i]; + NFind::CFileInfo fi; + if (!enumerator.Fill_FileInfo(de, fi, !SymLinks)) + // if (!fi.Find_AfterEnumerator(path)) + { + const FString path = phyPrefix + de.Name; + { + RINOK(AddError(path)) + continue; + } + } + + files.Add(fi); + + if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(ScanProgress(phyPrefix)) + } + } + + return S_OK; + + #endif // _WIN32 +} + + + + +HRESULT CDirItems::EnumerateDir(int phyParent, int logParent, const FString &phyPrefix) +{ + RINOK(ScanProgress(phyPrefix)) + + CObjectVector files; + RINOK(EnumerateOneDir(phyPrefix, files)) + + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + const NFind::CFileInfo &fi = files[i]; + #else + const NFind::CFileInfo &fi = files[i]; + /* + NFind::CFileInfo fi; + { + const NFind::CDirEntry &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(AddError(path)); + continue; + } + fi.Name = di.Name; + } + */ + #endif + + if (CanIncludeItem(fi.IsDir())) + { + int secureIndex = -1; + #ifdef Z7_USE_SECURITY_CODE + if (ReadSecure) + { + RINOK(AddSecurityItem(phyPrefix + fi.Name, secureIndex)) + } + #endif + AddDirFileInfo(phyParent, logParent, secureIndex, fi); + } + + if (Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(ScanProgress(phyPrefix)) + } + + if (fi.IsDir()) + { + const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; + unsigned parent = AddPrefix(phyParent, logParent, fs2us(name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + name2)) + } + } + return S_OK; +} + + +/* +EnumerateItems2() + const FStringVector &filePaths - are path without tail slashes. + All dir prefixes of filePaths will be not stores in logical paths +fix it: we can scan AltStream also. +*/ + +#ifdef _WIN32 +// #define FOLLOW_LINK_PARAM +// #define FOLLOW_LINK_PARAM2 +#define FOLLOW_LINK_PARAM , (!SymLinks) +#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) +#else +#define FOLLOW_LINK_PARAM , (!SymLinks) +#define FOLLOW_LINK_PARAM2 , (!dirItems.SymLinks) +#endif + +HRESULT CDirItems::EnumerateItems2( + const FString &phyPrefix, + const UString &logPrefix, + const FStringVector &filePaths, + FStringVector *requestedPaths) +{ + const int phyParent = phyPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, fs2us(phyPrefix)); + const int logParent = logPrefix.IsEmpty() ? -1 : (int)AddPrefix(-1, -1, logPrefix); + + #ifdef _WIN32 + const bool phyPrefix_isAltStreamPrefix = + NFile::NName::IsAltStreamPrefixWithColon(fs2us(phyPrefix)); + #endif + + FOR_VECTOR (i, filePaths) + { + const FString &filePath = filePaths[i]; + NFind::CFileInfo fi; + const FString phyPath = phyPrefix + filePath; + if (!FindFile_KeepDots(fi, phyPath FOLLOW_LINK_PARAM)) + { + RINOK(AddError(phyPath)) + continue; + } + if (requestedPaths) + requestedPaths->Add(phyPath); + + const int delimiter = filePath.ReverseFind_PathSepar(); + FString phyPrefixCur; + int phyParentCur = phyParent; + if (delimiter >= 0) + { + phyPrefixCur.SetFrom(filePath, (unsigned)(delimiter + 1)); + phyParentCur = (int)AddPrefix(phyParent, logParent, fs2us(phyPrefixCur)); + } + + if (CanIncludeItem(fi.IsDir())) + { + int secureIndex = -1; + #ifdef Z7_USE_SECURITY_CODE + if (ReadSecure) + { + RINOK(AddSecurityItem(phyPath, secureIndex)) + } + #endif + #ifdef _WIN32 + if (phyPrefix_isAltStreamPrefix && fi.IsAltStream) + { + const int pos = fi.Name.Find(FChar(':')); + if (pos >= 0) + fi.Name.DeleteFrontal((unsigned)pos + 1); + } + #endif + AddDirFileInfo(phyParentCur, logParent, secureIndex, fi); + } + + if (fi.IsDir()) + { + const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR; + const unsigned parent = AddPrefix(phyParentCur, logParent, fs2us(name2)); + RINOK(EnumerateDir((int)parent, (int)parent, phyPrefix + phyPrefixCur + name2)) + } + } + + ReserveDown(); + return S_OK; +} + + + + +static HRESULT EnumerateDirItems( + const NWildcard::CCensorNode &curNode, + const int phyParent, const int logParent, + const FString &phyPrefix, + const UStringVector &addParts, // additional parts from curNode + CDirItems &dirItems, + bool enterToSubFolders); + + +/* EnumerateDirItems_Spec() + adds new Dir item prefix, and enumerates dir items, + then it can remove that Dir item prefix, if there are no items in that dir. +*/ + + +/* + EnumerateDirItems_Spec() + it's similar to EnumerateDirItems, but phyPrefix doesn't include (curFolderName) +*/ + +static HRESULT EnumerateDirItems_Spec( + const NWildcard::CCensorNode &curNode, + const int phyParent, const int logParent, const FString &curFolderName, + const FString &phyPrefix, // without (curFolderName) + const UStringVector &addParts, // (curNode + addParts) includes (curFolderName) + CDirItems &dirItems, + bool enterToSubFolders) +{ + const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR; + const unsigned parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2)); + const unsigned numItems = dirItems.Items.Size(); + HRESULT res = EnumerateDirItems( + curNode, (int)parent, (int)parent, phyPrefix + name2, + addParts, dirItems, enterToSubFolders); + if (numItems == dirItems.Items.Size()) + dirItems.DeleteLastPrefix(); + return res; +} + + +#ifndef UNDER_CE + +#ifdef _WIN32 + +static HRESULT EnumerateAltStreams( + const NFind::CFileInfo &fi, + const NWildcard::CCensorNode &curNode, + const int phyParent, const int logParent, + const FString &phyPath, // with (fi.Name), without tail slash for folders + const UStringVector &addParts, // with (fi.Name), prefix parts from curNode + bool addAllSubStreams, + CDirItems &dirItems) +{ + // we don't use (ExcludeFileItems) rules for AltStreams + // if (dirItems.ExcludeFileItems) return S_OK; + + NFind::CStreamEnumerator enumerator(phyPath); + for (;;) + { + NFind::CStreamInfo si; + bool found; + if (!enumerator.Next(si, found)) + { + return dirItems.AddError(phyPath + FTEXT(":*")); // , (DWORD)E_FAIL + } + if (!found) + return S_OK; + if (si.IsMainStream()) + continue; + UStringVector parts = addParts; + const UString reducedName = si.GetReducedName(); + parts.Back() += reducedName; + if (curNode.CheckPathToRoot(false, parts, true)) + continue; + if (!addAllSubStreams) + if (!curNode.CheckPathToRoot(true, parts, true)) + continue; + + NFind::CFileInfo fi2 = fi; + fi2.Name += us2fs(reducedName); + fi2.Size = si.Size; + fi2.Attrib &= ~(DWORD)(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + fi2.IsAltStream = true; + dirItems.AddDirFileInfo(phyParent, logParent, -1, fi2); + } +} + +#endif // _WIN32 + + +/* We get Reparse data and parse it. + If there is Reparse error, we free dirItem.Reparse data. + Do we need to work with empty reparse data? +*/ + +HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi, + const FString &phyPrefix) +{ + if (!SymLinks) + return S_OK; + + #ifdef _WIN32 + if (!fi.HasReparsePoint() || fi.IsAltStream) + #else // _WIN32 + if (!fi.IsPosixLink()) + #endif // _WIN32 + return S_OK; + + const FString path = phyPrefix + fi.Name; + CByteBuffer &buf = dirItem.ReparseData; + if (NIO::GetReparseData(path, buf)) + { + // if (dirItem.ReparseData.Size() != 0) + Stat.FilesSize -= fi.Size; + return S_OK; + } + + DWORD res = ::GetLastError(); + buf.Free(); + return AddError(path, res); +} + +#endif // UNDER_CE + + + +static HRESULT EnumerateForItem( + const NFind::CFileInfo &fi, + const NWildcard::CCensorNode &curNode, + const int phyParent, const int logParent, const FString &phyPrefix, + const UStringVector &addParts, // additional parts from curNode, without (fi.Name) + CDirItems &dirItems, + bool enterToSubFolders) +{ + const UString name = fs2us(fi.Name); + UStringVector newParts = addParts; + newParts.Add(name); + + // check the path in exclude rules + if (curNode.CheckPathToRoot(false, newParts, !fi.IsDir())) + return S_OK; + + #if !defined(UNDER_CE) + int dirItemIndex = -1; + #if defined(_WIN32) + bool addAllSubStreams = false; + bool needAltStreams = true; + #endif // _WIN32 + #endif // !defined(UNDER_CE) + + // check the path in inlcude rules + if (curNode.CheckPathToRoot(true, newParts, !fi.IsDir())) + { + #if !defined(UNDER_CE) + // dirItemIndex = (int)dirItems.Items.Size(); + #if defined(_WIN32) + // we will not check include rules for substreams. + addAllSubStreams = true; + #endif // _WIN32 + #endif // !defined(UNDER_CE) + + if (dirItems.CanIncludeItem(fi.IsDir())) + { + int secureIndex = -1; + #ifdef Z7_USE_SECURITY_CODE + if (dirItems.ReadSecure) + { + RINOK(dirItems.AddSecurityItem(phyPrefix + fi.Name, secureIndex)) + } + #endif + #if !defined(UNDER_CE) + dirItemIndex = (int)dirItems.Items.Size(); + #endif // !defined(UNDER_CE) + dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); + } + else + { + #if defined(_WIN32) && !defined(UNDER_CE) + needAltStreams = false; + #endif + } + + if (fi.IsDir()) + enterToSubFolders = true; + } + + #if !defined(UNDER_CE) + + // we don't scan AltStreams for link files + + if (dirItemIndex >= 0) + { + CDirItem &dirItem = dirItems.Items[(unsigned)dirItemIndex]; + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) + if (dirItem.ReparseData.Size() != 0) + return S_OK; + } + + #if defined(_WIN32) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) + { + RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, + phyPrefix + fi.Name, // with (fi.Name) + newParts, // with (fi.Name) + addAllSubStreams, + dirItems)) + } + #endif + + #endif // !defined(UNDER_CE) + + + #ifndef _WIN32 + if (!fi.IsPosixLink()) // posix link can follow to dir + #endif + if (!fi.IsDir()) + return S_OK; + + const NWildcard::CCensorNode *nextNode = NULL; + + if (addParts.IsEmpty()) + { + int index = curNode.FindSubNode(name); + if (index >= 0) + { + nextNode = &curNode.SubNodes[(unsigned)index]; + newParts.Clear(); + } + } + + if (!nextNode) + { + if (!enterToSubFolders) + return S_OK; + + #ifndef _WIN32 + if (fi.IsPosixLink()) + { + // here we can try to resolve posix link + // if the link to dir, then can we follow it + return S_OK; // we don't follow posix link + } + #else + if (dirItems.SymLinks && fi.HasReparsePoint()) + { + /* 20.03: in SymLinks mode: we don't enter to directory that + has reparse point and has no CCensorNode + NOTE: (curNode and parent nodes) still can have wildcard rules + to include some items of target directory (of reparse point), + but we ignore these rules here. + */ + return S_OK; + } + #endif + nextNode = &curNode; + } + + return EnumerateDirItems_Spec( + *nextNode, phyParent, logParent, fi.Name, + phyPrefix, // without (fi.Name) + newParts, // relative to (*nextNode). (*nextNode + newParts) includes (fi.Name) + dirItems, + enterToSubFolders); +} + + +static bool CanUseFsDirect(const NWildcard::CCensorNode &curNode) +{ + FOR_VECTOR (i, curNode.IncludeItems) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + if (item.Recursive || item.PathParts.Size() != 1) + return false; + const UString &name = item.PathParts.Front(); + /* + if (name.IsEmpty()) + return false; + */ + + /* Windows doesn't support file name with wildcard + But if another system supports file name with wildcard, + and wildcard mode is disabled, we can ignore wildcard in name + */ + /* + #ifndef _WIN32 + if (!item.WildcardParsing) + continue; + #endif + */ + if (DoesNameContainWildcard(name)) + return false; + } + return true; +} + + +#if defined(_WIN32) && !defined(UNDER_CE) + +static bool IsVirtualFsFolder(const FString &prefix, const UString &name) +{ + UString s = fs2us(prefix); + s += name; + s.Add_PathSepar(); + // it returns (true) for non real FS folder path like - "\\SERVER\" + return IsPathSepar(s[0]) && GetRootPrefixSize(s) == 0; +} + +#endif + + + +static HRESULT EnumerateDirItems( + const NWildcard::CCensorNode &curNode, + const int phyParent, const int logParent, const FString &phyPrefix, + const UStringVector &addParts, // prefix from curNode including + CDirItems &dirItems, + bool enterToSubFolders) +{ + if (!enterToSubFolders) + { + /* if there are IncludeItems censor rules that affect items in subdirs, + then we will enter to all subfolders */ + if (curNode.NeedCheckSubDirs()) + enterToSubFolders = true; + } + + RINOK(dirItems.ScanProgress(phyPrefix)) + + // try direct_names case at first + if (addParts.IsEmpty() && !enterToSubFolders) + { + if (CanUseFsDirect(curNode)) + { + // all names are direct (no wildcards) + // so we don't need file_system's dir enumerator + CRecordVector needEnterVector; + unsigned i; + + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + const UString &name = item.PathParts.Front(); + FString fullPath = phyPrefix + us2fs(name); + + /* + // not possible now + if (!item.ForDir && !item.ForFile) + { + RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER)); + continue; + } + */ + + #if defined(_WIN32) && !defined(UNDER_CE) + bool needAltStreams = true; + #endif + + #ifdef Z7_USE_SECURITY_CODE + bool needSecurity = true; + #endif + + if (phyPrefix.IsEmpty()) + { + if (!item.ForFile) + { + /* we don't like some names for alt streams inside archive: + ":sname" for "\" + "c:::sname" for "C:\" + So we ignore alt streams for these cases */ + if (name.IsEmpty()) + { + #if defined(_WIN32) && !defined(UNDER_CE) + needAltStreams = false; + #endif + + /* + // do we need to ignore security info for "\\" folder ? + #ifdef Z7_USE_SECURITY_CODE + needSecurity = false; + #endif + */ + + fullPath = CHAR_PATH_SEPARATOR; + } + #if defined(_WIN32) && !defined(UNDER_CE) + else if (item.IsDriveItem()) + { + needAltStreams = false; + fullPath.Add_PathSepar(); + } + #endif + } + } + + NFind::CFileInfo fi; + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsVirtualFsFolder(phyPrefix, name)) + { + fi.SetAsDir(); + fi.Name = us2fs(name); + } + else + #endif + if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) + { + RINOK(dirItems.AddError(fullPath)) + continue; + } + + /* + #ifdef _WIN32 + #define MY_ERROR_IS_DIR ERROR_FILE_NOT_FOUND + #define MY_ERROR_NOT_DIR DI_DEFAULT_ERROR + #else + #define MY_ERROR_IS_DIR EISDIR + #define MY_ERROR_NOT_DIR ENOTDIR + #endif + */ + + const bool isDir = fi.IsDir(); + if (isDir ? !item.ForDir : !item.ForFile) + { + // RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR)); + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) + continue; + } + { + UStringVector pathParts; + pathParts.Add(fs2us(fi.Name)); + if (curNode.CheckPathToRoot(false, pathParts, !isDir)) + continue; + } + + + if (dirItems.CanIncludeItem(fi.IsDir())) + { + int secureIndex = -1; + #ifdef Z7_USE_SECURITY_CODE + if (needSecurity && dirItems.ReadSecure) + { + RINOK(dirItems.AddSecurityItem(fullPath, secureIndex)) + } + #endif + + dirItems.AddDirFileInfo(phyParent, logParent, secureIndex, fi); + + // we don't scan AltStreams for link files + + #if !defined(UNDER_CE) + { + CDirItem &dirItem = dirItems.Items.Back(); + RINOK(dirItems.SetLinkInfo(dirItem, fi, phyPrefix)) + if (dirItem.ReparseData.Size() != 0) + continue; + } + + #if defined(_WIN32) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) + { + UStringVector pathParts; + pathParts.Add(fs2us(fi.Name)); + RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, + fullPath, // including (name) + pathParts, // including (fi.Name) + true, /* addAllSubStreams */ + dirItems)) + } + #endif // defined(_WIN32) + + #endif // !defined(UNDER_CE) + } + + + #ifndef _WIN32 + if (!fi.IsPosixLink()) // posix link can follow to dir + #endif + if (!isDir) + continue; + + UStringVector newParts; + const NWildcard::CCensorNode *nextNode = NULL; + int index = curNode.FindSubNode(name); + if (index >= 0) + { + for (int t = (int)needEnterVector.Size(); t <= index; t++) + needEnterVector.Add(true); + needEnterVector[(unsigned)index] = false; + nextNode = &curNode.SubNodes[(unsigned)index]; + } + else + { + #ifndef _WIN32 + if (fi.IsPosixLink()) + { + // here we can try to resolve posix link + // if the link to dir, then can we follow it + continue; // we don't follow posix link + } + #else + if (dirItems.SymLinks) + { + if (fi.HasReparsePoint()) + { + /* 20.03: in SymLinks mode: we don't enter to directory that + has reparse point and has no CCensorNode */ + continue; + } + } + #endif + nextNode = &curNode; + newParts.Add(name); // don't change it to fi.Name. It's for shortnames support + } + + RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix, + newParts, dirItems, true)) + } + + for (i = 0; i < curNode.SubNodes.Size(); i++) + { + if (i < needEnterVector.Size()) + if (!needEnterVector[i]) + continue; + const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; + FString fullPath = phyPrefix + us2fs(nextNode.Name); + NFind::CFileInfo fi; + + if (nextNode.Name.IsEmpty()) + { + if (phyPrefix.IsEmpty()) + fullPath = CHAR_PATH_SEPARATOR; + } + #ifdef _WIN32 + else if(phyPrefix.IsEmpty() + || (phyPrefix.Len() == NName::kSuperPathPrefixSize + && IsSuperPath(phyPrefix))) + { + if (NWildcard::IsDriveColonName(nextNode.Name)) + fullPath.Add_PathSepar(); + } + #endif + + // we don't want to call fi.Find() for root folder or virtual folder + if ((phyPrefix.IsEmpty() && nextNode.Name.IsEmpty()) + #if defined(_WIN32) && !defined(UNDER_CE) + || IsVirtualFsFolder(phyPrefix, nextNode.Name) + #endif + ) + { + fi.SetAsDir(); + fi.Name = us2fs(nextNode.Name); + } + else + { + if (!FindFile_KeepDots(fi, fullPath FOLLOW_LINK_PARAM2)) + { + if (!nextNode.AreThereIncludeItems()) + continue; + RINOK(dirItems.AddError(fullPath)) + continue; + } + + if (!fi.IsDir()) + { + RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR)) + continue; + } + } + + RINOK(EnumerateDirItems_Spec(nextNode, phyParent, logParent, fi.Name, phyPrefix, + UStringVector(), dirItems, false)) + } + + return S_OK; + } + } + + #ifdef _WIN32 + #ifndef UNDER_CE + + // scan drives, if wildcard is "*:\" + + if (phyPrefix.IsEmpty() && curNode.IncludeItems.Size() > 0) + { + unsigned i; + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + if (item.PathParts.Size() < 1) + break; + const UString &name = item.PathParts.Front(); + if (name.Len() != 2 || name[1] != ':') + break; + if (item.PathParts.Size() == 1) + if (item.ForFile || !item.ForDir) + break; + if (NWildcard::IsDriveColonName(name)) + continue; + if (name[0] != '*' && name[0] != '?') + break; + } + if (i == curNode.IncludeItems.Size()) + { + FStringVector driveStrings; + NFind::MyGetLogicalDriveStrings(driveStrings); + for (i = 0; i < driveStrings.Size(); i++) + { + FString driveName = driveStrings[i]; + if (driveName.Len() < 3 || driveName.Back() != '\\') + return E_FAIL; + driveName.DeleteBack(); + NFind::CFileInfo fi; + fi.SetAsDir(); + fi.Name = driveName; + + RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, + addParts, dirItems, enterToSubFolders)) + } + return S_OK; + } + } + + #endif + #endif + + + CObjectVector files; + + // for (int y = 0; y < 1; y++) + { + // files.Clear(); + RINOK(dirItems.EnumerateOneDir(phyPrefix, files)) + /* + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + // const NFind::CFileInfo &fi = files[i]; + #else + NFind::CFileInfo &fi = files[i]; + { + const NFind::CFileInfo &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(dirItems.AddError(path)); + continue; + } + fi.Name = di.Name; + } + #endif + + } + */ + } + + FOR_VECTOR (i, files) + { + #ifdef _WIN32 + const NFind::CFileInfo &fi = files[i]; + #else + const NFind::CFileInfo &fi = files[i]; + /* + NFind::CFileInfo fi; + { + const NFind::CDirEntry &di = files[i]; + const FString path = phyPrefix + di.Name; + if (!fi.Find_AfterEnumerator(path)) + { + RINOK(dirItems.AddError(path)); + continue; + } + fi.Name = di.Name; + } + */ + #endif + + RINOK(EnumerateForItem(fi, curNode, phyParent, logParent, phyPrefix, + addParts, dirItems, enterToSubFolders)) + if (dirItems.Callback && (i & kScanProgressStepMask) == kScanProgressStepMask) + { + RINOK(dirItems.ScanProgress(phyPrefix)) + } + } + + return S_OK; +} + + + + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + const NWildcard::ECensorPathMode pathMode, + const UString &addPathPrefix, // prefix that will be added to Logical Path + CDirItems &dirItems) +{ + FOR_VECTOR (i, censor.Pairs) + { + const NWildcard::CPair &pair = censor.Pairs[i]; + const int phyParent = pair.Prefix.IsEmpty() ? -1 : (int)dirItems.AddPrefix(-1, -1, pair.Prefix); + int logParent = -1; + + if (pathMode == NWildcard::k_AbsPath) + logParent = phyParent; + else + { + if (!addPathPrefix.IsEmpty()) + logParent = (int)dirItems.AddPrefix(-1, -1, addPathPrefix); + } + + RINOK(EnumerateDirItems(pair.Head, phyParent, logParent, us2fs(pair.Prefix), UStringVector(), + dirItems, + false // enterToSubFolders + )) + } + dirItems.ReserveDown(); + + #if defined(_WIN32) && !defined(UNDER_CE) + RINOK(dirItems.FillFixedReparse()) + #endif + + #ifndef _WIN32 + RINOK(dirItems.FillDeviceSizes()) + #endif + + return S_OK; +} + + +#if defined(_WIN32) && !defined(UNDER_CE) + +HRESULT CDirItems::FillFixedReparse() +{ + FOR_VECTOR(i, Items) + { + CDirItem &item = Items[i]; + + if (!SymLinks) + { + // continue; // for debug + if (!item.Has_Attrib_ReparsePoint()) + continue; + /* + We want to get properties of target file instead of properies of symbolic link. + Probably this code is unused, because + CFileInfo::Find(with followLink = true) called Fill_From_ByHandleFileInfo() already. + */ + // if (item.IsDir()) continue; + const FString phyPath = GetPhyPath(i); + NFind::CFileInfo fi; + if (fi.Fill_From_ByHandleFileInfo(phyPath)) // item.IsDir() + { + item.Size = fi.Size; + item.CTime = fi.CTime; + item.ATime = fi.ATime; + item.MTime = fi.MTime; + item.Attrib = fi.Attrib; + continue; + } + RINOK(AddError(phyPath)) + continue; + } + + // (SymLinks == true) + if (item.ReparseData.Size() == 0) + continue; + // if (item.Size == 0) + { + // 20.03: we use Reparse Data instead of real data + item.Size = item.ReparseData.Size(); + } + + CReparseAttr attr; + if (!attr.Parse(item.ReparseData, item.ReparseData.Size())) + { + const FString phyPath = GetPhyPath(i); + AddError(phyPath, attr.ErrorCode); + continue; + } + + /* imagex/WIM reduces absolute paths in links (raparse data), + if we archive non root folder. We do same thing here */ + + // bool isWSL = false; + if (attr.IsSymLink_WSL()) + { + // isWSL = true; + // we don't change WSL symlinks + continue; + } + else + { + if (attr.IsRelative_Win()) + continue; + } + + const UString &link = attr.GetPath(); + if (!IsDrivePath(link)) + continue; + // maybe we need to support networks paths also ? + + FString fullPathF; + if (!NDir::MyGetFullPathName(GetPhyPath(i), fullPathF)) + continue; + const UString fullPath = fs2us(fullPathF); + const UString logPath = GetLogPath(i); + if (logPath.Len() >= fullPath.Len()) + continue; + if (CompareFileNames(logPath, fullPath.RightPtr(logPath.Len())) != 0) + continue; + + const UString prefix = fullPath.Left(fullPath.Len() - logPath.Len()); + if (!IsPathSepar(prefix.Back())) + continue; + + const unsigned rootPrefixSize = GetRootPrefixSize(prefix); + if (rootPrefixSize == 0) + continue; + if (rootPrefixSize == prefix.Len()) + continue; // simple case: paths are from root + if (link.Len() <= prefix.Len()) + continue; + if (CompareFileNames(link.Left(prefix.Len()), prefix) != 0) + continue; + + UString newLink = prefix.Left(rootPrefixSize); + newLink += link.Ptr(prefix.Len()); + + CByteBuffer &data = item.ReparseData2; +/* + if (isWSL) + { + Convert_WinPath_to_WslLinuxPath(newLink, true); // is absolute : change it + FillLinkData_WslLink(data, newLink); + } + else +*/ + FillLinkData_WinLink(data, newLink, !attr.IsMountPoint()); + if (data.Size() == 0) + continue; + // item.ReparseData2 = data; + } + return S_OK; +} + +#endif + + +#ifndef _WIN32 + +HRESULT CDirItems::FillDeviceSizes() +{ + { + FOR_VECTOR (i, Items) + { + CDirItem &item = Items[i]; + + if (S_ISBLK(item.mode) && item.Size == 0) + { + const FString phyPath = GetPhyPath(i); + NIO::CInFile inFile; + inFile.PreserveATime = true; + if (inFile.OpenShared(phyPath, ShareForWrite)) // fixme: OpenShared ?? + { + UInt64 size = 0; + if (inFile.GetLength(size)) + item.Size = size; + } + } + if (StoreOwnerName) + { + OwnerNameMap.Add_UInt32(item.uid); + OwnerGroupMap.Add_UInt32(item.gid); + } + } + } + + if (StoreOwnerName) + { + UString u; + AString a; + { + FOR_VECTOR (i, OwnerNameMap.Numbers) + { + // 200K/sec speed + u.Empty(); + const passwd *pw = getpwuid(OwnerNameMap.Numbers[i]); + // printf("\ngetpwuid=%s\n", pw->pw_name); + if (pw) + { + a = pw->pw_name; + ConvertUTF8ToUnicode(a, u); + } + OwnerNameMap.Strings.Add(u); + } + } + { + FOR_VECTOR (i, OwnerGroupMap.Numbers) + { + u.Empty(); + const group *gr = getgrgid(OwnerGroupMap.Numbers[i]); + if (gr) + { + // printf("\ngetgrgid %d %s\n", OwnerGroupMap.Numbers[i], gr->gr_name); + a = gr->gr_name; + ConvertUTF8ToUnicode(a, u); + } + OwnerGroupMap.Strings.Add(u); + } + } + + FOR_VECTOR (i, Items) + { + CDirItem &item = Items[i]; + { + const int index = OwnerNameMap.Find(item.uid); + if (index < 0) throw 1; + item.OwnerNameIndex = index; + } + { + const int index = OwnerGroupMap.Find(item.gid); + if (index < 0) throw 1; + item.OwnerGroupIndex = index; + } + } + } + + + // if (NeedOwnerNames) + { + /* + { + for (unsigned i = 0 ; i < 10000; i++) + { + const passwd *pw = getpwuid(i); + if (pw) + { + UString u; + ConvertUTF8ToUnicode(AString(pw->pw_name), u); + OwnerNameMap.Add(i, u); + OwnerNameMap.Add(i, u); + OwnerNameMap.Add(i, u); + } + const group *gr = getgrgid(i); + if (gr) + { + // we can use utf-8 here. + UString u; + ConvertUTF8ToUnicode(AString(gr->gr_name), u); + OwnerGroupMap.Add(i, u); + } + } + } + */ + /* + { + FOR_VECTOR (i, OwnerNameMap.Strings) + { + AString s; + ConvertUnicodeToUTF8(OwnerNameMap.Strings[i], s); + printf("\n%5d %s", (unsigned)OwnerNameMap.Numbers[i], s.Ptr()); + } + } + { + printf("\n\n=========Groups\n"); + FOR_VECTOR (i, OwnerGroupMap.Strings) + { + AString s; + ConvertUnicodeToUTF8(OwnerGroupMap.Strings[i], s); + printf("\n%5d %s", (unsigned)OwnerGroupMap.Numbers[i], s.Ptr()); + } + } + */ + } + /* + for (unsigned i = 0 ; i < 100000000; i++) + { + // const passwd *pw = getpwuid(1000); + // pw = pw; + int pos = OwnerNameMap.Find(1000); + if (pos < 0 - (int)i) + throw 1; + } + */ + + return S_OK; +} + +#endif + + + +static const char * const kCannotFindArchive = "Cannot find archive"; + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode censorPathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback) +{ + FStringVector paths; + + { + CDirItems dirItems; + dirItems.Callback = callback; + { + HRESULT res = EnumerateItems(censor, censorPathMode, addPathPrefix, dirItems); + st = dirItems.Stat; + RINOK(res) + } + + FOR_VECTOR (i, dirItems.Items) + { + const CDirItem &dirItem = dirItems.Items[i]; + if (!dirItem.IsDir()) + paths.Add(dirItems.GetPhyPath(i)); + } + } + + if (paths.Size() == 0) + { + // return S_OK; + throw CMessagePathException(kCannotFindArchive); + } + + UStringVector fullPaths; + + unsigned i; + + for (i = 0; i < paths.Size(); i++) + { + FString fullPath; + NFile::NDir::MyGetFullPathName(paths[i], fullPath); + fullPaths.Add(fs2us(fullPath)); + } + + CUIntVector indices; + SortFileNames(fullPaths, indices); + sortedPaths.ClearAndReserve(indices.Size()); + sortedFullPaths.ClearAndReserve(indices.Size()); + + for (i = 0; i < indices.Size(); i++) + { + unsigned index = indices[i]; + sortedPaths.AddInReserved(fs2us(paths[index])); + sortedFullPaths.AddInReserved(fullPaths[index]); + if (i > 0 && CompareFileNames(sortedFullPaths[i], sortedFullPaths[i - 1]) == 0) + throw CMessagePathException("Duplicate archive path:", sortedFullPaths[i]); + } + + return S_OK; +} + + + + +#ifdef _WIN32 + +static bool IsDotsName(const wchar_t *s) +{ + return s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)); +} + +// This code converts all short file names to long file names. + +static void ConvertToLongName(const UString &prefix, UString &name) +{ + if (name.IsEmpty() + || DoesNameContainWildcard(name) + || IsDotsName(name)) + return; + NFind::CFileInfo fi; + const FString path (us2fs(prefix + name)); + #ifndef UNDER_CE + if (NFile::NName::IsDevicePath(path)) + return; + #endif + if (fi.Find(path)) + name = fs2us(fi.Name); +} + +static void ConvertToLongNames(const UString &prefix, CObjectVector &items) +{ + FOR_VECTOR (i, items) + { + NWildcard::CItem &item = items[i]; + if (item.Recursive || item.PathParts.Size() != 1) + continue; + if (prefix.IsEmpty() && item.IsDriveItem()) + continue; + ConvertToLongName(prefix, item.PathParts.Front()); + } +} + +static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) +{ + ConvertToLongNames(prefix, node.IncludeItems); + ConvertToLongNames(prefix, node.ExcludeItems); + unsigned i; + for (i = 0; i < node.SubNodes.Size(); i++) + { + UString &name = node.SubNodes[i].Name; + if (prefix.IsEmpty() && NWildcard::IsDriveColonName(name)) + continue; + ConvertToLongName(prefix, name); + } + // mix folders with same name + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; + for (unsigned j = i + 1; j < node.SubNodes.Size();) + { + const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; + if (nextNode1.Name.IsEqualTo_NoCase(nextNode2.Name)) + { + nextNode1.IncludeItems += nextNode2.IncludeItems; + nextNode1.ExcludeItems += nextNode2.ExcludeItems; + node.SubNodes.Delete(j); + } + else + j++; + } + } + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode = node.SubNodes[i]; + ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode); + } +} + +void ConvertToLongNames(NWildcard::CCensor &censor) +{ + FOR_VECTOR (i, censor.Pairs) + { + NWildcard::CPair &pair = censor.Pairs[i]; + ConvertToLongNames(pair.Prefix, pair.Head); + } +} + +#endif + + +CMessagePathException::CMessagePathException(const char *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} + +CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/EnumDirItems.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/EnumDirItems.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/EnumDirItems.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,21 +1,38 @@ -// EnumDirItems.h - -#ifndef __ENUM_DIR_ITEMS_H -#define __ENUM_DIR_ITEMS_H - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileFind.h" - -#include "DirItem.h" - -void AddDirFileInfo(int phyParent, int logParent, int secureIndex, - const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector &dirItems); - -HRESULT EnumerateItems( - const NWildcard::CCensor &censor, - NWildcard::ECensorPathMode pathMode, - const UString &addPathPrefix, - CDirItems &dirItems); - -#endif +// EnumDirItems.h + +#ifndef ZIP7_INC_ENUM_DIR_ITEMS_H +#define ZIP7_INC_ENUM_DIR_ITEMS_H + +#include "../../../Common/Wildcard.h" + +#include "DirItem.h" + + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + NWildcard::ECensorPathMode pathMode, + const UString &addPathPrefix, + CDirItems &dirItems); + + +struct CMessagePathException: public UString +{ + CMessagePathException(const char *a, const wchar_t *u = NULL); + CMessagePathException(const wchar_t *a, const wchar_t *u = NULL); +}; + + +HRESULT EnumerateDirItemsAndSort( + NWildcard::CCensor &censor, + NWildcard::ECensorPathMode pathMode, + const UString &addPathPrefix, + UStringVector &sortedPaths, + UStringVector &sortedFullPaths, + CDirItemsStat &st, + IDirItemsCallback *callback); + +#ifdef _WIN32 +void ConvertToLongNames(NWildcard::CCensor &censor); +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ExitCode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExitCode.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ExitCode.h 2008-08-14 09:11:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExitCode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,27 +1,27 @@ -// ExitCode.h - -#ifndef __EXIT_CODE_H -#define __EXIT_CODE_H - -namespace NExitCode { - -enum EEnum { - - kSuccess = 0, // Successful operation - kWarning = 1, // Non fatal error(s) occurred - kFatalError = 2, // A fatal error occurred - // kCRCError = 3, // A CRC error occurred when unpacking - // kLockedArchive = 4, // Attempt to modify an archive previously locked - // kWriteError = 5, // Write to disk error - // kOpenError = 6, // Open file error - kUserError = 7, // Command line option error - kMemoryError = 8, // Not enough memory for operation - // kCreateFileError = 9, // Create file error - - kUserBreak = 255 // User stopped the process - -}; - -} - -#endif +// ExitCode.h + +#ifndef ZIP7_INC_EXIT_CODE_H +#define ZIP7_INC_EXIT_CODE_H + +namespace NExitCode { + +enum EEnum { + + kSuccess = 0, // Successful operation + kWarning = 1, // Non fatal error(s) occurred + kFatalError = 2, // A fatal error occurred + // kCRCError = 3, // A CRC error occurred when unpacking + // kLockedArchive = 4, // Attempt to modify an archive previously locked + // kWriteError = 5, // Write to disk error + // kOpenError = 6, // Open file error + kUserError = 7, // Command line option error + kMemoryError = 8, // Not enough memory for operation + // kCreateFileError = 9, // Create file error + + kUserBreak = 255 // User stopped the process + +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Extract.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/Extract.cpp 2016-05-20 08:44:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -1,477 +1,575 @@ -// Extract.cpp - -#include "StdAfx.h" - -#include "../../../../C/Sort.h" - -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../Common/ExtractingFilePath.h" - -#include "Extract.h" -#include "SetProperties.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static HRESULT DecompressArchive( - CCodecs *codecs, - const CArchiveLink &arcLink, - UInt64 packSize, - const NWildcard::CCensorNode &wildcardCensor, - const CExtractOptions &options, - bool calcCrc, - IExtractCallbackUI *callback, - CArchiveExtractCallback *ecs, - UString &errorMessage, - UInt64 &stdInProcessed) -{ - const CArc &arc = arcLink.Arcs.Back(); - stdInProcessed = 0; - IInArchive *archive = arc.Archive; - CRecordVector realIndices; - - UStringVector removePathParts; - - FString outDir = options.OutputDir; - UString replaceName = arc.DefaultName; - - if (arcLink.Arcs.Size() > 1) - { - // Most "pe" archives have same name of archive subfile "[0]" or ".rsrc_1". - // So it extracts different archives to one folder. - // We will use top level archive name - const CArc &arc0 = arcLink.Arcs[0]; - if (StringsAreEqualNoCase_Ascii(codecs->Formats[arc0.FormatIndex].Name, "pe")) - replaceName = arc0.DefaultName; - } - - outDir.Replace(FSTRING_ANY_MASK, us2fs(Get_Correct_FsFile_Name(replaceName))); - - bool elimIsPossible = false; - UString elimPrefix; // only pure name without dir delimiter - FString outDirReduced = outDir; - - if (options.ElimDup.Val && options.PathMode != NExtract::NPathMode::kAbsPaths) - { - UString dirPrefix; - SplitPathToParts_Smart(fs2us(outDir), dirPrefix, elimPrefix); - if (!elimPrefix.IsEmpty()) - { - if (IsPathSepar(elimPrefix.Back())) - elimPrefix.DeleteBack(); - if (!elimPrefix.IsEmpty()) - { - outDirReduced = us2fs(dirPrefix); - elimIsPossible = true; - } - } - } - - bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); - - if (!options.StdInMode) - { - UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - - CReadArcItem item; - - for (UInt32 i = 0; i < numItems; i++) - { - if (elimIsPossible || !allFilesAreAllowed) - { - RINOK(arc.GetItem(i, item)); - } - else - { - #ifdef SUPPORT_ALT_STREAMS - item.IsAltStream = false; - if (!options.NtOptions.AltStreams.Val && arc.Ask_AltStream) - { - RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)); - } - #endif - } - - #ifdef SUPPORT_ALT_STREAMS - if (!options.NtOptions.AltStreams.Val && item.IsAltStream) - continue; - #endif - - if (elimIsPossible) - { - const UString &s = - #ifdef SUPPORT_ALT_STREAMS - item.MainPath; - #else - item.Path; - #endif - if (!IsPath1PrefixedByPath2(s, elimPrefix)) - elimIsPossible = false; - else - { - wchar_t c = s[elimPrefix.Len()]; - if (c == 0) - { - if (!item.MainIsDir) - elimIsPossible = false; - } - else if (!IsPathSepar(c)) - elimIsPossible = false; - } - } - - if (!allFilesAreAllowed) - { - if (!CensorNode_CheckPath(wildcardCensor, item)) - continue; - } - - realIndices.Add(i); - } - - if (realIndices.Size() == 0) - { - callback->ThereAreNoFiles(); - return callback->ExtractResult(S_OK); - } - } - - if (elimIsPossible) - { - removePathParts.Add(elimPrefix); - // outDir = outDirReduced; - } - - #ifdef _WIN32 - // GetCorrectFullFsPath doesn't like "..". - // outDir.TrimRight(); - // outDir = GetCorrectFullFsPath(outDir); - #endif - - if (outDir.IsEmpty()) - outDir = FTEXT(".") FSTRING_PATH_SEPARATOR; - /* - #ifdef _WIN32 - else if (NName::IsAltPathPrefix(outDir)) {} - #endif - */ - else if (!CreateComplexDir(outDir)) - { - HRESULT res = ::GetLastError(); - if (res == S_OK) - res = E_FAIL; - errorMessage.SetFromAscii("Can not create output directory: "); - errorMessage += fs2us(outDir); - return res; - } - - ecs->Init( - options.NtOptions, - options.StdInMode ? &wildcardCensor : NULL, - &arc, - callback, - options.StdOutMode, options.TestMode, - outDir, - removePathParts, false, - packSize); - - - #ifdef SUPPORT_LINKS - - if (!options.StdInMode && - !options.TestMode && - options.NtOptions.HardLinks.Val) - { - RINOK(ecs->PrepareHardLinks(&realIndices)); - } - - #endif - - - HRESULT result; - Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; - if (options.StdInMode) - { - result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs); - NCOM::CPropVariant prop; - if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK) - ConvertPropVariantToUInt64(prop, stdInProcessed); - } - else - result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs); - if (result == S_OK && !options.StdInMode) - result = ecs->SetDirsTimes(); - return callback->ExtractResult(result); -} - -/* v9.31: BUG was fixed: - 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) -{ - unsigned left = 0, right = fileName.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - const UString &midValue = fileName[mid]; - int compare = CompareFileNames(name, midValue); - if (compare == 0) - return mid; - if (compare < 0) - right = mid; - else - left = mid + 1; - } - return -1; -} - -HRESULT Extract( - CCodecs *codecs, - const CObjectVector &types, - const CIntVector &excludedFormats, - UStringVector &arcPaths, UStringVector &arcPathsFull, - const NWildcard::CCensorNode &wildcardCensor, - const CExtractOptions &options, - IOpenCallbackUI *openCallback, - IExtractCallbackUI *extractCallback, - #ifndef _SFX - IHashCalc *hash, - #endif - UString &errorMessage, - CDecompressStat &st) -{ - st.Clear(); - UInt64 totalPackSize = 0; - CRecordVector arcSizes; - - unsigned numArcs = options.StdInMode ? 1 : arcPaths.Size(); - - unsigned i; - - for (i = 0; i < numArcs; i++) - { - NFind::CFileInfo fi; - fi.Size = 0; - if (!options.StdInMode) - { - const FString &arcPath = us2fs(arcPaths[i]); - if (!fi.Find(arcPath,true)) - throw "there is no such archive"; - if (fi.IsDir()) - throw "can't decompress folder"; - } - arcSizes.Add(fi.Size); - totalPackSize += fi.Size; - } - - CBoolArr skipArcs(numArcs); - for (i = 0; i < numArcs; i++) - skipArcs[i] = false; - - CArchiveExtractCallback *ecs = new CArchiveExtractCallback; - CMyComPtr ec(ecs); - bool multi = (numArcs > 1); - ecs->InitForMulti(multi, options.PathMode, options.OverwriteMode); - #ifndef _SFX - ecs->SetHashMethods(hash); - #endif - - if (multi) - { - RINOK(extractCallback->SetTotal(totalPackSize)); - } - - UInt64 totalPackProcessed = 0; - bool thereAreNotOpenArcs = false; - - for (i = 0; i < numArcs; i++) - { - if (skipArcs[i]) - continue; - - const UString &arcPath = arcPaths[i]; - NFind::CFileInfo fi; - if (options.StdInMode) - { - fi.Size = 0; - fi.Attrib = 0; - } - else - { - if (!fi.Find(us2fs(arcPath),true) || fi.IsDir()) - throw "there is no such archive"; - } - - /* - #ifndef _NO_CRYPTO - openCallback->Open_Clear_PasswordWasAsked_Flag(); - #endif - */ - - RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)); - CArchiveLink arcLink; - - CObjectVector types2 = types; - /* - #ifndef _SFX - if (types.IsEmpty()) - { - int pos = arcPath.ReverseFind(L'.'); - if (pos >= 0) - { - UString s = arcPath.Ptr(pos + 1); - int index = codecs->FindFormatForExtension(s); - if (index >= 0 && s == L"001") - { - s = arcPath.Left(pos); - pos = s.ReverseFind(L'.'); - if (pos >= 0) - { - int index2 = codecs->FindFormatForExtension(s.Ptr(pos + 1)); - if (index2 >= 0) // && s.CompareNoCase(L"rar") != 0 - { - types2.Add(index2); - types2.Add(index); - } - } - } - } - } - #endif - */ - - COpenOptions op; - #ifndef _SFX - op.props = &options.Properties; - #endif - op.codecs = codecs; - op.types = &types2; - op.excludedFormats = &excludedFormats; - op.stdInMode = options.StdInMode; - op.stream = NULL; - op.filePath = arcPath; - - HRESULT result = arcLink.Open3(op, openCallback); - - if (result == E_ABORT) - return result; - - if (result == S_OK && arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - result = S_FALSE; - - // arcLink.Set_ErrorsText(); - RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)); - - if (result != S_OK) - { - thereAreNotOpenArcs = true; - if (!options.StdInMode) - { - NFind::CFileInfo fi2; - if (fi2.Find(us2fs(arcPath))) - if (!fi2.IsDir()) - totalPackProcessed += fi2.Size; - } - continue; - } - - if (!options.StdInMode) - { - // numVolumes += arcLink.VolumePaths.Size(); - // arcLink.VolumesSize; - - // totalPackSize -= DeleteUsedFileNamesFromList(arcLink, i + 1, arcPaths, arcPathsFull, &arcSizes); - // numArcs = arcPaths.Size(); - if (arcLink.VolumePaths.Size() != 0) - { - Int64 correctionSize = arcLink.VolumesSize; - FOR_VECTOR (v, arcLink.VolumePaths) - { - int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); - if (index >= 0) - { - if ((unsigned)index > i) - { - skipArcs[(unsigned)index] = true; - correctionSize -= arcSizes[(unsigned)index]; - } - } - } - if (correctionSize != 0) - { - Int64 newPackSize = (Int64)totalPackSize + correctionSize; - if (newPackSize < 0) - newPackSize = 0; - totalPackSize = newPackSize; - RINOK(extractCallback->SetTotal(totalPackSize)); - } - } - } - - /* - // Now openCallback and extractCallback use same object. So we don't need to send password. - - #ifndef _NO_CRYPTO - bool passwordIsDefined; - UString password; - RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)); - if (passwordIsDefined) - { - RINOK(extractCallback->SetPassword(password)); - } - #endif - */ - - CArc &arc = arcLink.Arcs.Back(); - arc.MTimeDefined = (!options.StdInMode && !fi.IsDevice); - arc.MTime = fi.MTime; - - UInt64 packProcessed; - bool calcCrc = - #ifndef _SFX - (hash != NULL); - #else - false; - #endif - - RINOK(DecompressArchive( - codecs, - arcLink, - fi.Size + arcLink.VolumesSize, - wildcardCensor, - options, - calcCrc, - extractCallback, ecs, errorMessage, packProcessed)); - - if (!options.StdInMode) - packProcessed = fi.Size + arcLink.VolumesSize; - totalPackProcessed += packProcessed; - ecs->LocalProgressSpec->InSize += packProcessed; - ecs->LocalProgressSpec->OutSize = ecs->UnpackSize; - if (!errorMessage.IsEmpty()) - return E_FAIL; - } - - if (multi || thereAreNotOpenArcs) - { - RINOK(extractCallback->SetTotal(totalPackSize)); - RINOK(extractCallback->SetCompleted(&totalPackProcessed)); - } - - st.NumFolders = ecs->NumFolders; - st.NumFiles = ecs->NumFiles; - st.NumAltStreams = ecs->NumAltStreams; - st.UnpackSize = ecs->UnpackSize; - st.AltStreams_UnpackSize = ecs->AltStreams_UnpackSize; - st.NumArchives = arcPaths.Size(); - st.PackSize = ecs->LocalProgressSpec->InSize; - return S_OK; -} +// Extract.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../Common/ExtractingFilePath.h" +#include "../Common/HashCalc.h" + +#include "Extract.h" +#include "SetProperties.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + + +static void SetErrorMessage(const char *message, + const FString &path, HRESULT errorCode, + UString &s) +{ + s = message; + s += " : "; + s += NError::MyFormatMessage(errorCode); + s += " : "; + s += fs2us(path); +} + + +static HRESULT DecompressArchive( + CCodecs *codecs, + const CArchiveLink &arcLink, + UInt64 packSize, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + bool calcCrc, + IExtractCallbackUI *callback, + IFolderArchiveExtractCallback *callbackFAE, + CArchiveExtractCallback *ecs, + UString &errorMessage, + UInt64 &stdInProcessed) +{ + const CArc &arc = arcLink.Arcs.Back(); + stdInProcessed = 0; + IInArchive *archive = arc.Archive; + CRecordVector realIndices; + + UStringVector removePathParts; + + FString outDir = options.OutputDir; + UString replaceName = arc.DefaultName; + + if (arcLink.Arcs.Size() > 1) + { + // Most "pe" archives have same name of archive subfile "[0]" or ".rsrc_1". + // So it extracts different archives to one folder. + // We will use top level archive name + const CArc &arc0 = arcLink.Arcs[0]; + if (arc0.FormatIndex >= 0 && StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)arc0.FormatIndex].Name, "pe")) + replaceName = arc0.DefaultName; + } + + outDir.Replace(FString("*"), us2fs(Get_Correct_FsFile_Name(replaceName))); + + bool elimIsPossible = false; + UString elimPrefix; // only pure name without dir delimiter + FString outDirReduced = outDir; + + if (options.ElimDup.Val && options.PathMode != NExtract::NPathMode::kAbsPaths) + { + UString dirPrefix; + SplitPathToParts_Smart(fs2us(outDir), dirPrefix, elimPrefix); + if (!elimPrefix.IsEmpty()) + { + if (IsPathSepar(elimPrefix.Back())) + elimPrefix.DeleteBack(); + if (!elimPrefix.IsEmpty()) + { + outDirReduced = us2fs(dirPrefix); + elimIsPossible = true; + } + } + } + + const bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); + + if (!options.StdInMode) + { + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)) + + CReadArcItem item; + + for (UInt32 i = 0; i < numItems; i++) + { + if (elimIsPossible + || !allFilesAreAllowed + || options.ExcludeDirItems + || options.ExcludeFileItems) + { + RINOK(arc.GetItem(i, item)) + if (item.IsDir ? options.ExcludeDirItems : options.ExcludeFileItems) + continue; + } + else + { + #ifdef SUPPORT_ALT_STREAMS + item.IsAltStream = false; + if (!options.NtOptions.AltStreams.Val && arc.Ask_AltStream) + { + RINOK(Archive_IsItem_AltStream(arc.Archive, i, item.IsAltStream)) + } + #endif + } + + #ifdef SUPPORT_ALT_STREAMS + if (!options.NtOptions.AltStreams.Val && item.IsAltStream) + continue; + #endif + + if (elimIsPossible) + { + const UString &s = + #ifdef SUPPORT_ALT_STREAMS + item.MainPath; + #else + item.Path; + #endif + if (!IsPath1PrefixedByPath2(s, elimPrefix)) + elimIsPossible = false; + else + { + wchar_t c = s[elimPrefix.Len()]; + if (c == 0) + { + if (!item.MainIsDir) + elimIsPossible = false; + } + else if (!IsPathSepar(c)) + elimIsPossible = false; + } + } + + if (!allFilesAreAllowed) + { + if (!CensorNode_CheckPath(wildcardCensor, item)) + continue; + } + + realIndices.Add(i); + } + + if (realIndices.Size() == 0) + { + callback->ThereAreNoFiles(); + return callback->ExtractResult(S_OK); + } + } + + if (elimIsPossible) + { + removePathParts.Add(elimPrefix); + // outDir = outDirReduced; + } + + #ifdef _WIN32 + // GetCorrectFullFsPath doesn't like "..". + // outDir.TrimRight(); + // outDir = GetCorrectFullFsPath(outDir); + #endif + + if (outDir.IsEmpty()) + outDir = "." STRING_PATH_SEPARATOR; + /* + #ifdef _WIN32 + else if (NName::IsAltPathPrefix(outDir)) {} + #endif + */ + else if (!CreateComplexDir(outDir)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot create output directory", outDir, res, errorMessage); + return res; + } + + ecs->Init( + options.NtOptions, + options.StdInMode ? &wildcardCensor : NULL, + &arc, + callbackFAE, + options.StdOutMode, options.TestMode, + outDir, + removePathParts, false, + packSize); + + ecs->Is_elimPrefix_Mode = elimIsPossible; + + + #ifdef SUPPORT_LINKS + + if (!options.StdInMode && + !options.TestMode && + options.NtOptions.HardLinks.Val) + { + RINOK(ecs->PrepareHardLinks(&realIndices)) + } + + #endif + + + HRESULT result; + const Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0; + + CArchiveExtractCallback_Closer ecsCloser(ecs); + + if (options.StdInMode) + { + result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs); + NCOM::CPropVariant prop; + if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK) + ConvertPropVariantToUInt64(prop, stdInProcessed); + } + else + { + // v23.02: we reset completed value that could be set by Open() operation + IArchiveExtractCallback *aec = ecs; + const UInt64 val = 0; + RINOK(aec->SetCompleted(&val)) + result = archive->Extract(realIndices.ConstData(), realIndices.Size(), testMode, aec); + } + + const HRESULT res2 = ecsCloser.Close(); + if (result == S_OK) + result = res2; + + return callback->ExtractResult(result); +} + +/* v9.31: BUG was fixed: + 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 &fileNames, const UString &name); +int Find_FileName_InSortedVector(const UStringVector &fileNames, const UString &name) +{ + unsigned left = 0, right = fileNames.Size(); + while (left != right) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const UString &midVal = fileNames[mid]; + const int comp = CompareFileNames(name, midVal); + if (comp == 0) + return (int)mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + return -1; +} + + + +HRESULT Extract( + // DECL_EXTERNAL_CODECS_LOC_VARS + CCodecs *codecs, + const CObjectVector &types, + const CIntVector &excludedFormats, + UStringVector &arcPaths, UStringVector &arcPathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX + IHashCalc *hash, + #endif + UString &errorMessage, + CDecompressStat &st) +{ + st.Clear(); + UInt64 totalPackSize = 0; + CRecordVector arcSizes; + + unsigned numArcs = options.StdInMode ? 1 : arcPaths.Size(); + + unsigned i; + + for (i = 0; i < numArcs; i++) + { + NFind::CFileInfo fi; + fi.Size = 0; + if (!options.StdInMode) + { + const FString arcPath = us2fs(arcPaths[i]); + if (!fi.Find_FollowLink(arcPath)) + { + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot find archive file", arcPath, errorCode, errorMessage); + return errorCode; + } + if (fi.IsDir()) + { + HRESULT errorCode = E_FAIL; + SetErrorMessage("The item is a directory", arcPath, errorCode, errorMessage); + return errorCode; + } + } + arcSizes.Add(fi.Size); + totalPackSize += fi.Size; + } + + CBoolArr skipArcs(numArcs); + for (i = 0; i < numArcs; i++) + skipArcs[i] = false; + + CArchiveExtractCallback *ecs = new CArchiveExtractCallback; + CMyComPtr ec(ecs); + + const bool multi = (numArcs > 1); + + ecs->InitForMulti(multi, + options.PathMode, + options.OverwriteMode, + options.ZoneMode, + false // keepEmptyDirParts + ); + #ifndef Z7_SFX + ecs->SetHashMethods(hash); + #endif + + if (multi) + { + RINOK(faeCallback->SetTotal(totalPackSize)) + } + + UInt64 totalPackProcessed = 0; + bool thereAreNotOpenArcs = false; + + for (i = 0; i < numArcs; i++) + { + if (skipArcs[i]) + continue; + + ecs->InitBeforeNewArchive(); + + const UString &arcPath = arcPaths[i]; + NFind::CFileInfo fi; + if (options.StdInMode) + { + // do we need ctime and mtime? + // fi.ClearBase(); + // fi.Size = 0; // (UInt64)(Int64)-1; + if (!fi.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); + } + else + { + if (!fi.Find_FollowLink(us2fs(arcPath)) || fi.IsDir()) + { + const HRESULT errorCode = GetLastError_noZero_HRESULT(); + SetErrorMessage("Cannot find archive file", us2fs(arcPath), errorCode, errorMessage); + return errorCode; + } + } + + /* + #ifndef Z7_NO_CRYPTO + openCallback->Open_Clear_PasswordWasAsked_Flag(); + #endif + */ + + RINOK(extractCallback->BeforeOpen(arcPath, options.TestMode)) + CArchiveLink arcLink; + + CObjectVector types2 = types; + /* + #ifndef Z7_SFX + if (types.IsEmpty()) + { + int pos = arcPath.ReverseFind(L'.'); + if (pos >= 0) + { + UString s = arcPath.Ptr(pos + 1); + int index = codecs->FindFormatForExtension(s); + if (index >= 0 && s.IsEqualTo("001")) + { + s = arcPath.Left(pos); + pos = s.ReverseFind(L'.'); + if (pos >= 0) + { + int index2 = codecs->FindFormatForExtension(s.Ptr(pos + 1)); + if (index2 >= 0) // && s.CompareNoCase(L"rar") != 0 + { + types2.Add(index2); + types2.Add(index); + } + } + } + } + } + #endif + */ + + COpenOptions op; + #ifndef Z7_SFX + op.props = &options.Properties; + #endif + op.codecs = codecs; + op.types = &types2; + op.excludedFormats = &excludedFormats; + op.stdInMode = options.StdInMode; + op.stream = NULL; + op.filePath = arcPath; + + HRESULT result = arcLink.Open_Strict(op, openCallback); + + if (result == E_ABORT) + return result; + + // arcLink.Set_ErrorsText(); + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, result)) + + if (result != S_OK) + { + thereAreNotOpenArcs = true; + if (!options.StdInMode) + totalPackProcessed += fi.Size; + continue; + } + + #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (options.ZoneMode != NExtract::NZoneIdMode::kNone + && !options.StdInMode) + { + ReadZoneFile_Of_BaseFile(us2fs(arcPath), ecs->ZoneBuf); + } + #endif + + + if (arcLink.Arcs.Size() != 0) + { + if (arcLink.GetArc()->IsHashHandler(op)) + { + if (!options.TestMode) + { + /* real Extracting to files is possible. + But user can think that hash archive contains real files. + So we block extracting here. */ + // v23.00 : we don't break process. + RINOK(extractCallback->OpenResult(codecs, arcLink, arcPath, E_NOTIMPL)) + thereAreNotOpenArcs = true; + if (!options.StdInMode) + totalPackProcessed += fi.Size; + continue; + // return E_NOTIMPL; // before v23 + } + FString dirPrefix = us2fs(options.HashDir); + if (dirPrefix.IsEmpty()) + { + if (!NFile::NDir::GetOnlyDirPrefix(us2fs(arcPath), dirPrefix)) + { + // return GetLastError_noZero_HRESULT(); + } + } + if (!dirPrefix.IsEmpty()) + NName::NormalizeDirPathPrefix(dirPrefix); + ecs->DirPathPrefix_for_HashFiles = dirPrefix; + } + } + + if (!options.StdInMode) + { + // numVolumes += arcLink.VolumePaths.Size(); + // arcLink.VolumesSize; + + // totalPackSize -= DeleteUsedFileNamesFromList(arcLink, i + 1, arcPaths, arcPathsFull, &arcSizes); + // numArcs = arcPaths.Size(); + if (arcLink.VolumePaths.Size() != 0) + { + Int64 correctionSize = (Int64)arcLink.VolumesSize; + FOR_VECTOR (v, arcLink.VolumePaths) + { + int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); + if (index >= 0) + { + if ((unsigned)index > i) + { + skipArcs[(unsigned)index] = true; + correctionSize -= arcSizes[(unsigned)index]; + } + } + } + if (correctionSize != 0) + { + Int64 newPackSize = (Int64)totalPackSize + correctionSize; + if (newPackSize < 0) + newPackSize = 0; + totalPackSize = (UInt64)newPackSize; + RINOK(faeCallback->SetTotal(totalPackSize)) + } + } + } + + /* + // Now openCallback and extractCallback use same object. So we don't need to send password. + + #ifndef Z7_NO_CRYPTO + bool passwordIsDefined; + UString password; + RINOK(openCallback->Open_GetPasswordIfAny(passwordIsDefined, password)) + if (passwordIsDefined) + { + RINOK(extractCallback->SetPassword(password)) + } + #endif + */ + + CArc &arc = arcLink.Arcs.Back(); + arc.MTime.Def = !options.StdInMode + #ifdef _WIN32 + && !fi.IsDevice + #endif + ; + if (arc.MTime.Def) + arc.MTime.Set_From_FiTime(fi.MTime); + + UInt64 packProcessed; + const bool calcCrc = + #ifndef Z7_SFX + (hash != NULL); + #else + false; + #endif + + RINOK(DecompressArchive( + codecs, + arcLink, + fi.Size + arcLink.VolumesSize, + wildcardCensor, + options, + calcCrc, + extractCallback, faeCallback, ecs, + errorMessage, packProcessed)) + + if (!options.StdInMode) + packProcessed = fi.Size + arcLink.VolumesSize; + totalPackProcessed += packProcessed; + ecs->LocalProgressSpec->InSize += packProcessed; + ecs->LocalProgressSpec->OutSize = ecs->UnpackSize; + if (!errorMessage.IsEmpty()) + return E_FAIL; + } + + if (multi || thereAreNotOpenArcs) + { + RINOK(faeCallback->SetTotal(totalPackSize)) + RINOK(faeCallback->SetCompleted(&totalPackProcessed)) + } + + st.NumFolders = ecs->NumFolders; + st.NumFiles = ecs->NumFiles; + st.NumAltStreams = ecs->NumAltStreams; + st.UnpackSize = ecs->UnpackSize; + st.AltStreams_UnpackSize = ecs->AltStreams_UnpackSize; + st.NumArchives = arcPaths.Size(); + st.PackSize = ecs->LocalProgressSpec->InSize; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Extract.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/Extract.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Extract.h 2024-03-07 18:00:00.000000000 +0000 @@ -1,94 +1,107 @@ -// Extract.h - -#ifndef __EXTRACT_H -#define __EXTRACT_H - -#include "../../../Windows/FileFind.h" - -#include "../../Archive/IArchive.h" - -#include "ArchiveExtractCallback.h" -#include "ArchiveOpenCallback.h" -#include "ExtractMode.h" -#include "Property.h" - -#include "../Common/LoadCodecs.h" - -struct CExtractOptionsBase -{ - CBoolPair ElimDup; - - bool PathMode_Force; - bool OverwriteMode_Force; - NExtract::NPathMode::EEnum PathMode; - NExtract::NOverwriteMode::EEnum OverwriteMode; - - FString OutputDir; - CExtractNtOptions NtOptions; - - CExtractOptionsBase(): - PathMode_Force(false), - OverwriteMode_Force(false), - PathMode(NExtract::NPathMode::kFullPaths), - OverwriteMode(NExtract::NOverwriteMode::kAsk) - {} -}; - -struct CExtractOptions: public CExtractOptionsBase -{ - bool StdInMode; - bool StdOutMode; - bool YesToAll; - bool TestMode; - - // bool ShowDialog; - // bool PasswordEnabled; - // UString Password; - #ifndef _SFX - CObjectVector Properties; - #endif - - #ifdef EXTERNAL_CODECS - CCodecs *Codecs; - #endif - - CExtractOptions(): - TestMode(false), - StdInMode(false), - StdOutMode(false), - YesToAll(false) - {} -}; - -struct CDecompressStat -{ - UInt64 NumArchives; - UInt64 UnpackSize; - UInt64 AltStreams_UnpackSize; - UInt64 PackSize; - UInt64 NumFolders; - UInt64 NumFiles; - UInt64 NumAltStreams; - - void Clear() - { - NumArchives = UnpackSize = AltStreams_UnpackSize = PackSize = NumFolders = NumFiles = NumAltStreams = 0; - } -}; - -HRESULT Extract( - CCodecs *codecs, - const CObjectVector &types, - const CIntVector &excludedFormats, - UStringVector &archivePaths, UStringVector &archivePathsFull, - const NWildcard::CCensorNode &wildcardCensor, - const CExtractOptions &options, - IOpenCallbackUI *openCallback, - IExtractCallbackUI *extractCallback, - #ifndef _SFX - IHashCalc *hash, - #endif - UString &errorMessage, - CDecompressStat &st); - -#endif +// Extract.h + +#ifndef ZIP7_INC_EXTRACT_H +#define ZIP7_INC_EXTRACT_H + +#include "../../../Windows/FileFind.h" + +#include "../../Archive/IArchive.h" + +#include "ArchiveExtractCallback.h" +#include "ArchiveOpenCallback.h" +#include "ExtractMode.h" +#include "Property.h" + +#include "../Common/LoadCodecs.h" + +struct CExtractOptionsBase +{ + CBoolPair ElimDup; + + bool ExcludeDirItems; + bool ExcludeFileItems; + + bool PathMode_Force; + bool OverwriteMode_Force; + NExtract::NPathMode::EEnum PathMode; + NExtract::NOverwriteMode::EEnum OverwriteMode; + NExtract::NZoneIdMode::EEnum ZoneMode; + + CExtractNtOptions NtOptions; + + FString OutputDir; + UString HashDir; + + CExtractOptionsBase(): + ExcludeDirItems(false), + ExcludeFileItems(false), + PathMode_Force(false), + OverwriteMode_Force(false), + PathMode(NExtract::NPathMode::kFullPaths), + OverwriteMode(NExtract::NOverwriteMode::kAsk), + ZoneMode(NExtract::NZoneIdMode::kNone) + {} +}; + +struct CExtractOptions: public CExtractOptionsBase +{ + bool StdInMode; + bool StdOutMode; + bool YesToAll; + bool TestMode; + + // bool ShowDialog; + // bool PasswordEnabled; + // UString Password; + #ifndef Z7_SFX + CObjectVector Properties; + #endif + + /* + #ifdef Z7_EXTERNAL_CODECS + CCodecs *Codecs; + #endif + */ + + CExtractOptions(): + StdInMode(false), + StdOutMode(false), + YesToAll(false), + TestMode(false) + {} +}; + +struct CDecompressStat +{ + UInt64 NumArchives; + UInt64 UnpackSize; + UInt64 AltStreams_UnpackSize; + UInt64 PackSize; + UInt64 NumFolders; + UInt64 NumFiles; + UInt64 NumAltStreams; + + void Clear() + { + NumArchives = UnpackSize = AltStreams_UnpackSize = PackSize = NumFolders = NumFiles = NumAltStreams = 0; + } +}; + +HRESULT Extract( + // DECL_EXTERNAL_CODECS_LOC_VARS + CCodecs *codecs, + const CObjectVector &types, + const CIntVector &excludedFormats, + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + IFolderArchiveExtractCallback *faeCallback, + #ifndef Z7_SFX + IHashCalc *hash, + #endif + UString &errorMessage, + CDecompressStat &st); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractMode.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractMode.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractMode.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractMode.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,34 +1,44 @@ -// ExtractMode.h - -#ifndef __EXTRACT_MODE_H -#define __EXTRACT_MODE_H - -namespace NExtract { - -namespace NPathMode -{ - enum EEnum - { - kFullPaths, - kCurPaths, - kNoPaths, - kAbsPaths, - kNoPathsAlt // alt streams must be extracted without name of base file - }; -} - -namespace NOverwriteMode -{ - enum EEnum - { - kAsk, - kOverwrite, - kSkip, - kRename, - kRenameExisting - }; -} - -} - -#endif +// ExtractMode.h + +#ifndef ZIP7_INC_EXTRACT_MODE_H +#define ZIP7_INC_EXTRACT_MODE_H + +namespace NExtract { + +namespace NPathMode +{ + enum EEnum + { + kFullPaths, + kCurPaths, + kNoPaths, + kAbsPaths, + kNoPathsAlt // alt streams must be extracted without name of base file + }; +} + +namespace NOverwriteMode +{ + enum EEnum + { + kAsk, + kOverwrite, + kSkip, + kRename, + kRenameExisting + }; +} + +namespace NZoneIdMode +{ + enum EEnum + { + kNone, + kAll, + kOffice + }; +} + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractingFilePath.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractingFilePath.cpp 2015-10-03 13:02:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -1,239 +1,296 @@ -// ExtractingFilePath.cpp - -#include "StdAfx.h" - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileName.h" - -#include "ExtractingFilePath.h" - -static void ReplaceIncorrectChars(UString &s) -{ - { - for (unsigned i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if ( - #ifdef _WIN32 - c == ':' || c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"' - || c == '/' - // || c == 0x202E // RLO - || - #endif - c == WCHAR_PATH_SEPARATOR) - s.ReplaceOneCharAtPos(i, '_'); - } - } - - #ifdef _WIN32 - { - for (unsigned i = s.Len(); i != 0;) - { - wchar_t c = s[--i]; - if (c != '.' && c != ' ') - break; - s.ReplaceOneCharAtPos(i, '_'); - } - } - #endif -} - -#if 1 // FIXME #ifdef _WIN32 - -/* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream. - But colon in postfix ":$DATA" is allowed. - WIN32 functions don't allow empty alt stream name "name:" */ - -void Correct_AltStream_Name(UString &s) -{ - unsigned len = s.Len(); - const unsigned kPostfixSize = 6; - if (s.Len() >= kPostfixSize - && StringsAreEqualNoCase_Ascii(s.RightPtr(kPostfixSize), ":$DATA")) - len -= kPostfixSize; - for (unsigned i = 0; i < len; i++) - { - wchar_t c = s[i]; - if (c == ':' || c == '\\' || c == '/' - || c == 0x202E // RLO - ) - s.ReplaceOneCharAtPos(i, '_'); - } - if (s.IsEmpty()) - s = L'_'; -} - -static const unsigned g_ReservedWithNum_Index = 4; - -static const char * const g_ReservedNames[] = -{ - "CON", "PRN", "AUX", "NUL", - "COM", "LPT" -}; - -static bool IsSupportedName(const UString &name) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_ReservedNames); i++) - { - const char *reservedName = g_ReservedNames[i]; - unsigned len = MyStringLen(reservedName); - if (name.Len() < len) - continue; - if (!name.IsPrefixedBy_Ascii_NoCase(reservedName)) - continue; - if (i >= g_ReservedWithNum_Index) - { - wchar_t c = name[len]; - if (c < L'0' || c > L'9') - continue; - len++; - } - for (;;) - { - wchar_t c = name[len++]; - if (c == 0 || c == '.') - return false; - if (c != ' ') - break; - } - } - return true; -} - -static void CorrectUnsupportedName(UString &name) -{ - if (!IsSupportedName(name)) - name.InsertAtFront(L'_'); -} - -#endif - -static void Correct_PathPart(UString &s) -{ - // "." and ".." - if (s[0] == '.' && (s[1] == 0 || s[1] == '.' && s[2] == 0)) - s.Empty(); - #ifdef _WIN32 - else - ReplaceIncorrectChars(s); - #endif -} - -// static const wchar_t *k_EmptyReplaceName = L"[]"; -static const wchar_t k_EmptyReplaceName = L'_'; - -UString Get_Correct_FsFile_Name(const UString &name) -{ - UString res = name; - Correct_PathPart(res); - - #ifdef _WIN32 - CorrectUnsupportedName(res); - #endif - - if (res.IsEmpty()) - res = k_EmptyReplaceName; - return res; -} - - -void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) -{ - unsigned i = 0; - - if (absIsAllowed) - { - #if defined(_WIN32) && !defined(UNDER_CE) - bool isDrive = false; - #endif - if (parts[0].IsEmpty()) - { - i = 1; - #if defined(_WIN32) && !defined(UNDER_CE) - if (parts.Size() > 1 && parts[1].IsEmpty()) - { - i = 2; - if (parts.Size() > 2 && parts[2] == L"?") - { - i = 3; - if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) - { - isDrive = true; - i = 4; - } - } - } - #endif - } - #if defined(_WIN32) && !defined(UNDER_CE) - else if (NWindows::NFile::NName::IsDrivePath2(parts[0])) - { - isDrive = true; - i = 1; - } - - if (isDrive) - { - // we convert "c:name" to "c:\name", if absIsAllowed path. - const UString &ds = parts[i - 1]; - if (ds.Len() != 2) - { - UString s = ds.Ptr(2); - parts.Insert(i, s); - } - } - #endif - } - - for (; i < parts.Size();) - { - UString &s = parts[i]; - - #if 1 // #ifdef _WIN32 // ticket #153 Relative paths extracted outside of extraction directory - Correct_PathPart(s); - #endif - - if (s.IsEmpty()) - { - if (isDir || i != parts.Size() - 1) - { - parts.Delete(i); - continue; - } - s = k_EmptyReplaceName; - } - else - { - #ifdef _WIN32 - CorrectUnsupportedName(s); - #endif - } - - i++; - } - - if (!isDir) - { - if (parts.IsEmpty()) - parts.Add(k_EmptyReplaceName); - else - { - UString &s = parts.Back(); - if (s.IsEmpty()) - s = k_EmptyReplaceName; - } - } -} - -UString MakePathFromParts(const UStringVector &parts) -{ - UString s; - FOR_VECTOR (i, parts) - { - if (i != 0) - s.Add_PathSepar(); - s += parts[i]; - } - return s; -} +// ExtractingFilePath.cpp + +#include "StdAfx.h" + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileName.h" + +#include "ExtractingFilePath.h" + +extern +bool g_PathTrailReplaceMode; +bool g_PathTrailReplaceMode = + #ifdef _WIN32 + true + #else + false + #endif + ; + + +#ifdef _WIN32 +static void ReplaceIncorrectChars(UString &s) +{ + { + for (unsigned i = 0; i < s.Len(); i++) + { + wchar_t c = s[i]; + if ( + #ifdef _WIN32 + c == ':' || c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"' + || c == '/' + // || c == 0x202E // RLO + || + #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, + c + // (wchar_t)(0xf000 + c) // 21.02 debug: WSL encoding for unsupported characters + ); + } + } + } + + if (g_PathTrailReplaceMode) + { + /* + // if (g_PathTrailReplaceMode == 1) + { + if (!s.IsEmpty()) + { + wchar_t c = s.Back(); + if (c == '.' || c == ' ') + { + // s += (wchar_t)(0x9c); // STRING TERMINATOR + s += (wchar_t)'_'; + } + } + } + else + */ + { + unsigned i; + for (i = s.Len(); i != 0;) + { + wchar_t c = s[i - 1]; + if (c != '.' && c != ' ') + break; + i--; + s.ReplaceOneCharAtPos(i, '_'); + // s.ReplaceOneCharAtPos(i, (c == ' ' ? (wchar_t)(0x2423) : (wchar_t)0x00B7)); + } + /* + if (g_PathTrailReplaceMode > 1 && i != s.Len()) + { + s.DeleteFrom(i); + } + */ + } + } +} +#endif + +/* WinXP-64 doesn't support ':', '\\' and '/' symbols in name of alt stream. + But colon in postfix ":$DATA" is allowed. + WIN32 functions don't allow empty alt stream name "name:" */ + +void Correct_AltStream_Name(UString &s) +{ + unsigned len = s.Len(); + const unsigned kPostfixSize = 6; + if (s.Len() >= kPostfixSize + && StringsAreEqualNoCase_Ascii(s.RightPtr(kPostfixSize), ":$DATA")) + len -= kPostfixSize; + for (unsigned i = 0; i < len; i++) + { + wchar_t c = s[i]; + if (c == ':' || c == '\\' || c == '/' + || c == 0x202E // RLO + ) + s.ReplaceOneCharAtPos(i, '_'); + } + if (s.IsEmpty()) + s = '_'; +} + +#ifdef _WIN32 + +static const unsigned g_ReservedWithNum_Index = 4; + +static const char * const g_ReservedNames[] = +{ + "CON", "PRN", "AUX", "NUL", + "COM", "LPT" +}; + +static bool IsSupportedName(const UString &name) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_ReservedNames); i++) + { + const char *reservedName = g_ReservedNames[i]; + unsigned len = MyStringLen(reservedName); + if (name.Len() < len) + continue; + if (!name.IsPrefixedBy_Ascii_NoCase(reservedName)) + continue; + if (i >= g_ReservedWithNum_Index) + { + wchar_t c = name[len]; + if (c < L'0' || c > L'9') + continue; + len++; + } + for (;;) + { + wchar_t c = name[len++]; + if (c == 0 || c == '.') + return false; + if (c != ' ') + break; + } + } + return true; +} + +static void CorrectUnsupportedName(UString &name) +{ + if (!IsSupportedName(name)) + name.InsertAtFront(L'_'); +} + +#endif + +static void Correct_PathPart(UString &s) +{ + // "." and ".." + if (s.IsEmpty()) + return; + + if (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) + s.Empty(); + #ifdef _WIN32 + else + ReplaceIncorrectChars(s); + #endif +} + +// static const char * const k_EmptyReplaceName = "[]"; +static const char k_EmptyReplaceName = '_'; + +UString Get_Correct_FsFile_Name(const UString &name) +{ + UString res = name; + Correct_PathPart(res); + + #ifdef _WIN32 + CorrectUnsupportedName(res); + #endif + + if (res.IsEmpty()) + res = k_EmptyReplaceName; + return res; +} + + +void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir) +{ + unsigned i = 0; + + if (absIsAllowed) + { + #if defined(_WIN32) && !defined(UNDER_CE) + bool isDrive = false; + #endif + + if (parts[0].IsEmpty()) + { + i = 1; + #if defined(_WIN32) && !defined(UNDER_CE) + if (parts.Size() > 1 && parts[1].IsEmpty()) + { + i = 2; + if (parts.Size() > 2 && parts[2].IsEqualTo("?")) + { + i = 3; + if (parts.Size() > 3 && NWindows::NFile::NName::IsDrivePath2(parts[3])) + { + isDrive = true; + i = 4; + } + } + } + #endif + } + #if defined(_WIN32) && !defined(UNDER_CE) + else if (NWindows::NFile::NName::IsDrivePath2(parts[0])) + { + isDrive = true; + i = 1; + } + + if (isDrive) + { + // we convert "c:name" to "c:\name", if absIsAllowed path. + UString &ds = parts[i - 1]; + if (ds.Len() > 2) + { + parts.Insert(i, ds.Ptr(2)); + ds.DeleteFrom(2); + } + } + #endif + } + + if (i != 0) + keepAndReplaceEmptyPrefixes = false; + + for (; i < parts.Size();) + { + UString &s = parts[i]; + + Correct_PathPart(s); + + if (s.IsEmpty()) + { + if (!keepAndReplaceEmptyPrefixes) + if (isDir || i != parts.Size() - 1) + { + parts.Delete(i); + continue; + } + s = k_EmptyReplaceName; + } + else + { + keepAndReplaceEmptyPrefixes = false; + #ifdef _WIN32 + CorrectUnsupportedName(s); + #endif + } + + i++; + } + + if (!isDir) + { + if (parts.IsEmpty()) + parts.Add((UString)k_EmptyReplaceName); + else + { + UString &s = parts.Back(); + if (s.IsEmpty()) + s = k_EmptyReplaceName; + } + } +} + +UString MakePathFromParts(const UStringVector &parts) +{ + UString s; + FOR_VECTOR (i, parts) + { + if (i != 0) + s.Add_PathSepar(); + s += parts[i]; + } + return s; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractingFilePath.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ExtractingFilePath.h 2015-10-03 12:40:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ExtractingFilePath.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,19 +1,31 @@ -// ExtractingFilePath.h - -#ifndef __EXTRACTING_FILE_PATH_H -#define __EXTRACTING_FILE_PATH_H - -#include "../../../Common/MyString.h" - -// #ifdef _WIN32 -void Correct_AltStream_Name(UString &s); -// #endif - -// replaces unsuported characters, and replaces "." , ".." and "" to "[]" -UString Get_Correct_FsFile_Name(const UString &name); - -void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir); - -UString MakePathFromParts(const UStringVector &parts); - -#endif +// ExtractingFilePath.h + +#ifndef ZIP7_INC_EXTRACTING_FILE_PATH_H +#define ZIP7_INC_EXTRACTING_FILE_PATH_H + +#include "../../../Common/MyString.h" + +// #ifdef _WIN32 +void Correct_AltStream_Name(UString &s); +// #endif + +// replaces unsuported characters, and replaces "." , ".." and "" to "[]" +UString Get_Correct_FsFile_Name(const UString &name); + +/* + Correct_FsPath() corrects path parts to prepare it for File System operations. + It also corrects empty path parts like "\\\\": + - frontal empty path parts : it removes them or changes them to "_" + - another empty path parts : it removes them + if (absIsAllowed && path is absolute) : it removes empty path parts after start absolute path prefix marker + else + { + if (!keepAndReplaceEmptyPrefixes) : it removes empty path parts + if ( keepAndReplaceEmptyPrefixes) : it changes each empty frontal path part to "_" + } +*/ +void Correct_FsPath(bool absIsAllowed, bool keepAndReplaceEmptyPrefixes, UStringVector &parts, bool isDir); + +UString MakePathFromParts(const UStringVector &parts); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/HashCalc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/HashCalc.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,351 +1,2273 @@ -// HashCalc.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" - -#include "../../../Common/StringToInt.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/StreamUtils.h" - -#include "EnumDirItems.h" -#include "HashCalc.h" - -using namespace NWindows; - -class CHashMidBuf -{ - void *_data; -public: - CHashMidBuf(): _data(0) {} - operator void *() { return _data; } - bool Alloc(size_t size) - { - if (_data != 0) - return false; - _data = ::MidAlloc(size); - return _data != 0; - } - ~CHashMidBuf() { ::MidFree(_data); } -}; - -static const char *k_DefaultHashMethod = "CRC32"; - -HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods) -{ - UStringVector names = hashMethods; - if (names.IsEmpty()) - { - UString s; - s.SetFromAscii(k_DefaultHashMethod); - names.Add(s); - } - - CRecordVector ids; - CObjectVector methods; - - unsigned i; - for (i = 0; i < names.Size(); i++) - { - COneMethodInfo m; - RINOK(m.ParseMethodFromString(names[i])); - - if (m.MethodName.IsEmpty()) - m.MethodName = k_DefaultHashMethod; - - if (m.MethodName == "*") - { - CRecordVector tempMethods; - GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods); - methods.Clear(); - ids.Clear(); - FOR_VECTOR (t, tempMethods) - { - unsigned index = ids.AddToUniqueSorted(tempMethods[t]); - if (ids.Size() != methods.Size()) - methods.Insert(index, m); - } - break; - } - else - { - // m.MethodName.RemoveChar(L'-'); - CMethodId id; - if (!FindHashMethod(EXTERNAL_CODECS_LOC_VARS m.MethodName, id)) - return E_NOTIMPL; - unsigned index = ids.AddToUniqueSorted(id); - if (ids.Size() != methods.Size()) - methods.Insert(index, m); - } - } - - for (i = 0; i < ids.Size(); i++) - { - CMyComPtr hasher; - AString name; - RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)); - if (!hasher) - throw "Can't create hasher"; - const COneMethodInfo &m = methods[i]; - { - CMyComPtr scp; - hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); - if (scp) - RINOK(m.SetCoderProps(scp, NULL)); - } - UInt32 digestSize = hasher->GetDigestSize(); - if (digestSize > k_HashCalc_DigestSize_Max) - return E_NOTIMPL; - CHasherState &h = Hashers.AddNew(); - h.Hasher = hasher; - h.Name = name; - h.DigestSize = digestSize; - for (unsigned k = 0; k < k_HashCalc_NumGroups; k++) - memset(h.Digests[k], 0, digestSize); - } - - return S_OK; -} - -void CHashBundle::InitForNewFile() -{ - CurSize = 0; - FOR_VECTOR (i, Hashers) - { - CHasherState &h = Hashers[i]; - h.Hasher->Init(); - memset(h.Digests[k_HashCalc_Index_Current], 0, h.DigestSize); - } -} - -void CHashBundle::Update(const void *data, UInt32 size) -{ - CurSize += size; - FOR_VECTOR (i, Hashers) - Hashers[i].Hasher->Update(data, size); -} - -void CHashBundle::SetSize(UInt64 size) -{ - CurSize = size; -} - -static void AddDigests(Byte *dest, const Byte *src, UInt32 size) -{ - unsigned next = 0; - for (UInt32 i = 0; i < size; i++) - { - next += (unsigned)dest[i] + (unsigned)src[i]; - dest[i] = (Byte)next; - next >>= 8; - } -} - -void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) -{ - if (isDir) - NumDirs++; - else if (isAltStream) - { - NumAltStreams++; - AltStreamsSize += CurSize; - } - else - { - NumFiles++; - FilesSize += CurSize; - } - - Byte pre[16]; - memset(pre, 0, sizeof(pre)); - if (isDir) - pre[0] = 1; - - FOR_VECTOR (i, Hashers) - { - CHasherState &h = Hashers[i]; - if (!isDir) - { - h.Hasher->Final(h.Digests[0]); - if (!isAltStream) - AddDigests(h.Digests[k_HashCalc_Index_DataSum], h.Digests[0], h.DigestSize); - } - - h.Hasher->Init(); - h.Hasher->Update(pre, sizeof(pre)); - h.Hasher->Update(h.Digests[0], h.DigestSize); - - for (unsigned k = 0; k < path.Len(); k++) - { - wchar_t c = path[k]; - Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) }; - h.Hasher->Update(temp, 2); - } - - Byte tempDigest[k_HashCalc_DigestSize_Max]; - h.Hasher->Final(tempDigest); - if (!isAltStream) - AddDigests(h.Digests[k_HashCalc_Index_NamesSum], tempDigest, h.DigestSize); - AddDigests(h.Digests[k_HashCalc_Index_StreamsSum], tempDigest, h.DigestSize); - } -} - - -HRESULT HashCalc( - DECL_EXTERNAL_CODECS_LOC_VARS - const NWildcard::CCensor &censor, - const CHashOptions &options, - AString &errorInfo, - IHashCallbackUI *callback) -{ - CDirItems dirItems; - dirItems.Callback = callback; - - if (options.StdInMode) - { - CDirItem di; - di.Size = (UInt64)(Int64)-1; - di.Attrib = 0; - di.MTime.dwLowDateTime = 0; - di.MTime.dwHighDateTime = 0; - di.CTime = di.ATime = di.MTime; - dirItems.Items.Add(di); - } - else - { - RINOK(callback->StartScanning()); - dirItems.ScanAltStreams = options.AltStreamsMode; - - HRESULT res = EnumerateItems(censor, - options.PathMode, - UString(), - dirItems); - - if (res != S_OK) - { - if (res != E_ABORT) - errorInfo = "Scanning error"; - return res; - } - RINOK(callback->FinishScanning(dirItems.Stat)); - } - - unsigned i; - CHashBundle hb; - RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)); - hb.Init(); - - hb.NumErrors = dirItems.Stat.NumErrors; - - if (options.StdInMode) - { - RINOK(callback->SetNumFiles(1)); - } - else - { - RINOK(callback->SetTotal(dirItems.Stat.GetTotalBytes())); - } - - const UInt32 kBufSize = 1 << 15; - CHashMidBuf buf; - if (!buf.Alloc(kBufSize)) - return E_OUTOFMEMORY; - - UInt64 completeValue = 0; - - RINOK(callback->BeforeFirstFile(hb)); - - for (i = 0; i < dirItems.Items.Size(); i++) - { - CMyComPtr inStream; - UString path; - bool isDir = false; - bool isAltStream = false; - if (options.StdInMode) - { - inStream = new CStdInFileStream; - } - else - { - CInFileStream *inStreamSpec = new CInFileStream; - inStream = inStreamSpec; - const CDirItem &dirItem = dirItems.Items[i]; - isDir = dirItem.IsDir(); - isAltStream = dirItem.IsAltStream; - path = dirItems.GetLogPath(i); - if (!isDir) - { - FString phyPath = dirItems.GetPhyPath(i); - if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite)) - { - HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); - hb.NumErrors++; - if (res != S_FALSE) - return res; - continue; - } - } - } - RINOK(callback->GetStream(path, isDir)); - UInt64 fileSize = 0; - - hb.InitForNewFile(); - if (!isDir) - { - for (UInt32 step = 0;; step++) - { - if ((step & 0xFF) == 0) - RINOK(callback->SetCompleted(&completeValue)); - UInt32 size; - RINOK(inStream->Read(buf, kBufSize, &size)); - if (size == 0) - break; - hb.Update(buf, size); - fileSize += size; - completeValue += size; - } - } - hb.Final(isDir, isAltStream, path); - RINOK(callback->SetOperationResult(fileSize, hb, !isDir)); - RINOK(callback->SetCompleted(&completeValue)); - } - return callback->AfterLastFile(hb); -} - - -static inline char GetHex(unsigned v) -{ - return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); -} - -void AddHashHexToString(char *dest, const Byte *data, UInt32 size) -{ - dest[size * 2] = 0; - - if (!data) - { - for (UInt32 i = 0; i < size; i++) - { - dest[0] = ' '; - dest[1] = ' '; - dest += 2; - } - return; - } - - int step = 2; - if (size <= 8) - { - step = -2; - dest += size * 2 - 2; - } - - for (UInt32 i = 0; i < size; i++) - { - unsigned b = data[i]; - dest[0] = GetHex((b >> 4) & 0xF); - dest[1] = GetHex(b & 0xF); - dest += step; - } -} +// HashCalc.cpp + +#include "StdAfx.h" + +#include "../../../../C/Alloc.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/DynLimBuf.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" + +#include "../../Archive/Common/ItemNameUtils.h" +#include "../../Archive/IArchive.h" + +#include "EnumDirItems.h" +#include "HashCalc.h" + +using namespace NWindows; + +#ifdef Z7_EXTERNAL_CODECS +extern const CExternalCodecs *g_ExternalCodecs_Ptr; +#endif + +class CHashMidBuf +{ + void *_data; +public: + CHashMidBuf(): _data(NULL) {} + operator void *() { return _data; } + bool Alloc(size_t size) + { + if (_data) + return false; + _data = ::MidAlloc(size); + return _data != NULL; + } + ~CHashMidBuf() { ::MidFree(_data); } +}; + +static const char * const k_DefaultHashMethod = "CRC32"; + +HRESULT CHashBundle::SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &hashMethods) +{ + UStringVector names = hashMethods; + if (names.IsEmpty()) + names.Add(UString(k_DefaultHashMethod)); + + CRecordVector ids; + CObjectVector methods; + + unsigned i; + for (i = 0; i < names.Size(); i++) + { + COneMethodInfo m; + RINOK(m.ParseMethodFromString(names[i])) + + if (m.MethodName.IsEmpty()) + m.MethodName = k_DefaultHashMethod; + + if (m.MethodName.IsEqualTo("*")) + { + CRecordVector tempMethods; + GetHashMethods(EXTERNAL_CODECS_LOC_VARS tempMethods); + methods.Clear(); + ids.Clear(); + FOR_VECTOR (t, tempMethods) + { + unsigned index = ids.AddToUniqueSorted(tempMethods[t]); + if (ids.Size() != methods.Size()) + methods.Insert(index, m); + } + break; + } + else + { + // m.MethodName.RemoveChar(L'-'); + CMethodId id; + if (!FindHashMethod(EXTERNAL_CODECS_LOC_VARS m.MethodName, id)) + return E_NOTIMPL; + unsigned index = ids.AddToUniqueSorted(id); + if (ids.Size() != methods.Size()) + methods.Insert(index, m); + } + } + + for (i = 0; i < ids.Size(); i++) + { + CMyComPtr hasher; + AString name; + RINOK(CreateHasher(EXTERNAL_CODECS_LOC_VARS ids[i], name, hasher)) + if (!hasher) + throw "Can't create hasher"; + const COneMethodInfo &m = methods[i]; + { + CMyComPtr scp; + hasher.QueryInterface(IID_ICompressSetCoderProperties, &scp); + if (scp) + RINOK(m.SetCoderProps(scp, NULL)) + } + const UInt32 digestSize = hasher->GetDigestSize(); + if (digestSize > k_HashCalc_DigestSize_Max) + return E_NOTIMPL; + CHasherState &h = Hashers.AddNew(); + h.DigestSize = digestSize; + h.Hasher = hasher; + h.Name = name; + for (unsigned k = 0; k < k_HashCalc_NumGroups; k++) + h.InitDigestGroup(k); + } + + return S_OK; +} + +void CHashBundle::InitForNewFile() +{ + CurSize = 0; + FOR_VECTOR (i, Hashers) + { + CHasherState &h = Hashers[i]; + h.Hasher->Init(); + h.InitDigestGroup(k_HashCalc_Index_Current); + } +} + +void CHashBundle::Update(const void *data, UInt32 size) +{ + CurSize += size; + FOR_VECTOR (i, Hashers) + Hashers[i].Hasher->Update(data, size); +} + +void CHashBundle::SetSize(UInt64 size) +{ + CurSize = size; +} + +static void AddDigests(Byte *dest, const Byte *src, UInt32 size) +{ + unsigned next = 0; + /* + // we could use big-endian addition for sha-1 and sha-256 + // but another hashers are little-endian + if (size > 8) + { + for (unsigned i = size; i != 0;) + { + i--; + next += (unsigned)dest[i] + (unsigned)src[i]; + dest[i] = (Byte)next; + next >>= 8; + } + } + else + */ + { + for (unsigned i = 0; i < size; i++) + { + next += (unsigned)dest[i] + (unsigned)src[i]; + dest[i] = (Byte)next; + next >>= 8; + } + } + + // we use little-endian to store extra bytes + dest += k_HashCalc_DigestSize_Max; + for (unsigned i = 0; i < k_HashCalc_ExtraSize; i++) + { + next += (unsigned)dest[i]; + dest[i] = (Byte)next; + next >>= 8; + } +} + +void CHasherState::AddDigest(unsigned groupIndex, const Byte *data) +{ + NumSums[groupIndex]++; + AddDigests(Digests[groupIndex], data, DigestSize); +} + +void CHashBundle::Final(bool isDir, bool isAltStream, const UString &path) +{ + if (isDir) + NumDirs++; + else if (isAltStream) + { + NumAltStreams++; + AltStreamsSize += CurSize; + } + else + { + NumFiles++; + FilesSize += CurSize; + } + + Byte pre[16]; + memset(pre, 0, sizeof(pre)); + if (isDir) + pre[0] = 1; + + FOR_VECTOR (i, Hashers) + { + CHasherState &h = Hashers[i]; + if (!isDir) + { + h.Hasher->Final(h.Digests[0]); // k_HashCalc_Index_Current + if (!isAltStream) + h.AddDigest(k_HashCalc_Index_DataSum, h.Digests[0]); + } + + h.Hasher->Init(); + h.Hasher->Update(pre, sizeof(pre)); + h.Hasher->Update(h.Digests[0], h.DigestSize); + + for (unsigned k = 0; k < path.Len(); k++) + { + wchar_t c = path[k]; + + // 21.04: we want same hash for linux and windows paths + #if CHAR_PATH_SEPARATOR != '/' + if (c == CHAR_PATH_SEPARATOR) + c = '/'; + // if (c == (wchar_t)('\\' + 0xf000)) c = '\\'; // to debug WSL + // if (c > 0xf000 && c < 0xf080) c -= 0xf000; // to debug WSL + #endif + + Byte temp[2] = { (Byte)(c & 0xFF), (Byte)((c >> 8) & 0xFF) }; + h.Hasher->Update(temp, 2); + } + + Byte tempDigest[k_HashCalc_DigestSize_Max]; + h.Hasher->Final(tempDigest); + if (!isAltStream) + h.AddDigest(k_HashCalc_Index_NamesSum, tempDigest); + h.AddDigest(k_HashCalc_Index_StreamsSum, tempDigest); + } +} + + +static void CSum_Name_OriginalToEscape(const AString &src, AString &dest) +{ + dest.Empty(); + for (unsigned i = 0; i < src.Len();) + { + char c = src[i++]; + if (c == '\n') + { + dest.Add_Char('\\'); + c = 'n'; + } + else if (c == '\\') + dest.Add_Char('\\'); + dest.Add_Char(c); + } +} + + +static bool CSum_Name_EscapeToOriginal(const char *s, AString &dest) +{ + bool isOK = true; + dest.Empty(); + for (;;) + { + char c = *s++; + if (c == 0) + break; + if (c == '\\') + { + const char c1 = *s; + if (c1 == 'n') + { + c = '\n'; + s++; + } + else if (c1 == '\\') + { + c = c1; + s++; + } + else + { + // original md5sum returns NULL for such bad strings + isOK = false; + } + } + dest.Add_Char(c); + } + return isOK; +} + + + +static void SetSpacesAndNul(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + +static const unsigned kHashColumnWidth_Min = 4 * 2; + +static unsigned GetColumnWidth(unsigned digestSize) +{ + const unsigned width = digestSize * 2; + return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; +} + + +static void AddHashResultLine( + AString &_s, + // bool showHash, + // UInt64 fileSize, bool showSize, + const CObjectVector &hashers + // unsigned digestIndex, = k_HashCalc_Index_Current + ) +{ + FOR_VECTOR (i, hashers) + { + const CHasherState &h = hashers[i]; + char s[k_HashCalc_DigestSize_Max * 2 + 64]; + s[0] = 0; + // if (showHash) + HashHexToString(s, h.Digests[k_HashCalc_Index_Current], h.DigestSize); + const unsigned pos = (unsigned)strlen(s); + const int numSpaces = (int)GetColumnWidth(h.DigestSize) - (int)pos; + if (numSpaces > 0) + SetSpacesAndNul(s + pos, (unsigned)numSpaces); + if (i != 0) + _s.Add_Space(); + _s += s; + } + + /* + if (showSize) + { + _s.Add_Space(); + static const unsigned kSizeField_Len = 13; // same as in HashCon.cpp + char s[kSizeField_Len + 32]; + char *p = s; + SetSpacesAndNul(s, kSizeField_Len); + p = s + kSizeField_Len; + ConvertUInt64ToString(fileSize, p); + int numSpaces = (int)kSizeField_Len - (int)strlen(p); + if (numSpaces > 0) + p -= (unsigned)numSpaces; + _s += p; + } + */ +} + + +static void Add_LF(CDynLimBuf &hashFileString, const CHashOptionsLocal &options) +{ + hashFileString += (char)(options.HashMode_Zero.Val ? 0 : '\n'); +} + + + + +static void WriteLine(CDynLimBuf &hashFileString, + const CHashOptionsLocal &options, + const UString &path2, + bool isDir, + const AString &methodName, + const AString &hashesString) +{ + if (options.HashMode_OnlyHash.Val) + { + hashFileString += hashesString; + Add_LF(hashFileString, options); + return; + } + + UString path = path2; + + bool isBin = false; + const bool zeroMode = options.HashMode_Zero.Val; + const bool tagMode = options.HashMode_Tag.Val; + +#if CHAR_PATH_SEPARATOR != '/' + path.Replace(WCHAR_PATH_SEPARATOR, L'/'); + // path.Replace((wchar_t)('\\' + 0xf000), L'\\'); // to debug WSL +#endif + + AString utf8; + ConvertUnicodeToUTF8(path, utf8); + + AString esc; + CSum_Name_OriginalToEscape(utf8, esc); + + if (!zeroMode) + { + if (esc != utf8) + { + /* Original md5sum writes escape in that case. + We do same for compatibility with original md5sum. */ + hashFileString += '\\'; + } + } + + if (isDir && !esc.IsEmpty() && esc.Back() != '/') + esc.Add_Slash(); + + if (tagMode) + { + if (!methodName.IsEmpty()) + { + hashFileString += methodName; + hashFileString += ' '; + } + hashFileString += '('; + hashFileString += esc; + hashFileString += ')'; + hashFileString += " = "; + } + + hashFileString += hashesString; + + if (!tagMode) + { + hashFileString += ' '; + hashFileString += (char)(isBin ? '*' : ' '); + hashFileString += esc; + } + + Add_LF(hashFileString, options); +} + + +static void Convert_TagName_to_MethodName(AString &method) +{ + // we need to convert at least SHA512/256 to SHA512-256, and SHA512/224 to SHA512-224 + // but we convert any '/' to '-'. + method.Replace('/', '-'); +} + +static void Convert_MethodName_to_TagName(AString &method) +{ + if (method.IsPrefixedBy_Ascii_NoCase("SHA512-2")) + method.ReplaceOneCharAtPos(6, '/'); +} + + +static void WriteLine(CDynLimBuf &hashFileString, + const CHashOptionsLocal &options, + const UString &path, + bool isDir, + const CHashBundle &hb) +{ + AString methodName; + if (!hb.Hashers.IsEmpty()) + { + methodName = hb.Hashers[0].Name; + Convert_MethodName_to_TagName(methodName); + } + AString hashesString; + AddHashResultLine(hashesString, hb.Hashers); + WriteLine(hashFileString, options, path, isDir, methodName, hashesString); +} + + +HRESULT HashCalc( + DECL_EXTERNAL_CODECS_LOC_VARS + const NWildcard::CCensor &censor, + const CHashOptions &options, + AString &errorInfo, + IHashCallbackUI *callback) +{ + CDirItems dirItems; + dirItems.Callback = callback; + + if (options.StdInMode) + { + CDirItem di; + if (!di.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); + dirItems.Items.Add(di); + } + else + { + RINOK(callback->StartScanning()) + + dirItems.SymLinks = options.SymLinks.Val; + dirItems.ScanAltStreams = options.AltStreamsMode; + dirItems.ExcludeDirItems = censor.ExcludeDirItems; + dirItems.ExcludeFileItems = censor.ExcludeFileItems; + + dirItems.ShareForWrite = options.OpenShareForWrite; + + HRESULT res = EnumerateItems(censor, + options.PathMode, + UString(), + dirItems); + + if (res != S_OK) + { + if (res != E_ABORT) + errorInfo = "Scanning error"; + return res; + } + RINOK(callback->FinishScanning(dirItems.Stat)) + } + + unsigned i; + CHashBundle hb; + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)) + // hb.Init(); + + hb.NumErrors = dirItems.Stat.NumErrors; + + UInt64 totalSize = 0; + if (options.StdInMode) + { + RINOK(callback->SetNumFiles(1)) + } + else + { + totalSize = dirItems.Stat.GetTotalBytes(); + RINOK(callback->SetTotal(totalSize)) + } + + const UInt32 kBufSize = 1 << 15; + CHashMidBuf buf; + if (!buf.Alloc(kBufSize)) + return E_OUTOFMEMORY; + + UInt64 completeValue = 0; + + RINOK(callback->BeforeFirstFile(hb)) + + /* + CDynLimBuf hashFileString((size_t)1 << 31); + const bool needGenerate = !options.HashFilePath.IsEmpty(); + */ + + for (i = 0; i < dirItems.Items.Size(); i++) + { + CMyComPtr inStream; + UString path; + bool isDir = false; + bool isAltStream = false; + + if (options.StdInMode) + { +#if 1 + inStream = new CStdInFileStream; +#else + if (!CreateStdInStream(inStream)) + { + const DWORD lastError = ::GetLastError(); + const HRESULT res = callback->OpenFileError(FString("stdin"), lastError); + hb.NumErrors++; + if (res != S_FALSE && res != S_OK) + return res; + continue; + } +#endif + } + else + { + path = dirItems.GetLogPath(i); + const CDirItem &di = dirItems.Items[i]; + #ifdef _WIN32 + isAltStream = di.IsAltStream; + #endif + + #ifndef UNDER_CE + // if (di.AreReparseData()) + if (di.ReparseData.Size() != 0) + { + CBufInStream *inStreamSpec = new CBufInStream(); + inStream = inStreamSpec; + inStreamSpec->Init(di.ReparseData, di.ReparseData.Size()); + } + else + #endif + { + CInFileStream *inStreamSpec = new CInFileStream; + inStreamSpec->Set_PreserveATime(options.PreserveATime); + inStream = inStreamSpec; + isDir = di.IsDir(); + if (!isDir) + { + const FString phyPath = dirItems.GetPhyPath(i); + if (!inStreamSpec->OpenShared(phyPath, options.OpenShareForWrite)) + { + const HRESULT res = callback->OpenFileError(phyPath, ::GetLastError()); + hb.NumErrors++; + if (res != S_FALSE) + return res; + continue; + } + if (!options.StdInMode) + { + UInt64 curSize = 0; + if (inStreamSpec->GetSize(&curSize) == S_OK) + { + if (curSize > di.Size) + { + totalSize += curSize - di.Size; + RINOK(callback->SetTotal(totalSize)) + // printf("\ntotal = %d MiB\n", (unsigned)(totalSize >> 20)); + } + } + } + // inStreamSpec->ReloadProps(); + } + } + } + + RINOK(callback->GetStream(path, isDir)) + UInt64 fileSize = 0; + + hb.InitForNewFile(); + + if (!isDir) + { + for (UInt32 step = 0;; step++) + { + if ((step & 0xFF) == 0) + { + // printf("\ncompl = %d\n", (unsigned)(completeValue >> 20)); + RINOK(callback->SetCompleted(&completeValue)) + } + UInt32 size; + RINOK(inStream->Read(buf, kBufSize, &size)) + if (size == 0) + break; + hb.Update(buf, size); + fileSize += size; + completeValue += size; + } + } + + hb.Final(isDir, isAltStream, path); + + /* + if (needGenerate + && (options.HashMode_Dirs.Val || !isDir)) + { + WriteLine(hashFileString, + options, + path, // change it + isDir, + hb); + + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + */ + + RINOK(callback->SetOperationResult(fileSize, hb, !isDir)) + RINOK(callback->SetCompleted(&completeValue)) + } + + /* + if (needGenerate) + { + NFile::NIO::COutFile file; + if (!file.Create(us2fs(options.HashFilePath), true)) // createAlways + return GetLastError_noZero_HRESULT(); + if (!file.WriteFull(hashFileString, hashFileString.Len())) + return GetLastError_noZero_HRESULT(); + } + */ + + return callback->AfterLastFile(hb); +} + + +void HashHexToString(char *dest, const Byte *data, size_t size) +{ + if (!data) + { + for (size_t i = 0; i < size; i++) + { + dest[0] = ' '; + dest[1] = ' '; + dest += 2; + } + *dest = 0; + return; + } + + if (size > 8) + ConvertDataToHex_Lower(dest, data, size); + else if (size == 0) + { + *dest = 0; + return; + } + else + { + const char *dest_start = dest; + dest += size * 2; + *dest = 0; + do + { + const size_t b = *data++; + dest -= 2; + dest[0] = GET_HEX_CHAR_UPPER(b >> 4); + dest[1] = GET_HEX_CHAR_UPPER(b & 15); + } + while (dest != dest_start); + } +} + +void CHasherState::WriteToString(unsigned digestIndex, char *s) const +{ + HashHexToString(s, Digests[digestIndex], DigestSize); + + if (digestIndex != 0 && NumSums[digestIndex] != 1) + { + unsigned numExtraBytes = GetNumExtraBytes_for_Group(digestIndex); + if (numExtraBytes > 4) + numExtraBytes = 8; + else // if (numExtraBytes >= 0) + numExtraBytes = 4; + // if (numExtraBytes != 0) + { + s += strlen(s); + *s++ = '-'; + // *s = 0; + HashHexToString(s, GetExtraData_for_Group(digestIndex), numExtraBytes); + } + } +} + + + +// ---------- Hash Handler ---------- + +namespace NHash { + +#define IsWhite(c) ((c) == ' ' || (c) == '\t') + +bool CHashPair::IsDir() const +{ + if (Name.IsEmpty() || Name.Back() != '/') + return false; + // here we expect that Dir items contain only zeros or no Hash + for (size_t i = 0; i < Hash.Size(); i++) + if (Hash.ConstData()[i] != 0) + return false; + return true; +} + + +bool CHashPair::ParseCksum(const char *s) +{ + const char *end; + + const UInt32 crc = ConvertStringToUInt32(s, &end); + if (*end != ' ') + return false; + end++; + + const UInt64 size = ConvertStringToUInt64(end, &end); + if (*end != ' ') + return false; + end++; + + Name = end; + + Hash.Alloc(4); + SetBe32a(Hash, crc) + + Size_from_Arc = size; + Size_from_Arc_Defined = true; + + return true; +} + + + +static const char *SkipWhite(const char *s) +{ + while (IsWhite(*s)) + s++; + return s; +} + +static const char * const k_CsumMethodNames[] = +{ + "sha256" + , "sha224" + , "sha512-224" + , "sha512-256" + , "sha384" + , "sha512" + , "sha3-224" + , "sha3-256" + , "sha3-384" + , "sha3-512" +// , "shake128" +// , "shake256" + , "sha1" + , "sha2" + , "sha3" + , "sha" + , "md5" + , "blake2s" + , "blake2b" + , "blake2sp" + , "xxh64" + , "crc32" + , "crc64" + , "cksum" +}; + + +// returns true, if (method) is known hash method or hash method group name. +static bool GetMethod_from_FileName(const UString &name, AString &method) +{ + method.Empty(); + AString s; + ConvertUnicodeToUTF8(name, s); + const int dotPos = s.ReverseFind_Dot(); + if (dotPos >= 0) + { + method = s.Ptr(dotPos + 1); + if (method.IsEqualTo_Ascii_NoCase("txt") || + method.IsEqualTo_Ascii_NoCase("asc")) + { + method.Empty(); + const int dotPos2 = s.Find('.'); + if (dotPos2 >= 0) + s.DeleteFrom(dotPos2); + } + } + if (method.IsEmpty()) + { + // we support file names with "sum" and "sums" postfixes: "sha256sum", "sha256sums" + unsigned size; + if (s.Len() > 4 && StringsAreEqualNoCase_Ascii(s.RightPtr(4), "sums")) + size = 4; + else if (s.Len() > 3 && StringsAreEqualNoCase_Ascii(s.RightPtr(3), "sum")) + size = 3; + else + return false; + method = s; + method.DeleteFrom(s.Len() - size); + } + + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(k_CsumMethodNames); i++) + { + const char *m = k_CsumMethodNames[i]; + if (method.IsEqualTo_Ascii_NoCase(m)) + { + // method = m; // we can get lowcase + return true; + } + } + +/* + for (i = 0; i < Z7_ARRAY_SIZE(k_CsumMethodNames); i++) + { + const char *m = k_CsumMethodNames[i]; + if (method.IsPrefixedBy_Ascii_NoCase(m)) + { + method = m; // we get lowcase + return true; + } + } +*/ + return false; +} + + +bool CHashPair::Parse(const char *s) +{ + // here we keep compatibility with original md5sum / shasum + bool escape = false; + + s = SkipWhite(s); + + if (*s == '\\') + { + s++; + escape = true; + } + Escape = escape; + + // const char *kMethod = GetMethod_from_FileName(s); + // if (kMethod) + if ((size_t)(FindNonHexChar(s) - s) < 4) + { + // BSD-style checksum line + { + const char *s2 = s; + for (; *s2 != 0; s2++) + { + const char c = *s2; + if (c == 0) + return false; + if (c == ' ' || c == '(') + break; + } + Method.SetFrom(s, (unsigned)(s2 - s)); + s = s2; + } + IsBSD = true; + if (*s == ' ') + s++; + if (*s != '(') + return false; + s++; + { + const char *s2 = s; + for (; *s2 != 0; s2++) + {} + for (;;) + { + s2--; + if (s2 < s) + return false; + if (*s2 == ')') + break; + } + Name.SetFrom(s, (unsigned)(s2 - s)); + s = s2 + 1; + } + + s = SkipWhite(s); + if (*s != '=') + return false; + s++; + s = SkipWhite(s); + } + + { + const size_t numChars = (size_t)(FindNonHexChar(s) - s) & ~(size_t)1; + Hash.Alloc(numChars / 2); + if ((size_t)(ParseHexString(s, Hash) - Hash) != numChars / 2) + throw 101; + HashString.SetFrom(s, (unsigned)numChars); + s += numChars; + } + + if (IsBSD) + { + if (*s != 0) + return false; + if (escape) + { + const AString temp (Name); + return CSum_Name_EscapeToOriginal(temp, Name); + } + return true; + } + + if (*s == 0) + return true; + + if (*s != ' ') + return false; + s++; + const char c = *s; + if (c != ' ' + && c != '*' + && c != 'U' // shasum Universal + && c != '^' // shasum 0/1 + ) + return false; + Mode = c; + s++; + if (escape) + return CSum_Name_EscapeToOriginal(s, Name); + Name = s; + return true; +} + + +static bool GetLine(CByteBuffer &buf, bool zeroMode, bool cr_lf_Mode, size_t &posCur, AString &s) +{ + s.Empty(); + size_t pos = posCur; + const Byte *p = buf; + unsigned numDigits = 0; + for (; pos < buf.Size(); pos++) + { + const Byte b = p[pos]; + if (b == 0) + { + numDigits = 1; + break; + } + if (zeroMode) + continue; + if (b == 0x0a) + { + numDigits = 1; + break; + } + if (!cr_lf_Mode) + continue; + if (b == 0x0d) + { + if (pos + 1 >= buf.Size()) + { + numDigits = 1; + break; + // return false; + } + if (p[pos + 1] == 0x0a) + { + numDigits = 2; + break; + } + } + } + s.SetFrom((const char *)(p + posCur), (unsigned)(pos - posCur)); + posCur = pos + numDigits; + return true; +} + + +static bool Is_CR_LF_Data(const Byte *buf, size_t size) +{ + bool isCrLf = false; + for (size_t i = 0; i < size;) + { + const Byte b = buf[i]; + if (b == 0x0a) + return false; + if (b == 0x0d) + { + if (i == size - 1) + return false; + if (buf[i + 1] != 0x0a) + return false; + isCrLf = true; + i += 2; + } + else + i++; + } + return isCrLf; +} + + +static const Byte kArcProps[] = +{ + // kpidComment, + kpidCharacts +}; + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidPackSize, + kpidMethod +}; + +static const Byte kRawProps[] = +{ + kpidChecksum +}; + + +Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */ , UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = Z7_ARRAY_SIZE(kRawProps); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)) +{ + *propID = kRawProps[index]; + *name = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidChecksum) + { + const CHashPair &hp = HashPairs[index]; + if (hp.Hash.Size() != 0) + { + *data = hp.Hash; + *dataSize = (UInt32)hp.Hash.Size(); + *propType = NPropDataType::kRaw; + } + return S_OK; + } + + return S_OK; +} + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = HashPairs.Size(); + return S_OK; +} + +static void Add_OptSpace_String(UString &dest, const char *src) +{ + dest.Add_Space_if_NotEmpty(); + dest += src; +} + +Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidPhySize: if (_phySize != 0) prop = _phySize; break; + /* + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc; + // if (_sres == k_Base64_RES_NeedMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd; + if (v != 0) + prop = v; + break; + } + */ + case kpidCharacts: + { + UString s; + if (_hashSize_Defined) + { + s.Add_Space_if_NotEmpty(); + s.Add_UInt32(_hashSize * 8); + s += "-bit"; + } + if (_is_PgpMethod) + { + Add_OptSpace_String(s, "PGP"); + if (!_pgpMethod.IsEmpty()) + { + s.Add_Colon(); + s += _pgpMethod; + } + } + if (_is_ZeroMode) + Add_OptSpace_String(s, "ZERO"); + if (_are_there_Tags) + Add_OptSpace_String(s, "TAG"); + if (_are_there_Dirs) + Add_OptSpace_String(s, "DIRS"); + if (!_method_from_FileName.IsEmpty()) + { + Add_OptSpace_String(s, "filename_method:"); + s += _method_from_FileName; + if (!_is_KnownMethod_in_FileName) + s += ":UNKNOWN"; + } + if (!_methods.IsEmpty()) + { + Add_OptSpace_String(s, "cmd_method:"); + s += _methods[0]; + } + prop = s; + break; + } + + case kpidReadOnly: + { + if (_isArc) + if (!CanUpdate()) + prop = true; + break; + } + default: break; + } + prop.Detach(value); + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + // COM_TRY_BEGIN + NCOM::CPropVariant prop; + const CHashPair &hp = HashPairs[index]; + switch (propID) + { + case kpidIsDir: + { + prop = hp.IsDir(); + break; + } + case kpidPath: + { + UString path; + hp.Get_UString_Path(path); + + bool useBackslashReplacement = true; + if (_supportWindowsBackslash && !hp.Escape && path.Find(L"\\\\") < 0) + { +#if WCHAR_PATH_SEPARATOR == L'/' + path.Replace(L'\\', L'/'); +#else + useBackslashReplacement = false; +#endif + } + NArchive::NItemName::ReplaceToOsSlashes_Remove_TailSlash( + path, useBackslashReplacement); + prop = path; + break; + } + case kpidSize: + { + // client needs processed size of last file + if (hp.Size_from_Disk_Defined) + prop = (UInt64)hp.Size_from_Disk; + else if (hp.Size_from_Arc_Defined) + prop = (UInt64)hp.Size_from_Arc; + break; + } + case kpidPackSize: + { + prop = (UInt64)hp.Hash.Size(); + break; + } + case kpidMethod: + { + if (!hp.Method.IsEmpty()) + prop = hp.Method; + break; + } + default: break; + } + prop.Detach(value); + return S_OK; + // COM_TRY_END +} + + +static HRESULT ReadStream_to_Buf(IInStream *stream, CByteBuffer &buf, IArchiveOpenCallback *openCallback) +{ + buf.Free(); + UInt64 len; + RINOK(InStream_AtBegin_GetSize(stream, len)) + if (len == 0 || len >= ((UInt64)1 << 31)) + return S_FALSE; + buf.Alloc((size_t)len); + UInt64 pos = 0; + // return ReadStream_FALSE(stream, buf, (size_t)len); + for (;;) + { + const UInt32 kBlockSize = ((UInt32)1 << 24); + const UInt32 curSize = (len < kBlockSize) ? (UInt32)len : kBlockSize; + UInt32 processedSizeLoc; + RINOK(stream->Read((Byte *)buf + pos, curSize, &processedSizeLoc)) + if (processedSizeLoc == 0) + return E_FAIL; + len -= processedSizeLoc; + pos += processedSizeLoc; + if (len == 0) + return S_OK; + if (openCallback) + { + const UInt64 files = 0; + RINOK(openCallback->SetCompleted(&files, &pos)) + } + } +} + + +static bool isThere_Zero_Byte(const Byte *data, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (data[i] == 0) + return true; + return false; +} + + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)) +{ + COM_TRY_BEGIN + { + Close(); + + CByteBuffer buf; + RINOK(ReadStream_to_Buf(stream, buf, openCallback)) + + CObjectVector &pairs = HashPairs; + + const bool zeroMode = isThere_Zero_Byte(buf, buf.Size()); + _is_ZeroMode = zeroMode; + bool cr_lf_Mode = false; + if (!zeroMode) + cr_lf_Mode = Is_CR_LF_Data(buf, buf.Size()); + + if (openCallback) + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenVolumeCallback, + openVolumeCallback, openCallback) + if (openVolumeCallback) + { + NCOM::CPropVariant prop; + RINOK(openVolumeCallback->GetProperty(kpidName, &prop)) + if (prop.vt == VT_BSTR) + _is_KnownMethod_in_FileName = GetMethod_from_FileName(prop.bstrVal, _method_from_FileName); + } + } + + if (!_methods.IsEmpty()) + { + ConvertUnicodeToUTF8(_methods[0], _method_for_Extraction); + } + if (_method_for_Extraction.IsEmpty()) + { + // if (_is_KnownMethod_in_FileName) + _method_for_Extraction = _method_from_FileName; + } + + const bool cksumMode = _method_for_Extraction.IsEqualTo_Ascii_NoCase("cksum"); + _is_CksumMode = cksumMode; + + size_t pos = 0; + AString s; + bool minusMode = false; + unsigned numLines = 0; + + while (pos < buf.Size()) + { + if (!GetLine(buf, zeroMode, cr_lf_Mode, pos, s)) + return S_FALSE; + numLines++; + if (s.IsEmpty()) + continue; + + if (s.IsPrefixedBy_Ascii_NoCase("; ")) + { + if (numLines != 1) + return S_FALSE; + // comment line of FileVerifier++ + continue; + } + + if (s.IsPrefixedBy_Ascii_NoCase("-----")) + { + if (minusMode) + break; // end of pgp mode + minusMode = true; + if (s.IsPrefixedBy_Ascii_NoCase("-----BEGIN PGP SIGNED MESSAGE")) + { + if (_is_PgpMethod) + return S_FALSE; + if (!GetLine(buf, zeroMode, cr_lf_Mode, pos, s)) + return S_FALSE; + const char *kStart = "Hash: "; + if (!s.IsPrefixedBy_Ascii_NoCase(kStart)) + return S_FALSE; + _pgpMethod = s.Ptr((unsigned)strlen(kStart)); + _is_PgpMethod = true; + } + continue; + } + + CHashPair pair; + pair.FullLine = s; + if (cksumMode) + { + if (!pair.ParseCksum(s)) + return S_FALSE; + } + else if (!pair.Parse(s)) + return S_FALSE; + pairs.Add(pair); + } + + { + unsigned hashSize = 0; + bool hashSize_Dismatch = false; + for (unsigned i = 0; i < HashPairs.Size(); i++) + { + const CHashPair &hp = HashPairs[i]; + if (i == 0) + hashSize = (unsigned)hp.Hash.Size(); + else + if (hashSize != hp.Hash.Size()) + hashSize_Dismatch = true; + + if (hp.IsBSD) + _are_there_Tags = true; + if (!_are_there_Dirs && hp.IsDir()) + _are_there_Dirs = true; + } + if (!hashSize_Dismatch && hashSize != 0) + { + _hashSize = hashSize; + _hashSize_Defined = true; + } + } + + _phySize = buf.Size(); + _isArc = true; + return S_OK; + } + COM_TRY_END +} + + +void CHandler::ClearVars() +{ + _phySize = 0; + _isArc = false; + _is_CksumMode = false; + _is_PgpMethod = false; + _is_ZeroMode = false; + _are_there_Tags = false; + _are_there_Dirs = false; + _is_KnownMethod_in_FileName = false; + _hashSize_Defined = false; + _hashSize = 0; +} + + +Z7_COM7F_IMF(CHandler::Close()) +{ + ClearVars(); + _method_from_FileName.Empty(); + _method_for_Extraction.Empty(); + _pgpMethod.Empty(); + HashPairs.Clear(); + return S_OK; +} + + +static bool CheckDigests(const Byte *a, const Byte *b, size_t size) +{ + if (size <= 8) + { + /* we use reversed order for one digest, when text representation + uses big-order for crc-32 and crc-64 */ + for (size_t i = 0; i < size; i++) + if (a[i] != b[size - 1 - i]) + return false; + return true; + } + { + for (size_t i = 0; i < size; i++) + if (a[i] != b[i]) + return false; + return true; + } +} + + +static void AddDefaultMethod(UStringVector &methods, + const char *name, unsigned size) +{ + int shaVersion = -1; + if (name) + { + if (StringsAreEqualNoCase_Ascii(name, "sha")) + { + shaVersion = 0; + if (size == 0) + size = 32; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha1")) + { + shaVersion = 1; + if (size == 0) + size = 20; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha2")) + { + shaVersion = 2; + if (size == 0) + size = 32; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha3")) + { + if (size == 0 || + size == 32) name = "sha3-256"; + else if (size == 28) name = "sha3-224"; + else if (size == 48) name = "sha3-384"; + else if (size == 64) name = "sha3-512"; + } + else if (StringsAreEqualNoCase_Ascii(name, "sha512")) + { + // we allow any sha512 derived hash inside .sha512 file: + if (size == 48) name = "sha384"; + else if (size == 32) name = "sha512-256"; + else if (size == 28) name = "sha512-224"; + } + if (shaVersion >= 0) + name = NULL; + } + + const char *m = NULL; + if (name) + m = name; + else + { + if (size == 64) m = "sha512"; + else if (size == 48) m = "sha384"; + else if (size == 32) m = "sha256"; + else if (size == 28) m = "sha224"; + else if (size == 20) m = "sha1"; + else if (shaVersion < 0) + { + if (size == 16) m = "md5"; + else if (size == 8) m = "crc64"; + else if (size == 4) m = "crc32"; + } + } + + if (!m) + return; + +#ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; +#endif + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS + AString(m), id)) + methods.Add(UString(m)); +} + + +Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback)) +{ + COM_TRY_BEGIN + + /* + if (testMode == 0) + return E_NOTIMPL; + */ + + const bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = HashPairs.Size(); + if (numItems == 0) + return S_OK; + + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; + #endif + + CHashBundle hb_Glob; + // UStringVector methods = options.Methods; + UStringVector methods; + +/* + if (methods.IsEmpty() && !utf_nameExtenstion.IsEmpty() && !_hashSize_Defined) + { + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS utf_nameExtenstion, id)) + methods.Add(_nameExtenstion); + } +*/ + + if (methods.IsEmpty() && !_pgpMethod.IsEmpty()) + { + CMethodId id; + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS _pgpMethod, id)) + methods.Add(UString(_pgpMethod)); + } + +/* + if (methods.IsEmpty() && _pgpMethod.IsEmpty() && _hashSize_Defined) + { + AddDefaultMethod(methods, + utf_nameExtenstion.IsEmpty() ? NULL : utf_nameExtenstion.Ptr(), + _hashSize); + } +*/ + + if (!methods.IsEmpty()) + { + RINOK(hb_Glob.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods)) + } + + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveUpdateCallbackFile, + updateCallbackFile, extractCallback) + if (!updateCallbackFile) + return E_NOTIMPL; + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetDiskProperty, + GetDiskProperty, extractCallback) + if (GetDiskProperty) + { + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const UInt32 index = allFilesMode ? i : indices[i]; + const CHashPair &hp = HashPairs[index]; + if (hp.IsDir()) + continue; + { + NCOM::CPropVariant prop; + RINOK(GetDiskProperty->GetDiskProperty(index, kpidSize, &prop)) + if (prop.vt != VT_UI8) + continue; + totalSize += prop.uhVal.QuadPart; + } + } + RINOK(extractCallback->SetTotal(totalSize)) + // RINOK(Hash_SetTotalUnpacked->Hash_SetTotalUnpacked(indices, numItems)); + } + } + + const UInt32 kBufSize = 1 << 15; + CHashMidBuf buf; + if (!buf.Alloc(kBufSize)) + return E_OUTOFMEMORY; + + CMyComPtr2_Create lps; + lps->Init(extractCallback, false); + + for (UInt32 i = 0;; i++) + { + RINOK(lps->SetCur()) + if (i >= numItems) + break; + const UInt32 index = allFilesMode ? i : indices[i]; + + CHashPair &hp = HashPairs[index]; + + UString path; + hp.Get_UString_Path(path); + + CMyComPtr inStream; + const bool isDir = hp.IsDir(); + if (!isDir) + { + RINOK(updateCallbackFile->GetStream2(index, &inStream, NUpdateNotifyOp::kHashRead)) + if (!inStream) + { + continue; // we have shown error in GetStream2() + } + // askMode = NArchive::NExtract::NAskMode::kSkip; + } + + Int32 askMode = testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + + CMyComPtr realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + + /* PrepareOperation() can expect kExtract to set + Attrib and security of output file */ + askMode = NArchive::NExtract::NAskMode::kReadExternal; + + RINOK(extractCallback->PrepareOperation(askMode)) + + const bool isAltStream = false; + + UInt64 fileSize = 0; + + CHashBundle hb_Loc; + + CHashBundle *hb_Use = &hb_Glob; + + HRESULT res_SetMethods = S_OK; + + UStringVector methods_loc; + + if (!hp.Method.IsEmpty()) + { + hb_Use = &hb_Loc; + CMethodId id; + AString methodName = hp.Method; + Convert_TagName_to_MethodName(methodName); + if (FindHashMethod(EXTERNAL_CODECS_LOC_VARS methodName, id)) + { + methods_loc.Add(UString(methodName)); + RINOK(hb_Loc.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods_loc)) + } + else + res_SetMethods = E_NOTIMPL; + } + else if (methods.IsEmpty()) + { + AddDefaultMethod(methods_loc, + _method_for_Extraction.IsEmpty() ? NULL : + _method_for_Extraction.Ptr(), + (unsigned)hp.Hash.Size()); + if (!methods_loc.IsEmpty()) + { + hb_Use = &hb_Loc; + RINOK(hb_Loc.SetMethods( + EXTERNAL_CODECS_LOC_VARS + methods_loc)) + } + } + + const bool isSupportedMode = hp.IsSupportedMode(); + hb_Use->InitForNewFile(); + + if (inStream) + { + for (UInt32 step = 0;; step++) + { + if ((step & 0xFF) == 0) + { + RINOK(lps.Interface()->SetRatioInfo(NULL, &fileSize)) + } + UInt32 size; + RINOK(inStream->Read(buf, kBufSize, &size)) + if (size == 0) + break; + hb_Use->Update(buf, size); + if (realOutStream) + { + RINOK(WriteStream(realOutStream, buf, size)) + } + fileSize += size; + } + + hp.Size_from_Disk = fileSize; + hp.Size_from_Disk_Defined = true; + } + + realOutStream.Release(); + inStream.Release(); + + lps->InSize += hp.Hash.Size(); + lps->OutSize += fileSize; + + hb_Use->Final(isDir, isAltStream, path); + + Int32 opRes = NArchive::NExtract::NOperationResult::kUnsupportedMethod; + if (isSupportedMode + && res_SetMethods != E_NOTIMPL + && !hb_Use->Hashers.IsEmpty() + ) + { + const CHasherState &hs = hb_Use->Hashers[0]; + if (hs.DigestSize == hp.Hash.Size()) + { + opRes = NArchive::NExtract::NOperationResult::kCRCError; + if (CheckDigests(hp.Hash, hs.Digests[0], hs.DigestSize)) + if (!hp.Size_from_Arc_Defined || hp.Size_from_Arc == fileSize) + opRes = NArchive::NExtract::NOperationResult::kOK; + } + } + + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + COM_TRY_END +} + + +// ---------- UPDATE ---------- + +struct CUpdateItem +{ + int IndexInArc; + unsigned IndexInClient; + UInt64 Size; + bool NewData; + bool NewProps; + bool IsDir; + UString Path; + + CUpdateItem(): Size(0), IsDir(false) {} +}; + + +static HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, + UString &res, + bool convertSlash) +{ + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(index, propId, &prop)) + if (prop.vt == VT_BSTR) + { + res = prop.bstrVal; + if (convertSlash) + NArchive::NItemName::ReplaceSlashes_OsToUnix(res); + } + else if (prop.vt != VT_EMPTY) + return E_INVALIDARG; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) +{ + *type = NFileTimeType::kUnix; + return S_OK; +} + + +Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, + IArchiveUpdateCallback *callback)) +{ + COM_TRY_BEGIN + + if (_isArc && !CanUpdate()) + return E_NOTIMPL; + + /* + Z7_DECL_CMyComPtr_QI_FROM(IArchiveUpdateCallbackArcProp, + reportArcProp, callback) + */ + + CObjectVector updateItems; + + UInt64 complexity = 0; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + CUpdateItem ui; + Int32 newData; + Int32 newProps; + UInt32 indexInArc; + + if (!callback) + return E_FAIL; + + RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArc)) + + ui.NewProps = IntToBool(newProps); + ui.NewData = IntToBool(newData); + ui.IndexInArc = (int)indexInArc; + ui.IndexInClient = i; + if (IntToBool(newProps)) + { + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidIsDir, &prop)) + if (prop.vt == VT_EMPTY) + ui.IsDir = false; + else if (prop.vt != VT_BOOL) + return E_INVALIDARG; + else + ui.IsDir = (prop.boolVal != VARIANT_FALSE); + } + + RINOK(GetPropString(callback, i, kpidPath, ui.Path, + true)) // convertSlash + /* + if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/') + ui.Name += '/'; + */ + } + + if (IntToBool(newData)) + { + NCOM::CPropVariant prop; + RINOK(callback->GetProperty(i, kpidSize, &prop)) + if (prop.vt == VT_UI8) + { + ui.Size = prop.uhVal.QuadPart; + complexity += ui.Size; + } + else if (prop.vt == VT_EMPTY) + ui.Size = (UInt64)(Int64)-1; + else + return E_INVALIDARG; + } + + updateItems.Add(ui); + } + + if (complexity != 0) + { + RINOK(callback->SetTotal(complexity)) + } + + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *_externalCodecs = g_ExternalCodecs_Ptr; + #endif + + CHashBundle hb; + UStringVector methods; + if (!_methods.IsEmpty()) + { + FOR_VECTOR(k, _methods) + { + methods.Add(_methods[k]); + } + } + else + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveGetRootProps, + getRootProps, callback) + if (getRootProps) + { + NCOM::CPropVariant prop; + RINOK(getRootProps->GetRootProp(kpidArcFileName, &prop)) + if (prop.vt == VT_BSTR) + { + AString method; + /* const bool isKnownMethod = */ GetMethod_from_FileName(prop.bstrVal, method); + if (!method.IsEmpty()) + { + AddDefaultMethod(methods, method, _crcSize_WasSet ? _crcSize : 0); + if (methods.IsEmpty()) + return E_NOTIMPL; + } + } + } + } + if (methods.IsEmpty() && _crcSize_WasSet) + { + AddDefaultMethod(methods, + NULL, // name + _crcSize); + } + + RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS methods)) + + CMyComPtr2_Create lps; + lps->Init(callback, true); + + const UInt32 kBufSize = 1 << 15; + CHashMidBuf buf; + if (!buf.Alloc(kBufSize)) + return E_OUTOFMEMORY; + + CDynLimBuf hashFileString((size_t)1 << 31); + + CHashOptionsLocal options = _options; + + if (_isArc) + { + if (!options.HashMode_Zero.Def && _is_ZeroMode) + options.HashMode_Zero.Val = true; + if (!options.HashMode_Tag.Def && _are_there_Tags) + options.HashMode_Tag.Val = true; + if (!options.HashMode_Dirs.Def && _are_there_Dirs) + options.HashMode_Dirs.Val = true; + } + if (options.HashMode_OnlyHash.Val && updateItems.Size() != 1) + options.HashMode_OnlyHash.Val = false; + + complexity = 0; + + for (i = 0; i < updateItems.Size(); i++) + { + lps->InSize = complexity; + RINOK(lps->SetCur()) + + const CUpdateItem &ui = updateItems[i]; + + /* + CHashPair item; + if (!ui.NewProps) + item = HashPairs[(unsigned)ui.IndexInArc]; + */ + + if (ui.NewData) + { + UInt64 currentComplexity = ui.Size; + UInt64 fileSize = 0; + + CMyComPtr fileInStream; + bool needWrite = true; + { + HRESULT res = callback->GetStream(ui.IndexInClient, &fileInStream); + + if (res == S_FALSE) + needWrite = false; + else + { + RINOK(res) + + if (fileInStream) + { + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetSize, + streamGetSize, fileInStream) + if (streamGetSize) + { + UInt64 size; + if (streamGetSize->GetSize(&size) == S_OK) + currentComplexity = size; + } + /* + Z7_DECL_CMyComPtr_QI_FROM( + IStreamGetProps, + getProps, fileInStream) + if (getProps) + { + FILETIME mTime; + UInt64 size2; + if (getProps->GetProps(&size2, NULL, NULL, &mTime, NULL) == S_OK) + { + currentComplexity = size2; + // item.MTime = NTime::FileTimeToUnixTime64(mTime);; + } + } + */ + } + else + { + currentComplexity = 0; + } + } + } + + hb.InitForNewFile(); + const bool isDir = ui.IsDir; + + if (needWrite && fileInStream && !isDir) + { + for (UInt32 step = 0;; step++) + { + if ((step & 0xFF) == 0) + { + RINOK(lps.Interface()->SetRatioInfo(&fileSize, NULL)) + // RINOK(callback->SetCompleted(&completeValue)); + } + UInt32 size; + RINOK(fileInStream->Read(buf, kBufSize, &size)) + if (size == 0) + break; + hb.Update(buf, size); + fileSize += size; + } + currentComplexity = fileSize; + } + + fileInStream.Release(); + const bool isAltStream = false; + hb.Final(isDir, isAltStream, ui.Path); + + if (options.HashMode_Dirs.Val || !isDir) + { + if (!hb.Hashers.IsEmpty()) + lps->OutSize += hb.Hashers[0].DigestSize; + WriteLine(hashFileString, + options, + ui.Path, + isDir, + hb); + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + + complexity += currentComplexity; + + /* + if (reportArcProp) + { + PROPVARIANT prop; + prop.vt = VT_EMPTY; + prop.wReserved1 = 0; + + NCOM::PropVarEm_Set_UInt64(&prop, fileSize); + RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidSize, &prop)); + + for (unsigned k = 0; k < hb.Hashers.Size(); k++) + { + const CHasherState &hs = hb.Hashers[k]; + + if (hs.DigestSize == 4 && hs.Name.IsEqualTo_Ascii_NoCase("crc32")) + { + NCOM::PropVarEm_Set_UInt32(&prop, GetUi32(hs.Digests[k_HashCalc_Index_Current])); + RINOK(reportArcProp->ReportProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, kpidCRC, &prop)); + } + else + { + RINOK(reportArcProp->ReportRawProp(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, + kpidChecksum, hs.Digests[k_HashCalc_Index_Current], + hs.DigestSize, NPropDataType::kRaw)); + } + RINOK(reportArcProp->ReportFinished(NArchive::NEventIndexType::kOutArcIndex, ui.IndexInClient, NArchive::NUpdate::NOperationResult::kOK)); + } + } + */ + RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) + } + else + { + // old data + const CHashPair &existItem = HashPairs[(unsigned)ui.IndexInArc]; + if (ui.NewProps) + { + WriteLine(hashFileString, + options, + ui.Path, + ui.IsDir, + existItem.Method, existItem.HashString + ); + } + else + { + hashFileString += existItem.FullLine; + Add_LF(hashFileString, options); + } + } + if (hashFileString.IsError()) + return E_OUTOFMEMORY; + } + + RINOK(WriteStream(outStream, hashFileString, hashFileString.Len())) + + return S_OK; + COM_TRY_END +} + + + +HRESULT CHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value) +{ + UString name = nameSpec; + name.MakeLower_Ascii(); + if (name.IsEmpty()) + return E_INVALIDARG; + + if (name.IsEqualTo("m")) // "hm" hash method + { + // COneMethodInfo omi; + // RINOK(omi.ParseMethodFromPROPVARIANT(L"", value)); + // _methods.Add(omi.MethodName); // change it. use omi.PropsString + if (value.vt != VT_BSTR) + return E_INVALIDARG; + UString s (value.bstrVal); + _methods.Add(s); + return S_OK; + } + + if (name.IsEqualTo("flags")) + { + if (value.vt != VT_BSTR) + return E_INVALIDARG; + if (!_options.ParseString(value.bstrVal)) + return E_INVALIDARG; + return S_OK; + } + + if (name.IsEqualTo("backslash")) + return PROPVARIANT_to_bool(value, _supportWindowsBackslash); + + if (name.IsPrefixedBy_Ascii_NoCase("crc")) + { + name.Delete(0, 3); + _crcSize = 4; + _crcSize_WasSet = true; + return ParsePropToUInt32(name, value, _crcSize); + } + + // common properties + if (name.IsPrefixedBy_Ascii_NoCase("mt") + || name.IsPrefixedBy_Ascii_NoCase("memuse")) + return S_OK; + + return E_INVALIDARG; +} + + +void CHandler::InitProps() +{ + _supportWindowsBackslash = true; + _crcSize_WasSet = false; + _crcSize = 4; + _methods.Clear(); + _options.Init_HashOptionsLocal(); +} + +Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)) +{ + COM_TRY_BEGIN + + InitProps(); + + for (UInt32 i = 0; i < numProps; i++) + { + RINOK(SetProperty(names[i], values[i])) + } + return S_OK; + COM_TRY_END +} + +CHandler::CHandler() +{ + ClearVars(); + InitProps(); +} + +} + + + +static IInArchive *CreateHashHandler_In() { return new NHash::CHandler; } +static IOutArchive *CreateHashHandler_Out() { return new NHash::CHandler; } + +void Codecs_AddHashArcHandler(CCodecs *codecs) +{ + { + CArcInfoEx item; + + item.Name = "Hash"; + item.CreateInArchive = CreateHashHandler_In; + item.CreateOutArchive = CreateHashHandler_Out; + item.IsArcFunc = NULL; + item.Flags = + NArcInfoFlags::kKeepName + | NArcInfoFlags::kStartOpen + | NArcInfoFlags::kByExtOnlyOpen + // | NArcInfoFlags::kPureStartOpen + | NArcInfoFlags::kHashHandler + ; + + // ubuntu uses "SHA256SUMS" file + item.AddExts(UString ( + "sha256" + " sha512" + " sha384" + " sha224" + " sha512-224" + " sha512-256" + " sha3-224" + " sha3-256" + " sha3-384" + " sha3-512" + // " shake128" + // " shake256" + " sha1" + " sha2" + " sha3" + " sha" + " md5" + " blake2s" + " blake2b" + " blake2sp" + " xxh64" + " crc32" + " crc64" + " cksum" + " asc" + // " b2sum" + ), + UString()); + + item.UpdateEnabled = (item.CreateOutArchive != NULL); + item.SignatureOffset = 0; + // item.Version = MY_VER_MIX; + item.NewInterface = true; + + item.Signatures.AddNew().CopyFrom(NULL, 0); + + codecs->Formats.Add(item); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/HashCalc.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/HashCalc.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/HashCalc.h 2024-12-09 09:00:00.000000000 +0000 @@ -1,107 +1,322 @@ -// HashCalc.h - -#ifndef __HASH_CALC_H -#define __HASH_CALC_H - -#include "../../../Common/Wildcard.h" - -#include "../../Common/CreateCoder.h" -#include "../../Common/MethodProps.h" - -#include "DirItem.h" -#include "Property.h" - -const unsigned k_HashCalc_DigestSize_Max = 64; - -const unsigned k_HashCalc_NumGroups = 4; - -enum -{ - k_HashCalc_Index_Current, - k_HashCalc_Index_DataSum, - k_HashCalc_Index_NamesSum, - k_HashCalc_Index_StreamsSum -}; - -struct CHasherState -{ - CMyComPtr Hasher; - AString Name; - UInt32 DigestSize; - Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max]; -}; - -struct IHashCalc -{ - virtual void InitForNewFile() = 0; - virtual void Update(const void *data, UInt32 size) = 0; - virtual void SetSize(UInt64 size) = 0; - virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; -}; - -struct CHashBundle: public IHashCalc -{ - CObjectVector Hashers; - - UInt64 NumDirs; - UInt64 NumFiles; - UInt64 NumAltStreams; - UInt64 FilesSize; - UInt64 AltStreamsSize; - UInt64 NumErrors; - - UInt64 CurSize; - - HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); - - void Init() - { - NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; - } - - void InitForNewFile(); - void Update(const void *data, UInt32 size); - void SetSize(UInt64 size); - void Final(bool isDir, bool isAltStream, const UString &path); -}; - -#define INTERFACE_IHashCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT SetNumFiles(UInt64 numFiles) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT CheckBreak() x; \ - virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \ - virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \ - -struct IHashCallbackUI: public IDirItemsCallback -{ - INTERFACE_IHashCallbackUI(=0) -}; - -struct CHashOptions -{ - UStringVector Methods; - bool OpenShareForWrite; - bool StdInMode; - bool AltStreamsMode; - NWildcard::ECensorPathMode PathMode; - - CHashOptions(): StdInMode(false), OpenShareForWrite(false), AltStreamsMode(false), PathMode(NWildcard::k_RelatPath) {}; -}; - -HRESULT HashCalc( - DECL_EXTERNAL_CODECS_LOC_VARS - const NWildcard::CCensor &censor, - const CHashOptions &options, - AString &errorInfo, - IHashCallbackUI *callback); - -void AddHashHexToString(char *dest, const Byte *data, UInt32 size); - -#endif +// HashCalc.h + +#ifndef ZIP7_INC_HASH_CALC_H +#define ZIP7_INC_HASH_CALC_H + +#include "../../../Common/UTFConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../Common/CreateCoder.h" +#include "../../Common/MethodProps.h" + +#include "DirItem.h" +#include "IFileExtractCallback.h" + +const unsigned k_HashCalc_DigestSize_Max = 64; +const unsigned k_HashCalc_ExtraSize = 8; +const unsigned k_HashCalc_NumGroups = 4; + +/* + if (size <= 8) : upper case : reversed byte order : it shows 32-bit/64-bit number, if data contains little-endian number + if (size > 8) : lower case : original byte order (as big-endian byte sequence) +*/ +void HashHexToString(char *dest, const Byte *data, size_t size); + +enum +{ + k_HashCalc_Index_Current, + k_HashCalc_Index_DataSum, + k_HashCalc_Index_NamesSum, + k_HashCalc_Index_StreamsSum +}; + +struct CHasherState +{ + CMyComPtr Hasher; + AString Name; + UInt32 DigestSize; + UInt64 NumSums[k_HashCalc_NumGroups]; + Byte Digests[k_HashCalc_NumGroups][k_HashCalc_DigestSize_Max + k_HashCalc_ExtraSize]; + + void InitDigestGroup(unsigned groupIndex) + { + NumSums[groupIndex] = 0; + memset(Digests[groupIndex], 0, sizeof(Digests[groupIndex])); + } + + const Byte *GetExtraData_for_Group(unsigned groupIndex) const + { + return Digests[groupIndex] + k_HashCalc_DigestSize_Max; + } + + unsigned GetNumExtraBytes_for_Group(unsigned groupIndex) const + { + const Byte *p = GetExtraData_for_Group(groupIndex); + // we use little-endian to read extra bytes + for (unsigned i = k_HashCalc_ExtraSize; i != 0; i--) + if (p[i - 1] != 0) + return i; + return 0; + } + + void AddDigest(unsigned groupIndex, const Byte *data); + + void WriteToString(unsigned digestIndex, char *s) const; +}; + + +Z7_PURE_INTERFACES_BEGIN + + +DECLARE_INTERFACE(IHashCalc) +{ + virtual void InitForNewFile() = 0; + virtual void Update(const void *data, UInt32 size) = 0; + virtual void SetSize(UInt64 size) = 0; + virtual void Final(bool isDir, bool isAltStream, const UString &path) = 0; +}; + +Z7_PURE_INTERFACES_END + +struct CHashBundle Z7_final: public IHashCalc +{ + CObjectVector Hashers; + + UInt64 NumDirs; + UInt64 NumFiles; + UInt64 NumAltStreams; + UInt64 FilesSize; + UInt64 AltStreamsSize; + UInt64 NumErrors; + + UInt64 CurSize; + + UString MainName; + UString FirstFileName; + + HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); + + // void Init() {} + CHashBundle() + { + NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; + } + + void InitForNewFile() Z7_override; + void Update(const void *data, UInt32 size) Z7_override; + void SetSize(UInt64 size) Z7_override; + void Final(bool isDir, bool isAltStream, const UString &path) Z7_override; +}; + +Z7_PURE_INTERFACES_BEGIN + +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IHashCallbackUI(x) \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT SetNumFiles(UInt64 numFiles) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT CheckBreak() x \ + virtual HRESULT BeforeFirstFile(const CHashBundle &hb) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x \ + virtual HRESULT AfterLastFile(CHashBundle &hb) x \ + +Z7_IFACE_DECL_PURE_(IHashCallbackUI, IDirItemsCallback) + +Z7_PURE_INTERFACES_END + + +struct CHashOptionsLocal +{ + CBoolPair HashMode_Zero; + CBoolPair HashMode_Tag; + CBoolPair HashMode_Dirs; + CBoolPair HashMode_OnlyHash; + + void Init_HashOptionsLocal() + { + HashMode_Zero.Init(); + HashMode_Tag.Init(); + HashMode_Dirs.Init(); + HashMode_OnlyHash.Init(); + // HashMode_Dirs = true; // for debug + } + + CHashOptionsLocal() + { + Init_HashOptionsLocal(); + } + + bool ParseFlagCharOption(wchar_t c, bool val) + { + c = MyCharLower_Ascii(c); + if (c == 'z') HashMode_Zero.SetVal_as_Defined(val); + else if (c == 't') HashMode_Tag.SetVal_as_Defined(val); + else if (c == 'd') HashMode_Dirs.SetVal_as_Defined(val); + else if (c == 'h') HashMode_OnlyHash.SetVal_as_Defined(val); + else return false; + return true; + } + + bool ParseString(const UString &s) + { + for (unsigned i = 0; i < s.Len();) + { + const wchar_t c = s[i++]; + bool val = true; + if (i < s.Len()) + { + const wchar_t next = s[i]; + if (next == '-') + { + val = false; + i++; + } + } + if (!ParseFlagCharOption(c, val)) + return false; + } + return true; + } +}; + + +struct CHashOptions + // : public CHashOptionsLocal +{ + UStringVector Methods; + // UString HashFilePath; + + bool PreserveATime; + bool OpenShareForWrite; + bool StdInMode; + bool AltStreamsMode; + CBoolPair SymLinks; + + NWildcard::ECensorPathMode PathMode; + + CHashOptions(): + PreserveATime(false), + OpenShareForWrite(false), + StdInMode(false), + AltStreamsMode(false), + PathMode(NWildcard::k_RelatPath) {} +}; + + +HRESULT HashCalc( + DECL_EXTERNAL_CODECS_LOC_VARS + const NWildcard::CCensor &censor, + const CHashOptions &options, + AString &errorInfo, + IHashCallbackUI *callback); + + + +#ifndef Z7_SFX + +namespace NHash { + +struct CHashPair +{ + CByteBuffer Hash; + char Mode; + bool IsBSD; + bool Escape; + bool Size_from_Arc_Defined; + bool Size_from_Disk_Defined; + AString Method; + AString Name; + + AString FullLine; + AString HashString; + // unsigned HashLengthInBits; + + // AString MethodName; + UInt64 Size_from_Arc; + UInt64 Size_from_Disk; + + bool IsDir() const; + + void Get_UString_Path(UString &path) const + { + path.Empty(); + if (!ConvertUTF8ToUnicode(Name, path)) + return; + } + + bool ParseCksum(const char *s); + bool Parse(const char *s); + + bool IsSupportedMode() const + { + return Mode != 'U' && Mode != '^'; + } + + CHashPair(): + Mode(0) + , IsBSD(false) + , Escape(false) + , Size_from_Arc_Defined(false) + , Size_from_Disk_Defined(false) + // , HashLengthInBits(0) + , Size_from_Arc(0) + , Size_from_Disk(0) + {} +}; + + +Z7_CLASS_IMP_CHandler_IInArchive_3( + IArchiveGetRawProps, + /* public IGetArchiveHashHandler, */ + IOutArchive, + ISetProperties +) + bool _isArc; + bool _supportWindowsBackslash; + bool _crcSize_WasSet; + bool _is_CksumMode; + bool _is_PgpMethod; + bool _is_ZeroMode; + bool _are_there_Tags; + bool _are_there_Dirs; + bool _is_KnownMethod_in_FileName; + bool _hashSize_Defined; + unsigned _hashSize; + UInt32 _crcSize; + UInt64 _phySize; + CObjectVector HashPairs; + UStringVector _methods; + AString _method_from_FileName; + AString _pgpMethod; + AString _method_for_Extraction; + CHashOptionsLocal _options; + + void ClearVars(); + void InitProps(); + + bool CanUpdate() const + { + if (!_isArc || _is_PgpMethod || _is_CksumMode) + return false; + return true; + } + + HRESULT SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value); + +public: + CHandler(); +}; + +} + +void Codecs_AddHashArcHandler(CCodecs *codecs); + +#endif + + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/IFileExtractCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/IFileExtractCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/IFileExtractCallback.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/IFileExtractCallback.h 2023-04-05 20:00:00.000000000 +0000 @@ -1,114 +1,112 @@ -// IFileExtractCallback.h - -#ifndef __I_FILE_EXTRACT_CALLBACK_H -#define __I_FILE_EXTRACT_CALLBACK_H - -#include "../../../Common/MyString.h" - -#include "../../IDecl.h" - -#include "LoadCodecs.h" -#include "OpenArchive.h" - -namespace NOverwriteAnswer -{ - enum EEnum - { - kYes, - kYesToAll, - kNo, - kNoToAll, - kAutoRename, - kCancel - }; -} - - -/* ---------- IFolderArchiveExtractCallback ---------- -is implemented by - Console/ExtractCallbackConsole.h CExtractCallbackConsole - FileManager/ExtractCallback.h CExtractCallbackImp - FAR/ExtractEngine.cpp CExtractCallBackImp: (QueryInterface is not supported) - -IID_IFolderArchiveExtractCallback is requested by: - - Agent/ArchiveFolder.cpp - CAgentFolder::CopyTo(..., IFolderOperationsExtractCallback *callback) - is sent to IArchiveFolder::Extract() - - - FileManager/PanelCopy.cpp - CPanel::CopyTo(), if (options->testMode) - is sent to IArchiveFolder::Extract() - - IFolderArchiveExtractCallback is used by Common/ArchiveExtractCallback.cpp -*/ - -#define INTERFACE_IFolderArchiveExtractCallback(x) \ - STDMETHOD(AskOverwrite)( \ - const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, \ - const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, \ - Int32 *answer) x; \ - STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position) x; \ - STDMETHOD(MessageError)(const wchar_t *message) x; \ - STDMETHOD(SetOperationResult)(Int32 opRes, Int32 encrypted) x; \ - -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07) -{ - INTERFACE_IFolderArchiveExtractCallback(PURE) -}; - -#define INTERFACE_IFolderArchiveExtractCallback2(x) \ - STDMETHOD(ReportExtractResult)(Int32 opRes, Int32 encrypted, const wchar_t *name) x; \ - -DECL_INTERFACE_SUB(IFolderArchiveExtractCallback2, IUnknown, 0x01, 0x08) -{ - INTERFACE_IFolderArchiveExtractCallback2(PURE) -}; - -/* ---------- IExtractCallbackUI ---------- -is implemented by - Console/ExtractCallbackConsole.h CExtractCallbackConsole - FileManager/ExtractCallback.h CExtractCallbackImp -*/ - -#ifdef _NO_CRYPTO - #define INTERFACE_IExtractCallbackUI_Crypto(x) -#else - #define INTERFACE_IExtractCallbackUI_Crypto(x) \ - virtual HRESULT SetPassword(const UString &password) x; -#endif - -#define INTERFACE_IExtractCallbackUI(x) \ - virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) x; \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT ThereAreNoFiles() x; \ - virtual HRESULT ExtractResult(HRESULT result) x; \ - INTERFACE_IExtractCallbackUI_Crypto(x) - -struct IExtractCallbackUI: IFolderArchiveExtractCallback -{ - INTERFACE_IExtractCallbackUI(PURE) -}; - - - -#define INTERFACE_IGetProp(x) \ - STDMETHOD(GetProp)(PROPID propID, PROPVARIANT *value) x; \ - -DECL_INTERFACE_SUB(IGetProp, IUnknown, 0x01, 0x20) -{ - INTERFACE_IGetProp(PURE) -}; - -#define INTERFACE_IFolderExtractToStreamCallback(x) \ - STDMETHOD(UseExtractToStream)(Int32 *res) x; \ - STDMETHOD(GetStream7)(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp) x; \ - STDMETHOD(PrepareOperation7)(Int32 askExtractMode) x; \ - STDMETHOD(SetOperationResult7)(Int32 resultEOperationResult, Int32 encrypted) x; \ - -DECL_INTERFACE_SUB(IFolderExtractToStreamCallback, IUnknown, 0x01, 0x30) -{ - INTERFACE_IFolderExtractToStreamCallback(PURE) -}; - - -#endif +// IFileExtractCallback.h + +#ifndef ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H +#define ZIP7_INC_I_FILE_EXTRACT_CALLBACK_H + +#include "../../../Common/MyString.h" + +#include "../../IDecl.h" + +#include "LoadCodecs.h" +#include "OpenArchive.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_FOLDERARC_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 1, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_FOLDERARC(i, n) \ + Z7_IFACE_CONSTR_FOLDERARC_SUB(i, IUnknown, n) + +namespace NOverwriteAnswer +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel + }; +} + + +/* ---------- IFolderArchiveExtractCallback ---------- +is implemented by + Console/ExtractCallbackConsole.h CExtractCallbackConsole + FileManager/ExtractCallback.h CExtractCallbackImp + FAR/ExtractEngine.cpp CExtractCallBackImp: (QueryInterface is not supported) + +IID_IFolderArchiveExtractCallback is requested by: + - Agent/ArchiveFolder.cpp + CAgentFolder::CopyTo(..., IFolderOperationsExtractCallback *callback) + is sent to IArchiveFolder::Extract() + + - FileManager/PanelCopy.cpp + CPanel::CopyTo(), if (options->testMode) + is sent to IArchiveFolder::Extract() + + IFolderArchiveExtractCallback is used by Common/ArchiveExtractCallback.cpp +*/ + +#define Z7_IFACEM_IFolderArchiveExtractCallback(x) \ + x(AskOverwrite( \ + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, \ + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, \ + Int32 *answer)) \ + x(PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) \ + x(MessageError(const wchar_t *message)) \ + x(SetOperationResult(Int32 opRes, Int32 encrypted)) \ + +Z7_IFACE_CONSTR_FOLDERARC_SUB(IFolderArchiveExtractCallback, IProgress, 0x07) + +#define Z7_IFACEM_IFolderArchiveExtractCallback2(x) \ + x(ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveExtractCallback2, 0x08) + +/* ---------- IExtractCallbackUI ---------- +is implemented by + Console/ExtractCallbackConsole.h CExtractCallbackConsole + FileManager/ExtractCallback.h CExtractCallbackImp +*/ + +#ifdef Z7_NO_CRYPTO + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) +#else + #define Z7_IFACEM_IExtractCallbackUI_Crypto(px) \ + virtual HRESULT SetPassword(const UString &password) px +#endif + +#define Z7_IFACEN_IExtractCallbackUI(px) \ + virtual HRESULT BeforeOpen(const wchar_t *name, bool testMode) px \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) px \ + virtual HRESULT ThereAreNoFiles() px \ + virtual HRESULT ExtractResult(HRESULT result) px \ + Z7_IFACEM_IExtractCallbackUI_Crypto(px) + +// IExtractCallbackUI - is non-COM interface +// IFolderArchiveExtractCallback - is COM interface +// Z7_IFACE_DECL_PURE_(IExtractCallbackUI, IFolderArchiveExtractCallback) +Z7_IFACE_DECL_PURE(IExtractCallbackUI) + + + +#define Z7_IFACEM_IGetProp(x) \ + x(GetProp(PROPID propID, PROPVARIANT *value)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IGetProp, 0x20) + +#define Z7_IFACEM_IFolderExtractToStreamCallback(x) \ + x(UseExtractToStream(Int32 *res)) \ + x(GetStream7(const wchar_t *name, Int32 isDir, ISequentialOutStream **outStream, Int32 askExtractMode, IGetProp *getProp)) \ + x(PrepareOperation7(Int32 askExtractMode)) \ + x(SetOperationResult8(Int32 resultEOperationResult, Int32 encrypted, UInt64 size)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderExtractToStreamCallback, 0x31) + +Z7_PURE_INTERFACES_END + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/LoadCodecs.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/LoadCodecs.cpp 2015-09-01 19:01:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -1,1082 +1,1337 @@ -// LoadCodecs.cpp - -/* -EXTERNAL_CODECS ---------------- - CCodecs::Load() tries to detect the directory with plugins. - It stops the checking, if it can find any of the following items: - - 7z.dll file - - "Formats" subdir - - "Codecs" subdir - The order of check: - 1) directory of client executable - 2) WIN32: directory for REGISTRY item [HKEY_*\Software\7-Zip\Path**] - The order for HKEY_* : Path** : - - HKEY_CURRENT_USER : PathXX - - HKEY_LOCAL_MACHINE : PathXX - - HKEY_CURRENT_USER : Path - - HKEY_LOCAL_MACHINE : Path - PathXX is Path32 in 32-bit code - PathXX is Path64 in 64-bit code - - -EXPORT_CODECS -------------- - if (EXTERNAL_CODECS) is defined, then the code exports internal - codecs of client from CCodecs object to external plugins. - 7-Zip doesn't use that feature. 7-Zip uses the scheme: - - client application without internal plugins. - - 7z.dll module contains all (or almost all) plugins. - 7z.dll can use codecs from another plugins, if required. -*/ - - -#include "StdAfx.h" - -#include "../../../../C/7zVersion.h" - -#include "../../../Common/MyCom.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariant.h" - -#include "LoadCodecs.h" - -using namespace NWindows; - -#ifdef NEW_FOLDER_INTERFACE -#include "../../../Common/StringToInt.h" -#endif - -#include "../../ICoder.h" -#include "../../Common/RegisterArc.h" - -#ifdef EXTERNAL_CODECS - -// #define EXPORT_CODECS - -#endif - -#ifdef NEW_FOLDER_INTERFACE -extern HINSTANCE g_hInstance; -#include "../../../Windows/ResourceString.h" -static const UINT kIconTypesResId = 100; -#endif - -#ifdef EXTERNAL_CODECS - -#include "../../../Windows/FileFind.h" -#include "../../../Windows/DLL.h" - -#ifdef _WIN32 -#include "../../../Windows/FileName.h" -#include "../../../Windows/Registry.h" -#endif - -using namespace NFile; - - -#define kCodecsFolderName FTEXT("Codecs") -#define kFormatsFolderName FTEXT("Formats") - - -static CFSTR kMainDll = - // #ifdef _WIN32 -#ifdef USE_LIB7Z_DLL - FTEXT("lib7z.dll"); -#else - FTEXT("7z.dll"); -#endif - // #else - // FTEXT("7z.so"); - // #endif - - -#ifdef _WIN32 - -static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip"); -static LPCWSTR kProgramPathValue = L"Path"; -static LPCWSTR kProgramPath2Value = L"Path" - #ifdef _WIN64 - L"64"; - #else - L"32"; - #endif - -static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path) -{ - NRegistry::CKey key; - if (key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS) - { - UString pathU; - if (key.QueryValue(value, pathU) == ERROR_SUCCESS) - { - path = us2fs(pathU); - NName::NormalizeDirPathPrefix(path); - return NFind::DoesFileExist(path + kMainDll); - } - } - return false; -} - -#endif // _WIN32 - -#endif // EXTERNAL_CODECS - - -static const unsigned kNumArcsMax = 64; -static unsigned g_NumArcs = 0; -static const CArcInfo *g_Arcs[kNumArcsMax]; - -void RegisterArc(const CArcInfo *arcInfo) throw() -{ - if (g_NumArcs < kNumArcsMax) - { - g_Arcs[g_NumArcs] = arcInfo; - g_NumArcs++; - } -} - -static void SplitString(const UString &srcString, UStringVector &destStrings) -{ - destStrings.Clear(); - UString s; - unsigned len = srcString.Len(); - if (len == 0) - return; - for (unsigned i = 0; i < len; i++) - { - wchar_t c = srcString[i]; - if (c == L' ') - { - if (!s.IsEmpty()) - { - destStrings.Add(s); - s.Empty(); - } - } - else - s += c; - } - if (!s.IsEmpty()) - destStrings.Add(s); -} - -int CArcInfoEx::FindExtension(const UString &ext) const -{ - FOR_VECTOR (i, Exts) - if (ext.IsEqualTo_NoCase(Exts[i].Ext)) - return i; - return -1; -} - -void CArcInfoEx::AddExts(const UString &ext, const UString &addExt) -{ - UStringVector exts, addExts; - SplitString(ext, exts); - SplitString(addExt, addExts); - FOR_VECTOR (i, exts) - { - CArcExtInfo extInfo; - extInfo.Ext = exts[i]; - if (i < addExts.Size()) - { - extInfo.AddExt = addExts[i]; - if (extInfo.AddExt == L"*") - extInfo.AddExt.Empty(); - } - Exts.Add(extInfo); - } -} - -#ifndef _SFX - -static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector &signatures) -{ - signatures.Clear(); - while (size > 0) - { - unsigned len = *data++; - size--; - if (len > size) - return false; - signatures.AddNew().CopyFrom(data, len); - data += len; - size -= len; - } - return true; -} - -#endif // _SFX - -#ifdef EXTERNAL_CODECS - -static FString GetBaseFolderPrefixFromRegistry() -{ - FString moduleFolderPrefix = NDLL::GetModuleDirPrefix(); - #ifdef _WIN32 - if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) && - !NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) && - !NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName)) - { - FString path; - if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path; - if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPath2Value, path)) return path; - if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPathValue, path)) return path; - if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path; - } - #endif - return moduleFolderPrefix; -} - - -static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 index, - PROPID propId, CLSID &clsId, bool &isAssigned) -{ - NCOM::CPropVariant prop; - isAssigned = false; - RINOK(getMethodProperty(index, propId, &prop)); - if (prop.vt == VT_BSTR) - { - if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) - return E_FAIL; - isAssigned = true; - clsId = *(const GUID *)prop.bstrVal; - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -HRESULT CCodecs::LoadCodecs() -{ - CCodecLib &lib = Libs.Back(); - - lib.CreateDecoder = (Func_CreateDecoder)lib.Lib.GetProc("CreateDecoder"); - lib.CreateEncoder = (Func_CreateEncoder)lib.Lib.GetProc("CreateEncoder"); - lib.GetMethodProperty = (Func_GetMethodProperty)lib.Lib.GetProc("GetMethodProperty"); - - if (lib.GetMethodProperty) - { - UInt32 numMethods = 1; - Func_GetNumberOfMethods getNumberOfMethods = (Func_GetNumberOfMethods)lib.Lib.GetProc("GetNumberOfMethods"); - if (getNumberOfMethods) - { - RINOK(getNumberOfMethods(&numMethods)); - } - for (UInt32 i = 0; i < numMethods; i++) - { - CDllCodecInfo info; - info.LibIndex = Libs.Size() - 1; - info.CodecIndex = i; - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)); - RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)); - Codecs.Add(info); - } - } - - Func_GetHashers getHashers = (Func_GetHashers)lib.Lib.GetProc("GetHashers"); - if (getHashers) - { - RINOK(getHashers(&lib.ComHashers)); - if (lib.ComHashers) - { - UInt32 numMethods = lib.ComHashers->GetNumHashers(); - for (UInt32 i = 0; i < numMethods; i++) - { - CDllHasherInfo info; - info.LibIndex = Libs.Size() - 1; - info.HasherIndex = i; - Hashers.Add(info); - } - } - } - - return S_OK; -} - -static HRESULT GetProp( - Func_GetHandlerProperty getProp, - Func_GetHandlerProperty2 getProp2, - UInt32 index, PROPID propID, NCOM::CPropVariant &prop) -{ - if (getProp2) - return getProp2(index, propID, &prop);; - return getProp(propID, &prop); -} - -static HRESULT GetProp_Bool( - Func_GetHandlerProperty getProp, - Func_GetHandlerProperty2 getProp2, - UInt32 index, PROPID propID, bool &res) -{ - res = false; - NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); - if (prop.vt == VT_BOOL) - res = VARIANT_BOOLToBool(prop.boolVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static HRESULT GetProp_UInt32( - Func_GetHandlerProperty getProp, - Func_GetHandlerProperty2 getProp2, - UInt32 index, PROPID propID, UInt32 &res, bool &defined) -{ - res = 0; - defined = false; - NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); - if (prop.vt == VT_UI4) - { - res = prop.ulVal; - defined = true; - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static HRESULT GetProp_String( - Func_GetHandlerProperty getProp, - Func_GetHandlerProperty2 getProp2, - UInt32 index, PROPID propID, UString &res) -{ - res.Empty(); - NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); - if (prop.vt == VT_BSTR) - res.SetFromBstr(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static HRESULT GetProp_RawData( - Func_GetHandlerProperty getProp, - Func_GetHandlerProperty2 getProp2, - UInt32 index, PROPID propID, CByteBuffer &bb) -{ - bb.Free(); - NCOM::CPropVariant prop; - RINOK(GetProp(getProp, getProp2, index, propID, prop)); - if (prop.vt == VT_BSTR) - { - UINT len = ::SysStringByteLen(prop.bstrVal); - bb.CopyFrom((const Byte *)prop.bstrVal, len); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static const UInt32 kArcFlagsPars[] = -{ - NArchive::NHandlerPropID::kKeepName, NArcInfoFlags::kKeepName, - NArchive::NHandlerPropID::kAltStreams, NArcInfoFlags::kAltStreams, - NArchive::NHandlerPropID::kNtSecure, NArcInfoFlags::kNtSecure -}; - -HRESULT CCodecs::LoadFormats() -{ - const NDLL::CLibrary &lib = Libs.Back().Lib; - - Func_GetHandlerProperty getProp = NULL; - Func_GetHandlerProperty2 getProp2 = (Func_GetHandlerProperty2)lib.GetProc("GetHandlerProperty2"); - Func_GetIsArc getIsArc = (Func_GetIsArc)lib.GetProc("GetIsArc"); - - UInt32 numFormats = 1; - - if (getProp2) - { - Func_GetNumberOfFormats getNumberOfFormats = (Func_GetNumberOfFormats)lib.GetProc("GetNumberOfFormats"); - if (getNumberOfFormats) - { - RINOK(getNumberOfFormats(&numFormats)); - } - } - else - { - getProp = (Func_GetHandlerProperty)lib.GetProc("GetHandlerProperty"); - if (!getProp) - return S_OK; - } - - for (UInt32 i = 0; i < numFormats; i++) - { - CArcInfoEx item; - item.LibIndex = Libs.Size() - 1; - item.FormatIndex = i; - - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)); - - { - NCOM::CPropVariant prop; - if (GetProp(getProp, getProp2, i, NArchive::NHandlerPropID::kClassID, prop) != S_OK) - continue; - if (prop.vt != VT_BSTR) - continue; - if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) - return E_FAIL; - item.ClassID = *(const GUID *)prop.bstrVal; - prop.Clear(); - } - - UString ext, addExt; - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)); - RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)); - item.AddExts(ext, addExt); - - GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled); - bool flags_Defined = false; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)); - item.NewInterface = flags_Defined; - if (!flags_Defined) // && item.UpdateEnabled - { - // support for DLL version before 9.31: - for (unsigned j = 0; j < ARRAY_SIZE(kArcFlagsPars); j += 2) - { - bool val = false; - GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val); - if (val) - item.Flags |= kArcFlagsPars[j + 1]; - } - } - - CByteBuffer sig; - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kSignature, sig)); - if (sig.Size() != 0) - item.Signatures.Add(sig); - else - { - RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)); - ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures); - } - - bool signatureOffset_Defined; - RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)); - - // bool version_Defined; - // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined)); - - if (getIsArc) - getIsArc(i, &item.IsArcFunc); - - Formats.Add(item); - } - return S_OK; -} - -#ifdef _7ZIP_LARGE_PAGES -extern "C" -{ - extern size_t g_LargePageSize; -} -#endif - -HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK) -{ - if (loadedOK) - *loadedOK = false; -#ifdef _WIN32 - if (needCheckDll) - { - NDLL::CLibrary lib; - if (!lib.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE)) - return S_OK; - } -#endif - Libs.AddNew(); - CCodecLib &lib = Libs.Back(); - lib.Path = dllPath; - bool used = false; - HRESULT res = S_OK; - - if (lib.Lib.Load(dllPath)) - { - if (loadedOK) - *loadedOK = true; - #ifdef NEW_FOLDER_INTERFACE - lib.LoadIcons(); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (g_LargePageSize != 0) - { - Func_SetLargePageMode setLargePageMode = (Func_SetLargePageMode)lib.Lib.GetProc("SetLargePageMode"); - if (setLargePageMode) - setLargePageMode(); - } - #endif - - if (CaseSensitiveChange) - { - Func_SetCaseSensitive setCaseSensitive = (Func_SetCaseSensitive)lib.Lib.GetProc("SetCaseSensitive"); - if (setCaseSensitive) - setCaseSensitive(CaseSensitive ? 1 : 0); - } - - lib.CreateObject = (Func_CreateObject)lib.Lib.GetProc("CreateObject"); - if (lib.CreateObject) - { - unsigned startSize = Codecs.Size() + Hashers.Size(); - res = LoadCodecs(); - used = (startSize != Codecs.Size() + Hashers.Size()); - if (res == S_OK) - { - startSize = Formats.Size(); - res = LoadFormats(); - if (startSize != Formats.Size()) - used = true; - } - } - } - - if (!used) - Libs.DeleteBack(); - - return res; -} - -HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix) -{ - NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK); - NFile::NFind::CFileInfo fi; - while (enumerator.Next(fi)) - { - if (fi.IsDir()) - continue; - RINOK(LoadDll(folderPrefix + fi.Name, true)); - } - return S_OK; -} - -void CCodecs::CloseLibs() -{ - // OutputDebugStringA("~CloseLibs start"); - /* - WIN32: FreeLibrary() (CLibrary::Free()) function doesn't work as expected, - if it's called from another FreeLibrary() call. - So we need to call FreeLibrary() before global destructors. - - Also we free global links from DLLs to object of this module before CLibrary::Free() call. - */ - - FOR_VECTOR(i, Libs) - { - const CCodecLib &lib = Libs[i]; - if (lib.SetCodecs) - lib.SetCodecs(NULL); - } - - // OutputDebugStringA("~CloseLibs after SetCodecs"); - Libs.Clear(); - // OutputDebugStringA("~CloseLibs end"); -} - -#endif // EXTERNAL_CODECS - - -HRESULT CCodecs::Load() -{ - #ifdef NEW_FOLDER_INTERFACE - #ifdef _WIN32 - InternalIcons.LoadIcons(g_hInstance); - #endif - #endif - - Formats.Clear(); - - #ifdef EXTERNAL_CODECS - MainDll_ErrorPath.Empty(); - Codecs.Clear(); - Hashers.Clear(); - #endif - - for (UInt32 i = 0; i < g_NumArcs; i++) - { - const CArcInfo &arc = *g_Arcs[i]; - CArcInfoEx item; - - item.Name.SetFromAscii(arc.Name); - item.CreateInArchive = arc.CreateInArchive; - item.IsArcFunc = arc.IsArc; - item.Flags = arc.Flags; - - { - UString e, ae; - if (arc.Ext) - e.SetFromAscii(arc.Ext); - if (arc.AddExt) - ae.SetFromAscii(arc.AddExt); - item.AddExts(e, ae); - } - - #ifndef _SFX - - item.CreateOutArchive = arc.CreateOutArchive; - item.UpdateEnabled = (arc.CreateOutArchive != NULL); - item.SignatureOffset = arc.SignatureOffset; - // item.Version = MY_VER_MIX; - item.NewInterface = true; - - if (arc.IsMultiSignature()) - ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures); - else - item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize); - - #endif - - Formats.Add(item); - } - - #ifdef EXTERNAL_CODECS - const FString baseFolder = GetBaseFolderPrefixFromRegistry(); - { - bool loadedOK; - RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)); - if (!loadedOK) - MainDll_ErrorPath = kMainDll; - } - RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR)); - RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR)); - - NeedSetLibCodecs = true; - - if (Libs.Size() == 0) - NeedSetLibCodecs = false; - else if (Libs.Size() == 1) - { - // we don't need to set ISetCompressCodecsInfo, if all arcs and codecs are in one external module. - #ifndef EXPORT_CODECS - if (g_NumArcs == 0) - NeedSetLibCodecs = false; - #endif - } - - if (NeedSetLibCodecs) - { - /* 15.00: now we call global function in DLL: SetCompressCodecsInfo(c) - old versions called only ISetCompressCodecsInfo::SetCompressCodecsInfo(c) for each archive handler */ - - FOR_VECTOR(i, Libs) - { - CCodecLib &lib = Libs[i]; - lib.SetCodecs = (Func_SetCodecs)lib.Lib.GetProc("SetCodecs"); - if (lib.SetCodecs) - { - RINOK(lib.SetCodecs(this)); - } - } - } - - #endif - - return S_OK; -} - -#ifndef _SFX - -int CCodecs::FindFormatForArchiveName(const UString &arcPath) const -{ - int dotPos = arcPath.ReverseFind_Dot(); - if (dotPos <= arcPath.ReverseFind_PathSepar()) - return -1; - const UString ext = arcPath.Ptr(dotPos + 1); - if (ext.IsEmpty()) - return -1; - if (ext.IsEqualTo_Ascii_NoCase("exe")) - return -1; - FOR_VECTOR (i, Formats) - { - const CArcInfoEx &arc = Formats[i]; - /* - if (!arc.UpdateEnabled) - continue; - */ - if (arc.FindExtension(ext) >= 0) - return i; - } - return -1; -} - -int CCodecs::FindFormatForExtension(const UString &ext) const -{ - if (ext.IsEmpty()) - return -1; - FOR_VECTOR (i, Formats) - if (Formats[i].FindExtension(ext) >= 0) - return i; - return -1; -} - -int CCodecs::FindFormatForArchiveType(const UString &arcType) const -{ - FOR_VECTOR (i, Formats) - if (Formats[i].Name.IsEqualTo_NoCase(arcType)) - return i; - return -1; -} - -bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const -{ - formatIndices.Clear(); - for (unsigned pos = 0; pos < arcType.Len();) - { - int pos2 = arcType.Find(L'.', pos); - if (pos2 < 0) - pos2 = arcType.Len(); - const UString name = arcType.Mid(pos, pos2 - pos); - if (name.IsEmpty()) - return false; - int index = FindFormatForArchiveType(name); - if (index < 0 && name != L"*") - { - formatIndices.Clear(); - return false; - } - formatIndices.Add(index); - pos = pos2 + 1; - } - return true; -} - -#endif // _SFX - - -#ifdef NEW_FOLDER_INTERFACE - -void CCodecIcons::LoadIcons(HMODULE m) -{ -#ifdef _WIN32 - UString iconTypes; - MyLoadString(m, kIconTypesResId, iconTypes); - UStringVector pairs; - SplitString(iconTypes, pairs); - FOR_VECTOR (i, pairs) - { - const UString &s = pairs[i]; - int pos = s.Find(L':'); - CIconPair iconPair; - iconPair.IconIndex = -1; - if (pos < 0) - pos = s.Len(); - else - { - UString num = s.Ptr(pos + 1); - if (!num.IsEmpty()) - { - const wchar_t *end; - iconPair.IconIndex = ConvertStringToUInt32(num, &end); - if (*end != 0) - continue; - } - } - iconPair.Ext = s.Left(pos); - IconPairs.Add(iconPair); - } -#endif -} - -bool CCodecIcons::FindIconIndex(const UString &ext, int &iconIndex) const -{ -#ifdef _WIN32 - iconIndex = -1; - FOR_VECTOR (i, IconPairs) - { - const CIconPair &pair = IconPairs[i]; - if (ext.IsEqualTo_NoCase(pair.Ext)) - { - iconIndex = pair.IconIndex; - return true; - } - } -#endif - return false; -} - -#endif // NEW_FOLDER_INTERFACE - - -#ifdef EXTERNAL_CODECS - -// #define EXPORT_CODECS - -#ifdef EXPORT_CODECS - -extern unsigned g_NumCodecs; -STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject); -STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject); -STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); -#define NUM_EXPORT_CODECS g_NumCodecs - -extern unsigned g_NumHashers; -STDAPI CreateHasher(UInt32 index, IHasher **hasher); -STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); -#define NUM_EXPORT_HASHERS g_NumHashers - -#else // EXPORT_CODECS - -#define NUM_EXPORT_CODECS 0 -#define NUM_EXPORT_HASHERS 0 - -#endif // EXPORT_CODECS - -STDMETHODIMP CCodecs::GetNumMethods(UInt32 *numMethods) -{ - *numMethods = NUM_EXPORT_CODECS - #ifdef EXTERNAL_CODECS - + Codecs.Size() - #endif - ; - return S_OK; -} - -STDMETHODIMP CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - return GetMethodProperty(index, propID, value); - #endif - - #ifdef EXTERNAL_CODECS - const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; - - if (propID == NMethodPropID::kDecoderIsAssigned || - propID == NMethodPropID::kEncoderIsAssigned) - { - NCOM::CPropVariant prop; - prop = (bool)((propID == NMethodPropID::kDecoderIsAssigned) ? - ci.DecoderIsAssigned : - ci.EncoderIsAssigned); - prop.Detach(value); - return S_OK; - } - const CCodecLib &lib = Libs[ci.LibIndex]; - return lib.GetMethodProperty(ci.CodecIndex, propID, value); - #else - return E_FAIL; - #endif -} - -STDMETHODIMP CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder) -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - return CreateDecoder(index, iid, coder); - #endif - - #ifdef EXTERNAL_CODECS - const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; - if (ci.DecoderIsAssigned) - { - const CCodecLib &lib = Libs[ci.LibIndex]; - if (lib.CreateDecoder) - return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder); - return lib.CreateObject(&ci.Decoder, iid, (void **)coder); - } - return S_OK; - #else - return E_FAIL; - #endif -} - -STDMETHODIMP CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder) -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - return CreateEncoder(index, iid, coder); - #endif - - #ifdef EXTERNAL_CODECS - const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; - if (ci.EncoderIsAssigned) - { - const CCodecLib &lib = Libs[ci.LibIndex]; - if (lib.CreateEncoder) - return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder); - return lib.CreateObject(&ci.Encoder, iid, (void **)coder); - } - return S_OK; - #else - return E_FAIL; - #endif -} - - -STDMETHODIMP_(UInt32) CCodecs::GetNumHashers() -{ - return NUM_EXPORT_HASHERS - #ifdef EXTERNAL_CODECS - + Hashers.Size() - #endif - ; -} - -STDMETHODIMP CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - #ifdef EXPORT_CODECS - if (index < g_NumHashers) - return ::GetHasherProp(index, propID, value); - #endif - - #ifdef EXTERNAL_CODECS - const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; - return Libs[ci.LibIndex].ComHashers->GetHasherProp(ci.HasherIndex, propID, value); - #else - return E_FAIL; - #endif -} - -STDMETHODIMP CCodecs::CreateHasher(UInt32 index, IHasher **hasher) -{ - #ifdef EXPORT_CODECS - if (index < g_NumHashers) - return CreateHasher(index, hasher); - #endif - #ifdef EXTERNAL_CODECS - const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; - return Libs[ci.LibIndex].ComHashers->CreateHasher(ci.HasherIndex, hasher); - #else - return E_FAIL; - #endif -} - -int CCodecs::GetCodec_LibIndex(UInt32 index) const -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - return -1; - #endif - - #ifdef EXTERNAL_CODECS - const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; - return ci.LibIndex; - #else - return -1; - #endif -} - -int CCodecs::GetHasherLibIndex(UInt32 index) -{ - #ifdef EXPORT_CODECS - if (index < g_NumHashers) - return -1; - #endif - - #ifdef EXTERNAL_CODECS - const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; - return ci.LibIndex; - #else - return -1; - #endif -} - -bool CCodecs::GetCodec_DecoderIsAssigned(UInt32 index) const -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - { - NCOM::CPropVariant prop; - if (GetProperty(index, NMethodPropID::kDecoderIsAssigned, &prop) == S_OK) - { - if (prop.vt == VT_BOOL) - return VARIANT_BOOLToBool(prop.boolVal); - } - return false; - } - #endif - - #ifdef EXTERNAL_CODECS - return Codecs[index - NUM_EXPORT_CODECS].DecoderIsAssigned; - #else - return false; - #endif -} - -bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const -{ - #ifdef EXPORT_CODECS - if (index < g_NumCodecs) - { - NCOM::CPropVariant prop; - if (GetProperty(index, NMethodPropID::kEncoderIsAssigned, &prop) == S_OK) - { - if (prop.vt == VT_BOOL) - return VARIANT_BOOLToBool(prop.boolVal); - } - return false; - } - #endif - - #ifdef EXTERNAL_CODECS - return Codecs[index - NUM_EXPORT_CODECS].EncoderIsAssigned; - #else - return false; - #endif -} - -UInt32 CCodecs::GetCodec_NumStreams(UInt32 index) -{ - NCOM::CPropVariant prop; - RINOK(GetProperty(index, NMethodPropID::kPackStreams, &prop)); - if (prop.vt == VT_UI4) - return (UInt32)prop.ulVal; - if (prop.vt == VT_EMPTY) - return 1; - return 0; -} - -HRESULT CCodecs::GetCodec_Id(UInt32 index, UInt64 &id) -{ - NCOM::CPropVariant prop; - RINOK(GetProperty(index, NMethodPropID::kID, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - id = prop.uhVal.QuadPart; - return S_OK; -} - -AString CCodecs::GetCodec_Name(UInt32 index) -{ - AString s; - NCOM::CPropVariant prop; - if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK) - if (prop.vt == VT_BSTR) - s.SetFromWStr_if_Ascii(prop.bstrVal); - return s; -} - -UInt64 CCodecs::GetHasherId(UInt32 index) -{ - NCOM::CPropVariant prop; - if (GetHasherProp(index, NMethodPropID::kID, &prop) != S_OK) - return 0; - if (prop.vt != VT_UI8) - return 0; - return prop.uhVal.QuadPart; -} - -AString CCodecs::GetHasherName(UInt32 index) -{ - AString s; - NCOM::CPropVariant prop; - if (GetHasherProp(index, NMethodPropID::kName, &prop) == S_OK) - if (prop.vt == VT_BSTR) - s.SetFromWStr_if_Ascii(prop.bstrVal); - return s; -} - -UInt32 CCodecs::GetHasherDigestSize(UInt32 index) -{ - NCOM::CPropVariant prop; - RINOK(GetHasherProp(index, NMethodPropID::kDigestSize, &prop)); - if (prop.vt != VT_UI4) - return 0; - return prop.ulVal; -} - -#endif // EXTERNAL_CODECS +// LoadCodecs.cpp + +/* +Z7_EXTERNAL_CODECS +--------------- + CCodecs::Load() tries to detect the directory with plugins. + It stops the checking, if it can find any of the following items: + - 7z.dll file + - "Formats" subdir + - "Codecs" subdir + The order of check: + 1) directory of client executable + 2) WIN32: directory for REGISTRY item [HKEY_*\Software\7-Zip\Path**] + The order for HKEY_* : Path** : + - HKEY_CURRENT_USER : PathXX + - HKEY_LOCAL_MACHINE : PathXX + - HKEY_CURRENT_USER : Path + - HKEY_LOCAL_MACHINE : Path + PathXX is Path32 in 32-bit code + PathXX is Path64 in 64-bit code + + +EXPORT_CODECS +------------- + if (Z7_EXTERNAL_CODECS) is defined, then the code exports internal + codecs of client from CCodecs object to external plugins. + 7-Zip doesn't use that feature. 7-Zip uses the scheme: + - client application without internal plugins. + - 7z.dll module contains all (or almost all) plugins. + 7z.dll can use codecs from another plugins, if required. +*/ + + +#include "StdAfx.h" + +#include "../../../Common/MyCom.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/PropVariant.h" + +#include "LoadCodecs.h" + +#include "../../ICoder.h" +#include "../../Common/RegisterArc.h" +#include "../../Common/RegisterCodec.h" + +#ifdef Z7_EXTERNAL_CODECS +// #define EXPORT_CODECS +#endif + +#ifdef Z7_EXTERNAL_CODECS + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/DLL.h" + +#ifdef _WIN32 +#include "../../../Windows/FileName.h" +#include "../../../Windows/Registry.h" +#endif + +using namespace NWindows; +using namespace NFile; + + +#define kCodecsFolderName FTEXT("Codecs") +#define kFormatsFolderName FTEXT("Formats") + + +static CFSTR const kMainDll = + #ifdef _WIN32 + FTEXT("7z.dll"); + #else + FTEXT("7z.so"); + #endif + + +#ifdef _WIN32 + +static LPCTSTR const kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip"); +static LPCWSTR const kProgramPathValue = L"Path"; +static LPCWSTR const kProgramPath2Value = L"Path" + #ifdef _WIN64 + L"64"; + #else + L"32"; + #endif + +static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path) +{ + NRegistry::CKey key; + if (key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS) + { + UString pathU; + if (key.QueryValue(value, pathU) == ERROR_SUCCESS) + { + path = us2fs(pathU); + NName::NormalizeDirPathPrefix(path); + return NFind::DoesFileExist_Raw(path + kMainDll); + } + } + return false; +} + +#endif // _WIN32 + +#endif // Z7_EXTERNAL_CODECS + + +static const unsigned kNumArcsMax = 72; +static unsigned g_NumArcs = 0; +static const CArcInfo *g_Arcs[kNumArcsMax]; + +void RegisterArc(const CArcInfo *arcInfo) throw() +{ + if (g_NumArcs < kNumArcsMax) + { + g_Arcs[g_NumArcs] = arcInfo; + g_NumArcs++; + } + // else throw 1; +} + +/* +static void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + UString s; + unsigned len = srcString.Len(); + if (len == 0) + return; + for (unsigned i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L' ') + { + if (!s.IsEmpty()) + { + destStrings.Add(s); + s.Empty(); + } + } + else + s += c; + } + if (!s.IsEmpty()) + destStrings.Add(s); +} +*/ + +int CArcInfoEx::FindExtension(const UString &ext) const +{ + FOR_VECTOR (i, Exts) + if (ext.IsEqualTo_NoCase(Exts[i].Ext)) + return (int)i; + return -1; +} + +void CArcInfoEx::AddExts(const UString &ext, const UString &addExt) +{ + UStringVector exts, addExts; + SplitString(ext, exts); + SplitString(addExt, addExts); + FOR_VECTOR (i, exts) + { + CArcExtInfo extInfo; + extInfo.Ext = exts[i]; + if (i < addExts.Size()) + { + extInfo.AddExt = addExts[i]; + if (extInfo.AddExt.IsEqualTo("*")) + extInfo.AddExt.Empty(); + } + Exts.Add(extInfo); + } +} + +#ifndef Z7_SFX + +static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector &signatures) +{ + signatures.Clear(); + while (size != 0) + { + const unsigned len = *data++; + size--; + if (len > size) + return false; + signatures.AddNew().CopyFrom(data, len); + data += len; + size -= len; + } + return true; +} + +#endif // Z7_SFX + +// #include + +#ifdef Z7_EXTERNAL_CODECS + +static FString GetBaseFolderPrefixFromRegistry() +{ + FString moduleFolderPrefix = NDLL::GetModuleDirPrefix(); + + #ifdef _WIN32 + if ( !NFind::DoesFileOrDirExist(moduleFolderPrefix + kMainDll) + && !NFind::DoesFileOrDirExist(moduleFolderPrefix + kCodecsFolderName) + && !NFind::DoesFileOrDirExist(moduleFolderPrefix + kFormatsFolderName)) + { + FString path; + if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path; + if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPath2Value, path)) return path; + if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPathValue, path)) return path; + if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path; + } + #endif + + // printf("\nmoduleFolderPrefix = %s\n", (const char *)GetAnsiString(moduleFolderPrefix)); + return moduleFolderPrefix; +} + + +static HRESULT GetCoderClass(Func_GetMethodProperty getMethodProperty, UInt32 index, + PROPID propId, CLSID &clsId, bool &isAssigned) +{ + NCOM::CPropVariant prop; + isAssigned = false; + RINOK(getMethodProperty(index, propId, &prop)) + if (prop.vt == VT_BSTR) + { + if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) + return E_FAIL; + isAssigned = true; + clsId = *(const GUID *)(const void *)prop.bstrVal; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +static HRESULT GetMethodBoolProp(Func_GetMethodProperty getMethodProperty, UInt32 index, + PROPID propId, bool &resVal, bool &isAssigned) +{ + NCOM::CPropVariant prop; + resVal = false; + isAssigned = false; + RINOK(getMethodProperty(index, propId, &prop)) + if (prop.vt == VT_BOOL) + { + isAssigned = true; + resVal = VARIANT_BOOLToBool(prop.boolVal); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#ifdef _WIN32 +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +#endif + +#define MY_GET_FUNC(dest, type, lib, func) \ + dest = Z7_GET_PROC_ADDRESS(type, lib.Get_HMODULE(), func); +// #define MY_GET_FUNC(dest, type, func) dest = (type)(func); + +#define MY_GET_FUNC_LOC(dest, type, lib, func) \ + type dest; MY_GET_FUNC(dest, type, lib, func) + +HRESULT CCodecs::LoadCodecs() +{ + CCodecLib &lib = Libs.Back(); + + MY_GET_FUNC (lib.CreateDecoder, Func_CreateDecoder, lib.Lib, "CreateDecoder") + MY_GET_FUNC (lib.CreateEncoder, Func_CreateEncoder, lib.Lib, "CreateEncoder") + MY_GET_FUNC (lib.GetMethodProperty, Func_GetMethodProperty, lib.Lib, "GetMethodProperty") + + if (lib.GetMethodProperty) + { + UInt32 numMethods = 1; + MY_GET_FUNC_LOC (getNumberOfMethods, Func_GetNumberOfMethods, lib.Lib, "GetNumberOfMethods") + if (getNumberOfMethods) + { + RINOK(getNumberOfMethods(&numMethods)) + } + for (UInt32 i = 0; i < numMethods; i++) + { + CDllCodecInfo info; + info.LibIndex = Libs.Size() - 1; + info.CodecIndex = i; + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned)) + RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned)) + RINOK(GetMethodBoolProp(lib.GetMethodProperty, i, NMethodPropID::kIsFilter, info.IsFilter, info.IsFilter_Assigned)) + Codecs.Add(info); + } + } + + MY_GET_FUNC_LOC (getHashers, Func_GetHashers, lib.Lib, "GetHashers") + if (getHashers) + { + RINOK(getHashers(&lib.ComHashers)) + if (lib.ComHashers) + { + UInt32 numMethods = lib.ComHashers->GetNumHashers(); + for (UInt32 i = 0; i < numMethods; i++) + { + CDllHasherInfo info; + info.LibIndex = Libs.Size() - 1; + info.HasherIndex = i; + Hashers.Add(info); + } + } + } + + return S_OK; +} + +static HRESULT GetProp( + Func_GetHandlerProperty getProp, + Func_GetHandlerProperty2 getProp2, + UInt32 index, PROPID propID, NCOM::CPropVariant &prop) +{ + if (getProp2) + return getProp2(index, propID, &prop); + return getProp(propID, &prop); +} + +static HRESULT GetProp_Bool( + Func_GetHandlerProperty getProp, + Func_GetHandlerProperty2 getProp2, + UInt32 index, PROPID propID, bool &res) +{ + res = false; + NCOM::CPropVariant prop; + RINOK(GetProp(getProp, getProp2, index, propID, prop)) + if (prop.vt == VT_BOOL) + res = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static HRESULT GetProp_UInt32( + Func_GetHandlerProperty getProp, + Func_GetHandlerProperty2 getProp2, + UInt32 index, PROPID propID, UInt32 &res, bool &defined) +{ + res = 0; + defined = false; + NCOM::CPropVariant prop; + RINOK(GetProp(getProp, getProp2, index, propID, prop)) + if (prop.vt == VT_UI4) + { + res = prop.ulVal; + defined = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static HRESULT GetProp_String( + Func_GetHandlerProperty getProp, + Func_GetHandlerProperty2 getProp2, + UInt32 index, PROPID propID, UString &res) +{ + res.Empty(); + NCOM::CPropVariant prop; + RINOK(GetProp(getProp, getProp2, index, propID, prop)) + if (prop.vt == VT_BSTR) + res.SetFromBstr(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static HRESULT GetProp_RawData( + Func_GetHandlerProperty getProp, + Func_GetHandlerProperty2 getProp2, + UInt32 index, PROPID propID, CByteBuffer &bb) +{ + bb.Free(); + NCOM::CPropVariant prop; + RINOK(GetProp(getProp, getProp2, index, propID, prop)) + if (prop.vt == VT_BSTR) + { + UINT len = ::SysStringByteLen(prop.bstrVal); + bb.CopyFrom((const Byte *)prop.bstrVal, len); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static const UInt32 kArcFlagsPars[] = +{ + NArchive::NHandlerPropID::kKeepName, NArcInfoFlags::kKeepName, + NArchive::NHandlerPropID::kAltStreams, NArcInfoFlags::kAltStreams, + NArchive::NHandlerPropID::kNtSecure, NArcInfoFlags::kNtSecure +}; + +HRESULT CCodecs::LoadFormats() +{ + const NDLL::CLibrary &lib = Libs.Back().Lib; + + Func_GetHandlerProperty getProp = NULL; + MY_GET_FUNC_LOC (getProp2, Func_GetHandlerProperty2, lib, "GetHandlerProperty2") + MY_GET_FUNC_LOC (getIsArc, Func_GetIsArc, lib, "GetIsArc") + + UInt32 numFormats = 1; + + if (getProp2) + { + MY_GET_FUNC_LOC (getNumberOfFormats, Func_GetNumberOfFormats, lib, "GetNumberOfFormats") + if (getNumberOfFormats) + { + RINOK(getNumberOfFormats(&numFormats)) + } + } + else + { + MY_GET_FUNC (getProp, Func_GetHandlerProperty, lib, "GetHandlerProperty") + if (!getProp) + return S_OK; + } + + for (UInt32 i = 0; i < numFormats; i++) + { + CArcInfoEx item; + item.LibIndex = (int)(Libs.Size() - 1); + item.FormatIndex = i; + + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kName, item.Name)) + + { + NCOM::CPropVariant prop; + if (GetProp(getProp, getProp2, i, NArchive::NHandlerPropID::kClassID, prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID)) + return E_FAIL; + item.ClassID = *(const GUID *)(const void *)prop.bstrVal; + prop.Clear(); + } + + UString ext, addExt; + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kExtension, ext)) + RINOK(GetProp_String(getProp, getProp2, i, NArchive::NHandlerPropID::kAddExtension, addExt)) + item.AddExts(ext, addExt); + + GetProp_Bool(getProp, getProp2, i, NArchive::NHandlerPropID::kUpdate, item.UpdateEnabled); + bool flags_Defined = false; + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kFlags, item.Flags, flags_Defined)) + item.NewInterface = flags_Defined; + if (!flags_Defined) // && item.UpdateEnabled + { + // support for DLL version before 9.31: + for (unsigned j = 0; j < Z7_ARRAY_SIZE(kArcFlagsPars); j += 2) + { + bool val = false; + GetProp_Bool(getProp, getProp2, i, kArcFlagsPars[j], val); + if (val) + 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)) + if (sig.Size() != 0) + item.Signatures.Add(sig); + else + { + RINOK(GetProp_RawData(getProp, getProp2, i, NArchive::NHandlerPropID::kMultiSignature, sig)) + ParseSignatures(sig, (unsigned)sig.Size(), item.Signatures); + } + + bool signatureOffset_Defined; + RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kSignatureOffset, item.SignatureOffset, signatureOffset_Defined)) + + // bool version_Defined; + // RINOK(GetProp_UInt32(getProp, getProp2, i, NArchive::NHandlerPropID::kVersion, item.Version, version_Defined)); + + if (getIsArc) + getIsArc(i, &item.IsArcFunc); + + Formats.Add(item); + } + return S_OK; +} + +#ifdef Z7_LARGE_PAGES +extern "C" +{ + extern SIZE_T g_LargePageSize; +} +#endif + + +void CCodecs::AddLastError(const FString &path) +{ + const HRESULT res = GetLastError_noZero_HRESULT(); + CCodecError &error = Errors.AddNew(); + error.Path = path; + error.ErrorCode = res; +} + + +static bool IsSupportedDll(CCodecLib &lib) +{ + MY_GET_FUNC_LOC ( + f_GetModuleProp, + Func_GetModuleProp, lib.Lib, + "GetModuleProp") + /* p7zip and 7-Zip before v23 used virtual destructor in IUnknown, + if _WIN32 is not defined */ + UInt32 flags = + #ifdef _WIN32 + NModuleInterfaceType::k_IUnknown_VirtDestructor_No; + #else + NModuleInterfaceType::k_IUnknown_VirtDestructor_Yes; + #endif + if (f_GetModuleProp) + { + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kInterfaceType, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + flags = prop.ulVal; + else if (prop.vt != VT_EMPTY) + return false; + } + } + { + NCOM::CPropVariant prop; + if (f_GetModuleProp(NModulePropID::kVersion, &prop) == S_OK) + { + if (prop.vt == VT_UI4) + lib.Version = prop.ulVal; + } + } + } + if ( + flags + // (flags & NModuleFlags::kMask) + != NModuleInterfaceType::k_IUnknown_VirtDestructor_ThisModule) + return false; + return true; +} + + +HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll, bool *loadedOK) +{ + if (loadedOK) + *loadedOK = false; + + // needCheckDll = 1; + + #ifdef _WIN32 + if (needCheckDll) + { + NDLL::CLibrary lib; + if (!lib.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE)) + { + /* if is not win32 + // %1 is not a valid Win32 application. + // #define ERROR_BAD_EXE_FORMAT 193L + */ + // return GetLastError_noZero_HRESULT(); + const DWORD lastError = GetLastError(); + if (lastError != ERROR_BAD_EXE_FORMAT) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "cannot load file as datafile library"; + error.ErrorCode = HRESULT_FROM_WIN32(lastError); + } + return S_OK; + } + } + #else + UNUSED_VAR(needCheckDll) + #endif + + Libs.AddNew(); + CCodecLib &lib = Libs.Back(); + lib.Path = dllPath; + bool used = false; + // HRESULT res = S_OK; + + if (lib.Lib.Load(dllPath)) + { + if (!IsSupportedDll(lib)) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "the module is not compatible with program"; + } + else + { + if (loadedOK) + *loadedOK = true; + /* + #ifdef NEW_FOLDER_INTERFACE + lib.LoadIcons(); + #endif + */ + + /* + { + MY_GET_FUNC_LOC (_libStartup, Func_libStartup, lib.Lib, "LibStartup") + if (_libStartup) + { + HRESULT res = _libStartup(); + if (res != 0) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.ErrorCode = res; + } + } + } + */ + + #ifdef Z7_LARGE_PAGES + if (g_LargePageSize != 0) + { + MY_GET_FUNC_LOC (setLargePageMode, Func_SetLargePageMode, lib.Lib, "SetLargePageMode") + if (setLargePageMode) + setLargePageMode(); + } + #endif + + if (CaseSensitive_Change) + { + MY_GET_FUNC_LOC (setCaseSensitive, Func_SetCaseSensitive, lib.Lib, "SetCaseSensitive") + if (setCaseSensitive) + setCaseSensitive(CaseSensitive ? 1 : 0); + } + + /* + { + MY_GET_FUNC_LOC (setClientVersion, Func_SetClientVersion, lib.Lib, "SetClientVersion") + if (setClientVersion) + { + // const UInt32 kVersion = (MY_VER_MAJOR << 16) | MY_VER_MINOR; + setClientVersion(g_ClientVersion); + } + } + */ + + + MY_GET_FUNC (lib.CreateObject, Func_CreateObject, lib.Lib, "CreateObject") + { + unsigned startSize = Codecs.Size() + Hashers.Size(); + HRESULT res = LoadCodecs(); + if (startSize != Codecs.Size() + Hashers.Size()) + used = true; + if (res == S_OK && lib.CreateObject) + { + startSize = Formats.Size(); + res = LoadFormats(); + if (startSize != Formats.Size()) + used = true; + } + if (res != S_OK) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.ErrorCode = res; + } + } + // plugins can use non-7-zip dlls, so we silently ignore non7zip DLLs + /* + if (!used) + { + CCodecError &error = Errors.AddNew(); + error.Path = dllPath; + error.Message = "no 7-Zip code"; + } + */ + } + } + else + { + AddLastError(dllPath); + } + + if (!used) + Libs.DeleteBack(); + + return S_OK; +} + +HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPath) +{ + if (!NFile::NFind::DoesDirExist_FollowLink(folderPath)) + // if (!NFile::NFind::DoesDirExist(folderPath)) + { + // AddLastError(folderPath); + return S_OK; + } + + FString folderPrefix = folderPath; + folderPrefix.Add_PathSepar(); + + NFile::NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(folderPrefix); + NFile::NFind::CDirEntry fi; + for (;;) + { + bool found; + if (!enumerator.Next(fi, found)) + { + // it can be wrong Symbolic link to folder here + AddLastError(folderPath); + break; + // return GetLastError_noZero_HRESULT(); + } + if (!found) + break; + #ifdef _WIN32 + if (fi.IsDir()) + continue; + #else + if (enumerator.DirEntry_IsDir(fi, true)) // followLink + continue; + #endif + + RINOK(LoadDll(folderPrefix + fi.Name, true)) + } + return S_OK; +} + +void CCodecs::CloseLibs() +{ + // OutputDebugStringA("~CloseLibs start"); + /* + WIN32: FreeLibrary() (CLibrary::Free()) function doesn't work as expected, + if it's called from another FreeLibrary() call. + So we need to call FreeLibrary() before global destructors. + + Also we free global links from DLLs to object of this module before CLibrary::Free() call. + */ + + FOR_VECTOR(i, Libs) + { + const CCodecLib &lib = Libs[i]; + if (lib.SetCodecs) + lib.SetCodecs(NULL); + } + + // OutputDebugStringA("~CloseLibs after SetCodecs"); + Libs.Clear(); + // OutputDebugStringA("~CloseLibs end"); +} + +#endif // Z7_EXTERNAL_CODECS + + +HRESULT CCodecs::Load() +{ + /* + #ifdef NEW_FOLDER_INTERFACE + InternalIcons.LoadIcons(g_hInstance); + #endif + */ + + Formats.Clear(); + + #ifdef Z7_EXTERNAL_CODECS + Errors.Clear(); + MainDll_ErrorPath.Empty(); + Codecs.Clear(); + Hashers.Clear(); + #endif + + for (UInt32 i = 0; i < g_NumArcs; i++) + { + const CArcInfo &arc = *g_Arcs[i]; + CArcInfoEx item; + + item.Name = arc.Name; + item.CreateInArchive = arc.CreateInArchive; + item.IsArcFunc = arc.IsArc; + item.Flags = arc.Flags; + + { + UString e, ae; + if (arc.Ext) + e = arc.Ext; + if (arc.AddExt) + ae = arc.AddExt; + item.AddExts(e, ae); + } + + #ifndef Z7_SFX + + item.CreateOutArchive = arc.CreateOutArchive; + item.UpdateEnabled = (arc.CreateOutArchive != NULL); + item.SignatureOffset = arc.SignatureOffset; + // item.Version = MY_VER_MIX; + item.NewInterface = true; + + if (arc.IsMultiSignature()) + ParseSignatures(arc.Signature, arc.SignatureSize, item.Signatures); + else + { + if (arc.SignatureSize != 0) // 21.04 + item.Signatures.AddNew().CopyFrom(arc.Signature, arc.SignatureSize); + } + + #endif + + Formats.Add(item); + } + + // printf("\nLoad codecs \n"); + + #ifdef Z7_EXTERNAL_CODECS + const FString baseFolder = GetBaseFolderPrefixFromRegistry(); + { + bool loadedOK; + RINOK(LoadDll(baseFolder + kMainDll, false, &loadedOK)) + if (!loadedOK) + MainDll_ErrorPath = kMainDll; + } + RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName)) + RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName)) + + NeedSetLibCodecs = true; + + if (Libs.Size() == 0) + NeedSetLibCodecs = false; + else if (Libs.Size() == 1) + { + // we don't need to set ISetCompressCodecsInfo, if all arcs and codecs are in one external module. + #ifndef EXPORT_CODECS + if (g_NumArcs == 0) + NeedSetLibCodecs = false; + #endif + } + + if (NeedSetLibCodecs) + { + /* 15.00: now we call global function in DLL: SetCompressCodecsInfo(c) + old versions called only ISetCompressCodecsInfo::SetCompressCodecsInfo(c) for each archive handler */ + + FOR_VECTOR(i, Libs) + { + CCodecLib &lib = Libs[i]; + MY_GET_FUNC (lib.SetCodecs, Func_SetCodecs, lib.Lib, "SetCodecs") + if (lib.SetCodecs) + { + RINOK(lib.SetCodecs(this)) + } + } + } + + #endif + + // we sort Formats to get fixed order of Formats after compilation. + Formats.Sort(); + return S_OK; +} + +#ifndef Z7_SFX + +int CCodecs::FindFormatForArchiveName(const UString &arcPath) const +{ + int dotPos = arcPath.ReverseFind_Dot(); + if (dotPos <= arcPath.ReverseFind_PathSepar()) + return -1; + const UString ext = arcPath.Ptr((unsigned)(dotPos + 1)); + if (ext.IsEmpty()) + return -1; + if (ext.IsEqualTo_Ascii_NoCase("exe")) + return -1; + FOR_VECTOR (i, Formats) + { + const CArcInfoEx &arc = Formats[i]; + /* + if (!arc.UpdateEnabled) + continue; + */ + if (arc.FindExtension(ext) >= 0) + return (int)i; + } + return -1; +} + +int CCodecs::FindFormatForExtension(const UString &ext) const +{ + if (ext.IsEmpty()) + return -1; + FOR_VECTOR (i, Formats) + if (Formats[i].FindExtension(ext) >= 0) + return (int)i; + return -1; +} + +int CCodecs::FindFormatForArchiveType(const UString &arcType) const +{ + FOR_VECTOR (i, Formats) + if (Formats[i].Name.IsEqualTo_NoCase(arcType)) + return (int)i; + return -1; +} + +bool CCodecs::FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const +{ + formatIndices.Clear(); + for (unsigned pos = 0; pos < arcType.Len();) + { + int pos2 = arcType.Find(L'.', pos); + if (pos2 < 0) + pos2 = (int)arcType.Len(); + const UString name = arcType.Mid(pos, (unsigned)pos2 - pos); + if (name.IsEmpty()) + return false; + const int index = FindFormatForArchiveType(name); + if (index < 0 && !name.IsEqualTo("*")) + { + formatIndices.Clear(); + return false; + } + formatIndices.Add(index); + pos = (unsigned)pos2 + 1; + } + return true; +} + +#endif // Z7_SFX + + +#ifdef Z7_EXTERNAL_CODECS + +// #define EXPORT_CODECS + +#ifdef EXPORT_CODECS + +extern unsigned g_NumCodecs; +STDAPI CreateDecoder(UInt32 index, const GUID *iid, void **outObject); +STDAPI CreateEncoder(UInt32 index, const GUID *iid, void **outObject); +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); +#define NUM_EXPORT_CODECS g_NumCodecs + +extern unsigned g_NumHashers; +STDAPI CreateHasher(UInt32 index, IHasher **hasher); +STDAPI GetHasherProp(UInt32 codecIndex, PROPID propID, PROPVARIANT *value); +#define NUM_EXPORT_HASHERS g_NumHashers + +#else // EXPORT_CODECS + +#define NUM_EXPORT_CODECS 0 +#define NUM_EXPORT_HASHERS 0 + +#endif // EXPORT_CODECS + +Z7_COM7F_IMF(CCodecs::GetNumMethods(UInt32 *numMethods)) +{ + *numMethods = NUM_EXPORT_CODECS + #ifdef Z7_EXTERNAL_CODECS + + Codecs.Size() + #endif + ; + return S_OK; +} + +Z7_COM7F_IMF(CCodecs::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + return GetMethodProperty(index, propID, value); + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; + + if (propID == NMethodPropID::kDecoderIsAssigned || + propID == NMethodPropID::kEncoderIsAssigned) + { + NCOM::CPropVariant prop; + prop = (bool)((propID == NMethodPropID::kDecoderIsAssigned) ? + ci.DecoderIsAssigned : + ci.EncoderIsAssigned); + prop.Detach(value); + return S_OK; + } + + if (propID == NMethodPropID::kIsFilter && ci.IsFilter_Assigned) + { + NCOM::CPropVariant prop; + prop = (bool)ci.IsFilter; + prop.Detach(value); + return S_OK; + } + + const CCodecLib &lib = Libs[ci.LibIndex]; + return lib.GetMethodProperty(ci.CodecIndex, propID, value); + #else + return E_FAIL; + #endif +} + +Z7_COM7F_IMF(CCodecs::CreateDecoder(UInt32 index, const GUID *iid, void **coder)) +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + return CreateDecoder(index, iid, coder); + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; + if (ci.DecoderIsAssigned) + { + const CCodecLib &lib = Libs[ci.LibIndex]; + if (lib.CreateDecoder) + return lib.CreateDecoder(ci.CodecIndex, iid, (void **)coder); + if (lib.CreateObject) + return lib.CreateObject(&ci.Decoder, iid, (void **)coder); + } + return S_OK; + #else + return E_FAIL; + #endif +} + +Z7_COM7F_IMF(CCodecs::CreateEncoder(UInt32 index, const GUID *iid, void **coder)) +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + return CreateEncoder(index, iid, coder); + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; + if (ci.EncoderIsAssigned) + { + const CCodecLib &lib = Libs[ci.LibIndex]; + if (lib.CreateEncoder) + return lib.CreateEncoder(ci.CodecIndex, iid, (void **)coder); + if (lib.CreateObject) + return lib.CreateObject(&ci.Encoder, iid, (void **)coder); + } + return S_OK; + #else + return E_FAIL; + #endif +} + + +Z7_COM7F_IMF2(UInt32, CCodecs::GetNumHashers()) +{ + return NUM_EXPORT_HASHERS + #ifdef Z7_EXTERNAL_CODECS + + Hashers.Size() + #endif + ; +} + +Z7_COM7F_IMF(CCodecs::GetHasherProp(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + #ifdef EXPORT_CODECS + if (index < g_NumHashers) + return ::GetHasherProp(index, propID, value); + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; + return Libs[ci.LibIndex].ComHashers->GetHasherProp(ci.HasherIndex, propID, value); + #else + return E_FAIL; + #endif +} + +Z7_COM7F_IMF(CCodecs::CreateHasher(UInt32 index, IHasher **hasher)) +{ + #ifdef EXPORT_CODECS + if (index < g_NumHashers) + return CreateHasher(index, hasher); + #endif + #ifdef Z7_EXTERNAL_CODECS + const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; + return Libs[ci.LibIndex].ComHashers->CreateHasher(ci.HasherIndex, hasher); + #else + return E_FAIL; + #endif +} + +int CCodecs::GetCodec_LibIndex(UInt32 index) const +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + return -1; + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllCodecInfo &ci = Codecs[index - NUM_EXPORT_CODECS]; + return (int)ci.LibIndex; + #else + return -1; + #endif +} + +int CCodecs::GetHasherLibIndex(UInt32 index) +{ + #ifdef EXPORT_CODECS + if (index < g_NumHashers) + return -1; + #endif + + #ifdef Z7_EXTERNAL_CODECS + const CDllHasherInfo &ci = Hashers[index - NUM_EXPORT_HASHERS]; + return (int)ci.LibIndex; + #else + return -1; + #endif +} + +bool CCodecs::GetCodec_DecoderIsAssigned(UInt32 index) const +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + { + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kDecoderIsAssigned, &prop) == S_OK) + { + if (prop.vt == VT_BOOL) + return VARIANT_BOOLToBool(prop.boolVal); + } + return false; + } + #endif + + #ifdef Z7_EXTERNAL_CODECS + return Codecs[index - NUM_EXPORT_CODECS].DecoderIsAssigned; + #else + return false; + #endif +} + + +bool CCodecs::GetCodec_EncoderIsAssigned(UInt32 index) const +{ + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + { + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kEncoderIsAssigned, &prop) == S_OK) + { + if (prop.vt == VT_BOOL) + return VARIANT_BOOLToBool(prop.boolVal); + } + return false; + } + #endif + + #ifdef Z7_EXTERNAL_CODECS + return Codecs[index - NUM_EXPORT_CODECS].EncoderIsAssigned; + #else + return false; + #endif +} + + +bool CCodecs::GetCodec_IsFilter(UInt32 index, bool &isAssigned) const +{ + isAssigned = false; + #ifdef EXPORT_CODECS + if (index < g_NumCodecs) + { + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kIsFilter, &prop) == S_OK) + { + if (prop.vt == VT_BOOL) + { + isAssigned = true; + return VARIANT_BOOLToBool(prop.boolVal); + } + } + return false; + } + #endif + + #ifdef Z7_EXTERNAL_CODECS + { + const CDllCodecInfo &c = Codecs[index - NUM_EXPORT_CODECS]; + isAssigned = c.IsFilter_Assigned; + return c.IsFilter; + } + #else + return false; + #endif +} + + +UInt32 CCodecs::GetCodec_NumStreams(UInt32 index) +{ + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kPackStreams, &prop) != S_OK) + return 0; + if (prop.vt == VT_UI4) + return (UInt32)prop.ulVal; + if (prop.vt == VT_EMPTY) + return 1; + return 0; +} + +HRESULT CCodecs::GetCodec_Id(UInt32 index, UInt64 &id) +{ + NCOM::CPropVariant prop; + RINOK(GetProperty(index, NMethodPropID::kID, &prop)) + if (prop.vt != VT_UI8) + return E_INVALIDARG; + id = prop.uhVal.QuadPart; + return S_OK; +} + +AString CCodecs::GetCodec_Name(UInt32 index) +{ + AString s; + NCOM::CPropVariant prop; + if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK) + if (prop.vt == VT_BSTR) + s.SetFromWStr_if_Ascii(prop.bstrVal); + return s; +} + +UInt64 CCodecs::GetHasherId(UInt32 index) +{ + NCOM::CPropVariant prop; + if (GetHasherProp(index, NMethodPropID::kID, &prop) != S_OK) + return 0; + if (prop.vt != VT_UI8) + return 0; + return prop.uhVal.QuadPart; +} + +AString CCodecs::GetHasherName(UInt32 index) +{ + AString s; + NCOM::CPropVariant prop; + if (GetHasherProp(index, NMethodPropID::kName, &prop) == S_OK) + if (prop.vt == VT_BSTR) + s.SetFromWStr_if_Ascii(prop.bstrVal); + return s; +} + +UInt32 CCodecs::GetHasherDigestSize(UInt32 index) +{ + NCOM::CPropVariant prop; + if (GetHasherProp(index, NMethodPropID::kDigestSize, &prop) != S_OK) + return 0; + if (prop.vt != VT_UI4) + return 0; + return prop.ulVal; +} + +void CCodecs::GetCodecsErrorMessage(UString &s) +{ + s.Empty(); + FOR_VECTOR (i, Errors) + { + const CCodecError &ce = Errors[i]; + s += "Codec Load Error: "; + s += fs2us(ce.Path); + if (ce.ErrorCode != 0) + { + s += " : "; + s += NWindows::NError::MyFormatMessage(ce.ErrorCode); + } + if (!ce.Message.IsEmpty()) + { + s += " : "; + s += ce.Message; + } + s.Add_LF(); + } +} + +#endif // Z7_EXTERNAL_CODECS + +#ifndef Z7_SFX + +extern unsigned g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +void CCodecs::Get_CodecsInfoUser_Vector(CObjectVector &v) +{ + v.Clear(); + { + for (unsigned i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &cod = *g_Codecs[i]; + CCodecInfoUser &u = v.AddNew(); + u.EncoderIsAssigned = (cod.CreateEncoder != NULL); + u.DecoderIsAssigned = (cod.CreateDecoder != NULL); + u.IsFilter_Assigned = true; + u.IsFilter = cod.IsFilter; + u.NumStreams = cod.NumStreams; + u.Name = cod.Name; + } + } + + + #ifdef Z7_EXTERNAL_CODECS + { + UInt32 numMethods; + if (GetNumMethods(&numMethods) == S_OK) + for (UInt32 j = 0; j < numMethods; j++) + { + CCodecInfoUser &u = v.AddNew(); + u.EncoderIsAssigned = GetCodec_EncoderIsAssigned(j); + u.DecoderIsAssigned = GetCodec_DecoderIsAssigned(j); + u.IsFilter = GetCodec_IsFilter(j, u.IsFilter_Assigned); + u.NumStreams = GetCodec_NumStreams(j); + u.Name = GetCodec_Name(j); + } + } + #endif +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/LoadCodecs.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/LoadCodecs.h 2015-06-21 08:01:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/LoadCodecs.h 2023-04-06 09:00:00.000000000 +0000 @@ -1,424 +1,482 @@ -// LoadCodecs.h - -#ifndef __LOAD_CODECS_H -#define __LOAD_CODECS_H - -/* -Client application uses LoadCodecs.* to load plugins to -CCodecs object, that contains 3 lists of plugins: - 1) Formats - internal and external archive handlers - 2) Codecs - external codecs - 3) Hashers - external hashers - -EXTERNAL_CODECS ---------------- - - if EXTERNAL_CODECS is defined, then the code tries to load external - plugins from DLL files (shared libraries). - - There are two types of executables in 7-Zip: - - 1) Executable that uses external plugins must be compiled - with EXTERNAL_CODECS defined: - - 7z.exe, 7zG.exe, 7zFM.exe - - Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h - that code is used in plugin module (7z.dll). - - 2) Standalone modules are compiled without EXTERNAL_CODECS: - - SFX modules: 7z.sfx, 7zCon.sfx - - standalone versions of console 7-Zip: 7za.exe, 7zr.exe - - if EXTERNAL_CODECS is defined, CCodecs class implements interfaces: - - ICompressCodecsInfo : for Codecs - - IHashers : for Hashers - - The client application can send CCodecs object to each plugin module. - And plugin module can use ICompressCodecsInfo or IHashers interface to access - another plugins. - - There are 2 ways to send (ICompressCodecsInfo * compressCodecsInfo) to plugin - 1) for old versions: - a) request ISetCompressCodecsInfo from created archive handler. - b) call ISetCompressCodecsInfo::SetCompressCodecsInfo(compressCodecsInfo) - 2) for new versions: - a) request "SetCodecs" function from DLL file - b) call SetCodecs(compressCodecsInfo) function from DLL file -*/ - -#include "../../../Common/MyBuffer.h" -#include "../../../Common/MyCom.h" -#include "../../../Common/MyString.h" -#include "../../../Common/ComTry.h" - -#ifdef EXTERNAL_CODECS -#include "../../../Windows/DLL.h" -#endif - -#include "../../ICoder.h" - -#include "../../Archive/IArchive.h" - - -#ifdef EXTERNAL_CODECS - -struct CDllCodecInfo -{ - unsigned LibIndex; - UInt32 CodecIndex; - bool EncoderIsAssigned; - bool DecoderIsAssigned; - CLSID Encoder; - CLSID Decoder; -}; - -struct CDllHasherInfo -{ - unsigned LibIndex; - UInt32 HasherIndex; -}; - -#endif - -struct CArcExtInfo -{ - UString Ext; - UString AddExt; - - CArcExtInfo() {} - CArcExtInfo(const UString &ext): Ext(ext) {} - CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {} -}; - - -struct CArcInfoEx -{ - UInt32 Flags; - - Func_CreateInArchive CreateInArchive; - Func_IsArc IsArcFunc; - - UString Name; - CObjectVector Exts; - - #ifndef _SFX - Func_CreateOutArchive CreateOutArchive; - bool UpdateEnabled; - bool NewInterface; - // UInt32 Version; - UInt32 SignatureOffset; - CObjectVector Signatures; - #ifdef NEW_FOLDER_INTERFACE - UStringVector AssociateExts; - #endif - #endif - - #ifdef EXTERNAL_CODECS - int LibIndex; - UInt32 FormatIndex; - CLSID ClassID; - #endif - - bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; } - bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; } - - bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; } - bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; } - bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; } - bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; } - - bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; } - bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; } - bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; } - bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; } - bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; } - - UString GetMainExt() const - { - if (Exts.IsEmpty()) - return UString(); - return Exts[0].Ext; - } - int FindExtension(const UString &ext) const; - - /* - UString GetAllExtensions() const - { - UString s; - for (int i = 0; i < Exts.Size(); i++) - { - if (i > 0) - s += ' '; - s += Exts[i].Ext; - } - return s; - } - */ - - 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), - CreateInArchive(NULL), - IsArcFunc(NULL) - #ifndef _SFX - , CreateOutArchive(NULL) - , UpdateEnabled(false) - , NewInterface(false) - // , Version(0) - , SignatureOffset(0) - #endif - #ifdef EXTERNAL_CODECS - , LibIndex(-1) - #endif - {} -}; - -#ifdef NEW_FOLDER_INTERFACE - -struct CCodecIcons -{ - struct CIconPair - { - UString Ext; - int IconIndex; - }; - CObjectVector IconPairs; - - void LoadIcons(HMODULE m); - bool FindIconIndex(const UString &ext, int &iconIndex) const; -}; - -#endif - -#ifdef EXTERNAL_CODECS - -struct CCodecLib - #ifdef NEW_FOLDER_INTERFACE - : public CCodecIcons - #endif -{ - NWindows::NDLL::CLibrary Lib; - FString Path; - - Func_CreateObject CreateObject; - Func_GetMethodProperty GetMethodProperty; - Func_CreateDecoder CreateDecoder; - Func_CreateEncoder CreateEncoder; - Func_SetCodecs SetCodecs; - - CMyComPtr ComHashers; - - #ifdef NEW_FOLDER_INTERFACE - void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); } - #endif - - CCodecLib(): - CreateObject(NULL), - GetMethodProperty(NULL), - CreateDecoder(NULL), - CreateEncoder(NULL), - SetCodecs(NULL) - {} -}; - -#endif - - -class CCodecs: - #ifdef EXTERNAL_CODECS - public ICompressCodecsInfo, - public IHashers, - #else - public IUnknown, - #endif - public CMyUnknownImp -{ - CLASS_NO_COPY(CCodecs); -public: - #ifdef EXTERNAL_CODECS - - CObjectVector Libs; - FString MainDll_ErrorPath; - - void CloseLibs(); - - class CReleaser - { - CLASS_NO_COPY(CReleaser); - - /* CCodecsReleaser object releases CCodecs links. - 1) CCodecs is COM object that is deleted when all links to that object will be released/ - 2) CCodecs::Libs[i] can hold (ICompressCodecsInfo *) link to CCodecs object itself. - To break that reference loop, we must close all CCodecs::Libs in CCodecsReleaser desttructor. */ - - CCodecs *_codecs; - - public: - CReleaser(): _codecs(NULL) {} - void Set(CCodecs *codecs) { _codecs = codecs; } - ~CReleaser() { if (_codecs) _codecs->CloseLibs(); } - }; - - bool NeedSetLibCodecs; // = false, if we don't need to set codecs for archive handler via ISetCompressCodecsInfo - - HRESULT LoadCodecs(); - HRESULT LoadFormats(); - HRESULT LoadDll(const FString &path, bool needCheckDll, bool *loadedOK = NULL); - HRESULT LoadDllsFromFolder(const FString &folderPrefix); - - HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const - { - return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); - } - - #endif - - #ifdef NEW_FOLDER_INTERFACE - CCodecIcons InternalIcons; - #endif - - CObjectVector Formats; - - #ifdef EXTERNAL_CODECS - CRecordVector Codecs; - CRecordVector Hashers; - #endif - - bool CaseSensitiveChange; - bool CaseSensitive; - - CCodecs(): - #ifdef EXTERNAL_CODECS - NeedSetLibCodecs(true), - #endif - CaseSensitiveChange(false), - CaseSensitive(false) - {} - - ~CCodecs() - { - // OutputDebugStringA("~CCodecs"); - } - - const wchar_t *GetFormatNamePtr(int formatIndex) const - { - return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name; - } - - HRESULT Load(); - - #ifndef _SFX - int FindFormatForArchiveName(const UString &arcPath) const; - int FindFormatForExtension(const UString &ext) const; - int FindFormatForArchiveType(const UString &arcType) const; - bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const; - #endif - - #ifdef EXTERNAL_CODECS - - MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers) - - STDMETHOD(GetNumMethods)(UInt32 *numMethods); - STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder); - STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder); - - STDMETHOD_(UInt32, GetNumHashers)(); - STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value); - STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher); - - #else - - MY_UNKNOWN_IMP - - #endif // EXTERNAL_CODECS - - - #ifdef EXTERNAL_CODECS - - int GetCodec_LibIndex(UInt32 index) const; - bool GetCodec_DecoderIsAssigned(UInt32 index) const; - bool GetCodec_EncoderIsAssigned(UInt32 index) const; - UInt32 GetCodec_NumStreams(UInt32 index); - HRESULT GetCodec_Id(UInt32 index, UInt64 &id); - AString GetCodec_Name(UInt32 index); - - int GetHasherLibIndex(UInt32 index); - UInt64 GetHasherId(UInt32 index); - AString GetHasherName(UInt32 index); - UInt32 GetHasherDigestSize(UInt32 index); - - #endif - - HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr &archive) const - { - const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS - if (ai.LibIndex < 0) - #endif - { - COM_TRY_BEGIN - archive = ai.CreateInArchive(); - return S_OK; - COM_TRY_END - } - #ifdef EXTERNAL_CODECS - return CreateArchiveHandler(ai, false, (void **)&archive); - #endif - } - - #ifndef _SFX - - HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr &archive) const - { - const CArcInfoEx &ai = Formats[formatIndex]; - #ifdef EXTERNAL_CODECS - if (ai.LibIndex < 0) - #endif - { - COM_TRY_BEGIN - archive = ai.CreateOutArchive(); - return S_OK; - COM_TRY_END - } - - #ifdef EXTERNAL_CODECS - return CreateArchiveHandler(ai, true, (void **)&archive); - #endif - } - - int FindOutFormatFromName(const UString &name) const - { - FOR_VECTOR (i, Formats) - { - const CArcInfoEx &arc = Formats[i]; - if (!arc.UpdateEnabled) - continue; - if (arc.Name.IsEqualTo_NoCase(name)) - return i; - } - return -1; - } - - #endif // _SFX -}; - -#ifdef EXTERNAL_CODECS - #define CREATE_CODECS_OBJECT \ - CCodecs *codecs = new CCodecs; \ - CExternalCodecs __externalCodecs; \ - __externalCodecs.GetCodecs = codecs; \ - __externalCodecs.GetHashers = codecs; \ - CCodecs::CReleaser codecsReleaser; \ - codecsReleaser.Set(codecs); -#else - #define CREATE_CODECS_OBJECT \ - CCodecs *codecs = new CCodecs; \ - CMyComPtr __codecsRef = codecs; -#endif - -#endif +// LoadCodecs.h + +#ifndef ZIP7_INC_LOAD_CODECS_H +#define ZIP7_INC_LOAD_CODECS_H + +/* +Client application uses LoadCodecs.* to load plugins to +CCodecs object, that contains 3 lists of plugins: + 1) Formats - internal and external archive handlers + 2) Codecs - external codecs + 3) Hashers - external hashers + +Z7_EXTERNAL_CODECS +--------------- + + if Z7_EXTERNAL_CODECS is defined, then the code tries to load external + plugins from DLL files (shared libraries). + + There are two types of executables in 7-Zip: + + 1) Executable that uses external plugins must be compiled + with Z7_EXTERNAL_CODECS defined: + - 7z.exe, 7zG.exe, 7zFM.exe + + Note: Z7_EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h + that code is used in plugin module (7z.dll). + + 2) Standalone modules are compiled without Z7_EXTERNAL_CODECS: + - SFX modules: 7z.sfx, 7zCon.sfx + - standalone versions of console 7-Zip: 7za.exe, 7zr.exe + + if Z7_EXTERNAL_CODECS is defined, CCodecs class implements interfaces: + - ICompressCodecsInfo : for Codecs + - IHashers : for Hashers + + The client application can send CCodecs object to each plugin module. + And plugin module can use ICompressCodecsInfo or IHashers interface to access + another plugins. + + There are 2 ways to send (ICompressCodecsInfo * compressCodecsInfo) to plugin + 1) for old versions: + a) request ISetCompressCodecsInfo from created archive handler. + b) call ISetCompressCodecsInfo::SetCompressCodecsInfo(compressCodecsInfo) + 2) for new versions: + a) request "SetCodecs" function from DLL file + b) call SetCodecs(compressCodecsInfo) function from DLL file +*/ + +#include "../../../Common/MyBuffer.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/MyString.h" +#include "../../../Common/ComTry.h" + +#ifdef Z7_EXTERNAL_CODECS +#include "../../../Windows/DLL.h" +#endif + +#include "../../ICoder.h" + +#include "../../Archive/IArchive.h" + + +#ifdef Z7_EXTERNAL_CODECS + +struct CDllCodecInfo +{ + unsigned LibIndex; + UInt32 CodecIndex; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + bool IsFilter; + bool IsFilter_Assigned; + CLSID Encoder; + CLSID Decoder; +}; + +struct CDllHasherInfo +{ + unsigned LibIndex; + UInt32 HasherIndex; +}; + +#endif + +struct CArcExtInfo +{ + UString Ext; + UString AddExt; + + CArcExtInfo() {} + CArcExtInfo(const UString &ext): Ext(ext) {} + CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {} +}; + + +struct CArcInfoEx +{ + UInt32 Flags; + UInt32 TimeFlags; + + Func_CreateInArchive CreateInArchive; + Func_IsArc IsArcFunc; + + UString Name; + CObjectVector Exts; + + #ifndef Z7_SFX + Func_CreateOutArchive CreateOutArchive; + bool UpdateEnabled; + bool NewInterface; + // UInt32 Version; + UInt32 SignatureOffset; + CObjectVector Signatures; + /* + #ifdef NEW_FOLDER_INTERFACE + UStringVector AssociateExts; + #endif + */ + #endif + + #ifdef Z7_EXTERNAL_CODECS + int LibIndex; + UInt32 FormatIndex; + CLSID ClassID; + #endif + + int Compare(const CArcInfoEx &a) const + { + const int res = Name.Compare(a.Name); + if (res != 0) + return res; + #ifdef Z7_EXTERNAL_CODECS + return MyCompare(LibIndex, a.LibIndex); + #else + return 0; + #endif + /* + if (LibIndex < a.LibIndex) return -1; + if (LibIndex > a.LibIndex) return 1; + return 0; + */ + } + + bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; } + bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; } + + bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; } + bool Flags_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; } + + bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; } + bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; } + bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; } + bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; } + bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; } + bool Flags_ByExtOnlyOpen() const { return (Flags & NArcInfoFlags::kByExtOnlyOpen) != 0; } + bool Flags_HashHandler() const { return (Flags & NArcInfoFlags::kHashHandler) != 0; } + + bool Flags_CTime() const { return (Flags & NArcInfoFlags::kCTime) != 0; } + bool Flags_ATime() const { return (Flags & NArcInfoFlags::kATime) != 0; } + bool Flags_MTime() const { return (Flags & NArcInfoFlags::kMTime) != 0; } + + bool Flags_CTime_Default() const { return (Flags & NArcInfoFlags::kCTime_Default) != 0; } + bool Flags_ATime_Default() const { return (Flags & NArcInfoFlags::kATime_Default) != 0; } + bool Flags_MTime_Default() const { return (Flags & NArcInfoFlags::kMTime_Default) != 0; } + + UInt32 Get_TimePrecFlags() const + { + return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Mask_bit_index) & + (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Mask_num_bits) - 1); + } + + UInt32 Get_DefaultTimePrec() const + { + return (TimeFlags >> NArcInfoTimeFlags::kTime_Prec_Default_bit_index) & + (((UInt32)1 << NArcInfoTimeFlags::kTime_Prec_Default_num_bits) - 1); + } + + + UString GetMainExt() const + { + if (Exts.IsEmpty()) + return UString(); + return Exts[0].Ext; + } + int FindExtension(const UString &ext) const; + + bool Is_7z() const { return Name.IsEqualTo_Ascii_NoCase("7z"); } + bool Is_Split() const { return Name.IsEqualTo_Ascii_NoCase("Split"); } + bool Is_Xz() const { return Name.IsEqualTo_Ascii_NoCase("xz"); } + bool Is_BZip2() const { return Name.IsEqualTo_Ascii_NoCase("bzip2"); } + bool Is_GZip() const { return Name.IsEqualTo_Ascii_NoCase("gzip"); } + bool Is_Tar() const { return Name.IsEqualTo_Ascii_NoCase("tar"); } + bool Is_Zip() const { return Name.IsEqualTo_Ascii_NoCase("zip"); } + bool Is_Rar() const { return Name.IsEqualTo_Ascii_NoCase("rar"); } + bool Is_Zstd() const { return Name.IsEqualTo_Ascii_NoCase("zstd"); } + + /* + UString GetAllExtensions() const + { + UString s; + for (int i = 0; i < Exts.Size(); i++) + { + if (i > 0) + s.Add_Space(); + s += Exts[i].Ext; + } + return s; + } + */ + + void AddExts(const UString &ext, const UString &addExt); + + + CArcInfoEx(): + Flags(0), + TimeFlags(0), + CreateInArchive(NULL), + IsArcFunc(NULL) + #ifndef Z7_SFX + , CreateOutArchive(NULL) + , UpdateEnabled(false) + , NewInterface(false) + // , Version(0) + , SignatureOffset(0) + #endif + #ifdef Z7_EXTERNAL_CODECS + , LibIndex(-1) + #endif + {} +}; + + +#ifdef Z7_EXTERNAL_CODECS + +struct CCodecLib +{ + NWindows::NDLL::CLibrary Lib; + FString Path; + + Func_CreateObject CreateObject; + Func_GetMethodProperty GetMethodProperty; + Func_CreateDecoder CreateDecoder; + Func_CreateEncoder CreateEncoder; + Func_SetCodecs SetCodecs; + + CMyComPtr ComHashers; + + UInt32 Version; + + /* + #ifdef NEW_FOLDER_INTERFACE + CCodecIcons CodecIcons; + void LoadIcons() { CodecIcons.LoadIcons((HMODULE)Lib); } + #endif + */ + + CCodecLib(): + CreateObject(NULL), + GetMethodProperty(NULL), + CreateDecoder(NULL), + CreateEncoder(NULL), + SetCodecs(NULL), + Version(0) + {} +}; + +#endif + +struct CCodecError +{ + FString Path; + HRESULT ErrorCode; + AString Message; + CCodecError(): ErrorCode(0) {} +}; + + +struct CCodecInfoUser +{ + // unsigned LibIndex; + // UInt32 CodecIndex; + // UInt64 id; + bool EncoderIsAssigned; + bool DecoderIsAssigned; + bool IsFilter; + bool IsFilter_Assigned; + UInt32 NumStreams; + AString Name; +}; + + +class CCodecs Z7_final: + #ifdef Z7_EXTERNAL_CODECS + public ICompressCodecsInfo, + public IHashers, + #else + public IUnknown, + #endif + public CMyUnknownImp +{ +#ifdef Z7_EXTERNAL_CODECS + Z7_IFACES_IMP_UNK_2(ICompressCodecsInfo, IHashers) +#else + Z7_COM_UNKNOWN_IMP_0 +#endif // Z7_EXTERNAL_CODECS + + Z7_CLASS_NO_COPY(CCodecs) +public: + #ifdef Z7_EXTERNAL_CODECS + + CObjectVector Libs; + FString MainDll_ErrorPath; + CObjectVector Errors; + + void AddLastError(const FString &path); + void CloseLibs(); + + class CReleaser + { + Z7_CLASS_NO_COPY(CReleaser) + + /* CCodecsReleaser object releases CCodecs links. + 1) CCodecs is COM object that is deleted when all links to that object will be released/ + 2) CCodecs::Libs[i] can hold (ICompressCodecsInfo *) link to CCodecs object itself. + To break that reference loop, we must close all CCodecs::Libs in CCodecsReleaser desttructor. */ + + CCodecs *_codecs; + + public: + CReleaser(): _codecs(NULL) {} + void Set(CCodecs *codecs) { _codecs = codecs; } + ~CReleaser() { if (_codecs) _codecs->CloseLibs(); } + }; + + bool NeedSetLibCodecs; // = false, if we don't need to set codecs for archive handler via ISetCompressCodecsInfo + + HRESULT LoadCodecs(); + HRESULT LoadFormats(); + HRESULT LoadDll(const FString &path, bool needCheckDll, bool *loadedOK = NULL); + HRESULT LoadDllsFromFolder(const FString &folderPrefix); + + HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const + { + return Libs[(unsigned)ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); + } + + #endif + + /* + #ifdef NEW_FOLDER_INTERFACE + CCodecIcons InternalIcons; + #endif + */ + + CObjectVector Formats; + + #ifdef Z7_EXTERNAL_CODECS + CRecordVector Codecs; + CRecordVector Hashers; + #endif + + bool CaseSensitive_Change; + bool CaseSensitive; + + CCodecs(): + #ifdef Z7_EXTERNAL_CODECS + NeedSetLibCodecs(true), + #endif + CaseSensitive_Change(false), + CaseSensitive(false) + {} + + ~CCodecs() + { + // OutputDebugStringA("~CCodecs"); + } + + const wchar_t *GetFormatNamePtr(int formatIndex) const + { + return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[(unsigned)formatIndex].Name; + } + + HRESULT Load(); + + #ifndef Z7_SFX + int FindFormatForArchiveName(const UString &arcPath) const; + int FindFormatForExtension(const UString &ext) const; + int FindFormatForArchiveType(const UString &arcType) const; + bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const; + #endif + + #ifdef Z7_EXTERNAL_CODECS + + int GetCodec_LibIndex(UInt32 index) const; + bool GetCodec_DecoderIsAssigned(UInt32 index) const; + bool GetCodec_EncoderIsAssigned(UInt32 index) const; + bool GetCodec_IsFilter(UInt32 index, bool &isAssigned) const; + UInt32 GetCodec_NumStreams(UInt32 index); + HRESULT GetCodec_Id(UInt32 index, UInt64 &id); + AString GetCodec_Name(UInt32 index); + + int GetHasherLibIndex(UInt32 index); + UInt64 GetHasherId(UInt32 index); + AString GetHasherName(UInt32 index); + UInt32 GetHasherDigestSize(UInt32 index); + + void GetCodecsErrorMessage(UString &s); + + #endif + + HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr &archive) const + { + const CArcInfoEx &ai = Formats[formatIndex]; + #ifdef Z7_EXTERNAL_CODECS + if (ai.LibIndex < 0) + #endif + { + COM_TRY_BEGIN + archive = ai.CreateInArchive(); + return S_OK; + COM_TRY_END + } + #ifdef Z7_EXTERNAL_CODECS + return CreateArchiveHandler(ai, false, (void **)&archive); + #endif + } + + #ifndef Z7_SFX + + HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr &archive) const + { + const CArcInfoEx &ai = Formats[formatIndex]; + #ifdef Z7_EXTERNAL_CODECS + if (ai.LibIndex < 0) + #endif + { + COM_TRY_BEGIN + archive = ai.CreateOutArchive(); + return S_OK; + COM_TRY_END + } + + #ifdef Z7_EXTERNAL_CODECS + return CreateArchiveHandler(ai, true, (void **)&archive); + #endif + } + + int FindOutFormatFromName(const UString &name) const + { + FOR_VECTOR (i, Formats) + { + const CArcInfoEx &arc = Formats[i]; + if (!arc.UpdateEnabled) + continue; + if (arc.Name.IsEqualTo_NoCase(name)) + return (int)i; + } + return -1; + } + + void Get_CodecsInfoUser_Vector(CObjectVector &v); + + #endif // Z7_SFX +}; + +#ifdef Z7_EXTERNAL_CODECS + #define CREATE_CODECS_OBJECT \ + CCodecs *codecs = new CCodecs; \ + CExternalCodecs _externalCodecs; \ + _externalCodecs.GetCodecs = codecs; \ + _externalCodecs.GetHashers = codecs; \ + CCodecs::CReleaser codecsReleaser; \ + codecsReleaser.Set(codecs); +#else + #define CREATE_CODECS_OBJECT \ + CCodecs *codecs = new CCodecs; \ + CMyComPtr _codecsRef = codecs; +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/OpenArchive.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/OpenArchive.cpp 2016-06-11 08:53:41.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,3544 +1,3702 @@ -// OpenArchive.cpp - -#include "StdAfx.h" - -// #define SHOW_DEBUG_INFO - -#ifdef SHOW_DEBUG_INFO -#include -#endif - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" - -#include "DefaultName.h" -#include "OpenArchive.h" - -#ifndef _SFX -#include "SetProperties.h" -#endif - -#ifdef SHOW_DEBUG_INFO -#define PRF(x) x -#else -#define PRF(x) -#endif - -// increase it, if you need to support larger SFX stubs -static const UInt64 kMaxCheckStartPosition = 1 << 23; - -/* -Open: - - formatIndex >= 0 (exact Format) - 1) Open with main type. Archive handler is allowed to use archive start finder. - Warning, if there is tail. - - - formatIndex = -1 (Parser:0) (default) - - same as #1 but doesn't return Parser - - - formatIndex = -2 (#1) - - file has supported extension (like a.7z) - Open with that main type (only starting from start of file). - - open OK: - - if there is no tail - return OK - - if there is tail: - - archive is not "Self Exe" - return OK with Warning, that there is tail - - archive is "Self Exe" - ignore "Self Exe" stub, and tries to open tail - - tail can be open as archive - shows that archive and stub size property. - - tail can't be open as archive - shows Parser ??? - - open FAIL: - Try to open with all other types from offset 0 only. - If some open type is OK and physical archive size is uequal or larger - than file size, then return that archive with warning that can not be open as [extension type]. - If extension was EXE, it will try to open as unknown_extension case - - file has unknown extension (like a.hhh) - It tries to open via parser code. - - if there is full archive or tail archive and unknown block or "Self Exe" - at front, it shows tail archive and stub size property. - - in another cases, if there is some archive inside file, it returns parser/ - - in another cases, it retuens S_FALSE - - - - formatIndex = -3 (#2) - - same as #1, but - - stub (EXE) + archive is open in Parser - - - formatIndex = -4 (#3) - - returns only Parser. skip full file archive. And show other sub-archives - - - formatIndex = -5 (#4) - - returns only Parser. skip full file archive. And show other sub-archives for each byte pos - -*/ - - - - -using namespace NWindows; - -/* -#ifdef _SFX -#define OPEN_PROPS_PARAM -#else -#define OPEN_PROPS_PARAM , props -#endif -*/ - -/* -CArc::~CArc() -{ - GetRawProps.Release(); - Archive.Release(); - printf("\nCArc::~CArc()\n"); -} -*/ - -#ifndef _SFX - -namespace NArchive { -namespace NParser { - -struct CParseItem -{ - UInt64 Offset; - UInt64 Size; - // UInt64 OkSize; - UString Name; - UString Extension; - FILETIME FileTime; - UString Comment; - UString ArcType; - - bool FileTime_Defined; - bool UnpackSize_Defined; - bool NumSubDirs_Defined; - bool NumSubFiles_Defined; - - bool IsSelfExe; - bool IsNotArcType; - - UInt64 UnpackSize; - UInt64 NumSubDirs; - UInt64 NumSubFiles; - - int FormatIndex; - - bool LenIsUnknown; - - CParseItem(): - LenIsUnknown(false), - FileTime_Defined(false), - UnpackSize_Defined(false), - NumSubFiles_Defined(false), - NumSubDirs_Defined(false), - IsSelfExe(false), - IsNotArcType(false) - // OkSize(0) - {} - - /* - bool IsEqualTo(const CParseItem &item) const - { - return Offset == item.Offset && Size == item.Size; - } - */ - - void NormalizeOffset() - { - if ((Int64)Offset < 0) - { - Size += Offset; - // OkSize += Offset; - Offset = 0; - } - } -}; - -class CHandler: - public IInArchive, - public IInArchiveGetStream, - public CMyUnknownImp -{ -public: - CObjectVector _items; - UInt64 _maxEndOffset; - CMyComPtr _stream; - - MY_UNKNOWN_IMP2( - IInArchive, - IInArchiveGetStream) - - INTERFACE_IInArchive(;) - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); - - UInt64 GetLastEnd() const - { - if (_items.IsEmpty()) - return 0; - const CParseItem &back = _items.Back(); - return back.Offset + back.Size; - } - - void AddUnknownItem(UInt64 next); - int FindInsertPos(const CParseItem &item) const; - void AddItem(const CParseItem &item); - - CHandler(): _maxEndOffset(0) {} -}; - -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]; - if (item.Offset < midItem.Offset) - right = mid; - else if (item.Offset > midItem.Offset) - left = mid + 1; - else if (item.Size < midItem.Size) - right = mid; - else if (item.Size > midItem.Size) - left = mid + 1; - else - { - left = mid + 1; - // return -1; - } - } - return left; -} - -void CHandler::AddUnknownItem(UInt64 next) -{ - /* - UInt64 prevEnd = 0; - if (!_items.IsEmpty()) - { - const CParseItem &back = _items.Back(); - prevEnd = back.Offset + back.Size; - } - */ - if (_maxEndOffset < next) - { - CParseItem item2; - item2.Offset = _maxEndOffset; - item2.Size = next - _maxEndOffset; - _maxEndOffset = next; - _items.Add(item2); - } - else if (_maxEndOffset > next && !_items.IsEmpty()) - { - CParseItem &back = _items.Back(); - if (back.LenIsUnknown) - { - back.Size = next - back.Offset; - _maxEndOffset = next; - } - } -} - -void CHandler::AddItem(const CParseItem &item) -{ - AddUnknownItem(item.Offset); - int pos = FindInsertPos(item); - if (pos >= 0) - { - _items.Insert(pos, item); - UInt64 next = item.Offset + item.Size; - if (_maxEndOffset < next) - _maxEndOffset = next; - } -} - -/* -static const CStatProp kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidType, VT_BSTR}, - { NULL, kpidComment, VT_BSTR}, - { NULL, kpidOffset, VT_UI8}, - { NULL, kpidUnpackSize, VT_UI8}, -// { NULL, kpidNumSubDirs, VT_UI8}, -}; -*/ - -static const Byte kProps[] = -{ - kpidPath, - kpidSize, - kpidMTime, - kpidType, - kpidComment, - kpidOffset, - kpidUnpackSize -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps_NO - -STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - { - Close(); - _stream = stream; - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _items.Clear(); - _stream.Release(); - return S_OK; -} - -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 CParseItem &item = _items[index]; - - switch (propID) - { - case kpidPath: - { - wchar_t sz[32]; - ConvertUInt32ToString(index + 1, sz); - UString s = sz; - if (!item.Name.IsEmpty()) - { - s += L'.'; - s += item.Name; - } - if (!item.Extension.IsEmpty()) - { - s += L'.'; - s += item.Extension; - } - prop = s; break; - } - case kpidSize: - case kpidPackSize: prop = item.Size; break; - case kpidOffset: prop = item.Offset; break; - case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break; - case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break; - case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break; - case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break; - case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break; - case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - - bool allFilesMode = (numItems == (UInt32)(Int32)-1); - if (allFilesMode) - numItems = _items.Size(); - if (_stream && numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _items[allFilesMode ? i : indices[i]].Size; - extractCallback->SetTotal(totalSize); - - totalSize = 0; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr inStream(streamSpec); - streamSpec->SetStream(_stream); - - CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; - CMyComPtr outStream(outStreamSpec); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr copyCoder = copyCoderSpec; - - for (i = 0; i < numItems; i++) - { - lps->InSize = totalSize; - lps->OutSize = totalSize; - RINOK(lps->SetCur()); - CMyComPtr realOutStream; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - Int32 index = allFilesMode ? i : indices[i]; - const CParseItem &item = _items[index]; - - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - UInt64 unpackSize = item.Size; - totalSize += unpackSize; - bool skipMode = false; - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - - outStreamSpec->SetStream(realOutStream); - realOutStream.Release(); - outStreamSpec->Init(skipMode ? 0 : unpackSize, true); - - Int32 opRes = NExtract::NOperationResult::kOK; - RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(unpackSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - - if (outStreamSpec->GetRem() != 0) - opRes = NExtract::NOperationResult::kDataError; - outStreamSpec->ReleaseStream(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - - return S_OK; - - COM_TRY_END -} - - -STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) -{ - COM_TRY_BEGIN - const CParseItem &item = _items[index]; - return CreateLimitedInStream(_stream, item.Offset, item.Size, stream); - COM_TRY_END -} - -}} - -#endif - -HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw() -{ - NCOM::CPropVariant prop; - result = false; - RINOK(arc->GetProperty(index, propID, &prop)); - if (prop.vt == VT_BOOL) - result = VARIANT_BOOLToBool(prop.boolVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw() -{ - return Archive_GetItemBoolProp(arc, index, kpidIsDir, result); -} - -HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw() -{ - return Archive_GetItemBoolProp(arc, index, kpidIsAux, result); -} - -HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw() -{ - return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result); -} - -HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw() -{ - return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); -} - -static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw() -{ - NCOM::CPropVariant prop; - result = false; - RINOK(arc->GetArchiveProperty(propid, &prop)); - if (prop.vt == VT_BOOL) - result = VARIANT_BOOLToBool(prop.boolVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined) -{ - defined = false; - NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); - switch (prop.vt) - { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = (Int64)prop.lVal; defined = true; break; - case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; - default: return E_FAIL; - } - return S_OK; -} - -static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined) -{ - defined = false; - NCOM::CPropVariant prop; - RINOK(arc->GetArchiveProperty(propid, &prop)); - switch (prop.vt) - { - case VT_UI4: result = prop.ulVal; defined = true; break; - case VT_I4: result = prop.lVal; defined = true; break; - case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break; - case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break; - case VT_EMPTY: break; - default: return E_FAIL; - } - return S_OK; -} - -#ifndef _SFX - -HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const -{ - if (!GetRawProps) - return E_FAIL; - if (index == parent) - return S_OK; - UInt32 curIndex = index; - - UString s; - - bool prevWasAltStream = false; - - for (;;) - { - #ifdef MY_CPU_LE - const void *p; - UInt32 size; - UInt32 propType; - RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)); - if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) - s = (const wchar_t *)p; - else - #endif - { - NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(curIndex, kpidName, &prop)); - if (prop.vt == VT_BSTR && prop.bstrVal) - s.SetFromBstr(prop.bstrVal); - else if (prop.vt == VT_EMPTY) - s.Empty(); - else - return E_FAIL; - } - - UInt32 curParent = (UInt32)(Int32)-1; - UInt32 parentType = 0; - RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)); - - if (parentType != NParentType::kAltStream) - { - for (;;) - { - int pos = s.ReverseFind_PathSepar(); - if (pos < 0) - { - break; - } - parts.Insert(0, s.Ptr(pos + 1)); - s.DeleteFrom(pos); - } - } - - parts.Insert(0, s); - - if (prevWasAltStream) - { - { - UString &s2 = parts[parts.Size() - 2]; - s2 += L':'; - s2 += parts.Back(); - } - parts.DeleteBack(); - } - - if (parent == curParent) - return S_OK; - - prevWasAltStream = false; - if (parentType == NParentType::kAltStream) - prevWasAltStream = true; - - if (curParent == (UInt32)(Int32)-1) - return E_FAIL; - curIndex = curParent; - } -} - -#endif - -HRESULT CArc::GetItemPath(UInt32 index, UString &result) const -{ - #ifdef MY_CPU_LE - if (GetRawProps) - { - const void *p; - UInt32 size; - UInt32 propType; - if (!IsTree) - { - if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK && - propType == NPropDataType::kUtf16z) - { - unsigned len = size / 2 - 1; - wchar_t *s = result.GetBuf(len); - for (unsigned i = 0; i < len; i++) - { - wchar_t c = GetUi16(p); - p = (const void *)((const Byte *)p + 2); - #if WCHAR_PATH_SEPARATOR != L'/' - if (c == L'/') - c = WCHAR_PATH_SEPARATOR; - #endif - *s++ = c; - } - *s = 0; - result.ReleaseBuf_SetLen(len); - if (len != 0) - return S_OK; - } - } - /* - else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK && - p && propType == NPropDataType::kUtf16z) - { - size -= 2; - UInt32 totalSize = size; - bool isOK = false; - - { - UInt32 index2 = index; - for (;;) - { - UInt32 parent = (UInt32)(Int32)-1; - UInt32 parentType = 0; - if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) - break; - if (parent == (UInt32)(Int32)-1) - { - if (parentType != 0) - totalSize += 2; - isOK = true; - break; - } - index2 = parent; - UInt32 size2; - const void *p2; - if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK && - p2 && propType == NPropDataType::kUtf16z) - break; - totalSize += size2; - } - } - - if (isOK) - { - wchar_t *sz = result.GetBuf_SetEnd(totalSize / 2); - UInt32 pos = totalSize - size; - memcpy((Byte *)sz + pos, p, size); - UInt32 index2 = index; - for (;;) - { - UInt32 parent = (UInt32)(Int32)-1; - UInt32 parentType = 0; - if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) - break; - if (parent == (UInt32)(Int32)-1) - { - if (parentType != 0) - sz[pos / 2 - 1] = L':'; - break; - } - index2 = parent; - UInt32 size2; - const void *p2; - if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK) - break; - pos -= size2; - memcpy((Byte *)sz + pos, p2, size2); - sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':'; - } - #ifdef _WIN32 - // result.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - return S_OK; - } - } - */ - } - #endif - - { - NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidPath, &prop)); - if (prop.vt == VT_BSTR && prop.bstrVal) - result.SetFromBstr(prop.bstrVal); - else if (prop.vt == VT_EMPTY) - result.Empty(); - else - return E_FAIL; - } - - if (result.IsEmpty()) - return GetDefaultItemPath(index, result); - return S_OK; -} - -HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const -{ - result.Empty(); - bool isDir; - RINOK(Archive_IsItem_Dir(Archive, index, isDir)); - if (!isDir) - { - result = DefaultName; - NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidExtension, &prop)); - if (prop.vt == VT_BSTR) - { - result += L'.'; - result += prop.bstrVal; - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - } - return S_OK; -} - -HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const -{ - RINOK(GetItemPath(index, result)); - if (Ask_Deleted) - { - bool isDeleted = false; - RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)); - if (isDeleted) - result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR); - } - return S_OK; -} - -#ifdef SUPPORT_ALT_STREAMS - -int FindAltStreamColon_in_Path(const wchar_t *path) -{ - unsigned i = 0; - int colonPos = -1; - for (;; i++) - { - wchar_t c = path[i]; - if (c == 0) - return colonPos; - if (c == ':') - { - if (colonPos < 0) - colonPos = i; - continue; - } - if (c == WCHAR_PATH_SEPARATOR) - colonPos = -1; - } -} - -#endif - -HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const -{ - #ifdef SUPPORT_ALT_STREAMS - item.IsAltStream = false; - item.AltStreamName.Empty(); - item.MainPath.Empty(); - #endif - - item.IsDir = false; - item.Path.Empty(); - item.ParentIndex = (UInt32)(Int32)-1; - - item.PathParts.Clear(); - - RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)); - item.MainIsDir = item.IsDir; - - RINOK(GetItemPath2(index, item.Path)); - - #ifndef _SFX - UInt32 mainIndex = index; - #endif - - #ifdef SUPPORT_ALT_STREAMS - - item.MainPath = item.Path; - if (Ask_AltStream) - { - RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)); - } - - bool needFindAltStream = false; - - if (item.IsAltStream) - { - needFindAltStream = true; - if (GetRawProps) - { - UInt32 parentType = 0; - UInt32 parentIndex; - RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)); - if (parentType == NParentType::kAltStream) - { - NCOM::CPropVariant prop; - RINOK(Archive->GetProperty(index, kpidName, &prop)); - if (prop.vt == VT_BSTR && prop.bstrVal) - item.AltStreamName.SetFromBstr(prop.bstrVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - else - { - // item.IsAltStream = false; - } - /* - if (item.AltStreamName.IsEmpty()) - item.IsAltStream = false; - */ - - needFindAltStream = false; - item.ParentIndex = parentIndex; - mainIndex = parentIndex; - - if (parentIndex == (UInt32)(Int32)-1) - { - item.MainPath.Empty(); - item.MainIsDir = true; - } - else - { - RINOK(GetItemPath2(parentIndex, item.MainPath)); - RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)); - } - } - } - } - - if (item.WriteToAltStreamIfColon || needFindAltStream) - { - /* Good handler must support GetRawProps::GetParent for alt streams./ - So the following code currently is not used */ - int colon = FindAltStreamColon_in_Path(item.Path); - if (colon >= 0) - { - item.MainPath.DeleteFrom(colon); - item.AltStreamName = item.Path.Ptr(colon + 1); - item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1])); - item.IsAltStream = true; - } - } - - #endif - - #ifndef _SFX - if (item._use_baseParentFolder_mode) - { - RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts)); - - #ifdef SUPPORT_ALT_STREAMS - if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) - { - int colon; - { - UString &s = item.PathParts.Back(); - colon = FindAltStreamColon_in_Path(s); - if (colon >= 0) - { - item.AltStreamName = s.Ptr(colon + 1); - item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1])); - item.IsAltStream = true; - s.DeleteFrom(colon); - } - } - if (colon == 0) - item.PathParts.DeleteBack(); - } - #endif - - } - else - #endif - SplitPathToParts( - #ifdef SUPPORT_ALT_STREAMS - item.MainPath - #else - item.Path - #endif - , item.PathParts); - - return S_OK; -} - -#ifndef _SFX - -static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined) -{ - NCOM::CPropVariant prop; - defined = false; - size = 0; - RINOK(archive->GetProperty(index, kpidSize, &prop)); - switch (prop.vt) - { - case VT_UI1: size = prop.bVal; break; - case VT_UI2: size = prop.uiVal; break; - case VT_UI4: size = prop.ulVal; break; - case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; - case VT_EMPTY: return S_OK; - default: return E_FAIL; - } - defined = true; - return S_OK; -} - -#endif - -HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const -{ - NCOM::CPropVariant prop; - defined = false; - size = 0; - RINOK(Archive->GetProperty(index, kpidSize, &prop)); - switch (prop.vt) - { - case VT_UI1: size = prop.bVal; break; - case VT_UI2: size = prop.uiVal; break; - case VT_UI4: size = prop.ulVal; break; - case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; - case VT_EMPTY: return S_OK; - default: return E_FAIL; - } - defined = true; - return S_OK; -} - -HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const -{ - 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; - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - else if (MTimeDefined) - { - ft = MTime; - defined = true; - } - return S_OK; -} - -#ifndef _SFX - -static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) -{ - for (size_t i = 0; i < size; i++) - if (p1[i] != p2[i]) - return false; - return true; -} - -static void MakeCheckOrder(CCodecs *codecs, - CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, - const Byte *data, size_t dataSize) -{ - for (unsigned i = 0; i < numTypes; i++) - { - int index = orderIndices[i]; - if (index < 0) - continue; - const CArcInfoEx &ai = codecs->Formats[index]; - if (ai.SignatureOffset != 0) - { - orderIndices2.Add(index); - orderIndices[i] = -1; - continue; - } - - const CObjectVector &sigs = ai.Signatures; - FOR_VECTOR (k, sigs) - { - const CByteBuffer &sig = sigs[k]; - if (sig.Size() == 0 && dataSize == 0 || - sig.Size() != 0 && sig.Size() <= dataSize && - TestSignature(data, sig, sig.Size())) - { - orderIndices2.Add(index); - orderIndices[i] = -1; - break; - } - } - } -} - -#endif - -#ifdef UNDER_CE - static const unsigned kNumHashBytes = 1; - #define HASH_VAL(buf, pos) ((buf)[pos]) -#else - static const unsigned kNumHashBytes = 2; - #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8)) -#endif - - -#ifndef _SFX - -static bool IsExeExt(const UString &ext) -{ - return ext.IsEqualTo_Ascii_NoCase("exe"); -} - -static const char * const k_PreArcFormats[] = -{ - "pe" - , "elf" - , "macho" - , "mub" - , "te" -}; - -static bool IsNameFromList(const UString &s, const char * const names[], size_t num) -{ - for (unsigned i = 0; i < num; i++) - if (StringsAreEqualNoCase_Ascii(s, names[i])) - return true; - return false; -} - - -static bool IsPreArcFormat(const CArcInfoEx &ai) -{ - if (ai.Flags_PreArc()) - return true; - return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats)); -} - -static const char * const k_Formats_with_simple_signuature[] = -{ - "7z" - , "xz" - , "rar" - , "bzip2" - , "gzip" - , "cab" - , "wim" - , "rpm" - , "vhd" - , "xar" -}; - -static bool IsNewStyleSignature(const CArcInfoEx &ai) -{ - // if (ai.Version >= 0x91F) - if (ai.NewInterface) - return true; - return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, ARRAY_SIZE(k_Formats_with_simple_signuature)); -} - -class CArchiveOpenCallback_Offset: - public IArchiveOpenCallback, - public IArchiveOpenVolumeCallback, - #ifndef _NO_CRYPTO - public ICryptoGetTextPassword, - #endif - public CMyUnknownImp -{ -public: - CMyComPtr Callback; - CMyComPtr OpenVolumeCallback; - UInt64 Files; - UInt64 Offset; - - #ifndef _NO_CRYPTO - CMyComPtr GetTextPassword; - #endif - - MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback) - MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif -}; - -#ifndef _NO_CRYPTO -STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - if (GetTextPassword) - return GetTextPassword->CryptoGetTextPassword(password); - return E_NOTIMPL; - COM_TRY_END -} -#endif - -STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *) -{ - return S_OK; -} - -STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes) -{ - if (!Callback) - return S_OK; - UInt64 value = Offset; - if (bytes) - value += *bytes; - return Callback->SetCompleted(&Files, &value); -} - -STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value) -{ - if (OpenVolumeCallback) - return OpenVolumeCallback->GetProperty(propID, value); - NCOM::PropVariant_Clear(value); - return S_OK; - // return E_NOTIMPL; -} - -STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream) -{ - if (OpenVolumeCallback) - return OpenVolumeCallback->GetStream(name, inStream); - return S_FALSE; -} - -#endif - - -UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp) -{ - if (isDefinedProp != NULL) - *isDefinedProp = false; - - switch (prop.vt) - { - case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart; - case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal; - case VT_EMPTY: return 0; - default: throw 151199; - } -} - -void CArcErrorInfo::ClearErrors() -{ - // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!! - - ThereIsTail = false; - UnexpecedEnd = false; - IgnoreTail = false; - // NonZerosTail = false; - ErrorFlags_Defined = false; - ErrorFlags = 0; - WarningFlags = 0; - TailSize = 0; - - ErrorMessage.Empty(); - WarningMessage.Empty(); -} - -HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) -{ - // OkPhySize_Defined = false; - PhySizeDefined = false; - PhySize = 0; - Offset = 0; - AvailPhySize = FileSize - startPos; - - ErrorInfo.ClearErrors(); - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)); - ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined); - } - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)); - ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop); - } - - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidError, &prop)); - if (prop.vt != VT_EMPTY) - ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error"); - } - - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidWarning, &prop)); - if (prop.vt != VT_EMPTY) - ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning"); - } - - if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) - { - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined)); - /* - RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); - if (!OkPhySize_Defined) - { - OkPhySize_Defined = PhySizeDefined; - OkPhySize = PhySize; - } - */ - - bool offsetDefined; - RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)); - - Int64 globalOffset = startPos + Offset; - AvailPhySize = FileSize - globalOffset; - if (PhySizeDefined) - { - UInt64 endPos = globalOffset + PhySize; - if (endPos < FileSize) - { - AvailPhySize = PhySize; - ErrorInfo.ThereIsTail = true; - ErrorInfo.TailSize = FileSize - endPos; - } - else if (endPos > FileSize) - ErrorInfo.UnexpecedEnd = true; - } - } - - return S_OK; -} - -/* -static PrintNumber(const char *s, int n) -{ - char temp[100]; - sprintf(temp, "%s %d", s, n); - OutputDebugStringA(temp); -} -*/ - -HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr &archive) -{ - // OutputDebugStringA("a1"); - // PrintNumber("formatIndex", formatIndex); - - RINOK(op.codecs->CreateInArchive(formatIndex, archive)); - // OutputDebugStringA("a2"); - if (!archive) - return S_OK; - - #ifdef EXTERNAL_CODECS - if (op.codecs->NeedSetLibCodecs) - { - const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; - if (ai.LibIndex >= 0 ? - !op.codecs->Libs[ai.LibIndex].SetCodecs : - !op.codecs->Libs.IsEmpty()) - { - CMyComPtr setCompressCodecsInfo; - archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)); - } - } - } - #endif - - - #ifndef _SFX - - const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; - - // OutputDebugStringW(ai.Name); - // OutputDebugStringA("a3"); - - if (ai.Flags_PreArc()) - { - /* we notify parsers that extract executables, that they don't need - to open archive, if there is tail after executable (for SFX cases) */ - CMyComPtr allowTail; - archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail); - if (allowTail) - allowTail->AllowTail(BoolToInt(true)); - } - - if (op.props) - { - /* - FOR_VECTOR (y, op.props) - { - const COptionalOpenProperties &optProps = (*op.props)[y]; - if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0) - { - RINOK(SetProperties(archive, optProps.Props)); - break; - } - } - */ - RINOK(SetProperties(archive, *op.props)); - } - - #endif - return S_OK; -} - -#ifndef _SFX - -static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi) -{ - pi.Extension = ai.GetMainExt(); - pi.FileTime_Defined = false; - pi.ArcType = ai.Name; - - RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType)); - - // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe)); - pi.IsSelfExe = ai.Flags_PreArc(); - - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidMTime, &prop)); - if (prop.vt == VT_FILETIME) - { - pi.FileTime_Defined = true; - pi.FileTime = prop.filetime; - } - } - - if (!pi.FileTime_Defined) - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidCTime, &prop)); - if (prop.vt == VT_FILETIME) - { - pi.FileTime_Defined = true; - pi.FileTime = prop.filetime; - } - } - - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidName, &prop)); - if (prop.vt == VT_BSTR) - { - pi.Name.SetFromBstr(prop.bstrVal); - pi.Extension.Empty(); - } - else - { - RINOK(archive->GetArchiveProperty(kpidExtension, &prop)); - if (prop.vt == VT_BSTR) - pi.Extension.SetFromBstr(prop.bstrVal); - } - } - - { - NCOM::CPropVariant prop; - RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)); - if (prop.vt == VT_BSTR) - pi.Comment.SetFromBstr(prop.bstrVal); - } - - - UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - - // pi.NumSubFiles = numItems; - // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined)); - // if (!pi.UnpackSize_Defined) - { - pi.NumSubFiles = 0; - pi.NumSubDirs = 0; - pi.UnpackSize = 0; - for (UInt32 i = 0; i < numItems; i++) - { - UInt64 size = 0; - bool defined = false; - Archive_GetItem_Size(archive, i, size, defined); - if (defined) - { - pi.UnpackSize_Defined = true; - pi.UnpackSize += size; - } - - bool isDir = false; - Archive_IsItem_Dir(archive, i, isDir); - if (isDir) - pi.NumSubDirs++; - else - pi.NumSubFiles++; - } - if (pi.NumSubDirs != 0) - pi.NumSubDirs_Defined = true; - pi.NumSubFiles_Defined = true; - } - - return S_OK; -} - -#endif - -HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) -{ - if (!op.stream) - return S_OK; - RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL)); - const UInt32 kBufSize = 1 << 11; - Byte buf[kBufSize]; - - for (;;) - { - UInt32 processed = 0; - RINOK(op.stream->Read(buf, kBufSize, &processed)); - if (processed == 0) - { - // ErrorInfo.NonZerosTail = false; - ErrorInfo.IgnoreTail = true; - return S_OK; - } - for (size_t i = 0; i < processed; i++) - { - if (buf[i] != 0) - { - // ErrorInfo.IgnoreTail = false; - // ErrorInfo.NonZerosTail = true; - return S_OK; - } - } - } -} - -#ifndef _SFX - -class CExtractCallback_To_OpenCallback: - public IArchiveExtractCallback, - public ICompressProgressInfo, - public CMyUnknownImp -{ -public: - CMyComPtr Callback; - UInt64 Files; - UInt64 Offset; - - MY_UNKNOWN_IMP2(IArchiveExtractCallback, ICompressProgressInfo) - INTERFACE_IArchiveExtractCallback(;) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - void Init(IArchiveOpenCallback *callback) - { - Callback = callback; - Files = 0; - Offset = 0; - } -}; - -STDMETHODIMP CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */) -{ - return S_OK; -} - -STDMETHODIMP CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */) -{ - return S_OK; -} - -STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */) -{ - if (Callback) - { - UInt64 value = Offset; - if (inSize) - value += *inSize; - return Callback->SetCompleted(&Files, &value); - } - return S_OK; -} - -STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */) -{ - *outStream = 0; - return S_OK; -} - -STDMETHODIMP CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */) -{ - return S_OK; -} - -STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */) -{ - return S_OK; -} - -static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, - IInStream *stream, const UInt64 *maxCheckStartPosition, - IArchiveOpenCallback *openCallback, - IArchiveExtractCallback *extractCallback) -{ - /* - if (needPhySize) - { - CMyComPtr open2; - archive->QueryInterface(IID_IArchiveOpen2, (void **)&open2); - if (open2) - return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback); - } - */ - RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)); - if (needPhySize) - { - bool phySize_Defined = false; - UInt64 phySize = 0; - RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)); - if (phySize_Defined) - return S_OK; - - bool phySizeCantBeDetected = false;; - RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)); - - if (!phySizeCantBeDetected) - { - RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)); - } - } - return S_OK; -} - -static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name) -{ - FOR_VECTOR (i, orderIndices) - if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name)) - return i; - return -1; -} - -#endif - -HRESULT CArc::OpenStream2(const COpenOptions &op) -{ - // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout); - - Archive.Release(); - GetRawProps.Release(); - GetRootProps.Release(); - - ErrorInfo.ClearErrors(); - ErrorInfo.ErrorFormatIndex = -1; - - IsParseArc = false; - ArcStreamOffset = 0; - - // OutputDebugStringA("1"); - // OutputDebugStringW(Path); - - const UString fileName = ExtractFileNameFromPath(Path); - UString extension; - { - int dotPos = fileName.ReverseFind_Dot(); - if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); - } - - CIntVector orderIndices; - - bool searchMarkerInHandler = false; - #ifdef _SFX - searchMarkerInHandler = true; - #endif - - CBoolArr isMainFormatArr(op.codecs->Formats.Size()); - { - FOR_VECTOR(i, op.codecs->Formats) - isMainFormatArr[i] = false; - } - - UInt64 maxStartOffset = - op.openType.MaxStartOffset_Defined ? - op.openType.MaxStartOffset : - kMaxCheckStartPosition; - - #ifndef _SFX - bool isUnknownExt = false; - #endif - - bool isForced = false; - unsigned numMainTypes = 0; - int formatIndex = op.openType.FormatIndex; - - if (formatIndex >= 0) - { - isForced = true; - orderIndices.Add(formatIndex); - numMainTypes = 1; - isMainFormatArr[(unsigned)formatIndex] = true; - - searchMarkerInHandler = true; - } - else - { - unsigned numFinded = 0; - #ifndef _SFX - bool isPrearcExt = false; - #endif - - { - #ifndef _SFX - - bool isZip = false; - bool isRar = false; - - const wchar_t c = extension[0]; - if (c == 'z' || c == 'Z' || c == 'r' || c == 'R') - { - bool isNumber = false; - for (unsigned k = 1;; k++) - { - const wchar_t d = extension[k]; - if (d == 0) - break; - if (d < '0' || d > '9') - { - isNumber = false; - break; - } - isNumber = true; - } - if (isNumber) - if (c == 'z' || c == 'Z') - isZip = true; - else - isRar = true; - } - - #endif - - FOR_VECTOR (i, op.codecs->Formats) - { - const CArcInfoEx &ai = op.codecs->Formats[i]; - - if (IgnoreSplit || !op.openType.CanReturnArc) - if (ai.IsSplit()) - continue; - if (op.excludedFormats->FindInSorted(i) >= 0) - continue; - - #ifndef _SFX - if (IsPreArcFormat(ai)) - isPrearcExt = true; - #endif - - if (ai.FindExtension(extension) >= 0 - #ifndef _SFX - || isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip") - || isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar") - #endif - ) - { - // PrintNumber("orderIndices.Insert", i); - orderIndices.Insert(numFinded++, i); - isMainFormatArr[i] = true; - } - else - orderIndices.Add(i); - } - } - - if (!op.stream) - { - if (numFinded != 1) - return E_NOTIMPL; - orderIndices.DeleteFrom(1); - } - // PrintNumber("numFinded", numFinded ); - - /* - if (op.openOnlySpecifiedByExtension) - { - if (numFinded != 0 && !IsExeExt(extension)) - orderIndices.DeleteFrom(numFinded); - } - */ - - #ifndef _SFX - - if (op.stream && orderIndices.Size() >= 2) - { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - CByteBuffer byteBuffer; - CIntVector orderIndices2; - if (numFinded == 0 || IsExeExt(extension)) - { - // signature search was here - } - else if (extension.IsEqualTo("000") || extension.IsEqualTo("001")) - { - int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); - if (i >= 0) - { - const size_t kBufSize = (1 << 10); - byteBuffer.Alloc(kBufSize); - size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); - if (processedSize >= 16) - { - const Byte *buf = byteBuffer; - const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; - if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0) - { - orderIndices2.Add(orderIndices[i]); - orderIndices[i] = -1; - if (i >= (int)numFinded) - numFinded++; - } - } - } - } - else - { - const size_t kBufSize = (1 << 10); - byteBuffer.Alloc(kBufSize); - size_t processedSize = kBufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); - if (processedSize == 0) - return S_FALSE; - - /* - check type order: - 1) matched extension, no signuature - 2) matched extension, matched signuature - // 3) no signuature - // 4) matched signuature - */ - - MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0); - MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize); - // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0); - // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize); - } - - FOR_VECTOR (i, orderIndices) - { - int val = orderIndices[i]; - if (val != -1) - orderIndices2.Add(val); - } - orderIndices = orderIndices2; - } - - if (orderIndices.Size() >= 2) - { - int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); - int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); - if (iUdf > iIso && iIso >= 0) - { - int isoIndex = orderIndices[iIso]; - int udfIndex = orderIndices[iUdf]; - orderIndices[iUdf] = isoIndex; - orderIndices[iIso] = udfIndex; - } - } - - numMainTypes = numFinded; - isUnknownExt = (numMainTypes == 0) || isPrearcExt; - - #else // _SFX - - numMainTypes = orderIndices.Size(); - - // we need correct numMainTypes for mutlivolume SFX (if some volume is missing) - if (numFinded != 0) - numMainTypes = numFinded; - - #endif - } - - UInt64 fileSize = 0; - if (op.stream) - { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - FileSize = fileSize; - - - #ifndef _SFX - - CBoolArr skipFrontalFormat(op.codecs->Formats.Size()); - { - FOR_VECTOR(i, op.codecs->Formats) - skipFrontalFormat[i] = false; - } - - #endif - - const COpenType &mode = op.openType; - - - - - - if (mode.CanReturnArc) - { - // ---------- OPEN main type by extenssion ---------- - - unsigned numCheckTypes = orderIndices.Size(); - if (formatIndex >= 0) - numCheckTypes = numMainTypes; - - for (unsigned i = 0; i < numCheckTypes; i++) - { - FormatIndex = orderIndices[i]; - - bool exactOnly = false; - - #ifndef _SFX - - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; - // OutputDebugStringW(ai.Name); - if (i >= numMainTypes) - { - if (!ai.Flags_BackwardOpen() - // && !ai.Flags_PureStartOpen() - ) - continue; - exactOnly = true; - } - - #endif - - // Some handlers do not set total bytes. So we set it here - if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); - - if (op.stream) - { - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - - CMyComPtr archive; - - RINOK(PrepareToOpen(op, FormatIndex, archive)); - if (!archive) - continue; - - HRESULT result; - if (op.stream) - { - UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0; - result = archive->Open(op.stream, &searchLimit, op.callback); - } - else - { - CMyComPtr openSeq; - archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq); - if (!openSeq) - return E_NOTIMPL; - result = openSeq->OpenSeq(op.seqStream); - } - - RINOK(ReadBasicProps(archive, 0, result)); - - if (result == S_FALSE) - { - bool isArc = ErrorInfo.IsArc_After_NonOpen(); - - #ifndef _SFX - // if it's archive, we allow another open attempt for parser - if (!mode.CanReturnParser || !isArc) - skipFrontalFormat[(unsigned)FormatIndex] = true; - #endif - - if (exactOnly) - continue; - - if (i == 0 && numMainTypes == 1) - { - // we set NonOpenErrorInfo, only if there is only one main format (defined by extension). - ErrorInfo.ErrorFormatIndex = FormatIndex; - NonOpen_ErrorInfo = ErrorInfo; - - if (!mode.CanReturnParser && isArc) - { - // if (formatIndex < 0 && !searchMarkerInHandler) - { - // if bad archive was detected, we don't need additional open attempts - #ifndef _SFX - if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */) - #endif - return S_FALSE; - } - } - } - - /* - #ifndef _SFX - if (IsExeExt(extension) || ai.Flags_PreArc()) - { - // openOnlyFullArc = false; - // canReturnTailArc = true; - // limitSignatureSearch = true; - } - #endif - */ - - continue; - } - - RINOK(result); - - #ifndef _SFX - - bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; - const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); - - bool thereIsTail = ErrorInfo.ThereIsTail; - if (thereIsTail && mode.ZerosTailIsAllowed) - { - RINOK(CheckZerosTail(op, Offset + PhySize)); - if (ErrorInfo.IgnoreTail) - thereIsTail = false; - } - - if (Offset > 0) - { - if (exactOnly - || !searchMarkerInHandler - || !specFlags.CanReturn_NonStart() - || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset)) - continue; - } - if (thereIsTail) - { - if (Offset > 0) - { - if (!specFlags.CanReturnMid) - continue; - } - else if (!specFlags.CanReturnFrontal) - continue; - } - - if (Offset > 0 || thereIsTail) - { - if (formatIndex < 0) - { - if (IsPreArcFormat(ai)) - { - // openOnlyFullArc = false; - // canReturnTailArc = true; - /* - if (mode.SkipSfxStub) - limitSignatureSearch = true; - */ - // if (mode.SkipSfxStub) - { - // skipFrontalFormat[FormatIndex] = true; - continue; - } - } - } - } - - #endif - - Archive = archive; - return S_OK; - } - } - - - - #ifndef _SFX - - if (!op.stream) - return S_FALSE; - - if (formatIndex >= 0 && !mode.CanReturnParser) - { - if (mode.MaxStartOffset_Defined) - { - if (mode.MaxStartOffset == 0) - return S_FALSE; - } - else - { - const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; - if (ai.FindExtension(extension) >= 0) - { - if (ai.Flags_FindSignature() && searchMarkerInHandler) - return S_FALSE; - } - } - } - - NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler; - CMyComPtr handler = handlerSpec; - - CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback; - CMyComPtr extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec; - extractCallback_To_OpenCallback_Spec->Init(op.callback); - - { - // ---------- Check all possible START archives ---------- - // this code is better for full file archives than Parser's code. - - CByteBuffer byteBuffer; - bool endOfFile = false; - size_t processedSize; - { - size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF) - if (bufSize > fileSize) - { - bufSize = (size_t)fileSize; - endOfFile = true; - } - byteBuffer.Alloc(bufSize); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - processedSize = bufSize; - RINOK(ReadStream(op.stream, byteBuffer, &processedSize)); - if (processedSize == 0) - return S_FALSE; - if (processedSize < bufSize) - endOfFile = true; - } - CUIntVector sortedFormats; - - unsigned i; - - int splitIndex = -1; - - for (i = 0; i < orderIndices.Size(); i++) - { - unsigned form = orderIndices[i]; - if (skipFrontalFormat[form]) - continue; - const CArcInfoEx &ai = op.codecs->Formats[form]; - if (ai.IsSplit()) - { - splitIndex = form; - continue; - } - - if (ai.IsArcFunc) - { - UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize); - if (isArcRes == k_IsArc_Res_NO) - continue; - if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) - continue; - // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue; - sortedFormats.Insert(0, form); - continue; - } - - bool isNewStyleSignature = IsNewStyleSignature(ai); - bool needCheck = !isNewStyleSignature - || ai.Signatures.IsEmpty() - || ai.Flags_PureStartOpen() - || ai.Flags_StartOpen() - || ai.Flags_BackwardOpen(); - - if (isNewStyleSignature && !ai.Signatures.IsEmpty()) - { - unsigned k; - for (k = 0; k < ai.Signatures.Size(); k++) - { - const CByteBuffer &sig = ai.Signatures[k]; - UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); - if (processedSize < signatureEnd) - { - if (!endOfFile) - needCheck = true; - } - else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0) - break; - } - if (k != ai.Signatures.Size()) - { - sortedFormats.Insert(0, form); - continue; - } - } - if (needCheck) - sortedFormats.Add(form); - } - - if (splitIndex >= 0) - sortedFormats.Insert(0, splitIndex); - - for (i = 0; i < sortedFormats.Size(); i++) - { - FormatIndex = sortedFormats[i]; - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; - - if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); - - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - - CMyComPtr archive; - RINOK(PrepareToOpen(op, FormatIndex, archive)); - if (!archive) - continue; - - PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name)); - HRESULT result; - { - UInt64 searchLimit = 0; - /* - if (mode.CanReturnArc) - result = archive->Open(op.stream, &searchLimit, op.callback); - else - */ - result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); - } - - if (result == S_FALSE) - { - skipFrontalFormat[(unsigned)FormatIndex] = true; - // FIXME: maybe we must use LenIsUnknown. - // printf(" OpenForSize Error"); - continue; - } - RINOK(result); - - RINOK(ReadBasicProps(archive, 0, result)); - - if (Offset > 0) - { - continue; // good handler doesn't return such Offset > 0 - // but there are some cases like false prefixed PK00 archive, when - // we can support it? - } - - NArchive::NParser::CParseItem pi; - pi.Offset = Offset; - pi.Size = AvailPhySize; - - // bool needScan = false; - - if (!PhySizeDefined) - { - // it's for Z format - pi.LenIsUnknown = true; - // needScan = true; - // phySize = arcRem; - // nextNeedCheckStartOpen = false; - } - - /* - if (OkPhySize_Defined) - pi.OkSize = pi.OkPhySize; - else - pi.OkSize = pi.Size; - */ - - pi.NormalizeOffset(); - // printf(" phySize = %8d", (unsigned)phySize); - - - if (mode.CanReturnArc) - { - bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; - const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); - bool openCur = false; - - if (!ErrorInfo.ThereIsTail) - openCur = true; - else - { - if (mode.ZerosTailIsAllowed) - { - RINOK(CheckZerosTail(op, Offset + PhySize)); - if (ErrorInfo.IgnoreTail) - openCur = true; - } - if (!openCur) - { - openCur = specFlags.CanReturnFrontal; - if (formatIndex < 0) // format is not forced - { - if (IsPreArcFormat(ai)) - { - // if (mode.SkipSfxStub) - { - openCur = false; - } - } - } - } - } - - if (openCur) - { - InStream = op.stream; - Archive = archive; - return S_OK; - } - } - - skipFrontalFormat[(unsigned)FormatIndex] = true; - - - // if (!mode.CanReturnArc) - /* - if (!ErrorInfo.ThereIsTail) - continue; - */ - if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) - continue; - - // printf("\nAdd offset = %d", (int)pi.Offset); - RINOK(ReadParseItemProps(archive, ai, pi)); - handlerSpec->AddItem(pi); - } - } - - - - - - // ---------- PARSER ---------- - - CUIntVector arc2sig; // formatIndex to signatureIndex - CUIntVector sig2arc; // signatureIndex to formatIndex; - { - unsigned sum = 0; - FOR_VECTOR (i, op.codecs->Formats) - { - arc2sig.Add(sum); - const CObjectVector &sigs = op.codecs->Formats[i].Signatures; - sum += sigs.Size(); - FOR_VECTOR (k, sigs) - sig2arc.Add(i); - } - } - - { - const size_t kBeforeSize = 1 << 16; - const size_t kAfterSize = 1 << 20; - const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize - - const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8); - CByteArr hashBuffer(kNumVals); - Byte *hash = hashBuffer; - memset(hash, 0xFF, kNumVals); - Byte prevs[256]; - memset(prevs, 0xFF, sizeof(prevs)); - if (sig2arc.Size() >= 0xFF) - return S_FALSE; - - CUIntVector difficultFormats; - CBoolArr difficultBools(256); - { - for (unsigned i = 0; i < 256; i++) - difficultBools[i] = false; - } - - bool thereAreHandlersForSearch = false; - - // UInt32 maxSignatureEnd = 0; - - FOR_VECTOR (i, orderIndices) - { - int index = orderIndices[i]; - if (index < 0) - continue; - const CArcInfoEx &ai = op.codecs->Formats[index]; - bool isDifficult = false; - // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) - if (!ai.NewInterface) - isDifficult = true; - else - { - if (ai.Flags_StartOpen()) - isDifficult = true; - FOR_VECTOR (k, ai.Signatures) - { - const CByteBuffer &sig = ai.Signatures[k]; - /* - UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); - if (maxSignatureEnd < signatureEnd) - maxSignatureEnd = signatureEnd; - */ - if (sig.Size() < kNumHashBytes) - { - isDifficult = true; - continue; - } - thereAreHandlersForSearch = true; - UInt32 v = HASH_VAL(sig, 0); - unsigned sigIndex = arc2sig[(unsigned)index] + k; - prevs[sigIndex] = hash[v]; - hash[v] = (Byte)sigIndex; - } - } - if (isDifficult) - { - difficultFormats.Add(index); - difficultBools[index] = true; - } - } - - if (!thereAreHandlersForSearch) - { - // openOnlyFullArc = true; - // canReturnTailArc = true; - } - - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - - CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream; - CMyComPtr limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(op.stream); - - CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL; - CMyComPtr openCallback_Offset; - if (op.callback) - { - openCallback_Offset_Spec = new CArchiveOpenCallback_Offset; - openCallback_Offset = openCallback_Offset_Spec; - openCallback_Offset_Spec->Callback = op.callback; - openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); - #ifndef _NO_CRYPTO - openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); - #endif - } - - if (op.callback) - RINOK(op.callback->SetTotal(NULL, &fileSize)); - - CByteBuffer &byteBuffer = limitedStreamSpec->Buffer; - byteBuffer.Alloc(kBufSize); - - UInt64 callbackPrev = 0; - bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos. - - bool endOfFile = false; - UInt64 bufPhyPos = 0; - size_t bytesInBuf = 0; - // UInt64 prevPos = 0; - - // ---------- Main Scan Loop ---------- - - UInt64 pos = 0; - - if (!mode.EachPos && handlerSpec->_items.Size() == 1) - { - NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; - if (!pi.LenIsUnknown && pi.Offset == 0) - pos = pi.Size; - } - - for (;;) - { - // printf("\nPos = %d", (int)pos); - UInt64 posInBuf = pos - bufPhyPos; - - // if (pos > ((UInt64)1 << 35)) break; - - if (!endOfFile) - { - if (bytesInBuf < kBufSize) - { - size_t processedSize = kBufSize - bytesInBuf; - // printf("\nRead ask = %d", (unsigned)processedSize); - UInt64 seekPos = bufPhyPos + bytesInBuf; - RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL)); - RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize)); - // printf(" processed = %d", (unsigned)processedSize); - if (processedSize == 0) - { - fileSize = seekPos; - endOfFile = true; - } - else - { - bytesInBuf += processedSize; - limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos); - } - continue; - } - - if (bytesInBuf < posInBuf) - { - UInt64 skipSize = posInBuf - bytesInBuf; - if (skipSize <= kBeforeSize) - { - size_t keepSize = (size_t)(kBeforeSize - skipSize); - // printf("\nmemmove skip = %d", (int)keepSize); - memmove(byteBuffer, byteBuffer + bytesInBuf - keepSize, keepSize); - bytesInBuf = keepSize; - bufPhyPos = pos - keepSize; - continue; - } - // printf("\nSkip %d", (int)(skipSize - kBeforeSize)); - // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL)); - bytesInBuf = 0; - bufPhyPos = pos - kBeforeSize; - continue; - } - - if (bytesInBuf - posInBuf < kAfterSize) - { - size_t beg = (size_t)posInBuf - kBeforeSize; - // printf("\nmemmove for after beg = %d", (int)beg); - memmove(byteBuffer, byteBuffer + beg, bytesInBuf - beg); - bufPhyPos += beg; - bytesInBuf -= beg; - continue; - } - } - - bool useOffsetCallback = false; - if (openCallback_Offset) - { - openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); - openCallback_Offset_Spec->Offset = pos; - - useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1); - - if (pos >= callbackPrev + (1 << 23)) - { - RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL)); - callbackPrev = pos; - } - } - - { - UInt64 endPos = bufPhyPos + bytesInBuf; - if (fileSize < endPos) - { - FileSize = fileSize; // why ???? - fileSize = endPos; - } - } - - size_t availSize = bytesInBuf - (size_t)posInBuf; - if (availSize < kNumHashBytes) - break; - size_t scanSize = availSize - - ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes); - - { - /* - UInt64 scanLimit = openOnlyFullArc ? - maxSignatureEnd : - op.openType.ScanSize + maxSignatureEnd; - */ - if (!mode.CanReturnParser) - { - if (pos > maxStartOffset) - break; - UInt64 remScan = maxStartOffset - pos; - if (scanSize > remScan) - scanSize = (size_t)remScan; - } - } - - scanSize++; - - const Byte *buf = byteBuffer + (size_t)posInBuf; - size_t ppp = 0; - - if (!needCheckStartOpen) - { - for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++); - pos += ppp; - if (ppp == scanSize) - continue; - } - - UInt32 v = HASH_VAL(buf, ppp); - bool nextNeedCheckStartOpen = true; - unsigned i = hash[v]; - unsigned indexOfDifficult = 0; - - // ---------- Open Loop for Current Pos ---------- - bool wasOpen = false; - - for (;;) - { - unsigned index; - bool isDifficult; - if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size()) - { - index = difficultFormats[indexOfDifficult++]; - isDifficult = true; - } - else - { - if (i == 0xFF) - break; - index = sig2arc[i]; - unsigned sigIndex = i - arc2sig[index]; - i = prevs[i]; - if (needCheckStartOpen && difficultBools[index]) - continue; - const CArcInfoEx &ai = op.codecs->Formats[index]; - - if (pos < ai.SignatureOffset) - continue; - - /* - if (openOnlyFullArc) - if (pos != ai.SignatureOffset) - continue; - */ - - const CByteBuffer &sig = ai.Signatures[sigIndex]; - - if (ppp + sig.Size() > availSize - || !TestSignature(buf + ppp, sig, sig.Size())) - continue; - // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos)); - // prevPos = pos; - isDifficult = false; - } - - const CArcInfoEx &ai = op.codecs->Formats[index]; - - - if ((isDifficult && pos == 0) || ai.SignatureOffset == pos) - { - // we don't check same archive second time */ - if (skipFrontalFormat[index]) - continue; - } - - UInt64 startArcPos = pos; - if (!isDifficult) - { - if (pos < ai.SignatureOffset) - continue; - startArcPos = pos - ai.SignatureOffset; - /* - // we don't need the check for Z files - if (startArcPos < handlerSpec->GetLastEnd()) - continue; - */ - } - - if (ai.IsArcFunc && startArcPos >= bufPhyPos) - { - size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); - if (offsetInBuf < bytesInBuf) - { - UInt32 isArcRes = ai.IsArcFunc(byteBuffer + offsetInBuf, bytesInBuf - offsetInBuf); - if (isArcRes == k_IsArc_Res_NO) - continue; - if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) - continue; - /* - if (isArcRes == k_IsArc_Res_YES_LOW_PROB) - { - // if (pos != ai.SignatureOffset) - continue; - } - */ - } - // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name); - } - - /* - if (pos == 67109888) - pos = pos; - */ - PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name)); - - bool isMainFormat = isMainFormatArr[index]; - const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); - - CMyComPtr archive; - RINOK(PrepareToOpen(op, index, archive)); - if (!archive) - return E_FAIL; - - // OutputDebugStringW(ai.Name); - - UInt64 rem = fileSize - startArcPos; - - UInt64 arcStreamOffset = 0; - - if (ai.Flags_UseGlobalOffset()) - { - limitedStreamSpec->InitAndSeek(0, fileSize); - limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL); - } - else - { - limitedStreamSpec->InitAndSeek(startArcPos, rem); - arcStreamOffset = startArcPos; - } - - UInt64 maxCheckStartPosition = 0; - - if (openCallback_Offset) - { - openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); - openCallback_Offset_Spec->Offset = startArcPos; - } - - // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset); - extractCallback_To_OpenCallback_Spec->Files = 0; - extractCallback_To_OpenCallback_Spec->Offset = startArcPos; - - HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, - useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, - extractCallback_To_OpenCallback); - - RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)); - - bool isOpen = false; - if (result == S_FALSE) - { - if (!mode.CanReturnParser) - { - if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen()) - { - ErrorInfo.ErrorFormatIndex = index; - NonOpen_ErrorInfo = ErrorInfo; - // if archive was detected, we don't need additional open attempts - return S_FALSE; - } - continue; - } - if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0) - continue; - } - else - { - isOpen = true; - RINOK(result); - PRF(printf(" OK ")); - } - - // fprintf(stderr, "\n %8X %S", startArcPos, Path); - // printf("\nOpen OK: %S", ai.Name); - - - NArchive::NParser::CParseItem pi; - pi.Offset = startArcPos; - - if (ai.Flags_UseGlobalOffset()) - pi.Offset = Offset; - else if (Offset != 0) - return E_FAIL; - UInt64 arcRem = FileSize - pi.Offset; - UInt64 phySize = arcRem; - bool phySizeDefined = PhySizeDefined; - if (phySizeDefined) - { - if (pi.Offset + PhySize > FileSize) - { - // ErrorInfo.ThereIsTail = true; - PhySize = FileSize - pi.Offset; - } - phySize = PhySize; - } - if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63)) - return E_FAIL; - - /* - if (!ai.UseGlobalOffset) - { - if (phySize > arcRem) - { - ThereIsTail = true; - phySize = arcRem; - } - } - */ - - bool needScan = false; - - - if (isOpen && !phySizeDefined) - { - // it's for Z format - pi.LenIsUnknown = true; - needScan = true; - phySize = arcRem; - nextNeedCheckStartOpen = false; - } - - pi.Size = phySize; - /* - if (OkPhySize_Defined) - pi.OkSize = OkPhySize; - */ - pi.NormalizeOffset(); - // printf(" phySize = %8d", (unsigned)phySize); - - /* - if (needSkipFullArc) - if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize) - continue; - */ - if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) - { - // it's possible for dmg archives - if (!mode.CanReturnArc) - continue; - } - - if (mode.EachPos) - pos++; - else if (needScan) - { - pos++; - /* - if (!OkPhySize_Defined) - pos++; - else - pos = pi.Offset + pi.OkSize; - */ - } - else - pos = pi.Offset + pi.Size; - - - RINOK(ReadParseItemProps(archive, ai, pi)); - - if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */) - { - /* It's for DMG format. - This code deletes all previous items that are included to current item */ - - while (!handlerSpec->_items.IsEmpty()) - { - { - const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back(); - if (back.Offset < pi.Offset) - break; - if (back.Offset + back.Size > pi.Offset + pi.Size) - break; - } - handlerSpec->_items.DeleteBack(); - } - } - - - if (isOpen && mode.CanReturnArc && phySizeDefined) - { - // if (pi.Offset + pi.Size >= fileSize) - bool openCur = false; - - bool thereIsTail = ErrorInfo.ThereIsTail; - if (thereIsTail && mode.ZerosTailIsAllowed) - { - RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize)); - if (ErrorInfo.IgnoreTail) - thereIsTail = false; - } - - if (pi.Offset != 0) - { - if (!pi.IsNotArcType) - if (thereIsTail) - openCur = specFlags.CanReturnMid; - else - openCur = specFlags.CanReturnTail; - } - else - { - if (!thereIsTail) - openCur = true; - else - openCur = specFlags.CanReturnFrontal; - - - if (formatIndex >= -2) - openCur = true; - } - if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */) - openCur = false; - - // We open file as SFX, if there is front archive or first archive is "Self Executable" - if (!openCur && !pi.IsSelfExe && !thereIsTail && - (!pi.IsNotArcType || pi.Offset == 0)) - { - if (handlerSpec->_items.IsEmpty()) - { - if (specFlags.CanReturnTail) - openCur = true; - } - else if (handlerSpec->_items.Size() == 1) - { - if (handlerSpec->_items[0].IsSelfExe) - { - if (mode.SpecUnknownExt.CanReturnTail) - openCur = true; - } - } - } - - if (openCur) - { - InStream = op.stream; - Archive = archive; - FormatIndex = index; - ArcStreamOffset = arcStreamOffset; - return S_OK; - } - } - - /* - if (openOnlyFullArc) - { - ErrorInfo.ClearErrors(); - return S_FALSE; - } - */ - - pi.FormatIndex = index; - - // printf("\nAdd offset = %d", (int)pi.Offset); - handlerSpec->AddItem(pi); - wasOpen = true; - break; - } - // ---------- End of Open Loop for Current Pos ---------- - - if (!wasOpen) - pos++; - needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen); - } - // ---------- End of Main Scan Loop ---------- - - /* - if (handlerSpec->_items.Size() == 1) - { - const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; - if (pi.Size == fileSize && pi.Offset == 0) - { - Archive = archive; - FormatIndex2 = pi.FormatIndex; - return S_OK; - } - } - */ - - if (mode.CanReturnParser) - { - bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing - handlerSpec->AddUnknownItem(fileSize); - if (handlerSpec->_items.Size() == 0) - return S_FALSE; - if (returnParser || handlerSpec->_items.Size() != 1) - { - // return S_FALSE; - handlerSpec->_stream = op.stream; - Archive = handler; - ErrorInfo.ClearErrors(); - IsParseArc = true; - FormatIndex = -1; // It's parser - Offset = 0; - return S_OK; - } - } - } - - #endif - - if (!Archive) - return S_FALSE; - return S_OK; -} - -HRESULT CArc::OpenStream(const COpenOptions &op) -{ - RINOK(OpenStream2(op)); - // PrintNumber("op.formatIndex 3", op.formatIndex); - - if (Archive) - { - GetRawProps.Release(); - GetRootProps.Release(); - 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)); - - const UString fileName = ExtractFileNameFromPath(Path); - UString extension; - { - int dotPos = fileName.ReverseFind_Dot(); - if (dotPos >= 0) - extension = fileName.Ptr(dotPos + 1); - } - - DefaultName.Empty(); - if (FormatIndex >= 0) - { - const CArcInfoEx &ai = op.codecs->Formats[FormatIndex]; - if (ai.Exts.Size() == 0) - DefaultName = GetDefaultName2(fileName, UString(), UString()); - else - { - int subExtIndex = ai.FindExtension(extension); - if (subExtIndex < 0) - subExtIndex = 0; - const CArcExtInfo &extInfo = ai.Exts[subExtIndex]; - DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); - } - } - } - - return S_OK; -} - -#ifdef _SFX - -#ifdef _WIN32 - static const char *k_ExeExt = ".exe"; - static const unsigned k_ExeExt_Len = 4; -#else - static const char *k_ExeExt = ""; - static const unsigned k_ExeExt_Len = 0; -#endif - -#endif - -HRESULT CArc::OpenStreamOrFile(COpenOptions &op) -{ - CMyComPtr fileStream; - CMyComPtr seqStream; - CInFileStream *fileStreamSpec = NULL; - - if (op.stdInMode) - { - seqStream = new CStdInFileStream; - op.seqStream = seqStream; - } - else if (!op.stream) - { - fileStreamSpec = new CInFileStream(true); - fileStream = fileStreamSpec; - Path = filePath; - if (!fileStreamSpec->Open(us2fs(Path))) - { - return GetLastError(); - } - op.stream = fileStream; - #ifdef _SFX - IgnoreSplit = true; - #endif - } - - /* - if (callback) - { - UInt64 fileSize; - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.callback->SetTotal(NULL, &fileSize)) - } - */ - - HRESULT res = OpenStream(op); - IgnoreSplit = false; - - #ifdef _SFX - - if (res != S_FALSE - || !fileStreamSpec - || !op.callbackSpec - || NonOpen_ErrorInfo.IsArc_After_NonOpen()) - return res; - - { - if (filePath.Len() > k_ExeExt_Len - && StringsAreEqualNoCase_Ascii(filePath.RightPtr(k_ExeExt_Len), k_ExeExt)) - { - const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len); - FOR_VECTOR (i, op.codecs->Formats) - { - const CArcInfoEx &ai = op.codecs->Formats[i]; - if (ai.IsSplit()) - continue; - UString path3 = path2; - path3 += L'.'; - path3 += ai.GetMainExt(); // "7z" for SFX. - Path = path3; - Path.AddAscii(".001"); - bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); - if (!isOk) - { - Path = path3; - isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); - } - if (isOk) - { - if (fileStreamSpec->Open(us2fs(Path))) - { - op.stream = fileStream; - NonOpen_ErrorInfo.ClearErrors_Full(); - if (OpenStream(op) == S_OK) - return S_OK; - } - } - } - } - } - - #endif - - return res; -} - -void CArchiveLink::KeepModeForNextOpen() -{ - for (unsigned i = Arcs.Size(); i != 0;) - { - i--; - CMyComPtr keep; - Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep); - if (keep) - keep->KeepModeForNextOpen(); - } -} - -HRESULT CArchiveLink::Close() -{ - for (unsigned i = Arcs.Size(); i != 0;) - { - i--; - RINOK(Arcs[i].Close()); - } - IsOpen = false; - // ErrorsText.Empty(); - return S_OK; -} - -void CArchiveLink::Release() -{ - // NonOpenErrorFormatIndex = -1; - NonOpen_ErrorInfo.ClearErrors(); - NonOpen_ArcPath.Empty(); - while (!Arcs.IsEmpty()) - Arcs.DeleteBack(); -} - -/* -void CArchiveLink::Set_ErrorsText() -{ - FOR_VECTOR(i, Arcs) - { - const CArc &arc = Arcs[i]; - if (!arc.ErrorFlagsText.IsEmpty()) - { - if (!ErrorsText.IsEmpty()) - ErrorsText.Add_LF(); - ErrorsText += GetUnicodeString(arc.ErrorFlagsText); - } - if (!arc.ErrorMessage.IsEmpty()) - { - if (!ErrorsText.IsEmpty()) - ErrorsText.Add_LF(); - ErrorsText += arc.ErrorMessage; - } - - if (!arc.WarningMessage.IsEmpty()) - { - if (!ErrorsText.IsEmpty()) - ErrorsText.Add_LF(); - ErrorsText += arc.WarningMessage; - } - } -} -*/ - -HRESULT CArchiveLink::Open(COpenOptions &op) -{ - Release(); - if (op.types->Size() >= 32) - return E_NOTIMPL; - - HRESULT resSpec; - - for (;;) - { - resSpec = S_OK; - - op.openType = COpenType(); - if (op.types->Size() >= 1) - { - COpenType latest; - if (Arcs.Size() < op.types->Size()) - latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; - else - { - latest = (*op.types)[0]; - if (!latest.Recursive) - break; - } - op.openType = latest; - } - else if (Arcs.Size() >= 32) - break; - - /* - op.formatIndex = -1; - if (op.types->Size() >= 1) - { - int latest; - if (Arcs.Size() < op.types->Size()) - latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; - else - { - latest = (*op.types)[0]; - if (latest != -2 && latest != -3) - break; - } - if (latest >= 0) - op.formatIndex = latest; - else if (latest == -1 || latest == -2) - { - // default - } - else if (latest == -3) - op.formatIndex = -2; - else - op.formatIndex = latest + 2; - } - else if (Arcs.Size() >= 32) - break; - */ - - if (Arcs.IsEmpty()) - { - CArc arc; - arc.filePath = op.filePath; - arc.Path = op.filePath; - arc.SubfileIndex = (UInt32)(Int32)-1; - HRESULT result = arc.OpenStreamOrFile(op); - if (result != S_OK) - { - if (result == S_FALSE) - { - NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo; - // NonOpenErrorFormatIndex = arc.ErrorFormatIndex; - NonOpen_ArcPath = arc.Path; - } - return result; - } - Arcs.Add(arc); - continue; - } - - // PrintNumber("op.formatIndex 11", op.formatIndex); - - const CArc &arc = Arcs.Back(); - - if (op.types->Size() > Arcs.Size()) - resSpec = E_NOTIMPL; - - UInt32 mainSubfile; - { - NCOM::CPropVariant prop; - RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)); - if (prop.vt == VT_UI4) - mainSubfile = prop.ulVal; - else - break; - UInt32 numItems; - RINOK(arc.Archive->GetNumberOfItems(&numItems)); - if (mainSubfile >= numItems) - break; - } - - - CMyComPtr getStream; - if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) - break; - - CMyComPtr subSeqStream; - if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) - break; - - CMyComPtr subStream; - if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream) - break; - - CArc arc2; - RINOK(arc.GetItemPath(mainSubfile, arc2.Path)); - - bool zerosTailIsAllowed; - RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)); - - - if (op.callback) - { - CMyComPtr setSubArchiveName; - op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); - if (setSubArchiveName) - setSubArchiveName->SetSubArchiveName(arc2.Path); - } - - arc2.SubfileIndex = mainSubfile; - - // CIntVector incl; - CIntVector excl; - - COpenOptions op2; - #ifndef _SFX - op2.props = op.props; - #endif - op2.codecs = op.codecs; - // op2.types = &incl; - op2.openType = op.openType; - op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed; - op2.excludedFormats = ! - op2.stdInMode = false; - op2.stream = subStream; - op2.filePath = arc2.Path; - op2.callback = op.callback; - op2.callbackSpec = op.callbackSpec; - - - HRESULT result = arc2.OpenStream(op2); - resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE); - if (result == S_FALSE) - { - NonOpen_ErrorInfo = arc2.ErrorInfo; - NonOpen_ArcPath = arc2.Path; - break; - } - RINOK(result); - RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined)); - Arcs.Add(arc2); - } - IsOpen = !Arcs.IsEmpty(); - return resSpec; -} - -HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) -{ - VolumesSize = 0; - COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; - CMyComPtr callback = openCallbackSpec; - openCallbackSpec->Callback = callbackUI; - - FString prefix, name; - - if (!op.stream && !op.stdInMode) - { - NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); - openCallbackSpec->Init(prefix, name); - } - else - { - openCallbackSpec->SetSubArchiveName(op.filePath); - } - - op.callback = callback; - op.callbackSpec = openCallbackSpec; - - HRESULT res = Open(op); - - PasswordWasAsked = openCallbackSpec->PasswordWasAsked; - // Password = openCallbackSpec->Password; - - RINOK(res); - // VolumePaths.Add(fs2us(prefix + name)); - - FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed) - { - if (openCallbackSpec->FileNames_WasUsed[i]) - { - VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]); - VolumesSize += openCallbackSpec->FileSizes[i]; - } - } - // VolumesSize = openCallbackSpec->TotalSize; - return S_OK; -} - -HRESULT CArc::ReOpen(const COpenOptions &op) -{ - ErrorInfo.ClearErrors(); - ErrorInfo.ErrorFormatIndex = -1; - - UInt64 fileSize = 0; - if (op.stream) - { - RINOK(op.stream->Seek(0, STREAM_SEEK_END, &fileSize)); - RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL)); - } - FileSize = fileSize; - - CMyComPtr stream2; - Int64 globalOffset = GetGlobalOffset(); - if (globalOffset <= 0) - stream2 = op.stream; - else - { - CTailInStream *tailStreamSpec = new CTailInStream; - stream2 = tailStreamSpec; - tailStreamSpec->Stream = op.stream; - tailStreamSpec->Offset = globalOffset; - tailStreamSpec->Init(); - RINOK(tailStreamSpec->SeekToStart()); - } - - // There are archives with embedded STUBs (like ZIP), so we must support signature scanning - // But for another archives we can use 0 here. So the code can be fixed !!! - UInt64 maxStartPosition = kMaxCheckStartPosition; - HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback); - - if (res == S_OK) - { - RINOK(ReadBasicProps(Archive, globalOffset, res)); - ArcStreamOffset = globalOffset; - if (ArcStreamOffset != 0) - InStream = op.stream; - } - return res; -} - -HRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI) -{ - HRESULT res = Open2(op, callbackUI); - if (callbackUI) - { - RINOK(callbackUI->Open_Finished()); - } - return res; -} - -HRESULT CArchiveLink::ReOpen(COpenOptions &op) -{ - if (Arcs.Size() > 1) - return E_NOTIMPL; - - CObjectVector inc; - CIntVector excl; - - op.types = &inc; - op.excludedFormats = ! - op.stdInMode = false; - op.stream = NULL; - if (Arcs.Size() == 0) // ??? - return Open2(op, NULL); - - COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; - CMyComPtr openCallbackNew = openCallbackSpec; - - openCallbackSpec->Callback = NULL; - openCallbackSpec->ReOpenCallback = op.callback; - { - FString dirPrefix, fileName; - NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); - openCallbackSpec->Init(dirPrefix, fileName); - } - - - CInFileStream *fileStreamSpec = new CInFileStream(true); - CMyComPtr stream(fileStreamSpec); - if (!fileStreamSpec->Open(us2fs(op.filePath))) - return GetLastError(); - op.stream = stream; - - CArc &arc = Arcs[0]; - HRESULT res = arc.ReOpen(op); - - PasswordWasAsked = openCallbackSpec->PasswordWasAsked; - // Password = openCallbackSpec->Password; - - IsOpen = (res == S_OK); - return res; -} - -#ifndef _SFX - -bool ParseComplexSize(const wchar_t *s, UInt64 &result) -{ - result = 0; - const wchar_t *end; - UInt64 number = ConvertStringToUInt64(s, &end); - if (end == s) - return false; - if (*end == 0) - { - result = number; - return true; - } - if (end[1] != 0) - return false; - unsigned numBits; - switch (MyCharLower_Ascii(*end)) - { - case 'b': result = number; return true; - case 'k': numBits = 10; break; - case 'm': numBits = 20; break; - case 'g': numBits = 30; break; - case 't': numBits = 40; break; - default: return false; - } - if (number >= ((UInt64)1 << (64 - numBits))) - return false; - result = number << numBits; - return true; -} - -static bool ParseTypeParams(const UString &s, COpenType &type) -{ - if (s[0] == 0) - return true; - if (s[1] == 0) - { - switch ((unsigned)(Byte)s[0]) - { - case 'e': type.EachPos = true; return true; - case 'a': type.CanReturnArc = true; return true; - case 'r': type.Recursive = true; return true; - } - return false; - } - if (s[0] == 's') - { - UInt64 result; - if (!ParseComplexSize(s.Ptr(1), result)) - return false; - type.MaxStartOffset = result; - type.MaxStartOffset_Defined = true; - return true; - } - - return false; -} - -bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) -{ - int pos2 = s.Find(L':'); - - { - UString name; - if (pos2 < 0) - { - name = s; - pos2 = s.Len(); - } - else - { - name = s.Left(pos2); - pos2++; - } - - int index = codecs.FindFormatForArchiveType(name); - type.Recursive = false; - - if (index < 0) - { - if (name[0] == '*') - { - if (name[1] != 0) - return false; - } - else if (name[0] == '#') - { - if (name[1] != 0) - return false; - type.CanReturnArc = false; - type.CanReturnParser = true; - } - else - return false; - } - - type.FormatIndex = index; - - } - - for (unsigned i = pos2; i < s.Len();) - { - int next = s.Find(L':', i); - if (next < 0) - next = s.Len(); - const UString name = s.Mid(i, next - i); - if (name.IsEmpty()) - return false; - if (!ParseTypeParams(name, type)) - return false; - i = next + 1; - } - - return true; -} - -bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector &types) -{ - types.Clear(); - for (unsigned pos = 0; pos < s.Len();) - { - int pos2 = s.Find(L'.', pos); - if (pos2 < 0) - pos2 = s.Len(); - UString name = s.Mid(pos, pos2 - pos); - if (name.IsEmpty()) - return false; - COpenType type; - if (!ParseType(codecs, name, type)) - return false; - types.Add(type); - pos = pos2 + 1; - } - return true; -} - -#endif +// OpenArchive.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/ProgressUtils.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "DefaultName.h" +#include "OpenArchive.h" + +#ifndef Z7_SFX +#include "SetProperties.h" +#endif + +#ifndef Z7_SFX +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif +#endif + +// increase it, if you need to support larger SFX stubs +static const UInt64 kMaxCheckStartPosition = 1 << 23; + +/* +Open: + - formatIndex >= 0 (exact Format) + 1) Open with main type. Archive handler is allowed to use archive start finder. + Warning, if there is tail. + + - formatIndex = -1 (Parser:0) (default) + - same as #1 but doesn't return Parser + + - formatIndex = -2 (#1) + - file has supported extension (like a.7z) + Open with that main type (only starting from start of file). + - open OK: + - if there is no tail - return OK + - if there is tail: + - archive is not "Self Exe" - return OK with Warning, that there is tail + - archive is "Self Exe" + ignore "Self Exe" stub, and tries to open tail + - tail can be open as archive - shows that archive and stub size property. + - tail can't be open as archive - shows Parser ??? + - open FAIL: + Try to open with all other types from offset 0 only. + If some open type is OK and physical archive size is uequal or larger + than file size, then return that archive with warning that cannot be open as [extension type]. + If extension was EXE, it will try to open as unknown_extension case + - file has unknown extension (like a.hhh) + It tries to open via parser code. + - if there is full archive or tail archive and unknown block or "Self Exe" + at front, it shows tail archive and stub size property. + - in another cases, if there is some archive inside file, it returns parser/ + - in another cases, it retuens S_FALSE + + + - formatIndex = -3 (#2) + - same as #1, but + - stub (EXE) + archive is open in Parser + + - formatIndex = -4 (#3) + - returns only Parser. skip full file archive. And show other sub-archives + + - formatIndex = -5 (#4) + - returns only Parser. skip full file archive. And show other sub-archives for each byte pos + +*/ + + + + +using namespace NWindows; + +/* +#ifdef Z7_SFX +#define OPEN_PROPS_PARAM +#else +#define OPEN_PROPS_PARAM , props +#endif +*/ + +/* +CArc::~CArc() +{ + GetRawProps.Release(); + Archive.Release(); + printf("\nCArc::~CArc()\n"); +} +*/ + +#ifndef Z7_SFX + +namespace NArchive { +namespace NParser { + +struct CParseItem +{ + UInt64 Offset; + UInt64 Size; + // UInt64 OkSize; + UString Name; + UString Extension; + FILETIME FileTime; + UString Comment; + UString ArcType; + + bool FileTime_Defined; + bool UnpackSize_Defined; + bool NumSubDirs_Defined; + bool NumSubFiles_Defined; + + bool IsSelfExe; + bool IsNotArcType; + + UInt64 UnpackSize; + UInt64 NumSubDirs; + UInt64 NumSubFiles; + + int FormatIndex; + + bool LenIsUnknown; + + CParseItem(): + // OkSize(0), + FileTime_Defined(false), + UnpackSize_Defined(false), + NumSubDirs_Defined(false), + NumSubFiles_Defined(false), + IsSelfExe(false), + IsNotArcType(false), + LenIsUnknown(false) + {} + + /* + bool IsEqualTo(const CParseItem &item) const + { + return Offset == item.Offset && Size == item.Size; + } + */ + + void NormalizeOffset() + { + if ((Int64)Offset < 0) + { + Size += Offset; + // OkSize += Offset; + Offset = 0; + } + } +}; + +Z7_CLASS_IMP_CHandler_IInArchive_1( + IInArchiveGetStream +) +public: + CObjectVector _items; + UInt64 _maxEndOffset; + CMyComPtr _stream; + + UInt64 GetLastEnd() const + { + if (_items.IsEmpty()) + return 0; + const CParseItem &back = _items.Back(); + return back.Offset + back.Size; + } + + void AddUnknownItem(UInt64 next); + int FindInsertPos(const CParseItem &item) const; + void AddItem(const CParseItem &item); + + CHandler(): _maxEndOffset(0) {} +}; + +int CHandler::FindInsertPos(const CParseItem &item) const +{ + unsigned left = 0, right = _items.Size(); + while (left != right) + { + const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const CParseItem &midItem = _items[mid]; + if (item.Offset < midItem.Offset) + right = mid; + else if (item.Offset > midItem.Offset) + left = mid + 1; + else if (item.Size < midItem.Size) + right = mid; + /* + else if (item.Size > midItem.Size) + left = mid + 1; + */ + else + { + left = mid + 1; + // return -1; + } + } + return (int)left; +} + +void CHandler::AddUnknownItem(UInt64 next) +{ + /* + UInt64 prevEnd = 0; + if (!_items.IsEmpty()) + { + const CParseItem &back = _items.Back(); + prevEnd = back.Offset + back.Size; + } + */ + if (_maxEndOffset < next) + { + CParseItem item2; + item2.Offset = _maxEndOffset; + item2.Size = next - _maxEndOffset; + _maxEndOffset = next; + _items.Add(item2); + } + else if (_maxEndOffset > next && !_items.IsEmpty()) + { + CParseItem &back = _items.Back(); + if (back.LenIsUnknown) + { + back.Size = next - back.Offset; + _maxEndOffset = next; + } + } +} + +void CHandler::AddItem(const CParseItem &item) +{ + AddUnknownItem(item.Offset); + const int pos = FindInsertPos(item); + if (pos != -1) + { + _items.Insert((unsigned)pos, item); + UInt64 next = item.Offset + item.Size; + if (_maxEndOffset < next) + _maxEndOffset = next; + } +} + +/* +static const CStatProp kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidType, VT_BSTR}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidOffset, VT_UI8}, + { NULL, kpidUnpackSize, VT_UI8}, +// { NULL, kpidNumSubDirs, VT_UI8}, +}; +*/ + +static const Byte kProps[] = +{ + kpidPath, + kpidSize, + kpidMTime, + kpidType, + kpidComment, + kpidOffset, + kpidUnpackSize +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_NO + +Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* openArchiveCallback */)) +{ + COM_TRY_BEGIN + { + Close(); + _stream = stream; + } + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CHandler::Close()) +{ + _items.Clear(); + _stream.Release(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + const CParseItem &item = _items[index]; + + switch (propID) + { + case kpidPath: + { + char sz[32]; + ConvertUInt32ToString(index + 1, sz); + UString s(sz); + if (!item.Name.IsEmpty()) + { + s.Add_Dot(); + s += item.Name; + } + if (!item.Extension.IsEmpty()) + { + s.Add_Dot(); + s += item.Extension; + } + prop = s; break; + } + case kpidSize: + case kpidPackSize: prop = item.Size; break; + case kpidOffset: prop = item.Offset; break; + case kpidUnpackSize: if (item.UnpackSize_Defined) prop = item.UnpackSize; break; + case kpidNumSubFiles: if (item.NumSubFiles_Defined) prop = item.NumSubFiles; break; + case kpidNumSubDirs: if (item.NumSubDirs_Defined) prop = item.NumSubDirs; break; + case kpidMTime: if (item.FileTime_Defined) prop = item.FileTime; break; + case kpidComment: if (!item.Comment.IsEmpty()) prop = item.Comment; break; + case kpidType: if (!item.ArcType.IsEmpty()) prop = item.ArcType; break; + default: break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(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 (_stream && numItems == 0) + return S_OK; + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + totalSize += _items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + totalSize = 0; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr progress = lps; + lps->Init(extractCallback, false); + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr inStream(streamSpec); + streamSpec->SetStream(_stream); + + CLimitedSequentialOutStream *outStreamSpec = new CLimitedSequentialOutStream; + CMyComPtr outStream(outStreamSpec); + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr copyCoder = copyCoderSpec; + + for (i = 0; i < numItems; i++) + { + lps->InSize = totalSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()) + CMyComPtr realOutStream; + const Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + const UInt32 index = allFilesMode ? i : indices[i]; + const CParseItem &item = _items[index]; + + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)) + UInt64 unpackSize = item.Size; + totalSize += unpackSize; + bool skipMode = false; + if (!testMode && !realOutStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)) + + outStreamSpec->SetStream(realOutStream); + realOutStream.Release(); + outStreamSpec->Init(skipMode ? 0 : unpackSize, true); + + Int32 opRes = NExtract::NOperationResult::kOK; + RINOK(InStream_SeekSet(_stream, item.Offset)) + streamSpec->Init(unpackSize); + RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) + + if (outStreamSpec->GetRem() != 0) + opRes = NExtract::NOperationResult::kDataError; + outStreamSpec->ReleaseStream(); + RINOK(extractCallback->SetOperationResult(opRes)) + } + + return S_OK; + + COM_TRY_END +} + + +Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) +{ + COM_TRY_BEGIN + const CParseItem &item = _items[index]; + return CreateLimitedInStream(_stream, item.Offset, item.Size, stream); + COM_TRY_END +} + +}} + +#endif + +HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw() +{ + NCOM::CPropVariant prop; + result = false; + RINOK(arc->GetProperty(index, propID, &prop)) + if (prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw() +{ + return Archive_GetItemBoolProp(arc, index, kpidIsDir, result); +} + +HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw() +{ + return Archive_GetItemBoolProp(arc, index, kpidIsAux, result); +} + +HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw() +{ + return Archive_GetItemBoolProp(arc, index, kpidIsAltStream, result); +} + +HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) throw() +{ + return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result); +} + +static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw() +{ + NCOM::CPropVariant prop; + result = false; + RINOK(arc->GetArchiveProperty(propid, &prop)) + if (prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &result, bool &defined) +{ + defined = false; + NCOM::CPropVariant prop; + RINOK(arc->GetArchiveProperty(propid, &prop)) + switch (prop.vt) + { + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = (UInt64)(Int64)prop.lVal; break; + case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break; + case VT_I8: result = (UInt64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; + default: return E_FAIL; + } + defined = true; + return S_OK; +} + +static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &result, bool &defined) +{ + defined = false; + NCOM::CPropVariant prop; + RINOK(arc->GetArchiveProperty(propid, &prop)) + switch (prop.vt) + { + case VT_UI4: result = prop.ulVal; break; + case VT_I4: result = prop.lVal; break; + case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break; + case VT_I8: result = (Int64)prop.hVal.QuadPart; break; + case VT_EMPTY: return S_OK; + default: return E_FAIL; + } + defined = true; + return S_OK; +} + +#ifndef Z7_SFX + +HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const +{ + if (!GetRawProps) + return E_FAIL; + if (index == parent) + return S_OK; + UInt32 curIndex = index; + + UString s; + + bool prevWasAltStream = false; + + for (;;) + { + #ifdef MY_CPU_LE + const void *p; + UInt32 size; + UInt32 propType; + RINOK(GetRawProps->GetRawProp(curIndex, kpidName, &p, &size, &propType)) + if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) + s = (const wchar_t *)p; + else + #endif + { + NCOM::CPropVariant prop; + RINOK(Archive->GetProperty(curIndex, kpidName, &prop)) + if (prop.vt == VT_BSTR && prop.bstrVal) + s.SetFromBstr(prop.bstrVal); + else if (prop.vt == VT_EMPTY) + s.Empty(); + else + return E_FAIL; + } + + UInt32 curParent = (UInt32)(Int32)-1; + UInt32 parentType = 0; + RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)) + + // 18.06: fixed : we don't want to split name to parts + /* + if (parentType != NParentType::kAltStream) + { + for (;;) + { + int pos = s.ReverseFind_PathSepar(); + if (pos < 0) + { + break; + } + parts.Insert(0, s.Ptr(pos + 1)); + s.DeleteFrom(pos); + } + } + */ + + parts.Insert(0, s); + + if (prevWasAltStream) + { + { + UString &s2 = parts[parts.Size() - 2]; + s2.Add_Colon(); + s2 += parts.Back(); + } + parts.DeleteBack(); + } + + if (parent == curParent) + return S_OK; + + prevWasAltStream = false; + if (parentType == NParentType::kAltStream) + prevWasAltStream = true; + + if (curParent == (UInt32)(Int32)-1) + return E_FAIL; + curIndex = curParent; + } +} + +#endif + + + +HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const +{ + #ifdef MY_CPU_LE + if (GetRawProps) + { + const void *p; + UInt32 size; + UInt32 propType; + if (!IsTree) + { + if (GetRawProps->GetRawProp(index, kpidPath, &p, &size, &propType) == S_OK && + propType == NPropDataType::kUtf16z) + { + unsigned len = size / 2 - 1; + // (len) doesn't include null terminator + + /* + #if WCHAR_MAX > 0xffff + len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len); + + wchar_t *s = result.GetBuf(len); + wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s); + if (s + len != sEnd) return E_FAIL; + *sEnd = 0; + + #else + */ + + wchar_t *s = result.GetBuf(len); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = GetUi16(p); + p = (const void *)((const Byte *)p + 2); + + #if WCHAR_PATH_SEPARATOR != L'/' + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + else if (c == L'\\') + c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme + #endif + + *s++ = c; + } + *s = 0; + + // #endif + + result.ReleaseBuf_SetLen(len); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); + if (len != 0) + return S_OK; + } + } + /* + else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK && + p && propType == NPropDataType::kUtf16z) + { + size -= 2; + UInt32 totalSize = size; + bool isOK = false; + + { + UInt32 index2 = index; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + UInt32 parentType = 0; + if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) + break; + if (parent == (UInt32)(Int32)-1) + { + if (parentType != 0) + totalSize += 2; + isOK = true; + break; + } + index2 = parent; + UInt32 size2; + const void *p2; + if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK && + p2 && propType == NPropDataType::kUtf16z) + break; + totalSize += size2; + } + } + + if (isOK) + { + wchar_t *sz = result.GetBuf_SetEnd(totalSize / 2); + UInt32 pos = totalSize - size; + memcpy((Byte *)sz + pos, p, size); + UInt32 index2 = index; + for (;;) + { + UInt32 parent = (UInt32)(Int32)-1; + UInt32 parentType = 0; + if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK) + break; + if (parent == (UInt32)(Int32)-1) + { + if (parentType != 0) + sz[pos / 2 - 1] = L':'; + break; + } + index2 = parent; + UInt32 size2; + const void *p2; + if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK) + break; + pos -= size2; + memcpy((Byte *)sz + pos, p2, size2); + sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':'; + } + #ifdef _WIN32 + // result.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + return S_OK; + } + } + */ + } + #endif + + { + NCOM::CPropVariant prop; + RINOK(Archive->GetProperty(index, kpidPath, &prop)) + if (prop.vt == VT_BSTR && prop.bstrVal) + result.SetFromBstr(prop.bstrVal); + else if (prop.vt == VT_EMPTY) + result.Empty(); + else + return E_FAIL; + } + + if (result.IsEmpty()) + return GetItem_DefaultPath(index, result); + + Convert_UnicodeEsc16_To_UnicodeEscHigh(result); + return S_OK; +} + +HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const +{ + result.Empty(); + bool isDir; + RINOK(Archive_IsItem_Dir(Archive, index, isDir)) + if (!isDir) + { + result = DefaultName; + NCOM::CPropVariant prop; + RINOK(Archive->GetProperty(index, kpidExtension, &prop)) + if (prop.vt == VT_BSTR) + { + result.Add_Dot(); + result += prop.bstrVal; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + return S_OK; +} + +HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const +{ + RINOK(GetItem_Path(index, result)) + if (Ask_Deleted) + { + bool isDeleted = false; + RINOK(Archive_IsItem_Deleted(Archive, index, isDeleted)) + if (isDeleted) + result.Insert(0, L"[DELETED]" WSTRING_PATH_SEPARATOR); + } + return S_OK; +} + +#ifdef SUPPORT_ALT_STREAMS + +int FindAltStreamColon_in_Path(const wchar_t *path) +{ + unsigned i = 0; + int colonPos = -1; + for (;; i++) + { + wchar_t c = path[i]; + if (c == 0) + return colonPos; + if (c == ':') + { + if (colonPos < 0) + colonPos = (int)i; + continue; + } + if (c == WCHAR_PATH_SEPARATOR) + colonPos = -1; + } +} + +#endif + +HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const +{ + #ifdef SUPPORT_ALT_STREAMS + item.IsAltStream = false; + item.AltStreamName.Empty(); + item.MainPath.Empty(); + #endif + + item.IsDir = false; + item.Path.Empty(); + item.ParentIndex = (UInt32)(Int32)-1; + + item.PathParts.Clear(); + + RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir)) + item.MainIsDir = item.IsDir; + + RINOK(GetItem_Path2(index, item.Path)) + + #ifndef Z7_SFX + UInt32 mainIndex = index; + #endif + + #ifdef SUPPORT_ALT_STREAMS + + item.MainPath = item.Path; + if (Ask_AltStream) + { + RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream)) + } + + bool needFindAltStream = false; + + if (item.IsAltStream) + { + needFindAltStream = true; + if (GetRawProps) + { + UInt32 parentType = 0; + UInt32 parentIndex; + RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType)) + if (parentType == NParentType::kAltStream) + { + NCOM::CPropVariant prop; + RINOK(Archive->GetProperty(index, kpidName, &prop)) + if (prop.vt == VT_BSTR && prop.bstrVal) + item.AltStreamName.SetFromBstr(prop.bstrVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + else + { + // item.IsAltStream = false; + } + /* + if (item.AltStreamName.IsEmpty()) + item.IsAltStream = false; + */ + + needFindAltStream = false; + item.ParentIndex = parentIndex; + mainIndex = parentIndex; + + if (parentIndex == (UInt32)(Int32)-1) + { + item.MainPath.Empty(); + item.MainIsDir = true; + } + else + { + RINOK(GetItem_Path2(parentIndex, item.MainPath)) + RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir)) + } + } + } + } + + if (item.WriteToAltStreamIfColon || needFindAltStream) + { + /* Good handler must support GetRawProps::GetParent for alt streams. + So the following code currently is not used */ + int colon = FindAltStreamColon_in_Path(item.Path); + if (colon >= 0) + { + item.MainPath.DeleteFrom((unsigned)colon); + item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1)); + item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1])); + item.IsAltStream = true; + } + } + + #endif + + #ifndef Z7_SFX + if (item._use_baseParentFolder_mode) + { + RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts)) + + #ifdef SUPPORT_ALT_STREAMS + if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty()) + { + int colon; + { + UString &s = item.PathParts.Back(); + colon = FindAltStreamColon_in_Path(s); + if (colon >= 0) + { + item.AltStreamName = s.Ptr((unsigned)(colon + 1)); + item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1])); + item.IsAltStream = true; + s.DeleteFrom((unsigned)colon); + } + } + if (colon == 0) + item.PathParts.DeleteBack(); + } + #endif + + } + else + #endif + SplitPathToParts( + #ifdef SUPPORT_ALT_STREAMS + item.MainPath + #else + item.Path + #endif + , item.PathParts); + + return S_OK; +} + +#ifndef Z7_SFX + +static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined) +{ + NCOM::CPropVariant prop; + defined = false; + size = 0; + RINOK(archive->GetProperty(index, kpidSize, &prop)) + switch (prop.vt) + { + case VT_UI1: size = prop.bVal; break; + case VT_UI2: size = prop.uiVal; break; + case VT_UI4: size = prop.ulVal; break; + case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; + case VT_EMPTY: return S_OK; + default: return E_FAIL; + } + defined = true; + return S_OK; +} + +#endif + +HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const +{ + NCOM::CPropVariant prop; + defined = false; + size = 0; + RINOK(Archive->GetProperty(index, kpidSize, &prop)) + switch (prop.vt) + { + case VT_UI1: size = prop.bVal; break; + case VT_UI2: size = prop.uiVal; break; + case VT_UI4: size = prop.ulVal; break; + case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break; + case VT_EMPTY: return S_OK; + default: return E_FAIL; + } + defined = true; + return S_OK; +} + +HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const +{ + at.Clear(); + NCOM::CPropVariant prop; + RINOK(Archive->GetProperty(index, kpidMTime, &prop)) + + if (prop.vt == VT_FILETIME) + { + /* + // 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; + } + + if (prop.vt != VT_EMPTY) + return E_FAIL; + if (MTime.Def) + at = MTime; + return S_OK; +} + +#ifndef Z7_SFX + +static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} + + +static void MakeCheckOrder(CCodecs *codecs, + CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2, + const Byte *data, size_t dataSize) +{ + for (unsigned i = 0; i < numTypes; i++) + { + const int index = orderIndices[i]; + if (index < 0) + continue; + const CArcInfoEx &ai = codecs->Formats[(unsigned)index]; + if (ai.SignatureOffset == 0) + { + if (ai.Signatures.IsEmpty()) + { + if (dataSize != 0) // 21.04: no Signature means Empty Signature + continue; + } + else + { + unsigned k; + const CObjectVector &sigs = ai.Signatures; + for (k = 0; k < sigs.Size(); k++) + { + const CByteBuffer &sig = sigs[k]; + if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size())) + break; + } + if (k == sigs.Size()) + continue; + } + } + orderIndices2.Add(index); + orderIndices[i] = -1; + } +} + +#ifdef UNDER_CE + static const unsigned kNumHashBytes = 1; + #define HASH_VAL(buf) ((buf)[0]) +#else + static const unsigned kNumHashBytes = 2; + // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8)) + #define HASH_VAL(buf) GetUi16(buf) +#endif + +static bool IsExeExt(const UString &ext) +{ + return ext.IsEqualTo_Ascii_NoCase("exe"); +} + +static const char * const k_PreArcFormats[] = +{ + "pe" + , "elf" + , "macho" + , "mub" + , "te" +}; + +static bool IsNameFromList(const UString &s, const char * const names[], size_t num) +{ + for (unsigned i = 0; i < num; i++) + if (StringsAreEqualNoCase_Ascii(s, names[i])) + return true; + return false; +} + + +static bool IsPreArcFormat(const CArcInfoEx &ai) +{ + if (ai.Flags_PreArc()) + return true; + return IsNameFromList(ai.Name, k_PreArcFormats, Z7_ARRAY_SIZE(k_PreArcFormats)); +} + +static const char * const k_Formats_with_simple_signuature[] = +{ + "7z" + , "xz" + , "rar" + , "bzip2" + , "gzip" + , "cab" + , "wim" + , "rpm" + , "vhd" + , "xar" +}; + +static bool IsNewStyleSignature(const CArcInfoEx &ai) +{ + // if (ai.Version >= 0x91F) + if (ai.NewInterface) + return true; + return IsNameFromList(ai.Name, k_Formats_with_simple_signuature, Z7_ARRAY_SIZE(k_Formats_with_simple_signuature)); +} + + + +class CArchiveOpenCallback_Offset Z7_final: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + #ifndef Z7_NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IArchiveOpenCallback) + Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + +public: + CMyComPtr Callback; + CMyComPtr OpenVolumeCallback; + UInt64 Files; + UInt64 Offset; + + #ifndef Z7_NO_CRYPTO + CMyComPtr GetTextPassword; + #endif +}; + +#ifndef Z7_NO_CRYPTO +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)) +{ + COM_TRY_BEGIN + if (GetTextPassword) + return GetTextPassword->CryptoGetTextPassword(password); + return E_NOTIMPL; + COM_TRY_END +} +#endif + +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)) +{ + if (!Callback) + return S_OK; + UInt64 value = Offset; + if (bytes) + value += *bytes; + return Callback->SetCompleted(&Files, &value); +} + +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)) +{ + if (OpenVolumeCallback) + return OpenVolumeCallback->GetProperty(propID, value); + NCOM::PropVariant_Clear(value); + return S_OK; + // return E_NOTIMPL; +} + +Z7_COM7F_IMF(CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)) +{ + if (OpenVolumeCallback) + return OpenVolumeCallback->GetStream(name, inStream); + return S_FALSE; +} + +#endif + + +UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp) +{ + if (isDefinedProp != NULL) + *isDefinedProp = false; + + switch (prop.vt) + { + case VT_UI8: if (isDefinedProp) *isDefinedProp = true; return (UInt32)prop.uhVal.QuadPart; + case VT_UI4: if (isDefinedProp) *isDefinedProp = true; return prop.ulVal; + case VT_EMPTY: return 0; + default: throw 151199; + } +} + +void CArcErrorInfo::ClearErrors() +{ + // ErrorFormatIndex = -1; // we don't need to clear ErrorFormatIndex here !!! + + ThereIsTail = false; + UnexpecedEnd = false; + IgnoreTail = false; + // NonZerosTail = false; + ErrorFlags_Defined = false; + ErrorFlags = 0; + WarningFlags = 0; + TailSize = 0; + + ErrorMessage.Empty(); + WarningMessage.Empty(); +} + +HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes) +{ + // OkPhySize_Defined = false; + PhySize_Defined = false; + PhySize = 0; + Offset = 0; + AvailPhySize = FileSize - startPos; + + ErrorInfo.ClearErrors(); + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidErrorFlags, &prop)) + ErrorInfo.ErrorFlags = GetOpenArcErrorFlags(prop, &ErrorInfo.ErrorFlags_Defined); + } + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidWarningFlags, &prop)) + ErrorInfo.WarningFlags = GetOpenArcErrorFlags(prop); + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidError, &prop)) + if (prop.vt != VT_EMPTY) + ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error"); + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidWarning, &prop)) + if (prop.vt != VT_EMPTY) + ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning"); + } + + if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen()) + { + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined)) + /* + RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined)); + if (!OkPhySize_Defined) + { + OkPhySize_Defined = PhySize_Defined; + OkPhySize = PhySize; + } + */ + + bool offsetDefined; + RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined)) + + Int64 globalOffset = (Int64)startPos + Offset; + AvailPhySize = (UInt64)((Int64)FileSize - globalOffset); + if (PhySize_Defined) + { + UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize); + if (endPos < FileSize) + { + AvailPhySize = PhySize; + ErrorInfo.ThereIsTail = true; + ErrorInfo.TailSize = FileSize - endPos; + } + else if (endPos > FileSize) + ErrorInfo.UnexpecedEnd = true; + } + } + + return S_OK; +} + +/* +static void PrintNumber(const char *s, int n) +{ + char temp[100]; + sprintf(temp, "%s %d", s, n); + // OutputDebugStringA(temp); + printf(temp); +} +*/ + +HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr &archive) +{ + // OutputDebugStringA("a1"); + // PrintNumber("formatIndex", formatIndex); + + RINOK(op.codecs->CreateInArchive(formatIndex, archive)) + // OutputDebugStringA("a2"); + if (!archive) + return S_OK; + + #ifdef Z7_EXTERNAL_CODECS + if (op.codecs->NeedSetLibCodecs) + { + const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; + if (ai.LibIndex >= 0 ? + !op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs : + !op.codecs->Libs.IsEmpty()) + { + CMyComPtr setCompressCodecsInfo; + archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs)) + } + } + } + #endif + + + #ifndef Z7_SFX + + const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; + + // OutputDebugStringW(ai.Name); + // OutputDebugStringA("a3"); + + if (ai.Flags_PreArc()) + { + /* we notify parsers that extract executables, that they don't need + to open archive, if there is tail after executable (for SFX cases) */ + CMyComPtr allowTail; + archive.QueryInterface(IID_IArchiveAllowTail, (void **)&allowTail); + if (allowTail) + allowTail->AllowTail(BoolToInt(true)); + } + + if (op.props) + { + /* + FOR_VECTOR (y, op.props) + { + const COptionalOpenProperties &optProps = (*op.props)[y]; + if (optProps.FormatName.IsEmpty() || optProps.FormatName.CompareNoCase(ai.Name) == 0) + { + RINOK(SetProperties(archive, optProps.Props)); + break; + } + } + */ + RINOK(SetProperties(archive, *op.props)) + } + + #endif + return S_OK; +} + +#ifndef Z7_SFX + +static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NArchive::NParser::CParseItem &pi) +{ + pi.Extension = ai.GetMainExt(); + pi.FileTime_Defined = false; + pi.ArcType = ai.Name; + + RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType)) + + // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe)); + pi.IsSelfExe = ai.Flags_PreArc(); + + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidMTime, &prop)) + if (prop.vt == VT_FILETIME) + { + pi.FileTime_Defined = true; + pi.FileTime = prop.filetime; + } + } + + if (!pi.FileTime_Defined) + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidCTime, &prop)) + if (prop.vt == VT_FILETIME) + { + pi.FileTime_Defined = true; + pi.FileTime = prop.filetime; + } + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidName, &prop)) + if (prop.vt == VT_BSTR) + { + pi.Name.SetFromBstr(prop.bstrVal); + pi.Extension.Empty(); + } + else + { + RINOK(archive->GetArchiveProperty(kpidExtension, &prop)) + if (prop.vt == VT_BSTR) + pi.Extension.SetFromBstr(prop.bstrVal); + } + } + + { + NCOM::CPropVariant prop; + RINOK(archive->GetArchiveProperty(kpidShortComment, &prop)) + if (prop.vt == VT_BSTR) + pi.Comment.SetFromBstr(prop.bstrVal); + } + + + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)) + + // pi.NumSubFiles = numItems; + // RINOK(Archive_GetArcProp_UInt(archive, kpidUnpackSize, pi.UnpackSize, pi.UnpackSize_Defined)); + // if (!pi.UnpackSize_Defined) + { + pi.NumSubFiles = 0; + pi.NumSubDirs = 0; + pi.UnpackSize = 0; + for (UInt32 i = 0; i < numItems; i++) + { + UInt64 size = 0; + bool defined = false; + Archive_GetItem_Size(archive, i, size, defined); + if (defined) + { + pi.UnpackSize_Defined = true; + pi.UnpackSize += size; + } + + bool isDir = false; + Archive_IsItem_Dir(archive, i, isDir); + if (isDir) + pi.NumSubDirs++; + else + pi.NumSubFiles++; + } + if (pi.NumSubDirs != 0) + pi.NumSubDirs_Defined = true; + pi.NumSubFiles_Defined = true; + } + + return S_OK; +} + +#endif + +HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset) +{ + if (!op.stream) + return S_OK; + RINOK(InStream_SeekSet(op.stream, offset)) + const UInt32 kBufSize = 1 << 11; + Byte buf[kBufSize]; + + for (;;) + { + UInt32 processed = 0; + RINOK(op.stream->Read(buf, kBufSize, &processed)) + if (processed == 0) + { + // ErrorInfo.NonZerosTail = false; + ErrorInfo.IgnoreTail = true; + return S_OK; + } + for (size_t i = 0; i < processed; i++) + { + if (buf[i] != 0) + { + // ErrorInfo.IgnoreTail = false; + // ErrorInfo.NonZerosTail = true; + return S_OK; + } + } + } +} + + + +#ifndef Z7_SFX + +Z7_CLASS_IMP_COM_2( + CExtractCallback_To_OpenCallback + , IArchiveExtractCallback + , ICompressProgressInfo +) + Z7_IFACE_COM7_IMP(IProgress) +public: + CMyComPtr Callback; + UInt64 Files; + UInt64 Offset; + + void Init(IArchiveOpenCallback *callback) + { + Callback = callback; + Files = 0; + Offset = 0; + } +}; + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetTotal(UInt64 /* size */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetCompleted(const UInt64 * /* completeValue */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)) +{ + if (Callback) + { + UInt64 value = Offset; + if (inSize) + value += *inSize; + return Callback->SetCompleted(&Files, &value); + } + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)) +{ + *outStream = NULL; + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::PrepareOperation(Int32 /* askExtractMode */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* operationResult */)) +{ + return S_OK; +} + + +static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize, + IInStream *stream, const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openCallback, + IArchiveExtractCallback *extractCallback) +{ + /* + if (needPhySize) + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpen2, + open2, archive) + if (open2) + return open2->ArcOpen2(stream, kOpenFlags_RealPhySize, openCallback); + } + */ + RINOK(archive->Open(stream, maxCheckStartPosition, openCallback)) + if (needPhySize) + { + bool phySize_Defined = false; + UInt64 phySize = 0; + RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, phySize, phySize_Defined)) + if (phySize_Defined) + return S_OK; + + bool phySizeCantBeDetected = false; + RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected)) + + if (!phySizeCantBeDetected) + { + PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()")); + // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize. + // But the Handler will know phySize after full archive testing. + RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback)) + PRF(printf("\n-- OK")); + } + } + return S_OK; +} + + + +static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name) +{ + FOR_VECTOR (i, orderIndices) + { + int oi = orderIndices[i]; + if (oi >= 0) + if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name)) + return (int)i; + } + return -1; +} + +#endif + +HRESULT CArc::OpenStream2(const COpenOptions &op) +{ + // fprintf(stdout, "\nOpen: %S", Path); fflush(stdout); + + Archive.Release(); + GetRawProps.Release(); + GetRootProps.Release(); + + ErrorInfo.ClearErrors(); + ErrorInfo.ErrorFormatIndex = -1; + + IsParseArc = false; + ArcStreamOffset = 0; + + // OutputDebugStringA("1"); + // OutputDebugStringW(Path); + + const UString fileName = ExtractFileNameFromPath(Path); + UString extension; + { + const int dotPos = fileName.ReverseFind_Dot(); + if (dotPos >= 0) + extension = fileName.Ptr((unsigned)(dotPos + 1)); + } + + CIntVector orderIndices; + + bool searchMarkerInHandler = false; + #ifdef Z7_SFX + searchMarkerInHandler = true; + #endif + + CBoolArr isMainFormatArr(op.codecs->Formats.Size()); + { + FOR_VECTOR(i, op.codecs->Formats) + isMainFormatArr[i] = false; + } + + const UInt64 maxStartOffset = + op.openType.MaxStartOffset_Defined ? + op.openType.MaxStartOffset : + kMaxCheckStartPosition; + + #ifndef Z7_SFX + bool isUnknownExt = false; + #endif + + #ifndef Z7_SFX + bool isForced = false; + #endif + + unsigned numMainTypes = 0; + const int formatIndex = op.openType.FormatIndex; + + if (formatIndex >= 0) + { + #ifndef Z7_SFX + isForced = true; + #endif + orderIndices.Add(formatIndex); + numMainTypes = 1; + isMainFormatArr[(unsigned)formatIndex] = true; + + searchMarkerInHandler = true; + } + else + { + unsigned numFinded = 0; + #ifndef Z7_SFX + bool isPrearcExt = false; + #endif + + { + #ifndef Z7_SFX + + bool isZip = false; + bool isRar = false; + + const wchar_t c = extension[0]; + if (c == 'z' || c == 'Z' || c == 'r' || c == 'R') + { + bool isNumber = false; + for (unsigned k = 1;; k++) + { + const wchar_t d = extension[k]; + if (d == 0) + break; + if (d < '0' || d > '9') + { + isNumber = false; + break; + } + isNumber = true; + } + if (isNumber) + { + if (c == 'z' || c == 'Z') + isZip = true; + else + isRar = true; + } + } + + #endif + + FOR_VECTOR (i, op.codecs->Formats) + { + const CArcInfoEx &ai = op.codecs->Formats[i]; + + if (IgnoreSplit || !op.openType.CanReturnArc) + if (ai.Is_Split()) + continue; + if (op.excludedFormats->FindInSorted((int)i) >= 0) + continue; + + #ifndef Z7_SFX + if (IsPreArcFormat(ai)) + isPrearcExt = true; + #endif + + if (ai.FindExtension(extension) >= 0 + #ifndef Z7_SFX + || (isZip && ai.Is_Zip()) + || (isRar && ai.Is_Rar()) + #endif + ) + { + // PrintNumber("orderIndices.Insert", i); + orderIndices.Insert(numFinded++, (int)i); + isMainFormatArr[i] = true; + } + else + orderIndices.Add((int)i); + } + } + + if (!op.stream) + { + if (numFinded != 1) + return E_NOTIMPL; + orderIndices.DeleteFrom(1); + } + // PrintNumber("numFinded", numFinded ); + + /* + if (op.openOnlySpecifiedByExtension) + { + if (numFinded != 0 && !IsExeExt(extension)) + orderIndices.DeleteFrom(numFinded); + } + */ + + #ifndef Z7_SFX + + if (op.stream && orderIndices.Size() >= 2) + { + RINOK(InStream_SeekToBegin(op.stream)) + CByteBuffer byteBuffer; + CIntVector orderIndices2; + if (numFinded == 0 || IsExeExt(extension)) + { + // signature search was here + } + else if (extension.IsEqualTo("000") || extension.IsEqualTo("001")) + { + const int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar"); + if (i >= 0) + { + const size_t kBufSize = (1 << 10); + byteBuffer.Alloc(kBufSize); + size_t processedSize = kBufSize; + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) + if (processedSize >= 16) + { + const Byte *buf = byteBuffer; + const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 }; + if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0) + { + orderIndices2.Add(orderIndices[(unsigned)i]); + orderIndices[(unsigned)i] = -1; + if (i >= (int)numFinded) + numFinded++; + } + } + } + } + else + { + const size_t kBufSize = (1 << 10); + byteBuffer.Alloc(kBufSize); + size_t processedSize = kBufSize; + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) + if (processedSize == 0) + return S_FALSE; + + /* + check type order: + 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); + // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, NULL, 0); + // MakeCheckOrder(op.codecs, orderIndices, orderIndices.Size(), orderIndices2, byteBuffer, processedSize); + } + + FOR_VECTOR (i, orderIndices) + { + const int val = orderIndices[i]; + if (val != -1) + orderIndices2.Add(val); + } + orderIndices = orderIndices2; + } + + if (orderIndices.Size() >= 2) + { + const int iIso = FindFormatForArchiveType(op.codecs, orderIndices, "iso"); + const int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf"); + if (iUdf > iIso && iIso >= 0) + { + const int isoIndex = orderIndices[(unsigned)iIso]; + const int udfIndex = orderIndices[(unsigned)iUdf]; + orderIndices[(unsigned)iUdf] = isoIndex; + orderIndices[(unsigned)iIso] = udfIndex; + } + } + + numMainTypes = numFinded; + isUnknownExt = (numMainTypes == 0) || isPrearcExt; + + #else // Z7_SFX + + numMainTypes = orderIndices.Size(); + + // we need correct numMainTypes for mutlivolume SFX (if some volume is missing) + if (numFinded != 0) + numMainTypes = numFinded; + + #endif + } + + UInt64 fileSize = 0; + if (op.stream) + { + RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) + } + FileSize = fileSize; + + + #ifndef Z7_SFX + + CBoolArr skipFrontalFormat(op.codecs->Formats.Size()); + { + FOR_VECTOR(i, op.codecs->Formats) + skipFrontalFormat[i] = false; + } + + #endif + + const COpenType &mode = op.openType; + + + + + + if (mode.CanReturnArc) + { + // ---------- OPEN main type by extenssion ---------- + + unsigned numCheckTypes = orderIndices.Size(); + if (formatIndex >= 0) + numCheckTypes = numMainTypes; + + for (unsigned i = 0; i < numCheckTypes; i++) + { + FormatIndex = orderIndices[i]; + + // orderIndices[] item cannot be negative here + + bool exactOnly = false; + + #ifndef Z7_SFX + + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; + // OutputDebugStringW(ai.Name); + if (i >= numMainTypes) + { + // here we allow mismatched extension only for backward handlers + if (!ai.Flags_BackwardOpen() + // && !ai.Flags_PureStartOpen() + ) + continue; + exactOnly = true; + } + + #endif + + // Some handlers do not set total bytes. So we set it here + if (op.callback) + RINOK(op.callback->SetTotal(NULL, &fileSize)) + + if (op.stream) + { + RINOK(InStream_SeekToBegin(op.stream)) + } + + CMyComPtr archive; + + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) + if (!archive) + continue; + + HRESULT result; + if (op.stream) + { + UInt64 searchLimit = (!exactOnly && searchMarkerInHandler) ? maxStartOffset: 0; + result = archive->Open(op.stream, &searchLimit, op.callback); + } + else + { + CMyComPtr openSeq; + archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq); + if (!openSeq) + return E_NOTIMPL; + result = openSeq->OpenSeq(op.seqStream); + } + + RINOK(ReadBasicProps(archive, 0, result)) + + if (result == S_FALSE) + { + bool isArc = ErrorInfo.IsArc_After_NonOpen(); + + #ifndef Z7_SFX + // if it's archive, we allow another open attempt for parser + if (!mode.CanReturnParser || !isArc) + skipFrontalFormat[(unsigned)FormatIndex] = true; + #endif + + if (exactOnly) + continue; + + if (i == 0 && numMainTypes == 1) + { + // we set NonOpenErrorInfo, only if there is only one main format (defined by extension). + ErrorInfo.ErrorFormatIndex = FormatIndex; + NonOpen_ErrorInfo = ErrorInfo; + + if (!mode.CanReturnParser && isArc) + { + // if (formatIndex < 0 && !searchMarkerInHandler) + { + // if bad archive was detected, we don't need additional open attempts + #ifndef Z7_SFX + if (!IsPreArcFormat(ai) /* || !mode.SkipSfxStub */) + #endif + return S_FALSE; + } + } + } + + /* + #ifndef Z7_SFX + if (IsExeExt(extension) || ai.Flags_PreArc()) + { + // openOnlyFullArc = false; + // canReturnTailArc = true; + // limitSignatureSearch = true; + } + #endif + */ + + continue; + } + + RINOK(result) + + #ifndef Z7_SFX + + bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; + const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); + + bool thereIsTail = ErrorInfo.ThereIsTail; + if (thereIsTail && mode.ZerosTailIsAllowed) + { + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) + if (ErrorInfo.IgnoreTail) + thereIsTail = false; + } + + if (Offset > 0) + { + if (exactOnly + || !searchMarkerInHandler + || !specFlags.CanReturn_NonStart() + || (mode.MaxStartOffset_Defined && (UInt64)Offset > mode.MaxStartOffset)) + continue; + } + if (thereIsTail) + { + if (Offset > 0) + { + if (!specFlags.CanReturnMid) + continue; + } + else if (!specFlags.CanReturnFrontal) + continue; + } + + if (Offset > 0 || thereIsTail) + { + if (formatIndex < 0) + { + if (IsPreArcFormat(ai)) + { + // openOnlyFullArc = false; + // canReturnTailArc = true; + /* + if (mode.SkipSfxStub) + limitSignatureSearch = true; + */ + // if (mode.SkipSfxStub) + { + // skipFrontalFormat[FormatIndex] = true; + continue; + } + } + } + } + + #endif + + Archive = archive; + return S_OK; + } + } + + + + #ifndef Z7_SFX + + if (!op.stream) + return S_FALSE; + + if (formatIndex >= 0 && !mode.CanReturnParser) + { + if (mode.MaxStartOffset_Defined) + { + if (mode.MaxStartOffset == 0) + return S_FALSE; + } + else + { + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex]; + if (ai.FindExtension(extension) >= 0) + { + if (ai.Flags_FindSignature() && searchMarkerInHandler) + return S_FALSE; + } + } + } + + NArchive::NParser::CHandler *handlerSpec = new NArchive::NParser::CHandler; + CMyComPtr handler = handlerSpec; + + CExtractCallback_To_OpenCallback *extractCallback_To_OpenCallback_Spec = new CExtractCallback_To_OpenCallback; + CMyComPtr extractCallback_To_OpenCallback = extractCallback_To_OpenCallback_Spec; + extractCallback_To_OpenCallback_Spec->Init(op.callback); + + { + // ---------- Check all possible START archives ---------- + // this code is better for full file archives than Parser's code. + + CByteBuffer byteBuffer; + bool endOfFile = false; + size_t processedSize; + { + size_t bufSize = 1 << 20; // it must be larger than max signature offset or IsArcFunc offset ((1 << 19) + x for UDF) + if (bufSize > fileSize) + { + bufSize = (size_t)fileSize; + endOfFile = true; + } + byteBuffer.Alloc(bufSize); + RINOK(InStream_SeekToBegin(op.stream)) + processedSize = bufSize; + RINOK(ReadStream(op.stream, byteBuffer, &processedSize)) + if (processedSize == 0) + return S_FALSE; + if (processedSize < bufSize) + endOfFile = true; + } + CUIntVector sortedFormats; + + unsigned i; + + int splitIndex = -1; + + for (i = 0; i < orderIndices.Size(); i++) + { + // orderIndices[] item cannot be negative here + unsigned form = (unsigned)orderIndices[i]; + if (skipFrontalFormat[form]) + continue; + + const CArcInfoEx &ai = op.codecs->Formats[form]; + + if (ai.Is_Split()) + { + splitIndex = (int)form; + continue; + } + + if (ai.Flags_ByExtOnlyOpen()) + continue; + + if (ai.IsArcFunc) + { + UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize); + if (isArcRes == k_IsArc_Res_NO) + continue; + if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) + continue; + // if (isArcRes == k_IsArc_Res_YES_LOW_PROB) continue; + sortedFormats.Insert(0, form); + continue; + } + + const bool isNewStyleSignature = IsNewStyleSignature(ai); + bool needCheck = !isNewStyleSignature + || ai.Signatures.IsEmpty() + || ai.Flags_PureStartOpen() + || ai.Flags_StartOpen() + || ai.Flags_BackwardOpen(); + + if (isNewStyleSignature && !ai.Signatures.IsEmpty()) + { + unsigned k; + for (k = 0; k < ai.Signatures.Size(); k++) + { + const CByteBuffer &sig = ai.Signatures[k]; + if (processedSize < ai.SignatureOffset + sig.Size()) + { + if (!endOfFile) + needCheck = true; + } + else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size())) + break; + } + if (k != ai.Signatures.Size()) + { + sortedFormats.Insert(0, form); + continue; + } + } + if (needCheck) + sortedFormats.Add(form); + } + + if (splitIndex >= 0) + sortedFormats.Insert(0, (unsigned)splitIndex); + + for (i = 0; i < sortedFormats.Size(); i++) + { + FormatIndex = (int)sortedFormats[i]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; + + if (op.callback) + RINOK(op.callback->SetTotal(NULL, &fileSize)) + + RINOK(InStream_SeekToBegin(op.stream)) + + CMyComPtr archive; + RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive)) + if (!archive) + continue; + + PRF(printf("\nSorted Open %S", (const wchar_t *)ai.Name)); + HRESULT result; + { + UInt64 searchLimit = 0; + /* + if (mode.CanReturnArc) + result = archive->Open(op.stream, &searchLimit, op.callback); + else + */ + // if (!CanReturnArc), it's ParserMode, and we need phy size + result = OpenArchiveSpec(archive, + !mode.CanReturnArc, // needPhySize + op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback); + } + + if (result == S_FALSE) + { + skipFrontalFormat[(unsigned)FormatIndex] = true; + // FIXME: maybe we must use LenIsUnknown. + // printf(" OpenForSize Error"); + continue; + } + RINOK(result) + + RINOK(ReadBasicProps(archive, 0, result)) + + if (Offset > 0) + { + continue; // good handler doesn't return such Offset > 0 + // but there are some cases like false prefixed PK00 archive, when + // we can support it? + } + + NArchive::NParser::CParseItem pi; + pi.Offset = (UInt64)Offset; + pi.Size = AvailPhySize; + + // bool needScan = false; + + if (!PhySize_Defined) + { + // it's for Z format + pi.LenIsUnknown = true; + // needScan = true; + // phySize = arcRem; + // nextNeedCheckStartOpen = false; + } + + /* + if (OkPhySize_Defined) + pi.OkSize = pi.OkPhySize; + else + pi.OkSize = pi.Size; + */ + + pi.NormalizeOffset(); + // printf(" phySize = %8d", (unsigned)phySize); + + + if (mode.CanReturnArc) + { + const bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex]; + const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); + bool openCur = false; + + if (!ErrorInfo.ThereIsTail) + openCur = true; + else + { + if (mode.ZerosTailIsAllowed) + { + RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize))) + if (ErrorInfo.IgnoreTail) + openCur = true; + } + if (!openCur) + { + openCur = specFlags.CanReturnFrontal; + if (formatIndex < 0) // format is not forced + { + if (IsPreArcFormat(ai)) + { + // if (mode.SkipSfxStub) + { + openCur = false; + } + } + } + } + } + + if (openCur) + { + InStream = op.stream; + Archive = archive; + return S_OK; + } + } + + skipFrontalFormat[(unsigned)FormatIndex] = true; + + + // if (!mode.CanReturnArc) + /* + if (!ErrorInfo.ThereIsTail) + continue; + */ + if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) + continue; + + // printf("\nAdd offset = %d", (int)pi.Offset); + RINOK(ReadParseItemProps(archive, ai, pi)) + handlerSpec->AddItem(pi); + } + } + + + + + + // ---------- PARSER ---------- + + CUIntVector arc2sig; // formatIndex to signatureIndex + CUIntVector sig2arc; // signatureIndex to formatIndex; + { + unsigned sum = 0; + FOR_VECTOR (i, op.codecs->Formats) + { + arc2sig.Add(sum); + const CObjectVector &sigs = op.codecs->Formats[i].Signatures; + sum += sigs.Size(); + FOR_VECTOR (k, sigs) + sig2arc.Add(i); + } + } + + { + const size_t kBeforeSize = 1 << 16; + const size_t kAfterSize = 1 << 20; + const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize + + const UInt32 kNumVals = (UInt32)1 << (kNumHashBytes * 8); + CByteArr hashBuffer(kNumVals); + Byte *hash = hashBuffer; + memset(hash, 0xFF, kNumVals); + Byte prevs[256]; + memset(prevs, 0xFF, sizeof(prevs)); + if (sig2arc.Size() >= 0xFF) + return S_FALSE; + + CUIntVector difficultFormats; + CBoolArr difficultBools(256); + { + for (unsigned i = 0; i < 256; i++) + difficultBools[i] = false; + } + + bool thereAreHandlersForSearch = false; + + // UInt32 maxSignatureEnd = 0; + + FOR_VECTOR (i, orderIndices) + { + int index = orderIndices[i]; + if (index < 0) + continue; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index]; + if (ai.Flags_ByExtOnlyOpen()) + continue; + bool isDifficult = false; + // if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31) + if (!ai.NewInterface) + isDifficult = true; + else + { + if (ai.Flags_StartOpen()) + isDifficult = true; + FOR_VECTOR (k, ai.Signatures) + { + const CByteBuffer &sig = ai.Signatures[k]; + /* + UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size(); + if (maxSignatureEnd < signatureEnd) + maxSignatureEnd = signatureEnd; + */ + if (sig.Size() < kNumHashBytes) + { + isDifficult = true; + continue; + } + thereAreHandlersForSearch = true; + UInt32 v = HASH_VAL(sig); + unsigned sigIndex = arc2sig[(unsigned)index] + k; + prevs[sigIndex] = hash[v]; + hash[v] = (Byte)sigIndex; + } + } + if (isDifficult) + { + difficultFormats.Add((unsigned)index); + difficultBools[(unsigned)index] = true; + } + } + + if (!thereAreHandlersForSearch) + { + // openOnlyFullArc = true; + // canReturnTailArc = true; + } + + RINOK(InStream_SeekToBegin(op.stream)) + + CLimitedCachedInStream *limitedStreamSpec = new CLimitedCachedInStream; + CMyComPtr limitedStream = limitedStreamSpec; + limitedStreamSpec->SetStream(op.stream); + + CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL; + CMyComPtr openCallback_Offset; + if (op.callback) + { + openCallback_Offset_Spec = new CArchiveOpenCallback_Offset; + openCallback_Offset = openCallback_Offset_Spec; + openCallback_Offset_Spec->Callback = op.callback; + openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback); + #ifndef Z7_NO_CRYPTO + openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword); + #endif + } + + if (op.callback) + RINOK(op.callback->SetTotal(NULL, &fileSize)) + + CByteBuffer &byteBuffer = limitedStreamSpec->Buffer; + byteBuffer.Alloc(kBufSize); + + UInt64 callbackPrev = 0; + bool needCheckStartOpen = true; // = true, if we need to test all archives types for current pos. + + bool endOfFile = false; + UInt64 bufPhyPos = 0; + size_t bytesInBuf = 0; + // UInt64 prevPos = 0; + + // ---------- Main Scan Loop ---------- + + UInt64 pos = 0; + + if (!mode.EachPos && handlerSpec->_items.Size() == 1) + { + NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; + if (!pi.LenIsUnknown && pi.Offset == 0) + pos = pi.Size; + } + + for (;;) + { + // printf("\nPos = %d", (int)pos); + UInt64 posInBuf = pos - bufPhyPos; + + // if (pos > ((UInt64)1 << 35)) break; + + if (!endOfFile) + { + if (bytesInBuf < kBufSize) + { + size_t processedSize = kBufSize - bytesInBuf; + // printf("\nRead ask = %d", (unsigned)processedSize); + UInt64 seekPos = bufPhyPos + bytesInBuf; + RINOK(InStream_SeekSet(op.stream, bufPhyPos + bytesInBuf)) + RINOK(ReadStream(op.stream, byteBuffer.NonConstData() + bytesInBuf, &processedSize)) + // printf(" processed = %d", (unsigned)processedSize); + if (processedSize == 0) + { + fileSize = seekPos; + endOfFile = true; + } + else + { + bytesInBuf += processedSize; + limitedStreamSpec->SetCache(processedSize, (size_t)bufPhyPos); + } + continue; + } + + if (bytesInBuf < posInBuf) + { + UInt64 skipSize = posInBuf - bytesInBuf; + if (skipSize <= kBeforeSize) + { + size_t keepSize = (size_t)(kBeforeSize - skipSize); + // printf("\nmemmove skip = %d", (int)keepSize); + memmove(byteBuffer, byteBuffer.ConstData() + bytesInBuf - keepSize, keepSize); + bytesInBuf = keepSize; + bufPhyPos = pos - keepSize; + continue; + } + // printf("\nSkip %d", (int)(skipSize - kBeforeSize)); + // RINOK(op.stream->Seek(skipSize - kBeforeSize, STREAM_SEEK_CUR, NULL)); + bytesInBuf = 0; + bufPhyPos = pos - kBeforeSize; + continue; + } + + if (bytesInBuf - posInBuf < kAfterSize) + { + size_t beg = (size_t)posInBuf - kBeforeSize; + // printf("\nmemmove for after beg = %d", (int)beg); + memmove(byteBuffer, byteBuffer.ConstData() + beg, bytesInBuf - beg); + bufPhyPos += beg; + bytesInBuf -= beg; + continue; + } + } + + if (bytesInBuf <= (size_t)posInBuf) + break; + + bool useOffsetCallback = false; + if (openCallback_Offset) + { + openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); + openCallback_Offset_Spec->Offset = pos; + + useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1); + + if (pos >= callbackPrev + (1 << 23)) + { + RINOK(openCallback_Offset->SetCompleted(NULL, NULL)) + callbackPrev = pos; + } + } + + { + UInt64 endPos = bufPhyPos + bytesInBuf; + if (fileSize < endPos) + { + FileSize = fileSize; // why ???? + fileSize = endPos; + } + } + + const size_t availSize = bytesInBuf - (size_t)posInBuf; + if (availSize < kNumHashBytes) + break; + size_t scanSize = availSize - + ((availSize >= kAfterSize) ? kAfterSize : kNumHashBytes); + + { + /* + UInt64 scanLimit = openOnlyFullArc ? + maxSignatureEnd : + op.openType.ScanSize + maxSignatureEnd; + */ + if (!mode.CanReturnParser) + { + if (pos > maxStartOffset) + break; + UInt64 remScan = maxStartOffset - pos; + if (scanSize > remScan) + scanSize = (size_t)remScan; + } + } + + scanSize++; + + const Byte *buf = byteBuffer.ConstData() + (size_t)posInBuf; + const Byte *bufLimit = buf + scanSize; + size_t ppp = 0; + + if (!needCheckStartOpen) + { + for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++); + ppp = (size_t)(buf - (byteBuffer.ConstData() + (size_t)posInBuf)); + pos += ppp; + if (buf == bufLimit) + continue; + } + + UInt32 v = HASH_VAL(buf); + bool nextNeedCheckStartOpen = true; + unsigned i = hash[v]; + unsigned indexOfDifficult = 0; + + // ---------- Open Loop for Current Pos ---------- + bool wasOpen = false; + + for (;;) + { + unsigned index; + bool isDifficult; + if (needCheckStartOpen && indexOfDifficult < difficultFormats.Size()) + { + index = difficultFormats[indexOfDifficult++]; + isDifficult = true; + } + else + { + if (i == 0xFF) + break; + index = sig2arc[i]; + unsigned sigIndex = i - arc2sig[index]; + i = prevs[i]; + if (needCheckStartOpen && difficultBools[index]) + continue; + const CArcInfoEx &ai = op.codecs->Formats[index]; + + if (pos < ai.SignatureOffset) + continue; + + /* + if (openOnlyFullArc) + if (pos != ai.SignatureOffset) + continue; + */ + + const CByteBuffer &sig = ai.Signatures[sigIndex]; + + if (ppp + sig.Size() > availSize + || !TestSignature(buf, sig, sig.Size())) + continue; + // printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos)); + // prevPos = pos; + isDifficult = false; + } + + const CArcInfoEx &ai = op.codecs->Formats[index]; + + + if ((isDifficult && pos == 0) || ai.SignatureOffset == pos) + { + // we don't check same archive second time */ + if (skipFrontalFormat[index]) + continue; + } + + UInt64 startArcPos = pos; + if (!isDifficult) + { + if (pos < ai.SignatureOffset) + continue; + startArcPos = pos - ai.SignatureOffset; + /* + // we don't need the check for Z files + if (startArcPos < handlerSpec->GetLastEnd()) + continue; + */ + } + + if (ai.IsArcFunc && startArcPos >= bufPhyPos) + { + const size_t offsetInBuf = (size_t)(startArcPos - bufPhyPos); + if (offsetInBuf < bytesInBuf) + { + const UInt32 isArcRes = ai.IsArcFunc(byteBuffer.ConstData() + offsetInBuf, bytesInBuf - offsetInBuf); + if (isArcRes == k_IsArc_Res_NO) + continue; + if (isArcRes == k_IsArc_Res_NEED_MORE && endOfFile) + continue; + /* + if (isArcRes == k_IsArc_Res_YES_LOW_PROB) + { + // if (pos != ai.SignatureOffset) + continue; + } + */ + } + // printf("\nIsArc OK: %S", (const wchar_t *)ai.Name); + } + + PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name)); + + const bool isMainFormat = isMainFormatArr[index]; + const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt); + + CMyComPtr archive; + RINOK(PrepareToOpen(op, index, archive)) + if (!archive) + return E_FAIL; + + // OutputDebugStringW(ai.Name); + + const UInt64 rem = fileSize - startArcPos; + + UInt64 arcStreamOffset = 0; + + if (ai.Flags_UseGlobalOffset()) + { + RINOK(limitedStreamSpec->InitAndSeek(0, fileSize)) + RINOK(InStream_SeekSet(limitedStream, startArcPos)) + } + else + { + RINOK(limitedStreamSpec->InitAndSeek(startArcPos, rem)) + arcStreamOffset = startArcPos; + } + + UInt64 maxCheckStartPosition = 0; + + if (openCallback_Offset) + { + openCallback_Offset_Spec->Files = handlerSpec->_items.Size(); + openCallback_Offset_Spec->Offset = startArcPos; + } + + // HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset); + extractCallback_To_OpenCallback_Spec->Files = 0; + extractCallback_To_OpenCallback_Spec->Offset = startArcPos; + + HRESULT result = OpenArchiveSpec(archive, + true, // needPhySize + limitedStream, &maxCheckStartPosition, + useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback, + extractCallback_To_OpenCallback); + + RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result)) + + bool isOpen = false; + + if (result == S_FALSE) + { + if (!mode.CanReturnParser) + { + if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen()) + { + ErrorInfo.ErrorFormatIndex = (int)index; + NonOpen_ErrorInfo = ErrorInfo; + // if archive was detected, we don't need additional open attempts + return S_FALSE; + } + continue; + } + if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0) + continue; + } + else + { + if (PhySize_Defined && PhySize == 0) + { + PRF(printf(" phySize_Defined && PhySize == 0 ")); + // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function. + continue; + } + isOpen = true; + RINOK(result) + PRF(printf(" OK ")); + } + + // fprintf(stderr, "\n %8X %S", startArcPos, Path); + // printf("\nOpen OK: %S", ai.Name); + + + NArchive::NParser::CParseItem pi; + pi.Offset = startArcPos; + + if (ai.Flags_UseGlobalOffset()) + pi.Offset = (UInt64)Offset; + else if (Offset != 0) + return E_FAIL; + + const UInt64 arcRem = FileSize - pi.Offset; + UInt64 phySize = arcRem; + const bool phySize_Defined = PhySize_Defined; + if (phySize_Defined) + { + if (pi.Offset + PhySize > FileSize) + { + // ErrorInfo.ThereIsTail = true; + PhySize = FileSize - pi.Offset; + } + phySize = PhySize; + } + if (phySize == 0 || (UInt64)phySize > ((UInt64)1 << 63)) + return E_FAIL; + + /* + if (!ai.UseGlobalOffset) + { + if (phySize > arcRem) + { + ThereIsTail = true; + phySize = arcRem; + } + } + */ + + bool needScan = false; + + + if (isOpen && !phySize_Defined) + { + // it's for Z format, or bzip2,gz,xz with phySize that was not detected + pi.LenIsUnknown = true; + needScan = true; + phySize = arcRem; + nextNeedCheckStartOpen = false; + } + + pi.Size = phySize; + /* + if (OkPhySize_Defined) + pi.OkSize = OkPhySize; + */ + pi.NormalizeOffset(); + // printf(" phySize = %8d", (unsigned)phySize); + + /* + if (needSkipFullArc) + if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize) + continue; + */ + if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize) + { + // it's possible for dmg archives + if (!mode.CanReturnArc) + continue; + } + + if (mode.EachPos) + pos++; + else if (needScan) + { + pos++; + /* + if (!OkPhySize_Defined) + pos++; + else + pos = pi.Offset + pi.OkSize; + */ + } + else + pos = pi.Offset + pi.Size; + + + RINOK(ReadParseItemProps(archive, ai, pi)) + + 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 */ + + while (!handlerSpec->_items.IsEmpty()) + { + { + const NArchive::NParser::CParseItem &back = handlerSpec->_items.Back(); + if (back.Offset < pi.Offset) + break; + if (back.Offset + back.Size > pi.Offset + pi.Size) + break; + } + handlerSpec->_items.DeleteBack(); + } + } + + + if (isOpen && mode.CanReturnArc && phySize_Defined) + { + // if (pi.Offset + pi.Size >= fileSize) + bool openCur = false; + + bool thereIsTail = ErrorInfo.ThereIsTail; + if (thereIsTail && mode.ZerosTailIsAllowed) + { + RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize))) + if (ErrorInfo.IgnoreTail) + thereIsTail = false; + } + + if (pi.Offset != 0) + { + if (!pi.IsNotArcType) + { + if (thereIsTail) + openCur = specFlags.CanReturnMid; + else + openCur = specFlags.CanReturnTail; + } + } + else + { + if (!thereIsTail) + openCur = true; + else + openCur = specFlags.CanReturnFrontal; + + if (formatIndex >= -2) + openCur = true; + } + + if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */) + openCur = false; + + // We open file as SFX, if there is front archive or first archive is "Self Executable" + if (!openCur && !pi.IsSelfExe && !thereIsTail && + (!pi.IsNotArcType || pi.Offset == 0)) + { + if (handlerSpec->_items.IsEmpty()) + { + if (specFlags.CanReturnTail) + openCur = true; + } + else if (handlerSpec->_items.Size() == 1) + { + if (handlerSpec->_items[0].IsSelfExe) + { + if (mode.SpecUnknownExt.CanReturnTail) + openCur = true; + } + } + } + + if (openCur) + { + InStream = op.stream; + Archive = archive; + FormatIndex = (int)index; + ArcStreamOffset = arcStreamOffset; + return S_OK; + } + } + + /* + if (openOnlyFullArc) + { + ErrorInfo.ClearErrors(); + return S_FALSE; + } + */ + + pi.FormatIndex = (int)index; + + // printf("\nAdd offset = %d", (int)pi.Offset); + handlerSpec->AddItem(pi); + wasOpen = true; + break; + } + // ---------- End of Open Loop for Current Pos ---------- + + if (!wasOpen) + pos++; + needCheckStartOpen = (nextNeedCheckStartOpen && wasOpen); + } + // ---------- End of Main Scan Loop ---------- + + /* + if (handlerSpec->_items.Size() == 1) + { + const NArchive::NParser::CParseItem &pi = handlerSpec->_items[0]; + if (pi.Size == fileSize && pi.Offset == 0) + { + Archive = archive; + FormatIndex2 = pi.FormatIndex; + return S_OK; + } + } + */ + + if (mode.CanReturnParser) + { + bool returnParser = (handlerSpec->_items.Size() == 1); // it's possible if fileSize was not correct at start of parsing + handlerSpec->AddUnknownItem(fileSize); + if (handlerSpec->_items.Size() == 0) + return S_FALSE; + if (returnParser || handlerSpec->_items.Size() != 1) + { + // return S_FALSE; + handlerSpec->_stream = op.stream; + Archive = handler; + ErrorInfo.ClearErrors(); + IsParseArc = true; + FormatIndex = -1; // It's parser + Offset = 0; + return S_OK; + } + } + } + + #endif + + if (!Archive) + return S_FALSE; + return S_OK; +} + + + + +HRESULT CArc::OpenStream(const COpenOptions &op) +{ + RINOK(OpenStream2(op)) + // PrintNumber("op.formatIndex 3", op.formatIndex); + + if (Archive) + { + GetRawProps.Release(); + GetRootProps.Release(); + Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps); + Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps); + + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode)) + RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly)) + + const UString fileName = ExtractFileNameFromPath(Path); + UString extension; + { + int dotPos = fileName.ReverseFind_Dot(); + if (dotPos >= 0) + extension = fileName.Ptr((unsigned)(dotPos + 1)); + } + + DefaultName.Empty(); + if (FormatIndex >= 0) + { + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex]; + if (ai.Exts.Size() == 0) + DefaultName = GetDefaultName2(fileName, UString(), UString()); + else + { + int subExtIndex = ai.FindExtension(extension); + if (subExtIndex < 0) + subExtIndex = 0; + const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex]; + DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); + } + } + } + + return S_OK; +} + +#ifdef Z7_SFX + +#ifdef _WIN32 + #define k_ExeExt ".exe" + static const unsigned k_ExeExt_Len = 4; +#else + #define k_ExeExt "" + static const unsigned k_ExeExt_Len = 0; +#endif + +#endif + +HRESULT CArc::OpenStreamOrFile(COpenOptions &op) +{ + CMyComPtr fileStream; + CMyComPtr seqStream; + CInFileStream *fileStreamSpec = NULL; + + if (op.stdInMode) + { +#if 1 + seqStream = new CStdInFileStream; +#else + if (!CreateStdInStream(seqStream)) + return GetLastError_noZero_HRESULT(); +#endif + op.seqStream = seqStream; + } + else if (!op.stream) + { + fileStreamSpec = new CInFileStream; + fileStream = fileStreamSpec; + Path = filePath; + if (!fileStreamSpec->Open(us2fs(Path))) + return GetLastError_noZero_HRESULT(); + op.stream = fileStream; + #ifdef Z7_SFX + IgnoreSplit = true; + #endif + } + + /* + if (callback) + { + UInt64 fileSize; + RINOK(InStream_GetSize_SeekToEnd(op.stream, fileSize)); + RINOK(op.callback->SetTotal(NULL, &fileSize)) + } + */ + + HRESULT res = OpenStream(op); + IgnoreSplit = false; + + #ifdef Z7_SFX + + if (res != S_FALSE + || !fileStreamSpec + || !op.callbackSpec + || NonOpen_ErrorInfo.IsArc_After_NonOpen()) + return res; + + { + if (filePath.Len() > k_ExeExt_Len + && StringsAreEqualNoCase_Ascii(filePath.RightPtr(k_ExeExt_Len), k_ExeExt)) + { + const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len); + FOR_VECTOR (i, op.codecs->Formats) + { + const CArcInfoEx &ai = op.codecs->Formats[i]; + if (ai.Is_Split()) + continue; + UString path3 = path2; + path3.Add_Dot(); + path3 += ai.GetMainExt(); // "7z" for SFX. + Path = path3; + Path += ".001"; + bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); + if (!isOk) + { + Path = path3; + isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path)); + } + if (isOk) + { + if (fileStreamSpec->Open(us2fs(Path))) + { + op.stream = fileStream; + NonOpen_ErrorInfo.ClearErrors_Full(); + if (OpenStream(op) == S_OK) + return S_OK; + } + } + } + } + } + + #endif + + return res; +} + +void CArchiveLink::KeepModeForNextOpen() +{ + for (unsigned i = Arcs.Size(); i != 0;) + { + i--; + CMyComPtr keep; + Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep); + if (keep) + keep->KeepModeForNextOpen(); + } +} + +HRESULT CArchiveLink::Close() +{ + for (unsigned i = Arcs.Size(); i != 0;) + { + i--; + RINOK(Arcs[i].Close()) + } + IsOpen = false; + // ErrorsText.Empty(); + return S_OK; +} + +void CArchiveLink::Release() +{ + // NonOpenErrorFormatIndex = -1; + NonOpen_ErrorInfo.ClearErrors(); + NonOpen_ArcPath.Empty(); + while (!Arcs.IsEmpty()) + Arcs.DeleteBack(); +} + +/* +void CArchiveLink::Set_ErrorsText() +{ + FOR_VECTOR(i, Arcs) + { + const CArc &arc = Arcs[i]; + if (!arc.ErrorFlagsText.IsEmpty()) + { + if (!ErrorsText.IsEmpty()) + ErrorsText.Add_LF(); + ErrorsText += GetUnicodeString(arc.ErrorFlagsText); + } + if (!arc.ErrorMessage.IsEmpty()) + { + if (!ErrorsText.IsEmpty()) + ErrorsText.Add_LF(); + ErrorsText += arc.ErrorMessage; + } + + if (!arc.WarningMessage.IsEmpty()) + { + if (!ErrorsText.IsEmpty()) + ErrorsText.Add_LF(); + ErrorsText += arc.WarningMessage; + } + } +} +*/ + +HRESULT CArchiveLink::Open(COpenOptions &op) +{ + Release(); + if (op.types->Size() >= 32) + return E_NOTIMPL; + + HRESULT resSpec; + + for (;;) + { + resSpec = S_OK; + + op.openType = COpenType(); + if (op.types->Size() >= 1) + { + COpenType latest; + if (Arcs.Size() < op.types->Size()) + latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; + else + { + latest = (*op.types)[0]; + if (!latest.Recursive) + break; + } + op.openType = latest; + } + else if (Arcs.Size() >= 32) + break; + + /* + op.formatIndex = -1; + if (op.types->Size() >= 1) + { + int latest; + if (Arcs.Size() < op.types->Size()) + latest = (*op.types)[op.types->Size() - Arcs.Size() - 1]; + else + { + latest = (*op.types)[0]; + if (latest != -2 && latest != -3) + break; + } + if (latest >= 0) + op.formatIndex = latest; + else if (latest == -1 || latest == -2) + { + // default + } + else if (latest == -3) + op.formatIndex = -2; + else + op.formatIndex = latest + 2; + } + else if (Arcs.Size() >= 32) + break; + */ + + if (Arcs.IsEmpty()) + { + CArc arc; + arc.filePath = op.filePath; + arc.Path = op.filePath; + arc.SubfileIndex = (UInt32)(Int32)-1; + HRESULT result = arc.OpenStreamOrFile(op); + if (result != S_OK) + { + if (result == S_FALSE) + { + NonOpen_ErrorInfo = arc.NonOpen_ErrorInfo; + // NonOpenErrorFormatIndex = arc.ErrorFormatIndex; + NonOpen_ArcPath = arc.Path; + } + return result; + } + Arcs.Add(arc); + continue; + } + + // PrintNumber("op.formatIndex 11", op.formatIndex); + + const CArc &arc = Arcs.Back(); + + if (op.types->Size() > Arcs.Size()) + resSpec = E_NOTIMPL; + + UInt32 mainSubfile; + { + NCOM::CPropVariant prop; + RINOK(arc.Archive->GetArchiveProperty(kpidMainSubfile, &prop)) + if (prop.vt == VT_UI4) + mainSubfile = prop.ulVal; + else + break; + UInt32 numItems; + RINOK(arc.Archive->GetNumberOfItems(&numItems)) + if (mainSubfile >= numItems) + break; + } + + + CMyComPtr getStream; + if (arc.Archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) + break; + + CMyComPtr subSeqStream; + if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) + break; + + CMyComPtr subStream; + if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK || !subStream) + break; + + CArc arc2; + RINOK(arc.GetItem_Path(mainSubfile, arc2.Path)) + + bool zerosTailIsAllowed; + RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed)) + + + if (op.callback) + { + Z7_DECL_CMyComPtr_QI_FROM( + IArchiveOpenSetSubArchiveName, + setSubArchiveName, op.callback) + if (setSubArchiveName) + setSubArchiveName->SetSubArchiveName(arc2.Path); + } + + arc2.SubfileIndex = mainSubfile; + + // CIntVector incl; + CIntVector excl; + + COpenOptions op2; + #ifndef Z7_SFX + op2.props = op.props; + #endif + op2.codecs = op.codecs; + // op2.types = &incl; + op2.openType = op.openType; + op2.openType.ZerosTailIsAllowed = zerosTailIsAllowed; + op2.excludedFormats = ! + op2.stdInMode = false; + op2.stream = subStream; + op2.filePath = arc2.Path; + op2.callback = op.callback; + op2.callbackSpec = op.callbackSpec; + + + HRESULT result = arc2.OpenStream(op2); + resSpec = (op.types->Size() == 0 ? S_OK : S_FALSE); + if (result == S_FALSE) + { + NonOpen_ErrorInfo = arc2.ErrorInfo; + NonOpen_ArcPath = arc2.Path; + break; + } + RINOK(result) + RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime)) + Arcs.Add(arc2); + } + IsOpen = !Arcs.IsEmpty(); + return resSpec; +} + +HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI) +{ + VolumesSize = 0; + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr callback = openCallbackSpec; + openCallbackSpec->Callback = callbackUI; + + FString prefix, name; + + if (!op.stream && !op.stdInMode) + { + NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name); + RINOK(openCallbackSpec->Init2(prefix, name)) + } + else + { + openCallbackSpec->SetSubArchiveName(op.filePath); + } + + op.callback = callback; + op.callbackSpec = openCallbackSpec; + + HRESULT res = Open(op); + + PasswordWasAsked = openCallbackSpec->PasswordWasAsked; + // Password = openCallbackSpec->Password; + + RINOK(res) + // VolumePaths.Add(fs2us(prefix + name)); + + FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed) + { + if (openCallbackSpec->FileNames_WasUsed[i]) + { + VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]); + VolumesSize += openCallbackSpec->FileSizes[i]; + } + } + // VolumesSize = openCallbackSpec->TotalSize; + return S_OK; +} + +HRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional) +{ + ErrorInfo.ClearErrors(); + ErrorInfo.ErrorFormatIndex = -1; + + UInt64 fileSize = 0; + if (op.stream) + { + RINOK(InStream_SeekToBegin(op.stream)) + RINOK(InStream_AtBegin_GetSize(op.stream, fileSize)) + // RINOK(InStream_GetSize_SeekToBegin(op.stream, fileSize)) + } + FileSize = fileSize; + + CMyComPtr stream2; + Int64 globalOffset = GetGlobalOffset(); + if (globalOffset <= 0) + stream2 = op.stream; + else + { + CTailInStream *tailStreamSpec = new CTailInStream; + stream2 = tailStreamSpec; + tailStreamSpec->Stream = op.stream; + tailStreamSpec->Offset = (UInt64)globalOffset; + tailStreamSpec->Init(); + RINOK(tailStreamSpec->SeekToStart()) + } + + // There are archives with embedded STUBs (like ZIP), so we must support signature scanning + // But for another archives we can use 0 here. So the code can be fixed !!! + UInt64 maxStartPosition = kMaxCheckStartPosition; + IArchiveOpenCallback *openCallback = openCallback_Additional; + if (!openCallback) + openCallback = op.callback; + HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback); + + if (res == S_OK) + { + RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res)) + ArcStreamOffset = (UInt64)globalOffset; + if (ArcStreamOffset != 0) + InStream = op.stream; + } + return res; +} + +HRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI) +{ + HRESULT res = Open2(op, callbackUI); + if (callbackUI) + { + RINOK(callbackUI->Open_Finished()) + } + return res; +} + +HRESULT CArchiveLink::ReOpen(COpenOptions &op) +{ + if (Arcs.Size() > 1) + return E_NOTIMPL; + + CObjectVector inc; + CIntVector excl; + + op.types = &inc; + op.excludedFormats = ! + op.stdInMode = false; + op.stream = NULL; + if (Arcs.Size() == 0) // ??? + return Open2(op, NULL); + + /* if archive is multivolume (unsupported here still) + COpenCallbackImp object will exist after Open stage. */ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr openCallbackNew = openCallbackSpec; + + openCallbackSpec->Callback = NULL; + openCallbackSpec->ReOpenCallback = op.callback; + { + FString dirPrefix, fileName; + NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName); + RINOK(openCallbackSpec->Init2(dirPrefix, fileName)) + } + + + CInFileStream *fileStreamSpec = new CInFileStream; + CMyComPtr stream(fileStreamSpec); + if (!fileStreamSpec->Open(us2fs(op.filePath))) + return GetLastError_noZero_HRESULT(); + op.stream = stream; + + CArc &arc = Arcs[0]; + const HRESULT res = arc.ReOpen(op, openCallbackNew); + + openCallbackSpec->ReOpenCallback = NULL; + + PasswordWasAsked = openCallbackSpec->PasswordWasAsked; + // Password = openCallbackSpec->Password; + + IsOpen = (res == S_OK); + return res; +} + +#ifndef Z7_SFX + +bool ParseComplexSize(const wchar_t *s, UInt64 &result); +bool ParseComplexSize(const wchar_t *s, UInt64 &result) +{ + result = 0; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(s, &end); + if (end == s) + return false; + if (*end == 0) + { + result = number; + return true; + } + if (end[1] != 0) + return false; + unsigned numBits; + switch (MyCharLower_Ascii(*end)) + { + case 'b': result = number; return true; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + if (number >= ((UInt64)1 << (64 - numBits))) + return false; + result = number << numBits; + return true; +} + +static bool ParseTypeParams(const UString &s, COpenType &type) +{ + if (s[0] == 0) + return true; + if (s[1] == 0) + { + switch ((unsigned)(Byte)s[0]) + { + case 'e': type.EachPos = true; return true; + case 'a': type.CanReturnArc = true; return true; + case 'r': type.Recursive = true; return true; + default: break; + } + return false; + } + if (s[0] == 's') + { + UInt64 result; + if (!ParseComplexSize(s.Ptr(1), result)) + return false; + type.MaxStartOffset = result; + type.MaxStartOffset_Defined = true; + return true; + } + + return false; +} + +static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type) +{ + int pos2 = s.Find(L':'); + + { + UString name; + if (pos2 < 0) + { + name = s; + pos2 = (int)s.Len(); + } + else + { + name = s.Left((unsigned)pos2); + pos2++; + } + + int index = codecs.FindFormatForArchiveType(name); + type.Recursive = false; + + if (index < 0) + { + if (name[0] == '*') + { + if (name[1] != 0) + return false; + } + else if (name[0] == '#') + { + if (name[1] != 0) + return false; + type.CanReturnArc = false; + type.CanReturnParser = true; + } + else if (name.IsEqualTo_Ascii_NoCase("hash")) + { + // type.CanReturnArc = false; + // type.CanReturnParser = false; + type.IsHashType = true; + } + else + return false; + } + + type.FormatIndex = index; + + } + + for (unsigned i = (unsigned)pos2; i < s.Len();) + { + int next = s.Find(L':', i); + if (next < 0) + next = (int)s.Len(); + const UString name = s.Mid(i, (unsigned)next - i); + if (name.IsEmpty()) + return false; + if (!ParseTypeParams(name, type)) + return false; + i = (unsigned)next + 1; + } + + return true; +} + +bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector &types) +{ + types.Clear(); + bool isHashType = false; + for (unsigned pos = 0; pos < s.Len();) + { + int pos2 = s.Find(L'.', pos); + if (pos2 < 0) + pos2 = (int)s.Len(); + UString name = s.Mid(pos, (unsigned)pos2 - pos); + if (name.IsEmpty()) + return false; + COpenType type; + if (!ParseType(codecs, name, type)) + return false; + if (isHashType) + return false; + if (type.IsHashType) + isHashType = true; + types.Add(type); + pos = (unsigned)pos2 + 1; + } + return true; +} + +/* +bool IsHashType(const CObjectVector &types) +{ + if (types.Size() != 1) + return false; + return types[0].IsHashType; +} +*/ + + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/OpenArchive.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/OpenArchive.h 2015-10-03 12:29:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/OpenArchive.h 2023-04-06 04:00:00.000000000 +0000 @@ -1,409 +1,469 @@ -// OpenArchive.h - -#ifndef __OPEN_ARCHIVE_H -#define __OPEN_ARCHIVE_H - -#include "../../../Windows/PropVariant.h" - -#include "ArchiveOpenCallback.h" -#include "LoadCodecs.h" -#include "Property.h" - -#ifndef _SFX - -#define SUPPORT_ALT_STREAMS - -#endif - -HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw(); -HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw(); -HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw(); -HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw(); -HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw(); - -#ifdef SUPPORT_ALT_STREAMS -int FindAltStreamColon_in_Path(const wchar_t *path); -#endif - -/* -struct COptionalOpenProperties -{ - UString FormatName; - CObjectVector Props; -}; -*/ - -#ifdef _SFX -#define OPEN_PROPS_DECL -#else -#define OPEN_PROPS_DECL const CObjectVector *props; -// #define OPEN_PROPS_DECL , const CObjectVector *props -#endif - -struct COpenSpecFlags -{ - // bool CanReturnFull; - bool CanReturnFrontal; - bool CanReturnTail; - bool CanReturnMid; - - bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; } - - COpenSpecFlags(): - // CanReturnFull(true), - CanReturnFrontal(false), - CanReturnTail(false), - CanReturnMid(false) - {} -}; - -struct COpenType -{ - int FormatIndex; - - COpenSpecFlags SpecForcedType; - COpenSpecFlags SpecMainType; - COpenSpecFlags SpecWrongExt; - COpenSpecFlags SpecUnknownExt; - - bool Recursive; - - bool CanReturnArc; - bool CanReturnParser; - bool EachPos; - - // bool SkipSfxStub; - // bool ExeAsUnknown; - - bool ZerosTailIsAllowed; - - bool MaxStartOffset_Defined; - UInt64 MaxStartOffset; - - const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const - { - return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt)); - } - - COpenType(): - FormatIndex(-1), - Recursive(true), - EachPos(false), - CanReturnArc(true), - CanReturnParser(false), - // SkipSfxStub(true), - // ExeAsUnknown(true), - ZerosTailIsAllowed(false), - MaxStartOffset_Defined(false), - MaxStartOffset(0) - { - SpecForcedType.CanReturnFrontal = true; - SpecForcedType.CanReturnTail = true; - SpecForcedType.CanReturnMid = true; - - SpecMainType.CanReturnFrontal = true; - - SpecUnknownExt.CanReturnTail = true; // for sfx - SpecUnknownExt.CanReturnMid = true; - SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad - - // ZerosTailIsAllowed = true; - } -}; - -struct COpenOptions -{ - CCodecs *codecs; - COpenType openType; - const CObjectVector *types; - const CIntVector *excludedFormats; - - IInStream *stream; - ISequentialInStream *seqStream; - IArchiveOpenCallback *callback; - COpenCallbackImp *callbackSpec; - OPEN_PROPS_DECL - // bool openOnlySpecifiedByExtension, - - bool stdInMode; - UString filePath; - - COpenOptions(): - codecs(NULL), - types(NULL), - excludedFormats(NULL), - stream(NULL), - seqStream(NULL), - callback(NULL), - callbackSpec(NULL), - stdInMode(false) - {} - -}; - -UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL); - -struct CArcErrorInfo -{ - bool ThereIsTail; - bool UnexpecedEnd; - bool IgnoreTail; // all are zeros - // bool NonZerosTail; - bool ErrorFlags_Defined; - UInt32 ErrorFlags; - UInt32 WarningFlags; - int ErrorFormatIndex; // - 1 means no Error. - // if FormatIndex == ErrorFormatIndex, the archive is open with offset - UInt64 TailSize; - - /* if CArc is Open OK with some format: - - ErrorFormatIndex shows error format index, if extension is incorrect - - other variables show message and warnings of archive that is open */ - - UString ErrorMessage; - UString WarningMessage; - - // call IsArc_After_NonOpen only if Open returns S_FALSE - bool IsArc_After_NonOpen() const - { - return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0); - } - - - CArcErrorInfo(): - ThereIsTail(false), - UnexpecedEnd(false), - IgnoreTail(false), - // NonZerosTail(false), - ErrorFlags_Defined(false), - ErrorFlags(0), - WarningFlags(0), - ErrorFormatIndex(-1), - TailSize(0) - {} - - void ClearErrors(); - - void ClearErrors_Full() - { - ErrorFormatIndex = -1; - ClearErrors(); - } - - bool IsThereErrorOrWarning() const - { - return ErrorFlags != 0 - || WarningFlags != 0 - || NeedTailWarning() - || UnexpecedEnd - || !ErrorMessage.IsEmpty() - || !WarningMessage.IsEmpty(); - } - - bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; } - bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); } - - bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; } - - UInt32 GetWarningFlags() const - { - UInt32 a = WarningFlags; - if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0) - a |= kpv_ErrorFlags_DataAfterEnd; - return a; - } - - UInt32 GetErrorFlags() const - { - UInt32 a = ErrorFlags; - if (UnexpecedEnd) - a |= kpv_ErrorFlags_UnexpectedEnd; - return a; - } -}; - -struct CReadArcItem -{ - UString Path; // Path from root (including alt stream name, if alt stream) - UStringVector PathParts; // without altStream name, path from root or from _baseParentFolder, if _use_baseParentFolder_mode - - #ifdef SUPPORT_ALT_STREAMS - UString MainPath; - /* MainPath = Path for non-AltStream, - MainPath = Path of parent, if there is parent for AltStream. */ - UString AltStreamName; - bool IsAltStream; - bool WriteToAltStreamIfColon; - #endif - - bool IsDir; - bool MainIsDir; - UInt32 ParentIndex; // use it, if IsAltStream - - #ifndef _SFX - bool _use_baseParentFolder_mode; - int _baseParentFolder; - #endif - - CReadArcItem() - { - #ifdef SUPPORT_ALT_STREAMS - WriteToAltStreamIfColon = false; - #endif - - #ifndef _SFX - _use_baseParentFolder_mode = false; - _baseParentFolder = -1; - #endif - } -}; - -class CArc -{ - HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr &archive); - HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset); - HRESULT OpenStream2(const COpenOptions &options); - - #ifndef _SFX - // parts.Back() can contain alt stream name "nams:AltName" - HRESULT GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; - #endif - -public: - CMyComPtr Archive; - CMyComPtr InStream; - // we use InStream in 2 cases (ArcStreamOffset != 0): - // 1) if we use additional cache stream - // 2) we reopen sfx archive with CTailInStream - - CMyComPtr GetRawProps; - CMyComPtr GetRootProps; - - CArcErrorInfo ErrorInfo; // for OK archives - CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) - - UString Path; - UString filePath; - UString DefaultName; - int FormatIndex; // - 1 means Parser. - int SubfileIndex; - FILETIME MTime; - bool MTimeDefined; - - Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler - UInt64 PhySize; - // UInt64 OkPhySize; - bool PhySizeDefined; - // 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 ArcStreamOffset; // offset of stream that is open by Archive Handler - Int64 GetGlobalOffset() const { return ArcStreamOffset + Offset; } // it's global offset of archive - - // AString ErrorFlagsText; - - bool IsParseArc; - - bool IsTree; - bool IsReadOnly; - - bool Ask_Deleted; - bool Ask_AltStream; - bool Ask_Aux; - bool Ask_INode; - - bool IgnoreSplit; // don't try split handler - - // void Set_ErrorFlagsText(); - - CArc(): - MTimeDefined(false), - IsTree(false), - IsReadOnly(false), - Ask_Deleted(false), - Ask_AltStream(false), - Ask_Aux(false), - Ask_INode(false), - IgnoreSplit(false) - {} - - HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes); - - // ~CArc(); - - HRESULT Close() - { - InStream.Release(); - return Archive->Close(); - } - - HRESULT GetItemPath(UInt32 index, UString &result) const; - HRESULT GetDefaultItemPath(UInt32 index, UString &result) const; - - // GetItemPath2 adds [DELETED] dir prefix for deleted items. - HRESULT GetItemPath2(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 - { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } - - - HRESULT OpenStream(const COpenOptions &options); - HRESULT OpenStreamOrFile(COpenOptions &options); - - HRESULT ReOpen(const COpenOptions &options); - - HRESULT CreateNewTailStream(CMyComPtr &stream); -}; - -struct CArchiveLink -{ - CObjectVector Arcs; - UStringVector VolumePaths; - UInt64 VolumesSize; - bool IsOpen; - - bool PasswordWasAsked; - // UString Password; - - // int NonOpenErrorFormatIndex; // - 1 means no Error. - UString NonOpen_ArcPath; - - CArcErrorInfo NonOpen_ErrorInfo; - - // UString ErrorsText; - // void Set_ErrorsText(); - - CArchiveLink(): - VolumesSize(0), - IsOpen(false), - PasswordWasAsked(false) - {} - - void KeepModeForNextOpen(); - HRESULT Close(); - void Release(); - ~CArchiveLink() { Release(); } - - const CArc *GetArc() const { return &Arcs.Back(); } - IInArchive *GetArchive() const { return Arcs.Back().Archive; } - IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; } - IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; } - - HRESULT Open(COpenOptions &options); - HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI); - HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI); - - HRESULT ReOpen(COpenOptions &options); -}; - -bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector &types); - -#endif +// OpenArchive.h + +#ifndef ZIP7_INC_OPEN_ARCHIVE_H +#define ZIP7_INC_OPEN_ARCHIVE_H + +#include "../../../Windows/PropVariant.h" + +#include "ArchiveOpenCallback.h" +#include "LoadCodecs.h" +#include "Property.h" +#include "DirItem.h" + +#ifndef Z7_SFX + +#define SUPPORT_ALT_STREAMS + +#endif + +HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bool &result) throw(); +HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw(); +HRESULT Archive_IsItem_Aux(IInArchive *arc, UInt32 index, bool &result) throw(); +HRESULT Archive_IsItem_AltStream(IInArchive *arc, UInt32 index, bool &result) throw(); +HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &deleted) throw(); + +#ifdef SUPPORT_ALT_STREAMS +int FindAltStreamColon_in_Path(const wchar_t *path); +#endif + +/* +struct COptionalOpenProperties +{ + UString FormatName; + CObjectVector Props; +}; +*/ + +#ifdef Z7_SFX +#define OPEN_PROPS_DECL +#else +#define OPEN_PROPS_DECL const CObjectVector *props; +// #define OPEN_PROPS_DECL , const CObjectVector *props +#endif + +struct COpenSpecFlags +{ + // bool CanReturnFull; + bool CanReturnFrontal; + bool CanReturnTail; + bool CanReturnMid; + + bool CanReturn_NonStart() const { return CanReturnTail || CanReturnMid; } + + COpenSpecFlags(): + // CanReturnFull(true), + CanReturnFrontal(false), + CanReturnTail(false), + CanReturnMid(false) + {} +}; + +struct COpenType +{ + int FormatIndex; + + COpenSpecFlags SpecForcedType; + COpenSpecFlags SpecMainType; + COpenSpecFlags SpecWrongExt; + COpenSpecFlags SpecUnknownExt; + + bool Recursive; + + bool CanReturnArc; + bool CanReturnParser; + bool IsHashType; + bool EachPos; + + // bool SkipSfxStub; + // bool ExeAsUnknown; + + bool ZerosTailIsAllowed; + + bool MaxStartOffset_Defined; + UInt64 MaxStartOffset; + + const COpenSpecFlags &GetSpec(bool isForced, bool isMain, bool isUnknown) const + { + return isForced ? SpecForcedType : (isMain ? SpecMainType : (isUnknown ? SpecUnknownExt : SpecWrongExt)); + } + + COpenType(): + FormatIndex(-1), + Recursive(true), + CanReturnArc(true), + CanReturnParser(false), + IsHashType(false), + EachPos(false), + // SkipSfxStub(true), + // ExeAsUnknown(true), + ZerosTailIsAllowed(false), + MaxStartOffset_Defined(false), + MaxStartOffset(0) + { + SpecForcedType.CanReturnFrontal = true; + SpecForcedType.CanReturnTail = true; + SpecForcedType.CanReturnMid = true; + + SpecMainType.CanReturnFrontal = true; + + SpecUnknownExt.CanReturnTail = true; // for sfx + SpecUnknownExt.CanReturnMid = true; + SpecUnknownExt.CanReturnFrontal = true; // for alt streams of sfx with pad + + // ZerosTailIsAllowed = true; + } +}; + +struct COpenOptions +{ + CCodecs *codecs; + COpenType openType; + const CObjectVector *types; + const CIntVector *excludedFormats; + + IInStream *stream; + ISequentialInStream *seqStream; + IArchiveOpenCallback *callback; + COpenCallbackImp *callbackSpec; // it's used for SFX only + OPEN_PROPS_DECL + // bool openOnlySpecifiedByExtension, + + bool stdInMode; + UString filePath; + + COpenOptions(): + codecs(NULL), + types(NULL), + excludedFormats(NULL), + stream(NULL), + seqStream(NULL), + callback(NULL), + callbackSpec(NULL), + stdInMode(false) + {} + +}; + +UInt32 GetOpenArcErrorFlags(const NWindows::NCOM::CPropVariant &prop, bool *isDefinedProp = NULL); + +struct CArcErrorInfo +{ + bool ThereIsTail; + bool UnexpecedEnd; + bool IgnoreTail; // all are zeros + // bool NonZerosTail; + bool ErrorFlags_Defined; + UInt32 ErrorFlags; + UInt32 WarningFlags; + int ErrorFormatIndex; // - 1 means no Error. + // if FormatIndex == ErrorFormatIndex, the archive is open with offset + UInt64 TailSize; + + /* if CArc is Open OK with some format: + - ErrorFormatIndex shows error format index, if extension is incorrect + - other variables show message and warnings of archive that is open */ + + UString ErrorMessage; + UString WarningMessage; + + // call IsArc_After_NonOpen only if Open returns S_FALSE + bool IsArc_After_NonOpen() const + { + return (ErrorFlags_Defined && (ErrorFlags & kpv_ErrorFlags_IsNotArc) == 0); + } + + + CArcErrorInfo(): + ThereIsTail(false), + UnexpecedEnd(false), + IgnoreTail(false), + // NonZerosTail(false), + ErrorFlags_Defined(false), + ErrorFlags(0), + WarningFlags(0), + ErrorFormatIndex(-1), + TailSize(0) + {} + + void ClearErrors(); + + void ClearErrors_Full() + { + ErrorFormatIndex = -1; + ClearErrors(); + } + + bool IsThereErrorOrWarning() const + { + return ErrorFlags != 0 + || WarningFlags != 0 + || NeedTailWarning() + || UnexpecedEnd + || !ErrorMessage.IsEmpty() + || !WarningMessage.IsEmpty(); + } + + bool AreThereErrors() const { return ErrorFlags != 0 || UnexpecedEnd; } + bool AreThereWarnings() const { return WarningFlags != 0 || NeedTailWarning(); } + + bool NeedTailWarning() const { return !IgnoreTail && ThereIsTail; } + + UInt32 GetWarningFlags() const + { + UInt32 a = WarningFlags; + if (NeedTailWarning() && (ErrorFlags & kpv_ErrorFlags_DataAfterEnd) == 0) + a |= kpv_ErrorFlags_DataAfterEnd; + return a; + } + + UInt32 GetErrorFlags() const + { + UInt32 a = ErrorFlags; + if (UnexpecedEnd) + a |= kpv_ErrorFlags_UnexpectedEnd; + return a; + } +}; + +struct CReadArcItem +{ + UString Path; // Path from root (including alt stream name, if alt stream) + UStringVector PathParts; // without altStream name, path from root or from _baseParentFolder, if _use_baseParentFolder_mode + + #ifdef SUPPORT_ALT_STREAMS + UString MainPath; + /* MainPath = Path for non-AltStream, + MainPath = Path of parent, if there is parent for AltStream. */ + UString AltStreamName; + bool IsAltStream; + bool WriteToAltStreamIfColon; + #endif + + bool IsDir; + bool MainIsDir; + UInt32 ParentIndex; // use it, if IsAltStream + + #ifndef Z7_SFX + bool _use_baseParentFolder_mode; + int _baseParentFolder; + #endif + + CReadArcItem() + { + #ifdef SUPPORT_ALT_STREAMS + WriteToAltStreamIfColon = false; + #endif + + #ifndef Z7_SFX + _use_baseParentFolder_mode = false; + _baseParentFolder = -1; + #endif + } +}; + + + + +class CArc +{ + HRESULT PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr &archive); + HRESULT CheckZerosTail(const COpenOptions &op, UInt64 offset); + HRESULT OpenStream2(const COpenOptions &options); + + #ifndef Z7_SFX + // parts.Back() can contain alt stream name "nams:AltName" + HRESULT GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const; + #endif + +public: + CMyComPtr Archive; + CMyComPtr InStream; + // we use InStream in 2 cases (ArcStreamOffset != 0): + // 1) if we use additional cache stream + // 2) we reopen sfx archive with CTailInStream + + CMyComPtr GetRawProps; + CMyComPtr GetRootProps; + + bool IsParseArc; + + bool IsTree; + bool IsReadOnly; + + bool Ask_Deleted; + bool Ask_AltStream; + bool Ask_Aux; + bool Ask_INode; + + bool IgnoreSplit; // don't try split handler + + UString Path; + UString filePath; + UString DefaultName; + int FormatIndex; // -1 means Parser + UInt32 SubfileIndex; // (UInt32)(Int32)-1; means no subfile + + // CFiTime MTime; + // bool MTime_Defined; + CArcTime MTime; + + Int64 Offset; // it's offset of start of archive inside stream that is open by Archive Handler + UInt64 PhySize; + // UInt64 OkPhySize; + bool PhySize_Defined; + // bool OkPhySize_Defined; + UInt64 FileSize; + UInt64 AvailPhySize; // PhySize, but it's reduced if exceed end of file + + CArcErrorInfo ErrorInfo; // for OK archives + CArcErrorInfo NonOpen_ErrorInfo; // ErrorInfo for mainArchive (false OPEN) + + UInt64 GetEstmatedPhySize() const { return PhySize_Defined ? PhySize : FileSize; } + + UInt64 ArcStreamOffset; // offset of stream that is open by Archive Handler + Int64 GetGlobalOffset() const { return (Int64)ArcStreamOffset + Offset; } // it's global offset of archive + + // AString ErrorFlagsText; + + // void Set_ErrorFlagsText(); + + CArc(): + // MTime_Defined(false), + IsTree(false), + IsReadOnly(false), + Ask_Deleted(false), + Ask_AltStream(false), + Ask_Aux(false), + Ask_INode(false), + IgnoreSplit(false) + {} + + HRESULT ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes); + + HRESULT Close() + { + InStream.Release(); + return Archive->Close(); + } + + 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 GetItem_Path2(UInt32 index, UString &result) const; + + HRESULT GetItem(UInt32 index, CReadArcItem &item) const; + + HRESULT GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const; + + /* if (GetProperty() returns vt==VT_EMPTY), this function sets + timestamp from archive file timestamp (MTime). + So (at) will be set in most cases (at.Def == true) + if (at.Prec == 0) + { + it means that (Prec == 0) was returned for (kpidMTime), + and no value was returned for (kpidTimeType). + it can mean Windows precision or unknown precision. + } + */ + HRESULT GetItem_MTime(UInt32 index, CArcTime &at) const; + + HRESULT IsItem_Anti(UInt32 index, bool &result) const + { return Archive_GetItemBoolProp(Archive, index, kpidIsAnti, result); } + + + HRESULT OpenStream(const COpenOptions &options); + HRESULT OpenStreamOrFile(COpenOptions &options); + + HRESULT ReOpen(const COpenOptions &options, IArchiveOpenCallback *openCallback_Additional); + + HRESULT CreateNewTailStream(CMyComPtr &stream); + + bool IsHashHandler(const COpenOptions &options) const + { + if (FormatIndex < 0) + return false; + return options.codecs->Formats[(unsigned)FormatIndex].Flags_HashHandler(); + } +}; + +struct CArchiveLink +{ + CObjectVector Arcs; + UStringVector VolumePaths; + UInt64 VolumesSize; + bool IsOpen; + + bool PasswordWasAsked; + // UString Password; + + // int NonOpenErrorFormatIndex; // - 1 means no Error. + UString NonOpen_ArcPath; + + CArcErrorInfo NonOpen_ErrorInfo; + + // UString ErrorsText; + // void Set_ErrorsText(); + + CArchiveLink(): + VolumesSize(0), + IsOpen(false), + PasswordWasAsked(false) + {} + + void KeepModeForNextOpen(); + HRESULT Close(); + void Release(); + ~CArchiveLink() { Release(); } + + const CArc *GetArc() const { return &Arcs.Back(); } + IInArchive *GetArchive() const { return Arcs.Back().Archive; } + IArchiveGetRawProps *GetArchiveGetRawProps() const { return Arcs.Back().GetRawProps; } + IArchiveGetRootProps *GetArchiveGetRootProps() const { return Arcs.Back().GetRootProps; } + + /* + Open() opens archive and COpenOptions::callback + Open2() uses COpenCallbackImp that implements Volumes and password callback + Open3() calls Open2() and callbackUI->Open_Finished(); + Open_Strict() returns S_FALSE also in case, if there is non-open expected nested archive. + */ + + HRESULT Open(COpenOptions &options); + HRESULT Open2(COpenOptions &options, IOpenCallbackUI *callbackUI); + HRESULT Open3(COpenOptions &options, IOpenCallbackUI *callbackUI); + + HRESULT Open_Strict(COpenOptions &options, IOpenCallbackUI *callbackUI) + { + HRESULT result = Open3(options, callbackUI); + if (result == S_OK && NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + result = S_FALSE; + return result; + } + + HRESULT ReOpen(COpenOptions &options); +}; + +bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector &types); + +// bool IsHashType(const CObjectVector &types); + + +struct CDirPathSortPair +{ + unsigned Len; + unsigned Index; + + void SetNumSlashes(const FChar *s); + + int Compare(const CDirPathSortPair &a) const + { + // We need sorting order where parent items will be after child items + if (Len < a.Len) return 1; + if (Len > a.Len) return -1; + if (Index < a.Index) return -1; + if (Index > a.Index) return 1; + return 0; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/PropIDUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/PropIDUtils.cpp 2015-11-20 21:15:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.cpp 2024-08-08 08:00:00.000000000 +0000 @@ -1,573 +1,745 @@ -// PropIDUtils.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileIO.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../PropID.h" - -#include "PropIDUtils.h" - -#define Get16(x) GetUi16(x) -#define Get32(x) GetUi32(x) - -using namespace NWindows; - -static const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_"; -/* -0 READONLY -1 HIDDEN -2 SYSTEM - -4 DIRECTORY -5 ARCHIVE -6 DEVICE -7 NORMAL -8 TEMPORARY -9 SPARSE_FILE -10 REPARSE_POINT -11 COMPRESSED -12 OFFLINE -13 NOT_CONTENT_INDEXED -14 ENCRYPTED - -16 VIRTUAL -*/ - -static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' }; -#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-'; - -static void ConvertPosixAttribToString(char *s, UInt32 a) throw() -{ - s[0] = kPosixTypes[(a >> 12) & 0xF]; - for (int i = 6; i >= 0; i -= 3) - { - s[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r'); - s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w'); - s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x'); - } - if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); - if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); - if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); - s[10] = 0; - - a &= ~(UInt32)0xFFFF; - if (a != 0) - { - s[10] = ' '; - ConvertUInt32ToHex8Digits(a, s + 11); - } -} - -void ConvertWinAttribToString(char *s, UInt32 wa) throw() -{ - for (int i = 0; i < 16; i++) - if ((wa & (1 << i)) && i != 7) - *s++ = g_WinAttribChars[i]; - *s = 0; - - // we support p7zip trick that stores posix attributes in high 16 bits, and 0x8000 flag - // we also support ZIP archives created in Unix, that store posix attributes in high 16 bits without 0x8000 flag - - // if (wa & 0x8000) - if ((wa >> 16) != 0) - { - *s++ = ' '; - ConvertPosixAttribToString(s, wa >> 16); - } -} - -void ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw() -{ - *dest = 0; - - if (prop.vt == VT_FILETIME) - { - FILETIME localFileTime; - if ((prop.filetime.dwHighDateTime == 0 && - prop.filetime.dwLowDateTime == 0) || - !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime)) - return; - ConvertFileTimeToString(localFileTime, dest, true, full); - return; - } - - switch (propID) - { - case kpidCRC: - { - if (prop.vt != VT_UI4) - break; - ConvertUInt32ToHex8Digits(prop.ulVal, dest); - return; - } - case kpidAttrib: - { - if (prop.vt != VT_UI4) - break; - UInt32 a = prop.ulVal; - - /* - if ((a & 0x8000) && (a & 0x7FFF) == 0) - ConvertPosixAttribToString(dest, a >> 16); - else - */ - ConvertWinAttribToString(dest, a); - return; - } - case kpidPosixAttrib: - { - if (prop.vt != VT_UI4) - break; - ConvertPosixAttribToString(dest, prop.ulVal); - return; - } - case kpidINode: - { - if (prop.vt != VT_UI8) - break; - ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest); - dest += strlen(dest); - *dest++ = '-'; - UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); - ConvertUInt64ToString(low, dest); - return; - } - case kpidVa: - { - UInt64 v = 0; - if (prop.vt == VT_UI4) - v = prop.ulVal; - else if (prop.vt == VT_UI8) - v = (UInt64)prop.uhVal.QuadPart; - else - break; - dest[0] = '0'; - dest[1] = 'x'; - ConvertUInt64ToHex(v, dest + 2); - return; - } - } - - ConvertPropVariantToShortString(prop, dest); -} - -void ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full) -{ - if (prop.vt == VT_BSTR) - { - dest.SetFromBstr(prop.bstrVal); - return; - } - char temp[64]; - ConvertPropertyToShortString(temp, prop, propID, full); - dest.SetFromAscii(temp); -} - -static inline unsigned GetHex(unsigned v) -{ - return (v < 10) ? ('0' + v) : ('A' + (v - 10)); -} - -#ifndef _SFX - -static inline void AddHexToString(AString &res, unsigned v) -{ - res += (char)GetHex(v >> 4); - res += (char)GetHex(v & 0xF); - res += ' '; -} - -/* -static AString Data_To_Hex(const Byte *data, size_t size) -{ - AString s; - for (size_t i = 0; i < size; i++) - AddHexToString(s, data[i]); - return s; -} -*/ - -static const char * const sidNames[] = -{ - "0" - , "Dialup" - , "Network" - , "Batch" - , "Interactive" - , "Logon" // S-1-5-5-X-Y - , "Service" - , "Anonymous" - , "Proxy" - , "EnterpriseDC" - , "Self" - , "AuthenticatedUsers" - , "RestrictedCode" - , "TerminalServer" - , "RemoteInteractiveLogon" - , "ThisOrganization" - , "16" - , "IUserIIS" - , "LocalSystem" - , "LocalService" - , "NetworkService" - , "Domains" -}; - -struct CSecID2Name -{ - UInt32 n; - const char *sz; -}; - -static const CSecID2Name sid_32_Names[] = -{ - { 544, "Administrators" }, - { 545, "Users" }, - { 546, "Guests" }, - { 547, "PowerUsers" }, - { 548, "AccountOperators" }, - { 549, "ServerOperators" }, - { 550, "PrintOperators" }, - { 551, "BackupOperators" }, - { 552, "Replicators" }, - { 553, "Backup Operators" }, - { 554, "PreWindows2000CompatibleAccess" }, - { 555, "RemoteDesktopUsers" }, - { 556, "NetworkConfigurationOperators" }, - { 557, "IncomingForestTrustBuilders" }, - { 558, "PerformanceMonitorUsers" }, - { 559, "PerformanceLogUsers" }, - { 560, "WindowsAuthorizationAccessGroup" }, - { 561, "TerminalServerLicenseServers" }, - { 562, "DistributedCOMUsers" }, - { 569, "CryptographicOperators" }, - { 573, "EventLogReaders" }, - { 574, "CertificateServiceDCOMAccess" } -}; - -static const CSecID2Name sid_21_Names[] = -{ - { 500, "Administrator" }, - { 501, "Guest" }, - { 502, "KRBTGT" }, - { 512, "DomainAdmins" }, - { 513, "DomainUsers" }, - { 515, "DomainComputers" }, - { 516, "DomainControllers" }, - { 517, "CertPublishers" }, - { 518, "SchemaAdmins" }, - { 519, "EnterpriseAdmins" }, - { 520, "GroupPolicyCreatorOwners" }, - { 553, "RASandIASServers" }, - { 553, "RASandIASServers" }, - { 571, "AllowedRODCPasswordReplicationGroup" }, - { 572, "DeniedRODCPasswordReplicationGroup" } -}; - -struct CServicesToName -{ - UInt32 n[5]; - const char *sz; -}; - -static const CServicesToName services_to_name[] = -{ - { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" } -}; - -static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize) -{ - sidSize = 0; - if (lim < 8) - { - s += "ERROR"; - return; - } - UInt32 rev = p[0]; - if (rev != 1) - { - s += "UNSUPPORTED"; - return; - } - UInt32 num = p[1]; - if (8 + num * 4 > lim) - { - s += "ERROR"; - return; - } - sidSize = 8 + num * 4; - UInt32 authority = GetBe32(p + 4); - - if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1) - { - UInt32 v0 = Get32(p + 8); - if (v0 < ARRAY_SIZE(sidNames)) - { - s += sidNames[v0]; - return; - } - if (v0 == 32 && num == 2) - { - UInt32 v1 = Get32(p + 12); - for (unsigned i = 0; i < ARRAY_SIZE(sid_32_Names); i++) - if (sid_32_Names[i].n == v1) - { - s += sid_32_Names[i].sz; - return; - } - } - if (v0 == 21 && num == 5) - { - UInt32 v4 = Get32(p + 8 + 4 * 4); - for (unsigned i = 0; i < ARRAY_SIZE(sid_21_Names); i++) - if (sid_21_Names[i].n == v4) - { - s += sid_21_Names[i].sz; - return; - } - } - if (v0 == 80 && num == 6) - { - for (unsigned i = 0; i < ARRAY_SIZE(services_to_name); i++) - { - const CServicesToName &sn = services_to_name[i]; - int j; - for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++); - if (j == 5) - { - s += sn.sz; - return; - } - } - } - } - - char sz[16]; - s += "S-1-"; - if (p[2] == 0 && p[3] == 0) - { - ConvertUInt32ToString(authority, sz); - s += sz; - } - else - { - s += "0x"; - for (int i = 2; i < 8; i++) - AddHexToString(s, p[i]); - } - for (UInt32 i = 0; i < num; i++) - { - s += '-'; - ConvertUInt32ToString(Get32(p + 8 + i * 4), sz); - s += sz; - } -} - -static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos) -{ - if (pos > size) - { - s += "ERROR"; - return; - } - UInt32 sidSize = 0; - ParseSid(s, p + pos, size - pos, sidSize); -} - -static void AddUInt32ToString(AString &s, UInt32 val) -{ - char sz[16]; - ConvertUInt32ToString(val, sz); - s += sz; -} - -static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset) -{ - UInt32 control = Get16(p + 2); - if ((flags & control) == 0) - return; - UInt32 pos = Get32(p + offset); - s += ' '; - s += strName; - if (pos >= size) - return; - p += pos; - size -= pos; - if (size < 8) - return; - if (Get16(p) != 2) // revision - return; - UInt32 num = Get32(p + 4); - AddUInt32ToString(s, num); - - /* - UInt32 aclSize = Get16(p + 2); - if (num >= (1 << 16)) - return; - if (aclSize > size) - return; - size = aclSize; - size -= 8; - p += 8; - for (UInt32 i = 0 ; i < num; i++) - { - if (size <= 8) - return; - // Byte type = p[0]; - // Byte flags = p[1]; - // UInt32 aceSize = Get16(p + 2); - // UInt32 mask = Get32(p + 4); - p += 8; - size -= 8; - - UInt32 sidSize = 0; - s += ' '; - ParseSid(s, p, size, sidSize); - if (sidSize == 0) - return; - p += sidSize; - size -= sidSize; - } - - // the tail can contain zeros. So (size != 0) is not ERROR - // if (size != 0) s += " ERROR"; - */ -} - -#define MY_SE_OWNER_DEFAULTED (0x0001) -#define MY_SE_GROUP_DEFAULTED (0x0002) -#define MY_SE_DACL_PRESENT (0x0004) -#define MY_SE_DACL_DEFAULTED (0x0008) -#define MY_SE_SACL_PRESENT (0x0010) -#define MY_SE_SACL_DEFAULTED (0x0020) -#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100) -#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200) -#define MY_SE_DACL_AUTO_INHERITED (0x0400) -#define MY_SE_SACL_AUTO_INHERITED (0x0800) -#define MY_SE_DACL_PROTECTED (0x1000) -#define MY_SE_SACL_PROTECTED (0x2000) -#define MY_SE_RM_CONTROL_VALID (0x4000) -#define MY_SE_SELF_RELATIVE (0x8000) - -void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s) -{ - s.Empty(); - if (size < 20 || size > (1 << 18)) - { - s += "ERROR"; - return; - } - if (Get16(data) != 1) // revision - { - s += "UNSUPPORTED"; - return; - } - ParseOwner(s, data, size, Get32(data + 4)); - s += ' '; - ParseOwner(s, data, size, Get32(data + 8)); - ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12); - ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16); - s += ' '; - AddUInt32ToString(s, size); - // s += '\n'; - // s += Data_To_Hex(data, size); -} - -#ifdef _WIN32 - -static bool CheckSid(const Byte *data, UInt32 size, UInt32 pos) throw() -{ - if (pos >= size) - return false; - size -= pos; - if (size < 8) - return false; - UInt32 rev = data[pos]; - if (rev != 1) - return false; - UInt32 num = data[pos + 1]; - return (8 + num * 4 <= size); -} - -static bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset) throw() -{ - UInt32 control = Get16(p + 2); - if ((flags & control) == 0) - return true; - UInt32 pos = Get32(p + offset); - if (pos >= size) - return false; - p += pos; - size -= pos; - if (size < 8) - return false; - UInt32 aclSize = Get16(p + 2); - return (aclSize <= size); -} - -bool CheckNtSecure(const Byte *data, UInt32 size) throw() -{ - if (size < 20) - return false; - if (Get16(data) != 1) // revision - return true; // windows function can handle such error, so we allow it - if (size > (1 << 18)) - return false; - if (!CheckSid(data, size, Get32(data + 4))) return false; - if (!CheckSid(data, size, Get32(data + 8))) return false; - if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false; - if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false; - return true; -} - -bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s) -{ - s.Empty(); - NFile::CReparseAttr attr; - if (attr.Parse(data, size)) - { - if (!attr.IsSymLink()) - s.AddAscii("Junction: "); - s += attr.GetPath(); - if (!attr.IsOkNamePair()) - { - s.AddAscii(" : "); - s += attr.PrintName; - } - return true; - } - - if (size < 8) - return false; - UInt32 tag = Get32(data); - UInt32 len = Get16(data + 4); - if (len + 8 > size) - return false; - if (Get16(data + 6) != 0) // padding - return false; - - char hex[16]; - ConvertUInt32ToHex8Digits(tag, hex); - s.AddAscii(hex); - s.Add_Space(); - - data += 8; - - for (UInt32 i = 0; i < len; i++) - { - unsigned b = ((const Byte *)data)[i]; - s += (wchar_t)GetHex((b >> 4) & 0xF); - s += (wchar_t)GetHex(b & 0xF); - } - return true; -} -#endif - -#endif +// PropIDUtils.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileIO.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../PropID.h" + +#include "PropIDUtils.h" + +#ifndef Z7_SFX +#define Get16(x) GetUi16(x) +#define Get32(x) GetUi32(x) +#endif + +using namespace NWindows; + +static const unsigned kNumWinAtrribFlags = 30; +static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEVvX.PU.M......B"; + +/* +FILE_ATTRIBUTE_ + +0 READONLY +1 HIDDEN +2 SYSTEM +3 (Volume label - obsolete) +4 DIRECTORY +5 ARCHIVE +6 DEVICE +7 NORMAL +8 TEMPORARY +9 SPARSE_FILE +10 REPARSE_POINT +11 COMPRESSED +12 OFFLINE +13 NOT_CONTENT_INDEXED (I - Win10 attrib/Explorer) +14 ENCRYPTED +15 INTEGRITY_STREAM (V - ReFS Win8/Win2012) +16 VIRTUAL (reserved) +17 NO_SCRUB_DATA (X - ReFS Win8/Win2012 attrib) +18 RECALL_ON_OPEN or EA +19 PINNED +20 UNPINNED +21 STRICTLY_SEQUENTIAL (10.0.16267) +22 RECALL_ON_DATA_ACCESS +29 STRICTLY_SEQUENTIAL (10.0.17134+) (SMR Blob) +*/ + + +static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' }; +#define MY_ATTR_CHAR(a, n, c) (((a) & (1 << (n))) ? c : '-') + +static void ConvertPosixAttribToString(char *s, UInt32 a) throw() +{ + s[0] = kPosixTypes[(a >> 12) & 0xF]; + for (int i = 6; i >= 0; i -= 3) + { + s[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r'); + s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w'); + s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x'); + } + if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); // S_ISUID + if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); // S_ISGID + if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); // S_ISVTX + s[10] = 0; + + a &= ~(UInt32)0xFFFF; + if (a != 0) + { + s[10] = ' '; + ConvertUInt32ToHex8Digits(a, s + 11); + } +} + + +void ConvertWinAttribToString(char *s, UInt32 wa) throw() +{ + /* + some programs store posix attributes in high 16 bits. + p7zip - stores additional 0x8000 flag marker. + macos - stores additional 0x4000 flag marker. + info-zip - no additional marker. + But this code works with Attrib from internal 7zip code. + So we expect that 0x8000 marker is set, if there are posix attributes. + (DT_UNKNOWN == 0) type in high bits is possible in some case for linux files. + 0x8000 flag is possible also in ReFS (Windows)? + */ + + const bool isPosix = ( + (wa & 0x8000) != 0 // FILE_ATTRIBUTE_UNIX_EXTENSION; + // && (wa & 0xFFFF0000u) != 0 + ); + + UInt32 posix = 0; + if (isPosix) + { + posix = wa >> 16; + if ((wa & 0xF0000000u) != 0) + wa &= (UInt32)0x3FFF; + } + + for (unsigned i = 0; i < kNumWinAtrribFlags; i++) + { + const UInt32 flag = (UInt32)1 << i; + if (wa & flag) + { + const char c = g_WinAttribChars[i]; + if (c != '.') + { + wa &= ~flag; + // if (i != 7) // we can disable N (NORMAL) printing + *s++ = c; + } + } + } + + if (wa != 0) + { + *s++ = ' '; + ConvertUInt32ToHex8Digits(wa, s); + s += strlen(s); + } + + *s = 0; + + if (isPosix) + { + *s++ = ' '; + ConvertPosixAttribToString(s, posix); + } +} + + +void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw() +{ + *dest = 0; + + if (prop.vt == VT_FILETIME) + { + const FILETIME &ft = prop.filetime; + unsigned ns100 = 0; + int numDigits = kTimestampPrintLevel_NTFS; + const unsigned prec = prop.wReserved1; + const unsigned ns100_Temp = prop.wReserved2; + if (prec != 0 + && prec <= k_PropVar_TimePrec_1ns + && ns100_Temp < 100 + && prop.wReserved3 == 0) + { + ns100 = ns100_Temp; + if (prec == k_PropVar_TimePrec_Unix || + prec == k_PropVar_TimePrec_DOS) + numDigits = 0; + else if (prec == k_PropVar_TimePrec_HighPrec) + numDigits = 9; + else + { + numDigits = (int)prec - (int)k_PropVar_TimePrec_Base; + if ( + // numDigits < kTimestampPrintLevel_DAY // for debuf + numDigits < kTimestampPrintLevel_SEC + ) + + numDigits = kTimestampPrintLevel_NTFS; + } + } + if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0) + return; + if (level > numDigits) + level = numDigits; + ConvertUtcFileTimeToString2(ft, ns100, dest, level); + return; + } + + switch (propID) + { + case kpidCRC: + { + if (prop.vt != VT_UI4) + break; + ConvertUInt32ToHex8Digits(prop.ulVal, dest); + return; + } + case kpidAttrib: + { + if (prop.vt != VT_UI4) + break; + const UInt32 a = prop.ulVal; + + /* + if ((a & 0x8000) && (a & 0x7FFF) == 0) + ConvertPosixAttribToString(dest, a >> 16); + else + */ + ConvertWinAttribToString(dest, a); + return; + } + case kpidPosixAttrib: + { + if (prop.vt != VT_UI4) + break; + ConvertPosixAttribToString(dest, prop.ulVal); + return; + } + case kpidINode: + { + if (prop.vt != VT_UI8) + break; + ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest); + dest += strlen(dest); + *dest++ = '-'; + const UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1); + ConvertUInt64ToString(low, dest); + return; + } + case kpidVa: + { + UInt64 v = 0; + if (prop.vt == VT_UI4) + v = prop.ulVal; + else if (prop.vt == VT_UI8) + v = (UInt64)prop.uhVal.QuadPart; + else + break; + dest[0] = '0'; + dest[1] = 'x'; + 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; + } + */ + default: break; + } + + ConvertPropVariantToShortString(prop, dest); +} + +void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level) +{ + if (prop.vt == VT_BSTR) + { + dest.SetFromBstr(prop.bstrVal); + return; + } + char temp[64]; + ConvertPropertyToShortString2(temp, prop, propID, level); + dest = temp; +} + +#ifndef Z7_SFX + +static inline void AddHexToString(AString &res, unsigned v) +{ + res.Add_Char((char)GET_HEX_CHAR_UPPER(v >> 4)); + res.Add_Char((char)GET_HEX_CHAR_UPPER(v & 15)); +} + +/* +static AString Data_To_Hex(const Byte *data, size_t size) +{ + AString s; + for (size_t i = 0; i < size; i++) + AddHexToString(s, data[i]); + return s; +} +*/ + +static const char * const sidNames[] = +{ + "0" + , "Dialup" + , "Network" + , "Batch" + , "Interactive" + , "Logon" // S-1-5-5-X-Y + , "Service" + , "Anonymous" + , "Proxy" + , "EnterpriseDC" + , "Self" + , "AuthenticatedUsers" + , "RestrictedCode" + , "TerminalServer" + , "RemoteInteractiveLogon" + , "ThisOrganization" + , "16" + , "IUserIIS" + , "LocalSystem" + , "LocalService" + , "NetworkService" + , "Domains" +}; + +struct CSecID2Name +{ + UInt32 n; + const char *sz; +}; + +static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id) +{ + for (unsigned i = 0; i < num; i++) + if (pairs[i].n == id) + return (int)i; + return -1; +} + +static const CSecID2Name sid_32_Names[] = +{ + { 544, "Administrators" }, + { 545, "Users" }, + { 546, "Guests" }, + { 547, "PowerUsers" }, + { 548, "AccountOperators" }, + { 549, "ServerOperators" }, + { 550, "PrintOperators" }, + { 551, "BackupOperators" }, + { 552, "Replicators" }, + { 553, "Backup Operators" }, + { 554, "PreWindows2000CompatibleAccess" }, + { 555, "RemoteDesktopUsers" }, + { 556, "NetworkConfigurationOperators" }, + { 557, "IncomingForestTrustBuilders" }, + { 558, "PerformanceMonitorUsers" }, + { 559, "PerformanceLogUsers" }, + { 560, "WindowsAuthorizationAccessGroup" }, + { 561, "TerminalServerLicenseServers" }, + { 562, "DistributedCOMUsers" }, + { 569, "CryptographicOperators" }, + { 573, "EventLogReaders" }, + { 574, "CertificateServiceDCOMAccess" } +}; + +static const CSecID2Name sid_21_Names[] = +{ + { 500, "Administrator" }, + { 501, "Guest" }, + { 502, "KRBTGT" }, + { 512, "DomainAdmins" }, + { 513, "DomainUsers" }, + { 515, "DomainComputers" }, + { 516, "DomainControllers" }, + { 517, "CertPublishers" }, + { 518, "SchemaAdmins" }, + { 519, "EnterpriseAdmins" }, + { 520, "GroupPolicyCreatorOwners" }, + { 553, "RASandIASServers" }, + { 553, "RASandIASServers" }, + { 571, "AllowedRODCPasswordReplicationGroup" }, + { 572, "DeniedRODCPasswordReplicationGroup" } +}; + +struct CServicesToName +{ + UInt32 n[5]; + const char *sz; +}; + +static const CServicesToName services_to_name[] = +{ + { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" } +}; + +static void ParseSid(AString &s, const Byte *p, size_t lim /* , unsigned &sidSize */) +{ + // sidSize = 0; + if (lim < 8) + { + s += "ERROR"; + return; + } + if (p[0] != 1) // rev + { + s += "UNSUPPORTED"; + return; + } + const unsigned num = p[1]; + const unsigned sidSize_Loc = 8 + num * 4; + if (sidSize_Loc > lim) + { + s += "ERROR"; + return; + } + // sidSize = sidSize_Loc; + const UInt32 authority = GetBe32(p + 4); + + if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1) + { + const UInt32 v0 = Get32(p + 8); + if (v0 < Z7_ARRAY_SIZE(sidNames)) + { + s += sidNames[v0]; + return; + } + if (v0 == 32 && num == 2) + { + const UInt32 v1 = Get32(p + 12); + const int index = FindPairIndex(sid_32_Names, Z7_ARRAY_SIZE(sid_32_Names), v1); + if (index >= 0) + { + s += sid_32_Names[(unsigned)index].sz; + return; + } + } + if (v0 == 21 && num == 5) + { + UInt32 v4 = Get32(p + 8 + 4 * 4); + const int index = FindPairIndex(sid_21_Names, Z7_ARRAY_SIZE(sid_21_Names), v4); + if (index >= 0) + { + s += sid_21_Names[(unsigned)index].sz; + return; + } + } + if (v0 == 80 && num == 6) + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(services_to_name); i++) + { + const CServicesToName &sn = services_to_name[i]; + int j; + for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++); + if (j == 5) + { + s += sn.sz; + return; + } + } + } + } + + s += "S-1-"; + if (p[2] == 0 && p[3] == 0) + s.Add_UInt32(authority); + else + { + s += "0x"; + for (int i = 2; i < 8; i++) + AddHexToString(s, p[i]); + } + for (UInt32 i = 0; i < num; i++) + { + s.Add_Minus(); + s.Add_UInt32(Get32(p + 8 + i * 4)); + } +} + +static void ParseOwner(AString &s, const Byte *p, size_t size, UInt32 pos) +{ + if (pos > size) + { + s += "ERROR"; + return; + } + // unsigned sidSize = 0; + ParseSid(s, p + pos, size - pos /* , sidSize */); +} + +static void ParseAcl(AString &s, const Byte *p, size_t size, const char *strName, UInt32 flags, UInt32 offset) +{ + const unsigned control = Get16(p + 2); + if ((flags & control) == 0) + return; + const UInt32 pos = Get32(p + offset); + s.Add_Space(); + s += strName; + if (pos >= size) + return; + p += pos; + size -= (size_t)pos; + if (size < 8) + return; + if (Get16(p) != 2) // revision + return; + const UInt32 num = Get32(p + 4); + s.Add_UInt32(num); + + /* + UInt32 aclSize = Get16(p + 2); + if (num >= (1 << 16)) + return; + if (aclSize > size) + return; + size = aclSize; + size -= 8; + p += 8; + for (UInt32 i = 0 ; i < num; i++) + { + if (size <= 8) + return; + // Byte type = p[0]; + // Byte flags = p[1]; + // UInt32 aceSize = Get16(p + 2); + // UInt32 mask = Get32(p + 4); + p += 8; + size -= 8; + + UInt32 sidSize = 0; + s.Add_Space(); + ParseSid(s, p, size, sidSize); + if (sidSize == 0) + return; + p += sidSize; + size -= sidSize; + } + + // the tail can contain zeros. So (size != 0) is not ERROR + // if (size != 0) s += " ERROR"; + */ +} + +/* +#define MY_SE_OWNER_DEFAULTED (0x0001) +#define MY_SE_GROUP_DEFAULTED (0x0002) +*/ +#define MY_SE_DACL_PRESENT (0x0004) +/* +#define MY_SE_DACL_DEFAULTED (0x0008) +*/ +#define MY_SE_SACL_PRESENT (0x0010) +/* +#define MY_SE_SACL_DEFAULTED (0x0020) +#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100) +#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200) +#define MY_SE_DACL_AUTO_INHERITED (0x0400) +#define MY_SE_SACL_AUTO_INHERITED (0x0800) +#define MY_SE_DACL_PROTECTED (0x1000) +#define MY_SE_SACL_PROTECTED (0x2000) +#define MY_SE_RM_CONTROL_VALID (0x4000) +#define MY_SE_SELF_RELATIVE (0x8000) +*/ + +void ConvertNtSecureToString(const Byte *data, size_t size, AString &s) +{ + s.Empty(); + if (size < 20 || size > (1 << 18)) + { + s += "ERROR"; + return; + } + if (Get16(data) != 1) // revision + { + s += "UNSUPPORTED"; + return; + } + ParseOwner(s, data, size, Get32(data + 4)); + s.Add_Space(); + ParseOwner(s, data, size, Get32(data + 8)); + ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12); + ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16); + s.Add_Space(); + s.Add_UInt32((UInt32)size); + // s.Add_LF(); + // s += Data_To_Hex(data, size); +} + +#ifdef _WIN32 + +static bool CheckSid(const Byte *data, size_t size, UInt32 pos) throw() +{ + if (pos >= size) + return false; + size -= pos; + if (size < 8) + return false; + if (data[pos] != 1) // rev + return false; + const unsigned num = data[pos + 1]; + return (8 + num * 4 <= size); +} + +static bool CheckAcl(const Byte *p, size_t size, UInt32 flags, size_t offset) throw() +{ + const unsigned control = Get16(p + 2); + if ((flags & control) == 0) + return true; + const UInt32 pos = Get32(p + offset); + if (pos >= size) + return false; + p += pos; + size -= pos; + if (size < 8) + return false; + const unsigned aclSize = Get16(p + 2); + return (aclSize <= size); +} + +bool CheckNtSecure(const Byte *data, size_t size) throw() +{ + if (size < 20) + return false; + if (Get16(data) != 1) // revision + return true; // windows function can handle such error, so we allow it + if (size > (1 << 18)) + return false; + if (!CheckSid(data, size, Get32(data + 4))) return false; + if (!CheckSid(data, size, Get32(data + 8))) return false; + if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false; + if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false; + return true; +} + +#endif + + + +// IO_REPARSE_TAG_* + +static const CSecID2Name k_ReparseTags[] = +{ + { 0xA0000003, "MOUNT_POINT" }, + { 0xC0000004, "HSM" }, + { 0x80000005, "DRIVE_EXTENDER" }, + { 0x80000006, "HSM2" }, + { 0x80000007, "SIS" }, + { 0x80000008, "WIM" }, + { 0x80000009, "CSV" }, + { 0x8000000A, "DFS" }, + { 0x8000000B, "FILTER_MANAGER" }, + { 0xA000000C, "SYMLINK" }, + { 0xA0000010, "IIS_CACHE" }, + { 0x80000012, "DFSR" }, + { 0x80000013, "DEDUP" }, + { 0xC0000014, "APPXSTRM" }, + { 0x80000014, "NFS" }, + { 0x80000015, "FILE_PLACEHOLDER" }, + { 0x80000016, "DFM" }, + { 0x80000017, "WOF" }, + { 0x80000018, "WCI" }, + { 0x8000001B, "APPEXECLINK" }, + { 0xA000001D, "LX_SYMLINK" }, + { 0x80000023, "AF_UNIX" }, + { 0x80000024, "LX_FIFO" }, + { 0x80000025, "LX_CHR" }, + { 0x80000026, "LX_BLK" } +}; + +bool ConvertNtReparseToString(const Byte *data, size_t size, UString &s) +{ + s.Empty(); + NFile::CReparseAttr attr; + + if (attr.Parse(data, size)) + { + if (attr.IsSymLink_WSL()) + { + s += "WSL: "; + s += attr.GetPath(); + } + else + { + if (!attr.IsSymLink_Win()) + s += "Junction: "; + s += attr.GetPath(); + if (s.IsEmpty()) + s += "Link: "; + if (!attr.IsOkNamePair()) + { + s += " : "; + s += attr.PrintName; + } + } + if (attr.MinorError) + s += " : MINOR_ERROR"; + return true; + // s.Add_Space(); // for debug + } + + if (size < 8) + return false; + const UInt32 tag = Get32(data); + const UInt32 len = Get16(data + 4); + if (len + 8 > size) + return false; + if (Get16(data + 6) != 0) // padding + return false; + + /* + #define my_IO_REPARSE_TAG_DEDUP (0x80000013L) + if (tag == my_IO_REPARSE_TAG_DEDUP) + { + } + */ + + { + const int index = FindPairIndex(k_ReparseTags, Z7_ARRAY_SIZE(k_ReparseTags), tag); + if (index >= 0) + s += k_ReparseTags[(unsigned)index].sz; + else + { + s += "REPARSE:"; + char hex[16]; + ConvertUInt32ToHex8Digits(tag, hex); + s += hex; + } + } + + s.Add_Colon(); + s.Add_UInt32(len); + + if (len != 0) + { + s.Add_Space(); + + data += 8; + + for (UInt32 i = 0; i < len; i++) + { + if (i >= 16) + { + s += "..."; + break; + } + const unsigned b = data[i]; + s.Add_Char((char)GET_HEX_CHAR_UPPER(b >> 4)); + s.Add_Char((char)GET_HEX_CHAR_UPPER(b & 15)); + } + } + + return true; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/PropIDUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/PropIDUtils.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/PropIDUtils.h 2023-09-05 08:00:00.000000000 +0000 @@ -1,18 +1,18 @@ -// PropIDUtils.h - -#ifndef __PROPID_UTILS_H -#define __PROPID_UTILS_H - -#include "../../../Common/MyString.h" - -// provide at least 64 bytes for buffer including zero-end -void ConvertPropertyToShortString(char *dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true) throw(); -void ConvertPropertyToString(UString &dest, const PROPVARIANT &propVariant, PROPID propID, bool full = true); - -bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s); -void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s); -bool CheckNtSecure(const Byte *data, UInt32 size) throw();; - -void ConvertWinAttribToString(char *s, UInt32 wa) throw(); - -#endif +// PropIDUtils.h + +#ifndef ZIP7_INC_PROPID_UTILS_H +#define ZIP7_INC_PROPID_UTILS_H + +#include "../../../Common/MyString.h" + +// provide at least 64 bytes for buffer including zero-end +void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0) throw(); +void ConvertPropertyToString2(UString &dest, const PROPVARIANT &propVariant, PROPID propID, int level = 0); + +bool ConvertNtReparseToString(const Byte *data, size_t size, UString &s); +void ConvertNtSecureToString(const Byte *data, size_t size, AString &s); +bool CheckNtSecure(const Byte *data, size_t size) throw(); + +void ConvertWinAttribToString(char *s, UInt32 wa) throw(); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Property.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Property.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/Property.h 2011-06-12 13:24:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Property.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// Property.h - -#ifndef __7Z_PROPERTY_H -#define __7Z_PROPERTY_H - -#include "../../../Common/MyString.h" - -struct CProperty -{ - UString Name; - UString Value; -}; - -#endif +// Property.h + +#ifndef ZIP7_INC_7Z_PROPERTY_H +#define ZIP7_INC_7Z_PROPERTY_H + +#include "../../../Common/MyString.h" + +struct CProperty +{ + UString Name; + UString Value; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/SetProperties.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/SetProperties.cpp 2014-12-21 12:44:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.cpp 2023-09-26 16:00:00.000000000 +0000 @@ -1,80 +1,88 @@ -// SetProperties.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyString.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../Archive/IArchive.h" - -#include "SetProperties.h" - -using namespace NWindows; -using namespace NCOM; - -static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) -{ - const wchar_t *end; - UInt64 result = ConvertStringToUInt64(s, &end); - if (*end != 0 || s.IsEmpty()) - prop = s; - else if (result <= (UInt32)0xFFFFFFFF) - prop = (UInt32)result; - else - prop = result; -} - -HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties) -{ - if (properties.IsEmpty()) - return S_OK; - CMyComPtr setProperties; - unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties); - if (!setProperties) - return S_OK; - - UStringVector realNames; - CPropVariant *values = new CPropVariant[properties.Size()]; - try - { - unsigned i; - for (i = 0; i < properties.Size(); i++) - { - const CProperty &property = properties[i]; - NCOM::CPropVariant propVariant; - UString name = property.Name; - if (property.Value.IsEmpty()) - { - if (!name.IsEmpty()) - { - wchar_t c = name.Back(); - if (c == L'-') - propVariant = false; - else if (c == L'+') - propVariant = true; - if (propVariant.vt != VT_EMPTY) - name.DeleteBack(); - } - } - else - ParseNumberString(property.Value, propVariant); - realNames.Add(name); - values[i] = propVariant; - } - CRecordVector names; - for (i = 0; i < realNames.Size(); i++) - names.Add((const wchar_t *)realNames[i]); - - RINOK(setProperties->SetProperties(&names.Front(), values, names.Size())); - } - catch(...) - { - delete []values; - throw; - } - delete []values; - return S_OK; -} +// SetProperties.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyString.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../Archive/IArchive.h" + +#include "SetProperties.h" + +using namespace NWindows; +using namespace NCOM; + +static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) +{ + const wchar_t *end; + const UInt64 result = ConvertStringToUInt64(s, &end); + if (*end != 0 || s.IsEmpty()) + prop = s; + else if (result <= (UInt32)0xFFFFFFFF) + prop = (UInt32)result; + else + prop = result; +} + + +struct CPropPropetiesVector +{ + CPropVariant *values; + CPropPropetiesVector(unsigned num) + { + values = new CPropVariant[num]; + } + ~CPropPropetiesVector() + { + delete []values; + } +}; + + +HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties) +{ + if (properties.IsEmpty()) + return S_OK; + Z7_DECL_CMyComPtr_QI_FROM( + ISetProperties, + setProperties, unknown) + if (!setProperties) + return S_OK; + + UStringVector realNames; + CPropPropetiesVector values(properties.Size()); + { + unsigned i; + for (i = 0; i < properties.Size(); i++) + { + const CProperty &property = properties[i]; + NCOM::CPropVariant propVariant; + UString name = property.Name; + if (property.Value.IsEmpty()) + { + if (!name.IsEmpty()) + { + const wchar_t c = name.Back(); + if (c == L'-') + propVariant = false; + else if (c == L'+') + propVariant = true; + if (propVariant.vt != VT_EMPTY) + name.DeleteBack(); + } + } + else + ParseNumberString(property.Value, propVariant); + realNames.Add(name); + values.values[i] = propVariant; + } + CRecordVector names; + for (i = 0; i < realNames.Size(); i++) + names.Add((const wchar_t *)realNames[i]); + + return setProperties->SetProperties(names.ConstData(), values.values, names.Size()); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/SetProperties.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/SetProperties.h 2008-08-05 09:48:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SetProperties.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// SetProperties.h - -#ifndef __SETPROPERTIES_H -#define __SETPROPERTIES_H - -#include "Property.h" - -HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties); - -#endif +// SetProperties.h + +#ifndef ZIP7_INC_SETPROPERTIES_H +#define ZIP7_INC_SETPROPERTIES_H + +#include "Property.h" + +HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/SortUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/SortUtils.cpp 2015-11-20 20:40:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.cpp 2015-11-10 07:08:33.000000000 +0000 @@ -1,25 +1,25 @@ -// SortUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/Wildcard.h" - -#include "SortUtils.h" - -static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param) -{ - const UStringVector &strings = *(const UStringVector *)param; - return CompareFileNames(strings[*p1], strings[*p2]); -} - -void SortFileNames(const UStringVector &strings, CUIntVector &indices) -{ - const unsigned numItems = strings.Size(); - indices.ClearAndSetSize(numItems); - if (numItems == 0) - return; - unsigned *vals = &indices[0]; - for (unsigned i = 0; i < numItems; i++) - vals[i] = i; - indices.Sort(CompareStrings, (void *)&strings); -} +// SortUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/Wildcard.h" + +#include "SortUtils.h" + +static int CompareStrings(const unsigned *p1, const unsigned *p2, void *param) +{ + const UStringVector &strings = *(const UStringVector *)param; + return CompareFileNames(strings[*p1], strings[*p2]); +} + +void SortFileNames(const UStringVector &strings, CUIntVector &indices) +{ + const unsigned numItems = strings.Size(); + indices.ClearAndSetSize(numItems); + if (numItems == 0) + return; + unsigned *vals = &indices[0]; + for (unsigned i = 0; i < numItems; i++) + vals[i] = i; + indices.Sort(CompareStrings, (void *)&strings); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/SortUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/SortUtils.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/SortUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// SortUtils.h - -#ifndef __SORT_UTLS_H -#define __SORT_UTLS_H - -#include "../../../Common/MyString.h" - -void SortFileNames(const UStringVector &strings, CUIntVector &indices); - -#endif +// SortUtils.h + +#ifndef ZIP7_INC_SORT_UTLS_H +#define ZIP7_INC_SORT_UTLS_H + +#include "../../../Common/MyString.h" + +void SortFileNames(const UStringVector &strings, CUIntVector &indices); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/TempFiles.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/TempFiles.cpp 2015-11-20 20:40:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.cpp 2024-10-15 15:00:00.000000000 +0000 @@ -1,19 +1,20 @@ -// TempFiles.cpp - -#include "StdAfx.h" - -#include "../../../Windows/FileDir.h" - -#include "TempFiles.h" - -using namespace NWindows; -using namespace NFile; - -void CTempFiles::Clear() -{ - while (!Paths.IsEmpty()) - { - NDir::DeleteFileAlways(Paths.Back()); - Paths.DeleteBack(); - } -} +// TempFiles.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileDir.h" + +#include "TempFiles.h" + +using namespace NWindows; +using namespace NFile; + +void CTempFiles::Clear() +{ + while (!Paths.IsEmpty()) + { + if (NeedDeleteFiles) + NDir::DeleteFileAlways(Paths.Back()); + Paths.DeleteBack(); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/TempFiles.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/TempFiles.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/TempFiles.h 2024-10-15 15:00:00.000000000 +0000 @@ -1,16 +1,19 @@ -// TempFiles.h - -#ifndef __TEMP_FILES_H -#define __TEMP_FILES_H - -#include "../../../Common/MyString.h" - -class CTempFiles -{ - void Clear(); -public: - FStringVector Paths; - ~CTempFiles() { Clear(); } -}; - -#endif +// TempFiles.h + +#ifndef ZIP7_INC_TEMP_FILES_H +#define ZIP7_INC_TEMP_FILES_H + +#include "../../../Common/MyString.h" + +class CTempFiles +{ + void Clear(); +public: + FStringVector Paths; + bool NeedDeleteFiles; + + CTempFiles(): NeedDeleteFiles(true) {} + ~CTempFiles() { Clear(); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Update.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/Update.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.cpp 2024-12-30 13:00:00.000000000 +0000 @@ -1,1558 +1,1931 @@ -// Update.cpp - -#include "StdAfx.h" - -#include "Update.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" -#include "../../../Windows/TimeUtils.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/LimitedStreams.h" - -#include "../../Compress/CopyCoder.h" - -#include "../Common/DirItem.h" -#include "../Common/EnumDirItems.h" -#include "../Common/OpenArchive.h" -#include "../Common/UpdateProduce.h" - -#include "EnumDirItems.h" -#include "SetProperties.h" -#include "TempFiles.h" -#include "UpdateCallback.h" - -static const char *kUpdateIsNotSupoorted = - "update operations are not supported for this archive"; - -using namespace NWindows; -using namespace NCOM; -using namespace NFile; -using namespace NDir; -using namespace NName; - -static CFSTR kTempFolderPrefix = FTEXT("7zE"); - - -void CUpdateErrorInfo::SetFromLastError(const char *message) -{ - SystemError = ::GetLastError(); - Message = message; -} - -HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &fileName) -{ - SetFromLastError(message); - FileNames.Add(fileName); - return Get_HRESULT_Error(); -} - -static bool DeleteEmptyFolderAndEmptySubFolders(const FString &path) -{ - NFind::CFileInfo fileInfo; - FString pathPrefix = path + FCHAR_PATH_SEPARATOR; - { - NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK); - while (enumerator.Next(fileInfo)) - { - if (fileInfo.IsDir()) - if (!DeleteEmptyFolderAndEmptySubFolders(pathPrefix + fileInfo.Name)) - return false; - } - } - /* - // we don't need clear read-only for folders - if (!MySetFileAttributes(path, 0)) - return false; - */ - return RemoveDir(path); -} - - -using namespace NUpdateArchive; - -class COutMultiVolStream: - public IOutStream, - public CMyUnknownImp -{ - unsigned _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CAltStreamInfo - { - COutFileStream *StreamSpec; - CMyComPtr Stream; - FString Name; - UInt64 Pos; - UInt64 RealSize; - }; - CObjectVector Streams; -public: - // CMyComPtr VolumeCallback; - CRecordVector Sizes; - FString Prefix; - CTempFiles *TempFiles; - - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - bool SetMTime(const FILETIME *mTime); - HRESULT Close(); - - UInt64 GetSize() const { return _length; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); -}; - -// static NSynchronization::CCriticalSection g_TempPathsCS; - -HRESULT COutMultiVolStream::Close() -{ - HRESULT res = S_OK; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - { - HRESULT res2 = s->Close(); - if (res2 != S_OK) - res = res2; - } - } - return res; -} - -bool COutMultiVolStream::SetMTime(const FILETIME *mTime) -{ - bool res = true; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - if (!s->SetMTime(mTime)) - res = false; - } - return res; -} - -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize != NULL) - *processedSize = 0; - while (size > 0) - { - if (_streamIndex >= Streams.Size()) - { - CAltStreamInfo altStream; - - FChar temp[16]; - ConvertUInt32ToString(_streamIndex + 1, temp); - FString name = temp; - while (name.Len() < 3) - name.InsertAtFront(FTEXT('0')); - name.Insert(0, Prefix); - altStream.StreamSpec = new COutFileStream; - altStream.Stream = altStream.StreamSpec; - if (!altStream.StreamSpec->Create(name, false)) - return ::GetLastError(); - { - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); - TempFiles->Paths.Add(name); - } - - altStream.Pos = 0; - altStream.RealSize = 0; - altStream.Name = name; - Streams.Add(altStream); - continue; - } - CAltStreamInfo &altStream = Streams[_streamIndex]; - - unsigned index = _streamIndex; - if (index >= Sizes.Size()) - index = Sizes.Size() - 1; - UInt64 volSize = Sizes[index]; - - if (_offsetPos >= volSize) - { - _offsetPos -= volSize; - _streamIndex++; - continue; - } - if (_offsetPos != altStream.Pos) - { - // CMyComPtr outStream; - // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(altStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); - altStream.Pos = _offsetPos; - } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos); - UInt32 realProcessed; - RINOK(altStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); - size -= realProcessed; - altStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (_offsetPos > altStream.RealSize) - altStream.RealSize = _offsetPos; - if (processedSize != NULL) - *processedSize += realProcessed; - if (altStream.Pos == volSize) - { - _streamIndex++; - _offsetPos = 0; - } - if (realProcessed == 0 && curSize != 0) - return E_FAIL; - break; - } - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - switch (seekOrigin) - { - case STREAM_SEEK_SET: _absPos = offset; break; - case STREAM_SEEK_CUR: _absPos += offset; break; - case STREAM_SEEK_END: _absPos = _length + offset; break; - } - _offsetPos = _absPos; - if (newPosition != NULL) - *newPosition = _absPos; - _streamIndex = 0; - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize) -{ - if (newSize < 0) - return E_INVALIDARG; - unsigned i = 0; - while (i < Streams.Size()) - { - CAltStreamInfo &altStream = Streams[i++]; - if ((UInt64)newSize < altStream.RealSize) - { - RINOK(altStream.Stream->SetSize(newSize)); - altStream.RealSize = newSize; - break; - } - newSize -= altStream.RealSize; - } - while (i < Streams.Size()) - { - { - CAltStreamInfo &altStream = Streams.Back(); - altStream.Stream.Release(); - DeleteFileAlways(altStream.Name); - } - Streams.DeleteBack(); - } - _offsetPos = _absPos; - _streamIndex = 0; - _length = newSize; - return S_OK; -} - -void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) -{ - OriginalPath = path; - - SplitPathToParts_2(path, Prefix, Name); - - if (mode == k_ArcNameMode_Add) - return; - if (mode == k_ArcNameMode_Exact) - { - BaseExtension.Empty(); - return; - } - - int dotPos = Name.ReverseFind_Dot(); - if (dotPos < 0) - return; - if ((unsigned)dotPos == Name.Len() - 1) - { - Name.DeleteBack(); - BaseExtension.Empty(); - return; - } - const UString ext = Name.Ptr(dotPos + 1); - if (BaseExtension.IsEqualTo_NoCase(ext)) - { - BaseExtension = ext; - Name.DeleteFrom(dotPos); - } - else - BaseExtension.Empty(); -} - -UString CArchivePath::GetFinalPath() const -{ - UString path = GetPathWithoutExt(); - if (!BaseExtension.IsEmpty()) - { - path += L'.'; - path += BaseExtension; - } - return path; -} - -UString CArchivePath::GetFinalVolPath() const -{ - UString path = GetPathWithoutExt(); - if (!BaseExtension.IsEmpty()) - { - path += L'.'; - path += VolExtension; - } - return path; -} - -FString CArchivePath::GetTempPath() const -{ - FString path = TempPrefix; - path += us2fs(Name); - if (!BaseExtension.IsEmpty()) - { - path += FTEXT('.'); - path += us2fs(BaseExtension); - } - path.AddAscii(".tmp"); - path += TempPostfix; - return path; -} - -static const wchar_t *kDefaultArcType = L"7z"; -static const wchar_t *kDefaultArcExt = L"7z"; -static const char *kSFXExtension = - #ifdef _WIN32 - "exe"; - #else - ""; - #endif - -bool CUpdateOptions::InitFormatIndex(const CCodecs *codecs, - const CObjectVector &types, const UString &arcPath) -{ - if (types.Size() > 1) - return false; - // int arcTypeIndex = -1; - if (types.Size() != 0) - { - MethodMode.Type = types[0]; - MethodMode.Type_Defined = true; - } - if (MethodMode.Type.FormatIndex < 0) - { - // MethodMode.Type = -1; - MethodMode.Type = COpenType(); - if (ArcNameMode != k_ArcNameMode_Add) - { - MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath); - if (MethodMode.Type.FormatIndex >= 0) - MethodMode.Type_Defined = true; - } - } - return true; -} - -bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) -{ - UString typeExt; - int formatIndex = MethodMode.Type.FormatIndex; - if (formatIndex < 0) - { - typeExt = kDefaultArcExt; - } - else - { - const CArcInfoEx &arcInfo = codecs->Formats[formatIndex]; - if (!arcInfo.UpdateEnabled) - return false; - typeExt = arcInfo.GetMainExt(); - } - UString ext = typeExt; - if (SfxMode) - ext.SetFromAscii(kSFXExtension); - ArchivePath.BaseExtension = ext; - ArchivePath.VolExtension = typeExt; - ArchivePath.ParseFromPath(arcPath, ArcNameMode); - FOR_VECTOR (i, Commands) - { - CUpdateArchiveCommand &uc = Commands[i]; - uc.ArchivePath.BaseExtension = ext; - uc.ArchivePath.VolExtension = typeExt; - uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode); - } - return true; -} - -struct CUpdateProduceCallbackImp: public IUpdateProduceCallback -{ - const CObjectVector *_arcItems; - IUpdateCallbackUI *_callback; - - CUpdateProduceCallbackImp(const CObjectVector *a, - IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {} - virtual HRESULT ShowDeleteFile(unsigned arcIndex); -}; - -HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex) -{ - const CArcItem &ai = (*_arcItems)[arcIndex]; - return _callback->ShowDeleteFile(ai.Name, ai.IsDir); -} - -bool CRenamePair::Prepare() -{ - if (RecursedType != NRecursedType::kNonRecursed) - return false; - if (!WildcardParsing) - return true; - return !DoesNameContainWildcard(OldName); -} - -extern bool g_CaseSensitive; - -static unsigned CompareTwoNames(const wchar_t *s1, const wchar_t *s2) -{ - for (unsigned i = 0;; i++) - { - wchar_t c1 = s1[i]; - wchar_t c2 = s2[i]; - if (c1 == 0 || c2 == 0) - return i; - if (c1 == c2) - continue; - if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2))) - continue; - if (IsPathSepar(c1) && IsPathSepar(c2)) - continue; - return i; - } -} - -bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const -{ - unsigned num = CompareTwoNames(OldName, src); - if (OldName[num] == 0) - { - if (src[num] != 0 && !IsPathSepar(src[num]) && num != 0 && !IsPathSepar(src[num - 1])) - return false; - } - else - { - // OldName[num] != 0 - // OldName = "1\1a.txt" - // src = "1" - - if (!isFolder - || src[num] != 0 - || !IsPathSepar(OldName[num]) - || OldName[num + 1] != 0) - return false; - } - dest = NewName + src.Ptr(num); - return true; -} - -#ifdef SUPPORT_ALT_STREAMS -int FindAltStreamColon_in_Path(const wchar_t *path); -#endif - -static HRESULT Compress( - const CUpdateOptions &options, - bool isUpdatingItself, - CCodecs *codecs, - const CActionSet &actionSet, - const CArc *arc, - CArchivePath &archivePath, - const CObjectVector &arcItems, - Byte *processedItemsStatuses, - const CDirItems &dirItems, - const CDirItem *parentDirItem, - CTempFiles &tempFiles, - CUpdateErrorInfo &errorInfo, - IUpdateCallbackUI *callback, - CFinishArchiveStat &st) -{ - CMyComPtr outArchive; - int formatIndex = options.MethodMode.Type.FormatIndex; - - if (arc) - { - formatIndex = arc->FormatIndex; - if (formatIndex < 0) - return E_NOTIMPL; - CMyComPtr archive2 = arc->Archive; - HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); - if (result != S_OK) - throw kUpdateIsNotSupoorted; - } - else - { - RINOK(codecs->CreateOutArchive(formatIndex, outArchive)); - - #ifdef EXTERNAL_CODECS - { - CMyComPtr setCompressCodecsInfo; - outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); - } - } - #endif - } - - if (outArchive == 0) - throw kUpdateIsNotSupoorted; - - NFileTimeType::EEnum fileTimeType; - { - UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); - - switch (value) - { - case NFileTimeType::kWindows: - case NFileTimeType::kUnix: - case NFileTimeType::kDOS: - fileTimeType = (NFileTimeType::EEnum)value; - break; - default: - return E_FAIL; - } - } - - { - const CArcInfoEx &arcInfo = codecs->Formats[formatIndex]; - if (options.AltStreams.Val && !arcInfo.Flags_AltStreams()) - return E_NOTIMPL; - if (options.NtSecurity.Val && !arcInfo.Flags_NtSecure()) - return E_NOTIMPL; - } - - CRecordVector updatePairs2; - - UStringVector newNames; - - if (options.RenamePairs.Size() != 0) - { - FOR_VECTOR (i, arcItems) - { - const CArcItem &ai = arcItems[i]; - bool needRename = false; - UString dest; - - if (ai.Censored) - { - FOR_VECTOR (j, options.RenamePairs) - { - const CRenamePair &rp = options.RenamePairs[j]; - if (rp.GetNewPath(ai.IsDir, ai.Name, dest)) - { - needRename = true; - break; - } - - #ifdef SUPPORT_ALT_STREAMS - if (ai.IsAltStream) - { - int colonPos = FindAltStreamColon_in_Path(ai.Name); - if (colonPos >= 0) - { - UString mainName = ai.Name.Left(colonPos); - /* - actually we must improve that code to support cases - with folder renaming like: rn arc dir1\ dir2\ - */ - if (rp.GetNewPath(false, mainName, dest)) - { - needRename = true; - dest += L':'; - dest += ai.Name.Ptr(colonPos + 1); - break; - } - } - } - #endif - } - } - - CUpdatePair2 up2; - up2.SetAs_NoChangeArcItem(ai.IndexInServer); - if (needRename) - { - up2.NewProps = true; - RINOK(arc->IsItemAnti(i, up2.IsAnti)); - up2.NewNameIndex = newNames.Add(dest); - } - updatePairs2.Add(up2); - } - } - else - { - CRecordVector updatePairs; - GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!! - CUpdateProduceCallbackImp upCallback(&arcItems, callback); - - UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL); - } - - { - UInt32 numItems = 0; - FOR_VECTOR (i, updatePairs2) - if (updatePairs2[i].NewData) - numItems++; - RINOK(callback->SetNumItems(numItems)); - } - - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - updateCallbackSpec->ShareForWrite = options.OpenShareForWrite; - updateCallbackSpec->StdInMode = options.StdInMode; - updateCallbackSpec->Callback = callback; - - if (arc) - { - // we set Archive to allow to transfer GetProperty requests back to DLL. - updateCallbackSpec->Archive = arc->Archive; - } - - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->ParentDirItem = parentDirItem; - - updateCallbackSpec->StoreNtSecurity = options.NtSecurity.Val; - updateCallbackSpec->StoreHardLinks = options.HardLinks.Val; - updateCallbackSpec->StoreSymLinks = options.SymLinks.Val; - - updateCallbackSpec->Arc = arc; - updateCallbackSpec->ArcItems = &arcItems; - updateCallbackSpec->UpdatePairs = &updatePairs2; - - updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses; - - if (options.RenamePairs.Size() != 0) - updateCallbackSpec->NewNames = &newNames; - - CMyComPtr outSeekStream; - CMyComPtr outStream; - - if (!options.StdOutMode) - { - FString dirPrefix; - if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix)) - throw 1417161; - CreateComplexDir(dirPrefix); - } - - COutFileStream *outStreamSpec = NULL; - CStdOutFileStream *stdOutFileStreamSpec = NULL; - COutMultiVolStream *volStreamSpec = NULL; - - if (options.VolumesSizes.Size() == 0) - { - if (options.StdOutMode) - { - stdOutFileStreamSpec = new CStdOutFileStream; - outStream = stdOutFileStreamSpec; - } - else - { - outStreamSpec = new COutFileStream; - outSeekStream = outStreamSpec; - outStream = outSeekStream; - bool isOK = false; - FString realPath; - - for (unsigned i = 0; i < (1 << 16); i++) - { - if (archivePath.Temp) - { - if (i > 0) - { - FChar s[16]; - ConvertUInt32ToString(i, s); - archivePath.TempPostfix = s; - } - realPath = archivePath.GetTempPath(); - } - else - realPath = us2fs(archivePath.GetFinalPath()); - if (outStreamSpec->Create(realPath, false)) - { - tempFiles.Paths.Add(realPath); - isOK = true; - break; - } - if (::GetLastError() != ERROR_FILE_EXISTS) - break; - if (!archivePath.Temp) - break; - } - - if (!isOK) - return errorInfo.SetFromLastError("cannot open file", realPath); - } - } - else - { - if (options.StdOutMode) - return E_FAIL; - if (arc && arc->GetGlobalOffset() > 0) - return E_NOTIMPL; - - volStreamSpec = new COutMultiVolStream; - outSeekStream = volStreamSpec; - outStream = outSeekStream; - volStreamSpec->Sizes = options.VolumesSizes; - volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); - volStreamSpec->Prefix += FTEXT('.'); - volStreamSpec->TempFiles = &tempFiles; - volStreamSpec->Init(); - - /* - updateCallbackSpec->VolumesSizes = volumesSizes; - updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; - if (!archivePath.VolExtension.IsEmpty()) - updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; - */ - } - - RINOK(SetProperties(outArchive, options.MethodMode.Properties)); - - if (options.SfxMode) - { - CInFileStream *sfxStreamSpec = new CInFileStream; - CMyComPtr sfxStream(sfxStreamSpec); - if (!sfxStreamSpec->Open(options.SfxModule)) - return errorInfo.SetFromLastError("cannot open SFX module", options.SfxModule); - - CMyComPtr sfxOutStream; - COutFileStream *outStreamSpec2 = NULL; - if (options.VolumesSizes.Size() == 0) - sfxOutStream = outStream; - else - { - outStreamSpec2 = new COutFileStream; - sfxOutStream = outStreamSpec2; - FString realPath = us2fs(archivePath.GetFinalPath()); - if (!outStreamSpec2->Create(realPath, false)) - return errorInfo.SetFromLastError("cannot open file", realPath); - } - - { - UInt64 sfxSize; - RINOK(sfxStreamSpec->GetSize(&sfxSize)); - RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)); - } - - RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)); - - if (outStreamSpec2) - { - RINOK(outStreamSpec2->Close()); - } - } - - CMyComPtr tailStream; - - if (options.SfxMode || !arc || arc->ArcStreamOffset == 0) - tailStream = outStream; - else - { - // Int64 globalOffset = arc->GetGlobalOffset(); - RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)); - if (options.StdOutMode) - tailStream = outStream; - else - { - CTailOutStream *tailStreamSpec = new CTailOutStream; - tailStream = tailStreamSpec; - tailStreamSpec->Stream = outSeekStream; - tailStreamSpec->Offset = arc->ArcStreamOffset; - tailStreamSpec->Init(); - } - } - - - HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); - // callback->Finalize(); - RINOK(result); - - if (!updateCallbackSpec->AreAllFilesClosed()) - { - errorInfo.Message = "There are unclosed input file:"; - errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths; - return E_FAIL; - } - - if (options.SetArcMTime) - { - FILETIME ft; - ft.dwLowDateTime = 0; - ft.dwHighDateTime = 0; - FOR_VECTOR (i, updatePairs2) - { - CUpdatePair2 &pair2 = updatePairs2[i]; - const FILETIME *ft2 = NULL; - if (pair2.NewProps && pair2.DirIndex >= 0) - ft2 = &dirItems.Items[pair2.DirIndex].MTime; - else if (pair2.UseArcProps && pair2.ArcIndex >= 0) - ft2 = &arcItems[pair2.ArcIndex].MTime; - if (ft2) - { - if (::CompareFileTime(&ft, ft2) < 0) - ft = *ft2; - } - } - if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) - { - if (outStreamSpec) - outStreamSpec->SetMTime(&ft); - else if (volStreamSpec) - volStreamSpec->SetMTime(&ft);; - } - } - - if (callback) - { - UInt64 size = 0; - if (outStreamSpec) - outStreamSpec->GetSize(&size); - else if (stdOutFileStreamSpec) - size = stdOutFileStreamSpec->GetSize(); - else - size = volStreamSpec->GetSize(); - - st.OutArcFileSize = size; - } - - if (outStreamSpec) - result = outStreamSpec->Close(); - else if (volStreamSpec) - result = volStreamSpec->Close(); - return result; -} - -bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); - -static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item) -{ - bool finded = false; - FOR_VECTOR (i, censor.Pairs) - { - bool include; - if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include)) - { - if (!include) - return false; - finded = true; - } - } - return finded; -} - -static HRESULT EnumerateInArchiveItems( - // bool storeStreamsMode, - const NWildcard::CCensor &censor, - const CArc &arc, - CObjectVector &arcItems) -{ - arcItems.Clear(); - UInt32 numItems; - IInArchive *archive = arc.Archive; - RINOK(archive->GetNumberOfItems(&numItems)); - arcItems.ClearAndReserve(numItems); - - CReadArcItem item; - - for (UInt32 i = 0; i < numItems; i++) - { - CArcItem ai; - - RINOK(arc.GetItem(i, item)); - ai.Name = item.Path; - ai.IsDir = item.IsDir; - ai.IsAltStream = - #ifdef SUPPORT_ALT_STREAMS - item.IsAltStream; - #else - false; - #endif - - /* - if (!storeStreamsMode && ai.IsAltStream) - continue; - */ - 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.IndexInServer = i; - arcItems.AddInReserved(ai); - } - return S_OK; -} - -#if defined(_WIN32) && !defined(UNDER_CE) - -#include - -#endif - -struct CRefSortPair -{ - unsigned Len; - unsigned Index; -}; - -#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } - -static int CompareRefSortPair(const CRefSortPair *a1, const CRefSortPair *a2, void *) -{ - RINOZ(-MyCompare(a1->Len, a2->Len)); - return MyCompare(a1->Index, a2->Index); -} - -static unsigned GetNumSlashes(const FChar *s) -{ - for (unsigned numSlashes = 0;;) - { - FChar c = *s++; - if (c == 0) - return numSlashes; - if (IS_PATH_SEPAR(c)) - numSlashes++; - } -} - -#ifdef _WIN32 -void ConvertToLongNames(NWildcard::CCensor &censor); -#endif - -HRESULT UpdateArchive( - CCodecs *codecs, - const CObjectVector &types, - const UString &cmdArcPath2, - NWildcard::CCensor &censor, - CUpdateOptions &options, - CUpdateErrorInfo &errorInfo, - IOpenCallbackUI *openCallback, - IUpdateCallbackUI2 *callback, - bool needSetPath) -{ - if (options.StdOutMode && options.EMailMode) - return E_FAIL; - - if (types.Size() > 1) - return E_NOTIMPL; - - bool renameMode = !options.RenamePairs.IsEmpty(); - if (renameMode) - { - if (options.Commands.Size() != 1) - return E_FAIL; - } - - if (options.DeleteAfterCompressing) - { - if (options.Commands.Size() != 1) - return E_NOTIMPL; - const CActionSet &as = options.Commands[0].ActionSet; - for (int i = 2; i < NPairState::kNumValues; i++) - if (as.StateActions[i] != NPairAction::kCompress) - return E_NOTIMPL; - } - - censor.AddPathsToCensor(options.PathMode); - #ifdef _WIN32 - ConvertToLongNames(censor); - #endif - censor.ExtendExclude(); - - - if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */)) - return E_NOTIMPL; - - if (options.SfxMode) - { - CProperty property; - property.Name.SetFromAscii("rsfx"); - options.MethodMode.Properties.Add(property); - if (options.SfxModule.IsEmpty()) - { - errorInfo.Message = "SFX file is not specified"; - return E_FAIL; - } - bool found = false; - if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0) - { - const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule; - if (NFind::DoesFileExist(fullName)) - { - options.SfxModule = fullName; - found = true; - } - } - if (!found) - { - if (!NFind::DoesFileExist(options.SfxModule)) - return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule); - } - } - - CArchiveLink arcLink; - - - if (needSetPath) - { - if (!options.InitFormatIndex(codecs, types, cmdArcPath2) || - !options.SetArcPath(codecs, cmdArcPath2)) - return E_NOTIMPL; - } - const UString arcPath = options.ArchivePath.GetFinalPath(); - - if (cmdArcPath2.IsEmpty()) - { - if (options.MethodMode.Type.FormatIndex < 0) - throw "type of archive is not specified"; - } - else - { - NFind::CFileInfo fi; - if (!fi.Find(us2fs(arcPath))) - { - if (renameMode) - throw "can't find archive";; - if (options.MethodMode.Type.FormatIndex < 0) - { - if (!options.SetArcPath(codecs, cmdArcPath2)) - return E_NOTIMPL; - } - } - else - { - if (fi.IsDir()) - throw "there is no such archive"; - if (fi.IsDevice) - return E_NOTIMPL; - if (options.VolumesSizes.Size() > 0) - return E_NOTIMPL; - CObjectVector types2; - // change it. - if (options.MethodMode.Type_Defined) - types2.Add(options.MethodMode.Type); - // We need to set Properties to open archive only in some cases (WIM archives). - - CIntVector excl; - COpenOptions op; - #ifndef _SFX - op.props = &options.MethodMode.Properties; - #endif - op.codecs = codecs; - op.types = &types2; - op.excludedFormats = ! - op.stdInMode = false; - op.stream = NULL; - op.filePath = arcPath; - - RINOK(callback->StartOpenArchive(arcPath)); - - HRESULT result = arcLink.Open3(op, openCallback); - - if (result == E_ABORT) - return result; - - if (result == S_OK && arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - result = S_FALSE; - - HRESULT res2 = callback->OpenResult(codecs, arcLink, arcPath, result); - /* - if (result == S_FALSE) - return E_FAIL; - */ - RINOK(res2); - RINOK(result); - - if (arcLink.VolumePaths.Size() > 1) - { - errorInfo.SystemError = (DWORD)E_NOTIMPL; - errorInfo.Message = "Updating for multivolume archives is not implemented"; - return E_NOTIMPL; - } - - CArc &arc = arcLink.Arcs.Back(); - arc.MTimeDefined = !fi.IsDevice; - arc.MTime = fi.MTime; - - if (arc.ErrorInfo.ThereIsTail) - { - errorInfo.SystemError = (DWORD)E_NOTIMPL; - errorInfo.Message = "There is some data block after the end of the archive"; - return E_NOTIMPL; - } - if (options.MethodMode.Type.FormatIndex < 0) - { - options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex; - if (!options.SetArcPath(codecs, cmdArcPath2)) - return E_NOTIMPL; - } - } - } - - if (options.MethodMode.Type.FormatIndex < 0) - { - options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArcType); - if (options.MethodMode.Type.FormatIndex < 0) - return E_NOTIMPL; - } - - bool thereIsInArchive = arcLink.IsOpen; - if (!thereIsInArchive && renameMode) - return E_FAIL; - - CDirItems dirItems; - dirItems.Callback = callback; - - CDirItem parentDirItem; - CDirItem *parentDirItem_Ptr = NULL; - - /* - FStringVector requestedPaths; - FStringVector *requestedPaths_Ptr = NULL; - if (options.DeleteAfterCompressing) - requestedPaths_Ptr = &requestedPaths; - */ - - if (options.StdInMode) - { - CDirItem di; - di.Name = options.StdInFileName; - di.Size = (UInt64)(Int64)-1; - di.Attrib = 0; - NTime::GetCurUtcFileTime(di.MTime); - di.CTime = di.ATime = di.MTime; - dirItems.Items.Add(di); - } - else - { - bool needScanning = false; - - if (!renameMode) - FOR_VECTOR (i, options.Commands) - if (options.Commands[i].ActionSet.NeedScanning()) - needScanning = true; - - if (needScanning) - { - RINOK(callback->StartScanning()); - - dirItems.SymLinks = options.SymLinks.Val; - - #if defined(_WIN32) && !defined(UNDER_CE) - dirItems.ReadSecure = options.NtSecurity.Val; - #endif - - dirItems.ScanAltStreams = options.AltStreams.Val; - - HRESULT res = EnumerateItems(censor, - options.PathMode, - options.AddPathPrefix, - dirItems); - - if (res != S_OK) - { - if (res != E_ABORT) - errorInfo.Message = "Scanning error"; - return res; - } - - RINOK(callback->FinishScanning(dirItems.Stat)); - - if (censor.Pairs.Size() == 1) - { - NFind::CFileInfo fi; - FString prefix = us2fs(censor.Pairs[0].Prefix); - prefix += FTEXT('.'); - // UString prefix = censor.Pairs[0].Prefix; - /* - if (prefix.Back() == WCHAR_PATH_SEPARATOR) - { - prefix.DeleteBack(); - } - */ - 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_Ptr = &parentDirItem; - - int secureIndex = -1; - #if defined(_WIN32) && !defined(UNDER_CE) - if (options.NtSecurity.Val) - dirItems.AddSecurityItem(prefix, secureIndex); - #endif - parentDirItem.SecureIndex = secureIndex; - - parentDirItem_Ptr = &parentDirItem; - } - } - } - } - - FString tempDirPrefix; - bool usesTempDir = false; - - #ifdef _WIN32 - CTempDir tempDirectory; - if (options.EMailMode && options.EMailRemoveAfter) - { - tempDirectory.Create(kTempFolderPrefix); - tempDirPrefix = tempDirectory.GetPath(); - NormalizeDirPathPrefix(tempDirPrefix); - usesTempDir = true; - } - #endif - - CTempFiles tempFiles; - - bool createTempFile = false; - - if (!options.StdOutMode && options.UpdateArchiveItself) - { - CArchivePath &ap = options.Commands[0].ArchivePath; - ap = options.ArchivePath; - // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) - if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) - { - createTempFile = true; - ap.Temp = true; - if (!options.WorkingDir.IsEmpty()) - ap.TempPrefix = options.WorkingDir; - else - ap.TempPrefix = us2fs(ap.Prefix); - NormalizeDirPathPrefix(ap.TempPrefix); - } - } - - unsigned ci; - - for (ci = 0; ci < options.Commands.Size(); ci++) - { - CArchivePath &ap = options.Commands[ci].ArchivePath; - if (usesTempDir) - { - // Check it - ap.Prefix = fs2us(tempDirPrefix); - // ap.Temp = true; - // ap.TempPrefix = tempDirPrefix; - } - if (!options.StdOutMode && - (ci > 0 || !createTempFile)) - { - const FString path = us2fs(ap.GetFinalPath()); - if (NFind::DoesFileOrDirExist(path)) - { - errorInfo.SystemError = ERROR_FILE_EXISTS; - errorInfo.Message = "The file already exists"; - errorInfo.FileNames.Add(path); - return errorInfo.Get_HRESULT_Error(); - } - } - } - - CObjectVector arcItems; - if (thereIsInArchive) - { - RINOK(EnumerateInArchiveItems( - // options.StoreAltStreams, - censor, arcLink.Arcs.Back(), arcItems)); - } - - /* - FStringVector processedFilePaths; - FStringVector *processedFilePaths_Ptr = NULL; - if (options.DeleteAfterCompressing) - processedFilePaths_Ptr = &processedFilePaths; - */ - - CByteBuffer processedItems; - if (options.DeleteAfterCompressing) - { - unsigned num = dirItems.Items.Size(); - processedItems.Alloc(num); - for (unsigned i = 0; i < num; i++) - processedItems[i] = 0; - } - - /* - #ifndef _NO_CRYPTO - if (arcLink.PasswordWasAsked) - { - // We set password, if open have requested password - RINOK(callback->SetPassword(arcLink.Password)); - } - #endif - */ - - for (ci = 0; ci < options.Commands.Size(); ci++) - { - const CArc *arc = thereIsInArchive ? arcLink.GetArc() : NULL; - CUpdateArchiveCommand &command = options.Commands[ci]; - UString name; - bool isUpdating; - - if (options.StdOutMode) - { - name.SetFromAscii("stdout"); - isUpdating = thereIsInArchive; - } - else - { - name = command.ArchivePath.GetFinalPath(); - isUpdating = (ci == 0 && options.UpdateArchiveItself && thereIsInArchive); - } - - RINOK(callback->StartArchive(name, isUpdating)) - - CFinishArchiveStat st; - - RINOK(Compress(options, - isUpdating, - codecs, - command.ActionSet, - arc, - command.ArchivePath, - arcItems, - options.DeleteAfterCompressing ? (Byte *)processedItems : NULL, - - dirItems, - parentDirItem_Ptr, - - tempFiles, - errorInfo, callback, st)); - - RINOK(callback->FinishArchive(st)); - } - - - if (thereIsInArchive) - { - RINOK(arcLink.Close()); - arcLink.Release(); - } - - tempFiles.Paths.Clear(); - if (createTempFile) - { - try - { - CArchivePath &ap = options.Commands[0].ArchivePath; - const FString &tempPath = ap.GetTempPath(); - - if (thereIsInArchive) - if (!DeleteFileAlways(us2fs(arcPath))) - return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); - - if (!MyMoveFile(tempPath, us2fs(arcPath))) - { - errorInfo.SetFromLastError("cannot move the file", tempPath); - errorInfo.FileNames.Add(us2fs(arcPath)); - return errorInfo.Get_HRESULT_Error(); - } - } - catch(...) - { - throw; - } - } - - - #if defined(_WIN32) && !defined(UNDER_CE) - - if (options.EMailMode) - { - NDLL::CLibrary mapiLib; - if (!mapiLib.Load(FTEXT("Mapi32.dll"))) - { - errorInfo.SetFromLastError("cannot load Mapi32.dll"); - return errorInfo.Get_HRESULT_Error(); - } - - /* - LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); - if (fnSend == 0) - { - errorInfo.SetFromLastError)("7-Zip cannot find MAPISendDocuments function"); - return errorInfo.Get_HRESULT_Error(); - } - */ - - LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)mapiLib.GetProc("MAPISendMail"); - if (sendMail == 0) - { - errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); - return errorInfo.Get_HRESULT_Error();; - } - - FStringVector fullPaths; - unsigned i; - - for (i = 0; i < options.Commands.Size(); i++) - { - CArchivePath &ap = options.Commands[i].ArchivePath; - FString finalPath = us2fs(ap.GetFinalPath()); - FString arcPath2; - if (!MyGetFullPathName(finalPath, arcPath2)) - return errorInfo.SetFromLastError("GetFullPathName error", finalPath); - fullPaths.Add(arcPath2); - } - - CCurrentDirRestorer curDirRestorer; - - for (i = 0; i < fullPaths.Size(); i++) - { - UString arcPath2 = fs2us(fullPaths[i]); - UString fileName = ExtractFileNameFromPath(arcPath2); - AString path = GetAnsiString(arcPath2); - AString name = GetAnsiString(fileName); - // Warning!!! MAPISendDocuments function changes Current directory - // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); - - MapiFileDesc f; - memset(&f, 0, sizeof(f)); - f.nPosition = 0xFFFFFFFF; - f.lpszPathName = (char *)(const char *)path; - f.lpszFileName = (char *)(const char *)name; - - MapiMessage m; - memset(&m, 0, sizeof(m)); - m.nFileCount = 1; - m.lpFiles = &f; - - const AString addr = GetAnsiString(options.EMailAddress); - MapiRecipDesc rec; - if (!addr.IsEmpty()) - { - memset(&rec, 0, sizeof(rec)); - rec.ulRecipClass = MAPI_TO; - rec.lpszAddress = (char *)(const char *)addr; - m.nRecipCount = 1; - m.lpRecips = &rec; - } - - sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); - } - } - - #endif - - if (options.DeleteAfterCompressing) - { - CRecordVector pairs; - FStringVector foldersNames; - - unsigned i; - - for (i = 0; i < dirItems.Items.Size(); i++) - { - const CDirItem &dirItem = dirItems.Items[i]; - FString phyPath = dirItems.GetPhyPath(i); - if (dirItem.IsDir()) - { - CRefSortPair pair; - pair.Index = i; - pair.Len = GetNumSlashes(phyPath); - pairs.Add(pair); - } - else - { - if (processedItems[i] != 0 || dirItem.Size == 0) - { - RINOK(callback->DeletingAfterArchiving(phyPath, false)); - DeleteFileAlways(phyPath); - } - else - { - // file was skipped - /* - errorInfo.SystemError = 0; - errorInfo.Message = "file was not processed"; - errorInfo.FileName = phyPath; - return E_FAIL; - */ - } - } - } - - pairs.Sort(CompareRefSortPair, NULL); - - for (i = 0; i < pairs.Size(); i++) - { - FString phyPath = dirItems.GetPhyPath(pairs[i].Index); - if (NFind::DoesDirExist(phyPath)) - { - RINOK(callback->DeletingAfterArchiving(phyPath, true)); - RemoveDir(phyPath); - } - } - - RINOK(callback->FinishDeletingAfterArchiving()); - } - - return S_OK; -} +// Update.cpp + +#include "StdAfx.h" + +// #include + +#include "Update.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/TimeUtils.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/LimitedStreams.h" +#include "../../Common/MultiOutStream.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/CopyCoder.h" + +#include "../Common/DirItem.h" +#include "../Common/EnumDirItems.h" +#include "../Common/OpenArchive.h" +#include "../Common/UpdateProduce.h" + +#include "EnumDirItems.h" +#include "SetProperties.h" +#include "TempFiles.h" +#include "UpdateCallback.h" + +static const char * const kUpdateIsNotSupoorted = + "update operations are not supported for this archive"; + +static const char * const kUpdateIsNotSupported_MultiVol = + "Updating for multivolume archives is not implemented"; + +using namespace NWindows; +using namespace NCOM; +using namespace NFile; +using namespace NDir; +using namespace NName; + +#ifdef _WIN32 +static CFSTR const kTempFolderPrefix = FTEXT("7zE"); +#endif + +void CUpdateErrorInfo::SetFromLastError(const char *message) +{ + SystemError = ::GetLastError(); + Message = message; +} + +HRESULT CUpdateErrorInfo::SetFromLastError(const char *message, const FString &fileName) +{ + SetFromLastError(message); + FileNames.Add(fileName); + return Get_HRESULT_Error(); +} + +HRESULT CUpdateErrorInfo::SetFromError_DWORD(const char *message, const FString &fileName, DWORD error) +{ + Message = message; + FileNames.Add(fileName); + SystemError = error; + return Get_HRESULT_Error(); +} + + +using namespace NUpdateArchive; + +struct CMultiOutStream_Rec +{ + CMultiOutStream *Spec; + CMyComPtr Ref; +}; + +struct CMultiOutStream_Bunch +{ + CObjectVector Items; + + HRESULT Destruct() + { + HRESULT hres = S_OK; + FOR_VECTOR (i, Items) + { + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + { + const HRESULT hres2 = rec.Spec->Destruct(); + if (hres == S_OK) + hres = hres2; + } + } + Items.Clear(); + return hres; + } + + void DisableDeletion() + { + FOR_VECTOR (i, Items) + { + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + rec.Spec->NeedDelete = false; + } + } +}; + + +void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) +{ + OriginalPath = path; + + SplitPathToParts_2(path, Prefix, Name); + + if (mode == k_ArcNameMode_Add) + return; + + if (mode != k_ArcNameMode_Exact) + { + int dotPos = Name.ReverseFind_Dot(); + if (dotPos < 0) + return; + if ((unsigned)dotPos == Name.Len() - 1) + Name.DeleteBack(); + else + { + const UString ext = Name.Ptr((unsigned)(dotPos + 1)); + if (BaseExtension.IsEqualTo_NoCase(ext)) + { + BaseExtension = ext; + Name.DeleteFrom((unsigned)dotPos); + return; + } + } + } + + BaseExtension.Empty(); +} + +UString CArchivePath::GetFinalPath() const +{ + UString path = GetPathWithoutExt(); + if (!BaseExtension.IsEmpty()) + { + path.Add_Dot(); + path += BaseExtension; + } + return path; +} + +UString CArchivePath::GetFinalVolPath() const +{ + UString path = GetPathWithoutExt(); + // if BaseExtension is empty, we must ignore VolExtension also. + if (!BaseExtension.IsEmpty()) + { + path.Add_Dot(); + path += VolExtension; + } + return path; +} + +FString CArchivePath::GetTempPath() const +{ + FString path = TempPrefix; + path += us2fs(Name); + if (!BaseExtension.IsEmpty()) + { + path.Add_Dot(); + path += us2fs(BaseExtension); + } + path += ".tmp"; + path += TempPostfix; + return path; +} + +static const char * const kDefaultArcType = "7z"; +static const char * const kDefaultArcExt = "7z"; +static const char * const kSFXExtension = + #ifdef _WIN32 + "exe"; + #else + ""; + #endif + +bool CUpdateOptions::InitFormatIndex(const CCodecs *codecs, + const CObjectVector &types, const UString &arcPath) +{ + if (types.Size() > 1) + return false; + // int arcTypeIndex = -1; + if (types.Size() != 0) + { + MethodMode.Type = types[0]; + MethodMode.Type_Defined = true; + } + if (MethodMode.Type.FormatIndex < 0) + { + // MethodMode.Type = -1; + MethodMode.Type = COpenType(); + if (ArcNameMode != k_ArcNameMode_Add) + { + MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveName(arcPath); + if (MethodMode.Type.FormatIndex >= 0) + MethodMode.Type_Defined = true; + } + } + return true; +} + +bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) +{ + UString typeExt; + int formatIndex = MethodMode.Type.FormatIndex; + if (formatIndex < 0) + { + typeExt = kDefaultArcExt; + } + else + { + const CArcInfoEx &arcInfo = codecs->Formats[(unsigned)formatIndex]; + if (!arcInfo.UpdateEnabled) + return false; + typeExt = arcInfo.GetMainExt(); + } + UString ext = typeExt; + if (SfxMode) + ext = kSFXExtension; + ArchivePath.BaseExtension = ext; + ArchivePath.VolExtension = typeExt; + ArchivePath.ParseFromPath(arcPath, ArcNameMode); + FOR_VECTOR (i, Commands) + { + CUpdateArchiveCommand &uc = Commands[i]; + uc.ArchivePath.BaseExtension = ext; + uc.ArchivePath.VolExtension = typeExt; + uc.ArchivePath.ParseFromPath(uc.UserArchivePath, ArcNameMode); + } + return true; +} + + +struct CUpdateProduceCallbackImp Z7_final: public IUpdateProduceCallback +{ + const CObjectVector *_arcItems; + CDirItemsStat *_stat; + IUpdateCallbackUI *_callback; + + CUpdateProduceCallbackImp( + const CObjectVector *a, + CDirItemsStat *stat, + IUpdateCallbackUI *callback): + _arcItems(a), + _stat(stat), + _callback(callback) {} + + virtual HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; +}; + + +HRESULT CUpdateProduceCallbackImp::ShowDeleteFile(unsigned arcIndex) +{ + const CArcItem &ai = (*_arcItems)[arcIndex]; + { + CDirItemsStat &stat = *_stat; + if (ai.IsDir) + stat.NumDirs++; + else if (ai.IsAltStream) + { + stat.NumAltStreams++; + stat.AltStreamsSize += ai.Size; + } + else + { + stat.NumFiles++; + stat.FilesSize += ai.Size; + } + } + return _callback->ShowDeleteFile(ai.Name, ai.IsDir); +} + +bool CRenamePair::Prepare() +{ + if (RecursedType != NRecursedType::kNonRecursed) + return false; + if (!WildcardParsing) + return true; + return !DoesNameContainWildcard(OldName); +} + +extern bool g_CaseSensitive; + +static unsigned CompareTwoNames(const wchar_t *s1, const wchar_t *s2) +{ + for (unsigned i = 0;; i++) + { + wchar_t c1 = s1[i]; + wchar_t c2 = s2[i]; + if (c1 == 0 || c2 == 0) + return i; + if (c1 == c2) + continue; + if (!g_CaseSensitive && (MyCharUpper(c1) == MyCharUpper(c2))) + continue; + if (IsPathSepar(c1) && IsPathSepar(c2)) + continue; + return i; + } +} + +bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) const +{ + unsigned num = CompareTwoNames(OldName, src); + if (OldName[num] == 0) + { + if (src[num] != 0 && !IsPathSepar(src[num]) && num != 0 && !IsPathSepar(src[num - 1])) + return false; + } + else + { + // OldName[num] != 0 + // OldName = "1\1a.txt" + // src = "1" + + if (!isFolder + || src[num] != 0 + || !IsPathSepar(OldName[num]) + || OldName[num + 1] != 0) + return false; + } + dest = NewName + src.Ptr(num); + return true; +} + +#ifdef SUPPORT_ALT_STREAMS +int FindAltStreamColon_in_Path(const wchar_t *path); +#endif + + + +static HRESULT Compress( + const CUpdateOptions &options, + bool isUpdatingItself, + CCodecs *codecs, + const CActionSet &actionSet, + const CArc *arc, + CArchivePath &archivePath, + const CObjectVector &arcItems, + Byte *processedItemsStatuses, + const CDirItems &dirItems, + const CDirItem *parentDirItem, + CTempFiles &tempFiles, + CMultiOutStream_Bunch &multiStreams, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI *callback, + CFinishArchiveStat &st) +{ + CMyComPtr outArchive; + int formatIndex = options.MethodMode.Type.FormatIndex; + + if (arc) + { + formatIndex = arc->FormatIndex; + if (formatIndex < 0) + return E_NOTIMPL; + CMyComPtr archive2 = arc->Archive; + HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); + if (result != S_OK) + throw kUpdateIsNotSupoorted; + } + else + { + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) + + #ifdef Z7_EXTERNAL_CODECS + { + CMyComPtr setCompressCodecsInfo; + outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); + if (setCompressCodecsInfo) + { + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) + } + } + #endif + } + + 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: + case NFileTimeType::kUnix: + case NFileTimeType::kDOS: + fileTimeType = (NFileTimeType::EEnum)value; + break; + 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_NtSecurity()) + return E_NOTIMPL; + if (options.DeleteAfterCompressing && arcInfo.Flags_HashHandler()) + return E_NOTIMPL; + } + + CRecordVector updatePairs2; + + UStringVector newNames; + + CArcToDoStat stat2; + + if (options.RenameMode || options.RenamePairs.Size() != 0) + { + FOR_VECTOR (i, arcItems) + { + const CArcItem &ai = arcItems[i]; + bool needRename = false; + UString dest; + + if (ai.Censored) + { + FOR_VECTOR (j, options.RenamePairs) + { + const CRenamePair &rp = options.RenamePairs[j]; + if (rp.GetNewPath(ai.IsDir, ai.Name, dest)) + { + needRename = true; + break; + } + + #ifdef SUPPORT_ALT_STREAMS + if (ai.IsAltStream) + { + int colonPos = FindAltStreamColon_in_Path(ai.Name); + if (colonPos >= 0) + { + UString mainName = ai.Name.Left((unsigned)colonPos); + /* + actually we must improve that code to support cases + with folder renaming like: rn arc dir1\ dir2\ + */ + if (rp.GetNewPath(false, mainName, dest)) + { + needRename = true; + dest.Add_Colon(); + dest += ai.Name.Ptr((unsigned)(colonPos + 1)); + break; + } + } + } + #endif + } + } + + CUpdatePair2 up2; + up2.SetAs_NoChangeArcItem(ai.IndexInServer); + if (needRename) + { + up2.NewProps = true; + RINOK(arc->IsItem_Anti(i, up2.IsAnti)) + up2.NewNameIndex = (int)newNames.Add(dest); + } + updatePairs2.Add(up2); + } + } + else + { + CRecordVector updatePairs; + GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!! + CUpdateProduceCallbackImp upCallback(&arcItems, &stat2.DeleteData, callback); + + UpdateProduce(updatePairs, actionSet, updatePairs2, isUpdatingItself ? &upCallback : NULL); + } + + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &up = updatePairs2[i]; + + // 17.01: anti-item is (up.NewData && (p.UseArcProps in most cases)) + + if (up.NewData && !up.UseArcProps) + { + if (up.ExistOnDisk()) + { + CDirItemsStat2 &stat = stat2.NewData; + const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; + if (di.IsDir()) + { + if (up.IsAnti) + stat.Anti_NumDirs++; + else + stat.NumDirs++; + } + #ifdef _WIN32 + else if (di.IsAltStream) + { + if (up.IsAnti) + stat.Anti_NumAltStreams++; + else + { + stat.NumAltStreams++; + stat.AltStreamsSize += di.Size; + } + } + #endif + else + { + if (up.IsAnti) + stat.Anti_NumFiles++; + else + { + stat.NumFiles++; + stat.FilesSize += di.Size; + } + } + } + } + else if (up.ArcIndex >= 0) + { + CDirItemsStat2 &stat = *(up.NewData ? &stat2.NewData : &stat2.OldData); + const CArcItem &ai = arcItems[(unsigned)up.ArcIndex]; + if (ai.IsDir) + { + if (up.IsAnti) + stat.Anti_NumDirs++; + else + stat.NumDirs++; + } + else if (ai.IsAltStream) + { + if (up.IsAnti) + stat.Anti_NumAltStreams++; + else + { + stat.NumAltStreams++; + stat.AltStreamsSize += ai.Size; + } + } + else + { + if (up.IsAnti) + stat.Anti_NumFiles++; + else + { + stat.NumFiles++; + stat.FilesSize += ai.Size; + } + } + } + } + RINOK(callback->SetNumItems(stat2)) + } + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + updateCallbackSpec->PreserveATime = options.PreserveATime; + updateCallbackSpec->ShareForWrite = options.OpenShareForWrite; + updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError; + updateCallbackSpec->StdInMode = options.StdInMode; + updateCallbackSpec->Callback = callback; + + if (arc) + { + // we set Archive to allow to transfer GetProperty requests back to DLL. + updateCallbackSpec->Archive = arc->Archive; + } + + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ParentDirItem = parentDirItem; + + 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; + updateCallbackSpec->UpdatePairs = &updatePairs2; + + updateCallbackSpec->ProcessedItemsStatuses = processedItemsStatuses; + + { + const UString arcPath = archivePath.GetFinalPath(); + updateCallbackSpec->ArcFileName = ExtractFileNameFromPath(arcPath); + } + + if (options.RenamePairs.Size() != 0) + updateCallbackSpec->NewNames = &newNames; + + if (options.SetArcMTime) + { + // updateCallbackSpec->Need_ArcMTime_Report = true; + updateCallbackSpec->Need_LatestMTime = true; + } + + CMyComPtr outSeekStream; + CMyComPtr outStream; + + if (!options.StdOutMode) + { + FString dirPrefix; + if (!GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix)) + throw 1417161; + CreateComplexDir(dirPrefix); + } + + COutFileStream *outStreamSpec = NULL; + CStdOutFileStream *stdOutFileStreamSpec = NULL; + CMultiOutStream *volStreamSpec = NULL; + + if (options.VolumesSizes.Size() == 0) + { + if (options.StdOutMode) + { + stdOutFileStreamSpec = new CStdOutFileStream; + outStream = stdOutFileStreamSpec; + } + else + { + outStreamSpec = new COutFileStream; + outSeekStream = outStreamSpec; + outStream = outSeekStream; + bool isOK = false; + FString realPath; + + for (unsigned i = 0; i < (1 << 16); i++) + { + if (archivePath.Temp) + { + if (i > 0) + { + archivePath.TempPostfix.Empty(); + archivePath.TempPostfix.Add_UInt32(i); + } + realPath = archivePath.GetTempPath(); + } + else + realPath = us2fs(archivePath.GetFinalPath()); + if (outStreamSpec->Create_NEW(realPath)) + { + tempFiles.Paths.Add(realPath); + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + break; + if (!archivePath.Temp) + break; + } + + if (!isOK) + return errorInfo.SetFromLastError("cannot open file", realPath); + } + } + else + { + if (options.StdOutMode) + return E_FAIL; + if (arc && arc->GetGlobalOffset() > 0) + return E_NOTIMPL; + + volStreamSpec = new CMultiOutStream(); + outSeekStream = volStreamSpec; + outStream = outSeekStream; + volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); + volStreamSpec->Prefix.Add_Dot(); + volStreamSpec->Init(options.VolumesSizes); + { + CMultiOutStream_Rec &rec = multiStreams.Items.AddNew(); + rec.Spec = volStreamSpec; + rec.Ref = rec.Spec; + } + + /* + updateCallbackSpec->VolumesSizes = volumesSizes; + updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; + if (!archivePath.VolExtension.IsEmpty()) + updateCallbackSpec->VolExt = UString('.') + archivePath.VolExtension; + */ + } + + if (options.SfxMode) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(options.SfxModule)) + return errorInfo.SetFromLastError("cannot open SFX module", options.SfxModule); + + CMyComPtr sfxOutStream; + COutFileStream *outStreamSpec2 = NULL; + if (options.VolumesSizes.Size() == 0) + sfxOutStream = outStream; + else + { + outStreamSpec2 = new COutFileStream; + sfxOutStream = outStreamSpec2; + const FString realPath = us2fs(archivePath.GetFinalPath()); + if (!outStreamSpec2->Create_NEW(realPath)) + return errorInfo.SetFromLastError("cannot open file", realPath); + } + + { + UInt64 sfxSize; + RINOK(sfxStreamSpec->GetSize(&sfxSize)) + RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)) + } + + RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)) + + if (outStreamSpec2) + { + RINOK(outStreamSpec2->Close()) + } + } + + CMyComPtr tailStream; + + if (options.SfxMode || !arc || arc->ArcStreamOffset == 0) + tailStream = outStream; + else + { + // Int64 globalOffset = arc->GetGlobalOffset(); + RINOK(InStream_SeekToBegin(arc->InStream)) + RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)) + if (options.StdOutMode) + tailStream = outStream; + else + { + CTailOutStream *tailStreamSpec = new CTailOutStream; + tailStream = tailStreamSpec; + tailStreamSpec->Stream = outSeekStream; + tailStreamSpec->Offset = arc->ArcStreamOffset; + tailStreamSpec->Init(); + } + } + + CFiTime ft; + FiTime_Clear(ft); + bool ft_Defined = false; + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &pair2 = updatePairs2[i]; + CFiTime ft2; + FiTime_Clear(ft2); + bool ft2_Defined = false; + /* we use full precision of dirItem, if dirItem is defined + and (dirItem will be used or dirItem is sameTime in dir and arc */ + if (pair2.DirIndex >= 0 && + (pair2.NewProps || pair2.IsSameTime)) + { + ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; + ft2_Defined = true; + } + else if (pair2.UseArcProps && pair2.ArcIndex >= 0) + { + const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; + if (arcItem.MTime.Def) + { + arcItem.MTime.Write_To_FiTime(ft2); + ft2_Defined = true; + } + } + if (ft2_Defined) + { + if (!ft_Defined || Compare_FiTime(&ft, &ft2) < 0) + { + ft = ft2; + ft_Defined = true; + } + } + } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ + } + + if (volStreamSpec && options.SetArcMTime && ft_Defined) + { + volStreamSpec->MTime = ft; + volStreamSpec->MTime_Defined = true; + } + + HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); + // callback->Finalize(); + RINOK(result) + + if (!updateCallbackSpec->AreAllFilesClosed()) + { + errorInfo.Message = "There are unclosed input files:"; + errorInfo.FileNames = updateCallbackSpec->_openFiles_Paths; + return E_FAIL; + } + + if (options.SetArcMTime) + { + // bool needNormalizeAfterStream; + // needParse; + /* + if (updateCallbackSpec->ArcMTime_WasReported) + { + isDefined = updateCallbackSpec->Reported_ArcMTime.Def; + if (isDefined) + updateCallbackSpec->Reported_ArcMTime.Write_To_FiTime(ft); + else + fileTimeType = NFileTimeType::kNotDefined; + } + if (!isDefined) + */ + { + if (updateCallbackSpec->LatestMTime_Defined) + { + // CArcTime at = StreamCallback_ArcMTime; + // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); + // we must normalize with precision from archive; + if (!ft_Defined || Compare_FiTime(&ft, &updateCallbackSpec->LatestMTime) < 0) + ft = updateCallbackSpec->LatestMTime; + ft_Defined = true; + } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ + } + // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) + if (ft_Defined) + { + // we ignore set time errors here. + // note that user could move some finished volumes to another folder. + if (outStreamSpec) + outStreamSpec->SetMTime(&ft); + else if (volStreamSpec) + volStreamSpec->SetMTime_Final(ft); + } + } + + if (callback) + { + UInt64 size = 0; + if (outStreamSpec) + outStreamSpec->GetSize(&size); + else if (stdOutFileStreamSpec) + size = stdOutFileStreamSpec->GetSize(); + else + size = volStreamSpec->GetSize(); + + st.OutArcFileSize = size; + } + + if (outStreamSpec) + result = outStreamSpec->Close(); + else if (volStreamSpec) + { + result = volStreamSpec->FinalFlush_and_CloseFiles(st.NumVolumes); + st.IsMultiVolMode = true; + } + + RINOK(result) + + if (processedItemsStatuses) + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &up = updatePairs2[i]; + if (up.NewData && up.DirIndex >= 0) + { + const CDirItem &di = dirItems.Items[(unsigned)up.DirIndex]; + if (di.AreReparseData() || (!di.IsDir() && di.Size == 0)) + processedItemsStatuses[(unsigned)up.DirIndex] = 1; + } + } + } + + return result; +} + + + +static bool Censor_AreAllAllowed(const NWildcard::CCensor &censor) +{ + if (censor.Pairs.Size() != 1) + return false; + const NWildcard::CPair &pair = censor.Pairs[0]; + /* Censor_CheckPath() ignores (CPair::Prefix). + So we also ignore (CPair::Prefix) here */ + // if (!pair.Prefix.IsEmpty()) return false; + return pair.Head.AreAllAllowed(); +} + +bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include); + +static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item) +{ + bool finded = false; + FOR_VECTOR (i, censor.Pairs) + { + /* (CPair::Prefix) in not used for matching items in archive. + So we ignore (CPair::Prefix) here */ + bool include; + if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include)) + { + // Check it and FIXME !!!! + // here we can exclude item via some Pair, that is still allowed by another Pair + if (!include) + return false; + finded = true; + } + } + return finded; +} + +static HRESULT EnumerateInArchiveItems( + // bool storeStreamsMode, + const NWildcard::CCensor &censor, + const CArc &arc, + CObjectVector &arcItems) +{ + arcItems.Clear(); + UInt32 numItems; + IInArchive *archive = arc.Archive; + RINOK(archive->GetNumberOfItems(&numItems)) + arcItems.ClearAndReserve(numItems); + + CReadArcItem item; + + const bool allFilesAreAllowed = Censor_AreAllAllowed(censor); + + for (UInt32 i = 0; i < numItems; i++) + { + CArcItem ai; + + RINOK(arc.GetItem(i, item)) + ai.Name = item.Path; + ai.IsDir = item.IsDir; + ai.IsAltStream = + #ifdef SUPPORT_ALT_STREAMS + item.IsAltStream; + #else + false; + #endif + + /* + if (!storeStreamsMode && ai.IsAltStream) + continue; + */ + if (allFilesAreAllowed) + ai.Censored = true; + else + ai.Censored = Censor_CheckPath(censor, item); + + // 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); + } + return S_OK; +} + +#if defined(_WIN32) && !defined(UNDER_CE) + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +extern "C" { + +#ifdef MAPI_FORCE_UNICODE + +#define Z7_WIN_LPMAPISENDMAILW LPMAPISENDMAILW +#define Z7_WIN_MapiFileDescW MapiFileDescW +#define Z7_WIN_MapiMessageW MapiMessageW +#define Z7_WIN_MapiRecipDescW MapiRecipDescW + +#else + +typedef struct +{ + ULONG ulReserved; + ULONG ulRecipClass; + PWSTR lpszName; + PWSTR lpszAddress; + ULONG ulEIDSize; + PVOID lpEntryID; +} Z7_WIN_MapiRecipDescW, *Z7_WIN_lpMapiRecipDescW; + +typedef struct +{ + ULONG ulReserved; + ULONG flFlags; + ULONG nPosition; + PWSTR lpszPathName; + PWSTR lpszFileName; + PVOID lpFileType; +} Z7_WIN_MapiFileDescW, *Z7_WIN_lpMapiFileDescW; + +typedef struct +{ + ULONG ulReserved; + PWSTR lpszSubject; + PWSTR lpszNoteText; + PWSTR lpszMessageType; + PWSTR lpszDateReceived; + PWSTR lpszConversationID; + FLAGS flFlags; + Z7_WIN_lpMapiRecipDescW lpOriginator; + ULONG nRecipCount; + Z7_WIN_lpMapiRecipDescW lpRecips; + ULONG nFileCount; + Z7_WIN_lpMapiFileDescW lpFiles; +} Z7_WIN_MapiMessageW, *Z7_WIN_lpMapiMessageW; + +typedef ULONG (FAR PASCAL Z7_WIN_MAPISENDMAILW)( + LHANDLE lhSession, + ULONG_PTR ulUIParam, + Z7_WIN_lpMapiMessageW lpMessage, + FLAGS flFlags, + ULONG ulReserved +); +typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; + +#endif // MAPI_FORCE_UNICODE +} +#endif // _WIN32 + + +struct C_CopyFileProgress_to_IUpdateCallbackUI2 Z7_final: + public ICopyFileProgress +{ + IUpdateCallbackUI2 *Callback; + HRESULT CallbackResult; + // bool Disable_Break; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + const HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // if (Disable_Break && res == E_ABORT) res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_IUpdateCallbackUI2( + IUpdateCallbackUI2 *callback) : + Callback(callback), + CallbackResult(S_OK) + // , Disable_Break(false) + {} +}; + + +HRESULT UpdateArchive( + CCodecs *codecs, + const CObjectVector &types, + const UString &cmdArcPath2, + NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback, + bool needSetPath) +{ + if (options.StdOutMode && options.EMailMode) + return E_FAIL; + + if (types.Size() > 1) + return E_NOTIMPL; + + bool renameMode = !options.RenamePairs.IsEmpty(); + if (renameMode) + { + if (options.Commands.Size() != 1) + return E_FAIL; + } + + if (options.DeleteAfterCompressing) + { + if (options.Commands.Size() != 1) + return E_NOTIMPL; + const CActionSet &as = options.Commands[0].ActionSet; + for (unsigned i = 2; i < NPairState::kNumValues; i++) + if (as.StateActions[i] != NPairAction::kCompress) + return E_NOTIMPL; + } + + censor.AddPathsToCensor(options.PathMode); + #ifdef _WIN32 + ConvertToLongNames(censor); + #endif + censor.ExtendExclude(); + + + if (options.VolumesSizes.Size() > 0 && (options.EMailMode /* || options.SfxMode */)) + return E_NOTIMPL; + + if (options.SfxMode) + { + CProperty property; + property.Name = "rsfx"; + options.MethodMode.Properties.Add(property); + if (options.SfxModule.IsEmpty()) + { + errorInfo.Message = "SFX file is not specified"; + return E_FAIL; + } + bool found = false; + if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0) + { + const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule; + if (NFind::DoesFileExist_FollowLink(fullName)) + { + options.SfxModule = fullName; + found = true; + } + } + if (!found) + { + if (!NFind::DoesFileExist_FollowLink(options.SfxModule)) + return errorInfo.SetFromLastError("cannot find specified SFX module", options.SfxModule); + } + } + + CArchiveLink arcLink; + + + if (needSetPath) + { + if (!options.InitFormatIndex(codecs, types, cmdArcPath2) || + !options.SetArcPath(codecs, cmdArcPath2)) + return E_NOTIMPL; + } + + UString arcPath = options.ArchivePath.GetFinalPath(); + + if (!options.VolumesSizes.IsEmpty()) + { + arcPath = options.ArchivePath.GetFinalVolPath(); + arcPath += ".001"; + } + + if (cmdArcPath2.IsEmpty()) + { + if (options.MethodMode.Type.FormatIndex < 0) + throw "type of archive is not specified"; + } + else + { + NFind::CFileInfo fi; + if (!fi.Find_FollowLink(us2fs(arcPath))) + { + if (renameMode) + throw "can't find archive"; + if (options.MethodMode.Type.FormatIndex < 0) + { + if (!options.SetArcPath(codecs, cmdArcPath2)) + return E_NOTIMPL; + } + } + else + { + if (fi.IsDir()) + return errorInfo.SetFromError_DWORD("There is a folder with the name of archive", + us2fs(arcPath), + #ifdef _WIN32 + ERROR_ACCESS_DENIED + #else + EISDIR + #endif + ); + #ifdef _WIN32 + if (fi.IsDevice) + return E_NOTIMPL; + #endif + + if (!options.StdOutMode && options.UpdateArchiveItself) + if (fi.IsReadOnly()) + { + return errorInfo.SetFromError_DWORD("The file is read-only", + us2fs(arcPath), + #ifdef _WIN32 + ERROR_ACCESS_DENIED + #else + EACCES + #endif + ); + } + + if (options.VolumesSizes.Size() > 0) + { + errorInfo.FileNames.Add(us2fs(arcPath)); + // errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = kUpdateIsNotSupported_MultiVol; + return E_NOTIMPL; + } + CObjectVector types2; + // change it. + if (options.MethodMode.Type_Defined) + types2.Add(options.MethodMode.Type); + // We need to set Properties to open archive only in some cases (WIM archives). + + CIntVector excl; + COpenOptions op; + #ifndef Z7_SFX + op.props = &options.MethodMode.Properties; + #endif + op.codecs = codecs; + op.types = &types2; + op.excludedFormats = ! + op.stdInMode = false; + op.stream = NULL; + op.filePath = arcPath; + + RINOK(callback->StartOpenArchive(arcPath)) + + HRESULT result = arcLink.Open_Strict(op, openCallback); + + if (result == E_ABORT) + return result; + + HRESULT res2 = callback->OpenResult(codecs, arcLink, arcPath, result); + /* + if (result == S_FALSE) + return E_FAIL; + */ + RINOK(res2) + RINOK(result) + + if (arcLink.VolumePaths.Size() > 1) + { + // errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = kUpdateIsNotSupported_MultiVol; + return E_NOTIMPL; + } + + CArc &arc = arcLink.Arcs.Back(); + arc.MTime.Def = + #ifdef _WIN32 + !fi.IsDevice; + #else + true; + #endif + if (arc.MTime.Def) + arc.MTime.Set_From_FiTime(fi.MTime); + + if (arc.ErrorInfo.ThereIsTail) + { + // errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = "There is some data block after the end of the archive"; + return E_NOTIMPL; + } + if (options.MethodMode.Type.FormatIndex < 0) + { + options.MethodMode.Type.FormatIndex = arcLink.GetArc()->FormatIndex; + if (!options.SetArcPath(codecs, cmdArcPath2)) + return E_NOTIMPL; + } + } + } + + if (options.MethodMode.Type.FormatIndex < 0) + { + options.MethodMode.Type.FormatIndex = codecs->FindFormatForArchiveType((UString)kDefaultArcType); + if (options.MethodMode.Type.FormatIndex < 0) + return E_NOTIMPL; + } + + const bool thereIsInArchive = arcLink.IsOpen; + if (!thereIsInArchive && renameMode) + return E_FAIL; + + CDirItems dirItems; + dirItems.Callback = callback; + + CDirItem parentDirItem; + CDirItem *parentDirItem_Ptr = NULL; + + /* + FStringVector requestedPaths; + FStringVector *requestedPaths_Ptr = NULL; + if (options.DeleteAfterCompressing) + requestedPaths_Ptr = &requestedPaths; + */ + + if (options.StdInMode) + { + CDirItem di; + // di.ClearBase(); + // di.Size = (UInt64)(Int64)-1; + if (!di.SetAs_StdInFile()) + return GetLastError_noZero_HRESULT(); + di.Name = options.StdInFileName; + // di.Attrib_IsDefined = false; + // NTime::GetCurUtc_FiTime(di.MTime); + // di.CTime = di.ATime = di.MTime; + dirItems.Items.Add(di); + } + else + { + bool needScanning = false; + + if (!renameMode) + FOR_VECTOR (i, options.Commands) + if (options.Commands[i].ActionSet.NeedScanning()) + needScanning = true; + + if (needScanning) + { + RINOK(callback->StartScanning()) + + dirItems.SymLinks = options.SymLinks.Val; + + #if defined(_WIN32) && !defined(UNDER_CE) + dirItems.ReadSecure = options.NtSecurity.Val; + #endif + + dirItems.ScanAltStreams = options.AltStreams.Val; + dirItems.ExcludeDirItems = censor.ExcludeDirItems; + dirItems.ExcludeFileItems = censor.ExcludeFileItems; + + dirItems.ShareForWrite = options.OpenShareForWrite; + + #ifndef _WIN32 + dirItems.StoreOwnerName = options.StoreOwnerName.Val; + #endif + + const HRESULT res = EnumerateItems(censor, + options.PathMode, + UString(), // options.AddPathPrefix, + dirItems); + + if (res != S_OK) + { + if (res != E_ABORT) + errorInfo.Message = "Scanning error"; + return res; + } + + RINOK(callback->FinishScanning(dirItems.Stat)) + + // 22.00: we don't need parent folder, if absolute path mode + if (options.PathMode != NWildcard::k_AbsPath) + if (censor.Pairs.Size() == 1) + { + NFind::CFileInfo fi; + FString prefix = us2fs(censor.Pairs[0].Prefix); + prefix.Add_Dot(); + // UString prefix = censor.Pairs[0].Prefix; + /* + if (prefix.Back() == WCHAR_PATH_SEPARATOR) + { + prefix.DeleteBack(); + } + */ + if (fi.Find(prefix)) + if (fi.IsDir()) + { + parentDirItem.Copy_From_FileInfoBase(fi); + parentDirItem_Ptr = &parentDirItem; + + int secureIndex = -1; + #if defined(_WIN32) && !defined(UNDER_CE) + if (options.NtSecurity.Val) + dirItems.AddSecurityItem(prefix, secureIndex); + #endif + parentDirItem.SecureIndex = secureIndex; + } + } + } + } + + FString tempDirPrefix; + bool usesTempDir = false; + + #ifdef _WIN32 + CTempDir tempDirectory; + if (options.EMailMode && options.EMailRemoveAfter) + { + tempDirectory.Create(kTempFolderPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NormalizeDirPathPrefix(tempDirPrefix); + usesTempDir = true; + } + #endif + + CTempFiles tempFiles; + + bool createTempFile = false; + + if (!options.StdOutMode && options.UpdateArchiveItself) + { + CArchivePath &ap = options.Commands[0].ArchivePath; + ap = options.ArchivePath; + // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) + if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) + { + createTempFile = true; + ap.Temp = true; + if (!options.WorkingDir.IsEmpty()) + ap.TempPrefix = options.WorkingDir; + else + ap.TempPrefix = us2fs(ap.Prefix); + NormalizeDirPathPrefix(ap.TempPrefix); + } + } + + unsigned ci; + + + // self including protection + if (options.DeleteAfterCompressing) + { + for (ci = 0; ci < options.Commands.Size(); ci++) + { + CArchivePath &ap = options.Commands[ci].ArchivePath; + const FString path = us2fs(ap.GetFinalPath()); + // maybe we must compare absolute paths path here + FOR_VECTOR (i, dirItems.Items) + { + const FString phyPath = dirItems.GetPhyPath(i); + if (phyPath == path) + { + UString s; + s = "It is not allowed to include archive to itself"; + s.Add_LF(); + s += fs2us(path); + throw s; + } + } + } + } + + + for (ci = 0; ci < options.Commands.Size(); ci++) + { + CArchivePath &ap = options.Commands[ci].ArchivePath; + if (usesTempDir) + { + // Check it + ap.Prefix = fs2us(tempDirPrefix); + // ap.Temp = true; + // ap.TempPrefix = tempDirPrefix; + } + if (!options.StdOutMode && + (ci > 0 || !createTempFile)) + { + const FString path = us2fs(ap.GetFinalPath()); + if (NFind::DoesFileOrDirExist(path)) + { + errorInfo.SystemError = ERROR_FILE_EXISTS; + errorInfo.Message = "The file already exists"; + errorInfo.FileNames.Add(path); + return errorInfo.Get_HRESULT_Error(); + } + } + } + + CObjectVector arcItems; + if (thereIsInArchive) + { + RINOK(EnumerateInArchiveItems( + // options.StoreAltStreams, + censor, arcLink.Arcs.Back(), arcItems)) + } + + /* + FStringVector processedFilePaths; + FStringVector *processedFilePaths_Ptr = NULL; + if (options.DeleteAfterCompressing) + processedFilePaths_Ptr = &processedFilePaths; + */ + + CByteBuffer processedItems; + if (options.DeleteAfterCompressing) + { + const unsigned num = dirItems.Items.Size(); + processedItems.Alloc(num); + for (unsigned i = 0; i < num; i++) + processedItems[i] = 0; + } + + CMultiOutStream_Bunch multiStreams; + + /* + #ifndef Z7_NO_CRYPTO + if (arcLink.PasswordWasAsked) + { + // We set password, if open have requested password + RINOK(callback->SetPassword(arcLink.Password)); + } + #endif + */ + + for (ci = 0; ci < options.Commands.Size(); ci++) + { + const CArc *arc = thereIsInArchive ? arcLink.GetArc() : NULL; + CUpdateArchiveCommand &command = options.Commands[ci]; + UString name; + bool isUpdating; + + if (options.StdOutMode) + { + name = "stdout"; + isUpdating = thereIsInArchive; + } + else + { + name = command.ArchivePath.GetFinalPath(); + isUpdating = (ci == 0 && options.UpdateArchiveItself && thereIsInArchive); + } + + RINOK(callback->StartArchive(name, isUpdating)) + + CFinishArchiveStat st; + + RINOK(Compress(options, + isUpdating, + codecs, + command.ActionSet, + arc, + command.ArchivePath, + arcItems, + options.DeleteAfterCompressing ? (Byte *)processedItems : NULL, + + dirItems, + parentDirItem_Ptr, + + tempFiles, + multiStreams, + errorInfo, callback, st)) + + RINOK(callback->FinishArchive(st)) + } + + + if (thereIsInArchive) + { + RINOK(arcLink.Close()) + arcLink.Release(); + } + + multiStreams.DisableDeletion(); + RINOK(multiStreams.Destruct()) + + // here we disable deleting of temp archives. + // note: archive moving can fail, or it can be interrupted, + // if we move new temp update from another volume. + // And we still want to keep temp archive in that case, + // because we will have deleted original archive. + tempFiles.NeedDeleteFiles = false; + // tempFiles.Paths.Clear(); + + if (createTempFile) + { + try + { + CArchivePath &ap = options.Commands[0].ArchivePath; + const FString &tempPath = ap.GetTempPath(); + + // DWORD attrib = 0; + if (thereIsInArchive) + { + // attrib = NFind::GetFileAttrib(us2fs(arcPath)); + if (!DeleteFileAlways(us2fs(arcPath))) + return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); + } + + UInt64 totalArcSize = 0; + { + NFind::CFileInfo fi; + if (fi.Find(tempPath)) + totalArcSize = fi.Size; + } + RINOK(callback->MoveArc_Start(fs2us(tempPath), arcPath, + totalArcSize, BoolToInt(thereIsInArchive))) + + C_CopyFileProgress_to_IUpdateCallbackUI2 prox(callback); + // if we update archive, we have removed original archive. + // So if we break archive moving, we will have only temporary archive. + // We can disable breaking here: + // prox.Disable_Break = thereIsInArchive; + + if (!MyMoveFile_with_Progress(tempPath, us2fs(arcPath), &prox)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = "cannot move the file"; + if (errorInfo.SystemError == ERROR_INVALID_PARAMETER) + { + if (totalArcSize > (UInt32)(Int32)-1) + { + // bool isFsDetected = false; + // if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected) + { + errorInfo.Message.Add_LF(); + errorInfo.Message += "Archive file size exceeds 4 GB"; + } + } + } + // if there was no input archive, and we have operation breaking. + // then we can remove temporary archive, because we still have original uncompressed files. + if (!thereIsInArchive + && prox.CallbackResult == E_ABORT) + tempFiles.NeedDeleteFiles = true; + errorInfo.FileNames.Add(tempPath); + errorInfo.FileNames.Add(us2fs(arcPath)); + RINOK(prox.CallbackResult) + return errorInfo.Get_HRESULT_Error(); + } + + // MoveArc_Finish() can return delayed user break (E_ABORT) status, + // if callback callee ignored interruption to finish archive creation operation. + RINOK(callback->MoveArc_Finish()) + + /* + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) + { + DWORD attrib2 = NFind::GetFileAttrib(us2fs(arcPath)); + if (attrib2 != INVALID_FILE_ATTRIBUTES) + NDir::SetFileAttrib(us2fs(arcPath), attrib2 | FILE_ATTRIBUTE_READONLY); + } + */ + } + catch(...) + { + throw; + } + } + + + #if defined(_WIN32) && !defined(UNDER_CE) + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + + if (options.EMailMode) + { + NDLL::CLibrary mapiLib; + if (!mapiLib.Load(FTEXT("Mapi32.dll"))) + { + errorInfo.SetFromLastError("cannot load Mapi32.dll"); + return errorInfo.Get_HRESULT_Error(); + } + + FStringVector fullPaths; + unsigned i; + + for (i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + const FString finalPath = us2fs(ap.GetFinalPath()); + FString arcPath2; + if (!MyGetFullPathName(finalPath, arcPath2)) + return errorInfo.SetFromLastError("GetFullPathName error", finalPath); + fullPaths.Add(arcPath2); + } + + /* + LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); + if (fnSend == 0) + { + errorInfo.SetFromLastError)("7-Zip cannot find MAPISendDocuments function"); + return errorInfo.Get_HRESULT_Error(); + } + */ + const + Z7_WIN_LPMAPISENDMAILW sendMailW = Z7_GET_PROC_ADDRESS( + Z7_WIN_LPMAPISENDMAILW, mapiLib.Get_HMODULE(), + "MAPISendMailW"); + if (sendMailW) + { + + CCurrentDirRestorer curDirRestorer; + + UStringVector paths; + UStringVector names; + + for (i = 0; i < fullPaths.Size(); i++) + { + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(arcPath2); + names.Add(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } + + CRecordVector files; + files.ClearAndSetSize(paths.Size()); + + for (i = 0; i < paths.Size(); i++) + { + Z7_WIN_MapiFileDescW &f = files[i]; + memset(&f, 0, sizeof(f)); + f.nPosition = 0xFFFFFFFF; + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { + Z7_WIN_MapiMessageW m; + memset(&m, 0, sizeof(m)); + m.nFileCount = files.Size(); + m.lpFiles = files.NonConstData(); + + const UString addr (options.EMailAddress); + Z7_WIN_MapiRecipDescW rec; + if (!addr.IsEmpty()) + { + memset(&rec, 0, sizeof(rec)); + rec.ulRecipClass = MAPI_TO; + rec.lpszAddress = addr.Ptr_non_const(); + m.nRecipCount = 1; + m.lpRecips = &rec; + } + + sendMailW((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); + } + } + else + { + const + LPMAPISENDMAIL sendMail = Z7_GET_PROC_ADDRESS( + LPMAPISENDMAIL, mapiLib.Get_HMODULE(), + "MAPISendMail"); + if (!sendMail) + { + errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); + return errorInfo.Get_HRESULT_Error(); + } + + CCurrentDirRestorer curDirRestorer; + + AStringVector paths; + AStringVector names; + + for (i = 0; i < fullPaths.Size(); i++) + { + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(GetAnsiString(arcPath2)); + names.Add(GetAnsiString(fileName)); + // const AString path (GetAnsiString(arcPath2)); + // const AString name (GetAnsiString(fileName)); + // Warning!!! MAPISendDocuments function changes Current directory + // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } + + CRecordVector files; + files.ClearAndSetSize(paths.Size()); + + for (i = 0; i < paths.Size(); i++) + { + MapiFileDesc &f = files[i]; + memset(&f, 0, sizeof(f)); + f.nPosition = 0xFFFFFFFF; + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { + MapiMessage m; + memset(&m, 0, sizeof(m)); + m.nFileCount = files.Size(); + m.lpFiles = files.NonConstData(); + + const AString addr (GetAnsiString(options.EMailAddress)); + MapiRecipDesc rec; + if (!addr.IsEmpty()) + { + memset(&rec, 0, sizeof(rec)); + rec.ulRecipClass = MAPI_TO; + rec.lpszAddress = addr.Ptr_non_const(); + m.nRecipCount = 1; + m.lpRecips = &rec; + } + + sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); + } + } + } + + #endif + + if (options.DeleteAfterCompressing) + { + CRecordVector pairs; + FStringVector foldersNames; + + unsigned i; + + for (i = 0; i < dirItems.Items.Size(); i++) + { + const CDirItem &dirItem = dirItems.Items[i]; + const FString phyPath = dirItems.GetPhyPath(i); + if (dirItem.IsDir()) + { + CDirPathSortPair pair; + pair.Index = i; + pair.SetNumSlashes(phyPath); + pairs.Add(pair); + } + else + { + // 21.04: we have set processedItems[*] before for all required items + if (processedItems[i] != 0 + // || dirItem.Size == 0 + // || dirItem.AreReparseData() + ) + { + NFind::CFileInfo fileInfo; + /* if (!SymLinks), we follow link here, similar to (dirItem) filling */ + if (fileInfo.Find(phyPath, !options.SymLinks.Val)) + { + bool is_SameSize = false; + if (options.SymLinks.Val && dirItem.AreReparseData()) + { + /* (dirItem.Size = dirItem.ReparseData.Size()) was set before. + So we don't compare sizes for that case here */ + is_SameSize = fileInfo.IsOsSymLink(); + } + else + is_SameSize = (fileInfo.Size == dirItem.Size); + + if (is_SameSize + && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 + && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) + { + RINOK(callback->DeletingAfterArchiving(phyPath, false)) + DeleteFileAlways(phyPath); + } + } + } + else + { + // file was skipped by some reason. We can throw error for debug: + /* + errorInfo.SystemError = 0; + errorInfo.Message = "file was not processed"; + errorInfo.FileNames.Add(phyPath); + return E_FAIL; + */ + } + } + } + + pairs.Sort2(); + + for (i = 0; i < pairs.Size(); i++) + { + const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); + if (NFind::DoesDirExist(phyPath)) + { + RINOK(callback->DeletingAfterArchiving(phyPath, true)) + RemoveDirAlways_if_Empty(phyPath); + } + } + + RINOK(callback->FinishDeletingAfterArchiving()) + } + + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/Update.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/Update.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/Update.h 2024-12-30 13:00:00.000000000 +0000 @@ -1,198 +1,221 @@ -// Update.h - -#ifndef __COMMON_UPDATE_H -#define __COMMON_UPDATE_H - -#include "../../../Common/Wildcard.h" - -#include "ArchiveOpenCallback.h" -#include "LoadCodecs.h" -#include "OpenArchive.h" -#include "Property.h" -#include "UpdateAction.h" -#include "UpdateCallback.h" - -#include "DirItem.h" - -enum EArcNameMode -{ - k_ArcNameMode_Smart, - k_ArcNameMode_Exact, - k_ArcNameMode_Add, -}; - -struct CArchivePath -{ - UString OriginalPath; - - UString Prefix; // path(folder) prefix including slash - UString Name; // base name - UString BaseExtension; // archive type extension or "exe" extension - UString VolExtension; // archive type extension for volumes - - bool Temp; - FString TempPrefix; // path(folder) for temp location - FString TempPostfix; - - CArchivePath(): Temp(false) {}; - - void ParseFromPath(const UString &path, EArcNameMode mode); - UString GetPathWithoutExt() const { return Prefix + Name; } - UString GetFinalPath() const; - UString GetFinalVolPath() const; - FString GetTempPath() const; -}; - -struct CUpdateArchiveCommand -{ - UString UserArchivePath; - CArchivePath ArchivePath; - NUpdateArchive::CActionSet ActionSet; -}; - -struct CCompressionMethodMode -{ - bool Type_Defined; - COpenType Type; - CObjectVector Properties; - - CCompressionMethodMode(): Type_Defined(false) {} -}; - -namespace NRecursedType { enum EEnum -{ - kRecursed, - kWildcardOnlyRecursed, - kNonRecursed -};} - -struct CRenamePair -{ - UString OldName; - UString NewName; - bool WildcardParsing; - NRecursedType::EEnum RecursedType; - - CRenamePair(): WildcardParsing(true), RecursedType(NRecursedType::kNonRecursed) {} - - bool Prepare(); - bool GetNewPath(bool isFolder, const UString &src, UString &dest) const; -}; - -struct CUpdateOptions -{ - CCompressionMethodMode MethodMode; - - CObjectVector Commands; - bool UpdateArchiveItself; - CArchivePath ArchivePath; - EArcNameMode ArcNameMode; - - bool SfxMode; - FString SfxModule; - - bool OpenShareForWrite; - - bool StdInMode; - UString StdInFileName; - bool StdOutMode; - - bool EMailMode; - bool EMailRemoveAfter; - UString EMailAddress; - - FString WorkingDir; - NWildcard::ECensorPathMode PathMode; - UString AddPathPrefix; - - CBoolPair NtSecurity; - CBoolPair AltStreams; - CBoolPair HardLinks; - CBoolPair SymLinks; - - bool DeleteAfterCompressing; - - bool SetArcMTime; - - CObjectVector RenamePairs; - - bool InitFormatIndex(const CCodecs *codecs, const CObjectVector &types, const UString &arcPath); - bool SetArcPath(const CCodecs *codecs, const UString &arcPath); - - CUpdateOptions(): - UpdateArchiveItself(true), - SfxMode(false), - StdInMode(false), - StdOutMode(false), - EMailMode(false), - EMailRemoveAfter(false), - OpenShareForWrite(false), - ArcNameMode(k_ArcNameMode_Smart), - PathMode(NWildcard::k_RelatPath), - - DeleteAfterCompressing(false), - SetArcMTime(false) - - {}; - - void SetActionCommand_Add() - { - Commands.Clear(); - CUpdateArchiveCommand c; - c.ActionSet = NUpdateArchive::k_ActionSet_Add; - Commands.Add(c); - } - - CRecordVector VolumesSizes; -}; - -struct CUpdateErrorInfo -{ - DWORD SystemError; - AString Message; - FStringVector FileNames; - - bool ThereIsError() const { return SystemError != 0 || !Message.IsEmpty() || !FileNames.IsEmpty(); } - HRESULT Get_HRESULT_Error() const { return SystemError == 0 ? E_FAIL : HRESULT_FROM_WIN32(SystemError); } - void SetFromLastError(const char *message); - HRESULT SetFromLastError(const char *message, const FString &fileName); - - CUpdateErrorInfo(): SystemError(0) {}; -}; - -struct CFinishArchiveStat -{ - UInt64 OutArcFileSize; - - CFinishArchiveStat(): OutArcFileSize(0) {} -}; - -#define INTERFACE_IUpdateCallbackUI2(x) \ - INTERFACE_IUpdateCallbackUI(x) \ - INTERFACE_IDirItemsCallback(x) \ - virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x; \ - virtual HRESULT StartScanning() x; \ - virtual HRESULT FinishScanning(const CDirItemsStat &st) x; \ - virtual HRESULT StartOpenArchive(const wchar_t *name) x; \ - virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \ - virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x; \ - virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x; \ - virtual HRESULT FinishDeletingAfterArchiving() x; \ - -struct IUpdateCallbackUI2: public IUpdateCallbackUI, public IDirItemsCallback -{ - INTERFACE_IUpdateCallbackUI2(=0) -}; - -HRESULT UpdateArchive( - CCodecs *codecs, - const CObjectVector &types, - const UString &cmdArcPath2, - NWildcard::CCensor &censor, - CUpdateOptions &options, - CUpdateErrorInfo &errorInfo, - IOpenCallbackUI *openCallback, - IUpdateCallbackUI2 *callback, - bool needSetPath); - -#endif +// Update.h + +#ifndef ZIP7_INC_COMMON_UPDATE_H +#define ZIP7_INC_COMMON_UPDATE_H + +#include "../../../Common/Wildcard.h" + +#include "ArchiveOpenCallback.h" +#include "LoadCodecs.h" +#include "OpenArchive.h" +#include "Property.h" +#include "UpdateAction.h" +#include "UpdateCallback.h" + +enum EArcNameMode +{ + k_ArcNameMode_Smart, + k_ArcNameMode_Exact, + k_ArcNameMode_Add +}; + +struct CArchivePath +{ + UString OriginalPath; + + UString Prefix; // path(folder) prefix including slash + UString Name; // base name + UString BaseExtension; // archive type extension or "exe" extension + UString VolExtension; // archive type extension for volumes + + bool Temp; + FString TempPrefix; // path(folder) for temp location + FString TempPostfix; + + CArchivePath(): Temp(false) {} + + void ParseFromPath(const UString &path, EArcNameMode mode); + UString GetPathWithoutExt() const { return Prefix + Name; } + UString GetFinalPath() const; + UString GetFinalVolPath() const; + FString GetTempPath() const; +}; + +struct CUpdateArchiveCommand +{ + UString UserArchivePath; + CArchivePath ArchivePath; + NUpdateArchive::CActionSet ActionSet; +}; + +struct CCompressionMethodMode +{ + bool Type_Defined; + COpenType Type; + CObjectVector Properties; + + CCompressionMethodMode(): Type_Defined(false) {} +}; + +namespace NRecursedType { enum EEnum +{ + kRecursed, + kWildcardOnlyRecursed, + kNonRecursed +};} + +struct CRenamePair +{ + UString OldName; + UString NewName; + bool WildcardParsing; + NRecursedType::EEnum RecursedType; + + CRenamePair(): WildcardParsing(true), RecursedType(NRecursedType::kNonRecursed) {} + + bool Prepare(); + bool GetNewPath(bool isFolder, const UString &src, UString &dest) const; +}; + +struct CUpdateOptions +{ + bool UpdateArchiveItself; + bool SfxMode; + + bool PreserveATime; + bool OpenShareForWrite; + bool StopAfterOpenError; + + bool StdInMode; + bool StdOutMode; + + bool EMailMode; + bool EMailRemoveAfter; + + bool DeleteAfterCompressing; + bool SetArcMTime; + bool RenameMode; + + CBoolPair NtSecurity; + CBoolPair AltStreams; + CBoolPair HardLinks; + CBoolPair SymLinks; + + CBoolPair StoreOwnerId; + CBoolPair StoreOwnerName; + + EArcNameMode ArcNameMode; + NWildcard::ECensorPathMode PathMode; + + CCompressionMethodMode MethodMode; + + CObjectVector Commands; + CArchivePath ArchivePath; + + FString SfxModule; + UString StdInFileName; + UString EMailAddress; + FString WorkingDir; + // UString AddPathPrefix; + + CObjectVector RenamePairs; + CRecordVector VolumesSizes; + + bool InitFormatIndex(const CCodecs *codecs, const CObjectVector &types, const UString &arcPath); + bool SetArcPath(const CCodecs *codecs, const UString &arcPath); + + CUpdateOptions(): + UpdateArchiveItself(true), + SfxMode(false), + + PreserveATime(false), + OpenShareForWrite(false), + StopAfterOpenError(false), + + StdInMode(false), + StdOutMode(false), + + EMailMode(false), + EMailRemoveAfter(false), + + DeleteAfterCompressing(false), + SetArcMTime(false), + RenameMode(false), + + ArcNameMode(k_ArcNameMode_Smart), + PathMode(NWildcard::k_RelatPath) + + {} + + void SetActionCommand_Add() + { + Commands.Clear(); + CUpdateArchiveCommand c; + c.ActionSet = NUpdateArchive::k_ActionSet_Add; + Commands.Add(c); + } +}; + + +struct CUpdateErrorInfo +{ + DWORD SystemError; // it's DWORD (WRes) only; + AString Message; + FStringVector FileNames; + + bool ThereIsError() const { return SystemError != 0 || !Message.IsEmpty() || !FileNames.IsEmpty(); } + HRESULT Get_HRESULT_Error() const { return SystemError == 0 ? E_FAIL : HRESULT_FROM_WIN32(SystemError); } + void SetFromLastError(const char *message); + HRESULT SetFromLastError(const char *message, const FString &fileName); + HRESULT SetFromError_DWORD(const char *message, const FString &fileName, DWORD error); + + CUpdateErrorInfo(): SystemError(0) {} +}; + +struct CFinishArchiveStat +{ + UInt64 OutArcFileSize; + unsigned NumVolumes; + bool IsMultiVolMode; + + CFinishArchiveStat(): OutArcFileSize(0), NumVolumes(0), IsMultiVolMode(false) {} +}; + +Z7_PURE_INTERFACES_BEGIN + +// INTERFACE_IUpdateCallbackUI(x) +// INTERFACE_IDirItemsCallback(x) + +#define Z7_IFACEN_IUpdateCallbackUI2(x) \ + virtual HRESULT OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) x \ + virtual HRESULT StartScanning() x \ + virtual HRESULT FinishScanning(const CDirItemsStat &st) x \ + virtual HRESULT StartOpenArchive(const wchar_t *name) x \ + virtual HRESULT StartArchive(const wchar_t *name, bool updating) x \ + virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \ + virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \ + virtual HRESULT FinishDeletingAfterArchiving() x \ + virtual HRESULT MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode) x \ + virtual HRESULT MoveArc_Progress(UInt64 total, UInt64 current) x \ + virtual HRESULT MoveArc_Finish() x \ + +DECLARE_INTERFACE(IUpdateCallbackUI2): + public IUpdateCallbackUI, + public IDirItemsCallback +{ + Z7_IFACE_PURE(IUpdateCallbackUI2) +}; +Z7_PURE_INTERFACES_END + +HRESULT UpdateArchive( + CCodecs *codecs, + const CObjectVector &types, + const UString &cmdArcPath2, + NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback, + bool needSetPath); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateAction.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateAction.cpp 2014-12-21 12:44:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.cpp 2014-04-30 12:34:30.000000000 +0000 @@ -1,64 +1,64 @@ -// UpdateAction.cpp - -#include "StdAfx.h" - -#include "UpdateAction.h" - -namespace NUpdateArchive { - -const CActionSet k_ActionSet_Add = -{{ - NPairAction::kCopy, - NPairAction::kCopy, - NPairAction::kCompress, - NPairAction::kCompress, - NPairAction::kCompress, - NPairAction::kCompress, - NPairAction::kCompress -}}; - -const CActionSet k_ActionSet_Update = -{{ - NPairAction::kCopy, - NPairAction::kCopy, - NPairAction::kCompress, - NPairAction::kCopy, - NPairAction::kCompress, - NPairAction::kCopy, - NPairAction::kCompress -}}; - -const CActionSet k_ActionSet_Fresh = -{{ - NPairAction::kCopy, - NPairAction::kCopy, - NPairAction::kIgnore, - NPairAction::kCopy, - NPairAction::kCompress, - NPairAction::kCopy, - NPairAction::kCompress -}}; - -const CActionSet k_ActionSet_Sync = -{{ - NPairAction::kCopy, - NPairAction::kIgnore, - NPairAction::kCompress, - NPairAction::kCopy, - NPairAction::kCompress, - NPairAction::kCopy, - NPairAction::kCompress, -}}; - -const CActionSet k_ActionSet_Delete = -{{ - NPairAction::kCopy, - NPairAction::kIgnore, - NPairAction::kIgnore, - NPairAction::kIgnore, - NPairAction::kIgnore, - NPairAction::kIgnore, - NPairAction::kIgnore -}}; - -} +// UpdateAction.cpp + +#include "StdAfx.h" + +#include "UpdateAction.h" + +namespace NUpdateArchive { + +const CActionSet k_ActionSet_Add = +{{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress +}}; + +const CActionSet k_ActionSet_Update = +{{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}}; + +const CActionSet k_ActionSet_Fresh = +{{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}}; + +const CActionSet k_ActionSet_Sync = +{{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, +}}; + +const CActionSet k_ActionSet_Delete = +{{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore +}}; + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateAction.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateAction.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateAction.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,66 +1,66 @@ -// UpdateAction.h - -#ifndef __UPDATE_ACTION_H -#define __UPDATE_ACTION_H - -namespace NUpdateArchive { - - namespace NPairState - { - const unsigned kNumValues = 7; - enum EEnum - { - kNotMasked = 0, - kOnlyInArchive, - kOnlyOnDisk, - kNewInArchive, - kOldInArchive, - kSameFiles, - kUnknowNewerFiles - }; - } - - namespace NPairAction - { - enum EEnum - { - kIgnore = 0, - kCopy, - kCompress, - kCompressAsAnti - }; - } - - struct CActionSet - { - NPairAction::EEnum StateActions[NPairState::kNumValues]; - - bool IsEqualTo(const CActionSet &a) const - { - for (unsigned i = 0; i < NPairState::kNumValues; i++) - if (StateActions[i] != a.StateActions[i]) - return false; - return true; - } - - bool NeedScanning() const - { - unsigned i; - for (i = 0; i < NPairState::kNumValues; i++) - if (StateActions[i] == NPairAction::kCompress) - return true; - for (i = 1; i < NPairState::kNumValues; i++) - if (StateActions[i] != NPairAction::kIgnore) - return true; - return false; - } - }; - - extern const CActionSet k_ActionSet_Add; - extern const CActionSet k_ActionSet_Update; - extern const CActionSet k_ActionSet_Fresh; - extern const CActionSet k_ActionSet_Sync; - extern const CActionSet k_ActionSet_Delete; -} - -#endif +// UpdateAction.h + +#ifndef ZIP7_INC_UPDATE_ACTION_H +#define ZIP7_INC_UPDATE_ACTION_H + +namespace NUpdateArchive { + + namespace NPairState + { + const unsigned kNumValues = 7; + enum EEnum + { + kNotMasked = 0, + kOnlyInArchive, + kOnlyOnDisk, + kNewInArchive, + kOldInArchive, + kSameFiles, + kUnknowNewerFiles + }; + } + + namespace NPairAction + { + enum EEnum + { + kIgnore = 0, + kCopy, + kCompress, + kCompressAsAnti + }; + } + + struct CActionSet + { + NPairAction::EEnum StateActions[NPairState::kNumValues]; + + bool IsEqualTo(const CActionSet &a) const + { + for (unsigned i = 0; i < NPairState::kNumValues; i++) + if (StateActions[i] != a.StateActions[i]) + return false; + return true; + } + + bool NeedScanning() const + { + unsigned i; + for (i = 0; i < NPairState::kNumValues; i++) + if (StateActions[i] == NPairAction::kCompress) + return true; + for (i = 1; i < NPairState::kNumValues; i++) + if (StateActions[i] != NPairAction::kIgnore) + return true; + return false; + } + }; + + extern const CActionSet k_ActionSet_Add; + extern const CActionSet k_ActionSet_Update; + extern const CActionSet k_ActionSet_Fresh; + extern const CActionSet k_ActionSet_Sync; + extern const CActionSet k_ActionSet_Delete; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateCallback.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateCallback.cpp 2016-05-20 08:46:33.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.cpp 2025-06-18 12:00:00.000000000 +0000 @@ -1,762 +1,1069 @@ -// UpdateCallback.cpp - -#include "StdAfx.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/Synchronization.h" -#endif - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/Synchronization.h" - -#include "../../Common/StreamObjects.h" - -#include "UpdateCallback.h" - -#if defined(_WIN32) && !defined(UNDER_CE) -#define _USE_SECURITY_CODE -#include "../../../Windows/SecurityUtils.h" -#endif - -using namespace NWindows; -using namespace NFile; - -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection g_CriticalSection; -#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); -#else -#define MT_LOCK -#endif - - -#ifdef _USE_SECURITY_CODE -bool InitLocalPrivileges(); -#endif - -CArchiveUpdateCallback::CArchiveUpdateCallback(): - _hardIndex_From((UInt32)(Int32)-1), - - Callback(NULL), - - DirItems(NULL), - ParentDirItem(NULL), - - Arc(NULL), - ArcItems(NULL), - UpdatePairs(NULL), - NewNames(NULL), - - ShareForWrite(false), - StdInMode(false), - - KeepOriginalItemNames(false), - StoreNtSecurity(false), - StoreHardLinks(false), - StoreSymLinks(false), - - ProcessedItemsStatuses(NULL) -{ - #ifdef _USE_SECURITY_CODE - _saclEnabled = InitLocalPrivileges(); - #endif -} - - -STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) -{ - COM_TRY_BEGIN - return Callback->SetTotal(size); - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) -{ - COM_TRY_BEGIN - return Callback->SetCompleted(completeValue); - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - COM_TRY_BEGIN - return Callback->SetRatioInfo(inSize, outSize); - COM_TRY_END -} - - -/* -static const CStatProp kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsDir, VT_BOOL}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidATime, VT_FILETIME}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidAttrib, VT_UI4}, - { NULL, kpidIsAnti, VT_BOOL} -}; - -STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) -{ - return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator); -} -*/ - -STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, - Int32 *newData, Int32 *newProps, UInt32 *indexInArchive) -{ - COM_TRY_BEGIN - RINOK(Callback->CheckBreak()); - const CUpdatePair2 &up = (*UpdatePairs)[index]; - if (newData) *newData = BoolToInt(up.NewData); - if (newProps) *newProps = BoolToInt(up.NewProps); - if (indexInArchive) - { - *indexInArchive = (UInt32)(Int32)-1; - if (up.ExistInArchive()) - *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer; - } - return S_OK; - 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; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType) -{ - *parentType = NParentType::kDir; - *parent = (UInt32)(Int32)-1; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps) -{ - *numProps = 0; - if (StoreNtSecurity) - *numProps = 1; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) -{ - *name = NULL; - *propID = kpidNtSecure; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID - #ifdef _USE_SECURITY_CODE - propID - #endif - , const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = 0; - *dataSize = 0; - *propType = 0; - if (!StoreNtSecurity) - return S_OK; - #ifdef _USE_SECURITY_CODE - if (propID == kpidNtSecure) - { - if (StdInMode) - return S_OK; - - if (ParentDirItem) - { - if (ParentDirItem->SecureIndex < 0) - return S_OK; - const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex]; - *data = buf; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kRaw; - return S_OK; - } - - if (Arc && Arc->GetRootProps) - return Arc->GetRootProps->GetRootRawProp(propID, data, dataSize, propType); - } - #endif - return S_OK; -} - -// #ifdef _USE_SECURITY_CODE -// #endif - -STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = 0; - *dataSize = 0; - *propType = 0; - - if (propID == kpidNtSecure || - propID == kpidNtReparse) - { - if (StdInMode) - return S_OK; - - const CUpdatePair2 &up = (*UpdatePairs)[index]; - if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps) - return Arc->GetRawProps->GetRawProp( - ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, - propID, data, dataSize, propType); - { - /* - if (!up.NewData) - return E_FAIL; - */ - if (up.IsAnti) - return S_OK; - - #ifndef UNDER_CE - const CDirItem &di = DirItems->Items[up.DirIndex]; - #endif - - #ifdef _USE_SECURITY_CODE - if (propID == kpidNtSecure) - { - if (!StoreNtSecurity) - return S_OK; - if (di.SecureIndex < 0) - return S_OK; - const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex]; - *data = buf; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kRaw; - } - else - #endif - { - // propID == kpidNtReparse - if (!StoreSymLinks) - return S_OK; - #if 0 // #ifndef UNDER_CE - const CByteBuffer *buf = &di.ReparseData2; - if (buf->Size() == 0) - buf = &di.ReparseData; - if (buf->Size() != 0) - { - *data = *buf; - *dataSize = (UInt32)buf->Size(); - *propType = NPropDataType::kRaw; - } - #endif - } - - return S_OK; - } - } - - return S_OK; -} - -#ifndef UNDER_CE - -static UString GetRelativePath(const UString &to, const UString &from) -{ - UStringVector partsTo, partsFrom; - SplitPathToParts(to, partsTo); - SplitPathToParts(from, partsFrom); - - unsigned i; - for (i = 0;; i++) - { - if (i + 1 >= partsFrom.Size() || - i + 1 >= partsTo.Size()) - break; - if (CompareFileNames(partsFrom[i], partsTo[i]) != 0) - break; - } - - if (i == 0) - { - #ifdef _WIN32 - if (NName::IsDrivePath(to) || - NName::IsDrivePath(from)) - return to; - #endif - } - - UString s; - unsigned k; - - for (k = i + 1; k < partsFrom.Size(); k++) - s += L".." WSTRING_PATH_SEPARATOR; - - for (k = i; k < partsTo.Size(); k++) - { - if (k != i) - s.Add_PathSepar(); - s += partsTo[k]; - } - - return s; -} - -#endif - -STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - const CUpdatePair2 &up = (*UpdatePairs)[index]; - NCOM::CPropVariant prop; - - if (up.NewData) - { - /* - if (propID == kpidIsHardLink) - { - prop = _isHardLink; - prop.Detach(value); - return S_OK; - } - */ - if (propID == kpidSymLink) - { - if (index == _hardIndex_From) - { - prop.Detach(value); - return S_OK; - } - if (up.DirIndex >= 0) - { - #if 0 // #ifndef UNDER_CE - const CDirItem &di = DirItems->Items[up.DirIndex]; - // if (di.IsDir()) - { - CReparseAttr attr; - if (attr.Parse(di.ReparseData, di.ReparseData.Size())) - { - UString simpleName = attr.GetPath(); - if (attr.IsRelative()) - prop = simpleName; - else - { - const FString phyPath = DirItems->GetPhyPath(up.DirIndex); - FString fullPath; - if (NDir::MyGetFullPathName(phyPath, fullPath)) - { - prop = GetRelativePath(simpleName, fs2us(fullPath)); - } - } - prop.Detach(value); - return S_OK; - } - } - #endif - } - } - else if (propID == kpidHardLink) - { - if (index == _hardIndex_From) - { - const CKeyKeyValPair &pair = _map[_hardIndex_To]; - const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value]; - prop = DirItems->GetLogPath(up2.DirIndex); - prop.Detach(value); - return S_OK; - } - if (up.DirIndex >= 0) - { - prop.Detach(value); - return S_OK; - } - } - } - - if (up.IsAnti - && propID != kpidIsDir - && propID != kpidPath - && propID != kpidIsAltStream) - { - switch (propID) - { - case kpidSize: prop = (UInt64)0; break; - case kpidIsAnti: prop = true; break; - } - } - else if (propID == kpidPath && up.NewNameIndex >= 0) - prop = (*NewNames)[up.NewNameIndex]; - else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem) - { - // we can generate new ShortName here; - } - else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream))) - && up.ExistInArchive() && Archive) - return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value); - else if (up.ExistOnDisk()) - { - const CDirItem &di = DirItems->Items[up.DirIndex]; - switch (propID) - { - case kpidPath: prop = DirItems->GetLogPath(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 kpidIsAltStream: prop = di.IsAltStream; break; - #if defined(_WIN32) && !defined(UNDER_CE) - // case kpidShortName: prop = di.ShortName; break; - #endif - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection CS; -#endif - -STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode) -{ - COM_TRY_BEGIN - *inStream = NULL; - const CUpdatePair2 &up = (*UpdatePairs)[index]; - if (!up.NewData) - return E_FAIL; - - RINOK(Callback->CheckBreak()); - // RINOK(Callback->Finalize()); - - bool isDir = IsDir(up); - - if (up.IsAnti) - { - UString name; - if (up.ArcIndex >= 0) - name = (*ArcItems)[up.ArcIndex].Name; - else if (up.DirIndex >= 0) - name = DirItems->GetLogPath(up.DirIndex); - RINOK(Callback->GetStream(name, isDir, true, mode)); - - /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file. - so we return empty stream */ - - if (!isDir) - { - CBufInStream *inStreamSpec = new CBufInStream(); - CMyComPtr inStreamLoc = inStreamSpec; - inStreamSpec->Init(NULL, 0); - *inStream = inStreamLoc.Detach(); - } - return S_OK; - } - - RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode)); - - if (isDir) - return S_OK; - - if (StdInMode) - { - if (mode != NUpdateNotifyOp::kAdd && - mode != NUpdateNotifyOp::kUpdate) - return S_OK; - - CStdInFileStream *inStreamSpec = new CStdInFileStream; - CMyComPtr inStreamLoc(inStreamSpec); - *inStream = inStreamLoc.Detach(); - } - else - { - CInFileStream *inStreamSpec = new CInFileStream; - CMyComPtr inStreamLoc(inStreamSpec); - - inStreamSpec->SupportHardLinks = StoreHardLinks; - inStreamSpec->Callback = this; - inStreamSpec->CallbackRef = index; - - const FString path = DirItems->GetPhyPath(up.DirIndex); - _openFiles_Indexes.Add(index); - _openFiles_Paths.Add(path); - - #if defined(_WIN32) && !defined(UNDER_CE) - if (DirItems->Items[up.DirIndex].AreReparseData()) - { - if (!inStreamSpec->File.OpenReparse(path)) - { - return Callback->OpenFileError(path, ::GetLastError()); - } - } - else - #endif - if (!inStreamSpec->OpenShared(path, ShareForWrite)) - { - return Callback->OpenFileError(path, ::GetLastError()); - } - -#ifdef _WIN32 // FIXME - if (StoreHardLinks) - { - CStreamFileProps props; - if (inStreamSpec->GetProps2(&props) == S_OK) - { - if (props.NumLinks > 1) - { - CKeyKeyValPair pair; - pair.Key1 = props.VolID; - pair.Key2 = props.FileID_Low; - pair.Value = index; - unsigned numItems = _map.Size(); - unsigned pairIndex = _map.AddToUniqueSorted2(pair); - if (numItems == _map.Size()) - { - // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex]; - _hardIndex_From = index; - _hardIndex_To = pairIndex; - // we could return NULL as stream, but it's better to return real stream - // return S_OK; - } - } - } - } -#endif - - if (ProcessedItemsStatuses) - { - #ifndef _7ZIP_ST - NSynchronization::CCriticalSectionLock lock(CS); - #endif - ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1; - } - *inStream = inStreamLoc.Detach(); - } - - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 opRes) -{ - COM_TRY_BEGIN - return Callback->SetOperationResult(opRes); - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) -{ - COM_TRY_BEGIN - return GetStream2(index, inStream, - (*UpdatePairs)[index].ArcIndex < 0 ? - NUpdateNotifyOp::kAdd : - NUpdateNotifyOp::kUpdate); - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op) -{ - COM_TRY_BEGIN - - bool isDir = false; - - if (indexType == NArchive::NEventIndexType::kOutArcIndex) - { - UString name; - if (index != (UInt32)(Int32)-1) - { - const CUpdatePair2 &up = (*UpdatePairs)[index]; - if (up.ExistOnDisk()) - { - name = DirItems->GetLogPath(up.DirIndex); - isDir = DirItems->Items[up.DirIndex].IsDir(); - } - } - return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir); - } - - wchar_t temp[16]; - UString s2; - const wchar_t *s = NULL; - - if (indexType == NArchive::NEventIndexType::kInArcIndex) - { - if (index != (UInt32)(Int32)-1) - { - if (ArcItems) - { - const CArcItem &ai = (*ArcItems)[index]; - s = ai.Name; - isDir = ai.IsDir; - } - else if (Arc) - { - RINOK(Arc->GetItemPath(index, s2)); - s = s2; - RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)); - } - } - } - else if (indexType == NArchive::NEventIndexType::kBlockIndex) - { - temp[0] = '#'; - ConvertUInt32ToString(index, temp + 1); - s = temp; - } - - if (!s) - s = L""; - - return Callback->ReportUpdateOpeartion(op, s, isDir); - - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes) -{ - COM_TRY_BEGIN - - bool isEncrypted = false; - wchar_t temp[16]; - UString s2; - const wchar_t *s = NULL; - - if (indexType == NArchive::NEventIndexType::kOutArcIndex) - { - /* - UString name; - if (index != (UInt32)(Int32)-1) - { - const CUpdatePair2 &up = (*UpdatePairs)[index]; - if (up.ExistOnDisk()) - { - s2 = DirItems->GetLogPath(up.DirIndex); - s = s2; - } - } - */ - return E_FAIL; - } - - if (indexType == NArchive::NEventIndexType::kInArcIndex) - { - if (index != (UInt32)(Int32)-1) - { - if (ArcItems) - s = (*ArcItems)[index].Name; - else if (Arc) - { - RINOK(Arc->GetItemPath(index, s2)); - s = s2; - } - if (Archive) - { - RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)); - } - } - } - else if (indexType == NArchive::NEventIndexType::kBlockIndex) - { - temp[0] = '#'; - ConvertUInt32ToString(index, temp + 1); - s = temp; - } - - return Callback->ReportExtractResult(opRes, BoolToInt(isEncrypted), s); - - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) -{ - if (VolumesSizes.Size() == 0) - return S_FALSE; - if (index >= (UInt32)VolumesSizes.Size()) - index = VolumesSizes.Size() - 1; - *size = VolumesSizes[index]; - return S_OK; -} - -STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) -{ - COM_TRY_BEGIN - FChar temp[16]; - ConvertUInt32ToString(index + 1, temp); - FString res = temp; - while (res.Len() < 2) - res.InsertAtFront(FTEXT('0')); - FString fileName = VolName; - fileName += FTEXT('.'); - fileName += res; - fileName += VolExt; - COutFileStream *streamSpec = new COutFileStream; - CMyComPtr streamLoc(streamSpec); - if (!streamSpec->Create(fileName, false)) - return ::GetLastError(); - *volumeStream = streamLoc.Detach(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - COM_TRY_BEGIN - return Callback->CryptoGetTextPassword2(passwordIsDefined, password); - COM_TRY_END -} - -STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - return Callback->CryptoGetTextPassword(password); - COM_TRY_END -} - -HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) -{ -#ifdef _WIN32 // FIXME - if (error == ERROR_LOCK_VIOLATION) - { - MT_LOCK - UInt32 index = (UInt32)val; - FOR_VECTOR(i, _openFiles_Indexes) - { - if (_openFiles_Indexes[i] == index) - { - RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)); - break; - } - } - } -#endif - return HRESULT_FROM_WIN32(error); -} - -void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val) -{ - MT_LOCK - UInt32 index = (UInt32)val; - FOR_VECTOR(i, _openFiles_Indexes) - { - if (_openFiles_Indexes[i] == index) - { - _openFiles_Indexes.Delete(i); - _openFiles_Paths.Delete(i); - return; - } - } - throw 20141125; -} +// UpdateCallback.cpp + +#include "StdAfx.h" + +// #include + +#ifndef _WIN32 +// #include +// #include +// for major()/minor(): +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#else +#include +#endif + +#endif // _WIN32 + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "../../Common/StreamObjects.h" +#include "../../Archive/Common/ItemNameUtils.h" + +#include "UpdateCallback.h" + +#if defined(_WIN32) && !defined(UNDER_CE) +#define Z7_USE_SECURITY_CODE +#include "../../../Windows/SecurityUtils.h" +#endif + +using namespace NWindows; +using namespace NFile; + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + + +#ifdef Z7_USE_SECURITY_CODE +bool InitLocalPrivileges(); +#endif + +CArchiveUpdateCallback::CArchiveUpdateCallback(): + PreserveATime(false), + ShareForWrite(false), + StopAfterOpenError(false), + StdInMode(false), + + KeepOriginalItemNames(false), + StoreNtSecurity(false), + StoreHardLinks(false), + StoreSymLinks(false), + + #ifndef _WIN32 + StoreOwnerId(false), + StoreOwnerName(false), + #endif + + /* + , Need_ArcMTime_Report(false), + , ArcMTime_WasReported(false), + */ + Need_LatestMTime(false), + LatestMTime_Defined(false), + + Callback(NULL), + + DirItems(NULL), + ParentDirItem(NULL), + + Arc(NULL), + ArcItems(NULL), + UpdatePairs(NULL), + NewNames(NULL), + Comment(NULL), + CommentIndex(-1), + + ProcessedItemsStatuses(NULL), + _hardIndex_From((UInt32)(Int32)-1) +{ + #ifdef Z7_USE_SECURITY_CODE + _saclEnabled = InitLocalPrivileges(); + #endif +} + + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 size)) +{ + COM_TRY_BEGIN + return Callback->SetTotal(size); + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)) +{ + COM_TRY_BEGIN + return Callback->SetCompleted(completeValue); + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + COM_TRY_BEGIN + return Callback->SetRatioInfo(inSize, outSize); + COM_TRY_END +} + + +/* +static const CStatProp kProps[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsDir, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidCTime, VT_FILETIME}, + { NULL, kpidATime, VT_FILETIME}, + { NULL, kpidMTime, VT_FILETIME}, + { NULL, kpidAttrib, VT_UI4}, + { NULL, kpidIsAnti, VT_BOOL} +}; + +Z7_COM7F_IMF(CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) +{ + return CStatPropEnumerator::CreateEnumerator(kProps, Z7_ARRAY_SIZE(kProps), enumerator); +} +*/ + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)) +{ + COM_TRY_BEGIN + RINOK(Callback->CheckBreak()) + const CUpdatePair2 &up = (*UpdatePairs)[index]; + if (newData) *newData = BoolToInt(up.NewData); + if (newProps) *newProps = BoolToInt(up.NewProps); + if (indexInArchive) + { + *indexInArchive = (UInt32)(Int32)-1; + if (up.ExistInArchive()) + *indexInArchive = ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex; + } + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->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; + default: break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 0; + if (StoreNtSecurity) + *numProps = 1; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = kpidNtSecure; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootRawProp(PROPID + propID + , const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + #ifndef Z7_USE_SECURITY_CODE + UNUSED_VAR(propID) + #endif + + *data = NULL; + *dataSize = 0; + *propType = 0; + if (!StoreNtSecurity) + return S_OK; + #ifdef Z7_USE_SECURITY_CODE + if (propID == kpidNtSecure) + { + if (StdInMode) + return S_OK; + + if (ParentDirItem) + { + if (ParentDirItem->SecureIndex < 0) + return S_OK; + const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)ParentDirItem->SecureIndex]; + *data = buf; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kRaw; + return S_OK; + } + + if (Arc && Arc->GetRootProps) + return Arc->GetRootProps->GetRootRawProp(propID, data, dataSize, propType); + } + #endif + return S_OK; +} + + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidNtSecure || + propID == kpidNtReparse) + { + if (StdInMode) + return S_OK; + + const CUpdatePair2 &up = (*UpdatePairs)[index]; + if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps) + return Arc->GetRawProps->GetRawProp( + ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, + propID, data, dataSize, propType); + { + /* + if (!up.NewData) + return E_FAIL; + */ + if (up.IsAnti) + return S_OK; + + #if defined(_WIN32) && !defined(UNDER_CE) + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + #endif + + #ifdef Z7_USE_SECURITY_CODE + if (propID == kpidNtSecure) + { + if (!StoreNtSecurity) + return S_OK; + if (di.SecureIndex < 0) + return S_OK; + const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)di.SecureIndex]; + *data = buf; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kRaw; + } + else + #endif + if (propID == kpidNtReparse) + { + if (!StoreSymLinks) + return S_OK; + #if defined(_WIN32) && !defined(UNDER_CE) + // we use ReparseData2 instead of ReparseData for WIM format + const CByteBuffer *buf = &di.ReparseData2; + if (buf->Size() == 0) + buf = &di.ReparseData; + if (buf->Size() != 0) + { + *data = *buf; + *dataSize = (UInt32)buf->Size(); + *propType = NPropDataType::kRaw; + } + #endif + } + + return S_OK; + } + } + + return S_OK; +} + +#if defined(_WIN32) && !defined(UNDER_CE) + +static UString GetRelativePath(const UString &to, const UString &from, bool isWSL) +{ + UStringVector partsTo, partsFrom; + SplitPathToParts(to, partsTo); + SplitPathToParts(from, partsFrom); + + unsigned i; + for (i = 0;; i++) + { + if (i + 1 >= partsFrom.Size() || + i + 1 >= partsTo.Size()) + break; + if (CompareFileNames(partsFrom[i], partsTo[i]) != 0) + break; + } + + if (i == 0) + { +#ifdef _WIN32 + if (isWSL || + (NName::IsDrivePath(to) || + NName::IsDrivePath(from))) + return to; +#endif + } + + UString s; + unsigned k; + + for (k = i + 1; k < partsFrom.Size(); k++) + s += ".." STRING_PATH_SEPARATOR; + + for (k = i; k < partsTo.Size(); k++) + { + if (k != i) + s.Add_PathSepar(); + s += partsTo[k]; + } + + return s; +} + +#endif + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + const CUpdatePair2 &up = (*UpdatePairs)[index]; + NCOM::CPropVariant prop; + + if (up.NewData) + { + /* + if (propID == kpidIsHardLink) + { + prop = _isHardLink; + prop.Detach(value); + return S_OK; + } + */ + if (propID == kpidSymLink) + { + if (index == _hardIndex_From) + { + prop.Detach(value); + return S_OK; + } + +#if !defined(UNDER_CE) + if (up.DirIndex >= 0) + { + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + if (di.ReparseData.Size()) + { +#ifdef _WIN32 + CReparseAttr attr; + if (attr.Parse(di.ReparseData, di.ReparseData.Size())) + { + UString path = attr.GetPath(); + if (!path.IsEmpty()) + { + bool isWSL = attr.IsSymLink_WSL(); + if (isWSL) + NArchive::NItemName::ReplaceToWinSlashes(path, true); // useBackslashReplacement + // it's expected that (path) now uses windows slashes. + // CReparseAttr::IsRelative_Win() returns true if FLAG_RELATIVE is set + // CReparseAttr::IsRelative_Win() returns true for "\dir1\path" + // but we want to store real relative paths without "\" root prefix. + // so we parse path instead of IsRelative_Win() calling. + if (// attr.IsRelative_Win() || + (isWSL ? + IS_PATH_SEPAR(path[0]) : + NName::IsAbsolutePath(path))) + { + // (path) is abolute path or relative to root: "\path" + // we try to convert (path) to relative path for writing to archive. + const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex); + FString fullPath; + if (NDir::MyGetFullPathName(phyPath, fullPath)) + { + if (IS_PATH_SEPAR(path[0]) && + !IS_PATH_SEPAR(path[1])) + { + // path is relative to root of (fullPath): "\path" + const unsigned prefixSize = NName::GetRootPrefixSize(fullPath); + if (prefixSize) + { + path.DeleteFrontal(1); + path.Insert(0, fs2us(fullPath.Left(prefixSize))); + // we have changed "\" prefix to drive prefix "c:\" in (path). + // (path) is Windows path now. + isWSL = false; + } + } + } + path = GetRelativePath(path, fs2us(fullPath), isWSL); + } +#if WCHAR_PATH_SEPARATOR != L'/' + // 7-Zip's TAR handler in Windows replaces windows slashes to linux slashes. + // so we can return any slashes to TAR handler. + // or we can convert to linux slashes here, + // because input IInArchive handler uses linux slashes for kpidSymLink. + // path.Replace(WCHAR_PATH_SEPARATOR, L'/'); +#endif + if (!path.IsEmpty()) + prop = path; + } + } +#else // ! _WIN32 + AString utf; + utf.SetFrom_CalcLen((const char *)(const Byte *)di.ReparseData, (unsigned)di.ReparseData.Size()); + #if 0 // 0 - for debug + // it's expected that link data uses system codepage. + // fs2us() ignores conversion errors. But we want correct path + UString us (fs2us(utf)); + #else + UString us; + if (ConvertUTF8ToUnicode(utf, us)) + #endif + { + if (!us.IsEmpty()) + prop = us; + } +#endif // ! _WIN32 + } + prop.Detach(value); + return S_OK; + } +#endif // !defined(UNDER_CE) + } + else if (propID == kpidHardLink) + { + if (index == _hardIndex_From) + { + const CKeyKeyValPair &pair = _map[_hardIndex_To]; + const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value]; + const UString path = DirItems->GetLogPath((unsigned)up2.DirIndex); +#if WCHAR_PATH_SEPARATOR != L'/' + // 7-Zip's TAR handler in Windows replaces windows slashes to linux slashes. + // path.Replace(WCHAR_PATH_SEPARATOR, L'/'); +#endif + prop = path; + prop.Detach(value); + return S_OK; + } + if (up.DirIndex >= 0) + { + prop.Detach(value); + return S_OK; + } + } + } // if (up.NewData) + + if (up.IsAnti + && propID != kpidIsDir + && propID != kpidPath + && propID != kpidIsAltStream) + { + switch (propID) + { + case kpidSize: prop = (UInt64)0; break; + case kpidIsAnti: prop = true; break; + default: break; + } + } + else if (propID == kpidPath && up.NewNameIndex >= 0) + prop = (*NewNames)[(unsigned)up.NewNameIndex]; + else if (propID == kpidComment + && CommentIndex >= 0 + && (unsigned)CommentIndex == index + && Comment) + prop = *Comment; + else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem) + { + // we can generate new ShortName here; + } + else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream))) + && up.ExistInArchive() && Archive) + return Archive->GetProperty(ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, propID, value); + else if (up.ExistOnDisk()) + { + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + switch (propID) + { + case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break; + case kpidIsDir: prop = di.IsDir(); 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: /* if (di.Attrib_IsDefined) */ prop = (UInt32)di.GetWinAttrib(); break; + case kpidPosixAttrib: /* if (di.Attrib_IsDefined) */ prop = (UInt32)di.GetPosixAttrib(); break; + + #if defined(_WIN32) + case kpidIsAltStream: prop = di.IsAltStream; break; + // case kpidShortName: prop = di.ShortName; break; + #else + + #if defined(__APPLE__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #endif + + case kpidDeviceMajor: + /* + printf("\ndi.mode = %o\n", di.mode); + printf("\nst.st_rdev major = %d\n", (unsigned)major(di.rdev)); + printf("\nst.st_rdev minor = %d\n", (unsigned)minor(di.rdev)); + */ + if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) + prop = (UInt32)major(di.rdev); + break; + + case kpidDeviceMinor: + if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) + prop = (UInt32)minor(di.rdev); + break; + + #if defined(__APPLE__) + #pragma GCC diagnostic pop + #endif + + // case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break; + + case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break; + case kpidGroupId: if (StoreOwnerId) prop = (UInt32)di.gid; break; + case kpidUser: + if (di.OwnerNameIndex >= 0) + prop = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex]; + break; + case kpidGroup: + if (di.OwnerGroupIndex >= 0) + prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex]; + break; + #endif + default: break; + } + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CS; +#endif + +void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex) +{ + if (ProcessedItemsStatuses) + { + #ifndef Z7_ST + NSynchronization::CCriticalSectionLock lock(g_CS); + #endif + ProcessedItemsStatuses[dirIndex] = 1; + } +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)) +{ + COM_TRY_BEGIN + *inStream = NULL; + const CUpdatePair2 &up = (*UpdatePairs)[index]; + if (!up.NewData) + return E_FAIL; + + RINOK(Callback->CheckBreak()) + // RINOK(Callback->Finalize()); + + bool isDir = IsDir(up); + + if (up.IsAnti) + { + UString name; + if (up.ArcIndex >= 0) + name = (*ArcItems)[(unsigned)up.ArcIndex].Name; + else if (up.DirIndex >= 0) + name = DirItems->GetLogPath((unsigned)up.DirIndex); + RINOK(Callback->GetStream(name, isDir, true, mode)) + + /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file. + so we return empty stream */ + + if (!isDir) + { + CBufInStream *inStreamSpec = new CBufInStream(); + CMyComPtr inStreamLoc = inStreamSpec; + inStreamSpec->Init(NULL, 0); + *inStream = inStreamLoc.Detach(); + } + return S_OK; + } + + RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode)) + + if (isDir) + return S_OK; + + if (StdInMode) + { + if (mode != NUpdateNotifyOp::kAdd && + mode != NUpdateNotifyOp::kUpdate) + return S_OK; + +#if 1 + CStdInFileStream *inStreamSpec = new CStdInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); +#else + CMyComPtr inStreamLoc; + if (!CreateStdInStream(inStreamLoc)) + return GetLastError_noZero_HRESULT(); +#endif + *inStream = inStreamLoc.Detach(); + } + else + { + #if !defined(UNDER_CE) + const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex]; + if (di.AreReparseData()) + { + /* + // we still need DeviceIoControlOut() instead of Read + if (!inStreamSpec->File.OpenReparse(path)) + { + return Callback->OpenFileError(path, ::GetLastError()); + } + */ + // 20.03: we use Reparse Data instead of real data + + CBufInStream *inStreamSpec = new CBufInStream(); + CMyComPtr inStreamLoc = inStreamSpec; + inStreamSpec->Init(di.ReparseData, di.ReparseData.Size()); + *inStream = inStreamLoc.Detach(); + + UpdateProcessedItemStatus((unsigned)up.DirIndex); + return S_OK; + } + #endif // !defined(UNDER_CE) + + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr 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; + const bool preserveATime = (PreserveATime + || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass. + inStreamSpec->Set_PreserveATime(preserveATime); + + const FString path = DirItems->GetPhyPath((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 */ + inStreamSpec->Callback = this; + inStreamSpec->CallbackRef = index; + + if (!inStreamSpec->OpenShared(path, ShareForWrite)) + { + bool isOpen = false; + if (preserveATime) + { + inStreamSpec->Set_PreserveATime(false); + isOpen = inStreamSpec->OpenShared(path, ShareForWrite); + } + if (!isOpen) + { + const DWORD error = ::GetLastError(); + const HRESULT hres = Callback->OpenFileError(path, error); + if (hres == S_OK || hres == S_FALSE) + if (StopAfterOpenError || + // v23: we check also for some critical errors: + #ifdef _WIN32 + error == ERROR_NO_SYSTEM_RESOURCES + #else + error == EMFILE + #endif + ) + { + if (error == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(error); + } + return hres; + } + } + + /* + { + // 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(Z7_FILE_STREAMS_USE_WIN_FILE) || !defined(_WIN32) + if (StoreHardLinks) + { + CStreamFileProps props; + if (inStreamSpec->GetProps2(&props) == S_OK) + { + if (props.NumLinks > 1) + { + CKeyKeyValPair pair; + pair.Key1 = props.VolID; + pair.Key2 = props.FileID_Low; + pair.Value = index; + const unsigned numItems = _map.Size(); + const unsigned pairIndex = _map.AddToUniqueSorted2(pair); + if (numItems == _map.Size()) + { + // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex]; + _hardIndex_From = index; + _hardIndex_To = pairIndex; + // we could return NULL as stream, but it's better to return real stream + // return S_OK; + } + } + } + } + // #endif + + UpdateProcessedItemStatus((unsigned)up.DirIndex); + *inStream = inStreamLoc.Detach(); + } + + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 opRes)) +{ + COM_TRY_BEGIN + return Callback->SetOperationResult(opRes); + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)) +{ + COM_TRY_BEGIN + return GetStream2(index, inStream, + (*UpdatePairs)[index].ArcIndex < 0 ? + NUpdateNotifyOp::kAdd : + NUpdateNotifyOp::kUpdate); + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op)) +{ + COM_TRY_BEGIN + + // if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index); + + bool isDir = false; + + if (indexType == NArchive::NEventIndexType::kOutArcIndex) + { + UString name; + if (index != (UInt32)(Int32)-1) + { + const CUpdatePair2 &up = (*UpdatePairs)[index]; + if (up.ExistOnDisk()) + { + name = DirItems->GetLogPath((unsigned)up.DirIndex); + isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir(); + } + } + return Callback->ReportUpdateOperation(op, name.IsEmpty() ? NULL : name.Ptr(), isDir); + } + + wchar_t temp[16]; + UString s2; + const wchar_t *s = NULL; + + if (indexType == NArchive::NEventIndexType::kInArcIndex) + { + if (index != (UInt32)(Int32)-1) + { + if (ArcItems) + { + const CArcItem &ai = (*ArcItems)[index]; + s = ai.Name; + isDir = ai.IsDir; + } + else if (Arc) + { + RINOK(Arc->GetItem_Path(index, s2)) + s = s2; + RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir)) + } + } + } + else if (indexType == NArchive::NEventIndexType::kBlockIndex) + { + temp[0] = '#'; + ConvertUInt32ToString(index, temp + 1); + s = temp; + } + + if (!s) + s = L""; + + return Callback->ReportUpdateOperation(op, s, isDir); + + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)) +{ + COM_TRY_BEGIN + + bool isEncrypted = false; + wchar_t temp[16]; + UString s2; + const wchar_t *s = NULL; + + if (indexType == NArchive::NEventIndexType::kOutArcIndex) + { + /* + UString name; + if (index != (UInt32)(Int32)-1) + { + const CUpdatePair2 &up = (*UpdatePairs)[index]; + if (up.ExistOnDisk()) + { + s2 = DirItems->GetLogPath(up.DirIndex); + s = s2; + } + } + */ + return E_FAIL; + } + + if (indexType == NArchive::NEventIndexType::kInArcIndex) + { + if (index != (UInt32)(Int32)-1) + { + if (ArcItems) + s = (*ArcItems)[index].Name; + else if (Arc) + { + RINOK(Arc->GetItem_Path(index, s2)) + s = s2; + } + if (Archive) + { + RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted)) + } + } + } + else if (indexType == NArchive::NEventIndexType::kBlockIndex) + { + temp[0] = '#'; + ConvertUInt32ToString(index, temp + 1); + s = temp; + } + + return Callback->ReportExtractResult(opRes, BoolToInt(isEncrypted), s); + + COM_TRY_END +} + + +/* +Z7_COM7F_IMF(CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer)) +{ + *answer = 0; + if (Need_ArcMTime_Report && propID == kpidComboMTime) + *answer = 1; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)) +{ + if (indexType == NArchive::NEventIndexType::kArcProp) + { + if (propID == kpidComboMTime) + { + ArcMTime_WasReported = true; + if (value->vt == VT_FILETIME) + { + Reported_ArcMTime.Set_From_Prop(*value); + Reported_ArcMTime.Def = true; + } + else + { + Reported_ArcMTime.Clear(); + if (value->vt != VT_EMPTY) + return E_FAIL; // for debug + } + } + } + return Callback->ReportProp(indexType, index, propID, value); +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index, + PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)) +{ + return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType); +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)) +{ + return Callback->ReportFinished(indexType, index, opRes); +} +*/ + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)) +{ + COM_TRY_BEGIN + char temp[16]; + ConvertUInt32ToString(index + 1, temp); + FString res (temp); + while (res.Len() < 2) + res.InsertAtFront(FTEXT('0')); + FString fileName = VolName; + fileName.Add_Dot(); + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if (!streamSpec->Create_NEW(fileName)) + return GetLastError_noZero_HRESULT(); + *volumeStream = streamLoc.Detach(); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword2(passwordIsDefined, password); + COM_TRY_END +} + +Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword(password); + COM_TRY_END +} + +HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error) +{ + #ifdef _WIN32 // FIX IT !!! + // why did we check only for ERROR_LOCK_VIOLATION ? + // if (error == ERROR_LOCK_VIOLATION) + #endif + { + MT_LOCK + const UInt32 index = (UInt32)val; + FOR_VECTOR(i, _openFiles_Indexes) + { + if (_openFiles_Indexes[i] == index) + { + RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error)) + break; + } + } + } + return HRESULT_FROM_WIN32(error); +} + +void CArchiveUpdateCallback::InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) +{ + MT_LOCK + 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, + we must disable the code below that raises new exception. + */ + // throw 20141125; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateCallback.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateCallback.h 2023-04-06 05:00:00.000000000 +0000 @@ -1,147 +1,197 @@ -// UpdateCallback.h - -#ifndef __UPDATE_CALLBACK_H -#define __UPDATE_CALLBACK_H - -#include "../../../Common/MyCom.h" - -#include "../../Common/FileStreams.h" - -#include "../../IPassword.h" -#include "../../ICoder.h" - -#include "../Common/UpdatePair.h" -#include "../Common/UpdateProduce.h" - -#include "OpenArchive.h" - -#define INTERFACE_IUpdateCallbackUI(x) \ - virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x; \ - virtual HRESULT SetTotal(UInt64 size) x; \ - virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \ - virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \ - virtual HRESULT CheckBreak() x; \ - /* virtual HRESULT Finalize() x; */ \ - virtual HRESULT SetNumItems(UInt64 numItems) x; \ - virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x; \ - virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x; \ - virtual HRESULT SetOperationResult(Int32 opRes) x; \ - virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x; \ - virtual HRESULT ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) x; \ - /* virtual HRESULT SetPassword(const UString &password) x; */ \ - virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \ - virtual HRESULT CryptoGetTextPassword(BSTR *password) x; \ - virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x; \ - /* virtual HRESULT CloseProgress() { return S_OK; } */ - -struct IUpdateCallbackUI -{ - INTERFACE_IUpdateCallbackUI(=0) -}; - -struct CKeyKeyValPair -{ - UInt64 Key1; - UInt64 Key2; - unsigned Value; - - int Compare(const CKeyKeyValPair &a) const - { - if (Key1 < a.Key1) return -1; - if (Key1 > a.Key1) return 1; - return MyCompare(Key2, a.Key2); - } -}; - - -class CArchiveUpdateCallback: - public IArchiveUpdateCallback2, - public IArchiveUpdateCallbackFile, - public IArchiveExtractCallbackMessage, - public IArchiveGetRawProps, - public IArchiveGetRootProps, - public ICryptoGetTextPassword2, - public ICryptoGetTextPassword, - public ICompressProgressInfo, - public IInFileStream_Callback, - public CMyUnknownImp -{ - #if defined(_WIN32) && !defined(UNDER_CE) - bool _saclEnabled; - #endif - CRecordVector _map; - - UInt32 _hardIndex_From; - UInt32 _hardIndex_To; - -public: - MY_QUERYINTERFACE_BEGIN2(IArchiveUpdateCallback2) - MY_QUERYINTERFACE_ENTRY(IArchiveUpdateCallbackFile) - MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRootProps) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword2) - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - INTERFACE_IArchiveUpdateCallback2(;) - INTERFACE_IArchiveUpdateCallbackFile(;) - INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_IArchiveGetRootProps(;) - - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - CRecordVector _openFiles_Indexes; - FStringVector _openFiles_Paths; - - bool AreAllFilesClosed() const { return _openFiles_Indexes.IsEmpty(); } - virtual HRESULT InFileStream_On_Error(UINT_PTR val, DWORD error); - virtual void InFileStream_On_Destroy(UINT_PTR val); - - CRecordVector VolumesSizes; - FString VolName; - FString VolExt; - - IUpdateCallbackUI *Callback; - - const CDirItems *DirItems; - const CDirItem *ParentDirItem; - - const CArc *Arc; - CMyComPtr Archive; - const CObjectVector *ArcItems; - const CRecordVector *UpdatePairs; - const UStringVector *NewNames; - - bool ShareForWrite; - bool StdInMode; - - bool KeepOriginalItemNames; - bool StoreNtSecurity; - bool StoreHardLinks; - bool StoreSymLinks; - - Byte *ProcessedItemsStatuses; - - - CArchiveUpdateCallback(); - - bool IsDir(const CUpdatePair2 &up) const - { - if (up.DirIndex >= 0) - return DirItems->Items[up.DirIndex].IsDir(); - else if (up.ArcIndex >= 0) - return (*ArcItems)[up.ArcIndex].IsDir; - return false; - } -}; - -#endif +// UpdateCallback.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_H +#define ZIP7_INC_UPDATE_CALLBACK_H + +#include "../../../Common/MyCom.h" + +#include "../../Common/FileStreams.h" + +#include "../../IPassword.h" +#include "../../ICoder.h" + +#include "../Common/UpdatePair.h" +#include "../Common/UpdateProduce.h" + +#include "OpenArchive.h" + +struct CArcToDoStat +{ + CDirItemsStat2 NewData; + CDirItemsStat2 OldData; + CDirItemsStat2 DeleteData; + + UInt64 Get_NumDataItems_Total() const + { + return NewData.Get_NumDataItems2() + OldData.Get_NumDataItems2(); + } +}; + + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACEN_IUpdateCallbackUI(x) \ + virtual HRESULT WriteSfx(const wchar_t *name, UInt64 size) x \ + virtual HRESULT SetTotal(UInt64 size) x \ + virtual HRESULT SetCompleted(const UInt64 *completeValue) x \ + virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x \ + virtual HRESULT CheckBreak() x \ + /* virtual HRESULT Finalize() x */ \ + virtual HRESULT SetNumItems(const CArcToDoStat &stat) x \ + virtual HRESULT GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode) x \ + virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT ReadingFileError(const FString &path, DWORD systemError) x \ + virtual HRESULT SetOperationResult(Int32 opRes) x \ + virtual HRESULT ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) x \ + virtual HRESULT ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) x \ + /* virtual HRESULT SetPassword(const UString &password) x */ \ + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x \ + virtual HRESULT CryptoGetTextPassword(BSTR *password) x \ + virtual HRESULT ShowDeleteFile(const wchar_t *name, bool isDir) x \ + + /* + virtual HRESULT ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) x \ + virtual HRESULT ReportRawProp(UInt32 indexType, UInt32 index, PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) x \ + virtual HRESULT ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) x \ + */ + + /* virtual HRESULT CloseProgress() { return S_OK; } */ + +Z7_IFACE_DECL_PURE(IUpdateCallbackUI) +Z7_PURE_INTERFACES_END + +struct CKeyKeyValPair +{ + UInt64 Key1; + UInt64 Key2; + unsigned Value; + + int Compare(const CKeyKeyValPair &a) const + { + if (Key1 < a.Key1) return -1; + if (Key1 > a.Key1) return 1; + return MyCompare(Key2, a.Key2); + } +}; + + +class CArchiveUpdateCallback Z7_final: + public IArchiveUpdateCallback2, + public IArchiveUpdateCallbackFile, + // public IArchiveUpdateCallbackArcProp, + public IArchiveExtractCallbackMessage2, + public IArchiveGetRawProps, + public IArchiveGetRootProps, + public ICryptoGetTextPassword2, + public ICryptoGetTextPassword, + public ICompressProgressInfo, + public IInFileStream_Callback, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IArchiveUpdateCallback2) + Z7_COM_QI_ENTRY(IArchiveUpdateCallbackFile) + // Z7_COM_QI_ENTRY(IArchiveUpdateCallbackArcProp) + Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage2) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IArchiveGetRootProps) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword2) + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + Z7_COM_QI_ENTRY(ICompressProgressInfo) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallback2) + Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackFile) + // Z7_IFACE_COM7_IMP(IArchiveUpdateCallbackArcProp) + Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage2) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IArchiveGetRootProps) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + + + void UpdateProcessedItemStatus(unsigned dirIndex); + +public: + bool PreserveATime; + bool ShareForWrite; + bool StopAfterOpenError; + bool StdInMode; + + bool KeepOriginalItemNames; + bool StoreNtSecurity; + bool StoreHardLinks; + bool StoreSymLinks; + + bool StoreOwnerId; + bool StoreOwnerName; + + bool Need_LatestMTime; + bool LatestMTime_Defined; + + /* + bool Need_ArcMTime_Report; + bool ArcMTime_WasReported; + */ + + 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) Z7_override; + virtual void InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val) Z7_override; + + IUpdateCallbackUI *Callback; + + const CDirItems *DirItems; + const CDirItem *ParentDirItem; + + const CArc *Arc; + CMyComPtr Archive; + const CObjectVector *ArcItems; + const CRecordVector *UpdatePairs; + + CRecordVector VolumesSizes; + FString VolName; + FString VolExt; + UString ArcFileName; // without path prefix + + const UStringVector *NewNames; + const UString *Comment; + int CommentIndex; + + /* + CArcTime Reported_ArcMTime; + */ + CFiTime LatestMTime; + + Byte *ProcessedItemsStatuses; + + + CArchiveUpdateCallback(); + + bool IsDir(const CUpdatePair2 &up) const + { + if (up.DirIndex >= 0) + return DirItems->Items[(unsigned)up.DirIndex].IsDir(); + else if (up.ArcIndex >= 0) + return (*ArcItems)[(unsigned)up.ArcIndex].IsDir; + return false; + } + +private: + #if defined(_WIN32) && !defined(UNDER_CE) + bool _saclEnabled; + #endif + CRecordVector _map; + + UInt32 _hardIndex_From; + UInt32 _hardIndex_To; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdatePair.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdatePair.cpp 2015-11-20 20:40:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.cpp 2023-04-06 05:00:00.000000000 +0000 @@ -1,234 +1,302 @@ -// UpdatePair.cpp - -#include "StdAfx.h" - -#include - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/TimeUtils.h" - -#include "SortUtils.h" -#include "UpdatePair.h" - -using namespace NWindows; -using namespace NTime; - -static int MyCompareTime(NFileTimeType::EEnum fileTimeType, const FILETIME &time1, const FILETIME &time2) -{ - switch (fileTimeType) - { - 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); - } - } - throw 4191618; -} - -static const char *k_Duplicate_inArc_Message = "Duplicate filename in archive:"; -static const char *k_Duplicate_inDir_Message = "Duplicate filename on disk:"; -static const char *k_NotCensoredCollision_Message = "Internal file name collision (file on disk, file in archive):"; - -static void ThrowError(const char *message, const UString &s1, const UString &s2) -{ - UString m; - m.SetFromAscii(message); - m.Add_LF(); m += s1; - m.Add_LF(); m += s2; - throw m; -} - -static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) -{ - int res = CompareFileNames(ai1.Name, ai2.Name); - if (res != 0) - return res; - if (ai1.IsDir != ai2.IsDir) - return ai1.IsDir ? -1 : 1; - return 0; -} - -static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param) -{ - unsigned i1 = *p1; - unsigned i2 = *p2; - const CObjectVector &arcItems = *(const CObjectVector *)param; - int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); - if (res != 0) - return res; - return MyCompare(i1, i2); -} - -void GetUpdatePairInfoList( - const CDirItems &dirItems, - const CObjectVector &arcItems, - NFileTimeType::EEnum fileTimeType, - CRecordVector &updatePairs) -{ - CUIntVector dirIndices, arcIndices; - - unsigned numDirItems = dirItems.Items.Size(); - unsigned numArcItems = arcItems.Size(); - - CIntArr duplicatedArcItem(numArcItems); - { - int *vals = &duplicatedArcItem[0]; - for (unsigned i = 0; i < numArcItems; i++) - vals[i] = 0; - } - - { - arcIndices.ClearAndSetSize(numArcItems); - if (numArcItems != 0) - { - unsigned *vals = &arcIndices[0]; - for (unsigned i = 0; i < numArcItems; i++) - vals[i] = i; - } - arcIndices.Sort(CompareArcItems, (void *)&arcItems); - for (unsigned i = 0; i + 1 < numArcItems; i++) - if (CompareArcItemsBase( - arcItems[arcIndices[i]], - arcItems[arcIndices[i + 1]]) == 0) - { - duplicatedArcItem[i] = 1; - duplicatedArcItem[i + 1] = -1; - } - } - - UStringVector dirNames; - { - dirNames.ClearAndReserve(numDirItems); - unsigned i; - for (i = 0; i < numDirItems; i++) - dirNames.AddInReserved(dirItems.GetLogPath(i)); - SortFileNames(dirNames, dirIndices); - for (i = 0; i + 1 < numDirItems; i++) - { - const UString &s1 = dirNames[dirIndices[i]]; - const UString &s2 = dirNames[dirIndices[i + 1]]; - if (CompareFileNames(s1, s2) == 0) - ThrowError(k_Duplicate_inDir_Message, s1, s2); - } - } - - unsigned dirIndex = 0; - unsigned arcIndex = 0; - - int prevHostFile = -1; - const UString *prevHostName = NULL; - - while (dirIndex < numDirItems || arcIndex < numArcItems) - { - CUpdatePair pair; - - int dirIndex2 = -1; - int arcIndex2 = -1; - const CDirItem *di = NULL; - const CArcItem *ai = NULL; - - int compareResult = -1; - const UString *name = NULL; - - if (dirIndex < numDirItems) - { - dirIndex2 = dirIndices[dirIndex]; - di = &dirItems.Items[dirIndex2]; - } - - if (arcIndex < numArcItems) - { - arcIndex2 = arcIndices[arcIndex]; - ai = &arcItems[arcIndex2]; - compareResult = 1; - if (dirIndex < numDirItems) - { - compareResult = CompareFileNames(dirNames[dirIndex2], ai->Name); - if (compareResult == 0) - { - if (di->IsDir() != ai->IsDir) - compareResult = (ai->IsDir ? 1 : -1); - } - } - } - - if (compareResult < 0) - { - name = &dirNames[dirIndex2]; - pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; - pair.DirIndex = dirIndex2; - dirIndex++; - } - else if (compareResult > 0) - { - name = &ai->Name; - pair.State = ai->Censored ? - NUpdateArchive::NPairState::kOnlyInArchive: - NUpdateArchive::NPairState::kNotMasked; - pair.ArcIndex = arcIndex2; - arcIndex++; - } - else - { - int dupl = duplicatedArcItem[arcIndex]; - if (dupl != 0) - ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[arcIndex + dupl]].Name); - - name = &dirNames[dirIndex2]; - if (!ai->Censored) - ThrowError(k_NotCensoredCollision_Message, *name, ai->Name); - - pair.DirIndex = dirIndex2; - pair.ArcIndex = arcIndex2; - - switch (ai->MTimeDefined ? MyCompareTime( - ai->TimeType != - 1 ? (NFileTimeType::EEnum)ai->TimeType : fileTimeType, - di->MTime, ai->MTime): 0) - { - 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) ? - NUpdateArchive::NPairState::kSameFiles : - NUpdateArchive::NPairState::kUnknowNewerFiles; - } - - dirIndex++; - arcIndex++; - } - - if ((di && di->IsAltStream) || - (ai && ai->IsAltStream)) - { - if (prevHostName) - { - unsigned hostLen = prevHostName->Len(); - if (name->Len() > hostLen) - if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0) - pair.HostIndex = prevHostFile; - } - } - else - { - prevHostFile = updatePairs.Size(); - prevHostName = name; - } - - updatePairs.Add(pair); - } - - updatePairs.ReserveDown(); -} +// UpdatePair.cpp + +#include "StdAfx.h" + +#include +// #include + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/TimeUtils.h" + +#include "SortUtils.h" +#include "UpdatePair.h" + +using namespace NWindows; +using namespace NTime; + + +/* + 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) +{ + // 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) + { + const UInt32 dosTime1 = a1.Get_DosTime(); + const UInt32 dosTime2 = a2.Get_DosTime(); + return MyCompare(dosTime1, dosTime2); + } + + 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):"; + +Z7_ATTR_NORETURN +static +void ThrowError(const char *message, const UString &s1, const UString &s2) +{ + UString m (message); + m.Add_LF(); m += s1; + m.Add_LF(); m += s2; + throw m; +} + +static int CompareArcItemsBase(const CArcItem &ai1, const CArcItem &ai2) +{ + const int res = CompareFileNames(ai1.Name, ai2.Name); + if (res != 0) + return res; + if (ai1.IsDir != ai2.IsDir) + return ai1.IsDir ? -1 : 1; + return 0; +} + +static int CompareArcItems(const unsigned *p1, const unsigned *p2, void *param) +{ + const unsigned i1 = *p1; + const unsigned i2 = *p2; + const CObjectVector &arcItems = *(const CObjectVector *)param; + const int res = CompareArcItemsBase(arcItems[i1], arcItems[i2]); + if (res != 0) + return res; + return MyCompare(i1, i2); +} + +void GetUpdatePairInfoList( + const CDirItems &dirItems, + const CObjectVector &arcItems, + NFileTimeType::EEnum fileTimeType, + CRecordVector &updatePairs) +{ + CUIntVector dirIndices, arcIndices; + + const unsigned numDirItems = dirItems.Items.Size(); + const unsigned numArcItems = arcItems.Size(); + + CIntArr duplicatedArcItem(numArcItems); + { + int *vals = &duplicatedArcItem[0]; + for (unsigned i = 0; i < numArcItems; i++) + vals[i] = 0; + } + + { + arcIndices.ClearAndSetSize(numArcItems); + if (numArcItems != 0) + { + unsigned *vals = &arcIndices[0]; + for (unsigned i = 0; i < numArcItems; i++) + vals[i] = i; + } + arcIndices.Sort(CompareArcItems, (void *)&arcItems); + for (unsigned i = 0; i + 1 < numArcItems; i++) + if (CompareArcItemsBase( + arcItems[arcIndices[i]], + arcItems[arcIndices[i + 1]]) == 0) + { + duplicatedArcItem[i] = 1; + duplicatedArcItem[i + 1] = -1; + } + } + + UStringVector dirNames; + { + dirNames.ClearAndReserve(numDirItems); + unsigned i; + for (i = 0; i < numDirItems; i++) + dirNames.AddInReserved(dirItems.GetLogPath(i)); + SortFileNames(dirNames, dirIndices); + for (i = 0; i + 1 < numDirItems; i++) + { + const UString &s1 = dirNames[dirIndices[i]]; + const UString &s2 = dirNames[dirIndices[i + 1]]; + if (CompareFileNames(s1, s2) == 0) + ThrowError(k_Duplicate_inDir_Message, s1, s2); + } + } + + unsigned dirIndex = 0; + unsigned arcIndex = 0; + + int prevHostFile = -1; + const UString *prevHostName = NULL; + + while (dirIndex < numDirItems || arcIndex < numArcItems) + { + CUpdatePair pair; + + int dirIndex2 = -1; + int arcIndex2 = -1; + const CDirItem *di = NULL; + const CArcItem *ai = NULL; + + int compareResult = -1; + const UString *name = NULL; + + if (dirIndex < numDirItems) + { + dirIndex2 = (int)dirIndices[dirIndex]; + di = &dirItems.Items[(unsigned)dirIndex2]; + } + + if (arcIndex < numArcItems) + { + arcIndex2 = (int)arcIndices[arcIndex]; + ai = &arcItems[(unsigned)arcIndex2]; + compareResult = 1; + if (dirIndex < numDirItems) + { + compareResult = CompareFileNames(dirNames[(unsigned)dirIndex2], ai->Name); + if (compareResult == 0) + { + if (di->IsDir() != ai->IsDir) + compareResult = (ai->IsDir ? 1 : -1); + } + } + } + + if (compareResult < 0) + { + name = &dirNames[(unsigned)dirIndex2]; + pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; + pair.DirIndex = dirIndex2; + dirIndex++; + } + else if (compareResult > 0) + { + name = &ai->Name; + pair.State = ai->Censored ? + NUpdateArchive::NPairState::kOnlyInArchive: + NUpdateArchive::NPairState::kNotMasked; + pair.ArcIndex = arcIndex2; + arcIndex++; + } + else + { + const int dupl = duplicatedArcItem[arcIndex]; + if (dupl != 0) + ThrowError(k_Duplicate_inArc_Message, ai->Name, arcItems[arcIndices[(unsigned)((int)arcIndex + dupl)]].Name); + + name = &dirNames[(unsigned)dirIndex2]; + if (!ai->Censored) + ThrowError(k_NotCensoredCollision_Message, *name, ai->Name); + + pair.DirIndex = dirIndex2; + pair.ArcIndex = arcIndex2; + + int compResult = 0; + if (ai->MTime.Def) + { + compResult = MyCompareTime((unsigned)fileTimeType, di->MTime, ai->MTime); + } + switch (compResult) + { + case -1: pair.State = NUpdateArchive::NPairState::kNewInArchive; break; + case 1: pair.State = NUpdateArchive::NPairState::kOldInArchive; break; + default: + pair.State = (ai->Size_Defined && di->Size == ai->Size) ? + NUpdateArchive::NPairState::kSameFiles : + NUpdateArchive::NPairState::kUnknowNewerFiles; + } + + dirIndex++; + arcIndex++; + } + + if ( + #ifdef _WIN32 + (di && di->IsAltStream) || + #endif + (ai && ai->IsAltStream)) + { + if (prevHostName) + { + const unsigned hostLen = prevHostName->Len(); + if (name->Len() > hostLen) + if ((*name)[hostLen] == ':' && CompareFileNames(*prevHostName, name->Left(hostLen)) == 0) + pair.HostIndex = prevHostFile; + } + } + else + { + prevHostFile = (int)updatePairs.Size(); + prevHostName = name; + } + + updatePairs.Add(pair); + } + + updatePairs.ReserveDown(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdatePair.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdatePair.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdatePair.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,27 +1,27 @@ -// UpdatePair.h - -#ifndef __UPDATE_PAIR_H -#define __UPDATE_PAIR_H - -#include "DirItem.h" -#include "UpdateAction.h" - -#include "../../Archive/IArchive.h" - -struct CUpdatePair -{ - NUpdateArchive::NPairState::EEnum State; - int ArcIndex; - int DirIndex; - int HostIndex; // >= 0 for alt streams only, contains index of host pair - - CUpdatePair(): ArcIndex(-1), DirIndex(-1), HostIndex(-1) {} -}; - -void GetUpdatePairInfoList( - const CDirItems &dirItems, - const CObjectVector &arcItems, - NFileTimeType::EEnum fileTimeType, - CRecordVector &updatePairs); - -#endif +// UpdatePair.h + +#ifndef ZIP7_INC_UPDATE_PAIR_H +#define ZIP7_INC_UPDATE_PAIR_H + +#include "DirItem.h" +#include "UpdateAction.h" + +#include "../../Archive/IArchive.h" + +struct CUpdatePair +{ + NUpdateArchive::NPairState::EEnum State; + int ArcIndex; + int DirIndex; + int HostIndex; // >= 0 for alt streams only, contains index of host pair + + CUpdatePair(): ArcIndex(-1), DirIndex(-1), HostIndex(-1) {} +}; + +void GetUpdatePairInfoList( + const CDirItems &dirItems, + const CObjectVector &arcItems, + NFileTimeType::EEnum fileTimeType, + CRecordVector &updatePairs); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateProduce.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateProduce.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.cpp 2024-03-03 16:00:00.000000000 +0000 @@ -1,70 +1,74 @@ -// UpdateProduce.cpp - -#include "StdAfx.h" - -#include "UpdateProduce.h" - -using namespace NUpdateArchive; - -static const char *kUpdateActionSetCollision = "Internal collision in update action set"; - -void UpdateProduce( - const CRecordVector &updatePairs, - const CActionSet &actionSet, - CRecordVector &operationChain, - IUpdateProduceCallback *callback) -{ - FOR_VECTOR (i, updatePairs) - { - const CUpdatePair &pair = updatePairs[i]; - - CUpdatePair2 up2; - up2.DirIndex = pair.DirIndex; - up2.ArcIndex = pair.ArcIndex; - up2.NewData = up2.NewProps = true; - up2.UseArcProps = false; - - switch (actionSet.StateActions[(unsigned)pair.State]) - { - case NPairAction::kIgnore: - if (pair.ArcIndex >= 0 && callback) - callback->ShowDeleteFile(pair.ArcIndex); - continue; - - case NPairAction::kCopy: - if (pair.State == NPairState::kOnlyOnDisk) - throw kUpdateActionSetCollision; - if (pair.State == NPairState::kOnlyInArchive) - { - if (pair.HostIndex >= 0) - { - /* - ignore alt stream if - 1) no such alt stream in Disk - 2) there is Host file in disk - */ - if (updatePairs[pair.HostIndex].DirIndex >= 0) - continue; - } - } - up2.NewData = up2.NewProps = false; - up2.UseArcProps = true; - break; - - case NPairAction::kCompress: - if (pair.State == NPairState::kOnlyInArchive || - pair.State == NPairState::kNotMasked) - throw kUpdateActionSetCollision; - break; - - case NPairAction::kCompressAsAnti: - up2.IsAnti = true; - up2.UseArcProps = (pair.ArcIndex >= 0); - break; - } - - operationChain.Add(up2); - } - - operationChain.ReserveDown(); -} +// UpdateProduce.cpp + +#include "StdAfx.h" + +#include "UpdateProduce.h" + +using namespace NUpdateArchive; + +static const char * const kUpdateActionSetCollision = "Internal collision in update action set"; + +void UpdateProduce( + const CRecordVector &updatePairs, + const CActionSet &actionSet, + CRecordVector &operationChain, + IUpdateProduceCallback *callback) +{ + FOR_VECTOR (i, updatePairs) + { + const CUpdatePair &pair = updatePairs[i]; + + CUpdatePair2 up2; + up2.DirIndex = pair.DirIndex; + up2.ArcIndex = pair.ArcIndex; + up2.NewData = up2.NewProps = true; + up2.UseArcProps = false; + + switch ((int)actionSet.StateActions[(unsigned)pair.State]) + { + case NPairAction::kIgnore: + if (pair.ArcIndex >= 0 && callback) + callback->ShowDeleteFile((unsigned)pair.ArcIndex); + continue; + + case NPairAction::kCopy: + if (pair.State == NPairState::kOnlyOnDisk) + throw kUpdateActionSetCollision; + if (pair.State == NPairState::kOnlyInArchive) + { + if (pair.HostIndex >= 0) + { + /* + ignore alt stream if + 1) no such alt stream in Disk + 2) there is Host file in disk + */ + if (updatePairs[(unsigned)pair.HostIndex].DirIndex >= 0) + continue; + } + } + up2.NewData = up2.NewProps = false; + up2.UseArcProps = true; + break; + + case NPairAction::kCompress: + if (pair.State == NPairState::kOnlyInArchive || + pair.State == NPairState::kNotMasked) + throw kUpdateActionSetCollision; + break; + + case NPairAction::kCompressAsAnti: + up2.IsAnti = true; + up2.UseArcProps = (pair.ArcIndex >= 0); + break; + + default: throw 123; // break; // is unexpected case + } + + up2.IsSameTime = ((unsigned)pair.State == NUpdateArchive::NPairState::kSameFiles); + + operationChain.Add(up2); + } + + operationChain.ReserveDown(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateProduce.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/UpdateProduce.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/UpdateProduce.h 2023-02-01 17:00:00.000000000 +0000 @@ -1,55 +1,60 @@ -// UpdateProduce.h - -#ifndef __UPDATE_PRODUCE_H -#define __UPDATE_PRODUCE_H - -#include "UpdatePair.h" - -struct CUpdatePair2 -{ - bool NewData; - bool NewProps; - bool UseArcProps; // if (UseArcProps && NewProps), we want to change only some properties. - bool IsAnti; // if (!IsAnti) we use other ways to detect Anti status - - int DirIndex; - int ArcIndex; - int NewNameIndex; - - bool IsMainRenameItem; - - void SetAs_NoChangeArcItem(int arcIndex) - { - NewData = NewProps = false; - UseArcProps = true; - IsAnti = false; - ArcIndex = arcIndex; - } - - bool ExistOnDisk() const { return DirIndex != -1; } - bool ExistInArchive() const { return ArcIndex != -1; } - - CUpdatePair2(): - NewData(false), - NewProps(false), - UseArcProps(false), - IsAnti(false), - DirIndex(-1), - ArcIndex(-1), - NewNameIndex(-1), - IsMainRenameItem(false) - {} -}; - -struct IUpdateProduceCallback -{ - virtual HRESULT ShowDeleteFile(unsigned arcIndex) = 0; -}; - -void UpdateProduce( - const CRecordVector &updatePairs, - const NUpdateArchive::CActionSet &actionSet, - CRecordVector &operationChain, - IUpdateProduceCallback *callback); - -#endif +// UpdateProduce.h + +#ifndef ZIP7_INC_UPDATE_PRODUCE_H +#define ZIP7_INC_UPDATE_PRODUCE_H + +#include "UpdatePair.h" + +struct CUpdatePair2 +{ + bool NewData; + bool NewProps; + bool UseArcProps; // if (UseArcProps && NewProps), we want to change only some properties. + bool IsAnti; // if (!IsAnti) we use other ways to detect Anti status + + int DirIndex; + int ArcIndex; + int NewNameIndex; + + bool IsMainRenameItem; + bool IsSameTime; + + void SetAs_NoChangeArcItem(unsigned arcIndex) // int + { + NewData = NewProps = false; + UseArcProps = true; + IsAnti = false; + ArcIndex = (int)arcIndex; + } + + bool ExistOnDisk() const { return DirIndex != -1; } + bool ExistInArchive() const { return ArcIndex != -1; } + + CUpdatePair2(): + NewData(false), + NewProps(false), + UseArcProps(false), + IsAnti(false), + DirIndex(-1), + ArcIndex(-1), + NewNameIndex(-1), + IsMainRenameItem(false), + IsSameTime(false) + {} +}; + +Z7_PURE_INTERFACES_BEGIN + +DECLARE_INTERFACE(IUpdateProduceCallback) +{ + virtual HRESULT ShowDeleteFile(unsigned arcIndex) = 0; +}; +Z7_PURE_INTERFACES_END + +void UpdateProduce( + const CRecordVector &updatePairs, + const NUpdateArchive::CActionSet &actionSet, + CRecordVector &operationChain, + IUpdateProduceCallback *callback); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/WorkDir.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/WorkDir.cpp 2015-11-20 20:40:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.cpp 2024-10-17 10:00:00.000000000 +0000 @@ -1,94 +1,84 @@ -// WorkDir.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileName.h" - -#include "WorkDir.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName) -{ - NWorkDir::NMode::EEnum mode = workDirInfo.Mode; - - #if defined(_WIN32) && !defined(UNDER_CE) - if (workDirInfo.ForRemovableOnly) - { - mode = NWorkDir::NMode::kCurrent; - FString prefix = path.Left(3); - if (prefix[1] == FTEXT(':') && prefix[2] == FTEXT('\\')) - { - UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP)); - if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) - mode = workDirInfo.Mode; - } - /* - CParsedPath parsedPath; - parsedPath.ParsePath(archiveName); - UINT driveType = GetDriveType(parsedPath.Prefix); - if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE)) - mode = NZipSettings::NWorkDir::NMode::kCurrent; - */ - } - #endif - - int pos = path.ReverseFind_PathSepar() + 1; - fileName = path.Ptr(pos); - - switch (mode) - { - case NWorkDir::NMode::kCurrent: - { - return path.Left(pos); - } - case NWorkDir::NMode::kSpecified: - { - FString tempDir = workDirInfo.Path; - NName::NormalizeDirPathPrefix(tempDir); - return tempDir; - } - default: - { - FString tempDir; - if (!MyGetTempPath(tempDir)) - throw 141717; - return tempDir; - } - } -} - -HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) -{ - NWorkDir::CInfo workDirInfo; - workDirInfo.Load(); - FString namePart; - FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); - CreateComplexDir(workDir); - CTempFile tempFile; - _outStreamSpec = new COutFileStream; - OutStream = _outStreamSpec; - if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) - { - DWORD error = GetLastError(); - return error ? error : E_FAIL; - } - _originalPath = originalPath; - return S_OK; -} - -HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal) -{ - OutStream.Release(); - if (!_tempFile.MoveTo(_originalPath, deleteOriginal)) - { - DWORD error = GetLastError(); - return error ? error : E_FAIL; - } - return S_OK; -} +// WorkDir.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileSystem.h" + +#include "WorkDir.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName) +{ + NWorkDir::NMode::EEnum mode = workDirInfo.Mode; + + #if defined(_WIN32) && !defined(UNDER_CE) + if (workDirInfo.ForRemovableOnly) + { + mode = NWorkDir::NMode::kCurrent; + const FString prefix = path.Left(3); + if (NName::IsDrivePath(prefix)) + { + const UINT driveType = NSystem::MyGetDriveType(prefix); + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + mode = workDirInfo.Mode; + } + /* + CParsedPath parsedPath; + parsedPath.ParsePath(archiveName); + UINT driveType = GetDriveType(parsedPath.Prefix); + if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE)) + mode = NZipSettings::NWorkDir::NMode::kCurrent; + */ + } + #endif + + const int pos = path.ReverseFind_PathSepar() + 1; + fileName = path.Ptr((unsigned)pos); + + FString tempDir; + switch ((int)mode) + { + case NWorkDir::NMode::kCurrent: + tempDir = path.Left((unsigned)pos); + break; + case NWorkDir::NMode::kSpecified: + tempDir = workDirInfo.Path; + break; + // case NWorkDir::NMode::kSystem: + default: + if (!MyGetTempPath(tempDir)) + throw 141717; + break; + } + NName::NormalizeDirPathPrefix(tempDir); + return tempDir; +} + +HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) +{ + NWorkDir::CInfo workDirInfo; + workDirInfo.Load(); + FString namePart; + FString path = GetWorkDir(workDirInfo, originalPath, namePart); + CreateComplexDir(path); + path += namePart; + _outStreamSpec = new COutFileStream; + OutStream = _outStreamSpec; + if (!_tempFile.Create(path, &_outStreamSpec->File)) + return GetLastError_noZero_HRESULT(); + _originalPath = originalPath; + return S_OK; +} + +HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress) +{ + OutStream.Release(); + if (!_tempFile.MoveTo(_originalPath, deleteOriginal, progress)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/WorkDir.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/WorkDir.h 2014-12-21 12:44:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/WorkDir.h 2024-10-17 10:00:00.000000000 +0000 @@ -1,26 +1,30 @@ -// WorkDir.h - -#ifndef __WORK_DIR_H -#define __WORK_DIR_H - -#include "../../../Windows/FileDir.h" - -#include "../../Common/FileStreams.h" - -#include "ZipRegistry.h" - -FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName); - -class CWorkDirTempFile -{ - FString _originalPath; - NWindows::NFile::NDir::CTempFile _tempFile; - COutFileStream *_outStreamSpec; -public: - CMyComPtr OutStream; - - HRESULT CreateTempFile(const FString &originalPath); - HRESULT MoveToOriginal(bool deleteOriginal); -}; - -#endif +// WorkDir.h + +#ifndef ZIP7_INC_WORK_DIR_H +#define ZIP7_INC_WORK_DIR_H + +#include "../../../Windows/FileDir.h" + +#include "../../Common/FileStreams.h" + +#include "ZipRegistry.h" + +FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName); + +class CWorkDirTempFile MY_UNCOPYABLE +{ + FString _originalPath; + NWindows::NFile::NDir::CTempFile _tempFile; + COutFileStream *_outStreamSpec; +public: + CMyComPtr OutStream; + + const FString &Get_OriginalFilePath() const { return _originalPath; } + const FString &Get_TempFilePath() const { return _tempFile.GetPath(); } + + HRESULT CreateTempFile(const FString &originalPath); + HRESULT MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress = NULL); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ZipRegistry.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Common/ZipRegistry.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -1,399 +1,599 @@ -// ZipRegistry.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/Registry.h" -#include "../../../Windows/Synchronization.h" - -#include "ZipRegistry.h" - -using namespace NWindows; -using namespace NRegistry; - -static NSynchronization::CCriticalSection g_CS; -#define CS_LOCK NSynchronization::CCriticalSectionLock lock(g_CS); - -static const TCHAR *kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR); - -static CSysString GetKeyPath(const CSysString &path) { return kCuPrefix + path; } - -static LONG OpenMainKey(CKey &key, LPCTSTR keyName) -{ - return key.Open(HKEY_CURRENT_USER, GetKeyPath(keyName), KEY_READ); -} - -static LONG CreateMainKey(CKey &key, LPCTSTR keyName) -{ - return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName)); -} - -static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b) -{ - if (b.Def) - key.SetValue(name, b.Val); -} - -static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) -{ - b.Val = false; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); -} - -static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b) -{ - b.Val = true; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); -} - -namespace NExtract -{ - -static const TCHAR *kKeyName = TEXT("Extraction"); - -static const TCHAR *kExtractMode = TEXT("ExtractMode"); -static const TCHAR *kOverwriteMode = TEXT("OverwriteMode"); -static const TCHAR *kShowPassword = TEXT("ShowPassword"); -static const TCHAR *kPathHistory = TEXT("PathHistory"); -static const TCHAR *kSplitDest = TEXT("SplitDest"); -static const TCHAR *kElimDup = TEXT("ElimDup"); -// static const TCHAR *kAltStreams = TEXT("AltStreams"); -static const TCHAR *kNtSecur = TEXT("Security"); - -void CInfo::Save() const -{ - CS_LOCK - CKey key; - CreateMainKey(key, kKeyName); - - if (PathMode_Force) - key.SetValue(kExtractMode, (UInt32)PathMode); - if (OverwriteMode_Force) - key.SetValue(kOverwriteMode, (UInt32)OverwriteMode); - - Key_Set_BoolPair(key, kSplitDest, SplitDest); - Key_Set_BoolPair(key, kElimDup, ElimDup); - // Key_Set_BoolPair(key, kAltStreams, AltStreams); - Key_Set_BoolPair(key, kNtSecur, NtSecurity); - Key_Set_BoolPair(key, kShowPassword, ShowPassword); - - key.RecurseDeleteKey(kPathHistory); - key.SetValue_Strings(kPathHistory, Paths); -} - -void Save_ShowPassword(bool showPassword) -{ - CS_LOCK - CKey key; - CreateMainKey(key, kKeyName); - key.SetValue(kShowPassword, showPassword); -} - -void CInfo::Load() -{ - PathMode = NPathMode::kCurPaths; - PathMode_Force = false; - OverwriteMode = NOverwriteMode::kAsk; - OverwriteMode_Force = false; - - SplitDest.Val = true; - - Paths.Clear(); - - CS_LOCK - CKey key; - if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) - return; - - key.GetValue_Strings(kPathHistory, Paths); - UInt32 v; - if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) - { - PathMode = (NPathMode::EEnum)v; - PathMode_Force = true; - } - if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) - { - OverwriteMode = (NOverwriteMode::EEnum)v; - OverwriteMode_Force = true; - } - - Key_Get_BoolPair_true(key, kSplitDest, SplitDest); - - Key_Get_BoolPair(key, kElimDup, ElimDup); - // Key_Get_BoolPair(key, kAltStreams, AltStreams); - Key_Get_BoolPair(key, kNtSecur, NtSecurity); - Key_Get_BoolPair(key, kShowPassword, ShowPassword); -} - -bool Read_ShowPassword() -{ - CS_LOCK - CKey key; - bool showPassword = false; - if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) - return showPassword; - key.GetValue_IfOk(kShowPassword, showPassword); - return showPassword; -} - -} - -namespace NCompression -{ - -static const TCHAR *kKeyName = TEXT("Compression"); - -static const TCHAR *kArcHistory = TEXT("ArcHistory"); -static const WCHAR *kArchiver = L"Archiver"; -static const TCHAR *kShowPassword = TEXT("ShowPassword"); -static const TCHAR *kEncryptHeaders = TEXT("EncryptHeaders"); - -static const TCHAR *kOptionsKeyName = TEXT("Options"); - -static const TCHAR *kLevel = TEXT("Level"); -static const TCHAR *kDictionary = TEXT("Dictionary"); -static const TCHAR *kOrder = TEXT("Order"); -static const TCHAR *kBlockSize = TEXT("BlockSize"); -static const TCHAR *kNumThreads = TEXT("NumThreads"); -static const WCHAR *kMethod = L"Method"; -static const WCHAR *kOptions = L"Options"; -static const WCHAR *kEncryptionMethod = L"EncryptionMethod"; - -static const TCHAR *kNtSecur = TEXT("Security"); -static const TCHAR *kAltStreams = TEXT("AltStreams"); -static const TCHAR *kHardLinks = TEXT("HardLinks"); -static const TCHAR *kSymLinks = TEXT("SymLinks"); - -static void SetRegString(CKey &key, const WCHAR *name, const UString &value) -{ - if (value.IsEmpty()) - key.DeleteValue(name); - else - key.SetValue(name, value); -} - -static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value) -{ - if (value == (UInt32)(Int32)-1) - key.DeleteValue(name); - else - key.SetValue(name, value); -} - -static void GetRegString(CKey &key, const WCHAR *name, UString &value) -{ - if (key.QueryValue(name, value) != ERROR_SUCCESS) - value.Empty(); -} - -static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value) -{ - if (key.QueryValue(name, value) != ERROR_SUCCESS) - value = (UInt32)(Int32)-1; -} - -void CInfo::Save() const -{ - CS_LOCK - - 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.SetValue(kShowPassword, ShowPassword); - key.SetValue(kLevel, (UInt32)Level); - key.SetValue(kArchiver, ArcType); - key.SetValue(kShowPassword, ShowPassword); - key.SetValue(kEncryptHeaders, EncryptHeaders); - key.RecurseDeleteKey(kArcHistory); - key.SetValue_Strings(kArcHistory, ArcPaths); - - key.RecurseDeleteKey(kOptionsKeyName); - { - CKey optionsKey; - optionsKey.Create(key, kOptionsKeyName); - FOR_VECTOR (i, Formats) - { - const CFormatOptions &fo = Formats[i]; - 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); - } - } -} - -void CInfo::Load() -{ - ArcPaths.Clear(); - Formats.Clear(); - - Level = 5; - ArcType = L"7z"; - ShowPassword = false; - EncryptHeaders = false; - - CS_LOCK - CKey key; - - if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) - return; - - Key_Get_BoolPair(key, kNtSecur, NtSecurity); - Key_Get_BoolPair(key, kAltStreams, AltStreams); - Key_Get_BoolPair(key, kHardLinks, HardLinks); - Key_Get_BoolPair(key, kSymLinks, SymLinks); - - key.GetValue_Strings(kArcHistory, ArcPaths); - - { - CKey optionsKey; - if (optionsKey.Open(key, kOptionsKeyName, KEY_READ) == ERROR_SUCCESS) - { - CSysStringVector formatIDs; - optionsKey.EnumKeys(formatIDs); - FOR_VECTOR (i, formatIDs) - { - CKey fk; - CFormatOptions fo; - fo.FormatID = formatIDs[i]; - if (fk.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS) - { - GetRegString(fk, kOptions, fo.Options); - GetRegString(fk, kMethod, fo.Method); - GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); - - 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); - - Formats.Add(fo); - } - } - } - } - - UString a; - if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) - ArcType = a; - key.GetValue_IfOk(kLevel, Level); - key.GetValue_IfOk(kShowPassword, ShowPassword); - key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders); -} - -} - -static const TCHAR *kOptionsInfoKeyName = TEXT("Options"); - -namespace NWorkDir -{ -static const TCHAR *kWorkDirType = TEXT("WorkDirType"); -static const WCHAR *kWorkDirPath = L"WorkDirPath"; -static const TCHAR *kTempRemovableOnly = TEXT("TempRemovableOnly"); - - -void CInfo::Save()const -{ - CS_LOCK - CKey key; - CreateMainKey(key, kOptionsInfoKeyName); - key.SetValue(kWorkDirType, (UInt32)Mode); - key.SetValue(kWorkDirPath, fs2us(Path)); - key.SetValue(kTempRemovableOnly, ForRemovableOnly); -} - -void CInfo::Load() -{ - SetDefault(); - - CS_LOCK - CKey key; - if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) - return; - - UInt32 dirType; - if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS) - return; - switch (dirType) - { - case NMode::kSystem: - case NMode::kCurrent: - case NMode::kSpecified: - Mode = (NMode::EEnum)dirType; - } - UString pathU; - if (key.QueryValue(kWorkDirPath, pathU) == ERROR_SUCCESS) - Path = us2fs(pathU); - else - { - Path.Empty(); - if (Mode == NMode::kSpecified) - Mode = NMode::kSystem; - } - key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly); -} - -} - -static const TCHAR *kCascadedMenu = TEXT("CascadedMenu"); -static const TCHAR *kContextMenu = TEXT("ContextMenu"); -static const TCHAR *kMenuIcons = TEXT("MenuIcons"); -static const TCHAR *kElimDup = TEXT("ElimDupExtract"); - -void CContextMenuInfo::Save() const -{ - CS_LOCK - CKey key; - CreateMainKey(key, kOptionsInfoKeyName); - - Key_Set_BoolPair(key, kCascadedMenu, Cascaded); - Key_Set_BoolPair(key, kMenuIcons, MenuIcons); - Key_Set_BoolPair(key, kElimDup, ElimDup); - - if (Flags_Def) - key.SetValue(kContextMenu, Flags); -} - -void CContextMenuInfo::Load() -{ - Cascaded.Val = true; - Cascaded.Def = false; - - MenuIcons.Val = false; - MenuIcons.Def = false; - - ElimDup.Val = true; - ElimDup.Def = false; - - Flags = (UInt32)(Int32)-1; - Flags_Def = false; - - CS_LOCK - - CKey key; - if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) - return; - - Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded); - Key_Get_BoolPair_true(key, kElimDup, ElimDup); - Key_Get_BoolPair(key, kMenuIcons, MenuIcons); - - Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); -} +// ZipRegistry.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/Registry.h" +#include "../../../Windows/Synchronization.h" + +// #include "../Explorer/ContextMenuFlags.h" +#include "ZipRegistry.h" + +using namespace NWindows; +using namespace NRegistry; + +static NSynchronization::CCriticalSection g_CS; +#define CS_LOCK NSynchronization::CCriticalSectionLock lock(g_CS); + +static LPCTSTR const kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR); + +static CSysString GetKeyPath(LPCTSTR path) { return kCuPrefix + (CSysString)path; } + +static LONG OpenMainKey(CKey &key, LPCTSTR keyName) +{ + return key.Open(HKEY_CURRENT_USER, GetKeyPath(keyName), KEY_READ); +} + +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) +{ + value = (UInt32)(Int32)-1; + key.GetValue_UInt32_IfOk(name, value); +} + + +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_bool_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; + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); +} + +static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b) +{ + b.Val = true; + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); +} + +namespace NExtract +{ + +static LPCTSTR const kKeyName = TEXT("Extraction"); + +static LPCTSTR const kExtractMode = TEXT("ExtractMode"); +static LPCTSTR const kOverwriteMode = TEXT("OverwriteMode"); +static LPCTSTR const kShowPassword = TEXT("ShowPassword"); +static LPCTSTR const kPathHistory = TEXT("PathHistory"); +static LPCTSTR const kSplitDest = TEXT("SplitDest"); +static LPCTSTR const kElimDup = TEXT("ElimDup"); +// static LPCTSTR const kAltStreams = TEXT("AltStreams"); +static LPCTSTR const kNtSecur = TEXT("Security"); +static LPCTSTR const kMemLimit = TEXT("MemLimit"); + +void CInfo::Save() const +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + + if (PathMode_Force) + key.SetValue(kExtractMode, (UInt32)PathMode); + if (OverwriteMode_Force) + key.SetValue(kOverwriteMode, (UInt32)OverwriteMode); + + Key_Set_BoolPair(key, kSplitDest, SplitDest); + Key_Set_BoolPair(key, kElimDup, ElimDup); + // Key_Set_BoolPair(key, kAltStreams, AltStreams); + Key_Set_BoolPair(key, kNtSecur, NtSecurity); + Key_Set_BoolPair(key, kShowPassword, ShowPassword); + + key.RecurseDeleteKey(kPathHistory); + key.SetValue_Strings(kPathHistory, Paths); +} + +void Save_ShowPassword(bool showPassword) +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + key.SetValue(kShowPassword, showPassword); +} + +void Save_LimitGB(UInt32 limit_GB) +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + Key_Set_UInt32(key, kMemLimit, limit_GB); +} + +void CInfo::Load() +{ + PathMode = NPathMode::kCurPaths; + PathMode_Force = false; + OverwriteMode = NOverwriteMode::kAsk; + OverwriteMode_Force = false; + + SplitDest.Val = true; + + Paths.Clear(); + + CS_LOCK + CKey key; + if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) + return; + + key.GetValue_Strings(kPathHistory, Paths); + UInt32 v; + if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) + { + PathMode = (NPathMode::EEnum)v; + PathMode_Force = true; + } + if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) + { + OverwriteMode = (NOverwriteMode::EEnum)v; + OverwriteMode_Force = true; + } + + Key_Get_BoolPair_true(key, kSplitDest, SplitDest); + + Key_Get_BoolPair(key, kElimDup, ElimDup); + // Key_Get_BoolPair(key, kAltStreams, AltStreams); + Key_Get_BoolPair(key, kNtSecur, NtSecurity); + Key_Get_BoolPair(key, kShowPassword, ShowPassword); +} + +bool Read_ShowPassword() +{ + CS_LOCK + CKey key; + bool showPassword = false; + if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) + return showPassword; + key.GetValue_bool_IfOk(kShowPassword, showPassword); + return showPassword; +} + +UInt32 Read_LimitGB() +{ + CS_LOCK + CKey key; + UInt32 v = (UInt32)(Int32)-1; + if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS) + key.GetValue_UInt32_IfOk(kMemLimit, v); + return v; +} + +} + +namespace NCompression +{ + +static LPCTSTR const kKeyName = TEXT("Compression"); + +static LPCTSTR const kArcHistory = TEXT("ArcHistory"); +static LPCWSTR const kArchiver = L"Archiver"; +static LPCTSTR const kShowPassword = TEXT("ShowPassword"); +static LPCTSTR const kEncryptHeaders = TEXT("EncryptHeaders"); + +static LPCTSTR const kOptionsKeyName = TEXT("Options"); + +static LPCTSTR const kLevel = TEXT("Level"); +static LPCTSTR const kDictionary = TEXT("Dictionary"); +// static LPCTSTR const kDictionaryChain = TEXT("DictionaryChain"); +static LPCTSTR const kOrder = TEXT("Order"); +static LPCTSTR const kBlockSize = TEXT("BlockSize"); +static LPCTSTR const kNumThreads = TEXT("NumThreads"); +static LPCWSTR const kMethod = L"Method"; +static LPCWSTR const kOptions = L"Options"; +static LPCWSTR const kEncryptionMethod = L"EncryptionMethod"; + +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) +{ + if (value.IsEmpty()) + 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 LPCWSTR const kMemUse = L"MemUse" + #if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4) + L"32"; + #else + L"64"; + #endif + +void CInfo::Save() const +{ + CS_LOCK + + CKey key; + CreateMainKey(key, kKeyName); + + 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); + key.SetValue(kArchiver, ArcType); + key.SetValue(kShowPassword, ShowPassword); + key.SetValue(kEncryptHeaders, EncryptHeaders); + key.RecurseDeleteKey(kArcHistory); + key.SetValue_Strings(kArcHistory, ArcPaths); + + key.RecurseDeleteKey(kOptionsKeyName); + { + CKey optionsKey; + optionsKey.Create(key, kOptionsKeyName); + FOR_VECTOR (i, Formats) + { + const CFormatOptions &fo = Formats[i]; + CKey fk; + fk.Create(optionsKey, fo.FormatID); + + 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, kDictionaryChain, fo.DictionaryChain); + 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); + } + } +} + +void CInfo::Load() +{ + ArcPaths.Clear(); + Formats.Clear(); + + Level = 5; + ArcType = L"7z"; + ShowPassword = false; + EncryptHeaders = false; + + CS_LOCK + CKey key; + + if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) + return; + + Key_Get_BoolPair(key, kNtSecur, NtSecurity); + 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); + + { + CKey optionsKey; + if (optionsKey.Open(key, kOptionsKeyName, KEY_READ) == ERROR_SUCCESS) + { + CSysStringVector formatIDs; + optionsKey.EnumKeys(formatIDs); + FOR_VECTOR (i, formatIDs) + { + CKey fk; + CFormatOptions fo; + fo.FormatID = formatIDs[i]; + if (fk.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS) + { + GetRegString(fk, kMethod, fo.Method); + GetRegString(fk, kOptions, fo.Options); + GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); + GetRegString(fk, kMemUse, fo.MemUse); + + Key_Get_UInt32(fk, kLevel, fo.Level); + Key_Get_UInt32(fk, kDictionary, fo.Dictionary); + // Key_Get_UInt32(fk, kDictionaryChain, fo.DictionaryChain); + 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); + } + } + } + } + + UString a; + if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) + ArcType = a; + key.GetValue_UInt32_IfOk(kLevel, Level); + key.GetValue_bool_IfOk(kShowPassword, ShowPassword); + key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders); +} + + +static bool ParseMemUse(const wchar_t *s, CMemUse &mu) +{ + mu.Clear(); + + bool percentMode = false; + { + const wchar_t c = *s; + if (MyCharLower_Ascii(c) == 'p') + { + percentMode = true; + s++; + } + } + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(s, &end); + if (end == s) + return false; + + wchar_t c = *end; + + if (percentMode) + { + if (c != 0) + return false; + mu.IsPercent = true; + mu.Val = number; + return true; + } + + if (c == 0) + { + mu.Val = number; + return true; + } + + c = MyCharLower_Ascii(c); + + const wchar_t c1 = end[1]; + + if (c == '%') + { + if (c1 != 0) + return false; + mu.IsPercent = true; + mu.Val = number; + return true; + } + + if (c == 'b') + { + if (c1 != 0) + return false; + mu.Val = number; + return true; + } + + if (c1 != 0) + if (MyCharLower_Ascii(c1) != 'b' || end[2] != 0) + return false; + + unsigned numBits; + switch (c) + { + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + default: return false; + } + if (number >= ((UInt64)1 << (64 - numBits))) + return false; + mu.Val = number << numBits; + return true; +} + + +void CMemUse::Parse(const UString &s) +{ + IsDefined = ParseMemUse(s, *this); +} + +/* +void MemLimit_Save(const UString &s) +{ + CS_LOCK + CKey key; + CreateMainKey(key, kKeyName); + SetRegString(key, kMemUse, s); +} + +bool MemLimit_Load(NCompression::CMemUse &mu) +{ + mu.Clear(); + UString a; + { + CS_LOCK + CKey key; + if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) + return false; + if (key.QueryValue(kMemUse, a) != ERROR_SUCCESS) + return false; + } + if (a.IsEmpty()) + return false; + mu.Parse(a); + return mu.IsDefined; +} +*/ + +} + +static LPCTSTR const kOptionsInfoKeyName = TEXT("Options"); + +namespace NWorkDir +{ +static LPCTSTR const kWorkDirType = TEXT("WorkDirType"); +static LPCWSTR const kWorkDirPath = L"WorkDirPath"; +static LPCTSTR const kTempRemovableOnly = TEXT("TempRemovableOnly"); + + +void CInfo::Save()const +{ + CS_LOCK + CKey key; + CreateMainKey(key, kOptionsInfoKeyName); + key.SetValue(kWorkDirType, (UInt32)Mode); + key.SetValue(kWorkDirPath, fs2us(Path)); + key.SetValue(kTempRemovableOnly, ForRemovableOnly); +} + +void CInfo::Load() +{ + SetDefault(); + + CS_LOCK + CKey key; + if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) + return; + + UInt32 dirType; + if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS) + return; + switch (dirType) + { + case NMode::kSystem: + case NMode::kCurrent: + case NMode::kSpecified: + Mode = (NMode::EEnum)dirType; + } + UString pathU; + if (key.QueryValue(kWorkDirPath, pathU) == ERROR_SUCCESS) + Path = us2fs(pathU); + else + { + Path.Empty(); + if (Mode == NMode::kSpecified) + Mode = NMode::kSystem; + } + key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly); +} + +} + +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 +{ + CS_LOCK + CKey key; + CreateMainKey(key, kOptionsInfoKeyName); + + 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); +} + +void CContextMenuInfo::Load() +{ + Cascaded.Val = true; + Cascaded.Def = false; + + MenuIcons.Val = false; + MenuIcons.Def = false; + + ElimDup.Val = true; + ElimDup.Def = false; + + WriteZone = (UInt32)(Int32)-1; + + /* we can disable email items by default, + because email code doesn't work in some systems */ + Flags = (UInt32)(Int32)-1 + /* + & ~NContextMenuFlags::kCompressEmail + & ~NContextMenuFlags::kCompressTo7zEmail + & ~NContextMenuFlags::kCompressToZipEmail + */ + ; + Flags_Def = false; + + CS_LOCK + + CKey key; + if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) + return; + + Key_Get_BoolPair_true(key, kCascadedMenu, Cascaded); + Key_Get_BoolPair_true(key, kElimDup, ElimDup); + Key_Get_BoolPair(key, kMenuIcons, MenuIcons); + + Key_Get_UInt32(key, kWriteZoneId, WriteZone); + + Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Common/ZipRegistry.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.h --- p7zip-rar-16.02/CPP/7zip/UI/Common/ZipRegistry.h 2016-05-18 17:31:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Common/ZipRegistry.h 2024-03-16 17:00:00.000000000 +0000 @@ -1,125 +1,212 @@ -// ZipRegistry.h - -#ifndef __ZIP_REGISTRY_H -#define __ZIP_REGISTRY_H - -#include "../../../Common/MyTypes.h" -#include "../../../Common/MyString.h" - -#include "ExtractMode.h" - -namespace NExtract -{ - struct CInfo - { - NPathMode::EEnum PathMode; - NOverwriteMode::EEnum OverwriteMode; - bool PathMode_Force; - bool OverwriteMode_Force; - - CBoolPair SplitDest; - CBoolPair ElimDup; - // CBoolPair AltStreams; - CBoolPair NtSecurity; - CBoolPair ShowPassword; - - UStringVector Paths; - - void Save() const; - void Load(); - }; - - void Save_ShowPassword(bool showPassword); - bool Read_ShowPassword(); -} - -namespace NCompression -{ - struct CFormatOptions - { - UInt32 Level; - UInt32 Dictionary; - UInt32 Order; - UInt32 BlockLogSize; - UInt32 NumThreads; - - CSysString FormatID; - UString Method; - UString Options; - UString EncryptionMethod; - - void ResetForLevelChange() - { - BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1); - Method.Empty(); - // Options.Empty(); - // EncryptionMethod.Empty(); - } - CFormatOptions() { ResetForLevelChange(); } - }; - - struct CInfo - { - UInt32 Level; - bool ShowPassword; - bool EncryptHeaders; - UString ArcType; - UStringVector ArcPaths; - - CObjectVector Formats; - - CBoolPair NtSecurity; - CBoolPair AltStreams; - CBoolPair HardLinks; - CBoolPair SymLinks; - - void Save() const; - void Load(); - }; -} - -namespace NWorkDir -{ - namespace NMode - { - enum EEnum - { - kSystem, - kCurrent, - kSpecified - }; - } - struct CInfo - { - NMode::EEnum Mode; - FString Path; - bool ForRemovableOnly; - - void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } - void SetDefault() - { - Mode = NMode::kSystem; - Path.Empty(); - SetForRemovableOnlyDefault(); - } - - void Save() const; - void Load(); - }; -} - - -struct CContextMenuInfo -{ - CBoolPair Cascaded; - CBoolPair MenuIcons; - CBoolPair ElimDup; - - bool Flags_Def; - UInt32 Flags; - - void Save() const; - void Load(); -}; - -#endif +// ZipRegistry.h + +#ifndef ZIP7_INC_ZIP_REGISTRY_H +#define ZIP7_INC_ZIP_REGISTRY_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +#include "../../Common/MethodProps.h" + +#include "ExtractMode.h" + +/* +CBoolPair::Def in writing functions means: + if ( CBoolPair::Def ), we write CBoolPair::Val + if ( !CBoolPair::Def ) + { + in NCompression functions we delete registry value + in another functions we do nothing + } +*/ + +namespace NExtract +{ + struct CInfo + { + NPathMode::EEnum PathMode; + NOverwriteMode::EEnum OverwriteMode; + bool PathMode_Force; + bool OverwriteMode_Force; + + CBoolPair SplitDest; + CBoolPair ElimDup; + // CBoolPair AltStreams; + CBoolPair NtSecurity; + CBoolPair ShowPassword; + + UStringVector Paths; + + void Save() const; + void Load(); + }; + + void Save_ShowPassword(bool showPassword); + bool Read_ShowPassword(); + + void Save_LimitGB(UInt32 limit_GB); + UInt32 Read_LimitGB(); +} + +namespace NCompression +{ + struct CMemUse + { + // UString Str; + bool IsDefined; + bool IsPercent; + UInt64 Val; + + CMemUse(): + IsDefined(false), + IsPercent(false), + Val(0) + {} + + void Clear() + { + // Str.Empty(); + IsDefined = false; + IsPercent = false; + Val = 0; + } + + UInt64 GetBytes(UInt64 ramSize) const + { + if (!IsPercent) + return Val; + return Calc_From_Val_Percents(ramSize, Val); + } + void Parse(const UString &s); + }; + + struct CFormatOptions + { + UInt32 Level; + UInt32 Dictionary; + // UInt32 DictionaryChain; + UInt32 Order; + UInt32 BlockLogSize; + UInt32 NumThreads; + + UInt32 TimePrec; + CBoolPair MTime; + CBoolPair ATime; + CBoolPair CTime; + CBoolPair SetArcMTime; + + CSysString FormatID; + UString Method; + UString Options; + UString EncryptionMethod; + UString MemUse; + + void Reset_TimePrec() + { + TimePrec = (UInt32)(Int32)-1; + } + + bool IsSet_TimePrec() const + { + return TimePrec != (UInt32)(Int32)-1; + } + + + void Reset_BlockLogSize() + { + BlockLogSize = (UInt32)(Int32)-1; + } + + void ResetForLevelChange() + { + BlockLogSize = NumThreads = Level = Dictionary = Order = (UInt32)(Int32)-1; + // DictionaryChain = (UInt32)(Int32)-1; + Method.Empty(); + // Options.Empty(); + // EncryptionMethod.Empty(); + } + CFormatOptions() + { + // TimePrec = 0; + Reset_TimePrec(); + ResetForLevelChange(); + } + }; + + struct CInfo + { + UInt32 Level; + bool ShowPassword; + bool EncryptHeaders; + + CBoolPair NtSecurity; + CBoolPair AltStreams; + CBoolPair HardLinks; + CBoolPair SymLinks; + + CBoolPair PreserveATime; + + UString ArcType; + UStringVector ArcPaths; + + CObjectVector Formats; + + void Save() const; + void Load(); + }; +} + +namespace NWorkDir +{ + namespace NMode + { + enum EEnum + { + kSystem, + kCurrent, + kSpecified + }; + } + struct CInfo + { + NMode::EEnum Mode; + bool ForRemovableOnly; + FString Path; + + void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } + void SetDefault() + { + Mode = NMode::kSystem; + Path.Empty(); + SetForRemovableOnlyDefault(); + } + + void Save() const; + void Load(); + }; +} + + +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(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/BenchCon.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/BenchCon.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.cpp 2023-04-01 19:00:00.000000000 +0000 @@ -1,41 +1,41 @@ -// BenchCon.cpp - -#include "StdAfx.h" - -#include "../Common/Bench.h" - -#include "BenchCon.h" -#include "ConsoleClose.h" - -struct CPrintBenchCallback: public IBenchPrintCallback -{ - FILE *_file; - - void Print(const char *s); - void NewLine(); - HRESULT CheckBreak(); -}; - -void CPrintBenchCallback::Print(const char *s) -{ - fputs(s, _file); -} - -void CPrintBenchCallback::NewLine() -{ - fputc('\n', _file); -} - -HRESULT CPrintBenchCallback::CheckBreak() -{ - return NConsoleClose::TestBreakSignal() ? E_ABORT: S_OK; -} - -HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector &props, UInt32 numIterations, FILE *f) -{ - CPrintBenchCallback callback; - callback._file = f; - return Bench(EXTERNAL_CODECS_LOC_VARS - &callback, NULL, props, numIterations, true); -} +// BenchCon.cpp + +#include "StdAfx.h" + +#include "../Common/Bench.h" + +#include "BenchCon.h" +#include "ConsoleClose.h" + +struct CPrintBenchCallback Z7_final: public IBenchPrintCallback +{ + FILE *_file; + + void Print(const char *s) Z7_override; + void NewLine() Z7_override; + HRESULT CheckBreak() Z7_override; +}; + +void CPrintBenchCallback::Print(const char *s) +{ + fputs(s, _file); +} + +void CPrintBenchCallback::NewLine() +{ + fputc('\n', _file); +} + +HRESULT CPrintBenchCallback::CheckBreak() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT: S_OK; +} + +HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS + const CObjectVector &props, UInt32 numIterations, FILE *f) +{ + CPrintBenchCallback callback; + callback._file = f; + return Bench(EXTERNAL_CODECS_LOC_VARS + &callback, NULL, props, numIterations, true); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/BenchCon.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/BenchCon.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/BenchCon.h 2023-04-01 19:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// BenchCon.h - -#ifndef __BENCH_CON_H -#define __BENCH_CON_H - -#include - -#include "../../Common/CreateCoder.h" -#include "../../UI/Common/Property.h" - -HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector &props, UInt32 numIterations, FILE *f); - -#endif +// BenchCon.h + +#ifndef ZIP7_INC_BENCH_CON_H +#define ZIP7_INC_BENCH_CON_H + +#include + +#include "../../Common/CreateCoder.h" +#include "../../UI/Common/Property.h" + +HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS + const CObjectVector &props, UInt32 numIterations, FILE *f); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/Console.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsp --- p7zip-rar-16.02/CPP/7zip/UI/Console/Console.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsp 2024-01-27 09:00:00.000000000 +0000 @@ -0,0 +1,1052 @@ +# Microsoft Developer Studio Project File - Name="Console" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Console - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Console.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Console.mak" CFG="Console - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Console - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Console - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GF /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept /ignore:4033 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Console___Win32_ReleaseU" +# PROP BASE Intermediate_Dir "Console___Win32_ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Console___Win32_DebugU" +# PROP BASE Intermediate_Dir "Console___Win32_DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_LARGE_PAGES" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Console - Win32 Release" +# Name "Console - Win32 Debug" +# Name "Console - Win32 ReleaseU" +# Name "Console - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BenchCon.cpp +# End Source File +# Begin Source File + +SOURCE=.\BenchCon.h +# End Source File +# Begin Source File + +SOURCE=.\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\HashCon.cpp +# End Source File +# Begin Source File + +SOURCE=.\HashCon.h +# End Source File +# Begin Source File + +SOURCE=.\List.cpp +# End Source File +# Begin Source File + +SOURCE=.\List.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer2.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyGuidDef.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Bench.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\RegisterArc.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "Console - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Console - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Console - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "ArchiveCommon" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Asm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\7zAsm.asm +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\Asm\x86\7zCrcOpt.asm + +!IF "$(CFG)" == "Console - Win32 Release" + +# Begin Custom Build +OutDir=.\Release +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Console - Win32 Debug" + +# Begin Custom Build +OutDir=.\Debug +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU" + +# Begin Custom Build +OutDir=.\ReleaseU +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Console - Win32 DebugU" + +# Begin Custom Build +OutDir=.\DebugU +InputPath=..\..\..\..\Asm\x86\7zCrcOpt.asm +InputName=7zCrcOpt + +"$(OutDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe -c -omf -Fo$(OutDir)\$(InputName).obj $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/Console.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsw --- p7zip-rar-16.02/CPP/7zip/UI/Console/Console.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.dsw 2003-06-25 14:06:48.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Console"=".\Console.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/Console.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.mak --- p7zip-rar-16.02/CPP/7zip/UI/Console/Console.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.mak 2024-01-29 08:00:00.000000000 +0000 @@ -0,0 +1,46 @@ +MY_CONSOLE = 1 + +!IFNDEF UNDER_CE +CFLAGS = $(CFLAGS) -DZ7_DEVICE_FILE +# -DZ7_LONG_PATH -DZ7_LARGE_PAGES +!ENDIF + +CONSOLE_OBJS = \ + $O\BenchCon.obj \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\HashCon.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\Bench.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + +C_OBJS = $(C_OBJS) \ + $O\DllSecur.obj \ + +# we need empty line after last line above diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/Console.manifest p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.manifest --- p7zip-rar-16.02/CPP/7zip/UI/Console/Console.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Console.manifest 2023-04-02 08:00:00.000000000 +0000 @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + +true + \ No newline at end of file diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/ConsoleClose.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/ConsoleClose.cpp 2008-08-05 09:48:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -1,49 +1,98 @@ -// ConsoleClose.cpp - -#include "StdAfx.h" - -#include "ConsoleClose.h" - -#include - -static int g_BreakCounter = 0; -static const int kBreakAbortThreshold = 2; - -namespace NConsoleClose { - -static void HandlerRoutine(int) -{ - g_BreakCounter++; - if (g_BreakCounter < kBreakAbortThreshold) - return ; - exit(EXIT_FAILURE); -} - -bool TestBreakSignal() -{ - return (g_BreakCounter > 0); -} - -void CheckCtrlBreak() -{ - if (TestBreakSignal()) - throw CCtrlBreakException(); -} - -CCtrlHandlerSetter::CCtrlHandlerSetter() -{ - memo_sig_int = signal(SIGINT,HandlerRoutine); // CTRL-C - if (memo_sig_int == SIG_ERR) - throw "SetConsoleCtrlHandler fails (SIGINT)"; - memo_sig_term = signal(SIGTERM,HandlerRoutine); // for kill -15 (before "kill -9") - if (memo_sig_term == SIG_ERR) - throw "SetConsoleCtrlHandler fails (SIGTERM)"; -} - -CCtrlHandlerSetter::~CCtrlHandlerSetter() -{ - signal(SIGINT,memo_sig_int); // CTRL-C - signal(SIGTERM,memo_sig_term); // kill {pid} -} - -} +// ConsoleClose.cpp + +#include "StdAfx.h" + +#include "ConsoleClose.h" + +#ifndef UNDER_CE + +#ifdef _WIN32 +#include "../../../Common/MyWindows.h" +#else +#include +#include +#endif + +namespace NConsoleClose { + +unsigned g_BreakCounter = 0; +static const unsigned kBreakAbortThreshold = 3; + +#ifdef _WIN32 + +static BOOL WINAPI HandlerRoutine(DWORD ctrlType) +{ + if (ctrlType == CTRL_LOGOFF_EVENT) + { + // printf("\nCTRL_LOGOFF_EVENT\n"); + return TRUE; + } + + if (++g_BreakCounter < kBreakAbortThreshold) + return TRUE; + return FALSE; + /* + switch (ctrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + if (g_BreakCounter < kBreakAbortThreshold) + return TRUE; + } + return FALSE; + */ +} + +CCtrlHandlerSetter::CCtrlHandlerSetter() +{ + if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) + throw 1019; // "SetConsoleCtrlHandler fails"; +} + +CCtrlHandlerSetter::~CCtrlHandlerSetter() +{ + if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) + { + // warning for throw in destructor. + // throw "SetConsoleCtrlHandler fails"; + } +} + +#else // _WIN32 + +static void HandlerRoutine(int) +{ + if (++g_BreakCounter < kBreakAbortThreshold) + return; + exit(EXIT_FAILURE); +} + +CCtrlHandlerSetter::CCtrlHandlerSetter() +{ + memo_sig_int = signal(SIGINT, HandlerRoutine); // CTRL-C + if (memo_sig_int == SIG_ERR) + throw "SetConsoleCtrlHandler fails (SIGINT)"; + memo_sig_term = signal(SIGTERM, HandlerRoutine); // for kill -15 (before "kill -9") + if (memo_sig_term == SIG_ERR) + throw "SetConsoleCtrlHandler fails (SIGTERM)"; +} + +CCtrlHandlerSetter::~CCtrlHandlerSetter() +{ + signal(SIGINT, memo_sig_int); // CTRL-C + signal(SIGTERM, memo_sig_term); // kill {pid} +} + +#endif // _WIN32 + +/* +void CheckCtrlBreak() +{ + if (TestBreakSignal()) + throw CCtrlBreakException(); +} +*/ + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/ConsoleClose.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/ConsoleClose.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ConsoleClose.h 2024-10-19 08:00:00.000000000 +0000 @@ -1,26 +1,39 @@ -// ConsoleCloseUtils.h - -#ifndef __CONSOLECLOSEUTILS_H -#define __CONSOLECLOSEUTILS_H - -namespace NConsoleClose { - -bool TestBreakSignal(); - -class CCtrlHandlerSetter -{ - void (*memo_sig_int)(int); - void (*memo_sig_term)(int); -public: - CCtrlHandlerSetter(); - virtual ~CCtrlHandlerSetter(); -}; - -class CCtrlBreakException -{}; - -void CheckCtrlBreak(); - -} - -#endif +// ConsoleClose.h + +#ifndef ZIP7_INC_CONSOLE_CLOSE_H +#define ZIP7_INC_CONSOLE_CLOSE_H + +namespace NConsoleClose { + +// class CCtrlBreakException {}; + +#ifdef UNDER_CE + +inline bool TestBreakSignal() { return false; } +struct CCtrlHandlerSetter {}; + +#else + +extern unsigned g_BreakCounter; + +inline bool TestBreakSignal() +{ + return (g_BreakCounter != 0); +} + +class CCtrlHandlerSetter Z7_final +{ + #ifndef _WIN32 + void (*memo_sig_int)(int); + void (*memo_sig_term)(int); + #endif +public: + CCtrlHandlerSetter(); + ~CCtrlHandlerSetter(); +}; + +#endif + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -1,764 +1,946 @@ -// ExtractCallbackConsole.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/TimeUtils.h" -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/PropVariantConv.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/Synchronization.h" -#endif - -#include "../../Common/FilePathAutoRename.h" - -#include "../Common/ExtractingFilePath.h" - -#include "ConsoleClose.h" -#include "ExtractCallbackConsole.h" -#include "UserInputUtils.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static HRESULT CheckBreak2() -{ - return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; -} - -static const char *kError = "ERROR: "; - - -void CExtractScanConsole::StartScanning() -{ - if (NeedPercents()) - _percent.Command = "Scan"; -} - -HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) -{ - if (NeedPercents()) - { - _percent.Files = st.NumDirs + st.NumFiles; - _percent.Completed = st.GetTotalBytes(); - _percent.FileName = fs2us(path); - _percent.Print(); - } - - return CheckBreak2(); -} - -HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError) -{ - ClosePercentsAndFlush(); - - if (_se) - { - *_se << endl << kError << NError::MyFormatMessage(systemError) << endl << - fs2us(path) << endl << endl; - _se->Flush(); - } - return HRESULT_FROM_WIN32(systemError); -} - - -void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) -{ - char temp[32]; - ConvertUInt64ToString(val, temp); - s += temp; - s.Add_Space(); - s += name; -} - -void PrintSize_bytes_Smart(AString &s, UInt64 val) -{ - Print_UInt64_and_String(s, val, "bytes"); - - if (val == 0) - return; - - unsigned numBits = 10; - char c = 'K'; - char temp[4] = { 'K', 'i', 'B', 0 }; - if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; } - else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; } - temp[0] = c; - s += " ("; - Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp); - s += ')'; -} - -void Print_DirItemsStat(AString &s, const CDirItemsStat &st) -{ - if (st.NumDirs != 0) - { - Print_UInt64_and_String(s, st.NumDirs, st.NumDirs == 1 ? "folder" : "folders"); - s += ", "; - } - Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files"); - s += ", "; - PrintSize_bytes_Smart(s, st.FilesSize); - if (st.NumAltStreams != 0) - { - s.Add_LF(); - Print_UInt64_and_String(s, st.NumAltStreams, "alternate streams"); - s += ", "; - PrintSize_bytes_Smart(s, st.AltStreamsSize); - } -} - -void CExtractScanConsole::PrintStat(const CDirItemsStat &st) -{ - if (_so) - { - AString s; - Print_DirItemsStat(s, st); - *_so << s << endl; - } -} - - - - - - - -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection g_CriticalSection; -#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); -#else -#define MT_LOCK -#endif - - -static const char *kTestString = "T"; -static const char *kExtractString = "-"; -static const char *kSkipString = "."; - -// static const char *kCantAutoRename = "can not create file with auto name\n"; -// static const char *kCantRenameFile = "can not rename existing file\n"; -// static const char *kCantDeleteOutputFile = "can not delete output file "; - -static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; - -static const char *kExtracting = "Extracting archive: "; -static const char *kTesting = "Testing archive: "; - -static const char *kEverythingIsOk = "Everything is Ok"; -static const char *kNoFiles = "No files to process"; - -static const char *kUnsupportedMethod = "Unsupported Method"; -static const char *kCrcFailed = "CRC Failed"; -static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; -static const char *kDataError = "Data Error"; -static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; -static const char *kUnavailableData = "Unavailable data"; -static const char *kUnexpectedEnd = "Unexpected end of data"; -static const char *kDataAfterEnd = "There are some data after the end of the payload data"; -static const char *kIsNotArc = "Is not archive"; -static const char *kHeadersError = "Headers Error"; -static const char *kWrongPassword = "Wrong password"; - -static const char * const k_ErrorFlagsMessages[] = -{ - "Is not archive" - , "Headers Error" - , "Headers Error in encrypted archive. Wrong password?" - , "Unavailable start of archive" - , "Unconfirmed start of archive" - , "Unexpected end of archive" - , "There are data after the end of archive" - , "Unsupported method" - , "Unsupported feature" - , "Data Error" - , "CRC Error" -}; - -STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64 size) -{ - MT_LOCK - - if (NeedPercents()) - { - _percent.Total = size; - _percent.Print(); - } - return CheckBreak2(); -} - -STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue) -{ - MT_LOCK - - if (NeedPercents()) - { - if (completeValue) - _percent.Completed = *completeValue; - _percent.Print(); - } - return CheckBreak2(); -} - -static const char *kTab = " "; - -static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) -{ - *_so << kTab << "Path: " << path << endl; - if (size) - { - AString s; - PrintSize_bytes_Smart(s, *size); - *_so << kTab << "Size: " << s << endl; - } - if (ft) - { - char temp[64]; - FILETIME locTime; - if (FileTimeToLocalFileTime(ft, &locTime)) - if (ConvertFileTimeToString(locTime, temp, true, true)) - *_so << kTab << "Modified: " << temp << endl; - } -} - -STDMETHODIMP CExtractCallbackConsole::AskOverwrite( - const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) -{ - MT_LOCK - - RINOK(CheckBreak2()); - - ClosePercentsAndFlush(); - - if (_so) - { - *_so << endl << "Would you like to replace the existing file:\n"; - PrintFileInfo(_so, existName, existTime, existSize); - *_so << "with the file from archive:\n"; - PrintFileInfo(_so, newName, newTime, newSize); - } - - NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so); - - switch (overwriteAnswer) - { - case NUserAnswerMode::kQuit: return E_ABORT; - case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break; - case NUserAnswerMode::kNoAll: *answer = NOverwriteAnswer::kNoToAll; break; - case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break; - case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break; - case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break; - default: return E_FAIL; - } - - if (_so) - { - *_so << endl; - if (NeedFlush) - _so->Flush(); - } - - return CheckBreak2(); -} - -STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 *position) -{ - MT_LOCK - - _currentName = name; - - const char *s; - unsigned requiredLevel = 1; - - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break; - case NArchive::NExtract::NAskMode::kTest: s = kTestString; break; - case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break; - default: s = "???"; requiredLevel = 2; - }; - - bool show2 = (LogLevel >= requiredLevel && _so); - - if (show2) - { - ClosePercents_for_so(); - - _tempA = s; - if (name) - _tempA.Add_Space(); - *_so << _tempA; - - _tempU.Empty(); - if (name) - _tempU = name; - _so->PrintUString(_tempU, _tempA); - if (position) - *_so << " <" << *position << ">"; - *_so << endl; - - if (NeedFlush) - _so->Flush(); - } - - if (NeedPercents()) - { - if (PercentsNameLevel >= 1) - { - _percent.FileName.Empty(); - _percent.Command.Empty(); - if (PercentsNameLevel > 1 || !show2) - { - _percent.Command = s; - if (name) - _percent.FileName = name; - } - } - _percent.Print(); - } - - return CheckBreak2(); -} - -STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) -{ - MT_LOCK - - RINOK(CheckBreak2()); - - NumFileErrors_in_Current++; - NumFileErrors++; - - ClosePercentsAndFlush(); - if (_se) - { - *_se << kError << message << endl; - _se->Flush(); - } - - return CheckBreak2(); -} - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest) -{ - dest.Empty(); - const char *s = NULL; - - switch (opRes) - { - case NArchive::NExtract::NOperationResult::kUnsupportedMethod: - s = kUnsupportedMethod; - break; - case NArchive::NExtract::NOperationResult::kCRCError: - s = (encrypted ? kCrcFailedEncrypted : kCrcFailed); - break; - case NArchive::NExtract::NOperationResult::kDataError: - s = (encrypted ? kDataErrorEncrypted : kDataError); - break; - case NArchive::NExtract::NOperationResult::kUnavailable: - s = kUnavailableData; - break; - case NArchive::NExtract::NOperationResult::kUnexpectedEnd: - s = kUnexpectedEnd; - break; - case NArchive::NExtract::NOperationResult::kDataAfterEnd: - s = kDataAfterEnd; - break; - case NArchive::NExtract::NOperationResult::kIsNotArc: - s = kIsNotArc; - break; - case NArchive::NExtract::NOperationResult::kHeadersError: - s = kHeadersError; - break; - case NArchive::NExtract::NOperationResult::kWrongPassword: - s = kWrongPassword; - break; - } - - dest += kError; - if (s) - dest += s; - else - { - char temp[16]; - ConvertUInt32ToString(opRes, temp); - dest += "Error #"; - dest += temp; - } -} - -STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted) -{ - MT_LOCK - - if (opRes == NArchive::NExtract::NOperationResult::kOK) - { - if (NeedPercents()) - { - _percent.Command.Empty(); - _percent.FileName.Empty(); - _percent.Files++; - } - } - else - { - NumFileErrors_in_Current++; - NumFileErrors++; - - if (_se) - { - ClosePercentsAndFlush(); - - AString s; - SetExtractErrorMessage(opRes, encrypted, s); - - *_se << s; - if (!_currentName.IsEmpty()) - *_se << " : " << _currentName; - *_se << endl; - _se->Flush(); - } - } - - return CheckBreak2(); -} - -STDMETHODIMP CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) -{ - if (opRes != NArchive::NExtract::NOperationResult::kOK) - { - _currentName = name; - return SetOperationResult(opRes, encrypted); - } - - return CheckBreak2(); -} - - - -#ifndef _NO_CRYPTO - -HRESULT CExtractCallbackConsole::SetPassword(const UString &password) -{ - PasswordIsDefined = true; - Password = password; - return S_OK; -} - -STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - MT_LOCK - return Open_CryptoGetTextPassword(password); - COM_TRY_END -} - -#endif - -HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) -{ - RINOK(CheckBreak2()); - - NumTryArcs++; - ThereIsError_in_Current = false; - ThereIsWarning_in_Current = false; - NumFileErrors_in_Current = 0; - - ClosePercents_for_so(); - if (_so) - *_so << endl << (testMode ? kTesting : kExtracting) << name << endl; - - if (NeedPercents()) - _percent.Command = "Open"; - return S_OK; -} - -HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); -HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); - -static AString GetOpenArcErrorMessage(UInt32 errorFlags) -{ - AString s; - - for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsMessages); i++) - { - UInt32 f = (1 << i); - if ((errorFlags & f) == 0) - continue; - const char *m = k_ErrorFlagsMessages[i]; - if (!s.IsEmpty()) - s.Add_LF(); - s += m; - errorFlags &= ~f; - } - - if (errorFlags != 0) - { - char sz[16]; - sz[0] = '0'; - sz[1] = 'x'; - ConvertUInt32ToHex(errorFlags, sz + 2); - if (!s.IsEmpty()) - s.Add_LF(); - s += sz; - } - - return s; -} - -void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags) -{ - if (errorFlags == 0) - return; - so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl; -} - -void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType) -{ - s.Add_LF(); - s.AddAscii(pre); - s.AddAscii(" as ["); - s += arcType; - s.AddAscii("] archive"); -} - -void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc) -{ - const CArcErrorInfo &er = arc.ErrorInfo; - - UString s = L"WARNING:\n"; - s += arc.Path; - if (arc.FormatIndex == er.ErrorFormatIndex) - { - s.Add_LF(); - s.AddAscii("The archive is open with offset"); - } - else - { - Add_Messsage_Pre_ArcType(s, "Can not open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex)); - Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex)); - } - - *_so << s << endl << endl; -} - - -HRESULT CExtractCallbackConsole::OpenResult( - const CCodecs *codecs, const CArchiveLink &arcLink, - const wchar_t *name, HRESULT result) -{ - ClosePercents(); - - if (NeedPercents()) - { - _percent.Files = 0; - _percent.Command.Empty(); - _percent.FileName.Empty(); - } - - - ClosePercentsAndFlush(); - - FOR_VECTOR (level, arcLink.Arcs) - { - const CArc &arc = arcLink.Arcs[level]; - const CArcErrorInfo &er = arc.ErrorInfo; - - UInt32 errorFlags = er.GetErrorFlags(); - - if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) - { - if (_se) - { - *_se << endl; - if (level != 0) - *_se << arc.Path << endl; - } - - if (errorFlags != 0) - { - if (_se) - PrintErrorFlags(*_se, "ERRORS:", errorFlags); - NumOpenArcErrors++; - ThereIsError_in_Current = true; - } - - if (!er.ErrorMessage.IsEmpty()) - { - if (_se) - *_se << "ERRORS:" << endl << er.ErrorMessage << endl; - NumOpenArcErrors++; - ThereIsError_in_Current = true; - } - - if (_se) - { - *_se << endl; - _se->Flush(); - } - } - - UInt32 warningFlags = er.GetWarningFlags(); - - if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) - { - if (_so) - { - *_so << endl; - if (level != 0) - *_so << arc.Path << endl; - } - - if (warningFlags != 0) - { - if (_so) - PrintErrorFlags(*_so, "WARNINGS:", warningFlags); - NumOpenArcWarnings++; - ThereIsWarning_in_Current = true; - } - - if (!er.WarningMessage.IsEmpty()) - { - if (_so) - *_so << "WARNINGS:" << endl << er.WarningMessage << endl; - NumOpenArcWarnings++; - ThereIsWarning_in_Current = true; - } - - if (_so) - { - *_so << endl; - if (NeedFlush) - _so->Flush(); - } - } - - - if (er.ErrorFormatIndex >= 0) - { - if (_so) - { - Print_ErrorFormatIndex_Warning(_so, codecs, arc); - if (NeedFlush) - _so->Flush(); - } - ThereIsWarning_in_Current = true; - } - } - - if (result == S_OK) - { - if (_so) - { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); - *_so << endl; - } - } - else - { - NumCantOpenArcs++; - if (_so) - _so->Flush(); - if (_se) - { - *_se << kError << name << endl; - HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); - if (result == S_FALSE) - { - } - else - { - if (result == E_OUTOFMEMORY) - *_se << "Can't allocate required memory"; - else - *_se << NError::MyFormatMessage(result); - *_se << endl; - } - _se->Flush(); - } - } - - - return CheckBreak2(); -} - -HRESULT CExtractCallbackConsole::ThereAreNoFiles() -{ - ClosePercents_for_so(); - - if (_so) - { - *_so << endl << kNoFiles << endl; - if (NeedFlush) - _so->Flush(); - } - return CheckBreak2(); -} - -HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) -{ - MT_LOCK - - if (NeedPercents()) - { - _percent.ClosePrint(true); - _percent.Command.Empty(); - _percent.FileName.Empty(); - } - - if (_so) - _so->Flush(); - - if (result == S_OK) - { - if (NumFileErrors_in_Current == 0 && !ThereIsError_in_Current) - { - if (ThereIsWarning_in_Current) - NumArcsWithWarnings++; - else - NumOkArcs++; - if (_so) - *_so << kEverythingIsOk << endl; - } - else - { - NumArcsWithError++; - if (_so) - { - *_so << endl; - if (NumFileErrors_in_Current != 0) - *_so << "Sub items Errors: " << NumFileErrors_in_Current << endl; - } - } - if (_so && NeedFlush) - _so->Flush(); - } - else - { - NumArcsWithError++; - if (result == E_ABORT || result == ERROR_DISK_FULL) - return result; - - if (_se) - { - *_se << endl << kError; - if (result == E_OUTOFMEMORY) - *_se << kMemoryExceptionMessage; - else - *_se << NError::MyFormatMessage(result); - *_se << endl; - _se->Flush(); - } - } - - return CheckBreak2(); -} +// ExtractCallbackConsole.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/TimeUtils.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/PropVariantConv.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" + +#include "ConsoleClose.h" +#include "ExtractCallbackConsole.h" +#include "UserInputUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +static const char * const kError = "ERROR: "; + + +void CExtractScanConsole::StartScanning() +{ + if (NeedPercents()) + _percent.Command = "Scan"; +} + +HRESULT CExtractScanConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) +{ + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + _percent.Print(); + } + + return CheckBreak2(); +} + +HRESULT CExtractScanConsole::ScanError(const FString &path, DWORD systemError) +{ + // 22.00: + // ScanErrors.AddError(path, systemError); + + ClosePercentsAndFlush(); + + if (_se) + { + *_se << endl << kError << NError::MyFormatMessage(systemError) << endl; + _se->NormalizePrint_UString_Path(fs2us(path)); + *_se << endl << endl; + _se->Flush(); + } + return HRESULT_FROM_WIN32(systemError); + + // 22.00: commented + // CommonError(path, systemError, true); + // return S_OK; +} + + +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name); +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) +{ + char temp[32]; + ConvertUInt64ToString(val, temp); + s += temp; + s.Add_Space(); + s += name; +} + +void PrintSize_bytes_Smart(AString &s, UInt64 val); +void PrintSize_bytes_Smart(AString &s, UInt64 val) +{ + Print_UInt64_and_String(s, val, "bytes"); + + if (val == 0) + return; + + unsigned numBits = 10; + char c = 'K'; + char temp[4] = { 'K', 'i', 'B', 0 }; + if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; } + else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; } + temp[0] = c; + s += " ("; + Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp); + s.Add_Char(')'); +} + +static void PrintSize_bytes_Smart_comma(AString &s, UInt64 val) +{ + if (val == (UInt64)(Int64)-1) + return; + s += ", "; + PrintSize_bytes_Smart(s, val); +} + + + +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); +void Print_DirItemsStat(AString &s, const CDirItemsStat &st) +{ + if (st.NumDirs != 0) + { + Print_UInt64_and_String(s, st.NumDirs, st.NumDirs == 1 ? "folder" : "folders"); + s += ", "; + } + Print_UInt64_and_String(s, st.NumFiles, st.NumFiles == 1 ? "file" : "files"); + PrintSize_bytes_Smart_comma(s, st.FilesSize); + if (st.NumAltStreams != 0) + { + s.Add_LF(); + Print_UInt64_and_String(s, st.NumAltStreams, "alternate streams"); + PrintSize_bytes_Smart_comma(s, st.AltStreamsSize); + } +} + + +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st); +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st) +{ + Print_DirItemsStat(s, (CDirItemsStat &)st); + bool needLF = true; + if (st.Anti_NumDirs != 0) + { + if (needLF) + s.Add_LF(); + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumDirs, st.Anti_NumDirs == 1 ? "anti-folder" : "anti-folders"); + } + if (st.Anti_NumFiles != 0) + { + if (needLF) + s.Add_LF(); + else + s += ", "; + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumFiles, st.Anti_NumFiles == 1 ? "anti-file" : "anti-files"); + } + if (st.Anti_NumAltStreams != 0) + { + if (needLF) + s.Add_LF(); + else + s += ", "; + needLF = false; + Print_UInt64_and_String(s, st.Anti_NumAltStreams, "anti-alternate-streams"); + } +} + + +void CExtractScanConsole::PrintStat(const CDirItemsStat &st) +{ + if (_so) + { + AString s; + Print_DirItemsStat(s, st); + *_so << s << endl; + } +} + + + + + + + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + + +static const char * const kTestString = "T"; +static const char * const kExtractString = "-"; +static const char * const kSkipString = "."; +static const char * const kReadString = "H"; + +// static const char * const kCantAutoRename = "cannot create file with auto name\n"; +// static const char * const kCantRenameFile = "cannot rename existing file\n"; +// static const char * const kCantDeleteOutputFile = "cannot delete output file "; + +static const char * const kMemoryExceptionMessage = "Can't allocate required memory!"; + +static const char * const kExtracting = "Extracting archive: "; +static const char * const kTesting = "Testing archive: "; + +static const char * const kEverythingIsOk = "Everything is Ok"; +static const char * const kNoFiles = "No files to process"; + +static const char * const kUnsupportedMethod = "Unsupported Method"; +static const char * const kCrcFailed = "CRC Failed"; +static const char * const kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; +static const char * const kDataError = "Data Error"; +static const char * const kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; +static const char * const kUnavailableData = "Unavailable data"; +static const char * const kUnexpectedEnd = "Unexpected end of data"; +static const char * const kDataAfterEnd = "There are some data after the end of the payload data"; +static const char * const kIsNotArc = "Is not archive"; +static const char * const kHeadersError = "Headers Error"; +static const char * const kWrongPassword = "Wrong password"; + +static const char * const k_ErrorFlagsMessages[] = +{ + "Is not archive" + , "Headers Error" + , "Headers Error in encrypted archive. Wrong password?" + , "Unavailable start of archive" + , "Unconfirmed start of archive" + , "Unexpected end of archive" + , "There are data after the end of archive" + , "Unsupported method" + , "Unsupported feature" + , "Data Error" + , "CRC Error" +}; + +Z7_COM7F_IMF(CExtractCallbackConsole::SetTotal(UInt64 size)) +{ + MT_LOCK + + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackConsole::SetCompleted(const UInt64 *completeValue)) +{ + MT_LOCK + + if (NeedPercents()) + { + if (completeValue) + _percent.Completed = *completeValue; + _percent.Print(); + } + return CheckBreak2(); +} + +static const char * const kTab = " "; + +static void PrintFileInfo(CStdOutStream *_so, const wchar_t *path, const FILETIME *ft, const UInt64 *size) +{ + *_so << kTab << "Path: "; + _so->NormalizePrint_wstr_Path(path); + *_so << endl; + if (size && *size != (UInt64)(Int64)-1) + { + AString s; + PrintSize_bytes_Smart(s, *size); + *_so << kTab << "Size: " << s << endl; + } + if (ft) + { + char temp[64]; + if (ConvertUtcFileTimeToString(*ft, temp, kTimestampPrintLevel_SEC)) + *_so << kTab << "Modified: " << temp << endl; + } +} + +Z7_COM7F_IMF(CExtractCallbackConsole::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer)) +{ + MT_LOCK + + RINOK(CheckBreak2()) + + ClosePercentsAndFlush(); + + if (_so) + { + *_so << endl << "Would you like to replace the existing file:\n"; + PrintFileInfo(_so, existName, existTime, existSize); + *_so << "with the file from archive:\n"; + PrintFileInfo(_so, newName, newTime, newSize); + } + + NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(_so); + + switch ((int)overwriteAnswer) + { + case NUserAnswerMode::kQuit: return E_ABORT; + case NUserAnswerMode::kNo: *answer = NOverwriteAnswer::kNo; break; + case NUserAnswerMode::kNoAll: *answer = NOverwriteAnswer::kNoToAll; break; + case NUserAnswerMode::kYesAll: *answer = NOverwriteAnswer::kYesToAll; break; + case NUserAnswerMode::kYes: *answer = NOverwriteAnswer::kYes; break; + case NUserAnswerMode::kAutoRenameAll: *answer = NOverwriteAnswer::kAutoRename; break; + case NUserAnswerMode::kEof: return E_ABORT; + case NUserAnswerMode::kError: return E_FAIL; + default: return E_FAIL; + } + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 *position)) +{ + MT_LOCK + + _currentName = name; + + const char *s; + unsigned requiredLevel = 1; + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break; + case NArchive::NExtract::NAskMode::kTest: s = kTestString; break; + case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; requiredLevel = 2; break; + case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; requiredLevel = 0; break; + default: s = "???"; requiredLevel = 2; + } + + const bool show2 = (LogLevel >= requiredLevel && _so); + + if (show2) + { + ClosePercents_for_so(); + + _tempA = s; + if (name) + _tempA.Add_Space(); + *_so << _tempA; + + _tempU.Empty(); + if (name) + { + _tempU = name; + _so->Normalize_UString_Path(_tempU); + // 21.04 + if (isFolder) + { + if (!_tempU.IsEmpty() && _tempU.Back() != WCHAR_PATH_SEPARATOR) + _tempU.Add_PathSepar(); + } + } + _so->PrintUString(_tempU, _tempA); + if (position) + *_so << " <" << *position << ">"; + *_so << endl; + + if (NeedFlush) + _so->Flush(); + // _so->Flush(); // for debug only + } + + if (NeedPercents()) + { + if (PercentsNameLevel >= 1) + { + _percent.FileName.Empty(); + _percent.Command.Empty(); + if (PercentsNameLevel > 1 || !show2) + { + _percent.Command = s; + if (name) + _percent.FileName = name; + } + } + _percent.Print(); + } + + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackConsole::MessageError(const wchar_t *message)) +{ + MT_LOCK + + RINOK(CheckBreak2()) + + NumFileErrors_in_Current++; + NumFileErrors++; + + ClosePercentsAndFlush(); + if (_se) + { + *_se << kError << message << endl; + _se->Flush(); + } + + return CheckBreak2(); +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest); +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest) +{ + dest.Empty(); + const char *s = NULL; + + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + s = kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + s = (encrypted ? kCrcFailedEncrypted : kCrcFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + s = (encrypted ? kDataErrorEncrypted : kDataError); + break; + case NArchive::NExtract::NOperationResult::kUnavailable: + s = kUnavailableData; + break; + case NArchive::NExtract::NOperationResult::kUnexpectedEnd: + s = kUnexpectedEnd; + break; + case NArchive::NExtract::NOperationResult::kDataAfterEnd: + s = kDataAfterEnd; + break; + case NArchive::NExtract::NOperationResult::kIsNotArc: + s = kIsNotArc; + break; + case NArchive::NExtract::NOperationResult::kHeadersError: + s = kHeadersError; + break; + case NArchive::NExtract::NOperationResult::kWrongPassword: + s = kWrongPassword; + break; + default: break; + } + + dest += kError; + if (s) + dest += s; + else + { + dest += "Error #"; + dest.Add_UInt32((UInt32)opRes); + } +} + +Z7_COM7F_IMF(CExtractCallbackConsole::SetOperationResult(Int32 opRes, Int32 encrypted)) +{ + MT_LOCK + + if (opRes == NArchive::NExtract::NOperationResult::kOK) + { + if (NeedPercents()) + { + _percent.Command.Empty(); + _percent.FileName.Empty(); + _percent.Files++; + } + } + else + { + NumFileErrors_in_Current++; + NumFileErrors++; + + if (_se) + { + ClosePercentsAndFlush(); + + AString s; + SetExtractErrorMessage(opRes, encrypted, s); + + *_se << s; + if (!_currentName.IsEmpty()) + { + *_se << " : "; + _se->NormalizePrint_UString_Path(_currentName); + } + *_se << endl; + _se->Flush(); + } + } + + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackConsole::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + _currentName = name; + return SetOperationResult(opRes, encrypted); + } + + return CheckBreak2(); +} + + + +#ifndef Z7_NO_CRYPTO + +HRESULT CExtractCallbackConsole::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)) +{ + COM_TRY_BEGIN + MT_LOCK + return Open_CryptoGetTextPassword(password); + COM_TRY_END +} + +#endif + + +#ifndef Z7_SFX + +void CExtractCallbackConsole::PrintTo_se_Path_WithTitle(const UString &path, const char *title) +{ + *_se << title; + _se->NormalizePrint_UString_Path(path); + *_se << endl; +} + +void CExtractCallbackConsole::Add_ArchiveName_Error() +{ + if (_needWriteArchivePath) + { + PrintTo_se_Path_WithTitle(_currentArchivePath, "Archive: "); + _needWriteArchivePath = false; + } +} + + +Z7_COM7F_IMF(CExtractCallbackConsole::RequestMemoryUse( + UInt32 flags, UInt32 /* indexType */, UInt32 /* index */, const wchar_t *path, + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +{ + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0 + && requiredSize <= *allowedSize) + { +#if 0 + // it's expected, that *answerFlags was set to NRequestMemoryAnswerFlags::k_Allow already, + // because it's default answer for (requiredSize <= *allowedSize) case. + // optional code: + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; +#endif + } + else + { + if ((flags & NRequestMemoryUseFlags::k_NoErrorMessage) == 0) + if (_se) + { + const UInt64 num_GB_allowed = (*allowedSize + ((1u << 30) - 1)) >> 30; + const UInt64 num_GB_required = (requiredSize + ((1u << 30) - 1)) >> 30; + ClosePercentsAndFlush(); + Add_ArchiveName_Error(); + if (path) + PrintTo_se_Path_WithTitle(path, "File: "); + *_se << "The extraction operation requires big amount memory (RAM):" << endl + << " " << num_GB_required << " GB : required memory usage size" << endl + << " " << num_GB_allowed << " GB : allowed memory usage limit" << endl + << " Use -smemx{size}g switch to set allowed memory usage limit for extraction." << endl; + *_se << "ERROR: Memory usage limit was exceeded." << endl; + const char *m = NULL; + // if (indexType == NArchive::NEventIndexType::kNoIndex) + if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipArc)) + m = "Archive unpacking was skipped."; +/* + else if ((flags & NRequestMemoryUseFlags::k_SkipBigFiles_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipBigFiles)) + m = "Extraction for some files will be skipped."; + else if ((flags & NRequestMemoryUseFlags::k_SkipBigFile_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipBigFile)) + m = "File extraction was skipped."; +*/ + if (m) + *_se << m; + _se->Flush(); + } + + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + // default answer can be k_Allow, if limit was not forced, + // so we change answer to non-allowed here. + *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded; + if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc; +/* + else if (flags & NRequestMemoryUseFlags::k_SkipBigFile_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipBigFile; + else if (flags & NRequestMemoryUseFlags::k_SkipBigFiles_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipBigFiles; +*/ + } + } + return CheckBreak2(); +} + +#endif + + +HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name, bool testMode) +{ + _currentArchivePath = name; + _needWriteArchivePath = true; + + RINOK(CheckBreak2()) + + NumTryArcs++; + ThereIsError_in_Current = false; + ThereIsWarning_in_Current = false; + NumFileErrors_in_Current = 0; + + ClosePercents_for_so(); + if (_so) + { + *_so << endl << (testMode ? kTesting : kExtracting); + _so->NormalizePrint_wstr_Path(name); + *_so << endl; + } + + if (NeedPercents()) + _percent.Command = "Open"; + return S_OK; +} + +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); + +static AString GetOpenArcErrorMessage(UInt32 errorFlags) +{ + AString s; + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsMessages); i++) + { + UInt32 f = (1 << i); + if ((errorFlags & f) == 0) + continue; + const char *m = k_ErrorFlagsMessages[i]; + if (!s.IsEmpty()) + s.Add_LF(); + s += m; + errorFlags &= ~f; + } + + if (errorFlags != 0) + { + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(errorFlags, sz + 2); + if (!s.IsEmpty()) + s.Add_LF(); + s += sz; + } + + return s; +} + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags) +{ + if (errorFlags == 0) + return; + so << s << endl << GetOpenArcErrorMessage(errorFlags) << endl; +} + +static void Add_Messsage_Pre_ArcType(UString &s, const char *pre, const wchar_t *arcType) +{ + s.Add_LF(); + s += pre; + s += " as ["; + s += arcType; + s += "] archive"; +} + +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc); +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc) +{ + const CArcErrorInfo &er = arc.ErrorInfo; + + *_so << "WARNING:\n"; + _so->NormalizePrint_UString_Path(arc.Path); + UString s; + if (arc.FormatIndex == er.ErrorFormatIndex) + { + s.Add_LF(); + s += "The archive is open with offset"; + } + else + { + Add_Messsage_Pre_ArcType(s, "Cannot open the file", codecs->GetFormatNamePtr(er.ErrorFormatIndex)); + Add_Messsage_Pre_ArcType(s, "The file is open", codecs->GetFormatNamePtr(arc.FormatIndex)); + } + + *_so << s << endl << endl; +} + + +HRESULT CExtractCallbackConsole::OpenResult( + const CCodecs *codecs, const CArchiveLink &arcLink, + const wchar_t *name, HRESULT result) +{ + _currentArchivePath = name; + _needWriteArchivePath = true; + + ClosePercents(); + + if (NeedPercents()) + { + _percent.Files = 0; + _percent.Command.Empty(); + _percent.FileName.Empty(); + } + + + ClosePercentsAndFlush(); + + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + UInt32 errorFlags = er.GetErrorFlags(); + + if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) + { + if (_se) + { + *_se << endl; + if (level != 0) + { + _se->NormalizePrint_UString_Path(arc.Path); + *_se << endl; + } + } + + if (errorFlags != 0) + { + if (_se) + PrintErrorFlags(*_se, "ERRORS:", errorFlags); + NumOpenArcErrors++; + ThereIsError_in_Current = true; + } + + if (!er.ErrorMessage.IsEmpty()) + { + if (_se) + *_se << "ERRORS:" << endl << er.ErrorMessage << endl; + NumOpenArcErrors++; + ThereIsError_in_Current = true; + } + + if (_se) + { + *_se << endl; + _se->Flush(); + } + } + + UInt32 warningFlags = er.GetWarningFlags(); + + if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) + { + if (_so) + { + *_so << endl; + if (level != 0) + { + _so->NormalizePrint_UString_Path(arc.Path); + *_so << endl; + } + } + + if (warningFlags != 0) + { + if (_so) + PrintErrorFlags(*_so, "WARNINGS:", warningFlags); + NumOpenArcWarnings++; + ThereIsWarning_in_Current = true; + } + + if (!er.WarningMessage.IsEmpty()) + { + if (_so) + *_so << "WARNINGS:" << endl << er.WarningMessage << endl; + NumOpenArcWarnings++; + ThereIsWarning_in_Current = true; + } + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + + + if (er.ErrorFormatIndex >= 0) + { + if (_so) + { + Print_ErrorFormatIndex_Warning(_so, codecs, arc); + if (NeedFlush) + _so->Flush(); + } + ThereIsWarning_in_Current = true; + } + } + + if (result == S_OK) + { + if (_so) + { + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) + *_so << endl; + } + } + else + { + NumCantOpenArcs++; + if (_so) + _so->Flush(); + if (_se) + { + *_se << kError; + _se->NormalizePrint_wstr_Path(name); + *_se << endl; + const HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res) + if (result == S_FALSE) + { + } + else + { + if (result == E_OUTOFMEMORY) + *_se << "Can't allocate required memory"; + else + *_se << NError::MyFormatMessage(result); + *_se << endl; + } + _se->Flush(); + } + } + + + return CheckBreak2(); +} + +HRESULT CExtractCallbackConsole::ThereAreNoFiles() +{ + ClosePercents_for_so(); + + if (_so) + { + *_so << endl << kNoFiles << endl; + if (NeedFlush) + _so->Flush(); + } + return CheckBreak2(); +} + +HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) +{ + MT_LOCK + + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.Command.Empty(); + _percent.FileName.Empty(); + } + + if (_so) + _so->Flush(); + + if (result == S_OK) + { + if (NumFileErrors_in_Current == 0 && !ThereIsError_in_Current) + { + if (ThereIsWarning_in_Current) + NumArcsWithWarnings++; + else + NumOkArcs++; + if (_so) + *_so << kEverythingIsOk << endl; + } + else + { + NumArcsWithError++; + if (_so) + { + *_so << endl; + if (NumFileErrors_in_Current != 0) + *_so << "Sub items Errors: " << NumFileErrors_in_Current << endl; + } + } + if (_so && NeedFlush) + _so->Flush(); + } + else + { + // we don't update NumArcsWithError, if error is not related to archive data. + if (result == E_ABORT + || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)) + return result; + NumArcsWithError++; + + if (_se) + { + *_se << endl << kError; + if (result == E_OUTOFMEMORY) + *_se << kMemoryExceptionMessage; + else + *_se << NError::MyFormatMessage(result); + *_se << endl; + _se->Flush(); + } + } + + return CheckBreak2(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/ExtractCallbackConsole.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/ExtractCallbackConsole.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/ExtractCallbackConsole.h 2024-06-17 11:00:00.000000000 +0000 @@ -1,164 +1,211 @@ -// ExtractCallbackConsole.h - -#ifndef __EXTRACT_CALLBACK_CONSOLE_H -#define __EXTRACT_CALLBACK_CONSOLE_H - -#include "../../../Common/StdOutStream.h" - -#include "../../IPassword.h" - -#include "../../Archive/IArchive.h" - -#include "../Common/ArchiveExtractCallback.h" - -#include "PercentPrinter.h" - -#include "OpenCallbackConsole.h" - -class CExtractScanConsole: public IDirItemsCallback -{ - CStdOutStream *_so; - CStdOutStream *_se; - CPercentPrinter _percent; - - bool NeedPercents() const { return _percent._so != NULL; } - - void ClosePercentsAndFlush() - { - if (NeedPercents()) - _percent.ClosePrint(true); - if (_so) - _so->Flush(); - } - -public: - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) - { - _so = outStream; - _se = errorStream; - _percent._so = percentStream; - } - - void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } - - void StartScanning(); - - INTERFACE_IDirItemsCallback(;) - - void CloseScanning() - { - if (NeedPercents()) - _percent.ClosePrint(true); - } - - void PrintStat(const CDirItemsStat &st); -}; - - - - -class CExtractCallbackConsole: - public IExtractCallbackUI, - // public IArchiveExtractCallbackMessage, - public IFolderArchiveExtractCallback2, - #ifndef _NO_CRYPTO - public ICryptoGetTextPassword, - #endif - public COpenCallbackConsole, - public CMyUnknownImp -{ - AString _tempA; - UString _tempU; - - UString _currentName; - - void ClosePercents_for_so() - { - if (NeedPercents() && _so == _percent._so) - _percent.ClosePrint(false); - } - - void ClosePercentsAndFlush() - { - if (NeedPercents()) - _percent.ClosePrint(true); - if (_so) - _so->Flush(); - } - -public: - MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) - // MY_QUERYINTERFACE_ENTRY(IArchiveExtractCallbackMessage) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - STDMETHOD(SetTotal)(UInt64 total); - STDMETHOD(SetCompleted)(const UInt64 *completeValue); - - INTERFACE_IFolderArchiveExtractCallback(;) - - INTERFACE_IExtractCallbackUI(;) - // INTERFACE_IArchiveExtractCallbackMessage(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - - #ifndef _NO_CRYPTO - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - #endif - - UInt64 NumTryArcs; - - bool ThereIsError_in_Current; - bool ThereIsWarning_in_Current; - - UInt64 NumOkArcs; - UInt64 NumCantOpenArcs; - UInt64 NumArcsWithError; - UInt64 NumArcsWithWarnings; - - UInt64 NumOpenArcErrors; - UInt64 NumOpenArcWarnings; - - UInt64 NumFileErrors; - UInt64 NumFileErrors_in_Current; - - bool NeedFlush; - unsigned PercentsNameLevel; - unsigned LogLevel; - - CExtractCallbackConsole(): - NeedFlush(false), - PercentsNameLevel(1), - LogLevel(0) - {} - - void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } - - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) - { - COpenCallbackConsole::Init(outStream, errorStream, percentStream); - - NumTryArcs = 0; - - ThereIsError_in_Current = false; - ThereIsWarning_in_Current = false; - - NumOkArcs = 0; - NumCantOpenArcs = 0; - NumArcsWithError = 0; - NumArcsWithWarnings = 0; - - NumOpenArcErrors = 0; - NumOpenArcWarnings = 0; - - NumFileErrors = 0; - NumFileErrors_in_Current = 0; - } -}; - -#endif +// ExtractCallbackConsole.h + +#ifndef ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H +#define ZIP7_INC_EXTRACT_CALLBACK_CONSOLE_H + +#include "../../../Common/StdOutStream.h" + +#include "../../IPassword.h" + +#include "../../Archive/IArchive.h" + +#include "../Common/ArchiveExtractCallback.h" + +#include "PercentPrinter.h" + +#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 Z7_final: public IDirItemsCallback +{ + Z7_IFACE_IMP(IDirItemsCallback) + + CStdOutStream *_so; + CStdOutStream *_se; + CPercentPrinter _percent; + + // CErrorPathCodes2 ScanErrors; + + bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; } + + void ClosePercentsAndFlush() + { + if (NeedPercents()) + _percent.ClosePrint(true); + if (_so) + _so->Flush(); + } + +public: + + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) + { + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + _percent.DisablePrint = disablePercents; + } + + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void StartScanning(); + + void CloseScanning() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + void PrintStat(const CDirItemsStat &st); +}; + + + + +class CExtractCallbackConsole Z7_final: + public IFolderArchiveExtractCallback, + public IExtractCallbackUI, + // public IArchiveExtractCallbackMessage, + public IFolderArchiveExtractCallback2, + #ifndef Z7_NO_CRYPTO + public ICryptoGetTextPassword, + #endif + #ifndef Z7_SFX + public IArchiveRequestMemoryUseCallback, + #endif + + public COpenCallbackConsole, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) + // Z7_COM_QI_ENTRY(IArchiveExtractCallbackMessage) + Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + #ifndef Z7_SFX + Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback) + #endif + + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) + Z7_IFACE_IMP(IExtractCallbackUI) + // Z7_IFACE_COM7_IMP(IArchiveExtractCallbackMessage) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + #ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) + #endif + + bool _needWriteArchivePath; + +public: + bool ThereIsError_in_Current; + bool ThereIsWarning_in_Current; + bool NeedFlush; + +private: + AString _tempA; + UString _tempU; + + UString _currentArchivePath; + UString _currentName; + +#ifndef Z7_SFX + void PrintTo_se_Path_WithTitle(const UString &path, const char *title); + void Add_ArchiveName_Error(); +#endif + + void ClosePercents_for_so() + { + if (NeedPercents() && _so == _percent._so) + _percent.ClosePrint(false); + } + + void ClosePercentsAndFlush() + { + if (NeedPercents()) + _percent.ClosePrint(true); + if (_so) + _so->Flush(); + } +public: + UInt64 NumTryArcs; + + UInt64 NumOkArcs; + UInt64 NumCantOpenArcs; + UInt64 NumArcsWithError; + UInt64 NumArcsWithWarnings; + + UInt64 NumOpenArcErrors; + UInt64 NumOpenArcWarnings; + + UInt64 NumFileErrors; + UInt64 NumFileErrors_in_Current; + + unsigned PercentsNameLevel; + unsigned LogLevel; + + CExtractCallbackConsole(): + _needWriteArchivePath(true), + NeedFlush(false), + PercentsNameLevel(1), + LogLevel(0) + {} + + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) + { + COpenCallbackConsole::Init(outStream, errorStream, percentStream, disablePercents); + + NumTryArcs = 0; + + ThereIsError_in_Current = false; + ThereIsWarning_in_Current = false; + + NumOkArcs = 0; + NumCantOpenArcs = 0; + NumArcsWithError = 0; + NumArcsWithWarnings = 0; + + NumOpenArcErrors = 0; + NumOpenArcWarnings = 0; + + NumFileErrors = 0; + NumFileErrors_in_Current = 0; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/HashCon.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/HashCon.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.cpp 2024-02-09 10:00:00.000000000 +0000 @@ -1,367 +1,426 @@ -// HashCon.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "ConsoleClose.h" -#include "HashCon.h" - -static const wchar_t *kEmptyFileAlias = L"[Content]"; - -static const char *kScanningMessage = "Scanning"; - -static HRESULT CheckBreak2() -{ - return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; -} - -HRESULT CHashCallbackConsole::CheckBreak() -{ - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::StartScanning() -{ - if (PrintHeaders && _so) - *_so << kScanningMessage << endl; - if (NeedPercents()) - { - _percent.ClearCurState(); - _percent.Command = "Scan"; - } - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) -{ - if (NeedPercents()) - { - _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; - _percent.Completed = st.GetTotalBytes(); - _percent.FileName = fs2us(path); - _percent.Print(); - } - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError) -{ - return ScanError_Base(path, systemError); -} - -void Print_DirItemsStat(AString &s, const CDirItemsStat &st); - -HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st) -{ - if (NeedPercents()) - { - _percent.ClosePrint(true); - _percent.ClearCurState(); - } - if (PrintHeaders && _so) - { - Print_DirItemsStat(_s, st); - *_so << _s << endl << endl; - } - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */) -{ - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::SetTotal(UInt64 size) -{ - if (NeedPercents()) - { - _percent.Total = size; - _percent.Print(); - } - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue) -{ - if (completeValue && NeedPercents()) - { - _percent.Completed = *completeValue; - _percent.Print(); - } - return CheckBreak2(); -} - -static void AddMinuses(AString &s, unsigned num) -{ - for (unsigned i = 0; i < num; i++) - s += '-'; -} - -static void AddSpaces_if_Positive(AString &s, int num) -{ - for (int i = 0; i < num; i++) - s.Add_Space(); -} - -static void SetSpacesAndNul(char *s, unsigned num) -{ - for (unsigned i = 0; i < num; i++) - s[i] = ' '; - s[num] = 0; -} - -static const unsigned kSizeField_Len = 13; -static const unsigned kNameField_Len = 12; - -static const unsigned kHashColumnWidth_Min = 4 * 2; - -static unsigned GetColumnWidth(unsigned digestSize) -{ - unsigned width = digestSize * 2; - return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; -} - -void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector &hashers) -{ - _s.Empty(); - - for (unsigned i = 0; i < hashers.Size(); i++) - { - if (i != 0) - _s.Add_Space(); - const CHasherState &h = hashers[i]; - AddMinuses(_s, GetColumnWidth(h.DigestSize)); - } - - if (PrintSize) - { - _s.Add_Space(); - AddMinuses(_s, kSizeField_Len); - } - - if (PrintName) - { - AddSpacesBeforeName(); - AddMinuses(_s, kNameField_Len); - } - - *_so << _s << endl; -} - -HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb) -{ - if (PrintHeaders && _so) - { - _s.Empty(); - ClosePercents_for_so(); - - FOR_VECTOR (i, hb.Hashers) - { - if (i != 0) - _s.Add_Space(); - const CHasherState &h = hb.Hashers[i]; - _s += h.Name; - AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len()); - } - - if (PrintSize) - { - _s.Add_Space(); - const AString s2 = "Size"; - AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len()); - _s += s2; - } - - if (PrintName) - { - AddSpacesBeforeName(); - _s += "Name"; - } - - *_so << _s << endl; - PrintSeparatorLine(hb.Hashers); - } - - return CheckBreak2(); -} - -HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError) -{ - return OpenFileError_Base(path, systemError); -} - -HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */) -{ - _fileName = name; - - if (NeedPercents()) - { - if (PrintNameInPercents) - { - _percent.FileName.Empty(); - if (name) - _percent.FileName = name; - } - _percent.Print(); - } - return CheckBreak2(); -} - -void CHashCallbackConsole::PrintResultLine(UInt64 fileSize, - const CObjectVector &hashers, unsigned digestIndex, bool showHash) -{ - ClosePercents_for_so(); - - _s.Empty(); - - FOR_VECTOR (i, hashers) - { - const CHasherState &h = hashers[i]; - char s[k_HashCalc_DigestSize_Max * 2 + 64]; - s[0] = 0; - if (showHash) - AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); - SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s)); - if (i != 0) - _s.Add_Space(); - _s += s; - } - - if (PrintSize) - { - _s.Add_Space(); - - char s[kSizeField_Len + 32]; - char *p = s; - - if (showHash) - { - p = s + kSizeField_Len; - ConvertUInt64ToString(fileSize, p); - int numSpaces = kSizeField_Len - (int)strlen(p); - if (numSpaces > 0) - { - p -= (unsigned)numSpaces; - for (unsigned i = 0; i < (unsigned)numSpaces; i++) - p[i] = ' '; - } - } - else - SetSpacesAndNul(s, kSizeField_Len); - - _s += p; - } - - if (PrintName) - AddSpacesBeforeName(); - - *_so << _s; -} - -HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) -{ - if (_so) - { - PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash); - if (PrintName) - { - if (_fileName.IsEmpty()) - *_so << kEmptyFileAlias; - else - *_so << _fileName; - } - *_so << endl; - } - - if (NeedPercents()) - { - _percent.Files++; - _percent.Print(); - } - - return CheckBreak2(); -} - -static const char *k_DigestTitles[] = -{ - " : " - , " for data: " - , " for data and names: " - , " for streams and names: " -}; - -static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex) -{ - so << h.Name; - - { - AString temp; - AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len()); - so << temp; - } - - so << k_DigestTitles[digestIndex]; - - char s[k_HashCalc_DigestSize_Max * 2 + 64]; - s[0] = 0; - AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize); - so << s << endl; -} - -void PrintHashStat(CStdOutStream &so, const CHashBundle &hb) -{ - FOR_VECTOR (i, hb.Hashers) - { - const CHasherState &h = hb.Hashers[i]; - PrintSum(so, h, k_HashCalc_Index_DataSum); - if (hb.NumFiles != 1 || hb.NumDirs != 0) - PrintSum(so, h, k_HashCalc_Index_NamesSum); - if (hb.NumAltStreams != 0) - PrintSum(so, h, k_HashCalc_Index_StreamsSum); - so << endl; - } -} - -void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value) -{ - char s[32]; - s[0] = ':'; - s[1] = ' '; - ConvertUInt64ToString(value, s + 2); - *_so << name << s << endl; -} - -HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb) -{ - ClosePercents2(); - - if (PrintHeaders && _so) - { - PrintSeparatorLine(hb.Hashers); - - PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true); - - *_so << endl << endl; - - if (hb.NumFiles != 1 || hb.NumDirs != 0) - { - if (hb.NumDirs != 0) - PrintProperty("Folders", hb.NumDirs); - PrintProperty("Files", hb.NumFiles); - } - - PrintProperty("Size", hb.FilesSize); - - if (hb.NumAltStreams != 0) - { - PrintProperty("Alternate streams", hb.NumAltStreams); - PrintProperty("Alternate streams size", hb.AltStreamsSize); - } - - *_so << endl; - PrintHashStat(*_so, hb); - } - - return S_OK; -} +// HashCon.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/FileName.h" + +#include "ConsoleClose.h" +#include "HashCon.h" + +static const char * const kEmptyFileAlias = "[Content]"; + +static const char * const kScanningMessage = "Scanning"; + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +HRESULT CHashCallbackConsole::CheckBreak() +{ + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::StartScanning() +{ + if (PrintHeaders && _so) + *_so << kScanningMessage << endl; + if (NeedPercents()) + { + _percent.ClearCurState(); + _percent.Command = "Scan"; + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) +{ + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_percent.FileName); + _percent.Print(); + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError) +{ + return ScanError_Base(path, systemError); +} + +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); + +HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st) +{ + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.ClearCurState(); + } + if (PrintHeaders && _so) + { + Print_DirItemsStat(_s, st); + *_so << _s << endl << endl; + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */) +{ + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetTotal(UInt64 size) +{ + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + if (completeValue && NeedPercents()) + { + _percent.Completed = *completeValue; + _percent.Print(); + } + return CheckBreak2(); +} + +static void AddMinuses(AString &s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s.Add_Minus(); +} + +static void AddSpaces_if_Positive(AString &s, int num) +{ + for (int i = 0; i < num; i++) + s.Add_Space(); +} + +static void SetSpacesAndNul(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + +static void SetSpacesAndNul_if_Positive(char *s, int num) +{ + if (num < 0) + return; + for (int i = 0; i < num; i++) + s[i] = ' '; + s[num] = 0; +} + +static const unsigned kSizeField_Len = 13; +static const unsigned kNameField_Len = 12; + +static const unsigned kHashColumnWidth_Min = 4 * 2; + +static unsigned GetColumnWidth(unsigned digestSize) +{ + unsigned width = digestSize * 2; + return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width; +} + + +AString CHashCallbackConsole::GetFields() const +{ + AString s (PrintFields); + if (s.IsEmpty()) + s = "hsn"; + s.MakeLower_Ascii(); + return s; +} + + +void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector &hashers) +{ + _s.Empty(); + const AString fields = GetFields(); + for (unsigned pos = 0; pos < fields.Len(); pos++) + { + const char c = fields[pos]; + if (c == 'h') + { + for (unsigned i = 0; i < hashers.Size(); i++) + { + AddSpace(); + const CHasherState &h = hashers[i]; + AddMinuses(_s, GetColumnWidth(h.DigestSize)); + } + } + else if (c == 's') + { + AddSpace(); + AddMinuses(_s, kSizeField_Len); + } + else if (c == 'n') + { + AddSpacesBeforeName(); + AddMinuses(_s, kNameField_Len); + } + } + + *_so << _s << endl; +} + + +HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb) +{ + if (PrintHeaders && _so) + { + _s.Empty(); + ClosePercents_for_so(); + + const AString fields = GetFields(); + for (unsigned pos = 0; pos < fields.Len(); pos++) + { + const char c = fields[pos]; + if (c == 'h') + { + FOR_VECTOR (i, hb.Hashers) + { + AddSpace(); + const CHasherState &h = hb.Hashers[i]; + _s += h.Name; + AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len()); + } + } + + else if (c == 's') + { + AddSpace(); + const AString s2 ("Size"); + AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len()); + _s += s2; + } + else if (c == 'n') + { + AddSpacesBeforeName(); + _s += "Name"; + } + } + + *_so << _s << endl; + PrintSeparatorLine(hb.Hashers); + } + + return CheckBreak2(); +} + +HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError) +{ + return OpenFileError_Base(path, systemError); +} + +HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool isDir) +{ + _fileName = name; + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_fileName); + + if (NeedPercents()) + { + if (PrintNameInPercents) + { + _percent.FileName.Empty(); + if (name) + _percent.FileName = name; + } + _percent.Print(); + } + return CheckBreak2(); +} + + +static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16; + + + +void CHashCallbackConsole::PrintResultLine(UInt64 fileSize, + const CObjectVector &hashers, unsigned digestIndex, bool showHash, + const AString &path) +{ + ClosePercents_for_so(); + + _s.Empty(); + const AString fields = GetFields(); + + for (unsigned pos = 0; pos < fields.Len(); pos++) + { + const char c = fields[pos]; + if (c == 'h') + { + FOR_VECTOR (i, hashers) + { + AddSpace(); + const CHasherState &h = hashers[i]; + char s[k_DigestStringSize]; + s[0] = 0; + if (showHash) + h.WriteToString(digestIndex, s); + const unsigned len = (unsigned)strlen(s); + SetSpacesAndNul_if_Positive(s + len, (int)GetColumnWidth(h.DigestSize) - (int)len); + _s += s; + } + } + else if (c == 's') + { + AddSpace(); + char s[kSizeField_Len + 32]; + char *p = s; + SetSpacesAndNul(s, kSizeField_Len); + if (showHash) + { + p = s + kSizeField_Len; + ConvertUInt64ToString(fileSize, p); + const int numSpaces = (int)kSizeField_Len - (int)strlen(p); + if (numSpaces > 0) + p -= (unsigned)numSpaces; + } + _s += p; + } + else if (c == 'n') + { + AddSpacesBeforeName(); + _s += path; + } + } + + *_so << _s; +} + + +HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) +{ + if (_so) + { + AString s; + if (_fileName.IsEmpty()) + s = kEmptyFileAlias; + else + { + UString temp (_fileName); + _so->Normalize_UString_Path(temp); + _so->Convert_UString_to_AString(temp, s); + } + PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash, s); + + /* + PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash); + if (PrintName) + { + if (_fileName.IsEmpty()) + *_so << kEmptyFileAlias; + else + _so->NormalizePrint_UString(_fileName); + } + */ + // if (PrintNewLine) + *_so << endl; + } + + if (NeedPercents()) + { + _percent.Files++; + _percent.Print(); + } + + return CheckBreak2(); +} + +static const char * const k_DigestTitles[] = +{ + " : " + , " for data: " + , " for data and names: " + , " for streams and names: " +}; + +static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex) +{ + so << h.Name; + + { + AString temp; + AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len()); + so << temp; + } + + so << k_DigestTitles[digestIndex]; + + char s[k_DigestStringSize]; + // s[0] = 0; + h.WriteToString(digestIndex, s); + so << s << endl; +} + +void PrintHashStat(CStdOutStream &so, const CHashBundle &hb) +{ + FOR_VECTOR (i, hb.Hashers) + { + const CHasherState &h = hb.Hashers[i]; + PrintSum(so, h, k_HashCalc_Index_DataSum); + if (hb.NumFiles != 1 || hb.NumDirs != 0) + PrintSum(so, h, k_HashCalc_Index_NamesSum); + if (hb.NumAltStreams != 0) + PrintSum(so, h, k_HashCalc_Index_StreamsSum); + so << endl; + } +} + +void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value) +{ + char s[32]; + s[0] = ':'; + s[1] = ' '; + ConvertUInt64ToString(value, s + 2); + *_so << name << s << endl; +} + +HRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb) +{ + ClosePercents2(); + + if (PrintHeaders && _so) + { + PrintSeparatorLine(hb.Hashers); + + PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true, AString()); + + *_so << endl << endl; + + if (hb.NumFiles != 1 || hb.NumDirs != 0) + { + if (hb.NumDirs != 0) + PrintProperty("Folders", hb.NumDirs); + PrintProperty("Files", hb.NumFiles); + } + + PrintProperty("Size", hb.FilesSize); + + if (hb.NumAltStreams != 0) + { + PrintProperty("Alternate streams", hb.NumAltStreams); + PrintProperty("Alternate streams size", hb.AltStreamsSize); + } + + *_so << endl; + PrintHashStat(*_so, hb); + } + + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/HashCon.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/HashCon.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/HashCon.h 2023-04-03 07:00:00.000000000 +0000 @@ -1,48 +1,58 @@ -// HashCon.h - -#ifndef __HASH_CON_H -#define __HASH_CON_H - -#include "../Common/HashCalc.h" - -#include "UpdateCallbackConsole.h" - -class CHashCallbackConsole: public IHashCallbackUI, public CCallbackConsoleBase -{ - UString _fileName; - AString _s; - - void AddSpacesBeforeName() - { - _s.Add_Space(); - _s.Add_Space(); - } - - void PrintSeparatorLine(const CObjectVector &hashers); - void PrintResultLine(UInt64 fileSize, - const CObjectVector &hashers, unsigned digestIndex, bool showHash); - void PrintProperty(const char *name, UInt64 value); - -public: - bool PrintNameInPercents; - - bool PrintHeaders; - - bool PrintSize; - bool PrintName; - - CHashCallbackConsole(): - PrintNameInPercents(true), - PrintHeaders(false), - PrintSize(true), - PrintName(true) - {} - - ~CHashCallbackConsole() { } - - INTERFACE_IHashCallbackUI(;) -}; - -void PrintHashStat(CStdOutStream &so, const CHashBundle &hb); - -#endif +// HashCon.h + +#ifndef ZIP7_INC_HASH_CON_H +#define ZIP7_INC_HASH_CON_H + +#include "../Common/HashCalc.h" + +#include "UpdateCallbackConsole.h" + +class CHashCallbackConsole Z7_final: + public IHashCallbackUI, + public CCallbackConsoleBase +{ + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IHashCallbackUI) + + UString _fileName; + AString _s; + + void AddSpace() + { + _s.Add_Space_if_NotEmpty(); + } + + void AddSpacesBeforeName() + { + if (!_s.IsEmpty()) + { + _s.Add_Space(); + _s.Add_Space(); + } + } + + void PrintSeparatorLine(const CObjectVector &hashers); + void PrintResultLine(UInt64 fileSize, + const CObjectVector &hashers, unsigned digestIndex, bool showHash, const AString &path); + void PrintProperty(const char *name, UInt64 value); + +public: + bool PrintNameInPercents; + bool PrintHeaders; + // bool PrintSize; + // bool PrintNewLine; // set it too (false), if you need only hash for single file without LF char. + AString PrintFields; + + AString GetFields() const; + + CHashCallbackConsole(): + PrintNameInPercents(true), + PrintHeaders(false) + // , PrintSize(true), + // , PrintNewLine(true) + {} +}; + +void PrintHashStat(CStdOutStream &so, const CHashBundle &hb); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/List.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/List.cpp 2016-05-20 08:47:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.cpp 2024-06-06 06:00:00.000000000 +0000 @@ -1,1295 +1,1417 @@ -// List.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/MyCom.h" -#include "../../../Common/StdOutStream.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../Common/OpenArchive.h" -#include "../Common/PropIDUtils.h" - -#include "ConsoleClose.h" -#include "List.h" -#include "OpenCallbackConsole.h" - -using namespace NWindows; -using namespace NCOM; - -extern CStdOutStream *g_StdStream; -extern CStdOutStream *g_ErrStream; - -static const char * const kPropIdToName[] = -{ - "0" - , "1" - , "2" - , "Path" - , "Name" - , "Extension" - , "Folder" - , "Size" - , "Packed Size" - , "Attributes" - , "Created" - , "Accessed" - , "Modified" - , "Solid" - , "Commented" - , "Encrypted" - , "Split Before" - , "Split After" - , "Dictionary Size" - , "CRC" - , "Type" - , "Anti" - , "Method" - , "Host OS" - , "File System" - , "User" - , "Group" - , "Block" - , "Comment" - , "Position" - , "Path Prefix" - , "Folders" - , "Files" - , "Version" - , "Volume" - , "Multivolume" - , "Offset" - , "Links" - , "Blocks" - , "Volumes" - , "Time Type" - , "64-bit" - , "Big-endian" - , "CPU" - , "Physical Size" - , "Headers Size" - , "Checksum" - , "Characteristics" - , "Virtual Address" - , "ID" - , "Short Name" - , "Creator Application" - , "Sector Size" - , "Mode" - , "Symbolic Link" - , "Error" - , "Total Size" - , "Free Space" - , "Cluster Size" - , "Label" - , "Local Name" - , "Provider" - , "NT Security" - , "Alternate Stream" - , "Aux" - , "Deleted" - , "Tree" - , "SHA-1" - , "SHA-256" - , "Error Type" - , "Errors" - , "Errors" - , "Warnings" - , "Warning" - , "Streams" - , "Alternate Streams" - , "Alternate Streams Size" - , "Virtual Size" - , "Unpack Size" - , "Total Physical Size" - , "Volume Index" - , "SubType" - , "Short Comment" - , "Code Page" - , "Is not archive type" - , "Physical Size can't be detected" - , "Zeros Tail Is Allowed" - , "Tail Size" - , "Embedded Stub Size" - , "Link" - , "Hard Link" - , "iNode" - , "Stream ID" - , "Read-only" - , "Out Name" - , "Copy Link" -}; - -static const char kEmptyAttribChar = '.'; - -static const char *kListing = "Listing archive: "; - -static const char *kString_Files = "files"; -static const char *kString_Dirs = "folders"; -static const char *kString_AltStreams = "alternate streams"; -static const char *kString_Streams = "streams"; - -static const char *kError = "ERROR: "; - -static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s) -{ - if (isDir) - wa |= FILE_ATTRIBUTE_DIRECTORY; - if (allAttribs) - { - ConvertWinAttribToString(s, wa); - return; - } - s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'D': kEmptyAttribChar; - s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar; - s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar; - s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar; - s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar; - s[5] = 0; -} - -enum EAdjustment -{ - kLeft, - kCenter, - kRight -}; - -struct CFieldInfo -{ - PROPID PropID; - bool IsRawProp; - UString NameU; - AString NameA; - EAdjustment TitleAdjustment; - EAdjustment TextAdjustment; - unsigned PrefixSpacesWidth; - unsigned Width; -}; - -struct CFieldInfoInit -{ - PROPID PropID; - const char *Name; - EAdjustment TitleAdjustment; - EAdjustment TextAdjustment; - unsigned PrefixSpacesWidth; - unsigned Width; -}; - -static const CFieldInfoInit kStandardFieldTable[] = -{ - { kpidMTime, " Date Time", kLeft, kLeft, 0, 19 }, - { kpidAttrib, "Attr", kRight, kCenter, 1, 5 }, - { kpidSize, "Size", kRight, kRight, 1, 12 }, - { kpidPackSize, "Compressed", kRight, kRight, 1, 12 }, - { kpidPath, "Name", kLeft, kLeft, 2, 24 } -}; - -const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width -static const char *g_Spaces = -" " ; - -static void PrintSpaces(unsigned numSpaces) -{ - if (numSpaces > 0 && numSpaces <= kNumSpacesMax) - g_StdOut << g_Spaces + (kNumSpacesMax - numSpaces); -} - -static void PrintSpacesToString(char *dest, unsigned numSpaces) -{ - unsigned i; - for (i = 0; i < numSpaces; i++) - dest[i] = ' '; - dest[i] = 0; -} - -// extern int g_CodePage; - -static void PrintUString(EAdjustment adj, unsigned width, const UString &s, AString &temp) -{ - /* - // we don't need multibyte align. - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - if (codePage == CP_UTF8) - ConvertUnicodeToUTF8(s, temp); - else - UnicodeStringToMultiByte2(temp, s, (UINT)codePage); - */ - - unsigned numSpaces = 0; - - if (width > s.Len()) - { - numSpaces = width - s.Len(); - unsigned numLeftSpaces = 0; - switch (adj) - { - case kLeft: numLeftSpaces = 0; break; - case kCenter: numLeftSpaces = numSpaces / 2; break; - case kRight: numLeftSpaces = numSpaces; break; - } - PrintSpaces(numLeftSpaces); - numSpaces -= numLeftSpaces; - } - - g_StdOut.PrintUString(s, temp); - PrintSpaces(numSpaces); -} - -static void PrintString(EAdjustment adj, unsigned width, const char *s) -{ - unsigned numSpaces = 0; - unsigned len = (unsigned)strlen(s); - - if (width > len) - { - numSpaces = width - len; - unsigned numLeftSpaces = 0; - switch (adj) - { - case kLeft: numLeftSpaces = 0; break; - case kCenter: numLeftSpaces = numSpaces / 2; break; - case kRight: numLeftSpaces = numSpaces; break; - } - PrintSpaces(numLeftSpaces); - numSpaces -= numLeftSpaces; - } - - g_StdOut << s; - PrintSpaces(numSpaces); -} - -static void PrintStringToString(char *dest, EAdjustment adj, unsigned width, const char *textString) -{ - unsigned numSpaces = 0; - unsigned len = (unsigned)strlen(textString); - - if (width > len) - { - numSpaces = width - len; - unsigned numLeftSpaces = 0; - switch (adj) - { - case kLeft: numLeftSpaces = 0; break; - case kCenter: numLeftSpaces = numSpaces / 2; break; - case kRight: numLeftSpaces = numSpaces; break; - } - PrintSpacesToString(dest, numLeftSpaces); - dest += numLeftSpaces; - numSpaces -= numLeftSpaces; - } - - memcpy(dest, textString, len); - dest += len; - PrintSpacesToString(dest, numSpaces); -} - -struct CListUInt64Def -{ - UInt64 Val; - bool Def; - - CListUInt64Def(): Val(0), Def(false) {} - void Add(UInt64 v) { Val += v; Def = true; } - 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; } - void Update(const CListFileTimeDef &t) - { - if (t.Def && (!Def || CompareFileTime(&Val, &t.Val) < 0)) - { - Val = t.Val; - Def = true; - } - } -}; - -struct CListStat -{ - CListUInt64Def Size; - CListUInt64Def PackSize; - CListFileTimeDef MTime; - UInt64 NumFiles; - - CListStat(): NumFiles(0) {} - void Update(const CListStat &st) - { - Size.Add(st.Size); - PackSize.Add(st.PackSize); - MTime.Update(st.MTime); - NumFiles += st.NumFiles; - } - void SetSizeDefIfNoFiles() { if (NumFiles == 0) Size.Def = true; } -}; - -struct CListStat2 -{ - CListStat MainFiles; - CListStat AltStreams; - UInt64 NumDirs; - - CListStat2(): NumDirs(0) {} - - void Update(const CListStat2 &st) - { - MainFiles.Update(st.MainFiles); - AltStreams.Update(st.AltStreams); - NumDirs += st.NumDirs; - } - const UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; } - CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; } -}; - -class CFieldPrinter -{ - CObjectVector _fields; - - void AddProp(const wchar_t *name, PROPID propID, bool isRawProp); -public: - const CArc *Arc; - bool TechMode; - UString FilePath; - AString TempAString; - UString TempWString; - bool IsDir; - - AString LinesString; - - void Clear() { _fields.Clear(); LinesString.Empty(); } - void Init(const CFieldInfoInit *standardFieldTable, unsigned numItems); - - HRESULT AddMainProps(IInArchive *archive); - HRESULT AddRawProps(IArchiveGetRawProps *getRawProps); - - void PrintTitle(); - void PrintTitleLines(); - HRESULT PrintItemInfo(UInt32 index, const CListStat &st); - void PrintSum(const CListStat &st, UInt64 numDirs, const char *str); - void PrintSum(const CListStat2 &stat2); -}; - -void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numItems) -{ - Clear(); - for (unsigned i = 0; i < numItems; i++) - { - CFieldInfo &f = _fields.AddNew(); - const CFieldInfoInit &fii = standardFieldTable[i]; - f.PropID = fii.PropID; - f.IsRawProp = false; - f.NameA = fii.Name; - f.TitleAdjustment = fii.TitleAdjustment; - f.TextAdjustment = fii.TextAdjustment; - f.PrefixSpacesWidth = fii.PrefixSpacesWidth; - f.Width = fii.Width; - - unsigned k; - for (k = 0; k < fii.PrefixSpacesWidth; k++) - LinesString.Add_Space(); - for (k = 0; k < fii.Width; k++) - LinesString += '-'; - } -} - -static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU) -{ - if (propID < ARRAY_SIZE(kPropIdToName)) - { - nameA = kPropIdToName[propID]; - return; - } - if (name) - nameU = name; - else - { - char s[16]; - ConvertUInt32ToString(propID, s); - nameA = s; - } -} - -void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp) -{ - CFieldInfo f; - f.PropID = propID; - f.IsRawProp = isRawProp; - GetPropName(propID, name, f.NameA, f.NameU); - f.NameU.AddAscii(" = "); - if (!f.NameA.IsEmpty()) - f.NameA += " = "; - else - { - const UString &s = f.NameU; - AString sA; - unsigned i; - for (i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if (c >= 0x80) - break; - sA += (char)c; - } - if (i == s.Len()) - f.NameA = sA; - } - _fields.Add(f); -} - -HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) -{ - UInt32 numProps; - RINOK(archive->GetNumberOfProperties(&numProps)); - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); - AddProp(name, propID, false); - } - return S_OK; -} - -HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps) -{ - UInt32 numProps; - RINOK(getRawProps->GetNumRawProps(&numProps)); - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)); - AddProp(name, propID, true); - } - return S_OK; -} - -void CFieldPrinter::PrintTitle() -{ - FOR_VECTOR (i, _fields) - { - const CFieldInfo &f = _fields[i]; - PrintSpaces(f.PrefixSpacesWidth); - PrintString(f.TitleAdjustment, ((f.PropID == kpidPath) ? 0: f.Width), f.NameA); - } -} - -void CFieldPrinter::PrintTitleLines() -{ - g_StdOut << LinesString; -} - -static void PrintTime(char *dest, const FILETIME *ft) -{ - *dest = 0; - if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0) - return; - FILETIME locTime; - if (!FileTimeToLocalFileTime(ft, &locTime)) - throw 20121211; - ConvertFileTimeToString(locTime, dest, true, true); -} - -#ifndef _SFX - -static inline char GetHex(Byte value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} - -static void HexToString(char *dest, const Byte *data, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) - { - Byte b = data[i]; - dest[0] = GetHex((Byte)((b >> 4) & 0xF)); - dest[1] = GetHex((Byte)(b & 0xF)); - dest += 2; - } - *dest = 0; -} - -#endif - -#define MY_ENDL endl - -HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) -{ - char temp[128]; - size_t tempPos = 0; - - bool techMode = this->TechMode; - /* - if (techMode) - { - g_StdOut << "Index = "; - g_StdOut << (UInt64)index; - g_StdOut << endl; - } - */ - FOR_VECTOR (i, _fields) - { - const CFieldInfo &f = _fields[i]; - - if (!techMode) - { - PrintSpacesToString(temp + tempPos, f.PrefixSpacesWidth); - tempPos += f.PrefixSpacesWidth; - } - - if (techMode) - { - if (!f.NameA.IsEmpty()) - g_StdOut << f.NameA; - else - g_StdOut << f.NameU; - } - - if (f.PropID == kpidPath) - { - if (!techMode) - g_StdOut << temp; - g_StdOut.PrintUString(FilePath, TempAString); - if (techMode) - g_StdOut << MY_ENDL; - continue; - } - - const unsigned width = f.Width; - - if (f.IsRawProp) - { - #ifndef _SFX - - const void *data; - UInt32 dataSize; - UInt32 propType; - RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)); - - if (dataSize != 0) - { - bool needPrint = true; - - if (f.PropID == kpidNtSecure) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - #ifndef _SFX - ConvertNtSecureToString((const Byte *)data, dataSize, TempAString); - g_StdOut << TempAString; - needPrint = false; - #endif - } -#ifdef _WIN32 - else if (f.PropID == kpidNtReparse) - { - UString s; - if (ConvertNtReparseToString((const Byte *)data, dataSize, s)) - { - needPrint = false; - g_StdOut.PrintUString(s, TempAString); - } - } -#endif - - if (needPrint) - { - if (propType != NPropDataType::kRaw) - return E_FAIL; - - const UInt32 kMaxDataSize = 64; - - if (dataSize > kMaxDataSize) - { - g_StdOut << "data:"; - g_StdOut << dataSize; - } - else - { - char hexStr[kMaxDataSize * 2 + 4]; - HexToString(hexStr, (const Byte *)data, dataSize); - g_StdOut << hexStr; - } - } - } - - #endif - } - else - { - CPropVariant prop; - switch (f.PropID) - { - 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; - default: - RINOK(Arc->Archive->GetProperty(index, f.PropID, &prop)); - } - if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) - { - GetAttribString((prop.vt == VT_EMPTY) ? 0 : prop.ulVal, IsDir, techMode, temp + tempPos); - if (techMode) - g_StdOut << temp + tempPos; - else - tempPos += strlen(temp + tempPos); - } - else if (prop.vt == VT_EMPTY) - { - if (!techMode) - { - PrintSpacesToString(temp + tempPos, width); - tempPos += width; - } - } - else if (prop.vt == VT_FILETIME) - { - PrintTime(temp + tempPos, &prop.filetime); - if (techMode) - g_StdOut << temp + tempPos; - else - { - size_t len = strlen(temp + tempPos); - tempPos += len; - if (len < (unsigned)f.Width) - { - len = f.Width - len; - PrintSpacesToString(temp + tempPos, (unsigned)len); - tempPos += len; - } - } - } - else if (prop.vt == VT_BSTR) - { - TempWString.SetFromBstr(prop.bstrVal); - if (techMode) - { - // replace CR/LF here. - g_StdOut.PrintUString(TempWString, TempAString); - } - else - PrintUString(f.TextAdjustment, width, TempWString, TempAString); - } - else - { - char s[64]; - ConvertPropertyToShortString(s, prop, f.PropID); - if (techMode) - g_StdOut << s; - else - { - PrintStringToString(temp + tempPos, f.TextAdjustment, width, s); - tempPos += strlen(temp + tempPos); - } - } - } - if (techMode) - g_StdOut << MY_ENDL; - } - g_StdOut << MY_ENDL; - return S_OK; -} - -static void PrintNumber(EAdjustment adj, unsigned width, const CListUInt64Def &value) -{ - char s[32]; - s[0] = 0; - if (value.Def) - ConvertUInt64ToString(value.Val, s); - PrintString(adj, width, s); -} - -void Print_UInt64_and_String(AString &s, UInt64 val, const char *name); - -void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *str) -{ - FOR_VECTOR (i, _fields) - { - const CFieldInfo &f = _fields[i]; - PrintSpaces(f.PrefixSpacesWidth); - if (f.PropID == kpidSize) - PrintNumber(f.TextAdjustment, f.Width, st.Size); - else if (f.PropID == kpidPackSize) - PrintNumber(f.TextAdjustment, f.Width, st.PackSize); - else if (f.PropID == kpidMTime) - { - char s[64]; - s[0] = 0; - if (st.MTime.Def) - PrintTime(s, &st.MTime.Val); - PrintString(f.TextAdjustment, f.Width, s); - } - else if (f.PropID == kpidPath) - { - AString s; - Print_UInt64_and_String(s, st.NumFiles, str); - if (numDirs != 0) - { - s += ", "; - Print_UInt64_and_String(s, numDirs, kString_Dirs); - } - PrintString(f.TextAdjustment, 0, s); - } - else - PrintString(f.TextAdjustment, f.Width, ""); - } - g_StdOut << endl; -} - -void CFieldPrinter::PrintSum(const CListStat2 &stat2) -{ - PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files); - if (stat2.AltStreams.NumFiles != 0) - { - PrintSum(stat2.AltStreams, 0, kString_AltStreams);; - CListStat st = stat2.MainFiles; - st.Update(stat2.AltStreams); - PrintSum(st, 0, kString_Streams); - } -} - -static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, CListUInt64Def &value) -{ - value.Val = 0; - value.Def = false; - CPropVariant prop; - RINOK(archive->GetProperty(index, propID, &prop)); - value.Def = ConvertPropVariantToUInt64(prop, value.Val); - return S_OK; -} - -static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t) -{ - t.Val.dwLowDateTime = 0; - t.Val.dwHighDateTime = 0; - t.Def = false; - CPropVariant prop; - RINOK(archive->GetProperty(index, kpidMTime, &prop)); - if (prop.vt == VT_FILETIME) - { - t.Val = prop.filetime; - t.Def = true; - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - -static void PrintPropNameAndNumber(CStdOutStream &so, const char *name, UInt64 val) -{ - so << name << ": " << val << endl; -} - -static void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID) -{ - const char *s; - char temp[16]; - if (propID < ARRAY_SIZE(kPropIdToName)) - s = kPropIdToName[propID]; - else - { - ConvertUInt32ToString(propID, temp); - s = temp; - } - so << s << " = "; -} - -static void PrintPropNameAndNumber(CStdOutStream &so, PROPID propID, UInt64 val) -{ - PrintPropName_and_Eq(so, propID); - so << val << endl; -} - -static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int64 val) -{ - PrintPropName_and_Eq(so, propID); - so << val << endl; -} - -static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val) -{ - so << name << " = " << val << endl; -} - - -static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop) -{ - UString s; - ConvertPropertyToString(s, prop, propID); - if (!s.IsEmpty()) - { - AString nameA; - UString nameU; - GetPropName(propID, name, nameA, nameU); - if (!nameA.IsEmpty()) - PrintPropPair(so, nameA, s); - else - so << nameU << " = " << s << endl; - } -} - -static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name) -{ - CPropVariant prop; - RINOK(archive->GetArchiveProperty(propID, &prop)); - PrintPropertyPair2(so, propID, name, prop); - return S_OK; -} - -static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning) -{ - so << "Open " << (isWarning ? "WARNING" : "ERROR") - << ": Can not open the file as [" - << type - << "] archive" - << endl; -} - -int Find_FileName_InSortedVector(const UStringVector &fileName, const UString& name); - -void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); - -static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er) -{ - PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); - if (!er.ErrorMessage.IsEmpty()) - PrintPropPair(so, "ERROR", er.ErrorMessage); - - PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); - if (!er.WarningMessage.IsEmpty()) - PrintPropPair(so, "WARNING", er.WarningMessage); -} - -HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) -{ - FOR_VECTOR (r, arcLink.Arcs) - { - const CArc &arc = arcLink.Arcs[r]; - const CArcErrorInfo &er = arc.ErrorInfo; - - so << "--\n"; - PrintPropPair(so, "Path", arc.Path); - if (er.ErrorFormatIndex >= 0) - { - if (er.ErrorFormatIndex == arc.FormatIndex) - so << "Warning: The archive is open with offset" << endl; - else - PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); - } - PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex)); - - ErrorInfo_Print(so, er); - - Int64 offset = arc.GetGlobalOffset(); - if (offset != 0) - PrintPropNameAndNumber_Signed(so, kpidOffset, offset); - IInArchive *archive = arc.Archive; - RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)); - if (er.TailSize != 0) - PrintPropNameAndNumber(so, kpidTailSize, er.TailSize); - { - UInt32 numProps; - RINOK(archive->GetNumberOfArchiveProperties(&numProps)); - - for (UInt32 j = 0; j < numProps; j++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)); - RINOK(PrintArcProp(so, archive, propID, name)); - } - } - - if (r != arcLink.Arcs.Size() - 1) - { - UInt32 numProps; - so << "----\n"; - if (archive->GetNumberOfProperties(&numProps) == S_OK) - { - UInt32 mainIndex = arcLink.Arcs[r + 1].SubfileIndex; - for (UInt32 j = 0; j < numProps; j++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)); - CPropVariant prop; - RINOK(archive->GetProperty(mainIndex, propID, &prop)); - PrintPropertyPair2(so, propID, name, prop); - } - } - } - } - return S_OK; -} - -HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) -{ - #ifndef _NO_CRYPTO - if (arcLink.PasswordWasAsked) - so << "Can not open encrypted archive. Wrong password?"; - else - #endif - { - if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - { - so << arcLink.NonOpen_ArcPath << endl; - PrintArcTypeError(so, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); - } - else - so << "Can not open the file as archive"; - } - - so << endl; - so << endl; - ErrorInfo_Print(so, arcLink.NonOpen_ErrorInfo); - - return S_OK; -} - -bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); - -HRESULT ListArchives(CCodecs *codecs, - const CObjectVector &types, - const CIntVector &excludedFormats, - bool stdInMode, - UStringVector &arcPaths, UStringVector &arcPathsFull, - bool processAltStreams, bool showAltStreams, - const NWildcard::CCensorNode &wildcardCensor, - bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO - bool &passwordEnabled, UString &password, - #endif - #ifndef _SFX - const CObjectVector *props, - #endif - UInt64 &numErrors, - UInt64 &numWarnings) -{ - bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); - - numErrors = 0; - numWarnings = 0; - - CFieldPrinter fp; - if (!techMode) - fp.Init(kStandardFieldTable, ARRAY_SIZE(kStandardFieldTable)); - - CListStat2 stat2total; - - CBoolArr skipArcs(arcPaths.Size()); - unsigned arcIndex; - for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) - skipArcs[arcIndex] = false; - UInt64 numVolumes = 0; - UInt64 numArcs = 0; - UInt64 totalArcSizes = 0; - - HRESULT lastError = 0; - - for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) - { - if (skipArcs[arcIndex]) - continue; - const UString &arcPath = arcPaths[arcIndex]; - UInt64 arcPackSize = 0; - - if (!stdInMode) - { - NFile::NFind::CFileInfo fi; - if (!fi.Find(us2fs(arcPath))) - { - DWORD errorCode = GetLastError(); -/* FIXME - if (errorCode == 0) - errorCode = ERROR_FILE_NOT_FOUND; -*/ - lastError = HRESULT_FROM_WIN32(lastError);; - g_StdOut.Flush(); - *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << - endl << arcPath << endl << endl; - numErrors++; - continue; - } - if (fi.IsDir()) - { - g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " is not a file" << endl << endl; - numErrors++; - continue; - } - arcPackSize = fi.Size; - totalArcSizes += arcPackSize; - } - - CArchiveLink arcLink; - - COpenCallbackConsole openCallback; - openCallback.Init(&g_StdOut, g_ErrStream, NULL); - - #ifndef _NO_CRYPTO - - openCallback.PasswordIsDefined = passwordEnabled; - openCallback.Password = password; - - #endif - - /* - CObjectVector optPropsVector; - COptionalOpenProperties &optProps = optPropsVector.AddNew(); - optProps.Props = *props; - */ - - COpenOptions options; - #ifndef _SFX - options.props = props; - #endif - options.codecs = codecs; - options.types = &types; - options.excludedFormats = &excludedFormats; - options.stdInMode = stdInMode; - options.stream = NULL; - options.filePath = arcPath; - - if (enableHeaders) - { - g_StdOut << endl << kListing << arcPath << endl << endl; - } - - HRESULT result = arcLink.Open3(options, &openCallback); - - if (result != S_OK) - { - if (result == E_ABORT) - return result; - g_StdOut.Flush(); - *g_ErrStream << endl << kError << arcPath << " : "; - if (result == S_FALSE) - { - Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); - } - else - { - lastError = result; - *g_ErrStream << "opening : "; - if (result == E_OUTOFMEMORY) - *g_ErrStream << "Can't allocate required memory"; - else - *g_ErrStream << NError::MyFormatMessage(result); - } - *g_ErrStream << endl; - numErrors++; - continue; - } - - { - if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - numErrors++; - - FOR_VECTOR (r, arcLink.Arcs) - { - const CArcErrorInfo &arc = arcLink.Arcs[r].ErrorInfo; - if (!arc.WarningMessage.IsEmpty()) - numWarnings++; - if (arc.AreThereWarnings()) - numWarnings++; - if (arc.ErrorFormatIndex >= 0) - numWarnings++; - if (arc.AreThereErrors()) - { - numErrors++; - // break; - } - if (!arc.ErrorMessage.IsEmpty()) - numErrors++; - } - } - - numArcs++; - numVolumes++; - - if (!stdInMode) - { - numVolumes += arcLink.VolumePaths.Size(); - totalArcSizes += arcLink.VolumesSize; - FOR_VECTOR (v, arcLink.VolumePaths) - { - int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); - if (index >= 0 && (unsigned)index > arcIndex) - skipArcs[(unsigned)index] = true; - } - } - - - if (enableHeaders) - { - RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)); - - g_StdOut << endl; - if (techMode) - g_StdOut << "----------\n"; - } - - if (enableHeaders && !techMode) - { - fp.PrintTitle(); - g_StdOut << endl; - fp.PrintTitleLines(); - g_StdOut << endl; - } - - const CArc &arc = arcLink.Arcs.Back(); - fp.Arc = &arc; - fp.TechMode = techMode; - IInArchive *archive = arc.Archive; - if (techMode) - { - fp.Clear(); - RINOK(fp.AddMainProps(archive)); - if (arc.GetRawProps) - { - RINOK(fp.AddRawProps(arc.GetRawProps)); - } - } - - CListStat2 stat2; - - UInt32 numItems; - RINOK(archive->GetNumberOfItems(&numItems)); - - CReadArcItem item; - UStringVector pathParts; - - for (UInt32 i = 0; i < numItems; i++) - { - if (NConsoleClose::TestBreakSignal()) - return E_ABORT; - - HRESULT res = arc.GetItemPath2(i, fp.FilePath); - - if (stdInMode && res == E_INVALIDARG) - break; - RINOK(res); - - if (arc.Ask_Aux) - { - bool isAux; - RINOK(Archive_IsItem_Aux(archive, i, isAux)); - if (isAux) - continue; - } - - bool isAltStream = false; - if (arc.Ask_AltStream) - { - RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)); - if (isAltStream && !processAltStreams) - continue; - } - - RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)); - - if (!allFilesAreAllowed) - { - if (isAltStream) - { - RINOK(arc.GetItem(i, item)); - if (!CensorNode_CheckPath(wildcardCensor, item)) - continue; - } - else - { - SplitPathToParts(fp.FilePath, pathParts);; - bool include; - if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include)) - continue; - if (!include) - continue; - } - } - - CListStat st; - - RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)); - RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)); - RINOK(GetItemMTime(archive, i, st.MTime)); - - if (fp.IsDir) - stat2.NumDirs++; - else - st.NumFiles = 1; - stat2.GetStat(isAltStream).Update(st); - - if (isAltStream && !showAltStreams) - continue; - RINOK(fp.PrintItemInfo(i, st)); - } - - UInt64 numStreams = stat2.GetNumStreams(); - if (!stdInMode - && !stat2.MainFiles.PackSize.Def - && !stat2.AltStreams.PackSize.Def) - { - if (arcLink.VolumePaths.Size() != 0) - arcPackSize += arcLink.VolumesSize; - stat2.MainFiles.PackSize.Add((numStreams == 0) ? 0 : arcPackSize); - } - - stat2.MainFiles.SetSizeDefIfNoFiles(); - stat2.AltStreams.SetSizeDefIfNoFiles(); - - if (enableHeaders && !techMode) - { - fp.PrintTitleLines(); - g_StdOut << endl; - fp.PrintSum(stat2); - } - - if (enableHeaders) - { - if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - { - g_StdOut << "----------\n"; - PrintPropPair(g_StdOut, "Path", arcLink.NonOpen_ArcPath); - PrintArcTypeError(g_StdOut, codecs->Formats[arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); - } - } - - stat2total.Update(stat2); - - g_StdOut.Flush(); - } - - if (enableHeaders && !techMode && (arcPaths.Size() > 1 || numVolumes > 1)) - { - g_StdOut << endl; - fp.PrintTitleLines(); - g_StdOut << endl; - fp.PrintSum(stat2total); - g_StdOut << endl; - PrintPropNameAndNumber(g_StdOut, "Archives", numArcs); - PrintPropNameAndNumber(g_StdOut, "Volumes", numVolumes); - PrintPropNameAndNumber(g_StdOut, "Total archives size", totalArcSizes); - } - - if (numErrors == 1 && lastError != 0) - return lastError; - - return S_OK; -} +// List.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/MyCom.h" +#include "../../../Common/StdOutStream.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../Common/OpenArchive.h" +#include "../Common/PropIDUtils.h" + +#include "ConsoleClose.h" +#include "List.h" +#include "OpenCallbackConsole.h" + +using namespace NWindows; +using namespace NCOM; + +extern CStdOutStream *g_StdStream; +extern CStdOutStream *g_ErrStream; + +static const char * const kPropIdToName[] = +{ + "0" + , "1" + , "2" + , "Path" + , "Name" + , "Extension" + , "Folder" + , "Size" + , "Packed Size" + , "Attributes" + , "Created" + , "Accessed" + , "Modified" + , "Solid" + , "Commented" + , "Encrypted" + , "Split Before" + , "Split After" + , "Dictionary Size" + , "CRC" + , "Type" + , "Anti" + , "Method" + , "Host OS" + , "File System" + , "User" + , "Group" + , "Block" + , "Comment" + , "Position" + , "Path Prefix" + , "Folders" + , "Files" + , "Version" + , "Volume" + , "Multivolume" + , "Offset" + , "Links" + , "Blocks" + , "Volumes" + , "Time Type" + , "64-bit" + , "Big-endian" + , "CPU" + , "Physical Size" + , "Headers Size" + , "Checksum" + , "Characteristics" + , "Virtual Address" + , "ID" + , "Short Name" + , "Creator Application" + , "Sector Size" + , "Mode" + , "Symbolic Link" + , "Error" + , "Total Size" + , "Free Space" + , "Cluster Size" + , "Label" + , "Local Name" + , "Provider" + , "NT Security" + , "Alternate Stream" + , "Aux" + , "Deleted" + , "Tree" + , "SHA-1" + , "SHA-256" + , "Error Type" + , "Errors" + , "Errors" + , "Warnings" + , "Warning" + , "Streams" + , "Alternate Streams" + , "Alternate Streams Size" + , "Virtual Size" + , "Unpack Size" + , "Total Physical Size" + , "Volume Index" + , "SubType" + , "Short Comment" + , "Code Page" + , "Is not archive type" + , "Physical Size can't be detected" + , "Zeros Tail Is Allowed" + , "Tail Size" + , "Embedded Stub Size" + , "Link" + , "Hard Link" + , "iNode" + , "Stream ID" + , "Read-only" + , "Out Name" + , "Copy Link" + , "ArcFileName" + , "IsHash" + , "Metadata Changed" + , "User ID" + , "Group ID" + , "Device Major" + , "Device Minor" + , "Dev Major" + , "Dev Minor" +}; + +static const char kEmptyAttribChar = '.'; + +static const char * const kListing = "Listing archive: "; + +static const char * const kString_Files = "files"; +static const char * const kString_Dirs = "folders"; +static const char * const kString_AltStreams = "alternate streams"; +static const char * const kString_Streams = "streams"; + +static const char * const kError = "ERROR: "; + +static void GetAttribString(UInt32 wa, bool isDir, bool allAttribs, char *s) +{ + if (isDir) + wa |= FILE_ATTRIBUTE_DIRECTORY; + if (allAttribs) + { + ConvertWinAttribToString(s, wa); + return; + } + s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0) ? 'D': kEmptyAttribChar; + s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar; + s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar; + s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar; + s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar; + s[5] = 0; +} + +enum EAdjustment +{ + kLeft, + kCenter, + kRight +}; + +struct CFieldInfo +{ + PROPID PropID; + bool IsRawProp; + UString NameU; + AString NameA; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + unsigned PrefixSpacesWidth; + unsigned Width; +}; + +struct CFieldInfoInit +{ + PROPID PropID; + const char *Name; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + unsigned PrefixSpacesWidth; + unsigned Width; +}; + +static const CFieldInfoInit kStandardFieldTable[] = +{ + { kpidMTime, " Date Time", kLeft, kLeft, 0, 19 }, + { kpidAttrib, "Attr", kRight, kCenter, 1, 5 }, + { kpidSize, "Size", kRight, kRight, 1, 12 }, + { kpidPackSize, "Compressed", kRight, kRight, 1, 12 }, + { kpidPath, "Name", kLeft, kLeft, 2, 24 } +}; + +const unsigned kNumSpacesMax = 32; // it must be larger than max CFieldInfoInit.Width +static const char *g_Spaces = +" " ; + +static void PrintSpaces(unsigned numSpaces) +{ + if (numSpaces > 0 && numSpaces <= kNumSpacesMax) + g_StdOut << g_Spaces + (kNumSpacesMax - numSpaces); +} + +static void PrintSpacesToString(char *dest, unsigned numSpaces) +{ + unsigned i; + for (i = 0; i < numSpaces; i++) + dest[i] = ' '; + dest[i] = 0; +} + +// extern int g_CodePage; + +static void PrintUString(EAdjustment adj, unsigned width, const UString &s, AString &temp) +{ + /* + // we don't need multibyte align. + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); + */ + + unsigned numSpaces = 0; + + if (width > s.Len()) + { + numSpaces = width - s.Len(); + unsigned numLeftSpaces = 0; + switch ((int)adj) + { + // case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; + } + PrintSpaces(numLeftSpaces); + numSpaces -= numLeftSpaces; + } + + g_StdOut.PrintUString(s, temp); + PrintSpaces(numSpaces); +} + +static void PrintString(EAdjustment adj, unsigned width, const char *s) +{ + unsigned numSpaces = 0; + unsigned len = (unsigned)strlen(s); + + if (width > len) + { + numSpaces = width - len; + unsigned numLeftSpaces = 0; + switch ((int)adj) + { + // case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; + } + PrintSpaces(numLeftSpaces); + numSpaces -= numLeftSpaces; + } + + g_StdOut << s; + PrintSpaces(numSpaces); +} + +static void PrintStringToString(char *dest, EAdjustment adj, unsigned width, const char *textString) +{ + unsigned numSpaces = 0; + unsigned len = (unsigned)strlen(textString); + + if (width > len) + { + numSpaces = width - len; + unsigned numLeftSpaces = 0; + switch ((int)adj) + { + // case kLeft: numLeftSpaces = 0; break; + case kCenter: numLeftSpaces = numSpaces / 2; break; + case kRight: numLeftSpaces = numSpaces; break; + // case kLeft: + default: break; + } + PrintSpacesToString(dest, numLeftSpaces); + dest += numLeftSpaces; + numSpaces -= numLeftSpaces; + } + + memcpy(dest, textString, len); + dest += len; + PrintSpacesToString(dest, numSpaces); +} + +struct CListUInt64Def +{ + UInt64 Val; + bool Def; + + CListUInt64Def(): Val(0), Def(false) {} + void Add(UInt64 v) { Val += v; Def = true; } + void Add(const CListUInt64Def &v) { if (v.Def) Add(v.Val); } +}; + + +struct CListFileTimeDef: public CArcTime +{ + void Update(const CListFileTimeDef &t) + { + if (t.Def && (!Def || CompareWith(t) < 0)) + (*this) = t; + } +}; + + + +struct CListStat +{ + CListUInt64Def Size; + CListUInt64Def PackSize; + CListFileTimeDef MTime; + UInt64 NumFiles; + + CListStat(): NumFiles(0) {} + void Update(const CListStat &st) + { + Size.Add(st.Size); + PackSize.Add(st.PackSize); + MTime.Update(st.MTime); + NumFiles += st.NumFiles; + } + void SetSizeDefIfNoFiles() { if (NumFiles == 0) Size.Def = true; } +}; + +struct CListStat2 +{ + CListStat MainFiles; + CListStat AltStreams; + UInt64 NumDirs; + + CListStat2(): NumDirs(0) {} + + void Update(const CListStat2 &st) + { + MainFiles.Update(st.MainFiles); + AltStreams.Update(st.AltStreams); + NumDirs += st.NumDirs; + } + UInt64 GetNumStreams() const { return MainFiles.NumFiles + AltStreams.NumFiles; } + CListStat &GetStat(bool altStreamsMode) { return altStreamsMode ? AltStreams : MainFiles; } +}; + +class CFieldPrinter +{ + CObjectVector _fields; + + void AddProp(const wchar_t *name, PROPID propID, bool isRawProp); +public: + const CArc *Arc; + bool TechMode; + UString FilePath; + AString TempAString; + UString TempWString; + bool IsDir; + + AString LinesString; + + void Clear() { _fields.Clear(); LinesString.Empty(); } + void Init(const CFieldInfoInit *standardFieldTable, unsigned numItems); + + HRESULT AddMainProps(IInArchive *archive); + HRESULT AddRawProps(IArchiveGetRawProps *getRawProps); + + void PrintTitle(); + void PrintTitleLines(); + HRESULT PrintItemInfo(UInt32 index, const CListStat &st); + void PrintSum(const CListStat &st, UInt64 numDirs, const char *str); + void PrintSum(const CListStat2 &stat2); +}; + +void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, unsigned numItems) +{ + Clear(); + for (unsigned i = 0; i < numItems; i++) + { + CFieldInfo &f = _fields.AddNew(); + const CFieldInfoInit &fii = standardFieldTable[i]; + f.PropID = fii.PropID; + f.IsRawProp = false; + f.NameA = fii.Name; + f.TitleAdjustment = fii.TitleAdjustment; + f.TextAdjustment = fii.TextAdjustment; + f.PrefixSpacesWidth = fii.PrefixSpacesWidth; + f.Width = fii.Width; + + unsigned k; + for (k = 0; k < fii.PrefixSpacesWidth; k++) + LinesString.Add_Space(); + for (k = 0; k < fii.Width; k++) + LinesString.Add_Minus(); + } +} + +static void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU) +{ + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) + { + nameA = kPropIdToName[propID]; + return; + } + if (name) + nameU = name; + else + { + nameA.Empty(); + nameA.Add_UInt32(propID); + } +} + +void CFieldPrinter::AddProp(const wchar_t *name, PROPID propID, bool isRawProp) +{ + CFieldInfo f; + f.PropID = propID; + f.IsRawProp = isRawProp; + GetPropName(propID, name, f.NameA, f.NameU); + f.NameU += " = "; + if (!f.NameA.IsEmpty()) + f.NameA += " = "; + else + { + const UString &s = f.NameU; + AString sA; + unsigned i; + for (i = 0; i < s.Len(); i++) + { + const wchar_t c = s[i]; + if (c >= 0x80) + break; + sA.Add_Char((char)c); + } + if (i == s.Len()) + f.NameA = sA; + } + _fields.Add(f); +} + +HRESULT CFieldPrinter::AddMainProps(IInArchive *archive) +{ + UInt32 numProps; + RINOK(archive->GetNumberOfProperties(&numProps)) + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)) + AddProp(name, propID, false); + } + return S_OK; +} + +HRESULT CFieldPrinter::AddRawProps(IArchiveGetRawProps *getRawProps) +{ + UInt32 numProps; + RINOK(getRawProps->GetNumRawProps(&numProps)) + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + RINOK(getRawProps->GetRawPropInfo(i, &name, &propID)) + AddProp(name, propID, true); + } + return S_OK; +} + +void CFieldPrinter::PrintTitle() +{ + FOR_VECTOR (i, _fields) + { + const CFieldInfo &f = _fields[i]; + PrintSpaces(f.PrefixSpacesWidth); + PrintString(f.TitleAdjustment, ((f.PropID == kpidPath) ? 0: f.Width), f.NameA); + } +} + +void CFieldPrinter::PrintTitleLines() +{ + g_StdOut << LinesString; +} + +static void PrintTime(char *dest, const CListFileTimeDef &t, bool showNS) +{ + *dest = 0; + if (t.IsZero()) + return; + int prec = kTimestampPrintLevel_SEC; + unsigned flags = 0; + if (showNS) // techmode + { + prec = kTimestampPrintLevel_NTFS; + if (t.Prec != 0) + { + prec = t.GetNumDigits(); + if (prec < kTimestampPrintLevel_DAY) + prec = kTimestampPrintLevel_NTFS; + } + } + else + { + // we want same default number of characters, so we disable 'Z' marker: + flags = kTimestampPrintFlags_DisableZ; + } + + ConvertUtcFileTimeToString2(t.FT, t.Ns100, dest, prec, flags); +} + +#ifndef Z7_SFX + +#endif + +#define MY_ENDL endl + +inline bool IsPropId_for_PathString(UInt32 propId) +{ + return (propId == kpidPath + // || propId == kpidName + || propId == kpidSymLink + || propId == kpidHardLink + || propId == kpidCopyLink); +} + +HRESULT CFieldPrinter::PrintItemInfo(UInt32 index, const CListStat &st) +{ + char temp[128]; + size_t tempPos = 0; + + bool techMode = this->TechMode; + /* + if (techMode) + { + g_StdOut << "Index = "; + g_StdOut << (UInt64)index; + g_StdOut << endl; + } + */ + FOR_VECTOR (i, _fields) + { + const CFieldInfo &f = _fields[i]; + + if (!techMode) + { + PrintSpacesToString(temp + tempPos, f.PrefixSpacesWidth); + tempPos += f.PrefixSpacesWidth; + } + + if (techMode) + { + if (!f.NameA.IsEmpty()) + g_StdOut << f.NameA; + else + g_StdOut << f.NameU; + } + + if (f.PropID == kpidPath) + { + if (!techMode) + g_StdOut << temp; + g_StdOut.NormalizePrint_UString_Path(FilePath, TempWString, TempAString); + if (techMode) + g_StdOut << MY_ENDL; + continue; + } + + const unsigned width = f.Width; + + if (f.IsRawProp) + { + #ifndef Z7_SFX + + const void *data; + UInt32 dataSize; + UInt32 propType; + RINOK(Arc->GetRawProps->GetRawProp(index, f.PropID, &data, &dataSize, &propType)) + + if (dataSize != 0) + { + bool needPrint = true; + + if (f.PropID == kpidNtSecure) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + #ifndef Z7_SFX + ConvertNtSecureToString((const Byte *)data, dataSize, TempAString); + g_StdOut << TempAString; + needPrint = false; + #endif + } + else if (f.PropID == kpidNtReparse) + { + UString s; + if (ConvertNtReparseToString((const Byte *)data, dataSize, s)) + { + needPrint = false; + g_StdOut.PrintUString(s, TempAString); + } + } + + if (needPrint) + { + if (propType != NPropDataType::kRaw) + return E_FAIL; + + const UInt32 kMaxDataSize = 64; + + if (dataSize > kMaxDataSize) + { + g_StdOut << "data:"; + g_StdOut << dataSize; + } + else + { + char hexStr[kMaxDataSize * 2 + 4]; + ConvertDataToHex_Lower(hexStr, (const Byte *)data, dataSize); + g_StdOut << hexStr; + } + } + } + + #endif + } + else + { + CPropVariant prop; + switch (f.PropID) + { + case kpidSize: if (st.Size.Def) prop = st.Size.Val; break; + case kpidPackSize: if (st.PackSize.Def) prop = st.PackSize.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)) + } + if (f.PropID == kpidAttrib && (prop.vt == VT_EMPTY || prop.vt == VT_UI4)) + { + GetAttribString((prop.vt == VT_EMPTY) ? 0 : prop.ulVal, IsDir, techMode, temp + tempPos); + if (techMode) + g_StdOut << temp + tempPos; + else + tempPos += strlen(temp + tempPos); + } + else if (prop.vt == VT_EMPTY) + { + if (!techMode) + { + PrintSpacesToString(temp + tempPos, width); + tempPos += width; + } + } + else if (prop.vt == VT_FILETIME) + { + CListFileTimeDef t; + t.Set_From_Prop(prop); + PrintTime(temp + tempPos, t, techMode); + if (techMode) + g_StdOut << temp + tempPos; + else + { + size_t len = strlen(temp + tempPos); + tempPos += len; + if (len < (unsigned)f.Width) + { + len = f.Width - len; + PrintSpacesToString(temp + tempPos, (unsigned)len); + tempPos += len; + } + } + } + else if (prop.vt == VT_BSTR) + { + TempWString.SetFromBstr(prop.bstrVal); + // do we need multi-line support here ? + if (IsPropId_for_PathString(f.PropID)) + g_StdOut.Normalize_UString_Path(TempWString); + else + g_StdOut.Normalize_UString(TempWString); + if (techMode) + g_StdOut.PrintUString(TempWString, TempAString); + else + PrintUString(f.TextAdjustment, width, TempWString, TempAString); + } + else + { + char s[64]; + ConvertPropertyToShortString2(s, prop, f.PropID); + if (techMode) + g_StdOut << s; + else + { + PrintStringToString(temp + tempPos, f.TextAdjustment, width, s); + tempPos += strlen(temp + tempPos); + } + } + } + if (techMode) + g_StdOut << MY_ENDL; + } + g_StdOut << MY_ENDL; + return S_OK; +} + +static void PrintNumber(EAdjustment adj, unsigned width, const CListUInt64Def &value) +{ + char s[32]; + s[0] = 0; + if (value.Def) + ConvertUInt64ToString(value.Val, s); + PrintString(adj, width, s); +} + +void Print_UInt64_and_String(AString &s, UInt64 val, const char *name); + +void CFieldPrinter::PrintSum(const CListStat &st, UInt64 numDirs, const char *str) +{ + FOR_VECTOR (i, _fields) + { + const CFieldInfo &f = _fields[i]; + PrintSpaces(f.PrefixSpacesWidth); + if (f.PropID == kpidSize) + PrintNumber(f.TextAdjustment, f.Width, st.Size); + else if (f.PropID == kpidPackSize) + PrintNumber(f.TextAdjustment, f.Width, st.PackSize); + else if (f.PropID == kpidMTime) + { + char s[64]; + s[0] = 0; + if (st.MTime.Def) + PrintTime(s, st.MTime, false); // showNS + PrintString(f.TextAdjustment, f.Width, s); + } + else if (f.PropID == kpidPath) + { + AString s; + Print_UInt64_and_String(s, st.NumFiles, str); + if (numDirs != 0) + { + s += ", "; + Print_UInt64_and_String(s, numDirs, kString_Dirs); + } + PrintString(f.TextAdjustment, 0, s); + } + else + PrintString(f.TextAdjustment, f.Width, ""); + } + g_StdOut << endl; +} + +void CFieldPrinter::PrintSum(const CListStat2 &stat2) +{ + PrintSum(stat2.MainFiles, stat2.NumDirs, kString_Files); + if (stat2.AltStreams.NumFiles != 0) + { + PrintSum(stat2.AltStreams, 0, kString_AltStreams); + CListStat st = stat2.MainFiles; + st.Update(stat2.AltStreams); + PrintSum(st, 0, kString_Streams); + } +} + +static HRESULT GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, CListUInt64Def &value) +{ + value.Val = 0; + value.Def = false; + CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)) + value.Def = ConvertPropVariantToUInt64(prop, value.Val); + return S_OK; +} + +static HRESULT GetItemMTime(IInArchive *archive, UInt32 index, CListFileTimeDef &t) +{ + /* 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.Set_From_Prop(prop); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +static void PrintPropNameAndNumber(CStdOutStream &so, const char *name, UInt64 val) +{ + so << name << ": " << val << endl; +} + +static void PrintPropName_and_Eq(CStdOutStream &so, PROPID propID) +{ + const char *s; + char temp[16]; + if (propID < Z7_ARRAY_SIZE(kPropIdToName)) + s = kPropIdToName[propID]; + else + { + ConvertUInt32ToString(propID, temp); + s = temp; + } + so << s << " = "; +} + +static void PrintPropNameAndNumber(CStdOutStream &so, PROPID propID, UInt64 val) +{ + PrintPropName_and_Eq(so, propID); + so << val << endl; +} + +static void PrintPropNameAndNumber_Signed(CStdOutStream &so, PROPID propID, Int64 val) +{ + PrintPropName_and_Eq(so, propID); + so << val << endl; +} + + +static void UString_Replace_CRLF_to_LF(UString &s) +{ + // s.Replace(L"\r\n", L"\n"); + wchar_t *src = s.GetBuf(); + wchar_t *dest = src; + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + if (c == '\r' && *src == '\n') + { + src++; + c = '\n'; + } + *dest++ = c; + } + s.ReleaseBuf_SetEnd((unsigned)(size_t)(dest - s.GetBuf())); +} + +static void PrintPropVal_MultiLine(CStdOutStream &so, const wchar_t *val) +{ + UString s (val); + if (s.Find(L'\n') >= 0) + { + so << endl; + so << "{"; + so << endl; + UString_Replace_CRLF_to_LF(s); + UString temp; + unsigned start = 0; + for (;;) + { + unsigned size = s.Len() - start; + if (size == 0) + break; + const int next = s.Find(L'\n', start); + if (next >= 0) + size = (unsigned)next - start; + temp.SetFrom(s.Ptr() + start, size); + so.NormalizePrint_UString(temp); + so << endl; + if (next < 0) + break; + start = (unsigned)next + 1; + } + so << "}"; + } + else + { + so.NormalizePrint_UString(s); + } + so << endl; +} + + +static void PrintPropPair(CStdOutStream &so, const char *name, const wchar_t *val, bool multiLine, bool isPath = false) +{ + so << name << " = "; + if (multiLine) + { + PrintPropVal_MultiLine(so, val); + return; + } + UString s (val); + if (isPath) + so.Normalize_UString_Path(s); + else + so.Normalize_UString(s); + so << s; + so << endl; +} + + +static void PrintPropPair_Path(CStdOutStream &so, const wchar_t *path) +{ + PrintPropPair(so, "Path", path, + false, // multiLine + true); // isPath +} + +static void PrintPropertyPair2(CStdOutStream &so, PROPID propID, const wchar_t *name, const CPropVariant &prop) +{ + UString s; + const int levelTopLimit = 9; // 1ns level + ConvertPropertyToString2(s, prop, propID, levelTopLimit); + if (!s.IsEmpty()) + { + AString nameA; + UString nameU; + GetPropName(propID, name, nameA, nameU); + if (!nameA.IsEmpty()) + so << nameA; + else + so << nameU; + so << " = "; + PrintPropVal_MultiLine(so, s); + } +} + +static HRESULT PrintArcProp(CStdOutStream &so, IInArchive *archive, PROPID propID, const wchar_t *name) +{ + CPropVariant prop; + RINOK(archive->GetArchiveProperty(propID, &prop)) + PrintPropertyPair2(so, propID, name, prop); + return S_OK; +} + +static void PrintArcTypeError(CStdOutStream &so, const UString &type, bool isWarning) +{ + so << "Open " << (isWarning ? "WARNING" : "ERROR") + << ": Cannot open the file as [" + << type + << "] archive" + << endl; +} + +int Find_FileName_InSortedVector(const UStringVector &fileName, const UString& name); + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); + +static void ErrorInfo_Print(CStdOutStream &so, const CArcErrorInfo &er) +{ + PrintErrorFlags(so, "ERRORS:", er.GetErrorFlags()); + if (!er.ErrorMessage.IsEmpty()) + PrintPropPair(so, "ERROR", er.ErrorMessage, true); + + PrintErrorFlags(so, "WARNINGS:", er.GetWarningFlags()); + if (!er.WarningMessage.IsEmpty()) + PrintPropPair(so, "WARNING", er.WarningMessage, true); +} + +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) +{ + FOR_VECTOR (r, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[r]; + const CArcErrorInfo &er = arc.ErrorInfo; + + so << "--\n"; + PrintPropPair_Path(so, arc.Path); + if (er.ErrorFormatIndex >= 0) + { + if (er.ErrorFormatIndex == arc.FormatIndex) + so << "Warning: The archive is open with offset" << endl; + else + PrintArcTypeError(so, codecs->GetFormatNamePtr(er.ErrorFormatIndex), true); + } + PrintPropPair(so, "Type", codecs->GetFormatNamePtr(arc.FormatIndex), false); + + ErrorInfo_Print(so, er); + + Int64 offset = arc.GetGlobalOffset(); + if (offset != 0) + PrintPropNameAndNumber_Signed(so, kpidOffset, offset); + IInArchive *archive = arc.Archive; + RINOK(PrintArcProp(so, archive, kpidPhySize, NULL)) + if (er.TailSize != 0) + PrintPropNameAndNumber(so, kpidTailSize, er.TailSize); + { + UInt32 numProps; + RINOK(archive->GetNumberOfArchiveProperties(&numProps)) + + for (UInt32 j = 0; j < numProps; j++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt)) + RINOK(PrintArcProp(so, archive, propID, name)) + } + } + + if (r != arcLink.Arcs.Size() - 1) + { + UInt32 numProps; + so << "----\n"; + if (archive->GetNumberOfProperties(&numProps) == S_OK) + { + UInt32 mainIndex = arcLink.Arcs[r + 1].SubfileIndex; + for (UInt32 j = 0; j < numProps; j++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt)) + CPropVariant prop; + RINOK(archive->GetProperty(mainIndex, propID, &prop)) + PrintPropertyPair2(so, propID, name, prop); + } + } + } + } + return S_OK; +} + +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink) +{ + #ifndef Z7_NO_CRYPTO + if (arcLink.PasswordWasAsked) + so << "Cannot open encrypted archive. Wrong password?"; + else + #endif + { + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + so.NormalizePrint_UString_Path(arcLink.NonOpen_ArcPath); + so << endl; + PrintArcTypeError(so, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + } + else + so << "Cannot open the file as archive"; + } + + so << endl; + so << endl; + ErrorInfo_Print(so, arcLink.NonOpen_ErrorInfo); + + return S_OK; +} + +bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); + +HRESULT ListArchives( + const CListOptions &listOptions, + CCodecs *codecs, + const CObjectVector &types, + const CIntVector &excludedFormats, + bool stdInMode, + UStringVector &arcPaths, UStringVector &arcPathsFull, + bool processAltStreams, bool showAltStreams, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, + #ifndef Z7_NO_CRYPTO + bool &passwordEnabled, UString &password, + #endif + #ifndef Z7_SFX + const CObjectVector *props, + #endif + UInt64 &numErrors, + UInt64 &numWarnings) +{ + bool allFilesAreAllowed = wildcardCensor.AreAllAllowed(); + + numErrors = 0; + numWarnings = 0; + + CFieldPrinter fp; + if (!techMode) + fp.Init(kStandardFieldTable, Z7_ARRAY_SIZE(kStandardFieldTable)); + + CListStat2 stat2total; + + CBoolArr skipArcs(arcPaths.Size()); + unsigned arcIndex; + for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) + skipArcs[arcIndex] = false; + UInt64 numVolumes = 0; + UInt64 numArcs = 0; + UInt64 totalArcSizes = 0; + + HRESULT lastError = 0; + + for (arcIndex = 0; arcIndex < arcPaths.Size(); arcIndex++) + { + if (skipArcs[arcIndex]) + continue; + const UString &arcPath = arcPaths[arcIndex]; + UInt64 arcPackSize = 0; + + if (!stdInMode) + { + NFile::NFind::CFileInfo fi; + if (!fi.Find_FollowLink(us2fs(arcPath))) + { + DWORD errorCode = GetLastError(); + if (errorCode == 0) + errorCode = ERROR_FILE_NOT_FOUND; + lastError = HRESULT_FROM_WIN32(errorCode); + g_StdOut.Flush(); + if (g_ErrStream) + { + *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; + g_ErrStream->NormalizePrint_UString_Path(arcPath); + *g_ErrStream << endl << endl; + } + numErrors++; + continue; + } + if (fi.IsDir()) + { + g_StdOut.Flush(); + if (g_ErrStream) + { + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString_Path(arcPath); + *g_ErrStream << " is not a file" << endl << endl; + } + numErrors++; + continue; + } + arcPackSize = fi.Size; + totalArcSizes += arcPackSize; + } + + CArchiveLink arcLink; + + COpenCallbackConsole openCallback; + openCallback.Init(&g_StdOut, g_ErrStream, NULL, listOptions.DisablePercents); + + #ifndef Z7_NO_CRYPTO + + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + + #endif + + /* + CObjectVector optPropsVector; + COptionalOpenProperties &optProps = optPropsVector.AddNew(); + optProps.Props = *props; + */ + + COpenOptions options; + #ifndef Z7_SFX + options.props = props; + #endif + options.codecs = codecs; + options.types = &types; + options.excludedFormats = &excludedFormats; + options.stdInMode = stdInMode; + options.stream = NULL; + options.filePath = arcPath; + + if (enableHeaders) + { + g_StdOut << endl << kListing; + g_StdOut.NormalizePrint_UString_Path(arcPath); + g_StdOut << endl << endl; + } + + HRESULT result = arcLink.Open_Strict(options, &openCallback); + + if (result != S_OK) + { + if (result == E_ABORT) + return result; + if (result != S_FALSE) + lastError = result; + g_StdOut.Flush(); + if (g_ErrStream) + { + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString_Path(arcPath); + *g_ErrStream << " : "; + if (result == S_FALSE) + { + Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); + } + else + { + *g_ErrStream << "opening : "; + if (result == E_OUTOFMEMORY) + *g_ErrStream << "Can't allocate required memory"; + else + *g_ErrStream << NError::MyFormatMessage(result); + } + *g_ErrStream << endl; + } + numErrors++; + continue; + } + + { + FOR_VECTOR (r, arcLink.Arcs) + { + const CArcErrorInfo &arc = arcLink.Arcs[r].ErrorInfo; + if (!arc.WarningMessage.IsEmpty()) + numWarnings++; + if (arc.AreThereWarnings()) + numWarnings++; + if (arc.ErrorFormatIndex >= 0) + numWarnings++; + if (arc.AreThereErrors()) + { + numErrors++; + // break; + } + if (!arc.ErrorMessage.IsEmpty()) + numErrors++; + } + } + + numArcs++; + numVolumes++; + + if (!stdInMode) + { + numVolumes += arcLink.VolumePaths.Size(); + totalArcSizes += arcLink.VolumesSize; + FOR_VECTOR (v, arcLink.VolumePaths) + { + int index = Find_FileName_InSortedVector(arcPathsFull, arcLink.VolumePaths[v]); + if (index >= 0 && (unsigned)index > arcIndex) + skipArcs[(unsigned)index] = true; + } + } + + + if (enableHeaders) + { + RINOK(Print_OpenArchive_Props(g_StdOut, codecs, arcLink)) + + g_StdOut << endl; + if (techMode) + g_StdOut << "----------\n"; + } + + if (enableHeaders && !techMode) + { + fp.PrintTitle(); + g_StdOut << endl; + fp.PrintTitleLines(); + g_StdOut << endl; + } + + const CArc &arc = arcLink.Arcs.Back(); + fp.Arc = &arc; + fp.TechMode = techMode; + IInArchive *archive = arc.Archive; + if (techMode) + { + fp.Clear(); + RINOK(fp.AddMainProps(archive)) + if (arc.GetRawProps) + { + RINOK(fp.AddRawProps(arc.GetRawProps)) + } + } + + CListStat2 stat2; + + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)) + + CReadArcItem item; + UStringVector pathParts; + + for (UInt32 i = 0; i < numItems; i++) + { + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + + HRESULT res = arc.GetItem_Path2(i, fp.FilePath); + + if (stdInMode && res == E_INVALIDARG) + break; + RINOK(res) + + if (arc.Ask_Aux) + { + bool isAux; + RINOK(Archive_IsItem_Aux(archive, i, isAux)) + if (isAux) + continue; + } + + bool isAltStream = false; + if (arc.Ask_AltStream) + { + RINOK(Archive_IsItem_AltStream(archive, i, isAltStream)) + if (isAltStream && !processAltStreams) + continue; + } + + RINOK(Archive_IsItem_Dir(archive, i, fp.IsDir)) + + if (fp.IsDir ? listOptions.ExcludeDirItems : listOptions.ExcludeFileItems) + continue; + + if (!allFilesAreAllowed) + { + if (isAltStream) + { + RINOK(arc.GetItem(i, item)) + if (!CensorNode_CheckPath(wildcardCensor, item)) + continue; + } + else + { + SplitPathToParts(fp.FilePath, pathParts); + bool include; + if (!wildcardCensor.CheckPathVect(pathParts, !fp.IsDir, include)) + continue; + if (!include) + continue; + } + } + + CListStat st; + + RINOK(GetUInt64Value(archive, i, kpidSize, st.Size)) + RINOK(GetUInt64Value(archive, i, kpidPackSize, st.PackSize)) + RINOK(GetItemMTime(archive, i, st.MTime)) + + if (fp.IsDir) + stat2.NumDirs++; + else + st.NumFiles = 1; + stat2.GetStat(isAltStream).Update(st); + + if (isAltStream && !showAltStreams) + continue; + RINOK(fp.PrintItemInfo(i, st)) + } + + UInt64 numStreams = stat2.GetNumStreams(); + if (!stdInMode + && !stat2.MainFiles.PackSize.Def + && !stat2.AltStreams.PackSize.Def) + { + if (arcLink.VolumePaths.Size() != 0) + arcPackSize += arcLink.VolumesSize; + stat2.MainFiles.PackSize.Add((numStreams == 0) ? 0 : arcPackSize); + } + + stat2.MainFiles.SetSizeDefIfNoFiles(); + stat2.AltStreams.SetSizeDefIfNoFiles(); + + if (enableHeaders && !techMode) + { + fp.PrintTitleLines(); + g_StdOut << endl; + fp.PrintSum(stat2); + } + + if (enableHeaders) + { + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + g_StdOut << "----------\n"; + PrintPropPair_Path(g_StdOut, arcLink.NonOpen_ArcPath); + PrintArcTypeError(g_StdOut, codecs->Formats[(unsigned)arcLink.NonOpen_ErrorInfo.ErrorFormatIndex].Name, false); + } + } + + stat2total.Update(stat2); + + g_StdOut.Flush(); + } + + if (enableHeaders && !techMode && (arcPaths.Size() > 1 || numVolumes > 1)) + { + g_StdOut << endl; + fp.PrintTitleLines(); + g_StdOut << endl; + fp.PrintSum(stat2total); + g_StdOut << endl; + PrintPropNameAndNumber(g_StdOut, "Archives", numArcs); + PrintPropNameAndNumber(g_StdOut, "Volumes", numVolumes); + PrintPropNameAndNumber(g_StdOut, "Total archives size", totalArcSizes); + } + + if (numErrors == 1 && lastError != 0) + return lastError; + + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/List.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/List.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/List.h 2024-06-06 06:00:00.000000000 +0000 @@ -1,27 +1,42 @@ -// List.h - -#ifndef __LIST_H -#define __LIST_H - -#include "../../../Common/Wildcard.h" - -#include "../Common/LoadCodecs.h" - -HRESULT ListArchives(CCodecs *codecs, - const CObjectVector &types, - const CIntVector &excludedFormats, - bool stdInMode, - UStringVector &archivePaths, UStringVector &archivePathsFull, - bool processAltStreams, bool showAltStreams, - const NWildcard::CCensorNode &wildcardCensor, - bool enableHeaders, bool techMode, - #ifndef _NO_CRYPTO - bool &passwordEnabled, UString &password, - #endif - #ifndef _SFX - const CObjectVector *props, - #endif - UInt64 &errors, - UInt64 &numWarnings); - -#endif +// List.h + +#ifndef ZIP7_INC_LIST_H +#define ZIP7_INC_LIST_H + +#include "../../../Common/Wildcard.h" + +#include "../Common/LoadCodecs.h" + +struct CListOptions +{ + bool ExcludeDirItems; + bool ExcludeFileItems; + bool DisablePercents; + + CListOptions(): + ExcludeDirItems(false), + ExcludeFileItems(false), + DisablePercents(false) + {} +}; + +HRESULT ListArchives( + const CListOptions &listOptions, + CCodecs *codecs, + const CObjectVector &types, + const CIntVector &excludedFormats, + bool stdInMode, + UStringVector &archivePaths, UStringVector &archivePathsFull, + bool processAltStreams, bool showAltStreams, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, + #ifndef Z7_NO_CRYPTO + bool &passwordEnabled, UString &password, + #endif + #ifndef Z7_SFX + const CObjectVector *props, + #endif + UInt64 &errors, + UInt64 &numWarnings); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/Main.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Main.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/Main.cpp 2015-11-06 15:35:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/Main.cpp 2025-01-24 07:00:00.000000000 +0000 @@ -1,1171 +1,1635 @@ -// Main.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyWindows.h" - -#ifdef _WIN32 -#include -#else -#include "myPrivate.h" -#endif - -#include "../../../../C/CpuArch.h" - -#if defined( _7ZIP_LARGE_PAGES) -#include "../../../../C/Alloc.h" -#endif - -#include "../../../Common/MyInitGuid.h" - -#include "../../../Common/CommandLineParser.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/MyException.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/ErrorMsg.h" - -#ifdef _WIN32 -#include "../../../Windows/MemoryLock.h" -#endif - -#include "../../../Windows/TimeUtils.h" - -#include "../Common/ArchiveCommandLine.h" -#include "../Common/ExitCode.h" -#include "../Common/Extract.h" - -#ifdef EXTERNAL_CODECS -#include "../Common/LoadCodecs.h" -#endif - -#include "../../Common/RegisterCodec.h" - -#include "BenchCon.h" -#include "ConsoleClose.h" -#include "ExtractCallbackConsole.h" -#include "List.h" -#include "OpenCallbackConsole.h" -#include "UpdateCallbackConsole.h" - -#include "HashCon.h" - -#ifdef PROG_VARIANT_R -#include "../../../../C/7zVersion.h" -#else -#include "../../MyVersion.h" -#endif - -using namespace NWindows; -using namespace NFile; -using namespace NCommandLineParser; - -#ifdef _WIN32 -HINSTANCE g_hInstance = 0; -#endif - -extern CStdOutStream *g_StdStream; -extern CStdOutStream *g_ErrStream; - -extern unsigned g_NumCodecs; -extern const CCodecInfo *g_Codecs[]; - -extern unsigned g_NumHashers; -extern const CHasherInfo *g_Hashers[]; - -static const char *kCopyrightString = "\n7-Zip" -#ifndef EXTERNAL_CODECS -#ifdef PROG_VARIANT_R -" (r)" -#else -" (a)" -#endif -#endif - -#ifdef MY_CPU_64BIT -" [64]" -#elif defined MY_CPU_32BIT -" [32]" -#endif - -" " MY_VERSION_COPYRIGHT_DATE "\n"; - -static const char *kHelpString = - "Usage: 7z" -#ifndef EXTERNAL_CODECS -#ifdef PROG_VARIANT_R - "r" -#else - "a" -#endif -#endif - " [...] [...]\n" - " [<@listfiles...>]\n" - "\n" - "\n" - " a : Add files to archive\n" - " b : Benchmark\n" - " d : Delete files from archive\n" - " e : Extract files from archive (without using directory names)\n" - " h : Calculate hash values for files\n" - " i : Show information about supported formats\n" - " l : List contents of archive\n" - " rn : Rename files in archive\n" - " t : Test integrity of archive\n" - " u : Update files to archive\n" - " x : eXtract files with full paths\n" - "\n" - "\n" - " -- : Stop switches parsing\n" - " -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n" - " -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n" - " -ao{a|s|t|u} : set Overwrite mode\n" - " -an : disable archive_name field\n" - " -bb[0-3] : set output log level\n" - " -bd : disable progress indicator\n" - " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" - " -bt : show execution time statistics\n" - " -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n" - " -m{Parameters} : set compression Method\n" - " -mmt[N] : set number of CPU threads\n" - " -o{Directory} : set Output directory\n" - #ifndef _NO_CRYPTO - " -p{Password} : set Password\n" - #endif - " -r[-|0] : Recurse subdirectories\n" - " -sa{a|e|s} : set Archive name mode\n" - " -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n" - " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" - " -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n" - " -sdel : delete files after compression\n" - " -seml[.] : send archive by email\n" - " -sfx[{name}] : Create SFX archive\n" - " -si[{name}] : read data from stdin\n" - " -slp : set Large Pages mode\n" - " -slt : show technical information for l (List) command\n" - " -snh : store hard links as links\n" - " -snl : store symbolic links as links\n" - " -sni : store NT security information\n" - " -sns[-] : store NTFS alternate streams\n" - " -so : write data to stdout\n" - " -spd : disable wildcard matching for file names\n" - " -spe : eliminate duplication of root folder for extract command\n" - " -spf : use fully qualified file paths\n" - " -ssc[-] : set sensitive case mode\n" - " -ssw : compress shared files\n" - " -stl : set archive timestamp from the most recently modified file\n" - " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" - " -stx{Type} : exclude archive type\n" - " -t{Type} : Set type of archive\n" - " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" - " -v{Size}[b|k|m|g] : Create volumes\n" - " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" - " -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames\n" - " -y : assume Yes on all queries\n"; - -// --------------------------- -// exception messages - -static const char *kEverythingIsOk = "Everything is Ok"; -static const char *kUserErrorMessage = "Incorrect command line"; -static const char *kNoFormats = "7-Zip cannot find the code that works with archives."; -static const char *kUnsupportedArcTypeMessage = "Unsupported archive type"; -// static const char *kUnsupportedUpdateArcType = "Can't create archive for that type"; - -static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx"); - -static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) -{ - if (g_ErrStream) - *g_ErrStream << endl << "ERROR: " << message << endl; - throw code; -} - -#ifndef _WIN32 -static void GetArguments(int numArgs, const char *args[], UStringVector &parts) -{ - parts.Clear(); - for (int i = 0; i < numArgs; i++) - { - UString s = MultiByteToUnicodeString(args[i]); - parts.Add(s); - } -} -#endif - -static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) -{ - if (!so) - return; - *so << kCopyrightString; - // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; - - showP7zipInfo(so); - - - if (needHelp) - *so << kHelpString; -} - - -static void PrintStringRight(CStdOutStream &so, const AString &s, unsigned size) -{ - unsigned len = s.Len(); - for (unsigned i = len; i < size; i++) - so << ' '; - so << s; -} - -static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) -{ - char s[16]; - ConvertUInt32ToString(val, s); - PrintStringRight(so, s, size); -} - -static void PrintLibIndex(CStdOutStream &so, int libIndex) -{ - if (libIndex >= 0) - PrintUInt32(so, libIndex, 2); - else - so << " "; - so << ' '; -} - -static void PrintString(CStdOutStream &so, const UString &s, unsigned size) -{ - unsigned len = s.Len(); - so << s; - for (unsigned i = len; i < size; i++) - so << ' '; -} - -static inline char GetHex(unsigned val) -{ - return (char)((val < 10) ? ('0' + val) : ('A' + (val - 10))); -} - -static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) -{ - FOR_VECTOR(i, pc.Paths) - { - so << pc.Paths[i] << " : "; - so << NError::MyFormatMessage(pc.Codes[i]) << endl; - } - so << "----------------" << endl; -} - -static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, - const CUpdateErrorInfo &errorInfo, - CStdOutStream *so, - CStdOutStream *se, - bool showHeaders) -{ - int exitCode = NExitCode::kSuccess; - - if (callback.ScanErrors.Paths.Size() != 0) - { - if (se) - { - *se << endl; - *se << "Scan WARNINGS for files and folders:" << endl << endl; - PrintWarningsPaths(callback.ScanErrors, *se); - *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size(); - *se << endl; - } - exitCode = NExitCode::kWarning; - } - - if (result != S_OK || errorInfo.ThereIsError()) - { - if (se) - { - UString message; - if (!errorInfo.Message.IsEmpty()) - { - message.AddAscii(errorInfo.Message); - message.Add_LF(); - } - { - FOR_VECTOR(i, errorInfo.FileNames) - { - message += fs2us(errorInfo.FileNames[i]); - message.Add_LF(); - } - } - if (errorInfo.SystemError != 0) - { - message += NError::MyFormatMessage(errorInfo.SystemError); - message.Add_LF(); - } - if (!message.IsEmpty()) - *se << L"\nError:\n" << message; - } - - // we will work with (result) later - // throw CSystemException(result); - return NExitCode::kFatalError; - } - - unsigned numErrors = callback.FailedFiles.Paths.Size(); - if (numErrors == 0) - { - if (showHeaders) - if (callback.ScanErrors.Paths.Size() == 0) - if (so) - { - if (se) - se->Flush(); - *so << kEverythingIsOk << endl; - } - } - else - { - if (se) - { - *se << endl; - *se << "WARNINGS for files:" << endl << endl; - PrintWarningsPaths(callback.FailedFiles, *se); - *se << "WARNING: Cannot open " << numErrors << " file"; - if (numErrors > 1) - *se << 's'; - *se << endl; - } - exitCode = NExitCode::kWarning; - } - - return exitCode; -} - -static void ThrowException_if_Error(HRESULT res) -{ - if (res != S_OK) - throw CSystemException(res); -} - - -static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') -{ - char temp[64]; - char *p = temp + 32; - ConvertUInt64ToString(val, p); - unsigned len = MyStringLen(p); - for (; len < numDigits; len++) - *--p = c; - *g_StdStream << p; -} - -static void PrintTime(const char *s, UInt64 val, UInt64 total) -{ - *g_StdStream << endl << s << " Time ="; - const UInt32 kFreq = 10000000; - UInt64 sec = val / kFreq; - PrintNum(sec, 6); - *g_StdStream << '.'; - UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); - PrintNum(ms, 3, '0'); - - while (val > ((UInt64)1 << 56)) - { - val >>= 1; - total >>= 1; - } - - UInt64 percent = 0; - if (total != 0) - percent = val * 100 / total; - *g_StdStream << " ="; - PrintNum(percent, 5); - *g_StdStream << '%'; -} - -#if 0 // #ifndef UNDER_CE - -#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num)) - -static void PrintMemUsage(const char *s, UInt64 val) -{ - *g_StdStream << " " << s << " Memory ="; - PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); - *g_StdStream << " MB"; -} - -EXTERN_C_BEGIN -typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, - PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); -EXTERN_C_END - -#endif - -static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } - -static void PrintStat() -{ -#if 0 - FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; - if (! - #ifdef UNDER_CE - ::GetThreadTimes(::GetCurrentThread() - #else - // NT 3.5 - ::GetProcessTimes(::GetCurrentProcess() - #endif - , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) - return; - FILETIME curTimeFT; - NTime::GetCurUtcFileTime(curTimeFT); - - #ifndef UNDER_CE - - PROCESS_MEMORY_COUNTERS m; - memset(&m, 0, sizeof(m)); - BOOL memDefined = FALSE; - { - /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll - Win7: new function K32GetProcessMemoryInfo() in kernel32.dll - It's faster to call kernel32.dll code than Psapi.dll code - GetProcessMemoryInfo() requires Psapi.lib - Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll - The program with K32GetProcessMemoryInfo will not work on systems before Win7 - // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); - */ - - Func_GetProcessMemoryInfo my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo) - ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "K32GetProcessMemoryInfo"); - if (!my_GetProcessMemoryInfo) - { - HMODULE lib = LoadLibraryW(L"Psapi.dll"); - if (lib) - my_GetProcessMemoryInfo = (Func_GetProcessMemoryInfo)::GetProcAddress(lib, "GetProcessMemoryInfo"); - } - if (my_GetProcessMemoryInfo) - memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); - // FreeLibrary(lib); - } - - #endif - - UInt64 curTime = GetTime64(curTimeFT); - UInt64 creationTime = GetTime64(creationTimeFT); - UInt64 kernelTime = GetTime64(kernelTimeFT); - UInt64 userTime = GetTime64(userTimeFT); - - UInt64 totalTime = curTime - creationTime; - - PrintTime("Kernel ", kernelTime, totalTime); - PrintTime("User ", userTime, totalTime); - - PrintTime("Process", kernelTime + userTime, totalTime); - #ifndef UNDER_CE - if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); - #endif - - PrintTime("Global ", totalTime, totalTime); - #ifndef UNDER_CE - if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); - #endif - - *g_StdStream << endl; -#endif // FIXME -} - -static void PrintHexId(CStdOutStream &so, UInt64 id) -{ - char s[32]; - ConvertUInt64ToHex(id, s); - PrintStringRight(so, s, 8); -} - -int Main2( - #ifndef _WIN32 - int numArgs, char *args[] - #endif -) -{ - #if defined(_WIN32) && !defined(UNDER_CE) - SetFileApisToOEM(); - #endif - - UStringVector commandStrings; - - #ifdef _WIN32 - NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); - #else - // GetArguments(numArgs, args, commandStrings); - mySplitCommandLine(numArgs,args,commandStrings); - #endif - - if (commandStrings.Size() == 1) - { - ShowCopyrightAndHelp(g_StdStream, true); - return 0; - } - - commandStrings.Delete(0); - - CArcCmdLineOptions options; - - CArcCmdLineParser parser; - - parser.Parse1(commandStrings, options); - - - if (options.Number_for_Out != k_OutStream_stdout) - g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); - - if (options.Number_for_Errors != k_OutStream_stderr) - g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL); - - CStdOutStream *percentsStream = NULL; - if (options.Number_for_Percents != k_OutStream_disabled) - percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut;; - - if (options.HelpMode) - { - ShowCopyrightAndHelp(g_StdStream, true); - return 0; - } - - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_SymLink(); - #endif - - #ifdef _7ZIP_LARGE_PAGES - if (options.LargePages) - { - SetLargePageSize(); - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_LockMemory(); - #endif - } - #endif - - if (options.EnableHeaders) - ShowCopyrightAndHelp(g_StdStream, false); - - parser.Parse2(options); - - unsigned percentsNameLevel = 1; - if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) - percentsNameLevel = 2; - - unsigned consoleWidth = 80; // FIXME - - if (percentsStream) - { -/* FIXME - #ifdef _WIN32 - - #if !defined(UNDER_CE) - CONSOLE_SCREEN_BUFFER_INFO consoleInfo; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) - consoleWidth = consoleInfo.dwSize.X; - #endif - - #else - - struct winsize w; - if (ioctl(0, TIOCGWINSZ, &w) == ) - consoleWidth = w.ws_col; - - #endif -*/ - } - - CREATE_CODECS_OBJECT - - codecs->CaseSensitiveChange = options.CaseSensitiveChange; - codecs->CaseSensitive = options.CaseSensitive; - ThrowException_if_Error(codecs->Load()); - - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); - - if (codecs->Formats.Size() == 0 && - (isExtractGroupCommand - || options.Command.CommandType == NCommandType::kList - || options.Command.IsFromUpdateGroup())) - { - #ifdef EXTERNAL_CODECS - if (!codecs->MainDll_ErrorPath.IsEmpty()) - { - UString s = L"Can't load module "; - s += fs2us(codecs->MainDll_ErrorPath); - throw s; - } - #endif - - throw kNoFormats; - } - - CObjectVector types; - if (!ParseOpenTypes(*codecs, options.ArcType, types)) - throw kUnsupportedArcTypeMessage; - - CIntVector excludedFormats; - FOR_VECTOR (k, options.ExcludedArcTypes) - { - CIntVector tempIndices; - if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) - || tempIndices.Size() != 1) - throw kUnsupportedArcTypeMessage; - excludedFormats.AddToUniqueSorted(tempIndices[0]); - // excludedFormats.Sort(); - } - - - #ifdef EXTERNAL_CODECS - if (isExtractGroupCommand - || options.Command.CommandType == NCommandType::kHash - || options.Command.CommandType == NCommandType::kBenchmark) - ThrowException_if_Error(__externalCodecs.Load()); - #endif - - int retCode = NExitCode::kSuccess; - HRESULT hresultMain = S_OK; - - // bool showStat = options.ShowTime; - - /* - if (!options.EnableHeaders || - options.TechMode) - showStat = false; - */ - - - if (options.Command.CommandType == NCommandType::kInfo) - { - CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); - unsigned i; - - #ifdef EXTERNAL_CODECS - so << endl << "Libs:" << endl; - for (i = 0; i < codecs->Libs.Size(); i++) - { - PrintLibIndex(so, i); - so << ' ' << codecs->Libs[i].Path << endl; - } - #endif - - so << endl << "Formats:" << endl; - - const char *kArcFlags = "KSNFMGOPBELH"; - const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); - - for (i = 0; i < codecs->Formats.Size(); i++) - { - const CArcInfoEx &arc = codecs->Formats[i]; - - #ifdef EXTERNAL_CODECS - PrintLibIndex(so, arc.LibIndex); - #else - so << " "; - #endif - - so << (char)(arc.UpdateEnabled ? 'C' : ' '); - - for (unsigned b = 0; b < kNumArcFlags; b++) - { - so << (char) - ((arc.Flags & ((UInt32)1 << b)) != 0 ? kArcFlags[b] : ' '); - } - - so << ' '; - PrintString(so, arc.Name, 8); - so << ' '; - UString s; - - FOR_VECTOR (t, arc.Exts) - { - if (t != 0) - s.Add_Space(); - const CArcExtInfo &ext = arc.Exts[t]; - s += ext.Ext; - if (!ext.AddExt.IsEmpty()) - { - s += L" ("; - s += ext.AddExt; - s += L')'; - } - } - - PrintString(so, s, 13); - so << ' '; - - if (arc.SignatureOffset != 0) - so << "offset=" << arc.SignatureOffset << ' '; - - FOR_VECTOR(si, arc.Signatures) - { - if (si != 0) - so << " || "; - - const CByteBuffer &sig = arc.Signatures[si]; - - for (size_t j = 0; j < sig.Size(); j++) - { - if (j != 0) - so << ' '; - Byte b = sig[j]; - if (b > 0x20 && b < 0x80) - { - so << (char)b; - } - else - { - so << GetHex((b >> 4) & 0xF); - so << GetHex(b & 0xF); - } - } - } - so << endl; - } - - so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl; - - for (i = 0; i < g_NumCodecs; i++) - { - const CCodecInfo &cod = *g_Codecs[i]; - - PrintLibIndex(so, -1); - - if (cod.NumStreams == 1) - so << ' '; - else - so << cod.NumStreams; - - so << (char)(cod.CreateEncoder ? 'E' : ' '); - so << (char)(cod.CreateDecoder ? 'D' : ' '); - - so << ' '; - PrintHexId(so, cod.Id); - so << ' ' << cod.Name << endl; - } - - - #ifdef EXTERNAL_CODECS - - UInt32 numMethods; - if (codecs->GetNumMethods(&numMethods) == S_OK) - for (UInt32 j = 0; j < numMethods; j++) - { - PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); - - UInt32 numStreams = codecs->GetCodec_NumStreams(j); - if (numStreams == 1) - so << ' '; - else - so << numStreams; - - so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); - so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); - - so << ' '; - UInt64 id; - HRESULT res = codecs->GetCodec_Id(j, id); - if (res != S_OK) - id = (UInt64)(Int64)-1; - PrintHexId(so, id); - so << ' ' << codecs->GetCodec_Name(j) << endl; - } - - #endif - - - so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl; - - for (i = 0; i < g_NumHashers; i++) - { - const CHasherInfo &codec = *g_Hashers[i]; - PrintLibIndex(so, -1); - PrintUInt32(so, codec.DigestSize, 4); - so << ' '; - PrintHexId(so, codec.Id); - so << ' ' << codec.Name << endl; - } - - #ifdef EXTERNAL_CODECS - - numMethods = codecs->GetNumHashers(); - for (UInt32 j = 0; j < numMethods; j++) - { - PrintLibIndex(so, codecs->GetHasherLibIndex(j)); - PrintUInt32(so, codecs->GetHasherDigestSize(j), 4); - so << ' '; - PrintHexId(so, codecs->GetHasherId(j)); - so << ' ' << codecs->GetHasherName(j) << endl; - } - - #endif - - } - else if (options.Command.CommandType == NCommandType::kBenchmark) - { - CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); - hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L - options.Properties, options.NumIterations, (FILE *)so); - if (hresultMain == S_FALSE) - { - if (g_ErrStream) - *g_ErrStream << "\nDecoding ERROR\n"; - retCode = NExitCode::kFatalError; - hresultMain = S_OK; - } - } - else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) - { - UStringVector ArchivePathsSorted; - UStringVector ArchivePathsFullSorted; - - if (options.StdInMode) - { - ArchivePathsSorted.Add(options.ArcName_for_StdInMode); - ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode); - } - else - { - CExtractScanConsole scan; - - scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream); - scan.SetWindowWidth(consoleWidth); - - if (g_StdStream && options.EnableHeaders) - *g_StdStream << "Scanning the drive for archives:" << endl; - - CDirItemsStat st; - - scan.StartScanning(); - - hresultMain = EnumerateDirItemsAndSort( - options.arcCensor, - NWildcard::k_RelatPath, - UString(), // addPathPrefix - ArchivePathsSorted, - ArchivePathsFullSorted, - st, - &scan); - - scan.CloseScanning(); - - if (hresultMain == S_OK) - { - if (options.EnableHeaders) - scan.PrintStat(st); - } - else - { - /* - if (res != E_ABORT) - { - throw CSystemException(res); - // errorInfo.Message = "Scanning error"; - } - return res; - */ - } - } - - if (hresultMain == S_OK) - if (isExtractGroupCommand) - { - CExtractCallbackConsole *ecs = new CExtractCallbackConsole; - CMyComPtr extractCallback = ecs; - - #ifndef _NO_CRYPTO - ecs->PasswordIsDefined = options.PasswordEnabled; - ecs->Password = options.Password; - #endif - - ecs->Init(g_StdStream, g_ErrStream, percentsStream); - ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); - - ecs->LogLevel = options.LogLevel; - ecs->PercentsNameLevel = percentsNameLevel; - - if (percentsStream) - ecs->SetWindowWidth(consoleWidth); - - /* - COpenCallbackConsole openCallback; - openCallback.Init(g_StdStream, g_ErrStream); - - #ifndef _NO_CRYPTO - openCallback.PasswordIsDefined = options.PasswordEnabled; - openCallback.Password = options.Password; - #endif - */ - - CExtractOptions eo; - (CExtractOptionsBase &)eo = options.ExtractOptions; - - eo.StdInMode = options.StdInMode; - eo.StdOutMode = options.StdOutMode; - eo.YesToAll = options.YesToAll; - eo.TestMode = options.Command.IsTestCommand(); - - #ifndef _SFX - eo.Properties = options.Properties; - #endif - - UString errorMessage; - CDecompressStat stat; - CHashBundle hb; - IHashCalc *hashCalc = NULL; - - if (!options.HashMethods.IsEmpty()) - { - hashCalc = &hb; - ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); - hb.Init(); - } - - hresultMain = Extract( - codecs, - types, - excludedFormats, - ArchivePathsSorted, - ArchivePathsFullSorted, - options.Censor.Pairs.Front().Head, - eo, ecs, ecs, hashCalc, errorMessage, stat); - - ecs->ClosePercents(); - - if (!errorMessage.IsEmpty()) - { - if (g_ErrStream) - *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl; - if (hresultMain == S_OK) - hresultMain = E_FAIL; - } - - CStdOutStream *so = g_StdStream; - - bool isError = false; - - if (so) - { - *so << endl; - - if (ecs->NumTryArcs > 1) - { - *so << "Archives: " << ecs->NumTryArcs << endl; - *so << "OK archives: " << ecs->NumOkArcs << endl; - } - } - - if (ecs->NumCantOpenArcs != 0) - { - isError = true; - if (so) - *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl; - } - - if (ecs->NumArcsWithError != 0) - { - isError = true; - if (so) - *so << "Archives with Errors: " << ecs->NumArcsWithError << endl; - } - - if (so) - { - if (ecs->NumArcsWithWarnings != 0) - *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl; - - if (ecs->NumOpenArcWarnings != 0) - { - *so << endl; - if (ecs->NumOpenArcWarnings != 0) - *so << "Warnings: " << ecs->NumOpenArcWarnings << endl; - } - } - - if (ecs->NumOpenArcErrors != 0) - { - isError = true; - if (so) - { - *so << endl; - if (ecs->NumOpenArcErrors != 0) - *so << "Open Errors: " << ecs->NumOpenArcErrors << endl; - } - } - - if (isError) - retCode = NExitCode::kFatalError; - - if (so) - if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) - { - // if (ecs->NumArchives > 1) - { - *so << endl; - if (ecs->NumFileErrors != 0) - *so << "Sub items Errors: " << ecs->NumFileErrors << endl; - } - } - else if (hresultMain == S_OK) - { - if (stat.NumFolders != 0) - *so << "Folders: " << stat.NumFolders << endl; - if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0) - *so << "Files: " << stat.NumFiles << endl; - if (stat.NumAltStreams != 0) - { - *so << "Alternate Streams: " << stat.NumAltStreams << endl; - *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl; - } - - *so - << "Size: " << stat.UnpackSize << endl - << "Compressed: " << stat.PackSize << endl; - if (hashCalc) - { - *so << endl; - PrintHashStat(*so, hb); - } - } - } - else - { - UInt64 numErrors = 0; - UInt64 numWarnings = 0; - - // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed - - hresultMain = ListArchives( - codecs, - types, - excludedFormats, - options.StdInMode, - ArchivePathsSorted, - ArchivePathsFullSorted, - options.ExtractOptions.NtOptions.AltStreams.Val, - options.AltStreams.Val, // we don't want to show AltStreams by default - options.Censor.Pairs.Front().Head, - options.EnableHeaders, - options.TechMode, - #ifndef _NO_CRYPTO - options.PasswordEnabled, - options.Password, - #endif - &options.Properties, - numErrors, numWarnings); - - if (options.EnableHeaders) - if (numWarnings > 0) - g_StdOut << endl << "Warnings: " << numWarnings << endl; - - if (numErrors > 0) - { - if (options.EnableHeaders) - g_StdOut << endl << "Errors: " << numErrors << endl; - retCode = NExitCode::kFatalError; - } - } - } - else if (options.Command.IsFromUpdateGroup()) - { - CUpdateOptions &uo = options.UpdateOptions; - if (uo.SfxMode && uo.SfxModule.IsEmpty()) - uo.SfxModule = kDefaultSfxModule; - - COpenCallbackConsole openCallback; - openCallback.Init(g_StdStream, g_ErrStream, percentsStream); - - #ifndef _NO_CRYPTO - bool passwordIsDefined = - (options.PasswordEnabled && !options.Password.IsEmpty()); - openCallback.PasswordIsDefined = passwordIsDefined; - openCallback.Password = options.Password; - #endif - - CUpdateCallbackConsole callback; - callback.LogLevel = options.LogLevel; - callback.PercentsNameLevel = percentsNameLevel; - - if (percentsStream) - callback.SetWindowWidth(consoleWidth); - - #ifndef _NO_CRYPTO - callback.PasswordIsDefined = passwordIsDefined; - callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); - callback.Password = options.Password; - #endif - - callback.StdOutMode = uo.StdOutMode; - callback.Init( - // NULL, - g_StdStream, g_ErrStream, percentsStream); - - CUpdateErrorInfo errorInfo; - - /* - if (!uo.Init(codecs, types, options.ArchiveName)) - throw kUnsupportedUpdateArcType; - */ - hresultMain = UpdateArchive(codecs, - types, - options.ArchiveName, - options.Censor, - uo, - errorInfo, &openCallback, &callback, true); - - callback.ClosePercents2(); - - CStdOutStream *se = g_StdStream; - if (!se) - se = g_ErrStream; - - retCode = WarningsCheck(hresultMain, callback, errorInfo, - g_StdStream, se, - true // options.EnableHeaders - ); -#ifdef ENV_UNIX - if (uo.SfxMode) - { - void myAddExeFlag(const UString &name); - for(int i = 0; i < uo.Commands.Size(); i++) - { - CUpdateArchiveCommand &command = uo.Commands[i]; - if (!uo.StdOutMode) - { - myAddExeFlag(command.ArchivePath.GetFinalPath()); - } - } - } -#endif - } - else if (options.Command.CommandType == NCommandType::kHash) - { - const CHashOptions &uo = options.HashOptions; - - CHashCallbackConsole callback; - if (percentsStream) - callback.SetWindowWidth(consoleWidth); - - callback.Init(g_StdStream, g_ErrStream, percentsStream); - callback.PrintHeaders = options.EnableHeaders; - - AString errorInfoString; - hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L - options.Censor, uo, - errorInfoString, &callback); - CUpdateErrorInfo errorInfo; - errorInfo.Message = errorInfoString; - CStdOutStream *se = g_StdStream; - if (!se) - se = g_ErrStream; - retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders); - } - else - ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); - - if (options.ShowTime && g_StdStream) - PrintStat(); - - ThrowException_if_Error(hresultMain); - - return retCode; -} +// Main.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#ifdef _WIN32 + +#ifndef Z7_OLD_WIN_SDK + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#else // Z7_OLD_WIN_SDK + +typedef struct { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS; +typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + +#endif // Z7_OLD_WIN_SDK + +#else // _WIN32 +#include +#include +#include +#include +#endif // _WIN32 + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StdInStream.h" +#include "../../../Common/StdOutStream.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" +#include "../../../Common/UTFConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/TimeUtils.h" +#include "../../../Windows/FileDir.h" + +#include "../Common/ArchiveCommandLine.h" +#include "../Common/Bench.h" +#include "../Common/ExitCode.h" +#include "../Common/Extract.h" + +#ifdef Z7_EXTERNAL_CODECS +#include "../Common/LoadCodecs.h" +#endif + +#include "../../Common/RegisterCodec.h" + +#include "BenchCon.h" +#include "ConsoleClose.h" +#include "ExtractCallbackConsole.h" +#include "HashCon.h" +#include "List.h" +#include "OpenCallbackConsole.h" +#include "UpdateCallbackConsole.h" + +#ifdef Z7_PROG_VARIANT_R +#include "../../../../C/7zVersion.h" +#else +#include "../../MyVersion.h" +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NCommandLineParser; + +#ifdef _WIN32 +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; +#endif + +extern CStdOutStream *g_StdStream; +extern CStdOutStream *g_ErrStream; + +extern unsigned g_NumCodecs; +extern const CCodecInfo *g_Codecs[]; + +extern unsigned g_NumHashers; +extern const CHasherInfo *g_Hashers[]; + +#ifdef Z7_EXTERNAL_CODECS +extern +const CExternalCodecs *g_ExternalCodecs_Ptr; +const CExternalCodecs *g_ExternalCodecs_Ptr; +#endif + +DECLARE_AND_SET_CLIENT_VERSION_VAR + +#if defined(Z7_PROG_VARIANT_Z) + #define PROG_POSTFIX "z" + #define PROG_POSTFIX_2 " (z)" +#elif defined(Z7_PROG_VARIANT_R) + #define PROG_POSTFIX "r" + #define PROG_POSTFIX_2 " (r)" +#elif defined(Z7_PROG_VARIANT_A) || !defined(Z7_EXTERNAL_CODECS) + #define PROG_POSTFIX "a" + #define PROG_POSTFIX_2 " (a)" +#else + #define PROG_POSTFIX "" + #define PROG_POSTFIX_2 "" +#endif + + +static const char * const kCopyrightString = "\n7-Zip" + PROG_POSTFIX_2 + " " MY_VERSION_CPU + " : " MY_COPYRIGHT_DATE "\n"; + +static const char * const kHelpString = + "Usage: 7z" + PROG_POSTFIX + " [...] [...] [@listfile]\n" + "\n" + "\n" + " a : Add files to archive\n" + " b : Benchmark\n" + " d : Delete files from archive\n" + " e : Extract files from archive (without using directory names)\n" + " h : Calculate hash values for files\n" + " i : Show information about supported formats\n" + " l : List contents of archive\n" + " rn : Rename files in archive\n" + " t : Test integrity of archive\n" + " u : Update files to archive\n" + " x : eXtract files with full paths\n" + "\n" + "\n" + " -- : Stop switches and @listfile parsing\n" + " -ai[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : Include archives\n" + " -ax[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : eXclude archives\n" + " -ao{a|s|t|u} : set Overwrite mode\n" + " -an : disable archive_name field\n" + " -bb[0-3] : set output log level\n" + " -bd : disable progress indicator\n" + " -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n" + " -bt : show execution time statistics\n" + " -i[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : Include filenames\n" + " -m{Parameters} : set compression Method\n" + " -mmt[N] : set number of CPU threads\n" + " -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)\n" + " -o{Directory} : set Output directory\n" + #ifndef Z7_NO_CRYPTO + " -p{Password} : set Password\n" + #endif + " -r[-|0] : Recurse subdirectories for name search\n" + " -sa{a|e|s} : set Archive name mode\n" + " -scc{UTF-8|WIN|DOS} : set charset for console input/output\n" + " -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n" + " -scrc[CRC32|CRC64|SHA256" +#ifndef Z7_PROG_VARIANT_R + "|SHA1|XXH64" +#ifdef Z7_PROG_VARIANT_Z + "|BLAKE2SP" +#endif +#endif + "|*] : set hash function for x, e, h commands\n" + " -sdel : delete files after compression\n" + " -seml[.] : send archive by email\n" + " -sfx[{name}] : Create SFX archive\n" + " -si[{name}] : read data from stdin\n" + " -slp : set Large Pages mode\n" + " -slt : show technical information for l (List) command\n" + " -snh : store hard links as links\n" + " -snl : store symbolic links as links\n" + " -sni : store NT security information\n" + " -sns[-] : store NTFS alternate streams\n" + " -so : write data to stdout\n" + " -spd : disable wildcard matching for file names\n" + " -spe : eliminate duplication of root folder for extract command\n" + " -spf[2] : use fully qualified file paths\n" + " -ssc[-] : set sensitive case mode\n" + " -sse : stop archive creating, if it can't open some input file\n" + " -ssp : do not change Last Access Time of source files while archiving\n" + " -ssw : compress shared files\n" + " -stl : set archive timestamp from the most recently modified file\n" + " -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n" + " -stx{Type} : exclude archive type\n" + " -t{Type} : Set type of archive\n" + " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n" + " -v{Size}[b|k|m|g] : Create volumes\n" + " -w[{path}] : assign Work directory. Empty path means a temporary directory\n" + " -x[r[-|0]][m[-|2]][w[-]]{@listfile|!wildcard} : eXclude filenames\n" + " -y : assume Yes on all queries\n"; + +// --------------------------- +// exception messages + +static const char * const kEverythingIsOk = "Everything is Ok"; +static const char * const kUserErrorMessage = "Incorrect command line"; +static const char * const kNoFormats = "7-Zip cannot find the code that works with archives."; +static const char * const kUnsupportedArcTypeMessage = "Unsupported archive type"; +// static const char * const kUnsupportedUpdateArcType = "Can't create archive for that type"; + +#ifndef Z7_EXTRACT_ONLY +#define kDefaultSfxModule "7zCon.sfx" +#endif + +Z7_ATTR_NORETURN +static void ShowMessageAndThrowException(LPCSTR message, NExitCode::EEnum code) +{ + if (g_ErrStream) + *g_ErrStream << endl << "ERROR: " << message << endl; + throw code; +} + + +#ifdef _WIN32 +#define ShowProgInfo(so) +#else +static void ShowProgInfo(CStdOutStream *so) +{ + if (!so) + return; + + *so + + /* + #ifdef __DATE__ + << " " << __DATE__ + #endif + #ifdef __TIME__ + << " " << __TIME__ + #endif + */ + + << " " << (unsigned)(sizeof(void *)) * 8 << "-bit" + + #ifdef __ILP32__ + << " ILP32" + #endif + + #ifdef __ARM_ARCH + << " arm_v:" << __ARM_ARCH + #if (__ARM_ARCH == 8) + // for macos: + #if defined(__ARM_ARCH_8_9__) + << ".9" + #elif defined(__ARM_ARCH_8_8__) + << ".8" + #elif defined(__ARM_ARCH_8_7__) + << ".7" + #elif defined(__ARM_ARCH_8_6__) + << ".6" + #elif defined(__ARM_ARCH_8_5__) + << ".5" + #elif defined(__ARM_ARCH_8_4__) + << ".4" + #elif defined(__ARM_ARCH_8_3__) + << ".3" + #elif defined(__ARM_ARCH_8_2__) + << ".2" + #elif defined(__ARM_ARCH_8_1__) + << ".1" + #endif + #endif + + #if defined(__ARM_ARCH_PROFILE) && \ + ( __ARM_ARCH_PROFILE >= 'A' && __ARM_ARCH_PROFILE <= 'Z' \ + || __ARM_ARCH_PROFILE >= 65 && __ARM_ARCH_PROFILE <= 65 + 25) + << "-" << (char)__ARM_ARCH_PROFILE + #endif + + #ifdef __ARM_ARCH_ISA_THUMB + << " thumb:" << __ARM_ARCH_ISA_THUMB + #endif + #endif + + #ifdef _MIPS_ARCH + << " mips_arch:" << _MIPS_ARCH + #endif + #ifdef __mips_isa_rev + << " mips_isa_rev:" << __mips_isa_rev + #endif + + #ifdef __iset__ + << " e2k_v:" << __iset__ + #endif + ; + + + + #ifdef ENV_HAVE_LOCALE + *so << " locale=" << GetLocale(); + #endif + #ifndef _WIN32 + { + const bool is_IsNativeUTF8 = IsNativeUTF8(); + if (!is_IsNativeUTF8) + *so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-"); + } + if (!g_ForceToUTF8) + *so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-"); + { + const unsigned wchar_t_size = (unsigned)sizeof(wchar_t); + if (wchar_t_size != 4) + *so << " wchar_t=" << wchar_t_size * 8 << "-bit"; + } + { + const unsigned off_t_size = (unsigned)sizeof(off_t); + if (off_t_size != 8) + *so << " Files=" << off_t_size * 8 << "-bit"; + } + #endif + + { + const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors(); + *so << " Threads:" << numCpus; + const UInt64 openMAX= NWindows::NSystem::Get_File_OPEN_MAX(); + *so << " OPEN_MAX:" << openMAX; + { + FString temp; + NDir::MyGetTempPath(temp); + if (!temp.IsEqualTo(STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR)) + *so << " temp_path:" << temp; + } + } + + #ifdef Z7_7ZIP_ASM + *so << ", ASM"; + #endif + + /* + { + AString s; + GetCpuName(s); + s.Trim(); + *so << ", " << s; + } + + #ifdef __ARM_FEATURE_CRC32 + << " CRC32" + #endif + + + #if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64)) + if (CPU_IsSupported_AES()) *so << ",AES"; + #endif + + #ifdef MY_CPU_ARM_OR_ARM64 + if (CPU_IsSupported_CRC32()) *so << ",CRC32"; + #if defined(_WIN32) + if (CPU_IsSupported_CRYPTO()) *so << ",CRYPTO"; + #else + if (CPU_IsSupported_SHA1()) *so << ",SHA1"; + if (CPU_IsSupported_SHA2()) *so << ",SHA2"; + #endif + #endif + */ + + *so << endl; +} +#endif + +static void ShowCopyrightAndHelp(CStdOutStream *so, bool needHelp) +{ + if (!so) + return; + *so << kCopyrightString; + // *so << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << endl; + ShowProgInfo(so); + *so << endl; + if (needHelp) + *so << kHelpString; +} + + +static void PrintStringRight(CStdOutStream &so, const char *s, unsigned size) +{ + unsigned len = MyStringLen(s); + for (unsigned i = len; i < size; i++) + so << ' '; + so << s; +} + +static void PrintUInt32(CStdOutStream &so, UInt32 val, unsigned size) +{ + char s[16]; + ConvertUInt32ToString(val, s); + PrintStringRight(so, s, size); +} + +#ifdef Z7_EXTERNAL_CODECS +static void PrintNumber(CStdOutStream &so, UInt32 val, unsigned numDigits) +{ + AString s; + s.Add_UInt32(val); + while (s.Len() < numDigits) + s.InsertAtFront('0'); + so << s; +} +#endif + +static void PrintLibIndex(CStdOutStream &so, int libIndex) +{ + if (libIndex >= 0) + PrintUInt32(so, (UInt32)libIndex, 2); + else + so << " "; + so << ' '; +} + +static void PrintString(CStdOutStream &so, const UString &s, unsigned size) +{ + unsigned len = s.Len(); + so << s; + for (unsigned i = len; i < size; i++) + so << ' '; +} + +static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) +{ + FOR_VECTOR(i, pc.Paths) + { + so.NormalizePrint_UString_Path(fs2us(pc.Paths[i])); + so << " : "; + so << NError::MyFormatMessage(pc.Codes[i]) << endl; + } + so << "----------------" << endl; +} + +static int WarningsCheck(HRESULT result, const CCallbackConsoleBase &callback, + const CUpdateErrorInfo &errorInfo, + CStdOutStream *so, + CStdOutStream *se, + bool showHeaders) +{ + int exitCode = NExitCode::kSuccess; + + if (callback.ScanErrors.Paths.Size() != 0) + { + if (se) + { + *se << endl; + *se << "Scan WARNINGS for files and folders:" << endl << endl; + PrintWarningsPaths(callback.ScanErrors, *se); + *se << "Scan WARNINGS: " << callback.ScanErrors.Paths.Size(); + *se << endl; + } + exitCode = NExitCode::kWarning; + } + + if (result != S_OK || errorInfo.ThereIsError()) + { + if (se) + { + UString message; + if (!errorInfo.Message.IsEmpty()) + { + message += errorInfo.Message.Ptr(); + message.Add_LF(); + } + { + FOR_VECTOR(i, errorInfo.FileNames) + { + message += fs2us(errorInfo.FileNames[i]); + message.Add_LF(); + } + } + if (errorInfo.SystemError != 0) + { + message += NError::MyFormatMessage(errorInfo.SystemError); + message.Add_LF(); + } + if (!message.IsEmpty()) + *se << L"\nError:\n" << message; + } + + // we will work with (result) later + // throw CSystemException(result); + return NExitCode::kFatalError; + } + + unsigned numErrors = callback.FailedFiles.Paths.Size(); + if (numErrors == 0) + { + if (showHeaders) + if (callback.ScanErrors.Paths.Size() == 0) + if (so) + { + if (se) + se->Flush(); + *so << kEverythingIsOk << endl; + } + } + else + { + if (se) + { + *se << endl; + *se << "WARNINGS for files:" << endl << endl; + PrintWarningsPaths(callback.FailedFiles, *se); + *se << "WARNING: Cannot open " << numErrors << " file"; + if (numErrors > 1) + *se << 's'; + *se << endl; + } + exitCode = NExitCode::kWarning; + } + + return exitCode; +} + +static void ThrowException_if_Error(HRESULT res) +{ + if (res != S_OK) + throw CSystemException(res); +} + +static void PrintNum(UInt64 val, unsigned numDigits, char c = ' ') +{ + char temp[64]; + char *p = temp + 32; + ConvertUInt64ToString(val, p); + unsigned len = MyStringLen(p); + for (; len < numDigits; len++) + *--p = c; + *g_StdStream << p; +} + +#ifdef _WIN32 + +static void PrintTime(const char *s, UInt64 val, UInt64 total) +{ + *g_StdStream << endl << s << " Time ="; + const UInt32 kFreq = 10000000; + UInt64 sec = val / kFreq; + PrintNum(sec, 6); + *g_StdStream << '.'; + UInt32 ms = (UInt32)(val - (sec * kFreq)) / (kFreq / 1000); + PrintNum(ms, 3, '0'); + + while (val > ((UInt64)1 << 56)) + { + val >>= 1; + total >>= 1; + } + + UInt64 percent = 0; + if (total != 0) + percent = val * 100 / total; + *g_StdStream << " ="; + PrintNum(percent, 5); + *g_StdStream << '%'; +} + +#ifndef UNDER_CE + +#define SHIFT_SIZE_VALUE(x, num) (((x) + (1 << (num)) - 1) >> (num)) + +static void PrintMemUsage(const char *s, UInt64 val) +{ + *g_StdStream << " " << s << " Memory ="; + PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); + *g_StdStream << " MB"; + /* + *g_StdStream << " ="; + PrintNum(SHIFT_SIZE_VALUE(val, 10), 9); + *g_StdStream << " KB"; + */ + #ifdef Z7_LARGE_PAGES + AString lp; + Add_LargePages_String(lp); + if (!lp.IsEmpty()) + *g_StdStream << lp; + #endif +} + +EXTERN_C_BEGIN +typedef BOOL (WINAPI *Func_GetProcessMemoryInfo)(HANDLE Process, + PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); +typedef BOOL (WINAPI *Func_QueryProcessCycleTime)(HANDLE Process, PULONG64 CycleTime); +EXTERN_C_END + +#endif + +static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; } + +static void PrintStat() +{ + FILETIME creationTimeFT, exitTimeFT, kernelTimeFT, userTimeFT; + if (! + #ifdef UNDER_CE + ::GetThreadTimes(::GetCurrentThread() + #else + // NT 3.5 + ::GetProcessTimes(::GetCurrentProcess() + #endif + , &creationTimeFT, &exitTimeFT, &kernelTimeFT, &userTimeFT)) + return; + FILETIME curTimeFT; + NTime::GetCurUtc_FiTime(curTimeFT); + + #ifndef UNDER_CE + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + + PROCESS_MEMORY_COUNTERS m; + memset(&m, 0, sizeof(m)); + BOOL memDefined = FALSE; + BOOL cycleDefined = FALSE; + ULONG64 cycleTime = 0; + { + /* NT 4.0: GetProcessMemoryInfo() in Psapi.dll + Win7: new function K32GetProcessMemoryInfo() in kernel32.dll + It's faster to call kernel32.dll code than Psapi.dll code + GetProcessMemoryInfo() requires Psapi.lib + Psapi.lib in SDK7+ can link to K32GetProcessMemoryInfo in kernel32.dll + The program with K32GetProcessMemoryInfo will not work on systems before Win7 + // memDefined = GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); + */ + const HMODULE kern = ::GetModuleHandleW(L"kernel32.dll"); + Func_GetProcessMemoryInfo + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, kern, + "K32GetProcessMemoryInfo"); + if (!my_GetProcessMemoryInfo) + { + const HMODULE lib = LoadLibraryW(L"Psapi.dll"); + if (lib) + my_GetProcessMemoryInfo = Z7_GET_PROC_ADDRESS( + Func_GetProcessMemoryInfo, lib, + "GetProcessMemoryInfo"); + } + if (my_GetProcessMemoryInfo) + memDefined = my_GetProcessMemoryInfo(GetCurrentProcess(), &m, sizeof(m)); + // FreeLibrary(lib); + const + Func_QueryProcessCycleTime + my_QueryProcessCycleTime = Z7_GET_PROC_ADDRESS( + Func_QueryProcessCycleTime, kern, + "QueryProcessCycleTime"); + if (my_QueryProcessCycleTime) + cycleDefined = my_QueryProcessCycleTime(GetCurrentProcess(), &cycleTime); + } + + #endif + + UInt64 curTime = GetTime64(curTimeFT); + UInt64 creationTime = GetTime64(creationTimeFT); + UInt64 kernelTime = GetTime64(kernelTimeFT); + UInt64 userTime = GetTime64(userTimeFT); + + UInt64 totalTime = curTime - creationTime; + + PrintTime("Kernel ", kernelTime, totalTime); + + const UInt64 processTime = kernelTime + userTime; + + #ifndef UNDER_CE + if (cycleDefined) + { + *g_StdStream << " Cnt:"; + PrintNum(cycleTime / 1000000, 15); + *g_StdStream << " MCycles"; + } + #endif + + PrintTime("User ", userTime, totalTime); + + #ifndef UNDER_CE + if (cycleDefined) + { + *g_StdStream << " Freq (cnt/ptime):"; + UInt64 us = processTime / 10; + if (us == 0) + us = 1; + PrintNum(cycleTime / us, 6); + *g_StdStream << " MHz"; + } + #endif + + PrintTime("Process", processTime, totalTime); + #ifndef UNDER_CE + if (memDefined) PrintMemUsage("Virtual ", m.PeakPagefileUsage); + #endif + + PrintTime("Global ", totalTime, totalTime); + #ifndef UNDER_CE + if (memDefined) PrintMemUsage("Physical", m.PeakWorkingSetSize); + #endif + *g_StdStream << endl; +} + + +#else // ! _WIN32 + +static UInt64 Get_timeofday_us() +{ + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + return (UInt64)now.tv_sec * 1000000 + (UInt64)now.tv_usec; + return 0; +} + +static void PrintTime(const char *s, UInt64 val, UInt64 total_us, UInt64 kFreq) +{ + *g_StdStream << endl << s << " Time ="; + + { + UInt64 sec, ms; + + if (kFreq == 0) + { + sec = val / 1000000; + ms = val % 1000000 / 1000; + } + else + { + sec = val / kFreq; + ms = (UInt32)((val - (sec * kFreq)) * 1000 / kFreq); + } + + PrintNum(sec, 6); + *g_StdStream << '.'; + PrintNum(ms, 3, '0'); + } + + if (total_us == 0) + return; + + UInt64 percent = 0; + if (kFreq == 0) + percent = val * 100 / total_us; + else + { + const UInt64 kMaxVal = (UInt64)(Int64)-1; + UInt32 m = 100000000; + for (;;) + { + if (m == 0 || kFreq == 0) + break; + if (kMaxVal / m > val && + kMaxVal / kFreq > total_us) + break; + if (val > m) + val >>= 1; + else + m >>= 1; + if (kFreq > total_us) + kFreq >>= 1; + else + total_us >>= 1; + } + const UInt64 total = kFreq * total_us; + if (total != 0) + percent = val * m / total; + } + *g_StdStream << " ="; + PrintNum(percent, 5); + *g_StdStream << '%'; +} + +static void PrintStat(const UInt64 startTime) +{ + tms t; + /* clock_t res = */ times(&t); + const UInt64 totalTime = Get_timeofday_us() - startTime; + const UInt64 kFreq = (UInt64)sysconf(_SC_CLK_TCK); + PrintTime("Kernel ", (UInt64)t.tms_stime, totalTime, kFreq); + PrintTime("User ", (UInt64)t.tms_utime, totalTime, kFreq); + PrintTime("Process", (UInt64)t.tms_utime + (UInt64)t.tms_stime, totalTime, kFreq); + PrintTime("Global ", totalTime, totalTime, 0); + *g_StdStream << endl; +} + +#endif // ! _WIN32 + + + + + +static void PrintHexId(CStdOutStream &so, UInt64 id) +{ + char s[32]; + ConvertUInt64ToHex(id, s); + PrintStringRight(so, s, 8); +} + +#ifndef _WIN32 +void Set_ModuleDirPrefix_From_ProgArg0(const char *s); +#endif + +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +); +int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +) +{ + #if defined(MY_CPU_SIZEOF_POINTER) + { unsigned k = sizeof(void *); if (k != MY_CPU_SIZEOF_POINTER) throw "incorrect MY_CPU_PTR_SIZE"; } + #endif + + #if defined(_WIN32) && !defined(UNDER_CE) + SetFileApisToOEM(); + #endif + + #ifdef ENV_HAVE_LOCALE + // printf("\nBefore SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); + MY_SetLocale(); + // printf("\nAfter SetLocale() : %s\n", IsNativeUtf8() ? "NATIVE UTF-8" : "IS NOT NATIVE UTF-8"); + #endif + + #ifndef _WIN32 + const UInt64 startTime = Get_timeofday_us(); + #endif + + /* + { + g_StdOut << "DWORD:" << (unsigned)sizeof(DWORD); + g_StdOut << " LONG:" << (unsigned)sizeof(LONG); + g_StdOut << " long:" << (unsigned)sizeof(long); + #ifdef _WIN64 + // g_StdOut << " long long:" << (unsigned)sizeof(long long); + #endif + g_StdOut << " int:" << (unsigned)sizeof(int); + g_StdOut << " void*:" << (unsigned)sizeof(void *); + g_StdOut << endl; + } + */ + + UStringVector commandStrings; + + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + { + if (numArgs > 0) + Set_ModuleDirPrefix_From_ProgArg0(args[0]); + + for (int i = 0; i < numArgs; i++) + { + AString a (args[i]); +#if 0 + printf("\n%d %s :", i, a.Ptr()); + for (unsigned k = 0; k < a.Len(); k++) + printf(" %2x", (unsigned)(Byte)a[k]); +#endif + const UString s = MultiByteToUnicodeString(a); + commandStrings.Add(s); + } + // printf("\n"); + } + + #endif + + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif + + if (commandStrings.Size() == 0) + { + ShowCopyrightAndHelp(g_StdStream, true); + return 0; + } + + CArcCmdLineOptions options; + + CArcCmdLineParser parser; + + parser.Parse1(commandStrings, options); + + g_StdOut.IsTerminalMode = options.IsStdOutTerminal; + g_StdErr.IsTerminalMode = options.IsStdErrTerminal; + + if (options.Number_for_Out != k_OutStream_stdout) + g_StdStream = (options.Number_for_Out == k_OutStream_stderr ? &g_StdErr : NULL); + + if (options.Number_for_Errors != k_OutStream_stderr) + g_ErrStream = (options.Number_for_Errors == k_OutStream_stdout ? &g_StdOut : NULL); + + CStdOutStream *percentsStream = NULL; + if (options.Number_for_Percents != k_OutStream_disabled) + percentsStream = (options.Number_for_Percents == k_OutStream_stderr) ? &g_StdErr : &g_StdOut; + + if (options.HelpMode) + { + ShowCopyrightAndHelp(g_StdStream, true); + return 0; + } + + if (options.EnableHeaders) + { + if (g_StdStream) + { + ShowCopyrightAndHelp(g_StdStream, false); + if (!parser.Parse1Log.IsEmpty()) + *g_StdStream << parser.Parse1Log; + } + } + + parser.Parse2(options); + + { + int cp = options.ConsoleCodePage; + + int stdout_cp = cp; + int stderr_cp = cp; + int stdin_cp = cp; + + /* + // these cases are complicated. + // maybe we must use CRT functions instead of console WIN32. + // different Windows/CRT versions also can work different ways. + // so the following code was not enabled: + if (cp == -1) + { + // we set CodePage only if stream is attached to terminal + // maybe we should set CodePage even if is not terminal? + #ifdef _WIN32 + { + UINT ccp = GetConsoleOutputCP(); + if (ccp != 0) + { + if (options.IsStdOutTerminal) stdout_cp = ccp; + if (options.IsStdErrTerminal) stderr_cp = ccp; + } + } + if (options.IsInTerminal) + { + UINT ccp = GetConsoleCP(); + if (ccp != 0) stdin_cp = ccp; + } + #endif + } + */ + + if (stdout_cp != -1) g_StdOut.CodePage = stdout_cp; + if (stderr_cp != -1) g_StdErr.CodePage = stderr_cp; + if (stdin_cp != -1) g_StdIn.CodePage = stdin_cp; + } + g_StdOut.ListPathSeparatorSlash = options.ListPathSeparatorSlash; + g_StdErr.ListPathSeparatorSlash = options.ListPathSeparatorSlash; + + unsigned percentsNameLevel = 1; + if (options.LogLevel == 0 || options.Number_for_Percents != options.Number_for_Out) + percentsNameLevel = 2; + + unsigned consoleWidth = 80; + + if (percentsStream) + { + #ifdef _WIN32 + + #if !defined(UNDER_CE) + CONSOLE_SCREEN_BUFFER_INFO consoleInfo; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) + consoleWidth = (USHORT)consoleInfo.dwSize.X; + #endif + + #else + +#if !defined(__sun) + struct winsize w; + if (ioctl(0, TIOCGWINSZ, &w) == 0) + consoleWidth = w.ws_col; +#endif + #endif + } + + CREATE_CODECS_OBJECT + + codecs->CaseSensitive_Change = options.CaseSensitive_Change; + codecs->CaseSensitive = options.CaseSensitive; + ThrowException_if_Error(codecs->Load()); + Codecs_AddHashArcHandler(codecs); + + #ifdef Z7_EXTERNAL_CODECS + { + g_ExternalCodecs_Ptr = &_externalCodecs; + UString s; + codecs->GetCodecsErrorMessage(s); + if (!s.IsEmpty()) + { + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + so << endl << s << endl; + } + } + #endif + + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + if (codecs->Formats.Size() == 0 && + (isExtractGroupCommand + || options.Command.CommandType == NCommandType::kList + || options.Command.IsFromUpdateGroup())) + { + #ifdef Z7_EXTERNAL_CODECS + if (!codecs->MainDll_ErrorPath.IsEmpty()) + { + UString s ("Can't load module: "); + s += fs2us(codecs->MainDll_ErrorPath); + throw s; + } + #endif + throw kNoFormats; + } + + CObjectVector types; + if (!ParseOpenTypes(*codecs, options.ArcType, types)) + { + throw kUnsupportedArcTypeMessage; + } + + + CIntVector excludedFormats; + FOR_VECTOR (k, options.ExcludedArcTypes) + { + CIntVector tempIndices; + if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) + || tempIndices.Size() != 1) + throw kUnsupportedArcTypeMessage; + + + + excludedFormats.AddToUniqueSorted(tempIndices[0]); + // excludedFormats.Sort(); + } + + #ifdef Z7_EXTERNAL_CODECS + if (isExtractGroupCommand + || options.Command.IsFromUpdateGroup() + || options.Command.CommandType == NCommandType::kHash + || options.Command.CommandType == NCommandType::kBenchmark) + ThrowException_if_Error(_externalCodecs.Load()); + #endif + + int retCode = NExitCode::kSuccess; + HRESULT hresultMain = S_OK; + + // bool showStat = options.ShowTime; + + /* + if (!options.EnableHeaders || + options.TechMode) + showStat = false; + */ + + + if (options.Command.CommandType == NCommandType::kInfo) + { + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + unsigned i; + + #ifdef Z7_EXTERNAL_CODECS + so << endl << "Libs:" << endl; + for (i = 0; i < codecs->Libs.Size(); i++) + { + PrintLibIndex(so, (int)i); + const CCodecLib &lib = codecs->Libs[i]; + // if (lib.Version != 0) + so << ": " << (lib.Version >> 16) << "."; + PrintNumber(so, lib.Version & 0xffff, 2); + so << " : " << lib.Path << endl; + } + #endif + + so << endl << "Formats:" << endl; + + const char * const kArcFlags = "KSNFMGOPBELHXCc+a+m+r+"; + const char * const kArcTimeFlags = "wudn"; + const unsigned kNumArcFlags = (unsigned)strlen(kArcFlags); + const unsigned kNumArcTimeFlags = (unsigned)strlen(kArcTimeFlags); + + for (i = 0; i < codecs->Formats.Size(); i++) + { + const CArcInfoEx &arc = codecs->Formats[i]; + + #ifdef Z7_EXTERNAL_CODECS + PrintLibIndex(so, arc.LibIndex); + #else + so << " "; + #endif + + so << (char)(arc.UpdateEnabled ? 'C' : ' '); + + { + 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 << ' '; + UString s; + + FOR_VECTOR (t, arc.Exts) + { + if (t != 0) + s.Add_Space(); + const CArcExtInfo &ext = arc.Exts[t]; + s += ext.Ext; + if (!ext.AddExt.IsEmpty()) + { + s += " ("; + s += ext.AddExt; + s.Add_Char(')'); + } + } + + PrintString(so, s, 13); + so << ' '; + + if (arc.SignatureOffset != 0) + so << "offset=" << arc.SignatureOffset << ' '; + + // so << "numSignatures = " << arc.Signatures.Size() << " "; + + FOR_VECTOR(si, arc.Signatures) + { + if (si != 0) + so << " || "; + + const CByteBuffer &sig = arc.Signatures[si]; + + for (size_t j = 0; j < sig.Size(); j++) + { + if (j != 0) + so << ' '; + const unsigned b = sig.ConstData()[j]; + if (b > 0x20 && b < 0x80) + { + so << (char)b; + } + else + { + so << GET_HEX_CHAR_UPPER(b >> 4); + so << GET_HEX_CHAR_UPPER(b & 15); + } + } + } + so << endl; + } + + so << endl << "Codecs:" << endl; // << "Lib ID Name" << endl; + + for (i = 0; i < g_NumCodecs; i++) + { + const CCodecInfo &cod = *g_Codecs[i]; + + PrintLibIndex(so, -1); + + if (cod.NumStreams == 1) + so << ' '; + else + so << cod.NumStreams; + + so << (char)(cod.CreateEncoder ? 'E' : ' '); + so << (char)(cod.CreateDecoder ? 'D' : ' '); + so << (char)(cod.IsFilter ? 'F' : ' '); + + so << ' '; + PrintHexId(so, cod.Id); + so << ' ' << cod.Name << endl; + } + + + #ifdef Z7_EXTERNAL_CODECS + + UInt32 numMethods; + if (_externalCodecs.GetCodecs->GetNumMethods(&numMethods) == S_OK) + for (UInt32 j = 0; j < numMethods; j++) + { + PrintLibIndex(so, codecs->GetCodec_LibIndex(j)); + + UInt32 numStreams = codecs->GetCodec_NumStreams(j); + if (numStreams == 1) + so << ' '; + else + so << numStreams; + + so << (char)(codecs->GetCodec_EncoderIsAssigned(j) ? 'E' : ' '); + so << (char)(codecs->GetCodec_DecoderIsAssigned(j) ? 'D' : ' '); + { + bool isFilter_Assigned; + const bool isFilter = codecs->GetCodec_IsFilter(j, isFilter_Assigned); + so << (char)(isFilter ? 'F' : isFilter_Assigned ? ' ' : '*'); + } + + + so << ' '; + UInt64 id; + HRESULT res = codecs->GetCodec_Id(j, id); + if (res != S_OK) + id = (UInt64)(Int64)-1; + PrintHexId(so, id); + so << ' ' << codecs->GetCodec_Name(j) << endl; + } + + #endif + + + so << endl << "Hashers:" << endl; // << " L Size ID Name" << endl; + + for (i = 0; i < g_NumHashers; i++) + { + const CHasherInfo &codec = *g_Hashers[i]; + PrintLibIndex(so, -1); + PrintUInt32(so, codec.DigestSize, 4); + so << ' '; + PrintHexId(so, codec.Id); + so << ' ' << codec.Name << endl; + } + + #ifdef Z7_EXTERNAL_CODECS + + numMethods = _externalCodecs.GetHashers->GetNumHashers(); + for (UInt32 j = 0; j < numMethods; j++) + { + PrintLibIndex(so, codecs->GetHasherLibIndex(j)); + PrintUInt32(so, codecs->GetHasherDigestSize(j), 4); + so << ' '; + PrintHexId(so, codecs->GetHasherId(j)); + so << ' ' << codecs->GetHasherName(j) << endl; + } + + #endif + + } + else if (options.Command.CommandType == NCommandType::kBenchmark) + { + CStdOutStream &so = (g_StdStream ? *g_StdStream : g_StdOut); + hresultMain = BenchCon(EXTERNAL_CODECS_VARS_L + options.Properties, options.NumIterations, (FILE *)so); + if (hresultMain == S_FALSE) + { + so << endl; + if (g_ErrStream) + *g_ErrStream << "\nDecoding ERROR\n"; + retCode = NExitCode::kFatalError; + hresultMain = S_OK; + } + } + else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) + { + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + + if (options.StdInMode) + { + ArchivePathsSorted.Add(options.ArcName_for_StdInMode); + ArchivePathsFullSorted.Add(options.ArcName_for_StdInMode); + } + else + { + CExtractScanConsole scan; + + scan.Init(options.EnableHeaders ? g_StdStream : NULL, + g_ErrStream, percentsStream, + options.DisablePercents); + scan.SetWindowWidth(consoleWidth); + + if (g_StdStream && options.EnableHeaders) + *g_StdStream << "Scanning the drive for archives:" << endl; + + CDirItemsStat st; + + scan.StartScanning(); + + hresultMain = EnumerateDirItemsAndSort( + options.arcCensor, + NWildcard::k_RelatPath, + UString(), // addPathPrefix + ArchivePathsSorted, + ArchivePathsFullSorted, + st, + &scan); + + scan.CloseScanning(); + + if (hresultMain == S_OK) + { + if (options.EnableHeaders) + scan.PrintStat(st); + } + else + { + /* + if (res != E_ABORT) + { + throw CSystemException(res); + // errorInfo.Message = "Scanning error"; + } + return res; + */ + } + } + + if (hresultMain == S_OK) { + if (isExtractGroupCommand) + { + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr extractCallback = ecs; + + #ifndef Z7_NO_CRYPTO + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + #endif + + ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); + ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); + + ecs->LogLevel = options.LogLevel; + ecs->PercentsNameLevel = percentsNameLevel; + + if (percentsStream) + ecs->SetWindowWidth(consoleWidth); + + /* + COpenCallbackConsole openCallback; + openCallback.Init(g_StdStream, g_ErrStream); + + #ifndef Z7_NO_CRYPTO + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + #endif + */ + + CExtractOptions eo; + (CExtractOptionsBase &)eo = options.ExtractOptions; + + eo.StdInMode = options.StdInMode; + eo.StdOutMode = options.StdOutMode; + eo.YesToAll = options.YesToAll; + eo.TestMode = options.Command.IsTestCommand(); + + #ifndef Z7_SFX + eo.Properties = options.Properties; + #endif + + UString errorMessage; + CDecompressStat stat; + CHashBundle hb; + IHashCalc *hashCalc = NULL; + + if (!options.HashMethods.IsEmpty()) + { + hashCalc = &hb; + ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); + // hb.Init(); + } + + hresultMain = Extract( + // EXTERNAL_CODECS_VARS_L + codecs, + types, + excludedFormats, + ArchivePathsSorted, + ArchivePathsFullSorted, + options.Censor.Pairs.Front().Head, + eo, + ecs, ecs, ecs, + hashCalc, errorMessage, stat); + + ecs->ClosePercents(); + + if (!errorMessage.IsEmpty()) + { + if (g_ErrStream) + *g_ErrStream << endl << "ERROR:" << endl << errorMessage << endl; + if (hresultMain == S_OK) + hresultMain = E_FAIL; + } + + CStdOutStream *so = g_StdStream; + + bool isError = false; + + if (so) + { + *so << endl; + + if (ecs->NumTryArcs > 1) + { + *so << "Archives: " << ecs->NumTryArcs << endl; + *so << "OK archives: " << ecs->NumOkArcs << endl; + } + } + + if (ecs->NumCantOpenArcs != 0) + { + isError = true; + if (so) + *so << "Can't open as archive: " << ecs->NumCantOpenArcs << endl; + } + + if (ecs->NumArcsWithError != 0) + { + isError = true; + if (so) + *so << "Archives with Errors: " << ecs->NumArcsWithError << endl; + } + + if (so) + { + if (ecs->NumArcsWithWarnings != 0) + *so << "Archives with Warnings: " << ecs->NumArcsWithWarnings << endl; + + if (ecs->NumOpenArcWarnings != 0) + { + *so << endl; + if (ecs->NumOpenArcWarnings != 0) + *so << "Warnings: " << ecs->NumOpenArcWarnings << endl; + } + } + + if (ecs->NumOpenArcErrors != 0) + { + isError = true; + if (so) + { + *so << endl; + if (ecs->NumOpenArcErrors != 0) + *so << "Open Errors: " << ecs->NumOpenArcErrors << endl; + } + } + + if (isError) + retCode = NExitCode::kFatalError; + + if (so) { + if (ecs->NumArcsWithError != 0 || ecs->NumFileErrors != 0) + { + // if (ecs->NumArchives > 1) + { + *so << endl; + if (ecs->NumFileErrors != 0) + *so << "Sub items Errors: " << ecs->NumFileErrors << endl; + } + } + else if (hresultMain == S_OK) + { + if (stat.NumFolders != 0) + *so << "Folders: " << stat.NumFolders << endl; + if (stat.NumFiles != 1 || stat.NumFolders != 0 || stat.NumAltStreams != 0) + *so << "Files: " << stat.NumFiles << endl; + if (stat.NumAltStreams != 0) + { + *so << "Alternate Streams: " << stat.NumAltStreams << endl; + *so << "Alternate Streams Size: " << stat.AltStreams_UnpackSize << endl; + } + + *so + << "Size: " << stat.UnpackSize << endl + << "Compressed: " << stat.PackSize << endl; + if (hashCalc) + { + *so << endl; + PrintHashStat(*so, hb); + } + } + } // if (so) + } + else // if_(!isExtractGroupCommand) + { + UInt64 numErrors = 0; + UInt64 numWarnings = 0; + + // options.ExtractNtOptions.StoreAltStreams = true, if -sns[-] is not definmed + + CListOptions lo; + lo.ExcludeDirItems = options.Censor.ExcludeDirItems; + lo.ExcludeFileItems = options.Censor.ExcludeFileItems; + lo.DisablePercents = options.DisablePercents; + + hresultMain = ListArchives( + lo, + codecs, + types, + excludedFormats, + options.StdInMode, + ArchivePathsSorted, + ArchivePathsFullSorted, + options.ExtractOptions.NtOptions.AltStreams.Val, + options.AltStreams.Val, // we don't want to show AltStreams by default + options.Censor.Pairs.Front().Head, + options.EnableHeaders, + options.TechMode, + #ifndef Z7_NO_CRYPTO + options.PasswordEnabled, + options.Password, + #endif + &options.Properties, + numErrors, numWarnings); + + if (options.EnableHeaders) + if (numWarnings > 0) + g_StdOut << endl << "Warnings: " << numWarnings << endl; + + if (numErrors > 0) + { + if (options.EnableHeaders) + g_StdOut << endl << "Errors: " << numErrors << endl; + retCode = NExitCode::kFatalError; + } + } // if_(isExtractGroupCommand) + } // if_(hresultMain == S_OK) + } + else if (options.Command.IsFromUpdateGroup()) + { + #ifdef Z7_EXTRACT_ONLY + throw "update commands are not implemented"; + #else + CUpdateOptions &uo = options.UpdateOptions; + if (uo.SfxMode && uo.SfxModule.IsEmpty()) + uo.SfxModule = kDefaultSfxModule; + + COpenCallbackConsole openCallback; + openCallback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); + + #ifndef Z7_NO_CRYPTO + bool passwordIsDefined = + (options.PasswordEnabled && !options.Password.IsEmpty()); + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + #endif + + CUpdateCallbackConsole callback; + callback.LogLevel = options.LogLevel; + callback.PercentsNameLevel = percentsNameLevel; + + if (percentsStream) + callback.SetWindowWidth(consoleWidth); + + #ifndef Z7_NO_CRYPTO + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty()); + callback.Password = options.Password; + #endif + + callback.StdOutMode = uo.StdOutMode; + callback.Init( + // NULL, + g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); + + CUpdateErrorInfo errorInfo; + + /* + if (!uo.Init(codecs, types, options.ArchiveName)) + throw kUnsupportedUpdateArcType; + */ + hresultMain = UpdateArchive(codecs, + types, + options.ArchiveName, + options.Censor, + uo, + errorInfo, &openCallback, &callback, true); + + callback.ClosePercents2(); + + CStdOutStream *se = g_StdStream; + if (!se) + se = g_ErrStream; + + retCode = WarningsCheck(hresultMain, callback, errorInfo, + g_StdStream, se, + true // options.EnableHeaders + ); + #endif + } + else if (options.Command.CommandType == NCommandType::kHash) + { + const CHashOptions &uo = options.HashOptions; + + CHashCallbackConsole callback; + if (percentsStream) + callback.SetWindowWidth(consoleWidth); + + callback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents); + callback.PrintHeaders = options.EnableHeaders; + callback.PrintFields = options.ListFields; + + AString errorInfoString; + hresultMain = HashCalc(EXTERNAL_CODECS_VARS_L + options.Censor, uo, + errorInfoString, &callback); + CUpdateErrorInfo errorInfo; + errorInfo.Message = errorInfoString; + CStdOutStream *se = g_StdStream; + if (!se) + se = g_ErrStream; + retCode = WarningsCheck(hresultMain, callback, errorInfo, g_StdStream, se, options.EnableHeaders); + } + else + ShowMessageAndThrowException(kUserErrorMessage, NExitCode::kUserError); + + if (options.ShowTime && g_StdStream) + PrintStat( + #ifndef _WIN32 + startTime + #endif + ); + + ThrowException_if_Error(hresultMain); + + return retCode; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/MainAr.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/MainAr.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/MainAr.cpp 2015-06-19 18:53:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/MainAr.cpp 2024-10-19 08:00:00.000000000 +0000 @@ -1,167 +1,235 @@ -// MainAr.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyException.h" -#include "../../../Common/StdOutStream.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/NtCheck.h" - -#include "../Common/ArchiveCommandLine.h" -#include "../Common/ExitCode.h" - -#include "ConsoleClose.h" - -using namespace NWindows; - -CStdOutStream *g_StdStream = NULL; -CStdOutStream *g_ErrStream = NULL; - -extern int Main2( - #ifndef _WIN32 - int numArgs, char *args[] - #endif -); - -static const char *kException_CmdLine_Error_Message = "Command Line Error:"; -static const char *kExceptionErrorMessage = "ERROR:"; -static const char *kUserBreakMessage = "Break signaled"; -static const char *kMemoryExceptionMessage = "ERROR: Can't allocate required memory!"; -static const char *kUnknownExceptionMessage = "Unknown Error"; -static const char *kInternalExceptionMessage = "\n\nInternal Error #"; - -static void FlushStreams() -{ - if (g_StdStream) - g_StdStream->Flush(); -} - -static void PrintError(const char *message) -{ - FlushStreams(); - if (g_ErrStream) - *g_ErrStream << "\n\n" << message << endl; -} - -#define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError; - -int MY_CDECL main -( - #ifndef _WIN32 - int numArgs, char *args[] - #endif -) -{ - g_ErrStream = &g_StdErr; - g_StdStream = &g_StdOut; - - NT_CHECK - - NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; - int res = 0; - - try - { - res = Main2( - #ifndef _WIN32 - numArgs, args - #endif - ); - } - catch(const CNewException &) - { - PrintError(kMemoryExceptionMessage); - return (NExitCode::kMemoryError); - } - catch(const NConsoleClose::CCtrlBreakException &) - { - PrintError(kUserBreakMessage); - return (NExitCode::kUserBreak); - } - catch(const CArcCmdLineException &e) - { - PrintError(kException_CmdLine_Error_Message); - if (g_ErrStream) - *g_ErrStream << e << endl; - return (NExitCode::kUserError); - } - catch(const CSystemException &systemError) - { - if (systemError.ErrorCode == E_OUTOFMEMORY) - { - PrintError(kMemoryExceptionMessage); - return (NExitCode::kMemoryError); - } - if (systemError.ErrorCode == E_ABORT) - { - PrintError(kUserBreakMessage); - return (NExitCode::kUserBreak); - } - if (g_ErrStream) - { - PrintError("System ERROR:"); - *g_ErrStream << NError::MyFormatMessage(systemError.ErrorCode) << endl; - } - return (NExitCode::kFatalError); - } - catch(NExitCode::EEnum &exitCode) - { - FlushStreams(); - if (g_ErrStream) - *g_ErrStream << kInternalExceptionMessage << exitCode << endl; - return (exitCode); - } - catch(const UString &s) - { - if (g_ErrStream) - { - PrintError(kExceptionErrorMessage); - *g_ErrStream << s << endl; - } - return (NExitCode::kFatalError); - } - catch(const AString &s) - { - if (g_ErrStream) - { - PrintError(kExceptionErrorMessage); - *g_ErrStream << s << endl; - } - return (NExitCode::kFatalError); - } - catch(const char *s) - { - if (g_ErrStream) - { - PrintError(kExceptionErrorMessage); - *g_ErrStream << s << endl; - } - return (NExitCode::kFatalError); - } - catch(const wchar_t *s) - { - if (g_ErrStream) - { - PrintError(kExceptionErrorMessage); - *g_ErrStream << s << endl; - } - return (NExitCode::kFatalError); - } - catch(int t) - { - if (g_ErrStream) - { - FlushStreams(); - *g_ErrStream << kInternalExceptionMessage << t << endl; - return (NExitCode::kFatalError); - } - } - catch(...) - { - PrintError(kUnknownExceptionMessage); - return (NExitCode::kFatalError); - } - - return res; -} +// MainAr.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "../../../../C/DllSecur.h" +#endif +#include "../../../../C/CpuArch.h" + +#include "../../../Common/MyException.h" +#include "../../../Common/StdOutStream.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/NtCheck.h" + +#include "../Common/ArchiveCommandLine.h" +#include "../Common/ExitCode.h" + +#include "ConsoleClose.h" + +using namespace NWindows; + +extern +CStdOutStream *g_StdStream; +CStdOutStream *g_StdStream = NULL; +extern +CStdOutStream *g_ErrStream; +CStdOutStream *g_ErrStream = NULL; + +extern int Main2( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +); + +static const char * const kException_CmdLine_Error_Message = "Command Line Error:"; +static const char * const kExceptionErrorMessage = "ERROR:"; +static const char * const kUserBreakMessage = "Break signaled"; +static const char * const kMemoryExceptionMessage = "ERROR: Can't allocate required memory!"; +static const char * const kUnknownExceptionMessage = "Unknown Error"; +static const char * const kInternalExceptionMessage = "\n\nInternal Error #"; + +static void FlushStreams() +{ + if (g_StdStream) + g_StdStream->Flush(); +} + +static void PrintError(const char *message) +{ + FlushStreams(); + if (g_ErrStream) + *g_ErrStream << "\n\n" << message << endl; +} + +#if defined(_WIN32) && defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION *g_StdStream << "Unsupported Windows version"; return NExitCode::kFatalError; +#endif + +static inline bool CheckIsa() +{ + // __try + { + // some compilers (e2k) support SSE/AVX, but cpuid() can be unavailable or return lower isa support +#ifdef MY_CPU_X86_OR_AMD64 + #if 0 && (defined(__AVX512F__) && defined(__AVX512VL__)) + if (!CPU_IsSupported_AVX512F_AVX512VL()) + return false; + #elif defined(__AVX2__) + if (!CPU_IsSupported_AVX2()) + return false; + #elif defined(__AVX__) + if (!CPU_IsSupported_AVX()) + return false; + #elif defined(__SSE2__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 2) + if (!CPU_IsSupported_SSE2()) + return false; + #elif defined(__SSE__) && !defined(MY_CPU_AMD64) || defined(_M_IX86_FP) && (_M_IX86_FP >= 1) + if (!CPU_IsSupported_SSE() || + !CPU_IsSupported_CMOV()) + return false; + #endif +#endif + /* + __asm + { + _emit 0fH + _emit 038H + _emit 0cbH + _emit (0c0H + 0 * 8 + 0) + } + */ + return true; + } + /* + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + */ +} + +int Z7_CDECL main +( + #ifndef _WIN32 + int numArgs, char *args[] + #endif +) +{ + g_ErrStream = &g_StdErr; + g_StdStream = &g_StdOut; + + // #if (defined(_MSC_VER) && defined(_M_IX86)) + if (!CheckIsa()) + { + PrintError("ERROR: processor doesn't support required ISA extension"); + return NExitCode::kFatalError; + } + // #endif + + NT_CHECK + + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; + int res = 0; + + try + { + #ifdef _WIN32 + My_SetDefaultDllDirectories(); + #endif + + res = Main2( + #ifndef _WIN32 + numArgs, args + #endif + ); + } + catch(const CNewException &) + { + PrintError(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } +/* + catch(const NConsoleClose::CCtrlBreakException &) + { + PrintError(kUserBreakMessage); + return (NExitCode::kUserBreak); + } +*/ + catch(const CMessagePathException &e) + { + PrintError(kException_CmdLine_Error_Message); + if (g_ErrStream) + *g_ErrStream << e << endl; + return (NExitCode::kUserError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + PrintError(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + PrintError(kUserBreakMessage); + return (NExitCode::kUserBreak); + } + if (g_ErrStream) + { + PrintError("System ERROR:"); + *g_ErrStream << NError::MyFormatMessage(systemError.ErrorCode) << endl; + } + return (NExitCode::kFatalError); + } + catch(NExitCode::EEnum exitCode) + { + FlushStreams(); + if (g_ErrStream) + *g_ErrStream << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + catch(const UString &s) + { + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } + return (NExitCode::kFatalError); + } + catch(const char *s) + { + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } + return (NExitCode::kFatalError); + } + catch(const wchar_t *s) + { + if (g_ErrStream) + { + PrintError(kExceptionErrorMessage); + *g_ErrStream << s << endl; + } + return (NExitCode::kFatalError); + } + catch(int t) + { + if (g_ErrStream) + { + FlushStreams(); + *g_ErrStream << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + } + catch(...) + { + PrintError(kUnknownExceptionMessage); + return (NExitCode::kFatalError); + } + + return res; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/OpenCallbackConsole.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 2015-09-17 19:02:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,111 +1,115 @@ -// OpenCallbackConsole.cpp - -#include "StdAfx.h" - -#include "OpenCallbackConsole.h" - -#include "ConsoleClose.h" -#include "UserInputUtils.h" - -static HRESULT CheckBreak2() -{ - return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; -} - -HRESULT COpenCallbackConsole::Open_CheckBreak() -{ - return CheckBreak2(); -} - -HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) -{ - if (!MultiArcMode && NeedPercents()) - { - if (files) - { - _totalFilesDefined = true; - // _totalFiles = *files; - _percent.Total = *files; - } - else - _totalFilesDefined = false; - - if (bytes) - { - _totalBytesDefined = true; - // _totalBytes = *bytes; - if (!files) - _percent.Total = *bytes; - } - else - _totalBytesDefined = false; - } - - return CheckBreak2(); -} - -HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) -{ - if (!MultiArcMode && NeedPercents()) - { - if (files) - { - _percent.Files = *files; - if (_totalFilesDefined) - _percent.Completed = *files; - } - - if (bytes) - { - if (!_totalFilesDefined) - _percent.Completed = *bytes; - } - _percent.Print(); - } - - return CheckBreak2(); -} - -HRESULT COpenCallbackConsole::Open_Finished() -{ - ClosePercents(); - return S_OK; -} - - -#ifndef _NO_CRYPTO - -HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) -{ - *password = NULL; - RINOK(CheckBreak2()); - - if (!PasswordIsDefined) - { - ClosePercents(); - Password = GetPassword(_so); - PasswordIsDefined = true; - } - return StringToBstr(Password, password); -} - -/* -HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) -{ - passwordIsDefined = PasswordIsDefined; - password = Password; - return S_OK; -} - -bool COpenCallbackConsole::Open_WasPasswordAsked() -{ - return PasswordWasAsked; -} - -void COpenCallbackConsole::Open_Clear_PasswordWasAsked_Flag () -{ - PasswordWasAsked = false; -} -*/ - -#endif +// OpenCallbackConsole.cpp + +#include "StdAfx.h" + +#include "OpenCallbackConsole.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +HRESULT COpenCallbackConsole::Open_CheckBreak() +{ + return CheckBreak2(); +} + +HRESULT COpenCallbackConsole::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + if (!MultiArcMode && NeedPercents()) + { + if (files) + { + _totalFilesDefined = true; + // _totalFiles = *files; + _percent.Total = *files; + } + else + _totalFilesDefined = false; + + if (bytes) + { + // _totalBytesDefined = true; + _totalBytes = *bytes; + if (!files) + _percent.Total = *bytes; + } + else + { + // _totalBytesDefined = false; + if (!files) + _percent.Total = _totalBytes; + } + } + + return CheckBreak2(); +} + +HRESULT COpenCallbackConsole::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + if (!MultiArcMode && NeedPercents()) + { + if (files) + { + _percent.Files = *files; + if (_totalFilesDefined) + _percent.Completed = *files; + } + + if (bytes) + { + if (!_totalFilesDefined) + _percent.Completed = *bytes; + } + _percent.Print(); + } + + return CheckBreak2(); +} + +HRESULT COpenCallbackConsole::Open_Finished() +{ + ClosePercents(); + return S_OK; +} + + +#ifndef Z7_NO_CRYPTO + +HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password) +{ + *password = NULL; + RINOK(CheckBreak2()) + + if (!PasswordIsDefined) + { + ClosePercents(); + RINOK(GetPassword_HRESULT(_so, Password)) + PasswordIsDefined = true; + } + return StringToBstr(Password, password); +} + +/* +HRESULT COpenCallbackConsole::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) +{ + passwordIsDefined = PasswordIsDefined; + password = Password; + return S_OK; +} + +bool COpenCallbackConsole::Open_WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void COpenCallbackConsole::Open_Clear_PasswordWasAsked_Flag () +{ + PasswordWasAsked = false; +} +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/OpenCallbackConsole.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/OpenCallbackConsole.h 2015-09-17 19:02:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/OpenCallbackConsole.h 2024-06-06 06:00:00.000000000 +0000 @@ -1,65 +1,73 @@ -// OpenCallbackConsole.h - -#ifndef __OPEN_CALLBACK_CONSOLE_H -#define __OPEN_CALLBACK_CONSOLE_H - -#include "../../../Common/StdOutStream.h" - -#include "../Common/ArchiveOpenCallback.h" - -#include "PercentPrinter.h" - -class COpenCallbackConsole: public IOpenCallbackUI -{ -protected: - CPercentPrinter _percent; - - CStdOutStream *_so; - CStdOutStream *_se; - - bool _totalFilesDefined; - bool _totalBytesDefined; - // UInt64 _totalFiles; - // UInt64 _totalBytes; - - bool NeedPercents() const { return _percent._so != NULL; } - -public: - - bool MultiArcMode; - - void ClosePercents() - { - if (NeedPercents()) - _percent.ClosePrint(true); - } - - COpenCallbackConsole(): - _totalFilesDefined(false), - _totalBytesDefined(false), - MultiArcMode(false) - - #ifndef _NO_CRYPTO - , PasswordIsDefined(false) - // , PasswordWasAsked(false) - #endif - - {} - - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) - { - _so = outStream; - _se = errorStream; - _percent._so = percentStream; - } - - INTERFACE_IOpenCallbackUI(;) - - #ifndef _NO_CRYPTO - bool PasswordIsDefined; - // bool PasswordWasAsked; - UString Password; - #endif -}; - -#endif +// OpenCallbackConsole.h + +#ifndef ZIP7_INC_OPEN_CALLBACK_CONSOLE_H +#define ZIP7_INC_OPEN_CALLBACK_CONSOLE_H + +#include "../../../Common/StdOutStream.h" + +#include "../Common/ArchiveOpenCallback.h" + +#include "PercentPrinter.h" + +class COpenCallbackConsole: public IOpenCallbackUI +{ +protected: + CPercentPrinter _percent; + + CStdOutStream *_so; + CStdOutStream *_se; + + // UInt64 _totalFiles; + UInt64 _totalBytes; + bool _totalFilesDefined; + // bool _totalBytesDefined; + + bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; } + +public: + + bool MultiArcMode; + + void ClosePercents() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + COpenCallbackConsole(): + _totalBytes(0), + _totalFilesDefined(false), + // _totalBytesDefined(false), + MultiArcMode(false) + + #ifndef Z7_NO_CRYPTO + , PasswordIsDefined(false) + // , PasswordWasAsked(false) + #endif + + {} + + virtual ~COpenCallbackConsole() {} + + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) + { + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + _percent.DisablePrint = disablePercents; + } + + Z7_IFACE_IMP(IOpenCallbackUI) + + #ifndef Z7_NO_CRYPTO + bool PasswordIsDefined; + // bool PasswordWasAsked; + UString Password; + #endif +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/PercentPrinter.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/PercentPrinter.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.cpp 2024-06-17 11:00:00.000000000 +0000 @@ -1,181 +1,186 @@ -// PercentPrinter.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "PercentPrinter.h" - -static const unsigned kPercentsSize = 4; - -CPercentPrinter::~CPercentPrinter() -{ - ClosePrint(false); -} - -void CPercentPrinterState::ClearCurState() -{ - Completed = 0; - Total = ((UInt64)(Int64)-1); - Files = 0; - Command.Empty(); - FileName.Empty(); -} - -void CPercentPrinter::ClosePrint(bool needFlush) -{ - unsigned num = _printedString.Len(); - if (num != 0) - { - - unsigned i; - - /* '\r' in old MAC OS means "new line". - So we can't use '\r' in some systems */ - - #ifdef _WIN32 - char *start = _temp.GetBuf(num + 2); - char *p = start; - *p++ = '\r'; - for (i = 0; i < num; i++) *p++ = ' '; - *p++ = '\r'; - #else - char *start = _temp.GetBuf(num * 3); - char *p = start; - for (i = 0; i < num; i++) *p++ = '\b'; - for (i = 0; i < num; i++) *p++ = ' '; - for (i = 0; i < num; i++) *p++ = '\b'; - #endif - - *p = 0; - _temp.ReleaseBuf_SetLen((unsigned)(p - start)); - *_so << _temp; - } - if (needFlush) - _so->Flush(); - _printedString.Empty(); -} - -void CPercentPrinter::GetPercents() -{ - char s[32]; - unsigned size; - { - char c = '%'; - UInt64 val = 0; - if (Total == (UInt64)(Int64)-1) - { - val = Completed >> 20; - c = 'M'; - } - else if (Total != 0) - val = Completed * 100 / Total; - ConvertUInt64ToString(val, s); - size = (unsigned)strlen(s); - s[size++] = c; - s[size] = 0; - } - - while (size < kPercentsSize) - { - _s += ' '; - size++; - } - - _s += s; -} - -void CPercentPrinter::Print() -{ - DWORD tick = 0; - if (_tickStep != 0) - tick = GetTickCount(); - - bool onlyPercentsChanged = false; - - if (!_printedString.IsEmpty()) - { - if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep) - return; - - CPercentPrinterState &st = *this; - if (_printedState.Command == st.Command - && _printedState.FileName == st.FileName - && _printedState.Files == st.Files) - { - if (_printedState.Total == st.Total - && _printedState.Completed == st.Completed) - return; - onlyPercentsChanged = true; - } - } - - _s.Empty(); - - GetPercents(); - - if (onlyPercentsChanged && _s == _printedPercents) - return; - - _printedPercents = _s; - - if (Files != 0) - { - char s[32]; - ConvertUInt64ToString(Files, s); - // unsigned size = (unsigned)strlen(s); - // for (; size < 3; size++) _s += ' '; - _s += ' '; - _s += s; - // _s += "f"; - } - - - if (!Command.IsEmpty()) - { - _s += ' '; - _s += Command; - } - - if (!FileName.IsEmpty() && _s.Len() < MaxLen) - { - _s += ' '; - - StdOut_Convert_UString_to_AString(FileName, _temp); - _temp.Replace('\n', ' '); - if (_s.Len() + _temp.Len() > MaxLen) - { - unsigned len = FileName.Len(); - for (; len != 0;) - { - unsigned delta = len / 8; - if (delta == 0) - delta = 1; - len -= delta; - _tempU = FileName; - _tempU.Delete(len / 2, FileName.Len() - len); - _tempU.Insert(len / 2, L" . "); - StdOut_Convert_UString_to_AString(_tempU, _temp); - if (_s.Len() + _temp.Len() <= MaxLen) - break; - } - if (len == 0) - _temp.Empty(); - } - _s += _temp; - } - - if (_printedString != _s) - { - ClosePrint(false); - *_so << _s; - if (NeedFlush) - _so->Flush(); - _printedString = _s; - } - - _printedState = *this; - - if (_tickStep != 0) - _prevTick = tick; -} +// PercentPrinter.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "PercentPrinter.h" + +static const unsigned kPercentsSize = 4; + +CPercentPrinter::~CPercentPrinter() +{ + ClosePrint(false); +} + +void CPercentPrinterState::ClearCurState() +{ + Completed = 0; + Total = ((UInt64)(Int64)-1); + Files = 0; + Command.Empty(); + FileName.Empty(); +} + +void CPercentPrinter::ClosePrint(bool needFlush) +{ + unsigned num = _printedString.Len(); + if (num != 0) + { + + unsigned i; + + /* '\r' in old MAC OS means "new line". + So we can't use '\r' in some systems */ + + #ifdef _WIN32 + char *start = _temp.GetBuf(num + 2); + char *p = start; + *p++ = '\r'; + for (i = 0; i < num; i++) *p++ = ' '; + *p++ = '\r'; + #else + char *start = _temp.GetBuf(num * 3); + char *p = start; + for (i = 0; i < num; i++) *p++ = '\b'; + for (i = 0; i < num; i++) *p++ = ' '; + for (i = 0; i < num; i++) *p++ = '\b'; + #endif + + *p = 0; + _temp.ReleaseBuf_SetLen((unsigned)(p - start)); + *_so << _temp; + } + if (needFlush) + _so->Flush(); + _printedString.Empty(); +} + +void CPercentPrinter::GetPercents() +{ + char s[32]; + unsigned size; + { + char c = '%'; + UInt64 val = 0; + if (Total == (UInt64)(Int64)-1 || + (Total == 0 && Completed != 0)) + { + val = Completed >> 20; + c = 'M'; + } + else if (Total != 0) + val = Completed * 100 / Total; + ConvertUInt64ToString(val, s); + size = (unsigned)strlen(s); + s[size++] = c; + s[size] = 0; + } + + while (size < kPercentsSize) + { + _s.Add_Space(); + size++; + } + + _s += s; +} + +void CPercentPrinter::Print() +{ + if (DisablePrint) + return; + DWORD tick = 0; + if (_tickStep != 0) + tick = GetTickCount(); + + bool onlyPercentsChanged = false; + + if (!_printedString.IsEmpty()) + { + if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep) + return; + + CPercentPrinterState &st = *this; + if (_printedState.Command == st.Command + && _printedState.FileName == st.FileName + && _printedState.Files == st.Files) + { + if (_printedState.Total == st.Total + && _printedState.Completed == st.Completed) + return; + onlyPercentsChanged = true; + } + } + + _s.Empty(); + + GetPercents(); + + if (onlyPercentsChanged && _s == _printedPercents) + return; + + _printedPercents = _s; + + if (Files != 0) + { + char s[32]; + ConvertUInt64ToString(Files, s); + // unsigned size = (unsigned)strlen(s); + // for (; size < 3; size++) _s.Add_Space(); + _s.Add_Space(); + _s += s; + // _s += "f"; + } + + + if (!Command.IsEmpty()) + { + _s.Add_Space(); + _s += Command; + } + + if (!FileName.IsEmpty() && _s.Len() < MaxLen) + { + _s.Add_Space(); + + _tempU = FileName; + _so->Normalize_UString_Path(_tempU); + _so->Convert_UString_to_AString(_tempU, _temp); + if (_s.Len() + _temp.Len() > MaxLen) + { + unsigned len = FileName.Len(); + for (; len != 0;) + { + unsigned delta = len / 8; + if (delta == 0) + delta = 1; + len -= delta; + _tempU = FileName; + _tempU.Delete(len / 2, _tempU.Len() - len); + _tempU.Insert(len / 2, L" . "); + _so->Normalize_UString_Path(_tempU); + _so->Convert_UString_to_AString(_tempU, _temp); + if (_s.Len() + _temp.Len() <= MaxLen) + break; + } + if (len == 0) + _temp.Empty(); + } + _s += _temp; + } + + if (_printedString != _s) + { + ClosePrint(false); + *_so << _s; + if (NeedFlush) + _so->Flush(); + _printedString = _s; + } + + _printedState = *this; + + if (_tickStep != 0) + _prevTick = tick; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/PercentPrinter.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/PercentPrinter.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/PercentPrinter.h 2024-10-19 07:00:00.000000000 +0000 @@ -1,62 +1,66 @@ -// PercentPrinter.h - -#ifndef __PERCENT_PRINTER_H -#define __PERCENT_PRINTER_H - -#include "../../../Common/StdOutStream.h" - -struct CPercentPrinterState -{ - UInt64 Completed; - UInt64 Total; - - UInt64 Files; - - AString Command; - UString FileName; - - void ClearCurState(); - - CPercentPrinterState(): - Completed(0), - Total((UInt64)(Int64)-1), - Files(0) - {} -}; - -class CPercentPrinter: public CPercentPrinterState -{ - UInt32 _tickStep; - DWORD _prevTick; - - AString _s; - - AString _printedString; - AString _temp; - UString _tempU; - - CPercentPrinterState _printedState; - AString _printedPercents; - - void GetPercents(); - -public: - CStdOutStream *_so; - - bool NeedFlush; - unsigned MaxLen; - - CPercentPrinter(UInt32 tickStep = 200): - _tickStep(tickStep), - _prevTick(0), - NeedFlush(true), - MaxLen(80 - 1) - {} - - ~CPercentPrinter(); - - void ClosePrint(bool needFlush); - void Print(); -}; - -#endif +// PercentPrinter.h + +#ifndef ZIP7_INC_PERCENT_PRINTER_H +#define ZIP7_INC_PERCENT_PRINTER_H + +#include "../../../Common/StdOutStream.h" + +struct CPercentPrinterState +{ + UInt64 Completed; + UInt64 Total; + + UInt64 Files; + + AString Command; + UString FileName; + + void ClearCurState(); + + CPercentPrinterState(): + Completed(0), + Total((UInt64)(Int64)-1), + Files(0) + {} +}; + +class CPercentPrinter: public CPercentPrinterState +{ +public: + CStdOutStream *_so; + bool DisablePrint; + bool NeedFlush; + unsigned MaxLen; + +private: + UInt32 _tickStep; + DWORD _prevTick; + + AString _s; + + AString _printedString; + AString _temp; + UString _tempU; + + CPercentPrinterState _printedState; + AString _printedPercents; + + void GetPercents(); + +public: + + CPercentPrinter(UInt32 tickStep = 200): + DisablePrint(false), + NeedFlush(true), + MaxLen(80 - 1), + _tickStep(tickStep), + _prevTick(0) + {} + + ~CPercentPrinter(); + + void ClosePrint(bool needFlush); + void Print(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.cpp 2004-11-09 12:58:00.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 2016-02-06 10:57:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp 2024-10-20 09:00:00.000000000 +0000 @@ -1,674 +1,998 @@ -// UpdateCallbackConsole.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/ErrorMsg.h" - -#ifndef _7ZIP_ST -#include "../../../Windows/Synchronization.h" -#endif - -#include "ConsoleClose.h" -#include "UserInputUtils.h" -#include "UpdateCallbackConsole.h" - -using namespace NWindows; - -#ifndef _7ZIP_ST -static NSynchronization::CCriticalSection g_CriticalSection; -#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); -#else -#define MT_LOCK -#endif - -static const wchar_t *kEmptyFileAlias = L"[Content]"; - -static const char *kOpenArchiveMessage = "Open archive: "; -static const char *kCreatingArchiveMessage = "Creating archive: "; -static const char *kUpdatingArchiveMessage = "Updating archive: "; -static const char *kScanningMessage = "Scanning the drive:"; - -static const char *kError = "ERROR: "; -static const char *kWarning = "WARNING: "; - -static HRESULT CheckBreak2() -{ - return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; -} - -HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); -HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); - -void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); - -void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc); - -HRESULT CUpdateCallbackConsole::OpenResult( - const CCodecs *codecs, const CArchiveLink &arcLink, - const wchar_t *name, HRESULT result) -{ - ClosePercents2(); - - FOR_VECTOR (level, arcLink.Arcs) - { - const CArc &arc = arcLink.Arcs[level]; - const CArcErrorInfo &er = arc.ErrorInfo; - - UInt32 errorFlags = er.GetErrorFlags(); - - if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) - { - if (_se) - { - *_se << endl; - if (level != 0) - *_se << arc.Path << endl; - } - - if (errorFlags != 0) - { - if (_se) - PrintErrorFlags(*_se, "ERRORS:", errorFlags); - } - - if (!er.ErrorMessage.IsEmpty()) - { - if (_se) - *_se << "ERRORS:" << endl << er.ErrorMessage << endl; - } - - if (_se) - { - *_se << endl; - _se->Flush(); - } - } - - UInt32 warningFlags = er.GetWarningFlags(); - - if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) - { - if (_so) - { - *_so << endl; - if (level != 0) - *_so << arc.Path << endl; - } - - if (warningFlags != 0) - { - if (_so) - PrintErrorFlags(*_so, "WARNINGS:", warningFlags); - } - - if (!er.WarningMessage.IsEmpty()) - { - if (_so) - *_so << "WARNINGS:" << endl << er.WarningMessage << endl; - } - - if (_so) - { - *_so << endl; - if (NeedFlush) - _so->Flush(); - } - } - - - if (er.ErrorFormatIndex >= 0) - { - if (_so) - { - Print_ErrorFormatIndex_Warning(_so, codecs, arc); - if (NeedFlush) - _so->Flush(); - } - } - } - - if (result == S_OK) - { - if (_so) - { - RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)); - *_so << endl; - } - } - else - { - if (_so) - _so->Flush(); - if (_se) - { - *_se << kError << name << endl; - HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); - RINOK(res); - _se->Flush(); - } - } - - return S_OK; -} - -HRESULT CUpdateCallbackConsole::StartScanning() -{ - if (_so) - *_so << kScanningMessage << endl; - _percent.Command = "Scan "; - return S_OK; -} - -HRESULT CUpdateCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) -{ - if (NeedPercents()) - { - _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; - _percent.Completed = st.GetTotalBytes(); - _percent.FileName = fs2us(path); - _percent.Print(); - } - - return CheckBreak(); -} - -void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, bool isWarning) -{ - ClosePercents2(); - - if (_se) - { - if (_so) - _so->Flush(); - - *_se << endl << (isWarning ? kWarning : kError) - << NError::MyFormatMessage(systemError) - << endl << fs2us(path) << endl << endl; - _se->Flush(); - } -} - - -HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError) -{ - MT_LOCK - - ScanErrors.AddError(path, systemError); - CommonError(path, systemError, true); - - return S_OK; -} - -HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD systemError) -{ - MT_LOCK - FailedFiles.AddError(path, systemError); - /* - if (systemError == ERROR_SHARING_VIOLATION) - { - */ - CommonError(path, systemError, true); - return S_FALSE; - /* - } - return systemError; - */ -} - -HRESULT CCallbackConsoleBase::ReadingFileError_Base(const FString &path, DWORD systemError) -{ - MT_LOCK - CommonError(path, systemError, false); - return HRESULT_FROM_WIN32(systemError); -} - -HRESULT CUpdateCallbackConsole::ScanError(const FString &path, DWORD systemError) -{ - return ScanError_Base(path, systemError); -} - - -static void PrintPropPair(AString &s, const char *name, UInt64 val) -{ - char temp[32]; - ConvertUInt64ToString(val, temp); - s += name; - s += ": "; - s += temp; -} - -void PrintSize_bytes_Smart(AString &s, UInt64 val); -void Print_DirItemsStat(AString &s, const CDirItemsStat &st); - -HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st) -{ - if (NeedPercents()) - { - _percent.ClosePrint(true); - _percent.ClearCurState(); - } - - if (_so) - { - AString s; - Print_DirItemsStat(s, st); - *_so << s << endl << endl; - } - return S_OK; -} - -static const char *k_StdOut_ArcName = "StdOut"; - -HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name) -{ - if (_so) - { - *_so << kOpenArchiveMessage; - if (name) - *_so << name; - else - *_so << k_StdOut_ArcName; - *_so << endl; - } - return S_OK; -} - -HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) -{ - if (_so) - { - *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); - if (name != 0) - *_so << name; - else - *_so << k_StdOut_ArcName; - *_so << endl << endl; - } - return S_OK; -} - -HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st) -{ - ClosePercents2(); - - if (_so) - { - AString s; - // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files); - PrintPropPair(s, "Files read from disk", _percent.Files); - s.Add_LF(); - s += "Archive size: "; - PrintSize_bytes_Smart(s, st.OutArcFileSize); - s.Add_LF(); - *_so << endl; - *_so << s; - // *_so << endl; - } - - return S_OK; -} - -HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size) -{ - if (_so) - { - *_so << "Write SFX: "; - *_so << name; - AString s = " : "; - PrintSize_bytes_Smart(s, size); - *_so << s << endl; - } - return S_OK; -} - - -HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) -{ - if (LogLevel > 0 && _so) - { - ClosePercents_for_so(); - - if (!DeleteMessageWasShown) - { - if (_so) - *_so << endl << ": Removing files after including to archive" << endl; - } - - { - { - _tempA = "Removing"; - _tempA.Add_Space(); - *_so << _tempA; - _tempU = fs2us(path); - _so->PrintUString(_tempU, _tempA); - *_so << endl; - if (NeedFlush) - _so->Flush(); - } - } - } - - if (!DeleteMessageWasShown) - { - if (NeedPercents()) - { - _percent.ClearCurState(); - } - DeleteMessageWasShown = true; - } - else - { - _percent.Files++; - } - - if (NeedPercents()) - { - // if (!FullLog) - { - _percent.Command = "Removing"; - _percent.FileName = fs2us(path); - } - _percent.Print(); - } - - return S_OK; -} - - -HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving() -{ - ClosePercents2(); - if (_so && DeleteMessageWasShown) - *_so << endl; - return S_OK; -} - -HRESULT CUpdateCallbackConsole::CheckBreak() -{ - return CheckBreak2(); -} - -/* -HRESULT CUpdateCallbackConsole::Finalize() -{ - // MT_LOCK - return S_OK; -} -*/ - -HRESULT CUpdateCallbackConsole::SetNumItems(UInt64 numItems) -{ - if (_so) - { - ClosePercents_for_so(); - AString s; - PrintPropPair(s, "Items to compress", numItems); - *_so << s << endl << endl; - } - return S_OK; -} - -HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) -{ - MT_LOCK - if (NeedPercents()) - { - _percent.Total = size; - _percent.Print(); - } - return S_OK; -} - -HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) -{ - MT_LOCK - if (completeValue) - { - if (NeedPercents()) - { - _percent.Completed = *completeValue; - _percent.Print(); - } - } - return CheckBreak2(); -} - -HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */) -{ - return CheckBreak2(); -} - -HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, const char *command, bool showInLog) -{ - MT_LOCK - - bool show2 = (showInLog && _so); - - if (show2) - { - ClosePercents_for_so(); - - _tempA = command; - if (name) - _tempA.Add_Space(); - *_so << _tempA; - - _tempU.Empty(); - if (name) - _tempU = name; - _so->PrintUString(_tempU, _tempA); - *_so << endl; - if (NeedFlush) - _so->Flush(); - } - - if (NeedPercents()) - { - if (PercentsNameLevel >= 1) - { - _percent.FileName.Empty(); - _percent.Command.Empty(); - if (PercentsNameLevel > 1 || !show2) - { - _percent.Command = command; - if (name) - _percent.FileName = name; - } - } - _percent.Print(); - } - - return CheckBreak2(); -} - -HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool /* isDir */, bool isAnti, UInt32 mode) -{ - if (StdOutMode) - return S_OK; - - if (!name || name[0] == 0) - name = kEmptyFileAlias; - - unsigned requiredLevel = 1; - - const char *s; - if (mode == NUpdateNotifyOp::kAdd || - mode == NUpdateNotifyOp::kUpdate) - { - if (isAnti) - s = "Anti"; - else if (mode == NUpdateNotifyOp::kAdd) - s = "+"; - else - s = "U"; - } - else - { - requiredLevel = 3; - if (mode == NUpdateNotifyOp::kAnalyze) - s = "A"; - else - s = "Reading"; - } - - return PrintProgress(name, s, LogLevel >= requiredLevel); -} - -HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError) -{ - return OpenFileError_Base(path, systemError); -} - -HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError) -{ - return ReadingFileError_Base(path, systemError); -} - -HRESULT CUpdateCallbackConsole::SetOperationResult(Int32) -{ - MT_LOCK - _percent.Files++; - return S_OK; -} - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest); - -HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) -{ - // if (StdOutMode) return S_OK; - - if (opRes != NArchive::NExtract::NOperationResult::kOK) - { - ClosePercents2(); - - if (_se) - { - if (_so) - _so->Flush(); - - AString s; - SetExtractErrorMessage(opRes, isEncrypted, s); - *_se << s << " : " << endl << name << endl << endl; - _se->Flush(); - } - return S_OK; - } - return S_OK; -} - - -HRESULT CUpdateCallbackConsole::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool /* isDir */) -{ - // if (StdOutMode) return S_OK; - - char temp[16]; - const char *s; - - unsigned requiredLevel = 1; - - switch (op) - { - case NUpdateNotifyOp::kAdd: s = "+"; break; - case NUpdateNotifyOp::kUpdate: s = "U"; break; - case NUpdateNotifyOp::kAnalyze: s = "A"; requiredLevel = 3; break; - case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break; - case NUpdateNotifyOp::kRepack: s = "R"; requiredLevel = 2; break; - case NUpdateNotifyOp::kSkip: s = "."; requiredLevel = 2; break; - case NUpdateNotifyOp::kDelete: s = "D"; requiredLevel = 3; break; - case NUpdateNotifyOp::kHeader: s = "Header creation"; requiredLevel = 100; break; - default: - { - temp[0] = 'o'; - temp[1] = 'p'; - ConvertUInt64ToString(op, temp + 2); - s = temp; - } - } - - return PrintProgress(name, s, LogLevel >= requiredLevel); -} - -/* -HRESULT CUpdateCallbackConsole::SetPassword(const UString & - #ifndef _NO_CRYPTO - password - #endif - ) -{ - #ifndef _NO_CRYPTO - PasswordIsDefined = true; - Password = password; - #endif - return S_OK; -} -*/ - -HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - COM_TRY_BEGIN - - *password = NULL; - - #ifdef _NO_CRYPTO - - *passwordIsDefined = false; - return S_OK; - - #else - - if (!PasswordIsDefined) - { - if (AskPassword) - { - Password = GetPassword(_so,true); - PasswordIsDefined = true; - } - } - *passwordIsDefined = BoolToInt(PasswordIsDefined); - return StringToBstr(Password, password); - - #endif - - COM_TRY_END -} - -HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - - *password = NULL; - - #ifdef _NO_CRYPTO - - return E_NOTIMPL; - - #else - - if (!PasswordIsDefined) - { - { - Password = GetPassword(_so); - PasswordIsDefined = true; - } - } - return StringToBstr(Password, password); - - #endif - COM_TRY_END -} - -HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool /* isDir */) -{ - if (StdOutMode) - return S_OK; - - if (LogLevel > 7) - { - if (!name || name[0] == 0) - name = kEmptyFileAlias; - return PrintProgress(name, "D", true); - } - return S_OK; -} +// UpdateCallbackConsole.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileName.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +// #include "../Common/PropIDUtils.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" +#include "UpdateCallbackConsole.h" + +using namespace NWindows; + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + +static const wchar_t * const kEmptyFileAlias = L"[Content]"; + +static const char * const kOpenArchiveMessage = "Open archive: "; +static const char * const kCreatingArchiveMessage = "Creating archive: "; +static const char * const kUpdatingArchiveMessage = "Updating archive: "; +static const char * const kScanningMessage = "Scanning the drive:"; + +static const char * const kError = "ERROR: "; +static const char * const kWarning = "WARNING: "; + +static HRESULT CheckBreak2() +{ + return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK; +} + +HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); +HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink); + +void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags); + +void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc); + +HRESULT CUpdateCallbackConsole::OpenResult( + const CCodecs *codecs, const CArchiveLink &arcLink, + const wchar_t *name, HRESULT result) +{ + ClosePercents2(); + + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + UInt32 errorFlags = er.GetErrorFlags(); + + if (errorFlags != 0 || !er.ErrorMessage.IsEmpty()) + { + if (_se) + { + *_se << endl; + if (level != 0) + *_se << arc.Path << endl; + } + + if (errorFlags != 0) + { + if (_se) + PrintErrorFlags(*_se, "ERRORS:", errorFlags); + } + + if (!er.ErrorMessage.IsEmpty()) + { + if (_se) + *_se << "ERRORS:" << endl << er.ErrorMessage << endl; + } + + if (_se) + { + *_se << endl; + _se->Flush(); + } + } + + UInt32 warningFlags = er.GetWarningFlags(); + + if (warningFlags != 0 || !er.WarningMessage.IsEmpty()) + { + if (_so) + { + *_so << endl; + if (level != 0) + *_so << arc.Path << endl; + } + + if (warningFlags != 0) + { + if (_so) + PrintErrorFlags(*_so, "WARNINGS:", warningFlags); + } + + if (!er.WarningMessage.IsEmpty()) + { + if (_so) + *_so << "WARNINGS:" << endl << er.WarningMessage << endl; + } + + if (_so) + { + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + + + if (er.ErrorFormatIndex >= 0) + { + if (_so) + { + Print_ErrorFormatIndex_Warning(_so, codecs, arc); + if (NeedFlush) + _so->Flush(); + } + } + } + + if (result == S_OK) + { + if (_so) + { + RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink)) + *_so << endl; + } + } + else + { + if (_so) + _so->Flush(); + if (_se) + { + *_se << kError; + _se->NormalizePrint_wstr_Path(name); + *_se << endl; + HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink); + RINOK(res) + _se->Flush(); + } + } + + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartScanning() +{ + if (_so) + *_so << kScanningMessage << endl; + _percent.Command = "Scan "; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */) +{ + if (NeedPercents()) + { + _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams; + _percent.Completed = st.GetTotalBytes(); + _percent.FileName = fs2us(path); + _percent.Print(); + } + + return CheckBreak(); +} + +void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, bool isWarning) +{ + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + *_se << endl << (isWarning ? kWarning : kError) + << NError::MyFormatMessage(systemError) + << endl; + _se->NormalizePrint_UString_Path(fs2us(path)); + *_se << endl << endl; + _se->Flush(); + } +} + +/* +void CCallbackConsoleBase::CommonError(const char *message) +{ + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + *_se << endl << kError << message << endl; + _se->Flush(); + } +} +*/ + + +HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + + ScanErrors.AddError(path, systemError); + CommonError(path, systemError, true); + + return S_OK; +} + +HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + FailedFiles.AddError(path, systemError); + NumNonOpenFiles++; + /* + if (systemError == ERROR_SHARING_VIOLATION) + { + */ + CommonError(path, systemError, true); + return S_FALSE; + /* + } + return systemError; + */ +} + +HRESULT CCallbackConsoleBase::ReadingFileError_Base(const FString &path, DWORD systemError) +{ + MT_LOCK + CommonError(path, systemError, false); + return HRESULT_FROM_WIN32(systemError); +} + +HRESULT CUpdateCallbackConsole::ScanError(const FString &path, DWORD systemError) +{ + return ScanError_Base(path, systemError); +} + + +static void PrintPropPair(AString &s, const char *name, UInt64 val) +{ + char temp[32]; + ConvertUInt64ToString(val, temp); + s += name; + s += ": "; + s += temp; +} + +void PrintSize_bytes_Smart(AString &s, UInt64 val); +void Print_DirItemsStat(AString &s, const CDirItemsStat &st); +void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st); + +HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st) +{ + if (NeedPercents()) + { + _percent.ClosePrint(true); + _percent.ClearCurState(); + } + + if (_so) + { + AString s; + Print_DirItemsStat(s, st); + *_so << s << endl << endl; + } + return S_OK; +} + +static const char * const k_StdOut_ArcName = "StdOut"; + +HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name) +{ + if (_so) + { + *_so << kOpenArchiveMessage; + if (name) + *_so << name; + else + *_so << k_StdOut_ArcName; + *_so << endl; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) +{ + if (NeedPercents()) + _percent.ClosePrint(true); + + _percent.ClearCurState(); + NumNonOpenFiles = 0; + + if (_so) + { + *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage); + if (name) + _so->NormalizePrint_wstr_Path(name); + else + *_so << k_StdOut_ArcName; + *_so << endl << endl; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st) +{ + ClosePercents2(); + + if (_so) + { + AString s; + // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files); + PrintPropPair(s, "Files read from disk", _percent.Files - NumNonOpenFiles); + s.Add_LF(); + s += "Archive size: "; + PrintSize_bytes_Smart(s, st.OutArcFileSize); + s.Add_LF(); + if (st.IsMultiVolMode) + { + s += "Volumes: "; + s.Add_UInt32(st.NumVolumes); + s.Add_LF(); + } + *_so << endl; + *_so << s; + // *_so << endl; + } + + return S_OK; +} + +HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size) +{ + if (_so) + { + *_so << "Write SFX: "; + *_so << name; + AString s (" : "); + PrintSize_bytes_Smart(s, size); + *_so << s << endl; + } + return S_OK; +} + + + +HRESULT CUpdateCallbackConsole::MoveArc_UpdateStatus() +{ + if (NeedPercents()) + { + AString &s = _percent.Command; + s = " : "; + s.Add_UInt64(_arcMoving_percents); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent.Print(); + } + + // we ignore single Ctrl-C, if (_arcMoving_updateMode) mode + // because we want to get good final archive instead of temp archive. + if (NConsoleClose::g_BreakCounter == 1 && _arcMoving_updateMode) + return S_OK; + return CheckBreak(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Start( + const wchar_t *srcTempPath, const wchar_t *destFinalPath, + UInt64 size, Int32 updateMode) +{ +#if 0 // 1 : for debug + if (LogLevel > 0 && _so) + { + ClosePercents_for_so(); + *_so << "Temporary archive moving:" << endl; + _tempU = srcTempPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + _tempU = destFinalPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + } +#else + UNUSED_VAR(srcTempPath) + UNUSED_VAR(destFinalPath) +#endif + + _arcMoving_updateMode = updateMode; + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize) +{ +#if 0 // 1 : for debug + if (_so) + { + ClosePercents_for_so(); + *_so << totalSize << " : " << currentSize << endl; + } +#endif + + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + // totalSize = (UInt64)(Int64)-1; // for debug + + if (percents == _arcMoving_percents) + return CheckBreak(); + _arcMoving_current = currentSize; + _arcMoving_total = totalSize; + _arcMoving_percents = percents; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Finish() +{ + // _arcMoving_percents = 0; + if (NeedPercents()) + { + _percent.Command.Empty(); + _percent.Print(); + } + // it can return delayed user break (E_ABORT) status, + // if it ignored single CTRL+C in MoveArc_Progress(). + return CheckBreak(); +} + + + +HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) +{ + if (LogLevel > 0 && _so) + { + ClosePercents_for_so(); + + if (!DeleteMessageWasShown) + { + if (_so) + *_so << endl << ": Removing files after including to archive" << endl; + } + + { + { + _tempA = "Removing"; + _tempA.Add_Space(); + *_so << _tempA; + _tempU = fs2us(path); + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + } + } + + if (!DeleteMessageWasShown) + { + if (NeedPercents()) + { + _percent.ClearCurState(); + } + DeleteMessageWasShown = true; + } + else + { + _percent.Files++; + } + + if (NeedPercents()) + { + // if (!FullLog) + { + _percent.Command = "Removing"; + _percent.FileName = fs2us(path); + } + _percent.Print(); + } + + return S_OK; +} + + +HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving() +{ + ClosePercents2(); + if (_so && DeleteMessageWasShown) + *_so << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CheckBreak() +{ + return CheckBreak2(); +} + +/* +HRESULT CUpdateCallbackConsole::Finalize() +{ + // MT_LOCK + return S_OK; +} +*/ + + +void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name) +{ + AString s; + Print_DirItemsStat2(s, stat); + *_so << name << ": " << s << endl; +} + +HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat) +{ + if (_so) + { + ClosePercents_for_so(); + if (!stat.DeleteData.IsEmpty()) + { + *_so << endl; + PrintToDoStat(_so, stat.DeleteData, "Delete data from archive"); + } + if (!stat.OldData.IsEmpty()) + PrintToDoStat(_so, stat.OldData, "Keep old data in archive"); + // if (!stat.NewData.IsEmpty()) + { + PrintToDoStat(_so, stat.NewData, "Add new data to archive"); + } + *_so << endl; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) +{ + MT_LOCK + if (NeedPercents()) + { + _percent.Total = size; + _percent.Print(); + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + MT_LOCK + if (completeValue) + { + if (NeedPercents()) + { + _percent.Completed = *completeValue; + _percent.Print(); + } + } + return CheckBreak2(); +} + +HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */) +{ + return CheckBreak2(); +} + +HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog) +{ + MT_LOCK + + bool show2 = (showInLog && _so); + + if (show2) + { + ClosePercents_for_so(); + + _tempA = command; + if (name) + _tempA.Add_Space(); + *_so << _tempA; + + _tempU.Empty(); + if (name) + { + _tempU = name; + if (isDir) + NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU); + _so->Normalize_UString_Path(_tempU); + } + _so->PrintUString(_tempU, _tempA); + *_so << endl; + if (NeedFlush) + _so->Flush(); + } + + if (NeedPercents()) + { + if (PercentsNameLevel >= 1) + { + _percent.FileName.Empty(); + _percent.Command.Empty(); + if (PercentsNameLevel > 1 || !show2) + { + _percent.Command = command; + if (name) + _percent.FileName = name; + } + } + _percent.Print(); + } + + 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) + return S_OK; + + if (!name || name[0] == 0) + name = kEmptyFileAlias; + + unsigned requiredLevel = 1; + + const char *s; + if (mode == NUpdateNotifyOp::kAdd || + mode == NUpdateNotifyOp::kUpdate) + { + if (isAnti) + s = "Anti"; + else if (mode == NUpdateNotifyOp::kAdd) + s = "+"; + else + s = "U"; + } + else + { + requiredLevel = 3; + if (mode == NUpdateNotifyOp::kAnalyze) + s = "A"; + else + s = "Reading"; + } + + return PrintProgress(name, isDir, s, LogLevel >= requiredLevel); +} + +HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError) +{ + return OpenFileError_Base(path, systemError); +} + +HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError) +{ + return ReadingFileError_Base(path, systemError); +} + +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; +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest); + +HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) +{ + // if (StdOutMode) return S_OK; + + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + ClosePercents2(); + + if (_se) + { + if (_so) + _so->Flush(); + + AString s; + SetExtractErrorMessage(opRes, isEncrypted, s); + *_se << s << " : " << endl; + _se->NormalizePrint_wstr_Path(name); + *_se << endl << endl; + _se->Flush(); + } + return S_OK; + } + return S_OK; +} + + +HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) +{ + // if (StdOutMode) return S_OK; + + char temp[16]; + const char *s; + + unsigned requiredLevel = 1; + + switch (op) + { + case NUpdateNotifyOp::kAdd: s = "+"; break; + case NUpdateNotifyOp::kUpdate: s = "U"; break; + case NUpdateNotifyOp::kAnalyze: s = "A"; requiredLevel = 3; break; + case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break; + case NUpdateNotifyOp::kRepack: s = "R"; requiredLevel = 2; break; + 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'; + temp[1] = 'p'; + ConvertUInt64ToString(op, temp + 2); + s = temp; + } + } + + return PrintProgress(name, isDir, s, LogLevel >= requiredLevel); +} + +/* +HRESULT CUpdateCallbackConsole::SetPassword(const UString & + #ifndef Z7_NO_CRYPTO + password + #endif + ) +{ + #ifndef Z7_NO_CRYPTO + PasswordIsDefined = true; + Password = password; + #endif + return S_OK; +} +*/ + +HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + COM_TRY_BEGIN + + *password = NULL; + + #ifdef Z7_NO_CRYPTO + + *passwordIsDefined = false; + return S_OK; + + #else + + if (!PasswordIsDefined) + { + if (AskPassword) + { + RINOK(GetPassword_HRESULT(_so, Password)) + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + return StringToBstr(Password, password); + + #endif + + COM_TRY_END +} + +HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + COM_TRY_BEGIN + + *password = NULL; + + #ifdef Z7_NO_CRYPTO + + return E_NOTIMPL; + + #else + + if (!PasswordIsDefined) + { + { + RINOK(GetPassword_HRESULT(_so, Password)) + PasswordIsDefined = true; + } + } + return StringToBstr(Password, password); + + #endif + COM_TRY_END +} + +HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir) +{ + if (StdOutMode) + return S_OK; + + if (LogLevel > 7) + { + if (!name || name[0] == 0) + name = kEmptyFileAlias; + return PrintProgress(name, isDir, "D", true); + } + return S_OK; +} + +/* +void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU); + +static void GetPropName(PROPID propID, UString &nameU) +{ + AString nameA; + GetPropName(propID, NULL, nameA, nameU); + // if (!nameA.IsEmpty()) + nameU = nameA; +} + + +static void AddPropNamePrefix(UString &s, PROPID propID) +{ + UString name; + GetPropName(propID, name); + s += name; + s += " = "; +} + +void CCallbackConsoleBase::PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value) +{ + AddPropNamePrefix(s, propID); + { + UString dest; + const int level = 9; // we show up to ns precision level + ConvertPropertyToString2(dest, *value, propID, level); + s += dest; + } + PrintInfoLine(s); +} + +static void Add_IndexType_Index(UString &s, UInt32 indexType, UInt32 index) +{ + if (indexType == NArchive::NEventIndexType::kArcProp) + { + } + else + { + if (indexType == NArchive::NEventIndexType::kBlockIndex) + { + s += "#"; + } + else if (indexType == NArchive::NEventIndexType::kOutArcIndex) + { + } + else + { + s += "indexType_"; + s.Add_UInt32(indexType); + s.Add_Space(); + } + s.Add_UInt32(index); + } + s += ": "; +} + +HRESULT CUpdateCallbackConsole::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value) +{ + UString s; + Add_IndexType_Index(s, indexType, index); + PrintPropInfo(s, propID, value); + return S_OK; +} + +static inline char GetHex(Byte value) +{ + return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10))); +} + +static void AddHexToString(UString &dest, const Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + { + Byte b = data[i]; + dest += GetHex((Byte)((b >> 4) & 0xF)); + dest += GetHex((Byte)(b & 0xF)); + } +} + +void HashHexToString(char *dest, const Byte *data, UInt32 size); + +HRESULT CUpdateCallbackConsole::ReportRawProp(UInt32 indexType, UInt32 index, + PROPID propID, const void *data, UInt32 dataSize, UInt32 propType) +{ + UString s; + propType = propType; + Add_IndexType_Index(s, indexType, index); + AddPropNamePrefix(s, propID); + if (propID == kpidChecksum) + { + char temp[k_HashCalc_DigestSize_Max + 8]; + HashHexToString(temp, (const Byte *)data, dataSize); + s += temp; + } + else + AddHexToString(s, (const Byte *)data, dataSize); + PrintInfoLine(s); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes) +{ + UString s; + Add_IndexType_Index(s, indexType, index); + s += "finished"; + if (opRes != NArchive::NUpdate::NOperationResult::kOK) + { + s += ": "; + s.Add_UInt32(opRes); + } + PrintInfoLine(s); + return S_OK; +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/UpdateCallbackConsole.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/UpdateCallbackConsole.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UpdateCallbackConsole.h 2024-10-20 09:00:00.000000000 +0000 @@ -1,124 +1,148 @@ -// UpdateCallbackConsole.h - -#ifndef __UPDATE_CALLBACK_CONSOLE_H -#define __UPDATE_CALLBACK_CONSOLE_H - -#include "../../../Common/StdOutStream.h" - -#include "../Common/Update.h" - -#include "PercentPrinter.h" - -struct CErrorPathCodes -{ - FStringVector Paths; - CRecordVector Codes; - - void AddError(const FString &path, DWORD systemError) - { - Paths.Add(path); - Codes.Add(systemError); - } - void Clear() - { - Paths.Clear(); - Codes.Clear(); - } -}; - -class CCallbackConsoleBase -{ -protected: - CPercentPrinter _percent; - - CStdOutStream *_so; - CStdOutStream *_se; - - void CommonError(const FString &path, DWORD systemError, bool isWarning); - - HRESULT ScanError_Base(const FString &path, DWORD systemError); - HRESULT OpenFileError_Base(const FString &name, DWORD systemError); - HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); - -public: - bool NeedPercents() const { return _percent._so != NULL; }; - - bool StdOutMode; - - bool NeedFlush; - unsigned PercentsNameLevel; - unsigned LogLevel; - - AString _tempA; - UString _tempU; - - CCallbackConsoleBase(): - StdOutMode(false), - NeedFlush(false), - PercentsNameLevel(1), - LogLevel(0) - {} - - void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } - - void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream) - { - FailedFiles.Clear(); - - _so = outStream; - _se = errorStream; - _percent._so = percentStream; - } - - void ClosePercents2() - { - if (NeedPercents()) - _percent.ClosePrint(true); - } - - void ClosePercents_for_so() - { - if (NeedPercents() && _so == _percent._so) - _percent.ClosePrint(false); - } - - - CErrorPathCodes FailedFiles; - CErrorPathCodes ScanErrors; - - HRESULT PrintProgress(const wchar_t *name, const char *command, bool showInLog); - -}; - -class CUpdateCallbackConsole: public IUpdateCallbackUI2, public CCallbackConsoleBase -{ - // void PrintPropPair(const char *name, const wchar_t *val); - -public: - #ifndef _NO_CRYPTO - bool PasswordIsDefined; - UString Password; - bool AskPassword; - #endif - - bool DeleteMessageWasShown; - - CUpdateCallbackConsole() - : DeleteMessageWasShown(false) - #ifndef _NO_CRYPTO - , PasswordIsDefined(false) - , AskPassword(false) - #endif - {} - - /* - void Init(CStdOutStream *outStream) - { - CCallbackConsoleBase::Init(outStream); - } - */ - // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); } - INTERFACE_IUpdateCallbackUI2(;) -}; - -#endif +// UpdateCallbackConsole.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H +#define ZIP7_INC_UPDATE_CALLBACK_CONSOLE_H + +#include "../../../Common/StdOutStream.h" + +#include "../Common/Update.h" + +#include "PercentPrinter.h" + +struct CErrorPathCodes +{ + FStringVector Paths; + CRecordVector Codes; + + void AddError(const FString &path, DWORD systemError) + { + Paths.Add(path); + Codes.Add(systemError); + } + void Clear() + { + Paths.Clear(); + Codes.Clear(); + } +}; + + +class CCallbackConsoleBase +{ + void CommonError(const FString &path, DWORD systemError, bool isWarning); + +protected: + CStdOutStream *_so; + CStdOutStream *_se; + + HRESULT ScanError_Base(const FString &path, DWORD systemError); + HRESULT OpenFileError_Base(const FString &name, DWORD systemError); + HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); + +public: + bool StdOutMode; + bool NeedFlush; + unsigned PercentsNameLevel; + unsigned LogLevel; + +protected: + AString _tempA; + UString _tempU; + CPercentPrinter _percent; + +public: + CErrorPathCodes FailedFiles; + CErrorPathCodes ScanErrors; + UInt64 NumNonOpenFiles; + + CCallbackConsoleBase(): + StdOutMode(false), + NeedFlush(false), + PercentsNameLevel(1), + LogLevel(0), + NumNonOpenFiles(0) + {} + + bool NeedPercents() const { return _percent._so != NULL; } + void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } + + void Init( + CStdOutStream *outStream, + CStdOutStream *errorStream, + CStdOutStream *percentStream, + bool disablePercents) + { + FailedFiles.Clear(); + + _so = outStream; + _se = errorStream; + _percent._so = percentStream; + _percent.DisablePrint = disablePercents; + } + + void ClosePercents2() + { + if (NeedPercents()) + _percent.ClosePrint(true); + } + + void ClosePercents_for_so() + { + if (NeedPercents() && _so == _percent._so) + _percent.ClosePrint(false); + } + + 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 Z7_final: + public IUpdateCallbackUI2, + public CCallbackConsoleBase +{ + // void PrintPropPair(const char *name, const wchar_t *val); + Z7_IFACE_IMP(IUpdateCallbackUI) + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IUpdateCallbackUI2) + + HRESULT MoveArc_UpdateStatus(); + + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + Int32 _arcMoving_updateMode; + +public: + bool DeleteMessageWasShown; + + #ifndef Z7_NO_CRYPTO + bool PasswordIsDefined; + bool AskPassword; + UString Password; + #endif + + CUpdateCallbackConsole(): + _arcMoving_total(0) + , _arcMoving_current(0) + , _arcMoving_percents(0) + , _arcMoving_updateMode(0) + , DeleteMessageWasShown(false) + #ifndef Z7_NO_CRYPTO + , PasswordIsDefined(false) + , AskPassword(false) + #endif + {} + + /* + void Init(CStdOutStream *outStream) + { + CCallbackConsoleBase::Init(outStream); + } + */ + // ~CUpdateCallbackConsole() { if (NeedPercents()) _percent.ClosePrint(); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/UserInputUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Console/UserInputUtils.cpp 2015-06-19 16:25:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.cpp 2024-02-26 09:00:00.000000000 +0000 @@ -1,105 +1,118 @@ -// UserInputUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/StdInStream.h" -#include "../../../Common/StringConvert.h" - -#include "UserInputUtils.h" - -#ifdef USE_FLTK -// the programs like file-roller or xarchiver do not support archives with password -// these programs freeze because p7zip is waiting for a password -// defining USE_FLTK allows p7zip to use a popup in order to ask the password. -#include -#include -#include -#else -#ifdef ENV_HAVE_GETPASS -#include -#include -#include "Common/MyException.h" -#endif -#endif - -static const char kYes = 'y'; -static const char kNo = 'n'; -static const char kYesAll = 'a'; -static const char kNoAll = 's'; -static const char kAutoRenameAll = 'u'; -static const char kQuit = 'q'; - -static const char *kFirstQuestionMessage = "? "; -static const char *kHelpQuestionMessage = - "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? "; - -// return true if pressed Quite; - -NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) -{ - if (outStream) - *outStream << kFirstQuestionMessage; - for (;;) - { - if (outStream) - { - *outStream << kHelpQuestionMessage; - outStream->Flush(); - } - AString scannedString = g_StdIn.ScanStringUntilNewLine(); - scannedString.Trim(); - if (!scannedString.IsEmpty()) - switch(::MyCharLower_Ascii(scannedString[0])) - { - case kYes: return NUserAnswerMode::kYes; - case kNo: return NUserAnswerMode::kNo; - case kYesAll: return NUserAnswerMode::kYesAll; - case kNoAll: return NUserAnswerMode::kNoAll; - case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll; - case kQuit: return NUserAnswerMode::kQuit; - } - } -} - -#ifdef _WIN32 -#ifndef UNDER_CE -#define MY_DISABLE_ECHO -#endif -#endif - -#ifdef ENV_HAVE_GETPASS -#define MY_DISABLE_ECHO -#endif - -UString GetPassword(CStdOutStream *outStream,bool verify) -{ -#ifdef USE_FLTK - const char *r = fl_password("Enter password", 0); - AString oemPassword = ""; - if (r) oemPassword = r; - return MultiByteToUnicodeString(oemPassword, CP_OEMCP); -#else /* USE_FLTK */ - if (outStream) - { - *outStream << "\nEnter password" - #ifdef MY_DISABLE_ECHO - " (will not be echoed)" - #endif - ":"; - outStream->Flush(); - } -#ifdef ENV_HAVE_GETPASS - AString oemPassword = getpass(""); - if ( (verify) && (outStream) ) - { - (*outStream) << "Verify password (will not be echoed) :"; - outStream->Flush(); - AString oemPassword2 = getpass(""); - if (oemPassword != oemPassword2) throw "password verification failed"; - } - return MultiByteToUnicodeString(oemPassword, CP_OEMCP); -#else - return g_StdIn.ScanUStringUntilNewLine(); -#endif -#endif /* USE_FLTK */ -} +// UserInputUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/StdInStream.h" +#include "../../../Common/StringConvert.h" + +#include "UserInputUtils.h" + +static const char kYes = 'y'; +static const char kNo = 'n'; +static const char kYesAll = 'a'; +static const char kNoAll = 's'; +static const char kAutoRenameAll = 'u'; +static const char kQuit = 'q'; + +static const char * const kFirstQuestionMessage = "? "; +static const char * const kHelpQuestionMessage = + "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? "; + +// return true if pressed Quite; + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) +{ + if (outStream) + *outStream << kFirstQuestionMessage; + for (;;) + { + if (outStream) + { + *outStream << kHelpQuestionMessage; + outStream->Flush(); + } + AString scannedString; + if (!g_StdIn.ScanAStringUntilNewLine(scannedString)) + return NUserAnswerMode::kError; + if (g_StdIn.Error()) + return NUserAnswerMode::kError; + scannedString.Trim(); + if (scannedString.IsEmpty() && g_StdIn.Eof()) + return NUserAnswerMode::kEof; + + if (scannedString.Len() == 1) + switch (::MyCharLower_Ascii(scannedString[0])) + { + case kYes: return NUserAnswerMode::kYes; + case kNo: return NUserAnswerMode::kNo; + case kYesAll: return NUserAnswerMode::kYesAll; + case kNoAll: return NUserAnswerMode::kNoAll; + case kAutoRenameAll: return NUserAnswerMode::kAutoRenameAll; + case kQuit: return NUserAnswerMode::kQuit; + default: break; + } + } +} + +#ifdef _WIN32 +#ifndef UNDER_CE +#define MY_DISABLE_ECHO +#endif +#endif + +static bool GetPassword(CStdOutStream *outStream, UString &psw) +{ + if (outStream) + { + *outStream << "\nEnter password" + #ifdef MY_DISABLE_ECHO + " (will not be echoed)" + #endif + ":"; + outStream->Flush(); + } + + #ifdef MY_DISABLE_ECHO + + const HANDLE console = GetStdHandle(STD_INPUT_HANDLE); + + /* + GetStdHandle() returns + INVALID_HANDLE_VALUE: If the function fails. + NULL : If an application does not have associated standard handles, + such as a service running on an interactive desktop, + and has not redirected them. */ + bool wasChanged = false; + DWORD mode = 0; + if (console != INVALID_HANDLE_VALUE && console != NULL) + if (GetConsoleMode(console, &mode)) + wasChanged = (SetConsoleMode(console, mode & ~(DWORD)ENABLE_ECHO_INPUT) != 0); + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); + if (wasChanged) + SetConsoleMode(console, mode); + + #else + + const bool res = g_StdIn.ScanUStringUntilNewLine(psw); + + #endif + + if (outStream) + { + *outStream << endl; + outStream->Flush(); + } + + return res; +} + +HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw) +{ + if (!GetPassword(outStream, psw)) + return E_INVALIDARG; + if (g_StdIn.Error()) + return E_FAIL; + if (g_StdIn.Eof() && psw.IsEmpty()) + return E_ABORT; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/UserInputUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/Console/UserInputUtils.h 2014-12-22 17:28:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/UserInputUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,24 +1,27 @@ -// UserInputUtils.h - -#ifndef __USER_INPUT_UTILS_H -#define __USER_INPUT_UTILS_H - -#include "../../../Common/StdOutStream.h" - -namespace NUserAnswerMode { - -enum EEnum -{ - kYes, - kNo, - kYesAll, - kNoAll, - kAutoRenameAll, - kQuit -}; -} - -NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); -UString GetPassword(CStdOutStream *outStream,bool verify = false); - -#endif +// UserInputUtils.h + +#ifndef ZIP7_INC_USER_INPUT_UTILS_H +#define ZIP7_INC_USER_INPUT_UTILS_H + +#include "../../../Common/StdOutStream.h" + +namespace NUserAnswerMode { + +enum EEnum +{ + kYes, + kNo, + kYesAll, + kNoAll, + kAutoRenameAll, + kQuit, + kEof, + kError +}; +} + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); +// bool GetPassword(CStdOutStream *outStream, UString &psw); +HRESULT GetPassword_HRESULT(CStdOutStream *outStream, UString &psw); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile --- p7zip-rar-16.02/CPP/7zip/UI/Console/makefile 2016-03-10 20:24:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,10 +1,68 @@ - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb - +PROG = 7z.exe +CFLAGS = $(CFLAGS) \ + -DZ7_EXTERNAL_CODECS \ + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Registry.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodProps.obj \ + $O\MultiOutStream.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + +C_OBJS = $(C_OBJS) \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../Sort.mak" +!include "Console.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/makefile.gcc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.gcc --- p7zip-rar-16.02/CPP/7zip/UI/Console/makefile.gcc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.gcc 2024-01-29 08:00:00.000000000 +0000 @@ -0,0 +1,187 @@ +PROG = 7z +IS_NOT_STANDALONE = 1 + +# IS_X64 = 1 +# USE_ASM = 1 +# ST_MODE = 1 + + +LOCAL_FLAGS_ST = +MT_OBJS = + +ifdef SystemDrive +IS_MINGW = 1 +else +ifdef SYSTEMDRIVE +# ifdef OS +IS_MINGW = 1 +endif +endif + +ifdef ST_MODE + +LOCAL_FLAGS_ST = -DZ7_ST + +ifdef IS_MINGW +MT_OBJS = \ + $O/Threads.o \ + +endif + +else + +MT_OBJS = \ + $O/Synchronization.o \ + $O/Threads.o \ + +endif + + + +LOCAL_FLAGS_SYS= + +ifdef IS_MINGW + +LOCAL_FLAGS_SYS = \ + -DZ7_DEVICE_FILE \ + +# -DZ7_LARGE_PAGES +# -DZ7_LONG_PATH + +SYS_OBJS = \ + $O/FileSystem.o \ + $O/Registry.o \ + $O/MemoryLock.o \ + $O/DllSecur.o \ + $O/resource.o \ + +else + +SYS_OBJS = \ + $O/MyWindows.o \ + +endif + + + +LOCAL_FLAGS = \ + $(LOCAL_FLAGS_SYS) \ + $(LOCAL_FLAGS_ST) \ + -DZ7_EXTERNAL_CODECS \ + + + +CONSOLE_OBJS = \ + $O/BenchCon.o \ + $O/ConsoleClose.o \ + $O/ExtractCallbackConsole.o \ + $O/HashCon.o \ + $O/List.o \ + $O/Main.o \ + $O/MainAr.o \ + $O/OpenCallbackConsole.o \ + $O/PercentPrinter.o \ + $O/UpdateCallbackConsole.o \ + $O/UserInputUtils.o \ + +UI_COMMON_OBJS = \ + $O/ArchiveCommandLine.o \ + $O/ArchiveExtractCallback.o \ + $O/ArchiveOpenCallback.o \ + $O/Bench.o \ + $O/DefaultName.o \ + $O/EnumDirItems.o \ + $O/Extract.o \ + $O/ExtractingFilePath.o \ + $O/HashCalc.o \ + $O/LoadCodecs.o \ + $O/OpenArchive.o \ + $O/PropIDUtils.o \ + $O/SetProperties.o \ + $O/SortUtils.o \ + $O/TempFiles.o \ + $O/Update.o \ + $O/UpdateAction.o \ + $O/UpdateCallback.o \ + $O/UpdatePair.o \ + $O/UpdateProduce.o \ + +COMMON_OBJS = \ + $O/CommandLineParser.o \ + $O/CRC.o \ + $O/CrcReg.o \ + $O/DynLimBuf.o \ + $O/IntToString.o \ + $O/ListFileUtils.o \ + $O/NewHandler.o \ + $O/StdInStream.o \ + $O/StdOutStream.o \ + $O/MyString.o \ + $O/StringConvert.o \ + $O/StringToInt.o \ + $O/UTFConvert.o \ + $O/MyVector.o \ + $O/Wildcard.o \ + +WIN_OBJS = \ + $O/DLL.o \ + $O/ErrorMsg.o \ + $O/FileDir.o \ + $O/FileFind.o \ + $O/FileIO.o \ + $O/FileLink.o \ + $O/FileName.o \ + $O/PropVariant.o \ + $O/PropVariantConv.o \ + $O/System.o \ + $O/SystemInfo.o \ + $O/TimeUtils.o \ + +7ZIP_COMMON_OBJS = \ + $O/CreateCoder.o \ + $O/CWrappers.o \ + $O/FilePathAutoRename.o \ + $O/FileStreams.o \ + $O/InBuffer.o \ + $O/InOutTempBuffer.o \ + $O/FilterCoder.o \ + $O/LimitedStreams.o \ + $O/MethodId.o \ + $O/MethodProps.o \ + $O/MultiOutStream.o \ + $O/OffsetStream.o \ + $O/OutBuffer.o \ + $O/ProgressUtils.o \ + $O/PropId.o \ + $O/StreamObjects.o \ + $O/StreamUtils.o \ + $O/UniqBlocks.o \ + +COMPRESS_OBJS = \ + $O/CopyCoder.o \ + +AR_COMMON_OBJS = \ + $O/ItemNameUtils.o \ + +C_OBJS = \ + $O/Alloc.o \ + $O/CpuArch.o \ + $O/Sort.o \ + $O/7zCrc.o \ + $O/7zCrcOpt.o \ + + +OBJS = \ + $(C_OBJS) \ + $(MT_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(SYS_OBJS) \ + $(COMPRESS_OBJS) \ + $(AR_COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(CONSOLE_OBJS) \ + + +include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/Console/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,333 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7z$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -ArchiveCommandLine.o : ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -Bench.o : ../../../../CPP/7zip/UI/Common/Bench.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Bench.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -EnumDirItems.o : ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp -Extract.o : ../../../../CPP/7zip/UI/Common/Extract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Extract.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -HashCalc.o : ../../../../CPP/7zip/UI/Common/HashCalc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/HashCalc.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -SetProperties.o : ../../../../CPP/7zip/UI/Common/SetProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SetProperties.cpp -SortUtils.o : ../../../../CPP/7zip/UI/Common/SortUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SortUtils.cpp -TempFiles.o : ../../../../CPP/7zip/UI/Common/TempFiles.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/TempFiles.cpp -Update.o : ../../../../CPP/7zip/UI/Common/Update.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Update.cpp -UpdateAction.o : ../../../../CPP/7zip/UI/Common/UpdateAction.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateAction.cpp -UpdateCallback.o : ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp -UpdatePair.o : ../../../../CPP/7zip/UI/Common/UpdatePair.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdatePair.cpp -UpdateProduce.o : ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp -BenchCon.o : ../../../../CPP/7zip/UI/Console/BenchCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/BenchCon.cpp -ConsoleClose.o : ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp -ExtractCallbackConsole.o : ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp -HashCon.o : ../../../../CPP/7zip/UI/Console/HashCon.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/HashCon.cpp -List.o : ../../../../CPP/7zip/UI/Console/List.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/List.cpp -Main.o : ../../../../CPP/7zip/UI/Console/Main.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/Main.cpp -MainAr.o : ../../../../CPP/7zip/UI/Console/MainAr.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/MainAr.cpp -OpenCallbackConsole.o : ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp -PercentPrinter.o : ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp -UpdateCallbackConsole.o : ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp -UserInputUtils.o : ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -ListFileUtils.o : ../../../../CPP/Common/ListFileUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/ListFileUtils.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -StdInStream.o : ../../../../CPP/Common/StdInStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdInStream.cpp -StdOutStream.o : ../../../../CPP/Common/StdOutStream.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StdOutStream.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -DLL.o : ../../../../CPP/Windows/DLL.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/DLL.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -myAddExeFlag.o : ../../../../CPP/myWindows/myAddExeFlag.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/myAddExeFlag.cpp -mySplitCommandLine.o : ../../../../CPP/myWindows/mySplitCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/mySplitCommandLine.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Alloc.o \ - CpuArch.o \ - Threads.o \ - OutStreamWithCRC.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - LimitedStreams.o \ - MethodProps.o \ - ProgressUtils.o \ - PropId.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - CopyCoder.o \ - ArchiveCommandLine.o \ - ArchiveExtractCallback.o \ - ArchiveOpenCallback.o \ - Bench.o \ - DefaultName.o \ - EnumDirItems.o \ - Extract.o \ - ExtractingFilePath.o \ - HashCalc.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - SetProperties.o \ - SortUtils.o \ - TempFiles.o \ - Update.o \ - UpdateAction.o \ - UpdateCallback.o \ - UpdatePair.o \ - UpdateProduce.o \ - BenchCon.o \ - ConsoleClose.o \ - ExtractCallbackConsole.o \ - HashCon.o \ - List.o \ - Main.o \ - MainAr.o \ - OpenCallbackConsole.o \ - PercentPrinter.o \ - UpdateCallbackConsole.o \ - UserInputUtils.o \ - CRC.o \ - CommandLineParser.o \ - IntToString.o \ - ListFileUtils.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - NewHandler.o \ - StdInStream.o \ - StdOutStream.o \ - StringConvert.o \ - StringToInt.o \ - UTFConvert.o \ - Wildcard.o \ - DLL.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - System.o \ - TimeUtils.o \ - myAddExeFlag.o \ - mySplitCommandLine.o \ - wine_date_and_time.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Console/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/Console/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Console/resource.rc 2018-04-04 13:02:25.000000000 +0000 @@ -0,0 +1,7 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Console" , "7z") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "Console.manifest" +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/7-zip.dll.manifest p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/7-zip.dll.manifest --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/7-zip.dll.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/7-zip.dll.manifest 2005-07-26 12:35:42.000000000 +0000 @@ -0,0 +1 @@ +7-Zip Extension. diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenu.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.cpp 2024-11-26 11:00:00.000000000 +0000 @@ -0,0 +1,1837 @@ +// ContextMenu.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/COM.h" +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/ProcessUtils.h" + +// for IS_INTRESOURCE(): +#include "../../../Windows/Window.h" + +#include "../../PropID.h" + +#include "../Common/ArchiveName.h" +#include "../Common/CompressCall.h" +#include "../Common/ExtractingFilePath.h" +#include "../Common/ZipRegistry.h" + +#include "../FileManager/FormatUtils.h" +#include "../FileManager/LangUtils.h" +#include "../FileManager/PropertyName.h" + +#include "ContextMenu.h" +#include "ContextMenuFlags.h" +#include "MyMessages.h" + +#include "resource.h" + + +// #define SHOW_DEBUG_CTX_MENU + +#ifdef SHOW_DEBUG_CTX_MENU +#include +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +#ifndef UNDER_CE +#define EMAIL_SUPPORT 1 +#endif + +extern LONG g_DllRefCount; + +#ifdef _WIN32 +extern HINSTANCE g_hInstance; +#endif + +#ifdef UNDER_CE + #define MY_IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0) +#else + #define MY_IS_INTRESOURCE(_r) IS_INTRESOURCE(_r) +#endif + + +#ifdef SHOW_DEBUG_CTX_MENU + +static void PrintStringA(const char *name, LPCSTR ptr) +{ + AString m; + m += name; + m += ": "; + char s[32]; + sprintf(s, "%p", (const void *)ptr); + m += s; + if (!MY_IS_INTRESOURCE(ptr)) + { + m += ": \""; + m += ptr; + m += "\""; + } + OutputDebugStringA(m); +} + +#if !defined(UNDER_CE) +static void PrintStringW(const char *name, LPCWSTR ptr) +{ + UString m; + m += name; + m += ": "; + char s[32]; + sprintf(s, "%p", (const void *)ptr); + m += s; + if (!MY_IS_INTRESOURCE(ptr)) + { + m += ": \""; + m += ptr; + m += "\""; + } + OutputDebugStringW(m); +} +#endif + +static void Print_Ptr(const void *p, const char *s) +{ + char temp[32]; + sprintf(temp, "%p", (const void *)p); + AString m; + m += temp; + m.Add_Space(); + m += s; + OutputDebugStringA(m); +} + +static void Print_Number(UInt32 number, const char *s) +{ + AString m; + m.Add_UInt32(number); + m.Add_Space(); + m += s; + OutputDebugStringA(m); +} + +#define ODS(sz) { Print_Ptr(this, sz); } +#define ODS_U(s) { OutputDebugStringW(s); } +#define ODS_(op) { op; } +#define ODS_SPRF_s(x) { char s[256]; x; OutputDebugStringA(s); } + +#else + +#define ODS(sz) +#define ODS_U(s) +#define ODS_(op) +#define ODS_SPRF_s(x) + +#endif + + +/* +DOCs: In Windows 7 and later, the number of items passed to + a verb is limited to 16 when a shortcut menu is queried. + The verb is then re-created and re-initialized with the full + selection when that verb is invoked. +win10 tests: + if (the number of selected file/dir objects > 16) + { + Explorer does the following actions: + - it creates ctx_menu_1 IContextMenu object + - it calls ctx_menu_1->Initialize() with list of only up to 16 items + - it calls ctx_menu_1->QueryContextMenu(menu_1) + - if (some menu command is pressed) + { + - it gets shown string from selected menu item : shown_menu_1_string + - it creates another ctx_menu_2 IContextMenu object + - it calls ctx_menu_2->Initialize() with list of all items + - it calls ctx_menu_2->QueryContextMenu(menu_2) + - if there is menu item with shown_menu_1_string string in menu_2, + Explorer calls ctx_menu_2->InvokeCommand() for that item. + Explorer probably doesn't use VERB from first object ctx_menu_1. + So we must provide same shown menu strings for both objects: + ctx_menu_1 and ctx_menu_2. + } + } +*/ + + +CZipContextMenu::CZipContextMenu(): + _isMenuForFM(true), + _fileNames_WereReduced(true), + _dropMode(false), + _bitmap(NULL), + _writeZone((UInt32)(Int32)-1), + IsSeparator(false), + IsRoot(true), + CurrentSubCommand(0) +{ + ODS("== CZipContextMenu()"); + InterlockedIncrement(&g_DllRefCount); +} + +CZipContextMenu::~CZipContextMenu() +{ + ODS("== ~CZipContextMenu"); + if (_bitmap) + DeleteObject(_bitmap); + InterlockedDecrement(&g_DllRefCount); +} + +// IShellExtInit + +/* +IShellExtInit::Initialize() + pidlFolder: + - for property sheet extension: + NULL + - for shortcut menu extensions: + pidl of folder that contains the item whose shortcut menu is being displayed: + - for nondefault drag-and-drop menu extensions: + pidl of target folder: for nondefault drag-and-drop menu extensions + pidlFolder == NULL in (win10): for context menu +*/ + +Z7_COMWF_B CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY /* hkeyProgID */) +{ + COM_TRY_BEGIN + ODS("==== CZipContextMenu::Initialize START") + _isMenuForFM = false; + _fileNames_WereReduced = true; + _dropMode = false; + _attribs.Clear(); + _fileNames.Clear(); + _dropPath.Empty(); + + if (pidlFolder) + { + ODS("==== CZipContextMenu::Initialize (pidlFolder != 0)") + #ifndef UNDER_CE + if (NShell::GetPathFromIDList(pidlFolder, _dropPath)) + { + ODS("==== CZipContextMenu::Initialize path from (pidl):") + ODS_U(_dropPath); + /* win10 : path with "\\\\?\\\" prefix is returned by GetPathFromIDList, if path is long + we can remove super prefix here. But probably prefix + is not problem for following 7-zip code. + so we don't remove super prefix */ + NFile::NName::If_IsSuperPath_RemoveSuperPrefix(_dropPath); + NName::NormalizeDirPathPrefix(_dropPath); + _dropMode = !_dropPath.IsEmpty(); + } + else + #endif + _dropPath.Empty(); + } + + if (!dataObject) + return E_INVALIDARG; + + #ifndef UNDER_CE + + RINOK(NShell::DataObject_GetData_HDROP_or_IDLIST_Names(dataObject, _fileNames)) + // for (unsigned y = 0; y < 10000; y++) + if (NShell::DataObject_GetData_FILE_ATTRS(dataObject, _attribs) != S_OK) + _attribs.Clear(); + + #endif + + ODS_SPRF_s(sprintf(s, "==== CZipContextMenu::Initialize END _files=%d", + _fileNames.Size())) + + return S_OK; + COM_TRY_END +} + + +///////////////////////////// +// IContextMenu + +static LPCSTR const kMainVerb = "SevenZip"; +static LPCSTR const kOpenCascadedVerb = "SevenZip.OpenWithType."; +static LPCSTR const kCheckSumCascadedVerb = "SevenZip.Checksum"; + + +struct CContextMenuCommand +{ + UInt32 flag; + CZipContextMenu::enum_CommandInternalID CommandInternalID; + LPCSTR Verb; + UINT ResourceID; +}; + +#define CMD_REC(cns, verb, ids) { NContextMenuFlags::cns, CZipContextMenu::cns, verb, ids } + +static const CContextMenuCommand g_Commands[] = +{ + CMD_REC( kOpen, "Open", IDS_CONTEXT_OPEN), + CMD_REC( kExtract, "Extract", IDS_CONTEXT_EXTRACT), + CMD_REC( kExtractHere, "ExtractHere", IDS_CONTEXT_EXTRACT_HERE), + CMD_REC( kExtractTo, "ExtractTo", IDS_CONTEXT_EXTRACT_TO), + CMD_REC( kTest, "Test", IDS_CONTEXT_TEST), + CMD_REC( kCompress, "Compress", IDS_CONTEXT_COMPRESS), + CMD_REC( kCompressEmail, "CompressEmail", IDS_CONTEXT_COMPRESS_EMAIL), + CMD_REC( kCompressTo7z, "CompressTo7z", IDS_CONTEXT_COMPRESS_TO), + CMD_REC( kCompressTo7zEmail, "CompressTo7zEmail", IDS_CONTEXT_COMPRESS_TO_EMAIL), + CMD_REC( kCompressToZip, "CompressToZip", IDS_CONTEXT_COMPRESS_TO), + CMD_REC( kCompressToZipEmail, "CompressToZipEmail", IDS_CONTEXT_COMPRESS_TO_EMAIL) +}; + + +struct CHashCommand +{ + CZipContextMenu::enum_CommandInternalID CommandInternalID; + LPCSTR UserName; + LPCSTR MethodName; +}; + +static const CHashCommand g_HashCommands[] = +{ + { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" }, + { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" }, + { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" }, + { CZipContextMenu::kHash_MD5, "MD5", "MD5" }, + { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" }, + { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" }, + { CZipContextMenu::kHash_SHA384, "SHA-384", "SHA384" }, + { CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" }, + { CZipContextMenu::kHash_SHA3_256, "SHA3-256", "SHA3-256" }, + { CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" }, + { CZipContextMenu::kHash_All, "*", "*" }, + { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" }, + { CZipContextMenu::kHash_TestArc, "Checksum : Test", "Hash" } +}; + + +static int FindCommand(CZipContextMenu::enum_CommandInternalID &id) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Commands); i++) + if (g_Commands[i].CommandInternalID == id) + return (int)i; + return -1; +} + + +void CZipContextMenu::FillCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) const +{ + mainString.Empty(); + const int i = FindCommand(id); + if (i < 0) + throw 201908; + const CContextMenuCommand &command = g_Commands[(unsigned)i]; + cmi.CommandInternalID = command.CommandInternalID; + cmi.Verb = kMainVerb; + cmi.Verb += command.Verb; + // cmi.HelpString = cmi.Verb; + LangString(command.ResourceID, mainString); + cmi.UserString = mainString; +} + + +static UString LangStringAlt(UInt32 id, const char *altString) +{ + UString s = LangString(id); + if (s.IsEmpty()) + s = altString; + return s; +} + + +void CZipContextMenu::AddCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) +{ + FillCommand(id, mainString, cmi); + _commandMap.Add(cmi); +} + + + +/* +note: old msdn article: +Duplicate Menu Items In the File Menu For a Shell Context Menu Extension (214477) +---------- + On systems with Shell32.dll version 4.71 or higher, a context menu extension + for a file folder that inserts one or more pop-up menus results in duplicates + of these menu items. + This occurs when the file menu is activated more than once for the selected object. + +CAUSE + In a context menu extension, if pop-up menus are inserted using InsertMenu + or AppendMenu, then the ID for the pop-up menu item cannot be specified. + Instead, this field should take in the HMENU of the pop-up menu. + Because the ID is not specified for the pop-up menu item, the Shell does + not keep track of the menu item if the file menu is pulled down multiple times. + As a result, the pop-up menu items are added multiple times in the context menu. + + This problem occurs only when the file menu is pulled down, and does not happen + when the context menu is invoked by using the right button or the context menu key. +RESOLUTION + To work around this problem, use InsertMenuItem and specify the ID of the + pop-up menu item in the wID member of the MENUITEMINFO structure. +*/ + +static void MyInsertMenu(CMenu &menu, unsigned pos, UINT id, const UString &s, HBITMAP bitmap) +{ + if (!menu) + return; + CMenuItem mi; + mi.fType = MFT_STRING; + mi.fMask = MIIM_TYPE | MIIM_ID; + if (bitmap) + mi.fMask |= MIIM_CHECKMARKS; + mi.wID = id; + mi.StringValue = s; + mi.hbmpUnchecked = bitmap; + // mi.hbmpChecked = bitmap; // do we need hbmpChecked ??? + if (!menu.InsertItem(pos, true, mi)) + throw 20190816; + + // SetMenuItemBitmaps also works + // ::SetMenuItemBitmaps(menu, pos, MF_BYPOSITION, bitmap, NULL); +} + + +static void MyAddSubMenu( + CObjectVector &_commandMap, + const char *verb, + CMenu &menu, unsigned pos, UINT id, const UString &s, HMENU hSubMenu, HBITMAP bitmap) +{ + CZipContextMenu::CCommandMapItem cmi; + cmi.CommandInternalID = CZipContextMenu::kCommandNULL; + cmi.Verb = verb; + cmi.IsPopup = true; + // cmi.HelpString = verb; + cmi.UserString = s; + _commandMap.Add(cmi); + + if (!menu) + return; + + CMenuItem mi; + mi.fType = MFT_STRING; + mi.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + if (bitmap) + mi.fMask |= MIIM_CHECKMARKS; + mi.wID = id; + mi.hSubMenu = hSubMenu; + mi.hbmpUnchecked = bitmap; + + mi.StringValue = s; + if (!menu.InsertItem(pos, true, mi)) + throw 20190817; +} + + +static const char * const kArcExts[] = +{ + "7z" + , "bz2" + , "gz" + , "rar" + , "zip" +}; + +static bool IsItArcExt(const UString &ext) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kArcExts); i++) + if (ext.IsEqualTo_Ascii_NoCase(kArcExts[i])) + return true; + return false; +} + +UString GetSubFolderNameForExtract(const UString &arcName); +UString GetSubFolderNameForExtract(const UString &arcName) +{ + int dotPos = arcName.ReverseFind_Dot(); + if (dotPos < 0) + return Get_Correct_FsFile_Name(arcName) + L'~'; + + const UString ext = arcName.Ptr(dotPos + 1); + UString res = arcName.Left(dotPos); + res.TrimRight(); + dotPos = res.ReverseFind_Dot(); + if (dotPos > 0) + { + const UString ext2 = res.Ptr(dotPos + 1); + if ((ext.IsEqualTo_Ascii_NoCase("001") && IsItArcExt(ext2)) + || (ext.IsEqualTo_Ascii_NoCase("rar") && + ( ext2.IsEqualTo_Ascii_NoCase("part001") + || ext2.IsEqualTo_Ascii_NoCase("part01") + || ext2.IsEqualTo_Ascii_NoCase("part1")))) + res.DeleteFrom(dotPos); + res.TrimRight(); + } + return Get_Correct_FsFile_Name(res); +} + +static void ReduceString(UString &s) +{ + const unsigned kMaxSize = 64; + if (s.Len() <= kMaxSize) + return; + s.Delete(kMaxSize / 2, s.Len() - kMaxSize); + s.Insert(kMaxSize / 2, L" ... "); +} + +static UString GetQuotedReducedString(const UString &s) +{ + UString s2 = s; + ReduceString(s2); + s2.Replace(L"&", L"&&"); + return GetQuotedString(s2); +} + +static void MyFormatNew_ReducedName(UString &s, const UString &name) +{ + s = MyFormatNew(s, GetQuotedReducedString(name)); +} + +static const char * const kExtractExcludeExtensions = + " 3gp" + " aac ans ape asc asm asp aspx avi awk" + " bas bat bmp" + " c cs cls clw cmd cpp csproj css ctl cxx" + " def dep dlg dsp dsw" + " eps" + " f f77 f90 f95 fla flac frm" + " gif" + " h hpp hta htm html hxx" + " ico idl inc ini inl" + " java jpeg jpg js" + " la lnk log" + " mak manifest wmv mov mp3 mp4 mpe mpeg mpg m4a" + " ofr ogg" + " pac pas pdf php php3 php4 php5 phptml pl pm png ps py pyo" + " ra rb rc reg rka rm rtf" + " sed sh shn shtml sln sql srt swa" + " tcl tex tiff tta txt" + " vb vcproj vbs" + " mkv wav webm wma wv" + " xml xsd xsl xslt" + " "; + +/* +static const char * const kNoOpenAsExtensions = + " 7z arj bz2 cab chm cpio flv gz lha lzh lzma rar swm tar tbz2 tgz wim xar xz z zip "; +*/ + +static const char * const kOpenTypes[] = +{ + "" + , "*" + , "#" + , "#:e" + // , "#:a" + , "7z" + , "zip" + , "cab" + , "rar" +}; + + +bool FindExt(const char *p, const UString &name, CStringFinder &finder); +bool FindExt(const char *p, const UString &name, CStringFinder &finder) +{ + const int dotPos = name.ReverseFind_Dot(); + int len = (int)name.Len() - (dotPos + 1); + if (len == 0 || len > 32 || dotPos < 0) + return false; + return finder.FindWord_In_LowCaseAsciiList_NoCase(p, name.Ptr(dotPos + 1)); +} + +/* returns false, if extraction of that file extension is not expected */ +static bool DoNeedExtract(const UString &name, CStringFinder &finder) +{ + // for (int y = 0; y < 1000; y++) FindExt(kExtractExcludeExtensions, name); + return !FindExt(kExtractExcludeExtensions, name, finder); +} + +// we must use diferent Verbs for Popup subMenu. +void CZipContextMenu::AddMapItem_ForSubMenu(const char *verb) +{ + CCommandMapItem cmi; + cmi.CommandInternalID = kCommandNULL; + cmi.Verb = verb; + // cmi.HelpString = verb; + _commandMap.Add(cmi); +} + + +static HRESULT RETURN_WIN32_LastError_AS_HRESULT() +{ + DWORD lastError = ::GetLastError(); + if (lastError == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(lastError); +} + + +/* + we add CCommandMapItem to _commandMap for each new Menu ID. + so then we use _commandMap[offset]. + That way we can execute commands that have menu item. + Another non-implemented way: + We can return the number off all possible commands in QueryContextMenu(). + so the caller could call InvokeCommand() via string verb even + without using menu items. +*/ + + +Z7_COMWF_B CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, + UINT commandIDFirst, UINT commandIDLast, UINT flags) +{ + ODS("+ QueryContextMenu()") + COM_TRY_BEGIN + try { + + _commandMap.Clear(); + + ODS_SPRF_s(sprintf(s, "QueryContextMenu: index=%u first=%u last=%u flags=%x _files=%u", + indexMenu, commandIDFirst, commandIDLast, flags, _fileNames.Size())) + /* + for (UInt32 i = 0; i < _fileNames.Size(); i++) + { + ODS_U(_fileNames[i]) + } + */ + + #define MAKE_HRESULT_SUCCESS_FAC0(code) (HRESULT)(code) + + if (_fileNames.Size() == 0) + { + return MAKE_HRESULT_SUCCESS_FAC0(0); + // return E_INVALIDARG; + } + + if (commandIDFirst > commandIDLast) + return E_INVALIDARG; + + UINT currentCommandID = commandIDFirst; + + if ((flags & 0x000F) != CMF_NORMAL + && (flags & CMF_VERBSONLY) == 0 + && (flags & CMF_EXPLORE) == 0) + return MAKE_HRESULT_SUCCESS_FAC0(currentCommandID - commandIDFirst); + // return MAKE_HRESULT_SUCCESS_FAC0(currentCommandID); + // 19.01 : we changed from (currentCommandID) to (currentCommandID - commandIDFirst) + // why it was so before? + +#ifdef Z7_LANG + LoadLangOneTime(); +#endif + + CMenu popupMenu; + CMenuDestroyer menuDestroyer; + + ODS("### 40") + CContextMenuInfo ci; + ci.Load(); + ODS("### 44") + + _elimDup = ci.ElimDup; + _writeZone = ci.WriteZone; + + HBITMAP bitmap = NULL; + if (ci.MenuIcons.Val) + { + ODS("### 45") + if (!_bitmap) + _bitmap = ::LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_MENU_LOGO)); + bitmap = _bitmap; + } + + UINT subIndex = indexMenu; + + ODS("### 50") + + if (ci.Cascaded.Val) + { + if (hMenu) + if (!popupMenu.CreatePopup()) + return RETURN_WIN32_LastError_AS_HRESULT(); + menuDestroyer.Attach(popupMenu); + + /* 9.31: we commented the following code. Probably we don't need. + Check more systems. Maybe it was for old Windows? */ + /* + AddMapItem_ForSubMenu(); + currentCommandID++; + */ + subIndex = 0; + } + else + { + popupMenu.Attach(hMenu); + CMenuItem mi; + mi.fType = MFT_SEPARATOR; + mi.fMask = MIIM_TYPE; + if (hMenu) + popupMenu.InsertItem(subIndex++, true, mi); + } + + const UInt32 contextMenuFlags = ci.Flags; + + NFind::CFileInfo fi0; + FString folderPrefix; + + if (_fileNames.Size() > 0) + { + const UString &fileName = _fileNames.Front(); + + #if defined(_WIN32) && !defined(UNDER_CE) + if (NName::IsDevicePath(us2fs(fileName))) + { + // CFileInfo::Find can be slow for device files. So we don't call it. + // we need only name here. + fi0.Name = us2fs(fileName.Ptr(NName::kDevicePathPrefixSize)); + folderPrefix = + #ifdef UNDER_CE + "\\"; + #else + "C:\\"; + #endif + } + else + #endif + { + if (!fi0.Find(us2fs(fileName))) + { + throw 20190820; + // return RETURN_WIN32_LastError_AS_HRESULT(); + } + GetOnlyDirPrefix(us2fs(fileName), folderPrefix); + } + } + + ODS("### 100") + + UString mainString; + CStringFinder finder; + UStringVector fileNames_Reduced; + const unsigned k_Explorer_NumReducedItems = 16; + const bool needReduce = !_isMenuForFM && (_fileNames.Size() >= k_Explorer_NumReducedItems); + _fileNames_WereReduced = needReduce; + // _fileNames_WereReduced = true; // for debug; + const UStringVector *fileNames = &_fileNames; + if (needReduce) + { + for (unsigned i = 0; i < k_Explorer_NumReducedItems + && i < _fileNames.Size(); i++) + fileNames_Reduced.Add(_fileNames[i]); + fileNames = &fileNames_Reduced; + } + + /* + if (_fileNames.Size() == k_Explorer_NumReducedItems) // for debug + { + for (int i = 0; i < 10; i++) + { + CCommandMapItem cmi; + AddCommand(kCompressToZipEmail, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + } + */ + + if (_fileNames.Size() == 1 && currentCommandID + 14 <= commandIDLast) + { + if (!fi0.IsDir() && DoNeedExtract(fs2us(fi0.Name), finder)) + { + // Open + const bool thereIsMainOpenItem = ((contextMenuFlags & NContextMenuFlags::kOpen) != 0); + if (thereIsMainOpenItem) + { + CCommandMapItem cmi; + AddCommand(kOpen, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + if ((contextMenuFlags & NContextMenuFlags::kOpenAs) != 0 + // && (!thereIsMainOpenItem || !FindExt(kNoOpenAsExtensions, fi0.Name)) + && hMenu // we want to reduce number of menu items below 16 + ) + { + CMenu subMenu; + if (!hMenu || subMenu.CreatePopup()) + { + MyAddSubMenu(_commandMap, kOpenCascadedVerb, popupMenu, subIndex++, currentCommandID++, LangString(IDS_CONTEXT_OPEN), subMenu, bitmap); + _commandMap.Back().CtxCommandType = CtxCommandType_OpenRoot; + + UINT subIndex2 = 0; + for (unsigned i = (thereIsMainOpenItem ? 1 : 0); i < Z7_ARRAY_SIZE(kOpenTypes); i++) + { + CCommandMapItem cmi; + if (i == 0) + FillCommand(kOpen, mainString, cmi); + else + { + mainString = kOpenTypes[i]; + cmi.CommandInternalID = kOpen; + cmi.Verb = kMainVerb; + cmi.Verb += ".Open."; + cmi.Verb += mainString; + // cmi.HelpString = cmi.Verb; + cmi.ArcType = mainString; + cmi.CtxCommandType = CtxCommandType_OpenChild; + } + _commandMap.Add(cmi); + Set_UserString_in_LastCommand(mainString); + MyInsertMenu(subMenu, subIndex2++, currentCommandID++, mainString, bitmap); + } + + subMenu.Detach(); + } + } + } + } + + ODS("### 150") + + if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) + { + ODS("### needExtract list START") + const bool needExtendedVerbs = ((flags & Z7_WIN_CMF_EXTENDEDVERBS) != 0); + // || _isMenuForFM; + bool needExtract = true; + bool areDirs = fi0.IsDir() || (unsigned)_attribs.FirstDirIndex < k_Explorer_NumReducedItems; + if (!needReduce) + areDirs = areDirs || (_attribs.FirstDirIndex != -1); + if (areDirs) + needExtract = false; + + if (!needExtendedVerbs) + if (needExtract) + { + UString name; + const unsigned numItemsCheck = fileNames->Size(); + for (unsigned i = 0; i < numItemsCheck; i++) + { + const UString &a = (*fileNames)[i]; + const int slash = a.ReverseFind_PathSepar(); + name = a.Ptr(slash + 1); + // for (int y = 0; y < 600; y++) // for debug + const bool needExtr2 = DoNeedExtract(name, finder); + if (!needExtr2) + { + needExtract = needExtr2; + break; + } + } + } + ODS("### needExtract list END") + + if (needExtract) + { + { + UString baseFolder = fs2us(folderPrefix); + if (_dropMode) + baseFolder = _dropPath; + + UString specFolder ('*'); + if (_fileNames.Size() == 1) + specFolder = GetSubFolderNameForExtract(fs2us(fi0.Name)); + specFolder.Add_PathSepar(); + + if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0) + { + // Extract + CCommandMapItem cmi; + cmi.Folder = baseFolder + specFolder; + AddCommand(kExtract, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + + if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0) + { + // Extract Here + CCommandMapItem cmi; + cmi.Folder = baseFolder; + AddCommand(kExtractHere, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + + if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0) + { + // Extract To + CCommandMapItem cmi; + UString s; + cmi.Folder = baseFolder + specFolder; + AddCommand(kExtractTo, s, cmi); + MyFormatNew_ReducedName(s, specFolder); + Set_UserString_in_LastCommand(s); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); + } + } + + if ((contextMenuFlags & NContextMenuFlags::kTest) != 0) + { + // Test + CCommandMapItem cmi; + AddCommand(kTest, mainString, cmi); + // if (_fileNames.Size() == 16) mainString += "_[16]"; // for debug + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + } + + ODS("### CreateArchiveName START") + UString arcName_base; + const UString arcName = CreateArchiveName( + *fileNames, + false, // isHash + fileNames->Size() == 1 ? &fi0 : NULL, + arcName_base); + ODS("### CreateArchiveName END") + UString arcName_Show = arcName; + if (needReduce) + { + /* we need same arcName_Show for two calls from Explorer: + 1) reduced call (only first 16 items) + 2) full call with all items (can be >= 16 items) + (fileNames) array was reduced to 16 items. + So we will have same (arcName) in both reduced and full calls. + If caller (Explorer) uses (reduce_to_first_16_items) scheme, + we can use (arcName) here instead of (arcName_base). + (arcName_base) has no number in name. + */ + arcName_Show = arcName_base; // we can comment that line + /* we use "_" in archive name as sign to user + that shows that final archive name can be changed. */ + arcName_Show += "_"; + } + + UString arcName_7z = arcName; + arcName_7z += ".7z"; + UString arcName_7z_Show = arcName_Show; + arcName_7z_Show += ".7z"; + UString arcName_zip = arcName; + arcName_zip += ".zip"; + UString arcName_zip_Show = arcName_Show; + arcName_zip_Show += ".zip"; + + + // Compress + if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0) + { + CCommandMapItem cmi; + if (_dropMode) + cmi.Folder = _dropPath; + else + cmi.Folder = fs2us(folderPrefix); + cmi.ArcName = arcName; + AddCommand(kCompress, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + + #ifdef EMAIL_SUPPORT + // CompressEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode) + { + CCommandMapItem cmi; + cmi.ArcName = arcName; + AddCommand(kCompressEmail, mainString, cmi); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString, bitmap); + } + #endif + + // CompressTo7z + if (contextMenuFlags & NContextMenuFlags::kCompressTo7z && + !arcName_7z.IsEqualTo_NoCase(fs2us(fi0.Name))) + { + CCommandMapItem cmi; + UString s; + if (_dropMode) + cmi.Folder = _dropPath; + else + cmi.Folder = fs2us(folderPrefix); + cmi.ArcName = arcName_7z; + cmi.ArcType = "7z"; + AddCommand(kCompressTo7z, s, cmi); + MyFormatNew_ReducedName(s, arcName_7z_Show); + Set_UserString_in_LastCommand(s); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); + } + + #ifdef EMAIL_SUPPORT + // CompressTo7zEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode) + { + CCommandMapItem cmi; + UString s; + cmi.ArcName = arcName_7z; + cmi.ArcType = "7z"; + AddCommand(kCompressTo7zEmail, s, cmi); + MyFormatNew_ReducedName(s, arcName_7z_Show); + Set_UserString_in_LastCommand(s); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); + } + #endif + + // CompressToZip + if (contextMenuFlags & NContextMenuFlags::kCompressToZip && + !arcName_zip.IsEqualTo_NoCase(fs2us(fi0.Name))) + { + CCommandMapItem cmi; + UString s; + if (_dropMode) + cmi.Folder = _dropPath; + else + cmi.Folder = fs2us(folderPrefix); + cmi.ArcName = arcName_zip; + cmi.ArcType = "zip"; + AddCommand(kCompressToZip, s, cmi); + MyFormatNew_ReducedName(s, arcName_zip_Show); + Set_UserString_in_LastCommand(s); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); + } + + #ifdef EMAIL_SUPPORT + // CompressToZipEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode) + { + CCommandMapItem cmi; + UString s; + cmi.ArcName = arcName_zip; + cmi.ArcType = "zip"; + AddCommand(kCompressToZipEmail, s, cmi); + MyFormatNew_ReducedName(s, arcName_zip_Show); + Set_UserString_in_LastCommand(s); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s, bitmap); + } + #endif + } + + ODS("### 300") + + // don't use InsertMenu: See MSDN: + // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension + // ID: Q214477 + + if (ci.Cascaded.Val) + { + CMenu menu; + menu.Attach(hMenu); + menuDestroyer.Disable(); + MyAddSubMenu(_commandMap, kMainVerb, menu, indexMenu++, currentCommandID++, (UString)"7-Zip", + popupMenu, // popupMenu.Detach(), + bitmap); + } + else + { + // popupMenu.Detach(); + indexMenu = subIndex; + } + + ODS("### 350") + + const bool needCrc = ((contextMenuFlags & + (NContextMenuFlags::kCRC | + NContextMenuFlags::kCRC_Cascaded)) != 0); + + if ( + // !_isMenuForFM && // 21.04: we don't hide CRC SHA menu in 7-Zip FM + needCrc + && currentCommandID + 1 < commandIDLast) + { + CMenu subMenu; + // CMenuDestroyer menuDestroyer_CRC; + + UINT subIndex_CRC = 0; + + if (!hMenu || subMenu.CreatePopup()) + { + // menuDestroyer_CRC.Attach(subMenu); + const bool insertHashMenuTo7zipMenu = (ci.Cascaded.Val + && (contextMenuFlags & NContextMenuFlags::kCRC_Cascaded) != 0); + + CMenu menu; + { + unsigned indexInParent; + if (insertHashMenuTo7zipMenu) + { + indexInParent = subIndex; + menu.Attach(popupMenu); + } + else + { + indexInParent = indexMenu; + menu.Attach(hMenu); + // menuDestroyer_CRC.Disable(); + } + MyAddSubMenu(_commandMap, kCheckSumCascadedVerb, menu, indexInParent++, currentCommandID++, (UString)"CRC SHA", subMenu, + /* insertHashMenuTo7zipMenu ? NULL : */ bitmap); + _commandMap.Back().CtxCommandType = CtxCommandType_CrcRoot; + if (!insertHashMenuTo7zipMenu) + indexMenu = indexInParent; + } + + ODS("### HashCommands") + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_HashCommands); i++) + { + if (currentCommandID >= commandIDLast) + break; + const CHashCommand &hc = g_HashCommands[i]; + CCommandMapItem cmi; + cmi.CommandInternalID = hc.CommandInternalID; + cmi.Verb = kCheckSumCascadedVerb; + cmi.Verb.Add_Dot(); + UString s; + s += hc.UserName; + + if (hc.CommandInternalID == kHash_Generate_SHA256) + { + cmi.Verb += "Generate"; + { + popupMenu.Attach(hMenu); + CMenuItem mi; + mi.fType = MFT_SEPARATOR; + mi.fMask = MIIM_TYPE; + subMenu.InsertItem(subIndex_CRC++, true, mi); + } + + UString name; + UString showName; + ODS("### Hash CreateArchiveName Start") + // for (int y = 0; y < 10000; y++) // for debug + // if (fileNames->Size() == 1) name = fs2us(fi0.Name); else + name = CreateArchiveName( + *fileNames, + true, // isHash + fileNames->Size() == 1 ? &fi0 : NULL, + showName); + if (needReduce) + showName += "_"; + else + showName = name; + + ODS("### Hash CreateArchiveName END") + name += ".sha256"; + showName += ".sha256"; + cmi.Folder = fs2us(folderPrefix); + cmi.ArcName = name; + s = "SHA-256 -> "; + s += showName; + } + else if (hc.CommandInternalID == kHash_TestArc) + { + cmi.Verb += "Test"; + s = LangStringAlt(IDS_CONTEXT_TEST, "Test archive"); + s += " : "; + s += GetNameOfProperty(kpidChecksum, UString("Checksum")); + } + else + cmi.Verb += "Calc"; + + cmi.Verb.Add_Dot(); + cmi.Verb += hc.MethodName; + + // cmi.HelpString = cmi.Verb; + cmi.UserString = s; + cmi.CtxCommandType = CtxCommandType_CrcChild; + _commandMap.Add(cmi); + MyInsertMenu(subMenu, subIndex_CRC++, currentCommandID++, s, bitmap); + ODS("### 380") + } + + subMenu.Detach(); + } + } + + popupMenu.Detach(); + /* + if (!ci.Cascaded.Val) + indexMenu = subIndex; + */ + const unsigned numCommands = currentCommandID - commandIDFirst; + ODS("+ QueryContextMenu() END") + ODS_SPRF_s(sprintf(s, "Commands=%u currentCommandID - commandIDFirst = %u", + _commandMap.Size(), numCommands)) + if (_commandMap.Size() != numCommands) + throw 20190818; + /* + FOR_VECTOR (k, _commandMap) + { + ODS_U(_commandMap[k].Verb); + } + */ + } + catch(...) + { + ODS_SPRF_s(sprintf(s, "catch() exception: Commands=%u", _commandMap.Size())) + if (_commandMap.Size() == 0) + throw; + } + /* we added some menu items already : num_added_menu_items, + So we MUST return (number_of_defined_ids), where (number_of_defined_ids >= num_added_menu_items) + This will prevent incorrect menu working, when same IDs can be + assigned in multiple menu items from different subhandlers. + And we must add items to _commandMap before adding to menu. + */ + return MAKE_HRESULT_SUCCESS_FAC0(_commandMap.Size()); + COM_TRY_END +} + + +int CZipContextMenu::FindVerb(const UString &verb) const +{ + FOR_VECTOR (i, _commandMap) + if (_commandMap[i].Verb == verb) + return (int)i; + return -1; +} + +static UString Get7zFmPath() +{ + return fs2us(NWindows::NDLL::GetModuleDirPrefix()) + L"7zFM.exe"; +} + + +Z7_COMWF_B CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) +{ + COM_TRY_BEGIN + + ODS("==== CZipContextMenu::InvokeCommand()") + + #ifdef SHOW_DEBUG_CTX_MENU + + ODS_SPRF_s(sprintf(s, ": InvokeCommand: cbSize=%u flags=%x ", + (unsigned)commandInfo->cbSize, (unsigned)commandInfo->fMask)) + + PrintStringA("Verb", commandInfo->lpVerb); + PrintStringA("Parameters", commandInfo->lpParameters); + PrintStringA("Directory", commandInfo->lpDirectory); + #endif + + int commandOffset = -1; + + // xp64 / Win10 : explorer.exe sends 0 in lpVerbW + // MSDN: if (IS_INTRESOURCE(lpVerbW)), we must use LOWORD(lpVerb) as command offset + + // FIXME: old MINGW doesn't define CMINVOKECOMMANDINFOEX / CMIC_MASK_UNICODE + #if !defined(UNDER_CE) && defined(CMIC_MASK_UNICODE) + bool unicodeVerb = false; + if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && + (commandInfo->fMask & CMIC_MASK_UNICODE) != 0) + { + LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo; + if (!MY_IS_INTRESOURCE(commandInfoEx->lpVerbW)) + { + unicodeVerb = true; + commandOffset = FindVerb(commandInfoEx->lpVerbW); + } + + #ifdef SHOW_DEBUG_CTX_MENU + PrintStringW("VerbW", commandInfoEx->lpVerbW); + PrintStringW("ParametersW", commandInfoEx->lpParametersW); + PrintStringW("DirectoryW", commandInfoEx->lpDirectoryW); + PrintStringW("TitleW", commandInfoEx->lpTitleW); + PrintStringA("Title", commandInfoEx->lpTitle); + #endif + } + if (!unicodeVerb) + #endif + { + ODS("use non-UNICODE verb") + // if (HIWORD(commandInfo->lpVerb) == 0) + if (MY_IS_INTRESOURCE(commandInfo->lpVerb)) + commandOffset = LOWORD(commandInfo->lpVerb); + else + commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb)); + } + + ODS_SPRF_s(sprintf(s, "commandOffset=%d", commandOffset)) + + if (/* commandOffset < 0 || */ (unsigned)commandOffset >= _commandMap.Size()) + return E_INVALIDARG; + const CCommandMapItem &cmi = _commandMap[(unsigned)commandOffset]; + return InvokeCommandCommon(cmi); + COM_TRY_END +} + + +HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi) +{ + const enum_CommandInternalID cmdID = cmi.CommandInternalID; + + try + { + switch (cmdID) + { + case kOpen: + { + UString params; + params = GetQuotedString(_fileNames[0]); + if (!cmi.ArcType.IsEmpty()) + { + params += " -t"; + params += cmi.ArcType; + } + MyCreateProcess(Get7zFmPath(), params); + break; + } + case kExtract: + case kExtractHere: + case kExtractTo: + { + if (_attribs.FirstDirIndex != -1) + { + ShowErrorMessageRes(IDS_SELECT_FILES); + break; + } + ExtractArchives(_fileNames, cmi.Folder, + (cmdID == kExtract), // showDialog + (cmdID == kExtractTo) && _elimDup.Val, // elimDup + _writeZone + ); + break; + } + case kTest: + { + TestArchives(_fileNames); + break; + } + case kCompress: + case kCompressEmail: + case kCompressTo7z: + case kCompressTo7zEmail: + case kCompressToZip: + case kCompressToZipEmail: + { + UString arcName = cmi.ArcName; + if (_fileNames_WereReduced) + { + UString arcName_base; + arcName = CreateArchiveName( + _fileNames, + false, // isHash + NULL, // fi0 + arcName_base); + const char *postfix = NULL; + if (cmdID == kCompressTo7z || + cmdID == kCompressTo7zEmail) + postfix = ".7z"; + else if ( + cmdID == kCompressToZip || + cmdID == kCompressToZipEmail) + postfix = ".zip"; + if (postfix) + arcName += postfix; + } + + const bool email = + cmdID == kCompressEmail || + cmdID == kCompressTo7zEmail || + cmdID == kCompressToZipEmail; + const bool showDialog = + cmdID == kCompress || + cmdID == kCompressEmail; + const bool addExtension = showDialog; + CompressFiles(cmi.Folder, + arcName, cmi.ArcType, + addExtension, + _fileNames, email, showDialog, + false // waitFinish + ); + break; + } + + case kHash_CRC32: + case kHash_CRC64: + case kHash_XXH64: + case kHash_MD5: + case kHash_SHA1: + case kHash_SHA256: + case kHash_SHA384: + case kHash_SHA512: + case kHash_SHA3_256: + case kHash_BLAKE2SP: + case kHash_All: + case kHash_Generate_SHA256: + case kHash_TestArc: + { + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_HashCommands); i++) + { + const CHashCommand &hc = g_HashCommands[i]; + if (hc.CommandInternalID == cmdID) + { + if (cmdID == kHash_TestArc) + { + TestArchives(_fileNames, true); // hashMode + break; + } + UString generateName; + if (cmdID == kHash_Generate_SHA256) + { + generateName = cmi.ArcName; + if (_fileNames_WereReduced) + { + UString arcName_base; + generateName = CreateArchiveName(_fileNames, + true, // isHash + NULL, // fi0 + arcName_base); + generateName += ".sha256"; + } + } + CalcChecksum(_fileNames, (UString)hc.MethodName, + cmi.Folder, generateName); + break; + } + } + break; + } + case kCommandNULL: + break; + } + } + catch(...) + { + ShowErrorMessage(NULL, L"Error"); + } + return S_OK; +} + + + +static void MyCopyString_isUnicode(void *dest, UINT size, const UString &src, bool writeInUnicode) +{ + if (size != 0) + size--; + if (writeInUnicode) + { + UString s = src; + s.DeleteFrom(size); + MyStringCopy((wchar_t *)dest, s); + ODS_U(s) + } + else + { + AString s = GetAnsiString(src); + s.DeleteFrom(size); + MyStringCopy((char *)dest, s); + } +} + + +Z7_COMWF_B CZipContextMenu::GetCommandString( + #ifdef Z7_OLD_WIN_SDK + UINT + #else + UINT_PTR + #endif + commandOffset, + UINT uType, + UINT * /* pwReserved */ , LPSTR pszName, UINT cchMax) +{ + COM_TRY_BEGIN + + ODS("GetCommandString") + + const int cmdOffset = (int)commandOffset; + + ODS_SPRF_s(sprintf(s, "GetCommandString: cmdOffset=%d uType=%d cchMax = %d", + cmdOffset, uType, cchMax)) + + if ((uType | GCS_UNICODE) == GCS_VALIDATEW) + { + if (/* cmdOffset < 0 || */ (unsigned)cmdOffset >= _commandMap.Size()) + return S_FALSE; + return S_OK; + } + + if (/* cmdOffset < 0 || */ (unsigned)cmdOffset >= _commandMap.Size()) + { + ODS("------ cmdOffset: E_INVALIDARG") + return E_INVALIDARG; + } + + // we use Verb as HelpString + if (cchMax != 0) + if ((uType | GCS_UNICODE) == GCS_VERBW || + (uType | GCS_UNICODE) == GCS_HELPTEXTW) + { + const CCommandMapItem &cmi = _commandMap[(unsigned)cmdOffset]; + MyCopyString_isUnicode(pszName, cchMax, cmi.Verb, (uType & GCS_UNICODE) != 0); + return S_OK; + } + + return E_INVALIDARG; + + COM_TRY_END +} + + + +// ---------- IExplorerCommand ---------- + +static HRESULT WINAPI My_SHStrDupW(LPCWSTR src, LPWSTR *dest) +{ + if (src) + { + const SIZE_T size = (wcslen(src) + 1) * sizeof(WCHAR); + WCHAR *p = (WCHAR *)CoTaskMemAlloc(size); + if (p) + { + memcpy(p, src, size); + *dest = p; + return S_OK; + } + } + *dest = NULL; + return E_OUTOFMEMORY; +} + + +#define CZipExplorerCommand CZipContextMenu + +class CCoTaskWSTR +{ + LPWSTR m_str; + Z7_CLASS_NO_COPY(CCoTaskWSTR) +public: + CCoTaskWSTR(): m_str(NULL) {} + ~CCoTaskWSTR() { ::CoTaskMemFree(m_str); } + LPWSTR* operator&() { return &m_str; } + operator LPCWSTR () const { return m_str; } + // operator LPCOLESTR() const { return m_str; } + operator bool() const { return m_str != NULL; } + // bool operator!() const { return m_str == NULL; } + + /* + void Wipe_and_Free() + { + if (m_str) + { + memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str)); + Empty(); + } + } + */ + +private: + /* + CCoTaskWSTR(LPCOLESTR src) { m_str = ::CoTaskMemAlloc(src); } + + CCoTaskWSTR& operator=(LPCOLESTR src) + { + ::CoTaskMemFree(m_str); + m_str = ::SysAllocString(src); + return *this; + } + + + void Empty() + { + ::CoTaskMemFree(m_str); + m_str = NULL; + } + */ +}; + +static HRESULT LoadPaths(IShellItemArray *psiItemArray, UStringVector &paths) +{ + if (psiItemArray) + { + DWORD numItems = 0; + RINOK(psiItemArray->GetCount(&numItems)) + { + ODS_(Print_Number(numItems, " ==== LoadPaths START === ")) + for (DWORD i = 0; i < numItems; i++) + { + CMyComPtr item; + RINOK(psiItemArray->GetItemAt(i, &item)) + if (item) + { + CCoTaskWSTR displayName; + if (item->GetDisplayName(SIGDN_FILESYSPATH, &displayName) == S_OK + && (bool)displayName) + { + ODS_U(displayName) + paths.Add((LPCWSTR)displayName); + } + } + } + ODS_(Print_Number(numItems, " ==== LoadPaths END === ")) + } + } + return S_OK; +} + + +void CZipExplorerCommand::LoadItems(IShellItemArray *psiItemArray) +{ + SubCommands.Clear(); + _fileNames.Clear(); + { + UStringVector paths; + if (LoadPaths(psiItemArray, paths) != S_OK) + return; + _fileNames = paths; + } + const HRESULT res = QueryContextMenu( + NULL, // hMenu, + 0, // indexMenu, + 0, // commandIDFirst, + 0 + 999, // commandIDLast, + CMF_NORMAL); + + if (FAILED(res)) + return /* res */; + + CZipExplorerCommand *crcHandler = NULL; + CZipExplorerCommand *openHandler = NULL; + + bool useCascadedCrc = true; // false; + bool useCascadedOpen = true; // false; + + for (unsigned i = 0; i < _commandMap.Size(); i++) + { + const CCommandMapItem &cmi = _commandMap[i]; + + if (cmi.IsPopup) + if (!cmi.IsSubMenu()) + continue; + + // if (cmi.IsSubMenu()) continue // for debug + + CZipContextMenu *shellExt = new CZipContextMenu(); + shellExt->IsRoot = false; + + if (cmi.CtxCommandType == CtxCommandType_CrcRoot && !useCascadedCrc) + shellExt->IsSeparator = true; + + { + CZipExplorerCommand *handler = this; + if (cmi.CtxCommandType == CtxCommandType_CrcChild && crcHandler) + handler = crcHandler; + else if (cmi.CtxCommandType == CtxCommandType_OpenChild && openHandler) + handler = openHandler; + handler->SubCommands.AddNew() = shellExt; + } + + shellExt->_commandMap_Cur.Add(cmi); + + ODS_U(cmi.UserString) + + if (cmi.CtxCommandType == CtxCommandType_CrcRoot && useCascadedCrc) + crcHandler = shellExt; + if (cmi.CtxCommandType == CtxCommandType_OpenRoot && useCascadedOpen) + { + // ODS("cmi.CtxCommandType == CtxCommandType_OpenRoot"); + openHandler = shellExt; + } + } +} + + +Z7_COMWF_B CZipExplorerCommand::GetTitle(IShellItemArray *psiItemArray, LPWSTR *ppszName) +{ + ODS("- GetTitle()") + // COM_TRY_BEGIN + if (IsSeparator) + { + *ppszName = NULL; + return S_FALSE; + } + + UString name; + if (IsRoot) + { + LoadItems(psiItemArray); + name = "7-Zip"; // "New" + } + else + name = "7-Zip item"; + + if (!_commandMap_Cur.IsEmpty()) + { + const CCommandMapItem &mi = _commandMap_Cur[0]; + // s += mi.Verb; + // s += " : "; + name = mi.UserString; + } + + return My_SHStrDupW(name, ppszName); + // return S_OK; + // COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::GetIcon(IShellItemArray * /* psiItemArray */, LPWSTR *ppszIcon) +{ + ODS("- GetIcon()") + // COM_TRY_BEGIN + *ppszIcon = NULL; + // return E_NOTIMPL; + UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix()); + // imageName += "7zG.exe"; + imageName += "7-zip.dll"; + // imageName += ",190"; + return My_SHStrDupW(imageName, ppszIcon); + // COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::GetToolTip (IShellItemArray * /* psiItemArray */, LPWSTR *ppszInfotip) +{ + // COM_TRY_BEGIN + ODS("- GetToolTip()") + *ppszInfotip = NULL; + return E_NOTIMPL; + // COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::GetCanonicalName(GUID *pguidCommandName) +{ + // COM_TRY_BEGIN + ODS("- GetCanonicalName()") + *pguidCommandName = GUID_NULL; + return E_NOTIMPL; + // COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::GetState(IShellItemArray * /* psiItemArray */, BOOL /* fOkToBeSlow */, EXPCMDSTATE *pCmdState) +{ + // COM_TRY_BEGIN + ODS("- GetState()") + *pCmdState = ECS_ENABLED; + return S_OK; + // COM_TRY_END +} + + + + +Z7_COMWF_B CZipExplorerCommand::Invoke(IShellItemArray *psiItemArray, IBindCtx * /* pbc */) +{ + COM_TRY_BEGIN + + if (_commandMap_Cur.IsEmpty()) + return E_INVALIDARG; + + ODS("- Invoke()") + _fileNames.Clear(); + UStringVector paths; + RINOK(LoadPaths(psiItemArray, paths)) + _fileNames = paths; + return InvokeCommandCommon(_commandMap_Cur[0]); + + COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::GetFlags(EXPCMDFLAGS *pFlags) +{ + ODS("- GetFlags()") + // COM_TRY_BEGIN + EXPCMDFLAGS f = ECF_DEFAULT; + if (IsSeparator) + f = ECF_ISSEPARATOR; + else if (IsRoot) + f = ECF_HASSUBCOMMANDS; + else + { + if (!_commandMap_Cur.IsEmpty()) + { + // const CCommandMapItem &cmi = ; + if (_commandMap_Cur[0].IsSubMenu()) + { + // ODS("ECF_HASSUBCOMMANDS") + f = ECF_HASSUBCOMMANDS; + } + } + } + *pFlags = f; + return S_OK; + // COM_TRY_END +} + + +Z7_COMWF_B CZipExplorerCommand::EnumSubCommands(IEnumExplorerCommand **ppEnum) +{ + ODS("- EnumSubCommands()") + // COM_TRY_BEGIN + *ppEnum = NULL; + + if (!_commandMap_Cur.IsEmpty() && _commandMap_Cur[0].IsSubMenu()) + { + } + else + { + if (!IsRoot) + return E_NOTIMPL; + if (SubCommands.IsEmpty()) + { + return E_NOTIMPL; + } + } + + // shellExt-> + return QueryInterface(IID_IEnumExplorerCommand, (void **)ppEnum); + + // return S_OK; + // COM_TRY_END +} + + +Z7_COMWF_B CZipContextMenu::Next(ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) +{ + ODS("CZipContextMenu::Next()") + ODS_(Print_Number(celt, "celt")) + ODS_(Print_Number(CurrentSubCommand, "CurrentSubCommand")) + ODS_(Print_Number(SubCommands.Size(), "SubCommands.Size()")) + + COM_TRY_BEGIN + ULONG fetched = 0; + + ULONG i; + for (i = 0; i < celt; i++) + { + pUICommand[i] = NULL; + } + + for (i = 0; i < celt && CurrentSubCommand < SubCommands.Size(); i++) + { + pUICommand[i] = SubCommands[CurrentSubCommand++]; + pUICommand[i]->AddRef(); + fetched++; + } + + if (pceltFetched) + *pceltFetched = fetched; + + ODS(fetched == celt ? " === OK === " : "=== ERROR ===") + + // we return S_FALSE for (fetched == 0) + return (fetched == celt) ? S_OK : S_FALSE; + COM_TRY_END +} + + +Z7_COMWF_B CZipContextMenu::Skip(ULONG /* celt */) +{ + ODS("CZipContextMenu::Skip()") + return E_NOTIMPL; +} + + +Z7_COMWF_B CZipContextMenu::Reset(void) +{ + ODS("CZipContextMenu::Reset()") + CurrentSubCommand = 0; + return S_OK; +} + + +Z7_COMWF_B CZipContextMenu::Clone(IEnumExplorerCommand **ppenum) +{ + ODS("CZipContextMenu::Clone()") + *ppenum = NULL; + return E_NOTIMPL; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenu.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenu.h 2010-11-07 21:29:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenu.h 2024-11-25 14:00:00.000000000 +0000 @@ -1,5 +1,173 @@ - - -/* TODO */ - - +// ContextMenu.h + +#ifndef ZIP7_INC_CONTEXT_MENU_H +#define ZIP7_INC_CONTEXT_MENU_H + +#include "../../../Windows/Shell.h" + +#include "MyExplorerCommand.h" + +#include "../FileManager/MyCom2.h" + +#ifdef CMF_EXTENDEDVERBS +#define Z7_WIN_CMF_EXTENDEDVERBS CMF_EXTENDEDVERBS +#else +#define Z7_WIN_CMF_EXTENDEDVERBS 0x00000100 +#endif + +enum enum_CtxCommandType +{ + CtxCommandType_Normal, + CtxCommandType_OpenRoot, + CtxCommandType_OpenChild, + CtxCommandType_CrcRoot, + CtxCommandType_CrcChild +}; + + +class CZipContextMenu Z7_final: + public IContextMenu, + public IShellExtInit, + public IExplorerCommand, + public IEnumExplorerCommand, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_4_MT( + IContextMenu, + IShellExtInit, + IExplorerCommand, + IEnumExplorerCommand + ) + + // IShellExtInit + STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT dataObject, HKEY hkeyProgID) Z7_override; + + // IContextMenu + STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) Z7_override; + STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici) Z7_override; + STDMETHOD(GetCommandString)( + #ifdef Z7_OLD_WIN_SDK + UINT + #else + UINT_PTR + #endif + idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax) Z7_override; + + // IExplorerCommand + STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName) Z7_override; + STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon) Z7_override; + STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) Z7_override; + STDMETHOD (GetCanonicalName) (GUID *pguidCommandName) Z7_override; + STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) Z7_override; + STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc) Z7_override; + STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags) Z7_override; + STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum) Z7_override; + + // IEnumExplorerCommand + STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) Z7_override; + STDMETHOD (Skip) (ULONG celt) Z7_override; + STDMETHOD (Reset) (void) Z7_override; + STDMETHOD (Clone) (IEnumExplorerCommand **ppenum) Z7_override; + +public: + + enum enum_CommandInternalID + { + kCommandNULL, + kOpen, + kExtract, + kExtractHere, + kExtractTo, + kTest, + kCompress, + kCompressEmail, + kCompressTo7z, + kCompressTo7zEmail, + kCompressToZip, + kCompressToZipEmail, + kHash_CRC32, + kHash_CRC64, + kHash_XXH64, + kHash_MD5, + kHash_SHA1, + kHash_SHA256, + kHash_SHA384, + kHash_SHA512, + kHash_SHA3_256, + kHash_BLAKE2SP, + kHash_All, + kHash_Generate_SHA256, + kHash_TestArc + }; + +public: + void Init_For_7zFM() + { + // _isMenuForFM = true; + // _fileNames_WereReduced = false; + } + + void LoadItems(IShellItemArray *psiItemArray); + + CZipContextMenu(); + ~CZipContextMenu(); + + struct CCommandMapItem + { + enum_CommandInternalID CommandInternalID; + UString Verb; + UString UserString; + // UString HelpString; + UString Folder; + UString ArcName; + UString ArcType; + bool IsPopup; + enum_CtxCommandType CtxCommandType; + + CCommandMapItem(): + IsPopup(false), + CtxCommandType(CtxCommandType_Normal) + {} + + bool IsSubMenu() const + { + return + CtxCommandType == CtxCommandType_CrcRoot || + CtxCommandType == CtxCommandType_OpenRoot; + } + }; + + UStringVector _fileNames; + NWindows::NShell::CFileAttribs _attribs; + +private: + bool _isMenuForFM; + bool _fileNames_WereReduced; // = true, if only first 16 items were used in QueryContextMenu() + bool _dropMode; + UString _dropPath; + CObjectVector _commandMap; + CObjectVector _commandMap_Cur; + + HBITMAP _bitmap; + UInt32 _writeZone; + CBoolPair _elimDup; + + bool IsSeparator; + bool IsRoot; + CObjectVector< CMyComPtr > SubCommands; + unsigned CurrentSubCommand; + + void Set_UserString_in_LastCommand(const UString &s) + { + _commandMap.Back().UserString = s; + } + + int FindVerb(const UString &verb) const; + void FillCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi) const; + void AddCommand(enum_CommandInternalID id, UString &mainString, CCommandMapItem &cmi); + void AddMapItem_ForSubMenu(const char *ver); + + HRESULT InvokeCommandCommon(const CCommandMapItem &cmi); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenuFlags.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenuFlags.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/ContextMenuFlags.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/ContextMenuFlags.h 2023-01-10 18:00:00.000000000 +0000 @@ -0,0 +1,27 @@ +// ContextMenuFlags.h + +#ifndef ZIP7_INC_CONTEXT_MENU_FLAGS_H +#define ZIP7_INC_CONTEXT_MENU_FLAGS_H + +namespace NContextMenuFlags +{ + const UInt32 kExtract = 1 << 0; + const UInt32 kExtractHere = 1 << 1; + const UInt32 kExtractTo = 1 << 2; + + const UInt32 kTest = 1 << 4; + const UInt32 kOpen = 1 << 5; + const UInt32 kOpenAs = 1 << 6; + + const UInt32 kCompress = 1 << 8; + const UInt32 kCompressTo7z = 1 << 9; + const UInt32 kCompressEmail = 1 << 10; + const UInt32 kCompressTo7zEmail = 1 << 11; + const UInt32 kCompressToZip = 1 << 12; + const UInt32 kCompressToZipEmail = 1 << 13; + + const UInt32 kCRC_Cascaded = (UInt32)1 << 30; + const UInt32 kCRC = (UInt32)1 << 31; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/DllExportsExplorer.cpp 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,268 @@ +// DLLExportsExplorer.cpp +// +// Notes: +// Win2000: +// If I register at HKCR\Folder\ShellEx then DLL is locked. +// otherwise it unloads after explorer closing. +// but if I call menu for desktop items it's locked all the time + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__clang__) && __clang_major__ >= 4 +#pragma GCC diagnostic ignored "-Wnonportable-system-include-path" +#endif +// : in new Windows Kit 10.0.2**** (NTDDI_WIN10_MN is defined) +// : in another Windows Kit versions +#if defined(NTDDI_WIN10_MN) || defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/ComTry.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/Registry.h" + +#include "../FileManager/IFolder.h" + +#include "ContextMenu.h" + +static LPCTSTR const k_ShellExtName = TEXT("7-Zip Shell Extension"); +static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"); + +// {23170F69-40C1-278A-1000-000100020000} +static LPCTSTR const k_Clsid = TEXT("{23170F69-40C1-278A-1000-000100020000}"); + +Z7_DEFINE_GUID(CLSID_CZipContextMenu, + k_7zip_GUID_Data1, + k_7zip_GUID_Data2, + k_7zip_GUID_Data3_Common, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +using namespace NWindows; + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance = NULL; + +extern +HWND g_HWND; +HWND g_HWND = NULL; + +extern +LONG g_DllRefCount; +LONG g_DllRefCount = 0; // Reference count of this DLL. + +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + + +// #define ODS(sz) OutputDebugStringW(L#sz) +#define ODS(sz) + +class CShellExtClassFactory Z7_final: + public IClassFactory, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1_MT(IClassFactory) + + STDMETHOD(CreateInstance)(LPUNKNOWN, REFIID, void**) Z7_override Z7_final; + STDMETHOD(LockServer)(BOOL) Z7_override Z7_final; +public: + CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } + ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); } +}; + +Z7_COMWF_B CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, + REFIID riid, void **ppvObj) +{ + ODS("CShellExtClassFactory::CreateInstance()\r\n"); + /* + char s[64]; + ConvertUInt32ToHex(riid.Data1, s); + OutputDebugStringA(s); + */ + *ppvObj = NULL; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + CZipContextMenu *shellExt; + try + { + shellExt = new CZipContextMenu(); + } + catch(...) { return E_OUTOFMEMORY; } + if (!shellExt) + return E_OUTOFMEMORY; + + IContextMenu *ctxm = shellExt; + const HRESULT res = ctxm->QueryInterface(riid, ppvObj); + if (res != S_OK) + delete shellExt; + return res; +} + + +Z7_COMWF_B CShellExtClassFactory::LockServer(BOOL /* fLock */) +{ + return S_OK; // Check it +} + + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION return FALSE; +#endif + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE hInstance + #else + HINSTANCE hInstance + #endif + , DWORD dwReason, LPVOID); + +extern "C" +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE hInstance + #else + HINSTANCE hInstance + #endif + , DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = (HINSTANCE)hInstance; + ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n"); + NT_CHECK + } + else if (dwReason == DLL_PROCESS_DETACH) + { + ODS("In DLLMain, DLL_PROCESS_DETACH\r\n"); + } + return TRUE; +} + + +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow(void) +{ + ODS("In DLLCanUnloadNow\r\n"); + /* + if (g_DllRefCount == 0) + ODS( "g_DllRefCount == 0"); + else + ODS( "g_DllRefCount != 0"); + */ + return (g_DllRefCount == 0 ? S_OK : S_FALSE); +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + ODS("In DllGetClassObject\r\n"); + *ppv = NULL; + if (IsEqualIID(rclsid, CLSID_CZipContextMenu)) + { + CShellExtClassFactory *cf; + try + { + cf = new CShellExtClassFactory; + } + catch(...) { return E_OUTOFMEMORY; } + if (!cf) + return E_OUTOFMEMORY; + IClassFactory *cf2 = cf; + const HRESULT res = cf2->QueryInterface(riid, ppv); + if (res != S_OK) + delete cf; + return res; + } + return CLASS_E_CLASSNOTAVAILABLE; + // return _Module.GetClassObject(rclsid, riid, ppv); +} + + +static BOOL RegisterServer() +{ + ODS("RegisterServer\r\n"); + FString modulePath; + if (!NDLL::MyGetModuleFileName(modulePath)) + return FALSE; + const UString modulePathU = fs2us(modulePath); + + CSysString s ("CLSID\\"); + s += k_Clsid; + + { + NRegistry::CKey key; + if (key.Create(HKEY_CLASSES_ROOT, s, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + key.SetValue(NULL, k_ShellExtName); + NRegistry::CKey keyInproc; + if (keyInproc.Create(key, TEXT("InprocServer32"), NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + keyInproc.SetValue(NULL, modulePathU); + keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment")); + } + + #if !defined(_WIN64) && !defined(UNDER_CE) + if (IsItWindowsNT()) + #endif + { + NRegistry::CKey key; + if (key.Create(HKEY_LOCAL_MACHINE, k_Approved, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR) + key.SetValue(k_Clsid, k_ShellExtName); + } + + ODS("RegisterServer :: return TRUE"); + return TRUE; +} + +STDAPI DllRegisterServer(void) +{ + return RegisterServer() ? S_OK: SELFREG_E_CLASS; +} + +static BOOL UnregisterServer() +{ + CSysString s ("CLSID\\"); + s += k_Clsid; + + RegDeleteKey(HKEY_CLASSES_ROOT, s + TEXT("\\InprocServer32")); + RegDeleteKey(HKEY_CLASSES_ROOT, s); + + #if !defined(_WIN64) && !defined(UNDER_CE) + if (IsItWindowsNT()) + #endif + { + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, k_Approved, 0, KEY_SET_VALUE, &hKey) == NOERROR) + { + RegDeleteValue(hKey, k_Clsid); + RegCloseKey(hKey); + } + } + + return TRUE; +} + +STDAPI DllUnregisterServer(void) +{ + return UnregisterServer() ? S_OK: SELFREG_E_CLASS; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.def --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.def 2009-08-04 11:02:58.000000000 +0000 @@ -0,0 +1,9 @@ +; 7-zip.def + +LIBRARY "7-zip" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsp 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,620 @@ +# Microsoft Developer Studio Project File - Name="Explorer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Explorer - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak" CFG="Explorer - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Explorer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 ReleaseU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 DebugU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Explorer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /FAcs /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Util\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "Z7_LANG" /D "Z7_LONG_PATH" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Util\7-Zip.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Explorer - Win32 Release" +# Name "Explorer - Win32 Debug" +# Name "Explorer - Win32 ReleaseU" +# Name "Explorer - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\DllExportsExplorer.cpp +# End Source File +# Begin Source File + +SOURCE=.\Explorer.def +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\ContextMenu.h +# End Source File +# Begin Source File + +SOURCE=.\MyExplorerCommand.h +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.h +# End Source File +# End Group +# Begin Group "FileManager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\IFolder.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\MyCom2.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\RegistryUtils.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\COM.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Source File + +SOURCE=".\7-zip.dll.manifest" +# End Source File +# Begin Source File + +SOURCE=.\ContextMenuFlags.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\FM.ico +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsw --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/Explorer.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/Explorer.dsw 2003-06-26 16:21:12.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Explorer"=".\Explorer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/Explorer/MenuLogo.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MenuLogo.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyExplorerCommand.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyExplorerCommand.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyExplorerCommand.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyExplorerCommand.h 2023-09-14 11:00:00.000000000 +0000 @@ -0,0 +1,217 @@ +// MyExplorerCommand.h + +#ifndef ZIP7_INC_MY_EXPLORER_COMMAND_H +#define ZIP7_INC_MY_EXPLORER_COMMAND_H + +#if _MSC_VER >= 1910 +#define USE_SYS_shobjidl_core +#endif + +#ifdef USE_SYS_shobjidl_core + +// #include + +#else + +/* IShellItem is defined: + ShObjIdl.h : old Windows SDK + ShObjIdl_core.h : new Windows 10 SDK */ + +#ifndef Z7_OLD_WIN_SDK +#include +#endif + +#ifndef __IShellItem_INTERFACE_DEFINED__ +#define __IShellItem_INTERFACE_DEFINED__ + +// For MINGW we define IShellItem + +// #error Stop_Compiling__NOT_DEFINED__IShellItem_INTERFACE_DEFINED__ + +typedef +enum +{ SIGDN_NORMALDISPLAY = 0, + SIGDN_PARENTRELATIVEPARSING = 0x80018001, + SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001, + SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, + SIGDN_PARENTRELATIVEEDITING = 0x80031001, + SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, + SIGDN_FILESYSPATH = 0x80058000, + SIGDN_URL = 0x80068000 +} SIGDN; + + +typedef DWORD SICHINTF; +typedef ULONG SFGAOF; + +struct IShellItem : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut) = 0; + virtual HRESULT STDMETHODCALLTYPE GetParent(IShellItem **ppsi) = 0; + virtual HRESULT STDMETHODCALLTYPE GetDisplayName(SIGDN sigdnName, LPOLESTR *ppszName) = 0; + virtual HRESULT STDMETHODCALLTYPE GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) = 0; + virtual HRESULT STDMETHODCALLTYPE Compare(IShellItem *psi, SICHINTF hint, int *piOrder) = 0; +}; + +#endif // __IShellItem_INTERFACE_DEFINED__ + + + +#ifndef __IShellItemArray_INTERFACE_DEFINED__ +#define __IShellItemArray_INTERFACE_DEFINED__ + +// propsys.h + +typedef /* [v1_enum] */ +enum GETPROPERTYSTOREFLAGS +{ + GPS_DEFAULT = 0, + GPS_HANDLERPROPERTIESONLY = 0x1, + GPS_READWRITE = 0x2, + GPS_TEMPORARY = 0x4, + GPS_FASTPROPERTIESONLY = 0x8, + GPS_OPENSLOWITEM = 0x10, + GPS_DELAYCREATION = 0x20, + GPS_BESTEFFORT = 0x40, + GPS_NO_OPLOCK = 0x80, + GPS_PREFERQUERYPROPERTIES = 0x100, + GPS_EXTRINSICPROPERTIES = 0x200, + GPS_EXTRINSICPROPERTIESONLY = 0x400, + GPS_VOLATILEPROPERTIES = 0x800, + GPS_VOLATILEPROPERTIESONLY = 0x1000, + GPS_MASK_VALID = 0x1fff +} GETPROPERTYSTOREFLAGS; + +// DEFINE_ENUM_FLAG_OPERATORS(GETPROPERTYSTOREFLAGS) + + +#ifndef PROPERTYKEY_DEFINED +#define PROPERTYKEY_DEFINED + +typedef +struct +{ + GUID fmtid; + DWORD pid; +} PROPERTYKEY; + +#endif // PROPERTYKEY_DEFINED + +// propkeydef.h +#define REFPROPERTYKEY const PROPERTYKEY & + +#ifdef INITGUID +#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid } +#else +#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const PROPERTYKEY name +#endif // INITGUID + + +// +typedef /* [v1_enum] */ +enum SIATTRIBFLAGS +{ + SIATTRIBFLAGS_AND = 0x1, + SIATTRIBFLAGS_OR = 0x2, + SIATTRIBFLAGS_APPCOMPAT = 0x3, + SIATTRIBFLAGS_MASK = 0x3, + SIATTRIBFLAGS_ALLITEMS = 0x4000 +} SIATTRIBFLAGS; + +// DEFINE_ENUM_FLAG_OPERATORS(SIATTRIBFLAGS) + + +// MIDL_INTERFACE("70629033-e363-4a28-a567-0db78006e6d7") +DEFINE_GUID(IID_IEnumShellItems, 0x70629033, 0xe363, 0xe363, 0xa5, 0x67, 0x0d, 0xb7, 0x80, 0x06, 0xe6, 0xd7); + +struct IEnumShellItems : public IUnknown +{ + STDMETHOD (Next) (ULONG celt, IShellItem **rgelt, ULONG *pceltFetched) = 0; + STDMETHOD (Skip) (ULONG celt) = 0; + STDMETHOD (Reset) (void) = 0; + STDMETHOD (Clone) (IEnumShellItems **ppenum) = 0; +}; + + +// MIDL_INTERFACE("b63ea76d-1f85-456f-a19c-48159efa858b") +DEFINE_GUID(IID_IShellItemArray, 0xb63ea76d, 0x1f85, 0x456f, 0xa1, 0x9c, 0x48, 0x15, 0x9e, 0xfa, 0x85, 0x8b); + +struct IShellItemArray : public IUnknown +{ + STDMETHOD (BindToHandler) (IBindCtx *pbc, REFGUID bhid, REFIID riid, void **ppvOut) = 0; + STDMETHOD (GetPropertyStore) (GETPROPERTYSTOREFLAGS flags, REFIID riid, void **ppv) = 0; + STDMETHOD (GetPropertyDescriptionList) (REFPROPERTYKEY keyType, REFIID riid, void **ppv) = 0; + STDMETHOD (GetAttributes) ( SIATTRIBFLAGS AttribFlags, SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs) = 0; + STDMETHOD (GetCount) (DWORD *pdwNumItems) = 0; + STDMETHOD (GetItemAt) (DWORD dwIndex, IShellItem **ppsi) = 0; + STDMETHOD (EnumItems) (IEnumShellItems **ppenumShellItems) = 0; +}; + + +#ifndef __IEnumExplorerCommand_INTERFACE_DEFINED__ +#define __IEnumExplorerCommand_INTERFACE_DEFINED__ + +struct IExplorerCommand; + +// MIDL_INTERFACE("a88826f8-186f-4987-aade-ea0cef8fbfe8") +DEFINE_GUID(IID_IEnumExplorerCommand , 0xa88826f8, 0x186f, 0x4987, 0xaa, 0xde, 0xea, 0x0c, 0xef, 0x8f, 0xbf, 0xe8); + +struct IEnumExplorerCommand : public IUnknown +{ + STDMETHOD (Next) (ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched) = 0; + STDMETHOD (Skip) (ULONG celt) = 0; + STDMETHOD (Reset) (void) = 0; + STDMETHOD (Clone) (IEnumExplorerCommand **ppenum) = 0; +}; + + +enum _EXPCMDSTATE +{ + ECS_ENABLED = 0, + ECS_DISABLED = 0x1, + ECS_HIDDEN = 0x2, + ECS_CHECKBOX = 0x4, + ECS_CHECKED = 0x8, + ECS_RADIOCHECK = 0x10 +}; + +typedef DWORD EXPCMDSTATE; + +/* [v1_enum] */ +enum _EXPCMDFLAGS +{ + ECF_DEFAULT = 0, + ECF_HASSUBCOMMANDS = 0x1, + ECF_HASSPLITBUTTON = 0x2, + ECF_HIDELABEL = 0x4, + ECF_ISSEPARATOR = 0x8, + ECF_HASLUASHIELD = 0x10, + ECF_SEPARATORBEFORE = 0x20, + ECF_SEPARATORAFTER = 0x40, + ECF_ISDROPDOWN = 0x80, + ECF_TOGGLEABLE = 0x100, + ECF_AUTOMENUICONS = 0x200 +}; +typedef DWORD EXPCMDFLAGS; + + +// MIDL_INTERFACE("a08ce4d0-fa25-44ab-b57c-c7b1c323e0b9") +DEFINE_GUID(IID_IExplorerCommand, 0xa08ce4d0, 0xfa25, 0x44ab, 0xb5, 0x7c, 0xc7, 0xb1, 0xc3, 0x23, 0xe0, 0xb9); + +struct IExplorerCommand : public IUnknown +{ + STDMETHOD (GetTitle) (IShellItemArray *psiItemArray, LPWSTR *ppszName) = 0; + STDMETHOD (GetIcon) (IShellItemArray *psiItemArray, LPWSTR *ppszIcon) = 0; + STDMETHOD (GetToolTip) (IShellItemArray *psiItemArray, LPWSTR *ppszInfotip) = 0; + STDMETHOD (GetCanonicalName) (GUID *pguidCommandName) = 0; + STDMETHOD (GetState) (IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState) = 0; + STDMETHOD (Invoke) (IShellItemArray *psiItemArray, IBindCtx *pbc) = 0; + STDMETHOD (GetFlags) (EXPCMDFLAGS *pFlags) = 0; + STDMETHOD (EnumSubCommands) (IEnumExplorerCommand **ppEnum) = 0; +}; + +#endif // IShellItemArray +#endif // __IEnumExplorerCommand_INTERFACE_DEFINED__ +#endif // USE_SYS_shobjidl_core + +#endif // __MY_EXPLORER_COMMAND_H diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyMessages.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyMessages.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.cpp 2024-03-10 09:00:00.000000000 +0000 @@ -1,37 +1,43 @@ -// MyMessages.cpp - -#include "StdAfx.h" - -#include "MyMessages.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/ResourceString.h" - -#include "../FileManager/LangUtils.h" - -using namespace NWindows; - -void ShowErrorMessage(HWND window, LPCWSTR message) -{ - ::MessageBoxW(window, message, L"7-Zip", MB_OK | MB_ICONSTOP); -} - -void ShowErrorMessageHwndRes(HWND window, UINT resID) -{ - ShowErrorMessage(window, LangString(resID)); -} - -void ShowErrorMessageRes(UINT resID) -{ - ShowErrorMessageHwndRes(0, resID); -} - -void ShowErrorMessageDWORD(HWND window, DWORD errorCode) -{ - ShowErrorMessage(window, NError::MyFormatMessage(errorCode)); -} - -void ShowLastErrorMessage(HWND window) -{ - ShowErrorMessageDWORD(window, ::GetLastError()); -} +// MyMessages.cpp + +#include "StdAfx.h" + +#include "MyMessages.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/ResourceString.h" + +#include "../FileManager/LangUtils.h" + +using namespace NWindows; + +extern bool g_DisableUserQuestions; + +void ShowErrorMessage(HWND window, LPCWSTR message) +{ + if (!g_DisableUserQuestions) + ::MessageBoxW(window, message, L"7-Zip", MB_OK | MB_ICONSTOP); +} + +void ShowErrorMessageHwndRes(HWND window, UInt32 resID) +{ + UString s = LangString(resID); + if (s.IsEmpty()) + s.Add_UInt32(resID); + ShowErrorMessage(window, s); +} + +void ShowErrorMessageRes(UInt32 resID) +{ + ShowErrorMessageHwndRes(NULL, resID); +} + +static void ShowErrorMessageDWORD(HWND window, DWORD errorCode) +{ + ShowErrorMessage(window, NError::MyFormatMessage(errorCode)); +} + +void ShowLastErrorMessage(HWND window) +{ + ShowErrorMessageDWORD(window, ::GetLastError()); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyMessages.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/MyMessages.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/MyMessages.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,16 +1,16 @@ -// MyMessages.h - -#ifndef __MY_MESSAGES_H -#define __MY_MESSAGES_H - -#include "../../../Common/MyString.h" - -void ShowErrorMessage(HWND window, LPCWSTR message); -inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(0, message); } - -void ShowErrorMessageHwndRes(HWND window, UInt32 langID); -void ShowErrorMessageRes(UInt32 langID); - -void ShowLastErrorMessage(HWND window = 0); - -#endif +// MyMessages.h + +#ifndef ZIP7_INC_MY_MESSAGES_H +#define ZIP7_INC_MY_MESSAGES_H + +#include "../../../Common/MyString.h" + +void ShowErrorMessage(HWND window, LPCWSTR message); +inline void ShowErrorMessage(LPCWSTR message) { ShowErrorMessage(NULL, message); } + +void ShowErrorMessageHwndRes(HWND window, UInt32 langID); +void ShowErrorMessageRes(UInt32 langID); + +void ShowLastErrorMessage(HWND window = NULL); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp 2024-01-25 06:00:00.000000000 +0000 @@ -0,0 +1,225 @@ +// RegistryContextMenu.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/Registry.h" + +#include "RegistryContextMenu.h" + +using namespace NWindows; +using namespace NRegistry; + +#ifndef UNDER_CE + +// does extension can work, if Approved is removed ? +// CLISID (and Approved ?) items are separated for 32-bit and 64-bit code. +// shellex items shared by 32-bit and 64-bit code? + +#define k_Clsid_A "{23170F69-40C1-278A-1000-000100020000}" + +static LPCTSTR const k_Clsid = TEXT(k_Clsid_A); +static LPCTSTR const k_ShellExtName = TEXT("7-Zip Shell Extension"); + +static LPCTSTR const k_Approved = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"); +static LPCTSTR const k_Inproc = TEXT("InprocServer32"); + +static LPCSTR const k_KeyPostfix_ContextMenu = "\\shellex\\ContextMenuHandlers\\7-Zip"; +static LPCSTR const k_KeyPostfix_DragDrop = "\\shellex\\DragDropHandlers\\7-Zip"; + +static LPCSTR const k_KeyName_File = "*"; +static LPCSTR const k_KeyName_Folder = "Folder"; +static LPCSTR const k_KeyName_Directory = "Directory"; +static LPCSTR const k_KeyName_Drive = "Drive"; + +static LPCSTR const k_shellex_Prefixes[] = +{ + k_KeyName_File, + k_KeyName_Folder, + k_KeyName_Directory, + k_KeyName_Drive +}; + +static const bool k_shellex_Statuses[2][4] = +{ + { true, true, true, false }, + { false, false, true, true } +}; + + +// RegDeleteKeyExW is supported starting from win2003sp1/xp-pro-x64 +// Z7_WIN32_WINNT_MIN < 0x0600 // Vista +#if !defined(Z7_WIN32_WINNT_MIN) \ + || Z7_WIN32_WINNT_MIN < 0x0502 /* < win2003 */ \ + || Z7_WIN32_WINNT_MIN == 0x0502 && !defined(_M_AMD64) +#define Z7_USE_DYN_RegDeleteKeyExW +#endif + +#ifdef Z7_USE_DYN_RegDeleteKeyExW +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +typedef +// WINADVAPI +LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved); +static Func_RegDeleteKeyExW func_RegDeleteKeyExW; + +static void Init_RegDeleteKeyExW() +{ + if (!func_RegDeleteKeyExW) + func_RegDeleteKeyExW = Z7_GET_PROC_ADDRESS( + Func_RegDeleteKeyExW, GetModuleHandleW(L"advapi32.dll"), + "RegDeleteKeyExW"); +} +#define INIT_REG_WOW if (wow != 0) Init_RegDeleteKeyExW(); +#else +#define INIT_REG_WOW +#endif + + +static LONG MyRegistry_DeleteKey(HKEY parentKey, LPCTSTR name, UInt32 wow) +{ + if (wow == 0) + return RegDeleteKey(parentKey, name); + +#ifdef Z7_USE_DYN_RegDeleteKeyExW + if (!func_RegDeleteKeyExW) + return E_NOTIMPL; + return func_RegDeleteKeyExW +#else + return RegDeleteKeyExW +#endif + (parentKey, GetUnicodeString(name), wow, 0); +} + +static LONG MyRegistry_DeleteKey_HKCR(LPCTSTR name, UInt32 wow) +{ + return MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, name, wow); +} + +// static NSynchronization::CCriticalSection g_CS; + +static AString Get_ContextMenuHandler_KeyName(LPCSTR keyName) + { return (AString)keyName + k_KeyPostfix_ContextMenu; } + +/* +static CSysString Get_DragDropHandler_KeyName(LPCTSTR keyName) + { return (AString)keyName + k_KeyPostfix_DragDrop); } +*/ + +static bool CheckHandlerCommon(const AString &keyName, UInt32 wow) +{ + CKey key; + if (key.Open(HKEY_CLASSES_ROOT, (CSysString)keyName, KEY_READ | wow) != ERROR_SUCCESS) + return false; + CSysString value; + if (key.QueryValue(NULL, value) != ERROR_SUCCESS) + return false; + return StringsAreEqualNoCase_Ascii(value, k_Clsid_A); +} + +bool CheckContextMenuHandler(const UString &path, UInt32 wow) +{ + // NSynchronization::CCriticalSectionLock lock(g_CS); + + CSysString s ("CLSID\\"); + s += k_Clsid_A; + s += "\\InprocServer32"; + + { + NRegistry::CKey key; + if (key.Open(HKEY_CLASSES_ROOT, s, KEY_READ | wow) != ERROR_SUCCESS) + return false; + UString regPath; + if (key.QueryValue(NULL, regPath) != ERROR_SUCCESS) + return false; + if (!path.IsEqualTo_NoCase(regPath)) + return false; + } + + return + CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_File), wow); + /* + && CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Directory), wow) + // && CheckHandlerCommon(Get_ContextMenuHandler_KeyName(k_KeyName_Folder)) + + && CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Directory), wow) + && CheckHandlerCommon(Get_DragDropHandler_KeyName(k_KeyName_Drive), wow); + */ +} + + +static LONG MyCreateKey(CKey &key, HKEY parentKey, LPCTSTR keyName, UInt32 wow) +{ + return key.Create(parentKey, keyName, REG_NONE, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | wow); +} + +LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow) +{ + // NSynchronization::CCriticalSectionLock lock(g_CS); + + INIT_REG_WOW + + LONG res; + + { + CSysString s ("CLSID\\"); + s += k_Clsid_A; + + if (setMode) + { + { + CKey key; + res = MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow); + if (res == ERROR_SUCCESS) + { + key.SetValue(NULL, k_ShellExtName); + CKey keyInproc; + res = MyCreateKey(keyInproc, key, k_Inproc, wow); + if (res == ERROR_SUCCESS) + { + res = keyInproc.SetValue(NULL, path); + keyInproc.SetValue(TEXT("ThreadingModel"), TEXT("Apartment")); + } + } + } + + { + CKey key; + if (MyCreateKey(key, HKEY_LOCAL_MACHINE, k_Approved, wow) == ERROR_SUCCESS) + key.SetValue(k_Clsid, k_ShellExtName); + } + } + else + { + CSysString s2 (s); + s2 += "\\InprocServer32"; + + MyRegistry_DeleteKey_HKCR(s2, wow); + res = MyRegistry_DeleteKey_HKCR(s, wow); + } + } + + // shellex items probably are shared beween 32-bit and 64-bit apps. So we don't delete items for delete operation. + if (setMode) + for (unsigned i = 0; i < 2; i++) + { + for (unsigned k = 0; k < Z7_ARRAY_SIZE(k_shellex_Prefixes); k++) + { + CSysString s (k_shellex_Prefixes[k]); + s += (i == 0 ? k_KeyPostfix_ContextMenu : k_KeyPostfix_DragDrop); + if (k_shellex_Statuses[i][k]) + { + CKey key; + MyCreateKey(key, HKEY_CLASSES_ROOT, s, wow); + key.SetValue(NULL, k_Clsid); + } + else + MyRegistry_DeleteKey_HKCR(s, wow); + } + } + + return res; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/RegistryContextMenu.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/RegistryContextMenu.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/RegistryContextMenu.h 2023-01-10 18:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +// RegistryContextMenu.h + +#ifndef ZIP7_INC_REGISTRY_CONTEXT_MENU_H +#define ZIP7_INC_REGISTRY_CONTEXT_MENU_H + +#ifndef UNDER_CE + +bool CheckContextMenuHandler(const UString &path, UInt32 wow = 0); +LONG SetContextMenuHandler(bool setMode, const UString &path, UInt32 wow = 0); + +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.cpp 2020-10-05 08:26:24.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/StdAfx.h 2023-03-06 18:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// StdAfx.h + +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../FileManager/StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/makefile --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -0,0 +1,78 @@ +PROG = 7-zip.dll +DEF_FILE = Explorer.def +CFLAGS = $(CFLAGS) \ + -DZ7_LANG \ + +!IFDEF UNDER_CE +LIBS = $(LIBS) Commctrl.lib +!ELSE +LIBS = $(LIBS) htmlhelp.lib comdlg32.lib Mpr.lib Gdi32.lib +# CFLAGS = $(CFLAGS) -DZ7_LONG_PATH +# -DZ7_NO_LARGE_PAGES +!ENDIF + +EXPLORER_OBJS = \ + $O\DllExportsExplorer.obj \ + $O\ContextMenu.obj \ + $O\MyMessages.obj \ + +COMMON_OBJS = \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\Menu.obj \ + $O\ProcessUtils.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\TimeUtils.obj \ + $O\Window.obj \ + +!IFDEF UNDER_CE + +WIN_OBJS = $(WIN_OBJS) \ + $O\CommonDialog.obj \ + +!ENDIF + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + $O\ListView.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveName.obj \ + $O\CompressCall.obj \ + $O\ExtractingFilePath.obj \ + $O\ZipRegistry.obj \ + +FM_OBJS = \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\ProgramLocation.obj \ + $O\PropertyName.obj \ + $O\RegistryUtils.obj \ + +C_OBJS = \ + $O\CpuArch.obj \ + $O\Threads.obj \ + +!include "../../Sort.mak" +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.h --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.h 2023-01-04 20:00:00.000000000 +0000 @@ -0,0 +1,15 @@ +#define IDS_CONTEXT_FOLDER 2320 +#define IDS_CONTEXT_ARCHIVE 2321 +#define IDS_CONTEXT_OPEN 2322 +#define IDS_CONTEXT_EXTRACT 2323 +#define IDS_CONTEXT_COMPRESS 2324 +#define IDS_CONTEXT_TEST 2325 +#define IDS_CONTEXT_EXTRACT_HERE 2326 +#define IDS_CONTEXT_EXTRACT_TO 2327 +#define IDS_CONTEXT_COMPRESS_TO 2328 +#define IDS_CONTEXT_COMPRESS_EMAIL 2329 +#define IDS_CONTEXT_COMPRESS_TO_EMAIL 2330 + +#define IDS_SELECT_FILES 3015 + +#define IDB_MENU_LOGO 190 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource.rc 2022-07-14 12:00:00.000000000 +0000 @@ -0,0 +1,10 @@ +#include "../../MyVersionInfo.rc" +#include "resource2.rc" + +MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip") + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "7-zip.dll.manifest" +#endif + +IDI_ICON ICON "../FileManager/FM.ico" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource2.rc --- p7zip-rar-16.02/CPP/7zip/UI/Explorer/resource2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Explorer/resource2.rc 2023-01-04 20:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +#include "resource.h" + +STRINGTABLE +BEGIN + IDS_CONTEXT_FOLDER "" + IDS_CONTEXT_ARCHIVE "" + IDS_CONTEXT_OPEN "Open archive" + IDS_CONTEXT_EXTRACT "Extract files..." + IDS_CONTEXT_COMPRESS "Add to archive..." + IDS_CONTEXT_TEST "Test archive" + IDS_CONTEXT_EXTRACT_HERE "Extract Here" + IDS_CONTEXT_EXTRACT_TO "Extract to {0}" + IDS_CONTEXT_COMPRESS_TO "Add to {0}" + IDS_CONTEXT_COMPRESS_EMAIL "Compress and email..." + IDS_CONTEXT_COMPRESS_TO_EMAIL "Compress to {0} and email" + IDS_SELECT_FILES "You must select one or more files" +END + +IDB_MENU_LOGO BITMAP "../../UI/Explorer/MenuLogo.bmp" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/ExtractEngine.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/ExtractEngine.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.cpp 2023-03-20 17:00:00.000000000 +0000 @@ -0,0 +1,274 @@ +// ExtractEngine.h + +#include "StdAfx.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +#include "../../../Common/StringConvert.h" + +#include "ExtractEngine.h" +#include "FarUtils.h" +#include "Messages.h" +#include "OverwriteDialogFar.h" + +using namespace NWindows; +using namespace NFar; + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + + +static HRESULT CheckBreak2() +{ + return WasEscPressed() ? E_ABORT : S_OK; +} + +extern void PrintMessage(const char *message); + +void CExtractCallbackImp::Init( + UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, + const UString &password) +{ + m_PasswordIsDefined = passwordIsDefined; + m_Password = password; + m_CodePage = codePage; + _percent = progressBox; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 size)) +{ + MT_LOCK + + if (_percent) + { + _percent->Total = size; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)) +{ + MT_LOCK + + if (_percent) + { + if (completeValue) + _percent->Completed = *completeValue; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer)) +{ + MT_LOCK + + NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo; + oldFileInfo.TimeIsDefined = (existTime != NULL); + if (oldFileInfo.TimeIsDefined) + oldFileInfo.Time = *existTime; + oldFileInfo.SizeIsDefined = (existSize != NULL); + if (oldFileInfo.SizeIsDefined) + oldFileInfo.Size = *existSize; + oldFileInfo.Name = existName; + + newFileInfo.TimeIsDefined = (newTime != NULL); + if (newFileInfo.TimeIsDefined) + newFileInfo.Time = *newTime; + newFileInfo.SizeIsDefined = (newSize != NULL); + if (newFileInfo.SizeIsDefined) + newFileInfo.Size = *newSize; + newFileInfo.Name = newName; + + NOverwriteDialog::NResult::EEnum result = + NOverwriteDialog::Execute(oldFileInfo, newFileInfo); + + switch ((int)result) + { + case NOverwriteDialog::NResult::kCancel: + // *answer = NOverwriteAnswer::kCancel; + // break; + return E_ABORT; + case NOverwriteDialog::NResult::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NOverwriteDialog::NResult::kNoToAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NOverwriteDialog::NResult::kYesToAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NOverwriteDialog::NResult::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NOverwriteDialog::NResult::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + return E_FAIL; + } + + return CheckBreak2(); +} + +static const char * const kTestString = "Testing"; +static const char * const kExtractString = "Extracting"; +static const char * const kSkipString = "Skipping"; +static const char * const kReadString = "Reading"; + +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 /* isFolder */, Int32 askExtractMode, const UInt64 * /* position */)) +{ + MT_LOCK + + m_CurrentFilePath = name; + const char *s; + + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: s = kExtractString; break; + case NArchive::NExtract::NAskMode::kTest: s = kTestString; break; + case NArchive::NExtract::NAskMode::kSkip: s = kSkipString; break; + case NArchive::NExtract::NAskMode::kReadExternal: s = kReadString; break; + default: s = "???"; // return E_FAIL; + } + + if (_percent) + { + _percent->Command = s; + _percent->FileName = name; + _percent->Print(); + } + + return CheckBreak2(); +} + +Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *message)) +{ + MT_LOCK + + AString s (UnicodeStringToMultiByte(message, CP_OEMCP)); + if (g_StartupInfo.ShowErrorMessage((const char *)s) == -1) + return E_ABORT; + + return CheckBreak2(); +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s); +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s) +{ + s.Empty(); + + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kOK: + return; + default: + { + UINT messageID = 0; + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + messageID = NMessageID::kExtractUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + messageID = encrypted ? + NMessageID::kExtractCRCFailedEncrypted : + NMessageID::kExtractCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + messageID = encrypted ? + NMessageID::kExtractDataErrorEncrypted : + NMessageID::kExtractDataError; + break; + } + if (messageID != 0) + { + s = g_StartupInfo.GetMsgString((int)messageID); + s.Replace((AString)" '%s'", AString()); + } + else if (opRes == NArchive::NExtract::NOperationResult::kUnavailable) + s = "Unavailable data"; + else if (opRes == NArchive::NExtract::NOperationResult::kUnexpectedEnd) + s = "Unexpected end of data"; + else if (opRes == NArchive::NExtract::NOperationResult::kDataAfterEnd) + s = "There are some data after the end of the payload data"; + else if (opRes == NArchive::NExtract::NOperationResult::kIsNotArc) + s = "Is not archive"; + else if (opRes == NArchive::NExtract::NOperationResult::kHeadersError) + s = "kHeaders Error"; + else if (opRes == NArchive::NExtract::NOperationResult::kWrongPassword) + s = "Wrong Password"; + else + { + s = "Error #"; + s.Add_UInt32((UInt32)opRes); + } + } + } +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)) +{ + MT_LOCK + + if (opRes == NArchive::NExtract::NOperationResult::kOK) + { + if (_percent) + { + _percent->Command.Empty(); + _percent->FileName.Empty(); + _percent->Files++; + } + } + else + { + AString s; + SetExtractErrorMessage(opRes, encrypted, s); + if (PrintErrorMessage(s, m_CurrentFilePath) == -1) + return E_ABORT; + } + + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) +{ + MT_LOCK + + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + AString s; + SetExtractErrorMessage(opRes, encrypted, s); + if (PrintErrorMessage(s, name) == -1) + return E_ABORT; + } + + return CheckBreak2(); +} + +extern HRESULT GetPassword(UString &password); + +Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)) +{ + MT_LOCK + + if (!m_PasswordIsDefined) + { + RINOK(GetPassword(m_Password)) + m_PasswordIsDefined = true; + } + return StringToBstr(m_Password, password); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/ExtractEngine.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/ExtractEngine.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ExtractEngine.h 2023-03-19 09:00:00.000000000 +0000 @@ -0,0 +1,43 @@ +// ExtractEngine.h + +#ifndef ZIP7_INC_EXTRACT_ENGINE_H +#define ZIP7_INC_EXTRACT_ENGINE_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyString.h" + +#include "../../IPassword.h" +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +Z7_CLASS_IMP_COM_3( + CExtractCallbackImp + , IFolderArchiveExtractCallback + , IFolderArchiveExtractCallback2 + , ICryptoGetTextPassword +) + Z7_IFACE_COM7_IMP(IProgress) + + UString m_CurrentFilePath; + + CProgressBox *_percent; + UINT m_CodePage; + + bool m_PasswordIsDefined; + UString m_Password; + + void CreateComplexDirectory(const UStringVector &dirPathParts); + /* + void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId, + PROPVARIANT *aValue); + bool IsEncrypted(LPITEMIDLIST anItemIDList); + */ + void AddErrorMessage(LPCTSTR message); +public: + void Init(UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, const UString &password); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Far.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/Far.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -0,0 +1,588 @@ +// Far.cpp +// Test Align for updating !!!!!!!!!!!!!!!!!! + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/NtCheck.h" + +#include "../../Common/FileStreams.h" + +#include "Messages.h" +#include "Plugin.h" +#include "ProgressBox.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NFar; + +static const DWORD kShowProgressTime_ms = 100; + +static const char * const kCommandPrefix = "7-zip"; +static const char * const kRegisrtryMainKeyName = NULL; // "" +static LPCTSTR const kRegisrtryValueNameEnabled = TEXT("UsedByDefault3"); +static const char * const kHelpTopicConfig = "Config"; +static bool kPluginEnabledDefault = true; + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance; + +namespace NFar { + +extern +const char *g_PluginName_for_Error; +const char *g_PluginName_for_Error = "7-Zip"; + +} + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION return FALSE; +#endif + +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID); +BOOL WINAPI DllMain( + #ifdef UNDER_CE + HANDLE + #else + HINSTANCE + #endif + hInstance, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + // OutputDebugStringA("7-Zip FAR DLL_PROCESS_ATTACH"); + g_hInstance = (HINSTANCE)hInstance; + NT_CHECK + } + if (dwReason == DLL_PROCESS_DETACH) + { + // OutputDebugStringA("7-Zip FAR DLL_PROCESS_DETACH"); + } + return TRUE; +} + +static struct COptions +{ + bool Enabled; +} g_Options; + +static const char * const kPliginNameForRegistry = "7-ZIP"; + +EXTERN_C void WINAPI ExitFAR() +{ + /* WIN32: + it's not allowed to call FreeLibrary() from FreeLibrary(). + So we try to free all DLLs before destructors */ + // OutputDebugStringA("-- ExitFAR --- START"); + + FreeGlobalCodecs(); + + // OutputDebugStringA("-- ExitFAR --- END"); +} + +EXTERN_C void WINAPI SetStartupInfo(const PluginStartupInfo *info) +{ + MY_TRY_BEGIN + g_StartupInfo.Init(*info, kPliginNameForRegistry); + g_Options.Enabled = g_StartupInfo.QueryRegKeyValue( + HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, kPluginEnabledDefault); + + // OutputDebugStringA("SetStartupInfo"); + // LoadGlobalCodecs(); + + MY_TRY_END1("SetStartupInfo") +} + +Z7_CLASS_IMP_COM_3( + COpenArchiveCallback + , IArchiveOpenCallback + , IProgress + , ICryptoGetTextPassword +) + // DWORD m_StartTickValue; + bool m_MessageBoxIsShown; + + bool _numFilesTotalDefined; + bool _numBytesTotalDefined; +public: + bool PasswordIsDefined; + UString Password; + +private: + CProgressBox _progressBox; +public: + + COpenArchiveCallback() + {} + + void Init() + { + PasswordIsDefined = false; + + _numFilesTotalDefined = false; + _numBytesTotalDefined = false; + + m_MessageBoxIsShown = false; + + _progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReading)); + } + void ShowMessage(); +}; + +static HRESULT CheckBreak2() +{ + return WasEscPressed() ? E_ABORT : S_OK; +} + +void COpenArchiveCallback::ShowMessage() +{ + if (!m_MessageBoxIsShown) + { + DWORD currentTime = GetTickCount(); + if (currentTime - _progressBox.StartTick < kShowProgressTime_ms) + return; + m_MessageBoxIsShown = true; + } + + _progressBox.UseBytesForPercents = !_numFilesTotalDefined; + _progressBox.Print(); +} + +Z7_COM7F_IMF(COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes)) +{ + _numFilesTotalDefined = (numFiles != NULL); + if (_numFilesTotalDefined) + _progressBox.FilesTotal = *numFiles; + + _numBytesTotalDefined = (numBytes != NULL); + if (_numBytesTotalDefined) + _progressBox.Total = *numBytes; + + return CheckBreak2(); +} + +Z7_COM7F_IMF(COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes)) +{ + if (numFiles) + _progressBox.Files = *numFiles; + + if (numBytes) + _progressBox.Completed = *numBytes; + + ShowMessage(); + return CheckBreak2(); +} + + +Z7_COM7F_IMF(COpenArchiveCallback::SetTotal(const UInt64 /* total */)) +{ + return CheckBreak2(); +} + +Z7_COM7F_IMF(COpenArchiveCallback::SetCompleted(const UInt64 * /* completed */)) +{ + ShowMessage(); + return CheckBreak2(); +} + +HRESULT GetPassword(UString &password); +HRESULT GetPassword(UString &password) +{ + if (WasEscPressed()) + return E_ABORT; + password.Empty(); + CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, 4, false, false, 0, false, NMessageID::kGetPasswordTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, DIF_SHOWAMPERSAND, false, NMessageID::kEnterPasswordForFile, NULL, NULL }, + { DI_PSWEDIT, 5, 3, 70, 3, true, false, 0, true, -1, "", NULL } + }; + + const int kNumItems = Z7_ARRAY_SIZE(initItems); + FarDialogItem dialogItems[kNumItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumItems); + + // sprintf(DialogItems[1].Data,GetMsg(MGetPasswordForFile),FileName); + if (g_StartupInfo.ShowDialog(76, 6, NULL, dialogItems, kNumItems) < 0) + return E_ABORT; + + password = MultiByteToUnicodeString(dialogItems[2].Data, CP_OEMCP); + return S_OK; +} + +Z7_COM7F_IMF(COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)) +{ + if (!PasswordIsDefined) + { + RINOK(GetPassword(Password)) + PasswordIsDefined = true; + } + return StringToBstr(Password, password); +} + +/* +HRESULT OpenArchive(const CSysString &fileName, + IInFolderArchive **archiveHandlerResult, + CArchiverInfo &archiverInfoResult, + UString &defaultName, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT OpenArchive(const CSysString &fileName, + IInArchive **archive, + CArchiverInfo &archiverInfoResult, + IArchiveOpenCallback *openArchiveCallback); +} +*/ + +static HANDLE MyOpenFilePluginW(const wchar_t *name, bool isAbortCodeSupported) +{ + FString normalizedName = us2fs(name); + normalizedName.Trim(); + FString fullName; + MyGetFullPathName(normalizedName, fullName); + NFind::CFileInfo fileInfo; + if (!fileInfo.Find(fullName)) + return INVALID_HANDLE_VALUE; + if (fileInfo.IsDir()) + return INVALID_HANDLE_VALUE; + + + CMyComPtr archiveHandler; + + // CArchiverInfo archiverInfoResult; + // ::OutputDebugStringA("before OpenArchive\n"); + + CScreenRestorer screenRestorer; + { + screenRestorer.Save(); + } + + COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback; + CMyComPtr uiCallback = openArchiveCallbackSpec; + + /* COpenCallbackImp object will exist after Open stage for multivolume archioves */ + COpenCallbackImp *impSpec = new COpenCallbackImp; + CMyComPtr impCallback = impSpec; + impSpec->ReOpenCallback = openArchiveCallbackSpec; // we set pointer without reference counter + + // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + openArchiveCallbackSpec->Init(); + { + FString dirPrefix, fileName; + GetFullPathAndSplit(fullName, dirPrefix, fileName); + impSpec->Init2(dirPrefix, fileName); + } + + // ::OutputDebugStringA("before OpenArchive\n"); + + CAgent *agent = new CAgent; + archiveHandler = agent; + CMyComBSTR archiveType; + HRESULT result = archiveHandler->Open(NULL, + GetUnicodeString(fullName, CP_OEMCP), UString(), &archiveType, impCallback); + /* + HRESULT result = ::OpenArchive(fullName, &archiveHandler, + archiverInfoResult, defaultName, openArchiveCallback); + */ + if (result == E_ABORT) + { + // fixed 18.06: + // OpenFilePlugin() is allowed to return (HANDLE)-2 as abort code + // OpenPlugin() is not allowed to return (HANDLE)-2. + return isAbortCodeSupported ? (HANDLE)-2 : INVALID_HANDLE_VALUE; + } + + UString errorMessage = agent->GetErrorMessage(); + if (!errorMessage.IsEmpty()) + g_StartupInfo.ShowErrorMessage(UnicodeStringToMultiByte(errorMessage, CP_OEMCP)); + + if (result != S_OK) + { + if (result == S_FALSE) + return INVALID_HANDLE_VALUE; + ShowSysErrorMessage(result); + return INVALID_HANDLE_VALUE; + } + + // ::OutputDebugStringA("after OpenArchive\n"); + + CPlugin *plugin = new CPlugin( + fullName, + // defaultName, + agent, + (const wchar_t *)archiveType + ); + + plugin->PasswordIsDefined = openArchiveCallbackSpec->PasswordIsDefined; + plugin->Password = openArchiveCallbackSpec->Password; + + // OutputDebugStringA("--- OpenFilePlugin ---- END"); + return (HANDLE)(plugin); +} + +static HANDLE MyOpenFilePlugin(const char *name, bool isAbortCodeSupported) +{ + UINT codePage = + #ifdef UNDER_CE + CP_OEMCP; + #else + ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + #endif + return MyOpenFilePluginW(GetUnicodeString(name, codePage), isAbortCodeSupported); +} + +EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const Byte * /* data */, int /* dataSize */) +{ + MY_TRY_BEGIN + // OutputDebugStringA("--- OpenFilePlugin"); + if (name == NULL || (!g_Options.Enabled)) + { + // if (!Opt.ProcessShiftF1) + return(INVALID_HANDLE_VALUE); + } + return MyOpenFilePlugin(name, true); // isAbortCodeSupported + MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE) +} + +/* +EXTERN_C HANDLE WINAPI OpenFilePluginW(const wchar_t *name,const Byte *Data,int DataSize,int OpMode) +{ + MY_TRY_BEGIN + if (name == NULL || (!g_Options.Enabled)) + { + // if (!Opt.ProcessShiftF1) + return(INVALID_HANDLE_VALUE); + } + return MyOpenFilePluginW(name); + ::OutputDebugStringA("OpenFilePluginW\n"); + MY_TRY_END2("OpenFilePluginW", INVALID_HANDLE_VALUE); +} +*/ + +EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) +{ + MY_TRY_BEGIN + + if (openFrom == OPEN_COMMANDLINE) + { + AString fileName ((const char *)item); + if (fileName.IsEmpty()) + return INVALID_HANDLE_VALUE; + if (fileName.Len() >= 2 + && fileName[0] == '\"' + && fileName.Back() == '\"') + { + fileName.DeleteBack(); + fileName.DeleteFrontal(1); + } + return MyOpenFilePlugin(fileName, false); // isAbortCodeSupported + } + + if (openFrom == OPEN_PLUGINSMENU) + { + switch (item) + { + case 0: + { + PluginPanelItem pluginPanelItem; + if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + throw 142134; + return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName, false); // isAbortCodeSupported + } + + case 1: + { + CObjectVector pluginPanelItem; + if (!g_StartupInfo.ControlGetActivePanelSelectedOrCurrentItems(pluginPanelItem)) + throw 142134; + HRESULT res = CompressFiles(pluginPanelItem); + if (res != S_OK && res != E_ABORT) + { + ShowSysErrorMessage(res); + } + // if (res == S_OK) + { + /* int t = */ g_StartupInfo.ControlClearPanelSelection(); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWANOTHERPANEL, NULL); + } + return INVALID_HANDLE_VALUE; + } + + default: + throw 4282215; + } + } + + return INVALID_HANDLE_VALUE; + MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE) +} + +EXTERN_C void WINAPI ClosePlugin(HANDLE plugin) +{ + // OutputDebugStringA("-- ClosePlugin --- START"); + // MY_TRY_BEGIN + delete (CPlugin *)plugin; + // OutputDebugStringA("-- ClosePlugin --- END"); + // MY_TRY_END1("ClosePlugin"); +} + +EXTERN_C int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, int *itemsNumber, int opMode) +{ + MY_TRY_BEGIN + return(((CPlugin *)plugin)->GetFindData(panelItems, itemsNumber, opMode)); + MY_TRY_END2("GetFindData", FALSE) +} + +EXTERN_C void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber) +{ + // MY_TRY_BEGIN + ((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber); + // MY_TRY_END1("FreeFindData"); +} + +EXTERN_C int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *destPath, int opMode) +{ + MY_TRY_BEGIN + return(((CPlugin *)plugin)->GetFiles(panelItems, (unsigned)itemsNumber, move, destPath, opMode)); + MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError) +} + +EXTERN_C int WINAPI SetDirectory(HANDLE plugin, const char *dir, int opMode) +{ + MY_TRY_BEGIN + return(((CPlugin *)plugin)->SetDirectory(dir, opMode)); + MY_TRY_END2("SetDirectory", FALSE) +} + +EXTERN_C void WINAPI GetPluginInfo(struct PluginInfo *info) +{ + MY_TRY_BEGIN + + info->StructSize = sizeof(*info); + info->Flags = 0; + info->DiskMenuStrings = NULL; + info->DiskMenuNumbers = NULL; + info->DiskMenuStringsNumber = 0; + static char *pluginMenuStrings[2]; + pluginMenuStrings[0] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString)); + pluginMenuStrings[1] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString)); + info->PluginMenuStrings = (char **)pluginMenuStrings; + info->PluginMenuStringsNumber = 2; + static char *pluginCfgStrings[1]; + pluginCfgStrings[0] = const_cast(g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString)); + info->PluginConfigStrings = (char **)pluginCfgStrings; + info->PluginConfigStringsNumber = Z7_ARRAY_SIZE(pluginCfgStrings); + info->CommandPrefix = const_cast(kCommandPrefix); + MY_TRY_END1("GetPluginInfo") +} + +EXTERN_C int WINAPI Configure(int /* itemNumber */) +{ + MY_TRY_BEGIN + + const int kEnabledCheckBoxIndex = 1; + + const int kYSize = 7; + + struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kConfigTitle, NULL, NULL }, + { DI_CHECKBOX, 5, 2, 0, 0, true, g_Options.Enabled, 0, false, NMessageID::kConfigPluginEnabled, NULL, NULL }, + { DI_TEXT, 5, 3, 0, 0, false, false, DIF_BOXCOLOR | DIF_SEPARATOR, false, -1, "", NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kOk, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }, + }; + + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); + const int kOkButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopicConfig, dialogItems, kNumDialogItems); + + if (askCode != kOkButtonIndex) + return (FALSE); + + g_Options.Enabled = BOOLToBool(dialogItems[kEnabledCheckBoxIndex].Selected); + + g_StartupInfo.SetRegKeyValue(HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, g_Options.Enabled); + return(TRUE); + MY_TRY_END2("Configure", FALSE) +} + +EXTERN_C void WINAPI GetOpenPluginInfo(HANDLE plugin,struct OpenPluginInfo *info) +{ + MY_TRY_BEGIN + ((CPlugin *)plugin)->GetOpenPluginInfo(info); + MY_TRY_END1("GetOpenPluginInfo") +} + +EXTERN_C int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, int itemsNumber, int move, int opMode) +{ + MY_TRY_BEGIN + return (((CPlugin *)plugin)->PutFiles(panelItems, (unsigned)itemsNumber, move, opMode)); + MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError) +} + +EXTERN_C int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, int itemsNumber, int opMode) +{ + MY_TRY_BEGIN + return (((CPlugin *)plugin)->DeleteFiles(panelItems, (unsigned)itemsNumber, opMode)); + MY_TRY_END2("DeleteFiles", FALSE) +} + +EXTERN_C int WINAPI ProcessKey(HANDLE plugin, int key, unsigned controlState) +{ + MY_TRY_BEGIN + /* FIXME: after folder creation with F7, it doesn't reload new file list + We need some to reload it */ + return (((CPlugin *)plugin)->ProcessKey(key, controlState)); + MY_TRY_END2("ProcessKey", FALSE) +} + +/* +struct MakeDirectoryInfo +{ + size_t StructSize; + HANDLE hPanel; + const wchar_t *Name; + OPERATION_MODES OpMode; + void* Instance; +}; + +typedef INT_PTR MY_intptr_t; + +MY_intptr_t WINAPI MakeDirectoryW(struct MakeDirectoryInfo *Info) +{ + MY_TRY_BEGIN + if (Info->StructSize < sizeof(MakeDirectoryInfo)) + { + return 0; + } + return 0; + MY_TRY_END2("MakeDirectoryW", FALSE); +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Far.def p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.def --- p7zip-rar-16.02/CPP/7zip/UI/Far/Far.def 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.def 2015-01-30 15:30:01.000000000 +0000 @@ -0,0 +1,35 @@ +; 7-ZipFar.def : Declares the module parameters for the DLL. + +LIBRARY "7-ZipFar" + +EXPORTS + ExitFAR + SetStartupInfo + OpenPlugin + OpenFilePlugin + ClosePlugin + GetFindData + FreeFindData + SetDirectory + GetPluginInfo + Configure + GetOpenPluginInfo + GetFiles + PutFiles + DeleteFiles + ProcessKey + + ;SetStartupInfoW + ;OpenPluginW + ;OpenFilePluginW + ;ClosePluginW + ;GetFindDataW + ;FreeFindDataW + ;SetDirectoryW + ;GetPluginInfoW + ;ConfigureW + ;GetOpenPluginInfoW + ;GetFilesW + ;PutFilesW + ;DeleteFilesW + ;ProcessKeyW diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Far.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsp --- p7zip-rar-16.02/CPP/7zip/UI/Far/Far.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsp 2023-03-25 16:00:00.000000000 +0000 @@ -0,0 +1,831 @@ +# Microsoft Developer Studio Project File - Name="Far" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Far - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Far.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Far.mak" CFG="Far - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Far - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Far - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Far - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Progs\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Far - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /D "Z7_EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Progs\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Far - Win32 Release" +# Name "Far - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Far.def +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Plugin" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractEngine.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.h +# End Source File +# Begin Source File + +SOURCE=.\Far.cpp +# End Source File +# Begin Source File + +SOURCE=.\Messages.h +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialogFar.cpp +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialogFar.h +# End Source File +# Begin Source File + +SOURCE=.\Plugin.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plugin.h +# End Source File +# Begin Source File + +SOURCE=.\PluginDelete.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginRead.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginWrite.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackFar.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackFar.h +# End Source File +# End Group +# Begin Group "Far" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FarPlugin.h +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Arc Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\IFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Far.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsw --- p7zip-rar-16.02/CPP/7zip/UI/Far/Far.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Far.dsw 2001-03-07 18:45:10.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Far"=.\Far.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/FarPlugin.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarPlugin.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/FarPlugin.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarPlugin.h 2024-01-27 13:00:00.000000000 +0000 @@ -0,0 +1,560 @@ +// FarPlugin.h + +// #include "plugin.hpp" + +const int kInfoPanelLineSize = 80; + +// #define __FAR_PLUGIN_H + +#ifdef UNDER_CE +typedef struct { + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } Char; + WORD Attributes; +} CHAR_INFO, *PCHAR_INFO; +#endif + +#ifndef ZIP7_INC_FAR_PLUGIN_H +#define ZIP7_INC_FAR_PLUGIN_H + +#ifndef _WIN64 +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a1 +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack(1) +#else + #pragma pack(push,1) +#endif +#endif + + // #if _MSC_VER + #define _export + // #endif + +#define NM 260 + +struct FarFindData +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + char cFileName[ MAX_PATH ]; + char cAlternateFileName[ 14 ]; +}; + +struct PluginPanelItem +{ + FarFindData FindData; + DWORD PackSizeHigh; + DWORD PackSize; + DWORD Flags; + DWORD NumberOfLinks; + char *Description; + char *Owner; + char **CustomColumnData; + int CustomColumnNumber; + DWORD_PTR UserData; + DWORD CRC32; + DWORD_PTR Reserved[2]; +}; + +#define PPIF_PROCESSDESCR 0x80000000 +#define PPIF_SELECTED 0x40000000 +#define PPIF_USERDATA 0x20000000 + +enum { + FMENU_SHOWAMPERSAND=1, + FMENU_WRAPMODE=2, + FMENU_AUTOHIGHLIGHT=4, + FMENU_REVERSEAUTOHIGHLIGHT=8 +}; + + +typedef int (WINAPI *FARAPIMENU)( + INT_PTR PluginNumber, + int X, + int Y, + int MaxHeight, + unsigned Flags, + char *Title, + char *Bottom, + char *HelpTopic, + int *BreakKeys, + int *BreakCode, + struct FarMenuItem *Item, + int ItemsNumber +); + +typedef int (WINAPI *FARAPIDIALOG)( + INT_PTR PluginNumber, + int X1, + int Y1, + int X2, + int Y2, + char *HelpTopic, + struct FarDialogItem *Item, + int ItemsNumber +); + +enum { + FMSG_WARNING = 0x00000001, + FMSG_ERRORTYPE = 0x00000002, + FMSG_KEEPBACKGROUND = 0x00000004, + FMSG_DOWN = 0x00000008, + FMSG_LEFTALIGN = 0x00000010, + + FMSG_ALLINONE = 0x00000020, + + FMSG_MB_OK = 0x00010000, + FMSG_MB_OKCANCEL = 0x00020000, + FMSG_MB_ABORTRETRYIGNORE = 0x00030000, + FMSG_MB_YESNO = 0x00040000, + FMSG_MB_YESNOCANCEL = 0x00050000, + FMSG_MB_RETRYCANCEL = 0x00060000 +}; + +typedef int (WINAPI *FARAPIMESSAGE)( + INT_PTR PluginNumber, + unsigned Flags, + const char *HelpTopic, + const char * const *Items, + int ItemsNumber, + int ButtonsNumber +); + +typedef char* (WINAPI *FARAPIGETMSG)( + INT_PTR PluginNumber, + int MsgId +); + + +enum DialogItemTypes { + DI_TEXT, + DI_VTEXT, + DI_SINGLEBOX, + DI_DOUBLEBOX, + DI_EDIT, + DI_PSWEDIT, + DI_FIXEDIT, + DI_BUTTON, + DI_CHECKBOX, + DI_RADIOBUTTON +}; + +enum FarDialogItemFlags { + DIF_COLORMASK = 0xff, + DIF_SETCOLOR = 0x100, + DIF_BOXCOLOR = 0x200, + DIF_GROUP = 0x400, + DIF_LEFTTEXT = 0x800, + DIF_MOVESELECT = 0x1000, + DIF_SHOWAMPERSAND = 0x2000, + DIF_CENTERGROUP = 0x4000, + DIF_NOBRACKETS = 0x8000, + DIF_SEPARATOR = 0x10000, + DIF_EDITOR = 0x20000, + DIF_HISTORY = 0x40000 +}; + +struct FarDialogItem +{ + int Type; + int X1,Y1,X2,Y2; + int Focus; + union + { + int Selected; + const char *History; + const char *Mask; + struct FarList *ListItems; + int ListPos; + CHAR_INFO *VBuf; + }; + unsigned Flags; + int DefaultButton; + char Data[512]; +}; + + +struct FarMenuItem +{ + char Text[128]; + int Selected; + int Checked; + int Separator; +}; + + +enum {FCTL_CLOSEPLUGIN,FCTL_GETPANELINFO,FCTL_GETANOTHERPANELINFO, + FCTL_UPDATEPANEL,FCTL_UPDATEANOTHERPANEL, + FCTL_REDRAWPANEL,FCTL_REDRAWANOTHERPANEL, + FCTL_SETANOTHERPANELDIR,FCTL_GETCMDLINE,FCTL_SETCMDLINE, + FCTL_SETSELECTION,FCTL_SETANOTHERSELECTION, + FCTL_SETVIEWMODE,FCTL_SETANOTHERVIEWMODE,FCTL_INSERTCMDLINE, + FCTL_SETUSERSCREEN,FCTL_SETPANELDIR,FCTL_SETCMDLINEPOS, + FCTL_GETCMDLINEPOS +}; + +enum {PTYPE_FILEPANEL,PTYPE_TREEPANEL,PTYPE_QVIEWPANEL,PTYPE_INFOPANEL}; + +struct PanelInfo +{ + int PanelType; + int Plugin; + RECT PanelRect; + struct PluginPanelItem *PanelItems; + int ItemsNumber; + struct PluginPanelItem *SelectedItems; + int SelectedItemsNumber; + int CurrentItem; + int TopPanelItem; + int Visible; + int Focus; + int ViewMode; + char ColumnTypes[80]; + char ColumnWidths[80]; + char CurDir[NM]; + int ShortNames; + int SortMode; + DWORD Flags; + DWORD Reserved; +}; + + +struct PanelRedrawInfo +{ + int CurrentItem; + int TopPanelItem; +}; + + +typedef int (WINAPI *FARAPICONTROL)( + HANDLE hPlugin, + int Command, + void *Param +); + +typedef HANDLE (WINAPI *FARAPISAVESCREEN)(int X1,int Y1,int X2,int Y2); + +typedef void (WINAPI *FARAPIRESTORESCREEN)(HANDLE hScreen); + +typedef int (WINAPI *FARAPIGETDIRLIST)( + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef int (WINAPI *FARAPIGETPLUGINDIRLIST)( + INT_PTR PluginNumber, + HANDLE hPlugin, + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef void (WINAPI *FARAPIFREEDIRLIST)(struct PluginPanelItem *PanelItem); + +enum VIEWER_FLAGS { + VF_NONMODAL=1,VF_DELETEONCLOSE=2 +}; + +typedef int (WINAPI *FARAPIVIEWER)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags +); + +typedef int (WINAPI *FARAPIEDITOR)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags, + int StartLine, + int StartChar +); + +typedef int (WINAPI *FARAPICMPNAME)( + char *Pattern, + char *String, + int SkipPath +); + + +#define FCT_DETECT 0x40000000 + +struct CharTableSet +{ + char DecodeTable[256]; + char EncodeTable[256]; + char UpperTable[256]; + char LowerTable[256]; + char TableName[128]; +}; + +typedef int (WINAPI *FARAPICHARTABLE)( + int Command, + char *Buffer, + int BufferSize +); + +typedef void (WINAPI *FARAPITEXT)( + int X, + int Y, + int Color, + char *Str +); + + +typedef int (WINAPI *FARAPIEDITORCONTROL)( + int Command, + void *Param +); + +struct PluginStartupInfo +{ + int StructSize; + char ModuleName[NM]; + INT_PTR ModuleNumber; + char *RootKey; + FARAPIMENU Menu; + FARAPIDIALOG Dialog; + FARAPIMESSAGE Message; + FARAPIGETMSG GetMsg; + FARAPICONTROL Control; + FARAPISAVESCREEN SaveScreen; + FARAPIRESTORESCREEN RestoreScreen; + FARAPIGETDIRLIST GetDirList; + FARAPIGETPLUGINDIRLIST GetPluginDirList; + FARAPIFREEDIRLIST FreeDirList; + FARAPIVIEWER Viewer; + FARAPIEDITOR Editor; + FARAPICMPNAME CmpName; + FARAPICHARTABLE CharTable; + FARAPITEXT Text; + FARAPIEDITORCONTROL EditorControl; +}; + + +enum PLUGIN_FLAGS { + PF_PRELOAD = 0x0001, + PF_DISABLEPANELS = 0x0002, + PF_EDITOR = 0x0004, + PF_VIEWER = 0x0008 +}; + + +struct PluginInfo +{ + int StructSize; + DWORD Flags; + char **DiskMenuStrings; + int *DiskMenuNumbers; + int DiskMenuStringsNumber; + char **PluginMenuStrings; + int PluginMenuStringsNumber; + char **PluginConfigStrings; + int PluginConfigStringsNumber; + char *CommandPrefix; +}; + +struct InfoPanelLine +{ + char Text[kInfoPanelLineSize]; + char Data[kInfoPanelLineSize]; + int Separator; +}; + + +struct PanelMode +{ + char *ColumnTypes; + char *ColumnWidths; + char **ColumnTitles; + int FullScreen; + int DetailedStatus; + int AlignExtensions; + int CaseConversion; + char *StatusColumnTypes; + char *StatusColumnWidths; + DWORD Reserved[2]; +}; + + +enum OPENPLUGININFO_FLAGS { + OPIF_USEFILTER = 0x0001, + OPIF_USESORTGROUPS = 0x0002, + OPIF_USEHIGHLIGHTING = 0x0004, + OPIF_ADDDOTS = 0x0008, + OPIF_RAWSELECTION = 0x0010, + OPIF_REALNAMES = 0x0020, + OPIF_SHOWNAMESONLY = 0x0040, + OPIF_SHOWRIGHTALIGNNAMES = 0x0080, + OPIF_SHOWPRESERVECASE = 0x0100, + OPIF_FINDFOLDERS = 0x0200, + OPIF_COMPAREFATTIME = 0x0400, + OPIF_EXTERNALGET = 0x0800, + OPIF_EXTERNALPUT = 0x1000, + OPIF_EXTERNALDELETE = 0x2000, + OPIF_EXTERNALMKDIR = 0x4000, + OPIF_USEATTRHIGHLIGHTING = 0x8000 +}; + + +enum OPENPLUGININFO_SORTMODES { + SM_DEFAULT,SM_UNSORTED,SM_NAME,SM_EXT,SM_MTIME,SM_CTIME, + SM_ATIME,SM_SIZE,SM_DESCR,SM_OWNER,SM_COMPRESSEDSIZE,SM_NUMLINKS +}; + + +struct KeyBarTitles +{ + char *Titles[12]; + char *CtrlTitles[12]; + char *AltTitles[12]; + char *ShiftTitles[12]; +}; + + +struct OpenPluginInfo +{ + int StructSize; + DWORD Flags; + const char *HostFile; + const char *CurDir; + const char *Format; + const char *PanelTitle; + const struct InfoPanelLine *InfoLines; + int InfoLinesNumber; + const char * const *DescrFiles; + int DescrFilesNumber; + const struct PanelMode *PanelModesArray; + int PanelModesNumber; + int StartPanelMode; + int StartSortMode; + int StartSortOrder; + const struct KeyBarTitles *KeyBar; + const char *ShortcutData; + // long Reserverd; +}; + +enum { + OPEN_DISKMENU, + OPEN_PLUGINSMENU, + OPEN_FINDLIST, + OPEN_SHORTCUT, + OPEN_COMMANDLINE, + OPEN_EDITOR, + OPEN_VIEWER +}; + +enum {PKF_CONTROL=1,PKF_ALT=2,PKF_SHIFT=4}; + +enum FAR_EVENTS { + FE_CHANGEVIEWMODE, + FE_REDRAW, + FE_IDLE, + FE_CLOSE, + FE_BREAK, + FE_COMMAND +}; + +enum OPERATION_MODES { + OPM_SILENT=1, + OPM_FIND=2, + OPM_VIEW=4, + OPM_EDIT=8, + OPM_TOPLEVEL=16, + OPM_DESCR=32 +}; + +#ifndef _WIN64 +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a. +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack() +#else + #pragma pack(pop) +#endif +#endif + +/* +EXTERN_C_BEGIN + + void WINAPI _export ClosePluginW(HANDLE hPlugin); + int WINAPI _export CompareW(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned Mode); + int WINAPI _export ConfigureW(int ItemNumber); + int WINAPI _export DeleteFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + void WINAPI _export ExitFARW(void); + void WINAPI _export FreeFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export FreeVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + int WINAPI _export GetFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t **DestPath,int OpMode); + int WINAPI _export GetFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode); + int WINAPI _export GetMinFarVersionW(void); + void WINAPI _export GetOpenPluginInfoW(HANDLE hPlugin,struct OpenPluginInfo *Info); + void WINAPI _export GetPluginInfoW(struct PluginInfo *Info); + int WINAPI _export GetVirtualFindDataW(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const wchar_t *Path); + int WINAPI _export MakeDirectoryW(HANDLE hPlugin,const wchar_t **Name,int OpMode); + HANDLE WINAPI _export OpenFilePluginW(const wchar_t *Name,const unsigned char *Data,int DataSize,int OpMode); + HANDLE WINAPI _export OpenPluginW(int OpenFrom,INT_PTR Item); + int WINAPI _export ProcessDialogEventW(int Event,void *Param); + int WINAPI _export ProcessEditorEventW(int Event,void *Param); + int WINAPI _export ProcessEditorInputW(const INPUT_RECORD *Rec); + int WINAPI _export ProcessEventW(HANDLE hPlugin,int Event,void *Param); + int WINAPI _export ProcessHostFileW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + int WINAPI _export ProcessKeyW(HANDLE hPlugin,int Key,unsigned ControlState); + int WINAPI _export ProcessSynchroEventW(int Event,void *Param); + int WINAPI _export ProcessViewerEventW(int Event,void *Param); + int WINAPI _export PutFilesW(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,const wchar_t *SrcPath,int OpMode); + int WINAPI _export SetDirectoryW(HANDLE hPlugin,const wchar_t *Dir,int OpMode); + int WINAPI _export SetFindListW(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export SetStartupInfoW(const struct PluginStartupInfo *Info); + +EXTERN_C_END +*/ +EXTERN_C_BEGIN + + void WINAPI _export ClosePlugin(HANDLE hPlugin); + int WINAPI _export Compare(HANDLE hPlugin,const struct PluginPanelItem *Item1,const struct PluginPanelItem *Item2,unsigned Mode); + int WINAPI _export Configure(int ItemNumber); + int WINAPI _export DeleteFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + void WINAPI _export ExitFAR(void); + void WINAPI _export FreeFindData(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export FreeVirtualFindData(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber); + int WINAPI _export GetFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,char *DestPath,int OpMode); + int WINAPI _export GetFindData(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode); + int WINAPI _export GetMinFarVersion(void); + void WINAPI _export GetOpenPluginInfo(HANDLE hPlugin,struct OpenPluginInfo *Info); + void WINAPI _export GetPluginInfo(struct PluginInfo *Info); + int WINAPI _export GetVirtualFindData(HANDLE hPlugin,struct PluginPanelItem **pPanelItem,int *pItemsNumber,const char *Path); + int WINAPI _export MakeDirectory(HANDLE hPlugin,char *Name,int OpMode); + HANDLE WINAPI _export OpenFilePlugin(char *Name,const BYTE *Data,int DataSize); + HANDLE WINAPI _export OpenPlugin(int OpenFrom,INT_PTR Item); + int WINAPI _export ProcessDialogEvent(int Event,void *Param); + int WINAPI _export ProcessEditorEvent(int Event,void *Param); + int WINAPI _export ProcessEditorInput(const INPUT_RECORD *Rec); + int WINAPI _export ProcessEvent(HANDLE hPlugin,int Event,void *Param); + int WINAPI _export ProcessHostFile(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode); + int WINAPI _export ProcessKey(HANDLE hPlugin,int Key,unsigned ControlState); + int WINAPI _export ProcessViewerEvent(int Event,void *Param); + int WINAPI _export PutFiles(HANDLE hPlugin,struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,int OpMode); + int WINAPI _export SetDirectory(HANDLE hPlugin,const char *Dir,int OpMode); + int WINAPI _export SetFindList(HANDLE hPlugin,const struct PluginPanelItem *PanelItem,int ItemsNumber); + void WINAPI _export SetStartupInfo(const struct PluginStartupInfo *Info); + +EXTERN_C_END + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/FarUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/FarUtils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -0,0 +1,524 @@ +// FarUtils.cpp + +#include "StdAfx.h" + +// #include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#ifndef UNDER_CE +#include "../../../Windows/Console.h" +#endif +#include "../../../Windows/Defs.h" +#include "../../../Windows/ErrorMsg.h" + +#include "FarUtils.h" + +using namespace NWindows; + +namespace NFar { + +CStartupInfo g_StartupInfo; + +const char kRegistryKeyDelimiter = '\\'; + +void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo, + const char *pluginNameForRegistry) +{ + m_Data = pluginStartupInfo; + m_RegistryPath = pluginStartupInfo.RootKey; + m_RegistryPath += kRegistryKeyDelimiter; + m_RegistryPath += pluginNameForRegistry; +} + +const char *CStartupInfo::GetMsgString(int messageId) +{ + return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId); +} + +int CStartupInfo::ShowMessage(UInt32 flags, + const char *helpTopic, const char **items, unsigned numItems, int numButtons) +{ + return m_Data.Message(m_Data.ModuleNumber, flags, helpTopic, + items, (int)numItems, numButtons); +} + +namespace NMessageID +{ + enum + { + kOk, + kCancel, + kWarning, + kError + }; +} + +int CStartupInfo::ShowWarningWithOk(const char **items, unsigned numItems) +{ + return ShowMessage(FMSG_WARNING | FMSG_MB_OK, NULL, items, numItems, 0); +} + +extern const char *g_PluginName_for_Error; + +void CStartupInfo::SetErrorTitle(AString &s) +{ + if (g_PluginName_for_Error) + { + s += g_PluginName_for_Error; + s += ": "; + } + s += GetMsgString(NMessageID::kError); +} + +/* +int CStartupInfo::ShowErrorMessage(const char *message) +{ + AString s; + SetErrorTitle(s); + const char *items[]= { s, message }; + return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items)); +} +*/ + +int CStartupInfo::ShowErrorMessage2(const char *m1, const char *m2) +{ + AString s; + SetErrorTitle(s); + const char *items[]= { s, m1, m2 }; + return ShowWarningWithOk(items, Z7_ARRAY_SIZE(items)); +} + +static void SplitString(const AString &src, AStringVector &destStrings) +{ + destStrings.Clear(); + AString s; + unsigned len = src.Len(); + if (len == 0) + return; + for (unsigned i = 0; i < len; i++) + { + char c = src[i]; + if (c == '\n') + { + if (!s.IsEmpty()) + { + destStrings.Add(s); + s.Empty(); + } + } + else + s += c; + } + if (!s.IsEmpty()) + destStrings.Add(s); +} + +int CStartupInfo::ShowErrorMessage(const char *message) +{ + AStringVector strings; + SplitString((AString)message, strings); + const unsigned kNumStringsMax = 20; + const char *items[kNumStringsMax + 1]; + unsigned pos = 0; + items[pos++] = GetMsgString(NMessageID::kError); + for (unsigned i = 0; i < strings.Size() && pos < kNumStringsMax; i++) + items[pos++] = strings[i]; + items[pos++] = GetMsgString(NMessageID::kOk); + + return ShowMessage(FMSG_WARNING, NULL, items, pos, 1); +} + +/* +int CStartupInfo::ShowMessageLines(const char *message) +{ + AString s = GetMsgString(NMessageID::kError); + s.Add_LF(); + s += message; + return ShowMessage(FMSG_WARNING | FMSG_MB_OK | FMSG_ALLINONE, NULL, + (const char **)(const char *)s, 1, 0); +} +*/ + +int CStartupInfo::ShowMessage(int messageId) +{ + return ShowErrorMessage(GetMsgString(messageId)); +} + +int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, unsigned numItems) +{ + return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, const_cast(helpTopic), + items, (int)numItems); +} + +int CStartupInfo::ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, unsigned numItems) +{ + return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems); +} + +inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); } + +void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, unsigned numItems) +{ + for (unsigned i = 0; i < numItems; i++) + { + const CInitDialogItem &srcItem = srcItems[i]; + FarDialogItem &destItem = destItems[i]; + + destItem.Type = srcItem.Type; + destItem.X1 = srcItem.X1; + destItem.Y1 = srcItem.Y1; + destItem.X2 = srcItem.X2; + destItem.Y2 = srcItem.Y2; + destItem.Focus = GetBOOLValue(srcItem.Focus); + if (srcItem.HistoryName != NULL) + destItem.History = srcItem.HistoryName; + else + destItem.Selected = GetBOOLValue(srcItem.Selected); + destItem.Flags = srcItem.Flags; + destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton); + + if (srcItem.DataMessageId < 0) + MyStringCopy(destItem.Data, srcItem.DataString); + else + MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId)); + + /* + if ((unsigned)Init[i].Data < 0xFFF) + MyStringCopy(destItem.Data, GetMsg((unsigned)srcItem.Data)); + else + MyStringCopy(destItem.Data,srcItem.Data); + */ + } +} + +// -------------------------------------------- + +HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2) +{ + return m_Data.SaveScreen(X1, Y1, X2, Y2); +} + +HANDLE CStartupInfo::SaveScreen() +{ + return SaveScreen(0, 0, -1, -1); +} + +void CStartupInfo::RestoreScreen(HANDLE handle) +{ + m_Data.RestoreScreen(handle); +} + +CSysString CStartupInfo::GetFullKeyName(const char *keyName) const +{ + AString s (m_RegistryPath); + if (keyName && *keyName) + { + s += kRegistryKeyDelimiter; + s += keyName; + } + return (CSysString)s; +} + + +LONG CStartupInfo::CreateRegKey(HKEY parentKey, + const char *keyName, NRegistry::CKey &destKey) const +{ + return destKey.Create(parentKey, GetFullKeyName(keyName)); +} + +LONG CStartupInfo::OpenRegKey(HKEY parentKey, + const char *keyName, NRegistry::CKey &destKey) const +{ + return destKey.Open(parentKey, GetFullKeyName(keyName)); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, LPCTSTR value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, UInt32 value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, bool value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, const CSysString &valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + CSysString value; + if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, UInt32 valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + UInt32 value; + if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, bool valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + bool value; + if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param) +{ + return BOOLToBool(m_Data.Control(pluginHandle, command, param)); +} + +bool CStartupInfo::ControlRequestActivePanel(int command, void *param) +{ + return Control(INVALID_HANDLE_VALUE, command, param); +} + +bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo); +} + +bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo); +} + +bool CStartupInfo::ControlGetActivePanelCurrentItemInfo( + PluginPanelItem &pluginPanelItem) +{ + PanelInfo panelInfo; + if (!ControlGetActivePanelInfo(panelInfo)) + return false; + if (panelInfo.ItemsNumber <= 0) + throw "There are no items"; + pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem]; + return true; +} + +bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems) +{ + pluginPanelItems.Clear(); + PanelInfo panelInfo; + if (!ControlGetActivePanelInfo(panelInfo)) + return false; + if (panelInfo.ItemsNumber <= 0) + throw "There are no items"; + if (panelInfo.SelectedItemsNumber == 0) + pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]); + else + for (int i = 0; i < panelInfo.SelectedItemsNumber; i++) + pluginPanelItems.Add(panelInfo.SelectedItems[i]); + return true; +} + +bool CStartupInfo::ControlClearPanelSelection() +{ + PanelInfo panelInfo; + if (!ControlGetActivePanelInfo(panelInfo)) + return false; + for (int i = 0; i < panelInfo.ItemsNumber; i++) + panelInfo.PanelItems[i].Flags &= ~(DWORD)PPIF_SELECTED; + return ControlSetSelection(panelInfo); +} + +//////////////////////////////////////////////// +// menu function + +int CStartupInfo::Menu( + int x, + int y, + int maxHeight, + unsigned flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + struct FarMenuItem *items, + unsigned numItems) +{ + return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, + const_cast(title), + const_cast(aBottom), + const_cast(helpTopic), + breakKeys, breakCode, items, (int)numItems); +} + +int CStartupInfo::Menu( + unsigned flags, + const char *title, + const char *helpTopic, + struct FarMenuItem *items, + unsigned numItems) +{ + return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL, + NULL, items, numItems); +} + +int CStartupInfo::Menu( + unsigned flags, + const char *title, + const char *helpTopic, + const AStringVector &items, + int selectedItem) +{ + CRecordVector farMenuItems; + FOR_VECTOR (i, items) + { + FarMenuItem item; + item.Checked = 0; + item.Separator = 0; + item.Selected = ((int)i == selectedItem); + const AString reducedString (items[i].Left(Z7_ARRAY_SIZE(item.Text) - 1)); + MyStringCopy(item.Text, reducedString); + farMenuItems.Add(item); + } + return Menu(flags, title, helpTopic, farMenuItems.NonConstData(), farMenuItems.Size()); +} + + +////////////////////////////////// +// CScreenRestorer + +CScreenRestorer::~CScreenRestorer() +{ + Restore(); +} +void CScreenRestorer::Save() +{ + if (m_Saved) + return; + m_HANDLE = g_StartupInfo.SaveScreen(); + m_Saved = true; +} + +void CScreenRestorer::Restore() +{ + if (m_Saved) + { + g_StartupInfo.RestoreScreen(m_HANDLE); + m_Saved = false; + } +} + +int PrintErrorMessage(const char *message, unsigned code) +{ + AString s (message); + s += " #"; + s.Add_UInt32((UInt32)code); + return g_StartupInfo.ShowErrorMessage(s); +} + +int PrintErrorMessage(const char *message, const char *text) +{ + return g_StartupInfo.ShowErrorMessage2(message, text); +} + + +void ReduceString(UString &s, unsigned size) +{ + if (s.Len() > size) + { + if (size > 5) + size -= 5; + s.Delete(size / 2, s.Len() - size); + s.Insert(size / 2, L" ... "); + } +} + +int PrintErrorMessage(const char *message, const wchar_t *name, unsigned maxLen) +{ + UString s = name; + ReduceString(s, maxLen); + return PrintErrorMessage(message, UnicodeStringToMultiByte(s, CP_OEMCP)); +} + +int ShowSysErrorMessage(DWORD errorCode) +{ + const UString message = NError::MyFormatMessage(errorCode); + return g_StartupInfo.ShowErrorMessage(UnicodeStringToMultiByte(message, CP_OEMCP)); +} + +int ShowLastErrorMessage() +{ + return ShowSysErrorMessage(::GetLastError()); +} + +int ShowSysErrorMessage(DWORD errorCode, const wchar_t *name) +{ + const UString s = NError::MyFormatMessage(errorCode); + return g_StartupInfo.ShowErrorMessage2( + UnicodeStringToMultiByte(s, CP_OEMCP), + UnicodeStringToMultiByte(name, CP_OEMCP)); +} + + +bool WasEscPressed() +{ + #ifdef UNDER_CE + return false; + #else + NConsole::CIn inConsole; + HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE); + if (handle == INVALID_HANDLE_VALUE) + return true; + inConsole.Attach(handle); + for (;;) + { + DWORD numEvents; + if (!inConsole.GetNumberOfEvents(numEvents)) + return true; + if (numEvents == 0) + return false; + + INPUT_RECORD event; + if (!inConsole.ReadEvent(event, numEvents)) + return true; + if (event.EventType == KEY_EVENT && + event.Event.KeyEvent.bKeyDown && + event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) + return true; + } + #endif +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/FarUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/FarUtils.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/FarUtils.h 2023-09-06 09:00:00.000000000 +0000 @@ -0,0 +1,203 @@ +// FarUtils.h + +#ifndef ZIP7_INC_FAR_UTILS_H +#define ZIP7_INC_FAR_UTILS_H + +#include "FarPlugin.h" + +#include "../../../Windows/Registry.h" + +namespace NFar { + +namespace NFileOperationReturnCode +{ + enum EEnum + { + kInterruptedByUser = -1, + kError = 0, + kSuccess = 1 + }; +} + +namespace NEditorReturnCode +{ + enum EEnum + { + kOpenError = 0, + kFileWasChanged = 1, + kFileWasNotChanged = 2, + kInterruptedByUser = 3 + }; +} + +struct CInitDialogItem +{ + DialogItemTypes Type; + int X1,Y1,X2,Y2; + bool Focus; + bool Selected; + UInt32 Flags; //FarDialogItemFlags Flags; + bool DefaultButton; + int DataMessageId; + const char *DataString; + const char *HistoryName; + // void InitToFarDialogItem(struct FarDialogItem &anItemDest); +}; + +class CStartupInfo +{ + PluginStartupInfo m_Data; + AString m_RegistryPath; + + CSysString GetFullKeyName(const char *keyName) const; + LONG CreateRegKey(HKEY parentKey, + const char *keyName, NWindows::NRegistry::CKey &destKey) const; + LONG OpenRegKey(HKEY parentKey, + const char *keyName, NWindows::NRegistry::CKey &destKey) const; + +public: + void Init(const PluginStartupInfo &pluginStartupInfo, + const char *pluginNameForRegistry); + const char *GetMsgString(int messageId); + + int ShowMessage(UInt32 flags, const char *helpTopic, + const char **items, unsigned numItems, int numButtons); + int ShowWarningWithOk(const char **items, unsigned numItems); + + void SetErrorTitle(AString &s); + int ShowErrorMessage(const char *message); + int ShowErrorMessage2(const char *m1, const char *m2); + // int ShowMessageLines(const char *messageLines); + int ShowMessage(int messageId); + + int ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, unsigned numItems); + int ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, unsigned numItems); + + void InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, unsigned numItems); + + HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); + HANDLE SaveScreen(); + void RestoreScreen(HANDLE handle); + + void SetRegKeyValue(HKEY parentKey, const char *keyName, + const LPCTSTR valueName, LPCTSTR value) const; + void SetRegKeyValue(HKEY hRoot, const char *keyName, + const LPCTSTR valueName, UInt32 value) const; + void SetRegKeyValue(HKEY hRoot, const char *keyName, + const LPCTSTR valueName, bool value) const; + + CSysString QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, const CSysString &valueDefault) const; + + UInt32 QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, UInt32 valueDefault) const; + + bool QueryRegKeyValue(HKEY parentKey, const char *keyName, + LPCTSTR valueName, bool valueDefault) const; + + bool Control(HANDLE plugin, int command, void *param); + bool ControlRequestActivePanel(int command, void *param); + bool ControlGetActivePanelInfo(PanelInfo &panelInfo); + bool ControlSetSelection(const PanelInfo &panelInfo); + bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &pluginPanelItem); + bool ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems); + + bool ControlClearPanelSelection(); + + int Menu( + int x, + int y, + int maxHeight, + unsigned flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + FarMenuItem *items, + unsigned numItems); + int Menu( + unsigned flags, + const char *title, + const char *helpTopic, + FarMenuItem *items, + unsigned numItems); + + int Menu( + unsigned flags, + const char *title, + const char *helpTopic, + const AStringVector &items, + int selectedItem); + + int Editor(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar) + { return m_Data.Editor(const_cast(fileName), const_cast(title), X1, Y1, X2, Y2, + flags, startLine, startChar); } + int Editor(const char *fileName) + { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); } + + int Viewer(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags) + { return m_Data.Viewer(const_cast(fileName), const_cast(title), X1, Y1, X2, Y2, flags); } + int Viewer(const char *fileName) + { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } + +}; + +class CScreenRestorer +{ + bool m_Saved; + HANDLE m_HANDLE; +public: + CScreenRestorer(): m_Saved(false) {} + ~CScreenRestorer(); + void Save(); + void Restore(); +}; + + +extern CStartupInfo g_StartupInfo; + + +int PrintErrorMessage(const char *message, unsigned code); +int PrintErrorMessage(const char *message, const char *text); +int PrintErrorMessage(const char *message, const wchar_t *name, unsigned maxLen = 70); + +#define MY_TRY_BEGIN try { + +#define MY_TRY_END1(x) }\ + catch(unsigned n) { PrintErrorMessage(x, n); return; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return; }\ + catch(const char *s) { PrintErrorMessage(x, s); return; }\ + catch(...) { g_StartupInfo.ShowErrorMessage(x); return; } + +#define MY_TRY_END2(x, y) }\ + catch(unsigned n) { PrintErrorMessage(x, n); return y; }\ + catch(const AString &s) { PrintErrorMessage(x, s); return y; }\ + catch(const char *s) { PrintErrorMessage(x, s); return y; }\ + catch(const UString &s) { PrintErrorMessage(x, s); return y; }\ + catch(const wchar_t *s) { PrintErrorMessage(x, s); return y; }\ + catch(...) { g_StartupInfo.ShowErrorMessage(x); return y; } + + +int ShowSysErrorMessage(DWORD errorCode); +int ShowSysErrorMessage(DWORD errorCode, const wchar_t *name); +int ShowLastErrorMessage(); + +inline int ShowSysErrorMessage(HRESULT errorCode) + { return ShowSysErrorMessage((DWORD)errorCode); } +inline int ShowSysErrorMessage(HRESULT errorCode, const wchar_t *name) + { return ShowSysErrorMessage((DWORD)errorCode, name); } + +bool WasEscPressed(); + +void ReduceString(UString &s, unsigned size); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Messages.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Messages.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/Messages.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Messages.h 2023-03-25 13:00:00.000000000 +0000 @@ -0,0 +1,136 @@ +// Far/Messages.h + +#ifndef ZIP7_INC_FAR_MESSAGES_H +#define ZIP7_INC_FAR_MESSAGES_H + +#include "../../PropID.h" + +namespace NMessageID { + +const unsigned k_Last_PropId_supported_by_plugin = kpidDevMinor; + +enum EEnum +{ + kOk, + kCancel, + + kWarning, + kError, + + kArchiveType, + + kProperties, + + kYes, + kNo, + + kGetPasswordTitle, + kEnterPasswordForFile, + + kExtractTitle, + kExtractTo, + + kExtractPathMode, + kExtractPathFull, + kExtractPathCurrent, + kExtractPathNo, + + kExtractOwerwriteMode, + kExtractOwerwriteAsk, + kExtractOwerwritePrompt, + kExtractOwerwriteSkip, + kExtractOwerwriteAutoRename, + kExtractOwerwriteAutoRenameExisting, + + kExtractFilesMode, + kExtractFilesSelected, + kExtractFilesAll, + + kExtractPassword, + + kExtractExtract, + kExtractCancel, + + kExtractCanNotOpenOutputFile, + + kExtractUnsupportedMethod, + kExtractCRCFailed, + kExtractDataError, + kExtractCRCFailedEncrypted, + kExtractDataErrorEncrypted, + + kOverwriteTitle, + kOverwriteMessage1, + kOverwriteMessageWouldYouLike, + kOverwriteMessageWithtTisOne, + + kOverwriteBytes, + kOverwriteModifiedOn, + + kOverwriteYes, + kOverwriteYesToAll, + kOverwriteNo, + kOverwriteNoToAll, + kOverwriteAutoRename, + kOverwriteCancel, + + kUpdateNotSupportedForThisArchive, + + kDeleteTitle, + kDeleteFile, + kDeleteFiles, + kDeleteNumberOfFiles, + kDeleteDelete, + kDeleteCancel, + + kUpdateTitle, + kUpdateAddToArchive, + + kUpdateMethod, + kUpdateMethod_Store, + kUpdateMethod_Fastest, + kUpdateMethod_Fast, + kUpdateMethod_Normal, + kUpdateMethod_Maximum, + kUpdateMethod_Ultra, + + kUpdateMode, + kUpdateMode_Add, + kUpdateMode_Update, + kUpdateMode_Fresh, + kUpdateMode_Sync, + + kUpdateAdd, + kUpdateSelectArchiver, + + kUpdateSelectArchiverMenuTitle, + + // kArcReadFiles, + + kWaitTitle, + + kReading, + kExtracting, + kDeleting, + kUpdating, + + // kReadingList, + + kMoveIsNotSupported, + + kOpenArchiveMenuString, + kCreateArchiveMenuString, + + kConfigTitle, + + kConfigPluginEnabled, + + // ---------- IDs for Properies (kpid*) ---------- + kNoProperty, + k_Last_MessageID_for_Property = kNoProperty + k_Last_PropId_supported_by_plugin + // ---------- +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/OverwriteDialogFar.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/OverwriteDialogFar.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.cpp 2024-03-13 06:00:00.000000000 +0000 @@ -0,0 +1,145 @@ +// OverwriteDialogFar.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/StringConvert.h" +#include "../../../Common/IntToString.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariantConv.h" + +#include "FarUtils.h" +#include "Messages.h" + +#include "OverwriteDialogFar.h" + +using namespace NWindows; +using namespace NFar; + +namespace NOverwriteDialog { + +struct CFileInfoStrings +{ + AString Size; + AString Time; +}; + +static void SetFileInfoStrings(const CFileInfo &fileInfo, + CFileInfoStrings &fileInfoStrings) +{ + char buffer[256]; + + if (fileInfo.SizeIsDefined) + { + ConvertUInt64ToString(fileInfo.Size, buffer); + fileInfoStrings.Size = buffer; + fileInfoStrings.Size.Add_Space(); + fileInfoStrings.Size += g_StartupInfo.GetMsgString(NMessageID::kOverwriteBytes); + } + else + { + fileInfoStrings.Size = ""; + } + + fileInfoStrings.Time.Empty(); + if (fileInfo.TimeIsDefined) + { + char timeString[64]; + ConvertUtcFileTimeToString(fileInfo.Time, timeString); + fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn); + fileInfoStrings.Time.Add_Space(); + fileInfoStrings.Time += timeString; + } +} + +static void ReduceString2(UString &s, unsigned size) +{ + if (!s.IsEmpty() && s.Back() == ' ') + { + // s += (wchar_t)(0x2423); + s.InsertAtFront(L'\"'); + s += L'\"'; + } + ReduceString(s, size); +} + +NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo) +{ + const int kYSize = 22; + const int kXSize = 76; + + CFileInfoStrings oldFileInfoStrings; + CFileInfoStrings newFileInfoStrings; + + SetFileInfoStrings(oldFileInfo, oldFileInfoStrings); + SetFileInfoStrings(newFileInfo, newFileInfoStrings); + + const UString &oldName2 = oldFileInfo.Name; + const UString &newName2 = newFileInfo.Name; + + int slashPos = oldName2.ReverseFind_PathSepar(); + UString pref1 = oldName2.Left(slashPos + 1); + UString name1 = oldName2.Ptr(slashPos + 1); + + slashPos = newName2.ReverseFind_PathSepar(); + UString pref2 = newName2.Left(slashPos + 1); + UString name2 = newName2.Ptr(slashPos + 1); + + const unsigned kNameOffset = 2; + { + const unsigned maxNameLen = kXSize - 9 - 2; + ReduceString(pref1, maxNameLen); + ReduceString(pref2, maxNameLen); + ReduceString2(name1, maxNameLen - kNameOffset); + ReduceString2(name2, maxNameLen - kNameOffset); + } + + const AString pref1A (UnicodeStringToMultiByte(pref1, CP_OEMCP)); + const AString pref2A (UnicodeStringToMultiByte(pref2, CP_OEMCP)); + const AString name1A (UnicodeStringToMultiByte(name1, CP_OEMCP)); + const AString name2A (UnicodeStringToMultiByte(name2, CP_OEMCP)); + + const struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessage1, NULL, NULL }, + + { DI_TEXT, 3, 3, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_TEXT, 5, 4, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWouldYouLike, NULL, NULL }, + + { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, pref1A, NULL }, + { DI_TEXT, 7 + kNameOffset, 7, 0, 0, false, false, 0, false, -1, name1A, NULL }, + { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 9, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL }, + + { DI_TEXT, 5, 11, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL }, + + { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, pref2A, NULL }, + { DI_TEXT, 7 + kNameOffset, 14, 0, 0, false, false, 0, false, -1, name2A, NULL }, + { DI_TEXT, 7, 15, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 16, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL }, + + { DI_TEXT, 3, kYSize - 5, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 4, 0, 0, true, false, DIF_CENTERGROUP, true, NMessageID::kOverwriteYes, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteYesToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNo, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNoToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteAutoRename, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteCancel, NULL, NULL } + }; + + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); + FarDialogItem aDialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, aDialogItems, kNumDialogItems); + const int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + NULL, aDialogItems, kNumDialogItems); + const int kButtonStartPos = kNumDialogItems - 6; + if (anAskCode >= kButtonStartPos && anAskCode < kNumDialogItems) + return NResult::EEnum(anAskCode - kButtonStartPos); + return NResult::kCancel; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/OverwriteDialogFar.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/OverwriteDialogFar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/OverwriteDialogFar.h 2023-01-22 20:00:00.000000000 +0000 @@ -0,0 +1,37 @@ +// OverwriteDialogFar.h + +#ifndef ZIP7_INC_OVERWRITE_DIALOG_FAR_H +#define ZIP7_INC_OVERWRITE_DIALOG_FAR_H + +#include "../../../Common/MyString.h" +#include "../../../Common/MyTypes.h" + +namespace NOverwriteDialog { + +struct CFileInfo +{ + bool SizeIsDefined; + bool TimeIsDefined; + UInt64 Size; + FILETIME Time; + UString Name; +}; + +namespace NResult +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel + }; +} + +NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Plugin.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/Plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -0,0 +1,926 @@ +// Plugin.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../Common/PropIDUtils.h" + +#include "FarUtils.h" +#include "Messages.h" +#include "Plugin.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NFar; + +// This function is used by CAgentFolder +int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2); +int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2) +{ + return MyStringCompareNoCase(s1, s2); +} + +CPlugin::CPlugin(const FString &fileName, CAgent *agent, UString archiveTypeName): + _agent(agent), + m_FileName(fileName), + _archiveTypeName(archiveTypeName), + PasswordIsDefined(false) +{ + m_ArchiveHandler = agent; + if (!m_FileInfo.Find(m_FileName)) + throw "error"; + m_ArchiveHandler->BindToRootFolder(&_folder); +} + +CPlugin::~CPlugin() {} + +static void MyGetFileTime(IFolderFolder *folder, UInt32 itemIndex, + PROPID propID, FILETIME &fileTime) +{ + NCOM::CPropVariant prop; + if (folder->GetProperty(itemIndex, propID, &prop) != S_OK) + throw 271932; + if (prop.vt == VT_EMPTY) + { + fileTime.dwHighDateTime = 0; + fileTime.dwLowDateTime = 0; + } + else + { + if (prop.vt != VT_FILETIME) + throw 4191730; + fileTime = prop.filetime; + } +} + +#define kDotsReplaceString "[[..]]" + +static void CopyStrLimited(char *dest, const AString &src, unsigned len) +{ + len--; + if (src.Len() < len) + len = src.Len(); + memcpy(dest, src, sizeof(dest[0]) * len); + dest[len] = 0; +} + +#define COPY_STR_LIMITED(dest, src) CopyStrLimited(dest, src, Z7_ARRAY_SIZE(dest)) + +void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UInt32 itemIndex) +{ + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) + throw 271932; + + if (prop.vt != VT_BSTR) + throw 272340; + + AString oemString (UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP)); + if (oemString.IsEqualTo("..")) + oemString = kDotsReplaceString; + + COPY_STR_LIMITED(panelItem.FindData.cFileName, oemString); + panelItem.FindData.cAlternateFileName[0] = 0; + + if (_folder->GetProperty(itemIndex, kpidAttrib, &prop) != S_OK) + throw 271932; + if (prop.vt == VT_UI4) + panelItem.FindData.dwFileAttributes = prop.ulVal; + else if (prop.vt == VT_EMPTY) + panelItem.FindData.dwFileAttributes = m_FileInfo.Attrib; + else + throw 21631; + + if (_folder->GetProperty(itemIndex, kpidIsDir, &prop) != S_OK) + throw 271932; + if (prop.vt == VT_BOOL) + { + if (VARIANT_BOOLToBool(prop.boolVal)) + panelItem.FindData.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + } + else if (prop.vt != VT_EMPTY) + throw 21632; + + if (_folder->GetProperty(itemIndex, kpidSize, &prop) != S_OK) + throw 271932; + UInt64 length = 0; + ConvertPropVariantToUInt64(prop, length); + panelItem.FindData.nFileSizeLow = (UInt32)length; + panelItem.FindData.nFileSizeHigh = (UInt32)(length >> 32); + + MyGetFileTime(_folder, itemIndex, kpidCTime, panelItem.FindData.ftCreationTime); + MyGetFileTime(_folder, itemIndex, kpidATime, panelItem.FindData.ftLastAccessTime); + MyGetFileTime(_folder, itemIndex, kpidMTime, panelItem.FindData.ftLastWriteTime); + + if (panelItem.FindData.ftLastWriteTime.dwHighDateTime == 0 && + panelItem.FindData.ftLastWriteTime.dwLowDateTime == 0) + panelItem.FindData.ftLastWriteTime = m_FileInfo.MTime; + + if (_folder->GetProperty(itemIndex, kpidPackSize, &prop) != S_OK) + throw 271932; + length = 0; + ConvertPropVariantToUInt64(prop, length); + panelItem.PackSize = UInt32(length); + panelItem.PackSizeHigh = UInt32(length >> 32); + + panelItem.Flags = 0; + panelItem.NumberOfLinks = 0; + + panelItem.Description = NULL; + panelItem.Owner = NULL; + panelItem.CustomColumnData = NULL; + panelItem.CustomColumnNumber = 0; + + panelItem.CRC32 = 0; + panelItem.Reserved[0] = 0; + panelItem.Reserved[1] = 0; +} + +int CPlugin::GetFindData(PluginPanelItem **panelItems, int *itemsNumber, int opMode) +{ + // CScreenRestorer screenRestorer; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + /* + screenRestorer.Save(); + const char *msgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReadingList) + }; + g_StartupInfo.ShowMessage(0, NULL, msgItems, Z7_ARRAY_SIZE(msgItems), 0); + */ + } + + UInt32 numItems; + _folder->GetNumberOfItems(&numItems); + *panelItems = new PluginPanelItem[numItems]; + try + { + for (UInt32 i = 0; i < numItems; i++) + { + PluginPanelItem &panelItem = (*panelItems)[i]; + ReadPluginPanelItem(panelItem, i); + panelItem.UserData = i; + } + } + catch(...) + { + delete [](*panelItems); + throw; + } + *itemsNumber = (int)numItems; + return(TRUE); +} + +void CPlugin::FreeFindData(struct PluginPanelItem *panelItems, int itemsNumber) +{ + for (int i = 0; i < itemsNumber; i++) + if (panelItems[i].Description != NULL) + delete []panelItems[i].Description; + delete []panelItems; +} + +void CPlugin::EnterToDirectory(const UString &dirName) +{ + CMyComPtr newFolder; + UString s = dirName; + if (dirName.IsEqualTo(kDotsReplaceString)) + s = ".."; + _folder->BindToFolder(s, &newFolder); + if (!newFolder) + { + if (dirName.IsEmpty()) + return; + else + throw 40325; + } + _folder = newFolder; +} + +int CPlugin::SetDirectory(const char *aszDir, int /* opMode */) +{ + UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP); + if (path.IsEqualTo(STRING_PATH_SEPARATOR)) + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + } + else if (path.IsEqualTo("..")) + { + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + if (!newFolder) + throw 40312; + _folder = newFolder; + } + else if (path.IsEmpty()) + EnterToDirectory(path); + else + { + if (path[0] == WCHAR_PATH_SEPARATOR) + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + path.DeleteFrontal(1); + } + UStringVector pathParts; + SplitPathToParts(path, pathParts); + FOR_VECTOR (i, pathParts) + EnterToDirectory(pathParts[i]); + } + SetCurrentDirVar(); + return TRUE; +} + +void CPlugin::GetPathParts(UStringVector &pathParts) +{ + pathParts.Clear(); + CMyComPtr folderItem = _folder; + for (;;) + { + CMyComPtr newFolder; + folderItem->BindToParentFolder(&newFolder); + if (!newFolder) + break; + NCOM::CPropVariant prop; + if (folderItem->GetFolderProperty(kpidName, &prop) == S_OK) + if (prop.vt == VT_BSTR) + pathParts.Insert(0, (const wchar_t *)prop.bstrVal); + folderItem = newFolder; + } +} + +void CPlugin::SetCurrentDirVar() +{ + m_CurrentDir.Empty(); + + /* + // kpidPath path has tail slash, but we don't need it for compatibility with default FAR style + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) + if (prop.vt == VT_BSTR) + { + m_CurrentDir = (wchar_t *)prop.bstrVal; + // if (!m_CurrentDir.IsEmpty()) + } + m_CurrentDir.InsertAtFront(WCHAR_PATH_SEPARATOR); + */ + + UStringVector pathParts; + GetPathParts(pathParts); + FOR_VECTOR (i, pathParts) + { + m_CurrentDir.Add_PathSepar(); + m_CurrentDir += pathParts[i]; + } +} + +static const char * const kPluginFormatName = "7-ZIP"; + + +static int FindPropNameID(PROPID propID) +{ + if (propID > NMessageID::k_Last_PropId_supported_by_plugin) + return -1; + return NMessageID::kNoProperty + (int)propID; +} + +/* +struct CPropertyIDInfo +{ + PROPID PropID; + const char *FarID; + int Width; + // char CharID; +}; + +static CPropertyIDInfo kPropertyIDInfos[] = +{ + { kpidName, "N", 0}, + { kpidSize, "S", 8}, + { kpidPackSize, "P", 8}, + { kpidAttrib, "A", 0}, + { kpidCTime, "DC", 14}, + { kpidATime, "DA", 14}, + { kpidMTime, "DM", 14}, + + { kpidSolid, NULL, 0, 'S'}, + { kpidEncrypted, NULL, 0, 'P'}, + + { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE }, + { kpidSplitBefore, NULL, 'B'}, + { kpidSplitAfter, NULL, 'A'}, + { kpidComment, NULL, 'C'}, + { kpidCRC, IDS_PROPERTY_CRC } + // { kpidType, L"Type" } +}; + +static const int kNumPropertyIDInfos = Z7_ARRAY_SIZE(kPropertyIDInfos); + +static int FindPropertyInfo(PROPID propID) +{ + for (int i = 0; i < kNumPropertyIDInfos; i++) + if (kPropertyIDInfos[i].PropID == propID) + return i; + return -1; +} +*/ + +// char *g_Titles[] = { "a", "f", "v" }; +/* +static void SmartAddToString(AString &destString, const char *srcString) +{ + if (!destString.IsEmpty()) + destString += ','; + destString += srcString; +} +*/ + +/* +void CPlugin::AddColumn(PROPID propID) +{ + int index = FindPropertyInfo(propID); + if (index >= 0) + { + for (int i = 0; i < m_ProxyHandler->m_InternalProperties.Size(); i++) + { + const CArchiveItemProperty &aHandlerProperty = m_ProxyHandler->m_InternalProperties[i]; + if (aHandlerProperty.ID == propID) + break; + } + if (i == m_ProxyHandler->m_InternalProperties.Size()) + return; + + const CPropertyIDInfo &propertyIDInfo = kPropertyIDInfos[index]; + SmartAddToString(PanelModeColumnTypes, propertyIDInfo.FarID); + char tmp[32]; + itoa(propertyIDInfo.Width, tmp, 10); + SmartAddToString(PanelModeColumnWidths, tmp); + return; + } +} +*/ + +static AString GetNameOfProp(PROPID propID, const wchar_t *name) +{ + int farID = FindPropNameID(propID); + if (farID >= 0) + return (AString)g_StartupInfo.GetMsgString(farID); + if (name) + return UnicodeStringToMultiByte(name, CP_OEMCP); + char s[16]; + ConvertUInt32ToString(propID, s); + return (AString)s; +} + +static AString GetNameOfProp2(PROPID propID, const wchar_t *name) +{ + AString s (GetNameOfProp(propID, name)); + if (s.Len() > (kInfoPanelLineSize - 1)) + s.DeleteFrom(kInfoPanelLineSize - 1); + return s; +} + +static AString ConvertSizeToString(UInt64 value) +{ + char s[32]; + ConvertUInt64ToString(value, s); + unsigned i = MyStringLen(s); + unsigned pos = Z7_ARRAY_SIZE(s); + s[--pos] = 0; + while (i > 3) + { + s[--pos] = s[--i]; + s[--pos] = s[--i]; + s[--pos] = s[--i]; + s[--pos] = ' '; + } + while (i > 0) + s[--pos] = s[--i]; + return (AString)(s + pos); +} + +static AString PropToString(const NCOM::CPropVariant &prop, PROPID propID) +{ + if (prop.vt == VT_BSTR) + { + AString s (UnicodeStringToMultiByte(prop.bstrVal, CP_OEMCP)); + s.Replace((char)0xA, ' '); + s.Replace((char)0xD, ' '); + return s; + } + if (prop.vt == VT_BOOL) + { + int messageID = VARIANT_BOOLToBool(prop.boolVal) ? + NMessageID::kYes : NMessageID::kNo; + return (AString)g_StartupInfo.GetMsgString(messageID); + } + if (prop.vt != VT_EMPTY) + { + if ((prop.vt == VT_UI8 || prop.vt == VT_UI4) && ( + propID == kpidSize || + propID == kpidPackSize || + propID == kpidNumSubDirs || + propID == kpidNumSubFiles || + propID == kpidNumBlocks || + propID == kpidPhySize || + propID == kpidHeadersSize || + propID == kpidClusterSize || + propID == kpidUnpackSize + )) + { + UInt64 v = 0; + ConvertPropVariantToUInt64(prop, v); + return ConvertSizeToString(v); + } + { + char sz[64]; + ConvertPropertyToShortString2(sz, prop, propID); + return (AString)sz; + } + } + return AString(); +} + +static AString PropToString2(const NCOM::CPropVariant &prop, PROPID propID) +{ + AString s (PropToString(prop, propID)); + if (s.Len() > (kInfoPanelLineSize - 1)) + s.DeleteFrom(kInfoPanelLineSize - 1); + return s; +} + +static void AddPropertyString(InfoPanelLine *lines, unsigned &numItems, PROPID propID, const wchar_t *name, + const NCOM::CPropVariant &prop) +{ + if (prop.vt != VT_EMPTY) + { + AString val (PropToString2(prop, propID)); + if (!val.IsEmpty()) + { + InfoPanelLine &item = lines[numItems++]; + COPY_STR_LIMITED(item.Text, GetNameOfProp2(propID, name)); + COPY_STR_LIMITED(item.Data, val); + } + } +} + +static void InsertSeparator(InfoPanelLine *lines, unsigned &numItems) +{ + if (numItems < kNumInfoLinesMax) + { + InfoPanelLine &item = lines[numItems++]; + *item.Text = 0; + *item.Data = 0; + item.Separator = TRUE; + } +} + +void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info) +{ + info->StructSize = sizeof(*info); + info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS | OPIF_USEHIGHLIGHTING | + OPIF_ADDDOTS | OPIF_COMPAREFATTIME; + + COPY_STR_LIMITED(m_FileNameBuffer, UnicodeStringToMultiByte(fs2us(m_FileName), CP_OEMCP)); + info->HostFile = m_FileNameBuffer; // test it it is not static + + COPY_STR_LIMITED(m_CurrentDirBuffer, UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP)); + info->CurDir = m_CurrentDirBuffer; + + info->Format = kPluginFormatName; + + { + UString name; + { + FString dirPrefix, fileName; + GetFullPathAndSplit(m_FileName, dirPrefix, fileName); + name = fs2us(fileName); + } + + m_PannelTitle = ' '; + m_PannelTitle += _archiveTypeName; + m_PannelTitle.Add_Colon(); + m_PannelTitle += name; + m_PannelTitle.Add_Space(); + if (!m_CurrentDir.IsEmpty()) + { + // m_PannelTitle += '\\'; + m_PannelTitle += m_CurrentDir; + } + + COPY_STR_LIMITED(m_PannelTitleBuffer, UnicodeStringToMultiByte(m_PannelTitle, CP_OEMCP)); + info->PanelTitle = m_PannelTitleBuffer; + + } + + memset(m_InfoLines, 0, sizeof(m_InfoLines)); + m_InfoLines[0].Text[0] = 0; + m_InfoLines[0].Separator = TRUE; + + MyStringCopy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType)); + MyStringCopy(m_InfoLines[1].Data, (const char *)UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP)); + + unsigned numItems = 2; + + { + CMyComPtr folderProperties; + _folder.QueryInterface(IID_IFolderProperties, &folderProperties); + if (folderProperties) + { + UInt32 numProps; + if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) + { + for (UInt32 i = 0; i < numProps && numItems < kNumInfoLinesMax; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(propID, &prop) != S_OK || prop.vt == VT_EMPTY) + continue; + + InfoPanelLine &item = m_InfoLines[numItems++]; + COPY_STR_LIMITED(item.Text, GetNameOfProp2(propID, name)); + COPY_STR_LIMITED(item.Data, PropToString2(prop, propID)); + } + } + } + } + + /* + if (numItems < kNumInfoLinesMax) + { + InsertSeparator(m_InfoLines, numItems); + } + */ + + { + CMyComPtr getFolderArcProps; + _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); + if (getFolderArcProps) + { + CMyComPtr getProps; + getFolderArcProps->GetFolderArcProps(&getProps); + if (getProps) + { + UInt32 numLevels; + if (getProps->GetArcNumLevels(&numLevels) != S_OK) + numLevels = 0; + for (UInt32 level2 = 0; level2 < numLevels; level2++) + { + { + UInt32 level = numLevels - 1 - level2; + UInt32 numProps; + if (getProps->GetArcNumProps(level, &numProps) == S_OK) + { + InsertSeparator(m_InfoLines, numItems); + for (Int32 i = -3; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + switch (i) + { + case -3: propID = kpidPath; break; + case -2: propID = kpidType; break; + case -1: propID = kpidError; break; + default: + if (getProps->GetArcPropInfo(level, (UInt32)i, &name, &propID, &vt) != S_OK) + continue; + } + NCOM::CPropVariant prop; + if (getProps->GetArcProp(level, propID, &prop) != S_OK) + continue; + AddPropertyString(m_InfoLines, numItems, propID, name, prop); + } + } + } + if (level2 != numLevels - 1) + { + UInt32 level = numLevels - 1 - level2; + UInt32 numProps; + if (getProps->GetArcNumProps2(level, &numProps) == S_OK) + { + InsertSeparator(m_InfoLines, numItems); + for (Int32 i = 0; i < (Int32)numProps && numItems < kNumInfoLinesMax; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (getProps->GetArcPropInfo2(level, (UInt32)i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (getProps->GetArcProp2(level, propID, &prop) != S_OK) + continue; + AddPropertyString(m_InfoLines, numItems, propID, name, prop); + } + } + } + } + } + } + } + + //m_InfoLines[1].Separator = 0; + + info->InfoLines = m_InfoLines; + info->InfoLinesNumber = (int)numItems; + + + info->DescrFiles = NULL; + info->DescrFilesNumber = 0; + + PanelModeColumnTypes.Empty(); + PanelModeColumnWidths.Empty(); + + /* + AddColumn(kpidName); + AddColumn(kpidSize); + AddColumn(kpidPackSize); + AddColumn(kpidMTime); + AddColumn(kpidCTime); + AddColumn(kpidATime); + AddColumn(kpidAttrib); + + _panelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; + _panelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; + _panelMode.ColumnTitles = NULL; + _panelMode.FullScreen = TRUE; + _panelMode.DetailedStatus = FALSE; + _panelMode.AlignExtensions = FALSE; + _panelMode.CaseConversion = FALSE; + _panelMode.StatusColumnTypes = "N"; + _panelMode.StatusColumnWidths = "0"; + _panelMode.Reserved[0] = 0; + _panelMode.Reserved[1] = 0; + + info->PanelModesArray = &_panelMode; + info->PanelModesNumber = 1; + */ + + info->PanelModesArray = NULL; + info->PanelModesNumber = 0; + + info->StartPanelMode = 0; + info->StartSortMode = 0; + info->KeyBar = NULL; + info->ShortcutData = NULL; +} + +struct CArchiveItemProperty +{ + AString Name; + PROPID ID; + VARTYPE Type; +}; + +static inline char GetHex_A_minus10(unsigned v, unsigned a10) +{ + return (char)(v < 10 ? v + '0' : v + a10); +} + +HRESULT CPlugin::ShowAttributesWindow() +{ + PluginPanelItem pluginPanelItem; + if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + return S_FALSE; + if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 && + NFind::NAttributes::IsDir(pluginPanelItem.FindData.dwFileAttributes)) + return S_FALSE; + const UInt32 itemIndex = (UInt32)pluginPanelItem.UserData; + + CObjectVector properties; + UInt32 numProps; + RINOK(_folder->GetNumberOfProperties(&numProps)) + unsigned i; + for (i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(_folder->GetPropertyInfo(i, &name, &propID, &vt)) + CArchiveItemProperty prop; + prop.Type = vt; + prop.ID = propID; + if (prop.ID == kpidPath) + prop.ID = kpidName; + prop.Name = GetNameOfProp(propID, name); + properties.Add(prop); + } + + int size = 2; + CRecordVector initDialogItems; + + int xSize = 70; + { + const CInitDialogItem idi = + { DI_DOUBLEBOX, 3, 1, xSize - 4, size - 2, false, false, 0, false, NMessageID::kProperties, NULL, NULL }; + initDialogItems.Add(idi); + } + + AStringVector values; + + const int kStartY = 3; + + for (i = 0; i < properties.Size(); i++) + { + const CArchiveItemProperty &property = properties[i]; + + const int startY = kStartY + (int)values.Size(); + + { + CInitDialogItem idi = + { DI_TEXT, 5, startY, 0, 0, false, false, 0, false, 0, NULL, NULL }; + idi.DataMessageId = FindPropNameID(property.ID); + if (idi.DataMessageId < 0) + idi.DataString = property.Name; + initDialogItems.Add(idi); + } + + NCOM::CPropVariant prop; + RINOK(_folder->GetProperty(itemIndex, property.ID, &prop)) + values.Add(PropToString(prop, property.ID)); + + { + const CInitDialogItem idi = + { DI_TEXT, 30, startY, 0, 0, false, false, 0, false, -1, NULL, NULL }; + initDialogItems.Add(idi); + } + } + + CMyComPtr _folderRawProps; + _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps); + + CObjectVector properties2; + + if (_folderRawProps) + { + _folderRawProps->GetNumRawProps(&numProps); + + for (i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + if (_folderRawProps->GetRawPropInfo(i, &name, &propID) != S_OK) + continue; + CArchiveItemProperty prop; + prop.Type = VT_EMPTY; + prop.ID = propID; + if (prop.ID == kpidPath) + prop.ID = kpidName; + prop.Name = GetNameOfProp(propID, name); + properties2.Add(prop); + } + + for (i = 0; i < properties2.Size(); i++) + { + const CArchiveItemProperty &property = properties2[i]; + CMyComBSTR name; + + const void *data; + UInt32 dataSize; + UInt32 propType; + if (_folderRawProps->GetRawProp(itemIndex, property.ID, &data, &dataSize, &propType) != S_OK) + continue; + + if (dataSize != 0) + { + AString s; + if (property.ID == kpidNtSecure) + ConvertNtSecureToString((const Byte *)data, dataSize, s); + else + { + const UInt32 kMaxDataSize = 64; + if (dataSize > kMaxDataSize) + { + s += "data:"; + s.Add_UInt32(dataSize); + } + else + { + const unsigned a = dataSize <= 8 + && (property.ID == kpidCRC || property.ID == kpidChecksum) + ? 'A' - 10 : 'a' - 10; + for (UInt32 k = 0; k < dataSize; k++) + { + const unsigned b = ((const Byte *)data)[k]; + s += GetHex_A_minus10(b >> 4, a); + s += GetHex_A_minus10(b & 15, a); + } + } + } + + const int startY = kStartY + (int)values.Size(); + + { + CInitDialogItem idi = + { DI_TEXT, 5, startY, 0, 0, false, false, 0, false, 0, NULL, NULL }; + idi.DataMessageId = FindPropNameID(property.ID); + if (idi.DataMessageId < 0) + idi.DataString = property.Name; + initDialogItems.Add(idi); + } + + values.Add(s); + + { + const CInitDialogItem idi = + { DI_TEXT, 30, startY, 0, 0, false, false, 0, false, -1, NULL, NULL }; + initDialogItems.Add(idi); + } + } + } + } + + const unsigned numLines = values.Size(); + for (i = 0; i < numLines; i++) + { + CInitDialogItem &idi = initDialogItems[1 + i * 2 + 1]; + idi.DataString = values[i]; + } + + const unsigned numDialogItems = initDialogItems.Size(); + + CObjArray dialogItems(numDialogItems); + g_StartupInfo.InitDialogItems(initDialogItems.ConstData(), dialogItems, numDialogItems); + + unsigned maxLen = 0; + + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2]; + unsigned len = (unsigned)strlen(dialogItem.Data); + if (len > maxLen) + maxLen = len; + } + + unsigned maxLen2 = 0; + const unsigned kSpace = 10; + + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1]; + const unsigned len = (unsigned)strlen(dialogItem.Data); + if (len > maxLen2) + maxLen2 = len; + dialogItem.X1 = (int)(maxLen + kSpace); + } + + size = (int)numLines + 6; + xSize = (int)(maxLen + kSpace + maxLen2 + 5); + FarDialogItem &firstDialogItem = dialogItems[0]; + firstDialogItem.Y2 = size - 2; + firstDialogItem.X2 = xSize - 4; + + /* int askCode = */ g_StartupInfo.ShowDialog(xSize, size, NULL, dialogItems, numDialogItems); + return S_OK; +} + +int CPlugin::ProcessKey(int key, unsigned controlState) +{ + if (key == VK_F7 && controlState == 0) + { + CreateFolder(); + return TRUE; + } + + if (controlState == PKF_CONTROL && key == 'A') + { + HRESULT result = ShowAttributesWindow(); + if (result == S_OK) + return TRUE; + if (result == S_FALSE) + return FALSE; + throw "Error"; + } + + if ((controlState & PKF_ALT) != 0 && key == VK_F6) + { + FString folderPath; + if (!GetOnlyDirPrefix(m_FileName, folderPath)) + return FALSE; + PanelInfo panelInfo; + g_StartupInfo.ControlGetActivePanelInfo(panelInfo); + GetFilesReal(panelInfo.SelectedItems, + (unsigned)panelInfo.SelectedItemsNumber, FALSE, + UnicodeStringToMultiByte(fs2us(folderPath), CP_OEMCP), OPM_SILENT, true); + g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL); + g_StartupInfo.Control(this, FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWANOTHERPANEL, NULL); + return TRUE; + } + + return FALSE; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/Plugin.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/Plugin.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/Plugin.h 2023-09-06 09:00:00.000000000 +0000 @@ -0,0 +1,94 @@ +// 7zip/Far/Plugin.h + +#ifndef ZIP7_INC_7ZIP_FAR_PLUGIN_H +#define ZIP7_INC_7ZIP_FAR_PLUGIN_H + +#include "../../../Common/MyCom.h" + +// #include "../../../Windows/COM.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariant.h" + +#include "../Common/WorkDir.h" + +#include "../Agent/Agent.h" + +#include "FarUtils.h" + +const UInt32 kNumInfoLinesMax = 64; + +class CPlugin +{ + CAgent *_agent; + CMyComPtr m_ArchiveHandler; + CMyComPtr _folder; + + // NWindows::NCOM::CComInitializer m_ComInitializer; + UString m_CurrentDir; + + UString m_PannelTitle; + FString m_FileName; + NWindows::NFile::NFind::CFileInfo m_FileInfo; + + UString _archiveTypeName; + + InfoPanelLine m_InfoLines[kNumInfoLinesMax]; + + char m_FileNameBuffer[1024]; + char m_CurrentDirBuffer[1024]; + char m_PannelTitleBuffer[1024]; + + AString PanelModeColumnTypes; + AString PanelModeColumnWidths; + // PanelMode _panelMode; + void AddColumn(PROPID aPropID); + + void EnterToDirectory(const UString &dirName); + void GetPathParts(UStringVector &pathParts); + void SetCurrentDirVar(); + // HRESULT AfterUpdate(CWorkDirTempFile &tempFile, const UStringVector &pathVector); + +public: + + bool PasswordIsDefined; + UString Password; + + CPlugin(const FString &fileName, CAgent *agent, UString archiveTypeName); + ~CPlugin(); + + void ReadPluginPanelItem(PluginPanelItem &panelItem, UInt32 itemIndex); + + int GetFindData(PluginPanelItem **panelItems,int *itemsNumber,int opMode); + void FreeFindData(PluginPanelItem *panelItem,int ItemsNumber); + int SetDirectory(const char *aszDir, int opMode); + void GetOpenPluginInfo(struct OpenPluginInfo *info); + int DeleteFiles(PluginPanelItem *panelItems, unsigned itemsNumber, int opMode); + + HRESULT ExtractFiles( + bool decompressAllItems, + const UInt32 *indices, + UInt32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password); + + NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *panelItem, unsigned itemsNumber, + int move, char *destPath, int opMode); + + NFar::NFileOperationReturnCode::EEnum GetFilesReal(struct PluginPanelItem *panelItems, + unsigned itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox); + + NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *panelItems, unsigned itemsNumber, + int move, int opMode); + HRESULT CreateFolder(); + + HRESULT ShowAttributesWindow(); + + int ProcessKey(int key, unsigned controlState); +}; + +HRESULT CompressFiles(const CObjectVector &pluginPanelItems); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/PluginCommon.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginCommon.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/PluginCommon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginCommon.cpp 2015-09-28 13:22:09.000000000 +0000 @@ -0,0 +1,50 @@ +// SevenZip/Plugin.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +/* +void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder, + int anIndexInVector, vector &aRealIndexes) +{ + const CArchiveFolderFileItem &anItem = aFolder.m_FileSubItems[anIndexInVector]; + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if (aHandlerItemIndex < 0) + throw "error"; + aRealIndexes.push_back(aHandlerItemIndex); +} + +void CPlugin::AddRealIndexes(const CArchiveFolderItem &anItem, + vector &aRealIndexes) +{ + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if (aHandlerItemIndex >= 0) // test -1 value + aRealIndexes.push_back(aHandlerItemIndex); + for (int i = 0; i < anItem.m_DirSubItems.Size(); i++) + AddRealIndexes(anItem.m_DirSubItems[i], aRealIndexes); + for (i = 0; i < anItem.m_FileSubItems.Size(); i++) + AddRealIndexOfFile(anItem, i , aRealIndexes); +} + + +void CPlugin::GetRealIndexes(PluginPanelItem *aPanelItems, int anItemsNumber, + vector &aRealIndexes) +{ + aRealIndexes.clear(); + for (int i = 0; i < anItemsNumber; i++) + { + int anIndex = aPanelItems[i].UserData; + if (anIndex < m_FolderItem->m_DirSubItems.Size()) + { + const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[anIndex]; + AddRealIndexes(anItem, aRealIndexes); + } + else + AddRealIndexOfFile(*m_FolderItem, anIndex - m_FolderItem->m_DirSubItems.Size(), + aRealIndexes); + } + sort(aRealIndexes.begin(), aRealIndexes.end()); +} + +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/PluginDelete.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginDelete.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/PluginDelete.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginDelete.cpp 2023-03-19 09:00:00.000000000 +0000 @@ -0,0 +1,144 @@ +// PluginDelete.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/StringConvert.h" +#include "FarUtils.h" + +#include "Messages.h" +#include "Plugin.h" +#include "UpdateCallbackFar.h" + +using namespace NFar; + +int CPlugin::DeleteFiles(PluginPanelItem *panelItems, unsigned numItems, int opMode) +{ + if (numItems == 0) + return FALSE; + if (_agent->IsThere_ReadOnlyArc()) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + if ((opMode & OPM_SILENT) == 0) + { + const char *msgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles), + g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete), + g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel) + }; + + // char msg[1024]; + AString str1; + + if (numItems == 1) + { + str1 = g_StartupInfo.GetMsgString(NMessageID::kDeleteFile); + AString name (panelItems[0].FindData.cFileName); + const unsigned kSizeLimit = 48; + if (name.Len() > kSizeLimit) + { + UString s = MultiByteToUnicodeString(name, CP_OEMCP); + ReduceString(s, kSizeLimit); + name = UnicodeStringToMultiByte(s, CP_OEMCP); + } + str1.Replace(AString ("%.40s"), name); + msgItems[1] = str1; + // sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), panelItems[0].FindData.cFileName); + // msgItems[2] = msg; + } + else if (numItems > 1) + { + str1 = g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles); + { + AString n; + n.Add_UInt32(numItems); + str1.Replace(AString ("%d"), n); + } + msgItems[1] = str1; + // sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), numItems); + // msgItems[1] = msg; + } + if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, Z7_ARRAY_SIZE(msgItems), 2) != 0) + return (FALSE); + } + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleting)); + } + + /* + CWorkDirTempFile tempFile; + if (tempFile.CreateTempFile(m_FileName) != S_OK) + return FALSE; + */ + + CObjArray indices(numItems); + unsigned i; + for (i = 0; i < numItems; i++) + indices[i] = (UInt32)panelItems[i].UserData; + + /* + UStringVector pathVector; + GetPathParts(pathVector); + + CMyComPtr outArchive; + HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + */ + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec); + + updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer); + updateCallbackSpec->PasswordIsDefined = PasswordIsDefined; + updateCallbackSpec->Password = Password; + + /* + outArchive->SetFolder(_folder); + result = outArchive->DeleteItems(tempFile.OutStream, indices, numItems, updateCallback); + updateCallback.Release(); + outArchive.Release(); + + if (result == S_OK) + { + result = AfterUpdate(tempFile, pathVector); + } + */ + + HRESULT result; + { + CMyComPtr folderOperations; + result = _folder.QueryInterface(IID_IFolderOperations, &folderOperations); + if (folderOperations) + result = folderOperations->Delete(indices, numItems, updateCallback); + else if (result != S_OK) + result = E_FAIL; + } + + if (result != S_OK) + { + ShowSysErrorMessage(result); + return FALSE; + } + + SetCurrentDirVar(); + return TRUE; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/PluginRead.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginRead.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/PluginRead.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginRead.cpp 2023-03-19 09:00:00.000000000 +0000 @@ -0,0 +1,301 @@ +// PluginRead.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Messages.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileDir.h" + +#include "../Common/ZipRegistry.h" + +#include "ExtractEngine.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NFar; + +static const char * const kHelpTopicExtrFromSevenZip = "Extract"; + +static const char kDirDelimiter = CHAR_PATH_SEPARATOR; + +static const char * const kExractPathHistoryName = "7-ZipExtractPath"; + +HRESULT CPlugin::ExtractFiles( + bool decompressAllItems, + const UInt32 *indices, + UInt32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password) +{ + if (_agent->_isHashHandler) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if (!silent) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kExtracting)); + } + + + CExtractCallbackImp *extractCallbackSpec = new CExtractCallbackImp; + CMyComPtr extractCallback(extractCallbackSpec); + + extractCallbackSpec->Init( + CP_OEMCP, + progressBoxPointer, + /* + GetDefaultName(m_FileName, m_ArchiverInfo.Extension), + m_FileInfo.MTime, m_FileInfo.Attributes, + */ + passwordIsDefined, password); + + if (decompressAllItems) + return m_ArchiveHandler->Extract(pathMode, overwriteMode, + destPath, BoolToInt(false), extractCallback); + else + { + CMyComPtr archiveFolder; + _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); + + return archiveFolder->Extract(indices, numIndices, + BoolToInt(true), // includeAltStreams + BoolToInt(false), // replaceAltStreamChars + pathMode, overwriteMode, + destPath, BoolToInt(false), extractCallback); + } +} + +NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems, + unsigned itemsNumber, int move, char *destPath, int opMode) +{ + return GetFilesReal(panelItems, itemsNumber, move, + destPath, opMode, (opMode & OPM_SILENT) == 0); +} + +NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems, + unsigned itemsNumber, int move, const char *destPathLoc, int opMode, bool showBox) +{ + if (move != 0) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + + AString destPath (destPathLoc); + UString destPathU = GetUnicodeString(destPath, CP_OEMCP); + NName::NormalizeDirPathPrefix(destPathU); + destPath = UnicodeStringToMultiByte(destPathU, CP_OEMCP); + + // bool extractSelectedFiles = true; + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = NExtract::NPathMode::kCurPaths; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite; + + const bool silent = (opMode & OPM_SILENT) != 0; + bool decompressAllItems = false; + UString password = Password; + bool passwordIsDefined = PasswordIsDefined; + + if (!silent) + { + const int kPathIndex = 2; + + extractionInfo.Load(); + + const int kPathModeRadioIndex = 4; + const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4; + const int kNumOverwriteOptions = 6; + const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions; + const int kXSize = 76; + const int kYSize = 19; + const int kPasswordYPos = 12; + + const int kXMid = kXSize / 2; + + AString oemPassword (UnicodeStringToMultiByte(password, CP_OEMCP)); + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL }, + + { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName}, + // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL}, + + { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kFullPaths, + DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kCurPaths, + 0, false, NMessageID::kExtractPathCurrent, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kNoPaths, + false, 0, NMessageID::kExtractPathNo, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAsk, + DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kOverwrite, + 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkip, + 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kRename, + 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kRenameExisting, + 0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL }, + + { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL }, + { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL }, + { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL}, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL } + }; + + const unsigned kNumDialogItems = Z7_ARRAY_SIZE(initItems); + const unsigned kOkButtonIndex = kNumDialogItems - 2; + const unsigned kPasswordIndex = kNumDialogItems - 4; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + for (;;) + { + int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + destPath = dialogItems[kPathIndex].Data; + destPathU = GetUnicodeString(destPath, CP_OEMCP); + destPathU.Trim(); + if (destPathU.IsEmpty()) + { + #ifdef UNDER_CE + destPathU = "\\"; + #else + FString destPathF = us2fs(destPathU); + if (!GetCurrentDir(destPathF)) + throw 318016; + NName::NormalizeDirPathPrefix(destPathF); + destPathU = fs2us(destPathF); + #endif + break; + } + else + { + if (destPathU.Back() == kDirDelimiter) + break; + } + g_StartupInfo.ShowErrorMessage("You must specify directory path"); + } + + if (dialogItems[kPathModeRadioIndex].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kFullPaths; + else if (dialogItems[kPathModeRadioIndex + 1].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kCurPaths; + else if (dialogItems[kPathModeRadioIndex + 2].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kNoPaths; + else + throw 31806; + + if (dialogItems[kOverwriteModeRadioIndex].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAsk; + else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kOverwrite; + else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkip; + else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kRename; + else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kRenameExisting; + else + throw 31806; + + if (dialogItems[kFilesModeIndex].Selected) + decompressAllItems = false; + else if (dialogItems[kFilesModeIndex + 1].Selected) + decompressAllItems = true; + else + throw 31806; + + extractionInfo.Save(); + + if (dialogItems[kFilesModeIndex].Selected) + { + // extractSelectedFiles = true; + } + else if (dialogItems[kFilesModeIndex + 1].Selected) + { + // extractSelectedFiles = false; + } + else + throw 31806; + + oemPassword = dialogItems[kPasswordIndex].Data; + password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); + passwordIsDefined = !password.IsEmpty(); + } + + CreateComplexDir(us2fs(destPathU)); + + /* + vector realIndices; + if (!decompressAllItems) + GetRealIndexes(panelItems, itemsNumber, realIndices); + */ + CObjArray indices(itemsNumber); + for (unsigned i = 0; i < itemsNumber; i++) + indices[i] = (UInt32)panelItems[i].UserData; + + const HRESULT result = ExtractFiles(decompressAllItems, indices, itemsNumber, + !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode, + destPathU, + passwordIsDefined, password); + // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox, + // extractionInfo, destPath, passwordIsDefined, password); + if (result != S_OK) + { + if (result == E_ABORT) + return NFileOperationReturnCode::kInterruptedByUser; + ShowSysErrorMessage(result); + return NFileOperationReturnCode::kError; + } + + // if (move != 0) + // { + // if (DeleteFiles(panelItems, itemsNumber, opMode) == FALSE) + // return NFileOperationReturnCode::kError; + // } + return NFileOperationReturnCode::kSuccess; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/PluginWrite.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginWrite.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/PluginWrite.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/PluginWrite.cpp 2024-01-24 19:00:00.000000000 +0000 @@ -0,0 +1,840 @@ +// PluginWrite.cpp + +#include "StdAfx.h" + +#include + +#include "Plugin.h" + +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileFind.h" + +#include "../Common/ZipRegistry.h" + +#include "../Agent/Agent.h" + +#include "ProgressBox.h" +#include "Messages.h" +#include "UpdateCallbackFar.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NFar; + +using namespace NUpdateArchive; + +static const char * const kHelpTopic = "Update"; + +static const char * const kArchiveHistoryKeyName = "7-ZipArcName"; + +static const UInt32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 }; + +static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UInt32 method) +{ + CMyComPtr setProperties; + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + { + /* + UStringVector realNames; + realNames.Add(UString("x")); + NCOM::CPropVariant value = (UInt32)method; + CRecordVector names; + FOR_VECTOR (i, realNames) + names.Add(realNames[i]); + RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size())); + */ + NCOM::CPropVariant value = (UInt32)method; + const wchar_t *name = L"x"; + RINOK(setProperties->SetProperties(&name, &value, 1)) + } + return S_OK; +} + +/* +HRESULT CPlugin::AfterUpdate(CWorkDirTempFile &tempFile, const UStringVector &pathVector) +{ + _folder.Release(); + m_ArchiveHandler->Close(); + + RINOK(tempFile.MoveToOriginal(true)); + + RINOK(m_ArchiveHandler->ReOpen(NULL)); // check it + + m_ArchiveHandler->BindToRootFolder(&_folder); + FOR_VECTOR (i, pathVector) + { + CMyComPtr newFolder; + _folder->BindToFolder(pathVector[i], &newFolder); + if (!newFolder) + break; + _folder = newFolder; + } + return S_OK; +} +*/ + +NFileOperationReturnCode::EEnum CPlugin::PutFiles( + struct PluginPanelItem *panelItems, unsigned numItems, + int moveMode, int opMode) +{ + if (moveMode != 0 + && _agent->_isHashHandler) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + + if (numItems <= 0) + return NFileOperationReturnCode::kError; + + if (_agent->IsThere_ReadOnlyArc()) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return NFileOperationReturnCode::kError; + } + + const int kYSize = 14; + const int kXMid = 38; + + NCompression::CInfo compressionInfo; + compressionInfo.Load(); + + unsigned methodIndex = 0; + + unsigned i; + for (i = Z7_ARRAY_SIZE(g_MethodMap); i != 0;) + { + i--; + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + } + + const int kMethodRadioIndex = 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + + { DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + + { DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0, DIF_GROUP, false, NMessageID::kUpdateMethod_Store, NULL, NULL }, + { DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1, 0, false, NMessageID::kUpdateMethod_Fastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2, 0, false, NMessageID::kUpdateMethod_Fast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3, 0, false, NMessageID::kUpdateMethod_Normal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4, 0, false, NMessageID::kUpdateMethod_Maximum, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5, 0, false, NMessageID::kUpdateMethod_Ultra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + + { DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true, DIF_GROUP, false, NMessageID::kUpdateMode_Add, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false, 0, false, NMessageID::kUpdateMode_Update, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false, 0, false, NMessageID::kUpdateMode_Fresh, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false, 0, false, NMessageID::kUpdateMode_Sync, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); + const int kOkButtonIndex = kNumDialogItems - 2; + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + const int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < Z7_ARRAY_SIZE(g_MethodMap); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + const CActionSet *actionSet; + + if (dialogItems[kModeRadioIndex ].Selected) actionSet = &k_ActionSet_Add; + else if (dialogItems[kModeRadioIndex + 1].Selected) actionSet = &k_ActionSet_Update; + else if (dialogItems[kModeRadioIndex + 2].Selected) actionSet = &k_ActionSet_Fresh; + else if (dialogItems[kModeRadioIndex + 3].Selected) actionSet = &k_ActionSet_Sync; + else throw 51751; + + compressionInfo.Save(); + + CWorkDirTempFile tempFile; + if (tempFile.CreateTempFile(m_FileName) != S_OK) + return NFileOperationReturnCode::kError; + + + /* + CSysStringVector fileNames; + for (int i = 0; i < numItems; i++) + { + const PluginPanelItem &panelItem = panelItems[i]; + CSysString fullName; + if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName)) + return NFileOperationReturnCode::kError; + fileNames.Add(fullName); + } + */ + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating)); + } + + UStringVector pathVector; + GetPathParts(pathVector); + + UStringVector fileNames; + fileNames.ClearAndReserve(numItems); + for (i = 0; i < (unsigned)numItems; i++) + fileNames.AddInReserved(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP)); + CObjArray fileNamePointers(numItems); + for (i = 0; i < (unsigned)numItems; i++) + fileNamePointers[i] = fileNames[i]; + + CMyComPtr outArchive; + HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return NFileOperationReturnCode::kError; + } + + /* + BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = (BYTE)actionSet->StateActions[i]; + */ + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer); + updateCallbackSpec->PasswordIsDefined = PasswordIsDefined; + updateCallbackSpec->Password = Password; + + if (!_agent->_isHashHandler) + { + if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK) + return NFileOperationReturnCode::kError; + } + + /* + outArchive->SetFolder(_folder); + outArchive->SetFiles(L"", fileNamePointers, numItems); + // FStringVector requestedPaths; + // FStringVector processedPaths; + result = outArchive->DoOperation2( + // &requestedPaths, &processedPaths, + NULL, NULL, + tempFile.OutStream, actionSetByte, NULL, updateCallback); + updateCallback.Release(); + outArchive.Release(); + + if (result == S_OK) + { + result = AfterUpdate(tempFile, pathVector); + } + */ + + { + result = _agent->SetFiles(L"", fileNamePointers, numItems); + if (result == S_OK) + { + CAgentFolder *agentFolder = NULL; + { + CMyComPtr afi; + _folder.QueryInterface(IID_IArchiveFolderInternal, &afi); + if (afi) + afi->GetAgentFolder(&agentFolder); + } + if (agentFolder) + result = agentFolder->CommonUpdateOperation(AGENT_OP_Uni, + (moveMode != 0), NULL, actionSet, NULL, 0, updateCallback); + else + result = E_FAIL; + } + } + + if (result != S_OK) + { + ShowSysErrorMessage(result); + return NFileOperationReturnCode::kError; + } + + return NFileOperationReturnCode::kSuccess; +} + +namespace NPathType +{ + enum EEnum + { + kLocal, + kUNC + }; + EEnum GetPathType(const UString &path); +} + +struct CParsedPath +{ + UString Prefix; // Disk or UNC with slash + UStringVector PathParts; + void ParsePath(const UString &path); + UString MergePath() const; +}; + +static const char kDirDelimiter = CHAR_PATH_SEPARATOR; +static const wchar_t kDiskDelimiter = L':'; + +namespace NPathType +{ + EEnum GetPathType(const UString &path) + { + if (path.Len() <= 2) + return kLocal; + if (path[0] == kDirDelimiter && path[1] == kDirDelimiter) + return kUNC; + return kLocal; + } +} + +void CParsedPath::ParsePath(const UString &path) +{ + int curPos = 0; + switch (NPathType::GetPathType(path)) + { + case NPathType::kLocal: + { + const int posDiskDelimiter = path.Find(kDiskDelimiter); + if (posDiskDelimiter >= 0) + { + curPos = posDiskDelimiter + 1; + if ((int)path.Len() > curPos) + if (path[curPos] == kDirDelimiter) + curPos++; + } + break; + } + case NPathType::kUNC: + { + // the bug was fixed: + curPos = path.Find((wchar_t)kDirDelimiter, 2); + if (curPos < 0) + curPos = (int)path.Len(); + else + curPos++; + } + } + Prefix = path.Left(curPos); + SplitPathToParts(path.Ptr(curPos), PathParts); +} + +UString CParsedPath::MergePath() const +{ + UString result = Prefix; + FOR_VECTOR (i, PathParts) + { + if (i != 0) + // result += kDirDelimiter; + result.Add_PathSepar(); + result += PathParts[i]; + } + return result; +} + + +static void SetArcName(UString &arcName, const CArcInfoEx &arcInfo) +{ + if (!arcInfo.Flags_KeepName()) + { + int dotPos = arcName.ReverseFind_Dot(); + int slashPos = arcName.ReverseFind_PathSepar(); + if (dotPos > slashPos + 1) + arcName.DeleteFrom(dotPos); + } + arcName.Add_Dot(); + arcName += arcInfo.GetMainExt(); +} + +HRESULT CompressFiles(const CObjectVector &pluginPanelItems) +{ + if (pluginPanelItems.Size() == 0) + return E_FAIL; + + UStringVector fileNames; + { + FOR_VECTOR (i, pluginPanelItems) + { + const PluginPanelItem &panelItem = pluginPanelItems[i]; + if (strcmp(panelItem.FindData.cFileName, "..") == 0 && + NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes)) + return E_FAIL; + if (strcmp(panelItem.FindData.cFileName, ".") == 0 && + NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes)) + return E_FAIL; + FString fullPath; + FString fileNameUnicode = us2fs(MultiByteToUnicodeString(panelItem.FindData.cFileName, CP_OEMCP)); + if (!MyGetFullPathName(fileNameUnicode, fullPath)) + return E_FAIL; + fileNames.Add(fs2us(fullPath)); + } + } + + NCompression::CInfo compressionInfo; + compressionInfo.Load(); + + int archiverIndex = -1; + + /* + CCodecs *codecs = new CCodecs; + CMyComPtr compressCodecsInfo = codecs; + if (codecs->Load() != S_OK) + throw "Can't load 7-Zip codecs"; + */ + + if (LoadGlobalCodecs() != S_OK) + throw "Can't load 7-Zip codecs"; + + CCodecs *codecs = g_CodecsObj; + + { + FOR_VECTOR (i, codecs->Formats) + { + const CArcInfoEx &arcInfo = codecs->Formats[i]; + if (arcInfo.UpdateEnabled) + { + if (archiverIndex == -1) + archiverIndex = (int)i; + if (MyStringCompareNoCase(arcInfo.Name, compressionInfo.ArcType) == 0) + archiverIndex = (int)i; + } + } + } + + if (archiverIndex < 0) + throw "there is no output handler"; + + UString resultPath; + { + CParsedPath parsedPath; + parsedPath.ParsePath(fileNames.Front()); + if (parsedPath.PathParts.Size() == 0) + return E_FAIL; + if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1) + { + // CSysString pureName, dot, extension; + resultPath = parsedPath.PathParts.Back(); + } + else + { + parsedPath.PathParts.DeleteBack(); + resultPath = parsedPath.PathParts.Back(); + } + } + UString archiveNameSrc = resultPath; + UString arcName = archiveNameSrc; + + int prevFormat = archiverIndex; + SetArcName(arcName, codecs->Formats[archiverIndex]); + + const CActionSet *actionSet = &k_ActionSet_Add; + + for (;;) + { + AString archiveNameA (UnicodeStringToMultiByte(arcName, CP_OEMCP)); + const int kYSize = 16; + const int kXMid = 38; + + const int kArchiveNameIndex = 2; + const int kMethodRadioIndex = kArchiveNameIndex + 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + // char updateAddToArchiveString[512]; + AString str1; + { + const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex]; + const AString s (UnicodeStringToMultiByte(arcInfo.Name, CP_OEMCP)); + str1 = g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive); + str1.Replace(AString ("%s"), s); + /* + sprintf(updateAddToArchiveString, + g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), (const char *)s); + */ + } + + unsigned methodIndex = 0; + unsigned i; + for (i = Z7_ARRAY_SIZE(g_MethodMap); i != 0;) + { + i--; + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + } + + const struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, str1, NULL }, + + { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName}, + // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, arcName, NULL}, + + { DI_SINGLEBOX, 4, 4, kXMid - 2, 4 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + + { DI_RADIOBUTTON, 6, 5, 0, 0, false, methodIndex == 0, DIF_GROUP, false, NMessageID::kUpdateMethod_Store, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, methodIndex == 1, 0, false, NMessageID::kUpdateMethod_Fastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, methodIndex == 2, 0, false, NMessageID::kUpdateMethod_Fast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, methodIndex == 3, 0, false, NMessageID::kUpdateMethod_Normal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 9, 0, 0, false, methodIndex == 4, 0, false, NMessageID::kUpdateMethod_Maximum, NULL, NULL }, + { DI_RADIOBUTTON, 6,10, 0, 0, false, methodIndex == 5, 0, false, NMessageID::kUpdateMethod_Ultra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 4, 70, 4 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, actionSet == &k_ActionSet_Add, DIF_GROUP, false, NMessageID::kUpdateMode_Add, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, actionSet == &k_ActionSet_Update, 0, false, NMessageID::kUpdateMode_Update, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, actionSet == &k_ActionSet_Fresh, 0, false, NMessageID::kUpdateMode_Fresh, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, actionSet == &k_ActionSet_Sync, 0, false, NMessageID::kUpdateMode_Sync, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kUpdateSelectArchiver, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); + + const int kOkButtonIndex = kNumDialogItems - 3; + const int kSelectarchiverButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + + archiveNameA = dialogItems[kArchiveNameIndex].Data; + archiveNameA.Trim(); + MultiByteToUnicodeString2(arcName, archiveNameA, CP_OEMCP); + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < Z7_ARRAY_SIZE(g_MethodMap); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + if (dialogItems[kModeRadioIndex ].Selected) actionSet = &k_ActionSet_Add; + else if (dialogItems[kModeRadioIndex + 1].Selected) actionSet = &k_ActionSet_Update; + else if (dialogItems[kModeRadioIndex + 2].Selected) actionSet = &k_ActionSet_Fresh; + else if (dialogItems[kModeRadioIndex + 3].Selected) actionSet = &k_ActionSet_Sync; + else throw 51751; + + if (askCode == kSelectarchiverButtonIndex) + { + CUIntVector indices; + AStringVector archiverNames; + FOR_VECTOR (k, codecs->Formats) + { + const CArcInfoEx &arc = codecs->Formats[k]; + if (arc.UpdateEnabled) + { + indices.Add(k); + archiverNames.Add(GetOemString(arc.Name)); + } + } + + const int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT, + g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle), + NULL, archiverNames, archiverIndex); + if (index >= 0) + { + const CArcInfoEx &prevArchiverInfo = codecs->Formats[prevFormat]; + if (prevArchiverInfo.Flags_KeepName()) + { + const UString &prevExtension = prevArchiverInfo.GetMainExt(); + const unsigned prevExtensionLen = prevExtension.Len(); + if (arcName.Len() >= prevExtensionLen && + MyStringCompareNoCase(arcName.RightPtr(prevExtensionLen), prevExtension) == 0) + { + const unsigned pos = arcName.Len() - prevExtensionLen; + if (pos > 2) + { + if (arcName[pos - 1] == '.') + arcName.DeleteFrom(pos - 1); + } + } + } + + archiverIndex = (int)indices[index]; + const CArcInfoEx &arcInfo = codecs->Formats[archiverIndex]; + prevFormat = archiverIndex; + + if (arcInfo.Flags_KeepName()) + arcName = archiveNameSrc; + SetArcName(arcName, arcInfo); + } + continue; + } + + if (askCode != kOkButtonIndex) + return E_ABORT; + + break; + } + + const CArcInfoEx &archiverInfoFinal = codecs->Formats[archiverIndex]; + compressionInfo.ArcType = archiverInfoFinal.Name; + compressionInfo.Save(); + + NWorkDir::CInfo workDirInfo; + workDirInfo.Load(); + + FString fullArcName; + if (!MyGetFullPathName(us2fs(arcName), fullArcName)) + return E_FAIL; + + CWorkDirTempFile tempFile; + RINOK(tempFile.CreateTempFile(fullArcName)) + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating)); + + + NFind::CFileInfo fileInfo; + + CMyComPtr outArchive; + + CMyComPtr archiveHandler; + if (fileInfo.Find(fullArcName)) + { + if (fileInfo.IsDir()) + throw "There is Directory with such name"; + + CAgent *agentSpec = new CAgent; + archiveHandler = agentSpec; + // CLSID realClassID; + CMyComBSTR archiveType; + RINOK(archiveHandler->Open(NULL, + GetUnicodeString(fullArcName, CP_OEMCP), UString(), + // &realClassID, + &archiveType, + NULL)) + + if (MyStringCompareNoCase(archiverInfoFinal.Name, (const wchar_t *)archiveType) != 0) + throw "Type of existing archive differs from specified type"; + const HRESULT result = archiveHandler.QueryInterface( + IID_IOutFolderArchive, &outArchive); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + } + else + { + // HRESULT result = outArchive.CoCreateInstance(classID); + CAgent *agentSpec = new CAgent; + outArchive = agentSpec; + + /* + HRESULT result = outArchive.CoCreateInstance(CLSID_CAgentArchiveHandler); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + */ + } + + CObjArray fileNamePointers(fileNames.Size()); + + unsigned i; + for (i = 0; i < fileNames.Size(); i++) + fileNamePointers[i] = fileNames[i]; + + outArchive->SetFolder(NULL); + outArchive->SetFiles(L"", fileNamePointers, fileNames.Size()); + BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = (BYTE)actionSet->StateActions[i]; + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(/* archiveHandler, */ progressBoxPointer); + + + RINOK(SetOutProperties(outArchive, compressionInfo.Level)) + + // FStringVector requestedPaths; + // FStringVector processedPaths; + HRESULT result = outArchive->DoOperation( + // &requestedPaths, &processedPaths, + NULL, NULL, + codecs, archiverIndex, + tempFile.OutStream, actionSetByte, + NULL, updateCallback); + updateCallback.Release(); + outArchive.Release(); + + if (result != S_OK) + { + ShowSysErrorMessage(result); + return result; + } + + if (archiveHandler) + { + archiveHandler->Close(); + } + + result = tempFile.MoveToOriginal(archiveHandler != NULL); + if (result != S_OK) + { + ShowSysErrorMessage(result); + return result; + } + return S_OK; +} + + +static const char * const k_CreateFolder_History = "NewFolder"; // we use default FAR folder name + +HRESULT CPlugin::CreateFolder() +{ + if (_agent->IsThere_ReadOnlyArc()) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return TRUE; + } + + UString destPathU; + { + const int kXSize = 60; + const int kYSize = 8; + const int kPathIndex = 2; + + AString destPath ("New Folder"); + + const struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, + -1, "Create Folder", NULL }, + + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, "Folder name:", NULL }, + + { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, k_CreateFolder_History }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kOk, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = Z7_ARRAY_SIZE(initItems); + const int kOkButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + for (;;) + { + int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + NULL, // kHelpTopic + dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return E_ABORT; + destPath = dialogItems[kPathIndex].Data; + destPathU = GetUnicodeString(destPath, CP_OEMCP); + destPathU.Trim(); + if (!destPathU.IsEmpty()) + break; + g_StartupInfo.ShowErrorMessage("You must specify folder name"); + } + + } + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init( + // g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleting)); + } + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec); + + updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer); + updateCallbackSpec->PasswordIsDefined = PasswordIsDefined; + updateCallbackSpec->Password = Password; + + HRESULT result; + { + CMyComPtr folderOperations; + result = _folder.QueryInterface(IID_IFolderOperations, &folderOperations); + if (folderOperations) + result = folderOperations->CreateFolder(destPathU, updateCallback); + else if (result != S_OK) + result = E_FAIL; + } + + if (result != S_OK) + { + ShowSysErrorMessage(result); + return result; + } + + g_StartupInfo.Control(this, FCTL_UPDATEPANEL, (void *)1); + g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL); + + PanelInfo panelInfo; + + if (g_StartupInfo.ControlGetActivePanelInfo(panelInfo)) + { + const AString destPath (GetOemString(destPathU)); + + for (int i = 0; i < panelInfo.ItemsNumber; i++) + { + const PluginPanelItem &pi = panelInfo.PanelItems[i]; + if (strcmp(destPath, pi.FindData.cFileName) == 0) + { + PanelRedrawInfo panelRedrawInfo; + panelRedrawInfo.CurrentItem = i; + panelRedrawInfo.TopPanelItem = 0; + g_StartupInfo.Control(this, FCTL_REDRAWPANEL, &panelRedrawInfo); + break; + } + } + } + + SetCurrentDirVar(); + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/ProgressBox.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/ProgressBox.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.cpp 2023-03-06 17:00:00.000000000 +0000 @@ -0,0 +1,305 @@ +// ProgressBox.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "FarUtils.h" +#include "ProgressBox.h" + +void CPercentPrinterState::ClearCurState() +{ + Completed = 0; + Total = ((UInt64)(Int64)-1); + Files = 0; + FilesTotal = 0; + Command.Empty(); + FileName.Empty(); +} + +void CProgressBox::Init(const char *title) +{ + _title = title; + _wasPrinted = false; + StartTick = GetTickCount(); + _prevTick = StartTick; + _prevElapsedSec = 0; +} + +static unsigned GetPower32(UInt32 val) +{ + const unsigned kStart = 32; + UInt32 mask = ((UInt32)1 << (kStart - 1)); + for (unsigned i = kStart;; i--) + { + if (i == 0 || (val & mask) != 0) + return i; + mask >>= 1; + } +} + +static unsigned GetPower64(UInt64 val) +{ + UInt32 high = (UInt32)(val >> 32); + if (high == 0) + return GetPower32((UInt32)val); + return GetPower32(high) + 32; +} + +static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider) +{ + unsigned pow1 = GetPower64(mult1); + unsigned pow2 = GetPower64(mult2); + while (pow1 + pow2 > 64) + { + if (pow1 > pow2) { pow1--; mult1 >>= 1; } + else { pow2--; mult2 >>= 1; } + divider >>= 1; + } + UInt64 res = mult1 * mult2; + if (divider != 0) + res /= divider; + return res; +} + +#define UINT_TO_STR_2(val) { s[0] = (char)('0' + (val) / 10); s[1] = (char)('0' + (val) % 10); s += 2; } + +static void GetTimeString(UInt64 timeValue, char *s) +{ + const UInt64 hours = timeValue / 3600; + UInt32 seconds = (UInt32)(timeValue - hours * 3600); + const UInt32 minutes = seconds / 60; + seconds %= 60; + if (hours > 99) + { + ConvertUInt64ToString(hours, s); + for (; *s != 0; s++); + } + else + { + const UInt32 hours32 = (UInt32)hours; + UINT_TO_STR_2(hours32) + } + *s++ = ':'; UINT_TO_STR_2(minutes) + *s++ = ':'; UINT_TO_STR_2(seconds) + *s = 0; +} + +void CProgressBox::ReduceString(const UString &src, AString &dest) +{ + UnicodeStringToMultiByte2(dest, src, CP_OEMCP); + + if (dest.Len() <= MaxLen) + return; + unsigned len = FileName.Len(); + for (; len != 0;) + { + unsigned delta = len / 8; + if (delta == 0) + delta = 1; + len -= delta; + _tempU = FileName; + _tempU.Delete(len / 2, FileName.Len() - len); + _tempU.Insert(len / 2, L" . "); + UnicodeStringToMultiByte2(dest, _tempU, CP_OEMCP); + if (dest.Len() <= MaxLen) + return; + } + dest.Empty(); +} + +static void Print_UInt64_and_String(AString &s, UInt64 val, const char *name) +{ + char temp[32]; + ConvertUInt64ToString(val, temp); + s += temp; + s.Add_Space(); + s += name; +} + + +static void PrintSize_bytes_Smart(AString &s, UInt64 val) +{ + // Print_UInt64_and_String(s, val, "bytes"); + { + char temp[32]; + ConvertUInt64ToString(val, temp); + s += temp; + } + + if (val == 0) + return; + + unsigned numBits = 10; + char c = 'K'; + char temp[4] = { 'K', 'i', 'B', 0 }; + if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; } + else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; } + temp[0] = c; + s += " ("; + Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp); + s += ')'; +} + + +static const unsigned kPercentsSize = 4; + +void CProgressBox::Print() +{ + DWORD tick = GetTickCount(); + DWORD elapsedTicks = tick - StartTick; + DWORD elapsedSec = elapsedTicks / 1000; + + if (_wasPrinted) + { + if (elapsedSec == _prevElapsedSec) + { + if ((UInt32)(tick - _prevTick) < _tickStep) + return; + if (_printedState.IsEqualTo((const CPercentPrinterState &)*this)) + return; + } + } + + UInt64 cur = Completed; + UInt64 total = Total; + + if (!UseBytesForPercents) + { + cur = Files; + total = FilesTotal; + } + + { + _timeStr.Empty(); + _timeStr = "Elapsed time: "; + char s[40]; + GetTimeString(elapsedSec, s); + _timeStr += s; + + if (cur != 0) + { + UInt64 remainingTime = 0; + if (cur < total) + remainingTime = MyMultAndDiv(elapsedTicks, total - cur, cur); + UInt64 remainingSec = remainingTime / 1000; + _timeStr += " Remaining time: "; + + GetTimeString(remainingSec, s); + _timeStr += s; + } + } + + + { + _perc.Empty(); + char s[32]; + unsigned size; + { + UInt64 val = 0; + if (total != (UInt64)(Int64)-1 && total != 0) + val = cur * 100 / Total; + + ConvertUInt64ToString(val, s); + size = (unsigned)strlen(s); + s[size++] = '%'; + s[size] = 0; + } + + unsigned len = size; + while (len < kPercentsSize) + len = kPercentsSize; + len++; + + if (len < MaxLen) + { + unsigned numChars = MaxLen - len; + unsigned filled = 0; + if (total != (UInt64)(Int64)-1 && total != 0) + filled = (unsigned)(cur * numChars / total); + if (filled > numChars) + filled = numChars; + unsigned i = 0; + for (i = 0; i < filled; i++) + _perc += (char)(Byte)0xDB; // '='; + for (; i < numChars; i++) + _perc += (char)(Byte)0xB0; // '.'; + } + + _perc.Add_Space(); + while (size < kPercentsSize) + { + _perc.Add_Space(); + size++; + } + _perc += s; + } + + _files.Empty(); + if (Files != 0 || FilesTotal != 0) + { + _files += "Files: "; + char s[32]; + // if (Files != 0) + { + ConvertUInt64ToString(Files, s); + _files += s; + } + if (FilesTotal != 0) + { + _files += " / "; + ConvertUInt64ToString(FilesTotal, s); + _files += s; + } + } + + _sizesStr.Empty(); + if (Total != 0) + { + _sizesStr += "Size: "; + PrintSize_bytes_Smart(_sizesStr, Completed); + if (Total != 0 && Total != (UInt64)(Int64)-1) + { + _sizesStr += " / "; + PrintSize_bytes_Smart(_sizesStr, Total); + } + } + + _name1.Empty(); + _name2.Empty(); + + if (!FileName.IsEmpty()) + { + _name1U.Empty(); + _name2U.Empty(); + + /* + if (_isDir) + s1 = _filePath; + else + */ + { + const int slashPos = FileName.ReverseFind_PathSepar(); + if (slashPos >= 0) + { + _name1U.SetFrom(FileName, (unsigned)(slashPos + 1)); + _name2U = FileName.Ptr(slashPos + 1); + } + else + _name2U = FileName; + } + ReduceString(_name1U, _name1); + ReduceString(_name2U, _name2); + } + + { + const char *strings[] = { _title, _timeStr, _files, _sizesStr, Command, _name1, _name2, _perc }; + NFar::g_StartupInfo.ShowMessage(FMSG_LEFTALIGN, NULL, strings, Z7_ARRAY_SIZE(strings), 0); + } + + _wasPrinted = true; + _printedState = *this; + _prevTick = tick; + _prevElapsedSec = elapsedSec; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/ProgressBox.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/ProgressBox.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/ProgressBox.h 2024-11-08 11:00:00.000000000 +0000 @@ -0,0 +1,85 @@ +// ProgressBox.h + +#ifndef ZIP7_INC_PROGRESS_BOX_H +#define ZIP7_INC_PROGRESS_BOX_H + +#include "../../../Common/MyString.h" +#include "../../../Common/MyTypes.h" + +struct CPercentPrinterState +{ + UInt64 Completed; + UInt64 Total; + + UInt64 Files; + UInt64 FilesTotal; + + AString Command; + UString FileName; + + void ClearCurState(); + + bool IsEqualTo(const CPercentPrinterState &s) const + { + return + Completed == s.Completed + && Total == s.Total + && Files == s.Files + && FilesTotal == s.FilesTotal + && Command == s.Command + && FileName == s.FileName; + } + + CPercentPrinterState(): + Completed(0), + Total((UInt64)(Int64)-1), + Files(0), + FilesTotal(0) + {} +}; + +class CProgressBox: public CPercentPrinterState +{ + UInt32 _tickStep; + DWORD _prevTick; + DWORD _prevElapsedSec; + + bool _wasPrinted; +public: + bool UseBytesForPercents; + DWORD StartTick; + unsigned MaxLen; + +private: + UString _tempU; + UString _name1U; + UString _name2U; + + CPercentPrinterState _printedState; + + AString _title; + + AString _timeStr; + AString _files; + AString _sizesStr; + AString _name1; + AString _name2; + AString _perc; + + void ReduceString(const UString &src, AString &dest); + +public: + + CProgressBox(UInt32 tickStep = 200): + _tickStep(tickStep), + _prevTick(0), + UseBytesForPercents(true), + StartTick(0), + MaxLen(60) + {} + + void Init(const char *title); + void Print(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.cpp 2000-08-28 18:23:14.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/UpdateCallbackFar.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.cpp --- p7zip-rar-16.02/CPP/7zip/UI/Far/UpdateCallbackFar.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.cpp 2024-10-22 09:00:00.000000000 +0000 @@ -0,0 +1,327 @@ +// UpdateCallbackFar.cpp + +#include "StdAfx.h" + +#ifndef Z7_ST +#include "../../../Windows/Synchronization.h" +#endif + +#include "../../../Common/StringConvert.h" + +#include "FarUtils.h" +#include "UpdateCallbackFar.h" + +using namespace NWindows; +using namespace NFar; + +#ifndef Z7_ST +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + +static HRESULT CheckBreak2() +{ + return WasEscPressed() ? E_ABORT : S_OK; +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanProgress(UInt64 numFolders, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */)) +{ + MT_LOCK + + if (_percent) + { + _percent->FilesTotal = numFolders + numFiles; + _percent->Total = totalSize; + _percent->Command = "Scanning"; + _percent->FileName = path; + _percent->Print(); + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode)) +{ + if (ShowSysErrorMessage(errorCode, path) == -1) + return E_ABORT; + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)) +{ + MT_LOCK + + if (_percent) + { + _percent->FilesTotal = numFiles; + _percent->Print(); + } + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + MT_LOCK + return CheckBreak2(); +} + + + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(UInt64 size)) +{ + MT_LOCK + + if (_percent) + { + _percent->Total = size; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 *completeValue)) +{ + MT_LOCK + + if (_percent) + { + if (completeValue) + _percent->Completed = *completeValue; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::CompressOperation(const wchar_t *name)) +{ + MT_LOCK + + if (_percent) + { + _percent->Command = "Adding"; + _percent->FileName = name; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)) +{ + MT_LOCK + + if (_percent) + { + _percent->Command = "Deleting"; + _percent->FileName = name; + _percent->Print(); + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::OperationResult(Int32 /* opRes */)) +{ + MT_LOCK + + if (_percent) + { + _percent->Files++; + } + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)) +{ + MT_LOCK + + if (g_StartupInfo.ShowErrorMessage(UnicodeStringToMultiByte(message, CP_OEMCP)) == -1) + return E_ABORT; + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode)) +{ + if (ShowSysErrorMessage(errorCode, path) == -1) + return E_ABORT; + return CheckBreak2(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode)) +{ + if (ShowSysErrorMessage(errorCode, path) == -1) + return E_ABORT; + return CheckBreak2(); +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &s); + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)) +{ + MT_LOCK + + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + AString s; + SetExtractErrorMessage(opRes, isEncrypted, s); + if (PrintErrorMessage(s, name) == -1) + return E_ABORT; + } + + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportUpdateOperation(UInt32 op, const wchar_t *name, Int32 /* isDir */)) +{ + const char *s; + switch (op) + { + case NUpdateNotifyOp::kAdd: s = "Adding"; break; + case NUpdateNotifyOp::kUpdate: s = "Updating"; break; + case NUpdateNotifyOp::kAnalyze: s = "Analyzing"; break; + case NUpdateNotifyOp::kReplicate: s = "Replicating"; break; + case NUpdateNotifyOp::kRepack: s = "Repacking"; break; + case NUpdateNotifyOp::kSkip: s = "Skipping"; break; + case NUpdateNotifyOp::kHeader: s = "Header creating"; break; + case NUpdateNotifyOp::kDelete: s = "Deleting"; break; + default: s = "Unknown operation"; + } + + MT_LOCK + + if (_percent) + { + _percent->Command = s; + _percent->FileName.Empty(); + if (name) + _percent->FileName = name; + _percent->Print(); + } + + return CheckBreak2(); +} + + +HRESULT CUpdateCallback100Imp::MoveArc_UpdateStatus() +{ + MT_LOCK + + if (_percent) + { + AString s; + s.Add_UInt64(_arcMoving_percents); + // status.Add_Space(); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent->Command = s; + _percent->Print(); + } + + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t * /* destFinalPath */ , UInt64 size, Int32 /* updateMode */)) +{ + MT_LOCK + + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = updateMode; + // _name2 = fs2us(destFinalPath); + if (_percent) + _percent->FileName = srcTempPath; + return MoveArc_UpdateStatus(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) +{ + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + if (percents == _arcMoving_percents) + return CheckBreak2(); + _arcMoving_total = totalSize; + _arcMoving_current = currentSize; + _arcMoving_percents = percents; + // if (_arcMoving_percents > 100) return E_FAIL; + return MoveArc_UpdateStatus(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish()) +{ + // _arcMoving_percents = 0; + if (_percent) + { + _percent->Command.Empty(); + _percent->FileName.Empty(); + _percent->Print(); + } + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen()) +{ + // fixme: we can use Clear_Stop_Status() here + return CheckBreak2(); +} + + +extern HRESULT GetPassword(UString &password); + +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) +{ + MT_LOCK + + *password = NULL; + if (!PasswordIsDefined) + { + RINOK(GetPassword(Password)) + PasswordIsDefined = true; + } + return StringToBstr(Password, password); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +{ + MT_LOCK + + *password = NULL; + *passwordIsDefined = BoolToInt(PasswordIsDefined); + if (!PasswordIsDefined) + return S_OK; + return StringToBstr(Password, password); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/UpdateCallbackFar.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.h --- p7zip-rar-16.02/CPP/7zip/UI/Far/UpdateCallbackFar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/UpdateCallbackFar.h 2024-10-22 09:00:00.000000000 +0000 @@ -0,0 +1,58 @@ +// UpdateCallbackFar.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_FAR_H +#define ZIP7_INC_UPDATE_CALLBACK_FAR_H + +#include "../../../Common/MyCom.h" + +#include "../../IPassword.h" + +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +Z7_CLASS_IMP_COM_7( + CUpdateCallback100Imp + , IFolderArchiveUpdateCallback + , IFolderArchiveUpdateCallback2 + , IFolderArchiveUpdateCallback_MoveArc + , IFolderScanProgress + , ICryptoGetTextPassword2 + , ICryptoGetTextPassword + , IArchiveOpenCallback +) + Z7_IFACE_COM7_IMP(IProgress) + + // CMyComPtr _archiveHandler; + CProgressBox *_percent; + // UInt64 _total; + + HRESULT MoveArc_UpdateStatus(); + +private: + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + // Int32 _arcMoving_updateMode; + +public: + bool PasswordIsDefined; + UString Password; + + CUpdateCallback100Imp() + // : _total(0) + {} + void Init(/* IInFolderArchive *archiveHandler, */ CProgressBox *progressBox) + { + // _archiveHandler = archiveHandler; + _percent = progressBox; + PasswordIsDefined = false; + Password.Empty(); + _arcMoving_total = 0; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = 0; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/makefile --- p7zip-rar-16.02/CPP/7zip/UI/Far/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -0,0 +1,107 @@ +PROG = 7-ZipFar.dll +DEF_FILE = Far.def +CFLAGS = $(CFLAGS) \ + -DZ7_EXTERNAL_CODECS \ + +!IFNDEF UNDER_CE +# CFLAGS = $(CFLAGS) -DZ7_LONG_PATH +# -DZ7_NO_LARGE_PAGES +!ENDIF + +CURRENT_OBJS = \ + $O\ExtractEngine.obj \ + $O\FarUtils.obj \ + $O\Far.obj \ + $O\OverwriteDialogFar.obj \ + $O\Plugin.obj \ + $O\PluginCommon.obj \ + $O\PluginDelete.obj \ + $O\PluginRead.obj \ + $O\PluginWrite.obj \ + $O\ProgressBox.obj \ + $O\UpdateCallbackFar.obj \ + +COMMON_OBJS = \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\MyVector.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodProps.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\ArchiveFolder.obj \ + $O\ArchiveFolderOut.obj \ + $O\UpdateCallbackAgent.obj \ + +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../Sort.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/Far/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/Far/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/Far/resource.rc 2005-07-22 19:25:52.000000000 +0000 @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7-Zip Plugin for FAR Manager", "7-ZipFar") diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/7zFM.exe.manifest p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/7zFM.exe.manifest --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/7zFM.exe.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/7zFM.exe.manifest 2023-04-02 08:00:00.000000000 +0000 @@ -0,0 +1,23 @@ + + + + 7-Zip File Manager. + + + + + + + + + + + + + true + + + + +true + Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/7zipLogo.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/7zipLogo.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -0,0 +1,81 @@ +// AboutDialog.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../MyVersion.h" + +#include "../Common/LoadCodecs.h" + +#include "AboutDialog.h" +#include "PropertyNameRes.h" + +#include "HelpUtils.h" +#include "LangUtils.h" + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_ABOUT_INFO +}; +#endif + +#define kHomePageURL TEXT("https://www.7-zip.org/") +#define kHelpTopic "start.htm" + +#define LLL_(quote) L##quote +#define LLL(quote) LLL_(quote) + +extern CCodecs *g_CodecsObj; + +bool CAboutDialog::OnInit() +{ + #ifdef Z7_EXTERNAL_CODECS + if (g_CodecsObj) + { + UString s; + g_CodecsObj->GetCodecsErrorMessage(s); + if (!s.IsEmpty()) + MessageBoxW(GetParent(), s, L"7-Zip", MB_ICONERROR); + } + #endif + + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_ABOUT); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + SetItemText(IDT_ABOUT_VERSION, UString("7-Zip " MY_VERSION_CPU)); + SetItemText(IDT_ABOUT_DATE, LLL(MY_DATE)); + + NormalizePosition(); + return CModalDialog::OnInit(); +} + +void CAboutDialog::OnHelp() +{ + ShowHelpWindow(kHelpTopic); +} + +bool CAboutDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + LPCTSTR url; + switch (buttonID) + { + case IDB_ABOUT_HOMEPAGE: url = kHomePageURL; break; + default: + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + + #ifdef UNDER_CE + SHELLEXECUTEINFO s; + memset(&s, 0, sizeof(s)); + s.cbSize = sizeof(s); + s.lpFile = url; + ::ShellExecuteEx(&s); + #else + ::ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL); + #endif + + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +// AboutDialog.h + +#ifndef ZIP7_INC_ABOUT_DIALOG_H +#define ZIP7_INC_ABOUT_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" + +#include "AboutDialogRes.h" + +class CAboutDialog: public NWindows::NControl::CModalDialog +{ +public: + virtual bool OnInit() Z7_override; + virtual void OnHelp() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + INT_PTR Create(HWND wndParent = NULL) { return CModalDialog::Create(IDD_ABOUT, wndParent); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialog.rc 2020-09-29 09:59:15.000000000 +0000 @@ -0,0 +1,26 @@ +#include "AboutDialogRes.h" +#include "../../GuiCommon.rc" +#include "../../MyVersion.h" + +#define xc 144 +#define yc 144 + +#define y 93 + +IDI_LOGO ICON "../../UI/FileManager/7zipLogo.ico" + +#ifndef SS_REALSIZEIMAGE +#define SS_REALSIZEIMAGE 0x800 +#endif + +IDD_ABOUT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "About 7-Zip" +{ + DEFPUSHBUTTON "OK", IDOK, bx1, by, bxs, bys + PUSHBUTTON "www.7-zip.org", IDB_ABOUT_HOMEPAGE, bx2, by, bxs, bys + ICON IDI_LOGO, -1, m, m, 32, 32, SS_REALSIZEIMAGE + LTEXT "", IDT_ABOUT_VERSION, m, 54, xc, 8 + LTEXT "", IDT_ABOUT_DATE, m, 67, xc, 8 + LTEXT MY_COPYRIGHT, -1, m, 80, xc, 8 + LTEXT "7-Zip is free software", IDT_ABOUT_INFO, m, y, xc, (by - y - 1) +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AboutDialogRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AboutDialogRes.h 2011-05-17 11:09:34.000000000 +0000 @@ -0,0 +1,8 @@ +#define IDD_ABOUT 2900 + +#define IDT_ABOUT_INFO 2901 + +#define IDI_LOGO 100 +#define IDT_ABOUT_VERSION 101 +#define IDT_ABOUT_DATE 102 +#define IDB_ABOUT_HOMEPAGE 110 Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Add.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Add.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Add2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Add2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp 2024-07-09 09:00:00.000000000 +0000 @@ -0,0 +1,946 @@ +// AltStreamsFolder.cpp + +#include "StdAfx.h" + +#ifdef __MINGW32_VERSION +// #if !defined(_MSC_VER) && (__GNUC__) && (__GNUC__ < 10) +// for old mingw +#include +#else +#ifndef Z7_OLD_WIN_SDK + #if !defined(_M_IA64) + #include + #endif +#else +typedef LONG NTSTATUS; +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; +#endif +#endif + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "../Common/ExtractingFilePath.h" + +#include "../Agent/IFolderArchive.h" + +#include "AltStreamsFolder.h" +#include "FSDrives.h" +#include "FSFolder.h" + +#include "SysIconUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; +using namespace NDir; +using namespace NName; + +#ifndef USE_UNICODE_FSTRING +int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2); +#endif + +#ifndef UNDER_CE + +namespace NFsFolder +{ +bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size); +} + +#endif + +namespace NAltStreamsFolder { + +static const Byte kProps[] = +{ + kpidName, + kpidSize, + kpidPackSize +}; + +static unsigned GetFsParentPrefixSize(const FString &path) +{ + if (IsNetworkShareRootPath(path)) + return 0; + const unsigned prefixSize = GetRootPrefixSize(path); + if (prefixSize == 0 || prefixSize >= path.Len()) + return 0; + FString parentPath = path; + int pos = parentPath.ReverseFind_PathSepar(); + if (pos < 0) + return 0; + if (pos == (int)parentPath.Len() - 1) + { + parentPath.DeleteBack(); + pos = parentPath.ReverseFind_PathSepar(); + if (pos < 0) + return 0; + } + if ((unsigned)pos + 1 < prefixSize) + return 0; + return (unsigned)pos + 1; +} + +HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFolder */) +{ + // _parentFolder = parentFolder; + if (path.Back() != ':') + return E_FAIL; + + _pathPrefix = path; + _pathBaseFile = path; + _pathBaseFile.DeleteBack(); + + { + CFileInfo fi; + if (!fi.Find(_pathBaseFile)) + return GetLastError_noZero_HRESULT(); + } + + unsigned prefixSize = GetFsParentPrefixSize(_pathBaseFile); + if (prefixSize == 0) + return S_OK; + FString parentPath = _pathBaseFile; + parentPath.DeleteFrom(prefixSize); + + _findChangeNotification.FindFirst(parentPath, false, + FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME + | FILE_NOTIFY_CHANGE_ATTRIBUTES + | FILE_NOTIFY_CHANGE_SIZE + | FILE_NOTIFY_CHANGE_LAST_WRITE + /* + | FILE_NOTIFY_CHANGE_LAST_ACCESS + | FILE_NOTIFY_CHANGE_CREATION + | FILE_NOTIFY_CHANGE_SECURITY + */ + ); + /* + if (_findChangeNotification.IsHandleAllocated()) + return S_OK; + return GetLastError(); + */ + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::LoadItems()) +{ + Int32 dummy; + WasChanged(&dummy); + Clear(); + + CStreamEnumerator enumerator(_pathBaseFile); + + CStreamInfo si; + for (;;) + { + bool found; + if (!enumerator.Next(si, found)) + { + // if (GetLastError() == ERROR_ACCESS_DENIED) + // break; + // return E_FAIL; + break; + } + if (!found) + break; + if (si.IsMainStream()) + continue; + CAltStream ss; + ss.Name = si.GetReducedName(); + if (!ss.Name.IsEmpty() && ss.Name[0] == ':') + ss.Name.Delete(0); + + ss.Size = si.Size; + ss.PackSize_Defined = false; + ss.PackSize = si.Size; + Streams.Add(ss); + } + + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Streams.Size(); + return S_OK; +} + +#ifdef USE_UNICODE_FSTRING + +Z7_COM7F_IMF(CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len)) +{ + *name = NULL; + *len = 0; + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) +{ + *name = NULL; + *len = 0; + { + const CAltStream &ss = Streams[index]; + *name = ss.Name; + *len = ss.Name.Len(); + } + return S_OK; +} + +Z7_COM7F_IMF2(UInt64, CAltStreamsFolder::GetItemSize(UInt32 index)) +{ + return Streams[index].Size; +} + +#endif + + +Z7_COM7F_IMF(CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + { + CAltStream &ss = Streams[index]; + switch (propID) + { + case kpidIsDir: prop = false; break; + case kpidIsAltStream: prop = true; break; + case kpidName: prop = ss.Name; break; + case kpidSize: prop = ss.Size; break; + case kpidPackSize: + #ifdef UNDER_CE + prop = ss.Size; + #else + if (!ss.PackSize_Defined) + { + ss.PackSize_Defined = true; + if (!NFsFolder::MyGetCompressedFileSizeW(_pathPrefix + us2fs(ss.Name), ss.PackSize)) + ss.PackSize = ss.Size; + } + prop = ss.PackSize; + #endif + break; + } + } + + prop.Detach(value); + return S_OK; +} + + +// returns Position of extension including '.' + +static inline const wchar_t *GetExtensionPtr(const UString &name) +{ + const int dotPos = name.ReverseFind_Dot(); + return name.Ptr(dotPos < 0 ? name.Len() : (unsigned)dotPos); +} + +Z7_COM7F_IMF2(Int32, CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */)) +{ + const CAltStream &ss1 = Streams[index1]; + const CAltStream &ss2 = Streams[index2]; + + switch (propID) + { + case kpidName: + { + return CompareFileNames_ForFolderList(ss1.Name, ss2.Name); + // return MyStringCompareNoCase(ss1.Name, ss2.Name); + } + case kpidSize: + return MyCompare(ss1.Size, ss2.Size); + case kpidPackSize: + { + #ifdef UNDER_CE + return MyCompare(ss1.Size, ss2.Size); + #else + // PackSize can be undefined here + return MyCompare( + ss1.PackSize, + ss2.PackSize); + #endif + } + + case kpidExtension: + return CompareFileNames_ForFolderList( + GetExtensionPtr(ss1.Name), + GetExtensionPtr(ss2.Name)); + } + + return 0; +} + +Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + return E_INVALIDARG; +} + +Z7_COM7F_IMF(CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + return E_INVALIDARG; +} + +// static CFSTR const kSuperPrefix = FTEXT("\\\\?\\"); + +Z7_COM7F_IMF(CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + /* + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + */ + + if (IsDriveRootPath_SuperAllowed(_pathBaseFile)) + { + CFSDrives *drivesFolderSpec = new CFSDrives; + CMyComPtr drivesFolder = drivesFolderSpec; + drivesFolderSpec->Init(); + *resultFolder = drivesFolder.Detach(); + return S_OK; + } + + /* + parentPath.DeleteFrom(pos + 1); + + if (parentPath == kSuperPrefix) + { + #ifdef UNDER_CE + *resultFolder = 0; + #else + CFSDrives *drivesFolderSpec = new CFSDrives; + CMyComPtr drivesFolder = drivesFolderSpec; + drivesFolderSpec->Init(false, true); + *resultFolder = drivesFolder.Detach(); + #endif + return S_OK; + } + + FString parentPathReduced = parentPath.Left(pos); + + #ifndef UNDER_CE + pos = parentPathReduced.ReverseFind_PathSepar(); + if (pos == 1) + { + if (!IS_PATH_SEPAR_CHAR(parentPath[0])) + return E_FAIL; + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr netFolder = netFolderSpec; + netFolderSpec->Init(fs2us(parentPath)); + *resultFolder = netFolder.Detach(); + return S_OK; + } + #endif + + CFSFolder *parentFolderSpec = new CFSFolder; + CMyComPtr parentFolder = parentFolderSpec; + RINOK(parentFolderSpec->Init(parentPath, 0)); + *resultFolder = parentFolder.Detach(); + */ + + return S_OK; +} + +IMP_IFolderFolder_Props(CAltStreamsFolder) + +Z7_COM7F_IMF(CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidType: prop = "AltStreamsFolder"; break; + case kpidPath: prop = fs2us(_pathPrefix); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CAltStreamsFolder::WasChanged(Int32 *wasChanged)) +{ + bool wasChangedMain = false; + for (;;) + { + if (!_findChangeNotification.IsHandleAllocated()) + { + *wasChanged = BoolToInt(false); + return S_OK; + } + + const DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); + const bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); + if (wasChangedLoc) + { + _findChangeNotification.FindNext(); + wasChangedMain = true; + } + else + break; + } + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::Clone(IFolderFolder **resultFolder)) +{ + CAltStreamsFolder *folderSpec = new CAltStreamsFolder; + CMyComPtr folderNew = folderSpec; + folderSpec->Init(_pathPrefix); + *resultFolder = folderNew.Detach(); + return S_OK; +} + +void CAltStreamsFolder::GetAbsPath(const wchar_t *name, FString &absPath) +{ + absPath.Empty(); + if (!IsAbsolutePath(name)) + absPath += _pathPrefix; + absPath += us2fs(name); +} + + + +static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, + const wchar_t *message, const FString &fileName) +{ + UString s = message; + s += " : "; + s += fs2us(fileName); + return callback->ShowMessage(s); +} + +static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback, + const wchar_t *message, const FString &fileName) +{ + UString s = message; + s += " : "; + s += fs2us(fileName); + return callback->UpdateErrorMessage(s); +} + +static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, + const char *message, const FString &fileName) +{ + return SendMessageError(callback, MultiByteToUnicodeString(message), fileName); +} + +/* +static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback, + const char *message, const FString &fileName) +{ + return SendMessageError(callback, MultiByteToUnicodeString(message), fileName); +} +*/ + +Z7_COM7F_IMF(CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)) +{ + FString absPath; + GetAbsPath(name, absPath); + NIO::COutFile outFile; + if (!outFile.Create_NEW(absPath)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + +static UString GetLastErrorMessage() +{ + return NError::MyFormatMessage(GetLastError_noZero_HRESULT()); +} + +static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR outPath, IFolderArchiveUpdateCallback *callback) +{ + if (NFind::DoesFileOrDirExist(outPath)) + { + RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath))) + CFileInfo fi; + if (fi.Find(inPath)) + { + if (state.TotalSize >= fi.Size) + state.TotalSize -= fi.Size; + } + return S_OK; + } + + { + if (callback) + RINOK(callback->CompressOperation(fs2us(inPath))) + RINOK(state.MyCopyFile(inPath, outPath)) + if (state.ErrorFileIndex >= 0) + { + if (state.ErrorMessage.IsEmpty()) + state.ErrorMessage = GetLastErrorMessage(); + FString errorName; + if (state.ErrorFileIndex == 0) + errorName = inPath; + else + errorName = outPath; + if (callback) + RINOK(SendMessageError(callback, state.ErrorMessage, errorName)) + } + if (callback) + RINOK(callback->OperationResult(0)) + } + + return S_OK; +} + +EXTERN_C_BEGIN + +typedef enum +{ + Z7_WIN_FileRenameInformation = 10 +} +Z7_WIN_FILE_INFORMATION_CLASS; + + +typedef struct +{ + // #if (_WIN32_WINNT >= _WIN32_WINNT_WIN10_RS1) + union + { + BOOLEAN ReplaceIfExists; // FileRenameInformation + ULONG Flags; // FileRenameInformationEx + } DUMMYUNIONNAME; + // #else + // BOOLEAN ReplaceIfExists; + // #endif + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} Z7_WIN_FILE_RENAME_INFORMATION; + +#if (_WIN32_WINNT >= 0x0500) && !defined(_M_IA64) +#define Z7_WIN_NTSTATUS NTSTATUS +#define Z7_WIN_IO_STATUS_BLOCK IO_STATUS_BLOCK +#else +typedef LONG Z7_WIN_NTSTATUS; +typedef struct +{ + union + { + Z7_WIN_NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + ULONG_PTR Information; +} Z7_WIN_IO_STATUS_BLOCK; +#endif + +typedef Z7_WIN_NTSTATUS (WINAPI *Func_NtSetInformationFile)( + HANDLE FileHandle, + Z7_WIN_IO_STATUS_BLOCK *IoStatusBlock, + PVOID FileInformation, + ULONG Length, + Z7_WIN_FILE_INFORMATION_CLASS FileInformationClass); + +// NTAPI +typedef ULONG (WINAPI *Func_RtlNtStatusToDosError)(Z7_WIN_NTSTATUS Status); + +#define MY_STATUS_SUCCESS 0 + +EXTERN_C_END + +// static Func_NtSetInformationFile f_NtSetInformationFile; +// static bool g_NtSetInformationFile_WasRequested = false; +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +Z7_COM7F_IMF(CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)) +{ + const CAltStream &ss = Streams[index]; + const FString srcPath = _pathPrefix + us2fs(ss.Name); + + const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + // if (!g_NtSetInformationFile_WasRequested) { + // g_NtSetInformationFile_WasRequested = true; + const + Func_NtSetInformationFile + f_NtSetInformationFile = Z7_GET_PROC_ADDRESS( + Func_NtSetInformationFile, ntdll, + "NtSetInformationFile"); + if (f_NtSetInformationFile) + { + NIO::CInFile inFile; + if (inFile.Open_for_FileRenameInformation(srcPath)) + { + UString destPath (':'); + destPath += newName; + const ULONG len = (ULONG)sizeof(wchar_t) * destPath.Len(); + CByteBuffer buffer(sizeof(Z7_WIN_FILE_RENAME_INFORMATION) + len); + // buffer is 4 bytes larger than required. + Z7_WIN_FILE_RENAME_INFORMATION *fri = (Z7_WIN_FILE_RENAME_INFORMATION *)(void *)(Byte *)buffer; + memset(fri, 0, sizeof(Z7_WIN_FILE_RENAME_INFORMATION)); + /* DOCS: If ReplaceIfExists is set to TRUE, the rename operation will succeed only + if a stream with the same name does not exist or is a zero-length data stream. */ + fri->ReplaceIfExists = FALSE; + fri->RootDirectory = NULL; + fri->FileNameLength = len; + memcpy(fri->FileName, destPath.Ptr(), len); + Z7_WIN_IO_STATUS_BLOCK iosb; + const Z7_WIN_NTSTATUS status = f_NtSetInformationFile (inFile.GetHandle(), + &iosb, fri, (ULONG)buffer.Size(), Z7_WIN_FileRenameInformation); + if (status != MY_STATUS_SUCCESS) + { + const + Func_RtlNtStatusToDosError + f_RtlNtStatusToDosError = Z7_GET_PROC_ADDRESS( + Func_RtlNtStatusToDosError, ntdll, + "RtlNtStatusToDosError"); + if (f_RtlNtStatusToDosError) + { + const ULONG res = f_RtlNtStatusToDosError(status); + if (res != ERROR_MR_MID_NOT_FOUND) + return HRESULT_FROM_WIN32(res); + } + } + return status; + } + } + + CMyComPtr callback; + if (progress) + { + RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback)) + } + + if (callback) + { + RINOK(callback->SetNumFiles(1)) + RINOK(callback->SetTotal(ss.Size)) + } + + NFsFolder::CCopyStateIO state; + state.Progress = progress; + state.TotalSize = 0; + state.DeleteSrcFile = true; + + const FString destPath = _pathPrefix + us2fs(newName); + return UpdateFile(state, srcPath, destPath, callback); +} + +Z7_COM7F_IMF(CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)) +{ + RINOK(progress->SetTotal(numItems)) + for (UInt32 i = 0; i < numItems; i++) + { + const CAltStream &ss = Streams[indices[i]]; + const FString fullPath = _pathPrefix + us2fs(ss.Name); + const bool result = DeleteFileAlways(fullPath); + if (!result) + return GetLastError_noZero_HRESULT(); + const UInt64 completed = i; + RINOK(progress->SetCompleted(&completed)) + } + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +{ + const CAltStream &ss = Streams[index]; + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + _pathPrefix + us2fs(ss.Name), + FILE_ATTRIBUTE_ARCHIVE, + iconIndex); +} + +/* +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) +public: + // const CArc *Arc; + // UInt32 IndexInArc; + UString Name; // relative path + UInt64 Size; +}; + +Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) +{ + if (propID == kpidName) + { + COM_TRY_BEGIN + NCOM::CPropVariant prop; + prop = Name; + prop.Detach(value); + return S_OK; + COM_TRY_END + } + if (propID == kpidSize) + { + NCOM::CPropVariant prop = Size; + prop.Detach(value); + return S_OK; + } + NCOM::CPropVariant prop; + prop.Detach(value); + return S_OK; +} +*/ + +static HRESULT CopyStream( + NFsFolder::CCopyStateIO &state, + const FString &srcPath, + const CFileInfo &srcFileInfo, + const CAltStream &srcAltStream, + const FString &destPathSpec, + IFolderOperationsExtractCallback *callback) +{ + FString destPath = destPathSpec; + if (CompareFileNames(destPath, srcPath) == 0) + { + RINOK(SendMessageError(callback, "Cannot copy file onto itself", destPath)) + return E_ABORT; + } + + Int32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite( + fs2us(srcPath), + BoolToInt(false), + &srcFileInfo.MTime, &srcAltStream.Size, + fs2us(destPath), + &destPathResult, + &writeAskResult)) + + if (IntToBool(writeAskResult)) + { + RINOK(callback->SetCurrentFilePath(fs2us(srcPath))) + FString destPathNew (us2fs((LPCOLESTR)destPathResult)); + RINOK(state.MyCopyFile(srcPath, destPathNew)) + if (state.ErrorFileIndex >= 0) + { + if (state.ErrorMessage.IsEmpty()) + state.ErrorMessage = GetLastErrorMessage(); + FString errorName; + if (state.ErrorFileIndex == 0) + errorName = srcPath; + else + errorName = destPathNew; + RINOK(SendMessageError(callback, state.ErrorMessage, errorName)) + return E_ABORT; + } + state.StartPos += state.CurrentSize; + } + else + { + if (state.TotalSize >= srcAltStream.Size) + { + state.TotalSize -= srcAltStream.Size; + RINOK(state.Progress->SetTotal(state.TotalSize)) + } + } + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, + Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, + const wchar_t *path, IFolderOperationsExtractCallback *callback)) +{ + if (numItems == 0) + return S_OK; + + /* + Z7_DECL_CMyComPtr_QI_FROM( + IFolderExtractToStreamCallback, + ExtractToStreamCallback, callback) + if (ExtractToStreamCallback) + { + Int32 useStreams = 0; + if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK) + useStreams = 0; + if (useStreams == 0) + ExtractToStreamCallback.Release(); + } + */ + + UInt64 totalSize = 0; + { + UInt32 i; + for (i = 0; i < numItems; i++) + { + totalSize += Streams[indices[i]].Size; + } + RINOK(callback->SetTotal(totalSize)) + RINOK(callback->SetNumFiles(numItems)) + } + + /* + if (ExtractToStreamCallback) + { + CGetProp *GetProp_Spec = new CGetProp; + CMyComPtr GetProp= GetProp_Spec; + + for (UInt32 i = 0; i < numItems; i++) + { + UInt32 index = indices[i]; + const CAltStream &ss = Streams[index]; + GetProp_Spec->Name = ss.Name; + GetProp_Spec->Size = ss.Size; + CMyComPtr outStream; + RINOK(ExtractToStreamCallback->GetStream7(GetProp_Spec->Name, BoolToInt(false), &outStream, + NArchive::NExtract::NAskMode::kExtract, GetProp)); // isDir + FString srcPath; + GetFullPath(ss, srcPath); + RINOK(ExtractToStreamCallback->PrepareOperation7(NArchive::NExtract::NAskMode::kExtract)); + RINOK(ExtractToStreamCallback->SetOperationResult7(NArchive::NExtract::NOperationResult::kOK, BoolToInt(false))); // _encrypted + // RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback, completedSize)); + } + return S_OK; + } + */ + + FString destPath (us2fs(path)); + if (destPath.IsEmpty() /* && !ExtractToStreamCallback */) + return E_INVALIDARG; + + const bool isAltDest = NName::IsAltPathPrefix(destPath); + const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); + + if (isDirectPath) + { + if (numItems > 1) + return E_INVALIDARG; + } + + CFileInfo fi; + if (!fi.Find(_pathBaseFile)) + return GetLastError_noZero_HRESULT(); + + NFsFolder::CCopyStateIO state; + state.Progress = callback; + state.DeleteSrcFile = IntToBool(moveMode); + state.TotalSize = totalSize; + + for (UInt32 i = 0; i < numItems; i++) + { + const UInt32 index = indices[i]; + const CAltStream &ss = Streams[index]; + FString destPath2 = destPath; + if (!isDirectPath) + destPath2 += us2fs(Get_Correct_FsFile_Name(ss.Name)); + FString srcPath; + GetFullPath(ss, srcPath); + RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback)) + } + + return S_OK; +} + +Z7_COM7F_IMF(CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, + const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)) +{ + /* + if (numItems == 0) + return S_OK; + + CMyComPtr callback; + if (progress) + { + RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback)); + } + + if (CompareFileNames(fromFolderPath, fs2us(_pathPrefix)) == 0) + { + RINOK(SendMessageError(callback, "Cannot copy file onto itself", _pathPrefix)); + return E_ABORT; + } + + if (callback) + RINOK(callback->SetNumFiles(numItems)); + + UInt64 totalSize = 0; + + UInt32 i; + + FString path; + for (i = 0; i < numItems; i++) + { + path = us2fs(fromFolderPath); + path += us2fs(itemsPaths[i]); + + CFileInfo fi; + if (!fi.Find(path)) + return ::GetLastError(); + if (fi.IsDir()) + return E_NOTIMPL; + totalSize += fi.Size; + } + + RINOK(progress->SetTotal(totalSize)); + + // UInt64 completedSize = 0; + + NFsFolder::CCopyStateIO state; + state.Progress = progress; + state.DeleteSrcFile = IntToBool(moveMode); + state.TotalSize = totalSize; + + // we need to clear READ-ONLY of parent before creating alt stream + { + DWORD attrib = GetFileAttrib(_pathBaseFile); + if (attrib != INVALID_FILE_ATTRIBUTES + && (attrib & FILE_ATTRIBUTE_READONLY) != 0) + { + if (!SetFileAttrib(_pathBaseFile, attrib & ~FILE_ATTRIBUTE_READONLY)) + { + if (callback) + { + RINOK(SendMessageError(callback, GetLastErrorMessage(), _pathBaseFile)); + return S_OK; + } + return Return_LastError_or_FAIL(); + } + } + } + + for (i = 0; i < numItems; i++) + { + path = us2fs(fromFolderPath); + path += us2fs(itemsPaths[i]); + + FString destPath = _pathPrefix + us2fs(itemsPaths[i]); + + RINOK(UpdateFile(state, path, destPath, callback)); + } + + return S_OK; + */ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AltStreamsFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AltStreamsFolder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AltStreamsFolder.h 2023-04-01 09:00:00.000000000 +0000 @@ -0,0 +1,92 @@ +// AltStreamsFolder.h + +#ifndef ZIP7_INC_ALT_STREAMS_FOLDER_H +#define ZIP7_INC_ALT_STREAMS_FOLDER_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/FileFind.h" + +#include "../../Archive/IArchive.h" + +#include "IFolder.h" + +namespace NAltStreamsFolder { + +class CAltStreamsFolder; + +struct CAltStream +{ + UInt64 Size; + UInt64 PackSize; + bool PackSize_Defined; + UString Name; +}; + + +class CAltStreamsFolder Z7_final: + public IFolderFolder, + public IFolderCompare, + #ifdef USE_UNICODE_FSTRING + public IFolderGetItemName, + #endif + public IFolderWasChanged, + public IFolderOperations, + // public IFolderOperationsDeleteToRecycleBin, + public IFolderClone, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IFolderFolder) + Z7_COM_QI_ENTRY(IFolderCompare) + #ifdef USE_UNICODE_FSTRING + Z7_COM_QI_ENTRY(IFolderGetItemName) + #endif + Z7_COM_QI_ENTRY(IFolderWasChanged) + // Z7_COM_QI_ENTRY(IFolderOperationsDeleteToRecycleBin) + Z7_COM_QI_ENTRY(IFolderOperations) + Z7_COM_QI_ENTRY(IFolderClone) + Z7_COM_QI_ENTRY(IFolderGetSystemIconIndex) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IFolderFolder) + Z7_IFACE_COM7_IMP(IFolderCompare) + #ifdef USE_UNICODE_FSTRING + Z7_IFACE_COM7_IMP(IFolderGetItemName) + #endif + Z7_IFACE_COM7_IMP(IFolderWasChanged) + Z7_IFACE_COM7_IMP(IFolderOperations) + Z7_IFACE_COM7_IMP(IFolderClone) + Z7_IFACE_COM7_IMP(IFolderGetSystemIconIndex) + + FString _pathBaseFile; // folder + FString _pathPrefix; // folder: + + CObjectVector Streams; + // CMyComPtr _parentFolder; + + NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; + + HRESULT GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress); + void GetAbsPath(const wchar_t *name, FString &absPath); + +public: + // path must be with ':' at tail + HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */); + + void GetFullPath(const CAltStream &item, FString &path) const + { + path = _pathPrefix; + path += us2fs(item.Name); + } + + void Clear() + { + Streams.Clear(); + } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/App.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/App.cpp 2015-06-22 20:08:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.cpp 2024-10-04 16:00:00.000000000 +0000 @@ -1,967 +1,1004 @@ -// App.cpp - -#include "StdAfx.h" - -#include "resource.h" -#include "OverwriteDialogRes.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariantConv.h" - -/* -#include "Windows/COM.h" -#include "Windows/Error.h" -#include "Windows/FileDir.h" - -#include "Windows/PropVariant.h" -#include "Windows/Thread.h" -*/ - -#include "App.h" -#include "CopyDialog.h" -#include "ExtractCallback.h" -#include "FormatUtils.h" -#include "IFolder.h" -#include "LangUtils.h" -#include "RegistryUtils.h" -#include "ViewSettings.h" - -#include "PropertyNameRes.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; -using namespace NFind; -using namespace NName; - -extern DWORD g_ComCtl32Version; -extern HINSTANCE g_hInstance; - -static CFSTR kTempDirPrefix = FTEXT("7zE"); - -void CPanelCallbackImp::OnTab() -{ - if (g_App.NumPanels != 1) - _app->Panels[1 - _index].SetFocusToList(); - _app->RefreshTitle(); -} - -void CPanelCallbackImp::SetFocusToPath(int index) -{ - int newPanelIndex = index; - if (g_App.NumPanels == 1) - newPanelIndex = g_App.LastFocusedPanel; - _app->RefreshTitle(); - // FIXME _app->Panels[newPanelIndex]._headerComboBox.SetFocus(); - // FIXME _app->Panels[newPanelIndex]._headerComboBox.ShowDropDown(); -} - - -void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) { _app->OnCopy(move, copyToSame, _index); } -void CPanelCallbackImp::OnSetSameFolder() { _app->OnSetSameFolder(_index); } -void CPanelCallbackImp::OnSetSubFolder() { _app->OnSetSubFolder(_index); } -void CPanelCallbackImp::PanelWasFocused() { _app->SetFocusedPanel(_index); _app->RefreshTitle(_index); } -void CPanelCallbackImp::DragBegin() { /* FIXME _app->DragBegin(_index) */ ; } -void CPanelCallbackImp::DragEnd() { /* FIXME _app->DragEnd() */ ; } -void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitle(_index, always); } - -void CApp::ReloadLang() -{ - LangString(IDS_N_SELECTED_ITEMS, LangString_N_SELECTED_ITEMS); -} - -void CApp::SetListSettings() -{ - bool showDots = ReadShowDots(); - bool showRealFileIcons = ReadShowRealFileIcons(); - - DWORD extendedStyle = 0; /* FIXME LVS_EX_HEADERDRAGDROP; - if (ReadFullRow()) - extendedStyle |= LVS_EX_FULLROWSELECT; - if (ReadShowGrid()) - extendedStyle |= LVS_EX_GRIDLINES; -*/ - bool mySelectionMode = ReadAlternativeSelection(); - -#ifdef _WIN32 - if (ReadSingleClick()) - { - extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT; - /* - if (ReadUnderline()) - extendedStyle |= LVS_EX_UNDERLINEHOT; - */ - } -#endif - - for (int i = 0; i < kNumPanelsMax; i++) - { - CPanel &panel = Panels[i]; - panel._mySelectMode = mySelectionMode; - panel._showDots = showDots; - panel._showRealFileIcons = showRealFileIcons; - panel._exStyle = extendedStyle; - -#ifdef _WIN32 - DWORD style = (DWORD)panel._listView.GetStyle(); - if (mySelectionMode) - style |= LVS_SINGLESEL; - else - style &= ~LVS_SINGLESEL; - panel._listView.SetStyle(style); -#endif - panel.SetExtendedStyle(); - } -} - -void CApp::SetShowSystemMenu() -{ - ShowSystemMenu = Read_ShowSystemMenu(); -} - -#ifndef ILC_COLOR32 -#define ILC_COLOR32 0x0020 -#endif - -HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, - bool &archiveIsOpened, bool &encrypted) -{ - if (PanelsCreated[panelIndex]) - return S_OK; - m_PanelCallbackImp[panelIndex].Init(this, panelIndex); - UString path; - if (mainPath.IsEmpty()) - { - if (!::ReadPanelPath(panelIndex, path)) - path.Empty(); - } - else - path = mainPath; - int id = 1000 + 100 * panelIndex; - RINOK(Panels[panelIndex].Create(_window, _window, - id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted)); - PanelsCreated[panelIndex] = true; - return S_OK; -} - -#ifdef _WIN32 -static void CreateToolbar(HWND parent, - NControl::CImageList &imageList, - NControl::CToolBar &toolBar, - bool largeButtons) -{ - toolBar.Attach(::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 0 - | WS_CHILD - | WS_VISIBLE - | TBSTYLE_FLAT - | TBSTYLE_TOOLTIPS - | TBSTYLE_WRAPABLE - // | TBSTYLE_AUTOSIZE - // | CCS_NORESIZE - #ifdef UNDER_CE - | CCS_NODIVIDER - | CCS_NOPARENTALIGN - #endif - ,0,0,0,0, parent, NULL, g_hInstance, NULL)); - - // TB_BUTTONSTRUCTSIZE message, which is required for - // backward compatibility. - toolBar.ButtonStructSize(); - - imageList.Create( - largeButtons ? 48: 24, - largeButtons ? 36: 24, - ILC_MASK | ILC_COLOR32, 0, 0); - toolBar.SetImageList(0, imageList); -} -#endif - -struct CButtonInfo -{ - int CommandID; - UINT BitmapResID; - UINT Bitmap2ResID; - UINT StringResID; - - UString GetText() const { return LangString(StringResID); } -}; - -static CButtonInfo g_StandardButtons[] = -{ - { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY }, - { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE }, - { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE } , - { IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO } -}; - -static CButtonInfo g_ArchiveButtons[] = -{ - { kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD }, - { kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT }, - { kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST } -}; - -static bool SetButtonText(int commandID, CButtonInfo *buttons, int numButtons, UString &s) -{ - for (int i = 0; i < numButtons; i++) - { - const CButtonInfo &b = buttons[i]; - if (b.CommandID == commandID) - { - s = b.GetText(); - return true; - } - } - return false; -} - -static void SetButtonText(int commandID, UString &s) -{ - if (SetButtonText(commandID, g_StandardButtons, ARRAY_SIZE(g_StandardButtons), s)) - return; - SetButtonText(commandID, g_ArchiveButtons, ARRAY_SIZE(g_ArchiveButtons), s); -} - -#ifdef _WIN32 -static void AddButton( - NControl::CImageList &imageList, - NControl::CToolBar &toolBar, - CButtonInfo &butInfo, bool showText, bool large) -{ - TBBUTTON but; - but.iBitmap = 0; - but.idCommand = butInfo.CommandID; - but.fsState = TBSTATE_ENABLED; - but.fsStyle = TBSTYLE_BUTTON; - but.dwData = 0; - - UString s = butInfo.GetText(); - but.iString = 0; - if (showText) - but.iString = (INT_PTR)(LPCWSTR)s; - - but.iBitmap = imageList.GetImageCount(); - HBITMAP b = ::LoadBitmap(g_hInstance, - large ? - MAKEINTRESOURCE(butInfo.BitmapResID): - MAKEINTRESOURCE(butInfo.Bitmap2ResID)); - if (b != 0) - { - imageList.AddMasked(b, RGB(255, 0, 255)); - ::DeleteObject(b); - } - #ifdef _UNICODE - toolBar.AddButton(1, &but); - #else - toolBar.AddButtonW(1, &but); - #endif -} - -void CApp::ReloadToolbars() -{ - _buttonsImageList.Destroy(); - _toolBar.Destroy(); - - - if (ShowArchiveToolbar || ShowStandardToolbar) - { - CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons); - int i; - if (ShowArchiveToolbar) - for (i = 0; i < ARRAY_SIZE(g_ArchiveButtons); i++) - AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons); - if (ShowStandardToolbar) - for (i = 0; i < ARRAY_SIZE(g_StandardButtons); i++) - AddButton(_buttonsImageList, _toolBar, g_StandardButtons[i], ShowButtonsLables, LargeButtons); - - _toolBar.AutoSize(); - } -} -#endif - -void CApp::SaveToolbarChanges() -{ -#ifdef _WIN32 - SaveToolbar(); - ReloadToolbars(); - MoveSubWindows(); -#endif -} - -void MyLoadMenu(); - -HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted) -{ - _window.Attach(hwnd); -#ifdef _WIN32 - #ifdef UNDER_CE - _commandBar.Create(g_hInstance, hwnd, 1); - #endif - MyLoadMenu(); - #ifdef UNDER_CE - _commandBar.AutoSize(); - #endif - - ReadToolbar(); - ReloadToolbars(); -#endif - - int i; - for (i = 0; i < kNumPanelsMax; i++) - PanelsCreated[i] = false; - - AppState.Read(); - SetListSettings(); - SetShowSystemMenu(); - if (LastFocusedPanel >= kNumPanelsMax) - LastFocusedPanel = 0; - // ShowDeletedFiles = Read_ShowDeleted(); - - CListMode listMode; - listMode.Read(); - for (i = 0; i < kNumPanelsMax; i++) - { - CPanel &panel = Panels[i]; - panel._ListViewMode = listMode.Panels[i]; - panel._xSize = xSizes[i]; - panel._flatModeForArc = ReadFlatView(i); - } - for (i = 0; i < kNumPanelsMax; i++) - if (NumPanels > 1 || i == LastFocusedPanel) - { - if (NumPanels == 1) - Panels[i]._xSize = xSizes[0] + xSizes[1]; - bool archiveIsOpened2 = false; - bool encrypted2 = false; - bool mainPanel = (i == LastFocusedPanel); - RINOK(CreateOnePanel(i, mainPanel ? mainPath : L"", arcFormat, archiveIsOpened2, encrypted2)); - if (mainPanel) - { - archiveIsOpened = archiveIsOpened2; - encrypted = encrypted2; - } - } - SetFocusedPanel(LastFocusedPanel); - Panels[LastFocusedPanel].SetFocusToList(); - return S_OK; -} - -HRESULT CApp::SwitchOnOffOnePanel() -{ - if (NumPanels == 1) - { - NumPanels++; - bool archiveIsOpened, encrypted; - RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(), archiveIsOpened, encrypted)); - // FIXME Panels[1 - LastFocusedPanel].Enable(true); - // FIXME Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); - } - else - { - NumPanels--; - // FIXME Panels[1 - LastFocusedPanel].Enable(false); - // FIXME Panels[1 - LastFocusedPanel].Show(SW_HIDE); - } - // FIXME MoveSubWindows(); - return S_OK; -} - -void CApp::Save() -{ - AppState.Save(); - CListMode listMode; - for (int i = 0; i < kNumPanelsMax; i++) - { - const CPanel &panel = Panels[i]; - UString path; - if (panel._parentFolders.IsEmpty()) - path = panel._currentFolderPrefix; - else - path = panel._parentFolders[0].ParentFolderPath; - // GetFolderPath(panel._parentFolders[0].ParentFolder); - SavePanelPath(i, path); - listMode.Panels[i] = panel.GetListViewMode(); - SaveFlatView(i, panel._flatModeForArc); - } - listMode.Save(); - // Save_ShowDeleted(ShowDeletedFiles); -} - -void CApp::Release() -{ - // It's for unloading COM dll's: don't change it. - for (int i = 0; i < kNumPanelsMax; i++) - Panels[i].Release(); -} - -// reduces path to part that exists on disk (or root prefix of path) -// output path is normalized (with WCHAR_PATH_SEPARATOR) -static void ReducePathToRealFileSystemPath(UString &path) -{ - unsigned prefixSize = GetRootPrefixSize(path); - - while (!path.IsEmpty()) - { - if (NFind::DoesDirExist(us2fs(path))) - { - NName::NormalizeDirPathPrefix(path); - break; - } - int pos = path.ReverseFind_PathSepar(); - if (pos < 0) - { - path.Empty(); - break; - } - path.DeleteFrom(pos + 1); - if ((unsigned)pos + 1 == prefixSize) - break; - path.DeleteFrom(pos); - } -} - -// returns: true, if such dir exists or is root -/* -static bool CheckFolderPath(const UString &path) -{ - UString pathReduced = path; - ReducePathToRealFileSystemPath(pathReduced); - return (pathReduced == path); -} -*/ - -extern UString ConvertSizeToString(UInt64 value); - -static void AddSizeValue(UString &s, UInt64 size) -{ - s += MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size)); -} - -static void AddValuePair1(UString &s, UINT resourceID, UInt64 size) -{ - AddLangString(s, resourceID); - s += L": "; - AddSizeValue(s, size); - s.Add_LF(); -} - -void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size) -{ - if (num == 0) - return; - AddLangString(s, resourceID); - s += L": "; - s += ConvertSizeToString(num); - - if (size != (UInt64)(Int64)-1) - { - s += L" ( "; - AddSizeValue(s, size); - s += L" )"; - } - s.Add_LF(); -} - -static void AddPropValueToSum(IFolderFolder *folder, int index, PROPID propID, UInt64 &sum) -{ - if (sum == (UInt64)(Int64)-1) - return; - NCOM::CPropVariant prop; - folder->GetProperty(index, propID, &prop); - UInt64 val = 0; - if (ConvertPropVariantToUInt64(prop, val)) - sum += val; - else - sum = (UInt64)(Int64)-1; -} - -UString CPanel::GetItemsInfoString(const CRecordVector &indices) -{ - UString info; - UInt64 numDirs, numFiles, filesSize, foldersSize; - numDirs = numFiles = filesSize = foldersSize = 0; - unsigned i; - for (i = 0; i < indices.Size(); i++) - { - int index = indices[i]; - if (IsItem_Folder(index)) - { - AddPropValueToSum(_folder, index, kpidSize, foldersSize); - numDirs++; - } - else - { - AddPropValueToSum(_folder, index, kpidSize, filesSize); - numFiles++; - } - } - - AddValuePair2(info, IDS_PROP_FOLDERS, numDirs, foldersSize); - AddValuePair2(info, IDS_PROP_FILES, numFiles, filesSize); - int numDefined = ((foldersSize != (UInt64)(Int64)-1) && foldersSize != 0) ? 1: 0; - numDefined += ((filesSize != (UInt64)(Int64)-1) && filesSize != 0) ? 1: 0; - if (numDefined == 2) - AddValuePair1(info, IDS_PROP_SIZE, filesSize + foldersSize); - - info.Add_LF(); -#ifdef _WIN32 - info += _currentFolderPrefix; -#else - { - extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); - - UString tmp = nameWindowToUnix(_currentFolderPrefix); - - info += tmp; - } -#endif - - for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++) - { - info += L"\n "; - int index = indices[i]; - info += GetItemRelPath(index); - if (IsItem_Folder(index)) - info.Add_PathSepar(); - } - if (i != indices.Size()) - info += L"\n ..."; - return info; -} - -bool IsCorrectFsName(const UString &name); - - - -/* Returns true, if path is path that can be used as path for File System functions -*/ - -/* -static bool IsFsPath(const FString &path) -{ - if (!IsAbsolutePath(path)) - return false; - unsigned prefixSize = GetRootPrefixSize(path); -} -*/ - -void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) -{ - int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); - CPanel &srcPanel = Panels[srcPanelIndex]; - CPanel &destPanel = Panels[destPanelIndex]; - - CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); - CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); - - if (move) - { - if (!srcPanel.CheckBeforeUpdate(IDS_MOVE)) - return; - } - else if (!srcPanel.DoesItSupportOperations()) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - - CRecordVector indices; - UString destPath; - bool useDestPanel = false; - - { - if (copyToSame) - { - int focusedItem = srcPanel._listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = srcPanel.GetRealItemIndex(focusedItem); - if (realIndex == kParentIndex) - return; - indices.Add(realIndex); - destPath = srcPanel.GetItemName(realIndex); - } - else - { - srcPanel.GetOperatedIndicesSmart(indices); - if (indices.Size() == 0) - return; - destPath = destPanel.GetFsPath(); - if (NumPanels == 1) - ReducePathToRealFileSystemPath(destPath); - } - } - - UStringVector copyFolders; - ReadCopyHistory(copyFolders); - - { - CCopyDialog copyDialog; - - copyDialog.Strings = copyFolders; - copyDialog.Value = destPath; - LangString(move ? IDS_MOVE : IDS_COPY, copyDialog.Title); - LangString(move ? IDS_MOVE_TO : IDS_COPY_TO, copyDialog.Static); - copyDialog.Info = srcPanel.GetItemsInfoString(indices); - - if (copyDialog.Create(srcPanel.GetParent()) != IDOK) - return; - - destPath = copyDialog.Value; - } - - { - if (destPath.IsEmpty()) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - - UString correctName; - if (!srcPanel.CorrectFsPath(destPath, correctName)) - { - srcPanel.MessageBoxError(E_INVALIDARG); - return; - } - - if (IsAbsolutePath(destPath)) - destPath.Empty(); - else - destPath = srcPanel.GetFsPath(); - destPath += correctName; - - #if defined(_WIN32) && !defined(UNDER_CE) - if (destPath.Len() > 0 && destPath[0] == '\\') - if (destPath.Len() == 1 || destPath[1] != '\\') - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - #endif - - bool possibleToUseDestPanel = false; - - if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0) - { - if (NumPanels == 1 || CompareFileNames(destPath, srcPanel.GetFsPath()) == 0) - { - srcPanel.MessageBoxMyError(L"Can not copy files onto itself"); - return; - } - - if (destPanel.DoesItSupportOperations()) - possibleToUseDestPanel = true; - } - - bool destIsFsPath = false; - - if (possibleToUseDestPanel) - { - if (destPanel.IsFSFolder() || destPanel.IsAltStreamsFolder()) - destIsFsPath = true; - else if (destPanel.IsFSDrivesFolder() || destPanel.IsRootFolder()) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - } - else - { -#ifdef _WIN32 - if (IsAltPathPrefix(us2fs(destPath))) - { - // we allow alt streams dest only to alt stream folder in second panel - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - /* - FString basePath = us2fs(destPath); - basePath.DeleteBack(); - if (!DoesFileOrDirExist(basePath)) - { - srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError() - return; - } - destIsFsPath = true; - */ - } - else -#endif - { - if (indices.Size() == 1 && - !destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR) - { - int pos = destPath.ReverseFind_PathSepar(); - if (pos < 0) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - { - /* - #ifdef _WIN32 - UString name = destPath.Ptr(pos + 1); - if (name.Find(L':') >= 0) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - #endif - */ - UString prefix = destPath.Left(pos + 1); - if (!CreateComplexDir(us2fs(prefix))) - { - srcPanel.MessageBoxError2Lines(prefix, GetLastError()); - return; - } - } - // bool isFolder = srcPanael.IsItem_Folder(indices[0]); - } - else - { - NName::NormalizeDirPathPrefix(destPath); - if (!CreateComplexDir(us2fs(destPath))) - { - srcPanel.MessageBoxError2Lines(destPath, GetLastError()); - return; - } - } - destIsFsPath = true; - } - } - - if (!destIsFsPath) - useDestPanel = true; - - AddUniqueStringToHeadOfList(copyFolders, destPath); - while (copyFolders.Size() > 20) - copyFolders.DeleteBack(); - SaveCopyHistory(copyFolders); - } - - bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); - - bool useTemp = useSrcPanel && useDestPanel; - if (useTemp && NumPanels == 1) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - - CTempDir tempDirectory; - FString tempDirPrefix; - if (useTemp) - { - tempDirectory.Create(kTempDirPrefix); - tempDirPrefix = tempDirectory.GetPath(); - NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); - } - - CSelectedState srcSelState; - CSelectedState destSelState; - srcPanel.SaveSelectedState(srcSelState); - destPanel.SaveSelectedState(destSelState); - - CPanel::CDisableNotify disableNotify1(destPanel); - CPanel::CDisableNotify disableNotify2(srcPanel); - - HRESULT result = S_OK; - - if (useSrcPanel) - { - CCopyToOptions options; - options.folder = useTemp ? fs2us(tempDirPrefix) : destPath; - options.moveMode = move; - options.includeAltStreams = true; - options.replaceAltStreamChars = false; - options.showErrorMessages = true; - - result = srcPanel.CopyTo(options, indices, NULL); - } - - if (result == S_OK && useDestPanel) - { - UStringVector filePaths; - UString folderPrefix; - if (useTemp) - folderPrefix = fs2us(tempDirPrefix); - else - folderPrefix = srcPanel.GetFsPath(); - filePaths.ClearAndReserve(indices.Size()); - FOR_VECTOR (i, indices) - filePaths.AddInReserved(srcPanel.GetItemRelPath2(indices[i])); - result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0); - } - - if (result != S_OK) - { - // disableNotify1.Restore(); - // disableNotify2.Restore(); - // For Password: - // srcPanel.SetFocusToList(); - // srcPanel.InvalidateList(NULL, true); - - if (result != E_ABORT) - srcPanel.MessageBoxError(result, L"Error"); - // return; - } - - RefreshTitleAlways(); - - if (copyToSame || move) - { - srcPanel.RefreshListCtrl(srcSelState); - } - - if (!copyToSame) - { - destPanel.RefreshListCtrl(destSelState); - srcPanel.KillSelection(); - } - - disableNotify1.Restore(); - disableNotify2.Restore(); - srcPanel.SetFocusToList(); -} - -void CApp::OnSetSameFolder(int srcPanelIndex) -{ - if (NumPanels <= 1) - return; - const CPanel &srcPanel = Panels[srcPanelIndex]; - CPanel &destPanel = Panels[1 - srcPanelIndex]; - destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix); -} - -void CApp::OnSetSubFolder(int srcPanelIndex) -{ - if (NumPanels <= 1) - return; - const CPanel &srcPanel = Panels[srcPanelIndex]; - CPanel &destPanel = Panels[1 - srcPanelIndex]; - - int focusedItem = srcPanel._listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = srcPanel.GetRealItemIndex(focusedItem); - if (!srcPanel.IsItem_Folder(realIndex)) - return; - - // destPanel.BindToFolder(srcPanel._currentFolderPrefix + srcPanel.GetItemName(realIndex) + WCHAR_PATH_SEPARATOR); - - CMyComPtr newFolder; - if (realIndex == kParentIndex) - { - if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK) - return; - } - else - { - if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK) - return; - } - destPanel.CloseOpenFolders(); - destPanel.SetNewFolder(newFolder); - destPanel.RefreshListCtrl(); -} - -/* -int CApp::GetFocusedPanelIndex() const -{ - return LastFocusedPanel; - HWND hwnd = ::GetFocus(); - for (;;) - { - if (hwnd == 0) - return 0; - for (int i = 0; i < kNumPanelsMax; i++) - { - if (PanelsCreated[i] && - ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd)) - return i; - } - hwnd = GetParent(hwnd); - } -} -*/ - -static UString g_ToolTipBuffer; -static CSysString g_ToolTipBufferSys; - -#ifdef _WIN32 -void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh) -{ - { - if (pnmh->code == TTN_GETDISPINFO) - { - LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh; - info->hinst = 0; - g_ToolTipBuffer.Empty(); - SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); - g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer); - info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBufferSys; - return; - } - #ifndef _UNICODE - if (pnmh->code == TTN_GETDISPINFOW) - { - LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh; - info->hinst = 0; - g_ToolTipBuffer.Empty(); - SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); - info->lpszText = (LPWSTR)(LPCWSTR)g_ToolTipBuffer; - return; - } - #endif - } -} -#endif - -void CApp::RefreshTitle(bool always) -{ - UString path = GetFocusedPanel()._currentFolderPrefix; -#ifndef _WIN32 - { - extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); - UString tmp = nameWindowToUnix(path); - path = tmp; - } -#endif - if (path.IsEmpty()) - path = L"7-Zip"; // LangString(IDS_APP_TITLE); - if (!always && path == PrevTitle) - return; - PrevTitle = path; - NWindows::MySetWindowText(_window, path); -} - -void CApp::RefreshTitle(int panelIndex, bool always) -{ - if (panelIndex != GetFocusedPanelIndex()) - return; - RefreshTitle(always); -} - -void AddUniqueStringToHead(UStringVector &list, const UString &s) -{ - for (unsigned i = 0; i < list.Size();) - if (s.IsEqualTo_NoCase(list[i])) - list.Delete(i); - else - i++; - list.Insert(0, s); -} - - -void CFolderHistory::Normalize() -{ - const unsigned kMaxSize = 100; - if (Strings.Size() > kMaxSize) - Strings.DeleteFrom(kMaxSize); -} - -void CFolderHistory::AddString(const UString &s) -{ - NSynchronization::CCriticalSectionLock lock(_criticalSection); - AddUniqueStringToHead(Strings, s); - Normalize(); -} +// App.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "OverwriteDialogRes.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariantConv.h" + +/* +#include "Windows/COM.h" +#include "Windows/Error.h" +#include "Windows/FileDir.h" + +#include "Windows/PropVariant.h" +#include "Windows/Thread.h" +*/ + +#include "App.h" +#include "CopyDialog.h" +#include "ExtractCallback.h" +#include "FormatUtils.h" +#include "IFolder.h" +#include "LangUtils.h" +#include "MyLoadMenu.h" +#include "RegistryUtils.h" +#include "ViewSettings.h" + +#include "PropertyNameRes.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NFind; +using namespace NName; + +extern HINSTANCE g_hInstance; + +#define kTempDirPrefix FTEXT("7zE") + +void CPanelCallbackImp::OnTab() +{ + if (g_App.NumPanels != 1) + _app->Panels[1 - _index].SetFocusToList(); + _app->RefreshTitle(); +} + +void CPanelCallbackImp::SetFocusToPath(unsigned index) +{ + unsigned newPanelIndex = index; + if (g_App.NumPanels == 1) + newPanelIndex = g_App.LastFocusedPanel; + _app->RefreshTitle(); + _app->Panels[newPanelIndex]._headerComboBox.SetFocus(); + _app->Panels[newPanelIndex]._headerComboBox.ShowDropDown(); +} + + +void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) { _app->OnCopy(move, copyToSame, _index); } +void CPanelCallbackImp::OnSetSameFolder() { _app->OnSetSameFolder(_index); } +void CPanelCallbackImp::OnSetSubFolder() { _app->OnSetSubFolder(_index); } +void CPanelCallbackImp::PanelWasFocused() { _app->SetFocusedPanel(_index); _app->RefreshTitlePanel(_index); } +void CPanelCallbackImp::DragBegin() { _app->DragBegin(_index); } +void CPanelCallbackImp::DragEnd() { _app->DragEnd(); } +void CPanelCallbackImp::RefreshTitle(bool always) { _app->RefreshTitlePanel(_index, always); } + +void CApp::ReloadLangItems() +{ + LangString(IDS_N_SELECTED_ITEMS, LangString_N_SELECTED_ITEMS); +} + +void CApp::SetListSettings() +{ + CFmSettings st; + st.Load(); + + ShowSystemMenu = st.ShowSystemMenu; + + DWORD extendedStyle = LVS_EX_HEADERDRAGDROP; + if (st.FullRow) + extendedStyle |= LVS_EX_FULLROWSELECT; + if (st.ShowGrid) + extendedStyle |= LVS_EX_GRIDLINES; + + if (st.SingleClick) + { + extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT; + /* + if (ReadUnderline()) + extendedStyle |= LVS_EX_UNDERLINEHOT; + */ + } + + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + panel._mySelectMode = st.AlternativeSelection; + panel._showDots = st.ShowDots; + panel._showRealFileIcons = st.ShowRealFileIcons; + panel._exStyle = extendedStyle; + + LONG_PTR style = panel._listView.GetStyle(); + if (st.AlternativeSelection) + style |= LVS_SINGLESEL; + else + style &= ~(LONG_PTR)(DWORD)LVS_SINGLESEL; + panel._listView.SetStyle(style); + panel.SetExtendedStyle(); + } +} + +#ifndef ILC_COLOR32 +#define ILC_COLOR32 0x0020 +#endif + +HRESULT CApp::CreateOnePanel(unsigned panelIndex, const UString &mainPath, const UString &arcFormat, + bool needOpenArc, + COpenResult &openRes) +{ + if (Panels[panelIndex].PanelCreated) + return S_OK; + + m_PanelCallbackImp[panelIndex].Init(this, panelIndex); + + UString path; + if (mainPath.IsEmpty()) + { + if (!::ReadPanelPath(panelIndex, path)) + path.Empty(); + } + else + path = mainPath; + + const unsigned id = 1000 + 100 * panelIndex; // check it + + return Panels[panelIndex].Create(_window, _window, + id, path, arcFormat, &m_PanelCallbackImp[panelIndex], &AppState, + needOpenArc, + openRes); +} + + +static void CreateToolbar(HWND parent, + NControl::CImageList &imageList, + NControl::CToolBar &toolBar, + bool largeButtons) +{ + toolBar.Attach(::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 0 + | WS_CHILD + | WS_VISIBLE + | TBSTYLE_FLAT + | TBSTYLE_TOOLTIPS + | TBSTYLE_WRAPABLE + // | TBSTYLE_AUTOSIZE + // | CCS_NORESIZE + #ifdef UNDER_CE + | CCS_NODIVIDER + | CCS_NOPARENTALIGN + #endif + ,0,0,0,0, parent, NULL, g_hInstance, NULL)); + + // TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + toolBar.ButtonStructSize(); + + imageList.Create( + largeButtons ? 48: 24, + largeButtons ? 36: 24, + ILC_MASK | ILC_COLOR32, 0, 0); + toolBar.SetImageList(0, imageList); +} + + +struct CButtonInfo +{ + int CommandID; + UINT BitmapResID; + UINT Bitmap2ResID; + UINT StringResID; + + UString GetText() const { return LangString(StringResID); } +}; + +static const CButtonInfo g_StandardButtons[] = +{ + { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY }, + { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE }, + { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE } , + { IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO } +}; + +static const CButtonInfo g_ArchiveButtons[] = +{ + { kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD }, + { kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT }, + { kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST } +}; + +static bool SetButtonText(int commandID, const CButtonInfo *buttons, unsigned numButtons, UString &s) +{ + for (unsigned i = 0; i < numButtons; i++) + { + const CButtonInfo &b = buttons[i]; + if (b.CommandID == commandID) + { + s = b.GetText(); + return true; + } + } + return false; +} + +static void SetButtonText(int commandID, UString &s) +{ + if (SetButtonText(commandID, g_StandardButtons, Z7_ARRAY_SIZE(g_StandardButtons), s)) + return; + SetButtonText(commandID, g_ArchiveButtons, Z7_ARRAY_SIZE(g_ArchiveButtons), s); +} + +static void AddButton( + NControl::CImageList &imageList, + NControl::CToolBar &toolBar, + const CButtonInfo &butInfo, bool showText, bool large) +{ + TBBUTTON but; + but.iBitmap = 0; + but.idCommand = butInfo.CommandID; + but.fsState = TBSTATE_ENABLED; + but.fsStyle = TBSTYLE_BUTTON; + but.dwData = 0; + + UString s = butInfo.GetText(); + but.iString = 0; + if (showText) + but.iString = (INT_PTR)(LPCWSTR)s; + + but.iBitmap = imageList.GetImageCount(); + HBITMAP b = ::LoadBitmap(g_hInstance, + large ? + MAKEINTRESOURCE(butInfo.BitmapResID): + MAKEINTRESOURCE(butInfo.Bitmap2ResID)); + if (b) + { + imageList.AddMasked(b, RGB(255, 0, 255)); + ::DeleteObject(b); + } + #ifdef _UNICODE + toolBar.AddButton(1, &but); + #else + toolBar.AddButtonW(1, &but); + #endif +} + +void CApp::ReloadToolbars() +{ + _buttonsImageList.Destroy(); + _toolBar.Destroy(); + + + if (ShowArchiveToolbar || ShowStandardToolbar) + { + CreateToolbar(_window, _buttonsImageList, _toolBar, LargeButtons); + unsigned i; + if (ShowArchiveToolbar) + for (i = 0; i < Z7_ARRAY_SIZE(g_ArchiveButtons); i++) + AddButton(_buttonsImageList, _toolBar, g_ArchiveButtons[i], ShowButtonsLables, LargeButtons); + if (ShowStandardToolbar) + for (i = 0; i < Z7_ARRAY_SIZE(g_StandardButtons); i++) + AddButton(_buttonsImageList, _toolBar, g_StandardButtons[i], ShowButtonsLables, LargeButtons); + + _toolBar.AutoSize(); + } +} + +void CApp::SaveToolbarChanges() +{ + SaveToolbar(); + ReloadToolbars(); + MoveSubWindows(); +} + + +HRESULT CApp::Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes) +{ + _window.Attach(hwnd); + + #ifdef UNDER_CE + _commandBar.Create(g_hInstance, hwnd, 1); + #endif + + MyLoadMenu(false); // needResetMenu + + #ifdef UNDER_CE + _commandBar.AutoSize(); + #endif + + ReadToolbar(); + ReloadToolbars(); + + unsigned i; + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].PanelCreated = false; + + AppState.Read(); + + SetListSettings(); + + if (LastFocusedPanel >= kNumPanelsMax) + LastFocusedPanel = 0; + // ShowDeletedFiles = Read_ShowDeleted(); + + CListMode listMode; + listMode.Read(); + + for (i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + panel._listViewMode = listMode.Panels[i]; + panel._xSize = xSizes[i]; + panel._flatModeForArc = ReadFlatView(i); + } + + for (i = 0; i < kNumPanelsMax; i++) + { + unsigned panelIndex = i; + if (needOpenArc && LastFocusedPanel == 1) + panelIndex = 1 - i; + + bool isMainPanel = (panelIndex == LastFocusedPanel); + + if (NumPanels > 1 || isMainPanel) + { + if (NumPanels == 1) + Panels[panelIndex]._xSize = xSizes[0] + xSizes[1]; + + COpenResult openRes2; + UString path; + if (isMainPanel) + path = mainPath; + + RINOK(CreateOnePanel(panelIndex, path, arcFormat, + isMainPanel && needOpenArc, + *(isMainPanel ? &openRes : &openRes2))) + + if (isMainPanel) + { + if (needOpenArc && !openRes.ArchiveIsOpened) + return S_OK; + } + } + } + + SetFocusedPanel(LastFocusedPanel); + Panels[LastFocusedPanel].SetFocusToList(); + return S_OK; +} + + +HRESULT CApp::SwitchOnOffOnePanel() +{ + if (NumPanels == 1) + { + NumPanels++; + COpenResult openRes; + RINOK(CreateOnePanel(1 - LastFocusedPanel, UString(), UString(), + false, // needOpenArc + openRes)) + Panels[1 - LastFocusedPanel].Enable(true); + Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); + } + else + { + NumPanels--; + Panels[1 - LastFocusedPanel].Enable(false); + Panels[1 - LastFocusedPanel].Show(SW_HIDE); + } + MoveSubWindows(); + return S_OK; +} + +void CApp::Save() +{ + AppState.Save(); + CListMode listMode; + + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + const CPanel &panel = Panels[i]; + UString path; + if (panel._parentFolders.IsEmpty()) + path = panel._currentFolderPrefix; + else + path = panel._parentFolders[0].ParentFolderPath; + // GetFolderPath(panel._parentFolders[0].ParentFolder); + SavePanelPath(i, path); + listMode.Panels[i] = panel.GetListViewMode(); + SaveFlatView(i, panel._flatModeForArc); + } + + listMode.Save(); + // Save_ShowDeleted(ShowDeletedFiles); +} + +void CApp::ReleaseApp() +{ + // 24.09: ReleasePanel() will stop panel timer processing. + // but we want to stop timer processing for all panels + // before ReleasePanel() calling. + unsigned i; + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].Disable_Processing_Timer_Notify_StatusBar(); + // It's for unloading COM dll's: don't change it. + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].ReleasePanel(); +} + +// reduces path to part that exists on disk (or root prefix of path) +// output path is normalized (with WCHAR_PATH_SEPARATOR) +static void Reduce_Path_To_RealFileSystemPath(UString &path) +{ + unsigned prefixSize = GetRootPrefixSize(path); + + while (!path.IsEmpty()) + { + if (NFind::DoesDirExist_FollowLink(us2fs(path))) + { + NName::NormalizeDirPathPrefix(path); + break; + } + int pos = path.ReverseFind_PathSepar(); + if (pos < 0) + { + path.Empty(); + break; + } + path.DeleteFrom((unsigned)(pos + 1)); + if ((unsigned)pos + 1 == prefixSize) + break; + path.DeleteFrom((unsigned)pos); + } +} + +// returns: true, if such dir exists or is root +/* +static bool CheckFolderPath(const UString &path) +{ + UString pathReduced = path; + Reduce_Path_To_RealFileSystemPath(pathReduced); + return (pathReduced == path); +} +*/ + +extern UString ConvertSizeToString(UInt64 value); + +static void AddSizeValue(UString &s, UInt64 size) +{ + s += MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size)); +} + +static void AddValuePair1(UString &s, UINT resourceID, UInt64 size) +{ + AddLangString(s, resourceID); + s += ": "; + AddSizeValue(s, size); + s.Add_LF(); +} + +void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size); +void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size) +{ + if (num == 0) + return; + AddLangString(s, resourceID); + s += ": "; + s += ConvertSizeToString(num); + + if (size != (UInt64)(Int64)-1) + { + s += " ( "; + AddSizeValue(s, size); + s += " )"; + } + s.Add_LF(); +} + +static void AddPropValueToSum(IFolderFolder *folder, UInt32 index, PROPID propID, UInt64 &sum) +{ + if (sum == (UInt64)(Int64)-1) + return; + NCOM::CPropVariant prop; + folder->GetProperty(index, propID, &prop); + UInt64 val = 0; + if (ConvertPropVariantToUInt64(prop, val)) + sum += val; + else + sum = (UInt64)(Int64)-1; +} + +UString CPanel::GetItemsInfoString(const CRecordVector &indices) +{ + UString info; + UInt64 numDirs, numFiles, filesSize, foldersSize; + numDirs = numFiles = filesSize = foldersSize = 0; + + unsigned i; + for (i = 0; i < indices.Size(); i++) + { + const UInt32 index = indices[i]; + if (IsItem_Folder(index)) + { + AddPropValueToSum(_folder, index, kpidSize, foldersSize); + numDirs++; + } + else + { + AddPropValueToSum(_folder, index, kpidSize, filesSize); + numFiles++; + } + } + + AddValuePair2(info, IDS_PROP_FOLDERS, numDirs, foldersSize); + AddValuePair2(info, IDS_PROP_FILES, numFiles, filesSize); + int numDefined = ((foldersSize != (UInt64)(Int64)-1) && foldersSize != 0) ? 1: 0; + numDefined += ((filesSize != (UInt64)(Int64)-1) && filesSize != 0) ? 1: 0; + if (numDefined == 2) + AddValuePair1(info, IDS_PROP_SIZE, filesSize + foldersSize); + + info.Add_LF(); + info += _currentFolderPrefix; + + for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++) + { + info.Add_LF(); + info += " "; + const UInt32 index = indices[i]; + info += GetItemRelPath(index); + if (IsItem_Folder(index)) + info.Add_PathSepar(); + } + if (i != indices.Size()) + { + info.Add_LF(); + info += " ..."; + } + return info; +} + +bool IsCorrectFsName(const UString &name); + + + +/* Returns true, if path is path that can be used as path for File System functions +*/ + +/* +static bool IsFsPath(const FString &path) +{ + if (!IsAbsolutePath(path)) + return false; + unsigned prefixSize = GetRootPrefixSize(path); +} +*/ + +void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) +{ + const unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[destPanelIndex]; + + CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); + CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); + + if (move) + { + if (!srcPanel.CheckBeforeUpdate(IDS_MOVE)) + return; + } + else if (!srcPanel.DoesItSupportOperations()) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + + CRecordVector indices; + UString destPath; + bool useDestPanel = false; + + { + if (copyToSame) + { + const int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + indices.Add(realIndex); + destPath = srcPanel.GetItemName(realIndex); + } + else + { + srcPanel.Get_ItemIndices_OperSmart(indices); + if (indices.Size() == 0) + return; + destPath = destPanel.GetFsPath(); + if (NumPanels == 1) + Reduce_Path_To_RealFileSystemPath(destPath); + } + } + + UStringVector copyFolders; + ReadCopyHistory(copyFolders); + + const bool useFullItemPaths = srcPanel.Is_IO_FS_Folder(); // maybe we need flat also here ?? + + { + CCopyDialog copyDialog; + + copyDialog.Strings = copyFolders; + copyDialog.Value = destPath; + LangString(move ? IDS_MOVE : IDS_COPY, copyDialog.Title); + LangString(move ? IDS_MOVE_TO : IDS_COPY_TO, copyDialog.Static); + copyDialog.Info = srcPanel.GetItemsInfoString(indices); + + if (copyDialog.Create(srcPanel.GetParent()) != IDOK) + return; + + destPath = copyDialog.Value; + } + + { + if (destPath.IsEmpty()) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + + UString correctName; + if (!srcPanel.CorrectFsPath(destPath, correctName)) + { + srcPanel.MessageBox_Error_HRESULT(E_INVALIDARG); + return; + } + + if (IsAbsolutePath(destPath)) + destPath.Empty(); + else + destPath = srcPanel.GetFsPath(); + destPath += correctName; + + #if defined(_WIN32) && !defined(UNDER_CE) + if (destPath.Len() != 0 && destPath[0] == '\\') + if (destPath.Len() == 1 || destPath[1] != '\\') + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + #endif + + bool possibleToUseDestPanel = false; + + if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0) + { + if (NumPanels == 1 || CompareFileNames(destPath, srcPanel.GetFsPath()) == 0) + { + srcPanel.MessageBox_Error(L"Cannot copy files onto itself"); + return; + } + + if (destPanel.DoesItSupportOperations()) + possibleToUseDestPanel = true; + } + + bool destIsFsPath = false; + + if (possibleToUseDestPanel) + { + if (destPanel.IsFSFolder() || destPanel.IsAltStreamsFolder()) + destIsFsPath = true; + else if (destPanel.IsFSDrivesFolder() || destPanel.IsRootFolder()) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + } + else + { + if (IsAltPathPrefix(us2fs(destPath))) + { + // we allow alt streams dest only to alt stream folder in second panel + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + /* + FString basePath = us2fs(destPath); + basePath.DeleteBack(); + if (!DoesFileOrDirExist(basePath)) + { + srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError() + return; + } + destIsFsPath = true; + */ + } + else + { + if (indices.Size() == 1 && + !destPath.IsEmpty() && !IS_PATH_SEPAR(destPath.Back())) + { + int pos = destPath.ReverseFind_PathSepar(); + if (pos < 0) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + { + /* + #ifdef _WIN32 + UString name = destPath.Ptr(pos + 1); + if (name.Find(L':') >= 0) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + #endif + */ + UString prefix = destPath.Left(pos + 1); + if (!CreateComplexDir(us2fs(prefix))) + { + const HRESULT lastError = GetLastError_noZero_HRESULT(); + srcPanel.MessageBox_Error_2Lines_Message_HRESULT(prefix, lastError); + return; + } + } + // bool isFolder = srcPanael.IsItem_Folder(indices[0]); + } + else + { + NName::NormalizeDirPathPrefix(destPath); + if (!CreateComplexDir(us2fs(destPath))) + { + const HRESULT lastError = GetLastError_noZero_HRESULT(); + srcPanel.MessageBox_Error_2Lines_Message_HRESULT(destPath, lastError); + return; + } + } + destIsFsPath = true; + } + } + + if (!destIsFsPath) + useDestPanel = true; + + AddUniqueStringToHeadOfList(copyFolders, destPath); + while (copyFolders.Size() > 20) + copyFolders.DeleteBack(); + SaveCopyHistory(copyFolders); + } + + bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder(); + + bool useTemp = useSrcPanel && useDestPanel; + if (useTemp && NumPanels == 1) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + + CTempDir tempDirectory; + FString tempDirPrefix; + if (useTemp) + { + tempDirectory.Create(kTempDirPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); + } + + CSelectedState srcSelState; + CSelectedState destSelState; + srcPanel.SaveSelectedState(srcSelState); + destPanel.SaveSelectedState(destSelState); + + CPanel::CDisableNotify disableNotify1(destPanel); + CPanel::CDisableNotify disableNotify2(srcPanel); + + HRESULT result = S_OK; + + if (useSrcPanel) + { + CCopyToOptions options; + // options.src_Is_IO_FS_Folder = useFullItemPaths; + options.folder = useTemp ? fs2us(tempDirPrefix) : destPath; + options.moveMode = move; + options.includeAltStreams = true; + options.replaceAltStreamChars = false; + options.showErrorMessages = true; + + result = srcPanel.CopyTo(options, indices, NULL); + } + + if (result == S_OK && useDestPanel) + { + UStringVector filePaths; + UString folderPrefix; + + if (useTemp) + folderPrefix = fs2us(tempDirPrefix); + else + folderPrefix = srcPanel.GetFsPath(); + + filePaths.ClearAndReserve(indices.Size()); + + FOR_VECTOR (i, indices) + { + UInt32 index = indices[i]; + UString s; + if (useFullItemPaths) + s = srcPanel.GetItemRelPath2(index); + else + s = srcPanel.GetItemName_for_Copy(index); + filePaths.AddInReserved(s); + } + + result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, NULL); + } + + if (result != S_OK) + { + // disableNotify1.Restore(); + // disableNotify2.Restore(); + // For Password: + // srcPanel.SetFocusToList(); + // srcPanel.InvalidateList(NULL, true); + + if (result != E_ABORT) + srcPanel.MessageBox_Error_HRESULT(result); + // return; + } + + RefreshTitleAlways(); + + if (copyToSame || move) + { + srcPanel.RefreshListCtrl(srcSelState); + } + + if (!copyToSame) + { + destPanel.RefreshListCtrl(destSelState); + srcPanel.KillSelection(); + } + + disableNotify1.Restore(); + disableNotify2.Restore(); + srcPanel.SetFocusToList(); +} + +void CApp::OnSetSameFolder(unsigned srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix); +} + +void CApp::OnSetSubFolder(unsigned srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + + const int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (!srcPanel.IsItem_Folder(realIndex)) + return; + + // destPanel.BindToFolder(srcPanel._currentFolderPrefix + srcPanel.GetItemName(realIndex) + WCHAR_PATH_SEPARATOR); + + CMyComPtr newFolder; + if (realIndex == kParentIndex) + { + if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK) + return; + if (!newFolder) + { + { + const UString parentPrefix = srcPanel.GetParentDirPrefix(); + COpenResult openRes; + destPanel.BindToPath(parentPrefix, UString(), openRes); + } + destPanel.RefreshListCtrl(); + return; + } + } + else + { + if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK) + return; + } + + if (!newFolder) + return; + + destPanel.CloseOpenFolders(); + destPanel.SetNewFolder(newFolder); + destPanel.RefreshListCtrl(); +} + +/* +int CApp::GetFocusedPanelIndex() const +{ + return LastFocusedPanel; + HWND hwnd = ::GetFocus(); + for (;;) + { + if (hwnd == 0) + return 0; + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + if (PanelsCreated[i] && + ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd)) + return i; + } + hwnd = GetParent(hwnd); + } +} +*/ + +static UString g_ToolTipBuffer; +static CSysString g_ToolTipBufferSys; + +void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh) +{ + { + if (pnmh->code == TTN_GETDISPINFO) + { + LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh; + info->hinst = NULL; + g_ToolTipBuffer.Empty(); + SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); + g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer); + info->lpszText = g_ToolTipBufferSys.Ptr_non_const(); + return; + } + #ifndef _UNICODE + if (pnmh->code == TTN_GETDISPINFOW) + { + LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh; + info->hinst = NULL; + g_ToolTipBuffer.Empty(); + SetButtonText((int)info->hdr.idFrom, g_ToolTipBuffer); + info->lpszText = g_ToolTipBuffer.Ptr_non_const(); + return; + } + #endif + } +} + +void CApp::RefreshTitle(bool always) +{ + UString path = GetFocusedPanel()._currentFolderPrefix; + if (path.IsEmpty()) + path = "7-Zip"; // LangString(IDS_APP_TITLE); + if (!always && path == PrevTitle) + return; + PrevTitle = path; + NWindows::MySetWindowText(_window, path); +} + +void CApp::RefreshTitlePanel(unsigned panelIndex, bool always) +{ + if (panelIndex != GetFocusedPanelIndex()) + return; + RefreshTitle(always); +} + +static void AddUniqueStringToHead(UStringVector &list, const UString &s) +{ + for (unsigned i = 0; i < list.Size();) + if (s.IsEqualTo_NoCase(list[i])) + list.Delete(i); + else + i++; + list.Insert(0, s); +} + + +void CFolderHistory::Normalize() +{ + const unsigned kMaxSize = 100; + if (Strings.Size() > kMaxSize) + Strings.DeleteFrom(kMaxSize); +} + +void CFolderHistory::AddString(const UString &s) +{ + NSynchronization::CCriticalSectionLock lock(_criticalSection); + AddUniqueStringToHead(Strings, s); + Normalize(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/App.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/App.h 2015-09-19 17:57:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/App.h 2024-10-12 07:00:00.000000000 +0000 @@ -1,364 +1,314 @@ -// App.h - -#ifndef __APP_H -#define __APP_H - -// #include "../../../Windows/Control/CommandBar.h" -// #include "../../../Windows/Control/ImageList.h" - -#include "AppState.h" -#include "Panel.h" - -class CApp; - -extern CApp g_App; -extern HWND g_HWND; - -const int kNumPanelsMax = 2; - -extern bool g_IsSmallScreen; - -const int kMenuCmdID_Plugin_Start = 10000; // must be large them context menu IDs and above all IDM_ABOUT -const int kMenuCmdID_Toolbar_Start = 15000; - -enum -{ - kMenuCmdID_Toolbar_Add = kMenuCmdID_Toolbar_Start, - kMenuCmdID_Toolbar_Extract, - kMenuCmdID_Toolbar_Test, - kMenuCmdID_Toolbar_End -}; - -class CPanelCallbackImp: public CPanelCallback -{ - CApp *_app; - int _index; -public: - void Init(CApp *app, int index) - { - _app = app; - _index = index; - } - virtual void OnTab(); - virtual void SetFocusToPath(int index); - virtual void OnCopy(bool move, bool copyToSame); - virtual void OnSetSameFolder(); - virtual void OnSetSubFolder(); - virtual void PanelWasFocused(); - virtual void DragBegin(); - virtual void DragEnd(); - virtual void RefreshTitle(bool always); -}; - -class CApp; - -#ifdef _WIN32 -class CDropTarget: - public IDropTarget, - public CMyUnknownImp -{ - CMyComPtr m_DataObject; - UStringVector m_SourcePaths; - int m_SelectionIndex; - bool m_DropIsAllowed; // = true, if data contain fillist - bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel. - // check it only if m_DropIsAllowed == true - int m_SubFolderIndex; - UString m_SubFolderName; - - CPanel *m_Panel; - bool m_IsAppTarget; // true, if we want to drop to app window (not to panel). - - bool m_SetPathIsOK; - - bool IsItSameDrive() const; - - void QueryGetData(IDataObject *dataObject); - bool IsFsFolderPath() const; - DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect); - void RemoveSelection(); - void PositionCursor(POINTL ptl); - UString GetTargetPath() const; - bool SetPath(bool enablePath) const; - bool SetPath(); - -public: - MY_UNKNOWN_IMP1_MT(IDropTarget) - STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState, POINTL pt, DWORD *effect); - STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect); - STDMETHOD(DragLeave)(); - STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState, POINTL pt, DWORD *effect); - - CDropTarget(): - TargetPanelIndex(-1), - SrcPanelIndex(-1), - m_IsAppTarget(false), - m_Panel(0), - App(0), - m_PanelDropIsAllowed(false), - m_DropIsAllowed(false), - m_SelectionIndex(-1), - m_SubFolderIndex(-1), - m_SetPathIsOK(false) {} - - CApp *App; - int SrcPanelIndex; // index of D&D source_panel - int TargetPanelIndex; // what panel to use as target_panel of Application -}; -#endif - -class CApp -{ -public: - NWindows::CWindow _window; - bool ShowSystemMenu; - // bool ShowDeletedFiles; - int NumPanels; - int LastFocusedPanel; - - bool ShowStandardToolbar; - bool ShowArchiveToolbar; - bool ShowButtonsLables; - bool LargeButtons; - - CAppState AppState; - CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax]; - CPanel Panels[kNumPanelsMax]; - bool PanelsCreated[kNumPanelsMax]; - -#ifdef _WIN32 - NWindows::NControl::CImageList _buttonsImageList; - - #ifdef UNDER_CE - NWindows::NControl::CCommandBar _commandBar; - #endif - NWindows::NControl::CToolBar _toolBar; - - CDropTarget *_dropTargetSpec; - CMyComPtr _dropTarget; -#endif - - UString LangString_N_SELECTED_ITEMS; - - void ReloadLang(); - - CApp(): _window(0), NumPanels(2), LastFocusedPanel(0), - AutoRefresh_Mode(true) - { - SetPanels_AutoRefresh_Mode(); - } - -#ifdef _WIN32 - void CreateDragTarget() - { - _dropTargetSpec = new CDropTarget(); - _dropTarget = _dropTargetSpec; - _dropTargetSpec->App = (this); - } -#endif - - void SetFocusedPanel(int index) - { - LastFocusedPanel = index; - // FIXME _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; - } - -#ifdef _WIN32 - void DragBegin(int panelIndex) - { - _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex; - _dropTargetSpec->SrcPanelIndex = panelIndex; - } - - void DragEnd() - { - _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; - _dropTargetSpec->SrcPanelIndex = -1; - } -#endif - - - void OnCopy(bool move, bool copyToSame, int srcPanelIndex); - void OnSetSameFolder(int srcPanelIndex); - void OnSetSubFolder(int srcPanelIndex); - - HRESULT CreateOnePanel(int panelIndex, const UString &mainPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted); - HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool &archiveIsOpened, bool &encrypted); - void Read(); - void Save(); - void Release(); - - // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } - // FIXME void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } - int GetFocusedPanelIndex() const { return LastFocusedPanel; } - bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); } - CPanel &GetFocusedPanel() { return Panels[GetFocusedPanelIndex()]; } - - // File Menu - void OpenItem() { GetFocusedPanel().OpenSelectedItems(true); } - void OpenItemInside(const wchar_t *type) { GetFocusedPanel().OpenFocusedItemAsInternal(type); } - void OpenItemOutside() { GetFocusedPanel().OpenSelectedItems(false); } - void EditItem(bool useEditor) { GetFocusedPanel().EditItem(useEditor); } - void Rename() { GetFocusedPanel().RenameFile(); } - void CopyTo() { OnCopy(false, false, GetFocusedPanelIndex()); } - void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); } - void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); } - HRESULT CalculateCrc2(const UString &methodName); - void CalculateCrc(const UString &methodName); - void DiffFiles(); - void Split(); - void Combine(); - void Properties() { GetFocusedPanel().Properties(); } - void Comment() { GetFocusedPanel().ChangeComment(); } - - #ifndef UNDER_CE - void Link(); - void OpenAltStreams() { GetFocusedPanel().OpenAltStreams(); } - #endif - - void CreateFolder() { GetFocusedPanel().CreateFolder(); } - void CreateFile() { GetFocusedPanel().CreateFile(); } - - // Edit - void EditCut() { GetFocusedPanel().EditCut(); } - void EditCopy() { GetFocusedPanel().EditCopy(); } - void EditPaste() { GetFocusedPanel().EditPaste(); } - - void SelectAll(bool selectMode) { GetFocusedPanel().SelectAll(selectMode); } - void InvertSelection() { GetFocusedPanel().InvertSelection(); } - void SelectSpec(bool selectMode) { GetFocusedPanel().SelectSpec(selectMode); } - void SelectByType(bool selectMode) { GetFocusedPanel().SelectByType(selectMode); } - - void Refresh_StatusBar() { /* FIXME GetFocusedPanel().Refresh_StatusBar() */ ; } - - void SetListViewMode(UInt32 index) { GetFocusedPanel().SetListViewMode(index); } - UInt32 GetListViewMode() { return GetFocusedPanel().GetListViewMode(); } - PROPID GetSortID() { return GetFocusedPanel().GetSortID(); } - - void SortItemsWithPropID(PROPID propID) { GetFocusedPanel().SortItemsWithPropID(propID); } - - void OpenRootFolder() { GetFocusedPanel().OpenDrivesFolder(); } - void OpenParentFolder() { GetFocusedPanel().OpenParentFolder(); } - void FoldersHistory() { GetFocusedPanel().FoldersHistory(); } - void RefreshView() { GetFocusedPanel().OnReload(); } - void RefreshAllPanels() - { - for (int i = 0; i < NumPanels; i++) - { - int index = i; - if (NumPanels == 1) - index = LastFocusedPanel; - Panels[index].OnReload(); - } - } - - /* - void SysIconsWereChanged() - { - for (int i = 0; i < NumPanels; i++) - { - int index = i; - if (NumPanels == 1) - index = LastFocusedPanel; - Panels[index].SysIconsWereChanged(); - } - } - */ - - void SetListSettings(); - void SetShowSystemMenu(); - HRESULT SwitchOnOffOnePanel(); - - bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); } - // bool Get_ShowNtfsStrems_Mode() { return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); } - - void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); } - // void Change_ShowNtfsStrems_Mode() { Panels[LastFocusedPanel].Change_ShowNtfsStrems_Mode(); } - // void Change_ShowDeleted() { ShowDeletedFiles = !ShowDeletedFiles; } - - bool AutoRefresh_Mode; - bool Get_AutoRefresh_Mode() - { - // return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); - return AutoRefresh_Mode; - } - void Change_AutoRefresh_Mode() - { - AutoRefresh_Mode = !AutoRefresh_Mode; - SetPanels_AutoRefresh_Mode(); - } - void SetPanels_AutoRefresh_Mode() - { - for (int i = 0; i < kNumPanelsMax; i++) - Panels[i].Set_AutoRefresh_Mode(AutoRefresh_Mode); - } - - void OpenBookmark(int index) { GetFocusedPanel().OpenBookmark(index); } - void SetBookmark(int index) { GetFocusedPanel().SetBookmark(index); } - - void ReloadToolbars(); - void ReadToolbar() - { - UInt32 mask = ReadToolbarsMask(); - if (mask & ((UInt32)1 << 31)) - { - ShowButtonsLables = !g_IsSmallScreen; - LargeButtons = false; - ShowStandardToolbar = ShowArchiveToolbar = true; - } - else - { - ShowButtonsLables = ((mask & 1) != 0); - LargeButtons = ((mask & 2) != 0); - ShowStandardToolbar = ((mask & 4) != 0); - ShowArchiveToolbar = ((mask & 8) != 0); - } - } - void SaveToolbar() - { - UInt32 mask = 0; - if (ShowButtonsLables) mask |= 1; - if (LargeButtons) mask |= 2; - if (ShowStandardToolbar) mask |= 4; - if (ShowArchiveToolbar) mask |= 8; - SaveToolbarsMask(mask); - } - - void SaveToolbarChanges(); - - void SwitchStandardToolbar() - { - ShowStandardToolbar = !ShowStandardToolbar; - SaveToolbarChanges(); - } - void SwitchArchiveToolbar() - { - ShowArchiveToolbar = !ShowArchiveToolbar; - SaveToolbarChanges(); - } - void SwitchButtonsLables() - { - ShowButtonsLables = !ShowButtonsLables; - SaveToolbarChanges(); - } - void SwitchLargeButtons() - { - LargeButtons = !LargeButtons; - SaveToolbarChanges(); - } - - void AddToArchive() { GetFocusedPanel().AddToArchive(); } - void ExtractArchives() { GetFocusedPanel().ExtractArchives(); } - void TestArchives() { GetFocusedPanel().TestArchives(); } - - // void OnNotify(int ctrlID, LPNMHDR pnmh); - - UString PrevTitle; - void RefreshTitle(bool always = false); - void RefreshTitleAlways() { RefreshTitle(true); } - void RefreshTitle(int panelIndex, bool always = false); - - void MoveSubWindows(); -}; - -#endif +// App.h + +#ifndef ZIP7_INC_APP_H +#define ZIP7_INC_APP_H + +#include "../../../Windows/Control/CommandBar.h" +#include "../../../Windows/Control/ImageList.h" + +#include "AppState.h" +#include "Panel.h" + +class CApp; + +extern CApp g_App; +extern HWND g_HWND; + +const unsigned kNumPanelsMax = 2; + +extern bool g_IsSmallScreen; + +// must be larger than context menu IDs +const int kMenuCmdID_Toolbar_Start = 1070; +const int kMenuCmdID_Plugin_Start = 1100; + +enum +{ + kMenuCmdID_Toolbar_Add = kMenuCmdID_Toolbar_Start, + kMenuCmdID_Toolbar_Extract, + kMenuCmdID_Toolbar_Test, + kMenuCmdID_Toolbar_End +}; + +class CPanelCallbackImp Z7_final: public CPanelCallback +{ + CApp *_app; + unsigned _index; +public: + void Init(CApp *app, unsigned index) + { + _app = app; + _index = index; + } + virtual void OnTab() Z7_override; + virtual void SetFocusToPath(unsigned index) Z7_override; + virtual void OnCopy(bool move, bool copyToSame) Z7_override; + virtual void OnSetSameFolder() Z7_override; + virtual void OnSetSubFolder() Z7_override; + virtual void PanelWasFocused() Z7_override; + virtual void DragBegin() Z7_override; + virtual void DragEnd() Z7_override; + virtual void RefreshTitle(bool always) Z7_override; +}; + + +class CDropTarget; + +class CApp +{ +public: + NWindows::CWindow _window; + bool ShowSystemMenu; + bool AutoRefresh_Mode; + // bool ShowDeletedFiles; + unsigned NumPanels; + unsigned LastFocusedPanel; + + bool ShowStandardToolbar; + bool ShowArchiveToolbar; + bool ShowButtonsLables; + bool LargeButtons; + + CAppState AppState; + CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax]; + CPanel Panels[kNumPanelsMax]; + + NWindows::NControl::CImageList _buttonsImageList; + + #ifdef UNDER_CE + NWindows::NControl::CCommandBar _commandBar; + #endif + NWindows::NControl::CToolBar _toolBar; + + CDropTarget *_dropTargetSpec; + CMyComPtr _dropTarget; + + UString LangString_N_SELECTED_ITEMS; + + void ReloadLangItems(); + + CApp(): + _window(NULL), + AutoRefresh_Mode(true), + NumPanels(2), + LastFocusedPanel(0) + { + SetPanels_AutoRefresh_Mode(); + } + + void CreateDragTarget(); + void SetFocusedPanel(unsigned index); + void DragBegin(unsigned panelIndex); + void DragEnd(); + + void OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex); + void OnSetSameFolder(unsigned srcPanelIndex); + void OnSetSubFolder(unsigned srcPanelIndex); + + HRESULT CreateOnePanel(unsigned panelIndex, const UString &mainPath, const UString &arcFormat, bool needOpenArc, COpenResult &openRes); + HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes); + void Read(); + void Save(); + void ReleaseApp(); + + // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } + void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } + unsigned GetFocusedPanelIndex() const { return LastFocusedPanel; } + bool IsPanelVisible(unsigned index) const { return (NumPanels > 1 || index == LastFocusedPanel); } + CPanel &GetFocusedPanel() { return Panels[GetFocusedPanelIndex()]; } + + // File Menu + void OpenItem() { GetFocusedPanel().OpenSelectedItems(true); } + void OpenItemInside(const wchar_t *type) { GetFocusedPanel().OpenFocusedItemAsInternal(type); } + void OpenItemOutside() { GetFocusedPanel().OpenSelectedItems(false); } + void EditItem(bool useEditor) { GetFocusedPanel().EditItem(useEditor); } + void Rename() { GetFocusedPanel().RenameFile(); } + void CopyTo() { OnCopy(false, false, GetFocusedPanelIndex()); } + void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); } + void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); } + HRESULT CalculateCrc2(const UString &methodName); + void CalculateCrc(const char *methodName); + + void DiffFiles(const UString &path1, const UString &path2); + void DiffFiles(); + + void VerCtrl(unsigned id); + + void Split(); + void Combine(); + void Properties() { GetFocusedPanel().Properties(); } + void Comment() { GetFocusedPanel().ChangeComment(); } + + #ifndef UNDER_CE + void Link(); + void OpenAltStreams() { GetFocusedPanel().OpenAltStreams(); } + #endif + + void CreateFolder() { GetFocusedPanel().CreateFolder(); } + void CreateFile() { GetFocusedPanel().CreateFile(); } + + // Edit + void EditCut() { GetFocusedPanel().EditCut(); } + void EditCopy() { GetFocusedPanel().EditCopy(); } + void EditPaste() { GetFocusedPanel().EditPaste(); } + + void SelectAll(bool selectMode) { GetFocusedPanel().SelectAll(selectMode); } + void InvertSelection() { GetFocusedPanel().InvertSelection(); } + void SelectSpec(bool selectMode) { GetFocusedPanel().SelectSpec(selectMode); } + void SelectByType(bool selectMode) { GetFocusedPanel().SelectByType(selectMode); } + + void Refresh_StatusBar() { GetFocusedPanel().Refresh_StatusBar(); } + + void SetListViewMode(UInt32 index) { GetFocusedPanel().SetListViewMode(index); } + UInt32 GetListViewMode() { return GetFocusedPanel().GetListViewMode(); } + PROPID GetSortID() { return GetFocusedPanel().GetSortID(); } + + void SortItemsWithPropID(PROPID propID) { GetFocusedPanel().SortItemsWithPropID(propID); } + + void OpenRootFolder() { GetFocusedPanel().OpenDrivesFolder(); } + void OpenParentFolder() { GetFocusedPanel().OpenParentFolder(); } + void FoldersHistory() { GetFocusedPanel().FoldersHistory(); } + void RefreshView() { GetFocusedPanel().OnReload(); } + void RefreshAllPanels() + { + for (unsigned i = 0; i < NumPanels; i++) + { + unsigned index = i; + if (NumPanels == 1) + index = LastFocusedPanel; + Panels[index].OnReload(); + } + } + + /* + void SysIconsWereChanged() + { + for (unsigned i = 0; i < NumPanels; i++) + { + unsigned index = i; + if (NumPanels == 1) + index = LastFocusedPanel; + Panels[index].SysIconsWereChanged(); + } + } + */ + + void SetListSettings(); + HRESULT SwitchOnOffOnePanel(); + + CIntVector _timestampLevels; + + bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); } + + int GetTimestampLevel() const { return Panels[LastFocusedPanel]._timestampLevel; } + void SetTimestampLevel(int level) + { + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + panel._timestampLevel = level; + } + RedrawListItems_InPanels(); + } + + void RedrawListItems_InPanels() + { + for (unsigned i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + if (panel.PanelCreated) + panel.RedrawListItems(); + } + } + + // bool Get_ShowNtfsStrems_Mode() { return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); } + + void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); } + // void Change_ShowNtfsStrems_Mode() { Panels[LastFocusedPanel].Change_ShowNtfsStrems_Mode(); } + // void Change_ShowDeleted() { ShowDeletedFiles = !ShowDeletedFiles; } + + bool Get_AutoRefresh_Mode() + { + // return Panels[LastFocusedPanel].Get_ShowNtfsStrems_Mode(); + return AutoRefresh_Mode; + } + void Change_AutoRefresh_Mode() + { + AutoRefresh_Mode = !AutoRefresh_Mode; + SetPanels_AutoRefresh_Mode(); + } + void SetPanels_AutoRefresh_Mode() + { + for (unsigned i = 0; i < kNumPanelsMax; i++) + Panels[i].Set_AutoRefresh_Mode(AutoRefresh_Mode); + } + + void OpenBookmark(unsigned index) { GetFocusedPanel().OpenBookmark(index); } + void SetBookmark(unsigned index) { GetFocusedPanel().SetBookmark(index); } + + void ReloadToolbars(); + void ReadToolbar() + { + const UInt32 mask = ReadToolbarsMask(); + if (mask & ((UInt32)1 << 31)) + { + ShowButtonsLables = !g_IsSmallScreen; + LargeButtons = false; + ShowStandardToolbar = ShowArchiveToolbar = true; + } + else + { + ShowButtonsLables = ((mask & 1) != 0); + LargeButtons = ((mask & 2) != 0); + ShowStandardToolbar = ((mask & 4) != 0); + ShowArchiveToolbar = ((mask & 8) != 0); + } + } + void SaveToolbar() + { + UInt32 mask = 0; + if (ShowButtonsLables) mask |= 1; + if (LargeButtons) mask |= 2; + if (ShowStandardToolbar) mask |= 4; + if (ShowArchiveToolbar) mask |= 8; + SaveToolbarsMask(mask); + } + + void SaveToolbarChanges(); + + void SwitchStandardToolbar() + { + ShowStandardToolbar = !ShowStandardToolbar; + SaveToolbarChanges(); + } + void SwitchArchiveToolbar() + { + ShowArchiveToolbar = !ShowArchiveToolbar; + SaveToolbarChanges(); + } + void SwitchButtonsLables() + { + ShowButtonsLables = !ShowButtonsLables; + SaveToolbarChanges(); + } + void SwitchLargeButtons() + { + LargeButtons = !LargeButtons; + SaveToolbarChanges(); + } + + void AddToArchive() { GetFocusedPanel().AddToArchive(); } + void ExtractArchives() { GetFocusedPanel().ExtractArchives(); } + void TestArchives() { GetFocusedPanel().TestArchives(); } + + void OnNotify(int ctrlID, LPNMHDR pnmh); + + UString PrevTitle; + void RefreshTitle(bool always = false); + void RefreshTitleAlways() { RefreshTitle(true); } + void RefreshTitlePanel(unsigned panelIndex, bool always = false); + + void MoveSubWindows(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/AppState.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AppState.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/AppState.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/AppState.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,95 +1,95 @@ -// AppState.h - -#ifndef __APP_STATE_H -#define __APP_STATE_H - -#include "../../../Windows/Synchronization.h" - -#include "ViewSettings.h" - -class CFastFolders -{ - NWindows::NSynchronization::CCriticalSection _criticalSection; -public: - UStringVector Strings; - void SetString(unsigned index, const UString &s) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - while (Strings.Size() <= index) - Strings.AddNew(); - Strings[index] = s; - } - UString GetString(unsigned index) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - if (index >= Strings.Size()) - return UString(); - return Strings[index]; - } - void Save() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - SaveFastFolders(Strings); - } - void Read() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - ReadFastFolders(Strings); - } -}; - -class CFolderHistory -{ - NWindows::NSynchronization::CCriticalSection _criticalSection; - UStringVector Strings; - - void Normalize(); - -public: - - void GetList(UStringVector &foldersHistory) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - foldersHistory = Strings; - } - - void AddString(const UString &s); - - void RemoveAll() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - Strings.Clear(); - } - - void Save() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - SaveFolderHistory(Strings); - } - - void Read() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - ReadFolderHistory(Strings); - Normalize(); - } -}; - -struct CAppState -{ - CFastFolders FastFolders; - CFolderHistory FolderHistory; - - void Save() - { - FastFolders.Save(); - FolderHistory.Save(); - } - void Read() - { - FastFolders.Read(); - FolderHistory.Read(); - } -}; - -#endif +// AppState.h + +#ifndef ZIP7_INC_APP_STATE_H +#define ZIP7_INC_APP_STATE_H + +#include "../../../Windows/Synchronization.h" + +#include "ViewSettings.h" + +class CFastFolders +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + UStringVector Strings; + void SetString(unsigned index, const UString &s) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + while (Strings.Size() <= index) + Strings.AddNew(); + Strings[index] = s; + } + UString GetString(unsigned index) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + if (index >= Strings.Size()) + return UString(); + return Strings[index]; + } + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFastFolders(Strings); + } + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFastFolders(Strings); + } +}; + +class CFolderHistory +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + UStringVector Strings; + + void Normalize(); + +public: + + void GetList(UStringVector &foldersHistory) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + foldersHistory = Strings; + } + + void AddString(const UString &s); + + void RemoveAll() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + Strings.Clear(); + } + + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFolderHistory(Strings); + } + + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFolderHistory(Strings); + Normalize(); + } +}; + +struct CAppState +{ + CFastFolders FastFolders; + CFolderHistory FolderHistory; + + void Save() + { + FastFolders.Save(); + FolderHistory.Save(); + } + void Read() + { + FastFolders.Read(); + FolderHistory.Read(); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.cpp 2024-07-09 11:00:00.000000000 +0000 @@ -0,0 +1,1132 @@ +// BrowseDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#include "../../../Common/IntToString.h" + +#ifndef UNDER_CE +#include "../../../Windows/CommonDialog.h" +#include "../../../Windows/Shell.h" +#endif + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileFind.h" + +#ifdef UNDER_CE +#include +#endif + +#include "BrowseDialog.h" + +#define USE_MY_BROWSE_DIALOG + +#ifdef USE_MY_BROWSE_DIALOG + +#include "../../../Common/Defs.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" +#include "../../../Windows/Control/ListView.h" + +#include "BrowseDialogRes.h" +#include "PropertyNameRes.h" +#include "SysIconUtils.h" + +#ifndef Z7_SFX +#include "RegistryUtils.h" +#endif + +#endif // USE_MY_BROWSE_DIALOG + +#include "ComboDialog.h" +#include "LangUtils.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NFind; + +static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) +{ + ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); +} + +#ifdef USE_MY_BROWSE_DIALOG + +#if 0 +extern HINSTANCE g_hInstance; +#endif +extern bool g_LVN_ITEMACTIVATE_Support; + +static const int kParentIndex = -1; +static const UINT k_Message_RefreshPathEdit = WM_APP + 1; + +extern UString HResultToMessage(HRESULT errorCode); + +static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name) +{ + UString s = HResultToMessage(errorCode); + if (name) + { + s.Add_LF(); + s += name; + } + MessageBox_Error_Global(wnd, s); +} + +class CBrowseDialog: public NControl::CModalDialog +{ + NControl::CListView _list; + NControl::CEdit _pathEdit; + NControl::CComboBox _filterCombo; + + CObjectVector _files; + + CExtToIconMap _extToIconMap; + int _sortIndex; + bool _ascending; + #ifndef Z7_SFX + bool _showDots; + #endif + UString _topDirPrefix; // we don't open parent of that folder + UString DirPrefix; + + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); + + void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); } + + bool GetParentPath(const UString &path, UString &parentPrefix, UString &name); + // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter + HRESULT Reload(const UString &pathPrefix, const UString &selectedName); + HRESULT Reload(); + + void OpenParentFolder(); + void SetPathEditText(); + void OnCreateDir(); + void OnItemEnter(); + void FinishOnOK(); + + int GetRealItemIndex(int indexInListView) const + { + LPARAM param; + if (!_list.GetItemParam((unsigned)indexInListView, param)) + return (int)-1; + return (int)param; + } + +public: + + bool SaveMode; + bool FolderMode; + int FilterIndex; // [in / out] + CObjectVector Filters; + + UString FilePath; // [in / out] + UString Title; + + CBrowseDialog(): + #ifndef Z7_SFX + _showDots(false), + #endif + SaveMode(false) + , FolderMode(false) + , FilterIndex(-1) + {} + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE, parent); } + int CompareItems(LPARAM lParam1, LPARAM lParam2) const; +}; + + +bool CBrowseDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + if (!Title.IsEmpty()) + SetText(Title); + _list.Attach(GetItem(IDL_BROWSE)); + _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER)); + _pathEdit.Attach(GetItem(IDE_BROWSE_PATH)); + + #ifndef UNDER_CE + _list.SetUnicodeFormat(); + #endif + + #ifndef Z7_SFX + CFmSettings st; + st.Load(); + if (st.SingleClick) + _list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT); + _showDots = st.ShowDots; + #endif + + { + /* + Filters.Clear(); // for debug + if (Filters.IsEmpty() && !FolderMode) + { + CBrowseFilterInfo &f = Filters.AddNew(); + const UString mask("*.*"); + f.Masks.Add(mask); + // f.Description = "("; + f.Description += mask; + // f.Description += ")"; + } + */ + + FOR_VECTOR (i, Filters) + { + _filterCombo.AddString(Filters[i].Description); + } + + if (Filters.Size() <= 1) + { + if (FolderMode) + HideItem(IDC_BROWSE_FILTER); + else + EnableItem(IDC_BROWSE_FILTER, false); + } + + if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size()) + _filterCombo.SetCurSel(FilterIndex); + } + + _list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL); + _list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL); + + _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100); + _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100); + { + LV_COLUMNW column; + column.iSubItem = 2; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + column.fmt = LVCFMT_RIGHT; + column.cx = 100; + const UString s = LangString(IDS_PROP_SIZE); + column.pszText = s.Ptr_non_const(); + _list.InsertColumn(2, &column); + } + + _list.InsertItem(0, L"12345678901234567" + #ifndef UNDER_CE + L"1234567890" + #endif + ); + _list.SetSubItem(0, 1, L"2009-09-09" + #ifndef UNDER_CE + L" 09:09" + #endif + ); + _list.SetSubItem(0, 2, L"9999 MB"); + for (int i = 0; i < 3; i++) + _list.SetColumnWidthAuto(i); + _list.DeleteAllItems(); + + _ascending = true; + _sortIndex = 0; + + NormalizeSize(); + + _topDirPrefix.Empty(); + { + unsigned rootSize = GetRootPrefixSize(FilePath); + #if defined(_WIN32) && !defined(UNDER_CE) + // We can go up from root folder to drives list + if (IsDrivePath(FilePath)) + rootSize = 0; + else if (IsSuperPath(FilePath)) + { + if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize))) + rootSize = kSuperPathPrefixSize; + } + #endif + _topDirPrefix.SetFrom(FilePath, rootSize); + } + + UString name; + if (!GetParentPath(FilePath, DirPrefix, name)) + DirPrefix = _topDirPrefix; + + for (;;) + { + UString baseFolder = DirPrefix; + if (Reload(baseFolder, name) == S_OK) + break; + name.Empty(); + if (DirPrefix.IsEmpty()) + break; + UString parent, name2; + GetParentPath(DirPrefix, parent, name2); + DirPrefix = parent; + } + + if (name.IsEmpty()) + name = FilePath; + if (FolderMode) + NormalizeDirPathPrefix(name); + _pathEdit.SetText(name); + + #ifndef UNDER_CE + /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible, + even if we use mouse for pressing the button to open this dialog. */ + PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS)); + #endif + +#if 0 + { + const HWND hwndTool = GetItem(IDB_BROWSE_CREATE_DIR); + if (hwndTool) + { + // Create the tooltip: + const HWND hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP + // | TTS_BALLOON + , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + *this, NULL, g_hInstance, NULL); + if (hwndTip) + { + // Associate the tooltip with the tool: + TOOLINFOW toolInfo; + memset(&toolInfo, 0, sizeof(toolInfo)); + toolInfo.cbSize = sizeof(toolInfo); + toolInfo.hwnd = *this; + toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + toolInfo.uId = (UINT_PTR)hwndTool; + UString s; +#ifdef Z7_LANG + LangString_OnlyFromLangFile(IDM_CREATE_FOLDER, s); + s.RemoveChar(L'&'); + if (s.IsEmpty()) +#endif + s = "Create Folder"; + toolInfo.lpszText = s.Ptr_non_const(); + SendMessage(hwndTip, TTM_ADDTOOLW, 0, (LPARAM)&toolInfo); + } + } + } +#endif + return CModalDialog::OnInit(); +} + +bool CBrowseDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + { + RECT r; + GetClientRectOfItem(IDB_BROWSE_PARENT, r); + mx = r.left; + my = r.top; + } + InvalidateRect(NULL); + + int xLim = xSize - mx; + { + RECT r; + GetClientRectOfItem(IDT_BROWSE_FOLDER, r); + MoveItem(IDT_BROWSE_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r)); + } + + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int y = ySize - my - by; + int x = xLim - bx1; + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + + // Y_Size of ComboBox is tricky. So we use Y_Size of _pathEdit instead + + int yPathSize; + { + RECT r; + GetClientRectOfItem(IDE_BROWSE_PATH, r); + yPathSize = RECT_SIZE_Y(r); + _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize); + } + + { + RECT r; + GetClientRectOfItem(IDC_BROWSE_FILTER, r); + _filterCombo.Move(r.left, y - my - yPathSize, xLim - r.left, RECT_SIZE_Y(r)); + } + + { + RECT r; + GetClientRectOfItem(IDL_BROWSE, r); + _list.Move(r.left, r.top, xLim - r.left, y - my - yPathSize - my - yPathSize - my - r.top); + } + + return false; +} + +bool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == k_Message_RefreshPathEdit) + { + SetPathEditText(); + return true; + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + + +bool CBrowseDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_BROWSE_FILTER: + { + Reload(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + + +bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _list) + return false; + switch (header->code) + { + case LVN_ITEMACTIVATE: + if (g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case NM_DBLCLK: + case NM_RETURN: // probably it's unused + if (!g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case LVN_COLUMNCLICK: + { + const int index = LPNMLISTVIEW(header)->iSubItem; + if (index == _sortIndex) + _ascending = !_ascending; + else + { + _ascending = (index == 0); + _sortIndex = index; + } + Reload(); + return false; + } + case LVN_KEYDOWN: + { + bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header)); + Post_RefreshPathEdit(); + return boolResult; + } + case NM_RCLICK: + case NM_CLICK: + case LVN_BEGINDRAG: + Post_RefreshPathEdit(); + break; + } + return false; +} + +bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + const bool ctrl = IsKeyDown(VK_CONTROL); + + switch (keyDownInfo->wVKey) + { + case VK_BACK: + OpenParentFolder(); + return true; + case 'R': + if (ctrl) + { + Reload(); + return true; + } + return false; + case VK_F7: + OnCreateDir(); + return true; + } + return false; +} + + +bool CBrowseDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_BROWSE_PARENT: OpenParentFolder(); break; + case IDB_BROWSE_CREATE_DIR: OnCreateDir(); break; + default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + _list.SetFocus(); + return true; +} + +void CBrowseDialog::OnOK() +{ + /* When we press "Enter" in listview, Windows sends message to first Button. + We check that message was from ListView; */ + if (GetFocus() == _list) + { + OnItemEnter(); + return; + } + FinishOnOK(); +} + + +bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, UString &name) +{ + parentPrefix.Empty(); + name.Empty(); + if (path.IsEmpty()) + return false; + if (_topDirPrefix == path) + return false; + UString s = path; + if (IS_PATH_SEPAR(s.Back())) + s.DeleteBack(); + if (s.IsEmpty()) + return false; + if (IS_PATH_SEPAR(s.Back())) + return false; + const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1); + parentPrefix.SetFrom(s, pos1); + name = s.Ptr(pos1); + return true; +} + +int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) const +{ + if (lParam1 == lParam2) return 0; + if (lParam1 == kParentIndex) return -1; + if (lParam2 == kParentIndex) return 1; + + const CFileInfo &f1 = _files[(int)lParam1]; + const CFileInfo &f2 = _files[(int)lParam2]; + + const bool isDir2 = f2.IsDir(); + if (f1.IsDir()) + { + if (!isDir2) return -1; + } + else if (isDir2) return 1; + + int res = 0; + switch (_sortIndex) + { + case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break; + case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break; + case 2: res = MyCompare(f1.Size, f2.Size); break; + } + return _ascending ? res: -res; +} + +static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2); +} + +wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s); +wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s) +{ + char c = 0; + if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; } + else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; } + else if (v >= ((UInt64)10000 << 0)) { v >>= 10; c = 'K'; } + s = ConvertUInt64ToString(v, s); + if (c != 0) + { + *s++ = ' '; + *s++ = (wchar_t)c; + *s++ = 'B'; + *s = 0; + } + return s; +} + +// Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter + +HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName) +{ + CObjectVector files; + + #ifndef UNDER_CE + bool isDrive = false; + if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix)) + { + isDrive = true; + FStringVector drives; + if (!MyGetLogicalDriveStrings(drives)) + return GetLastError_noZero_HRESULT(); + FOR_VECTOR (i, drives) + { + const FString &d = drives[i]; + if (d.Len() < 2 || d.Back() != '\\') + return E_FAIL; + CFileInfo &fi = files.AddNew(); + fi.SetAsDir(); + fi.Name = d; + fi.Name.DeleteBack(); + } + } + else + #endif + { + const UStringVector *masks = NULL; + if (!Filters.IsEmpty() && _filterCombo.GetCount() > 0) + { + const int selected = _filterCombo.GetCurSel(); + // GetItemData_of_CurSel(); // we don't use data field + if (/* selected >= 0 && */ (unsigned)selected < Filters.Size()) + { + const UStringVector &m = Filters[selected].Masks; + if (m.Size() > 1 || (m.Size() == 1 + && !m[0].IsEqualTo("*.*") + && !m[0].IsEqualTo("*"))) + masks = &m; + } + } + CEnumerator enumerator; + enumerator.SetDirPrefix(us2fs(pathPrefix)); + CFileInfo fi; + for (;;) + { + bool found; + if (!enumerator.Next(fi, found)) + return GetLastError_noZero_HRESULT(); + if (!found) + break; + if (!fi.IsDir()) + { + if (FolderMode) + continue; + if (masks) + { + unsigned i; + const unsigned numMasks = masks->Size(); + for (i = 0; i < numMasks; i++) + if (DoesWildcardMatchName((*masks)[i], fs2us(fi.Name))) + break; + if (i == numMasks) + continue; + } + } + files.Add(fi); + } + } + + DirPrefix = pathPrefix; + + _files = files; + + SetItemText(IDT_BROWSE_FOLDER, DirPrefix); + + _list.SetRedraw(false); + _list.DeleteAllItems(); + + LVITEMW item; + + unsigned index = 0; + int cursorIndex = -1; + + #ifndef Z7_SFX + if (_showDots && _topDirPrefix != DirPrefix) + { + item.iItem = (int)index; + const UString itemName (".."); + if (selectedName.IsEmpty()) + cursorIndex = (int)index; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = kParentIndex; + item.pszText = itemName.Ptr_non_const(); + item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); + _list.SetSubItem(index, subItem++, L""); + _list.SetSubItem(index, subItem++, L""); + index++; + } + #endif + + for (unsigned i = 0; i < _files.Size(); i++, index++) + { + item.iItem = (int)index; + const CFileInfo &fi = _files[i]; + const UString name = fs2us(fi.Name); + if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0) + cursorIndex = (int)index; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = (LPARAM)i; + item.pszText = name.Ptr_non_const(); + + const UString fullPath = DirPrefix + name; + #ifndef UNDER_CE + if (isDrive) + { + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path( + fi.Name + FCHAR_PATH_SEPARATOR, + FILE_ATTRIBUTE_DIRECTORY); + } + else + #endif + item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); + wchar_t s[64]; + { + s[0] = 0; + if (!FILETIME_IsZero(fi.MTime)) + ConvertUtcFileTimeToString(fi.MTime, s, + #ifndef UNDER_CE + kTimestampPrintLevel_MIN + #else + kTimestampPrintLevel_DAY + #endif + ); + _list.SetSubItem(index, subItem++, s); + } + { + s[0] = 0; + if (!fi.IsDir()) + Browse_ConvertSizeToString(fi.Size, s); + _list.SetSubItem(index, subItem++, s); + } + } + + if (_list.GetItemCount() > 0 && cursorIndex >= 0) + _list.SetItemState_FocusedSelected(cursorIndex); + _list.SortItems(CompareItems2, (LPARAM)this); + if (_list.GetItemCount() > 0 && cursorIndex < 0) + _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED); + _list.EnsureVisible(_list.GetFocusedItem(), false); + _list.SetRedraw(true); + _list.InvalidateRect(NULL, true); + return S_OK; +} + +HRESULT CBrowseDialog::Reload() +{ + UString selected; + const int index = _list.GetNextSelectedItem(-1); + if (index >= 0) + { + const int fileIndex = GetRealItemIndex(index); + if (fileIndex != kParentIndex) + selected = fs2us(_files[fileIndex].Name); + } + const UString dirPathTemp = DirPrefix; + return Reload(dirPathTemp, selected); +} + +void CBrowseDialog::OpenParentFolder() +{ + UString parent, selected; + if (GetParentPath(DirPrefix, parent, selected)) + { + Reload(parent, selected); + SetPathEditText(); + } +} + +void CBrowseDialog::SetPathEditText() +{ + const int index = _list.GetNextSelectedItem(-1); + if (index < 0) + { + if (FolderMode) + _pathEdit.SetText(DirPrefix); + return; + } + const int fileIndex = GetRealItemIndex(index); + if (fileIndex == kParentIndex) + { + if (FolderMode) + _pathEdit.SetText(L".." WSTRING_PATH_SEPARATOR); + return; + } + const CFileInfo &file = _files[fileIndex]; + if (file.IsDir()) + { + if (!FolderMode) + return; + _pathEdit.SetText(fs2us(file.Name) + WCHAR_PATH_SEPARATOR); + } + else + _pathEdit.SetText(fs2us(file.Name)); +} + +void CBrowseDialog::OnCreateDir() +{ + UString name; + { + UString enteredName; + Dlg_CreateFolder((HWND)*this, enteredName); + if (enteredName.IsEmpty()) + return; + if (!CorrectFsPath(DirPrefix, enteredName, name)) + { + MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, name); + return; + } + } + if (name.IsEmpty()) + return; + + FString destPath; + if (GetFullPath(us2fs(DirPrefix), us2fs(name), destPath)) + { + if (!NDir::CreateComplexDir(destPath)) + { + MessageBox_HResError((HWND)*this, GetLastError_noZero_HRESULT(), fs2us(destPath)); + } + else + { + UString tempPath = DirPrefix; + Reload(tempPath, name); + SetPathEditText(); + } + _list.SetFocus(); + } +} + +void CBrowseDialog::OnItemEnter() +{ + const int index = _list.GetNextSelectedItem(-1); + if (index < 0) + return; + const int fileIndex = GetRealItemIndex(index); + if (fileIndex == kParentIndex) + OpenParentFolder(); + else + { + const CFileInfo &file = _files[fileIndex]; + if (!file.IsDir()) + { + if (!FolderMode) + FinishOnOK(); + /* + MessageBox_Error_Global(*this, FolderMode ? + L"You must select some folder": + L"You must select some file"); + */ + return; + } + UString s = DirPrefix; + s += fs2us(file.Name); + s.Add_PathSepar(); + const HRESULT res = Reload(s, UString()); + if (res != S_OK) + MessageBox_HResError(*this, res, s); + SetPathEditText(); + } +} + +void CBrowseDialog::FinishOnOK() +{ + UString s; + _pathEdit.GetText(s); + FString destPath; + if (!GetFullPath(us2fs(DirPrefix), us2fs(s), destPath)) + { + MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, s); + return; + } + FilePath = fs2us(destPath); + if (FolderMode) + NormalizeDirPathPrefix(FilePath); + FilterIndex = _filterCombo.GetCurSel(); + End(IDOK); +} + +#endif // USE_MY_BROWSE_DIALOG + + + +bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath) +{ + resultPath.Empty(); + + #ifndef UNDER_CE + +#ifdef USE_MY_BROWSE_DIALOG + if (!IsSuperOrDevicePath(path)) + if (MyStringLen(path) < MAX_PATH) +#endif + return NShell::BrowseForFolder(owner, title, path, resultPath); + + #endif // UNDER_CE + + #ifdef USE_MY_BROWSE_DIALOG + + CBrowseDialog dialog; + dialog.FolderMode = true; + if (title) + dialog.Title = title; + if (path) + dialog.FilePath = path; + if (dialog.Create(owner) != IDOK) + return false; + resultPath = dialog.FilePath; + return true; + + #endif +} + + +// LPCWSTR filterDescription, LPCWSTR filter, + +bool CBrowseInfo::BrowseForFile(const CObjectVector &filters) +{ +#ifndef UNDER_CE +#ifdef USE_MY_BROWSE_DIALOG + /* win10: + GetOpenFileName() for FilePath doesn't support super prefix "\\\\?\\" + GetOpenFileName() for FilePath doesn't support long path + */ + if (!IsSuperOrDevicePath(FilePath)) + // if (filters.Size() > 100) // for debug +#endif + { + const UString filePath_Store = FilePath; + UString dirPrefix; + { + FString prefix, name; + if (NDir::GetFullPathAndSplit(us2fs(FilePath), prefix, name)) + { + dirPrefix = fs2us(prefix); + FilePath = fs2us(name); + } + } + UStringVector filters2; + FOR_VECTOR (i, filters) + { + const CBrowseFilterInfo &fi = filters[i]; + filters2.Add(fi.Description); + UString s; + FOR_VECTOR (k, fi.Masks) + { + if (k != 0) + s += ";"; + s += fi.Masks[k]; + } + filters2.Add(s); + } + if (CommonDlg_BrowseForFile(!dirPrefix.IsEmpty() ? dirPrefix.Ptr(): NULL, filters2)) + return true; + FilePath = filePath_Store; + + #ifdef UNDER_CE + return false; + #else + // maybe we must use GetLastError in WinCE. + const DWORD errorCode = CommDlgExtendedError(); + #ifdef USE_MY_BROWSE_DIALOG + // FNERR_INVALIDFILENAME is expected error, if long path was used + if (errorCode != FNERR_INVALIDFILENAME + || FilePath.Len() < MAX_PATH) + #endif + { + if (errorCode == 0) // cancel or close on dialog + return false; + const char *message = NULL; + if (errorCode == FNERR_INVALIDFILENAME) + message = "Invalid file name"; + UString s ("Open Dialog Error:"); + s.Add_LF(); + if (message) + s += message; + else + { + char temp[16]; + ConvertUInt32ToHex8Digits(errorCode, temp); + s += "Error #"; + s += temp; + } + s.Add_LF(); + s += FilePath; + MessageBox_Error_Global(hwndOwner, s); + } + #endif // UNDER_CE + } + +#endif // UNDER_CE + +#ifdef USE_MY_BROWSE_DIALOG + + CBrowseDialog dialog; + + dialog.FolderMode = false; + dialog.SaveMode = SaveMode; + dialog.FilterIndex = FilterIndex; + dialog.Filters = filters; + + if (lpstrTitle) + dialog.Title = lpstrTitle; + dialog.FilePath = FilePath; + if (dialog.Create(hwndOwner) != IDOK) + return false; + FilePath = dialog.FilePath; + FilterIndex = dialog.FilterIndex; +#endif + + return true; +} + + +#ifdef _WIN32 + +static void RemoveDotsAndSpaces(UString &path) +{ + while (!path.IsEmpty()) + { + wchar_t c = path.Back(); + if (c != ' ' && c != '.') + return; + path.DeleteBack(); + } +} + + +bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result) +{ + result.Empty(); + + UString path = path2; + #ifdef _WIN32 + path.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + unsigned start = 0; + UString base; + + if (IsAbsolutePath(path)) + { + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsSuperOrDevicePath(path)) + { + result = path; + return true; + } + #endif + start = GetRootPrefixSize(path); + } + else + { + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsSuperOrDevicePath(relBase)) + { + result = path; + return true; + } + #endif + base = relBase; + } + + /* We can't use backward, since we must change only disk paths */ + /* + for (;;) + { + if (path.Len() <= start) + break; + if (DoesFileOrDirExist(us2fs(path))) + break; + if (path.Back() == WCHAR_PATH_SEPARATOR) + { + path.DeleteBack(); + result.Insert(0, WCHAR_PATH_SEPARATOR); + } + int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1; + UString cur = path.Ptr(pos); + RemoveDotsAndSpaces(cur); + result.Insert(0, cur); + path.DeleteFrom(pos); + } + result.Insert(0, path); + return true; + */ + + result += path.Left(start); + bool checkExist = true; + UString cur; + + for (;;) + { + if (start == path.Len()) + break; + const int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); + cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : (unsigned)slashPos) - start); + if (checkExist) + { + CFileInfo fi; + if (fi.Find(us2fs(base + result + cur))) + { + if (!fi.IsDir()) + { + result = path; + break; + } + } + else + checkExist = false; + } + if (!checkExist) + RemoveDotsAndSpaces(cur); + result += cur; + if (slashPos < 0) + break; + start = (unsigned)(slashPos + 1); + result.Add_PathSepar(); + } + + return true; +} + +#else + +bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result) +{ + result = path; + return true; +} + +#endif + +bool Dlg_CreateFolder(HWND wnd, UString &destName) +{ + destName.Empty(); + CComboDialog dlg; + LangString(IDS_CREATE_FOLDER, dlg.Title); + LangString(IDS_CREATE_FOLDER_NAME, dlg.Static); + LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value); + if (dlg.Create(wnd) != IDOK) + return false; + destName = dlg.Value; + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.h 2015-06-21 18:31:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,33 +1,32 @@ -// BrowseDialog.h - -#ifndef __BROWSE_DIALOG_H -#define __BROWSE_DIALOG_H - -#include "../../../Common/MyString.h" - -/* FIXME -bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath); -bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath); -*/ -#include "Windows/CommonDialog.h" -#include "Windows/Shell.h" - -#define MyBrowseForFolder(h, title, initialFolder, resultPath) \ - NShell::BrowseForFolder(h, title, initialFolder, resultPath) - -// FIXME : filterDescription -#define MyBrowseForFile(h, title, initialFolder, filterDescription, s, resultPath) \ - MyGetOpenFileName(h, title, NULL, initialFolder,filterDescription, s, resultPath) - - -/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file) - But it doesn't change "bad" name in any of the following cases: - - path is Super Path (with \\?\ prefix) - - path is relative and relBase is Super Path - - there is file or dir in filesystem with specified "bad" name */ - -bool CorrectFsPath(const UString &relBase, const UString &path, UString &result); - -bool Dlg_CreateFolder(HWND wnd, UString &destName); - -#endif +// BrowseDialog.h + +#ifndef ZIP7_INC_BROWSE_DIALOG_H +#define ZIP7_INC_BROWSE_DIALOG_H + +#include "../../../Windows/CommonDialog.h" + +bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath); + +struct CBrowseFilterInfo +{ + UStringVector Masks; + UString Description; +}; + +struct CBrowseInfo: public NWindows::CCommonDialogInfo +{ + bool BrowseForFile(const CObjectVector &filters); +}; + + +/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file) + But it doesn't change "bad" name in any of the following cases: + - path is Super Path (with \\?\ prefix) + - path is relative and relBase is Super Path + - there is file or dir in filesystem with specified "bad" name */ + +bool CorrectFsPath(const UString &relBase, const UString &path, UString &result); + +bool Dlg_CreateFolder(HWND wnd, UString &destName); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog.rc 2012-11-26 08:27:37.000000000 +0000 @@ -0,0 +1,25 @@ +#include "BrowseDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 256 +#define yc 320 + +#define k_BROWSE_y_CtrlSize 14 + +#define k_BROWSE_y_List 24 + +IDD_BROWSE DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "7-Zip: Browse" +{ + EDITTEXT IDE_BROWSE_PATH, m, by - m - k_BROWSE_y_CtrlSize - k_BROWSE_y_CtrlSize - m, xc, k_BROWSE_y_CtrlSize, ES_AUTOHSCROLL + COMBOBOX IDC_BROWSE_FILTER, m, by - m - k_BROWSE_y_CtrlSize, xc, 30, MY_COMBO + + PUSHBUTTON "OK", IDOK, bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + PUSHBUTTON "<--", IDB_BROWSE_PARENT, m, m, 24, bys + PUSHBUTTON "+", IDB_BROWSE_CREATE_DIR, m + 32, m, 24, bys + LTEXT "", IDT_BROWSE_FOLDER, m + 64, m + 3, xc - 20, 8 + CONTROL "List1", IDL_BROWSE, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP, + m, m + k_BROWSE_y_List, xc, yc - bys - m - k_BROWSE_y_List - k_BROWSE_y_CtrlSize - m - k_BROWSE_y_CtrlSize - m +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.cpp 2024-07-09 11:00:00.000000000 +0000 @@ -0,0 +1,1834 @@ +// BrowseDialog2.cpp + +#include "StdAfx.h" + +#ifdef UNDER_CE +#include +#endif + +#include + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/ProcessUtils.h" +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" +#include "../../../Windows/Control/ListView.h" + +#include "../Explorer/MyMessages.h" + +#ifndef Z7_NO_REGISTRY +#include "HelpUtils.h" +#endif + +#include "../Common/PropIDUtils.h" + +#include "PropertyNameRes.h" +#include "RegistryUtils.h" +#include "SysIconUtils.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +#include "resource.h" +#include "BrowseDialog2Res.h" +#include "BrowseDialog2.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NFind; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +extern bool g_LVN_ITEMACTIVATE_Support; + +static const int kParentIndex = -1; +// static const UINT k_Message_RefreshPathEdit = WM_APP + 1; + + +static const wchar_t *k_Message_Link_operation_was_Blocked = + L"link openning was blocked by 7-Zip"; + +extern UString HResultToMessage(HRESULT errorCode); + +static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name) +{ + UString s = HResultToMessage(errorCode); + if (name) + { + s.Add_LF(); + s += name; + } + ShowErrorMessage(wnd, s); +} + +static void MessageBox_LastError_path(HWND wnd, const FString &path) +{ + const HRESULT hres = GetLastError_noZero_HRESULT(); + MessageBox_HResError(wnd, hres, fs2us(path)); +} + + +static const UInt32 k_EnumerateDirsLimit = 200; +static const UInt32 k_EnumerateFilesLimit = 2000; + +struct CBrowseItem +{ + unsigned MainFileIndex; + int SubFileIndex; + bool WasInterrupted; + UInt32 NumFiles; + UInt32 NumDirs; + UInt32 NumRootItems; + UInt64 Size; + + CBrowseItem(): + // MainFileIndex(0), + SubFileIndex(-1), + WasInterrupted(false), + NumFiles(0), + NumDirs(0), + NumRootItems(0), + Size(0) + {} +}; + + +struct CBrowseEnumerator +{ + FString Path; // folder path without slash at the end + CFileInfo fi; // temp + CFileInfo fi_SubFile; + CBrowseItem bi; + + void Enumerate(unsigned level); + bool NeedInterrupt() const + { + return bi.NumFiles >= k_EnumerateFilesLimit + || bi.NumDirs >= k_EnumerateDirsLimit; + } +}; + +void CBrowseEnumerator::Enumerate(unsigned level) +{ + Path.Add_PathSepar(); + const unsigned len = Path.Len(); + CObjectVector names; + { + CEnumerator enumerator; + enumerator.SetDirPrefix(Path); + while (enumerator.Next(fi)) + { + if (level == 0) + { + if (bi.NumRootItems == 0) + fi_SubFile = fi; + bi.NumRootItems++; + } + + if (fi.IsDir()) + { + bi.NumDirs++; + if (!fi.HasReparsePoint()) + names.Add(fi.Name); + } + else + { + bi.NumFiles++; + bi.Size += fi.Size; + } + + if (level != 0 || bi.NumRootItems > 1) + if (NeedInterrupt()) + { + bi.WasInterrupted = true; + return; + } + } + } + + FOR_VECTOR (i, names) + { + if (NeedInterrupt()) + { + bi.WasInterrupted = true; + return; + } + Path.DeleteFrom(len); + Path += names[i]; + Enumerate(level + 1); + } +} + + + + +class CBrowseDialog2: public NControl::CModalDialog +{ + CRecordVector _items; + CObjectVector _files; + + NControl::CListView _list; + // NControl::CEdit _pathEdit; + NControl::CComboBox _filterCombo; + + CExtToIconMap _extToIconMap; + int _sortIndex; + int _columnIndex_fileNameInDir; + int _columnIndex_NumFiles; + int _columnIndex_NumDirs; + bool _ascending; + #ifndef Z7_SFX + bool _showDots; + #endif + UString _topDirPrefix; // we don't open parent of that folder + UString DirPrefix; + + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override; + // virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); + + // void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); } + bool GetParentPath(const UString &path, UString &parentPrefix, UString &name); + // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter + HRESULT Reload(const UString &pathPrefix, const UStringVector &selectedNames, const UString &focusedName); + HRESULT Reload(const UString &pathPrefix, const UString &selectedNames); + HRESULT Reload(); + + void ChangeSorting_and_Reload(int columnIndex); + + const CFileInfo & Get_MainFileInfo_for_realIndex(unsigned realIndex) const + { + return _files[_items[realIndex].MainFileIndex]; + } + + const FString & Get_MainFileName_for_realIndex(unsigned realIndex) const + { + return Get_MainFileInfo_for_realIndex(realIndex).Name; + } + + void Reload_WithErrorMessage(); + void OpenParentFolder(); + // void SetPathEditText(); + void PrintFileProps(UString &s, const CFileInfo &file); + void Show_FileProps_Window(const CFileInfo &file); + void OnItemEnter(); + // void FinishOnOK(); + void OnDelete(/* bool toRecycleBin */); + virtual void OnHelp() Z7_override; + bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); + + int GetRealItemIndex(int indexInListView) const + { + LPARAM param; + if (!_list.GetItemParam((unsigned)indexInListView, param)) + return (int)-1; + return (int)param; + } + + void GetSelected_RealIndexes(CUIntVector &vector); + +public: + // bool TempMode; + // bool Show_Non7zDirs_InTemp; + // int FilterIndex; // [in / out] + // CObjectVector Filters; + + UString TempFolderPath; // with slash + UString Title; + + bool IsExactTempFolder(const UString &pathPrefix) const + { + return CompareFileNames(pathPrefix, TempFolderPath) == 0; + } + + CBrowseDialog2(): + #ifndef Z7_SFX + _showDots(false) + #endif + // , TempMode(false) + // Show_Non7zDirs_InTemp(false), + // FilterIndex(-1) + {} + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE2, parent); } + int CompareItems(LPARAM lParam1, LPARAM lParam2) const; +}; + + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDS_BUTTON_DELETE, + IDM_VIEW_REFRESH +}; +#endif + +bool CBrowseDialog2::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + if (!Title.IsEmpty()) + SetText(Title); + + _list.Attach(GetItem(IDL_BROWSE2)); + _filterCombo.Attach(GetItem(IDC_BROWSE2_FILTER)); + + _ascending = true; + _sortIndex = 0; + _columnIndex_fileNameInDir = -1; + _columnIndex_NumFiles = -1; + _columnIndex_NumDirs = -1; + // _pathEdit.Attach(GetItem(IDE_BROWSE_PATH)); + + #ifndef UNDER_CE + _list.SetUnicodeFormat(); + #endif + + #ifndef Z7_SFX + { + CFmSettings st; + st.Load(); + + DWORD extendedStyle = 0; + if (st.FullRow) + extendedStyle |= LVS_EX_FULLROWSELECT; + if (st.ShowGrid) + extendedStyle |= LVS_EX_GRIDLINES; + if (st.SingleClick) + { + extendedStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT; + /* + if (ReadUnderline()) + extendedStyle |= LVS_EX_UNDERLINEHOT; + */ + } + if (extendedStyle) + _list.SetExtendedListViewStyle(extendedStyle); + _showDots = st.ShowDots; + } + #endif + + { + /* + Filters.Clear(); // for debug + if (Filters.IsEmpty() && !FolderMode) + { + CBrowseFilterInfo &f = Filters.AddNew(); + const UString mask("*.*"); + f.Masks.Add(mask); + // f.Description = "("; + f.Description += mask; + // f.Description += ")"; + } + */ + _filterCombo.AddString(L"7-Zip temp files (7z*)"); + _filterCombo.SetCurSel(0); + EnableItem(IDC_BROWSE2_FILTER, false); +#if 0 + FOR_VECTOR (i, Filters) + { + _filterCombo.AddString(Filters[i].Description); + } + if (Filters.Size() <= 1) + { + EnableItem(IDC_BROWSE_FILTER, false); + } + if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size()) + _filterCombo.SetCurSel(FilterIndex); +#endif + } + + _list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL); + _list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL); + + unsigned columnIndex = 0; + _list.InsertColumn(columnIndex++, LangString(IDS_PROP_NAME), 100); + _list.InsertColumn(columnIndex++, LangString(IDS_PROP_MTIME), 100); + { + LV_COLUMNW column; + column.iSubItem = (int)columnIndex; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + column.fmt = LVCFMT_RIGHT; + column.cx = 100; + UString s = LangString(IDS_PROP_SIZE); + column.pszText = s.Ptr_non_const(); + _list.InsertColumn(columnIndex++, &column); + + // if (TempMode) + { + _columnIndex_NumFiles = (int)columnIndex; + s = LangString(IDS_PROP_FILES); + column.pszText = s.Ptr_non_const(); + _list.InsertColumn(columnIndex++, &column); + + _columnIndex_NumDirs = (int)columnIndex; + s = LangString(IDS_PROP_FOLDERS); + column.pszText = s.Ptr_non_const(); + _list.InsertColumn(columnIndex++, &column); + + _columnIndex_fileNameInDir = (int)columnIndex; + s = LangString(IDS_PROP_NAME); + s += "-2"; + _list.InsertColumn(columnIndex++, s, 100); + } + } + + _list.InsertItem(0, L"12345678901234567" + #ifndef UNDER_CE + L"1234567890" + #endif + ); + _list.SetSubItem(0, 1, L"2009-09-09" + #ifndef UNDER_CE + L" 09:09:09" + #endif + ); + _list.SetSubItem(0, 2, L"99999 MB+"); + + if (_columnIndex_NumFiles >= 0) + _list.SetSubItem(0, (unsigned)_columnIndex_NumFiles, L"123456789+"); + if (_columnIndex_NumDirs >= 0) + _list.SetSubItem(0, (unsigned)_columnIndex_NumDirs, L"123456789+"); + if (_columnIndex_fileNameInDir >= 0) + _list.SetSubItem(0, (unsigned)_columnIndex_fileNameInDir, L"12345678901234567890"); + + for (unsigned i = 0; i < columnIndex; i++) + _list.SetColumnWidthAuto((int)i); + _list.DeleteAllItems(); + + // if (TempMode) + { + _sortIndex = 1; // for MTime column + // _ascending = false; + } + + + NormalizeSize(); + + _topDirPrefix.Empty(); + { + unsigned rootSize = GetRootPrefixSize(TempFolderPath); + #if defined(_WIN32) && !defined(UNDER_CE) + // We can go up from root folder to drives list + if (IsDrivePath(TempFolderPath)) + rootSize = 0; + else if (IsSuperPath(TempFolderPath)) + { + if (IsDrivePath(TempFolderPath.Ptr(kSuperPathPrefixSize))) + rootSize = kSuperPathPrefixSize; + } + #endif + _topDirPrefix.SetFrom(TempFolderPath, rootSize); + } + + if (Reload(TempFolderPath, UString()) != S_OK) + { + // return false; + } +/* + UString name; + DirPrefix = TempFolderPath; + for (;;) + { + UString baseFolder = DirPrefix; + if (Reload(baseFolder, name) == S_OK) + break; + name.Empty(); + if (DirPrefix.IsEmpty()) + break; + UString parent, name2; + GetParentPath(DirPrefix, parent, name2); + DirPrefix = parent; + } +*/ + + #ifndef UNDER_CE + /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible, + even if we use mouse for pressing the button to open this dialog. */ + PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS)); + #endif + + /* + */ + + return CModalDialog::OnInit(); +} + + +bool CBrowseDialog2::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + { + RECT r; + GetClientRectOfItem(IDS_BUTTON_DELETE, r); + mx = r.left; + my = r.top; + } + InvalidateRect(NULL); + + const int xLim = xSize - mx; + { + RECT r; + GetClientRectOfItem(IDT_BROWSE2_FOLDER, r); + MoveItem(IDT_BROWSE2_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r)); + } + + int bx1, bx2, by; + GetItemSizes(IDCLOSE, bx1, by); + GetItemSizes(IDHELP, bx2, by); + const int y = ySize - my - by; + const int x = xLim - bx1; + MoveItem(IDCLOSE, x - mx - bx2, y, bx1, by); + MoveItem(IDHELP, x, y, bx2, by); + /* + int yPathSize; + { + RECT r; + GetClientRectOfItem(IDE_BROWSE_PATH, r); + yPathSize = RECT_SIZE_Y(r); + _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize); + } + */ + // Y_Size of ComboBox is tricky. Can we use it? + int yFilterSize; + { + RECT r; + GetClientRectOfItem(IDC_BROWSE2_FILTER, r); + yFilterSize = RECT_SIZE_Y(r); + _filterCombo.Move(r.left, y - my - yFilterSize, xLim - r.left, yFilterSize); + } + { + RECT r; + GetClientRectOfItem(IDL_BROWSE2, r); + _list.Move(r.left, r.top, xLim - r.left, y - my - yFilterSize - my - r.top); + } + return false; +} + + +bool CBrowseDialog2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + /* + if (message == k_Message_RefreshPathEdit) + { + // SetPathEditText(); + return true; + } + */ + if (message == WM_CONTEXTMENU) + { + if (OnContextMenu((HANDLE)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) + return true; + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + + +/* +bool CBrowseDialog2::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_BROWSE2_FILTER: + { + Reload(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} +*/ + +bool CBrowseDialog2::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _list) + { + if (::GetParent(header->hwndFrom) == _list) + { + // NMHDR:code is UINT + // NM_RCLICK is unsigned in windows sdk + // NM_RCLICK is int in MinGW + if (header->code == (UINT)NM_RCLICK) + { +#ifdef UNDER_CE +#define MY_NMLISTVIEW_NMITEMACTIVATE NMLISTVIEW +#else +#define MY_NMLISTVIEW_NMITEMACTIVATE NMITEMACTIVATE +#endif + MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate = (MY_NMLISTVIEW_NMITEMACTIVATE *)header; + if (itemActivate->hdr.hwndFrom == HWND(_list)) + return false; + /* + POINT point; + ::GetCursorPos(&point); + ShowColumnsContextMenu(point.x, point.y); + */ + // we want to disable menu for columns. + // to return the value from a dialog procedure we must + // call SetMsgResult(val) and return true; + // NM_RCLICK : Return nonzero to not allow the default processing + SetMsgResult(TRUE); // do not allow default processing + return true; + } + } + return false; + } + + switch (header->code) + { + case LVN_ITEMACTIVATE: + if (g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case NM_DBLCLK: + case NM_RETURN: // probably it's unused + if (!g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case LVN_COLUMNCLICK: + { + const int index = LPNMLISTVIEW(header)->iSubItem; + ChangeSorting_and_Reload(index); + return false; + } + case LVN_KEYDOWN: + { + bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header)); + // Post_RefreshPathEdit(); + return boolResult; + } + /* + case NM_RCLICK: + case NM_CLICK: + case LVN_BEGINDRAG: + Post_RefreshPathEdit(); + break; + */ + } + + return false; +} + +bool CBrowseDialog2::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + const bool ctrl = IsKeyDown(VK_CONTROL); + // const bool alt = IsKeyDown(VK_MENU); + // const bool leftCtrl = IsKeyDown(VK_LCONTROL); + // const bool rightCtrl = IsKeyDown(VK_RCONTROL); + // const bool shift = IsKeyDown(VK_SHIFT); + + switch (keyDownInfo->wVKey) + { + case VK_BACK: + OpenParentFolder(); + return true; + case 'R': + if (ctrl) + { + Reload_WithErrorMessage(); + return true; + } + return false; + case VK_F3: + case VK_F5: + case VK_F6: + if (ctrl) + { + int index = 0; // name + if (keyDownInfo->wVKey == VK_F5) index = 1; // MTime + else if (keyDownInfo->wVKey == VK_F6) index = 2; // Size + ChangeSorting_and_Reload(index); + Reload_WithErrorMessage(); + return true; + } + return false; + case 'A': + if (ctrl) + { + // if (TempMode) + _list.SelectAll(); + return true; + } + return false; + + case VK_DELETE: + // if (TempMode) + OnDelete(/* !shift */); + return true; +#if 0 + case VK_NEXT: + case VK_PRIOR: + { + if (ctrl && !alt && !shift) + { + if (keyDownInfo->wVKey == VK_NEXT) + OnItemEnter(); + else + OpenParentFolder(); + SetMsgResult(TRUE); // to disable processing + return true; + } + break; + } +#endif + } + return false; +} + + +bool CBrowseDialog2::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_BROWSE2_PARENT: OpenParentFolder(); break; + case IDS_BUTTON_DELETE: + { + OnDelete(/* !IsKeyDown(VK_SHIFT) */); + break; + } + case IDM_VIEW_REFRESH: + { + Reload_WithErrorMessage(); + break; + } + default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + _list.SetFocus(); + return true; +} + + + +static void PrintPropsPrefix(UString &s, UInt32 id) +{ + s.Add_LF(); + s += " "; + AddLangString(s, id); + s += ": "; +} + +wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s); + +static void Browse_ConvertSizeToString(const CBrowseItem &bi, wchar_t *s) +{ + s = Browse_ConvertSizeToString(bi.Size, s); + if (bi.WasInterrupted) + { + *s++ = '+'; + *s = 0; + } +} + +void AddSizeValue(UString &s, UInt64 value); + +static void PrintProps_Size(UString &s, UInt64 size) +{ + PrintPropsPrefix(s, IDS_PROP_SIZE); +#if 1 + AddSizeValue(s, size); +#else + s.Add_UInt64(size); + if (size >= 10000) + { + s += " ("; + wchar_t temp[64]; + Browse_ConvertSizeToString(size, temp); + s += temp; + s.Add_Char(')'); + } +#endif +} + +static void PrintProps_MTime(UString &s, const CFileInfo &fi) +{ + PrintPropsPrefix(s, IDS_PROP_MTIME); + char t[64]; + ConvertUtcFileTimeToString(fi.MTime, t); + s += t; +} + + +static void PrintProps_Name(UString &s, const CFileInfo &fi) +{ + s += fs2us(fi.Name); + if (fi.IsDir()) + s.Add_PathSepar(); +} + +static void PrintProps_Attrib(UString &s, const CFileInfo &fi) +{ + PrintPropsPrefix(s, IDS_PROP_ATTRIBUTES); + char props[64]; + ConvertWinAttribToString(props, fi.Attrib); + s += props; +#if 0 + if (fi.HasReparsePoint()) + { + s.Add_LF(); + s += "IsLink: +"; + } +#endif +} + +static void PrintProps(UString &s, const CBrowseItem &bi, + const CFileInfo &fi, const CFileInfo *fi2) +{ + PrintProps_Name(s, fi); + PrintProps_Attrib(s, fi); + if (bi.NumDirs != 0) + { + PrintPropsPrefix(s, IDS_PROP_FOLDERS); + s.Add_UInt32(bi.NumDirs); + if (bi.WasInterrupted) + s += "+"; + } + if (bi.NumFiles != 0) + { + PrintPropsPrefix(s, IDS_PROP_FILES); + s.Add_UInt32(bi.NumFiles); + if (bi.WasInterrupted) + s += "+"; + } + { + PrintProps_Size(s, bi.Size); + if (bi.WasInterrupted) + s += "+"; + } + + PrintProps_MTime(s, fi); + + if (fi2) + { + s.Add_LF(); + s += "----------------"; + s.Add_LF(); + PrintProps_Name(s, *fi2); + PrintProps_Attrib(s, *fi2); + if (!fi2->IsDir()) + PrintProps_Size(s, fi2->Size); + PrintProps_MTime(s, *fi2); + } +} + + +void CBrowseDialog2::GetSelected_RealIndexes(CUIntVector &vector) +{ + vector.Clear(); + int index = -1; + for (;;) + { + index = _list.GetNextSelectedItem(index); + if (index < 0) + break; + const int realIndex = GetRealItemIndex(index); + if (realIndex >= 0) + vector.Add((unsigned)realIndex); + } +} + + +void CBrowseDialog2::PrintFileProps(UString &s, const CFileInfo &file) +{ + CFileInfo file2; + FString path = us2fs(DirPrefix); + path += file.Name; + if (!file2.Find(path)) + { + MessageBox_LastError_path(*this, path); + Reload_WithErrorMessage(); + return; + } + CBrowseEnumerator enumer; + enumer.bi.Size = file2.Size; + if (file2.IsDir() && !file2.HasReparsePoint()) + { + enumer.Path = path; + enumer.Enumerate(0); // level + } + PrintProps(s, enumer.bi, file2, + enumer.bi.NumRootItems == 1 ? &enumer.fi_SubFile : NULL); +} + + +void CBrowseDialog2::Show_FileProps_Window(const CFileInfo &file) +{ + UString s; + PrintFileProps(s, file); + MessageBoxW(*this, s, LangString(IDS_PROPERTIES), MB_OK); +} + + +void CBrowseDialog2::OnDelete(/* bool toRecycleBin */) +{ +#if 1 + // we don't want deleting in non temp folders + if (!DirPrefix.IsPrefixedBy(TempFolderPath)) + return; +#endif + + CUIntVector indices; + GetSelected_RealIndexes(indices); + if (indices.Size() == 0) + return; + { + UInt32 titleID, messageID; + UString messageParam; + UString s2; + if (indices.Size() == 1) + { + const unsigned index = indices[0]; + const CBrowseItem &bi = _items[index]; + const CFileInfo &file = _files[bi.MainFileIndex]; + PrintFileProps(s2, file); + messageParam = fs2us(file.Name); + if (file.IsDir()) + { + titleID = IDS_CONFIRM_FOLDER_DELETE; + messageID = IDS_WANT_TO_DELETE_FOLDER; + } + else + { + titleID = IDS_CONFIRM_FILE_DELETE; + messageID = IDS_WANT_TO_DELETE_FILE; + } + } + else + { + titleID = IDS_CONFIRM_ITEMS_DELETE; + messageID = IDS_WANT_TO_DELETE_ITEMS; + messageParam = NumberToString(indices.Size()); + + for (UInt32 i = 0; i < indices.Size(); i++) + { + if (i >= 10) + { + s2 += "..."; + break; + } + const CBrowseItem &bi = _items[indices[i]]; + const CFileInfo &fi = _files[bi.MainFileIndex]; + PrintProps_Name(s2, fi); + s2.Add_LF(); + } + } + UString s = MyFormatNew(messageID, messageParam); + if (!s2.IsEmpty()) + { + s.Add_LF(); + s.Add_LF(); + s += s2; + } + if (::MessageBoxW((HWND)*this, s, LangString(titleID), + MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) + return; + } + + for (UInt32 i = 0; i < indices.Size(); i++) + { + const unsigned index = indices[i]; + bool result = true; + const CBrowseItem &bi = _items[index]; + const CFileInfo &fi = _files[bi.MainFileIndex]; + if (fi.Name.IsEmpty()) + return; // some error + const FString fullPath = us2fs(DirPrefix) + fi.Name; + if (fi.IsDir()) + result = NFile::NDir::RemoveDirWithSubItems(fullPath); + else + result = NFile::NDir::DeleteFileAlways(fullPath); + if (!result) + { + MessageBox_LastError_path(*this, fullPath); + return; + } + } + + Reload_WithErrorMessage(); +} + + +#ifndef Z7_NO_REGISTRY +#define kHelpTopic "fm/temp.htm" +void CBrowseDialog2::OnHelp() +{ + ShowHelpWindow(kHelpTopic); + CModalDialog::OnHelp(); +} +#endif + + +HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process); +HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process) +{ + UString path2 = path; + + #ifdef _WIN32 + { + const int dot = path2.ReverseFind_Dot(); + const int separ = path2.ReverseFind_PathSepar(); + if (dot < 0 || dot < separ) + path2.Add_Dot(); + } + #endif + + UINT32 result; + +#ifndef _UNICODE + if (g_IsNT) + { + SHELLEXECUTEINFOW execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = path2; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = NULL; +typedef BOOL (WINAPI * Func_ShellExecuteExW)(LPSHELLEXECUTEINFOW lpExecInfo); +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + const + Func_ShellExecuteExW + f_ShellExecuteExW = Z7_GET_PROC_ADDRESS( + Func_ShellExecuteExW, ::GetModuleHandleW(L"shell32.dll"), + "ShellExecuteExW"); + if (!f_ShellExecuteExW) + return 0; + f_ShellExecuteExW(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + process.Attach(execInfo.hProcess); + } + else +#endif + { + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS + #ifndef UNDER_CE + | SEE_MASK_FLAG_DDEWAIT + #endif + ; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + const CSysString sysPath (GetSystemString(path2)); + const CSysString sysDir (GetSystemString(dir)); + execInfo.lpFile = sysPath; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = + #ifdef UNDER_CE + NULL + #else + sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir + #endif + ; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = NULL; + ::ShellExecuteEx(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + process.Attach(execInfo.hProcess); + } + + // DEBUG_PRINT_NUM("-- ShellExecuteEx -- execInfo.hInstApp = ", result) + + if (result <= 32) + { + switch (result) + { + case SE_ERR_NOASSOC: + MessageBox_HResError(window, + GetLastError_noZero_HRESULT(), + NULL + // L"There is no application associated with the given file name extension", + ); + } + + return E_FAIL; // fixed in 15.13. Can we use it for any Windows version? + } + + return S_OK; +} + +void StartApplicationDontWait(const UString &dir, const UString &path, HWND window); +void StartApplicationDontWait(const UString &dir, const UString &path, HWND window) +{ + CProcess process; + StartApplication(dir, path, window, process); +} + + +static UString GetQuotedString2(const UString &s) +{ + UString s2 ('\"'); + s2 += s; + s2.Add_Char('\"'); + return s2; +} + + +bool CBrowseDialog2::OnContextMenu(HANDLE windowHandle, int xPos, int yPos) +{ + if (windowHandle != _list) + return false; + + CUIntVector indices; + GetSelected_RealIndexes(indices); + + // negative x,y are possible for multi-screen modes. + // x=-1 && y=-1 for keyboard call (SHIFT+F10 and others). +#if 1 // 0 : for debug + if (xPos == -1 && yPos == -1) +#endif + { +/* + if (indices.Size() == 0) + { + xPos = 0; + yPos = 0; + } + else +*/ + { + const int itemIndex = _list.GetFocusedItem(); + if (itemIndex == -1) + return false; + RECT rect; + if (!_list.GetItemRect(itemIndex, &rect, LVIR_ICON)) + return false; + // rect : rect of file icon relative to listVeiw. + xPos = (rect.left + rect.right) / 2; + yPos = (rect.top + rect.bottom) / 2; + RECT r; + GetClientRectOfItem(IDL_BROWSE2, r); + if (yPos < 0 || yPos >= RECT_SIZE_Y(r)) + yPos = 0; + } + POINT point = {xPos, yPos}; + _list.ClientToScreen(&point); + xPos = point.x; + yPos = point.y; + } + + const UInt32 k_CmdId_Delete = 1; + const UInt32 k_CmdId_Open_Explorer = 2; + const UInt32 k_CmdId_Open_7zip = 3; + const UInt32 k_CmdId_Props = 4; + int menuResult; + { + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + menu.CreatePopup(); + + unsigned numMenuItems = 0; + // unsigned defaultCmd = 0; + + for (unsigned cmd = k_CmdId_Delete; cmd <= k_CmdId_Props; cmd++) + { + if (cmd == k_CmdId_Delete) + { + if (/* !TempMode || */ indices.Size() == 0) + continue; + // defaultCmd = cmd; + } + else if (indices.Size() > 1) + break; + + + if (numMenuItems != 0) + { + if (cmd == k_CmdId_Open_Explorer) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); + if (cmd == k_CmdId_Props) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); + } + + const UINT flags = MF_STRING; + UString s; + if (cmd == k_CmdId_Delete) + { + s = LangString(IDS_BUTTON_DELETE); + s += "\tDelete"; + } + else if (cmd == k_CmdId_Open_Explorer) + { + s = LangString(IDM_OPEN_OUTSIDE); + if (s.IsEmpty()) + s = "Open Outside"; + s += "\tShift+Enter"; + } + else if (cmd == k_CmdId_Open_7zip) + { + s = LangString(IDM_OPEN_OUTSIDE); + if (s.IsEmpty()) + s = "Open Outside"; + s += " : 7-Zip"; + } + else if (cmd == k_CmdId_Props) + { + s = LangString(IDS_PROPERTIES); + if (s.IsEmpty()) + s = "Properties"; + s += "\tAlt+Enter"; + } + else + break; + s.RemoveChar(L'&'); + menu.AppendItem(flags, cmd, s); + numMenuItems++; + } + // default item is useless for us + /* + if (defaultCmd != 0) + SetMenuDefaultItem(menu, (unsigned)defaultCmd, + FALSE); // byPos + */ + /* hwnd for TrackPopupMenuEx(): DOCS: + A handle to the window that owns the shortcut menu. + This window receives all messages from the menu. + The window does not receive a WM_COMMAND message from the menu + until the function returns. + If you specify TPM_NONOTIFY in the fuFlags parameter, + the function does not send messages to the window identified by hwnd. + */ + if (numMenuItems == 0) + return true; + menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + xPos, yPos, *this); + /* menu.Track() return value is zero, if the user cancels + the menu without making a selection, or if an error occurs */ + if (menuResult <= 0) + return true; + } + + if (menuResult == k_CmdId_Delete) + { + OnDelete(/* !IsKeyDown(VK_SHIFT) */); + return true; + } + + if (indices.Size() <= 1) + { + UString fullPath = DirPrefix; + if (indices.Size() != 0) + { + const CBrowseItem &bi = _items[indices[0]]; + const CFileInfo &file = _files[bi.MainFileIndex]; + if (file.HasReparsePoint()) + { + // we don't want external program was used to work with Links + ShowErrorMessage(*this, k_Message_Link_operation_was_Blocked); + return true; + } + fullPath += fs2us(file.Name); + } + if (menuResult == k_CmdId_Open_Explorer) + { + StartApplicationDontWait(DirPrefix, fullPath, (HWND)*this); + return true; + } + + if (menuResult == k_CmdId_Open_7zip) + { + UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix()); + imageName += "7zFM.exe"; + WRes wres; + { + CProcess process; + wres = process.Create(imageName, GetQuotedString2(fullPath), NULL); // curDir + } + if (wres != 0) + { + const HRESULT hres = HRESULT_FROM_WIN32(wres); + MessageBox_HResError(*this, hres, imageName); + } + return true; + } + + if (indices.Size() == 1) + if (menuResult == k_CmdId_Props) + { + const CBrowseItem &bi = _items[indices[0]]; + const CFileInfo &file = _files[bi.MainFileIndex]; + Show_FileProps_Window(file); + return true; + } + } + + return true; +} + + + +struct CWaitCursor2 +{ + HCURSOR _waitCursor; + HCURSOR _oldCursor; + + CWaitCursor2(): + _waitCursor(NULL), + _oldCursor(NULL) + {} + void Set() + { + if (!_waitCursor) + { + _waitCursor = LoadCursor(NULL, IDC_WAIT); + if (_waitCursor) + _oldCursor = SetCursor(_waitCursor); + } + } + ~CWaitCursor2() + { + if (_waitCursor) + SetCursor(_oldCursor); + } +}; + + +void CBrowseDialog2::OnOK() +{ + /* DOCS: + If a dialog box or one of its controls currently has the input focus, + then pressing the ENTER key causes Windows to send a WM_COMMAND message + with the idItem (wParam) parameter set to the ID of the default command button. + If the dialog box does not have a default command button, + then the idItem parameter is set to IDOK by default. + + We process IDOK here for Enter pressing, because we have no DEFPUSHBUTTON. + */ + if (GetFocus() == _list) + { + OnItemEnter(); + return; + } + // Enter can be pressed in another controls (Edit). + // So we don't need End() call here +} + + +bool CBrowseDialog2::GetParentPath(const UString &path, UString &parentPrefix, UString &name) +{ + parentPrefix.Empty(); + name.Empty(); + if (path.IsEmpty()) + return false; + if (_topDirPrefix == path) + return false; + UString s = path; + if (IS_PATH_SEPAR(s.Back())) + s.DeleteBack(); + if (s.IsEmpty()) + return false; + if (IS_PATH_SEPAR(s.Back())) + return false; + const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1); + parentPrefix.SetFrom(s, pos1); + name = s.Ptr(pos1); + return true; +} + + +int CBrowseDialog2::CompareItems(LPARAM lParam1, LPARAM lParam2) const +{ + if (lParam1 == lParam2) return 0; + if (lParam1 == kParentIndex) return -1; + if (lParam2 == kParentIndex) return 1; + + const int index1 = (int)lParam1; + const int index2 = (int)lParam2; + + const CBrowseItem &item1 = _items[index1]; + const CBrowseItem &item2 = _items[index2]; + + const CFileInfo &f1 = _files[item1.MainFileIndex]; + const CFileInfo &f2 = _files[item2.MainFileIndex]; + + const bool isDir2 = f2.IsDir(); + if (f1.IsDir()) + { + if (!isDir2) return -1; + } + else if (isDir2) return 1; + + const int res2 = MyCompare(index1, index2); + int res = 0; + switch (_sortIndex) + { + case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break; + case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break; + case 2: res = MyCompare(item1.Size, item2.Size); break; + case 3: res = MyCompare(item1.NumFiles, item2.NumFiles); break; + case 4: res = MyCompare(item1.NumDirs, item2.NumDirs); break; + case 5: + { + const int sub1 = item1.SubFileIndex; + const int sub2 = item2.SubFileIndex; + if (sub1 < 0) + { + if (sub2 >= 0) + res = -1; + } + else if (sub2 < 0) + res = 1; + else + res = CompareFileNames(fs2us(_files[sub1].Name), fs2us(_files[sub2].Name)); + break; + } + } + if (res == 0) + res = res2; + return _ascending ? res: -res; +} + +static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + return ((CBrowseDialog2 *)lpData)->CompareItems(lParam1, lParam2); +} + + +static const FChar *FindNonHexChar_F(const FChar *s) throw() +{ + for (;;) + { + const FChar c = (FChar)*s++; // pointer can go 1 byte after end + if ( (c < '0' || c > '9') + && (c < 'a' || c > 'z') + && (c < 'A' || c > 'Z')) + return s - 1; + } +} + + +void CBrowseDialog2::Reload_WithErrorMessage() +{ + const HRESULT res = Reload(); + if (res != S_OK) + MessageBox_HResError(*this, res, DirPrefix); +} + +void CBrowseDialog2::ChangeSorting_and_Reload(int columnIndex) +{ + if (columnIndex == _sortIndex) + _ascending = !_ascending; + else + { + _ascending = (columnIndex == 0 || columnIndex == _columnIndex_fileNameInDir); // for name columns + _sortIndex = columnIndex; + } + Reload_WithErrorMessage(); +} + + +// Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter +HRESULT CBrowseDialog2::Reload(const UString &pathPrefix, const UString &selectedName) +{ + UStringVector selectedVector; + if (!selectedName.IsEmpty()) + selectedVector.Add(selectedName); + return Reload(pathPrefix, selectedVector, selectedName); +} + + +HRESULT CBrowseDialog2::Reload(const UString &pathPrefix, const UStringVector &selectedVector2, const UString &focusedName) +{ + UStringVector selectedVector = selectedVector2; + selectedVector.Sort(); + CObjectVector files; + CRecordVector items; + CWaitCursor2 waitCursor; + + #ifndef UNDER_CE + bool isDrive = false; + if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix)) + { + isDrive = true; + FStringVector drives; + if (!MyGetLogicalDriveStrings(drives)) + return GetLastError_noZero_HRESULT(); + FOR_VECTOR (i, drives) + { + const FString &d = drives[i]; + if (d.Len() < 2 || d.Back() != '\\') + return E_FAIL; + CBrowseItem item; + item.MainFileIndex = files.Size(); + CFileInfo &fi = files.AddNew(); + fi.SetAsDir(); + fi.Name = d; + fi.Name.DeleteBack(); + items.Add(item); + } + } + else + #endif + { + { + CEnumerator enumerator; + enumerator.SetDirPrefix(us2fs(pathPrefix)); + CFileInfo fi; + FString tail; + + const bool isTempFolder = ( + // TempMode && + IsExactTempFolder(pathPrefix) + ); + for (;;) + { + { + bool found; + if (!enumerator.Next(fi, found)) + return GetLastError_noZero_HRESULT(); + if (!found) + break; + } + if (isTempFolder) + { + // if (!Show_Non7zDirs_InTemp) + { + if (!fi.Name.IsPrefixedBy_Ascii_NoCase("7z")) + continue; + tail = fi.Name.Ptr(2); + if ( !tail.IsPrefixedBy_Ascii_NoCase("E") // drag and drop / Copy / create to email + && !tail.IsPrefixedBy_Ascii_NoCase("O") // open + && !tail.IsPrefixedBy_Ascii_NoCase("S")) // SFXSetup + continue; + const FChar *beg = tail.Ptr(1); + const FChar *end = FindNonHexChar_F(beg); + if (end - beg != 8 || *end != 0) + continue; + } + } + CBrowseItem item; + item.MainFileIndex = files.Size(); + item.Size = fi.Size; + files.Add(fi); + items.Add(item); + } + } + + UInt64 cnt = items.Size(); + // if (TempMode) + { + FOR_VECTOR (i, items) + { + CBrowseItem &item = items[i]; + const CFileInfo &fi = files[item.MainFileIndex]; + if (!fi.IsDir() || fi.HasReparsePoint()) + continue; + + CBrowseEnumerator enumer; + // we need to keep MainFileIndex and Size value of item: + enumer.bi = item; // don't change it + enumer.Path = us2fs(pathPrefix); + enumer.Path += fi.Name; + enumer.Enumerate(0); // level + item = enumer.bi; + if (item.NumRootItems == 1) + { + item.SubFileIndex = (int)files.Size(); + files.Add(enumer.fi_SubFile); + } + cnt += item.NumDirs; + cnt += item.NumFiles; + if (cnt > 1000) + waitCursor.Set(); + } + } + } + _items = items; + _files = files; + + DirPrefix = pathPrefix; + + EnableItem(IDB_BROWSE2_PARENT, !IsExactTempFolder(pathPrefix)); + + SetItemText(IDT_BROWSE2_FOLDER, DirPrefix); + + _list.SetRedraw(false); + _list.DeleteAllItems(); + + LVITEMW item; + + unsigned index = 0; + int cursorIndex = -1; + + #ifndef Z7_SFX + if (_showDots && _topDirPrefix != DirPrefix) + { + item.iItem = (int)index; + const UString itemName (".."); + if (focusedName == itemName) + cursorIndex = (int)index; + /* + if (selectedVector.IsEmpty() + // && focusedName.IsEmpty() + // && focusedName == ".." + ) + cursorIndex = (int)index; + */ + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = kParentIndex; + item.pszText = itemName.Ptr_non_const(); + item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); +#if 0 + for (int k = 1; k < 6; k++) + _list.SetSubItem(index, subItem++, L"2"); +#endif + index++; + } + #endif + + for (unsigned i = 0; i < _items.Size(); i++, index++) + { + item.iItem = (int)index; + const CBrowseItem &bi = _items[i]; + const CFileInfo &fi = _files[bi.MainFileIndex]; + const UString name = fs2us(fi.Name); + // if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0) + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + item.state = 0; + if (selectedVector.FindInSorted(name) != -1) + { + /* + if (cursorIndex == -1) + cursorIndex = (int)index; + */ + item.mask |= LVIF_STATE; + item.state |= LVIS_SELECTED; + } + if (focusedName == name) + { + if (cursorIndex == -1) + cursorIndex = (int)index; + item.mask |= LVIF_STATE; + item.state |= LVIS_FOCUSED; + } + + unsigned subItem = 0; + item.iSubItem = (int)(subItem++); + item.lParam = (LPARAM)i; + item.pszText = name.Ptr_non_const(); + + const UString fullPath = DirPrefix + name; + #ifndef UNDER_CE + if (isDrive) + { + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path( + fi.Name + FCHAR_PATH_SEPARATOR, + FILE_ATTRIBUTE_DIRECTORY); + } + else + #endif + item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); + wchar_t s[64]; + { + s[0] = 0; + if (!FILETIME_IsZero(fi.MTime)) + ConvertUtcFileTimeToString(fi.MTime, s, + #ifndef UNDER_CE + kTimestampPrintLevel_MIN + #else + kTimestampPrintLevel_DAY + #endif + ); + _list.SetSubItem(index, subItem++, s); + } + { + s[0] = 0; + Browse_ConvertSizeToString(bi, s); + _list.SetSubItem(index, subItem++, s); + } + if (_columnIndex_NumFiles >= 0) + { + UString s2; + if (fi.HasReparsePoint()) + { + s2 = "Link"; + } + else if (bi.NumFiles != 0) + { + s2.Add_UInt32(bi.NumFiles); + if (bi.WasInterrupted) + s2 += "+"; + } + _list.SetSubItem(index, subItem, s2); + } + subItem++; + if (_columnIndex_NumDirs >= 0 && bi.NumDirs != 0) + { + UString s2; + s2.Add_UInt32(bi.NumDirs); + if (bi.WasInterrupted) + s2 += "+"; + _list.SetSubItem(index, subItem, s2); + } + subItem++; + if (_columnIndex_fileNameInDir >= 0 && bi.SubFileIndex >= 0) + { + _list.SetSubItem(index, subItem, fs2us(_files[bi.SubFileIndex].Name)); + } + subItem++; + } + + if (_list.GetItemCount() > 0 && cursorIndex >= 0) + { + // _list.SetItemState_FocusedSelected(cursorIndex); + // _list.SetItemState_Focused(cursorIndex); + } + _list.SortItems(CompareItems2, (LPARAM)this); + if (_list.GetItemCount() > 0 && cursorIndex < 0) + { + if (selectedVector.IsEmpty()) + _list.SetItemState_FocusedSelected(0); + else + _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED); + } + _list.EnsureVisible(_list.GetFocusedItem(), false); + _list.SetRedraw(true); + _list.InvalidateRect(NULL, true); + return S_OK; +} + + + +HRESULT CBrowseDialog2::Reload() +{ + UStringVector selected; + { + CUIntVector indexes; + GetSelected_RealIndexes(indexes); + FOR_VECTOR (i, indexes) + selected.Add(fs2us(Get_MainFileName_for_realIndex(indexes[i]))); + } + UString focusedName; + const int focusedItem = _list.GetFocusedItem(); + if (focusedItem >= 0) + { + const int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + focusedName = fs2us(Get_MainFileName_for_realIndex((unsigned)realIndex)); + } + const UString dirPathTemp = DirPrefix; + return Reload(dirPathTemp, selected, focusedName); +} + + +void CBrowseDialog2::OpenParentFolder() +{ +#if 1 // 0 : for debug + // we don't allow to go to parent of TempFolder. + // if (TempMode) + { + if (IsExactTempFolder(DirPrefix)) + return; + } +#endif + + UString parent, selected; + if (GetParentPath(DirPrefix, parent, selected)) + Reload(parent, selected); +} + + +void CBrowseDialog2::OnItemEnter() +{ + const bool alt = IsKeyDown(VK_MENU); + const bool ctrl = IsKeyDown(VK_CONTROL); + const bool shift = IsKeyDown(VK_SHIFT); + + const int index = _list.GetNextSelectedItem(-1); + if (index < 0) + return; + if (_list.GetNextSelectedItem(index) >= 0) + return; // more than one selected + const int realIndex = GetRealItemIndex(index); + if (realIndex == kParentIndex) + OpenParentFolder(); + else + { + const CBrowseItem &bi = _items[realIndex]; + const CFileInfo &file = _files[bi.MainFileIndex]; + if (alt) + { + Show_FileProps_Window(file); + return; + } + if (file.HasReparsePoint()) + { + // we don't want Link open operation, + // because user can think that it's usual folder/file (non-link). + ShowErrorMessage(*this, k_Message_Link_operation_was_Blocked); + return; + } + bool needExternal = true; + if (file.IsDir()) + { + if (!shift || alt || ctrl) // open folder in Explorer: + needExternal = false; + } + const UString fullPath = DirPrefix + fs2us(file.Name); + if (needExternal) + { + StartApplicationDontWait(DirPrefix, fullPath, (HWND)*this); + return; + } + UString s = fullPath; + s.Add_PathSepar(); + const HRESULT res = Reload(s, UString()); + if (res != S_OK) + MessageBox_HResError(*this, res, s); + // SetPathEditText(); + } +} + + +void MyBrowseForTempFolder(HWND owner) +{ + FString tempPathF; + if (!NFile::NDir::MyGetTempPath(tempPathF) || tempPathF.IsEmpty()) + { + MessageBox_LastError_path(owner, tempPathF); + return; + } + CBrowseDialog2 dialog; + + LangString_OnlyFromLangFile(IDM_TEMP_DIR, dialog.Title); + dialog.Title.Replace(L"...", L""); + if (dialog.Title.IsEmpty()) + dialog.Title = "Delete Temporary Files"; + + dialog.TempFolderPath = fs2us(tempPathF); + dialog.Create(owner); + // we can exit from dialog with 2 ways: + // IDCANCEL : Esc Key, or close icons + // IDCLOSE : with Close button +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.h 2024-03-28 20:00:00.000000000 +0000 @@ -0,0 +1,10 @@ +// BrowseDialog2.h + +#ifndef ZIP7_INC_BROWSE_DIALOG2_H +#define ZIP7_INC_BROWSE_DIALOG2_H + +#include "../../../Windows/Window.h" + +void MyBrowseForTempFolder(HWND owner); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2.rc 2024-03-29 21:00:00.000000000 +0000 @@ -0,0 +1,32 @@ +#include "BrowseDialog2Res.h" +#include "../../GuiCommon.rc" +// #include "resource.h" + +#define xc 450 +#define yc 328 + +#define k_BROWSE2_y_CtrlSize 14 + +#define k_BROWSE2_y_List 40 + +IDD_BROWSE2 DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "7-Zip: Browse Temp Files" +{ +// EDITTEXT IDE_BROWSE_PATH, m, by - m - k_BROWSE_y_CtrlSize - k_BROWSE_y_CtrlSize - m, xc, k_BROWSE_y_CtrlSize, ES_AUTOHSCROLL + COMBOBOX IDC_BROWSE2_FILTER, m, by - m - k_BROWSE2_y_CtrlSize, xc, 30, MY_COMBO + +// DON'T USE DEFPUSHBUTTON here, because we use IDOK as default action for Enter key. + PUSHBUTTON "Close", IDCLOSE, bx2, by, bxs, bys, WS_GROUP + PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys + + PUSHBUTTON "Delete", IDS_BUTTON_DELETE, m , m, 64, bys + PUSHBUTTON "Refresh", IDM_VIEW_REFRESH, m + 64 + 8, m, 64, bys + + PUSHBUTTON "<--", IDB_BROWSE2_PARENT, m, m + 21, 24, bys +// LTEXT "", IDT_BROWSE_FOLDER, m + 30, m + 24, xc - 30, 8 + EDITTEXT IDT_BROWSE2_FOLDER, m + 28, m + 22, xc - 28, 14, ES_AUTOHSCROLL | ES_READONLY + + CONTROL "List1", IDL_BROWSE2, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, + m, m + k_BROWSE2_y_List, xc, yc - bys - m - k_BROWSE2_y_List - k_BROWSE2_y_CtrlSize - m +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2Res.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2Res.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialog2Res.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialog2Res.h 2024-04-01 11:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_BROWSE2 93 + +#define IDL_BROWSE2 100 +#define IDT_BROWSE2_FOLDER 101 +// #define IDE_BROWSE2_PATH 102 +#define IDC_BROWSE2_FILTER 103 + +#define IDB_BROWSE2_PARENT 110 +// #define IDB_BROWSE2_CREATE_DIR 112 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/BrowseDialogRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/BrowseDialogRes.h 2013-02-20 09:43:13.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_BROWSE 95 + +#define IDL_BROWSE 100 +#define IDT_BROWSE_FOLDER 101 +#define IDE_BROWSE_PATH 102 +#define IDC_BROWSE_FILTER 103 + +#define IDB_BROWSE_PARENT 110 +#define IDB_BROWSE_CREATE_DIR 112 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ClassDefs.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ClassDefs.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ClassDefs.cpp 2015-09-01 18:04:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ClassDefs.cpp 2021-10-23 17:08:38.000000000 +0000 @@ -1,11 +1,12 @@ -// ClassDefs.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyWindows.h" - -#include "../../../Common/MyInitGuid.h" - -#include "../Agent/Agent.h" - -#include "MyWindowsNew.h" +// ClassDefs.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#include "../../../Common/MyInitGuid.h" + +#include "../Agent/Agent.h" + +#include "MyWindowsNew.h" +#include "../Explorer/MyExplorerCommand.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.cpp 2015-01-02 19:20:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.cpp 2023-01-29 20:00:00.000000000 +0000 @@ -1,66 +1,64 @@ -// ComboDialog.cpp - -#include "StdAfx.h" -#include "ComboDialog.h" - -#include "../../../Windows/Control/Static.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -using namespace NWindows; - -bool CComboDialog::OnInit() -{ - #ifdef LANG - LangSetDlgItems(*this, NULL, 0); - #endif - _comboBox.Attach(GetItem(IDC_COMBO)); - - /* - // why it doesn't work ? - DWORD style = _comboBox.GetStyle(); - if (Sorted) - style |= CBS_SORT; - else - style &= ~CBS_SORT; - _comboBox.SetStyle(style); - */ - SetText(Title); - - NControl::CStatic staticContol; - staticContol.Attach(GetItem(IDT_COMBO)); - staticContol.SetText(Static); - _comboBox.SetText(Value); - FOR_VECTOR (i, Strings) - _comboBox.AddString(Strings[i]); - NormalizeSize(); - return CModalDialog::OnInit(); -} - -bool CComboDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int mx, my; - GetMargins(8, mx, my); - int bx1, bx2, by; - GetItemSizes(IDCANCEL, bx1, by); - GetItemSizes(IDOK, bx2, by); - int y = ySize - my - by; - int x = xSize - mx - bx1; - - InvalidateRect(NULL); - - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDOK, x - mx - bx2, y, bx2, by); - ChangeSubWindowSizeX(_comboBox, xSize - mx * 2); -#endif - return false; -} - -void CComboDialog::OnOK() -{ - _comboBox.GetText(Value); - CModalDialog::OnOK(); -} +// ComboDialog.cpp + +#include "StdAfx.h" +#include "ComboDialog.h" + +#include "../../../Windows/Control/Static.h" + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +bool CComboDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _comboBox.Attach(GetItem(IDC_COMBO)); + + /* + // why it doesn't work ? + DWORD style = _comboBox.GetStyle(); + if (Sorted) + style |= CBS_SORT; + else + style &= ~CBS_SORT; + _comboBox.SetStyle(style); + */ + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDT_COMBO)); + staticContol.SetText(Static); + _comboBox.SetText(Value); + FOR_VECTOR (i, Strings) + _comboBox.AddString(Strings[i]); + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CComboDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int y = ySize - my - by; + int x = xSize - mx - bx1; + + InvalidateRect(NULL); + + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + ChangeSubWindowSizeX(_comboBox, xSize - mx * 2); + return false; +} + +void CComboDialog::OnOK() +{ + _comboBox.GetText(Value); + CModalDialog::OnOK(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,28 +1,28 @@ -// ComboDialog.h - -#ifndef __COMBO_DIALOG_H -#define __COMBO_DIALOG_H - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Dialog.h" - -#include "ComboDialogRes.h" - -class CComboDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox _comboBox; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); -public: - // bool Sorted; - UString Title; - UString Static; - UString Value; - UStringVector Strings; - - // CComboDialog(): Sorted(false) {}; - INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_COMBO, parentWindow); } -}; - -#endif +// ComboDialog.h + +#ifndef ZIP7_INC_COMBO_DIALOG_H +#define ZIP7_INC_COMBO_DIALOG_H + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" + +#include "ComboDialogRes.h" + +class CComboDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _comboBox; + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; +public: + // bool Sorted; + UString Title; + UString Static; + UString Value; + UStringVector Strings; + + // CComboDialog(): Sorted(false) {}; + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_COMBO, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog.rc 2011-06-06 11:49:33.000000000 +0000 @@ -0,0 +1,16 @@ +#include "ComboDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 240 +#define yc 64 + +IDD_COMBO DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Combo" +{ + LTEXT "", IDT_COMBO, m, m, xc, 8 + COMBOBOX IDC_COMBO, m, 20, xc, 65, MY_COMBO_WITH_EDIT + OK_CANCEL +} + +#undef xc +#undef yc diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialogRes.h 2011-06-06 11:50:09.000000000 +0000 @@ -1,4 +1,4 @@ -#define IDD_COMBO 98 - -#define IDT_COMBO 100 -#define IDC_COMBO 101 +#define IDD_COMBO 98 + +#define IDT_COMBO 100 +#define IDC_COMBO 101 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ComboDialog_rc.cpp 2015-01-02 20:26:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ComboDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "ComboDialogRes.h" - -class ComboDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - ComboDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent,int id) : CModalDialogImpl(dialog, parent, id, wxT("Combo")) - { - - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - - topsizer->Add(new wxStaticText(this, IDT_COMBO, _T("")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - - - wxArrayString pathArray; - wxComboBox *combo = new wxComboBox(this, IDC_COMBO, wxEmptyString, wxDefaultPosition, wxSize(200,-1), pathArray, wxCB_DROPDOWN|wxCB_SORT); - - topsizer->Add(combo, 0 ,wxALL | wxALIGN_LEFT, 5 ); - - topsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_COMBO,ComboDialog,0) - -BEGIN_EVENT_TABLE(ComboDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Copy.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Copy.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Copy2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Copy2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.cpp 2015-10-03 17:45:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.cpp 2023-03-19 10:00:00.000000000 +0000 @@ -1,116 +1,103 @@ -// CopyDialog.cpp - -#include "StdAfx.h" - -#include "../../../Windows/FileName.h" - -#include "../../../Windows/Control/Static.h" - -#include "BrowseDialog.h" -#include "CopyDialog.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -#ifndef _WIN32 -extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); -#endif - - -using namespace NWindows; - -bool CCopyDialog::OnInit() -{ - #ifdef LANG - LangSetDlgItems(*this, NULL, 0); - #endif - _path.Attach(GetItem(IDC_COPY)); - SetText(Title); - - NControl::CStatic staticContol; - staticContol.Attach(GetItem(IDT_COPY)); - staticContol.SetText(Static); - #ifdef UNDER_CE - // we do it, since WinCE selects Value\something instead of Value !!!! - _path.AddString(Value); - #endif - FOR_VECTOR (i, Strings) - _path.AddString(Strings[i]); -#ifndef _WIN32 - UString tmp = nameWindowToUnix(Value); - Value = tmp; -#endif - _path.SetText(Value); - SetItemText(IDT_COPY_INFO, Info); - NormalizeSize(true); - return CModalDialog::OnInit(); -} - -bool CCopyDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int mx, my; - GetMargins(8, mx, my); - int bx1, bx2, by; - GetItemSizes(IDCANCEL, bx1, by); - GetItemSizes(IDOK, bx2, by); - int y = ySize - my - by; - int x = xSize - mx - bx1; - - InvalidateRect(NULL); - - { - RECT r; - GetClientRectOfItem(IDB_COPY_SET_PATH, r); - int bx = RECT_SIZE_X(r); - MoveItem(IDB_COPY_SET_PATH, xSize - mx - bx, r.top, bx, RECT_SIZE_Y(r)); - ChangeSubWindowSizeX(_path, xSize - mx - mx - bx - mx); - } - - { - RECT r; - GetClientRectOfItem(IDT_COPY_INFO, r); - NControl::CStatic staticContol; - staticContol.Attach(GetItem(IDT_COPY_INFO)); - int yPos = r.top; - staticContol.Move(mx, yPos, xSize - mx * 2, y - 2 - yPos); - } - - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDOK, x - mx - bx2, y, bx2, by); -#endif - return false; -} - -bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDB_COPY_SET_PATH: - OnButtonSetPath(); - return true; - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CCopyDialog::OnButtonSetPath() -{ - UString currentPath; - _path.GetText(currentPath); - - const UString title = LangString(IDS_SET_FOLDER); - - UString resultPath; - if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) - return; - NFile::NName::NormalizeDirPathPrefix(resultPath); - _path.SetCurSel(-1); - _path.SetText(resultPath); -} - -void CCopyDialog::OnOK() -{ - _path.GetText(Value); - CModalDialog::OnOK(); -} +// CopyDialog.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileName.h" + +#include "../../../Windows/Control/Static.h" + +#include "BrowseDialog.h" +#include "CopyDialog.h" +#include "LangUtils.h" + +using namespace NWindows; + +bool CCopyDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _path.Attach(GetItem(IDC_COPY)); + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDT_COPY)); + staticContol.SetText(Static); + #ifdef UNDER_CE + // we do it, since WinCE selects Value\something instead of Value !!!! + _path.AddString(Value); + #endif + FOR_VECTOR (i, Strings) + _path.AddString(Strings[i]); + _path.SetText(Value); + SetItemText(IDT_COPY_INFO, Info); + NormalizeSize(true); + return CModalDialog::OnInit(); +} + +bool CCopyDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + const int y = ySize - my - by; + const int x = xSize - mx - bx1; + + InvalidateRect(NULL); + + { + RECT r; + GetClientRectOfItem(IDB_COPY_SET_PATH, r); + const int bx = RECT_SIZE_X(r); + MoveItem(IDB_COPY_SET_PATH, xSize - mx - bx, r.top, bx, RECT_SIZE_Y(r)); + ChangeSubWindowSizeX(_path, xSize - mx - mx - bx - mx); + } + + { + RECT r; + GetClientRectOfItem(IDT_COPY_INFO, r); + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDT_COPY_INFO)); + const int yPos = r.top; + staticContol.Move(mx, yPos, xSize - mx * 2, y - 2 - yPos); + } + + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + + return false; +} + +bool CCopyDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_COPY_SET_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CCopyDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + + const UString title = LangString(IDS_SET_FOLDER); + + UString resultPath; + if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _path.SetCurSel(-1); + _path.SetText(resultPath); +} + +void CCopyDialog::OnOK() +{ + _path.GetText(Value); + CModalDialog::OnOK(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,31 +1,31 @@ -// CopyDialog.h - -#ifndef __COPY_DIALOG_H -#define __COPY_DIALOG_H - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Dialog.h" - -#include "CopyDialogRes.h" - -const int kCopyDialog_NumInfoLines = 11; - -class CCopyDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox _path; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - void OnButtonSetPath(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); -public: - UString Title; - UString Static; - UString Value; - UString Info; - UStringVector Strings; - - INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_COPY, parentWindow); } -}; - -#endif +// CopyDialog.h + +#ifndef ZIP7_INC_COPY_DIALOG_H +#define ZIP7_INC_COPY_DIALOG_H + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" + +#include "CopyDialogRes.h" + +const int kCopyDialog_NumInfoLines = 11; + +class CCopyDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _path; + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void OnButtonSetPath(); +public: + UString Title; + UString Static; + UString Value; + UString Info; + UStringVector Strings; + + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_COPY, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog.rc 2011-06-06 11:53:19.000000000 +0000 @@ -0,0 +1,20 @@ +#include "CopyDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 320 +#define yc 144 + +#define y 40 + +IDD_COPY DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Copy" +{ + LTEXT "", IDT_COPY, m, m, xc, 8 + COMBOBOX IDC_COPY, m, 20, xc - bxsDots - m, 65, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_COPY_SET_PATH, xs - m - bxsDots, 18, bxsDots, bys, WS_GROUP + LTEXT "", IDT_COPY_INFO, m, y, xc, by - y - 1, SS_NOPREFIX | SS_LEFTNOWORDWRAP + OK_CANCEL +} + +#undef xc +#undef yc diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialogRes.h 2011-05-10 10:39:50.000000000 +0000 @@ -1,8 +1,8 @@ -#define IDD_COPY 96 - -#define IDT_COPY 100 -#define IDC_COPY 101 -#define IDB_COPY_SET_PATH 102 -#define IDT_COPY_INFO 103 - -#define IDS_SET_FOLDER 6007 +#define IDD_COPY 96 + +#define IDT_COPY 100 +#define IDC_COPY 101 +#define IDB_COPY_SET_PATH 102 +#define IDT_COPY_INFO 103 + +#define IDS_SET_FOLDER 6007 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/CopyDialog_rc.cpp 2015-01-02 20:09:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/CopyDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "CopyDialogRes.h" - -class CopyDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CopyDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent,int id) : CModalDialogImpl(dialog, parent, id, wxT("Copy")) - { - - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - - topsizer->Add(new wxStaticText(this, IDT_COPY, _T("")) , 0 ,wxEXPAND | wxALL | wxALIGN_LEFT, 5 ); - - - { - wxBoxSizer *pathSizer = new wxBoxSizer(wxHORIZONTAL); - - wxArrayString pathArray; - wxComboBox *combo = new wxComboBox(this, IDC_COPY, wxEmptyString, wxDefaultPosition, wxSize(600,-1), pathArray, wxCB_DROPDOWN|wxCB_SORT); - wxButton *button = new wxButton(this, IDB_COPY_SET_PATH, wxT("..."), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - pathSizer->Add(combo, 1, wxLEFT|wxRIGHT|wxEXPAND, 5); - pathSizer->Add(button, 0, wxLEFT|wxRIGHT|wxEXPAND, 5); - - topsizer->Add(pathSizer, 0 ,wxALL | wxALIGN_LEFT, 5 ); - } - -// topsizer->Add(new wxStaticText(this, IDT_COPY_INFO, _T("line1\nline2\nline3\nline4\n")) , 0 ,wxEXPAND | wxALL | wxALIGN_LEFT, 5 ); - topsizer->Add(new wxStaticText(this, IDT_COPY_INFO, _T("")) , 0 ,wxEXPAND | wxALL | wxALIGN_LEFT, 5 ); - - topsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -static CStringTable g_stringTable[] = -{ - { IDS_SET_FOLDER, L"Specify a location for output folder." }, - { 0 , 0 } -}; - - -REGISTER_DIALOG(IDD_COPY,CopyDialog,g_stringTable) - -BEGIN_EVENT_TABLE(CopyDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Delete.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Delete.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Delete2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Delete2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/DialogSize.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/DialogSize.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/DialogSize.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/DialogSize.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,16 +1,16 @@ -// DialogSize.h - -#ifndef __DIALOG_SIZE_H -#define __DIALOG_SIZE_H - -#include "../../../Windows/Control/Dialog.h" - -#ifdef UNDER_CE -#define BIG_DIALOG_SIZE(x, y) bool isBig = NWindows::NControl::IsDialogSizeOK(x, y); -#define SIZED_DIALOG(big) (isBig ? big : big ## _2) -#else -#define BIG_DIALOG_SIZE(x, y) -#define SIZED_DIALOG(big) big -#endif - -#endif +// DialogSize.h + +#ifndef ZIP7_INC_DIALOG_SIZE_H +#define ZIP7_INC_DIALOG_SIZE_H + +#include "../../../Windows/Control/Dialog.h" + +#ifdef UNDER_CE +#define BIG_DIALOG_SIZE(x, y) bool isBig = NWindows::NControl::IsDialogSizeOK(x, y); +#define SIZED_DIALOG(big) (isBig ? big : big ## _2) +#else +#define BIG_DIALOG_SIZE(x, y) +#define SIZED_DIALOG(big) big +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.cpp 2023-03-19 10:00:00.000000000 +0000 @@ -0,0 +1,57 @@ +// EditDialog.cpp + +#include "StdAfx.h" + +#include "EditDialog.h" + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +bool CEditDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _edit.Attach(GetItem(IDE_EDIT)); + + SetText(Title); + _edit.SetText(Text); + + NormalizeSize(); + return CModalDialog::OnInit(); +} + +// #define MY_CLOSE_BUTTON_ID IDCANCEL +#define MY_CLOSE_BUTTON_ID IDCLOSE + +bool CEditDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, by; + GetItemSizes(MY_CLOSE_BUTTON_ID, bx1, by); + + // int bx2; + // GetItemSizes(IDOK, bx2, by); + + const int y = ySize - my - by; + const int x = xSize - mx - bx1; + + /* + RECT rect; + GetClientRect(&rect); + rect.top = y - my; + InvalidateRect(&rect); + */ + InvalidateRect(NULL); + + MoveItem(MY_CLOSE_BUTTON_ID, x, y, bx1, by); + // MoveItem(IDOK, x - mx - bx2, y, bx2, by); + /* + if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE) + mx = 0; + */ + _edit.Move(mx, my, xSize - mx * 2, y - my * 2); + return false; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,25 @@ +// EditDialog.h + +#ifndef ZIP7_INC_EDIT_DIALOG_H +#define ZIP7_INC_EDIT_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" + +#include "EditDialogRes.h" + +class CEditDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _edit; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; +public: + UString Title; + UString Text; + + INT_PTR Create(HWND wndParent = NULL) { return CModalDialog::Create(IDD_EDIT_DLG, wndParent); } + + CEditDialog() {} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialog.rc 2018-03-19 15:27:12.000000000 +0000 @@ -0,0 +1,15 @@ +#include "EditDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 320 +#define yc 240 + +IDD_EDIT_DLG DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Edit" +{ + // OK_CANCEL + MY_BUTTON__CLOSE + + EDITTEXT IDE_EDIT, m, m, xc, yc - bys - m, + ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | ES_WANTRETURN +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditDialogRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditDialogRes.h 2018-03-17 08:02:42.000000000 +0000 @@ -0,0 +1,2 @@ +#define IDD_EDIT_DLG 94 +#define IDE_EDIT 100 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -0,0 +1,159 @@ +// EditPage.cpp + +#include "StdAfx.h" + +#include "EditPage.h" +#include "EditPageRes.h" + +#include "BrowseDialog.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "RegistryUtils.h" + +using namespace NWindows; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_EDIT_EDITOR, + IDT_EDIT_DIFF +}; + +static const UInt32 kLangIDs_Colon[] = +{ + IDT_EDIT_VIEWER +}; +#endif + +#define kEditTopic "FM/options.htm#editor" + +bool CEditPage::OnInit() +{ + _initMode = true; + + #ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + LangSetDlgItems_Colon(*this, kLangIDs_Colon, Z7_ARRAY_SIZE(kLangIDs_Colon)); + #endif + + _ctrls[0].Ctrl = IDE_EDIT_VIEWER; _ctrls[0].Button = IDB_EDIT_VIEWER; + _ctrls[1].Ctrl = IDE_EDIT_EDITOR; _ctrls[1].Button = IDB_EDIT_EDITOR; + _ctrls[2].Ctrl = IDE_EDIT_DIFF; _ctrls[2].Button = IDB_EDIT_DIFF; + + for (unsigned i = 0; i < 3; i++) + { + CEditPageCtrl &c = _ctrls[i]; + c.WasChanged = false; + c.Edit.Attach(GetItem(c.Ctrl)); + UString path; + if (i < 2) + ReadRegEditor(i > 0, path); + else + ReadRegDiff(path); + c.Edit.SetText(path); + } + + _initMode = false; + + return CPropertyPage::OnInit(); +} + +LONG CEditPage::OnApply() +{ + for (unsigned i = 0; i < 3; i++) + { + CEditPageCtrl &c = _ctrls[i]; + if (c.WasChanged) + { + UString path; + c.Edit.GetText(path); + if (i < 2) + SaveRegEditor(i > 0, path); + else + SaveRegDiff(path); + c.WasChanged = false; + } + } + + return PSNRET_NOERROR; +} + +void CEditPage::OnNotifyHelp() +{ + ShowHelpWindow(kEditTopic); +} + +void SplitCmdLineSmart(const UString &cmd, UString &prg, UString ¶ms); + +static void Edit_BrowseForFile(NWindows::NControl::CEdit &edit, HWND hwnd) +{ + UString cmd; + edit.GetText(cmd); + + UString param; + UString prg; + + SplitCmdLineSmart(cmd, prg, param); + + CObjectVector filters; + CBrowseFilterInfo &bfi = filters.AddNew(); + bfi.Description = "*.exe"; + bfi.Masks.Add(UString("*.exe")); + + CBrowseInfo bi; + bi.FilterIndex = 0; + bi.FilePath = prg; + bi.hwndOwner = hwnd; + + if (bi.BrowseForFile(filters)) + { + cmd = bi.FilePath; + cmd.Trim(); + /* + if (!param.IsEmpty() && !resPath.IsEmpty()) + { + cmd.InsertAtFront(L'\"'); + cmd += L'\"'; + cmd.Add_Space(); + cmd += param; + } + */ + + edit.SetText(cmd); + // Changed(); + } +} + +bool CEditPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + for (unsigned i = 0; i < 3; i++) + { + CEditPageCtrl &c = _ctrls[i]; + if (buttonID == c.Button) + { + Edit_BrowseForFile(c.Edit, *this); + return true; + } + } + + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} + +bool CEditPage::OnCommand(unsigned code, unsigned itemID, LPARAM param) +{ + if (!_initMode && code == EN_CHANGE) + { + for (unsigned i = 0; i < 3; i++) + { + CEditPageCtrl &c = _ctrls[i]; + if (itemID == c.Ctrl) + { + c.WasChanged = true; + Changed(); + return true; + } + } + } + + return CPropertyPage::OnCommand(code, itemID, param); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,30 @@ +// EditPage.h + +#ifndef ZIP7_INC_EDIT_PAGE_H +#define ZIP7_INC_EDIT_PAGE_H + +#include "../../../Windows/Control/PropertyPage.h" +#include "../../../Windows/Control/Edit.h" + +struct CEditPageCtrl +{ + NWindows::NControl::CEdit Edit; + bool WasChanged; + unsigned Ctrl; + unsigned Button; +}; + +class CEditPage: public NWindows::NControl::CPropertyPage +{ + CEditPageCtrl _ctrls[3]; + + bool _initMode; +public: + virtual bool OnInit() Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM param) Z7_override; + virtual LONG OnApply() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage.rc 2024-03-16 05:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +#include "EditPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc 100 + +IDD_EDIT MY_PAGE +#include "EditPage2.rc" + +#ifdef UNDER_CE + +#undef xc + +#define xc SMALL_PAGE_SIZE_X + +IDD_EDIT_2 MY_PAGE +#include "EditPage2.rc" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPage2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPage2.rc 2011-06-06 11:56:46.000000000 +0000 @@ -0,0 +1,14 @@ +CAPTION "Editor" +{ + LTEXT "&View:", IDT_EDIT_VIEWER, m, m, xc, 8 + EDITTEXT IDE_EDIT_VIEWER, m, m + 12, xc - m - bxsDots, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EDIT_VIEWER, xs - m - bxsDots, m + 11, bxsDots, bys + + LTEXT "&Editor:", IDT_EDIT_EDITOR, m, m + 32, xc, 8 + EDITTEXT IDE_EDIT_EDITOR, m, m + 44, xc - m - bxsDots, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EDIT_EDITOR, xs - m - bxsDots, m + 43, bxsDots, bys + + LTEXT "&Diff:", IDT_EDIT_DIFF, m, m + 64, xc, 8 + EDITTEXT IDE_EDIT_DIFF, m, m + 76, xc - m - bxsDots, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_EDIT_DIFF, xs - m - bxsDots, m + 75, bxsDots, bys +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EditPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EditPageRes.h 2011-06-04 05:16:35.000000000 +0000 @@ -0,0 +1,15 @@ +#define IDD_EDIT 2103 +#define IDD_EDIT_2 12103 + +#define IDT_EDIT_VIEWER 543 +#define IDT_EDIT_EDITOR 2104 +#define IDT_EDIT_DIFF 2105 + +#define IDE_EDIT_VIEWER 100 +#define IDB_EDIT_VIEWER 101 + +#define IDE_EDIT_EDITOR 102 +#define IDB_EDIT_EDITOR 103 + +#define IDE_EDIT_DIFF 104 +#define IDB_EDIT_DIFF 105 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp 2023-02-01 17:00:00.000000000 +0000 @@ -0,0 +1,107 @@ +// EnumFormatEtc.cpp + +#include "StdAfx.h" + +#include "EnumFormatEtc.h" +#include "../../IDecl.h" +#include "MyCom2.h" + +class CEnumFormatEtc Z7_final: + public IEnumFORMATETC, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1_MT(IEnumFORMATETC) + + STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) Z7_override; + STDMETHOD(Skip)(ULONG celt) Z7_override; + STDMETHOD(Reset)(void) Z7_override; + STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc) Z7_override; + + LONG m_RefCount; + ULONG m_NumFormats; + FORMATETC *m_Formats; + ULONG m_Index; +public: + CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats); + ~CEnumFormatEtc(); +}; + +static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src) +{ + *dest = *src; + if (src->ptd) + { + dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); + *(dest->ptd) = *(src->ptd); + } +} + +CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats) +{ + m_RefCount = 1; + m_Index = 0; + m_NumFormats = 0; + m_Formats = new FORMATETC[numFormats]; + // if (m_Formats) + { + m_NumFormats = numFormats; + for (ULONG i = 0; i < numFormats; i++) + DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]); + } +} + +CEnumFormatEtc::~CEnumFormatEtc() +{ + if (m_Formats) + { + for (ULONG i = 0; i < m_NumFormats; i++) + if (m_Formats[i].ptd) + CoTaskMemFree(m_Formats[i].ptd); + delete []m_Formats; + } +} + +Z7_COMWF_B CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched) +{ + ULONG copied = 0; + if (celt == 0 || !pFormatEtc) + return E_INVALIDARG; + while (m_Index < m_NumFormats && copied < celt) + { + DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]); + copied++; + m_Index++; + } + if (pceltFetched) + *pceltFetched = copied; + return (copied == celt) ? S_OK : S_FALSE; +} + +Z7_COMWF_B CEnumFormatEtc::Skip(ULONG celt) +{ + m_Index += celt; + return (m_Index <= m_NumFormats) ? S_OK : S_FALSE; +} + +Z7_COMWF_B CEnumFormatEtc::Reset(void) +{ + m_Index = 0; + return S_OK; +} + +Z7_COMWF_B CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc) +{ + HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc); + if (hResult == S_OK) + ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index; + return hResult; +} + +// replacement for SHCreateStdEnumFmtEtc +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat) +{ + if (numFormats == 0 || !formats || !enumFormat) + return E_INVALIDARG; + *enumFormat = new CEnumFormatEtc(formats, numFormats); + return (*enumFormat) ? S_OK : E_OUTOFMEMORY; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/EnumFormatEtc.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/EnumFormatEtc.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/EnumFormatEtc.h 2023-01-10 18:00:00.000000000 +0000 @@ -0,0 +1,10 @@ +// EnumFormatEtc.h + +#ifndef ZIP7_INC_ENUMFORMATETC_H +#define ZIP7_INC_ENUMFORMATETC_H + +#include "../../../Common/MyWindows.h" + +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat); + +#endif Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Extract.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Extract.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Extract2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Extract2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ExtractCallback.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ExtractCallback.cpp 2015-09-19 09:43:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.cpp 2024-10-13 08:00:00.000000000 +0000 @@ -1,1035 +1,1272 @@ -// ExtractCallback.cpp - -#include "StdAfx.h" - - -#include "../../../Common/ComTry.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/Lang.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../Common/FilePathAutoRename.h" -#include "../../Common/StreamUtils.h" -#include "../Common/ExtractingFilePath.h" - -#ifndef _SFX -#include "../Common/ZipRegistry.h" -#endif - -#include "../GUI/ExtractRes.h" -#include "resourceGui.h" - -#include "ExtractCallback.h" -#include "FormatUtils.h" -#include "LangUtils.h" -#include "OverwriteDialog.h" -#ifndef _NO_CRYPTO -#include "PasswordDialog.h" -#endif -#include "PropertyName.h" - -using namespace NWindows; -using namespace NFile; -using namespace NFind; - -CExtractCallbackImp::~CExtractCallbackImp() {} - -void CExtractCallbackImp::Init() -{ - _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); - _lang_Testing = LangString(IDS_PROGRESS_TESTING); - _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); - - NumArchiveErrors = 0; - ThereAreMessageErrors = false; - #ifndef _SFX - NumFolders = NumFiles = 0; - NeedAddFile = false; - #endif -} - -void CExtractCallbackImp::AddError_Message(LPCWSTR s) -{ - ThereAreMessageErrors = true; - ProgressDialog->Sync.AddError_Message(s); -} - -#ifndef _SFX - -STDMETHODIMP CExtractCallbackImp::SetNumFiles(UInt64 - #ifndef _SFX - numFiles - #endif - ) -{ - #ifndef _SFX - ProgressDialog->Sync.Set_NumFilesTotal(numFiles); - #endif - return S_OK; -} - -#endif - -STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) -{ - ProgressDialog->Sync.Set_NumBytesTotal(total); - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *value) -{ - return ProgressDialog->Sync.Set_NumBytesCur(value); -} - -HRESULT CExtractCallbackImp::Open_CheckBreak() -{ - return ProgressDialog->Sync.CheckStop(); -} - -HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) -{ - HRESULT res = S_OK; - if (!MultiArcMode) - { - if (files) - { - _totalFilesDefined = true; - // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); - } - else - _totalFilesDefined = false; - - if (bytes) - { - _totalBytesDefined = true; - ProgressDialog->Sync.Set_NumBytesTotal(*bytes); - } - else - _totalBytesDefined = false; - } - - return res; -} - -HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) -{ - if (!MultiArcMode) - { - if (files) - { - ProgressDialog->Sync.Set_NumFilesCur(*files); - } - - if (bytes) - { - } - } - - return ProgressDialog->Sync.CheckStop(); -} - -HRESULT CExtractCallbackImp::Open_Finished() -{ - return ProgressDialog->Sync.CheckStop(); -} - -#ifndef _NO_CRYPTO - -HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password) -{ - return CryptoGetTextPassword(password); -} - -/* -HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) -{ - passwordIsDefined = PasswordIsDefined; - password = Password; - return S_OK; -} - -bool CExtractCallbackImp::Open_WasPasswordAsked() -{ - return PasswordWasAsked; -} - -void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag() -{ - PasswordWasAsked = false; -} -*/ - -#endif - - -#ifndef _SFX -STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - ProgressDialog->Sync.Set_Ratio(inSize, outSize); - return S_OK; -} -#endif - -/* -STDMETHODIMP CExtractCallbackImp::SetTotalFiles(UInt64 total) -{ - ProgressDialog->Sync.SetNumFilesTotal(total); - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) -{ - if (value != NULL) - ProgressDialog->Sync.SetNumFilesCur(*value); - return S_OK; -} -*/ - -STDMETHODIMP CExtractCallbackImp::AskOverwrite( - const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, - const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, - Int32 *answer) -{ - COverwriteDialog dialog; - - dialog.OldFileInfo.SetTime(existTime); - dialog.OldFileInfo.SetSize(existSize); - dialog.OldFileInfo.Name = existName; - - dialog.NewFileInfo.SetTime(newTime); - dialog.NewFileInfo.SetSize(newSize); - dialog.NewFileInfo.Name = newName; - - ProgressDialog->WaitCreating(); - INT_PTR writeAnswer = dialog.Create(*ProgressDialog); - - switch (writeAnswer) - { - case IDCANCEL: *answer = NOverwriteAnswer::kCancel; return E_ABORT; - case IDYES: *answer = NOverwriteAnswer::kYes; break; - case IDNO: *answer = NOverwriteAnswer::kNo; break; - case IDB_YES_TO_ALL: *answer = NOverwriteAnswer::kYesToAll; break; - case IDB_NO_TO_ALL: *answer = NOverwriteAnswer::kNoToAll; break; - case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break; - default: return E_FAIL; - } - return S_OK; -} - - -STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */) -{ - _isFolder = IntToBool(isFolder); - _currentFilePath = name; - - const UString *msg = &_lang_Empty; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break; - case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break; - case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break; - // default: s = "Unknown operation"; - } - - return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder)); -} - -STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s) -{ - AddError_Message(s); - return S_OK; -} - -HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path) -{ - ThereAreMessageErrors = true; - ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path)); - return S_OK; -} - -#ifndef _SFX - -STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s) -{ - AddError_Message(s); - return S_OK; -} - -#endif - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s) -{ - s.Empty(); - - if (opRes == NArchive::NExtract::NOperationResult::kOK) - return; - - UINT messageID = 0; - UINT id = 0; - - switch (opRes) - { - case NArchive::NExtract::NOperationResult::kUnsupportedMethod: - messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; - id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD; - break; - case NArchive::NExtract::NOperationResult::kDataError: - messageID = encrypted ? - IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: - IDS_EXTRACT_MESSAGE_DATA_ERROR; - id = IDS_EXTRACT_MSG_DATA_ERROR; - break; - case NArchive::NExtract::NOperationResult::kCRCError: - messageID = encrypted ? - IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED: - IDS_EXTRACT_MESSAGE_CRC_ERROR; - id = IDS_EXTRACT_MSG_CRC_ERROR; - break; - case NArchive::NExtract::NOperationResult::kUnavailable: - id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA; - break; - case NArchive::NExtract::NOperationResult::kUnexpectedEnd: - id = IDS_EXTRACT_MSG_UEXPECTED_END; - break; - case NArchive::NExtract::NOperationResult::kDataAfterEnd: - id = IDS_EXTRACT_MSG_DATA_AFTER_END; - break; - case NArchive::NExtract::NOperationResult::kIsNotArc: - id = IDS_EXTRACT_MSG_IS_NOT_ARC; - break; - case NArchive::NExtract::NOperationResult::kHeadersError: - id = IDS_EXTRACT_MSG_HEADERS_ERROR; - break; - case NArchive::NExtract::NOperationResult::kWrongPassword: - id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM; - break; - /* - default: - messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR; - break; - */ - } - - UString msg; - UString msgOld; - - #ifndef _SFX - if (id != 0) - LangString_OnlyFromLangFile(id, msg); - if (messageID != 0 && msg.IsEmpty()) - LangString_OnlyFromLangFile(messageID, msgOld); - #endif - - if (msg.IsEmpty() && !msgOld.IsEmpty()) - s = MyFormatNew(msgOld, fileName); - else - { - if (msg.IsEmpty() && id != 0) - LangString(id, msg); - if (!msg.IsEmpty()) - s += msg; - else - { - char temp[16]; - ConvertUInt32ToString(opRes, temp); - s.AddAscii("Error #"); - s.AddAscii(temp); - } - - if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword) - { - // s.AddAscii(" : "); - // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED); - s.AddAscii(" : "); - AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); - } - s.AddAscii(" : "); - s += fileName; - } -} - -STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted) -{ - switch (opRes) - { - case NArchive::NExtract::NOperationResult::kOK: - break; - default: - { - UString s; - SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s); - Add_ArchiveName_Error(); - AddError_Message(s); - } - } - - #ifndef _SFX - if (_isFolder) - NumFolders++; - else - NumFiles++; - ProgressDialog->Sync.Set_NumFilesCur(NumFiles); - #endif - - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) -{ - if (opRes != NArchive::NExtract::NOperationResult::kOK) - { - UString s; - SetExtractErrorMessage(opRes, encrypted, name, s); - Add_ArchiveName_Error(); - AddError_Message(s); - } - return S_OK; -} - -//////////////////////////////////////// -// IExtractCallbackUI - -HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */) -{ - #ifndef _SFX - RINOK(ProgressDialog->Sync.CheckStop()); - ProgressDialog->Sync.Set_TitleFileName(name); - #endif - _currentArchivePath = name; - return S_OK; -} - -HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) -{ - _currentFilePath = path; - #ifndef _SFX - ProgressDialog->Sync.Set_FilePath(path); - #endif - return S_OK; -} - -#ifndef _SFX - -HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) -{ - #ifndef _SFX - if (NeedAddFile) - NumFiles++; - NeedAddFile = true; - ProgressDialog->Sync.Set_NumFilesCur(NumFiles); - #endif - return SetCurrentFilePath2(path); -} - -#endif - -UString HResultToMessage(HRESULT errorCode); - -static const UInt32 k_ErrorFlagsIds[] = -{ - IDS_EXTRACT_MSG_IS_NOT_ARC, - IDS_EXTRACT_MSG_HEADERS_ERROR, - IDS_EXTRACT_MSG_HEADERS_ERROR, - IDS_OPEN_MSG_UNAVAILABLE_START, - IDS_OPEN_MSG_UNCONFIRMED_START, - IDS_EXTRACT_MSG_UEXPECTED_END, - IDS_EXTRACT_MSG_DATA_AFTER_END, - IDS_EXTRACT_MSG_UNSUPPORTED_METHOD, - IDS_OPEN_MSG_UNSUPPORTED_FEATURE, - IDS_EXTRACT_MSG_DATA_ERROR, - IDS_EXTRACT_MSG_CRC_ERROR -}; - -static void AddNewLineString(UString &s, const UString &m) -{ - s += m; - s.Add_LF(); -} - -UString GetOpenArcErrorMessage(UInt32 errorFlags) -{ - UString s; - - for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++) - { - UInt32 f = ((UInt32)1 << i); - if ((errorFlags & f) == 0) - continue; - UInt32 id = k_ErrorFlagsIds[i]; - UString m = LangString(id); - if (m.IsEmpty()) - continue; - if (f == kpv_ErrorFlags_EncryptedHeadersError) - { - m.AddAscii(" : "); - AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); - } - if (!s.IsEmpty()) - s.Add_LF(); - s += m; - errorFlags &= ~f; - } - - if (errorFlags != 0) - { - char sz[16]; - sz[0] = '0'; - sz[1] = 'x'; - ConvertUInt32ToHex(errorFlags, sz + 2); - if (!s.IsEmpty()) - s.Add_LF(); - s.AddAscii(sz); - } - - return s; -} - -static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) -{ - UInt32 errorFlags = er.GetErrorFlags(); - UInt32 warningFlags = er.GetWarningFlags(); - - if (errorFlags != 0) - AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); - - if (!er.ErrorMessage.IsEmpty()) - AddNewLineString(s, er.ErrorMessage); - - if (warningFlags != 0) - { - s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); - s.AddAscii(":"); - s.Add_LF(); - AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); - } - - if (!er.WarningMessage.IsEmpty()) - { - s += GetNameOfProperty(kpidWarning, L"Warning"); - s.AddAscii(": "); - s += er.WarningMessage; - s.Add_LF(); - } -} - -static UString GetBracedType(const wchar_t *type) -{ - UString s = L'['; - s += type; - s += L']'; - return s; -} - -void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) -{ - FOR_VECTOR (level, arcLink.Arcs) - { - const CArc &arc = arcLink.Arcs[level]; - const CArcErrorInfo &er = arc.ErrorInfo; - - if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0) - continue; - - if (s.IsEmpty()) - { - s += name; - s.Add_LF(); - } - - if (level != 0) - { - AddNewLineString(s, arc.Path); - } - - ErrorInfo_Print(s, er); - - if (er.ErrorFormatIndex >= 0) - { - AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning")); - if (arc.FormatIndex == er.ErrorFormatIndex) - { - AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET)); - } - else - { - AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex)))); - AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex)))); - } - } - } - - if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK) - { - s += name; - s.Add_LF(); - if (!arcLink.Arcs.IsEmpty()) - AddNewLineString(s, arcLink.NonOpen_ArcPath); - - if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE) - { - UINT id = IDS_CANT_OPEN_ARCHIVE; - UString param; - if (arcLink.PasswordWasAsked) - id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE; - else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) - { - id = IDS_CANT_OPEN_AS_TYPE; - param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex)); - } - UString s2 = MyFormatNew(id, param); - s2.Replace(L" ''", L""); - s2.Replace(L"''", L""); - s += s2; - } - else - s += HResultToMessage(result); - - s.Add_LF(); - ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo); - } - - if (!s.IsEmpty() && s.Back() == '\n') - s.DeleteBack(); -} - -HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) -{ - _currentArchivePath = name; - _needWriteArchivePath = true; - - UString s; - OpenResult_GUI(s, codecs, arcLink, name, result); - if (!s.IsEmpty()) - { - NumArchiveErrors++; - AddError_Message(s); - _needWriteArchivePath = false; - } - - return S_OK; -} - -HRESULT CExtractCallbackImp::ThereAreNoFiles() -{ - return S_OK; -} - -void CExtractCallbackImp::Add_ArchiveName_Error() -{ - if (_needWriteArchivePath) - { - if (!_currentArchivePath.IsEmpty()) - AddError_Message(_currentArchivePath); - _needWriteArchivePath = false; - } -} - -HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) -{ - if (result == S_OK) - return result; - NumArchiveErrors++; - if (result == E_ABORT || result == ERROR_DISK_FULL) - return result; - - Add_ArchiveName_Error(); - if (!_currentFilePath.IsEmpty()) - MessageError(_currentFilePath); - MessageError(NError::MyFormatMessage(result)); - return S_OK; -} - -#ifndef _NO_CRYPTO - -HRESULT CExtractCallbackImp::SetPassword(const UString &password) -{ - PasswordIsDefined = true; - Password = password; - return S_OK; -} - -STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) -{ - PasswordWasAsked = true; - if (!PasswordIsDefined) - { - CPasswordDialog dialog; - #ifndef _SFX - bool showPassword = NExtract::Read_ShowPassword(); - dialog.ShowPassword = showPassword; - #endif - ProgressDialog->WaitCreating(); - if (dialog.Create(*ProgressDialog) != IDOK) - return E_ABORT; - Password = dialog.Password; - PasswordIsDefined = true; - #ifndef _SFX - if (dialog.ShowPassword != showPassword) - NExtract::Save_ShowPassword(dialog.ShowPassword); - #endif - } - return StringToBstr(Password, password); -} - -#endif - -#ifndef _SFX - -STDMETHODIMP CExtractCallbackImp::AskWrite( - const wchar_t *srcPath, Int32 srcIsFolder, - const FILETIME *srcTime, const UInt64 *srcSize, - const wchar_t *destPath, - BSTR *destPathResult, - Int32 *writeAnswer) -{ - UString destPathResultTemp = destPath; - - // RINOK(StringToBstr(destPath, destPathResult)); - - *destPathResult = 0; - *writeAnswer = BoolToInt(false); - - FString destPathSys = us2fs(destPath); - bool srcIsFolderSpec = IntToBool(srcIsFolder); - CFileInfo destFileInfo; - - if (destFileInfo.Find(destPathSys)) - { - if (srcIsFolderSpec) - { - if (!destFileInfo.IsDir()) - { - RINOK(MessageError("can not replace file with folder with same name", destPathSys)); - return E_ABORT; - } - *writeAnswer = BoolToInt(false); - return S_OK; - } - - if (destFileInfo.IsDir()) - { - RINOK(MessageError("can not replace folder with file with same name", destPathSys)); - *writeAnswer = BoolToInt(false); - return S_OK; - } - - switch (OverwriteMode) - { - case NExtract::NOverwriteMode::kSkip: - return S_OK; - case NExtract::NOverwriteMode::kAsk: - { - Int32 overwriteResult; - UString destPathSpec = destPath; - int slashPos = destPathSpec.ReverseFind_PathSepar(); - destPathSpec.DeleteFrom(slashPos + 1); - destPathSpec += fs2us(destFileInfo.Name); - - RINOK(AskOverwrite( - destPathSpec, - &destFileInfo.MTime, &destFileInfo.Size, - srcPath, - srcTime, srcSize, - &overwriteResult)); - - switch (overwriteResult) - { - case NOverwriteAnswer::kCancel: return E_ABORT; - case NOverwriteAnswer::kNo: return S_OK; - case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; - case NOverwriteAnswer::kYes: break; - case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break; - case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break; - default: - return E_FAIL; - } - } - } - - if (OverwriteMode == NExtract::NOverwriteMode::kRename) - { - if (!AutoRenamePath(destPathSys)) - { - RINOK(MessageError("can not create name for file", destPathSys)); - return E_ABORT; - } - destPathResultTemp = fs2us(destPathSys); - } - else - if (!NDir::DeleteFileAlways(destPathSys)) - { - RINOK(MessageError("can not delete output file", destPathSys)); - return E_ABORT; - } - } - *writeAnswer = BoolToInt(true); - return StringToBstr(destPathResultTemp, destPathResult); -} - - -STDMETHODIMP CExtractCallbackImp::UseExtractToStream(Int32 *res) -{ - *res = BoolToInt(StreamMode); - return S_OK; -} - -static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined) -{ - ftDefined = false; - NCOM::CPropVariant prop; - RINOK(getProp->GetProp(propID, &prop)); - if (prop.vt == VT_FILETIME) - { - ft = prop.filetime; - ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - - -static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) -{ - NCOM::CPropVariant prop; - result = false; - RINOK(getProp->GetProp(propID, &prop)); - if (prop.vt == VT_BOOL) - result = VARIANT_BOOLToBool(prop.boolVal); - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} - - -STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, - Int32 isDir, - ISequentialOutStream **outStream, Int32 askExtractMode, - IGetProp *getProp) -{ - COM_TRY_BEGIN - *outStream = 0; - _newVirtFileWasAdded = false; - _hashStreamWasUsed = false; - _needUpdateStat = false; - - if (_hashStream) - _hashStreamSpec->ReleaseStream(); - - GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); - - if (!ProcessAltStreams && _isAltStream) - return S_OK; - - _filePath = name; - _isFolder = IntToBool(isDir); - _curSize = 0; - _curSizeDefined = false; - - UInt64 size = 0; - bool sizeDefined; - { - NCOM::CPropVariant prop; - RINOK(getProp->GetProp(kpidSize, &prop)); - sizeDefined = ConvertPropVariantToUInt64(prop, size); - } - - if (sizeDefined) - { - _curSize = size; - _curSizeDefined = true; - } - - if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && - askExtractMode != NArchive::NExtract::NAskMode::kTest) - return S_OK; - - _needUpdateStat = true; - - CMyComPtr outStreamLoc; - - if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) - { - CVirtFile &file = VirtFileSystemSpec->AddNewFile(); - _newVirtFileWasAdded = true; - file.Name = name; - file.IsDir = IntToBool(isDir); - file.IsAltStream = _isAltStream; - file.Size = 0; - - RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)); - RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)); - RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)); - - NCOM::CPropVariant prop; - RINOK(getProp->GetProp(kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - { - file.Attrib = prop.ulVal; - file.AttribDefined = true; - } - // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY; - - file.ExpectedSize = 0; - if (sizeDefined) - file.ExpectedSize = size; - outStreamLoc = VirtFileSystem; - } - - if (_hashStream) - { - { - _hashStreamSpec->SetStream(outStreamLoc); - outStreamLoc = _hashStream; - _hashStreamSpec->Init(true); - _hashStreamWasUsed = true; - } - } - - if (outStreamLoc) - *outStream = outStreamLoc.Detach(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode) -{ - COM_TRY_BEGIN - _needUpdateStat = ( - askExtractMode == NArchive::NExtract::NAskMode::kExtract || - askExtractMode == NArchive::NExtract::NAskMode::kTest); - - /* - _extractMode = false; - switch (askExtractMode) - { - case NArchive::NExtract::NAskMode::kExtract: - if (_testMode) - askExtractMode = NArchive::NExtract::NAskMode::kTest; - else - _extractMode = true; - break; - }; - */ - return SetCurrentFilePath2(_filePath); - COM_TRY_END -} - -STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted) -{ - COM_TRY_BEGIN - if (VirtFileSystem && _newVirtFileWasAdded) - { - // FIXME: probably we must request file size from VirtFileSystem - // _curSize = VirtFileSystem->GetLastFileSize() - // _curSizeDefined = true; - RINOK(VirtFileSystemSpec->CloseMemFile()); - } - if (_hashStream && _hashStreamWasUsed) - { - _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath); - _curSize = _hashStreamSpec->GetSize(); - _curSizeDefined = true; - _hashStreamSpec->ReleaseStream(); - _hashStreamWasUsed = false; - } - else if (_hashCalc && _needUpdateStat) - { - _hashCalc->SetSize(_curSize); - _hashCalc->Final(_isFolder, _isAltStream, _filePath); - } - return SetOperationResult(opRes, encrypted); - COM_TRY_END -} - - -static const size_t k_SizeT_MAX = (size_t)((size_t)0 - 1); - -static const UInt32 kBlockSize = ((UInt32)1 << 31); - -STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (size == 0) - return S_OK; - if (!_fileMode) - { - CVirtFile &file = Files.Back(); - size_t rem = file.Data.Size() - (size_t)file.Size; - bool useMem = true; - if (rem < size) - { - UInt64 b = 0; - if (file.Data.Size() == 0) - b = file.ExpectedSize; - UInt64 a = file.Size + size; - if (b < a) - b = a; - a = (UInt64)file.Data.Size() * 2; - if (b < a) - b = a; - useMem = false; - if (b <= k_SizeT_MAX && b <= MaxTotalAllocSize) - useMem = file.Data.ReAlloc_KeepData((size_t)b, (size_t)file.Size); - } - if (useMem) - { - memcpy(file.Data + file.Size, data, size); - file.Size += size; - if (processedSize) - *processedSize = (UInt32)size; - return S_OK; - } - _fileMode = true; - } - RINOK(FlushToDisk(false)); - return _outFileStream->Write(data, size, processedSize); -} - -HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) -{ - if (!_outFileStream) - { - _outFileStreamSpec = new COutFileStream; - _outFileStream = _outFileStreamSpec; - } - while (_numFlushed < Files.Size()) - { - const CVirtFile &file = Files[_numFlushed]; - const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name)); - if (!_fileIsOpen) - { - if (!_outFileStreamSpec->Create(path, false)) - { - _outFileStream.Release(); - return E_FAIL; - // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath)); - } - _fileIsOpen = true; - RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)); - } - if (_numFlushed == Files.Size() - 1 && !closeLast) - break; - if (file.CTimeDefined || - file.ATimeDefined || - file.MTimeDefined) - _outFileStreamSpec->SetTime( - file.CTimeDefined ? &file.CTime : NULL, - file.ATimeDefined ? &file.ATime : NULL, - file.MTimeDefined ? &file.MTime : NULL); - _outFileStreamSpec->Close(); - _numFlushed++; - _fileIsOpen = false; - if (file.AttribDefined) - NDir::SetFileAttrib(path, file.Attrib); - } - return S_OK; -} - -#endif +// ExtractCallback.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/Lang.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../Common/FilePathAutoRename.h" +#include "../../Common/StreamUtils.h" +#include "../Common/ExtractingFilePath.h" + +#ifndef Z7_SFX +#include "../Common/ZipRegistry.h" +#endif + +#include "../GUI/ExtractRes.h" +#include "resourceGui.h" + +#include "ExtractCallback.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "MemDialog.h" +#include "OverwriteDialog.h" +#ifndef Z7_NO_CRYPTO +#include "PasswordDialog.h" +#endif +#include "PropertyName.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +extern bool g_DisableUserQuestions; + +CExtractCallbackImp::~CExtractCallbackImp() {} + +void CExtractCallbackImp::Init() +{ + LangString(IDS_PROGRESS_EXTRACTING, _lang_Extracting); + LangString(IDS_PROGRESS_TESTING, _lang_Testing); + LangString(IDS_PROGRESS_SKIPPING, _lang_Skipping); + _lang_Reading = "Reading"; + + NumArchiveErrors = 0; + ThereAreMessageErrors = false; + #ifndef Z7_SFX + NumFolders = NumFiles = 0; + NeedAddFile = false; + #endif +} + +void CExtractCallbackImp::AddError_Message(LPCWSTR s) +{ + ThereAreMessageErrors = true; + ProgressDialog->Sync.AddError_Message(s); +} + +void CExtractCallbackImp::AddError_Message_ShowArcPath(LPCWSTR s) +{ + Add_ArchiveName_Error(); + AddError_Message(s); +} + + +#ifndef Z7_SFX + +Z7_COM7F_IMF(CExtractCallbackImp::SetNumFiles(UInt64 numFiles)) +{ + #ifdef Z7_SFX + UNUSED_VAR(numFiles) + #else + ProgressDialog->Sync.Set_NumFilesTotal(numFiles); + #endif + return S_OK; +} + +#endif + +Z7_COM7F_IMF(CExtractCallbackImp::SetTotal(UInt64 total)) +{ + ProgressDialog->Sync.Set_NumBytesTotal(total); + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetCompleted(const UInt64 *value)) +{ + return ProgressDialog->Sync.Set_NumBytesCur(value); +} + +HRESULT CExtractCallbackImp::Open_CheckBreak() +{ + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + HRESULT res = S_OK; + if (!MultiArcMode) + { + if (files) + { + _totalFiles_Defined = true; + // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); + } + else + _totalFiles_Defined = false; + + if (bytes) + { + _totalBytes_Defined = true; + ProgressDialog->Sync.Set_NumBytesTotal(*bytes); + } + else + _totalBytes_Defined = false; + } + + return res; +} + +HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + if (!MultiArcMode) + { + if (files) + { + ProgressDialog->Sync.Set_NumFilesCur(*files); + } + + if (bytes) + { + } + } + + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CExtractCallbackImp::Open_Finished() +{ + return ProgressDialog->Sync.CheckStop(); +} + +#ifndef Z7_NO_CRYPTO + +HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password) +{ + return CryptoGetTextPassword(password); +} + +/* +HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) +{ + passwordIsDefined = PasswordIsDefined; + password = Password; + return S_OK; +} + +bool CExtractCallbackImp::Open_WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag() +{ + PasswordWasAsked = false; +} +*/ + +#endif + + +#ifndef Z7_SFX +Z7_COM7F_IMF(CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + ProgressDialog->Sync.Set_Ratio(inSize, outSize); + return S_OK; +} +#endif + +/* +Z7_COM7F_IMF(CExtractCallbackImp::SetTotalFiles(UInt64 total) +{ + ProgressDialog->Sync.SetNumFilesTotal(total); + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) +{ + if (value != NULL) + ProgressDialog->Sync.SetNumFilesCur(*value); + return S_OK; +} +*/ + +Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer)) +{ + COverwriteDialog dialog; + + dialog.OldFileInfo.SetTime2(existTime); + dialog.OldFileInfo.SetSize2(existSize); + dialog.OldFileInfo.Path = existName; + dialog.OldFileInfo.Is_FileSystemFile = true; + + dialog.NewFileInfo.SetTime2(newTime); + dialog.NewFileInfo.SetSize2(newSize); + dialog.NewFileInfo.Path = newName; + dialog.NewFileInfo.Is_FileSystemFile = Src_Is_IO_FS_Folder; + + ProgressDialog->WaitCreating(); + const INT_PTR writeAnswer = dialog.Create(*ProgressDialog); + + switch (writeAnswer) + { + case IDCANCEL: *answer = NOverwriteAnswer::kCancel; return E_ABORT; + case IDYES: *answer = NOverwriteAnswer::kYes; break; + case IDNO: *answer = NOverwriteAnswer::kNo; break; + case IDB_YES_TO_ALL: *answer = NOverwriteAnswer::kYesToAll; break; + case IDB_NO_TO_ALL: *answer = NOverwriteAnswer::kNoToAll; break; + case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break; + default: return E_FAIL; + } + return S_OK; +} + + +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)) +{ + _isFolder = IntToBool(isFolder); + _currentFilePath = name; + + const UString *msg = &_lang_Empty; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break; + case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break; + case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break; + case NArchive::NExtract::NAskMode::kReadExternal: msg = &_lang_Reading; break; + // default: s = "Unknown operation"; + } + + return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder)); +} + +Z7_COM7F_IMF(CExtractCallbackImp::MessageError(const wchar_t *s)) +{ + AddError_Message(s); + return S_OK; +} + +HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path) +{ + ThereAreMessageErrors = true; + ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path)); + return S_OK; +} + +#ifndef Z7_SFX + +Z7_COM7F_IMF(CExtractCallbackImp::ShowMessage(const wchar_t *s)) +{ + AddError_Message(s); + return S_OK; +} + +#endif + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s) +{ + s.Empty(); + + if (opRes == NArchive::NExtract::NOperationResult::kOK) + return; + + #ifndef Z7_SFX + UINT messageID = 0; + #endif + UINT id = 0; + + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + #ifndef Z7_SFX + messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; + #endif + id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD; + break; + case NArchive::NExtract::NOperationResult::kDataError: + #ifndef Z7_SFX + messageID = encrypted ? + IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: + IDS_EXTRACT_MESSAGE_DATA_ERROR; + #endif + id = IDS_EXTRACT_MSG_DATA_ERROR; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + #ifndef Z7_SFX + messageID = encrypted ? + IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED: + IDS_EXTRACT_MESSAGE_CRC_ERROR; + #endif + id = IDS_EXTRACT_MSG_CRC_ERROR; + break; + case NArchive::NExtract::NOperationResult::kUnavailable: + id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA; + break; + case NArchive::NExtract::NOperationResult::kUnexpectedEnd: + id = IDS_EXTRACT_MSG_UEXPECTED_END; + break; + case NArchive::NExtract::NOperationResult::kDataAfterEnd: + id = IDS_EXTRACT_MSG_DATA_AFTER_END; + break; + case NArchive::NExtract::NOperationResult::kIsNotArc: + id = IDS_EXTRACT_MSG_IS_NOT_ARC; + break; + case NArchive::NExtract::NOperationResult::kHeadersError: + id = IDS_EXTRACT_MSG_HEADERS_ERROR; + break; + case NArchive::NExtract::NOperationResult::kWrongPassword: + id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM; + break; + /* + default: + messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR; + break; + */ + } + + UString msg; + + #ifndef Z7_SFX + UString msgOld; + #ifdef Z7_LANG + if (id != 0) + LangString_OnlyFromLangFile(id, msg); + if (messageID != 0 && msg.IsEmpty()) + LangString_OnlyFromLangFile(messageID, msgOld); + #endif + if (msg.IsEmpty() && !msgOld.IsEmpty()) + s = MyFormatNew(msgOld, fileName); + else + #endif + { + if (msg.IsEmpty() && id != 0) + LangString(id, msg); + if (!msg.IsEmpty()) + s += msg; + else + { + s += "Error #"; + s.Add_UInt32((UInt32)opRes); + } + + if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword) + { + // s += " : "; + // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED); + s += " : "; + AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); + } + s += " : "; + s += fileName; + } +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)) +{ + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UString s; + SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s); + AddError_Message_ShowArcPath(s); + } + } + + _currentFilePath.Empty(); + #ifndef Z7_SFX + if (_isFolder) + NumFolders++; + else + NumFiles++; + ProgressDialog->Sync.Set_NumFilesCur(NumFiles); + #endif + + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + UString s; + SetExtractErrorMessage(opRes, encrypted, name, s); + AddError_Message_ShowArcPath(s); + } + return S_OK; +} + +//////////////////////////////////////// +// IExtractCallbackUI + +HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */) +{ + _currentArchivePath = name; + _needWriteArchivePath = true; + #ifndef Z7_SFX + RINOK(ProgressDialog->Sync.CheckStop()) + ProgressDialog->Sync.Set_TitleFileName(name); + #endif + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) +{ + _currentFilePath = path; + #ifndef Z7_SFX + ProgressDialog->Sync.Set_FilePath(path); + #endif + return S_OK; +} + +#ifndef Z7_SFX + +Z7_COM7F_IMF(CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)) +{ + #ifndef Z7_SFX + if (NeedAddFile) + NumFiles++; + NeedAddFile = true; + ProgressDialog->Sync.Set_NumFilesCur(NumFiles); + #endif + return SetCurrentFilePath2(path); +} + +#endif + +UString HResultToMessage(HRESULT errorCode); + +static const UInt32 k_ErrorFlagsIds[] = +{ + IDS_EXTRACT_MSG_IS_NOT_ARC, + IDS_EXTRACT_MSG_HEADERS_ERROR, + IDS_EXTRACT_MSG_HEADERS_ERROR, + IDS_OPEN_MSG_UNAVAILABLE_START, + IDS_OPEN_MSG_UNCONFIRMED_START, + IDS_EXTRACT_MSG_UEXPECTED_END, + IDS_EXTRACT_MSG_DATA_AFTER_END, + IDS_EXTRACT_MSG_UNSUPPORTED_METHOD, + IDS_OPEN_MSG_UNSUPPORTED_FEATURE, + IDS_EXTRACT_MSG_DATA_ERROR, + IDS_EXTRACT_MSG_CRC_ERROR +}; + +static void AddNewLineString(UString &s, const UString &m) +{ + s += m; + s.Add_LF(); +} + +UString GetOpenArcErrorMessage(UInt32 errorFlags); +UString GetOpenArcErrorMessage(UInt32 errorFlags) +{ + UString s; + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++) + { + const UInt32 f = (UInt32)1 << i; + if ((errorFlags & f) == 0) + continue; + const UInt32 id = k_ErrorFlagsIds[i]; + UString m = LangString(id); + if (m.IsEmpty()) + continue; + if (f == kpv_ErrorFlags_EncryptedHeadersError) + { + m += " : "; + AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); + } + if (!s.IsEmpty()) + s.Add_LF(); + s += m; + errorFlags &= ~f; + } + + if (errorFlags != 0) + { + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(errorFlags, sz + 2); + if (!s.IsEmpty()) + s.Add_LF(); + s += sz; + } + + return s; +} + +static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) +{ + const UInt32 errorFlags = er.GetErrorFlags(); + const UInt32 warningFlags = er.GetWarningFlags(); + + if (errorFlags != 0) + AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); + + if (!er.ErrorMessage.IsEmpty()) + AddNewLineString(s, er.ErrorMessage); + + if (warningFlags != 0) + { + s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); + s.Add_Colon(); + s.Add_LF(); + AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); + } + + if (!er.WarningMessage.IsEmpty()) + { + s += GetNameOfProperty(kpidWarning, L"Warning"); + s += ": "; + s += er.WarningMessage; + s.Add_LF(); + } +} + +static UString GetBracedType(const wchar_t *type) +{ + UString s ('['); + s += type; + s.Add_Char(']'); + return s; +} + +void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result); +void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) +{ + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0) + continue; + + if (s.IsEmpty()) + { + s += name; + s.Add_LF(); + } + + if (level != 0) + { + AddNewLineString(s, arc.Path); + } + + ErrorInfo_Print(s, er); + + if (er.ErrorFormatIndex >= 0) + { + AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning")); + if (arc.FormatIndex == er.ErrorFormatIndex) + { + AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET)); + } + else + { + AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex)))); + AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex)))); + } + } + } + + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK) + { + s += name; + s.Add_LF(); + if (!arcLink.Arcs.IsEmpty()) + AddNewLineString(s, arcLink.NonOpen_ArcPath); + + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE) + { + UINT id = IDS_CANT_OPEN_ARCHIVE; + UString param; + if (arcLink.PasswordWasAsked) + id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE; + else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + id = IDS_CANT_OPEN_AS_TYPE; + param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex)); + } + UString s2 = MyFormatNew(id, param); + s2.Replace(L" ''", L""); + s2.Replace(L"''", L""); + s += s2; + } + else + s += HResultToMessage(result); + + s.Add_LF(); + ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo); + } + + if (!s.IsEmpty() && s.Back() == '\n') + s.DeleteBack(); +} + +HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) +{ + _currentArchivePath = name; + _needWriteArchivePath = true; + + UString s; + OpenResult_GUI(s, codecs, arcLink, name, result); + if (!s.IsEmpty()) + { + NumArchiveErrors++; + AddError_Message(s); + _needWriteArchivePath = false; + } + + return S_OK; +} + +HRESULT CExtractCallbackImp::ThereAreNoFiles() +{ + return S_OK; +} + +void CExtractCallbackImp::Add_ArchiveName_Error() +{ + if (_needWriteArchivePath) + { + if (!_currentArchivePath.IsEmpty()) + AddError_Message(_currentArchivePath); + _needWriteArchivePath = false; + } +} + +HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) +{ + #ifndef Z7_SFX + ProgressDialog->Sync.Set_FilePath(L""); + #endif + + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT + || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL) + ) + return result; + + Add_ArchiveName_Error(); + if (!_currentFilePath.IsEmpty()) + MessageError(_currentFilePath); + MessageError(NError::MyFormatMessage(result)); + return S_OK; +} + +#ifndef Z7_NO_CRYPTO + +HRESULT CExtractCallbackImp::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + +Z7_COM7F_IMF(CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + #ifndef Z7_SFX + const bool showPassword = NExtract::Read_ShowPassword(); + dialog.ShowPassword = showPassword; + #endif + ProgressDialog->WaitCreating(); + if (dialog.Create(*ProgressDialog) != IDOK) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + #ifndef Z7_SFX + if (dialog.ShowPassword != showPassword) + NExtract::Save_ShowPassword(dialog.ShowPassword); + #endif + } + return StringToBstr(Password, password); +} + +#endif + +#ifndef Z7_SFX + +Z7_COM7F_IMF(CExtractCallbackImp::AskWrite( + const wchar_t *srcPath, Int32 srcIsFolder, + const FILETIME *srcTime, const UInt64 *srcSize, + const wchar_t *destPath, + BSTR *destPathResult, + Int32 *writeAnswer)) +{ + UString destPathResultTemp = destPath; + + // RINOK(StringToBstr(destPath, destPathResult)); + + *destPathResult = NULL; + *writeAnswer = BoolToInt(false); + + FString destPathSys = us2fs(destPath); + const bool srcIsFolderSpec = IntToBool(srcIsFolder); + CFileInfo destFileInfo; + + if (destFileInfo.Find(destPathSys)) + { + if (srcIsFolderSpec) + { + if (!destFileInfo.IsDir()) + { + RINOK(MessageError("Cannot replace file with folder with same name", destPathSys)) + return E_ABORT; + } + *writeAnswer = BoolToInt(false); + return S_OK; + } + + if (destFileInfo.IsDir()) + { + RINOK(MessageError("Cannot replace folder with file with same name", destPathSys)) + *writeAnswer = BoolToInt(false); + return S_OK; + } + + switch ((int)OverwriteMode) + { + case NExtract::NOverwriteMode::kSkip: + return S_OK; + case NExtract::NOverwriteMode::kAsk: + { + Int32 overwriteResult; + UString destPathSpec = destPath; + const int slashPos = destPathSpec.ReverseFind_PathSepar(); + destPathSpec.DeleteFrom((unsigned)(slashPos + 1)); + destPathSpec += fs2us(destFileInfo.Name); + + RINOK(AskOverwrite( + destPathSpec, + &destFileInfo.MTime, &destFileInfo.Size, + srcPath, + srcTime, srcSize, + &overwriteResult)) + + switch (overwriteResult) + { + case NOverwriteAnswer::kCancel: return E_ABORT; + case NOverwriteAnswer::kNo: return S_OK; + case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; + case NOverwriteAnswer::kYes: break; + case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break; + case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break; + default: + return E_FAIL; + } + break; + } + default: + break; + } + + if (OverwriteMode == NExtract::NOverwriteMode::kRename) + { + if (!AutoRenamePath(destPathSys)) + { + RINOK(MessageError("Cannot create name for file", destPathSys)) + return E_ABORT; + } + destPathResultTemp = fs2us(destPathSys); + } + else + { + if (NFind::DoesFileExist_Raw(destPathSys)) + if (!NDir::DeleteFileAlways(destPathSys)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) + { + RINOK(MessageError("Cannot delete output file", destPathSys)) + return E_ABORT; + } + } + } + *writeAnswer = BoolToInt(true); + return StringToBstr(destPathResultTemp, destPathResult); +} + + +Z7_COM7F_IMF(CExtractCallbackImp::UseExtractToStream(Int32 *res)) +{ + *res = BoolToInt(StreamMode); + return S_OK; +} + +static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined) +{ + ftDefined = false; + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(propID, &prop)) + if (prop.vt == VT_FILETIME) + { + ft = prop.filetime; + ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + result = false; + RINOK(getProp->GetProp(propID, &prop)) + if (prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name, + Int32 isDir, + ISequentialOutStream **outStream, Int32 askExtractMode, + IGetProp *getProp)) +{ + COM_TRY_BEGIN + *outStream = NULL; + _newVirtFileWasAdded = false; + _hashStream_WasUsed = false; + _needUpdateStat = false; + _isFolder = IntToBool(isDir); + _curSize_Defined = false; + _curSize = 0; + + if (_hashStream) + _hashStream->ReleaseStream(); + + _filePath = name; + + UInt64 size = 0; + bool size_Defined; + { + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(kpidSize, &prop)) + size_Defined = ConvertPropVariantToUInt64(prop, size); + } + if (size_Defined) + { + _curSize = size; + _curSize_Defined = true; + } + + GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); + if (!ProcessAltStreams && _isAltStream) + return S_OK; + + if (isDir) // we don't support dir items extraction in this code + return S_OK; + + if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && + askExtractMode != NArchive::NExtract::NAskMode::kTest) + return S_OK; + + _needUpdateStat = true; + + CMyComPtr outStreamLoc; + + if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + if (!VirtFileSystemSpec->Files.IsEmpty()) + VirtFileSystemSpec->MaxTotalAllocSize -= VirtFileSystemSpec->Files.Back().Data.Size(); + CVirtFile &file = VirtFileSystemSpec->Files.AddNew(); + _newVirtFileWasAdded = true; + // file.IsDir = _isFolder; + file.IsAltStream = _isAltStream; + file.WrittenSize = 0; + file.ExpectedSize = 0; + if (size_Defined) + file.ExpectedSize = size; + + if (VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files < 0) + if (!file.IsAltStream || VirtFileSystemSpec->IsAltStreamFile) + VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files = + (int)(VirtFileSystemSpec->Files.Size() - 1); + + /* if we open only AltStream, then (name) contains only name without "fileName:" prefix */ + file.BaseName = name; + + if (file.IsAltStream + && !VirtFileSystemSpec->IsAltStreamFile + && file.BaseName.IsPrefixedBy_NoCase(VirtFileSystemSpec->FileName)) + { + const unsigned colonPos = VirtFileSystemSpec->FileName.Len(); + if (file.BaseName[colonPos] == ':') + { + file.ColonWasUsed = true; + file.AltStreamName = name + (size_t)colonPos + 1; + file.BaseName.DeleteFrom(colonPos); + if (Is_ZoneId_StreamName(file.AltStreamName)) + { + if (VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files < 0) + VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files = + (int)(VirtFileSystemSpec->Files.Size() - 1); + } + } + } + RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTime_Defined)) + RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATime_Defined)) + RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTime_Defined)) + { + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + { + file.Attrib = prop.ulVal; + file.Attrib_Defined = true; + } + } + outStreamLoc = VirtFileSystem; + } + + if (_hashStream) + { + _hashStream->SetStream(outStreamLoc); + outStreamLoc = _hashStream; + _hashStream->Init(true); + _hashStream_WasUsed = true; + } + + if (outStreamLoc) + *outStream = outStreamLoc.Detach(); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)) +{ + COM_TRY_BEGIN + _needUpdateStat = ( + askExtractMode == NArchive::NExtract::NAskMode::kExtract + || askExtractMode == NArchive::NExtract::NAskMode::kTest + || askExtractMode == NArchive::NExtract::NAskMode::kReadExternal + ); + + /* + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + askExtractMode = NArchive::NExtract::NAskMode::kTest; + else + _extractMode = true; + break; + }; + */ + return SetCurrentFilePath2(_filePath); + COM_TRY_END +} + +Z7_COM7F_IMF(CExtractCallbackImp::SetOperationResult8(Int32 opRes, Int32 encrypted, UInt64 size)) +{ + COM_TRY_BEGIN + if (VirtFileSystem && _newVirtFileWasAdded) + { + // FIXME: probably we must request file size from VirtFileSystem + // _curSize = VirtFileSystem->GetLastFileSize() + // _curSize_Defined = true; + RINOK(VirtFileSystemSpec->CloseMemFile()) + } + if (_hashStream && _hashStream_WasUsed) + { + _hashStream->_hash->Final(_isFolder, _isAltStream, _filePath); + _curSize = _hashStream->GetSize(); + _curSize_Defined = true; + _hashStream->ReleaseStream(); + _hashStream_WasUsed = false; + } + else if (_hashCalc && _needUpdateStat) + { + _hashCalc->SetSize(size); // (_curSize) before 21.04 + _hashCalc->Final(_isFolder, _isAltStream, _filePath); + } + return SetOperationResult(opRes, encrypted); + COM_TRY_END +} + + +Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse( + UInt32 flags, UInt32 indexType, UInt32 /* index */, const wchar_t *path, + UInt64 requiredSize, UInt64 *allowedSize, UInt32 *answerFlags)) +{ + UInt32 limit_GB = (UInt32)((*allowedSize + ((1u << 30) - 1)) >> 30); + + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + UInt64 limit_bytes = *allowedSize; + const UInt32 limit_GB_Registry = NExtract::Read_LimitGB(); + if (limit_GB_Registry != 0 && limit_GB_Registry != (UInt32)(Int32)-1) + { + const UInt64 limit_bytes_Registry = (UInt64)limit_GB_Registry << 30; + // registry_WasForced = true; + if ((flags & NRequestMemoryUseFlags::k_AllowedSize_WasForced) == 0 + || limit_bytes < limit_bytes_Registry) + { + limit_bytes = limit_bytes_Registry; + limit_GB = limit_GB_Registry; + } + } + *allowedSize = limit_bytes; + if (requiredSize <= limit_bytes) + { + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; + return S_OK; + } + // default answer can be k_Allow, if limit was not forced, + // so we change answer to non-allowed here, + // because user has chance to change limit in GUI. + *answerFlags = NRequestMemoryAnswerFlags::k_Limit_Exceeded; + if (flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) + *answerFlags |= NRequestMemoryAnswerFlags::k_SkipArc; + } + + const UInt32 required_GB = (UInt32)((requiredSize + ((1u << 30) - 1)) >> 30); + + CMemDialog dialog; + dialog.Limit_GB = limit_GB; + dialog.Required_GB = required_GB; + dialog.TestMode = TestMode; + if (MultiArcMode) + dialog.ArcPath = _currentArchivePath; + if (path) + dialog.FilePath = path; + + if (!g_DisableUserQuestions + && (flags & NRequestMemoryUseFlags::k_IsReport) == 0) + { + if (_remember) + dialog.SkipArc = _skipArc; + else + { + dialog.ShowRemember = + (MultiArcMode + || indexType != NArchive::NEventIndexType::kNoIndex + || path); + ProgressDialog->WaitCreating(); + if (dialog.Create(*ProgressDialog) != IDCONTINUE) + { + *answerFlags = NRequestMemoryAnswerFlags::k_Stop; + return E_ABORT; + } + if (dialog.NeedSave) + NExtract::Save_LimitGB(dialog.Limit_GB); + if (dialog.Remember) + { + _remember = true; + _skipArc = dialog.SkipArc; + } + } + + *allowedSize = (UInt64)dialog.Limit_GB << 30; + if (!dialog.SkipArc) + { + *answerFlags = NRequestMemoryAnswerFlags::k_Allow; + return S_OK; + } + *answerFlags = + NRequestMemoryAnswerFlags::k_SkipArc + | NRequestMemoryAnswerFlags::k_Limit_Exceeded; + flags |= NRequestMemoryUseFlags::k_Report_SkipArc; + } + + if ((flags & NRequestMemoryUseFlags::k_NoErrorMessage) == 0) + { + UString s ("ERROR: "); + dialog.AddInfoMessage_To_String(s); + s.Add_LF(); + // if (indexType == NArchive::NEventIndexType::kNoIndex) + if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) || + (flags & NRequestMemoryUseFlags::k_Report_SkipArc)) + AddLangString(s, IDS_MSG_ARC_UNPACKING_WAS_SKIPPED); +/* + else + AddLangString(, IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED); +*/ + AddError_Message_ShowArcPath(s); + } + +/* + if ((flags & NRequestMemoryUseFlags::k_IsReport) == 0) + *answerFlags |= NRequestMemoryAnswerFlags::k_Limit_Exceeded; +*/ + return S_OK; +} + + +Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (!_wasSwitchedToFsMode) + { + CVirtFile &file = Files.Back(); + const size_t rem = file.Data.Size() - file.WrittenSize; + bool useMem = true; + if (rem < size) + { + UInt64 b = 0; + if (file.Data.Size() == 0) + b = file.ExpectedSize; + UInt64 a = (UInt64)file.WrittenSize + size; + if (b < a) + b = a; + a = (UInt64)file.Data.Size() * 2; + if (b < a) + b = a; + useMem = false; + if (b <= MaxTotalAllocSize) + useMem = file.Data.ReAlloc_KeepData((size_t)b, file.WrittenSize); + } + +#if 0 // 1 for debug : FLUSHING TO FS + useMem = false; +#endif + + if (useMem) + { + memcpy(file.Data + file.WrittenSize, data, size); + file.WrittenSize += size; + if (processedSize) + *processedSize = (UInt32)size; + return S_OK; + } + _wasSwitchedToFsMode = true; + } + + if (!_newVirtFileStream_IsReadyToWrite) // we check for _newVirtFileStream_IsReadyToWrite to optimize execution + { + RINOK(FlushToDisk(false)) + } + + if (_needWriteToRealFile) + return _outFileStream.Interface()->Write(data, size, processedSize); + if (processedSize) + *processedSize = size; + return S_OK; +} + + +HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) +{ + while (_numFlushed < Files.Size()) + { + CVirtFile &file = Files[_numFlushed]; + const FString basePath = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.BaseName)); + FString path = basePath; + + if (file.ColonWasUsed) + { + if (ZoneBuf.Size() != 0 + && Is_ZoneId_StreamName(file.AltStreamName)) + { + // it's expected that + // CArchiveExtractCallback::GetStream() have excluded + // ZoneId alt stream from extraction already. + // But we exclude alt stream extraction here too. + _numFlushed++; + continue; + } + path.Add_Colon(); + path += us2fs(Get_Correct_FsFile_Name(file.AltStreamName)); + } + + if (!_newVirtFileStream_IsReadyToWrite) + { + if (file.ColonWasUsed) + { + NFind::CFileInfo parentFi; + if (parentFi.Find(basePath) + && parentFi.IsReadOnly()) + { + _altStream_NeedRestore_Attrib_bool = true; + _altStream_NeedRestore_AttribVal = parentFi.Attrib; + NDir::SetFileAttrib(basePath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } + } + _outFileStream.Create_if_Empty(); + _needWriteToRealFile = _outFileStream->Create_NEW(path); + if (!_needWriteToRealFile) + { + if (!file.ColonWasUsed) + return GetLastError_noZero_HRESULT(); // it's main file and we can't ignore such error. + // (file.ColonWasUsed == true) + // So it's additional alt stream. + // And we ignore file creation error for additional alt stream. + // ShowErrorMessage(UString("Can't create file ") + fs2us(path)); + } + _newVirtFileStream_IsReadyToWrite = true; + // _openFilePath = path; + HRESULT hres = S_OK; + if (_needWriteToRealFile) + hres = WriteStream(_outFileStream, file.Data, file.WrittenSize); + // we free allocated memory buffer after data flushing: + file.WrittenSize = 0; + file.Data.Free(); + RINOK(hres) + } + + if (_numFlushed == Files.Size() - 1 && !closeLast) + break; + + if (_needWriteToRealFile) + { + if (file.CTime_Defined || + file.ATime_Defined || + file.MTime_Defined) + _outFileStream->SetTime( + file.CTime_Defined ? &file.CTime : NULL, + file.ATime_Defined ? &file.ATime : NULL, + file.MTime_Defined ? &file.MTime : NULL); + _outFileStream->Close(); + } + + _numFlushed++; + _newVirtFileStream_IsReadyToWrite = false; + + if (_needWriteToRealFile) + { + if (!file.ColonWasUsed + && ZoneBuf.Size() != 0) + WriteZoneFile_To_BaseFile(path, ZoneBuf); + if (file.Attrib_Defined) + NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); + // _openFilePath.Empty(); + _needWriteToRealFile = false; + } + + if (_altStream_NeedRestore_Attrib_bool) + { + _altStream_NeedRestore_Attrib_bool = false; + NDir::SetFileAttrib(basePath, _altStream_NeedRestore_AttribVal); + } + } + return S_OK; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ExtractCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ExtractCallback.h 2015-09-19 09:42:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ExtractCallback.h 2024-10-21 07:00:00.000000000 +0000 @@ -1,328 +1,347 @@ -// ExtractCallback.h - -#ifndef __EXTRACT_CALLBACK_H -#define __EXTRACT_CALLBACK_H - -#include "../../../../C/Alloc.h" - -#include "../../../Common/MyCom.h" -#include "../../../Common/StringConvert.h" - -#ifndef _SFX -#include "../Agent/IFolderArchive.h" -#endif - -#include "../Common/ArchiveExtractCallback.h" -#include "../Common/ArchiveOpenCallback.h" - -#ifndef _NO_CRYPTO -#include "../../IPassword.h" -#endif - -#ifndef _SFX -#include "IFolder.h" -#endif - -#include "ProgressDialog2.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -#ifndef _SFX - -class CGrowBuf -{ - Byte *_items; - size_t _size; - - CLASS_NO_COPY(CGrowBuf); - -public: - bool ReAlloc_KeepData(size_t newSize, size_t keepSize) - { - void *buf = MyAlloc(newSize); - if (!buf) - return false; - if (keepSize != 0) - memcpy(buf, _items, keepSize); - MyFree(_items); - _items = (Byte *)buf; - _size = newSize; - return true; - } - - CGrowBuf(): _items(0), _size(0) {} - ~CGrowBuf() { MyFree(_items); } - - operator Byte *() { return _items; } - operator const Byte *() const { return _items; } - size_t Size() const { return _size; } -}; - -struct CVirtFile -{ - CGrowBuf Data; - - UInt64 Size; // real size - UInt64 ExpectedSize; // the size from props request. 0 if unknown - - UString Name; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool AttribDefined; - - bool IsDir; - bool IsAltStream; - - DWORD Attrib; - - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - - CVirtFile(): - CTimeDefined(false), - ATimeDefined(false), - MTimeDefined(false), - AttribDefined(false), - IsDir(false), - IsAltStream(false) {} -}; - -class CVirtFileSystem: - public ISequentialOutStream, - public CMyUnknownImp -{ - UInt64 _totalAllocSize; - - size_t _pos; - unsigned _numFlushed; - bool _fileIsOpen; - bool _fileMode; - COutFileStream *_outFileStreamSpec; - CMyComPtr _outFileStream; -public: - CObjectVector Files; - UInt64 MaxTotalAllocSize; - FString DirPrefix; - - CVirtFile &AddNewFile() - { - if (!Files.IsEmpty()) - { - MaxTotalAllocSize -= Files.Back().Data.Size(); - } - return Files.AddNew(); - } - HRESULT CloseMemFile() - { - if (_fileMode) - { - return FlushToDisk(true); - } - CVirtFile &file = Files.Back(); - if (file.Data.Size() != file.Size) - { - file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); - } - return S_OK; - } - - bool IsStreamInMem() const - { - if (_fileMode) - return false; - if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir) - return false; - return true; - } - - size_t GetMemStreamWrittenSize() const { return _pos; } - - CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {} - - void Init() - { - _totalAllocSize = 0; - _fileMode = false; - _pos = 0; - _numFlushed = 0; - _fileIsOpen = false; - } - - HRESULT CloseFile(const FString &path); - HRESULT FlushToDisk(bool closeLast); - size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -#endif - -class CExtractCallbackImp: - public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback - public IOpenCallbackUI, - public IFolderArchiveExtractCallback2, - #ifndef _SFX - public IFolderOperationsExtractCallback, - public IFolderExtractToStreamCallback, - public ICompressProgressInfo, - #endif - #ifndef _NO_CRYPTO - public ICryptoGetTextPassword, - #endif - public CMyUnknownImp -{ - HRESULT MessageError(const char *message, const FString &path); - void Add_ArchiveName_Error(); -public: - MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) - MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) - #ifndef _SFX - MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback) - MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback) - MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) - #endif - #ifndef _NO_CRYPTO - MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) - #endif - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - INTERFACE_IProgress(;) - INTERFACE_IOpenCallbackUI(;) - INTERFACE_IFolderArchiveExtractCallback(;) - INTERFACE_IFolderArchiveExtractCallback2(;) - // STDMETHOD(SetTotalFiles)(UInt64 total); - // STDMETHOD(SetCompletedFiles)(const UInt64 *value); - - INTERFACE_IExtractCallbackUI(;) - - #ifndef _SFX - // IFolderOperationsExtractCallback - STDMETHOD(AskWrite)( - const wchar_t *srcPath, - Int32 srcIsFolder, - const FILETIME *srcTime, - const UInt64 *srcSize, - const wchar_t *destPathRequest, - BSTR *destPathResult, - Int32 *writeAnswer); - STDMETHOD(ShowMessage)(const wchar_t *message); - STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); - STDMETHOD(SetNumFiles)(UInt64 numFiles); - INTERFACE_IFolderExtractToStreamCallback(;) - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - #endif - - // ICryptoGetTextPassword - #ifndef _NO_CRYPTO - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - #endif - -private: - UString _currentArchivePath; - bool _needWriteArchivePath; - - UString _currentFilePath; - bool _isFolder; - - bool _isAltStream; - UInt64 _curSize; - bool _curSizeDefined; - UString _filePath; - // bool _extractMode; - // bool _testMode; - bool _newVirtFileWasAdded; - bool _needUpdateStat; - - - HRESULT SetCurrentFilePath2(const wchar_t *filePath); - void AddError_Message(LPCWSTR message); - - #ifndef _SFX - bool _hashStreamWasUsed; - COutStreamWithHash *_hashStreamSpec; - CMyComPtr _hashStream; - IHashCalc *_hashCalc; // it's for stat in Test operation - #endif - -public: - - #ifndef _SFX - CVirtFileSystem *VirtFileSystemSpec; - CMyComPtr VirtFileSystem; - #endif - - bool ProcessAltStreams; - - bool StreamMode; - - CProgressDialog *ProgressDialog; - #ifndef _SFX - UInt64 NumFolders; - UInt64 NumFiles; - bool NeedAddFile; - #endif - UInt32 NumArchiveErrors; - bool ThereAreMessageErrors; - NExtract::NOverwriteMode::EEnum OverwriteMode; - - #ifndef _NO_CRYPTO - bool PasswordIsDefined; - bool PasswordWasAsked; - UString Password; - #endif - - - UString _lang_Extracting; - UString _lang_Testing; - UString _lang_Skipping; - UString _lang_Empty; - - bool _totalFilesDefined; - bool _totalBytesDefined; - bool MultiArcMode; - - CExtractCallbackImp(): - #ifndef _NO_CRYPTO - PasswordIsDefined(false), - PasswordWasAsked(false), - #endif - OverwriteMode(NExtract::NOverwriteMode::kAsk), - StreamMode(false), - ProcessAltStreams(true), - - _totalFilesDefined(false), - _totalBytesDefined(false), - MultiArcMode(false) - - #ifndef _SFX - , _hashCalc(NULL) - #endif - {} - - ~CExtractCallbackImp(); - void Init(); - - #ifndef _SFX - void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } - - void SetHashMethods(IHashCalc *hash) - { - if (!hash) - return; - _hashStreamSpec = new COutStreamWithHash; - _hashStream = _hashStreamSpec; - _hashStreamSpec->_hash = hash; - } - #endif - - bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } -}; - -#endif +// ExtractCallback.h + +#ifndef ZIP7_INC_EXTRACT_CALLBACK_H +#define ZIP7_INC_EXTRACT_CALLBACK_H + +#include "../../../../C/Alloc.h" + +#include "../../../Common/MyCom.h" +#include "../../../Common/StringConvert.h" + +#ifndef Z7_SFX +#include "../Agent/IFolderArchive.h" +#endif + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/ArchiveOpenCallback.h" + +#ifndef Z7_NO_CRYPTO +#include "../../IPassword.h" +#endif + +#ifndef Z7_SFX +#include "IFolder.h" +#endif + +#include "ProgressDialog2.h" + +#ifndef Z7_SFX + +class CGrowBuf +{ + Byte *_items; + size_t _size; + + Z7_CLASS_NO_COPY(CGrowBuf) + +public: + void Free() + { + MyFree(_items); + _items = NULL; + _size = 0; + } + + // newSize >= keepSize + bool ReAlloc_KeepData(size_t newSize, size_t keepSize) + { + void *buf = NULL; + if (newSize) + { + buf = MyAlloc(newSize); + if (!buf) + return false; + } + if (keepSize) + memcpy(buf, _items, keepSize); + MyFree(_items); + _items = (Byte *)buf; + _size = newSize; + return true; + } + + CGrowBuf(): _items(NULL), _size(0) {} + ~CGrowBuf() { MyFree(_items); } + + operator Byte *() { return _items; } + operator const Byte *() const { return _items; } + size_t Size() const { return _size; } +}; + + +struct CVirtFile +{ + CGrowBuf Data; + + UInt64 ExpectedSize; // size from props request. 0 if unknown + size_t WrittenSize; // size of written data in (Data) buffer + // use (WrittenSize) only if (CVirtFileSystem::_newVirtFileStream_IsReadyToWrite == false) + UString BaseName; // original name of file inside archive, + // It's not path. So any path separators + // should be treated as part of name (or as incorrect chars) + UString AltStreamName; + + bool CTime_Defined; + bool ATime_Defined; + bool MTime_Defined; + bool Attrib_Defined; + + // bool IsDir; + bool IsAltStream; + bool ColonWasUsed; + DWORD Attrib; + + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + + CVirtFile(): + CTime_Defined(false), + ATime_Defined(false), + MTime_Defined(false), + Attrib_Defined(false), + // IsDir(false), + IsAltStream(false), + ColonWasUsed(false) + {} +}; + + +/* + We use CVirtFileSystem only for single file extraction: + It supports the following cases and names: + - "fileName" : single file + - "fileName" item (main base file) and additional "fileName:altStream" items + - "altStream" : single item without "fileName:" prefix. + If file is flushed to disk, it uses Get_Correct_FsFile_Name(name). +*/ + +Z7_CLASS_IMP_NOQIB_1( + CVirtFileSystem, + ISequentialOutStream +) + unsigned _numFlushed; +public: + bool IsAltStreamFile; // in: + // = true, if extracting file is alt stream without "fileName:" prefix. + // = false, if extracting file is normal file, but additional + // alt streams "fileName:altStream" items are possible. +private: + bool _newVirtFileStream_IsReadyToWrite; // it can non real file (if can't open alt stream) + bool _needWriteToRealFile; // we need real writing to open file. + bool _wasSwitchedToFsMode; + bool _altStream_NeedRestore_Attrib_bool; + DWORD _altStream_NeedRestore_AttribVal; + + CMyComPtr2 _outFileStream; +public: + CObjectVector Files; + size_t MaxTotalAllocSize; // remain size, including Files.Back() + FString DirPrefix; // files will be flushed to this FS directory. + UString FileName; // name of file that will be extracted. + // it can be name of alt stream without "fileName:" prefix, if (IsAltStreamFile == trye). + // we use that name to detect altStream part in "FileName:altStream". + CByteBuffer ZoneBuf; + int Index_of_MainExtractedFile_in_Files; // out: index in Files. == -1, if expected file was not extracted + int Index_of_ZoneBuf_AltStream_in_Files; // out: index in Files. == -1, if no zonbuf alt stream + + + CVirtFileSystem() + { + _numFlushed = 0; + IsAltStreamFile = false; + _newVirtFileStream_IsReadyToWrite = false; + _needWriteToRealFile = false; + _wasSwitchedToFsMode = false; + _altStream_NeedRestore_Attrib_bool = false; + MaxTotalAllocSize = (size_t)0 - 1; + Index_of_MainExtractedFile_in_Files = -1; + Index_of_ZoneBuf_AltStream_in_Files = -1; + } + + bool WasStreamFlushedToFS() const { return _wasSwitchedToFsMode; } + + HRESULT CloseMemFile() + { + if (_wasSwitchedToFsMode) + return FlushToDisk(true); // closeLast + CVirtFile &file = Files.Back(); + if (file.Data.Size() != file.WrittenSize) + file.Data.ReAlloc_KeepData(file.WrittenSize, file.WrittenSize); + return S_OK; + } + + HRESULT FlushToDisk(bool closeLast); +}; + +#endif + + + +class CExtractCallbackImp Z7_final: + public IFolderArchiveExtractCallback, + /* IExtractCallbackUI: + before v23.00 : it included IFolderArchiveExtractCallback + since v23.00 : it doesn't include IFolderArchiveExtractCallback + */ + public IExtractCallbackUI, // NON-COM interface since 23.00 + public IOpenCallbackUI, // NON-COM interface + public IFolderArchiveExtractCallback2, + #ifndef Z7_SFX + public IFolderOperationsExtractCallback, + public IFolderExtractToStreamCallback, + public ICompressProgressInfo, + public IArchiveRequestMemoryUseCallback, + #endif + #ifndef Z7_NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IFolderArchiveExtractCallback) + Z7_COM_QI_ENTRY(IFolderArchiveExtractCallback2) + #ifndef Z7_SFX + Z7_COM_QI_ENTRY(IFolderOperationsExtractCallback) + Z7_COM_QI_ENTRY(IFolderExtractToStreamCallback) + Z7_COM_QI_ENTRY(ICompressProgressInfo) + Z7_COM_QI_ENTRY(IArchiveRequestMemoryUseCallback) + #endif + #ifndef Z7_NO_CRYPTO + Z7_COM_QI_ENTRY(ICryptoGetTextPassword) + #endif + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_IMP(IExtractCallbackUI) + Z7_IFACE_IMP(IOpenCallbackUI) + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback) + Z7_IFACE_COM7_IMP(IFolderArchiveExtractCallback2) + #ifndef Z7_SFX + Z7_IFACE_COM7_IMP(IFolderOperationsExtractCallback) + Z7_IFACE_COM7_IMP(IFolderExtractToStreamCallback) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) + Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) + #endif + #ifndef Z7_NO_CRYPTO + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + #endif + + bool _needWriteArchivePath; + bool _isFolder; + bool _totalFiles_Defined; + bool _totalBytes_Defined; +public: + bool MultiArcMode; + bool ProcessAltStreams; + bool StreamMode; // set to true, if you want the callee to call GetStream7() + bool ThereAreMessageErrors; + bool Src_Is_IO_FS_Folder; + +#ifndef Z7_NO_CRYPTO + bool PasswordIsDefined; + bool PasswordWasAsked; +#endif + +private: +#ifndef Z7_SFX + bool _needUpdateStat; + bool _newVirtFileWasAdded; + bool _isAltStream; + // bool _extractMode; + // bool _testMode; + bool _hashStream_WasUsed; + bool _curSize_Defined; + bool NeedAddFile; + + bool _remember; + bool _skipArc; +#endif + +public: + bool YesToAll; + bool TestMode; + + UInt32 NumArchiveErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + +private: + UString _currentArchivePath; + UString _currentFilePath; + UString _filePath; // virtual path than will be sent via IFolderExtractToStreamCallback + +#ifndef Z7_SFX + UInt64 _curSize; + CMyComPtr2 _hashStream; + IHashCalc *_hashCalc; // it's for stat in Test operation +#endif + +public: + CProgressDialog *ProgressDialog; + +#ifndef Z7_SFX + CVirtFileSystem *VirtFileSystemSpec; + CMyComPtr VirtFileSystem; + UInt64 NumFolders; + UInt64 NumFiles; +#endif + +#ifndef Z7_NO_CRYPTO + UString Password; +#endif + + UString _lang_Extracting; + UString _lang_Testing; + UString _lang_Skipping; + UString _lang_Reading; + UString _lang_Empty; + + CExtractCallbackImp(): + _totalFiles_Defined(false) + , _totalBytes_Defined(false) + , MultiArcMode(false) + , ProcessAltStreams(true) + , StreamMode(false) + , ThereAreMessageErrors(false) + , Src_Is_IO_FS_Folder(false) +#ifndef Z7_NO_CRYPTO + , PasswordIsDefined(false) + , PasswordWasAsked(false) +#endif +#ifndef Z7_SFX + , _remember(false) + , _skipArc(false) +#endif + , YesToAll(false) + , TestMode(false) + , OverwriteMode(NExtract::NOverwriteMode::kAsk) +#ifndef Z7_SFX + , _hashCalc(NULL) +#endif + {} + + ~CExtractCallbackImp(); + void Init(); + + HRESULT SetCurrentFilePath2(const wchar_t *filePath); + void AddError_Message(LPCWSTR message); + void AddError_Message_ShowArcPath(LPCWSTR message); + HRESULT MessageError(const char *message, const FString &path); + void Add_ArchiveName_Error(); + + #ifndef Z7_SFX + void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } + + void SetHashMethods(IHashCalc *hash) + { + if (!hash) + return; + _hashStream.Create_if_Empty(); + _hashStream->_hash = hash; + } + #endif + + bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.cpp 2015-09-19 18:33:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.cpp 2025-06-15 08:00:00.000000000 +0000 @@ -1,1124 +1,1223 @@ -// FM.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/ErrorMsg.h" -// FIXME #include "../../../Windows/MemoryLock.h" -// FIXME #include "../../../Windows/NtCheck.h" -#include "../../../Windows/System.h" - -#ifndef UNDER_CE -// FIXME #include "../../../Windows/SecurityUtils.h" -#endif - -#include "../GUI/ExtractRes.h" - -#include "resource.h" - -#include "App.h" -#include "FormatUtils.h" -#include "LangUtils.h" -#include "MyLoadMenu.h" -#include "Panel.h" -#include "RegistryUtils.h" -#include "StringUtils.h" -#include "ViewSettings.h" - -static void local_WM_CREATE(HWND hWnd); - -using namespace NWindows; -using namespace NFile; -using namespace NFind; - -#define MAX_LOADSTRING 100 - -#define MENU_HEIGHT 26 - -UInt64 g_RAM_Size; - -#ifdef _WIN32 -HINSTANCE g_hInstance; -#endif -HWND g_HWND; -bool g_OpenArchive = false; -static UString g_MainPath; -static UString g_ArcFormat; -static bool g_Maximized = false; - -// HRESULT LoadGlobalCodecs(); -void FreeGlobalCodecs(); - -#if 0 // #ifndef UNDER_CE - -DWORD g_ComCtl32Version; - -static DWORD GetDllVersion(LPCTSTR dllName) -{ - DWORD dwVersion = 0; - HINSTANCE hinstDll = LoadLibrary(dllName); - if (hinstDll) - { - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion"); - if (pDllGetVersion) - { - DLLVERSIONINFO dvi; - ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hr = (*pDllGetVersion)(&dvi); - if (SUCCEEDED(hr)) - dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); - } - FreeLibrary(hinstDll); - } - return dwVersion; -} - -#endif - -bool g_IsSmallScreen = false; - -bool g_LVN_ITEMACTIVATE_Support = true; -// LVN_ITEMACTIVATE replaces both NM_DBLCLK & NM_RETURN -// Windows 2000 -// NT/98 + IE 3 (g_ComCtl32Version >= 4.70) - - -const int kNumDefaultPanels = 1; - -const int kSplitterWidth = 4; -int kSplitterRateMax = 1 << 16; -int kPanelSizeMin = 120; - -// bool OnMenuCommand(HWND hWnd, int id); - -#ifdef _WIN32 -class CSplitterPos -{ - int _ratio; // 10000 is max - int _pos; - int _fullWidth; - void SetRatioFromPos(HWND hWnd) - { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax / - MyMax(GetWidth(hWnd), 1); } -public: - int GetPos() const - { return _pos; } - int GetWidth(HWND hWnd) const - { - RECT rect; - ::GetClientRect(hWnd, &rect); - return rect.right; - } - void SetRatio(HWND hWnd, int aRatio) - { - _ratio = aRatio; - SetPosFromRatio(hWnd); - } - void SetPosPure(HWND hWnd, int pos) - { - int posMax = GetWidth(hWnd) - kSplitterWidth; - if (posMax < kPanelSizeMin * 2) - pos = posMax / 2; - else - { - if (pos > posMax - kPanelSizeMin) - pos = posMax - kPanelSizeMin; - else if (pos < kPanelSizeMin) - pos = kPanelSizeMin; - } - _pos = pos; - } - void SetPos(HWND hWnd, int pos) - { - _fullWidth = GetWidth(hWnd); - SetPosPure(hWnd, pos); - SetRatioFromPos(hWnd); - } - void SetPosFromRatio(HWND hWnd) - { - int fullWidth = GetWidth(hWnd); - if (_fullWidth != fullWidth && fullWidth != 0) - { - _fullWidth = fullWidth; - SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2); - } - } -}; - -static bool g_CanChangeSplitter = false; -static UInt32 g_SplitterPos = 0; -static CSplitterPos g_Splitter; -#endif -static bool g_PanelsInfoDefined = false; - -static int g_StartCaptureMousePos; -static int g_StartCaptureSplitterPos; - -CApp g_App; - -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - -const wchar_t *kWindowClass = L"FM"; - -#ifdef UNDER_CE -#define WS_OVERLAPPEDWINDOW ( \ - WS_OVERLAPPED | \ - WS_CAPTION | \ - WS_SYSMENU | \ - WS_THICKFRAME | \ - WS_MINIMIZEBOX | \ - WS_MAXIMIZEBOX) -#endif - -// FUNCTION: InitInstance(HANDLE, int) -static BOOL InitInstance(int nCmdShow) -{ - CWindow wnd; - - // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING); - - UString title = L"7-Zip (ALPHA Software)"; // LangString(IDS_APP_TITLE, 0x03000000); - - /* - //If it is already running, then focus on the window - hWnd = FindWindow(windowClass, title); - if (hWnd) - { - SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01)); - return 0; - } - */ - -#ifdef _WIN32 - WNDCLASSW wc; - - // wc.style = CS_HREDRAW | CS_VREDRAW; - wc.style = 0; - wc.lpfnWndProc = (WNDPROC) WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = g_hInstance; - wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON)); - - // wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hCursor = ::LoadCursor(0, IDC_SIZEWE); - // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - - wc.lpszMenuName = - #ifdef UNDER_CE - 0 - #else - MAKEINTRESOURCEW(IDM_MENU) - #endif - ; - - wc.lpszClassName = kWindowClass; - - MyRegisterClass(&wc); - - // RECT rect; - // GetClientRect(hWnd, &rect); - - DWORD style = WS_OVERLAPPEDWINDOW; - // DWORD style = 0; - - CWindowInfo info; - info.maximized = false; - int x, y, xSize, ySize; - x = y = xSize = ySize = CW_USEDEFAULT; - bool windowPosIsRead; - info.Read(windowPosIsRead, g_PanelsInfoDefined); - - if (windowPosIsRead) - { - // x = rect.left; - // y = rect.top; - xSize = RECT_SIZE_X(info.rect); - ySize = RECT_SIZE_Y(info.rect); - } - - - if (g_PanelsInfoDefined) - { - g_SplitterPos = info.splitterPos; - if (info.numPanels < 1 || info.numPanels > 2) - info.numPanels = kNumDefaultPanels; - if (info.currentPanel >= 2) - info.currentPanel = 0; - } - else - { - info.numPanels = kNumDefaultPanels; - info.currentPanel = 0; - } -#endif - g_App.NumPanels = kNumDefaultPanels; // FIXME info.numPanels; - g_App.LastFocusedPanel = 0; // FIXME info.currentPanel; - -#ifdef _WIN32 - if (!wnd.Create(kWindowClass, title, style, - x, y, xSize, ySize, NULL, NULL, g_hInstance, NULL)) - return FALSE; -#else - { - extern HWND myCreateAndShowMainWindow(LPCTSTR title,void (*fct)(HWND)); - g_HWND = myCreateAndShowMainWindow(title,local_WM_CREATE); - } -#endif - -#if 0 - if (nCmdShow == SW_SHOWNORMAL || - nCmdShow == SW_SHOW - #ifndef UNDER_CE - || nCmdShow == SW_SHOWDEFAULT - #endif - ) - { - if (info.maximized) - nCmdShow = SW_SHOWMAXIMIZED; - else - nCmdShow = SW_SHOWNORMAL; - } - - if (nCmdShow == SW_SHOWMAXIMIZED) - g_Maximized = true; - - #ifndef UNDER_CE - WINDOWPLACEMENT placement; - placement.length = sizeof(placement); - if (wnd.GetPlacement(&placement)) - { - if (windowPosIsRead) - placement.rcNormalPosition = info.rect; - placement.showCmd = nCmdShow; - wnd.SetPlacement(&placement); - } - else - #endif - wnd.Show(nCmdShow); -#endif - - return TRUE; -} - -/* -static void GetCommands(const UString &aCommandLine, UString &aCommands) -{ - UString aProgramName; - aCommands.Empty(); - bool aQuoteMode = false; - for (int i = 0; i < aCommandLine.Length(); i++) - { - wchar_t aChar = aCommandLine[i]; - if (aChar == L'\"') - aQuoteMode = !aQuoteMode; - else if (aChar == L' ' && !aQuoteMode) - { - if (!aQuoteMode) - { - i++; - break; - } - } - else - aProgramName += aChar; - } - aCommands = aCommandLine.Ptr(i); -} -*/ - -/* -#ifndef _WIN64 -typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); - -static bool IsWow64() -{ - LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( - GetModuleHandle("kernel32"), "IsWow64Process"); - if (fnIsWow64Process == NULL) - return false; - BOOL isWow; - if (!fnIsWow64Process(GetCurrentProcess(),&isWow)) - return false; - return isWow != FALSE; -} -#endif -*/ - -bool IsLargePageSupported() -{ - #ifdef _WIN64 - return true; - #elif defined(_WIN32) - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return false; - if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5) - return false; - if (versionInfo.dwMajorVersion > 5) - return true; - if (versionInfo.dwMinorVersion < 1) - return false; - if (versionInfo.dwMinorVersion > 1) - return true; - // return IsWow64(); - return false; - #else - return false; - #endif -} - -#if 0 // ifndef UNDER_CE - -static void SetMemoryLock() -{ - if (!IsLargePageSupported()) - return; - // if (ReadLockMemoryAdd()) - NSecurity::AddLockMemoryPrivilege(); - - if (ReadLockMemoryEnable()) - NSecurity::EnablePrivilege_LockMemory(); -} - -bool g_SymLink_Supported = false; - -static void Set_SymLink_Supported() -{ - g_SymLink_Supported = false; - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return; - if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 6) - return; - g_SymLink_Supported = true; - // if (g_SymLink_Supported) - { - NSecurity::EnablePrivilege_SymLink(); - } -} - -#endif - -/* -static const int kNumSwitches = 1; - -namespace NKey { -enum Enum -{ - kOpenArachive = 0 -}; - -} - -static const CSwitchForm kSwitchForms[kNumSwitches] = - { - { L"SOA", NSwitchType::kSimple, false }, - }; -*/ - -// int APIENTRY WinMain2(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */); - -static void ErrorMessage(const wchar_t *s) -{ - MessageBoxW(0, s, L"7-Zip", MB_ICONERROR); -} - - -#define NT_CHECK_FAIL_ACTION ErrorMessage(L"Unsupported Windows version"); return 1; -#ifdef _WIN32 -static int WINAPI WinMain2(int nCmdShow) -{ - g_RAM_Size = NSystem::GetRamSize(); - - #ifdef _WIN32 - - /* - #ifndef _WIN64 - #ifndef UNDER_CE - { - HMODULE hMod = GetModuleHandle("Kernel32.dll"); - if (hMod) - { - typedef BOOL (WINAPI *PSETDEP)(DWORD); - #define MY_PROCESS_DEP_ENABLE 1 - PSETDEP procSet = (PSETDEP)GetProcAddress(hMod,"SetProcessDEPPolicy"); - if (procSet) - procSet(MY_PROCESS_DEP_ENABLE); - - typedef BOOL (WINAPI *HSI)(HANDLE, HEAP_INFORMATION_CLASS ,PVOID, SIZE_T); - HSI hsi = (HSI)GetProcAddress(hMod, "HeapSetInformation"); - #define MY_HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)1) - if (hsi) - hsi(NULL, MY_HeapEnableTerminationOnCorruption, NULL, 0); - } - } - #endif - #endif - */ - - NT_CHECK - SetLargePageSize(); - - #endif - - LoadLangOneTime(); - - InitCommonControls(); - - #ifndef UNDER_CE - g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); - g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); - #endif - - g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200); - - // OleInitialize is required for drag and drop. - #ifndef UNDER_CE - OleInitialize(NULL); - #endif - // Maybe needs CoInitializeEx also ? - // NCOM::CComInitializer comInitializer; - - UString commandsString; - // MessageBoxW(0, GetCommandLineW(), L"", 0); - - #ifdef UNDER_CE - commandsString = GetCommandLineW(); - #else - UString programString; - SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString); - #endif - - commandsString.Trim(); - UString paramString, tailString; - SplitStringToTwoStrings(commandsString, paramString, tailString); - paramString.Trim(); - tailString.Trim(); - if (tailString.IsPrefixedBy(L"-t")) - g_ArcFormat = tailString.Ptr(2); - - /* - UStringVector switches; - for (;;) - { - if (tailString.IsEmpty()) - break; - UString s1, s2; - SplitStringToTwoStrings(tailString, s1, s2); - if (s2.IsEmpty()) - { - tailString.Trim(); - switches.Add(tailString); - break; - } - s1.Trim(); - switches.Add(s1); - tailString = s2; - } - - FOR_VECTOR(i, switches) - { - const UString &sw = switches[i]; - if (sw.IsPrefixedBy(L"-t")) - g_ArcFormat = sw.Ptr(2); - // - else if (sw.IsPrefixedBy(L"-stp")) - { - const wchar_t *end; - UInt32 val = ConvertStringToUInt32(sw.Ptr(4), &end); - if (*end != 0) - throw 111; - g_TypeParseLevel = val; - } - else - // - throw 112; - } - */ - - if (!paramString.IsEmpty()) - { - g_MainPath = paramString; - // return WinMain2(hInstance, hPrevInstance, lpCmdLine, nCmdShow); - - // MessageBoxW(0, paramString, L"", 0); - } - /* - UStringVector commandStrings; - NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); - NCommandLineParser::CParser parser(kNumSwitches); - try - { - parser.ParseStrings(kSwitchForms, commandStrings); - const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; - if (nonSwitchStrings.Size() > 1) - { - g_MainPath = nonSwitchStrings[1]; - // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs; - CFileInfoW fileInfo; - if (FindFile(g_MainPath, fileInfo)) - { - if (!fileInfo.IsDir()) - g_OpenArchive = true; - } - } - } - catch(...) { } - */ - - - #if defined(_WIN32) && !defined(UNDER_CE) - SetMemoryLock(); - Set_SymLink_Supported(); - #endif - - g_App.ReloadLang(); - - MSG msg; - if (!InitInstance (nCmdShow)) - return FALSE; - - // we will load Global_Codecs at first use instead. - /* - OutputDebugStringW(L"Before LoadGlobalCodecs"); - LoadGlobalCodecs(); - OutputDebugStringW(L"After LoadGlobalCodecs"); - */ - - #ifndef _UNICODE - if (g_IsNT) - { - HACCEL hAccels = LoadAcceleratorsW(g_hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1)); - while (GetMessageW(&msg, NULL, 0, 0)) - { - if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0) - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } - } - else - #endif - { - HACCEL hAccels = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); - while (GetMessage(&msg, NULL, 0, 0)) - { - if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0) - { - // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg)) - // if (!IsDialogMessage(g_Hwnd, &msg)) - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - - // Destructor of g_CodecsReleaser can release DLLs. - // But we suppose that it's better to release DLLs here (before destructor). - FreeGlobalCodecs(); - - g_HWND = 0; - #ifndef UNDER_CE - OleUninitialize(); - #endif - return (int)msg.wParam; -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, - #ifdef UNDER_CE - LPWSTR - #else - LPSTR - #endif - /* lpCmdLine */, int nCmdShow) -{ - g_hInstance = hInstance; - - try - { - return WinMain2(nCmdShow); - } - catch(const CNewException &) - { - ErrorMessage(LangString(IDS_MEM_ERROR)); - return 1; - } - catch(const UString &s) - { - ErrorMessage(s); - return 1; - } - catch(const AString &s) - { - ErrorMessage(GetUnicodeString(s)); - return 1; - } - catch(const wchar_t *s) - { - ErrorMessage(s); - return 1; - } - catch(const char *s) - { - ErrorMessage(GetUnicodeString(s)); - return 1; - } - catch(int v) - { - wchar_t s[32]; - ConvertUInt32ToString(v, s); - ErrorMessage(UString(L"Error: ") + s); - return 1; - } - catch(...) - { - ErrorMessage(L"Unknown error"); - return 1; - } -} - -static void SaveWindowInfo(HWND aWnd) -{ - CWindowInfo info; - - #ifdef UNDER_CE - - if (!::GetWindowRect(aWnd, &info.rect)) - return; - info.maximized = g_Maximized; - - #else - - WINDOWPLACEMENT placement; - placement.length = sizeof(placement); - if (!::GetWindowPlacement(aWnd, &placement)) - return; - info.rect = placement.rcNormalPosition; - info.maximized = BOOLToBool(::IsZoomed(aWnd)); - - #endif - - info.numPanels = g_App.NumPanels; - info.currentPanel = g_App.LastFocusedPanel; - info.splitterPos = g_Splitter.GetPos(); - - info.Save(); -} -#else -int Main1(int argc,TCHAR **argv) -{ - if (argc >= 2) - { - g_MainPath = argv[1]; - } - - if (!InitInstance (0)) - return FALSE; - - MyLoadMenu(); - - // FIXME : install Accelerators ? - - return 0; -} - -#endif - -/* FIXME static */ void ExecuteCommand(UINT commandID) -{ - CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]); - CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]); - - switch (commandID) - { - case kMenuCmdID_Toolbar_Add: g_App.AddToArchive(); break; - case kMenuCmdID_Toolbar_Extract: g_App.ExtractArchives(); break; - case kMenuCmdID_Toolbar_Test: g_App.TestArchives(); break; - } -} - -static void local_WM_CREATE(HWND hWnd) -{ -printf("**local_WM_CREATE**\n"); - - int xSizes[2] = { 0,0 }; - - // g_App.CreateDragTarget(); - bool archiveIsOpened; - bool encrypted; - bool needOpenFile = false; - if (!g_MainPath.IsEmpty() /* && g_OpenArchive */) - { - if (NFile::NFind::DoesFileExist(us2fs(g_MainPath))) - needOpenFile = true; - } - HRESULT res = g_App.Create(hWnd, g_MainPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted); - - if (res == E_ABORT) - { - return ; // -1; - } - if (needOpenFile && !archiveIsOpened || res != S_OK) - { - UString message = L"Error"; - if (res == S_FALSE || res == S_OK) - { - message = MyFormatNew(encrypted ? - IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : - IDS_CANT_OPEN_ARCHIVE, - g_MainPath); - } - else if (res != S_OK) - message = HResultToMessage(res); - ErrorMessage(message); - return ; // -1; - } - // g_SplitterPos = 0; - - // ::DragAcceptFiles(hWnd, TRUE); - // RegisterDragDrop(hWnd, g_App._dropTarget); -} - -#ifdef _WIN32 -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - int wmId, wmEvent; - switch (message) - { - case WM_COMMAND: - wmId = LOWORD(wParam); - wmEvent = HIWORD(wParam); - if ((HWND) lParam != NULL && wmEvent != 0) - break; - if (wmId >= kMenuCmdID_Toolbar_Start && wmId < kMenuCmdID_Toolbar_End) - { - ExecuteCommand(wmId); - return 0; - } - if (OnMenuCommand(hWnd, wmId)) - return 0; - break; - case WM_INITMENUPOPUP: - OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam)); - break; - - /* - It doesn't help - case WM_EXITMENULOOP: - { - OnMenuUnActivating(hWnd); - break; - } - case WM_UNINITMENUPOPUP: - OnMenuUnActivating(hWnd, HMENU(wParam), lParam); - break; - */ - - case WM_CREATE: - { - g_HWND = hWnd; - /* - INITCOMMONCONTROLSEX icex; - icex.dwSize = sizeof(INITCOMMONCONTROLSEX); - icex.dwICC = ICC_BAR_CLASSES; - InitCommonControlsEx(&icex); - - // Toolbar buttons used to create the first 4 buttons. - TBBUTTON tbb [ ] = - { - // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, - // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, - // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, - {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, - }; - - int baseID = 100; - NWindows::NControl::CToolBar aToolBar; - aToolBar.Attach(::CreateToolbarEx (hWnd, - WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT - baseID + 2, 11, - (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR, - (LPCTBBUTTON)&tbb, ARRAY_SIZE(tbb), - 0, 0, 100, 30, sizeof (TBBUTTON))); - */ - // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE); - // ::SetCursor(cursor); - - if (g_PanelsInfoDefined) - g_Splitter.SetPos(hWnd, g_SplitterPos); - else - { - g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); - g_SplitterPos = g_Splitter.GetPos(); - } - - RECT rect; - ::GetClientRect(hWnd, &rect); - int xSize = rect.right; - int xSizes[2]; - xSizes[0] = g_Splitter.GetPos(); - xSizes[1] = xSize - kSplitterWidth - xSizes[0]; - if (xSizes[1] < 0) - xSizes[1] = 0; - - g_App.CreateDragTarget(); - - bool archiveIsOpened; - bool encrypted; - bool needOpenFile = false; - - UString fullPath = g_MainPath; - if (!fullPath.IsEmpty() /* && g_OpenArchive */) - { - if (!NFile::NName::IsAbsolutePath(fullPath)) - { - FString fullPathF; - if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF)) - fullPath = fs2us(fullPathF); - } - if (NFile::NFind::DoesFileExist(us2fs(fullPath))) - needOpenFile = true; - } - - HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted); - - if (res == E_ABORT) - return -1; - - if (needOpenFile && !archiveIsOpened || res != S_OK) - { - UString message = L"Error"; - if (res == S_FALSE || res == S_OK) - { - message = MyFormatNew(encrypted ? - IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : - IDS_CANT_OPEN_ARCHIVE, - fullPath); - } - else if (res != S_OK) - message = HResultToMessage(res); - ErrorMessage(message); - return -1; - } - - // g_SplitterPos = 0; - - // ::DragAcceptFiles(hWnd, TRUE); - RegisterDragDrop(hWnd, g_App._dropTarget); - - break; - } - - case WM_DESTROY: - { - // ::DragAcceptFiles(hWnd, FALSE); - RevokeDragDrop(hWnd); - g_App._dropTarget.Release(); - - g_App.Save(); - g_App.Release(); - SaveWindowInfo(hWnd); - PostQuitMessage(0); - break; - } - /* - case WM_MOVE: - { - break; - } - */ - case WM_LBUTTONDOWN: - g_StartCaptureMousePos = LOWORD(lParam); - g_StartCaptureSplitterPos = g_Splitter.GetPos(); - ::SetCapture(hWnd); - break; - - case WM_LBUTTONUP: - { - ::ReleaseCapture(); - break; - } - - case WM_MOUSEMOVE: - { - if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd) - { - g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos + - (short)LOWORD(lParam) - g_StartCaptureMousePos); - g_App.MoveSubWindows(); - } - break; - } - - case WM_SIZE: - { - if (g_CanChangeSplitter) - g_Splitter.SetPosFromRatio(hWnd); - else - { - g_Splitter.SetPos(hWnd, g_SplitterPos ); - g_CanChangeSplitter = true; - } - - g_Maximized = (wParam == SIZE_MAXIMIZED) || (wParam == SIZE_MAXSHOW); - - g_App.MoveSubWindows(); - /* - int xSize = LOWORD(lParam); - int ySize = HIWORD(lParam); - // int xSplitter = 2; - int xWidth = g_SplitPos; - // int xSplitPos = xWidth; - g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize); - g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize); - */ - return 0; - break; - } - - case WM_SETFOCUS: - // g_App.SetFocus(g_App.LastFocusedPanel); - g_App.SetFocusToLastItem(); - break; - - /* - case WM_ACTIVATE: - { - int fActive = LOWORD(wParam); - switch (fActive) - { - case WA_INACTIVE: - { - // g_FocusIndex = g_App.LastFocusedPanel; - // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex(); - // return 0; - } - } - break; - } - */ - - /* - case kLangWasChangedMessage: - MyLoadMenu(); - return 0; - */ - - /* - case WM_SETTINGCHANGE: - break; - */ - - case WM_NOTIFY: - { - g_App.OnNotify((int)wParam, (LPNMHDR)lParam); - break; - } - - /* - case WM_DROPFILES: - { - g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam); - return 0 ; - } - */ - } - #ifndef _UNICODE - if (g_IsNT) - return DefWindowProcW(hWnd, message, wParam, lParam); - else - #endif - return DefWindowProc(hWnd, message, wParam, lParam); - -} - -static int Window_GetRealHeight(NWindows::CWindow &w) -{ - RECT rect; - w.GetWindowRect(&rect); - int res = RECT_SIZE_Y(rect); - #ifndef UNDER_CE - WINDOWPLACEMENT placement; - if (w.GetPlacement(&placement)) - res += placement.rcNormalPosition.top; - #endif - return res; -} - -void CApp::MoveSubWindows() -{ - HWND hWnd = _window; - RECT rect; - if (hWnd == 0) - return; - ::GetClientRect(hWnd, &rect); - int xSize = rect.right; - if (xSize == 0) - return; - int headerSize = 0; - #ifdef UNDER_CE - _commandBar.AutoSize(); - { - _commandBar.Show(true); // maybe we need it for - headerSize += _commandBar.Height(); - } - #endif - if (_toolBar) - { - _toolBar.AutoSize(); - #ifdef UNDER_CE - int h2 = Window_GetRealHeight(_toolBar); - _toolBar.Move(0, headerSize, xSize, h2); - #endif - headerSize += Window_GetRealHeight(_toolBar); - } - int ySize = MyMax((int)(rect.bottom - headerSize), 0); - - if (NumPanels > 1) - { - Panels[0].Move(0, headerSize, g_Splitter.GetPos(), ySize); - int xWidth1 = g_Splitter.GetPos() + kSplitterWidth; - Panels[1].Move(xWidth1, headerSize, xSize - xWidth1, ySize); - } - else - { - /* - int otherPanel = 1 - LastFocusedPanel; - if (PanelsCreated[otherPanel]) - Panels[otherPanel].Move(0, headerSize, 0, ySize); - */ - Panels[LastFocusedPanel].Move(0, headerSize, xSize, ySize); - } -} -#else -void main_WM_DESTROY() -{ - // // ::DragAcceptFiles(hWnd, FALSE); - // RevokeDragDrop(hWnd); - // g_App._dropTarget.Release(); - - g_App.Save(); - g_App.Release(); - // SaveWindowInfo(hWnd); - // PostQuitMessage(0); -} -#endif - - -// for mac -void doMacOpenFile( const UString & fileName ) -{ - g_App.GetFocusedPanel().BindToPathAndRefresh(fileName); -} - +// FM.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../../C/Compiler.h" +#include "../../../../C/Alloc.h" +#ifdef _WIN32 +#include "../../../../C/DllSecur.h" +#endif + +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/MemoryLock.h" +#include "../../../Windows/NtCheck.h" +#include "../../../Windows/System.h" + +#ifndef UNDER_CE +#include "../../../Windows/SecurityUtils.h" +#endif + +#include "../GUI/ExtractRes.h" + +#include "resource.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "MyLoadMenu.h" +#include "Panel.h" +#include "RegistryUtils.h" +#include "StringUtils.h" +#include "ViewSettings.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +// #define MAX_LOADSTRING 100 + +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + +extern +bool g_RAM_Size_Defined; +bool g_RAM_Size_Defined; + +extern +bool g_LargePagesMode; +bool g_LargePagesMode = false; +// static bool g_OpenArchive = false; + +static bool g_Maximized = false; + +extern +size_t g_RAM_Size; +size_t g_RAM_Size; + +#ifdef _WIN32 +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance; +#endif + +HWND g_HWND; + +static UString g_MainPath; +static UString g_ArcFormat; + +// HRESULT LoadGlobalCodecs(); +void FreeGlobalCodecs(); + +#ifndef UNDER_CE + +#ifdef Z7_USE_DYN_ComCtl32Version +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +DWORD g_ComCtl32Version; + +static DWORD GetDllVersion(LPCTSTR dllName) +{ + DWORD dwVersion = 0; + const HMODULE hmodule = LoadLibrary(dllName); + if (hmodule) + { + const + DLLGETVERSIONPROC f_DllGetVersion = Z7_GET_PROC_ADDRESS( + DLLGETVERSIONPROC, hmodule, + "DllGetVersion"); + if (f_DllGetVersion) + { + DLLVERSIONINFO dvi; + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + const HRESULT hr = f_DllGetVersion(&dvi); + if (SUCCEEDED(hr)) + dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + FreeLibrary(hmodule); + } + return dwVersion; +} + +#endif +#endif + +bool g_IsSmallScreen = false; + +extern +bool g_LVN_ITEMACTIVATE_Support; +bool g_LVN_ITEMACTIVATE_Support = true; +// LVN_ITEMACTIVATE replaces both NM_DBLCLK & NM_RETURN +// Windows 2000 +// NT/98 + IE 3 (g_ComCtl32Version >= 4.70) + + +static const int kNumDefaultPanels = 1; +static const int kSplitterWidth = 4; +static const int kSplitterRateMax = 1 << 16; +static const int kPanelSizeMin = 120; + + +class CSplitterPos +{ + int _ratio; // 10000 is max + int _pos; + int _fullWidth; + void SetRatioFromPos(HWND hWnd) + { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax / + MyMax(GetWidth(hWnd), 1); } +public: + int GetPos() const + { return _pos; } + int GetWidth(HWND hWnd) const + { + RECT rect; + ::GetClientRect(hWnd, &rect); + return rect.right; + } + void SetRatio(HWND hWnd, int aRatio) + { + _ratio = aRatio; + SetPosFromRatio(hWnd); + } + void SetPosPure(HWND hWnd, int pos) + { + int posMax = GetWidth(hWnd) - kSplitterWidth; + if (posMax < kPanelSizeMin * 2) + pos = posMax / 2; + else + { + if (pos > posMax - kPanelSizeMin) + pos = posMax - kPanelSizeMin; + else if (pos < kPanelSizeMin) + pos = kPanelSizeMin; + } + _pos = pos; + } + void SetPos(HWND hWnd, int pos) + { + _fullWidth = GetWidth(hWnd); + SetPosPure(hWnd, pos); + SetRatioFromPos(hWnd); + } + void SetPosFromRatio(HWND hWnd) + { + int fullWidth = GetWidth(hWnd); + if (_fullWidth != fullWidth && fullWidth != 0) + { + _fullWidth = fullWidth; + SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2); + } + } +}; + +static bool g_CanChangeSplitter = false; +static UInt32 g_SplitterPos = 0; +static CSplitterPos g_Splitter; +static bool g_PanelsInfoDefined = false; +static bool g_WindowWasCreated = false; + +static int g_StartCaptureMousePos; +static int g_StartCaptureSplitterPos; + +CApp g_App; + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +static const wchar_t * const kWindowClass = L"7-Zip::FM"; + +#ifdef UNDER_CE +#define WS_OVERLAPPEDWINDOW ( \ + WS_OVERLAPPED | \ + WS_CAPTION | \ + WS_SYSMENU | \ + WS_THICKFRAME | \ + WS_MINIMIZEBOX | \ + WS_MAXIMIZEBOX) +#endif + + +/* +typedef HRESULT (WINAPI *Func_SetWindowTheme)( + HWND hwnd, + LPCWSTR pszSubAppName, + LPCWSTR pszSubIdList +); + +typedef BOOL (WINAPI *Func_AllowDarkModeForWindow)( + HWND a_HWND, BOOL a_Allow); + +enum PreferredAppMode +{ + Default, + AllowDark, + ForceDark, + ForceLight, + Max +}; +// ordinal 135, in 1903 +typedef BOOL (WINAPI *Func_SetPreferredAppMode)(PreferredAppMode appMode); + +typedef HRESULT (WINAPI *Func_DwmSetWindowAttribute)( + HWND hwnd, + DWORD dwAttribute, + LPCVOID pvAttribute, + DWORD cbAttribute +); +*/ + +static BOOL InitInstance(int nCmdShow) +{ + CWindow wnd; + + // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING); + + UString title ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); + + /* + //If it is already running, then focus on the window + hWnd = FindWindow(windowClass, title); + if (hWnd) + { + SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01)); + return 0; + } + */ + + WNDCLASSW wc; + + // wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON)); + + // wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hCursor = ::LoadCursor(NULL, IDC_SIZEWE); + // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + + wc.lpszMenuName = + #ifdef UNDER_CE + 0 + #else + MAKEINTRESOURCEW(IDM_MENU) + #endif + ; + + wc.lpszClassName = kWindowClass; + + if (MyRegisterClass(&wc) == 0) + return FALSE; + + // RECT rect; + // GetClientRect(hWnd, &rect); + + DWORD style = WS_OVERLAPPEDWINDOW; + // DWORD style = 0; + + CWindowInfo info; + info.maximized = false; + int x, y, xSize, ySize; + x = y = xSize = ySize = CW_USEDEFAULT; + bool windowPosIsRead; + info.Read(windowPosIsRead, g_PanelsInfoDefined); + + if (windowPosIsRead) + { + x = info.rect.left; + y = info.rect.top; + + xSize = RECT_SIZE_X(info.rect); + ySize = RECT_SIZE_Y(info.rect); + } + + + if (g_PanelsInfoDefined) + { + g_SplitterPos = info.splitterPos; + if (info.numPanels < 1 || info.numPanels > 2) + info.numPanels = kNumDefaultPanels; + if (info.currentPanel >= 2) + info.currentPanel = 0; + } + else + { + info.numPanels = kNumDefaultPanels; + info.currentPanel = 0; + } + + g_App.NumPanels = info.numPanels; + g_App.LastFocusedPanel = info.currentPanel; + + if (!wnd.Create(kWindowClass, title, style, + x, y, xSize, ySize, NULL, NULL, g_hInstance, NULL)) + return FALSE; + + /* + // doesn't work + { + const HMODULE hmodule = LoadLibrary("UxTheme.dll"); + if (hmodule) + { + { + const + Func_AllowDarkModeForWindow f = Z7_GET_PROC_ADDRESS( + Func_AllowDarkModeForWindow, hmodule, + MAKEINTRESOURCEA(133)); + if (f) + { + BOOL res = f((HWND)wnd, TRUE); + res = res; + } + } + { + const + Func_SetPreferredAppMode f = Z7_GET_PROC_ADDRESS( + Func_SetPreferredAppMode, hmodule, + MAKEINTRESOURCEA(135)); + if (f) + { + f(ForceDark); + } + } + { + const + Func_SetWindowTheme f = Z7_GET_PROC_ADDRESS( + Func_SetWindowTheme, hmodule, + "SetWindowTheme"); + if (f) + { + // HRESULT hres = f((HWND)wnd, L"DarkMode_Explorer", NULL); + HRESULT hres = f((HWND)wnd, L"Explorer", NULL); + hres = hres; + } + } + FreeLibrary(hmodule); + } + } + { + const HMODULE hmodule = LoadLibrary("Dwmapi.dll"); + if (hmodule) + { + const + Func_DwmSetWindowAttribute f = Z7_GET_PROC_ADDRESS( + Func_DwmSetWindowAttribute, hmodule, + "DwmSetWindowAttribute"); + if (f) + { + #ifndef Z7_WIN_DWMWA_USE_IMMERSIVE_DARK_MODE + #define Z7_WIN_DWMWA_USE_IMMERSIVE_DARK_MODE 20 + #endif + BOOL value = TRUE; + f((HWND)wnd, Z7_WIN_DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); + } + FreeLibrary(hmodule); + } + } + */ + + if (nCmdShow == SW_SHOWNORMAL || + nCmdShow == SW_SHOW + #ifndef UNDER_CE + || nCmdShow == SW_SHOWDEFAULT + #endif + ) + { + if (info.maximized) + nCmdShow = SW_SHOWMAXIMIZED; + else + nCmdShow = SW_SHOWNORMAL; + } + + if (nCmdShow == SW_SHOWMAXIMIZED) + g_Maximized = true; + + #ifndef UNDER_CE + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (wnd.GetPlacement(&placement)) + { + if (windowPosIsRead) + placement.rcNormalPosition = info.rect; + placement.showCmd = (UINT)nCmdShow; + wnd.SetPlacement(&placement); + } + else + #endif + wnd.Show(nCmdShow); + + return TRUE; +} + +/* +static void GetCommands(const UString &aCommandLine, UString &aCommands) +{ + UString aProgramName; + aCommands.Empty(); + bool aQuoteMode = false; + for (int i = 0; i < aCommandLine.Length(); i++) + { + wchar_t aChar = aCommandLine[i]; + if (aChar == L'\"') + aQuoteMode = !aQuoteMode; + else if (aChar == L' ' && !aQuoteMode) + { + if (!aQuoteMode) + { + i++; + break; + } + } + else + aProgramName += aChar; + } + aCommands = aCommandLine.Ptr(i); +} +*/ + +#if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE) + +extern +bool g_Is_Wow64; +bool g_Is_Wow64; + +typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL); + +static void Set_Wow64() +{ + g_Is_Wow64 = false; + const + Func_IsWow64Process fn = Z7_GET_PROC_ADDRESS( + Func_IsWow64Process, GetModuleHandleA("kernel32.dll"), + "IsWow64Process"); + if (fn) + { + BOOL isWow; + if (fn(GetCurrentProcess(), &isWow)) + g_Is_Wow64 = (isWow != FALSE); + } +} + +#endif + +#if _MSC_VER > 1400 /* && _MSC_VER <= 1900 */ + // GetVersion was declared deprecated + #pragma warning(disable : 4996) +#endif +#ifdef __clang__ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +bool IsLargePageSupported(); +bool IsLargePageSupported() +{ + #ifdef _WIN64 + return true; + #else + + DWORD v = GetVersion(); + // low byte is major version: + // next byte is minor version: + v = ((v & 0xff) << 8) | ((v >> 8) & 0xFF); + return (v > 0x501); + // if ((Byte)v < 5) return false; + // if ((Byte)v > 5) return true; + // return ((Byte)(v >> 8) > 1); + /* large pages work in 5.1 (XP-32bit) if it's (g_Is_Wow64) mode; + but here we don't enable them in (XP-32bit). */ + #endif +} + +#ifndef UNDER_CE + +static void SetMemoryLock() +{ + if (!IsLargePageSupported()) + return; + // if (ReadLockMemoryAdd()) + NSecurity::AddLockMemoryPrivilege(); + + if (ReadLockMemoryEnable()) + if (NSecurity::Get_LargePages_RiskLevel() == 0) + { + // note: child processes can inherit that Privilege + g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory(); + } +} + +extern +bool g_SymLink_Supported; +bool g_SymLink_Supported = false; + +static void Set_SymLink_Supported() +{ + // g_SymLink_Supported = false; + const DWORD v = GetVersion(); + // low byte is major version: + if ((Byte)v < 6) + return; + g_SymLink_Supported = true; + // if (g_SymLink_Supported) + { + NSecurity::EnablePrivilege_SymLink(); + } +} + +#endif + +/* +static const int kNumSwitches = 1; + +namespace NKey { +enum Enum +{ + kOpenArachive = 0 +}; + +} + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"SOA", NSwitchType::kSimple, false }, + }; +*/ + +// int APIENTRY WinMain2(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */); + +static void ErrorMessage(const wchar_t *s) +{ + MessageBoxW(NULL, s, L"7-Zip", MB_ICONERROR); +} + +static void ErrorMessage(const char *s) +{ + ErrorMessage(GetUnicodeString(s)); +} + + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return 1; +#endif + +static int WINAPI WinMain2(int nCmdShow) +{ + g_RAM_Size_Defined = NSystem::GetRamSize(g_RAM_Size); + + #ifdef _WIN32 + + /* + #ifndef _WIN64 + #ifndef UNDER_CE + { + HMODULE hMod = GetModuleHandle("Kernel32.dll"); + if (hMod) + { + typedef BOOL (WINAPI *PSETDEP)(DWORD); + #define MY_PROCESS_DEP_ENABLE 1 + PSETDEP procSet = (PSETDEP)GetProcAddress(hMod,"SetProcessDEPPolicy"); + if (procSet) + procSet(MY_PROCESS_DEP_ENABLE); + + typedef BOOL (WINAPI *HSI)(HANDLE, HEAP_INFORMATION_CLASS ,PVOID, SIZE_T); + HSI hsi = (HSI)GetProcAddress(hMod, "HeapSetInformation"); + #define MY_HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)1) + if (hsi) + hsi(NULL, MY_HeapEnableTerminationOnCorruption, NULL, 0); + } + } + #endif + #endif + */ + + NT_CHECK + #ifdef Z7_LARGE_PAGES + SetLargePageSize(); + #endif + + #endif + + #ifdef Z7_LANG + LoadLangOneTime(); + #endif + + InitCommonControls(); + +#ifdef Z7_USE_DYN_ComCtl32Version + g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); +#endif + + #if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE) + Set_Wow64(); + #endif + + + g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200); + + // OleInitialize is required for drag and drop. + #ifndef UNDER_CE + OleInitialize(NULL); + #endif + // Maybe needs CoInitializeEx also ? + // NCOM::CComInitializer comInitializer; + + UString commandsString; + // MessageBoxW(NULL, GetCommandLineW(), L"", 0); + + #ifdef UNDER_CE + commandsString = GetCommandLineW(); + #else + UString programString; + SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString); + #endif + + commandsString.Trim(); + UString paramString, tailString; + SplitStringToTwoStrings(commandsString, paramString, tailString); + paramString.Trim(); + tailString.Trim(); + if (tailString.IsPrefixedBy("-t")) + g_ArcFormat = tailString.Ptr(2); + + /* + UStringVector switches; + for (;;) + { + if (tailString.IsEmpty()) + break; + UString s1, s2; + SplitStringToTwoStrings(tailString, s1, s2); + if (s2.IsEmpty()) + { + tailString.Trim(); + switches.Add(tailString); + break; + } + s1.Trim(); + switches.Add(s1); + tailString = s2; + } + + FOR_VECTOR(i, switches) + { + const UString &sw = switches[i]; + if (sw.IsPrefixedBy(L"-t")) + g_ArcFormat = sw.Ptr(2); + // + else if (sw.IsPrefixedBy(L"-stp")) + { + const wchar_t *end; + UInt32 val = ConvertStringToUInt32(sw.Ptr(4), &end); + if (*end != 0) + throw 111; + g_TypeParseLevel = val; + } + else + // + throw 112; + } + */ + + if (!paramString.IsEmpty()) + { + g_MainPath = paramString; + // return WinMain2(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + + // MessageBoxW(NULL, paramString, L"", 0); + } + /* + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + NCommandLineParser::CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + if (nonSwitchStrings.Size() > 1) + { + g_MainPath = nonSwitchStrings[1]; + // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs; + CFileInfoW fileInfo; + if (FindFile(g_MainPath, fileInfo)) + { + if (!fileInfo.IsDir()) + g_OpenArchive = true; + } + } + } + catch(...) { } + */ + + + #if defined(_WIN32) && !defined(UNDER_CE) + SetMemoryLock(); + Set_SymLink_Supported(); + #endif + + g_App.ReloadLangItems(); + + MSG msg; + if (!InitInstance (nCmdShow)) + return FALSE; + + // we will load Global_Codecs at first use instead. + /* + OutputDebugStringW(L"Before LoadGlobalCodecs"); + LoadGlobalCodecs(); + OutputDebugStringW(L"After LoadGlobalCodecs"); + */ + + #ifndef _UNICODE + if (g_IsNT) + { + HACCEL hAccels = LoadAcceleratorsW(g_hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1)); + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + } + else + #endif + { + HACCEL hAccels = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); + while (GetMessage(&msg, NULL, 0, 0)) + { + if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0) + { + // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg)) + // if (!IsDialogMessage(g_Hwnd, &msg)) + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + // Destructor of g_CodecsReleaser can release DLLs. + // But we suppose that it's better to release DLLs here (before destructor). + FreeGlobalCodecs(); + + g_HWND = NULL; + #ifndef UNDER_CE + OleUninitialize(); + #endif + return (int)msg.wParam; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + /* lpCmdLine */, int nCmdShow) +{ + g_hInstance = hInstance; + + try + { + try + { + #ifdef _WIN32 + My_SetDefaultDllDirectories(); + #endif + return WinMain2(nCmdShow); + } + catch (...) + { + g_ExitEventLauncher.Exit(true); + throw; + } + } + catch(const CNewException &) + { + ErrorMessage(LangString(IDS_MEM_ERROR)); + return 1; + } + catch(const UString &s) + { + ErrorMessage(s); + return 1; + } + catch(const AString &s) + { + ErrorMessage(s.Ptr()); + return 1; + } + catch(const wchar_t *s) + { + ErrorMessage(s); + return 1; + } + catch(const char *s) + { + ErrorMessage(s); + return 1; + } + catch(int v) + { + AString e ("Error: "); + e.Add_UInt32((unsigned)v); + ErrorMessage(e); + return 1; + } + catch(...) + { + ErrorMessage("Unknown error"); + return 1; + } +} + +static void SaveWindowInfo(HWND aWnd) +{ + CWindowInfo info; + + #ifdef UNDER_CE + + if (!::GetWindowRect(aWnd, &info.rect)) + return; + info.maximized = g_Maximized; + + #else + + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (!::GetWindowPlacement(aWnd, &placement)) + return; + info.rect = placement.rcNormalPosition; + info.maximized = BOOLToBool(::IsZoomed(aWnd)); + + #endif + + info.numPanels = g_App.NumPanels; + info.currentPanel = g_App.LastFocusedPanel; + info.splitterPos = (unsigned)g_Splitter.GetPos(); + + info.Save(); +} + +static void ExecuteCommand(UINT commandID) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]); + CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]); + + switch (commandID) + { + case kMenuCmdID_Toolbar_Add: g_App.AddToArchive(); break; + case kMenuCmdID_Toolbar_Extract: g_App.ExtractArchives(); break; + case kMenuCmdID_Toolbar_Test: g_App.TestArchives(); break; + } +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND: + { + unsigned wmId = LOWORD(wParam); + unsigned wmEvent = HIWORD(wParam); + if ((HWND) lParam != NULL && wmEvent != 0) + break; + if (wmId >= kMenuCmdID_Toolbar_Start && wmId < kMenuCmdID_Toolbar_End) + { + ExecuteCommand(wmId); + return 0; + } + if (OnMenuCommand(hWnd, wmId)) + return 0; + break; + } + case WM_INITMENUPOPUP: + OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam)); + break; + + /* + It doesn't help + case WM_EXITMENULOOP: + { + OnMenuUnActivating(hWnd); + break; + } + case WM_UNINITMENUPOPUP: + OnMenuUnActivating(hWnd, HMENU(wParam), lParam); + break; + */ + + case WM_CREATE: + { + g_HWND = hWnd; + /* + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + // Toolbar buttons used to create the first 4 buttons. + TBBUTTON tbb [ ] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + + int baseID = 100; + NWindows::NControl::CToolBar aToolBar; + aToolBar.Attach(::CreateToolbarEx (hWnd, + WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT + baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, Z7_ARRAY_SIZE(tbb), + 0, 0, 100, 30, sizeof (TBBUTTON))); + */ + // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE); + // ::SetCursor(cursor); + + if (g_PanelsInfoDefined) + g_Splitter.SetPos(hWnd, (int)g_SplitterPos); + else + { + g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); + g_SplitterPos = (unsigned)g_Splitter.GetPos(); + } + + RECT rect; + ::GetClientRect(hWnd, &rect); + const int xSize = rect.right; + int xSizes[2]; + xSizes[0] = g_Splitter.GetPos(); + xSizes[1] = xSize - kSplitterWidth - xSizes[0]; + if (xSizes[1] < 0) + xSizes[1] = 0; + + g_App.CreateDragTarget(); + + COpenResult openRes; + bool needOpenArc = false; + + UString fullPath = g_MainPath; + if (!fullPath.IsEmpty() /* && g_OpenArchive */) + { + if (!NFile::NName::IsAbsolutePath(fullPath)) + { + FString fullPathF; + if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF)) + fullPath = fs2us(fullPathF); + } + if (NFile::NFind::DoesFileExist_FollowLink(us2fs(fullPath))) + needOpenArc = true; + } + + HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes, + needOpenArc, + openRes); + + if (res == E_ABORT) + return -1; + + if ((needOpenArc && !openRes.ArchiveIsOpened) || res != S_OK) + { + UString m ("Error"); + if (res == S_FALSE || res == S_OK) + { + m = MyFormatNew(openRes.Encrypted ? + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : + IDS_CANT_OPEN_ARCHIVE, + fullPath); + } + else if (res != S_OK) + m = HResultToMessage(res); + if (!openRes.ErrorMessage.IsEmpty()) + { + m.Add_LF(); + m += openRes.ErrorMessage; + } + ErrorMessage(m); + return -1; + } + + g_WindowWasCreated = true; + + // g_SplitterPos = 0; + + // ::DragAcceptFiles(hWnd, TRUE); + RegisterDragDrop(hWnd, g_App._dropTarget); + + break; + } + + case WM_CLOSE: + { + // why do we use WA_INACTIVE here ? + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + g_ExitEventLauncher.Exit(false); + // ::DragAcceptFiles(hWnd, FALSE); + RevokeDragDrop(hWnd); + g_App._dropTarget.Release(); + + if (g_WindowWasCreated) + g_App.Save(); + + g_App.ReleaseApp(); + + if (g_WindowWasCreated) + SaveWindowInfo(hWnd); + + g_ExitEventLauncher.Exit(true); + // default DefWindowProc will call DestroyWindow / WM_DESTROY + break; + } + + case WM_DESTROY: + { + PostQuitMessage(0); + break; + } + + // case WM_MOVE: break; + + case WM_LBUTTONDOWN: + g_StartCaptureMousePos = LOWORD(lParam); + g_StartCaptureSplitterPos = g_Splitter.GetPos(); + ::SetCapture(hWnd); + break; + + case WM_LBUTTONUP: + { + ::ReleaseCapture(); + break; + } + + case WM_MOUSEMOVE: + { + if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd) + { + g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos + + (short)LOWORD(lParam) - g_StartCaptureMousePos); + g_App.MoveSubWindows(); + } + break; + } + + case WM_SIZE: + { + if (g_CanChangeSplitter) + g_Splitter.SetPosFromRatio(hWnd); + else + { + g_Splitter.SetPos(hWnd, (int)g_SplitterPos ); + g_CanChangeSplitter = true; + } + + g_Maximized = (wParam == SIZE_MAXIMIZED) || (wParam == SIZE_MAXSHOW); + + g_App.MoveSubWindows(); + /* + int xSize = LOWORD(lParam); + int ySize = HIWORD(lParam); + // int xSplitter = 2; + int xWidth = g_SplitPos; + // int xSplitPos = xWidth; + g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize); + g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize); + */ + return 0; + // break; + } + + case WM_SETFOCUS: + // g_App.SetFocus(g_App.LastFocusedPanel); + g_App.SetFocusToLastItem(); + break; + + /* + case WM_ACTIVATE: + { + int fActive = LOWORD(wParam); + switch (fActive) + { + case WA_INACTIVE: + { + // g_FocusIndex = g_App.LastFocusedPanel; + // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex(); + // return 0; + } + } + break; + } + */ + + /* + case kLangWasChangedMessage: + MyLoadMenu(); + return 0; + */ + + /* + case WM_SETTINGCHANGE: + break; + */ + + case WM_NOTIFY: + { + g_App.OnNotify((int)wParam, (LPNMHDR)lParam); + break; + } + + /* + case WM_DROPFILES: + { + g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam); + return 0 ; + } + */ + } + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(hWnd, message, wParam, lParam); + else + #endif + return DefWindowProc(hWnd, message, wParam, lParam); + +} + +static int Window_GetRealHeight(NWindows::CWindow &w) +{ + RECT rect; + w.GetWindowRect(&rect); + int res = RECT_SIZE_Y(rect); + #ifndef UNDER_CE + WINDOWPLACEMENT placement; + if (w.GetPlacement(&placement)) + res += placement.rcNormalPosition.top; + #endif + return res; +} + +void CApp::MoveSubWindows() +{ + HWND hWnd = _window; + RECT rect; + if (!hWnd) + return; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + if (xSize == 0) + return; + int headerSize = 0; + + #ifdef UNDER_CE + _commandBar.AutoSize(); + { + _commandBar.Show(true); // maybe we need it for + headerSize += _commandBar.Height(); + } + #endif + + if (_toolBar) + { + _toolBar.AutoSize(); + #ifdef UNDER_CE + int h2 = Window_GetRealHeight(_toolBar); + _toolBar.Move(0, headerSize, xSize, h2); + #endif + headerSize += Window_GetRealHeight(_toolBar); + } + + int ySize = MyMax((int)(rect.bottom - headerSize), 0); + + if (NumPanels > 1) + { + Panels[0].Move(0, headerSize, g_Splitter.GetPos(), ySize); + int xWidth1 = g_Splitter.GetPos() + kSplitterWidth; + Panels[1].Move(xWidth1, headerSize, xSize - xWidth1, ySize); + } + else + { + /* + int otherPanel = 1 - LastFocusedPanel; + if (PanelsCreated[otherPanel]) + Panels[otherPanel].Move(0, headerSize, 0, ySize); + */ + Panels[LastFocusedPanel].Move(0, headerSize, xSize, ySize); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsp 2024-03-28 08:00:00.000000000 +0000 @@ -0,0 +1,1699 @@ +# Microsoft Developer Studio Project File - Name="FM" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=FM - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "FM.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "FM.mak" CFG="FM - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "FM - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "FM - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /FAcs /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zFM.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "FM - Win32 Release" +# Name "FM - Win32 Debug" +# Name "FM - Win32 ReleaseU" +# Name "FM - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\add.bmp +# End Source File +# Begin Source File + +SOURCE=.\ClassDefs.cpp +# End Source File +# Begin Source File + +SOURCE=.\Copy.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract.bmp +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\Move.bmp +# End Source File +# Begin Source File + +SOURCE=.\MyWindowsNew.h +# End Source File +# Begin Source File + +SOURCE=.\Parent.bmp +# End Source File +# Begin Source File + +SOURCE=.\Properties.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# ADD BASE RSC /l 0x419 +# ADD RSC /l 0x409 +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Test.bmp +# End Source File +# End Group +# Begin Group "Folders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\AltStreamsFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\AltStreamsFolder.h +# End Source File +# Begin Source File + +SOURCE=.\FSDrives.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSDrives.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolderCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\IFolder.h +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.h +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.h +# End Source File +# End Group +# Begin Group "Registry" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\RegistryAssociations.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryAssociations.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.h +# End Source File +# End Group +# Begin Group "Panel" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\App.cpp +# End Source File +# Begin Source File + +SOURCE=.\App.h +# End Source File +# Begin Source File + +SOURCE=.\AppState.h +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.h +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.h +# End Source File +# Begin Source File + +SOURCE=.\Panel.cpp +# End Source File +# Begin Source File + +SOURCE=.\Panel.h +# End Source File +# Begin Source File + +SOURCE=.\PanelCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelCrc.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelDrag.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelFolderChange.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItemOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItems.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelKey.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelListNotify.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelOperations.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSelect.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSort.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSplitFile.cpp +# End Source File +# Begin Source File + +SOURCE=.\VerCtrl.cpp +# End Source File +# End Group +# Begin Group "Dialog" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\EditPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\EditPage.h +# End Source File +# Begin Source File + +SOURCE=.\FoldersPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\FoldersPage.h +# End Source File +# Begin Source File + +SOURCE=.\LangPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\LangPage.h +# End Source File +# Begin Source File + +SOURCE=.\MenuPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\MenuPage.h +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\SettingsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SettingsPage.h +# End Source File +# Begin Source File + +SOURCE=.\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SystemPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\AboutDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\AboutDialog.h +# End Source File +# Begin Source File + +SOURCE=.\BrowseDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\BrowseDialog.h +# End Source File +# Begin Source File + +SOURCE=.\BrowseDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=.\BrowseDialog2.h +# End Source File +# Begin Source File + +SOURCE=.\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=CopyDialog.cpp +# End Source File +# Begin Source File + +SOURCE=CopyDialog.h +# End Source File +# Begin Source File + +SOURCE=.\DialogSize.h +# End Source File +# Begin Source File + +SOURCE=.\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\EditDialog.h +# End Source File +# Begin Source File + +SOURCE=.\LinkDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\LinkDialog.h +# End Source File +# Begin Source File + +SOURCE=.\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ListViewDialog.h +# End Source File +# Begin Source File + +SOURCE=.\MemDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\MemDialog.h +# End Source File +# Begin Source File + +SOURCE=MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=MessagesDialog.h +# End Source File +# Begin Source File + +SOURCE=OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=.\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\PasswordDialog.h +# End Source File +# Begin Source File + +SOURCE=.\ProgressDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressDialog2.h +# End Source File +# Begin Source File + +SOURCE=.\SplitDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitDialog.h +# End Source File +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\CommandBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ImageList.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ReBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Static.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\StatusBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ToolBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\COM.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\NtCheck.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ProcessUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SecurityUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\AutoPtr.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common0.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyInitGuid.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Explorer\ContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\ContextMenu.h +# End Source File +# Begin Source File + +SOURCE=..\Explorer\ContextMenuFlags.h +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyExplorerCommand.h +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyMessages.h +# End Source File +# Begin Source File + +SOURCE=..\Explorer\RegistryContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\RegistryContextMenu.h +# End Source File +# End Group +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\GUI\HashGUI.cpp +# End Source File +# Begin Source File + +SOURCE=..\GUI\HashGUI.h +# End Source File +# Begin Source File + +SOURCE=..\GUI\UpdateCallbackGUI2.cpp +# End Source File +# Begin Source File + +SOURCE=..\GUI\UpdateCallbackGUI2.h +# End Source File +# End Group +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\PropID.h +# End Source File +# End Group +# Begin Group "ArchiveCommon" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zFM.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\Add2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Copy2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract2.bmp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.h +# End Source File +# Begin Source File + +SOURCE=.\FM.cpp +# End Source File +# Begin Source File + +SOURCE=.\Info.bmp +# End Source File +# Begin Source File + +SOURCE=.\Info2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Move2.bmp +# End Source File +# Begin Source File + +SOURCE=.\MyCom2.h +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.h +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=.\PluginInterface.h +# End Source File +# Begin Source File + +SOURCE=.\PluginLoader.h +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.h +# End Source File +# Begin Source File + +SOURCE=.\Test2.bmp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.cpp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.h +# End Source File +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsw --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.dsw 2002-07-20 18:14:30.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "FM"=.\FM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.mak --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM.mak 2024-03-28 11:00:00.000000000 +0000 @@ -0,0 +1,103 @@ +CFLAGS = $(CFLAGS) \ + -DZ7_LANG \ + +!IFDEF UNDER_CE +LIBS = $(LIBS) ceshell.lib Commctrl.lib +!ELSE +LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib Mpr.lib Gdi32.lib +CFLAGS = $(CFLAGS) -DZ7_DEVICE_FILE +# -DZ7_LONG_PATH +LFLAGS = $(LFLAGS) /DELAYLOAD:mpr.dll +LIBS = $(LIBS) delayimp.lib +!ENDIF + +FM_OBJS = \ + $O\App.obj \ + $O\BrowseDialog.obj \ + $O\BrowseDialog2.obj \ + $O\ClassDefs.obj \ + $O\EnumFormatEtc.obj \ + $O\ExtractCallback.obj \ + $O\FileFolderPluginOpen.obj \ + $O\FilePlugins.obj \ + $O\FM.obj \ + $O\FoldersPage.obj \ + $O\FormatUtils.obj \ + $O\FSFolder.obj \ + $O\FSFolderCopy.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\MemDialog.obj \ + $O\MenuPage.obj \ + $O\MyLoadMenu.obj \ + $O\OpenCallback.obj \ + $O\OptionsDialog.obj \ + $O\Panel.obj \ + $O\PanelCopy.obj \ + $O\PanelCrc.obj \ + $O\PanelDrag.obj \ + $O\PanelFolderChange.obj \ + $O\PanelItemOpen.obj \ + $O\PanelItems.obj \ + $O\PanelKey.obj \ + $O\PanelListNotify.obj \ + $O\PanelMenu.obj \ + $O\PanelOperations.obj \ + $O\PanelSelect.obj \ + $O\PanelSort.obj \ + $O\PanelSplitFile.obj \ + $O\ProgramLocation.obj \ + $O\PropertyName.obj \ + $O\RegistryAssociations.obj \ + $O\RegistryUtils.obj \ + $O\RootFolder.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\SysIconUtils.obj \ + $O\TextPairs.obj \ + $O\UpdateCallback100.obj \ + $O\ViewSettings.obj \ + $O\AboutDialog.obj \ + $O\ComboDialog.obj \ + $O\CopyDialog.obj \ + $O\EditDialog.obj \ + $O\EditPage.obj \ + $O\LangPage.obj \ + $O\ListViewDialog.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog2.obj \ + $O\SettingsPage.obj \ + $O\SplitDialog.obj \ + $O\SystemPage.obj \ + $O\VerCtrl.obj \ + +!IFNDEF UNDER_CE + +FM_OBJS = $(FM_OBJS) \ + $O\AltStreamsFolder.obj \ + $O\FSDrives.obj \ + $O\LinkDialog.obj \ + $O\NetFolder.obj \ + +WIN_OBJS = $(WIN_OBJS) \ + $O\FileSystem.obj \ + $O\Net.obj \ + $O\SecurityUtils.obj \ + +!ENDIF + +C_OBJS = $(C_OBJS) \ + $O\DllSecur.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\ArchiveFolder.obj \ + $O\ArchiveFolderOpen.obj \ + $O\ArchiveFolderOut.obj \ + $O\UpdateCallbackAgent.obj \ + +# we need empty line after last line above diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FM_rc.cpp 2015-09-19 18:25:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FM_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1170 +0,0 @@ -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -#include "wx/mimetype.h" -#include "wx/artprov.h" -#include "wx/imaglist.h" - -#undef _WIN32 - -#include "resource.h" - -#include "PropertyNameRes.h" - -#include "App.h" - -#include "Windows/Window.h" // FIXME -#include "Windows/Control/DialogImpl.h" -#include "Windows/Control/ListView.h" -#include "Windows/Control/Window2.h" - -#define static const -#include "../GUI/p7zip_32.xpm" -#undef static - -extern HWND g_HWND; - -#define BASE_ID_PANEL_1 (1000 + 100 * 0) -#define BASE_ID_PANEL_2 (1000 + 100 * 1) - -////////////////////////////////////// Tool bar images -#include "res/AddPNG.h" -#include "res/Add2PNG.h" -#include "res/ExtractPNG.h" -#include "res/Extract2PNG.h" -#include "res/TestPNG.h" -#include "res/Test2PNG.h" -#include "res/CopyPNG.h" -#include "res/Copy2PNG.h" -#include "res/MovePNG.h" -#include "res/Move2PNG.h" -#include "res/DeletePNG.h" -#include "res/Delete2PNG.h" -#include "res/InfoPNG.h" -#include "res/Info2PNG.h" - -#include "LangUtils.h" - -#include -#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name ## _png, sizeof(name ## _png)) - -static inline wxBitmap _wxGetBitmapFromMemory(const unsigned char *data, int length) { - wxMemoryInputStream is(data, length); - return wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1); -} - -///////////////////////////////////// SevenZipPanel.h ///////////////////// - -#include - -typedef wxListCtrl CExplorerListCtrl; - -class MyFrame; -class myToolBar; - -class SevenZipPanel : public wxPanel -{ - static int count; - - MyFrame *m_frame; - - CExplorerListCtrl *m_pListCtrlExplorer; - NWindows::NControl::CWindow2 *_wList; - - - wxBitmapButton *m_pBmpButtonParentFolder; - wxComboBox *m_pComboBoxPath; - wxStatusBar *m_pStatusBar; - - wxImageList imgList; - - int _panelIndex; - - // wxString m_currentDirectory; - - // int m_nbDirs; - - // wxString m_prompt; - -public: - SevenZipPanel(MyFrame *frame, wxWindow *parent,int id,int panelIndex); - - void registerWindow2(NWindows::NControl::CWindow2 *w) - { - _wList = w; - _wList->OnMessage(WM_CREATE,0,0); - } - - void OnAnyButton( wxCommandEvent &event ); - void OnSelected(wxListEvent& event); - void OnDeselected(wxListEvent& event); - void OnActivated(wxListEvent& event); - void OnFocused(wxListEvent& event); - void OnLeftDownBeginDrag(wxListEvent& event); - void OnRightClick(wxListEvent& event); - void OnColumnClick(wxListEvent& event); - - void OnLeftDown(wxMouseEvent &event ); - void OnRightDown(wxMouseEvent &event ); - - void OnTextEnter(wxCommandEvent& event); - - void WriteText(const wxString& text) { - printf("DEBUG : %ls",(const wchar_t *)text); - } - - /* Don't work ... - void OnCloseWindow(wxCloseEvent& WXUNUSED(event)) { - _wList->OnDestroy(); - } - */ - - void evt_destroy() { - _wList->OnDestroy(); - } - - -private: - DECLARE_EVENT_TABLE() -}; - - - -///////////////////////////////////// SevenZipPanel.h ///////////////////// - - - -class MyFrame: public wxFrame -{ -public: - // ctor - MyFrame(void (*fct)(HWND),wxFrame *frame, const wxString& title, int x, int y, int w, int h); - // virtual ~MyFrame(); - - void registerWindow2(int baseID,NWindows::NControl::CWindow2 *w) - { - printf("MyFrame::registerWindow2(%d,%p)\n",baseID,w); - switch (baseID) - { - case BASE_ID_PANEL_1: _panel1->registerWindow2(w); break; - case BASE_ID_PANEL_2: _panel2->registerWindow2(w); break; - default: printf("FIXME - MyFrame::registerWindow2\n"); - } - } - - void PopulateToolbar(wxToolBar* toolBar); - void RecreateToolbar(); - - -protected: - // callbacks - void OnWorkerEvent(wxCommandEvent& event); - void OnAnyMenu(wxCommandEvent& event) - { - extern bool OnMenuCommand(HWND hWnd, int id); - extern void ExecuteCommand(UINT commandID); - - int wmId = event.GetId(); - - if (wmId >= kMenuCmdID_Toolbar_Start && wmId < kMenuCmdID_Toolbar_End) - { - ExecuteCommand(wmId); - return ; // 0; - } - OnMenuCommand(this, wmId); - } - void OnCloseWindow(wxCloseEvent& WXUNUSED(event)) - { - if (_panel1) _panel1->evt_destroy(); - if (_panel2) _panel2->evt_destroy(); - - extern void main_WM_DESTROY(); - main_WM_DESTROY(); - Destroy(); - } -private: - SevenZipPanel * _panel1; - SevenZipPanel * _panel2; - myToolBar * m_toolBar; - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent) - EVT_MENU(wxID_ANY, MyFrame::OnAnyMenu) - EVT_CLOSE(MyFrame::OnCloseWindow) -END_EVENT_TABLE() - - -static bool TEST_create(HWND hWnd) // FIXME -{ -extern HWND g_HWND; - CMyListView _listView; - - int _baseID = 1000; - - HWND w = NWindows::GetDlgItem(g_HWND, _baseID + 1); - if (w == 0) - { - printf("Can't find id=%d\n",_baseID + 1); - return false; - } - printf("CPanel::OnCreate : _listView.Attach(%p)\n",w); - _listView.Attach(w); - - _listView.SetRedraw(false); - - _listView.DeleteAllItems(); - - _listView.DeleteColumn(1); - - _listView.InsertColumn(0, L"toto", 100); - -// _listView.SetItemCount(1); - - _listView.InsertItem(0, L"item 1"); - - - _listView.SetRedraw(true); - - return true; -} - -// My frame constructor -MyFrame::MyFrame(void (*wm_create)(HWND),wxFrame *frame, const wxString& title, - int x, int y, int w, int h) - : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)) -{ -printf("===MyFrame::MyFrame===BEGIN===\n"); - - m_toolBar = 0; - - this->SetIcon(wxICON(p7zip_32)); - - g_HWND = this; // FIXME - - SetMinSize(wxSize(800,700)); - - wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); - - _panel1 = new SevenZipPanel(this,this,BASE_ID_PANEL_1,0); // FIXME panelIndex = 0 - _panel2 = 0; - topsizer->Add( - _panel1, - 1, // make vertically stretchable - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - 0 ); // set border width to 10 - - // Create the toolbar - // FIXME RecreateToolbar(); -printf("===MyFrame::MyFrame===WM_CREATE===\n"); - wm_create(this); -// FIXME TEST_create(this); - - - // Create the toolbar // FIXME - RecreateToolbar(); - - -printf("===MyFrame::MyFrame===SIZER===\n"); - - SetSizer( topsizer ); // use the sizer for layout - - topsizer->SetSizeHints( this ); // set size hints to honour minimum size -printf("===MyFrame::MyFrame===END===\n"); -} - -void myCreateHandle(int n); -void MyFrame::OnWorkerEvent(wxCommandEvent& event) -{ - int n = event.GetInt(); -// printf(" MyFrame::OnWorkerEvent(n=%d)\n",n); - myCreateHandle(n); -} - -wxWindow * g_window=0; -HWND myCreateAndShowMainWindow(LPCTSTR title,void (*fct)(HWND)) -{ - MyFrame *frame = new MyFrame(fct,(wxFrame *)NULL, title, 40, 40, 800, 600); - - g_window = frame; - - // Don't Show the frame ! - frame->Show(true); // FIXME - - // FIXME : SetTopWindow(g_HWND); - - return frame; -} - - -class myToolBar -{ - wxToolBar * m_toolbar; - - bool m_bShowText; - -public: - myToolBar(wxToolBar * toolbar,bool bShowText ) : m_toolbar(toolbar), m_bShowText(bShowText) { } - - myToolBar* AddTool(int toolId, const wxString& label, const wxBitmap& bitmap1, const wxString& shortHelpString = _T(""), wxItemKind kind = wxITEM_NORMAL) - { - wxString text = wxEmptyString; - if (m_bShowText) text = label; - - wxSize tb_size = m_toolbar->GetToolBitmapSize(); - int tb_witdh = tb_size.GetWidth(); - int tb_height = tb_size.GetHeight(); - - if ((bitmap1.GetWidth() > tb_witdh) || ( bitmap1.GetHeight()> tb_height)) - { - wxBitmap bmp(bitmap1.ConvertToImage().Scale(tb_witdh, tb_height)); - m_toolbar->AddTool(toolId,text,bmp,shortHelpString,kind); - } - else - { - m_toolbar->AddTool(toolId,text,bitmap1,shortHelpString,kind); - } - - return this; - } - - void SetToolBitmapSize(const wxSize& size) - { - m_toolbar->SetToolBitmapSize(size); - } - - bool Realize() - { - return m_toolbar->Realize(); - } - - void AddSeparator() { m_toolbar->AddSeparator(); } -}; - -void MyFrame::PopulateToolbar(wxToolBar* p_toolBar) -{/* - toolBar->AddTool(wxID_NEW, _T("New"),toolBarBitmaps[Tool_new], wxNullBitmap, wxITEM_NORMAL, - _T("New file"), _T("This is help for new file tool")); - */ - m_toolBar = new myToolBar(p_toolBar,true); - - const int kWidth = 24; - const int kHeight = 24; - - - UString msg; - - // FIXME toolBar->SetToolBitmapSize(wxSize(24,24)); - m_toolBar->SetToolBitmapSize(wxSize(kWidth,kHeight)); - - msg = LangString(IDS_ADD); // kMenuCmdID_Toolbar_Add, IDB_ADD, IDB_ADD2, IDS_ADD }, - if (msg == L"") msg = L"Add"; - m_toolBar->AddTool(kMenuCmdID_Toolbar_Add, (const wchar_t *)msg, wxGetBitmapFromMemory(ADD2)); - - msg = LangString(IDS_EXTRACT); // { kMenuCmdID_Toolbar_Extract, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT }, - if (msg == L"") msg = L"Extract"; - m_toolBar->AddTool(kMenuCmdID_Toolbar_Extract,(const wchar_t *)msg, wxGetBitmapFromMemory(EXTRACT2)); - - msg = LangString(IDS_TEST); // { kMenuCmdID_Toolbar_Test, IDB_TEST, IDB_TEST2, IDS_TEST } - if (msg == L"") msg = L"Test"; - m_toolBar->AddTool(kMenuCmdID_Toolbar_Test,(const wchar_t *)msg, wxGetBitmapFromMemory(TEST2)); - - m_toolBar->AddSeparator(); - - msg = LangString(IDS_BUTTON_COPY); // { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY }, - if (msg == L"") msg = L"Copy"; - m_toolBar->AddTool(IDS_BUTTON_COPY, (const wchar_t *)msg, wxGetBitmapFromMemory(COPY2)); - - msg = LangString(IDS_BUTTON_MOVE); // { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE } - if (msg == L"") msg = L"Move"; - m_toolBar->AddTool(IDM_MOVE_TO, (const wchar_t *)msg, wxGetBitmapFromMemory(MOVE2)); - - msg = LangString(IDS_BUTTON_DELETE); // { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE } , - if (msg == L"") msg = L"Delete"; - m_toolBar->AddTool(IDM_DELETE, (const wchar_t *)msg, wxGetBitmapFromMemory(DELETE2)); - - msg = LangString(IDS_BUTTON_INFO); // { IDM_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO } - if (msg == L"") msg = L"Info"; - m_toolBar->AddTool(IDM_PROPERTIES, (const wchar_t *)msg, wxGetBitmapFromMemory(INFO2)); - -#if 0 - //////////////////////////////////////////////////////// - - /* FIXME - if (g_mimeDatabase) - { - toolBar.AddSeparator(); - - TryMime(&toolBar, _T("txt")); - TryMime(&toolBar, _T("rar")); - TryMime(&toolBar, _T("7z")); - } - - toolBar.AddSeparator(); - - wxIcon i_plus = wxArtProvider::GetIcon(wxART_ADD_BOOKMARK , wxART_TOOLBAR , wxSize(kWidth,kHeight)); - m_toolBar->AddTool(wxID_ANY, wxT("Add Bookmark"), i_plus); - - wxIcon i_go_up_dir = wxArtProvider::GetIcon(wxART_GO_DIR_UP , wxART_TOOLBAR , wxSize(kWidth,kHeight)); - m_toolBar->AddTool(wxID_ANY, wxT("Go up dir"), i_go_up_dir); - - wxIcon i_folder = wxArtProvider::GetIcon(wxART_FOLDER , wxART_TOOLBAR , wxSize(kWidth,kHeight)); - m_toolBar->AddTool(wxID_ANY, wxT("Folder"), i_folder); - - wxIcon i_missing_image = wxArtProvider::GetIcon(wxART_MISSING_IMAGE , wxART_TOOLBAR , wxSize(kWidth,kHeight)); - m_toolBar->AddTool(wxID_ANY, wxT("missing image"), i_missing_image); - */ - - /////////////////////////////////////////////////////// - -#endif - m_toolBar->Realize(); - - // toolBar->SetRows(!(toolBar->IsVertical()) ? m_rows : 10 / m_rows); -} -void MyFrame::RecreateToolbar() -{ - // delete and recreate the toolbar - wxToolBar *toolBar = GetToolBar(); - // long style = toolBar ? toolBar->GetWindowStyle() : TOOLBAR_STYLE; - - SetToolBar(NULL); - - delete toolBar; - /* - style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT); - switch( m_toolbarPosition ) - { - case TOOLBAR_LEFT:style |= wxTB_LEFT; break; - case TOOLBAR_TOP: style |= wxTB_TOP;break; - case TOOLBAR_RIGHT:style |= wxTB_RIGHT;break; - case TOOLBAR_BOTTOM:style |= wxTB_BOTTOM;break; - } - */ - long style = wxTB_FLAT | wxTB_NODIVIDER | wxTB_TEXT; // TOOLBAR_STYLE | wxTB_TOP; - /* - if ( m_showTooltips ) style &= ~wxTB_NO_TOOLTIPS; - else style |= wxTB_NO_TOOLTIPS; - - if ( style & wxTB_TEXT && !(style & wxTB_NOICONS) && m_horzText ) style |= wxTB_HORZ_LAYOUT; - */ - toolBar = CreateToolBar(style, wxID_ANY); - - PopulateToolbar(toolBar); -} - -void registerWindow2(int baseID,NWindows::NControl::CWindow2 *w) -{ - MyFrame * f = (MyFrame *) g_HWND; - f->registerWindow2(baseID,w); - -} - - -///////////////////////////////////////////////////////// -#include "LangUtils.h" - -static const UINT kOpenBookmarkMenuID = 730; // FIXME / duplicate -static const UINT kSetBookmarkMenuID = 740; - - -void rc_MyLoadMenu(HWND hWnd) -{ - wxFrame *hwnd = (wxFrame *)hWnd; - wxMenu *m; - wxMenu *m_file = m = new wxMenu; - { - m->Append(IDM_OPEN, _T("&Open")); // FIXME "&Open\tEnter" - don't use Enter to support combobox enter ... - m->Append(IDM_OPEN_INSIDE,_T("Open &Inside\tCtrl+PgDn")); - m->Append(IDM_OPEN_INSIDE_ONE,_T("Open Inside *")); - m->Append(IDM_OPEN_INSIDE_PARSER,_T("Open Inside #")); - m->Append(IDM_OPEN_OUTSIDE,_T("Open O&utside\tShift+Enter")); - m->Append(IDM_FILE_VIEW,_T("&View\tF3")); - m->Append(IDM_FILE_EDIT,_T("&Edit\tF4")); - m->AppendSeparator(); - m->Append(IDM_RENAME,_T("Rena&me\tF2")); - m->Append(IDM_COPY_TO,_T("&Copy To...\tF5")); - m->Append(IDM_MOVE_TO,_T("&Move To...\tF6")); - m->Append(IDM_DELETE,_T("&Delete\tDel")); - m->AppendSeparator(); - m->Append(IDM_SPLIT,_T("&Split file...")); - m->Append(IDM_COMBINE,_T("Com&bine files...")); - m->AppendSeparator(); - m->Append(IDM_PROPERTIES,_T("P&roperties\tAlt+Enter")); - m->Append(IDM_COMMENT,_T("Comme&nt\tCtrl+Z")); - - wxMenu * subMenuCRC = new wxMenu; - subMenuCRC->Append(IDM_CRC32 ,_T("CRC-32")); - subMenuCRC->Append(IDM_CRC64 ,_T("CRC-64")); - subMenuCRC->Append(IDM_SHA1 ,_T("SHA-1")); - subMenuCRC->Append(IDM_SHA256 ,_T("SHA-256")); - subMenuCRC->Append(IDM_HASH_ALL,_T("*")); - m->AppendSubMenu(subMenuCRC,_T("CRC")); - - m->Append(IDM_DIFF,_T("Di&ff")); - m->AppendSeparator(); - m->Append(IDM_CREATE_FOLDER,_T("Create Folder\tF7")); - m->Append(IDM_CREATE_FILE,_T("Create File\tCtrl+N")); - m->AppendSeparator(); - m->Append(IDEXIT,_T("E&xit\tAlt+F4")); - } - wxMenu *m_edit = m = new wxMenu; - { - // m->Append(IDM_EDIT_CUT, _T("Cu&t\tCtrl+X"))->Enable(true); // GRAYED - // m->Append(IDM_EDIT_COPY, _T("&Copy\tCtrl+C"))->Enable(true); // GRAYED - // m->Append(IDM_EDIT_PASTE, _T("&Paste\tCtrl+V"))->Enable(true); // GRAYED - // m->AppendSeparator(); - m->Append(IDM_SELECT_ALL, _T("Select &All\tShift+[Grey +]")); - m->Append(IDM_DESELECT_ALL, _T("Deselect All\tShift+[Grey -]")); - m->Append(IDM_INVERT_SELECTION, _T("&Invert Selection\tGrey *")); - m->Append(IDM_SELECT, _T("Select...\tGrey +")); - m->Append(IDM_DESELECT, _T("Deselect...\tGrey -")); -// FIXME m->Append(IDM_SELECT_BY_TYPE, _T("Select by Type\tAlt+[Grey+]")); -// FIXME m->Append(IDM_DESELECT_BY_TYPE, _T("Deselect by Type\tAlt+[Grey -]")); - } - wxMenu *m_view = m = new wxMenu; - { -/* - m->AppendRadioItem(IDM_VIEW_LARGE_ICONS, _T("Lar&ge Icons\tCtrl+1")); - m->AppendRadioItem(IDM_VIEW_SMALL_ICONS, _T("S&mall Icons\tCtrl+2")); - m->AppendRadioItem(IDM_VIEW_LIST, _T("&List\tCtrl+3")); - m->AppendRadioItem(IDM_VIEW_DETAILS, _T("&Details\tCtrl+4"))->Check(true); // CHECKED - m->AppendSeparator(); - m->Append(IDM_VIEW_ARANGE_BY_NAME, _T("Name\tCtrl+F3")); - m->Append(IDM_VIEW_ARANGE_BY_TYPE, _T("Type\tCtrl+F4")); - m->Append(IDM_VIEW_ARANGE_BY_DATE, _T("Date\tCtrl+F5")); - m->Append(IDM_VIEW_ARANGE_BY_SIZE, _T("Size\tCtrl+F6")); - m->Append(IDM_VIEW_ARANGE_NO_SORT, _T("Unsorted\tCtrl+F7")); - m->AppendSeparator(); - m->AppendCheckItem(IDM_VIEW_FLAT_VIEW, _T("Flat View")); - m->AppendCheckItem(IDM_VIEW_TWO_PANELS, _T("&2 Panels\tF9")); - - { - wxMenu* subMenu = new wxMenu; - subMenu->AppendCheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, _T("Archive Toolbar")); - subMenu->AppendCheckItem(IDM_VIEW_STANDARD_TOOLBAR, _T("Standard Toolbar")); - subMenu->AppendSeparator(); - subMenu->AppendCheckItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, _T("Large Buttons")); - subMenu->AppendCheckItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, _T("Show Buttons Text")); - m->Append(12112, _T("Toolbars"), subMenu); // FIXME ID ? - } - m->AppendSeparator(); -*/ - // NO "/" is used on Unix Path ... m->Append(IDM_OPEN_ROOT_FOLDER, _T("Open Root Folder\t" STRING_PATH_SEPARATOR)); - m->Append(IDM_OPEN_ROOT_FOLDER, _T("Open Root Folder\t" "\\")); - - m->Append(IDM_OPEN_PARENT_FOLDER, _T("Up One Level\tBackspace")); - m->Append(IDM_FOLDERS_HISTORY, _T("Folders History...\tAlt+F12")); - m->AppendSeparator(); - m->Append(IDM_VIEW_REFRESH, _T("&Refresh\tCtrl+R")); - } - wxMenu *m_favorites = m = new wxMenu; - { - { - wxMenu* subMenu = new wxMenu; - for (int i = 0; i < 10; i++) - { - UString s = LangString(IDS_BOOKMARK); - s += L" "; - wchar_t c = (wchar_t)(L'0' + i); - s += c; - s += L"\tAlt+Shift+"; - s += c; - subMenu->Append( kSetBookmarkMenuID + i, wxString(s)); - } - - m->Append(12111, _T("&Add folder to Favorites as"), subMenu); // FIXME ID ? - } - m->AppendSeparator(); - for (int i = 0; i < 10; i++) - { - UString s = g_App.AppState.FastFolders.GetString(i); - const int kMaxSize = 100; - const int kFirstPartSize = kMaxSize / 2; - if (s.Len() > kMaxSize) - { - s.Delete(kFirstPartSize, s.Len() - kMaxSize); - s.Insert(kFirstPartSize, L" ... "); - } - if (s.IsEmpty()) - s = L'-'; - s += L"\tAlt+"; - s += (wchar_t)(L'0' + i); - // menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s); - m->Append( kOpenBookmarkMenuID + i, wxString(s)); - } - - } - wxMenu *m_tools = m = new wxMenu; - { -// m->Append(IDM_OPTIONS, _T("&Options...")); - m->Append(IDM_BENCHMARK, _T("&Benchmark")); - } - wxMenu *m_help = m = new wxMenu; - { - m->Append(IDM_HELP_CONTENTS, _T("&Contents...\tF1")); - m->AppendSeparator(); - m->Append(IDM_ABOUT, _T("&About 7-Zip...")); - } - - wxMenuBar *menuBar = new wxMenuBar; - - menuBar->Append(m_file, _T("&File")); - menuBar->Append(m_edit, _T("&Edit")); - menuBar->Append(m_view, _T("&View")); - menuBar->Append(m_favorites, _T("F&avorites")); - menuBar->Append(m_tools, _T("&Tools")); - menuBar->Append(m_help, _T("&Help")); - hwnd->SetMenuBar(menuBar); -} - -////////////////////////////////////////////////////////////////// - - -static CStringTable g_stringTable[] = -{ - /* resource.rc */ - /***************/ - { IDS_BOOKMARK ,L"Bookmark" }, - - { IDS_OPTIONS ,L"Options" }, - - { IDS_N_SELECTED_ITEMS ,L"{0} object(s) selected" }, - - { IDS_FILE_EXIST ,L"File {0} is already exist" }, - { IDS_WANT_UPDATE_MODIFIED_FILE ,L"File '{0}' was modified.\nDo you want to update it in the archive?" }, - { IDS_CANNOT_UPDATE_FILE ,L"Can not update file\n'{0}'" }, - { IDS_CANNOT_START_EDITOR ,L"Cannot start editor." }, - { IDS_VIRUS ,L"The file looks like a virus (the file name contains long spaces in name)." }, - { IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER ,L"The operation cannot be called from a folder that has a long path." }, - { IDS_SELECT_ONE_FILE ,L"You must select one file" }, - { IDS_SELECT_FILES ,L"You must select one or more files" }, - { IDS_TOO_MANY_ITEMS ,L"Too many items" }, - - { IDS_COPY ,L"Copy" }, - { IDS_MOVE ,L"Move" }, - { IDS_COPY_TO ,L"Copy to:" }, - { IDS_MOVE_TO ,L"Move to:" }, - { IDS_COPYING ,L"Copying..." }, - { IDS_MOVING ,L"Moving..." }, - { IDS_RENAMING ,L"Renaming..." }, - - { IDS_OPERATION_IS_NOT_SUPPORTED ,L"Operation is not supported." }, - { IDS_ERROR_RENAMING ,L"Error Renaming File or Folder" }, - { IDS_CONFIRM_FILE_COPY ,L"Confirm File Copy" }, - { IDS_WANT_TO_COPY_FILES ,L"Are you sure you want to copy files to archive" }, - - { IDS_CONFIRM_FILE_DELETE ,L"Confirm File Delete" }, - { IDS_CONFIRM_FOLDER_DELETE ,L"Confirm Folder Delete" }, - { IDS_CONFIRM_ITEMS_DELETE ,L"Confirm Multiple File Delete" }, - { IDS_WANT_TO_DELETE_FILE ,L"Are you sure you want to delete '{0}'?" }, - { IDS_WANT_TO_DELETE_FOLDER ,L"Are you sure you want to delete the folder '{0}' and all its contents?" }, - { IDS_WANT_TO_DELETE_ITEMS ,L"Are you sure you want to delete these {0} items?" }, - { IDS_DELETING ,L"Deleting..." }, - { IDS_ERROR_DELETING ,L"Error Deleting File or Folder" }, - { IDS_ERROR_LONG_PATH_TO_RECYCLE ,L"The system cannot move a file with long path to the Recycle Bin" }, - - { IDS_CREATE_FOLDER ,L"Create Folder" }, - { IDS_CREATE_FILE ,L"Create File" }, - { IDS_CREATE_FOLDER_NAME ,L"Folder name:" }, - { IDS_CREATE_FILE_NAME ,L"File Name:" }, - { IDS_CREATE_FOLDER_DEFAULT_NAME ,L"New Folder" }, - { IDS_CREATE_FILE_DEFAULT_NAME ,L"New File" }, - { IDS_CREATE_FOLDER_ERROR ,L"Error Creating Folder" }, - { IDS_CREATE_FILE_ERROR ,L"Error Creating File" }, - - { IDS_COMMENT ,L"Comment" }, - { IDS_COMMENT2 ,L"&Comment:" }, - { IDS_SELECT ,L"Select" }, - { IDS_DESELECT ,L"Deselect" }, - { IDS_SELECT_MASK ,L"Mask:" }, - - { IDS_PROPERTIES ,L"Properties" }, - { IDS_FOLDERS_HISTORY ,L"Folders History" }, - - { IDS_COMPUTER ,L"Computer" }, - { IDS_NETWORK ,L"Network" }, - { IDS_DOCUMENTS ,L"Documents" }, - { IDS_SYSTEM ,L"System" }, - - { IDS_ADD ,L"Add" }, - { IDS_EXTRACT ,L"Extract" }, - { IDS_TEST ,L"Test" }, - { IDS_BUTTON_COPY ,L"Copy" }, - { IDS_BUTTON_MOVE ,L"Move" }, - { IDS_BUTTON_DELETE ,L"Delete" }, - { IDS_BUTTON_INFO ,L"Info" }, - - { IDS_SPLITTING ,L"Splitting..." }, - { IDS_SPLIT_CONFIRM_TITLE ,L"Confirm Splitting" }, - { IDS_SPLIT_CONFIRM_MESSAGE ,L"Are you sure you want to split file into {0} volumes?" }, - { IDS_SPLIT_VOL_MUST_BE_SMALLER ,L"Volume size must be smaller than size of original file" }, - - { IDS_COMBINE ,L"Combine Files" }, - { IDS_COMBINE_TO ,L"&Combine to:" }, - { IDS_COMBINING ,L"Combining..." }, - { IDS_COMBINE_SELECT_ONE_FILE ,L"Select only first part of split file" }, - { IDS_COMBINE_CANT_DETECT_SPLIT_FILE ,L"Can not detect file as split file" }, - { IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART ,L"Can not find more than one part of split file" }, - - - - /* PropertyName.rc */ - /*******************/ - { IDS_PROP_PATH ,L"Path" }, - { IDS_PROP_NAME ,L"Name" }, - { IDS_PROP_EXTENSION ,L"Extension" }, - { IDS_PROP_IS_FOLDER ,L"Folder" }, - { IDS_PROP_SIZE ,L"Size" }, - { IDS_PROP_PACKED_SIZE ,L"Packed Size" }, - { IDS_PROP_ATTRIBUTES ,L"Attributes" }, - { IDS_PROP_CTIME ,L"Created" }, - { IDS_PROP_ATIME ,L"Accessed" }, - { IDS_PROP_MTIME ,L"Modified" }, - { IDS_PROP_SOLID ,L"Solid" }, - { IDS_PROP_C0MMENTED ,L"Commented" }, - { IDS_PROP_ENCRYPTED ,L"Encrypted" }, - { IDS_PROP_SPLIT_BEFORE ,L"Split Before" }, - { IDS_PROP_SPLIT_AFTER ,L"Split After" }, - { IDS_PROP_DICTIONARY_SIZE ,L"Dictionary" }, - { IDS_PROP_CRC ,L"CRC" }, - { IDS_PROP_FILE_TYPE ,L"Type" }, - { IDS_PROP_ANTI ,L"Anti" }, - { IDS_PROP_METHOD ,L"Method" }, - { IDS_PROP_HOST_OS ,L"Host OS" }, - { IDS_PROP_FILE_SYSTEM ,L"File System" }, - { IDS_PROP_USER ,L"User" }, - { IDS_PROP_GROUP ,L"Group" }, - { IDS_PROP_BLOCK ,L"Block" }, - { IDS_PROP_COMMENT ,L"Comment" }, - { IDS_PROP_POSITION ,L"Position" }, - { IDS_PROP_PREFIX ,L"Path Prefix" }, - { IDS_PROP_FOLDERS ,L"Folders" }, - { IDS_PROP_FILES ,L"Files" }, - { IDS_PROP_VERSION ,L"Version" }, - { IDS_PROP_VOLUME ,L"Volume" }, - { IDS_PROP_IS_VOLUME ,L"Multivolume" }, - { IDS_PROP_OFFSET ,L"Offset" }, - { IDS_PROP_LINKS ,L"Links" }, - { IDS_PROP_NUM_BLOCKS ,L"Blocks" }, - { IDS_PROP_NUM_VOLUMES ,L"Volumes" }, - - { IDS_PROP_BIT64 ,L"64-bit" }, - { IDS_PROP_BIG_ENDIAN ,L"Big-endian" }, - { IDS_PROP_CPU ,L"CPU" }, - { IDS_PROP_PHY_SIZE ,L"Physical Size" }, - { IDS_PROP_HEADERS_SIZE ,L"Headers Size" }, - { IDS_PROP_CHECKSUM ,L"Checksum" }, - { IDS_PROP_CHARACTS ,L"Characteristics" }, - { IDS_PROP_VA ,L"Virtual Address" }, - { IDS_PROP_ID ,L"ID" }, - { IDS_PROP_SHORT_NAME ,L"Short Name" }, - { IDS_PROP_CREATOR_APP ,L"Creator Application" }, - { IDS_PROP_SECTOR_SIZE ,L"Sector Size" }, - { IDS_PROP_POSIX_ATTRIB ,L"Mode" }, - { IDS_PROP_SYM_LINK ,L"Symbolic Link" }, - { IDS_PROP_ERROR ,L"Error" }, - { IDS_PROP_TOTAL_SIZE ,L"Total Size" }, - { IDS_PROP_FREE_SPACE ,L"Free Space" }, - { IDS_PROP_CLUSTER_SIZE ,L"Cluster Size" }, - { IDS_PROP_VOLUME_NAME ,L"Label" }, - { IDS_PROP_LOCAL_NAME ,L"Local Name" }, - { IDS_PROP_PROVIDER ,L"Provider" }, - { IDS_PROP_NT_SECURITY ,L"NT Security" }, - { IDS_PROP_ALT_STREAM ,L"Alternate Stream" }, - { IDS_PROP_AUX ,L"Aux" }, - { IDS_PROP_DELETED ,L"Deleted" }, - { IDS_PROP_IS_TREE ,L"Is Tree" }, - { IDS_PROP_SHA1 ,L"SHA-1" }, - { IDS_PROP_SHA256 ,L"SHA-256" }, - { IDS_PROP_ERROR_TYPE ,L"Error Type" }, - { IDS_PROP_NUM_ERRORS ,L"Errors" }, - { IDS_PROP_ERROR_FLAGS ,L"Errors" }, - { IDS_PROP_WARNING_FLAGS ,L"Warnings" }, - { IDS_PROP_WARNING ,L"Warning" }, - { IDS_PROP_NUM_STREAMS ,L"Streams" }, - { IDS_PROP_NUM_ALT_STREAMS ,L"Alternate Streams" }, - { IDS_PROP_ALT_STREAMS_SIZE ,L"Alternate Streams Size" }, - { IDS_PROP_VIRTUAL_SIZE ,L"Virtual Size" }, - { IDS_PROP_UNPACK_SIZE ,L"Unpack Size" }, - { IDS_PROP_TOTAL_PHY_SIZE ,L"Total Physical Size" }, - { IDS_PROP_VOLUME_INDEX ,L"Volume Index" }, - { IDS_PROP_SUBTYPE ,L"SubType" }, - { IDS_PROP_SHORT_COMMENT ,L"Short Comment" }, - { IDS_PROP_CODE_PAGE ,L"Code Page" }, - { IDS_PROP_IS_NOT_ARC_TYPE ,L"Is not archive type" }, - { IDS_PROP_PHY_SIZE_CANT_BE_DETECTED ,L"Physical Size can't be detected" }, - { IDS_PROP_ZEROS_TAIL_IS_ALLOWED ,L"Zeros Tail Is Allowed" }, - { IDS_PROP_TAIL_SIZE ,L"Tail Size" }, - { IDS_PROP_EMB_STUB_SIZE ,L"Embedded Stub Size" }, - { IDS_PROP_NT_REPARSE ,L"Link" }, - { IDS_PROP_HARD_LINK ,L"Hard Link" }, - { IDS_PROP_INODE ,L"iNode" }, - { IDS_PROP_STREAM_ID ,L"Stream ID" }, - - { 0 , 0 } -}; - -REGISTER_STRINGTABLE(g_stringTable) - -///////////////////////////////////////////////////// - -#include "res/ParentFolder.h" - - SevenZipPanel::SevenZipPanel(MyFrame *frame, wxWindow *parent,int id,int panelIndex) : - wxPanel(parent,id) , m_frame(frame), _wList(0) - { - _panelIndex = panelIndex; - - int _baseID = id; // FIXME - int _listID = _baseID + 1; - int _comboBoxID = _baseID + 3; - int _statusBarID = _comboBoxID + 1; - int kParentFolderID = 100; // FIXME Panel.h - - - ///Sizer for adding the controls created by users - wxBoxSizer* pMainSizer = new wxBoxSizer(wxVERTICAL); - int sizes[] = {150, 250, 350, -1}; - wxArrayString pathArray; - wxBoxSizer *pPathSizer = new wxBoxSizer(wxHORIZONTAL); - m_pBmpButtonParentFolder = new wxBitmapButton(this, kParentFolderID, wxGetBitmapFromMemory(PARENT_FOLDER), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW); - m_pComboBoxPath = new wxComboBox(this, _comboBoxID, wxEmptyString, wxDefaultPosition, wxSize(300,-1), pathArray, wxCB_DROPDOWN | wxCB_SORT ); - pPathSizer->Add(m_pBmpButtonParentFolder, 0, wxALL|wxEXPAND, 0); - pPathSizer->Add(m_pComboBoxPath, 1, wxALL|wxEXPAND, 5); - - m_pListCtrlExplorer = new CExplorerListCtrl(this,_listID,wxDefaultPosition, wxSize(300,300), - wxLC_REPORT | // wxLC_EDIT_LABELS | FIXME - wxSUNKEN_BORDER); - - printf("DEBUG : new CExplorerListCtrl(id=%d) => %p\n",_listID,m_pListCtrlExplorer); - - m_pStatusBar = new wxStatusBar(this, _statusBarID); - m_pStatusBar->SetFieldsCount(4, sizes); - pMainSizer->Add(pPathSizer, 0, wxALL|wxEXPAND, 0); - pMainSizer->Add(m_pListCtrlExplorer, 1, wxALL|wxEXPAND, 0); - pMainSizer->Add(m_pStatusBar, 0, wxALL|wxEXPAND, 0); - SetSizer(pMainSizer); - SetAutoLayout (true); - SetMinSize(wxSize(800,400)); - Layout(); - - - // m_pListCtrlExplorer->SetDropTarget(new DnDFile(this)); - - } - - void SevenZipPanel::OnAnyButton( wxCommandEvent &event ) - { - count++; - - int id = event.GetId(); - - wxString msg = wxString::Format(_T("P %d : button %d \n"), count,id); - - WriteText(msg); - - _wList->OnMessage(WM_COMMAND , id , 0); - } - - void SevenZipPanel::OnSelected(wxListEvent& event) - { - const wxListItem & item = event.GetItem(); - count++; - - wxString msg = wxString::Format(_T("P %d : OnSelected %d \n"), count,event.GetId()); - - WriteText(msg); - - NMLISTVIEW info; - info.hdr.hwndFrom = m_pListCtrlExplorer; - info.hdr.code = LVN_ITEMCHANGED; - info.uOldState = 0; - info.uNewState = LVIS_SELECTED; - info.lParam = item.GetData(); // event.GetIndex(); // FIXME ? event.GetData(); - _wList->OnMessage(WM_NOTIFY , event.GetId() , (LPARAM)&info); - /* - if ( GetWindowStyle() & wxLC_REPORT ) - { - wxListItem info; - info.m_itemId = event.m_itemIndex; - info.m_col = 1; - info.m_mask = wxLIST_MASK_TEXT; - if ( GetItem(info) ) - { - wxLogMessage(wxT("Value of the 2nd field of the selected item: %s"), - info.m_text.c_str()); - } - else - { - wxFAIL_MSG(wxT("wxListCtrl::GetItem() failed")); - } - } - */ - } - - - - void SevenZipPanel::OnDeselected(wxListEvent& event) - { - const wxListItem & item = event.GetItem(); - count++; - wxString msg = wxString::Format(_T("P %d : OnDeselected %d \n"), count,event.GetId()); - WriteText(msg); - - NMLISTVIEW info; - info.hdr.hwndFrom = m_pListCtrlExplorer; - info.hdr.code = LVN_ITEMCHANGED; - info.uOldState = LVIS_SELECTED; - info.uNewState = 0; - info.lParam = item.GetData(); // event.GetIndex(); // FIXME ? event.GetData(); - _wList->OnMessage(WM_NOTIFY , event.GetId() , (LPARAM)&info); - } - - void SevenZipPanel::OnColumnClick(wxListEvent& event) - { - count++; - wxString msg = wxString::Format(_T("P %d : OnColumnClick %d col=%d\n"), count,event.GetId(),event.GetColumn()); - WriteText(msg); - - NMLISTVIEW info; - info.hdr.hwndFrom = m_pListCtrlExplorer; - info.hdr.code = LVN_COLUMNCLICK; - info.iSubItem = event.GetColumn(); - _wList->OnMessage(WM_NOTIFY , event.GetId() , (LPARAM)&info); - - } - - - void SevenZipPanel::OnActivated(wxListEvent& event) - { - count++; - - int ind = event.GetIndex(); - - NMHDR info; - info.hwndFrom = m_pListCtrlExplorer; - info.code = NM_DBLCLK; - _wList->OnMessage(WM_NOTIFY , event.GetId() , (LPARAM)&info); - - /* - if ((ind >= 0) && ( ind < m_nbDirs)) - { - wxString msg = wxString::Format(_T("P %d : OnActivated %d : DIR = %d\n"), count,event.GetId(),ind); - WriteText(msg); - - wxString name = m_pListCtrlExplorer->GetItemText(ind); - - wxFileName filename (m_currentDirectory,name); - BinPath(filename.GetFullPath()); - - } - else - */ - { - wxString msg = wxString::Format(_T("P %d : OnActivated %d : FILE = %d\n"), count,event.GetId(),ind); - WriteText(msg); - } - } - - void SevenZipPanel::OnFocused(wxListEvent& event) - { - count++; - - wxString msg = wxString::Format(_T("P %d : OnFocused %d \n"), count,event.GetId()); - - WriteText(msg); - - event.Skip(); - } - - void SevenZipPanel::OnLeftDownBeginDrag(wxListEvent& event) - { - count++; - - wxString msg = wxString::Format(_T("P %d : OnLeftDownBeginDrag %d \n"), count,event.GetId()); - WriteText(msg); - -#if 0 - if ( m_pListCtrlExplorer->GetSelectedItemCount() < 1) return ; - - // start drag operation - wxFileDataObject filesData; - - - long item = -1; - for ( ;; ) - { - item = m_pListCtrlExplorer->GetNextItem(item, - wxLIST_NEXT_ALL, - wxLIST_STATE_SELECTED); - if ( item == -1 ) - break; - - // this item is selected - do whatever is needed with it - // wxLogMessage("Item %ld is selected.", item); - wxString file = m_currentDirectory + _T("/") + m_pListCtrlExplorer->GetItemText(item); - - filesData.AddFile(file); - - } - - msg = wxString::Format(_T("P %d : wxDropSource %d \n"), count,event.GetId()); - WriteText(msg); - - wxDropSource source(filesData, this, - wxDROP_ICON(dnd_copy), - wxDROP_ICON(dnd_move), - wxDROP_ICON(dnd_none)); - - int flags = 0; - /* - if ( m_moveByDefault ) - flags |= wxDrag_DefaultMove; - else if ( m_moveAllow ) - flags |= wxDrag_AllowMove; - */ - flags |= wxDrag_AllowMove; - - msg = wxString::Format(_T("P %d : DoDragDrop %d \n"), count,event.GetId()); - WriteText(msg); - - - wxDragResult result = source.DoDragDrop(flags); - - - const wxChar *pc; - switch ( result ) - { - case wxDragError: pc = _T("Error!"); break; - case wxDragNone: pc = _T("Nothing"); break; - case wxDragCopy: pc = _T("Copied"); break; - case wxDragMove: pc = _T("Moved"); break; - case wxDragCancel: pc = _T("Cancelled"); break; - default: pc = _T("Huh?"); break; - } - - WriteText(wxString(_T(" Drag result: ")) + pc); -#endif - } - -void SevenZipPanel::OnLeftDown(wxMouseEvent &WXUNUSED(event) ) -{ - WriteText(_T("OnLeftDown")); -#if 0 - if ( !m_strText.empty() ) - { - // start drag operation - wxTextDataObject textData(m_strText); - wxDropSource source(textData, this, - wxDROP_ICON(dnd_copy), - wxDROP_ICON(dnd_move), - wxDROP_ICON(dnd_none)); - - int flags = 0; - if ( m_moveByDefault ) - flags |= wxDrag_DefaultMove; - else if ( m_moveAllow ) - flags |= wxDrag_AllowMove; - - wxDragResult result = source.DoDragDrop(flags); - -#if wxUSE_STATUSBAR - const wxChar *pc; - switch ( result ) - { - case wxDragError: pc = _T("Error!"); break; - case wxDragNone: pc = _T("Nothing"); break; - case wxDragCopy: pc = _T("Copied"); break; - case wxDragMove: pc = _T("Moved"); break; - case wxDragCancel: pc = _T("Cancelled"); break; - default: pc = _T("Huh?"); break; - } - - SetStatusText(wxString(_T("Drag result: ")) + pc); -#else - wxUnusedVar(result); -#endif // wxUSE_STATUSBAR - } -#endif // wxUSE_DRAG_AND_DROP -} - -void SevenZipPanel::OnRightClick(wxListEvent& event) -{ - wxPoint point = event.GetPoint(); - - WriteText(_T("OnRightClick")); - wxMenu menu; // (_T("Dnd sample menu")); - - menu.Append(wxID_ANY, _T("&Test drag...")); - menu.AppendSeparator(); - menu.Append(wxID_ANY, _T("item1")); - menu.Append(wxID_ANY, _T("item2")); - menu.Append(wxID_ANY, _T("item3")); - menu.Append(wxID_ANY, _T("&About")); - - PopupMenu( &menu, point.x, point.y ); -} - -void SevenZipPanel::OnTextEnter(wxCommandEvent& event) -{ - count++; - - NMCBEENDEDITW info; - info.hdr.hwndFrom = m_pComboBoxPath; - info.hdr.code = CBEN_ENDEDITW; - info.iWhy = CBENF_RETURN; - - _wList->OnMessage(WM_NOTIFY , event.GetId() , (LPARAM)&info); - - { - wxString msg = wxString::Format(_T("P %d : OnTextEnter %d\n"), count,event.GetId()); - WriteText(msg); - } -} - -int SevenZipPanel::count = 0; - -BEGIN_EVENT_TABLE(SevenZipPanel, wxPanel) -// EVT_MENU(wxID_ANY, SevenZipPanel::OnAnyMenu) -// EVT_LISTBOX (wxID_ANY, MyPanel::OnListBox) -// EVT_LISTBOX_DCLICK(wxID_ANY, MyPanel::OnAnyListBoxDoubleClick) -EVT_BUTTON (wxID_ANY, SevenZipPanel::OnAnyButton) - - // EVT_CLOSE(SevenZipPanel::OnCloseWindow) - -///////////////// -EVT_LIST_ITEM_SELECTED(wxID_ANY, SevenZipPanel::OnSelected) -EVT_LIST_ITEM_DESELECTED(wxID_ANY, SevenZipPanel::OnDeselected) -EVT_LIST_ITEM_ACTIVATED(wxID_ANY, SevenZipPanel::OnActivated) -EVT_LIST_ITEM_FOCUSED(wxID_ANY, SevenZipPanel::OnFocused) - -EVT_LIST_BEGIN_DRAG(wxID_ANY, SevenZipPanel::OnLeftDownBeginDrag) -// FIXME - add for menu on item - EVT_LIST_ITEM_RIGHT_CLICK(wxID_ANY, SevenZipPanel::OnRightClick) - -EVT_LIST_COL_CLICK(wxID_ANY, SevenZipPanel::OnColumnClick) - - -EVT_TEXT_ENTER(wxID_ANY, SevenZipPanel::OnTextEnter) // FIXME - not called - - -END_EVENT_TABLE() - - - -void appClose(void) -{ - g_window->Close(true); -} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSDrives.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSDrives.cpp 2015-10-03 17:46:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.cpp 2024-07-09 09:00:00.000000000 +0000 @@ -1,524 +1,512 @@ -// FSDrives.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/Defs.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileIO.h" -#include "../../../Windows/FileName.h" -// #include "../../../Windows/FileSystem.h" -#include "../../../Windows/PropVariant.h" - -#include "../../PropID.h" - -#include "FSDrives.h" -#include "FSFolder.h" -#include "LangUtils.h" -#include "SysIconUtils.h" - -#include "resource.h" - -using namespace NWindows; -using namespace NFile; -using namespace NFind; - -static const CFSTR kVolPrefix = FTEXT("\\\\.\\"); -static const CFSTR kSuperPrefix = FTEXT("\\\\?\\"); - -FString CDriveInfo::GetDeviceFileIoName() const -{ - return kVolPrefix + Name; -} - -struct CPhysTempBuffer -{ - void *buffer; - CPhysTempBuffer(): buffer(0) {} - ~CPhysTempBuffer() { MidFree(buffer); } -}; - -static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt64 fileSize, - UInt32 bufferSize, UInt64 progressStart, IProgress *progress) -{ - NIO::CInFile inFile; - if (!inFile.Open(fromPath)) - return GetLastError(); - if (fileSize == (UInt64)(Int64)-1) - { - if (!inFile.GetLength(fileSize)) - ::GetLastError(); - } - - NIO::COutFile outFile; - if (writeToDisk) - { - if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0)) - return GetLastError(); - } - else - if (!outFile.Create(toPath, true)) - return GetLastError(); - - CPhysTempBuffer tempBuffer; - tempBuffer.buffer = MidAlloc(bufferSize); - if (!tempBuffer.buffer) - return E_OUTOFMEMORY; - - for (UInt64 pos = 0; pos < fileSize;) - { - UInt64 progressCur = progressStart + pos; - RINOK(progress->SetCompleted(&progressCur)); - UInt64 rem = fileSize - pos; - UInt32 curSize = (UInt32)MyMin(rem, (UInt64)bufferSize); - UInt32 processedSize; - if (!inFile.Read(tempBuffer.buffer, curSize, processedSize)) - return GetLastError(); - if (processedSize == 0) - break; - curSize = processedSize; - if (writeToDisk) - { - const UInt32 kMask = 0x1FF; - curSize = (curSize + kMask) & ~kMask; - if (curSize > bufferSize) - return E_FAIL; - } - - if (!outFile.Write(tempBuffer.buffer, curSize, processedSize)) - return GetLastError(); - if (curSize != processedSize) - return E_FAIL; - pos += curSize; - } - - return S_OK; -} - -static const Byte kProps[] = -{ - kpidName, - // kpidOutName, - kpidTotalSize, - kpidFreeSpace, - kpidType, - kpidVolumeName, - kpidFileSystem, - kpidClusterSize -}; - -static const char * const kDriveTypes[] = -{ - "Unknown" - , "No Root Dir" - , "Removable" - , "Fixed" - , "Remote" - , "CD-ROM" - , "RAM disk" -}; - -STDMETHODIMP CFSDrives::LoadItems() -{ - _drives.Clear(); -#ifdef _WIN32 - FStringVector driveStrings; - MyGetLogicalDriveStrings(driveStrings); - - FOR_VECTOR (i, driveStrings) - { - CDriveInfo di; - - const FString &driveName = driveStrings[i]; - - di.FullSystemName = driveName; - if (!driveName.IsEmpty()) - di.Name.SetFrom(driveName, driveName.Len() - 1); - di.ClusterSize = 0; - di.DriveSize = 0; - di.FreeSpace = 0; - di.DriveType = NSystem::MyGetDriveType(driveName); - bool needRead = true; - - if (di.DriveType == DRIVE_CDROM || di.DriveType == DRIVE_REMOVABLE) - { - /* - DWORD dwSerialNumber;` - if (!::GetVolumeInformation(di.FullSystemName, - NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0)) - */ - { - needRead = false; - } - } - - if (needRead) - { - DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; - NSystem::MyGetVolumeInformation(driveName, - di.VolumeName, - &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, - di.FileSystemName); - - NSystem::MyGetDiskFreeSpace(driveName, - di.ClusterSize, di.DriveSize, di.FreeSpace); - di.KnownSizes = true; - di.KnownSize = true; - } - - _drives.Add(di); - } - - if (_volumeMode) - { - // we must use IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS - for (unsigned n = 0; n < 16; n++) // why 16 ? - { - FChar temp[16]; - ConvertUInt32ToString(n, temp); - FString name = FTEXT("PhysicalDrive"); - name += temp; - FString fullPath = kVolPrefix; - fullPath += name; - - CFileInfo fi; - if (!fi.Find(fullPath)) - continue; - - CDriveInfo di; - di.Name = name; - di.FullSystemName = fullPath; - di.ClusterSize = 0; - di.DriveSize = fi.Size; - di.FreeSpace = 0; - di.DriveType = 0; - - di.IsPhysicalDrive = true; - di.KnownSize = true; - - _drives.Add(di); - } - } -#else - CDriveInfo di; - // Root - di.FullSystemName = L"/"; - di.VolumeName = L"/"; - di.FileSystemName = L"img"; - di.Name = L"/"; // di.FullSystemName.Left(di.FullSystemName.Length() - 1); - di.ClusterSize = 0; - di.DriveSize = 0; - di.FreeSpace = 0; - di.DriveType = 0; // FIXME NFile::NSystem::MyGetDriveType(driveName); - di.KnownSizes = false; - _drives.Add(di); - - // Home Directory - const char * home = getenv("HOME"); - if (home) { - UString ustr = GetUnicodeString(home); - di.FullSystemName = ustr + L"/"; - di.VolumeName = ustr; - di.FileSystemName = L"img"; - di.Name = ustr; - _drives.Add(di); - } -#endif - - return S_OK; -} - -STDMETHODIMP CFSDrives::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _drives.Size(); - return S_OK; -} - -STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) -{ - if (itemIndex >= (UInt32)_drives.Size()) - return E_INVALIDARG; - NCOM::CPropVariant prop; - const CDriveInfo &di = _drives[itemIndex]; - switch (propID) - { - case kpidIsDir: prop = !_volumeMode; break; - case kpidName: prop = di.Name; break; - case kpidOutName: - if (!di.Name.IsEmpty() && di.Name.Back() == ':') - { - FString s = di.Name; - s.DeleteBack(); - AddExt(s, itemIndex); - prop = s; - } - break; - - case kpidTotalSize: if (di.KnownSize) prop = di.DriveSize; break; - case kpidFreeSpace: if (di.KnownSizes) prop = di.FreeSpace; break; - case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break; - case kpidType: - if (di.DriveType < ARRAY_SIZE(kDriveTypes)) - prop = kDriveTypes[di.DriveType]; - break; - case kpidVolumeName: prop = di.VolumeName; break; - case kpidFileSystem: prop = di.FileSystemName; break; - } - prop.Detach(value); - return S_OK; -} - -HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder) -{ - *resultFolder = 0; - if (_volumeMode) - return S_OK; - NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; - CMyComPtr subFolder = fsFolderSpec; - FString path; - if (_superMode) - path = kSuperPrefix; - path += name; - RINOK(fsFolderSpec->Init(path)); - *resultFolder = subFolder.Detach(); - return S_OK; -} - -STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder) -{ - *resultFolder = 0; - if (index >= (UInt32)_drives.Size()) - return E_INVALIDARG; - const CDriveInfo &di = _drives[index]; - /* - if (_volumeMode) - { - *resultFolder = 0; - CPhysDriveFolder *folderSpec = new CPhysDriveFolder; - CMyComPtr subFolder = folderSpec; - RINOK(folderSpec->Init(di.Name)); - *resultFolder = subFolder.Detach(); - return S_OK; - } - */ - return BindToFolderSpec(di.FullSystemName, resultFolder); -} - -STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) -{ - return BindToFolderSpec(us2fs(name), resultFolder); -} - -STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder) -{ - *resultFolder = 0; - return S_OK; -} - -IMP_IFolderFolder_Props(CFSDrives) - -STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch (propID) - { - case kpidType: prop = "FSDrives"; break; - case kpidPath: - if (_volumeMode) - prop = kVolPrefix; - else if (_superMode) - prop = kSuperPrefix; - else - prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR; - break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - - -STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex) -{ - *iconIndex = 0; - const CDriveInfo &di = _drives[index]; - if (di.IsPhysicalDrive) - return S_OK; - int iconIndexTemp; - if (GetRealIconIndex(di.FullSystemName, 0, iconIndexTemp) != 0) - { - *iconIndex = iconIndexTemp; - return S_OK; - } - return GetLastError(); -} - -void CFSDrives::AddExt(FString &s, unsigned index) const -{ - s += FTEXT('.'); - const CDriveInfo &di = _drives[index]; - const char *ext; -#ifdef _WIN32 - if (di.DriveType == DRIVE_CDROM) - ext = "iso"; - else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("NTFS")) - ext = "ntfs"; - else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("FAT")) - ext = "fat"; - else -#endif - ext = "img"; - s.AddAscii(ext); -} - -HRESULT CFSDrives::GetFileSize(unsigned index, UInt64 &fileSize) const -{ -#ifdef _WIN32 - NIO::CInFile inFile; - if (!inFile.Open(_drives[index].GetDeviceFileIoName())) - return GetLastError(); - if (!inFile.SizeDefined) - return E_FAIL; - fileSize = inFile.Size; -#else - fileSize = 0; -#endif - return S_OK; -} - -STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, - Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, - const wchar_t *path, IFolderOperationsExtractCallback *callback) -{ - if (numItems == 0) - return S_OK; - - if (moveMode) - return E_NOTIMPL; - - if (!_volumeMode) - return E_NOTIMPL; - - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - const CDriveInfo &di = _drives[indices[i]]; - if (di.KnownSize) - totalSize += di.DriveSize; - } - RINOK(callback->SetTotal(totalSize)); - RINOK(callback->SetNumFiles(numItems)); - - FString destPath = us2fs(path); - if (destPath.IsEmpty()) - return E_INVALIDARG; - - bool isAltDest = false; // FIXME NName::IsAltPathPrefix(destPath); - bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); - - if (isDirectPath) - { - if (numItems > 1) - return E_INVALIDARG; - } - - UInt64 completedSize = 0; - RINOK(callback->SetCompleted(&completedSize)); - - for (i = 0; i < numItems; i++) - { - unsigned index = indices[i]; - const CDriveInfo &di = _drives[index]; - FString destPath2 = destPath; - - if (!isDirectPath) - { - FString destName = di.Name; - if (!destName.IsEmpty() && destName.Back() == ':') - { - destName.DeleteBack(); - AddExt(destName, index); - } - destPath2 += destName; - } - - FString srcPath = di.GetDeviceFileIoName(); - - UInt64 fileSize = 0; - if (GetFileSize(index, fileSize) != S_OK) - { - return E_FAIL; - } - if (!di.KnownSize) - { - totalSize += fileSize; - RINOK(callback->SetTotal(totalSize)); - } - - Int32 writeAskResult; - CMyComBSTR destPathResult; - RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize, - fs2us(destPath2), &destPathResult, &writeAskResult)); - - if (!IntToBool(writeAskResult)) - { - if (totalSize >= fileSize) - totalSize -= fileSize; - RINOK(callback->SetTotal(totalSize)); - continue; - } - - RINOK(callback->SetCurrentFilePath(fs2us(srcPath))); - - static const UInt32 kBufferSize = (4 << 20); - UInt32 bufferSize = /* FIXME (di.DriveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : */ kBufferSize; - RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback)); - completedSize += fileSize; - } - - return S_OK; -} - -STDMETHODIMP CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, - const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CFSDrives::SetProperty(UInt32 /* index */, PROPID /* propID */, - const PROPVARIANT * /* value */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} +// FSDrives.cpp + +#include "StdAfx.h" + +#include "../../../../C/Alloc.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/Defs.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileSystem.h" +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#include "FSDrives.h" +#include "FSFolder.h" +#include "LangUtils.h" +#include "SysIconUtils.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +static const char * const kVolPrefix = "\\\\.\\"; +static const char * const kSuperPrefix = "\\\\?\\"; + +FString CDriveInfo::GetDeviceFileIoName() const +{ + FString f (kVolPrefix); + f += Name; + return f; +} + +struct CPhysTempBuffer +{ + void *buffer; + CPhysTempBuffer(): buffer(NULL) {} + ~CPhysTempBuffer() { MidFree(buffer); } +}; + +static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, + bool writeToDisk, UInt64 fileSize, + UInt32 bufferSize, UInt64 progressStart, IProgress *progress) +{ + NIO::CInFile inFile; + if (!inFile.Open(fromPath)) + return GetLastError_noZero_HRESULT(); + if (fileSize == (UInt64)(Int64)-1) + { + if (!inFile.GetLength(fileSize)) + return GetLastError_noZero_HRESULT(); + } + + NIO::COutFile outFile; + if (writeToDisk) + { + if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0)) + return GetLastError_noZero_HRESULT(); + } + else + if (!outFile.Create_ALWAYS(toPath)) + return GetLastError_noZero_HRESULT(); + + CPhysTempBuffer tempBuffer; + tempBuffer.buffer = MidAlloc(bufferSize); + if (!tempBuffer.buffer) + return E_OUTOFMEMORY; + + for (UInt64 pos = 0; pos < fileSize;) + { + { + const UInt64 progressCur = progressStart + pos; + RINOK(progress->SetCompleted(&progressCur)) + } + const UInt64 rem = fileSize - pos; + UInt32 curSize = (UInt32)MyMin(rem, (UInt64)bufferSize); + UInt32 processedSize; + if (!inFile.Read(tempBuffer.buffer, curSize, processedSize)) + return GetLastError_noZero_HRESULT(); + if (processedSize == 0) + break; + curSize = processedSize; + if (writeToDisk) + { + const UInt32 kMask = 0x1FF; + curSize = (curSize + kMask) & ~kMask; + if (curSize > bufferSize) + return E_FAIL; + } + if (!outFile.Write(tempBuffer.buffer, curSize, processedSize)) + return GetLastError_noZero_HRESULT(); + if (curSize != processedSize) + return E_FAIL; + pos += curSize; + } + + return S_OK; +} + +static const Byte kProps[] = +{ + kpidName, + // kpidOutName, + kpidTotalSize, + kpidFreeSpace, + kpidType, + kpidVolumeName, + kpidFileSystem, + kpidClusterSize +}; + +static const char * const kDriveTypes[] = +{ + "Unknown" + , "No Root Dir" + , "Removable" + , "Fixed" + , "Remote" + , "CD-ROM" + , "RAM disk" +}; + +Z7_COM7F_IMF(CFSDrives::LoadItems()) +{ + _drives.Clear(); + + FStringVector driveStrings; + MyGetLogicalDriveStrings(driveStrings); + + FOR_VECTOR (i, driveStrings) + { + CDriveInfo di; + const FString &driveName = driveStrings[i]; + di.FullSystemName = driveName; + if (!driveName.IsEmpty()) + di.Name.SetFrom(driveName, driveName.Len() - 1); + di.ClusterSize = 0; + di.DriveSize = 0; + di.FreeSpace = 0; + di.DriveType = NSystem::MyGetDriveType(driveName); + bool needRead = true; + + if (di.DriveType == DRIVE_CDROM || di.DriveType == DRIVE_REMOVABLE) + { + /* + DWORD dwSerialNumber;` + if (!::GetVolumeInformation(di.FullSystemName, + NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0)) + */ + { + needRead = false; + } + } + + if (needRead) + { + DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; + NSystem::MyGetVolumeInformation(driveName, + di.VolumeName, + &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, + di.FileSystemName); + + NSystem::MyGetDiskFreeSpace(driveName, + di.ClusterSize, di.DriveSize, di.FreeSpace); + di.KnownSizes = true; + di.KnownSize = true; + } + + _drives.Add(di); + } + + if (_volumeMode) + { + // we must use IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS + for (unsigned n = 0; n < 16; n++) // why 16 ? + { + FString name ("PhysicalDrive"); + name.Add_UInt32(n); + FString fullPath (kVolPrefix); + fullPath += name; + CFileInfo fi; + if (!fi.Find(fullPath)) + continue; + + CDriveInfo di; + di.Name = name; + // if (_volumeMode == true) we use CDriveInfo::FullSystemName only in GetSystemIconIndex(). + // And we need name without "\\\\.\\" prefix in GetSystemIconIndex(). + // So we don't set di.FullSystemName = fullPath; + di.FullSystemName = name; + di.ClusterSize = 0; + di.DriveSize = fi.Size; + di.FreeSpace = 0; + di.DriveType = 0; + di.IsPhysicalDrive = true; + di.KnownSize = true; + _drives.Add(di); + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CFSDrives::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _drives.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)) +{ + if (itemIndex >= _drives.Size()) + return E_INVALIDARG; + NCOM::CPropVariant prop; + const CDriveInfo &di = _drives[itemIndex]; + switch (propID) + { + case kpidIsDir: prop = !_volumeMode; break; + case kpidName: prop = fs2us(di.Name); break; + case kpidOutName: + if (!di.Name.IsEmpty() && di.Name.Back() == ':') + { + FString s = di.Name; + s.DeleteBack(); + AddExt(s, itemIndex); + prop = fs2us(s); + } + break; + + case kpidTotalSize: if (di.KnownSize) prop = di.DriveSize; break; + case kpidFreeSpace: if (di.KnownSizes) prop = di.FreeSpace; break; + case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break; + case kpidType: + if (di.DriveType < Z7_ARRAY_SIZE(kDriveTypes)) + prop = kDriveTypes[di.DriveType]; + break; + case kpidVolumeName: prop = di.VolumeName; break; + case kpidFileSystem: prop = di.FileSystemName; break; + } + prop.Detach(value); + return S_OK; +} + +HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder) +{ + *resultFolder = NULL; + if (_volumeMode) + return S_OK; + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + FString path; + if (_superMode) + path = kSuperPrefix; + path += name; + RINOK(fsFolderSpec->Init(path)) + *resultFolder = subFolder.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + if (index >= _drives.Size()) + return E_INVALIDARG; + const CDriveInfo &di = _drives[index]; + /* + if (_volumeMode) + { + *resultFolder = 0; + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(di.Name)); + *resultFolder = subFolder.Detach(); + return S_OK; + } + */ + return BindToFolderSpec(di.FullSystemName, resultFolder); +} + +Z7_COM7F_IMF(CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) +{ + return BindToFolderSpec(us2fs(name), resultFolder); +} + +Z7_COM7F_IMF(CFSDrives::BindToParentFolder(IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + return S_OK; +} + +IMP_IFolderFolder_Props(CFSDrives) + +Z7_COM7F_IMF(CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + switch (propID) + { + case kpidType: prop = "FSDrives"; break; + case kpidPath: + if (_volumeMode) + prop = kVolPrefix; + else if (_superMode) + prop = kSuperPrefix; + else + prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR; + break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +Z7_COM7F_IMF(CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +{ + *iconIndex = -1; + const CDriveInfo &di = _drives[index]; + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + di.FullSystemName, + _volumeMode ? + FILE_ATTRIBUTE_ARCHIVE: + FILE_ATTRIBUTE_DIRECTORY, + iconIndex); +} + +void CFSDrives::AddExt(FString &s, unsigned index) const +{ + s.Add_Dot(); + const CDriveInfo &di = _drives[index]; + UString n = di.FileSystemName; + n.MakeLower_Ascii(); + const char *ext; + if (di.DriveType == DRIVE_CDROM) + ext = "iso"; + else + { + unsigned i; + for (i = 0; i < n.Len(); i++) + { + const wchar_t c = n[i]; + if (c < 'a' || c > 'z') + break; + } + if (i != 0) + { + n.DeleteFrom(i); + s += us2fs(n); + return; + } + ext = "img"; + } + /* + if (n.IsPrefixedBy_Ascii_NoCase("NTFS")) ext = "ntfs"; + else if (n.IsPrefixedBy_Ascii_NoCase("UDF")) ext = "udf"; + else if (n.IsPrefixedBy_Ascii_NoCase("exFAT")) ext = "exfat"; + */ + s += ext; +} + +HRESULT CFSDrives::GetFileSize(unsigned index, UInt64& fileSize) const +{ +#ifdef Z7_DEVICE_FILE + NIO::CInFile inFile; + if (!inFile.Open(_drives[index].GetDeviceFileIoName())) + return GetLastError_noZero_HRESULT(); + if (inFile.SizeDefined) + { + fileSize = inFile.Size; + return S_OK; + } +#else + UNUSED_VAR(index) +#endif + fileSize = 0; + return E_FAIL; +} + +Z7_COM7F_IMF(CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, + Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, + const wchar_t *path, IFolderOperationsExtractCallback *callback)) +{ + if (numItems == 0) + return S_OK; + if (moveMode) + return E_NOTIMPL; + if (!_volumeMode) + return E_NOTIMPL; + + UInt64 totalSize = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + const CDriveInfo &di = _drives[indices[i]]; + if (di.KnownSize) + totalSize += di.DriveSize; + } + RINOK(callback->SetTotal(totalSize)) + RINOK(callback->SetNumFiles(numItems)) + + const FString destPath = us2fs(path); + if (destPath.IsEmpty()) + return E_INVALIDARG; + + const bool isAltDest = NName::IsAltPathPrefix(destPath); + const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); + + if (isDirectPath) + { + if (numItems > 1) + return E_INVALIDARG; + } + + UInt64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)) + for (i = 0; i < numItems; i++) + { + const unsigned index = indices[i]; + const CDriveInfo &di = _drives[index]; + FString destPath2 = destPath; + + if (!isDirectPath) + { + FString destName = di.Name; + if (!destName.IsEmpty() && destName.Back() == ':') + { + destName.DeleteBack(); + AddExt(destName, index); + } + destPath2 += destName; + } + + const FString srcPath = di.GetDeviceFileIoName(); + + UInt64 fileSize = 0; + if (GetFileSize(index, fileSize) != S_OK) + { + return E_FAIL; + } + if (!di.KnownSize) + { + totalSize += fileSize; + RINOK(callback->SetTotal(totalSize)) + } + + Int32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize, + fs2us(destPath2), &destPathResult, &writeAskResult)) + + if (!IntToBool(writeAskResult)) + { + if (totalSize >= fileSize) + totalSize -= fileSize; + RINOK(callback->SetTotal(totalSize)) + continue; + } + + RINOK(callback->SetCurrentFilePath(fs2us(srcPath))) + + const UInt32 kBufferSize = (4 << 20); + const UInt32 bufferSize = (di.DriveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : kBufferSize; + RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback)) + completedSize += fileSize; + } + + return S_OK; +} + +Z7_COM7F_IMF(CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, + const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::CreateFile(const wchar_t * /* name */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSDrives::SetProperty(UInt32 /* index */, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSDrives.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSDrives.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSDrives.h 2023-04-01 11:00:00.000000000 +0000 @@ -1,59 +1,52 @@ -// FSDrives.h - -#ifndef __FS_DRIVES_H -#define __FS_DRIVES_H - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyString.h" - -#include "IFolder.h" - -struct CDriveInfo -{ - FString Name; - FString FullSystemName; - UInt64 DriveSize; - UInt64 FreeSpace; - UInt64 ClusterSize; - // UString Type; - UString VolumeName; - UString FileSystemName; - UINT DriveType; - - bool KnownSize; - bool KnownSizes; - bool IsPhysicalDrive; - - FString GetDeviceFileIoName() const; - CDriveInfo(): KnownSize(false), KnownSizes(false), IsPhysicalDrive(false) {} -}; - -class CFSDrives: - public IFolderFolder, - public IFolderOperations, - public IFolderGetSystemIconIndex, - public CMyUnknownImp -{ - CObjectVector _drives; - bool _volumeMode; - bool _superMode; - - HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder); - void AddExt(FString &s, unsigned index) const; - HRESULT GetFileSize(unsigned index, UInt64 &fileSize) const; -public: - MY_UNKNOWN_IMP2(IFolderGetSystemIconIndex, IFolderOperations) - - INTERFACE_FolderFolder(;) - INTERFACE_FolderOperations(;) - - STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex); - - void Init(bool volMode = false, bool superMode = false) - { - _volumeMode = volMode; - _superMode = superMode; - } -}; - -#endif +// FSDrives.h + +#ifndef ZIP7_INC_FS_DRIVES_H +#define ZIP7_INC_FS_DRIVES_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyString.h" + +#include "IFolder.h" + +struct CDriveInfo +{ + FString Name; + FString FullSystemName; + UInt64 DriveSize; + UInt64 FreeSpace; + UInt64 ClusterSize; + // UString Type; + UString VolumeName; + UString FileSystemName; + UINT DriveType; + + bool KnownSize; + bool KnownSizes; + bool IsPhysicalDrive; + + FString GetDeviceFileIoName() const; + CDriveInfo(): KnownSize(false), KnownSizes(false), IsPhysicalDrive(false) {} +}; + +Z7_CLASS_IMP_NOQIB_3( + CFSDrives + , IFolderFolder + , IFolderOperations + , IFolderGetSystemIconIndex +) + CObjectVector _drives; + bool _volumeMode; + bool _superMode; + + HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder); + void AddExt(FString &s, unsigned index) const; + HRESULT GetFileSize(unsigned index, UInt64 &fileSize) const; +public: + void Init(bool volMode = false, bool superMode = false) + { + _volumeMode = volMode; + _superMode = superMode; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolder.cpp 2015-06-22 20:24:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.cpp 2024-07-09 09:00:00.000000000 +0000 @@ -1,1110 +1,1197 @@ -// FSFolder.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/Defs.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/UTFConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileIO.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" - -#include "../../PropID.h" - -#include "FSDrives.h" -#include "FSFolder.h" - -#if 0 // #ifndef UNDER_CE -#include "NetFolder.h" -#endif - -#include "SysIconUtils.h" - -#if _WIN32_WINNT < 0x0501 -#ifdef _APISETFILE_ -// Windows SDK 8.1 defines in fileapi.h the function GetCompressedFileSizeW only if _WIN32_WINNT >= 0x0501 -// But real support version for that function is NT 3.1 (probably) -// So we must define GetCompressedFileSizeW -EXTERN_C_BEGIN -WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh); -EXTERN_C_END -#endif -#endif - -using namespace NWindows; -using namespace NFile; -using namespace NFind; -using namespace NDir; -using namespace NName; - -#ifndef USE_UNICODE_FSTRING -int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2) -{ - return CompareFileNames_ForFolderList(fs2us(s1), fs2us(s2)); -} -#endif - -namespace NFsFolder { - -static const Byte kProps[] = -{ - kpidName, - kpidSize, - kpidMTime, - kpidCTime, - kpidATime, - kpidAttrib, - kpidPackSize, - #ifdef FS_SHOW_LINKS_INFO - kpidINode, - kpidLinks, - #endif - kpidComment, - kpidNumSubDirs, - kpidNumSubFiles, - kpidPrefix -}; - -HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */) -{ - // _parentFolder = parentFolder; - _path = path; - -#ifdef _WIN32 - _findChangeNotification.FindFirst(_path, false, - FILE_NOTIFY_CHANGE_FILE_NAME - | FILE_NOTIFY_CHANGE_DIR_NAME - | FILE_NOTIFY_CHANGE_ATTRIBUTES - | FILE_NOTIFY_CHANGE_SIZE - | FILE_NOTIFY_CHANGE_LAST_WRITE - /* - | FILE_NOTIFY_CHANGE_LAST_ACCESS - | FILE_NOTIFY_CHANGE_CREATION - | FILE_NOTIFY_CHANGE_SECURITY - */ - ); - if (!_findChangeNotification.IsHandleAllocated()) - { - DWORD lastError = GetLastError(); - CFindFile findFile; - CFileInfo fi; - if (!findFile.FindFirst(_path + FCHAR_ANY_MASK, fi)) - return lastError; - } -#endif - return S_OK; -} - -HRESULT CFsFolderStat::Enumerate() -{ - if (Progress) - { - RINOK(Progress->SetCompleted(NULL)); - } - Path.Add_PathSepar(); - unsigned len = Path.Len(); - Path += FCHAR_ANY_MASK; - CEnumerator enumerator(Path); - CFileInfo fi; - while (enumerator.Next(fi)) - { - if (fi.IsDir()) - { - Path.DeleteFrom(len); - Path += fi.Name; - RINOK(Enumerate()); - NumFolders++; - } - else - { - NumFiles++; - Size += fi.Size; - } - } - return S_OK; -} - -#if 0 // FIXME #ifndef UNDER_CE - -bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size) -{ - DWORD highPart; - DWORD lowPart = INVALID_FILE_SIZE; - IF_USE_MAIN_PATH - { - lowPart = ::GetCompressedFileSizeW(fs2us(path), &highPart); - if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) - { - size = ((UInt64)highPart << 32) | lowPart; - return true; - } - } - #ifdef WIN_LONG_PATH - if (USE_SUPER_PATH) - { - UString superPath; - if (GetSuperPath(path, superPath, USE_MAIN_PATH)) - { - lowPart = ::GetCompressedFileSizeW(superPath, &highPart); - if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) - { - size = ((UInt64)highPart << 32) | lowPart; - return true; - } - } - } - #endif - return false; -} - -#endif - -HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix) -{ - unsigned startIndex = Folders.Size(); - { - CEnumerator enumerator(_path + relPrefix + FCHAR_ANY_MASK); - CDirItem fi; - fi.FolderStat_Defined = false; - fi.NumFolders = 0; - fi.NumFiles = 0; - fi.Parent = dirItem; - - while (enumerator.Next(fi)) - { - if (fi.IsDir()) - { - fi.Size = 0; - if (_flatMode) - Folders.Add(relPrefix + fi.Name + FCHAR_PATH_SEPARATOR); - } - else - { - /* - fi.PackSize_Defined = true; - if (!MyGetCompressedFileSizeW(_path + relPrefix + fi.Name, fi.PackSize)) - fi.PackSize = fi.Size; - */ - } - - #if 0 // FIXME #ifndef UNDER_CE - - fi.Reparse.Free(); - fi.PackSize_Defined = false; - - #ifdef FS_SHOW_LINKS_INFO - fi.FileInfo_Defined = false; - fi.FileInfo_WasRequested = false; - fi.FileIndex = 0; - fi.NumLinks = 0; - #endif - - fi.PackSize = fi.Size; - if (fi.HasReparsePoint()) - { - fi.FileInfo_WasRequested = true; - BY_HANDLE_FILE_INFORMATION info; - NIO::GetReparseData(_path + relPrefix + fi.Name, fi.Reparse, &info); - fi.NumLinks = info.nNumberOfLinks; - fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; - fi.FileInfo_Defined = true; - } - - #endif - - /* unsigned fileIndex = */ Files.Add(fi); - - #if defined(_WIN32) && !defined(UNDER_CE) - /* - if (_scanAltStreams) - { - CStreamEnumerator enumerator(_path + relPrefix + fi.Name); - CStreamInfo si; - for (;;) - { - bool found; - if (!enumerator.Next(si, found)) - { - // if (GetLastError() == ERROR_ACCESS_DENIED) - // break; - // return E_FAIL; - break; - } - if (!found) - break; - if (si.IsMainStream()) - continue; - CAltStream ss; - ss.Parent = fileIndex; - ss.Name = si.GetReducedName(); - ss.Size = si.Size; - ss.PackSize_Defined = false; - ss.PackSize = si.Size; - Streams.Add(ss); - } - } - */ - #endif - } - } - if (!_flatMode) - return S_OK; - - unsigned endIndex = Folders.Size(); - for (unsigned i = startIndex; i < endIndex; i++) - LoadSubItems(i, Folders[i]); - return S_OK; -} - -STDMETHODIMP CFSFolder::LoadItems() -{ - Int32 dummy; - WasChanged(&dummy); - Clear(); - RINOK(LoadSubItems(-1, FString())); - _commentsAreLoaded = false; - return S_OK; -} - -static CFSTR kDescriptionFileName = FTEXT("descript.ion"); - -bool CFSFolder::LoadComments() -{ - _comments.Clear(); - _commentsAreLoaded = true; - NIO::CInFile file; - if (!file.Open(_path + kDescriptionFileName)) - return false; - UInt64 len; - if (!file.GetLength(len)) - return false; - if (len >= (1 << 28)) - return false; - AString s; - char *p = s.GetBuf((unsigned)(size_t)len); - UInt32 processedSize; - file.Read(p, (UInt32)len, processedSize); - s.ReleaseBuf_CalcLen((unsigned)(size_t)len); - if (processedSize != len) - return false; - file.Close(); - UString unicodeString; - if (!ConvertUTF8ToUnicode(s, unicodeString)) - return false; - return _comments.ReadFromString(unicodeString); -} - -bool CFSFolder::SaveComments() -{ - AString utf; - { - UString unicode; - _comments.SaveToString(unicode); - ConvertUnicodeToUTF8(unicode, utf); - } - if (!utf.IsAscii()) - utf.Insert(0, "\xEF\xBB\xBF" "\r\n"); - - FString path = _path + kDescriptionFileName; - // We must set same attrib. COutFile::CreateAlways can fail, if file has another attrib. - DWORD attrib = FILE_ATTRIBUTE_NORMAL; - { - CFileInfo fi; - if (fi.Find(path)) - attrib = fi.Attrib; - } - NIO::COutFile file; - if (!file.CreateAlways(path, attrib)) - return false; - UInt32 processed; - file.Write(utf, utf.Len(), processed); - _commentsAreLoaded = false; - return true; -} - -STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = Files.Size() /* + Streams.Size() */; - return S_OK; -} - -#ifdef USE_UNICODE_FSTRING - -STDMETHODIMP CFSFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len) -{ - *name = 0; - *len = 0; - /* - if (index >= Files.Size()) - index = Streams[index - Files.Size()].Parent; - */ - CDirItem &fi = Files[index]; - if (fi.Parent >= 0) - { - const FString &fo = Folders[fi.Parent]; - USE_UNICODE_FSTRING - *name = fo; - *len = fo.Len(); - } - return S_OK; -} - -STDMETHODIMP CFSFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len) -{ - *name = 0; - *len = 0; - if (index < Files.Size()) - { - CDirItem &fi = Files[index]; - *name = fi.Name; - *len = fi.Name.Len(); - return S_OK; - } - else - { - // const CAltStream &ss = Streams[index - Files.Size()]; - // *name = ss.Name; - // *len = ss.Name.Len(); - // - // change it; - } - return S_OK; -} - -STDMETHODIMP_(UInt64) CFSFolder::GetItemSize(UInt32 index) -{ - /* - if (index >= Files.Size()) - return Streams[index - Files.Size()].Size; - */ - CDirItem &fi = Files[index]; - return fi.IsDir() ? 0 : fi.Size; -} - -#endif - -#ifdef FS_SHOW_LINKS_INFO -bool CFSFolder::ReadFileInfo(CDirItem &di) -{ - di.FileInfo_WasRequested = true; - BY_HANDLE_FILE_INFORMATION info; - if (!NIO::CFileBase::GetFileInformation(_path + GetRelPath(di), &info)) - return false; - di.NumLinks = info.nNumberOfLinks; - di.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; - di.FileInfo_Defined = true; - return true; -} -#endif - -STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - /* - if (index >= (UInt32)Files.Size()) - { - CAltStream &ss = Streams[index - Files.Size()]; - CDirItem &fi = Files[ss.Parent]; - switch (propID) - { - case kpidIsDir: prop = false; break; - case kpidIsAltStream: prop = true; break; - case kpidName: prop = fs2us(fi.Name) + ss.Name; break; - case kpidSize: prop = ss.Size; break; - case kpidPackSize: - #ifdef UNDER_CE - prop = ss.Size; - #else - if (!ss.PackSize_Defined) - { - ss.PackSize_Defined = true; - if (!MyGetCompressedFileSizeW(_path + GetRelPath(fi) + us2fs(ss.Name), ss.PackSize)) - ss.PackSize = ss.Size; - } - prop = ss.PackSize; - #endif - break; - case kpidComment: break; - default: index = ss.Parent; - } - if (index >= (UInt32)Files.Size()) - { - prop.Detach(value); - return S_OK; - } - } - */ - CDirItem &fi = Files[index]; - switch (propID) - { - case kpidIsDir: prop = fi.IsDir(); break; - case kpidIsAltStream: prop = false; break; - case kpidName: prop = fs2us(fi.Name); break; - case kpidSize: if (!fi.IsDir() || fi.FolderStat_Defined) prop = fi.Size; break; - case kpidPackSize: - #if 1 // ifdef UNDER_CE - prop = fi.Size; - #else - if (!fi.PackSize_Defined) - { - fi.PackSize_Defined = true; - if (fi.IsDir () || !MyGetCompressedFileSizeW(_path + GetRelPath(fi), fi.PackSize)) - fi.PackSize = fi.Size; - } - prop = fi.PackSize; - #endif - break; - - #ifdef FS_SHOW_LINKS_INFO - - case kpidLinks: - #ifdef UNDER_CE - // prop = fi.NumLinks; - #else - if (!fi.FileInfo_WasRequested) - ReadFileInfo(fi); - if (fi.FileInfo_Defined) - prop = fi.NumLinks; - #endif - break; - - case kpidINode: - #ifdef UNDER_CE - // prop = fi.FileIndex; - #else - if (!fi.FileInfo_WasRequested) - ReadFileInfo(fi); - if (fi.FileInfo_Defined) - prop = fi.FileIndex; - #endif - break; - - #endif - - case kpidAttrib: prop = (UInt32)fi.Attrib; break; - case kpidCTime: prop = fi.CTime; break; - case kpidATime: prop = fi.ATime; break; - case kpidMTime: prop = fi.MTime; break; - case kpidComment: - { - if (!_commentsAreLoaded) - LoadComments(); - UString comment; - if (_comments.GetValue(fs2us(GetRelPath(fi)), comment)) - { - int pos = comment.Find((wchar_t)4); - if (pos >= 0) - comment.DeleteFrom(pos); - prop = comment; - } - break; - } - case kpidPrefix: - if (fi.Parent >= 0) - prop = Folders[fi.Parent]; - break; - case kpidNumSubDirs: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFolders; break; - case kpidNumSubFiles: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFiles; break; - } - prop.Detach(value); - return S_OK; -} - - -// ---------- IArchiveGetRawProps ---------- - - -STDMETHODIMP CFSFolder::GetNumRawProps(UInt32 *numProps) -{ - *numProps = 1; - return S_OK; -} - -STDMETHODIMP CFSFolder::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID) -{ - index = index; - *name = NULL; - *propID = kpidNtReparse; - return S_OK; -} - -STDMETHODIMP CFSFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */) -{ - return E_FAIL; -} - -STDMETHODIMP CFSFolder::GetRawProp(UInt32 - #ifndef UNDER_CE - index - #endif - , PROPID - #ifndef UNDER_CE - propID - #endif - , const void **data, UInt32 *dataSize, UInt32 *propType) -{ - *data = NULL; - *dataSize = 0; - *propType = 0; - - #if 0 // #ifndef UNDER_CE - if (propID == kpidNtReparse) - { - const CDirItem &fi = Files[index]; - const CByteBuffer &buf = fi.Reparse; - if (buf.Size() == 0) - return S_OK; - *data = buf; - *dataSize = (UInt32)buf.Size(); - *propType = NPropDataType::kRaw; - return S_OK; - } - #endif - - return S_OK; -} - - -// returns Position of extension including '.' - -static inline CFSTR GetExtensionPtr(const FString &name) -{ - int dotPos = name.ReverseFind_Dot(); - return name.Ptr((dotPos < 0) ? name.Len() : dotPos); -} - -STDMETHODIMP_(Int32) CFSFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */) -{ - /* - const CAltStream *ss1 = NULL; - const CAltStream *ss2 = NULL; - if (index1 >= (UInt32)Files.Size()) { ss1 = &Streams[index1 - Files.Size()]; index1 = ss1->Parent; } - if (index2 >= (UInt32)Files.Size()) { ss2 = &Streams[index2 - Files.Size()]; index2 = ss2->Parent; } - */ - CDirItem &fi1 = Files[index1]; - CDirItem &fi2 = Files[index2]; - - switch (propID) - { - case kpidName: - { - int comp = CompareFileNames_ForFolderList(fi1.Name, fi2.Name); - /* - if (comp != 0) - return comp; - if (!ss1) - return ss2 ? -1 : 0; - if (!ss2) - return 1; - return MyStringCompareNoCase(ss1->Name, ss2->Name); - */ - return comp; - } - case kpidSize: - return MyCompare( - /* ss1 ? ss1->Size : */ fi1.Size, - /* ss2 ? ss2->Size : */ fi2.Size); - case kpidAttrib: return MyCompare(fi1.Attrib, fi2.Attrib); - case kpidCTime: return CompareFileTime(&fi1.CTime, &fi2.CTime); - case kpidATime: return CompareFileTime(&fi1.ATime, &fi2.ATime); - case kpidMTime: return CompareFileTime(&fi1.MTime, &fi2.MTime); - case kpidIsDir: - { - bool isDir1 = /* ss1 ? false : */ fi1.IsDir(); - bool isDir2 = /* ss2 ? false : */ fi2.IsDir(); - if (isDir1 == isDir2) - return 0; - return isDir1 ? -1 : 1; - } - case kpidPackSize: - { - #if 1 // #ifdef UNDER_CE - return MyCompare(fi1.Size, fi2.Size); - #else - // PackSize can be undefined here - return MyCompare( - /* ss1 ? ss1->PackSize : */ fi1.PackSize, - /* ss2 ? ss2->PackSize : */ fi2.PackSize); - #endif - } - - #ifdef FS_SHOW_LINKS_INFO - case kpidINode: - { - #ifndef UNDER_CE - if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1); - if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2); - return MyCompare( - fi1.FileIndex, - fi2.FileIndex); - #endif - } - case kpidLinks: - { - #ifndef UNDER_CE - if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1); - if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2); - return MyCompare( - fi1.NumLinks, - fi2.NumLinks); - #endif - } - #endif - - case kpidComment: - { - // change it ! - UString comment1, comment2; - _comments.GetValue(fs2us(GetRelPath(fi1)), comment1); - _comments.GetValue(fs2us(GetRelPath(fi2)), comment2); - return MyStringCompareNoCase(comment1, comment2); - } - case kpidPrefix: - if (fi1.Parent < 0) return (fi2.Parent < 0) ? 0 : -1; - if (fi2.Parent < 0) return 1; - return CompareFileNames_ForFolderList( - Folders[fi1.Parent], - Folders[fi2.Parent]); - case kpidExtension: - return CompareFileNames_ForFolderList( - GetExtensionPtr(fi1.Name), - GetExtensionPtr(fi2.Name)); - } - - return 0; -} - -HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder) -{ - *resultFolder = 0; - CFSFolder *folderSpec = new CFSFolder; - CMyComPtr subFolder = folderSpec; - RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR)); - *resultFolder = subFolder.Detach(); - return S_OK; -} - -/* -void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const -{ - if (item.Parent >= 0) - prefix = Folders[item.Parent]; - else - prefix.Empty(); -} -*/ - -/* -void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const -{ - int parent = item.Parent; - - unsigned len = 0; - - while (parent >= 0) - { - const CDirItem &cur = Files[parent]; - len += cur.Name.Len() + 1; - parent = cur.Parent; - } - - wchar_t *p = prefix.GetBuf_SetEnd(len) + len; - parent = item.Parent; - - while (parent >= 0) - { - const CDirItem &cur = Files[parent]; - *(--p) = FCHAR_PATH_SEPARATOR; - p -= cur.Name.Len(); - wmemcpy(p, cur.Name, cur.Name.Len()); - parent = cur.Parent; - } -} -*/ - -FString CFSFolder::GetRelPath(const CDirItem &item) const -{ - if (item.Parent < 0) - return item.Name; - return Folders[item.Parent] + item.Name; -} - -STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) -{ - *resultFolder = 0; - const CDirItem &fi = Files[index]; - if (!fi.IsDir()) - return E_INVALIDARG; - return BindToFolderSpec(GetRelPath(fi), resultFolder); -} - -STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) -{ - return BindToFolderSpec(us2fs(name), resultFolder); -} - -static const CFSTR kSuperPrefix = FTEXT("\\\\?\\"); - -STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder) -{ - *resultFolder = 0; - /* - if (_parentFolder) - { - CMyComPtr parentFolder = _parentFolder; - *resultFolder = parentFolder.Detach(); - return S_OK; - } - */ - if (_path.IsEmpty()) - return E_INVALIDARG; - int pos = _path.ReverseFind_PathSepar(); - if (pos < 0 || pos != (int)_path.Len() - 1) - return E_FAIL; - FString parentPath = _path.Left(pos); - pos = parentPath.ReverseFind_PathSepar(); - if (pos < 0) - { - #ifdef UNDER_CE - *resultFolder = 0; - #else - CFSDrives *drivesFolderSpec = new CFSDrives; - CMyComPtr drivesFolder = drivesFolderSpec; - drivesFolderSpec->Init(); - *resultFolder = drivesFolder.Detach(); - #endif - return S_OK; - } - - /* - parentPath.DeleteFrom(pos + 1); - - if (parentPath == kSuperPrefix) - { - #ifdef UNDER_CE - *resultFolder = 0; - #else - CFSDrives *drivesFolderSpec = new CFSDrives; - CMyComPtr drivesFolder = drivesFolderSpec; - drivesFolderSpec->Init(false, true); - *resultFolder = drivesFolder.Detach(); - #endif - return S_OK; - } - - FString parentPathReduced = parentPath.Left(pos); - - #ifndef UNDER_CE - pos = parentPathReduced.ReverseFind_PathSepar(); - if (pos == 1) - { - if (!IS_PATH_SEPAR_CHAR(parentPath[0])) - return E_FAIL; - CNetFolder *netFolderSpec = new CNetFolder; - CMyComPtr netFolder = netFolderSpec; - netFolderSpec->Init(fs2us(parentPath)); - *resultFolder = netFolder.Detach(); - return S_OK; - } - #endif - - CFSFolder *parentFolderSpec = new CFSFolder; - CMyComPtr parentFolder = parentFolderSpec; - RINOK(parentFolderSpec->Init(parentPath, 0)); - *resultFolder = parentFolder.Detach(); - */ - return S_OK; -} - -STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties) -{ - *numProperties = ARRAY_SIZE(kProps); - if (!_flatMode) - (*numProperties)--; - return S_OK; -} - -STDMETHODIMP CFSFolder::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps) - -STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch (propID) - { - case kpidType: prop = "FSFolder"; break; - case kpidPath: prop = fs2us(_path); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CFSFolder::WasChanged(Int32 *wasChanged) -{ - bool wasChangedMain = false; -#ifdef _WIN32 - for (;;) - { - if (!_findChangeNotification.IsHandleAllocated()) - { - *wasChanged = BoolToInt(false); - return S_OK; - } - - DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); - bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); - if (wasChangedLoc) - { - _findChangeNotification.FindNext(); - wasChangedMain = true; - } - else - break; - } -#endif - *wasChanged = BoolToInt(wasChangedMain); - return S_OK; -} - -STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder) -{ - CFSFolder *fsFolderSpec = new CFSFolder; - CMyComPtr folderNew = fsFolderSpec; - fsFolderSpec->Init(_path); - *resultFolder = folderNew.Detach(); - return S_OK; -} - -HRESULT CFSFolder::GetItemsFullSize(const UInt32 *indices, UInt32 numItems, CFsFolderStat &stat) -{ - for (UInt32 i = 0; i < numItems; i++) - { - UInt32 index = indices[i]; - /* - if (index >= Files.Size()) - { - size += Streams[index - Files.Size()].Size; - // numFiles++; - continue; - } - */ - const CDirItem &fi = Files[index]; - if (fi.IsDir()) - { - stat.Path = _path; - stat.Path += GetRelPath(fi); - RINOK(stat.Enumerate()); - stat.NumFolders++; - } - else - { - stat.NumFiles++; - stat.Size += fi.Size; - } - } - return S_OK; -} - -/* -HRESULT CFSFolder::GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress) -{ - if (index >= Files.Size()) - { - size = Streams[index - Files.Size()].Size; - return S_OK; - } - const CDirItem &fi = Files[index]; - if (fi.IsDir()) - { - UInt64 numFolders = 0, numFiles = 0; - size = 0; - return GetFolderSize(_path + GetRelPath(fi), numFolders, numFiles, size, progress); - } - size = fi.Size; - return S_OK; -} - -STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress) -{ - NCOM::CPropVariant prop; - UInt64 size = 0; - HRESULT result = GetItemFullSize(index, size, progress); - prop = size; - prop.Detach(value); - return result; -} -*/ - -STDMETHODIMP CFSFolder::CalcItemFullSize(UInt32 index, IProgress *progress) -{ - if (index >= (UInt32)Files.Size()) - return S_OK; - CDirItem &fi = Files[index]; - if (!fi.IsDir()) - return S_OK; - CFsFolderStat stat(_path + GetRelPath(fi), progress); - RINOK(stat.Enumerate()); - fi.Size = stat.Size; - fi.NumFolders = stat.NumFolders; - fi.NumFiles = stat.NumFiles; - fi.FolderStat_Defined = true; - return S_OK; -} - -void CFSFolder::GetAbsPath(const wchar_t *name, FString &absPath) -{ - absPath.Empty(); - if (!IsAbsolutePath(name)) - absPath += _path; - absPath += us2fs(name); -} - -STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */) -{ - FString absPath; - GetAbsPath(name, absPath); - if (CreateDir(absPath)) - return S_OK; - if (::GetLastError() == ERROR_ALREADY_EXISTS) - return ::GetLastError(); - if (!CreateComplexDir(absPath)) - return ::GetLastError(); - return S_OK; -} - -STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */) -{ - FString absPath; - GetAbsPath(name, absPath); - NIO::COutFile outFile; - if (!outFile.Create(absPath, false)) - return ::GetLastError(); - return S_OK; -} - -STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */) -{ - if (index >= (UInt32)Files.Size()) - return E_NOTIMPL; - const CDirItem &fi = Files[index]; - // FString prefix; - // GetPrefix(fi, prefix); - FString fullPrefix = _path; - if (fi.Parent >= 0) - fullPrefix += Folders[fi.Parent]; - if (!MyMoveFile(fullPrefix + fi.Name, fullPrefix + us2fs(newName))) - return GetLastError(); - return S_OK; -} - -STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress) -{ - RINOK(progress->SetTotal(numItems)); - // int prevDeletedFileIndex = -1; - for (UInt32 i = 0; i < numItems; i++) - { - // Sleep(200); - UInt32 index = indices[i]; - bool result = true; - /* - if (index >= (UInt32)Files.Size()) - { - const CAltStream &ss = Streams[index - (UInt32)Files.Size()]; - if (prevDeletedFileIndex != ss.Parent) - { - const CDirItem &fi = Files[ss.Parent]; - result = DeleteFileAlways(_path + GetRelPath(fi) + us2fs(ss.Name)); - } - } - else - */ - { - const CDirItem &fi = Files[index]; - const FString fullPath = _path + GetRelPath(fi); - // prevDeletedFileIndex = index; - if (fi.IsDir()) - result = RemoveDirWithSubItems(fullPath); - else - result = DeleteFileAlways(fullPath); - } - if (!result) - return GetLastError(); - UInt64 completed = i; - RINOK(progress->SetCompleted(&completed)); - } - return S_OK; -} - -STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID, - const PROPVARIANT *value, IProgress * /* progress */) -{ - if (index >= (UInt32)Files.Size()) - return E_INVALIDARG; - CDirItem &fi = Files[index]; - if (fi.Parent >= 0) - return E_NOTIMPL; - switch (propID) - { - case kpidComment: - { - UString filename = fs2us(fi.Name); - filename.Trim(); - if (value->vt == VT_EMPTY) - _comments.DeletePair(filename); - else if (value->vt == VT_BSTR) - { - CTextPair pair; - pair.ID = filename; - pair.ID.Trim(); - pair.Value.SetFromBstr(value->bstrVal); - pair.Value.Trim(); - if (pair.Value.IsEmpty()) - _comments.DeletePair(filename); - else - _comments.AddPair(pair); - } - else - return E_INVALIDARG; - SaveComments(); - break; - } - default: - return E_NOTIMPL; - } - return S_OK; -} - -STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex) -{ - if (index >= (UInt32)Files.Size()) - return E_INVALIDARG; - const CDirItem &fi = Files[index]; - *iconIndex = 0; - int iconIndexTemp; - if (GetRealIconIndex(_path + GetRelPath(fi), fi.Attrib, iconIndexTemp) != 0) - { - *iconIndex = iconIndexTemp; - return S_OK; - } - return GetLastError(); -} - -STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode) -{ - _flatMode = IntToBool(flatMode); - return S_OK; -} - -/* -STDMETHODIMP CFSFolder::SetShowNtfsStreamsMode(Int32 showStreamsMode) -{ - _scanAltStreams = IntToBool(showStreamsMode); - return S_OK; -} -*/ - -} +// FSFolder.cpp + +#include "StdAfx.h" + +#ifdef __MINGW32_VERSION +// #if !defined(_MSC_VER) && (__GNUC__) && (__GNUC__ < 10) +// for old mingw +#include +#else +#ifndef Z7_OLD_WIN_SDK + #if !defined(_M_IA64) + #include + #endif +#else +typedef LONG NTSTATUS; +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; +#endif +#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" +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#include "FSDrives.h" +#include "FSFolder.h" + +#ifndef UNDER_CE +#include "NetFolder.h" +#endif + +#include "SysIconUtils.h" + +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0501 +#ifdef _APISETFILE_ +// Windows SDK 8.1 defines in fileapi.h the function GetCompressedFileSizeW only if _WIN32_WINNT >= 0x0501 +// But real support version for that function is NT 3.1 (probably) +// So we must define GetCompressedFileSizeW +EXTERN_C_BEGIN +WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh); +EXTERN_C_END +#endif +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NFind; +using namespace NDir; +using namespace NName; + +#ifndef USE_UNICODE_FSTRING +int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2); +int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2) +{ + return CompareFileNames_ForFolderList(fs2us(s1), fs2us(s2)); +} +#endif + +namespace NFsFolder { + +static const Byte kProps[] = +{ + kpidName, + kpidSize, + kpidMTime, + kpidCTime, + kpidATime, + #ifdef FS_SHOW_LINKS_INFO + kpidChangeTime, + #endif + kpidAttrib, + kpidPackSize, + #ifdef FS_SHOW_LINKS_INFO + kpidINode, + kpidLinks, + #endif + kpidComment, + kpidNumSubDirs, + kpidNumSubFiles, + kpidPrefix +}; + +HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */) +{ + // _parentFolder = parentFolder; + _path = path; + + #ifdef _WIN32 + + _findChangeNotification.FindFirst(_path, false, + FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME + | FILE_NOTIFY_CHANGE_ATTRIBUTES + | FILE_NOTIFY_CHANGE_SIZE + | FILE_NOTIFY_CHANGE_LAST_WRITE + /* + | FILE_NOTIFY_CHANGE_LAST_ACCESS + | FILE_NOTIFY_CHANGE_CREATION + | FILE_NOTIFY_CHANGE_SECURITY + */ + ); + + if (!_findChangeNotification.IsHandleAllocated()) + { + const HRESULT lastError = GetLastError_noZero_HRESULT(); + CFindFile findFile; + CFileInfo fi; + FString path2 = _path; + path2.Add_Char('*'); // CHAR_ANY_MASK; + if (!findFile.FindFirst(path2, fi)) + return lastError; + } + + #endif + + return S_OK; +} + + +HRESULT CFsFolderStat::Enumerate() +{ + if (Progress) + { + RINOK(Progress->SetCompleted(NULL)) + } + Path.Add_PathSepar(); + const unsigned len = Path.Len(); + CEnumerator enumerator; + enumerator.SetDirPrefix(Path); + CDirEntry fi; + while (enumerator.Next(fi)) + { + if (fi.IsDir()) + { + NumFolders++; + Path.DeleteFrom(len); + Path += fi.Name; + RINOK(Enumerate()) + } + else + { + NumFiles++; + Size += fi.Size; + } + } + return S_OK; +} + +#ifndef UNDER_CE + +bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size); +bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size) +{ + DWORD highPart; + DWORD lowPart = INVALID_FILE_SIZE; + IF_USE_MAIN_PATH + { + lowPart = ::GetCompressedFileSizeW(fs2us(path), &highPart); + if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) + { + size = ((UInt64)highPart << 32) | lowPart; + return true; + } + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + { + lowPart = ::GetCompressedFileSizeW(superPath, &highPart); + if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) + { + size = ((UInt64)highPart << 32) | lowPart; + return true; + } + } + } + #endif + return false; +} + +#endif + +HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix) +{ + const unsigned startIndex = Folders.Size(); + { + CEnumerator enumerator; + enumerator.SetDirPrefix(_path + relPrefix); + CDirItem fi; + fi.FolderStat_Defined = false; + fi.NumFolders = 0; + fi.NumFiles = 0; + fi.Parent = dirItem; + + while (enumerator.Next(fi)) + { + if (fi.IsDir()) + { + fi.Size = 0; + if (_flatMode) + Folders.Add(relPrefix + fi.Name + FCHAR_PATH_SEPARATOR); + } + else + { + /* + fi.PackSize_Defined = true; + if (!MyGetCompressedFileSizeW(_path + relPrefix + fi.Name, fi.PackSize)) + fi.PackSize = fi.Size; + */ + } + + #ifndef UNDER_CE + + fi.Reparse.Free(); + fi.PackSize_Defined = false; + + #ifdef FS_SHOW_LINKS_INFO + fi.FileInfo_Defined = false; + fi.FileInfo_WasRequested = false; + fi.FileIndex = 0; + fi.NumLinks = 0; + 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; + BY_HANDLE_FILE_INFORMATION info; + NIO::GetReparseData(_path + relPrefix + fi.Name, fi.Reparse, &info); + fi.NumLinks = info.nNumberOfLinks; + fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + fi.FileInfo_Defined = true; + } + #endif + + #endif // UNDER_CE + + /* unsigned fileIndex = */ Files.Add(fi); + + #if defined(_WIN32) && !defined(UNDER_CE) + /* + if (_scanAltStreams) + { + CStreamEnumerator enumerator(_path + relPrefix + fi.Name); + CStreamInfo si; + for (;;) + { + bool found; + if (!enumerator.Next(si, found)) + { + // if (GetLastError() == ERROR_ACCESS_DENIED) + // break; + // return E_FAIL; + break; + } + if (!found) + break; + if (si.IsMainStream()) + continue; + CAltStream ss; + ss.Parent = fileIndex; + ss.Name = si.GetReducedName(); + ss.Size = si.Size; + ss.PackSize_Defined = false; + ss.PackSize = si.Size; + Streams.Add(ss); + } + } + */ + #endif + } + } + if (!_flatMode) + return S_OK; + + const unsigned endIndex = Folders.Size(); + for (unsigned i = startIndex; i < endIndex; i++) + LoadSubItems((int)i, Folders[i]); + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::LoadItems()) +{ + Int32 dummy; + WasChanged(&dummy); + Clear(); + RINOK(LoadSubItems(-1, FString())) + _commentsAreLoaded = false; + return S_OK; +} + +static CFSTR const kDescriptionFileName = FTEXT("descript.ion"); + +bool CFSFolder::LoadComments() +{ + _comments.Clear(); + _commentsAreLoaded = true; + NIO::CInFile file; + if (!file.Open(_path + kDescriptionFileName)) + return false; + UInt64 len; + if (!file.GetLength(len)) + return false; + if (len >= (1 << 28)) + return false; + AString s; + char *p = s.GetBuf((unsigned)(size_t)len); + size_t processedSize; + if (!file.ReadFull(p, (unsigned)(size_t)len, processedSize)) + return false; + s.ReleaseBuf_CalcLen((unsigned)(size_t)len); + if (processedSize != len) + return false; + file.Close(); + UString unicodeString; + if (!ConvertUTF8ToUnicode(s, unicodeString)) + return false; + return _comments.ReadFromString(unicodeString); +} + +bool CFSFolder::SaveComments() +{ + AString utf; + { + UString unicode; + _comments.SaveToString(unicode); + ConvertUnicodeToUTF8(unicode, utf); + } + if (!utf.IsAscii()) + utf.Insert(0, "\xEF\xBB\xBF" "\r\n"); + + FString path = _path + kDescriptionFileName; + // We must set same attrib. COutFile::CreateAlways can fail, if file has another attrib. + DWORD attrib = FILE_ATTRIBUTE_NORMAL; + { + CFileInfo fi; + if (fi.Find(path)) + attrib = fi.Attrib; + } + NIO::COutFile file; + if (!file.Create_ALWAYS_with_Attribs(path, attrib)) + return false; + UInt32 processed; + file.Write(utf, utf.Len(), processed); + _commentsAreLoaded = false; + return true; +} + +Z7_COM7F_IMF(CFSFolder::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = Files.Size() /* + Streams.Size() */; + return S_OK; +} + +#ifdef USE_UNICODE_FSTRING + +Z7_COM7F_IMF(CFSFolder::GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len)) +{ + *name = NULL; + *len = 0; + /* + if (index >= Files.Size()) + index = Streams[index - Files.Size()].Parent; + */ + CDirItem &fi = Files[index]; + if (fi.Parent >= 0) + { + const FString &fo = Folders[fi.Parent]; + USE_UNICODE_FSTRING + *name = fo; + *len = fo.Len(); + } + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) +{ + *name = NULL; + *len = 0; + if (index < Files.Size()) + { + CDirItem &fi = Files[index]; + *name = fi.Name; + *len = fi.Name.Len(); + return S_OK; + } + else + { + // const CAltStream &ss = Streams[index - Files.Size()]; + // *name = ss.Name; + // *len = ss.Name.Len(); + // + // change it; + } + return S_OK; +} + +Z7_COM7F_IMF2(UInt64, CFSFolder::GetItemSize(UInt32 index)) +{ + /* + if (index >= Files.Size()) + return Streams[index - Files.Size()].Size; + */ + CDirItem &fi = Files[index]; + return fi.IsDir() ? 0 : fi.Size; +} + +#endif + + +#ifdef FS_SHOW_LINKS_INFO + +bool CFSFolder::ReadFileInfo(CDirItem &di) +{ + di.FileInfo_WasRequested = true; + BY_HANDLE_FILE_INFORMATION info; + memset(&info, 0, sizeof(info)); // for vc6-O2 + if (!NIO::CFileBase::GetFileInformation(_path + GetRelPath(di), &info)) + return false; + di.NumLinks = info.nNumberOfLinks; + di.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + di.FileInfo_Defined = true; + return true; +} + + +EXTERN_C_BEGIN + +typedef struct +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; + UInt32 Reserved; // it's expected for alignment +} +Z7_WIN_FILE_BASIC_INFORMATION; + + +typedef enum +{ + Z7_WIN_FileDirectoryInformation = 1, + Z7_WIN_FileFullDirectoryInformation, + Z7_WIN_FileBothDirectoryInformation, + Z7_WIN_FileBasicInformation +} +Z7_WIN_FILE_INFORMATION_CLASS; + + +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500) && !defined(_M_IA64) +#define Z7_WIN_NTSTATUS NTSTATUS +#define Z7_WIN_IO_STATUS_BLOCK IO_STATUS_BLOCK +#else +typedef LONG Z7_WIN_NTSTATUS; +typedef struct +{ + union + { + Z7_WIN_NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + ULONG_PTR Information; +} Z7_WIN_IO_STATUS_BLOCK; +#endif + + +typedef Z7_WIN_NTSTATUS (WINAPI * Func_NtQueryInformationFile)( + HANDLE handle, Z7_WIN_IO_STATUS_BLOCK *io, + void *ptr, LONG len, Z7_WIN_FILE_INFORMATION_CLASS cls); + +#define MY_STATUS_SUCCESS 0 + +EXTERN_C_END + +static Func_NtQueryInformationFile f_NtQueryInformationFile; +static bool g_NtQueryInformationFile_WasRequested = false; + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +void CFSFolder::ReadChangeTime(CDirItem &di) +{ + di.ChangeTime_WasRequested = true; + + if (!g_NtQueryInformationFile_WasRequested) + { + g_NtQueryInformationFile_WasRequested = true; + f_NtQueryInformationFile = Z7_GET_PROC_ADDRESS( + Func_NtQueryInformationFile, ::GetModuleHandleW(L"ntdll.dll"), + "NtQueryInformationFile"); + } + if (!f_NtQueryInformationFile) + return; + + NIO::CInFile file; + if (!file.Open_for_ReadAttributes(_path + GetRelPath(di))) + return; + Z7_WIN_FILE_BASIC_INFORMATION fbi; + Z7_WIN_IO_STATUS_BLOCK IoStatusBlock; + const Z7_WIN_NTSTATUS status = f_NtQueryInformationFile(file.GetHandle(), &IoStatusBlock, + &fbi, sizeof(fbi), Z7_WIN_FileBasicInformation); + if (status != MY_STATUS_SUCCESS) + return; + if (IoStatusBlock.Information != sizeof(fbi)) + return; + di.ChangeTime.dwLowDateTime = fbi.ChangeTime.u.LowPart; + di.ChangeTime.dwHighDateTime = (DWORD)fbi.ChangeTime.u.HighPart; + di.ChangeTime_Defined = true; +} + +#endif // FS_SHOW_LINKS_INFO + + +Z7_COM7F_IMF(CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + /* + if (index >= Files.Size()) + { + CAltStream &ss = Streams[index - Files.Size()]; + CDirItem &fi = Files[ss.Parent]; + switch (propID) + { + case kpidIsDir: prop = false; break; + case kpidIsAltStream: prop = true; break; + case kpidName: prop = fs2us(fi.Name) + ss.Name; break; + case kpidSize: prop = ss.Size; break; + case kpidPackSize: + #ifdef UNDER_CE + prop = ss.Size; + #else + if (!ss.PackSize_Defined) + { + ss.PackSize_Defined = true; + if (!MyGetCompressedFileSizeW(_path + GetRelPath(fi) + us2fs(ss.Name), ss.PackSize)) + ss.PackSize = ss.Size; + } + prop = ss.PackSize; + #endif + break; + case kpidComment: break; + default: index = ss.Parent; + } + if (index >= Files.Size()) + { + prop.Detach(value); + return S_OK; + } + } + */ + CDirItem &fi = Files[index]; + switch (propID) + { + case kpidIsDir: prop = fi.IsDir(); break; + case kpidIsAltStream: prop = false; break; + case kpidName: prop = fs2us(fi.Name); break; + case kpidSize: if (!fi.IsDir() || fi.FolderStat_Defined) prop = fi.Size; break; + case kpidPackSize: + #ifdef UNDER_CE + prop = fi.Size; + #else + if (!fi.PackSize_Defined) + { + fi.PackSize_Defined = true; + if (fi.IsDir () || !MyGetCompressedFileSizeW(_path + GetRelPath(fi), fi.PackSize)) + fi.PackSize = fi.Size; + } + prop = fi.PackSize; + #endif + break; + + #ifdef FS_SHOW_LINKS_INFO + + case kpidLinks: + #ifdef UNDER_CE + // prop = fi.NumLinks; + #else + if (!fi.FileInfo_WasRequested) + ReadFileInfo(fi); + if (fi.FileInfo_Defined) + prop = fi.NumLinks; + #endif + break; + + case kpidINode: + #ifdef UNDER_CE + // prop = fi.FileIndex; + #else + if (!fi.FileInfo_WasRequested) + ReadFileInfo(fi); + if (fi.FileInfo_Defined) + 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; + case kpidCTime: prop = fi.CTime; break; + case kpidATime: prop = fi.ATime; break; + case kpidMTime: prop = fi.MTime; break; + case kpidComment: + { + if (!_commentsAreLoaded) + LoadComments(); + UString comment; + if (_comments.GetValue(fs2us(GetRelPath(fi)), comment)) + { + int pos = comment.Find((wchar_t)4); + if (pos >= 0) + comment.DeleteFrom((unsigned)pos); + prop = comment; + } + break; + } + case kpidPrefix: + if (fi.Parent >= 0) + prop = fs2us(Folders[fi.Parent]); + break; + case kpidNumSubDirs: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFolders; break; + case kpidNumSubFiles: if (fi.IsDir() && fi.FolderStat_Defined) prop = fi.NumFiles; break; + } + prop.Detach(value); + return S_OK; +} + + +// ---------- IArchiveGetRawProps ---------- + + +Z7_COM7F_IMF(CFSFolder::GetNumRawProps(UInt32 *numProps)) +{ + *numProps = 1; + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)) +{ + *name = NULL; + *propID = kpidNtReparse; + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetParent(UInt32 /* index */, UInt32 * /* parent */, UInt32 * /* parentType */)) +{ + return E_FAIL; +} + +Z7_COM7F_IMF(CFSFolder::GetRawProp(UInt32 index, PROPID propID, + const void **data, UInt32 *dataSize, UInt32 *propType)) +{ + #ifdef UNDER_CE + UNUSED(index) + UNUSED(propID) + #endif + + *data = NULL; + *dataSize = 0; + *propType = 0; + + #ifndef UNDER_CE + if (propID == kpidNtReparse) + { + const CDirItem &fi = Files[index]; + const CByteBuffer &buf = fi.Reparse; + if (buf.Size() == 0) + return S_OK; + *data = buf; + *dataSize = (UInt32)buf.Size(); + *propType = NPropDataType::kRaw; + return S_OK; + } + #endif + + return S_OK; +} + + +// returns Position of extension including '.' + +static inline CFSTR GetExtensionPtr(const FString &name) +{ + const int dotPos = name.ReverseFind_Dot(); + return name.Ptr((dotPos < 0) ? name.Len() : (unsigned)dotPos); +} + +Z7_COM7F_IMF2(Int32, CFSFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */)) +{ + /* + const CAltStream *ss1 = NULL; + const CAltStream *ss2 = NULL; + if (index1 >= Files.Size()) { ss1 = &Streams[index1 - Files.Size()]; index1 = ss1->Parent; } + if (index2 >= Files.Size()) { ss2 = &Streams[index2 - Files.Size()]; index2 = ss2->Parent; } + */ + CDirItem &fi1 = Files[index1]; + CDirItem &fi2 = Files[index2]; + + switch (propID) + { + case kpidName: + { + const int comp = CompareFileNames_ForFolderList(fi1.Name, fi2.Name); + /* + if (comp != 0) + return comp; + if (!ss1) + return ss2 ? -1 : 0; + if (!ss2) + return 1; + return MyStringCompareNoCase(ss1->Name, ss2->Name); + */ + return comp; + } + case kpidSize: + return MyCompare( + /* ss1 ? ss1->Size : */ fi1.Size, + /* ss2 ? ss2->Size : */ fi2.Size); + case kpidAttrib: return MyCompare(fi1.Attrib, fi2.Attrib); + case kpidCTime: return CompareFileTime(&fi1.CTime, &fi2.CTime); + case kpidATime: return CompareFileTime(&fi1.ATime, &fi2.ATime); + case kpidMTime: return CompareFileTime(&fi1.MTime, &fi2.MTime); + case kpidIsDir: + { + bool isDir1 = /* ss1 ? false : */ fi1.IsDir(); + bool isDir2 = /* ss2 ? false : */ fi2.IsDir(); + if (isDir1 == isDir2) + return 0; + return isDir1 ? -1 : 1; + } + case kpidPackSize: + { + #ifdef UNDER_CE + return MyCompare(fi1.Size, fi2.Size); + #else + // PackSize can be undefined here + return MyCompare( + /* ss1 ? ss1->PackSize : */ fi1.PackSize, + /* ss2 ? ss2->PackSize : */ fi2.PackSize); + #endif + } + + #ifdef FS_SHOW_LINKS_INFO + case kpidINode: + { + #ifndef UNDER_CE + if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1); + if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2); + return MyCompare( + fi1.FileIndex, + fi2.FileIndex); + #endif + } + case kpidLinks: + { + #ifndef UNDER_CE + if (!fi1.FileInfo_WasRequested) ReadFileInfo(fi1); + if (!fi2.FileInfo_WasRequested) ReadFileInfo(fi2); + return MyCompare( + fi1.NumLinks, + fi2.NumLinks); + #endif + } + #endif + + case kpidComment: + { + // change it ! + UString comment1, comment2; + _comments.GetValue(fs2us(GetRelPath(fi1)), comment1); + _comments.GetValue(fs2us(GetRelPath(fi2)), comment2); + return MyStringCompareNoCase(comment1, comment2); + } + case kpidPrefix: + if (fi1.Parent < 0) return (fi2.Parent < 0) ? 0 : -1; + if (fi2.Parent < 0) return 1; + return CompareFileNames_ForFolderList( + Folders[fi1.Parent], + Folders[fi2.Parent]); + case kpidExtension: + return CompareFileNames_ForFolderList( + GetExtensionPtr(fi1.Name), + GetExtensionPtr(fi2.Name)); + } + + return 0; +} + +HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder) +{ + *resultFolder = NULL; + CFSFolder *folderSpec = new CFSFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR)) + *resultFolder = subFolder.Detach(); + return S_OK; +} + +/* +void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const +{ + if (item.Parent >= 0) + prefix = Folders[item.Parent]; + else + prefix.Empty(); +} +*/ + +/* +void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const +{ + int parent = item.Parent; + + unsigned len = 0; + + while (parent >= 0) + { + const CDirItem &cur = Files[parent]; + len += cur.Name.Len() + 1; + parent = cur.Parent; + } + + wchar_t *p = prefix.GetBuf_SetEnd(len) + len; + parent = item.Parent; + + while (parent >= 0) + { + const CDirItem &cur = Files[parent]; + *(--p) = FCHAR_PATH_SEPARATOR; + p -= cur.Name.Len(); + wmemcpy(p, cur.Name, cur.Name.Len()); + parent = cur.Parent; + } +} +*/ + +FString CFSFolder::GetRelPath(const CDirItem &item) const +{ + if (item.Parent < 0) + return item.Name; + return Folders[item.Parent] + item.Name; +} + +Z7_COM7F_IMF(CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + const CDirItem &fi = Files[index]; + if (!fi.IsDir()) + return E_INVALIDARG; + return BindToFolderSpec(GetRelPath(fi), resultFolder); +} + +Z7_COM7F_IMF(CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) +{ + return BindToFolderSpec(us2fs(name), resultFolder); +} + +Z7_COM7F_IMF(CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + /* + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + */ + if (_path.IsEmpty()) + return E_INVALIDARG; + + #ifndef UNDER_CE + + if (IsDriveRootPath_SuperAllowed(_path)) + { + CFSDrives *drivesFolderSpec = new CFSDrives; + CMyComPtr drivesFolder = drivesFolderSpec; + drivesFolderSpec->Init(false, IsSuperPath(_path)); + *resultFolder = drivesFolder.Detach(); + return S_OK; + } + + int pos = _path.ReverseFind_PathSepar(); + if (pos < 0 || pos != (int)_path.Len() - 1) + return E_FAIL; + FString parentPath = _path.Left((unsigned)pos); + pos = parentPath.ReverseFind_PathSepar(); + parentPath.DeleteFrom((unsigned)(pos + 1)); + + if (NName::IsDrivePath_SuperAllowed(parentPath)) + { + CFSFolder *parentFolderSpec = new CFSFolder; + CMyComPtr parentFolder = parentFolderSpec; + if (parentFolderSpec->Init(parentPath) == S_OK) + { + *resultFolder = parentFolder.Detach(); + return S_OK; + } + } + + /* + FString parentPathReduced = parentPath.Left(pos); + + pos = parentPathReduced.ReverseFind_PathSepar(); + if (pos == 1) + { + if (!IS_PATH_SEPAR_CHAR(parentPath[0])) + return E_FAIL; + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr netFolder = netFolderSpec; + netFolderSpec->Init(fs2us(parentPath)); + *resultFolder = netFolder.Detach(); + return S_OK; + } + */ + + #endif + + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetNumberOfProperties(UInt32 *numProperties)) +{ + *numProperties = Z7_ARRAY_SIZE(kProps); + if (!_flatMode) + (*numProperties)--; + return S_OK; +} + +IMP_IFolderFolder_GetProp(CFSFolder::GetPropertyInfo, kProps) + +Z7_COM7F_IMF(CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidType: prop = "FSFolder"; break; + case kpidPath: prop = fs2us(_path); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +Z7_COM7F_IMF(CFSFolder::WasChanged(Int32 *wasChanged)) +{ + bool wasChangedMain = false; + + #ifdef _WIN32 + + for (;;) + { + if (!_findChangeNotification.IsHandleAllocated()) + break; + DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); + if (waitResult != WAIT_OBJECT_0) + break; + _findChangeNotification.FindNext(); + wasChangedMain = true; + } + + #endif + + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::Clone(IFolderFolder **resultFolder)) +{ + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr folderNew = fsFolderSpec; + fsFolderSpec->Init(_path); + *resultFolder = folderNew.Detach(); + return S_OK; +} + + +/* +HRESULT CFSFolder::GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress) +{ + if (index >= Files.Size()) + { + size = Streams[index - Files.Size()].Size; + return S_OK; + } + const CDirItem &fi = Files[index]; + if (fi.IsDir()) + { + UInt64 numFolders = 0, numFiles = 0; + size = 0; + return GetFolderSize(_path + GetRelPath(fi), numFolders, numFiles, size, progress); + } + size = fi.Size; + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress) +{ + NCOM::CPropVariant prop; + UInt64 size = 0; + HRESULT result = GetItemFullSize(index, size, progress); + prop = size; + prop.Detach(value); + return result; +} +*/ + +Z7_COM7F_IMF(CFSFolder::CalcItemFullSize(UInt32 index, IProgress *progress)) +{ + if (index >= Files.Size()) + return S_OK; + CDirItem &fi = Files[index]; + if (!fi.IsDir()) + return S_OK; + CFsFolderStat stat(_path + GetRelPath(fi), progress); + RINOK(stat.Enumerate()) + fi.Size = stat.Size; + fi.NumFolders = stat.NumFolders; + fi.NumFiles = stat.NumFiles; + fi.FolderStat_Defined = true; + return S_OK; +} + +void CFSFolder::GetAbsPath(const wchar_t *name, FString &absPath) +{ + absPath.Empty(); + if (!IsAbsolutePath(name)) + absPath += _path; + absPath += us2fs(name); +} + +Z7_COM7F_IMF(CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */)) +{ + FString absPath; + GetAbsPath(name, absPath); + if (CreateDir(absPath)) + return S_OK; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + if (CreateComplexDir(absPath)) + return S_OK; + return GetLastError_noZero_HRESULT(); +} + +Z7_COM7F_IMF(CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)) +{ + FString absPath; + GetAbsPath(name, absPath); + NIO::COutFile outFile; + if (!outFile.Create_NEW(absPath)) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */)) +{ + if (index >= Files.Size()) + return E_NOTIMPL; + const CDirItem &fi = Files[index]; + // FString prefix; + // GetPrefix(fi, prefix); + FString fullPrefix = _path; + if (fi.Parent >= 0) + fullPrefix += Folders[fi.Parent]; + if (!MyMoveFile(fullPrefix + fi.Name, fullPrefix + us2fs(newName))) + return GetLastError_noZero_HRESULT(); + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)) +{ + RINOK(progress->SetTotal(numItems)) + // int prevDeletedFileIndex = -1; + for (UInt32 i = 0; i < numItems; i++) + { + // Sleep(200); + UInt32 index = indices[i]; + bool result = true; + /* + if (index >= Files.Size()) + { + const CAltStream &ss = Streams[index - Files.Size()]; + if (prevDeletedFileIndex != ss.Parent) + { + const CDirItem &fi = Files[ss.Parent]; + result = DeleteFileAlways(_path + GetRelPath(fi) + us2fs(ss.Name)); + } + } + else + */ + { + const CDirItem &fi = Files[index]; + const FString fullPath = _path + GetRelPath(fi); + // prevDeletedFileIndex = index; + if (fi.IsDir()) + result = RemoveDirWithSubItems(fullPath); + else + result = DeleteFileAlways(fullPath); + } + if (!result) + return GetLastError_noZero_HRESULT(); + const UInt64 completed = i; + RINOK(progress->SetCompleted(&completed)) + } + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::SetProperty(UInt32 index, PROPID propID, + const PROPVARIANT *value, IProgress * /* progress */)) +{ + if (index >= Files.Size()) + return E_INVALIDARG; + CDirItem &fi = Files[index]; + if (fi.Parent >= 0) + return E_NOTIMPL; + switch (propID) + { + case kpidComment: + { + UString filename = fs2us(fi.Name); + filename.Trim(); + if (value->vt == VT_EMPTY) + _comments.DeletePair(filename); + else if (value->vt == VT_BSTR) + { + CTextPair pair; + pair.ID = filename; + pair.ID.Trim(); + pair.Value.SetFromBstr(value->bstrVal); + pair.Value.Trim(); + if (pair.Value.IsEmpty()) + _comments.DeletePair(filename); + else + _comments.AddPair(pair); + } + else + return E_INVALIDARG; + SaveComments(); + break; + } + default: + return E_NOTIMPL; + } + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +{ + *iconIndex = -1; + if (index >= Files.Size()) + return E_INVALIDARG; + const CDirItem &fi = Files[index]; + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + _path + GetRelPath(fi), fi.Attrib, iconIndex); +} + +Z7_COM7F_IMF(CFSFolder::SetFlatMode(Int32 flatMode)) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + +/* +Z7_COM7F_IMF(CFSFolder::SetShowNtfsStreamsMode(Int32 showStreamsMode) +{ + _scanAltStreams = IntToBool(showStreamsMode); + return S_OK; +} +*/ + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolder.h 2015-06-22 20:20:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolder.h 2024-07-09 09:00:00.000000000 +0000 @@ -1,215 +1,220 @@ -// FSFolder.h - -#ifndef __FS_FOLDER_H -#define __FS_FOLDER_H - -#include "../../../Common/MyCom.h" -#include "../../../Common/MyBuffer.h" - -#include "../../../Windows/FileFind.h" - -#include "../../Archive/IArchive.h" - -#include "IFolder.h" -#include "TextPairs.h" - -namespace NFsFolder { - -class CFSFolder; - -#ifdef _WIN32 -#define FS_SHOW_LINKS_INFO -#endif - -struct CDirItem: public NWindows::NFile::NFind::CFileInfo -{ - #ifndef UNDER_CE - UInt64 PackSize; - #endif - - #ifdef FS_SHOW_LINKS_INFO - UInt64 FileIndex; - UInt32 NumLinks; - bool FileInfo_Defined; - bool FileInfo_WasRequested; - #endif - - #ifndef UNDER_CE - bool PackSize_Defined; - #endif - - bool FolderStat_Defined; - - #ifndef UNDER_CE - CByteBuffer Reparse; - #endif - - UInt64 NumFolders; - UInt64 NumFiles; - - int Parent; -}; - -/* -struct CAltStream -{ - UInt64 Size; - UInt64 PackSize; - bool PackSize_Defined; - int Parent; - UString Name; -}; -*/ - -struct CFsFolderStat -{ - UInt64 NumFolders; - UInt64 NumFiles; - UInt64 Size; - IProgress *Progress; - FString Path; - - CFsFolderStat(): NumFolders(0), NumFiles(0), Size(0), Progress(NULL) {} - CFsFolderStat(const FString &path, IProgress *progress = NULL): - NumFolders(0), NumFiles(0), Size(0), Progress(progress), Path(path) {} - - HRESULT Enumerate(); -}; - -class CFSFolder: - public IFolderFolder, - public IArchiveGetRawProps, - public IFolderCompare, - #ifdef USE_UNICODE_FSTRING - public IFolderGetItemName, - #endif - public IFolderWasChanged, - public IFolderOperations, - // public IFolderOperationsDeleteToRecycleBin, - public IFolderCalcItemFullSize, - public IFolderClone, - public IFolderGetSystemIconIndex, - public IFolderSetFlatMode, - // public IFolderSetShowNtfsStreamsMode, - public CMyUnknownImp -{ -public: - MY_QUERYINTERFACE_BEGIN2(IFolderFolder) - MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps) - MY_QUERYINTERFACE_ENTRY(IFolderCompare) - #ifdef USE_UNICODE_FSTRING - MY_QUERYINTERFACE_ENTRY(IFolderGetItemName) - #endif - MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) - // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin) - MY_QUERYINTERFACE_ENTRY(IFolderOperations) - MY_QUERYINTERFACE_ENTRY(IFolderCalcItemFullSize) - MY_QUERYINTERFACE_ENTRY(IFolderClone) - MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) - MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) - // MY_QUERYINTERFACE_ENTRY(IFolderSetShowNtfsStreamsMode) - MY_QUERYINTERFACE_END - MY_ADDREF_RELEASE - - - INTERFACE_FolderFolder(;) - INTERFACE_IArchiveGetRawProps(;) - INTERFACE_FolderOperations(;) - - STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); - - #ifdef USE_UNICODE_FSTRING - INTERFACE_IFolderGetItemName(;) - #endif - STDMETHOD(WasChanged)(Int32 *wasChanged); - STDMETHOD(Clone)(IFolderFolder **resultFolder); - STDMETHOD(CalcItemFullSize)(UInt32 index, IProgress *progress); - - STDMETHOD(SetFlatMode)(Int32 flatMode); - // STDMETHOD(SetShowNtfsStreamsMode)(Int32 showStreamsMode); - - STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex); - -private: - FString _path; - - CObjectVector Files; - FStringVector Folders; - // CObjectVector Streams; - // CMyComPtr _parentFolder; - - bool _commentsAreLoaded; - CPairsStorage _comments; - - // bool _scanAltStreams; - bool _flatMode; - - // FIXME NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; - - HRESULT GetItemsFullSize(const UInt32 *indices, UInt32 numItems, CFsFolderStat &stat); - - HRESULT GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress); - void GetAbsPath(const wchar_t *name, FString &absPath); - HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder); - - bool LoadComments(); - bool SaveComments(); - HRESULT LoadSubItems(int dirItem, const FString &path); - - #ifdef FS_SHOW_LINKS_INFO - bool ReadFileInfo(CDirItem &di); - #endif - -public: - HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */); - #if !defined(_WIN32) || defined(UNDER_CE) - HRESULT InitToRoot() { return Init(FSTRING_PATH_SEPARATOR /* , NULL */); } - #endif - - CFSFolder() : _flatMode(false) - // , _scanAltStreams(false) - {} - - void GetFullPath(const CDirItem &item, FString &path) const - { - // FString prefix; - // GetPrefix(item, prefix); - path = _path; - if (item.Parent >= 0) - path += Folders[item.Parent]; - path += item.Name; - } - - // void GetPrefix(const CDirItem &item, FString &prefix) const; - - FString GetRelPath(const CDirItem &item) const; - - void Clear() - { - Files.Clear(); - Folders.Clear(); - // Streams.Clear(); - } -}; - -struct CCopyStateIO -{ - IProgress *Progress; - UInt64 TotalSize; - UInt64 StartPos; - UInt64 CurrentSize; - bool DeleteSrcFile; - - int ErrorFileIndex; - UString ErrorMessage; - - CCopyStateIO(): DeleteSrcFile(false), TotalSize(0), StartPos(0) {} - - HRESULT MyCopyFile(CFSTR inPath, CFSTR outPath); -}; - -HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName); - -} - -#endif +// FSFolder.h + +#ifndef ZIP7_INC_FS_FOLDER_H +#define ZIP7_INC_FS_FOLDER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyBuffer.h" + +#include "../../../Windows/FileFind.h" + +#include "../../Archive/IArchive.h" + +#include "IFolder.h" +#include "TextPairs.h" + +namespace NFsFolder { + +class CFSFolder; + +#define FS_SHOW_LINKS_INFO +// #define FS_SHOW_CHANGE_TIME + +struct CDirItem: public NWindows::NFile::NFind::CFileInfo +{ +#ifndef UNDER_CE + UInt64 PackSize; +#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 + bool PackSize_Defined; +#endif + + bool FolderStat_Defined; + int Parent; + +#ifndef UNDER_CE + CByteBuffer Reparse; +#endif + + UInt64 NumFolders; + UInt64 NumFiles; +}; + +/* +struct CAltStream +{ + UInt64 Size; + UInt64 PackSize; + bool PackSize_Defined; + int Parent; + UString Name; +}; +*/ + +struct CFsFolderStat +{ + UInt64 NumFolders; + UInt64 NumFiles; + UInt64 Size; + IProgress *Progress; + FString Path; + + CFsFolderStat(): NumFolders(0), NumFiles(0), Size(0), Progress(NULL) {} + CFsFolderStat(const FString &path, IProgress *progress = NULL): + NumFolders(0), NumFiles(0), Size(0), Progress(progress), Path(path) {} + + HRESULT Enumerate(); +}; + +class CFSFolder Z7_final: + public IFolderFolder, + public IArchiveGetRawProps, + public IFolderCompare, + #ifdef USE_UNICODE_FSTRING + public IFolderGetItemName, + #endif + public IFolderWasChanged, + public IFolderOperations, + // public IFolderOperationsDeleteToRecycleBin, + public IFolderCalcItemFullSize, + public IFolderClone, + public IFolderGetSystemIconIndex, + public IFolderSetFlatMode, + // public IFolderSetShowNtfsStreamsMode, + public CMyUnknownImp +{ + Z7_COM_QI_BEGIN2(IFolderFolder) + Z7_COM_QI_ENTRY(IArchiveGetRawProps) + Z7_COM_QI_ENTRY(IFolderCompare) + #ifdef USE_UNICODE_FSTRING + Z7_COM_QI_ENTRY(IFolderGetItemName) + #endif + Z7_COM_QI_ENTRY(IFolderWasChanged) + // Z7_COM_QI_ENTRY(IFolderOperationsDeleteToRecycleBin) + Z7_COM_QI_ENTRY(IFolderOperations) + Z7_COM_QI_ENTRY(IFolderCalcItemFullSize) + Z7_COM_QI_ENTRY(IFolderClone) + Z7_COM_QI_ENTRY(IFolderGetSystemIconIndex) + Z7_COM_QI_ENTRY(IFolderSetFlatMode) + // Z7_COM_QI_ENTRY(IFolderSetShowNtfsStreamsMode) + Z7_COM_QI_END + Z7_COM_ADDREF_RELEASE + + Z7_IFACE_COM7_IMP(IFolderFolder) + Z7_IFACE_COM7_IMP(IArchiveGetRawProps) + Z7_IFACE_COM7_IMP(IFolderCompare) + #ifdef USE_UNICODE_FSTRING + Z7_IFACE_COM7_IMP(IFolderGetItemName) + #endif + Z7_IFACE_COM7_IMP(IFolderWasChanged) + Z7_IFACE_COM7_IMP(IFolderOperations) + Z7_IFACE_COM7_IMP(IFolderCalcItemFullSize) + Z7_IFACE_COM7_IMP(IFolderClone) + Z7_IFACE_COM7_IMP(IFolderGetSystemIconIndex) + Z7_IFACE_COM7_IMP(IFolderSetFlatMode) + // Z7_IFACE_COM7_IMP(IFolderSetShowNtfsStreamsMode) + + bool _flatMode; + bool _commentsAreLoaded; + // bool _scanAltStreams; + + FString _path; + CObjectVector Files; + FStringVector Folders; + // CObjectVector Streams; + // CMyComPtr _parentFolder; + + CPairsStorage _comments; + + #ifdef _WIN32 + NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; + #endif + + // HRESULT GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress); + void GetAbsPath(const wchar_t *name, FString &absPath); + HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder); + + bool LoadComments(); + bool SaveComments(); + HRESULT LoadSubItems(int dirItem, const FString &path); + + #ifdef FS_SHOW_LINKS_INFO + bool ReadFileInfo(CDirItem &di); + void ReadChangeTime(CDirItem &di); + #endif + +public: + HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */); + #if !defined(_WIN32) || defined(UNDER_CE) + HRESULT InitToRoot() { return Init((FString) FSTRING_PATH_SEPARATOR /* , NULL */); } + #endif + + CFSFolder(): + _flatMode(false), + _commentsAreLoaded(false) + // , _scanAltStreams(false) + {} + + void GetFullPath(const CDirItem &item, FString &path) const + { + // FString prefix; + // GetPrefix(item, prefix); + path = _path; + if (item.Parent >= 0) + path += Folders[item.Parent]; + path += item.Name; + } + + // void GetPrefix(const CDirItem &item, FString &prefix) const; + + FString GetRelPath(const CDirItem &item) const; + + void Clear() + { + Files.Clear(); + Folders.Clear(); + // Streams.Clear(); + } +}; + +struct CCopyStateIO +{ + IProgress *Progress; + UInt64 TotalSize; + UInt64 StartPos; + UInt64 CurrentSize; + bool DeleteSrcFile; + + int ErrorFileIndex; + UString ErrorMessage; + + CCopyStateIO(): TotalSize(0), StartPos(0), DeleteSrcFile(false) {} + + HRESULT MyCopyFile(CFSTR inPath, CFSTR outPath, DWORD attrib = INVALID_FILE_ATTRIBUTES); +}; + +HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName); + +/* destDirPrefix is allowed to be: + "full_path\" or "full_path:" for alt streams */ + +HRESULT CopyFileSystemItems( + const UStringVector &itemsPaths, + const FString &destDirPrefix, + bool moveMode, + IFolderOperationsExtractCallback *callback); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolderCopy.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolderCopy.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FSFolderCopy.cpp 2015-09-08 21:14:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FSFolderCopy.cpp 2024-07-16 17:00:00.000000000 +0000 @@ -1,707 +1,871 @@ -// FSFolderCopy.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyWindows.h" - -#ifdef _WIN32 -#include -#endif - -#include "../../../Common/Defs.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" - -#include "../../Common/FilePathAutoRename.h" - -#include "FSFolder.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; -using namespace NName; -using namespace NFind; - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -namespace NFsFolder { - -HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath) -{ - ErrorFileIndex = -1; - ErrorMessage.Empty(); - CurrentSize = 0; - - { - const size_t kBufSize = 1 << 16; - CByteArr buf(kBufSize); - - NIO::CInFile inFile; - NIO::COutFile outFile; - - if (!inFile.Open(inPath)) - { - ErrorFileIndex = 0; - return S_OK; - } - - if (!outFile.Create(outPath, true)) - { - ErrorFileIndex = 1; - return S_OK; - } - - for (;;) - { - UInt32 num; - if (!inFile.Read(buf, kBufSize, num)) - { - ErrorFileIndex = 0; - return S_OK; - } - if (num == 0) - break; - - UInt32 written = 0; - if (!outFile.Write(buf, num, written)) - { - ErrorFileIndex = 1; - return S_OK; - } - if (written != num) - { - ErrorMessage = L"Write error"; - return S_OK; - } - CurrentSize += num; - if (Progress) - { - UInt64 completed = StartPos + CurrentSize; - RINOK(Progress->SetCompleted(&completed)); - } - } - } - - if (DeleteSrcFile) - { - if (!DeleteFileAlways(inPath)) - { - ErrorFileIndex = 0; - return S_OK; - } - } - - return S_OK; -} - - -/* -static bool IsItWindows2000orHigher() -{ - OSVERSIONINFO versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); - if (!::GetVersionEx(&versionInfo)) - return false; - return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && - (versionInfo.dwMajorVersion >= 5); -} -*/ - -struct CProgressInfo -{ - UInt64 TotalSize; - UInt64 StartPos; - UInt64 FileSize; - IProgress *Progress; - HRESULT ProgressResult; - - void Init() { ProgressResult = S_OK; } -}; - -#ifdef _WIN32 - -#ifndef PROGRESS_CONTINUE - -#define PROGRESS_CONTINUE 0 -#define PROGRESS_CANCEL 1 - -#define COPY_FILE_FAIL_IF_EXISTS 0x00000001 - -typedef -DWORD -(WINAPI* LPPROGRESS_ROUTINE)( - LARGE_INTEGER TotalFileSize, - LARGE_INTEGER TotalBytesTransferred, - LARGE_INTEGER StreamSize, - LARGE_INTEGER StreamBytesTransferred, - DWORD dwStreamNumber, - DWORD dwCallbackReason, - HANDLE hSourceFile, - HANDLE hDestinationFile, - LPVOID lpData - ); - -#endif - -static DWORD CALLBACK CopyProgressRoutine( - LARGE_INTEGER TotalFileSize, // file size - LARGE_INTEGER TotalBytesTransferred, // bytes transferred - LARGE_INTEGER /* StreamSize */, // bytes in stream - LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream - DWORD /* dwStreamNumber */, // current stream - DWORD /* dwCallbackReason */, // callback reason - HANDLE /* hSourceFile */, // handle to source file - HANDLE /* hDestinationFile */, // handle to destination file - LPVOID lpData // from CopyFileEx -) -{ - TotalFileSize = TotalFileSize; - // TotalBytesTransferred = TotalBytesTransferred; - // StreamSize = StreamSize; - // StreamBytesTransferred = StreamBytesTransferred; - // dwStreamNumber = dwStreamNumber; - // dwCallbackReason = dwCallbackReason; - - CProgressInfo &pi = *(CProgressInfo *)lpData; - - if ((UInt64)TotalFileSize.QuadPart > pi.FileSize) - { - pi.TotalSize += (UInt64)TotalFileSize.QuadPart - pi.FileSize; - pi.FileSize = (UInt64)TotalFileSize.QuadPart; - pi.ProgressResult = pi.Progress->SetTotal(pi.TotalSize); - } - UInt64 completed = pi.StartPos + TotalBytesTransferred.QuadPart; - pi.ProgressResult = pi.Progress->SetCompleted(&completed); - return (pi.ProgressResult == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL); -} - -typedef BOOL (WINAPI * Func_CopyFileExA)( - IN LPCSTR lpExistingFileName, - IN LPCSTR lpNewFileName, - IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, - IN LPVOID lpData OPTIONAL, - IN LPBOOL pbCancel OPTIONAL, - IN DWORD dwCopyFlags - ); - -typedef BOOL (WINAPI * Func_CopyFileExW)( - IN LPCWSTR lpExistingFileName, - IN LPCWSTR lpNewFileName, - IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, - IN LPVOID lpData OPTIONAL, - IN LPBOOL pbCancel OPTIONAL, - IN DWORD dwCopyFlags - ); - -typedef BOOL (WINAPI * Func_MoveFileWithProgressW)( - IN LPCWSTR lpExistingFileName, - IN LPCWSTR lpNewFileName, - IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, - IN LPVOID lpData OPTIONAL, - IN DWORD dwFlags - ); - -struct CCopyState -{ - CProgressInfo ProgressInfo; - IFolderOperationsExtractCallback *Callback; - UInt64 TotalSize; - bool MoveMode; - bool UseReadWriteMode; - - Func_CopyFileExW my_CopyFileExW; - #ifndef UNDER_CE - Func_MoveFileWithProgressW my_MoveFileWithProgressW; - #endif - #ifndef _UNICODE - Func_CopyFileExA my_CopyFileExA; - #endif - - void Prepare(); - bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile); - bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile); - bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile); - - HRESULT CallProgress(); - - bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; } -}; -#else -struct CCopyState -{ - CProgressInfo ProgressInfo; - IFolderOperationsExtractCallback *Callback; - UInt64 TotalSize; - bool MoveMode; - bool UseReadWriteMode; - HRESULT CallProgress(); - - void Prepare(); - bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile); - bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile); - bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile); - - bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; } -}; -#endif - -HRESULT CCopyState::CallProgress() -{ - return ProgressInfo.Progress->SetCompleted(&ProgressInfo.StartPos); -} - - -void CCopyState::Prepare() -{ -#ifdef _WIN32 - my_CopyFileExW = NULL; - #ifndef UNDER_CE - my_MoveFileWithProgressW = NULL; - #endif - #ifndef _UNICODE - my_CopyFileExA = NULL; - if (!g_IsNT) - { - my_CopyFileExA = (Func_CopyFileExA)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "CopyFileExA"); - } - else - #endif - { - HMODULE module = ::GetModuleHandleW( - #ifdef UNDER_CE - L"coredll.dll" - #else - L"kernel32.dll" - #endif - ); - my_CopyFileExW = (Func_CopyFileExW)My_GetProcAddress(module, "CopyFileExW"); - #ifndef UNDER_CE - my_MoveFileWithProgressW = (Func_MoveFileWithProgressW)My_GetProcAddress(module, "MoveFileWithProgressW"); - #endif - } -#endif -} - -/* WinXP-64: - CopyFileW(fromFile, toFile:altStream) - OK - there are NO alt streams in fromFile - ERROR_INVALID_PARAMETER - there are alt streams in fromFile -*/ - -bool CCopyState::CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile) -{ -#ifdef _WIN32 - BOOL cancelFlag = FALSE; - if (my_CopyFileExW) - return BOOLToBool(my_CopyFileExW(oldFile, newFile, CopyProgressRoutine, - &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS)); - return BOOLToBool(::CopyFileW(oldFile, newFile, TRUE)); -#else - - extern bool wxw_CopyFile(LPCWSTR existingFile, LPCWSTR newFile, bool overwrite); - return wxw_CopyFile(oldFile, newFile, true); - -#endif -} - - -bool CCopyState::CopyFile_Sys(CFSTR oldFile, CFSTR newFile) -{ -#ifdef _WIN32 - #ifndef _UNICODE - if (!g_IsNT) - { - if (my_CopyFileExA) - { - BOOL cancelFlag = FALSE; - if (my_CopyFileExA(fs2fas(oldFile), fs2fas(newFile), - CopyProgressRoutine, &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS)) - return true; - if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return false; - } - return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE)); - } - else - #endif - { - IF_USE_MAIN_PATH_2(oldFile, newFile) - { - if (CopyFile_NT(fs2us(oldFile), fs2us(newFile))) - return true; - } - #ifdef WIN_LONG_PATH - if (USE_SUPER_PATH_2) - { - if (IsCallbackProgressError()) - return false; - UString superPathOld, superPathNew; - if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2)) - return false; - if (CopyFile_NT(superPathOld, superPathNew)) - return true; - } - #endif - return false; - } -#else - - extern bool wxw_CopyFile(LPCWSTR existingFile, LPCWSTR newFile, bool overwrite); - return wxw_CopyFile(oldFile, newFile, true); - -#endif -} - -bool CCopyState::MoveFile_Sys(CFSTR oldFile, CFSTR newFile) -{ - #if 0 // FIXME #ifndef UNDER_CE - // if (IsItWindows2000orHigher()) - // { - if (my_MoveFileWithProgressW) - { - IF_USE_MAIN_PATH_2(oldFile, newFile) - { - if (my_MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine, - &ProgressInfo, MOVEFILE_COPY_ALLOWED)) - return true; - } - #ifdef WIN_LONG_PATH - if ((!(USE_MAIN_PATH_2) || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) && USE_SUPER_PATH_2) - { - if (IsCallbackProgressError()) - return false; - UString superPathOld, superPathNew; - if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2)) - return false; - if (my_MoveFileWithProgressW(superPathOld, superPathNew, CopyProgressRoutine, - &ProgressInfo, MOVEFILE_COPY_ALLOWED)) - return true; - } - #endif - if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return false; - } - // } - // else - #endif - return MyMoveFile(oldFile, newFile); -} - -static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, - const wchar_t *message, const FString &fileName) -{ - UString s = message; - s += L" : "; - s += fs2us(fileName); - return callback->ShowMessage(s); -} - -static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, - const char *message, const FString &fileName) -{ - return SendMessageError(callback, MultiByteToUnicodeString(message), fileName); -} - -static DWORD Return_LastError_or_FAIL() -{ - DWORD errorCode = GetLastError(); - if (errorCode == 0) - errorCode = (DWORD)E_FAIL; - return errorCode; -} - -static UString GetLastErrorMessage() -{ - return NError::MyFormatMessage(Return_LastError_or_FAIL()); -} - -HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName) -{ - return SendMessageError(callback, GetLastErrorMessage(), fileName); -} - -static HRESULT CopyFile_Ask( - CCopyState &state, - const FString &srcPath, - const CFileInfo &srcFileInfo, - const FString &destPath) -{ - if (CompareFileNames(destPath, srcPath) == 0) - { - RINOK(SendMessageError(state.Callback, - state.MoveMode ? - "can not move file onto itself" : - "can not copy file onto itself" - , destPath)); - return E_ABORT; - } - - Int32 writeAskResult; - CMyComBSTR destPathResult; - RINOK(state.Callback->AskWrite( - fs2us(srcPath), - BoolToInt(false), - &srcFileInfo.MTime, &srcFileInfo.Size, - fs2us(destPath), - &destPathResult, - &writeAskResult)); - - if (IntToBool(writeAskResult)) - { - FString destPathNew = us2fs((LPCOLESTR)destPathResult); - RINOK(state.Callback->SetCurrentFilePath(fs2us(srcPath))); - - if (state.UseReadWriteMode) - { - NFsFolder::CCopyStateIO state2; - state2.Progress = state.Callback; - state2.DeleteSrcFile = state.MoveMode; - state2.TotalSize = state.TotalSize; - state2.StartPos = state.ProgressInfo.StartPos; - RINOK(state2.MyCopyFile(srcPath, destPathNew)); - if (state2.ErrorFileIndex >= 0) - { - if (state2.ErrorMessage.IsEmpty()) - state2.ErrorMessage = GetLastErrorMessage(); - FString errorName; - if (state2.ErrorFileIndex == 0) - errorName = srcPath; - else - errorName = destPathNew; - RINOK(SendMessageError(state.Callback, state2.ErrorMessage, errorName)); - return E_ABORT; - } - state.ProgressInfo.StartPos += state2.CurrentSize; - } - else - { - state.ProgressInfo.FileSize = srcFileInfo.Size; - bool res; - if (state.MoveMode) - res = state.MoveFile_Sys(srcPath, destPathNew); - else - res = state.CopyFile_Sys(srcPath, destPathNew); - RINOK(state.ProgressInfo.ProgressResult); - if (!res) - { - // GetLastError() is ERROR_REQUEST_ABORTED in case of PROGRESS_CANCEL. - RINOK(SendMessageError(state.Callback, GetLastErrorMessage(), destPathNew)); - return E_ABORT; - } - state.ProgressInfo.StartPos += state.ProgressInfo.FileSize; - } - } - else - { - if (state.TotalSize >= srcFileInfo.Size) - { - state.TotalSize -= srcFileInfo.Size; - RINOK(state.ProgressInfo.Progress->SetTotal(state.TotalSize)); - } - } - return state.CallProgress(); -} - -static FString CombinePath(const FString &folderPath, const FString &fileName) -{ - return folderPath + FCHAR_PATH_SEPARATOR + fileName; -} - -static bool IsDestChild(const FString &src, const FString &dest) -{ - unsigned len = src.Len(); - if (dest.Len() < len) - return false; - if (dest.Len() != len && dest[len] != FCHAR_PATH_SEPARATOR) - return false; - return CompareFileNames(dest.Left(len), src) == 0; -} - -static HRESULT CopyFolder( - CCopyState &state, - const FString &srcPath, // without TAIL separator - const FString &destPath) // without TAIL separator -{ - RINOK(state.CallProgress()); - - if (IsDestChild(srcPath, destPath)) - { - RINOK(SendMessageError(state.Callback, - state.MoveMode ? - "can not copy folder onto itself" : - "can not move folder onto itself" - , destPath)); - return E_ABORT; - } - - if (state.MoveMode) - { - if (state.MoveFile_Sys(srcPath, destPath)) - return S_OK; - - // MSDN: MoveFile() fails for dirs on different volumes. - } - - if (!CreateComplexDir(destPath)) - { - RINOK(SendMessageError(state.Callback, "can not create folder", destPath)); - return E_ABORT; - } - - CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK)); - - for (;;) - { - NFind::CFileInfo fi; - bool found; - if (!enumerator.Next(fi, found)) - { - SendLastErrorMessage(state.Callback, srcPath); - return S_OK; - } - if (!found) - break; - const FString srcPath2 = CombinePath(srcPath, fi.Name); - const FString destPath2 = CombinePath(destPath, fi.Name); - if (fi.IsDir()) - { - RINOK(CopyFolder(state, srcPath2, destPath2)) - } - else - { - RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2)); - } - } - - if (state.MoveMode) - { - if (!RemoveDir(srcPath)) - { - RINOK(SendMessageError(state.Callback, "can not remove folder", srcPath)); - return E_ABORT; - } - } - - return S_OK; -} - -STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, - Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, - const wchar_t *path, IFolderOperationsExtractCallback *callback) -{ - if (numItems == 0) - return S_OK; - - FString destPath = us2fs(path); - if (destPath.IsEmpty()) - return E_INVALIDARG; - - bool isAltDest = false; // FIXME NName::IsAltPathPrefix(destPath);; - bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); - - if (isDirectPath) - { - if (numItems > 1) - return E_INVALIDARG; - } - - CFsFolderStat stat; - stat.Progress = callback; - RINOK(GetItemsFullSize(indices, numItems, stat)); - - if (stat.NumFolders != 0 && isAltDest) - return E_NOTIMPL; - - RINOK(callback->SetTotal(stat.Size)); - RINOK(callback->SetNumFiles(stat.NumFiles)); - - UInt64 completedSize = 0; - RINOK(callback->SetCompleted(&completedSize)); - - CCopyState state; - state.ProgressInfo.TotalSize = stat.Size; - state.ProgressInfo.StartPos = 0; - state.ProgressInfo.Progress = callback; - state.ProgressInfo.Init(); - state.Callback = callback; - state.MoveMode = IntToBool(moveMode); - state.UseReadWriteMode = isAltDest; - state.Prepare(); - - for (UInt32 i = 0; i < numItems; i++) - { - UInt32 index = indices[i]; - if (index >= (UInt32)Files.Size()) - continue; - const CDirItem &fi = Files[index]; - FString destPath2 = destPath; - if (!isDirectPath) - destPath2 += fi.Name; - FString srcPath; - GetFullPath(fi, srcPath); - - if (fi.IsDir()) - { - RINOK(CopyFolder(state, srcPath, destPath2)); - } - else - { - RINOK(CopyFile_Ask(state, srcPath, fi, destPath2)); - } - } - return S_OK; -} - -STDMETHODIMP CFSFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, - const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) -{ - /* - UInt64 numFolders, numFiles, totalSize; - numFiles = numFolders = totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - { - UString path = (UString)fromFolderPath + itemsPaths[i]; - - CFileInfo fi; - if (!FindFile(path, fi)) - return ::GetLastError(); - if (fi.IsDir()) - { - UInt64 subFolders, subFiles, subSize; - RINOK(GetFolderSize(CombinePath(path, fi.Name), subFolders, subFiles, subSize, progress)); - numFolders += subFolders; - numFolders++; - numFiles += subFiles; - totalSize += subSize; - } - else - { - numFiles++; - totalSize += fi.Size; - } - } - RINOK(progress->SetTotal(totalSize)); - RINOK(callback->SetNumFiles(numFiles)); - for (i = 0; i < numItems; i++) - { - UString path = (UString)fromFolderPath + itemsPaths[i]; - } - return S_OK; - */ - return E_NOTIMPL; -} - -STDMETHODIMP CFSFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */) -{ - return E_NOTIMPL; -} - -} +// FSFolderCopy.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#include "../../../Common/Defs.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "FSFolder.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; +using namespace NName; +using namespace NFind; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NFsFolder { + +static const char * const k_CannotCopyDirToAltStream = "Cannot copy folder as alternate stream"; + + +HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath, DWORD attrib) +{ + ErrorFileIndex = -1; + ErrorMessage.Empty(); + CurrentSize = 0; + + { + const size_t kBufSize = 1 << 16; + CByteArr buf(kBufSize); + + NIO::CInFile inFile; + NIO::COutFile outFile; + + if (!inFile.Open(inPath)) + { + ErrorFileIndex = 0; + return S_OK; + } + + if (!outFile.Create_ALWAYS(outPath)) + { + ErrorFileIndex = 1; + return S_OK; + } + + for (;;) + { + UInt32 num; + if (!inFile.Read(buf, kBufSize, num)) + { + ErrorFileIndex = 0; + return S_OK; + } + if (num == 0) + break; + + UInt32 written = 0; + if (!outFile.Write(buf, num, written)) + { + ErrorFileIndex = 1; + return S_OK; + } + if (written != num) + { + ErrorMessage = "Write error"; + return S_OK; + } + CurrentSize += num; + if (Progress) + { + UInt64 completed = StartPos + CurrentSize; + RINOK(Progress->SetCompleted(&completed)) + } + } + } + + /* SetFileAttrib("path:alt_stream_name") sets attributes for main file "path". + But we don't want to change attributes of main file, when we write alt stream. + So we need INVALID_FILE_ATTRIBUTES for alt stream here */ + + if (attrib != INVALID_FILE_ATTRIBUTES) + SetFileAttrib(outPath, attrib); + + if (DeleteSrcFile) + { + if (!DeleteFileAlways(inPath)) + { + ErrorFileIndex = 0; + return S_OK; + } + } + + return S_OK; +} + + +/* +static bool IsItWindows2000orHigher() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && + (versionInfo.dwMajorVersion >= 5); +} +*/ + +struct CProgressInfo +{ + UInt64 TotalSize; + UInt64 StartPos; + UInt64 FileSize; + IProgress *Progress; + HRESULT ProgressResult; + + void Init() { ProgressResult = S_OK; } +}; + +#ifndef PROGRESS_CONTINUE + +#define PROGRESS_CONTINUE 0 +#define PROGRESS_CANCEL 1 + +#define COPY_FILE_FAIL_IF_EXISTS 0x00000001 + +typedef +DWORD +(WINAPI* LPPROGRESS_ROUTINE)( + LARGE_INTEGER TotalFileSize, + LARGE_INTEGER TotalBytesTransferred, + LARGE_INTEGER StreamSize, + LARGE_INTEGER StreamBytesTransferred, + DWORD dwStreamNumber, + DWORD dwCallbackReason, + HANDLE hSourceFile, + HANDLE hDestinationFile, + LPVOID lpData + ); + +#endif + +static DWORD CALLBACK CopyProgressRoutine( + LARGE_INTEGER TotalFileSize, // file size + LARGE_INTEGER TotalBytesTransferred, // bytes transferred + LARGE_INTEGER /* StreamSize */, // bytes in stream + LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream + DWORD /* dwStreamNumber */, // current stream + DWORD /* dwCallbackReason */, // callback reason + HANDLE /* hSourceFile */, // handle to source file + HANDLE /* hDestinationFile */, // handle to destination file + LPVOID lpData // from CopyFileEx +) +{ + // StreamSize = StreamSize; + // StreamBytesTransferred = StreamBytesTransferred; + // dwStreamNumber = dwStreamNumber; + // dwCallbackReason = dwCallbackReason; + + CProgressInfo &pi = *(CProgressInfo *)lpData; + + if ((UInt64)TotalFileSize.QuadPart > pi.FileSize) + { + pi.TotalSize += (UInt64)TotalFileSize.QuadPart - pi.FileSize; + pi.FileSize = (UInt64)TotalFileSize.QuadPart; + pi.ProgressResult = pi.Progress->SetTotal(pi.TotalSize); + } + const UInt64 completed = pi.StartPos + (UInt64)TotalBytesTransferred.QuadPart; + pi.ProgressResult = pi.Progress->SetCompleted(&completed); + return (pi.ProgressResult == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL); +} + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000 +#define Z7_USE_DYN_MoveFileWithProgressW +#endif + +#ifdef Z7_USE_DYN_MoveFileWithProgressW +// nt4 +typedef BOOL (WINAPI * Func_CopyFileExA)( + IN LPCSTR lpExistingFileName, + IN LPCSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +// nt4 +typedef BOOL (WINAPI * Func_CopyFileExW)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +// win2000 +typedef BOOL (WINAPI * Func_MoveFileWithProgressW)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN DWORD dwFlags + ); +#endif + +struct CCopyState +{ + CProgressInfo ProgressInfo; + IFolderOperationsExtractCallback *Callback; + bool MoveMode; + bool UseReadWriteMode; + bool IsAltStreamsDest; + +#ifdef Z7_USE_DYN_MoveFileWithProgressW +private: + Func_CopyFileExW my_CopyFileExW; + #ifndef UNDER_CE + Func_MoveFileWithProgressW my_MoveFileWithProgressW; + #endif + #ifndef _UNICODE + Func_CopyFileExA my_CopyFileExA; + #endif +public: + CCopyState(); +#endif + + bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile); + bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile); + bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile); + + HRESULT CallProgress(); + + bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; } +}; + +HRESULT CCopyState::CallProgress() +{ + return ProgressInfo.Progress->SetCompleted(&ProgressInfo.StartPos); +} + +#ifdef Z7_USE_DYN_MoveFileWithProgressW + +CCopyState::CCopyState() +{ + my_CopyFileExW = NULL; + #ifndef UNDER_CE + my_MoveFileWithProgressW = NULL; + #endif + #ifndef _UNICODE + my_CopyFileExA = NULL; + if (!g_IsNT) + { + my_CopyFileExA = Z7_GET_PROC_ADDRESS( + Func_CopyFileExA, ::GetModuleHandleA("kernel32.dll"), + "CopyFileExA"); + } + else + #endif + { + const HMODULE module = ::GetModuleHandleW( + #ifdef UNDER_CE + L"coredll.dll" + #else + L"kernel32.dll" + #endif + ); + my_CopyFileExW = Z7_GET_PROC_ADDRESS( + Func_CopyFileExW, module, + "CopyFileExW"); + #ifndef UNDER_CE + my_MoveFileWithProgressW = Z7_GET_PROC_ADDRESS( + Func_MoveFileWithProgressW, module, + "MoveFileWithProgressW"); + #endif + } +} + +#endif + +/* WinXP-64: + CopyFileW(fromFile, toFile:altStream) + OK - there are NO alt streams in fromFile + ERROR_INVALID_PARAMETER - there are alt streams in fromFile +*/ + +bool CCopyState::CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile) +{ + BOOL cancelFlag = FALSE; +#ifdef Z7_USE_DYN_MoveFileWithProgressW + if (my_CopyFileExW) +#endif + return BOOLToBool( +#ifdef Z7_USE_DYN_MoveFileWithProgressW + my_CopyFileExW +#else + CopyFileExW +#endif + (oldFile, newFile, CopyProgressRoutine, + &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS)); +#ifdef Z7_USE_DYN_MoveFileWithProgressW + return BOOLToBool(::CopyFileW(oldFile, newFile, TRUE)); +#endif +} + +bool CCopyState::CopyFile_Sys(CFSTR oldFile, CFSTR newFile) +{ + #ifndef _UNICODE + if (!g_IsNT) + { +#ifdef Z7_USE_DYN_MoveFileWithProgressW + if (my_CopyFileExA) +#endif + { + BOOL cancelFlag = FALSE; + if ( +#ifdef Z7_USE_DYN_MoveFileWithProgressW + my_CopyFileExA +#else + CopyFileExA +#endif + (fs2fas(oldFile), fs2fas(newFile), + CopyProgressRoutine, &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE)); + } + else + #endif + { + IF_USE_MAIN_PATH_2(oldFile, newFile) + { + if (CopyFile_NT(fs2us(oldFile), fs2us(newFile))) + return true; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH_2) + { + if (IsCallbackProgressError()) + return false; + UString superPathOld, superPathNew; + if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2)) + return false; + if (CopyFile_NT(superPathOld, superPathNew)) + return true; + } + #endif + return false; + } +} + +bool CCopyState::MoveFile_Sys(CFSTR oldFile, CFSTR newFile) +{ + #ifndef UNDER_CE + // if (IsItWindows2000orHigher()) + // { +#ifdef Z7_USE_DYN_MoveFileWithProgressW + if (my_MoveFileWithProgressW) +#endif + { + IF_USE_MAIN_PATH_2(oldFile, newFile) + { + if ( +#ifdef Z7_USE_DYN_MoveFileWithProgressW + my_MoveFileWithProgressW +#else + MoveFileWithProgressW +#endif + (fs2us(oldFile), fs2us(newFile), CopyProgressRoutine, + &ProgressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + } + #ifdef Z7_LONG_PATH + if ((!(USE_MAIN_PATH_2) || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) && USE_SUPER_PATH_2) + { + if (IsCallbackProgressError()) + return false; + UString superPathOld, superPathNew; + if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2)) + return false; + if ( +#ifdef Z7_USE_DYN_MoveFileWithProgressW + my_MoveFileWithProgressW +#else + MoveFileWithProgressW +#endif + (superPathOld, superPathNew, CopyProgressRoutine, + &ProgressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + } + #endif + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + // } + // else + #endif + return MyMoveFile(oldFile, newFile); +} + +static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, + const wchar_t *message, const FString &fileName) +{ + UString s = message; + s += " : "; + s += fs2us(fileName); + return callback->ShowMessage(s); +} + +static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback, + const char *message, const FString &fileName) +{ + return SendMessageError(callback, MultiByteToUnicodeString(message), fileName); +} + +static DWORD Return_LastError_or_FAIL() +{ + DWORD errorCode = GetLastError(); + if (errorCode == 0) + errorCode = (DWORD)E_FAIL; + return errorCode; +} + +static UString GetLastErrorMessage() +{ + return NError::MyFormatMessage(Return_LastError_or_FAIL()); +} + +HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName) +{ + return SendMessageError(callback, GetLastErrorMessage(), fileName); +} + +static HRESULT CopyFile_Ask( + CCopyState &state, + const FString &srcPath, + const CFileInfo &srcFileInfo, + const FString &destPath) +{ + if (CompareFileNames(destPath, srcPath) == 0) + { + RINOK(SendMessageError(state.Callback, + state.MoveMode ? + "Cannot move file onto itself" : + "Cannot copy file onto itself" + , destPath)) + return E_ABORT; + } + + Int32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(state.Callback->AskWrite( + fs2us(srcPath), + BoolToInt(false), + &srcFileInfo.MTime, &srcFileInfo.Size, + fs2us(destPath), + &destPathResult, + &writeAskResult)) + + if (IntToBool(writeAskResult)) + { + FString destPathNew = us2fs((LPCOLESTR)destPathResult); + RINOK(state.Callback->SetCurrentFilePath(fs2us(srcPath))) + + if (state.UseReadWriteMode) + { + NFsFolder::CCopyStateIO state2; + state2.Progress = state.Callback; + state2.DeleteSrcFile = state.MoveMode; + state2.TotalSize = state.ProgressInfo.TotalSize; + state2.StartPos = state.ProgressInfo.StartPos; + + RINOK(state2.MyCopyFile(srcPath, destPathNew, + state.IsAltStreamsDest ? INVALID_FILE_ATTRIBUTES: srcFileInfo.Attrib)) + + if (state2.ErrorFileIndex >= 0) + { + if (state2.ErrorMessage.IsEmpty()) + state2.ErrorMessage = GetLastErrorMessage(); + FString errorName; + if (state2.ErrorFileIndex == 0) + errorName = srcPath; + else + errorName = destPathNew; + RINOK(SendMessageError(state.Callback, state2.ErrorMessage, errorName)) + return E_ABORT; + } + state.ProgressInfo.StartPos += state2.CurrentSize; + } + else + { + state.ProgressInfo.FileSize = srcFileInfo.Size; + bool res; + if (state.MoveMode) + res = state.MoveFile_Sys(srcPath, destPathNew); + else + res = state.CopyFile_Sys(srcPath, destPathNew); + RINOK(state.ProgressInfo.ProgressResult) + if (!res) + { + const DWORD errorCode = GetLastError(); + UString errorMessage = NError::MyFormatMessage(Return_LastError_or_FAIL()); + if (errorCode == ERROR_INVALID_PARAMETER) + { + NFind::CFileInfo fi; + if (fi.Find(srcPath) && + fi.Size > (UInt32)(Int32)-1) + { + // bool isFsDetected = false; + // if (NSystem::Is_File_LimitedBy_4GB(destPathNew, isFsDetected) || !isFsDetected) + errorMessage += " File size exceeds 4 GB"; + } + } + + // GetLastError() is ERROR_REQUEST_ABORTED in case of PROGRESS_CANCEL. + RINOK(SendMessageError(state.Callback, errorMessage, destPathNew)) + return E_ABORT; + } + state.ProgressInfo.StartPos += state.ProgressInfo.FileSize; + } + } + else + { + if (state.ProgressInfo.TotalSize >= srcFileInfo.Size) + { + state.ProgressInfo.TotalSize -= srcFileInfo.Size; + RINOK(state.ProgressInfo.Progress->SetTotal(state.ProgressInfo.TotalSize)) + } + } + return state.CallProgress(); +} + +static FString CombinePath(const FString &folderPath, const FString &fileName) +{ + FString s (folderPath); + s.Add_PathSepar(); // FCHAR_PATH_SEPARATOR + s += fileName; + return s; +} + +static bool IsDestChild(const FString &src, const FString &dest) +{ + unsigned len = src.Len(); + if (dest.Len() < len) + return false; + if (dest.Len() != len && dest[len] != FCHAR_PATH_SEPARATOR) + return false; + return CompareFileNames(dest.Left(len), src) == 0; +} + +static HRESULT CopyFolder( + CCopyState &state, + const FString &srcPath, // without TAIL separator + const FString &destPath) // without TAIL separator +{ + RINOK(state.CallProgress()) + + if (IsDestChild(srcPath, destPath)) + { + RINOK(SendMessageError(state.Callback, + state.MoveMode ? + "Cannot copy folder onto itself" : + "Cannot move folder onto itself" + , destPath)) + return E_ABORT; + } + + if (state.MoveMode) + { + if (state.MoveFile_Sys(srcPath, destPath)) + return S_OK; + + // MSDN: MoveFile() fails for dirs on different volumes. + } + + if (!CreateComplexDir(destPath)) + { + RINOK(SendMessageError(state.Callback, "Cannot create folder", destPath)) + return E_ABORT; + } + + CEnumerator enumerator; + enumerator.SetDirPrefix(CombinePath(srcPath, FString())); + + for (;;) + { + NFind::CFileInfo fi; + bool found; + if (!enumerator.Next(fi, found)) + { + SendLastErrorMessage(state.Callback, srcPath); + return S_OK; + } + if (!found) + break; + const FString srcPath2 = CombinePath(srcPath, fi.Name); + const FString destPath2 = CombinePath(destPath, fi.Name); + if (fi.IsDir()) + { + RINOK(CopyFolder(state, srcPath2, destPath2)) + } + else + { + RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2)) + } + } + + if (state.MoveMode) + { + if (!RemoveDir(srcPath)) + { + RINOK(SendMessageError(state.Callback, "Cannot remove folder", srcPath)) + return E_ABORT; + } + } + + return S_OK; +} + +Z7_COM7F_IMF(CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, + Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */, + const wchar_t *path, IFolderOperationsExtractCallback *callback)) +{ + if (numItems == 0) + return S_OK; + + const FString destPath = us2fs(path); + if (destPath.IsEmpty()) + return E_INVALIDARG; + + const bool isAltDest = NName::IsAltPathPrefix(destPath); + const bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back())); + + if (isDirectPath) + if (numItems > 1) + return E_INVALIDARG; + + CFsFolderStat stat; + stat.Progress = callback; + + UInt32 i; + for (i = 0; i < numItems; i++) + { + const UInt32 index = indices[i]; + /* + if (index >= Files.Size()) + { + size += Streams[index - Files.Size()].Size; + // numFiles++; + continue; + } + */ + const CDirItem &fi = Files[index]; + if (fi.IsDir()) + { + if (!isAltDest) + { + stat.Path = _path; + stat.Path += GetRelPath(fi); + RINOK(stat.Enumerate()) + } + stat.NumFolders++; + } + else + { + stat.NumFiles++; + stat.Size += fi.Size; + } + } + + /* + if (stat.NumFolders != 0 && isAltDest) + return E_NOTIMPL; + */ + + RINOK(callback->SetTotal(stat.Size)) + RINOK(callback->SetNumFiles(stat.NumFiles)) + + UInt64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)) + + CCopyState state; + state.ProgressInfo.TotalSize = stat.Size; + state.ProgressInfo.StartPos = 0; + state.ProgressInfo.Progress = callback; + state.ProgressInfo.Init(); + state.Callback = callback; + state.MoveMode = IntToBool(moveMode); + state.IsAltStreamsDest = isAltDest; + /* CopyFileW(fromFile, toFile:altStream) returns ERROR_INVALID_PARAMETER, + if there are alt streams in fromFile. + So we don't use CopyFileW() for alt Streams. */ + state.UseReadWriteMode = isAltDest; + + for (i = 0; i < numItems; i++) + { + const UInt32 index = indices[i]; + if (index >= (UInt32)Files.Size()) + continue; + const CDirItem &fi = Files[index]; + FString destPath2 = destPath; + if (!isDirectPath) + destPath2 += fi.Name; + FString srcPath; + GetFullPath(fi, srcPath); + + if (fi.IsDir()) + { + if (isAltDest) + { + RINOK(SendMessageError(callback, k_CannotCopyDirToAltStream, srcPath)) + } + else + { + RINOK(CopyFolder(state, srcPath, destPath2)) + } + } + else + { + RINOK(CopyFile_Ask(state, srcPath, fi, destPath2)) + } + } + return S_OK; +} + + + +/* we can call CopyFileSystemItems() from CDropTarget::Drop() */ + +HRESULT CopyFileSystemItems( + const UStringVector &itemsPaths, + const FString &destDirPrefix, + bool moveMode, + IFolderOperationsExtractCallback *callback) +{ + if (itemsPaths.IsEmpty()) + return S_OK; + + if (destDirPrefix.IsEmpty()) + return E_INVALIDARG; + + const bool isAltDest = NName::IsAltPathPrefix(destDirPrefix); + + CFsFolderStat stat; + stat.Progress = callback; + + { + FOR_VECTOR (i, itemsPaths) + { + const UString &path = itemsPaths[i]; + CFileInfo fi; + if (!fi.Find(us2fs(path))) + continue; + if (fi.IsDir()) + { + if (!isAltDest) + { + stat.Path = us2fs(path); + RINOK(stat.Enumerate()) + } + stat.NumFolders++; + } + else + { + stat.NumFiles++; + stat.Size += fi.Size; + } + } + } + + /* + if (stat.NumFolders != 0 && isAltDest) + return E_NOTIMPL; + */ + + RINOK(callback->SetTotal(stat.Size)) + // RINOK(progress->SetNumFiles(stat.NumFiles)); + + UInt64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)) + + CCopyState state; + state.ProgressInfo.TotalSize = stat.Size; + state.ProgressInfo.StartPos = 0; + state.ProgressInfo.Progress = callback; + state.ProgressInfo.Init(); + state.Callback = callback; + state.MoveMode = moveMode; + state.IsAltStreamsDest = isAltDest; + /* CopyFileW(fromFile, toFile:altStream) returns ERROR_INVALID_PARAMETER, + if there are alt streams in fromFile. + So we don't use CopyFileW() for alt Streams. */ + state.UseReadWriteMode = isAltDest; + + FOR_VECTOR (i, itemsPaths) + { + const UString path = itemsPaths[i]; + CFileInfo fi; + + if (!fi.Find(us2fs(path))) + { + RINOK(SendMessageError(callback, "Cannot find the file", us2fs(path))) + continue; + } + + FString destPath = destDirPrefix; + destPath += fi.Name; + + if (fi.IsDir()) + { + if (isAltDest) + { + RINOK(SendMessageError(callback, k_CannotCopyDirToAltStream, us2fs(path))) + } + else + { + RINOK(CopyFolder(state, us2fs(path), destPath)) + } + } + else + { + RINOK(CopyFile_Ask(state, us2fs(path), fi, destPath)) + } + } + return S_OK; +} + + +/* we don't use CFSFolder::CopyFrom() because the caller of CopyFrom() + is optimized for IFolderArchiveUpdateCallback interface, + but we want to use IFolderOperationsExtractCallback interface instead */ + +Z7_COM7F_IMF(CFSFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */, + const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)) +{ + /* + Z7_DECL_CMyComPtr_QI_FROM( + IFolderOperationsExtractCallback, + callback, progress) + if (!callback) + return E_NOTIMPL; + return CopyFileSystemItems(_path, + moveMode, fromDirPrefix, + itemsPaths, numItems, callback); + */ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CFSFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)) +{ + return E_NOTIMPL; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp 2015-06-21 18:36:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,195 +1,394 @@ -// FileFolderPluginOpen.cpp - -#include "StdAfx.h" - -#include "resource.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/Thread.h" - -#include "../Agent/Agent.h" - -#include "LangUtils.h" -#include "OpenCallback.h" -#include "PluginLoader.h" -#include "RegistryPlugins.h" - -using namespace NWindows; - -struct CThreadArchiveOpen -{ - UString Path; - UString ArcFormat; - CMyComPtr InStream; - CMyComPtr FolderManager; - CMyComPtr OpenCallback; - COpenArchiveCallback *OpenCallbackSpec; - - CMyComPtr Folder; - HRESULT Result; - - void Process() - { - try - { - CProgressCloser closer(OpenCallbackSpec->ProgressDialog); - Result = FolderManager->OpenFolderFile(InStream, Path, ArcFormat, &Folder, OpenCallback); - } - catch(...) { Result = E_FAIL; } - } - - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadArchiveOpen *)param)->Process(); - return 0; - } -}; - -/* -static int FindPlugin(const CObjectVector &plugins, const UString &pluginName) -{ - for (int i = 0; i < plugins.Size(); i++) - if (plugins[i].Name.CompareNoCase(pluginName) == 0) - return i; - return -1; -} -*/ - -static const FChar kExtensionDelimiter = FTEXT('.'); - -static void SplitNameToPureNameAndExtension(const FString &fullName, - FString &pureName, FString &extensionDelimiter, FString &extension) -{ - int index = fullName.ReverseFind_Dot(); - if (index < 0) - { - pureName = fullName; - extensionDelimiter.Empty(); - extension.Empty(); - } - else - { - pureName.SetFrom(fullName, index); - extensionDelimiter = FTEXT('.'); - extension = fullName.Ptr(index + 1); - } -} - -HRESULT OpenFileFolderPlugin( - IInStream *inStream, - const FString &path, - const UString &arcFormat, - HMODULE *module, - IFolderFolder **resultFolder, - HWND parentWindow, - bool &encrypted, UString &password) -{ -#ifdef _WIN32 - CObjectVector plugins; - ReadFileFolderPluginInfoList(plugins); -#endif - - FString extension, name, pureName, dot; - - int slashPos = path.ReverseFind_PathSepar(); - FString dirPrefix; - FString fileName; - if (slashPos >= 0) - { - dirPrefix.SetFrom(path, slashPos + 1); - fileName = path.Ptr(slashPos + 1); - } - else - fileName = path; - - SplitNameToPureNameAndExtension(fileName, pureName, dot, extension); - - /* - if (!extension.IsEmpty()) - { - CExtInfo extInfo; - if (ReadInternalAssociation(extension, extInfo)) - { - for (int i = extInfo.Plugins.Size() - 1; i >= 0; i--) - { - int pluginIndex = FindPlugin(plugins, extInfo.Plugins[i]); - if (pluginIndex >= 0) - { - const CPluginInfo plugin = plugins[pluginIndex]; - plugins.Delete(pluginIndex); - plugins.Insert(0, plugin); - } - } - } - } - */ - -#ifdef _WIN32 - FOR_VECTOR (i, plugins) - { - const CPluginInfo &plugin = plugins[i]; - if (!plugin.ClassIDDefined) - continue; -#endif - CPluginLibrary library; - - CThreadArchiveOpen t; - -#ifdef _WIN32 - if (plugin.FilePath.IsEmpty()) - t.FolderManager = new CArchiveFolderManager; - else if (library.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &t.FolderManager) != S_OK) - continue; -#else - t.FolderManager = new CArchiveFolderManager; -#endif - - t.OpenCallbackSpec = new COpenArchiveCallback; - t.OpenCallback = t.OpenCallbackSpec; - t.OpenCallbackSpec->PasswordIsDefined = encrypted; - t.OpenCallbackSpec->Password = password; - t.OpenCallbackSpec->ParentWindow = parentWindow; - - if (inStream) - t.OpenCallbackSpec->SetSubArchiveName(fs2us(fileName)); - else - t.OpenCallbackSpec->LoadFileInfo(dirPrefix, fileName); - - t.InStream = inStream; - t.Path = fs2us(path); - t.ArcFormat = arcFormat; - - UString progressTitle = LangString(IDS_OPENNING); - t.OpenCallbackSpec->ProgressDialog.MainWindow = parentWindow; - t.OpenCallbackSpec->ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - t.OpenCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + L' '; - // FIXME t.OpenCallbackSpec->ProgressDialog.WaitMode = true; - - { - NWindows::CThread thread; - RINOK(thread.Create(CThreadArchiveOpen::MyThreadFunction, &t)); - t.OpenCallbackSpec->StartProgressDialog(progressTitle, thread); - } - - if (t.Result == E_ABORT) - return t.Result; - - encrypted = t.OpenCallbackSpec->PasswordIsDefined; - if (t.Result == S_OK) - { - // if (openCallbackSpec->PasswordWasAsked) - { - password = t.OpenCallbackSpec->Password; - } - *module = library.Detach(); - *resultFolder = t.Folder.Detach(); - return S_OK; - } - - if (t.Result != S_FALSE) - return t.Result; -#ifdef _WIN32 - } -#endif - return S_FALSE; -} +// FileFolderPluginOpen.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/Thread.h" + +#include "../Agent/Agent.h" +#include "../GUI/ExtractRes.h" + +#include "FileFolderPluginOpen.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "OpenCallback.h" +#include "PluginLoader.h" +#include "PropertyName.h" +#include "RegistryPlugins.h" + +using namespace NWindows; + +struct CThreadArchiveOpen +{ + UString Path; + UString ArcFormat; + CMyComPtr InStream; + CMyComPtr FolderManager; + CMyComPtr OpenCallbackProgress; + + COpenArchiveCallback *OpenCallbackSpec; + /* + CMyComPtr + // CMyComPtr + // CMyComPtr + OpenCallbackSpec_Ref; + */ + + CMyComPtr Folder; + HRESULT Result; + + void Process() + { + try + { + CProgressCloser closer(OpenCallbackSpec->ProgressDialog); + Result = FolderManager->OpenFolderFile(InStream, Path, ArcFormat, &Folder, OpenCallbackProgress); + } + catch(...) { Result = E_FAIL; } + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + ((CThreadArchiveOpen *)param)->Process(); + return 0; + } +}; + +/* +static int FindPlugin(const CObjectVector &plugins, const UString &pluginName) +{ + for (int i = 0; i < plugins.Size(); i++) + if (plugins[i].Name.CompareNoCase(pluginName) == 0) + return i; + return -1; +} +*/ + +static void SplitNameToPureNameAndExtension(const FString &fullName, + FString &pureName, FString &extensionDelimiter, FString &extension) +{ + const int index = fullName.ReverseFind_Dot(); + if (index < 0) + { + pureName = fullName; + extensionDelimiter.Empty(); + extension.Empty(); + } + else + { + pureName.SetFrom(fullName, (unsigned)index); + extensionDelimiter = '.'; + extension = fullName.Ptr((unsigned)index + 1); + } +} + + +struct CArcLevelInfo +{ + UString Error; + UString Path; + UString Type; + UString ErrorType; + UString ErrorFlags; +}; + + +struct CArcLevelsInfo +{ + CObjectVector Levels; // LastLevel Is NON-OPEN +}; + + +UString GetOpenArcErrorMessage(UInt32 errorFlags); + + +static void GetFolderLevels(CMyComPtr &folder, CArcLevelsInfo &levels) +{ + levels.Levels.Clear(); + + CMyComPtr getFolderArcProps; + folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); + + if (!getFolderArcProps) + return; + CMyComPtr arcProps; + getFolderArcProps->GetFolderArcProps(&arcProps); + if (!arcProps) + return; + + UInt32 numLevels; + if (arcProps->GetArcNumLevels(&numLevels) != S_OK) + numLevels = 0; + + for (UInt32 level = 0; level <= numLevels; level++) + { + const PROPID propIDs[] = { kpidError, kpidPath, kpidType, kpidErrorType }; + + CArcLevelInfo lev; + + for (Int32 i = 0; i < 4; i++) + { + CMyComBSTR name; + NCOM::CPropVariant prop; + if (arcProps->GetArcProp(level, propIDs[i], &prop) != S_OK) + continue; + if (prop.vt != VT_EMPTY) + { + UString *s = NULL; + switch (propIDs[i]) + { + case kpidError: s = &lev.Error; break; + case kpidPath: s = &lev.Path; break; + case kpidType: s = &lev.Type; break; + case kpidErrorType: s = &lev.ErrorType; break; + } + *s = (prop.vt == VT_BSTR) ? prop.bstrVal : L"?"; + } + } + + { + NCOM::CPropVariant prop; + if (arcProps->GetArcProp(level, kpidErrorFlags, &prop) == S_OK) + { + UInt32 flags = GetOpenArcErrorFlags(prop); + if (flags != 0) + lev.ErrorFlags = GetOpenArcErrorMessage(flags); + } + } + + levels.Levels.Add(lev); + } +} + +static UString GetBracedType(const wchar_t *type) +{ + UString s ('['); + s += type; + s.Add_Char(']'); + return s; +} + +static void GetFolderError(CMyComPtr &folder, UString &open_Errors, UString &nonOpen_Errors) +{ + CArcLevelsInfo levs; + GetFolderLevels(folder, levs); + open_Errors.Empty(); + nonOpen_Errors.Empty(); + + FOR_VECTOR (i, levs.Levels) + { + bool isNonOpenLevel = (i == 0); + const CArcLevelInfo &lev = levs.Levels[levs.Levels.Size() - 1 - i]; + + UString m; + + if (!lev.ErrorType.IsEmpty()) + { + m = MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(lev.ErrorType)); + if (!isNonOpenLevel) + { + m.Add_LF(); + m += MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(lev.Type)); + } + } + + if (!lev.Error.IsEmpty()) + { + if (!m.IsEmpty()) + m.Add_LF(); + m += GetBracedType(lev.Type); + m += " : "; + m += GetNameOfProperty(kpidError, L"Error"); + m += " : "; + m += lev.Error; + } + + if (!lev.ErrorFlags.IsEmpty()) + { + if (!m.IsEmpty()) + m.Add_LF(); + m += GetNameOfProperty(kpidErrorFlags, L"Errors"); + m += ": "; + m += lev.ErrorFlags; + } + + if (!m.IsEmpty()) + { + if (isNonOpenLevel) + { + UString &s = nonOpen_Errors; + s += lev.Path; + s.Add_LF(); + s += m; + } + else + { + UString &s = open_Errors; + if (!s.IsEmpty()) + s += "--------------------\n"; + s += lev.Path; + s.Add_LF(); + s += m; + } + } + } +} + +#ifdef _MSC_VER +#pragma warning(error : 4702) // unreachable code +#endif + +HRESULT CFfpOpen::OpenFileFolderPlugin(IInStream *inStream, + const FString &path, const UString &arcFormat, HWND parentWindow) +{ + /* + CObjectVector plugins; + ReadFileFolderPluginInfoList(plugins); + */ + + FString extension, name, pureName, dot; + + const int slashPos = path.ReverseFind_PathSepar(); + FString dirPrefix; + FString fileName; + if (slashPos >= 0) + { + dirPrefix.SetFrom(path, (unsigned)(slashPos + 1)); + fileName = path.Ptr((unsigned)(slashPos + 1)); + } + else + fileName = path; + + SplitNameToPureNameAndExtension(fileName, pureName, dot, extension); + + /* + if (!extension.IsEmpty()) + { + CExtInfo extInfo; + if (ReadInternalAssociation(extension, extInfo)) + { + for (int i = extInfo.Plugins.Size() - 1; i >= 0; i--) + { + int pluginIndex = FindPlugin(plugins, extInfo.Plugins[i]); + if (pluginIndex >= 0) + { + const CPluginInfo plugin = plugins[pluginIndex]; + plugins.Delete(pluginIndex); + plugins.Insert(0, plugin); + } + } + } + } + */ + + ErrorMessage.Empty(); + + // FOR_VECTOR (i, plugins) + // { + /* + const CPluginInfo &plugin = plugins[i]; + if (!plugin.ClassID_Defined && !plugin.FilePath.IsEmpty()) + continue; + */ + CPluginLibrary library; + + CThreadArchiveOpen t; + + // if (plugin.FilePath.IsEmpty()) + t.FolderManager = new CArchiveFolderManager; + /* + else if (library.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &t.FolderManager) != S_OK) + continue; + */ + + COpenArchiveCallback OpenCallbackSpec_loc; + t.OpenCallbackSpec = &OpenCallbackSpec_loc; + /* + t.OpenCallbackSpec = new COpenArchiveCallback; + t.OpenCallbackSpec_Ref = t.OpenCallbackSpec; + */ + t.OpenCallbackSpec->PasswordIsDefined = Encrypted; + t.OpenCallbackSpec->Password = Password; + t.OpenCallbackSpec->ParentWindow = parentWindow; + + /* COpenCallbackImp object will exist after Open stage for multivolume archives */ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + t.OpenCallbackProgress = openCallbackSpec; + // openCallbackSpec->Callback_Ref = t.OpenCallbackSpec; + // we set pointer without reference counter: + openCallbackSpec->Callback = + // openCallbackSpec->ReOpenCallback = + t.OpenCallbackSpec; + + if (inStream) + openCallbackSpec->SetSubArchiveName(fs2us(fileName)); + else + { + RINOK(openCallbackSpec->Init2(dirPrefix, fileName)) + } + + t.InStream = inStream; + t.Path = fs2us(path); + t.ArcFormat = arcFormat; + + const UString progressTitle = LangString(IDS_OPENNING); + { + CProgressDialog &pd = t.OpenCallbackSpec->ProgressDialog; + pd.MainWindow = parentWindow; + pd.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + pd.MainAddTitle = progressTitle + L' '; + pd.WaitMode = true; + } + + { + NWindows::CThread thread; + const WRes wres = thread.Create(CThreadArchiveOpen::MyThreadFunction, &t); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + t.OpenCallbackSpec->StartProgressDialog(progressTitle, thread); + } + + /* + if archive is multivolume: + COpenCallbackImp object will exist after Open stage. + COpenCallbackImp object will be deleted when last reference + from each volume object (CInFileStreamVol) will be closed (when archive will be closed). + */ + t.OpenCallbackProgress.Release(); + + if (t.Result != S_FALSE && t.Result != S_OK) + return t.Result; + + if (t.Folder) + { + UString open_Errors, nonOpen_Errors; + GetFolderError(t.Folder, open_Errors, nonOpen_Errors); + if (!nonOpen_Errors.IsEmpty()) + { + ErrorMessage = nonOpen_Errors; + // if (t.Result != S_OK) return t.Result; + /* if there are good open leves, and non0open level, + we could force error as critical error and return error here + but it's better to allow to open such rachives */ + // return S_FALSE; + } + } + + // if (openCallbackSpec->PasswordWasAsked) + { + Encrypted = t.OpenCallbackSpec->PasswordIsDefined; + Password = t.OpenCallbackSpec->Password; + } + + if (t.Result == S_OK) + { + Library.Attach(library.Detach()); + // Folder.Attach(t.Folder.Detach()); + Folder = t.Folder; + } + + return t.Result; + // } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h 2011-06-12 13:24:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h 2023-01-31 18:00:00.000000000 +0000 @@ -1,9 +1,27 @@ -// FileFolderPluginOpen.h - -#ifndef __FILE_FOLDER_PLUGIN_OPEN_H -#define __FILE_FOLDER_PLUGIN_OPEN_H - -HRESULT OpenFileFolderPlugin(IInStream *inStream, const FString &path, const UString &arcFormat, - HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted, UString &password); - -#endif +// FileFolderPluginOpen.h + +#ifndef ZIP7_INC_FILE_FOLDER_PLUGIN_OPEN_H +#define ZIP7_INC_FILE_FOLDER_PLUGIN_OPEN_H + +#include "../../../Windows/DLL.h" + +struct CFfpOpen +{ + Z7_CLASS_NO_COPY(CFfpOpen) +public: + // out: + bool Encrypted; + UString Password; + + NWindows::NDLL::CLibrary Library; + CMyComPtr Folder; + UString ErrorMessage; + + CFfpOpen(): Encrypted (false) {} + + HRESULT OpenFileFolderPlugin(IInStream *inStream, + const FString &path, const UString &arcFormat, HWND parentWindow); +}; + + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FilePlugins.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FilePlugins.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.cpp 2023-02-01 08:00:00.000000000 +0000 @@ -0,0 +1,78 @@ +// FilePlugins.cpp + +#include "StdAfx.h" + +#include "../Agent/Agent.h" + +#include "FilePlugins.h" +#include "PluginLoader.h" +#include "StringUtils.h" + +int CExtDatabase::FindExt(const UString &ext) const +{ + FOR_VECTOR (i, Exts) + if (Exts[i].Ext.IsEqualTo_NoCase(ext)) + return (int)i; + return -1; +} + +void CExtDatabase::Read() +{ + /* + ReadFileFolderPluginInfoList(Plugins); + FOR_VECTOR (pluginIndex, Plugins) + */ + { + // const CPluginInfo &plugin = Plugins[pluginIndex]; + + CPluginLibrary pluginLib; + CMyComPtr folderManager; + + // if (plugin.FilePath.IsEmpty()) + folderManager = new CArchiveFolderManager; + /* + else + { + if (!plugin.ClassID_Defined) + continue; + if (pluginLib.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &folderManager) != S_OK) + continue; + } + */ + CMyComBSTR extBSTR; + if (folderManager->GetExtensions(&extBSTR) != S_OK) + return; + UStringVector exts; + SplitString((const wchar_t *)extBSTR, exts); + FOR_VECTOR (i, exts) + { + const UString &ext = exts[i]; + #ifdef UNDER_CE + if (ext == L"cab") + continue; + #endif + + Int32 iconIndex; + CMyComBSTR iconPath; + CPluginToIcon plugPair; + // plugPair.PluginIndex = pluginIndex; + if (folderManager->GetIconPath(ext, &iconPath, &iconIndex) == S_OK) + if (iconPath) + { + plugPair.IconPath = (const wchar_t *)iconPath; + plugPair.IconIndex = iconIndex; + } + + const int index = FindExt(ext); + if (index >= 0) + Exts[index].Plugins.Add(plugPair); + else + { + CExtPlugins extInfo; + extInfo.Plugins.Add(plugPair); + extInfo.Ext = ext; + Exts.Add(extInfo); + } + } + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FilePlugins.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FilePlugins.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FilePlugins.h 2023-01-30 20:00:00.000000000 +0000 @@ -0,0 +1,33 @@ +// FilePlugins.h + +#ifndef ZIP7_INC_FILE_PLUGINS_H +#define ZIP7_INC_FILE_PLUGINS_H + +#include "RegistryPlugins.h" + +struct CPluginToIcon +{ + // unsigned PluginIndex; + int IconIndex; + UString IconPath; + + CPluginToIcon(): IconIndex(-1) {} +}; + +struct CExtPlugins +{ + UString Ext; + CObjectVector Plugins; +}; + +class CExtDatabase +{ + int FindExt(const UString &ext) const; +public: + CObjectVector Exts; + // CObjectVector Plugins; + + void Read(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.cpp 2023-03-19 10:00:00.000000000 +0000 @@ -0,0 +1,172 @@ +// FoldersPage.cpp + +#include "StdAfx.h" + +#include "FoldersPageRes.h" +#include "FoldersPage.h" + +#include "../FileManager/BrowseDialog.h" +#include "../FileManager/HelpUtils.h" +#include "../FileManager/LangUtils.h" + +using namespace NWindows; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_FOLDERS_WORKING_FOLDER, + IDR_FOLDERS_WORK_SYSTEM, + IDR_FOLDERS_WORK_CURRENT, + IDR_FOLDERS_WORK_SPECIFIED, + IDX_FOLDERS_WORK_FOR_REMOVABLE +}; +#endif + +static const unsigned kWorkModeButtons[] = +{ + IDR_FOLDERS_WORK_SYSTEM, + IDR_FOLDERS_WORK_CURRENT, + IDR_FOLDERS_WORK_SPECIFIED +}; + +#define kFoldersTopic "fm/options.htm#folders" + +static const unsigned kNumWorkModeButtons = Z7_ARRAY_SIZE(kWorkModeButtons); + +bool CFoldersPage::OnInit() +{ + _initMode = true; + _needSave = false; + + #ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + m_WorkDirInfo.Load(); + + CheckButton(IDX_FOLDERS_WORK_FOR_REMOVABLE, m_WorkDirInfo.ForRemovableOnly); + + CheckRadioButton( + kWorkModeButtons[0], + kWorkModeButtons[kNumWorkModeButtons - 1], + kWorkModeButtons[m_WorkDirInfo.Mode]); + + m_WorkPath.Init(*this, IDE_FOLDERS_WORK_PATH); + + m_WorkPath.SetText(fs2us(m_WorkDirInfo.Path)); + + MyEnableControls(); + + _initMode = false; + return CPropertyPage::OnInit(); +} + +int CFoldersPage::GetWorkMode() const +{ + for (unsigned i = 0; i < kNumWorkModeButtons; i++) + if (IsButtonCheckedBool(kWorkModeButtons[i])) + return (int)i; + throw 0; +} + +void CFoldersPage::MyEnableControls() +{ + bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified); + m_WorkPath.Enable(enablePath); + EnableItem(IDB_FOLDERS_WORK_PATH, enablePath); +} + +void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo) +{ + UString s; + m_WorkPath.GetText(s); + workDirInfo.Path = us2fs(s); + workDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDX_FOLDERS_WORK_FOR_REMOVABLE); + workDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode()); +} + +/* +bool CFoldersPage::WasChanged() +{ + NWorkDir::CInfo workDirInfo; + GetWorkDir(workDirInfo); + return (workDirInfo.Mode != m_WorkDirInfo.Mode || + workDirInfo.ForRemovableOnly != m_WorkDirInfo.ForRemovableOnly || + workDirInfo.Path.Compare(m_WorkDirInfo.Path) != 0); +} +*/ + +void CFoldersPage::ModifiedEvent() +{ + if (!_initMode) + { + _needSave = true; + Changed(); + } + /* + if (WasChanged()) + Changed(); + else + UnChanged(); + */ +} + +bool CFoldersPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + for (unsigned i = 0; i < kNumWorkModeButtons; i++) + if (buttonID == kWorkModeButtons[i]) + { + MyEnableControls(); + ModifiedEvent(); + return true; + } + + switch (buttonID) + { + case IDB_FOLDERS_WORK_PATH: + OnFoldersWorkButtonPath(); + return true; + case IDX_FOLDERS_WORK_FOR_REMOVABLE: + break; + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + + ModifiedEvent(); + return true; +} + +bool CFoldersPage::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == EN_CHANGE && itemID == IDE_FOLDERS_WORK_PATH) + { + ModifiedEvent(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, lParam); +} + +void CFoldersPage::OnFoldersWorkButtonPath() +{ + UString currentPath; + m_WorkPath.GetText(currentPath); + UString title = LangString(IDS_FOLDERS_SET_WORK_PATH_TITLE); + UString resultPath; + if (MyBrowseForFolder(*this, title, currentPath, resultPath)) + m_WorkPath.SetText(resultPath); +} + +LONG CFoldersPage::OnApply() +{ + if (_needSave) + { + GetWorkDir(m_WorkDirInfo); + m_WorkDirInfo.Save(); + _needSave = false; + } + return PSNRET_NOERROR; +} + +void CFoldersPage::OnNotifyHelp() +{ + ShowHelpWindow(kFoldersTopic); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,32 @@ +// FoldersPage.h + +#ifndef ZIP7_INC_FOLDERS_PAGE_H +#define ZIP7_INC_FOLDERS_PAGE_H + +#include "../../../Windows/Control/PropertyPage.h" + +#include "../Common/ZipRegistry.h" + +class CFoldersPage : public NWindows::NControl::CPropertyPage +{ + NWorkDir::CInfo m_WorkDirInfo; + NWindows::NControl::CDialogChildControl m_WorkPath; + + bool _needSave; + bool _initMode; + + void MyEnableControls(); + void ModifiedEvent(); + + void OnFoldersWorkButtonPath(); + int GetWorkMode() const; + void GetWorkDir(NWorkDir::CInfo &workDirInfo); + // bool WasChanged(); + virtual bool OnInit() Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual LONG OnApply() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage.rc 2024-03-16 05:00:00.000000000 +0000 @@ -0,0 +1,23 @@ +#include "FoldersPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc 100 + +IDD_FOLDERS MY_PAGE +#include "FoldersPage2.rc" + +#ifdef UNDER_CE + +#undef xc +#define xc SMALL_PAGE_SIZE_X + +IDD_FOLDERS_2 MY_PAGE +#include "FoldersPage2.rc" + +#endif + +STRINGTABLE +BEGIN + IDS_FOLDERS_SET_WORK_PATH_TITLE "Specify a location for temporary archive files." +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPage2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPage2.rc 2024-03-16 07:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +CAPTION "Folders" +BEGIN + // GROUPBOX "&Working folder", IDT_FOLDERS_WORKING_FOLDER, m, m, xc, 98 + LTEXT "&Working folder", IDT_FOLDERS_WORKING_FOLDER, m, m, xc, 8 + MY_CONTROL_AUTORADIOBUTTON_GROUP ( "&System temp folder", IDR_FOLDERS_WORK_SYSTEM, m, 20, xc) + MY_CONTROL_AUTORADIOBUTTON ( "&Current", IDR_FOLDERS_WORK_CURRENT, m, 34, xc) + MY_CONTROL_AUTORADIOBUTTON ( "Specified:", IDR_FOLDERS_WORK_SPECIFIED, m, 48, xc) + EDITTEXT IDE_FOLDERS_WORK_PATH, m + m, 62, xc - m - m - bxsDots, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDB_FOLDERS_WORK_PATH, xs - m - bxsDots, 61, bxsDots, bys + MY_CONTROL_CHECKBOX ( "Use for removable drives only", IDX_FOLDERS_WORK_FOR_REMOVABLE, m, 86, xc) +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FoldersPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FoldersPageRes.h 2011-06-06 13:46:31.000000000 +0000 @@ -0,0 +1,12 @@ +#define IDD_FOLDERS 2400 +#define IDD_FOLDERS_2 12400 + +#define IDT_FOLDERS_WORKING_FOLDER 2401 +#define IDR_FOLDERS_WORK_SYSTEM 2402 +#define IDR_FOLDERS_WORK_CURRENT 2403 +#define IDR_FOLDERS_WORK_SPECIFIED 2404 +#define IDX_FOLDERS_WORK_FOR_REMOVABLE 2405 +#define IDS_FOLDERS_SET_WORK_PATH_TITLE 2406 + +#define IDE_FOLDERS_WORK_PATH 100 +#define IDB_FOLDERS_WORK_PATH 101 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FormatUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FormatUtils.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.cpp 2013-01-17 10:24:53.000000000 +0000 @@ -1,28 +1,28 @@ -// FormatUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "FormatUtils.h" - -#include "LangUtils.h" - -UString NumberToString(UInt64 number) -{ - wchar_t numberString[32]; - ConvertUInt64ToString(number, numberString); - return numberString; -} - -UString MyFormatNew(const UString &format, const UString &argument) -{ - UString result = format; - result.Replace(L"{0}", argument); - return result; -} - -UString MyFormatNew(UINT resourceID, const UString &argument) -{ - return MyFormatNew(LangString(resourceID), argument); -} +// FormatUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "FormatUtils.h" + +#include "LangUtils.h" + +UString NumberToString(UInt64 number) +{ + wchar_t numberString[32]; + ConvertUInt64ToString(number, numberString); + return numberString; +} + +UString MyFormatNew(const UString &format, const UString &argument) +{ + UString result = format; + result.Replace(L"{0}", argument); + return result; +} + +UString MyFormatNew(UINT resourceID, const UString &argument) +{ + return MyFormatNew(LangString(resourceID), argument); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/FormatUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/FormatUtils.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/FormatUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// FormatUtils.h - -#ifndef __FORMAT_UTILS_H -#define __FORMAT_UTILS_H - -#include "../../../Common/MyTypes.h" -#include "../../../Common/MyString.h" - -UString NumberToString(UInt64 number); - -UString MyFormatNew(const UString &format, const UString &argument); -UString MyFormatNew(UINT resourceID, const UString &argument); - -#endif +// FormatUtils.h + +#ifndef ZIP7_INC_FORMAT_UTILS_H +#define ZIP7_INC_FORMAT_UTILS_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +UString NumberToString(UInt64 number); + +UString MyFormatNew(const UString &format, const UString &argument); +UString MyFormatNew(UINT resourceID, const UString &argument); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/HelpUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/HelpUtils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.cpp 2023-03-21 12:00:00.000000000 +0000 @@ -0,0 +1,78 @@ +// HelpUtils.cpp + +#include "StdAfx.h" + +#include "HelpUtils.h" + +#if defined(UNDER_CE) || defined(__MINGW32_VERSION) + +void ShowHelpWindow(LPCSTR) +{ +} + +#else + +/* USE_EXTERNAL_HELP creates new help process window for each HtmlHelp() call. + HtmlHelp() call uses one window. */ + +#if defined(__MINGW32_VERSION) /* || defined(Z7_OLD_WIN_SDK) */ +#define USE_EXTERNAL_HELP +#endif + +// #define USE_EXTERNAL_HELP + +#ifdef USE_EXTERNAL_HELP + +#include "../../../Windows/ProcessUtils.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" + +#else +#include +#endif + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" + +#define kHelpFileName "7-zip.chm::/" + +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 -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/HelpUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/HelpUtils.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/HelpUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// HelpUtils.h - -#ifndef __HELP_UTILS_H -#define __HELP_UTILS_H - -#include "../../../Common/MyString.h" - -void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile); - -#endif +// HelpUtils.h + +#ifndef ZIP7_INC_HELP_UTILS_H +#define ZIP7_INC_HELP_UTILS_H + +#include "../../../Common/MyString.h" + +void ShowHelpWindow(LPCSTR topicFile); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/IFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/IFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/IFolder.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/IFolder.h 2023-03-16 12:00:00.000000000 +0000 @@ -1,218 +1,187 @@ -// IFolder.h - -#ifndef __IFOLDER_H -#define __IFOLDER_H - -#include "../../IProgress.h" -#include "../../IStream.h" - -#define FOLDER_INTERFACE_SUB(i, b, x) DECL_INTERFACE_SUB(i, b, 8, x) -#define FOLDER_INTERFACE(i, x) FOLDER_INTERFACE_SUB(i, IUnknown, x) - -namespace NPlugin -{ - enum - { - kName = 0, - kType, - kClassID, - kOptionsClassID - }; -} - -#define INTERFACE_FolderFolder(x) \ - STDMETHOD(LoadItems)() x; \ - STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ - STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder) x; \ - STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) x; \ - STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) x; \ - STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ - STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - STDMETHOD(GetFolderProperty)(PROPID propID, PROPVARIANT *value) x; \ - -FOLDER_INTERFACE(IFolderFolder, 0x00) -{ - INTERFACE_FolderFolder(PURE) -}; - -/* - IFolderAltStreams:: - BindToAltStreams((UInt32)(Int32)-1, ... ) means alt streams of that folder -*/ - -#define INTERFACE_FolderAltStreams(x) \ - STDMETHOD(BindToAltStreams)(UInt32 index, IFolderFolder **resultFolder) x; \ - STDMETHOD(BindToAltStreams)(const wchar_t *name, IFolderFolder **resultFolder) x; \ - STDMETHOD(AreAltStreamsSupported)(UInt32 index, Int32 *isSupported) x; \ - -FOLDER_INTERFACE(IFolderAltStreams, 0x17) -{ - INTERFACE_FolderAltStreams(PURE) -}; - -FOLDER_INTERFACE(IFolderWasChanged, 0x04) -{ - STDMETHOD(WasChanged)(Int32 *wasChanged) PURE; -}; - -FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B) -{ - // STDMETHOD(SetTotalFiles)(UInt64 total) PURE; - // STDMETHOD(SetCompletedFiles)(const UInt64 *completedValue) PURE; - STDMETHOD(AskWrite)( - const wchar_t *srcPath, - Int32 srcIsFolder, - const FILETIME *srcTime, - const UInt64 *srcSize, - const wchar_t *destPathRequest, - BSTR *destPathResult, - Int32 *writeAnswer) PURE; - STDMETHOD(ShowMessage)(const wchar_t *message) PURE; - STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE; - STDMETHOD(SetNumFiles)(UInt64 numFiles) PURE; -}; - -#define INTERFACE_FolderOperations(x) \ - STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) x; \ - STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) x; \ - STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress) x; \ - STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress) x; \ - STDMETHOD(CopyTo)(Int32 moveMode, const UInt32 *indices, UInt32 numItems, \ - Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, \ - const wchar_t *path, IFolderOperationsExtractCallback *callback) x; \ - STDMETHOD(CopyFrom)(Int32 moveMode, const wchar_t *fromFolderPath, \ - const wchar_t * const *itemsPaths, UInt32 numItems, IProgress *progress) x; \ - STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) x; \ - STDMETHOD(CopyFromFile)(UInt32 index, const wchar_t *fullFilePath, IProgress *progress) x; \ - -FOLDER_INTERFACE(IFolderOperations, 0x13) -{ - INTERFACE_FolderOperations(PURE) -}; - -/* -FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03) -{ - STDMETHOD(DeleteToRecycleBin)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE; -}; -*/ - -FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07) -{ - STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex) PURE; -}; - -FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08) -{ - STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress) PURE; -}; - -FOLDER_INTERFACE(IFolderCalcItemFullSize, 0x14) -{ - STDMETHOD(CalcItemFullSize)(UInt32 index, IProgress *progress) PURE; -}; - -FOLDER_INTERFACE(IFolderClone, 0x09) -{ - STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE; -}; - -FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A) -{ - STDMETHOD(SetFlatMode)(Int32 flatMode) PURE; -}; - -/* -FOLDER_INTERFACE(IFolderSetShowNtfsStreamsMode, 0xFA) -{ - STDMETHOD(SetShowNtfsStreamsMode)(Int32 showStreamsMode) PURE; -}; -*/ - -#define INTERFACE_FolderProperties(x) \ - STDMETHOD(GetNumberOfFolderProperties)(UInt32 *numProperties) x; \ - STDMETHOD(GetFolderPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - -FOLDER_INTERFACE(IFolderProperties, 0x0E) -{ - INTERFACE_FolderProperties(PURE) -}; - -#define INTERFACE_IFolderArcProps(x) \ - STDMETHOD(GetArcNumLevels)(UInt32 *numLevels) x; \ - STDMETHOD(GetArcProp)(UInt32 level, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetArcNumProps)(UInt32 level, UInt32 *numProps) x; \ - STDMETHOD(GetArcPropInfo)(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - STDMETHOD(GetArcProp2)(UInt32 level, PROPID propID, PROPVARIANT *value) x; \ - STDMETHOD(GetArcNumProps2)(UInt32 level, UInt32 *numProps) x; \ - STDMETHOD(GetArcPropInfo2)(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ - -FOLDER_INTERFACE(IFolderArcProps, 0x10) -{ - INTERFACE_IFolderArcProps(PURE) -}; - -FOLDER_INTERFACE(IGetFolderArcProps, 0x11) -{ - STDMETHOD(GetFolderArcProps)(IFolderArcProps **object) PURE; -}; - -FOLDER_INTERFACE(IFolderCompare, 0x15) -{ - STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw) PURE; -}; - -#define INTERFACE_IFolderGetItemName(x) \ - STDMETHOD(GetItemName)(UInt32 index, const wchar_t **name, unsigned *len) x; \ - STDMETHOD(GetItemPrefix)(UInt32 index, const wchar_t **name, unsigned *len) x; \ - STDMETHOD_(UInt64, GetItemSize)(UInt32 index) x; \ - -FOLDER_INTERFACE(IFolderGetItemName, 0x16) -{ - INTERFACE_IFolderGetItemName(PURE) -}; - -#define FOLDER_MANAGER_INTERFACE(i, x) DECL_INTERFACE(i, 9, x) - -#define INTERFACE_IFolderManager(x) \ - STDMETHOD(OpenFolderFile)(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, IFolderFolder **resultFolder, IProgress *progress) x; \ - STDMETHOD(GetExtensions)(BSTR *extensions) x; \ - STDMETHOD(GetIconPath)(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) x; \ - - // STDMETHOD(GetTypes)(BSTR *types) PURE; - // STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE; - -FOLDER_MANAGER_INTERFACE(IFolderManager, 0x05) -{ - INTERFACE_IFolderManager(PURE); -}; - -/* -#define IMP_IFolderFolder_GetProp(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - const CMy_STATPROPSTG_2 &srcItem = k[index]; \ - *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \ - -#define IMP_IFolderFolder_Props(c) \ - STDMETHODIMP c::GetNumberOfProperties(UInt32 *numProperties) \ - { *numProperties = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP c::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps) -*/ - -#define IMP_IFolderFolder_GetProp(k) \ - (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ - { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ - -#define IMP_IFolderFolder_Props(c) \ - STDMETHODIMP c::GetNumberOfProperties(UInt32 *numProperties) \ - { *numProperties = ARRAY_SIZE(kProps); return S_OK; } \ - STDMETHODIMP c::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps) - - -int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2); -// int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2); - -#endif +// IFolder.h + +#ifndef ZIP7_INC_IFOLDER_H +#define ZIP7_INC_IFOLDER_H + +#include "../../IProgress.h" +#include "../../IStream.h" + +Z7_PURE_INTERFACES_BEGIN + +#define Z7_IFACE_CONSTR_FOLDER_SUB(i, base, n) \ + Z7_DECL_IFACE_7ZIP_SUB(i, base, 8, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACE_CONSTR_FOLDER(i, n) \ + Z7_IFACE_CONSTR_FOLDER_SUB(i, IUnknown, n) + +namespace NPlugin +{ + enum + { + kName = 0, + kType, + kClassID, + kOptionsClassID + }; +} + +#define Z7_IFACEM_IFolderFolder(x) \ + x(LoadItems()) \ + x(GetNumberOfItems(UInt32 *numItems)) \ + x(GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)) \ + x(BindToFolder(UInt32 index, IFolderFolder **resultFolder)) \ + x(BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) \ + x(BindToParentFolder(IFolderFolder **resultFolder)) \ + x(GetNumberOfProperties(UInt32 *numProperties)) \ + x(GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetFolderProperty(PROPID propID, PROPVARIANT *value)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderFolder, 0x00) + +/* + IFolderAltStreams:: + BindToAltStreams((UInt32)(Int32)-1, ... ) means alt streams of that folder +*/ + +#define Z7_IFACEM_IFolderAltStreams(x) \ + x(BindToAltStreams(UInt32 index, IFolderFolder **resultFolder)) \ + x(BindToAltStreams(const wchar_t *name, IFolderFolder **resultFolder)) \ + x(AreAltStreamsSupported(UInt32 index, Int32 *isSupported)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderAltStreams, 0x17) + +#define Z7_IFACEM_IFolderWasChanged(x) \ + x(WasChanged(Int32 *wasChanged)) +Z7_IFACE_CONSTR_FOLDER(IFolderWasChanged, 0x04) + + /* x(SetTotalFiles(UInt64 total)) */ \ + /* x(SetCompletedFiles(const UInt64 *completedValue)) */ \ +#define Z7_IFACEM_IFolderOperationsExtractCallback(x) \ + x(AskWrite( \ + const wchar_t *srcPath, \ + Int32 srcIsFolder, \ + const FILETIME *srcTime, \ + const UInt64 *srcSize, \ + const wchar_t *destPathRequest, \ + BSTR *destPathResult, \ + Int32 *writeAnswer)) \ + x(ShowMessage(const wchar_t *message)) \ + x(SetCurrentFilePath(const wchar_t *filePath)) \ + x(SetNumFiles(UInt64 numFiles)) \ + +Z7_IFACE_CONSTR_FOLDER_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B) + + +#define Z7_IFACEM_IFolderOperations(x) \ + x(CreateFolder(const wchar_t *name, IProgress *progress)) \ + x(CreateFile(const wchar_t *name, IProgress *progress)) \ + x(Rename(UInt32 index, const wchar_t *newName, IProgress *progress)) \ + x(Delete(const UInt32 *indices, UInt32 numItems, IProgress *progress)) \ + x(CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, \ + Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, \ + const wchar_t *path, IFolderOperationsExtractCallback *callback)) \ + x(CopyFrom(Int32 moveMode, const wchar_t *fromFolderPath, \ + const wchar_t * const *itemsPaths, UInt32 numItems, IProgress *progress)) \ + x(SetProperty(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress)) \ + x(CopyFromFile(UInt32 index, const wchar_t *fullFilePath, IProgress *progress)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderOperations, 0x13) + +/* +FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03) +{ + x(DeleteToRecycleBin(const UInt32 *indices, UInt32 numItems, IProgress *progress)) \ +}; +*/ + +#define Z7_IFACEM_IFolderGetSystemIconIndex(x) \ + x(GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +Z7_IFACE_CONSTR_FOLDER(IFolderGetSystemIconIndex, 0x07) + +#define Z7_IFACEM_IFolderGetItemFullSize(x) \ + x(GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress)) +Z7_IFACE_CONSTR_FOLDER(IFolderGetItemFullSize, 0x08) + +#define Z7_IFACEM_IFolderCalcItemFullSize(x) \ + x(CalcItemFullSize(UInt32 index, IProgress *progress)) +Z7_IFACE_CONSTR_FOLDER(IFolderCalcItemFullSize, 0x14) + +#define Z7_IFACEM_IFolderClone(x) \ + x(Clone(IFolderFolder **resultFolder)) +Z7_IFACE_CONSTR_FOLDER(IFolderClone, 0x09) + +#define Z7_IFACEM_IFolderSetFlatMode(x) \ + x(SetFlatMode(Int32 flatMode)) +Z7_IFACE_CONSTR_FOLDER(IFolderSetFlatMode, 0x0A) + +/* +#define Z7_IFACEM_IFolderSetShowNtfsStreamsMode(x) \ + x(SetShowNtfsStreamsMode(Int32 showStreamsMode)) +Z7_IFACE_CONSTR_FOLDER(IFolderSetShowNtfsStreamsMode, 0xFA) +*/ + +#define Z7_IFACEM_IFolderProperties(x) \ + x(GetNumberOfFolderProperties(UInt32 *numProperties)) \ + x(GetFolderPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderProperties, 0x0E) + +#define Z7_IFACEM_IFolderArcProps(x) \ + x(GetArcNumLevels(UInt32 *numLevels)) \ + x(GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)) \ + x(GetArcNumProps(UInt32 level, UInt32 *numProps)) \ + x(GetArcPropInfo(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + x(GetArcProp2(UInt32 level, PROPID propID, PROPVARIANT *value)) \ + x(GetArcNumProps2(UInt32 level, UInt32 *numProps)) \ + x(GetArcPropInfo2(UInt32 level, UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderArcProps, 0x10) + +#define Z7_IFACEM_IGetFolderArcProps(x) \ + x(GetFolderArcProps(IFolderArcProps **object)) +Z7_IFACE_CONSTR_FOLDER(IGetFolderArcProps, 0x11) + +#define Z7_IFACEM_IFolderCompare(x) \ + x##2(Int32, CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw)) +Z7_IFACE_CONSTR_FOLDER(IFolderCompare, 0x15) + +#define Z7_IFACEM_IFolderGetItemName(x) \ + x(GetItemName(UInt32 index, const wchar_t **name, unsigned *len)) \ + x(GetItemPrefix(UInt32 index, const wchar_t **name, unsigned *len)) \ + x##2(UInt64, GetItemSize(UInt32 index)) \ + +Z7_IFACE_CONSTR_FOLDER(IFolderGetItemName, 0x16) + + +#define Z7_IFACEM_IFolderManager(x) \ + x(OpenFolderFile(IInStream *inStream, const wchar_t *filePath, const wchar_t *arcFormat, IFolderFolder **resultFolder, IProgress *progress)) \ + x(GetExtensions(BSTR *extensions)) \ + x(GetIconPath(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex)) \ + + // x(GetTypes(BSTR *types)) + // x(CreateFolderFile(const wchar_t *type, const wchar_t *filePath, IProgress *progress)) + +Z7_DECL_IFACE_7ZIP(IFolderManager, 9, 5) + { Z7_IFACE_COM7_PURE(IFolderManager) }; + +/* + const CMy_STATPROPSTG_2 &srcItem = k[index]; \ + *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \ +*/ +#define IMP_IFolderFolder_GetProp(fn, k) \ + Z7_COM7F_IMF(fn(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)) \ + { if (index >= Z7_ARRAY_SIZE(k)) return E_INVALIDARG; \ + *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = NULL; return S_OK; } \ + +#define IMP_IFolderFolder_Props(c) \ + Z7_COM7F_IMF(c::GetNumberOfProperties(UInt32 *numProperties)) \ + { *numProperties = Z7_ARRAY_SIZE(kProps); return S_OK; } \ + IMP_IFolderFolder_GetProp(c::GetPropertyInfo, kProps) + + +int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2); +// int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2); + +Z7_PURE_INTERFACES_END +#endif Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Info.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Info.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Info2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Info2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.cpp 2024-03-23 10:00:00.000000000 +0000 @@ -0,0 +1,361 @@ +// LangPage.cpp + +#include "StdAfx.h" + +#include "../../../Common/Lang.h" + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/ResourceString.h" + +#include "HelpUtils.h" +#include "LangPage.h" +#include "LangPageRes.h" +#include "LangUtils.h" +#include "RegistryUtils.h" + +using namespace NWindows; + + +static const unsigned k_NumLangLines_EN = 443; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_LANG_LANG +}; +#endif + +#define kLangTopic "fm/options.htm#language" + + +struct CLangListRecord +{ + int Order; + unsigned LangInfoIndex; + bool IsSelected; + UString Mark; + UString Name; + + CLangListRecord(): Order (10), IsSelected(false) {} + int Compare(const CLangListRecord &a) const + { + if (Order < a.Order) return -1; + if (Order > a.Order) return 1; + return MyStringCompareNoCase(Name, a.Name); + } +}; + + +static void NativeLangString(UString &dest, const wchar_t *s) +{ + dest += " ("; + dest += s; + dest.Add_Char(')'); +} + +bool LangOpen(CLang &lang, CFSTR fileName); + +bool CLangPage::OnInit() +{ +#ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); +#endif + _langCombo.Attach(GetItem(IDC_LANG_LANG)); + + + unsigned listRecords_SelectedIndex = 0; + + CObjectVector listRecords; + { + CLangListRecord listRecord; + listRecord.Order = 0; + listRecord.Mark = "---"; + listRecord.Name = MyLoadString(IDS_LANG_ENGLISH); + NativeLangString(listRecord.Name, MyLoadString(IDS_LANG_NATIVE)); + listRecord.LangInfoIndex = _langs.Size(); + listRecords.Add(listRecord); + } + + AStringVector names; + unsigned subLangIndex = 0; + Lang_GetShortNames_for_DefaultLang(names, subLangIndex); + + const FString dirPrefix = GetLangDirPrefix(); + NFile::NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(dirPrefix); + NFile::NFind::CFileInfo fi; + + CLang lang_en; + { + CLangInfo &langInfo = _langs.AddNew(); + langInfo.Name = "-"; + if (LangOpen(lang_en, dirPrefix + FTEXT("en.ttt"))) + { + langInfo.NumLines = lang_en._ids.Size(); + // langInfo.Comments = lang_en.Comments; + } + else + langInfo.NumLines = k_NumLangLines_EN; + NumLangLines_EN = langInfo.NumLines; + } + + CLang lang; + UString error; + UString n; + + while (enumerator.Next(fi)) + { + if (fi.IsDir()) + continue; + const unsigned kExtSize = 4; + if (fi.Name.Len() < kExtSize) + continue; + const unsigned pos = fi.Name.Len() - kExtSize; + if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".txt")) + { + // if (!StringsAreEqualNoCase_Ascii(fi.Name.Ptr(pos), ".ttt")) + continue; + } + + if (!LangOpen(lang, dirPrefix + fi.Name)) + { + error.Add_Space_if_NotEmpty(); + error += fs2us(fi.Name); + continue; + } + + const UString shortName = fs2us(fi.Name.Left(pos)); + + CLangListRecord listRecord; + if (!names.IsEmpty()) + { + for (unsigned i = 0; i < names.Size(); i++) + if (shortName.IsEqualTo_Ascii_NoCase(names[i])) + { + if (subLangIndex == i || names.Size() == 1) + { + listRecord.Mark = "***"; + // listRecord.Order = 1; + } + else + { + listRecord.Mark = "+++"; + // listRecord.Order = 2; + } + break; + } + if (listRecord.Mark.IsEmpty()) + { + const int minusPos = shortName.Find(L'-'); + if (minusPos >= 0) + { + const UString shortName2 = shortName.Left(minusPos); + if (shortName2.IsEqualTo_Ascii_NoCase(names[0])) + { + listRecord.Mark = "+++"; + // listRecord.Order = 3; + } + } + } + } + UString s = shortName; + const wchar_t *eng = lang.Get(IDS_LANG_ENGLISH); + if (eng) + s = eng; + const wchar_t *native = lang.Get(IDS_LANG_NATIVE); + if (native) + NativeLangString(s, native); + + listRecord.Name = s; + listRecord.LangInfoIndex = _langs.Size(); + listRecords.Add(listRecord); + if (g_LangID.IsEqualTo_NoCase(shortName)) + listRecords_SelectedIndex = listRecords.Size() - 1; + + CLangInfo &langInfo = _langs.AddNew(); + langInfo.Comments = lang.Comments; + langInfo.Name = shortName; + unsigned numLines = lang._ids.Size(); + if (!lang_en.IsEmpty()) + { + numLines = 0; + unsigned i1 = 0; + unsigned i2 = 0; + for (;;) + { + UInt32 id1 = (UInt32)0 - 1; + UInt32 id2 = (UInt32)0 - 1; + bool id1_defined = false; + bool id2_defined = false; + if (i1 < lang_en._ids.Size()) + { + id1 = lang_en._ids[i1]; + id1_defined = true; + } + if (i2 < lang._ids.Size()) + { + id2 = lang._ids[i2]; + id2_defined = true; + } + + bool id1_is_smaller = true; + if (id1_defined) + { + if (id2_defined) + { + if (id1 == id2) + { + i1++; + i2++; + numLines++; + continue; + } + if (id1 > id2) + id1_is_smaller = false; + } + } + else if (!id2_defined) + break; + else + id1_is_smaller = false; + + n.Empty(); + if (id1_is_smaller) + { + n.Add_UInt32(id1); + n += " : "; + n += lang_en.Get_by_index(i1); + langInfo.MissingLines.Add(n); + i1++; + } + else + { + n.Add_UInt32(id2); + n += " : "; + n += lang.Get_by_index(i2); + langInfo.ExtraLines.Add(n); + i2++; + } + } + } + langInfo.NumLines = numLines + langInfo.ExtraLines.Size(); + } + + listRecords[listRecords_SelectedIndex].IsSelected = true; + + listRecords.Sort(); + FOR_VECTOR (i, listRecords) + { + const CLangListRecord &rec= listRecords[i]; + UString temp = rec.Name; + if (!rec.Mark.IsEmpty()) + { + temp += " "; + temp += rec.Mark; + } + const int index = (int)_langCombo.AddString(temp); + _langCombo.SetItemData(index, (LPARAM)rec.LangInfoIndex); + if (rec.IsSelected) + _langCombo.SetCurSel(index); + } + + ShowLangInfo(); + + if (!error.IsEmpty()) + MessageBoxW(NULL, error, L"Error in Lang file", MB_ICONERROR); + return CPropertyPage::OnInit(); +} + +LONG CLangPage::OnApply() +{ + if (_needSave) + { + const int pathIndex = (int)_langCombo.GetItemData_of_CurSel(); + if ((unsigned)pathIndex < _langs.Size()) + SaveRegLang(_langs[pathIndex].Name); + } + _needSave = false; + #ifdef Z7_LANG + ReloadLang(); + #endif + LangWasChanged = true; + return PSNRET_NOERROR; +} + +void CLangPage::OnNotifyHelp() +{ + ShowHelpWindow(kLangTopic); +} + +bool CLangPage::OnCommand(unsigned code, unsigned itemID, LPARAM param) +{ + if (code == CBN_SELCHANGE && itemID == IDC_LANG_LANG) + { + _needSave = true; + Changed(); + ShowLangInfo(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, param); +} + +static void AddVectorToString(UString &s, const UStringVector &v) +{ + UString a; + FOR_VECTOR (i, v) + { + if (i >= 50) + break; + a = v[i]; + if (a.Len() > 1500) + continue; + if (a[0] == ';') + { + a.DeleteFrontal(1); + a.Trim(); + } + s += a; + s.Add_LF(); + } +} + +static void AddVectorToString2(UString &s, const char *name, const UStringVector &v) +{ + if (v.IsEmpty()) + return; + s.Add_LF(); + s += "------ "; + s += name; + s += ": "; + s.Add_UInt32(v.Size()); + s += " :"; + s.Add_LF(); + AddVectorToString(s, v); +} + +void CLangPage::ShowLangInfo() +{ + UString s; + const int pathIndex = (int)_langCombo.GetItemData_of_CurSel(); + if ((unsigned)pathIndex < _langs.Size()) + { + const CLangInfo &langInfo = _langs[pathIndex]; + const unsigned numLines = langInfo.NumLines; + s += langInfo.Name; + s += " : "; + s.Add_UInt32(numLines); + if (NumLangLines_EN != 0) + { + s += " / "; + s.Add_UInt32(NumLangLines_EN); + s += " = "; + s.Add_UInt32(numLines * 100 / NumLangLines_EN); + s += "%"; + } + s.Add_LF(); + AddVectorToString(s, langInfo.Comments); + AddVectorToString2(s, "Missing lines", langInfo.MissingLines); + AddVectorToString2(s, "Extra lines", langInfo.ExtraLines); + } + SetItemText(IDT_LANG_INFO, s); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.h 2023-05-16 14:00:00.000000000 +0000 @@ -0,0 +1,36 @@ +// LangPage.h + +#ifndef ZIP7_INC_LANG_PAGE_H +#define ZIP7_INC_LANG_PAGE_H + +#include "../../../Windows/Control/PropertyPage.h" +#include "../../../Windows/Control/ComboBox.h" + +struct CLangInfo +{ + unsigned NumLines; + UString Name; + UStringVector Comments; + UStringVector MissingLines; + UStringVector ExtraLines; +}; + +class CLangPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CComboBox _langCombo; + CObjectVector _langs; + unsigned NumLangLines_EN; + bool _needSave; + + void ShowLangInfo(); +public: + bool LangWasChanged; + + CLangPage(): _needSave(false), LangWasChanged(false) {} + virtual bool OnInit() Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM param) Z7_override; + virtual LONG OnApply() Z7_override; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPage.rc 2024-03-17 04:00:00.000000000 +0000 @@ -0,0 +1,40 @@ +#include "LangPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc OPTIONS_PAGE_YC_SIZE + +#define y 32 + +IDD_LANG DIALOG MY_PAGE_POSTFIX +CAPTION "Language" +{ + LTEXT "Language:", IDT_LANG_LANG, m, m, xc, 8 + COMBOBOX IDC_LANG_LANG, m, 20, 160, yc - 20, MY_COMBO // MY_COMBO_SORTED + LTEXT "", IDT_LANG_INFO, m, m + y, xc, yc - y, SS_NOPREFIX +} + + +#ifdef UNDER_CE + +#undef m +#undef xc + +#define m 4 +#define xc (SMALL_PAGE_SIZE_X + 8) + +IDD_LANG_2 MY_PAGE +CAPTION "Language" +{ + LTEXT "Language:", IDT_LANG_LANG, m, m, xc, 8 + COMBOBOX IDC_LANG_LANG, m, 20, xc, yc - 20, MY_COMBO // MY_COMBO_SORTED +} + +#endif + + +STRINGTABLE +BEGIN + IDS_LANG_ENGLISH "English" + IDS_LANG_NATIVE "English" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangPageRes.h 2023-05-15 07:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_LANG 2101 +#define IDD_LANG_2 12101 + +#define IDS_LANG_ENGLISH 1 +#define IDS_LANG_NATIVE 2 + +#define IDT_LANG_LANG 2102 +#define IDC_LANG_LANG 100 +#define IDT_LANG_INFO 101 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangUtils.cpp 2016-02-01 16:38:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.cpp 2025-01-07 20:00:00.000000000 +0000 @@ -1,288 +1,333 @@ -// LangUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/Lang.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/Synchronization.h" -#include "../../../Windows/Window.h" - -#include "LangUtils.h" -#include "RegistryUtils.h" - -using namespace NWindows; - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -UString g_LangID; - -static CLang g_Lang; -static bool g_Loaded = false; -static NSynchronization::CCriticalSection g_CriticalSection; - -bool LangOpen(CLang &lang, CFSTR fileName) -{ - return lang.Open(fileName, L"7-Zip"); -} - -FString GetLangDirPrefix() -{ - return NDLL::GetModuleDirPrefix() + FTEXT("Lang") FSTRING_PATH_SEPARATOR; -} - -void LoadLangOneTime() -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - if (g_Loaded) - return; - g_Loaded = true; - ReloadLang(); -} - -void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID) -{ - const wchar_t *s = g_Lang.Get(langID); - if (s) - { - CWindow window(GetDlgItem(dialog, controlID)); - window.SetText(s); - } -} - -static const CIDLangPair kLangPairs[] = -{ - { IDOK, 401 }, - { IDCANCEL, 402 }, - { IDYES, 406 }, - { IDNO, 407 }, - { IDHELP, 409 } -}; - - -void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE(kLangPairs); i++) - { - const CIDLangPair &pair = kLangPairs[i]; - CWindow window(GetDlgItem(dialog, pair.ControlID)); - if (window) - { - const wchar_t *s = g_Lang.Get(pair.LangID); - if (s) - window.SetText(s); - } - } - - for (i = 0; i < numItems; i++) - { - UInt32 id = ids[i]; - LangSetDlgItemText(dialog, id, id); - } -} - -void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems) -{ - for (unsigned i = 0; i < numItems; i++) - { - UInt32 id = ids[i]; - const wchar_t *s = g_Lang.Get(id); - if (s) - { - CWindow window(GetDlgItem(dialog, id)); - UString s2 = s; - s2 += L':'; - window.SetText(s2); - } - } -} - -void LangSetWindowText(HWND window, UInt32 langID) -{ - const wchar_t *s = g_Lang.Get(langID); - if (s) - MySetWindowText(window, s); -} - -UString LangString(UInt32 langID) -{ - const wchar_t *s = g_Lang.Get(langID); - if (s) - return s; - return MyLoadString(langID); -} - -void AddLangString(UString &s, UInt32 langID) -{ - s += LangString(langID); -} - -void LangString(UInt32 langID, UString &dest) -{ - const wchar_t *s = g_Lang.Get(langID); - if (s) - { - dest = s; - return; - } - MyLoadString(langID, dest); -} - -void LangString_OnlyFromLangFile(UInt32 langID, UString &dest) -{ - dest.Empty(); - const wchar_t *s = g_Lang.Get(langID); - if (s) - dest = s; -} - -static const char *kLangs = - "ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is." - "it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.sk.sq.sv.th.tr." - "ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk." - "st.ts.tn.ve.xh.zu.af.ka.fo.hi.mt.se.ga.yi.ms.kk." - "ky.sw.tk.uz.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa." - "mn.=mn.=mng.bo.cy.kh.lo.my.gl.kok..sd.syr.si..iu.am.tzm." - "ks.ne.fy.ps.tl.dv..ff.ha..yo.qu.st.ba.lb.kl." - "ig.kr.om.ti.gn..la.so.ii..arn..moh..br.." - "ug.mi.oc.co." - // "gsw.sah.qut.rw.wo....prs...." - // ".gd." - ; - -static void FindShortNames(UInt32 primeLang, UStringVector &names) -{ - UInt32 index = 0; - for (const char *p = kLangs; *p != 0;) - { - const char *p2 = p; - for (; *p2 != '.'; p2++); - bool isSub = (p[0] == '-' || p[0] == '='); - if (!isSub) - index++; - if (index >= primeLang) - { - if (index > primeLang) - break; - UString s; - if (isSub) - { - if (p[0] == '-') - s = names[0]; - else - p++; - } - while (p != p2) - s += (wchar_t)(Byte)*p++; - names.Add(s); - } - p = p2 + 1; - } -} - -/* -#include "../../../Common/IntToString.h" - -static struct CC1Lang -{ - CC1Lang() - { - for (int i = 1; i < 150; i++) - { - UString s; - char ttt[32]; - ConvertUInt32ToHex(i, ttt); - s.AddAscii(ttt); - UStringVector names; - FindShortNames(i, names); - - FOR_VECTOR (k, names) - { - s.Add_Space(); - s += names[k]; - } - OutputDebugStringW(s); - } - } -} g_cc1; -*/ - -// typedef LANGID (WINAPI *GetUserDefaultUILanguageP)(); - -static void OpenDefaultLang() -{ - LANGID sysLang = GetSystemDefaultLangID(); // "Language for non-Unicode programs" in XP64 - LANGID userLang = GetUserDefaultLangID(); // "Standards and formats" language in XP64 - - if (sysLang != userLang) - return; - LANGID langID = userLang; - - /* - LANGID sysUILang; // english in XP64 - LANGID userUILang; // english in XP64 - - GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress( - GetModuleHandle("kernel32"), "GetUserDefaultUILanguage"); - if (fn) - userUILang = fn(); - fn = (GetUserDefaultUILanguageP)GetProcAddress( - GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage"); - if (fn) - sysUILang = fn(); - */ - - WORD primLang = (WORD)(PRIMARYLANGID(langID)); - WORD subLang = (WORD)(SUBLANGID(langID)); - { - UStringVector names; - FindShortNames(primLang, names); - const FString dirPrefix = GetLangDirPrefix(); - for (unsigned i = 0; i < 2; i++) - { - unsigned index = (i == 0 ? subLang : 0); - if (index < names.Size()) - { - const UString &name = names[index]; - if (!name.IsEmpty()) - { - if (LangOpen(g_Lang, dirPrefix + us2fs(name) + FTEXT(".txt"))) - { - g_LangID = name; - return; - } - } - } - } - } -} - -void ReloadLang() -{ - g_Lang.Clear(); - ReadRegLang(g_LangID); - #ifndef _UNICODE - if (g_IsNT) - #endif - { - if (g_LangID.IsEmpty()) - { - OpenDefaultLang(); - return; - } - } - if (g_LangID.Len() > 1 || g_LangID[0] != L'-') - { - FString s = us2fs(g_LangID); - if (s.Find(FCHAR_PATH_SEPARATOR) < 0) - { - if (s.Find(FTEXT('.')) < 0) - s += FTEXT(".txt"); - s.Insert(0, GetLangDirPrefix()); - } - LangOpen(g_Lang, s); - } -} +// LangUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/Lang.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Window.h" + +#include "LangUtils.h" +#include "RegistryUtils.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +UString g_LangID; + +// static +CLang g_Lang; +static bool g_Loaded = false; +static NSynchronization::CCriticalSection g_CriticalSection; + +bool LangOpen(CLang &lang, CFSTR fileName); +bool LangOpen(CLang &lang, CFSTR fileName) +{ + return lang.Open(fileName, "7-Zip"); +} + +FString GetLangDirPrefix() +{ + return NDLL::GetModuleDirPrefix() + FTEXT("Lang") FSTRING_PATH_SEPARATOR; +} + +#ifdef Z7_LANG + +void LoadLangOneTime() +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (g_Loaded) + return; + g_Loaded = true; + ReloadLang(); +} + +void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID) +{ + const wchar_t *s = g_Lang.Get(langID); + if (s) + { + CWindow window(GetDlgItem(dialog, (int)controlID)); + window.SetText(s); + } +} + +#ifndef IDCONTINUE +#define IDCONTINUE 11 +#endif + +static const CIDLangPair kLangPairs[] = +{ + { IDOK, 401 }, + { IDCANCEL, 402 }, + { IDYES, 406 }, + { IDNO, 407 }, + { IDCLOSE, 408 }, + { IDHELP, 409 }, + { IDCONTINUE, 411 } +}; + + +void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems) +{ + unsigned i; + for (i = 0; i < Z7_ARRAY_SIZE(kLangPairs); i++) + { + const CIDLangPair &pair = kLangPairs[i]; + CWindow window(GetDlgItem(dialog, (int)pair.ControlID)); + if (window) + { + const wchar_t *s = g_Lang.Get(pair.LangID); + if (s) + window.SetText(s); + } + } + + for (i = 0; i < numItems; i++) + { + const UInt32 id = ids[i]; + LangSetDlgItemText(dialog, id, id); + } +} + +void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems) +{ + for (unsigned i = 0; i < numItems; i++) + { + const UInt32 id = ids[i]; + const wchar_t *s = g_Lang.Get(id); + if (s) + { + CWindow window(GetDlgItem(dialog, (int)id)); + UString s2 = s; + s2.Add_Colon(); + window.SetText(s2); + } + } +} + +void LangSetDlgItems_RemoveColon(HWND dialog, const UInt32 *ids, unsigned numItems) +{ + for (unsigned i = 0; i < numItems; i++) + { + const UInt32 id = ids[i]; + const wchar_t *s = g_Lang.Get(id); + if (s) + { + CWindow window(GetDlgItem(dialog, (int)id)); + UString s2 = s; + if (!s2.IsEmpty() && s2.Back() == ':') + s2.DeleteBack(); + window.SetText(s2); + } + } +} + +void LangSetWindowText(HWND window, UInt32 langID) +{ + const wchar_t *s = g_Lang.Get(langID); + if (s) + MySetWindowText(window, s); +} + +UString LangString(UInt32 langID) +{ + const wchar_t *s = g_Lang.Get(langID); + if (s) + return s; + return MyLoadString(langID); +} + +void AddLangString(UString &s, UInt32 langID) +{ + s += LangString(langID); +} + +void LangString(UInt32 langID, UString &dest) +{ + const wchar_t *s = g_Lang.Get(langID); + if (s) + { + dest = s; + return; + } + MyLoadString(langID, dest); +} + +void LangString_OnlyFromLangFile(UInt32 langID, UString &dest) +{ + dest.Empty(); + const wchar_t *s = g_Lang.Get(langID); + if (s) + dest = s; +} + +static const char * const kLangs = + "ar.bg.ca.zh.-tw.-cn.cs.da.de.el.en.es.fi.fr.he.hu.is." + "it.ja.ko.nl.no.=nb.=nn.pl.pt.-br.rm.ro.ru.sr.=hr.-spl.-spc.=hr.=bs.sk.sq.sv.th.tr." + "ur.id.uk.be.sl.et.lv.lt.tg.fa.vi.hy.az.eu.hsb.mk." + "st.ts.tn.ve.xh.zu.af.ka.fo.hi.mt.se.ga.yi.ms.kk." + "ky.sw.tk.uz.-latn.-cyrl.tt.bn.pa.-in.gu.or.ta.te.kn.ml.as.mr.sa." + "mn.=mn.=mng.bo.cy.kh.lo.my.gl.kok..sd.syr.si..iu.am.tzm." + "ks.ne.fy.ps.tl.dv..ff.ha..yo.qu.st.ba.lb.kl." + "ig.kr.om.ti.gn..la.so.ii..arn..moh..br.." + "ug.mi.oc.co." + // "gsw.sah.qut.rw.wo....prs...." + // ".gd." + ; + +static void FindShortNames(UInt32 primeLang, AStringVector &names) +{ + UInt32 index = 0; + for (const char *p = kLangs; *p != 0;) + { + const char *p2 = p; + for (; *p2 != '.'; p2++); + bool isSub = (p[0] == '-' || p[0] == '='); + if (!isSub) + index++; + if (index >= primeLang) + { + if (index > primeLang) + break; + AString s; + if (isSub) + { + if (p[0] == '-') + s = names[0]; + else + p++; + } + while (p != p2) + s.Add_Char((char)(Byte)*p++); + names.Add(s); + } + p = p2 + 1; + } +} + +/* +#include "../../../Common/IntToString.h" + +static struct CC1Lang +{ + CC1Lang() + { + for (int i = 1; i < 150; i++) + { + UString s; + char ttt[32]; + ConvertUInt32ToHex(i, ttt); + s += ttt; + UStringVector names; + FindShortNames(i, names); + + FOR_VECTOR (k, names) + { + s.Add_Space(); + s += names[k]; + } + OutputDebugStringW(s); + } + } +} g_cc1; +*/ + +// typedef LANGID (WINAPI *GetUserDefaultUILanguageP)(); + +void Lang_GetShortNames_for_DefaultLang(AStringVector &names, unsigned &subLang) +{ + names.Clear(); + subLang = 0; + // Region / Administative / Language for non-Unicode programs: + const LANGID sysLang = GetSystemDefaultLangID(); + + // Region / Formats / Format: + const LANGID userLang = GetUserDefaultLangID(); + + if (PRIMARYLANGID(sysLang) != + PRIMARYLANGID(userLang)) + return; + const LANGID langID = userLang; + + // const LANGID langID = MAKELANGID(0x1a, 1); // for debug + + /* + LANGID sysUILang; // english in XP64 + LANGID userUILang; // english in XP64 + + GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress( + GetModuleHandle("kernel32"), "GetUserDefaultUILanguage"); + if (fn) + userUILang = fn(); + fn = (GetUserDefaultUILanguageP)GetProcAddress( + GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage"); + if (fn) + sysUILang = fn(); + */ + + const WORD primLang = (WORD)(PRIMARYLANGID(langID)); + subLang = SUBLANGID(langID); + FindShortNames(primLang, names); +} + + +static void OpenDefaultLang() +{ + AStringVector names; + unsigned subLang; + Lang_GetShortNames_for_DefaultLang(names, subLang); + { + const FString dirPrefix (GetLangDirPrefix()); + for (unsigned i = 0; i < 2; i++) + { + const unsigned index = (i == 0 ? subLang : 0); + if (index < names.Size()) + { + const AString &name = names[index]; + if (!name.IsEmpty()) + { + FString path (dirPrefix); + path += name; + path += ".txt"; + if (LangOpen(g_Lang, path)) + { + g_LangID = name; + return; + } + } + } + } + } +} + +void ReloadLang() +{ + g_Lang.Clear(); + ReadRegLang(g_LangID); + if (g_LangID.IsEmpty()) + { +#ifndef _UNICODE + if (g_IsNT) +#endif + OpenDefaultLang(); + return; + } + if (g_LangID.Len() > 1 || g_LangID[0] != L'-') + { + FString s = us2fs(g_LangID); + if (s.ReverseFind_PathSepar() < 0) + { + if (s.ReverseFind_Dot() < 0) + s += ".txt"; + s.Insert(0, GetLangDirPrefix()); + LangOpen(g_Lang, s); + } + } +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LangUtils.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LangUtils.h 2023-06-18 08:00:00.000000000 +0000 @@ -1,40 +1,48 @@ -// LangUtils.h - -#ifndef __LANG_UTILS_H -#define __LANG_UTILS_H - -#include "../../../Windows/ResourceString.h" - -#ifdef LANG - -extern UString g_LangID; - -struct CIDLangPair -{ - UInt32 ControlID; - UInt32 LangID; -}; - -void ReloadLang(); -void LoadLangOneTime(); -FString GetLangDirPrefix(); - -void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID); -void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems); -void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems); -void LangSetWindowText(HWND window, UInt32 langID); - -UString LangString(UInt32 langID); -void AddLangString(UString &s, UInt32 langID); -void LangString(UInt32 langID, UString &dest); -void LangString_OnlyFromLangFile(UInt32 langID, UString &dest); - -#else - -inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); } -inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); } -inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); } - -#endif - -#endif +// LangUtils.h + +#ifndef ZIP7_INC_LANG_UTILS_H +#define ZIP7_INC_LANG_UTILS_H + +#include "../../../Common/Lang.h" + +#include "../../../Windows/ResourceString.h" + +extern UString g_LangID; +extern CLang g_Lang; + +#ifdef Z7_LANG + +struct CIDLangPair +{ + UInt32 ControlID; + UInt32 LangID; +}; + +void ReloadLang(); +void LoadLangOneTime(); + +void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID); +void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetDlgItems_RemoveColon(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetWindowText(HWND window, UInt32 langID); + +UString LangString(UInt32 langID); +void AddLangString(UString &s, UInt32 langID); +void LangString(UInt32 langID, UString &dest); +void LangString_OnlyFromLangFile(UInt32 langID, UString &dest); + +#else + +inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); } +inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); } +inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); } + +#endif + +FString GetLangDirPrefix(); +// bool LangOpen(CLang &lang, CFSTR fileName); + +void Lang_GetShortNames_for_DefaultLang(AStringVector &names, unsigned &subLang); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.cpp 2025-06-20 10:00:00.000000000 +0000 @@ -0,0 +1,402 @@ +// LinkDialog.cpp + +#include "StdAfx.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" + +#include "LangUtils.h" + +#include "BrowseDialog.h" +#include "CopyDialogRes.h" +#include "LinkDialog.h" +#include "resourceGui.h" + +#include "App.h" + +#include "resource.h" + +extern bool g_SymLink_Supported; + +using namespace NWindows; +using namespace NFile; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDB_LINK_LINK, + IDT_LINK_PATH_FROM, + IDT_LINK_PATH_TO, + IDG_LINK_TYPE, + IDR_LINK_TYPE_HARD, + IDR_LINK_TYPE_SYM_FILE, + IDR_LINK_TYPE_SYM_DIR, + IDR_LINK_TYPE_JUNCTION, + IDR_LINK_TYPE_WSL +}; +#endif + + +static bool GetSymLink(CFSTR path, CReparseAttr &attr, UString &errorMessage) +{ + CByteBuffer buf; + if (!NIO::GetReparseData(path, buf, NULL)) + return false; + if (!attr.Parse(buf, buf.Size())) + { + SetLastError(attr.ErrorCode); + return false; + } + CByteBuffer data2; + FillLinkData(data2, attr.GetPath(), + !attr.IsMountPoint(), attr.IsSymLink_WSL()); + if (data2.Size() == 0) + { + errorMessage = "Cannot reproduce reparse point"; + return false; + } + if (data2 != buf) + { + errorMessage = "mismatch for reproduced reparse point"; + return false; + } + return true; +} + + +static const unsigned k_LinkType_Buttons[] = +{ + IDR_LINK_TYPE_HARD, + IDR_LINK_TYPE_SYM_FILE, + IDR_LINK_TYPE_SYM_DIR, + IDR_LINK_TYPE_JUNCTION, + IDR_LINK_TYPE_WSL +}; + +void CLinkDialog::Set_LinkType_Radio(unsigned idb) +{ + CheckRadioButton( + k_LinkType_Buttons[0], + k_LinkType_Buttons[Z7_ARRAY_SIZE(k_LinkType_Buttons) - 1], + idb); +} + +bool CLinkDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_LINK); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + + _pathFromCombo.Attach(GetItem(IDC_LINK_PATH_FROM)); + _pathToCombo.Attach(GetItem(IDC_LINK_PATH_TO)); + + if (!FilePath.IsEmpty()) + { + NFind::CFileInfo fi; + unsigned linkType = 0; + if (!fi.Find(us2fs(FilePath))) + linkType = IDR_LINK_TYPE_SYM_FILE; + else + { + if (fi.HasReparsePoint()) + { + CReparseAttr attr; + UString error; + const bool res = GetSymLink(us2fs(FilePath), attr, error); + if (!res && error.IsEmpty()) + { + const DWORD lastError = GetLastError(); + if (lastError) + error = NError::MyFormatMessage(lastError); + } + + UString s = attr.GetPath(); + if (!attr.IsSymLink_WSL()) + if (!attr.IsOkNamePair()) + { + s += " : "; + s += attr.PrintName; + } + + if (!res) + { + s.Insert(0, L"ERROR: "); + if (!error.IsEmpty()) + { + s += " : "; + s += error; + } + } + + + SetItemText(IDT_LINK_PATH_TO_CUR, s); + + const UString destPath = attr.GetPath(); + _pathFromCombo.SetText(FilePath); + _pathToCombo.SetText(destPath); + + // if (res) + { + if (attr.IsMountPoint()) + linkType = IDR_LINK_TYPE_JUNCTION; + else if (attr.IsSymLink_WSL()) + linkType = IDR_LINK_TYPE_WSL; + else if (attr.IsSymLink_Win()) + { + linkType = + fi.IsDir() ? + IDR_LINK_TYPE_SYM_DIR : + IDR_LINK_TYPE_SYM_FILE; + // if (attr.IsRelative()) linkType = IDR_LINK_TYPE_SYM_RELATIVE; + } + + if (linkType != 0) + Set_LinkType_Radio(linkType); + } + } + else + { + // no ReparsePoint + _pathFromCombo.SetText(AnotherPath); + _pathToCombo.SetText(FilePath); + if (fi.IsDir()) + linkType = g_SymLink_Supported ? + IDR_LINK_TYPE_SYM_DIR : + IDR_LINK_TYPE_JUNCTION; + else + linkType = IDR_LINK_TYPE_HARD; + } + } + if (linkType != 0) + Set_LinkType_Radio(linkType); + } + + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CLinkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDB_LINK_LINK, bx2, by); + int yPos = ySize - my - by; + int xPos = xSize - mx - bx1; + + InvalidateRect(NULL); + + { + RECT r, r2; + GetClientRectOfItem(IDB_LINK_PATH_FROM, r); + GetClientRectOfItem(IDB_LINK_PATH_TO, r2); + int bx = RECT_SIZE_X(r); + int newButtonXpos = xSize - mx - bx; + + MoveItem(IDB_LINK_PATH_FROM, newButtonXpos, r.top, bx, RECT_SIZE_Y(r)); + MoveItem(IDB_LINK_PATH_TO, newButtonXpos, r2.top, bx, RECT_SIZE_Y(r2)); + + int newComboXsize = newButtonXpos - mx - mx; + ChangeSubWindowSizeX(_pathFromCombo, newComboXsize); + ChangeSubWindowSizeX(_pathToCombo, newComboXsize); + } + + MoveItem(IDCANCEL, xPos, yPos, bx1, by); + MoveItem(IDB_LINK_LINK, xPos - mx - bx2, yPos, bx2, by); + + return false; +} + +bool CLinkDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_LINK_PATH_FROM: + OnButton_SetPath(false); + return true; + case IDB_LINK_PATH_TO: + OnButton_SetPath(true); + return true; + case IDB_LINK_LINK: + OnButton_Link(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CLinkDialog::OnButton_SetPath(bool to) +{ + UString currentPath; + NWindows::NControl::CComboBox &combo = to ? + _pathToCombo : + _pathFromCombo; + combo.GetText(currentPath); + // UString title = "Specify a location for output folder"; + const UString title = LangString(IDS_SET_FOLDER); + + UString resultPath; + if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) + return; + NName::NormalizeDirPathPrefix(resultPath); + combo.SetCurSel(-1); + combo.SetText(resultPath); +} + +void CLinkDialog::ShowError(const wchar_t *s) +{ + ::MessageBoxW(*this, s, L"7-Zip", MB_ICONERROR); +} + +void CLinkDialog::ShowLastErrorMessage() +{ + ShowError(NError::MyFormatMessage(GetLastError())); +} + +void CLinkDialog::OnButton_Link() +{ + UString from, to; + _pathFromCombo.GetText(from); + _pathToCombo.GetText(to); + + if (from.IsEmpty()) + return; + if (!NName::IsAbsolutePath(from)) + from.Insert(0, CurDirPrefix); + + unsigned idb = 0; + for (unsigned i = 0;; i++) + { + if (i >= Z7_ARRAY_SIZE(k_LinkType_Buttons)) + return; + idb = k_LinkType_Buttons[i]; + if (IsButtonCheckedBool(idb)) + break; + } + + NFind::CFileInfo info1, info2; + const bool finded1 = info1.Find(us2fs(from)); + const bool finded2 = info2.Find(us2fs(to)); + + const bool isDirLink = ( + idb == IDR_LINK_TYPE_SYM_DIR || + idb == IDR_LINK_TYPE_JUNCTION); + + const bool isWSL = (idb == IDR_LINK_TYPE_WSL); + + if (!isWSL) + if ((finded1 && info1.IsDir() != isDirLink) || + (finded2 && info2.IsDir() != isDirLink)) + { + ShowError(L"Incorrect link type"); + return; + } + + if (idb == IDR_LINK_TYPE_HARD) + { + if (!NDir::MyCreateHardLink(us2fs(from), us2fs(to))) + { + ShowLastErrorMessage(); + return; + } + } + else + { + if (finded1 && !info1.IsDir() && !info1.HasReparsePoint() && info1.Size != 0) + { + UString s ("WARNING: reparse point will hide the data of existing file"); + s.Add_LF(); + s += from; + ShowError(s); + return; + } + + CByteBuffer data; + const bool isSymLink = (idb != IDR_LINK_TYPE_JUNCTION); + FillLinkData(data, to, isSymLink, isWSL); + if (data.Size() == 0) + { + ShowError(L"Incorrect link"); + return; + } + + CReparseAttr attr; + if (!attr.Parse(data, data.Size())) + { + ShowError(L"Internal conversion error"); + return; + } + + bool res; + if (to.IsEmpty()) + { + // res = NIO::SetReparseData(us2fs(from), isDirLink, NULL, 0); + res = NIO::DeleteReparseData(us2fs(from)); + } + else + res = NIO::SetReparseData(us2fs(from), isDirLink, data, (DWORD)data.Size()); + + if (!res) + { + ShowLastErrorMessage(); + return; + } + } + + End(IDOK); +} + +void CApp::Link() +{ + const unsigned srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + CRecordVector indices; + srcPanel.Get_ItemIndices_Operated(indices); + if (indices.IsEmpty()) + return; + if (indices.Size() != 1) + { + srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE); + return; + } + const UInt32 index = indices[0]; + const UString itemName = srcPanel.GetItemName(index); + + const UString fsPrefix = srcPanel.GetFsPath(); + const UString srcPath = fsPrefix + srcPanel.GetItemPrefix(index); + UString path = srcPath; + { + const unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel.GetFsPath(); + } + + CSelectedState srcSelState; + srcPanel.SaveSelectedState(srcSelState); + + CLinkDialog dlg; + dlg.CurDirPrefix = fsPrefix; + dlg.FilePath = srcPath + itemName; + dlg.AnotherPath = path; + + if (dlg.Create(srcPanel.GetParent()) != IDOK) + return; + + // we refresh srcPanel to show changes in "Link" (kpidNtReparse) column. + // maybe we should refresh another panel also? + if (srcPanel._visibleColumns.FindItem_for_PropID(kpidNtReparse) >= 0) + srcPanel.RefreshListCtrl(srcSelState); + + RefreshTitleAlways(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,34 @@ +// LinkDialog.h + +#ifndef ZIP7_INC_LINK_DIALOG_H +#define ZIP7_INC_LINK_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ComboBox.h" + +#include "LinkDialogRes.h" + +class CLinkDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _pathFromCombo; + NWindows::NControl::CComboBox _pathToCombo; + + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void OnButton_SetPath(bool to); + void OnButton_Link(); + + void ShowLastErrorMessage(); + void ShowError(const wchar_t *s); + void Set_LinkType_Radio(unsigned idb); +public: + UString CurDirPrefix; + UString FilePath; + UString AnotherPath; + + INT_PTR Create(HWND parentWindow = NULL) + { return CModalDialog::Create(IDD_LINK, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialog.rc 2020-09-11 09:37:42.000000000 +0000 @@ -0,0 +1,38 @@ +#include "LinkDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 288 +#define yc 214 + +#undef xRadioSize +#define xRadioSize xc - m - 2 + +IDD_LINK DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Link" +BEGIN + LTEXT "Link from:", IDT_LINK_PATH_FROM, m, m, xc, 8 + COMBOBOX IDC_LINK_PATH_FROM, m, 20, xc - bxsDots - m, 64, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_LINK_PATH_FROM, xs - m - bxsDots, 18, bxsDots, bys, WS_GROUP + + LTEXT "Link to:", IDT_LINK_PATH_TO, m, 48, xc, 8 + COMBOBOX IDC_LINK_PATH_TO, m, 60, xc - bxsDots - m, 64, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_LINK_PATH_TO, xs - m - bxsDots, 58, bxsDots, bys, WS_GROUP + + LTEXT "", IDT_LINK_PATH_TO_CUR, m, 78, xc, 8 + + GROUPBOX "Link Type", IDG_LINK_TYPE, m, 104, xc, 90 + + CONTROL "Hard Link", IDR_LINK_TYPE_HARD, "Button", BS_AUTORADIOBUTTON | WS_GROUP, + m + m, 120, xRadioSize, 10 + CONTROL "File Symbolic Link", IDR_LINK_TYPE_SYM_FILE, "Button", BS_AUTORADIOBUTTON, + m + m, 134, xRadioSize, 10 + CONTROL "Directory Symbolic Link", IDR_LINK_TYPE_SYM_DIR, "Button", BS_AUTORADIOBUTTON, + m + m, 148, xRadioSize, 10 + CONTROL "Directory Junction", IDR_LINK_TYPE_JUNCTION, "Button", BS_AUTORADIOBUTTON, + m + m, 162, xRadioSize, 10 + CONTROL "WSL", IDR_LINK_TYPE_WSL, "Button", BS_AUTORADIOBUTTON, + m + m, 176, xRadioSize, 10 + + DEFPUSHBUTTON "Link", IDB_LINK_LINK, bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/LinkDialogRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/LinkDialogRes.h 2020-09-11 09:36:17.000000000 +0000 @@ -0,0 +1,22 @@ +#define IDD_LINK 7700 + +#define IDB_LINK_LINK 7701 + +#define IDT_LINK_PATH_FROM 7702 +#define IDT_LINK_PATH_TO 7703 + +#define IDG_LINK_TYPE 7710 +#define IDR_LINK_TYPE_HARD 7711 +#define IDR_LINK_TYPE_SYM_FILE 7712 +#define IDR_LINK_TYPE_SYM_DIR 7713 +#define IDR_LINK_TYPE_JUNCTION 7714 +#define IDR_LINK_TYPE_WSL 7715 + + +#define IDC_LINK_PATH_FROM 100 +#define IDC_LINK_PATH_TO 101 + +#define IDT_LINK_PATH_TO_CUR 102 + +#define IDB_LINK_PATH_FROM 103 +#define IDB_LINK_PATH_TO 104 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.cpp 2015-10-03 17:47:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.cpp 2023-03-17 12:00:00.000000000 +0000 @@ -1,145 +1,321 @@ -// ListViewDialog.cpp - -#include "StdAfx.h" - -#include "ListViewDialog.h" -#include "RegistryUtils.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -using namespace NWindows; - -bool CListViewDialog::OnInit() -{ - #ifdef LANG - LangSetDlgItems(*this, NULL, 0); - #endif - _listView.Attach(GetItem(IDL_LISTVIEW)); - - // FIXME if (ReadSingleClick()) - // FIXME _listView.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT); - - SetText(Title); - - LVCOLUMN columnInfo; - columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; - columnInfo.fmt = LVCFMT_LEFT; - columnInfo.iSubItem = 0; - columnInfo.cx = 200; - - _listView.InsertColumn(0, &columnInfo); - - FOR_VECTOR (i, Strings) - _listView.InsertItem(i, Strings[i]); - - if (Strings.Size() > 0) - _listView.SetItemState_FocusedSelected(0); - - _listView.SetColumnWidthAuto(0); - StringsWereChanged = false; - - NormalizeSize(); - return CModalDialog::OnInit(); -} - -bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int mx, my; - GetMargins(8, mx, my); - int bx1, bx2, by; - GetItemSizes(IDCANCEL, bx1, by); - GetItemSizes(IDOK, bx2, by); - int y = ySize - my - by; - int x = xSize - mx - bx1; - - /* - RECT rect; - GetClientRect(&rect); - rect.top = y - my; - InvalidateRect(&rect); - */ - InvalidateRect(NULL); - - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDOK, x - mx - bx2, y, bx2, by); - /* - if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE) - mx = 0; - */ - _listView.Move(mx, my, xSize - mx * 2, y - my * 2); -#endif - return false; -} - -extern bool g_LVN_ITEMACTIVATE_Support; - -bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) -{ -#ifdef _WIN32 - if (header->hwndFrom != _listView) - return false; - switch (header->code) - { - case LVN_ITEMACTIVATE: - if (g_LVN_ITEMACTIVATE_Support) - { - OnOK(); - return true; - } - break; - case NM_DBLCLK: - case NM_RETURN: // probabably it's unused - if (!g_LVN_ITEMACTIVATE_Support) - { - OnOK(); - return true; - } - break; - - case LVN_KEYDOWN: - { - LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); - switch (keyDownInfo->wVKey) - { - case VK_DELETE: - { - if (!DeleteIsAllowed) - return false; - for (;;) - { - int index = _listView.GetNextSelectedItem(-1); - if (index < 0) - break; - StringsWereChanged = true; - _listView.DeleteItem(index); - Strings.Delete(index); - } - int focusedIndex = _listView.GetFocusedItem(); - if (focusedIndex >= 0) - _listView.SetItemState_FocusedSelected(focusedIndex); - _listView.SetColumnWidthAuto(0); - return true; - } - case 'A': - { - if (IsKeyDown(VK_CONTROL)) - { - _listView.SelectAll(); - return true; - } - } - } - } - } -#endif - return false; -} - -void CListViewDialog::OnOK() -{ - FocusedItemIndex = _listView.GetFocusedItem(); - CModalDialog::OnOK(); -} +// ListViewDialog.cpp + +#include "StdAfx.h" + +#include "../../../Windows/Clipboard.h" + +#include "EditDialog.h" +#include "ListViewDialog.h" +#include "RegistryUtils.h" + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +static const unsigned kOneStringMaxSize = 1024; + + +static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector) +{ + vector.Clear(); + int index = -1; + for (;;) + { + index = listView.GetNextSelectedItem(index); + if (index < 0) + break; + vector.Add((unsigned)index); + } +} + + +bool CListViewDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _listView.Attach(GetItem(IDL_LISTVIEW)); + + if (NumColumns > 1) + { + LONG_PTR style = _listView.GetStyle(); + style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER; + _listView.SetStyle(style); + } + + CFmSettings st; + st.Load(); + + DWORD exStyle = 0; + + if (st.SingleClick) + exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT; + + exStyle |= LVS_EX_FULLROWSELECT; + if (exStyle != 0) + _listView.SetExtendedListViewStyle(exStyle); + + + SetText(Title); + + const int kWidth = 400; + + LVCOLUMN columnInfo; + columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + columnInfo.iSubItem = 0; + columnInfo.cx = kWidth; + columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property" + + if (NumColumns > 1) + { + columnInfo.cx = 100; + /* + // Windows always uses LVCFMT_LEFT for first column. + // if we need LVCFMT_RIGHT, we can create dummy column and then remove it + + // columnInfo.mask |= LVCF_TEXT; + _listView.InsertColumn(0, &columnInfo); + + columnInfo.iSubItem = 1; + columnInfo.fmt = LVCFMT_RIGHT; + _listView.InsertColumn(1, &columnInfo); + _listView.DeleteColumn(0); + */ + } + // else + _listView.InsertColumn(0, &columnInfo); + + if (NumColumns > 1) + { + // columnInfo.fmt = LVCFMT_LEFT; + columnInfo.cx = kWidth - columnInfo.cx; + columnInfo.iSubItem = 1; + // columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value" + _listView.InsertColumn(1, &columnInfo); + } + + + UString s; + + FOR_VECTOR (i, Strings) + { + _listView.InsertItem(i, Strings[i]); + + if (NumColumns > 1 && i < Values.Size()) + { + s = Values[i]; + if (s.Len() > kOneStringMaxSize) + { + s.DeleteFrom(kOneStringMaxSize); + s += " ..."; + } + s.Replace(L"\r\n", L" "); + s.Replace(L"\n", L" "); + _listView.SetSubItem(i, 1, s); + } + } + + if (SelectFirst && Strings.Size() > 0) + _listView.SetItemState_FocusedSelected(0); + + _listView.SetColumnWidthAuto(0); + if (NumColumns > 1) + _listView.SetColumnWidthAuto(1); + StringsWereChanged = false; + + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int y = ySize - my - by; + int x = xSize - mx - bx1; + + /* + RECT rect; + GetClientRect(&rect); + rect.top = y - my; + InvalidateRect(&rect); + */ + InvalidateRect(NULL); + + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + /* + if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE) + mx = 0; + */ + _listView.Move(mx, my, xSize - mx * 2, y - my * 2); + return false; +} + + +extern bool g_LVN_ITEMACTIVATE_Support; + +void CListViewDialog::CopyToClipboard() +{ + CUIntVector indexes; + ListView_GetSelected(_listView, indexes); + UString s; + + FOR_VECTOR (i, indexes) + { + unsigned index = indexes[i]; + s += Strings[index]; + if (NumColumns > 1 && index < Values.Size()) + { + const UString &v = Values[index]; + // if (!v.IsEmpty()) + { + s += ": "; + s += v; + } + } + // if (indexes.Size() > 1) + { + s += + #ifdef _WIN32 + "\r\n" + #else + "\n" + #endif + ; + } + } + + ClipboardSetText(*this, s); +} + + +void CListViewDialog::ShowItemInfo() +{ + CUIntVector indexes; + ListView_GetSelected(_listView, indexes); + if (indexes.Size() != 1) + return; + unsigned index = indexes[0]; + + CEditDialog dlg; + if (NumColumns == 1) + dlg.Text = Strings[index]; + else + { + dlg.Title = Strings[index]; + if (index < Values.Size()) + dlg.Text = Values[index]; + } + + #ifdef _WIN32 + if (dlg.Text.Find(L'\r') < 0) + dlg.Text.Replace(L"\n", L"\r\n"); + #endif + + dlg.Create(*this); +} + + +void CListViewDialog::DeleteItems() +{ + for (;;) + { + const int index = _listView.GetNextSelectedItem(-1); + if (index < 0) + break; + StringsWereChanged = true; + _listView.DeleteItem((unsigned)index); + if ((unsigned)index < Strings.Size()) + Strings.Delete((unsigned)index); + if ((unsigned)index < Values.Size()) + Values.Delete((unsigned)index); + } + const int focusedIndex = _listView.GetFocusedItem(); + if (focusedIndex >= 0) + _listView.SetItemState_FocusedSelected(focusedIndex); + _listView.SetColumnWidthAuto(0); +} + + +void CListViewDialog::OnEnter() +{ + if (IsKeyDown(VK_MENU) + || NumColumns > 1) + { + ShowItemInfo(); + return; + } + OnOK(); +} + +bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _listView) + return false; + switch (header->code) + { + case LVN_ITEMACTIVATE: + if (g_LVN_ITEMACTIVATE_Support) + { + OnEnter(); + return true; + } + break; + case NM_DBLCLK: + case NM_RETURN: // probabably it's unused + if (!g_LVN_ITEMACTIVATE_Support) + { + OnEnter(); + return true; + } + break; + + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + switch (keyDownInfo->wVKey) + { + case VK_DELETE: + { + if (!DeleteIsAllowed) + return false; + DeleteItems(); + return true; + } + case 'A': + { + if (IsKeyDown(VK_CONTROL)) + { + _listView.SelectAll(); + return true; + } + break; + } + case VK_INSERT: + case 'C': + { + if (IsKeyDown(VK_CONTROL)) + { + CopyToClipboard(); + return true; + } + break; + } + } + } + } + return false; +} + +void CListViewDialog::OnOK() +{ + FocusedItemIndex = _listView.GetFocusedItem(); + CModalDialog::OnOK(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,30 +1,46 @@ -// ListViewDialog.h - -#ifndef __LISTVIEW_DIALOG_H -#define __LISTVIEW_DIALOG_H - -#include "../../../Windows/Control/Dialog.h" -#include "../../../Windows/Control/ListView.h" - -#include "ListViewDialogRes.h" - -class CListViewDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CListView _listView; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual bool OnNotify(UINT controlID, LPNMHDR header); -public: - UString Title; - bool DeleteIsAllowed; - bool StringsWereChanged; - UStringVector Strings; - int FocusedItemIndex; - - INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); } - - CListViewDialog(): DeleteIsAllowed(false) {} -}; - -#endif +// ListViewDialog.h + +#ifndef ZIP7_INC_LISTVIEW_DIALOG_H +#define ZIP7_INC_LISTVIEW_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ListView.h" + +#include "ListViewDialogRes.h" + +class CListViewDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _listView; + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override; + void CopyToClipboard(); + void DeleteItems(); + void ShowItemInfo(); + void OnEnter(); +public: + UString Title; + + bool SelectFirst; + bool DeleteIsAllowed; + bool StringsWereChanged; + + UStringVector Strings; + UStringVector Values; + + int FocusedItemIndex; + unsigned NumColumns; + + INT_PTR Create(HWND wndParent = NULL) { return CModalDialog::Create(IDD_LISTVIEW, wndParent); } + + CListViewDialog(): + SelectFirst(false), + DeleteIsAllowed(false), + StringsWereChanged(false), + FocusedItemIndex(-1), + NumColumns(1) + {} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog.rc 2021-10-01 12:57:12.000000000 +0000 @@ -0,0 +1,14 @@ +#include "ListViewDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 480 +#define yc 320 + +IDD_LISTVIEW DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "ListView" +{ + CONTROL "List1", IDL_LISTVIEW, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | + LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP, + m, m, xc, yc - bys - m + OK_CANCEL +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialogRes.h 2011-04-26 08:40:39.000000000 +0000 @@ -1,2 +1,2 @@ -#define IDD_LISTVIEW 99 -#define IDL_LISTVIEW 100 +#define IDD_LISTVIEW 99 +#define IDL_LISTVIEW 100 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp 2015-10-03 18:49:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "ListViewDialogRes.h" - -class CListViewDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CListViewDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent,int id) : - CModalDialogImpl(dialog,parent, id, wxT("ListView"), wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX) - - { - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - wxListCtrl *list = new wxListCtrl(this, IDL_LISTVIEW, wxDefaultPosition, wxSize(645,195), wxLC_REPORT | wxLC_NO_HEADER); - - topsizer->Add(list, 1, wxALL|wxEXPAND, 5); - - topsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_LISTVIEW,CListViewDialog,0) - -BEGIN_EVENT_TABLE(CListViewDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.cpp 2024-10-21 10:00:00.000000000 +0000 @@ -0,0 +1,218 @@ +// MemDialog.cpp + +#include "StdAfx.h" + +#include + +#include "MemDialog.h" + +#include "../../../Common/StringToInt.h" +#include "../../../Windows/System.h" +#include "../../../Windows/ErrorMsg.h" + +#include "../Explorer/MyMessages.h" +#include "../GUI/ExtractRes.h" + +#include "resourceGui.h" + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDX_MEM_SAVE_LIMIT, + IDX_MEM_REMEMBER, + IDG_MEM_ACTION, + IDR_MEM_ACTION_ALLOW, + IDR_MEM_ACTION_SKIP_ARC + // , IDR_MEM_SKIP_FILE +}; +#endif + +static const unsigned k_Action_Buttons[] = +{ + IDR_MEM_ACTION_ALLOW, + IDR_MEM_ACTION_SKIP_ARC + // , IDR_MEM_SKIP_FILE +}; + + +void CMemDialog::EnableSpin(bool enable) +{ + EnableItem(IDC_MEM_SPIN, enable); + EnableItem(IDE_MEM_SPIN_EDIT, enable); +} + + +static void AddSize_GB(UString &s, UInt32 size_GB, UInt32 id) +{ + s.Add_LF(); + s += " "; + s.Add_UInt32(size_GB); + s += " GB : "; + AddLangString(s, id); +} + +void CMemDialog::AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB) +{ + AddLangString(s, IDS_MEM_REQUIRES_BIG_MEM); + AddSize_GB(s, Required_GB, IDS_MEM_REQUIRED_MEM_SIZE); + AddSize_GB(s, Limit_GB, IDS_MEM_CURRENT_MEM_LIMIT); + if (ramSize_GB) + AddSize_GB(s, *ramSize_GB, IDS_MEM_RAM_SIZE); + if (!FilePath.IsEmpty()) + { + s.Add_LF(); + s += "File: "; + s += FilePath; + } +} + +/* +int CMemDialog::AddAction(UINT id) +{ + const int index = (int)m_Action.AddString(LangString(id)); + m_Action.SetItemData(index, (LPARAM)id); + return index; +} +*/ + +bool CMemDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_MEM); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + + // m_Action.Attach(GetItem(IDC_MEM_ACTION)); + + size_t ramSize = (size_t)sizeof(size_t) << 29; + const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); + // ramSize *= 10; // for debug + + UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30); + if (ramSize_GB == 0) + ramSize_GB = 1; + + const bool is_Allowed = (!ramSize_defined || ramSize > ((UInt64)Required_GB << 30)); + { + UString s; + if (!is_Allowed) + { + AddLangString(s, IDS_MEM_ERROR); + s.Add_LF(); + } + AddInfoMessage_To_String(s, is_Allowed ? NULL : &ramSize_GB); + if (!ArcPath.IsEmpty()) + // for (int i = 0; i < 10; i++) + { + s.Add_LF(); + AddLangString(s, TestMode ? + IDS_PROGRESS_TESTING : + IDS_PROGRESS_EXTRACTING); + s += ": "; + s += ArcPath; + } + SetItemText(IDT_MEM_MESSAGE, s); + + s = "GB"; + if (ramSize_defined) + { + s += " / "; + s.Add_UInt32(ramSize_GB); + s += " GB (RAM)"; + } + SetItemText(IDT_MEM_GB, s); + } + const UINT valMin = 1; + UINT valMax = 64; // 64GB for RAR7 + if (ramSize_defined /* && ramSize_GB > valMax */) + { + const UINT k_max_val = 1u << 14; + if (ramSize_GB >= k_max_val) + valMax = k_max_val; + else if (ramSize_GB > 1) + valMax = (UINT)ramSize_GB - 1; + else + valMax = 1; + } + + SendItemMessage(IDC_MEM_SPIN, UDM_SETRANGE, 0, MAKELPARAM(valMax, valMin)); // Sets the controls direction + // UDM_SETPOS doesn't set value larger than max value (valMax) of range: + SendItemMessage(IDC_MEM_SPIN, UDM_SETPOS, 0, Required_GB); + { + UString s; + s.Add_UInt32(Required_GB); + SetItemText(IDE_MEM_SPIN_EDIT, s); + } + + EnableSpin(false); + + /* + AddAction(IDB_ALLOW_OPERATION); + m_Action.SetCurSel(0); + AddAction(IDB_MEM_SKIP_ARC); + AddAction(IDB_MEM_SKIP_FILE); + */ + + const UINT buttonId = is_Allowed ? + IDR_MEM_ACTION_ALLOW : + IDR_MEM_ACTION_SKIP_ARC; + + CheckRadioButton( + k_Action_Buttons[0], + k_Action_Buttons[Z7_ARRAY_SIZE(k_Action_Buttons) - 1], + buttonId); + /* + if (!ShowSkipFile) + HideItem(IDR_MEM_SKIP_FILE); + */ + if (!ShowRemember) + HideItem(IDX_MEM_REMEMBER); + return CModalDialog::OnInit(); +} + + +bool CMemDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + if (buttonID == IDX_MEM_SAVE_LIMIT) + { + EnableSpin(IsButtonCheckedBool(IDX_MEM_SAVE_LIMIT)); + return true; + } + return CDialog::OnButtonClicked(buttonID, buttonHWND); +} + + +void CMemDialog::OnContinue() +{ + Remember = IsButtonCheckedBool(IDX_MEM_REMEMBER); + NeedSave = IsButtonCheckedBool(IDX_MEM_SAVE_LIMIT); + SkipArc = IsButtonCheckedBool(IDR_MEM_ACTION_SKIP_ARC); + if (NeedSave) + { +#if 0 + // UDM_GETPOS doesn't support value outside of range that was set: + LRESULT lresult = SendItemMessage(IDC_MEM_SPIN, UDM_GETPOS, 0, 0); + const UInt32 val = LOWORD(lresult); + if (HIWORD(lresult) != 0) // the value outside of allowed range +#else + UString s; + GetItemText(IDE_MEM_SPIN_EDIT, s); + const wchar_t *end; + const UInt32 val = ConvertStringToUInt32(s.Ptr(), &end); + if (s.IsEmpty() || *end != 0 || val > (1u << 30)) +#endif + { + ShowErrorMessage(*this, + NWindows::NError::MyFormatMessage(E_INVALIDARG) + // L"Incorrect value" + ); + return; + } + Limit_GB = val; + } + CModalDialog::OnContinue(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.h 2024-10-21 12:00:00.000000000 +0000 @@ -0,0 +1,48 @@ +// MemDialog.h + +#ifndef ZIP7_INC_MEM_DIALOG_H +#define ZIP7_INC_MEM_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +// #include "../../../Windows/Control/ComboBox.h" + +#include "MemDialogRes.h" + +class CMemDialog: public NWindows::NControl::CModalDialog +{ + // NWindows::NControl::CComboBox m_Action; + // we can disable default OnOK() when we press Enter + // virtual void OnOK() Z7_override { } + virtual void OnContinue() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void EnableSpin(bool enable); + // int AddAction(UINT id); +public: + bool NeedSave; + bool Remember; + bool SkipArc; + bool TestMode; + bool ShowRemember; + // bool ShowSkipFile; + UInt32 Required_GB; + UInt32 Limit_GB; + UString ArcPath; + UString FilePath; + + void AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB = NULL); + + CMemDialog(): + NeedSave(false), + Remember(false), + SkipArc(false), + TestMode(false), + ShowRemember(true), + // ShowSkipFile(true), + Required_GB(4), + Limit_GB(4) + {} + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_MEM, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialog.rc 2024-03-22 08:00:00.000000000 +0000 @@ -0,0 +1,49 @@ +#include "MemDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 320 +#define yc 200 + +#define spin_x_size 50 +#define info_y_size 72 +#define save_y (m + info_y_size + 4) +#define spin_y (save_y + 16) + +#define xsg (xc - m - m) +#define xg (m + m) +#define yg (spin_y + 20) + +IDD_MEM DIALOG MY_MODAL_DIALOG_POSTFIX +CAPTION "Memory usage request" +BEGIN + LTEXT "", IDT_MEM_MESSAGE, m, m, xc, info_y_size, SS_NOPREFIX + CONTROL "Change allowed limit for next operations", IDX_MEM_SAVE_LIMIT, MY_CHECKBOX, + m, save_y, xc, 10 + + MY_CONTROL_EDIT_WITH_SPIN( + IDE_MEM_SPIN_EDIT, + IDC_MEM_SPIN, + "4", m + 10, spin_y, spin_x_size) + + LTEXT "GB", IDT_MEM_GB, m + 10 + spin_x_size + 8, spin_y + 2, 160, 10 + + GROUPBOX "Action", IDG_MEM_ACTION, m, yg, xc, 62 + + MY_CONTROL_AUTORADIOBUTTON_GROUP ( + "&Allow archive unpacking", IDR_MEM_ACTION_ALLOW, + xg, yg + 14, xsg) + MY_CONTROL_AUTORADIOBUTTON ( + "&Skip archive unpacking", IDR_MEM_ACTION_SKIP_ARC, + xg, yg + 28, xsg) +// CONTROL "&Skip file extracting", IDR_MEM_SKIP_FILE, MY_AUTORADIOBUTTON, +// xg, yg + 42, xsg, 10 + + CONTROL "&Repeat selected action for current operation", IDX_MEM_REMEMBER, MY_CHECKBOX, + xg + 10, yg + 44, xsg - 10, 10 + + CONTINUE_CANCEL +END + +#undef save_y +#undef spin_y +#undef spin_x_size diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MemDialogRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MemDialogRes.h 2024-03-14 09:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +#define IDD_MEM 7800 + +#define IDX_MEM_SAVE_LIMIT 7801 +#define IDX_MEM_REMEMBER 7802 +#define IDG_MEM_ACTION 7803 + +#define IDR_MEM_ACTION_ALLOW 7820 +#define IDR_MEM_ACTION_SKIP_ARC 7821 + +#define IDT_MEM_MESSAGE 101 +#define IDE_MEM_SPIN_EDIT 110 +#define IDC_MEM_SPIN 111 +#define IDT_MEM_GB 112 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -0,0 +1,440 @@ +// MenuPage.cpp + +#include "StdAfx.h" + +#include "../Common/ZipRegistry.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileFind.h" + +#include "../Explorer/ContextMenuFlags.h" +#include "../Explorer/RegistryContextMenu.h" +#include "../Explorer/resource.h" + +#include "../FileManager/PropertyNameRes.h" + +#include "../GUI/ExtractDialogRes.h" + +#include "FormatUtils.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "MenuPage.h" +#include "MenuPageRes.h" + + +using namespace NWindows; +using namespace NContextMenuFlags; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDX_SYSTEM_INTEGRATE_TO_MENU, + IDX_SYSTEM_CASCADED_MENU, + IDX_SYSTEM_ICON_IN_MENU, + IDX_EXTRACT_ELIM_DUP, + IDT_SYSTEM_ZONE, + IDT_SYSTEM_CONTEXT_MENU_ITEMS +}; +#endif + +#define kMenuTopic "fm/options.htm#sevenZip" + +struct CContextMenuItem +{ + unsigned ControlID; + UInt32 Flag; +}; + +static const CContextMenuItem kMenuItems[] = +{ + { IDS_CONTEXT_OPEN, kOpen }, + { IDS_CONTEXT_OPEN, kOpenAs }, + { IDS_CONTEXT_EXTRACT, kExtract }, + { IDS_CONTEXT_EXTRACT_HERE, kExtractHere }, + { IDS_CONTEXT_EXTRACT_TO, kExtractTo }, + + { IDS_CONTEXT_TEST, kTest }, + + { IDS_CONTEXT_COMPRESS, kCompress }, + { IDS_CONTEXT_COMPRESS_TO, kCompressTo7z }, + { IDS_CONTEXT_COMPRESS_TO, kCompressToZip }, + + #ifndef UNDER_CE + { IDS_CONTEXT_COMPRESS_EMAIL, kCompressEmail }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressTo7zEmail }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail }, + #endif + + { IDS_PROP_CHECKSUM, kCRC }, + { IDS_PROP_CHECKSUM, kCRC_Cascaded }, +}; + + +#if !defined(_WIN64) +extern bool g_Is_Wow64; +#endif + +#ifndef KEY_WOW64_64KEY + #define KEY_WOW64_64KEY (0x0100) +#endif + +#ifndef KEY_WOW64_32KEY + #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; + + Clear_MenuChanged(); + +#ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); +#endif + + #ifdef UNDER_CE + + HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU); + HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU_2); + + #else + + { + UString s; + { + CWindow window(GetItem(IDX_SYSTEM_INTEGRATE_TO_MENU)); + window.GetText(s); + } + UString bit64 = LangString(IDS_PROP_BIT64); + if (bit64.IsEmpty()) + bit64 = "64-bit"; + #ifdef _WIN64 + bit64.Replace(L"64", L"32"); + #endif + s.Add_Space(); + s.Add_Char('('); + s += bit64; + s.Add_Char(')'); + SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s); + } + + const FString prefix = NDLL::GetModuleDirPrefix(); + + _dlls[0].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU; + _dlls[1].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU_2; + + _dlls[0].wow = 0; + _dlls[1].wow = + #ifdef _WIN64 + KEY_WOW64_32KEY + #else + KEY_WOW64_64KEY + #endif + ; + + for (unsigned d = 0; d < 2; d++) + { + CShellDll &dll = _dlls[d]; + + dll.wasChanged = false; + + #ifndef _WIN64 + if (d != 0 && !g_Is_Wow64) + { + HideItem(dll.ctrl); + continue; + } + #endif + + FString &path = dll.Path; + path = prefix; + path += (d == 0 ? "7-zip.dll" : + #ifdef _WIN64 + "7-zip32.dll" + #else + "7-zip64.dll" + #endif + ); + + + if (!NFile::NFind::DoesFileExist_Raw(path)) + { + path.Empty(); + EnableItem(dll.ctrl, false); + } + else + { + dll.prevValue = CheckContextMenuHandler(fs2us(path), dll.wow); + CheckButton(dll.ctrl, dll.prevValue); + } + } + + #endif + + + CContextMenuInfo ci; + ci.Load(); + + CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded.Val); + CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons.Val); + 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, (LPARAM)val); + if (val == wz) + _zoneCombo.SetCurSel(index); + } + } + + + const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; + _listView.SetExtendedListViewStyle(newFlags, newFlags); + + _listView.InsertColumn(0, L"", 200); + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kMenuItems); i++) + { + const CContextMenuItem &menuItem = kMenuItems[i]; + + UString s = LangString(menuItem.ControlID); + if (menuItem.Flag == kCRC) + s = "CRC SHA"; + else if (menuItem.Flag == kCRC_Cascaded) + s = "7-Zip > CRC SHA"; + if (menuItem.Flag == kOpenAs + || menuItem.Flag == kCRC + || menuItem.Flag == kCRC_Cascaded) + s += " >"; + + switch (menuItem.ControlID) + { + case IDS_CONTEXT_EXTRACT_TO: + { + s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER)); + break; + } + case IDS_CONTEXT_COMPRESS_TO: + case IDS_CONTEXT_COMPRESS_TO_EMAIL: + { + UString s2 = LangString(IDS_CONTEXT_ARCHIVE); + switch (menuItem.Flag) + { + case kCompressTo7z: + case kCompressTo7zEmail: + s2 += (".7z"); + break; + case kCompressToZip: + case kCompressToZipEmail: + s2 += (".zip"); + break; + } + s = MyFormatNew(s, s2); + break; + } + } + + const int itemIndex = _listView.InsertItem(i, s); + _listView.SetCheckState((unsigned)itemIndex, ((ci.Flags & menuItem.Flag) != 0)); + } + + _listView.SetColumnWidthAuto(0); + _initMode = false; + + return CPropertyPage::OnInit(); +} + + +#ifndef UNDER_CE + +static void ShowMenuErrorMessage(const wchar_t *m, HWND hwnd) +{ + MessageBoxW(hwnd, m, L"7-Zip", MB_ICONERROR); +} + +#endif + + +LONG CMenuPage::OnApply() +{ + #ifndef UNDER_CE + + for (unsigned d = 2; d != 0;) + { + d--; + CShellDll &dll = _dlls[d]; + if (dll.wasChanged && !dll.Path.IsEmpty()) + { + const bool newVal = IsButtonCheckedBool(dll.ctrl); + const LONG res = SetContextMenuHandler(newVal, fs2us(dll.Path), dll.wow); + if (res != ERROR_SUCCESS && (dll.prevValue != newVal || newVal)) + ShowMenuErrorMessage(NError::MyFormatMessage(res), *this); + dll.prevValue = CheckContextMenuHandler(fs2us(dll.Path), dll.wow); + CheckButton(dll.ctrl, dll.prevValue); + dll.wasChanged = false; + } + } + + #endif + + if (_cascaded_Changed + || _menuIcons_Changed + || _elimDup_Changed + || _writeZone_Changed + || _flags_Changed) + { + CContextMenuInfo ci; + ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU); + ci.Cascaded.Def = _cascaded_Changed; + + ci.MenuIcons.Val = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU); + ci.MenuIcons.Def = _menuIcons_Changed; + + 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 < Z7_ARRAY_SIZE(kMenuItems); i++) + if (_listView.GetCheckState(i)) + ci.Flags |= kMenuItems[i].Flag; + + ci.Flags_Def = _flags_Changed; + ci.Save(); + + Clear_MenuChanged(); + } + + // UnChanged(); + + return PSNRET_NOERROR; +} + +void CMenuPage::OnNotifyHelp() +{ + ShowHelpWindow(kMenuTopic); +} + +bool CMenuPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + #ifndef UNDER_CE + case IDX_SYSTEM_INTEGRATE_TO_MENU: + case IDX_SYSTEM_INTEGRATE_TO_MENU_2: + { + for (unsigned d = 0; d < 2; d++) + { + CShellDll &dll = _dlls[d]; + if (buttonID == dll.ctrl && !dll.Path.IsEmpty()) + dll.wasChanged = true; + } + break; + } + #endif + + 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); + } + + Changed(); + return true; +} + + +bool CMenuPage::OnCommand(unsigned code, unsigned 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)) + { + switch (lParam->code) + { + case (LVN_ITEMCHANGED): + return OnItemChanged((const NMLISTVIEW *)lParam); + } + } + return CPropertyPage::OnNotify(controlID, lParam); +} + + +bool CMenuPage::OnItemChanged(const NMLISTVIEW *info) +{ + if (_initMode) + return true; + if ((info->uChanged & LVIF_STATE) != 0) + { + UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + { + _flags_Changed = true; + Changed(); + } + } + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.h 2023-03-19 17:00:00.000000000 +0000 @@ -0,0 +1,57 @@ +// MenuPage.h + +#ifndef ZIP7_INC_MENU_PAGE_H +#define ZIP7_INC_MENU_PAGE_H + +#include "../../../Windows/Control/PropertyPage.h" +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/ListView.h" + +struct CShellDll +{ + FString Path; + bool wasChanged; + bool prevValue; + unsigned ctrl; + UInt32 wow; + + CShellDll(): wasChanged (false), prevValue(false), ctrl(0), wow(0) {} +}; + +class CMenuPage: public NWindows::NControl::CPropertyPage +{ + bool _initMode; + + bool _cascaded_Changed; + bool _menuIcons_Changed; + bool _elimDup_Changed; + bool _writeZone_Changed; + bool _flags_Changed; + + void Clear_MenuChanged() + { + _cascaded_Changed = false; + _menuIcons_Changed = false; + _elimDup_Changed = false; + _writeZone_Changed = false; + _flags_Changed = false; + } + + #ifndef UNDER_CE + CShellDll _dlls[2]; + #endif + + NWindows::NControl::CListView _listView; + NWindows::NControl::CComboBox _zoneCombo; + + virtual bool OnInit() Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR lParam) Z7_override; + virtual LONG OnApply() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM param) Z7_override; + + bool OnItemChanged(const NMLISTVIEW* info); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage.rc 2024-03-16 06:00:00.000000000 +0000 @@ -0,0 +1,24 @@ +#include "MenuPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc OPTIONS_PAGE_YC_SIZE + +IDD_MENU MY_PAGE +#include "MenuPage2.rc" + +#ifdef UNDER_CE + +#undef m +#undef xc +#undef yc + +#define m 4 +#define xc (SMALL_PAGE_SIZE_X + 8) + +#define yc 112 + +IDD_MENU_2 MY_PAGE +#include "MenuPage2.rc" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPage2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPage2.rc 2024-03-16 06:00:00.000000000 +0000 @@ -0,0 +1,28 @@ +#include "../GUI/ExtractDialogRes.h" + +#define y 96 + +#define zoneX 100 + +CAPTION "7-Zip" +BEGIN + MY_CONTROL_CHECKBOX ( "Integrate 7-Zip to shell context menu", IDX_SYSTEM_INTEGRATE_TO_MENU, m, m, xc) + MY_CONTROL_CHECKBOX ( "(32-bit)", IDX_SYSTEM_INTEGRATE_TO_MENU_2, m, m + 14, xc) + MY_CONTROL_CHECKBOX ( "Cascaded context menu", IDX_SYSTEM_CASCADED_MENU, m, m + 28, xc) + MY_CONTROL_CHECKBOX ( "Icons in context menu", IDX_SYSTEM_ICON_IN_MENU, m, m + 42, xc) + MY_CONTROL_CHECKBOX ( "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, m, m + 56, xc) + + 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 -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MenuPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MenuPageRes.h 2022-06-06 10:00:00.000000000 +0000 @@ -0,0 +1,15 @@ +#define IDD_MENU 2300 +#define IDD_MENU_2 12300 + +#define IDX_SYSTEM_INTEGRATE_TO_MENU 2301 +#define IDX_SYSTEM_CASCADED_MENU 2302 +#define IDT_SYSTEM_CONTEXT_MENU_ITEMS 2303 +#define IDX_SYSTEM_ICON_IN_MENU 2304 + +#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 -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.cpp 2014-12-28 18:44:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.cpp 2023-01-29 20:00:00.000000000 +0000 @@ -1,78 +1,76 @@ -// MessagesDialog.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/ResourceString.h" - -#include "MessagesDialog.h" - -#include "LangUtils.h" - -#include "ProgressDialog2Res.h" - -using namespace NWindows; - -void CMessagesDialog::AddMessageDirect(LPCWSTR message) -{ - int i = _messageList.GetItemCount(); - wchar_t sz[16]; - ConvertUInt32ToString((UInt32)i, sz); - _messageList.InsertItem(i, sz); - _messageList.SetSubItem(i, 1, message); -} - -void CMessagesDialog::AddMessage(LPCWSTR message) -{ - UString s = message; - while (!s.IsEmpty()) - { - int pos = s.Find(L'\n'); - if (pos < 0) - break; - AddMessageDirect(s.Left(pos)); - s.DeleteFrontal(pos + 1); - } - AddMessageDirect(s); -} - -bool CMessagesDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_MESSAGES); - LangSetDlgItems(*this, NULL, 0); - SetItemText(IDOK, LangString(IDS_CLOSE)); - #endif - _messageList.Attach(GetItem(IDL_MESSAGE)); - _messageList.SetUnicodeFormat(); - - _messageList.InsertColumn(0, L"", 30); - _messageList.InsertColumn(1, LangString(IDS_MESSAGE), 600); - - FOR_VECTOR (i, *Messages) - AddMessage((*Messages)[i]); - - _messageList.SetColumnWidthAuto(0); - _messageList.SetColumnWidthAuto(1); - NormalizeSize(); - return CModalDialog::OnInit(); -} - -bool CMessagesDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int mx, my; - GetMargins(8, mx, my); - int bx, by; - GetItemSizes(IDOK, bx, by); - int y = ySize - my - by; - int x = xSize - mx - bx; - - InvalidateRect(NULL); - - MoveItem(IDOK, x, y, bx, by); - _messageList.Move(mx, my, xSize - mx * 2, y - my * 2); -#endif - return false; -} +// MessagesDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/ResourceString.h" + +#include "MessagesDialog.h" + +#include "LangUtils.h" + +#include "ProgressDialog2Res.h" + +using namespace NWindows; + +void CMessagesDialog::AddMessageDirect(LPCWSTR message) +{ + const unsigned i = (unsigned)_messageList.GetItemCount(); + wchar_t sz[16]; + ConvertUInt32ToString(i, sz); + _messageList.InsertItem(i, sz); + _messageList.SetSubItem(i, 1, message); +} + +void CMessagesDialog::AddMessage(LPCWSTR message) +{ + UString s = message; + while (!s.IsEmpty()) + { + const int pos = s.Find(L'\n'); + if (pos < 0) + break; + AddMessageDirect(s.Left(pos)); + s.DeleteFrontal((unsigned)pos + 1); + } + AddMessageDirect(s); +} + +bool CMessagesDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_MESSAGES); + LangSetDlgItems(*this, NULL, 0); + SetItemText(IDOK, LangString(IDS_CLOSE)); + #endif + _messageList.Attach(GetItem(IDL_MESSAGE)); + _messageList.SetUnicodeFormat(); + + _messageList.InsertColumn(0, L"", 30); + _messageList.InsertColumn(1, LangString(IDS_MESSAGE), 600); + + FOR_VECTOR (i, *Messages) + AddMessage((*Messages)[i]); + + _messageList.SetColumnWidthAuto(0); + _messageList.SetColumnWidthAuto(1); + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CMessagesDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx, by; + GetItemSizes(IDOK, bx, by); + int y = ySize - my - by; + int x = xSize - mx - bx; + + InvalidateRect(NULL); + + MoveItem(IDOK, x, y, bx, by); + _messageList.Move(mx, my, xSize - mx * 2, y - my * 2); + return false; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,25 +1,25 @@ -// MessagesDialog.h - -#ifndef __MESSAGES_DIALOG_H -#define __MESSAGES_DIALOG_H - -#include "../../../Windows/Control/Dialog.h" -#include "../../../Windows/Control/ListView.h" - -#include "MessagesDialogRes.h" - -class CMessagesDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CListView _messageList; - - void AddMessageDirect(LPCWSTR message); - void AddMessage(LPCWSTR message); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); -public: - const UStringVector *Messages; - - INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_MESSAGES, parent); } -}; - -#endif +// MessagesDialog.h + +#ifndef ZIP7_INC_MESSAGES_DIALOG_H +#define ZIP7_INC_MESSAGES_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ListView.h" + +#include "MessagesDialogRes.h" + +class CMessagesDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _messageList; + + void AddMessageDirect(LPCWSTR message); + void AddMessage(LPCWSTR message); + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; +public: + const UStringVector *Messages; + + INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_MESSAGES, parent); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog.rc 2011-06-06 14:23:35.000000000 +0000 @@ -0,0 +1,14 @@ +#include "MessagesDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 440 +#define yc 160 + +IDD_MESSAGES DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "7-Zip: Diagnostic messages" +{ + DEFPUSHBUTTON "&Close", IDOK, bx, by, bxs, bys + CONTROL "List1", IDL_MESSAGE, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + m, m, xc, yc - bys - m +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialogRes.h 2011-06-06 07:43:25.000000000 +0000 @@ -1,3 +1,3 @@ -#define IDD_MESSAGES 6602 -#define IDS_MESSAGE 6603 -#define IDL_MESSAGE 100 +#define IDD_MESSAGES 6602 +#define IDS_MESSAGE 6603 +#define IDL_MESSAGE 100 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp 2015-01-02 20:28:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -// MessagesDialog_rc.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" -#include "MessagesDialogRes.h" - -/* -IDD_MESSAGES DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE -CAPTION "7-Zip: Diagnostic messages" -MY_FONT -BEGIN - DEFPUSHBUTTON "&Close", IDOK, bXPos, bYPos, bXSize, bYSize - CONTROL "List1",IDL_MESSAGE,"SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, - marg, marg, xSize2, ySize2 - bYSize - 6 -END - -STRINGTABLE -BEGIN - IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message" -END -*/ - -class CMessagesDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CMessagesDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : - CModalDialogImpl(dialog,parent, id, wxT("7-Zip: Diagnostic messages"), wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX) - { - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - - wxListCtrl *list = new wxListCtrl(this, IDL_MESSAGE, wxDefaultPosition, wxSize(645,195), wxLC_REPORT ); - -#if 0 - list->InsertColumn(0, wxT("Col1"), wxLIST_FORMAT_LEFT); - list->InsertColumn(1, wxT("Col2"), wxLIST_FORMAT_RIGHT); - list->InsertItem(0, wxT("#1")); - list->SetItem(0, 1, L"message 1"); - list->InsertItem(1, wxT("#2")); - list->SetItem(1, 1, L"message 2"); -#endif - topsizer->Add(list , 1, wxALL|wxEXPAND, 5); - - - topsizer->Add(new wxButton(this, wxID_OK, _T("&Close")) , 0, wxALL | wxALIGN_RIGHT, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_MESSAGES,CMessagesDialog,0) - -BEGIN_EVENT_TABLE(CMessagesDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Move.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Move.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Move2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Move2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyCom2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyCom2.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyCom2.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyCom2.h 2024-03-28 18:00:00.000000000 +0000 @@ -0,0 +1,46 @@ +// MyCom2.h + +#ifndef ZIP7_INC_MYCOM2_H +#define ZIP7_INC_MYCOM2_H + +#include "../../../Common/MyCom.h" + +#define Z7_COM_UNKNOWN_IMP_SPEC_MT2(i1, i) \ + Z7_COM_QI_BEGIN \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + i \ + Z7_COM_QI_END_MT \ + Z7_COM_ADDREF_RELEASE_MT + + +#define Z7_COM_UNKNOWN_IMP_1_MT(i) \ + Z7_COM_UNKNOWN_IMP_SPEC_MT2( \ + i, \ + Z7_COM_QI_ENTRY(i) \ + ) + +#define Z7_COM_UNKNOWN_IMP_2_MT(i1, i2) \ + Z7_COM_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + ) + +#define Z7_COM_UNKNOWN_IMP_3_MT(i1, i2, i3) \ + Z7_COM_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + ) + +#define Z7_COM_UNKNOWN_IMP_4_MT(i1, i2, i3, i4) \ + Z7_COM_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + ) + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyLoadMenu.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyLoadMenu.cpp 2015-09-19 19:01:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.cpp 2024-11-25 14:00:00.000000000 +0000 @@ -1,727 +1,964 @@ -// MyLoadMenu - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -#undef _WIN32 - -#include - -#include "../../../../C/CpuArch.h" -#include "PropertyNameRes.h" - -typedef wxMenuBar * HMENU; - -#include "Common/StringConvert.h" - -#include "Windows/Menu.h" -#include "Windows/ErrorMsg.h" -// FIXME #include "Windows/Clipboard.h" - -#include "../../PropID.h" - -#include "resource.h" -#include "App.h" -// FIXME #include "AboutDialog.h" -#include "../Common/CompressCall.h" - -#include "HelpUtils.h" -#include "LangUtils.h" -#include "PluginInterface.h" - -#include "../../MyVersion.h" - -static const UINT kOpenBookmarkMenuID = 730; -static const UINT kSetBookmarkMenuID = 740; - -extern HINSTANCE g_hInstance; - -static LPCWSTR kFMHelpTopic = L"fm/index.htm"; - -extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance); - -using namespace NWindows; - -enum -{ - kMenuIndex_File = 0, - kMenuIndex_Edit, - kMenuIndex_View, - kMenuIndex_Bookmarks -}; - -struct CStringLangPair -{ - const wchar_t *String; - UINT32 LangID; -}; - -static CStringLangPair kStringLangPairs[] = -{ - { L"&File", 0x03000102 }, - { L"&Edit", 0x03000103 }, - { L"&View", 0x03000104 }, - { L"&Bookmarks", 0x03000107 }, - { L"&Tools", 0x03000105 }, - { L"&Help", 0x03000106 }, -}; - -UINT32 kAddToFavoritesLangID = 0x03000710; -UINT32 kToolbarsLangID = 0x03000451; - -static CIDLangPair kIDLangPairs[] = -{ - // File - { IDM_OPEN, 0x03000210 }, - { IDM_OPEN_INSIDE, 0x03000211 }, - { IDM_OPEN_OUTSIDE, 0x03000212 }, - // { IDM_FILE_VIEW, 0x03000220 }, // FIXME : does not exist ! - { IDM_FILE_EDIT, 0x03000221 }, - { IDM_RENAME, 0x03000230 }, - { IDM_COPY_TO, 0x03000231 }, - { IDM_MOVE_TO, 0x03000232 }, - { IDM_DELETE, 0x03000233 }, - { IDM_PROPERTIES, 0x03000240 }, - { IDM_COMMENT, 0x03000241 }, - { IDM_CRC32, 0x03000242 }, - { IDM_DIFF, 0x03000243 }, - { IDM_SPLIT, 0x03000270 }, - { IDM_COMBINE, 0x03000271 }, - { IDM_CREATE_FOLDER, 0x03000250 }, - { IDM_CREATE_FILE, 0x03000251 }, - // FIXME { IDCLOSE, 0x03000260 }, - - // Edit -/* FIXME - { IDM_EDIT_CUT, 0x03000320 }, - { IDM_EDIT_COPY, 0x03000321 }, - { IDM_EDIT_PASTE, 0x03000322 }, -*/ - { IDM_SELECT_ALL, 0x03000330 }, - { IDM_DESELECT_ALL, 0x03000331 }, - { IDM_INVERT_SELECTION, 0x03000332 }, - { IDM_SELECT, 0x03000333 }, - { IDM_DESELECT, 0x03000334 }, - { IDM_SELECT_BY_TYPE, 0x03000335 }, - { IDM_DESELECT_BY_TYPE, 0x03000336 }, - - { IDM_VIEW_LARGE_ICONS, 0x03000410 }, - { IDM_VIEW_SMALL_ICONS, 0x03000411 }, - { IDM_VIEW_LIST, 0x03000412 }, - { IDM_VIEW_DETAILS, 0x03000413 }, - - { IDM_VIEW_ARANGE_BY_NAME, 0x02000204 }, - { IDM_VIEW_ARANGE_BY_TYPE, 0x02000214 }, - { IDM_VIEW_ARANGE_BY_DATE, 0x0200020C }, - { IDM_VIEW_ARANGE_BY_SIZE, 0x02000207 }, - { IDM_VIEW_ARANGE_NO_SORT, 0x03000420 }, - - { IDM_OPEN_ROOT_FOLDER, 0x03000430 }, - { IDM_OPEN_PARENT_FOLDER, 0x03000431 }, - { IDM_FOLDERS_HISTORY, 0x03000432 }, - - { IDM_VIEW_REFRESH, 0x03000440 }, - - { IDM_VIEW_FLAT_VIEW, 0x03000449 }, - { IDM_VIEW_TWO_PANELS, 0x03000450 }, - { IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 }, - { IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 }, - { IDM_VIEW_TOOLBARS_LARGE_BUTTONS, 0x03000462 }, - { IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, 0x03000463 }, - - { IDM_OPTIONS, 0x03000510 }, - { IDM_BENCHMARK, 0x03000511 }, - - { IDM_HELP_CONTENTS, 0x03000610 }, - { IDM_ABOUT, 0x03000620 }, - - { 12111 , 0x03000710 }, // FIXME kAddToFavoritesLangID - { 12112 , 0x03000451 } // FIXME kToolbarsLangID -}; - - -#ifdef _WIN32 -static int FindLangItem(int ControlID) -{ - for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++) - if (kIDLangPairs[i].ControlID == ControlID) - return i; - return -1; -} -#endif - - -/* -static bool g_IsNew_fMask = true; - -class CInit_fMask -{ -public: - CInit_fMask() - { - g_IsNew_fMask = false; - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (::GetVersionEx(&vi)) - { - g_IsNew_fMask = (vi.dwMajorVersion > 4 || - (vi.dwMajorVersion == 4 && vi.dwMinorVersion > 0)); - } - g_IsNew_fMask = false; - } -} g_Init_fMask; - -// it's hack for supporting Windows NT -// constants are from WinUser.h - -#if(WINVER < 0x0500) -#define MIIM_STRING 0x00000040 -#define MIIM_BITMAP 0x00000080 -#define MIIM_FTYPE 0x00000100 -#endif - -static UINT Get_fMaskForString() -{ - return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; -} - -static UINT Get_fMaskForFTypeAndString() -{ - return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; -} -*/ - -#ifdef _WIN32 -static UINT Get_fMaskForString() -{ - return MIIM_TYPE; -} - -static UINT Get_fMaskForFTypeAndString() -{ - return MIIM_TYPE; -} -#endif - - -static void MyChangeItem(wxMenuItem * mi,int LangID) -{ - UString newString = LangString(LangID); - if (newString.IsEmpty()) - return; - wxString ss = mi->GetItemLabel(); - UString shorcutString((const wchar_t *)ss); // = item.StringValue; - int tabPos = shorcutString.ReverseFind(wchar_t('\t')); - if (tabPos >= 0) - newString += shorcutString.Ptr(tabPos); - // printf("Change Menu : %ls => %ls\n",(const wchar_t *)ss,(const wchar_t *)newString); - mi->SetItemLabel((const wchar_t *)newString); - -} - -static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) -{ - // Sets the label of the top-level menus - for (int i1= 0; i1< sizeof(kStringLangPairs) / sizeof(kStringLangPairs[0]); i1++) - { - UString newString = LangString(kStringLangPairs[i1].LangID); - if (! newString.IsEmpty()) menuLoc->SetMenuLabel(i1, (const TCHAR *)newString); - } - - // sub-menu items - for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++) - { - wxMenuItem * mi = menuLoc->FindItem(kIDLangPairs[i].ControlID); - if (mi) - { - MyChangeItem(mi,kIDLangPairs[i].LangID); - } -// else -// printf("Change Menu : id=%d index=%d<>\n",kIDLangPairs[i].ControlID,i); - } -} - -#ifdef _WIN32 -CMenu g_FileMenu; - -class CFileMenuDestroyer -{ -public: - ~CFileMenuDestroyer() - { - if ((HMENU)g_FileMenu != 0) - g_FileMenu.Destroy(); - } -} g_FileMenuDestroyer; -#endif - - -void MyLoadMenu(HWND hWnd) -{ -#ifdef _WIN32 - if ((HMENU)g_FileMenu != 0) - g_FileMenu.Destroy(); - HMENU oldMenu = ::GetMenu(hWnd); - HMENU baseMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)); - ::SetMenu(hWnd, baseMenu); - ::DestroyMenu(oldMenu); - if (!g_LangID.IsEmpty()) - { - HMENU menuOld = ::GetMenu(hWnd); - MyChangeMenu(menuOld, 0, 0); - } - ::DrawMenuBar(hWnd); -#else - extern void rc_MyLoadMenu(HWND hWnd); - rc_MyLoadMenu(hWnd); - if (!g_LangID.IsEmpty()) - { - HMENU menuOld = ((wxFrame *)hWnd)->GetMenuBar(); // ::GetMenu(hWnd); - MyChangeMenu(menuOld, 0, 0); - } -#endif -} - -extern HWND g_HWND; -void MyLoadMenu() -{ - MyLoadMenu(g_HWND); -} - -#ifdef _WIN32 -static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec) -{ - CMenu srcMenu; - srcMenu.Attach(srcMenuSpec); - CMenu destMenu; - destMenu.Attach(destMenuSpec); - int startPos = 0; - for (int i = 0; i < srcMenu.GetItemCount(); i++) - { - CMenuItem item; - item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); - item.fType = MFT_STRING; - if (srcMenu.GetItem(i, true, item)) - if (destMenu.InsertItem(startPos, true, item)) - startPos++; - } -} - -void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position) -{ - if (::GetSubMenu(::GetMenu(g_HWND), position) != hMenu) - return; - if (position == kFileMenuIndex) - { - if ((HMENU)g_FileMenu == 0) - { - g_FileMenu.CreatePopup(); - CopyMenu(hMenu, g_FileMenu); - } - CMenu menu; - menu.Attach(hMenu); - while (menu.GetItemCount() > 0) - { - if (!menu.RemoveItem(0, MF_BYPOSITION)) - break; - } - // CopyMenu(g_FileMenu, hMenu); - g_App.GetFocusedPanel().CreateFileMenu(hMenu); - } - else if (position == kEditMenuIndex) - { - /* - CMenu menu; - menu.Attach(hMenu); - menu.EnableItem(IDM_EDIT_CUT, MF_ENABLED); - menu.EnableItem(IDM_EDIT_COPY, MF_ENABLED); - menu.EnableItem(IDM_EDIT_PASTE, IsClipboardFormatAvailableHDROP() ? MF_ENABLED : MF_GRAYED); - */ - } - else if (position == kViewMenuIndex) - { - // View; - CMenu menu; - menu.Attach(hMenu); - menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, - IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND); - menu.CheckItem(IDM_VIEW_TWO_PANELS, MF_BYCOMMAND | - ((g_App.NumPanels == 2) ? MF_CHECKED : MF_UNCHECKED)); - menu.CheckItem(IDM_VIEW_FLAT_VIEW, MF_BYCOMMAND | - ((g_App.GetFlatMode()) ? MF_CHECKED : MF_UNCHECKED)); - menu.CheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, MF_BYCOMMAND | - (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED)); - menu.CheckItem(IDM_VIEW_STANDARD_TOOLBAR, MF_BYCOMMAND | - (g_App.ShowStandardToolbar ? MF_CHECKED : MF_UNCHECKED)); - menu.CheckItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, MF_BYCOMMAND | - (g_App.LargeButtons ? MF_CHECKED : MF_UNCHECKED)); - menu.CheckItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, MF_BYCOMMAND | - (g_App.ShowButtonsLables ? MF_CHECKED : MF_UNCHECKED)); - } - else if (position == kBookmarksMenuIndex) - { - CMenu menu; - menu.Attach(hMenu); - - CMenu subMenu; - subMenu.Attach(menu.GetSubMenu(0)); - while (subMenu.GetItemCount() > 0) - subMenu.RemoveItem(subMenu.GetItemCount() - 1, MF_BYPOSITION); - int i; - for (i = 0; i < 10; i++) - { - UString s = LangString(IDS_BOOKMARK, 0x03000720); - s += L" "; - wchar_t c = (wchar_t)(L'0' + i); - s += c; - s += L"\tAlt+Shift+"; - s += c; - subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s); - } - - while (menu.GetItemCount() > 2) - menu.RemoveItem(menu.GetItemCount() - 1, MF_BYPOSITION); - - for (i = 0; i < 10; i++) - { - UString path = g_App.AppState.FastFolders.GetString(i); - const int kMaxSize = 100; - const int kFirstPartSize = kMaxSize / 2; - if (path.Length() > kMaxSize) - { - path = path.Left(kFirstPartSize) + UString(L" ... ") + - path.Right(kMaxSize - kFirstPartSize); - } - UString s = path; - if (s.IsEmpty()) - s = L"-"; - s += L"\tAlt+"; - s += (wchar_t)(L'0' + i); - menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s); - } - } -} - -/* -It doesn't help -void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id) -{ - if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu) - return; - // g_App.GetFocusedPanel()._contextMenu.Release(); -} - -void OnMenuUnActivating(HWND hWnd) -{ -} -*/ - - -void LoadFileMenu(HMENU hMenu, int startPos, bool /* forFileMode */, bool programMenu) -{ - { - CMenu srcMenu; - srcMenu.Attach(::GetSubMenu(::GetMenu(g_HWND), 0)); - if ((HMENU)g_FileMenu == 0) - { - g_FileMenu.CreatePopup(); - CopyMenu(srcMenu, g_FileMenu); - } - } - - CMenu destMenu; - destMenu.Attach(hMenu); - - for (int i = 0; i < g_FileMenu.GetItemCount(); i++) - { - CMenuItem item; - - item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); - item.fType = MFT_STRING; - if (g_FileMenu.GetItem(i, true, item)) - { - if (!programMenu) - if (item.wID == IDCLOSE) - continue; - /* - bool createItem = (item.wID == IDM_CREATE_FOLDER || item.wID == IDM_CREATE_FILE); - if (forFileMode) - { - if (createItem) - continue; - } - else - { - if (!createItem) - continue; - } - */ - if (destMenu.InsertItem(startPos, true, item)) - startPos++; - } - } - while (destMenu.GetItemCount() > 0) - { - CMenuItem item; - item.fMask = MIIM_TYPE; - item.fType = 0; - // item.dwTypeData = 0; - int lastIndex = destMenu.GetItemCount() - 1; - if (!destMenu.GetItem(lastIndex, true, item)) - break; - if(item.fType != MFT_SEPARATOR) - break; - if (!destMenu.RemoveItem(lastIndex, MF_BYPOSITION)) - break; - } -} -#endif - -bool ExecuteFileCommand(int id) -{ - if (id >= kMenuCmdID_Plugin_Start) - { - printf("DEBUG : ExecuteFileCommand(id=%d)-0\n",id); -#ifdef _WIN32 - g_App.GetFocusedPanel().InvokePluginCommand(id); - g_App.GetFocusedPanel()._sevenZipContextMenu.Release(); - g_App.GetFocusedPanel()._systemContextMenu.Release(); -#endif - return true; - } - - printf("DEBUG : ExecuteFileCommand(id=%d)-1\n",id); - switch (id) - { - // File - case IDM_OPEN: g_App.OpenItem(); break; - case IDM_OPEN_INSIDE: g_App.OpenItemInside(NULL); break; - case IDM_OPEN_INSIDE_ONE: g_App.OpenItemInside(L"*"); break; - case IDM_OPEN_INSIDE_PARSER: g_App.OpenItemInside(L"#"); break; - case IDM_OPEN_OUTSIDE: g_App.OpenItemOutside(); break; - case IDM_FILE_VIEW: g_App.EditItem(false); break; - case IDM_FILE_EDIT: g_App.EditItem(true); break; - case IDM_RENAME: g_App.Rename(); break; - case IDM_COPY_TO: g_App.CopyTo(); break; - case IDM_MOVE_TO: g_App.MoveTo(); break; -#ifdef _WIN32 // FIXME - case IDM_DELETE: g_App.Delete(!IsKeyDown(VK_SHIFT)); break; -#else - case IDM_DELETE: g_App.Delete(true); break; // FIXME -#endif - - case IDM_HASH_ALL: g_App.CalculateCrc(L"*"); break; - case IDM_CRC32: g_App.CalculateCrc(L"CRC32"); break; - case IDM_CRC64: g_App.CalculateCrc(L"CRC64"); break; - case IDM_SHA1: g_App.CalculateCrc(L"SHA1"); break; - case IDM_SHA256: g_App.CalculateCrc(L"SHA256"); break; - - case IDM_DIFF: g_App.DiffFiles(); break; - case IDM_SPLIT: g_App.Split(); break; - case IDM_COMBINE: g_App.Combine(); break; - case IDM_PROPERTIES: g_App.Properties(); break; - case IDM_COMMENT: g_App.Comment(); break; - case IDM_CREATE_FOLDER: g_App.CreateFolder(); break; - case IDM_CREATE_FILE: g_App.CreateFile(); break; - #if 0 // FIXME #ifndef UNDER_CE - case IDM_LINK: g_App.Link(); break; - #endif - default: return false; - } - printf("DEBUG : ExecuteFileCommand(id=%d)-2\n",id); - return true; -} - -#define LLL_(quote) L##quote -#define LLL(quote) LLL_(quote) - -void createAboutDialog(void) -{ - wxAboutDialogInfo info; - - UString msg; - - msg = L"7-Zip is free software"; - info.SetDescription((const wchar_t *)msg); - - - UString version = LLL(MY_VERSION); - #ifdef MY_CPU_64BIT - version += L" ["; - version += LangString(IDS_PROP_BIT64); - version += L']'; - #endif - - info.SetName(_("P7ZIP")); - // info.SetVersion(wxString(MY_VERSION, wxConvUTF8)); - info.SetVersion((const wchar_t *)version); - info.SetCopyright(wxString(MY_COPYRIGHT, wxConvUTF8)); - info.SetWebSite(_T("www.7-zip.org")); - - wxAboutBox(info); -} - -static void MyBenchmark(bool totalMode) -{ - CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]); - CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]); - Benchmark(totalMode); -} - -bool OnMenuCommand(HWND hWnd, int id) -{ - printf("DEBUG : OnMenuCommand(%p,id=%d)-0\n",hWnd,id); - - if (ExecuteFileCommand(id)) - return true; - - printf("DEBUG : OnMenuCommand(%p,id=%d)-1\n",hWnd,id); - - switch (id) - { - // File - case IDCLOSE: - /* FIXME - SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); - SendMessage (hWnd, WM_CLOSE, 0, 0); - */ - hWnd->Close(true); - break; - - // Edit - /* - case IDM_EDIT_CUT: - g_App.EditCut(); - break; - case IDM_EDIT_COPY: - g_App.EditCopy(); - break; - case IDM_EDIT_PASTE: - g_App.EditPaste(); - break; - */ - case IDM_SELECT_ALL: - g_App.SelectAll(true); - g_App.Refresh_StatusBar(); - break; - case IDM_DESELECT_ALL: - g_App.SelectAll(false); - g_App.Refresh_StatusBar(); - break; - case IDM_INVERT_SELECTION: - g_App.InvertSelection(); - g_App.Refresh_StatusBar(); - break; - case IDM_SELECT: - g_App.SelectSpec(true); - g_App.Refresh_StatusBar(); - break; - case IDM_DESELECT: - g_App.SelectSpec(false); - g_App.Refresh_StatusBar(); - break; - case IDM_SELECT_BY_TYPE: - g_App.SelectByType(true); - g_App.Refresh_StatusBar(); - break; - case IDM_DESELECT_BY_TYPE: - g_App.SelectByType(false); - g_App.Refresh_StatusBar(); - break; - - //View - case IDM_VIEW_LARGE_ICONS: - case IDM_VIEW_SMALL_ICONS: - case IDM_VIEW_LIST: - case IDM_VIEW_DETAILS: - { - UINT index = id - IDM_VIEW_LARGE_ICONS; - if (index < 4) - { - g_App.SetListViewMode(index); - /* - CMenu menu; - menu.Attach(::GetSubMenu(::GetMenu(hWnd), kMenuIndex_View)); - menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, - id, MF_BYCOMMAND); - */ - } - break; - } - case IDM_VIEW_ARANGE_BY_NAME: g_App.SortItemsWithPropID(kpidName); break; - case IDM_VIEW_ARANGE_BY_TYPE: g_App.SortItemsWithPropID(kpidExtension); break; - case IDM_VIEW_ARANGE_BY_DATE: g_App.SortItemsWithPropID(kpidMTime); break; - case IDM_VIEW_ARANGE_BY_SIZE: g_App.SortItemsWithPropID(kpidSize); break; - case IDM_VIEW_ARANGE_NO_SORT: g_App.SortItemsWithPropID(kpidNoProperty); break; - - case IDM_OPEN_ROOT_FOLDER: g_App.OpenRootFolder(); break; - case IDM_OPEN_PARENT_FOLDER: g_App.OpenParentFolder(); break; - case IDM_FOLDERS_HISTORY: g_App.FoldersHistory(); break; - case IDM_VIEW_FLAT_VIEW: g_App.ChangeFlatMode(); break; - case IDM_VIEW_REFRESH: g_App.RefreshView(); break; - case IDM_VIEW_AUTO_REFRESH: g_App.Change_AutoRefresh_Mode(); break; - - // case IDM_VIEW_SHOW_STREAMS: g_App.Change_ShowNtfsStrems_Mode(); break; - /* - case IDM_VIEW_SHOW_DELETED: - { - g_App.Change_ShowDeleted(); - bool isChecked = g_App.ShowDeletedFiles; - Save_ShowDeleted(isChecked); - } - */ - - case IDM_VIEW_TWO_PANELS: g_App.SwitchOnOffOnePanel(); break; - case IDM_VIEW_STANDARD_TOOLBAR: g_App.SwitchStandardToolbar(); break; - case IDM_VIEW_ARCHIVE_TOOLBAR: g_App.SwitchArchiveToolbar(); break; - - case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: g_App.SwitchButtonsLables(); break; - case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: g_App.SwitchLargeButtons(); break; - - // Tools - // FIXME case IDM_OPTIONS: OptionsDialog(hWnd, g_hInstance); break; - - case IDM_BENCHMARK: MyBenchmark(false); break; - case IDM_BENCHMARK2: MyBenchmark(true); break; - - // Help - case IDM_HELP_CONTENTS: - ShowHelpWindow(NULL, kFMHelpTopic); - break; - case IDM_ABOUT: - { - /* FIXME - CAboutDialog dialog; - dialog.Create(hWnd); - */ - createAboutDialog(); - break; - } - default: - { - if (id >= kOpenBookmarkMenuID && id <= kOpenBookmarkMenuID + 9) - { - g_App.OpenBookmark(id - kOpenBookmarkMenuID); - return true; - } - else if (id >= kSetBookmarkMenuID && id <= kSetBookmarkMenuID + 9) - { - g_App.SetBookmark(id - kSetBookmarkMenuID); - return true; - } - return false; - } - } - return true; -} - +// MyLoadMenu.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/TimeUtils.h" +#include "../../../Windows/Control/Dialog.h" + +#include "../../PropID.h" + +#include "../Common/CompressCall.h" + +#include "AboutDialog.h" +#include "App.h" +#include "BrowseDialog2.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "MyLoadMenu.h" +#include "RegistryUtils.h" + +#include "PropertyNameRes.h" +#include "resource.h" + +using namespace NWindows; + +static const UINT k_MenuID_OpenBookmark = 830; +static const UINT k_MenuID_SetBookmark = 810; +static const UINT k_MenuID_TimePopup = IDM_VIEW_TIME_POPUP; +static const UINT k_MenuID_Time = IDM_VIEW_TIME; + +#if 0 +// static const UINT k_MenuID_Bookmark_Temp = 850; +#endif + +extern HINSTANCE g_hInstance; + +#define kFMHelpTopic "FM/index.htm" + +extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance); + +enum +{ + k_MenuIndex_File = 0, + k_MenuIndex_Edit, + k_MenuIndex_View, + k_MenuIndex_Bookmarks +}; + +#ifdef Z7_LANG +static const UInt32 k_LangID_TopMenuItems[] = +{ + IDM_FILE, + IDM_EDIT, + IDM_VIEW, + IDM_FAVORITES, + IDM_TOOLS, + IDM_HELP +}; + +static const UInt32 k_LangID_Toolbars = IDM_VIEW_TOOLBARS; +static const UInt32 k_LangID_AddToFavorites = IDM_ADD_TO_FAVORITES; + +static const CIDLangPair kIDLangPairs[] = +{ + { IDCLOSE, 557 }, // IDM_EXIT + { IDM_VIEW_ARANGE_BY_NAME, IDS_PROP_NAME }, + { IDM_VIEW_ARANGE_BY_TYPE, IDS_PROP_FILE_TYPE }, + { IDM_VIEW_ARANGE_BY_DATE, IDS_PROP_MTIME }, + { IDM_VIEW_ARANGE_BY_SIZE, IDS_PROP_SIZE } +}; + +static int FindLangItem(unsigned controlID) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kIDLangPairs); i++) + if (kIDLangPairs[i].ControlID == controlID) + return (int)i; + return -1; +} +#endif + +static unsigned GetSortControlID(PROPID propID) +{ + switch (propID) + { + case kpidName: return IDM_VIEW_ARANGE_BY_NAME; + case kpidExtension: return IDM_VIEW_ARANGE_BY_TYPE; + case kpidMTime: return IDM_VIEW_ARANGE_BY_DATE; + case kpidSize: return IDM_VIEW_ARANGE_BY_SIZE; + case kpidNoProperty: return IDM_VIEW_ARANGE_NO_SORT; + } + return IDM_VIEW_ARANGE_BY_NAME; + // IDM_VIEW_ARANGE_NO_SORT; + // return -1; +} + +/* +#if _MSC_VER > 1400 +// GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif + +static bool g_IsNew_fMask = false; +static class CInit_fMask +{ +public: + CInit_fMask() + { + DWORD v = GetVersion(); + v = ((v & 0xff) << 8) | ((v >> 8) & 0xFF); + g_IsNew_fMask = (v > 0x400); // (win98/win2000) or newer + } +} g_Init_fMask; +static UINT Get_fMask_for_String() + { return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; } +static UINT Get_fMask_for_FType_and_String() + { return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; } +*/ + +/* +We can use new MIIM_STRING / MIIM_FTYPE flags in the following conditions: + 1) we run at new Windows (win98/win2000) or newer + 2) also we probably must set MENUITEMINFO::cbSize as sizeof of full + (MENUITEMINFO) that was compiled with (WINVER >= 0x0500) +But it's simpler to use old MIIM_TYPE without these complex checks. +*/ + +// /* +static inline UINT Get_fMask_for_String() { return MIIM_TYPE; } +static inline UINT Get_fMask_for_FType_and_String() { return MIIM_TYPE; } +// */ + +static bool Is_MenuItem_TimePopup(const CMenuItem &item) +{ + return item.wID == k_MenuID_TimePopup || + item.StringValue.IsPrefixedBy_Ascii_NoCase("20"); +} + +#ifdef Z7_LANG +static void MyChangeMenu(HMENU menuLoc, unsigned menuID, unsigned level, unsigned menuIndex) +{ + CMenu menu; + menu.Attach(menuLoc); + + for (unsigned i = 0;; i++) + { + CMenuItem item; + /* here we can use + Get_fMask_for_String() or + Get_fMask_for_FType_and_String() + We want to change only String of menu item. + It's not required to change (fType) of menu item. + We can look (fType) to check for SEPARATOR item. + But String of separator is empty and (wID == 0). + So we can check for SEPARATOR without (fType) requesting. + So it's enough to use Get_fMask_for_String() here */ + item.fMask = + Get_fMask_for_String() + // Get_fMask_for_FType_and_String() + | MIIM_SUBMENU | MIIM_ID; + if (!menu.GetItem(i, true, item)) + break; + { + UString newString; + if (item.hSubMenu) + { + /* in win10: + MENU+POPUP: + (wID == item.hSubMenu) + MENUEX+POPUP where ID is not set: + (wID == 0) + MENU+SEPARATOR + (wID == 0) + */ + UInt32 langID = item.wID; + if (langID >= (1 << 16)) + { + // here we try to exclude the case (wID == item.hSubMenu) if (MENU+POPUP) + continue; + } + if (langID == 0) + { + if (level == 0) + { + if (i < Z7_ARRAY_SIZE(k_LangID_TopMenuItems)) + langID = k_LangID_TopMenuItems[i]; + } + else if (level == 1) + { + if (menuID == IDM_FAVORITES || (menuID == 0 && menuIndex == k_MenuIndex_Bookmarks)) + langID = k_LangID_AddToFavorites; + else if (menuID == IDM_VIEW || (menuID == 0 && menuIndex == k_MenuIndex_View)) + { + if (Is_MenuItem_TimePopup(item)) + langID = k_MenuID_TimePopup; + else + langID = k_LangID_Toolbars; + } + } + } + if (langID == k_MenuID_TimePopup) + continue; + if (langID != k_LangID_AddToFavorites) + MyChangeMenu(item.hSubMenu, langID, level + 1, i); + if (langID == 0) + continue; + LangString_OnlyFromLangFile(langID, newString); + if (newString.IsEmpty()) + continue; + } + else + { + if (item.fMask & (MIIM_TYPE | MIIM_FTYPE)) + if (item.IsSeparator()) + continue; + if (item.StringValue.IsEmpty()) + continue; + const int langPos = FindLangItem(item.wID); + // we don't need lang change for CRC items!!! + const UInt32 langID = langPos >= 0 ? kIDLangPairs[langPos].LangID : item.wID; + if (langID == 0) + continue; + + if (langID == IDM_OPEN_INSIDE_ONE || + langID == IDM_OPEN_INSIDE_PARSER) + { + LangString_OnlyFromLangFile(IDM_OPEN_INSIDE, newString); + if (newString.IsEmpty()) + continue; + newString.Replace(L"&", L""); + const int tabPos = newString.Find(L"\t"); + if (tabPos >= 0) + newString.DeleteFrom(tabPos); + newString += (langID == IDM_OPEN_INSIDE_ONE ? " *" : " #"); + } + else if (langID == IDM_BENCHMARK2) + { + LangString_OnlyFromLangFile(IDM_BENCHMARK, newString); + if (newString.IsEmpty()) + continue; + newString.Replace(L"&", L""); + const int tabPos = newString.Find(L"\t"); + if (tabPos >= 0) + newString.DeleteFrom(tabPos); + newString += " 2"; + } + else + { + LangString_OnlyFromLangFile(langID, newString); + } + + if (newString.IsEmpty()) + continue; + + const int tabPos = item.StringValue.ReverseFind(L'\t'); + if (tabPos >= 0) + newString += item.StringValue.Ptr(tabPos); + } + + { + item.StringValue = newString; + // we want to change only String + item.fMask = Get_fMask_for_String(); + menu.SetItem(i, true, item); + } + } + } +} +#endif + +static CMenu g_FileMenu; + +static struct CFileMenuDestroyer +{ + ~CFileMenuDestroyer() { if ((HMENU)g_FileMenu) g_FileMenu.Destroy(); } +} g_FileMenuDestroyer; + + +static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec); + +static void CopyPopMenu_IfRequired(CMenuItem &item) +{ + /* if (item.hSubMenu) is defined + { + - it creates new (popup) menu + - it copies menu items from old item.hSubMenu menu to new (popup) menu + - it sets item.hSubMenu to handle of created (popup) menu + } */ + if (item.hSubMenu) + { + CMenu popup; + popup.CreatePopup(); + CopyMenu(item.hSubMenu, popup); + item.hSubMenu = popup; + } +} + +/* destMenuSpec must be non-NULL handle to created empty popup menu */ +static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec) +{ + CMenu srcMenu; + srcMenu.Attach(srcMenuSpec); + CMenu destMenu; + destMenu.Attach(destMenuSpec); + unsigned startPos = 0; + for (unsigned i = 0;; i++) + { + CMenuItem item; + item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String(); + if (!srcMenu.GetItem(i, true, item)) + break; + CopyPopMenu_IfRequired(item); + if (destMenu.InsertItem(startPos, true, item)) + startPos++; + } +} + + +/* use for (needResetMenu): + false : for call from program window creation code + true : for another calls : (from Options language change) +*/ +void MyLoadMenu(bool needResetMenu) +{ + #ifdef UNDER_CE + + const HMENU oldMenu = g_App._commandBar.GetMenu(0); + if (oldMenu) + ::DestroyMenu(oldMenu); + /* BOOL b = */ g_App._commandBar.InsertMenubar(g_hInstance, IDM_MENU, 0); + const HMENU baseMenu = g_App._commandBar.GetMenu(0); + // if (startInit) + // SetIdsForSubMenus(baseMenu, 0, 0); + if (!g_LangID.IsEmpty()) + MyChangeMenu(baseMenu, 0, 0); + g_App._commandBar.DrawMenuBar(0); + + #else // UNDER_CE + + const HWND hWnd = g_HWND; + bool menuWasChanged = false; + /* + We must reload to english default menu for at least two cases: + - if some submenu was changed (File or another submenu can be changed after menu activating). + - for change from non-english lang to another partial non-english lang, + where we still need some english strings. + But we reload menu to default menu everytime except of program starting stage. + That scheme is simpler than complex checks for exact conditions for menu reload. + */ + if (needResetMenu) + { + const HMENU oldMenu = ::GetMenu(hWnd); + const HMENU newMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)); + // docs for SetMenu(): the window is redrawn to reflect the menu change. + if (newMenu && ::SetMenu(hWnd, newMenu)) + ::DestroyMenu(oldMenu); + menuWasChanged = true; + } + const HMENU baseMenu = ::GetMenu(hWnd); + // if (startInit) + // SetIdsForSubMenus(baseMenu, 0, 0); + #ifdef Z7_LANG + if (!g_Lang.IsEmpty()) // !g_LangID.IsEmpty() && + { + MyChangeMenu(baseMenu, 0, 0, 0); + menuWasChanged = true; + } + #endif + + if (menuWasChanged) + ::DrawMenuBar(hWnd); + + #endif // UNDER_CE + + // menuWasChanged = false; // for debug + if (menuWasChanged || !(HMENU)g_FileMenu) + { + if ((HMENU)g_FileMenu) + g_FileMenu.Destroy(); + g_FileMenu.CreatePopup(); + CopyMenu(::GetSubMenu(baseMenu, k_MenuIndex_File), g_FileMenu); + } +} + +void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position) +{ + HMENU mainMenu = + #ifdef UNDER_CE + g_App._commandBar.GetMenu(0); + #else + ::GetMenu(g_HWND) + #endif + ; + + if (::GetSubMenu(mainMenu, position) != hMenu) + return; + + if (position == k_MenuIndex_File) + { + CMenu menu; + menu.Attach(hMenu); + menu.RemoveAllItems(); + g_App.GetFocusedPanel().CreateFileMenu(hMenu); + } + else if (position == k_MenuIndex_Edit) + { + /* + CMenu menu; + menu.Attach(hMenu); + menu.EnableItem(IDM_EDIT_CUT, MF_ENABLED); + menu.EnableItem(IDM_EDIT_COPY, MF_ENABLED); + menu.EnableItem(IDM_EDIT_PASTE, IsClipboardFormatAvailableHDROP() ? MF_ENABLED : MF_GRAYED); + */ + } + else if (position == k_MenuIndex_View) + { + // View; + CMenu menu; + menu.Attach(hMenu); + menu.CheckRadioItem( + IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND); + + menu.CheckRadioItem( + IDM_VIEW_ARANGE_BY_NAME, + IDM_VIEW_ARANGE_NO_SORT, + GetSortControlID(g_App.GetSortID()), + MF_BYCOMMAND); + + menu.CheckItemByID(IDM_VIEW_TWO_PANELS, g_App.NumPanels == 2); + menu.CheckItemByID(IDM_VIEW_FLAT_VIEW, g_App.GetFlatMode()); + menu.CheckItemByID(IDM_VIEW_ARCHIVE_TOOLBAR, g_App.ShowArchiveToolbar); + menu.CheckItemByID(IDM_VIEW_STANDARD_TOOLBAR, g_App.ShowStandardToolbar); + menu.CheckItemByID(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, g_App.LargeButtons); + menu.CheckItemByID(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, g_App.ShowButtonsLables); + menu.CheckItemByID(IDM_VIEW_AUTO_REFRESH, g_App.Get_AutoRefresh_Mode()); + // menu.CheckItemByID(IDM_VIEW_SHOW_STREAMS, g_App.Get_ShowNtfsStrems_Mode()); + // menu.CheckItemByID(IDM_VIEW_SHOW_DELETED, g_App.ShowDeletedFiles); + + for (unsigned i = 0;; i++) + { + CMenuItem item; + item.fMask = Get_fMask_for_String() | MIIM_SUBMENU | MIIM_ID; + item.fType = MFT_STRING; + if (!menu.GetItem(i, true, item)) + break; + if (item.hSubMenu && Is_MenuItem_TimePopup(item)) + { + FILETIME ft; + NTime::GetCurUtcFileTime(ft); + + { + wchar_t s[64]; + s[0] = 0; + if (ConvertUtcFileTimeToString(ft, s, kTimestampPrintLevel_DAY)) + item.StringValue = s; + } + + item.fMask = Get_fMask_for_String() | MIIM_ID; + item.fType = MFT_STRING; + item.wID = k_MenuID_TimePopup; + menu.SetItem(i, true, item); + + CMenu subMenu; + subMenu.Attach(menu.GetSubMenu((int)i)); + subMenu.RemoveAllItems(); + + const int k_TimeLevels[] = + { + kTimestampPrintLevel_DAY, + kTimestampPrintLevel_MIN, + kTimestampPrintLevel_SEC, + // 1,2,3,4,5,6, + kTimestampPrintLevel_NTFS, + kTimestampPrintLevel_NS + }; + + unsigned last = k_MenuID_Time; + unsigned selectedCommand = 0; + g_App._timestampLevels.Clear(); + unsigned id = k_MenuID_Time; + + for (unsigned k = 0; k < Z7_ARRAY_SIZE(k_TimeLevels); k++) + { + wchar_t s[64]; + s[0] = 0; + const int timestampLevel = k_TimeLevels[k]; + if (ConvertUtcFileTimeToString(ft, s, timestampLevel)) + { + if (subMenu.AppendItem(MF_STRING, id, s)) + { + last = id; + g_App._timestampLevels.Add(timestampLevel); + if (g_App.GetTimestampLevel() == timestampLevel) + selectedCommand = id; + id++; + } + } + } + if (selectedCommand != 0) + menu.CheckRadioItem(k_MenuID_Time, last, selectedCommand, MF_BYCOMMAND); + + if (subMenu.AppendItem(MF_STRING, IDM_VIEW_TIME_UTC, L"UTC")) + subMenu.CheckItemByID(IDM_VIEW_TIME_UTC, g_Timestamp_Show_UTC); + } + } + } + else if (position == k_MenuIndex_Bookmarks) + { + CMenu menu; + menu.Attach(hMenu); + + CMenu subMenu; + subMenu.Attach(menu.GetSubMenu(0)); + subMenu.RemoveAllItems(); + unsigned i; + + for (i = 0; i < 10; i++) + { + UString s = LangString(IDS_BOOKMARK); + s.Add_Space(); + const char c = (char)(L'0' + i); + s.Add_Char(c); + s += "\tAlt+Shift+"; + s.Add_Char(c); + subMenu.AppendItem(MF_STRING, k_MenuID_SetBookmark + i, s); + } + + menu.RemoveAllItemsFrom(2); + + for (i = 0; i < 10; i++) + { + UString s = g_App.AppState.FastFolders.GetString(i); + const int kMaxSize = 100; + const int kFirstPartSize = kMaxSize / 2; + if (s.Len() > kMaxSize) + { + s.Delete(kFirstPartSize, s.Len() - kMaxSize); + s.Insert(kFirstPartSize, L" ... "); + } + if (s.IsEmpty()) + s = '-'; + s += "\tAlt+"; + s.Add_Char((char)('0' + i)); + menu.AppendItem(MF_STRING, k_MenuID_OpenBookmark + i, s); + } +#if 0 + { + FString tempPathF; + if (NFile::NDir::MyGetTempPath(tempPathF)) + { + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); + UString s; + s = "Temp : "; + s += fs2us(tempPathF); + menu.AppendItem(MF_STRING, k_MenuID_Bookmark_Temp, s); + } + } +#endif + } +} + +/* +It doesn't help +void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id) +{ + if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu) + return; +} +*/ + +static const unsigned g_Zvc_IDs[] = +{ + IDM_VER_EDIT, + IDM_VER_COMMIT, + IDM_VER_REVERT, + IDM_VER_DIFF +}; + +static const char * const g_Zvc_Strings[] = +{ + "Ver Edit (&1)" + , "Ver Commit" + , "Ver Revert" + , "Ver Diff (&0)" +}; + +void CFileMenu::Load(HMENU hMenu, unsigned startPos) +{ + CMenu destMenu; + destMenu.Attach(hMenu); + + UString diffPath; + ReadRegDiff(diffPath); + + unsigned numRealItems = startPos; + + const bool isBigScreen = NControl::IsDialogSizeOK(40, 200, g_HWND); + + for (unsigned i = 0;; i++) + { + CMenuItem item; + + item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String(); + item.fType = MFT_STRING; + + if (!g_FileMenu.GetItem(i, true, item)) + break; + + { + if (!programMenu && item.wID == IDCLOSE) + continue; + + if (item.wID == IDM_DIFF && diffPath.IsEmpty()) + continue; + + if (item.wID == IDM_OPEN_INSIDE_ONE || item.wID == IDM_OPEN_INSIDE_PARSER) + { + // We use diff as "super mode" marker for additional commands. + /* + if (diffPath.IsEmpty()) + continue; + */ + } + + if (item.wID == IDM_BENCHMARK2) + { + // We use diff as "super mode" marker for additional commands. + if (diffPath.IsEmpty()) + continue; + } + + bool isOneFsFile = (isFsFolder && numItems == 1 && allAreFiles); + bool disable = (!isOneFsFile && (item.wID == IDM_SPLIT || item.wID == IDM_COMBINE)); + + if (readOnly) + { + switch (item.wID) + { + case IDM_RENAME: + case IDM_MOVE_TO: + case IDM_DELETE: + case IDM_COMMENT: + case IDM_CREATE_FOLDER: + case IDM_CREATE_FILE: + disable = true; + } + } + + if (isHashFolder) + { + switch (item.wID) + { + case IDM_OPEN: + case IDM_OPEN_INSIDE: + case IDM_OPEN_INSIDE_ONE: + case IDM_OPEN_INSIDE_PARSER: + case IDM_OPEN_OUTSIDE: + case IDM_FILE_VIEW: + case IDM_FILE_EDIT: + // case IDM_RENAME: + case IDM_COPY_TO: + case IDM_MOVE_TO: + // case IDM_DELETE: + case IDM_COMMENT: + case IDM_CREATE_FOLDER: + case IDM_CREATE_FILE: + case IDM_LINK: + case IDM_DIFF: + disable = true; + } + } + + + if (item.wID == IDM_LINK && numItems != 1) + disable = true; + + if (item.wID == IDM_ALT_STREAMS) + disable = !isAltStreamsSupported; + + if (!isBigScreen && (disable || item.IsSeparator())) + continue; + + CopyPopMenu_IfRequired(item); + if (destMenu.InsertItem(startPos, true, item)) + { + if (disable) + destMenu.EnableItem(startPos, MF_BYPOSITION | MF_GRAYED); + startPos++; + } + + if (!item.IsSeparator()) + numRealItems = startPos; + } + } + + UString vercPath; + if (!diffPath.IsEmpty() && isFsFolder && allAreFiles && numItems == 1) + ReadReg_VerCtrlPath(vercPath); + + if (!vercPath.IsEmpty()) + { + NFile::NFind::CFileInfo fi; + if (fi.Find(FilePath) && fi.Size < ((UInt32)1 << 31) && !fi.IsDir()) + { + for (unsigned k = 0; k < Z7_ARRAY_SIZE(g_Zvc_IDs); k++) + { + const unsigned id = g_Zvc_IDs[k]; + if (fi.IsReadOnly()) + { + if (id == IDM_VER_COMMIT || + id == IDM_VER_REVERT || + id == IDM_VER_DIFF) + continue; + } + else + { + if (id == IDM_VER_EDIT) + continue; + } + + CMenuItem item; + UString s (g_Zvc_Strings[k]); + if (destMenu.AppendItem(MF_STRING, id, s)) + { + startPos++; + numRealItems = startPos; + } + } + } + } + + destMenu.RemoveAllItemsFrom(numRealItems); +} + +bool ExecuteFileCommand(unsigned id) +{ + if (id >= kMenuCmdID_Plugin_Start) + { + g_App.GetFocusedPanel().InvokePluginCommand(id); + g_App.GetFocusedPanel()._sevenZipContextMenu.Release(); + g_App.GetFocusedPanel()._systemContextMenu.Release(); + return true; + } + + switch (id) + { + // File + case IDM_OPEN: g_App.OpenItem(); break; + + case IDM_OPEN_INSIDE: g_App.OpenItemInside(NULL); break; + case IDM_OPEN_INSIDE_ONE: g_App.OpenItemInside(L"*"); break; + case IDM_OPEN_INSIDE_PARSER: g_App.OpenItemInside(L"#"); break; + + case IDM_OPEN_OUTSIDE: g_App.OpenItemOutside(); break; + case IDM_FILE_VIEW: g_App.EditItem(false); break; + case IDM_FILE_EDIT: g_App.EditItem(true); break; + case IDM_RENAME: g_App.Rename(); break; + case IDM_COPY_TO: g_App.CopyTo(); break; + case IDM_MOVE_TO: g_App.MoveTo(); break; + case IDM_DELETE: g_App.Delete(!IsKeyDown(VK_SHIFT)); break; + + case IDM_HASH_ALL: g_App.CalculateCrc("*"); break; + case IDM_CRC32: g_App.CalculateCrc("CRC32"); break; + case IDM_CRC64: g_App.CalculateCrc("CRC64"); break; + case IDM_XXH64: g_App.CalculateCrc("XXH64"); break; + case IDM_MD5: g_App.CalculateCrc("MD5"); break; + case IDM_SHA1: g_App.CalculateCrc("SHA1"); break; + case IDM_SHA256: g_App.CalculateCrc("SHA256"); break; + case IDM_SHA384: g_App.CalculateCrc("SHA384"); break; + case IDM_SHA512: g_App.CalculateCrc("SHA512"); break; + case IDM_SHA3_256: g_App.CalculateCrc("SHA3-256"); break; + case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break; + + case IDM_DIFF: g_App.DiffFiles(); break; + + case IDM_VER_EDIT: + case IDM_VER_COMMIT: + case IDM_VER_REVERT: + case IDM_VER_DIFF: + g_App.VerCtrl(id); break; + + case IDM_SPLIT: g_App.Split(); break; + case IDM_COMBINE: g_App.Combine(); break; + case IDM_PROPERTIES: g_App.Properties(); break; + case IDM_COMMENT: g_App.Comment(); break; + case IDM_CREATE_FOLDER: g_App.CreateFolder(); break; + case IDM_CREATE_FILE: g_App.CreateFile(); break; + #ifndef UNDER_CE + case IDM_LINK: g_App.Link(); break; + case IDM_ALT_STREAMS: g_App.OpenAltStreams(); break; + #endif + default: return false; + } + return true; +} + +static void MyBenchmark(bool totalMode) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]); + CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]); + Benchmark(totalMode); +} + +bool OnMenuCommand(HWND hWnd, unsigned id) +{ + if (ExecuteFileCommand(id)) + return true; + + switch (id) + { + // File + case IDCLOSE: + // SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + // g_ExitEventLauncher.Exit(false); + SendMessage(hWnd, WM_CLOSE, 0, 0); + break; + + // Edit + /* + case IDM_EDIT_CUT: + g_App.EditCut(); + break; + case IDM_EDIT_COPY: + g_App.EditCopy(); + break; + case IDM_EDIT_PASTE: + g_App.EditPaste(); + break; + */ + case IDM_SELECT_ALL: + g_App.SelectAll(true); + g_App.Refresh_StatusBar(); + break; + case IDM_DESELECT_ALL: + g_App.SelectAll(false); + g_App.Refresh_StatusBar(); + break; + case IDM_INVERT_SELECTION: + g_App.InvertSelection(); + g_App.Refresh_StatusBar(); + break; + case IDM_SELECT: + g_App.SelectSpec(true); + g_App.Refresh_StatusBar(); + break; + case IDM_DESELECT: + g_App.SelectSpec(false); + g_App.Refresh_StatusBar(); + break; + case IDM_SELECT_BY_TYPE: + g_App.SelectByType(true); + g_App.Refresh_StatusBar(); + break; + case IDM_DESELECT_BY_TYPE: + g_App.SelectByType(false); + g_App.Refresh_StatusBar(); + break; + + //View + case IDM_VIEW_LARGE_ICONS: + case IDM_VIEW_SMALL_ICONS: + case IDM_VIEW_LIST: + case IDM_VIEW_DETAILS: + { + UINT index = id - IDM_VIEW_LARGE_ICONS; + if (index < 4) + { + g_App.SetListViewMode(index); + /* + CMenu menu; + menu.Attach(::GetSubMenu(::GetMenu(hWnd), k_MenuIndex_View)); + menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + id, MF_BYCOMMAND); + */ + } + break; + } + case IDM_VIEW_ARANGE_BY_NAME: g_App.SortItemsWithPropID(kpidName); break; + case IDM_VIEW_ARANGE_BY_TYPE: g_App.SortItemsWithPropID(kpidExtension); break; + case IDM_VIEW_ARANGE_BY_DATE: g_App.SortItemsWithPropID(kpidMTime); break; + case IDM_VIEW_ARANGE_BY_SIZE: g_App.SortItemsWithPropID(kpidSize); break; + case IDM_VIEW_ARANGE_NO_SORT: g_App.SortItemsWithPropID(kpidNoProperty); break; + + case IDM_OPEN_ROOT_FOLDER: g_App.OpenRootFolder(); break; + case IDM_OPEN_PARENT_FOLDER: g_App.OpenParentFolder(); break; + case IDM_FOLDERS_HISTORY: g_App.FoldersHistory(); break; + case IDM_VIEW_FLAT_VIEW: g_App.ChangeFlatMode(); break; + case IDM_VIEW_REFRESH: g_App.RefreshView(); break; + case IDM_VIEW_AUTO_REFRESH: g_App.Change_AutoRefresh_Mode(); break; + + // case IDM_VIEW_SHOW_STREAMS: g_App.Change_ShowNtfsStrems_Mode(); break; + /* + case IDM_VIEW_SHOW_DELETED: + { + g_App.Change_ShowDeleted(); + bool isChecked = g_App.ShowDeletedFiles; + Save_ShowDeleted(isChecked); + } + */ + + case IDM_VIEW_TWO_PANELS: g_App.SwitchOnOffOnePanel(); break; + case IDM_VIEW_STANDARD_TOOLBAR: g_App.SwitchStandardToolbar(); break; + case IDM_VIEW_ARCHIVE_TOOLBAR: g_App.SwitchArchiveToolbar(); break; + + case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: g_App.SwitchButtonsLables(); break; + case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: g_App.SwitchLargeButtons(); break; + + case IDM_VIEW_TIME_UTC: + g_Timestamp_Show_UTC = !g_Timestamp_Show_UTC; + g_App.RedrawListItems_InPanels(); + break; + + // Tools + case IDM_OPTIONS: OptionsDialog(hWnd, g_hInstance); break; + + case IDM_BENCHMARK: MyBenchmark(false); break; + case IDM_BENCHMARK2: MyBenchmark(true); break; + + // Help + case IDM_HELP_CONTENTS: + ShowHelpWindow(kFMHelpTopic); + break; + case IDM_ABOUT: + { + CAboutDialog dialog; + dialog.Create(hWnd); + break; + } + + case IDM_TEMP_DIR: + { + /* + CPanel &panel = g_App.GetFocusedPanel(); + FString tempPathF; + if (NFile::NDir::MyGetTempPath(tempPathF)) + panel.BindToPathAndRefresh(tempPathF); + */ + MyBrowseForTempFolder(g_HWND); + break; + } + + default: + { + if (id >= k_MenuID_OpenBookmark && id <= k_MenuID_OpenBookmark + 9) + { + g_App.OpenBookmark(id - k_MenuID_OpenBookmark); + return true; + } + else if (id >= k_MenuID_SetBookmark && id <= k_MenuID_SetBookmark + 9) + { + g_App.SetBookmark(id - k_MenuID_SetBookmark); + return true; + } + else if (id >= k_MenuID_Time && (unsigned)id < k_MenuID_Time + g_App._timestampLevels.Size()) + { + g_App.SetTimestampLevel(g_App._timestampLevels[id - k_MenuID_Time]); + return true; + } + return false; + } + } + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyLoadMenu.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyLoadMenu.h 2015-09-19 18:00:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyLoadMenu.h 2023-01-21 16:00:00.000000000 +0000 @@ -1,39 +1,40 @@ -// MyLoadMenu.h - -#ifndef __MY_LOAD_MENU_H -#define __MY_LOAD_MENU_H - -class myHMENU; // FIXME -typedef myHMENU * HMENU; // FIXME - -void OnMenuActivating(HWND hWnd, HMENU hMenu, int position); -// void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id); -// void OnMenuUnActivating(HWND hWnd); - -bool OnMenuCommand(HWND hWnd, int id); -void MyLoadMenu(); - -struct CFileMenu -{ - bool programMenu; - bool readOnly; - bool isFsFolder; - bool allAreFiles; - bool isAltStreamsSupported; - int numItems; - - CFileMenu(): - programMenu(false), - readOnly(false), - isFsFolder(false), - allAreFiles(false), - isAltStreamsSupported(true), - numItems(0) - {} - - void Load(HMENU hMenu, unsigned startPos); -}; - -bool ExecuteFileCommand(int id); - -#endif +// MyLoadMenu.h + +#ifndef ZIP7_INC_MY_LOAD_MENU_H +#define ZIP7_INC_MY_LOAD_MENU_H + +void OnMenuActivating(HWND hWnd, HMENU hMenu, int position); +// void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id); +// void OnMenuUnActivating(HWND hWnd); + +bool OnMenuCommand(HWND hWnd, unsigned id); +void MyLoadMenu(bool needResetMenu); + +struct CFileMenu +{ + bool programMenu; + bool readOnly; + bool isHashFolder; + bool isFsFolder; + bool allAreFiles; + bool isAltStreamsSupported; + unsigned numItems; + + FString FilePath; + + CFileMenu(): + programMenu(false), + readOnly(false), + isHashFolder(false), + isFsFolder(false), + allAreFiles(false), + isAltStreamsSupported(true), + numItems(0) + {} + + void Load(HMENU hMenu, unsigned startPos); +}; + +bool ExecuteFileCommand(unsigned id); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyWindowsNew.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyWindowsNew.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/MyWindowsNew.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/MyWindowsNew.h 2023-04-13 10:00:00.000000000 +0000 @@ -1,76 +1,119 @@ -// MyWindowsNew.h - -#ifndef __MY_WINDOWS_NEW_H -#define __MY_WINDOWS_NEW_H - -#ifdef _MSC_VER - -#include - -#ifndef __ITaskbarList3_INTERFACE_DEFINED__ -#define __ITaskbarList3_INTERFACE_DEFINED__ - -typedef enum THUMBBUTTONFLAGS -{ - THBF_ENABLED = 0, - THBF_DISABLED = 0x1, - THBF_DISMISSONCLICK = 0x2, - THBF_NOBACKGROUND = 0x4, - THBF_HIDDEN = 0x8, - THBF_NONINTERACTIVE = 0x10 -} THUMBBUTTONFLAGS; - -typedef enum THUMBBUTTONMASK -{ - THB_BITMAP = 0x1, - THB_ICON = 0x2, - THB_TOOLTIP = 0x4, - THB_FLAGS = 0x8 -} THUMBBUTTONMASK; - -// #include - -typedef struct THUMBBUTTON -{ - THUMBBUTTONMASK dwMask; - UINT iId; - UINT iBitmap; - HICON hIcon; - WCHAR szTip[260]; - THUMBBUTTONFLAGS dwFlags; -} THUMBBUTTON; - -typedef struct THUMBBUTTON *LPTHUMBBUTTON; - -typedef enum TBPFLAG -{ - TBPF_NOPROGRESS = 0, - TBPF_INDETERMINATE = 0x1, - TBPF_NORMAL = 0x2, - TBPF_ERROR = 0x4, - TBPF_PAUSED = 0x8 -} TBPFLAG; - -DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF); - -struct ITaskbarList3: public ITaskbarList2 -{ - STDMETHOD(SetProgressValue)(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0; - STDMETHOD(SetProgressState)(HWND hwnd, TBPFLAG tbpFlags) = 0; - STDMETHOD(RegisterTab)(HWND hwndTab, HWND hwndMDI) = 0; - STDMETHOD(UnregisterTab)(HWND hwndTab) = 0; - STDMETHOD(SetTabOrder)(HWND hwndTab, HWND hwndInsertBefore) = 0; - STDMETHOD(SetTabActive)(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; - STDMETHOD(ThumbBarAddButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; - STDMETHOD(ThumbBarUpdateButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; - STDMETHOD(ThumbBarSetImageList)(HWND hwnd, HIMAGELIST himl) = 0; - STDMETHOD(SetOverlayIcon)(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0; - STDMETHOD(SetThumbnailTooltip)(HWND hwnd, LPCWSTR pszTip) = 0; - STDMETHOD(SetThumbnailClip)(HWND hwnd, RECT *prcClip) = 0; -}; - -#endif - -#endif - -#endif +// MyWindowsNew.h + +#ifndef ZIP7_INC_MY_WINDOWS_NEW_H +#define ZIP7_INC_MY_WINDOWS_NEW_H + +#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__MINGW32_VERSION) +#include + +#if defined(__MINGW32_VERSION) && !defined(__ITaskbarList3_INTERFACE_DEFINED__) +// for old mingw +extern "C" { +DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF); +DEFINE_GUID(CLSID_TaskbarList, 0x56fdf344, 0xfd6d, 0x11d0, 0x95,0x8a, 0x00,0x60,0x97,0xc9,0xa0,0x90); +} +#endif + +#else // is not __MINGW* + +#ifndef Z7_OLD_WIN_SDK +#include +#else + +#ifndef HIMAGELIST +struct _IMAGELIST; +typedef struct _IMAGELIST* HIMAGELIST; +#endif + +#ifndef __ITaskbarList_INTERFACE_DEFINED__ +#define __ITaskbarList_INTERFACE_DEFINED__ +DEFINE_GUID(IID_ITaskbarList, 0x56FDF342, 0xFD6D, 0x11d0, 0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90); +struct ITaskbarList: public IUnknown +{ + STDMETHOD(HrInit)(void) = 0; + STDMETHOD(AddTab)(HWND hwnd) = 0; + STDMETHOD(DeleteTab)(HWND hwnd) = 0; + STDMETHOD(ActivateTab)(HWND hwnd) = 0; + STDMETHOD(SetActiveAlt)(HWND hwnd) = 0; +}; +#endif // __ITaskbarList_INTERFACE_DEFINED__ + +#ifndef __ITaskbarList2_INTERFACE_DEFINED__ +#define __ITaskbarList2_INTERFACE_DEFINED__ +DEFINE_GUID(IID_ITaskbarList2, 0x602D4995, 0xB13A, 0x429b, 0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17); +struct ITaskbarList2: public ITaskbarList +{ + STDMETHOD(MarkFullscreenWindow)(HWND hwnd, BOOL fFullscreen) = 0; +}; +#endif // __ITaskbarList2_INTERFACE_DEFINED__ + +#endif // Z7_OLD_WIN_SDK + + +#ifndef __ITaskbarList3_INTERFACE_DEFINED__ +#define __ITaskbarList3_INTERFACE_DEFINED__ + +typedef enum THUMBBUTTONFLAGS +{ + THBF_ENABLED = 0, + THBF_DISABLED = 0x1, + THBF_DISMISSONCLICK = 0x2, + THBF_NOBACKGROUND = 0x4, + THBF_HIDDEN = 0x8, + THBF_NONINTERACTIVE = 0x10 +} THUMBBUTTONFLAGS; + +typedef enum THUMBBUTTONMASK +{ + THB_BITMAP = 0x1, + THB_ICON = 0x2, + THB_TOOLTIP = 0x4, + THB_FLAGS = 0x8 +} THUMBBUTTONMASK; + +// #include + +typedef struct THUMBBUTTON +{ + THUMBBUTTONMASK dwMask; + UINT iId; + UINT iBitmap; + HICON hIcon; + WCHAR szTip[260]; + THUMBBUTTONFLAGS dwFlags; +} THUMBBUTTON; + +typedef struct THUMBBUTTON *LPTHUMBBUTTON; + +typedef enum TBPFLAG +{ + TBPF_NOPROGRESS = 0, + TBPF_INDETERMINATE = 0x1, + TBPF_NORMAL = 0x2, + TBPF_ERROR = 0x4, + TBPF_PAUSED = 0x8 +} TBPFLAG; + +DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF); + +struct ITaskbarList3: public ITaskbarList2 +{ + STDMETHOD(SetProgressValue)(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0; + STDMETHOD(SetProgressState)(HWND hwnd, TBPFLAG tbpFlags) = 0; + STDMETHOD(RegisterTab)(HWND hwndTab, HWND hwndMDI) = 0; + STDMETHOD(UnregisterTab)(HWND hwndTab) = 0; + STDMETHOD(SetTabOrder)(HWND hwndTab, HWND hwndInsertBefore) = 0; + STDMETHOD(SetTabActive)(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; + STDMETHOD(ThumbBarAddButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; + STDMETHOD(ThumbBarUpdateButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; + STDMETHOD(ThumbBarSetImageList)(HWND hwnd, HIMAGELIST himl) = 0; + STDMETHOD(SetOverlayIcon)(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0; + STDMETHOD(SetThumbnailTooltip)(HWND hwnd, LPCWSTR pszTip) = 0; + STDMETHOD(SetThumbnailClip)(HWND hwnd, RECT *prcClip) = 0; +}; + +#endif // __ITaskbarList3_INTERFACE_DEFINED__ + +#endif // __MINGW* + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/NetFolder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/NetFolder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.cpp 2024-07-09 09:00:00.000000000 +0000 @@ -0,0 +1,276 @@ +// NetFolder.cpp + +#include "StdAfx.h" + +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#include "FSFolder.h" +#include "NetFolder.h" +#include "SysIconUtils.h" + +using namespace NWindows; +using namespace NNet; + +static const Byte kProps[] = +{ + kpidName, + kpidLocalName, + kpidComment, + kpidProvider +}; + +void CNetFolder::Init(const UString &path) +{ + /* + if (path.Len() > 2) + { + if (path[0] == L'\\' && path[1] == L'\\') + { + CResource netResource; + netResource.RemoteName = GetSystemString(path.Left(path.Len() - 1)); + netResource.Scope = RESOURCE_GLOBALNET; + netResource.Type = RESOURCETYPE_DISK; + netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER; + netResource.Usage = RESOURCEUSAGE_CONTAINER; + Init(&netResource, 0, path); + return; + } + } + Init(0, 0 , L""); + */ + CResourceW resource; + resource.RemoteNameIsDefined = true; + if (!path.IsEmpty()) + resource.RemoteName.SetFrom(path, path.Len() - 1); + resource.ProviderIsDefined = false; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.Type = RESOURCETYPE_DISK; + resource.Scope = RESOURCE_GLOBALNET; + resource.Usage = 0; + resource.DisplayType = 0; + CResourceW destResource; + UString systemPathPart; + DWORD result = GetResourceInformation(resource, destResource, systemPathPart); + if (result == NO_ERROR) + Init(&destResource, NULL, path); + else + Init(NULL, NULL , L""); + return; +} + +void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path) +{ + _path = path; + if (!netResource) + _netResourcePointer = NULL; + else + { + _netResource = *netResource; + _netResourcePointer = &_netResource; + + // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + _path = _netResource.RemoteName; + + /* WinXP-64: When we move UP from Network share without _parentFolder chain, + we can get empty _netResource.RemoteName. Do we need to use Provider there ? */ + if (_path.IsEmpty()) + _path = _netResource.Provider; + + if (!_path.IsEmpty()) + _path.Add_PathSepar(); + } + _parentFolder = parentFolder; +} + +Z7_COM7F_IMF(CNetFolder::LoadItems()) +{ + _items.Clear(); + CEnum enumerator; + + for (;;) + { + DWORD result = enumerator.Open( + RESOURCE_GLOBALNET, + RESOURCETYPE_DISK, + 0, // enumerate all resources + _netResourcePointer + ); + if (result == NO_ERROR) + break; + if (result != ERROR_ACCESS_DENIED) + return HRESULT_FROM_WIN32(result); + if (_netResourcePointer) + result = AddConnection2(_netResource, + NULL, NULL, CONNECT_INTERACTIVE); + if (result != NO_ERROR) + return HRESULT_FROM_WIN32(result); + } + + for (;;) + { + CResourceEx resource; + const DWORD result = enumerator.Next(resource); + if (result == NO_ERROR) + { + if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong + resource.RemoteName = resource.Comment; + resource.Name = resource.RemoteName; + const int pos = resource.Name.ReverseFind_PathSepar(); + if (pos >= 0) + { + // _path = resource.Name.Left(pos + 1); + resource.Name.DeleteFrontal((unsigned)pos + 1); + } + _items.Add(resource); + } + else if (result == ERROR_NO_MORE_ITEMS) + break; + else + return HRESULT_FROM_WIN32(result); + } + + /* + It's too slow for some systems. + if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + for (char c = 'a'; c <= 'z'; c++) + { + CResourceEx resource; + resource.Name = UString(wchar_t(c)) + L'$'; + resource.RemoteNameIsDefined = true; + resource.RemoteName = _path + resource.Name; + + NFile::NFind::CFindFile findFile; + NFile::NFind::CFileInfo fileInfo; + if (!findFile.FindFirst(us2fs(resource.RemoteName) + FString(FCHAR_PATH_SEPARATOR) + FCHAR_ANY_MASK, fileInfo)) + continue; + resource.Usage = RESOURCEUSAGE_CONNECTABLE; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.ProviderIsDefined = false; + _items.Add(resource); + } + } + */ + return S_OK; +} + + +Z7_COM7F_IMF(CNetFolder::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = _items.Size(); + return S_OK; +} + +Z7_COM7F_IMF(CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + const CResourceEx &item = _items[itemIndex]; + switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidName: + // if (item.RemoteNameIsDefined) + prop = item.Name; + break; + case kpidLocalName: if (item.LocalNameIsDefined) prop = item.LocalName; break; + case kpidComment: if (item.CommentIsDefined) prop = item.Comment; break; + case kpidProvider: if (item.ProviderIsDefined) prop = item.Provider; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + const CResourceEx &resource = _items[index]; + if (resource.Usage == RESOURCEUSAGE_CONNECTABLE || + resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE) + { + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))) // , this + *resultFolder = subFolder.Detach(); + } + else + { + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resource, this, resource.Name + WCHAR_PATH_SEPARATOR); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +Z7_COM7F_IMF(CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */)) +{ + return E_NOTIMPL; +} + +Z7_COM7F_IMF(CNetFolder::BindToParentFolder(IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + if (_netResourcePointer) + { + CResourceW resourceParent; + const DWORD result = GetResourceParent(_netResource, resourceParent); + if (result != NO_ERROR) + return HRESULT_FROM_WIN32(result); + if (!_netResource.RemoteNameIsDefined) + return S_OK; + + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resourceParent, NULL, WSTRING_PATH_SEPARATOR); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +IMP_IFolderFolder_Props(CNetFolder) + +Z7_COM7F_IMF(CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + NWindows::NCOM::CPropVariant prop; + switch (propID) + { + case kpidType: prop = "NetFolder"; break; + case kpidPath: prop = _path; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +{ + *iconIndex = -1; + if (index >= _items.Size()) + return E_INVALIDARG; + const CResourceW &resource = _items[index]; + if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER || + resource.Usage == RESOURCEUSAGE_CONNECTABLE) + { + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + us2fs(resource.RemoteName), FILE_ATTRIBUTE_DIRECTORY, iconIndex); + } + else + { +#if 0 + return S_FALSE; +#else + return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + FTEXT("__DIR__"), FILE_ATTRIBUTE_DIRECTORY, iconIndex); +#endif + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/NetFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/NetFolder.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/NetFolder.h 2023-04-01 11:00:00.000000000 +0000 @@ -0,0 +1,36 @@ +// NetFolder.h + +#ifndef ZIP7_INC_NET_FOLDER_H +#define ZIP7_INC_NET_FOLDER_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/Net.h" + +#include "IFolder.h" + +struct CResourceEx: public NWindows::NNet::CResourceW +{ + UString Name; +}; + +Z7_CLASS_IMP_NOQIB_2( + CNetFolder + , IFolderFolder + , IFolderGetSystemIconIndex +) + NWindows::NNet::CResourceW _netResource; + NWindows::NNet::CResourceW *_netResourcePointer; + + CObjectVector _items; + + CMyComPtr _parentFolder; + UString _path; +public: + CNetFolder(): _netResourcePointer(NULL) {} + void Init(const UString &path); + void Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OpenCallback.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OpenCallback.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.cpp 2024-10-21 09:00:00.000000000 +0000 @@ -1,129 +1,86 @@ -// OpenCallback.cpp - -#include "StdAfx.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" - -#include "../../Common/FileStreams.h" - -#include "../Common/ZipRegistry.h" - -#include "OpenCallback.h" -#include "PasswordDialog.h" - -using namespace NWindows; - -STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes) -{ - RINOK(ProgressDialog.Sync.CheckStop()); - { - // NSynchronization::CCriticalSectionLock lock(_criticalSection); - if (numFiles) - { - ProgressDialog.Sync.Set_NumFilesTotal(*numFiles); - ProgressDialog.Sync.Set_BytesProgressMode(false); - } - if (numBytes) - ProgressDialog.Sync.Set_NumBytesTotal(*numBytes); - } - return S_OK; -} - -STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes) -{ - // NSynchronization::CCriticalSectionLock lock(_criticalSection); - if (numFiles) - ProgressDialog.Sync.Set_NumFilesCur(*numFiles); - if (numBytes) - ProgressDialog.Sync.Set_NumBytesCur(*numBytes); - return ProgressDialog.Sync.CheckStop(); -} - -STDMETHODIMP COpenArchiveCallback::SetTotal(const UInt64 total) -{ - RINOK(ProgressDialog.Sync.CheckStop()); - ProgressDialog.Sync.Set_NumBytesTotal(total); - return S_OK; -} - -STDMETHODIMP COpenArchiveCallback::SetCompleted(const UInt64 *completed) -{ - return ProgressDialog.Sync.Set_NumBytesCur(completed); -} - -STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - if (_subArchiveMode) - { - switch (propID) - { - case kpidName: prop = _subArchiveName; break; - } - } - else - { - switch (propID) - { - case kpidName: prop = _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; - } - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream) -{ - COM_TRY_BEGIN - *inStream = NULL; - if (_subArchiveMode) - return S_FALSE; - - FString fullPath; - if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath)) - return S_FALSE; - if (!_fileInfo.Find(fullPath)) - return S_FALSE; - if (_fileInfo.IsDir()) - return S_FALSE; - CInFileStream *inFile = new CInFileStream; - CMyComPtr inStreamTemp = inFile; - if (!inFile->Open(fullPath)) - return ::GetLastError(); - *inStream = inStreamTemp.Detach(); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) -{ - COM_TRY_BEGIN - PasswordWasAsked = true; - if (!PasswordIsDefined) - { - CPasswordDialog dialog; - bool showPassword = NExtract::Read_ShowPassword(); - dialog.ShowPassword = showPassword; - - ProgressDialog.WaitCreating(); - if (dialog.Create(ProgressDialog) != IDOK) - return E_ABORT; - - Password = dialog.Password; - PasswordIsDefined = true; - if (dialog.ShowPassword != showPassword) - NExtract::Save_ShowPassword(dialog.ShowPassword); - } - return StringToBstr(Password, password); - COM_TRY_END -} +// OpenCallback.cpp + +#include "StdAfx.h" + +#include "../../../Common/ComTry.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +#include "../Common/ZipRegistry.h" + +#include "OpenCallback.h" +#include "PasswordDialog.h" + +using namespace NWindows; + +HRESULT COpenArchiveCallback::Open_SetTotal(const UInt64 *numFiles, const UInt64 *numBytes) +// Z7_COM7F_IMF(COpenArchiveCallback::SetTotal(const UInt64 *numFiles, const UInt64 *numBytes)) +{ + // COM_TRY_BEGIN + RINOK(ProgressDialog.Sync.CheckStop()) + { + // NSynchronization::CCriticalSectionLock lock(_criticalSection); + ProgressDialog.Sync.Set_NumFilesTotal(numFiles ? *numFiles : (UInt64)(Int64)-1); + // if (numFiles) + { + ProgressDialog.Sync.Set_FilesProgressMode(numFiles != NULL); + } + if (numBytes) + ProgressDialog.Sync.Set_NumBytesTotal(*numBytes); + } + return S_OK; + // COM_TRY_END +} + +HRESULT COpenArchiveCallback::Open_SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes) +// Z7_COM7F_IMF(COpenArchiveCallback::SetCompleted(const UInt64 *numFiles, const UInt64 *numBytes)) +{ + // COM_TRY_BEGIN + // NSynchronization::CCriticalSectionLock lock(_criticalSection); + if (numFiles) + ProgressDialog.Sync.Set_NumFilesCur(*numFiles); + if (numBytes) + ProgressDialog.Sync.Set_NumBytesCur(*numBytes); + return ProgressDialog.Sync.CheckStop(); + // COM_TRY_END +} + +HRESULT COpenArchiveCallback::Open_CheckBreak() +{ + return ProgressDialog.Sync.CheckStop(); +} + +HRESULT COpenArchiveCallback::Open_Finished() +{ + return ProgressDialog.Sync.CheckStop(); +} + +#ifndef Z7_NO_CRYPTO +HRESULT COpenArchiveCallback::Open_CryptoGetTextPassword(BSTR *password) +// Z7_COM7F_IMF(COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)) +{ + // COM_TRY_BEGIN + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + bool showPassword = NExtract::Read_ShowPassword(); + dialog.ShowPassword = showPassword; + + ProgressDialog.WaitCreating(); + if (dialog.Create(ProgressDialog) != IDOK) + return E_ABORT; + + Password = dialog.Password; + PasswordIsDefined = true; + if (dialog.ShowPassword != showPassword) + NExtract::Save_ShowPassword(dialog.ShowPassword); + } + return StringToBstr(Password, password); + // COM_TRY_END +} +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OpenCallback.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OpenCallback.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OpenCallback.h 2023-02-01 15:00:00.000000000 +0000 @@ -1,91 +1,69 @@ -// OpenCallback.h - -#ifndef __OPEN_CALLBACK_H -#define __OPEN_CALLBACK_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/FileFind.h" - -#include "../../IPassword.h" - -#include "../../Archive/IArchive.h" - -#ifdef _SFX -#include "ProgressDialog.h" -#else -#include "ProgressDialog2.h" -#endif - - -class COpenArchiveCallback: - public IArchiveOpenCallback, - public IArchiveOpenVolumeCallback, - public IArchiveOpenSetSubArchiveName, - public IProgress, - public ICryptoGetTextPassword, - public CMyUnknownImp -{ - FString _folderPrefix; - NWindows::NFile::NFind::CFileInfo _fileInfo; - // NWindows::NSynchronization::CCriticalSection _criticalSection; - bool _subArchiveMode; - UString _subArchiveName; - -public: - bool PasswordIsDefined; - bool PasswordWasAsked; - UString Password; - HWND ParentWindow; - CProgressDialog ProgressDialog; - - MY_UNKNOWN_IMP5( - IArchiveOpenCallback, - IArchiveOpenVolumeCallback, - IArchiveOpenSetSubArchiveName, - IProgress, - ICryptoGetTextPassword) - - INTERFACE_IProgress(;) - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IArchiveOpenVolumeCallback(;) - - // ICryptoGetTextPassword - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - - STDMETHOD(SetSubArchiveName(const wchar_t *name)) - { - _subArchiveMode = true; - _subArchiveName = name; - return S_OK; - } - - COpenArchiveCallback(): - ParentWindow(0) - { - _subArchiveMode = false; - PasswordIsDefined = false; - PasswordWasAsked = false; - } - /* - void Init() - { - PasswordIsDefined = false; - _subArchiveMode = false; - } - */ - void LoadFileInfo(const FString &folderPrefix, const FString &fileName) - { - _folderPrefix = folderPrefix; - if (!_fileInfo.Find(_folderPrefix + fileName)) - throw 1; - } - void ShowMessage(const UInt64 *completed); - - INT_PTR StartProgressDialog(const UString &title, NWindows::CThread &thread) - { - return ProgressDialog.Create(title, thread, ParentWindow); - } -}; - -#endif +// OpenCallback.h + +#ifndef ZIP7_INC_OPEN_CALLBACK_H +#define ZIP7_INC_OPEN_CALLBACK_H + +#include "../Common/ArchiveOpenCallback.h" + +#ifdef Z7_SFX +#include "ProgressDialog.h" +#else +#include "ProgressDialog2.h" +#endif + +/* we can use IArchiveOpenCallback or IOpenCallbackUI here */ + +class COpenArchiveCallback Z7_final: + /* + public IArchiveOpenCallback, + public IProgress, + public ICryptoGetTextPassword, + public CMyUnknownImp + */ + public IOpenCallbackUI +{ + // NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + bool PasswordIsDefined; + bool PasswordWasAsked; + UString Password; + HWND ParentWindow; + CProgressDialog ProgressDialog; + + /* + Z7_COM_UNKNOWN_IMP_3( + IArchiveOpenVolumeCallback, + IProgress + ICryptoGetTextPassword + ) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + // ICryptoGetTextPassword + Z7_COM7F_IMP(CryptoGetTextPassword(BSTR *password)) + */ + + Z7_IFACE_IMP(IOpenCallbackUI) + + COpenArchiveCallback(): + ParentWindow(NULL) + { + // _subArchiveMode = false; + PasswordIsDefined = false; + PasswordWasAsked = false; + } + /* + void Init() + { + PasswordIsDefined = false; + _subArchiveMode = false; + } + */ + + INT_PTR StartProgressDialog(const UString &title, NWindows::CThread &thread) + { + return ProgressDialog.Create(title, thread, ParentWindow); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OptionsDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OptionsDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OptionsDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OptionsDialog.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -0,0 +1,89 @@ +// OptionsDialog.cpp + +#include "StdAfx.h" + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/PropertyPage.h" + +#include "DialogSize.h" + +#include "EditPage.h" +#include "EditPageRes.h" +#include "FoldersPage.h" +#include "FoldersPageRes.h" +#include "LangPage.h" +#include "LangPageRes.h" +#include "MenuPage.h" +#include "MenuPageRes.h" +#include "SettingsPage.h" +#include "SettingsPageRes.h" +#include "SystemPage.h" +#include "SystemPageRes.h" + +#include "App.h" +#include "LangUtils.h" +#include "MyLoadMenu.h" + +#include "resource.h" + +using namespace NWindows; + +void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance); +void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */) +{ + CSystemPage systemPage; + CMenuPage menuPage; + CFoldersPage foldersPage; + CEditPage editPage; + CSettingsPage settingsPage; + CLangPage langPage; + + CObjectVector pages; + BIG_DIALOG_SIZE(200, 200); + + const UINT pageIDs[] = { + SIZED_DIALOG(IDD_SYSTEM), + SIZED_DIALOG(IDD_MENU), + SIZED_DIALOG(IDD_FOLDERS), + SIZED_DIALOG(IDD_EDIT), + SIZED_DIALOG(IDD_SETTINGS), + SIZED_DIALOG(IDD_LANG) }; + + NControl::CPropertyPage *pagePointers[] = { &systemPage, &menuPage, &foldersPage, &editPage, &settingsPage, &langPage }; + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(pageIDs); i++) + { + NControl::CPageInfo &page = pages.AddNew(); + page.ID = pageIDs[i]; + #ifdef Z7_LANG + LangString_OnlyFromLangFile(page.ID, page.Title); + #endif + page.Page = pagePointers[i]; + } + + const INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS)); + + if (res != -1 && res != 0) + { + if (langPage.LangWasChanged) + { + // g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000)); + MyLoadMenu(true); // needResetMenu + g_App.ReloadToolbars(); + g_App.MoveSubWindows(); // we need it to change list window aafter _toolBar.AutoSize(); + g_App.ReloadLangItems(); + } + + /* + if (systemPage.WasChanged) + { + // probably it doesn't work, since image list is locked? + g_App.SysIconsWereChanged(); + } + */ + + g_App.SetListSettings(); + g_App.RefreshAllPanels(); + // ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.cpp 2015-06-21 18:40:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.cpp 2024-07-08 05:00:00.000000000 +0000 @@ -1,121 +1,288 @@ -// OverwriteDialog.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariantConv.h" -#include "../../../Windows/ResourceString.h" - -#include "../../../Windows/Control/Static.h" - -#include "FormatUtils.h" -#include "LangUtils.h" -#include "OverwriteDialog.h" - -#include "PropertyNameRes.h" - -using namespace NWindows; - -#ifdef LANG -static const UInt32 kLangIDs[] = -{ - IDT_OVERWRITE_HEADER, - IDT_OVERWRITE_QUESTION_BEGIN, - IDT_OVERWRITE_QUESTION_END, - IDB_YES_TO_ALL, - IDB_NO_TO_ALL, - IDB_AUTO_RENAME -}; -#endif - -static const unsigned kCurrentFileNameSizeLimit = 82; -static const unsigned kCurrentFileNameSizeLimit2 = 30; - -void COverwriteDialog::ReduceString(UString &s) -{ - unsigned size = _isBig ? kCurrentFileNameSizeLimit : kCurrentFileNameSizeLimit2; - if (s.Len() > size) - { - s.Delete(size / 2, s.Len() - size); - s.Insert(size / 2, L" ... "); - } -} - -void COverwriteDialog::SetFileInfoControl(int textID, int iconID, - const NOverwriteDialog::CFileInfo &fileInfo) -{ - UString sizeString; - if (fileInfo.SizeIsDefined) - sizeString = MyFormatNew(IDS_FILE_SIZE, NumberToString(fileInfo.Size)); - - const UString &fileName = fileInfo.Name; - int slashPos = fileName.ReverseFind_PathSepar(); - UString s1 = fileName.Left(slashPos + 1); - UString s2 = fileName.Ptr(slashPos + 1); - - ReduceString(s1); - ReduceString(s2); - - UString s = s1; - s.Add_LF(); - s += s2; - s.Add_LF(); - s += sizeString; - s.Add_LF(); - - if (fileInfo.TimeIsDefined) - { - FILETIME localFileTime; - if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) - throw 4190402; - AddLangString(s, IDS_PROP_MTIME); - s += L": "; - wchar_t t[32]; - ConvertFileTimeToString(localFileTime, t); - s += t; - } - - NControl::CDialogChildControl control; - control.Init(*this, textID); - control.SetText(s); - -#if _WIN32 - SHFILEINFO shellFileInfo; - if (::SHGetFileInfo( - GetSystemString(fileInfo.Name), FILE_ATTRIBUTE_NORMAL, &shellFileInfo, - sizeof(shellFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_LARGEICON)) - { - NControl::CStatic staticContol; - staticContol.Attach(GetItem(iconID)); - staticContol.SetIcon(shellFileInfo.hIcon); - } -#endif -} - -bool COverwriteDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_OVERWRITE); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - #endif - SetFileInfoControl(IDT_OVERWRITE_OLD_FILE_SIZE_TIME, IDI_OVERWRITE_OLD_FILE, OldFileInfo); - SetFileInfoControl(IDT_OVERWRITE_NEW_FILE_SIZE_TIME, IDI_OVERWRITE_NEW_FILE, NewFileInfo); - NormalizePosition(); - return CModalDialog::OnInit(); -} - -bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDYES: - case IDNO: - case IDB_YES_TO_ALL: - case IDB_NO_TO_ALL: - case IDB_AUTO_RENAME: - End(buttonID); - return true; - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/ResourceString.h" + +#include "../../../Windows/Control/Static.h" + +#include "FormatUtils.h" +#include "LangUtils.h" +#include "OverwriteDialog.h" + +#include "PropertyNameRes.h" + +using namespace NWindows; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_OVERWRITE_HEADER, + IDT_OVERWRITE_QUESTION_BEGIN, + IDT_OVERWRITE_QUESTION_END, + IDB_YES_TO_ALL, + IDB_NO_TO_ALL, + IDB_AUTO_RENAME +}; +#endif + +static const unsigned kCurrentFileNameSizeLimit = 72; + +void COverwriteDialog::ReduceString(UString &s) +{ + const unsigned size = +#ifdef UNDER_CE + !_isBig ? 30 : // kCurrentFileNameSizeLimit2 +#endif + kCurrentFileNameSizeLimit; + + if (s.Len() > size) + { + s.Delete(size / 2, s.Len() - size); + s.Insert(size / 2, L" ... "); + } + if (!s.IsEmpty() && s.Back() == ' ') + { + // s += (wchar_t)(0x2423); // visible space + s.InsertAtFront(L'\"'); + s.Add_Char('\"'); + } +} + + +void COverwriteDialog::SetItemIcon(unsigned iconID, HICON hIcon) +{ + NControl::CStatic staticContol; + staticContol.Attach(GetItem(iconID)); + hIcon = staticContol.SetIcon(hIcon); + if (hIcon) + DestroyIcon(hIcon); +} + +void AddSizeValue(UString &s, UInt64 value); +void AddSizeValue(UString &s, UInt64 value) +{ + { + wchar_t sz[32]; + ConvertUInt64ToString(value, sz); + s += MyFormatNew(IDS_FILE_SIZE, sz); + } + if (value >= (1 << 10)) + { + char c; + if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; } + else if (value >= (10 << 20)) { value >>= 20; c = 'M'; } + else { value >>= 10; c = 'K'; } + s += " : "; + s.Add_UInt64(value); + s.Add_Space(); + s.Add_Char(c); + s += "iB"; + } +} + + +void COverwriteDialog::SetFileInfoControl( + const NOverwriteDialog::CFileInfo &fileInfo, + unsigned textID, + unsigned iconID, + unsigned iconID_2) +{ + { + const UString &path = fileInfo.Path; + const int slashPos = path.ReverseFind_PathSepar(); + UString s = path.Left((unsigned)(slashPos + 1)); + ReduceString(s); + s.Add_LF(); + { + UString s2 = path.Ptr((unsigned)(slashPos + 1)); + ReduceString(s2); + s += s2; + } + s.Add_LF(); + if (fileInfo.Size_IsDefined) + AddSizeValue(s, fileInfo.Size); + s.Add_LF(); + if (fileInfo.Time_IsDefined) + { + AddLangString(s, IDS_PROP_MTIME); + s += ": "; + char t[64]; + ConvertUtcFileTimeToString(fileInfo.Time, t); + s += t; + } + SetItemText(textID, s); + } +/* + SHGetFileInfo(): + DOCs: If uFlags does not contain SHGFI_EXETYPE or SHGFI_SYSICONINDEX, + the return value is nonzero if successful, or zero otherwise. + We don't use SHGFI_EXETYPE or SHGFI_SYSICONINDEX here. + win10: we call with SHGFI_ICON flag set. + it returns 0: if error : (shFileInfo::*) members are not set. + it returns non_0, if successful, and retrieve: + { shFileInfo.hIcon != NULL : the handle to icon (must be destroyed by our code) + shFileInfo.iIcon is index of the icon image within the system image list. + } + Note: + If we send path to ".exe" file, + SHGFI_USEFILEATTRIBUTES flag is ignored, and it tries to open file. + and return icon from that exe file. + So we still need to reduce path, if want to get raw icon of exe file. + + if (name.Len() >= MAX_PATH)) + { + it can return: + return 0. + return 1 and: + { shFileInfo.hIcon != NULL : is some default icon for file + shFileInfo.iIcon == 0 + } + return results (0 or 1) can depend from: + - unicode/non-unicode + - (SHGFI_USEFILEATTRIBUTES) flag + - exact file extension (.exe). + } +*/ + int iconIndex = -1; + for (unsigned i = 0; i < 2; i++) + { + CSysString name = GetSystemString(fileInfo.Path); + if (i != 0) + { + if (!fileInfo.Is_FileSystemFile) + break; + if (name.Len() < 4 || + (!StringsAreEqualNoCase_Ascii(name.RightPtr(4), ".exe") && + !StringsAreEqualNoCase_Ascii(name.RightPtr(4), ".ico"))) + break; + // if path for ".exe" file is long, it returns default icon (shFileInfo.iIcon == 0). + // We don't want to show that default icon. + // But we will check for default icon later instead of MAX_PATH check here. + // if (name.Len() >= MAX_PATH) break; // optional + } + else + { + // we need only file extension with dot + const int separ = name.ReverseFind_PathSepar(); + name.DeleteFrontal((unsigned)(separ + 1)); + // if (name.Len() >= MAX_PATH) + { + const int dot = name.ReverseFind_Dot(); + if (dot >= 0) + name.DeleteFrontal((unsigned)dot); + // else name.Empty(); to set default name below + } + // name.Empty(); // for debug + } + + if (name.IsEmpty()) + { + // If we send empty name, SHGetFileInfo() returns some strange icon. + // So we use common dummy name without extension, + // and SHGetFileInfo() will return default icon (iIcon == 0) + name = "__file__"; + } + + DWORD attrib = FILE_ATTRIBUTE_ARCHIVE; + if (fileInfo.Is_FileSystemFile) + { + NFile::NFind::CFileInfo fi; + if (fi.Find(us2fs(fileInfo.Path)) && !fi.IsAltStream && !fi.IsDir()) + attrib = fi.Attrib; + } + + SHFILEINFO shFileInfo; + // ZeroMemory(&shFileInfo, sizeof(shFileInfo)); // optional + shFileInfo.hIcon = NULL; // optional + shFileInfo.iIcon = -1; // optional + // memset(&shFileInfo, 1, sizeof(shFileInfo)); // for debug + const DWORD_PTR res = ::SHGetFileInfo(name, attrib, + &shFileInfo, sizeof(shFileInfo), + SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SHELLICONSIZE | + // (i == 0 ? SHGFI_USEFILEATTRIBUTES : 0) + SHGFI_USEFILEATTRIBUTES + // we use SHGFI_USEFILEATTRIBUTES for second icon, because + // it still returns real icon from exe files + ); + if (res && shFileInfo.hIcon) + { + // we don't show second icon, if icon index (iIcon) is same + // as first icon index of first shown icon (exe file without icon) + if ( shFileInfo.iIcon >= 0 + && shFileInfo.iIcon != iconIndex + && (shFileInfo.iIcon != 0 || i == 0)) // we don't want default icon for second icon + { + iconIndex = shFileInfo.iIcon; + SetItemIcon(i == 0 ? iconID : iconID_2, shFileInfo.hIcon); + } + else + DestroyIcon(shFileInfo.hIcon); + } + } +} + + + +bool COverwriteDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_OVERWRITE); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + SetFileInfoControl(OldFileInfo, + IDT_OVERWRITE_OLD_FILE_SIZE_TIME, + IDI_OVERWRITE_OLD_FILE, + IDI_OVERWRITE_OLD_FILE_2); + SetFileInfoControl(NewFileInfo, + IDT_OVERWRITE_NEW_FILE_SIZE_TIME, + IDI_OVERWRITE_NEW_FILE, + IDI_OVERWRITE_NEW_FILE_2); + NormalizePosition(); + + if (!ShowExtraButtons) + { + HideItem(IDB_YES_TO_ALL); + HideItem(IDB_NO_TO_ALL); + HideItem(IDB_AUTO_RENAME); + } + + if (DefaultButton_is_NO) + { + PostMsg(DM_SETDEFID, IDNO); + HWND h = GetItem(IDNO); + PostMsg(WM_NEXTDLGCTL, (WPARAM)h, TRUE); + // ::SetFocus(h); + } + + return CModalDialog::OnInit(); +} + +bool COverwriteDialog::OnDestroy() +{ + SetItemIcon(IDI_OVERWRITE_OLD_FILE, NULL); + SetItemIcon(IDI_OVERWRITE_OLD_FILE_2, NULL); + SetItemIcon(IDI_OVERWRITE_NEW_FILE, NULL); + SetItemIcon(IDI_OVERWRITE_NEW_FILE_2, NULL); + return false; // we return (false) to perform default dialog operation +} + +bool COverwriteDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDYES: + case IDNO: + case IDB_YES_TO_ALL: + case IDB_NO_TO_ALL: + case IDB_AUTO_RENAME: + End((INT_PTR)buttonID); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.h 2024-07-05 05:00:00.000000000 +0000 @@ -1,69 +1,89 @@ -// OverwriteDialog.h - -#ifndef __OVERWRITE_DIALOG_H -#define __OVERWRITE_DIALOG_H - -#include "../../../Windows/Control/Dialog.h" - -#include "DialogSize.h" -#include "OverwriteDialogRes.h" - -namespace NOverwriteDialog -{ - struct CFileInfo - { - bool SizeIsDefined; - bool TimeIsDefined; - UInt64 Size; - FILETIME Time; - UString Name; - - void SetTime(const FILETIME *t) - { - if (t == 0) - TimeIsDefined = false; - else - { - TimeIsDefined = true; - Time = *t; - } - } - void SetSize(const UInt64 *size) - { - if (size == 0) - SizeIsDefined = false; - else - { - SizeIsDefined = true; - Size = *size; - } - } - }; -} - -class COverwriteDialog: public NWindows::NControl::CModalDialog -{ - bool _isBig; - - void SetFileInfoControl(int textID, int iconID, const NOverwriteDialog::CFileInfo &fileInfo); - virtual bool OnInit(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); - void ReduceString(UString &s); - -public: - INT_PTR Create(HWND parent = 0) - { - BIG_DIALOG_SIZE(280, 200); - #ifdef UNDER_CE - _isBig = isBig; - #else - _isBig = true; - #endif - return CModalDialog::Create(SIZED_DIALOG(IDD_OVERWRITE), parent); - } - - NOverwriteDialog::CFileInfo OldFileInfo; - NOverwriteDialog::CFileInfo NewFileInfo; -}; - -#endif +// OverwriteDialog.h + +#ifndef ZIP7_INC_OVERWRITE_DIALOG_H +#define ZIP7_INC_OVERWRITE_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" + +#include "DialogSize.h" +#include "OverwriteDialogRes.h" + +namespace NOverwriteDialog +{ + struct CFileInfo + { + bool Size_IsDefined; + bool Time_IsDefined; + bool Is_FileSystemFile; + UInt64 Size; + FILETIME Time; + UString Path; + + void SetTime(const FILETIME &t) + { + Time = t; + Time_IsDefined = true; + } + + void SetTime2(const FILETIME *t) + { + if (!t) + Time_IsDefined = false; + else + SetTime(*t); + } + + void SetSize(UInt64 size) + { + Size = size; + Size_IsDefined = true; + } + + void SetSize2(const UInt64 *size) + { + if (!size) + Size_IsDefined = false; + else + SetSize(*size); + } + + CFileInfo(): + Size_IsDefined(false), + Time_IsDefined(false), + Is_FileSystemFile(false) + {} + }; +} + +class COverwriteDialog: public NWindows::NControl::CModalDialog +{ +#ifdef UNDER_CE + bool _isBig; +#endif + + void SetItemIcon(unsigned iconID, HICON hIcon); + void SetFileInfoControl(const NOverwriteDialog::CFileInfo &fileInfo, unsigned textID, unsigned iconID, unsigned iconID_2); + virtual bool OnInit() Z7_override; + virtual bool OnDestroy() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void ReduceString(UString &s); + +public: + bool ShowExtraButtons; + bool DefaultButton_is_NO; + NOverwriteDialog::CFileInfo OldFileInfo; + NOverwriteDialog::CFileInfo NewFileInfo; + + COverwriteDialog(): ShowExtraButtons(true), DefaultButton_is_NO(false) {} + + INT_PTR Create(HWND parent = NULL) + { +#ifdef UNDER_CE + BIG_DIALOG_SIZE(280, 200); + _isBig = isBig; +#endif + return CModalDialog::Create(SIZED_DIALOG(IDD_OVERWRITE), parent); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog.rc 2024-07-05 06:00:00.000000000 +0000 @@ -0,0 +1,93 @@ +#include "OverwriteDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 340 +#define yc 200 + +#undef iconSize +#define iconSize 24 + +#undef x +#undef fx +#undef fy +#define x (m + iconSize + m) +#define fx (xc - iconSize - m) +#define fy 50 + +#define bSizeBig 104 +#undef bx1 +#define bx1 (xs - m - bSizeBig) + +IDD_OVERWRITE DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Confirm File Replace" +BEGIN + LTEXT "Destination folder already contains processed file.", IDT_OVERWRITE_HEADER, m, 7, xc, 8 + LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, 28, xc, 8 + + ICON "", IDI_OVERWRITE_OLD_FILE, m, 44, iconSize, iconSize + ICON "", IDI_OVERWRITE_OLD_FILE_2, m, 44 + iconSize, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 44, fx, fy, SS_NOPREFIX + + LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 98, xc, 8 + + ICON "", IDI_OVERWRITE_NEW_FILE, m, 114, iconSize, iconSize + ICON "", IDI_OVERWRITE_NEW_FILE_2, m, 114 + iconSize, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 114, fx, fy, SS_NOPREFIX + + PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys + PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys + PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bSizeBig, bys + PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys + PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys + PUSHBUTTON "&Cancel", IDCANCEL, xs - m - bxs, by1, bxs, bys +END + + +#ifdef UNDER_CE + +#undef m +#undef xc +#undef yc + +#define m 4 +#define xc 152 +#define yc 144 + +#undef fy +#define fy 40 + +#undef bxs +#define bxs 48 + +#undef bx1 + +#define bx1 (xs - m - bxs) + +IDD_OVERWRITE_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Confirm File Replace" +BEGIN + LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, m, xc, 8 + + ICON "", IDI_OVERWRITE_OLD_FILE, m, 20, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 20, fx, fy, SS_NOPREFIX + + LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 60, xc, 8 + + ICON "", IDI_OVERWRITE_NEW_FILE, m, 72, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 72, fx, fy, SS_NOPREFIX + + PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys + PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys + PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bxs, bys + PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys + PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys + PUSHBUTTON "&Cancel", IDCANCEL, bx1, by1, bxs, bys +END + +#endif + + +STRINGTABLE +BEGIN + IDS_FILE_SIZE "{0} bytes" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialogRes.h 2024-07-04 14:00:00.000000000 +0000 @@ -1,17 +1,19 @@ -#define IDD_OVERWRITE 3500 -#define IDD_OVERWRITE_2 13500 - -#define IDT_OVERWRITE_HEADER 3501 -#define IDT_OVERWRITE_QUESTION_BEGIN 3502 -#define IDT_OVERWRITE_QUESTION_END 3503 -#define IDS_FILE_SIZE 3504 - -#define IDB_AUTO_RENAME 3505 -#define IDB_YES_TO_ALL 440 -#define IDB_NO_TO_ALL 441 - -#define IDI_OVERWRITE_OLD_FILE 100 -#define IDI_OVERWRITE_NEW_FILE 101 - -#define IDT_OVERWRITE_OLD_FILE_SIZE_TIME 102 -#define IDT_OVERWRITE_NEW_FILE_SIZE_TIME 103 +#define IDD_OVERWRITE 3500 +#define IDD_OVERWRITE_2 13500 + +#define IDT_OVERWRITE_HEADER 3501 +#define IDT_OVERWRITE_QUESTION_BEGIN 3502 +#define IDT_OVERWRITE_QUESTION_END 3503 +#define IDS_FILE_SIZE 3504 + +#define IDB_AUTO_RENAME 3505 +#define IDB_YES_TO_ALL 440 +#define IDB_NO_TO_ALL 441 + +#define IDI_OVERWRITE_OLD_FILE 100 +#define IDI_OVERWRITE_OLD_FILE_2 101 +#define IDT_OVERWRITE_OLD_FILE_SIZE_TIME 102 + +#define IDI_OVERWRITE_NEW_FILE 110 +#define IDI_OVERWRITE_NEW_FILE_2 111 +#define IDT_OVERWRITE_NEW_FILE_SIZE_TIME 112 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp 2014-12-28 20:04:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -// OverwriteDialog_rc.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "OverwriteDialogRes.h" -#include "Windows/Control/DialogImpl.h" - -/* -IDD_OVERWRITE DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE -CAPTION "Confirm File Replace" -MY_FONT -BEGIN - LTEXT "Destination folder already contains processed file.", IDT_OVERWRITE_HEADER, marg, 7, xSize2, 8 - LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, marg, 28, xSize2, 8 - ICON "", IDI_OVERWRITE_OLD_FILE, marg, 44, iconSize, iconSize - LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, fiXPos, 44, fiXSize, fiYSize, SS_NOPREFIX - LTEXT "with this one?",IDT_OVERWRITE_QUESTION_END, marg, 98, xSize2, 8 - ICON "",IDI_OVERWRITE_NEW_FILE, marg, 114, iconSize, iconSize - LTEXT "",IDT_OVERWRITE_NEW_FILE_SIZE_TIME, fiXPos, 114, fiXSize, fiYSize, SS_NOPREFIX - PUSHBUTTON "&Yes", IDYES, 78, b2YPos, bXSize, bYSize - PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, 152, b2YPos, bXSize, bYSize - PUSHBUTTON "&No", IDNO, 226, b2YPos, bXSize, bYSize - PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, 300, b2YPos, bXSize, bYSize - PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, 181, b1YPos, 109, bYSize - PUSHBUTTON "&Cancel", IDCANCEL, 300, b1YPos, bXSize, bYSize -END -*/ - -class COverwriteDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - COverwriteDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : CModalDialogImpl(dialog,parent, id, wxT("Confirm File Replace")) - { - ///Sizer for adding the controls created by users - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - topsizer->Add(new wxStaticText(this, IDT_OVERWRITE_HEADER, _T("Destination folder already contains processed file.")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - topsizer->Add(new wxStaticText(this, IDT_OVERWRITE_QUESTION_BEGIN, _T("Would you like to replace the existing file")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - - // FIXME ICON "", IDI_OVERWRITE_OLD_FILE, marg, 44, iconSize, iconSize - topsizer->Add(new wxStaticText(this, IDT_OVERWRITE_OLD_FILE_SIZE_TIME, _T(""), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT) , 0 ,wxALL | wxALIGN_LEFT, 15 ); - topsizer->Add(new wxStaticText(this, IDT_OVERWRITE_QUESTION_END, _T("with this one?")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - - // FIXME ICON "",IDI_OVERWRITE_NEW_FILE, marg, 114, iconSize, iconSize - topsizer->Add(new wxStaticText(this, IDT_OVERWRITE_NEW_FILE_SIZE_TIME, _T(""), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT) , 0 ,wxALL | wxALIGN_LEFT, 15 ); - - wxBoxSizer* Sizer1 = new wxBoxSizer(wxHORIZONTAL); - Sizer1->Add(new wxButton(this, wxID_YES, _T("&Yes")) , 0, wxALL | wxALIGN_RIGHT, 5); - Sizer1->Add(new wxButton(this, IDB_YES_TO_ALL, _T("Yes to &All")) , 0, wxALL | wxALIGN_RIGHT, 5); - Sizer1->Add(new wxButton(this, wxID_NO, _T("&No")) , 0, wxALL | wxALIGN_RIGHT, 5); - Sizer1->Add(new wxButton(this, IDB_NO_TO_ALL, _T("No to A&ll")) , 0, wxALL | wxALIGN_RIGHT, 5); - topsizer->Add(Sizer1 , 0, wxALL | wxALIGN_RIGHT, 5); - - wxBoxSizer* Sizer2 = new wxBoxSizer(wxHORIZONTAL); - Sizer2->Add(new wxButton(this, IDB_AUTO_RENAME, _T("A&uto Rename")) , 0, wxALL | wxALIGN_RIGHT, 5); - Sizer2->Add(new wxButton(this, wxID_CANCEL, _T("&Cancel")) , 0, wxALL | wxALIGN_RIGHT, 5); - topsizer->Add(Sizer2 , 1, wxALL | wxALIGN_RIGHT, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -static CStringTable g_stringTable[] = -{ - { IDS_FILE_SIZE, L"{0} bytes" }, - { 0 , 0 } -}; - -REGISTER_DIALOG(IDD_OVERWRITE,COverwriteDialog,g_stringTable) - -BEGIN_EVENT_TABLE(COverwriteDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/Panel.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/Panel.cpp 2015-06-22 20:43:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.cpp 2024-10-08 09:00:00.000000000 +0000 @@ -1,1157 +1,1177 @@ -// Panel.cpp - -#include "StdAfx.h" - -// #include - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/Thread.h" - -#include "../../PropID.h" - -#include "resource.h" -#include "../GUI/ExtractRes.h" - -#include "../Common/ArchiveName.h" -#include "../Common/CompressCall.h" - -#include "../Agent/IFolderArchive.h" - -#include "App.h" -#include "ExtractCallback.h" -#include "FSFolder.h" -#include "FormatUtils.h" -#include "Panel.h" -#include "RootFolder.h" - -#include "PropertyNameRes.h" - -using namespace NWindows; -using namespace NControl; - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -static const UINT_PTR kTimerID = 1; -static const UINT kTimerElapse = 1000; - -// FIXME static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; - -// static const int kCreateFolderID = 101; - -extern HINSTANCE g_hInstance; -extern DWORD g_ComCtl32Version; - -void CPanel::Release() -{ - // It's for unloading COM dll's: don't change it. - CloseOpenFolders(); - // FIXME _sevenZipContextMenu.Release(); - // FIXME _systemContextMenu.Release(); -} - -CPanel::~CPanel() -{ - CloseOpenFolders(); -} - -HWND CPanel::GetParent() -{ -#ifdef _WIN32 - HWND h = CWindow2::GetParent(); - return (h == 0) ? _mainWindow : h; -#else - return 0; -#endif -} - -static LPCWSTR kClassName = L"7-Zip::Panel"; - - -HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, - const UString ¤tFolderPrefix, - const UString &arcFormat, - CPanelCallback *panelCallback, CAppState *appState, - bool &archiveIsOpened, bool &encrypted) -{ - _mainWindow = mainWindow; - _processTimer = true; - _processNotify = true; - _processStatusBar = true; - - _panelCallback = panelCallback; - _appState = appState; - // _index = index; - _baseID = id; - _comboBoxID = _baseID + 3; - _statusBarID = _comboBoxID + 1; - - UString cfp = currentFolderPrefix; - - if (!currentFolderPrefix.IsEmpty()) - if (currentFolderPrefix[0] == L'.') - { - FString cfpF; - if (NFile::NDir::MyGetFullPathName(us2fs(currentFolderPrefix), cfpF)) - cfp = fs2us(cfpF); - } - - RINOK(BindToPath(cfp, arcFormat, archiveIsOpened, encrypted)); - -#ifdef _WIN32 - if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE, - 0, 0, _xSize, 260, - parentWindow, (HMENU)(UINT_PTR)id, g_hInstance)) - return E_FAIL; -#else - { - // printf("WARNING CPanel::Create => CreateEx\n"); - // this->OnCreate(0); - extern void registerWindow2(int baseID,NWindows::NControl::CWindow2 *w); - registerWindow2(_baseID,this); - } -#endif - return S_OK; -} - -LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case kShiftSelectMessage: - OnShiftSelectMessage(); - return 0; - case kReLoadMessage: - RefreshListCtrl(_selectedState); - return 0; - case kSetFocusToListView: - _listView.SetFocus(); - return 0; - case kOpenItemChanged: - return OnOpenItemChanged(lParam); - case kRefresh_StatusBar: - if (_processStatusBar) - Refresh_StatusBar(); - return 0; -#ifdef _WIN32 - #ifdef UNDER_CE - case kRefresh_HeaderComboBox: - LoadFullPathAndShow(); - return 0; - #endif - case WM_TIMER: - OnTimer(); - return 0; - case WM_CONTEXTMENU: - if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) - return 0; - break; - /* - case WM_DROPFILES: - CompressDropFiles(HDROP(wParam)); - return 0; - */ -#endif - } - return CWindow2::OnMessage(message, wParam, lParam); -} - -LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ -#ifdef _WIN32 - if (message == WM_CHAR) - { - UINT scanCode = (UINT)((lParam >> 16) & 0xFF); - bool extended = ((lParam & 0x1000000) != 0); - UINT virtualKey = MapVirtualKey(scanCode, 1); - if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD || - virtualKey == VK_SUBTRACT) - return 0; - if ((wParam == '/' && extended) - || wParam == '\\' || wParam == '/') - { - _panel->OpenDrivesFolder(); - return 0; - } - } - else if (message == WM_SYSCHAR) - { - // For Alt+Enter Beep disabling - UINT scanCode = (UINT)(lParam >> 16) & 0xFF; - UINT virtualKey = MapVirtualKey(scanCode, 1); - if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY || - virtualKey == VK_ADD || virtualKey == VK_SUBTRACT) - return 0; - } - /* - else if (message == WM_SYSKEYDOWN) - { - // return 0; - } - */ - else if (message == WM_KEYDOWN) - { - bool alt = IsKeyDown(VK_MENU); - bool ctrl = IsKeyDown(VK_CONTROL); - bool shift = IsKeyDown(VK_SHIFT); - switch (wParam) - { - /* - case VK_RETURN: - { - if (shift && !alt && !ctrl) - { - _panel->OpenSelectedItems(false); - return 0; - } - break; - } - */ - case VK_NEXT: - { - if (ctrl && !alt && !shift) - { - _panel->OpenFocusedItemAsInternal(); - return 0; - } - break; - } - case VK_PRIOR: - if (ctrl && !alt && !shift) - { - _panel->OpenParentFolder(); - return 0; - } - } - } - #ifdef UNDER_CE - else if (message == WM_KEYUP) - { - if (wParam == VK_F2) // it's VK_TSOFT2 - { - // Activate Menu - ::PostMessage(g_HWND, WM_SYSCOMMAND, SC_KEYMENU, 0); - return 0; - } - } - #endif - else if (message == WM_SETFOCUS) - { - _panel->_lastFocusedIsList = true; - _panel->_panelCallback->PanelWasFocused(); - } -#endif - return CListView2::OnMessage(message, wParam, lParam); -} - -/* -static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - CWindow tempDialog(hwnd); - CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr()); - if (w == NULL) - return 0; - return w->OnMessage(message, wParam, lParam); -} - -LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); -} -*/ - -#ifdef _WIN32 -#ifndef UNDER_CE - -static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - CWindow tempDialog(hwnd); - CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr()); - if (w == NULL) - return 0; - return w->OnMessage(message, wParam, lParam); -} - -#endif - -LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - // See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar - switch (message) - { - case WM_SYSKEYDOWN: - switch (wParam) - { - case VK_F1: - case VK_F2: - { - // check ALT - if ((lParam & (1<<29)) == 0) - break; - bool alt = IsKeyDown(VK_MENU); - bool ctrl = IsKeyDown(VK_CONTROL); - bool shift = IsKeyDown(VK_SHIFT); - if (alt && !ctrl && !shift) - { - _panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1); - return 0; - } - break; - } - } - break; - case WM_KEYDOWN: - switch (wParam) - { - case VK_TAB: - // SendMessage(hwndMain, WM_ENTER, 0, 0); - _panel->SetFocusToList(); - return 0; - case VK_F9: - { - bool alt = IsKeyDown(VK_MENU); - bool ctrl = IsKeyDown(VK_CONTROL); - bool shift = IsKeyDown(VK_SHIFT); - if (!alt && !ctrl && !shift) - { - g_App.SwitchOnOffOnePanel();; - return 0; - } - break; - } - } - break; - case WM_CHAR: - switch (wParam) - { - case VK_TAB: - case VK_ESCAPE: - return 0; - } - } - #ifndef _UNICODE - if (g_IsNT) - return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); - else - #endif - return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); -} - -bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */) -{ - // _virtualMode = false; - // _sortIndex = 0; - _sortID = kpidName; - _ascending = true; - _lastFocusedIsList = true; - - DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS;; - - style |= LVS_SHAREIMAGELISTS; - // style |= LVS_AUTOARRANGE; - style |= WS_CLIPCHILDREN; - style |= WS_CLIPSIBLINGS; - - const UInt32 kNumListModes = ARRAY_SIZE(kStyles); - if (_ListViewMode >= kNumListModes) - _ListViewMode = kNumListModes - 1; - - style |= kStyles[_ListViewMode] - | WS_TABSTOP - | LVS_EDITLABELS; - if (_mySelectMode) - style |= LVS_SINGLESEL; - - /* - if (_virtualMode) - style |= LVS_OWNERDATA; - */ - - DWORD exStyle; - exStyle = WS_EX_CLIENTEDGE; - - if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260, - *this, (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL)) - return false; - - _listView.SetUnicodeFormat(); - _listView._panel = this; - _listView.SetWindowProc(); - - _listView.SetImageList(GetSysImageList(true), LVSIL_SMALL); - _listView.SetImageList(GetSysImageList(false), LVSIL_NORMAL); - - // _exStyle |= LVS_EX_HEADERDRAGDROP; - // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); - // extendedStyle |= _exStyle; - // _listView.SetExtendedListViewStyle(extendedStyle); - SetExtendedStyle(); - - _listView.Show(SW_SHOW); - _listView.InvalidateRect(NULL, true); - _listView.Update(); - - // Ensure that the common control DLL is loaded. - INITCOMMONCONTROLSEX icex; - - icex.dwSize = sizeof(INITCOMMONCONTROLSEX); - icex.dwICC = ICC_BAR_CLASSES; - InitCommonControlsEx(&icex); - - TBBUTTON tbb [ ] = - { - // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, - {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, - // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, - // {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, - }; - - #ifndef UNDER_CE - if (g_ComCtl32Version >= MAKELONG(71, 4)) - #endif - { - icex.dwSize = sizeof(INITCOMMONCONTROLSEX); - icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; - InitCommonControlsEx(&icex); - - // if there is no CCS_NOPARENTALIGN, there is space of some pixels after rebar (Incorrect GetWindowRect ?) - - _headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, - REBARCLASSNAME, - NULL, WS_VISIBLE | WS_BORDER | WS_CHILD | - WS_CLIPCHILDREN | WS_CLIPSIBLINGS - | CCS_NODIVIDER - | CCS_NOPARENTALIGN - | CCS_TOP - | RBS_VARHEIGHT - | RBS_BANDBORDERS - ,0,0,0,0, *this, NULL, g_hInstance, NULL)); - } - - DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ; - if (_headerReBar) - { - toolbarStyle |= 0 - // | WS_CLIPCHILDREN - // | WS_CLIPSIBLINGS - - | TBSTYLE_TOOLTIPS - | CCS_NODIVIDER - | CCS_NORESIZE - | TBSTYLE_FLAT - ; - } - - _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle, - _baseID + 2, 11, - (HINSTANCE)HINST_COMMCTRL, - IDB_VIEW_SMALL_COLOR, - (LPCTBBUTTON)&tbb, ARRAY_SIZE(tbb), - 0, 0, 0, 0, sizeof (TBBUTTON))); - - #ifndef UNDER_CE - // Load ComboBoxEx class - icex.dwSize = sizeof(INITCOMMONCONTROLSEX); - icex.dwICC = ICC_USEREX_CLASSES; - InitCommonControlsEx(&icex); - #endif - - _headerComboBox.CreateEx(0, - #ifdef UNDER_CE - WC_COMBOBOXW - #else - WC_COMBOBOXEXW - #endif - , NULL, - WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL, - 0, 0, 100, 520, - ((_headerReBar == 0) ? (HWND)*this : _headerToolBar), - (HMENU)(UINT_PTR)(_comboBoxID), - g_hInstance, NULL); - #ifndef UNDER_CE - _headerComboBox.SetUnicodeFormat(true); - - _headerComboBox.SetImageList(GetSysImageList(true)); - - _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC); - - /* - _headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox)); - _headerComboBox._panel = this; - _headerComboBox._origWindowProc = - (WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC, - LONG_PTR(ComboBoxSubclassProc)); - */ - _comboBoxEdit.Attach(_headerComboBox.GetEditControl()); - - // _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); - - _comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit)); - _comboBoxEdit._panel = this; - #ifndef _UNICODE - if (g_IsNT) - _comboBoxEdit._origWindowProc = - (WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); - else - #endif - _comboBoxEdit._origWindowProc = - (WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); - - #endif - - if (_headerReBar) - { - REBARINFO rbi; - rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. - rbi.fMask = 0; - rbi.himl = (HIMAGELIST)NULL; - _headerReBar.SetBarInfo(&rbi); - - // Send the TB_BUTTONSTRUCTSIZE message, which is required for - // backward compatibility. - // _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); - SIZE size; - _headerToolBar.GetMaxSize(&size); - - REBARBANDINFO rbBand; - rbBand.cbSize = sizeof(REBARBANDINFO); // Required - rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; - rbBand.fStyle = RBBS_NOGRIPPER; - rbBand.cxMinChild = size.cx; - rbBand.cyMinChild = size.cy; - rbBand.cyChild = size.cy; - rbBand.cx = size.cx; - rbBand.hwndChild = _headerToolBar; - _headerReBar.InsertBand(-1, &rbBand); - - RECT rc; - ::GetWindowRect(_headerComboBox, &rc); - rbBand.cxMinChild = 30; - rbBand.cyMinChild = rc.bottom - rc.top; - rbBand.cx = 1000; - rbBand.hwndChild = _headerComboBox; - _headerReBar.InsertBand(-1, &rbBand); - // _headerReBar.MaximizeBand(1, false); - } - - _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); - // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1); - - int sizes[] = {160, 250, 350, -1}; - _statusBar.SetParts(4, sizes); - // _statusBar2.SetParts(5, sizes); - - /* - RECT rect; - GetClientRect(&rect); - OnSize(0, RECT_SIZE_X(rect), RECT_SIZE_Y(rect)); - */ - - SetTimer(kTimerID, kTimerElapse); - - // InitListCtrl(); - RefreshListCtrl(); - - return true; -} -#else -bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */) -{ - printf("WARNING CPanel::OnCreate\n"); - _sortID = kpidName; - _ascending = true; - _lastFocusedIsList = true; - - extern HWND g_HWND; - HWND w = GetDlgItem(g_HWND, _comboBoxID); - if (w == 0) - { - printf("Can't find id=%d\n",_comboBoxID); - return false; - } - printf("CPanel::OnCreate : _headerComboBox.Attach(%p)\n",w); - _headerComboBox.Attach(w); - - w = GetDlgItem(g_HWND, _statusBarID); - if (w == 0) - { - printf("Can't find id=%d\n",_statusBarID); - return false; - } - printf("CPanel::OnCreate : _statusBar.Attach(%p)\n",w); - _statusBar.Attach(w); - - w = GetDlgItem(g_HWND, _baseID + 1); - if (w == 0) - { - printf("Can't find id=%d\n",_baseID + 1); - return false; - } - printf("CPanel::OnCreate : _listView.Attach(%p)\n",w); - _listView.Attach(w); - - _listView.SetUnicodeFormat(true); - - // _listView.SetUserDataLongPtr(LONG_PTR(&_listView)); - _listView._panel = this; - - // FIXME _listView.SetImageList(GetSysImageList(true), LVSIL_SMALL); - // FIXME _listView.SetImageList(GetSysImageList(false), LVSIL_NORMAL); - - // FIXME SetExtendedStyle(); - - // FIXME _listView.Show(SW_SHOW); - // FIXME _listView.InvalidateRect(NULL, true); - _listView.Update(); - - /* FIXME - _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle, - _baseID + 2, 11, - (HINSTANCE)HINST_COMMCTRL, - IDB_VIEW_SMALL_COLOR, - (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]), - 0, 0, 0, 0, sizeof (TBBUTTON))); - */ - - /* FIXME - _headerComboBox.CreateEx(0, WC_COMBOBOXEXW, NULL, - WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL, - 0, 0, 100, 520, - ((_headerReBar == 0) ? HWND(*this) : _headerToolBar), - (HMENU)(UINT_PTR)(_comboBoxID), - g_hInstance, NULL); - _headerComboBox.SendMessage(CBEM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); - - _headerComboBox.SetImageList(GetSysImageList(true)); - - _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC); - */ - - // FIXME _comboBoxEdit.Attach(_headerComboBox.GetEditControl()); - - _comboBoxEdit._panel = this; - - // FIXME if (_headerReBar) ... - - // _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); - - // int sizes[] = {150, 250, 350, -1}; - // _statusBar.SetParts(4, sizes); - - // SetTimer(kTimerID, kTimerElapse); - - // InitListCtrl(); - RefreshListCtrl(); - - return true; -} -#endif - -void CPanel::OnDestroy() -{ - SaveListViewInfo(); - CWindow2::OnDestroy(); -} - -#ifdef _WIN32 -void CPanel::ChangeWindowSize(int xSize, int ySize) -{ - if ((HWND)*this == 0) - return; - int kHeaderSize; - int kStatusBarSize; - // int kStatusBar2Size; - RECT rect; - if (_headerReBar) - _headerReBar.GetWindowRect(&rect); - else - _headerToolBar.GetWindowRect(&rect); - - kHeaderSize = RECT_SIZE_Y(rect); - - _statusBar.GetWindowRect(&rect); - kStatusBarSize = RECT_SIZE_Y(rect); - - // _statusBar2.GetWindowRect(&rect); - // kStatusBar2Size = RECT_SIZE_Y(rect); - - int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0); - const int kStartXPos = 32; - if (_headerReBar) - { - } - else - { - _headerToolBar.Move(0, 0, xSize, 0); - _headerComboBox.Move(kStartXPos, 2, - MyMax(xSize - kStartXPos - 10, kStartXPos), 0); - } - _listView.Move(0, kHeaderSize, xSize, yListViewSize); - _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize); - // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size); - // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize); - // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size); -} - -bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ - if ((HWND)*this == 0) - return true; - if (_headerReBar) - _headerReBar.Move(0, 0, xSize, 0); - ChangeWindowSize(xSize, ySize); - return true; -} - -bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */) -{ - switch (header->code) - { - case RBN_HEIGHTCHANGE: - { - RECT rect; - GetWindowRect(&rect); - ChangeWindowSize(RECT_SIZE_X(rect), RECT_SIZE_Y(rect)); - return false; - } - } - return false; -} -#endif - -bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result) -{ - if (!_processNotify) - return false; - if (header->hwndFrom == _headerComboBox) - return OnNotifyComboBox(header, result); -#ifdef _WIN32 - else if (header->hwndFrom == _headerReBar) - return OnNotifyReBar(header, result); -#endif - else if (header->hwndFrom == _listView) - return OnNotifyList(header, result); -#ifdef _WIN32 - else if (::GetParent(header->hwndFrom) == _listView && - header->code == NM_RCLICK) - return OnRightClick((MY_NMLISTVIEW_NMITEMACTIVATE *)header, result); -#endif - return false; -} - -bool CPanel::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result) -{ - printf("CPanel::OnCommand(code=%d,itemID=%d)\n",code,itemID); - if (itemID == kParentFolderID) - { - OpenParentFolder(); - result = 0; - return true; - } - /* - if (itemID == kCreateFolderID) - { - CreateFolder(); - result = 0; - return true; - } - */ - if (itemID == _comboBoxID) - { - if (OnComboBoxCommand(code, lParam, result)) - return true; - } - return CWindow2::OnCommand(code, itemID, lParam, result); -} - -void CPanel::MessageBoxInfo(LPCWSTR message, LPCWSTR caption) - { ::MessageBoxW((HWND)*this, message, caption, MB_OK); } -void CPanel::MessageBox(LPCWSTR message, LPCWSTR caption) - { ::MessageBoxW((HWND)*this, message, caption, MB_OK | MB_ICONSTOP); } -void CPanel::MessageBox(LPCWSTR message) - { MessageBox(message, L"7-Zip"); } -/* FIXME -void CPanel::MessageBoxWarning(LPCWSTR message) - { ::MessageBoxW(NULL, message, L"7-Zip", MB_OK | MB_ICONWARNING); } -*/ -void CPanel::MessageBoxMyError(LPCWSTR message) - { MessageBox(message, L"7-Zip"); } - - -void CPanel::MessageBoxError(HRESULT errorCode, LPCWSTR caption) -{ - MessageBox(HResultToMessage(errorCode), caption); -} - -void CPanel::MessageBoxError2Lines(LPCWSTR message, HRESULT errorCode) -{ - UString m = message; - if (errorCode != 0) - { - m.Add_LF(); - m += HResultToMessage(errorCode); - } - MessageBoxMyError(m); -} - -void CPanel::MessageBoxError(HRESULT errorCode) - { MessageBoxError(errorCode, L"7-Zip"); } -void CPanel::MessageBoxLastError(LPCWSTR caption) - { MessageBoxError(::GetLastError(), caption); } -void CPanel::MessageBoxLastError() - { MessageBoxLastError(L"7-Zip"); } - -void CPanel::MessageBoxErrorLang(UINT resourceID) - { MessageBox(LangString(resourceID)); } - - -void CPanel::SetFocusToList() -{ - _listView.SetFocus(); - // SetCurrentPathText(); -} - -void CPanel::SetFocusToLastRememberedItem() -{ - if (_lastFocusedIsList) - SetFocusToList(); - // FIXME else - // FIXME _headerComboBox.SetFocus(); -} - -UString CPanel::GetFolderTypeID() const -{ - { - NCOM::CPropVariant prop; - if (_folder->GetFolderProperty(kpidType, &prop) == S_OK) - if (prop.vt == VT_BSTR) - return (const wchar_t *)prop.bstrVal; - } - return UString(); -} - -bool CPanel::IsFolderTypeEqTo(const char *s) const -{ - return StringsAreEqual_Ascii(GetFolderTypeID(), s); -} - -bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo("RootFolder"); } -bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo("FSFolder"); } -bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo("FSDrives"); } -bool CPanel::IsAltStreamsFolder() const { return IsFolderTypeEqTo("AltStreamsFolder"); } -bool CPanel::IsArcFolder() const -{ - return GetFolderTypeID().IsPrefixedBy_Ascii_NoCase("7-Zip"); -} - -UString CPanel::GetFsPath() const -{ - if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix() && !IsSuperDrivesPrefix()) - return UString(); - return _currentFolderPrefix; -} - -UString CPanel::GetDriveOrNetworkPrefix() const -{ - if (!IsFSFolder()) - return UString(); - UString drive = GetFsPath(); - // FIXME drive.DeleteFrom(NFile::NName::GetRootPrefixSize(drive)); - return drive; -} - -void CPanel::SetListViewMode(UInt32 index) -{ - if (index >= 4) - return; - _ListViewMode = index; -#ifdef _WIN32 - DWORD oldStyle = (DWORD)_listView.GetStyle(); - DWORD newStyle = kStyles[index]; - - // DWORD tickCount1 = GetTickCount(); - if ((oldStyle & LVS_TYPEMASK) != newStyle) - _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle); - // RefreshListCtrlSaveFocused(); - /* - DWORD tickCount2 = GetTickCount(); - char s[256]; - sprintf(s, "SetStyle = %5d", - tickCount2 - tickCount1 - ); - OutputDebugStringA(s); - */ -#endif -} - -void CPanel::ChangeFlatMode() -{ - _flatMode = !_flatMode; - if (_parentFolders.Size() > 0) - _flatModeForArc = _flatMode; - else - _flatModeForDisk = _flatMode; - RefreshListCtrlSaveFocused(); -} - -/* -void CPanel::Change_ShowNtfsStrems_Mode() -{ - _showNtfsStrems_Mode = !_showNtfsStrems_Mode; - if (_parentFolders.Size() > 0) - _showNtfsStrems_ModeForArc = _showNtfsStrems_Mode; - else - _showNtfsStrems_ModeForDisk = _showNtfsStrems_Mode; - RefreshListCtrlSaveFocused(); -} -*/ - -void CPanel::Post_Refresh_StatusBar() -{ - // FIXME if (_processStatusBar) - // FIXME PostMessage(kRefresh_StatusBar); -} - -void CPanel::AddToArchive() -{ - CRecordVector indices; - GetOperatedItemIndices(indices); - if (!Is_IO_FS_Folder()) - { - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - if (indices.Size() == 0) - { - MessageBoxErrorLang(IDS_SELECT_FILES); - return; - } - UStringVector names; - - const UString curPrefix = GetFsPath(); - UString destCurDirPrefix = curPrefix; - if (IsFSDrivesFolder()) - destCurDirPrefix = ROOT_FS_FOLDER; - - FOR_VECTOR (i, indices) - names.Add(curPrefix + GetItemRelPath2(indices[i])); - bool fromPrev = (names.Size() > 1); - const UString arcName = CreateArchiveName(names.Front(), fromPrev, false); - HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"", - true, // addExtension - names, false, true, false); - if (res != S_OK) - { - if (destCurDirPrefix.Len() >= MAX_PATH) - MessageBoxErrorLang(IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER); - } - // KillSelection(); -} - -static UString GetSubFolderNameForExtract(const UString &arcPath) -{ - UString s = arcPath; - int slashPos = s.ReverseFind_PathSepar(); - int dotPos = s.ReverseFind_Dot(); - if (dotPos <= slashPos + 1) - s += L'~'; - else - { - s.DeleteFrom(dotPos); - s.TrimRight(); - } - return s; -} - -void CPanel::GetFilePaths(const CRecordVector &indices, UStringVector &paths, bool allowFolders) -{ - const UString prefix = GetFsPath(); - FOR_VECTOR (i, indices) - { - int index = indices[i]; - if (!allowFolders && IsItem_Folder(index)) - { - paths.Clear(); - break; - } - paths.Add(prefix + GetItemRelPath2(index)); - } - if (paths.Size() == 0) - { - MessageBoxErrorLang(IDS_SELECT_FILES); - return; - } -} - -void CPanel::ExtractArchives() -{ - if (_parentFolders.Size() > 0) - { - _panelCallback->OnCopy(false, false); - return; - } - CRecordVector indices; - GetOperatedItemIndices(indices); - UStringVector paths; - GetFilePaths(indices, paths); - if (paths.IsEmpty()) - return; - - UString outFolder = GetFsPath(); - if (indices.Size() == 1) - outFolder += GetSubFolderNameForExtract(GetItemRelPath(indices[0])); - else - outFolder += L'*'; - outFolder.Add_PathSepar(); - - ::ExtractArchives(paths, outFolder - , true // showDialog - , false // elimDup - ); -} - -/* -static void AddValuePair(UINT resourceID, UInt64 value, UString &s) -{ - AddLangString(s, resourceID); - char sz[32]; - s += L": "; - ConvertUInt64ToString(value, sz); - s.AddAsciiStr(sz); - s.Add_LF(); -} -*/ - -class CThreadTest: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - CRecordVector Indices; - CExtractCallbackImp *ExtractCallbackSpec; - CMyComPtr ExtractCallback; - CMyComPtr ArchiveFolder; -}; - -// actually now we don't need CThreadTest, since now we call CopyTo for "test command - -/* -HRESULT CThreadTest::ProcessVirt() -{ - RINOK(ArchiveFolder->Extract(&Indices[0], Indices.Size(), - true, // includeAltStreams - false, // replaceAltStreamColon - NExtract::NPathMode::kFullPathnames, - NExtract::NOverwriteMode::kAskBefore, - NULL, // path - BoolToInt(true), // testMode - ExtractCallback)); - if (ExtractCallbackSpec->IsOK()) - { - UString s; - AddValuePair(IDS_PROP_FOLDERS, ExtractCallbackSpec->NumFolders, s); - AddValuePair(IDS_PROP_FILES, ExtractCallbackSpec->NumFiles, s); - // AddValuePair(IDS_PROP_SIZE, ExtractCallbackSpec->UnpackSize, s); - // AddSizePair(IDS_COMPRESSED_COLON, Stat.PackSize, s); - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - FinalMessage.OkMessage.Message = s; - } - return S_OK; -} -*/ - -/* -static void AddSizePair(UInt32 langID, UInt64 value, UString &s) -{ - char sz[32]; - AddLangString(s, langID); - s += L' '; - ConvertUInt64ToString(value, sz); - s.AddAsciiStr(sz); - ConvertUInt64ToString(value >> 20, sz); - s.AddAsciiStr(" ("); - s.AddAsciiStr(sz); - s.AddAsciiStr(" MB)"); - s.Add_LF(); -} -*/ - -void CPanel::TestArchives() -{ - CRecordVector indices; - GetOperatedIndicesSmart(indices); - CMyComPtr archiveFolder; - _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); - if (archiveFolder) - { - CCopyToOptions options; - options.streamMode = true; - options.showErrorMessages = true; - options.testMode = true; - - UStringVector messages; - HRESULT res = CopyTo(options, indices, &messages); - if (res != S_OK) - { - if (res != E_ABORT) - MessageBoxError(res); - } - return; - - /* - { - CThreadTest extracter; - - extracter.ArchiveFolder = archiveFolder; - extracter.ExtractCallbackSpec = new CExtractCallbackImp; - extracter.ExtractCallback = extracter.ExtractCallbackSpec; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; - if (!_parentFolders.IsEmpty()) - { - const CFolderLink &fl = _parentFolders.Back(); - extracter.ExtractCallbackSpec->PasswordIsDefined = fl.UsePassword; - extracter.ExtractCallbackSpec->Password = fl.Password; - } - - if (indices.IsEmpty()) - return; - - extracter.Indices = indices; - - UString title = LangString(IDS_PROGRESS_TESTING); - UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - - extracter.ProgressDialog.CompressingMode = false; - extracter.ProgressDialog.MainWindow = GetParent(); - extracter.ProgressDialog.MainTitle = progressWindowTitle; - extracter.ProgressDialog.MainAddTitle = title + L' '; - - extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; - extracter.ExtractCallbackSpec->Init(); - - if (extracter.Create(title, GetParent()) != S_OK) - return; - - } - RefreshTitleAlways(); - return; - */ - } - - if (!IsFSFolder()) - { - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - UStringVector paths; - GetFilePaths(indices, paths, true); - if (paths.IsEmpty()) - return; - ::TestArchives(paths); -} +// Panel.cpp + +#include "StdAfx.h" + +#include + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/Thread.h" + +#include "../../PropID.h" + +#include "resource.h" +#include "../GUI/ExtractRes.h" + +#include "../Common/ArchiveName.h" +#include "../Common/CompressCall.h" +#include "../Common/ZipRegistry.h" + +#include "../Agent/IFolderArchive.h" + +#include "App.h" +#include "ExtractCallback.h" +#include "FSFolder.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "Panel.h" +#include "RootFolder.h" + +#include "PropertyNameRes.h" + +using namespace NWindows; +using namespace NControl; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static const UINT_PTR kTimerID = 1; +static const UINT kTimerElapse = 1000; + +static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; + +// static const int kCreateFolderID = 101; + +extern HINSTANCE g_hInstance; + +void CPanel::ReleasePanel() +{ + Disable_Processing_Timer_Notify_StatusBar(); + // It's for unloading COM dll's: don't change it. + CloseOpenFolders(); + _sevenZipContextMenu.Release(); + _systemContextMenu.Release(); +} + +CPanel::~CPanel() +{ + CloseOpenFolders(); +} + +HWND CPanel::GetParent() const +{ + const HWND h = CWindow2::GetParent(); + return h ? h : _mainWindow; +} + +#define kClassName L"7-Zip::Panel" + + +HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, + const UString ¤tFolderPrefix, + const UString &arcFormat, + CPanelCallback *panelCallback, CAppState *appState, + bool needOpenArc, + COpenResult &openRes) +{ + _mainWindow = mainWindow; + _processTimer = true; + _processNotify = true; + _processStatusBar = true; + + _panelCallback = panelCallback; + _appState = appState; + // _index = index; + _baseID = id; + _comboBoxID = _baseID + 3; + _statusBarID = _comboBoxID + 1; + + UString cfp = currentFolderPrefix; + + if (!currentFolderPrefix.IsEmpty()) + if (currentFolderPrefix[0] == L'.') + { + FString cfpF; + if (NFile::NDir::MyGetFullPathName(us2fs(currentFolderPrefix), cfpF)) + cfp = fs2us(cfpF); + } + + RINOK(BindToPath(cfp, arcFormat, openRes)) + + if (needOpenArc && !openRes.ArchiveIsOpened) + return S_OK; + + if (!CreateEx(0, kClassName, NULL, WS_CHILD | WS_VISIBLE, + 0, 0, _xSize, 260, + parentWindow, (HMENU)(UINT_PTR)id, g_hInstance)) + return E_FAIL; + PanelCreated = true; + + return S_OK; +} + +// extern UInt32 g_NumMessages; + +LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + // g_NumMessages++; + switch (message) + { + case kShiftSelectMessage: + OnShiftSelectMessage(); + return 0; + case kReLoadMessage: + RefreshListCtrl(_selectedState); + return 0; + case kSetFocusToListView: + _listView.SetFocus(); + return 0; + case kOpenItemChanged: + return OnOpenItemChanged(lParam); + case kRefresh_StatusBar: + if (_processStatusBar) + Refresh_StatusBar(); + return 0; + #ifdef UNDER_CE + case kRefresh_HeaderComboBox: + LoadFullPathAndShow(); + return 0; + #endif + case WM_TIMER: + OnTimer(); + return 0; + case WM_CONTEXTMENU: + if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) + return 0; + break; + /* + case WM_DROPFILES: + CompressDropFiles(HDROP(wParam)); + return 0; + */ + } + return CWindow2::OnMessage(message, wParam, lParam); +} + +LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_CHAR) + { + UINT scanCode = (UINT)((lParam >> 16) & 0xFF); + bool extended = ((lParam & 0x1000000) != 0); + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD || + virtualKey == VK_SUBTRACT) + return 0; + if ((wParam == '/' && extended) + || wParam == '\\' || wParam == '/') + { + _panel->OpenDrivesFolder(); + return 0; + } + } + else if (message == WM_SYSCHAR) + { + // For Alt+Enter Beep disabling + UINT scanCode = (UINT)(lParam >> 16) & 0xFF; + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY || + virtualKey == VK_ADD || virtualKey == VK_SUBTRACT) + return 0; + } + /* + else if (message == WM_SYSKEYDOWN) + { + // return 0; + } + */ + else if (message == WM_KEYDOWN) + { + bool alt = IsKeyDown(VK_MENU); + bool ctrl = IsKeyDown(VK_CONTROL); + bool shift = IsKeyDown(VK_SHIFT); + switch (wParam) + { + /* + case VK_RETURN: + { + if (shift && !alt && !ctrl) + { + _panel->OpenSelectedItems(false); + return 0; + } + break; + } + */ + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + _panel->OpenFocusedItemAsInternal(); + return 0; + } + break; + } + case VK_PRIOR: + if (ctrl && !alt && !shift) + { + _panel->OpenParentFolder(); + return 0; + } + } + } + #ifdef UNDER_CE + else if (message == WM_KEYUP) + { + if (wParam == VK_F2) // it's VK_TSOFT2 + { + // Activate Menu + ::PostMessage(g_HWND, WM_SYSCOMMAND, SC_KEYMENU, 0); + return 0; + } + } + #endif + else if (message == WM_SETFOCUS) + { + _panel->_lastFocusedIsList = true; + _panel->_panelCallback->PanelWasFocused(); + } + return CListView2::OnMessage(message, wParam, lParam); +} + +/* +static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} +*/ + +#ifndef UNDER_CE + +static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +#endif + +LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + // See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar + switch (message) + { + case WM_SYSKEYDOWN: + switch (wParam) + { + case VK_F1: + case VK_F2: + { + // check ALT + if ((lParam & (1<<29)) == 0) + break; + bool alt = IsKeyDown(VK_MENU); + bool ctrl = IsKeyDown(VK_CONTROL); + bool shift = IsKeyDown(VK_SHIFT); + if (alt && !ctrl && !shift) + { + _panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1); + return 0; + } + break; + } + } + break; + case WM_KEYDOWN: + switch (wParam) + { + case VK_TAB: + // SendMessage(hwndMain, WM_ENTER, 0, 0); + _panel->SetFocusToList(); + return 0; + case VK_F9: + { + bool alt = IsKeyDown(VK_MENU); + bool ctrl = IsKeyDown(VK_CONTROL); + bool shift = IsKeyDown(VK_SHIFT); + if (!alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel(); + return 0; + } + break; + } + case 'W': + { + bool ctrl = IsKeyDown(VK_CONTROL); + if (ctrl) + { + PostMessage(g_HWND, WM_COMMAND, IDCLOSE, 0); + return 0; + } + break; + } + } + break; + case WM_CHAR: + switch (wParam) + { + case VK_TAB: + case VK_ESCAPE: + return 0; + } + } + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + + +/* + REBARBANDINFO in vista (_WIN32_WINNT >= 0x0600) has additional fields + we want 2000/xp compatibility. + so we must use reduced structure, if we compile with (_WIN32_WINNT >= 0x0600) + Also there are additional fields, if (_WIN32_IE >= 0x0400). + but (_WIN32_IE >= 0x0400) is expected. + note: + in x64 (64-bit): + { + (108 == REBARBANDINFO_V6_SIZE) + (112 == sizeof(REBARBANDINFO) // for (_WIN32_WINNT < 0x0600) + (128 == sizeof(REBARBANDINFO) // for (_WIN32_WINNT >= 0x0600) + there is difference in sizes, because REBARBANDINFO size was + not aligned for 8-bytes in (_WIN32_WINNT < 0x0600). + We hope that WinVista+ support support both (108 and 112) sizes. + But does WinXP-x64 support (108 == REBARBANDINFO_V6_SIZE)? + { + 96 LPARAM lParam; + 104 UINT cxHeader; + #if (_WIN32_WINNT >= 0x0600) + 108 RECT rcChevronLocation; + 124 UINT uChevronState; + #endif + } +*/ + +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) && defined(REBARBANDINFOA_V6_SIZE) + #define my_compatib_REBARBANDINFO_size REBARBANDINFO_V6_SIZE +#else + #define my_compatib_REBARBANDINFO_size sizeof(REBARBANDINFO) +#endif + + +bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */) +{ + // _virtualMode = false; + // _sortIndex = 0; + _sortID = kpidName; + _ascending = true; + _lastFocusedIsList = true; + + DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS; + + style |= LVS_SHAREIMAGELISTS; + // style |= LVS_AUTOARRANGE; + style |= WS_CLIPCHILDREN; + style |= WS_CLIPSIBLINGS; + + const UInt32 kNumListModes = Z7_ARRAY_SIZE(kStyles); + if (_listViewMode >= kNumListModes) + _listViewMode = kNumListModes - 1; + + style |= kStyles[_listViewMode] + | WS_TABSTOP + | LVS_EDITLABELS; + if (_mySelectMode) + style |= LVS_SINGLESEL; + + /* + if (_virtualMode) + style |= LVS_OWNERDATA; + */ + + DWORD exStyle; + exStyle = WS_EX_CLIENTEDGE; + + if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260, + *this, (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL)) + return false; + + _listView.SetUnicodeFormat(); + _listView._panel = this; + _listView.SetWindowProc(); + + _listView.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL); + _listView.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL); + + // _exStyle |= LVS_EX_HEADERDRAGDROP; + // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); + // extendedStyle |= _exStyle; + // _listView.SetExtendedListViewStyle(extendedStyle); + SetExtendedStyle(); + + _listView.Show(SW_SHOW); + _listView.InvalidateRect(NULL, true); + _listView.Update(); + + // Ensure that the common control DLL is loaded. + INITCOMMONCONTROLSEX icex; + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + const TBBUTTON tbb[] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, { 0, 0 }, 0, 0 }, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + +#ifdef Z7_USE_DYN_ComCtl32Version + if (g_ComCtl32Version >= MAKELONG(71, 4)) +#endif + { + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + // if there is no CCS_NOPARENTALIGN, there is space of some pixels after rebar (Incorrect GetWindowRect ?) + + _headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, WS_VISIBLE | WS_BORDER | WS_CHILD | + WS_CLIPCHILDREN | WS_CLIPSIBLINGS + | CCS_NODIVIDER + | CCS_NOPARENTALIGN + | CCS_TOP + | RBS_VARHEIGHT + | RBS_BANDBORDERS + ,0,0,0,0, *this, NULL, g_hInstance, NULL)); + } + + DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ; + if (_headerReBar) + { + toolbarStyle |= 0 + // | WS_CLIPCHILDREN + // | WS_CLIPSIBLINGS + + | TBSTYLE_TOOLTIPS + | CCS_NODIVIDER + | CCS_NORESIZE + | TBSTYLE_FLAT + ; + } + + _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle, + _baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, + IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, Z7_ARRAY_SIZE(tbb), + 0, 0, 0, 0, sizeof (TBBUTTON))); + + #ifndef UNDER_CE + // Load ComboBoxEx class + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icex); + #endif + + _headerComboBox.CreateEx(0, + #ifdef UNDER_CE + WC_COMBOBOXW + #else + WC_COMBOBOXEXW + #endif + , NULL, + WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL, + 0, 0, 100, 620, + (_headerReBar ? _headerToolBar : (HWND)*this), + (HMENU)(UINT_PTR)(_comboBoxID), + g_hInstance, NULL); + +#ifndef UNDER_CE + _headerComboBox.SetUnicodeFormat(true); + _headerComboBox.SetImageList(Shell_Get_SysImageList_smallIcons(true)); + _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC); + /* + _headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox)); + _headerComboBox._panel = this; + _headerComboBox._origWindowProc = + (WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC, + LONG_PTR(ComboBoxSubclassProc)); + */ + _comboBoxEdit.Attach(_headerComboBox.GetEditControl()); + // _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); + _comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit)); + _comboBoxEdit._panel = this; + #ifndef _UNICODE + if (g_IsNT) + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); + else + #endif + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); +#endif + + if (_headerReBar) + { + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + _headerReBar.SetBarInfo(&rbi); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + // _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + SIZE size; + _headerToolBar.GetMaxSize(&size); + + REBARBANDINFO rbBand; + memset(&rbBand, 0, sizeof(rbBand)); + // rbBand.cbSize = sizeof(rbBand); // for debug + // rbBand.cbSize = REBARBANDINFO_V3_SIZE; // for debug + rbBand.cbSize = my_compatib_REBARBANDINFO_size; + rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + rbBand.fStyle = RBBS_NOGRIPPER; + rbBand.cxMinChild = (UINT)size.cx; + rbBand.cyMinChild = (UINT)size.cy; + rbBand.cyChild = (UINT)size.cy; + rbBand.cx = (UINT)size.cx; + rbBand.hwndChild = _headerToolBar; + _headerReBar.InsertBand(-1, &rbBand); + + RECT rc; + ::GetWindowRect(_headerComboBox, &rc); + rbBand.cxMinChild = 30; + rbBand.cyMinChild = (UINT)(rc.bottom - rc.top); + rbBand.cx = 1000; + rbBand.hwndChild = _headerComboBox; + _headerReBar.InsertBand(-1, &rbBand); + // _headerReBar.MaximizeBand(1, false); + } + + _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); + // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1); + + const int sizes[] = {220, 320, 420, -1}; + _statusBar.SetParts(4, sizes); + // _statusBar2.SetParts(5, sizes); + + /* + RECT rect; + GetClientRect(&rect); + OnSize(0, RECT_SIZE_X(rect), RECT_SIZE_Y(rect)); + */ + + SetTimer(kTimerID, kTimerElapse); + + // InitListCtrl(); + RefreshListCtrl(); + + return true; +} + +void CPanel::OnDestroy() +{ + SaveListViewInfo(); + CWindow2::OnDestroy(); +} + +void CPanel::ChangeWindowSize(int xSize, int ySize) +{ + if (!(HWND)*this) + return; + int kHeaderSize; + int kStatusBarSize; + // int kStatusBar2Size; + RECT rect; + if (_headerReBar) + _headerReBar.GetWindowRect(&rect); + else + _headerToolBar.GetWindowRect(&rect); + + kHeaderSize = RECT_SIZE_Y(rect); + + _statusBar.GetWindowRect(&rect); + kStatusBarSize = RECT_SIZE_Y(rect); + + // _statusBar2.GetWindowRect(&rect); + // kStatusBar2Size = RECT_SIZE_Y(rect); + + int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0); + const int kStartXPos = 32; + if (_headerReBar) + { + } + else + { + _headerToolBar.Move(0, 0, xSize, 0); + _headerComboBox.Move(kStartXPos, 2, + MyMax(xSize - kStartXPos - 10, kStartXPos), 0); + } + _listView.Move(0, kHeaderSize, xSize, yListViewSize); + _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size); + // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size); +} + +bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + if (!(HWND)*this) + return true; + if (_headerReBar) + _headerReBar.Move(0, 0, xSize, 0); + ChangeWindowSize(xSize, ySize); + return true; +} + +bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */) +{ + switch (header->code) + { + case RBN_HEIGHTCHANGE: + { + RECT rect; + GetWindowRect(&rect); + ChangeWindowSize(RECT_SIZE_X(rect), RECT_SIZE_Y(rect)); + return false; + } + } + return false; +} + +/* +UInt32 g_OnNotify = 0; +UInt32 g_LVIF_TEXT = 0; +UInt32 g_Time = 0; + +void Print_OnNotify(const char *name) +{ + char s[256]; + DWORD tim = GetTickCount(); + sprintf(s, + "Time = %7u ms, Notify = %9u, TEXT = %9u, %s", + tim - g_Time, + g_OnNotify, + g_LVIF_TEXT, + name); + g_Time = tim; + OutputDebugStringA(s); + g_OnNotify = 0; + g_LVIF_TEXT = 0; +} +*/ + +bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result) +{ + /* + g_OnNotify++; + + if (header->hwndFrom == _listView) + { + if (header->code == LVN_GETDISPINFOW) + { + LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header; + if ((dispInfo->item.mask & LVIF_TEXT)) + g_LVIF_TEXT++; + } + } + */ + + if (!_processNotify) + return false; + + if (header->hwndFrom == _headerComboBox) + return OnNotifyComboBox(header, result); + else if (header->hwndFrom == _headerReBar) + return OnNotifyReBar(header, result); + else if (header->hwndFrom == _listView) + return OnNotifyList(header, result); + else if (::GetParent(header->hwndFrom) == _listView) + { + // NMHDR:code is UINT + // NM_RCLICK is unsigned in windows sdk + // NM_RCLICK is int in MinGW + if (header->code == (UINT)NM_RCLICK) + return OnRightClick((MY_NMLISTVIEW_NMITEMACTIVATE *)header, result); + } + return false; +} + +bool CPanel::OnCommand(unsigned code, unsigned itemID, LPARAM lParam, LRESULT &result) +{ + if (itemID == kParentFolderID) + { + OpenParentFolder(); + result = 0; + return true; + } + /* + if (itemID == kCreateFolderID) + { + CreateFolder(); + result = 0; + return true; + } + */ + if (itemID == _comboBoxID) + { + if (OnComboBoxCommand(code, lParam, result)) + return true; + } + return CWindow2::OnCommand(code, itemID, lParam, result); +} + + + +/* +void CPanel::MessageBox_Info(LPCWSTR message, LPCWSTR caption) const + { ::MessageBoxW((HWND)*this, message, caption, MB_OK); } +void CPanel::MessageBox_Warning(LPCWSTR message) const + { ::MessageBoxW((HWND)*this, message, L"7-Zip", MB_OK | MB_ICONWARNING); } +*/ + +void CPanel::MessageBox_Error_Caption(LPCWSTR message, LPCWSTR caption) const + { ::MessageBoxW((HWND)*this, message, caption, MB_OK | MB_ICONSTOP); } + +void CPanel::MessageBox_Error(LPCWSTR message) const + { MessageBox_Error_Caption(message, L"7-Zip"); } + +static UString ErrorHResult_To_Message(HRESULT errorCode) +{ + if (errorCode == 0) + errorCode = E_FAIL; + return HResultToMessage(errorCode); +} + +void CPanel::MessageBox_Error_HRESULT_Caption(HRESULT errorCode, LPCWSTR caption) const +{ + MessageBox_Error_Caption(ErrorHResult_To_Message(errorCode), caption); +} + +void CPanel::MessageBox_Error_HRESULT(HRESULT errorCode) const + { MessageBox_Error_HRESULT_Caption(errorCode, L"7-Zip"); } + +void CPanel::MessageBox_Error_2Lines_Message_HRESULT(LPCWSTR message, HRESULT errorCode) const +{ + UString m = message; + m.Add_LF(); + m += ErrorHResult_To_Message(errorCode); + MessageBox_Error(m); +} + +void CPanel::MessageBox_LastError(LPCWSTR caption) const + { MessageBox_Error_HRESULT_Caption(GetLastError_noZero_HRESULT(), caption); } + +void CPanel::MessageBox_LastError() const + { MessageBox_LastError(L"7-Zip"); } + +void CPanel::MessageBox_Error_LangID(UINT resourceID) const + { MessageBox_Error(LangString(resourceID)); } + +void CPanel::MessageBox_Error_UnsupportOperation() const + { MessageBox_Error_LangID(IDS_OPERATION_IS_NOT_SUPPORTED); } + + + + +void CPanel::SetFocusToList() +{ + _listView.SetFocus(); + // SetCurrentPathText(); +} + +void CPanel::SetFocusToLastRememberedItem() +{ + if (_lastFocusedIsList) + SetFocusToList(); + else + _headerComboBox.SetFocus(); +} + +UString CPanel::GetFolderTypeID() const +{ + { + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidType, &prop) == S_OK) + if (prop.vt == VT_BSTR) + return (const wchar_t *)prop.bstrVal; + } + return UString(); +} + +bool CPanel::IsFolderTypeEqTo(const char *s) const +{ + return StringsAreEqual_Ascii(GetFolderTypeID(), s); +} + +bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo("RootFolder"); } +bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo("FSFolder"); } +bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo("FSDrives"); } +bool CPanel::IsAltStreamsFolder() const { return IsFolderTypeEqTo("AltStreamsFolder"); } +bool CPanel::IsArcFolder() const +{ + return GetFolderTypeID().IsPrefixedBy_Ascii_NoCase("7-Zip"); +} + +bool CPanel::IsHashFolder() const +{ + if (_folder) + { + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidIsHash, &prop) == S_OK) + if (prop.vt == VT_BOOL) + return VARIANT_BOOLToBool(prop.boolVal); + } + return false; +} + +UString CPanel::GetFsPath() const +{ + if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix() && !IsSuperDrivesPrefix()) + return UString(); + return _currentFolderPrefix; +} + +UString CPanel::GetDriveOrNetworkPrefix() const +{ + if (!IsFSFolder()) + return UString(); + UString drive = GetFsPath(); + drive.DeleteFrom(NFile::NName::GetRootPrefixSize(drive)); + return drive; +} + +void CPanel::SetListViewMode(UInt32 index) +{ + if (index >= 4) + return; + _listViewMode = index; + const LONG_PTR oldStyle = _listView.GetStyle(); + const DWORD newStyle = kStyles[index]; + + // DWORD tickCount1 = GetTickCount(); + if ((oldStyle & LVS_TYPEMASK) != (LONG_PTR)newStyle) + _listView.SetStyle((oldStyle & ~(LONG_PTR)(DWORD)LVS_TYPEMASK) | (LONG_PTR)newStyle); + // RefreshListCtrlSaveFocused(); + /* + DWORD tickCount2 = GetTickCount(); + char s[256]; + sprintf(s, "SetStyle = %5d", + tickCount2 - tickCount1 + ); + OutputDebugStringA(s); + */ + +} + +void CPanel::ChangeFlatMode() +{ + _flatMode = !_flatMode; + if (!_parentFolders.IsEmpty()) + _flatModeForArc = _flatMode; + else + _flatModeForDisk = _flatMode; + RefreshListCtrl_SaveFocused(); +} + +/* +void CPanel::Change_ShowNtfsStrems_Mode() +{ + _showNtfsStrems_Mode = !_showNtfsStrems_Mode; + if (!_parentFolders.IsEmpty()) + _showNtfsStrems_ModeForArc = _showNtfsStrems_Mode; + else + _showNtfsStrems_ModeForDisk = _showNtfsStrems_Mode; + RefreshListCtrlSaveFocused(); +} +*/ + +void CPanel::Post_Refresh_StatusBar() +{ + if (_processStatusBar) + PostMsg(kRefresh_StatusBar); +} + +void CPanel::AddToArchive() +{ + if (!Is_IO_FS_Folder()) + { + MessageBox_Error_UnsupportOperation(); + return; + } + CRecordVector indices; + Get_ItemIndices_Operated(indices); + if (indices.Size() == 0) + { + MessageBox_Error_LangID(IDS_SELECT_FILES); + return; + } + UString destCurDirPrefix = GetFsPath(); + if (IsFSDrivesFolder()) + destCurDirPrefix = ROOT_FS_FOLDER; + UStringVector names; + GetFilePaths(indices, names); + UString baseName; + const UString arcName = CreateArchiveName(names, + false, // isHash + NULL, // CFileInfo *fi + baseName); + const HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"", + true, // addExtension + names, + false, // email + true, // showDialog + false); // waitFinish + if (res != S_OK) + { + if (destCurDirPrefix.Len() >= MAX_PATH) + MessageBox_Error_LangID(IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER); + } + // KillSelection(); +} + +// function from ContextMenu.cpp +UString GetSubFolderNameForExtract(const UString &arcPath); + +static UString GetSubFolderNameForExtract2(const UString &arcPath) +{ + int slashPos = arcPath.ReverseFind_PathSepar(); + UString s; + UString name = arcPath; + if (slashPos >= 0) + { + s = arcPath.Left((unsigned)(slashPos + 1)); + name = arcPath.Ptr((unsigned)(slashPos + 1)); + } + s += GetSubFolderNameForExtract(name); + return s; +} + + +int CPanel::FindDir_InOperatedList(const CRecordVector &operatedIndices) const +{ + const bool *isDirVector = _isDirVector.ConstData(); + const UInt32 *indices = operatedIndices.ConstData(); + const unsigned numItems = operatedIndices.Size(); + for (unsigned i = 0; i < numItems; i++) + if (isDirVector[indices[i]]) + return (int)i; + return -1; +} + + +void CPanel::GetFilePaths(const CRecordVector &operatedIndices, UStringVector &paths) const +{ + paths.ClearAndReserve(operatedIndices.Size()); + UString path = GetFsPath(); + const unsigned prefixLen = path.Len(); + const UInt32 *indices = operatedIndices.ConstData(); + const unsigned numItems = operatedIndices.Size(); + // for (unsigned y = 0; y < 10000; y++, paths.Clear()) + for (unsigned i = 0; i < numItems; i++) + { + path.DeleteFrom(prefixLen); + Add_ItemRelPath2_To_String(indices[i], path); + // ODS_U(path) + paths.AddInReserved(path); + } +} + + +void CPanel::ExtractArchives() +{ + if (!_parentFolders.IsEmpty()) + { + _panelCallback->OnCopy(false, false); + return; + } + CRecordVector indices; + Get_ItemIndices_Operated(indices); + if (indices.IsEmpty() || FindDir_InOperatedList(indices) != -1) + { + MessageBox_Error_LangID(IDS_SELECT_FILES); + return; + } + UStringVector paths; + GetFilePaths(indices, paths); + UString outFolder = GetFsPath(); + if (indices.Size() == 1) + outFolder += GetSubFolderNameForExtract2(GetItemRelPath(indices[0])); + else + outFolder.Add_Char('*'); + outFolder.Add_PathSepar(); + + CContextMenuInfo ci; + ci.Load(); + + ::ExtractArchives(paths, outFolder + , true // showDialog + , false // elimDup + , ci.WriteZone + ); +} + +/* +static void AddValuePair(UINT resourceID, UInt64 value, UString &s) +{ + AddLangString(s, resourceID); + char sz[32]; + s += ": "; + ConvertUInt64ToString(value, sz); + s += sz; + s.Add_LF(); +} + +// now we don't need CThreadTest, since now we call CopyTo for "test command + +class CThreadTest: public CProgressThreadVirt +{ + HRESULT ProcessVirt(); +public: + CRecordVector Indices; + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + CMyComPtr ArchiveFolder; +}; + +HRESULT CThreadTest::ProcessVirt() +{ + RINOK(ArchiveFolder->Extract(&Indices[0], Indices.Size(), + true, // includeAltStreams + false, // replaceAltStreamColon + NExtract::NPathMode::kFullPathnames, + NExtract::NOverwriteMode::kAskBefore, + NULL, // path + BoolToInt(true), // testMode + ExtractCallback)); + if (ExtractCallbackSpec->IsOK()) + { + UString s; + AddValuePair(IDS_PROP_FOLDERS, ExtractCallbackSpec->NumFolders, s); + AddValuePair(IDS_PROP_FILES, ExtractCallbackSpec->NumFiles, s); + // AddValuePair(IDS_PROP_SIZE, ExtractCallbackSpec->UnpackSize, s); + // AddSizePair(IDS_COMPRESSED_COLON, Stat.PackSize, s); + s.Add_LF(); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + FinalMessage.OkMessage.Message = s; + } + return S_OK; +} + +static void AddSizePair(UInt32 langID, UInt64 value, UString &s) +{ + char sz[32]; + AddLangString(s, langID); + s += L' '; + ConvertUInt64ToString(value, sz); + s += sz; + ConvertUInt64ToString(value >> 20, sz); + s += " ("; + s += sz; + s += " MB)"; + s.Add_LF(); +} +*/ + +void CPanel::TestArchives() +{ + CRecordVector indices; + Get_ItemIndices_OperSmart(indices); + CMyComPtr archiveFolder; + _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); + if (archiveFolder) + { + CCopyToOptions options; + options.streamMode = true; + options.showErrorMessages = true; + options.testMode = true; + + UStringVector messages; + HRESULT res = CopyTo(options, indices, &messages); + if (res != S_OK) + { + if (res != E_ABORT) + MessageBox_Error_HRESULT(res); + } + return; + + /* + { + CThreadTest extracter; + + extracter.ArchiveFolder = archiveFolder; + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &fl = _parentFolders.Back(); + extracter.ExtractCallbackSpec->PasswordIsDefined = fl.UsePassword; + extracter.ExtractCallbackSpec->Password = fl.Password; + } + + if (indices.IsEmpty()) + return; + + extracter.Indices = indices; + + const UString title = LangString(IDS_PROGRESS_TESTING); + + extracter.ProgressDialog.CompressingMode = false; + extracter.ProgressDialog.MainWindow = GetParent(); + extracter.ProgressDialog.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + extracter.ProgressDialog.MainAddTitle = title + L' '; + + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + extracter.ExtractCallbackSpec->Init(); + + if (extracter.Create(title, GetParent()) != S_OK) + return; + + } + RefreshTitleAlways(); + return; + */ + } + + if (!IsFSFolder()) + { + MessageBox_Error_UnsupportOperation(); + return; + } + UStringVector paths; + GetFilePaths(indices, paths); + if (paths.IsEmpty()) + { + MessageBox_Error_LangID(IDS_SELECT_FILES); + return; + } + ::TestArchives(paths); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/Panel.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/Panel.h 2015-09-19 18:02:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Panel.h 2025-06-16 06:00:00.000000000 +0000 @@ -1,801 +1,1020 @@ -// Panel.h - -#ifndef __PANEL_H -#define __PANEL_H - -#include "../../../../C/Alloc.h" - -#include "../../../Common/Defs.h" -#include "../../../Common/MyCom.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileName.h" -// #include "../../../Windows/Handle.h" -#include "../../../Windows/Synchronization.h" - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Edit.h" -#include "../../../Windows/Control/ListView.h" -// FIXME #include "../../../Windows/Control/ReBar.h" -#include "../../../Windows/Control/Static.h" -#include "../../../Windows/Control/StatusBar.h" -// FIXME #include "../../../Windows/Control/ToolBar.h" -#include "../../../Windows/Control/Window2.h" - -#include "../../Archive/IArchive.h" - -#include "ExtractCallback.h" - -#include "AppState.h" -#include "IFolder.h" -// FIXME #include "MyCom2.h" -#include "ProgressDialog2.h" -#include "SysIconUtils.h" - -#ifdef UNDER_CE -#define NON_CE_VAR(_v_) -#else -#define NON_CE_VAR(_v_) _v_ -#endif - -const int kParentFolderID = 100; - -const int kParentIndex = -1; - -#if !defined(_WIN32) || defined(UNDER_CE) -#define ROOT_FS_FOLDER L"\\" -#else -#define ROOT_FS_FOLDER L"C:\\" -#endif - -struct CPanelCallback -{ - virtual void OnTab() = 0; - virtual void SetFocusToPath(int index) = 0; - virtual void OnCopy(bool move, bool copyToSame) = 0; - virtual void OnSetSameFolder() = 0; - virtual void OnSetSubFolder() = 0; - virtual void PanelWasFocused() = 0; - virtual void DragBegin() = 0; - virtual void DragEnd() = 0; - virtual void RefreshTitle(bool always) = 0; -}; - -void PanelCopyItems(); - -struct CItemProperty -{ - UString Name; - PROPID ID; - VARTYPE Type; - int Order; - bool IsVisible; - bool IsRawProp; - UInt32 Width; - - int Compare(const CItemProperty &a) const { return MyCompare(Order, a.Order); } -}; - -class CItemProperties: public CObjectVector -{ -public: - int FindItemWithID(PROPID id) - { - FOR_VECTOR (i, (*this)) - if ((*this)[i].ID == id) - return i; - return -1; - } -}; - -struct CTempFileInfo -{ - UInt32 FileIndex; // index of file in folder - UString RelPath; // Relative path of file from Folder - FString FolderPath; - FString FilePath; - NWindows::NFile::NFind::CFileInfo FileInfo; - bool NeedDelete; - - CTempFileInfo(): FileIndex((UInt32)(Int32)-1), NeedDelete(false) {} - void DeleteDirAndFile() const - { - if (NeedDelete) - { - NWindows::NFile::NDir::DeleteFileAlways(FilePath); - NWindows::NFile::NDir::RemoveDir(FolderPath); - } - } - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const - { - return newFileInfo.Size != FileInfo.Size || - CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0; - } -}; - -struct CFolderLink: public CTempFileInfo -{ - NWindows::NDLL::CLibrary Library; - CMyComPtr ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0]) - UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level) - bool UsePassword; - UString Password; - bool IsVirtual; - - UString VirtualPath; // without tail slash - CFolderLink(): UsePassword(false), IsVirtual(false) {} - - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const - { - return IsVirtual || CTempFileInfo::WasChanged(newFileInfo); - } - -}; - -enum MyMessages -{ - // we can use WM_USER, since we have defined new window class. - // so we don't need WM_APP. - kShiftSelectMessage = WM_USER + 1, - kReLoadMessage, - kSetFocusToListView, - kOpenItemChanged, - kRefresh_StatusBar - #ifdef UNDER_CE - , kRefresh_HeaderComboBox - #endif -}; - -UString GetFolderPath(IFolderFolder *folder); - -class CPanel; - -class CMyListView: public NWindows::NControl::CListView2 -{ -public: - CPanel *_panel; - LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); -}; - -/* -class CMyComboBox: public NWindows::NControl::CComboBoxEx -{ -public: - WNDPROC _origWindowProc; - CPanel *_panel; - LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); -}; -*/ -class CMyComboBoxEdit: public NWindows::NControl::CEdit -{ -public: - WNDPROC _origWindowProc; - CPanel *_panel; - LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); -}; - -struct CSelectedState -{ - int FocusedItem; - UString FocusedName; - bool SelectFocused; - UStringVector SelectedNames; - CSelectedState(): FocusedItem(-1), SelectFocused(false) {} -}; - -#ifdef UNDER_CE -#define MY_NMLISTVIEW_NMITEMACTIVATE NMLISTVIEW -#else -#define MY_NMLISTVIEW_NMITEMACTIVATE NMITEMACTIVATE -#endif - -struct CCopyToOptions -{ - bool streamMode; - bool moveMode; - bool testMode; - bool includeAltStreams; - bool replaceAltStreamChars; - bool showErrorMessages; - - UString folder; - - UStringVector hashMethods; - - CVirtFileSystem *VirtFileSystemSpec; - ISequentialOutStream *VirtFileSystem; - - CCopyToOptions(): - streamMode(false), - moveMode(false), - testMode(false), - includeAltStreams(true), - replaceAltStreamChars(false), - showErrorMessages(false), - VirtFileSystemSpec(NULL), - VirtFileSystem(NULL) - {} -}; - - -class CPanel: public NWindows::NControl::CWindow2 -{ - CExtToIconMap _extToIconMap; - UINT _baseID; - int _comboBoxID; - UINT _statusBarID; - - CAppState *_appState; - - bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result); - LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - virtual bool OnCreate(CREATESTRUCT *createStruct); - // FIXME virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual void OnDestroy(); - virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result); - - void AddComboBoxItem(const UString &name, int iconIndex, int indent, bool addToList); - - bool OnComboBoxCommand(UINT code, LPARAM param, LRESULT &result); - - #ifndef UNDER_CE - - LRESULT OnNotifyComboBoxEnter(const UString &s); - bool OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result); - #ifndef _UNICODE - bool OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result); - #endif - - #endif - - bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result); - bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result); - void OnItemChanged(NMLISTVIEW *item); - void OnNotifyActivateItems(); - bool OnNotifyList(LPNMHDR lParam, LRESULT &result); -/* FIXME - void OnDrag(LPNMLISTVIEW nmListView); - bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result); - BOOL OnBeginLabelEdit(LV_DISPINFOW * lpnmh); - BOOL OnEndLabelEdit(LV_DISPINFOW * lpnmh); -*/ - void OnColumnClick(LPNMLISTVIEW info); - // FIXME bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); - - -public: - HWND _mainWindow; - CPanelCallback *_panelCallback; - - void SysIconsWereChanged() { _extToIconMap.Clear(); } - - void DeleteItems(bool toRecycleBin); - void CreateFolder(); - void CreateFile(); - bool CorrectFsPath(const UString &path, UString &result); - // bool IsPathForPlugin(const UString &path); - -private: - - void ChangeWindowSize(int xSize, int ySize); - - HRESULT InitColumns(); - // void InitColumns2(PROPID sortID); - void InsertColumn(unsigned index); - - void SetFocusedSelectedItem(int index, bool select); - HRESULT RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, - const UStringVector &selectedNames); - - void OnShiftSelectMessage(); - void OnArrowWithShift(); - - void OnInsert(); - // void OnUpWithShift(); - // void OnDownWithShift(); -public: - void UpdateSelection(); - void SelectSpec(bool selectMode); - void SelectByType(bool selectMode); - void SelectAll(bool selectMode); - void InvertSelection(); -private: - - // UString GetFileType(UInt32 index); - LRESULT SetItemText(LVITEMW &item); - - // CRecordVector m_ColumnsPropIDs; - -public: - // NWindows::NControl::CReBar _headerReBar; - // NWindows::NControl::CToolBar _headerToolBar; - NWindows::NControl:: - #ifdef UNDER_CE - CComboBox - #else - CComboBoxEx - #endif - _headerComboBox; - UStringVector ComboBoxPaths; - // CMyComboBox _headerComboBox; - CMyComboBoxEdit _comboBoxEdit; - CMyListView _listView; - NWindows::NControl::CStatusBar _statusBar; - bool _lastFocusedIsList; - // NWindows::NControl::CStatusBar _statusBar2; - - DWORD _exStyle; - bool _showDots; - bool _showRealFileIcons; - // bool _virtualMode; - // CUIntVector _realIndices; - bool _enableItemChangeNotify; - bool _mySelectMode; - CBoolVector _selectedStatusVector; - - CSelectedState _selectedState; - bool _thereAreDeletedItems; - bool _markDeletedItems; - - HWND GetParent(); - - UInt32 GetRealIndex(const LVITEMW &item) const - { - /* - if (_virtualMode) - return _realIndices[item.iItem]; - */ - return (UInt32)item.lParam; - } - - int GetRealItemIndex(int indexInListView) const - { - /* - if (_virtualMode) - return indexInListView; - */ - LPARAM param; - if (!_listView.GetItemParam(indexInListView, param)) - throw 1; - return (int)param; - } - - UInt32 _ListViewMode; - int _xSize; - - bool _flatMode; - bool _flatModeForDisk; - bool _flatModeForArc; - - // bool _showNtfsStrems_Mode; - // bool _showNtfsStrems_ModeForDisk; - // bool _showNtfsStrems_ModeForArc; - - bool _dontShowMode; - - - UString _currentFolderPrefix; - - CObjectVector _parentFolders; - NWindows::NDLL::CLibrary _library; - - CMyComPtr _folder; - CMyComPtr _folderCompare; - CMyComPtr _folderGetItemName; - CMyComPtr _folderRawProps; - CMyComPtr _folderAltStreams; - CMyComPtr _folderOperations; - - void ReleaseFolder(); - void SetNewFolder(IFolderFolder *newFolder); - - // CMyComPtr _folderGetSystemIconIndex; - - UStringVector _fastFolders; - - void GetSelectedNames(UStringVector &selectedNames); - void SaveSelectedState(CSelectedState &s); - HRESULT RefreshListCtrl(const CSelectedState &s); - HRESULT RefreshListCtrlSaveFocused(); - - bool GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const; - bool IsItem_Deleted(int itemIndex) const; - bool IsItem_Folder(int itemIndex) const; - bool IsItem_AltStream(int itemIndex) const; - - UString GetItemName(int itemIndex) const; - UString GetItemName_for_Copy(int itemIndex) const; - void GetItemName(int itemIndex, UString &s) const; - UString GetItemPrefix(int itemIndex) const; - UString GetItemRelPath(int itemIndex) const; - UString GetItemRelPath2(int itemIndex) const; - UString GetItemFullPath(int itemIndex) const; - UInt64 GetItemSize(int itemIndex) const; - - //////////////////////// - // PanelFolderChange.cpp - - void SetToRootFolder(); - HRESULT BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted); // can be prefix - HRESULT BindToPathAndRefresh(const UString &path); - void OpenDrivesFolder(); - - void SetBookmark(int index); - void OpenBookmark(int index); - - void LoadFullPath(); - void LoadFullPathAndShow(); - void FoldersHistory(); - void OpenParentFolder(); - void CloseOneLevel(); - void CloseOpenFolders(); - void OpenRootFolder(); - - - HRESULT Create(HWND mainWindow, HWND parentWindow, - UINT id, - const UString ¤tFolderPrefix, - const UString &arcFormat, - CPanelCallback *panelCallback, - CAppState *appState, bool &archiveIsOpened, bool &encrypted); - void SetFocusToList(); - void SetFocusToLastRememberedItem(); - - - void ReadListViewInfo(); - void SaveListViewInfo(); - - CPanel() : - // _virtualMode(flase), - _exStyle(0), - _showDots(false), - _showRealFileIcons(false), - _needSaveInfo(false), - _startGroupSelect(0), - _selectionIsDefined(false), - _ListViewMode(3), - _flatMode(false), - _flatModeForDisk(false), - _flatModeForArc(false), - - // _showNtfsStrems_Mode(false), - // _showNtfsStrems_ModeForDisk(false), - // _showNtfsStrems_ModeForArc(false), - - _xSize(300), - _mySelectMode(false), - _thereAreDeletedItems(false), - _markDeletedItems(true), - _enableItemChangeNotify(true), - _dontShowMode(false) - {} - - void SetExtendedStyle() - { -/* FIXME - if (_listView != 0) - _listView.SetExtendedListViewStyle(_exStyle); -*/ - } - - - bool _needSaveInfo; - UString _typeIDString; - CListViewInfo _listViewInfo; - CItemProperties _properties; - CItemProperties _visibleProperties; - - PROPID _sortID; - // int _sortIndex; - bool _ascending; - Int32 _isRawSortProp; - - void SetSortRawStatus(); - - void Release(); - ~CPanel(); - // FIXME void OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate); - // FIXME bool OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result); - void ShowColumnsContextMenu(int x, int y); - - void OnTimer(); - void OnReload(); - bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); - -#ifdef _WIN32 - CMyComPtr _sevenZipContextMenu; - CMyComPtr _systemContextMenu; - HRESULT CreateShellContextMenu( - const CRecordVector &operatedIndices, - CMyComPtr &systemContextMenu); - void CreateSystemMenu(HMENU menu, - const CRecordVector &operatedIndices, - CMyComPtr &systemContextMenu); - void CreateSevenZipMenu(HMENU menu, - const CRecordVector &operatedIndices, - CMyComPtr &sevenZipContextMenu); - void CreateFileMenu(HMENU menu, - CMyComPtr &sevenZipContextMenu, - CMyComPtr &systemContextMenu, - bool programMenu); - void CreateFileMenu(HMENU menu); - bool InvokePluginCommand(int id); - bool InvokePluginCommand(int id, IContextMenu *sevenZipContextMenu, - IContextMenu *systemContextMenu); -#endif - - void InvokeSystemCommand(const char *command); - void Properties(); - void EditCut(); - void EditCopy(); - void EditPaste(); - - int _startGroupSelect; - - bool _selectionIsDefined; - bool _selectMark; - int _prevFocusedItem; - - - // void SortItems(int index); - void SortItemsWithPropID(PROPID propID); - - void GetSelectedItemsIndices(CRecordVector &indices) const; - void GetOperatedItemIndices(CRecordVector &indices) const; - void GetAllItemIndices(CRecordVector &indices) const; - void GetOperatedIndicesSmart(CRecordVector &indices) const; - // void GetOperatedListViewIndices(CRecordVector &indices) const; - void KillSelection(); - - UString GetFolderTypeID() const; - - bool IsFolderTypeEqTo(const char *s) const; - bool IsRootFolder() const; - bool IsFSFolder() const; - bool IsFSDrivesFolder() const; - bool IsAltStreamsFolder() const; - bool IsArcFolder() const; - - /* - c:\Dir - Computer\ - \\?\ - \\.\ - */ - bool Is_IO_FS_Folder() const - { - return IsFSFolder() || IsFSDrivesFolder() || IsAltStreamsFolder(); - } - - bool Is_Slow_Icon_Folder() const - { - return IsFSFolder() || IsAltStreamsFolder(); - } - - // bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); } - bool IsDeviceDrivesPrefix() const { return _currentFolderPrefix == L"\\\\.\\"; } - bool IsSuperDrivesPrefix() const { return _currentFolderPrefix == L"\\\\?\\"; } - - /* - c:\Dir - Computer\ - \\?\ - */ - bool IsFsOrPureDrivesFolder() const { return IsFSFolder() || (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()); } - - /* - c:\Dir - Computer\ - \\?\ - \\SERVER\ - */ - bool IsFolder_with_FsItems() const - { - if (IsFsOrPureDrivesFolder()) - return true; - #if defined(_WIN32) && !defined(UNDER_CE) - FString prefix = us2fs(GetFsPath()); - return (prefix.Len() == NWindows::NFile::NName::GetNetworkServerPrefixSize(prefix)); - #else - return false; - #endif - } - - UString GetFsPath() const; - UString GetDriveOrNetworkPrefix() const; - - bool DoesItSupportOperations() const { return _folderOperations != NULL; } - bool IsThereReadOnlyFolder() const; - bool CheckBeforeUpdate(UINT resourceID); - - bool _processTimer; - bool _processNotify; - bool _processStatusBar; - - class CDisableTimerProcessing - { - CLASS_NO_COPY(CDisableTimerProcessing); - - bool _processTimer; - - CPanel &_panel; - - public: - - CDisableTimerProcessing(CPanel &panel): _panel(panel) { Disable(); } - ~CDisableTimerProcessing() { Restore(); } - void Disable() - { - _processTimer = _panel._processTimer; - _panel._processTimer = false; - } - void Restore() - { - _panel._processTimer = _processTimer; - } - }; - - class CDisableNotify - { - CLASS_NO_COPY(CDisableNotify); - - bool _processNotify; - bool _processStatusBar; - - CPanel &_panel; - - public: - - CDisableNotify(CPanel &panel): _panel(panel) { Disable(); } - ~CDisableNotify() { Restore(); } - void Disable() - { - _processNotify = _panel._processNotify; - _processStatusBar = _panel._processStatusBar; - _panel._processNotify = false; - _panel._processStatusBar = false; - } - void SetMemMode_Enable() - { - _processNotify = true; - _processStatusBar = true; - } - void Restore() - { - _panel._processNotify = _processNotify; - _panel._processStatusBar = _processStatusBar; - } - }; - - // bool _passwordIsDefined; - // UString _password; - - void InvalidateList() { _listView.InvalidateRect(NULL, true); } - - HRESULT RefreshListCtrl(); - - void MessageBoxInfo(LPCWSTR message, LPCWSTR caption); - void MessageBox(LPCWSTR message); - void MessageBoxWarning(LPCWSTR message); - void MessageBox(LPCWSTR message, LPCWSTR caption); - void MessageBoxMyError(LPCWSTR message); - void MessageBoxError(HRESULT errorCode, LPCWSTR caption); - void MessageBoxError(HRESULT errorCode); - void MessageBoxError2Lines(LPCWSTR message, HRESULT errorCode); - void MessageBoxLastError(LPCWSTR caption); - void MessageBoxLastError(); - - // void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID); - - void MessageBoxErrorLang(UINT resourceID); - - void OpenAltStreams(); - - void OpenFocusedItemAsInternal(const wchar_t *type = NULL); - void OpenSelectedItems(bool internal); - - void OpenFolderExternal(int index); - - void OpenFolder(int index); - HRESULT OpenParentArchiveFolder(); - HRESULT OpenItemAsArchive(IInStream *inStream, - const CTempFileInfo &tempFileInfo, - const UString &virtualFilePath, - const UString &arcFormat, - bool &encrypted); - HRESULT OpenItemAsArchive(const UString &relPath, const UString &arcFormat, bool &encrypted); - HRESULT OpenItemAsArchive(int index, const wchar_t *type = NULL); - void OpenItemInArchive(int index, bool tryInternal, bool tryExternal, - bool editMode, bool useEditor, const wchar_t *type = NULL); - HRESULT OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, bool usePassword, const UString &password); - LRESULT OnOpenItemChanged(LPARAM lParam); - - bool IsVirus_Message(const UString &name); - void OpenItem(int index, bool tryInternal, bool tryExternal, const wchar_t *type = NULL); - void EditItem(bool useEditor); - void EditItem(int index, bool useEditor); - - void RenameFile(); - void ChangeComment(); - - void SetListViewMode(UInt32 index); - UInt32 GetListViewMode() const { return _ListViewMode; } - PROPID GetSortID() const { return _sortID; } - - void ChangeFlatMode(); - void Change_ShowNtfsStrems_Mode(); - bool GetFlatMode() const { return _flatMode; } - // bool Get_ShowNtfsStrems_Mode() const { return _showNtfsStrems_Mode; } - - bool AutoRefresh_Mode; - void Set_AutoRefresh_Mode(bool mode) - { - AutoRefresh_Mode = mode; - } - - void Post_Refresh_StatusBar(); - void Refresh_StatusBar(); - - void AddToArchive(); - - void GetFilePaths(const CRecordVector &indices, UStringVector &paths, bool allowFolders = false); - void ExtractArchives(); - void TestArchives(); - - HRESULT CopyTo(CCopyToOptions &options, - const CRecordVector &indices, - UStringVector *messages, - bool &usePassword, UString &password); - - HRESULT CopyTo(CCopyToOptions &options, const CRecordVector &indices, UStringVector *messages) - { - bool usePassword = false; - UString password; - if (_parentFolders.Size() > 0) - { - const CFolderLink &fl = _parentFolders.Back(); - usePassword = fl.UsePassword; - password = fl.Password; - } - return CopyTo(options, indices, messages, usePassword, password); - } - - HRESULT CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths, - bool showErrorMessages, UStringVector *messages); - - void CopyFromNoAsk(const UStringVector &filePaths); - void CopyFromAsk(const UStringVector &filePaths); - -#ifdef _WIN32 - // empty folderPath means create new Archive to path of first fileName. - void DropObject(IDataObject * dataObject, const UString &folderPath); - - // empty folderPath means create new Archive to path of first fileName. - void CompressDropFiles(const UStringVector &fileNames, const UString &folderPath); -#endif - - void RefreshTitle(bool always = false) { _panelCallback->RefreshTitle(always); } - void RefreshTitleAlways() { RefreshTitle(true); } - - UString GetItemsInfoString(const CRecordVector &indices); -}; - -class CMyBuffer -{ - void *_data; -public: - CMyBuffer(): _data(0) {} - operator void *() { return _data; } - bool Allocate(size_t size) - { - if (_data != 0) - return false; - _data = ::MidAlloc(size); - return _data != 0; - } - ~CMyBuffer() { ::MidFree(_data); } -}; - -#endif +// Panel.h + +#ifndef ZIP7_INC_PANEL_H +#define ZIP7_INC_PANEL_H + +#include "../../../Common/MyWindows.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../../C/Alloc.h" + +#include "../../../Common/Defs.h" +#include "../../../Common/MyCom.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Handle.h" +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/Synchronization.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" +#include "../../../Windows/Control/ListView.h" +#include "../../../Windows/Control/ReBar.h" +#include "../../../Windows/Control/Static.h" +#include "../../../Windows/Control/StatusBar.h" +#include "../../../Windows/Control/ToolBar.h" +#include "../../../Windows/Control/Window2.h" + +#include "../../Archive/IArchive.h" + +#include "ExtractCallback.h" + +#include "AppState.h" +#include "IFolder.h" +#include "MyCom2.h" +#include "ProgressDialog2.h" +#include "SysIconUtils.h" + +#ifdef UNDER_CE +#define NON_CE_VAR(_v_) +#else +#define NON_CE_VAR(_v_) _v_ +#endif + +const int kParentFolderID = 100; + +const unsigned kParentIndex = (unsigned)(int)-1; +const UInt32 kParentIndex_UInt32 = (UInt32)(Int32)kParentIndex; + +#if !defined(_WIN32) || defined(UNDER_CE) +#define ROOT_FS_FOLDER L"\\" +#else +#define ROOT_FS_FOLDER L"C:\\" +#endif + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // < win2000 +#define Z7_USE_DYN_ComCtl32Version +extern DWORD g_ComCtl32Version; +#endif + +Z7_PURE_INTERFACES_BEGIN + +DECLARE_INTERFACE(CPanelCallback) +{ + virtual void OnTab() = 0; + virtual void SetFocusToPath(unsigned index) = 0; + virtual void OnCopy(bool move, bool copyToSame) = 0; + virtual void OnSetSameFolder() = 0; + virtual void OnSetSubFolder() = 0; + virtual void PanelWasFocused() = 0; + virtual void DragBegin() = 0; + virtual void DragEnd() = 0; + virtual void RefreshTitle(bool always) = 0; +}; +Z7_PURE_INTERFACES_END + +void PanelCopyItems(); + + +struct CPropColumn +{ + int Order; + PROPID ID; + VARTYPE Type; + bool IsVisible; + bool IsRawProp; + UInt32 Width; + UString Name; + + bool IsEqualTo(const CPropColumn &a) const + { + return Order == a.Order + && ID == a.ID + && Type == a.Type + && IsVisible == a.IsVisible + && IsRawProp == a.IsRawProp + && Width == a.Width + && Name == a.Name; + } + + int Compare(const CPropColumn &a) const { return MyCompare(Order, a.Order); } + + int Compare_NameFirst(const CPropColumn &a) const + { + if (ID == kpidName) + { + if (a.ID != kpidName) + return -1; + } + else if (a.ID == kpidName) + return 1; + return MyCompare(Order, a.Order); + } +}; + + +class CPropColumns: public CObjectVector +{ +public: + int FindItem_for_PropID(PROPID id) const + { + FOR_VECTOR (i, (*this)) + if ((*this)[i].ID == id) + return (int)i; + return -1; + } + + bool IsEqualTo(const CPropColumns &props) const + { + if (Size() != props.Size()) + return false; + FOR_VECTOR (i, (*this)) + if (!(*this)[i].IsEqualTo(props[i])) + return false; + return true; + } +}; + + +struct CTempFileInfo +{ + UInt32 FileIndex; // index of file in folder + bool NeedDelete; + UString RelPath; // Relative path of file from Folder + FString FolderPath; + FString FilePath; + NWindows::NFile::NFind::CFileInfo FileInfo; + + CTempFileInfo(): FileIndex((UInt32)(Int32)-1), NeedDelete(false) {} + void DeleteDirAndFile() const + { + if (NeedDelete) + { + NWindows::NFile::NDir::DeleteFileAlways(FilePath); + NWindows::NFile::NDir::RemoveDir(FolderPath); + } + } + bool WasChanged_from_TempFileInfo(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const + { + return newFileInfo.Size != FileInfo.Size || + CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0; + } +}; + + +struct CFolderLink: public CTempFileInfo +{ + bool IsVirtual; // == true (if archive was open via IInStream): + // archive was open from another archive, + // archive size meets the size conditions derived from g_RAM_Size. + // VirtFileSystem was used + // archive was fully extracted to memory. + bool UsePassword; + NWindows::NDLL::CLibrary Library; + CMyComPtr ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0]) + UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level) + UString Password; + UString VirtualPath; // without tail slash + CByteBuffer ZoneBuf; // ZoneBuf for virtaul stream (IsVirtual) + + CFolderLink(): IsVirtual(false), UsePassword(false) {} + bool WasChanged_from_FolderLink(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const + { + // we call it, if we have two real files. + // if archive was virtual, it means that we have updated that virtual to real file. + return IsVirtual || CTempFileInfo::WasChanged_from_TempFileInfo(newFileInfo); + } +}; + + +enum MyMessages +{ + // we can use WM_USER, since we have defined new window class. + // so we don't need WM_APP. + kShiftSelectMessage = WM_USER + 1, + kReLoadMessage, + kSetFocusToListView, + kOpenItemChanged, + kRefresh_StatusBar + #ifdef UNDER_CE + , kRefresh_HeaderComboBox + #endif +}; + +UString GetFolderPath(IFolderFolder *folder); + +class CPanel; + +class CMyListView Z7_final: public NWindows::NControl::CListView2 +{ + // ~CMyListView() ZIP7_eq_delete; + // CMyListView() ZIP7_eq_delete; +public: + // CMyListView() {} + // ~CMyListView() Z7_DESTRUCTOR_override {} // change it + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; +}; + +/* +class CMyComboBox: public NWindows::NControl::CComboBoxEx +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; +*/ +class CMyComboBoxEdit: public NWindows::NControl::CEdit +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +struct CSelectedState +{ + int FocusedItem; + bool SelectFocused; + bool FocusedName_Defined; + bool CalledFromTimer; + UString FocusedName; + UStringVector SelectedNames; + + CSelectedState(): + FocusedItem(-1), + SelectFocused(true), + FocusedName_Defined(false), + CalledFromTimer(false) + {} +}; + +#ifdef UNDER_CE +#define MY_NMLISTVIEW_NMITEMACTIVATE NMLISTVIEW +#else +#define MY_NMLISTVIEW_NMITEMACTIVATE NMITEMACTIVATE +#endif + +struct CCopyToOptions +{ + bool streamMode; + bool moveMode; + bool testMode; + bool includeAltStreams; + bool replaceAltStreamChars; + bool showErrorMessages; + + bool NeedRegistryZone; + NExtract::NZoneIdMode::EEnum ZoneIdMode; + CByteBuffer ZoneBuf; + + UString folder; + + UStringVector hashMethods; + + CVirtFileSystem *VirtFileSystemSpec; + // ISequentialOutStream *VirtFileSystem; + + CCopyToOptions(): + streamMode(false), + moveMode(false), + testMode(false), + includeAltStreams(true), + replaceAltStreamChars(false), + showErrorMessages(false), + NeedRegistryZone(true), + ZoneIdMode(NExtract::NZoneIdMode::kNone), + VirtFileSystemSpec(NULL) + // , VirtFileSystem(NULL) + {} +}; + + + +struct COpenResult +{ + // bool needOpenArc; + // out: + bool ArchiveIsOpened; + bool Encrypted; + UString ErrorMessage; + + COpenResult(): + // needOpenArc(false), + ArchiveIsOpened(false), Encrypted(false) {} +}; + + + + +class CPanel Z7_final: public NWindows::NControl::CWindow2 +{ + bool _thereAre_ListView_Items; + // bool _virtualMode; + bool _enableItemChangeNotify; + bool _thereAreDeletedItems; + bool _markDeletedItems; + bool _dontShowMode; + bool _needSaveInfo; + +public: + bool PanelCreated; + bool _mySelectMode; + bool _showDots; + bool _showRealFileIcons; + bool _flatMode; + bool _flatModeForArc; + bool _flatModeForDisk; + bool _selectionIsDefined; + // bool _showNtfsStrems_Mode; + // bool _showNtfsStrems_ModeForDisk; + // bool _showNtfsStrems_ModeForArc; + + bool _selectMark; + bool _lastFocusedIsList; + + bool _processTimer; + bool _processNotify; + bool _processStatusBar; + +public: + bool _ascending; + PROPID _sortID; + // int _sortIndex; + Int32 _isRawSortProp; + + CMyListView _listView; + CPanelCallback *_panelCallback; + +private: + + // CExtToIconMap _extToIconMap; + UINT _baseID; + unsigned _comboBoxID; + UINT _statusBarID; + +public: + DWORD _exStyle; + // CUIntVector _realIndices; + int _timestampLevel; + UInt32 _listViewMode; + int _xSize; +private: + int _startGroupSelect; + int _prevFocusedItem; + + CAppState *_appState; + + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam, LRESULT &result) Z7_override; + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnCreate(CREATESTRUCT *createStruct) Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual void OnDestroy() Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result) Z7_override; + + void AddComboBoxItem(const UString &name, int iconIndex, unsigned indent, bool addToList); + + bool OnComboBoxCommand(UINT code, LPARAM param, LRESULT &result); + + #ifndef UNDER_CE + + LRESULT OnNotifyComboBoxEnter(const UString &s); + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result); + #ifndef _UNICODE + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result); + #endif + + #endif + + bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result); + bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result); + void OnItemChanged(NMLISTVIEW *item); + void OnNotifyActivateItems(); + bool OnNotifyList(LPNMHDR lParam, LRESULT &result); + void OnDrag(LPNMLISTVIEW nmListView, bool isRightButton = false); + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result); + BOOL OnBeginLabelEdit(LV_DISPINFOW * lpnmh); + BOOL OnEndLabelEdit(LV_DISPINFOW * lpnmh); + void OnColumnClick(LPNMLISTVIEW info); + bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); + + + void ChangeWindowSize(int xSize, int ySize); + HRESULT InitColumns(); + void DeleteColumn(unsigned index); + void AddColumn(const CPropColumn &prop); + + void SetFocusedSelectedItem(int index, bool select); + + void OnShiftSelectMessage(); + void OnArrowWithShift(); + + void OnInsert(); + // void OnUpWithShift(); + // void OnDownWithShift(); + // UString GetFileType(UInt32 index); + LRESULT SetItemText(LVITEMW &item); + // CRecordVector m_ColumnsPropIDs; + +public: + HWND _mainWindow; + + NWindows::NControl::CReBar _headerReBar; + NWindows::NControl::CToolBar _headerToolBar; + NWindows::NControl:: + #ifdef UNDER_CE + CComboBox + #else + CComboBoxEx + #endif + _headerComboBox; + UStringVector ComboBoxPaths; + // CMyComboBox _headerComboBox; + CMyComboBoxEdit _comboBoxEdit; + NWindows::NControl::CStatusBar _statusBar; + // NWindows::NControl::CStatusBar _statusBar2; + + CBoolVector _selectedStatusVector; + CSelectedState _selectedState; + + UString _currentFolderPrefix; + + CObjectVector _parentFolders; + NWindows::NDLL::CLibrary _library; + + CMyComPtr _folder; + CBoolVector _isDirVector; + CMyComPtr _folderCompare; + CMyComPtr _folderGetItemName; + CMyComPtr _folderRawProps; + CMyComPtr _folderAltStreams; + CMyComPtr _folderOperations; + + // for drag and drop highliting + int m_DropHighlighted_SelectionIndex; + // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item) + UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder) + + // CMyComPtr _folderGetSystemIconIndex; + UStringVector _fastFolders; + + UString _typeIDString; + CListViewInfo _listViewInfo; + + CPropColumns _columns; + CPropColumns _visibleColumns; + + CMyComPtr _sevenZipContextMenu; + CMyComPtr _systemContextMenu; + + void UpdateSelection(); + void SelectSpec(bool selectMode); + void SelectByType(bool selectMode); + void SelectAll(bool selectMode); + void InvertSelection(); + + void RedrawListItems() + { + _listView.RedrawAllItems(); + } + void DeleteListItems() + { + if (_thereAre_ListView_Items) + { + const bool b = _enableItemChangeNotify; + _enableItemChangeNotify = false; + _listView.DeleteAllItems(); + _thereAre_ListView_Items = false; + _enableItemChangeNotify = b; + } + } + + // void SysIconsWereChanged() { _extToIconMap.Clear(); } + + void DeleteItems(bool toRecycleBin); + void CreateFolder(); + void CreateFile(); + bool CorrectFsPath(const UString &path, UString &result); + // bool IsPathForPlugin(const UString &path); + + + HWND GetParent() const; + + UInt32 GetRealIndex(const LVITEMW &item) const + { + /* + if (_virtualMode) + return _realIndices[item.iItem]; + */ + return (UInt32)item.lParam; + } + + unsigned GetRealItemIndex(int indexInListView) const + { + /* + if (_virtualMode) + return indexInListView; + */ + LPARAM param; + if (!_listView.GetItemParam((unsigned)indexInListView, param)) + throw 1; + return (unsigned)param; + } + + void ReleaseFolder(); + void SetNewFolder(IFolderFolder *newFolder); + void GetSelectedNames(UStringVector &selectedNames); + void SaveSelectedState(CSelectedState &s); + HRESULT RefreshListCtrl(const CSelectedState &s); + HRESULT RefreshListCtrl_SaveFocused(bool onTimer = false); + + // UInt32 GetItem_Attrib(UInt32 itemIndex) const; + + bool GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const; + + bool IsItem_Deleted(unsigned itemIndex) const; + bool IsItem_Folder(unsigned itemIndex) const; + bool IsItem_AltStream(unsigned itemIndex) const; + + UString GetItemName(unsigned itemIndex) const; + UString GetItemName_for_Copy(unsigned itemIndex) const; + void GetItemName(unsigned itemIndex, UString &s) const; + UString GetItemPrefix(unsigned itemIndex) const; + UString GetItemRelPath(unsigned itemIndex) const; + UString GetItemRelPath2(unsigned itemIndex) const; + + void Add_ItemRelPath2_To_String(unsigned itemIndex, UString &s) const; + + UString GetItemFullPath(unsigned itemIndex) const; + UInt64 GetItem_UInt64Prop(unsigned itemIndex, PROPID propID) const; + UInt64 GetItemSize(unsigned itemIndex) const; + + //////////////////////// + // PanelFolderChange.cpp + + void SetToRootFolder(); + HRESULT BindToPath(const UString &fullPath, const UString &arcFormat, COpenResult &openRes); // can be prefix + HRESULT BindToPathAndRefresh(const UString &path); + void OpenDrivesFolder(); + + void SetBookmark(unsigned index); + void OpenBookmark(unsigned index); + + void LoadFullPath(); + void LoadFullPathAndShow(); + void FoldersHistory(); + void OpenParentFolder(); + void CloseOneLevel(); + void CloseOpenFolders(); + void OpenRootFolder(); + + UString GetParentDirPrefix() const; + + HRESULT Create(HWND mainWindow, HWND parentWindow, + UINT id, + const UString ¤tFolderPrefix, + const UString &arcFormat, + CPanelCallback *panelCallback, + CAppState *appState, + bool needOpenArc, + COpenResult &openRes); + + void SetFocusToList(); + void SetFocusToLastRememberedItem(); + + + void SaveListViewInfo(); + + CPanel() : + _thereAre_ListView_Items(false), + // _virtualMode(false), + _enableItemChangeNotify(true), + _thereAreDeletedItems(false), + _markDeletedItems(true), + _dontShowMode(false), + _needSaveInfo(false), + + PanelCreated(false), + _mySelectMode(false), + _showDots(false), + _showRealFileIcons(false), + _flatMode(false), + _flatModeForArc(false), + _flatModeForDisk(false), + _selectionIsDefined(false), + // _showNtfsStrems_Mode(false), + // _showNtfsStrems_ModeForDisk(false), + // _showNtfsStrems_ModeForArc(false), + + _exStyle(0), + _timestampLevel(kTimestampPrintLevel_MIN), + _listViewMode(3), + _xSize(300), + _startGroupSelect(0), + m_DropHighlighted_SelectionIndex(-1) + {} + + ~CPanel() Z7_DESTRUCTOR_override; + + void ReleasePanel(); + + void SetExtendedStyle() + { + if (_listView) + _listView.SetExtendedListViewStyle(_exStyle); + } + + void SetSortRawStatus(); + void OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate); + bool OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result); + void ShowColumnsContextMenu(int x, int y); + + void OnTimer(); + void OnReload(bool onTimer = false); + bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); + + HRESULT CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + + void CreateSystemMenu(HMENU menu, + bool showExtendedVerbs, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + + void CreateSevenZipMenu(HMENU menu, + bool showExtendedVerbs, + const CRecordVector &operatedIndices, + int firstDirIndex, + CMyComPtr &sevenZipContextMenu); + + void CreateFileMenu(HMENU menu, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu); + + void CreateFileMenu(HMENU menu); + bool InvokePluginCommand(unsigned id); + bool InvokePluginCommand(unsigned id, IContextMenu *sevenZipContextMenu, + IContextMenu *systemContextMenu); + + void InvokeSystemCommand(const char *command); + void Properties(); + void EditCut(); + void EditCopy(); + void EditPaste(); + + + // void SortItems(int index); + void SortItemsWithPropID(PROPID propID); + + void Get_ItemIndices_Selected(CRecordVector &indices) const; + void Get_ItemIndices_Operated(CRecordVector &indices) const; + void Get_ItemIndices_All(CRecordVector &indices) const; + void Get_ItemIndices_OperSmart(CRecordVector &indices) const; + // void GetOperatedListViewIndices(CRecordVector &indices) const; + void KillSelection(); + + UString GetFolderTypeID() const; + + bool IsFolderTypeEqTo(const char *s) const; + bool IsRootFolder() const; + bool IsFSFolder() const; + bool IsFSDrivesFolder() const; + bool IsAltStreamsFolder() const; + bool IsArcFolder() const; + bool IsHashFolder() const; + + /* + c:\Dir + Computer\ + \\?\ + \\.\ + */ + bool Is_IO_FS_Folder() const + { + return IsFSFolder() || IsFSDrivesFolder() || IsAltStreamsFolder(); + } + + bool Is_Slow_Icon_Folder() const + { + return IsFSFolder() || IsAltStreamsFolder(); + } + + // bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); } + bool IsDeviceDrivesPrefix() const { return _currentFolderPrefix.IsEqualTo("\\\\.\\"); } + bool IsSuperDrivesPrefix() const { return _currentFolderPrefix.IsEqualTo("\\\\?\\"); } + + /* + c:\Dir + Computer\ + \\?\ + */ + bool IsFsOrPureDrivesFolder() const { return IsFSFolder() || (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()); } + + /* + c:\Dir + Computer\ + \\?\ + \\SERVER\ + */ + bool IsFolder_with_FsItems() const + { + if (IsFsOrPureDrivesFolder()) + return true; + #if defined(_WIN32) && !defined(UNDER_CE) + FString prefix = us2fs(GetFsPath()); + return (prefix.Len() == NWindows::NFile::NName::GetNetworkServerPrefixSize(prefix)); + #else + return false; + #endif + } + + UString GetFsPath() const; + UString GetDriveOrNetworkPrefix() const; + + bool DoesItSupportOperations() const { return _folderOperations != NULL; } + bool IsThereReadOnlyFolder() const; + bool CheckBeforeUpdate(UINT resourceID); + + void Disable_Processing_Timer_Notify_StatusBar() + { + _processTimer = false; + _processNotify = false; + _processStatusBar = false; + } + + class CDisableTimerProcessing + { + Z7_CLASS_NO_COPY(CDisableTimerProcessing) + + bool _processTimer; + CPanel &_panel; + + public: + + CDisableTimerProcessing(CPanel &panel): _panel(panel) { Disable(); } + ~CDisableTimerProcessing() { Restore(); } + void Disable() + { + _processTimer = _panel._processTimer; + _panel._processTimer = false; + } + void Restore() + { + _panel._processTimer = _processTimer; + } + }; + + class CDisableTimerProcessing2 + { + Z7_CLASS_NO_COPY(CDisableTimerProcessing2) + + bool _processTimer; + CPanel *_panel; + + public: + + CDisableTimerProcessing2(CPanel *panel): _processTimer(true), _panel(panel) { Disable(); } + ~CDisableTimerProcessing2() { Restore(); } + void Disable() + { + if (_panel) + { + _processTimer = _panel->_processTimer; + _panel->_processTimer = false; + } + } + void Restore() + { + if (_panel) + { + _panel->_processTimer = _processTimer; + _panel = NULL; + } + } + }; + + class CDisableNotify + { + Z7_CLASS_NO_COPY(CDisableNotify) + + bool _processNotify; + bool _processStatusBar; + + CPanel &_panel; + + public: + + CDisableNotify(CPanel &panel): _panel(panel) { Disable(); } + ~CDisableNotify() { Restore(); } + void Disable() + { + _processNotify = _panel._processNotify; + _processStatusBar = _panel._processStatusBar; + _panel._processNotify = false; + _panel._processStatusBar = false; + } + void SetMemMode_Enable() + { + _processNotify = true; + _processStatusBar = true; + } + void Restore() + { + _panel._processNotify = _processNotify; + _panel._processStatusBar = _processStatusBar; + } + }; + + void InvalidateList() { _listView.InvalidateRect(NULL, true); } + + HRESULT RefreshListCtrl(); + + + // void MessageBox_Info(LPCWSTR message, LPCWSTR caption) const; + // void MessageBox_Warning(LPCWSTR message) const; + void MessageBox_Error_Caption(LPCWSTR message, LPCWSTR caption) const; + void MessageBox_Error(LPCWSTR message) const; + void MessageBox_Error_HRESULT_Caption(HRESULT errorCode, LPCWSTR caption) const; + void MessageBox_Error_HRESULT(HRESULT errorCode) const; + void MessageBox_Error_2Lines_Message_HRESULT(LPCWSTR message, HRESULT errorCode) const; + void MessageBox_LastError(LPCWSTR caption) const; + void MessageBox_LastError() const; + void MessageBox_Error_LangID(UINT resourceID) const; + void MessageBox_Error_UnsupportOperation() const; + // void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID); + + + void OpenAltStreams(); + + void OpenFocusedItemAsInternal(const wchar_t *type = NULL); + void OpenSelectedItems(bool internal); + + void OpenFolderExternal(unsigned index); + + void OpenFolder(unsigned index); + HRESULT OpenParentArchiveFolder(); + + HRESULT OpenAsArc(IInStream *inStream, + const CTempFileInfo &tempFileInfo, + const UString &virtualFilePath, + const UString &arcFormat, + COpenResult &openRes); + + HRESULT OpenAsArc_Msg(IInStream *inStream, + const CTempFileInfo &tempFileInfo, + const UString &virtualFilePath, + const UString &arcFormat + // , bool showErrorMessage + ); + + HRESULT OpenAsArc_Name(const UString &relPath, const UString &arcFormat + // , bool showErrorMessage + ); + HRESULT OpenAsArc_Index(unsigned index, const wchar_t *type /* = NULL */ + // , bool showErrorMessage + ); + + void OpenItemInArchive(unsigned index, bool tryInternal, bool tryExternal, + bool editMode, bool useEditor, const wchar_t *type = NULL); + + HRESULT OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, bool usePassword, const UString &password); + LRESULT OnOpenItemChanged(LPARAM lParam); + + bool IsVirus_Message(const UString &name); + void OpenItem(unsigned index, bool tryInternal, bool tryExternal, const wchar_t *type = NULL); + void EditItem(bool useEditor); + void EditItem(unsigned index, bool useEditor); + + void RenameFile(); + void ChangeComment(); + + void SetListViewMode(UInt32 index); + UInt32 GetListViewMode() const { return _listViewMode; } + PROPID GetSortID() const { return _sortID; } + + void ChangeFlatMode(); + void Change_ShowNtfsStrems_Mode(); + bool GetFlatMode() const { return _flatMode; } + // bool Get_ShowNtfsStrems_Mode() const { return _showNtfsStrems_Mode; } + + bool AutoRefresh_Mode; + void Set_AutoRefresh_Mode(bool mode) + { + AutoRefresh_Mode = mode; + } + + void Post_Refresh_StatusBar(); + void Refresh_StatusBar(); + + void AddToArchive(); + + int FindDir_InOperatedList(const CRecordVector &indices) const; + void GetFilePaths(const CRecordVector &indices, UStringVector &paths) const; + void ExtractArchives(); + void TestArchives(); + + void Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf); + + HRESULT CopyTo(CCopyToOptions &options, + const CRecordVector &indices, + UStringVector *messages, + bool &usePassword, UString &password, + const UStringVector *filePaths = NULL); + + HRESULT CopyTo(CCopyToOptions &options, + const CRecordVector &indices, + UStringVector *messages) + { + bool usePassword = false; + UString password; + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &fl = _parentFolders.Back(); + usePassword = fl.UsePassword; + password = fl.Password; + } + return CopyTo(options, indices, messages, usePassword, password); + } + + HRESULT CopyFsItems(CCopyToOptions &options, + const UStringVector &filePaths, + UStringVector *messages) + { + bool usePassword = false; + UString password; + CRecordVector indices; + return CopyTo(options, indices, messages, usePassword, password, &filePaths); + } + + + HRESULT CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages); + + void CopyFromNoAsk(bool moveMode, const UStringVector &filePaths); + + void CompressDropFiles( + const UStringVector &filePaths, + const UString &folderPath, + bool createNewArchive, + bool moveMode, + UInt32 sourceFlags, + UInt32 &targetFlags); + + void RefreshTitle(bool always = false) { _panelCallback->RefreshTitle(always); } + void RefreshTitleAlways() { RefreshTitle(true); } + + UString GetItemsInfoString(const CRecordVector &indices); +}; + + +class CMyBuffer +{ + void *_data; +public: + CMyBuffer(): _data(NULL) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data) + return false; + _data = ::MidAlloc(size); + return _data != NULL; + } + ~CMyBuffer() { ::MidFree(_data); } +}; + +struct CExitEventLauncher +{ + NWindows::NSynchronization::CManualResetEvent _exitEvent; + bool _needExit; + unsigned _numActiveThreads; + CRecordVector< ::CThread > _threads; + + CExitEventLauncher() + { + _needExit = false; + if (_exitEvent.Create(false) != S_OK) + throw 9387173; + _needExit = true; + _numActiveThreads = 0; + } + + ~CExitEventLauncher() { Exit(true); } + + void Exit(bool hardExit); +}; + +extern CExitEventLauncher g_ExitEventLauncher; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelCopy.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCopy.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelCopy.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCopy.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -1,356 +1,477 @@ -/// PanelCopy.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyException.h" - -#include "../GUI/HashGUI.h" - -#include "ExtractCallback.h" -#include "LangUtils.h" -#include "Panel.h" -#include "resource.h" -#include "UpdateCallback100.h" - -using namespace NWindows; - -class CPanelCopyThread: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - const CCopyToOptions *options; - CMyComPtr FolderOperations; - CRecordVector Indices; - CExtractCallbackImp *ExtractCallbackSpec; - CMyComPtr ExtractCallback; - - CHashBundle Hash; - UString FirstFilePath; - - HRESULT Result; - - - CPanelCopyThread(): Result(E_FAIL) {} -}; - -HRESULT CPanelCopyThread::ProcessVirt() -{ - /* - CMyComPtr iReplace; - FolderOperations.QueryInterface(IID_IFolderSetReplaceAltStreamCharsMode, &iReplace); - if (iReplace) - { - RINOK(iReplace->SetReplaceAltStreamCharsMode(ReplaceAltStreamChars ? 1 : 0)); - } - */ - - if (options->testMode) - { - CMyComPtr archiveFolder; - FolderOperations.QueryInterface(IID_IArchiveFolder, &archiveFolder); - if (!archiveFolder) - return E_NOTIMPL; - CMyComPtr extractCallback2; - RINOK(ExtractCallback.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)); - NExtract::NPathMode::EEnum pathMode = - NExtract::NPathMode::kCurPaths; - // NExtract::NPathMode::kFullPathnames; - Result = archiveFolder->Extract(&Indices.Front(), Indices.Size(), - BoolToInt(options->includeAltStreams), - BoolToInt(options->replaceAltStreamChars), - pathMode, NExtract::NOverwriteMode::kAsk, - options->folder, BoolToInt(true), extractCallback2); - } - else - Result = FolderOperations->CopyTo( - BoolToInt(options->moveMode), - &Indices.Front(), Indices.Size(), - BoolToInt(options->includeAltStreams), - BoolToInt(options->replaceAltStreamChars), - options->folder, ExtractCallback); - - if (Result == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors && - (!options->hashMethods.IsEmpty() || options->testMode)) - { - CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); - AddHashBundleRes(pair.Message, Hash, FirstFilePath); - } - - return Result; -} - - -/* -#ifdef EXTERNAL_CODECS - -static void ThrowException_if_Error(HRESULT res) -{ - if (res != S_OK) - throw CSystemException(res); -} - -#endif -*/ - - -HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector &indices, - UStringVector *messages, - bool &usePassword, UString &password) -{ - if (!_folderOperations) - { - UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); - if (options.showErrorMessages) - MessageBox(errorMessage); - else if (messages != 0) - messages->Add(errorMessage); - return E_FAIL; - } - - HRESULT res = S_OK; - - { - /* - #ifdef EXTERNAL_CODECS - CExternalCodecs g_ExternalCodecs; - #endif - */ - /* extracter.Hash uses g_ExternalCodecs - extracter must be declared after g_ExternalCodecs for correct destructor order !!! */ - - CPanelCopyThread extracter; - - extracter.ExtractCallbackSpec = new CExtractCallbackImp; - extracter.ExtractCallback = extracter.ExtractCallbackSpec; - - extracter.options = &options; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; - extracter.ProgressDialog.CompressingMode = false; - - extracter.ExtractCallbackSpec->StreamMode = options.streamMode; - - - if (indices.Size() == 1) - extracter.FirstFilePath = GetItemRelPath(indices[0]); - - if (options.VirtFileSystem) - { - extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystem; - extracter.ExtractCallbackSpec->VirtFileSystemSpec = options.VirtFileSystemSpec; - } - extracter.ExtractCallbackSpec->ProcessAltStreams = options.includeAltStreams; - - if (!options.hashMethods.IsEmpty()) - { - /* this code is used when we call CRC calculation for files in side archive - But new code uses global codecs so we don't need to call LoadGlobalCodecs again */ - - /* - #ifdef EXTERNAL_CODECS - ThrowException_if_Error(LoadGlobalCodecs()); - #endif - */ - - extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS_G options.hashMethods); - extracter.ExtractCallbackSpec->SetHashMethods(&extracter.Hash); - } - else if (options.testMode) - { - extracter.ExtractCallbackSpec->SetHashCalc(&extracter.Hash); - } - - extracter.Hash.Init(); - - UString title; - { - UInt32 titleID = IDS_COPYING; - if (options.moveMode) - titleID = IDS_MOVING; - else if (!options.hashMethods.IsEmpty() && options.streamMode) - { - titleID = IDS_CHECKSUM_CALCULATING; - if (options.hashMethods.Size() == 1) - { - const UString &s = options.hashMethods[0]; - if (s != L"*") - title = s; - } - } - else if (options.testMode) - titleID = IDS_PROGRESS_TESTING; - - if (title.IsEmpty()) - title = LangString(titleID); - } - - UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - - extracter.ProgressDialog.MainWindow = GetParent(); - extracter.ProgressDialog.MainTitle = progressWindowTitle; - extracter.ProgressDialog.MainAddTitle = title + L' '; - - extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk; - extracter.ExtractCallbackSpec->Init(); - extracter.Indices = indices; - extracter.FolderOperations = _folderOperations; - - extracter.ExtractCallbackSpec->PasswordIsDefined = usePassword; - extracter.ExtractCallbackSpec->Password = password; - - RINOK(extracter.Create(title, GetParent())); - - if (messages != 0) - *messages = extracter.ProgressDialog.Sync.Messages; - res = extracter.Result; - - if (res == S_OK && extracter.ExtractCallbackSpec->IsOK()) - { - usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined; - password = extracter.ExtractCallbackSpec->Password; - } - } - - RefreshTitleAlways(); - return res; -} - - -struct CThreadUpdate -{ - CMyComPtr FolderOperations; - UString FolderPrefix; - UStringVector FileNames; - CRecordVector FileNamePointers; - CProgressDialog ProgressDialog; - CMyComPtr UpdateCallback; - CUpdateCallback100Imp *UpdateCallbackSpec; - HRESULT Result; - bool MoveMode; - - void Process() - { - try - { - CProgressCloser closer(ProgressDialog); - Result = FolderOperations->CopyFrom( - MoveMode, - FolderPrefix, - &FileNamePointers.Front(), - FileNamePointers.Size(), - UpdateCallback); - } - catch(...) { Result = E_FAIL; } - } - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadUpdate *)param)->Process(); - return 0; - } -}; - -HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths, - bool showErrorMessages, UStringVector *messages) -{ - HRESULT res; - if (!_folderOperations) - res = E_NOINTERFACE; - else - { - CThreadUpdate updater; - updater.MoveMode = moveMode; - updater.UpdateCallbackSpec = new CUpdateCallback100Imp; - updater.UpdateCallback = updater.UpdateCallbackSpec; - updater.UpdateCallbackSpec->Init(); - - updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog; - - UString title = LangString(IDS_COPYING); - UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - - updater.ProgressDialog.MainWindow = GetParent(); - updater.ProgressDialog.MainTitle = progressWindowTitle; - updater.ProgressDialog.MainAddTitle = title + L' '; - - { - if (!_parentFolders.IsEmpty()) - { - const CFolderLink &fl = _parentFolders.Back(); - updater.UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; - updater.UpdateCallbackSpec->Password = fl.Password; - } - } - - updater.FolderOperations = _folderOperations; - updater.FolderPrefix = folderPrefix; - updater.FileNames.ClearAndReserve(filePaths.Size()); - unsigned i; - for (i = 0; i < filePaths.Size(); i++) - updater.FileNames.AddInReserved(filePaths[i]); - updater.FileNamePointers.ClearAndReserve(updater.FileNames.Size()); - for (i = 0; i < updater.FileNames.Size(); i++) - updater.FileNamePointers.AddInReserved(updater.FileNames[i]); - - NWindows::CThread thread; - RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater)); - updater.ProgressDialog.Create(title, thread, GetParent()); - - if (messages != 0) - *messages = updater.ProgressDialog.Sync.Messages; - - res = updater.Result; - } - - if (res == E_NOINTERFACE) - { - UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); - if (showErrorMessages) - MessageBox(errorMessage); - else if (messages != 0) - messages->Add(errorMessage); - return E_ABORT; - } - - RefreshTitleAlways(); - return res; -} - -void CPanel::CopyFromNoAsk(const UStringVector &filePaths) -{ - CDisableTimerProcessing disableTimerProcessing(*this); - - CSelectedState srcSelState; - SaveSelectedState(srcSelState); - - HRESULT result = CopyFrom(false, L"", filePaths, true, 0); - - CDisableNotify disableNotify(*this); - - if (result != S_OK) - { - disableNotify.Restore(); - // For Password: - SetFocusToList(); - if (result != E_ABORT) - MessageBoxError(result); - return; - } - - RefreshListCtrl(srcSelState); - - disableNotify.Restore(); - SetFocusToList(); -} - -void CPanel::CopyFromAsk(const UStringVector &filePaths) -{ - UString title = LangString(IDS_CONFIRM_FILE_COPY); - UString message = LangString(IDS_WANT_TO_COPY_FILES); - message += L"\n\'"; - message += _currentFolderPrefix; - message += L"\' ?"; - int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION); - if (res != IDYES) - return; - - CopyFromNoAsk(filePaths); -} +/// PanelCopy.cpp + +#include "StdAfx.h" + +#include "../Common/ZipRegistry.h" + +#include "../GUI/HashGUI.h" + +#include "FSFolder.h" +#include "ExtractCallback.h" +#include "LangUtils.h" +#include "Panel.h" +#include "UpdateCallback100.h" + +#include "resource.h" + + +class CPanelCopyThread: public CProgressThreadVirt +{ + bool ResultsWereShown; + bool NeedShowRes; + + HRESULT ProcessVirt() Z7_override; + virtual void ProcessWasFinished_GuiVirt() Z7_override; +public: + const CCopyToOptions *options; + const UStringVector *CopyFrom_Paths; + CMyComPtr FolderOperations; + CRecordVector Indices; + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + + CHashBundle Hash; + // UString FirstFilePath; + + // HRESULT Result2; + + void ShowFinalResults(HWND hwnd); + + CPanelCopyThread(): + ResultsWereShown(false), + NeedShowRes(false), + CopyFrom_Paths(NULL) + // , Result2(E_FAIL) + {} +}; + +void CPanelCopyThread::ShowFinalResults(HWND hwnd) +{ + if (NeedShowRes) + if (!ResultsWereShown) + { + ResultsWereShown = true; + ShowHashResults(Hash, hwnd); + } +} + +void CPanelCopyThread::ProcessWasFinished_GuiVirt() +{ + ShowFinalResults(*this); +} + +HRESULT CPanelCopyThread::ProcessVirt() +{ + /* + CMyComPtr iReplace; + FolderOperations.QueryInterface(IID_IFolderSetReplaceAltStreamCharsMode, &iReplace); + if (iReplace) + { + RINOK(iReplace->SetReplaceAltStreamCharsMode(ReplaceAltStreamChars ? 1 : 0)); + } + */ + + HRESULT result2; + + if (FolderOperations) + { + { + CMyComPtr setZoneMode; + FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode); + if (setZoneMode) + { + RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode)) + } + } + { + CMyComPtr setZoneFile; + FolderOperations.QueryInterface(IID_IFolderSetZoneIdFile, &setZoneFile); + if (setZoneFile) + { + RINOK(setZoneFile->SetZoneIdFile(options->ZoneBuf, (UInt32)options->ZoneBuf.Size())) + } + } + } + + if (CopyFrom_Paths) + { + result2 = NFsFolder::CopyFileSystemItems( + *CopyFrom_Paths, + us2fs(options->folder), + options->moveMode, + (IFolderOperationsExtractCallback *)ExtractCallbackSpec); + } + else if (options->testMode) + { + CMyComPtr archiveFolder; + FolderOperations.QueryInterface(IID_IArchiveFolder, &archiveFolder); + if (!archiveFolder) + return E_NOTIMPL; + CMyComPtr extractCallback2; + RINOK(ExtractCallback.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2)) + NExtract::NPathMode::EEnum pathMode = + NExtract::NPathMode::kCurPaths; + // NExtract::NPathMode::kFullPathnames; + result2 = archiveFolder->Extract(Indices.ConstData(), Indices.Size(), + BoolToInt(options->includeAltStreams), + BoolToInt(options->replaceAltStreamChars), + pathMode, NExtract::NOverwriteMode::kAsk, + options->folder, BoolToInt(true), extractCallback2); + } + else + result2 = FolderOperations->CopyTo( + BoolToInt(options->moveMode), + Indices.ConstData(), Indices.Size(), + BoolToInt(options->includeAltStreams), + BoolToInt(options->replaceAltStreamChars), + options->folder, ExtractCallback); + + if (result2 == S_OK && !ExtractCallbackSpec->ThereAreMessageErrors) + { + if (!options->hashMethods.IsEmpty()) + NeedShowRes = true; + else if (options->testMode) + { + CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); + AddHashBundleRes(pair.Message, Hash); + } + } + + return result2; +} + + +/* +#ifdef Z7_EXTERNAL_CODECS + +static void ThrowException_if_Error(HRESULT res) +{ + if (res != S_OK) + throw CSystemException(res); +} + +#endif +*/ + +void CPanel::Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf) +{ + // we suppose that ZoneId of top parent has priority over ZoneId from childs. + FOR_VECTOR (i, _parentFolders) + { + // _parentFolders[0] = is top level archive + // _parentFolders[1 ... ].isVirtual == true is possible + // if extracted size meets size conditions derived from g_RAM_Size. + const CFolderLink &fl = _parentFolders[i]; + if (fl.IsVirtual) + { + if (fl.ZoneBuf.Size() != 0) + { + buf = fl.ZoneBuf; + return; + } + } + else if (!fl.FilePath.IsEmpty()) + { + ReadZoneFile_Of_BaseFile(fl.FilePath, buf); + if (buf.Size() != 0) + return; + } + } +} + +HRESULT CPanel::CopyTo(CCopyToOptions &options, + const CRecordVector &indices, + UStringVector *messages, + bool &usePassword, UString &password, + const UStringVector *filePaths) +{ + 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 (options.ZoneBuf.Size() == 0 + && options.ZoneIdMode != NExtract::NZoneIdMode::kNone) + Get_ZoneId_Stream_from_ParentFolders(options.ZoneBuf); + + if (IsHashFolder()) + { + if (!options.testMode) + return E_NOTIMPL; + } + + if (!filePaths) + if (!_folderOperations) + { + const UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); + if (options.showErrorMessages) + MessageBox_Error(errorMessage); + else if (messages) + messages->Add(errorMessage); + return E_FAIL; + } + + HRESULT res = S_OK; + + { + /* + #ifdef Z7_EXTERNAL_CODECS + CExternalCodecs g_ExternalCodecs; + #endif + */ + /* extracter.Hash uses g_ExternalCodecs + extracter must be declared after g_ExternalCodecs for correct destructor order !!! */ + + CPanelCopyThread extracter; + + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + extracter.ExtractCallbackSpec->Src_Is_IO_FS_Folder = + IsFSFolder() || IsAltStreamsFolder(); + // options.src_Is_IO_FS_Folder; + extracter.options = &options; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter; + extracter.CompressingMode = false; + + extracter.ExtractCallbackSpec->StreamMode = options.streamMode; + + + if (indices.Size() == 1) + { + extracter.Hash.FirstFileName = GetItemRelPath(indices[0]); + extracter.Hash.MainName = extracter.Hash.FirstFileName; + } + + if (options.VirtFileSystemSpec) + { + extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystemSpec; + extracter.ExtractCallbackSpec->VirtFileSystemSpec = options.VirtFileSystemSpec; + } + extracter.ExtractCallbackSpec->ProcessAltStreams = options.includeAltStreams; + + if (!options.hashMethods.IsEmpty()) + { + /* this code is used when we call CRC calculation for files in side archive + But new code uses global codecs so we don't need to call LoadGlobalCodecs again */ + + /* + #ifdef Z7_EXTERNAL_CODECS + ThrowException_if_Error(LoadGlobalCodecs()); + #endif + */ + + extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS_G options.hashMethods); + extracter.ExtractCallbackSpec->SetHashMethods(&extracter.Hash); + } + else if (options.testMode) + { + extracter.ExtractCallbackSpec->SetHashCalc(&extracter.Hash); + } + + // extracter.Hash.Init(); + + UString title; + { + UInt32 titleID = IDS_COPYING; + if (options.moveMode) + titleID = IDS_MOVING; + else if (!options.hashMethods.IsEmpty() && options.streamMode) + { + titleID = IDS_CHECKSUM_CALCULATING; + if (options.hashMethods.Size() == 1) + { + const UString &s = options.hashMethods[0]; + if (!s.IsEqualTo("*")) + title = s; + } + } + else if (options.testMode) + titleID = IDS_PROGRESS_TESTING; + + if (title.IsEmpty()) + title = LangString(titleID); + } + + const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE); + + extracter.MainWindow = GetParent(); + extracter.MainTitle = progressWindowTitle; + extracter.MainAddTitle = title + L' '; + + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk; + extracter.ExtractCallbackSpec->Init(); + + extracter.CopyFrom_Paths = filePaths; + if (!filePaths) + { + extracter.Indices = indices; + extracter.FolderOperations = _folderOperations; + } + + extracter.ExtractCallbackSpec->PasswordIsDefined = usePassword; + extracter.ExtractCallbackSpec->Password = password; + + RINOK(extracter.Create(title, GetParent())) + + + if (messages) + *messages = extracter.Sync.Messages; + + // res = extracter.Result2; + res = extracter.Result; + + if (res == S_OK && extracter.ExtractCallbackSpec->IsOK()) + { + usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined; + password = extracter.ExtractCallbackSpec->Password; + } + + extracter.ShowFinalResults(_window); + + } + + RefreshTitleAlways(); + return res; +} + + +struct CThreadUpdate +{ + CMyComPtr FolderOperations; + UString FolderPrefix; + UStringVector FileNames; + CRecordVector FileNamePointers; + CProgressDialog ProgressDialog; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + bool MoveMode; + + void Process() + { + try + { + CProgressCloser closer(ProgressDialog); + Result = FolderOperations->CopyFrom( + MoveMode, + FolderPrefix, + FileNamePointers.ConstData(), + FileNamePointers.Size(), + UpdateCallback); + } + catch(...) { Result = E_FAIL; } + } + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + ((CThreadUpdate *)param)->Process(); + return 0; + } +}; + + +HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages) +{ + if (IsHashFolder()) + { + if (moveMode) + return E_NOTIMPL; + } + // CDisableNotify disableNotify(*this); + + HRESULT res; + if (!_folderOperations) + res = E_NOINTERFACE; + else + { + CThreadUpdate updater; + updater.MoveMode = moveMode; + updater.UpdateCallbackSpec = new CUpdateCallback100Imp; + updater.UpdateCallback = updater.UpdateCallbackSpec; + updater.UpdateCallbackSpec->Init(); + + updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog; + + const UString title = LangString(IDS_COPYING); + const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE); + + updater.ProgressDialog.MainWindow = GetParent(); + updater.ProgressDialog.MainTitle = progressWindowTitle; + updater.ProgressDialog.MainAddTitle = title + L' '; + + { + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &fl = _parentFolders.Back(); + updater.UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; + updater.UpdateCallbackSpec->Password = fl.Password; + } + } + + updater.FolderOperations = _folderOperations; + updater.FolderPrefix = folderPrefix; + updater.FileNames.ClearAndReserve(filePaths.Size()); + unsigned i; + for (i = 0; i < filePaths.Size(); i++) + updater.FileNames.AddInReserved(filePaths[i]); + updater.FileNamePointers.ClearAndReserve(updater.FileNames.Size()); + for (i = 0; i < updater.FileNames.Size(); i++) + updater.FileNamePointers.AddInReserved(updater.FileNames[i]); + + { + NWindows::CThread thread; + const WRes wres = thread.Create(CThreadUpdate::MyThreadFunction, &updater); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + updater.ProgressDialog.Create(title, thread, GetParent()); + } + + if (messages) + *messages = updater.ProgressDialog.Sync.Messages; + + res = updater.Result; + } + + if (res == E_NOINTERFACE) + { + const UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED); + if (showErrorMessages) + MessageBox_Error(errorMessage); + else if (messages) + messages->Add(errorMessage); + return E_ABORT; + } + + RefreshTitleAlways(); + return res; +} + +void CPanel::CopyFromNoAsk(bool moveMode, const UStringVector &filePaths) +{ + CDisableTimerProcessing disableTimerProcessing(*this); + + CSelectedState srcSelState; + SaveSelectedState(srcSelState); + + CDisableNotify disableNotify(*this); + + const HRESULT result = CopyFrom(moveMode, L"", filePaths, true, NULL); + + if (result != S_OK) + { + disableNotify.Restore(); + // For Password: + SetFocusToList(); + if (result != E_ABORT) + MessageBox_Error_HRESULT(result); + return; + } + + RefreshListCtrl(srcSelState); + + disableNotify.Restore(); + SetFocusToList(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelCrc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCrc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelCrc.cpp 2016-06-11 08:08:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelCrc.cpp 2023-03-20 13:03:00.000000000 +0000 @@ -1,386 +1,422 @@ -// PanelCrc.cpp - -#include "StdAfx.h" - -#include "../../../Common/MyException.h" - -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileIO.h" -#include "../../../Windows/FileName.h" - -#include "../Common/LoadCodecs.h" - -#include "../GUI/HashGUI.h" - -#include "App.h" -#include "LangUtils.h" - -#include "resource.h" - -using namespace NWindows; -using namespace NFile; - -#ifdef EXTERNAL_CODECS -extern CExternalCodecs g_ExternalCodecs; -HRESULT LoadGlobalCodecs(); -#endif - -static const UInt32 kBufSize = (1 << 15); - -struct CDirEnumerator -{ - bool EnterToDirs; - FString BasePrefix; - FString BasePrefix_for_Open; - FStringVector FilePaths; - - CObjectVector Enumerators; - FStringVector Prefixes; - unsigned Index; - - CDirEnumerator(): EnterToDirs(false), Index(0) {}; - - void Init(); - DWORD GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath); -}; - -void CDirEnumerator::Init() -{ - Enumerators.Clear(); - Prefixes.Clear(); - Index = 0; -} - -static DWORD GetNormalizedError() -{ - DWORD error = GetLastError(); - return (error == 0) ? E_FAIL : error; -} - -DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath) -{ - filled = false; - resPath.Empty(); - - for (;;) - { - #if defined(_WIN32) && !defined(UNDER_CE) - bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0)); - #endif - - if (Enumerators.IsEmpty()) - { - if (Index >= FilePaths.Size()) - return S_OK; - const FString &path = FilePaths[Index++]; - int pos = path.ReverseFind_PathSepar(); - if (pos >= 0) - resPath.SetFrom(path, pos + 1); - - #if defined(_WIN32) && !defined(UNDER_CE) - if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path)) - { - // we use "c:" item as directory item - fi.ClearBase(); - fi.Name = path; - fi.SetAsDir(); - fi.Size = 0; - } - else - #endif - if (!fi.Find(BasePrefix + path)) - { - DWORD error = GetNormalizedError(); - resPath = path; - return error; - } - - break; - } - - bool found; - - if (Enumerators.Back().Next(fi, found)) - { - if (found) - { - resPath = Prefixes.Back(); - break; - } - } - else - { - DWORD error = GetNormalizedError(); - resPath = Prefixes.Back(); - Enumerators.DeleteBack(); - Prefixes.DeleteBack(); - return error; - } - - Enumerators.DeleteBack(); - Prefixes.DeleteBack(); - } - - resPath += fi.Name; - - if (EnterToDirs && fi.IsDir()) - { - FString s = resPath; - s.Add_PathSepar(); - Prefixes.Add(s); - s += FCHAR_ANY_MASK; - Enumerators.Add(NFind::CEnumerator(BasePrefix + s)); - } - - filled = true; - return S_OK; -} - -class CThreadCrc: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - CDirEnumerator Enumerator; - CHashBundle Hash; - - void SetStatus(const UString &s); - void AddErrorMessage(DWORD systemError, const FChar *name); -}; - -void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name) -{ - ProgressDialog.Sync.AddError_Code_Name(systemError, fs2us(Enumerator.BasePrefix + name)); - Hash.NumErrors++; -} - -void CThreadCrc::SetStatus(const UString &s2) -{ - UString s = s2; - if (!Enumerator.BasePrefix.IsEmpty()) - { - s.Add_Space_if_NotEmpty(); - s += fs2us(Enumerator.BasePrefix); - } - ProgressDialog.Sync.Set_Status(s); -} - -HRESULT CThreadCrc::ProcessVirt() -{ - Hash.Init(); - - CMyBuffer buf; - if (!buf.Allocate(kBufSize)) - return E_OUTOFMEMORY; - - CProgressSync &sync = ProgressDialog.Sync; - - SetStatus(LangString(IDS_SCANNING)); - - Enumerator.Init(); - - FString path; - NFind::CFileInfo fi; - UInt64 numFiles = 0; - UInt64 numItems = 0, numItems_Prev = 0; - UInt64 totalSize = 0; - - for (;;) - { - bool filled; - DWORD error = Enumerator.GetNextFile(fi, filled, path); - if (error != 0) - { - AddErrorMessage(error, path); - continue; - } - if (!filled) - break; - if (!fi.IsDir()) - { - totalSize += fi.Size; - numFiles++; - } - numItems++; - bool needPrint = false; - // if (fi.IsDir()) - { - if (numItems - numItems_Prev >= 100) - { - needPrint = true; - numItems_Prev = numItems; - } - } - /* - else if (numFiles - numFiles_Prev >= 200) - { - needPrint = true; - numFiles_Prev = numFiles; - } - */ - if (needPrint) - { - RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir())); - } - } - RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false)); - // sync.SetNumFilesTotal(numFiles); - // sync.SetProgress(totalSize, 0); - // SetStatus(LangString(IDS_CHECKSUM_CALCULATING)); - // sync.SetCurFilePath(L""); - SetStatus(L""); - - Enumerator.Init(); - - FString tempPath; - FString firstFilePath; - bool isFirstFile = true; - UInt64 errorsFilesSize = 0; - - for (;;) - { - bool filled; - DWORD error = Enumerator.GetNextFile(fi, filled, path); - if (error != 0) - { - AddErrorMessage(error, path); - continue; - } - if (!filled) - break; - - error = 0; - Hash.InitForNewFile(); - if (!fi.IsDir()) - { - NIO::CInFile inFile; - tempPath = Enumerator.BasePrefix_for_Open; - tempPath += path; - if (!inFile.Open(tempPath)) - { - error = GetNormalizedError(); - AddErrorMessage(error, path); - continue; - } - if (isFirstFile) - { - firstFilePath = path; - isFirstFile = false; - } - sync.Set_FilePath(fs2us(path)); - sync.Set_NumFilesCur(Hash.NumFiles); - UInt64 progress_Prev = 0; - for (;;) - { - UInt32 size; - if (!inFile.Read(buf, kBufSize, size)) - { - error = GetNormalizedError(); - AddErrorMessage(error, path); - UInt64 errorSize = 0; - if (inFile.GetLength(errorSize)) - errorsFilesSize += errorSize; - break; - } - if (size == 0) - break; - Hash.Update(buf, size); - if (Hash.CurSize - progress_Prev >= ((UInt32)1 << 21)) - { - RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize + Hash.CurSize)); - progress_Prev = Hash.CurSize; - } - } - } - if (error == 0) - Hash.Final(fi.IsDir(), false, fs2us(path)); - RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); - } - RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); - sync.Set_NumFilesCur(Hash.NumFiles); - if (Hash.NumFiles != 1) - sync.Set_FilePath(L""); - SetStatus(L""); - - CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); - AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath)); - LangString(IDS_CHECKSUM_INFORMATION, pair.Title); - return S_OK; -} - - -HRESULT CApp::CalculateCrc2(const UString &methodName) -{ - unsigned srcPanelIndex = GetFocusedPanelIndex(); - CPanel &srcPanel = Panels[srcPanelIndex]; - - CRecordVector indices; - srcPanel.GetOperatedIndicesSmart(indices); - if (indices.IsEmpty()) - return S_OK; - - if (!srcPanel.Is_IO_FS_Folder()) - { - CCopyToOptions options; - options.streamMode = true; - options.showErrorMessages = true; - options.hashMethods.Add(methodName); - - UStringVector messages; - return srcPanel.CopyTo(options, indices, &messages); - } - - #ifdef EXTERNAL_CODECS - - LoadGlobalCodecs(); - - #endif - - { - CThreadCrc t; - { - UStringVector methods; - methods.Add(methodName); - RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods)); - } - FOR_VECTOR (i, indices) - t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); - - UString basePrefix = srcPanel.GetFsPath(); - UString basePrefix2 = basePrefix; - if (basePrefix2.Back() == ':') - { - int pos = basePrefix2.ReverseFind_PathSepar(); - if (pos >= 0) - basePrefix2.DeleteFrom(pos + 1); - } - - t.Enumerator.BasePrefix = us2fs(basePrefix); - t.Enumerator.BasePrefix_for_Open = us2fs(basePrefix2); - - t.Enumerator.EnterToDirs = !GetFlatMode(); - - t.ProgressDialog.ShowCompressionInfo = false; - - UString title = LangString(IDS_CHECKSUM_CALCULATING); - - t.ProgressDialog.MainWindow = _window; - t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - t.ProgressDialog.MainAddTitle = title; - t.ProgressDialog.MainAddTitle.Add_Space(); - - RINOK(t.Create(title, _window)); - } - RefreshTitleAlways(); - return S_OK; -} - -void CApp::CalculateCrc(const UString &methodName) -{ - HRESULT res = CalculateCrc2(methodName); - if (res != S_OK && res != E_ABORT) - { - unsigned srcPanelIndex = GetFocusedPanelIndex(); - CPanel &srcPanel = Panels[srcPanelIndex]; - srcPanel.MessageBoxError(res); - } -} +// PanelCrc.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyException.h" + +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileIO.h" +#include "../../../Windows/FileName.h" + +#include "../Common/LoadCodecs.h" + +#include "../GUI/HashGUI.h" + +#include "App.h" +#include "LangUtils.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; + +#ifdef Z7_EXTERNAL_CODECS +extern CExternalCodecs g_ExternalCodecs; +HRESULT LoadGlobalCodecs(); +#endif + +static const UInt32 kBufSize = (1 << 15); + +struct CDirEnumerator +{ + bool EnterToDirs; + FString BasePrefix; + FString BasePrefix_for_Open; + FStringVector FilePaths; + + CObjectVector Enumerators; + FStringVector Prefixes; + unsigned Index; + + CDirEnumerator(): EnterToDirs(false), Index(0) {} + + void Init(); + DWORD GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath); +}; + +void CDirEnumerator::Init() +{ + Enumerators.Clear(); + Prefixes.Clear(); + Index = 0; +} + +static DWORD GetNormalizedError() +{ + const DWORD error = GetLastError(); + return (error == 0) ? (DWORD)E_FAIL : error; +} + +DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath) +{ + filled = false; + resPath.Empty(); + + for (;;) + { + #if defined(_WIN32) && !defined(UNDER_CE) + bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0)); + #endif + + if (Enumerators.IsEmpty()) + { + if (Index >= FilePaths.Size()) + return S_OK; + const FString &path = FilePaths[Index++]; + const int pos = path.ReverseFind_PathSepar(); + if (pos >= 0) + resPath.SetFrom(path, (unsigned)pos + 1); + + #if defined(_WIN32) && !defined(UNDER_CE) + if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path)) + { + // we use "c:" item as directory item + fi.ClearBase(); + fi.Name = path; + fi.SetAsDir(); + fi.Size = 0; + } + else + #endif + if (!fi.Find(BasePrefix + path)) + { + const DWORD error = GetNormalizedError(); + resPath = path; + return error; + } + + break; + } + + bool found; + + if (Enumerators.Back().Next(fi, found)) + { + if (found) + { + resPath = Prefixes.Back(); + break; + } + } + else + { + const DWORD error = GetNormalizedError(); + resPath = Prefixes.Back(); + Enumerators.DeleteBack(); + Prefixes.DeleteBack(); + return error; + } + + Enumerators.DeleteBack(); + Prefixes.DeleteBack(); + } + + resPath += fi.Name; + + if (EnterToDirs && fi.IsDir()) + { + FString s = resPath; + s.Add_PathSepar(); + Prefixes.Add(s); + Enumerators.AddNew().SetDirPrefix(BasePrefix + s); + } + + filled = true; + return S_OK; +} + + + +class CThreadCrc: public CProgressThreadVirt +{ + bool ResultsWereShown; + bool WasFinished; + + HRESULT ProcessVirt() Z7_override; + virtual void ProcessWasFinished_GuiVirt() Z7_override; +public: + CDirEnumerator Enumerator; + CHashBundle Hash; + // FString FirstFilePath; + + void SetStatus(const UString &s); + void AddErrorMessage(DWORD systemError, const FChar *name); + void ShowFinalResults(HWND hwnd); + + CThreadCrc(): + ResultsWereShown(false), + WasFinished(false) + {} +}; + +void CThreadCrc::ShowFinalResults(HWND hwnd) +{ + if (WasFinished) + if (!ResultsWereShown) + { + ResultsWereShown = true; + ShowHashResults(Hash, hwnd); + } +} + +void CThreadCrc::ProcessWasFinished_GuiVirt() +{ + ShowFinalResults(*this); +} + +void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name) +{ + Sync.AddError_Code_Name(HRESULT_FROM_WIN32(systemError), fs2us(Enumerator.BasePrefix + name)); + Hash.NumErrors++; +} + +void CThreadCrc::SetStatus(const UString &s2) +{ + UString s = s2; + if (!Enumerator.BasePrefix.IsEmpty()) + { + s.Add_Space_if_NotEmpty(); + s += fs2us(Enumerator.BasePrefix); + } + Sync.Set_Status(s); +} + +HRESULT CThreadCrc::ProcessVirt() +{ + // Hash.Init(); + + CMyBuffer buf; + if (!buf.Allocate(kBufSize)) + return E_OUTOFMEMORY; + + CProgressSync &sync = Sync; + + SetStatus(LangString(IDS_SCANNING)); + + Enumerator.Init(); + + FString path; + NFind::CFileInfo fi; + UInt64 numFiles = 0; + UInt64 numItems = 0, numItems_Prev = 0; + UInt64 totalSize = 0; + + for (;;) + { + bool filled; + const DWORD error = Enumerator.GetNextFile(fi, filled, path); + if (error != 0) + { + AddErrorMessage(error, path); + continue; + } + if (!filled) + break; + if (!fi.IsDir()) + { + totalSize += fi.Size; + numFiles++; + } + numItems++; + bool needPrint = false; + // if (fi.IsDir()) + { + if (numItems - numItems_Prev >= 100) + { + needPrint = true; + numItems_Prev = numItems; + } + } + /* + else if (numFiles - numFiles_Prev >= 200) + { + needPrint = true; + numFiles_Prev = numFiles; + } + */ + if (needPrint) + { + RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir())) + } + } + RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false)) + // sync.SetNumFilesTotal(numFiles); + // sync.SetProgress(totalSize, 0); + // SetStatus(LangString(IDS_CHECKSUM_CALCULATING)); + // sync.SetCurFilePath(L""); + SetStatus(L""); + + Enumerator.Init(); + + FString tempPath; + bool isFirstFile = true; + UInt64 errorsFilesSize = 0; + + for (;;) + { + bool filled; + DWORD error = Enumerator.GetNextFile(fi, filled, path); + if (error != 0) + { + AddErrorMessage(error, path); + continue; + } + if (!filled) + break; + + error = 0; + Hash.InitForNewFile(); + if (!fi.IsDir()) + { + NIO::CInFile inFile; + tempPath = Enumerator.BasePrefix_for_Open; + tempPath += path; + if (!inFile.Open(tempPath)) + { + error = GetNormalizedError(); + AddErrorMessage(error, path); + continue; + } + if (isFirstFile) + { + Hash.FirstFileName = fs2us(path); + isFirstFile = false; + } + sync.Set_FilePath(fs2us(path)); + sync.Set_NumFilesCur(Hash.NumFiles); + UInt64 progress_Prev = 0; + for (;;) + { + UInt32 size; + if (!inFile.Read(buf, kBufSize, size)) + { + error = GetNormalizedError(); + AddErrorMessage(error, path); + UInt64 errorSize = 0; + if (inFile.GetLength(errorSize)) + errorsFilesSize += errorSize; + break; + } + if (size == 0) + break; + Hash.Update(buf, size); + if (Hash.CurSize - progress_Prev >= ((UInt32)1 << 21)) + { + RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize + Hash.CurSize)) + progress_Prev = Hash.CurSize; + } + } + } + if (error == 0) + Hash.Final(fi.IsDir(), false, fs2us(path)); + RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)) + } + RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)) + sync.Set_NumFilesCur(Hash.NumFiles); + if (Hash.NumFiles != 1) + sync.Set_FilePath(L""); + SetStatus(L""); + + CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); + WasFinished = true; + LangString(IDS_CHECKSUM_INFORMATION, pair.Title); + return S_OK; +} + + + +HRESULT CApp::CalculateCrc2(const UString &methodName) +{ + unsigned srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + + CRecordVector indices; + srcPanel.Get_ItemIndices_OperSmart(indices); + if (indices.IsEmpty()) + return S_OK; + + if (!srcPanel.Is_IO_FS_Folder()) + { + CCopyToOptions options; + options.streamMode = true; + options.showErrorMessages = true; + options.hashMethods.Add(methodName); + options.NeedRegistryZone = false; + + UStringVector messages; + return srcPanel.CopyTo(options, indices, &messages); + } + + #ifdef Z7_EXTERNAL_CODECS + + LoadGlobalCodecs(); + + #endif + + { + CThreadCrc t; + + { + UStringVector methods; + methods.Add(methodName); + RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods)) + } + + FOR_VECTOR (i, indices) + t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); + + if (t.Enumerator.FilePaths.Size() == 1) + t.Hash.MainName = fs2us(t.Enumerator.FilePaths[0]); + + UString basePrefix = srcPanel.GetFsPath(); + UString basePrefix2 = basePrefix; + if (basePrefix2.Back() == ':') + { + const int pos = basePrefix2.ReverseFind_PathSepar(); + if (pos >= 0) + basePrefix2.DeleteFrom((unsigned)(pos + 1)); + } + + t.Enumerator.BasePrefix = us2fs(basePrefix); + t.Enumerator.BasePrefix_for_Open = us2fs(basePrefix2); + + t.Enumerator.EnterToDirs = !GetFlatMode(); + + t.ShowCompressionInfo = false; + + const UString title = LangString(IDS_CHECKSUM_CALCULATING); + + t.MainWindow = _window; + t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + t.MainAddTitle = title; + t.MainAddTitle.Add_Space(); + + RINOK(t.Create(title, _window)) + + t.ShowFinalResults(_window); + } + + RefreshTitleAlways(); + return S_OK; +} + +void CApp::CalculateCrc(const char *methodName) +{ + HRESULT res = CalculateCrc2(UString(methodName)); + if (res != S_OK && res != E_ABORT) + { + unsigned srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + srcPanel.MessageBox_Error_HRESULT(res); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelDrag.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelDrag.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelDrag.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelDrag.cpp 2024-11-12 07:00:00.000000000 +0000 @@ -0,0 +1,3006 @@ +// PanelDrag.cpp + +#include "StdAfx.h" + +#ifdef UNDER_CE +#include +#endif + +#include "../../../../C/7zVersion.h" +#include "../../../../C/CpuArch.h" + +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/COM.h" +#include "../../../Windows/MemoryGlobal.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Shell.h" + +#include "../Common/ArchiveName.h" +#include "../Common/CompressCall.h" +#include "../Common/ExtractingFilePath.h" + +#include "MessagesDialog.h" + +#include "App.h" +#include "EnumFormatEtc.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +#include "resource.h" +#include "../Explorer/resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#define PRF(x) +#define PRF_W(x) +// #define PRF2(x) +#define PRF3(x) +#define PRF3_W(x) +#define PRF4(x) +// #define PRF4(x) OutputDebugStringA(x) +// #define PRF4_W(x) OutputDebugStringW(x) + +// #define SHOW_DEBUG_DRAG + +#ifdef SHOW_DEBUG_DRAG + +#define PRF_(x) { x; } + +static void Print_Point(const char *name, DWORD keyState, const POINTL &pt, DWORD effect) +{ + AString s (name); + s += " x="; s.Add_UInt32((unsigned)pt.x); + s += " y="; s.Add_UInt32((unsigned)pt.y); + s += " k="; s.Add_UInt32(keyState); + s += " e="; s.Add_UInt32(effect); + PRF4(s); +} + +#else + +#define PRF_(x) + +#endif + + +#define kTempDirPrefix FTEXT("7zE") + +// all versions: k_Format_7zip_SetTargetFolder format to transfer folder path from target to source +static LPCTSTR const k_Format_7zip_SetTargetFolder = TEXT("7-Zip::SetTargetFolder"); +// new v23 formats: +static LPCTSTR const k_Format_7zip_SetTransfer = TEXT("7-Zip::SetTransfer"); +static LPCTSTR const k_Format_7zip_GetTransfer = TEXT("7-Zip::GetTransfer"); + +/* + Win10: clipboard formats. + There are about 16K free ids (formats) per system that can be + registered with RegisterClipboardFormat() with different names. + Probably that 16K ids space is common for ids registering for both + formats: RegisterClipboardFormat(), and registered window classes: + RegisterClass(). But ids for window classes will be deleted from + the list after process finishing. And registered clipboard + formats probably will be deleted from the list only after reboot. +*/ + +// static bool const g_CreateArchive_for_Drag_from_7zip = false; +// static bool const g_CreateArchive_for_Drag_from_Explorer = true; + // = false; // for debug + +/* +How DoDragDrop() works: +{ + IDropSource::QueryContinueDrag() (keyState & MK_LBUTTON) != 0 + IDropTarget::Enter() + IDropSource::GiveFeedback() + IDropTarget::DragOver() + IDropSource::GiveFeedback() + + for() + { + IDropSource::QueryContinueDrag() (keyState & MK_LBUTTON) != 0 + IDropTarget::DragOver() (keyState & MK_LBUTTON) != 0 + IDropSource::GiveFeedback() + } + + { + // DoDragDrop() in Win10 before calling // QueryContinueDrag() + // with (*(keyState & MK_LBUTTON) == 0) probably calls: + // 1) IDropTarget::DragOver() with same point values (x,y), but (keyState & MK_LBUTTON) != 0) + // 2) IDropSource::GiveFeedback(). + // so DropSource can know exact GiveFeedback(effect) mode just before LBUTTON releasing. + + if (IDropSource::QueryContinueDrag() for (keyState & MK_LBUTTON) == 0 + returns DRAGDROP_S_DROP), it will call + IDropTarget::Drop() + } + or + { + IDropSource::QueryContinueDrag() + IDropTarget::DragLeave() + IDropSource::GiveFeedback(0) + } + or + { + if (IDropSource::QueryContinueDrag() + returns DRAGDROP_S_CANCEL) + IDropTarget::DragLeave() + } +} +*/ + + +// ---------- CDropTarget ---------- + +static const UInt32 k_Struct_Id_SetTranfer = 2; // it's our selected id +static const UInt32 k_Struct_Id_GetTranfer = 3; // it's our selected id + +static const UInt64 k_Program_Id = 1; // "7-Zip" + +enum E_Program_ISA +{ + k_Program_ISA_x86 = 2, + k_Program_ISA_x64 = 3, + k_Program_ISA_armt = 4, + k_Program_ISA_arm64 = 5, + k_Program_ISA_arm32 = 6, + k_Program_ISA_ia64 = 9 +}; + +#define k_Program_Ver ((MY_VER_MAJOR << 16) | MY_VER_MINOR) + + +// k_SourceFlags_* are flags that are sent from Source to Target + +static const UInt32 k_SourceFlags_DoNotProcessInTarget = 1 << 1; +/* Do not process in Target. Source will process operation instead of Target. + By default Target processes Drop opearation. */ +// static const UInt32 k_SourceFlags_ProcessInTarget = 1 << 2; + +static const UInt32 k_SourceFlags_DoNotWaitFinish = 1 << 3; +static const UInt32 k_SourceFlags_WaitFinish = 1 << 4; +/* usually Source needs WaitFinish, if temp files were created. */ + +static const UInt32 k_SourceFlags_TempFiles = 1 << 6; +static const UInt32 k_SourceFlags_NamesAreParent = 1 << 7; +/* if returned path list for GetData(CF_HDROP) contains + path of parent temp folder instead of final paths of items + that will be extracted later from archive */ + +static const UInt32 k_SourceFlags_SetTargetFolder = 1 << 8; +/* SetData::("SetTargetFolder") was called (with empty or non-empty string) */ + +static const UInt32 k_SourceFlags_SetTargetFolder_NonEmpty = 1 << 9; +/* SetData::("SetTargetFolder") was called with non-empty string */ + +static const UInt32 k_SourceFlags_NeedExtractOpToFs = 1 << 10; + +static const UInt32 k_SourceFlags_Copy_WasCalled = 1 << 11; + +static const UInt32 k_SourceFlags_LeftButton = 1 << 14; +static const UInt32 k_SourceFlags_RightButton = 1 << 15; + + +static const UInt32 k_TargetFlags_WasCanceled = 1 << 0; +static const UInt32 k_TargetFlags_MustBeProcessedBySource = 1 << 1; +static const UInt32 k_TargetFlags_WasProcessed = 1 << 2; +static const UInt32 k_TargetFlags_DoNotWaitFinish = 1 << 3; +static const UInt32 k_TargetFlags_WaitFinish = 1 << 4; +static const UInt32 k_TargetFlags_MenuWasShown = 1 << 16; + +struct CDataObject_TransferBase +{ + UInt32 Struct_Id; + UInt32 Struct_Size; + + UInt64 Program_Id; + UInt32 Program_Ver_Main; + UInt32 Program_Ver_Build; + UInt32 Program_ISA; + UInt32 Program_Flags; + + UInt32 ProcessId; + UInt32 _reserved1[7]; + +protected: + void Init_Program(); +}; + + +void CDataObject_TransferBase::Init_Program() +{ + Program_Id = k_Program_Id; + Program_ISA = + #if defined(MY_CPU_AMD64) + k_Program_ISA_x64 + #elif defined(MY_CPU_X86) + k_Program_ISA_x86 + #elif defined(MY_CPU_ARM64) + k_Program_ISA_arm64 + #elif defined(MY_CPU_ARM32) + k_Program_ISA_arm32 + #elif defined(MY_CPU_ARMT) || defined(MY_CPU_ARM) + k_Program_ISA_armt + #elif defined(MY_CPU_IA64) + k_Program_ISA_ia64 + #else + 0 + #endif + ; + Program_Flags = sizeof(size_t); + Program_Ver_Main = k_Program_Ver; + // Program_Ver_Build = 0; + ProcessId = GetCurrentProcessId(); +} + + +#if defined(__GNUC__) && !defined(__clang__) +/* 'void* memset(void*, int, size_t)' clearing an object + of non-trivial type 'struct CDataObject_SetTransfer' */ +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + + +struct CDataObject_GetTransfer: +public CDataObject_TransferBase +{ + UInt32 Flags; + + UInt32 _reserved2[11]; + + CDataObject_GetTransfer() + { + memset(this, 0, sizeof(*this)); + Init_Program(); + Struct_Id = k_Struct_Id_GetTranfer; + Struct_Size = sizeof(*this); + } + + bool Check() const + { + return Struct_Size >= sizeof(*this) && Struct_Id == k_Struct_Id_GetTranfer; + } +}; + + +enum Enum_FolderType +{ + k_FolderType_None, + k_FolderType_Unknown = 1, + k_FolderType_Fs = 2, + k_FolderType_AltStreams = 3, + k_FolderType_Archive = 4 +}; + +struct CTargetTransferInfo +{ + UInt32 Flags; + UInt32 FuncType; + + UInt32 KeyState; + UInt32 OkEffects; + POINTL Point; + + UInt32 Cmd_Effect; + UInt32 Cmd_Type; + UInt32 FolderType; + UInt32 _reserved3[3]; + + CTargetTransferInfo() + { + memset(this, 0, sizeof(*this)); + } +}; + +struct CDataObject_SetTransfer: +public CDataObject_TransferBase +{ + CTargetTransferInfo Target; + + void Init() + { + memset(this, 0, sizeof(*this)); + Init_Program(); + Struct_Id = k_Struct_Id_SetTranfer; + Struct_Size = sizeof(*this); + } + + bool Check() const + { + return Struct_Size >= sizeof(*this) && Struct_Id == k_Struct_Id_SetTranfer; + } +}; + + + + + +enum Enum_DragTargetMode +{ + k_DragTargetMode_None = 0, + k_DragTargetMode_Leave = 1, + k_DragTargetMode_Enter = 2, + k_DragTargetMode_Over = 3, + k_DragTargetMode_Drop_Begin = 4, + k_DragTargetMode_Drop_End = 5 +}; + + +// ---- menu ---- + +namespace NDragMenu { + +enum Enum_CmdId +{ + k_None = 0, + k_Cancel = 1, + k_Copy_Base = 2, // to fs + k_Copy_ToArc = 3, + k_AddToArc = 4 + /* + k_OpenArc = 8, + k_TestArc = 9, + k_ExtractFiles = 10, + k_ExtractHere = 11 + */ +}; + +struct CCmdLangPair +{ + unsigned CmdId_and_Flags; + unsigned LangId; +}; + +static const UInt32 k_MenuFlags_CmdMask = (1 << 7) - 1; +static const UInt32 k_MenuFlag_Copy = 1 << 14; +static const UInt32 k_MenuFlag_Move = 1 << 15; +// #define IDS_CANCEL (IDCANCEL + 400) +#define IDS_CANCEL 402 + +static const CCmdLangPair g_Pairs[] = +{ + { k_Copy_Base | k_MenuFlag_Copy, IDS_COPY }, + { k_Copy_Base | k_MenuFlag_Move, IDS_MOVE }, + { k_Copy_ToArc | k_MenuFlag_Copy, IDS_COPY_TO }, + // { k_Copy_ToArc | k_MenuFlag_Move, IDS_MOVE_TO }, // IDS_CONTEXT_COMPRESS_TO + // { k_OpenArc, IDS_CONTEXT_OPEN }, + // { k_ExtractFiles, IDS_CONTEXT_EXTRACT }, + // { k_ExtractHere, IDS_CONTEXT_EXTRACT_HERE }, + // { k_TestArc, IDS_CONTEXT_TEST }, + { k_AddToArc | k_MenuFlag_Copy, IDS_CONTEXT_COMPRESS }, + { k_Cancel, IDS_CANCEL } +}; + +} + + +class CDropTarget Z7_final: + public IDropTarget, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1_MT(IDropTarget) + STDMETHOD(DragEnter)(IDataObject *dataObject, DWORD keyState, POINTL pt, DWORD *effect) Z7_override; + STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD *effect) Z7_override; + STDMETHOD(DragLeave)() Z7_override; + STDMETHOD(Drop)(IDataObject *dataObject, DWORD keyState, POINTL pt, DWORD *effect) Z7_override; + + bool m_IsRightButton; + bool m_GetTransfer_WasSuccess; + bool m_DropIsAllowed; // = true, if data IDataObject can return CF_HDROP (so we can get list of paths) + bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel. + // check it only if m_DropIsAllowed == true + // we use it to show icon effect that drop is not allowed here. + + CMyComPtr m_DataObject; // we set it in DragEnter() + UStringVector m_SourcePaths; + + // int m_DropHighlighted_SelectionIndex; + // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item) + // UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder) + + CPanel *m_Panel; + bool m_IsAppTarget; // true, if we want to drop to app window (not to panel) + + bool m_TargetPath_WasSent_ToDataObject; // true, if TargetPath was sent + bool m_TargetPath_NonEmpty_WasSent_ToDataObject; // true, if non-empty TargetPath was sent + bool m_Transfer_WasSent_ToDataObject; // true, if Transfer was sent + UINT m_Format_7zip_SetTargetFolder; + UINT m_Format_7zip_SetTransfer; + UINT m_Format_7zip_GetTransfer; + + UInt32 m_ProcessId; // for sending + + bool IsItSameDrive() const; + + // void Try_QueryGetData(IDataObject *dataObject); + void LoadNames_From_DataObject(IDataObject *dataObject); + + UInt32 GetFolderType() const; + bool IsFsFolderPath() const; + DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect) const; + void RemoveSelection(); + void PositionCursor(const POINTL &ptl); + UString GetTargetPath() const; + bool SendToSource_TargetPath_enable(IDataObject *dataObject, bool enablePath); + bool SendToSource_UInt32(IDataObject *dataObject, UINT format, UInt32 value); + bool SendToSource_TransferInfo(IDataObject *dataObject, + const CTargetTransferInfo &info); + void SendToSource_auto(IDataObject *dataObject, + const CTargetTransferInfo &info); + void SendToSource_Drag(CTargetTransferInfo &info) + { + SendToSource_auto(m_DataObject, info); + } + + void ClearState(); + +public: + CDropTarget(); + + CApp *App; + int SrcPanelIndex; // index of D&D source_panel + int TargetPanelIndex; // what panel to use as target_panel of Application +}; + + + + +// ---------- CDataObject ---------- + +/* + Some programs (like Sticky Notes in Win10) do not like + virtual non-existing items (files/dirs) in CF_HDROP format. + So we use two versions of CF_HDROP data: + m_hGlobal_HDROP_Pre : the list contains only destination path of temp directory. + That directory later will be filled with extracted items. + m_hGlobal_HDROP_Final : the list contains paths of all root items that + will be created in temp directory by archive extraction operation, + or the list of existing fs items, if source is filesystem directory. + + The DRAWBACK: some programs (like Edge in Win10) can use names from IDataObject::GetData() + call that was called before IDropSource::QueryContinueDrag() where we set (UseFinalGlobal = true) + So such programs will use non-relevant m_hGlobal_HDROP_Pre item, + instead of m_hGlobal_HDROP_Final items. +*/ + +class CDataObject Z7_final: + public IDataObject, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1_MT(IDataObject) + + Z7_COMWF_B GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM medium) Z7_override; + Z7_COMWF_B GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM medium) Z7_override; + Z7_COMWF_B QueryGetData(LPFORMATETC pformatetc) Z7_override; + + Z7_COMWF_B GetCanonicalFormatEtc(LPFORMATETC /* pformatetc */, LPFORMATETC pformatetcOut) Z7_override + { + if (!pformatetcOut) + return E_INVALIDARG; + pformatetcOut->ptd = NULL; + return E_NOTIMPL; + } + + Z7_COMWF_B SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release) Z7_override; + Z7_COMWF_B EnumFormatEtc(DWORD drection, LPENUMFORMATETC *enumFormatEtc) Z7_override; + + Z7_COMWF_B DAdvise(FORMATETC * /* etc */, DWORD /* advf */, LPADVISESINK /* pAdvSink */, DWORD * /* pdwConnection */) Z7_override + { return OLE_E_ADVISENOTSUPPORTED; } + Z7_COMWF_B DUnadvise(DWORD /* dwConnection */) Z7_override + { return OLE_E_ADVISENOTSUPPORTED; } + Z7_COMWF_B EnumDAdvise(LPENUMSTATDATA *ppenumAdvise) Z7_override + { + if (ppenumAdvise) + *ppenumAdvise = NULL; + return OLE_E_ADVISENOTSUPPORTED; + } + + bool m_PerformedDropEffect_WasSet; + bool m_LogicalPerformedDropEffect_WasSet; + bool m_DestDirPrefix_FromTarget_WasSet; +public: + bool m_Transfer_WasSet; +private: + // GetData formats (source to target): + FORMATETC m_Etc; + // UINT m_Format_FileOpFlags; + // UINT m_Format_PreferredDropEffect; + + // SetData() formats (target to source): + // 7-Zip's format: + UINT m_Format_7zip_SetTargetFolder; + UINT m_Format_7zip_SetTransfer; + UINT m_Format_7zip_GetTransfer; // for GetData() + + UINT m_Format_PerformedDropEffect; + UINT m_Format_LogicalPerformedDropEffect; + UINT m_Format_DisableDragText; + UINT m_Format_IsShowingLayered; + UINT m_Format_IsShowingText; + UINT m_Format_DropDescription; + UINT m_Format_TargetCLSID; + + DWORD m_PerformedDropEffect; + DWORD m_LogicalPerformedDropEffect; + + void CopyFromPanelTo_Folder(); + HRESULT SetData2(const FORMATETC *formatetc, const STGMEDIUM *medium); + +public: + bool IsRightButton; + bool IsTempFiles; + + bool UsePreGlobal; + bool DoNotProcessInTarget; + + bool NeedCall_Copy; + bool Copy_WasCalled; + + NMemory::CGlobal m_hGlobal_HDROP_Pre; + NMemory::CGlobal m_hGlobal_HDROP_Final; + // NMemory::CGlobal m_hGlobal_FileOpFlags; + // NMemory::CGlobal m_hGlobal_PreferredDropEffect; + + CPanel *Panel; + CRecordVector Indices; + + UString SrcDirPrefix_Temp; // FS directory with source files or Temp + UString DestDirPrefix_FromTarget; + /* destination Path that was sent by Target via SetData(). + it can be altstreams prefix. + if (!DestDirPrefix_FromTarget.IsEmpty()) m_Panel->CompressDropFiles() was not called by Target. + So we must do drop actions in Source */ + HRESULT Copy_HRESULT; + UStringVector Messages; + + CDataObject(); +public: + CDataObject_SetTransfer m_Transfer; +}; + + +// for old mingw: +#ifndef CFSTR_LOGICALPERFORMEDDROPEFFECT +#define CFSTR_LOGICALPERFORMEDDROPEFFECT TEXT("Logical Performed DropEffect") +#endif +#ifndef CFSTR_TARGETCLSID +#define CFSTR_TARGETCLSID TEXT("TargetCLSID") // HGLOBAL with a CLSID of the drop target +#endif + + + +CDataObject::CDataObject() +{ + // GetData formats (source to target): + // and we use CF_HDROP format to transfer file paths from source to target: + m_Etc.cfFormat = CF_HDROP; + m_Etc.ptd = NULL; + m_Etc.dwAspect = DVASPECT_CONTENT; + m_Etc.lindex = -1; + m_Etc.tymed = TYMED_HGLOBAL; + + // m_Format_FileOpFlags = RegisterClipboardFormat(TEXT("FileOpFlags")); + // m_Format_PreferredDropEffect = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT); // "Preferred DropEffect" + + // SetData() formats (target to source): + m_Format_7zip_SetTargetFolder = RegisterClipboardFormat(k_Format_7zip_SetTargetFolder); + m_Format_7zip_SetTransfer = RegisterClipboardFormat(k_Format_7zip_SetTransfer); + m_Format_7zip_GetTransfer = RegisterClipboardFormat(k_Format_7zip_GetTransfer); + + m_Format_PerformedDropEffect = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); // "Performed DropEffect" + m_Format_LogicalPerformedDropEffect = RegisterClipboardFormat(CFSTR_LOGICALPERFORMEDDROPEFFECT); // "Logical Performed DropEffect" + m_Format_DisableDragText = RegisterClipboardFormat(TEXT("DisableDragText")); + m_Format_IsShowingLayered = RegisterClipboardFormat(TEXT("IsShowingLayered")); + m_Format_IsShowingText = RegisterClipboardFormat(TEXT("IsShowingText")); + m_Format_DropDescription = RegisterClipboardFormat(TEXT("DropDescription")); + m_Format_TargetCLSID = RegisterClipboardFormat(CFSTR_TARGETCLSID); + + m_PerformedDropEffect = 0; + m_LogicalPerformedDropEffect = 0; + + m_PerformedDropEffect_WasSet = false; + m_LogicalPerformedDropEffect_WasSet = false; + + m_DestDirPrefix_FromTarget_WasSet = false; + m_Transfer_WasSet = false; + + IsRightButton = false; + IsTempFiles = false; + + UsePreGlobal = false; + DoNotProcessInTarget = false; + + NeedCall_Copy = false; + Copy_WasCalled = false; + + Copy_HRESULT = S_OK; +} + + + +void CDataObject::CopyFromPanelTo_Folder() +{ + try + { + CCopyToOptions options; + options.folder = SrcDirPrefix_Temp; + /* 15.13: fixed problem with mouse cursor for password window. + DoDragDrop() probably calls SetCapture() to some hidden window. + But it's problem, if we show some modal window, like MessageBox. + So we return capture to our window. + If you know better way to solve the problem, please notify 7-Zip developer. + */ + // MessageBoxW(*Panel, L"test", L"test", 0); + /* HWND oldHwnd = */ SetCapture(*Panel); + Copy_WasCalled = true; + Copy_HRESULT = E_FAIL; + Copy_HRESULT = Panel->CopyTo(options, Indices, &Messages); + // do we need to restore capture? + // ReleaseCapture(); + // oldHwnd = SetCapture(oldHwnd); + } + catch(...) + { + Copy_HRESULT = E_FAIL; + } +} + + +#ifdef SHOW_DEBUG_DRAG + +static void PrintFormat2(AString &s, unsigned format) +{ + s += " "; + s += "= format="; + s.Add_UInt32(format); + s += " "; + const int k_len = 512; + CHAR temp[k_len]; + if (GetClipboardFormatNameA(format, temp, k_len) && strlen(temp) != 0) + s += temp; +} + +static void PrintFormat(const char *title, unsigned format) +{ + AString s (title); + PrintFormat2(s, format); + PRF4(s); +} + +static void PrintFormat_AndData(const char *title, unsigned format, const void *data, size_t size) +{ + AString s (title); + PrintFormat2(s, format); + s += " size="; + s.Add_UInt32((UInt32)size); + for (size_t i = 0; i < size && i < 16; i++) + { + s += " "; + s.Add_UInt32(((const Byte *)data)[i]); + } + PRF4(s); +} + +static void PrintFormat_GUIDToStringW(const void *p) +{ + const GUID *guid = (const GUID *)p; + UString s; + const unsigned kSize = 48; + StringFromGUID2(*guid, s.GetBuf(kSize), kSize); + s.ReleaseBuf_CalcLen(kSize); + PRF3_W(s); +} + +// Vista +typedef enum +{ + MY_DROPIMAGE_INVALID = -1, // no image preference (use default) + MY_DROPIMAGE_NONE = 0, // red "no" circle + MY_DROPIMAGE_COPY = DROPEFFECT_COPY, // plus for copy + MY_DROPIMAGE_MOVE = DROPEFFECT_MOVE, // movement arrow for move + MY_DROPIMAGE_LINK = DROPEFFECT_LINK, // link arrow for link + MY_DROPIMAGE_LABEL = 6, // tag icon to indicate metadata will be changed + MY_DROPIMAGE_WARNING = 7, // yellow exclamation, something is amiss with the operation + MY_DROPIMAGE_NOIMAGE = 8 // no image at all +} MY_DROPIMAGETYPE; + +typedef struct { + MY_DROPIMAGETYPE type; + WCHAR szMessage[MAX_PATH]; + WCHAR szInsert[MAX_PATH]; +} MY_DROPDESCRIPTION; + +#endif + + +/* +IDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release) +====================================================================== + + Main purpose of CDataObject is to transfer data from source to target + of drag and drop operation. + But also CDataObject can be used to transfer data in backward direction + from target to source (even if target and source are different processes). + There are some predefined Explorer's formats to transfer some data from target to source. + And 7-Zip uses 7-Zip's format k_Format_7zip_SetTargetFolder to transfer + destination directory path from target to source. + + Our CDataObject::SetData() function here is used only to transfer data from target to source. + Usual source_to_target data is filled to m_hGlobal_* objects directly without SetData() calling. + +The main problem of SetData() is ownership of medium for (release == TRUE) case. + +SetData(,, release = TRUE) from different processes (DropSource and DropTarget) +=============================================================================== +{ + MS DOCs about (STGMEDIUM *medium) ownership: + The data object called does not take ownership of the data + until it has successfully received it and no error code is returned. + + Each of processes (Source and Target) has own copy of medium allocated. + Windows code creates proxy IDataObject object in Target process to transferr + SetData() call between Target and Source processes via special proxies: + DropTarget -> + proxy_DataObject_in_Target -> + proxy_in_Source -> + DataObject_in_Source + when Target calls SetData() with proxy_DataObject_in_Target, + the system and proxy_in_Source + - allocates proxy-medium-in-Source process + - copies medium data from Target to that proxy-medium-in-Source + - sends proxy-medium-in-Source to DataObject_in_Source->SetData(). + + after returning from SetData() to Target process: + Win10 proxy_DataObject_in_Target releases original medium in Target process, + only if SetData() in Source returns S_OK. It's consistent with DOCs above. + + for unsupported cfFormat: + [DropSource is 7-Zip 22.01 (old) : (etc->cfFormat != m_Format_7zip_SetTargetFolder && release == TRUE)] + (DropSource is WinRAR case): + Source doesn't release medium and returns error (for example, E_NOTIMPL) + { + Then Win10 proxy_in_Source also doesn't release proxy-medium-in-Source. + So there is memory leak in Source process. + Probably Win10 proxy_in_Source tries to avoid possible double releasing + that can be more fatal than memory leak. + + Then Win10 proxy_DataObject_in_Target also doesn't release + original medium, that was allocated by DropTarget. + So if DropTarget also doesn't release medium, there is memory leak in + DropTarget process too. + DropTarget is Win10-Explorer probably doesn't release medium in that case. + } + + [DropSource is 7-Zip 22.01 (old) : (etc->cfFormat == m_Format_7zip_SetTargetFolder && release == TRUE)] + DropSource returns S_OK and doesn't release medium: + { + then there is memory leak in DropSource process only. + } + + (DropSource is 7-Zip v23 (new)): + (DropSource is Win10-Explorer case) + { + Win10-Explorer-DropSource probably always releases medium, + and then it always returns S_OK. + So Win10 proxy_DataObject_in_Target also releases + original medium, that was allocated by DropTarget. + So there is no memory leak in Source and Target processes. + } + + if (DropTarget is Win10-Explorer) + { + Explorer Target uses SetData(,, (release = TRUE)) and + Explorer Target probably doesn't free memory after SetData(), + even if SetData(,, (release = TRUE)) returns E_NOTIMPL; + } + + if (DropSource is Win10-Explorer) + { + (release == FALSE) doesn't work, and SetData() returns E_NOTIMPL; + (release == TRUE) works, and SetData() returns S_OK, and + it returns S_OK even for formats unsupported by Explorer. + } + + To be more compatible with DOCs and Win10-Explorer and to avoid memory leaks, + we use the following scheme for our IDataObject::SetData(,, release == TRUE) + in DropSource code: + if (release == TRUE) { our SetData() always releases medium + with ReleaseStgMedium() and returns S_OK; } + The DRAWBACK of that scheme: + The caller always receives S_OK, + so the caller doesn't know about any error in SetData() in that case. + +for 7zip-Target to 7zip-Source calls: + we use (release == FALSE) + So we avoid (release == TRUE) memory leak problems, + and we can get real return code from SetData(). + +for 7zip-Target to Explorer-Source calls: + we use (release == TRUE). + beacuse Explorer-Source doesn't accept (release == FALSE). +} +*/ + +/* +https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/shell/datascenarios.md +CFSTR_PERFORMEDDROPEFFECT: + is used by the target to inform the data object through its + IDataObject::SetData method of the outcome of a data transfer. +CFSTR_PREFERREDDROPEFFECT: + is used by the source to specify whether its preferred method of data transfer is move or copy. +*/ + +Z7_COMWF_B CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release) +{ + try { + const HRESULT hres = SetData2(etc, medium); + // PrintFormat(release ? "SetData RELEASE=TRUE" : "SetData RELEASE=FALSE" , etc->cfFormat); + if (release) + { + /* + const DWORD tymed = medium->tymed; + IUnknown *pUnkForRelease = medium->pUnkForRelease; + */ + // medium->tymed = NULL; // for debug + // return E_NOTIMPL; // for debug + ReleaseStgMedium(medium); + /* ReleaseStgMedium() will change STGMEDIUM::tymed to (TYMED_NULL = 0). + but we also can clear (medium.hGlobal = NULL), + to prevent some incorrect releasing, if the caller will try to release the data */ + /* + if (medium->tymed == TYMED_NULL && tymed == TYMED_HGLOBAL && !pUnkForRelease) + medium->hGlobal = NULL; + */ + // do we need return S_OK; for (tymed != TYMED_HGLOBAL) cases ? + /* we return S_OK here to shows that we take ownership of the data in (medium), + so the caller will not try to release (medium) */ + return S_OK; // to be more compatible with Win10-Explorer and DOCs. + } + return hres; + } catch(...) { return E_FAIL; } +} + + + +HRESULT CDataObject::SetData2(const FORMATETC *etc, const STGMEDIUM *medium) +{ + // PRF3("== CDataObject::SetData()"); + + HRESULT hres = S_OK; + + if (etc->cfFormat == 0) + return DV_E_FORMATETC; + if (etc->tymed != TYMED_HGLOBAL) + return E_NOTIMPL; // DV_E_TYMED; + if (etc->dwAspect != DVASPECT_CONTENT) + return E_NOTIMPL; // DV_E_DVASPECT; + if (medium->tymed != TYMED_HGLOBAL) + return E_NOTIMPL; // DV_E_TYMED; + + if (!medium->hGlobal) + return S_OK; + + if (etc->cfFormat == m_Format_7zip_SetTargetFolder) + { + DestDirPrefix_FromTarget.Empty(); + m_DestDirPrefix_FromTarget_WasSet = true; + } + else if (etc->cfFormat == m_Format_7zip_SetTransfer) + m_Transfer_WasSet = false; + + const size_t size = GlobalSize(medium->hGlobal); + // GlobalLock() can return NULL, if memory block has a zero size + if (size == 0) + return S_OK; + const void *src = (const Byte *)GlobalLock(medium->hGlobal); + if (!src) + return E_FAIL; + + PRF_(PrintFormat_AndData("SetData", etc->cfFormat, src, size)) + + if (etc->cfFormat == m_Format_7zip_SetTargetFolder) + { + /* this is our registered k_Format_7zip_SetTargetFolder format. + so it's call from 7-zip's CDropTarget */ + /* 7-zip's CDropTarget calls SetData() for m_Format_7zip_SetTargetFolder + with (release == FALSE) */ + const size_t num = size / sizeof(wchar_t); + if (size != num * sizeof(wchar_t)) + return E_FAIL; + // if (num == 0) return S_OK; + // GlobalLock() can return NULL, if memory block has a zero-byte size + const wchar_t *s = (const wchar_t *)src; + UString &dest = DestDirPrefix_FromTarget; + for (size_t i = 0; i < num; i++) + { + const wchar_t c = s[i]; + if (c == 0) + break; + dest += c; + } + // PRF_(PrintFormat_AndData("SetData", etc->cfFormat, src, size)) + PRF3_W(DestDirPrefix_FromTarget); + } + else if (etc->cfFormat == m_Format_7zip_SetTransfer) + { + /* 7-zip's CDropTarget calls SetData() for m_Format_7zip_SetTransfer + with (release == FALSE) */ + if (size < sizeof(CDataObject_SetTransfer)) + return E_FAIL; + const CDataObject_SetTransfer *t = (const CDataObject_SetTransfer *)src; + if (!t->Check()) + return E_FAIL; + m_Transfer = *t; + if (t->Target.FuncType != k_DragTargetMode_Leave) + m_Transfer_WasSet = true; + bool needProcessBySource = !DestDirPrefix_FromTarget.IsEmpty(); + if (t->Target.FuncType == k_DragTargetMode_Drop_Begin) + { + if (t->Target.Cmd_Type != NDragMenu::k_Copy_Base + // || t->Target.Cmd_Effect != DROPEFFECT_COPY + ) + needProcessBySource = false; + } + if (t->Target.FuncType == k_DragTargetMode_Drop_End) + { + if (t->Target.Flags & k_TargetFlags_MustBeProcessedBySource) + needProcessBySource = true; + else if (t->Target.Flags & k_TargetFlags_WasProcessed) + needProcessBySource = false; + } + DoNotProcessInTarget = needProcessBySource; + } + else + { + // SetData() from Explorer Target: + if (etc->cfFormat == m_Format_PerformedDropEffect) + { + m_PerformedDropEffect_WasSet = false; + if (size == sizeof(DWORD)) + { + m_PerformedDropEffect = *(const DWORD *)src; + m_PerformedDropEffect_WasSet = true; + } + } + else if (etc->cfFormat == m_Format_LogicalPerformedDropEffect) + { + m_LogicalPerformedDropEffect_WasSet = false; + if (size == sizeof(DWORD)) + { + m_LogicalPerformedDropEffect = *(const DWORD *)src; + m_LogicalPerformedDropEffect_WasSet = true; + } + } + else if (etc->cfFormat == m_Format_DropDescription) + { + // drop description contains only name of dest folder without full path + #ifdef SHOW_DEBUG_DRAG + if (size == sizeof(MY_DROPDESCRIPTION)) + { + // const MY_DROPDESCRIPTION *s = (const MY_DROPDESCRIPTION *)src; + // PRF3_W(s->szMessage); + // PRF3_W(s->szInsert); + } + #endif + } + else if (etc->cfFormat == m_Format_TargetCLSID) + { + // it's called after call QueryContinueDrag() (keyState & MK_LBUTTON) == 0 + // Shell File System Folder (explorer) guid: F3364BA0-65B9-11CE-A9BA-00AA004AE837 + #ifdef SHOW_DEBUG_DRAG + if (size == 16) + { + PrintFormat_GUIDToStringW((const Byte *)src); + } + #endif + } + else if (etc->cfFormat == m_Format_DisableDragText) + { + // (size == 4) (UInt32 value) + // value==0 : if drag to folder item or folder + // value==1 : if drag to file or non list_view */ + } + else if ( + etc->cfFormat == m_Format_IsShowingLayered || + etc->cfFormat == m_Format_IsShowingText) + { + // (size == 4) (UInt32 value) value==0 : + } + else + hres = DV_E_FORMATETC; + // hres = E_NOTIMPL; // for debug + // hres = DV_E_FORMATETC; // for debug + } + + GlobalUnlock(medium->hGlobal); + return hres; +} + + + +static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal) +{ + /* GlobalSize() returns 0: If the specified handle + is not valid or if the object has been discarded */ + const SIZE_T size = GlobalSize(srcGlobal); + if (size == 0) + return NULL; + // GlobalLock() can return NULL, if memory block has a zero-byte size + const void *src = GlobalLock(srcGlobal); + if (!src) + return NULL; + HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); + if (destGlobal) + { + void *dest = GlobalLock(destGlobal); + if (!dest) + { + GlobalFree(destGlobal); + destGlobal = NULL; + } + else + { + memcpy(dest, src, size); + GlobalUnlock(destGlobal); + } + } + GlobalUnlock(srcGlobal); + return destGlobal; +} + + +static bool Medium_CopyFrom(LPSTGMEDIUM medium, const void *data, size_t size) +{ + medium->tymed = TYMED_NULL; + medium->pUnkForRelease = NULL; + medium->hGlobal = NULL; + const HGLOBAL global = GlobalAlloc(GHND | GMEM_SHARE, size); + if (!global) + return false; + void *dest = GlobalLock(global); + if (!dest) + { + GlobalFree(global); + return false; + } + memcpy(dest, data, size); + GlobalUnlock(global); + medium->hGlobal = global; + medium->tymed = TYMED_HGLOBAL; + return true; +} + + +Z7_COMWF_B CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium) +{ + try { + PRF_(PrintFormat("-- GetData", etc->cfFormat)) + + medium->tymed = TYMED_NULL; + medium->pUnkForRelease = NULL; + medium->hGlobal = NULL; + + if (NeedCall_Copy && !Copy_WasCalled) + CopyFromPanelTo_Folder(); + + // PRF3("+ CDataObject::GetData"); + // PrintFormat(etc->cfFormat); + HGLOBAL global; + RINOK(QueryGetData(etc)) + + /* + if (etc->cfFormat == m_Format_FileOpFlags) + global = m_hGlobal_FileOpFlags; + else if (etc->cfFormat == m_Format_PreferredDropEffect) + { + // Explorer requests PreferredDropEffect only if Move/Copy selection is possible: + // Shift is not pressed and Ctrl is not pressed + PRF3("------ CDataObject::GetData() PreferredDropEffect"); + global = m_hGlobal_PreferredDropEffect; + } + else + */ + if (etc->cfFormat == m_Etc.cfFormat) // CF_HDROP + global = UsePreGlobal ? m_hGlobal_HDROP_Pre : m_hGlobal_HDROP_Final; + else if (etc->cfFormat == m_Format_7zip_GetTransfer) + { + CDataObject_GetTransfer transfer; + if (m_DestDirPrefix_FromTarget_WasSet) + { + transfer.Flags |= k_SourceFlags_SetTargetFolder; + } + if (!DestDirPrefix_FromTarget.IsEmpty()) + { + transfer.Flags |= k_SourceFlags_SetTargetFolder_NonEmpty; + } + if (IsTempFiles) + { + transfer.Flags |= k_SourceFlags_TempFiles; + transfer.Flags |= k_SourceFlags_WaitFinish; + transfer.Flags |= k_SourceFlags_NeedExtractOpToFs; + if (UsePreGlobal) + transfer.Flags |= k_SourceFlags_NamesAreParent; + } + else + transfer.Flags |= k_SourceFlags_DoNotWaitFinish; + + if (IsRightButton) + transfer.Flags |= k_SourceFlags_RightButton; + else + transfer.Flags |= k_SourceFlags_LeftButton; + + if (DoNotProcessInTarget) + transfer.Flags |= k_SourceFlags_DoNotProcessInTarget; + if (Copy_WasCalled) + transfer.Flags |= k_SourceFlags_Copy_WasCalled; + + if (Medium_CopyFrom(medium, &transfer, sizeof(transfer))) + return S_OK; + return E_OUTOFMEMORY; + } + else + return DV_E_FORMATETC; + + if (!global) + return DV_E_FORMATETC; + medium->tymed = m_Etc.tymed; + medium->hGlobal = DuplicateGlobalMem(global); + if (!medium->hGlobal) + return E_OUTOFMEMORY; + return S_OK; + } catch(...) { return E_FAIL; } +} + +Z7_COMWF_B CDataObject::GetDataHere(LPFORMATETC /* etc */, LPSTGMEDIUM /* medium */) +{ + PRF3("CDataObject::GetDataHere()"); + // Seems Windows doesn't call it, so we will not implement it. + return E_UNEXPECTED; +} + + +/* + IDataObject::QueryGetData() Determines whether the data object is capable of + rendering the data as specified. Objects attempting a paste or drop + operation can call this method before calling IDataObject::GetData + to get an indication of whether the operation may be successful. + + The client of a data object calls QueryGetData to determine whether + passing the specified FORMATETC structure to a subsequent call to + IDataObject::GetData is likely to be successful. + + we check Try_QueryGetData with CF_HDROP +*/ + +Z7_COMWF_B CDataObject::QueryGetData(LPFORMATETC etc) +{ + PRF3("-- CDataObject::QueryGetData()"); + if ( etc->cfFormat == m_Etc.cfFormat // CF_HDROP + || etc->cfFormat == m_Format_7zip_GetTransfer + // || (etc->cfFormat == m_Format_FileOpFlags && (HGLOBAL)m_hGlobal_FileOpFlags) + // || (etc->cfFormat == m_Format_PreferredDropEffect && (HGLOBAL)m_hGlobal_PreferredDropEffect) + ) + { + } + else + return DV_E_FORMATETC; + if (etc->dwAspect != m_Etc.dwAspect) + return DV_E_DVASPECT; + /* GetData(): It is possible to specify more than one medium by using the Boolean OR + operator, allowing the method to choose the best medium among those specified. */ + if ((etc->tymed & m_Etc.tymed) == 0) + return DV_E_TYMED; + return S_OK; +} + +Z7_COMWF_B CDataObject::EnumFormatEtc(DWORD direction, LPENUMFORMATETC FAR* enumFormatEtc) +{ + // we don't enumerate for DATADIR_SET. Seems it can work without it. + if (direction != DATADIR_GET) + return E_NOTIMPL; + // we don't enumerate for m_Format_FileOpFlags also. Seems it can work without it. + return CreateEnumFormatEtc(1, &m_Etc, enumFormatEtc); +} + + + +//////////////////////////////////////////////////////// + +class CDropSource Z7_final: + public IDropSource, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_1_MT(IDropSource) + STDMETHOD(QueryContinueDrag)(BOOL escapePressed, DWORD keyState) Z7_override; + STDMETHOD(GiveFeedback)(DWORD effect) Z7_override; + + DWORD m_Effect; +public: + CDataObject *DataObjectSpec; + CMyComPtr DataObject; + + HRESULT DragProcessing_HRESULT; + bool DragProcessing_WasFinished; + + CDropSource(): + m_Effect(DROPEFFECT_NONE), + // Panel(NULL), + DragProcessing_HRESULT(S_OK), + DragProcessing_WasFinished(false) + {} +}; + +// static bool g_Debug = 0; + + +Z7_COMWF_B CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState) +{ + // try { + + /* Determines whether a drag-and-drop operation should be continued, canceled, or completed. + escapePressed : Indicates whether the Esc key has been pressed + since the previous call to QueryContinueDrag + or to DoDragDrop if this is the first call to QueryContinueDrag: + TRUE : the end user has pressed the escape key; + FALSE : it has not been pressed. + keyState : The current state of the keyboard modifier keys on the keyboard. + Possible values can be a combination of any of the flags: + MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON. + */ + #ifdef SHOW_DEBUG_DRAG + { + AString s ("CDropSource::QueryContinueDrag()"); + s.Add_Space(); + s += "keystate="; + s.Add_UInt32(keyState); + PRF4(s); + } + #endif + + /* + if ((keyState & MK_LBUTTON) == 0) + { + // PRF4("CDropSource::QueryContinueDrag() (keyState & MK_LBUTTON) == 0"); + g_Debug = true; + } + else + { + // PRF4("CDropSource::QueryContinueDrag() (keyState & MK_LBUTTON) != 0"); + } + */ + + if (escapePressed) + { + // The drag operation should be canceled with no drop operation occurring. + DragProcessing_WasFinished = true; + DragProcessing_HRESULT = DRAGDROP_S_CANCEL; + return DRAGDROP_S_CANCEL; + } + + if (DragProcessing_WasFinished) + return DragProcessing_HRESULT; + + if ((keyState & MK_RBUTTON) != 0) + { + if (!DataObjectSpec->IsRightButton) + { + DragProcessing_WasFinished = true; + DragProcessing_HRESULT = DRAGDROP_S_CANCEL; + return DRAGDROP_S_CANCEL; + } + return S_OK; + } + + if ((keyState & MK_LBUTTON) != 0) + { + if (DataObjectSpec->IsRightButton) + { + DragProcessing_WasFinished = true; + DragProcessing_HRESULT = DRAGDROP_S_CANCEL; + return DRAGDROP_S_CANCEL; + } + /* The drag operation should continue. This result occurs if no errors are detected, + the mouse button starting the drag-and-drop operation has not been released, + and the Esc key has not been detected. */ + return S_OK; + } + { + // the mouse button starting the drag-and-drop operation has been released. + + /* Win10 probably calls DragOver()/GiveFeedback() just before LBUTTON releasing. + so m_Effect is effect returned by DropTarget::DragOver() + just before LBUTTON releasing. + So here we can use Effect sent to last GiveFeedback() */ + + if (m_Effect == DROPEFFECT_NONE) + { + DragProcessing_WasFinished = true; + DragProcessing_HRESULT = DRAGDROP_S_CANCEL; + // Drop target cannot accept the data. So we cancel drag and drop + // maybe return DRAGDROP_S_DROP also OK here ? + // return DRAGDROP_S_DROP; // for debug + return DRAGDROP_S_CANCEL; + } + + // we switch to real names for items that will be created in temp folder + DataObjectSpec->UsePreGlobal = false; + DataObjectSpec->Copy_HRESULT = S_OK; + // MoveMode = (((keyState & MK_SHIFT) != 0) && MoveIsAllowed); + /* + if (DataObjectSpec->IsRightButton) + return DRAGDROP_S_DROP; + */ + + if (DataObjectSpec->IsTempFiles) + { + if (!DataObjectSpec->DestDirPrefix_FromTarget.IsEmpty()) + { + /* we know the destination Path. + So we can copy or extract items later in Source with simpler code. */ + DataObjectSpec->DoNotProcessInTarget = true; + // return DRAGDROP_S_CANCEL; + } + else + { + DataObjectSpec->NeedCall_Copy = true; + /* + if (Copy_HRESULT != S_OK || !Messages.IsEmpty()) + { + DragProcessing_WasFinished = true; + DragProcessing_HRESULT = DRAGDROP_S_CANCEL; + return DRAGDROP_S_CANCEL; + } + */ + } + } + DragProcessing_HRESULT = DRAGDROP_S_DROP; + DragProcessing_WasFinished = true; + return DRAGDROP_S_DROP; + } + // } catch(...) { return E_FAIL; } +} + + +Z7_COMWF_B CDropSource::GiveFeedback(DWORD effect) +{ + // PRF3("CDropSource::GiveFeedback"); + /* Enables a source application to give visual feedback to the end user + during a drag-and-drop operation by providing the DoDragDrop function + with an enumeration value specifying the visual effect. + in (effect): + The DROPEFFECT value returned by the most recent call to + IDropTarget::DragEnter, + IDropTarget::DragOver, + or DROPEFFECT_NONE after IDropTarget::DragLeave. + 0: DROPEFFECT_NONE + 1: DROPEFFECT_COPY + 2: DROPEFFECT_MOVE + 4: DROPEFFECT_LINK + 0x80000000: DROPEFFECT_SCROLL + The dwEffect parameter can include DROPEFFECT_SCROLL, indicating that the + source should put up the drag-scrolling variation of the appropriate pointer. + */ + m_Effect = effect; + + #ifdef SHOW_DEBUG_DRAG + AString w ("GiveFeedback effect="); + if (effect & DROPEFFECT_SCROLL) + w += " SCROLL "; + w.Add_UInt32(effect & ~DROPEFFECT_SCROLL); + // if (g_Debug) + PRF4(w); + #endif + + /* S_OK : no special drag and drop cursors. + Maybe it's for case where we created custom custom cursors. + DRAGDROP_S_USEDEFAULTCURSORS: Indicates successful completion of the method, + and requests OLE to update the cursor using the OLE-provided default cursors. */ + // return S_OK; // for debug + return DRAGDROP_S_USEDEFAULTCURSORS; +} + + + +/* +static bool Global_SetUInt32(NMemory::CGlobal &hg, const UInt32 v) +{ + if (!hg.Alloc(GHND | GMEM_SHARE, sizeof(v))) + return false; + NMemory::CGlobalLock dropLock(hg); + *(UInt32 *)dropLock.GetPointer() = v; + return true; +} +*/ + +static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &names) +{ + size_t totalLen = 1; + + #ifndef _UNICODE + if (!g_IsNT) + { + AStringVector namesA; + unsigned i; + for (i = 0; i < names.Size(); i++) + namesA.Add(GetSystemString(names[i])); + for (i = 0; i < namesA.Size(); i++) + totalLen += namesA[i].Len() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLen * sizeof(CHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES *dropFiles = (DROPFILES *)dropLock.GetPointer(); + if (!dropFiles) + return false; + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = FALSE; + CHAR *p = (CHAR *) (void *) ((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < namesA.Size(); i++) + { + const AString &s = namesA[i]; + const unsigned fullLen = s.Len() + 1; + MyStringCopy(p, (const char *)s); + p += fullLen; + totalLen -= fullLen; + } + *p = 0; + } + else + #endif + { + unsigned i; + for (i = 0; i < names.Size(); i++) + totalLen += names[i].Len() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLen * sizeof(WCHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES *dropFiles = (DROPFILES *)dropLock.GetPointer(); + if (!dropFiles) + return false; + /* fNC: + TRUE : pt specifies the screen coordinates of a point in a window's nonclient area. + FALSE : pt specifies the client coordinates of a point in the client area. + */ + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = TRUE; + WCHAR *p = (WCHAR *) (void *) ((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + const unsigned fullLen = s.Len() + 1; + MyStringCopy(p, (const WCHAR *)s); + p += fullLen; + totalLen -= fullLen; + } + *p = 0; + } + // if (totalLen != 1) return false; + return true; +} + + +void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */, bool isRightButton) +{ + PRF("CPanel::OnDrag"); + if (!DoesItSupportOperations()) + return; + + CDisableTimerProcessing disableTimerProcessing2(*this); + + CRecordVector indices; + Get_ItemIndices_Operated(indices); + if (indices.Size() == 0) + return; + + // CSelectedState selState; + // SaveSelectedState(selState); + + const bool isFSFolder = IsFSFolder(); + // why we don't allow drag with rightButton from archive? + if (!isFSFolder && isRightButton) + return; + + UString dirPrefix; + CTempDir tempDirectory; + + CDataObject *dataObjectSpec = new CDataObject; + CMyComPtr dataObject = dataObjectSpec; + dataObjectSpec->IsRightButton = isRightButton; + + { + /* we can change confirmation mode and another options. + Explorer target requests that FILEOP_FLAGS value. */ + /* + const FILEOP_FLAGS fopFlags = + FOF_NOCONFIRMATION + | FOF_NOCONFIRMMKDIR + | FOF_NOERRORUI + | FOF_SILENT; + // | FOF_SIMPLEPROGRESS; // it doesn't work as expected in Win10 + Global_SetUInt32(dataObjectSpec->m_hGlobal_FileOpFlags, fopFlags); + // dataObjectSpec->m_hGlobal_FileOpFlags.Free(); // for debug : disable these options + */ + } + { + /* we can change Preferred DropEffect. + Explorer target requests that FILEOP_FLAGS value. */ + /* + const DWORD effect = DROPEFFECT_MOVE; // DROPEFFECT_COPY; + Global_SetUInt32(dataObjectSpec->m_hGlobal_PreferredDropEffect, effect); + */ + } + if (isFSFolder) + { + dirPrefix = GetFsPath(); // why this in 22.01 ? + dataObjectSpec->UsePreGlobal = false; + // dataObjectSpec->IsTempFiles = false; + } + else + { + if (!tempDirectory.Create(kTempDirPrefix)) + { + MessageBox_Error(L"Can't create temp folder"); + return; + } + dirPrefix = fs2us(tempDirectory.GetPath()); + { + UStringVector names; + names.Add(dirPrefix); + dataObjectSpec->IsTempFiles = true; + dataObjectSpec->UsePreGlobal = true; + if (!CopyNamesToHGlobal(dataObjectSpec->m_hGlobal_HDROP_Pre, names)) + return; + } + NFile::NName::NormalizeDirPathPrefix(dirPrefix); + /* + { + FString path2 = dirPrefix; + path2 += "1.txt"; + CopyFileW(L"C:\\1\\1.txt", path2, FALSE); + } + */ + } + + { + UStringVector names; + // names variable is USED for drag and drop from 7-zip to Explorer or to 7-zip archive folder. + // names variable is NOT USED for drag and drop from 7-zip to 7-zip File System folder. + FOR_VECTOR (i, indices) + { + const UInt32 index = indices[i]; + UString s; + if (isFSFolder) + s = GetItemRelPath(index); + else + { + s = GetItemName(index); + /* + // We use (keepAndReplaceEmptyPrefixes = true) in CAgentFolder::Extract + // So the following code is not required. + // Maybe we also can change IFolder interface and send some flag also. + if (s.IsEmpty()) + { + // Correct_FsFile_Name("") returns "_". + // If extracting code removes empty folder prefixes from path (as it was in old version), + // Explorer can't find "_" folder in temp folder. + // We can ask Explorer to copy parent temp folder "7zE" instead. + names.Clear(); + names.Add(dirPrefix2); + break; + } + */ + s = Get_Correct_FsFile_Name(s); + } + names.Add(dirPrefix + s); + } + if (!CopyNamesToHGlobal(dataObjectSpec->m_hGlobal_HDROP_Final, names)) + return; + } + + CDropSource *dropSourceSpec = new CDropSource; + CMyComPtr dropSource = dropSourceSpec; + dataObjectSpec->Panel = this; + dataObjectSpec->Indices = indices; + dataObjectSpec->SrcDirPrefix_Temp = dirPrefix; + + dropSourceSpec->DataObjectSpec = dataObjectSpec; + dropSourceSpec->DataObject = dataObjectSpec; + + + /* + CTime - file creation timestamp. + There are two operations in Windows with Drag and Drop: + COPY_OPERATION : icon with Plus sign : CTime will be set as current_time. + MOVE_OPERATION : icon without Plus sign : CTime will be preserved. + + Note: if we call DoDragDrop() with (effectsOK = DROPEFFECT_MOVE), then + it will use MOVE_OPERATION and CTime will be preserved. + But MoveFile() function doesn't preserve CTime, if different volumes are used. + Why it's so? + Does DoDragDrop() use some another function (not MoveFile())? + + if (effectsOK == DROPEFFECT_COPY) it works as COPY_OPERATION + + if (effectsOK == DROPEFFECT_MOVE) drag works as MOVE_OPERATION + + if (effectsOK == (DROPEFFECT_COPY | DROPEFFECT_MOVE)) + { + if we drag file to same volume, then Windows suggests: + CTRL - COPY_OPERATION + [default] - MOVE_OPERATION + + if we drag file to another volume, then Windows suggests + [default] - COPY_OPERATION + SHIFT - MOVE_OPERATION + } + + We want to use MOVE_OPERATION for extracting from archive (open in 7-Zip) to Explorer: + It has the following advantages: + 1) it uses fast MOVE_OPERATION instead of slow COPY_OPERATION and DELETE, if same volume. + 2) it preserves CTime + + Some another programs support only COPY_OPERATION. + So we can use (DROPEFFECT_COPY | DROPEFFECT_MOVE) + + Also another program can return from DoDragDrop() before + files using. But we delete temp folder after DoDragDrop(), + and another program can't open input files in that case. + + We create objects: + IDropSource *dropSource + IDataObject *dataObject + if DropTarget is 7-Zip window, then 7-Zip's + IDropTarget::DragOver() sets DestDirPrefix_FromTarget in IDataObject. + and + IDropSource::QueryContinueDrag() sets DoNotProcessInTarget, if DestDirPrefix_FromTarget is not empty. + So we can detect destination path after DoDragDrop(). + Now we don't know any good way to detect destination path for D&D to Explorer. + */ + + /* + DWORD effectsOK = DROPEFFECT_COPY; + if (moveIsAllowed) + effectsOK |= DROPEFFECT_MOVE; + */ + const bool moveIsAllowed = isFSFolder; + _panelCallback->DragBegin(); + PRF("=== DoDragDrop()"); + DWORD effect = 0; + // 18.04: was changed + const DWORD effectsOK = DROPEFFECT_MOVE | DROPEFFECT_COPY; + // effectsOK |= (1 << 8); // for debug + HRESULT res = ::DoDragDrop(dataObject, dropSource, effectsOK, &effect); + PRF("=== After DoDragDrop()"); + _panelCallback->DragEnd(); + + /* + Win10 drag and drop to Explorer: + DoDragDrop() output variables: + for MOVE operation: + { + effect == DROPEFFECT_NONE; + dropSourceSpec->m_PerformedDropEffect == DROPEFFECT_MOVE; + } + for COPY operation: + { + effect == DROPEFFECT_COPY; + dropSourceSpec->m_PerformedDropEffect == DROPEFFECT_COPY; + } + DOCs: The source inspects the two values that can be returned by the target. + If both are set to DROPEFFECT_MOVE, it completes the unoptimized move + by deleting the original data. Otherwise, the target did an optimized + move and the original data has been deleted. + + We didn't see "unoptimized move" case (two values of DROPEFFECT_MOVE), + where we still need to delete source files. + So we don't delete files after DoDragDrop(). + + Also DOCs say for "optimized move": + The target also calls the data object's IDataObject::SetData method and passes + it a CFSTR_PERFORMEDDROPEFFECT format identifier set to DROPEFFECT_NONE. + but actually in Win10 we always have + (dropSourceSpec->m_PerformedDropEffect == DROPEFFECT_MOVE) + for any MOVE operation. + */ + + const bool canceled = (res == DRAGDROP_S_CANCEL); + + CDisableNotify disableNotify(*this); + + if (res == DRAGDROP_S_DROP) + { + /* DRAGDROP_S_DROP is returned. It means that + - IDropTarget::Drop() was called, + - IDropTarget::Drop() returned (ret_code >= 0) + */ + res = dataObjectSpec->Copy_HRESULT; + bool need_Process = dataObjectSpec->DoNotProcessInTarget; + if (dataObjectSpec->m_Transfer_WasSet) + { + if (dataObjectSpec->m_Transfer.Target.FuncType == k_DragTargetMode_Drop_End) + { + if (dataObjectSpec->m_Transfer.Target.Flags & k_TargetFlags_MustBeProcessedBySource) + need_Process = true; + } + } + + if (need_Process) + if (!dataObjectSpec->DestDirPrefix_FromTarget.IsEmpty()) + { + if (!NFile::NName::IsAltStreamPrefixWithColon(dataObjectSpec->DestDirPrefix_FromTarget)) + NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->DestDirPrefix_FromTarget); + CCopyToOptions options; + options.folder = dataObjectSpec->DestDirPrefix_FromTarget; + // if MOVE is not allowed, we just use COPY operation + /* it was 7-zip's Target that set non-empty dataObjectSpec->DestDirPrefix_FromTarget. + it means that target didn't completed operation, + and we can use (effect) value returned by target via DoDragDrop(). + as indicator of type of operation + */ + // options.moveMode = (moveIsAllowed && effect == DROPEFFECT_MOVE) // before v23.00: + options.moveMode = moveIsAllowed; + if (moveIsAllowed) + { + if (dataObjectSpec->m_Transfer_WasSet) + options.moveMode = ( + dataObjectSpec->m_Transfer.Target.Cmd_Effect == DROPEFFECT_MOVE); + else + options.moveMode = (effect == DROPEFFECT_MOVE); + // we expect (DROPEFFECT_MOVE) as indicator of move operation for Drag&Drop MOVE ver 22.01. + } + res = CopyTo(options, indices, &dataObjectSpec->Messages); + } + /* + if (effect & DROPEFFECT_MOVE) + RefreshListCtrl(selState); + */ + } + else + { + // we ignore E_UNEXPECTED that is returned if we drag file to printer + if (res != DRAGDROP_S_CANCEL + && res != S_OK + && res != E_UNEXPECTED) + MessageBox_Error_HRESULT(res); + res = dataObjectSpec->Copy_HRESULT; + } + + if (!dataObjectSpec->Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &dataObjectSpec->Messages; + messagesDialog.Create((*this)); + } + + if (res != S_OK && res != E_ABORT) + { + // we restore Notify before MessageBox_Error_HRESULT. So we will see files selection + disableNotify.Restore(); + // SetFocusToList(); + MessageBox_Error_HRESULT(res); + } + if (res == S_OK && dataObjectSpec->Messages.IsEmpty() && !canceled) + KillSelection(); +} + + + + + +CDropTarget::CDropTarget(): + m_IsRightButton(false), + m_GetTransfer_WasSuccess(false), + m_DropIsAllowed(false), + m_PanelDropIsAllowed(false), + // m_DropHighlighted_SelectionIndex(-1), + // m_SubFolderIndex(-1), + m_Panel(NULL), + m_IsAppTarget(false), + m_TargetPath_WasSent_ToDataObject(false), + m_TargetPath_NonEmpty_WasSent_ToDataObject(false), + m_Transfer_WasSent_ToDataObject(false), + App(NULL), + SrcPanelIndex(-1), + TargetPanelIndex(-1) +{ + m_Format_7zip_SetTargetFolder = RegisterClipboardFormat(k_Format_7zip_SetTargetFolder); + m_Format_7zip_SetTransfer = RegisterClipboardFormat(k_Format_7zip_SetTransfer); + m_Format_7zip_GetTransfer = RegisterClipboardFormat(k_Format_7zip_GetTransfer); + + m_ProcessId = GetCurrentProcessId(); + // m_TransactionId = ((UInt64)m_ProcessId << 32) + 1; + // ClearState(); +} + +// clear internal state +void CDropTarget::ClearState() +{ + m_DataObject.Release(); + m_SourcePaths.Clear(); + + m_IsRightButton = false; + + m_GetTransfer_WasSuccess = false; + m_DropIsAllowed = false; + + m_PanelDropIsAllowed = false; + // m_SubFolderIndex = -1; + // m_DropHighlighted_SubFolderName.Empty(); + m_Panel = NULL; + m_IsAppTarget = false; + m_TargetPath_WasSent_ToDataObject = false; + m_TargetPath_NonEmpty_WasSent_ToDataObject = false; + m_Transfer_WasSent_ToDataObject = false; +} + +/* + IDataObject::QueryGetData() Determines whether the data object is capable of + rendering the data as specified. Objects attempting a paste or drop + operation can call this method before calling IDataObject::GetData + to get an indication of whether the operation may be successful. + + The client of a data object calls QueryGetData to determine whether + passing the specified FORMATETC structure to a subsequent call to + IDataObject::GetData is likely to be successful. + + We check Try_QueryGetData with CF_HDROP +*/ +/* +void CDropTarget::Try_QueryGetData(IDataObject *dataObject) +{ + FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + m_DropIsAllowed = (dataObject->QueryGetData(&etc) == S_OK); +} +*/ + +static void ListView_SetItemState_DropHighlighted( + NControl::CListView &listView, int index, bool highlighted) +{ + // LVIS_DROPHILITED : The item is highlighted as a drag-and-drop target + /* + LVITEM item; + item.mask = LVIF_STATE; + item.iItem = index; + item.iSubItem = 0; + item.state = enable ? LVIS_DROPHILITED : 0; + item.stateMask = LVIS_DROPHILITED; + item.pszText = NULL; + listView.SetItem(&item); + */ + listView.SetItemState(index, highlighted ? LVIS_DROPHILITED : 0, LVIS_DROPHILITED); +} + +// Removes DropHighlighted state in ListView item, if it was set before +void CDropTarget::RemoveSelection() +{ + if (m_Panel) + { + m_Panel->m_DropHighlighted_SubFolderName.Empty(); + if (m_Panel->m_DropHighlighted_SelectionIndex >= 0) + { + ListView_SetItemState_DropHighlighted(m_Panel->_listView, + m_Panel->m_DropHighlighted_SelectionIndex, false); + m_Panel->m_DropHighlighted_SelectionIndex = -1; + } + } +} + +#ifdef UNDER_CE +#define ChildWindowFromPointEx(hwndParent, pt, uFlags) ChildWindowFromPoint(hwndParent, pt) +#endif + + +/* + PositionCursor() function sets m_Panel under cursor drop, and + m_SubFolderIndex/m_DropHighlighted_SubFolderName, if drop to some folder in Panel list. +*/ +/* +PositionCursor() uses as input variables: + m_DropIsAllowed must be set before PositionCursor() + if (m_DropHighlighted_SelectionIndex >= 0 && m_Panel) it uses m_Panel and removes previous selection +PositionCursor() sets + m_PanelDropIsAllowed + m_Panel + m_IsAppTarget + m_SubFolderIndex + m_DropHighlighted_SubFolderName + m_DropHighlighted_SelectionIndex +*/ +void CDropTarget::PositionCursor(const POINTL &ptl) +{ + RemoveSelection(); + + // m_SubFolderIndex = -1; + // m_DropHighlighted_SubFolderName.Empty(); + m_IsAppTarget = true; + m_Panel = NULL; + m_PanelDropIsAllowed = false; + + if (!m_DropIsAllowed) + return; + + POINT pt; + pt.x = ptl.x; + pt.y = ptl.y; + { + POINT pt2 = pt; + if (App->_window.ScreenToClient(&pt2)) + for (unsigned i = 0; i < kNumPanelsMax; i++) + if (App->IsPanelVisible(i)) + { + CPanel *panel = &App->Panels[i]; + if (panel->IsEnabled()) + if (::ChildWindowFromPointEx(App->_window, pt2, + CWP_SKIPINVISIBLE | CWP_SKIPDISABLED) == (HWND)*panel) + { + m_Panel = panel; + m_IsAppTarget = false; + if ((int)i == SrcPanelIndex) + return; // we don't allow to drop to source panel + break; + } + } + } + + m_PanelDropIsAllowed = true; + + if (!m_Panel) + { + if (TargetPanelIndex >= 0) + m_Panel = &App->Panels[TargetPanelIndex]; + // we don't need to find item in panel + return; + } + + // we will try to find and highlight drop folder item in listView under cursor + /* + m_PanelDropIsAllowed = m_Panel->DoesItSupportOperations(); + if (!m_PanelDropIsAllowed) + return; + */ + /* now we don't allow drop to subfolder under cursor, if dest panel is archive. + Another code must be fixed for that case, where we must use m_SubFolderIndex/m_DropHighlighted_SubFolderName */ + if (!m_Panel->IsFsOrPureDrivesFolder()) + return; + + if (::WindowFromPoint(pt) != (HWND)m_Panel->_listView) + return; + + LVHITTESTINFO info; + m_Panel->_listView.ScreenToClient(&pt); + info.pt = pt; + const int index = ListView_HitTest(m_Panel->_listView, &info); + if (index < 0) + return; + const unsigned realIndex = m_Panel->GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + if (!m_Panel->IsItem_Folder(realIndex)) + return; + // m_SubFolderIndex = (int)realIndex; + m_Panel->m_DropHighlighted_SubFolderName = m_Panel->GetItemName(realIndex); + ListView_SetItemState_DropHighlighted(m_Panel->_listView, index, true); + m_Panel->m_DropHighlighted_SelectionIndex = index; +} + + +/* returns true, if !m_IsAppTarget + and target is FS folder or altStream folder +*/ + +UInt32 CDropTarget::GetFolderType() const +{ + if (m_IsAppTarget || !m_Panel) + return k_FolderType_None; + if (m_Panel->IsFSFolder() || + (m_Panel->IsFSDrivesFolder() + && m_Panel->m_DropHighlighted_SelectionIndex >= 0)) + return k_FolderType_Fs; + if (m_Panel->IsAltStreamsFolder()) + return k_FolderType_AltStreams; + if (m_Panel->IsArcFolder()) + return k_FolderType_Archive; + return k_FolderType_Unknown; +} + +bool CDropTarget::IsFsFolderPath() const +{ + if (m_IsAppTarget || !m_Panel) + return false; + if (m_Panel->IsFSFolder()) + return true; + if (m_Panel->IsAltStreamsFolder()) + return true; + return m_Panel->IsFSDrivesFolder() && + m_Panel->m_DropHighlighted_SelectionIndex >= 0; +} + + +#define INIT_FORMATETC_HGLOBAL(type) { (type), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } + +static bool DataObject_GetData_GetTransfer(IDataObject *dataObject, + UINT a_Format_7zip_GetTransfer, CDataObject_GetTransfer &transfer) +{ + FORMATETC etc = INIT_FORMATETC_HGLOBAL((CLIPFORMAT)a_Format_7zip_GetTransfer); + NCOM::CStgMedium medium; + const HRESULT res = dataObject->GetData(&etc, &medium); + if (res != S_OK) + return false; + if (medium.tymed != TYMED_HGLOBAL) + return false; + const size_t size = GlobalSize(medium.hGlobal); + if (size < sizeof(transfer)) + return false; + NMemory::CGlobalLock dropLock(medium.hGlobal); + const CDataObject_GetTransfer *t = (const CDataObject_GetTransfer *)dropLock.GetPointer(); + if (!t) + return false; + if (!t->Check()) // isSetData + return false; + transfer = *t; + return true; +} + +/* + returns true, if all m_SourcePaths[] items are same drive + as destination drop path in m_Panel +*/ +bool CDropTarget::IsItSameDrive() const +{ + if (!m_Panel) + return false; + if (!IsFsFolderPath()) + return false; + + UString drive; + + if (m_Panel->IsFSFolder()) + { + drive = m_Panel->GetDriveOrNetworkPrefix(); + if (drive.IsEmpty()) + return false; + } + else if (m_Panel->IsFSDrivesFolder() + && m_Panel->m_DropHighlighted_SelectionIndex >= 0) + { + drive = m_Panel->m_DropHighlighted_SubFolderName; + drive.Add_PathSepar(); + } + else + return false; + + if (m_SourcePaths.Size() == 0) + return false; + + FOR_VECTOR (i, m_SourcePaths) + { + if (!m_SourcePaths[i].IsPrefixedBy_NoCase(drive)) + return false; + } + return true; +} + + +/* + There are 2 different actions, when we drag to 7-Zip: + 1) if target panel is "7-Zip" FS and any of the 2 cases: + - Drag from any non "7-Zip" program; + or + - Drag from "7-Zip" to non-panel area of "7-Zip". + We want to create new archive for that operation with "Add to Archive" window. + 2) all another operations work as usual file COPY/MOVE + - Drag from "7-Zip" FS to "7-Zip" FS. + COPY/MOVE are supported. + - Drag to open archive in 7-Zip. + We want to update archive. + We replace COPY to MOVE. + - Drag from "7-Zip" archive to "7-Zip" FS. + We replace COPY to MOVE. +*/ + +// we try to repeat Explorer's effects. +// out: 0 - means that use default effect +static DWORD GetEffect_ForKeys(DWORD keyState) +{ + if (keyState & MK_CONTROL) + { + if (keyState & MK_ALT) + return 0; + if (keyState & MK_SHIFT) + return DROPEFFECT_LINK; // CONTROL + SHIFT + return DROPEFFECT_COPY; // CONTROL + } + // no CONTROL + if (keyState & MK_SHIFT) + { + if (keyState & MK_ALT) + return 0; + return DROPEFFECT_MOVE; // SHIFT + } + // no CONTROL, no SHIFT + if (keyState & MK_ALT) + return DROPEFFECT_LINK; // ALT + return 0; +} + + +/* GetEffect() uses m_TargetPath_WasSentToDataObject + to disale MOVE operation, if Source is not 7-Zip +*/ +DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect) const +{ + // (DROPEFFECT_NONE == 0) + if (!m_DropIsAllowed || !m_PanelDropIsAllowed) + return 0; + if (!IsFsFolderPath() || !m_TargetPath_WasSent_ToDataObject) + { + // we don't allow MOVE, if Target is archive or Source is not 7-Zip + // disabled for debug: + // allowedEffect &= ~DROPEFFECT_MOVE; + } + DWORD effect; + { + effect = GetEffect_ForKeys(keyState); + if (effect == DROPEFFECT_LINK) + return 0; + effect &= allowedEffect; + } + if (effect == 0) + { + if (allowedEffect & DROPEFFECT_COPY) + effect = DROPEFFECT_COPY; + if (allowedEffect & DROPEFFECT_MOVE) + { + /* MOVE operation can be optimized. So MOVE is preferred way + for default action, if Source and Target are at same drive */ + if (IsItSameDrive()) + effect = DROPEFFECT_MOVE; + } + } + return effect; +} + + +/* returns: + - target folder path prefix, if target is FS folder + - empty string, if target is not FS folder +*/ +UString CDropTarget::GetTargetPath() const +{ + if (!IsFsFolderPath()) + return UString(); + UString path = m_Panel->GetFsPath(); + if (/* m_SubFolderIndex >= 0 && */ + !m_Panel->m_DropHighlighted_SubFolderName.IsEmpty()) + { + path += m_Panel->m_DropHighlighted_SubFolderName; + path.Add_PathSepar(); + } + return path; +} + + +/* +if IDropSource is Win10-Explorer +-------------------------------- + As in MS DOCs: + The source inspects the two (effect) values that can be returned by the target: + 1) SetData(CFSTR_PERFORMEDDROPEFFECT) + 2) returned value (*effect) by + CDropTarget::Drop(IDataObject *dataObject, DWORD keyState, + POINTL pt, DWORD *effect) + If both are set to DROPEFFECT_MOVE, Explorer completes the unoptimized move by deleting + the original data. + // Otherwise, the target did an optimized move and the original data has been deleted. +*/ + + +/* + Send targetPath from target to dataObject (to Source) + input: set (enablePath = false) to send empty path + returns true, if SetData() returns S_OK : (source is 7-zip) + returns false, if SetData() doesn't return S_OK : (source is Explorer) +*/ +bool CDropTarget::SendToSource_TargetPath_enable(IDataObject *dataObject, bool enablePath) +{ + m_TargetPath_NonEmpty_WasSent_ToDataObject = false; + UString path; + if (enablePath) + path = GetTargetPath(); + PRF("CDropTarget::SetPath"); + PRF_W(path); + if (!dataObject || m_Format_7zip_SetTargetFolder == 0) + return false; + FORMATETC etc = INIT_FORMATETC_HGLOBAL((CLIPFORMAT)m_Format_7zip_SetTargetFolder); + STGMEDIUM medium; + medium.tymed = etc.tymed; + medium.pUnkForRelease = NULL; + const size_t num = path.Len() + 1; // + (1 << 19) // for debug + medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, num * sizeof(wchar_t)); + if (!medium.hGlobal) + return false; + // Sleep(1000); + wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal); + // Sleep(1000); + bool res = false; + if (dest) + { + MyStringCopy(dest, (const wchar_t *)path); + GlobalUnlock(medium.hGlobal); + // OutputDebugString("m_DataObject->SetData"); + const BOOL release = FALSE; // that way is more simple for correct releasing. + // TRUE; // for debug : is not good for some cases. + /* If DropSource is Win10-Explorer, dataObject->SetData() returns E_NOTIMPL; */ + const HRESULT hres = dataObject->SetData(&etc, &medium, release); + // Sleep(1000); + res = (hres == S_OK); + } + + ReleaseStgMedium(&medium); + if (res && !path.IsEmpty()) + m_TargetPath_NonEmpty_WasSent_ToDataObject = true; + // Sleep(1000); + return res; +} + + +void CDropTarget::SendToSource_auto(IDataObject *dataObject, + const CTargetTransferInfo &info) +{ + /* we try to send target path to Source. + If Source is 7-Zip, then it will accept k_Format_7zip_SetTargetFolder. + That sent path will be non-Empty, if this target is FS folder and drop is allowed */ + bool need_Send = false; + if ( info.FuncType == k_DragTargetMode_Enter + || info.FuncType == k_DragTargetMode_Over + || (info.FuncType == k_DragTargetMode_Drop_Begin + // && targetOp_Cmd != NDragMenu::k_None + && info.Cmd_Type != NDragMenu::k_Cancel)) + // if (!g_CreateArchive_for_Drag_from_7zip) + need_Send = m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath(); + m_TargetPath_WasSent_ToDataObject = SendToSource_TargetPath_enable(dataObject, need_Send); + SendToSource_TransferInfo(dataObject, info); +} + + +bool CDropTarget::SendToSource_TransferInfo(IDataObject *dataObject, + const CTargetTransferInfo &info) +{ + m_Transfer_WasSent_ToDataObject = false; + PRF("CDropTarget::SendToSource_TransferInfo"); + + if (!dataObject || m_Format_7zip_SetTransfer == 0) + return false; + FORMATETC etc = INIT_FORMATETC_HGLOBAL((CLIPFORMAT)m_Format_7zip_SetTransfer); + STGMEDIUM medium; + medium.tymed = etc.tymed; + medium.pUnkForRelease = NULL; + CDataObject_SetTransfer transfer; + const size_t size = sizeof(transfer); // + (1 << 19) // for debug + // OutputDebugString("GlobalAlloc"); + medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); + // Sleep(1000); + if (!medium.hGlobal) + return false; + // OutputDebugString("GlobalLock"); + void *dest = (wchar_t *)GlobalLock(medium.hGlobal); + // Sleep(1000); + bool res = false; + if (dest) + { + transfer.Init(); + transfer.Target = info; + + memcpy(dest, &transfer, sizeof(transfer)); + GlobalUnlock(medium.hGlobal); + // OutputDebugString("m_DataObject->SetData"); + const BOOL release = FALSE; // that way is more simple for correct releasing. + // TRUE; // for debug : is not good for some cases + const HRESULT hres = dataObject->SetData(&etc, &medium, release); + res = (hres == S_OK); + } + + ReleaseStgMedium(&medium); + if (res) + m_Transfer_WasSent_ToDataObject = true; + return res; +} + + +bool CDropTarget::SendToSource_UInt32(IDataObject *dataObject, UINT format, UInt32 value) +{ + PRF("CDropTarget::Send_UInt32 (Performed)"); + + if (!dataObject || format == 0) + return false; + FORMATETC etc = INIT_FORMATETC_HGLOBAL((CLIPFORMAT)format); + STGMEDIUM medium; + medium.tymed = etc.tymed; + medium.pUnkForRelease = NULL; + const size_t size = 4; + medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); + if (!medium.hGlobal) + return false; + void *dest = GlobalLock(medium.hGlobal); + bool res = false; + if (dest) + { + *(UInt32 *)dest = value; + GlobalUnlock(medium.hGlobal); + // OutputDebugString("m_DataObject->SetData"); + const BOOL release = TRUE; + // FALSE; // for debug + /* If DropSource is Win10-Explorer, then (release == FALSE) doesn't work + and dataObject->SetData() returns E_NOTIMPL; + So we use release = TRUE; here */ + const HRESULT hres = dataObject->SetData(&etc, &medium, release); + // we return here without calling ReleaseStgMedium(). + return (hres == S_OK); + // Sleep(1000); + /* + if (we use release = TRUE), we expect that + - SetData() will release medium, and + - SetData() will set STGMEDIUM::tymed to (TYMED_NULL = 0). + but some "incorrect" SetData() implementations can keep STGMEDIUM::tymed unchanged. + And it's not safe to call ReleaseStgMedium() here for that case, + because DropSource also could release medium. + We can reset (medium.tymed = TYMED_NULL) manually here to disable + unsafe medium releasing in ReleaseStgMedium(). + */ + /* + if (release) + { + medium.tymed = TYMED_NULL; + medium.pUnkForRelease = NULL; + medium.hGlobal = NULL; + } + res = (hres == S_OK); + */ + } + ReleaseStgMedium(&medium); + return res; +} + + +void CDropTarget::LoadNames_From_DataObject(IDataObject *dataObject) +{ + // "\\\\.\\" prefix is possible for long names + m_DropIsAllowed = NShell::DataObject_GetData_HDROP_or_IDLIST_Names(dataObject, m_SourcePaths) == S_OK; +} + + +Z7_COMWF_B CDropTarget::DragEnter(IDataObject *dataObject, DWORD keyState, POINTL pt, DWORD *effect) +{ + /* *(effect): + - on input : value of the dwOKEffects parameter of the DoDragDrop() function. + - on return : must contain one of the DROPEFFECT flags, which indicates + what the result of the drop operation would be. + (pt): the current cursor coordinates in screen coordinates. + */ + PRF_(Print_Point("CDropTarget::DragEnter", keyState, pt, *effect)) + try { + + if ((keyState & (MK_RBUTTON | MK_MBUTTON)) != 0) + m_IsRightButton = true; + + LoadNames_From_DataObject(dataObject); + // Try_QueryGetData(dataObject); + // we will use (m_DataObject) later in DragOver() and DragLeave(). + m_DataObject = dataObject; + // return DragOver(keyState, pt, effect); + PositionCursor(pt); + CTargetTransferInfo target; + target.FuncType = k_DragTargetMode_Enter; + target.KeyState = keyState; + target.Point = pt; + target.OkEffects = *effect; + SendToSource_Drag(target); + + CDataObject_GetTransfer transfer; + m_GetTransfer_WasSuccess = DataObject_GetData_GetTransfer( + dataObject, m_Format_7zip_GetTransfer, transfer); + if (m_GetTransfer_WasSuccess) + { + if (transfer.Flags & k_SourceFlags_LeftButton) + m_IsRightButton = false; + else if (transfer.Flags & k_SourceFlags_RightButton) + m_IsRightButton = true; + } + + *effect = GetEffect(keyState, pt, *effect); + return S_OK; + } catch(...) { return E_FAIL; } +} + + +Z7_COMWF_B CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect) +{ + PRF_(Print_Point("CDropTarget::DragOver", keyState, pt, *effect)) + /* + For efficiency reasons, a data object is not passed in IDropTarget::DragOver. + The data object passed in the most recent call to IDropTarget::DragEnter + is available and can be used. + + When IDropTarget::DragOver has completed its operation, the DoDragDrop + function calls IDropSource::GiveFeedback so the source application can display + the appropriate visual feedback to the user. + */ + /* + we suppose that it's unexpected that (keyState) shows that mouse + button is not pressed, because such cases will be processed by + IDropSource::QueryContinueDrag() that returns DRAGDROP_S_DROP or DRAGDROP_S_CANCEL. + So DragOver() will not be called. + */ + + if ((keyState & MK_LBUTTON) == 0) + { + PRF4("CDropTarget::DragOver() (keyState & MK_LBUTTON) == 0"); + // g_Debug = true; + } + + try { + /* we suppose that source names were not changed after DragEnter() + so we don't request GetNames_From_DataObject() for each call of DragOver() */ + PositionCursor(pt); + CTargetTransferInfo target; + target.FuncType = k_DragTargetMode_Over; + target.KeyState = keyState; + target.Point = pt; + target.OkEffects = *effect; + SendToSource_Drag(target); + *effect = GetEffect(keyState, pt, *effect); + // *effect = 1 << 8; // for debug + return S_OK; + } catch(...) { return E_FAIL; } +} + + +Z7_COMWF_B CDropTarget::DragLeave() +{ + PRF4("CDropTarget::DragLeave"); + try { + RemoveSelection(); + // we send empty TargetPath to 7-Zip Source to clear value of TargetPath that was sent before + + CTargetTransferInfo target; + target.FuncType = k_DragTargetMode_Leave; + /* + target.KeyState = 0; + target.Point = pt; + pt.x = 0; // -1 + pt.y = 0; // -1 + target.Effect = 0; + */ + SendToSource_Drag(target); + ClearState(); + return S_OK; + } catch(...) { return E_FAIL; } +} + + +static unsigned Drag_OnContextMenu(int xPos, int yPos, UInt32 cmdFlags); + +/* + We suppose that there was DragEnter/DragOver for same (POINTL pt) before Drop(). + But we can work without DragEnter/DragOver too. +*/ +Z7_COMWF_B CDropTarget::Drop(IDataObject *dataObject, DWORD keyState, + POINTL pt, DWORD *effect) +{ + PRF_(Print_Point("CDropTarget::Drop", keyState, pt, *effect)) + /* Drop() is called after SourceDrop::QueryContinueDrag() returned DRAGDROP_S_DROP. + So it's possible that Source have done some operations already. + */ + HRESULT hres = S_OK; + bool needDrop_by_Source = false; + DWORD opEffect = DROPEFFECT_NONE; + + try { + // we don't need m_DataObject reference anymore, because we use local (dataObject) + m_DataObject.Release(); + + /* in normal case : we called LoadNames_From_DataObject() in DragEnter() already. + But if by some reason DragEnter() was not called, + we need to call LoadNames_From_DataObject() before PositionCursor(). + */ + if (!m_DropIsAllowed) LoadNames_From_DataObject(dataObject); + PositionCursor(pt); + + CPanel::CDisableTimerProcessing2 disableTimerProcessing(m_Panel); + // CDisableNotify disableNotify2(m_Panel); + + UInt32 cmd = NDragMenu::k_None; + UInt32 cmdEffect = DROPEFFECT_NONE; + bool menu_WasShown = false; + if (m_IsRightButton && m_Panel) + { + UInt32 flagsMask; + if (m_Panel->IsArcFolder()) + flagsMask = (UInt32)1 << NDragMenu::k_Copy_ToArc; + else + { + flagsMask = (UInt32)1 << NDragMenu::k_AddToArc; + if (IsFsFolderPath()) + flagsMask |= (UInt32)1 << NDragMenu::k_Copy_Base; + } + // flagsMask |= (UInt32)1 << NDragMenu::k_Cancel; + const UInt32 cmd32 = Drag_OnContextMenu(pt.x, pt.y, flagsMask); + cmd = cmd32 & NDragMenu::k_MenuFlags_CmdMask; + if (cmd32 & NDragMenu::k_MenuFlag_Copy) + cmdEffect = DROPEFFECT_COPY; + else if (cmd32 & NDragMenu::k_MenuFlag_Move) + cmdEffect = DROPEFFECT_MOVE; + opEffect = cmdEffect; + menu_WasShown = true; + } + else + { + opEffect = GetEffect(keyState, pt, *effect); + if (m_IsAppTarget) + cmd = NDragMenu::k_AddToArc; + else if (m_Panel) + { + if (IsFsFolderPath()) + { + const bool is7zip = m_TargetPath_WasSent_ToDataObject; + bool createNewArchive = false; + if (is7zip) + createNewArchive = false; // g_CreateArchive_for_Drag_from_7zip; + else + createNewArchive = true; // g_CreateArchive_for_Drag_from_Explorer; + + if (createNewArchive) + cmd = NDragMenu::k_AddToArc; + else + { + if (opEffect != 0) + cmd = NDragMenu::k_Copy_Base; + cmdEffect = opEffect; + } + } + else + { + /* if we are inside open archive: + if archive support operations -> we will call operations + if archive doesn't support operations -> we will create new archove + */ + if (m_Panel->IsArcFolder() + || m_Panel->DoesItSupportOperations()) + { + cmd = NDragMenu::k_Copy_ToArc; + // we don't want move to archive operation here. + // so we force to DROPEFFECT_COPY. + if (opEffect != DROPEFFECT_NONE) + opEffect = DROPEFFECT_COPY; + cmdEffect = opEffect; + } + else + cmd = NDragMenu::k_AddToArc; + } + } + } + + if (cmd == 0) + cmd = NDragMenu::k_AddToArc; + + if (cmd == NDragMenu::k_AddToArc) + { + opEffect = DROPEFFECT_COPY; + cmdEffect = DROPEFFECT_COPY; + } + + if (m_Panel) + if (cmd == NDragMenu::k_Copy_ToArc) + { + const UString title = LangString(IDS_CONFIRM_FILE_COPY); + UString s = LangString(cmdEffect == DROPEFFECT_MOVE ? + IDS_MOVE_TO : IDS_COPY_TO); + s.Add_LF(); + // s += "\'"; + s += m_Panel->_currentFolderPrefix; + // s += "\'"; + s.Add_LF(); + AddLangString(s, IDS_WANT_TO_COPY_FILES); + s += " ?"; + const int res = ::MessageBoxW(*m_Panel, s, title, MB_YESNOCANCEL | MB_ICONQUESTION); + if (res != IDYES) + cmd = NDragMenu::k_Cancel; + } + + CTargetTransferInfo target; + target.FuncType = k_DragTargetMode_Drop_Begin; + target.KeyState = keyState; + target.Point = pt; + target.OkEffects = *effect; + target.Flags = 0; + + target.Cmd_Effect = cmdEffect; + target.Cmd_Type = cmd; + target.FolderType = GetFolderType(); + + if (cmd == NDragMenu::k_Cancel) + target.Flags |= k_TargetFlags_WasCanceled; + if (menu_WasShown) + target.Flags |= k_TargetFlags_MenuWasShown; + + SendToSource_auto(dataObject, target); + + CDataObject_GetTransfer transfer; + m_GetTransfer_WasSuccess = DataObject_GetData_GetTransfer( + dataObject, m_Format_7zip_GetTransfer, transfer); + + /* The Source (for example, 7-zip) could change file names when drop was confirmed. + So we must reload source file paths here */ + if (cmd != NDragMenu::k_Cancel) + LoadNames_From_DataObject(dataObject); + + if (cmd == NDragMenu::k_Cancel) + { + opEffect = DROPEFFECT_NONE; + cmdEffect = DROPEFFECT_NONE; + } + else + { + if (m_GetTransfer_WasSuccess) + needDrop_by_Source = ((transfer.Flags & k_SourceFlags_DoNotProcessInTarget) != 0); + if (!needDrop_by_Source) + { + bool moveMode = (cmdEffect == DROPEFFECT_MOVE); + bool needDrop = false; + if (m_IsRightButton && m_Panel) + needDrop = true; + if (m_DropIsAllowed && m_PanelDropIsAllowed) + { + /* if non-empty TargetPath was sent successfully to DataObject, + then the Source is 7-Zip, and that 7zip-Source can copy to FS operation. + So we can disable Drop operation here for such case. + */ + needDrop_by_Source = (cmd != NDragMenu::k_AddToArc + && m_TargetPath_WasSent_ToDataObject + && m_TargetPath_NonEmpty_WasSent_ToDataObject); + needDrop = !(needDrop_by_Source); + } + if (needDrop) + { + UString path = GetTargetPath(); + if (m_IsAppTarget && m_Panel) + if (m_Panel->IsFSFolder()) + path = m_Panel->GetFsPath(); + + UInt32 sourceFlags = 0; + if (m_GetTransfer_WasSuccess) + sourceFlags = transfer.Flags; + + if (menu_WasShown) + target.Flags |= k_TargetFlags_MenuWasShown; + + target.Flags |= k_TargetFlags_WasProcessed; + + RemoveSelection(); + // disableTimerProcessing.Restore(); + m_Panel->CompressDropFiles(m_SourcePaths, path, + (cmd == NDragMenu::k_AddToArc), // createNewArchive, + moveMode, sourceFlags, + target.Flags + ); + } + } + } // end of if (cmd != NDragMenu::k_Cancel) + { + /* note that, if (we send CFSTR_PERFORMEDDROPEFFECT as DROPEFFECT_MOVE + and Drop() returns (*effect == DROPEFFECT_MOVE), then + Win10-Explorer-Source will try to remove files just after Drop() exit. + But our CompressFiles() could be run without waiting finishing. + DOCs say, that we must send CFSTR_PERFORMEDDROPEFFECT + - DROPEFFECT_NONE : for optimized move + - DROPEFFECT_MOVE : for unoptimized move. + But actually Win10-Explorer-Target sends (DROPEFFECT_MOVE) for move operation. + And it still works as in optimized mode, because "unoptimized" deleting by Source will be performed + if both conditions are met: + 1) DROPEFFECT_MOVE is sent to (CFSTR_PERFORMEDDROPEFFECT) and + 2) (*effect == DROPEFFECT_MOVE) is returend by Drop(). + We don't want to send DROPEFFECT_MOVE here to protect from + deleting file by Win10-Explorer. + We are not sure that allfile fieree processed by move. + */ + + // for debug: we test the case when source tries to delete original files + // bool res; + // only CFSTR_PERFORMEDDROPEFFECT affects file removing in Win10-Explorer. + // res = SendToSource_UInt32(dataObject, RegisterClipboardFormat(CFSTR_LOGICALPERFORMEDDROPEFFECT), DROPEFFECT_MOVE); // for debug + /* res = */ SendToSource_UInt32(dataObject, + RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT), + cmd == NDragMenu::k_Cancel ? DROPEFFECT_NONE : DROPEFFECT_COPY); + // res = res; + } + RemoveSelection(); + + target.FuncType = k_DragTargetMode_Drop_End; + target.Cmd_Type = cmd; + if (needDrop_by_Source) + target.Flags |= k_TargetFlags_MustBeProcessedBySource; + + SendToSource_TransferInfo(dataObject, target); + } catch(...) { hres = E_FAIL; } + + ClearState(); + // *effect |= (1 << 10); // for debug + // *effect = DROPEFFECT_COPY; // for debug + + /* + if we return (*effect == DROPEFFECT_MOVE) here, + Explorer-Source at some conditions can treat it as (unoptimized move) mode, + and Explorer-Source will remove source files after DoDragDrop() + in that (unoptimized move) mode. + We want to avoid such (unoptimized move) cases. + So we don't return (*effect == DROPEFFECT_MOVE), here if Source is not 7-Zip. + If source is 7-Zip that will do acual opeartion, then we can return DROPEFFECT_MOVE. + */ + if (hres != S_OK || (opEffect == DROPEFFECT_MOVE && !needDrop_by_Source)) + { + // opEffect = opEffect; + // opEffect = DROPEFFECT_NONE; // for debug disabled + } + + *effect = opEffect; + /* if (hres < 0), DoDragDrop() also will return (hres). + if (hres >= 0), DoDragDrop() will return DRAGDROP_S_DROP; + */ + return hres; +} + + + +// ---------- CPanel ---------- + + +static bool Is_Path1_Prefixed_by_Path2(const UString &path, const UString &prefix) +{ + const unsigned len = prefix.Len(); + if (path.Len() < len) + return false; + return CompareFileNames(path.Left(len), prefix) == 0; +} + +static bool IsFolderInTemp(const UString &path) +{ + FString tempPathF; + if (!MyGetTempPath(tempPathF)) + return false; + const UString tempPath = fs2us(tempPathF); + if (tempPath.IsEmpty()) + return false; + return Is_Path1_Prefixed_by_Path2(path, tempPath); +} + +static bool AreThereNamesFromTemp(const UStringVector &filePaths) +{ + FString tempPathF; + if (!MyGetTempPath(tempPathF)) + return false; + const UString tempPath = fs2us(tempPathF); + if (tempPath.IsEmpty()) + return false; + FOR_VECTOR (i, filePaths) + if (Is_Path1_Prefixed_by_Path2(filePaths[i], tempPath)) + return true; + return false; +} + + +/* + empty folderPath means create new Archive to path of first fileName. + createNewArchive == true : show "Add to archive ..." dialog with external program + folderPath.IsEmpty() : create archive in folder of filePaths[0]. + createNewArchive == false : + folderPath.IsEmpty() : copy to archive folder that is open in panel + !folderPath.IsEmpty() : CopyFsItems() to folderPath. +*/ +void CPanel::CompressDropFiles( + const UStringVector &filePaths, + const UString &folderPath, + bool createNewArchive, + bool moveMode, + UInt32 sourceFlags, + UInt32 &targetFlags + ) +{ + if (filePaths.Size() == 0) + return; + // createNewArchive = false; // for debug + + if (createNewArchive) + { + UString folderPath2 = folderPath; + // folderPath2.Empty(); // for debug + if (folderPath2.IsEmpty()) + { + { + FString folderPath2F; + GetOnlyDirPrefix(us2fs(filePaths.Front()), folderPath2F); + folderPath2 = fs2us(folderPath2F); + } + if (IsFolderInTemp(folderPath2)) + { + /* we don't want archive to be created in temp directory. + so we change the path to root folder (non-temp) */ + folderPath2 = ROOT_FS_FOLDER; + } + } + + UString arcName_base; + const UString arcName = CreateArchiveName(filePaths, + false, // isHash + NULL, // CFileInfo *fi + arcName_base); + + bool needWait; + if (sourceFlags & k_SourceFlags_WaitFinish) + needWait = true; + else if (sourceFlags & k_SourceFlags_DoNotWaitFinish) + needWait = false; + else if (sourceFlags & k_SourceFlags_TempFiles) + needWait = true; + else + needWait = AreThereNamesFromTemp(filePaths); + + targetFlags |= (needWait ? + k_TargetFlags_WaitFinish : + k_TargetFlags_DoNotWaitFinish); + + CompressFiles(folderPath2, arcName, + L"", // arcType + true, // addExtension + filePaths, + false, // email + true, // showDialog + needWait); + } + else + { + targetFlags |= k_TargetFlags_WaitFinish; + if (!folderPath.IsEmpty()) + { + CCopyToOptions options; + options.moveMode = moveMode; + options.folder = folderPath; + options.showErrorMessages = true; // showErrorMessages is not used for this operation + options.NeedRegistryZone = false; + options.ZoneIdMode = NExtract::NZoneIdMode::kNone; + // maybe we need more options here: FIXME + /* HRESULT hres = */ CopyFsItems(options, + filePaths, + NULL // UStringVector *messages + ); + // hres = hres; + } + else + { + CopyFromNoAsk(moveMode, filePaths); + } + } +} + + + +static unsigned Drag_OnContextMenu(int xPos, int yPos, UInt32 cmdFlags) +{ + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + /* + Esc key in shown menu doesn't work if we call Drag_OnContextMenu from ::Drop(). + We call SetFocus() tp solve that problem. + But the focus will be changed to Target Window after Drag and Drop. + Is it OK to use SetFocus() here ? + Is there another way to enable Esc key ? + */ + // _listView.SetFocus(); // for debug + ::SetFocus(g_HWND); + menu.CreatePopup(); + /* + int defaultCmd; // = NDragMenu::k_Move; + defaultCmd = NDragMenu::k_None; + */ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(NDragMenu::g_Pairs); i++) + { + const NDragMenu::CCmdLangPair &pair = NDragMenu::g_Pairs[i]; + const UInt32 cmdAndFlags = pair.CmdId_and_Flags; + const UInt32 cmdId = cmdAndFlags & NDragMenu::k_MenuFlags_CmdMask; + if (cmdId != NDragMenu::k_Cancel) + if ((cmdFlags & ((UInt32)1 << cmdId)) == 0) + continue; + const UINT flags = MF_STRING; + /* + if (prop.IsVisible) + flags |= MF_CHECKED; + if (i == 0) + flags |= MF_GRAYED; + */ + // MF_DEFAULT doesn't work + // if (i == 2) flags |= MF_DEFAULT; + // if (i == 4) flags |= MF_HILITE; + // if (cmd == defaultCmd) flags |= MF_HILITE; + UString name = LangString(pair.LangId); + if (name.IsEmpty()) + { + if (cmdId == NDragMenu::k_Cancel) + name = "Cancel"; + else + name.Add_UInt32(pair.LangId); + } + if (cmdId == NDragMenu::k_Copy_ToArc) + { + // UString destPath = _currentFolderPrefix; + /* + UString destPath = LangString(IDS_CONTEXT_ARCHIVE); + name = MyFormatNew(name, destPath); + */ + name.Add_Space(); + AddLangString(name, IDS_CONTEXT_ARCHIVE); + } + if (cmdId == NDragMenu::k_Cancel) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); + menu.AppendItem(flags, cmdAndFlags, name); + } + /* + if (defaultCmd != 0) + SetMenuDefaultItem(menu, (unsigned)defaultCmd, + FALSE); // byPos + */ + int menuResult = menu.Track( + TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + xPos, yPos, + g_HWND + // _listView // for debug + ); + /* menu.Track() return value is zero, if the user cancels + the menu without making a selection, or if an error occurs */ + if (menuResult <= 0) + menuResult = NDragMenu::k_Cancel; + return (unsigned)menuResult; +} + + + +void CApp::CreateDragTarget() +{ + _dropTargetSpec = new CDropTarget(); + _dropTarget = _dropTargetSpec; + _dropTargetSpec->App = (this); +} + +void CApp::SetFocusedPanel(unsigned index) +{ + LastFocusedPanel = index; + _dropTargetSpec->TargetPanelIndex = (int)LastFocusedPanel; +} + +void CApp::DragBegin(unsigned panelIndex) +{ + _dropTargetSpec->TargetPanelIndex = (int)(NumPanels > 1 ? 1 - panelIndex : panelIndex); + _dropTargetSpec->SrcPanelIndex = (int)panelIndex; +} + +void CApp::DragEnd() +{ + _dropTargetSpec->TargetPanelIndex = (int)LastFocusedPanel; + _dropTargetSpec->SrcPanelIndex = -1; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelFolderChange.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelFolderChange.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelFolderChange.cpp 2015-10-03 18:09:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelFolderChange.cpp 2025-06-16 08:00:00.000000000 +0000 @@ -1,821 +1,1122 @@ -// PanelFolderChange.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/PropVariant.h" - -#include "../../PropID.h" - -#ifdef UNDER_CE -#include "FSFolder.h" -#else -#include "FSDrives.h" -#endif -#include "LangUtils.h" -#include "ListViewDialog.h" -#include "Panel.h" -#include "RootFolder.h" -#include "ViewSettings.h" - -#include "resource.h" - -using namespace NWindows; -using namespace NFile; -using namespace NFind; - -void CPanel::ReleaseFolder() -{ - _folder.Release(); - - _folderCompare.Release(); - _folderGetItemName.Release(); - _folderRawProps.Release(); - _folderAltStreams.Release(); - _folderOperations.Release(); - - _thereAreDeletedItems = false; -} - -void CPanel::SetNewFolder(IFolderFolder *newFolder) -{ - ReleaseFolder(); - _folder = newFolder; - if (_folder) - { - _folder.QueryInterface(IID_IFolderCompare, &_folderCompare); - _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName); - _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps); - _folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams); - _folder.QueryInterface(IID_IFolderOperations, &_folderOperations); - } -} - -void CPanel::SetToRootFolder() -{ - ReleaseFolder(); - _library.Free(); - - CRootFolder *rootFolderSpec = new CRootFolder; - SetNewFolder(rootFolderSpec); - rootFolderSpec->Init(); -} - -HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted) -{ - UString path = fullPath; - #ifdef _WIN32 - path.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - - archiveIsOpened = false; - encrypted = false; - - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - - for (; !_parentFolders.IsEmpty(); CloseOneLevel()) - { - // ---------- we try to use open archive ---------- - - const CFolderLink &link = _parentFolders.Back(); - const UString &virtPath = link.VirtualPath; - if (!path.IsPrefixedBy(virtPath)) - continue; - UString relatPath = path.Ptr(virtPath.Len()); - if (!relatPath.IsEmpty()) - { - if (!IS_PATH_SEPAR(relatPath[0])) - continue; - else - relatPath.Delete(0); - } - - UString relatPath2 = relatPath; - if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back())) - relatPath2.Add_PathSepar(); - - for (;;) - { - const UString foldPath = GetFolderPath(_folder); - if (relatPath2 == foldPath) - break; - if (relatPath.IsPrefixedBy(foldPath)) - { - path = relatPath.Ptr(foldPath.Len()); - break; - } - CMyComPtr newFolder; - if (_folder->BindToParentFolder(&newFolder) != S_OK) - throw 20140918; - if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder) - throw 20140918; - SetNewFolder(newFolder); - } - break; - } - - if (_parentFolders.IsEmpty()) - { - // ---------- we open file or folder from file system ---------- - - CloseOpenFolders(); - UString sysPath = path; - - unsigned prefixSize = NName::GetRootPrefixSize(sysPath); - if (prefixSize == 0 || sysPath[prefixSize] == 0) - sysPath.Empty(); - - #if defined(_WIN32) && !defined(UNDER_CE) - if (!sysPath.IsEmpty() && sysPath.Back() == ':' && - (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath))) - { - UString baseFile = sysPath; - baseFile.DeleteBack(); - if (NFind::DoesFileOrDirExist(us2fs(baseFile))) - sysPath.Empty(); - } - #endif - - CFileInfo fileInfo; - - while (!sysPath.IsEmpty()) - { - if (fileInfo.Find(us2fs(sysPath))) - break; - int pos = sysPath.ReverseFind_PathSepar(); - if (pos < 0) - sysPath.Empty(); - else - { - /* - if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1) - reducedParts.Add(sysPath.Ptr(pos + 1)); - */ - #if defined(_WIN32) && !defined(UNDER_CE) - if (pos == 2 && NName::IsDrivePath2(sysPath) && sysPath.Len() > 3) - pos++; - #endif - - sysPath.DeleteFrom(pos); - } - } - - SetToRootFolder(); - - CMyComPtr newFolder; - - if (sysPath.IsEmpty()) - { - _folder->BindToFolder(path, &newFolder); - } - else if (fileInfo.IsDir()) - { - NName::NormalizeDirPathPrefix(sysPath); - _folder->BindToFolder(sysPath, &newFolder); - } - else - { - FString dirPrefix, fileName; - NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); - HRESULT res; - // = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted); - { - CTempFileInfo tfi; - tfi.RelPath = fs2us(fileName); - tfi.FolderPath = dirPrefix; - tfi.FilePath = us2fs(sysPath); - res = OpenItemAsArchive(NULL, tfi, sysPath, arcFormat, encrypted); - } - - if (res == S_FALSE) - _folder->BindToFolder(fs2us(dirPrefix), &newFolder); - else - { - RINOK(res); - archiveIsOpened = true; - _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix); - path.DeleteFrontal(sysPath.Len()); - if (!path.IsEmpty() && IS_PATH_SEPAR(path[0])) - path.Delete(0); - } - } - if (newFolder) - { - SetNewFolder(newFolder); - // LoadFullPath(); - return S_OK; - } - } - - { - // ---------- we open folder remPath in archive and sub archives ---------- - - for (unsigned curPos = 0; curPos != path.Len();) - { - UString s = path.Ptr(curPos); - int slashPos = NName::FindSepar(s); - unsigned skipLen = s.Len(); - if (slashPos >= 0) - { - s.DeleteFrom(slashPos); - skipLen = slashPos + 1; - } - - CMyComPtr newFolder; - _folder->BindToFolder(s, &newFolder); - if (newFolder) - curPos += skipLen; - else if (_folderAltStreams) - { - int pos = s.Find(L':'); - if (pos >= 0) - { - UString baseName = s; - baseName.DeleteFrom(pos); - if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder) - curPos += pos + 1; - } - } - - if (!newFolder) - break; - - SetNewFolder(newFolder); - } - } - - return S_OK; -} - -HRESULT CPanel::BindToPathAndRefresh(const UString &path) -{ - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - bool archiveIsOpened, encrypted; - RINOK(BindToPath(path, UString(), archiveIsOpened, encrypted)); - RefreshListCtrl(UString(), -1, true, UStringVector()); - return S_OK; -} - -void CPanel::SetBookmark(int index) -{ - _appState->FastFolders.SetString(index, _currentFolderPrefix); -} - -void CPanel::OpenBookmark(int index) -{ - BindToPathAndRefresh(_appState->FastFolders.GetString(index)); -} - -UString GetFolderPath(IFolderFolder *folder) -{ - { - NCOM::CPropVariant prop; - if (folder->GetFolderProperty(kpidPath, &prop) == S_OK) - if (prop.vt == VT_BSTR) - return (wchar_t *)prop.bstrVal; - } - return UString(); -} - -void CPanel::LoadFullPath() -{ - _currentFolderPrefix.Empty(); - FOR_VECTOR (i, _parentFolders) - { - const CFolderLink &folderLink = _parentFolders[i]; - _currentFolderPrefix += folderLink.ParentFolderPath; - // GetFolderPath(folderLink.ParentFolder); - _currentFolderPrefix += folderLink.RelPath; - _currentFolderPrefix.Add_PathSepar(); - } - if (_folder) - _currentFolderPrefix += GetFolderPath(_folder); -} - -static int GetRealIconIndex(CFSTR path, DWORD attributes) -{ - int index = -1; - if (GetRealIconIndex(path, attributes, index) != 0) - return index; - return -1; -} - -void CPanel::LoadFullPathAndShow() -{ - LoadFullPath(); - _appState->FolderHistory.AddString(_currentFolderPrefix); - -#ifdef _WIN32 - _headerComboBox.SetText(_currentFolderPrefix); -#else - { - extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); - UString tmp = nameWindowToUnix(_currentFolderPrefix); - _headerComboBox.SetText(tmp); - } -#endif - -#ifdef _WIN32 // FIXME - #ifndef UNDER_CE - - COMBOBOXEXITEM item; - item.mask = 0; - - UString path = _currentFolderPrefix; - if (path.Len() > - #ifdef _WIN32 - 3 - #else - 1 - #endif - && path.Back() == WCHAR_PATH_SEPARATOR) - path.DeleteBack(); - - DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; - - // GetRealIconIndex is slow for direct DVD/UDF path. So we use dummy path - if (path.IsPrefixedBy(L"\\\\.\\")) - path = L"_TestFolder_"; - else - { - CFileInfo fi; - if (fi.Find(us2fs(path))) - attrib = fi.Attrib; - } - item.iImage = GetRealIconIndex(us2fs(path), attrib); - - if (item.iImage >= 0) - { - item.iSelectedImage = item.iImage; - item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); - } - item.iItem = -1; - _headerComboBox.SetItem(&item); - - #endif -#endif - - RefreshTitle(); -} - -#ifndef UNDER_CE -LRESULT CPanel::OnNotifyComboBoxEnter(const UString &s) -{ - if (BindToPathAndRefresh(GetUnicodeString(s)) == S_OK) - { - // FIXME PostMsg(kSetFocusToListView); - return TRUE; - } - return FALSE; -} - -bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) -{ - if (info->iWhy == CBENF_ESCAPE) - { - _headerComboBox.SetText(_currentFolderPrefix); - // FIXME PostMsg(kSetFocusToListView); - result = FALSE; - return true; - } - - /* - if (info->iWhy == CBENF_DROPDOWN) - { - result = FALSE; - return true; - } - */ - - if (info->iWhy == CBENF_RETURN) - { - // When we use Edit control and press Enter. - UString s; - _headerComboBox.GetText(s); - result = OnNotifyComboBoxEnter(s); - return true; - } - return false; -} -#endif - -#ifndef _UNICODE -bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) -{ - if (info->iWhy == CBENF_ESCAPE) - { - _headerComboBox.SetText(_currentFolderPrefix); - PostMsg(kSetFocusToListView); - result = FALSE; - return true; - } - /* - if (info->iWhy == CBENF_DROPDOWN) - { - result = FALSE; - return true; - } - */ - - if (info->iWhy == CBENF_RETURN) - { - UString s; - _headerComboBox.GetText(s); - // GetUnicodeString(info->szText) - result = OnNotifyComboBoxEnter(s); - return true; - } - return false; -} -#endif - -void CPanel::AddComboBoxItem(const UString &name, int iconIndex, int indent, bool addToList) -{ - #if 1 // ifdef UNDER_CE - - UString s; - iconIndex = iconIndex; - for (int i = 0; i < indent; i++) - s += L" "; - _headerComboBox.AddString(s + name); - - #else - - COMBOBOXEXITEMW item; - item.mask = CBEIF_TEXT | CBEIF_INDENT; - item.iSelectedImage = item.iImage = iconIndex; - if (iconIndex >= 0) - item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); - item.iItem = -1; - item.iIndent = indent; - item.pszText = (LPWSTR)(LPCWSTR)name; - _headerComboBox.InsertItem(&item); - - #endif - - if (addToList) - ComboBoxPaths.Add(name); -} - -extern UString RootFolder_GetName_Computer(int &iconIndex); -extern UString RootFolder_GetName_Network(int &iconIndex); -extern UString RootFolder_GetName_Documents(int &iconIndex); - -bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result) -{ -#ifdef _WIN32 // FIXME - result = FALSE; - switch (code) - { - case CBN_DROPDOWN: - { - ComboBoxPaths.Clear(); - _headerComboBox.ResetContent(); - - unsigned i; - UStringVector pathParts; - - SplitPathToParts(_currentFolderPrefix, pathParts); - UString sumPass; - if (!pathParts.IsEmpty()) - pathParts.DeleteBack(); - for (i = 0; i < pathParts.Size(); i++) - { - UString name = pathParts[i]; - sumPass += name; - sumPass.Add_PathSepar(); - CFileInfo info; - DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; - if (info.Find(us2fs(sumPass))) - attrib = info.Attrib; - AddComboBoxItem(name.IsEmpty() ? L"\\" : name, GetRealIconIndex(us2fs(sumPass), attrib), i, false); - ComboBoxPaths.Add(sumPass); - } - - #ifndef UNDER_CE - - int iconIndex; - UString name; - name = RootFolder_GetName_Documents(iconIndex); - AddComboBoxItem(name, iconIndex, 0, true); - - name = RootFolder_GetName_Computer(iconIndex); - AddComboBoxItem(name, iconIndex, 0, true); - - FStringVector driveStrings; - MyGetLogicalDriveStrings(driveStrings); - for (i = 0; i < driveStrings.Size(); i++) - { - FString s = driveStrings[i]; - ComboBoxPaths.Add(fs2us(s)); - int iconIndex = GetRealIconIndex(s, 0); - if (s.Len() > 0 && s.Back() == FCHAR_PATH_SEPARATOR) - s.DeleteBack(); - AddComboBoxItem(fs2us(s), iconIndex, 1, false); - } - - name = RootFolder_GetName_Network(iconIndex); - AddComboBoxItem(name, iconIndex, 0, true); - - #endif - - return false; - } - - case CBN_SELENDOK: - { - code = code; - int index = _headerComboBox.GetCurSel(); - if (index >= 0) - { - UString pass = ComboBoxPaths[index]; - _headerComboBox.SetCurSel(-1); - // _headerComboBox.SetText(pass); // it's fix for seclecting by mouse. - if (BindToPathAndRefresh(pass) == S_OK) - { - PostMsg(kSetFocusToListView); - #ifdef UNDER_CE - PostMsg(kRefresh_HeaderComboBox); - #endif - return true; - } - } - return false; - } - /* - case CBN_CLOSEUP: - { - LoadFullPathAndShow(); - true; - - } - case CBN_SELCHANGE: - { - // LoadFullPathAndShow(); - return true; - } - */ - } -#endif - return false; -} - -bool CPanel::OnNotifyComboBox(LPNMHDR NON_CE_VAR(header), LRESULT & NON_CE_VAR(result)) -{ - #ifndef UNDER_CE - switch (header->code) - { - case CBEN_BEGINEDIT: - { - _lastFocusedIsList = false; - _panelCallback->PanelWasFocused(); - break; - } -#ifdef _WIN32 - #ifndef _UNICODE - case CBEN_ENDEDIT: - { - return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); - } - #endif -#endif - case CBEN_ENDEDITW: - { - return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); - } - } - #endif - return false; -} - - -void CPanel::FoldersHistory() -{ - CListViewDialog listViewDialog; - listViewDialog.DeleteIsAllowed = true; - LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title); - _appState->FolderHistory.GetList(listViewDialog.Strings); - if (listViewDialog.Create(GetParent()) != IDOK) - return; - UString selectString; - if (listViewDialog.StringsWereChanged) - { - _appState->FolderHistory.RemoveAll(); - for (int i = listViewDialog.Strings.Size() - 1; i >= 0; i--) - _appState->FolderHistory.AddString(listViewDialog.Strings[i]); - if (listViewDialog.FocusedItemIndex >= 0) - selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; - } - else - { - if (listViewDialog.FocusedItemIndex >= 0) - selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; - } - if (listViewDialog.FocusedItemIndex >= 0) - BindToPathAndRefresh(selectString); -} - -void CPanel::OpenParentFolder() -{ - LoadFullPath(); // Maybe we don't need it ?? - - UString parentFolderPrefix; - UString focusedName; - - if (!_currentFolderPrefix.IsEmpty()) - { - wchar_t c = _currentFolderPrefix.Back(); - if (c == WCHAR_PATH_SEPARATOR || c == ':') - { - focusedName = _currentFolderPrefix; - focusedName.DeleteBack(); - /* - if (c == ':' && !focusedName.IsEmpty() && focusedName.Back() == WCHAR_PATH_SEPARATOR) - { - focusedName.DeleteBack(); - } - else - */ - if (focusedName != L"\\\\." && - focusedName != L"\\\\?") - { - int pos = focusedName.ReverseFind_PathSepar(); - if (pos >= 0) - { - parentFolderPrefix = focusedName; - parentFolderPrefix.DeleteFrom(pos + 1); - focusedName.DeleteFrontal(pos + 1); - } - } - } - } - - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - - CMyComPtr newFolder; - _folder->BindToParentFolder(&newFolder); - - // newFolder.Release(); // for test - - if (newFolder) - SetNewFolder(newFolder); - else - { - bool needSetFolder = true; - if (!_parentFolders.IsEmpty()) - { - { - const CFolderLink &link = _parentFolders.Back(); - parentFolderPrefix = link.ParentFolderPath; - focusedName = link.RelPath; - } - CloseOneLevel(); - needSetFolder = (!_folder); - } - - if (needSetFolder) - { - { - bool archiveIsOpened; - bool encrypted; - BindToPath(parentFolderPrefix, UString(), archiveIsOpened, encrypted); - } - } - } - - UStringVector selectedItems; - /* - if (!focusedName.IsEmpty()) - selectedItems.Add(focusedName); - */ - LoadFullPath(); - // ::SetCurrentDirectory(::_currentFolderPrefix); - RefreshListCtrl(focusedName, -1, true, selectedItems); - // _listView.EnsureVisible(_listView.GetFocusedItem(), false); -} - -void CPanel::CloseOneLevel() -{ - ReleaseFolder(); - _library.Free(); - { - CFolderLink &link = _parentFolders.Back(); - if (link.ParentFolder) - SetNewFolder(link.ParentFolder); - _library.Attach(link.Library.Detach()); - } - if (_parentFolders.Size() > 1) - OpenParentArchiveFolder(); - _parentFolders.DeleteBack(); - if (_parentFolders.IsEmpty()) - _flatMode = _flatModeForDisk; -} - -void CPanel::CloseOpenFolders() -{ - while (!_parentFolders.IsEmpty()) - CloseOneLevel(); - _flatMode = _flatModeForDisk; - ReleaseFolder(); - _library.Free(); -} - -void CPanel::OpenRootFolder() -{ - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - _parentFolders.Clear(); - SetToRootFolder(); - RefreshListCtrl(UString(), -1, true, UStringVector()); - // ::SetCurrentDirectory(::_currentFolderPrefix); - /* - BeforeChangeFolder(); - _currentFolderPrefix.Empty(); - AfterChangeFolder(); - SetCurrentPathText(); - RefreshListCtrl(UString(), 0, UStringVector()); - _listView.EnsureVisible(_listView.GetFocusedItem(), false); - */ -} - -void CPanel::OpenDrivesFolder() -{ - CloseOpenFolders(); - #ifdef UNDER_CE - NFsFolder::CFSFolder *folderSpec = new NFsFolder::CFSFolder; - SetNewFolder(folderSpec); - folderSpec->InitToRoot(); - #else - CFSDrives *folderSpec = new CFSDrives; - SetNewFolder(folderSpec); - folderSpec->Init(); - #endif - RefreshListCtrl(); -} - -void CPanel::OpenFolder(int index) -{ - if (index == kParentIndex) - { - OpenParentFolder(); - return; - } - CMyComPtr newFolder; - _folder->BindToFolder(index, &newFolder); - if (!newFolder) - return; - SetNewFolder(newFolder); - LoadFullPath(); - RefreshListCtrl(); - _listView.SetItemState_Selected(_listView.GetFocusedItem()); - _listView.EnsureVisible(_listView.GetFocusedItem(), false); -} - -void CPanel::OpenAltStreams() -{ - CRecordVector indices; - GetOperatedItemIndices(indices); - Int32 realIndex = -1; - if (indices.Size() > 1) - return; - if (indices.Size() == 1) - realIndex = indices[0]; - - if (_folderAltStreams) - { - CMyComPtr newFolder; - _folderAltStreams->BindToAltStreams(realIndex, &newFolder); - if (newFolder) - { - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - SetNewFolder(newFolder); - RefreshListCtrl(UString(), -1, true, UStringVector()); - return; - } - return; - } - - #if defined(_WIN32) && !defined(UNDER_CE) - UString path; - if (realIndex >= 0) - path = GetItemFullPath(realIndex); - else - { - path = GetFsPath(); - if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path))) - if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back())) - path.DeleteBack(); - } - - path += L':'; - BindToPathAndRefresh(path); - #endif -} +// PanelFolderChange.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#ifdef UNDER_CE +#include "FSFolder.h" +#else +#include "FSDrives.h" +#endif +#include "LangUtils.h" +#include "ListViewDialog.h" +#include "Panel.h" +#include "RootFolder.h" +#include "ViewSettings.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +void CPanel::ReleaseFolder() +{ + DeleteListItems(); + + _folder.Release(); + + _folderCompare.Release(); + _folderGetItemName.Release(); + _folderRawProps.Release(); + _folderAltStreams.Release(); + _folderOperations.Release(); + + _thereAreDeletedItems = false; +} + +void CPanel::SetNewFolder(IFolderFolder *newFolder) +{ + ReleaseFolder(); + _folder = newFolder; + if (_folder) + { + _folder.QueryInterface(IID_IFolderCompare, &_folderCompare); + _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName); + _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps); + _folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams); + _folder.QueryInterface(IID_IFolderOperations, &_folderOperations); + } +} + +void CPanel::SetToRootFolder() +{ + ReleaseFolder(); + _library.Free(); + + CRootFolder *rootFolderSpec = new CRootFolder; + SetNewFolder(rootFolderSpec); + rootFolderSpec->Init(); +} + + +static bool DoesNameContainWildcard_SkipRoot(const UString &path) +{ + return DoesNameContainWildcard(path.Ptr(NName::GetRootPrefixSize(path))); +} + +HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, COpenResult &openRes) +{ + UString path = fullPath; + #ifdef _WIN32 + path.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + + openRes.ArchiveIsOpened = false; + openRes.Encrypted = false; + + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + + for (; !_parentFolders.IsEmpty(); CloseOneLevel()) + { + // ---------- we try to use open archive ---------- + + const CFolderLink &link = _parentFolders.Back(); + const UString &virtPath = link.VirtualPath; + if (!path.IsPrefixedBy(virtPath)) + continue; + UString relatPath = path.Ptr(virtPath.Len()); + if (!relatPath.IsEmpty()) + { + if (!IS_PATH_SEPAR(relatPath[0])) + continue; + else + relatPath.Delete(0); + } + + UString relatPath2 = relatPath; + if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back())) + relatPath2.Add_PathSepar(); + + for (;;) + { + const UString foldPath = GetFolderPath(_folder); + if (relatPath2 == foldPath) + break; + if (relatPath.IsPrefixedBy(foldPath)) + { + path = relatPath.Ptr(foldPath.Len()); + break; + } + CMyComPtr newFolder; + if (_folder->BindToParentFolder(&newFolder) != S_OK) + throw 20140918; + if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder) + throw 20140918; + SetNewFolder(newFolder); + } + break; + } + + if (_parentFolders.IsEmpty()) + { + // ---------- we open file or folder from file system ---------- + + CloseOpenFolders(); + UString sysPath = path; + /* we will Empty() sysPath variable, if we need to BindToFolder() + directly with (path) variable */ + const unsigned prefixSize = NName::GetRootPrefixSize(sysPath); + if (prefixSize == 0 || sysPath[prefixSize] == 0) + sysPath.Empty(); + + #if defined(_WIN32) && !defined(UNDER_CE) + if (!sysPath.IsEmpty() && sysPath.Back() == ':' && + (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath))) + { + // if base item for alt streams prefix "base:" exists, we will use it + UString baseFile = sysPath; + baseFile.DeleteBack(); + if (NFind::DoesFileOrDirExist(us2fs(baseFile))) + sysPath.Empty(); + } + #endif + + CFileInfo fileInfo; + + while (!sysPath.IsEmpty()) + { + if (sysPath.Len() <= prefixSize) + { + path.DeleteFrom(prefixSize); + sysPath.Empty(); + break; + } + + fileInfo.ClearBase(); + if (IsPathSepar(sysPath.Back())) + { + /* Windows 10 by default doesn't allow look "Local Settings" that is junction to "AppData\Local", + but it does allow look "Local Settings\Temp\*" + 22.02: at first we try to use paths with slashes "path\" */ + CFileInfo fi; + // CFindFile findFile; + // FString path2 = us2fs(sysPath); + // path2 += '*'; // CHAR_ANY_MASK; + // if (findFile.FindFirst(path2, fi)) + CEnumerator enumerator; + enumerator.SetDirPrefix(us2fs(sysPath)); + bool found = false; + if (enumerator.Next(fi, found)) + { + // sysPath.DeleteBack(); + fileInfo.SetAsDir(); + fileInfo.Size = 0; + fileInfo.Name.Empty(); + break; + } + sysPath.DeleteBack(); + continue; + } + + if (fileInfo.Find(us2fs(sysPath))) + break; + int pos = sysPath.ReverseFind_PathSepar(); + if (pos < 0) + { + sysPath.Empty(); + break; + } + { + if ((unsigned)pos != sysPath.Len() - 1) + pos++; + sysPath.DeleteFrom((unsigned)pos); + } + } + + SetToRootFolder(); + + CMyComPtr newFolder; + + if (sysPath.IsEmpty()) + { + _folder->BindToFolder(path, &newFolder); + } + else if (fileInfo.IsDir()) + { + #ifdef _WIN32 + if (DoesNameContainWildcard_SkipRoot(sysPath)) + { + FString dirPrefix, fileName; + NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); + if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix))) + return E_INVALIDARG; + sysPath = fs2us(dirPrefix + fileInfo.Name); + } + #endif + + NName::NormalizeDirPathPrefix(sysPath); + _folder->BindToFolder(sysPath, &newFolder); + } + else + { + FString dirPrefix, fileName; + + NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); + + HRESULT res = S_OK; + + #ifdef _WIN32 + if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix))) + return E_INVALIDARG; + + if (DoesNameContainWildcard(fs2us(fileName))) + res = S_FALSE; + else + #endif + { + CTempFileInfo tfi; + tfi.RelPath = fs2us(fileName); + tfi.FolderPath = dirPrefix; + tfi.FilePath = us2fs(sysPath); + res = OpenAsArc(NULL, tfi, sysPath, arcFormat, openRes); + } + + if (res == S_FALSE) + _folder->BindToFolder(fs2us(dirPrefix), &newFolder); + else + { + RINOK(res) + openRes.ArchiveIsOpened = true; + _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix); + path.DeleteFrontal(sysPath.Len()); + if (!path.IsEmpty() && IS_PATH_SEPAR(path[0])) + path.Delete(0); + } + } + + if (newFolder) + { + SetNewFolder(newFolder); + // LoadFullPath(); + return S_OK; + } + } + + { + // ---------- we open folder remPath in archive and sub archives ---------- + + for (unsigned curPos = 0; curPos != path.Len();) + { + UString s = path.Ptr(curPos); + const int slashPos = NName::FindSepar(s); + unsigned skipLen = s.Len(); + if (slashPos >= 0) + { + s.DeleteFrom((unsigned)slashPos); + skipLen = (unsigned)slashPos + 1; + } + + CMyComPtr newFolder; + _folder->BindToFolder(s, &newFolder); + if (newFolder) + curPos += skipLen; + else if (_folderAltStreams) + { + const int pos = s.Find(L':'); + if (pos >= 0) + { + UString baseName = s; + baseName.DeleteFrom((unsigned)pos); + if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder) + curPos += (unsigned)pos + 1; + } + } + + if (!newFolder) + break; + + SetNewFolder(newFolder); + } + } + + return S_OK; +} + +HRESULT CPanel::BindToPathAndRefresh(const UString &path) +{ + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + COpenResult openRes; + UString s = path; + + #ifdef _WIN32 + if (!s.IsEmpty() && s[0] == '\"' && s.Back() == '\"') + { + s.DeleteBack(); + s.Delete(0); + } + #endif + + HRESULT res = BindToPath(s, UString(), openRes); + RefreshListCtrl(); + return res; +} + +void CPanel::SetBookmark(unsigned index) +{ + _appState->FastFolders.SetString(index, _currentFolderPrefix); +} + +void CPanel::OpenBookmark(unsigned index) +{ + BindToPathAndRefresh(_appState->FastFolders.GetString(index)); +} + +UString GetFolderPath(IFolderFolder *folder) +{ + { + NCOM::CPropVariant prop; + if (folder->GetFolderProperty(kpidPath, &prop) == S_OK) + if (prop.vt == VT_BSTR) + return (wchar_t *)prop.bstrVal; + } + return UString(); +} + +void CPanel::LoadFullPath() +{ + _currentFolderPrefix.Empty(); + FOR_VECTOR (i, _parentFolders) + { + const CFolderLink &folderLink = _parentFolders[i]; + _currentFolderPrefix += folderLink.ParentFolderPath; + // GetFolderPath(folderLink.ParentFolder); + _currentFolderPrefix += folderLink.RelPath; + _currentFolderPrefix.Add_PathSepar(); + } + if (_folder) + _currentFolderPrefix += GetFolderPath(_folder); +} + + + +static int GetRealIconIndex_for_DirPath(CFSTR path, DWORD attrib) +{ + attrib |= FILE_ATTRIBUTE_DIRECTORY; // optional + int index = -1; + if (Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(path, attrib, index)) + if (index >= 0) + return index; + return g_Ext_to_Icon_Map.GetIconIndex_DIR(attrib); +} + + +extern UString RootFolder_GetName_Computer(int &iconIndex); +extern UString RootFolder_GetName_Network(int &iconIndex); +extern UString RootFolder_GetName_Documents(int &iconIndex); + + +static int Find_FileExtension_DotPos_in_path(const wchar_t *path) +{ + int dotPos = -1; + unsigned i; + for (i = 0;; i++) + { + const wchar_t c = path[i]; + if (c == 0) + return dotPos; + if (c == '.') + dotPos = (int)i; + else if (IS_PATH_SEPAR(c) || c == ':') + dotPos = -1; + } +} + + +void CPanel::LoadFullPathAndShow() +{ + LoadFullPath(); + _appState->FolderHistory.AddString(_currentFolderPrefix); + + _headerComboBox.SetText(_currentFolderPrefix); + + #ifndef UNDER_CE + + COMBOBOXEXITEM item; + item.mask = 0; + item.iImage = -1; + + UString path = _currentFolderPrefix; + // path = "\\\\.\\PhysicalDrive1\\"; // for debug + // path = "\\\\.\\y:\\"; // for debug + if (!path.IsEmpty()) + { + const unsigned rootPrefixSize = NName::GetRootPrefixSize(path); + if (rootPrefixSize == 0 && path[0] != '\\') + { + int iconIndex = -1; + UString name_Computer = RootFolder_GetName_Computer(iconIndex); + name_Computer.Add_PathSepar(); + if (path == name_Computer + || path.IsEqualTo("\\\\?\\")) + item.iImage = iconIndex; + else + { + UString name = RootFolder_GetName_Network(iconIndex); + name.Add_PathSepar(); + if (path == name) + item.iImage = iconIndex; + } + } + + if (item.iImage < 0) + { + if (rootPrefixSize == 0 || rootPrefixSize == path.Len()) + { + DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; + CFileInfo info; + if (info.Find(us2fs(path))) + attrib = info.Attrib; + NName::If_IsSuperPath_RemoveSuperPrefix(path); + item.iImage = GetRealIconIndex_for_DirPath(us2fs(path), attrib); + } + else if (rootPrefixSize == NName::kDevicePathPrefixSize + && NName::IsDevicePath(us2fs(path.Left(path.Len() - 1)))) + { + if (path.IsPrefixedBy_Ascii_NoCase("\\\\.\\")) + path.DeleteFrontal(4); + if (path.Len() > 3) // is not "c:\\" + { + // PhysicalDrive + if (path.Back() == '\\') + path.DeleteBack(); + } + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(path), FILE_ATTRIBUTE_ARCHIVE); + } + else + { + if (path.Back() == '\\') + path.DeleteBack(); + bool need_Fs_Check = true; + bool is_File = false; + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &link = _parentFolders.Back(); + if (link.VirtualPath == path) + { + is_File = true; + if (_parentFolders.Size() != 1) + need_Fs_Check = false; + } + else + need_Fs_Check = false; + } + if (need_Fs_Check) + { + CFileInfo info; + const bool finded = info.Find(us2fs(path)); + DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; + if (finded) + attrib = info.Attrib; + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(path), attrib); + } + if (item.iImage <= 0 && is_File) + { + int dotPos = Find_FileExtension_DotPos_in_path(path); + if (dotPos < 0) + dotPos = (int)path.Len(); + item.iImage = g_Ext_to_Icon_Map.GetIconIndex(FILE_ATTRIBUTE_ARCHIVE, path.Ptr(dotPos)); + } + } + } + } + + if (item.iImage < 0) + item.iImage = g_Ext_to_Icon_Map.GetIconIndex_DIR(); + // if (item.iImage < 0) item.iImage = 0; + // item.iImage = -1; // for debug + if (item.iImage >= 0) + { + item.iSelectedImage = item.iImage; + item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); + } + item.iItem = -1; + _headerComboBox.SetItem(&item); + + #endif + + RefreshTitle(); +} + +#ifndef UNDER_CE +LRESULT CPanel::OnNotifyComboBoxEnter(const UString &s) +{ + if (BindToPathAndRefresh(GetUnicodeString(s)) == S_OK) + { + PostMsg(kSetFocusToListView); + return TRUE; + } + return FALSE; +} + +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMsg(kSetFocusToListView); + result = FALSE; + return true; + } + + /* + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + */ + + if (info->iWhy == CBENF_RETURN) + { + // When we use Edit control and press Enter. + UString s; + _headerComboBox.GetText(s); + result = OnNotifyComboBoxEnter(s); + return true; + } + return false; +} +#endif + +#ifndef _UNICODE +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMsg(kSetFocusToListView); + result = FALSE; + return true; + } + /* + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + */ + + if (info->iWhy == CBENF_RETURN) + { + UString s; + _headerComboBox.GetText(s); + // GetUnicodeString(info->szText) + result = OnNotifyComboBoxEnter(s); + return true; + } + return false; +} +#endif + +void CPanel::AddComboBoxItem(const UString &name, int iconIndex, unsigned indent, bool addToList) +{ + #ifdef UNDER_CE + + UString s; + iconIndex = iconIndex; + for (unsigned i = 0; i < indent; i++) + s += " "; + _headerComboBox.AddString(s + name); + + #else + + COMBOBOXEXITEMW item; + item.mask = CBEIF_TEXT | CBEIF_INDENT; + if (iconIndex < 0) + iconIndex = g_Ext_to_Icon_Map.GetIconIndex_DIR(); + item.iSelectedImage = item.iImage = iconIndex; + if (iconIndex >= 0) + item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); + item.iItem = -1; + item.iIndent = (int)indent; + item.pszText = name.Ptr_non_const(); + _headerComboBox.InsertItem(&item); + + #endif + + if (addToList) + { + UString s = name; + s.Add_PathSepar(); + ComboBoxPaths.Add(s); + } +} + + +bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result) +{ + result = FALSE; + switch (code) + { + case CBN_DROPDOWN: + { + ComboBoxPaths.Clear(); + _headerComboBox.ResetContent(); + + UString sumPath; + UStringVector pathParts; + unsigned indent = 0; + { + UString path = _currentFolderPrefix; + // path = "\\\\.\\y:\\"; // for debug + UString prefix0; + if (path.IsPrefixedBy_Ascii_NoCase("\\\\")) + { + const int separ = FindCharPosInString(path.Ptr(2), '\\'); + if (separ > 0 + && (separ > 1 || path[2] != '.')) // "\\\\.\\" will be processed later + { + const UString s = path.Left(2 + separ); + prefix0 = s; + prefix0.Add_PathSepar(); + AddComboBoxItem(s, + GetRealIconIndex_for_DirPath(us2fs(prefix0), FILE_ATTRIBUTE_DIRECTORY), + indent++, + false); // addToList + ComboBoxPaths.Add(prefix0); + } + } + + unsigned rootPrefixSize = NName::GetRootPrefixSize(path); + + sumPath = path; + + if (rootPrefixSize <= prefix0.Len()) + { + rootPrefixSize = prefix0.Len(); + sumPath.DeleteFrom(rootPrefixSize); + } + else + { + // rootPrefixSize > prefix0.Len() + sumPath.DeleteFrom(rootPrefixSize); + + CFileInfo info; + DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; + if (info.Find(us2fs(sumPath)) && info.IsDir()) + attrib = info.Attrib; + UString s = sumPath.Ptr(prefix0.Len()); + if (!s.IsEmpty()) + { + const wchar_t c = s.Back(); + if (IS_PATH_SEPAR(c)) + s.DeleteBack(); + } + UString path_for_icon = sumPath; + NName::If_IsSuperPath_RemoveSuperPrefix(path_for_icon); + + AddComboBoxItem(s, + GetRealIconIndex_for_DirPath(us2fs(path_for_icon), attrib), + indent++, + false); // addToList + ComboBoxPaths.Add(sumPath); + } + + path.DeleteFrontal(rootPrefixSize); + SplitPathToParts(path, pathParts); + } + + // it's expected that pathParts.Back() is empty, because _currentFolderPrefix has PathSeparator. + unsigned next_Arc_index = 0; + int iconIndex_Computer; + const UString name_Computer = RootFolder_GetName_Computer(iconIndex_Computer); + + // const bool is_devicePrefix = (sumPath.IsEqualTo("\\\\.\\")); + + if (pathParts.Size() > 1) + if (!sumPath.IsEmpty() + || pathParts.Size() != 2 + || pathParts[0] != name_Computer) + for (unsigned i = 0; i + 1 < pathParts.Size(); i++) + { + UString name = pathParts[i]; + sumPath += name; + + bool isRootDir_inLink = false; + if (next_Arc_index < _parentFolders.Size()) + { + const CFolderLink &link = _parentFolders[next_Arc_index]; + if (link.VirtualPath == sumPath) + { + isRootDir_inLink = true; + next_Arc_index++; + } + } + + int iconIndex = -1; + DWORD attrib = isRootDir_inLink ? + FILE_ATTRIBUTE_ARCHIVE: + FILE_ATTRIBUTE_DIRECTORY; + if (next_Arc_index == 0 + || (next_Arc_index == 1 && isRootDir_inLink)) + { + if (i == 0 && NName::IsDevicePath(us2fs(sumPath))) + { + UString path = name; + path.Add_PathSepar(); + attrib = FILE_ATTRIBUTE_ARCHIVE; + // FILE_ATTRIBUTE_DIRECTORY; + } + else + { + CFileInfo info; + if (info.Find(us2fs(sumPath))) + attrib = info.Attrib; + } + iconIndex = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(sumPath), attrib); + } + + if (iconIndex < 0) + iconIndex = g_Ext_to_Icon_Map.GetIconIndex(attrib, name); + // iconIndex = -1; // for debug + if (iconIndex < 0 && isRootDir_inLink) + iconIndex = 0; // default file + + sumPath.Add_PathSepar(); + + ComboBoxPaths.Add(sumPath); + if (name.IsEmpty()) + name.Add_PathSepar(); + AddComboBoxItem(name, iconIndex, indent++, + false); // addToList + } + +#ifndef UNDER_CE + + { + int iconIndex; + const UString name = RootFolder_GetName_Documents(iconIndex); + // iconIndex = -1; // for debug + AddComboBoxItem(name, iconIndex, 0, true); + } + AddComboBoxItem(name_Computer, iconIndex_Computer, 0, true); + { + FStringVector driveStrings; + MyGetLogicalDriveStrings(driveStrings); + FOR_VECTOR (i, driveStrings) + { + FString s = driveStrings[i]; + ComboBoxPaths.Add(fs2us(s)); + int iconIndex2 = GetRealIconIndex_for_DirPath(s, FILE_ATTRIBUTE_DIRECTORY); + if (!s.IsEmpty()) + { + const FChar c = s.Back(); + if (IS_PATH_SEPAR(c)) + s.DeleteBack(); + } + // iconIndex2 = -1; // for debug + AddComboBoxItem(fs2us(s), iconIndex2, 1, false); + } + } + { + int iconIndex; + const UString name = RootFolder_GetName_Network(iconIndex); + AddComboBoxItem(name, iconIndex, 0, true); + } + +#endif + + return false; + } + + case CBN_SELENDOK: + { + int index = _headerComboBox.GetCurSel(); + if (index >= 0) + { + const UString path = ComboBoxPaths[index]; + _headerComboBox.SetCurSel(-1); + // _headerComboBox.SetText(pass); // it's fix for selecting by mouse. + if (BindToPathAndRefresh(path) == S_OK) + { + PostMsg(kSetFocusToListView); + #ifdef UNDER_CE + PostMsg(kRefresh_HeaderComboBox); + #endif + return true; + } + } + return false; + } + /* + case CBN_CLOSEUP: + { + LoadFullPathAndShow(); + true; + + } + case CBN_SELCHANGE: + { + // LoadFullPathAndShow(); + return true; + } + */ + } + return false; +} + +bool CPanel::OnNotifyComboBox(LPNMHDR NON_CE_VAR(header), LRESULT & NON_CE_VAR(result)) +{ + #ifndef UNDER_CE + switch (header->code) + { + case CBEN_BEGINEDIT: + { + _lastFocusedIsList = false; + _panelCallback->PanelWasFocused(); + break; + } + #ifndef _UNICODE + case CBEN_ENDEDIT: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); + } + #endif + case CBEN_ENDEDITW: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); + } + } + #endif + return false; +} + + +void CPanel::FoldersHistory() +{ + CListViewDialog listViewDialog; + listViewDialog.DeleteIsAllowed = true; + listViewDialog.SelectFirst = true; + LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title); + _appState->FolderHistory.GetList(listViewDialog.Strings); + if (listViewDialog.Create(GetParent()) != IDOK) + return; + UString selectString; + if (listViewDialog.StringsWereChanged) + { + _appState->FolderHistory.RemoveAll(); + for (int i = (int)listViewDialog.Strings.Size() - 1; i >= 0; i--) + _appState->FolderHistory.AddString(listViewDialog.Strings[i]); + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + else + { + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + if (listViewDialog.FocusedItemIndex >= 0) + BindToPathAndRefresh(selectString); +} + + +UString CPanel::GetParentDirPrefix() const +{ + UString s; + if (!_currentFolderPrefix.IsEmpty()) + { + wchar_t c = _currentFolderPrefix.Back(); + if (IS_PATH_SEPAR(c) || c == ':') + { + s = _currentFolderPrefix; + s.DeleteBack(); + if (!s.IsEqualTo("\\\\.") && + !s.IsEqualTo("\\\\?")) + { + int pos = s.ReverseFind_PathSepar(); + if (pos >= 0) + s.DeleteFrom((unsigned)(pos + 1)); + } + } + } + return s; +} + + +void CPanel::OpenParentFolder() +{ + LoadFullPath(); // Maybe we don't need it ?? + + UString parentFolderPrefix; + UString focusedName; + + if (!_currentFolderPrefix.IsEmpty()) + { + wchar_t c = _currentFolderPrefix.Back(); + if (IS_PATH_SEPAR(c) || c == ':') + { + focusedName = _currentFolderPrefix; + focusedName.DeleteBack(); + /* + if (c == ':' && !focusedName.IsEmpty() && IS_PATH_SEPAR(focusedName.Back())) + { + focusedName.DeleteBack(); + } + else + */ + if (!focusedName.IsEqualTo("\\\\.") && + !focusedName.IsEqualTo("\\\\?")) + { + const int pos = focusedName.ReverseFind_PathSepar(); + if (pos >= 0) + { + parentFolderPrefix = focusedName; + parentFolderPrefix.DeleteFrom((unsigned)(pos + 1)); + focusedName.DeleteFrontal((unsigned)(pos + 1)); + } + } + } + } + + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + + // newFolder.Release(); // for test + + if (newFolder) + SetNewFolder(newFolder); + else + { + bool needSetFolder = true; + if (!_parentFolders.IsEmpty()) + { + { + const CFolderLink &link = _parentFolders.Back(); + parentFolderPrefix = link.ParentFolderPath; + focusedName = link.RelPath; + } + CloseOneLevel(); + needSetFolder = (!_folder); + } + + if (needSetFolder) + { + { + COpenResult openRes; + BindToPath(parentFolderPrefix, UString(), openRes); + } + } + } + + CSelectedState state; + state.FocusedName = focusedName; + state.FocusedName_Defined = true; + /* + if (!focusedName.IsEmpty()) + state.SelectedNames.Add(focusedName); + */ + LoadFullPath(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + RefreshListCtrl(state); + // _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + + +void CPanel::CloseOneLevel() +{ + ReleaseFolder(); + _library.Free(); + { + CFolderLink &link = _parentFolders.Back(); + if (link.ParentFolder) + SetNewFolder(link.ParentFolder); + _library.Attach(link.Library.Detach()); + } + if (_parentFolders.Size() > 1) + OpenParentArchiveFolder(); + _parentFolders.DeleteBack(); + if (_parentFolders.IsEmpty()) + _flatMode = _flatModeForDisk; +} + +void CPanel::CloseOpenFolders() +{ + while (!_parentFolders.IsEmpty()) + CloseOneLevel(); + _flatMode = _flatModeForDisk; + ReleaseFolder(); + _library.Free(); +} + +void CPanel::OpenRootFolder() +{ + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + _parentFolders.Clear(); + SetToRootFolder(); + RefreshListCtrl(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + /* + BeforeChangeFolder(); + _currentFolderPrefix.Empty(); + AfterChangeFolder(); + SetCurrentPathText(); + RefreshListCtrl(UString(), 0, UStringVector()); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + */ +} + +void CPanel::OpenDrivesFolder() +{ + CloseOpenFolders(); + #ifdef UNDER_CE + NFsFolder::CFSFolder *folderSpec = new NFsFolder::CFSFolder; + SetNewFolder(folderSpec); + folderSpec->InitToRoot(); + #else + CFSDrives *folderSpec = new CFSDrives; + SetNewFolder(folderSpec); + folderSpec->Init(); + #endif + RefreshListCtrl(); +} + +void CPanel::OpenFolder(unsigned index) +{ + if (index == kParentIndex) + { + OpenParentFolder(); + return; + } + CMyComPtr newFolder; + const HRESULT res = _folder->BindToFolder((unsigned)index, &newFolder); + if (res != 0) + { + MessageBox_Error_HRESULT(res); + return; + } + if (!newFolder) + return; + SetNewFolder(newFolder); + LoadFullPath(); + RefreshListCtrl(); + // 17.02: fixed : now we don't select first item + // _listView.SetItemState_Selected(_listView.GetFocusedItem()); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + +void CPanel::OpenAltStreams() +{ + CRecordVector indices; + Get_ItemIndices_Operated(indices); + Int32 realIndex = -1; + if (indices.Size() > 1) + return; + if (indices.Size() == 1) + realIndex = (Int32)indices[0]; + + if (_folderAltStreams) + { + CMyComPtr newFolder; + _folderAltStreams->BindToAltStreams((UInt32)realIndex, &newFolder); + if (newFolder) + { + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + SetNewFolder(newFolder); + RefreshListCtrl(); + return; + } + return; + } + + #if defined(_WIN32) && !defined(UNDER_CE) + UString path; + if (realIndex >= 0) + path = GetItemFullPath((UInt32)realIndex); + else + { + path = GetFsPath(); + if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path))) + if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back())) + path.DeleteBack(); + } + + path.Add_Colon(); + BindToPathAndRefresh(path); + #endif +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelItemOpen.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItemOpen.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelItemOpen.cpp 2015-09-19 19:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItemOpen.cpp 2024-10-22 09:00:00.000000000 +0000 @@ -1,1269 +1,1798 @@ -// PanelItemOpen.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif -#include "wx/mimetype.h" - -#undef _WIN32 - -// #include - -#include "../../../Common/AutoPtr.h" -#include "../../../Common/StringConvert.h" - -// #include "../../../Windows/ProcessUtils.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../Common/FileStreams.h" -#include "../../Common/StreamObjects.h" - -#include "../Common/ExtractingFilePath.h" - -#include "App.h" - -#include "FileFolderPluginOpen.h" -#include "FormatUtils.h" -#include "LangUtils.h" -#include "RegistryUtils.h" -#include "UpdateCallback100.h" - -#include "resource.h" - -using namespace NWindows; -using namespace NSynchronization; -using namespace NFile; -using namespace NDir; - -extern UInt64 g_RAM_Size; - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -static CFSTR kTempDirPrefix = FTEXT("7zO"); - -#if 0 // ifndef UNDER_CE - -class CProcessSnapshot -{ - HANDLE _handle; -public: - CProcessSnapshot(): _handle(INVALID_HANDLE_VALUE) {}; - ~CProcessSnapshot() { Close(); } - - bool Close() - { - if (_handle == INVALID_HANDLE_VALUE) - return true; - if (!::CloseHandle(_handle)) - return false; - _handle = INVALID_HANDLE_VALUE; - return true; - } - - bool Create() - { - _handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - return (_handle != INVALID_HANDLE_VALUE); - } - - bool GetFirstProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32First(_handle, pe)); } - bool GetNextProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32Next(_handle, pe)); } -}; - -typedef DWORD (WINAPI *GetProcessIdFunc)(HANDLE process); - -class CChildProcesses -{ - #ifndef UNDER_CE - CRecordVector _ids; - #endif -public: - CRecordVector Handles; - CRecordVector NeedWait; - - ~CChildProcesses() { CloseAll(); } - void DisableWait(int index) { NeedWait[index] = false; } - - void CloseAll() - { - FOR_VECTOR (i, Handles) - { - HANDLE h = Handles[i]; - if (h != NULL) - CloseHandle(h); - } - Handles.Clear(); - NeedWait.Clear(); - } - - void AddProcess(HANDLE h) - { - #ifndef UNDER_CE - GetProcessIdFunc func = (GetProcessIdFunc)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId"); - if (func) - _ids.AddToUniqueSorted(func(h)); - #endif - Handles.Add(h); - NeedWait.Add(true); - } - - void Update() - { - #ifndef UNDER_CE - CRecordVector ids, parents; - { - CProcessSnapshot snapshot; - if (snapshot.Create()) - { - PROCESSENTRY32 pe; - memset(&pe, 0, sizeof(pe)); - pe.dwSize = sizeof(pe); - BOOL res = snapshot.GetFirstProcess(&pe); - while (res) - { - ids.Add(pe.th32ProcessID); - parents.Add(pe.th32ParentProcessID); - res = snapshot.GetNextProcess(&pe); - } - } - } - - for (;;) - { - unsigned i; - for (i = 0; i < ids.Size(); i++) - { - DWORD id = ids[i]; - if (_ids.FindInSorted(parents[i]) >= 0 && - _ids.FindInSorted(id) < 0) - { - HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id); - if (hProcess) - { - _ids.AddToUniqueSorted(id); - Handles.Add(hProcess); - NeedWait.Add(true); - break; - } - } - } - if (i == ids.Size()) - break; - } - #endif - } -}; -#endif - -struct CTmpProcessInfo: public CTempFileInfo -{ - HANDLE ProcessHandle; // CChildProcesses Processes; - HWND Window; - UString FullPathFolderPrefix; - bool UsePassword; - UString Password; - - CTmpProcessInfo(): UsePassword(false) {} -}; - -class CTmpProcessInfoRelease -{ - CTmpProcessInfo *_tmpProcessInfo; -public: - bool _needDelete; - CTmpProcessInfoRelease(CTmpProcessInfo &tpi): - _tmpProcessInfo(&tpi), _needDelete(true) {} - ~CTmpProcessInfoRelease() - { - if (_needDelete) - _tmpProcessInfo->DeleteDirAndFile(); - } -}; - -HRESULT CPanel::OpenItemAsArchive(IInStream *inStream, - const CTempFileInfo &tempFileInfo, - const UString &virtualFilePath, - const UString &arcFormat, - bool &encrypted) -{ - encrypted = false; - CFolderLink folderLink; - (CTempFileInfo &)folderLink = tempFileInfo; - if (inStream) - folderLink.IsVirtual = true; - else - { - if (!folderLink.FileInfo.Find(folderLink.FilePath)) - return ::GetLastError(); - if (folderLink.FileInfo.IsDir()) - return S_FALSE; - folderLink.IsVirtual = false; - } - - folderLink.VirtualPath = virtualFilePath; - - CMyComPtr newFolder; - - // _passwordIsDefined = false; - // _password.Empty(); - - NDLL::CLibrary library; - - UString password; - RINOK(OpenFileFolderPlugin(inStream, - folderLink.FilePath.IsEmpty() ? us2fs(virtualFilePath) : folderLink.FilePath, - arcFormat, - &library, &newFolder, GetParent(), encrypted, password)); - - folderLink.Password = password; - folderLink.UsePassword = encrypted; - - if (_folder) - folderLink.ParentFolderPath = GetFolderPath(_folder); - else - folderLink.ParentFolderPath = _currentFolderPrefix; - if (!_parentFolders.IsEmpty()) - folderLink.ParentFolder = _folder; - - _parentFolders.Add(folderLink); - _parentFolders.Back().Library.Attach(_library.Detach()); - - ReleaseFolder(); - _library.Free(); - SetNewFolder(newFolder); - _library.Attach(library.Detach()); - - _flatMode = _flatModeForArc; - - CMyComPtr getFolderArcProps; - _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); - _thereAreDeletedItems = false; - if (getFolderArcProps) - { - CMyComPtr arcProps; - getFolderArcProps->GetFolderArcProps(&arcProps); - if (arcProps) - { - /* - UString s; - UInt32 numLevels; - if (arcProps->GetArcNumLevels(&numLevels) != S_OK) - numLevels = 0; - for (UInt32 level2 = 0; level2 <= numLevels; level2++) - { - UInt32 level = numLevels - level2; - PROPID propIDs[] = { kpidError, kpidPath, kpidType, kpidErrorType } ; - UString values[4]; - for (Int32 i = 0; i < 4; i++) - { - CMyComBSTR name; - NCOM::CPropVariant prop; - if (arcProps->GetArcProp(level, propIDs[i], &prop) != S_OK) - continue; - if (prop.vt != VT_EMPTY) - values[i] = (prop.vt == VT_BSTR) ? prop.bstrVal : L"?"; - } - UString s2; - if (!values[3].IsEmpty()) - { - s2 = L"Can not open the file as [" + values[3] + L"] archive"; - if (level2 != 0) - s2 += L"\nThe file is open as [" + values[2] + L"] archive"; - } - if (!values[0].IsEmpty()) - { - if (!s2.IsEmpty()) - s2.Add_LF(); - s2 += L"["; - s2 += values[2]; - s2 += L"] Error: "; - s2 += values[0]; - } - if (!s2.IsEmpty()) - { - if (!s.IsEmpty()) - s += L"--------------------\n"; - s += values[1]; - s.Add_LF(); - s += s2; - } - } - */ - /* - if (!s.IsEmpty()) - MessageBoxWarning(s); - else - */ - // after MessageBoxWarning it throws exception in nested archives in Debug Mode. why ?. - // MessageBoxWarning(L"test error"); - } - } - - return S_OK; -} - -HRESULT CPanel::OpenItemAsArchive(const UString &relPath, const UString &arcFormat, bool &encrypted) -{ - CTempFileInfo tfi; - tfi.RelPath = relPath; - tfi.FolderPath = us2fs(GetFsPath()); - const UString fullPath = GetFsPath() + relPath; - tfi.FilePath = us2fs(fullPath); - return OpenItemAsArchive(NULL, tfi, fullPath, arcFormat, encrypted); -} - -HRESULT CPanel::OpenItemAsArchive(int index, const wchar_t *type) -{ - CDisableTimerProcessing disableTimerProcessing1(*this); - CDisableNotify disableNotify(*this); - bool encrypted; - HRESULT res = OpenItemAsArchive(GetItemRelPath2(index), type ? type : L"", encrypted); - if (res != S_OK) - { - RefreshTitle(true); // in case of error we must refresh changed title of 7zFM - return res; - } - RefreshListCtrl(); - return S_OK; -} - -HRESULT CPanel::OpenParentArchiveFolder() -{ - CDisableTimerProcessing disableTimerProcessing(*this); - CDisableNotify disableNotify(*this); - if (_parentFolders.Size() < 2) - return S_OK; - const CFolderLink &folderLinkPrev = _parentFolders[_parentFolders.Size() - 2]; - const CFolderLink &folderLink = _parentFolders.Back(); - NFind::CFileInfo newFileInfo; - if (newFileInfo.Find(folderLink.FilePath)) - { - if (folderLink.WasChanged(newFileInfo)) - { - UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath); - if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) - { - if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath), - folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK) - { - ::MessageBoxW((HWND)*this, MyFormatNew(IDS_CANNOT_UPDATE_FILE, - fs2us(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP); - return S_OK; - } - } - } - } - folderLink.DeleteDirAndFile(); - return S_OK; -} - -static const char *kStartExtensions = - #ifdef UNDER_CE - " cab" - #endif - " exe bat com" - " chm" - " msi doc xls ppt pps wps wpt wks xlr wdb vsd pub" - - " docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps" - " xlam pptx pptm potx potm ppam ppsx ppsm xsn" - " mpp" - " msg" - " dwf" - - " flv swf" - - " odt ods" - " wb3" - " pdf" - " "; - -static bool FindExt(const char *p, const UString &name) -{ - int dotPos = name.ReverseFind_Dot(); - if (dotPos < 0 || dotPos == (int)name.Len() - 1) - return false; - - AString s; - for (unsigned pos = dotPos + 1;; pos++) - { - 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 bool DoItemAlwaysStart(const UString &name) -{ - return FindExt(kStartExtensions, name); -} - -UString GetQuotedString(const UString &s); - -static void StartEditApplication(const UString &path, bool useEditor, HWND window /* , CProcess &process */ ) -{ - UString command; - ReadRegEditor(useEditor, command); - if (command.IsEmpty()) - { -#ifdef _WIN32 - #ifdef UNDER_CE - command = L"\\Windows\\"; - #else - FString winDir; - if (!GetWindowsDir(winDir)) - return 0; - NName::NormalizeDirPathPrefix(winDir); - command = fs2us(winDir); - #endif - command += L"notepad.exe"; -#else - command += L"vi"; -#endif - } - -#ifdef _WIN32 - HRESULT res = process.Create(command, GetQuotedString(path), NULL); - if (res != SZ_OK) - ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP); - return res; -#else - wxString cmd = (const wchar_t *)command; - long pid = wxExecute(cmd, wxEXEC_ASYNC); - if (pid) return ; - ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP); -#endif -} - -void CApp::DiffFiles() -{ - const CPanel &panel = GetFocusedPanel(); - - CRecordVector indices; - panel.GetSelectedItemsIndices(indices); - - UString path1, path2; - if (indices.Size() == 2) - { - path1 = panel.GetItemFullPath(indices[0]); - path2 = panel.GetItemFullPath(indices[1]); - } - else if (indices.Size() == 1 && NumPanels >= 2) - { - const CPanel &destPanel = Panels[1 - LastFocusedPanel]; - path1 = panel.GetItemFullPath(indices[0]); - CRecordVector indices2; - destPanel.GetSelectedItemsIndices(indices2); - if (indices2.Size() == 1) - path2 = destPanel.GetItemFullPath(indices2[0]); - else - { - UString relPath = panel.GetItemRelPath2(indices[0]); - if (panel._flatMode && !destPanel._flatMode) - relPath = panel.GetItemName(indices[0]); - path2 = destPanel._currentFolderPrefix + relPath; - } - } - else - return; - - UString command; - ReadRegDiff(command); - if (command.IsEmpty()) - return; - - UString param = GetQuotedString(path1); - param.Add_Space(); - param += GetQuotedString(path2); - -#ifdef _WIN32 - HRESULT res = MyCreateProcess(command, param); - if (res == SZ_OK) - return; -#else - wxString cmd = (const wchar_t *)command; - cmd += L" "; - cmd += (const wchar_t *)param; - - long pid = wxExecute(cmd, wxEXEC_ASYNC); - if (pid) return ; -#endif - ::MessageBoxW(_window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP); -} - -#ifndef _UNICODE -typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo); -#endif - -static void StartApplication(const UString &dir, const UString &path, HWND window /* , CProcess &process */ ) -{ - // FIXME - extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); - UString tmpPath = path; - - wxString filename(nameWindowToUnix(tmpPath)); - - - wxString ext = filename.AfterLast(_T('.')); - - printf("StartApplication(%ls) ext='%ls'\n",(const wchar_t *)filename,(const wchar_t *)ext); - - if ( ! ext.empty() ) - { - wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext); - // printf("StartApplication(%ls) ft=%p\n",(const wchar_t *)filename,ft); - if (ft) - { - wxString cmd; - // wxString type; ft->GetMimeType(&type); - wxFileType::MessageParameters params(filename); // , type); - bool ok = ft->GetOpenCommand(&cmd, params); - // printf("StartApplication(%ls) ok=%d\n",(const wchar_t *)filename,(int)ok); - delete ft; - if ( ok ) - { - printf("StartApplication(%ls) cmd='%ls'\n",(const wchar_t *)filename,(const wchar_t *)cmd); - long pid = wxExecute(cmd, wxEXEC_ASYNC); - if (pid) return ; - } - } - } - ::MessageBoxW(window, - // NError::MyFormatMessageW(::GetLastError()), - L"There is no application associated with the given file name extension", - L"7-Zip", MB_OK | MB_ICONSTOP); - -} - -static void StartApplicationDontWait(const UString &dir, const UString &path, HWND window) -{ - // CProcess process; - StartApplication(dir, path, window /* , process */ ); -} - -void CPanel::EditItem(int index, bool useEditor) -{ - if (!_parentFolders.IsEmpty()) - { - OpenItemInArchive(index, false, true, true, useEditor); - return; - } - // CProcess process; - StartEditApplication(GetItemFullPath(index), useEditor, (HWND)*this /* , process */ ); -} - -void CPanel::OpenFolderExternal(int index) -{ - UString fsPrefix = GetFsPath(); - UString name; - if (index == kParentIndex) - { - int pos = fsPrefix.ReverseFind_PathSepar(); - if (pos >= 0 && pos == (int)fsPrefix.Len() - 1) - { - UString s = fsPrefix.Left(pos); - pos = s.ReverseFind_PathSepar(); - if (pos >= 0) - fsPrefix.SetFrom(s, pos + 1); - } - name = fsPrefix; - } - else - name = fsPrefix + GetItemRelPath(index) + WCHAR_PATH_SEPARATOR; - StartApplicationDontWait(fsPrefix, name, (HWND)*this); -} - -bool CPanel::IsVirus_Message(const UString &name) -{ - UString name2; - - const wchar_t cRLO = (wchar_t)0x202E; - bool isVirus = false; - bool isSpaceError = false; - name2 = name; - - if (name2.Find(cRLO) >= 0) - { - UString badString = cRLO; - name2.Replace(badString, L"[RLO]"); - isVirus = true; - } - { - const wchar_t *kVirusSpaces = L" "; - // const unsigned kNumSpaces = strlen(kVirusSpaces); - for (;;) - { - int pos = name2.Find(kVirusSpaces); - if (pos < 0) - break; - isVirus = true; - isSpaceError = true; - name2.Replace(kVirusSpaces, L" "); - } - } - - if (!isVirus) - return false; - - UString s = LangString(IDS_VIRUS); - - if (!isSpaceError) - { - int pos1 = s.Find(L'('); - if (pos1 >= 0) - { - int pos2 = s.Find(L')', pos1 + 1); - if (pos2 >= 0) - { - s.Delete(pos1, pos2 + 1 - pos1); - if (pos1 > 0 && s[pos1 - 1] == ' ' && s[pos1] == '.') - s.Delete(pos1 - 1); - } - } - } - - UString name3 = name; - name3.Replace(L'\n', L'_'); - name2.Replace(L'\n', L'_'); - - s.Add_LF(); s += name2; - s.Add_LF(); s += name3; - - MessageBoxMyError(s); - return true; -} - -void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal, const wchar_t *type) -{ - CDisableTimerProcessing disableTimerProcessing(*this); - UString name = GetItemRelPath2(index); - - if (IsVirus_Message(name)) - return; - - if (!_parentFolders.IsEmpty()) - { - OpenItemInArchive(index, tryInternal, tryExternal, false, false, type); - return; - } - - CDisableNotify disableNotify(*this); - UString prefix = GetFsPath(); - UString fullPath = prefix + name; - - if (tryInternal) - if (!tryExternal || !DoItemAlwaysStart(name)) - { - HRESULT res = OpenItemAsArchive(index, type); - disableNotify.Restore(); // we must restore to allow text notification update - InvalidateList(); - if (res == S_OK || res == E_ABORT) - return; - if (res != S_FALSE) - { - MessageBoxError(res); - return; - } - } - - if (tryExternal) - { - // SetCurrentDirectory opens HANDLE to folder!!! - // NDirectory::MySetCurrentDirectory(prefix); - StartApplicationDontWait(prefix, fullPath, (HWND)*this); - } -} - -class CThreadCopyFrom: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - UString FullPath; - UInt32 ItemIndex; - - CMyComPtr FolderOperations; - CMyComPtr UpdateCallback; - CUpdateCallback100Imp *UpdateCallbackSpec; -}; - -HRESULT CThreadCopyFrom::ProcessVirt() -{ - return FolderOperations->CopyFromFile(ItemIndex, FullPath, UpdateCallback); -} - -HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, - bool usePassword, const UString &password) -{ - if (!_folderOperations) - { - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return E_FAIL; - } - - CThreadCopyFrom t; - t.UpdateCallbackSpec = new CUpdateCallback100Imp; - t.UpdateCallback = t.UpdateCallbackSpec; - t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog; - t.ItemIndex = index; - t.FullPath = fullFilePath; - t.FolderOperations = _folderOperations; - - t.UpdateCallbackSpec->Init(); - t.UpdateCallbackSpec->PasswordIsDefined = usePassword; - t.UpdateCallbackSpec->Password = password; - - - RINOK(t.Create(GetItemName(index), (HWND)*this)); - return t.Result; -} - -LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) -{ - CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam; - if (tpi.FullPathFolderPrefix != _currentFolderPrefix) - return 0; - UInt32 fileIndex = tpi.FileIndex; - UInt32 numItems; - _folder->GetNumberOfItems(&numItems); - - // This code is not 100% OK for cases when there are several files with - // tpi.RelPath name and there are changes in archive before update. - // So tpi.FileIndex can point to another file. - - if (fileIndex >= numItems || GetItemRelPath(fileIndex) != tpi.RelPath) - { - UInt32 i; - for (i = 0; i < numItems; i++) - if (GetItemRelPath(i) == tpi.RelPath) - break; - if (i == numItems) - return 0; - fileIndex = i; - } - - CSelectedState state; - SaveSelectedState(state); - - CDisableNotify disableNotify(*this); // do we need it?? - - HRESULT result = OnOpenItemChanged(fileIndex, fs2us(tpi.FilePath), tpi.UsePassword, tpi.Password); - RefreshListCtrl(state); - if (result != S_OK) - return 0; - return 1; -} - -class CExitEventLauncher -{ -public: - NWindows::NSynchronization::CManualResetEvent _exitEvent; - CExitEventLauncher() - { - if (_exitEvent.Create(false) != S_OK) - throw 9387173; - }; - ~CExitEventLauncher() { _exitEvent.Set(); } -} g_ExitEventLauncher; - -#ifdef _WIN32 -static THREAD_FUNC_DECL MyThreadFunction(void *param) -{ - CMyAutoPtr tmpProcessInfoPtr((CTmpProcessInfo *)param); - CTmpProcessInfo *tpi = tmpProcessInfoPtr.get(); - CChildProcesses &processes = tpi->Processes; - - for (;;) - { - CRecordVector handles; - CRecordVector indices; - - FOR_VECTOR (i, processes.Handles) - { - if (processes.NeedWait[i]) - { - handles.Add(processes.Handles[i]); - indices.Add(i); - } - } - - if (handles.IsEmpty()) - break; - - handles.Add(g_ExitEventLauncher._exitEvent); - - DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE); - - if (waitResult >= (DWORD)handles.Size() - 1) - { - processes.CloseAll(); - return waitResult >= (DWORD)handles.Size() ? 1 : 0; - } - processes.Update(); - processes.DisableWait(indices[waitResult]); - } - - NFind::CFileInfo newFileInfo; - if (newFileInfo.Find(tpi->FilePath)) - { - if (tpi->WasChanged(newFileInfo)) - { - UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath); - if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) - { - if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1) - { - ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE, - fs2us(tpi->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP); - return 0; - } - } - } - } - tpi->DeleteDirAndFile(); - return 0; -} -#endif - -#if defined(_WIN32) && !defined(UNDER_CE) -static const FChar *k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); -#endif - - -#ifndef UNDER_CE - -static void ReadZoneFile(CFSTR fileName, CByteBuffer &buf) -{ - buf.Free(); - NIO::CInFile file; - if (!file.Open(fileName)) - return; - UInt64 fileSize; - if (!file.GetLength(fileSize)) - return; - if (fileSize == 0 || fileSize >= ((UInt32)1 << 20)) - return; - buf.Alloc((size_t)fileSize); - UInt32 processed; - if (file.Read(buf, (UInt32)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; - UInt32 processed; - if (!file.Write(buf, (UInt32)buf.Size(), processed)) - return false; - return processed == buf.Size(); -} - -#endif - -/* -class CBufSeqOutStream_WithFile: - public ISequentialOutStream, - public CMyUnknownImp -{ - Byte *_buffer; - size_t _size; - size_t _pos; - - - size_t _fileWritePos; - bool fileMode; -public: - - bool IsStreamInMem() const { return !fileMode; } - size_t GetMemStreamWrittenSize() const { return _pos; } - - // ISequentialOutStream *FileStream; - FString FilePath; - COutFileStream *outFileStreamSpec; - CMyComPtr outFileStream; - - CBufSeqOutStream_WithFile(): outFileStreamSpec(NULL) {} - - void Init(Byte *buffer, size_t size) - { - fileMode = false; - _buffer = buffer; - _pos = 0; - _size = size; - _fileWritePos = 0; - } - - HRESULT FlushToFile(); - size_t GetPos() const { return _pos; } - - MY_UNKNOWN_IMP - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); -}; - -static const UInt32 kBlockSize = ((UInt32)1 << 31); - -STDMETHODIMP CBufSeqOutStream_WithFile::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if (processedSize) - *processedSize = 0; - if (!fileMode) - { - if (_size - _pos >= size) - { - if (size != 0) - { - memcpy(_buffer + _pos, data, size); - _pos += size; - } - if (processedSize) - *processedSize = (UInt32)size; - return S_OK; - } - - fileMode = true; - } - RINOK(FlushToFile()); - return outFileStream->Write(data, size, processedSize); -} - -HRESULT CBufSeqOutStream_WithFile::FlushToFile() -{ - if (!outFileStream) - { - outFileStreamSpec = new COutFileStream; - outFileStream = outFileStreamSpec; - if (!outFileStreamSpec->Create(FilePath, false)) - { - outFileStream.Release(); - return E_FAIL; - // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath)); - } - } - while (_fileWritePos != _pos) - { - size_t cur = _pos - _fileWritePos; - UInt32 curSize = (cur < kBlockSize) ? (UInt32)cur : kBlockSize; - UInt32 processedSizeLoc = 0; - HRESULT res = outFileStream->Write(_buffer + _fileWritePos, curSize, &processedSizeLoc); - _fileWritePos += processedSizeLoc; - RINOK(res); - if (processedSizeLoc == 0) - return E_FAIL; - } - return S_OK; -} -*/ - -/* -static HRESULT GetTime(IFolderFolder *folder, UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) -{ - filetimeIsDefined = false; - NCOM::CPropVariant prop; - RINOK(folder->GetProperty(index, propID, &prop)); - if (prop.vt == VT_FILETIME) - { - filetime = prop.filetime; - filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0); - } - else if (prop.vt != VT_EMPTY) - return E_FAIL; - return S_OK; -} -*/ - -void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode, bool useEditor, const wchar_t *type) -{ - const UString name = GetItemName(index); - const UString relPath = GetItemRelPath(index); - - if (IsVirus_Message(name)) - return; - - if (!_folderOperations) - { - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - - bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name)); - - UString fullVirtPath = _currentFolderPrefix + relPath; - - CTempDir tempDirectory; - if (!tempDirectory.Create(kTempDirPrefix)) - { - MessageBoxLastError(); - return; - } - FString tempDir = tempDirectory.GetPath(); - FString tempDirNorm = tempDir; - NName::NormalizeDirPathPrefix(tempDirNorm); - const FString tempFilePath = tempDirNorm + us2fs(Get_Correct_FsFile_Name(name)); - - CTempFileInfo tempFileInfo; - tempFileInfo.FileIndex = index; - tempFileInfo.RelPath = relPath; - tempFileInfo.FolderPath = tempDir; - tempFileInfo.FilePath = tempFilePath; - tempFileInfo.NeedDelete = true; - - if (tryAsArchive) - { - CMyComPtr getStream; - _folder.QueryInterface(IID_IInArchiveGetStream, &getStream); - if (getStream) - { - CMyComPtr subSeqStream; - getStream->GetStream(index, &subSeqStream); - if (subSeqStream) - { - CMyComPtr subStream; - subSeqStream.QueryInterface(IID_IInStream, &subStream); - if (subStream) - { - bool encrypted; - HRESULT res = OpenItemAsArchive(subStream, tempFileInfo, fullVirtPath, type ? type : L"", encrypted); - if (res == S_OK) - { - tempDirectory.DisableDeleting(); - RefreshListCtrl(); - return; - } - if (res == E_ABORT) - return; - if (res != S_FALSE) - { - // probably we must show some message here - // return; - } - } - } - } - } - - - CRecordVector indices; - indices.Add(index); - - UStringVector messages; - - bool usePassword = false; - UString password; - if (_parentFolders.Size() > 0) - { - const CFolderLink &fl = _parentFolders.Back(); - usePassword = fl.UsePassword; - password = fl.Password; - } - - #if defined(_WIN32) && !defined(UNDER_CE) - CByteBuffer zoneBuf; - #ifndef _UNICODE - if (g_IsNT) - #endif - if (_parentFolders.Size() > 0) - { - const CFolderLink &fl = _parentFolders.Front(); - if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) - ReadZoneFile(fl.FilePath + k_ZoneId_StreamName, zoneBuf); - } - #endif - - - CVirtFileSystem *virtFileSystemSpec = NULL; - CMyComPtr virtFileSystem; - - bool isAltStream = IsItem_AltStream(index); - - CCopyToOptions options; - options.includeAltStreams = true; - options.replaceAltStreamChars = isAltStream; - - if (tryAsArchive) - { - NCOM::CPropVariant prop; - _folder->GetProperty(index, kpidSize, &prop); - UInt64 fileLimit = g_RAM_Size / 4; - UInt64 fileSize = 0; - if (!ConvertPropVariantToUInt64(prop, fileSize)) - fileSize = fileLimit; - if (fileSize <= fileLimit && fileSize > 0) - { - options.streamMode = true; - virtFileSystemSpec = new CVirtFileSystem; - virtFileSystem = virtFileSystemSpec; - // we allow additional total size for small alt streams; - virtFileSystemSpec->MaxTotalAllocSize = fileSize + (1 << 10); - - virtFileSystemSpec->DirPrefix = tempDirNorm; - virtFileSystemSpec->Init(); - options.VirtFileSystem = virtFileSystem; - options.VirtFileSystemSpec = virtFileSystemSpec; - } - } - - options.folder = fs2us(tempDirNorm); - options.showErrorMessages = true; - HRESULT result = CopyTo(options, indices, &messages, usePassword, password); - - if (_parentFolders.Size() > 0) - { - CFolderLink &fl = _parentFolders.Back(); - fl.UsePassword = usePassword; - fl.Password = password; - } - - if (!messages.IsEmpty()) - return; - if (result != S_OK) - { - if (result != E_ABORT) - MessageBoxError(result); - return; - } - - if (options.VirtFileSystem) - { - if (virtFileSystemSpec->IsStreamInMem()) - { - const CVirtFile &file = virtFileSystemSpec->Files[0]; - - size_t streamSize = (size_t)file.Size; - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - bufInStreamSpec->Init(file.Data, streamSize, virtFileSystem); - bool encrypted; - if (OpenItemAsArchive(bufInStream, tempFileInfo, fullVirtPath, type ? type : L"", encrypted) == S_OK) - { - tempDirectory.DisableDeleting(); - RefreshListCtrl(); - return; - } - if (virtFileSystemSpec->FlushToDisk(true) != S_OK) - return; - } - } - - - #if defined(_WIN32) && !defined(UNDER_CE) - if (zoneBuf.Size() != 0) - { - if (NFind::DoesFileExist(tempFilePath)) - { - WriteZoneFile(tempFilePath + k_ZoneId_StreamName, zoneBuf); - } - } - #endif - - - if (tryAsArchive) - { - bool encrypted; - if (OpenItemAsArchive(NULL, tempFileInfo, fullVirtPath, type ? type : L"", encrypted) == S_OK) - { - tempDirectory.DisableDeleting(); - RefreshListCtrl(); - return; - } - } - - CMyAutoPtr tmpProcessInfoPtr(new CTmpProcessInfo()); - CTmpProcessInfo *tpi = tmpProcessInfoPtr.get(); - tpi->FolderPath = tempDir; - tpi->FilePath = tempFilePath; - tpi->NeedDelete = true; - tpi->UsePassword = usePassword; - tpi->Password = password; - - if (!tpi->FileInfo.Find(tempFilePath)) - return; - - CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi); - - if (!tryExternal) - return; - - // CProcess process; - // HRESULT res; - if (editMode) - /* res = */ StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this /* , process */ ); - else - /* res = */ StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this /* , process */ ); - -#ifdef _WIN32 - if ((HANDLE)process == 0) - return; - - tpi->Window = (HWND)(*this); - tpi->FullPathFolderPrefix = _currentFolderPrefix; - tpi->FileIndex = index; - tpi->RelPath = relPath; - tpi->Processes.AddProcess(process.Detach()); - - NWindows::CThread thread; - if (thread.Create(MyThreadFunction, tpi) != S_OK) - throw 271824; -#endif - tempDirectory.DisableDeleting(); - tmpProcessInfoPtr.release(); - tmpProcessInfoRelease._needDelete = false; -} - -/* -static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24; - -static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime) -{ - return (currentFileTime - folderFileTime > kTimeLimit && - folderFileTime - currentFileTime > kTimeLimit); -} - -void DeleteOldTempFiles() -{ - UString tempPath; - if(!MyGetTempPath(tempPath)) - throw 1; - - UINT64 currentFileTime; - NTime::GetCurUtcFileTime(currentFileTime); - UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp"; - searchWildCard += WCHAR(NName::kAnyStringWildcard); - NFind::CEnumeratorW enumerator(searchWildCard); - NFind::CFileInfo fileInfo; - while(enumerator.Next(fileInfo)) - { - if (!fileInfo.IsDir()) - continue; - const UINT64 &cTime = *(const UINT64 *)(&fileInfo.CTime); - if(CheckDeleteItem(cTime, currentFileTime)) - RemoveDirectoryWithSubItems(tempPath + fileInfo.Name); - } -} -*/ +// PanelItemOpen.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#include + +#include "../../../Common/IntToString.h" + +#include "../../../Common/AutoPtr.h" + +#include "../../../Windows/ProcessUtils.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamObjects.h" + +#include "../Common/ExtractingFilePath.h" + +#include "App.h" + +#include "FileFolderPluginOpen.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "PropertyNameRes.h" +#include "RegistryUtils.h" +#include "UpdateCallback100.h" + +#include "../GUI/ExtractRes.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NSynchronization; +using namespace NFile; +using namespace NDir; + +extern bool g_RAM_Size_Defined; +extern size_t g_RAM_Size; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#define kTempDirPrefix FTEXT("7zO") + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO + #define DEBUG_PRINT(s) OutputDebugStringA(s); + #define DEBUG_PRINT_W(s) OutputDebugStringW(s); + #define DEBUG_PRINT_NUM(s, num) { char ttt[32]; ConvertUInt32ToString(num, ttt); OutputDebugStringA(s); OutputDebugStringA(ttt); } +#else + #define DEBUG_PRINT(s) + #define DEBUG_PRINT_W(s) + #define DEBUG_PRINT_NUM(s, num) +#endif + + + +#ifndef UNDER_CE + +class CProcessSnapshot +{ + HANDLE _handle; +public: + CProcessSnapshot(): _handle(INVALID_HANDLE_VALUE) {} + ~CProcessSnapshot() { Close(); } + + bool Close() + { + if (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; + } + + bool Create() + { + _handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + return (_handle != INVALID_HANDLE_VALUE); + } + + bool GetFirstProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32First(_handle, pe)); } + bool GetNextProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32Next(_handle, pe)); } +}; + +#endif + + +/* +struct COpenExtProg +{ + const char *Ext; + const char *Prog; +}; + +static const COpenExtProg g_Progs[] = +{ + { "jpeg jpg png bmp gif", "Microsoft.Photos.exe" }, + { "html htm pdf", "MicrosoftEdge.exe" }, + // , { "rrr", "notepad.exe" } +}; + +static bool FindExtProg(const char *exts, const char *ext) +{ + unsigned len = (unsigned)strlen(ext); + for (;;) + { + const char *p = exts; + for (;; p++) + { + const char c = *p; + if (c == 0 || c == ' ') + break; + } + if (len == (unsigned)(p - exts) && IsString1PrefixedByString2(exts, ext)) + return true; + if (*p == 0) + return false; + exts = p + 1; + } +} + +class CPossibleProgs +{ +public: + AStringVector ProgNames; + + void SetFromExtension(const char *ext) // ext must be low case + { + ProgNames.Clear(); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Progs); i++) + if (FindExtProg(g_Progs[i].Ext, ext)) + { + ProgNames.Add(g_Progs[i].Prog); + } + } + + bool IsFromList(const UString &progName) const + { + FOR_VECTOR (i, ProgNames) + if (progName.IsEqualTo_Ascii_NoCase(ProgNames[i])) + return true; + return false; + } +}; +*/ + + +#ifndef UNDER_CE + +EXTERN_C_BEGIN + +/* +GetProcessImageFileName + returns the path in device form, rather than drive letters: + \Device\HarddiskVolume1\WINDOWS\SysWOW64\notepad.exe + +GetModuleFileNameEx works only after Sleep(something). Why? + returns the path + C:\WINDOWS\system32\NOTEPAD.EXE +*/ + +/* Kernel32.dll: Win7, Win2008R2; + Psapi.dll: (if PSAPI_VERSION=1) on Win7 and Win2008R2; + Psapi.dll: XP, Win2003, Vista, 2008; +*/ + +typedef DWORD (WINAPI *Func_GetProcessImageFileNameW)( + HANDLE hProcess, LPWSTR lpFilename, DWORD nSize); + +typedef DWORD (WINAPI *Func_GetModuleFileNameExW)( + HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); + +typedef DWORD (WINAPI *Func_GetProcessId)(HANDLE process); + +EXTERN_C_END + + +static HMODULE g_Psapi_dll_module; + +/* +static void My_GetProcessFileName_2(HANDLE hProcess, UString &path) +{ + path.Empty(); + const unsigned maxPath = 1024; + WCHAR temp[maxPath + 1]; + + const char *func_name = "GetModuleFileNameExW"; + Func_GetModuleFileNameExW my_func = (Func_GetModuleFileNameExW) + ::GetProcAddress(::GetModuleHandleA("kernel32.dll"), func_name); + if (!my_func) + { + if (!g_Psapi_dll_module) + g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll"); + if (g_Psapi_dll_module) + my_func = (Func_GetModuleFileNameExW)::GetProcAddress(g_Psapi_dll_module, func_name); + } + if (my_func) + { + // DWORD num = GetModuleFileNameEx(hProcess, NULL, temp, maxPath); + DWORD num = my_func(hProcess, NULL, temp, maxPath); + if (num != 0) + path = temp; + } + // FreeLibrary(lib); +} +*/ + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +static void My_GetProcessFileName(HANDLE hProcess, UString &path) +{ + path.Empty(); + const unsigned maxPath = 1024; + WCHAR temp[maxPath + 1]; + + const char *func_name = + "GetProcessImageFileNameW"; + Func_GetProcessImageFileNameW my_func = Z7_GET_PROC_ADDRESS( + Func_GetProcessImageFileNameW, ::GetModuleHandleA("kernel32.dll"), func_name); + + if (!my_func) + { + if (!g_Psapi_dll_module) + g_Psapi_dll_module = LoadLibraryW(L"Psapi.dll"); + if (g_Psapi_dll_module) + my_func = Z7_GET_PROC_ADDRESS( + Func_GetProcessImageFileNameW, g_Psapi_dll_module, func_name); + } + + if (my_func) + { + const DWORD num = + // GetProcessImageFileNameW(hProcess, temp, maxPath); + my_func(hProcess, temp, maxPath); + if (num != 0) + path = temp; + } + // FreeLibrary(lib); +} + +struct CSnapshotProcess +{ + DWORD Id; + DWORD ParentId; + UString Name; +}; + +static void GetSnapshot(CObjectVector &items) +{ + items.Clear(); + + CProcessSnapshot snapshot; + if (!snapshot.Create()) + return; + + DEBUG_PRINT("snapshot.Create() OK"); + PROCESSENTRY32 pe; + CSnapshotProcess item; + memset(&pe, 0, sizeof(pe)); + pe.dwSize = sizeof(pe); + BOOL res = snapshot.GetFirstProcess(&pe); + while (res) + { + item.Id = pe.th32ProcessID; + item.ParentId = pe.th32ParentProcessID; + item.Name = GetUnicodeString(pe.szExeFile); + items.Add(item); + res = snapshot.GetNextProcess(&pe); + } +} + +#endif + + +class CChildProcesses +{ + #ifndef UNDER_CE + CRecordVector _ids; + #endif + +public: + // bool ProgsWereUsed; + CRecordVector Handles; + CRecordVector NeedWait; + // UStringVector Names; + + #ifndef UNDER_CE + UString Path; + #endif + + // CChildProcesses(): ProgsWereUsed(false) {} + ~CChildProcesses() { CloseAll(); } + void DisableWait(unsigned index) { NeedWait[index] = false; } + + void CloseAll() + { + FOR_VECTOR (i, Handles) + { + HANDLE h = Handles[i]; + if (h != NULL) + CloseHandle(h); + } + + Handles.Clear(); + NeedWait.Clear(); + // Names.Clear(); + + #ifndef UNDER_CE + // Path.Empty(); + _ids.Clear(); + #endif + } + + void SetMainProcess(HANDLE h) + { + #ifndef UNDER_CE + const + Func_GetProcessId func = Z7_GET_PROC_ADDRESS( + Func_GetProcessId, ::GetModuleHandleA("kernel32.dll"), + "GetProcessId"); + if (func) + { + const DWORD id = func(h); + if (id != 0) + _ids.AddToUniqueSorted(id); + } + + My_GetProcessFileName(h, Path); + DEBUG_PRINT_W(Path); + + #endif + + Handles.Add(h); + NeedWait.Add(true); + } + + #ifndef UNDER_CE + + void Update(bool needFindProcessByPath /* , const CPossibleProgs &progs */) + { + /* + if (_ids.IsEmpty()) + return; + */ + + CObjectVector sps; + GetSnapshot(sps); + + const int separ = Path.ReverseFind_PathSepar(); + const UString mainName = Path.Ptr((unsigned)(separ + 1)); + if (mainName.IsEmpty()) + needFindProcessByPath = false; + + const DWORD currentProcessId = GetCurrentProcessId(); + + for (;;) + { + bool wasAdded = false; + + FOR_VECTOR (i, sps) + { + const CSnapshotProcess &sp = sps[i]; + const DWORD id = sp.Id; + + if (id == currentProcessId) + continue; + if (_ids.FindInSorted(id) >= 0) + continue; + + bool isSameName = false; + const UString &name = sp.Name; + + if (needFindProcessByPath) + isSameName = mainName.IsEqualTo_NoCase(name); + + bool needAdd = false; + // bool isFromProgs = false; + + if (isSameName || _ids.FindInSorted(sp.ParentId) >= 0) + needAdd = true; + /* + else if (progs.IsFromList(name)) + { + needAdd = true; + isFromProgs = true; + } + */ + + if (needAdd) + { + DEBUG_PRINT("----- OpenProcess -----"); + DEBUG_PRINT_W(name); + HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id); + if (hProcess) + { + DEBUG_PRINT("----- OpenProcess OK -----"); + // if (!isFromProgs) + _ids.AddToUniqueSorted(id); + Handles.Add(hProcess); + NeedWait.Add(true); + // Names.Add(name); + wasAdded = true; + // ProgsWereUsed = isFromProgs; + } + } + } + + if (!wasAdded) + break; + } + } + + #endif +}; + + +struct CTmpProcessInfo: public CTempFileInfo +{ + CChildProcesses Processes; + HWND Window; + UString FullPathFolderPrefix; + bool UsePassword; + UString Password; + + bool ReadOnly; + + CTmpProcessInfo(): UsePassword(false), ReadOnly(false) {} +}; + + +class CTmpProcessInfoRelease +{ + CTmpProcessInfo *_tmpProcessInfo; +public: + bool _needDelete; + CTmpProcessInfoRelease(CTmpProcessInfo &tpi): + _tmpProcessInfo(&tpi), _needDelete(true) {} + ~CTmpProcessInfoRelease() + { + if (_needDelete) + _tmpProcessInfo->DeleteDirAndFile(); + } +}; + +void GetFolderError(CMyComPtr &folder, UString &s); + + +HRESULT CPanel::OpenAsArc(IInStream *inStream, + const CTempFileInfo &tempFileInfo, + const UString &virtualFilePath, + const UString &arcFormat, + COpenResult &openRes) +{ + openRes.Encrypted = false; + CFolderLink folderLink; + (CTempFileInfo &)folderLink = tempFileInfo; + + if (inStream) + folderLink.IsVirtual = true; + else + { + if (!folderLink.FileInfo.Find(folderLink.FilePath)) + return GetLastError_noZero_HRESULT(); + if (folderLink.FileInfo.IsDir()) + return S_FALSE; + folderLink.IsVirtual = false; + } + + folderLink.VirtualPath = virtualFilePath; + + CFfpOpen ffp; + const HRESULT res = ffp.OpenFileFolderPlugin(inStream, + folderLink.FilePath.IsEmpty() ? us2fs(virtualFilePath) : folderLink.FilePath, + arcFormat, GetParent()); + + openRes.Encrypted = ffp.Encrypted; + openRes.ErrorMessage = ffp.ErrorMessage; + + RINOK(res) + + folderLink.Password = ffp.Password; + folderLink.UsePassword = ffp.Encrypted; + + if (_folder) + folderLink.ParentFolderPath = GetFolderPath(_folder); + else + folderLink.ParentFolderPath = _currentFolderPrefix; + + if (!_parentFolders.IsEmpty()) + folderLink.ParentFolder = _folder; + + _parentFolders.Add(folderLink); + _parentFolders.Back().Library.Attach(_library.Detach()); + + ReleaseFolder(); + _library.Free(); + SetNewFolder(ffp.Folder); + _library.Attach(ffp.Library.Detach()); + + _flatMode = _flatModeForArc; + + _thereAreDeletedItems = false; + + if (!openRes.ErrorMessage.IsEmpty()) + MessageBox_Error(openRes.ErrorMessage); + /* + UString s; + GetFolderError(_folder, s); + if (!s.IsEmpty()) + MessageBox_Error(s); + */ + // we don't show error here by some reasons: + // after MessageBox_Warning it throws exception in nested archives in Debug Mode. why ?. + // MessageBox_Warning(L"test error"); + + return S_OK; +} + + +HRESULT CPanel::OpenAsArc_Msg(IInStream *inStream, + const CTempFileInfo &tempFileInfo, + const UString &virtualFilePath, + const UString &arcFormat + // , bool &encrypted + // , bool showErrorMessage + ) +{ + COpenResult opRes; + + HRESULT res = OpenAsArc(inStream, tempFileInfo, virtualFilePath, arcFormat, opRes); + + if (res == S_OK) + return res; + if (res == E_ABORT) + return res; + + // if (showErrorMessage) + if (opRes.Encrypted || res != S_FALSE) // 17.01 : we show message also for (res != S_FALSE) + { + UString message; + if (res == S_FALSE) + { + message = MyFormatNew( + opRes.Encrypted ? + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : + IDS_CANT_OPEN_ARCHIVE, + virtualFilePath); + } + else + message = HResultToMessage(res); + MessageBox_Error(message); + } + + return res; +} + + +HRESULT CPanel::OpenAsArc_Name(const UString &relPath, const UString &arcFormat + // , bool &encrypted, + // , bool showErrorMessage + ) +{ + CTempFileInfo tfi; + tfi.RelPath = relPath; + tfi.FolderPath = us2fs(GetFsPath()); + const UString fullPath = GetFsPath() + relPath; + tfi.FilePath = us2fs(fullPath); + return OpenAsArc_Msg(NULL, tfi, fullPath, arcFormat /* , encrypted, showErrorMessage */); +} + + +HRESULT CPanel::OpenAsArc_Index(unsigned index, const wchar_t *type + // , bool showErrorMessage + ) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + CDisableNotify disableNotify(*this); + + HRESULT res = OpenAsArc_Name(GetItemRelPath2(index), type ? type : L"" /* , encrypted, showErrorMessage */); + if (res != S_OK) + { + RefreshTitle(true); // in case of error we must refresh changed title of 7zFM + return res; + } + RefreshListCtrl(); + return S_OK; +} + + +HRESULT CPanel::OpenParentArchiveFolder() +{ + CDisableTimerProcessing disableTimerProcessing(*this); + CDisableNotify disableNotify(*this); + if (_parentFolders.Size() < 2) + return S_OK; + const CFolderLink &folderLinkPrev = _parentFolders[_parentFolders.Size() - 2]; + const CFolderLink &folderLink = _parentFolders.Back(); + NFind::CFileInfo newFileInfo; + if (newFileInfo.Find(folderLink.FilePath)) + { + if (folderLink.WasChanged_from_FolderLink(newFileInfo)) + { + const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath); + if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES) + { + if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath), + folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK) + { + ::MessageBoxW((HWND)*this, MyFormatNew(IDS_CANNOT_UPDATE_FILE, + fs2us(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP); + return S_OK; + } + } + } + } + folderLink.DeleteDirAndFile(); + return S_OK; +} + + +static const char * const kExeExtensions = + " exe bat ps1 com lnk" + " "; + +static const char * const kStartExtensions = + #ifdef UNDER_CE + " cab" + #endif + " exe bat ps1 com lnk" + " chm" + " msi doc dot xls ppt pps wps wpt wks xlr wdb vsd pub" + + " docx docm dotx dotm xlsx xlsm xltx xltm xlsb xps" + " xlam pptx pptm potx potm ppam ppsx ppsm vsdx xsn" + " mpp" + " msg" + " dwf" + + " flv swf" + + " epub" + " odt ods" + " wb3" + " pdf" + " ps" + " txt" + " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" + " h hpp hxx c cpp cxx m mm go swift" + " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs" + " asm" + " mak clw csproj vcproj sln dsp dsw" + " "; + +// bool FindExt(const char *p, const UString &name, AString &s); +bool FindExt(const char *p, const UString &name, CStringFinder &finder); + +static bool DoItemAlwaysStart(const UString &name) +{ + CStringFinder finder; + return FindExt(kStartExtensions, name, finder); +} + +UString GetQuotedString(const UString &s); + + +void SplitCmdLineSmart(const UString &cmd, UString &prg, UString ¶ms); +void SplitCmdLineSmart(const UString &cmd, UString &prg, UString ¶ms) +{ + params.Empty(); + prg = cmd; + prg.Trim(); + if (prg.Len() >= 2 && prg[0] == L'"') + { + int pos = prg.Find(L'"', 1); + if (pos >= 0) + { + if ((unsigned)(pos + 1) == prg.Len() || prg[pos + 1] == ' ') + { + params = prg.Ptr((unsigned)(pos + 1)); + params.Trim(); + prg.DeleteFrom((unsigned)pos); + prg.DeleteFrontal(1); + } + } + } +} + + +static WRes StartAppWithParams(const UString &cmd, const UStringVector ¶mVector, CProcess &process) +{ + UString param; + UString prg; + + SplitCmdLineSmart(cmd, prg, param); + + param.Trim(); + + // int pos = params.Find(L"%1"); + + FOR_VECTOR (i, paramVector) + { + if (!param.IsEmpty() && param.Back() != ' ') + param.Add_Space(); + param += GetQuotedString(paramVector[i]); + } + + return process.Create(prg, param, NULL); +} + + +static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND window, CProcess &process) +{ + UString command; + ReadRegEditor(useEditor, command); + if (command.IsEmpty()) + { + #ifdef UNDER_CE + command = "\\Windows\\"; + #else + FString winDir; + if (!GetWindowsDir(winDir)) + return 0; + NName::NormalizeDirPathPrefix(winDir); + command = fs2us(winDir); + #endif + command += "notepad.exe"; + } + + UStringVector params; + params.Add(path); + + const WRes res = StartAppWithParams(command, params, process); + if (res != 0) + ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP); + return HRESULT_FROM_WIN32(res); +} + + +void CApp::DiffFiles() +{ + const CPanel &panel = GetFocusedPanel(); + + if (!panel.Is_IO_FS_Folder()) + { + panel.MessageBox_Error_UnsupportOperation(); + return; + } + + CRecordVector indices; + panel.Get_ItemIndices_Selected(indices); + + UString path1, path2; + if (indices.Size() == 2) + { + path1 = panel.GetItemFullPath(indices[0]); + path2 = panel.GetItemFullPath(indices[1]); + } + else if (indices.Size() == 1 && NumPanels >= 2) + { + const CPanel &destPanel = Panels[1 - LastFocusedPanel]; + + if (!destPanel.Is_IO_FS_Folder()) + { + panel.MessageBox_Error_UnsupportOperation(); + return; + } + + path1 = panel.GetItemFullPath(indices[0]); + CRecordVector indices2; + destPanel.Get_ItemIndices_Selected(indices2); + if (indices2.Size() == 1) + path2 = destPanel.GetItemFullPath(indices2[0]); + else + { + UString relPath = panel.GetItemRelPath2(indices[0]); + if (panel._flatMode && !destPanel._flatMode) + relPath = panel.GetItemName(indices[0]); + path2 = destPanel._currentFolderPrefix + relPath; + } + } + else + return; + + DiffFiles(path1, path2); +} + +void CApp::DiffFiles(const UString &path1, const UString &path2) +{ + UString command; + ReadRegDiff(command); + if (command.IsEmpty()) + return; + + UStringVector params; + params.Add(path1); + params.Add(path2); + + WRes res; + { + CProcess process; + res = StartAppWithParams(command, params, process); + } + if (res == 0) + return; + ::MessageBoxW(_window, LangString(IDS_CANNOT_START_EDITOR), L"7-Zip", MB_OK | MB_ICONSTOP); +} + + +HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process); +void StartApplicationDontWait(const UString &dir, const UString &path, HWND window); + +void CPanel::EditItem(unsigned index, bool useEditor) +{ + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, false, true, true, useEditor); + return; + } + CProcess process; + StartEditApplication(GetItemFullPath(index), useEditor, (HWND)*this, process); +} + + +void CPanel::OpenFolderExternal(unsigned index) +{ + UString prefix = GetFsPath(); + UString path = prefix; + + if (index == kParentIndex) + { + if (prefix.IsEmpty()) + return; + const wchar_t c = prefix.Back(); + if (!IS_PATH_SEPAR(c) && c != ':') + return; + prefix.DeleteBack(); + int pos = prefix.ReverseFind_PathSepar(); + if (pos < 0) + return; + prefix.DeleteFrom((unsigned)(pos + 1)); + path = prefix; + } + else + { + path += GetItemRelPath(index); + path.Add_PathSepar(); + } + + StartApplicationDontWait(prefix, path, (HWND)*this); +} + + +bool CPanel::IsVirus_Message(const UString &name) +{ + UString name2; + + const wchar_t cRLO = (wchar_t)0x202E; + bool isVirus = false; + bool isSpaceError = false; + name2 = name; + + if (name2.Find(cRLO) >= 0) + { + const UString badString(cRLO); + name2.Replace(badString, L"[RLO]"); + isVirus = true; + } + { + const wchar_t * const kVirusSpaces = L" "; + // const unsigned kNumSpaces = strlen(kVirusSpaces); + for (;;) + { + int pos = name2.Find(kVirusSpaces); + if (pos < 0) + break; + isVirus = true; + isSpaceError = true; + name2.Replace(kVirusSpaces, L" "); + } + } + + #ifdef _WIN32 + { + unsigned i; + for (i = name2.Len(); i != 0;) + { + wchar_t c = name2[i - 1]; + if (c != '.' && c != ' ') + break; + i--; + name2.ReplaceOneCharAtPos(i, '_'); + } + if (i != name2.Len()) + { + CStringFinder finder; + UString name3 = name2; + name3.DeleteFrom(i); + if (FindExt(kExeExtensions, name3, finder)) + isVirus = true; + } + } + #endif + + if (!isVirus) + return false; + + UString s = LangString(IDS_VIRUS); + + if (!isSpaceError) + { + const int pos1 = s.Find(L'('); + if (pos1 >= 0) + { + const int pos2 = s.Find(L')', (unsigned)pos1 + 1); + if (pos2 >= 0) + { + s.Delete((unsigned)pos1, (unsigned)pos2 + 1 - (unsigned)pos1); + if (pos1 > 0 && s[pos1 - 1] == ' ' && s[pos1] == '.') + s.Delete(pos1 - 1); + } + } + } + + UString name3 = name; + name3.Replace(L'\n', L'_'); + name2.Replace(L'\n', L'_'); + + s.Add_LF(); s += name2; + s.Add_LF(); s += name3; + + MessageBox_Error(s); + return true; +} + + +void CPanel::OpenItem(unsigned index, bool tryInternal, bool tryExternal, const wchar_t *type) +{ + CDisableTimerProcessing disableTimerProcessing(*this); + const UString name = GetItemRelPath2(index); + + if (tryExternal) + if (IsVirus_Message(name)) + return; + + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, tryInternal, tryExternal, false, false, type); + return; + } + + CDisableNotify disableNotify(*this); + UString prefix = GetFsPath(); + UString fullPath = prefix + name; + + if (tryInternal) + if (!tryExternal || !DoItemAlwaysStart(name)) + { + HRESULT res = OpenAsArc_Index(index, type + // , true + ); + disableNotify.Restore(); // we must restore to allow text notification update + InvalidateList(); + if (res == S_OK || res == E_ABORT) + return; + if (res != S_FALSE) + { + MessageBox_Error_HRESULT(res); + return; + } + } + + if (tryExternal) + { + // SetCurrentDirectory opens HANDLE to folder!!! + // NDirectory::MySetCurrentDirectory(prefix); + StartApplicationDontWait(prefix, fullPath, (HWND)*this); + } +} + +class CThreadCopyFrom: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + UString FullPath; + UInt32 ItemIndex; + + CMyComPtr FolderOperations; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; +}; + +HRESULT CThreadCopyFrom::ProcessVirt() +{ + return FolderOperations->CopyFromFile(ItemIndex, FullPath, UpdateCallback); +} + +HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, + bool usePassword, const UString &password) +{ + if (!_folderOperations) + { + MessageBox_Error_UnsupportOperation(); + return E_FAIL; + } + + CThreadCopyFrom t; + t.UpdateCallbackSpec = new CUpdateCallback100Imp; + t.UpdateCallback = t.UpdateCallbackSpec; + t.UpdateCallbackSpec->ProgressDialog = &t; + t.ItemIndex = index; + t.FullPath = fullFilePath; + t.FolderOperations = _folderOperations; + + t.UpdateCallbackSpec->Init(); + t.UpdateCallbackSpec->PasswordIsDefined = usePassword; + t.UpdateCallbackSpec->Password = password; + + + RINOK(t.Create(GetItemName(index), (HWND)*this)) + return t.Result; +} + +LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) +{ + // DEBUG_PRINT_NUM("OnOpenItemChanged", GetCurrentThreadId()); + + CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam; + if (tpi.FullPathFolderPrefix != _currentFolderPrefix) + return 0; + UInt32 fileIndex = tpi.FileIndex; + UInt32 numItems; + _folder->GetNumberOfItems(&numItems); + + // This code is not 100% OK for cases when there are several files with + // tpi.RelPath name and there are changes in archive before update. + // So tpi.FileIndex can point to another file. + + if (fileIndex >= numItems || GetItemRelPath(fileIndex) != tpi.RelPath) + { + UInt32 i; + for (i = 0; i < numItems; i++) + if (GetItemRelPath(i) == tpi.RelPath) + break; + if (i == numItems) + return 0; + fileIndex = i; + } + + CSelectedState state; + SaveSelectedState(state); + + CDisableNotify disableNotify(*this); // do we need it?? + + HRESULT result = OnOpenItemChanged(fileIndex, fs2us(tpi.FilePath), tpi.UsePassword, tpi.Password); + RefreshListCtrl(state); + if (result != S_OK) + return 0; + return 1; +} + + +CExitEventLauncher g_ExitEventLauncher; + +void CExitEventLauncher::Exit(bool hardExit) +{ + if (_needExit) + { + _exitEvent.Set(); + _needExit = false; + } + + if (_numActiveThreads == 0) + return; + + FOR_VECTOR (i, _threads) + { + ::CThread &th = _threads[i]; + if (Thread_WasCreated(&th)) + { + const DWORD waitResult = WaitForSingleObject(th, hardExit ? 100 : INFINITE); + // Thread_Wait(&th); + // if (waitResult == WAIT_TIMEOUT) wait = 1; + if (!hardExit && waitResult != WAIT_OBJECT_0) + continue; + Thread_Close(&th); + _numActiveThreads--; + } + } +} + + + +static THREAD_FUNC_DECL MyThreadFunction(void *param) +{ + DEBUG_PRINT("==== MyThreadFunction ===="); + + CMyUniquePtr tpi((CTmpProcessInfo *)param); + CChildProcesses &processes = tpi->Processes; + + const bool mainProcessWasSet = !processes.Handles.IsEmpty(); + + bool isComplexMode = true; + + if (!processes.Handles.IsEmpty()) + { + + const DWORD startTime = GetTickCount(); + + /* + CPossibleProgs progs; + { + const UString &name = tpi->RelPath; + int slashPos = name.ReverseFind_PathSepar(); + int dotPos = name.ReverseFind_Dot(); + if (dotPos > slashPos) + { + const UString ext = name.Ptr(dotPos + 1); + AString extA = UnicodeStringToMultiByte(ext); + extA.MakeLower_Ascii(); + progs.SetFromExtension(extA); + } + } + */ + + bool firstPass = true; + + for (;;) + { + CRecordVector handles; + CUIntVector indices; + + FOR_VECTOR (i, processes.Handles) + { + if (handles.Size() > 60) + break; + if (processes.NeedWait[i]) + { + handles.Add(processes.Handles[i]); + indices.Add(i); + } + } + + bool needFindProcessByPath = false; + + if (handles.IsEmpty()) + { + if (!firstPass) + break; + } + else + { + handles.Add(g_ExitEventLauncher._exitEvent); + + DWORD waitResult = WaitForMultiObj_Any_Infinite(handles.Size(), handles.ConstData()); + + waitResult -= WAIT_OBJECT_0; + + if (waitResult >= handles.Size() - 1) + { + processes.CloseAll(); + /* + if (waitResult == handles.Size() - 1) + { + // exit event + // we want to delete temp files, if progs were used + if (processes.ProgsWereUsed) + break; + } + */ + return waitResult >= (DWORD)handles.Size() ? 1 : 0; + } + + if (firstPass && indices.Size() == 1) + { + const DWORD curTime = GetTickCount() - startTime; + + /* + if (curTime > 5 * 1000) + progs.ProgNames.Clear(); + */ + + needFindProcessByPath = (curTime < 2 * 1000); + + if (needFindProcessByPath) + { + NFind::CFileInfo newFileInfo; + if (newFileInfo.Find(tpi->FilePath)) + if (tpi->WasChanged_from_TempFileInfo(newFileInfo)) + needFindProcessByPath = false; + } + + DEBUG_PRINT_NUM(" -- firstPass -- time = ", curTime) + } + + processes.DisableWait(indices[(unsigned)waitResult]); + } + + firstPass = false; + + // Sleep(300); + #ifndef UNDER_CE + processes.Update(needFindProcessByPath /* , progs */); + #endif + } + + + const DWORD curTime = GetTickCount() - startTime; + + DEBUG_PRINT_NUM("after time = ", curTime) + + processes.CloseAll(); + + isComplexMode = (curTime < 2 * 1000); + + } + + bool needCheckTimestamp = true; + + for (;;) + { + NFind::CFileInfo newFileInfo; + + if (!newFileInfo.Find(tpi->FilePath)) + break; + + if (mainProcessWasSet) + { + if (tpi->WasChanged_from_TempFileInfo(newFileInfo)) + { + UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath)); + if (tpi->ReadOnly) + { + m.Add_LF(); + AddLangString(m, IDS_PROP_READ_ONLY); + m.Add_LF(); + m += tpi->FullPathFolderPrefix; + ::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; + } + { + const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath); + if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES) + { + // DEBUG_PRINT_NUM("SendMessage", GetCurrentThreadId()); + if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi.get()) != 1) + { + ::MessageBoxW(g_HWND, m, L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; + } + } + needCheckTimestamp = false; + break; + } + } + + if (!isComplexMode) + break; + } + + // DEBUG_PRINT("WaitForSingleObject"); + DWORD waitResult = ::WaitForSingleObject(g_ExitEventLauncher._exitEvent, INFINITE); + // DEBUG_PRINT("---"); + + if (waitResult == WAIT_OBJECT_0) + break; + + return 1; + } + + { + NFind::CFileInfo newFileInfo; + const bool finded = newFileInfo.Find(tpi->FilePath); + if (!needCheckTimestamp + || !finded + || !tpi->WasChanged_from_TempFileInfo(newFileInfo)) + { + DEBUG_PRINT("Delete Temp file"); + tpi->DeleteDirAndFile(); + } + } + + return 0; +} + + +/* +#if defined(_WIN32) && !defined(UNDER_CE) +static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); +#endif + + +#ifndef UNDER_CE + +static void ReadZoneFile(CFSTR fileName, CByteBuffer &buf) +{ + buf.Free(); + NIO::CInFile file; + if (!file.Open(fileName)) + return; + UInt64 fileSize; + if (!file.GetLength(fileSize)) + return; + if (fileSize == 0 || fileSize >= ((UInt32)1 << 20)) + 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; + UInt32 processed; + if (!file.Write(buf, (UInt32)buf.Size(), processed)) + return false; + return processed == buf.Size(); +} + +#endif +*/ + +/* +Z7_CLASS_IMP_COM_1( + CBufSeqOutStream_WithFile + , ISequentialOutStream +) + Byte *_buffer; + size_t _size; + size_t _pos; + + size_t _fileWritePos; + bool fileMode; +public: + + bool IsStreamInMem() const { return !fileMode; } + size_t GetMemStreamWrittenSize() const { return _pos; } + + // ISequentialOutStream *FileStream; + FString FilePath; + COutFileStream *outFileStreamSpec; + CMyComPtr outFileStream; + + CBufSeqOutStream_WithFile(): outFileStreamSpec(NULL) {} + + void Init(Byte *buffer, size_t size) + { + fileMode = false; + _buffer = buffer; + _pos = 0; + _size = size; + _fileWritePos = 0; + } + + HRESULT FlushToFile(); + size_t GetPos() const { return _pos; } +}; + +static const UInt32 kBlockSize = ((UInt32)1 << 31); + +STDMETHODIMP CBufSeqOutStream_WithFile::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (!fileMode) + { + if (_size - _pos >= size) + { + if (size != 0) + { + memcpy(_buffer + _pos, data, size); + _pos += size; + } + if (processedSize) + *processedSize = (UInt32)size; + return S_OK; + } + + fileMode = true; + } + RINOK(FlushToFile()); + return outFileStream->Write(data, size, processedSize); +} + +HRESULT CBufSeqOutStream_WithFile::FlushToFile() +{ + if (!outFileStream) + { + outFileStreamSpec = new COutFileStream; + outFileStream = outFileStreamSpec; + if (!outFileStreamSpec->Create(FilePath, false)) + { + outFileStream.Release(); + return E_FAIL; + // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath)); + } + } + while (_fileWritePos != _pos) + { + size_t cur = _pos - _fileWritePos; + UInt32 curSize = (cur < kBlockSize) ? (UInt32)cur : kBlockSize; + UInt32 processedSizeLoc = 0; + HRESULT res = outFileStream->Write(_buffer + _fileWritePos, curSize, &processedSizeLoc); + _fileWritePos += processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return E_FAIL; + } + return S_OK; +} +*/ + +/* +static HRESULT GetTime(IFolderFolder *folder, UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) +{ + filetimeIsDefined = false; + NCOM::CPropVariant prop; + RINOK(folder->GetProperty(index, propID, &prop)); + if (prop.vt == VT_FILETIME) + { + filetime = prop.filetime; + filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} +*/ + + +/* +tryInternal tryExternal + false false : unused + false true : external + true false : internal + true true : smart based on file extension: + !alwaysStart(name) : both + alwaysStart(name) : external +*/ + +void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExternal, bool editMode, bool useEditor, const wchar_t *type) +{ + // we don't want to change hash data here + if (IsHashFolder()) + return; + + const UString name = GetItemName(index); + const UString relPath = GetItemRelPath(index); + + if (tryExternal) + if (IsVirus_Message(name)) + return; + + if (!_folderOperations) + { + MessageBox_Error_UnsupportOperation(); + return; + } + + bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name)); + + const UString fullVirtPath = _currentFolderPrefix + relPath; + + CTempDir tempDirectory; + if (!tempDirectory.Create(kTempDirPrefix)) + { + MessageBox_LastError(); + return; + } + + FString tempDir = tempDirectory.GetPath(); + FString tempDirNorm = tempDir; + NName::NormalizeDirPathPrefix(tempDirNorm); + const FString tempFilePath = tempDirNorm + us2fs(Get_Correct_FsFile_Name(name)); + + CTempFileInfo tempFileInfo; + tempFileInfo.FileIndex = index; + tempFileInfo.RelPath = relPath; + tempFileInfo.FolderPath = tempDir; + tempFileInfo.FilePath = tempFilePath; + tempFileInfo.NeedDelete = true; + + if (tryAsArchive) + { + CMyComPtr getStream; + _folder.QueryInterface(IID_IInArchiveGetStream, &getStream); + if (getStream) + { + CMyComPtr subSeqStream; + getStream->GetStream(index, &subSeqStream); + if (subSeqStream) + { + CMyComPtr subStream; + subSeqStream.QueryInterface(IID_IInStream, &subStream); + if (subStream) + { + HRESULT res = OpenAsArc_Msg(subStream, tempFileInfo, fullVirtPath, type ? type : L"" + // , true // showErrorMessage + ); + if (res == S_OK) + { + tempDirectory.DisableDeleting(); + RefreshListCtrl(); + return; + } + if (res == E_ABORT || res != S_FALSE) + return; + if (!tryExternal) + return; + tryAsArchive = false; + } + } + } + } + + + CRecordVector indices; + indices.Add(index); + + UStringVector messages; + + bool usePassword = false; + UString password; + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &fl = _parentFolders.Back(); + usePassword = fl.UsePassword; + password = fl.Password; + } + + /* + #if defined(_WIN32) && !defined(UNDER_CE) + CByteBuffer zoneBuf; + #ifndef _UNICODE + if (g_IsNT) + #endif + if (!_parentFolders.IsEmpty()) + { + const CFolderLink &fl = _parentFolders.Front(); + if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) + ReadZoneFile(fl.FilePath + k_ZoneId_StreamName, zoneBuf); + } + #endif + */ + + + CVirtFileSystem *virtFileSystemSpec = NULL; + CMyComPtr virtFileSystem; + + 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) + { + // actually we want to get sum: size of main file plus sizes of altStreams. + // but now there is no interface to get altStreams sizes. + NCOM::CPropVariant prop; + _folder->GetProperty(index, kpidSize, &prop); + const size_t fileLimit = g_RAM_Size_Defined ? + g_RAM_Size >> MyMax(_parentFolders.Size() + 1, 8u): + 1u << 22; + UInt64 fileSize = 0; + if (!ConvertPropVariantToUInt64(prop, fileSize)) + fileSize = fileLimit; +#if 0 // 1 : for debug + fileLimit = 1; +#endif + + if (fileSize <= fileLimit) + { + options.streamMode = true; + virtFileSystemSpec = new CVirtFileSystem; + virtFileSystem = virtFileSystemSpec; + virtFileSystemSpec->FileName = name; + virtFileSystemSpec->IsAltStreamFile = isAltStream; + +#if defined(_WIN32) && !defined(UNDER_CE) +#ifndef _UNICODE + if (g_IsNT) +#endif + { + Get_ZoneId_Stream_from_ParentFolders(virtFileSystemSpec->ZoneBuf); + options.ZoneBuf = virtFileSystemSpec->ZoneBuf; + } +#endif + + virtFileSystemSpec->MaxTotalAllocSize = (size_t)fileSize + + (1 << 16); // we allow additional total size for small alt streams. + virtFileSystemSpec->DirPrefix = tempDirNorm; + // options.VirtFileSystem = virtFileSystem; + options.VirtFileSystemSpec = virtFileSystemSpec; + } + } + + options.folder = fs2us(tempDirNorm); + options.showErrorMessages = true; + + const HRESULT result = CopyTo(options, indices, &messages, usePassword, password); + + if (!_parentFolders.IsEmpty()) + { + CFolderLink &fl = _parentFolders.Back(); + fl.UsePassword = usePassword; + fl.Password = password; + } + + if (!messages.IsEmpty()) + return; + if (result != S_OK) + { + if (result != E_ABORT) + MessageBox_Error_HRESULT(result); + return; + } + + if (virtFileSystemSpec && !virtFileSystemSpec->WasStreamFlushedToFS()) + { + int index_in_Files = virtFileSystemSpec->Index_of_MainExtractedFile_in_Files; + if (index_in_Files < 0) + { + if (virtFileSystemSpec->Files.Size() != 1) + { + MessageBox_Error_HRESULT(E_FAIL); + return; + } + // it's not expected case that index was not set, but we support that case + index_in_Files = 0; + } + { + const CVirtFile &file = virtFileSystemSpec->Files[index_in_Files]; + CMyComPtr2_Create bufInStream; + bufInStream->Init(file.Data, file.WrittenSize, virtFileSystem); + const HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo, + fullVirtPath, type ? type : L"" + // , encrypted + // , true // showErrorMessage + ); + if (res == S_OK) + { + if (virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files >= 0 + && !_parentFolders.IsEmpty()) + { + const CVirtFile &fileZone = virtFileSystemSpec->Files[ + virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files]; + _parentFolders.Back().ZoneBuf.CopyFrom(fileZone.Data, fileZone.WrittenSize); + } + + tempDirectory.DisableDeleting(); + RefreshListCtrl(); + return; + } + if (res == E_ABORT || res != S_FALSE) + return; + if (!tryExternal) + return; + tryAsArchive = false; + if (virtFileSystemSpec->FlushToDisk(true) != S_OK) + return; + } + } + + + /* + #if defined(_WIN32) && !defined(UNDER_CE) + if (zoneBuf.Size() != 0) + { + if (NFind::DoesFileExist_Raw(tempFilePath)) + { + WriteZoneFile(tempFilePath + k_ZoneId_StreamName, zoneBuf); + } + } + #endif + */ + + + if (tryAsArchive) + { + const HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L"" + // , encrypted + // , true // showErrorMessage + ); + if (res == S_OK) + { + tempDirectory.DisableDeleting(); + RefreshListCtrl(); + return; + } + if (res == E_ABORT || res != S_FALSE) + return; + } + + if (!tryExternal) + return; + + CMyUniquePtr tpi(new CTmpProcessInfo()); + tpi->FolderPath = tempDir; + tpi->FilePath = tempFilePath; + tpi->NeedDelete = true; + tpi->UsePassword = usePassword; + tpi->Password = password; + tpi->ReadOnly = IsThereReadOnlyFolder(); + if (IsHashFolder()) + tpi->ReadOnly = true; + + if (!tpi->FileInfo.Find(tempFilePath)) + return; + + CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi); + + CProcess process; + HRESULT res; + if (editMode) + res = StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process); + else + res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process); + + if ((HANDLE)process == NULL) + { + // win7 / win10 work so for some extensions (pdf, html ..); + DEBUG_PRINT("#### (HANDLE)process == 0"); + // return; + if (res != S_OK) + return; + } + + tpi->Window = (HWND)*this; + tpi->FullPathFolderPrefix = _currentFolderPrefix; + tpi->FileIndex = index; + tpi->RelPath = relPath; + + if ((HANDLE)process) + tpi->Processes.SetMainProcess(process.Detach()); + + ::CThread th; + if (Thread_Create(&th, MyThreadFunction, tpi.get()) != 0) + throw 271824; + g_ExitEventLauncher._threads.Add(th); + g_ExitEventLauncher._numActiveThreads++; + + tempDirectory.DisableDeleting(); + tpi.release(); + tmpProcessInfoRelease._needDelete = false; +} + + +/* +static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24; + +static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime) +{ + return (currentFileTime - folderFileTime > kTimeLimit && + folderFileTime - currentFileTime > kTimeLimit); +} + +void DeleteOldTempFiles() +{ + UString tempPath; + if (!MyGetTempPath(tempPath)) + throw 1; + + UINT64 currentFileTime; + NTime::GetCurUtcFileTime(currentFileTime); + UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp"; + searchWildCard += WCHAR(NName::kAnyStringWildcard); + NFind::CEnumeratorW enumerator(searchWildCard); + NFind::CFileInfo fileInfo; + while (enumerator.Next(fileInfo)) + { + if (!fileInfo.IsDir()) + continue; + const UINT64 &cTime = *(const UINT64 *)(&fileInfo.CTime); + if (CheckDeleteItem(cTime, currentFileTime)) + RemoveDirectoryWithSubItems(tempPath + fileInfo.Name); + } +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelItems.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItems.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelItems.cpp 2015-10-09 10:25:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelItems.cpp 2024-10-04 08:00:00.000000000 +0000 @@ -1,1164 +1,1453 @@ -// PanelItems.cpp - -#include "StdAfx.h" - -#include "../../../../C/Sort.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/Menu.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../PropID.h" - -#include "resource.h" - -#include "LangUtils.h" -#include "Panel.h" -#include "PropertyName.h" -#include "RootFolder.h" - -using namespace NWindows; - -static bool GetColumnVisible(PROPID propID, bool isFsFolder) -{ - if (isFsFolder) - { - switch (propID) - { - case kpidATime: - case kpidAttrib: - case kpidPackSize: - case kpidINode: - case kpidLinks: - case kpidNtReparse: - return false; - } - } - return true; -} - -static int GetColumnWidth(PROPID propID, VARTYPE /* varType */) -{ - switch (propID) - { - case kpidName: return 160; - } - return 100; -} - -static int GetColumnAlign(PROPID propID, VARTYPE varType) -{ - switch (propID) - { - case kpidCTime: - case kpidATime: - case kpidMTime: - return LVCFMT_LEFT; - } - - switch (varType) - { - case VT_UI1: - case VT_I2: - case VT_UI2: - case VT_I4: - case VT_INT: - case VT_UI4: - case VT_UINT: - case VT_I8: - case VT_UI8: - case VT_BOOL: - return LVCFMT_RIGHT; - - case VT_EMPTY: - case VT_I1: - case VT_FILETIME: - case VT_BSTR: - return LVCFMT_LEFT; - - default: - return LVCFMT_CENTER; - } -} - -HRESULT CPanel::InitColumns() -{ -printf("CPanel::InitColumns\n"); - if (_needSaveInfo) - SaveListViewInfo(); - - _listView.DeleteAllItems(); - _selectedStatusVector.Clear(); - // printf("CPanel::InitColumns : _selectedStatusVector.Clear()\n"); - - ReadListViewInfo(); - - // PROPID sortID; - /* - if (_listViewInfo.SortIndex >= 0) - sortID = _listViewInfo.Columns[_listViewInfo.SortIndex].PropID; - */ - // sortID = _listViewInfo.SortID; - - _ascending = _listViewInfo.Ascending; - - _properties.Clear(); - - _needSaveInfo = true; - bool isFsFolder = IsFSFolder() || IsAltStreamsFolder(); - - { - UInt32 numProps; - _folder->GetNumberOfProperties(&numProps); - - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE varType; - HRESULT res = _folder->GetPropertyInfo(i, &name, &propID, &varType); - - if (res != S_OK) - { - /* We can return ERROR, but in that case, other code will not be called, - and user can see empty window without error message. So we just ignore that field */ - continue; - } - if (propID == kpidIsDir) - continue; - CItemProperty prop; - prop.Type = varType; - prop.ID = propID; - prop.Name = GetNameOfProperty(propID, name); - prop.Order = -1; - prop.IsVisible = GetColumnVisible(propID, isFsFolder); - prop.Width = GetColumnWidth(propID, varType); - prop.IsRawProp = false; - _properties.Add(prop); - } - } - - if (_folderRawProps) - { - UInt32 numProps; - _folderRawProps->GetNumRawProps(&numProps); - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - RINOK(_folderRawProps->GetRawPropInfo(i, &name, &propID)); - - CItemProperty prop; - prop.Type = VT_EMPTY; - prop.ID = propID; - prop.Name = GetNameOfProperty(propID, name); - prop.Order = -1; - prop.IsVisible = GetColumnVisible(propID, isFsFolder); - prop.Width = GetColumnWidth(propID, VT_BSTR);; - prop.IsRawProp = true; - _properties.Add(prop); - } - } - - // InitColumns2(sortID); - - for (;;) - if (!_listView.DeleteColumn(0)) - break; - - unsigned order = 0; - unsigned i; - for (i = 0; i < _listViewInfo.Columns.Size(); i++) - { - const CColumnInfo &columnInfo = _listViewInfo.Columns[i]; - int index = _properties.FindItemWithID(columnInfo.PropID); - if (index >= 0) - { - CItemProperty &item = _properties[index]; - item.IsVisible = columnInfo.IsVisible; - item.Width = columnInfo.Width; - if (columnInfo.IsVisible) - item.Order = order++; - continue; - } - } - - for (i = 0; i < _properties.Size(); i++) - { - CItemProperty &item = _properties[i]; - if (item.Order < 0) - item.Order = order++; - } - - _visibleProperties.Clear(); - for (i = 0; i < _properties.Size(); i++) - { - const CItemProperty &prop = _properties[i]; - if (prop.IsVisible) - _visibleProperties.Add(prop); - } - - // _sortIndex = 0; - _sortID = kpidName; - /* - if (_listViewInfo.SortIndex >= 0) - { - int sortIndex = _properties.FindItemWithID(sortID); - if (sortIndex >= 0) - _sortIndex = sortIndex; - } - */ - _sortID = _listViewInfo.SortID; - - _visibleProperties.Sort(); - for (i = 0; i < _visibleProperties.Size(); i++) - { - InsertColumn(i); - } - return S_OK; -} - -void CPanel::InsertColumn(unsigned index) -{ - const CItemProperty &prop = _visibleProperties[index]; - LV_COLUMNW column; - column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER; - column.cx = prop.Width; - column.fmt = GetColumnAlign(prop.ID, prop.Type); - // FIXME not available column.iOrder = prop.Order; - // iOrder must be <= _listView.ItemCount - column.iSubItem = index; - column.pszText = const_cast((const wchar_t *)prop.Name); - // printf("CPanel::InsertColumn(%d)=>'%ls'\n",index,column.pszText); fflush(stdout); - _listView.InsertColumn(index, &column); -} - -HRESULT CPanel::RefreshListCtrl() -{ - return RefreshListCtrl(UString(), -1, true, UStringVector()); -} - -// int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); -int -#if defined(__WIN32__) && !defined(__WXMICROWIN__) // FIXME - wxCALLBACK -#endif - CompareItems_WX(long item1, long item2, long sortData); - - -void CPanel::GetSelectedNames(UStringVector &selectedNames) -{ - CRecordVector indices; - GetSelectedItemsIndices(indices); - selectedNames.ClearAndReserve(indices.Size()); - FOR_VECTOR (i, indices) - selectedNames.AddInReserved(GetItemRelPath(indices[i])); - - /* - for (int i = 0; i < _listView.GetItemCount(); i++) - { - const int kSize = 1024; - WCHAR name[kSize + 1]; - LVITEMW item; - item.iItem = i; - item.pszText = name; - item.cchTextMax = kSize; - item.iSubItem = 0; - item.mask = LVIF_TEXT | LVIF_PARAM; - if (!_listView.GetItem(&item)) - continue; - int realIndex = GetRealIndex(item); - if (realIndex == kParentIndex) - continue; - if (_selectedStatusVector[realIndex]) - selectedNames.Add(item.pszText); - } - */ - selectedNames.Sort(); -} - -void CPanel::SaveSelectedState(CSelectedState &s) -{ - s.FocusedName.Empty(); - s.SelectedNames.Clear(); - s.FocusedItem = _listView.GetFocusedItem(); - { - if (s.FocusedItem >= 0) - { - int realIndex = GetRealItemIndex(s.FocusedItem); - if (realIndex != kParentIndex) - s.FocusedName = GetItemRelPath(realIndex); - /* - const int kSize = 1024; - WCHAR name[kSize + 1]; - LVITEMW item; - item.iItem = focusedItem; - item.pszText = name; - item.cchTextMax = kSize; - item.iSubItem = 0; - item.mask = LVIF_TEXT; - if (_listView.GetItem(&item)) - focusedName = item.pszText; - */ - } - } - GetSelectedNames(s.SelectedNames); -} - -HRESULT CPanel::RefreshListCtrl(const CSelectedState &s) -{ -printf("CPanel::RefreshListCtrl\n"); - bool selectFocused = s.SelectFocused; - if (_mySelectMode) - selectFocused = true; - return RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames); -} - -HRESULT CPanel::RefreshListCtrlSaveFocused() -{ - CSelectedState state; - SaveSelectedState(state); - return RefreshListCtrl(state); -} - -void CPanel::SetFocusedSelectedItem(int index, bool select) -{ - UINT state = LVIS_FOCUSED; - if (select) - state |= LVIS_SELECTED; - _listView.SetItemState(index, state, state); - if (!_mySelectMode && select) - { - int realIndex = GetRealItemIndex(index); - if (realIndex != kParentIndex) - { - // printf("CPanel::SetFocusedSelectedItem(%d,%d) : _selectedStatusVector[%d]=%d => true\n",index,select,realIndex,_selectedStatusVector[realIndex]); - _selectedStatusVector[realIndex] = true; - } - } -} - -HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, - const UStringVector &selectedNames) -{ - _dontShowMode = false; - LoadFullPathAndShow(); - // OutputDebugStringA("=======\n"); - // OutputDebugStringA("s1 \n"); - CDisableTimerProcessing timerProcessing(*this); - CDisableNotify disableNotify(*this); - - if (focusedPos < 0) - focusedPos = 0; - - _listView.SetRedraw(false); - // m_RedrawEnabled = false; - -#ifdef _WIN32 - LVITEMW item; - ZeroMemory(&item, sizeof(item)); -#else - LVITEMW item = { 0 }; -#endif - - // DWORD tickCount0 = GetTickCount(); - _enableItemChangeNotify = false; - _listView.DeleteAllItems(); - _enableItemChangeNotify = true; - - - int listViewItemCount = 0; - - // printf("&&&&&&&&&&&&&& _selectedStatusVector.Clear() &&&&&&&&&&&&&&\n"); - _selectedStatusVector.Clear(); - // _realIndices.Clear(); - _startGroupSelect = 0; - - _selectionIsDefined = false; - - // m_Files.Clear(); - - if (!_folder) - { - // throw 1; - SetToRootFolder(); - } - - // FIXME _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); - - { - CMyComPtr folderSetFlatMode; - _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); - if (folderSetFlatMode) - folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); - } - - /* - { - CMyComPtr setShow; - _folder.QueryInterface(IID_IFolderSetShowNtfsStreamsMode, &setShow); - if (setShow) - setShow->SetShowNtfsStreamsMode(BoolToInt(_showNtfsStrems_Mode)); - } - */ - - // DWORD tickCount1 = GetTickCount(); - RINOK(_folder->LoadItems()); - // DWORD tickCount2 = GetTickCount(); - RINOK(InitColumns()); - - // OutputDebugString(TEXT("Start Dir\n")); - UInt32 numItems; - _folder->GetNumberOfItems(&numItems); - - bool showDots = _showDots && !IsRootFolder(); - - _listView.SetItemCount(numItems + (showDots ? 1 : 0)); - - _selectedStatusVector.ClearAndReserve(numItems); - // printf("_selectedStatusVector.ClearAndReserve(%d)\n",numItems); - int cursorIndex = -1; - - CMyComPtr folderGetSystemIconIndex; - if (!Is_Slow_Icon_Folder() || _showRealFileIcons) - _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); - - if (!IsFSFolder()) - { - CMyComPtr getFolderArcProps; - _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); - _thereAreDeletedItems = false; - if (getFolderArcProps) - { - CMyComPtr arcProps; - getFolderArcProps->GetFolderArcProps(&arcProps); - if (arcProps) - { - UInt32 numLevels; - if (arcProps->GetArcNumLevels(&numLevels) != S_OK) - numLevels = 0; - NCOM::CPropVariant prop; - if (arcProps->GetArcProp(numLevels - 1, kpidIsDeleted, &prop) == S_OK) - if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal)) - _thereAreDeletedItems = true; - } - } - } - - if (showDots) - { - UString itemName = L".."; - item.iItem = listViewItemCount; - if (itemName == focusedName) - cursorIndex = item.iItem; - item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - int subItem = 0; - item.iSubItem = subItem++; - item.lParam = kParentIndex; - item.pszText = const_cast((const wchar_t *)itemName); // FIXME item.pszText = LPSTR_TEXTCALLBACKW; - UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY; - item.iImage = _extToIconMap.GetIconIndex(attrib, itemName); - if (item.iImage < 0) - item.iImage = 0; - if (_listView.InsertItem(&item) == -1) - return E_FAIL; - - listViewItemCount++; - } - - // OutputDebugStringA("S1\n"); - - UString correctedName; - UString itemName; - UString relPath; - - printf("ADD ITEMS - BEGIN\n"); - for (UInt32 i = 0; i < numItems; i++) - { - const wchar_t *name = NULL; - unsigned nameLen = 0; - - if (_folderGetItemName) - _folderGetItemName->GetItemName(i, &name, &nameLen); - if (!name) - { - GetItemName(i, itemName); - name = itemName; - nameLen = itemName.Len(); - } - - bool selected = false; - - if (!focusedName.IsEmpty() || !selectedNames.IsEmpty()) - { - relPath.Empty(); - - // relPath += GetItemPrefix(i); - // change it (_flatMode) - if (i != kParentIndex && _flatMode) - { - const wchar_t *prefix = NULL; - if (_folderGetItemName) - { - unsigned prefixLen = 0; - _folderGetItemName->GetItemPrefix(i, &prefix, &prefixLen); - if (prefix) - relPath += prefix; - } - if (!prefix) - { - NCOM::CPropVariant prop; - if (_folder->GetProperty(i, kpidPrefix, &prop) != S_OK) - throw 2723400; - if (prop.vt == VT_BSTR) - relPath += prop.bstrVal; - } - } - relPath += name; - if (relPath == focusedName) - cursorIndex = listViewItemCount; - if (selectedNames.FindInSorted(relPath) >= 0) - selected = true; - } - - _selectedStatusVector.AddInReserved(selected); - // printf("_selectedStatusVector.AddInReserved(%d)\n",selected); - - - item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; - - if (!_mySelectMode) - if (selected) - { - item.mask |= LVIF_STATE; - item.state = LVIS_SELECTED; - } - - int subItem = 0; - item.iItem = listViewItemCount; - - item.iSubItem = subItem++; - item.lParam = i; - - /* - int finish = nameLen - 4; - int j; - for (j = 0; j < finish; j++) - { - if (name[j ] == ' ' && - name[j + 1] == ' ' && - name[j + 2] == ' ' && - name[j + 3] == ' ' && - name[j + 4] == ' ') - break; - } - if (j < finish) - { - correctedName.Empty(); - correctedName = L"virus"; - int pos = 0; - for (;;) - { - int posNew = itemName.Find(L" ", pos); - if (posNew < 0) - { - correctedName += itemName.Ptr(pos); - break; - } - correctedName += itemName.Mid(pos, posNew - pos); - correctedName += L" ... "; - pos = posNew; - while (itemName[++pos] == ' '); - } - item.pszText = const_cast((const wchar_t *)correctedName); - } - else - */ - { - item.pszText = const_cast((const wchar_t *)name); // FIXME item.pszText = LPSTR_TEXTCALLBACKW; - /* LPSTR_TEXTCALLBACKW works, but in some cases there are problems, - since we block notify handler. */ - } - - UInt32 attrib = 0; - // for (int yyy = 0; yyy < 6000000; yyy++) { - NCOM::CPropVariant prop; - RINOK(_folder->GetProperty(i, kpidAttrib, &prop)); - if (prop.vt == VT_UI4) - { - // char s[256]; sprintf(s, "attrib = %7x", attrib); OutputDebugStringA(s); - attrib = prop.ulVal; - } - else if (IsItem_Folder(i)) - attrib |= FILE_ATTRIBUTE_DIRECTORY; - // } - - bool defined = false; -#ifdef _WIN32 - if (folderGetSystemIconIndex) - { - folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); - defined = (item.iImage > 0); - } -#endif - if (!defined) - { - if (_currentFolderPrefix.IsEmpty()) - { - int iconIndexTemp; - GetRealIconIndex(us2fs((UString)name) + FCHAR_PATH_SEPARATOR, attrib, iconIndexTemp); - item.iImage = iconIndexTemp; - } - else - { - item.iImage = _extToIconMap.GetIconIndex(attrib, name); - } - } - - if (item.iImage < 0) - item.iImage = 0; - - if (_listView.InsertItem(&item) == -1) - return E_FAIL; - - - // FIXME Added - item.pszText = (LPWSTR)malloc(4096); // FIXME - for(int col=1;col < _listView.GetColumnCount(); col++) - { - item.iSubItem = col; - item.cchTextMax = 4096 / sizeof(item.pszText[0]); - this->SetItemText(item); - _listView.SetItem(&item); - } - free(item.pszText); item.pszText = 0; - - listViewItemCount++; - } - printf("ADD ITEMS - END\n"); - - // OutputDebugStringA("End2\n"); - -#if _WIN32 - // FIXME : with wxWidget, after sortitems, the item is unselected and unfocused - if (_listView.GetItemCount() > 0 && cursorIndex >= 0) - SetFocusedSelectedItem(cursorIndex, selectFocused); -#endif - // DWORD tickCount3 = GetTickCount(); - SetSortRawStatus(); - _listView.SortItems(CompareItems_WX, (LPARAM)this); - - - - // DWORD tickCount4 = GetTickCount(); - if (cursorIndex < 0 && _listView.GetItemCount() > 0) - { - if (focusedPos >= _listView.GetItemCount()) - focusedPos = _listView.GetItemCount() - 1; - // we select item only in showDots mode. - SetFocusedSelectedItem(focusedPos, showDots); - } - // m_RedrawEnabled = true; - // DWORD tickCount5 = GetTickCount(); - _listView.EnsureVisible(_listView.GetFocusedItem(), false); - // DWORD tickCount6 = GetTickCount(); - - disableNotify.SetMemMode_Enable(); - disableNotify.Restore(); - _listView.SetRedraw(true); - // DWORD tickCount7 = GetTickCount(); - _listView.InvalidateRect(NULL, true); - // DWORD tickCount8 = GetTickCount(); - // OutputDebugStringA("End1\n"); - /* - _listView.UpdateWindow(); - */ - Refresh_StatusBar(); - // DWORD tickCount9 = GetTickCount(); - /* - char s[256]; - sprintf(s, - // "attribMap = %5d, extMap = %5d, " - "delete = %5d, load = %5d, list = %5d, sort = %5d, end = %5d", - // _extToIconMap._attribMap.Size(), - // _extToIconMap._extMap.Size(), - tickCount1 - tickCount0, - tickCount2 - tickCount1, - tickCount3 - tickCount2, - tickCount4 - tickCount3, - tickCount5 - tickCount4 - ); - sprintf(s, - "5 = %5d, 6 = %5d, 7 = %5d, 8 = %5d, 9 = %5d", - tickCount5 - tickCount4, - tickCount6 - tickCount5, - tickCount7 - tickCount6, - tickCount8 - tickCount7, - tickCount9 - tickCount8 - ); - OutputDebugStringA(s); - */ - return S_OK; -} - -void CPanel::GetSelectedItemsIndices(CRecordVector &indices) const -{ - indices.Clear(); - /* - int itemIndex = -1; - while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1) - { - LPARAM param; - if (_listView.GetItemParam(itemIndex, param)) - indices.Add(param); - } - */ - FOR_VECTOR (i, _selectedStatusVector) - if (_selectedStatusVector[i]) - indices.Add(i); - // HeapSort(&indices.Front(), indices.Size()); -} - -void CPanel::GetOperatedItemIndices(CRecordVector &indices) const -{ - GetSelectedItemsIndices(indices); - if (!indices.IsEmpty()) - return; - if (_listView.GetSelectedCount() == 0) - return; - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem >= 0) - { - if (_listView.IsItemSelected(focusedItem)) - { - int realIndex = GetRealItemIndex(focusedItem); - if (realIndex != kParentIndex) - indices.Add(realIndex); - } - } -} - -void CPanel::GetAllItemIndices(CRecordVector &indices) const -{ - indices.Clear(); - UInt32 numItems; - if (_folder->GetNumberOfItems(&numItems) == S_OK) - for (UInt32 i = 0; i < numItems; i++) - indices.Add(i); -} - -void CPanel::GetOperatedIndicesSmart(CRecordVector &indices) const -{ - GetOperatedItemIndices(indices); - if (indices.IsEmpty() || (indices.Size() == 1 && indices[0] == (UInt32)(Int32)-1)) - GetAllItemIndices(indices); -} - -/* -void CPanel::GetOperatedListViewIndices(CRecordVector &indices) const -{ - indices.Clear(); - int numItems = _listView.GetItemCount(); - for (int i = 0; i < numItems; i++) - { - int realIndex = GetRealItemIndex(i); - if (realIndex >= 0) - if (_selectedStatusVector[realIndex]) - indices.Add(i); - } - if (indices.IsEmpty()) - { - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem >= 0) - indices.Add(focusedItem); - } -} -*/ - -void CPanel::EditItem(bool useEditor) -{ - if (!useEditor) - { - CMyComPtr calcItemFullSize; - _folder.QueryInterface(IID_IFolderCalcItemFullSize, &calcItemFullSize); - if (calcItemFullSize) - { - bool needRefresh = false; - CRecordVector indices; - GetOperatedItemIndices(indices); - FOR_VECTOR (i, indices) - { - UInt32 index = indices[i]; - if (IsItem_Folder(index)) - { - calcItemFullSize->CalcItemFullSize(index, NULL); - needRefresh = true; - } - } - if (needRefresh) - { - // _listView.RedrawItem(0); - // _listView.RedrawAllItems(); - InvalidateList(); - return; - } - } - } - - - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = GetRealItemIndex(focusedItem); - if (realIndex == kParentIndex) - return; - if (!IsItem_Folder(realIndex)) - EditItem(realIndex, useEditor); -} - -void CPanel::OpenFocusedItemAsInternal(const wchar_t *type) -{ - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = GetRealItemIndex(focusedItem); - if (IsItem_Folder(realIndex)) - OpenFolder(realIndex); - else - OpenItem(realIndex, true, false, type); -} - -void CPanel::OpenSelectedItems(bool tryInternal) -{ - CRecordVector indices; - GetOperatedItemIndices(indices); - if (indices.Size() > 20) - { - MessageBoxErrorLang(IDS_TOO_MANY_ITEMS); - return; - } - - int focusedItem = _listView.GetFocusedItem(); - - // printf("###### CPanel::OpenSelectedItems(tryInternal=%d)-1 focusedItem=%d indices.Size()=%d\n",(int)tryInternal,focusedItem,(int)indices.Size()); - - if (focusedItem >= 0) - { - int realIndex = GetRealItemIndex(focusedItem); - if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0) && _listView.IsItemSelected(focusedItem)) - indices.Insert(0, realIndex); - // printf("###### CPanel::OpenSelectedItems(tryInternal=%d) realIndex=%d indices.Size()=%d\n",(int)tryInternal,realIndex,(int)indices.Size()); - } - - bool dirIsStarted = false; - FOR_VECTOR (i, indices) - { - UInt32 index = indices[i]; - // CFileInfo &aFile = m_Files[index]; - if (IsItem_Folder(index)) - { - if (!dirIsStarted) - { - if (tryInternal) - { - OpenFolder(index); - dirIsStarted = true; - break; - } - else - OpenFolderExternal(index); - } - } - else - OpenItem(index, (tryInternal && indices.Size() == 1), true); - } -} - -UString CPanel::GetItemName(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return L".."; - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) - throw 2723400; - if (prop.vt != VT_BSTR) - throw 2723401; - return prop.bstrVal; -} - -UString CPanel::GetItemName_for_Copy(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return L".."; - { - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidOutName, &prop) == S_OK) - { - if (prop.vt == VT_BSTR) - return prop.bstrVal; - if (prop.vt != VT_EMPTY) - throw 2723401; - } - } - return GetItemName(itemIndex); -} - -void CPanel::GetItemName(int itemIndex, UString &s) const -{ - if (itemIndex == kParentIndex) - { - s = L".."; - return; - } - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) - throw 2723400; - if (prop.vt != VT_BSTR) - throw 2723401; - s.SetFromBstr(prop.bstrVal); -} - -UString CPanel::GetItemPrefix(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return UString(); - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidPrefix, &prop) != S_OK) - throw 2723400; - UString prefix; - if (prop.vt == VT_BSTR) - prefix.SetFromBstr(prop.bstrVal); - return prefix; -} - -UString CPanel::GetItemRelPath(int itemIndex) const -{ - return GetItemPrefix(itemIndex) + GetItemName(itemIndex); -} - -UString CPanel::GetItemRelPath2(int itemIndex) const -{ - UString s = GetItemRelPath(itemIndex); - #if defined(_WIN32) && !defined(UNDER_CE) - if (s.Len() == 2 && NFile::NName::IsDrivePath2(s)) - { - if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()) - s.Add_PathSepar(); - } - #endif - return s; -} - -UString CPanel::GetItemFullPath(int itemIndex) const -{ - return GetFsPath() + GetItemRelPath2(itemIndex); -} - -bool CPanel::GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const -{ - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, propID, &prop) != S_OK) - throw 2723400; - if (prop.vt == VT_BOOL) - return VARIANT_BOOLToBool(prop.boolVal); - if (prop.vt == VT_EMPTY) - return false; - throw 2723401; -} - -bool CPanel::IsItem_Deleted(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return false; - return GetItem_BoolProp(itemIndex, kpidIsDeleted); -} - -bool CPanel::IsItem_Folder(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return true; - return GetItem_BoolProp(itemIndex, kpidIsDir); -} - -bool CPanel::IsItem_AltStream(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return false; - return GetItem_BoolProp(itemIndex, kpidIsAltStream); -} - -UInt64 CPanel::GetItemSize(int itemIndex) const -{ - if (itemIndex == kParentIndex) - return 0; - if (_folderGetItemName) - return _folderGetItemName->GetItemSize(itemIndex); - NCOM::CPropVariant prop; - if (_folder->GetProperty(itemIndex, kpidSize, &prop) != S_OK) - throw 2723400; - UInt64 val = 0; - if (ConvertPropVariantToUInt64(prop, val)) - return val; - return 0; -} - -void CPanel::ReadListViewInfo() -{ - _typeIDString = GetFolderTypeID(); - if (!_typeIDString.IsEmpty()) - _listViewInfo.Read(_typeIDString); -} - -void CPanel::SaveListViewInfo() -{ - unsigned i; - - printf("CPanel::SaveListViewInfo - BEGIN\n"); - for (i = 0; i < _visibleProperties.Size(); i++) - { - CItemProperty &prop = _visibleProperties[i]; - LVCOLUMN winColumnInfo; - winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH; - if (!_listView.GetColumn(i, &winColumnInfo)) - throw 1; - // FIXME printf("CPanel::SaveListViewInfo - i=%d ID=%d Order=%d => %d\n",i,prop.ID,prop.Order,winColumnInfo.iOrder); - // FIXME prop.Order = winColumnInfo.iOrder; winColumnInfo.iOrder not set with _listView.GetColumn - prop.Width = winColumnInfo.cx; - } - printf("CPanel::SaveListViewInfo - END\n"); - - CListViewInfo viewInfo; - - // PROPID sortPropID = _properties[_sortIndex].ID; - PROPID sortPropID = _sortID; - - _visibleProperties.Sort(); - - for (i = 0; i < _visibleProperties.Size(); i++) - { - const CItemProperty &prop = _visibleProperties[i]; - CColumnInfo columnInfo; - columnInfo.IsVisible = prop.IsVisible; - columnInfo.PropID = prop.ID; - columnInfo.Width = prop.Width; - viewInfo.Columns.Add(columnInfo); - } - - for (i = 0; i < _properties.Size(); i++) - { - const CItemProperty &prop = _properties[i]; - if (!prop.IsVisible) - { - CColumnInfo columnInfo; - columnInfo.IsVisible = prop.IsVisible; - columnInfo.PropID = prop.ID; - columnInfo.Width = prop.Width; - viewInfo.Columns.Add(columnInfo); - } - } - - viewInfo.SortID = sortPropID; - viewInfo.Ascending = _ascending; - if (!_listViewInfo.IsEqual(viewInfo)) - { - viewInfo.Save(_typeIDString); - _listViewInfo = viewInfo; - } -} - -#ifdef _WIN32 -bool CPanel::OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActiveate, LRESULT &result) -{ - if (itemActiveate->hdr.hwndFrom == HWND(_listView)) - return false; - POINT point; - ::GetCursorPos(&point); - ShowColumnsContextMenu(point.x, point.y); - result = TRUE; - return true; -} - -void CPanel::ShowColumnsContextMenu(int x, int y) -{ - CMenu menu; - CMenuDestroyer menuDestroyer(menu); - - menu.CreatePopup(); - - const int kCommandStart = 100; - FOR_VECTOR (i, _properties) - { - const CItemProperty &prop = _properties[i]; - UINT flags = MF_STRING; - if (prop.IsVisible) - flags |= MF_CHECKED; - if (i == 0) - flags |= MF_GRAYED; - menu.AppendItem(flags, kCommandStart + i, prop.Name); - } - - int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, x, y, _listView); - - if (menuResult >= kCommandStart && menuResult <= kCommandStart + (int)_properties.Size()) - { - int index = menuResult - kCommandStart; - CItemProperty &prop = _properties[index]; - prop.IsVisible = !prop.IsVisible; - - if (prop.IsVisible) - { - unsigned num = _visibleProperties.Size(); - prop.Order = num; - _visibleProperties.Add(prop); - InsertColumn(num); - } - else - { - int visibleIndex = _visibleProperties.FindItemWithID(prop.ID); - if (visibleIndex >= 0) - { - _visibleProperties.Delete(visibleIndex); - /* - if (_sortIndex == index) - { - _sortIndex = 0; - _ascending = true; - } - */ - if (_sortID == prop.ID) - { - _sortID = kpidName; - _ascending = true; - } - - _listView.DeleteColumn(visibleIndex); - } - } - } -} -#endif - -void CPanel::OnReload() -{ - HRESULT res = RefreshListCtrlSaveFocused(); - if (res != S_OK) - MessageBoxError(res); -} - -void CPanel::OnTimer() -{ - if (!_processTimer) - return; - if (!AutoRefresh_Mode) - return; - CMyComPtr folderWasChanged; - if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK) - return; - Int32 wasChanged; - if (folderWasChanged->WasChanged(&wasChanged) != S_OK) - return; - if (wasChanged == 0) - return; - OnReload(); -} +// PanelItems.cpp + +#include "StdAfx.h" + +#include "../../../../C/Sort.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../PropID.h" + +#include "../Common/ExtractingFilePath.h" + +#include "resource.h" + +#include "LangUtils.h" +#include "Panel.h" +#include "PropertyName.h" +#include "RootFolder.h" + +using namespace NWindows; + +static bool GetColumnVisible(PROPID propID, bool isFsFolder) +{ + if (isFsFolder) + { + switch (propID) + { + case kpidATime: + case kpidChangeTime: + case kpidAttrib: + case kpidPackSize: + case kpidINode: + case kpidLinks: + case kpidNtReparse: + return false; + } + } + return true; +} + +static unsigned GetColumnWidth(PROPID propID, VARTYPE /* varType */) +{ + switch (propID) + { + case kpidName: return 160; + } + return 100; +} + +static int GetColumnAlign(PROPID propID, VARTYPE varType) +{ + switch (propID) + { + case kpidCTime: + case kpidATime: + case kpidMTime: + case kpidChangeTime: + return LVCFMT_LEFT; + } + + switch (varType) + { + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_I4: + case VT_INT: + case VT_UI4: + case VT_UINT: + case VT_I8: + case VT_UI8: + case VT_BOOL: + return LVCFMT_RIGHT; + + case VT_EMPTY: + case VT_I1: + case VT_FILETIME: + case VT_BSTR: + return LVCFMT_LEFT; + + default: + return LVCFMT_CENTER; + } +} + + +static int ItemProperty_Compare_NameFirst(void *const *a1, void *const *a2, void * /* param */) +{ + return (*(*((const CPropColumn *const *)a1))).Compare_NameFirst + (*(*((const CPropColumn *const *)a2))); +} + +HRESULT CPanel::InitColumns() +{ + SaveListViewInfo(); + + // DeleteListItems(); + _selectedStatusVector.Clear(); + + { + // ReadListViewInfo(); + const UString oldType = _typeIDString; + _typeIDString = GetFolderTypeID(); + // an empty _typeIDString is allowed. + + // we read registry only for new FolderTypeID + if (!_needSaveInfo || _typeIDString != oldType) + _listViewInfo.Read(_typeIDString); + + // folders with same FolderTypeID can have different columns + // so we still read columns for that case. + // if (_needSaveInfo && _typeIDString == oldType) return S_OK; + } + + // PROPID sortID; + /* + if (_listViewInfo.SortIndex >= 0) + sortID = _listViewInfo.Columns[_listViewInfo.SortIndex].PropID; + */ + // sortID = _listViewInfo.SortID; + + _ascending = _listViewInfo.Ascending; + + _columns.Clear(); + + const bool isFsFolder = IsFSFolder() || IsAltStreamsFolder(); + + { + UInt32 numProps; + _folder->GetNumberOfProperties(&numProps); + + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + HRESULT res = _folder->GetPropertyInfo(i, &name, &propID, &varType); + + if (res != S_OK) + { + /* We can return ERROR, but in that case, other code will not be called, + and user can see empty window without error message. So we just ignore that field */ + continue; + } + if (propID == kpidIsDir) + continue; + CPropColumn prop; + prop.Type = varType; + prop.ID = propID; + prop.Name = GetNameOfProperty(propID, name); + prop.Order = -1; + prop.IsVisible = GetColumnVisible(propID, isFsFolder); + prop.Width = GetColumnWidth(propID, varType); + prop.IsRawProp = false; + _columns.Add(prop); + } + + /* + { + // debug column + CPropColumn prop; + prop.Type = VT_BSTR; + prop.ID = 2000; + prop.Name = "Debug"; + prop.Order = -1; + prop.IsVisible = true; + prop.Width = 300; + prop.IsRawProp = false; + _columns.Add(prop); + } + */ + } + + if (_folderRawProps) + { + UInt32 numProps; + _folderRawProps->GetNumRawProps(&numProps); + + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + const HRESULT res = _folderRawProps->GetRawPropInfo(i, &name, &propID); + if (res != S_OK) + continue; + CPropColumn prop; + prop.Type = VT_EMPTY; + prop.ID = propID; + prop.Name = GetNameOfProperty(propID, name); + prop.Order = -1; + prop.IsVisible = GetColumnVisible(propID, isFsFolder); + prop.Width = GetColumnWidth(propID, VT_BSTR); + prop.IsRawProp = true; + _columns.Add(prop); + } + } + + unsigned order = 0; + unsigned i; + + for (i = 0; i < _listViewInfo.Columns.Size(); i++) + { + const CColumnInfo &columnInfo = _listViewInfo.Columns[i]; + const int index = _columns.FindItem_for_PropID(columnInfo.PropID); + if (index >= 0) + { + CPropColumn &item = _columns[index]; + if (item.Order >= 0) + continue; // we ignore duplicated items + bool isVisible = columnInfo.IsVisible; + // we enable kpidName, if it was disabled by some incorrect code + if (columnInfo.PropID == kpidName) + isVisible = true; + item.IsVisible = isVisible; + item.Width = columnInfo.Width; + if (isVisible) + item.Order = (int)(order++); + continue; + } + } + + for (i = 0; i < _columns.Size(); i++) + { + CPropColumn &item = _columns[i]; + if (item.IsVisible && item.Order < 0) + item.Order = (int)(order++); + } + + for (i = 0; i < _columns.Size(); i++) + { + CPropColumn &item = _columns[i]; + if (item.Order < 0) + item.Order = (int)(order++); + } + + CPropColumns newColumns; + + for (i = 0; i < _columns.Size(); i++) + { + const CPropColumn &prop = _columns[i]; + if (prop.IsVisible) + newColumns.Add(prop); + } + + + /* + _sortIndex = 0; + if (_listViewInfo.SortIndex >= 0) + { + int sortIndex = _columns.FindItem_for_PropID(sortID); + if (sortIndex >= 0) + _sortIndex = sortIndex; + } + */ + + if (_listViewInfo.IsLoaded) + _sortID = _listViewInfo.SortID; + else + { + _sortID = 0; + if (IsFSFolder() || IsAltStreamsFolder() || IsArcFolder()) + _sortID = kpidName; + } + + /* There are restrictions in ListView control: + 1) main column (kpidName) must have (LV_COLUMNW::iSubItem = 0) + So we need special sorting for columns. + 2) when we add new column, LV_COLUMNW::iOrder cannot be larger than already inserted columns) + So we set column order after all columns are added. + */ + newColumns.Sort(ItemProperty_Compare_NameFirst, NULL); + + if (newColumns.IsEqualTo(_visibleColumns)) + return S_OK; + + CIntArr columns(newColumns.Size()); + for (i = 0; i < newColumns.Size(); i++) + columns[i] = -1; + + bool orderError = false; + + for (i = 0; i < newColumns.Size(); i++) + { + const CPropColumn &prop = newColumns[i]; + if (prop.Order < (int)newColumns.Size() && columns[prop.Order] == -1) + columns[prop.Order] = (int)i; + else + orderError = true; + } + + for (;;) + { + const unsigned numColumns = _visibleColumns.Size(); + if (numColumns == 0) + break; + DeleteColumn(numColumns - 1); + } + + for (i = 0; i < newColumns.Size(); i++) + AddColumn(newColumns[i]); + + // columns[0], columns[1], .... should be displayed from left to right: + if (!orderError) + _listView.SetColumnOrderArray(_visibleColumns.Size(), columns); + + _needSaveInfo = true; + + return S_OK; +} + + +void CPanel::DeleteColumn(unsigned index) +{ + _visibleColumns.Delete(index); + _listView.DeleteColumn(index); +} + +void CPanel::AddColumn(const CPropColumn &prop) +{ + const unsigned index = _visibleColumns.Size(); + + LV_COLUMNW column; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER; + column.cx = (int)prop.Width; + column.fmt = GetColumnAlign(prop.ID, prop.Type); + column.iOrder = (int)index; // must be <= _listView.ItemCount + column.iSubItem = (int)index; // must be <= _listView.ItemCount + column.pszText = const_cast((const wchar_t *)prop.Name); + + _visibleColumns.Add(prop); + _listView.InsertColumn(index, &column); +} + + +HRESULT CPanel::RefreshListCtrl() +{ + CSelectedState state; + return RefreshListCtrl(state); +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); + + +void CPanel::GetSelectedNames(UStringVector &selectedNames) +{ + CRecordVector indices; + Get_ItemIndices_Selected(indices); + selectedNames.ClearAndReserve(indices.Size()); + FOR_VECTOR (i, indices) + selectedNames.AddInReserved(GetItemRelPath(indices[i])); + + /* + for (int i = 0; i < _listView.GetItemCount(); i++) + { + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = i; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT | LVIF_PARAM; + if (!_listView.GetItem(&item)) + continue; + const unsigned realIndex = GetRealIndex(item); + if (realIndex == kParentIndex) + continue; + if (_selectedStatusVector[realIndex]) + selectedNames.Add(item.pszText); + } + */ + selectedNames.Sort(); +} + +void CPanel::SaveSelectedState(CSelectedState &s) +{ + s.FocusedName_Defined = false; + s.FocusedName.Empty(); + s.SelectFocused = true; // false; + s.SelectedNames.Clear(); + s.FocusedItem = _listView.GetFocusedItem(); + { + if (s.FocusedItem >= 0) + { + const unsigned realIndex = GetRealItemIndex(s.FocusedItem); + if (realIndex != kParentIndex) + { + s.FocusedName = GetItemRelPath(realIndex); + s.FocusedName_Defined = true; + + s.SelectFocused = _listView.IsItemSelected(s.FocusedItem); + + /* + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = focusedItem; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + if (_listView.GetItem(&item)) + focusedName = item.pszText; + */ + } + } + } + GetSelectedNames(s.SelectedNames); +} + +/* +HRESULT CPanel::RefreshListCtrl(const CSelectedState &s) +{ + bool selectFocused = s.SelectFocused; + if (_mySelectMode) + selectFocused = true; + return RefreshListCtrl2( + s.FocusedItem >= 0, // allowEmptyFocusedName + s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames); +} +*/ + +HRESULT CPanel::RefreshListCtrl_SaveFocused(bool onTimer) +{ + CSelectedState state; + SaveSelectedState(state); + state.CalledFromTimer = onTimer; + return RefreshListCtrl(state); +} + +void CPanel::SetFocusedSelectedItem(int index, bool select) +{ + UINT state = LVIS_FOCUSED; + if (select) + state |= LVIS_SELECTED; + _listView.SetItemState(index, state, state); + if (!_mySelectMode && select) + { + const unsigned realIndex = GetRealItemIndex(index); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; + } +} + +// #define PRINT_STAT + +#ifdef PRINT_STAT + void Print_OnNotify(const char *name); +#else + #define Print_OnNotify(x) +#endif + + + +/* + +extern UInt32 g_NumGroups; +extern DWORD g_start_tick; +extern DWORD g_prev_tick; +extern DWORD g_Num_SetItemText; +extern UInt32 g_NumMessages; +*/ + +HRESULT CPanel::RefreshListCtrl(const CSelectedState &state) +{ + m_DropHighlighted_SelectionIndex = -1; + m_DropHighlighted_SubFolderName.Empty(); + + if (!_folder) + return S_OK; + + /* + g_start_tick = GetTickCount(); + g_Num_SetItemText = 0; + g_NumMessages = 0; + */ + + _dontShowMode = false; + if (!state.CalledFromTimer) + LoadFullPathAndShow(); + // OutputDebugStringA("=======\n"); + // OutputDebugStringA("s1 \n"); + CDisableTimerProcessing timerProcessing(*this); + CDisableNotify disableNotify(*this); + + int focusedPos = state.FocusedItem; + if (focusedPos < 0) + focusedPos = 0; + + _listView.SetRedraw(false); + // m_RedrawEnabled = false; + + LVITEMW item; + ZeroMemory(&item, sizeof(item)); + + // DWORD tickCount0 = GetTickCount(); + + // _enableItemChangeNotify = false; + DeleteListItems(); + _enableItemChangeNotify = true; + + int listViewItemCount = 0; + + _selectedStatusVector.Clear(); + // _realIndices.Clear(); + _startGroupSelect = 0; + + _selectionIsDefined = false; + + // m_Files.Clear(); + + /* + if (!_folder) + { + // throw 1; + SetToRootFolder(); + } + */ + + _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); + + { + CMyComPtr folderSetFlatMode; + _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); + if (folderSetFlatMode) + folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); + } + + /* + { + CMyComPtr setShow; + _folder.QueryInterface(IID_IFolderSetShowNtfsStreamsMode, &setShow); + if (setShow) + setShow->SetShowNtfsStreamsMode(BoolToInt(_showNtfsStrems_Mode)); + } + */ + + _isDirVector.Clear(); + // DWORD tickCount1 = GetTickCount(); + IFolderFolder *folder = _folder; + RINOK(_folder->LoadItems()) + // DWORD tickCount2 = GetTickCount(); + // OutputDebugString(TEXT("Start Dir\n")); + RINOK(InitColumns()) + + UInt32 numItems; + _folder->GetNumberOfItems(&numItems); + { + NCOM::CPropVariant prop; + _isDirVector.ClearAndSetSize(numItems); + bool *vec = _isDirVector.NonConstData(); + HRESULT hres = S_OK; + unsigned i; + for (i = 0; i < numItems; i++) + { + hres = folder->GetProperty(i, kpidIsDir, &prop); + if (hres != S_OK) + break; + bool v = false; + if (prop.vt == VT_BOOL) + v = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + break; + vec[i] = v; + } + if (i != numItems) + { + _isDirVector.Clear(); + if (hres == S_OK) + hres = E_FAIL; + } + RINOK(hres) + } + + const bool showDots = _showDots && !IsRootFolder(); + + _listView.SetItemCount(numItems + (showDots ? 1 : 0)); + + _selectedStatusVector.ClearAndReserve(numItems); + int cursorIndex = -1; + + CMyComPtr folderGetSystemIconIndex; +#if 1 // 0 : for debug local icons loading + if (!Is_Slow_Icon_Folder() || _showRealFileIcons) + _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); +#endif + + const bool isFSDrivesFolder = IsFSDrivesFolder(); + const bool isArcFolder = IsArcFolder(); + + if (!IsFSFolder()) + { + CMyComPtr getFolderArcProps; + _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); + _thereAreDeletedItems = false; + if (getFolderArcProps) + { + CMyComPtr arcProps; + getFolderArcProps->GetFolderArcProps(&arcProps); + if (arcProps) + { + UInt32 numLevels; + if (arcProps->GetArcNumLevels(&numLevels) != S_OK) + numLevels = 0; + NCOM::CPropVariant prop; + if (arcProps->GetArcProp(numLevels - 1, kpidIsDeleted, &prop) == S_OK) + if (prop.vt == VT_BOOL && VARIANT_BOOLToBool(prop.boolVal)) + _thereAreDeletedItems = true; + } + } + } + + _thereAre_ListView_Items = true; + + // OutputDebugStringA("\n\n"); + + Print_OnNotify("===== Before Load"); + + // #define USE_EMBED_ITEM + + if (showDots) + { + const UString itemName (".."); + item.iItem = listViewItemCount; + if (itemName == state.FocusedName) + cursorIndex = listViewItemCount; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + int subItem = 0; + item.iSubItem = subItem++; + item.lParam = (LPARAM)(int)kParentIndex; + #ifdef USE_EMBED_ITEM + item.pszText = const_cast((const wchar_t *)itemName); + #else + item.pszText = LPSTR_TEXTCALLBACKW; + #endif + // const UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY; + item.iImage = g_Ext_to_Icon_Map.GetIconIndex_DIR(); + // g_Ext_to_Icon_Map.GetIconIndex(attrib, itemName); + if (item.iImage < 0) + item.iImage = 0; + if (_listView.InsertItem(&item) == -1) + return E_FAIL; + listViewItemCount++; + } + + // OutputDebugStringA("S1\n"); + + UString correctedName; + UString itemName; + UString relPath; + + for (UInt32 i = 0; i < numItems; i++) + { + const wchar_t *name = NULL; + unsigned nameLen = 0; + + if (_folderGetItemName) + _folderGetItemName->GetItemName(i, &name, &nameLen); + if (!name) + { + GetItemName(i, itemName); + name = itemName; + nameLen = itemName.Len(); + } + + bool selected = false; + + if (state.FocusedName_Defined || !state.SelectedNames.IsEmpty()) + { + relPath.Empty(); + // relPath += GetItemPrefix(i); + if (_flatMode) + { + const wchar_t *prefix = NULL; + if (_folderGetItemName) + { + unsigned prefixLen = 0; + _folderGetItemName->GetItemPrefix(i, &prefix, &prefixLen); + if (prefix) + relPath = prefix; + } + if (!prefix) + { + NCOM::CPropVariant prop; + if (_folder->GetProperty(i, kpidPrefix, &prop) != S_OK) + throw 2723400; + if (prop.vt == VT_BSTR) + relPath.SetFromBstr(prop.bstrVal); + } + } + relPath += name; + if (relPath == state.FocusedName) + cursorIndex = listViewItemCount; + if (state.SelectedNames.FindInSorted(relPath) != -1) + selected = true; + } + + _selectedStatusVector.AddInReserved(selected); + + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + + if (!_mySelectMode) + if (selected) + { + item.mask |= LVIF_STATE; + item.state = LVIS_SELECTED; + } + + int subItem = 0; + item.iItem = listViewItemCount; + + item.iSubItem = subItem++; + item.lParam = (LPARAM)i; + + /* + int finish = nameLen - 4; + int j; + for (j = 0; j < finish; j++) + { + if (name[j ] == ' ' && + name[j + 1] == ' ' && + name[j + 2] == ' ' && + name[j + 3] == ' ' && + name[j + 4] == ' ') + break; + } + if (j < finish) + { + correctedName.Empty(); + correctedName = "virus"; + int pos = 0; + for (;;) + { + int posNew = itemName.Find(L" ", pos); + if (posNew < 0) + { + correctedName += itemName.Ptr(pos); + break; + } + correctedName += itemName.Mid(pos, posNew - pos); + correctedName += " ... "; + pos = posNew; + while (itemName[++pos] == ' '); + } + item.pszText = const_cast((const wchar_t *)correctedName); + } + else + */ + { + #ifdef USE_EMBED_ITEM + item.pszText = const_cast((const wchar_t *)name); + #else + item.pszText = LPSTR_TEXTCALLBACKW; + #endif + /* LPSTR_TEXTCALLBACKW works, but in some cases there are problems, + since we block notify handler. + LPSTR_TEXTCALLBACKW can be 2-3 times faster for loading in this loop. */ + } + + bool defined = false; + item.iImage = -1; + + if (folderGetSystemIconIndex) + { + const HRESULT res = folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); + if (res == S_OK) + { + // item.iImage = -1; // for debug + defined = (item.iImage > 0); +#if 0 // 0: can be slower: 2 attempts for some paths. + // 1: faster, but we can get default icon for some cases (where non default icon is possible) + + if (item.iImage == 0) + { + // (item.iImage == 0) means default icon. + // But (item.iImage == 0) also can be returned for exe/ico files, + // if filePath is LONG PATH (path_len() >= MAX_PATH). + // Also we want to show split icon (.001) for any split extension: 001 002 003. + // Are there another cases for (item.iImage == 0) for files with known extensions? + // We don't want to do second attempt to request icon, + // if it also will return (item.iImage == 0). + + int dotPos = -1; + for (unsigned k = 0;; k++) + { + const wchar_t c = name[k]; + if (c == 0) + break; + if (c == '.') + dotPos = (int)i; + // we don't need IS_PATH_SEPAR check, because we have only (fileName) doesn't include path prefix. + // if (IS_PATH_SEPAR(c) || c == ':') dotPos = -1; + } + defined = true; + if (dotPos >= 0) + { +#if 0 + const wchar_t *ext = name + dotPos; + if (StringsAreEqualNoCase_Ascii(ext, ".exe") || + StringsAreEqualNoCase_Ascii(ext, ".ico")) +#endif + defined = false; + } + } +#endif + } + } + + if (!defined) + { + UInt32 attrib = 0; + { + NCOM::CPropVariant prop; + RINOK(_folder->GetProperty(i, kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + { + attrib = prop.ulVal; + if (isArcFolder) + { + // if attrib (high 16-bits) is supposed from posix, + // we keep only low bits (basic Windows attrib flags): + if (attrib & 0xF0000000) + attrib &= 0x3FFF; + } + } + } + if (IsItem_Folder(i)) + attrib |= FILE_ATTRIBUTE_DIRECTORY; + else + attrib &= ~(UInt32)FILE_ATTRIBUTE_DIRECTORY; + + item.iImage = -1; + if (isFSDrivesFolder) + { + FString fs (us2fs((UString)name)); + fs.Add_PathSepar(); + item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(fs, attrib); + // item.iImage = 0; // for debug + } + if (item.iImage < 0) // <= 0 check? + item.iImage = g_Ext_to_Icon_Map.GetIconIndex(attrib, name); + } + + // item.iImage = -1; // for debug + if (item.iImage < 0) + item.iImage = 0; // default image + if (_listView.InsertItem(&item) == -1) + return E_FAIL; + listViewItemCount++; + } + + /* + xp-64: there is different order when Windows calls CPanel::OnNotify for _listView modes: + Details : after whole code + List : 2 times: + 1) - ListView.SotRedraw() + 2) - after whole code + Small Icons : + Large icons : 2 times: + 1) - ListView.Sort() + 2) - after whole code (calls with reverse order of items) + + So we need to allow Notify(), when windows requests names during the following code. + */ + + Print_OnNotify("after Load"); + + disableNotify.SetMemMode_Enable(); + disableNotify.Restore(); + + if (_listView.GetItemCount() > 0 && cursorIndex >= 0) + SetFocusedSelectedItem(cursorIndex, state.SelectFocused); + + Print_OnNotify("after SetFocusedSelectedItem"); + + SetSortRawStatus(); + _listView.SortItems(CompareItems, (LPARAM)this); + + Print_OnNotify("after Sort"); + + if (cursorIndex < 0 && _listView.GetItemCount() > 0) + { + if (focusedPos >= _listView.GetItemCount()) + focusedPos = _listView.GetItemCount() - 1; + // we select item only in showDots mode. + SetFocusedSelectedItem(focusedPos, showDots && (focusedPos == 0)); + } + + // m_RedrawEnabled = true; + + Print_OnNotify("after SetFocusedSelectedItem2"); + + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + + // disableNotify.SetMemMode_Enable(); + // disableNotify.Restore(); + + Print_OnNotify("after EnsureVisible"); + + _listView.SetRedraw(true); + + Print_OnNotify("after SetRedraw"); + + _listView.InvalidateRect(NULL, true); + + Print_OnNotify("after InvalidateRect"); + /* + _listView.UpdateWindow(); + */ + Refresh_StatusBar(); + /* + char s[256]; + sprintf(s, + // "attribMap = %5d, extMap = %5d, " + "delete = %5d, load = %5d, list = %5d, sort = %5d, end = %5d", + // g_Ext_to_Icon_Map._attribMap.Size(), + // g_Ext_to_Icon_Map._extMap.Size(), + tickCount1 - tickCount0, + tickCount2 - tickCount1, + tickCount3 - tickCount2, + tickCount4 - tickCount3, + tickCount5 - tickCount4 + ); + sprintf(s, + "5 = %5d, 6 = %5d, 7 = %5d, 8 = %5d, 9 = %5d", + tickCount5 - tickCount4, + tickCount6 - tickCount5, + tickCount7 - tickCount6, + tickCount8 - tickCount7, + tickCount9 - tickCount8 + ); + OutputDebugStringA(s); + */ + return S_OK; +} + + +void CPanel::Get_ItemIndices_Selected(CRecordVector &indices) const +{ + indices.Clear(); + /* + int itemIndex = -1; + while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1) + { + LPARAM param; + if (_listView.GetItemParam(itemIndex, param)) + indices.Add(param); + } + HeapSort(&indices.Front(), indices.Size()); + */ + const bool *v = _selectedStatusVector.ConstData(); + const unsigned size = _selectedStatusVector.Size(); + for (unsigned i = 0; i < size; i++) + if (v[i]) + indices.Add(i); +} + + +void CPanel::Get_ItemIndices_Operated(CRecordVector &indices) const +{ + Get_ItemIndices_Selected(indices); + if (!indices.IsEmpty()) + return; + if (_listView.GetSelectedCount() == 0) + return; + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + if (_listView.IsItemSelected(focusedItem)) + { + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + indices.Add(realIndex); + } + } +} + +void CPanel::Get_ItemIndices_All(CRecordVector &indices) const +{ + indices.Clear(); + UInt32 numItems; + if (_folder->GetNumberOfItems(&numItems) != S_OK) + return; + indices.ClearAndSetSize(numItems); + UInt32 *vec = indices.NonConstData(); + for (UInt32 i = 0; i < numItems; i++) + vec[i] = i; +} + +void CPanel::Get_ItemIndices_OperSmart(CRecordVector &indices) const +{ + Get_ItemIndices_Operated(indices); + if (indices.IsEmpty() || (indices.Size() == 1 && indices[0] == (UInt32)(Int32)-1)) + Get_ItemIndices_All(indices); +} + +/* +void CPanel::GetOperatedListViewIndices(CRecordVector &indices) const +{ + indices.Clear(); + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + const unsigned realIndex = GetRealItemIndex(i); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + indices.Add(i); + } + if (indices.IsEmpty()) + { + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + indices.Add(focusedItem); + } +} +*/ + +void CPanel::EditItem(bool useEditor) +{ + if (!useEditor) + { + CMyComPtr calcItemFullSize; + _folder.QueryInterface(IID_IFolderCalcItemFullSize, &calcItemFullSize); + if (calcItemFullSize) + { + bool needRefresh = false; + CRecordVector indices; + Get_ItemIndices_Operated(indices); + FOR_VECTOR (i, indices) + { + UInt32 index = indices[i]; + if (IsItem_Folder(index)) + { + calcItemFullSize->CalcItemFullSize(index, NULL); + needRefresh = true; + } + } + if (needRefresh) + { + // _listView.RedrawItem(0); + // _listView.RedrawAllItems(); + InvalidateList(); + return; + } + } + } + + + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + if (!IsItem_Folder(realIndex)) + EditItem(realIndex, useEditor); +} + +void CPanel::OpenFocusedItemAsInternal(const wchar_t *type) +{ + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (IsItem_Folder(realIndex)) + OpenFolder(realIndex); + else + OpenItem(realIndex, true, false, type); +} + +void CPanel::OpenSelectedItems(bool tryInternal) +{ + CRecordVector indices; + Get_ItemIndices_Operated(indices); + if (indices.Size() > 20) + { + MessageBox_Error_LangID(IDS_TOO_MANY_ITEMS); + return; + } + + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0) && _listView.IsItemSelected(focusedItem)) + indices.Insert(0, realIndex); + } + + bool dirIsStarted = false; + FOR_VECTOR (i, indices) + { + UInt32 index = indices[i]; + // CFileInfo &aFile = m_Files[index]; + if (IsItem_Folder(index)) + { + if (!dirIsStarted) + { + if (tryInternal) + { + OpenFolder(index); + dirIsStarted = true; + break; + } + else + OpenFolderExternal(index); + } + } + else + OpenItem(index, (tryInternal && indices.Size() == 1), true); + } +} + +UString CPanel::GetItemName(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return L".."; + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) + throw 2723400; + if (prop.vt != VT_BSTR) + throw 2723401; + return prop.bstrVal; +} + +UString CPanel::GetItemName_for_Copy(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return L".."; + UString s; + { + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidOutName, &prop) == S_OK) + { + if (prop.vt == VT_BSTR) + s = prop.bstrVal; + else if (prop.vt != VT_EMPTY) + throw 2723401; + } + if (s.IsEmpty()) + s = GetItemName(itemIndex); + } + return Get_Correct_FsFile_Name(s); +} + +void CPanel::GetItemName(unsigned itemIndex, UString &s) const +{ + if (itemIndex == kParentIndex) + { + s = ".."; + return; + } + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) + throw 2723400; + if (prop.vt != VT_BSTR) + throw 2723401; + s.SetFromBstr(prop.bstrVal); +} + +UString CPanel::GetItemPrefix(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return UString(); + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidPrefix, &prop) != S_OK) + throw 2723400; + UString prefix; + if (prop.vt == VT_BSTR) + prefix.SetFromBstr(prop.bstrVal); + return prefix; +} + +UString CPanel::GetItemRelPath(unsigned itemIndex) const +{ + return GetItemPrefix(itemIndex) + GetItemName(itemIndex); +} + +UString CPanel::GetItemRelPath2(unsigned itemIndex) const +{ + UString s = GetItemRelPath(itemIndex); + #if defined(_WIN32) && !defined(UNDER_CE) + if (s.Len() == 2 && NFile::NName::IsDrivePath2(s)) + { + if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()) + s.Add_PathSepar(); + } + #endif + return s; +} + + +void CPanel::Add_ItemRelPath2_To_String(unsigned itemIndex, UString &s) const +{ + if (itemIndex == kParentIndex) + { + s += ".."; + return; + } + + const unsigned start = s.Len(); + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, kpidPrefix, &prop) != S_OK) + throw 2723400; + if (prop.vt == VT_BSTR) + s += prop.bstrVal; + + const wchar_t *name = NULL; + unsigned nameLen = 0; + + if (_folderGetItemName) + _folderGetItemName->GetItemName(itemIndex, &name, &nameLen); + if (name) + s += name; + else + { + prop.Clear(); + if (_folder->GetProperty(itemIndex, kpidName, &prop) != S_OK) + throw 2723400; + if (prop.vt != VT_BSTR) + throw 2723401; + s += prop.bstrVal; + } + + #if defined(_WIN32) && !defined(UNDER_CE) + if (s.Len() - start == 2 && NFile::NName::IsDrivePath2(s.Ptr(start))) + { + if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()) + s.Add_PathSepar(); + } + #endif +} + + +UString CPanel::GetItemFullPath(unsigned itemIndex) const +{ + return GetFsPath() + GetItemRelPath2(itemIndex); +} + +bool CPanel::GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const +{ + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, propID, &prop) != S_OK) + throw 2723400; + if (prop.vt == VT_BOOL) + return VARIANT_BOOLToBool(prop.boolVal); + if (prop.vt == VT_EMPTY) + return false; + throw 2723401; +} + +bool CPanel::IsItem_Deleted(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return false; + return GetItem_BoolProp(itemIndex, kpidIsDeleted); +} + +bool CPanel::IsItem_Folder(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return true; + if (itemIndex < _isDirVector.Size()) + return _isDirVector[itemIndex]; + return GetItem_BoolProp(itemIndex, kpidIsDir); +} + +bool CPanel::IsItem_AltStream(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return false; + return GetItem_BoolProp(itemIndex, kpidIsAltStream); +} + +UInt64 CPanel::GetItem_UInt64Prop(unsigned itemIndex, PROPID propID) const +{ + if (itemIndex == kParentIndex) + return 0; + NCOM::CPropVariant prop; + if (_folder->GetProperty(itemIndex, propID, &prop) != S_OK) + throw 2723400; + UInt64 val = 0; + if (ConvertPropVariantToUInt64(prop, val)) + return val; + return 0; +} + +UInt64 CPanel::GetItemSize(unsigned itemIndex) const +{ + if (itemIndex == kParentIndex) + return 0; + if (_folderGetItemName) + return _folderGetItemName->GetItemSize(itemIndex); + return GetItem_UInt64Prop(itemIndex, kpidSize); +} + +void CPanel::SaveListViewInfo() +{ + if (!_needSaveInfo) + return; + + unsigned i; + + for (i = 0; i < _visibleColumns.Size(); i++) + { + CPropColumn &prop = _visibleColumns[i]; + LVCOLUMN winColumnInfo; + winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH; + if (!_listView.GetColumn(i, &winColumnInfo)) + throw 1; + prop.Order = winColumnInfo.iOrder; + prop.Width = (UInt32)(Int32)winColumnInfo.cx; + } + + CListViewInfo viewInfo; + + // PROPID sortPropID = _columns[_sortIndex].ID; + const PROPID sortPropID = _sortID; + + // we save columns as "sorted by order" to registry + + CPropColumns sortedProperties = _visibleColumns; + + sortedProperties.Sort(); + + for (i = 0; i < sortedProperties.Size(); i++) + { + const CPropColumn &prop = sortedProperties[i]; + CColumnInfo columnInfo; + columnInfo.IsVisible = prop.IsVisible; + columnInfo.PropID = prop.ID; + columnInfo.Width = prop.Width; + viewInfo.Columns.Add(columnInfo); + } + + for (i = 0; i < _columns.Size(); i++) + { + const CPropColumn &prop = _columns[i]; + if (sortedProperties.FindItem_for_PropID(prop.ID) < 0) + { + CColumnInfo columnInfo; + columnInfo.IsVisible = false; + columnInfo.PropID = prop.ID; + columnInfo.Width = prop.Width; + viewInfo.Columns.Add(columnInfo); + } + } + + viewInfo.SortID = sortPropID; + viewInfo.Ascending = _ascending; + viewInfo.IsLoaded = true; + if (!_listViewInfo.IsEqual(viewInfo)) + { + viewInfo.Save(_typeIDString); + _listViewInfo = viewInfo; + } +} + + +bool CPanel::OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result) +{ + if (itemActivate->hdr.hwndFrom == HWND(_listView)) + return false; + POINT point; + ::GetCursorPos(&point); + ShowColumnsContextMenu(point.x, point.y); + result = TRUE; + return true; +} + +void CPanel::ShowColumnsContextMenu(int x, int y) +{ + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + + menu.CreatePopup(); + + const int kCommandStart = 100; + FOR_VECTOR (i, _columns) + { + const CPropColumn &prop = _columns[i]; + UINT flags = MF_STRING; + if (prop.IsVisible) + flags |= MF_CHECKED; + if (i == 0) + flags |= MF_GRAYED; + menu.AppendItem(flags, kCommandStart + i, prop.Name); + } + + const int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, x, y, _listView); + + if (menuResult >= kCommandStart && menuResult <= kCommandStart + (int)_columns.Size()) + { + const unsigned index = (unsigned)(menuResult - kCommandStart); + CPropColumn &prop = _columns[index]; + prop.IsVisible = !prop.IsVisible; + + if (prop.IsVisible) + { + prop.Order = (int)_visibleColumns.Size(); + AddColumn(prop); + } + else + { + const int visibleIndex = _visibleColumns.FindItem_for_PropID(prop.ID); + if (visibleIndex >= 0) + { + /* + if (_sortIndex == index) + { + _sortIndex = 0; + _ascending = true; + } + */ + if (_sortID == prop.ID) + { + _sortID = kpidName; + _ascending = true; + } + DeleteColumn((unsigned)visibleIndex); + } + } + } +} + +void CPanel::OnReload(bool onTimer) +{ + const HRESULT res = RefreshListCtrl_SaveFocused(onTimer); + if (res != S_OK) + MessageBox_Error_HRESULT(res); +} + +void CPanel::OnTimer() +{ + if (!_processTimer) + return; + if (!AutoRefresh_Mode) + return; + if (!_folder) // it's unexpected case, but we use it as additional protection. + return; + { + CMyComPtr folderWasChanged; + _folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged); + if (!folderWasChanged) + return; + Int32 wasChanged; + if (folderWasChanged->WasChanged(&wasChanged) != S_OK || wasChanged == 0) + return; + } + OnReload(true); // onTimer +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelKey.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelKey.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelKey.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelKey.cpp 2023-03-20 12:00:00.000000000 +0000 @@ -0,0 +1,357 @@ +// PanelKey.cpp + +#include "StdAfx.h" + +#include "Panel.h" +#include "HelpUtils.h" + +#include "../../PropID.h" +#include "App.h" + +using namespace NWindows; + +// #define kHelpTopic "FM/index.htm" + +struct CVKeyPropIDPair +{ + WORD VKey; + PROPID PropID; +}; + +static const CVKeyPropIDPair g_VKeyPropIDPairs[] = +{ + { VK_F3, kpidName }, + { VK_F4, kpidExtension }, + { VK_F5, kpidMTime }, + { VK_F6, kpidSize }, + { VK_F7, kpidNoProperty } +}; + +static int FindVKeyPropIDPair(WORD vKey) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_VKeyPropIDPairs); i++) + if (g_VKeyPropIDPairs[i].VKey == vKey) + return (int)i; + return -1; +} + + +bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) +{ + if (keyDownInfo->wVKey == VK_TAB && keyDownInfo->hdr.hwndFrom == _listView) + { + _panelCallback->OnTab(); + return false; + } + const bool alt = IsKeyDown(VK_MENU); + const bool ctrl = IsKeyDown(VK_CONTROL); + // const bool leftCtrl = IsKeyDown(VK_LCONTROL); + const bool rightCtrl = IsKeyDown(VK_RCONTROL); + const bool shift = IsKeyDown(VK_SHIFT); + result = 0; + + if (keyDownInfo->wVKey >= '0' && + keyDownInfo->wVKey <= '9' && + (rightCtrl || alt)) + { + const unsigned index = (unsigned)(keyDownInfo->wVKey - '0'); + if (shift) + { + SetBookmark(index); + return true; + } + else + { + OpenBookmark(index); + return true; + } + } + + if ((keyDownInfo->wVKey == VK_F2 || + keyDownInfo->wVKey == VK_F1) + && alt && !ctrl && !shift) + { + _panelCallback->SetFocusToPath(keyDownInfo->wVKey == VK_F1 ? 0 : 1); + return true; + } + + if ((keyDownInfo->wVKey == VK_F9) && !alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel(); + } + + if (keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl) + { + const int index = FindVKeyPropIDPair(keyDownInfo->wVKey); + if (index >= 0) + SortItemsWithPropID(g_VKeyPropIDPairs[index].PropID); + } + + switch (keyDownInfo->wVKey) + { + case VK_SHIFT: + { + _selectionIsDefined = false; + _prevFocusedItem = _listView.GetFocusedItem(); + break; + } + /* + case VK_F1: + { + // ShowHelpWindow(NULL, kHelpTopic); + break; + } + */ + case VK_F2: + { + if (!alt && !ctrl &&!shift) + { + RenameFile(); + return true; + } + break; + } + case VK_F3: + { + if (!alt && !ctrl && !shift) + { + EditItem(false); + return true; + } + break; + } + case VK_F4: + { + if (!alt && !ctrl && !shift) + { + EditItem(true); + return true; + } + if (!alt && !ctrl && shift) + { + CreateFile(); + return true; + } + break; + } + case VK_F5: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(false, shift); + return true; + } + break; + } + case VK_F6: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(true, shift); + return true; + } + break; + } + case VK_F7: + { + if (!alt && !ctrl && !shift) + { + /* we can process F7 via menu ACCELERATOR. + But menu loading can be slow in case of UNC paths and system menu. + So we use don't use ACCELERATOR */ + CreateFolder(); + return true; + } + break; + } + case VK_DELETE: + { + DeleteItems(!shift); + return true; + } + case VK_INSERT: + { + if (!alt) + { + if (ctrl && !shift) + { + EditCopy(); + return true; + } + if (shift && !ctrl) + { + EditPaste(); + return true; + } + if (!shift && !ctrl && _mySelectMode) + { + OnInsert(); + return true; + } + } + return false; + } + case VK_DOWN: + { + if (shift) + OnArrowWithShift(); + return false; + } + case VK_UP: + { + if (alt) + _panelCallback->OnSetSameFolder(); + else if (shift) + OnArrowWithShift(); + return false; + } + case VK_RIGHT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if (shift) + OnArrowWithShift(); + return false; + } + case VK_LEFT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if (shift) + OnArrowWithShift(); + return false; + } + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + // EnterToFocused(); + return true; + } + break; + } + case VK_ADD: + { + if (alt) + SelectByType(true); + else if (shift) + SelectAll(true); + else if (!ctrl) + SelectSpec(true); + return true; + } + case VK_SUBTRACT: + { + if (alt) + SelectByType(false); + else if (shift) + SelectAll(false); + else + SelectSpec(false); + return true; + } + /* + case VK_DELETE: + CommandDelete(); + return 0; + case VK_F1: + CommandHelp(); + return 0; + */ + case VK_BACK: + OpenParentFolder(); + return true; + /* + case VK_DIVIDE: + case '\\': + case '/': + case VK_OEM_5: + { + // OpenRootFolder(); + OpenDrivesFolder(); + + return true; + } + */ + case 'A': + if (ctrl) + { + SelectAll(true); + return true; + } + return false; + case 'X': + if (ctrl) + { + EditCut(); + return true; + } + return false; + case 'C': + if (ctrl) + { + EditCopy(); + return true; + } + return false; + case 'V': + if (ctrl) + { + EditPaste(); + return true; + } + return false; + case 'N': + if (ctrl) + { + CreateFile(); + return true; + } + return false; + case 'R': + if (ctrl) + { + OnReload(); + return true; + } + return false; + case 'W': + if (ctrl) + { + // SendMessage(); + PostMessage(g_HWND, WM_COMMAND, IDCLOSE, 0); + return true; + } + return false; + case 'Z': + if (ctrl) + { + ChangeComment(); + return true; + } + return false; + case '1': + case '2': + case '3': + case '4': + if (ctrl) + { + const unsigned styleIndex = (unsigned)(keyDownInfo->wVKey - '1'); + SetListViewMode(styleIndex); + return true; + } + return false; + case VK_MULTIPLY: + { + InvertSelection(); + return true; + } + case VK_F12: + if (alt && !ctrl && !shift) + { + FoldersHistory(); + return true; + } + } + return false; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelListNotify.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelListNotify.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelListNotify.cpp 2015-10-09 09:05:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelListNotify.cpp 2024-10-04 17:00:00.000000000 +0000 @@ -1,756 +1,838 @@ -// PanelListNotify.cpp - -#include "StdAfx.h" - -#include "resource.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../Common/PropIDUtils.h" -#include "../../PropID.h" - -#include "App.h" -#include "Panel.h" -#include "FormatUtils.h" - -using namespace NWindows; - -#define INT_TO_STR_SPEC(v) \ - while (v >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(v % 10)); v /= 10; } \ - *s++ = (unsigned char)('0' + (unsigned)v); - -static void ConvertSizeToString(UInt64 val, wchar_t *s) throw() -{ - unsigned char temp[32]; - unsigned i = 0; - - if (val <= (UInt32)0xFFFFFFFF) - { - UInt32 val32 = (UInt32)val; - INT_TO_STR_SPEC(val32) - } - else - { - INT_TO_STR_SPEC(val) - } - - if (i < 3) - { - if (i != 0) - { - *s++ = temp[i - 1]; - if (i == 2) - *s++ = temp[0]; - } - *s = 0; - return; - } - - unsigned r = i % 3; - if (r != 0) - { - s[0] = temp[--i]; - if (r == 2) - s[1] = temp[--i]; - s += r; - } - - do - { - s[0] = ' '; - s[1] = temp[i - 1]; - s[2] = temp[i - 2]; - s[3] = temp[i - 3]; - s += 4; - } - while (i -= 3); - - *s = 0; -} - -UString ConvertSizeToString(UInt64 value) -{ - wchar_t s[32]; - ConvertSizeToString(value, s); - return s; -} - -static inline unsigned GetHex(unsigned v) -{ - return (v < 10) ? ('0' + v) : ('A' + (v - 10)); -} - -/* -static void HexToString(char *dest, const Byte *data, UInt32 size) -{ - for (UInt32 i = 0; i < size; i++) - { - unsigned b = data[i]; - dest[0] = GetHex((b >> 4) & 0xF); - dest[1] = GetHex(b & 0xF); - dest += 2; - } - *dest = 0; -} -*/ - -bool IsSizeProp(UINT propID) throw() -{ - switch (propID) - { - case kpidSize: - case kpidPackSize: - case kpidNumSubDirs: - case kpidNumSubFiles: - case kpidOffset: - case kpidLinks: - case kpidNumBlocks: - case kpidNumVolumes: - case kpidPhySize: - case kpidHeadersSize: - case kpidTotalSize: - case kpidFreeSpace: - case kpidClusterSize: - case kpidNumErrors: - case kpidNumStreams: - case kpidNumAltStreams: - case kpidAltStreamsSize: - case kpidVirtualSize: - case kpidUnpackSize: - case kpidTotalPhySize: - case kpidTailSize: - case kpidEmbeddedStubSize: - return true; - } - return false; -} - -LRESULT CPanel::SetItemText(LVITEMW &item) -{ - if (_dontShowMode) - return 0; - UInt32 realIndex = GetRealIndex(item); - - /* - if ((item.mask & LVIF_IMAGE) != 0) - { - bool defined = false; - CComPtr folderGetSystemIconIndex; - _folder.QueryInterface(&folderGetSystemIconIndex); - if (folderGetSystemIconIndex) - { - folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage); - defined = (item.iImage > 0); - } - if (!defined) - { - NCOM::CPropVariant prop; - _folder->GetProperty(index, kpidAttrib, &prop); - UINT32 attrib = 0; - if (prop.vt == VT_UI4) - attrib = prop.ulVal; - else if (IsItemFolder(index)) - attrib |= FILE_ATTRIBUTE_DIRECTORY; - if (_currentFolderPrefix.IsEmpty()) - throw 1; - else - item.iImage = _extToIconMap.GetIconIndex(attrib, GetSystemString(GetItemName(index))); - } - // item.iImage = 1; - } - */ - - if ((item.mask & LVIF_TEXT) == 0) - return 0; - - LPWSTR text = item.pszText; - - if (item.cchTextMax > 0) - text[0] = 0; - - if (item.cchTextMax <= 1) - return 0; - - const CItemProperty &property = _visibleProperties[item.iSubItem]; - PROPID propID = property.ID; - - if (realIndex == kParentIndex) - { - if (propID == kpidName) - { - if (item.cchTextMax > 2) - { - text[0] = '.'; - text[1] = '.'; - text[2] = 0; - } - } - return 0; - } - - - if (property.IsRawProp) - { - const void *data; - UInt32 dataSize; - UInt32 propType; - RINOK(_folderRawProps->GetRawProp(realIndex, propID, &data, &dataSize, &propType)); - unsigned limit = item.cchTextMax - 1; - if (dataSize == 0) - { - text[0] = 0; - return 0; - } - -#ifdef _WIN32 - if (propID == kpidNtReparse) - { - UString s; - ConvertNtReparseToString((const Byte *)data, dataSize, s); - if (!s.IsEmpty()) - { - unsigned i; - for (i = 0; i < limit; i++) - { - wchar_t c = s[i]; - if (c == 0) - break; - text[i] = c; - } - text[i] = 0; - return 0; - } - } -#endif - else if (propID == kpidNtSecure) - { - AString s; - ConvertNtSecureToString((const Byte *)data, dataSize, s); - if (!s.IsEmpty()) - { - unsigned i; - for (i = 0; i < limit; i++) - { - wchar_t c = (Byte)s[i]; - if (c == 0) - break; - text[i] = c; - } - text[i] = 0; - return 0; - } - } - { - const unsigned kMaxDataSize = 64; - if (dataSize > kMaxDataSize) - { - char temp[32]; - MyStringCopy(temp, "data:"); - ConvertUInt32ToString(dataSize, temp + 5); - unsigned i; - for (i = 0; i < limit; i++) - { - wchar_t c = (Byte)temp[i]; - if (c == 0) - break; - text[i] = c; - } - text[i] = 0; - } - else - { - if (dataSize > limit) - dataSize = limit; - WCHAR *dest = text; - for (UInt32 i = 0; i < dataSize; i++) - { - unsigned b = ((const Byte *)data)[i]; - dest[0] = (WCHAR)GetHex((b >> 4) & 0xF); - dest[1] = (WCHAR)GetHex(b & 0xF); - dest += 2; - } - *dest = 0; - } - } - return 0; - } - /* - { - NCOM::CPropVariant prop; - if (propID == kpidType) - string = GetFileType(index); - else - { - HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &prop); - if (result != S_OK) - { - // PrintMessage("GetPropertyValue error"); - return 0; - } - string = ConvertPropertyToString(prop, propID, false); - } - } - */ - // const NFind::CFileInfo &aFileInfo = m_Files[index]; - - NCOM::CPropVariant prop; - /* - bool needRead = true; - if (propID == kpidSize) - { - CComPtr getItemFullSize; - if (_folder.QueryInterface(&getItemFullSize) == S_OK) - { - if (getItemFullSize->GetItemFullSize(index, &prop) == S_OK) - needRead = false; - } - } - if (needRead) - */ - - if (item.cchTextMax < 32) - return 0; - - if (propID == kpidName) - { - if (_folderGetItemName) - { - const wchar_t *name = NULL; - unsigned nameLen = 0; - _folderGetItemName->GetItemName(realIndex, &name, &nameLen); - - if (name) - { - unsigned dest = 0; - unsigned limit = item.cchTextMax - 1; - - for (unsigned i = 0; dest < limit;) - { - wchar_t c = name[i++]; - if (c == 0) - break; - text[dest++] = c; - - if (c != ' ') - { - if (c != 0x202E) // RLO - continue; - text[dest - 1] = '_'; - continue; - } - - if (name[i + 1] != ' ') - continue; - - unsigned t = 2; - for (; name[i + t] == ' '; t++); - - if (t >= 4 && dest + 4 <= limit) - { - text[dest++] = '.'; - text[dest++] = '.'; - text[dest++] = '.'; - text[dest++] = ' '; - i += t; - } - } - - text[dest] = 0; - return 0; - } - } - } - - if (propID == kpidPrefix) - { - if (_folderGetItemName) - { - const wchar_t *name = NULL; - unsigned nameLen = 0; - _folderGetItemName->GetItemPrefix(realIndex, &name, &nameLen); - if (name) - { - unsigned dest = 0; - unsigned limit = item.cchTextMax - 1; - for (unsigned i = 0; dest < limit;) - { - wchar_t c = name[i++]; - if (c == 0) - break; - text[dest++] = c; - } - text[dest] = 0; - return 0; - } - } - } - - HRESULT res = _folder->GetProperty(realIndex, propID, &prop); - - if (res != S_OK) - { - MyStringCopy(text, L"Error: "); - // s = UString(L"Error: ") + HResultToMessage(res); - } - else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID)) - { - UInt64 v = 0; - ConvertPropVariantToUInt64(prop, v); - ConvertSizeToString(v, text); - } - else if (prop.vt == VT_BSTR) - { - unsigned limit = item.cchTextMax - 1; - const wchar_t *src = prop.bstrVal; - unsigned i; - for (i = 0; i < limit; i++) - { - wchar_t c = src[i]; - if (c == 0) break; - if (c == 0xA) c = ' '; - if (c == 0xD) c = ' '; - text[i] = c; - } - text[i] = 0; - } - else - { - char temp[64]; - ConvertPropertyToShortString(temp, prop, propID, false); - unsigned i; - unsigned limit = item.cchTextMax - 1; - for (i = 0; i < limit; i++) - { - wchar_t c = (Byte)temp[i]; - if (c == 0) - break; - text[i] = c; - } - text[i] = 0; - } - - return 0; -} - -#ifndef UNDER_CE -extern DWORD g_ComCtl32Version; -#endif - -void CPanel::OnItemChanged(NMLISTVIEW *item) -{ - int index = (int)item->lParam; - if (index == kParentIndex) - return; - bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0; - bool newSelected = (item->uNewState & LVIS_SELECTED) != 0; - // Don't change this code. It works only with such check - if (oldSelected != newSelected) - { - printf("CPanel::OnItemChanged : _selectedStatusVector[%d]= %d %d => %d\n",index,_selectedStatusVector[index],oldSelected,newSelected); - _selectedStatusVector[index] = newSelected; - } -} - -extern bool g_LVN_ITEMACTIVATE_Support; - -void CPanel::OnNotifyActivateItems() -{ -#ifdef _WIN32 - bool alt = IsKeyDown(VK_MENU); - bool ctrl = IsKeyDown(VK_CONTROL); - bool shift = IsKeyDown(VK_SHIFT); - if (!shift && alt && !ctrl) - Properties(); - else - OpenSelectedItems(!shift || alt || ctrl); -#else - OpenSelectedItems(true); -#endif -} - -bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) -{ - switch (header->code) - { - case LVN_ITEMCHANGED: - { - if (_enableItemChangeNotify) - { - if (!_mySelectMode) - OnItemChanged((LPNMLISTVIEW)header); - - // Post_Refresh_StatusBar(); - /* 9.26: we don't call Post_Refresh_StatusBar. - it was very slow if we select big number of files - and then clead slection by selecting just new file. - probably it called slow Refresh_StatusBar for each item deselection. - I hope Refresh_StatusBar still will be called for each key / mouse action. - */ - } - return false; - } - /* - - case LVN_ODSTATECHANGED: - { - break; - } - */ - -#ifdef _WIN32 - case LVN_GETDISPINFOW: - { - LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header; - - //is the sub-item information being requested? - - if ((dispInfo->item.mask & LVIF_TEXT) != 0 || - (dispInfo->item.mask & LVIF_IMAGE) != 0) - SetItemText(dispInfo->item); - return false; - } - case LVN_KEYDOWN: - { - LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); - bool boolResult = OnKeyDown(keyDownInfo, result); - switch (keyDownInfo->wVKey) - { - case VK_CONTROL: - case VK_SHIFT: - case VK_MENU: - break; - default: - Post_Refresh_StatusBar(); - } - return boolResult; - } -#endif - - case LVN_COLUMNCLICK: - OnColumnClick(LPNMLISTVIEW(header)); - return false; - -#ifdef _WIN32 - case LVN_ITEMACTIVATE: - if (g_LVN_ITEMACTIVATE_Support) - { - OnNotifyActivateItems(); - return false; - } - break; -#endif - case NM_DBLCLK: - // FIXME case NM_RETURN: - // FIXME if (!g_LVN_ITEMACTIVATE_Support) - { - OnNotifyActivateItems(); - return false; - } - break; - -#ifdef _WIN32 - case NM_RCLICK: - Post_Refresh_StatusBar(); - break; - - /* - return OnRightClick((LPNMITEMACTIVATE)header, result); - */ - /* - case NM_CLICK: - SendRefreshStatusBarMessage(); - return 0; - - // TODO : Handler default action... - return 0; - case LVN_ITEMCHANGED: - { - NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh; - SelChange(pNMLV); - return TRUE; - } - case NM_SETFOCUS: - return onSetFocus(NULL); - case NM_KILLFOCUS: - return onKillFocus(NULL); - */ - case NM_CLICK: - { - // we need SetFocusToList, if we drag-select items from other panel. - SetFocusToList(); - Post_Refresh_StatusBar(); - if (_mySelectMode) - #ifndef UNDER_CE - if (g_ComCtl32Version >= MAKELONG(71, 4)) - #endif - OnLeftClick((MY_NMLISTVIEW_NMITEMACTIVATE *)header); - return false; - } - case LVN_BEGINLABELEDITW: - result = OnBeginLabelEdit((LV_DISPINFOW *)header); - return true; - case LVN_ENDLABELEDITW: - result = OnEndLabelEdit((LV_DISPINFOW *)header); - return true; - - case NM_CUSTOMDRAW: - { - if (_mySelectMode || (_markDeletedItems && _thereAreDeletedItems)) - return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result); - break; - } - case LVN_BEGINDRAG: - { - OnDrag((LPNMLISTVIEW)header); - Post_Refresh_StatusBar(); - break; - } - // case LVN_BEGINRDRAG: -#endif - } - return false; -} - -#ifdef _WIN32 -bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result) -{ - switch (lplvcd->nmcd.dwDrawStage) - { - case CDDS_PREPAINT : - result = CDRF_NOTIFYITEMDRAW; - return true; - - case CDDS_ITEMPREPAINT: - /* - SelectObject(lplvcd->nmcd.hdc, - GetFontForItem(lplvcd->nmcd.dwItemSpec, - lplvcd->nmcd.lItemlParam) ); - lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec, - lplvcd->nmcd.lItemlParam); - lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec, - lplvcd->nmcd.lItemlParam); - */ - int realIndex = (int)lplvcd->nmcd.lItemlParam; - lplvcd->clrTextBk = _listView.GetBkColor(); - if (_mySelectMode) - { - if (realIndex != kParentIndex && _selectedStatusVector[realIndex]) - lplvcd->clrTextBk = RGB(255, 192, 192); - } - - if (_markDeletedItems && _thereAreDeletedItems) - { - if (IsItem_Deleted(realIndex)) - lplvcd->clrText = RGB(255, 0, 0); - } - // lplvcd->clrText = RGB(0, 0, 0); - // result = CDRF_NEWFONT; - result = CDRF_NOTIFYITEMDRAW; - return true; - - // return false; - // return true; - /* - case CDDS_SUBITEM | CDDS_ITEMPREPAINT: - if (lplvcd->iSubItem == 0) - { - // lplvcd->clrText = RGB(255, 0, 0); - lplvcd->clrTextBk = RGB(192, 192, 192); - } - else - { - lplvcd->clrText = RGB(0, 0, 0); - lplvcd->clrTextBk = RGB(255, 255, 255); - } - return true; - */ - - /* At this point, you can change the background colors for the item - and any subitems and return CDRF_NEWFONT. If the list-view control - is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW - to customize the item's subitems individually */ - } - return false; -} -#endif - -void CPanel::Refresh_StatusBar() -{ -#ifdef _WIN32 - /* - g_name_cnt++; - char s[256]; - sprintf(s, "g_name_cnt = %8d", g_name_cnt); - OutputDebugStringA(s); - */ - // DWORD dw = GetTickCount(); - - CRecordVector indices; - GetOperatedItemIndices(indices); - - wchar_t temp[32]; - ConvertUInt32ToString(indices.Size(), temp); - - // UString s1 = MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, NumberToString(indices.Size())); - // UString s1 = MyFormatNew(IDS_N_SELECTED_ITEMS, NumberToString(indices.Size())); - _statusBar.SetText(0, MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp)); - // _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, NumberToString(indices.Size()))); - - wchar_t selectSizeString[32]; - selectSizeString[0] = 0; - - if (indices.Size() > 0) - { - // for (unsigned ttt = 0; ttt < 1000; ttt++) { - UInt64 totalSize = 0; - FOR_VECTOR (i, indices) - totalSize += GetItemSize(indices[i]); - ConvertSizeToString(totalSize, selectSizeString); - // } - } - _statusBar.SetText(1, selectSizeString); - - int focusedItem = _listView.GetFocusedItem(); - wchar_t sizeString[32]; - sizeString[0] = 0; - wchar_t dateString[32]; - dateString[0] = 0; - if (focusedItem >= 0 && _listView.GetSelectedCount() > 0) - { - int realIndex = GetRealItemIndex(focusedItem); - if (realIndex != kParentIndex) - { - ConvertSizeToString(GetItemSize(realIndex), sizeString); - NCOM::CPropVariant prop; - if (_folder->GetProperty(realIndex, kpidMTime, &prop) == S_OK) - { - char dateString2[32]; - dateString2[0] = 0; - ConvertPropertyToShortString(dateString2, prop, kpidMTime, false); - for (unsigned i = 0;; i++) - { - char c = dateString2[i]; - dateString[i] = (Byte)c; - if (c == 0) - break; - } - } - } - } - _statusBar.SetText(2, sizeString); - _statusBar.SetText(3, dateString); - - // _statusBar.SetText(4, nameString); - // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize))); - // } - /* - dw = GetTickCount() - dw; - sprintf(s, "status = %8d ms", dw); - OutputDebugStringA(s); - */ -#endif -} +// PanelListNotify.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../Common/PropIDUtils.h" +#include "../../PropID.h" + +#include "App.h" +#include "Panel.h" +#include "FormatUtils.h" + +using namespace NWindows; + +/* Unicode characters for space: +0x009C STRING TERMINATOR +0x00B7 Middle dot +0x237D Shouldered open box +0x2420 Symbol for space +0x2422 Blank symbol +0x2423 Open box +*/ + +#define SPACE_REPLACE_CHAR (wchar_t)(0x2423) +#define SPACE_TERMINATOR_CHAR (wchar_t)(0x9C) + +#define INT_TO_STR_SPEC(v) \ + while (v >= 10) { temp[i++] = (Byte)('0' + (unsigned)(v % 10)); v /= 10; } \ + *s++ = (Byte)('0' + (unsigned)v); + +static void ConvertSizeToString(UInt64 val, wchar_t *s) throw() +{ + Byte temp[32]; + unsigned i = 0; + + if (val <= (UInt32)0xFFFFFFFF) + { + UInt32 val32 = (UInt32)val; + INT_TO_STR_SPEC(val32) + } + else + { + INT_TO_STR_SPEC(val) + } + + if (i < 3) + { + if (i != 0) + { + *s++ = temp[(size_t)i - 1]; + if (i == 2) + *s++ = temp[0]; + } + *s = 0; + return; + } + + unsigned r = i % 3; + if (r != 0) + { + s[0] = temp[--i]; + if (r == 2) + s[1] = temp[--i]; + s += r; + } + + do + { + s[0] = ' '; + s[1] = temp[(size_t)i - 1]; + s[2] = temp[(size_t)i - 2]; + s[3] = temp[(size_t)i - 3]; + s += 4; + } + while (i -= 3); + + *s = 0; +} + +UString ConvertSizeToString(UInt64 value); +UString ConvertSizeToString(UInt64 value) +{ + wchar_t s[32]; + ConvertSizeToString(value, s); + return s; +} + +bool IsSizeProp(UINT propID) throw(); +bool IsSizeProp(UINT propID) throw() +{ + switch (propID) + { + case kpidSize: + case kpidPackSize: + case kpidNumSubDirs: + case kpidNumSubFiles: + case kpidOffset: + case kpidLinks: + case kpidNumBlocks: + case kpidNumVolumes: + case kpidPhySize: + case kpidHeadersSize: + case kpidTotalSize: + case kpidFreeSpace: + case kpidClusterSize: + case kpidNumErrors: + case kpidNumStreams: + case kpidNumAltStreams: + case kpidAltStreamsSize: + case kpidVirtualSize: + case kpidUnpackSize: + case kpidTotalPhySize: + case kpidTailSize: + case kpidEmbeddedStubSize: + return true; + } + return false; +} + + + +/* +#include + +UInt64 GetCpuTicks() +{ + #ifdef _WIN64 + return __rdtsc(); + #else + UInt32 lowVal, highVal; + __asm RDTSC; + __asm mov lowVal, EAX; + __asm mov highVal, EDX; + return ((UInt64)highVal << 32) | lowVal; + #endif +} + +UInt32 g_NumGroups; +UInt64 g_start_tick; +UInt64 g_prev_tick; +DWORD g_Num_SetItemText; +UInt32 g_NumMessages; +*/ + +LRESULT CPanel::SetItemText(LVITEMW &item) +{ + if (_dontShowMode) + return 0; + UInt32 realIndex = GetRealIndex(item); + + // g_Num_SetItemText++; + + /* + if ((item.mask & LVIF_IMAGE) != 0) + { + bool defined = false; + CComPtr folderGetSystemIconIndex; + _folder.QueryInterface(&folderGetSystemIconIndex); + if (folderGetSystemIconIndex) + { + folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage); + defined = (item.iImage > 0); + } + if (!defined) + { + NCOM::CPropVariant prop; + _folder->GetProperty(index, kpidAttrib, &prop); + UINT32 attrib = 0; + if (prop.vt == VT_UI4) + attrib = prop.ulVal; + else if (IsItemFolder(index)) + attrib |= FILE_ATTRIBUTE_DIRECTORY; + if (_currentFolderPrefix.IsEmpty()) + throw 1; + else + item.iImage = _extToIconMap.GetIconIndex(attrib, GetSystemString(GetItemName(index))); + } + // item.iImage = 1; + } + */ + + if ((item.mask & LVIF_TEXT) == 0) + return 0; + + LPWSTR text = item.pszText; + + if (item.cchTextMax > 0) + text[0] = 0; + + if (item.cchTextMax <= 1) + return 0; + + // item.cchTextMax > 1 + + const CPropColumn &property = _visibleColumns[item.iSubItem]; + PROPID propID = property.ID; + + if (realIndex == kParentIndex_UInt32) + { + if (propID == kpidName) + { + if (item.cchTextMax > 2) + { + text[0] = '.'; + text[1] = '.'; + text[2] = 0; + } + } + return 0; + } + + /* + // List-view in report-view in Windows 10 is slow (50+ ms) for page change. + // that code shows the time of page reload for items + // if you know how to improve the speed of list view refresh, notify 7-Zip developer + + // if (propID == 2000) + // if (propID == kpidName) + { + // debug column; + // DWORD dw = GetCpuTicks(); + UInt64 dw = GetCpuTicks(); + UInt64 deltaLast = dw - g_prev_tick; + #define conv_ticks(t) ((unsigned)((t) / 100000)) + if (deltaLast > 1000u * 1000 * 1000) + { + UInt64 deltaFull = g_prev_tick - g_start_tick; + char s[128]; + sprintf(s, "%d", conv_ticks(deltaFull)); + OutputDebugStringA(s); + g_start_tick = dw; + g_NumGroups++; + } + g_prev_tick = dw; + UString u; + char s[128]; + UInt64 deltaFull = dw - g_start_tick; + // for (int i = 0; i < 100000; i++) + sprintf(s, "%d %d %d-%d ", g_NumMessages, g_Num_SetItemText, g_NumGroups, conv_ticks(deltaFull)); + // sprintf(s, "%d-%d ", g_NumGroups, conv_ticks(deltaFull)); + u = s; + lstrcpyW(text, u.Ptr()); + text += u.Len(); + + // dw = GetCpuTicks(); + // deltaFull = dw - g_prev_tick; + // sprintf(s, "-%d ", conv_ticks(deltaFull)); + // u = s; + // lstrcpyW(text, u.Ptr()); + // text += u.Len(); + + if (propID != kpidName) + return 0; + } + */ + + + if (property.IsRawProp) + { + const void *data; + UInt32 dataSize; + UInt32 propType; + RINOK(_folderRawProps->GetRawProp(realIndex, propID, &data, &dataSize, &propType)) + unsigned limit = (unsigned)item.cchTextMax - 1; + // limit != 0 + if (dataSize == 0) + return 0; + + if (propID == kpidNtReparse) + { + UString s; + ConvertNtReparseToString((const Byte *)data, dataSize, s); + if (!s.IsEmpty()) + { + unsigned i; + for (i = 0; i < limit; i++) + { + const wchar_t c = s[i]; + if (c == 0) + break; + text[i] = c; + } + text[i] = 0; + return 0; + } + } + else if (propID == kpidNtSecure) + { + AString s; + ConvertNtSecureToString((const Byte *)data, dataSize, s); + if (!s.IsEmpty()) + { + unsigned i; + for (i = 0; i < limit; i++) + { + const wchar_t c = (Byte)s[i]; + if (c == 0) + break; + text[i] = c; + } + text[i] = 0; + return 0; + } + } + { + const unsigned kMaxDataSize = 64; + if (dataSize > kMaxDataSize) + { + char temp[32]; + MyStringCopy(temp, "data:"); + ConvertUInt32ToString(dataSize, temp + 5); + unsigned i; + for (i = 0; i < limit; i++) + { + wchar_t c = (Byte)temp[i]; + if (c == 0) + break; + *text++ = c; + } + *text = 0; + } + else + { + const char * const k_Hex = + (dataSize <= 8 + && (propID == kpidCRC || propID == kpidChecksum)) + ? k_Hex_Upper : k_Hex_Lower; + limit /= 2; + if (limit > dataSize) + limit = dataSize; + const Byte *data2 = (const Byte *)data; + do + { + const size_t b = *data2++; + text[0] = (Byte)k_Hex[b >> 4]; + text[1] = (Byte)k_Hex[b & 15]; + text += 2; + } + while (--limit); + *text = 0; + } + } + return 0; + } + /* + { + NCOM::CPropVariant prop; + if (propID == kpidType) + string = GetFileType(index); + else + { + HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &prop); + if (result != S_OK) + { + // PrintMessage("GetPropertyValue error"); + return 0; + } + string = ConvertPropertyToString(prop, propID, false); + } + } + */ + // const NFind::CFileInfo &aFileInfo = m_Files[index]; + + NCOM::CPropVariant prop; + /* + bool needRead = true; + if (propID == kpidSize) + { + CComPtr getItemFullSize; + if (_folder.QueryInterface(&getItemFullSize) == S_OK) + { + if (getItemFullSize->GetItemFullSize(index, &prop) == S_OK) + needRead = false; + } + } + if (needRead) + */ + + if (item.cchTextMax < 32) + return 0; + + if (propID == kpidName) + { + if (_folderGetItemName) + { + const wchar_t *name = NULL; + unsigned nameLen = 0; + _folderGetItemName->GetItemName(realIndex, &name, &nameLen); + + if (name) + { + unsigned dest = 0; + const unsigned limit = (unsigned)item.cchTextMax - 1; + + for (unsigned i = 0; dest < limit;) + { + const wchar_t c = name[i++]; + if (c == 0) + break; + text[dest++] = c; + + if (c != ' ') + { + if (c != 0x202E) // RLO + continue; + text[(size_t)dest - 1] = '_'; + continue; + } + + if (name[i] != ' ') + continue; + + unsigned t = 1; + for (; name[i + t] == ' '; t++); + + if (t >= 4 && dest + 4 < limit) + { + text[dest++] = '.'; + text[dest++] = '.'; + text[dest++] = '.'; + text[dest++] = ' '; + i += t; + } + } + + if (dest == 0) + text[dest++]= '_'; + + #ifdef _WIN32 + else if (text[(size_t)dest - 1] == ' ') + { + if (dest < limit) + text[dest++] = SPACE_TERMINATOR_CHAR; + else + text[dest - 1] = SPACE_REPLACE_CHAR; + } + #endif + + text[dest] = 0; + // OutputDebugStringW(text); + return 0; + } + } + } + + if (propID == kpidPrefix) + { + if (_folderGetItemName) + { + const wchar_t *name = NULL; + unsigned nameLen = 0; + _folderGetItemName->GetItemPrefix(realIndex, &name, &nameLen); + if (name) + { + unsigned dest = 0; + const unsigned limit = (unsigned)item.cchTextMax - 1; + for (unsigned i = 0; dest < limit;) + { + const wchar_t c = name[i++]; + if (c == 0) + break; + text[dest++] = c; + } + text[dest] = 0; + return 0; + } + } + } + + const HRESULT res = _folder->GetProperty(realIndex, propID, &prop); + + if (res != S_OK) + { + MyStringCopy(text, L"Error: "); + // s = UString("Error: ") + HResultToMessage(res); + } + else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID)) + { + UInt64 v = 0; + ConvertPropVariantToUInt64(prop, v); + ConvertSizeToString(v, text); + } + else if (prop.vt == VT_BSTR) + { + const unsigned limit = (unsigned)item.cchTextMax - 1; + const wchar_t *src = prop.bstrVal; + unsigned i; + for (i = 0; i < limit; i++) + { + wchar_t c = src[i]; + if (c == 0) break; + if (c == 0xA) c = ' '; + if (c == 0xD) c = ' '; + text[i] = c; + } + text[i] = 0; + } + else + { + char temp[64]; + ConvertPropertyToShortString2(temp, prop, propID, _timestampLevel); + unsigned i; + const unsigned limit = (unsigned)item.cchTextMax - 1; + for (i = 0; i < limit; i++) + { + const wchar_t c = (Byte)temp[i]; + if (c == 0) + break; + text[i] = c; + } + text[i] = 0; + } + + return 0; +} + +void CPanel::OnItemChanged(NMLISTVIEW *item) +{ + const unsigned index = (unsigned)item->lParam; + if (index == kParentIndex) + return; + const bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0; + const bool newSelected = (item->uNewState & LVIS_SELECTED) != 0; + // Don't change this code. It works only with such check + if (oldSelected != newSelected) + _selectedStatusVector[index] = newSelected; +} + +extern bool g_LVN_ITEMACTIVATE_Support; + +void CPanel::OnNotifyActivateItems() +{ + bool alt = IsKeyDown(VK_MENU); + bool ctrl = IsKeyDown(VK_CONTROL); + bool shift = IsKeyDown(VK_SHIFT); + if (!shift && alt && !ctrl) + Properties(); + else + OpenSelectedItems(!shift || alt || ctrl); +} + +bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) +{ + switch (header->code) + { + case LVN_ITEMCHANGED: + { + if (_enableItemChangeNotify) + { + if (!_mySelectMode) + OnItemChanged((LPNMLISTVIEW)header); + + // Post_Refresh_StatusBar(); + /* 9.26: we don't call Post_Refresh_StatusBar. + it was very slow if we select big number of files + and then clead slection by selecting just new file. + probably it called slow Refresh_StatusBar for each item deselection. + I hope Refresh_StatusBar still will be called for each key / mouse action. + */ + } + return false; + } + /* + + case LVN_ODSTATECHANGED: + { + break; + } + */ + + case LVN_GETDISPINFOW: + { + LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header; + + //is the sub-item information being requested? + + if ((dispInfo->item.mask & LVIF_TEXT) != 0 || + (dispInfo->item.mask & LVIF_IMAGE) != 0) + SetItemText(dispInfo->item); + { + // 20.03: + result = 0; + return true; + // old 7-Zip: + // return false; + } + } + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + bool boolResult = OnKeyDown(keyDownInfo, result); + switch (keyDownInfo->wVKey) + { + case VK_CONTROL: + case VK_SHIFT: + case VK_MENU: + break; + default: + Post_Refresh_StatusBar(); + } + return boolResult; + } + + case LVN_COLUMNCLICK: + OnColumnClick(LPNMLISTVIEW(header)); + return false; + + case LVN_ITEMACTIVATE: + if (g_LVN_ITEMACTIVATE_Support) + { + OnNotifyActivateItems(); + return false; + } + break; + case NM_DBLCLK: + case NM_RETURN: + if (!g_LVN_ITEMACTIVATE_Support) + { + OnNotifyActivateItems(); + return false; + } + break; + + case NM_RCLICK: + Post_Refresh_StatusBar(); + break; + + /* + return OnRightClick((LPNMITEMACTIVATE)header, result); + */ + /* + case NM_CLICK: + SendRefreshStatusBarMessage(); + return 0; + + // TODO : Handler default action... + return 0; + case LVN_ITEMCHANGED: + { + NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh; + SelChange(pNMLV); + return TRUE; + } + case NM_SETFOCUS: + return onSetFocus(NULL); + case NM_KILLFOCUS: + return onKillFocus(NULL); + */ + case NM_CLICK: + { + // we need SetFocusToList, if we drag-select items from other panel. + SetFocusToList(); + Post_Refresh_StatusBar(); + if (_mySelectMode) +#ifdef Z7_USE_DYN_ComCtl32Version + if (g_ComCtl32Version >= MAKELONG(71, 4)) +#endif + OnLeftClick((MY_NMLISTVIEW_NMITEMACTIVATE *)header); + return false; + } + case LVN_BEGINLABELEDITW: + result = OnBeginLabelEdit((LV_DISPINFOW *)header); + return true; + case LVN_ENDLABELEDITW: + result = OnEndLabelEdit((LV_DISPINFOW *)header); + return true; + + case NM_CUSTOMDRAW: + { + if (_mySelectMode || (_markDeletedItems && _thereAreDeletedItems)) + return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result); + break; + } + case LVN_BEGINDRAG: + { + OnDrag((LPNMLISTVIEW)header, false); + Post_Refresh_StatusBar(); + break; + } + case LVN_BEGINRDRAG: + { + OnDrag((LPNMLISTVIEW)header, true); + Post_Refresh_StatusBar(); + break; + } + // case LVN_BEGINRDRAG: + } + return false; +} + +bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result) +{ + switch (lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : + result = CDRF_NOTIFYITEMDRAW; + return true; + + case CDDS_ITEMPREPAINT: + /* + SelectObject(lplvcd->nmcd.hdc, + GetFontForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam) ); + lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + */ + const unsigned realIndex = (unsigned)lplvcd->nmcd.lItemlParam; + lplvcd->clrTextBk = _listView.GetBkColor(); + if (_mySelectMode) + { + if (realIndex != kParentIndex && _selectedStatusVector[realIndex]) + lplvcd->clrTextBk = RGB(255, 192, 192); + } + + if (_markDeletedItems && _thereAreDeletedItems) + { + if (IsItem_Deleted(realIndex)) + lplvcd->clrText = RGB(255, 0, 0); + } + // lplvcd->clrText = RGB(0, 0, 0); + // result = CDRF_NEWFONT; + result = CDRF_NOTIFYITEMDRAW; + return true; + + // return false; + // return true; + /* + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: + if (lplvcd->iSubItem == 0) + { + // lplvcd->clrText = RGB(255, 0, 0); + lplvcd->clrTextBk = RGB(192, 192, 192); + } + else + { + lplvcd->clrText = RGB(0, 0, 0); + lplvcd->clrTextBk = RGB(255, 255, 255); + } + return true; + */ + + /* At this point, you can change the background colors for the item + and any subitems and return CDRF_NEWFONT. If the list-view control + is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW + to customize the item's subitems individually */ + } + return false; +} + +void CPanel::Refresh_StatusBar() +{ + /* + g_name_cnt++; + char s[256]; + sprintf(s, "g_name_cnt = %8d", g_name_cnt); + OutputDebugStringA(s); + */ + // DWORD dw = GetTickCount(); + + CRecordVector indices; + Get_ItemIndices_Operated(indices); + + { + UString s; + s.Add_UInt32(indices.Size()); + s += " / "; + s.Add_UInt32(_selectedStatusVector.Size()); + + // UString s1 = MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, NumberToString(indices.Size())); + // UString s1 = MyFormatNew(IDS_N_SELECTED_ITEMS, NumberToString(indices.Size())); + _statusBar.SetText(0, MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, s)); + // _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, NumberToString(indices.Size()))); + } + + { + wchar_t selectSizeString[32]; + selectSizeString[0] = 0; + + if (!indices.IsEmpty()) + { + // for (unsigned ttt = 0; ttt < 1000; ttt++) { + UInt64 totalSize = 0; + FOR_VECTOR (i, indices) + totalSize += GetItemSize(indices[i]); + ConvertSizeToString(totalSize, selectSizeString); + // } + } + _statusBar.SetText(1, selectSizeString); + } + + const int focusedItem = _listView.GetFocusedItem(); + wchar_t sizeString[32]; + sizeString[0] = 0; + wchar_t dateString[32]; + dateString[0] = 0; + if (focusedItem >= 0 && _listView.GetSelectedCount() > 0) + { + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + { + ConvertSizeToString(GetItemSize(realIndex), sizeString); + NCOM::CPropVariant prop; + if (_folder->GetProperty(realIndex, kpidMTime, &prop) == S_OK) + { + char dateString2[64]; + dateString2[0] = 0; + ConvertPropertyToShortString2(dateString2, prop, kpidMTime); + for (unsigned i = 0;; i++) + { + char c = dateString2[i]; + dateString[i] = (Byte)c; + if (c == 0) + break; + } + } + } + } + _statusBar.SetText(2, sizeString); + _statusBar.SetText(3, dateString); + + // _statusBar.SetText(4, nameString); + // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize))); + // } + /* + dw = GetTickCount() - dw; + sprintf(s, "status = %8d ms", dw); + OutputDebugStringA(s); + */ +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelMenu.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelMenu.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelMenu.cpp 2015-10-03 17:51:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelMenu.cpp 2023-09-30 16:00:00.000000000 +0000 @@ -1,879 +1,1156 @@ -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/COM.h" -#include "../../../Windows/Clipboard.h" -#include "../../../Windows/Menu.h" -#include "../../../Windows/PropVariant.h" -#include "../../../Windows/PropVariantConv.h" - -#include "../../PropID.h" -#include "../Common/PropIDUtils.h" -#include "../Explorer/ContextMenu.h" - -#include "App.h" -#include "LangUtils.h" -#include "MyLoadMenu.h" -#include "PropertyName.h" - -#include "resource.h" -#include "PropertyNameRes.h" - -using namespace NWindows; - -LONG g_DllRefCount = 0; - -static const UINT kSevenZipStartMenuID = kMenuCmdID_Plugin_Start; -static const UINT kSystemStartMenuID = kMenuCmdID_Plugin_Start + 100; - -void CPanel::InvokeSystemCommand(const char *command) -{ -#ifdef _WIN32 - NCOM::CComInitializer comInitializer; - if (!IsFsOrPureDrivesFolder()) - return; - CRecordVector operatedIndices; - GetOperatedItemIndices(operatedIndices); - if (operatedIndices.IsEmpty()) - return; - CMyComPtr contextMenu; - if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK) - return; - - CMINVOKECOMMANDINFO ci; - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(CMINVOKECOMMANDINFO); - ci.hwnd = GetParent(); - ci.lpVerb = command; - contextMenu->InvokeCommand(&ci); -#else - printf(" WARNING CPanel::InvokeSystemCommand(%s)\n",command); -#endif -} - -static const char *kSeparator = "----------------------------\n"; -static const char *kSeparatorSmall = "----\n"; -static const char *kPropValueSeparator = ": "; - -extern UString ConvertSizeToString(UInt64 value) throw(); -bool IsSizeProp(UINT propID) throw(); - -UString GetOpenArcErrorMessage(UInt32 errorFlags); - -static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, - const NCOM::CPropVariant &prop, UString &s) -{ - if (prop.vt != VT_EMPTY) - { - UString val; - - if (propID == kpidErrorFlags || - propID == kpidWarningFlags) - { - UInt32 flags = GetOpenArcErrorFlags(prop); - if (flags == 0) - return; - if (flags != 0) - val = GetOpenArcErrorMessage(flags); - } - if (val.IsEmpty()) - if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID)) - { - UInt64 v = 0; - ConvertPropVariantToUInt64(prop, v); - val = ConvertSizeToString(v); - } - else - ConvertPropertyToString(val, prop, propID); - - if (!val.IsEmpty()) - { - s += GetNameOfProperty(propID, nameBSTR); - s.AddAscii(kPropValueSeparator); - /* - if (propID == kpidComment) - s.Add_LF(); - */ - s += val; - s.Add_LF(); - } - } -} - -static inline char GetHex(Byte value) -{ - return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10))); -} - -static const Byte kSpecProps[] = -{ - kpidPath, - kpidType, - kpidErrorType, - kpidError, - kpidErrorFlags, - kpidWarning, - kpidWarningFlags, - kpidOffset, - kpidPhySize, - kpidTailSize -}; - -void CPanel::Properties() -{ - CMyComPtr getFolderArcProps; - _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); - if (!getFolderArcProps) - { - InvokeSystemCommand("properties"); - return; - } - - { - UString message; - - CRecordVector operatedIndices; - GetOperatedItemIndices(operatedIndices); - if (operatedIndices.Size() == 1) - { - UInt32 index = operatedIndices[0]; - // message += L"Item:\n"; - UInt32 numProps; - if (_folder->GetNumberOfProperties(&numProps) == S_OK) - { - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE varType; - - if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) - continue; - - NCOM::CPropVariant prop; - if (_folder->GetProperty(index, propID, &prop) != S_OK) - continue; - AddPropertyString(propID, name, prop, message); - } - } - - - if (_folderRawProps) - { - _folderRawProps->GetNumRawProps(&numProps); - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - if (_folderRawProps->GetRawPropInfo(i, &name, &propID) != S_OK) - continue; - - const void *data; - UInt32 dataSize; - UInt32 propType; - if (_folderRawProps->GetRawProp(index, propID, &data, &dataSize, &propType) != S_OK) - continue; - - if (dataSize != 0) - { - AString s; - if (propID == kpidNtSecure) - ConvertNtSecureToString((const Byte *)data, dataSize, s); - else - { - const UInt32 kMaxDataSize = 64; - if (dataSize > kMaxDataSize) - { - char temp[64]; - s += "data:"; - ConvertUInt32ToString(dataSize, temp); - s += temp; - } - else - { - for (UInt32 i = 0; i < dataSize; i++) - { - Byte b = ((const Byte *)data)[i]; - s += GetHex((Byte)((b >> 4) & 0xF)); - s += GetHex((Byte)(b & 0xF)); - } - } - } - message += GetNameOfProperty(propID, name); - message.AddAscii(kPropValueSeparator); - message.AddAscii(s); - message.Add_LF(); - } - } - } - - message.AddAscii(kSeparator); - } - - /* - AddLangString(message, IDS_PROP_FILE_TYPE); - message += kPropValueSeparator; - message += GetFolderTypeID(); - message.Add_LF(); - */ - - { - NCOM::CPropVariant prop; - if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) - { - AddPropertyString(kpidName, L"Path", prop, message); - } - } - - CMyComPtr folderProperties; - _folder.QueryInterface(IID_IFolderProperties, &folderProperties); - if (folderProperties) - { - UInt32 numProps; - if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) - { - for (UInt32 i = 0; i < numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) - continue; - NCOM::CPropVariant prop; - if (_folder->GetFolderProperty(propID, &prop) != S_OK) - continue; - AddPropertyString(propID, name, prop, message); - } - } - } - - CMyComPtr getFolderArcProps; - _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); - if (getFolderArcProps) - { - CMyComPtr getProps; - getFolderArcProps->GetFolderArcProps(&getProps); - if (getProps) - { - UInt32 numLevels; - if (getProps->GetArcNumLevels(&numLevels) != S_OK) - numLevels = 0; - for (UInt32 level2 = 0; level2 < numLevels; level2++) - { - { - UInt32 level = numLevels - 1 - level2; - UInt32 numProps; - if (getProps->GetArcNumProps(level, &numProps) == S_OK) - { - const int kNumSpecProps = ARRAY_SIZE(kSpecProps); - - message.AddAscii(kSeparator); - - for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - if (i < 0) - propID = kSpecProps[i + kNumSpecProps]; - else if (getProps->GetArcPropInfo(level, i, &name, &propID, &vt) != S_OK) - continue; - NCOM::CPropVariant prop; - if (getProps->GetArcProp(level, propID, &prop) != S_OK) - continue; - AddPropertyString(propID, name, prop, message); - } - } - } - - if (level2 != numLevels - 1) - { - UInt32 level = numLevels - 1 - level2; - UInt32 numProps; - if (getProps->GetArcNumProps2(level, &numProps) == S_OK) - { - message.AddAscii(kSeparatorSmall); - for (Int32 i = 0; i < (Int32)numProps; i++) - { - CMyComBSTR name; - PROPID propID; - VARTYPE vt; - if (getProps->GetArcPropInfo2(level, i, &name, &propID, &vt) != S_OK) - continue; - NCOM::CPropVariant prop; - if (getProps->GetArcProp2(level, propID, &prop) != S_OK) - continue; - AddPropertyString(propID, name, prop, message); - } - } - } - } - } - } - ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES), MB_OK); - } -} - -void CPanel::EditCut() -{ - // InvokeSystemCommand("cut"); -} - -void CPanel::EditCopy() -{ - /* - CMyComPtr getFolderArcProps; - _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); - if (!getFolderArcProps) - { - InvokeSystemCommand("copy"); - return; - } - */ - UString s; - CRecordVector indices; - GetSelectedItemsIndices(indices); - FOR_VECTOR (i, indices) - { - if (i > 0) - s += L"\xD\n"; - s += GetItemName(indices[i]); - } - ClipboardSetText(_mainWindow, s); -} - -void CPanel::EditPaste() -{ - /* - UStringVector names; - ClipboardGetFileNames(names); - CopyFromNoAsk(names); - UString s; - for (int i = 0; i < names.Size(); i++) - { - s += L' '; - s += names[i]; - } - - MessageBoxW(0, s, L"", 0); - */ - - // InvokeSystemCommand("paste"); -} - -#ifdef _WIN32 -HRESULT CPanel::CreateShellContextMenu( - const CRecordVector &operatedIndices, - CMyComPtr &systemContextMenu) -{ - systemContextMenu.Release(); - UString folderPath = GetFsPath(); - - CMyComPtr desktopFolder; - RINOK(::SHGetDesktopFolder(&desktopFolder)); - if (!desktopFolder) - { - // ShowMessage("Failed to get Desktop folder."); - return E_FAIL; - } - - // Separate the file from the folder. - - - // Get a pidl for the folder the file - // is located in. - LPITEMIDLIST parentPidl; - DWORD eaten; - RINOK(desktopFolder->ParseDisplayName( - GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath, - &eaten, &parentPidl, 0)); - - // Get an IShellFolder for the folder - // the file is located in. - CMyComPtr parentFolder; - RINOK(desktopFolder->BindToObject(parentPidl, - 0, IID_IShellFolder, (void**)&parentFolder)); - if (!parentFolder) - { - // ShowMessage("Invalid file name."); - return E_FAIL; - } - - // Get a pidl for the file itself. - CRecordVector pidls; - pidls.ClearAndReserve(operatedIndices.Size()); - FOR_VECTOR (i, operatedIndices) - { - LPITEMIDLIST pidl; - UString fileName = GetItemRelPath2(operatedIndices[i]); - RINOK(parentFolder->ParseDisplayName(GetParent(), 0, - (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0)); - pidls.AddInReserved(pidl); - } - - ITEMIDLIST temp; - if (pidls.Size() == 0) - { - temp.mkid.cb = 0; - /* - LPITEMIDLIST pidl; - HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0, - L"." WSTRING_PATH_SEPARATOR, &eaten, &pidl, 0); - if (result != NOERROR) - return; - */ - pidls.Add(&temp); - } - - // Get the IContextMenu for the file. - CMyComPtr cm; - RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(), - (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm)); - if (!cm) - { - // ShowMessage("Unable to get context menu interface."); - return E_FAIL; - } - systemContextMenu = cm; - return S_OK; -} - -void CPanel::CreateSystemMenu(HMENU menuSpec, - const CRecordVector &operatedIndices, - CMyComPtr &systemContextMenu) -{ - systemContextMenu.Release(); - - CreateShellContextMenu(operatedIndices, systemContextMenu); - - if (systemContextMenu == 0) - return; - - // Set up a CMINVOKECOMMANDINFO structure. - CMINVOKECOMMANDINFO ci; - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(CMINVOKECOMMANDINFO); - ci.hwnd = GetParent(); - - /* - if (Sender == GoBtn) - { - // Verbs that can be used are cut, paste, - // properties, delete, and so on. - String action; - if (CutRb->Checked) - action = "cut"; - else if (CopyRb->Checked) - action = "copy"; - else if (DeleteRb->Checked) - action = "delete"; - else if (PropertiesRb->Checked) - action = "properties"; - - ci.lpVerb = action.c_str(); - result = cm->InvokeCommand(&ci); - if (result) - ShowMessage( - "Error copying file to clipboard."); - - } - else - */ - { - // HMENU hMenu = CreatePopupMenu(); - CMenu popupMenu; - // CMenuDestroyer menuDestroyer(popupMenu); - if (!popupMenu.CreatePopup()) - throw 210503; - - HMENU hMenu = popupMenu; - - DWORD Flags = CMF_EXPLORE; - // Optionally the shell will show the extended - // context menu on some operating systems when - // the shift key is held down at the time the - // context menu is invoked. The following is - // commented out but you can uncommnent this - // line to show the extended context menu. - // Flags |= 0x00000080; - systemContextMenu->QueryContextMenu(hMenu, 0, kSystemStartMenuID, 0x7FFF, Flags); - - - { - CMenu menu; - menu.Attach(menuSpec); - CMenuItem menuItem; - menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; - menuItem.fType = MFT_STRING; - menuItem.hSubMenu = popupMenu.Detach(); - // menuDestroyer.Disable(); - LangString(IDS_SYSTEM, menuItem.StringValue); - menu.InsertItem(0, true, menuItem); - } - /* - if (Cmd < 100 && Cmd != 0) - { - ci.lpVerb = MAKEINTRESOURCE(Cmd - 1); - ci.lpParameters = ""; - ci.lpDirectory = ""; - ci.nShow = SW_SHOWNORMAL; - cm->InvokeCommand(&ci); - } - // If Cmd is > 100 then it's one of our - // inserted menu items. - else - // Find the menu item. - for (int i = 0; i < popupMenu1->Items->Count; i++) - { - TMenuItem* menu = popupMenu1->Items->Items[i]; - // Call its OnClick handler. - if (menu->Command == Cmd - 100) - menu->OnClick(this); - } - // Release the memory allocated for the menu. - DestroyMenu(hMenu); - */ - } -} - -void CPanel::CreateFileMenu(HMENU menuSpec) -{ - CreateFileMenu(menuSpec, _sevenZipContextMenu, _systemContextMenu, true); -} - -void CPanel::CreateSevenZipMenu(HMENU menuSpec, - const CRecordVector &operatedIndices, - CMyComPtr &sevenZipContextMenu) -{ - sevenZipContextMenu.Release(); - - CMenu menu; - menu.Attach(menuSpec); - // CMenuDestroyer menuDestroyer(menu); - // menu.CreatePopup(); - - bool sevenZipMenuCreated = false; - - CZipContextMenu *contextMenuSpec = new CZipContextMenu; - CMyComPtr contextMenu = contextMenuSpec; - // if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK) - { - /* - CMyComPtr initContextMenu; - if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK) - return; - */ - UString currentFolderUnicode = GetFsPath(); - UStringVector names; - unsigned i; - for (i = 0; i < operatedIndices.Size(); i++) - names.Add(currentFolderUnicode + GetItemRelPath2(operatedIndices[i])); - CRecordVector namePointers; - for (i = 0; i < operatedIndices.Size(); i++) - namePointers.Add(names[i]); - - // NFile::NDirectory::MySetCurrentDirectory(currentFolderUnicode); - if (contextMenuSpec->InitContextMenu(currentFolderUnicode, &namePointers.Front(), - operatedIndices.Size()) == S_OK) - { - HRESULT res = contextMenu->QueryContextMenu(menu, 0, kSevenZipStartMenuID, - kSystemStartMenuID - 1, 0); - sevenZipMenuCreated = (HRESULT_SEVERITY(res) == SEVERITY_SUCCESS); - if (sevenZipMenuCreated) - sevenZipContextMenu = contextMenu; - // int code = HRESULT_CODE(res); - // int nextItemID = code; - } - } -} - -#endif - -static bool IsReadOnlyFolder(IFolderFolder *folder) -{ - if (!folder) - return false; - - bool res = false; - { - NCOM::CPropVariant prop; - if (folder->GetFolderProperty(kpidReadOnly, &prop) == S_OK) - if (prop.vt == VT_BOOL) - res = VARIANT_BOOLToBool(prop.boolVal); - } - return res; -} - -bool CPanel::IsThereReadOnlyFolder() const -{ - if (!_folderOperations) - return true; - if (IsReadOnlyFolder(_folder)) - return true; - FOR_VECTOR (i, _parentFolders) - { - if (IsReadOnlyFolder(_parentFolders[i].ParentFolder)) - return true; - } - return false; -} - -bool CPanel::CheckBeforeUpdate(UINT resourceID) -{ - if (!_folderOperations) - { - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - // resourceID = resourceID; - // MessageBoxErrorForUpdate(E_NOINTERFACE, resourceID); - return false; - } - - for (int i = (int)_parentFolders.Size(); i >= 0; i--) - { - IFolderFolder *folder; - if (i == (int)_parentFolders.Size()) - folder = _folder; - else - folder = _parentFolders[i].ParentFolder; - - if (!IsReadOnlyFolder(folder)) - continue; - - UString s; - AddLangString(s, resourceID); - s.Add_LF(); - AddLangString(s, IDS_OPERATION_IS_NOT_SUPPORTED); - s.Add_LF(); - if (i == 0) - s += GetFolderPath(folder); - else - s += _parentFolders[i - 1].VirtualPath; - s.Add_LF(); - AddLangString(s, IDS_PROP_READ_ONLY); - MessageBoxMyError(s); - return false; - } - - return true; -} - -#ifdef _WIN32 -void CPanel::CreateFileMenu(HMENU menuSpec, - CMyComPtr &sevenZipContextMenu, - CMyComPtr &systemContextMenu, - bool programMenu) -{ - sevenZipContextMenu.Release(); - systemContextMenu.Release(); - - CRecordVector operatedIndices; - GetOperatedItemIndices(operatedIndices); - - CMenu menu; - menu.Attach(menuSpec); - - if (!IsArcFolder()) - { - CreateSevenZipMenu(menu, operatedIndices, sevenZipContextMenu); - // CreateSystemMenu is very slow if you call it inside ZIP archive with big number of files - // Windows probably can parse items inside ZIP archive. - if (g_App.ShowSystemMenu) - CreateSystemMenu(menu, operatedIndices, systemContextMenu); - } - - /* - if (menu.GetItemCount() > 0) - menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)0); - */ - - unsigned i; - for (i = 0; i < operatedIndices.Size(); i++) - if (IsItem_Folder(operatedIndices[i])) - break; - bool allAreFiles = (i == operatedIndices.Size()); - - CFileMenu fm; - - fm.readOnly = IsThereReadOnlyFolder(); - fm.isFsFolder = Is_IO_FS_Folder(); - fm.programMenu = programMenu; - fm.allAreFiles = allAreFiles; - fm.numItems = operatedIndices.Size(); - - fm.isAltStreamsSupported = false; - - if (_folderAltStreams) - { - if (operatedIndices.Size() <= 1) - { - Int32 realIndex = -1; - if (operatedIndices.Size() == 1) - realIndex = operatedIndices[0]; - Int32 val = 0; - if (_folderAltStreams->AreAltStreamsSupported(realIndex, &val) == S_OK) - fm.isAltStreamsSupported = IntToBool(val); - } - } - else - { - if (fm.numItems == 0) - fm.isAltStreamsSupported = IsFSFolder(); - else - fm.isAltStreamsSupported = IsFolder_with_FsItems(); - } - - fm.Load(menu, menu.GetItemCount()); -} - -bool CPanel::InvokePluginCommand(int id) -{ - return InvokePluginCommand(id, _sevenZipContextMenu, _systemContextMenu); -} - -#if defined(_MSC_VER) && !defined(UNDER_CE) -#define use_CMINVOKECOMMANDINFOEX -#endif - -bool CPanel::InvokePluginCommand(int id, - IContextMenu *sevenZipContextMenu, IContextMenu *systemContextMenu) -{ - UInt32 offset; - bool isSystemMenu = (id >= kSystemStartMenuID); - if (isSystemMenu) - offset = id - kSystemStartMenuID; - else - offset = id - kSevenZipStartMenuID; - - #ifdef use_CMINVOKECOMMANDINFOEX - CMINVOKECOMMANDINFOEX - #else - CMINVOKECOMMANDINFO - #endif - commandInfo; - - memset(&commandInfo, 0, sizeof(commandInfo)); - commandInfo.cbSize = sizeof(commandInfo); - - commandInfo.fMask = 0 - #ifdef use_CMINVOKECOMMANDINFOEX - | CMIC_MASK_UNICODE - #endif - ; - - commandInfo.hwnd = GetParent(); - commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset)); - commandInfo.lpParameters = NULL; - CSysString currentFolderSys = GetSystemString(_currentFolderPrefix); - commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys); - commandInfo.nShow = SW_SHOW; - - #ifdef use_CMINVOKECOMMANDINFOEX - - commandInfo.lpParametersW = NULL; - commandInfo.lpTitle = ""; - commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset)); - UString currentFolderUnicode = _currentFolderPrefix; - commandInfo.lpDirectoryW = currentFolderUnicode; - commandInfo.lpTitleW = L""; - // commandInfo.ptInvoke.x = xPos; - // commandInfo.ptInvoke.y = yPos; - commandInfo.ptInvoke.x = 0; - commandInfo.ptInvoke.y = 0; - - #endif - - HRESULT result; - if (isSystemMenu) - result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); - else - result = sevenZipContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); - if (result == NOERROR) - { - KillSelection(); - return true; - } - return false; -} - -bool CPanel::OnContextMenu(HANDLE windowHandle, int xPos, int yPos) -{ - if (::GetParent((HWND)windowHandle) == _listView) - { - ShowColumnsContextMenu(xPos, yPos); - return true; - } - - if (windowHandle != _listView) - return false; - /* - POINT point; - point.x = xPos; - point.y = yPos; - if (!_listView.ScreenToClient(&point)) - return false; - - LVHITTESTINFO info; - info.pt = point; - int index = _listView.HitTest(&info); - */ - - CRecordVector operatedIndices; - GetOperatedItemIndices(operatedIndices); - - // negative x,y are possible for multi-screen modes. - // x=-1 && y=-1 for keyboard call (SHIFT+F10 and others). - if (xPos == -1 && yPos == -1) - { - if (operatedIndices.Size() == 0) - { - xPos = 0; - yPos = 0; - } - else - { - int itemIndex = _listView.GetNextItem(-1, LVNI_FOCUSED); - if (itemIndex == -1) - return false; - RECT rect; - if (!_listView.GetItemRect(itemIndex, &rect, LVIR_ICON)) - return false; - xPos = (rect.left + rect.right) / 2; - yPos = (rect.top + rect.bottom) / 2; - } - POINT point = {xPos, yPos}; - _listView.ClientToScreen(&point); - xPos = point.x; - yPos = point.y; - } - - CMenu menu; - CMenuDestroyer menuDestroyer(menu); - menu.CreatePopup(); - - CMyComPtr sevenZipContextMenu; - CMyComPtr systemContextMenu; - CreateFileMenu(menu, sevenZipContextMenu, systemContextMenu, false); - - int result = menu.Track(TPM_LEFTALIGN - #ifndef UNDER_CE - | TPM_RIGHTBUTTON - #endif - | TPM_RETURNCMD | TPM_NONOTIFY, - xPos, yPos, _listView); - - if (result == 0) - return true; - - if (result >= kMenuCmdID_Plugin_Start) - { - InvokePluginCommand(result, sevenZipContextMenu, systemContextMenu); - return true; - } - if (ExecuteFileCommand(result)) - return true; - return true; -} -#endif - +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/COM.h" +#include "../../../Windows/Clipboard.h" +#include "../../../Windows/Menu.h" +#include "../../../Windows/PropVariant.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../PropID.h" +#include "../Common/PropIDUtils.h" +#include "../Explorer/ContextMenu.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "ListViewDialog.h" +#include "MyLoadMenu.h" +#include "PropertyName.h" + +#include "PropertyNameRes.h" +#include "resource.h" + +// #define SHOW_DEBUG_PANEL_MENU + +using namespace NWindows; + +extern +LONG g_DllRefCount; +LONG g_DllRefCount = 0; + +static const UINT kSevenZipStartMenuID = kMenuCmdID_Plugin_Start; +static const UINT kSystemStartMenuID = kMenuCmdID_Plugin_Start + 400; + + +#ifdef SHOW_DEBUG_PANEL_MENU +static void Print_Ptr(void *p, const char *s) +{ + char temp[32]; + ConvertUInt64ToHex((UInt64)(void *)p, temp); + AString m; + m += temp; + m.Add_Space(); + m += s; + OutputDebugStringA(m); +} +#define ODS(sz) { Print_Ptr(this, sz); } +#define ODS_U(s) { OutputDebugStringW(s); } +#else +#define ODS(sz) +#define ODS_U(s) +#endif + + +void CPanel::InvokeSystemCommand(const char *command) +{ + NCOM::CComInitializer comInitializer; + if (!IsFsOrPureDrivesFolder()) + return; + CRecordVector operatedIndices; + Get_ItemIndices_Operated(operatedIndices); + if (operatedIndices.IsEmpty()) + return; + CMyComPtr contextMenu; + if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK) + return; + + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + ci.lpVerb = command; + contextMenu->InvokeCommand(&ci); +} + +static const char * const kSeparator = "------------------------"; +static const char * const kSeparatorSmall = "----------------"; + +extern UString ConvertSizeToString(UInt64 value) throw(); +bool IsSizeProp(UINT propID) throw(); + +UString GetOpenArcErrorMessage(UInt32 errorFlags); + + +static void AddListAscii(CListViewDialog &dialog, const char *s) +{ + dialog.Strings.Add((UString)s); + dialog.Values.AddNew(); +} + +static void AddSeparator(CListViewDialog &dialog) +{ + AddListAscii(dialog, kSeparator); +} + +static void AddSeparatorSmall(CListViewDialog &dialog) +{ + AddListAscii(dialog, kSeparatorSmall); +} + +static void AddPropertyPair(const UString &name, const UString &val, CListViewDialog &dialog) +{ + dialog.Strings.Add(name); + dialog.Values.Add(val); +} + + +static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, + const NCOM::CPropVariant &prop, CListViewDialog &dialog) +{ + if (prop.vt != VT_EMPTY) + { + UString val; + + if (propID == kpidErrorFlags || + propID == kpidWarningFlags) + { + UInt32 flags = GetOpenArcErrorFlags(prop); + if (flags == 0) + return; + if (flags != 0) + val = GetOpenArcErrorMessage(flags); + } + + if (val.IsEmpty()) + { + if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID)) + { + UInt64 v = 0; + ConvertPropVariantToUInt64(prop, v); + val = ConvertSizeToString(v); + } + else + ConvertPropertyToString2(val, prop, propID, 9); // we send 9 - is ns precision + } + + if (!val.IsEmpty()) + { + if (propID == kpidErrorType) + { + AddPropertyPair(L"Open WARNING:", L"Cannot open the file as expected archive type", dialog); + } + AddPropertyPair(GetNameOfProperty(propID, nameBSTR), val, dialog); + } + } +} + + +static void AddPropertyString(PROPID propID, UInt64 val, CListViewDialog &dialog) +{ + NCOM::CPropVariant prop = val; + AddPropertyString(propID, NULL, prop, dialog); +} + + +static const Byte kSpecProps[] = +{ + kpidPath, + kpidType, + kpidErrorType, + kpidError, + kpidErrorFlags, + kpidWarning, + kpidWarningFlags, + kpidOffset, + kpidPhySize, + kpidTailSize +}; + +void CPanel::Properties() +{ + CMyComPtr getFolderArcProps; + _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); + if (!getFolderArcProps) + { + InvokeSystemCommand("properties"); + return; + } + + { + CListViewDialog message; + // message.DeleteIsAllowed = false; + // message.SelectFirst = false; + + CRecordVector operatedIndices; + Get_ItemIndices_Operated(operatedIndices); + + if (operatedIndices.Size() == 1) + { + UInt32 index = operatedIndices[0]; + // message += "Item:\n"); + UInt32 numProps; + if (_folder->GetNumberOfProperties(&numProps) == S_OK) + { + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + + if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) + continue; + + NCOM::CPropVariant prop; + if (_folder->GetProperty(index, propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + + + if (_folderRawProps) + { + _folderRawProps->GetNumRawProps(&numProps); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + if (_folderRawProps->GetRawPropInfo(i, &name, &propID) != S_OK) + continue; + + const void *data; + UInt32 dataSize; + UInt32 propType; + if (_folderRawProps->GetRawProp(index, propID, &data, &dataSize, &propType) != S_OK) + continue; + + if (dataSize != 0) + { + AString s; + if (propID == kpidNtSecure) + ConvertNtSecureToString((const Byte *)data, dataSize, s); + else + { + const unsigned kMaxDataSize = 1 << 8; + if (dataSize > kMaxDataSize) + { + s += "data:"; + s.Add_UInt32(dataSize); + } + else + { + char temp[kMaxDataSize * 2 + 2]; + if (dataSize <= 8 && (propID == kpidCRC || propID == kpidChecksum)) + ConvertDataToHex_Upper(temp, (const Byte *)data, dataSize); + else + ConvertDataToHex_Lower(temp, (const Byte *)data, dataSize); + s += temp; + } + } + AddPropertyPair(GetNameOfProperty(propID, name), (UString)s.Ptr(), message); + } + } + } + + AddSeparator(message); + } + else if (operatedIndices.Size() >= 1) + { + UInt64 packSize = 0; + UInt64 unpackSize = 0; + UInt64 numFiles = 0; + UInt64 numDirs = 0; + + FOR_VECTOR (i, operatedIndices) + { + const UInt32 index = operatedIndices[i]; + unpackSize += GetItemSize(index); + packSize += GetItem_UInt64Prop(index, kpidPackSize); + if (IsItem_Folder(index)) + { + numDirs++; + numDirs += GetItem_UInt64Prop(index, kpidNumSubDirs); + numFiles += GetItem_UInt64Prop(index, kpidNumSubFiles); + } + else + numFiles++; + } + { + wchar_t temp[32]; + ConvertUInt32ToString(operatedIndices.Size(), temp); + AddPropertyPair(L"", MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, temp), message); + } + + if (numDirs != 0) + AddPropertyString(kpidNumSubDirs, numDirs, message); + if (numFiles != 0) + AddPropertyString(kpidNumSubFiles, numFiles, message); + AddPropertyString(kpidSize, unpackSize, message); + AddPropertyString(kpidPackSize, packSize, message); + + AddSeparator(message); + } + + + /* + AddLangString(message, IDS_PROP_FILE_TYPE); + message += kPropValueSeparator; + message += GetFolderTypeID(); + message.Add_LF(); + */ + + { + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) + { + AddPropertyString(kpidName, L"Path", prop, message); + } + } + + CMyComPtr folderProperties; + _folder.QueryInterface(IID_IFolderProperties, &folderProperties); + if (folderProperties) + { + UInt32 numProps; + if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) + { + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + } + + if (getFolderArcProps) + { + CMyComPtr getProps; + getFolderArcProps->GetFolderArcProps(&getProps); + if (getProps) + { + UInt32 numLevels; + if (getProps->GetArcNumLevels(&numLevels) != S_OK) + numLevels = 0; + for (UInt32 level2 = 0; level2 < numLevels; level2++) + { + { + UInt32 level = numLevels - 1 - level2; + UInt32 numProps; + if (getProps->GetArcNumProps(level, &numProps) == S_OK) + { + const int kNumSpecProps = Z7_ARRAY_SIZE(kSpecProps); + + AddSeparator(message); + + for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (i < 0) + propID = kSpecProps[i + kNumSpecProps]; + else if (getProps->GetArcPropInfo(level, (UInt32)i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (getProps->GetArcProp(level, propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + } + + if (level2 < numLevels - 1) + { + const UInt32 level = numLevels - 1 - level2; + UInt32 numProps; + if (getProps->GetArcNumProps2(level, &numProps) == S_OK) + { + AddSeparatorSmall(message); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (getProps->GetArcPropInfo2(level, i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (getProps->GetArcProp2(level, propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + } + } + + { + // we ERROR message for NonOpen level + bool needSep = true; + const int kNumSpecProps = Z7_ARRAY_SIZE(kSpecProps); + for (Int32 i = -(int)kNumSpecProps; i < 0; i++) + { + CMyComBSTR name; + const PROPID propID = kSpecProps[i + kNumSpecProps]; + NCOM::CPropVariant prop; + if (getProps->GetArcProp(numLevels, propID, &prop) != S_OK) + continue; + if (needSep) + { + AddSeparator(message); + AddSeparator(message); + needSep = false; + } + AddPropertyString(propID, name, prop, message); + } + } + + } + } + + message.Title = LangString(IDS_PROPERTIES); + message.NumColumns = 2; + message.Create(GetParent()); + } +} + + + +void CPanel::EditCut() +{ + // InvokeSystemCommand("cut"); +} + +void CPanel::EditCopy() +{ + /* + CMyComPtr getFolderArcProps; + _folder.QueryInterface(IID_IGetFolderArcProps, &getFolderArcProps); + if (!getFolderArcProps) + { + InvokeSystemCommand("copy"); + return; + } + */ + UString s; + CRecordVector indices; + Get_ItemIndices_Selected(indices); + FOR_VECTOR (i, indices) + { + if (i != 0) + s += "\xD\n"; + s += GetItemName(indices[i]); + } + ClipboardSetText(_mainWindow, s); +} + +void CPanel::EditPaste() +{ + /* + UStringVector names; + ClipboardGetFileNames(names); + CopyFromNoAsk(names); + UString s; + for (int i = 0; i < names.Size(); i++) + { + s += L' '; + s += names[i]; + } + + MessageBoxW(0, s, L"", 0); + */ + + // InvokeSystemCommand("paste"); +} + + + +struct CFolderPidls +{ + LPITEMIDLIST parent; + CRecordVector items; + + CFolderPidls(): parent(NULL) {} + ~CFolderPidls() + { + FOR_VECTOR (i, items) + CoTaskMemFree(items[i]); + CoTaskMemFree(parent); + } +}; + + +static HRESULT ShellFolder_ParseDisplayName(IShellFolder *shellFolder, + HWND hwnd, const UString &path, LPITEMIDLIST *ppidl) +{ + ULONG eaten = 0; + return shellFolder->ParseDisplayName(hwnd, NULL, + path.Ptr_non_const(), &eaten, ppidl, NULL); +} + + +HRESULT CPanel::CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + ODS("==== CPanel::CreateShellContextMenu"); + systemContextMenu.Release(); + UString folderPath = GetFsPath(); + + CMyComPtr desktopFolder; + RINOK(::SHGetDesktopFolder(&desktopFolder)) + if (!desktopFolder) + { + // ShowMessage("Failed to get Desktop folder"); + return E_FAIL; + } + + CFolderPidls pidls; + // NULL is allowed for parentHWND in ParseDisplayName() + const HWND parentHWND_for_ParseDisplayName = GetParent(); + // if (folderPath.IsEmpty()), then ParseDisplayName returns pidls of "My Computer" + /* win10: ParseDisplayName() supports folder path with tail slash + ParseDisplayName() returns { + E_INVALIDARG : path with super path prefix "\\\\?\\" + ERROR_FILE_NOT_FOUND : path for network share (\\server\path1\long path2") larger than MAX_PATH + } */ + const HRESULT res = ShellFolder_ParseDisplayName(desktopFolder, + parentHWND_for_ParseDisplayName, + folderPath, &pidls.parent); + if (res != S_OK) + { + ODS_U(folderPath); + if (res != E_INVALIDARG) + return res; + if (!NFile::NName::If_IsSuperPath_RemoveSuperPrefix(folderPath)) + return res; + RINOK(ShellFolder_ParseDisplayName(desktopFolder, + parentHWND_for_ParseDisplayName, + folderPath, &pidls.parent)) + } + if (!pidls.parent) + return E_FAIL; + + /* + UString path2; + NShell::GetPathFromIDList(pidls.parent, path2); + ODS_U(path2); + */ + + if (operatedIndices.IsEmpty()) + { + // how to get IContextMenu, if there are no selected files? + return E_FAIL; + + /* + xp64 : + 1) we can't use GetUIObjectOf() with (numItems == 0), it throws exception + 2) we can't use desktopFolder->GetUIObjectOf() with absolute pidls of folder + context menu items are different in that case: + "Open / Explorer" for folder + "Delete" for "My Computer" icon + "Preperties" for "System" + */ + /* + parentFolder = desktopFolder; + pidls.items.AddInReserved(pidls.parent); + pidls.parent = NULL; + */ + + // CreateViewObject() doesn't show all context menu items + /* + HRESULT res = parentFolder->CreateViewObject( + GetParent(), IID_IContextMenu, (void**)&systemContextMenu); + */ + } + + CMyComPtr parentFolder; + RINOK(desktopFolder->BindToObject(pidls.parent, + NULL, IID_IShellFolder, (void**)&parentFolder)) + if (!parentFolder) + return E_FAIL; + + ODS("==== CPanel::CreateShellContextMenu pidls START"); + + pidls.items.ClearAndReserve(operatedIndices.Size()); + UString fileName; + FOR_VECTOR (i, operatedIndices) + { + fileName.Empty(); + Add_ItemRelPath2_To_String(operatedIndices[i], fileName); + /* ParseDisplayName() in win10 returns: + E_INVALIDARG : if empty name, or path with dots only: "." , ".." + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) : if there is no such file + */ + LPITEMIDLIST pidl = NULL; + RINOK(ShellFolder_ParseDisplayName(parentFolder, + parentHWND_for_ParseDisplayName, + fileName, &pidl)) + if (!pidl) + return E_FAIL; + pidls.items.AddInReserved(pidl); + } + + ODS("==== CPanel::CreateShellContextMenu pidls END"); + // Get IContextMenu for items + RINOK(parentFolder->GetUIObjectOf(GetParent(), + pidls.items.Size(), (LPCITEMIDLIST *)(void *)pidls.items.ConstData(), + IID_IContextMenu, NULL, (void**)&systemContextMenu)) + ODS("==== CPanel::CreateShellContextMenu GetUIObjectOf finished"); + if (!systemContextMenu) + { + // ShowMessage("Unable to get context menu interface"); + return E_FAIL; + } + return S_OK; +} + + +// #define SHOW_DEBUG_FM_CTX_MENU + +#ifdef SHOW_DEBUG_FM_CTX_MENU + +static void PrintHex(UString &s, UInt32 v) +{ + char sz[32]; + ConvertUInt32ToHex(v, sz); + s += sz; +} + +static void PrintContextStr(UString &s, IContextMenu *ctxm, unsigned i, unsigned id, const char *name) +{ + s += " | "; + s += name; + s += ": "; + UString s1; + { + char buf[256]; + buf[0] = 0; + const HRESULT res = ctxm->GetCommandString(i, id, + NULL, buf, Z7_ARRAY_SIZE(buf) - 1); + if (res != S_OK) + { + PrintHex(s1, res); + s1.Add_Space(); + } + s1 += GetUnicodeString(buf); + } + UString s2; + { + wchar_t buf2[256]; + buf2[0] = 0; + const HRESULT res = ctxm->GetCommandString(i, id | GCS_UNICODE, + NULL, (char *)buf2, Z7_ARRAY_SIZE(buf2) - sizeof(wchar_t)); + if (res != S_OK) + { + PrintHex(s2, res); + s2.Add_Space(); + } + s2 += buf2; + } + s += s1; + if (s2.Compare(s1) != 0) + { + s += " Unicode: "; + s += s2; + } +} + +static void PrintAllContextItems(IContextMenu *ctxm, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + { + UString s; + s.Add_UInt32(i); + s += ": "; + PrintContextStr(s, ctxm, i, GCS_VALIDATEA, "valid"); + PrintContextStr(s, ctxm, i, GCS_VERBA, "verb"); + PrintContextStr(s, ctxm, i, GCS_HELPTEXTA, "helptext"); + OutputDebugStringW(s); + } +} + +#endif + + +void CPanel::CreateSystemMenu(HMENU menuSpec, + bool showExtendedVerbs, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + systemContextMenu.Release(); + + CreateShellContextMenu(operatedIndices, systemContextMenu); + + if (!systemContextMenu) + return; + + /* + // Set up a CMINVOKECOMMANDINFO structure. + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + */ + + /* + if (Sender == GoBtn) + { + // Verbs that can be used are cut, paste, + // properties, delete, and so on. + String action; + if (CutRb->Checked) + action = "cut"; + else if (CopyRb->Checked) + action = "copy"; + else if (DeleteRb->Checked) + action = "delete"; + else if (PropertiesRb->Checked) + action = "properties"; + + ci.lpVerb = action.c_str(); + result = cm->InvokeCommand(&ci); + if (result) + ShowMessage( + "Error copying file to clipboard."); + + } + else + */ + { + // HMENU hMenu = CreatePopupMenu(); + CMenu popupMenu; + CMenuDestroyer menuDestroyer(popupMenu); + if (!popupMenu.CreatePopup()) + throw 210503; + const HMENU hMenu = popupMenu; + DWORD flags = CMF_EXPLORE; + if (showExtendedVerbs) + flags |= Z7_WIN_CMF_EXTENDEDVERBS; + ODS("=== systemContextMenu->QueryContextMenu START"); + const HRESULT res = systemContextMenu->QueryContextMenu(hMenu, 0, kSystemStartMenuID, 0x7FFF, flags); + ODS("=== systemContextMenu->QueryContextMenu END"); + if (SUCCEEDED(res)) + { + #ifdef SHOW_DEBUG_FM_CTX_MENU + PrintAllContextItems(systemContextMenu, (unsigned)res); + #endif + + CMenu menu; + menu.Attach(menuSpec); + CMenuItem menuItem; + menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + menuItem.fType = MFT_STRING; + menuItem.hSubMenu = popupMenu.Detach(); + menuDestroyer.Disable(); + LangString(IDS_SYSTEM, menuItem.StringValue); + menu.InsertItem(0, true, menuItem); + } + /* + if (Cmd < 100 && Cmd != 0) + { + ci.lpVerb = MAKEINTRESOURCE(Cmd - 1); + ci.lpParameters = ""; + ci.lpDirectory = ""; + ci.nShow = SW_SHOWNORMAL; + cm->InvokeCommand(&ci); + } + // If Cmd is > 100 then it's one of our + // inserted menu items. + else + // Find the menu item. + for (int i = 0; i < popupMenu1->Items->Count; i++) + { + TMenuItem* menu = popupMenu1->Items->Items[i]; + // Call its OnClick handler. + if (menu->Command == Cmd - 100) + menu->OnClick(this); + } + // Release the memory allocated for the menu. + DestroyMenu(hMenu); + */ + } +} + +void CPanel::CreateFileMenu(HMENU menuSpec) +{ + CreateFileMenu(menuSpec, _sevenZipContextMenu, _systemContextMenu, true); // programMenu +} + +void CPanel::CreateSevenZipMenu(HMENU menuSpec, + bool showExtendedVerbs, + const CRecordVector &operatedIndices, + int firstDirIndex, + CMyComPtr &sevenZipContextMenu) +{ + sevenZipContextMenu.Release(); + + CMenu menu; + menu.Attach(menuSpec); + // CMenuDestroyer menuDestroyer(menu); + // menu.CreatePopup(); + + CZipContextMenu *contextMenuSpec = new CZipContextMenu; + CMyComPtr contextMenu = contextMenuSpec; + // if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK) + { + /* + CMyComPtr initContextMenu; + if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK) + return; + */ + ODS("=== FileName List Add START") + // for (unsigned y = 0; y < 10000; y++, contextMenuSpec->_fileNames.Clear()) + GetFilePaths(operatedIndices, contextMenuSpec->_fileNames); + ODS("=== FileName List Add END") + contextMenuSpec->Init_For_7zFM(); + contextMenuSpec->_attribs.FirstDirIndex = firstDirIndex; + { + DWORD flags = CMF_EXPLORE; + if (showExtendedVerbs) + flags |= Z7_WIN_CMF_EXTENDEDVERBS; + const HRESULT res = contextMenu->QueryContextMenu(menu, + 0, // indexMenu + kSevenZipStartMenuID, // first + kSystemStartMenuID - 1, // last + flags); + ODS("=== contextMenu->QueryContextMenu END") + const bool sevenZipMenuCreated = SUCCEEDED(res); + if (sevenZipMenuCreated) + { + // if (res != 0) + { + // some "non-good" implementation of QueryContextMenu() could add some items to menu, but it return 0. + // so we still allow these items + sevenZipContextMenu = contextMenu; + #ifdef SHOW_DEBUG_FM_CTX_MENU + PrintAllContextItems(contextMenu, (unsigned)res); + #endif + } + } + else + { + // MessageBox_Error_HRESULT_Caption(res, L"QueryContextMenu"); + } + // int code = HRESULT_CODE(res); + // int nextItemID = code; + } + } +} + +static bool IsReadOnlyFolder(IFolderFolder *folder) +{ + if (!folder) + return false; + + bool res = false; + { + NCOM::CPropVariant prop; + if (folder->GetFolderProperty(kpidReadOnly, &prop) == S_OK) + if (prop.vt == VT_BOOL) + res = VARIANT_BOOLToBool(prop.boolVal); + } + return res; +} + +bool CPanel::IsThereReadOnlyFolder() const +{ + if (!_folderOperations) + return true; + if (IsReadOnlyFolder(_folder)) + return true; + FOR_VECTOR (i, _parentFolders) + { + if (IsReadOnlyFolder(_parentFolders[i].ParentFolder)) + return true; + } + return false; +} + +bool CPanel::CheckBeforeUpdate(UINT resourceID) +{ + if (!_folderOperations) + { + MessageBox_Error_UnsupportOperation(); + // resourceID = resourceID; + // MessageBoxErrorForUpdate(E_NOINTERFACE, resourceID); + return false; + } + + for (int i = (int)_parentFolders.Size(); i >= 0; i--) + { + IFolderFolder *folder; + if (i == (int)_parentFolders.Size()) + folder = _folder; + else + folder = _parentFolders[i].ParentFolder; + + if (!IsReadOnlyFolder(folder)) + continue; + + UString s; + AddLangString(s, resourceID); + s.Add_LF(); + AddLangString(s, IDS_OPERATION_IS_NOT_SUPPORTED); + s.Add_LF(); + if (i == 0) + s += GetFolderPath(folder); + else + s += _parentFolders[i - 1].VirtualPath; + s.Add_LF(); + AddLangString(s, IDS_PROP_READ_ONLY); + MessageBox_Error(s); + return false; + } + + return true; +} + +void CPanel::CreateFileMenu(HMENU menuSpec, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu) +{ + sevenZipContextMenu.Release(); + systemContextMenu.Release(); + + const bool showExtendedVerbs = IsKeyDown(VK_SHIFT); + + CRecordVector operatedIndices; + Get_ItemIndices_Operated(operatedIndices); + const int firstDirIndex = FindDir_InOperatedList(operatedIndices); + + CMenu menu; + menu.Attach(menuSpec); + + if (!IsArcFolder()) + { + CreateSevenZipMenu(menu, showExtendedVerbs, operatedIndices, firstDirIndex, sevenZipContextMenu); + // CreateSystemMenu is very slow if you call it inside ZIP archive with big number of files + // Windows probably can parse items inside ZIP archive. + if (g_App.ShowSystemMenu) + CreateSystemMenu(menu, showExtendedVerbs, operatedIndices, systemContextMenu); + } + + /* + if (menu.GetItemCount() > 0) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)0); + */ + + CFileMenu fm; + + fm.readOnly = IsThereReadOnlyFolder(); + fm.isHashFolder = IsHashFolder(); + fm.isFsFolder = Is_IO_FS_Folder(); + fm.programMenu = programMenu; + fm.allAreFiles = (firstDirIndex == -1); + fm.numItems = operatedIndices.Size(); + + fm.isAltStreamsSupported = false; + + if (fm.numItems == 1) + fm.FilePath = us2fs(GetItemFullPath(operatedIndices[0])); + + if (_folderAltStreams) + { + if (operatedIndices.Size() <= 1) + { + UInt32 realIndex = (UInt32)(Int32)-1; + if (operatedIndices.Size() == 1) + realIndex = operatedIndices[0]; + Int32 val = 0; + if (_folderAltStreams->AreAltStreamsSupported(realIndex, &val) == S_OK) + fm.isAltStreamsSupported = IntToBool(val); + } + } + else + { + if (fm.numItems == 0) + fm.isAltStreamsSupported = IsFSFolder(); + else + fm.isAltStreamsSupported = IsFolder_with_FsItems(); + } + + fm.Load(menu, (unsigned)menu.GetItemCount()); +} + +bool CPanel::InvokePluginCommand(unsigned id) +{ + return InvokePluginCommand(id, _sevenZipContextMenu, _systemContextMenu); +} + +#if defined(_MSC_VER) && !defined(UNDER_CE) +#define use_CMINVOKECOMMANDINFOEX +/* CMINVOKECOMMANDINFOEX depends from (_WIN32_IE >= 0x0400) */ +#endif + +bool CPanel::InvokePluginCommand(unsigned id, + IContextMenu *sevenZipContextMenu, IContextMenu *systemContextMenu) +{ + UInt32 offset; + const bool isSystemMenu = (id >= kSystemStartMenuID); + if (isSystemMenu) + { + if (!systemContextMenu) + return false; + offset = id - kSystemStartMenuID; + } + else + { + if (!sevenZipContextMenu) + return false; + offset = id - kSevenZipStartMenuID; + } + + #ifdef use_CMINVOKECOMMANDINFOEX + CMINVOKECOMMANDINFOEX + #else + CMINVOKECOMMANDINFO + #endif + commandInfo; + + memset(&commandInfo, 0, sizeof(commandInfo)); + commandInfo.cbSize = sizeof(commandInfo); + + commandInfo.fMask = 0 + #ifdef use_CMINVOKECOMMANDINFOEX + | CMIC_MASK_UNICODE + #endif + ; + + commandInfo.hwnd = GetParent(); + commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset)); + commandInfo.lpParameters = NULL; + // 19.01: fixed CSysString to AString + // MSDN suggest to send NULL: lpDirectory: This member is always NULL for menu items inserted by a Shell extension. + const AString currentFolderA (GetAnsiString(_currentFolderPrefix)); + commandInfo.lpDirectory = (LPCSTR)(currentFolderA); + commandInfo.nShow = SW_SHOW; + + #ifdef use_CMINVOKECOMMANDINFOEX + + commandInfo.lpParametersW = NULL; + commandInfo.lpTitle = ""; + + /* + system ContextMenu handler supports ContextMenu subhandlers. + so InvokeCommand() converts (command_offset) from global number to subhandler number. + XP-64 / win10: + system ContextMenu converts (command_offset) in lpVerb only, + and it keeps lpVerbW unchanged. + also explorer.exe sends 0 in lpVerbW. + We try to keep compatibility with Windows Explorer here. + */ + commandInfo.lpVerbW = NULL; + + const UString currentFolderUnicode = _currentFolderPrefix; + commandInfo.lpDirectoryW = currentFolderUnicode; + commandInfo.lpTitleW = L""; + // commandInfo.ptInvoke.x = xPos; + // commandInfo.ptInvoke.y = yPos; + commandInfo.ptInvoke.x = 0; + commandInfo.ptInvoke.y = 0; + + #endif + + HRESULT result; + if (isSystemMenu) + result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + else + result = sevenZipContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + if (result == NOERROR) + { + KillSelection(); + return true; + } + else + MessageBox_Error_HRESULT_Caption(result, L"InvokeCommand"); + return false; +} + +bool CPanel::OnContextMenu(HANDLE windowHandle, int xPos, int yPos) +{ + if (::GetParent((HWND)windowHandle) == _listView) + { + ShowColumnsContextMenu(xPos, yPos); + return true; + } + + if (windowHandle != _listView) + return false; + /* + POINT point; + point.x = xPos; + point.y = yPos; + if (!_listView.ScreenToClient(&point)) + return false; + + LVHITTESTINFO info; + info.pt = point; + int index = _listView.HitTest(&info); + */ + + CRecordVector operatedIndices; + Get_ItemIndices_Operated(operatedIndices); + + // negative x,y are possible for multi-screen modes. + // x=-1 && y=-1 for keyboard call (SHIFT+F10 and others). + if (xPos == -1 && yPos == -1) + { + if (operatedIndices.Size() == 0) + { + xPos = 0; + yPos = 0; + } + else + { + int itemIndex = _listView.GetNextItem(-1, LVNI_FOCUSED); + if (itemIndex == -1) + return false; + RECT rect; + if (!_listView.GetItemRect(itemIndex, &rect, LVIR_ICON)) + return false; + xPos = (rect.left + rect.right) / 2; + yPos = (rect.top + rect.bottom) / 2; + } + POINT point = {xPos, yPos}; + _listView.ClientToScreen(&point); + xPos = point.x; + yPos = point.y; + } + + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + menu.CreatePopup(); + + CMyComPtr sevenZipContextMenu; + CMyComPtr systemContextMenu; + CreateFileMenu(menu, sevenZipContextMenu, systemContextMenu, false); // programMenu + + const unsigned id = (unsigned)menu.Track(TPM_LEFTALIGN + #ifndef UNDER_CE + | TPM_RIGHTBUTTON + #endif + | TPM_RETURNCMD | TPM_NONOTIFY, + xPos, yPos, _listView); + + if (id == 0) + return true; + + if (id >= kMenuCmdID_Plugin_Start) + { + InvokePluginCommand(id, sevenZipContextMenu, systemContextMenu); + return true; + } + if (ExecuteFileCommand(id)) + return true; + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelOperations.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelOperations.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelOperations.cpp 2015-06-22 21:09:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelOperations.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,547 +1,533 @@ -// PanelOperations.cpp - -#include "StdAfx.h" - -#include "../../../Common/DynamicBuffer.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/COM.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" - -#include "ComboDialog.h" - -#include "FSFolder.h" -#include "FormatUtils.h" -#include "LangUtils.h" -#include "Panel.h" -#include "UpdateCallback100.h" - -#include "resource.h" - -using namespace NWindows; -using namespace NFile; -using namespace NName; - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -enum EFolderOpType -{ - FOLDER_TYPE_CREATE_FOLDER = 0, - FOLDER_TYPE_DELETE = 1, - FOLDER_TYPE_RENAME = 2 -}; - -class CThreadFolderOperations: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - EFolderOpType OpType; - UString Name; - UInt32 Index; - CRecordVector Indices; - - CMyComPtr FolderOperations; - CMyComPtr UpdateCallback; - CUpdateCallback100Imp *UpdateCallbackSpec; - - HRESULT Result; - - CThreadFolderOperations(EFolderOpType opType): OpType(opType), Result(E_FAIL) {} - HRESULT DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError); -}; - -HRESULT CThreadFolderOperations::ProcessVirt() -{ - // FIXME NCOM::CComInitializer comInitializer; - switch(OpType) - { - case FOLDER_TYPE_CREATE_FOLDER: - Result = FolderOperations->CreateFolder(Name, UpdateCallback); - break; - case FOLDER_TYPE_DELETE: - Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback); - break; - case FOLDER_TYPE_RENAME: - Result = FolderOperations->Rename(Index, Name, UpdateCallback); - break; - default: - Result = E_FAIL; - } - return Result; -} - - -HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError) -{ - UpdateCallbackSpec = new CUpdateCallback100Imp; - UpdateCallback = UpdateCallbackSpec; - UpdateCallbackSpec->ProgressDialog = &ProgressDialog; - - // FIXME ProgressDialog.WaitMode = true; - ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError; - Result = S_OK; - - UpdateCallbackSpec->Init(); - - if (panel._parentFolders.Size() > 0) - { - const CFolderLink &fl = panel._parentFolders.Back(); - UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; - UpdateCallbackSpec->Password = fl.Password; - } - - - ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent() - ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - ProgressDialog.MainAddTitle = progressTitle + L' '; - - RINOK(Create(progressTitle, ProgressDialog.MainWindow)); - return Result; -} - -#ifndef _UNICODE -typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp); -#endif - -/* -void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID) -{ - if (errorCode == E_NOINTERFACE) - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - else - MessageBoxError(errorCode, LangString(resourceID)); -} -*/ - -void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin)) -{ - CDisableTimerProcessing disableTimerProcessing(*this); - CRecordVector indices; - GetOperatedItemIndices(indices); - if (indices.IsEmpty()) - return; - CSelectedState state; - SaveSelectedState(state); - - #ifndef UNDER_CE - // WM6 / SHFileOperationW doesn't ask user! So we use internal delete - if (IsFSFolder() && toRecycleBin) - { - bool useInternalDelete = false; - #ifndef _UNICODE - if (!g_IsNT) - { - CDynamicBuffer buffer; - FOR_VECTOR (i, indices) - { - const AString path = GetSystemString(GetItemFullPath(indices[i])); - buffer.AddData(path, path.Len() + 1); - } - *buffer.GetCurPtrAndGrow(1) = 0; - SHFILEOPSTRUCTA fo; - fo.hwnd = GetParent(); - fo.wFunc = FO_DELETE; - fo.pFrom = (const CHAR *)buffer; - fo.pTo = 0; - fo.fFlags = 0; - if (toRecycleBin) - fo.fFlags |= FOF_ALLOWUNDO; - // fo.fFlags |= FOF_NOCONFIRMATION; - // fo.fFlags |= FOF_NOERRORUI; - // fo.fFlags |= FOF_SILENT; - // fo.fFlags |= FOF_WANTNUKEWARNING; - fo.fAnyOperationsAborted = FALSE; - fo.hNameMappings = 0; - fo.lpszProgressTitle = 0; - /* int res = */ ::SHFileOperationA(&fo); - } - else - #endif - { - CDynamicBuffer buffer; - unsigned maxLen = 0; - const UString prefix = GetFsPath(); - FOR_VECTOR (i, indices) - { - // L"\\\\?\\") doesn't work here. - const UString path = prefix + GetItemRelPath2(indices[i]); - if (path.Len() > maxLen) - maxLen = path.Len(); - buffer.AddData(path, path.Len() + 1); - } - *buffer.GetCurPtrAndGrow(1) = 0; -#ifdef _WIN32 - if (maxLen >= MAX_PATH) - { - if (toRecycleBin) - { - MessageBoxErrorLang(IDS_ERROR_LONG_PATH_TO_RECYCLE); - return; - } - useInternalDelete = true; - } - else - { - SHFILEOPSTRUCTW fo; - fo.hwnd = GetParent(); - fo.wFunc = FO_DELETE; - fo.pFrom = (const WCHAR *)buffer; - fo.pTo = 0; - fo.fFlags = 0; - if (toRecycleBin) - fo.fFlags |= FOF_ALLOWUNDO; - fo.fAnyOperationsAborted = FALSE; - fo.hNameMappings = 0; - fo.lpszProgressTitle = 0; - // int res; - #ifdef _UNICODE - /* res = */ ::SHFileOperationW(&fo); - #else - SHFileOperationWP shFileOperationW = (SHFileOperationWP) - ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW"); - if (shFileOperationW == 0) - return; - /* res = */ shFileOperationW(&fo); - #endif - } -#else - // FIXME - how to use the recycle bin undex Gnome or KDE ? - useInternalDelete = true; -#endif - } - /* - if (fo.fAnyOperationsAborted) - MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); - */ - if (!useInternalDelete) - { - RefreshListCtrl(state); - return; - } - } - #endif - - // DeleteItemsInternal - - if (!CheckBeforeUpdate(IDS_ERROR_DELETING)) - return; - - UInt32 titleID, messageID; - UString messageParam; - if (indices.Size() == 1) - { - int index = indices[0]; - messageParam = GetItemRelPath2(index); - if (IsItem_Folder(index)) - { - titleID = IDS_CONFIRM_FOLDER_DELETE; - messageID = IDS_WANT_TO_DELETE_FOLDER; - } - else - { - titleID = IDS_CONFIRM_FILE_DELETE; - messageID = IDS_WANT_TO_DELETE_FILE; - } - } - else - { - titleID = IDS_CONFIRM_ITEMS_DELETE; - messageID = IDS_WANT_TO_DELETE_ITEMS; - messageParam = NumberToString(indices.Size()); - } - if (::MessageBoxW(GetParent(), MyFormatNew(messageID, messageParam), LangString(titleID), MB_OKCANCEL | MB_ICONQUESTION) != IDOK) - return; - - CDisableNotify disableNotify(*this); - { - CThreadFolderOperations op(FOLDER_TYPE_DELETE); - op.FolderOperations = _folderOperations; - op.Indices = indices; - op.DoOperation(*this, - LangString(IDS_DELETING), - LangString(IDS_ERROR_DELETING)); - } - RefreshTitleAlways(); - RefreshListCtrl(state); -} - -#ifdef _WIN32 -BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh) -{ - int realIndex = GetRealIndex(lpnmh->item); - if (realIndex == kParentIndex) - return TRUE; - if (IsThereReadOnlyFolder()) - return TRUE; - return FALSE; -} -#endif - -bool IsCorrectFsName(const UString &name) -{ - const UString lastPart = name.Ptr(name.ReverseFind_PathSepar() + 1); - return - lastPart != L"." && - lastPart != L".."; -} - -bool CorrectFsPath(const UString &relBase, const UString &path, UString &result); - -bool CPanel::CorrectFsPath(const UString &path2, UString &result) -{ - return ::CorrectFsPath(GetFsPath(), path2, result); -} - -#ifdef _WIN32 -BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) -{ - if (lpnmh->item.pszText == NULL) - return FALSE; - CDisableTimerProcessing disableTimerProcessing2(*this); - - if (!CheckBeforeUpdate(IDS_ERROR_RENAMING)) - return FALSE; - - UString newName = lpnmh->item.pszText; - if (!IsCorrectFsName(newName)) - { - MessageBoxError(E_INVALIDARG); - return FALSE; - } - - if (IsFSFolder()) - { - UString correctName; - if (!CorrectFsPath(newName, correctName)) - { - MessageBoxError(E_INVALIDARG); - return FALSE; - } - newName = correctName; - } - - SaveSelectedState(_selectedState); - - int realIndex = GetRealIndex(lpnmh->item); - if (realIndex == kParentIndex) - return FALSE; - const UString prefix = GetItemPrefix(realIndex); - - - CDisableNotify disableNotify(*this); - { - CThreadFolderOperations op(FOLDER_TYPE_RENAME); - op.FolderOperations = _folderOperations; - op.Index = realIndex; - op.Name = newName; - /* HRESULTres = */ op.DoOperation(*this, - LangString(IDS_RENAMING), - LangString(IDS_ERROR_RENAMING)); - // fixed in 9.26: we refresh list even after errors - // (it's more safe, since error can be at different stages, so list can be incorrect). - /* - if (res != S_OK) - return FALSE; - */ - } - - // Can't use RefreshListCtrl here. - // RefreshListCtrlSaveFocused(); - _selectedState.FocusedName = prefix + newName; - _selectedState.SelectFocused = true; - - // We need clear all items to disable GetText before Reload: - // number of items can change. - // _listView.DeleteAllItems(); - // But seems it can still call GetText (maybe for current item) - // so we can't delete items. - - _dontShowMode = true; - - PostMessage(kReLoadMessage); - return TRUE; -} -#endif - -bool Dlg_CreateFolder(HWND wnd, UString &destName); - -void CPanel::CreateFolder() -{ - if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR)) - return; - - CDisableTimerProcessing disableTimerProcessing2(*this); - CSelectedState state; - SaveSelectedState(state); - - UString newName; - if (!Dlg_CreateFolder(GetParent(), newName)) - return; - - if (!IsCorrectFsName(newName)) - { - MessageBoxError(E_INVALIDARG); - return; - } - - if (IsFSFolder()) - { - UString correctName; - if (!CorrectFsPath(newName, correctName)) - { - MessageBoxError(E_INVALIDARG); - return; - } - newName = correctName; - } - - HRESULT res; - CDisableNotify disableNotify(*this); - { - CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER); - op.FolderOperations = _folderOperations; - op.Name = newName; - res = op.DoOperation(*this, - LangString(IDS_CREATE_FOLDER), - LangString(IDS_CREATE_FOLDER_ERROR)); - /* - // fixed for 9.26: we must refresh always - if (res != S_OK) - return; - */ - } - if (res == S_OK) - { - int pos = newName.Find(WCHAR_PATH_SEPARATOR); - if (pos >= 0) - newName.DeleteFrom(pos); - if (!_mySelectMode) - state.SelectedNames.Clear(); - state.FocusedName = newName; - state.SelectFocused = true; - } - RefreshTitleAlways(); - RefreshListCtrl(state); -} - -void CPanel::CreateFile() -{ - if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR)) - return; - - CDisableTimerProcessing disableTimerProcessing2(*this); - CSelectedState state; - SaveSelectedState(state); - CComboDialog dlg; - LangString(IDS_CREATE_FILE, dlg.Title); - LangString(IDS_CREATE_FILE_NAME, dlg.Static); - LangString(IDS_CREATE_FILE_DEFAULT_NAME, dlg.Value); - - if (dlg.Create(GetParent()) != IDOK) - return; - - CDisableNotify disableNotify(*this); - - UString newName = dlg.Value; - - if (IsFSFolder()) - { - UString correctName; - if (!CorrectFsPath(newName, correctName)) - { - MessageBoxError(E_INVALIDARG); - return; - } - newName = correctName; - } - - HRESULT result = _folderOperations->CreateFile(newName, 0); - if (result != S_OK) - { - MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR)); - // MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR); - return; - } - int pos = newName.Find(WCHAR_PATH_SEPARATOR); - if (pos >= 0) - newName.DeleteFrom(pos); - if (!_mySelectMode) - state.SelectedNames.Clear(); - state.FocusedName = newName; - state.SelectFocused = true; - RefreshListCtrl(state); -} - -void CPanel::RenameFile() -{ - if (!CheckBeforeUpdate(IDS_ERROR_RENAMING)) - return; - int index = _listView.GetFocusedItem(); - if (index >= 0) - _listView.EditLabel(index); -} - -void CPanel::ChangeComment() -{ - if (!CheckBeforeUpdate(IDS_COMMENT)) - return; - CDisableTimerProcessing disableTimerProcessing2(*this); - int index = _listView.GetFocusedItem(); - if (index < 0) - return; - int realIndex = GetRealItemIndex(index); - if (realIndex == kParentIndex) - return; - CSelectedState state; - SaveSelectedState(state); - UString comment; - { - NCOM::CPropVariant propVariant; - if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK) - return; - if (propVariant.vt == VT_BSTR) - comment = propVariant.bstrVal; - else if (propVariant.vt != VT_EMPTY) - return; - } - UString name = GetItemRelPath2(realIndex); - CComboDialog dlg; - dlg.Title = name; - dlg.Title += L" : "; - AddLangString(dlg.Title, IDS_COMMENT); - dlg.Value = comment; - LangString(IDS_COMMENT2, dlg.Static); - if (dlg.Create(GetParent()) != IDOK) - return; - NCOM::CPropVariant propVariant = dlg.Value.Ptr(); - - CDisableNotify disableNotify(*this); - HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL); - if (result != S_OK) - { - if (result == E_NOINTERFACE) - MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - else - MessageBoxError(result, L"Set Comment Error"); - } - RefreshListCtrl(state); -} - -// From CPP/7zip/UI/FileManager/BrowseDialog.cpp -bool Dlg_CreateFolder(HWND wnd, UString &destName) -{ - destName.Empty(); - CComboDialog dlg; - LangString(IDS_CREATE_FOLDER, dlg.Title); - LangString(IDS_CREATE_FOLDER_NAME, dlg.Static); - LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value); - if (dlg.Create(wnd) != IDOK) - return false; - destName = dlg.Value; - return true; -} - +// PanelOperations.cpp + +#include "StdAfx.h" + +#include "../../../Common/DynamicBuffer.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/COM.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "ComboDialog.h" + +#include "FSFolder.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "Panel.h" +#include "UpdateCallback100.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +enum EFolderOpType +{ + FOLDER_TYPE_CREATE_FOLDER = 0, + FOLDER_TYPE_DELETE = 1, + FOLDER_TYPE_RENAME = 2 +}; + +class CThreadFolderOperations: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + EFolderOpType OpType; + UString Name; + UInt32 Index; + CRecordVector Indices; + + CMyComPtr FolderOperations; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + + CThreadFolderOperations(EFolderOpType opType): OpType(opType) {} + HRESULT DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError); +}; + +HRESULT CThreadFolderOperations::ProcessVirt() +{ + NCOM::CComInitializer comInitializer; + switch ((int)OpType) + { + case FOLDER_TYPE_CREATE_FOLDER: + return FolderOperations->CreateFolder(Name, UpdateCallback); + case FOLDER_TYPE_DELETE: + return FolderOperations->Delete(Indices.ConstData(), Indices.Size(), UpdateCallback); + case FOLDER_TYPE_RENAME: + return FolderOperations->Rename(Index, Name, UpdateCallback); + default: + return E_FAIL; + } +} + + +HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError) +{ + UpdateCallbackSpec = new CUpdateCallback100Imp; + UpdateCallback = UpdateCallbackSpec; + UpdateCallbackSpec->ProgressDialog = this; + + WaitMode = true; + Sync.FinalMessage.ErrorMessage.Title = titleError; + + UpdateCallbackSpec->Init(); + + if (!panel._parentFolders.IsEmpty()) + { + const CFolderLink &fl = panel._parentFolders.Back(); + UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; + UpdateCallbackSpec->Password = fl.Password; + } + + MainWindow = panel._mainWindow; // panel.GetParent() + MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + MainAddTitle = progressTitle + L' '; + + RINOK(Create(progressTitle, MainWindow)) + return Result; +} + +#ifndef _UNICODE +typedef int (WINAPI * Func_SHFileOperationW)(LPSHFILEOPSTRUCTW lpFileOp); +#endif + +/* +void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID) +{ + if (errorCode == E_NOINTERFACE) + MessageBox_Error_UnsupportOperation(); + else + MessageBox_Error_HRESULT_Caption(errorCode, LangString(resourceID)); +} +*/ + +void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin)) +{ + CDisableTimerProcessing disableTimerProcessing(*this); + CRecordVector indices; + Get_ItemIndices_Operated(indices); + if (indices.IsEmpty()) + return; + CSelectedState state; + SaveSelectedState(state); + + #ifndef UNDER_CE + // WM6 / SHFileOperationW doesn't ask user! So we use internal delete + if (IsFSFolder() && toRecycleBin) + { + bool useInternalDelete = false; + #ifndef _UNICODE + if (!g_IsNT) + { + CDynamicBuffer buffer; + FOR_VECTOR (i, indices) + { + const AString path (GetSystemString(GetItemFullPath(indices[i]))); + buffer.AddData(path, path.Len() + 1); + } + *buffer.GetCurPtrAndGrow(1) = 0; + SHFILEOPSTRUCTA fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const CHAR *)buffer; + fo.pTo = NULL; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + // fo.fFlags |= FOF_NOCONFIRMATION; + // fo.fFlags |= FOF_NOERRORUI; + // fo.fFlags |= FOF_SILENT; + // fo.fFlags |= FOF_WANTNUKEWARNING; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = NULL; + fo.lpszProgressTitle = NULL; + /* int res = */ ::SHFileOperationA(&fo); + } + else + #endif + { + CDynamicBuffer buffer; + unsigned maxLen = 0; + const UString prefix = GetFsPath(); + FOR_VECTOR (i, indices) + { + // L"\\\\?\\") doesn't work here. + const UString path = prefix + GetItemRelPath2(indices[i]); + if (path.Len() > maxLen) + maxLen = path.Len(); + buffer.AddData(path, path.Len() + 1); + } + *buffer.GetCurPtrAndGrow(1) = 0; + if (maxLen >= MAX_PATH) + { + if (toRecycleBin) + { + MessageBox_Error_LangID(IDS_ERROR_LONG_PATH_TO_RECYCLE); + return; + } + useInternalDelete = true; + } + else + { + SHFILEOPSTRUCTW fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const WCHAR *)buffer; + fo.pTo = NULL; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = NULL; + fo.lpszProgressTitle = NULL; + // int res; + #ifdef _UNICODE + /* res = */ ::SHFileOperationW(&fo); + #else +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + const + Func_SHFileOperationW + f_SHFileOperationW = Z7_GET_PROC_ADDRESS( + Func_SHFileOperationW, ::GetModuleHandleW(L"shell32.dll"), + "SHFileOperationW"); + if (!f_SHFileOperationW) + return; + /* res = */ f_SHFileOperationW(&fo); + #endif + } + } + /* + if (fo.fAnyOperationsAborted) + MessageBox_Error_HRESULT_Caption(result, LangString(IDS_ERROR_DELETING)); + */ + if (!useInternalDelete) + { + RefreshListCtrl(state); + return; + } + } + #endif + + // DeleteItemsInternal + + if (!CheckBeforeUpdate(IDS_ERROR_DELETING)) + return; + + UInt32 titleID, messageID; + UString messageParam; + if (indices.Size() == 1) + { + const unsigned index = indices[0]; + messageParam = GetItemRelPath2(index); + if (IsItem_Folder(index)) + { + titleID = IDS_CONFIRM_FOLDER_DELETE; + messageID = IDS_WANT_TO_DELETE_FOLDER; + } + else + { + titleID = IDS_CONFIRM_FILE_DELETE; + messageID = IDS_WANT_TO_DELETE_FILE; + } + } + else + { + titleID = IDS_CONFIRM_ITEMS_DELETE; + messageID = IDS_WANT_TO_DELETE_ITEMS; + messageParam = NumberToString(indices.Size()); + } + if (::MessageBoxW(GetParent(), MyFormatNew(messageID, messageParam), LangString(titleID), + MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) + return; + + CDisableNotify disableNotify(*this); + { + CThreadFolderOperations op(FOLDER_TYPE_DELETE); + op.FolderOperations = _folderOperations; + op.Indices = indices; + op.DoOperation(*this, + LangString(IDS_DELETING), + LangString(IDS_ERROR_DELETING)); + } + RefreshTitleAlways(); + RefreshListCtrl(state); +} + +BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh) +{ + const unsigned realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return TRUE; + if (IsThereReadOnlyFolder()) + return TRUE; + return FALSE; +} + +static bool IsCorrectFsName(const UString &name) +{ + const UString lastPart = name.Ptr((unsigned)(name.ReverseFind_PathSepar() + 1)); + return + !lastPart.IsEqualTo(".") && + !lastPart.IsEqualTo(".."); +} + +bool CorrectFsPath(const UString &relBase, const UString &path, UString &result); + +bool CPanel::CorrectFsPath(const UString &path2, UString &result) +{ + return ::CorrectFsPath(GetFsPath(), path2, result); +} + +BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) +{ + if (lpnmh->item.pszText == NULL) + return FALSE; + CDisableTimerProcessing disableTimerProcessing2(*this); + + if (!CheckBeforeUpdate(IDS_ERROR_RENAMING)) + return FALSE; + + UString newName = lpnmh->item.pszText; + if (!IsCorrectFsName(newName)) + { + MessageBox_Error_HRESULT(E_INVALIDARG); + return FALSE; + } + + if (IsFSFolder()) + { + UString correctName; + if (!CorrectFsPath(newName, correctName)) + { + MessageBox_Error_HRESULT(E_INVALIDARG); + return FALSE; + } + newName = correctName; + } + + SaveSelectedState(_selectedState); + + const unsigned realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return FALSE; + const UString prefix = GetItemPrefix(realIndex); + const UString oldName = GetItemName(realIndex); + + CDisableNotify disableNotify(*this); + { + CThreadFolderOperations op(FOLDER_TYPE_RENAME); + op.FolderOperations = _folderOperations; + op.Index = realIndex; + op.Name = newName; + const HRESULT res = op.DoOperation(*this, + LangString(IDS_RENAMING), + LangString(IDS_ERROR_RENAMING)); + // fixed in 9.26: we refresh list even after errors + // (it's more safe, since error can be at different stages, so list can be incorrect). + if (res == S_OK) + _selectedState.FocusedName = prefix + newName; + else + { + _selectedState.FocusedName = prefix + oldName; + // return FALSE; + } + } + + // Can't use RefreshListCtrl here. + // RefreshListCtrlSaveFocused(); + _selectedState.FocusedName_Defined = true; + _selectedState.SelectFocused = true; + + // We need clear all items to disable GetText before Reload: + // number of items can change. + // DeleteListItems(); + // But seems it can still call GetText (maybe for current item) + // so we can't delete items. + + _dontShowMode = true; + + PostMsg(kReLoadMessage); + return TRUE; +} + +bool Dlg_CreateFolder(HWND wnd, UString &destName); + +void CPanel::CreateFolder() +{ + if (IsHashFolder()) + return; + + if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR)) + return; + + CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + + UString newName; + if (!Dlg_CreateFolder(GetParent(), newName)) + return; + + if (!IsCorrectFsName(newName)) + { + MessageBox_Error_HRESULT(E_INVALIDARG); + return; + } + + if (IsFSFolder()) + { + UString correctName; + if (!CorrectFsPath(newName, correctName)) + { + MessageBox_Error_HRESULT(E_INVALIDARG); + return; + } + newName = correctName; + } + + HRESULT res; + CDisableNotify disableNotify(*this); + { + CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER); + op.FolderOperations = _folderOperations; + op.Name = newName; + res = op.DoOperation(*this, + LangString(IDS_CREATE_FOLDER), + LangString(IDS_CREATE_FOLDER_ERROR)); + /* + // fixed for 9.26: we must refresh always + if (res != S_OK) + return; + */ + } + if (res == S_OK) + { + int pos = newName.Find(WCHAR_PATH_SEPARATOR); + if (pos >= 0) + newName.DeleteFrom((unsigned)(pos)); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.FocusedName_Defined = true; + state.SelectFocused = true; + } + RefreshTitleAlways(); + RefreshListCtrl(state); +} + +void CPanel::CreateFile() +{ + if (IsHashFolder()) + return; + + if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR)) + return; + + CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + CComboDialog dlg; + LangString(IDS_CREATE_FILE, dlg.Title); + LangString(IDS_CREATE_FILE_NAME, dlg.Static); + LangString(IDS_CREATE_FILE_DEFAULT_NAME, dlg.Value); + + if (dlg.Create(GetParent()) != IDOK) + return; + + CDisableNotify disableNotify(*this); + + UString newName = dlg.Value; + + if (IsFSFolder()) + { + UString correctName; + if (!CorrectFsPath(newName, correctName)) + { + MessageBox_Error_HRESULT(E_INVALIDARG); + return; + } + newName = correctName; + } + + const HRESULT result = _folderOperations->CreateFile(newName, NULL); + if (result != S_OK) + { + MessageBox_Error_HRESULT_Caption(result, LangString(IDS_CREATE_FILE_ERROR)); + // MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR); + return; + } + const int pos = newName.Find(WCHAR_PATH_SEPARATOR); + if (pos >= 0) + newName.DeleteFrom((unsigned)pos); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.FocusedName_Defined = true; + state.SelectFocused = true; + RefreshListCtrl(state); +} + +void CPanel::RenameFile() +{ + if (!CheckBeforeUpdate(IDS_ERROR_RENAMING)) + return; + int index = _listView.GetFocusedItem(); + if (index >= 0) + _listView.EditLabel(index); +} + +void CPanel::ChangeComment() +{ + if (IsHashFolder()) + return; + if (!CheckBeforeUpdate(IDS_COMMENT)) + return; + CDisableTimerProcessing disableTimerProcessing2(*this); + const int index = _listView.GetFocusedItem(); + if (index < 0) + return; + const unsigned realIndex = GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + CSelectedState state; + SaveSelectedState(state); + UString comment; + { + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK) + return; + if (propVariant.vt == VT_BSTR) + comment = propVariant.bstrVal; + else if (propVariant.vt != VT_EMPTY) + return; + } + const UString name = GetItemRelPath2(realIndex); + CComboDialog dlg; + dlg.Title = name; + dlg.Title += " : "; + AddLangString(dlg.Title, IDS_COMMENT); + dlg.Value = comment; + LangString(IDS_COMMENT2, dlg.Static); + if (dlg.Create(GetParent()) != IDOK) + return; + NCOM::CPropVariant propVariant (dlg.Value); + + CDisableNotify disableNotify(*this); + const HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL); + if (result != S_OK) + { + if (result == E_NOINTERFACE) + MessageBox_Error_UnsupportOperation(); + else + MessageBox_Error_HRESULT_Caption(result, L"Set Comment Error"); + } + RefreshListCtrl(state); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSelect.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSelect.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSelect.cpp 2015-10-09 09:15:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSelect.cpp 2023-03-20 12:00:00.000000000 +0000 @@ -1,329 +1,317 @@ -// PanelSelect.cpp - -#include "StdAfx.h" - -#include "resource.h" - -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "ComboDialog.h" -#include "LangUtils.h" -#include "Panel.h" - -void CPanel::OnShiftSelectMessage() -{ - if (!_mySelectMode) - return; - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - if (!_selectionIsDefined) - return; - int startItem = MyMin(focusedItem, _prevFocusedItem); - int finishItem = MyMax(focusedItem, _prevFocusedItem); - - int numItems = _listView.GetItemCount(); - for (int i = 0; i < numItems; i++) - { - int realIndex = GetRealItemIndex(i); - if (realIndex == kParentIndex) - continue; - if (i >= startItem && i <= finishItem) - if (_selectedStatusVector[realIndex] != _selectMark) - { - printf("CPanel::OnShiftSelectMessage : __selectedStatusVector[%d]=%d => %d\n", - realIndex,_selectedStatusVector[realIndex] , _selectMark); - _selectedStatusVector[realIndex] = _selectMark; - _listView.RedrawItem(i); - } - } - - _prevFocusedItem = focusedItem; -} - -#ifdef _WIN32 -void CPanel::OnArrowWithShift() -{ - if (!_mySelectMode) - return; - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = GetRealItemIndex(focusedItem); - - if (_selectionIsDefined) - { - if (realIndex != kParentIndex) - _selectedStatusVector[realIndex] = _selectMark; - } - else - { - if (realIndex == kParentIndex) - { - _selectionIsDefined = true; - _selectMark = true; - } - else - { - _selectionIsDefined = true; - _selectMark = !_selectedStatusVector[realIndex]; - _selectedStatusVector[realIndex] = _selectMark; - } - } - - _prevFocusedItem = focusedItem; - PostMessage(kShiftSelectMessage); - _listView.RedrawItem(focusedItem); -} - -void CPanel::OnInsert() -{ - /* - const int kState = CDIS_MARKED; // LVIS_DROPHILITED; - UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ? - LVIS_CUT : 0; - _listView.SetItemState(focusedItem, state, LVIS_CUT); - // _listView.SetItemState_Selected(focusedItem); - - */ - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = GetRealItemIndex(focusedItem); - bool isSelected = !_selectedStatusVector[realIndex]; - if (realIndex != kParentIndex) - _selectedStatusVector[realIndex] = isSelected; - - if (!_mySelectMode) - _listView.SetItemState_Selected(focusedItem, isSelected); - - _listView.RedrawItem(focusedItem); - - int nextIndex = focusedItem + 1; - if (nextIndex < _listView.GetItemCount()) - { - _listView.SetItemState_FocusedSelected(nextIndex); - _listView.EnsureVisible(nextIndex, false); - } -} -#endif - -/* -void CPanel::OnUpWithShift() -{ - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int index = GetRealItemIndex(focusedItem); - _selectedStatusVector[index] = !_selectedStatusVector[index]; - _listView.RedrawItem(index); -} - -void CPanel::OnDownWithShift() -{ - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int index = GetRealItemIndex(focusedItem); - _selectedStatusVector[index] = !_selectedStatusVector[index]; - _listView.RedrawItem(index); -} -*/ - -void CPanel::UpdateSelection() -{ - if (!_mySelectMode) - { - bool enableTemp = _enableItemChangeNotify; - _enableItemChangeNotify = false; - int numItems = _listView.GetItemCount(); - for (int i = 0; i < numItems; i++) - { - int realIndex = GetRealItemIndex(i); - if (realIndex != kParentIndex) - _listView.SetItemState_Selected(i, _selectedStatusVector[realIndex]); - } - _enableItemChangeNotify = enableTemp; - } - _listView.RedrawAllItems(); -} - - -void CPanel::SelectSpec(bool selectMode) -{ - CComboDialog dlg; - LangString(selectMode ? IDS_SELECT : IDS_DESELECT, dlg.Title ); - LangString(IDS_SELECT_MASK, dlg.Static); - dlg.Value = L'*'; - if (dlg.Create(GetParent()) != IDOK) - return; - const UString &mask = dlg.Value; - FOR_VECTOR (i, _selectedStatusVector) - if (DoesWildcardMatchName(mask, GetItemName(i))) - { - printf("CPanel::SelectSpec : __selectedStatusVector[%d]=%d => %d\n", - i,_selectedStatusVector[i] , selectMode); - _selectedStatusVector[i] = selectMode; - } - UpdateSelection(); -} - -void CPanel::SelectByType(bool selectMode) -{ - int focusedItem = _listView.GetFocusedItem(); - if (focusedItem < 0) - return; - int realIndex = GetRealItemIndex(focusedItem); - UString name = GetItemName(realIndex); - bool isItemFolder = IsItem_Folder(realIndex); - - if (isItemFolder) - { - FOR_VECTOR (i, _selectedStatusVector) - if (IsItem_Folder(i) == isItemFolder) - { - printf("CPanel::SelectByType : __selectedStatusVector[%d]=%d => %d\n",i,_selectedStatusVector[i] , selectMode); - _selectedStatusVector[i] = selectMode; - } - } - else - { - int pos = name.ReverseFind_Dot(); - if (pos < 0) - { - FOR_VECTOR (i, _selectedStatusVector) - if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind_Dot() < 0) - { - printf("CPanel::SelectByType-2 : __selectedStatusVector[%d]=%d => %d\n",i,_selectedStatusVector[i] , selectMode); - _selectedStatusVector[i] = selectMode; - } - } - else - { - UString mask = L'*'; - mask += name.Ptr(pos); - FOR_VECTOR (i, _selectedStatusVector) - if (IsItem_Folder(i) == isItemFolder && DoesWildcardMatchName(mask, GetItemName(i))) - { - printf("CPanel::SelectByType-3 : __selectedStatusVector[%d]=%d => %d\n",i,_selectedStatusVector[i] , selectMode); - _selectedStatusVector[i] = selectMode; - } - } - } - - UpdateSelection(); -} - -void CPanel::SelectAll(bool selectMode) -{ - printf("CPanel::SelectAll\n"); - FOR_VECTOR (i, _selectedStatusVector) - _selectedStatusVector[i] = selectMode; - UpdateSelection(); -} - -void CPanel::InvertSelection() -{ - printf("CPanel::InvertSelection\n"); - if (!_mySelectMode) - { - unsigned numSelected = 0; - FOR_VECTOR (i, _selectedStatusVector) - if (_selectedStatusVector[i]) - numSelected++; - if (numSelected == 1) - { - int focused = _listView.GetFocusedItem(); - if (focused >= 0) - { - int realIndex = GetRealItemIndex(focused); - if (realIndex >= 0) - if (_selectedStatusVector[realIndex]) - _selectedStatusVector[realIndex] = false; - } - } - } - FOR_VECTOR (i, _selectedStatusVector) - _selectedStatusVector[i] = !_selectedStatusVector[i]; - UpdateSelection(); -} - -void CPanel::KillSelection() -{ - SelectAll(false); - if (!_mySelectMode) - { - int focused = _listView.GetFocusedItem(); - if (focused >= 0) - { - // CPanel::OnItemChanged notify for LVIS_SELECTED change doesn't work here. Why? - // so we change _selectedStatusVector[realIndex] here. - int realIndex = GetRealItemIndex(focused); - if (realIndex != kParentIndex) - { - printf("CPanel::KillSelection _selectedStatusVector[%d]=%d => true\n",realIndex,_selectedStatusVector[realIndex]); - - _selectedStatusVector[realIndex] = true; - } - _listView.SetItemState_Selected(focused); - } - } -} - -#ifdef _WIN32 -void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate) -{ - if (itemActivate->hdr.hwndFrom != HWND(_listView)) - return; - // It will work only for Version 4.71 (IE 4); - int indexInList = itemActivate->iItem; - if (indexInList < 0) - return; - - #ifndef UNDER_CE - if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0) - { - // int focusedIndex = _listView.GetFocusedItem(); - int focusedIndex = _startGroupSelect; - if (focusedIndex < 0) - return; - int startItem = MyMin(focusedIndex, indexInList); - int finishItem = MyMax(focusedIndex, indexInList); - - int numItems = _listView.GetItemCount(); - for (int i = 0; i < numItems; i++) - { - int realIndex = GetRealItemIndex(i); - if (realIndex == kParentIndex) - continue; - bool selected = (i >= startItem && i <= finishItem); - if (_selectedStatusVector[realIndex] != selected) - { - _selectedStatusVector[realIndex] = selected; - _listView.RedrawItem(i); - } - } - } - else - #endif - { - _startGroupSelect = indexInList; - - #ifndef UNDER_CE - if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0) - { - int realIndex = GetRealItemIndex(indexInList); - if (realIndex != kParentIndex) - { - _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex]; - _listView.RedrawItem(indexInList); - } - } - #endif - } - - return; -} -#endif - +// PanelSelect.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "ComboDialog.h" +#include "LangUtils.h" +#include "Panel.h" + +void CPanel::OnShiftSelectMessage() +{ + if (!_mySelectMode) + return; + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + if (!_selectionIsDefined) + return; + int startItem = MyMin(focusedItem, _prevFocusedItem); + int finishItem = MyMax(focusedItem, _prevFocusedItem); + + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + const unsigned realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + if (i >= startItem && i <= finishItem) + if (_selectedStatusVector[realIndex] != _selectMark) + { + _selectedStatusVector[realIndex] = _selectMark; + _listView.RedrawItem(i); + } + } + + _prevFocusedItem = focusedItem; +} + +void CPanel::OnArrowWithShift() +{ + if (!_mySelectMode) + return; + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = GetRealItemIndex(focusedItem); + + if (_selectionIsDefined) + { + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = _selectMark; + } + else + { + if (realIndex == kParentIndex) + { + _selectionIsDefined = true; + _selectMark = true; + } + else + { + _selectionIsDefined = true; + _selectMark = !_selectedStatusVector[realIndex]; + _selectedStatusVector[realIndex] = _selectMark; + } + } + + _prevFocusedItem = focusedItem; + PostMsg(kShiftSelectMessage); + _listView.RedrawItem(focusedItem); +} + +void CPanel::OnInsert() +{ + /* + const int kState = CDIS_MARKED; // LVIS_DROPHILITED; + UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ? + LVIS_CUT : 0; + _listView.SetItemState(focusedItem, state, LVIS_CUT); + // _listView.SetItemState_Selected(focusedItem); + */ + + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + + const unsigned realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + { + bool isSelected = !_selectedStatusVector[realIndex]; + _selectedStatusVector[realIndex] = isSelected; + if (!_mySelectMode) + _listView.SetItemState_Selected(focusedItem, isSelected); + _listView.RedrawItem(focusedItem); + } + + int nextIndex = focusedItem + 1; + if (nextIndex < _listView.GetItemCount()) + { + _listView.SetItemState_FocusedSelected(nextIndex); + _listView.EnsureVisible(nextIndex, false); + } +} + +/* +void CPanel::OnUpWithShift() +{ + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const int index = GetRealItemIndex(focusedItem); + if (index == kParentIndex) + return; + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} + +void CPanel::OnDownWithShift() +{ + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const int index = GetRealItemIndex(focusedItem); + if (index == kParentIndex) + return; + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} +*/ + +void CPanel::UpdateSelection() +{ + if (!_mySelectMode) + { + bool enableTemp = _enableItemChangeNotify; + _enableItemChangeNotify = false; + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + const unsigned realIndex = GetRealItemIndex(i); + if (realIndex != kParentIndex) + _listView.SetItemState_Selected(i, _selectedStatusVector[realIndex]); + } + _enableItemChangeNotify = enableTemp; + } + _listView.RedrawAllItems(); +} + + +void CPanel::SelectSpec(bool selectMode) +{ + CComboDialog dlg; + LangString(selectMode ? IDS_SELECT : IDS_DESELECT, dlg.Title ); + LangString(IDS_SELECT_MASK, dlg.Static); + dlg.Value = '*'; + if (dlg.Create(GetParent()) != IDOK) + return; + const UString &mask = dlg.Value; + FOR_VECTOR (i, _selectedStatusVector) + if (DoesWildcardMatchName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::SelectByType(bool selectMode) +{ + const int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + const unsigned realIndex = GetRealItemIndex(focusedItem); + UString name = GetItemName(realIndex); + bool isItemFolder = IsItem_Folder(realIndex); + + if (isItemFolder) + { + FOR_VECTOR (i, _selectedStatusVector) + if (IsItem_Folder(i) == isItemFolder) + _selectedStatusVector[i] = selectMode; + } + else + { + int pos = name.ReverseFind_Dot(); + if (pos < 0) + { + FOR_VECTOR (i, _selectedStatusVector) + if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind_Dot() < 0) + _selectedStatusVector[i] = selectMode; + } + else + { + UString mask ('*'); + mask += name.Ptr((unsigned)pos); + FOR_VECTOR (i, _selectedStatusVector) + if (IsItem_Folder(i) == isItemFolder && DoesWildcardMatchName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + } + } + + UpdateSelection(); +} + +void CPanel::SelectAll(bool selectMode) +{ + FOR_VECTOR (i, _selectedStatusVector) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::InvertSelection() +{ + if (!_mySelectMode) + { + /* + unsigned numSelected = 0; + FOR_VECTOR (i, _selectedStatusVector) + if (_selectedStatusVector[i]) + numSelected++; + */ + // 17.02: fixed : now we invert item even, if single item is selected + /* + if (numSelected == 1) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + { + const unsigned realIndex = GetRealItemIndex(focused); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + _selectedStatusVector[realIndex] = false; + } + } + */ + } + FOR_VECTOR (i, _selectedStatusVector) + _selectedStatusVector[i] = !_selectedStatusVector[i]; + UpdateSelection(); +} + +void CPanel::KillSelection() +{ + SelectAll(false); + // ver 20.01: now we don't like that focused will be selected item. + // So the following code was disabled: + /* + if (!_mySelectMode) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + { + // CPanel::OnItemChanged notify for LVIS_SELECTED change doesn't work here. Why? + // so we change _selectedStatusVector[realIndex] here. + const unsigned realIndex = GetRealItemIndex(focused); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; + _listView.SetItemState_Selected(focused); + } + } + */ +} + +void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate) +{ + if (itemActivate->hdr.hwndFrom != HWND(_listView)) + return; + // It will work only for Version 4.71 (IE 4); + int indexInList = itemActivate->iItem; + if (indexInList < 0) + return; + + #ifndef UNDER_CE + if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0) + { + // int focusedIndex = _listView.GetFocusedItem(); + const int focusedIndex = _startGroupSelect; + if (focusedIndex < 0) + return; + const int startItem = MyMin(focusedIndex, indexInList); + const int finishItem = MyMax(focusedIndex, indexInList); + + const int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + const unsigned realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + const bool selected = (i >= startItem && i <= finishItem); + if (_selectedStatusVector[realIndex] != selected) + { + _selectedStatusVector[realIndex] = selected; + _listView.RedrawItem(i); + } + } + } + else + #endif + { + _startGroupSelect = indexInList; + + #ifndef UNDER_CE + if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0) + { + const unsigned realIndex = GetRealItemIndex(indexInList); + if (realIndex != kParentIndex) + { + _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex]; + _listView.RedrawItem(indexInList); + } + } + #endif + } + + return; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSort.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSort.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSort.cpp 2015-06-22 19:45:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSort.cpp 2023-01-19 20:00:00.000000000 +0000 @@ -1,286 +1,269 @@ -// PanelSort.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" -#include "../../../Windows/PropVariant.h" - -#include "../../PropID.h" - -#include "Panel.h" - -using namespace NWindows; - -int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2) -{ - for (;;) - { - wchar_t c1 = *s1; - wchar_t c2 = *s2; - if ((c1 >= '0' && c1 <= '9') && - (c2 >= '0' && c2 <= '9')) - { - for (; *s1 == '0'; s1++); - for (; *s2 == '0'; s2++); - size_t len1 = 0; - size_t len2 = 0; - for (; (s1[len1] >= '0' && s1[len1] <= '9'); len1++); - for (; (s2[len2] >= '0' && s2[len2] <= '9'); len2++); - if (len1 < len2) return -1; - if (len1 > len2) return 1; - for (; len1 > 0; s1++, s2++, len1--) - { - if (*s1 == *s2) continue; - return (*s1 < *s2) ? -1 : 1; - } - c1 = *s1; - c2 = *s2; - } - s1++; - s2++; - if (c1 != c2) - { - // Probably we need to change the order for special characters like in Explorer. - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); - if (u1 < u2) return -1; - if (u1 > u2) return 1; - } - if (c1 == 0) return 0; - } -} - -static int CompareFileNames_Le16(const Byte *s1, unsigned size1, const Byte *s2, unsigned size2) -{ - size1 &= ~1; - size2 &= ~1; - for (unsigned i = 0;; i += 2) - { - if (i >= size1) - return (i >= size2) ? 0 : -1; - if (i >= size2) - return 1; - UInt16 c1 = GetUi16(s1 + i); - UInt16 c2 = GetUi16(s2 + i); - if (c1 == c2) - { - if (c1 == 0) - return 0; - continue; - } - if (c1 < c2) - return -1; - return 1; - } -} - -static inline const wchar_t *GetExtensionPtr(const UString &name) -{ - int dotPos = name.ReverseFind_Dot(); - return name.Ptr((dotPos < 0) ? name.Len() : dotPos); -} - -void CPanel::SetSortRawStatus() -{ - _isRawSortProp = false; - FOR_VECTOR (i, _properties) - { - const CItemProperty &prop = _properties[i]; - if (prop.ID == _sortID) - { - _isRawSortProp = prop.IsRawProp ? 1 : 0; - return; - } - } -} - - -int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) -{ - if (lpData == 0) - return 0; - CPanel *panel = (CPanel*)lpData; - - - PROPID propID = panel->_sortID; - - if (propID == kpidNoProperty) - return MyCompare(lParam1, lParam2); - - if (panel->_isRawSortProp) - { - // Sha1, NtSecurity, NtReparse - const void *data1; - const void *data2; - UInt32 dataSize1; - UInt32 dataSize2; - UInt32 propType1; - UInt32 propType2; - if (panel->_folderRawProps->GetRawProp((UInt32)lParam1, propID, &data1, &dataSize1, &propType1) != 0) return 0; - if (panel->_folderRawProps->GetRawProp((UInt32)lParam2, propID, &data2, &dataSize2, &propType2) != 0) return 0; - if (dataSize1 == 0) - return (dataSize2 == 0) ? 0 : -1; - if (dataSize2 == 0) - return 1; - if (propType1 != NPropDataType::kRaw) return 0; - if (propType2 != NPropDataType::kRaw) return 0; -#ifdef _WIN32 - if (propID == kpidNtReparse) - { - NFile::CReparseShortInfo r1; r1.Parse((const Byte *)data1, dataSize1); - NFile::CReparseShortInfo r2; r2.Parse((const Byte *)data2, dataSize2); - return CompareFileNames_Le16( - (const Byte *)data1 + r1.Offset, r1.Size, - (const Byte *)data2 + r2.Offset, r2.Size); - } -#endif - } - - if (panel->_folderCompare) - return panel->_folderCompare->CompareItems((UInt32)lParam1, (UInt32)lParam2, propID, panel->_isRawSortProp); - - switch (propID) - { - // if (panel->_sortIndex == 0) - case kpidName: - { - const UString name1 = panel->GetItemName((int)lParam1); - const UString name2 = panel->GetItemName((int)lParam2); - int res = CompareFileNames_ForFolderList(name1, name2); - /* - if (res != 0 || !panel->_flatMode) - return res; - const UString prefix1 = panel->GetItemPrefix(lParam1); - const UString prefix2 = panel->GetItemPrefix(lParam2); - return res = CompareFileNames_ForFolderList(prefix1, prefix2); - */ - return res; - } - case kpidExtension: - { - const UString name1 = panel->GetItemName((int)lParam1); - const UString name2 = panel->GetItemName((int)lParam2); - return CompareFileNames_ForFolderList( - GetExtensionPtr(name1), - GetExtensionPtr(name2)); - } - } - /* - if (panel->_sortIndex == 1) - return MyCompare(file1.Size, file2.Size); - return ::CompareFileTime(&file1.MTime, &file2.MTime); - */ - - // PROPID propID = panel->_properties[panel->_sortIndex].ID; - - NCOM::CPropVariant prop1, prop2; - // Name must be first property - panel->_folder->GetProperty((UInt32)lParam1, propID, &prop1); - panel->_folder->GetProperty((UInt32)lParam2, propID, &prop2); - if (prop1.vt != prop2.vt) - { - return MyCompare(prop1.vt, prop2.vt); - } - if (prop1.vt == VT_BSTR) - { - return _wcsicmp(prop1.bstrVal, prop2.bstrVal); - } - return prop1.Compare(prop2); - // return 0; -} - -int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) -{ - if (lpData == 0) return 0; - if (lParam1 == kParentIndex) return -1; - if (lParam2 == kParentIndex) return 1; - - CPanel *panel = (CPanel*)lpData; - - bool isDir1 = panel->IsItem_Folder((int)lParam1); - bool isDir2 = panel->IsItem_Folder((int)lParam2); - - if (isDir1 && !isDir2) return -1; - if (isDir2 && !isDir1) return 1; - - int result = CompareItems2(lParam1, lParam2, lpData); - return panel->_ascending ? result: (-result); -} - -int -#if defined(__WIN32__) && !defined(__WXMICROWIN__) // FIXME - wxCALLBACK -#endif - CompareItems_WX(long item1, long item2, long sortData) -{ - return CompareItems(item1,item2,sortData); -} - - -/* -void CPanel::SortItems(int index) -{ - if (index == _sortIndex) - _ascending = !_ascending; - else - { - _sortIndex = index; - _ascending = true; - switch (_properties[_sortIndex].ID) - { - case kpidSize: - case kpidPackedSize: - case kpidCTime: - case kpidATime: - case kpidMTime: - _ascending = false; - break; - } - } - _listView.SortItems(CompareItems, (LPARAM)this); - _listView.EnsureVisible(_listView.GetFocusedItem(), false); -} -void CPanel::SortItemsWithPropID(PROPID propID) -{ - int index = _properties.FindItemWithID(propID); - if (index >= 0) - SortItems(index); -} -*/ -void CPanel::SortItemsWithPropID(PROPID propID) -{ - if (propID == _sortID) - _ascending = !_ascending; - else - { - _sortID = propID; - _ascending = true; - switch (propID) - { - case kpidSize: - case kpidPackSize: - case kpidCTime: - case kpidATime: - case kpidMTime: - _ascending = false; - break; - } - } - SetSortRawStatus(); - if (sizeof(long) != sizeof(LPARAM)) { - printf("INTERNAL ERROR : sizeof(long) != sizeof(LPARAM)\n"); - exit(-1); - } - _listView.SortItems(CompareItems_WX, (LPARAM)this); // FIXED _listView.SortItems(CompareItems, (LPARAM)this); - _listView.EnsureVisible(_listView.GetFocusedItem(), false); -} - - -void CPanel::OnColumnClick(LPNMLISTVIEW info) -{ - /* - int index = _properties.FindItemWithID(_visibleProperties[info->iSubItem].ID); - SortItems(index); - */ - SortItemsWithPropID(_visibleProperties[info->iSubItem].ID); -} +// PanelSort.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#include "Panel.h" + +using namespace NWindows; + +int CompareFileNames_ForFolderList(const wchar_t *s1, const wchar_t *s2) +{ + for (;;) + { + wchar_t c1 = *s1; + wchar_t c2 = *s2; + if ((c1 >= '0' && c1 <= '9') && + (c2 >= '0' && c2 <= '9')) + { + for (; *s1 == '0'; s1++); + for (; *s2 == '0'; s2++); + size_t len1 = 0; + size_t len2 = 0; + for (; (s1[len1] >= '0' && s1[len1] <= '9'); len1++); + for (; (s2[len2] >= '0' && s2[len2] <= '9'); len2++); + if (len1 < len2) return -1; + if (len1 > len2) return 1; + for (; len1 > 0; s1++, s2++, len1--) + { + if (*s1 == *s2) continue; + return (*s1 < *s2) ? -1 : 1; + } + c1 = *s1; + c2 = *s2; + } + s1++; + s2++; + if (c1 != c2) + { + // Probably we need to change the order for special characters like in Explorer. + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +static int CompareFileNames_Le16(const Byte *s1, unsigned size1, const Byte *s2, unsigned size2) +{ + size1 &= ~1u; + size2 &= ~1u; + for (unsigned i = 0;; i += 2) + { + if (i >= size1) + return (i >= size2) ? 0 : -1; + if (i >= size2) + return 1; + UInt16 c1 = GetUi16(s1 + i); + UInt16 c2 = GetUi16(s2 + i); + if (c1 == c2) + { + if (c1 == 0) + return 0; + continue; + } + if (c1 < c2) + return -1; + return 1; + } +} + +static inline const wchar_t *GetExtensionPtr(const UString &name) +{ + const int dotPos = name.ReverseFind_Dot(); + return name.Ptr(dotPos < 0 ? name.Len() : (unsigned)dotPos); +} + +void CPanel::SetSortRawStatus() +{ + _isRawSortProp = false; + FOR_VECTOR (i, _columns) + { + const CPropColumn &prop = _columns[i]; + if (prop.ID == _sortID) + { + _isRawSortProp = prop.IsRawProp ? 1 : 0; + return; + } + } +} + + +static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if (lpData == 0) + return 0; + CPanel *panel = (CPanel*)lpData; + + + PROPID propID = panel->_sortID; + + if (propID == kpidNoProperty) + return MyCompare(lParam1, lParam2); + + if (panel->_isRawSortProp) + { + // Sha1, NtSecurity, NtReparse + const void *data1; + const void *data2; + UInt32 dataSize1; + UInt32 dataSize2; + UInt32 propType1; + UInt32 propType2; + if (panel->_folderRawProps->GetRawProp((UInt32)lParam1, propID, &data1, &dataSize1, &propType1) != 0) return 0; + if (panel->_folderRawProps->GetRawProp((UInt32)lParam2, propID, &data2, &dataSize2, &propType2) != 0) return 0; + if (dataSize1 == 0) + return (dataSize2 == 0) ? 0 : -1; + if (dataSize2 == 0) + return 1; + if (propType1 != NPropDataType::kRaw) return 0; + if (propType2 != NPropDataType::kRaw) return 0; + if (propID == kpidNtReparse) + { + NFile::CReparseShortInfo r1; r1.Parse((const Byte *)data1, dataSize1); + NFile::CReparseShortInfo r2; r2.Parse((const Byte *)data2, dataSize2); + return CompareFileNames_Le16( + (const Byte *)data1 + r1.Offset, r1.Size, + (const Byte *)data2 + r2.Offset, r2.Size); + } + } + + if (panel->_folderCompare) + return panel->_folderCompare->CompareItems((UInt32)lParam1, (UInt32)lParam2, propID, panel->_isRawSortProp); + + switch (propID) + { + // if (panel->_sortIndex == 0) + case kpidName: + { + const UString name1 = panel->GetItemName((unsigned)lParam1); + const UString name2 = panel->GetItemName((unsigned)lParam2); + const int res = CompareFileNames_ForFolderList(name1, name2); + /* + if (res != 0 || !panel->_flatMode) + return res; + const UString prefix1 = panel->GetItemPrefix(lParam1); + const UString prefix2 = panel->GetItemPrefix(lParam2); + return res = CompareFileNames_ForFolderList(prefix1, prefix2); + */ + return res; + } + case kpidExtension: + { + const UString name1 = panel->GetItemName((unsigned)lParam1); + const UString name2 = panel->GetItemName((unsigned)lParam2); + return CompareFileNames_ForFolderList( + GetExtensionPtr(name1), + GetExtensionPtr(name2)); + } + } + /* + if (panel->_sortIndex == 1) + return MyCompare(file1.Size, file2.Size); + return ::CompareFileTime(&file1.MTime, &file2.MTime); + */ + + // PROPID propID = panel->_columns[panel->_sortIndex].ID; + + NCOM::CPropVariant prop1, prop2; + // Name must be first property + panel->_folder->GetProperty((UInt32)lParam1, propID, &prop1); + panel->_folder->GetProperty((UInt32)lParam2, propID, &prop2); + if (prop1.vt != prop2.vt) + return MyCompare(prop1.vt, prop2.vt); + if (prop1.vt == VT_BSTR) + return MyStringCompareNoCase(prop1.bstrVal, prop2.bstrVal); + return prop1.Compare(prop2); +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if (lpData == 0) return 0; + if (lParam1 == (int)kParentIndex) return -1; + if (lParam2 == (int)kParentIndex) return 1; + + CPanel *panel = (CPanel*)lpData; + + const bool isDir1 = panel->IsItem_Folder((unsigned)lParam1); + const bool isDir2 = panel->IsItem_Folder((unsigned)lParam2); + + if (isDir1 && !isDir2) return -1; + if (isDir2 && !isDir1) return 1; + + const int result = CompareItems2(lParam1, lParam2, lpData); + return panel->_ascending ? result: (-result); +} + + +/* +void CPanel::SortItems(int index) +{ + if (index == _sortIndex) + _ascending = !_ascending; + else + { + _sortIndex = index; + _ascending = true; + switch (_columns[_sortIndex].ID) + { + case kpidSize: + case kpidPackedSize: + case kpidCTime: + case kpidATime: + case kpidMTime: + _ascending = false; + break; + } + } + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + +void CPanel::SortItemsWithPropID(PROPID propID) +{ + int index = _columns.FindItem_for_PropID(propID); + if (index >= 0) + SortItems(index); +} +*/ + +void CPanel::SortItemsWithPropID(PROPID propID) +{ + if (propID == _sortID) + _ascending = !_ascending; + else + { + _sortID = propID; + _ascending = true; + switch (propID) + { + case kpidSize: + case kpidPackSize: + case kpidCTime: + case kpidATime: + case kpidMTime: + _ascending = false; + break; + } + } + SetSortRawStatus(); + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + + +void CPanel::OnColumnClick(LPNMLISTVIEW info) +{ + /* + int index = _columns.FindItem_for_PropID(_visibleColumns[info->iSubItem].ID); + SortItems(index); + */ + SortItemsWithPropID(_visibleColumns[info->iSubItem].ID); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSplitFile.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSplitFile.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PanelSplitFile.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PanelSplitFile.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,489 +1,562 @@ -// PanelSplitFile.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/FileName.h" - -#include "../GUI/ExtractRes.h" - -#include "resource.h" - -#include "App.h" -#include "CopyDialog.h" -#include "FormatUtils.h" -#include "LangUtils.h" -#include "SplitDialog.h" -#include "SplitUtils.h" - -#include "PropertyNameRes.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static const wchar_t *g_Message_FileWriteError = L"File write error"; - -struct CVolSeqName -{ - UString UnchangedPart; - UString ChangedPart; - CVolSeqName(): ChangedPart(L"000") {}; - - void SetNumDigits(UInt64 numVolumes) - { - ChangedPart = L"000"; - while (numVolumes > 999) - { - numVolumes /= 10; - ChangedPart += L'0'; - } - } - - bool ParseName(const UString &name) - { - if (name.Len() < 2) - return false; - if (name.Back() != L'1' || name[name.Len() - 2] != L'0') - return false; - - unsigned pos = name.Len() - 2; - for (; pos > 0 && name[pos - 1] == '0'; pos--); - UnchangedPart.SetFrom(name, pos); - ChangedPart = name.Ptr(pos); - return true; - } - - UString GetNextName(); -}; - - -UString CVolSeqName::GetNextName() -{ - for (int i = (int)ChangedPart.Len() - 1; i >= 0; i--) - { - wchar_t c = ChangedPart[i]; - if (c != L'9') - { - ChangedPart.ReplaceOneCharAtPos(i, (wchar_t)(c + 1)); - break; - } - ChangedPart.ReplaceOneCharAtPos(i, L'0'); - if (i == 0) - ChangedPart.InsertAtFront(L'1'); - } - return UnchangedPart + ChangedPart; -} - -static const UInt32 kBufSize = (1 << 20); - -class CThreadSplit: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - FString FilePath; - FString VolBasePath; - UInt64 NumVolumes; - CRecordVector VolumeSizes; -}; - -HRESULT CThreadSplit::ProcessVirt() -{ - NIO::CInFile inFile; - if (!inFile.Open(FilePath)) - return GetLastError(); - NIO::COutFile outFile; - CMyBuffer bufferObject; - if (!bufferObject.Allocate(kBufSize)) - return E_OUTOFMEMORY; - Byte *buffer = (Byte *)(void *)bufferObject; - UInt64 curVolSize = 0; - CVolSeqName seqName; - seqName.SetNumDigits(NumVolumes); - UInt64 length; - if (!inFile.GetLength(length)) - return GetLastError(); - - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_NumBytesTotal(length); - UInt64 pos = 0; - - UInt64 numFiles = 0; - unsigned volIndex = 0; - - for (;;) - { - UInt64 volSize; - if (volIndex < VolumeSizes.Size()) - volSize = VolumeSizes[volIndex]; - else - volSize = VolumeSizes.Back(); - - UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize)); - UInt32 processedSize; - if (!inFile.Read(buffer, needSize, processedSize)) - return GetLastError(); - if (processedSize == 0) - break; - needSize = processedSize; - if (curVolSize == 0) - { - FString name = VolBasePath; - name += FTEXT('.'); - name += us2fs(seqName.GetNextName()); - sync.Set_FilePath(fs2us(name)); - sync.Set_NumFilesCur(numFiles++); - if (!outFile.Create(name, false)) - { - HRESULT res = GetLastError(); - AddErrorPath(name); - return res; - } - } - if (!outFile.Write(buffer, needSize, processedSize)) - return GetLastError(); - if (needSize != processedSize) - throw g_Message_FileWriteError; - curVolSize += processedSize; - if (curVolSize == volSize) - { - outFile.Close(); - if (volIndex < VolumeSizes.Size()) - volIndex++; - curVolSize = 0; - } - pos += processedSize; - RINOK(sync.Set_NumBytesCur(pos)); - } - sync.Set_NumFilesCur(numFiles); - return S_OK; -} - -void CApp::Split() -{ - int srcPanelIndex = GetFocusedPanelIndex(); - CPanel &srcPanel = Panels[srcPanelIndex]; - if (!srcPanel.Is_IO_FS_Folder()) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - CRecordVector indices; - srcPanel.GetOperatedItemIndices(indices); - if (indices.IsEmpty()) - return; - if (indices.Size() != 1) - { - srcPanel.MessageBoxErrorLang(IDS_SELECT_ONE_FILE); - return; - } - int index = indices[0]; - if (srcPanel.IsItem_Folder(index)) - { - srcPanel.MessageBoxErrorLang(IDS_SELECT_ONE_FILE); - return; - } - const UString itemName = srcPanel.GetItemName(index); - - UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); - UString path = srcPath; - int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); - CPanel &destPanel = Panels[destPanelIndex]; - if (NumPanels > 1) - if (destPanel.IsFSFolder()) - path = destPanel.GetFsPath(); - CSplitDialog splitDialog; - splitDialog.FilePath = srcPanel.GetItemRelPath(index); - splitDialog.Path = path; - if (splitDialog.Create(srcPanel.GetParent()) != IDOK) - return; - - NFind::CFileInfo fileInfo; - if (!fileInfo.Find(us2fs(srcPath + itemName))) - { - srcPanel.MessageBoxMyError(L"Can not find file"); - return; - } - if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) - { - srcPanel.MessageBoxErrorLang(IDS_SPLIT_VOL_MUST_BE_SMALLER); - return; - } - const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); - if (numVolumes >= 100) - { - wchar_t s[32]; - ConvertUInt64ToString(numVolumes, s); - if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, s), - LangString(IDS_SPLIT_CONFIRM_TITLE), - MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) - return; - } - - path = splitDialog.Path; - NName::NormalizeDirPathPrefix(path); - if (!CreateComplexDir(us2fs(path))) - { - srcPanel.MessageBoxError2Lines(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, path), ::GetLastError()); - return; - } - - { - CThreadSplit spliter; - spliter.NumVolumes = numVolumes; - - CProgressDialog &progressDialog = spliter.ProgressDialog; - - UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE, 0x03000000); - UString title = LangString(IDS_SPLITTING); - - progressDialog.ShowCompressionInfo = false; - - progressDialog.MainWindow = _window; - progressDialog.MainTitle = progressWindowTitle; - progressDialog.MainAddTitle = title; - progressDialog.MainAddTitle.Add_Space(); - progressDialog.Sync.Set_TitleFileName(itemName); - - - spliter.FilePath = us2fs(srcPath + itemName); - spliter.VolBasePath = us2fs(path + srcPanel.GetItemName_for_Copy(index)); - spliter.VolumeSizes = splitDialog.VolumeSizes; - - // if (splitDialog.VolumeSizes.Size() == 0) return; - - // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); - // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); - - if (spliter.Create(title, _window) != 0) - return; - } - RefreshTitleAlways(); - - - // disableNotify.Restore(); - // disableNotify.Restore(); - // srcPanel.SetFocusToList(); - // srcPanel.RefreshListCtrlSaveFocused(); -} - - -class CThreadCombine: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - FString InputDirPrefix; - FStringVector Names; - FString OutputPath; - UInt64 TotalSize; -}; - -HRESULT CThreadCombine::ProcessVirt() -{ - NIO::COutFile outFile; - if (!outFile.Create(OutputPath, false)) - { - HRESULT res = GetLastError(); - AddErrorPath(OutputPath); - return res; - } - - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_NumBytesTotal(TotalSize); - - CMyBuffer bufferObject; - if (!bufferObject.Allocate(kBufSize)) - return E_OUTOFMEMORY; - Byte *buffer = (Byte *)(void *)bufferObject; - UInt64 pos = 0; - FOR_VECTOR (i, Names) - { - NIO::CInFile inFile; - const FString nextName = InputDirPrefix + Names[i]; - if (!inFile.Open(nextName)) - { - HRESULT res = GetLastError(); - AddErrorPath(nextName); - return res; - } - sync.Set_FilePath(fs2us(nextName)); - for (;;) - { - UInt32 processedSize; - if (!inFile.Read(buffer, kBufSize, processedSize)) - { - HRESULT res = GetLastError(); - AddErrorPath(nextName); - return res; - } - if (processedSize == 0) - break; - UInt32 needSize = processedSize; - if (!outFile.Write(buffer, needSize, processedSize)) - { - HRESULT res = GetLastError(); - AddErrorPath(OutputPath); - return res; - } - if (needSize != processedSize) - throw g_Message_FileWriteError; - pos += processedSize; - RINOK(sync.Set_NumBytesCur(pos)); - } - } - return S_OK; -} - -extern void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size); - -static void AddInfoFileName(UString &dest, const UString &name) -{ - dest += L"\n "; - dest += name; -} - -void CApp::Combine() -{ - int srcPanelIndex = GetFocusedPanelIndex(); - CPanel &srcPanel = Panels[srcPanelIndex]; - if (!srcPanel.IsFSFolder()) - { - srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED); - return; - } - CRecordVector indices; - srcPanel.GetOperatedItemIndices(indices); - if (indices.IsEmpty()) - return; - int index = indices[0]; - if (indices.Size() != 1 || srcPanel.IsItem_Folder(index)) - { - srcPanel.MessageBoxErrorLang(IDS_COMBINE_SELECT_ONE_FILE); - return; - } - const UString itemName = srcPanel.GetItemName(index); - - UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); - UString path = srcPath; - int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); - CPanel &destPanel = Panels[destPanelIndex]; - if (NumPanels > 1) - if (destPanel.IsFSFolder()) - path = destPanel.GetFsPath(); - - CVolSeqName volSeqName; - if (!volSeqName.ParseName(itemName)) - { - srcPanel.MessageBoxErrorLang(IDS_COMBINE_CANT_DETECT_SPLIT_FILE); - return; - } - - { - CThreadCombine combiner; - - UString nextName = itemName; - combiner.TotalSize = 0; - for (;;) - { - NFind::CFileInfo fileInfo; - if (!fileInfo.Find(us2fs(srcPath + nextName)) || fileInfo.IsDir()) - break; - combiner.Names.Add(us2fs(nextName)); - combiner.TotalSize += fileInfo.Size; - nextName = volSeqName.GetNextName(); - } - if (combiner.Names.Size() == 1) - { - srcPanel.MessageBoxErrorLang(IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART); - return; - } - - if (combiner.TotalSize == 0) - { - srcPanel.MessageBoxMyError(L"No data"); - return; - } - - UString info; - AddValuePair2(info, IDS_PROP_FILES, combiner.Names.Size(), combiner.TotalSize); - - info.Add_LF(); - info += srcPath; - - unsigned i; - for (i = 0; i < combiner.Names.Size() && i < 2; i++) - AddInfoFileName(info, fs2us(combiner.Names[i])); - if (i != combiner.Names.Size()) - { - if (i + 1 != combiner.Names.Size()) - AddInfoFileName(info, L"..."); - AddInfoFileName(info, fs2us(combiner.Names.Back())); - } - - { - CCopyDialog copyDialog; - copyDialog.Value = path; - LangString(IDS_COMBINE, copyDialog.Title); - copyDialog.Title.Add_Space(); - copyDialog.Title += srcPanel.GetItemRelPath(index); - LangString(IDS_COMBINE_TO, copyDialog.Static); - copyDialog.Info = info; - if (copyDialog.Create(srcPanel.GetParent()) != IDOK) - return; - path = copyDialog.Value; - } - - NName::NormalizeDirPathPrefix(path); - if (!CreateComplexDir(us2fs(path))) - { - srcPanel.MessageBoxError2Lines(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, path), ::GetLastError()); - return; - } - - UString outName = volSeqName.UnchangedPart; - while (!outName.IsEmpty()) - { - if (outName.Back() != L'.') - break; - outName.DeleteBack(); - } - if (outName.IsEmpty()) - outName = L"file"; - - NFind::CFileInfo fileInfo; - UString destFilePath = path + outName; - combiner.OutputPath = us2fs(destFilePath); - if (fileInfo.Find(combiner.OutputPath)) - { - srcPanel.MessageBoxMyError(MyFormatNew(IDS_FILE_EXIST, destFilePath)); - return; - } - - CProgressDialog &progressDialog = combiner.ProgressDialog; - progressDialog.ShowCompressionInfo = false; - - UString progressWindowTitle = L"7-Zip"; // LangString(IDS_APP_TITLE, 0x03000000); - UString title = LangString(IDS_COMBINING); - - progressDialog.MainWindow = _window; - progressDialog.MainTitle = progressWindowTitle; - progressDialog.MainAddTitle = title; - progressDialog.MainAddTitle.Add_Space(); - - combiner.InputDirPrefix = us2fs(srcPath); - - // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); - // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); - - if (combiner.Create(title, _window) != 0) - return; - } - RefreshTitleAlways(); - - // disableNotify.Restore(); - // disableNotify.Restore(); - // srcPanel.SetFocusToList(); - // srcPanel.RefreshListCtrlSaveFocused(); -} +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileName.h" + +#include "../GUI/ExtractRes.h" + +#include "resource.h" + +#include "App.h" +#include "CopyDialog.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "SplitDialog.h" +#include "SplitUtils.h" + +#include "PropertyNameRes.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const char * const g_Message_FileWriteError = "File write error"; + +struct CVolSeqName +{ + UString UnchangedPart; + UString ChangedPart; + CVolSeqName(): ChangedPart("000") {} + + void SetNumDigits(UInt64 numVolumes) + { + ChangedPart = "000"; + while (numVolumes > 999) + { + numVolumes /= 10; + ChangedPart.Add_Char('0'); + } + } + + bool ParseName(const UString &name) + { + if (name.Len() < 2) + return false; + if (name.Back() != L'1' || name[name.Len() - 2] != L'0') + return false; + + unsigned pos = name.Len() - 2; + for (; pos > 0 && name[pos - 1] == '0'; pos--); + UnchangedPart.SetFrom(name, pos); + ChangedPart = name.Ptr(pos); + return true; + } + + UString GetNextName(); +}; + + +UString CVolSeqName::GetNextName() +{ + for (int i = (int)ChangedPart.Len() - 1; i >= 0; i--) + { + const wchar_t c = ChangedPart[i]; + if (c != L'9') + { + ChangedPart.ReplaceOneCharAtPos((unsigned)i, (wchar_t)(c + 1)); + break; + } + ChangedPart.ReplaceOneCharAtPos((unsigned)i, L'0'); + if (i == 0) + ChangedPart.InsertAtFront(L'1'); + } + return UnchangedPart + ChangedPart; +} + +class CThreadSplit: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + FString FilePath; + FString VolBasePath; + UInt64 NumVolumes; + CRecordVector VolumeSizes; +}; + + +class CPreAllocOutFile +{ + UInt64 _preAllocSize; +public: + NIO::COutFile File; + UInt64 Written; + + CPreAllocOutFile(): _preAllocSize(0), Written(0) {} + + ~CPreAllocOutFile() + { + SetCorrectFileLength(); + } + + void PreAlloc(UInt64 preAllocSize) + { + _preAllocSize = 0; + if (File.SetLength(preAllocSize)) + _preAllocSize = preAllocSize; + File.SeekToBegin(); + } + + bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw() + { + bool res = File.Write(data, size, processedSize); + Written += processedSize; + return res; + } + + void Close() + { + SetCorrectFileLength(); + Written = 0; + _preAllocSize = 0; + File.Close(); + } + + void SetCorrectFileLength() + { + if (Written < _preAllocSize) + { + File.SetLength(Written); + _preAllocSize = 0; + } + } +}; + + +static const UInt32 kBufSize = (1 << 20); + +HRESULT CThreadSplit::ProcessVirt() +{ + NIO::CInFile inFile; + if (!inFile.Open(FilePath)) + return GetLastError_noZero_HRESULT(); + + CPreAllocOutFile outFile; + + CMyBuffer buffer; + if (!buffer.Allocate(kBufSize)) + return E_OUTOFMEMORY; + + CVolSeqName seqName; + seqName.SetNumDigits(NumVolumes); + + UInt64 length; + if (!inFile.GetLength(length)) + return GetLastError_noZero_HRESULT(); + + CProgressSync &sync = Sync; + sync.Set_NumBytesTotal(length); + + UInt64 pos = 0; + UInt64 prev = 0; + UInt64 numFiles = 0; + unsigned volIndex = 0; + + for (;;) + { + UInt64 volSize; + if (volIndex < VolumeSizes.Size()) + volSize = VolumeSizes[volIndex]; + else + volSize = VolumeSizes.Back(); + + UInt32 needSize = kBufSize; + { + const UInt64 rem = volSize - outFile.Written; + if (needSize > rem) + needSize = (UInt32)rem; + } + UInt32 processedSize; + if (!inFile.Read(buffer, needSize, processedSize)) + return GetLastError_noZero_HRESULT(); + if (processedSize == 0) + return S_OK; + needSize = processedSize; + + if (outFile.Written == 0) + { + FString name = VolBasePath; + name.Add_Dot(); + name += us2fs(seqName.GetNextName()); + sync.Set_FilePath(fs2us(name)); + if (!outFile.File.Create_NEW(name)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + AddErrorPath(name); + return res; + } + UInt64 expectSize = volSize; + if (pos < length) + { + const UInt64 rem = length - pos; + if (expectSize > rem) + expectSize = rem; + } + outFile.PreAlloc(expectSize); + } + + if (!outFile.Write(buffer, needSize, processedSize)) + return GetLastError_noZero_HRESULT(); + if (needSize != processedSize) + throw g_Message_FileWriteError; + + pos += processedSize; + + if (outFile.Written == volSize) + { + outFile.Close(); + sync.Set_NumFilesCur(++numFiles); + if (volIndex < VolumeSizes.Size()) + volIndex++; + } + + if (pos - prev >= ((UInt32)1 << 22) || outFile.Written == 0) + { + RINOK(sync.Set_NumBytesCur(pos)) + prev = pos; + } + } +} + + +void CApp::Split() +{ + const unsigned srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.Is_IO_FS_Folder()) + { + srcPanel.MessageBox_Error_UnsupportOperation(); + return; + } + CRecordVector indices; + srcPanel.Get_ItemIndices_Operated(indices); + if (indices.IsEmpty()) + return; + if (indices.Size() != 1) + { + srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE); + return; + } + const unsigned index = indices[0]; + if (srcPanel.IsItem_Folder(index)) + { + srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + const UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); + UString path = srcPath; + unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel.GetFsPath(); + CSplitDialog splitDialog; + splitDialog.FilePath = srcPanel.GetItemRelPath(index); + splitDialog.Path = path; + if (splitDialog.Create(srcPanel.GetParent()) != IDOK) + return; + + NFind::CFileInfo fileInfo; + if (!fileInfo.Find(us2fs(srcPath + itemName))) + { + srcPanel.MessageBox_Error(L"Cannot find file"); + return; + } + if (fileInfo.Size <= splitDialog.VolumeSizes.FrontItem()) + { + srcPanel.MessageBox_Error_LangID(IDS_SPLIT_VOL_MUST_BE_SMALLER); + return; + } + const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); + if (numVolumes >= 100) + { + wchar_t s[32]; + ConvertUInt64ToString(numVolumes, s); + if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, s), + LangString(IDS_SPLIT_CONFIRM_TITLE), + MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) + return; + } + + path = splitDialog.Path; + NName::NormalizeDirPathPrefix(path); + if (!CreateComplexDir(us2fs(path))) + { + const HRESULT lastError = GetLastError_noZero_HRESULT(); + srcPanel.MessageBox_Error_2Lines_Message_HRESULT(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, path), lastError); + return; + } + + { + CThreadSplit spliter; + spliter.NumVolumes = numVolumes; + + CProgressDialog &progressDialog = spliter; + + const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); + const UString title = LangString(IDS_SPLITTING); + + progressDialog.ShowCompressionInfo = false; + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title; + progressDialog.MainAddTitle.Add_Space(); + progressDialog.Sync.Set_TitleFileName(itemName); + + + spliter.FilePath = us2fs(srcPath + itemName); + spliter.VolBasePath = us2fs(path + srcPanel.GetItemName_for_Copy(index)); + spliter.VolumeSizes = splitDialog.VolumeSizes; + + // if (splitDialog.VolumeSizes.Size() == 0) return; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + if (spliter.Create(title, _window) != 0) + return; + } + RefreshTitleAlways(); + + + // disableNotify.Restore(); + // disableNotify.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} + + +class CThreadCombine: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + FString InputDirPrefix; + FStringVector Names; + FString OutputPath; + UInt64 TotalSize; +}; + +HRESULT CThreadCombine::ProcessVirt() +{ + NIO::COutFile outFile; + if (!outFile.Create_NEW(OutputPath)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + AddErrorPath(OutputPath); + return res; + } + + CProgressSync &sync = Sync; + sync.Set_NumBytesTotal(TotalSize); + + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + return E_OUTOFMEMORY; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 pos = 0; + FOR_VECTOR (i, Names) + { + NIO::CInFile inFile; + const FString nextName = InputDirPrefix + Names[i]; + if (!inFile.Open(nextName)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + AddErrorPath(nextName); + return res; + } + sync.Set_FilePath(fs2us(nextName)); + for (;;) + { + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + AddErrorPath(nextName); + return res; + } + if (processedSize == 0) + break; + const UInt32 needSize = processedSize; + if (!outFile.Write(buffer, needSize, processedSize)) + { + const HRESULT res = GetLastError_noZero_HRESULT(); + AddErrorPath(OutputPath); + return res; + } + if (needSize != processedSize) + throw g_Message_FileWriteError; + pos += processedSize; + RINOK(sync.Set_NumBytesCur(pos)) + } + } + return S_OK; +} + +extern void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size); + +static void AddInfoFileName(UString &dest, const UString &name) +{ + dest += "\n "; + dest += name; +} + +void CApp::Combine() +{ + const unsigned srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox_Error_LangID(IDS_OPERATION_IS_NOT_SUPPORTED); + return; + } + CRecordVector indices; + srcPanel.Get_ItemIndices_Operated(indices); + if (indices.IsEmpty()) + return; + const unsigned index = indices[0]; + if (indices.Size() != 1 || srcPanel.IsItem_Folder(index)) + { + srcPanel.MessageBox_Error_LangID(IDS_COMBINE_SELECT_ONE_FILE); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index); + UString path = srcPath; + unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel.GetFsPath(); + + CVolSeqName volSeqName; + if (!volSeqName.ParseName(itemName)) + { + srcPanel.MessageBox_Error_LangID(IDS_COMBINE_CANT_DETECT_SPLIT_FILE); + return; + } + + { + CThreadCombine combiner; + + UString nextName = itemName; + combiner.TotalSize = 0; + for (;;) + { + NFind::CFileInfo fileInfo; + if (!fileInfo.Find(us2fs(srcPath + nextName)) || fileInfo.IsDir()) + break; + combiner.Names.Add(us2fs(nextName)); + combiner.TotalSize += fileInfo.Size; + nextName = volSeqName.GetNextName(); + } + if (combiner.Names.Size() == 1) + { + srcPanel.MessageBox_Error_LangID(IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART); + return; + } + + if (combiner.TotalSize == 0) + { + srcPanel.MessageBox_Error(L"No data"); + return; + } + + UString info; + AddValuePair2(info, IDS_PROP_FILES, combiner.Names.Size(), combiner.TotalSize); + + info.Add_LF(); + info += srcPath; + + unsigned i; + for (i = 0; i < combiner.Names.Size() && i < 2; i++) + AddInfoFileName(info, fs2us(combiner.Names[i])); + if (i != combiner.Names.Size()) + { + if (i + 1 != combiner.Names.Size()) + AddInfoFileName(info, L"..."); + AddInfoFileName(info, fs2us(combiner.Names.Back())); + } + + { + CCopyDialog copyDialog; + copyDialog.Value = path; + LangString(IDS_COMBINE, copyDialog.Title); + copyDialog.Title.Add_Space(); + copyDialog.Title += srcPanel.GetItemRelPath(index); + LangString(IDS_COMBINE_TO, copyDialog.Static); + copyDialog.Info = info; + if (copyDialog.Create(srcPanel.GetParent()) != IDOK) + return; + path = copyDialog.Value; + } + + NName::NormalizeDirPathPrefix(path); + if (!CreateComplexDir(us2fs(path))) + { + const HRESULT lastError = GetLastError_noZero_HRESULT(); + srcPanel.MessageBox_Error_2Lines_Message_HRESULT(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, path), lastError); + return; + } + + UString outName = volSeqName.UnchangedPart; + while (!outName.IsEmpty()) + { + if (outName.Back() != L'.') + break; + outName.DeleteBack(); + } + if (outName.IsEmpty()) + outName = "file"; + + NFind::CFileInfo fileInfo; + UString destFilePath = path + outName; + combiner.OutputPath = us2fs(destFilePath); + if (fileInfo.Find(combiner.OutputPath)) + { + srcPanel.MessageBox_Error(MyFormatNew(IDS_FILE_EXIST, destFilePath)); + return; + } + + CProgressDialog &progressDialog = combiner; + progressDialog.ShowCompressionInfo = false; + + const UString progressWindowTitle ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000); + const UString title = LangString(IDS_COMBINING); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title; + progressDialog.MainAddTitle.Add_Space(); + + combiner.InputDirPrefix = us2fs(srcPath); + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + if (combiner.Create(title, _window) != 0) + return; + } + RefreshTitleAlways(); + + // disableNotify.Restore(); + // disableNotify.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -1,58 +1,58 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -#include "PasswordDialog.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -#ifdef LANG -static const UInt32 kLangIDs[] = -{ - IDT_PASSWORD_ENTER, - IDX_PASSWORD_SHOW -}; -#endif - -void CPasswordDialog::ReadControls() -{ - _passwordEdit.GetText(Password); - ShowPassword = IsButtonCheckedBool(IDX_PASSWORD_SHOW); -} - -void CPasswordDialog::SetTextSpec() -{ - _passwordEdit.SetPasswordChar(ShowPassword ? 0: TEXT('*')); - _passwordEdit.SetText(Password); -} - -bool CPasswordDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_PASSWORD); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - #endif - _passwordEdit.Attach(GetItem(IDE_PASSWORD_PASSWORD)); - CheckButton(IDX_PASSWORD_SHOW, ShowPassword); - SetTextSpec(); - return CModalDialog::OnInit(); -} - -bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - if (buttonID == IDX_PASSWORD_SHOW) - { - ReadControls(); - SetTextSpec(); - return true; - } - return CDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CPasswordDialog::OnOK() -{ - ReadControls(); - CModalDialog::OnOK(); -} +// PasswordDialog.cpp + +#include "StdAfx.h" + +#include "PasswordDialog.h" + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_PASSWORD_ENTER, + IDX_PASSWORD_SHOW +}; +#endif + +void CPasswordDialog::ReadControls() +{ + _passwordEdit.GetText(Password); + ShowPassword = IsButtonCheckedBool(IDX_PASSWORD_SHOW); +} + +void CPasswordDialog::SetTextSpec() +{ + _passwordEdit.SetPasswordChar(ShowPassword ? 0: TEXT('*')); + _passwordEdit.SetText(Password); +} + +bool CPasswordDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_PASSWORD); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + _passwordEdit.Attach(GetItem(IDE_PASSWORD_PASSWORD)); + CheckButton(IDX_PASSWORD_SHOW, ShowPassword); + SetTextSpec(); + return CModalDialog::OnInit(); +} + +bool CPasswordDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + if (buttonID == IDX_PASSWORD_SHOW) + { + ReadControls(); + SetTextSpec(); + return true; + } + return CDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CPasswordDialog::OnOK() +{ + ReadControls(); + CModalDialog::OnOK(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,28 +1,28 @@ -// PasswordDialog.h - -#ifndef __PASSWORD_DIALOG_H -#define __PASSWORD_DIALOG_H - -#include "../../../Windows/Control/Dialog.h" -#include "../../../Windows/Control/Edit.h" - -#include "PasswordDialogRes.h" - -class CPasswordDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CEdit _passwordEdit; - - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - void SetTextSpec(); - void ReadControls(); -public: - UString Password; - bool ShowPassword; - - CPasswordDialog(): ShowPassword(false) {} - INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); } -}; - -#endif +// PasswordDialog.h + +#ifndef ZIP7_INC_PASSWORD_DIALOG_H +#define ZIP7_INC_PASSWORD_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" + +#include "PasswordDialogRes.h" + +class CPasswordDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _passwordEdit; + + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void SetTextSpec(); + void ReadControls(); +public: + UString Password; + bool ShowPassword; + + CPasswordDialog(): ShowPassword(false) {} + INT_PTR Create(HWND parentWindow = NULL) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog.rc 2024-03-06 07:00:00.000000000 +0000 @@ -0,0 +1,18 @@ +#include "PasswordDialogRes.h" +#include "../../GuiCommon.rc" + +#ifdef UNDER_CE +#define xc 140 +#else +#define xc 200 +#endif +#define yc 72 + +IDD_PASSWORD DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Enter password" +BEGIN + LTEXT "&Enter password:", IDT_PASSWORD_ENTER, m, m, xc, 8 + EDITTEXT IDE_PASSWORD_PASSWORD, m, 20, xc, 14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "&Show password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, 42, xc, 10 + OK_CANCEL +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialogRes.h 2011-05-07 03:56:42.000000000 +0000 @@ -1,5 +1,5 @@ -#define IDD_PASSWORD 3800 -#define IDT_PASSWORD_ENTER 3801 -#define IDX_PASSWORD_SHOW 3803 - -#define IDE_PASSWORD_PASSWORD 120 +#define IDD_PASSWORD 3800 +#define IDT_PASSWORD_ENTER 3801 +#define IDX_PASSWORD_SHOW 3803 + +#define IDE_PASSWORD_PASSWORD 120 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp 2014-12-28 19:52:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "PasswordDialogRes.h" - -class CPasswordDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CPasswordDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent,int id) : CModalDialogImpl(dialog, parent, id, wxT("Enter password")) - { - bool bShowPassword = false; - - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - { - wxStaticBoxSizer *passwdSizer = new wxStaticBoxSizer(new wxStaticBox(this,IDT_PASSWORD_ENTER,_T("&Enter password:")),wxVERTICAL); - - wxTextCtrl *TxtPasswd = new wxTextCtrl(this, IDE_PASSWORD_PASSWORD, L"", - wxDefaultPosition, wxSize(260,-1), bShowPassword?wxTE_LEFT:wxTE_PASSWORD ); - - wxCheckBox *ChkShowPasswd = new wxCheckBox(this, IDX_PASSWORD_SHOW, wxT("&Show password")); - - ChkShowPasswd->SetValue(bShowPassword); - passwdSizer->Add(TxtPasswd, 0, wxALL, 5); - passwdSizer->Add(ChkShowPasswd, 0, wxALL, 5); - - topsizer->Add(passwdSizer, 0, wxALL, 5); - } - topsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_PASSWORD,CPasswordDialog,0) - -BEGIN_EVENT_TABLE(CPasswordDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PluginInterface.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginInterface.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PluginInterface.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginInterface.h 2023-02-01 18:00:00.000000000 +0000 @@ -1,31 +1,32 @@ -// PluginInterface.h - -#ifndef __PLUGIN_INTERFACE_H -#define __PLUGIN_INTERFACE_H - -/* -#include "../../../Common/Types.h" -#include "../../IDecl.h" - -#define PLUGIN_INTERFACE(i, x) DECL_INTERFACE(i, 0x0A, x) - -PLUGIN_INTERFACE(IInitContextMenu, 0x00) -{ - STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t * const *names, UInt32 numFiles) PURE; -}; - -PLUGIN_INTERFACE(IPluginOptionsCallback, 0x01) -{ - STDMETHOD(GetProgramFolderPath)(BSTR *value) PURE; - STDMETHOD(GetProgramPath)(BSTR *value) PURE; - STDMETHOD(GetRegistryCUPath)(BSTR *value) PURE; -}; - -PLUGIN_INTERFACE(IPluginOptions, 0x02) -{ - STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback) PURE; - // STDMETHOD(GetFileExtensions)(BSTR *extensions) PURE; -}; -*/ - -#endif +// PluginInterface.h + +#ifndef ZIP7_INC_PLUGIN_INTERFACE_H +#define ZIP7_INC_PLUGIN_INTERFACE_H + +/* +#include "../../../../C/7zTypes.h" +#include "../../IDecl.h" + +#define Z7_IFACE_CONSTR_PLUGIN(i, n) \ + Z7_DECL_IFACE_7ZIP(i, 0x0A, n) \ + { Z7_IFACE_COM7_PURE(i) }; + +#define Z7_IFACEM_IInitContextMenu(x) \ + x(InitContextMenu(const wchar_t *folder, const wchar_t * const *names, UInt32 numFiles)) \ + +Z7_IFACE_CONSTR_PLUGIN(IInitContextMenu, 0x00) + +#define Z7_IFACEM_IPluginOptionsCallback(x) \ + x(GetProgramFolderPath(BSTR *value)) \ + x(GetProgramPath(BSTR *value)) \ + x(GetRegistryCUPath(BSTR *value)) \ + +Z7_IFACE_CONSTR_PLUGIN(IPluginOptionsCallback, 0x01) + +#define Z7_IFACEM_IPluginOptions(x) \ + x(PluginOptions(HWND hWnd, IPluginOptionsCallback *callback)) \ + // x(GetFileExtensions(BSTR *extensions)) + +Z7_IFACE_CONSTR_PLUGIN(IPluginOptions, 0x02) +*/ +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PluginLoader.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginLoader.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PluginLoader.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PluginLoader.h 2023-12-03 18:00:00.000000000 +0000 @@ -1,28 +1,33 @@ -// PluginLoader.h - -#ifndef __PLUGIN_LOADER_H -#define __PLUGIN_LOADER_H - -#include "../../../Windows/DLL.h" - -#include "IFolder.h" - -class CPluginLibrary: public NWindows::NDLL::CLibrary -{ -public: - HRESULT CreateManager(REFGUID clsID, IFolderManager **manager) - { - Func_CreateObject createObject = (Func_CreateObject)GetProc("CreateObject"); - if (!createObject) - return GetLastError(); - return createObject(&clsID, &IID_IFolderManager, (void **)manager); - } - HRESULT LoadAndCreateManager(CFSTR filePath, REFGUID clsID, IFolderManager **manager) - { - if (!Load(filePath)) - return GetLastError(); - return CreateManager(clsID, manager); - } -}; - -#endif +// PluginLoader.h + +#ifndef ZIP7_INC_PLUGIN_LOADER_H +#define ZIP7_INC_PLUGIN_LOADER_H + +#include "../../../Windows/DLL.h" + +#include "IFolder.h" + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +class CPluginLibrary: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateManager(REFGUID clsID, IFolderManager **manager) + { + const + Func_CreateObject createObject = Z7_GET_PROC_ADDRESS( + Func_CreateObject, Get_HMODULE(), + "CreateObject"); + if (!createObject) + return GetLastError_noZero_HRESULT(); + return createObject(&clsID, &IID_IFolderManager, (void **)manager); + } + HRESULT LoadAndCreateManager(CFSTR filePath, REFGUID clsID, IFolderManager **manager) + { + if (!Load(filePath)) + return GetLastError_noZero_HRESULT(); + return CreateManager(clsID, manager); + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgramLocation.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgramLocation.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.cpp 2011-02-25 09:32:13.000000000 +0000 @@ -1,3 +1,3 @@ -// ProgramLocation.cpp - -#include "StdAfx.h" +// ProgramLocation.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgramLocation.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgramLocation.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgramLocation.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,6 +1,6 @@ -// ProgramLocation.h - -#ifndef __PROGRAM_LOCATION_H -#define __PROGRAM_LOCATION_H - -#endif +// ProgramLocation.h + +#ifndef ZIP7_INC_PROGRAM_LOCATION_H +#define ZIP7_INC_PROGRAM_LOCATION_H + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.cpp 2023-03-20 11:00:00.000000000 +0000 @@ -0,0 +1,201 @@ +// ProgressDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "resource.h" + +#include "ProgressDialog.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 100; + +#ifdef Z7_LANG +#include "LangUtils.h" +#endif + +HRESULT CProgressSync::ProcessStopAndPause() +{ + for (;;) + { + if (GetStopped()) + return E_ABORT; + if (!GetPaused()) + break; + ::Sleep(100); + } + return S_OK; +} + +#ifndef Z7_SFX +CProgressDialog::~CProgressDialog() +{ + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + MySetWindowText(MainWindow, UString(s) + MainTitle); +} +#endif + + +#define UNDEFINED_VAL ((UInt64)(Int64)-1) + +bool CProgressDialog::OnInit() +{ + _range = UNDEFINED_VAL; + _prevPercentValue = UNDEFINED_VAL; + + _wasCreated = true; + _dialogCreatedEvent.Set(); + + #ifdef Z7_LANG + LangSetDlgItems(*this, NULL, 0); + #endif + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + + if (IconID >= 0) + { + HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID)); + SetIcon(ICON_BIG, icon); + } + + _timer = SetTimer(kTimerID, kTimerElapse); + SetText(_title); + CheckNeedClose(); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() { Sync.SetStopped(true); } +void CProgressDialog::OnOK() { } + +void CProgressDialog::SetRange(UInt64 range) +{ + _range = range; + _peviousPos = (UInt64)(Int64)-1; + _converter.Init(range); + m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% +} + +void CProgressDialog::SetPos(UInt64 pos) +{ + bool redraw = true; + if (pos < _range && pos > _peviousPos) + { + UInt64 posDelta = pos - _peviousPos; + if (posDelta < (_range >> 10)) + redraw = false; + } + if (redraw) + { + m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% + _peviousPos = pos; + } +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (Sync.GetPaused()) + return true; + + CheckNeedClose(); + + UInt64 total, completed; + Sync.GetProgress(total, completed); + if (total != _range) + SetRange(total); + SetPos(completed); + + if (total == 0) + total = 1; + + const UInt64 percentValue = completed * 100 / total; + if (percentValue != _prevPercentValue) + { + wchar_t s[64]; + ConvertUInt64ToString(percentValue, s); + UString title = s; + title += "% "; + SetText(title + _title); + #ifndef Z7_SFX + AddToTitle(title + MainAddTitle); + #endif + _prevPercentValue = percentValue; + } + return true; +} + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case kCloseMessage: + { + if (_timer) + { + KillTimer(kTimerID); + _timer = 0; + } + if (_inCancelMessageBox) + { + _externalCloseMessageWasReceived = true; + break; + } + return OnExternalCloseMessage(); + } + /* + case WM_SETTEXT: + { + if (_timer == 0) + return true; + } + */ + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDCANCEL: + { + bool paused = Sync.GetPaused(); + Sync.SetPaused(true); + _inCancelMessageBox = true; + int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL); + _inCancelMessageBox = false; + Sync.SetPaused(paused); + if (res == IDCANCEL || res == IDNO) + { + if (_externalCloseMessageWasReceived) + OnExternalCloseMessage(); + return true; + } + break; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CProgressDialog::CheckNeedClose() +{ + if (_needClose) + { + PostMsg(kCloseMessage); + _needClose = false; + } +} + +bool CProgressDialog::OnExternalCloseMessage() +{ + End(0); + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.h 2023-03-20 18:00:00.000000000 +0000 @@ -0,0 +1,171 @@ +// ProgressDialog.h + +#ifndef ZIP7_INC_PROGRESS_DIALOG_H +#define ZIP7_INC_PROGRESS_DIALOG_H + +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Thread.h" + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ProgressBar.h" + +#include "ProgressDialogRes.h" + +class CProgressSync +{ + NWindows::NSynchronization::CCriticalSection _cs; + bool _stopped; + bool _paused; + UInt64 _total; + UInt64 _completed; +public: + CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {} + + HRESULT ProcessStopAndPause(); + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _paused = value; + } + void SetProgress(UInt64 total, UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _total = total; + _completed = completed; + } + void SetPos(UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _completed = completed; + } + void GetProgress(UInt64 &total, UInt64 &completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + total = _total; + completed = _completed; + } +}; + +class CU64ToI32Converter +{ + UInt64 _numShiftBits; +public: + void Init(UInt64 range) + { + // Windows CE doesn't like big number here. + for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++) + range >>= 1; + } + int Count(UInt64 value) { return int(value >> _numShiftBits); } +}; + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ +private: + UINT_PTR _timer; + + UString _title; + CU64ToI32Converter _converter; + UInt64 _peviousPos; + UInt64 _range; + NWindows::NControl::CProgressBar m_ProgressBar; + + UInt64 _prevPercentValue; + + bool _wasCreated; + bool _needClose; + bool _inCancelMessageBox; + bool _externalCloseMessageWasReceived; + + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override; + virtual bool OnInit() Z7_override; + virtual void OnCancel() Z7_override; + virtual void OnOK() Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + + void SetRange(UInt64 range); + void SetPos(UInt64 pos); + + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef Z7_SFX + void AddToTitle(LPCWSTR string); + #endif + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + void CheckNeedClose(); + bool OnExternalCloseMessage(); +public: + CProgressSync Sync; + int IconID; + + #ifndef Z7_SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0) + #ifndef Z7_SFX + ,MainWindow(NULL) + #endif + { + IconID = -1; + _wasCreated = false; + _needClose = false; + _inCancelMessageBox = false; + _externalCloseMessageWasReceived = false; + + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + } + + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL) + { + _title = title; + INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent); + thread.Wait_Close(); + return res; + } + + enum + { + kCloseMessage = WM_APP + 1 + }; + + void ProcessWasFinished() + { + WaitCreating(); + if (_wasCreated) + PostMsg(kCloseMessage); + else + _needClose = true; + } +}; + + +class CProgressCloser +{ + CProgressDialog *_p; +public: + CProgressCloser(CProgressDialog &p) : _p(&p) {} + ~CProgressCloser() { _p->ProcessWasFinished(); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog.rc 2011-06-08 06:59:48.000000000 +0000 @@ -0,0 +1,12 @@ +#include "ProgressDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 172 +#define yc 44 + +IDD_PROGRESS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Progress" +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, bx, by, bxs, bys + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, m, xc, 14 +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.cpp 2015-10-17 15:26:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.cpp 2024-10-21 10:00:00.000000000 +0000 @@ -1,1357 +1,1483 @@ -// ProgressDialog2.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/Control/Static.h" -#include "../../../Windows/ErrorMsg.h" - -#include "../GUI/ExtractRes.h" - -#include "LangUtils.h" - -#include "DialogSize.h" -#include "ProgressDialog2.h" -#include "ProgressDialog2Res.h" - -using namespace NWindows; - -extern HINSTANCE g_hInstance; - -static const UINT_PTR kTimerID = 3; - -static const UINT kCloseMessage = WM_APP + 1; -// we can't use WM_USER, since WM_USER can be used by standard Windows procedure for Dialog - -static const UINT kTimerElapse = - #ifdef UNDER_CE - 500 - #else - 200 - #endif - ; - -static const UINT kCreateDelay = - #ifdef UNDER_CE - 2500 - #else - 500 - #endif - ; - -static const DWORD kPauseSleepTime = 100; - -#ifdef LANG - -static const UInt32 kLangIDs[] = -{ - IDT_PROGRESS_ELAPSED, - IDT_PROGRESS_REMAINING, - IDT_PROGRESS_TOTAL, - IDT_PROGRESS_SPEED, - IDT_PROGRESS_PROCESSED, - IDT_PROGRESS_RATIO, - IDT_PROGRESS_ERRORS, - IDB_PROGRESS_BACKGROUND, - IDB_PAUSE -}; - -static const UInt32 kLangIDs_Colon[] = -{ - IDT_PROGRESS_PACKED, - IDT_PROGRESS_FILES -}; - -#endif - - -#define UNDEFINED_VAL ((UInt64)(Int64)-1) -#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL; -#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL) -#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) - -CProgressSync::CProgressSync(): - _stopped(false), _paused(false), - _bytesProgressMode(true), - _totalBytes(UNDEFINED_VAL), _completedBytes(0), - _totalFiles(UNDEFINED_VAL), _curFiles(0), - _inSize(UNDEFINED_VAL), - _outSize(UNDEFINED_VAL), - _isDir(false) - {} - -#define CHECK_STOP if (_stopped) return E_ABORT; if (!_paused) return S_OK; -#define CRITICAL_LOCK NSynchronization::CCriticalSectionLock lock(_cs); - -bool CProgressSync::Get_Paused() -{ - CRITICAL_LOCK - return _paused; -} - -HRESULT CProgressSync::CheckStop() -{ - for (;;) - { - { - CRITICAL_LOCK - CHECK_STOP - } - ::Sleep(kPauseSleepTime); - } -} - -HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir) -{ - { - CRITICAL_LOCK - _totalFiles = numFiles; - _totalBytes = totalSize; - _filePath = fs2us(fileName); - _isDir = isDir; - // _completedBytes = 0; - CHECK_STOP - } - return CheckStop(); -} - -HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val) -{ - { - CRITICAL_LOCK - _totalFiles = val; - CHECK_STOP - } - return CheckStop(); -} - -void CProgressSync::Set_NumBytesTotal(UInt64 val) -{ - CRITICAL_LOCK - _totalBytes = val; -} - -void CProgressSync::Set_NumFilesCur(UInt64 val) -{ - CRITICAL_LOCK - _curFiles = val; -} - -HRESULT CProgressSync::Set_NumBytesCur(const UInt64 *val) -{ - { - CRITICAL_LOCK - if (val) - _completedBytes = *val; - CHECK_STOP - } - return CheckStop(); -} - -HRESULT CProgressSync::Set_NumBytesCur(UInt64 val) -{ - { - CRITICAL_LOCK - _completedBytes = val; - CHECK_STOP - } - return CheckStop(); -} - -void CProgressSync::Set_Ratio(const UInt64 *inSize, const UInt64 *outSize) -{ - CRITICAL_LOCK - if (inSize) - _inSize = *inSize; - if (outSize) - _outSize = *outSize; -} - -void CProgressSync::Set_TitleFileName(const UString &fileName) -{ - CRITICAL_LOCK - _titleFileName = fileName; -} - -void CProgressSync::Set_Status(const UString &s) -{ - CRITICAL_LOCK - _status = s; -} - -HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir) -{ - { - CRITICAL_LOCK - _status = s; - if (path) - _filePath = path; - else - _filePath.Empty(); - _isDir = isDir; - } - return CheckStop(); -} - -void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir) -{ - CRITICAL_LOCK - if (path) - _filePath = path; - else - _filePath.Empty(); - _isDir = isDir; -} - - -void CProgressSync::AddError_Message(const wchar_t *message) -{ - CRITICAL_LOCK - Messages.Add(message); -} - -void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t *name) -{ - UString s; - if (name && *name != 0) - s += name; - if (message && *message != 0 ) - { - if (!s.IsEmpty()) - s.Add_LF(); - s += message; - if (!s.IsEmpty() && s.Back() == L'\n') - s.DeleteBack(); - } - AddError_Message(s); -} - -void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name) -{ - UString s = NError::MyFormatMessage(systemError); - if (systemError == 0) - s = L"Error"; - AddError_Message_Name(s, name); -} - -CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0) -{ - _isDir = false; - - _numMessages = 0; - IconID = -1; - MessagesDisplayed = false; - _wasCreated = false; - _needClose = false; - _inCancelMessageBox = false; - _externalCloseMessageWasReceived = false; - - _numPostedMessages = 0; - _numAutoSizeMessages = 0; - _errorsWereDisplayed = false; - _waitCloseByCancelButton = false; - _cancelWasPressed = false; - ShowCompressionInfo = true; - // FIXME not supported WaitMode = false; - if (_dialogCreatedEvent.Create() != S_OK) - throw 1334987; - if (_createDialogEvent.Create() != S_OK) - throw 1334987; - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList); - if (_taskbarList) - _taskbarList->HrInit(); - #endif -} - -#ifndef _SFX - -CProgressDialog::~CProgressDialog() -{ - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - SetTaskbarProgressState(TBPF_NOPROGRESS); - #endif - AddToTitle(L""); -} -void CProgressDialog::AddToTitle(LPCWSTR s) -{ - if (MainWindow != 0) - { - CWindow window(MainWindow); - window.SetText((UString)s + MainTitle); - } -} - -#endif - - -void CProgressDialog::SetTaskbarProgressState() -{ - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - if (_taskbarList && _hwndForTaskbar) - { - TBPFLAG tbpFlags; - if (Sync.Get_Paused()) - tbpFlags = TBPF_PAUSED; - else - tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL; - SetTaskbarProgressState(tbpFlags); - } - #endif -} - -static const unsigned kTitleFileNameSizeLimit = 36; -static const unsigned kCurrentFileNameSizeLimit = 82; - -static void ReduceString(UString &s, unsigned size) -{ - if (s.Len() <= size) - return; - s.Delete(size / 2, s.Len() - size); - s.Insert(size / 2, L" ... "); -} - -void CProgressDialog::EnableErrorsControls(bool enable) -{ - ShowItem_Bool(IDT_PROGRESS_ERRORS, enable); - ShowItem_Bool(IDT_PROGRESS_ERRORS_VAL, enable); - ShowItem_Bool(IDL_PROGRESS_MESSAGES, enable); -} - -bool CProgressDialog::OnInit() -{ -#ifdef _WIN32 - _hwndForTaskbar = MainWindow; - if (!_hwndForTaskbar) - _hwndForTaskbar = GetParent(); - if (!_hwndForTaskbar) - _hwndForTaskbar = *this; -#endif - - INIT_AS_UNDEFINED(_progressBar_Range); - INIT_AS_UNDEFINED(_progressBar_Pos); - - INIT_AS_UNDEFINED(_prevPercentValue); - INIT_AS_UNDEFINED(_prevElapsedSec); - INIT_AS_UNDEFINED(_prevRemainingSec); - - INIT_AS_UNDEFINED(_prevSpeed); - _prevSpeed_MoveBits = 0; - - _prevTime = ::GetTickCount(); - _elapsedTime = 0; - - INIT_AS_UNDEFINED(_totalBytes_Prev); - INIT_AS_UNDEFINED(_processed_Prev); - INIT_AS_UNDEFINED(_packed_Prev); - INIT_AS_UNDEFINED(_ratio_Prev); - _filesStr_Prev.Empty(); - - _foreground = true; - - m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); - // FIXME _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); - // FIXME _messageList.SetUnicodeFormat(); - - _wasCreated = true; - _dialogCreatedEvent.Set(); - - #ifdef LANG - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); - #endif - - CWindow window(GetItem(IDB_PROGRESS_BACKGROUND)); - window.GetText(_background_String); - _backgrounded_String = _background_String; - _backgrounded_String.RemoveChar(L'&'); - - window = GetItem(IDB_PAUSE); - window.GetText(_pause_String); - - LangString(IDS_PROGRESS_FOREGROUND, _foreground_String); - LangString(IDS_CONTINUE, _continue_String); - LangString(IDS_PROGRESS_PAUSED, _paused_String); - - SetText(_title); - SetPauseText(); - SetPriorityText(); - - // FIXME _messageList.InsertColumn(0, L"", 30); - // FIXME _messageList.InsertColumn(1, L"", 600); - - // FIXME _messageList.SetColumnWidthAuto(0); - // FIXME _messageList.SetColumnWidthAuto(1); - - EnableErrorsControls(false); - - // FIXME GetItemSizes(IDCANCEL, _buttonSizeX, _buttonSizeY); - _numReduceSymbols = kCurrentFileNameSizeLimit; - NormalizeSize(true); - - if (!ShowCompressionInfo) - { - HideItem(IDT_PROGRESS_PACKED); - HideItem(IDT_PROGRESS_PACKED_VAL); - HideItem(IDT_PROGRESS_RATIO); - HideItem(IDT_PROGRESS_RATIO_VAL); - } - -#ifdef _WIN32 - if (IconID >= 0) - { - HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID)); - // SetIcon(ICON_SMALL, icon); - SetIcon(ICON_BIG, icon); - } -#endif - _timer = SetTimer(kTimerID, kTimerElapse); - #ifdef UNDER_CE - Foreground(); - #endif - - CheckNeedClose(); - - SetTaskbarProgressState(); - - return CModalDialog::OnInit(); -} - -static const UINT kIDs[] = -{ - IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL, - IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL, - IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL, - IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL, - IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL, - - IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL, - IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL, - IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL, - IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL -}; - -bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int sY; - int sStep; - int mx, my; - { - RECT r; - GetClientRectOfItem(IDT_PROGRESS_ELAPSED, r); - mx = r.left; - my = r.top; - sY = RECT_SIZE_Y(r); - GetClientRectOfItem(IDT_PROGRESS_REMAINING, r); - sStep = r.top - my; - } - - InvalidateRect(NULL); - - int xSizeClient = xSize - mx * 2; - - { - int i; - for (i = 800; i > 40; i = i * 9 / 10) - if (Units_To_Pixels_X(i) <= xSizeClient) - break; - _numReduceSymbols = i / 4; - } - - int yPos = ySize - my - _buttonSizeY; - - ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2); - ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2); - ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2); - - int bSizeX = _buttonSizeX; - int mx2 = mx; - for (;; mx2--) - { - int bSize2 = bSizeX * 3 + mx2 * 2; - if (bSize2 <= xSizeClient) - break; - if (mx2 < 5) - { - bSizeX = (xSizeClient - mx2 * 2) / 3; - break; - } - } - if (bSizeX < 2) - bSizeX = 2; - - { - RECT r; - GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r); - int y = r.top; - int ySize2 = yPos - my - y; - const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4; - int xx = xSize - mx * 2; - if (ySize2 < kMinYSize) - { - ySize2 = kMinYSize; - if (xx > bSizeX * 2) - xx -= bSizeX; - } - - _messageList.Move(mx, y, xx, ySize2); - } - - { - int xPos = xSize - mx; - xPos -= bSizeX; - MoveItem(IDCANCEL, xPos, yPos, bSizeX, _buttonSizeY); - xPos -= (mx2 + bSizeX); - MoveItem(IDB_PAUSE, xPos, yPos, bSizeX, _buttonSizeY); - xPos -= (mx2 + bSizeX); - MoveItem(IDB_PROGRESS_BACKGROUND, xPos, yPos, bSizeX, _buttonSizeY); - } - - int valueSize; - int labelSize; - int padSize; - - labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN); - valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS); - padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS); - int requiredSize = (labelSize + valueSize) * 2 + padSize; - - int gSize; - { - if (requiredSize < xSizeClient) - { - int incr = (xSizeClient - requiredSize) / 3; - labelSize += incr; - } - else - labelSize = (xSizeClient - valueSize * 2 - padSize) / 2; - if (labelSize < 0) - labelSize = 0; - - gSize = labelSize + valueSize; - padSize = xSizeClient - gSize * 2; - } - - labelSize = gSize - valueSize; - - yPos = my; - for (int i = 0; i < ARRAY_SIZE(kIDs); i += 2) - { - int x = mx; - const int kNumColumn1Items = 5 * 2; - if (i >= kNumColumn1Items) - { - if (i == kNumColumn1Items) - yPos = my; - x = mx + gSize + padSize; - } - MoveItem(kIDs[i], x, yPos, labelSize, sY); - MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY); - yPos += sStep; - } -#endif - return false; -} - -void CProgressDialog::OnCancel() { Sync.Set_Stopped(true); } -void CProgressDialog::OnOK() { } - -void CProgressDialog::SetProgressRange(UInt64 range) -{ - if (range == _progressBar_Range) - return; - _progressBar_Range = range; - INIT_AS_UNDEFINED(_progressBar_Pos); - _progressConv.Init(range); - m_ProgressBar.SetRange32(0, _progressConv.Count(range)); -} - -void CProgressDialog::SetProgressPos(UInt64 pos) -{ - if (pos >= _progressBar_Range || - pos <= _progressBar_Pos || - pos - _progressBar_Pos >= (_progressBar_Range >> 10)) - { - m_ProgressBar.SetPos(_progressConv.Count(pos)); - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - if (_taskbarList && _hwndForTaskbar) - _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range); - #endif - _progressBar_Pos = pos; - } -} - -#define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; } - -void GetTimeString(UInt64 timeValue, wchar_t *s) -{ - UInt64 hours = timeValue / 3600; - UInt32 seconds = (UInt32)(timeValue - hours * 3600); - UInt32 minutes = seconds / 60; - seconds %= 60; - if (hours > 99) - { - ConvertUInt64ToString(hours, s); - for (; *s != 0; s++); - } - else - { - UInt32 hours32 = (UInt32)hours; - UINT_TO_STR_2(hours32); - } - *s++ = ':'; UINT_TO_STR_2(minutes); - *s++ = ':'; UINT_TO_STR_2(seconds); - *s = 0; -} - -static void ConvertSizeToString(UInt64 v, wchar_t *s) -{ - Byte c = 0; - if (v >= ((UInt64)100000 << 20)) { v >>= 30; c = 'G'; } - else if (v >= ((UInt64)100000 << 10)) { v >>= 20; c = 'M'; } - else if (v >= ((UInt64)100000 << 0)) { v >>= 10; c = 'K'; } - ConvertUInt64ToString(v, s); - if (c != 0) - { - s += MyStringLen(s); - *s++ = ' '; - *s++ = c; - *s++ = 0; - } -} - -void CProgressDialog::ShowSize(int id, UInt64 val, UInt64 &prev) -{ - if (val == prev) - return; - prev = val; - wchar_t s[40]; - s[0] = 0; - if (IS_DEFINED_VAL(val)) - ConvertSizeToString(val, s); - SetItemText(id, s); -} - -static void GetChangedString(const UString &newStr, UString &prevStr, bool &hasChanged) -{ - hasChanged = !(prevStr == newStr); - if (hasChanged) - prevStr = newStr; -} - -static unsigned GetPower32(UInt32 val) -{ - const unsigned kStart = 32; - UInt32 mask = ((UInt32)1 << (kStart - 1)); - for (unsigned i = kStart;; i--) - { - if (i == 0 || (val & mask) != 0) - return i; - mask >>= 1; - } -} - -static unsigned GetPower64(UInt64 val) -{ - UInt32 high = (UInt32)(val >> 32); - if (high == 0) - return GetPower32((UInt32)val); - return GetPower32(high) + 32; -} - -static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider) -{ - unsigned pow1 = GetPower64(mult1); - unsigned pow2 = GetPower64(mult2); - while (pow1 + pow2 > 64) - { - if (pow1 > pow2) { pow1--; mult1 >>= 1; } - else { pow2--; mult2 >>= 1; } - divider >>= 1; - } - UInt64 res = mult1 * mult2; - if (divider != 0) - res /= divider; - return res; -} - -void CProgressDialog::UpdateStatInfo(bool showAll) -{ - UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; - bool bytesProgressMode; - - bool titleFileName_Changed; - bool curFilePath_Changed; - bool status_Changed; - unsigned numErrors; - { - NSynchronization::CCriticalSectionLock lock(Sync._cs); - total = Sync._totalBytes; - completed = Sync._completedBytes; - totalFiles = Sync._totalFiles; - completedFiles = Sync._curFiles; - inSize = Sync._inSize; - outSize = Sync._outSize; - bytesProgressMode = Sync._bytesProgressMode; - - GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed); - GetChangedString(Sync._filePath, _filePath, curFilePath_Changed); - GetChangedString(Sync._status, _status, status_Changed); - if (_isDir != Sync._isDir) - { - curFilePath_Changed = true; - _isDir = Sync._isDir; - } - numErrors = Sync.Messages.Size(); - } - - UInt32 curTime = ::GetTickCount(); - - const UInt64 progressTotal = bytesProgressMode ? total : totalFiles; - const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles; - { - if (IS_UNDEFINED_VAL(progressTotal)) - { - // SetPos(0); - // SetRange(progressCompleted); - } - else - { - if (_progressBar_Pos != 0 || progressCompleted != 0 || - (_progressBar_Range == 0 && progressTotal != 0)) - { - SetProgressRange(progressTotal); - SetProgressPos(progressCompleted); - } - } - } - - ShowSize(IDT_PROGRESS_TOTAL_VAL, total, _totalBytes_Prev); - - _elapsedTime += (curTime - _prevTime); - _prevTime = curTime; - UInt64 elapsedSec = _elapsedTime / 1000; - bool elapsedChanged = false; - if (elapsedSec != _prevElapsedSec) - { - _prevElapsedSec = elapsedSec; - elapsedChanged = true; - wchar_t s[40]; - GetTimeString(elapsedSec, s); - SetItemText(IDT_PROGRESS_ELAPSED_VAL, s); - } - - bool needSetTitle = false; - if (elapsedChanged || showAll) - { - if (numErrors > _numPostedMessages) - { - UpdateMessagesDialog(); - wchar_t s[32]; - ConvertUInt64ToString(numErrors, s); - SetItemText(IDT_PROGRESS_ERRORS_VAL, s); - if (!_errorsWereDisplayed) - { - _errorsWereDisplayed = true; - EnableErrorsControls(true); - SetTaskbarProgressState(); - } - } - - if (progressCompleted != 0) - { - if (IS_UNDEFINED_VAL(progressTotal)) - { - if (IS_DEFINED_VAL(_prevRemainingSec)) - { - INIT_AS_UNDEFINED(_prevRemainingSec); - SetItemText(IDT_PROGRESS_REMAINING_VAL, L""); - } - } - else - { - UInt64 remainingTime = 0; - if (progressCompleted < progressTotal) - remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted); - UInt64 remainingSec = remainingTime / 1000; - if (remainingSec != _prevRemainingSec) - { - _prevRemainingSec = remainingSec; - wchar_t s[40]; - GetTimeString(remainingSec, s); - SetItemText(IDT_PROGRESS_REMAINING_VAL, s); - } - } - { - UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime; - UInt64 v = (progressCompleted * 1000) / elapsedTime; - Byte c = 0; - unsigned moveBits = 0; - if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; } - else if (v >= ((UInt64)10000 << 0)) { moveBits = 10; c = 'K'; } - v >>= moveBits; - if (moveBits != _prevSpeed_MoveBits || v != _prevSpeed) - { - _prevSpeed_MoveBits = moveBits; - _prevSpeed = v; - wchar_t s[40]; - ConvertUInt64ToString(v, s); - unsigned pos = MyStringLen(s); - s[pos++] = ' '; - if (moveBits != 0) - s[pos++] = c; - s[pos++] = 'B'; - s[pos++] = '/'; - s[pos++] = 's'; - s[pos++] = 0; - SetItemText(IDT_PROGRESS_SPEED_VAL, s); - } - } - } - - { - UInt64 percent = 0; - { - if (IS_DEFINED_VAL(progressTotal)) - { - percent = progressCompleted * 100; - if (progressTotal != 0) - percent /= progressTotal; - } - } - if (percent != _prevPercentValue) - { - _prevPercentValue = percent; - needSetTitle = true; - } - } - - { - wchar_t s[64]; - ConvertUInt64ToString(completedFiles, s); - if (IS_DEFINED_VAL(totalFiles)) - { - wcscat(s, L" / "); - ConvertUInt64ToString(totalFiles, s + wcslen(s)); - } - if (_filesStr_Prev != s) - { - _filesStr_Prev = s; - SetItemText(IDT_PROGRESS_FILES_VAL, s); - } - } - - const UInt64 packSize = CompressingMode ? outSize : inSize; - const UInt64 unpackSize = CompressingMode ? inSize : outSize; - - if (IS_UNDEFINED_VAL(unpackSize) && - IS_UNDEFINED_VAL(packSize)) - { - ShowSize(IDT_PROGRESS_PROCESSED_VAL, completed, _processed_Prev); - ShowSize(IDT_PROGRESS_PACKED_VAL, UNDEFINED_VAL, _packed_Prev); - } - else - { - ShowSize(IDT_PROGRESS_PROCESSED_VAL, unpackSize, _processed_Prev); - ShowSize(IDT_PROGRESS_PACKED_VAL, packSize, _packed_Prev); - - if (IS_DEFINED_VAL(packSize) && - IS_DEFINED_VAL(unpackSize) && - unpackSize != 0) - { - wchar_t s[32]; - UInt64 ratio = packSize * 100 / unpackSize; - if (_ratio_Prev != ratio) - { - _ratio_Prev = ratio; - ConvertUInt64ToString(ratio, s); - wcscat(s, L"%"); - SetItemText(IDT_PROGRESS_RATIO_VAL, s); - } - } - } - } - - if (needSetTitle || titleFileName_Changed) - SetTitleText(); - - if (status_Changed) - { - UString s = _status; - ReduceString(s, _numReduceSymbols); - SetItemText(IDT_PROGRESS_STATUS, _status); - } - - if (curFilePath_Changed) - { - UString s1, s2; - if (_isDir) - s1 = _filePath; - else - { - int slashPos = _filePath.ReverseFind_PathSepar(); - if (slashPos >= 0) - { - s1.SetFrom(_filePath, slashPos + 1); - s2 = _filePath.Ptr(slashPos + 1); - } - else - s2 = _filePath; - } - ReduceString(s1, _numReduceSymbols); - ReduceString(s2, _numReduceSymbols); - s1.Add_LF(); - s1 += s2; - SetItemText(IDT_PROGRESS_FILE_NAME, s1); - } -} - -bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) -{ - if (Sync.Get_Paused()) - return true; - CheckNeedClose(); - UpdateStatInfo(false); - return true; -} - -#ifdef _WIN32 // FIXME -struct CWaitCursor -{ - HCURSOR _waitCursor; - HCURSOR _oldCursor; - CWaitCursor() - { - _waitCursor = LoadCursor(NULL, IDC_WAIT); - if (_waitCursor != NULL) - _oldCursor = SetCursor(_waitCursor); - } - ~CWaitCursor() - { - if (_waitCursor != NULL) - SetCursor(_oldCursor); - } -}; -#endif - -INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, HWND wndParent) -{ - INT_PTR res = 0; - try - { -#ifdef _WIN32 - if (WaitMode) - { - CWaitCursor waitCursor; - HANDLE h[] = { thread, _createDialogEvent }; - - WRes res = WaitForMultipleObjects(ARRAY_SIZE(h), h, FALSE, kCreateDelay); - if (res == WAIT_OBJECT_0 && !Sync.ThereIsMessage()) - return 0; - } -#endif - _title = title; - BIG_DIALOG_SIZE(360, 192); - res = CModalDialog::Create(SIZED_DIALOG(IDD_PROGRESS), wndParent); - } - catch(...) - { - _wasCreated = true; - _dialogCreatedEvent.Set(); - res = res; - } - thread.Wait(); - if (!MessagesDisplayed) - MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR); - return res; -} - -bool CProgressDialog::OnExternalCloseMessage() -{ - // it doesn't work if there is MessageBox. - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - SetTaskbarProgressState(TBPF_NOPROGRESS); - #endif - // AddToTitle(L"Finished "); - // SetText(L"Finished2 "); - - UpdateStatInfo(true); - - SetItemText(IDCANCEL, LangString(IDS_CLOSE)); - // FIXME ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); - HideItem(IDB_PROGRESS_BACKGROUND); - HideItem(IDB_PAUSE); - - bool thereAreMessages; - CProgressFinalMessage fm; - { - NSynchronization::CCriticalSectionLock lock(Sync._cs); - thereAreMessages = !Sync.Messages.IsEmpty(); - fm = Sync.FinalMessage; - } - if (!fm.ErrorMessage.Message.IsEmpty()) - { - MessagesDisplayed = true; - if (fm.ErrorMessage.Title.IsEmpty()) - fm.ErrorMessage.Title = L"7-Zip"; - MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR); - } - else if (!thereAreMessages) - { - MessagesDisplayed = true; - if (!fm.OkMessage.Message.IsEmpty()) - { - if (fm.OkMessage.Title.IsEmpty()) - fm.OkMessage.Title = L"7-Zip"; - MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK); - } - } - - if (thereAreMessages && !_cancelWasPressed) - { -#ifdef _WIN32 - _waitCloseByCancelButton = true; - UpdateMessagesDialog(); - return true; -#else - - // FIXME : p7zip does not have a messages zone - // FIXME : even if so, the close button does not close the main window - // So p7zip uses a MessageBoxW ... - UStringVector messages; - { - NWindows::NSynchronization::CCriticalSectionLock lock(Sync._cs); - for (int i = 0; i < Sync.Messages.Size(); i++) - messages.Add(Sync.Messages[i]); - _numPostedMessages = Sync.Messages.Size(); - } - - if (!messages.IsEmpty()) - { - for (int i = 0; i < messages.Size(); i++) - fm.ErrorMessage.Message = fm.ErrorMessage.Message + messages[i] + L"\n"; - } - else - fm.ErrorMessage.Message = L"Error(s) in the archive"; - - MessageBoxW(*this, fm.ErrorMessage.Message, L"7-Zip - ERROR", MB_ICONERROR | MB_OK); - - MessagesDisplayed = true; -#endif - } - - End(0); - return true; -} - -bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case kCloseMessage: - { - KillTimer(_timer); - _timer = 0; - if (_inCancelMessageBox) - { - _externalCloseMessageWasReceived = true; - break; - } - return OnExternalCloseMessage(); - } - /* - case WM_SETTEXT: - { - if (_timer == 0) - return true; - break; - } - */ - } - return CModalDialog::OnMessage(message, wParam, lParam); -} - -void CProgressDialog::SetTitleText() -{ - UString s; - if (Sync.Get_Paused()) - { - s += _paused_String; - s.Add_Space(); - } - if (IS_DEFINED_VAL(_prevPercentValue)) - { - char temp[32]; - ConvertUInt64ToString(_prevPercentValue, temp); - s.AddAscii(temp); - s += L'%'; - } - if (!_foreground) - { - s.Add_Space(); - s += _backgrounded_String; - } - - s.Add_Space(); - #ifndef _SFX - { - unsigned len = s.Len(); - s += MainAddTitle; - AddToTitle(s); - s.DeleteFrom(len); - } - #endif - - s += _title; - if (!_titleFileName.IsEmpty()) - { - UString fileName = _titleFileName; - ReduceString(fileName, kTitleFileNameSizeLimit); - s.Add_Space(); - s += fileName; - } - SetText(s); -} - -void CProgressDialog::SetPauseText() -{ - SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); - SetTitleText(); -} - -void CProgressDialog::OnPauseButton() -{ - bool paused = !Sync.Get_Paused(); - Sync.Set_Paused(paused); - UInt32 curTime = ::GetTickCount(); - if (paused) - _elapsedTime += (curTime - _prevTime); - SetTaskbarProgressState(); - _prevTime = curTime; - SetPauseText(); -} - -void CProgressDialog::SetPriorityText() -{ - SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ? - _background_String : - _foreground_String); - SetTitleText(); -} - -void CProgressDialog::OnPriorityButton() -{ - _foreground = !_foreground; - #ifndef UNDER_CE - SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); - #endif - SetPriorityText(); -} - -void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber) -{ -#ifdef _WIN32 // FIXME - int itemIndex = _messageList.GetItemCount(); - wchar_t sz[16]; - sz[0] = 0; - if (needNumber) - ConvertUInt32ToString(_numMessages + 1, sz); - _messageList.InsertItem(itemIndex, sz); - _messageList.SetSubItem(itemIndex, 1, message); -#endif -} - -void CProgressDialog::AddMessage(LPCWSTR message) -{ - UString s = message; - bool needNumber = true; - while (!s.IsEmpty()) - { - int pos = s.Find(L'\n'); - if (pos < 0) - break; - AddMessageDirect(s.Left(pos), needNumber); - needNumber = false; - s.DeleteFrontal(pos + 1); - } - AddMessageDirect(s, needNumber); - _numMessages++; -} - -static unsigned GetNumDigits(UInt32 val) -{ - unsigned i; - for (i = 0; val >= 10; i++) - val /= 10; - return i; -} - -void CProgressDialog::UpdateMessagesDialog() -{ - UStringVector messages; - { - NSynchronization::CCriticalSectionLock lock(Sync._cs); - unsigned num = Sync.Messages.Size(); - if (num > _numPostedMessages) - { - messages.ClearAndReserve(num - _numPostedMessages); - for (unsigned i = _numPostedMessages; i < num; i++) - messages.AddInReserved(Sync.Messages[i]); - _numPostedMessages = num; - } - } - if (!messages.IsEmpty()) - { - FOR_VECTOR (i, messages) - AddMessage(messages[i]); - if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages)) - { - // FIXME _messageList.SetColumnWidthAuto(0); - // FIXME _messageList.SetColumnWidthAuto(1); - _numAutoSizeMessages = _numPostedMessages; - } - } -} - - -bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - // case IDOK: // if IDCANCEL is not DEFPUSHBUTTON - case IDCANCEL: - { - if (_waitCloseByCancelButton) - { - MessagesDisplayed = true; - End(IDCLOSE); - break; - } - - bool paused = Sync.Get_Paused(); - if (!paused) - OnPauseButton(); - _inCancelMessageBox = true; - int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL); - _inCancelMessageBox = false; - if (!paused) - OnPauseButton(); - if (res == IDCANCEL || res == IDNO) - { - if (_externalCloseMessageWasReceived) - OnExternalCloseMessage(); - return true; - } - - _cancelWasPressed = true; - MessagesDisplayed = true; - break; - } - - case IDB_PAUSE: - OnPauseButton(); - return true; - case IDB_PROGRESS_BACKGROUND: - OnPriorityButton(); - return true; - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CProgressDialog::CheckNeedClose() -{ - if (_needClose) - { - PostMsg(kCloseMessage); - _needClose = false; - } -} - -void CProgressDialog::ProcessWasFinished() -{ - // Set Window title here. - // FIXME - not supported if (!WaitMode) - WaitCreating(); - - if (_wasCreated) - PostMsg(kCloseMessage); - else - _needClose = true; -} - - -HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) -{ - NWindows::CThread thread; - RINOK(thread.Create(MyThreadFunction, this)); - ProgressDialog.Create(title, thread, parentWindow); - return S_OK; -} - -static void AddMessageToString(UString &dest, const UString &src) -{ - if (!src.IsEmpty()) - { - if (!dest.IsEmpty()) - dest.Add_LF(); - dest += src; - } -} - -void CProgressThreadVirt::Process() -{ - CProgressCloser closer(ProgressDialog); - UString m; - try { Result = ProcessVirt(); } - catch(const wchar_t *s) { m = s; } - catch(const UString &s) { m = s; } - catch(const char *s) { m = GetUnicodeString(s); } - catch(int v) - { - wchar_t s[16]; - ConvertUInt32ToString(v, s); - m = L"Error #"; - m += s; - } - catch(...) { m = L"Error"; } - if (Result != E_ABORT) - { - if (m.IsEmpty() && Result != S_OK) - m = HResultToMessage(Result); - } - AddMessageToString(m, FinalMessage.ErrorMessage.Message); - - { - FOR_VECTOR(i, ErrorPaths) - { - if (i >= 32) - break; - AddMessageToString(m, fs2us(ErrorPaths[i])); - } - } - - CProgressSync &sync = ProgressDialog.Sync; - NSynchronization::CCriticalSectionLock lock(sync._cs); - if (m.IsEmpty()) - { - if (!FinalMessage.OkMessage.Message.IsEmpty()) - sync.FinalMessage.OkMessage = FinalMessage.OkMessage; - } - else - { - sync.FinalMessage.ErrorMessage.Message = m; - if (Result == S_OK) - Result = E_FAIL; - } -} - -UString HResultToMessage(HRESULT errorCode) -{ - if (errorCode == E_OUTOFMEMORY) - return LangString(IDS_MEM_ERROR); - else - return NError::MyFormatMessage(errorCode); -} +// ProgressDialog2.cpp + +#include "StdAfx.h" + +#ifdef Z7_OLD_WIN_SDK +#include +#endif + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/Clipboard.h" +#include "../../../Windows/ErrorMsg.h" + +#include "../GUI/ExtractRes.h" + +#include "LangUtils.h" + +#include "DialogSize.h" +#include "ProgressDialog2.h" +#include "ProgressDialog2Res.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; +extern bool g_DisableUserQuestions; + +static const UINT_PTR kTimerID = 3; + +static const UINT kCloseMessage = WM_APP + 1; +// we can't use WM_USER, since WM_USER can be used by standard Windows procedure for Dialog + +static const UINT kTimerElapse = + #ifdef UNDER_CE + 500 + #else + 200 + #endif + ; + +static const UINT kCreateDelay = + #ifdef UNDER_CE + 2500 + #else + 500 + #endif + ; + +static const DWORD kPauseSleepTime = 100; + +#ifdef Z7_LANG + +static const UInt32 kLangIDs[] = +{ + IDT_PROGRESS_ELAPSED, + IDT_PROGRESS_REMAINING, + IDT_PROGRESS_TOTAL, + IDT_PROGRESS_SPEED, + IDT_PROGRESS_PROCESSED, + IDT_PROGRESS_RATIO, + IDT_PROGRESS_ERRORS, + IDB_PROGRESS_BACKGROUND, + IDB_PAUSE +}; + +static const UInt32 kLangIDs_Colon[] = +{ + IDT_PROGRESS_PACKED, + IDT_PROGRESS_FILES +}; + +#endif + + +#define UNDEFINED_VAL ((UInt64)(Int64)-1) +#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL; +#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL) +#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) + +CProgressSync::CProgressSync(): + _stopped(false), + _paused(false), + _filesProgressMode(false), + _isDir(false), + _totalBytes(UNDEFINED_VAL), _completedBytes(0), + _totalFiles(UNDEFINED_VAL), _curFiles(0), + _inSize(UNDEFINED_VAL), + _outSize(UNDEFINED_VAL) + {} + +#define CHECK_STOP if (_stopped) return E_ABORT; if (!_paused) return S_OK; +#define CRITICAL_LOCK NSynchronization::CCriticalSectionLock lock(_cs); + +bool CProgressSync::Get_Paused() +{ + CRITICAL_LOCK + return _paused; +} + +HRESULT CProgressSync::CheckStop() +{ + for (;;) + { + { + CRITICAL_LOCK + CHECK_STOP + } + ::Sleep(kPauseSleepTime); + } +} + +void CProgressSync::Clear_Stop_Status() +{ + CRITICAL_LOCK + if (_stopped) + _stopped = false; +} + +HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir) +{ + { + CRITICAL_LOCK + _totalFiles = numFiles; + _totalBytes = totalSize; + _filePath = fs2us(fileName); + _isDir = isDir; + // _completedBytes = 0; + CHECK_STOP + } + return CheckStop(); +} + +HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val) +{ + { + CRITICAL_LOCK + _totalFiles = val; + CHECK_STOP + } + return CheckStop(); +} + +void CProgressSync::Set_NumBytesTotal(UInt64 val) +{ + CRITICAL_LOCK + _totalBytes = val; +} + +void CProgressSync::Set_NumFilesCur(UInt64 val) +{ + CRITICAL_LOCK + _curFiles = val; +} + +HRESULT CProgressSync::Set_NumBytesCur(const UInt64 *val) +{ + { + CRITICAL_LOCK + if (val) + _completedBytes = *val; + CHECK_STOP + } + return CheckStop(); +} + +HRESULT CProgressSync::Set_NumBytesCur(UInt64 val) +{ + { + CRITICAL_LOCK + _completedBytes = val; + CHECK_STOP + } + return CheckStop(); +} + +void CProgressSync::Set_Ratio(const UInt64 *inSize, const UInt64 *outSize) +{ + CRITICAL_LOCK + if (inSize) + _inSize = *inSize; + if (outSize) + _outSize = *outSize; +} + +void CProgressSync::Set_TitleFileName(const UString &fileName) +{ + CRITICAL_LOCK + _titleFileName = fileName; +} + +void CProgressSync::Set_Status(const UString &s) +{ + CRITICAL_LOCK + _status = s; +} + +HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir) +{ + { + CRITICAL_LOCK + _status = s; + if (path) + _filePath = path; + else + _filePath.Empty(); + _isDir = isDir; + } + return CheckStop(); +} + +void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir) +{ + CRITICAL_LOCK + if (path) + _filePath = path; + else + _filePath.Empty(); + _isDir = isDir; +} + + +void CProgressSync::AddError_Message(const wchar_t *message) +{ + CRITICAL_LOCK + Messages.Add(message); +} + +void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t *name) +{ + UString s; + if (name && *name != 0) + s += name; + if (message && *message != 0) + { + if (!s.IsEmpty()) + s.Add_LF(); + s += message; + if (!s.IsEmpty() && s.Back() == L'\n') + s.DeleteBack(); + } + AddError_Message(s); +} + +void CProgressSync::AddError_Code_Name(HRESULT systemError, const wchar_t *name) +{ + UString s = NError::MyFormatMessage(systemError); + if (systemError == 0) + s = "Error"; + AddError_Message_Name(s, name); +} + +CProgressDialog::CProgressDialog(): + _isDir(false), + _wasCreated(false), + _needClose(false), + _errorsWereDisplayed(false), + _waitCloseByCancelButton(false), + _cancelWasPressed(false), + _inCancelMessageBox(false), + _externalCloseMessageWasReceived(false), + _background(false), + WaitMode(false), + MessagesDisplayed(false), + CompressingMode(true), + ShowCompressionInfo(true), + _numPostedMessages(0), + _numAutoSizeMessages(0), + _numMessages(0), + _timer(0), + IconID(-1), + MainWindow(NULL) +{ + + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + if (_createDialogEvent.Create() != S_OK) + throw 1334987; + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList); + if (_taskbarList) + _taskbarList->HrInit(); + // #endif +} + +#ifndef Z7_SFX + +CProgressDialog::~CProgressDialog() +{ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + SetTaskbarProgressState(TBPF_NOPROGRESS); + // #endif + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow) + { + CWindow window(MainWindow); + window.SetText((UString)s + MainTitle); + } +} + +#endif + + +void CProgressDialog::SetTaskbarProgressState() +{ + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + if (_taskbarList && _hwndForTaskbar) + { + TBPFLAG tbpFlags; + if (Sync.Get_Paused()) + tbpFlags = TBPF_PAUSED; + else + tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL; + SetTaskbarProgressState(tbpFlags); + } + // #endif +} + +static const unsigned kTitleFileNameSizeLimit = 36; +static const unsigned kCurrentFileNameSizeLimit = 82; + +static void ReduceString(UString &s, unsigned size) +{ + if (s.Len() <= size) + return; + s.Delete(size / 2, s.Len() - size); + s.Insert(size / 2, L" ... "); +} + +void CProgressDialog::EnableErrorsControls(bool enable) +{ + ShowItem_Bool(IDT_PROGRESS_ERRORS, enable); + ShowItem_Bool(IDT_PROGRESS_ERRORS_VAL, enable); + ShowItem_Bool(IDL_PROGRESS_MESSAGES, enable); +} + +bool CProgressDialog::OnInit() +{ + _hwndForTaskbar = MainWindow; + if (!_hwndForTaskbar) + _hwndForTaskbar = GetParent(); + if (!_hwndForTaskbar) + _hwndForTaskbar = *this; + + INIT_AS_UNDEFINED(_progressBar_Range) + INIT_AS_UNDEFINED(_progressBar_Pos) + + INIT_AS_UNDEFINED(_prevPercentValue) + INIT_AS_UNDEFINED(_prevElapsedSec) + INIT_AS_UNDEFINED(_prevRemainingSec) + + INIT_AS_UNDEFINED(_prevSpeed) + _prevSpeed_MoveBits = 0; + + _prevTime = ::GetTickCount(); + _elapsedTime = 0; + + INIT_AS_UNDEFINED(_totalBytes_Prev) + INIT_AS_UNDEFINED(_processed_Prev) + INIT_AS_UNDEFINED(_packed_Prev) + INIT_AS_UNDEFINED(_ratio_Prev) + + _filesStr_Prev.Empty(); + _filesTotStr_Prev.Empty(); + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); + _messageList.SetUnicodeFormat(); + _messageList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); + + _wasCreated = true; + _dialogCreatedEvent.Set(); + + #ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + LangSetDlgItems_Colon(*this, kLangIDs_Colon, Z7_ARRAY_SIZE(kLangIDs_Colon)); + #endif + + CWindow window(GetItem(IDB_PROGRESS_BACKGROUND)); + window.GetText(_background_String); + _backgrounded_String = _background_String; + _backgrounded_String.RemoveChar(L'&'); + + window = GetItem(IDB_PAUSE); + window.GetText(_pause_String); + + LangString(IDS_PROGRESS_FOREGROUND, _foreground_String); + LangString(IDS_CONTINUE, _continue_String); + LangString(IDS_PROGRESS_PAUSED, _paused_String); + + SetText(_title); + SetPauseText(); + SetPriorityText(); + + _messageList.InsertColumn(0, L"", 40); + _messageList.InsertColumn(1, L"", 460); + _messageList.SetColumnWidthAuto(0); + _messageList.SetColumnWidthAuto(1); + + EnableErrorsControls(false); + + GetItemSizes(IDCANCEL, _buttonSizeX, _buttonSizeY); + _numReduceSymbols = kCurrentFileNameSizeLimit; + NormalizeSize(true); + + if (!ShowCompressionInfo) + { + HideItem(IDT_PROGRESS_PACKED); + HideItem(IDT_PROGRESS_PACKED_VAL); + HideItem(IDT_PROGRESS_RATIO); + HideItem(IDT_PROGRESS_RATIO_VAL); + } + + if (IconID >= 0) + { + HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID)); + // SetIcon(ICON_SMALL, icon); + SetIcon(ICON_BIG, icon); + } + _timer = SetTimer(kTimerID, kTimerElapse); + #ifdef UNDER_CE + Foreground(); + #endif + + CheckNeedClose(); + + SetTaskbarProgressState(); + + return CModalDialog::OnInit(); +} + +static const UINT kIDs[] = +{ + IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL, + IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL, + IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL, + 0, IDT_PROGRESS_FILES_TOTAL, + IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL, + + IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL, + IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL, + IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL, + IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL, + IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL +}; + +bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int sY; + int sStep; + int mx, my; + { + RECT r; + GetClientRectOfItem(IDT_PROGRESS_ELAPSED, r); + mx = r.left; + my = r.top; + sY = RECT_SIZE_Y(r); + GetClientRectOfItem(IDT_PROGRESS_REMAINING, r); + sStep = r.top - my; + } + + InvalidateRect(NULL); + + const int xSizeClient = xSize - mx * 2; + + { + unsigned i; + for (i = 800; i > 40; i = i * 9 / 10) + if (Units_To_Pixels_X((int)i) <= xSizeClient) + break; + _numReduceSymbols = i / 4; + } + + int yPos = ySize - my - _buttonSizeY; + + ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2); + ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2); + ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2); + + int bSizeX = _buttonSizeX; + int mx2 = mx; + for (;; mx2--) + { + const int bSize2 = bSizeX * 3 + mx2 * 2; + if (bSize2 <= xSizeClient) + break; + if (mx2 < 5) + { + bSizeX = (xSizeClient - mx2 * 2) / 3; + break; + } + } + if (bSizeX < 2) + bSizeX = 2; + + { + RECT r; + GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r); + const int y = r.top; + int ySize2 = yPos - my - y; + const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4; + int xx = xSize - mx * 2; + if (ySize2 < kMinYSize) + { + ySize2 = kMinYSize; + if (xx > bSizeX * 2) + xx -= bSizeX; + } + + _messageList.Move(mx, y, xx, ySize2); + } + + { + int xPos = xSize - mx; + xPos -= bSizeX; + MoveItem(IDCANCEL, xPos, yPos, bSizeX, _buttonSizeY); + xPos -= (mx2 + bSizeX); + MoveItem(IDB_PAUSE, xPos, yPos, bSizeX, _buttonSizeY); + xPos -= (mx2 + bSizeX); + MoveItem(IDB_PROGRESS_BACKGROUND, xPos, yPos, bSizeX, _buttonSizeY); + } + + int valueSize; + int labelSize; + int padSize; + + labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN); + valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS); + padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS); + const int requiredSize = (labelSize + valueSize) * 2 + padSize; + + int gSize; + { + if (requiredSize < xSizeClient) + { + const int incr = (xSizeClient - requiredSize) / 3; + labelSize += incr; + } + else + labelSize = (xSizeClient - valueSize * 2 - padSize) / 2; + if (labelSize < 0) + labelSize = 0; + + gSize = labelSize + valueSize; + padSize = xSizeClient - gSize * 2; + } + + labelSize = gSize - valueSize; + + yPos = my; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(kIDs); i += 2) + { + int x = mx; + const unsigned kNumColumn1Items = 5 * 2; + if (i >= kNumColumn1Items) + { + if (i == kNumColumn1Items) + yPos = my; + x = mx + gSize + padSize; + } + if (kIDs[i] != 0) + MoveItem(kIDs[i], x, yPos, labelSize, sY); + MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY); + yPos += sStep; + } + return false; +} + +void CProgressDialog::OnCancel() { Sync.Set_Stopped(true); } +void CProgressDialog::OnOK() { } + +void CProgressDialog::SetProgressRange(UInt64 range) +{ + if (range == _progressBar_Range) + return; + _progressBar_Range = range; + INIT_AS_UNDEFINED(_progressBar_Pos) + _progressConv.Init(range); + m_ProgressBar.SetRange32(0, _progressConv.Count(range)); +} + +void CProgressDialog::SetProgressPos(UInt64 pos) +{ + if (pos >= _progressBar_Range || + pos <= _progressBar_Pos || + pos - _progressBar_Pos >= (_progressBar_Range >> 10)) + { + m_ProgressBar.SetPos(_progressConv.Count(pos)); + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + if (_taskbarList && _hwndForTaskbar) + _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range); + // #endif + _progressBar_Pos = pos; + } +} + +#define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; } + +void GetTimeString(UInt64 timeValue, wchar_t *s); +void GetTimeString(UInt64 timeValue, wchar_t *s) +{ + UInt64 hours = timeValue / 3600; + UInt32 seconds = (UInt32)(timeValue - hours * 3600); + UInt32 minutes = seconds / 60; + seconds %= 60; + if (hours > 99) + { + ConvertUInt64ToString(hours, s); + for (; *s != 0; s++); + } + else + { + UInt32 hours32 = (UInt32)hours; + UINT_TO_STR_2(hours32) + } + *s++ = ':'; UINT_TO_STR_2(minutes) + *s++ = ':'; UINT_TO_STR_2(seconds) + *s = 0; +} + +static void ConvertSizeToString(UInt64 v, wchar_t *s) +{ + Byte c = 0; + if (v >= ((UInt64)100000 << 20)) { v >>= 30; c = 'G'; } + else if (v >= ((UInt64)100000 << 10)) { v >>= 20; c = 'M'; } + else if (v >= ((UInt64)100000 << 0)) { v >>= 10; c = 'K'; } + ConvertUInt64ToString(v, s); + if (c != 0) + { + s += MyStringLen(s); + *s++ = ' '; + *s++ = c; + *s++ = 'B'; + *s++ = 0; + } +} + +void CProgressDialog::ShowSize(unsigned id, UInt64 val, UInt64 &prev) +{ + if (val == prev) + return; + prev = val; + wchar_t s[40]; + s[0] = 0; + if (IS_DEFINED_VAL(val)) + ConvertSizeToString(val, s); + SetItemText(id, s); +} + +static void GetChangedString(const UString &newStr, UString &prevStr, bool &hasChanged) +{ + hasChanged = !(prevStr == newStr); + if (hasChanged) + prevStr = newStr; +} + +static unsigned GetPower32(UInt32 val) +{ + const unsigned kStart = 32; + UInt32 mask = ((UInt32)1 << (kStart - 1)); + for (unsigned i = kStart;; i--) + { + if (i == 0 || (val & mask) != 0) + return i; + mask >>= 1; + } +} + +static unsigned GetPower64(UInt64 val) +{ + UInt32 high = (UInt32)(val >> 32); + if (high == 0) + return GetPower32((UInt32)val); + return GetPower32(high) + 32; +} + +static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider) +{ + unsigned pow1 = GetPower64(mult1); + unsigned pow2 = GetPower64(mult2); + while (pow1 + pow2 > 64) + { + if (pow1 > pow2) { pow1--; mult1 >>= 1; } + else { pow2--; mult2 >>= 1; } + divider >>= 1; + } + UInt64 res = mult1 * mult2; + if (divider != 0) + res /= divider; + return res; +} + +void CProgressDialog::UpdateStatInfo(bool showAll) +{ + UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; + bool filesProgressMode; + + bool titleFileName_Changed; + bool curFilePath_Changed; + bool status_Changed; + unsigned numErrors; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + total = Sync._totalBytes; + completed = Sync._completedBytes; + totalFiles = Sync._totalFiles; + completedFiles = Sync._curFiles; + inSize = Sync._inSize; + outSize = Sync._outSize; + filesProgressMode = Sync._filesProgressMode; + + GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed); + GetChangedString(Sync._filePath, _filePath, curFilePath_Changed); + GetChangedString(Sync._status, _status, status_Changed); + if (_isDir != Sync._isDir) + { + curFilePath_Changed = true; + _isDir = Sync._isDir; + } + numErrors = Sync.Messages.Size(); + } + + UInt32 curTime = ::GetTickCount(); + + const UInt64 progressTotal = filesProgressMode ? totalFiles : total; + const UInt64 progressCompleted = filesProgressMode ? completedFiles : completed; + { + if (IS_UNDEFINED_VAL(progressTotal)) + { + // SetPos(0); + // SetRange(progressCompleted); + } + else + { + if (_progressBar_Pos != 0 || progressCompleted != 0 || + (_progressBar_Range == 0 && progressTotal != 0)) + { + SetProgressRange(progressTotal); + SetProgressPos(progressCompleted); + } + } + } + + ShowSize(IDT_PROGRESS_TOTAL_VAL, total, _totalBytes_Prev); + + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + UInt64 elapsedSec = _elapsedTime / 1000; + bool elapsedChanged = false; + if (elapsedSec != _prevElapsedSec) + { + _prevElapsedSec = elapsedSec; + elapsedChanged = true; + wchar_t s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDT_PROGRESS_ELAPSED_VAL, s); + } + + bool needSetTitle = false; + if (elapsedChanged || showAll) + { + if (numErrors > _numPostedMessages) + { + UpdateMessagesDialog(); + wchar_t s[32]; + ConvertUInt64ToString(numErrors, s); + SetItemText(IDT_PROGRESS_ERRORS_VAL, s); + if (!_errorsWereDisplayed) + { + _errorsWereDisplayed = true; + EnableErrorsControls(true); + SetTaskbarProgressState(); + } + } + + if (progressCompleted != 0) + { + if (IS_UNDEFINED_VAL(progressTotal)) + { + if (IS_DEFINED_VAL(_prevRemainingSec)) + { + INIT_AS_UNDEFINED(_prevRemainingSec) + SetItemText(IDT_PROGRESS_REMAINING_VAL, L""); + } + } + else + { + UInt64 remainingTime = 0; + if (progressCompleted < progressTotal) + remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted); + UInt64 remainingSec = remainingTime / 1000; + if (remainingSec != _prevRemainingSec) + { + _prevRemainingSec = remainingSec; + wchar_t s[40]; + GetTimeString(remainingSec, s); + SetItemText(IDT_PROGRESS_REMAINING_VAL, s); + } + } + { + const UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime; + // 22.02: progressCompleted can be for number of files + UInt64 v = (completed * 1000) / elapsedTime; + Byte c = 0; + unsigned moveBits = 0; + if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; } + else if (v >= ((UInt64)10000 << 0)) { moveBits = 10; c = 'K'; } + v >>= moveBits; + if (moveBits != _prevSpeed_MoveBits || v != _prevSpeed) + { + _prevSpeed_MoveBits = moveBits; + _prevSpeed = v; + wchar_t s[40]; + ConvertUInt64ToString(v, s); + unsigned pos = MyStringLen(s); + s[pos++] = ' '; + if (moveBits != 0) + s[pos++] = c; + s[pos++] = 'B'; + s[pos++] = '/'; + s[pos++] = 's'; + s[pos++] = 0; + SetItemText(IDT_PROGRESS_SPEED_VAL, s); + } + } + } + + { + UInt64 percent = 0; + { + if (IS_DEFINED_VAL(progressTotal)) + { + percent = progressCompleted * 100; + if (progressTotal != 0) + percent /= progressTotal; + } + } + if (percent != _prevPercentValue) + { + _prevPercentValue = percent; + needSetTitle = true; + } + } + + { + wchar_t s[64]; + + ConvertUInt64ToString(completedFiles, s); + if (_filesStr_Prev != s) + { + _filesStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_VAL, s); + } + + s[0] = 0; + if (IS_DEFINED_VAL(totalFiles)) + { + MyStringCopy(s, L" / "); + ConvertUInt64ToString(totalFiles, s + MyStringLen(s)); + } + if (_filesTotStr_Prev != s) + { + _filesTotStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_TOTAL, s); + } + } + + const UInt64 packSize = CompressingMode ? outSize : inSize; + const UInt64 unpackSize = CompressingMode ? inSize : outSize; + + if (IS_UNDEFINED_VAL(unpackSize) && + IS_UNDEFINED_VAL(packSize)) + { + ShowSize(IDT_PROGRESS_PROCESSED_VAL, completed, _processed_Prev); + ShowSize(IDT_PROGRESS_PACKED_VAL, UNDEFINED_VAL, _packed_Prev); + } + else + { + ShowSize(IDT_PROGRESS_PROCESSED_VAL, unpackSize, _processed_Prev); + ShowSize(IDT_PROGRESS_PACKED_VAL, packSize, _packed_Prev); + + if (IS_DEFINED_VAL(packSize) && + IS_DEFINED_VAL(unpackSize) && + unpackSize != 0) + { + wchar_t s[32]; + UInt64 ratio = packSize * 100 / unpackSize; + if (_ratio_Prev != ratio) + { + _ratio_Prev = ratio; + ConvertUInt64ToString(ratio, s); + MyStringCat(s, L"%"); + SetItemText(IDT_PROGRESS_RATIO_VAL, s); + } + } + } + } + + if (needSetTitle || titleFileName_Changed) + SetTitleText(); + + if (status_Changed) + { + UString s = _status; + ReduceString(s, _numReduceSymbols); + SetItemText(IDT_PROGRESS_STATUS, s); + } + + if (curFilePath_Changed) + { + UString s1, s2; + if (_isDir) + s1 = _filePath; + else + { + int slashPos = _filePath.ReverseFind_PathSepar(); + if (slashPos >= 0) + { + s1.SetFrom(_filePath, (unsigned)(slashPos + 1)); + s2 = _filePath.Ptr((unsigned)(slashPos + 1)); + } + else + s2 = _filePath; + } + ReduceString(s1, _numReduceSymbols); + ReduceString(s2, _numReduceSymbols); + s1.Add_LF(); + s1 += s2; + SetItemText(IDT_PROGRESS_FILE_NAME, s1); + } +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (Sync.Get_Paused()) + return true; + CheckNeedClose(); + UpdateStatInfo(false); + return true; +} + +struct CWaitCursor +{ + HCURSOR _waitCursor; + HCURSOR _oldCursor; + CWaitCursor() + { + _waitCursor = LoadCursor(NULL, IDC_WAIT); + if (_waitCursor != NULL) + _oldCursor = SetCursor(_waitCursor); + } + ~CWaitCursor() + { + if (_waitCursor != NULL) + SetCursor(_oldCursor); + } +}; + +INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, HWND wndParent) +{ + INT_PTR res = 0; + try + { + if (WaitMode) + { + CWaitCursor waitCursor; + HANDLE h[] = { thread, _createDialogEvent }; + + const DWORD res2 = WaitForMultipleObjects(Z7_ARRAY_SIZE(h), h, FALSE, kCreateDelay); + if (res2 == WAIT_OBJECT_0 && !Sync.ThereIsMessage()) + return 0; + } + _title = title; + BIG_DIALOG_SIZE(360, 192); + res = CModalDialog::Create(SIZED_DIALOG(IDD_PROGRESS), wndParent); + } + catch(...) + { + _wasCreated = true; + _dialogCreatedEvent.Set(); + } + thread.Wait_Close(); + if (!MessagesDisplayed) + if (!g_DisableUserQuestions) + MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR); + return res; +} + +bool CProgressDialog::OnExternalCloseMessage() +{ + // it doesn't work if there is MessageBox. + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + SetTaskbarProgressState(TBPF_NOPROGRESS); + // #endif + // AddToTitle(L"Finished "); + // SetText(L"Finished2 "); + + UpdateStatInfo(true); + + SetItemText(IDCANCEL, LangString(IDS_CLOSE)); + ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); + HideItem(IDB_PROGRESS_BACKGROUND); + HideItem(IDB_PAUSE); + + ProcessWasFinished_GuiVirt(); + + bool thereAreMessages; + CProgressFinalMessage fm; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + thereAreMessages = !Sync.Messages.IsEmpty(); + fm = Sync.FinalMessage; + } + + if (!fm.ErrorMessage.Message.IsEmpty()) + { + MessagesDisplayed = true; + if (fm.ErrorMessage.Title.IsEmpty()) + fm.ErrorMessage.Title = "7-Zip"; + if (!g_DisableUserQuestions) + MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR); + } + else if (!thereAreMessages) + { + MessagesDisplayed = true; + + if (!fm.OkMessage.Message.IsEmpty()) + { + if (fm.OkMessage.Title.IsEmpty()) + fm.OkMessage.Title = "7-Zip"; + if (!g_DisableUserQuestions) + MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK); + } + } + + if (!g_DisableUserQuestions) + if (thereAreMessages && !_cancelWasPressed) + { + _waitCloseByCancelButton = true; + UpdateMessagesDialog(); + return true; + } + + End(0); + return true; +} + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case kCloseMessage: + { + if (_timer) + { + /* 21.03 : KillTimer(kTimerID) instead of KillTimer(_timer). + But (_timer == kTimerID) in Win10. So it worked too */ + KillTimer(kTimerID); + _timer = 0; + } + if (_inCancelMessageBox) + { + /* if user is in MessageBox(), we will call OnExternalCloseMessage() + later, when MessageBox() will be closed */ + _externalCloseMessageWasReceived = true; + break; + } + return OnExternalCloseMessage(); + } + /* + case WM_SETTEXT: + { + if (_timer == 0) + return true; + break; + } + */ + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +void CProgressDialog::SetTitleText() +{ + UString s; + if (Sync.Get_Paused()) + { + s += _paused_String; + s.Add_Space(); + } + if (IS_DEFINED_VAL(_prevPercentValue)) + { + s.Add_UInt64(_prevPercentValue); + s.Add_Char('%'); + } + if (_background) + { + s.Add_Space(); + s += _backgrounded_String; + } + + s.Add_Space(); + #ifndef Z7_SFX + { + unsigned len = s.Len(); + s += MainAddTitle; + AddToTitle(s); + s.DeleteFrom(len); + } + #endif + + s += _title; + if (!_titleFileName.IsEmpty()) + { + UString fileName = _titleFileName; + ReduceString(fileName, kTitleFileNameSizeLimit); + s.Add_Space(); + s += fileName; + } + SetText(s); +} + +void CProgressDialog::SetPauseText() +{ + SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); + SetTitleText(); +} + +void CProgressDialog::OnPauseButton() +{ + bool paused = !Sync.Get_Paused(); + Sync.Set_Paused(paused); + UInt32 curTime = ::GetTickCount(); + if (paused) + _elapsedTime += (curTime - _prevTime); + SetTaskbarProgressState(); + _prevTime = curTime; + SetPauseText(); +} + +void CProgressDialog::SetPriorityText() +{ + SetItemText(IDB_PROGRESS_BACKGROUND, _background ? + _foreground_String : + _background_String); + SetTitleText(); +} + +void CProgressDialog::OnPriorityButton() +{ + _background = !_background; + #ifndef UNDER_CE + SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS); + #endif + SetPriorityText(); +} + +void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber) +{ + wchar_t sz[16]; + sz[0] = 0; + if (needNumber) + ConvertUInt32ToString(_numMessages + 1, sz); + const unsigned itemIndex = _messageStrings.Size(); // _messageList.GetItemCount(); + if (_messageList.InsertItem(itemIndex, sz) == (int)itemIndex) + { + _messageList.SetSubItem(itemIndex, 1, message); + _messageStrings.Add(message); + } +} + +void CProgressDialog::AddMessage(LPCWSTR message) +{ + UString s = message; + bool needNumber = true; + while (!s.IsEmpty()) + { + const int pos = s.Find(L'\n'); + if (pos < 0) + break; + AddMessageDirect(s.Left((unsigned)pos), needNumber); + needNumber = false; + s.DeleteFrontal((unsigned)pos + 1); + } + AddMessageDirect(s, needNumber); + _numMessages++; +} + +static unsigned GetNumDigits(unsigned val) +{ + unsigned i = 0; + for (;;) + { + i++; + val /= 10; + if (val == 0) + return i; + } +} + +void CProgressDialog::UpdateMessagesDialog() +{ + UStringVector messages; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + const unsigned num = Sync.Messages.Size(); + if (num > _numPostedMessages) + { + messages.ClearAndReserve(num - _numPostedMessages); + for (unsigned i = _numPostedMessages; i < num; i++) + messages.AddInReserved(Sync.Messages[i]); + _numPostedMessages = num; + } + } + if (!messages.IsEmpty()) + { + FOR_VECTOR (i, messages) + AddMessage(messages[i]); + // SetColumnWidthAuto() can be slow for big number of files. + if (_numPostedMessages < 1000000 || _numAutoSizeMessages < 100) + if (_numAutoSizeMessages < 100 || + GetNumDigits(_numPostedMessages) > + GetNumDigits(_numAutoSizeMessages)) + { + _messageList.SetColumnWidthAuto(0); + _messageList.SetColumnWidthAuto(1); + _numAutoSizeMessages = _numPostedMessages; + } + } +} + + +bool CProgressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + // case IDOK: // if IDCANCEL is not DEFPUSHBUTTON + case IDCANCEL: + { + if (_waitCloseByCancelButton) + { + MessagesDisplayed = true; + End(IDCLOSE); + break; + } + + if (_cancelWasPressed) + return true; + + const bool paused = Sync.Get_Paused(); + + if (!paused) + { + OnPauseButton(); + } + + _inCancelMessageBox = true; + const int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL); + _inCancelMessageBox = false; + if (res == IDYES) + _cancelWasPressed = true; + + if (!paused) + { + OnPauseButton(); + } + + if (_externalCloseMessageWasReceived) + { + /* we have received kCloseMessage while we were in MessageBoxW(). + so we call OnExternalCloseMessage() here. + it can show MessageBox and it can close dialog */ + OnExternalCloseMessage(); + return true; + } + + if (!_cancelWasPressed) + return true; + + MessagesDisplayed = true; + // we will call Sync.Set_Stopped(true) in OnButtonClicked() : OnCancel() + break; + } + + case IDB_PAUSE: + OnPauseButton(); + return true; + case IDB_PROGRESS_BACKGROUND: + OnPriorityButton(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CProgressDialog::CheckNeedClose() +{ + if (_needClose) + { + PostMsg(kCloseMessage); + _needClose = false; + } +} + +void CProgressDialog::ProcessWasFinished() +{ + // Set Window title here. + if (!WaitMode) + WaitCreating(); + + if (_wasCreated) + PostMsg(kCloseMessage); + else + _needClose = true; +} + + +bool CProgressDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _messageList) + return false; + switch (header->code) + { + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + switch (keyDownInfo->wVKey) + { + case 'A': + { + if (IsKeyDown(VK_CONTROL)) + { + _messageList.SelectAll(); + return true; + } + break; + } + case VK_INSERT: + case 'C': + { + if (IsKeyDown(VK_CONTROL)) + { + CopyToClipboard(); + return true; + } + break; + } + } + } + } + return false; +} + + +static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector) +{ + vector.Clear(); + int index = -1; + for (;;) + { + index = listView.GetNextSelectedItem(index); + if (index < 0) + break; + vector.Add((unsigned)index); + } +} + + +void CProgressDialog::CopyToClipboard() +{ + CUIntVector indexes; + ListView_GetSelected(_messageList, indexes); + UString s; + unsigned numIndexes = indexes.Size(); + if (numIndexes == 0) + numIndexes = (unsigned)_messageList.GetItemCount(); + + for (unsigned i = 0; i < numIndexes; i++) + { + const unsigned index = (i < indexes.Size() ? indexes[i] : i); + // s.Add_UInt32(index); + // s += ": "; + s += _messageStrings[index]; + { + s += + #ifdef _WIN32 + "\r\n" + #else + "\n" + #endif + ; + } + } + + ClipboardSetText(*this, s); +} + + +static THREAD_FUNC_DECL MyThreadFunction(void *param) +{ + CProgressThreadVirt *p = (CProgressThreadVirt *)param; + try + { + p->Process(); + p->ThreadFinishedOK = true; + } + catch (...) { p->Result = E_FAIL; } + return 0; +} + + +HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) +{ + NWindows::CThread thread; + const WRes wres = thread.Create(MyThreadFunction, this); + if (wres != 0) + return HRESULT_FROM_WIN32(wres); + CProgressDialog::Create(title, thread, parentWindow); + return S_OK; +} + +static void AddMessageToString(UString &dest, const UString &src) +{ + if (!src.IsEmpty()) + { + if (!dest.IsEmpty()) + dest.Add_LF(); + dest += src; + } +} + +void CProgressThreadVirt::Process() +{ + CProgressCloser closer(*this); + UString m; + try { Result = ProcessVirt(); } + catch(const wchar_t *s) { m = s; } + catch(const UString &s) { m = s; } + catch(const char *s) { m = GetUnicodeString(s); } + catch(int v) + { + m = "Error #"; + m.Add_UInt32((unsigned)v); + } + catch(...) { m = "Error"; } + if (Result != E_ABORT) + { + if (m.IsEmpty() && Result != S_OK) + m = HResultToMessage(Result); + } + AddMessageToString(m, FinalMessage.ErrorMessage.Message); + + { + FOR_VECTOR(i, ErrorPaths) + { + if (i >= 32) + break; + AddMessageToString(m, fs2us(ErrorPaths[i])); + } + } + + CProgressSync &sync = Sync; + NSynchronization::CCriticalSectionLock lock(sync._cs); + if (m.IsEmpty()) + { + if (!FinalMessage.OkMessage.Message.IsEmpty()) + sync.FinalMessage.OkMessage = FinalMessage.OkMessage; + } + else + { + sync.FinalMessage.ErrorMessage.Message = m; + if (Result == S_OK) + Result = E_FAIL; + } +} + +UString HResultToMessage(HRESULT errorCode) +{ + if (errorCode == E_OUTOFMEMORY) + return LangString(IDS_MEM_ERROR); + else + return NError::MyFormatMessage(errorCode); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.h 2015-06-21 18:50:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.h 2024-10-21 10:00:00.000000000 +0000 @@ -1,313 +1,355 @@ -// ProgressDialog2.h - -#ifndef __PROGRESS_DIALOG_2_H -#define __PROGRESS_DIALOG_2_H - -#include "../../../Common/MyCom.h" - -#include "../../../Windows/ErrorMsg.h" -#include "../../../Windows/Synchronization.h" -#include "../../../Windows/Thread.h" - -#include "../../../Windows/Control/Dialog.h" -#include "../../../Windows/Control/ListView.h" -#include "../../../Windows/Control/ProgressBar.h" - -#include "MyWindowsNew.h" - -struct CProgressMessageBoxPair -{ - UString Title; - UString Message; -}; - -struct CProgressFinalMessage -{ - CProgressMessageBoxPair ErrorMessage; - CProgressMessageBoxPair OkMessage; - - bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); } -}; - -class CProgressSync -{ - bool _stopped; - bool _paused; - -public: - bool _bytesProgressMode; - UInt64 _totalBytes; - UInt64 _completedBytes; - UInt64 _totalFiles; - UInt64 _curFiles; - UInt64 _inSize; - UInt64 _outSize; - - UString _titleFileName; - UString _status; - UString _filePath; - bool _isDir; - - UStringVector Messages; - CProgressFinalMessage FinalMessage; - - NWindows::NSynchronization::CCriticalSection _cs; - - CProgressSync(); - - bool Get_Stopped() - { - NWindows::NSynchronization::CCriticalSectionLock lock(_cs); - return _stopped; - } - void Set_Stopped(bool val) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_cs); - _stopped = val; - } - - bool Get_Paused(); - void Set_Paused(bool val) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_cs); - _paused = val; - } - - void Set_BytesProgressMode(bool bytesProgressMode) - { - NWindows::NSynchronization::CCriticalSectionLock lock(_cs); - _bytesProgressMode = bytesProgressMode; - } - - HRESULT CheckStop(); - HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false); - - HRESULT Set_NumFilesTotal(UInt64 val); - void Set_NumBytesTotal(UInt64 val); - void Set_NumFilesCur(UInt64 val); - HRESULT Set_NumBytesCur(const UInt64 *val); - HRESULT Set_NumBytesCur(UInt64 val); - void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize); - - void Set_TitleFileName(const UString &fileName); - void Set_Status(const UString &s); - HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false); - void Set_FilePath(const wchar_t *path, bool isDir = false); - - void AddError_Message(const wchar_t *message); - void AddError_Message_Name(const wchar_t *message, const wchar_t *name); - void AddError_Code_Name(DWORD systemError, const wchar_t *name); - - bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } -}; - -class CProgressDialog: public NWindows::NControl::CModalDialog -{ - UString _titleFileName; - UString _filePath; - UString _status; - bool _isDir; - - UString _background_String; - UString _backgrounded_String; - UString _foreground_String; - UString _pause_String; - UString _continue_String; - UString _paused_String; - - int _buttonSizeX; - int _buttonSizeY; - - UINT_PTR _timer; - - UString _title; - - class CU64ToI32Converter - { - unsigned _numShiftBits; - UInt64 _range; - public: - CU64ToI32Converter(): _numShiftBits(0), _range(1) {} - void Init(UInt64 range) - { - _range = range; - // Windows CE doesn't like big number for ProgressBar. - for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++) - range >>= 1; - } - int Count(UInt64 val) - { - int res = (int)(val >> _numShiftBits); - if (val == _range) - res++; - return res; - } - }; - - CU64ToI32Converter _progressConv; - UInt64 _progressBar_Pos; - UInt64 _progressBar_Range; - - NWindows::NControl::CProgressBar m_ProgressBar; - // FIXME NWindows::NControl::CListView _messageList; - - int _numMessages; - - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - CMyComPtr _taskbarList; - #endif - HWND _hwndForTaskbar; - - UInt32 _prevTime; - UInt64 _elapsedTime; - - UInt64 _prevPercentValue; - UInt64 _prevElapsedSec; - UInt64 _prevRemainingSec; - - UInt64 _totalBytes_Prev; - UInt64 _processed_Prev; - UInt64 _packed_Prev; - UInt64 _ratio_Prev; - UString _filesStr_Prev; - - unsigned _prevSpeed_MoveBits; - UInt64 _prevSpeed; - - bool _foreground; - - unsigned _numReduceSymbols; - - bool _wasCreated; - bool _needClose; - - unsigned _numPostedMessages; - UInt32 _numAutoSizeMessages; - - bool _errorsWereDisplayed; - - bool _waitCloseByCancelButton; - bool _cancelWasPressed; - - bool _inCancelMessageBox; - bool _externalCloseMessageWasReceived; - - - #ifdef __ITaskbarList3_INTERFACE_DEFINED__ - void SetTaskbarProgressState(TBPFLAG tbpFlags) - { - if (_taskbarList && _hwndForTaskbar) - _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); - } - #endif - void SetTaskbarProgressState(); - - void UpdateStatInfo(bool showAll); - bool OnTimer(WPARAM timerID, LPARAM callback); - void SetProgressRange(UInt64 range); - void SetProgressPos(UInt64 pos); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual void OnCancel(); - virtual void OnOK(); - NWindows::NSynchronization::CManualResetEvent _createDialogEvent; - NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; - #ifndef _SFX - void AddToTitle(LPCWSTR string); - #endif - - void SetPauseText(); - void SetPriorityText(); - void OnPauseButton(); - void OnPriorityButton(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); - bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - - void SetTitleText(); - void ShowSize(int id, UInt64 val, UInt64 &prev); - - void UpdateMessagesDialog(); - - void AddMessageDirect(LPCWSTR message, bool needNumber); - void AddMessage(LPCWSTR message); - - bool OnExternalCloseMessage(); - void EnableErrorsControls(bool enable); - - void ShowAfterMessages(HWND wndParent); - - void CheckNeedClose(); -public: - CProgressSync Sync; - bool CompressingMode; - // FIXME - not supported bool WaitMode; - bool ShowCompressionInfo; - bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. - int IconID; - - HWND MainWindow; - #ifndef _SFX - UString MainTitle; - UString MainAddTitle; - ~CProgressDialog(); - #endif - - CProgressDialog(); - void WaitCreating() - { - _createDialogEvent.Set(); - _dialogCreatedEvent.Lock(); - } - - INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); - - void ProcessWasFinished(); -}; - - -class CProgressCloser -{ - CProgressDialog *_p; -public: - CProgressCloser(CProgressDialog &p) : _p(&p) {} - ~CProgressCloser() { _p->ProcessWasFinished(); } -}; - -class CProgressThreadVirt -{ -protected: - FStringVector ErrorPaths; - CProgressFinalMessage FinalMessage; - - // error if any of HRESULT, ErrorMessage, ErrorPath - virtual HRESULT ProcessVirt() = 0; - void Process(); -public: - HRESULT Result; - bool ThreadFinishedOK; // if there is no fatal exception - CProgressDialog ProgressDialog; - - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - CProgressThreadVirt *p = (CProgressThreadVirt *)param; - try - { - p->Process(); - p->ThreadFinishedOK = true; - } - catch (...) { p->Result = E_FAIL; } - return 0; - } - - void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } - - HRESULT Create(const UString &title, HWND parentWindow = 0); - CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} - - CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } - -}; - -UString HResultToMessage(HRESULT errorCode); - -#endif +// ProgressDialog2.h + +#ifndef ZIP7_INC_PROGRESS_DIALOG_2_H +#define ZIP7_INC_PROGRESS_DIALOG_2_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Thread.h" + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ListView.h" +#include "../../../Windows/Control/ProgressBar.h" + +#include "MyWindowsNew.h" + +struct CProgressMessageBoxPair +{ + UString Title; + UString Message; +}; + +struct CProgressFinalMessage +{ + CProgressMessageBoxPair ErrorMessage; + CProgressMessageBoxPair OkMessage; + + bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); } +}; + +class CProgressSync +{ + bool _stopped; + bool _paused; +public: + bool _filesProgressMode; + bool _isDir; + UInt64 _totalBytes; + UInt64 _completedBytes; + UInt64 _totalFiles; + UInt64 _curFiles; + UInt64 _inSize; + UInt64 _outSize; + + UString _titleFileName; + UString _status; + UString _filePath; + + UStringVector Messages; + CProgressFinalMessage FinalMessage; + + NWindows::NSynchronization::CCriticalSection _cs; + + CProgressSync(); + + bool Get_Stopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _stopped; + } + void Set_Stopped(bool val) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _stopped = val; + } + + bool Get_Paused(); + void Set_Paused(bool val) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _paused = val; + } + + void Set_FilesProgressMode(bool filesProgressMode) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _filesProgressMode = filesProgressMode; + } + + HRESULT CheckStop(); + void Clear_Stop_Status(); + HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false); + + HRESULT Set_NumFilesTotal(UInt64 val); + void Set_NumBytesTotal(UInt64 val); + void Set_NumFilesCur(UInt64 val); + HRESULT Set_NumBytesCur(const UInt64 *val); + HRESULT Set_NumBytesCur(UInt64 val); + void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize); + + void Set_TitleFileName(const UString &fileName); + void Set_Status(const UString &s); + HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false); + void Set_FilePath(const wchar_t *path, bool isDir = false); + + void AddError_Message(const wchar_t *message); + void AddError_Message_Name(const wchar_t *message, const wchar_t *name); + // void AddError_Code_Name(DWORD systemError, const wchar_t *name); + void AddError_Code_Name(HRESULT systemError, const wchar_t *name); + + bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } +}; + + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ + bool _isDir; + bool _wasCreated; + bool _needClose; + bool _errorsWereDisplayed; + bool _waitCloseByCancelButton; + bool _cancelWasPressed; + bool _inCancelMessageBox; + bool _externalCloseMessageWasReceived; + bool _background; +public: + bool WaitMode; + bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. + bool CompressingMode; + bool ShowCompressionInfo; + +private: + unsigned _numPostedMessages; + unsigned _numAutoSizeMessages; + unsigned _numMessages; + + UString _titleFileName; + UString _filePath; + UString _status; + + UString _background_String; + UString _backgrounded_String; + UString _foreground_String; + UString _pause_String; + UString _continue_String; + UString _paused_String; + + int _buttonSizeX; + int _buttonSizeY; + + UINT_PTR _timer; + + UString _title; + + class CU64ToI32Converter + { + unsigned _numShiftBits; + UInt64 _range; + public: + CU64ToI32Converter(): _numShiftBits(0), _range(1) {} + void Init(UInt64 range) + { + _range = range; + // Windows CE doesn't like big number for ProgressBar. + for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++) + range >>= 1; + } + int Count(UInt64 val) + { + int res = (int)(val >> _numShiftBits); + if (val == _range) + res++; + return res; + } + }; + + CU64ToI32Converter _progressConv; + UInt64 _progressBar_Pos; + UInt64 _progressBar_Range; + + NWindows::NControl::CProgressBar m_ProgressBar; + NWindows::NControl::CListView _messageList; + + UStringVector _messageStrings; + + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + CMyComPtr _taskbarList; + // #endif + HWND _hwndForTaskbar; + + UInt32 _prevTime; + UInt64 _elapsedTime; + + UInt64 _prevPercentValue; + UInt64 _prevElapsedSec; + UInt64 _prevRemainingSec; + + UInt64 _totalBytes_Prev; + UInt64 _processed_Prev; + UInt64 _packed_Prev; + UInt64 _ratio_Prev; + + UString _filesStr_Prev; + UString _filesTotStr_Prev; + + unsigned _numReduceSymbols; + unsigned _prevSpeed_MoveBits; + UInt64 _prevSpeed; + + // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + void SetTaskbarProgressState(TBPFLAG tbpFlags) + { + if (_taskbarList && _hwndForTaskbar) + _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); + } + // #endif + void SetTaskbarProgressState(); + + void UpdateStatInfo(bool showAll); + void SetProgressRange(UInt64 range); + void SetProgressPos(UInt64 pos); + virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual void OnCancel() Z7_override; + virtual void OnOK() Z7_override; + virtual bool OnNotify(UINT /* controlID */, LPNMHDR header) Z7_override; + void CopyToClipboard(); + + NWindows::NSynchronization::CManualResetEvent _createDialogEvent; + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef Z7_SFX + void AddToTitle(LPCWSTR string); + #endif + + void SetPauseText(); + void SetPriorityText(); + void OnPauseButton(); + void OnPriorityButton(); + bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + + void SetTitleText(); + void ShowSize(unsigned id, UInt64 val, UInt64 &prev); + + void UpdateMessagesDialog(); + + void AddMessageDirect(LPCWSTR message, bool needNumber); + void AddMessage(LPCWSTR message); + + bool OnExternalCloseMessage(); + void EnableErrorsControls(bool enable); + + void ShowAfterMessages(HWND wndParent); + + void CheckNeedClose(); + +public: + CProgressSync Sync; + int IconID; + HWND MainWindow; + #ifndef Z7_SFX + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog() Z7_DESTRUCTOR_override; + #endif + + CProgressDialog(); + void WaitCreating() + { + _createDialogEvent.Set(); + _dialogCreatedEvent.Lock(); + } + + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL); + + + /* how it works: + 1) the working thread calls ProcessWasFinished() + that sends kCloseMessage message to CProgressDialog (GUI) thread + 2) CProgressDialog (GUI) thread receives kCloseMessage message and + calls ProcessWasFinished_GuiVirt(); + So we can implement ProcessWasFinished_GuiVirt() and show special + results window in GUI thread with CProgressDialog as parent window + */ + + void ProcessWasFinished(); + virtual void ProcessWasFinished_GuiVirt() {} +}; + + +class CProgressCloser +{ + CProgressDialog *_p; +public: + CProgressCloser(CProgressDialog &p) : _p(&p) {} + ~CProgressCloser() { _p->ProcessWasFinished(); } +}; + + +class CProgressThreadVirt: public CProgressDialog +{ +protected: + FStringVector ErrorPaths; + CProgressFinalMessage FinalMessage; + + // error if any of HRESULT, ErrorMessage, ErrorPath + virtual HRESULT ProcessVirt() = 0; +public: + HRESULT Result; + bool ThreadFinishedOK; // if there is no fatal exception + + void Process(); + void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } + + HRESULT Create(const UString &title, HWND parentWindow = NULL); + CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} + + CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } +}; + +UString HResultToMessage(HRESULT errorCode); + +/* +how it works: + +client code inherits CProgressThreadVirt and calls +CProgressThreadVirt::Create() +{ + it creates new thread that calls CProgressThreadVirt::Process(); + it creates modal progress dialog window with ProgressDialog.Create() +} + +CProgressThreadVirt::Process() +{ + { + Result = ProcessVirt(); // virtual function that must implement real work + } + if (exceptions) or FinalMessage.ErrorMessage.Message + { + set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message + } + else if (FinalMessage.OkMessage.Message) + { + set message to ProgressDialog.Sync.FinalMessage.OkMessage + } + + PostMsg(kCloseMessage); +} + + +CProgressDialog::OnExternalCloseMessage() +{ + if (ProgressDialog.Sync.FinalMessage) + { + WorkWasFinishedVirt(); + Show (ProgressDialog.Sync.FinalMessage) + MessagesDisplayed = true; + } +} + +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2.rc 2011-05-07 07:37:03.000000000 +0000 @@ -0,0 +1,40 @@ +#include "ProgressDialog2Res.h" +#include "../../GuiCommon.rc" + +#undef DIALOG_ID +#define DIALOG_ID IDD_PROGRESS +#define xc 360 +#define k 11 +#define z1s 16 + +#include "ProgressDialog2a.rc" + +#ifdef UNDER_CE + +#include "../../GuiCommon.rc" + + +#undef DIALOG_ID +#undef m +#undef k +#undef z1s + +#define DIALOG_ID IDD_PROGRESS_2 +#define m 4 +#define k 8 +#define z1s 12 + +#define xc 280 + +#include "ProgressDialog2a.rc" + +#endif + +STRINGTABLE DISCARDABLE +{ + IDS_PROGRESS_PAUSED "Paused" + IDS_PROGRESS_FOREGROUND "&Foreground" + IDS_CONTINUE "&Continue" + IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" + IDS_CLOSE "&Close" +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2Res.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2Res.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2Res.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2Res.h 2021-05-21 09:27:29.000000000 +0000 @@ -1,48 +1,49 @@ -#define IDD_PROGRESS 97 -#define IDD_PROGRESS_2 10097 - -#define IDS_CLOSE 408 -#define IDS_CONTINUE 411 - -#define IDB_PROGRESS_BACKGROUND 444 -#define IDS_PROGRESS_FOREGROUND 445 -#define IDB_PAUSE 446 -#define IDS_PROGRESS_PAUSED 447 -#define IDS_PROGRESS_ASK_CANCEL 448 - -#define IDT_PROGRESS_PACKED 1008 -#define IDT_PROGRESS_FILES 1032 - -#define IDT_PROGRESS_ELAPSED 3900 -#define IDT_PROGRESS_REMAINING 3901 -#define IDT_PROGRESS_TOTAL 3902 -#define IDT_PROGRESS_SPEED 3903 -#define IDT_PROGRESS_PROCESSED 3904 -#define IDT_PROGRESS_RATIO 3905 -#define IDT_PROGRESS_ERRORS 3906 - -#define IDC_PROGRESS1 100 -#define IDL_PROGRESS_MESSAGES 101 -#define IDT_PROGRESS_FILE_NAME 102 -#define IDT_PROGRESS_STATUS 103 - -#define IDT_PROGRESS_PACKED_VAL 110 -#define IDT_PROGRESS_FILES_VAL 111 - -#define IDT_PROGRESS_ELAPSED_VAL 120 -#define IDT_PROGRESS_REMAINING_VAL 121 -#define IDT_PROGRESS_TOTAL_VAL 122 -#define IDT_PROGRESS_SPEED_VAL 123 -#define IDT_PROGRESS_PROCESSED_VAL 124 -#define IDT_PROGRESS_RATIO_VAL 125 -#define IDT_PROGRESS_ERRORS_VAL 126 - - -#ifdef UNDER_CE -#define MY_PROGRESS_VAL_UNITS 44 -#else -#define MY_PROGRESS_VAL_UNITS 76 -#endif -#define MY_PROGRESS_LABEL_UNITS_MIN 60 -#define MY_PROGRESS_LABEL_UNITS_START 90 -#define MY_PROGRESS_PAD_UNITS 4 +#define IDD_PROGRESS 97 +#define IDD_PROGRESS_2 10097 + +#define IDS_CLOSE 408 +#define IDS_CONTINUE 411 + +#define IDB_PROGRESS_BACKGROUND 444 +#define IDS_PROGRESS_FOREGROUND 445 +#define IDB_PAUSE 446 +#define IDS_PROGRESS_PAUSED 447 +#define IDS_PROGRESS_ASK_CANCEL 448 + +#define IDT_PROGRESS_PACKED 1008 +#define IDT_PROGRESS_FILES 1032 + +#define IDT_PROGRESS_ELAPSED 3900 +#define IDT_PROGRESS_REMAINING 3901 +#define IDT_PROGRESS_TOTAL 3902 +#define IDT_PROGRESS_SPEED 3903 +#define IDT_PROGRESS_PROCESSED 3904 +#define IDT_PROGRESS_RATIO 3905 +#define IDT_PROGRESS_ERRORS 3906 + +#define IDC_PROGRESS1 100 +#define IDL_PROGRESS_MESSAGES 101 +#define IDT_PROGRESS_FILE_NAME 102 +#define IDT_PROGRESS_STATUS 103 + +#define IDT_PROGRESS_PACKED_VAL 110 +#define IDT_PROGRESS_FILES_VAL 111 +#define IDT_PROGRESS_FILES_TOTAL 112 + +#define IDT_PROGRESS_ELAPSED_VAL 120 +#define IDT_PROGRESS_REMAINING_VAL 121 +#define IDT_PROGRESS_TOTAL_VAL 122 +#define IDT_PROGRESS_SPEED_VAL 123 +#define IDT_PROGRESS_PROCESSED_VAL 124 +#define IDT_PROGRESS_RATIO_VAL 125 +#define IDT_PROGRESS_ERRORS_VAL 126 + + +#ifdef UNDER_CE +#define MY_PROGRESS_VAL_UNITS 44 +#else +#define MY_PROGRESS_VAL_UNITS 72 +#endif +#define MY_PROGRESS_LABEL_UNITS_MIN 60 +#define MY_PROGRESS_LABEL_UNITS_START 90 +#define MY_PROGRESS_PAD_UNITS 4 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp 2015-01-14 19:54:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -// ProgressDialog2_rc.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "ProgressDialog2Res.h" - -#include "Windows/Control/DialogImpl.h" - -/* -IDD_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX -CAPTION "Progress" -MY_FONT -BEGIN - PUSHBUTTON "&Background", IDB_PROGRESS_BACKGROUND, bXPos3, bYPos, bXSize, bYSize - PUSHBUTTON "&Pause", IDB_PAUSE, bXPos2, bYPos, bXSize, bYSize - PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize - LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, marg, y0, x0Size, 8 - LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, marg, y1, x0Size, 8 - LTEXT "Files:", IDT_PROGRESS_FILES, marg, y2, x0Size, 8 - LTEXT "Compression ratio:",IDT_PROGRESS_RATIO, marg, y3, x0Size, 8 - - LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2Size, 8 - LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2Size, 8 - LTEXT "Processed:", IDT_PROGRESS_PROCESSED, x2, y2, x2Size, 8 - LTEXT "Compressed size:", IDT_PROGRESS_PACKED, x2, y3, x2Size, 8 - - RTEXT "00:00:00", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1Size, 8 - RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1Size, 8 - RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1Size, 8 - RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1Size, 8 - - RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3Size, 8 - RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3Size, 8 - RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3Size, 8 - RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3Size, 8 - - LTEXT "", IDT_PROGRESS_FILE_NAME, marg, bYPos - 30, xSize2, 8, SS_NOPREFIX - CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13 -END - - -STRINGTABLE DISCARDABLE -BEGIN - IDS_PROGRESS_PAUSED "Paused" - IDS_PROGRESS_FOREGROUND "&Foreground" - IDS_PROGRESS_CONTINUE "&Continue" - IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" -END - -*/ -class CProgressDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CProgressDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : CModalDialogImpl(dialog,parent, id, wxT("Progress")) - { -// FIXME : ProgressDialog2 but ProgressDialog ... - - ///Sizer for adding the controls created by users - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - wxStaticText *pStaticTextElapsedTime = new wxStaticText(this, IDT_PROGRESS_ELAPSED, wxT("Elapsed time:")); - wxStaticText *m_pStaticTextElapsedTime = new wxStaticText(this, IDT_PROGRESS_ELAPSED_VAL, wxT("00:00:00"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - wxStaticText *pStaticTextRemainingTime = new wxStaticText(this, IDT_PROGRESS_REMAINING, wxT("Remaining time")); - wxStaticText *m_pStaticTextRemainingTime = new wxStaticText(this, IDT_PROGRESS_REMAINING_VAL, wxT("00:00:00"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - wxStaticText *pStaticTextFiles = new wxStaticText(this, IDT_PROGRESS_FILES, wxT("Files:")); - wxStaticText *m_pStaticTextFiles = new wxStaticText(this, IDT_PROGRESS_FILES_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - wxStaticText *pStaticTextRatio = new wxStaticText(this, IDT_PROGRESS_RATIO, wxT("Compression ratio:")); - wxStaticText *m_pStaticTextRatio = new wxStaticText(this, IDT_PROGRESS_RATIO_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - - wxStaticText *pStaticTextSize = new wxStaticText(this, IDT_PROGRESS_TOTAL, wxT("Total Size:")); - wxStaticText *m_pStaticTextSize = new wxStaticText(this, IDT_PROGRESS_TOTAL_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - wxStaticText *pStaticTextSpeed = new wxStaticText(this, IDT_PROGRESS_SPEED, wxT("Speed:")); - wxStaticText *m_pStaticTextSpeed = new wxStaticText(this, IDT_PROGRESS_SPEED_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - wxStaticText *pStaticTextUnpacked = new wxStaticText(this, IDT_PROGRESS_PROCESSED, wxT("Processed:")); - wxStaticText *m_pStaticTextUnpacked = new wxStaticText(this, IDT_PROGRESS_PROCESSED_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - wxStaticText *pStaticTextPacked = new wxStaticText(this, IDT_PROGRESS_PACKED, wxT("Compressed size:")); - wxStaticText *m_pStaticTextPacked = new wxStaticText(this, IDT_PROGRESS_PACKED_VAL, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - - wxBoxSizer *pInfoSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pTimeSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pTimeLabelSizer = new wxBoxSizer(wxVERTICAL); - pTimeLabelSizer->Add(pStaticTextElapsedTime , 0, wxALL|wxEXPAND, 5); - pTimeLabelSizer->Add(pStaticTextRemainingTime, 0, wxALL|wxEXPAND, 5); - pTimeLabelSizer->Add(pStaticTextFiles , 0, wxALL|wxEXPAND, 5); - pTimeLabelSizer->Add(pStaticTextRatio , 0, wxALL|wxEXPAND, 5); - wxBoxSizer *pTimeInfoSizer = new wxBoxSizer(wxVERTICAL); - pTimeInfoSizer->Add(m_pStaticTextElapsedTime , 0, wxALL|wxEXPAND, 5); - pTimeInfoSizer->Add(m_pStaticTextRemainingTime, 0, wxALL|wxEXPAND, 5); - pTimeInfoSizer->Add(m_pStaticTextFiles , 0, wxALL|wxEXPAND, 5); - pTimeInfoSizer->Add(m_pStaticTextRatio , 0, wxALL|wxEXPAND, 5); - pTimeSizer->Add(pTimeLabelSizer , 0, wxALL|wxEXPAND, 5); - pTimeSizer->Add(pTimeInfoSizer , 0, wxALL|wxEXPAND, 5); - wxBoxSizer *pSizeSpeedSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pSizeSpeedLabelSizer = new wxBoxSizer(wxVERTICAL); - pSizeSpeedLabelSizer->Add(pStaticTextSize , 0, wxALL|wxEXPAND, 5); - pSizeSpeedLabelSizer->Add(pStaticTextSpeed , 0, wxALL|wxEXPAND, 5); - pSizeSpeedLabelSizer->Add(pStaticTextUnpacked , 0, wxALL|wxEXPAND, 5); - pSizeSpeedLabelSizer->Add(pStaticTextPacked , 0, wxALL|wxEXPAND, 5); - - wxBoxSizer *pSizeSpeedInfoSizer = new wxBoxSizer(wxVERTICAL); - pSizeSpeedInfoSizer->Add(m_pStaticTextSize , 0, wxALL|wxEXPAND, 5); - pSizeSpeedInfoSizer->Add(m_pStaticTextSpeed , 0, wxALL|wxEXPAND, 5); - pSizeSpeedInfoSizer->Add(m_pStaticTextUnpacked, 0, wxALL|wxEXPAND, 5); - pSizeSpeedInfoSizer->Add(m_pStaticTextPacked , 0, wxALL|wxEXPAND, 5); - - pSizeSpeedSizer->Add(pSizeSpeedLabelSizer, 1, wxALL|wxEXPAND, 5); - pSizeSpeedSizer->Add(pSizeSpeedInfoSizer, 1, wxALL|wxEXPAND, 5); - pInfoSizer->Add(pTimeSizer, 0, wxALL|wxEXPAND, 5); - pInfoSizer->Add(pSizeSpeedSizer, 0, wxALL|wxEXPAND, 5); - - // wxStaticText *m_pStaticArchiveName = new wxStaticText(this, IDT_PROGRESS_FILE_NAME, wxT(" \n ")); - wxStaticText *m_pStaticArchiveName = new wxStaticText(this, IDT_PROGRESS_FILE_NAME, wxT("")); - // m_pStaticArchiveName->Wrap( -1 ); // No Wrapping - - wxGauge *m_pGaugeProgress = new wxGauge(this, IDC_PROGRESS1, 100); - - wxBoxSizer *pButtonSizer = new wxBoxSizer(wxHORIZONTAL); - wxButton *m_pButtonBackground = new wxButton(this, IDB_PROGRESS_BACKGROUND, wxT("&Background")); - wxButton *m_pButtonPause = new wxButton(this, IDB_PAUSE, wxT("&Pause")); - wxButton *m_pButtonCancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel")); - // FIXME pButtonSizer->AddStretchSpacer(1); - pButtonSizer->Add(m_pButtonBackground, 0, wxALL|wxEXPAND, 5); - pButtonSizer->Add(m_pButtonPause, 0, wxALL|wxEXPAND, 5); - pButtonSizer->Add(m_pButtonCancel, 0, wxALL|wxEXPAND, 5); - - topsizer->Add(pInfoSizer, 0, wxBOTTOM|wxEXPAND, 5); - topsizer->Add(m_pStaticArchiveName, 0, wxEXPAND | wxALL | wxALIGN_LEFT, 10); - topsizer->Add(m_pGaugeProgress, 0, wxALL|wxEXPAND, 10); - topsizer->Add(pButtonSizer, 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } - -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -static CStringTable g_stringTable[] = -{ - { IDS_PROGRESS_PAUSED , L"Paused" }, - { IDS_PROGRESS_FOREGROUND , L"&Foreground" }, - { IDS_CONTINUE , L"&Continue" }, - { IDS_PROGRESS_ASK_CANCEL , L"Are you sure you want to cancel?" }, - { IDS_CLOSE , L"&Close" }, - { 0 , 0 } -}; - -REGISTER_DIALOG(IDD_PROGRESS,CProgressDialog,g_stringTable) - -BEGIN_EVENT_TABLE(CProgressDialogImpl, wxDialog) - EVT_TIMER(wxID_ANY, CModalDialogImpl::OnAnyTimer) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2a.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2a.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialog2a.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialog2a.rc 2021-12-21 13:00:00.000000000 +0000 @@ -0,0 +1,85 @@ +#undef bxs +#define bxs 80 + +#define x0s MY_PROGRESS_LABEL_UNITS_START +#define x1s MY_PROGRESS_VAL_UNITS +#define x2s MY_PROGRESS_LABEL_UNITS_START +#define x3s MY_PROGRESS_VAL_UNITS + +#define x1 (m + x0s) +#define x3 (xs - m - x3s) +#define x2 (x3 - x2s) + +#undef y0 +#undef y1 +#undef y2 +#undef y3 +#undef y4 + +#undef z0 +#undef z1 +#undef z2 +#undef z3 + +#define y0 m +#define y1 (y0 + k) +#define y2 (y1 + k) +#define y3 (y2 + k) +#define y4 (y3 + k) + +#define z3 (y4 + k + 1) + +#define z2 (z3 + k + 1) +#define z2s 24 + +#define z1 (z2 + z2s) + +#define z0 (z1 + z1s + m) +#define z0s 48 + +#define yc (z0 + z0s + bys) + + +DIALOG_ID DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Progress" +{ + DEFPUSHBUTTON "&Background", IDB_PROGRESS_BACKGROUND, bx3, by, bxs, bys + PUSHBUTTON "&Pause", IDB_PAUSE, bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + + + LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8 + LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8 + LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8 + + LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8 + + + LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8 + LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8 + LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8 + LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8 + LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, x2, y4, x2s, 8 + + + RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_FILES_TOTAL, x1, y3, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX + + RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_RATIO_VAL, x3, y4, x3s, MY_TEXT_NOPREFIX + + LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX + CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s + + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, z1, xc, z1s + + CONTROL "List1", IDL_PROGRESS_MESSAGES, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + m, z0, xc, z0s +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ProgressDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ProgressDialogRes.h 2011-04-25 12:02:45.000000000 +0000 @@ -1,3 +1,3 @@ -#define IDD_PROGRESS 97 - -#define IDC_PROGRESS1 100 +#define IDD_PROGRESS 97 + +#define IDC_PROGRESS1 100 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.cpp 2013-01-17 10:35:19.000000000 +0000 @@ -1,23 +1,23 @@ -// PropertyName.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "LangUtils.h" -#include "PropertyName.h" - -UString GetNameOfProperty(PROPID propID, const wchar_t *name) -{ - if (propID < 1000) - { - UString s = LangString(1000 + propID); - if (!s.IsEmpty()) - return s; - } - if (name) - return name; - wchar_t temp[16]; - ConvertUInt32ToString(propID, temp); - return temp; -} +// PropertyName.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "LangUtils.h" +#include "PropertyName.h" + +UString GetNameOfProperty(PROPID propID, const wchar_t *name) +{ + if (propID < 1000) + { + UString s = LangString(1000 + propID); + if (!s.IsEmpty()) + return s; + } + if (name) + return name; + wchar_t temp[16]; + ConvertUInt32ToString(propID, temp); + return temp; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,10 +1,10 @@ -// PropertyName.h - -#ifndef __PROPERTY_NAME_H -#define __PROPERTY_NAME_H - -#include "../../../Common/MyString.h" - -UString GetNameOfProperty(PROPID propID, const wchar_t *name); - -#endif +// PropertyName.h + +#ifndef ZIP7_INC_PROPERTY_NAME_H +#define ZIP7_INC_PROPERTY_NAME_H + +#include "../../../Common/MyString.h" + +UString GetNameOfProperty(PROPID propID, const wchar_t *name); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyName.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyName.rc 2022-11-05 14:00:00.000000000 +0000 @@ -0,0 +1,109 @@ +#include "PropertyNameRes.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_PROP_PATH "Path" + IDS_PROP_NAME "Name" + IDS_PROP_EXTENSION "Extension" + IDS_PROP_IS_FOLDER "Folder" + IDS_PROP_SIZE "Size" + IDS_PROP_PACKED_SIZE "Packed Size" + IDS_PROP_ATTRIBUTES "Attributes" + IDS_PROP_CTIME "Created" + IDS_PROP_ATIME "Accessed" + IDS_PROP_MTIME "Modified" + IDS_PROP_SOLID "Solid" + IDS_PROP_C0MMENTED "Commented" + IDS_PROP_ENCRYPTED "Encrypted" + IDS_PROP_SPLIT_BEFORE "Split Before" + IDS_PROP_SPLIT_AFTER "Split After" + IDS_PROP_DICTIONARY_SIZE "Dictionary" + IDS_PROP_CRC "CRC" + IDS_PROP_FILE_TYPE "Type" + IDS_PROP_ANTI "Anti" + IDS_PROP_METHOD "Method" + IDS_PROP_HOST_OS "Host OS" + IDS_PROP_FILE_SYSTEM "File System" + IDS_PROP_USER "User" + IDS_PROP_GROUP "Group" + IDS_PROP_BLOCK "Block" + IDS_PROP_COMMENT "Comment" + IDS_PROP_POSITION "Position" + IDS_PROP_PREFIX "Path Prefix" + IDS_PROP_FOLDERS "Folders" + IDS_PROP_FILES "Files" + IDS_PROP_VERSION "Version" + IDS_PROP_VOLUME "Volume" + IDS_PROP_IS_VOLUME "Multivolume" + IDS_PROP_OFFSET "Offset" + IDS_PROP_LINKS "Links" + IDS_PROP_NUM_BLOCKS "Blocks" + IDS_PROP_NUM_VOLUMES "Volumes" + + IDS_PROP_BIT64 "64-bit" + IDS_PROP_BIG_ENDIAN "Big-endian" + IDS_PROP_CPU "CPU" + IDS_PROP_PHY_SIZE "Physical Size" + IDS_PROP_HEADERS_SIZE "Headers Size" + IDS_PROP_CHECKSUM "Checksum" + IDS_PROP_CHARACTS "Characteristics" + IDS_PROP_VA "Virtual Address" + IDS_PROP_ID "ID" + IDS_PROP_SHORT_NAME "Short Name" + IDS_PROP_CREATOR_APP "Creator Application" + IDS_PROP_SECTOR_SIZE "Sector Size" + IDS_PROP_POSIX_ATTRIB "Mode" + IDS_PROP_SYM_LINK "Symbolic Link" + IDS_PROP_ERROR "Error" + IDS_PROP_TOTAL_SIZE "Total Size" + IDS_PROP_FREE_SPACE "Free Space" + IDS_PROP_CLUSTER_SIZE "Cluster Size" + IDS_PROP_VOLUME_NAME "Label" + IDS_PROP_LOCAL_NAME "Local Name" + IDS_PROP_PROVIDER "Provider" + IDS_PROP_NT_SECURITY "NT Security" + IDS_PROP_ALT_STREAM "Alternate Stream" + IDS_PROP_AUX "Aux" + IDS_PROP_DELETED "Deleted" + IDS_PROP_IS_TREE "Is Tree" + IDS_PROP_SHA1 "SHA-1" + IDS_PROP_SHA256 "SHA-256" + IDS_PROP_ERROR_TYPE "Error Type" + IDS_PROP_NUM_ERRORS "Errors" + IDS_PROP_ERROR_FLAGS "Errors" + IDS_PROP_WARNING_FLAGS "Warnings" + IDS_PROP_WARNING "Warning" + IDS_PROP_NUM_STREAMS "Streams" + IDS_PROP_NUM_ALT_STREAMS "Alternate Streams" + IDS_PROP_ALT_STREAMS_SIZE "Alternate Streams Size" + IDS_PROP_VIRTUAL_SIZE "Virtual Size" + IDS_PROP_UNPACK_SIZE "Unpack Size" + IDS_PROP_TOTAL_PHY_SIZE "Total Physical Size" + IDS_PROP_VOLUME_INDEX "Volume Index" + IDS_PROP_SUBTYPE "SubType" + IDS_PROP_SHORT_COMMENT "Short Comment" + IDS_PROP_CODE_PAGE "Code Page" + IDS_PROP_IS_NOT_ARC_TYPE "Is not archive type" + IDS_PROP_PHY_SIZE_CANT_BE_DETECTED "Physical Size can't be detected" + IDS_PROP_ZEROS_TAIL_IS_ALLOWED "Zeros Tail Is Allowed" + IDS_PROP_TAIL_SIZE "Tail Size" + IDS_PROP_EMB_STUB_SIZE "Embedded Stub Size" + IDS_PROP_NT_REPARSE "Link" + IDS_PROP_HARD_LINK "Hard Link" + IDS_PROP_INODE "iNode" + IDS_PROP_STREAM_ID "Stream ID" + 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" + IDS_PROP_DEV_MAJOR "Dev Major" + IDS_PROP_DEV_MINOR "Dev Minor" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyNameRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyNameRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/PropertyNameRes.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/PropertyNameRes.h 2022-11-05 14:00:00.000000000 +0000 @@ -1,94 +1,104 @@ - - -#define IDS_PROP_PATH 1003 -#define IDS_PROP_NAME 1004 -#define IDS_PROP_EXTENSION 1005 -#define IDS_PROP_IS_FOLDER 1006 -#define IDS_PROP_SIZE 1007 -#define IDS_PROP_PACKED_SIZE 1008 -#define IDS_PROP_ATTRIBUTES 1009 -#define IDS_PROP_CTIME 1010 -#define IDS_PROP_ATIME 1011 -#define IDS_PROP_MTIME 1012 -#define IDS_PROP_SOLID 1013 -#define IDS_PROP_C0MMENTED 1014 -#define IDS_PROP_ENCRYPTED 1015 -#define IDS_PROP_SPLIT_BEFORE 1016 -#define IDS_PROP_SPLIT_AFTER 1017 -#define IDS_PROP_DICTIONARY_SIZE 1018 -#define IDS_PROP_CRC 1019 -#define IDS_PROP_FILE_TYPE 1020 -#define IDS_PROP_ANTI 1021 -#define IDS_PROP_METHOD 1022 -#define IDS_PROP_HOST_OS 1023 -#define IDS_PROP_FILE_SYSTEM 1024 -#define IDS_PROP_USER 1025 -#define IDS_PROP_GROUP 1026 -#define IDS_PROP_BLOCK 1027 -#define IDS_PROP_COMMENT 1028 -#define IDS_PROP_POSITION 1029 -#define IDS_PROP_PREFIX 1030 -#define IDS_PROP_FOLDERS 1031 -#define IDS_PROP_FILES 1032 -#define IDS_PROP_VERSION 1033 -#define IDS_PROP_VOLUME 1034 -#define IDS_PROP_IS_VOLUME 1035 -#define IDS_PROP_OFFSET 1036 -#define IDS_PROP_LINKS 1037 -#define IDS_PROP_NUM_BLOCKS 1038 -#define IDS_PROP_NUM_VOLUMES 1039 - -#define IDS_PROP_BIT64 1041 -#define IDS_PROP_BIG_ENDIAN 1042 -#define IDS_PROP_CPU 1043 -#define IDS_PROP_PHY_SIZE 1044 -#define IDS_PROP_HEADERS_SIZE 1045 -#define IDS_PROP_CHECKSUM 1046 -#define IDS_PROP_CHARACTS 1047 -#define IDS_PROP_VA 1048 -#define IDS_PROP_ID 1049 -#define IDS_PROP_SHORT_NAME 1050 -#define IDS_PROP_CREATOR_APP 1051 -#define IDS_PROP_SECTOR_SIZE 1052 -#define IDS_PROP_POSIX_ATTRIB 1053 -#define IDS_PROP_SYM_LINK 1054 -#define IDS_PROP_ERROR 1055 -#define IDS_PROP_TOTAL_SIZE 1056 -#define IDS_PROP_FREE_SPACE 1057 -#define IDS_PROP_CLUSTER_SIZE 1058 -#define IDS_PROP_VOLUME_NAME 1059 -#define IDS_PROP_LOCAL_NAME 1060 -#define IDS_PROP_PROVIDER 1061 -#define IDS_PROP_NT_SECURITY 1062 -#define IDS_PROP_ALT_STREAM 1063 -#define IDS_PROP_AUX 1064 -#define IDS_PROP_DELETED 1065 -#define IDS_PROP_IS_TREE 1066 -#define IDS_PROP_SHA1 1067 -#define IDS_PROP_SHA256 1068 -#define IDS_PROP_ERROR_TYPE 1069 -#define IDS_PROP_NUM_ERRORS 1070 -#define IDS_PROP_ERROR_FLAGS 1071 -#define IDS_PROP_WARNING_FLAGS 1072 -#define IDS_PROP_WARNING 1073 -#define IDS_PROP_NUM_STREAMS 1074 -#define IDS_PROP_NUM_ALT_STREAMS 1075 -#define IDS_PROP_ALT_STREAMS_SIZE 1076 -#define IDS_PROP_VIRTUAL_SIZE 1077 -#define IDS_PROP_UNPACK_SIZE 1078 -#define IDS_PROP_TOTAL_PHY_SIZE 1079 -#define IDS_PROP_VOLUME_INDEX 1080 -#define IDS_PROP_SUBTYPE 1081 -#define IDS_PROP_SHORT_COMMENT 1082 -#define IDS_PROP_CODE_PAGE 1083 -#define IDS_PROP_IS_NOT_ARC_TYPE 1084 -#define IDS_PROP_PHY_SIZE_CANT_BE_DETECTED 1085 -#define IDS_PROP_ZEROS_TAIL_IS_ALLOWED 1086 -#define IDS_PROP_TAIL_SIZE 1087 -#define IDS_PROP_EMB_STUB_SIZE 1088 -#define IDS_PROP_NT_REPARSE 1089 -#define IDS_PROP_HARD_LINK 1090 -#define IDS_PROP_INODE 1091 -#define IDS_PROP_STREAM_ID 1092 -#define IDS_PROP_READ_ONLY 1093 -#define IDS_PROP_OUT_NAME 1094 + + +#define IDS_PROP_PATH 1003 +#define IDS_PROP_NAME 1004 +#define IDS_PROP_EXTENSION 1005 +#define IDS_PROP_IS_FOLDER 1006 +#define IDS_PROP_SIZE 1007 +#define IDS_PROP_PACKED_SIZE 1008 +#define IDS_PROP_ATTRIBUTES 1009 +#define IDS_PROP_CTIME 1010 +#define IDS_PROP_ATIME 1011 +#define IDS_PROP_MTIME 1012 +#define IDS_PROP_SOLID 1013 +#define IDS_PROP_C0MMENTED 1014 +#define IDS_PROP_ENCRYPTED 1015 +#define IDS_PROP_SPLIT_BEFORE 1016 +#define IDS_PROP_SPLIT_AFTER 1017 +#define IDS_PROP_DICTIONARY_SIZE 1018 +#define IDS_PROP_CRC 1019 +#define IDS_PROP_FILE_TYPE 1020 +#define IDS_PROP_ANTI 1021 +#define IDS_PROP_METHOD 1022 +#define IDS_PROP_HOST_OS 1023 +#define IDS_PROP_FILE_SYSTEM 1024 +#define IDS_PROP_USER 1025 +#define IDS_PROP_GROUP 1026 +#define IDS_PROP_BLOCK 1027 +#define IDS_PROP_COMMENT 1028 +#define IDS_PROP_POSITION 1029 +#define IDS_PROP_PREFIX 1030 +#define IDS_PROP_FOLDERS 1031 +#define IDS_PROP_FILES 1032 +#define IDS_PROP_VERSION 1033 +#define IDS_PROP_VOLUME 1034 +#define IDS_PROP_IS_VOLUME 1035 +#define IDS_PROP_OFFSET 1036 +#define IDS_PROP_LINKS 1037 +#define IDS_PROP_NUM_BLOCKS 1038 +#define IDS_PROP_NUM_VOLUMES 1039 + +#define IDS_PROP_BIT64 1041 +#define IDS_PROP_BIG_ENDIAN 1042 +#define IDS_PROP_CPU 1043 +#define IDS_PROP_PHY_SIZE 1044 +#define IDS_PROP_HEADERS_SIZE 1045 +#define IDS_PROP_CHECKSUM 1046 +#define IDS_PROP_CHARACTS 1047 +#define IDS_PROP_VA 1048 +#define IDS_PROP_ID 1049 +#define IDS_PROP_SHORT_NAME 1050 +#define IDS_PROP_CREATOR_APP 1051 +#define IDS_PROP_SECTOR_SIZE 1052 +#define IDS_PROP_POSIX_ATTRIB 1053 +#define IDS_PROP_SYM_LINK 1054 +#define IDS_PROP_ERROR 1055 +#define IDS_PROP_TOTAL_SIZE 1056 +#define IDS_PROP_FREE_SPACE 1057 +#define IDS_PROP_CLUSTER_SIZE 1058 +#define IDS_PROP_VOLUME_NAME 1059 +#define IDS_PROP_LOCAL_NAME 1060 +#define IDS_PROP_PROVIDER 1061 +#define IDS_PROP_NT_SECURITY 1062 +#define IDS_PROP_ALT_STREAM 1063 +#define IDS_PROP_AUX 1064 +#define IDS_PROP_DELETED 1065 +#define IDS_PROP_IS_TREE 1066 +#define IDS_PROP_SHA1 1067 +#define IDS_PROP_SHA256 1068 +#define IDS_PROP_ERROR_TYPE 1069 +#define IDS_PROP_NUM_ERRORS 1070 +#define IDS_PROP_ERROR_FLAGS 1071 +#define IDS_PROP_WARNING_FLAGS 1072 +#define IDS_PROP_WARNING 1073 +#define IDS_PROP_NUM_STREAMS 1074 +#define IDS_PROP_NUM_ALT_STREAMS 1075 +#define IDS_PROP_ALT_STREAMS_SIZE 1076 +#define IDS_PROP_VIRTUAL_SIZE 1077 +#define IDS_PROP_UNPACK_SIZE 1078 +#define IDS_PROP_TOTAL_PHY_SIZE 1079 +#define IDS_PROP_VOLUME_INDEX 1080 +#define IDS_PROP_SUBTYPE 1081 +#define IDS_PROP_SHORT_COMMENT 1082 +#define IDS_PROP_CODE_PAGE 1083 +#define IDS_PROP_IS_NOT_ARC_TYPE 1084 +#define IDS_PROP_PHY_SIZE_CANT_BE_DETECTED 1085 +#define IDS_PROP_ZEROS_TAIL_IS_ALLOWED 1086 +#define IDS_PROP_TAIL_SIZE 1087 +#define IDS_PROP_EMB_STUB_SIZE 1088 +#define IDS_PROP_NT_REPARSE 1089 +#define IDS_PROP_HARD_LINK 1090 +#define IDS_PROP_INODE 1091 +#define IDS_PROP_STREAM_ID 1092 +#define IDS_PROP_READ_ONLY 1093 +#define IDS_PROP_OUT_NAME 1094 +#define IDS_PROP_COPY_LINK 1095 +#define IDS_PROP_ARC_FILE_NAME 1096 +#define IDS_PROP_IS_HASH 1097 +#define IDS_PROP_CHANGE_TIME 1098 +#define IDS_PROP_USER_ID 1099 +#define IDS_PROP_GROUP_ID 1100 +#define IDS_PROP_DEVICE_MAJOR 1101 +#define IDS_PROP_DEVICE_MINOR 1102 +#define IDS_PROP_DEV_MAJOR 1103 +#define IDS_PROP_DEV_MINOR 1104 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryAssociations.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryAssociations.cpp 2010-04-25 15:14:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,312 +1,167 @@ -// RegistryAssociations.cpp - -#include "StdAfx.h" - -#include "RegistryAssociations.h" - -#include "Common/IntToString.h" -#include "Common/StringConvert.h" -#include "Common/StringToInt.h" - -#include "Windows/Registry.h" -#include "Windows/Synchronization.h" - -#include "StringUtils.h" - -using namespace NWindows; -using namespace NRegistry; - -namespace NRegistryAssociations { - -static NSynchronization::CCriticalSection g_CriticalSection; - -#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM") - -/* - -static const TCHAR *kCUKeyPath = REG_PATH_FM; -static const WCHAR *kExtPlugins = L"Plugins"; -static const TCHAR *kExtEnabled = TEXT("Enabled"); - -#define kAssociations TEXT("Associations") -#define kAssociationsPath REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) kAssociations - -bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo) -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey key; - if (key.Open(HKEY_CURRENT_USER, - CSysString(kAssociationsPath TEXT(STRING_PATH_SEPARATOR)) + - GetSystemString(ext), KEY_READ) != ERROR_SUCCESS) - return false; - UString pluginsString; - key.QueryValue(kExtPlugins, pluginsString); - SplitString(pluginsString, extInfo.Plugins); - return true; -} - -void ReadInternalAssociations(CObjectVector &items) -{ - items.Clear(); - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey associationsKey; - if (associationsKey.Open(HKEY_CURRENT_USER, kAssociationsPath, KEY_READ) != ERROR_SUCCESS) - return; - CSysStringVector extNames; - associationsKey.EnumKeys(extNames); - for(int i = 0; i < extNames.Size(); i++) - { - const CSysString extName = extNames[i]; - CExtInfo extInfo; - // extInfo.Enabled = false; - extInfo.Ext = GetUnicodeString(extName); - CKey key; - if (key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS) - return; - UString pluginsString; - key.QueryValue(kExtPlugins, pluginsString); - SplitString(pluginsString, extInfo.Plugins); - // if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS) - // extInfo.Enabled = false; - items.Add(extInfo); - } -} - -void WriteInternalAssociations(const CObjectVector &items) -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey mainKey; - mainKey.Create(HKEY_CURRENT_USER, kCUKeyPath); - mainKey.RecurseDeleteKey(kAssociations); - CKey associationsKey; - associationsKey.Create(mainKey, kAssociations); - for(int i = 0; i < items.Size(); i++) - { - const CExtInfo &extInfo = items[i]; - CKey key; - key.Create(associationsKey, GetSystemString(extInfo.Ext)); - key.SetValue(kExtPlugins, JoinStrings(extInfo.Plugins)); - // key.SetValue(kExtEnabled, extInfo.Enabled); - } -} -*/ - -/////////////////////////////////// -// External - -static const TCHAR *kShellNewKeyName = TEXT("ShellNew"); -static const TCHAR *kShellNewDataValueName = TEXT("Data"); - -static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon"); -static const TCHAR *kShellKeyName = TEXT("shell"); -static const TCHAR *kOpenKeyName = TEXT("open"); -static const TCHAR *kCommandKeyName = TEXT("command"); -static const TCHAR *k7zipPrefix = TEXT("7-Zip."); - -static CSysString GetExtensionKeyName(const CSysString &extension) -{ - return CSysString(TEXT(".")) + extension; -} - -static CSysString GetExtProgramKeyName(const CSysString &extension) -{ - return CSysString(k7zipPrefix) + extension; -} - -static bool CheckShellExtensionInfo2(const CSysString &extension, - CSysString programKeyName, UString &iconPath, int &iconIndex) -{ - iconIndex = -1; - iconPath.Empty(); - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey extKey; - if (extKey.Open(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension), KEY_READ) != ERROR_SUCCESS) - return false; - if (extKey.QueryValue(NULL, programKeyName) != ERROR_SUCCESS) - return false; - UString s = GetUnicodeString(k7zipPrefix); - if (s.CompareNoCase(GetUnicodeString(programKeyName.Left(s.Length()))) != 0) - return false; - CKey iconKey; - if (extKey.Open(HKEY_CLASSES_ROOT, programKeyName + CSysString(TEXT(CHAR_PATH_SEPARATOR)) + kDefaultIconKeyName, KEY_READ) != ERROR_SUCCESS) - return false; - UString value; - if (extKey.QueryValue(NULL, value) == ERROR_SUCCESS) - { - int pos = value.ReverseFind(L','); - iconPath = value; - if (pos >= 0) - { - const wchar_t *end; - UInt64 index = ConvertStringToUInt64((const wchar_t *)value + pos + 1, &end); - if (*end == 0) - { - iconIndex = (int)index; - iconPath = value.Left(pos); - } - } - } - return true; -} - -bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex) -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CSysString programKeyName; - if (!CheckShellExtensionInfo2(extension, programKeyName, iconPath, iconIndex)) - return false; - CKey extProgKey; - return (extProgKey.Open(HKEY_CLASSES_ROOT, programKeyName, KEY_READ) == ERROR_SUCCESS); -} - -static void DeleteShellExtensionKey(const CSysString &extension) -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey rootKey; - rootKey.Attach(HKEY_CLASSES_ROOT); - rootKey.RecurseDeleteKey(GetExtensionKeyName(extension)); - rootKey.Detach(); -} - -static void DeleteShellExtensionProgramKey(const CSysString &extension) -{ - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CKey rootKey; - rootKey.Attach(HKEY_CLASSES_ROOT); - rootKey.RecurseDeleteKey(GetExtProgramKeyName(extension)); - rootKey.Detach(); -} - -void DeleteShellExtensionInfo(const CSysString &extension) -{ - CSysString programKeyName; - UString iconPath; - int iconIndex; - if (CheckShellExtensionInfo2(extension, programKeyName, iconPath, iconIndex)) - DeleteShellExtensionKey(extension); - DeleteShellExtensionProgramKey(extension); -} - -void AddShellExtensionInfo(const CSysString &extension, - const UString &programTitle, - const UString &programOpenCommand, - const UString &iconPath, int iconIndex, - const void *shellNewData, int shellNewDataSize) -{ - DeleteShellExtensionKey(extension); - DeleteShellExtensionProgramKey(extension); - NSynchronization::CCriticalSectionLock lock(g_CriticalSection); - CSysString programKeyName; - { - CSysString ext = extension; - if (iconIndex < 0) - ext = TEXT("*"); - programKeyName = GetExtProgramKeyName(ext); - } - { - CKey extKey; - extKey.Create(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension)); - extKey.SetValue(NULL, programKeyName); - if (shellNewData != NULL) - { - CKey shellNewKey; - shellNewKey.Create(extKey, kShellNewKeyName); - shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize); - } - } - CKey programKey; - programKey.Create(HKEY_CLASSES_ROOT, programKeyName); - programKey.SetValue(NULL, programTitle); - { - CKey iconKey; - iconKey.Create(programKey, kDefaultIconKeyName); - UString iconPathFull = iconPath; - if (iconIndex < 0) - iconIndex = 0; - // if (iconIndex >= 0) - { - iconPathFull += L","; - wchar_t s[16]; - ConvertUInt32ToString(iconIndex, s); - iconPathFull += s; - } - iconKey.SetValue(NULL, iconPathFull); - } - - CKey shellKey; - shellKey.Create(programKey, kShellKeyName); - shellKey.SetValue(NULL, TEXT("")); - - CKey openKey; - openKey.Create(shellKey, kOpenKeyName); - openKey.SetValue(NULL, TEXT("")); - - CKey commandKey; - commandKey.Create(openKey, kCommandKeyName); - - commandKey.SetValue(NULL, programOpenCommand); -} - -/////////////////////////// -// ContextMenu -/* - -static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip"); -static const TCHAR *kContextMenuHandlerCLASSIDValue = - TEXT("{23170F69-40C1-278A-1000-000100020000}"); -static const TCHAR *kRootKeyNameForFile = TEXT("*"); -static const TCHAR *kRootKeyNameForFolder = TEXT("Folder"); - -static CSysString GetFullContextMenuKeyName(const CSysString &aKeyName) - { return (aKeyName + kContextMenuKeyName); } - -static bool CheckContextMenuHandlerCommon(const CSysString &aKeyName) -{ - NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); - CKey aKey; - if (aKey.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName), KEY_READ) - != ERROR_SUCCESS) - return false; - CSysString aValue; - if (aKey.QueryValue(NULL, aValue) != ERROR_SUCCESS) - return false; - return (aValue.CompareNoCase(kContextMenuHandlerCLASSIDValue) == 0); -} - -bool CheckContextMenuHandler() -{ - return CheckContextMenuHandlerCommon(kRootKeyNameForFile) && - CheckContextMenuHandlerCommon(kRootKeyNameForFolder); -} - -static void DeleteContextMenuHandlerCommon(const CSysString &aKeyName) -{ - CKey rootKey; - rootKey.Attach(HKEY_CLASSES_ROOT); - rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(aKeyName)); - rootKey.Detach(); -} - -void DeleteContextMenuHandler() -{ - DeleteContextMenuHandlerCommon(kRootKeyNameForFile); - DeleteContextMenuHandlerCommon(kRootKeyNameForFolder); -} - -static void AddContextMenuHandlerCommon(const CSysString &aKeyName) -{ - DeleteContextMenuHandlerCommon(aKeyName); - NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); - CKey aKey; - aKey.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName)); - aKey.SetValue(NULL, kContextMenuHandlerCLASSIDValue); -} - -void AddContextMenuHandler() -{ - AddContextMenuHandlerCommon(kRootKeyNameForFile); - AddContextMenuHandlerCommon(kRootKeyNameForFolder); -} -*/ - -} +// RegistryAssociations.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/Registry.h" + +#include "RegistryAssociations.h" + +using namespace NWindows; +using namespace NRegistry; + +namespace NRegistryAssoc { + +// static NSynchronization::CCriticalSection g_CriticalSection; + +static const TCHAR * const kClasses = TEXT("Software\\Classes\\"); +// static const TCHAR * const kShellNewKeyName = TEXT("ShellNew"); +// static const TCHAR * const kShellNewDataValueName = TEXT("Data"); +static const TCHAR * const kDefaultIconKeyName = TEXT("DefaultIcon"); +static const TCHAR * const kShellKeyName = TEXT("shell"); +static const TCHAR * const kOpenKeyName = TEXT("open"); +static const TCHAR * const kCommandKeyName = TEXT("command"); +static const char * const k7zipPrefix = "7-Zip."; + +static CSysString GetExtProgramKeyName(const CSysString &ext) +{ + return CSysString(k7zipPrefix) + ext; +} + +static CSysString GetFullKeyPath(HKEY hkey, const CSysString &name) +{ + CSysString s; + if (hkey != HKEY_CLASSES_ROOT) + s = kClasses; + return s + name; +} + +static CSysString GetExtKeyPath(HKEY hkey, const CSysString &ext) +{ + return GetFullKeyPath(hkey, (TEXT(".")) + ext); +} + +bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext) +{ + ProgramKey.Empty(); + IconPath.Empty(); + IconIndex = -1; + // NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + { + CKey extKey; + if (extKey.Open(hkey, GetExtKeyPath(hkey, ext), KEY_READ) != ERROR_SUCCESS) + return false; + if (extKey.QueryValue(NULL, ProgramKey) != ERROR_SUCCESS) + return false; + } + { + CKey iconKey; + + if (iconKey.Open(hkey, GetFullKeyPath(hkey, ProgramKey + CSysString(CHAR_PATH_SEPARATOR) + kDefaultIconKeyName), KEY_READ) == ERROR_SUCCESS) + { + UString value; + if (iconKey.QueryValue(NULL, value) == ERROR_SUCCESS) + { + const int pos = value.ReverseFind(L','); + IconPath = value; + if (pos >= 0) + { + const wchar_t *end; + const Int32 index = ConvertStringToInt32((const wchar_t *)value + pos + 1, &end); + if (*end == 0) + { + // 9.31: if there is no icon index, we use -1. Is it OK? + if (pos != (int)value.Len() - 1) + IconIndex = (int)index; + IconPath.SetFrom(value, (unsigned)pos); + } + } + } + } + } + return true; +} + +bool CShellExtInfo::IsIt7Zip() const +{ + return ProgramKey.IsPrefixedBy_Ascii_NoCase(k7zipPrefix); +} + +LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext) +{ + // NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey rootKey; + rootKey.Attach(hkey); + LONG res = rootKey.RecurseDeleteKey(GetExtKeyPath(hkey, ext)); + // then we delete only 7-Zip.* key. + rootKey.RecurseDeleteKey(GetFullKeyPath(hkey, GetExtProgramKeyName(ext))); + rootKey.Detach(); + return res; +} + +LONG AddShellExtensionInfo(HKEY hkey, + const CSysString &ext, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, int iconIndex + // , const void *shellNewData, int shellNewDataSize + ) +{ + LONG res = 0; + DeleteShellExtensionInfo(hkey, ext); + // NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CSysString programKeyName; + { + CSysString ext2 (ext); + if (iconIndex < 0) + ext2 = "*"; + programKeyName = GetExtProgramKeyName(ext2); + } + { + CKey extKey; + res = extKey.Create(hkey, GetExtKeyPath(hkey, ext)); + extKey.SetValue(NULL, programKeyName); + /* + if (shellNewData != NULL) + { + CKey shellNewKey; + shellNewKey.Create(extKey, kShellNewKeyName); + shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize); + } + */ + } + CKey programKey; + programKey.Create(hkey, GetFullKeyPath(hkey, programKeyName)); + programKey.SetValue(NULL, programTitle); + { + CKey iconKey; + UString iconPathFull = iconPath; + if (iconIndex < 0) + iconIndex = 0; + // if (iconIndex >= 0) + { + iconPathFull.Add_Char(','); + iconPathFull.Add_UInt32((UInt32)iconIndex); + } + iconKey.Create(programKey, kDefaultIconKeyName); + iconKey.SetValue(NULL, iconPathFull); + } + + CKey shellKey; + shellKey.Create(programKey, kShellKeyName); + shellKey.SetValue(NULL, TEXT("")); + + CKey openKey; + openKey.Create(shellKey, kOpenKeyName); + openKey.SetValue(NULL, TEXT("")); + + CKey commandKey; + commandKey.Create(openKey, kCommandKeyName); + commandKey.SetValue(NULL, programOpenCommand); + return res; +} + +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryAssociations.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryAssociations.h 2010-04-25 15:14:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryAssociations.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,46 +1,31 @@ -// RegistryAssociations.h - -#ifndef __REGISTRYASSOCIATIONS_H -#define __REGISTRYASSOCIATIONS_H - -#include "Common/MyString.h" - -namespace NRegistryAssociations { - - /* - struct CExtInfo - { - UString Ext; - UStringVector Plugins; - // bool Enabled; - }; - bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo); - void ReadInternalAssociations(CObjectVector &items); - void WriteInternalAssociations(const CObjectVector &items); - */ - - bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex); - - // void ReadCompressionInfo(NZipSettings::NCompression::CInfo &anInfo, - void DeleteShellExtensionInfo(const CSysString &extension); - - void AddShellExtensionInfo(const CSysString &extension, - const UString &programTitle, - const UString &programOpenCommand, - const UString &iconPath, int iconIndex, - const void *shellNewData, int shellNewDataSize); - - - /////////////////////////// - // ContextMenu - /* - bool CheckContextMenuHandler(); - void AddContextMenuHandler(); - void DeleteContextMenuHandler(); - */ - -} - -// bool GetProgramDirPrefix(CSysString &aFolder); - -#endif +// RegistryAssociations.h + +#ifndef ZIP7_INC_REGISTRY_ASSOCIATIONS_H +#define ZIP7_INC_REGISTRY_ASSOCIATIONS_H + +#include "../../../Common/MyString.h" + +namespace NRegistryAssoc { + + struct CShellExtInfo + { + CSysString ProgramKey; + UString IconPath; + int IconIndex; + + bool ReadFromRegistry(HKEY hkey, const CSysString &ext); + bool IsIt7Zip() const; + }; + + LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext); + + LONG AddShellExtensionInfo(HKEY hkey, + const CSysString &ext, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, int iconIndex + // , const void *shellNewData, int shellNewDataSize + ); +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryPlugins.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryPlugins.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.cpp 2023-01-30 18:00:00.000000000 +0000 @@ -0,0 +1,145 @@ +// RegistryPlugins.cpp + +#include "StdAfx.h" + +/* +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariant.h" + +#include "IFolder.h" +*/ +#include "RegistryPlugins.h" + +// using namespace NWindows; +// using namespace NFile; + +/* +typedef UINT32 (WINAPI * Func_GetPluginProperty)(PROPID propID, PROPVARIANT *value); + +static bool ReadPluginInfo(CPluginInfo &plugin, bool needCheckDll) +{ + if (needCheckDll) + { + NDLL::CLibrary lib; + if (!lib.LoadEx(plugin.FilePath, LOAD_LIBRARY_AS_DATAFILE)) + return false; + } + NDLL::CLibrary lib; + if (!lib.Load(plugin.FilePath)) + return false; + const + Func_GetPluginProperty + f_GetPluginProperty = ZIP7_GET_PROC_ADDRESS( + Func_GetPluginProperty, lib.Get_HMODULE(), + "GetPluginProperty"); + if (!f_GetPluginProperty) + return false; + + NCOM::CPropVariant prop; + if (f_GetPluginProperty(NPlugin::kType, &prop) != S_OK) + return false; + if (prop.vt == VT_EMPTY) + plugin.Type = kPluginTypeFF; + else if (prop.vt == VT_UI4) + plugin.Type = (EPluginType)prop.ulVal; + else + return false; + prop.Clear(); + + if (f_GetPluginProperty(NPlugin::kName, &prop) != S_OK) + return false; + if (prop.vt != VT_BSTR) + return false; + plugin.Name = prop.bstrVal; + prop.Clear(); + + if (f_GetPluginProperty(NPlugin::kClassID, &prop) != S_OK) + return false; + if (prop.vt == VT_EMPTY) + plugin.ClassID_Defined = false; + else if (prop.vt != VT_BSTR) + return false; + else + { + plugin.ClassID_Defined = true; + plugin.ClassID = *(const GUID *)(const void *)prop.bstrVal; + } + prop.Clear(); + return true; +*/ + +/* +{ + if (f_GetPluginProperty(NPlugin::kOptionsClassID, &prop) != S_OK) + return false; + if (prop.vt == VT_EMPTY) + plugin.OptionsClassID_Defined = false; + else if (prop.vt != VT_BSTR) + return false; + else + { + plugin.OptionsClassID_Defined = true; + plugin.OptionsClassID = *(const GUID *)(const void *)prop.bstrVal; + } +} +*/ + + /* + { + // very old 7-zip used agent plugin in "7-zip.dll" + // but then agent code was moved to 7zfm. + // so now we don't need to load "7-zip.dll" here + CPluginInfo plugin; + plugin.FilePath = baseFolderPrefix + FTEXT("7-zip.dll"); + if (::ReadPluginInfo(plugin, false)) + if (plugin.Type == kPluginTypeFF) + plugins.Add(plugin); + } + */ + /* + FString folderPath = NDLL::GetModuleDirPrefix(); + folderPath += "Plugins" STRING_PATH_SEPARATOR; + NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(folderPath); + NFind::CFileInfo fi; + while (enumerator.Next(fi)) + { + if (fi.IsDir()) + continue; + CPluginInfo plugin; + plugin.FilePath = folderPath + fi.Name; + if (::ReadPluginInfo(plugin, true)) + if (plugin.Type == kPluginTypeFF) + plugins.Add(plugin); + } + */ + + /* + ReadPluginInfoList(plugins); + for (unsigned i = 0; i < plugins.Size();) + if (plugins[i].Type != kPluginTypeFF) + plugins.Delete(i); + else + i++; + */ + +/* +void ReadFileFolderPluginInfoList(CObjectVector &plugins) +{ + plugins.Clear(); + { + } + + { + CPluginInfo &plugin = plugins.AddNew(); + // p.FilePath.Empty(); + plugin.Type = kPluginTypeFF; + plugin.Name = "7-Zip"; + // plugin.ClassID = CLSID_CAgentArchiveHandler; + // plugin.ClassID_Defined = true; + // plugin.ClassID_Defined = false; + // plugin.OptionsClassID_Defined = false; + } +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryPlugins.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryPlugins.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryPlugins.h 2023-01-30 20:00:00.000000000 +0000 @@ -1,32 +1,29 @@ -// RegistryPlugins.h - -#ifndef __REGISTRY_PLUGINS_H -#define __REGISTRY_PLUGINS_H - -#include "../../../Common/MyString.h" - -enum EPluginType -{ - kPluginTypeFF = 0 -}; - -struct CPluginInfo -{ - FString FilePath; - EPluginType Type; - UString Name; - CLSID ClassID; - CLSID OptionsClassID; - bool ClassIDDefined; - bool OptionsClassIDDefined; - - // CSysString Extension; - // CSysString AddExtension; - // bool UpdateEnabled; - // bool KeepName; -}; - -void ReadPluginInfoList(CObjectVector &plugins); -void ReadFileFolderPluginInfoList(CObjectVector &plugins); - -#endif +// RegistryPlugins.h + +#ifndef ZIP7_INC_REGISTRY_PLUGINS_H +#define ZIP7_INC_REGISTRY_PLUGINS_H + +#include "../../../Common/MyString.h" + +/* +enum EPluginType +{ + kPluginTypeFF = 0 +}; + +struct CPluginInfo +{ + EPluginType Type; + // bool ClassID_Defined; + // bool OptionsClassID_Defined; + // FString FilePath; + // UString Name; + // CLSID ClassID; + // CLSID OptionsClassID; +}; + +// void ReadPluginInfoList(CObjectVector &plugins); +// void ReadFileFolderPluginInfoList(CObjectVector &plugins); +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryUtils.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.cpp 2024-11-04 16:00:00.000000000 +0000 @@ -1,167 +1,194 @@ -// RegistryUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" - -#include "../../../Windows/Registry.h" - -#include "RegistryUtils.h" - -using namespace NWindows; -using namespace NRegistry; - -#define REG_PATH_7Z TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") - -static const TCHAR *kCUBasePath = REG_PATH_7Z; -static const TCHAR *kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM"); -// static const TCHAR *kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM"); - -static const WCHAR *kLangValueName = L"Lang"; -static const WCHAR *kViewer = L"Viewer"; -static const WCHAR *kEditor = L"Editor"; -static const WCHAR *kDiff = L"Diff"; -static const TCHAR *kShowDots = TEXT("ShowDots"); -static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons"); -static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu"); - -static const TCHAR *kFullRow = TEXT("FullRow"); -static const TCHAR *kShowGrid = TEXT("ShowGrid"); -static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection"); -// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd"); -static const TCHAR *kLargePagesEnable = TEXT("LargePages"); -static const TCHAR *kSingleClick = TEXT("SingleClick"); -// static const TCHAR *kUnderline = TEXT("Underline"); - -static const TCHAR *kFlatViewName = TEXT("FlatViewArc"); -// static const TCHAR *kShowDeletedFiles = TEXT("ShowDeleted"); - -static void SaveCuString(LPCTSTR keyPath, LPCWSTR valuePath, LPCWSTR value) -{ - CKey key; - key.Create(HKEY_CURRENT_USER, keyPath); - key.SetValue(valuePath, value); -} - -static void ReadCuString(LPCTSTR keyPath, LPCWSTR valuePath, UString &res) -{ - res.Empty(); - CKey key; - if (key.Open(HKEY_CURRENT_USER, keyPath, KEY_READ) == ERROR_SUCCESS) - key.QueryValue(valuePath, res); -} - -void SaveRegLang(const UString &path) { SaveCuString(kCUBasePath, kLangValueName, path); } -void ReadRegLang(UString &path) { ReadCuString(kCUBasePath, kLangValueName, path); } - -void SaveRegEditor(bool useEditor, const UString &path) { SaveCuString(kCU_FMPath, useEditor ? kEditor : kViewer, path); } -void ReadRegEditor(bool useEditor, UString &path) { ReadCuString(kCU_FMPath, useEditor ? kEditor : kViewer, path); } - -void SaveRegDiff(const UString &path) { SaveCuString(kCU_FMPath, kDiff, path); } -void ReadRegDiff(UString &path) { ReadCuString(kCU_FMPath, kDiff, path); } - -static void Save7ZipOption(const TCHAR *value, bool enabled) -{ - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - key.SetValue(value, enabled); -} - -static void SaveOption(const TCHAR *value, bool enabled) -{ - CKey key; - key.Create(HKEY_CURRENT_USER, kCU_FMPath); - key.SetValue(value, enabled); -} - -static bool Read7ZipOption(const TCHAR *value, bool defaultValue) -{ - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) - { - bool enabled; - if (key.QueryValue(value, enabled) == ERROR_SUCCESS) - return enabled; - } - return defaultValue; -} - -static bool ReadOption(const TCHAR *value, bool defaultValue) -{ - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) - { - bool enabled; - if (key.QueryValue(value, enabled) == ERROR_SUCCESS) - return enabled; - } - return defaultValue; -} - -/* -static void SaveLmOption(const TCHAR *value, bool enabled) -{ - CKey key; - key.Create(HKEY_LOCAL_MACHINE, kLM_Path); - key.SetValue(value, enabled); -} - -static bool ReadLmOption(const TCHAR *value, bool defaultValue) -{ - CKey key; - if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS) - { - bool enabled; - if (key.QueryValue(value, enabled) == ERROR_SUCCESS) - return enabled; - } - return defaultValue; -} -*/ - -void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); } -bool ReadShowDots() { return ReadOption(kShowDots, false); } - -void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); } -bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); } - -void Save_ShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); } -bool Read_ShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); } - -void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); } -bool ReadFullRow() { return ReadOption(kFullRow, false); } - -void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); } -bool ReadShowGrid(){ return ReadOption(kShowGrid, false); } - -void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); } -bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); } - -void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); } -bool ReadSingleClick(){ return ReadOption(kSingleClick, false); } - -/* -void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); } -bool ReadUnderline(){ return ReadOption(kUnderline, false); } -*/ - -// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); } -// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); } - -void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); } -bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); } - -static CSysString GetFlatViewName(UInt32 panelIndex) -{ - TCHAR panelString[16]; - ConvertUInt32ToString(panelIndex, panelString); - return (CSysString)kFlatViewName + panelString; -} - -void SaveFlatView(UInt32 panelIndex, bool enable) { SaveOption(GetFlatViewName(panelIndex), enable); } -bool ReadFlatView(UInt32 panelIndex) { return ReadOption(GetFlatViewName(panelIndex), false); } - -/* -void Save_ShowDeleted(bool enable) { SaveOption(kShowDeletedFiles, enable); } -bool Read_ShowDeleted() { return ReadOption(kShowDeletedFiles, false); } -*/ \ No newline at end of file +// RegistryUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "../../../Windows/Registry.h" + +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NRegistry; + +#define REG_PATH_7Z TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") + +static LPCTSTR const kCUBasePath = REG_PATH_7Z; +static LPCTSTR const kCU_FMPath = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM"); +// static LPCTSTR const kLM_Path = REG_PATH_7Z TEXT(STRING_PATH_SEPARATOR) TEXT("FM"); + +static LPCWSTR const kLangValueName = L"Lang"; + +static LPCWSTR const kViewer = L"Viewer"; +static LPCWSTR const kEditor = L"Editor"; +static LPCWSTR const kDiff = L"Diff"; +static LPCWSTR const kVerCtrlPath = L"7vc"; + +static LPCTSTR const kShowDots = TEXT("ShowDots"); +static LPCTSTR const kShowRealFileIcons = TEXT("ShowRealFileIcons"); +static LPCTSTR const kFullRow = TEXT("FullRow"); +static LPCTSTR const kShowGrid = TEXT("ShowGrid"); +static LPCTSTR const kSingleClick = TEXT("SingleClick"); +static LPCTSTR const kAlternativeSelection = TEXT("AlternativeSelection"); +// static LPCTSTR const kUnderline = TEXT("Underline"); + +static LPCTSTR const kShowSystemMenu = TEXT("ShowSystemMenu"); + +// static LPCTSTR const kLockMemoryAdd = TEXT("LockMemoryAdd"); +static LPCTSTR const kLargePages = TEXT("LargePages"); + +static LPCTSTR const kFlatViewName = TEXT("FlatViewArc"); +// static LPCTSTR const kShowDeletedFiles = TEXT("ShowDeleted"); + +static void SaveCuString(LPCTSTR keyPath, LPCWSTR valuePath, LPCWSTR value) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, keyPath); + key.SetValue(valuePath, value); +} + +static void ReadCuString(LPCTSTR keyPath, LPCWSTR valuePath, UString &res) +{ + res.Empty(); + CKey key; + if (key.Open(HKEY_CURRENT_USER, keyPath, KEY_READ) == ERROR_SUCCESS) + key.QueryValue(valuePath, res); +} + +void SaveRegLang(const UString &path) { SaveCuString(kCUBasePath, kLangValueName, path); } +void ReadRegLang(UString &path) { ReadCuString(kCUBasePath, kLangValueName, path); } + +void SaveRegEditor(bool useEditor, const UString &path) { SaveCuString(kCU_FMPath, useEditor ? kEditor : kViewer, path); } +void ReadRegEditor(bool useEditor, UString &path) { ReadCuString(kCU_FMPath, useEditor ? kEditor : kViewer, path); } + +void SaveRegDiff(const UString &path) { SaveCuString(kCU_FMPath, kDiff, path); } +void ReadRegDiff(UString &path) { ReadCuString(kCU_FMPath, kDiff, path); } + +void ReadReg_VerCtrlPath(UString &path) { ReadCuString(kCU_FMPath, kVerCtrlPath, path); } + +static void Save7ZipOption(LPCTSTR value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(value, enabled); +} + +static void SaveOption(LPCTSTR value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCU_FMPath); + key.SetValue(value, enabled); +} + +static bool Read7ZipOption(LPCTSTR value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.GetValue_bool_IfOk(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} + +static void ReadOption(CKey &key, LPCTSTR name, bool &dest) +{ + key.GetValue_bool_IfOk(name, dest); +} + +/* +static void SaveLmOption(LPCTSTR value, bool enabled) +{ + CKey key; + key.Create(HKEY_LOCAL_MACHINE, kLM_Path); + key.SetValue(value, enabled); +} + +static bool ReadLmOption(LPCTSTR value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} +*/ + +void CFmSettings::Save() const +{ + SaveOption(kShowDots, ShowDots); + SaveOption(kShowRealFileIcons, ShowRealFileIcons); + SaveOption(kFullRow, FullRow); + SaveOption(kShowGrid, ShowGrid); + SaveOption(kSingleClick, SingleClick); + SaveOption(kAlternativeSelection, AlternativeSelection); + // SaveOption(kUnderline, Underline); + + SaveOption(kShowSystemMenu, ShowSystemMenu); +} + +void CFmSettings::Load() +{ + ShowDots = false; + ShowRealFileIcons = false; + /* if (FullRow == false), we can use mouse click on another columns + to select group of files. We need to implement additional + way to select files in any column as in Explorer. + Then we can enable (FullRow == true) default mode. */ + // FullRow = true; + FullRow = false; + ShowGrid = false; + SingleClick = false; + AlternativeSelection = false; + // Underline = false; + + ShowSystemMenu = false; + + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + { + ReadOption(key, kShowDots, ShowDots); + ReadOption(key, kShowRealFileIcons, ShowRealFileIcons); + ReadOption(key, kFullRow, FullRow); + ReadOption(key, kShowGrid, ShowGrid); + ReadOption(key, kSingleClick, SingleClick); + ReadOption(key, kAlternativeSelection, AlternativeSelection); + // ReadOption(key, kUnderline, Underline); + + ReadOption(key, kShowSystemMenu, ShowSystemMenu ); + } +} + + +// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); } +// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); } + +void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePages, enable); } +bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePages, false); } + +static CSysString GetFlatViewName(UInt32 panelIndex) +{ + TCHAR panelString[16]; + ConvertUInt32ToString(panelIndex, panelString); + return (CSysString)kFlatViewName + panelString; +} + +void SaveFlatView(UInt32 panelIndex, bool enable) { SaveOption(GetFlatViewName(panelIndex), enable); } + +bool ReadFlatView(UInt32 panelIndex) +{ + bool enabled = false; + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + ReadOption(key, GetFlatViewName(panelIndex), enabled); + return enabled; +} + +/* +void Save_ShowDeleted(bool enable) { SaveOption(kShowDeletedFiles, enable); } +bool Read_ShowDeleted() { return ReadOption(kShowDeletedFiles, false); } +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RegistryUtils.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RegistryUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,58 +1,50 @@ -// RegistryUtils.h - -#ifndef __REGISTRY_UTILS_H -#define __REGISTRY_UTILS_H - -#include "../../../Common/MyTypes.h" -#include "../../../Common/MyString.h" - -void SaveRegLang(const UString &path); -void ReadRegLang(UString &path); - -void SaveRegEditor(bool useEditor, const UString &path); -void ReadRegEditor(bool useEditor, UString &path); - -void SaveRegDiff(const UString &path); -void ReadRegDiff(UString &path); - -void SaveShowDots(bool showDots); -bool ReadShowDots(); - -void SaveShowRealFileIcons(bool show); -bool ReadShowRealFileIcons(); - -void Save_ShowSystemMenu(bool showSystemMenu); -bool Read_ShowSystemMenu(); - -void SaveFullRow(bool enable); -bool ReadFullRow(); - -void SaveShowGrid(bool enable); -bool ReadShowGrid(); - -void SaveAlternativeSelection(bool enable); -bool ReadAlternativeSelection(); - -// void SaveLockMemoryAdd(bool enable); -// bool ReadLockMemoryAdd(); - -bool ReadLockMemoryEnable(); -void SaveLockMemoryEnable(bool enable); - -void SaveSingleClick(bool enable); -bool ReadSingleClick(); - -/* -void SaveUnderline(bool enable); -bool ReadUnderline(); -*/ - -void SaveFlatView(UInt32 panelIndex, bool enable); -bool ReadFlatView(UInt32 panelIndex); - -/* -void Save_ShowDeleted(bool enable); -bool Read_ShowDeleted(); -*/ - -#endif +// RegistryUtils.h + +#ifndef ZIP7_INC_REGISTRY_UTILS_H +#define ZIP7_INC_REGISTRY_UTILS_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +void SaveRegLang(const UString &path); +void ReadRegLang(UString &path); + +void SaveRegEditor(bool useEditor, const UString &path); +void ReadRegEditor(bool useEditor, UString &path); + +void SaveRegDiff(const UString &path); +void ReadRegDiff(UString &path); + +void ReadReg_VerCtrlPath(UString &path); + +struct CFmSettings +{ + bool ShowDots; + bool ShowRealFileIcons; + bool FullRow; + bool ShowGrid; + bool SingleClick; + bool AlternativeSelection; + // bool Underline; + + bool ShowSystemMenu; + + void Save() const; + void Load(); +}; + +// void SaveLockMemoryAdd(bool enable); +// bool ReadLockMemoryAdd(); + +bool ReadLockMemoryEnable(); +void SaveLockMemoryEnable(bool enable); + +void SaveFlatView(UInt32 panelIndex, bool enable); +bool ReadFlatView(UInt32 panelIndex); + +/* +void Save_ShowDeleted(bool enable); +bool Read_ShowDeleted(); +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RootFolder.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RootFolder.cpp 2015-10-03 17:53:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.cpp 2025-06-16 06:00:00.000000000 +0000 @@ -1,313 +1,342 @@ -// RootFolder.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/PropVariant.h" - -#include "../../PropID.h" - -#if defined(_WIN32) && !defined(UNDER_CE) -#define USE_WIN_PATHS -#endif - -static const unsigned kNumRootFolderItems = - #ifdef USE_WIN_PATHS - 4 - #else - 1 - #endif - ; - - -#include "FSFolder.h" -#include "LangUtils.h" -#ifdef USE_WIN_PATHS -#include "NetFolder.h" -#include "FSDrives.h" -#include "AltStreamsFolder.h" -#endif -#include "RootFolder.h" -#include "SysIconUtils.h" - -#include "resource.h" - -using namespace NWindows; - -static const Byte kProps[] = -{ - kpidName -}; - -UString RootFolder_GetName_Computer(int &iconIndex) -{ - #ifdef USE_WIN_PATHS - iconIndex = GetIconIndexForCSIDL(CSIDL_DRIVES); - #else - GetRealIconIndex(FSTRING_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, iconIndex); - #endif - return LangString(IDS_COMPUTER); -} - -UString RootFolder_GetName_Network(int &iconIndex) -{ - iconIndex = 0; // FIXME GetIconIndexForCSIDL(CSIDL_NETWORK); - return LangString(IDS_NETWORK); -} - -UString RootFolder_GetName_Documents(int &iconIndex) -{ - iconIndex = 0; // FIXME GetIconIndexForCSIDL(CSIDL_PERSONAL); - return LangString(IDS_DOCUMENTS); -} - -enum -{ - ROOT_INDEX_COMPUTER = 0 - #ifdef USE_WIN_PATHS - , ROOT_INDEX_DOCUMENTS - , ROOT_INDEX_NETWORK - , ROOT_INDEX_VOLUMES - #endif -}; - -#ifdef USE_WIN_PATHS -static const wchar_t *kVolPrefix = L"\\\\."; -#endif - -void CRootFolder::Init() -{ - // FIXME _names[ROOT_INDEX_COMPUTER] = RootFolder_GetName_Computer(_iconIndices[ROOT_INDEX_COMPUTER]); - #ifdef USE_WIN_PATHS - _names[ROOT_INDEX_DOCUMENTS] = RootFolder_GetName_Documents(_iconIndices[ROOT_INDEX_DOCUMENTS]); - _names[ROOT_INDEX_NETWORK] = RootFolder_GetName_Network(_iconIndices[ROOT_INDEX_NETWORK]); - _names[ROOT_INDEX_VOLUMES] = kVolPrefix; - _iconIndices[ROOT_INDEX_VOLUMES] = GetIconIndexForCSIDL(CSIDL_DRIVES); - #endif -} - -STDMETHODIMP CRootFolder::LoadItems() -{ - Init(); - return S_OK; -} - -STDMETHODIMP CRootFolder::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = kNumRootFolderItems; - return S_OK; -} - -STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidIsDir: prop = true; break; - case kpidName: prop = _names[itemIndex]; break; - } - prop.Detach(value); - return S_OK; -} - -#ifdef _WIN32 -typedef BOOL (WINAPI *SHGetSpecialFolderPathWp)(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate); -typedef BOOL (WINAPI *SHGetSpecialFolderPathAp)(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate); - -UString GetMyDocsPath() -{ - UString us; - WCHAR s[MAX_PATH + 1]; - SHGetSpecialFolderPathWp getW = (SHGetSpecialFolderPathWp) - #ifdef UNDER_CE - My_GetProcAddress(GetModuleHandle(TEXT("coredll.dll")), "SHGetSpecialFolderPath"); - #else - My_GetProcAddress(GetModuleHandle(TEXT("shell32.dll")), "SHGetSpecialFolderPathW"); - #endif - if (getW && getW(0, s, CSIDL_PERSONAL, FALSE)) - us = s; - #ifndef _UNICODE - else - { - SHGetSpecialFolderPathAp getA = (SHGetSpecialFolderPathAp) - ::GetProcAddress(::GetModuleHandleA("shell32.dll"), "SHGetSpecialFolderPathA"); - CHAR s2[MAX_PATH + 1]; - if (getA && getA(0, s2, CSIDL_PERSONAL, FALSE)) - us = GetUnicodeString(s2); - } - #endif - NFile::NName::NormalizeDirPathPrefix(us); - return us; -} -#endif - -STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) -{ - *resultFolder = NULL; - CMyComPtr subFolder; - - #ifdef USE_WIN_PATHS - if (index == ROOT_INDEX_COMPUTER || index == ROOT_INDEX_VOLUMES) - { - CFSDrives *fsDrivesSpec = new CFSDrives; - subFolder = fsDrivesSpec; - fsDrivesSpec->Init(index == ROOT_INDEX_VOLUMES); - } - else if (index == ROOT_INDEX_NETWORK) - { - CNetFolder *netFolderSpec = new CNetFolder; - subFolder = netFolderSpec; - netFolderSpec->Init(0, 0, _names[ROOT_INDEX_NETWORK] + WCHAR_PATH_SEPARATOR); - } - else if (index == ROOT_INDEX_DOCUMENTS) - { - UString s = GetMyDocsPath(); - if (!s.IsEmpty()) - { - NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; - subFolder = fsFolderSpec; - RINOK(fsFolderSpec->Init(us2fs(s))); - } - } - #else - if (index == ROOT_INDEX_COMPUTER) - { - NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder; - subFolder = fsFolder; - fsFolder->InitToRoot(); - } - #endif - else - return E_INVALIDARG; - - *resultFolder = subFolder.Detach(); - return S_OK; -} - -static bool AreEqualNames(const UString &path, const wchar_t *name) -{ - unsigned len = MyStringLen(name); - if (len > path.Len() || len + 1 < path.Len()) - return false; - if (len + 1 == path.Len() && path[len] != WCHAR_PATH_SEPARATOR) - return false; - return path.IsPrefixedBy(name); -} - -STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) -{ - *resultFolder = 0; - UString name2 = name; - name2.Trim(); - - if (name2.IsEmpty()) - { - CRootFolder *rootFolderSpec = new CRootFolder; - CMyComPtr rootFolder = rootFolderSpec; - rootFolderSpec->Init(); - *resultFolder = rootFolder.Detach(); - return S_OK; - } - - for (unsigned i = 0; i < kNumRootFolderItems; i++) - if (AreEqualNames(name2, _names[i])) - return BindToFolder((UInt32)i, resultFolder); - - #ifdef USE_WIN_PATHS - if (AreEqualNames(name2, L"My Documents") || - AreEqualNames(name2, L"Documents")) - return BindToFolder((UInt32)ROOT_INDEX_DOCUMENTS, resultFolder); - #else - if (name2 == WSTRING_PATH_SEPARATOR) - return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder); - #endif - - if (AreEqualNames(name2, L"My Computer") || - AreEqualNames(name2, L"Computer")) - return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder); - - if (name2 == WSTRING_PATH_SEPARATOR) - { - CMyComPtr subFolder = this; - *resultFolder = subFolder.Detach(); - return S_OK; - } - - if (name2.Len() < 2) - return E_INVALIDARG; - - CMyComPtr subFolder; - - #ifdef USE_WIN_PATHS - if (name2.IsPrefixedBy(kVolPrefix)) - { - CFSDrives *folderSpec = new CFSDrives; - subFolder = folderSpec; - folderSpec->Init(true); - } - else if (name2 == NFile::NName::kSuperPathPrefix) - { - CFSDrives *folderSpec = new CFSDrives; - subFolder = folderSpec; - folderSpec->Init(false, true); - } - else if (name2.Back() == ':') - { - NAltStreamsFolder::CAltStreamsFolder *folderSpec = new NAltStreamsFolder::CAltStreamsFolder; - subFolder = folderSpec; - if (folderSpec->Init(us2fs(name2)) != S_OK) - return E_INVALIDARG; - } - else - #endif - { - NFile::NName::NormalizeDirPathPrefix(name2); - NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; - subFolder = fsFolderSpec; - if (fsFolderSpec->Init(us2fs(name2)) != S_OK) - { - #ifdef USE_WIN_PATHS - if (name2[0] == WCHAR_PATH_SEPARATOR) - { - CNetFolder *netFolderSpec = new CNetFolder; - subFolder = netFolderSpec; - netFolderSpec->Init(name2); - } - else - #endif - return E_INVALIDARG; - } - } - - *resultFolder = subFolder.Detach(); - return S_OK; -} - -STDMETHODIMP CRootFolder::BindToParentFolder(IFolderFolder **resultFolder) -{ - *resultFolder = 0; - return S_OK; -} - -IMP_IFolderFolder_Props(CRootFolder) - -STDMETHODIMP CRootFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) -{ - NCOM::CPropVariant prop; - switch (propID) - { - case kpidType: prop = "RootFolder"; break; - case kpidPath: prop = ""; break; - } - prop.Detach(value); - return S_OK; -} - -STDMETHODIMP CRootFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex) -{ - *iconIndex = _iconIndices[index]; - return S_OK; -} +// RootFolder.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" + +#include "../../PropID.h" + +#if defined(_WIN32) && !defined(UNDER_CE) +#define USE_WIN_PATHS +#endif + +static const unsigned kNumRootFolderItems = + #ifdef USE_WIN_PATHS + 4 + #else + 1 + #endif + ; + + +#include "FSFolder.h" +#include "LangUtils.h" +#ifdef USE_WIN_PATHS +#include "NetFolder.h" +#include "FSDrives.h" +#include "AltStreamsFolder.h" +#endif +#include "RootFolder.h" +#include "SysIconUtils.h" + +#include "resource.h" + +using namespace NWindows; + +static const Byte kProps[] = +{ + kpidName +}; + +UString RootFolder_GetName_Computer(int &iconIndex); +UString RootFolder_GetName_Computer(int &iconIndex) +{ + #ifdef USE_WIN_PATHS + iconIndex = Shell_GetFileInfo_SysIconIndex_for_CSIDL(CSIDL_DRIVES); + #else + iconIndex = Shell_GetFileInfo_SysIconIndex_for_Path(FSTRING_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY); + #endif + return LangString(IDS_COMPUTER); +} + +UString RootFolder_GetName_Network(int &iconIndex); +UString RootFolder_GetName_Network(int &iconIndex) +{ + iconIndex = Shell_GetFileInfo_SysIconIndex_for_CSIDL(CSIDL_NETWORK); + return LangString(IDS_NETWORK); +} + +UString RootFolder_GetName_Documents(int &iconIndex); +UString RootFolder_GetName_Documents(int &iconIndex) +{ + iconIndex = Shell_GetFileInfo_SysIconIndex_for_CSIDL(CSIDL_PERSONAL); + return LangString(IDS_DOCUMENTS); +} + +enum +{ + ROOT_INDEX_COMPUTER = 0 + #ifdef USE_WIN_PATHS + , ROOT_INDEX_DOCUMENTS + , ROOT_INDEX_NETWORK + , ROOT_INDEX_VOLUMES + #endif +}; + +#ifdef USE_WIN_PATHS +static const char * const kVolPrefix = "\\\\."; +#endif + +void CRootFolder::Init() +{ + _names[ROOT_INDEX_COMPUTER] = RootFolder_GetName_Computer(_iconIndices[ROOT_INDEX_COMPUTER]); + #ifdef USE_WIN_PATHS + _names[ROOT_INDEX_DOCUMENTS] = RootFolder_GetName_Documents(_iconIndices[ROOT_INDEX_DOCUMENTS]); + _names[ROOT_INDEX_NETWORK] = RootFolder_GetName_Network(_iconIndices[ROOT_INDEX_NETWORK]); + _names[ROOT_INDEX_VOLUMES] = kVolPrefix; + _iconIndices[ROOT_INDEX_VOLUMES] = Shell_GetFileInfo_SysIconIndex_for_CSIDL(CSIDL_DRIVES); + #endif +} + +Z7_COM7F_IMF(CRootFolder::LoadItems()) +{ + Init(); + return S_OK; +} + +Z7_COM7F_IMF(CRootFolder::GetNumberOfItems(UInt32 *numItems)) +{ + *numItems = kNumRootFolderItems; + return S_OK; +} + +Z7_COM7F_IMF(CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidIsDir: prop = true; break; + case kpidName: prop = _names[itemIndex]; break; + } + prop.Detach(value); + return S_OK; +} + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0400 // nt4 +#define Z7_USE_DYN_SHGetSpecialFolderPath +#endif + +#ifdef Z7_USE_DYN_SHGetSpecialFolderPath +typedef BOOL (WINAPI *Func_SHGetSpecialFolderPathW)(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate); +typedef BOOL (WINAPI *Func_SHGetSpecialFolderPathA)(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate); +#endif + +static UString GetMyDocsPath() +{ + UString us; + WCHAR s[MAX_PATH + 1]; +#ifdef Z7_USE_DYN_SHGetSpecialFolderPath +#ifdef UNDER_CE + #define shell_name TEXT("coredll.dll") +#else + #define shell_name TEXT("shell32.dll") +#endif + Func_SHGetSpecialFolderPathW getW = Z7_GET_PROC_ADDRESS( + Func_SHGetSpecialFolderPathW, GetModuleHandle(shell_name), + "SHGetSpecialFolderPathW"); + if (getW && getW +#else + if (SHGetSpecialFolderPathW +#endif + (NULL, s, CSIDL_PERSONAL, FALSE)) + us = s; + #ifndef _UNICODE + else + { + CHAR s2[MAX_PATH + 1]; +#ifdef Z7_USE_DYN_SHGetSpecialFolderPath + Func_SHGetSpecialFolderPathA getA = Z7_GET_PROC_ADDRESS( + Func_SHGetSpecialFolderPathA, ::GetModuleHandleA("shell32.dll"), + "SHGetSpecialFolderPathA"); + if (getA && getA +#else + if (SHGetSpecialFolderPathA +#endif + (NULL, s2, CSIDL_PERSONAL, FALSE)) + us = GetUnicodeString(s2); + } + #endif + NFile::NName::NormalizeDirPathPrefix(us); + return us; +} + +Z7_COM7F_IMF(CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + CMyComPtr subFolder; + + #ifdef USE_WIN_PATHS + if (index == ROOT_INDEX_COMPUTER || index == ROOT_INDEX_VOLUMES) + { + CFSDrives *fsDrivesSpec = new CFSDrives; + subFolder = fsDrivesSpec; + fsDrivesSpec->Init(index == ROOT_INDEX_VOLUMES); + } + else if (index == ROOT_INDEX_NETWORK) + { + CNetFolder *netFolderSpec = new CNetFolder; + subFolder = netFolderSpec; + netFolderSpec->Init(NULL, NULL, _names[ROOT_INDEX_NETWORK] + WCHAR_PATH_SEPARATOR); + } + else if (index == ROOT_INDEX_DOCUMENTS) + { + UString s = GetMyDocsPath(); + if (!s.IsEmpty()) + { + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(us2fs(s))) + } + } + #else + if (index == ROOT_INDEX_COMPUTER) + { + NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder; + subFolder = fsFolder; + fsFolder->InitToRoot(); + } + #endif + else + return E_INVALIDARG; + + *resultFolder = subFolder.Detach(); + return S_OK; +} + +static bool AreEqualNames(const UString &path, const wchar_t *name) +{ + unsigned len = MyStringLen(name); + if (len > path.Len() || len + 1 < path.Len()) + return false; + if (len + 1 == path.Len() && !IS_PATH_SEPAR(path[len])) + return false; + return path.IsPrefixedBy(name); +} + +Z7_COM7F_IMF(CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + UString name2 = name; + name2.Trim(); + + if (name2.IsEmpty()) + { + CRootFolder *rootFolderSpec = new CRootFolder; + CMyComPtr rootFolder = rootFolderSpec; + rootFolderSpec->Init(); + *resultFolder = rootFolder.Detach(); + return S_OK; + } + + for (unsigned i = 0; i < kNumRootFolderItems; i++) + if (AreEqualNames(name2, _names[i])) + return BindToFolder((UInt32)i, resultFolder); + + #ifdef USE_WIN_PATHS + if (AreEqualNames(name2, L"My Documents") || + AreEqualNames(name2, L"Documents")) + return BindToFolder((UInt32)ROOT_INDEX_DOCUMENTS, resultFolder); + #else + if (name2.IsEqualTo(STRING_PATH_SEPARATOR)) + return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder); + #endif + + if (AreEqualNames(name2, L"My Computer") || + AreEqualNames(name2, L"Computer")) + return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder); + + if (name2.IsEqualTo(STRING_PATH_SEPARATOR)) + { + CMyComPtr subFolder = this; + *resultFolder = subFolder.Detach(); + return S_OK; + } + + if (name2.Len() < 2) + return E_INVALIDARG; + + CMyComPtr subFolder; + + #ifdef USE_WIN_PATHS + if (name2.IsPrefixedBy_Ascii_NoCase(kVolPrefix)) + { + CFSDrives *folderSpec = new CFSDrives; + subFolder = folderSpec; + folderSpec->Init(true); + } + else if (name2.IsEqualTo(NFile::NName::kSuperPathPrefix)) + { + CFSDrives *folderSpec = new CFSDrives; + subFolder = folderSpec; + folderSpec->Init(false, true); + } + else if (name2.Back() == ':' + && (name2.Len() != 2 || !NFile::NName::IsDrivePath2(name2))) + { + NAltStreamsFolder::CAltStreamsFolder *folderSpec = new NAltStreamsFolder::CAltStreamsFolder; + subFolder = folderSpec; + if (folderSpec->Init(us2fs(name2)) != S_OK) + return E_INVALIDARG; + } + else + #endif + { + NFile::NName::NormalizeDirPathPrefix(name2); + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + subFolder = fsFolderSpec; + if (fsFolderSpec->Init(us2fs(name2)) != S_OK) + { + #ifdef USE_WIN_PATHS + if (IS_PATH_SEPAR(name2[0])) + { + CNetFolder *netFolderSpec = new CNetFolder; + subFolder = netFolderSpec; + netFolderSpec->Init(name2); + } + else + #endif + return E_INVALIDARG; + } + } + + *resultFolder = subFolder.Detach(); + return S_OK; +} + +Z7_COM7F_IMF(CRootFolder::BindToParentFolder(IFolderFolder **resultFolder)) +{ + *resultFolder = NULL; + return S_OK; +} + +IMP_IFolderFolder_Props(CRootFolder) + +Z7_COM7F_IMF(CRootFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)) +{ + NCOM::CPropVariant prop; + switch (propID) + { + case kpidType: prop = "RootFolder"; break; + case kpidPath: prop = ""; break; + } + prop.Detach(value); + return S_OK; +} + +Z7_COM7F_IMF(CRootFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)) +{ + *iconIndex = _iconIndices[index]; + return S_OK; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/RootFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/RootFolder.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/RootFolder.h 2023-04-01 11:00:00.000000000 +0000 @@ -1,27 +1,24 @@ -// RootFolder.h - -#ifndef __ROOT_FOLDER_H -#define __ROOT_FOLDER_H - -#include "../../../Common/MyString.h" - -#include "IFolder.h" - -const unsigned kNumRootFolderItems_Max = 4; - -class CRootFolder: - public IFolderFolder, - public IFolderGetSystemIconIndex, - public CMyUnknownImp -{ - UString _names[kNumRootFolderItems_Max]; - int _iconIndices[kNumRootFolderItems_Max]; - -public: - MY_UNKNOWN_IMP1(IFolderGetSystemIconIndex) - INTERFACE_FolderFolder(;) - STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex); - void Init(); -}; - -#endif +// RootFolder.h + +#ifndef ZIP7_INC_ROOT_FOLDER_H +#define ZIP7_INC_ROOT_FOLDER_H + +#include "../../../Common/MyCom.h" +#include "../../../Common/MyString.h" + +#include "IFolder.h" + +const unsigned kNumRootFolderItems_Max = 4; + +Z7_CLASS_IMP_NOQIB_2( + CRootFolder + , IFolderFolder + , IFolderGetSystemIconIndex +) + UString _names[kNumRootFolderItems_Max]; + int _iconIndices[kNumRootFolderItems_Max]; +public: + void Init(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.cpp 2024-10-21 12:00:00.000000000 +0000 @@ -0,0 +1,453 @@ +// SettingsPage.cpp + +#include "StdAfx.h" + +#include + +// #include "../../../Common/IntToString.h" +// #include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#ifndef UNDER_CE +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/MemoryLock.h" +#include "../../../Windows/System.h" +#endif + +#include "../Explorer/MyMessages.h" + +#include "../Common/ZipRegistry.h" + +#include "HelpUtils.h" +#include "LangUtils.h" +#include "RegistryUtils.h" +#include "SettingsPage.h" +#include "SettingsPageRes.h" + +using namespace NWindows; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDX_SETTINGS_SHOW_DOTS, + IDX_SETTINGS_SHOW_REAL_FILE_ICONS, + IDX_SETTINGS_SHOW_SYSTEM_MENU, + IDX_SETTINGS_FULL_ROW, + IDX_SETTINGS_SHOW_GRID, + IDX_SETTINGS_SINGLE_CLICK, + IDX_SETTINGS_ALTERNATIVE_SELECTION, + IDX_SETTINGS_LARGE_PAGES, + IDT_MEM_USAGE_EXTRACT + // , IDT_COMPRESS_MEMORY +}; +#endif + +#define kSettingsTopic "FM/options.htm#settings" + +extern bool IsLargePageSupported(); + +/* +static void AddMemSize(UString &res, UInt64 size, bool needRound = false) +{ + char c; + unsigned moveBits = 0; + if (needRound) + { + UInt64 rn = 0; + if (size >= (1 << 31)) + rn = (1 << 28) - 1; + UInt32 kRound = (1 << 20) - 1; + if (rn < kRound) + rn = kRound; + size += rn; + size &= ~rn; + } + if (size >= ((UInt64)1 << 31) && (size & 0x3FFFFFFF) == 0) + { moveBits = 30; c = 'G'; } + else + { moveBits = 20; c = 'M'; } + res.Add_UInt64(size >> moveBits); + res.Add_Space(); + if (moveBits != 0) + res += c; + res += 'B'; +} + + +int CSettingsPage::AddMemComboItem(UInt64 size, UInt64 percents, bool isDefault) +{ + UString sUser; + UString sRegistry; + if (size == 0) + { + UString s; + s.Add_UInt64(percents); + s += '%'; + if (isDefault) + sUser = "* "; + else + sRegistry = s; + sUser += s; + } + else + { + AddMemSize(sUser, size); + sRegistry = sUser; + for (;;) + { + int pos = sRegistry.Find(L' '); + if (pos < 0) + break; + sRegistry.Delete(pos); + } + if (!sRegistry.IsEmpty()) + if (sRegistry.Back() == 'B') + sRegistry.DeleteBack(); + } + const int index = (int)_memCombo.AddString(sUser); + _memCombo.SetItemData(index, _memLimitStrings.Size()); + _memLimitStrings.Add(sRegistry); + return index; +} +*/ + +bool CSettingsPage::OnInit() +{ + _initMode = true; + _wasChanged = false; + _largePages_wasChanged = false; + _memx_wasChanged = false; + /* + _wasChanged_MemLimit = false; + _memLimitStrings.Clear(); + _memCombo.Attach(GetItem(IDC_SETTINGS_MEM)); + */ + +#ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); +#endif + + CFmSettings st; + st.Load(); + + CheckButton(IDX_SETTINGS_SHOW_DOTS, st.ShowDots); + CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, st.ShowRealFileIcons); + CheckButton(IDX_SETTINGS_FULL_ROW, st.FullRow); + CheckButton(IDX_SETTINGS_SHOW_GRID, st.ShowGrid); + CheckButton(IDX_SETTINGS_SINGLE_CLICK, st.SingleClick); + CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection); + // CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline); + + CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, st.ShowSystemMenu); + + if (IsLargePageSupported()) + CheckButton(IDX_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable()); + else + EnableItem(IDX_SETTINGS_LARGE_PAGES, false); + + + /* + NCompression::CMemUse mu; + bool needSetCur = NCompression::MemLimit_Load(mu); + UInt64 curMemLimit; + { + AddMemComboItem(0, 90, true); + _memCombo.SetCurSel(0); + } + if (mu.IsPercent) + { + const int index = AddMemComboItem(0, mu.Val); + _memCombo.SetCurSel(index); + needSetCur = false; + } + { + _ramSize = (size_t)sizeof(size_t) << 29; + _ramSize_Defined = NSystem::GetRamSize(_ramSize); + UString s; + if (_ramSize_Defined) + { + s += "/ "; + AddMemSize(s, _ramSize, true); + } + SetItemText(IDT_SETTINGS_MEM_RAM, s); + + curMemLimit = mu.GetBytes(_ramSize); + + // size = 100 << 20; // for debug only; + for (unsigned i = (27) * 2;; i++) + { + UInt64 size = (UInt64)(2 + (i & 1)) << (i / 2); + if (i > (20 + sizeof(size_t) * 3 * 1 - 1) * 2) + size = (UInt64)(Int64)-1; + if (needSetCur && (size >= curMemLimit)) + { + const int index = AddMemComboItem(curMemLimit); + _memCombo.SetCurSel(index); + needSetCur = false; + if (size == curMemLimit) + continue; + } + if (size == (UInt64)(Int64)-1) + break; + AddMemComboItem(size); + } + } + */ + + // EnableSubItems(); + + + { + size_t ramSize = (size_t)sizeof(size_t) << 29; + const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); + // ramSize *= 10; // for debug + UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30); + if (ramSize_GB == 0) + ramSize_GB = 1; + UString s ("GB"); + if (ramSize_defined) + { + s += " / "; + s.Add_UInt64(ramSize_GB); + s += " GB (RAM)"; + } + SetItemText(IDT_SETTINGS_MEM_GB, s); + + const UINT valMin = 1; + UINT valMax = 64; // 64GB for RAR7 + if (ramSize_defined /* && ramSize_GB > valMax */) + { + const UINT k_max_val = 1u << 14; + if (ramSize_GB >= k_max_val) + valMax = k_max_val; + else if (ramSize_GB > 1) + valMax = (UINT)ramSize_GB - 1; + else + valMax = 1; + } + + UInt32 limit = NExtract::Read_LimitGB(); + if (limit != 0 && limit != (UInt32)(Int32)-1) + CheckButton(IDX_SETTINGS_MEM_SET, true); + else + { + limit = 4; + EnableSpin(false); + } + SendItemMessage(IDC_SETTINGS_MEM_SPIN, UDM_SETRANGE, 0, MAKELPARAM(valMax, valMin)); // Sets the controls direction + // UDM_SETPOS doesn't set value larger than max value (valMax) of range: + SendItemMessage(IDC_SETTINGS_MEM_SPIN, UDM_SETPOS, 0, limit); + s.Empty(); + s.Add_UInt32(limit); + SetItemText(IDE_SETTINGS_MEM_SPIN_EDIT, s); + } + + _initMode = false; + return CPropertyPage::OnInit(); +} + + +void CSettingsPage::EnableSpin(bool enable) +{ + EnableItem(IDC_SETTINGS_MEM_SPIN, enable); + EnableItem(IDE_SETTINGS_MEM_SPIN_EDIT, enable); +} + + +/* +void CSettingsPage::EnableSubItems() +{ + EnableItem(IDX_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK)); +} +*/ + +/* +static void AddSize_MB(UString &s, UInt64 size) +{ + s.Add_UInt64((size + (1 << 20) - 1) >> 20); + s += " MB"; +} +*/ + +LONG CSettingsPage::OnApply() +{ + if (_wasChanged) + { + CFmSettings st; + st.ShowDots = IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS); + st.ShowRealFileIcons = IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS); + st.FullRow = IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW); + st.ShowGrid = IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID); + st.SingleClick = IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK); + st.AlternativeSelection = IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION); + // st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE); + + st.ShowSystemMenu = IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU); + + st.Save(); + _wasChanged = false; + } + + #ifndef UNDER_CE + if (_largePages_wasChanged) + { + if (IsLargePageSupported()) + { + const bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES); + NSecurity::EnablePrivilege_LockMemory(enable); + SaveLockMemoryEnable(enable); + } + _largePages_wasChanged = false; + } + #endif + + if (_memx_wasChanged) + { + UInt32 val = (UInt32)(Int32)-1; + if (IsButtonCheckedBool(IDX_SETTINGS_MEM_SET)) + { + UString s; + GetItemText(IDE_SETTINGS_MEM_SPIN_EDIT, s); + const wchar_t *end; + val = ConvertStringToUInt32(s.Ptr(), &end); + if (s.IsEmpty() || *end != 0 || val > (1u << 30)) + { + // L"Incorrect value" + ShowErrorMessage(*this, NError::MyFormatMessage(E_INVALIDARG)); + return PSNRET_INVALID; + } + } + NExtract::Save_LimitGB(val); + _memx_wasChanged = false; + } + + /* + if (_wasChanged_MemLimit) + { + const unsigned index = (int)_memCombo.GetItemData_of_CurSel(); + const UString str = _memLimitStrings[index]; + + bool needSave = true; + + NCompression::CMemUse mu; + + if (_ramSize_Defined) + mu.Parse(str); + if (mu.IsDefined) + { + const UInt64 usage64 = mu.GetBytes(_ramSize); + if (_ramSize <= usage64) + { + UString s2 = LangString(IDT_COMPRESS_MEMORY); + if (s2.IsEmpty()) + GetItemText(IDT_COMPRESS_MEMORY, s2); + UString s; + + s += "The selected value is not safe for system performance."; + s.Add_LF(); + s += "The memory consumption for compression operation will exceed RAM size."; + s.Add_LF(); + s.Add_LF(); + AddSize_MB(s, usage64); + + if (!s2.IsEmpty()) + { + s += " : "; + s += s2; + } + + s.Add_LF(); + AddSize_MB(s, _ramSize); + s += " : RAM"; + + s.Add_LF(); + s.Add_LF(); + s += "Are you sure you want set that unsafe value for memory usage?"; + + int res = MessageBoxW(*this, s, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION); + if (res != IDYES) + needSave = false; + } + } + + if (needSave) + { + NCompression::MemLimit_Save(str); + _wasChanged_MemLimit = false; + } + else + return PSNRET_INVALID_NOCHANGEPAGE; + } + */ + + return PSNRET_NOERROR; +} + +void CSettingsPage::OnNotifyHelp() +{ + ShowHelpWindow(kSettingsTopic); +} + +bool CSettingsPage::OnCommand(unsigned code, unsigned itemID, LPARAM param) +{ + if (!_initMode) + { + if (code == EN_CHANGE && itemID == IDE_SETTINGS_MEM_SPIN_EDIT) + { + _memx_wasChanged = true; + Changed(); + } + /* + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_SETTINGS_MEM: + { + _wasChanged_MemLimit = true; + Changed(); + break; + } + } + } + */ + } + return CPropertyPage::OnCommand(code, itemID, param); +} + +bool CSettingsPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDX_SETTINGS_SINGLE_CLICK: + /* + EnableSubItems(); + break; + */ + case IDX_SETTINGS_SHOW_DOTS: + case IDX_SETTINGS_SHOW_SYSTEM_MENU: + case IDX_SETTINGS_SHOW_REAL_FILE_ICONS: + case IDX_SETTINGS_FULL_ROW: + case IDX_SETTINGS_SHOW_GRID: + case IDX_SETTINGS_ALTERNATIVE_SELECTION: + _wasChanged = true; + break; + + case IDX_SETTINGS_LARGE_PAGES: + _largePages_wasChanged = true; + break; + + case IDX_SETTINGS_MEM_SET: + { + _memx_wasChanged = true; + EnableSpin(IsButtonCheckedBool(IDX_SETTINGS_MEM_SET)); + break; + } + + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + + Changed(); + return true; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.h 2024-03-16 10:00:00.000000000 +0000 @@ -0,0 +1,37 @@ +// SettingsPage.h + +#ifndef ZIP7_INC_SETTINGS_PAGE_H +#define ZIP7_INC_SETTINGS_PAGE_H + +#include "../../../Windows/Control/PropertyPage.h" +// #include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" + +class CSettingsPage: public NWindows::NControl::CPropertyPage +{ + bool _wasChanged; + bool _largePages_wasChanged; + bool _memx_wasChanged; + bool _initMode; + /* + bool _wasChanged_MemLimit; + NWindows::NControl::CComboBox _memCombo; + UStringVector _memLimitStrings; + UInt64 _ramSize; + UInt64 _ramSize_Defined; + + int AddMemComboItem(UInt64 size, UInt64 percents = 0, bool isDefault = false); + */ + + // void EnableSubItems(); + bool OnCommand(unsigned code, unsigned itemID, LPARAM param) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual bool OnInit() Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual LONG OnApply() Z7_override; + + void EnableSpin(bool enable); +public: +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage.rc 2024-03-16 06:00:00.000000000 +0000 @@ -0,0 +1,22 @@ +#include "SettingsPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc OPTIONS_PAGE_YC_SIZE + +IDD_SETTINGS MY_PAGE +#include "SettingsPage2.rc" + + +#ifdef UNDER_CE + +#undef m +#undef xc + +#define m 4 +#define xc (SMALL_PAGE_SIZE_X + 8) + +IDD_SETTINGS_2 MY_PAGE +#include "SettingsPage2.rc" + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage2.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPage2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPage2.rc 2024-03-16 17:00:00.000000000 +0000 @@ -0,0 +1,37 @@ +// #define g1xs 60 +// #include "MemDialogRes.h" + +#define save_y 144 +#define spin_y (save_y + 12) +#define spin_x_size 50 + +CAPTION "Settings" +BEGIN + MY_CONTROL_CHECKBOX ( "Show "".."" item", IDX_SETTINGS_SHOW_DOTS, m, 8, xc) + MY_CONTROL_CHECKBOX ( "Show real file &icons", IDX_SETTINGS_SHOW_REAL_FILE_ICONS, m, 22, xc) + MY_CONTROL_CHECKBOX ( "&Full row select", IDX_SETTINGS_FULL_ROW, m, 36, xc) + MY_CONTROL_CHECKBOX ( "Show &grid lines", IDX_SETTINGS_SHOW_GRID, m, 50, xc) + MY_CONTROL_CHECKBOX ( "&Single-click to open an item", IDX_SETTINGS_SINGLE_CLICK, m, 64, xc) + MY_CONTROL_CHECKBOX ( "&Alternative selection mode", IDX_SETTINGS_ALTERNATIVE_SELECTION, m, 78, xc) + + MY_CONTROL_CHECKBOX ( "Show system &menu", IDX_SETTINGS_SHOW_SYSTEM_MENU, m, 100, xc) + + MY_CONTROL_CHECKBOX ( "Use &large memory pages", IDX_SETTINGS_LARGE_PAGES, m, 122, xc) + + LTEXT "Maximum amount of RAM memory usage allowed to unpack archives:", + IDT_MEM_USAGE_EXTRACT, m, save_y, xc, 8 + MY_CONTROL_CHECKBOX_COLON(IDX_SETTINGS_MEM_SET, m + 10, spin_y + 1) + MY_CONTROL_EDIT_WITH_SPIN( + IDE_SETTINGS_MEM_SPIN_EDIT, + IDC_SETTINGS_MEM_SPIN, + "4", m + 30, spin_y, spin_x_size) + LTEXT "GB", IDT_SETTINGS_MEM_GB, m + 30 + spin_x_size + 8, spin_y + 2, xc - m - 30 - spin_x_size - 8, 8 + + // LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 140, xc, 8 + // COMBOBOX IDC_SETTINGS_MEM, m , 152, g1xs, yc - 152, MY_COMBO + // LTEXT "/ RAM", IDT_SETTINGS_MEM_RAM, m + g1xs + m, 154, xc - g1xs - m, MY_TEXT_NOPREFIX +END + +#undef save_y +#undef spin_y +#undef spin_x_size diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SettingsPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SettingsPageRes.h 2024-03-16 11:00:00.000000000 +0000 @@ -0,0 +1,23 @@ +#define IDD_SETTINGS 2500 +#define IDD_SETTINGS_2 12500 + +#define IDX_SETTINGS_SHOW_DOTS 2501 +#define IDX_SETTINGS_SHOW_REAL_FILE_ICONS 2502 +#define IDX_SETTINGS_SHOW_SYSTEM_MENU 2503 +#define IDX_SETTINGS_FULL_ROW 2504 +#define IDX_SETTINGS_SHOW_GRID 2505 +#define IDX_SETTINGS_SINGLE_CLICK 2506 +#define IDX_SETTINGS_ALTERNATIVE_SELECTION 2507 +#define IDX_SETTINGS_LARGE_PAGES 2508 + +#define IDT_MEM_USAGE_EXTRACT 7816 + +#define IDX_SETTINGS_MEM_SET 100 +#define IDE_SETTINGS_MEM_SPIN_EDIT 101 +#define IDC_SETTINGS_MEM_SPIN 102 +#define IDT_SETTINGS_MEM_GB 103 + +// #define IDT_SETTINGS_MEM 100 +// #define IDC_SETTINGS_MEM 101 +// #define IDT_SETTINGS_MEM_RAM 102 +// #define IDT_COMPRESS_MEMORY 4017 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.cpp 2015-10-03 17:53:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.cpp 2023-03-20 10:00:00.000000000 +0000 @@ -1,117 +1,114 @@ -// SplitDialog.cpp - -#include "StdAfx.h" - -#include "../../../Windows/FileName.h" - -#ifdef LANG -#include "LangUtils.h" -#endif - -#include "BrowseDialog.h" -#include "CopyDialogRes.h" -#include "SplitDialog.h" -#include "SplitUtils.h" -#include "resourceGui.h" - -using namespace NWindows; - -#ifdef LANG -static const UInt32 kLangIDs[] = -{ - IDT_SPLIT_PATH, - IDT_SPLIT_VOLUME -}; -#endif - - -bool CSplitDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_SPLIT); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - #endif - _pathCombo.Attach(GetItem(IDC_SPLIT_PATH)); - _volumeCombo.Attach(GetItem(IDC_SPLIT_VOLUME)); - - if (!FilePath.IsEmpty()) - { - UString title; - GetText(title); - title.Add_Space(); - title += FilePath; - SetText(title); - } - _pathCombo.SetText(Path); - AddVolumeItems(_volumeCombo); - _volumeCombo.SetCurSel(0); - NormalizeSize(); - return CModalDialog::OnInit(); -} - -bool CSplitDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ -#ifdef _WIN32 - int mx, my; - GetMargins(8, mx, my); - int bx1, bx2, by; - GetItemSizes(IDCANCEL, bx1, by); - GetItemSizes(IDOK, bx2, by); - int yPos = ySize - my - by; - int xPos = xSize - mx - bx1; - - InvalidateRect(NULL); - - { - RECT r; - GetClientRectOfItem(IDB_SPLIT_PATH, r); - int bx = RECT_SIZE_X(r); - MoveItem(IDB_SPLIT_PATH, xSize - mx - bx, r.top, bx, RECT_SIZE_Y(r)); - ChangeSubWindowSizeX(_pathCombo, xSize - mx - mx - bx - mx); - } - - MoveItem(IDCANCEL, xPos, yPos, bx1, by); - MoveItem(IDOK, xPos - mx - bx2, yPos, bx2, by); -#endif - return false; -} - -bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDB_SPLIT_PATH: - OnButtonSetPath(); - return true; - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CSplitDialog::OnButtonSetPath() -{ - UString currentPath; - _pathCombo.GetText(currentPath); - // UString title = L"Specify a location for output folder"; - UString title = LangString(IDS_SET_FOLDER); - - UString resultPath; - if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) - return; - NFile::NName::NormalizeDirPathPrefix(resultPath); - _pathCombo.SetCurSel(-1); - _pathCombo.SetText(resultPath); -} - -void CSplitDialog::OnOK() -{ - _pathCombo.GetText(Path); - UString volumeString; - _volumeCombo.GetText(volumeString); - volumeString.Trim(); - if (!ParseVolumeSizes(volumeString, VolumeSizes) || VolumeSizes.Size() == 0) - { - ::MessageBoxW(*this, LangString(IDS_INCORRECT_VOLUME_SIZE), L"7-Zip", MB_ICONERROR); - return; - } - CModalDialog::OnOK(); -} +// SplitDialog.cpp + +#include "StdAfx.h" + +#include "../../../Windows/FileName.h" + +#include "LangUtils.h" + +#include "BrowseDialog.h" +#include "CopyDialogRes.h" +#include "SplitDialog.h" +#include "SplitUtils.h" +#include "resourceGui.h" + +using namespace NWindows; + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_SPLIT_PATH, + IDT_SPLIT_VOLUME +}; +#endif + + +bool CSplitDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_SPLIT); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + #endif + _pathCombo.Attach(GetItem(IDC_SPLIT_PATH)); + _volumeCombo.Attach(GetItem(IDC_SPLIT_VOLUME)); + + if (!FilePath.IsEmpty()) + { + UString title; + GetText(title); + title.Add_Space(); + title += FilePath; + SetText(title); + } + _pathCombo.SetText(Path); + AddVolumeItems(_volumeCombo); + _volumeCombo.SetCurSel(0); + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CSplitDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int yPos = ySize - my - by; + int xPos = xSize - mx - bx1; + + InvalidateRect(NULL); + + { + RECT r; + GetClientRectOfItem(IDB_SPLIT_PATH, r); + int bx = RECT_SIZE_X(r); + MoveItem(IDB_SPLIT_PATH, xSize - mx - bx, r.top, bx, RECT_SIZE_Y(r)); + ChangeSubWindowSizeX(_pathCombo, xSize - mx - mx - bx - mx); + } + + MoveItem(IDCANCEL, xPos, yPos, bx1, by); + MoveItem(IDOK, xPos - mx - bx2, yPos, bx2, by); + + return false; +} + +bool CSplitDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_SPLIT_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CSplitDialog::OnButtonSetPath() +{ + UString currentPath; + _pathCombo.GetText(currentPath); + // UString title = "Specify a location for output folder"; + const UString title = LangString(IDS_SET_FOLDER); + + UString resultPath; + if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _pathCombo.SetCurSel(-1); + _pathCombo.SetText(resultPath); +} + +void CSplitDialog::OnOK() +{ + _pathCombo.GetText(Path); + UString volumeString; + _volumeCombo.GetText(volumeString); + volumeString.Trim(); + if (!ParseVolumeSizes(volumeString, VolumeSizes) || VolumeSizes.Size() == 0) + { + ::MessageBoxW(*this, LangString(IDS_INCORRECT_VOLUME_SIZE), L"7-Zip", MB_ICONERROR); + return; + } + CModalDialog::OnOK(); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.h 2023-01-28 19:00:00.000000000 +0000 @@ -1,28 +1,28 @@ -// SplitDialog.h - -#ifndef __SPLIT_DIALOG_H -#define __SPLIT_DIALOG_H - -#include "../../../Windows/Control/Dialog.h" -#include "../../../Windows/Control/ComboBox.h" - -#include "SplitDialogRes.h" - -class CSplitDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox _pathCombo; - NWindows::NControl::CComboBox _volumeCombo; - virtual void OnOK(); - virtual bool OnInit(); - virtual bool OnSize(WPARAM wParam, int xSize, int ySize); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - void OnButtonSetPath(); -public: - UString FilePath; - UString Path; - CRecordVector VolumeSizes; - INT_PTR Create(HWND parentWindow = 0) - { return CModalDialog::Create(IDD_SPLIT, parentWindow); } -}; - -#endif +// SplitDialog.h + +#ifndef ZIP7_INC_SPLIT_DIALOG_H +#define ZIP7_INC_SPLIT_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ComboBox.h" + +#include "SplitDialogRes.h" + +class CSplitDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _pathCombo; + NWindows::NControl::CComboBox _volumeCombo; + virtual void OnOK() Z7_override; + virtual bool OnInit() Z7_override; + virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + void OnButtonSetPath(); +public: + UString FilePath; + UString Path; + CRecordVector VolumeSizes; + INT_PTR Create(HWND parentWindow = NULL) + { return CModalDialog::Create(IDD_SPLIT, parentWindow); } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog.rc 2011-06-07 14:08:46.000000000 +0000 @@ -0,0 +1,16 @@ +#include "SplitDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 288 +#define yc 96 + +IDD_SPLIT DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Split File" +BEGIN + LTEXT "&Split to:", IDT_SPLIT_PATH, m, m, xc, 8 + COMBOBOX IDC_SPLIT_PATH, m, 20, xc - bxsDots - m, 64, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_SPLIT_PATH, xs - m - bxsDots, 18, bxsDots, bys, WS_GROUP + LTEXT "Split to &volumes, bytes:", IDT_SPLIT_VOLUME, m, 44, xc, 8 + COMBOBOX IDC_SPLIT_VOLUME, m, 56, 96, 52, MY_COMBO_WITH_EDIT + OK_CANCEL +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialogRes.h 2011-04-26 08:54:06.000000000 +0000 @@ -1,8 +1,8 @@ -#define IDD_SPLIT 7300 - -#define IDT_SPLIT_PATH 7301 -#define IDT_SPLIT_VOLUME 7302 - -#define IDC_SPLIT_PATH 100 -#define IDB_SPLIT_PATH 101 -#define IDC_SPLIT_VOLUME 102 +#define IDD_SPLIT 7300 + +#define IDT_SPLIT_PATH 7301 +#define IDT_SPLIT_VOLUME 7302 + +#define IDC_SPLIT_PATH 100 +#define IDB_SPLIT_PATH 101 +#define IDC_SPLIT_VOLUME 102 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitDialog_rc.cpp 2015-01-02 20:23:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -// PasswordDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "SplitDialogRes.h" - -class CSplitDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CSplitDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent,int id) : CModalDialogImpl(dialog, parent, id, wxT("Split File")) - { - - wxArrayString pathArray; - - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - - topsizer->Add(new wxStaticText(this, IDT_SPLIT_PATH, _T("&Split to:")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - - - { - wxBoxSizer *pathSizer = new wxBoxSizer(wxHORIZONTAL); - - wxComboBox *combo = new wxComboBox(this, IDC_SPLIT_PATH, wxEmptyString, wxDefaultPosition, wxSize(600,-1), pathArray, wxCB_DROPDOWN|wxCB_SORT); - wxButton *button = new wxButton(this, IDB_SPLIT_PATH, wxT("..."), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - pathSizer->Add(combo, 1, wxLEFT|wxRIGHT|wxEXPAND, 5); - pathSizer->Add(button, 0, wxLEFT|wxRIGHT|wxEXPAND, 5); - - topsizer->Add(pathSizer, 0 ,wxALL | wxALIGN_LEFT, 5 ); - } - - topsizer->Add(new wxStaticText(this, IDT_SPLIT_VOLUME, _T("Split to &volumes, bytes:")) , 0 ,wxALL | wxALIGN_LEFT, 5 ); - - wxComboBox *combo = new wxComboBox(this, IDC_SPLIT_VOLUME, wxEmptyString, wxDefaultPosition, wxSize(600,-1), pathArray, wxCB_DROPDOWN|wxCB_SORT); - - topsizer->Add(combo, 0 ,wxALL | wxALIGN_LEFT, 5 ); - - - topsizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -static CStringTable g_stringTable[] = -{ - { 0 , 0 } -}; - - -REGISTER_DIALOG(IDD_SPLIT,CSplitDialog,g_stringTable) - -BEGIN_EVENT_TABLE(CSplitDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitUtils.cpp 2014-12-28 12:49:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -1,87 +1,96 @@ -// SplitUtils.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringToInt.h" - -#include "SplitUtils.h" - -bool ParseVolumeSizes(const UString &s, CRecordVector &values) -{ - values.Clear(); - bool prevIsNumber = false; - for (unsigned i = 0; i < s.Len();) - { - wchar_t c = s[i++]; - if (c == L' ') - continue; - if (c == L'-') - return true; - if (prevIsNumber) - { - prevIsNumber = false; - unsigned numBits = 0; - switch (MyCharLower_Ascii(c)) - { - case 'b': continue; - case 'k': numBits = 10; break; - case 'm': numBits = 20; break; - case 'g': numBits = 30; break; - case 't': numBits = 40; break; - } - if (numBits != 0) - { - UInt64 &val = values.Back(); - if (val >= ((UInt64)1 << (64 - numBits))) - return false; - val <<= numBits; - - for (; i < s.Len(); i++) - if (s[i] == L' ') - break; - continue; - } - } - i--; - const wchar_t *start = s.Ptr(i); - const wchar_t *end; - UInt64 val = ConvertStringToUInt64(start, &end); - if (start == end) - return false; - if (val == 0) - return false; - values.Add(val); - prevIsNumber = true; - i += (unsigned)(end - start); - } - return true; -} - -void AddVolumeItems(NWindows::NControl::CComboBox &combo) -{ - combo.AddString(TEXT("10M")); - combo.AddString(TEXT("650M - CD")); - combo.AddString(TEXT("700M - CD")); - combo.AddString(TEXT("4092M - FAT")); - combo.AddString(TEXT("4480M - DVD")); // 4489 MiB limit - combo.AddString(TEXT("8128M - DVD DL")); // 8147 MiB limit - combo.AddString(TEXT("23040M - BD")); // 23866 MiB limit - combo.AddString(TEXT("1457664 - 3.5\" floppy")); -} - -UInt64 GetNumberOfVolumes(UInt64 size, const CRecordVector &volSizes) -{ - if (size == 0 || volSizes.Size() == 0) - return 1; - FOR_VECTOR (i, volSizes) - { - UInt64 volSize = volSizes[i]; - if (volSize >= size) - return i + 1; - size -= volSize; - } - UInt64 volSize = volSizes.Back(); - if (volSize == 0) - return (UInt64)(Int64)-1; - return volSizes.Size() + (size - 1) / volSize + 1; -} +// SplitUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringToInt.h" + +#include "SplitUtils.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values) +{ + values.Clear(); + bool prevIsNumber = false; + for (unsigned i = 0; i < s.Len();) + { + wchar_t c = s[i++]; + if (c == L' ') + continue; + if (c == L'-') + return true; + if (prevIsNumber) + { + prevIsNumber = false; + unsigned numBits = 0; + switch (MyCharLower_Ascii(c)) + { + case 'b': continue; + case 'k': numBits = 10; break; + case 'm': numBits = 20; break; + case 'g': numBits = 30; break; + case 't': numBits = 40; break; + } + if (numBits != 0) + { + UInt64 &val = values.Back(); + if (val >= ((UInt64)1 << (64 - numBits))) + return false; + val <<= numBits; + + for (; i < s.Len(); i++) + if (s[i] == L' ') + break; + continue; + } + } + i--; + const wchar_t *start = s.Ptr(i); + const wchar_t *end; + UInt64 val = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + if (val == 0) + return false; + values.Add(val); + prevIsNumber = true; + i += (unsigned)(end - start); + } + return true; +} + + +static const char * const k_Sizes[] = +{ + "10M" + , "100M" + , "1000M" + , "650M - CD" + , "700M - CD" + , "4092M - FAT" + , "4480M - DVD" // 4489 MiB limit + , "8128M - DVD DL" // 8147 MiB limit + , "23040M - BD" // 23866 MiB limit + // , "1457664 - 3.5\" floppy" +}; + +void AddVolumeItems(NWindows::NControl::CComboBox &combo) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_Sizes); i++) + combo.AddString(CSysString(k_Sizes[i])); +} + +UInt64 GetNumberOfVolumes(UInt64 size, const CRecordVector &volSizes) +{ + if (size == 0 || volSizes.Size() == 0) + return 1; + FOR_VECTOR (i, volSizes) + { + UInt64 volSize = volSizes[i]; + if (volSize >= size) + return i + 1; + size -= volSize; + } + UInt64 volSize = volSizes.Back(); + if (volSize == 0) + return (UInt64)(Int64)-1; + return volSizes.Size() + (size - 1) / volSize + 1; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SplitUtils.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SplitUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,15 +1,15 @@ -// SplitUtils.h - -#ifndef __SPLIT_UTILS_H -#define __SPLIT_UTILS_H - -#include "../../../Common/MyTypes.h" -#include "../../../Common/MyString.h" - -#include "../../../Windows/Control/ComboBox.h" - -bool ParseVolumeSizes(const UString &s, CRecordVector &values); -void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo); -UInt64 GetNumberOfVolumes(UInt64 size, const CRecordVector &volSizes); - -#endif +// SplitUtils.h + +#ifndef ZIP7_INC_SPLIT_UTILS_H +#define ZIP7_INC_SPLIT_UTILS_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +#include "../../../Windows/Control/ComboBox.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values); +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo); +UInt64 GetNumberOfVolumes(UInt64 size, const CRecordVector &volSizes); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.cpp 2006-10-11 10:05:07.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StdAfx.h 2024-01-27 09:00:00.000000000 +0000 @@ -0,0 +1,67 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#include "../../../Common/Common.h" + +#endif + +/* +WINVER and _WIN32_WINNT + +MSVC6 / 2003sdk: +{ + doesn't set _WIN32_WINNT + if WINVER is not set sets WINVER to value: + 0x0400 : MSVC6 + 0x0501 : Windows Server 2003 PSDK / 2003 R2 PSDK +} + +SDK for Win7 (and later) +{ + sets _WIN32_WINNT if it's not set. + sets WINVER if it's not set. + includes that does: +#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_) + #define _WIN32_WINNT 0x0601 // in win7 sdk + #define _WIN32_WINNT 0x0A00 // in win10 sdk +#endif +#ifndef WINVER + #ifdef _WIN32_WINNT + #define WINVER _WIN32_WINNT + else + #define WINVER 0x0601 // in win7 sdk + #define WINVER 0x0A00 // in win10 sdk + endif +#endif +} + +Some GUI structures defined by windows will be larger, +If (_WIN32_WINNT) value is larger. + +Also if we send sizeof(win_gui_struct) to some windows function, +and we compile that code with big (_WIN32_WINNT) value, +the window function in old Windows can fail, if that old Windows +doesn't understand new big version of (win_gui_struct) compiled +with big (_WIN32_WINNT) value. + +So it's better to define smallest (_WIN32_WINNT) value here. +In 7-Zip FM we use some functions that require (_WIN32_WINNT == 0x0500). +So it's simpler to define (_WIN32_WINNT == 0x0500) here. +If we define (_WIN32_WINNT == 0x0400) here, we need some manual +declarations for functions and macros that require (0x0500) functions. +Also libs must contain these (0x0500+) functions. + +Some code in 7-zip FM uses also CommCtrl.h structures +that depend from (_WIN32_IE) value. But default +(_WIN32_IE) value from probably is OK for us. +So we don't set _WIN32_IE here. +default _WIN32_IE value set by : + 0x501 2003sdk + 0xa00 win10 sdk +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/StringUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/StringUtils.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.cpp 2023-03-20 10:00:00.000000000 +0000 @@ -1,70 +1,39 @@ -// StringUtils.cpp - -#include "StdAfx.h" - -#include "StringUtils.h" - -void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) -{ - dest1.Empty(); - dest2.Empty(); - bool quoteMode = false; - unsigned i; - for (i = 0; i < src.Len(); i++) - { - wchar_t c = src[i]; - if (c == L'\"') - quoteMode = !quoteMode; - else if (c == L' ' && !quoteMode) - { - if (!quoteMode) - { - i++; - break; - } - } - else - dest1 += c; - } - dest2 = src.Ptr(i); -} - -void SplitString(const UString &srcString, UStringVector &destStrings) -{ - destStrings.Clear(); - unsigned len = srcString.Len(); - if (len == 0) - return; - UString s; - for (unsigned i = 0; i < len; i++) - { - wchar_t c = srcString[i]; - if (c == L' ') - { - if (!s.IsEmpty()) - { - destStrings.Add(s); - s.Empty(); - } - } - else - s += c; - } - if (!s.IsEmpty()) - destStrings.Add(s); -} - -/* -UString JoinStrings(const UStringVector &srcStrings) -{ - - UString s; - FOR_VECTOR (i, srcStrings) - { - if (i != 0) - s.Add_Space(); - s += srcStrings[i]; - } - return s; -} -*/ +// StringUtils.cpp + +#include "StdAfx.h" + +#include "StringUtils.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) +{ + dest1.Empty(); + dest2.Empty(); + bool quoteMode = false; + for (unsigned i = 0; i < src.Len(); i++) + { + const wchar_t c = src[i]; + if (c == '\"') + quoteMode = !quoteMode; + else if (c == ' ' && !quoteMode) + { + dest2 = src.Ptr(i + 1); + return; + } + else + dest1 += c; + } +} + +/* +UString JoinStrings(const UStringVector &srcStrings) +{ + UString s; + FOR_VECTOR (i, srcStrings) + { + if (i != 0) + s.Add_Space(); + s += srcStrings[i]; + } + return s; +} +*/ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/StringUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/StringUtils.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/StringUtils.h 2023-01-30 09:00:00.000000000 +0000 @@ -1,13 +1,11 @@ -// StringUtils.h - -#ifndef __STRING_UTILS_H -#define __STRING_UTILS_H - -#include "../../../Common/MyString.h" - -void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2); - -void SplitString(const UString &srcString, UStringVector &destStrings); -UString JoinStrings(const UStringVector &srcStrings); - -#endif +// StringUtils.h + +#ifndef ZIP7_INC_STRING_UTILS_H +#define ZIP7_INC_STRING_UTILS_H + +#include "../../../Common/MyString.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2); +// UString JoinStrings(const UStringVector &srcStrings); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SysIconUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SysIconUtils.cpp 2015-06-22 21:29:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.cpp 2024-10-14 09:00:00.000000000 +0000 @@ -1,268 +1,351 @@ -// SysIconUtils.cpp - -#include "StdAfx.h" - -#ifndef _UNICODE -#include "../../../Common/StringConvert.h" -#endif - -#include "../../../Windows/FileDir.h" - -#include "SysIconUtils.h" - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -#ifdef _WIN32 -int GetIconIndexForCSIDL(int csidl) -{ - LPITEMIDLIST pidl = 0; - SHGetSpecialFolderLocation(NULL, csidl, &pidl); - if (pidl) - { - SHFILEINFO shellInfo; - SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL, - &shellInfo, sizeof(shellInfo), - SHGFI_PIDL | SHGFI_SYSICONINDEX); - IMalloc *pMalloc; - SHGetMalloc(&pMalloc); - if (pMalloc) - { - pMalloc->Free(pidl); - pMalloc->Release(); - } - return shellInfo.iIcon; - } - return 0; -} - -#ifndef _UNICODE -typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); - -struct CSHGetFileInfoInit -{ - SHGetFileInfoWP shGetFileInfoW; - CSHGetFileInfoInit() - { - shGetFileInfoW = (SHGetFileInfoWP) - ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); - } -} g_SHGetFileInfoInit; -#endif - -static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) -{ - #ifdef _UNICODE - return SHGetFileInfo - #else - if (g_SHGetFileInfoInit.shGetFileInfoW == 0) - return 0; - return g_SHGetFileInfoInit.shGetFileInfoW - #endif - (pszPath, attrib, psfi, cbFileInfo, uFlags); -} - -DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex) -{ - #ifndef _UNICODE - if (!g_IsNT) - { - SHFILEINFO shellInfo; - DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, - sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); - iconIndex = shellInfo.iIcon; - return res; - } - else - #endif - { - SHFILEINFOW shellInfo; - DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, - sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); - iconIndex = shellInfo.iIcon; - return res; - } -} - -/* -DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex, UString *typeName) -{ - #ifndef _UNICODE - if (!g_IsNT) - { - SHFILEINFO shellInfo; - shellInfo.szTypeName[0] = 0; - DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, - sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); - if (typeName) - *typeName = GetUnicodeString(shellInfo.szTypeName); - iconIndex = shellInfo.iIcon; - return res; - } - else - #endif - { - SHFILEINFOW shellInfo; - shellInfo.szTypeName[0] = 0; - DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, - sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); - if (typeName) - *typeName = shellInfo.szTypeName; - iconIndex = shellInfo.iIcon; - return res; - } -} -*/ - -static int FindInSorted_Attrib(const CRecordVector &vect, DWORD attrib, int &insertPos) -{ - unsigned left = 0, right = vect.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - DWORD midAttrib = vect[mid].Attrib; - if (attrib == midAttrib) - return mid; - if (attrib < midAttrib) - right = mid; - else - left = mid + 1; - } - insertPos = left; - return -1; -} - -static int FindInSorted_Ext(const CObjectVector &vect, const wchar_t *ext, int &insertPos) -{ - unsigned left = 0, right = vect.Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - int compare = MyStringCompareNoCase(ext, vect[mid].Ext); - if (compare == 0) - return mid; - if (compare < 0) - right = mid; - else - left = mid + 1; - } - insertPos = left; - return -1; -} - -int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */) -{ - int dotPos = -1; - unsigned i; - for (i = 0;; i++) - { - wchar_t c = fileName[i]; - if (c == 0) - break; - if (c == '.') - dotPos = i; - } - - /* - if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0) - { - char s[256]; - sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib); - OutputDebugStringA(s); - OutputDebugStringW(fileName); - } - */ - - if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0) - { - int insertPos = 0; - int index = FindInSorted_Attrib(_attribMap, attrib, insertPos); - if (index >= 0) - { - // if (typeName) *typeName = _attribMap[index].TypeName; - return _attribMap[index].IconIndex; - } - CAttribIconPair pair; - GetRealIconIndex( - #ifdef UNDER_CE - FTEXT("\\") - #endif - FTEXT("__DIR__") - , attrib, pair.IconIndex - // , pair.TypeName - ); - - /* - char s[256]; - sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib); - OutputDebugStringA(s); - */ - - pair.Attrib = attrib; - _attribMap.Insert(insertPos, pair); - // if (typeName) *typeName = pair.TypeName; - return pair.IconIndex; - } - - const wchar_t *ext = fileName + dotPos + 1; - int insertPos = 0; - int index = FindInSorted_Ext(_extMap, ext, insertPos); - if (index >= 0) - { - const CExtIconPair &pa = _extMap[index]; - // if (typeName) *typeName = pa.TypeName; - return pa.IconIndex; - } - - for (i = 0;; i++) - { - wchar_t c = ext[i]; - if (c == 0) - break; - if (c < L'0' || c > L'9') - break; - } - if (i != 0 && ext[i] == 0) - { - // GetRealIconIndex is too slow for big number of split extensions: .001, .002, .003 - if (!SplitIconIndex_Defined) - { - GetRealIconIndex( - #ifdef UNDER_CE - FTEXT("\\") - #endif - FTEXT("__FILE__.001"), 0, SplitIconIndex); - SplitIconIndex_Defined = true; - } - return SplitIconIndex; - } - - CExtIconPair pair; - pair.Ext = ext; - GetRealIconIndex(us2fs(fileName + dotPos), attrib, pair.IconIndex); - _extMap.Insert(insertPos, pair); - // if (typeName) *typeName = pair.TypeName; - return pair.IconIndex; -} - -/* -int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName) -{ - return GetIconIndex(attrib, fileName, NULL); -} -*/ - -#endif - -DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex) -{ - iconIndex = 0; // FIXME - return 0; -} - -int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */) -{ - return 0; -} - +// SysIconUtils.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../../../Common/StringConvert.h" +#endif + +#include "../../../Windows/FileDir.h" + +#include "SysIconUtils.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +CExtToIconMap g_Ext_to_Icon_Map; + +int Shell_GetFileInfo_SysIconIndex_for_CSIDL(int csidl) +{ + LPITEMIDLIST pidl = NULL; + SHGetSpecialFolderLocation(NULL, csidl, &pidl); + if (pidl) + { + SHFILEINFO shFileInfo; + shFileInfo.iIcon = -1; + const DWORD_PTR res = SHGetFileInfo((LPCTSTR)(const void *)(pidl), + FILE_ATTRIBUTE_DIRECTORY, + &shFileInfo, sizeof(shFileInfo), + SHGFI_PIDL | SHGFI_SYSICONINDEX); + /* + IMalloc *pMalloc; + SHGetMalloc(&pMalloc); + if (pMalloc) + { + pMalloc->Free(pidl); + pMalloc->Release(); + } + */ + // we use OLE2.dll function here + CoTaskMemFree(pidl); + if (res) + return shFileInfo.iIcon; + } + return -1; +} + +#ifndef _UNICODE +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +typedef DWORD_PTR (WINAPI * Func_SHGetFileInfoW)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); + +static struct C_SHGetFileInfo_Init +{ + Func_SHGetFileInfoW f_SHGetFileInfoW; + C_SHGetFileInfo_Init() + { + f_SHGetFileInfoW = Z7_GET_PROC_ADDRESS( + Func_SHGetFileInfoW, ::GetModuleHandleW(L"shell32.dll"), + "SHGetFileInfoW"); + // f_SHGetFileInfoW = NULL; // for debug + } +} g_SHGetFileInfo_Init; +#endif + +#ifdef _UNICODE +#define My_SHGetFileInfoW SHGetFileInfoW +#else +static DWORD_PTR My_SHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) +{ + if (!g_SHGetFileInfo_Init.f_SHGetFileInfoW) + return 0; + return g_SHGetFileInfo_Init.f_SHGetFileInfoW(pszPath, attrib, psfi, cbFileInfo, uFlags); +} +#endif + +DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( + CFSTR path, DWORD attrib, int &iconIndex) +{ +#ifndef _UNICODE + if (!g_IsNT || !g_SHGetFileInfo_Init.f_SHGetFileInfoW) + { + SHFILEINFO shFileInfo; + // ZeroMemory(&shFileInfo, sizeof(shFileInfo)); + shFileInfo.iIcon = -1; // optional + const DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), + attrib ? attrib : FILE_ATTRIBUTE_ARCHIVE, + &shFileInfo, sizeof(shFileInfo), + SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shFileInfo.iIcon; + return res; + } + else +#endif + { + SHFILEINFOW shFileInfo; + // ZeroMemory(&shFileInfo, sizeof(shFileInfo)); + shFileInfo.iIcon = -1; // optional + const DWORD_PTR res = ::My_SHGetFileInfoW(fs2us(path), + attrib ? attrib : FILE_ATTRIBUTE_ARCHIVE, + &shFileInfo, sizeof(shFileInfo), + SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + // (shFileInfo.iIcon == 0) returned for unknown extensions and files without extension + iconIndex = shFileInfo.iIcon; + // we use SHGFI_USEFILEATTRIBUTES, and + // (res != 0) is expected for main cases, even if there are no such file. + // (res == 0) for path with kSuperPrefix "\\?\" + // Also SHGFI_USEFILEATTRIBUTES still returns icon inside exe. + // So we can use SHGFI_USEFILEATTRIBUTES for any case. + // UString temp = fs2us(path); // for debug + // UString tempName = temp.Ptr(temp.ReverseFind_PathSepar() + 1); // for debug + // iconIndex = -1; // for debug + return res; + } +} + +int Shell_GetFileInfo_SysIconIndex_for_Path(CFSTR path, DWORD attrib) +{ + int iconIndex = -1; + if (!Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( + path, attrib, iconIndex)) + iconIndex = -1; + return iconIndex; +} + + +HRESULT Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + CFSTR path, DWORD attrib, Int32 *iconIndex) +{ + *iconIndex = -1; + int iconIndexTemp; + if (Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( + path, attrib, iconIndexTemp)) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError_noZero_HRESULT(); +} + +/* +DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path(const UString &fileName, DWORD attrib, int &iconIndex, UString *typeName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + SHFILEINFO shFileInfo; + shFileInfo.szTypeName[0] = 0; + DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_ARCHIVE | attrib, &shFileInfo, + sizeof(shFileInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); + if (typeName) + *typeName = GetUnicodeString(shFileInfo.szTypeName); + iconIndex = shFileInfo.iIcon; + return res; + } + else + #endif + { + SHFILEINFOW shFileInfo; + shFileInfo.szTypeName[0] = 0; + DWORD_PTR res = ::My_SHGetFileInfoW(fileName, FILE_ATTRIBUTE_ARCHIVE | attrib, &shFileInfo, + sizeof(shFileInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); + if (typeName) + *typeName = shFileInfo.szTypeName; + iconIndex = shFileInfo.iIcon; + return res; + } +} +*/ + +static int FindInSorted_Attrib(const CRecordVector &vect, DWORD attrib, unsigned &insertPos) +{ + unsigned left = 0, right = vect.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const DWORD midAttrib = vect[mid].Attrib; + if (attrib == midAttrib) + return (int)mid; + if (attrib < midAttrib) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +static int FindInSorted_Ext(const CObjectVector &vect, const wchar_t *ext, unsigned &insertPos) +{ + unsigned left = 0, right = vect.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const int compare = MyStringCompareNoCase(ext, vect[mid].Ext); + if (compare == 0) + return (int)mid; + if (compare < 0) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + + +// bool DoItemAlwaysStart(const UString &name); + +int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */) +{ + int dotPos = -1; + unsigned i; + for (i = 0;; i++) + { + const wchar_t c = fileName[i]; + if (c == 0) + break; + if (c == '.') + dotPos = (int)i; + // we don't need IS_PATH_SEPAR check, because (fileName) doesn't include path prefix. + // if (IS_PATH_SEPAR(c) || c == ':') dotPos = -1; + } + + /* + if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0) + { + char s[256]; + sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib); + OutputDebugStringA(s); + OutputDebugStringW(fileName); + } + */ + + if ((attrib & FILE_ATTRIBUTE_DIRECTORY) || dotPos < 0) + for (unsigned k = 0;; k++) + { + if (k >= 2) + return -1; + unsigned insertPos = 0; + const int index = FindInSorted_Attrib(_attribMap, attrib, insertPos); + if (index >= 0) + { + // if (typeName) *typeName = _attribMap[index].TypeName; + return _attribMap[(unsigned)index].IconIndex; + } + CAttribIconPair pair; + pair.IconIndex = Shell_GetFileInfo_SysIconIndex_for_Path( + #ifdef UNDER_CE + FTEXT("\\") + #endif + FTEXT("__DIR__") + , attrib + // , pair.TypeName + ); + if (_attribMap.Size() < (1u << 16) // we limit cache size + || attrib < (1u << 15)) // we want to put all items with basic attribs to cache + { + /* + char s[256]; + sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib); + OutputDebugStringA(s); + */ + pair.Attrib = attrib; + _attribMap.Insert(insertPos, pair); + // if (typeName) *typeName = pair.TypeName; + return pair.IconIndex; + } + if (pair.IconIndex >= 0) + return pair.IconIndex; + attrib = (attrib & FILE_ATTRIBUTE_DIRECTORY) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + } + + CObjectVector &map = + (attrib & FILE_ATTRIBUTE_COMPRESSED) ? + _extMap_Compressed : _extMap_Normal; + const wchar_t *ext = fileName + dotPos + 1; + unsigned insertPos = 0; + const int index = FindInSorted_Ext(map, ext, insertPos); + if (index >= 0) + { + const CExtIconPair &pa = map[index]; + // if (typeName) *typeName = pa.TypeName; + return pa.IconIndex; + } + + for (i = 0;; i++) + { + const wchar_t c = ext[i]; + if (c == 0) + break; + if (c < L'0' || c > L'9') + break; + } + if (i != 0 && ext[i] == 0) + { + // Shell_GetFileInfo_SysIconIndex_for_Path is too slow for big number of split extensions: .001, .002, .003 + if (!SplitIconIndex_Defined) + { + Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( + #ifdef UNDER_CE + FTEXT("\\") + #endif + FTEXT("__FILE__.001"), FILE_ATTRIBUTE_ARCHIVE, SplitIconIndex); + SplitIconIndex_Defined = true; + } + return SplitIconIndex; + } + + CExtIconPair pair; + pair.Ext = ext; + pair.IconIndex = Shell_GetFileInfo_SysIconIndex_for_Path( + us2fs(fileName + dotPos), + attrib & FILE_ATTRIBUTE_COMPRESSED ? + FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED: + FILE_ATTRIBUTE_ARCHIVE); + if (map.Size() < (1u << 16) // we limit cache size + // || DoItemAlwaysStart(fileName + dotPos) // we want some popular extensions in cache + ) + map.Insert(insertPos, pair); + // if (typeName) *typeName = pair.TypeName; + return pair.IconIndex; +} + + +HIMAGELIST Shell_Get_SysImageList_smallIcons(bool smallIcons) +{ + SHFILEINFO shFileInfo; + // shFileInfo.hIcon = NULL; // optional + const DWORD_PTR res = SHGetFileInfo(TEXT(""), + /* FILE_ATTRIBUTE_ARCHIVE | */ + FILE_ATTRIBUTE_DIRECTORY, + &shFileInfo, sizeof(shFileInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + (smallIcons ? SHGFI_SMALLICON : SHGFI_LARGEICON)); +#if 0 + // (shFileInfo.hIcon == NULL), because we don't use SHGFI_ICON. + // so DestroyIcon() is not required + if (res && shFileInfo.hIcon) // unexpected + DestroyIcon(shFileInfo.hIcon); +#endif + return (HIMAGELIST)res; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SysIconUtils.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SysIconUtils.h 2015-06-21 18:44:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SysIconUtils.h 2024-07-09 11:00:00.000000000 +0000 @@ -1,60 +1,65 @@ -// SysIconUtils.h - -#ifndef __SYS_ICON_UTILS_H -#define __SYS_ICON_UTILS_H - -#include "Common/MyString.h" - -struct CExtIconPair -{ - UString Ext; - int IconIndex; - // UString TypeName; - - // int Compare(const CExtIconPair &a) const { return MyStringCompareNoCase(Ext, a.Ext); } -}; - -struct CAttribIconPair -{ - DWORD Attrib; - int IconIndex; - // UString TypeName; - - // int Compare(const CAttribIconPair &a) const { return Ext.Compare(a.Ext); } -}; - -class CExtToIconMap -{ -public: - CRecordVector _attribMap; - CObjectVector _extMap; - int SplitIconIndex; - int SplitIconIndex_Defined; - - CExtToIconMap(): SplitIconIndex_Defined(false) {} - - void Clear() - { - SplitIconIndex_Defined = false; - _extMap.Clear(); - _attribMap.Clear(); - } - int GetIconIndex(DWORD attrib, const wchar_t *fileName /* , UString *typeName */); - // int GetIconIndex(DWORD attrib, const UString &fileName); -}; - -DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex); -int GetIconIndexForCSIDL(int csidl); - -#ifdef WIN32 -inline HIMAGELIST GetSysImageList(bool smallIcons) -{ - SHFILEINFO shellInfo; - return (HIMAGELIST)SHGetFileInfo(TEXT(""), - FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY, - &shellInfo, sizeof(shellInfo), - SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON)); -} -#endif - -#endif +// SysIconUtils.h + +#ifndef ZIP7_INC_SYS_ICON_UTILS_H +#define ZIP7_INC_SYS_ICON_UTILS_H + +#include "../../../Common/MyWindows.h" + +#include + +#include "../../../Common/MyString.h" + +struct CExtIconPair +{ + UString Ext; + int IconIndex; + // UString TypeName; + // int Compare(const CExtIconPair &a) const { return MyStringCompareNoCase(Ext, a.Ext); } +}; + +struct CAttribIconPair +{ + DWORD Attrib; + int IconIndex; + // UString TypeName; + // int Compare(const CAttribIconPair &a) const { return Ext.Compare(a.Ext); } +}; + + +struct CExtToIconMap +{ + CRecordVector _attribMap; + CObjectVector _extMap_Normal; + CObjectVector _extMap_Compressed; + int SplitIconIndex; + int SplitIconIndex_Defined; + + CExtToIconMap(): SplitIconIndex_Defined(false) {} + + void Clear() + { + SplitIconIndex_Defined = false; + _extMap_Normal.Clear(); + _extMap_Compressed.Clear(); + _attribMap.Clear(); + } + int GetIconIndex_DIR(DWORD attrib = FILE_ATTRIBUTE_DIRECTORY) + { + return GetIconIndex(attrib, L"__DIR__"); + } + int GetIconIndex(DWORD attrib, const wchar_t *fileName /* , UString *typeName */); +}; + +extern CExtToIconMap g_Ext_to_Icon_Map; + +DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( + CFSTR path, DWORD attrib, int &iconIndex); +HRESULT Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT( + CFSTR path, DWORD attrib, Int32 *iconIndex); +int Shell_GetFileInfo_SysIconIndex_for_Path(CFSTR path, DWORD attrib); + +int Shell_GetFileInfo_SysIconIndex_for_CSIDL(int csidl); + +HIMAGELIST Shell_Get_SysImageList_smallIcons(bool smallIcons); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.cpp 2024-03-16 06:00:00.000000000 +0000 @@ -0,0 +1,472 @@ +// SystemPage.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../Common/Defs.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/ErrorMsg.h" + +#include "HelpUtils.h" +#include "IFolder.h" +#include "LangUtils.h" +#include "PropertyNameRes.h" +#include "SystemPage.h" +#include "SystemPageRes.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_SYSTEM_ASSOCIATE +}; +#endif + +#define kSystemTopic "FM/options.htm#system" + +CSysString CModifiedExtInfo::GetString() const +{ + const char *s; + if (State == kExtState_7Zip) + s = "7-Zip"; + else if (State == kExtState_Clear) + s = ""; + else if (Other7Zip) + s = "[7-Zip]"; + else + return ProgramKey; + return CSysString (s); +} + + +int CSystemPage::AddIcon(const UString &iconPath, int iconIndex) +{ + if (iconPath.IsEmpty()) + return -1; + if (iconIndex == -1) + iconIndex = 0; + + HICON hicon; + + #ifdef UNDER_CE + ExtractIconExW(iconPath, iconIndex, NULL, &hicon, 1); + if (!hicon) + #else + // we expand path from REG_EXPAND_SZ registry item. + UString path; + const DWORD size = MAX_PATH + 10; + const DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuf(size + 2), size); + path.ReleaseBuf_CalcLen(size); + if (needLen == 0 || needLen >= size) + path = iconPath; + const UINT num = ExtractIconExW(path, iconIndex, NULL, &hicon, 1); + if (num != 1 || !hicon) + #endif + return -1; + + _imageList.AddIcon(hicon); + DestroyIcon(hicon); + return (int)(_numIcons++); +} + + +void CSystemPage::RefreshListItem(unsigned group, unsigned listIndex) +{ + const CAssoc &assoc = _items[GetRealIndex(listIndex)]; + _listView.SetSubItem(listIndex, group + 1, assoc.Pair[group].GetString()); + LVITEMW newItem; + memset(&newItem, 0, sizeof(newItem)); + newItem.iItem = (int)listIndex; + newItem.mask = LVIF_IMAGE; + newItem.iImage = assoc.GetIconIndex(); + _listView.SetItem(&newItem); +} + + +void CSystemPage::ChangeState(unsigned group, const CUIntVector &indices) +{ + if (indices.IsEmpty()) + return; + + bool thereAreClearItems = false; + unsigned counters[3] = { 0, 0, 0 }; + + unsigned i; + for (i = 0; i < indices.Size(); i++) + { + const CModifiedExtInfo &mi = _items[GetRealIndex(indices[i])].Pair[group]; + int state = kExtState_7Zip; + if (mi.State == kExtState_7Zip) + state = kExtState_Clear; + else if (mi.State == kExtState_Clear) + { + thereAreClearItems = true; + if (mi.Other) + state = kExtState_Other; + } + counters[state]++; + } + + int state = kExtState_Clear; + if (counters[kExtState_Other] != 0) + state = kExtState_Other; + else if (counters[kExtState_7Zip] != 0) + state = kExtState_7Zip; + + for (i = 0; i < indices.Size(); i++) + { + unsigned listIndex = indices[i]; + CAssoc &assoc = _items[GetRealIndex(listIndex)]; + CModifiedExtInfo &mi = assoc.Pair[group]; + bool change = false; + + switch (state) + { + case kExtState_Clear: change = true; break; + case kExtState_Other: change = mi.Other; break; + default: change = !(mi.Other && thereAreClearItems); break; + } + + if (change) + { + mi.State = state; + RefreshListItem(group, listIndex); + } + } + + _needSave = true; + Changed(); +} + + +bool CSystemPage::OnInit() +{ + _needSave = false; + +#ifdef Z7_LANG + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); +#endif + + _listView.Attach(GetItem(IDL_SYSTEM_ASSOCIATE)); + _listView.SetUnicodeFormat(); + DWORD newFlags = LVS_EX_FULLROWSELECT; + _listView.SetExtendedListViewStyle(newFlags, newFlags); + + _numIcons = 0; + _imageList.Create(16, 16, ILC_MASK | ILC_COLOR32, 0, 0); + + _listView.SetImageList(_imageList, LVSIL_SMALL); + + _listView.InsertColumn(0, LangString(IDS_PROP_FILE_TYPE), 80); + + UString s; + + #if NUM_EXT_GROUPS == 1 + s = "Program"; + #else + #ifndef UNDER_CE + const unsigned kSize = 256; + BOOL res; + + DWORD size = kSize; + + #ifndef _UNICODE + if (!g_IsNT) + { + AString s2; + res = GetUserNameA(s2.GetBuf(size), &size); + s2.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize)); + s = GetUnicodeString(s2); + } + else + #endif + { + res = GetUserNameW(s.GetBuf(size), &size); + s.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize)); + } + + if (!res) + #endif + s = "Current User"; + #endif + + LV_COLUMNW ci; + ci.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; + ci.cx = 152; + ci.fmt = LVCFMT_CENTER; + ci.pszText = s.Ptr_non_const(); + ci.iSubItem = 1; + _listView.InsertColumn(1, &ci); + + #if NUM_EXT_GROUPS > 1 + { + LangString(IDS_SYSTEM_ALL_USERS, s); + ci.pszText = s.Ptr_non_const(); + ci.iSubItem = 2; + _listView.InsertColumn(2, &ci); + } + #endif + + _extDB.Read(); + _items.Clear(); + + FOR_VECTOR (i, _extDB.Exts) + { + const CExtPlugins &extInfo = _extDB.Exts[i]; + + LVITEMW item; + item.iItem = (int)i; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + item.lParam = (LPARAM)i; + item.iSubItem = 0; + // ListView always uses internal iImage that is 0 by default? + // so we always use LVIF_IMAGE. + item.iImage = -1; + item.pszText = extInfo.Ext.Ptr_non_const(); + + CAssoc assoc; + const CPluginToIcon &plug = extInfo.Plugins[0]; + assoc.SevenZipImageIndex = AddIcon(plug.IconPath, plug.IconIndex); + + CSysString texts[NUM_EXT_GROUPS]; + unsigned g; + for (g = 0; g < NUM_EXT_GROUPS; g++) + { + CModifiedExtInfo &mi = assoc.Pair[g]; + mi.ReadFromRegistry(GetHKey(g), GetSystemString(extInfo.Ext)); + mi.SetState(plug.IconPath); + mi.ImageIndex = AddIcon(mi.IconPath, mi.IconIndex); + texts[g] = mi.GetString(); + } + item.iImage = assoc.GetIconIndex(); + const int itemIndex = _listView.InsertItem(&item); + for (g = 0; g < NUM_EXT_GROUPS; g++) + _listView.SetSubItem((unsigned)itemIndex, 1 + g, texts[g]); + _items.Add(assoc); + } + + if (_listView.GetItemCount() > 0) + _listView.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED); + + return CPropertyPage::OnInit(); +} + + +static UString GetProgramCommand() +{ + UString s ('\"'); + s += fs2us(NDLL::GetModuleDirPrefix()); + s += "7zFM.exe\" \"%1\""; + return s; +} + + +LONG CSystemPage::OnApply() +{ + if (!_needSave) + return PSNRET_NOERROR; + + const UString command = GetProgramCommand(); + + LONG res = 0; + + FOR_VECTOR (listIndex, _extDB.Exts) + { + unsigned realIndex = GetRealIndex(listIndex); + const CExtPlugins &extInfo = _extDB.Exts[realIndex]; + CAssoc &assoc = _items[realIndex]; + + for (unsigned g = 0; g < NUM_EXT_GROUPS; g++) + { + CModifiedExtInfo &mi = assoc.Pair[g]; + HKEY key = GetHKey(g); + + if (mi.OldState != mi.State) + { + LONG res2 = 0; + + if (mi.State == kExtState_7Zip) + { + UString title = extInfo.Ext; + title += " Archive"; + const CPluginToIcon &plug = extInfo.Plugins[0]; + res2 = NRegistryAssoc::AddShellExtensionInfo(key, GetSystemString(extInfo.Ext), + title, command, plug.IconPath, plug.IconIndex); + } + else if (mi.State == kExtState_Clear) + res2 = NRegistryAssoc::DeleteShellExtensionInfo(key, GetSystemString(extInfo.Ext)); + + if (res == 0) + res = res2; + if (res2 == 0) + mi.OldState = mi.State; + + mi.State = mi.OldState; + RefreshListItem(g, listIndex); + } + } + } + + #ifndef UNDER_CE + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + #endif + + WasChanged = true; + + _needSave = false; + + if (res != 0) + MessageBoxW(*this, NError::MyFormatMessage(res), L"7-Zip", MB_ICONERROR); + + return PSNRET_NOERROR; +} + + +void CSystemPage::OnNotifyHelp() +{ + ShowHelpWindow(kSystemTopic); +} + + +bool CSystemPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + /* + case IDC_SYSTEM_SELECT_ALL: + _listView.SelectAll(); + return true; + */ + case IDB_SYSTEM_CURRENT: + case IDB_SYSTEM_ALL: + ChangeState(buttonID == IDB_SYSTEM_CURRENT ? 0 : 1); + return true; + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} + + +bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(_listView)) + { + switch (lParam->code) + { + case NM_RETURN: + { + ChangeState(0); + return true; + } + + case NM_CLICK: + { + #ifdef UNDER_CE + NMLISTVIEW *item = (NMLISTVIEW *)lParam; + #else + NMITEMACTIVATE *item = (NMITEMACTIVATE *)lParam; + if (item->uKeyFlags == 0) + #endif + { + if (item->iItem >= 0) + { + // unsigned realIndex = GetRealIndex(item->iItem); + if (item->iSubItem >= 1 && item->iSubItem <= 2) + { + CUIntVector indices; + indices.Add((unsigned)item->iItem); + ChangeState(item->iSubItem < 2 ? 0 : 1, indices); + } + } + } + break; + } + + case LVN_KEYDOWN: + { + if (OnListKeyDown(LPNMLVKEYDOWN(lParam))) + return true; + break; + } + + /* + case NM_RCLICK: + case NM_DBLCLK: + case LVN_BEGINRDRAG: + // PostMessage(kRefreshpluginsListMessage, 0); + PostMessage(kUpdateDatabase, 0); + break; + */ + } + } + return CPropertyPage::OnNotify(controlID, lParam); +} + + +void CSystemPage::ChangeState(unsigned group) +{ + CUIntVector indices; + + int itemIndex = -1; + while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1) + indices.Add((unsigned)itemIndex); + + if (indices.IsEmpty()) + FOR_VECTOR (i, _items) + indices.Add(i); + + ChangeState(group, indices); +} + + +bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + bool ctrl = IsKeyDown(VK_CONTROL); + bool alt = IsKeyDown(VK_MENU); + + if (alt) + return false; + + if ((ctrl && keyDownInfo->wVKey == 'A') + || (!ctrl && keyDownInfo->wVKey == VK_MULTIPLY)) + { + _listView.SelectAll(); + return true; + } + + switch (keyDownInfo->wVKey) + { + case VK_SPACE: + case VK_ADD: + case VK_SUBTRACT: + case VK_SEPARATOR: + case VK_DIVIDE: + + #ifndef UNDER_CE + case VK_OEM_PLUS: + case VK_OEM_MINUS: + #endif + + if (!ctrl) + { + ChangeState(keyDownInfo->wVKey == VK_SPACE ? 0 : 1); + return true; + } + break; + } + + return false; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.h 2023-01-28 19:00:00.000000000 +0000 @@ -0,0 +1,126 @@ +// SystemPage.h + +#ifndef ZIP7_INC_SYSTEM_PAGE_H +#define ZIP7_INC_SYSTEM_PAGE_H + +#include "../../../Windows/Control/ImageList.h" +#include "../../../Windows/Control/ListView.h" +#include "../../../Windows/Control/PropertyPage.h" + +#include "FilePlugins.h" +#include "RegistryAssociations.h" + +enum EExtState +{ + kExtState_Clear = 0, + kExtState_Other, + kExtState_7Zip +}; + +struct CModifiedExtInfo: public NRegistryAssoc::CShellExtInfo +{ + int OldState; + int State; + int ImageIndex; + bool Other; + bool Other7Zip; + + CModifiedExtInfo(): ImageIndex(-1) {} + + CSysString GetString() const; + + void SetState(const UString &iconPath) + { + State = kExtState_Clear; + Other = false; + Other7Zip = false; + if (!ProgramKey.IsEmpty()) + { + State = kExtState_Other; + Other = true; + if (IsIt7Zip()) + { + Other7Zip = !iconPath.IsEqualTo_NoCase(IconPath); + if (!Other7Zip) + { + State = kExtState_7Zip; + Other = false; + } + } + } + OldState = State; + } +}; + +struct CAssoc +{ + CModifiedExtInfo Pair[2]; + int SevenZipImageIndex; + + int GetIconIndex() const + { + for (unsigned i = 0; i < 2; i++) + { + const CModifiedExtInfo &pair = Pair[i]; + if (pair.State == kExtState_Clear) + continue; + if (pair.State == kExtState_7Zip) + return SevenZipImageIndex; + if (pair.ImageIndex != -1) + return pair.ImageIndex; + } + return -1; + } +}; + +#ifdef UNDER_CE + #define NUM_EXT_GROUPS 1 +#else + #define NUM_EXT_GROUPS 2 +#endif + +class CSystemPage: public NWindows::NControl::CPropertyPage +{ + CExtDatabase _extDB; + CObjectVector _items; + + unsigned _numIcons; + NWindows::NControl::CImageList _imageList; + NWindows::NControl::CListView _listView; + + bool _needSave; + + HKEY GetHKey(unsigned + #if NUM_EXT_GROUPS != 1 + group + #endif + ) const + { + #if NUM_EXT_GROUPS == 1 + return HKEY_CLASSES_ROOT; + #else + return group == 0 ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + #endif + } + + int AddIcon(const UString &path, int iconIndex); + unsigned GetRealIndex(unsigned listIndex) const { return listIndex; } + void RefreshListItem(unsigned group, unsigned listIndex); + void ChangeState(unsigned group, const CUIntVector &indices); + void ChangeState(unsigned group); + + bool OnListKeyDown(LPNMLVKEYDOWN keyDownInfo); + +public: + bool WasChanged; + + CSystemPage(): WasChanged(false) {} + + virtual bool OnInit() Z7_override; + virtual void OnNotifyHelp() Z7_override; + virtual bool OnNotify(UINT controlID, LPNMHDR lParam) Z7_override; + virtual LONG OnApply() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPage.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPage.rc 2024-03-16 17:00:00.000000000 +0000 @@ -0,0 +1,43 @@ +#include "SystemPageRes.h" +#include "../../GuiCommon.rc" + +#define xc OPTIONS_PAGE_XC_SIZE +#define yc OPTIONS_PAGE_YC_SIZE + +IDD_SYSTEM DIALOG MY_PAGE_POSTFIX +CAPTION "System" +BEGIN + LTEXT "Associate 7-Zip with:", IDT_SYSTEM_ASSOCIATE, m, m, xc, 8 + PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 92, m + 12, 40, bys + PUSHBUTTON "+", IDB_SYSTEM_ALL, 194, m + 12, 40, bys + CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + m, m + 32, xc, (yc - 32) +END + +#ifdef UNDER_CE + +#undef m +#undef xc +#undef yc + +#define m 4 +#define xc (SMALL_PAGE_SIZE_X + 8) +#define yc (128 + 8) + +IDD_SYSTEM_2 DIALOG MY_PAGE_POSTFIX +CAPTION "System" +BEGIN + LTEXT "Associate 7-Zip with:", IDT_SYSTEM_ASSOCIATE, m, m, xc, 8 + PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 60, m + 12, 40, bys + CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + m, m + 32, xc, (yc - 32) +END + +#endif + +STRINGTABLE +BEGIN + IDS_SYSTEM_ALL_USERS "All users" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPageRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPageRes.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/SystemPageRes.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/SystemPageRes.h 2014-09-01 12:34:24.000000000 +0000 @@ -0,0 +1,9 @@ +#define IDD_SYSTEM 2200 +#define IDD_SYSTEM_2 12200 + +#define IDT_SYSTEM_ASSOCIATE 2201 +#define IDS_SYSTEM_ALL_USERS 2202 + +#define IDL_SYSTEM_ASSOCIATE 100 +#define IDB_SYSTEM_CURRENT 101 +#define IDB_SYSTEM_ALL 102 Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Test.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Test.bmp differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/FileManager/Test2.bmp and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/Test2.bmp differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/TextPairs.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/TextPairs.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,190 +1,193 @@ -// TextPairs.cpp - -#include "StdAfx.h" - -#include "TextPairs.h" - -static const wchar_t kNewLineChar = '\n'; -static const wchar_t kQuoteChar = '\"'; - -static const wchar_t kBOM = (wchar_t)0xFEFF; - -static bool IsSeparatorChar(wchar_t c) -{ - return (c == ' ' || c == '\t'); -} - -static void RemoveCr(UString &s) -{ - s.RemoveChar(L'\x0D'); -} - -static UString GetIDString(const wchar_t *srcString, unsigned &finishPos) -{ - UString result; - bool quotes = false; - for (finishPos = 0;;) - { - wchar_t c = srcString[finishPos]; - if (c == 0) - break; - finishPos++; - bool isSeparatorChar = IsSeparatorChar(c); - if (c == kNewLineChar || (isSeparatorChar && !quotes) - || (c == kQuoteChar && quotes)) - break; - else if (c == kQuoteChar) - quotes = true; - else - result += c; - } - result.Trim(); - RemoveCr(result); - return result; -} - -static UString GetValueString(const wchar_t *srcString, unsigned &finishPos) -{ - UString result; - for (finishPos = 0;;) - { - wchar_t c = srcString[finishPos]; - if (c == 0) - break; - finishPos++; - if (c == kNewLineChar) - break; - result += c; - } - result.Trim(); - RemoveCr(result); - return result; -} - -static bool GetTextPairs(const UString &srcString, CObjectVector &pairs) -{ - pairs.Clear(); - unsigned pos = 0; - - if (srcString.Len() > 0) - { - if (srcString[0] == kBOM) - pos++; - } - while (pos < srcString.Len()) - { - unsigned finishPos; - UString id = GetIDString((const wchar_t *)srcString + pos, finishPos); - pos += finishPos; - if (id.IsEmpty()) - continue; - UString value = GetValueString((const wchar_t *)srcString + pos, finishPos); - pos += finishPos; - if (!id.IsEmpty()) - { - CTextPair pair; - pair.ID = id; - pair.Value = value; - pairs.Add(pair); - } - } - return true; -} - -static int ComparePairIDs(const UString &s1, const UString &s2) - { return MyStringCompareNoCase(s1, s2); } - -static int ComparePairItems(const CTextPair &p1, const CTextPair &p2) - { return ComparePairIDs(p1.ID, p2.ID); } - -static int ComparePairItems(void *const *a1, void *const *a2, void * /* param */) - { return ComparePairItems(**(const CTextPair **)a1, **(const CTextPair **)a2); } - -void CPairsStorage::Sort() { Pairs.Sort(ComparePairItems, 0); } - -int CPairsStorage::FindID(const UString &id, int &insertPos) const -{ - int left = 0, right = Pairs.Size(); - while (left != right) - { - int mid = (left + right) / 2; - int compResult = ComparePairIDs(id, Pairs[mid].ID); - if (compResult == 0) - return mid; - if (compResult < 0) - right = mid; - else - left = mid + 1; - } - insertPos = left; - return -1; -} - -int CPairsStorage::FindID(const UString &id) const -{ - int pos; - return FindID(id, pos); -} - -void CPairsStorage::AddPair(const CTextPair &pair) -{ - int insertPos; - int pos = FindID(pair.ID, insertPos); - if (pos >= 0) - Pairs[pos] = pair; - else - Pairs.Insert(insertPos, pair); -} - -void CPairsStorage::DeletePair(const UString &id) -{ - int pos = FindID(id); - if (pos >= 0) - Pairs.Delete(pos); -} - -bool CPairsStorage::GetValue(const UString &id, UString &value) const -{ - value.Empty(); - int pos = FindID(id); - if (pos < 0) - return false; - value = Pairs[pos].Value; - return true; -} - -UString CPairsStorage::GetValue(const UString &id) const -{ - int pos = FindID(id); - if (pos < 0) - return UString(); - return Pairs[pos].Value; -} - -bool CPairsStorage::ReadFromString(const UString &text) -{ - bool result = ::GetTextPairs(text, Pairs); - if (result) - Sort(); - else - Pairs.Clear(); - return result; -} - -void CPairsStorage::SaveToString(UString &text) const -{ - FOR_VECTOR (i, Pairs) - { - const CTextPair &pair = Pairs[i]; - bool multiWord = (pair.ID.Find(L' ') >= 0); - if (multiWord) - text += L'\"'; - text += pair.ID; - if (multiWord) - text += L'\"'; - text += L' '; - text += pair.Value; - text += L'\x0D'; - text.Add_LF(); - } -} +// TextPairs.cpp + +#include "StdAfx.h" + +#include "TextPairs.h" + +static const wchar_t kNewLineChar = '\n'; +static const wchar_t kQuoteChar = '\"'; + +static const wchar_t kBOM = (wchar_t)0xFEFF; + +static bool IsSeparatorChar(wchar_t c) +{ + return (c == ' ' || c == '\t'); +} + +static void RemoveCr(UString &s) +{ + s.RemoveChar(L'\x0D'); +} + +static UString GetIDString(const wchar_t *srcString, unsigned &finishPos) +{ + UString result; + bool quotes = false; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == 0) + break; + finishPos++; + bool isSeparatorChar = IsSeparatorChar(c); + if (c == kNewLineChar || (isSeparatorChar && !quotes) + || (c == kQuoteChar && quotes)) + break; + else if (c == kQuoteChar) + quotes = true; + else + result += c; + } + result.Trim(); + RemoveCr(result); + return result; +} + +static UString GetValueString(const wchar_t *srcString, unsigned &finishPos) +{ + UString result; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == 0) + break; + finishPos++; + if (c == kNewLineChar) + break; + result += c; + } + result.Trim(); + RemoveCr(result); + return result; +} + +static bool GetTextPairs(const UString &srcString, CObjectVector &pairs) +{ + pairs.Clear(); + unsigned pos = 0; + + if (srcString.Len() > 0) + { + if (srcString[0] == kBOM) + pos++; + } + while (pos < srcString.Len()) + { + unsigned finishPos; + UString id = GetIDString((const wchar_t *)srcString + pos, finishPos); + pos += finishPos; + if (id.IsEmpty()) + continue; + UString value = GetValueString((const wchar_t *)srcString + pos, finishPos); + pos += finishPos; + if (!id.IsEmpty()) + { + CTextPair pair; + pair.ID = id; + pair.Value = value; + pairs.Add(pair); + } + } + return true; +} + +static int ComparePairIDs(const UString &s1, const UString &s2) + { return MyStringCompareNoCase(s1, s2); } + +static int ComparePairItems(const CTextPair &p1, const CTextPair &p2) + { return ComparePairIDs(p1.ID, p2.ID); } + +static int ComparePairItems(void *const *a1, void *const *a2, void * /* param */) + { return ComparePairItems(**(const CTextPair *const *)a1, **(const CTextPair *const *)a2); } + +void CPairsStorage::Sort() { Pairs.Sort(ComparePairItems, NULL); } + +int CPairsStorage::FindID(const UString &id, unsigned &insertPos) const +{ + unsigned left = 0, right = Pairs.Size(); + while (left != right) + { + const unsigned mid = (left + right) / 2; + const int compResult = ComparePairIDs(id, Pairs[mid].ID); + if (compResult == 0) + { + insertPos = mid; // to disable GCC warning + return (int)mid; + } + if (compResult < 0) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +int CPairsStorage::FindID(const UString &id) const +{ + unsigned pos; + return FindID(id, pos); +} + +void CPairsStorage::AddPair(const CTextPair &pair) +{ + unsigned insertPos; + const int pos = FindID(pair.ID, insertPos); + if (pos >= 0) + Pairs[pos] = pair; + else + Pairs.Insert(insertPos, pair); +} + +void CPairsStorage::DeletePair(const UString &id) +{ + const int pos = FindID(id); + if (pos >= 0) + Pairs.Delete((unsigned)pos); +} + +bool CPairsStorage::GetValue(const UString &id, UString &value) const +{ + value.Empty(); + const int pos = FindID(id); + if (pos < 0) + return false; + value = Pairs[pos].Value; + return true; +} + +UString CPairsStorage::GetValue(const UString &id) const +{ + const int pos = FindID(id); + if (pos < 0) + return UString(); + return Pairs[pos].Value; +} + +bool CPairsStorage::ReadFromString(const UString &text) +{ + bool result = ::GetTextPairs(text, Pairs); + if (result) + Sort(); + else + Pairs.Clear(); + return result; +} + +void CPairsStorage::SaveToString(UString &text) const +{ + FOR_VECTOR (i, Pairs) + { + const CTextPair &pair = Pairs[i]; + bool multiWord = (pair.ID.Find(L' ') >= 0); + if (multiWord) + text.Add_Char('\"'); + text += pair.ID; + if (multiWord) + text.Add_Char('\"'); + text.Add_Space(); + text += pair.Value; + text.Add_Char('\x0D'); + text.Add_LF(); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/TextPairs.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/TextPairs.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/TextPairs.h 2023-01-19 20:00:00.000000000 +0000 @@ -1,32 +1,32 @@ -// TextPairs.h - -#ifndef __FM_TEXT_PAIRS_H -#define __FM_TEXT_PAIRS_H - -#include "../../../Common/MyString.h" - -struct CTextPair -{ - UString ID; - UString Value; -}; - -class CPairsStorage -{ - CObjectVector Pairs; - - int FindID(const UString &id, int &insertPos) const; - int FindID(const UString &id) const; - void Sort(); -public: - void Clear() { Pairs.Clear(); } - bool ReadFromString(const UString &text); - void SaveToString(UString &text) const; - - bool GetValue(const UString &id, UString &value) const; - UString GetValue(const UString &id) const; - void AddPair(const CTextPair &pair); - void DeletePair(const UString &id); -}; - -#endif +// TextPairs.h + +#ifndef ZIP7_INC_FM_TEXT_PAIRS_H +#define ZIP7_INC_FM_TEXT_PAIRS_H + +#include "../../../Common/MyString.h" + +struct CTextPair +{ + UString ID; + UString Value; +}; + +class CPairsStorage +{ + CObjectVector Pairs; + + int FindID(const UString &id, unsigned &insertPos) const; + int FindID(const UString &id) const; + void Sort(); +public: + void Clear() { Pairs.Clear(); } + bool ReadFromString(const UString &text); + void SaveToString(UString &text) const; + + bool GetValue(const UString &id, UString &value) const; + UString GetValue(const UString &id) const; + void AddPair(const CTextPair &pair); + void DeletePair(const UString &id); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/UpdateCallback100.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/UpdateCallback100.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.cpp 2024-10-16 08:00:00.000000000 +0000 @@ -1,124 +1,147 @@ -// UpdateCallback100.cpp - -#include "StdAfx.h" - -#include "../../../Windows/ErrorMsg.h" - -#include "../GUI/resource3.h" - -#include "LangUtils.h" -#include "UpdateCallback100.h" - -STDMETHODIMP CUpdateCallback100Imp::ScanProgress(UInt64 /* numFolders */, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */) -{ - return ProgressDialog->Sync.ScanProgress(numFiles, totalSize, us2fs(path)); -} - -STDMETHODIMP CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode) -{ - ProgressDialog->Sync.AddError_Code_Name(errorCode, path); - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles) -{ - return ProgressDialog->Sync.Set_NumFilesTotal(numFiles); -} - -STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size) -{ - ProgressDialog->Sync.Set_NumBytesTotal(size); - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 *completed) -{ - return ProgressDialog->Sync.Set_NumBytesCur(completed); -} - -STDMETHODIMP CUpdateCallback100Imp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - ProgressDialog->Sync.Set_Ratio(inSize, outSize); - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name) -{ - return SetOperation_Base(NUpdateNotifyOp::kAdd, name, false); -} - -STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *name) -{ - return SetOperation_Base(NUpdateNotifyOp::kDelete, name, false); -} - -STDMETHODIMP CUpdateCallback100Imp::OperationResult(Int32 /* operationResult */) -{ - ProgressDialog->Sync.Set_NumFilesCur(++NumFiles); - return S_OK; -} - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); - -HRESULT CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) -{ - if (opRes != NArchive::NExtract::NOperationResult::kOK) - { - UString s; - SetExtractErrorMessage(opRes, isEncrypted, name, s); - ProgressDialog->Sync.AddError_Message(s); - } - return S_OK; -} - -HRESULT CUpdateCallback100Imp::ReportUpdateOperation(UInt32 notifyOp, const wchar_t *name, Int32 isDir) -{ - return SetOperation_Base(notifyOp, name, IntToBool(isDir)); -} - -STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) -{ - ProgressDialog->Sync.AddError_Message(message); - return S_OK; -} - -HRESULT CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode) -{ - ProgressDialog->Sync.AddError_Code_Name(errorCode, path); - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode) -{ - ProgressDialog->Sync.AddError_Code_Name(errorCode, path); - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - *password = NULL; - *passwordIsDefined = BoolToInt(PasswordIsDefined); - if (!PasswordIsDefined) - return S_OK; - return StringToBstr(Password, password); -} - -STDMETHODIMP CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) -{ - return S_OK; -} - -STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) -{ - return ProgressDialog->Sync.CheckStop(); -} - -STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password) -{ - *password = NULL; - if (!PasswordIsDefined) - { - RINOK(ShowAskPasswordDialog()) - } - return StringToBstr(Password, password); -} +// UpdateCallback100.cpp + +#include "StdAfx.h" + +#include "../../../Windows/ErrorMsg.h" + +#include "../GUI/resource3.h" + +#include "LangUtils.h" +#include "UpdateCallback100.h" + +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanProgress(UInt64 /* numFolders */, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */)) +{ + return ProgressDialog->Sync.ScanProgress(numFiles, totalSize, us2fs(path)); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode)) +{ + ProgressDialog->Sync.AddError_Code_Name(errorCode, path); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)) +{ + return ProgressDialog->Sync.Set_NumFilesTotal(numFiles); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(UInt64 size)) +{ + ProgressDialog->Sync.Set_NumBytesTotal(size); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 *completed)) +{ + return ProgressDialog->Sync.Set_NumBytesCur(completed); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) +{ + ProgressDialog->Sync.Set_Ratio(inSize, outSize); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::CompressOperation(const wchar_t *name)) +{ + return SetOperation_Base(NUpdateNotifyOp::kAdd, name, false); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)) +{ + return SetOperation_Base(NUpdateNotifyOp::kDelete, name, false); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::OperationResult(Int32 /* operationResult */)) +{ + ProgressDialog->Sync.Set_NumFilesCur(++NumFiles); + return S_OK; +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + UString s; + SetExtractErrorMessage(opRes, isEncrypted, name, s); + ProgressDialog->Sync.AddError_Message(s); + } + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReportUpdateOperation(UInt32 notifyOp, const wchar_t *name, Int32 isDir)) +{ + return SetOperation_Base(notifyOp, name, IntToBool(isDir)); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)) +{ + ProgressDialog->Sync.AddError_Message(message); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode)) +{ + ProgressDialog->Sync.AddError_Code_Name(errorCode, path); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode)) +{ + ProgressDialog->Sync.AddError_Code_Name(errorCode, path); + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)) +{ + *password = NULL; + *passwordIsDefined = BoolToInt(PasswordIsDefined); + if (!PasswordIsDefined) + return S_OK; + return StringToBstr(Password, password); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + return S_OK; +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)) +{ + return ProgressDialog->Sync.CheckStop(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) +{ + return MoveArc_Start_Base(srcTempPath, destFinalPath, size, updateMode); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) +{ + return MoveArc_Progress_Base(totalSize, currentSize); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish()) +{ + return MoveArc_Finish_Base(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen()) +{ + ProgressDialog->Sync.Clear_Stop_Status(); + return S_OK; +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) +{ + *password = NULL; + if (!PasswordIsDefined) + { + RINOK(ShowAskPasswordDialog()) + } + return StringToBstr(Password, password); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/UpdateCallback100.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/UpdateCallback100.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/UpdateCallback100.h 2024-10-14 10:00:00.000000000 +0000 @@ -1,52 +1,49 @@ -// UpdateCallback100.h - -#ifndef __UPDATE_CALLBACK100_H -#define __UPDATE_CALLBACK100_H - -#include "../../../Common/MyCom.h" - -#include "../../IPassword.h" - -#include "../Agent/IFolderArchive.h" - -#include "../GUI/UpdateCallbackGUI2.h" - -#include "ProgressDialog2.h" - -class CUpdateCallback100Imp: - public IFolderArchiveUpdateCallback, - public IFolderArchiveUpdateCallback2, - public IFolderScanProgress, - public ICryptoGetTextPassword2, - public ICryptoGetTextPassword, - public IArchiveOpenCallback, - public ICompressProgressInfo, - public CUpdateCallbackGUI2, - public CMyUnknownImp -{ -public: - - // CUpdateCallback100Imp() {} - - MY_UNKNOWN_IMP7( - IFolderArchiveUpdateCallback, - IFolderArchiveUpdateCallback2, - IFolderScanProgress, - ICryptoGetTextPassword2, - ICryptoGetTextPassword, - IArchiveOpenCallback, - ICompressProgressInfo) - - INTERFACE_IProgress(;) - INTERFACE_IArchiveOpenCallback(;) - INTERFACE_IFolderArchiveUpdateCallback(;) - INTERFACE_IFolderArchiveUpdateCallback2(;) - INTERFACE_IFolderScanProgress(;) - - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); - - STDMETHOD(CryptoGetTextPassword)(BSTR *password); - STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); -}; - -#endif +// UpdateCallback100.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK100_H +#define ZIP7_INC_UPDATE_CALLBACK100_H + +#include "../../../Common/MyCom.h" + +#include "../../IPassword.h" + +#include "../Agent/IFolderArchive.h" + +#include "../GUI/UpdateCallbackGUI2.h" + +#include "ProgressDialog2.h" + +class CUpdateCallback100Imp Z7_final: + public IFolderArchiveUpdateCallback, + public IFolderArchiveUpdateCallback2, + public IFolderArchiveUpdateCallback_MoveArc, + public IFolderScanProgress, + public ICryptoGetTextPassword2, + public ICryptoGetTextPassword, + public IArchiveOpenCallback, + public ICompressProgressInfo, + public CUpdateCallbackGUI2, + public CMyUnknownImp +{ + Z7_COM_UNKNOWN_IMP_8( + IFolderArchiveUpdateCallback, + IFolderArchiveUpdateCallback2, + IFolderArchiveUpdateCallback_MoveArc, + IFolderScanProgress, + ICryptoGetTextPassword2, + ICryptoGetTextPassword, + IArchiveOpenCallback, + ICompressProgressInfo) + + Z7_IFACE_COM7_IMP(IProgress) + Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback) + Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback2) + Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback_MoveArc) + Z7_IFACE_COM7_IMP(IFolderScanProgress) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) + Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) + Z7_IFACE_COM7_IMP(IArchiveOpenCallback) + Z7_IFACE_COM7_IMP(ICompressProgressInfo) +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/VerCtrl.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/VerCtrl.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/VerCtrl.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/VerCtrl.cpp 2024-07-05 05:00:00.000000000 +0000 @@ -0,0 +1,428 @@ +// VerCtrl.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileFind.h" + +#include "App.h" +#include "RegistryUtils.h" +#include "OverwriteDialog.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; +using namespace NDir; + +static FString ConvertPath_to_Ctrl(const FString &path) +{ + FString s = path; + s.Replace(FChar(':'), FChar('_')); + return s; +} + +struct CFileDataInfo +{ + CByteBuffer Data; + BY_HANDLE_FILE_INFORMATION Info; + bool IsOpen; + + CFileDataInfo(): IsOpen (false) {} + UInt64 GetSize() const { return (((UInt64)Info.nFileSizeHigh) << 32) + Info.nFileSizeLow; } + bool Read(const FString &path); +}; + + +bool CFileDataInfo::Read(const FString &path) +{ + IsOpen = false; + NIO::CInFile file; + if (!file.Open(path)) + return false; + if (!file.GetFileInformation(&Info)) + return false; + + const UInt64 size = GetSize(); + const size_t size2 = (size_t)size; + if (size2 != size || size2 > (1 << 28)) + { + SetLastError(1); + return false; + } + + Data.Alloc(size2); + + size_t processedSize; + if (!file.ReadFull(Data, size2, processedSize)) + return false; + if (processedSize != size2) + { + SetLastError(1); + return false; + } + IsOpen = true; + return true; +} + + +static bool CreateComplexDir_for_File(const FString &path) +{ + FString resDirPrefix; + FString resFileName; + if (!GetFullPathAndSplit(path, resDirPrefix, resFileName)) + return false; + return CreateComplexDir(resDirPrefix); +} + + +static bool ParseNumberString(const FString &s, UInt32 &number) +{ + const FChar *end; + UInt64 result = ConvertStringToUInt64(s, &end); + if (*end != 0 || s.IsEmpty() || result > (UInt32)0x7FFFFFFF) + return false; + number = (UInt32)result; + return true; +} + + +static void WriteFile(const FString &path, bool createAlways, const CFileDataInfo &fdi, const CPanel &panel) +{ + NIO::COutFile outFile; + if (!outFile.Create_ALWAYS_or_NEW(path, createAlways)) // (createAlways = false) means CREATE_NEW + { + panel.MessageBox_LastError(); + return; + } + UInt32 processedSize; + if (!outFile.Write(fdi.Data, (UInt32)fdi.Data.Size(), processedSize)) + { + panel.MessageBox_LastError(); + return; + } + if (processedSize != fdi.Data.Size()) + { + panel.MessageBox_Error(L"Write error"); + return; + } + if (!outFile.SetTime( + &fdi.Info.ftCreationTime, + &fdi.Info.ftLastAccessTime, + &fdi.Info.ftLastWriteTime)) + { + panel.MessageBox_LastError(); + return; + } + + if (!SetFileAttrib(path, fdi.Info.dwFileAttributes)) + { + panel.MessageBox_LastError(); + return; + } +} + + +static UInt64 FILETIME_to_UInt64(const FILETIME &ft) +{ + return ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); +} + +static void UInt64_TO_FILETIME(UInt64 v, FILETIME &ft) +{ + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + + +void CApp::VerCtrl(unsigned id) +{ + const CPanel &panel = GetFocusedPanel(); + + if (!panel.Is_IO_FS_Folder()) + { + panel.MessageBox_Error_UnsupportOperation(); + return; + } + + CRecordVector indices; + panel.Get_ItemIndices_Selected(indices); + + if (indices.Size() != 1) + { + // panel.MessageBox_Error_UnsupportOperation(); + return; + } + + const FString path = us2fs(panel.GetItemFullPath(indices[0])); + + UString vercPath; + ReadReg_VerCtrlPath(vercPath); + if (vercPath.IsEmpty()) + return; + NName::NormalizeDirPathPrefix(vercPath); + + FString dirPrefix; + FString fileName; + if (!GetFullPathAndSplit(path, dirPrefix, fileName)) + { + panel.MessageBox_LastError(); + return; + } + + const FString dirPrefix2 = us2fs(vercPath) + ConvertPath_to_Ctrl(dirPrefix); + const FString path2 = dirPrefix2 + fileName; + + bool sameTime = false; + bool sameData = false; + bool areIdentical = false; + + CFileDataInfo fdi, fdi2; + if (!fdi.Read(path)) + { + panel.MessageBox_LastError(); + return; + } + + if (fdi2.Read(path2)) + { + sameData = (fdi.Data == fdi2.Data); + sameTime = (CompareFileTime(&fdi.Info.ftLastWriteTime, &fdi2.Info.ftLastWriteTime) == 0); + areIdentical = (sameData && sameTime); + } + + const bool isReadOnly = NAttributes::IsReadOnly(fdi.Info.dwFileAttributes); + + if (id == IDM_VER_EDIT) + { + if (!isReadOnly) + { + panel.MessageBox_Error(L"File is not read-only"); + return; + } + + if (!areIdentical) + { + if (fdi2.IsOpen) + { + NFind::CEnumerator enumerator; + FString d2 = dirPrefix2; + d2 += "_7vc"; + d2.Add_PathSepar(); + d2 += fileName; + d2.Add_PathSepar(); + enumerator.SetDirPrefix(d2); + NFind::CDirEntry fi; + Int32 maxVal = -1; + while (enumerator.Next(fi)) + { + UInt32 val; + if (!ParseNumberString(fi.Name, val)) + continue; + if ((Int32)val > maxVal) + maxVal = (Int32)val; + } + + UInt32 next = (UInt32)maxVal + 1; + if (maxVal < 0) + { + next = 1; + if (!::CreateComplexDir_for_File(path2)) + { + panel.MessageBox_LastError(); + return; + } + } + + // we rename old file2 to some name; + FString path_num = d2; + { + AString t; + t.Add_UInt32((UInt32)next); + while (t.Len() < 3) + t.InsertAtFront('0'); + path_num += t; + } + + if (maxVal < 0) + { + if (!::CreateComplexDir_for_File(path_num)) + { + panel.MessageBox_LastError(); + return; + } + } + + if (!NDir::MyMoveFile(path2, path_num)) + { + panel.MessageBox_LastError(); + return; + } + } + else + { + if (!::CreateComplexDir_for_File(path2)) + { + panel.MessageBox_LastError(); + return; + } + } + /* + if (!::CopyFile(fs2fas(path), fs2fas(path2), TRUE)) + { + panel.MessageBox_LastError(); + return; + } + */ + WriteFile(path2, + false, // (createAlways = false) means CREATE_NEW + fdi, panel); + } + + if (!SetFileAttrib(path, fdi.Info.dwFileAttributes & ~(DWORD)FILE_ATTRIBUTE_READONLY)) + { + panel.MessageBox_LastError(); + return; + } + + return; + } + + if (isReadOnly) + { + panel.MessageBox_Error(L"File is read-only"); + return; + } + + if (id == IDM_VER_COMMIT) + { + if (sameData) + { + if (!sameTime) + { + panel.MessageBox_Error( + L"Same data, but different timestamps.\n" + L"Use `Revert` to recover timestamp."); + return; + } + } + + const UInt64 timeStampOriginal = FILETIME_to_UInt64(fdi.Info.ftLastWriteTime); + UInt64 timeStamp2 = 0; + if (fdi2.IsOpen) + timeStamp2 = FILETIME_to_UInt64(fdi2.Info.ftLastWriteTime); + + if (timeStampOriginal > timeStamp2) + { + const UInt64 k_Ntfs_prec = 10000000; + UInt64 timeStamp = timeStampOriginal; + const UInt32 k_precs[] = { 60 * 60, 60, 2, 1 }; + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_precs); i++) + { + timeStamp = timeStampOriginal; + const UInt64 prec = k_Ntfs_prec * k_precs[i]; + // timeStamp += prec - 1; // for rounding up + timeStamp /= prec; + timeStamp *= prec; + if (timeStamp > timeStamp2) + break; + } + + if (timeStamp != timeStampOriginal + && timeStamp > timeStamp2) + { + FILETIME mTime; + UInt64_TO_FILETIME(timeStamp, mTime); + // NDir::SetFileAttrib(path, 0); + { + NIO::COutFile outFile; + if (!outFile.Open_EXISTING(path)) + { + panel.MessageBox_LastError(); + return; + // if (::GetLastError() != ERROR_SUCCESS) + // throw "open error"; + } + else + { + const UInt64 cTime = FILETIME_to_UInt64(fdi.Info.ftCreationTime); + if (cTime > timeStamp) + outFile.SetTime(&mTime, NULL, &mTime); + else + outFile.SetMTime(&mTime); + } + } + } + } + + if (!SetFileAttrib(path, fdi.Info.dwFileAttributes | FILE_ATTRIBUTE_READONLY)) + { + panel.MessageBox_LastError(); + return; + } + return; + } + + if (id == IDM_VER_REVERT) + { + if (!fdi2.IsOpen) + { + panel.MessageBox_Error(L"No file to revert"); + return; + } + if (!sameData || !sameTime) + { + if (!sameData) + { + /* + UString m; + m = "Are you sure you want to revert file ?"; + m.Add_LF(); + m += path; + if (::MessageBoxW(panel.GetParent(), m, L"Version Control: File Revert", MB_OKCANCEL | MB_ICONQUESTION) != IDOK) + return; + */ + COverwriteDialog dialog; + + dialog.OldFileInfo.SetTime(fdi.Info.ftLastWriteTime); + dialog.OldFileInfo.SetSize(fdi.GetSize()); + dialog.OldFileInfo.Path = fs2us(path); + + dialog.NewFileInfo.SetTime(fdi2.Info.ftLastWriteTime); + dialog.NewFileInfo.SetSize(fdi2.GetSize()); + dialog.NewFileInfo.Path = fs2us(path2); + + dialog.ShowExtraButtons = false; + dialog.DefaultButton_is_NO = true; + + INT_PTR writeAnswer = dialog.Create(panel.GetParent()); + + if (writeAnswer != IDYES) + return; + } + + WriteFile(path, + true, // (createAlways = true) means CREATE_ALWAYS + fdi2, panel); + } + else + { + if (!SetFileAttrib(path, fdi2.Info.dwFileAttributes | FILE_ATTRIBUTE_READONLY)) + { + panel.MessageBox_LastError(); + return; + } + } + return; + } + + // if (id == IDM_VER_DIFF) + { + if (!fdi2.IsOpen) + return; + DiffFiles(fs2us(path2), fs2us(path)); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ViewSettings.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ViewSettings.cpp 2015-10-06 10:02:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.cpp 2024-11-08 11:00:00.000000000 +0000 @@ -1,312 +1,315 @@ -// ViewSettings.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/Registry.h" -#include "../../../Windows/Synchronization.h" - -#include "ViewSettings.h" - -using namespace NWindows; -using namespace NRegistry; - -#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM") - -static const TCHAR *kCUBasePath = REG_PATH_FM; -static const TCHAR *kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns"); - -static const TCHAR *kPositionValueName = TEXT("Position"); -static const TCHAR *kPanelsInfoValueName = TEXT("Panels"); -static const TCHAR *kToolbars = TEXT("Toolbars"); - -static const WCHAR *kPanelPathValueName = L"PanelPath"; -static const TCHAR *kListMode = TEXT("ListMode"); -static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory"); -static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts"); -static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory"); - -static NSynchronization::CCriticalSection g_CS; - -#define Set32(p, v) SetUi32(((Byte *)p), v) -#define SetBool(p, v) Set32(p, ((v) ? 1 : 0)) - -#define Get32(p, dest) dest = GetUi32((const Byte *)p) -#define GetBool(p, dest) dest = (GetUi32(p) != 0); - -/* -struct CColumnHeader -{ - UInt32 Version; - UInt32 SortID; - UInt32 Ascending; // bool -}; -*/ - -static const UInt32 kListViewHeaderSize = 3 * 4; -static const UInt32 kColumnInfoSize = 3 * 4; -static const UInt32 kListViewVersion = 1; - -void CListViewInfo::Save(const UString &id) const -{ - const UInt32 dataSize = kListViewHeaderSize + kColumnInfoSize * Columns.Size(); - CByteArr buf(dataSize); - - Set32(buf, kListViewVersion); - Set32(buf + 4, SortID); - SetBool(buf + 8, Ascending); - FOR_VECTOR (i, Columns) - { - const CColumnInfo &column = Columns[i]; - Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize; - Set32(p, column.PropID); - SetBool(p + 4, column.IsVisible); - Set32(p + 8, column.Width); - } - { - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - key.Create(HKEY_CURRENT_USER, kCulumnsKeyName); - key.SetValue(GetSystemString(id), (const Byte *)buf, dataSize); - } -} - -void CListViewInfo::Read(const UString &id) -{ - Clear(); - CByteBuffer buf; - UInt32 size; - { - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS) - return; - if (key.QueryValue(GetSystemString(id), buf, size) != ERROR_SUCCESS) - return; - } - if (size < kListViewHeaderSize) - return; - UInt32 version; - Get32(buf, version); - if (version != kListViewVersion) - return; - Get32(buf + 4, SortID); - GetBool(buf + 8, Ascending); - - size -= kListViewHeaderSize; - if (size % kColumnInfoSize != 0) - return; - unsigned numItems = size / kColumnInfoSize; - Columns.ClearAndReserve(numItems); - for (unsigned i = 0; i < numItems; i++) - { - CColumnInfo column; - const Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize; - Get32(p, column.PropID); - GetBool(p + 4, column.IsVisible); - Get32(p + 8, column.Width); - Columns.AddInReserved(column); - } -} - - -/* -struct CWindowPosition -{ - RECT Rect; - UInt32 Maximized; // bool -}; - -struct CPanelsInfo -{ - UInt32 NumPanels; - UInt32 CurrentPanel; - UInt32 SplitterPos; -}; -*/ - -static const UInt32 kWindowPositionHeaderSize = 5 * 4; -static const UInt32 kPanelsInfoHeaderSize = 3 * 4; - -#ifdef _WIN32 -void CWindowInfo::Save() const -{ - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - { - Byte buf[kWindowPositionHeaderSize]; - Set32(buf, rect.left); - Set32(buf + 4, rect.top); - Set32(buf + 8, rect.right); - Set32(buf + 12, rect.bottom); - SetBool(buf + 16, maximized); - key.SetValue(kPositionValueName, buf, kWindowPositionHeaderSize); - } - { - Byte buf[kPanelsInfoHeaderSize]; - Set32(buf, numPanels); - Set32(buf + 4, currentPanel); - Set32(buf + 8, splitterPos); - key.SetValue(kPanelsInfoValueName, buf, kPanelsInfoHeaderSize); - } -} - -static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize) -{ - UInt32 size; - return key.QueryValue(name, buf, size) == ERROR_SUCCESS && size == dataSize; -} - -void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined) -{ - windowPosDefined = false; - panelInfoDefined = false; - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) - return; - CByteBuffer buf; - if (QueryBuf(key, kPositionValueName, buf, kWindowPositionHeaderSize)) - { - Get32(buf, rect.left); - Get32(buf + 4, rect.top); - Get32(buf + 8, rect.right); - Get32(buf + 12, rect.bottom); - GetBool(buf + 16, maximized); - windowPosDefined = true; - } - if (QueryBuf(key, kPanelsInfoValueName, buf, kPanelsInfoHeaderSize)) - { - Get32(buf, numPanels); - Get32(buf + 4, currentPanel); - Get32(buf + 8, splitterPos); - panelInfoDefined = true; - } - return; -} -#endif - - -void SaveUi32Val(const TCHAR *name, UInt32 value) -{ - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - key.SetValue(name, value); -} - -bool ReadUi32Val(const TCHAR *name, UInt32 &value) -{ - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) - return false; - return key.QueryValue(name, value) == ERROR_SUCCESS; -} - -void SaveToolbarsMask(UInt32 toolbarMask) -{ - SaveUi32Val(kToolbars, toolbarMask); -} - -static const UInt32 kDefaultToolbarMask = ((UInt32)1 << 31) | 8 | 4 | 1; - -UInt32 ReadToolbarsMask() -{ - UInt32 mask; - if (!ReadUi32Val(kToolbars, mask)) - return kDefaultToolbarMask; - return mask; -} - - -void CListMode::Save() const -{ - UInt32 t = 0; - for (int i = 0; i < 2; i++) - t |= ((Panels[i]) & 0xFF) << (i * 8); - SaveUi32Val(kListMode, t); -} - -void CListMode::Read() -{ - Init(); - UInt32 t; - if (!ReadUi32Val(kListMode, t)) - return; - for (int i = 0; i < 2; i++) - { - Panels[i] = (t & 0xFF); - t >>= 8; - } -} - -static UString GetPanelPathName(UInt32 panelIndex) -{ - WCHAR s[16]; - ConvertUInt32ToString(panelIndex, s); - return (UString)kPanelPathValueName + s; -} - -void SavePanelPath(UInt32 panel, const UString &path) -{ - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - key.SetValue(GetPanelPathName(panel), path); -} - -bool ReadPanelPath(UInt32 panel, UString &path) -{ - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) - return false; - return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); -} - - -static void SaveStringList(LPCTSTR valueName, const UStringVector &folders) -{ - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - key.SetValue_Strings(valueName, folders); -} - -static void ReadStringList(LPCTSTR valueName, UStringVector &folders) -{ - folders.Clear(); - NSynchronization::CCriticalSectionLock lock(g_CS); - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) - key.GetValue_Strings(valueName, folders); -} - -void SaveFolderHistory(const UStringVector &folders) - { SaveStringList(kFolderHistoryValueName, folders); } -void ReadFolderHistory(UStringVector &folders) - { ReadStringList(kFolderHistoryValueName, folders); } - -void SaveFastFolders(const UStringVector &folders) - { SaveStringList(kFastFoldersValueName, folders); } -void ReadFastFolders(UStringVector &folders) - { ReadStringList(kFastFoldersValueName, folders); } - -void SaveCopyHistory(const UStringVector &folders) - { SaveStringList(kCopyHistoryValueName, folders); } -void ReadCopyHistory(UStringVector &folders) - { ReadStringList(kCopyHistoryValueName, folders); } - -void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s) -{ - for (unsigned i = 0; i < list.Size();) - if (s.IsEqualTo_NoCase(list[i])) - list.Delete(i); - else - i++; - list.Insert(0, s); -} +// ViewSettings.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/Registry.h" +#include "../../../Windows/Synchronization.h" + +#include "ViewSettings.h" + +using namespace NWindows; +using namespace NRegistry; + +#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM") + +static LPCTSTR const kCUBasePath = REG_PATH_FM; +static LPCTSTR const kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns"); + +static LPCTSTR const kPositionValueName = TEXT("Position"); +static LPCTSTR const kPanelsInfoValueName = TEXT("Panels"); +static LPCTSTR const kToolbars = TEXT("Toolbars"); + +static LPCWSTR const kPanelPathValueName = L"PanelPath"; + +static LPCTSTR const kListMode = TEXT("ListMode"); +static LPCTSTR const kFolderHistoryValueName = TEXT("FolderHistory"); +static LPCTSTR const kFastFoldersValueName = TEXT("FolderShortcuts"); +static LPCTSTR const kCopyHistoryValueName = TEXT("CopyHistory"); + +static NSynchronization::CCriticalSection g_CS; + +#define Set32(p, v) SetUi32(((Byte *)p), v) +#define SetBool(p, v) Set32(p, ((v) ? 1 : 0)) + +#define Get32(p, dest) dest = GetUi32((const Byte *)p); +#define Get32_LONG(p, dest) dest = (LONG)GetUi32((const Byte *)p); +#define GetBool(p, dest) dest = (GetUi32(p) != 0); + +/* +struct CColumnHeader +{ + UInt32 Version; + UInt32 SortID; + UInt32 Ascending; // bool +}; +*/ + +static const UInt32 kListViewHeaderSize = 3 * 4; +static const UInt32 kColumnInfoSize = 3 * 4; +static const UInt32 kListViewVersion = 1; + +void CListViewInfo::Save(const UString &id) const +{ + const UInt32 dataSize = kListViewHeaderSize + kColumnInfoSize * Columns.Size(); + CByteArr buf(dataSize); + + Set32(buf, kListViewVersion) + Set32(buf + 4, SortID) + SetBool(buf + 8, Ascending) + FOR_VECTOR (i, Columns) + { + const CColumnInfo &column = Columns[i]; + Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize; + Set32(p, column.PropID) + SetBool(p + 4, column.IsVisible) + Set32(p + 8, column.Width) + } + { + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + key.Create(HKEY_CURRENT_USER, kCulumnsKeyName); + key.SetValue(GetSystemString(id), (const Byte *)buf, dataSize); + } +} + +void CListViewInfo::Read(const UString &id) +{ + Clear(); + CByteBuffer buf; + { + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS) + return; + if (key.QueryValue_Binary(GetSystemString(id), buf) != ERROR_SUCCESS) + return; + } + unsigned size = (unsigned)buf.Size(); + if (size < kListViewHeaderSize) + return; + UInt32 version; + Get32(buf, version) + if (version != kListViewVersion) + return; + Get32(buf + 4, SortID) + GetBool(buf + 8, Ascending) + + IsLoaded = true; + + size -= kListViewHeaderSize; + if (size % kColumnInfoSize != 0) + return; + if (size > 1000 * kColumnInfoSize) + return; + const unsigned numItems = size / kColumnInfoSize; + Columns.ClearAndReserve(numItems); + for (unsigned i = 0; i < numItems; i++) + { + CColumnInfo column; + const Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize; + Get32(p, column.PropID) + GetBool(p + 4, column.IsVisible) + Get32(p + 8, column.Width) + Columns.AddInReserved(column); + } +} + + +/* +struct CWindowPosition +{ + RECT Rect; + UInt32 Maximized; // bool +}; + +struct CPanelsInfo +{ + UInt32 NumPanels; + UInt32 CurrentPanel; + UInt32 SplitterPos; +}; +*/ + +static const UInt32 kWindowPositionHeaderSize = 5 * 4; +static const UInt32 kPanelsInfoHeaderSize = 3 * 4; + +void CWindowInfo::Save() const +{ + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + { + Byte buf[kWindowPositionHeaderSize]; + Set32(buf, (UInt32)rect.left) + Set32(buf + 4, (UInt32)rect.top) + Set32(buf + 8, (UInt32)rect.right) + Set32(buf + 12, (UInt32)rect.bottom) + SetBool(buf + 16, maximized) + key.SetValue(kPositionValueName, buf, kWindowPositionHeaderSize); + } + { + Byte buf[kPanelsInfoHeaderSize]; + Set32(buf, numPanels) + Set32(buf + 4, currentPanel) + Set32(buf + 8, splitterPos) + key.SetValue(kPanelsInfoValueName, buf, kPanelsInfoHeaderSize); + } +} + +static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize) +{ + return key.QueryValue_Binary(name, buf) == ERROR_SUCCESS && buf.Size() == dataSize; +} + +void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined) +{ + windowPosDefined = false; + panelInfoDefined = false; + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + CByteBuffer buf; + if (QueryBuf(key, kPositionValueName, buf, kWindowPositionHeaderSize)) + { + Get32_LONG(buf, rect.left) + Get32_LONG(buf + 4, rect.top) + Get32_LONG(buf + 8, rect.right) + Get32_LONG(buf + 12, rect.bottom) + GetBool(buf + 16, maximized) + windowPosDefined = true; + } + if (QueryBuf(key, kPanelsInfoValueName, buf, kPanelsInfoHeaderSize)) + { + Get32(buf, numPanels) + Get32(buf + 4, currentPanel) + Get32(buf + 8, splitterPos) + panelInfoDefined = true; + } + return; +} + + +static void SaveUi32Val(const TCHAR *name, UInt32 value) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(name, value); +} + +static bool ReadUi32Val(const TCHAR *name, UInt32 &value) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return key.GetValue_UInt32_IfOk(name, value) == ERROR_SUCCESS; +} + +void SaveToolbarsMask(UInt32 toolbarMask) +{ + SaveUi32Val(kToolbars, toolbarMask); +} + +static const UInt32 kDefaultToolbarMask = ((UInt32)1 << 31) | 8 | 4 | 1; + +UInt32 ReadToolbarsMask() +{ + UInt32 mask; + if (!ReadUi32Val(kToolbars, mask)) + return kDefaultToolbarMask; + return mask; +} + + +void CListMode::Save() const +{ + UInt32 t = 0; + for (int i = 0; i < 2; i++) + t |= (Panels[i] & 0xFF) << (i * 8); + SaveUi32Val(kListMode, t); +} + +void CListMode::Read() +{ + Init(); + UInt32 t; + if (!ReadUi32Val(kListMode, t)) + return; + for (int i = 0; i < 2; i++) + { + Panels[i] = t & 0xFF; + t >>= 8; + } +} + +static UString GetPanelPathName(UInt32 panelIndex) +{ + UString s (kPanelPathValueName); + s.Add_UInt32(panelIndex); + return s; +} + +void SavePanelPath(UInt32 panel, const UString &path) +{ + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(GetPanelPathName(panel), path); +} + +bool ReadPanelPath(UInt32 panel, UString &path) +{ + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); +} + + +static void SaveStringList(LPCTSTR valueName, const UStringVector &folders) +{ + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue_Strings(valueName, folders); +} + +static void ReadStringList(LPCTSTR valueName, UStringVector &folders) +{ + folders.Clear(); + NSynchronization::CCriticalSectionLock lock(g_CS); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + key.GetValue_Strings(valueName, folders); +} + +void SaveFolderHistory(const UStringVector &folders) + { SaveStringList(kFolderHistoryValueName, folders); } +void ReadFolderHistory(UStringVector &folders) + { ReadStringList(kFolderHistoryValueName, folders); } + +void SaveFastFolders(const UStringVector &folders) + { SaveStringList(kFastFoldersValueName, folders); } +void ReadFastFolders(UStringVector &folders) + { ReadStringList(kFastFoldersValueName, folders); } + +void SaveCopyHistory(const UStringVector &folders) + { SaveStringList(kCopyHistoryValueName, folders); } +void ReadCopyHistory(UStringVector &folders) + { ReadStringList(kCopyHistoryValueName, folders); } + +void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s) +{ + for (unsigned i = 0; i < list.Size();) + if (s.IsEqualTo_NoCase(list[i])) + list.Delete(i); + else + i++; + list.Insert(0, s); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/ViewSettings.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/ViewSettings.h 2015-01-02 17:23:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/ViewSettings.h 2023-01-10 18:00:00.000000000 +0000 @@ -1,109 +1,115 @@ -// ViewSettings.h - -#ifndef __VIEW_SETTINGS_H -#define __VIEW_SETTINGS_H - -#include "../../../Common/MyTypes.h" -#include "../../../Common/MyString.h" - -struct CColumnInfo -{ - PROPID PropID; - bool IsVisible; - UInt32 Width; - - bool IsEqual(const CColumnInfo &a) const - { - return PropID == a.PropID && IsVisible == a.IsVisible && Width == a.Width; - } -}; - -struct CListViewInfo -{ - CRecordVector Columns; - PROPID SortID; - bool Ascending; - - void Clear() - { - SortID = 0; - Ascending = true; - Columns.Clear(); - } - - /* - int FindColumnWithID(PROPID propID) const - { - FOR_VECTOR (i, Columns) - if (Columns[i].PropID == propID) - return i; - return -1; - } - */ - - bool IsEqual(const CListViewInfo &info) const - { - if (Columns.Size() != info.Columns.Size() || - SortID != info.SortID || - Ascending != info.Ascending) - return false; - FOR_VECTOR (i, Columns) - if (!Columns[i].IsEqual(info.Columns[i])) - return false; - return true; - } - - void Save(const UString &id) const; - void Read(const UString &id); -}; - - -#ifdef _WIN32 -struct CWindowInfo -{ - RECT rect; - bool maximized; - - UInt32 numPanels; - UInt32 currentPanel; - UInt32 splitterPos; - - void Save() const; - void Read(bool &windowPosDefined, bool &panelInfoDefined); -}; -#endif - -void SaveToolbarsMask(UInt32 toolbarMask); -UInt32 ReadToolbarsMask(); - -const UInt32 kListMode_Report = 3; - -struct CListMode -{ - UInt32 Panels[2]; - - void Init() { Panels[0] = Panels[1] = kListMode_Report; } - CListMode() { Init(); } - - void Save() const ; - void Read(); -}; - - - -void SavePanelPath(UInt32 panel, const UString &path); -bool ReadPanelPath(UInt32 panel, UString &path); - - -void SaveFolderHistory(const UStringVector &folders); -void ReadFolderHistory(UStringVector &folders); - -void SaveFastFolders(const UStringVector &folders); -void ReadFastFolders(UStringVector &folders); - -void SaveCopyHistory(const UStringVector &folders); -void ReadCopyHistory(UStringVector &folders); - -void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s); - -#endif +// ViewSettings.h + +#ifndef ZIP7_INC_VIEW_SETTINGS_H +#define ZIP7_INC_VIEW_SETTINGS_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +struct CColumnInfo +{ + PROPID PropID; + bool IsVisible; + UInt32 Width; + + bool IsEqual(const CColumnInfo &a) const + { + return PropID == a.PropID && IsVisible == a.IsVisible && Width == a.Width; + } +}; + +struct CListViewInfo +{ + CRecordVector Columns; + PROPID SortID; + bool Ascending; + bool IsLoaded; + + void Clear() + { + SortID = 0; + Ascending = true; + IsLoaded = false; + Columns.Clear(); + } + + CListViewInfo(): + SortID(0), + Ascending(true), + IsLoaded(false) + {} + + /* + int FindColumnWithID(PROPID propID) const + { + FOR_VECTOR (i, Columns) + if (Columns[i].PropID == propID) + return i; + return -1; + } + */ + + bool IsEqual(const CListViewInfo &info) const + { + if (Columns.Size() != info.Columns.Size() || + SortID != info.SortID || + Ascending != info.Ascending) + return false; + FOR_VECTOR (i, Columns) + if (!Columns[i].IsEqual(info.Columns[i])) + return false; + return true; + } + + void Save(const UString &id) const; + void Read(const UString &id); +}; + + +struct CWindowInfo +{ + RECT rect; + bool maximized; + + UInt32 numPanels; + UInt32 currentPanel; + UInt32 splitterPos; + + void Save() const; + void Read(bool &windowPosDefined, bool &panelInfoDefined); +}; + +void SaveToolbarsMask(UInt32 toolbarMask); +UInt32 ReadToolbarsMask(); + +const UInt32 kListMode_Report = 3; + +struct CListMode +{ + UInt32 Panels[2]; + + void Init() { Panels[0] = Panels[1] = kListMode_Report; } + CListMode() { Init(); } + + void Save() const ; + void Read(); +}; + + + +void SavePanelPath(UInt32 panel, const UString &path); +bool ReadPanelPath(UInt32 panel, UString &path); + + +void SaveFolderHistory(const UStringVector &folders); +void ReadFolderHistory(UStringVector &folders); + +void SaveFastFolders(const UStringVector &folders); +void ReadFastFolders(UStringVector &folders); + +void SaveCopyHistory(const UStringVector &folders); +void ReadCopyHistory(UStringVector &folders); + +void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/makefile 2015-10-03 20:18:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,10 +1,110 @@ - -TARGET_FLAGS=`wx-config --unicode=yes --cxxflags` - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LIBS=`wx-config --unicode=yes --libs` $(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb - +PROG = 7zFM.exe +CFLAGS = $(CFLAGS) \ + -DZ7_EXTERNAL_CODECS \ + +# -DZ7_NO_LARGE_PAGES + +!include "FM.mak" + +COMMON_OBJS = \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = $(WIN_OBJS) \ + $O\Clipboard.obj \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\MemoryGlobal.obj \ + $O\MemoryLock.obj \ + $O\Menu.obj \ + $O\ProcessUtils.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\TimeUtils.obj \ + $O\Window.obj \ + + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + $O\PropertyPage.obj \ + $O\Window2.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodProps.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveName.obj \ + $O\ArchiveOpenCallback.obj \ + $O\CompressCall.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +EXPLORER_OBJS = \ + $O\ContextMenu.obj \ + $O\MyMessages.obj \ + $O\RegistryContextMenu.obj \ + +GUI_OBJS = \ + $O\HashGUI.obj \ + $O\UpdateCallbackGUI2.obj \ + +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + + +C_OBJS = $(C_OBJS) \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\Threads.obj \ + +!include "../../Sort.mak" +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,559 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7zFM_do_not_use$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DLANG \ - -DNEW_FOLDER_INTERFACE \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/UI/Agent/Agent.cpp \ - ../../../../CPP/7zip/UI/Agent/AgentOut.cpp \ - ../../../../CPP/7zip/UI/Agent/AgentProxy.cpp \ - ../../../../CPP/7zip/UI/Agent/ArchiveFolder.cpp \ - ../../../../CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp \ - ../../../../CPP/7zip/UI/Agent/ArchiveFolderOut.cpp \ - ../../../../CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveName.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/CompressCall.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Common/WorkDir.cpp \ - ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp \ - ../../../../CPP/7zip/UI/FileManager/App.cpp \ - ../../../../CPP/7zip/UI/FileManager/ClassDefs.cpp \ - ../../../../CPP/7zip/UI/FileManager/ComboDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/ComboDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/CopyDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/CopyDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp \ - ../../../../CPP/7zip/UI/FileManager/FM.cpp \ - ../../../../CPP/7zip/UI/FileManager/FM_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/FSDrives.cpp \ - ../../../../CPP/7zip/UI/FileManager/FSFolder.cpp \ - ../../../../CPP/7zip/UI/FileManager/FSFolderCopy.cpp \ - ../../../../CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp \ - ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/ListViewDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/MessagesDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/MyLoadMenu.cpp \ - ../../../../CPP/7zip/UI/FileManager/OpenCallback.cpp \ - ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/Panel.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelCopy.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelCrc.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelFolderChange.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelItemOpen.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelItems.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelListNotify.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelMenu.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelOperations.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelSelect.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelSort.cpp \ - ../../../../CPP/7zip/UI/FileManager/PanelSplitFile.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp \ - ../../../../CPP/7zip/UI/FileManager/RegistryUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/RootFolder.cpp \ - ../../../../CPP/7zip/UI/FileManager/SplitDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/SplitDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/SysIconUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/TextPairs.cpp \ - ../../../../CPP/7zip/UI/FileManager/UpdateCallback100.cpp \ - ../../../../CPP/7zip/UI/FileManager/ViewSettings.cpp \ - ../../../../CPP/7zip/UI/FileManager/wxFM.cpp \ - ../../../../CPP/7zip/UI/GUI/HashGUI.cpp \ - ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/Lang.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/TextConfig.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/Clipboard.cpp \ - ../../../../CPP/Windows/Control/Controls.cpp \ - ../../../../CPP/Windows/Control/Dialog.cpp \ - ../../../../CPP/Windows/Control/Window2.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Registry.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/Windows/Window.cpp \ - ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Sha256.o : ../../../../C/Sha256.c - $(CC) $(CFLAGS) ../../../../C/Sha256.c -Sort.o : ../../../../C/Sort.c - $(CC) $(CFLAGS) ../../../../C/Sort.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -Agent.o : ../../../../CPP/7zip/UI/Agent/Agent.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/Agent.cpp -AgentOut.o : ../../../../CPP/7zip/UI/Agent/AgentOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/AgentOut.cpp -AgentProxy.o : ../../../../CPP/7zip/UI/Agent/AgentProxy.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/AgentProxy.cpp -ArchiveFolder.o : ../../../../CPP/7zip/UI/Agent/ArchiveFolder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/ArchiveFolder.cpp -ArchiveFolderOpen.o : ../../../../CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp -ArchiveFolderOut.o : ../../../../CPP/7zip/UI/Agent/ArchiveFolderOut.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/ArchiveFolderOut.cpp -UpdateCallbackAgent.o : ../../../../CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveName.o : ../../../../CPP/7zip/UI/Common/ArchiveName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveName.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -CompressCall.o : ../../../../CPP/7zip/UI/Common/CompressCall.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/CompressCall.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -EnumDirItems.o : ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -HashCalc.o : ../../../../CPP/7zip/UI/Common/HashCalc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/HashCalc.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -SetProperties.o : ../../../../CPP/7zip/UI/Common/SetProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SetProperties.cpp -SortUtils.o : ../../../../CPP/7zip/UI/Common/SortUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SortUtils.cpp -UpdateAction.o : ../../../../CPP/7zip/UI/Common/UpdateAction.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateAction.cpp -UpdateCallback.o : ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp -UpdatePair.o : ../../../../CPP/7zip/UI/Common/UpdatePair.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdatePair.cpp -UpdateProduce.o : ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp -WorkDir.o : ../../../../CPP/7zip/UI/Common/WorkDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/WorkDir.cpp -ZipRegistry.o : ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp -App.o : ../../../../CPP/7zip/UI/FileManager/App.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/App.cpp -ClassDefs.o : ../../../../CPP/7zip/UI/FileManager/ClassDefs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ClassDefs.cpp -ComboDialog.o : ../../../../CPP/7zip/UI/FileManager/ComboDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ComboDialog.cpp -ComboDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/ComboDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ComboDialog_rc.cpp -CopyDialog.o : ../../../../CPP/7zip/UI/FileManager/CopyDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/CopyDialog.cpp -CopyDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/CopyDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/CopyDialog_rc.cpp -ExtractCallback.o : ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp -FM.o : ../../../../CPP/7zip/UI/FileManager/FM.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FM.cpp -FM_rc.o : ../../../../CPP/7zip/UI/FileManager/FM_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FM_rc.cpp -FSDrives.o : ../../../../CPP/7zip/UI/FileManager/FSDrives.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FSDrives.cpp -FSFolder.o : ../../../../CPP/7zip/UI/FileManager/FSFolder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FSFolder.cpp -FSFolderCopy.o : ../../../../CPP/7zip/UI/FileManager/FSFolderCopy.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FSFolderCopy.cpp -FileFolderPluginOpen.o : ../../../../CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp -FormatUtils.o : ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp -LangUtils.o : ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp -ListViewDialog.o : ../../../../CPP/7zip/UI/FileManager/ListViewDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ListViewDialog.cpp -ListViewDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp -MessagesDialog.o : ../../../../CPP/7zip/UI/FileManager/MessagesDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/MessagesDialog.cpp -MessagesDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp -MyLoadMenu.o : ../../../../CPP/7zip/UI/FileManager/MyLoadMenu.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/MyLoadMenu.cpp -OpenCallback.o : ../../../../CPP/7zip/UI/FileManager/OpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/OpenCallback.cpp -OverwriteDialog.o : ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp -OverwriteDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp -Panel.o : ../../../../CPP/7zip/UI/FileManager/Panel.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/Panel.cpp -PanelCopy.o : ../../../../CPP/7zip/UI/FileManager/PanelCopy.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelCopy.cpp -PanelCrc.o : ../../../../CPP/7zip/UI/FileManager/PanelCrc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelCrc.cpp -PanelFolderChange.o : ../../../../CPP/7zip/UI/FileManager/PanelFolderChange.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelFolderChange.cpp -PanelItemOpen.o : ../../../../CPP/7zip/UI/FileManager/PanelItemOpen.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelItemOpen.cpp -PanelItems.o : ../../../../CPP/7zip/UI/FileManager/PanelItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelItems.cpp -PanelListNotify.o : ../../../../CPP/7zip/UI/FileManager/PanelListNotify.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelListNotify.cpp -PanelMenu.o : ../../../../CPP/7zip/UI/FileManager/PanelMenu.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelMenu.cpp -PanelOperations.o : ../../../../CPP/7zip/UI/FileManager/PanelOperations.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelOperations.cpp -PanelSelect.o : ../../../../CPP/7zip/UI/FileManager/PanelSelect.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelSelect.cpp -PanelSort.o : ../../../../CPP/7zip/UI/FileManager/PanelSort.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelSort.cpp -PanelSplitFile.o : ../../../../CPP/7zip/UI/FileManager/PanelSplitFile.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PanelSplitFile.cpp -PasswordDialog.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp -PasswordDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp -ProgramLocation.o : ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp -ProgressDialog2.o : ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp -ProgressDialog2_rc.o : ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp -PropertyName.o : ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp -RegistryUtils.o : ../../../../CPP/7zip/UI/FileManager/RegistryUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/RegistryUtils.cpp -RootFolder.o : ../../../../CPP/7zip/UI/FileManager/RootFolder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/RootFolder.cpp -SplitDialog.o : ../../../../CPP/7zip/UI/FileManager/SplitDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/SplitDialog.cpp -SplitDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/SplitDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/SplitDialog_rc.cpp -SplitUtils.o : ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp -StringUtils.o : ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp -SysIconUtils.o : ../../../../CPP/7zip/UI/FileManager/SysIconUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/SysIconUtils.cpp -TextPairs.o : ../../../../CPP/7zip/UI/FileManager/TextPairs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/TextPairs.cpp -UpdateCallback100.o : ../../../../CPP/7zip/UI/FileManager/UpdateCallback100.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/UpdateCallback100.cpp -ViewSettings.o : ../../../../CPP/7zip/UI/FileManager/ViewSettings.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ViewSettings.cpp -wxFM.o : ../../../../CPP/7zip/UI/FileManager/wxFM.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/wxFM.cpp -HashGUI.o : ../../../../CPP/7zip/UI/GUI/HashGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/HashGUI.cpp -UpdateCallbackGUI2.o : ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CrcReg.o : ../../../../CPP/Common/CrcReg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CrcReg.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -Lang.o : ../../../../CPP/Common/Lang.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Lang.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -TextConfig.o : ../../../../CPP/Common/TextConfig.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/TextConfig.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -Clipboard.o : ../../../../CPP/Windows/Clipboard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Clipboard.cpp -Controls.o : ../../../../CPP/Windows/Control/Controls.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Controls.cpp -Dialog.o : ../../../../CPP/Windows/Control/Dialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Dialog.cpp -Window2.o : ../../../../CPP/Windows/Control/Window2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Window2.cpp -DLL.o : ../../../../CPP/Windows/DLL.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/DLL.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -Registry.o : ../../../../CPP/Windows/Registry.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Registry.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -Window.o : ../../../../CPP/Windows/Window.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Window.cpp -wine_GetXXXDefaultLangID.o : ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Alloc.o \ - CpuArch.o \ - Sha256.o \ - Sort.o \ - Threads.o \ - OutStreamWithCRC.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - LimitedStreams.o \ - MethodProps.o \ - ProgressUtils.o \ - PropId.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - CopyCoder.o \ - Agent.o \ - AgentOut.o \ - AgentProxy.o \ - ArchiveFolder.o \ - ArchiveFolderOpen.o \ - ArchiveFolderOut.o \ - UpdateCallbackAgent.o \ - ArchiveExtractCallback.o \ - ArchiveName.o \ - ArchiveOpenCallback.o \ - CompressCall.o \ - DefaultName.o \ - EnumDirItems.o \ - ExtractingFilePath.o \ - HashCalc.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - SetProperties.o \ - SortUtils.o \ - UpdateAction.o \ - UpdateCallback.o \ - UpdatePair.o \ - UpdateProduce.o \ - WorkDir.o \ - ZipRegistry.o \ - App.o \ - ClassDefs.o \ - ComboDialog.o \ - ComboDialog_rc.o \ - CopyDialog.o \ - CopyDialog_rc.o \ - ExtractCallback.o \ - FM.o \ - FM_rc.o \ - FSDrives.o \ - FSFolder.o \ - FSFolderCopy.o \ - FileFolderPluginOpen.o \ - FormatUtils.o \ - LangUtils.o \ - ListViewDialog.o \ - ListViewDialog_rc.o \ - MessagesDialog.o \ - MessagesDialog_rc.o \ - MyLoadMenu.o \ - OpenCallback.o \ - OverwriteDialog.o \ - OverwriteDialog_rc.o \ - Panel.o \ - PanelCopy.o \ - PanelCrc.o \ - PanelFolderChange.o \ - PanelItemOpen.o \ - PanelItems.o \ - PanelListNotify.o \ - PanelMenu.o \ - PanelOperations.o \ - PanelSelect.o \ - PanelSort.o \ - PanelSplitFile.o \ - PasswordDialog.o \ - PasswordDialog_rc.o \ - ProgramLocation.o \ - ProgressDialog2.o \ - ProgressDialog2_rc.o \ - PropertyName.o \ - RegistryUtils.o \ - RootFolder.o \ - SplitDialog.o \ - SplitDialog_rc.o \ - SplitUtils.o \ - StringUtils.o \ - SysIconUtils.o \ - TextPairs.o \ - UpdateCallback100.o \ - ViewSettings.o \ - wxFM.o \ - HashGUI.o \ - UpdateCallbackGUI2.o \ - CRC.o \ - CrcReg.o \ - IntToString.o \ - Lang.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - NewHandler.o \ - StringConvert.o \ - StringToInt.o \ - TextConfig.o \ - UTFConvert.o \ - Wildcard.o \ - Clipboard.o \ - Controls.o \ - Dialog.o \ - Window2.o \ - DLL.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - Registry.o \ - Synchronization.o \ - System.o \ - TimeUtils.o \ - Window.o \ - wine_GetXXXDefaultLangID.o \ - wine_date_and_time.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Add2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Add2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Add2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Add2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -static const unsigned char ADD2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x3b, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0xc0, 0x0b, 0x78, 0xef, 0xde, -0xbd, 0x8b, 0xe0, 0xac, 0x5a, 0xb5, 0xb6, 0x80, 0x6c, 0x0e, 0xc8, 0x28, -0x20, 0x07, 0x62, 0x20, 0x50, 0x18, 0x02, 0x40, 0x92, 0x64, 0x71, 0xe0, -0xa6, 0x81, 0x4c, 0x2f, 0x2f, 0x2f, 0x07, 0x72, 0x80, 0x64, 0x01, 0xf9, -0x0e, 0x85, 0x1a, 0x05, 0x01, 0x70, 0xa3, 0x70, 0x01, 0x00, 0x61, 0xed, -0x52, 0x81, 0x19, 0x73, 0x26, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, -0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/AddPNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/AddPNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/AddPNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/AddPNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -static const unsigned char ADD_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x4d, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0xa0, 0x01, 0xe0, 0xbd, 0x0b, -0x04, 0x17, 0xb0, 0x49, 0xac, 0x02, 0x82, 0xeb, 0x43, 0x5b, 0x02, 0xe4, -0xb7, 0xbb, 0x20, 0x09, 0x30, 0x03, 0x49, 0xe2, 0xd6, 0x2a, 0x24, 0xb0, -0xb6, 0x60, 0xc8, 0x4a, 0xa0, 0x7a, 0x10, 0x49, 0x82, 0xbd, 0xbc, 0xbc, -0xbc, 0x16, 0x1c, 0x24, 0x40, 0x46, 0x39, 0x92, 0x04, 0xe9, 0x81, 0x38, -0xf0, 0x12, 0x20, 0xbf, 0x61, 0x93, 0x60, 0x00, 0xf9, 0xad, 0x1c, 0x9b, -0x04, 0xcd, 0x00, 0x00, 0xa3, 0xbb, 0xae, 0x61, 0x7b, 0x93, 0x6d, 0x0f, -0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, -0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Copy2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Copy2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Copy2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Copy2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -static const unsigned char COPY2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x52, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x95, 0xce, 0x31, 0x0a, 0xc0, 0x30, 0x08, -0x40, 0x51, 0xb7, 0xdc, 0xd4, 0x4d, 0x70, 0xf3, 0x9a, 0x99, 0xec, 0xe4, -0x5d, 0x9a, 0x18, 0x68, 0xff, 0x1a, 0xc9, 0xf2, 0x79, 0x22, 0x11, 0xb9, -0x9a, 0xc9, 0x28, 0x46, 0x92, 0xd2, 0x18, 0xda, 0x54, 0xb5, 0x5e, 0xa5, -0xda, 0x59, 0xf0, 0xd4, 0x3d, 0x93, 0x61, 0x8c, 0x4d, 0xbf, 0x38, 0xe2, -0xe9, 0x6b, 0x7e, 0xae, 0x2d, 0x90, 0x11, 0x3e, 0x22, 0xb2, 0xe1, 0xfb, -0x81, 0x23, 0x00, 0x52, 0x00, 0x21, 0x5c, 0xcd, 0x0b, 0x7e, 0x4c, 0x37, -0xbb, 0x3f, 0x86, 0x84, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, -0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/CopyPNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/CopyPNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/CopyPNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/CopyPNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -static const unsigned char COPY_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x80, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0xbd, 0xd1, 0x31, 0x0e, 0x80, 0x20, 0x0c, -0x85, 0xe1, 0x6e, 0x4e, 0x5c, 0x93, 0x8d, 0xa4, 0x1b, 0xd7, 0x64, 0x2a, -0x53, 0xef, 0xe2, 0x43, 0x23, 0x12, 0xed, 0x5b, 0xe9, 0x60, 0x62, 0x7e, -0xbf, 0x00, 0x22, 0xb2, 0x7d, 0x1a, 0x0b, 0xce, 0x82, 0x31, 0x62, 0x85, -0x85, 0x4c, 0x88, 0x65, 0x42, 0x2c, 0x13, 0x82, 0x10, 0x13, 0x84, 0x85, -0x24, 0x77, 0xec, 0xdf, 0xc7, 0x8c, 0xf0, 0x92, 0x84, 0x17, 0xbd, 0x3e, -0xbe, 0xa7, 0xb1, 0x50, 0x58, 0x98, 0xe4, 0x17, 0x0a, 0x0b, 0x9d, 0xad, -0xa1, 0x24, 0xf4, 0xb9, 0x38, 0x0e, 0xa0, 0xcb, 0x39, 0x1e, 0x20, 0x52, -0x6b, 0x55, 0x39, 0xf0, 0xac, 0xb6, 0x82, 0xef, 0xbf, 0x52, 0x12, 0x42, -0x30, 0xee, 0x23, 0x04, 0x08, 0x31, 0xc0, 0x9d, 0xc7, 0x40, 0x8c, 0x00, -0x71, 0x02, 0x84, 0x81, 0xcd, 0x73, 0x02, 0xb6, 0x2b, 0x69, 0xbd, 0x15, -0x92, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, -0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Delete2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Delete2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Delete2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Delete2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -static const unsigned char DELETE2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x5a, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x9d, 0x8e, 0xc1, 0x11, 0x00, 0x21, 0x08, -0x03, 0x69, 0xc0, 0x5e, 0x6d, 0xe0, 0x0a, 0xc9, 0xc3, 0x9e, 0xf8, 0x31, -0x76, 0x73, 0x80, 0x06, 0x7d, 0xde, 0x5c, 0x46, 0xf3, 0x60, 0x27, 0x10, -0x91, 0xcf, 0x6a, 0x65, 0xae, 0xa9, 0x34, 0x9f, 0x61, 0x6c, 0x8b, 0x19, -0xa0, 0xcb, 0x92, 0x60, 0xc4, 0xef, 0x44, 0xfe, 0x6c, 0x6f, 0x03, 0x0a, -0x24, 0x22, 0x58, 0x29, 0x82, 0x24, 0x2a, 0x77, 0xe6, 0x00, 0x9e, 0xc9, -0xc4, 0x83, 0xd3, 0xc0, 0xae, 0x06, 0xbe, 0xaa, 0x55, 0x03, 0xa3, 0x05, -0xea, 0xb4, 0x1f, 0x7a, 0x01, 0xc5, 0x78, 0x3b, 0x10, 0xc3, 0x1f, 0xc3, -0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, -0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/DeletePNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/DeletePNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/DeletePNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/DeletePNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -static const unsigned char DELETE_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x81, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0xc5, 0xd1, 0xc1, 0x0d, 0x80, 0x30, 0x08, -0x05, 0x50, 0x17, 0x60, 0x57, 0xd7, 0xe1, 0xd0, 0x9d, 0x7a, 0x23, 0x6e, -0x63, 0x2c, 0x14, 0x2d, 0xff, 0x7b, 0x55, 0x2e, 0xfd, 0x31, 0xbc, 0x58, -0xe8, 0xb6, 0x7d, 0x57, 0x1d, 0x82, 0x97, 0xb4, 0x1a, 0xa2, 0x0e, 0xed, -0x25, 0x44, 0x9f, 0x6a, 0x5b, 0x43, 0x02, 0xf5, 0xce, 0x0c, 0xb7, 0x18, -0x9d, 0xe3, 0xdc, 0x09, 0xb9, 0x0e, 0x5b, 0x6f, 0x35, 0x08, 0x82, 0x20, -0x08, 0x82, 0x10, 0xe0, 0x84, 0x00, 0x27, 0x0c, 0x04, 0x41, 0xc0, 0x66, -0x78, 0x8a, 0x8e, 0xdf, 0xe3, 0x1f, 0x2f, 0x80, 0x90, 0x9c, 0x83, 0x01, -0xab, 0xbb, 0xcd, 0x2b, 0x09, 0x92, 0xd8, 0x12, 0x90, 0x39, 0x03, 0x90, -0x5c, 0x2b, 0x79, 0x41, 0x1f, 0x5a, 0xf0, 0x05, 0xad, 0x84, 0x49, 0x66, -0x9f, 0xd4, 0x75, 0x19, 0x84, 0x3f, 0xeb, 0x04, 0x1a, 0xa7, 0x7e, 0xab, -0x5a, 0xf7, 0xe4, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, -0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Extract2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Extract2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Extract2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Extract2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -static const unsigned char EXTRACT2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x22, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0xa0, 0x17, 0xe0, 0xbd, 0x0b, -0x05, 0x17, 0x40, 0x9c, 0x33, 0x50, 0x70, 0x9d, 0x5c, 0x0e, 0xcc, 0x34, -0x10, 0x87, 0xa1, 0x1c, 0x06, 0xe8, 0xe6, 0x1b, 0x00, 0xa6, 0x78, 0x38, -0x15, 0x21, 0xee, 0x22, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, -0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/ExtractPNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ExtractPNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/ExtractPNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ExtractPNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -static const unsigned char EXTRACT_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x28, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0x18, 0x05, 0xa4, 0x81, 0xbb, -0x28, 0x00, 0x49, 0xe2, 0xce, 0x19, 0x24, 0x70, 0xb6, 0x60, 0xc8, 0x4a, -0xa0, 0x7a, 0x10, 0x49, 0x82, 0xbd, 0x1c, 0x19, 0x20, 0x49, 0x8c, 0x02, -0x8a, 0x00, 0x00, 0x11, 0x6c, 0x7c, 0x67, 0x00, 0x94, 0xd4, 0x2c, 0x00, -0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Info2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Info2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Info2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Info2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -static const unsigned char INFO2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x46, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0x40, 0x07, 0xbc, 0x77, 0xef, -0x5e, 0x40, 0x70, 0x76, 0xef, 0xbe, 0x8e, 0x83, 0x73, 0xf7, 0x2e, 0x82, -0xc3, 0x50, 0x5e, 0x5e, 0x8e, 0x61, 0x10, 0x54, 0x15, 0xc2, 0x34, 0xa0, -0x7e, 0x84, 0x01, 0xbc, 0x77, 0x91, 0x4d, 0xab, 0xc5, 0x6d, 0x0f, 0xe9, -0x1c, 0x90, 0xd1, 0x70, 0x5b, 0x41, 0x96, 0xc2, 0xa5, 0x40, 0xce, 0x41, -0x38, 0xbb, 0xbc, 0x1c, 0x97, 0xb3, 0x09, 0x03, 0x00, 0x3a, 0xb2, 0x32, -0x23, 0xbc, 0x78, 0x77, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, -0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/InfoPNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/InfoPNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/InfoPNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/InfoPNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -static const unsigned char INFO_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x57, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x60, 0xa0, 0x05, 0xb8, 0x0b, 0x04, -0x17, 0xb0, 0x49, 0xdc, 0xde, 0xbd, 0x7b, 0xf7, 0x75, 0xea, 0x48, 0x80, -0xec, 0xc0, 0x2a, 0xc1, 0x5e, 0x0e, 0x04, 0xc4, 0xba, 0x94, 0x2c, 0xc0, -0x7b, 0x17, 0x87, 0x07, 0x79, 0x77, 0xef, 0xc6, 0xee, 0x5c, 0xdc, 0x12, -0x77, 0x71, 0x79, 0xb0, 0x9c, 0x8a, 0x61, 0x35, 0x18, 0x25, 0x20, 0x3e, -0xbf, 0x7b, 0x17, 0x53, 0x02, 0x1c, 0x56, 0xbb, 0xf7, 0x16, 0x10, 0x2f, -0x71, 0x17, 0x02, 0x30, 0x24, 0x18, 0xca, 0x21, 0x00, 0x53, 0x62, 0x30, -0x01, 0x00, 0xd3, 0xa5, 0x67, 0xc0, 0x11, 0x9d, 0x79, 0xc0, 0x00, 0x00, -0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Move2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Move2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Move2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Move2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -static const unsigned char MOVE2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x4c, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x95, 0xce, 0xb1, 0x0d, 0xc0, 0x20, 0x0c, -0x44, 0xd1, 0xeb, 0xb2, 0x18, 0xad, 0x77, 0xa1, 0x63, 0x4d, 0x0a, 0x4b, -0xa9, 0xbc, 0x4b, 0x82, 0x41, 0xf0, 0x5b, 0xae, 0xfb, 0x3c, 0xc9, 0x42, -0xba, 0x5a, 0x67, 0x04, 0xc3, 0x49, 0x6e, 0x8c, 0x92, 0x14, 0x39, 0x2f, -0x36, 0xdf, 0xd6, 0x3a, 0xc3, 0x18, 0x83, 0x8e, 0x54, 0xc4, 0xcb, 0x6b, -0x3f, 0xe8, 0x69, 0x63, 0x9e, 0xb0, 0x7f, 0x50, 0x11, 0x00, 0x05, 0x40, -0x84, 0xab, 0x7d, 0xa9, 0x14, 0x30, 0x23, 0x6c, 0x8b, 0xd3, 0x1c, 0x00, -0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/MovePNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/MovePNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/MovePNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/MovePNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -static const unsigned char MOVE_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x71, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0xbd, 0xd1, 0xb1, 0x0d, 0xc0, 0x20, 0x0c, -0x05, 0x51, 0x2f, 0xc0, 0x56, 0x6e, 0xd9, 0x85, 0x2e, 0x6b, 0x52, 0x58, -0xa2, 0x62, 0x97, 0x98, 0x22, 0x84, 0x10, 0x5f, 0xcb, 0x6f, 0x4f, 0x4f, -0x08, 0x10, 0x39, 0xbe, 0x4a, 0xa1, 0x53, 0x30, 0x22, 0x96, 0x29, 0x28, -0x10, 0x53, 0x20, 0xa6, 0x40, 0x3c, 0xc4, 0xc4, 0xc3, 0x42, 0x52, 0x9f, -0x1b, 0xe1, 0x25, 0x49, 0xbf, 0xab, 0x14, 0x32, 0x85, 0x49, 0x7e, 0x21, -0x53, 0x68, 0x74, 0x46, 0x81, 0xd0, 0xe6, 0xe1, 0xdb, 0x3d, 0x1e, 0x20, -0x72, 0xcd, 0xd9, 0x0a, 0xf6, 0xb7, 0x2a, 0x10, 0x42, 0x30, 0xfe, 0x23, -0x04, 0x1e, 0x62, 0xe0, 0x7f, 0x1e, 0x03, 0x31, 0x00, 0xd2, 0x01, 0x08, -0x81, 0xc3, 0xbb, 0x01, 0xf5, 0x5d, 0x59, 0xea, 0x53, 0xc3, 0x86, 0x77, -0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, -0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/ParentFolder.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ParentFolder.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/ParentFolder.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/ParentFolder.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -static unsigned char PARENT_FOLDER_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, -0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, 0x53, 0x00, 0x00, 0x03, -0x00, 0x50, 0x4c, 0x54, 0x45, 0x01, 0x67, 0x01, 0x08, 0x6e, 0x05, 0x08, -0x77, 0x04, 0x0c, 0x79, 0x07, 0x11, 0x70, 0x0a, 0x11, 0x7c, 0x09, 0x16, -0x7c, 0x0c, 0x17, 0x79, 0x13, 0x1f, 0x78, 0x1f, 0x37, 0x7a, 0x0b, 0x21, -0x7d, 0x21, 0x14, 0x8c, 0x0b, 0x19, 0x98, 0x0d, 0x1c, 0xa0, 0x0f, 0x22, -0x81, 0x17, 0x27, 0x8c, 0x14, 0x27, 0x8f, 0x14, 0x26, 0x8b, 0x1a, 0x27, -0x8c, 0x1b, 0x2f, 0x94, 0x1f, 0x31, 0x81, 0x1b, 0x2f, 0x81, 0x2f, 0x3b, -0x85, 0x2e, 0x3d, 0x8a, 0x3d, 0x3e, 0x8a, 0x3f, 0x3c, 0xa1, 0x1f, 0x34, -0xb3, 0x1b, 0x41, 0x8c, 0x3e, 0x51, 0x8e, 0x29, 0x43, 0xad, 0x22, 0x44, -0xb7, 0x22, 0x49, 0xbd, 0x25, 0x59, 0xbe, 0x39, 0x61, 0x93, 0x2e, 0x4e, -0x8f, 0x41, 0x6b, 0xa5, 0x6c, 0x6c, 0xa6, 0x6d, 0x79, 0xad, 0x7a, 0x57, -0xc4, 0x2c, 0x67, 0xcc, 0x34, 0x6c, 0xd1, 0x39, 0x60, 0xc5, 0x40, 0x75, -0xda, 0x42, 0x74, 0xd8, 0x47, 0x7f, 0xe3, 0x4c, 0xb9, 0x9c, 0x11, 0x81, -0xac, 0x47, 0x85, 0xea, 0x53, 0x8e, 0xf4, 0x5c, 0xcc, 0x99, 0x01, 0xd6, -0xa5, 0x17, 0xd1, 0xa4, 0x1e, 0xd3, 0xa9, 0x2c, 0xdd, 0xaf, 0x35, 0xde, -0xb5, 0x36, 0xdf, 0xba, 0x3c, 0xe6, 0xbc, 0x3e, 0xde, 0xbe, 0x51, 0xd9, -0xb9, 0x58, 0xdb, 0xbe, 0x66, 0xe2, 0xb8, 0x43, 0xe6, 0xbc, 0x51, 0xdf, -0xc3, 0x6b, 0xe6, 0xc2, 0x44, 0xec, 0xc6, 0x4e, 0xea, 0xc0, 0x57, 0xf2, -0xcc, 0x5b, 0xe2, 0xc6, 0x71, 0xe6, 0xc9, 0x79, 0xe6, 0xd1, 0x63, 0xf2, -0xd5, 0x64, 0xf5, 0xdf, 0x79, 0xff, 0xdc, 0x77, 0xef, 0xe0, 0x7b, 0xfc, -0xe4, 0x7c, 0x89, 0xb7, 0x8b, 0x8f, 0xbc, 0x87, 0xb7, 0xd3, 0xba, 0xdf, -0xec, 0x86, 0xdf, 0xe6, 0xaf, 0xe3, 0xce, 0x92, 0xe4, 0xd3, 0x9e, 0xe4, -0xd4, 0x9e, 0xec, 0xd9, 0x99, 0xec, 0xd9, 0x9f, 0xfc, 0xd4, 0x83, 0xff, -0xdb, 0x89, 0xe5, 0xd6, 0xa3, 0xe5, 0xd7, 0xab, 0xef, 0xdf, 0xab, 0xff, -0xe8, 0x83, 0xff, 0xea, 0x95, 0xff, 0xf2, 0x8c, 0xff, 0xf9, 0x93, 0xff, -0xff, 0x99, 0xef, 0xf5, 0xbc, 0xf2, 0xe6, 0xa4, 0xff, 0xe6, 0xa0, 0xff, -0xf2, 0xa9, 0xff, 0xf8, 0xa6, 0xff, 0xff, 0xac, 0xff, 0xff, 0xbe, 0xc6, -0xdb, 0xc9, 0xd6, 0xe3, 0xd9, 0xea, 0xe2, 0xca, 0xeb, 0xe7, 0xd6, 0xee, -0xea, 0xdb, 0xf5, 0xea, 0xc1, 0xff, 0xf4, 0xc8, 0xff, 0xfe, 0xc6, 0xfc, -0xf9, 0xcf, 0xff, 0xff, 0xd1, 0xff, 0xff, 0xd9, 0xe5, 0xed, 0xe9, 0xff, -0xff, 0xe7, 0xf3, 0xf4, 0xf7, 0xff, 0xff, 0xf2, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xd0, 0xf6, 0xa4, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, -0x0e, 0xc4, 0x01, 0x95, 0x2b, 0x0e, 0x1b, 0x00, 0x00, 0x00, 0xc1, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x28, 0x86, 0x02, 0x15, 0x89, 0x74, -0x30, 0xcd, 0x00, 0xe5, 0xfb, 0x32, 0xf1, 0xb0, 0x7b, 0x23, 0x09, 0x14, -0x72, 0xf1, 0x4a, 0xc9, 0x09, 0x88, 0xa6, 0xc1, 0x05, 0x94, 0xb9, 0xa5, -0xe4, 0xd5, 0xd4, 0x25, 0x19, 0x55, 0xc1, 0x02, 0xa6, 0xa6, 0xa6, 0x0c, -0xcc, 0xac, 0xb2, 0xea, 0x1a, 0x1c, 0xac, 0xac, 0x20, 0x01, 0xd3, 0xe0, -0xbc, 0x78, 0xa0, 0x18, 0xbf, 0x86, 0x96, 0x38, 0xc4, 0x0c, 0xd3, 0xdc, -0xb8, 0xb8, 0xd4, 0xfc, 0x5c, 0x36, 0x2d, 0x1d, 0x31, 0xa8, 0x40, 0x72, -0x2c, 0x10, 0x98, 0x72, 0xea, 0x68, 0x2b, 0x99, 0x9a, 0x82, 0x05, 0xa2, -0xbd, 0xdc, 0xec, 0xcd, 0x43, 0xa4, 0xf5, 0x15, 0x7c, 0x4a, 0xec, 0xc0, -0x02, 0x61, 0x36, 0x91, 0x45, 0x05, 0xb9, 0x7c, 0x06, 0x82, 0xfe, 0x09, -0xe1, 0x60, 0x81, 0x50, 0xe7, 0x94, 0xb8, 0x38, 0x3f, 0x61, 0x4d, 0xc5, -0x24, 0x4b, 0x88, 0x19, 0x8e, 0xd9, 0x31, 0x31, 0x31, 0x7a, 0x42, 0x22, -0x9e, 0xee, 0x01, 0x10, 0x01, 0xdb, 0x9c, 0xa8, 0xa8, 0x28, 0x16, 0x19, -0x57, 0x07, 0xb3, 0x2c, 0x88, 0x80, 0x4b, 0xa2, 0x87, 0x93, 0x85, 0xae, -0xa1, 0xb1, 0x55, 0x10, 0xd4, 0xda, 0x10, 0x23, 0x43, 0x13, 0xeb, 0xc0, -0x8c, 0x62, 0x98, 0x6f, 0x4d, 0x4d, 0x23, 0x32, 0x8b, 0xe1, 0x00, 0x00, -0xfc, 0x33, 0x50, 0x72, 0x6d, 0x03, 0x36, 0xf2, 0x00, 0x00, 0x00, 0x00, -0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Test2PNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Test2PNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/Test2PNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/Test2PNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -static const unsigned char TEST2_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, -0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, 0xcb, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x47, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0xb5, 0xcd, 0xbb, 0x11, 0x00, 0x20, 0x08, -0x03, 0x50, 0x16, 0x60, 0x57, 0x47, 0xb5, 0xb3, 0xc2, 0x0d, 0xcc, 0x0c, -0x22, 0x9f, 0xc3, 0xde, 0x33, 0x05, 0x29, 0x5e, 0xee, 0x20, 0xfa, 0x1e, -0x16, 0x91, 0x1e, 0x97, 0x26, 0xb0, 0x9a, 0x17, 0x31, 0x80, 0x71, 0x06, -0xda, 0x3d, 0xc0, 0x29, 0xc0, 0x29, 0xc1, 0x28, 0xc1, 0x29, 0xc1, 0x68, -0xd4, 0xc7, 0x0b, 0x94, 0x0a, 0x94, 0x2e, 0x78, 0xc9, 0x06, 0xae, 0xb5, -0x39, 0x27, 0x85, 0x82, 0xfa, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, -0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/TestPNG.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/TestPNG.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/res/TestPNG.h 2008-08-17 17:40:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/res/TestPNG.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -static const unsigned char TEST_png[] = { -0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, -0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x24, -0x04, 0x03, 0x00, 0x00, 0x00, 0x3d, 0x6b, 0xa4, 0x39, 0x00, 0x00, 0x00, -0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, -0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, -0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, -0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, -0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x14, 0x3b, 0x9d, 0x00, 0x00, 0x00, -0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, -0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0xea, 0x65, 0x16, 0xa4, 0x00, 0x00, 0x00, 0x75, 0x49, -0x44, 0x41, 0x54, 0x78, 0x9c, 0xd5, 0xd1, 0x31, 0x1a, 0x80, 0x20, 0x08, -0x05, 0x60, 0xc7, 0x96, 0xee, 0xdb, 0xd8, 0x05, 0xb8, 0x9b, 0x9b, 0x53, -0xdd, 0xa0, 0xce, 0x10, 0x20, 0xfa, 0x55, 0xef, 0xd5, 0x2e, 0x23, 0xf2, -0x2b, 0x60, 0x4a, 0x63, 0xc4, 0x66, 0x91, 0x31, 0x3f, 0x9f, 0x1a, 0xc7, -0x82, 0x07, 0xbb, 0x1d, 0x94, 0xf5, 0x1f, 0xdc, 0x6f, 0x7d, 0x00, 0xf1, -0x2a, 0xf2, 0xc2, 0xe4, 0x65, 0x99, 0xbc, 0xd0, 0xc9, 0xbb, 0xa5, 0x4e, -0xa0, 0xa5, 0x20, 0x38, 0x43, 0x10, 0x32, 0x43, 0x25, 0x64, 0xe8, 0x4a, -0xd8, 0xd0, 0x12, 0x79, 0xd8, 0x52, 0x23, 0xb8, 0x25, 0xe1, 0xa0, 0x11, -0xb2, 0x56, 0x27, 0xec, 0x1f, 0x9c, 0x30, 0x60, 0x84, 0x02, 0x23, 0x1c, -0x28, 0xe1, 0x40, 0xc9, 0x07, 0x18, 0x21, 0x2e, 0x97, 0xf8, 0xa1, 0xe3, -0xf9, 0x5b, 0x6d, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, -0xae, 0x42, 0x60, 0x82, 0x00, -}; diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/resource.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/resource.h 2015-09-19 18:23:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.h 2024-11-25 14:00:00.000000000 +0000 @@ -1,175 +1,199 @@ -#include "resourceGui.h" - -#define IDR_MENUBAR1 70 -#define IDM_MENU 71 -#define IDR_ACCELERATOR1 72 - -#define IDB_ADD 100 -#define IDB_EXTRACT 101 -#define IDB_TEST 102 -#define IDB_COPY 103 -#define IDB_MOVE 104 -#define IDB_DELETE 105 -#define IDB_INFO 106 - -#define IDB_ADD2 150 -#define IDB_EXTRACT2 151 -#define IDB_TEST2 152 -#define IDB_COPY2 153 -#define IDB_MOVE2 154 -#define IDB_DELETE2 155 -#define IDB_INFO2 156 - -#define IDM_HASH_ALL 101 -#define IDM_CRC32 102 -#define IDM_CRC64 103 -#define IDM_SHA1 104 -#define IDM_SHA256 105 - -#define IDM_OPEN 540 -#define IDM_OPEN_INSIDE 541 -#define IDM_OPEN_OUTSIDE 542 -#define IDM_FILE_VIEW 543 -#define IDM_FILE_EDIT 544 -#define IDM_RENAME 545 -#define IDM_COPY_TO 546 -#define IDM_MOVE_TO 547 -#define IDM_DELETE 548 -#define IDM_SPLIT 549 -#define IDM_COMBINE 550 -#define IDM_PROPERTIES 551 -#define IDM_COMMENT 552 -#define IDM_CRC 553 -#define IDM_DIFF 554 -#define IDM_CREATE_FOLDER 555 -#define IDM_CREATE_FILE 556 -// #define IDM_EXIT 557 -#define IDM_LINK 558 -#define IDM_ALT_STREAMS 559 - -#define IDM_OPEN_INSIDE_ONE 590 -#define IDM_OPEN_INSIDE_PARSER 591 - -#define IDM_SELECT_ALL 600 -#define IDM_DESELECT_ALL 601 -#define IDM_INVERT_SELECTION 602 -#define IDM_SELECT 603 -#define IDM_DESELECT 604 -#define IDM_SELECT_BY_TYPE 605 -#define IDM_DESELECT_BY_TYPE 606 - -#define IDM_VIEW_LARGE_ICONS 700 -#define IDM_VIEW_SMALL_ICONS 701 -#define IDM_VIEW_LIST 702 -#define IDM_VIEW_DETAILS 703 - -#define IDM_VIEW_ARANGE_BY_NAME 710 -#define IDM_VIEW_ARANGE_BY_TYPE 711 -#define IDM_VIEW_ARANGE_BY_DATE 712 -#define IDM_VIEW_ARANGE_BY_SIZE 713 - -#define IDM_VIEW_ARANGE_NO_SORT 730 -#define IDM_VIEW_FLAT_VIEW 731 -#define IDM_VIEW_TWO_PANELS 732 -#define IDM_VIEW_TOOLBARS 733 -#define IDM_OPEN_ROOT_FOLDER 734 -#define IDM_OPEN_PARENT_FOLDER 735 -#define IDM_FOLDERS_HISTORY 736 -#define IDM_VIEW_REFRESH 737 -#define IDM_VIEW_AUTO_REFRESH 738 -// #define IDM_VIEW_SHOW_DELETED 739 -// #define IDM_VIEW_SHOW_STREAMS 740 - -#define IDM_VIEW_ARCHIVE_TOOLBAR 750 -#define IDM_VIEW_STANDARD_TOOLBAR 751 -#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752 -#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753 - -#define IDS_BOOKMARK 801 - -#define IDM_OPTIONS 900 -#define IDM_BENCHMARK 901 -#define IDM_BENCHMARK2 902 - -#define IDM_HELP_CONTENTS 960 -#define IDM_ABOUT 5014 /* FIXME 961 5014 = wxID_ABOUT */ - -#define IDS_OPTIONS 2100 - -#define IDS_N_SELECTED_ITEMS 3002 - -#define IDS_FILE_EXIST 3008 -#define IDS_WANT_UPDATE_MODIFIED_FILE 3009 -#define IDS_CANNOT_UPDATE_FILE 3010 -#define IDS_CANNOT_START_EDITOR 3011 -#define IDS_VIRUS 3012 -#define IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER 3013 -#define IDS_SELECT_ONE_FILE 3014 -#define IDS_SELECT_FILES 3015 -#define IDS_TOO_MANY_ITEMS 3016 - -#define IDS_COPY 6000 -#define IDS_MOVE 6001 -#define IDS_COPY_TO 6002 -#define IDS_MOVE_TO 6003 -#define IDS_COPYING 6004 -#define IDS_MOVING 6005 -#define IDS_RENAMING 6006 - -#define IDS_OPERATION_IS_NOT_SUPPORTED 6008 -#define IDS_ERROR_RENAMING 6009 -#define IDS_CONFIRM_FILE_COPY 6010 -#define IDS_WANT_TO_COPY_FILES 6011 - -#define IDS_CONFIRM_FILE_DELETE 6100 -#define IDS_CONFIRM_FOLDER_DELETE 6101 -#define IDS_CONFIRM_ITEMS_DELETE 6102 -#define IDS_WANT_TO_DELETE_FILE 6103 -#define IDS_WANT_TO_DELETE_FOLDER 6104 -#define IDS_WANT_TO_DELETE_ITEMS 6105 -#define IDS_DELETING 6106 -#define IDS_ERROR_DELETING 6107 -#define IDS_ERROR_LONG_PATH_TO_RECYCLE 6108 - -#define IDS_CREATE_FOLDER 6300 -#define IDS_CREATE_FILE 6301 -#define IDS_CREATE_FOLDER_NAME 6302 -#define IDS_CREATE_FILE_NAME 6303 -#define IDS_CREATE_FOLDER_DEFAULT_NAME 6304 -#define IDS_CREATE_FILE_DEFAULT_NAME 6305 -#define IDS_CREATE_FOLDER_ERROR 6306 -#define IDS_CREATE_FILE_ERROR 6307 - -#define IDS_COMMENT 6400 -#define IDS_COMMENT2 6401 -#define IDS_SELECT 6402 -#define IDS_DESELECT 6403 -#define IDS_SELECT_MASK 6404 - -#define IDS_PROPERTIES 6600 -#define IDS_FOLDERS_HISTORY 6601 - -#define IDS_COMPUTER 7100 -#define IDS_NETWORK 7101 -#define IDS_DOCUMENTS 7102 -#define IDS_SYSTEM 7103 - -#define IDS_ADD 7200 -#define IDS_EXTRACT 7201 -#define IDS_TEST 7202 -#define IDS_BUTTON_COPY 7203 -#define IDS_BUTTON_MOVE 7204 -#define IDS_BUTTON_DELETE 7205 -#define IDS_BUTTON_INFO 7206 - -#define IDS_SPLITTING 7303 -#define IDS_SPLIT_CONFIRM_TITLE 7304 -#define IDS_SPLIT_CONFIRM_MESSAGE 7305 -#define IDS_SPLIT_VOL_MUST_BE_SMALLER 7306 - -#define IDS_COMBINE 7400 -#define IDS_COMBINE_TO 7401 -#define IDS_COMBINING 7402 -#define IDS_COMBINE_SELECT_ONE_FILE 7403 -#define IDS_COMBINE_CANT_DETECT_SPLIT_FILE 7404 -#define IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART 7405 +#include "resourceGui.h" + +#define IDR_MENUBAR1 70 +#define IDM_MENU 71 +#define IDR_ACCELERATOR1 72 + +#define IDB_ADD 100 +#define IDB_EXTRACT 101 +#define IDB_TEST 102 +#define IDB_COPY 103 +#define IDB_MOVE 104 +#define IDB_DELETE 105 +#define IDB_INFO 106 + +#define IDB_ADD2 150 +#define IDB_EXTRACT2 151 +#define IDB_TEST2 152 +#define IDB_COPY2 153 +#define IDB_MOVE2 154 +#define IDB_DELETE2 155 +#define IDB_INFO2 156 + +#define IDM_HASH_ALL 101 +#define IDM_CRC32 102 +#define IDM_CRC64 103 +#define IDM_SHA1 104 +#define IDM_SHA256 105 +#define IDM_SHA384 106 +#define IDM_SHA512 107 +#define IDM_SHA3_256 108 +#define IDM_XXH64 120 +#define IDM_BLAKE2SP 121 +#define IDM_MD5 122 + +#define IDM_FILE 500 +#define IDM_EDIT 501 +#define IDM_VIEW 502 +#define IDM_FAVORITES 503 +#define IDM_TOOLS 504 +#define IDM_HELP 505 + +#define IDM_OPEN 540 +#define IDM_OPEN_INSIDE 541 +#define IDM_OPEN_OUTSIDE 542 +#define IDM_FILE_VIEW 543 +#define IDM_FILE_EDIT 544 +#define IDM_RENAME 545 +#define IDM_COPY_TO 546 +#define IDM_MOVE_TO 547 +#define IDM_DELETE 548 +#define IDM_SPLIT 549 +#define IDM_COMBINE 550 +#define IDM_PROPERTIES 551 +#define IDM_COMMENT 552 +#define IDM_CRC 553 +#define IDM_DIFF 554 +#define IDM_CREATE_FOLDER 555 +#define IDM_CREATE_FILE 556 +// #define IDM_EXIT 557 +#define IDM_LINK 558 +#define IDM_ALT_STREAMS 559 + +#define IDM_VER_EDIT 580 +#define IDM_VER_COMMIT 581 +#define IDM_VER_REVERT 582 +#define IDM_VER_DIFF 583 + +#define IDM_OPEN_INSIDE_ONE 590 +#define IDM_OPEN_INSIDE_PARSER 591 + +#define IDM_SELECT_ALL 600 +#define IDM_DESELECT_ALL 601 +#define IDM_INVERT_SELECTION 602 +#define IDM_SELECT 603 +#define IDM_DESELECT 604 +#define IDM_SELECT_BY_TYPE 605 +#define IDM_DESELECT_BY_TYPE 606 + +#define IDM_VIEW_LARGE_ICONS 700 +#define IDM_VIEW_SMALL_ICONS 701 +#define IDM_VIEW_LIST 702 +#define IDM_VIEW_DETAILS 703 + +#define IDM_VIEW_ARANGE_BY_NAME 710 +#define IDM_VIEW_ARANGE_BY_TYPE 711 +#define IDM_VIEW_ARANGE_BY_DATE 712 +#define IDM_VIEW_ARANGE_BY_SIZE 713 + +#define IDM_VIEW_ARANGE_NO_SORT 730 +#define IDM_VIEW_FLAT_VIEW 731 +#define IDM_VIEW_TWO_PANELS 732 +#define IDM_VIEW_TOOLBARS 733 +#define IDM_OPEN_ROOT_FOLDER 734 +#define IDM_OPEN_PARENT_FOLDER 735 +#define IDM_FOLDERS_HISTORY 736 +#define IDM_VIEW_REFRESH 737 +#define IDM_VIEW_AUTO_REFRESH 738 +// #define IDM_VIEW_SHOW_DELETED 739 +// #define IDM_VIEW_SHOW_STREAMS 740 + +#define IDM_VIEW_ARCHIVE_TOOLBAR 750 +#define IDM_VIEW_STANDARD_TOOLBAR 751 +#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752 +#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753 + +#define IDM_VIEW_TIME_POPUP 760 +#define IDM_VIEW_TIME 761 +#define IDM_VIEW_TIME_UTC 799 + +#define IDM_ADD_TO_FAVORITES 800 +#define IDS_BOOKMARK 801 + +#define IDM_OPTIONS 900 +#define IDM_BENCHMARK 901 +#define IDM_BENCHMARK2 902 +#define IDM_TEMP_DIR 910 + +#define IDM_HELP_CONTENTS 960 +#define IDM_ABOUT 961 + +#define IDS_OPTIONS 2100 + +#define IDS_N_SELECTED_ITEMS 3002 + +#define IDS_FILE_EXIST 3008 +#define IDS_WANT_UPDATE_MODIFIED_FILE 3009 +#define IDS_CANNOT_UPDATE_FILE 3010 +#define IDS_CANNOT_START_EDITOR 3011 +#define IDS_VIRUS 3012 +#define IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER 3013 +#define IDS_SELECT_ONE_FILE 3014 +#define IDS_SELECT_FILES 3015 +#define IDS_TOO_MANY_ITEMS 3016 + +#define IDS_COPY 6000 +#define IDS_MOVE 6001 +#define IDS_COPY_TO 6002 +#define IDS_MOVE_TO 6003 +#define IDS_COPYING 6004 +// #define IDS_MOVING 6005 +#define IDS_RENAMING 6006 + +#define IDS_OPERATION_IS_NOT_SUPPORTED 6008 +#define IDS_ERROR_RENAMING 6009 +#define IDS_CONFIRM_FILE_COPY 6010 +#define IDS_WANT_TO_COPY_FILES 6011 + +#define IDS_CONFIRM_FILE_DELETE 6100 +#define IDS_CONFIRM_FOLDER_DELETE 6101 +#define IDS_CONFIRM_ITEMS_DELETE 6102 +#define IDS_WANT_TO_DELETE_FILE 6103 +#define IDS_WANT_TO_DELETE_FOLDER 6104 +#define IDS_WANT_TO_DELETE_ITEMS 6105 +#define IDS_DELETING 6106 +#define IDS_ERROR_DELETING 6107 +#define IDS_ERROR_LONG_PATH_TO_RECYCLE 6108 + +#define IDS_CREATE_FOLDER 6300 +#define IDS_CREATE_FILE 6301 +#define IDS_CREATE_FOLDER_NAME 6302 +#define IDS_CREATE_FILE_NAME 6303 +#define IDS_CREATE_FOLDER_DEFAULT_NAME 6304 +#define IDS_CREATE_FILE_DEFAULT_NAME 6305 +#define IDS_CREATE_FOLDER_ERROR 6306 +#define IDS_CREATE_FILE_ERROR 6307 + +#define IDS_COMMENT 6400 +#define IDS_COMMENT2 6401 +#define IDS_SELECT 6402 +#define IDS_DESELECT 6403 +#define IDS_SELECT_MASK 6404 + +#define IDS_PROPERTIES 6600 +#define IDS_FOLDERS_HISTORY 6601 + +#define IDS_COMPUTER 7100 +#define IDS_NETWORK 7101 +#define IDS_DOCUMENTS 7102 +#define IDS_SYSTEM 7103 + +#define IDS_ADD 7200 +#define IDS_EXTRACT 7201 +#define IDS_TEST 7202 +#define IDS_BUTTON_COPY 7203 +#define IDS_BUTTON_MOVE 7204 +#define IDS_BUTTON_DELETE 7205 +#define IDS_BUTTON_INFO 7206 + +#define IDS_SPLITTING 7303 +#define IDS_SPLIT_CONFIRM_TITLE 7304 +#define IDS_SPLIT_CONFIRM_MESSAGE 7305 +#define IDS_SPLIT_VOL_MUST_BE_SMALLER 7306 + +#define IDS_COMBINE 7400 +#define IDS_COMBINE_TO 7401 +#define IDS_COMBINING 7402 +#define IDS_COMBINE_SELECT_ONE_FILE 7403 +#define IDS_COMBINE_CANT_DETECT_SPLIT_FILE 7404 +#define IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART 7405 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resource.rc 2024-11-25 14:00:00.000000000 +0000 @@ -0,0 +1,296 @@ +#include "../../MyVersionInfo.rc" +#include "../../GuiCommon.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7-Zip File Manager", "7zFM") + +IDR_ACCELERATOR1 ACCELERATORS +BEGIN +// "N", IDM_CREATE_FILE, VIRTKEY, CONTROL, NOINVERT + VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT + VK_F12, IDM_FOLDERS_HISTORY, VIRTKEY, ALT, NOINVERT +// VK_F7, IDM_CREATE_FOLDER, VIRTKEY, NOINVERT +END + +// for MENUEX: +// /* +#define MY_MENUITEM_SEPARATOR MENUITEM "", 0, MFT_SEPARATOR +#define MY_MFT_MENUBREAK MFT_MENUBREAK +#define MY_MFT_MENUBARBREAK MFT_MENUBARBREAK +#define MY_MFS_CHECKED MFT_STRING, MFS_CHECKED +#define MY_MENUITEM_ID(x) , x +// */ + +// for MENU: +/* +#define MY_MENUITEM_SEPARATOR MENUITEM SEPARATOR +#define MY_MFT_MENUBREAK MENUBREAK +#define MY_MFT_MENUBARBREAK MENUBARBREAK +#define MY_MFS_CHECKED CHECKED +#define MY_MENUITEM_ID(x) +*/ + +IDM_MENU MENUEX +BEGIN + POPUP "&File" MY_MENUITEM_ID(IDM_FILE) + BEGIN + MENUITEM "&Open\tEnter", IDM_OPEN + MENUITEM "Open &Inside\tCtrl+PgDn", IDM_OPEN_INSIDE + MENUITEM "Open Inside *", IDM_OPEN_INSIDE_ONE + MENUITEM "Open Inside #", IDM_OPEN_INSIDE_PARSER + MENUITEM "Open O&utside\tShift+Enter", IDM_OPEN_OUTSIDE + MENUITEM "&View\tF3", IDM_FILE_VIEW + MENUITEM "&Edit\tF4", IDM_FILE_EDIT + MY_MENUITEM_SEPARATOR + MENUITEM "Rena&me\tF2", IDM_RENAME + MENUITEM "&Copy To...\tF5", IDM_COPY_TO + MENUITEM "&Move To...\tF6", IDM_MOVE_TO + MENUITEM "&Delete\tDel", IDM_DELETE + MY_MENUITEM_SEPARATOR + MENUITEM "&Split file...", IDM_SPLIT + MENUITEM "Com&bine files...", IDM_COMBINE + MY_MENUITEM_SEPARATOR + MENUITEM "P&roperties\tAlt+Enter", IDM_PROPERTIES + MENUITEM "Comme&nt...\tCtrl+Z", IDM_COMMENT + // MENUITEM "Calculate checksum", IDM_CRC + POPUP "CRC" MY_MENUITEM_ID(0) + BEGIN + MENUITEM "CRC-32", IDM_CRC32 + MENUITEM "CRC-64", IDM_CRC64 + MENUITEM "XXH64", IDM_XXH64 + MENUITEM "MD5", IDM_MD5 + MENUITEM "SHA-1", IDM_SHA1 + MENUITEM "SHA-256", IDM_SHA256 + MENUITEM "SHA-384", IDM_SHA384 + MENUITEM "SHA-512", IDM_SHA512 + MENUITEM "SHA3-256", IDM_SHA3_256 + MENUITEM "BLAKE2sp", IDM_BLAKE2SP + MENUITEM "*", IDM_HASH_ALL + END + MENUITEM "Di&ff", IDM_DIFF + MY_MENUITEM_SEPARATOR + MENUITEM "Create Folder\tF7", IDM_CREATE_FOLDER + MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE + MY_MENUITEM_SEPARATOR + MENUITEM "&Link...", IDM_LINK + MENUITEM "&Alternate streams", IDM_ALT_STREAMS + MY_MENUITEM_SEPARATOR + MENUITEM "E&xit\tAlt+F4", IDCLOSE + END + POPUP "&Edit" MY_MENUITEM_ID(IDM_EDIT) + BEGIN + // MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT, GRAYED + // MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY, GRAYED + // MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE, GRAYED + // MY_MENUITEM_SEPARATOR + MENUITEM "Select &All\tShift+[Grey +]", IDM_SELECT_ALL + MENUITEM "Deselect All\tShift+[Grey -]", IDM_DESELECT_ALL + MENUITEM "&Invert Selection\tGrey *", IDM_INVERT_SELECTION + MENUITEM "Select...\tGrey +", IDM_SELECT + MENUITEM "Deselect...\tGrey -", IDM_DESELECT + MENUITEM "", 0, MY_MFT_MENUBARBREAK + MENUITEM "Select by Type\tAlt+[Grey+]", IDM_SELECT_BY_TYPE + MENUITEM "Deselect by Type\tAlt+[Grey -]", IDM_DESELECT_BY_TYPE + END + POPUP "&View" MY_MENUITEM_ID(IDM_VIEW) + BEGIN + MENUITEM "Lar&ge Icons\tCtrl+1", IDM_VIEW_LARGE_ICONS + MENUITEM "S&mall Icons\tCtrl+2", IDM_VIEW_SMALL_ICONS + MENUITEM "&List\tCtrl+3", IDM_VIEW_LIST + MENUITEM "&Details\tCtrl+4", IDM_VIEW_DETAILS, MY_MFS_CHECKED + MY_MENUITEM_SEPARATOR + MENUITEM "Name\tCtrl+F3", IDM_VIEW_ARANGE_BY_NAME + MENUITEM "Type\tCtrl+F4", IDM_VIEW_ARANGE_BY_TYPE + MENUITEM "Date\tCtrl+F5", IDM_VIEW_ARANGE_BY_DATE + MENUITEM "Size\tCtrl+F6", IDM_VIEW_ARANGE_BY_SIZE + MENUITEM "Unsorted\tCtrl+F7", IDM_VIEW_ARANGE_NO_SORT + MY_MENUITEM_SEPARATOR + MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW + MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS + + POPUP "2017" MY_MENUITEM_ID(IDM_VIEW_TIME_POPUP) + BEGIN + MENUITEM "Time", IDM_VIEW_TIME + END + + POPUP "Toolbars" MY_MENUITEM_ID(IDM_VIEW_TOOLBARS) + BEGIN + MENUITEM "Archive Toolbar", IDM_VIEW_ARCHIVE_TOOLBAR + MENUITEM "Standard Toolbar", IDM_VIEW_STANDARD_TOOLBAR + MY_MENUITEM_SEPARATOR + MENUITEM "Large Buttons", IDM_VIEW_TOOLBARS_LARGE_BUTTONS + MENUITEM "Show Buttons Text", IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT + END + MENUITEM "Open Root Folder\t\\", IDM_OPEN_ROOT_FOLDER + MENUITEM "Up One Level\tBackspace", IDM_OPEN_PARENT_FOLDER + MENUITEM "Folders History...\tAlt+F12", IDM_FOLDERS_HISTORY + MENUITEM "&Refresh\tCtrl+R", IDM_VIEW_REFRESH + MENUITEM "Auto Refresh", IDM_VIEW_AUTO_REFRESH + + // MENUITEM "Show NTFS streams", IDM_VIEW_SHOW_STREAMS + // MENUITEM "Show deleted files", IDM_VIEW_SHOW_DELETED + + END + POPUP "F&avorites" MY_MENUITEM_ID(IDM_FAVORITES) + BEGIN + POPUP "&Add folder to Favorites as" MY_MENUITEM_ID(IDM_ADD_TO_FAVORITES) + BEGIN + MY_MENUITEM_SEPARATOR + END + MY_MENUITEM_SEPARATOR + END + POPUP "&Tools" MY_MENUITEM_ID(IDM_TOOLS) + BEGIN + MENUITEM "&Options...", IDM_OPTIONS + MY_MENUITEM_SEPARATOR + MENUITEM "&Benchmark", IDM_BENCHMARK + #ifdef UNDER_CE + MENUITEM "Benchmark 2", IDM_BENCHMARK2 + #endif + MY_MENUITEM_SEPARATOR + MENUITEM "Delete Temporary Files...", IDM_TEMP_DIR + #ifndef UNDER_CE + END + POPUP "&Help" MY_MENUITEM_ID(IDM_HELP) + BEGIN + MENUITEM "&Contents...\tF1", IDM_HELP_CONTENTS + #endif + MY_MENUITEM_SEPARATOR + MENUITEM "&About 7-Zip...", IDM_ABOUT + END +END + + +IDI_ICON ICON "../../UI/FileManager/FM.ico" + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "../../UI/FileManager/7zFM.exe.manifest" +#endif + +IDB_ADD BITMAP "../../UI/FileManager/Add.bmp" +IDB_EXTRACT BITMAP "../../UI/FileManager/Extract.bmp" +IDB_TEST BITMAP "../../UI/FileManager/Test.bmp" +IDB_COPY BITMAP "../../UI/FileManager/Copy.bmp" +IDB_MOVE BITMAP "../../UI/FileManager/Move.bmp" +IDB_DELETE BITMAP "../../UI/FileManager/Delete.bmp" +IDB_INFO BITMAP "../../UI/FileManager/Info.bmp" +IDB_ADD2 BITMAP "../../UI/FileManager/Add2.bmp" +IDB_EXTRACT2 BITMAP "../../UI/FileManager/Extract2.bmp" +IDB_TEST2 BITMAP "../../UI/FileManager/Test2.bmp" +IDB_COPY2 BITMAP "../../UI/FileManager/Copy2.bmp" +IDB_MOVE2 BITMAP "../../UI/FileManager/Move2.bmp" +IDB_DELETE2 BITMAP "../../UI/FileManager/Delete2.bmp" +IDB_INFO2 BITMAP "../../UI/FileManager/Info2.bmp" + + +STRINGTABLE +BEGIN + IDS_BOOKMARK "Bookmark" + + IDS_OPTIONS "Options" + + IDS_N_SELECTED_ITEMS "{0} object(s) selected" + + IDS_FILE_EXIST "File {0} is already exist" + IDS_WANT_UPDATE_MODIFIED_FILE "File '{0}' was modified.\nDo you want to update it in the archive?" + IDS_CANNOT_UPDATE_FILE "Cannot update file\n'{0}'" + IDS_CANNOT_START_EDITOR "Cannot start editor." + IDS_VIRUS "The file looks like a virus (the file name contains long spaces in name)." + IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER "The operation cannot be called from a folder that has a long path." + IDS_SELECT_ONE_FILE "You must select one file" + // IDS_SELECT_FILES "You must select one or more files" + IDS_TOO_MANY_ITEMS "Too many items" + + IDS_COPY "Copy" + IDS_MOVE "Move" + IDS_COPY_TO "Copy to:" + IDS_MOVE_TO "Move to:" + IDS_COPYING "Copying..." +// IDS_MOVING "Moving..." + IDS_RENAMING "Renaming..." + + IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." + IDS_ERROR_RENAMING "Error Renaming File or Folder" + IDS_CONFIRM_FILE_COPY "Confirm File Copy" + IDS_WANT_TO_COPY_FILES "Are you sure you want to copy files to archive" + + IDS_CONFIRM_FILE_DELETE "Confirm File Delete" + IDS_CONFIRM_FOLDER_DELETE "Confirm Folder Delete" + IDS_CONFIRM_ITEMS_DELETE "Confirm Multiple File Delete" + IDS_WANT_TO_DELETE_FILE "Are you sure you want to delete '{0}'?" + IDS_WANT_TO_DELETE_FOLDER "Are you sure you want to delete the folder '{0}' and all its contents?" + IDS_WANT_TO_DELETE_ITEMS "Are you sure you want to delete these {0} items?" + IDS_DELETING "Deleting..." + IDS_ERROR_DELETING "Error Deleting File or Folder" + IDS_ERROR_LONG_PATH_TO_RECYCLE "The system cannot move a file with long path to the Recycle Bin" + + IDS_CREATE_FOLDER "Create Folder" + IDS_CREATE_FILE "Create File" + IDS_CREATE_FOLDER_NAME "Folder name:" + IDS_CREATE_FILE_NAME "File Name:" + IDS_CREATE_FOLDER_DEFAULT_NAME "New Folder" + IDS_CREATE_FILE_DEFAULT_NAME "New File" + IDS_CREATE_FOLDER_ERROR "Error Creating Folder" + IDS_CREATE_FILE_ERROR "Error Creating File" + + IDS_COMMENT "Comment" + IDS_COMMENT2 "&Comment:" + IDS_SELECT "Select" + IDS_DESELECT "Deselect" + IDS_SELECT_MASK "Mask:" + + IDS_PROPERTIES "Properties" + IDS_FOLDERS_HISTORY "Folders History" + + IDS_COMPUTER "Computer" + IDS_NETWORK "Network" + IDS_DOCUMENTS "Documents" + IDS_SYSTEM "System" + + IDS_ADD "Add" + IDS_EXTRACT "Extract" + IDS_TEST "Test" + IDS_BUTTON_COPY "Copy" + IDS_BUTTON_MOVE "Move" + IDS_BUTTON_DELETE "Delete" + IDS_BUTTON_INFO "Info" + + IDS_SPLITTING "Splitting..." + IDS_SPLIT_CONFIRM_TITLE "Confirm Splitting" + IDS_SPLIT_CONFIRM_MESSAGE "Are you sure you want to split file into {0} volumes?" + IDS_SPLIT_VOL_MUST_BE_SMALLER "Volume size must be smaller than size of original file" + + IDS_COMBINE "Combine Files" + IDS_COMBINE_TO "&Combine to:" + IDS_COMBINING "Combining..." + IDS_COMBINE_SELECT_ONE_FILE "Select only first part of split file" + IDS_COMBINE_CANT_DETECT_SPLIT_FILE "Cannot detect file as split file" + IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART "Cannot find more than one part of split file" + +END + +#include "AboutDialog.rc" +#include "BrowseDialog.rc" +#include "BrowseDialog2.rc" +#include "ComboDialog.rc" +#include "CopyDialog.rc" +#include "EditDialog.rc" +#include "EditPage.rc" +#include "FoldersPage.rc" +#include "LangPage.rc" +#include "LinkDialog.rc" +#include "ListViewDialog.rc" +#include "MemDialog.rc" +#include "MenuPage.rc" +#include "MessagesDialog.rc" +#include "OverwriteDialog.rc" +#include "PasswordDialog.rc" +#include "ProgressDialog2.rc" +#include "PropertyName.rc" +#include "SettingsPage.rc" +#include "SplitDialog.rc" +#include "SystemPage.rc" +#include "../GUI/Extract.rc" +#include "../GUI/resource3.rc" +#include "../Explorer/resource2.rc" +#include "resourceGui.rc" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/resourceGui.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.h --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/resourceGui.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.h 2024-10-13 11:00:00.000000000 +0000 @@ -1,15 +1,25 @@ -#define IDI_ICON 1 - -#define IDS_MESSAGE_NO_ERRORS 3001 - -#define IDS_PROGRESS_TESTING 3302 -#define IDS_OPENNING 3303 -#define IDS_SCANNING 3304 - -#define IDS_CHECKSUM_CALCULATING 7500 -#define IDS_CHECKSUM_INFORMATION 7501 -#define IDS_CHECKSUM_CRC_DATA 7502 -#define IDS_CHECKSUM_CRC_DATA_NAMES 7503 -#define IDS_CHECKSUM_CRC_STREAMS_NAMES 7504 - -#define IDS_INCORRECT_VOLUME_SIZE 7307 +#define IDI_ICON 1 + +#define IDS_MESSAGE_NO_ERRORS 3001 + +#define IDS_PROGRESS_TESTING 3302 +#define IDS_OPENNING 3303 +#define IDS_SCANNING 3304 + +#define IDS_MOVING 6005 + +#define IDS_CHECKSUM_CALCULATING 7500 +#define IDS_CHECKSUM_INFORMATION 7501 +#define IDS_CHECKSUM_CRC_DATA 7502 +#define IDS_CHECKSUM_CRC_DATA_NAMES 7503 +#define IDS_CHECKSUM_CRC_STREAMS_NAMES 7504 + +#define IDS_INCORRECT_VOLUME_SIZE 7307 + +#define IDS_MEM_REQUIRES_BIG_MEM 7811 +#define IDS_MEM_REQUIRED_MEM_SIZE 7812 +#define IDS_MEM_CURRENT_MEM_LIMIT 7813 +#define IDS_MEM_USAGE_LIMIT_SET_BY_7ZIP 7814 +#define IDS_MEM_RAM_SIZE 7815 + +#define IDS_MSG_ARC_UNPACKING_WAS_SKIPPED 7822 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/resourceGui.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.rc --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/resourceGui.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/resourceGui.rc 2024-10-13 11:00:00.000000000 +0000 @@ -0,0 +1,30 @@ +#include "resourceGui.h" + +STRINGTABLE +BEGIN + IDS_MESSAGE_NO_ERRORS "There are no errors" + + IDS_PROGRESS_TESTING "Testing" + + IDS_MOVING "Moving..." + + IDS_CHECKSUM_CALCULATING "Checksum calculating..." + IDS_CHECKSUM_INFORMATION "Checksum information" + IDS_CHECKSUM_CRC_DATA "CRC checksum for data:" + IDS_CHECKSUM_CRC_DATA_NAMES "CRC checksum for data and names:" + IDS_CHECKSUM_CRC_STREAMS_NAMES "CRC checksum for streams and names:" + + IDS_INCORRECT_VOLUME_SIZE "Incorrect volume size" + + IDS_OPENNING "Opening..." + IDS_SCANNING "Scanning..." + IDS_MEM_REQUIRES_BIG_MEM "The operation requires big amount of memory (RAM)." + IDS_MEM_REQUIRED_MEM_SIZE "required memory usage size" + IDS_MEM_CURRENT_MEM_LIMIT "allowed memory usage limit" + IDS_MEM_USAGE_LIMIT_SET_BY_7ZIP "memory usage limit set by 7-Zip" + IDS_MEM_RAM_SIZE "RAM size" + + IDS_MSG_ARC_UNPACKING_WAS_SKIPPED "Archive extraction was skipped." +// IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED "Files extraction was skipped." + +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/FileManager/wxFM.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/wxFM.cpp --- p7zip-rar-16.02/CPP/7zip/UI/FileManager/wxFM.cpp 2015-06-22 21:18:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/FileManager/wxFM.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,361 +0,0 @@ -// wxFM.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#ifdef __WXMAC__ - -#define UInt32 max_UInt32 -#include -#undef UInt32 - -#endif - -#include "Windows/Control/Dialog.h" // REGISTER_STRINGTABLE - -#include "Common/StringConvert.h" - -bool GetProgramFolderPath(UString &folder) -{ - const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR"); - if (p7zip_home_dir == 0) p7zip_home_dir="./"; - - folder = MultiByteToUnicodeString(p7zip_home_dir); - - return true; -} - -// FIXME - -static pthread_t g_main_thread; - -void verify_main_thread(void) -{ - if (g_main_thread != pthread_self()) - { - printf("verify_main_thread-wxFM\n"); - abort(); - } -} - -// #include "../GUI/p7zip_32.xpm" - -int Main1(int argc,TCHAR **argv); - -/* -int Main1(int argc,TCHAR **argv) -{ - // FIXME - Sleep(10000); -} -*/ - - -#include "Windows/Registry.h" -using namespace NWindows; -using namespace NRegistry; - - -#include "Common/StringConvert.h" -#include "Windows/FileDir.h" -#include "Windows/Synchronization.h" - -// FIXME #include "ExtractRes.h" -#include "../Explorer/MyMessages.h" - -// FIXME #include "ExtractGUI.h" -// FIXME #include "UpdateGUI.h" -// FIXME #include "BenchmarkDialog.h" -#include "RegistryUtils.h" - -using namespace NWindows; -using namespace NFile; - -#include "../FileManager/ProgramLocation.h" - -static LPCWSTR kHelpFileName = L"help/"; - -void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile) -{ - UString path; - if (!::GetProgramFolderPath(path)) - return; - path += kHelpFileName; - path += topicFile; - printf("ShowHelpWindow(%p,%ls)=>%ls\n",hwnd,topicFile,(const wchar_t *)path); - // HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL); - wxString path2(path); - wxLaunchDefaultBrowser(path2); -} - -////////////////////////////////// - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" // global_use_utf16_conversion - -void mySplitCommandLineW(int numArguments, TCHAR **arguments,UStringVector &parts) { - - parts.Clear(); - for(int ind=0;ind < numArguments; ind++) { - UString tmp = arguments[ind]; - // tmp.Trim(); " " is a valid filename ... - if (!tmp.IsEmpty()) { - parts.Add(tmp); - } - } -} - -// ---------------------------------------------------------------------------- -// private classes -// ---------------------------------------------------------------------------- - -// Define a new application type, each program should derive a class from wxApp -class MyApp : public wxApp -{ -public: - // override base class virtuals - // ---------------------------- - - // this one is called on application startup and is a good place for the app - // initialization (doing it here and not in the ctor allows to have an error - // return: if OnInit() returns false, the application terminates) - virtual bool OnInit(); - -#ifdef __WXMAC__ - virtual void MacOpenFile ( const wxString & fileName ) ; -#endif - -}; - -// Create a new application object: this macro will allow wxWidgets to create -// the application object during program execution (it's better than using a -// static object for many reasons) and also implements the accessor function -// wxGetApp() which will return the reference of the right type (i.e. MyApp and -// not wxApp) -IMPLEMENT_APP(MyApp) - -time_t g_T0 = 0; - -#if 0 -class MyThread : public wxThread -{ - int _argc; - TCHAR **_argv; -public: - MyThread(int argc,TCHAR **argv): wxThread(),_argc(argc), _argv(argv) {} - - // thread execution starts here - virtual void *Entry() - { - int ret = Main1(_argc,_argv); - exit(ret); - } -}; -#endif - -#ifdef __WXMAC__ -void doMacOpenFile( const UString & fileName ); - -void MyApp::MacOpenFile ( const wxString & fileName ) -{ - const wchar_t * wstr = fileName.wc_str (); - - // ::MessageBoxW(0, L"MyApp::MacOpenFile 2", wstr , MB_OKCANCEL | MB_ICONQUESTION); - - doMacOpenFile(wstr); -} -#endif - -// 'Main program' equivalent: the program execution "starts" here -bool MyApp::OnInit() -{ - // don't parse the command-line options ! - // : if ( !wxApp::OnInit() ) return false; - -/* -*/ -#ifdef __WXMAC__ -ProcessSerialNumber PSN; -GetCurrentProcess(&PSN); -TransformProcessType(&PSN,kProcessTransformToForegroundApplication); -#endif - - -/* - UString args(L"Args="); - - for(int i = 0 ; i < wxApp::argc ; i++) - args = args + L" '" + wxApp::argv[i] + L"'"; - - - ::MessageBoxW(0, L"MyApp::OnInit 3", args, MB_OKCANCEL | MB_ICONQUESTION); -*/ - - g_main_thread = pthread_self(); - - { // define P7ZIP_HOME_DIR - extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base); - static char p7zip_home_dir[MAX_PATH]; - - UString fullPath; - NDir::MyGetFullPathName(wxApp::argv[0], fullPath); - AString afullPath = GetAnsiString(fullPath); - - AString dir,name; - - my_windows_split_path(afullPath,dir,name); - - const char *dir2 = nameWindowToUnix((const char *)dir); - snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",dir2); - p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0; - putenv(p7zip_home_dir); - // DEBUG printf("putenv(%s)\n",p7zip_home_dir); - } - global_use_utf16_conversion = 1; // UNICODE ! - - g_T0 = time(0); - // DEBUG printf("MAIN Thread : 0x%lx\n",wxThread::GetCurrentId()); - - // Create the main frame window -#if 0 - MyFrame *frame = new MyFrame((wxFrame *)NULL, _T("7-zip Main Window"), 50, 50, 450, 340); - // Don't Show the frame ! - frame->Show(true); // FIXME - - SetTopWindow(frame); - -#endif - - /* - MyThread *thread = new MyThread(wxApp::argc,wxApp::argv); - thread->Create(); // != wxTHREAD_NO_ERROR - thread->Run(); - */ - - wxInitAllImageHandlers(); - - Main1(wxApp::argc,wxApp::argv); - - // success: wxApp::OnRun() will be called which will enter the main message - // loop and the application will run. If we returned false here, the - // application would exit immediately. - return true; -} - -////////////////////////////////////////// - -#include "resourceGui.h" - -static CStringTable g_stringTable[] = -{ - /* resourceGui.rc */ - /******************/ - { IDS_MESSAGE_NO_ERRORS ,L"There are no errors" }, - - { IDS_PROGRESS_TESTING ,L"Testing" }, - - { IDS_CHECKSUM_CALCULATING ,L"Checksum calculating..." }, - { IDS_CHECKSUM_INFORMATION ,L"Checksum information" }, - { IDS_CHECKSUM_CRC_DATA ,L"CRC checksum for data:" }, - { IDS_CHECKSUM_CRC_DATA_NAMES ,L"CRC checksum for data and names:" }, - { IDS_CHECKSUM_CRC_STREAMS_NAMES ,L"CRC checksum for streams and names:" }, - - { IDS_INCORRECT_VOLUME_SIZE ,L"Incorrect volume size" }, - - { IDS_OPENNING ,L"Opening..." }, - { IDS_SCANNING ,L"Scanning..." }, - - { 0 , 0 } -}; - -REGISTER_STRINGTABLE(g_stringTable) - -#if 0 -#include "resource.h" -#include "ExtractRes.h" - -static CStringTable g_stringTable[] = -{ - /* resource.rc */ - /***************/ - { IDS_OPEN_TYPE_ALL_FILES, L"All Files" }, - { IDS_METHOD_STORE, L"Store" }, - { IDS_METHOD_NORMAL, L"Normal" }, - { IDS_METHOD_MAXIMUM, L"Maximum" }, - { IDS_METHOD_FAST, L"Fast" }, - { IDS_METHOD_FASTEST, L"Fastest" }, - { IDS_METHOD_ULTRA, L"Ultra" }, - { IDS_COMPRESS_NON_SOLID, L"Non-solid" }, - { IDS_COMPRESS_SOLID, L"Solid" }, - - { IDS_COMPRESS_UPDATE_MODE_ADD, L"Add and replace files" }, - { IDS_COMPRESS_UPDATE_MODE_UPDATE, L"Update and add files" }, - { IDS_COMPRESS_UPDATE_MODE_FRESH, L"Freshen existing files" }, - { IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE, L"Synchronize files" }, - { IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, L"Browse" }, - { IDS_COMPRESS_INCORRECT_VOLUME_SIZE, L"Incorrect volume size" }, - { IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE, L"Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?" }, - - { IDS_PASSWORD_USE_ASCII, L"Use only English letters, numbers and special characters (!, #, $, ...) for password." }, - { IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH, L"Passwords do not match" }, - { IDS_PASSWORD_IS_TOO_LONG, L"Password is too long" }, - - { IDS_PROGRESS_COMPRESSING, L"Compressing" }, - { IDS_PROGRESS_TESTING, L"Testing" }, - { IDS_MESSAGE_NO_ERRORS, L"There are no errors" }, - { IDS_FILES_COLON, L"Files:" }, - { IDS_FOLDERS_COLON, L"Folders:" }, - { IDS_SIZE_COLON, L"Size:" }, - { IDS_COMPRESSED_COLON, L"Compressed size:" }, - { IDS_ARCHIVES_COLON, L"Archives:" }, - - /* Extract.rc */ - /**************/ - { IDS_CANNOT_CREATE_FOLDER , L"Cannot create folder '{0}'"}, - { IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, L"File is not supported archive."}, - - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC , L"CRC failed in '{0}'. File is broken."}, - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR , L"Data error in '{0}'. File is broken"}, - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD , L"Unsupported compression method for '{0}'."}, - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED , L"CRC failed in encrypted file '{0}'. Wrong password?"}, - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED , L"Data error in encrypted file '{0}'. Wrong password?"}, - - { IDS_EXTRACT_SET_FOLDER , L"Specify a location for extracted files."}, - { IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE, L"Can not open output file '{0}'."}, - { IDS_PROGRESS_EXTRACTING, L"Extracting" }, - - { IDS_CANT_OPEN_ARCHIVE , L"Can not open file '{0}' as archive"}, - { IDS_CANT_OPEN_ENCRYPTED_ARCHIVE , L"Can not open encrypted archive '{0}'. Wrong password?"}, - - { 0 , 0 } -}; - -REGISTER_STRINGTABLE(g_stringTable) -#endif - - -/////////////////////////////////////////// - -namespace NFsFolder { - - // FIXME - bool wxw_CopyFile(LPCWSTR existingFile, LPCWSTR newFile, bool overwrite) - { - return wxCopyFile(wxString(existingFile), wxString(newFile), overwrite); - } -} - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/7zG.exe.manifest p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/7zG.exe.manifest --- p7zip-rar-16.02/CPP/7zip/UI/GUI/7zG.exe.manifest 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/7zG.exe.manifest 2023-04-02 08:00:00.000000000 +0000 @@ -0,0 +1,23 @@ + + + + 7-Zip GUI. + + + + + + + + + + + + + true + + + + +true + diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.cpp 2016-05-20 08:48:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.cpp 2025-06-16 07:00:00.000000000 +0000 @@ -1,841 +1,1932 @@ -// BenchmarkDialog.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/Defs.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/MyException.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/System.h" -#include "../../../Windows/Thread.h" - -#include "../../Common/MethodProps.h" - -#include "../FileManager/HelpUtils.h" - -#include "../../MyVersion.h" - -#include "BenchmarkDialog.h" - -using namespace NWindows; - -void GetCpuName(AString &s); - -static LPCWSTR kHelpTopic = L"fm/benchmark.htm"; - -static const UINT_PTR kTimerID = 4; -static const UINT kTimerElapse = 1000; - -#ifdef LANG -#include "../FileManager/LangUtils.h" -#endif - -using namespace NWindows; - -UString HResultToMessage(HRESULT errorCode); - -#ifdef LANG -static const UInt32 kLangIDs[] = -{ - IDT_BENCH_DICTIONARY, - IDT_BENCH_MEMORY, - IDT_BENCH_NUM_THREADS, - IDT_BENCH_SPEED, - IDT_BENCH_RATING_LABEL, - IDT_BENCH_USAGE_LABEL, - IDT_BENCH_RPU_LABEL, - IDG_BENCH_COMPRESSING, - IDG_BENCH_DECOMPRESSING, - IDG_BENCH_TOTAL_RATING, - IDT_BENCH_CURRENT, - IDT_BENCH_RESULTING, - IDT_BENCH_ELAPSED, - IDT_BENCH_PASSES, - IDB_STOP, - IDB_RESTART -}; - -static const UInt32 kLangIDs_Colon[] = -{ - IDT_BENCH_SIZE -}; - -#endif - -static const LPCTSTR kProcessingString = TEXT("..."); -static const LPCTSTR kMB = TEXT(" MB"); -static const LPCTSTR kMIPS = TEXT(" MIPS"); -static const LPCTSTR kKBs = TEXT(" KB/s"); - -static const unsigned kMinDicLogSize = - #ifdef UNDER_CE - 20; - #else - 21; - #endif - -static const UInt32 kMinDicSize = (1 << kMinDicLogSize); -static const UInt32 kMaxDicSize = - #ifdef MY_CPU_64BIT - (1 << 30); - #else - (1 << 27); - #endif - -bool CBenchmarkDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_BENCH); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); - LangSetDlgItemText(*this, IDT_BENCH_CURRENT2, IDT_BENCH_CURRENT); - LangSetDlgItemText(*this, IDT_BENCH_RESULTING2, IDT_BENCH_RESULTING); - #endif - - Sync.Init(); - -#ifdef _WIN32 - if (TotalMode) - { - _consoleEdit.Attach(GetItem(IDE_BENCH2_EDIT)); - LOGFONT f; - memset(&f, 0, sizeof(f)); - f.lfHeight = 14; - f.lfWidth = 0; - f.lfWeight = FW_DONTCARE; - f.lfCharSet = DEFAULT_CHARSET; - f.lfOutPrecision = OUT_DEFAULT_PRECIS; - f.lfClipPrecision = CLIP_DEFAULT_PRECIS; - f.lfQuality = DEFAULT_QUALITY; - - f.lfPitchAndFamily = FIXED_PITCH; - // MyStringCopy(f.lfFaceName, TEXT("")); - // f.lfFaceName[0] = 0; - _font.Create(&f); - if (_font._font) - _consoleEdit.SendMsg(WM_SETFONT, (WPARAM)_font._font, TRUE); - } -#endif - - { - TCHAR s[40]; - s[0] = '/'; - s[1] = ' '; - ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2); - SetItemText(IDT_BENCH_HARDWARE_THREADS, s); - } - - { - UString s; - { - AString cpuName; - GetCpuName(cpuName); - s.SetFromAscii(cpuName); - SetItemText(IDT_BENCH_CPU, s); - } - - s.SetFromAscii("7-Zip " MY_VERSION " [" - #ifdef MY_CPU_64BIT - "64-bit" - #elif defined MY_CPU_32BIT - "32-bit" - #endif - "]"); - SetItemText(IDT_BENCH_VER, s); - } - - - UInt32 numCPUs = NSystem::GetNumberOfProcessors(); - if (numCPUs < 1) - numCPUs = 1; - numCPUs = MyMin(numCPUs, (UInt32)(1 << 8)); - - if (Sync.NumThreads == (UInt32)(Int32)-1) - { - Sync.NumThreads = numCPUs; - if (Sync.NumThreads > 1) - Sync.NumThreads &= ~1; - } - m_NumThreads.Attach(GetItem(IDC_BENCH_NUM_THREADS)); - int cur = 0; - for (UInt32 num = 1; num <= numCPUs * 2;) - { - TCHAR s[16]; - ConvertUInt32ToString(num, s); - int index = (int)m_NumThreads.AddString(s); - m_NumThreads.SetItemData(index, num); - if (num <= Sync.NumThreads) - cur = index; - if (num > 1) - num++; - num++; - } - m_NumThreads.SetCurSel(cur); - Sync.NumThreads = GetNumberOfThreads(); - - m_Dictionary.Attach(GetItem(IDC_BENCH_DICTIONARY)); - cur = 0; - - UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; - bool ramSize_Defined = NSystem::GetRamSize(ramSize); - - #ifdef UNDER_CE - const UInt32 kNormalizedCeSize = (16 << 20); - if (ramSize > kNormalizedCeSize && ramSize < (33 << 20)) - ramSize = kNormalizedCeSize; - #endif - - if (Sync.DictionarySize == (UInt32)(Int32)-1) - { - unsigned dicSizeLog = 25; - - #ifdef UNDER_CE - dicSizeLog = 20; - #endif - - if (ramSize_Defined) - for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) - if (GetBenchMemoryUsage(Sync.NumThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize) - break; - Sync.DictionarySize = (1 << dicSizeLog); - } - - if (Sync.DictionarySize < kMinDicSize) Sync.DictionarySize = kMinDicSize; - if (Sync.DictionarySize > kMaxDicSize) Sync.DictionarySize = kMaxDicSize; - - for (unsigned i = kMinDicLogSize; i <= 30; i++) - for (unsigned j = 0; j < 2; j++) - { - UInt32 dict = (1 << i) + (j << (i - 1)); - if (dict > kMaxDicSize) - continue; - TCHAR s[16]; - ConvertUInt32ToString((dict >> 20), s); - lstrcat(s, kMB); - int index = (int)m_Dictionary.AddString(s); - m_Dictionary.SetItemData(index, dict); - if (dict <= Sync.DictionarySize) - cur = index; - } - m_Dictionary.SetCurSel(cur); - - OnChangeSettings(); - - Sync._startEvent.Set(); - _timer = SetTimer(kTimerID, kTimerElapse); - - if (TotalMode) - NormalizeSize(true); - else - NormalizePosition(); - return CModalDialog::OnInit(); -} - -#ifdef _WIN32 -bool CBenchmarkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) -{ - if (!TotalMode) - return false; - int mx, my; - GetMargins(8, mx, my); - int bx1, bx2, by; - GetItemSizes(IDCANCEL, bx1, by); - GetItemSizes(IDHELP, bx2, by); - - { - int y = ySize - my - by; - int x = xSize - mx - bx1; - - InvalidateRect(NULL); - - MoveItem(IDCANCEL, x, y, bx1, by); - MoveItem(IDHELP, x - mx - bx2, y, bx2, by); - } - - if (_consoleEdit) - { - int yPos = ySize - my - by; - RECT rect; - GetClientRectOfItem(IDE_BENCH2_EDIT, rect); - int y = rect.top; - int ySize2 = yPos - my - y; - const int kMinYSize = 20; - int xx = xSize - mx * 2; - if (ySize2 < kMinYSize) - { - ySize2 = kMinYSize; - } - _consoleEdit.Move(mx, y, xx, ySize2); - } - return false; -} -#endif - -UInt32 CBenchmarkDialog::GetNumberOfThreads() -{ - return (UInt32)m_NumThreads.GetItemData_of_CurSel(); -} - -UInt32 CBenchmarkDialog::OnChangeDictionary() -{ - UInt32 dict = (UInt32)m_Dictionary.GetItemData_of_CurSel(); - UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dict); - memUsage = (memUsage + (1 << 20) - 1) >> 20; - TCHAR s[40]; - ConvertUInt64ToString(memUsage, s); - lstrcat(s, kMB); - SetItemText(IDT_BENCH_MEMORY_VAL, s); - return dict; -} - -static const UInt32 g_IDs[] = -{ - IDT_BENCH_COMPRESS_USAGE1, - IDT_BENCH_COMPRESS_USAGE2, - IDT_BENCH_COMPRESS_SPEED1, - IDT_BENCH_COMPRESS_SPEED2, - IDT_BENCH_COMPRESS_RATING1, - IDT_BENCH_COMPRESS_RATING2, - IDT_BENCH_COMPRESS_RPU1, - IDT_BENCH_COMPRESS_RPU2, - - IDT_BENCH_DECOMPR_SPEED1, - IDT_BENCH_DECOMPR_SPEED2, - IDT_BENCH_DECOMPR_RATING1, - IDT_BENCH_DECOMPR_RATING2, - IDT_BENCH_DECOMPR_USAGE1, - IDT_BENCH_DECOMPR_USAGE2, - IDT_BENCH_DECOMPR_RPU1, - IDT_BENCH_DECOMPR_RPU2, - - IDT_BENCH_TOTAL_USAGE_VAL, - IDT_BENCH_TOTAL_RATING_VAL, - IDT_BENCH_TOTAL_RPU_VAL -}; - -void CBenchmarkDialog::OnChangeSettings() -{ - EnableItem(IDB_STOP, true); - UInt32 dict = OnChangeDictionary(); - - for (int i = 0; i < ARRAY_SIZE(g_IDs); i++) - SetItemText(g_IDs[i], kProcessingString); - _startTime = GetTickCount(); - PrintTime(); - NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); - Sync.Init(); - Sync.DictionarySize = dict; - Sync.Changed = true; - Sync.NumThreads = GetNumberOfThreads(); -} - -void CBenchmarkDialog::OnRestartButton() -{ - OnChangeSettings(); -} - -void CBenchmarkDialog::OnStopButton() -{ - EnableItem(IDB_STOP, false); - Sync.Pause(); -} - -void CBenchmarkDialog::OnHelp() -{ - ShowHelpWindow(NULL, kHelpTopic); -} - -void CBenchmarkDialog::OnCancel() -{ - Sync.Stop(); - KillTimer(_timer); - CModalDialog::OnCancel(); -} - -void GetTimeString(UInt64 timeValue, wchar_t *s); - -void CBenchmarkDialog::PrintTime() -{ - UInt32 curTime = ::GetTickCount(); - UInt32 elapsedTime = (curTime - _startTime); - UInt32 elapsedSec = elapsedTime / 1000; - if (elapsedSec != 0 && Sync.WasPaused()) - return; - WCHAR s[40]; - GetTimeString(elapsedSec, s); - SetItemText(IDT_BENCH_ELAPSED_VAL, s); -} - -void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) -{ - TCHAR s[40]; - ConvertUInt64ToString(rating / 1000000, s); - lstrcat(s, kMIPS); - SetItemText(controlID, s); -} - -void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID) -{ - TCHAR s[40]; - ConvertUInt64ToString((usage + 5000) / 10000, s); - lstrcat(s, TEXT("%")); - SetItemText(controlID, s); -} - -void CBenchmarkDialog::PrintResults( - UInt32 dictionarySize, - const CBenchInfo2 &info, - UINT usageID, UINT speedID, UINT rpuID, UINT ratingID, - bool decompressMode) -{ - if (info.GlobalTime == 0) - return; - - TCHAR s[40]; - { - UInt64 speed = info.UnpackSize * info.NumIterations * info.GlobalFreq / info.GlobalTime; - ConvertUInt64ToString(speed / 1024, s); - lstrcat(s, kKBs); - SetItemText(speedID, s); - } - UInt64 rating; - if (decompressMode) - rating = info.GetDecompressRating(); - else - rating = info.GetCompressRating(dictionarySize); - - PrintRating(rating, ratingID); - PrintRating(info.GetRatingPerUsage(rating), rpuID); - PrintUsage(info.GetUsage(), usageID); -} - -bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) -{ - bool printTime = true; - if (TotalMode) - { - if (Sync.WasStopped()) - printTime = false; - } - if (printTime) - PrintTime(); - NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); - - if (TotalMode) - { - if (Sync.TextWasChanged) - { - _consoleEdit.SetText(GetSystemString(Sync.Text)); - Sync.TextWasChanged = false; - } - return true; - } - - TCHAR s[40]; - ConvertUInt64ToString((Sync.ProcessedSize >> 20), s); - lstrcat(s, kMB); - SetItemText(IDT_BENCH_SIZE_VAL, s); - - ConvertUInt64ToString(Sync.NumPasses, s); - SetItemText(IDT_BENCH_PASSES_VAL, s); - - /* - if (Sync.FreqWasChanged) - { - SetItemText(IDT_BENCH_FREQ, Sync.Freq); - Sync.FreqWasChanged = false; - } - */ - - { - UInt32 dicSizeTemp = (UInt32)MyMax(Sync.ProcessedSize, UInt64(1) << 20); - dicSizeTemp = MyMin(dicSizeTemp, Sync.DictionarySize), - PrintResults(dicSizeTemp, - Sync.CompressingInfoTemp, - IDT_BENCH_COMPRESS_USAGE1, - IDT_BENCH_COMPRESS_SPEED1, - IDT_BENCH_COMPRESS_RPU1, - IDT_BENCH_COMPRESS_RATING1); - } - - { - PrintResults( - Sync.DictionarySize, - Sync.CompressingInfo, - IDT_BENCH_COMPRESS_USAGE2, - IDT_BENCH_COMPRESS_SPEED2, - IDT_BENCH_COMPRESS_RPU2, - IDT_BENCH_COMPRESS_RATING2); - } - - { - PrintResults( - Sync.DictionarySize, - Sync.DecompressingInfoTemp, - IDT_BENCH_DECOMPR_USAGE1, - IDT_BENCH_DECOMPR_SPEED1, - IDT_BENCH_DECOMPR_RPU1, - IDT_BENCH_DECOMPR_RATING1, - true); - } - { - PrintResults( - Sync.DictionarySize, - Sync.DecompressingInfo, - IDT_BENCH_DECOMPR_USAGE2, - IDT_BENCH_DECOMPR_SPEED2, - IDT_BENCH_DECOMPR_RPU2, - IDT_BENCH_DECOMPR_RATING2, - true); - if (Sync.DecompressingInfo.GlobalTime > 0 && - Sync.CompressingInfo.GlobalTime > 0) - { - UInt64 comprRating = Sync.CompressingInfo.GetCompressRating(Sync.DictionarySize); - UInt64 decomprRating = Sync.DecompressingInfo.GetDecompressRating(); - PrintRating((comprRating + decomprRating) / 2, IDT_BENCH_TOTAL_RATING_VAL); - PrintRating(( - Sync.CompressingInfo.GetRatingPerUsage(comprRating) + - Sync.DecompressingInfo.GetRatingPerUsage(decomprRating)) / 2, IDT_BENCH_TOTAL_RPU_VAL); - PrintUsage( - (Sync.CompressingInfo.GetUsage() + - Sync.DecompressingInfo.GetUsage()) / 2, IDT_BENCH_TOTAL_USAGE_VAL); - } - } - return true; -} - -bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam) -{ - if (code == CBN_SELCHANGE && - (itemID == IDC_BENCH_DICTIONARY || - itemID == IDC_BENCH_NUM_THREADS)) - { - OnChangeSettings(); - return true; - } - return CModalDialog::OnCommand(code, itemID, lParam); -} - -bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDB_RESTART: - OnRestartButton(); - return true; - case IDB_STOP: - OnStopButton(); - return true; - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -struct CThreadBenchmark -{ - CBenchmarkDialog *BenchmarkDialog; - DECL_EXTERNAL_CODECS_LOC_VARS2; - // UInt32 dictionarySize; - // UInt32 numThreads; - - HRESULT Process(); - HRESULT Result; - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process(); - return 0; - } -}; - -struct CBenchCallback: public IBenchCallback -{ - UInt32 dictionarySize; - CProgressSyncInfo *Sync; - - // void AddCpuFreq(UInt64 cpuFreq); - HRESULT SetFreq(bool showFreq, UInt64 cpuFreq); - HRESULT SetEncodeResult(const CBenchInfo &info, bool final); - HRESULT SetDecodeResult(const CBenchInfo &info, bool final); -}; - -/* -void CBenchCallback::AddCpuFreq(UInt64 cpuFreq) -{ - NSynchronization::CCriticalSectionLock lock(Sync->CS); - { - wchar_t s[32]; - ConvertUInt64ToString(cpuFreq, s); - Sync->Freq.Add_Space_if_NotEmpty(); - Sync->Freq += s; - Sync->FreqWasChanged = true; - } -} -*/ - -HRESULT CBenchCallback::SetFreq(bool /* showFreq */, UInt64 /* cpuFreq */) -{ - return S_OK; -} - -HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final) -{ - NSynchronization::CCriticalSectionLock lock(Sync->CS); - if (Sync->Changed || Sync->Paused || Sync->Stopped) - return E_ABORT; - Sync->ProcessedSize = info.UnpackSize * info.NumIterations; - if (final && Sync->CompressingInfo.GlobalTime == 0) - { - (CBenchInfo&)Sync->CompressingInfo = info; - if (Sync->CompressingInfo.GlobalTime == 0) - Sync->CompressingInfo.GlobalTime = 1; - } - else - (CBenchInfo&)Sync->CompressingInfoTemp = info; - - return S_OK; -} - -HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final) -{ - NSynchronization::CCriticalSectionLock lock(Sync->CS); - if (Sync->Changed || Sync->Paused || Sync->Stopped) - return E_ABORT; - CBenchInfo info2 = info; - if (final && Sync->DecompressingInfo.GlobalTime == 0) - { - (CBenchInfo&)Sync->DecompressingInfo = info2; - if (Sync->DecompressingInfo.GlobalTime == 0) - Sync->DecompressingInfo.GlobalTime = 1; - } - else - (CBenchInfo&)Sync->DecompressingInfoTemp = info2; - return S_OK; -} - -struct CBenchCallback2: public IBenchPrintCallback -{ - CProgressSyncInfo *Sync; - - void Print(const char *s); - void NewLine(); - HRESULT CheckBreak(); -}; - -void CBenchCallback2::Print(const char *s) -{ - NSynchronization::CCriticalSectionLock lock(Sync->CS); - Sync->Text += s; - Sync->TextWasChanged = true; -} - -void CBenchCallback2::NewLine() -{ - Print("\xD\n"); -} - -HRESULT CBenchCallback2::CheckBreak() -{ - if (Sync->Changed || Sync->Paused || Sync->Stopped) - return E_ABORT; - return S_OK; -} - - -HRESULT CThreadBenchmark::Process() -{ - CProgressSyncInfo &sync = BenchmarkDialog->Sync; - sync.WaitCreating(); - try - { - for (;;) - { - if (sync.WasStopped()) - return 0; - if (sync.WasPaused()) - { - Sleep(200); - continue; - } - UInt32 dictionarySize; - UInt32 numThreads; - { - NSynchronization::CCriticalSectionLock lock(sync.CS); - if (sync.Stopped || sync.Paused) - continue; - if (sync.Changed) - sync.Init(); - dictionarySize = sync.DictionarySize; - numThreads = sync.NumThreads; - } - - CBenchCallback callback; - callback.dictionarySize = dictionarySize; - callback.Sync = &sync; - CBenchCallback2 callback2; - callback2.Sync = &sync; - HRESULT result; - - try - { - CObjectVector props; - if (BenchmarkDialog->TotalMode) - { - props = BenchmarkDialog->Props; - } - else - { - { - CProperty prop; - prop.Name = L"mt"; - wchar_t s[16]; - ConvertUInt32ToString(numThreads, s); - prop.Value = s; - props.Add(prop); - } - { - CProperty prop; - prop.Name = L'd'; - wchar_t s[16]; - ConvertUInt32ToString(dictionarySize, s); - prop.Name += s; - prop.Name += L'b'; - props.Add(prop); - } - } - result = Bench(EXTERNAL_CODECS_LOC_VARS - BenchmarkDialog->TotalMode ? &callback2 : NULL, - BenchmarkDialog->TotalMode ? NULL : &callback, - props, 1, false); - if (BenchmarkDialog->TotalMode) - { - sync.Stop(); - } - } - catch(...) - { - result = E_FAIL; - } - - if (result != S_OK) - { - if (result != E_ABORT) - { - { - NSynchronization::CCriticalSectionLock lock(sync.CS); - sync.Pause(); - } - UString message; - if (result == S_FALSE) - message = L"Decoding error"; - else if (result == CLASS_E_CLASSNOTAVAILABLE) - message = L"Can't find 7z.dll"; - else - message = HResultToMessage(result); - BenchmarkDialog->MessageBoxError(message); - } - } - else - { - NSynchronization::CCriticalSectionLock lock(sync.CS); - sync.NumPasses++; - } - } - // return S_OK; - } - catch(CSystemException &e) - { - BenchmarkDialog->MessageBoxError(HResultToMessage(e.ErrorCode)); - return E_FAIL; - } - catch(...) - { - BenchmarkDialog->MessageBoxError(HResultToMessage(E_FAIL)); - return E_FAIL; - } -} - -static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) -{ - const wchar_t *end; - UInt64 result = ConvertStringToUInt64(s, &end); - if (*end != 0 || s.IsEmpty()) - prop = s; - else if (result <= (UInt32)0xFFFFFFFF) - prop = (UInt32)result; - else - prop = result; -} - -HRESULT Benchmark( - DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector props, HWND hwndParent) -{ - CThreadBenchmark benchmarker; - #ifdef EXTERNAL_CODECS - benchmarker.__externalCodecs = __externalCodecs; - #endif - - CBenchmarkDialog bd; - bd.Props = props; - bd.TotalMode = false; - bd.Sync.DictionarySize = (UInt32)(Int32)-1; - bd.Sync.NumThreads = (UInt32)(Int32)-1; - - COneMethodInfo method; - - UInt32 numCPUs = 1; - #ifndef _7ZIP_ST - numCPUs = NSystem::GetNumberOfProcessors(); - #endif - UInt32 numThreads = numCPUs; - - FOR_VECTOR (i, props) - { - const CProperty &prop = props[i]; - UString name = prop.Name; - name.MakeLower_Ascii(); - if (name.IsEqualTo_Ascii_NoCase("m") && prop.Value == L"*") - { - bd.TotalMode = true; - continue; - } - - NCOM::CPropVariant propVariant; - if (!prop.Value.IsEmpty()) - ParseNumberString(prop.Value, propVariant); - if (name.IsPrefixedBy(L"mt")) - { - #ifndef _7ZIP_ST - RINOK(ParseMtProp(name.Ptr(2), propVariant, numCPUs, numThreads)); - if (numThreads != numCPUs) - bd.Sync.NumThreads = numThreads; - #endif - continue; - } - if (name.IsEqualTo("testtime")) - { - // UInt32 testTime = 4; - // RINOK(ParsePropToUInt32(L"", propVariant, testTime)); - continue; - } - RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); - } - - // bool totalBenchMode = (method.MethodName == L"*"); - - { - UInt32 dict; - if (method.Get_DicSize(dict)) - bd.Sync.DictionarySize = dict; - } - - benchmarker.BenchmarkDialog = &bd; - - NWindows::CThread thread; - RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker)); - bd.Create(hwndParent); - return thread.Wait(); -} +// BenchmarkDialog.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/Defs.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/System.h" +#include "../../../Windows/Thread.h" +#include "../../../Windows/SystemInfo.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" + +#include "../../Common/MethodProps.h" + +#include "../FileManager/DialogSize.h" +#include "../FileManager/HelpUtils.h" +#include "../FileManager/LangUtils.h" +#include "../FileManager/resourceGui.h" + +#include "../../MyVersion.h" + +#include "../Common/Bench.h" + +#include "BenchmarkDialogRes.h" +#include "BenchmarkDialog.h" + +using namespace NWindows; + +#define kHelpTopic "fm/benchmark.htm" + +static const UINT_PTR kTimerID = 4; +static const UINT kTimerElapse = 1000; // 1000 + +// use PRINT_ITER_TIME to show time of each iteration in log box +// #define PRINT_ITER_TIME + +static const unsigned kRatingVector_NumBundlesMax = 20; + +enum MyBenchMessages +{ + k_Message_Finished = WM_APP + 1 +}; + +enum My_Message_WPARAM +{ + k_Msg_WPARM_Thread_Finished = 0, + k_Msg_WPARM_Iter_Finished, + k_Msg_WPARM_Enc1_Finished +}; + + +struct CBenchPassResult +{ + CTotalBenchRes Enc; + CTotalBenchRes Dec; +#ifdef PRINT_ITER_TIME + DWORD Ticks; +#endif + // CBenchInfo EncInfo; // for debug + // CBenchPassResult() {}; +}; + + +struct CTotalBenchRes2: public CTotalBenchRes +{ + UInt64 UnpackSize; + + void Init() + { + CTotalBenchRes::Init(); + UnpackSize = 0; + } + + void SetFrom_BenchInfo(const CBenchInfo &info) + { + NumIterations2 = 1; + Generate_From_BenchInfo(info); + UnpackSize = info.Get_UnpackSize_Full(); + } + + void Update_With_Res2(const CTotalBenchRes2 &r) + { + Update_With_Res(r); + UnpackSize += r.UnpackSize; + } +}; + + +struct CSyncData +{ + UInt32 NumPasses_Finished; +#ifdef PRINT_ITER_TIME + DWORD TotalTicks; +#endif + int RatingVector_DeletedIndex; + // UInt64 RatingVector_NumDeleted; + + bool BenchWasFinished; // all passes were finished + bool NeedPrint_Freq; + bool NeedPrint_RatingVector; + bool NeedPrint_Enc_1; + bool NeedPrint_Enc; + bool NeedPrint_Dec_1; + bool NeedPrint_Dec; + bool NeedPrint_Tot; // intermediate Total was updated after current pass + + // UInt64 NumEncProgress; // for debug + // UInt64 NumDecProgress; // for debug + // CBenchInfo EncInfo; // for debug + + CTotalBenchRes2 Enc_BenchRes_1; + CTotalBenchRes2 Enc_BenchRes; + + CTotalBenchRes2 Dec_BenchRes_1; + CTotalBenchRes2 Dec_BenchRes; + + void Init(); +}; + + +void CSyncData::Init() +{ + NumPasses_Finished = 0; + + // NumEncProgress = 0; + // NumDecProgress = 0; + + Enc_BenchRes.Init(); + Enc_BenchRes_1.Init(); + Dec_BenchRes.Init(); + Dec_BenchRes_1.Init(); + + #ifdef PRINT_ITER_TIME + TotalTicks = 0; + #endif + + RatingVector_DeletedIndex = -1; + // RatingVector_NumDeleted = 0; + + BenchWasFinished = + NeedPrint_Freq = + NeedPrint_RatingVector = + NeedPrint_Enc_1 = + NeedPrint_Enc = + NeedPrint_Dec_1 = + NeedPrint_Dec = + NeedPrint_Tot = false; +} + + +struct CBenchProgressSync +{ + bool Exit; // GUI asks BenchThread to Exit, and BenchThread reads that variable + bool TextWasChanged; + + UInt32 NumThreads; + UInt64 DictSize; + UInt32 NumPasses_Limit; + int Level; + + AString Text; + + /* BenchFinish_Task_HRESULT - for result from benchmark code + BenchFinish_Thread_HRESULT - for Exceptions and service errors + these arreos must be shown even if user escapes benchmark */ + HRESULT BenchFinish_Task_HRESULT; + HRESULT BenchFinish_Thread_HRESULT; + + UInt32 NumFreqThreadsPrev; + UString FreqString_Sync; + UString FreqString_GUI; + + // must be written by benchmark thread, read by GUI thread */ + CRecordVector RatingVector; + CSyncData sd; + + NWindows::NSynchronization::CCriticalSection CS; + + CBenchProgressSync() + { + NumPasses_Limit = 1; + } + + void Init(); + + void SendExit() + { + NWindows::NSynchronization::CCriticalSectionLock lock(CS); + Exit = true; + } +}; + + +void CBenchProgressSync::Init() +{ + Exit = false; + + BenchFinish_Task_HRESULT = S_OK; + BenchFinish_Thread_HRESULT = S_OK; + + sd.Init(); + RatingVector.Clear(); + + NumFreqThreadsPrev = 0; + FreqString_Sync.Empty(); + FreqString_GUI.Empty(); + + Text.Empty(); + TextWasChanged = true; +} + + + +struct CMyFont +{ + HFONT _font; + CMyFont(): _font(NULL) {} + ~CMyFont() + { + if (_font) + DeleteObject(_font); + } + void Create(const LOGFONT *lplf) + { + _font = CreateFontIndirect(lplf); + } +}; + + +class CBenchmarkDialog; + +struct CThreadBenchmark +{ + CBenchmarkDialog *BenchmarkDialog; + DECL_EXTERNAL_CODECS_LOC_VARS_DECL + // HRESULT Result; + + HRESULT Process(); + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + /* ((CThreadBenchmark *)param)->Result = */ + ((CThreadBenchmark *)param)->Process(); + return 0; + } +}; + + +class CBenchmarkDialog: + public NWindows::NControl::CModalDialog +{ + bool _finishTime_WasSet; + + bool WasStopped_in_GUI; + bool ExitWasAsked_in_GUI; + bool NeedRestart; + + bool RamSize_Defined; + +public: + bool TotalMode; + +private: + + NWindows::NControl::CComboBox m_Dictionary; + NWindows::NControl::CComboBox m_NumThreads; + NWindows::NControl::CComboBox m_NumPasses; + NWindows::NControl::CEdit _consoleEdit; + UINT_PTR _timer; + + UInt32 _startTime; + UInt32 _finishTime; + + CMyFont _font; + + size_t RamSize; + size_t RamSize_Limit; + + UInt32 NumPasses_Finished_Prev; + + UString ElapsedSec_Prev; + + void InitSyncNew() + { + NumPasses_Finished_Prev = (UInt32)(Int32)-1; + ElapsedSec_Prev.Empty(); + Sync.Init(); + } + + virtual bool OnInit() Z7_override; + virtual bool OnDestroy() Z7_override; + virtual bool OnSize(WPARAM /* wParam */, int xSize, int ySize) Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual void OnHelp() Z7_override; + virtual void OnCancel() Z7_override; + virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + + void Disable_Stop_Button(); + void OnStopButton(); + void RestartBenchmark(); + void StartBenchmark(); + + void UpdateGui(); + + void PrintTime(); + void PrintRating(UInt64 rating, UINT controlID); + void PrintUsage(UInt64 usage, UINT controlID); + void PrintBenchRes(const CTotalBenchRes2 &info, const UINT ids[]); + + UInt32 GetNumberOfThreads(); + size_t OnChangeDictionary(); + + void SetItemText_Number(unsigned itemID, UInt64 val, LPCTSTR post = NULL); + void Print_MemUsage(UString &s, UInt64 memUsage) const; + bool IsMemoryUsageOK(UInt64 memUsage) const + { return memUsage + (1 << 20) <= RamSize_Limit; } + + void MyKillTimer(); + + void SendExit_Status(const wchar_t *message) + { + SetItemText(IDT_BENCH_ERROR_MESSAGE, message); + Sync.SendExit(); + } + +public: + CBenchProgressSync Sync; + + CObjectVector Props; + + CSysString Bench2Text; + + NWindows::CThread _thread; + CThreadBenchmark _threadBenchmark; + + CBenchmarkDialog(): + WasStopped_in_GUI(false), + ExitWasAsked_in_GUI(false), + NeedRestart(false), + TotalMode(false), + _timer(0) + {} + + ~CBenchmarkDialog() Z7_DESTRUCTOR_override; + + bool PostMsg_Finish(WPARAM wparam) + { + if ((HWND)*this) + return PostMsg(k_Message_Finished, wparam); + // the (HWND)*this is NULL only for some internal code failure + return true; + } + + INT_PTR Create(HWND wndParent = NULL) + { + BIG_DIALOG_SIZE(332, 228); + return CModalDialog::Create(TotalMode ? IDD_BENCH_TOTAL : SIZED_DIALOG(IDD_BENCH), wndParent); + } + void MessageBoxError(LPCWSTR message) + { + MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR); + } + void MessageBoxError_Status(LPCWSTR message) + { + UString s ("ERROR: "); + s += message; + MessageBoxError(s); + SetItemText(IDT_BENCH_ERROR_MESSAGE, s); + } +}; + + + + + + + + + +UString HResultToMessage(HRESULT errorCode); + +#ifdef Z7_LANG +static const UInt32 kLangIDs[] = +{ + IDT_BENCH_DICTIONARY, + IDT_BENCH_MEMORY, + IDT_BENCH_NUM_THREADS, + IDT_BENCH_SIZE, + IDT_BENCH_RATING_LABEL, + IDT_BENCH_USAGE_LABEL, + IDT_BENCH_RPU_LABEL, + IDG_BENCH_COMPRESSING, + IDG_BENCH_DECOMPRESSING, + IDG_BENCH_TOTAL_RATING, + IDT_BENCH_CURRENT, + IDT_BENCH_RESULTING, + IDT_BENCH_ELAPSED, + IDT_BENCH_PASSES, + IDB_STOP, + IDB_RESTART +}; + +static const UInt32 kLangIDs_RemoveColon[] = +{ + IDT_BENCH_SPEED +}; + +#endif + +static LPCTSTR const kProcessingString = TEXT("..."); +static LPCTSTR const kGB = TEXT(" GB"); +static LPCTSTR const kMB = TEXT(" MB"); +static LPCTSTR const kKB = TEXT(" KB"); +// static LPCTSTR const kMIPS = TEXT(" MIPS"); +static LPCTSTR const kKBs = TEXT(" KB/s"); + +static const unsigned kMinDicLogSize = 18; + +static const UInt32 kMinDicSize = (UInt32)1 << kMinDicLogSize; +static const size_t kMaxDicSize = (size_t)1 << (22 + sizeof(size_t) / 4 * 5); +// static const size_t kMaxDicSize = (size_t)1 << 16; + /* + #ifdef MY_CPU_64BIT + (UInt32)(Int32)-1; // we can use it, if we want 4 GB buffer + // (UInt32)15 << 28; + #else + (UInt32)1 << 27; + #endif + */ + + +static int ComboBox_Add_UInt32(NWindows::NControl::CComboBox &cb, UInt32 v) +{ + TCHAR s[16]; + ConvertUInt32ToString(v, s); + const int index = (int)cb.AddString(s); + cb.SetItemData(index, (LPARAM)v); + return index; +} + + +bool CBenchmarkDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_BENCH); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + LangSetDlgItems_RemoveColon(*this, kLangIDs_RemoveColon, Z7_ARRAY_SIZE(kLangIDs_RemoveColon)); + LangSetDlgItemText(*this, IDT_BENCH_CURRENT2, IDT_BENCH_CURRENT); + LangSetDlgItemText(*this, IDT_BENCH_RESULTING2, IDT_BENCH_RESULTING); + #endif + + InitSyncNew(); + + if (TotalMode) + { + _consoleEdit.Attach(GetItem(IDE_BENCH2_EDIT)); + LOGFONT f; + memset(&f, 0, sizeof(f)); + f.lfHeight = 14; + f.lfWidth = 0; + f.lfWeight = FW_DONTCARE; + f.lfCharSet = DEFAULT_CHARSET; + f.lfOutPrecision = OUT_DEFAULT_PRECIS; + f.lfClipPrecision = CLIP_DEFAULT_PRECIS; + f.lfQuality = DEFAULT_QUALITY; + + f.lfPitchAndFamily = FIXED_PITCH; + // MyStringCopy(f.lfFaceName, TEXT("")); + // f.lfFaceName[0] = 0; + _font.Create(&f); + if (_font._font) + _consoleEdit.SendMsg(WM_SETFONT, (WPARAM)_font._font, TRUE); + } + + UInt32 numCPUs = 1; + + { + AString s ("/ "); + + NSystem::CProcessAffinity threadsInfo; + threadsInfo.InitST(); + + #ifndef Z7_ST + if (threadsInfo.Get() && threadsInfo.processAffinityMask != 0) + numCPUs = threadsInfo.GetNumProcessThreads(); + else + numCPUs = NSystem::GetNumberOfProcessors(); + #endif + + s.Add_UInt32(numCPUs); + s += GetProcessThreadsInfo(threadsInfo); + SetItemTextA(IDT_BENCH_HARDWARE_THREADS, s); + + { + AString s2; + GetSysInfo(s, s2); + SetItemTextA(IDT_BENCH_SYS1, s); + if (s != s2 && !s2.IsEmpty()) + SetItemTextA(IDT_BENCH_SYS2, s2); + } + { + AString registers; + GetCpuName_MultiLine(s, registers); + SetItemTextA(IDT_BENCH_CPU, s); + } + { + GetOsInfoText(s); + s += " : "; + AddCpuFeatures(s); + SetItemTextA(IDT_BENCH_CPU_FEATURE, s); + } + + s = "7-Zip " MY_VERSION_CPU; + SetItemTextA(IDT_BENCH_VER, s); + } + + + // ----- Num Threads ---------- + + if (numCPUs < 1) + numCPUs = 1; + numCPUs = MyMin(numCPUs, (UInt32)(1 << 6)); // it's WIN32 limit + + UInt32 numThreads = Sync.NumThreads; + + if (numThreads == (UInt32)(Int32)-1) + numThreads = numCPUs; + if (numThreads > 1) + numThreads &= ~(UInt32)1; + const UInt32 kNumThreadsMax = (1 << 12); + if (numThreads > kNumThreadsMax) + numThreads = kNumThreadsMax; + + m_NumThreads.Attach(GetItem(IDC_BENCH_NUM_THREADS)); + const UInt32 numTheads_Combo = numCPUs * 2; + UInt32 v = 1; + int cur = 0; + for (; v <= numTheads_Combo;) + { + int index = ComboBox_Add_UInt32(m_NumThreads, v); + const UInt32 vNext = v + (v < 2 ? 1 : 2); + if (v <= numThreads) + if (numThreads < vNext || vNext > numTheads_Combo) + { + if (v != numThreads) + index = ComboBox_Add_UInt32(m_NumThreads, numThreads); + cur = index; + } + v = vNext; + } + m_NumThreads.SetCurSel(cur); + Sync.NumThreads = GetNumberOfThreads(); + + + // ----- Dictionary ---------- + + m_Dictionary.Attach(GetItem(IDC_BENCH_DICTIONARY)); + + RamSize = (UInt64)(sizeof(size_t)) << 29; + RamSize_Defined = NSystem::GetRamSize(RamSize); + + + #ifdef UNDER_CE + const UInt32 kNormalizedCeSize = (16 << 20); + if (RamSize > kNormalizedCeSize && RamSize < (33 << 20)) + RamSize = kNormalizedCeSize; + #endif + RamSize_Limit = RamSize / 16 * 15; + + if (Sync.DictSize == (UInt64)(Int64)-1) + { + unsigned dicSizeLog = 25; + #ifdef UNDER_CE + dicSizeLog = 20; + #endif + if (RamSize_Defined) + for (; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--) + if (IsMemoryUsageOK(GetBenchMemoryUsage( + Sync.NumThreads, Sync.Level, (UInt64)1 << dicSizeLog, TotalMode))) + break; + Sync.DictSize = (UInt64)1 << dicSizeLog; + } + + if (Sync.DictSize < kMinDicSize) Sync.DictSize = kMinDicSize; + if (Sync.DictSize > kMaxDicSize) Sync.DictSize = kMaxDicSize; + + cur = 0; + for (unsigned i = (kMinDicLogSize - 1) * 2; i <= (32 - 1) * 2; i++) + { + const size_t dict = (size_t)(2 + (i & 1)) << (i / 2); + // if (i == (32 - 1) * 2) dict = kMaxDicSize; + TCHAR s[32]; + const TCHAR *post; + UInt32 d; + if (dict >= ((UInt32)1 << 31)) { d = (UInt32)(dict >> 30); post = kGB; } + else if (dict >= ((UInt32)1 << 21)) { d = (UInt32)(dict >> 20); post = kMB; } + else { d = (UInt32)(dict >> 10); post = kKB; } + ConvertUInt32ToString(d, s); + lstrcat(s, post); + const int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, (LPARAM)dict); + if (dict <= Sync.DictSize) + cur = index; + if (dict >= kMaxDicSize) + break; + } + m_Dictionary.SetCurSel(cur); + + + // ----- Num Passes ---------- + + m_NumPasses.Attach(GetItem(IDC_BENCH_NUM_PASSES)); + cur = 0; + v = 1; + for (;;) + { + int index = ComboBox_Add_UInt32(m_NumPasses, v); + const bool isLast = (v >= 10000000); + UInt32 vNext = v * 10; + if (v < 2) vNext = 2; + else if (v < 5) vNext = 5; + else if (v < 10) vNext = 10; + + if (v <= Sync.NumPasses_Limit) + if (isLast || Sync.NumPasses_Limit < vNext) + { + if (v != Sync.NumPasses_Limit) + index = ComboBox_Add_UInt32(m_NumPasses, Sync.NumPasses_Limit); + cur = index; + } + v = vNext; + if (isLast) + break; + } + m_NumPasses.SetCurSel(cur); + + if (TotalMode) + NormalizeSize(true); + else + NormalizePosition(); + + RestartBenchmark(); + + return CModalDialog::OnInit(); +} + + +bool CBenchmarkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + + if (!TotalMode) + { + RECT rect; + GetClientRectOfItem(IDT_BENCH_LOG, rect); + int x = xSize - rect.left - mx; + int y = ySize - rect.top - my; + if (x < 0) x = 0; + if (y < 0) y = 0; + MoveItem(IDT_BENCH_LOG, rect.left, rect.top, x, y, true); + return false; + } + + int bx1, bx2, by; + + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDHELP, bx2, by); + + { + int y = ySize - my - by; + int x = xSize - mx - bx1; + + InvalidateRect(NULL); + + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDHELP, x - mx - bx2, y, bx2, by); + } + + if (_consoleEdit) + { + int yPos = ySize - my - by; + RECT rect; + GetClientRectOfItem(IDE_BENCH2_EDIT, rect); + int y = rect.top; + int ySize2 = yPos - my - y; + const int kMinYSize = 20; + int xx = xSize - mx * 2; + if (ySize2 < kMinYSize) + { + ySize2 = kMinYSize; + } + _consoleEdit.Move(mx, y, xx, ySize2); + } + return false; +} + + +UInt32 CBenchmarkDialog::GetNumberOfThreads() +{ + return (UInt32)m_NumThreads.GetItemData_of_CurSel(); +} + + +#define UINT_TO_STR_3(s, val) { \ + s[0] = (wchar_t)('0' + (val) / 100); \ + s[1] = (wchar_t)('0' + (val) % 100 / 10); \ + s[2] = (wchar_t)('0' + (val) % 10); \ + s += 3; s[0] = 0; } + +static WCHAR *NumberToDot3(UInt64 val, WCHAR *s) +{ + s = ConvertUInt64ToString(val / 1000, s); + const UInt32 rem = (UInt32)(val % 1000); + *s++ = '.'; + UINT_TO_STR_3(s, rem) + return s; +} + +void CBenchmarkDialog::SetItemText_Number(unsigned itemID, UInt64 val, LPCTSTR post) +{ + TCHAR s[64]; + ConvertUInt64ToString(val, s); + if (post) + lstrcat(s, post); + SetItemText(itemID, s); +} + +static void AddSize_MB(UString &s, UInt64 size) +{ + s.Add_UInt64((size + (1 << 20) - 1) >> 20); + s += kMB; +} + +void CBenchmarkDialog::Print_MemUsage(UString &s, UInt64 memUsage) const +{ + AddSize_MB(s, memUsage); + if (RamSize_Defined) + { + s += " / "; + AddSize_MB(s, RamSize); + } +} + +size_t CBenchmarkDialog::OnChangeDictionary() +{ + const size_t dict = (size_t)m_Dictionary.GetItemData_of_CurSel(); + const UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), + Sync.Level, + dict, + false); // totalBench mode + + UString s; + Print_MemUsage(s, memUsage); + + #ifdef Z7_LARGE_PAGES + { + AString s2; + Add_LargePages_String(s2); + if (!s2.IsEmpty()) + { + s.Add_Space(); + s += s2; + } + } + #endif + + SetItemText(IDT_BENCH_MEMORY_VAL, s); + + return dict; +} + + +static const UInt32 g_IDs[] = +{ + IDT_BENCH_COMPRESS_SIZE1, + IDT_BENCH_COMPRESS_SIZE2, + IDT_BENCH_COMPRESS_USAGE1, + IDT_BENCH_COMPRESS_USAGE2, + IDT_BENCH_COMPRESS_SPEED1, + IDT_BENCH_COMPRESS_SPEED2, + IDT_BENCH_COMPRESS_RATING1, + IDT_BENCH_COMPRESS_RATING2, + IDT_BENCH_COMPRESS_RPU1, + IDT_BENCH_COMPRESS_RPU2, + + IDT_BENCH_DECOMPR_SIZE1, + IDT_BENCH_DECOMPR_SIZE2, + IDT_BENCH_DECOMPR_SPEED1, + IDT_BENCH_DECOMPR_SPEED2, + IDT_BENCH_DECOMPR_RATING1, + IDT_BENCH_DECOMPR_RATING2, + IDT_BENCH_DECOMPR_USAGE1, + IDT_BENCH_DECOMPR_USAGE2, + IDT_BENCH_DECOMPR_RPU1, + IDT_BENCH_DECOMPR_RPU2, + + IDT_BENCH_TOTAL_USAGE_VAL, + IDT_BENCH_TOTAL_RATING_VAL, + IDT_BENCH_TOTAL_RPU_VAL +}; + + +static const unsigned k_Ids_Enc_1[] = { + IDT_BENCH_COMPRESS_USAGE1, + IDT_BENCH_COMPRESS_SPEED1, + IDT_BENCH_COMPRESS_RPU1, + IDT_BENCH_COMPRESS_RATING1, + IDT_BENCH_COMPRESS_SIZE1 }; + +static const unsigned k_Ids_Enc[] = { + IDT_BENCH_COMPRESS_USAGE2, + IDT_BENCH_COMPRESS_SPEED2, + IDT_BENCH_COMPRESS_RPU2, + IDT_BENCH_COMPRESS_RATING2, + IDT_BENCH_COMPRESS_SIZE2 }; + +static const unsigned k_Ids_Dec_1[] = { + IDT_BENCH_DECOMPR_USAGE1, + IDT_BENCH_DECOMPR_SPEED1, + IDT_BENCH_DECOMPR_RPU1, + IDT_BENCH_DECOMPR_RATING1, + IDT_BENCH_DECOMPR_SIZE1 }; + +static const unsigned k_Ids_Dec[] = { + IDT_BENCH_DECOMPR_USAGE2, + IDT_BENCH_DECOMPR_SPEED2, + IDT_BENCH_DECOMPR_RPU2, + IDT_BENCH_DECOMPR_RATING2, + IDT_BENCH_DECOMPR_SIZE2 }; + +static const unsigned k_Ids_Tot[] = { + IDT_BENCH_TOTAL_USAGE_VAL, + 0, + IDT_BENCH_TOTAL_RPU_VAL, + IDT_BENCH_TOTAL_RATING_VAL, + 0 }; + + +void CBenchmarkDialog::MyKillTimer() +{ + if (_timer != 0) + { + KillTimer(kTimerID); + _timer = 0; + } +} + + +bool CBenchmarkDialog::OnDestroy() +{ + /* actually timer was removed before. + also the timer must be removed by Windows, when window will be removed. */ + MyKillTimer(); // it's optional code + return false; // we return (false) to perform default dialog operation +} + +void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString); + +void CBenchmarkDialog::StartBenchmark() +{ + NeedRestart = false; + WasStopped_in_GUI = false; + + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + + MyKillTimer(); // optional code. timer was killed before + + const size_t dict = OnChangeDictionary(); + const UInt32 numThreads = GetNumberOfThreads(); + const UInt32 numPasses = (UInt32)m_NumPasses.GetItemData_of_CurSel(); + + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_IDs); i++) + SetItemText(g_IDs[i], kProcessingString); + + SetItemText_Empty(IDT_BENCH_LOG); + SetItemText_Empty(IDT_BENCH_ELAPSED_VAL); + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + + const UInt64 memUsage = GetBenchMemoryUsage(numThreads, Sync.Level, dict, + false); // totalBench + if (!IsMemoryUsageOK(memUsage)) + { + UString s2; + LangString_OnlyFromLangFile(IDS_MEM_REQUIRED_MEM_SIZE, s2); + if (s2.IsEmpty()) + { + s2 = LangString(IDT_BENCH_MEMORY); + if (s2.IsEmpty()) + GetItemText(IDT_BENCH_MEMORY, s2); + s2.RemoveChar(L':'); + } + UString s; + SetErrorMessage_MemUsage(s, memUsage, RamSize, RamSize_Limit, s2); + MessageBoxError_Status(s); + return; + } + + EnableItem(IDB_STOP, true); + + _startTime = GetTickCount(); + _finishTime = _startTime; + _finishTime_WasSet = false; + + { + NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); + InitSyncNew(); + Sync.DictSize = dict; + Sync.NumThreads = numThreads; + Sync.NumPasses_Limit = numPasses; + } + + PrintTime(); + + _timer = SetTimer(kTimerID, kTimerElapse); + if (_thread.Create(CThreadBenchmark::MyThreadFunction, &_threadBenchmark) != 0) + { + MyKillTimer(); + MessageBoxError_Status(L"Can't create thread"); + } + return; +} + + +void CBenchmarkDialog::RestartBenchmark() +{ + if (ExitWasAsked_in_GUI) + return; + + if (_thread.IsCreated()) + { + NeedRestart = true; + SendExit_Status(L"Stop for restart ..."); + } + else + StartBenchmark(); +} + + +void CBenchmarkDialog::Disable_Stop_Button() +{ + // if we disable focused button, then focus will be lost + if (GetFocus() == GetItem(IDB_STOP)) + { + // SendMsg_NextDlgCtl_Prev(); + SendMsg_NextDlgCtl_CtlId(IDB_RESTART); + } + EnableItem(IDB_STOP, false); +} + + +void CBenchmarkDialog::OnStopButton() +{ + if (ExitWasAsked_in_GUI) + return; + + Disable_Stop_Button(); + + WasStopped_in_GUI = true; + if (_thread.IsCreated()) + { + SendExit_Status(L"Stop ..."); + } +} + + + +void CBenchmarkDialog::OnCancel() +{ + ExitWasAsked_in_GUI = true; + + /* + SendMsg_NextDlgCtl_Prev(); + EnableItem(IDCANCEL, false); + */ + + if (_thread.IsCreated()) + SendExit_Status(L"Cancel ..."); + else + CModalDialog::OnCancel(); +} + + +void CBenchmarkDialog::OnHelp() +{ + ShowHelpWindow(kHelpTopic); +} + + + +// void GetTimeString(UInt64 timeValue, wchar_t *s); + +void CBenchmarkDialog::PrintTime() +{ + const UInt32 curTime = + _finishTime_WasSet ? + _finishTime : + ::GetTickCount(); + + const UInt32 elapsedTime = (curTime - _startTime); + + WCHAR s[64]; + + WCHAR *p = ConvertUInt32ToString(elapsedTime / 1000, s); + + if (_finishTime_WasSet) + { + *p++ = '.'; + UINT_TO_STR_3(p, elapsedTime % 1000) + } + + // p = NumberToDot3((UInt64)elapsedTime, s); + + MyStringCopy(p, L" s"); + + // if (WasStopped_in_GUI) wcscat(s, L" X"); // for debug + + if (s == ElapsedSec_Prev) + return; + + ElapsedSec_Prev = s; + + // static cnt = 0; cnt++; wcscat(s, L" "); + // UString s2; s2.Add_UInt32(cnt); wcscat(s, s2.Ptr()); + + SetItemText(IDT_BENCH_ELAPSED_VAL, s); +} + + +static UInt64 GetMips(UInt64 ips) +{ + return (ips + 500000) / 1000000; +} + + +static UInt64 GetUsagePercents(UInt64 usage) +{ + return Benchmark_GetUsage_Percents(usage); +} + + +static UInt32 GetRating(const CTotalBenchRes &info) +{ + UInt64 numIter = info.NumIterations2; + if (numIter == 0) + numIter = 1000000; + const UInt64 rating64 = GetMips(info.Rating / numIter); + // return rating64; + UInt32 rating32 = (UInt32)rating64; + if (rating32 != rating64) + rating32 = (UInt32)(Int32)-1; + return rating32; +} + + +static void AddUsageString(UString &s, const CTotalBenchRes &info) +{ + UInt64 numIter = info.NumIterations2; + if (numIter == 0) + numIter = 1000000; + UInt64 usage = GetUsagePercents(info.Usage / numIter); + + wchar_t w[64]; + ConvertUInt64ToString(usage, w); + unsigned len = MyStringLen(w); + while (len < 5) + { + s.Add_Space(); + len++; + } + s += w; + s += "%"; +} + + +static void Add_Dot3String(UString &s, UInt64 val) +{ + WCHAR temp[32]; + NumberToDot3(val, temp); + s += temp; +} + + +static void AddRatingString(UString &s, const CTotalBenchRes &info) +{ + // AddUsageString(s, info); + // s.Add_Space(); + // s.Add_UInt32(GetRating(info)); + Add_Dot3String(s, GetRating(info)); +} + + +static void AddRatingsLine(UString &s, const CTotalBenchRes &enc, const CTotalBenchRes &dec + #ifdef PRINT_ITER_TIME + , DWORD ticks + #endif + ) +{ + // AddUsageString(s, enc); s.Add_Space(); + + AddRatingString(s, enc); + s += " "; + AddRatingString(s, dec); + + CTotalBenchRes tot_BenchRes; + tot_BenchRes.SetSum(enc, dec); + + s += " "; + AddRatingString(s, tot_BenchRes); + + s.Add_Space(); AddUsageString(s, tot_BenchRes); + + + #ifdef PRINT_ITER_TIME + s.Add_Space(); + { + Add_Dot3String(s, ticks; + s += " s"; + // s.Add_UInt32(ticks); s += " ms"; + } + #endif +} + + +void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID) +{ + // SetItemText_Number(controlID, GetMips(rating), kMIPS); + WCHAR s[64]; + MyStringCopy(NumberToDot3(GetMips(rating), s), L" GIPS"); + SetItemText(controlID, s); +} + +void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID) +{ + SetItemText_Number(controlID, GetUsagePercents(usage), TEXT("%")); +} + + +// void SetItemText_Number + +void CBenchmarkDialog::PrintBenchRes( + const CTotalBenchRes2 &info, + const UINT ids[]) +{ + if (info.NumIterations2 == 0) + return; + if (ids[1] != 0) + SetItemText_Number(ids[1], (info.Speed >> 10) / info.NumIterations2, kKBs); + PrintRating(info.Rating / info.NumIterations2, ids[3]); + PrintRating(info.RPU / info.NumIterations2, ids[2]); + PrintUsage(info.Usage / info.NumIterations2, ids[0]); + if (ids[4] != 0) + { + UInt64 val = info.UnpackSize; + LPCTSTR kPostfix; + if (val >= ((UInt64)1 << 40)) + { + kPostfix = kGB; + val >>= 30; + } + else + { + kPostfix = kMB; + val >>= 20; + } + SetItemText_Number(ids[4], val, kPostfix); + } +} + + +// static UInt32 k_Message_Finished_cnt = 0; +// static UInt32 k_OnTimer_cnt = 0; + +bool CBenchmarkDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message != k_Message_Finished) + return CModalDialog::OnMessage(message, wParam, lParam); + + { + if (wParam == k_Msg_WPARM_Thread_Finished) + { + _finishTime = GetTickCount(); + _finishTime_WasSet = true; + MyKillTimer(); + + if (_thread.Wait_Close() != 0) + { + MessageBoxError_Status(L"Thread Wait Error"); + } + + if (!WasStopped_in_GUI) + { + WasStopped_in_GUI = true; + Disable_Stop_Button(); + } + + HRESULT res = Sync.BenchFinish_Thread_HRESULT; + if (res != S_OK) + // if (!ExitWasAsked_in_GUI || res != E_ABORT) + MessageBoxError_Status(HResultToMessage(res)); + + if (ExitWasAsked_in_GUI) + { + // SetItemText(IDT_BENCH_ERROR_MESSAGE, "before CModalDialog::OnCancel()"); + // Sleep (2000); + // MessageBoxError(L"test"); + CModalDialog::OnCancel(); + return true; + } + + SetItemText_Empty(IDT_BENCH_ERROR_MESSAGE); + + res = Sync.BenchFinish_Task_HRESULT; + if (res != S_OK) + { + if (!WasStopped_in_GUI || res != E_ABORT) + { + UString m; + if (res == S_FALSE) + m = "Decoding error"; + else if (res == CLASS_E_CLASSNOTAVAILABLE) + m = "Can't find 7z.dll"; + else + m = HResultToMessage(res); + MessageBoxError_Status(m); + } + } + + if (NeedRestart) + { + StartBenchmark(); + return true; + } + } + // k_Message_Finished_cnt++; + UpdateGui(); + return true; + } +} + + +bool CBenchmarkDialog::OnTimer(WPARAM timerID, LPARAM /* callback */) +{ + // k_OnTimer_cnt++; + if (timerID == kTimerID) + UpdateGui(); + return true; +} + + +void CBenchmarkDialog::UpdateGui() +{ + PrintTime(); + + if (TotalMode) + { + bool wasChanged = false; + { + NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); + + if (Sync.TextWasChanged) + { + wasChanged = true; + Bench2Text += Sync.Text; + Sync.Text.Empty(); + Sync.TextWasChanged = false; + } + } + if (wasChanged) + _consoleEdit.SetText(Bench2Text); + return; + } + + CSyncData sd; + CRecordVector RatingVector; + + { + NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS); + sd = Sync.sd; + + if (sd.NeedPrint_RatingVector) + RatingVector = Sync.RatingVector; + + if (sd.NeedPrint_Freq) + { + Sync.FreqString_GUI = Sync.FreqString_Sync; + sd.NeedPrint_RatingVector = true; + } + + Sync.sd.NeedPrint_RatingVector = false; + Sync.sd.NeedPrint_Enc_1 = false; + Sync.sd.NeedPrint_Enc = false; + Sync.sd.NeedPrint_Dec_1 = false; + Sync.sd.NeedPrint_Dec = false; + Sync.sd.NeedPrint_Tot = false; + Sync.sd.NeedPrint_Freq = false; + } + + if (sd.NumPasses_Finished != NumPasses_Finished_Prev) + { + SetItemText_Number(IDT_BENCH_PASSES_VAL, sd.NumPasses_Finished, TEXT(" /")); + NumPasses_Finished_Prev = sd.NumPasses_Finished; + } + + if (sd.NeedPrint_Enc_1) PrintBenchRes(sd.Enc_BenchRes_1, k_Ids_Enc_1); + if (sd.NeedPrint_Enc) PrintBenchRes(sd.Enc_BenchRes, k_Ids_Enc); + if (sd.NeedPrint_Dec_1) PrintBenchRes(sd.Dec_BenchRes_1, k_Ids_Dec_1); + if (sd.NeedPrint_Dec) PrintBenchRes(sd.Dec_BenchRes, k_Ids_Dec); + + if (sd.BenchWasFinished && sd.NeedPrint_Tot) + { + CTotalBenchRes2 tot_BenchRes = sd.Enc_BenchRes; + tot_BenchRes.Update_With_Res2(sd.Dec_BenchRes); + PrintBenchRes(tot_BenchRes, k_Ids_Tot); + } + + + if (sd.NeedPrint_RatingVector) + // for (unsigned k = 0; k < 1; k++) + { + UString s; + s += Sync.FreqString_GUI; + if (!RatingVector.IsEmpty()) + { + if (!s.IsEmpty()) + s.Add_LF(); + s += "Compr Decompr Total CPU" + #ifdef PRINT_ITER_TIME + " Time" + #endif + ; + s.Add_LF(); + } + // s += "GIPS GIPS GIPS % s"; s.Add_LF(); + for (unsigned i = 0; i < RatingVector.Size(); i++) + { + if (i != 0) + s.Add_LF(); + if ((int)i == sd.RatingVector_DeletedIndex) + { + s += "..."; + s.Add_LF(); + } + const CBenchPassResult &pair = RatingVector[i]; + /* + s += "g:"; s.Add_UInt32((UInt32)pair.EncInfo.GlobalTime); + s += " u:"; s.Add_UInt32((UInt32)pair.EncInfo.UserTime); + s.Add_Space(); + */ + AddRatingsLine(s, pair.Enc, pair.Dec + #ifdef PRINT_ITER_TIME + , pair.Ticks + #endif + ); + /* + { + UInt64 v = i + 1; + if (sd.RatingVector_DeletedIndex >= 0 && i >= (unsigned)sd.RatingVector_DeletedIndex) + v += sd.RatingVector_NumDeleted; + char temp[64]; + ConvertUInt64ToString(v, temp); + s += " : "; + s += temp; + } + */ + } + + if (sd.BenchWasFinished) + { + s.Add_LF(); + s += "-------------"; + s.Add_LF(); + { + // average time is not correct because of freq detection in first iteration + AddRatingsLine(s, sd.Enc_BenchRes, sd.Dec_BenchRes + #ifdef PRINT_ITER_TIME + , (DWORD)(sd.TotalTicks / (sd.NumPasses_Finished ? sd.NumPasses_Finished : 1)) + #endif + ); + } + } + // s.Add_LF(); s += "OnTimer: "; s.Add_UInt32(k_OnTimer_cnt); + // s.Add_LF(); s += "finished Message: "; s.Add_UInt32(k_Message_Finished_cnt); + // static cnt = 0; cnt++; s.Add_LF(); s += "Print: "; s.Add_UInt32(cnt); + // s.Add_LF(); s += "NumEncProgress: "; s.Add_UInt32((UInt32)sd.NumEncProgress); + // s.Add_LF(); s += "NumDecProgress: "; s.Add_UInt32((UInt32)sd.NumDecProgress); + SetItemText(IDT_BENCH_LOG, s); + } +} + + +bool CBenchmarkDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE && + (itemID == IDC_BENCH_DICTIONARY || + itemID == IDC_BENCH_NUM_PASSES || + itemID == IDC_BENCH_NUM_THREADS)) + { + RestartBenchmark(); + return true; + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + + +bool CBenchmarkDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_RESTART: + RestartBenchmark(); + return true; + case IDB_STOP: + OnStopButton(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + + + + + +// ---------- Benchmark Thread ---------- + +struct CBenchCallback Z7_final: public IBenchCallback +{ + UInt64 dictionarySize; + CBenchProgressSync *Sync; + CBenchmarkDialog *BenchmarkDialog; + + HRESULT SetEncodeResult(const CBenchInfo &info, bool final) Z7_override; + HRESULT SetDecodeResult(const CBenchInfo &info, bool final) Z7_override; +}; + +HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final) +{ + bool needPost = false; + { + NSynchronization::CCriticalSectionLock lock(Sync->CS); + if (Sync->Exit) + return E_ABORT; + CSyncData &sd = Sync->sd; + // sd.NumEncProgress++; + CTotalBenchRes2 &br = sd.Enc_BenchRes_1; + { + UInt64 dictSize = Sync->DictSize; + if (final) + { + // sd.EncInfo = info; + } + else + { + /* if (!final), then CBenchInfo::NumIterations means totalNumber of threads. + so we can reduce the dictionary */ + if (dictSize > info.UnpackSize) + dictSize = info.UnpackSize; + } + br.Rating = info.GetRating_LzmaEnc(dictSize); + } + br.SetFrom_BenchInfo(info); + sd.NeedPrint_Enc_1 = true; + if (final) + { + sd.Enc_BenchRes.Update_With_Res2(br); + sd.NeedPrint_Enc = true; + needPost = true; + } + } + + if (needPost) + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + + return S_OK; +} + + +HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final) +{ + NSynchronization::CCriticalSectionLock lock(Sync->CS); + if (Sync->Exit) + return E_ABORT; + CSyncData &sd = Sync->sd; + // sd.NumDecProgress++; + CTotalBenchRes2 &br = sd.Dec_BenchRes_1; + br.Rating = info.GetRating_LzmaDec(); + br.SetFrom_BenchInfo(info); + sd.NeedPrint_Dec_1 = true; + if (final) + sd.Dec_BenchRes.Update_With_Res2(br); + return S_OK; +} + + +struct CBenchCallback2 Z7_final: public IBenchPrintCallback +{ + CBenchProgressSync *Sync; + bool TotalMode; + + void Print(const char *s) Z7_override; + void NewLine() Z7_override; + HRESULT CheckBreak() Z7_override; +}; + +void CBenchCallback2::Print(const char *s) +{ + if (TotalMode) + { + NSynchronization::CCriticalSectionLock lock(Sync->CS); + Sync->Text += s; + Sync->TextWasChanged = true; + } +} + +void CBenchCallback2::NewLine() +{ + Print("\xD\n"); +} + +HRESULT CBenchCallback2::CheckBreak() +{ + if (Sync->Exit) + return E_ABORT; + return S_OK; +} + + + +struct CFreqCallback Z7_final: public IBenchFreqCallback +{ + CBenchmarkDialog *BenchmarkDialog; + + virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) Z7_override; + virtual HRESULT FreqsFinished(unsigned numThreads) Z7_override; +}; + +HRESULT CFreqCallback::AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) +{ + HRESULT res; + { + CBenchProgressSync &sync = BenchmarkDialog->Sync; + NSynchronization::CCriticalSectionLock lock(sync.CS); + UString &s = sync.FreqString_Sync; + if (sync.NumFreqThreadsPrev != numThreads) + { + sync.NumFreqThreadsPrev = numThreads; + if (!s.IsEmpty()) + s.Add_LF(); + s.Add_UInt32(numThreads); + s += "T Frequency (MHz):"; + s.Add_LF(); + } + s.Add_Space(); + if (numThreads != 1) + { + s.Add_UInt64(GetUsagePercents(usage)); + s.Add_Char('%'); + s.Add_Space(); + } + s.Add_UInt64(GetMips(freq)); + // BenchmarkDialog->Sync.sd.NeedPrint_Freq = true; + res = sync.Exit ? E_ABORT : S_OK; + } + // BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + return res; +} + +HRESULT CFreqCallback::FreqsFinished(unsigned /* numThreads */) +{ + HRESULT res; + { + CBenchProgressSync &sync = BenchmarkDialog->Sync; + NSynchronization::CCriticalSectionLock lock(sync.CS); + sync.sd.NeedPrint_Freq = true; + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + res = sync.Exit ? E_ABORT : S_OK; + } + BenchmarkDialog->PostMsg(k_Message_Finished, k_Msg_WPARM_Enc1_Finished); + return res; +} + + + +// define USE_DUMMY only for debug +// #define USE_DUMMY +#ifdef USE_DUMMY +static unsigned dummy = 1; +static unsigned Dummy(unsigned limit) +{ + unsigned sum = 0; + for (unsigned k = 0; k < limit; k++) + { + sum += dummy; + if (sum == 0) + break; + } + return sum; +} +#endif + + +HRESULT CThreadBenchmark::Process() +{ + /* the first benchmark pass can be slow, + if we run benchmark while the window is being created, + and (no freq detecion loop) && (dictionary is small) (-mtic is small) */ + + // Sleep(300); // for debug + #ifdef USE_DUMMY + Dummy(1000 * 1000 * 1000); // for debug + #endif + + CBenchProgressSync &sync = BenchmarkDialog->Sync; + HRESULT finishHRESULT = S_OK; + + try + { + for (UInt32 passIndex = 0;; passIndex++) + { + // throw 1; // to debug + // throw CSystemException(E_INVALIDARG); // to debug + + UInt64 dictionarySize; + UInt32 numThreads; + { + NSynchronization::CCriticalSectionLock lock(sync.CS); + if (sync.Exit) + break; + dictionarySize = sync.DictSize; + numThreads = sync.NumThreads; + } + + #ifdef PRINT_ITER_TIME + const DWORD startTick = GetTickCount(); + #endif + + CBenchCallback callback; + + callback.dictionarySize = dictionarySize; + callback.Sync = &sync; + callback.BenchmarkDialog = BenchmarkDialog; + + CBenchCallback2 callback2; + callback2.TotalMode = BenchmarkDialog->TotalMode; + callback2.Sync = &sync; + + CFreqCallback freqCallback; + freqCallback.BenchmarkDialog = BenchmarkDialog; + + HRESULT result; + + try + { + CObjectVector props; + + props = BenchmarkDialog->Props; + + if (BenchmarkDialog->TotalMode) + { + props = BenchmarkDialog->Props; + } + else + { + { + CProperty prop; + prop.Name = "mt"; + prop.Value.Add_UInt32(numThreads); + props.Add(prop); + } + { + CProperty prop; + prop.Name = 'd'; + prop.Name.Add_UInt32((UInt32)(dictionarySize >> 10)); + prop.Name.Add_Char('k'); + props.Add(prop); + } + } + + result = Bench(EXTERNAL_CODECS_LOC_VARS + BenchmarkDialog->TotalMode ? &callback2 : NULL, + BenchmarkDialog->TotalMode ? NULL : &callback, + props, 1, false, + (!BenchmarkDialog->TotalMode) && passIndex == 0 ? &freqCallback: NULL); + + // result = S_FALSE; // for debug; + // throw 1; + } + catch(...) + { + result = E_FAIL; + } + + #ifdef PRINT_ITER_TIME + const DWORD numTicks = GetTickCount() - startTick; + #endif + + bool finished = true; + + NSynchronization::CCriticalSectionLock lock(sync.CS); + + if (result != S_OK) + { + sync.BenchFinish_Task_HRESULT = result; + break; + } + + { + CSyncData &sd = sync.sd; + + sd.NumPasses_Finished++; + #ifdef PRINT_ITER_TIME + sd.TotalTicks += numTicks; + #endif + + if (BenchmarkDialog->TotalMode) + break; + + { + CTotalBenchRes tot_BenchRes = sd.Enc_BenchRes_1; + tot_BenchRes.Update_With_Res(sd.Dec_BenchRes_1); + + sd.NeedPrint_RatingVector = true; + { + CBenchPassResult pair; + // pair.EncInfo = sd.EncInfo; // for debug + pair.Enc = sd.Enc_BenchRes_1; + pair.Dec = sd.Dec_BenchRes_1; + #ifdef PRINT_ITER_TIME + pair.Ticks = numTicks; + #endif + sync.RatingVector.Add(pair); + // pair.Dec_Defined = true; + } + } + + sd.NeedPrint_Dec = true; + sd.NeedPrint_Tot = true; + + if (sync.RatingVector.Size() > kRatingVector_NumBundlesMax) + { + // sd.RatingVector_NumDeleted++; + sd.RatingVector_DeletedIndex = (int)(kRatingVector_NumBundlesMax / 4); + sync.RatingVector.Delete((unsigned)(sd.RatingVector_DeletedIndex)); + } + + if (sync.sd.NumPasses_Finished < sync.NumPasses_Limit) + finished = false; + else + { + sync.sd.BenchWasFinished = true; + // BenchmarkDialog->_finishTime = GetTickCount(); + // return 0; + } + } + + if (BenchmarkDialog->TotalMode) + break; + + /* + if (newTick - prevTick < 1000) + numSameTick++; + if (numSameTick > 5 || finished) + { + prevTick = newTick; + numSameTick = 0; + */ + // for (unsigned i = 0; i < 1; i++) + { + // we suppose that PostMsg messages will be processed in order. + if (!BenchmarkDialog->PostMsg_Finish(k_Msg_WPARM_Iter_Finished)) + { + finished = true; + finishHRESULT = E_FAIL; + // throw 1234567; + } + } + if (finished) + break; + } + // return S_OK; + } + catch(CSystemException &e) + { + finishHRESULT = e.ErrorCode; + // BenchmarkDialog->MessageBoxError(HResultToMessage(e.ErrorCode)); + // return E_FAIL; + } + catch(...) + { + finishHRESULT = E_FAIL; + // BenchmarkDialog->MessageBoxError(HResultToMessage(E_FAIL)); + // return E_FAIL; + } + + if (finishHRESULT != S_OK) + { + NSynchronization::CCriticalSectionLock lock(sync.CS); + sync.BenchFinish_Thread_HRESULT = finishHRESULT; + } + if (!BenchmarkDialog->PostMsg_Finish(k_Msg_WPARM_Thread_Finished)) + { + // sync.BenchFinish_Thread_HRESULT = E_FAIL; + } + return 0; +} + + + +static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop) +{ + const wchar_t *end; + UInt64 result = ConvertStringToUInt64(s, &end); + if (*end != 0 || s.IsEmpty()) + prop = s; + else if (result <= (UInt32)0xFFFFFFFF) + prop = (UInt32)result; + else + prop = result; +} + + +HRESULT Benchmark( + DECL_EXTERNAL_CODECS_LOC_VARS + const CObjectVector &props, UInt32 numIterations, HWND hwndParent) +{ + CBenchmarkDialog bd; + + bd.TotalMode = false; + bd.Props = props; + if (numIterations == 0) + numIterations = 1; + bd.Sync.NumPasses_Limit = numIterations; + bd.Sync.DictSize = (UInt64)(Int64)-1; + bd.Sync.NumThreads = (UInt32)(Int32)-1; + bd.Sync.Level = -1; + + COneMethodInfo method; + + UInt32 numCPUs = 1; + #ifndef Z7_ST + numCPUs = NSystem::GetNumberOfProcessors(); + #endif + UInt32 numThreads = numCPUs; + + FOR_VECTOR (i, props) + { + const CProperty &prop = props[i]; + UString name = prop.Name; + name.MakeLower_Ascii(); + if (name.IsEqualTo_Ascii_NoCase("m") && prop.Value.IsEqualTo("*")) + { + bd.TotalMode = true; + continue; + } + + NCOM::CPropVariant propVariant; + if (!prop.Value.IsEmpty()) + ParseNumberString(prop.Value, propVariant); + if (name.IsPrefixedBy("mt")) + { + #ifndef Z7_ST + RINOK(ParseMtProp(name.Ptr(2), propVariant, numCPUs, numThreads)) + if (numThreads != numCPUs) + bd.Sync.NumThreads = numThreads; + #endif + continue; + } + /* + if (name.IsEqualTo("time")) + { + // UInt32 testTime = 4; + // RINOK(ParsePropToUInt32(L"", propVariant, testTime)); + continue; + } + RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant)); + */ + // here we need to parse DictSize property, and ignore unknown properties + method.ParseMethodFromPROPVARIANT(name, propVariant); + } + + if (bd.TotalMode) + { + // bd.Bench2Text.Empty(); + bd.Bench2Text = "7-Zip " MY_VERSION_CPU; + // bd.Bench2Text.Add_Char((char)0xD); + bd.Bench2Text.Add_LF(); + } + + { + UInt64 dict; + if (method.Get_DicSize(dict)) + bd.Sync.DictSize = dict; + } + bd.Sync.Level = (int)method.GetLevel(); + + // Dummy(1000 * 1000 * 1); + + { + CThreadBenchmark &benchmarker = bd._threadBenchmark; + #ifdef Z7_EXTERNAL_CODECS + benchmarker._externalCodecs = _externalCodecs; + #endif + benchmarker.BenchmarkDialog = &bd; + } + + bd.Create(hwndParent); + + return S_OK; +} + + +CBenchmarkDialog::~CBenchmarkDialog() +{ + if (_thread.IsCreated()) + { + /* the following code will be not executed in normal code flow. + it can be called, if there is some internal failure in dialog code. */ + Attach(NULL); + MessageBoxError(L"The flaw in benchmark thread code"); + Sync.SendExit(); + _thread.Wait_Close(); + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.h 2015-06-20 17:56:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,187 +1,15 @@ -// BenchmarkDialog.h - -#ifndef __BENCHMARK_DIALOG_H -#define __BENCHMARK_DIALOG_H - -#include "../../../Windows/Synchronization.h" - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Edit.h" - -#include "../Common/Bench.h" - -#include "../FileManager/DialogSize.h" - -#include "BenchmarkDialogRes.h" - -struct CBenchInfo2 : public CBenchInfo -{ - void Init() { GlobalTime = UserTime = 0; } - - UInt64 GetCompressRating(UInt32 dictSize) const - { - return ::GetCompressRating(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations); - } - - UInt64 GetDecompressRating() const - { - return ::GetDecompressRating(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations); - } -}; - -class CProgressSyncInfo -{ -public: - bool Stopped; - bool Paused; - bool Changed; - UInt32 DictionarySize; - UInt32 NumThreads; - UInt64 NumPasses; - NWindows::NSynchronization::CManualResetEvent _startEvent; - NWindows::NSynchronization::CCriticalSection CS; - - CBenchInfo2 CompressingInfoTemp; - CBenchInfo2 CompressingInfo; - UInt64 ProcessedSize; - - CBenchInfo2 DecompressingInfoTemp; - CBenchInfo2 DecompressingInfo; - - AString Text; - bool TextWasChanged; - - // UString Freq; - // bool FreqWasChanged; - - CProgressSyncInfo() - { - if (_startEvent.Create() != S_OK) - throw 3986437; - } - - void Init() - { - Changed = false; - Stopped = false; - Paused = false; - CompressingInfoTemp.Init(); - CompressingInfo.Init(); - ProcessedSize = 0; - - DecompressingInfoTemp.Init(); - DecompressingInfo.Init(); - - NumPasses = 0; - - // Freq.SetFromAscii("MHz: "); - // FreqWasChanged = true; - - Text.Empty(); - TextWasChanged = true; - } - - void Stop() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Stopped = true; - } - bool WasStopped() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - return Stopped; - } - void Pause() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Paused = true; - } - void Start() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - Paused = false; - } - bool WasPaused() - { - NWindows::NSynchronization::CCriticalSectionLock lock(CS); - return Paused; - } - void WaitCreating() { _startEvent.Lock(); } -}; - -#ifdef _WIN32 -struct CMyFont -{ - HFONT _font; - CMyFont(): _font(NULL) {} - ~CMyFont() - { - if (_font) - DeleteObject(_font); - } - void Create(const LOGFONT *lplf) - { - _font = CreateFontIndirect(lplf); - } -}; -#else -struct CMyFont -{ - CMyFont() {} -}; -#endif - - -class CBenchmarkDialog: - public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox m_Dictionary; - NWindows::NControl::CComboBox m_NumThreads; - NWindows::NControl::CEdit _consoleEdit; - UINT_PTR _timer; - UInt32 _startTime; - CMyFont _font; - - bool OnSize(WPARAM /* wParam */, int xSize, int ySize); - bool OnTimer(WPARAM timerID, LPARAM callback); - virtual bool OnInit(); - void OnRestartButton(); - void OnStopButton(); - void OnHelp(); - virtual void OnCancel(); - bool OnButtonClicked(int buttonID, HWND buttonHWND); - bool OnCommand(int code, int itemID, LPARAM lParam); - - void PrintTime(); - void PrintRating(UInt64 rating, UINT controlID); - void PrintUsage(UInt64 usage, UINT controlID); - void PrintResults( - UInt32 dictionarySize, - const CBenchInfo2 &info, UINT usageID, UINT speedID, UINT rpuID, UINT ratingID, - bool decompressMode = false); - - UInt32 GetNumberOfThreads(); - UInt32 OnChangeDictionary(); - void OnChangeSettings(); -public: - CProgressSyncInfo Sync; - bool TotalMode; - CObjectVector Props; - - CBenchmarkDialog(): _timer(0), TotalMode(false) {} - INT_PTR Create(HWND wndParent = 0) - { - BIG_DIALOG_SIZE(332, 228); - return CModalDialog::Create(TotalMode ? IDD_BENCH_TOTAL : SIZED_DIALOG(IDD_BENCH), wndParent); - } - void MessageBoxError(LPCWSTR message) - { - MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR); - } -}; - -HRESULT Benchmark( - DECL_EXTERNAL_CODECS_LOC_VARS - const CObjectVector props, HWND hwndParent = NULL); - -#endif +// BenchmarkDialog.h + +#ifndef ZIP7_INC_BENCHMARK_DIALOG_H +#define ZIP7_INC_BENCHMARK_DIALOG_H + +#include "../../Common/CreateCoder.h" +#include "../../UI/Common/Property.h" + +const UInt32 k_NumBenchIterations_Default = 10; + +HRESULT Benchmark( + DECL_EXTERNAL_CODECS_LOC_VARS + const CObjectVector &props, UInt32 numIterations, HWND hwndParent = NULL); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog.rc 2025-07-03 12:00:00.000000000 +0000 @@ -0,0 +1,288 @@ +#include "BenchmarkDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 332 +#define yc 248 + +#undef g0xs +#undef g1x +#undef g1xs +#undef g2xs +#undef g3x +#undef g3xs +#undef g4x + +#define gs 160 +#define gSpace 24 + +#define g0xs 90 +#define g1xs 48 +#define g1x (m + g0xs) +#define gc2x (g1x + g1xs + m) +#define gc2xs 80 + +#define g4x (m + m) + +#define sRating 58 +#define sSpeed 60 +#define sUsage 46 +#define sRpu 58 +#define sSize 52 +// #define sFreq 34 + +#define xRating (xs - m - m - sRating) +#define xRpu (xRating - sRpu) +#define xUsage (xRpu - sUsage) +#define xSpeed (xUsage - sSpeed) +#define xSize (xSpeed - sSize) + +// #define xFreq (xUsage - sFreq) + +#define sLabel (xSize - g4x) +#define sTotalRating (sUsage + sRpu + sRating + m + m) +#define xTotalRating (xs - m - sTotalRating) + +#define sPasses 60 + +#define g2xs 60 +#define g3xs 64 +#define g3x (m + g2xs) + +#undef GROUP_Y_SIZE +#undef GROUP_Y2_SIZE +#ifdef UNDER_CE +#define GROUP_Y_SIZE 8 +#define GROUP_Y2_SIZE 8 +#else +#define GROUP_Y_SIZE 40 +#define GROUP_Y2_SIZE 32 +#endif + +#define g7xs bx1 - m - g0xs - g1xs - m + +#define sLog 140 + 0 + +// MY_MODAL_DIALOG_STYLE +IDD_BENCH DIALOG 0, 0, xs + sLog, ys MY_MODAL_RESIZE_DIALOG_STYLE | WS_MINIMIZEBOX +CAPTION "Benchmark" +MY_FONT +BEGIN + PUSHBUTTON "&Restart", IDB_RESTART, bx1, m, bxs, bys + PUSHBUTTON "&Stop", IDB_STOP, bx1, m + bys + 6, bxs, bys + + PUSHBUTTON "&Help", IDHELP, bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + + LTEXT "&Dictionary size:", IDT_BENCH_DICTIONARY, m, m + 1, g0xs, 8 + COMBOBOX IDC_BENCH_DICTIONARY, g1x, m, g1xs, 140, MY_COMBO + + LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m - 2, g7xs, 8 + LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, MY_TEXT_NOPREFIX + + LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 30, g0xs, 8 + COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 29, g1xs, 140, MY_COMBO + LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 30, g7xs, 24, SS_NOPREFIX + + RTEXT "Size", IDT_BENCH_SIZE, xSize, 54, sSize, MY_TEXT_NOPREFIX + RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, MY_TEXT_NOPREFIX + RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, MY_TEXT_NOPREFIX + RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, MY_TEXT_NOPREFIX + RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, MY_TEXT_NOPREFIX + + GROUPBOX "Compressing", IDG_BENCH_COMPRESSING, m, 64, xc, GROUP_Y_SIZE + + LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SIZE1, xSize, 76, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, MY_TEXT_NOPREFIX + + LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SIZE2, xSize, 89, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, MY_TEXT_NOPREFIX + + GROUPBOX "Decompressing", IDG_BENCH_DECOMPRESSING, m, 111, xc, GROUP_Y_SIZE + + LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SIZE1, xSize, 123, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, MY_TEXT_NOPREFIX + + LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SIZE2, xSize, 136, sSize, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, MY_TEXT_NOPREFIX + + RTEXT "", IDT_BENCH_ERROR_MESSAGE, m, 155, xc, MY_TEXT_NOPREFIX + + GROUPBOX "Total Rating", IDG_BENCH_TOTAL_RATING, xTotalRating, 163, sTotalRating, GROUP_Y2_SIZE + + RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, MY_TEXT_NOPREFIX + + + // RTEXT "", IDT_BENCH_CPU, m + sPasses, 202, xc - sPasses, 16, SS_NOPREFIX + RTEXT "", IDT_BENCH_CPU, m + 0, 202, xc - 0, 16, SS_NOPREFIX + RTEXT "", IDT_BENCH_VER, m + xc - 100, 222, 100, MY_TEXT_NOPREFIX + + LTEXT "", IDT_BENCH_CPU_FEATURE, m, 222, xc - 100, 16, SS_NOPREFIX // - 100 + LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, MY_TEXT_NOPREFIX + LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, MY_TEXT_NOPREFIX + + LTEXT "", IDT_BENCH_LOG, m + xc + m, m, sLog - m, yc, SS_LEFTNOWORDWRAP | SS_NOPREFIX + + + LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 163, g2xs, 8 +// LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8 + LTEXT "Passes:", IDT_BENCH_PASSES, m, 176, g2xs, 8 + COMBOBOX IDC_BENCH_NUM_PASSES, m, 187, sPasses, 140, MY_COMBO + + RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, MY_TEXT_NOPREFIX + // RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX + RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX + +END + +#ifdef UNDER_CE + +#undef m +#define m 4 + +#undef xc +#undef yc + +#define xc 154 +#define yc 160 + +#undef g0xs +#undef g1x +#undef g1xs +#undef g2xs +#undef g3x +#undef g3xs + +#undef bxs +#undef bys + +#define bxs 60 +#define bys 14 + +#undef gs +#undef gSpace + +#define gs 160 +#define gSpace 24 + +#define g0xs (xc - bxs) +#define g1xs 44 + +#undef g4x +#define g4x (m) + +#undef xRpu +#undef xUsage +#undef xRating +#undef xTotalRating + +#undef sRpu +#undef sRating +#undef sUsage +#undef sLabel +#undef sTotalRating + +#define sRating 40 +#define sUsage 24 +#define sRpu 40 + +#define xRating (xs - m - sRating) +#define xRpu (xRating - sRpu) +#define xUsage (xRpu - sUsage) + +#define sLabel (xUsage - g4x) +#define sTotalRating (sRpu + sRating) +#define xTotalRating (xs - m - sTotalRating) + +#define g3xs 32 +#define g3x (xRpu - g3xs) +#define g2xs (g3x - m) + + +IDD_BENCH_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX +CAPTION "Benchmark" +MY_FONT +BEGIN + PUSHBUTTON "&Restart", IDB_RESTART, bx1, m, bxs, bys + PUSHBUTTON "&Stop", IDB_STOP, bx1, m + bys + m, bxs, bys + + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + + LTEXT "&Dictionary size:", IDT_BENCH_DICTIONARY, m, m, g0xs, 8 + COMBOBOX IDC_BENCH_DICTIONARY, m, m + 11, g1xs, 140, MY_COMBO + + LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 31, g0xs, 8 + COMBOBOX IDC_BENCH_NUM_THREADS, m, 42, g1xs, 140, MY_COMBO + + LTEXT "", IDT_BENCH_MEMORY_VAL, m + g1xs + 8, m + 13, xc - bxs - g1xs - 8, 8 + LTEXT "", IDT_BENCH_HARDWARE_THREADS, m + g1xs + 8, 44, xc - bxs - g1xs - 8, 8 + + LTEXT "Current", IDT_BENCH_CURRENT, g4x, 70, sLabel, 8 + RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 70, sUsage, 8 + RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 70, sRpu, 8 + RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 70, sRating, 8 + + LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 80, sLabel, 8 + RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 80, sUsage, 8 + RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 80, sRpu, 8 + RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 80, sRating, 8 + + LTEXT "Compressing", IDG_BENCH_COMPRESSING, m, 60, xc - bxs, 8 + + LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 104, sLabel, 8 + RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 104, sUsage, 8 + RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 104, sRpu, 8 + RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 104, sRating, 8 + + LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 114, sLabel, 8 + RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 114, sUsage, 8 + RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 114, sRpu, 8 + RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 114, sRating, 8 + + LTEXT "Decompressing", IDG_BENCH_DECOMPRESSING, m, 94, xc, 8 + + RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 140, sRpu, 8 + RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 140, sRating, 8 + + LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 130, g2xs, 8 + LTEXT "Size:", IDT_BENCH_SIZE, m, 140, g2xs, 8 + LTEXT "Passes:", IDT_BENCH_PASSES, m, 150, g2xs, 8 + + RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 130, g3xs, 8 + RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 140, g3xs, 8 + RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 150, g3xs, 8 +END + +#endif + +#include "../../GuiCommon.rc" + +#define xc 360 +#define yc 260 + +IDD_BENCH_TOTAL DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Benchmark" +{ + LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, m, 58, 8 + RTEXT "", IDT_BENCH_ELAPSED_VAL, m + 58, m, 38, 8 + EDITTEXT IDE_BENCH2_EDIT, m, m + 14, xc, yc - bys - m - 14, ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL + PUSHBUTTON "&Help", IDHELP, bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialogRes.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialogRes.h 2021-05-26 10:53:38.000000000 +0000 @@ -1,65 +1,79 @@ -#define IDD_BENCH 7600 -#define IDD_BENCH_2 17600 -#define IDD_BENCH_TOTAL 7699 - -#define IDE_BENCH2_EDIT 100 - -#define IDC_BENCH_DICTIONARY 101 -#define IDT_BENCH_MEMORY_VAL 102 -#define IDC_BENCH_NUM_THREADS 103 -#define IDT_BENCH_HARDWARE_THREADS 104 - -#define IDT_BENCH_VER 105 -#define IDT_BENCH_CPU 106 - -#define IDT_BENCH_COMPRESS_SPEED1 110 -#define IDT_BENCH_COMPRESS_SPEED2 111 -#define IDT_BENCH_COMPRESS_RATING1 112 -#define IDT_BENCH_COMPRESS_RATING2 113 -#define IDT_BENCH_COMPRESS_USAGE1 114 -#define IDT_BENCH_COMPRESS_USAGE2 115 -#define IDT_BENCH_COMPRESS_RPU1 116 -#define IDT_BENCH_COMPRESS_RPU2 117 - -#define IDT_BENCH_DECOMPR_SPEED1 118 -#define IDT_BENCH_DECOMPR_SPEED2 119 -#define IDT_BENCH_DECOMPR_RATING1 120 -#define IDT_BENCH_DECOMPR_RATING2 121 -#define IDT_BENCH_DECOMPR_USAGE1 122 -#define IDT_BENCH_DECOMPR_USAGE2 123 -#define IDT_BENCH_DECOMPR_RPU1 124 -#define IDT_BENCH_DECOMPR_RPU2 125 - -#define IDT_BENCH_TOTAL_RATING_VAL 130 -#define IDT_BENCH_TOTAL_RPU_VAL 131 -#define IDT_BENCH_TOTAL_USAGE_VAL 133 - -#define IDT_BENCH_ELAPSED_VAL 140 -#define IDT_BENCH_SIZE_VAL 141 -#define IDT_BENCH_PASSES_VAL 142 - - -#define IDB_STOP 442 -#define IDB_RESTART 443 - -#define IDT_BENCH_DICTIONARY 4006 -#define IDT_BENCH_NUM_THREADS 4009 - -#define IDT_BENCH_SIZE 1007 -#define IDT_BENCH_ELAPSED 3900 -#define IDT_BENCH_SPEED 3903 - -#define IDT_BENCH_MEMORY 7601 - -#define IDG_BENCH_COMPRESSING 7602 -#define IDG_BENCH_DECOMPRESSING 7603 -#define IDG_BENCH_TOTAL_RATING 7605 - -#define IDT_BENCH_RATING_LABEL 7604 -#define IDT_BENCH_CURRENT 7606 -#define IDT_BENCH_RESULTING 7607 -#define IDT_BENCH_USAGE_LABEL 7608 -#define IDT_BENCH_RPU_LABEL 7609 -#define IDT_BENCH_PASSES 7610 -#define IDT_BENCH_CURRENT2 (7606+50) -#define IDT_BENCH_RESULTING2 (7607+50) +#define IDD_BENCH 7600 +#define IDD_BENCH_2 17600 +#define IDD_BENCH_TOTAL 7699 + +#define IDE_BENCH2_EDIT 100 + +#define IDC_BENCH_DICTIONARY 101 +#define IDT_BENCH_MEMORY_VAL 102 +#define IDC_BENCH_NUM_THREADS 103 +#define IDT_BENCH_HARDWARE_THREADS 104 + +#define IDT_BENCH_VER 105 +#define IDT_BENCH_CPU 106 +#define IDT_BENCH_SYS1 107 +#define IDT_BENCH_SYS2 108 +#define IDT_BENCH_CPU_FEATURE 109 + +#define IDT_BENCH_COMPRESS_SPEED1 110 +#define IDT_BENCH_COMPRESS_SPEED2 111 +#define IDT_BENCH_COMPRESS_RATING1 112 +#define IDT_BENCH_COMPRESS_RATING2 113 +#define IDT_BENCH_COMPRESS_USAGE1 114 +#define IDT_BENCH_COMPRESS_USAGE2 115 +#define IDT_BENCH_COMPRESS_RPU1 116 +#define IDT_BENCH_COMPRESS_RPU2 117 + +#define IDT_BENCH_DECOMPR_SPEED1 118 +#define IDT_BENCH_DECOMPR_SPEED2 119 +#define IDT_BENCH_DECOMPR_RATING1 120 +#define IDT_BENCH_DECOMPR_RATING2 121 +#define IDT_BENCH_DECOMPR_USAGE1 122 +#define IDT_BENCH_DECOMPR_USAGE2 123 +#define IDT_BENCH_DECOMPR_RPU1 124 +#define IDT_BENCH_DECOMPR_RPU2 125 + +#define IDT_BENCH_TOTAL_RATING_VAL 130 +#define IDT_BENCH_TOTAL_RPU_VAL 131 +#define IDT_BENCH_TOTAL_USAGE_VAL 133 + +#define IDT_BENCH_ELAPSED_VAL 140 +// #define IDT_BENCH_SIZE_VAL 141 +#define IDT_BENCH_PASSES_VAL 142 +#define IDC_BENCH_NUM_PASSES 143 + +#define IDT_BENCH_LOG 160 +#define IDT_BENCH_ERROR_MESSAGE 161 + +#define IDT_BENCH_COMPRESS_SIZE1 170 +#define IDT_BENCH_COMPRESS_SIZE2 171 +#define IDT_BENCH_DECOMPR_SIZE1 172 +#define IDT_BENCH_DECOMPR_SIZE2 173 + +// #define IDT_BENCH_FREQ_CUR 150 +// #define IDT_BENCH_FREQ_RES 151 + +#define IDB_STOP 442 +#define IDB_RESTART 443 + +#define IDT_BENCH_DICTIONARY 4006 +#define IDT_BENCH_NUM_THREADS 4009 + +#define IDT_BENCH_SIZE 1007 +#define IDT_BENCH_ELAPSED 3900 +#define IDT_BENCH_SPEED 3903 + +#define IDT_BENCH_MEMORY 7601 + +#define IDG_BENCH_COMPRESSING 7602 +#define IDG_BENCH_DECOMPRESSING 7603 +#define IDG_BENCH_TOTAL_RATING 7605 + +#define IDT_BENCH_RATING_LABEL 7604 +#define IDT_BENCH_CURRENT 7606 +#define IDT_BENCH_RESULTING 7607 +#define IDT_BENCH_USAGE_LABEL 7608 +#define IDT_BENCH_RPU_LABEL 7609 +#define IDT_BENCH_PASSES 7610 +#define IDT_BENCH_CURRENT2 (7606+50) +#define IDT_BENCH_RESULTING2 (7607+50) diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp 2015-06-21 19:23:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -// BenchmarkDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" -#include "BenchmarkDialogRes.h" - -#if 0 - -IDD_BENCH DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX -CAPTION "Benchmark" -MY_FONT -BEGIN - PUSHBUTTON "&Restart", IDB_RESTART, bx1, m, bxs, bys - PUSHBUTTON "&Stop", IDB_STOP, bx1, m + bys + 6, bxs, bys - - PUSHBUTTON "&Help", IDHELP, bx2, by, bxs, bys - PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys - - LTEXT "&Dictionary size:", IDT_BENCH_DICTIONARY, m, m + 1, g0xs, 8 - COMBOBOX IDC_BENCH_DICTIONARY, g1x, m, g1xs, 140, MY_COMBO - - LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m + 1, gc2xs, 8 - LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x + gc2xs, m + 1, 40, 8 - - LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 28, g0xs, 8 - COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 27, g1xs, 140, MY_COMBO - LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 28, 40, 8 - - RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, 8 - RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, 8 - RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, 8 - RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, 8 - - GROUPBOX "Compressing", IDG_BENCH_COMPRESSING, m, 64, xc, GROUP_Y_SIZE - - LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, 8 - RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, 8 - RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, 8 - RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, 8 - RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, 8 - - LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, 8 - RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, 8 - RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, 8 - RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, 8 - RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, 8 - - GROUPBOX "Decompressing", IDG_BENCH_DECOMPRESSING, m, 111, xc, GROUP_Y_SIZE - - LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, 8 - RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, 8 - RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, 8 - RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, 8 - RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, 8 - - LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, 8 - RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, 8 - RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, 8 - RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, 8 - RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, 8 - - GROUPBOX "Total Rating", IDG_BENCH_TOTAL_RATING, xTotalRating, 163, sTotalRating, GROUP_Y2_SIZE - - RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, 8 - RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, 8 - RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, 8 - - RTEXT "", IDT_BENCH_CPU, m, 202, xc, 8 - RTEXT "", IDT_BENCH_VER, m, 216, xc, 8 - - LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 163, g2xs, 8 - LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8 - LTEXT "Passes:", IDT_BENCH_PASSES, m, 189, g2xs, 8 - - RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, 8 - RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, 8 - RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 189, g3xs, 8 -END -#endif // #if 0 - -class CBenchmarkDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CBenchmarkDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : CModalDialogImpl(dialog,parent, id, wxT("Benchmark")) - { - - wxSizer *topsizer = new wxBoxSizer(wxVERTICAL); - - wxSizer *sizerLine1 = new wxBoxSizer(wxHORIZONTAL); - - wxSizer *sizeLine1Btn = new wxBoxSizer(wxVERTICAL); - sizeLine1Btn->Add(new wxButton(this, IDB_RESTART, _T("&Restart")) , 0, wxALL|wxEXPAND, 5 ); - sizeLine1Btn->Add(new wxButton(this, IDB_STOP, _T("&Stop")) , 0, wxALL|wxEXPAND, 5 ); - - wxSizer *sizeLine1Combo = new wxBoxSizer(wxVERTICAL); - - wxComboBox * chcDicoSize = new wxComboBox(this, IDC_BENCH_DICTIONARY, - wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - wxComboBox * chcThread = new wxComboBox(this, IDC_BENCH_NUM_THREADS, - wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - sizeLine1Combo->Add(chcDicoSize , 0, wxALL, 5 ); - sizeLine1Combo->Add(chcThread , 0, wxALL, 5 ); - - wxSizer *sizeLine1ComboLabel = new wxBoxSizer(wxVERTICAL); - sizeLine1ComboLabel->Add(new wxStaticText(this, IDT_BENCH_DICTIONARY, _T("&Dictionary size:")) , 1, wxALL|wxEXPAND, 5 ); - sizeLine1ComboLabel->Add(new wxStaticText(this, IDT_BENCH_MEMORY, _T("&Number of CPU threads:")) , 1, wxALL|wxEXPAND, 5 ); - - wxSizer *sizeLine1Col3 = new wxBoxSizer(wxVERTICAL); - sizeLine1Col3->Add(new wxStaticText(this, IDT_BENCH_MEMORY, _T("Memory usage:")) , 1, wxALL|wxEXPAND, 5 ); - // FIXME sizeLine1Col3->Add(new wxStaticText(this, IDC_BENCHMARK_HARDWARE_THREADS, _T("1")) , 1, wxALL|wxEXPAND, 5 ); - - wxSizer *sizeLine1Col4 = new wxBoxSizer(wxVERTICAL); - sizeLine1Col4->Add(new wxStaticText(this, IDT_BENCH_MEMORY_VAL, _T("0 MB")) , 0, wxALL|wxEXPAND, 5 ); - - sizerLine1->Add(sizeLine1ComboLabel,0, wxALL|wxEXPAND, 5); - sizerLine1->Add(sizeLine1Combo,0, wxALL|wxEXPAND, 5); - sizerLine1->Add(sizeLine1Col3,0, wxALL|wxEXPAND, 5); - sizerLine1->Add(sizeLine1Col4,0, wxALL|wxEXPAND, 5); - sizerLine1->Add(sizeLine1Btn,0, wxALL|wxEXPAND, 5); - - // LABEL (copy the structure of the compressing or decompressing group - - wxStaticBoxSizer * sizerLine2 = new wxStaticBoxSizer(new wxStaticBox(this,wxID_ANY,_T("")),wxVERTICAL); - wxSizer *sizerLabel = new wxBoxSizer(wxHORIZONTAL); - sizerLabel->Add(new wxStaticText(this, wxID_ANY, _T(" ")) , 1, wxALL|wxEXPAND, 5 ); - sizerLabel->Add(new wxStaticText(this, IDT_BENCH_SPEED, _T("Speed")) , 1, wxALL|wxEXPAND, 5 ); - sizerLabel->Add(new wxStaticText(this, IDT_BENCH_USAGE_LABEL, _T("CPU Usage")) , 1, wxALL|wxEXPAND, 5 ); - sizerLabel->Add(new wxStaticText(this, IDT_BENCH_RPU_LABEL, _T("Rating / Usage")), 1, wxALL|wxEXPAND, 5 ); - sizerLabel->Add(new wxStaticText(this, IDT_BENCH_RATING_LABEL, _T("Rating")) , 1, wxALL|wxEXPAND, 5 ); - - sizerLine2->Add(sizerLabel, 0, wxALL|wxEXPAND, 5); - - // GROUP COMPRESSING - - wxStaticBoxSizer * grpCompress = new wxStaticBoxSizer(new wxStaticBox(this,IDG_BENCH_COMPRESSING,_T("Compressing")),wxVERTICAL); - wxSizer *grpCompress1 = new wxBoxSizer(wxHORIZONTAL); - grpCompress1->Add(new wxStaticText(this, IDT_BENCH_CURRENT, _T("Current")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress1->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_SPEED1, _T("100 KB/s")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress1->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_USAGE1, _T("100%")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress1->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_RPU1, _T("0")), 1, wxALL|wxEXPAND, 5 ); - grpCompress1->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_RATING1, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - - wxSizer *grpCompress2 = new wxBoxSizer(wxHORIZONTAL); - grpCompress2->Add(new wxStaticText(this, IDT_BENCH_RESULTING, _T("Resulting")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress2->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_SPEED2, _T("100 KB/s")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress2->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_USAGE2, _T("100%")) , 1, wxALL|wxEXPAND, 5 ); - grpCompress2->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_RPU2, _T("0")) , 1, wxALL|wxEXPAND, 5); - grpCompress2->Add(new wxStaticText(this, IDT_BENCH_COMPRESS_RATING2, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - - grpCompress->Add(grpCompress1, 0, wxALL|wxEXPAND, 5); - grpCompress->Add(grpCompress2, 0, wxALL|wxEXPAND, 5); - - // GROUP DECOMPRESSING - - wxStaticBoxSizer * grpDecompress = new wxStaticBoxSizer(new wxStaticBox(this,IDG_BENCH_DECOMPRESSING,_T("Decompressing")),wxVERTICAL); - wxSizer *grpDecompress1 = new wxBoxSizer(wxHORIZONTAL); - grpDecompress1->Add(new wxStaticText(this, IDT_BENCH_CURRENT2, _T("Current")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress1->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_SPEED1, _T("100 KB/s")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress1->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_USAGE1, _T("100%")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress1->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_RPU1, _T("0")), 1, wxALL|wxEXPAND, 5 ); - grpDecompress1->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_RATING1, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - - wxSizer *grpDecompress2 = new wxBoxSizer(wxHORIZONTAL); - grpDecompress2->Add(new wxStaticText(this, IDT_BENCH_RESULTING2, _T("Resulting")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress2->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_SPEED2, _T("100 KB/s")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress2->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_USAGE2, _T("100%")) , 1, wxALL|wxEXPAND, 5 ); - grpDecompress2->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_RPU2, _T("0")) , 1, wxALL|wxEXPAND, 5); - grpDecompress2->Add(new wxStaticText(this, IDT_BENCH_DECOMPR_RATING2, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - - grpDecompress->Add(grpDecompress1, 0, wxALL|wxEXPAND, 5); - grpDecompress->Add(grpDecompress2, 0, wxALL|wxEXPAND, 5); - - // GROUPE TOTAL RATING - wxStaticBoxSizer * grpTotalRating = new wxStaticBoxSizer(new wxStaticBox(this,IDG_BENCH_TOTAL_RATING,_T("Total Rating")),wxHORIZONTAL); - grpTotalRating->Add(new wxStaticText(this, wxID_ANY, _T("")) , 1, wxALL|wxEXPAND, 5 ); - grpTotalRating->Add(new wxStaticText(this, IDT_BENCH_TOTAL_USAGE_VAL, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - grpTotalRating->Add(new wxStaticText(this, IDT_BENCH_TOTAL_RPU_VAL, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - grpTotalRating->Add(new wxStaticText(this, IDT_BENCH_TOTAL_RATING_VAL, _T("0")) , 1, wxALL|wxEXPAND, 5 ); - - // GROUPE ELAPSED TIME - wxSizer * grpElapsedTime = new wxBoxSizer(wxHORIZONTAL); - - wxSizer * grpElapsedTime1 = new wxBoxSizer(wxVERTICAL); - grpElapsedTime1->Add(new wxStaticText(this, IDT_BENCH_ELAPSED, _T("Elapsed time:")) , 0, wxALL|wxEXPAND, 5 ); - grpElapsedTime1->Add(new wxStaticText(this, IDT_BENCH_SIZE, _T("Size:")) , 0, wxALL|wxEXPAND, 5 ); - grpElapsedTime1->Add(new wxStaticText(this, IDT_BENCH_PASSES, _T("Passes:")) , 0, wxALL|wxEXPAND, 5 ); - - wxSizer * grpElapsedTime2 = new wxBoxSizer(wxVERTICAL); - grpElapsedTime2->Add(new wxStaticText(this, IDT_BENCH_ELAPSED_VAL, _T("00:00:00")) , 0, wxALL|wxEXPAND, 5 ); - grpElapsedTime2->Add(new wxStaticText(this, IDT_BENCH_SIZE_VAL, _T("0")) , 0, wxALL|wxEXPAND, 5 ); - grpElapsedTime2->Add(new wxStaticText(this, IDT_BENCH_PASSES_VAL, _T("0")) , 0, wxALL|wxEXPAND, 5 ); - - grpElapsedTime->Add(grpElapsedTime1,0, wxALL|wxEXPAND, 5); - grpElapsedTime->Add(grpElapsedTime2,0, wxALL|wxEXPAND, 5); - - wxSizer * grp_ElapsedTime_TotalRating = new wxBoxSizer(wxHORIZONTAL); - grp_ElapsedTime_TotalRating->Add(grpElapsedTime, 0, wxALL|wxEXPAND, 5); - grp_ElapsedTime_TotalRating->Add(grpTotalRating, 1, wxALL|wxEXPAND, 5); - - // TOP - topsizer->Add(sizerLine1,0, wxALL|wxEXPAND, 5); - topsizer->Add(sizerLine2,0, wxALL|wxEXPAND, 5); - topsizer->Add(grpCompress, 0, wxALL|wxEXPAND, 5); - topsizer->Add(grpDecompress, 0, wxALL|wxEXPAND, 5); - topsizer->Add(grp_ElapsedTime_TotalRating, 0, wxALL|wxEXPAND, 5); - - topsizer->Add(new wxStaticText(this, IDT_BENCH_CPU, _T("")) , 0, wxALL|wxALIGN_RIGHT, 5 ); - topsizer->Add(new wxStaticText(this, IDT_BENCH_VER, _T("")) , 0, wxALL|wxALIGN_RIGHT, 5 ); - - topsizer->Add(CreateButtonSizer(wxHELP|wxCANCEL), 0, wxALL|wxEXPAND, 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_BENCH,CBenchmarkDialog,0) - -// ---------------------------------------------------------------------------- -// event tables and other macros for wxWidgets -// ---------------------------------------------------------------------------- - -// the event tables connect the wxWidgets events with the functions (event -// handlers) which process them. It can be also done at run-time, but for the -// simple menu events like this the static method is much simpler. -BEGIN_EVENT_TABLE(CBenchmarkDialogImpl, wxDialog) - EVT_TIMER(wxID_ANY, CModalDialogImpl::OnAnyTimer) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_COMBOBOX(wxID_ANY, CModalDialogImpl::OnAnyChoice) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.cpp 2016-05-20 08:49:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.cpp 2025-07-04 09:00:00.000000000 +0000 @@ -1,1729 +1,3824 @@ -// CompressDialog.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/System.h" - -#include "../FileManager/BrowseDialog.h" -#include "../FileManager/FormatUtils.h" -#include "../FileManager/HelpUtils.h" -#include "../FileManager/SplitUtils.h" - -#include "../Explorer/MyMessages.h" - -#include "../Common/ZipRegistry.h" - -#include "CompressDialog.h" - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -#ifdef LANG -#include "../FileManager/LangUtils.h" -#endif - -#include "CompressDialogRes.h" -#include "ExtractRes.h" - -#ifdef LANG -static const UInt32 kLangIDs[] = -{ - IDT_COMPRESS_ARCHIVE, - IDT_COMPRESS_UPDATE_MODE, - IDT_COMPRESS_FORMAT, - IDT_COMPRESS_LEVEL, - IDT_COMPRESS_METHOD, - IDT_COMPRESS_DICTIONARY, - IDT_COMPRESS_ORDER, - IDT_COMPRESS_SOLID, - IDT_COMPRESS_THREADS, - IDT_COMPRESS_PARAMETERS, - - IDG_COMPRESS_OPTIONS, - IDX_COMPRESS_SFX, - IDX_COMPRESS_SHARED, - IDX_COMPRESS_DEL, - - 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, - - IDT_PASSWORD_ENTER, - IDT_PASSWORD_REENTER, - IDX_PASSWORD_SHOW, - - IDT_SPLIT_TO_VOLUMES, - IDT_COMPRESS_PATH_MODE -}; -#endif - -using namespace NWindows; -using namespace NFile; -using namespace NName; -using namespace NDir; - -static const unsigned kHistorySize = 20; - -static LPCWSTR kExeExt = L".exe"; -static LPCWSTR k7zFormat = L"7z"; - -static const UInt32 g_Levels[] = -{ - IDS_METHOD_STORE, - IDS_METHOD_FASTEST, - 0, - IDS_METHOD_FAST, - 0, - IDS_METHOD_NORMAL, - 0, - IDS_METHOD_MAXIMUM, - 0, - IDS_METHOD_ULTRA -}; - -enum EMethodID -{ - kCopy, - kLZMA, - kLZMA2, - kPPMd, - kBZip2, - kDeflate, - kDeflate64, - kPPMdZip -}; - -static const LPCWSTR kMethodsNames[] = -{ - L"Copy", - L"LZMA", - L"LZMA2", - L"PPMd", - L"BZip2", - L"Deflate", - L"Deflate64", - L"PPMd" -}; - -static const EMethodID g_7zMethods[] = -{ - kLZMA2, - kLZMA, - kPPMd, - kBZip2 -}; - -static const EMethodID g_7zSfxMethods[] = -{ - kCopy, - kLZMA, - kLZMA2, - kPPMd -}; - -static const EMethodID g_ZipMethods[] = -{ - kDeflate, - kDeflate64, - kBZip2, - kLZMA, - kPPMdZip -}; - -static const EMethodID g_GZipMethods[] = -{ - kDeflate -}; - -static const EMethodID g_BZip2Methods[] = -{ - kBZip2 -}; - -static const EMethodID g_XzMethods[] = -{ - kLZMA2 -}; - -static const EMethodID g_SwfcMethods[] = -{ - kDeflate - // kLZMA -}; - -struct CFormatInfo -{ - LPCWSTR Name; - UInt32 LevelsMask; - const EMethodID *MathodIDs; - unsigned NumMethods; - bool Filter; - bool Solid; - bool MultiThread; - bool SFX; - - bool Encrypt; - bool EncryptFileNames; -}; - -#define METHODS_PAIR(x) x, ARRAY_SIZE(x) - -static const CFormatInfo g_Formats[] = -{ - { - L"", - (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - 0, 0, - false, false, false, false, false, false - }, - { - k7zFormat, - (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_7zMethods), - true, true, true, true, true, true - }, - { - L"Zip", - (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_ZipMethods), - false, false, true, false, true, false - }, - { - L"GZip", - (1 << 1) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_GZipMethods), - false, false, false, false, false, false - }, - { - L"BZip2", - (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_BZip2Methods), - false, false, true, false, false, false - }, - { - L"xz", - (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_XzMethods), - false, false, true, false, false, false - }, - { - L"Swfc", - (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), - METHODS_PAIR(g_SwfcMethods), - false, false, true, false, false, false - }, - { - L"Tar", - (1 << 0), - 0, 0, - false, false, false, false, false, false - }, - { - L"wim", - (1 << 0), - 0, 0, - false, false, false, false, false, false - } -}; - -static bool IsMethodSupportedBySfx(int methodID) -{ - for (int i = 0; i < ARRAY_SIZE(g_7zSfxMethods); i++) - if (methodID == g_7zSfxMethods[i]) - return true; - return false; -} - -static bool GetMaxRamSizeForProgram(UInt64 &physSize) -{ - physSize = (UInt64)(sizeof(size_t)) << 29; - bool ramSize_Defined = NSystem::GetRamSize(physSize); - const UInt64 kMinSysSize = (1 << 24); - if (physSize <= kMinSysSize) - physSize = 0; - else - physSize -= kMinSysSize; - const UInt64 kMinUseSize = (1 << 24); - if (physSize < kMinUseSize) - physSize = kMinUseSize; - return ramSize_Defined; -} - - -static const - // NCompressDialog::NUpdateMode::EEnum - int - k_UpdateMode_Vals[] = -{ - NCompressDialog::NUpdateMode::kAdd, - NCompressDialog::NUpdateMode::kUpdate, - NCompressDialog::NUpdateMode::kFresh, - NCompressDialog::NUpdateMode::kSync -}; - -static const UInt32 k_UpdateMode_IDs[] = -{ - IDS_COMPRESS_UPDATE_MODE_ADD, - IDS_COMPRESS_UPDATE_MODE_UPDATE, - IDS_COMPRESS_UPDATE_MODE_FRESH, - IDS_COMPRESS_UPDATE_MODE_SYNC -}; - -static const - // NWildcard::ECensorPathMode - int - k_PathMode_Vals[] = -{ - NWildcard::k_RelatPath, - NWildcard::k_FullPath, - NWildcard::k_AbsPath, -}; - -static const UInt32 k_PathMode_IDs[] = -{ - IDS_PATH_MODE_RELAT, - IDS_EXTRACT_PATHS_FULL, - IDS_EXTRACT_PATHS_ABS -}; - -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; -} - - -bool CCompressDialog::OnInit() -{ - #ifdef LANG - LangSetWindowText(*this, IDD_COMPRESS); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - #endif - - _password1Control.Attach(GetItem(IDE_COMPRESS_PASSWORD1)); - _password2Control.Attach(GetItem(IDE_COMPRESS_PASSWORD2)); - _password1Control.SetText(Info.Password); - _password2Control.SetText(Info.Password); - _encryptionMethod.Attach(GetItem(IDC_COMPRESS_ENCRYPTION_METHOD)); - - m_ArchivePath.Attach(GetItem(IDC_COMPRESS_ARCHIVE)); - m_Format.Attach(GetItem(IDC_COMPRESS_FORMAT)); - m_Level.Attach(GetItem(IDC_COMPRESS_LEVEL)); - m_Method.Attach(GetItem(IDC_COMPRESS_METHOD)); - m_Dictionary.Attach(GetItem(IDC_COMPRESS_DICTIONARY)); - m_Order.Attach(GetItem(IDC_COMPRESS_ORDER)); - m_Solid.Attach(GetItem(IDC_COMPRESS_SOLID)); - m_NumThreads.Attach(GetItem(IDC_COMPRESS_THREADS)); - - m_UpdateMode.Attach(GetItem(IDC_COMPRESS_UPDATE_MODE)); - m_PathMode.Attach(GetItem(IDC_COMPRESS_PATH_MODE)); - - m_Volume.Attach(GetItem(IDC_COMPRESS_VOLUME)); - m_Params.Attach(GetItem(IDE_COMPRESS_PARAMETERS)); - - AddVolumeItems(m_Volume); - - m_RegistryInfo.Load(); - 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(); - - { - bool needSetMain = (Info.FormatIndex < 0); - FOR_VECTOR(i, ArcIndices) - { - unsigned arcIndex = ArcIndices[i]; - const CArcInfoEx &ai = (*ArcFormats)[arcIndex]; - int index = (int)m_Format.AddString(ai.Name); - m_Format.SetItemData(index, arcIndex); - if (!needSetMain) - { - if (Info.FormatIndex == (int)arcIndex) - m_Format.SetCurSel(index); - continue; - } - if (i == 0 || ai.Name.IsEqualTo_NoCase(m_RegistryInfo.ArcType)) - { - m_Format.SetCurSel(index); - Info.FormatIndex = arcIndex; - } - } - } - - { - UString fileName; - SetArcPathFields(Info.ArcPath, fileName, true); - StartDirPrefix = DirPrefix; - SetArchiveName(fileName); - } - SetLevel(); - SetParams(); - - for (unsigned i = 0; i < m_RegistryInfo.ArcPaths.Size() && i < kHistorySize; i++) - m_ArchivePath.AddString(m_RegistryInfo.ArcPaths[i]); - - AddComboItems(m_UpdateMode, k_UpdateMode_IDs, ARRAY_SIZE(k_UpdateMode_IDs), - k_UpdateMode_Vals, Info.UpdateMode); - - AddComboItems(m_PathMode, k_PathMode_IDs, ARRAY_SIZE(k_PathMode_IDs), - k_PathMode_Vals, Info.PathMode); - - SetSolidBlockSize(); - SetNumThreads(); - - TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 }; - ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2); - SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s); - - CheckButton(IDX_COMPRESS_SFX, Info.SFXMode); - CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite); - CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing); - - CheckControlsEnable(); - - // OnButtonSFX(); - - SetEncryptionMethod(); - SetMemoryUsage(); - - NormalizePosition(); - - return CModalDialog::OnInit(); -} - -/* -namespace NCompressDialog -{ - bool CInfo::GetFullPathName(UString &result) const - { - #ifndef UNDER_CE - // NDirectory::MySetCurrentDirectory(CurrentDirPrefix); - #endif - FString resultF; - bool res = MyGetFullPathName(us2fs(ArchiveName), resultF); - result = fs2us(resultF); - return res; - } -} -*/ - -void CCompressDialog::UpdatePasswordControl() -{ - bool showPassword = IsShowPasswordChecked(); - TCHAR c = showPassword ? (TCHAR)0: TEXT('*'); - _password1Control.SetPasswordChar(c); - _password2Control.SetPasswordChar(c); - UString password; - _password1Control.GetText(password); - _password1Control.SetText(password); - _password2Control.GetText(password); - _password2Control.SetText(password); - - ShowItem_Bool(IDT_PASSWORD_REENTER, !showPassword); - _password2Control.Show_Bool(!showPassword); -} - -bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDB_COMPRESS_SET_ARCHIVE: - { - OnButtonSetArchive(); - return true; - } - case IDX_COMPRESS_SFX: - { - SetMethod(GetMethodID()); - OnButtonSFX(); - SetMemoryUsage(); - return true; - } - case IDX_PASSWORD_SHOW: - { - UpdatePasswordControl(); - return true; - } - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CCompressDialog::CheckSFXControlsEnable() -{ - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - bool enable = fi.SFX; - if (enable) - { - int methodID = GetMethodID(); - enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); - } - if (!enable) - CheckButton(IDX_COMPRESS_SFX, false); - EnableItem(IDX_COMPRESS_SFX, enable); -} - -/* -void CCompressDialog::CheckVolumeEnable() -{ - bool isSFX = IsSFX(); - m_Volume.Enable(!isSFX); - if (isSFX) - m_Volume.SetText(TEXT("")); -} -*/ - -void CCompressDialog::CheckControlsEnable() -{ - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - Info.SolidIsSpecified = fi.Solid; - bool multiThreadEnable = fi.MultiThread; - Info.MultiThreadIsAllowed = multiThreadEnable; - Info.EncryptHeadersIsAllowed = fi.EncryptFileNames; - - EnableItem(IDC_COMPRESS_SOLID, fi.Solid); - EnableItem(IDC_COMPRESS_THREADS, multiThreadEnable); - - CheckSFXControlsEnable(); - - { - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - - 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()); - - ShowItem_Bool(IDG_COMPRESS_NTFS, - ai.Flags_SymLinks() - || ai.Flags_HardLinks() - || ai.Flags_AltStreams() - || ai.Flags_NtSecure()); - } - // CheckVolumeEnable(); - - EnableItem(IDG_COMPRESS_ENCRYPTION, fi.Encrypt); - - EnableItem(IDT_PASSWORD_ENTER, fi.Encrypt); - EnableItem(IDT_PASSWORD_REENTER, fi.Encrypt); - EnableItem(IDE_COMPRESS_PASSWORD1, fi.Encrypt); - EnableItem(IDE_COMPRESS_PASSWORD2, fi.Encrypt); - EnableItem(IDX_PASSWORD_SHOW, fi.Encrypt); - - EnableItem(IDT_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt); - EnableItem(IDC_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt); - EnableItem(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames); - - ShowItem_Bool(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames); -} - -bool CCompressDialog::IsSFX() -{ - CWindow sfxButton = GetItem(IDX_COMPRESS_SFX); - return sfxButton.IsEnabled() && IsButtonCheckedBool(IDX_COMPRESS_SFX); -} - -static int GetExtDotPos(const UString &s) -{ - int dotPos = s.ReverseFind_Dot(); - if (dotPos > s.ReverseFind_PathSepar() + 1) - return dotPos; - return -1; -} - -void CCompressDialog::OnButtonSFX() -{ - UString fileName; - m_ArchivePath.GetText(fileName); - int dotPos = GetExtDotPos(fileName); - if (IsSFX()) - { - if (dotPos >= 0) - fileName.DeleteFrom(dotPos); - fileName += kExeExt; - m_ArchivePath.SetText(fileName); - } - else - { - if (dotPos >= 0) - { - UString ext = fileName.Ptr(dotPos); - if (ext.IsEqualTo_NoCase(kExeExt)) - { - fileName.DeleteFrom(dotPos); - m_ArchivePath.SetText(fileName); - } - } - SetArchiveName2(false); // it's for OnInit - } - - // CheckVolumeEnable(); -} - -bool CCompressDialog::GetFinalPath_Smart(UString &resPath) -{ - UString name; - m_ArchivePath.GetText(name); - name.Trim(); - UString tempPath = name; - if (!IsAbsolutePath(name)) - { - UString newDirPrefix = DirPrefix; - if (newDirPrefix.IsEmpty()) - newDirPrefix = StartDirPrefix; - FString resultF; - if (!MyGetFullPathName(us2fs(newDirPrefix + name), resultF)) - return false; - tempPath = fs2us(resultF); - } - if (!SetArcPathFields(tempPath, name, false)) - return false; - FString resultF; - if (!MyGetFullPathName(us2fs(DirPrefix + name), resultF)) - return false; - resPath = fs2us(resultF); - return true; -} - -bool CCompressDialog::SetArcPathFields(const UString &path, UString &name, bool always) -{ - FString resDirPrefix; - FString resFileName; - bool res = GetFullPathAndSplit(us2fs(path), resDirPrefix, resFileName); - if (res) - { - DirPrefix = fs2us(resDirPrefix); - name = fs2us(resFileName); - } - else - { - if (!always) - return false; - DirPrefix.Empty(); - name = path; - } - SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); - m_ArchivePath.SetText(name); - return res; -} - -static const wchar_t *k_IncorrectPathMessage = L"Incorrect archive path"; - -void CCompressDialog::OnButtonSetArchive() -{ - UString path; - if (!GetFinalPath_Smart(path)) - { - ShowErrorMessage(*this, k_IncorrectPathMessage); - return; - } - - UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_BROWSE); - UString filterDescription = LangString(IDS_OPEN_TYPE_ALL_FILES); - filterDescription += L" (*.*)"; - UString resPath; - CurrentDirWasChanged = true; - if (!MyBrowseForFile(*this, title, - // DirPrefix.IsEmpty() ? NULL : (const wchar_t *)DirPrefix, - // NULL, - path, - filterDescription, - NULL, // L"*.*", - resPath)) - return; - UString dummyName; - SetArcPathFields(resPath, dummyName, true); -} - -// in ExtractDialog.cpp -extern void AddUniqueString(UStringVector &strings, const UString &srcString); - -static bool IsAsciiString(const UString &s) -{ - for (unsigned i = 0; i < s.Len(); i++) - { - wchar_t c = s[i]; - if (c < 0x20 || c > 0x7F) - return false; - } - return true; -} - -void CCompressDialog::OnOK() -{ - _password1Control.GetText(Info.Password); - if (IsZipFormat()) - { - if (!IsAsciiString(Info.Password)) - { - ShowErrorMessageHwndRes(*this, IDS_PASSWORD_USE_ASCII); - return; - } - UString method = GetEncryptionMethodSpec(); - if (method.IsPrefixedBy_Ascii_NoCase("aes")) - { - if (Info.Password.Len() > 99) - { - ShowErrorMessageHwndRes(*this, IDS_PASSWORD_TOO_LONG); - return; - } - } - } - if (!IsShowPasswordChecked()) - { - UString password2; - _password2Control.GetText(password2); - if (password2 != Info.Password) - { - ShowErrorMessageHwndRes(*this, IDS_PASSWORD_NOT_MATCH); - return; - } - } - - SaveOptionsInMem(); - { - UString s; - if (!GetFinalPath_Smart(s)) - { - ShowErrorMessage(*this, k_IncorrectPathMessage); - return; - } - - m_RegistryInfo.ArcPaths.Clear(); - AddUniqueString(m_RegistryInfo.ArcPaths, s); - Info.ArcPath = s; - } - - Info.UpdateMode = (NCompressDialog::NUpdateMode::EEnum)k_UpdateMode_Vals[m_UpdateMode.GetCurSel()];; - Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()]; - - Info.Level = GetLevelSpec(); - Info.Dictionary = GetDictionarySpec(); - Info.Order = GetOrderSpec(); - Info.OrderMode = GetOrderMode(); - Info.NumThreads = GetNumThreadsSpec(); - - UInt32 solidLogSize = GetBlockSizeSpec(); - Info.SolidBlockSize = 0; - if (solidLogSize > 0 && solidLogSize != (UInt32)(Int32)-1) - Info.SolidBlockSize = (solidLogSize >= 64) ? (UInt64)(Int64)-1 : ((UInt64)1 << solidLogSize); - - Info.Method = GetMethodSpec(); - Info.EncryptionMethod = GetEncryptionMethodSpec(); - Info.FormatIndex = GetFormatIndex(); - Info.SFXMode = IsSFX(); - Info.OpenShareForWrite = IsButtonCheckedBool(IDX_COMPRESS_SHARED); - Info.DeleteAfterCompressing = IsButtonCheckedBool(IDX_COMPRESS_DEL); - - m_RegistryInfo.EncryptHeaders = - 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); - - { - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - 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; - } - - m_Params.GetText(Info.Options); - - UString volumeString; - m_Volume.GetText(volumeString); - volumeString.Trim(); - Info.VolumeSizes.Clear(); - - if (!volumeString.IsEmpty()) - { - if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) - { - ShowErrorMessageHwndRes(*this, IDS_INCORRECT_VOLUME_SIZE); - return; - } - if (!Info.VolumeSizes.IsEmpty()) - { - const UInt64 volumeSize = Info.VolumeSizes.Back(); - if (volumeSize < (100 << 10)) - { - wchar_t s[32]; - ConvertUInt64ToString(volumeSize, s); - if (::MessageBoxW(*this, MyFormatNew(IDS_SPLIT_CONFIRM, s), - L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) - return; - } - } - } - - for (int i = 0; i < m_ArchivePath.GetCount(); i++) - { - UString sTemp; - m_ArchivePath.GetLBText(i, sTemp); - sTemp.Trim(); - AddUniqueString(m_RegistryInfo.ArcPaths, sTemp); - } - - if (m_RegistryInfo.ArcPaths.Size() > kHistorySize) - m_RegistryInfo.ArcPaths.DeleteBack(); - - if (Info.FormatIndex >= 0) - m_RegistryInfo.ArcType = (*ArcFormats)[Info.FormatIndex].Name; - m_RegistryInfo.ShowPassword = IsShowPasswordChecked(); - - m_RegistryInfo.Save(); - - CModalDialog::OnOK(); -} - -static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/add.htm"; - -void CCompressDialog::OnHelp() -{ - ShowHelpWindow(NULL, kHelpTopic); -} - -bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam) -{ - if (code == CBN_SELCHANGE) - { - switch (itemID) - { - case IDC_COMPRESS_ARCHIVE: - { - // we can 't change m_ArchivePath in that handler ! - DirPrefix.Empty(); - SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); - - /* - UString path; - m_ArchivePath.GetText(path); - m_ArchivePath.SetText(L""); - if (IsAbsolutePath(path)) - { - UString fileName; - SetArcPathFields(path, fileName); - SetArchiveName(fileName); - } - */ - return true; - } - case IDC_COMPRESS_FORMAT: - { - bool isSFX = IsSFX(); - SaveOptionsInMem(); - SetLevel(); - SetSolidBlockSize(); - SetNumThreads(); - SetParams(); - CheckControlsEnable(); - SetArchiveName2(isSFX); - SetEncryptionMethod(); - SetMemoryUsage(); - return true; - } - case IDC_COMPRESS_LEVEL: - { - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormatAlways(ai.Name); - NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - fo.ResetForLevelChange(); - SetMethod(); - SetSolidBlockSize(); - SetNumThreads(); - CheckSFXNameChange(); - SetMemoryUsage(); - return true; - } - case IDC_COMPRESS_METHOD: - { - SetDictionary(); - SetOrder(); - SetSolidBlockSize(); - SetNumThreads(); - CheckSFXNameChange(); - SetMemoryUsage(); - return true; - } - case IDC_COMPRESS_DICTIONARY: - case IDC_COMPRESS_ORDER: - { - SetSolidBlockSize(); - SetMemoryUsage(); - return true; - } - case IDC_COMPRESS_THREADS: - { - SetMemoryUsage(); - return true; - } - } - } - return CModalDialog::OnCommand(code, itemID, lParam); -} - -void CCompressDialog::CheckSFXNameChange() -{ - bool isSFX = IsSFX(); - CheckSFXControlsEnable(); - if (isSFX != IsSFX()) - SetArchiveName2(isSFX); -} - -void CCompressDialog::SetArchiveName2(bool prevWasSFX) -{ - UString fileName; - m_ArchivePath.GetText(fileName); - const CArcInfoEx &prevArchiverInfo = (*ArcFormats)[m_PrevFormat]; - if (prevArchiverInfo.Flags_KeepName() || Info.KeepName) - { - UString prevExtension; - if (prevWasSFX) - prevExtension = kExeExt; - else - prevExtension = UString(L'.') + prevArchiverInfo.GetMainExt(); - const unsigned prevExtensionLen = prevExtension.Len(); - if (fileName.Len() >= prevExtensionLen) - if (StringsAreEqualNoCase(fileName.RightPtr(prevExtensionLen), prevExtension)) - fileName.DeleteFrom(fileName.Len() - prevExtensionLen); - } - SetArchiveName(fileName); -} - -// if type.KeepName then use OriginalFileName -// else if !KeepName remove extension -// add new extension - -void CCompressDialog::SetArchiveName(const UString &name) -{ - UString fileName = name; - Info.FormatIndex = GetFormatIndex(); - const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; - m_PrevFormat = Info.FormatIndex; - if (ai.Flags_KeepName()) - { - fileName = OriginalFileName; - } - else - { - if (!Info.KeepName) - { - int dotPos = GetExtDotPos(fileName); - if (dotPos >= 0) - fileName.DeleteFrom(dotPos); - } - } - - if (IsSFX()) - fileName += kExeExt; - else - { - fileName += L'.'; - fileName += ai.GetMainExt(); - } - m_ArchivePath.SetText(fileName); -} - -int CCompressDialog::FindRegistryFormat(const UString &name) -{ - FOR_VECTOR (i, m_RegistryInfo.Formats) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[i]; - if (name.IsEqualTo_NoCase(GetUnicodeString(fo.FormatID))) - return i; - } - return -1; -} - -int CCompressDialog::FindRegistryFormatAlways(const UString &name) -{ - int index = FindRegistryFormat(name); - if (index < 0) - { - NCompression::CFormatOptions fo; - fo.FormatID = GetSystemString(name); - index = m_RegistryInfo.Formats.Add(fo); - } - return index; -} - -int CCompressDialog::GetStaticFormatIndex() -{ - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - for (unsigned i = 0; i < ARRAY_SIZE(g_Formats); i++) - if (ai.Name.IsEqualTo_NoCase(g_Formats[i].Name)) - return i; - return 0; // -1; -} - -void CCompressDialog::SetNearestSelectComboBox(NControl::CComboBox &comboBox, UInt32 value) -{ - for (int i = comboBox.GetCount() - 1; i >= 0; i--) - if ((UInt32)comboBox.GetItemData(i) <= value) - { - comboBox.SetCurSel(i); - return; - } - if (comboBox.GetCount() > 0) - comboBox.SetCurSel(0); -} - -void CCompressDialog::SetLevel() -{ - m_Level.ResetContent(); - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - UInt32 level = 5; - { - int index = FindRegistryFormat(ai.Name); - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - if (fo.Level <= 9) - level = fo.Level; - else - level = 9; - } - } - - for (unsigned i = 0; i <= 9; i++) - { - if ((fi.LevelsMask & (1 << i)) != 0) - { - UInt32 langID = g_Levels[i]; - int index = (int)m_Level.AddString(LangString(langID)); - m_Level.SetItemData(index, i); - } - } - SetNearestSelectComboBox(m_Level, level); - SetMethod(); -} - -void CCompressDialog::SetMethod(int keepMethodId) -{ - m_Method.ResetContent(); - UInt32 level = GetLevel(); - if (level == 0) - { - SetDictionary(); - SetOrder(); - return; - } - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormat(ai.Name); - UString defaultMethod; - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - defaultMethod = fo.Method; - } - bool isSfx = IsSFX(); - bool weUseSameMethod = false; - - for (unsigned m = 0; m < fi.NumMethods; m++) - { - EMethodID methodID = fi.MathodIDs[m]; - if (isSfx) - if (!IsMethodSupportedBySfx(methodID)) - continue; - const LPCWSTR method = kMethodsNames[methodID]; - int itemIndex = (int)m_Method.AddString(GetSystemString(method)); - m_Method.SetItemData(itemIndex, methodID); - if (keepMethodId == methodID) - { - m_Method.SetCurSel(itemIndex); - weUseSameMethod = true; - continue; - } - if ((defaultMethod.IsEqualTo_NoCase(method) || m == 0) && !weUseSameMethod) - m_Method.SetCurSel(itemIndex); - } - - if (!weUseSameMethod) - { - SetDictionary(); - SetOrder(); - } -} - -bool CCompressDialog::IsZipFormat() -{ - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - return ai.Name.IsEqualTo_Ascii_NoCase("zip"); -} - -void CCompressDialog::SetEncryptionMethod() -{ - _encryptionMethod.ResetContent(); - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - if (ai.Name.IsEqualTo_Ascii_NoCase("7z")) - { - _encryptionMethod.AddString(TEXT("AES-256")); - _encryptionMethod.SetCurSel(0); - } - else if (ai.Name.IsEqualTo_Ascii_NoCase("zip")) - { - int index = FindRegistryFormat(ai.Name); - UString encryptionMethod; - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - encryptionMethod = fo.EncryptionMethod; - } - _encryptionMethod.AddString(TEXT("ZipCrypto")); - _encryptionMethod.AddString(TEXT("AES-256")); - _encryptionMethod.SetCurSel(encryptionMethod.IsPrefixedBy_Ascii_NoCase("aes") ? 1 : 0); - } -} - -int CCompressDialog::GetMethodID() -{ - if (m_Method.GetCount() <= 0) - return -1; - return (int)(UInt32)m_Method.GetItemData_of_CurSel(); -} - -UString CCompressDialog::GetMethodSpec() -{ - if (m_Method.GetCount() <= 1) - return UString(); - return kMethodsNames[GetMethodID()]; -} - -UString CCompressDialog::GetEncryptionMethodSpec() -{ - if (_encryptionMethod.GetCount() <= 1) - return UString(); - if (_encryptionMethod.GetCurSel() <= 0) - return UString(); - UString result; - _encryptionMethod.GetText(result); - result.RemoveChar(L'-'); - return result; -} - -void CCompressDialog::AddDictionarySize(UInt32 size) -{ - Byte c = 0; - unsigned moveBits = 0; - if ((size & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } - else if ((size & 0x3FF) == 0) { moveBits = 10; c = 'K'; } - TCHAR s[40]; - ConvertUInt32ToString(size >> moveBits, s); - unsigned pos = MyStringLen(s); - s[pos++] = ' '; - if (moveBits != 0) - s[pos++] = c; - s[pos++] = 'B'; - s[pos++] = 0; - int index = (int)m_Dictionary.AddString(s); - m_Dictionary.SetItemData(index, size); -} - -void CCompressDialog::SetDictionary() -{ - m_Dictionary.ResetContent(); - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormat(ai.Name); - UInt32 defaultDict = (UInt32)(Int32)-1; - - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - if (fo.Method.IsEqualTo_NoCase(GetMethodSpec())) - defaultDict = fo.Dictionary; - } - - int methodID = GetMethodID(); - UInt32 level = GetLevel2(); - if (methodID < 0) - return; - UInt64 maxRamSize; - bool maxRamSize_Defined = GetMaxRamSizeForProgram(maxRamSize); - - switch (methodID) - { - case kLZMA: - case kLZMA2: - { - static const UInt32 kMinDicSize = (1 << 16); - if (defaultDict == (UInt32)(Int32)-1) - { - if (level >= 9) defaultDict = (1 << 26); - else if (level >= 7) defaultDict = (1 << 25); - else if (level >= 5) defaultDict = (1 << 24); - else if (level >= 3) defaultDict = (1 << 20); - else defaultDict = (kMinDicSize); - } - - AddDictionarySize(kMinDicSize); - m_Dictionary.SetCurSel(0); - - for (unsigned i = 20; i <= 31; i++) - for (unsigned j = 0; j < 2; j++) - { - if (i == 20 && j > 0) - continue; - UInt32 dict = ((UInt32)(2 + j) << (i - 1)); - - if (dict > - #ifdef MY_CPU_64BIT - (3 << 29) - #else - (1 << 26) - #endif - ) - continue; - - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if (dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - - // SetNearestSelectComboBox(m_Dictionary, defaultDict); - break; - } - - case kPPMd: - { - if (defaultDict == (UInt32)(Int32)-1) - { - if (level >= 9) defaultDict = (192 << 20); - else if (level >= 7) defaultDict = ( 64 << 20); - else if (level >= 5) defaultDict = ( 16 << 20); - else defaultDict = ( 4 << 20); - } - - for (unsigned i = 20; i < 31; i++) - for (unsigned j = 0; j < 2; j++) - { - if (i == 20 && j > 0) - continue; - UInt32 dict = ((UInt32)(2 + j) << (i - 1)); - if (dict > - #ifdef MY_CPU_64BIT - (1 << 30) - #else - (1 << 29) - #endif - ) - continue; - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - || m_Dictionary.GetCount() == 1) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - - // SetNearestSelectComboBox(m_Dictionary, defaultDict); - break; - } - - case kDeflate: - { - AddDictionarySize(32 << 10); - m_Dictionary.SetCurSel(0); - break; - } - - case kDeflate64: - { - AddDictionarySize(64 << 10); - m_Dictionary.SetCurSel(0); - break; - } - - case kBZip2: - { - if (defaultDict == (UInt32)(Int32)-1) - { - if (level >= 5) defaultDict = (900 << 10); - else if (level >= 3) defaultDict = (500 << 10); - else defaultDict = (100 << 10); - } - - for (unsigned i = 1; i <= 9; i++) - { - UInt32 dict = ((UInt32)i * 100) << 10; - AddDictionarySize(dict); - if (dict <= defaultDict || m_Dictionary.GetCount() == 0) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - - break; - } - - case kPPMdZip: - { - if (defaultDict == (UInt32)(Int32)-1) - defaultDict = (1 << (19 + (level > 8 ? 8 : level))); - - for (unsigned i = 20; i <= 28; i++) - { - UInt32 dict = (1 << i); - AddDictionarySize(dict); - UInt64 decomprSize; - UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize); - if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize)) - || m_Dictionary.GetCount() == 1) - m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); - } - - // SetNearestSelectComboBox(m_Dictionary, defaultDict); - break; - } - } -} - -UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax) -{ - if (c.GetCount() <= defMax) - return (UInt32)(Int32)-1; - return (UInt32)c.GetItemData_of_CurSel(); -} - -UInt32 CCompressDialog::GetLevel2() -{ - UInt32 level = GetLevel(); - if (level == (UInt32)(Int32)-1) - level = 5; - return level; -} - -int CCompressDialog::AddOrder(UInt32 size) -{ - TCHAR s[40]; - ConvertUInt32ToString(size, s); - int index = (int)m_Order.AddString(s); - m_Order.SetItemData(index, size); - return index; -} - -void CCompressDialog::SetOrder() -{ - m_Order.ResetContent(); - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormat(ai.Name); - UInt32 defaultOrder = (UInt32)(Int32)-1; - - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - if (fo.Method.IsEqualTo_NoCase(GetMethodSpec())) - defaultOrder = fo.Order; - } - - int methodID = GetMethodID(); - UInt32 level = GetLevel2(); - if (methodID < 0) - return; - - switch (methodID) - { - case kLZMA: - case kLZMA2: - { - if (defaultOrder == (UInt32)(Int32)-1) - defaultOrder = (level >= 7) ? 64 : 32; - for (unsigned i = 3; i <= 8; i++) - for (unsigned j = 0; j < 2; j++) - { - UInt32 order = ((UInt32)(2 + j) << (i - 1)); - if (order <= 256) - AddOrder(order); - } - AddOrder(273); - SetNearestSelectComboBox(m_Order, defaultOrder); - break; - } - - case kPPMd: - { - if (defaultOrder == (UInt32)(Int32)-1) - { - if (level >= 9) defaultOrder = 32; - else if (level >= 7) defaultOrder = 16; - else if (level >= 5) defaultOrder = 6; - else defaultOrder = 4; - } - - AddOrder(2); - AddOrder(3); - - for (unsigned i = 2; i < 8; i++) - for (unsigned j = 0; j < 4; j++) - { - UInt32 order = (4 + j) << (i - 2); - if (order < 32) - AddOrder(order); - } - - AddOrder(32); - SetNearestSelectComboBox(m_Order, defaultOrder); - break; - } - - case kDeflate: - case kDeflate64: - { - if (defaultOrder == (UInt32)(Int32)-1) - { - if (level >= 9) defaultOrder = 128; - else if (level >= 7) defaultOrder = 64; - else defaultOrder = 32; - } - - for (unsigned i = 3; i <= 8; i++) - for (unsigned j = 0; j < 2; j++) - { - UInt32 order = ((UInt32)(2 + j) << (i - 1));; - if (order <= 256) - AddOrder(order); - } - - AddOrder(methodID == kDeflate64 ? 257 : 258); - SetNearestSelectComboBox(m_Order, defaultOrder); - break; - } - - case kBZip2: - break; - - case kPPMdZip: - { - if (defaultOrder == (UInt32)(Int32)-1) - defaultOrder = level + 3; - for (unsigned i = 2; i <= 16; i++) - AddOrder(i); - SetNearestSelectComboBox(m_Order, defaultOrder); - break; - } - } -} - -bool CCompressDialog::GetOrderMode() -{ - switch (GetMethodID()) - { - case kPPMd: - case kPPMdZip: - return true; - } - return false; -} - -static const UInt32 kNoSolidBlockSize = 0; -static const UInt32 kSolidBlockSize = 64; - -void CCompressDialog::SetSolidBlockSize() -{ - m_Solid.ResetContent(); - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - if (!fi.Solid) - return; - - UInt32 level = GetLevel2(); - if (level == 0) - return; - - UInt32 dict = GetDictionarySpec(); - if (dict == (UInt32)(Int32)-1) - dict = 1; - - UInt32 defaultBlockSize = (UInt32)(Int32)-1; - - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - { - int index = FindRegistryFormat(ai.Name); - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - if (fo.Method.IsEqualTo_NoCase(GetMethodSpec())) - defaultBlockSize = fo.BlockLogSize; - } - } - - { - int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_NON_SOLID)); - m_Solid.SetItemData(index, (UInt32)kNoSolidBlockSize); - m_Solid.SetCurSel(0); - } - - bool needSet = (defaultBlockSize == (UInt32)(Int32)-1); - - for (unsigned i = 20; i <= 36; i++) - { - if (needSet && dict >= (((UInt64)1 << (i - 7))) && i <= 32) - defaultBlockSize = i; - TCHAR s[40]; - ConvertUInt32ToString(1 << (i % 10), s); - if (i < 30) lstrcat(s, TEXT(" M")); - else lstrcat(s, TEXT(" G")); - lstrcat(s, TEXT("B")); - int index = (int)m_Solid.AddString(s); - m_Solid.SetItemData(index, (UInt32)i); - } - - { - int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID)); - m_Solid.SetItemData(index, kSolidBlockSize); - } - - if (defaultBlockSize == (UInt32)(Int32)-1) - defaultBlockSize = kSolidBlockSize; - if (defaultBlockSize != kNoSolidBlockSize) - SetNearestSelectComboBox(m_Solid, defaultBlockSize); -} - -void CCompressDialog::SetNumThreads() -{ - m_NumThreads.ResetContent(); - - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - if (!fi.MultiThread) - return; - - UInt32 numHardwareThreads = NSystem::GetNumberOfProcessors(); - UInt32 defaultValue = numHardwareThreads; - - { - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - int index = FindRegistryFormat(ai.Name); - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - if (fo.Method.IsEqualTo_NoCase(GetMethodSpec()) && fo.NumThreads != (UInt32)(Int32)-1) - defaultValue = fo.NumThreads; - } - } - - UInt32 numAlgoThreadsMax = 1; - int methodID = GetMethodID(); - switch (methodID) - { - case kLZMA: numAlgoThreadsMax = 2; break; - case kLZMA2: numAlgoThreadsMax = 32; break; - case kBZip2: numAlgoThreadsMax = 32; break; - } - if (IsZipFormat()) - numAlgoThreadsMax = 128; - for (UInt32 i = 1; i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++) - { - TCHAR s[40]; - ConvertUInt32ToString(i, s); - int index = (int)m_NumThreads.AddString(s); - m_NumThreads.SetItemData(index, (UInt32)i); - } - SetNearestSelectComboBox(m_NumThreads, defaultValue); -} - -UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory) -{ - decompressMemory = UInt64(Int64(-1)); - UInt32 level = GetLevel2(); - if (level == 0) - { - decompressMemory = (1 << 20); - return decompressMemory; - } - UInt64 size = 0; - - const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; - if (fi.Filter && level >= 9) - size += (12 << 20) * 2 + (5 << 20); - UInt32 numThreads = GetNumThreads2(); - - if (IsZipFormat()) - { - UInt32 numSubThreads = 1; - if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5) - numSubThreads = 2; - UInt32 numMainThreads = numThreads / numSubThreads; - if (numMainThreads > 1) - size += (UInt64)numMainThreads << 25; - } - - int methidId = GetMethodID(); - - switch (methidId) - { - case kLZMA: - case kLZMA2: - { - UInt32 hs = dict - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; - if (hs > (1 << 24)) - hs >>= 1; - hs++; - UInt64 size1 = (UInt64)hs * 4; - size1 += (UInt64)dict * 4; - if (level >= 5) - size1 += (UInt64)dict * 4; - size1 += (2 << 20); - - UInt32 numThreads1 = 1; - if (numThreads > 1 && level >= 5) - { - size1 += (2 << 20) + (4 << 20); - numThreads1 = 2; - } - - UInt32 numBlockThreads = numThreads / numThreads1; - - if (methidId == kLZMA || numBlockThreads == 1) - size1 += (UInt64)dict * 3 / 2; - else - { - UInt64 chunkSize = (UInt64)dict << 2; - chunkSize = MyMax(chunkSize, (UInt64)(1 << 20)); - chunkSize = MyMin(chunkSize, (UInt64)(1 << 28)); - chunkSize = MyMax(chunkSize, (UInt64)dict); - size1 += chunkSize * 2; - } - size += size1 * numBlockThreads; - - decompressMemory = dict + (2 << 20); - return size; - } - - case kPPMd: - { - decompressMemory = dict + (2 << 20); - return size + decompressMemory; - } - - case kDeflate: - case kDeflate64: - { - UInt32 order = GetOrder(); - if (order == (UInt32)(Int32)-1) - order = 32; - if (level >= 7) - size += (1 << 20); - size += 3 << 20; - decompressMemory = (2 << 20); - return size; - } - - case kBZip2: - { - decompressMemory = (7 << 20); - UInt64 memForOneThread = (10 << 20); - return size + memForOneThread * numThreads; - } - - case kPPMdZip: - { - decompressMemory = dict + (2 << 20); - return size + (UInt64)decompressMemory * numThreads; - } - } - - return (UInt64)(Int64)-1; -} - -UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory) -{ - return GetMemoryUsage(GetDictionary(), decompressMemory); -} - -void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) -{ - if (value == (UInt64)(Int64)-1) - { - SetItemText(res, TEXT("?")); - return; - } - value = (value + (1 << 20) - 1) >> 20; - TCHAR s[40]; - ConvertUInt64ToString(value, s); - lstrcat(s, TEXT(" MB")); - SetItemText(res, s); -} - -void CCompressDialog::SetMemoryUsage() -{ - UInt64 decompressMem; - UInt64 memUsage = GetMemoryUsage(decompressMem); - PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage); - PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem); -} - -void CCompressDialog::SetParams() -{ - const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()]; - m_Params.SetText(TEXT("")); - int index = FindRegistryFormat(ai.Name); - if (index >= 0) - { - const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - m_Params.SetText(fo.Options); - } -} - -void CCompressDialog::SaveOptionsInMem() -{ - const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; - int index = FindRegistryFormatAlways(ai.Name); - m_Params.GetText(Info.Options); - Info.Options.Trim(); - NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; - fo.Options = Info.Options; - fo.Level = GetLevelSpec(); - fo.Dictionary = GetDictionarySpec(); - fo.Order = GetOrderSpec(); - fo.Method = GetMethodSpec(); - fo.EncryptionMethod = GetEncryptionMethodSpec(); - fo.NumThreads = GetNumThreadsSpec(); - fo.BlockLogSize = GetBlockSizeSpec(); -} - -unsigned CCompressDialog::GetFormatIndex() -{ - return (unsigned)m_Format.GetItemData_of_CurSel(); -} +// CompressDialog.cpp + +#include "StdAfx.h" + +#include "../../../../C/CpuArch.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/System.h" + +#include "../../Common/MethodProps.h" + +#include "../FileManager/BrowseDialog.h" +#include "../FileManager/FormatUtils.h" +#include "../FileManager/HelpUtils.h" +#include "../FileManager/PropertyName.h" +#include "../FileManager/SplitUtils.h" +#include "../FileManager/resourceGui.h" + +#include "../Explorer/MyMessages.h" + +#include "../Common/ZipRegistry.h" + +#include "CompressDialog.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#include "../FileManager/LangUtils.h" + +#include "CompressDialogRes.h" +#include "ExtractRes.h" +#include "resource2.h" + +// #define PRINT_PARAMS + +#ifdef Z7_LANG + +// #define IDS_OPTIONS 2100 + +static const UInt32 kLangIDs[] = +{ + IDT_COMPRESS_ARCHIVE, + IDT_COMPRESS_UPDATE_MODE, + IDT_COMPRESS_FORMAT, + IDT_COMPRESS_LEVEL, + IDT_COMPRESS_METHOD, + IDT_COMPRESS_DICTIONARY, + IDT_COMPRESS_ORDER, + IDT_COMPRESS_SOLID, + IDT_COMPRESS_THREADS, + IDT_COMPRESS_PARAMETERS, + + IDB_COMPRESS_OPTIONS, // IDS_OPTIONS + + IDG_COMPRESS_OPTIONS, + IDX_COMPRESS_SFX, + IDX_COMPRESS_SHARED, + IDX_COMPRESS_DEL, + + IDT_COMPRESS_MEMORY, + IDT_COMPRESS_MEMORY_DE, + + IDG_COMPRESS_ENCRYPTION, + IDT_COMPRESS_ENCRYPTION_METHOD, + IDX_COMPRESS_ENCRYPT_FILE_NAMES, + + IDT_PASSWORD_ENTER, + IDT_PASSWORD_REENTER, + IDX_PASSWORD_SHOW, + + IDT_SPLIT_TO_VOLUMES, + IDT_COMPRESS_PATH_MODE, +}; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NDir; + +static const unsigned kHistorySize = 20; + +static const UInt32 kSolidLog_NoSolid = 0; +static const UInt32 kSolidLog_FullSolid = 64; + +static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28; + +static const UINT k_Message_ArcChanged = WM_APP + 1; + +/* +static const UInt32 kZstd_MAX_DictSize = (UInt32)1 << MY_ZSTD_WINDOWLOG_MAX; +*/ + +/* The top value for windowLog_Chain: + (MY_ZSTD_CHAINLOG_MAX - 1): in BT mode + (MY_ZSTD_CHAINLOG_MAX) : in non-BT mode. But such big value is useless in most cases. + So we always reduce top value to (MY_ZSTD_CHAINLOG_MAX - 1) */ +/* +static const unsigned kMaxDictChain = MY_ZSTD_CHAINLOG_MAX - 1; +static const UInt32 kZstd_MAX_DictSize_Chain = (UInt32)1 << kMaxDictChain; +*/ + +static LPCSTR const kExeExt = ".exe"; + +static const UInt32 g_Levels[] = +{ + IDS_METHOD_STORE, + IDS_METHOD_FASTEST, + 0, + IDS_METHOD_FAST, + 0, + IDS_METHOD_NORMAL, + 0, + IDS_METHOD_MAXIMUM, + 0, + IDS_METHOD_ULTRA +}; + +enum EMethodID +{ + kCopy, + kLZMA, + kLZMA2, + kPPMd, + kBZip2, + kDeflate, + kDeflate64, + kPPMdZip, + // kZSTD, + kSha256, + kSha1, + kCrc32, + kCrc64, + kGnu, + kPosix +}; + +static LPCSTR const kMethodsNames[] = +{ + "Copy" + , "LZMA" + , "LZMA2" + , "PPMd" + , "BZip2" + , "Deflate" + , "Deflate64" + , "PPMd" + // , "ZSTD" + , "SHA256" + , "SHA1" + , "CRC32" + , "CRC64" + , "GNU" + , "POSIX" +}; + +static const EMethodID g_7zMethods[] = +{ + kLZMA2, + kLZMA, + kPPMd, + kBZip2 + , kDeflate + , kDeflate64 + // , kZSTD + , kCopy +}; + +static const EMethodID g_7zSfxMethods[] = +{ + kCopy, + kLZMA, + kLZMA2, + kPPMd +}; + +static const EMethodID g_ZipMethods[] = +{ + kDeflate, + kDeflate64, + kBZip2, + kLZMA, + kPPMdZip + // , kZSTD +}; + +static const EMethodID g_GZipMethods[] = +{ + kDeflate +}; + +static const EMethodID g_BZip2Methods[] = +{ + kBZip2 +}; + +static const EMethodID g_XzMethods[] = +{ + kLZMA2 +}; + +/* +static const EMethodID g_ZstdMethods[] = +{ + kZSTD +}; +*/ + +/* +static const EMethodID g_SwfcMethods[] = +{ + kDeflate + // kLZMA +}; +*/ + +static const EMethodID g_TarMethods[] = +{ + kGnu, + kPosix +}; + +static const EMethodID g_HashMethods[] = +{ + kSha256 + , kSha1 + // , kCrc32 + // , kCrc64 +}; + +static const UInt32 kFF_Filter = 1 << 0; +static const UInt32 kFF_Solid = 1 << 1; +static const UInt32 kFF_MultiThread = 1 << 2; +static const UInt32 kFF_Encrypt = 1 << 3; +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; + UInt32 LevelsMask; + unsigned NumMethods; + const EMethodID *MethodIDs; + + UInt32 Flags; + + bool Filter_() const { return (Flags & kFF_Filter) != 0; } + bool Solid_() const { return (Flags & kFF_Solid) != 0; } + bool MultiThread_() const { return (Flags & kFF_MultiThread) != 0; } + bool Encrypt_() const { return (Flags & kFF_Encrypt) != 0; } + bool EncryptFileNames_() const { return (Flags & kFF_EncryptFileNames) != 0; } + bool MemUse_() const { return (Flags & kFF_MemUse) != 0; } + bool SFX_() const { return (Flags & kFF_SFX) != 0; } +}; + +#define METHODS_PAIR(x) Z7_ARRAY_SIZE(x), x + +static const CFormatInfo g_Formats[] = +{ + { + "", + // (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + ((UInt32)1 << 10) - 1, + // (UInt32)(Int32)-1, + 0, NULL, + kFF_MultiThread | kFF_MemUse + }, + { + "7z", + // (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + (1 << 10) - 1, + METHODS_PAIR(g_7zMethods), + kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt | + kFF_EncryptFileNames | kFF_MemUse | kFF_SFX + // | 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", + (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + METHODS_PAIR(g_BZip2Methods), + kFF_MultiThread | kFF_MemUse + }, + { + "xz", + // (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + (1 << 10) - 1 - (1 << 0), // store (1 << 0) is not supported + METHODS_PAIR(g_XzMethods), + kFF_Solid | kFF_MultiThread | kFF_MemUse + }, + /* + { + "zstd", + // (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1, + (1 << (9 + 1)) - 1, + METHODS_PAIR(g_ZstdMethods), + // kFF_Solid | + kFF_MultiThread + | kFF_MemUse + }, + */ +/* + { + "Swfc", + (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + METHODS_PAIR(g_SwfcMethods), + 0 + }, +*/ + { + "Tar", + (1 << 0), + METHODS_PAIR(g_TarMethods), + 0 + // kFF_Time_Unix | kFF_Time_Win // | kFF_Time_1ns + }, + { + "wim", + (1 << 0), + 0, NULL, + 0 + // | kFF_Time_Win + }, + { + "Hash", + (0 << 0), + METHODS_PAIR(g_HashMethods), + 0 + } +}; + +static bool IsMethodSupportedBySfx(int methodID) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_7zSfxMethods); i++) + if (methodID == g_7zSfxMethods[i]) + return true; + return false; +} + + +static const + // NCompressDialog::NUpdateMode::EEnum + int + k_UpdateMode_Vals[] = +{ + NCompressDialog::NUpdateMode::kAdd, + NCompressDialog::NUpdateMode::kUpdate, + NCompressDialog::NUpdateMode::kFresh, + NCompressDialog::NUpdateMode::kSync +}; + +static const UInt32 k_UpdateMode_IDs[] = +{ + IDS_COMPRESS_UPDATE_MODE_ADD, + IDS_COMPRESS_UPDATE_MODE_UPDATE, + IDS_COMPRESS_UPDATE_MODE_FRESH, + IDS_COMPRESS_UPDATE_MODE_SYNC +}; + +static const + // NWildcard::ECensorPathMode + int + k_PathMode_Vals[] = +{ + NWildcard::k_RelatPath, + NWildcard::k_FullPath, + NWildcard::k_AbsPath, +}; + +static const UInt32 k_PathMode_IDs[] = +{ + IDS_PATH_MODE_RELAT, + IDS_EXTRACT_PATHS_FULL, + IDS_EXTRACT_PATHS_ABS +}; + +void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal); + +void CCompressDialog::SetMethods(const CObjectVector &userCodecs) +{ + ExternalMethods.Clear(); + { + FOR_VECTOR (i, userCodecs) + { + const CCodecInfoUser &c = userCodecs[i]; + if (!c.EncoderIsAssigned + || !c.IsFilter_Assigned + || c.IsFilter + || c.NumStreams != 1) + continue; + unsigned k; + for (k = 0; k < Z7_ARRAY_SIZE(g_7zMethods); k++) + if (c.Name.IsEqualTo_Ascii_NoCase(kMethodsNames[g_7zMethods[k]])) + break; + if (k != Z7_ARRAY_SIZE(g_7zMethods)) + continue; + ExternalMethods.Add(c.Name); + } + } +} + + +bool CCompressDialog::OnInit() +{ + #ifdef Z7_LANG + LangSetWindowText(*this, IDD_COMPRESS); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + // LangSetDlgItemText(*this, IDB_COMPRESS_OPTIONS, IDS_OPTIONS); // IDG_COMPRESS_OPTIONS + #endif + + { + size_t size = (size_t)sizeof(size_t) << 29; + _ramSize_Defined = NSystem::GetRamSize(size); + // size = (UInt64)3 << 62; // for debug only; + { + // we use reduced limit for 32-bit version: + unsigned bits = sizeof(size_t) * 8; + if (bits == 32) + { + const UInt32 limit2 = (UInt32)7 << 28; + if (size > limit2) + size = limit2; + } + } + _ramSize = size; + const size_t kMinUseSize = 1 << 26; + if (size < kMinUseSize) + size = kMinUseSize; + _ramSize_Reduced = size; + + // 80% - is auto usage limit in handlers + _ramUsage_Auto = Calc_From_Val_Percents(size, 80); + } + + _password1Control.Attach(GetItem(IDE_COMPRESS_PASSWORD1)); + _password2Control.Attach(GetItem(IDE_COMPRESS_PASSWORD2)); + _password1Control.SetText(Info.Password); + _password2Control.SetText(Info.Password); + _encryptionMethod.Attach(GetItem(IDC_COMPRESS_ENCRYPTION_METHOD)); + _default_encryptionMethod_Index = -1; + + m_ArchivePath.Attach(GetItem(IDC_COMPRESS_ARCHIVE)); + m_Format.Attach(GetItem(IDC_COMPRESS_FORMAT)); // that combo has CBS_SORT style in resources + m_Level.Attach(GetItem(IDC_COMPRESS_LEVEL)); + m_Method.Attach(GetItem(IDC_COMPRESS_METHOD)); + m_Dictionary.Attach(GetItem(IDC_COMPRESS_DICTIONARY)); + + /* + { + RECT r; + GetClientRectOfItem(IDC_COMPRESS_DICTIONARY, r); + _dictionaryCombo_left = r.left; + } + */ + _dictionaryCombo_left = 0; // 230; + + // m_Dictionary_Chain.Attach(GetItem(IDC_COMPRESS_DICTIONARY2)); + m_Order.Attach(GetItem(IDC_COMPRESS_ORDER)); + m_Solid.Attach(GetItem(IDC_COMPRESS_SOLID)); + m_NumThreads.Attach(GetItem(IDC_COMPRESS_THREADS)); + m_MemUse.Attach(GetItem(IDC_COMPRESS_MEM_USE)); + + m_UpdateMode.Attach(GetItem(IDC_COMPRESS_UPDATE_MODE)); + m_PathMode.Attach(GetItem(IDC_COMPRESS_PATH_MODE)); + + m_Volume.Attach(GetItem(IDC_COMPRESS_VOLUME)); + m_Params.Attach(GetItem(IDE_COMPRESS_PARAMETERS)); + + AddVolumeItems(m_Volume); + + m_RegistryInfo.Load(); + CheckButton(IDX_PASSWORD_SHOW, m_RegistryInfo.ShowPassword); + CheckButton(IDX_COMPRESS_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders); + + UpdatePasswordControl(); + + { + const bool needSetMain = (Info.FormatIndex < 0); + FOR_VECTOR(i, ArcIndices) + { + const unsigned arcIndex = ArcIndices[i]; + const CArcInfoEx &ai = (*ArcFormats)[arcIndex]; + const int index = (int)m_Format.AddString(ai.Name); + m_Format.SetItemData(index, (LPARAM)arcIndex); + if (!needSetMain) + { + if (Info.FormatIndex == (int)arcIndex) + m_Format.SetCurSel(index); + continue; + } + if (i == 0 || ai.Name.IsEqualTo_NoCase(m_RegistryInfo.ArcType)) + { + m_Format.SetCurSel(index); + Info.FormatIndex = (int)arcIndex; + } + } + } + + CheckButton(IDX_COMPRESS_SFX, Info.SFXMode); + + { + UString fileName; + SetArcPathFields(Info.ArcPath, fileName, true); + StartDirPrefix = DirPrefix; + SetArchiveName(fileName); + } + + for (unsigned i = 0; i < m_RegistryInfo.ArcPaths.Size() && i < kHistorySize; i++) + m_ArchivePath.AddString(m_RegistryInfo.ArcPaths[i]); + + AddComboItems(m_UpdateMode, k_UpdateMode_IDs, Z7_ARRAY_SIZE(k_UpdateMode_IDs), + k_UpdateMode_Vals, Info.UpdateMode); + + AddComboItems(m_PathMode, k_PathMode_IDs, Z7_ARRAY_SIZE(k_PathMode_IDs), + k_PathMode_Vals, Info.PathMode); + + + TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 }; + ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2); + SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s); + + CheckButton(IDX_COMPRESS_SHARED, Info.OpenShareForWrite); + CheckButton(IDX_COMPRESS_DEL, Info.DeleteAfterCompressing); + + FormatChanged(false); // isChanged + + // OnButtonSFX(); + + NormalizePosition(); + + return CModalDialog::OnInit(); +} + +/* +namespace NCompressDialog +{ + bool CInfo::GetFullPathName(UString &result) const + { + #ifndef UNDER_CE + // NDirectory::MySetCurrentDirectory(CurrentDirPrefix); + #endif + FString resultF; + bool res = MyGetFullPathName(us2fs(ArchiveName), resultF); + result = fs2us(resultF); + return res; + } +} +*/ + +void CCompressDialog::UpdatePasswordControl() +{ + const bool showPassword = IsShowPasswordChecked(); + const TCHAR c = showPassword ? (TCHAR)0: TEXT('*'); + _password1Control.SetPasswordChar((WPARAM)c); + _password2Control.SetPasswordChar((WPARAM)c); + UString password; + _password1Control.GetText(password); + _password1Control.SetText(password); + _password2Control.GetText(password); + _password2Control.SetText(password); + + ShowItem_Bool(IDT_PASSWORD_REENTER, !showPassword); + _password2Control.Show_Bool(!showPassword); +} + +bool CCompressDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_COMPRESS_SET_ARCHIVE: + { + OnButtonSetArchive(); + return true; + } + case IDX_COMPRESS_SFX: + { + SetMethod(GetMethodID()); + OnButtonSFX(); + SetMemoryUsage(); + return true; + } + case IDX_PASSWORD_SHOW: + { + UpdatePasswordControl(); + return true; + } + case IDB_COMPRESS_OPTIONS: + { + COptionsDialog dialog(this); + if (dialog.Create(*this) == IDOK) + ShowOptionsString(); + return true; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CCompressDialog::CheckSFXControlsEnable() +{ + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + bool enable = fi.SFX_(); + if (enable) + { + const int methodID = GetMethodID(); + enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); + } + if (!enable) + CheckButton(IDX_COMPRESS_SFX, false); + EnableItem(IDX_COMPRESS_SFX, enable); +} + +/* +void CCompressDialog::CheckVolumeEnable() +{ + bool isSFX = IsSFX(); + m_Volume.Enable(!isSFX); + if (isSFX) + m_Volume.SetText(TEXT("")); +} +*/ + +void CCompressDialog::EnableMultiCombo(unsigned id) +{ + NWindows::NControl::CComboBox combo; + combo.Attach(GetItem(id)); + const bool enable = (combo.GetCount() > 1); + EnableItem(id, enable); +} + +static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s); + +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(); + SetParams(); + SetMemUseCombo(); + SetNumThreads(); + + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + Info.SolidIsSpecified = fi.Solid_(); + Info.EncryptHeadersIsAllowed = fi.EncryptFileNames_(); + + /* + const bool multiThreadEnable = fi.MultiThread; + Info.MultiThreadIsAllowed = multiThreadEnable; + EnableItem(IDC_COMPRESS_SOLID, fi.Solid); + EnableItem(IDC_COMPRESS_THREADS, multiThreadEnable); + const bool methodEnable = (fi.MethodIDs != NULL); + EnableItem(IDC_COMPRESS_METHOD, methodEnable); + EnableMultiCombo(IDC_COMPRESS_DICTIONARY, methodEnable); + EnableItem(IDC_COMPRESS_ORDER, methodEnable); + */ + + CheckSFXControlsEnable(); + + { + if (!isChanged) + { + SET_GUI_BOOL (SymLinks); + SET_GUI_BOOL (HardLinks); + SET_GUI_BOOL (AltStreams); + SET_GUI_BOOL (NtSecurity); + SET_GUI_BOOL (PreserveATime); + } + + 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(); + + const bool encrypt = fi.Encrypt_(); + EnableItem(IDG_COMPRESS_ENCRYPTION, encrypt); + + EnableItem(IDT_PASSWORD_ENTER, encrypt); + EnableItem(IDT_PASSWORD_REENTER, encrypt); + EnableItem(IDE_COMPRESS_PASSWORD1, encrypt); + EnableItem(IDE_COMPRESS_PASSWORD2, encrypt); + EnableItem(IDX_PASSWORD_SHOW, encrypt); + + EnableItem(IDT_COMPRESS_ENCRYPTION_METHOD, encrypt); + EnableItem(IDC_COMPRESS_ENCRYPTION_METHOD, encrypt); + EnableItem(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames_()); + + ShowItem_Bool(IDX_COMPRESS_ENCRYPT_FILE_NAMES, fi.EncryptFileNames_()); + + SetEncryptionMethod(); + SetMemoryUsage(); +} + + +bool CCompressDialog::IsSFX() +{ + return IsWindowEnabled(GetItem(IDX_COMPRESS_SFX)) + && IsButtonCheckedBool(IDX_COMPRESS_SFX); +} + +static int GetExtDotPos(const UString &s) +{ + const int dotPos = s.ReverseFind_Dot(); + if (dotPos > s.ReverseFind_PathSepar() + 1) + return dotPos; + return -1; +} + +void CCompressDialog::OnButtonSFX() +{ + UString fileName; + m_ArchivePath.GetText(fileName); + const int dotPos = GetExtDotPos(fileName); + if (IsSFX()) + { + if (dotPos >= 0) + fileName.DeleteFrom(dotPos); + fileName += kExeExt; + m_ArchivePath.SetText(fileName); + } + else + { + if (dotPos >= 0) + { + const UString ext = fileName.Ptr(dotPos); + if (ext.IsEqualTo_Ascii_NoCase(kExeExt)) + { + fileName.DeleteFrom(dotPos); + m_ArchivePath.SetText(fileName); + } + } + SetArchiveName2(false); // it's for OnInit + } + + // CheckVolumeEnable(); +} + + +bool CCompressDialog::GetFinalPath_Smart(UString &resPath) const +{ + resPath.Empty(); + UString name; + m_ArchivePath.GetText(name); + name.Trim(); + FString fullPath; + UString dirPrefx = DirPrefix; + if (dirPrefx.IsEmpty()) + dirPrefx = StartDirPrefix; + const bool res = !dirPrefx.IsEmpty() ? + NName::GetFullPath(us2fs(dirPrefx), us2fs(name), fullPath): + NName::GetFullPath( us2fs(name), fullPath); + if (res) + resPath = fs2us(fullPath); + return res; +} + + +bool CCompressDialog::SetArcPathFields(const UString &path) +{ + UString name; + return SetArcPathFields(path, name, true); // always +} + + +bool CCompressDialog::SetArcPathFields(const UString &path, UString &name, bool always) +{ + FString resDirPrefix; + FString resFileName; + const bool res = GetFullPathAndSplit(us2fs(path), resDirPrefix, resFileName); + if (res) + { + DirPrefix = fs2us(resDirPrefix); + name = fs2us(resFileName); + } + else + { + if (!always) + return false; + DirPrefix.Empty(); + name = path; + } + SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); + m_ArchivePath.SetText(name); + return res; +} + + +static const wchar_t * const k_IncorrectPathMessage = L"Incorrect archive path"; + +static void AddFilter(CObjectVector &filters, + const UString &description, const UString &ext) +{ + CBrowseFilterInfo &f = filters.AddNew(); + UString mask ("*."); + mask += ext; + f.Masks.Add(mask); + f.Description = description; + f.Description += " ("; + f.Description += mask; + f.Description += ")"; +} + + +static const char * const k_DontSave_Exts = + "xpi odt ods docx xlsx "; + +void CCompressDialog::OnButtonSetArchive() +{ + UString path; + if (!GetFinalPath_Smart(path)) + { + ShowErrorMessage(*this, k_IncorrectPathMessage); + return; + } + + int filterIndex; + CObjectVector filters; + unsigned numFormats = 0; + + const bool isSFX = IsSFX(); + if (isSFX) + { + filterIndex = 0; + const UString ext ("exe"); + AddFilter(filters, ext, ext); + } + else + { + filterIndex = m_Format.GetCurSel(); + numFormats = (unsigned)m_Format.GetCount(); + + // filters [0, ... numFormats - 1] corresponds to items in m_Format combo + UString desc; + UStringVector masks; + CStringFinder finder; + + for (unsigned i = 0; i < numFormats; i++) + { + const CArcInfoEx &ai = (*ArcFormats)[(unsigned)m_Format.GetItemData(i)]; + CBrowseFilterInfo &f = filters.AddNew(); + f.Description = ai.Name; + f.Description += " ("; + bool needSpace_desc = false; + + FOR_VECTOR (k, ai.Exts) + { + const UString &ext = ai.Exts[k].Ext; + UString mask ("*."); + mask += ext; + + if (finder.FindWord_In_LowCaseAsciiList_NoCase(k_DontSave_Exts, ext)) + continue; + + f.Masks.Add(mask); + masks.Add(mask); + if (needSpace_desc) + f.Description.Add_Space(); + needSpace_desc = true; + f.Description += ext; + } + f.Description += ")"; + // we use only main ext in desc to reduce the size of list + if (i != 0) + desc.Add_Space(); + desc += ai.GetMainExt(); + } + + CBrowseFilterInfo &f = filters.AddNew(); + f.Description = LangString(IDT_COMPRESS_ARCHIVE); // IDS_ARCHIVES_COLON; + if (f.Description.IsEmpty()) + GetItemText(IDT_COMPRESS_ARCHIVE, f.Description); + f.Description.RemoveChar(L'&'); + // f.Description = "archive"; + f.Description += " ("; + f.Description += desc; + f.Description += ")"; + f.Masks = masks; + } + + AddFilter(filters, LangString(IDS_OPEN_TYPE_ALL_FILES), UString("*")); + if (filterIndex < 0) + filterIndex = (int)filters.Size() - 1; + + const UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_BROWSE); + CBrowseInfo bi; + bi.lpstrTitle = title; + bi.SaveMode = true; + bi.FilterIndex = filterIndex; + bi.hwndOwner = *this; + bi.FilePath = path; + + if (!bi.BrowseForFile(filters)) + return; + + path = bi.FilePath; + + if (isSFX) + { + const int dotPos = GetExtDotPos(path); + if (dotPos >= 0) + path.DeleteFrom(dotPos); + path += kExeExt; + } + else + // if (bi.FilterIndex >= 0) + // if (bi.FilterIndex != filterIndex) + if ((unsigned)bi.FilterIndex < numFormats) + { + // archive format was confirmed. So we try to set format extension + bool needAddExt = true; + const CArcInfoEx &ai = (*ArcFormats)[(unsigned)m_Format.GetItemData((unsigned)bi.FilterIndex)]; + const int dotPos = GetExtDotPos(path); + if (dotPos >= 0) + { + const UString ext = path.Ptr(dotPos + 1); + if (ai.FindExtension(ext) >= 0) + needAddExt = false; + } + if (needAddExt) + { + if (path.IsEmpty() || path.Back() != '.') + path.Add_Dot(); + path += ai.GetMainExt(); + } + } + + SetArcPathFields(path); + + if (!isSFX) + if ((unsigned)bi.FilterIndex < numFormats) + if (bi.FilterIndex != m_Format.GetCurSel()) + { + m_Format.SetCurSel(bi.FilterIndex); + SaveOptionsInMem(); + FormatChanged(true); // isChanged + return; + } + + ArcPath_WasChanged(path); +} + + +// in ExtractDialog.cpp +extern void AddUniqueString(UStringVector &strings, const UString &srcString); + +static bool IsAsciiString(const UString &s) +{ + for (unsigned i = 0; i < s.Len(); i++) + { + const wchar_t c = s[i]; + if (c < 0x20 || c > 0x7F) + return false; + } + return true; +} + + +static void AddSize_MB(UString &s, UInt64 size) +{ + s.Add_LF(); + const UInt64 v2 = size + ((UInt32)1 << 20) - 1; + if (size < v2) + size = v2; + s.Add_UInt64(size >> 20); + s += " MB : "; +} + +static void AddSize_MB_id(UString &s, UInt64 size, UInt32 id) +{ + AddSize_MB(s, size); + AddLangString(s, id); +} + +void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString); +void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString) +{ + AddLangString(s, IDS_MEM_OPERATION_BLOCKED); + s.Add_LF(); + AddLangString(s, IDS_MEM_REQUIRES_BIG_MEM); + s.Add_LF(); + AddSize_MB(s, reqSize); + s += usageString; + AddSize_MB_id(s, ramSize, IDS_MEM_RAM_SIZE); + // if (ramLimit != 0) + { + AddSize_MB_id(s, ramLimit, IDS_MEM_USAGE_LIMIT_SET_BY_7ZIP); + } + s.Add_LF(); + s.Add_LF(); + AddLangString(s, IDS_MEM_ERROR); +} + + +void CCompressDialog::OnOK() +{ + _password1Control.GetText(Info.Password); + if (IsZipFormat()) + { + if (!IsAsciiString(Info.Password)) + { + ShowErrorMessageHwndRes(*this, IDS_PASSWORD_USE_ASCII); + return; + } + UString method = GetEncryptionMethodSpec(); + if (method.IsPrefixedBy_Ascii_NoCase("aes")) + { + if (Info.Password.Len() > 99) + { + ShowErrorMessageHwndRes(*this, IDS_PASSWORD_TOO_LONG); + return; + } + } + } + if (!IsShowPasswordChecked()) + { + UString password2; + _password2Control.GetText(password2); + if (password2 != Info.Password) + { + ShowErrorMessageHwndRes(*this, IDS_PASSWORD_NOT_MATCH); + return; + } + } + + { + UInt64 decompressMem; + const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); + if (memUsage != (UInt64)(Int64)-1) + { + const UInt64 limit = Get_MemUse_Bytes(); + if (memUsage > limit) + { + UString s2; + LangString_OnlyFromLangFile(IDS_MEM_REQUIRED_MEM_SIZE, s2); + if (s2.IsEmpty()) + { + s2 = LangString(IDT_COMPRESS_MEMORY); + if (s2.IsEmpty()) + GetItemText(IDT_COMPRESS_MEMORY, s2); + s2.RemoveChar(L':'); + } + UString s; + SetErrorMessage_MemUsage(s, memUsage, _ramSize, limit, s2); + MessageBoxError(s); + return; + } + } + } + + SaveOptionsInMem(); + + UStringVector arcPaths; + { + UString s; + if (!GetFinalPath_Smart(s)) + { + ShowErrorMessage(*this, k_IncorrectPathMessage); + return; + } + Info.ArcPath = s; + AddUniqueString(arcPaths, s); + } + + Info.UpdateMode = (NCompressDialog::NUpdateMode::EEnum)k_UpdateMode_Vals[m_UpdateMode.GetCurSel()]; + Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()]; + + Info.Level = GetLevelSpec(); + Info.Dict64 = GetDictSpec(); + // Info.Dict64_Chain = GetDictChainSpec(); + Info.Order = GetOrderSpec(); + Info.OrderMode = GetOrderMode(); + Info.NumThreads = GetNumThreadsSpec(); + + Info.MemUsage.Clear(); + { + const UString mus = Get_MemUse_Spec(); + if (!mus.IsEmpty()) + { + NCompression::CMemUse mu; + mu.Parse(mus); + if (mu.IsDefined) + Info.MemUsage = mu; + } + } + + { + // Info.SolidIsSpecified = g_Formats[GetStaticFormatIndex()].Solid; + const UInt32 solidLogSize = GetBlockSizeSpec(); + Info.SolidBlockSize = 0; + if (solidLogSize == (UInt32)(Int32)-1) + Info.SolidIsSpecified = false; + else if (solidLogSize > 0) + Info.SolidBlockSize = (solidLogSize >= 64) ? + (UInt64)(Int64)-1 : + ((UInt64)1 << solidLogSize); + } + + Info.Method = GetMethodSpec(); + Info.EncryptionMethod = GetEncryptionMethodSpec(); + Info.FormatIndex = (int)GetFormatIndex(); + Info.SFXMode = IsSFX(); + Info.OpenShareForWrite = IsButtonCheckedBool(IDX_COMPRESS_SHARED); + Info.DeleteAfterCompressing = IsButtonCheckedBool(IDX_COMPRESS_DEL); + + m_RegistryInfo.EncryptHeaders = + Info.EncryptHeaders = IsButtonCheckedBool(IDX_COMPRESS_ENCRYPT_FILE_NAMES); + + + /* (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) */ + + { + /* 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); + + UString volumeString; + m_Volume.GetText(volumeString); + volumeString.Trim(); + Info.VolumeSizes.Clear(); + + if (!volumeString.IsEmpty()) + { + if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) + { + ShowErrorMessageHwndRes(*this, IDS_INCORRECT_VOLUME_SIZE); + return; + } + if (!Info.VolumeSizes.IsEmpty()) + { + const UInt64 volumeSize = Info.VolumeSizes.Back(); + if (volumeSize < (100 << 10)) + { + wchar_t s[32]; + ConvertUInt64ToString(volumeSize, s); + if (::MessageBoxW(*this, MyFormatNew(IDS_SPLIT_CONFIRM, s), + L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES) + return; + } + } + } + + if (Info.FormatIndex >= 0) + m_RegistryInfo.ArcType = (*ArcFormats)[Info.FormatIndex].Name; + m_RegistryInfo.ShowPassword = IsShowPasswordChecked(); + + FOR_VECTOR (i, m_RegistryInfo.ArcPaths) + { + if (arcPaths.Size() >= kHistorySize) + break; + AddUniqueString(arcPaths, m_RegistryInfo.ArcPaths[i]); + } + m_RegistryInfo.ArcPaths = arcPaths; + + m_RegistryInfo.Save(); + + CModalDialog::OnOK(); +} + +#define kHelpTopic "fm/plugins/7-zip/add.htm" +#define kHelpTopic_Options "fm/plugins/7-zip/add.htm#options" + +void CCompressDialog::OnHelp() +{ + ShowHelpWindow(kHelpTopic); +} + + +void CCompressDialog::ArcPath_WasChanged(const UString &path) +{ + const int dotPos = GetExtDotPos(path); + if (dotPos < 0) + return; + const UString ext = path.Ptr(dotPos + 1); + { + const CArcInfoEx &ai = Get_ArcInfoEx(); + if (ai.FindExtension(ext) >= 0) + return; + } + + const unsigned count = (unsigned)m_Format.GetCount(); + for (unsigned i = 0; i < count; i++) + { + const CArcInfoEx &ai = (*ArcFormats)[(unsigned)m_Format.GetItemData(i)]; + if (ai.FindExtension(ext) >= 0) + { + m_Format.SetCurSel(i); + SaveOptionsInMem(); + FormatChanged(true); // isChanged + return; + } + } +} + + +bool CCompressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case k_Message_ArcChanged: + { + // UString path; + // m_ArchivePath.GetText(path); + const int select = m_ArchivePath.GetCurSel(); + if ((unsigned)select < m_RegistryInfo.ArcPaths.Size()) + // if (path == m_RegistryInfo.ArcPaths[select]) + { + const UString &path = m_RegistryInfo.ArcPaths[select]; + SetArcPathFields(path); + // ArcPath_WasChanged(path); + } + return 0; + } + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + + +bool CCompressDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch (itemID) + { + case IDC_COMPRESS_ARCHIVE: + { + /* CBN_SELCHANGE is called before actual value of combo text will be changed. + So GetText() here returns old value (before change) of combo text. + So here we can change all controls except of m_ArchivePath. + */ + const int select = m_ArchivePath.GetCurSel(); + if ((unsigned)select < m_RegistryInfo.ArcPaths.Size()) + { + // DirPrefix.Empty(); + // SetItemText(IDT_COMPRESS_ARCHIVE_FOLDER, DirPrefix); + const UString &path = m_RegistryInfo.ArcPaths[select]; + // SetArcPathFields(path); + ArcPath_WasChanged(path); + // we use PostMessage(k_Message_ArcChanged) here that later will change m_ArchivePath control + PostMsg(k_Message_ArcChanged); + } + return true; + } + + case IDC_COMPRESS_FORMAT: + { + const bool isSFX = IsSFX(); + SaveOptionsInMem(); + FormatChanged(true); // isChanged + SetArchiveName2(isSFX); + return true; + } + + case IDC_COMPRESS_LEVEL: + { + Get_FormatOptions().ResetForLevelChange(); + + SetMethod(); // call it if level changes method + + // call the following if level change keeps old method + /* + { + // try to keep old method + SetMethod(GetMethodID()); + MethodChanged(); + } + */ + + SetSolidBlockSize(); + SetNumThreads(); + CheckSFXNameChange(); + SetMemoryUsage(); + return true; + } + + case IDC_COMPRESS_METHOD: + { + MethodChanged(); + SetSolidBlockSize(); + SetNumThreads(); + CheckSFXNameChange(); + SetMemoryUsage(); + if (Get_ArcInfoEx().Flags_HashHandler()) + SetArchiveName2(false); + + return true; + } + + case IDC_COMPRESS_DICTIONARY: + // case IDC_COMPRESS_DICTIONARY2: + { + /* we want to change the reported threads for Auto line + and keep selected NumThreads option + So we save selected NumThreads option in memory */ + SaveOptionsInMem(); + const UInt32 blockSizeLog = GetBlockSizeSpec(); + if (// blockSizeLog != (UInt32)(Int32)-1 && + blockSizeLog != kSolidLog_NoSolid + && blockSizeLog != kSolidLog_FullSolid) + { + Get_FormatOptions().Reset_BlockLogSize(); + // SetSolidBlockSize(true); + } + + SetDictionary2(); + SetSolidBlockSize(); + SetNumThreads(); // we want to change the reported threads for Auto line only + SetMemoryUsage(); + return true; + } + + case IDC_COMPRESS_ORDER: + { + #ifdef PRINT_PARAMS + Print_Params(); + #endif + return true; + } + + case IDC_COMPRESS_SOLID: + { + SetMemoryUsage(); + return true; + } + + case IDC_COMPRESS_THREADS: + { + SetMemoryUsage(); + return true; + } + + case IDC_COMPRESS_MEM_USE: + { + /* we want to change the reported threads for Auto line + and keep selected NumThreads option + So we save selected NumThreads option in memory */ + SaveOptionsInMem(); + + SetNumThreads(); // we want to change the reported threads for Auto line only + SetMemoryUsage(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + +void CCompressDialog::CheckSFXNameChange() +{ + const bool isSFX = IsSFX(); + CheckSFXControlsEnable(); + if (isSFX != IsSFX()) + SetArchiveName2(isSFX); +} + +void CCompressDialog::SetArchiveName2(bool prevWasSFX) +{ + UString fileName; + m_ArchivePath.GetText(fileName); + const CArcInfoEx &prevArchiverInfo = (*ArcFormats)[m_PrevFormat]; + if (prevArchiverInfo.Flags_KeepName() || Info.KeepName) + { + UString prevExtension; + if (prevWasSFX) + prevExtension = kExeExt; + else + { + prevExtension.Add_Dot(); + prevExtension += prevArchiverInfo.GetMainExt(); + } + const unsigned prevExtensionLen = prevExtension.Len(); + if (fileName.Len() >= prevExtensionLen) + if (StringsAreEqualNoCase(fileName.RightPtr(prevExtensionLen), prevExtension)) + fileName.DeleteFrom(fileName.Len() - prevExtensionLen); + } + SetArchiveName(fileName); +} + +// if type.KeepName then use OriginalFileName +// else if !KeepName remove extension +// add new extension + +void CCompressDialog::SetArchiveName(const UString &name) +{ + UString fileName = name; + Info.FormatIndex = (int)GetFormatIndex(); + const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex]; + m_PrevFormat = Info.FormatIndex; + if (ai.Flags_KeepName()) + { + fileName = OriginalFileName; + } + else + { + if (!Info.KeepName) + { + int dotPos = GetExtDotPos(fileName); + if (dotPos >= 0) + fileName.DeleteFrom(dotPos); + } + } + + if (IsSFX()) + fileName += kExeExt; + else + { + fileName.Add_Dot(); + UString ext = ai.GetMainExt(); + if (ai.Flags_HashHandler()) + { + UString estimatedName; + GetMethodSpec(estimatedName); + if (!estimatedName.IsEmpty()) + { + ext = estimatedName; + ext.MakeLower_Ascii(); + } + } + fileName += ext; + } + m_ArchivePath.SetText(fileName); +} + + +int CCompressDialog::FindRegistryFormat(const UString &name) +{ + FOR_VECTOR (i, m_RegistryInfo.Formats) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[i]; + if (name.IsEqualTo_NoCase(GetUnicodeString(fo.FormatID))) + return (int)i; + } + return -1; +} + + +unsigned CCompressDialog::FindRegistryFormat_Always(const UString &name) +{ + const int index = FindRegistryFormat(name); + if (index >= 0) + return (unsigned)index; + { + NCompression::CFormatOptions fo; + fo.FormatID = GetSystemString(name); + return m_RegistryInfo.Formats.Add(fo); + } +} + + +NCompression::CFormatOptions &CCompressDialog::Get_FormatOptions() +{ + const CArcInfoEx &ai = Get_ArcInfoEx(); + return m_RegistryInfo.Formats[FindRegistryFormat_Always(ai.Name)]; +} + + +unsigned CCompressDialog::GetStaticFormatIndex() +{ + const CArcInfoEx &ai = Get_ArcInfoEx(); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_Formats); i++) + if (ai.Name.IsEqualTo_Ascii_NoCase(g_Formats[i].Name)) + return i; + return 0; // -1; +} + +void CCompressDialog::SetNearestSelectComboBox(NControl::CComboBox &comboBox, UInt32 value) +{ + for (int i = comboBox.GetCount() - 1; i >= 0; i--) + if ((UInt32)comboBox.GetItemData(i) <= value) + { + comboBox.SetCurSel(i); + return; + } + if (comboBox.GetCount() > 0) + comboBox.SetCurSel(0); +} + +void CCompressDialog::SetLevel2() +{ + m_Level.ResetContent(); + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArcInfoEx &ai = Get_ArcInfoEx(); + UInt32 level = 5; + { + int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + if (fo.Level <= 9) + level = fo.Level; + else if (fo.Level == (UInt32)(Int32)-1) + level = 5; + else + level = 9; + } + } + + const bool isZstd = ai.Is_Zstd(); + + for (unsigned i = 0; i < sizeof(UInt32) * 8; i++) + { + const UInt32 mask = fi.LevelsMask >> i; + // if (mask == 0) break; + if (mask & 1) + { + UString s; + s.Add_UInt32(i); + if (i < Z7_ARRAY_SIZE(g_Levels)) + { + const UInt32 langID = g_Levels[i]; + // if (fi.LevelsMask < (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1) + if (langID) + if (i != 0 || !isZstd) + { + s += " - "; + AddLangString(s, langID); + } + } + const int index = (int)m_Level.AddString(s); + m_Level.SetItemData(index, (LPARAM)i); + } + } + SetNearestSelectComboBox(m_Level, level); +} + + +static LRESULT ComboBox_AddStringAscii(NControl::CComboBox &cb, const char *s) +{ + return cb.AddString((CSysString)s); +} + +static const char *k_Auto_Prefix = "* "; + +static void Modify_Auto(AString &s) +{ + s.Insert(0, k_Auto_Prefix); +} + +void CCompressDialog::SetMethod2(int keepMethodId) +{ + m_Method.ResetContent(); + _auto_MethodId = -1; + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArcInfoEx &ai = Get_ArcInfoEx(); + if (GetLevel() == 0 && !ai.Flags_HashHandler()) + { + if (!ai.Is_Tar() && + !ai.Is_Zstd()) + { + MethodChanged(); + return; + } + } + UString defaultMethod; + { + const int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + defaultMethod = fo.Method; + } + } + const bool isSfx = IsSFX(); + bool weUseSameMethod = false; + + const bool is7z = ai.Is_7z(); + + for (unsigned m = 0;; m++) + { + int methodID; + const char *method; + if (m < fi.NumMethods) + { + methodID = fi.MethodIDs[m]; + method = kMethodsNames[methodID]; + if (is7z) + if (methodID == kCopy + || methodID == kDeflate + || methodID == kDeflate64 + ) + continue; + } + else + { + if (!is7z) + break; + const unsigned extIndex = m - fi.NumMethods; + if (extIndex >= ExternalMethods.Size()) + break; + methodID = (int)(Z7_ARRAY_SIZE(kMethodsNames) + extIndex); + method = ExternalMethods[extIndex].Ptr(); + } + if (isSfx) + if (!IsMethodSupportedBySfx(methodID)) + continue; + + AString s (method); + int writtenMethodId = methodID; + if (m == 0) + { + _auto_MethodId = methodID; + writtenMethodId = -1; + Modify_Auto(s); + } + const int itemIndex = (int)ComboBox_AddStringAscii(m_Method, s); + m_Method.SetItemData(itemIndex, writtenMethodId); + if (keepMethodId == methodID) + { + m_Method.SetCurSel(itemIndex); + weUseSameMethod = true; + continue; + } + if ((defaultMethod.IsEqualTo_Ascii_NoCase(method) || m == 0) && !weUseSameMethod) + m_Method.SetCurSel(itemIndex); + } + + if (!weUseSameMethod) + MethodChanged(); +} + + + +bool CCompressDialog::IsZipFormat() +{ + return Get_ArcInfoEx().Is_Zip(); +} + +bool CCompressDialog::IsXzFormat() +{ + return Get_ArcInfoEx().Is_Xz(); +} + +void CCompressDialog::SetEncryptionMethod() +{ + _encryptionMethod.ResetContent(); + _default_encryptionMethod_Index = -1; + const CArcInfoEx &ai = Get_ArcInfoEx(); + if (ai.Is_7z()) + { + ComboBox_AddStringAscii(_encryptionMethod, "AES-256"); + _encryptionMethod.SetCurSel(0); + _default_encryptionMethod_Index = 0; + } + else if (ai.Is_Zip()) + { + int index = FindRegistryFormat(ai.Name); + UString encryptionMethod; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + encryptionMethod = fo.EncryptionMethod; + } + int sel = 0; + // if (ZipCryptoIsAllowed) + { + ComboBox_AddStringAscii(_encryptionMethod, "ZipCrypto"); + sel = (encryptionMethod.IsPrefixedBy_Ascii_NoCase("aes") ? 1 : 0); + _default_encryptionMethod_Index = 0; + } + ComboBox_AddStringAscii(_encryptionMethod, "AES-256"); + _encryptionMethod.SetCurSel(sel); + } +} + + +int CCompressDialog::GetMethodID_RAW() +{ + if (m_Method.GetCount() <= 0) + return -1; + return (int)(Int32)(UInt32)m_Method.GetItemData_of_CurSel(); +} + +int CCompressDialog::GetMethodID() +{ + int raw = GetMethodID_RAW(); + if (raw < 0) + return _auto_MethodId; + return raw; +} + + +UString CCompressDialog::GetMethodSpec(UString &estimatedName) +{ + estimatedName.Empty(); + if (m_Method.GetCount() < 1) + return estimatedName; + const int methodIdRaw = GetMethodID_RAW(); + int methodId = methodIdRaw; + if (methodIdRaw < 0) + methodId = _auto_MethodId; + UString s; + if (methodId >= 0) + { + if ((unsigned)methodId < Z7_ARRAY_SIZE(kMethodsNames)) + estimatedName = kMethodsNames[methodId]; + else + estimatedName = ExternalMethods[(unsigned)methodId - (unsigned)Z7_ARRAY_SIZE(kMethodsNames)]; + if (methodIdRaw >= 0) + s = estimatedName; + } + return s; +} + + +UString CCompressDialog::GetMethodSpec() +{ + UString estimatedName; + UString s = GetMethodSpec(estimatedName); + return s; +} + +bool CCompressDialog::IsMethodEqualTo(const UString &s) +{ + UString estimatedName; + const UString shortName = GetMethodSpec(estimatedName); + if (s.IsEmpty()) + return shortName.IsEmpty(); + return s.IsEqualTo_NoCase(estimatedName); +} + + +UString CCompressDialog::GetEncryptionMethodSpec() +{ + UString s; + if (_encryptionMethod.GetCount() > 0 + && _encryptionMethod.GetCurSel() != _default_encryptionMethod_Index) + { + _encryptionMethod.GetText(s); + s.RemoveChar(L'-'); + } + return s; +} + + +static const size_t k_Auto_Dict = (size_t)0 - 1; + +static int Combo_AddDict2(NWindows::NControl::CComboBox &cb, size_t sizeReal, size_t sizeShow) +{ + char c = 0; + unsigned moveBits = 0; + if ((sizeShow & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } + else if ((sizeShow & 0x3FF) == 0) { moveBits = 10; c = 'K'; } + AString s; + s.Add_UInt64(sizeShow >> moveBits); + s.Add_Space(); + if (c != 0) + s.Add_Char(c); + s.Add_Char('B'); + if (sizeReal == k_Auto_Dict) + Modify_Auto(s); + const int index = (int)ComboBox_AddStringAscii(cb, s); + cb.SetItemData(index, (LPARAM)sizeReal); + return index; +} + +int CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow) +{ + return Combo_AddDict2(m_Dictionary, sizeReal, sizeShow); +} + +int CCompressDialog::AddDict(size_t size) +{ + return AddDict2(size, size); +} + +/* +int CCompressDialog::AddDict_Chain(size_t size) +{ + return Combo_AddDict2(m_Dictionary_Chain, size, size); +} +*/ + +void CCompressDialog::SetDictionary2() +{ + m_Dictionary.ResetContent(); + // m_Dictionary_Chain.ResetContent(); + + // _auto_Dict = (UInt32)1 << 24; // we can use this dictSize to calculate _auto_Solid for unknown method for 7z + _auto_Dict = (UInt32)(Int32)-1; // for debug + // _auto_Dict_Chain = (UInt32)(Int32)-1; // for debug + + const CArcInfoEx &ai = Get_ArcInfoEx(); + UInt32 defaultDict = (UInt32)(Int32)-1; + // UInt32 defaultDict_Chain = (UInt32)(Int32)-1; + { + const int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + if (IsMethodEqualTo(fo.Method)) + { + defaultDict = fo.Dictionary; + // defaultDict_Chain = fo.DictionaryChain; + } + } + } + + const int methodID = GetMethodID(); + const UInt32 level = GetLevel2(); + + { + RECT r, rLabel; + GetClientRectOfItem(IDT_COMPRESS_DICTIONARY, rLabel); + GetClientRectOfItem(IDC_COMPRESS_DICTIONARY, r); + if (_dictionaryCombo_left == 0) + _dictionaryCombo_left = r.left; + + // bool showDict2; + int newLableRight; + int newDictLeft; + + /* + if (methodID == kZSTD) + { + showDict2 = true; + newDictLeft = _dictionaryCombo_left; + RECT r2; + GetClientRectOfItem(IDC_COMPRESS_DICTIONARY2, r2); + newLableRight = r2.left; + } + else + */ + { + // showDict2 = false; + RECT rBig; + GetClientRectOfItem(IDC_COMPRESS_METHOD, rBig); + newDictLeft= rBig.left; + newLableRight = newDictLeft; + } + + if (newLableRight != rLabel.right) + { + rLabel.right = newLableRight; + MoveItem_RECT(IDT_COMPRESS_DICTIONARY, rLabel); + InvalidateRect(&rLabel); + } + if (newDictLeft != r.left) + { + r.left = newDictLeft; + MoveItem_RECT(IDC_COMPRESS_DICTIONARY, r); + // InvalidateRect(&r); + } + // ShowItem_Bool(IDC_COMPRESS_DICTIONARY2, showDict2); + } + + if (methodID < 0) + return; + + switch (methodID) + { + case kLZMA: + case kLZMA2: + { + { + _auto_Dict = level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); + } + + // we use threshold 3.75 GiB to switch to kLzmaMaxDictSize. + if (defaultDict != (UInt32)(Int32)-1 + && defaultDict >= ((UInt32)15 << 28)) + defaultDict = kLzmaMaxDictSize; + + const size_t kLzmaMaxDictSize_Up = (size_t)1 << (20 + sizeof(size_t) / 4 * 6); + + int curSel = AddDict2(k_Auto_Dict, _auto_Dict); + + for (unsigned i = (16 - 1) * 2; i <= (32 - 1) * 2; i++) + { + if (i < (20 - 1) * 2 + && i != (16 - 1) * 2 + && i != (18 - 1) * 2) + continue; + if (i == (20 - 1) * 2 + 1) + continue; + const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); + size_t dict = dict_up; + if (dict_up >= kLzmaMaxDictSize) + dict = kLzmaMaxDictSize; // we reduce dictionary + + const int index = AddDict(dict); + // AddDict2(dict, dict_up); // for debug : we show 4 GB + + // const UInt32 numThreads = 2; + // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(numThreads, dict); + if (defaultDict != (UInt32)(Int32)-1) + if (dict <= defaultDict || curSel <= 0) + // if (!maxRamSize_Defined || memUsage <= maxRamSize) + curSel = index; + if (dict_up >= kLzmaMaxDictSize_Up) + break; + } + + m_Dictionary.SetCurSel(curSel); + break; + } + + /* + case kZSTD: + { + if (defaultDict != (UInt32)(Int32)-1 && + defaultDict > kZstd_MAX_DictSize) + defaultDict = kZstd_MAX_DictSize; + + if (defaultDict_Chain != (UInt32)(Int32)-1 && + defaultDict_Chain > kZstd_MAX_DictSize_Chain) + defaultDict_Chain = kZstd_MAX_DictSize_Chain; + + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = level; + ZstdEncProps_Set_WindowSize(&props, defaultDict != (UInt32)(Int32)-1 ? defaultDict: 0); + ZstdEncProps_NormalizeFull(&props); + _auto_Dict_Chain = (UInt32)1 << props.windowLog_Chain; + } + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = level; + ZstdEncProps_Set_WindowChainSize(&props, defaultDict_Chain != (UInt32)(Int32)-1 ? defaultDict_Chain: 0); + ZstdEncProps_NormalizeFull(&props); + _auto_Dict = (UInt32)1 << props.windowLog; + } + + // if there is collision of two window sizes, we reduce dict_Chain + if (defaultDict != (UInt32)(Int32)-1 && + defaultDict_Chain != (UInt32)(Int32)-1 && + defaultDict < defaultDict_Chain) + defaultDict_Chain = defaultDict; + + { + int curSel = AddDict2(k_Auto_Dict, _auto_Dict); + + // defaultDict = 12 << 10; // for debug + const UInt32 kWinStart = 18; + if (defaultDict != 0 && defaultDict < ((UInt32)1 << kWinStart)) + curSel = AddDict(defaultDict); + + for (unsigned i = kWinStart; i <= MY_ZSTD_WINDOWLOG_MAX; i++) + { + const size_t dict = (size_t)1 << i; + const int index = AddDict(dict); + if (defaultDict != (UInt32)(Int32)-1) + if (dict <= defaultDict || curSel <= 0) + curSel = index; + } + m_Dictionary.SetCurSel(curSel); + } + + { + int curSel = Combo_AddDict2(m_Dictionary_Chain, k_Auto_Dict, _auto_Dict_Chain); + + // defaultDict_Chain = 10 << 10; // for debug + const UInt32 kWinChainStart = 15; + if (defaultDict_Chain != 0 && defaultDict_Chain < ((UInt32)1 << kWinChainStart)) + curSel = AddDict_Chain(defaultDict_Chain); + + for (unsigned i = kWinChainStart; i <= kMaxDictChain; i++) + { + const size_t dict = (size_t)1 << i; + if (defaultDict != (UInt32)(Int32)-1 && dict > defaultDict) + break; + const int index = AddDict_Chain(dict); + if (defaultDict_Chain != (UInt32)(Int32)-1) + if (dict <= defaultDict_Chain || curSel <= 0) + curSel = index; + } + m_Dictionary_Chain.SetCurSel(curSel); + } + + break; + } + */ + + case kPPMd: + { + _auto_Dict = (UInt32)1 << (level + 19); + + const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10); + const size_t kPpmd_MaxDictSize_Up = (size_t)1 << (29 + sizeof(size_t) / 8); + + if (defaultDict != (UInt32)(Int32)-1 + && defaultDict >= ((UInt32)15 << 28)) // threshold + defaultDict = kPpmd_Default_4g; + + int curSel = AddDict2(k_Auto_Dict, _auto_Dict); + + for (unsigned i = (20 - 1) * 2; i <= (32 - 1) * 2; i++) + { + if (i == (20 - 1) * 2 + 1) + continue; + + const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2); + size_t dict = dict_up; + if (dict_up >= kPpmd_Default_4g) + dict = kPpmd_Default_4g; + + const int index = AddDict2(dict, dict_up); + // AddDict2((UInt32)((UInt32)0 - 2), dict_up); // for debug + // AddDict(dict_up); // for debug + // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(1, dict); + if (defaultDict != (UInt32)(Int32)-1) + if (dict <= defaultDict || curSel <= 0) + // if (!maxRamSize_Defined || memUsage <= maxRamSize) + curSel = index; + if (dict_up >= kPpmd_MaxDictSize_Up) + break; + } + m_Dictionary.SetCurSel(curSel); + break; + } + + case kPPMdZip: + { + _auto_Dict = (UInt32)1 << (level + 19); + + int curSel = AddDict2(k_Auto_Dict, _auto_Dict); + + for (unsigned i = 20; i <= 28; i++) + { + const UInt32 dict = (UInt32)1 << i; + const int index = AddDict(dict); + // const UInt64 memUsage = GetMemoryUsageComp_Threads_Dict(1, dict); + if (defaultDict != (UInt32)(Int32)-1) + if (dict <= defaultDict || curSel <= 0) + // if (!maxRamSize_Defined || memUsage <= maxRamSize) + curSel = index; + } + m_Dictionary.SetCurSel(curSel); + break; + } + + case kDeflate: + case kDeflate64: + { + const UInt32 dict = (methodID == kDeflate ? (UInt32)(1 << 15) : (UInt32)(1 << 16)); + _auto_Dict = dict; + AddDict2(k_Auto_Dict, _auto_Dict); + m_Dictionary.SetCurSel(0); + // EnableItem(IDC_COMPRESS_DICTIONARY, false); + break; + } + + case kBZip2: + { + { + if (level >= 5) _auto_Dict = (900 << 10); + else if (level >= 3) _auto_Dict = (500 << 10); + else _auto_Dict = (100 << 10); + } + + int curSel = AddDict2(k_Auto_Dict, _auto_Dict); + + for (unsigned i = 1; i <= 9; i++) + { + const UInt32 dict = ((UInt32)i * 100) << 10; + AddDict(dict); + // AddDict2(i * 100000, dict); + if (defaultDict != (UInt32)(Int32)-1) + if (i <= defaultDict / 100000 || curSel <= 0) + curSel = m_Dictionary.GetCount() - 1; + } + m_Dictionary.SetCurSel(curSel); + break; + } + + case kCopy: + { + _auto_Dict = 0; + AddDict(0); + m_Dictionary.SetCurSel(0); + break; + } + } +} + + +UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax) +{ + if (c.GetCount() <= defMax) + return (UInt32)(Int32)-1; + return (UInt32)c.GetItemData_of_CurSel(); +} + + +UInt64 CCompressDialog::GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax) +{ + if (c.GetCount() <= defMax) + return (UInt64)(Int64)-1; + // LRESULT is signed. so we cast it to unsigned size_t at first: + LRESULT val = c.GetItemData_of_CurSel(); + if (val == (LPARAM)(INT_PTR)(-1)) + return (UInt64)(Int64)-1; + return (UInt64)(size_t)c.GetItemData_of_CurSel(); +} + +UInt32 CCompressDialog::GetLevel2() +{ + UInt32 level = GetLevel(); + if (level == (UInt32)(Int32)-1) + level = 5; + return level; +} + + +int CCompressDialog::AddOrder(UInt32 size) +{ + char s[32]; + ConvertUInt32ToString(size, s); + const int index = (int)ComboBox_AddStringAscii(m_Order, s); + m_Order.SetItemData(index, (LPARAM)size); + return index; +} + +int CCompressDialog::AddOrder_Auto() +{ + AString s; + s.Add_UInt32(_auto_Order); + Modify_Auto(s); + int index = (int)ComboBox_AddStringAscii(m_Order, s); + m_Order.SetItemData(index, (LPARAM)(INT_PTR)(-1)); + return index; +} + +void CCompressDialog::SetOrder2() +{ + m_Order.ResetContent(); + + _auto_Order = 1; + + const CArcInfoEx &ai = Get_ArcInfoEx(); + UInt32 defaultOrder = (UInt32)(Int32)-1; + + { + const int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + if (IsMethodEqualTo(fo.Method)) + defaultOrder = fo.Order; + } + } + + const int methodID = GetMethodID(); + const UInt32 level = GetLevel2(); + if (methodID < 0) + return; + + switch (methodID) + { + case kLZMA: + case kLZMA2: + { + _auto_Order = (level < 7 ? 32 : 64); + int curSel = AddOrder_Auto(); + for (unsigned i = 2 * 2; i < 8 * 2; i++) + { + UInt32 order = ((UInt32)(2 + (i & 1)) << (i / 2)); + if (order > 256) + order = 273; + const int index = AddOrder(order); + if (defaultOrder != (UInt32)(Int32)-1) + if (order <= defaultOrder || curSel <= 0) + curSel = index; + } + m_Order.SetCurSel(curSel); + break; + } + + /* + case kZSTD: + { + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = level; + ZstdEncProps_NormalizeFull(&props); + _auto_Order = props.targetLength; + if (props.strategy < ZSTD_strategy_btopt) + { + // ZSTD_strategy_fast uses targetLength to change fast level. + // targetLength probably is used only in ZSTD_strategy_btopt and higher + break; + } + } + int curSel = AddOrder_Auto(); + + for (unsigned i = 6; i <= 9 * 2; i++) + { + UInt32 order = ((UInt32)(2 + (i & 1)) << (i / 2)); + // if (order > 999) order = 999; + const int index = AddOrder(order); + if (defaultOrder != (UInt32)(Int32)-1) + if (order <= defaultOrder || curSel <= 0) + curSel = index; + } + m_Order.SetCurSel(curSel); + break; + } + */ + + case kDeflate: + case kDeflate64: + { + { + if (level >= 9) _auto_Order = 128; + else if (level >= 7) _auto_Order = 64; + else _auto_Order = 32; + } + int curSel = AddOrder_Auto(); + for (unsigned i = 2 * 2; i < 8 * 2; i++) + { + UInt32 order = ((UInt32)(2 + (i & 1)) << (i / 2)); + if (order > 256) + order = (methodID == kDeflate64 ? 257 : 258); + const int index = AddOrder(order); + if (defaultOrder != (UInt32)(Int32)-1) + if (order <= defaultOrder || curSel <= 0) + curSel = index; + } + + m_Order.SetCurSel(curSel); + break; + } + + case kPPMd: + { + { + if (level >= 9) _auto_Order = 32; + else if (level >= 7) _auto_Order = 16; + else if (level >= 5) _auto_Order = 6; + else _auto_Order = 4; + } + + int curSel = AddOrder_Auto(); + + for (unsigned i = 0;; i++) + { + UInt32 order = i + 2; + if (i >= 2) + order = (4 + ((i - 2) & 3)) << ((i - 2) / 4); + const int index = AddOrder(order); + if (defaultOrder != (UInt32)(Int32)-1) + if (order <= defaultOrder || curSel <= 0) + curSel = index; + if (order >= 32) + break; + } + m_Order.SetCurSel(curSel); + break; + } + + case kPPMdZip: + { + _auto_Order = level + 3; + int curSel = AddOrder_Auto(); + for (unsigned i = 2; i <= 16; i++) + { + const int index = AddOrder(i); + if (defaultOrder != (UInt32)(Int32)-1) + if (i <= defaultOrder || curSel <= 0) + curSel = index; + } + m_Order.SetCurSel(curSel); + break; + } + + // case kBZip2: + default: + break; + } +} + +bool CCompressDialog::GetOrderMode() +{ + switch (GetMethodID()) + { + case kPPMd: + case kPPMdZip: + return true; + } + return false; +} + + +static UInt64 Get_Lzma2_ChunkSize(UInt64 dict) +{ + // we use same default chunk sizes as defined in 7z encoder and lzma2 encoder + UInt64 cs = (UInt64)dict << 2; + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + if (cs < kMinSize) cs = kMinSize; + if (cs > kMaxSize) cs = kMaxSize; + if (cs < dict) cs = dict; + cs += (kMinSize - 1); + cs &= ~(UInt64)(kMinSize - 1); + return cs; +} + + +static void Add_Size(AString &s, UInt64 val) +{ + unsigned moveBits = 0; + char c = 0; + if ((val & 0x3FFFFFFF) == 0) { moveBits = 30; c = 'G'; } + else if ((val & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; } + else if ((val & 0x3FF) == 0) { moveBits = 10; c = 'K'; } + s.Add_UInt64(val >> moveBits); + s.Add_Space(); + if (moveBits != 0) + s.Add_Char(c); + s.Add_Char('B'); +} + + +void CCompressDialog::SetSolidBlockSize2() +{ + m_Solid.ResetContent(); + _auto_Solid = 1 << 20; + + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + if (!fi.Solid_()) + return; + + const UInt32 level = GetLevel2(); + if (level == 0) + return; + + UInt64 dict = GetDict2(); + if (dict == (UInt64)(Int64)-1) + { + dict = 1 << 25; // default dict for unknown methods + // return; + } + + + UInt32 defaultBlockSize = (UInt32)(Int32)-1; + + const CArcInfoEx &ai = Get_ArcInfoEx(); + + /* + if (usePrevDictionary) + defaultBlockSize = GetBlockSizeSpec(); + else + */ + { + const int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + if (IsMethodEqualTo(fo.Method)) + defaultBlockSize = fo.BlockLogSize; + } + } + + const bool is7z = ai.Is_7z(); + + const UInt64 cs = Get_Lzma2_ChunkSize(dict); + + // Solid Block Size + UInt64 blockSize = cs; // for xz + + if (is7z) + { + // we use same default block sizes as defined in 7z encoder + UInt64 kMaxSize = (UInt64)1 << 32; + const int methodId = GetMethodID(); + if (methodId == kLZMA2) + { + blockSize = cs << 6; + kMaxSize = (UInt64)1 << 34; + } + else + { + UInt64 dict2 = dict; + if (methodId == kBZip2) + { + dict2 /= 100000; + if (dict2 < 1) + dict2 = 1; + dict2 *= 100000; + } + blockSize = dict2 << 7; + } + + const UInt32 kMinSize = (UInt32)1 << 24; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + } + + _auto_Solid = blockSize; + + int curSel; + { + AString s; + Add_Size(s, _auto_Solid); + Modify_Auto(s); + const int index = (int)ComboBox_AddStringAscii(m_Solid, s); + m_Solid.SetItemData(index, (LPARAM)(UInt32)(Int32)-1); + curSel = index; + } + + if (is7z) + { + UString s ('-'); + // kSolidLog_NoSolid = 0 for xz means default blockSize + if (is7z) + LangString(IDS_COMPRESS_NON_SOLID, s); + const int index = (int)m_Solid.AddString(s); + m_Solid.SetItemData(index, (LPARAM)(UInt32)kSolidLog_NoSolid); + if (defaultBlockSize == kSolidLog_NoSolid) + curSel = index; + } + + for (unsigned i = 20; i <= 36; i++) + { + AString s; + Add_Size(s, (UInt64)1 << i); + const int index = (int)ComboBox_AddStringAscii(m_Solid, s); + m_Solid.SetItemData(index, (LPARAM)(UInt32)i); + if (defaultBlockSize != (UInt32)(Int32)-1) + if (i <= defaultBlockSize || index <= 1) + curSel = index; + } + + { + const int index = (int)m_Solid.AddString(LangString(IDS_COMPRESS_SOLID)); + m_Solid.SetItemData(index, (LPARAM)kSolidLog_FullSolid); + if (defaultBlockSize == kSolidLog_FullSolid) + curSel = index; + } + + m_Solid.SetCurSel(curSel); +} + + +/* +static void ZstdEncProps_SetDictProps_From_CompressDialog(CZstdEncProps *props, CCompressDialog &cd) +{ + { + const UInt64 d64 = cd.GetDictSpec(); + UInt32 d32 = 0; // 0 is default for ZstdEncProps::windowLog + if (d64 != (UInt64)(Int64)-1) + { + d32 = (UInt32)d64; + if (d32 != d64) + d32 = (UInt32)(Int32)-2; + } + ZstdEncProps_Set_WindowSize(props, d32); + } + { + const UInt64 d64 = cd.GetDictChainSpec(); + UInt32 d32 = 0; // 0 is default for ZstdEncProps::windowLog_Chain + if (d64 != (UInt64)(Int64)-1) + { + d32 = (UInt32)d64; + if (d32 != d64) + d32 = (UInt32)(Int32)-2; + } + ZstdEncProps_Set_WindowChainSize(props, d32); + } +} + +static bool Is_Zstd_Mt_Supported() +{ + if (!GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "InitializeConditionVariable")) + return false; + return true; +} +*/ + +static const char *k_ST_Threads = " (ST)"; + +void CCompressDialog::SetNumThreads2() +{ + _auto_NumThreads = 1; + + m_NumThreads.ResetContent(); + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + if (!fi.MultiThread_()) + return; + + const UInt32 numHardwareThreads = NSystem::GetNumberOfProcessors(); + // 64; // for debug: + + UInt32 defaultValue = numHardwareThreads; + bool useAutoThreads = true; + + { + const CArcInfoEx &ai = Get_ArcInfoEx(); + int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + if (IsMethodEqualTo(fo.Method) && fo.NumThreads != (UInt32)(Int32)-1) + { + defaultValue = fo.NumThreads; + useAutoThreads = false; + } + } + } + + // const UInt32 num_ZSTD_threads_MAX = Is_Zstd_Mt_Supported() ? MY_ZSTDMT_NBWORKERS_MAX : 0; + + UInt32 numAlgoThreadsMax = numHardwareThreads * 2; + const int methodID = GetMethodID(); + + const bool isZip = IsZipFormat(); + if (isZip) + numAlgoThreadsMax = + 8 << (sizeof(size_t) / 2); // 32 threads for 32-bit : 128 threads for 64-bit + else if (IsXzFormat()) + numAlgoThreadsMax = 256 * 2; + else switch (methodID) + { + case kLZMA: numAlgoThreadsMax = 2; break; + case kLZMA2: numAlgoThreadsMax = 256; break; + case kBZip2: numAlgoThreadsMax = 64; break; + // case kZSTD: numAlgoThreadsMax = num_ZSTD_threads_MAX; break; + case kCopy: + case kPPMd: + case kDeflate: + case kDeflate64: + case kPPMdZip: + numAlgoThreadsMax = 1; + } + UInt32 autoThreads = numHardwareThreads; + if (autoThreads > numAlgoThreadsMax) + autoThreads = numAlgoThreadsMax; + + const UInt64 memUse_Limit = Get_MemUse_Bytes(); + + if (_ramSize_Defined) + if (autoThreads > 1 + // || (autoThreads == 0 && methodID == kZSTD) + ) + { + if (isZip) + { + for (; autoThreads > 1; autoThreads--) + { + const UInt64 dict64 = GetDict2(); + UInt64 decompressMemory; + const UInt64 usage = GetMemoryUsage_Threads_Dict_DecompMem(autoThreads, dict64, decompressMemory); + if (usage <= memUse_Limit) + break; + } + } + else if (methodID == kLZMA2) + { + const UInt64 dict64 = GetDict2(); + const UInt32 numThreads1 = (GetLevel2() >= 5 ? 2 : 1); + UInt32 numBlockThreads = autoThreads / numThreads1; + for (; numBlockThreads > 1; numBlockThreads--) + { + autoThreads = numBlockThreads * numThreads1; + UInt64 decompressMemory; + const UInt64 usage = GetMemoryUsage_Threads_Dict_DecompMem(autoThreads, dict64, decompressMemory); + if (usage <= memUse_Limit) + break; + } + autoThreads = numBlockThreads * numThreads1; + } + /* + else if (methodID == kZSTD) + { + if (num_ZSTD_threads_MAX != 0) + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = GetLevel2(); + ZstdEncProps_SetDictProps_From_CompressDialog(&props, *this); + autoThreads = ZstdEncProps_GetNumThreads_for_MemUsageLimit(&props, memUse_Limit, autoThreads); + } + } + */ + } + + _auto_NumThreads = autoThreads; + + int curSel = -1; + { + AString s; + s.Add_UInt32(autoThreads); + if (autoThreads == 0) s += k_ST_Threads; + Modify_Auto(s); + const int index = (int)ComboBox_AddStringAscii(m_NumThreads, s); + m_NumThreads.SetItemData(index, (LPARAM)(INT_PTR)(-1)); + // m_NumThreads.SetItemData(index, autoThreads); + if (useAutoThreads) + curSel = index; + } + + if (numAlgoThreadsMax != autoThreads || autoThreads != 1) + for (UInt32 i = + // (methodID == kZSTD) ? 0 : + 1; + i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++) + { + AString s; + s.Add_UInt32(i); + if (i == 0) s += k_ST_Threads; + const int index = (int)ComboBox_AddStringAscii(m_NumThreads, s); + m_NumThreads.SetItemData(index, (LPARAM)(UInt32)i); + if (!useAutoThreads && i == defaultValue) + curSel = index; + } + + m_NumThreads.SetCurSel(curSel); +} + + +static void AddMemSize(UString &res, UInt64 size) +{ + char c; + unsigned moveBits = 0; + if (size >= ((UInt64)1 << 31) && (size & 0x3FFFFFFF) == 0) + { moveBits = 30; c = 'G'; } + else // if (size >= ((UInt32)1 << 21) && (size & 0xFFFFF) == 0) + { moveBits = 20; c = 'M'; } + // else { moveBits = 10; c = 'K'; } + res.Add_UInt64(size >> moveBits); + res.Add_Space(); + if (moveBits != 0) + res.Add_Char(c); + res.Add_Char('B'); +} + + +int CCompressDialog::AddMemComboItem(UInt64 val, bool isPercent, bool isDefault) +{ + UString sUser; + UString sRegistry; + if (isPercent) + { + UString s; + s.Add_UInt64(val); + s.Add_Char('%'); + if (isDefault) + sUser = k_Auto_Prefix; + else + sRegistry = s; + sUser += s; + } + else + { + AddMemSize(sUser, val); + sRegistry = sUser; + for (;;) + { + const int pos = sRegistry.Find(L' '); + if (pos < 0) + break; + sRegistry.Delete(pos); + } + if (!sRegistry.IsEmpty()) + if (sRegistry.Back() == 'B') + sRegistry.DeleteBack(); + } + const unsigned dataIndex = _memUse_Strings.Add(sRegistry); + const int index = (int)m_MemUse.AddString(sUser); + m_MemUse.SetItemData(index, (LPARAM)dataIndex); + return index; +} + + + +void CCompressDialog::SetMemUseCombo() +{ + _memUse_Strings.Clear(); + m_MemUse.ResetContent(); + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + + { + const bool enable = fi.MemUse_(); + ShowItem_Bool(IDT_COMPRESS_MEMORY, enable); + ShowItem_Bool(IDT_COMPRESS_MEMORY_VALUE, enable); + ShowItem_Bool(IDT_COMPRESS_MEMORY_DE, enable); + ShowItem_Bool(IDT_COMPRESS_MEMORY_DE_VALUE, enable); + ShowItem_Bool(IDC_COMPRESS_MEM_USE, enable); + EnableItem(IDC_COMPRESS_MEM_USE, enable); + if (!enable) + return; + } + + UInt64 curMem_Bytes = 0; + UInt64 curMem_Percents = 0; + bool needSetCur_Bytes = false; + bool needSetCur_Percents = false; + { + const NCompression::CFormatOptions &fo = Get_FormatOptions(); + if (!fo.MemUse.IsEmpty()) + { + NCompression::CMemUse mu; + mu.Parse(fo.MemUse); + if (mu.IsDefined) + { + if (mu.IsPercent) + { + curMem_Percents = mu.Val; + needSetCur_Percents = true; + } + else + { + curMem_Bytes = mu.GetBytes(_ramSize_Reduced); + needSetCur_Bytes = true; + } + } + } + } + + + // 80% - is auto usage limit in handlers + AddMemComboItem(80, true, true); + m_MemUse.SetCurSel(0); + + { + for (unsigned i = 10;; i += 10) + { + UInt64 size = i; + if (i > 100) + size = (UInt64)(Int64)-1; + if (needSetCur_Percents && size >= curMem_Percents) + { + const int index = AddMemComboItem(curMem_Percents, true); + m_MemUse.SetCurSel(index); + needSetCur_Percents = false; + if (size == curMem_Percents) + continue; + } + if (size == (UInt64)(Int64)-1) + break; + AddMemComboItem(size, true); + } + } + { + for (unsigned i = (27) * 2;; i++) + { + UInt64 size = (UInt64)(2 + (i & 1)) << (i / 2); + if (i > (20 + sizeof(size_t) * 3 - 1) * 2) + size = (UInt64)(Int64)-1; + if (needSetCur_Bytes && size >= curMem_Bytes) + { + const int index = AddMemComboItem(curMem_Bytes); + m_MemUse.SetCurSel(index); + needSetCur_Bytes = false; + if (size == curMem_Bytes) + continue; + } + if (size == (UInt64)(Int64)-1) + break; + AddMemComboItem(size); + } + } +} + + +UString CCompressDialog::Get_MemUse_Spec() +{ + if (m_MemUse.GetCount() < 1) + return UString(); + return _memUse_Strings[(unsigned)m_MemUse.GetItemData_of_CurSel()]; +} + + +UInt64 CCompressDialog::Get_MemUse_Bytes() +{ + const UString mus = Get_MemUse_Spec(); + NCompression::CMemUse mu; + if (!mus.IsEmpty()) + { + mu.Parse(mus); + if (mu.IsDefined) + return mu.GetBytes(_ramSize_Reduced); + } + return _ramUsage_Auto; // _ramSize_Reduced; // _ramSize;; +} + + + +UInt64 CCompressDialog::GetMemoryUsage_DecompMem(UInt64 &decompressMemory) +{ + return GetMemoryUsage_Dict_DecompMem(GetDict2(), decompressMemory); +} + + +/* +we could use that function to reduce the dictionary if small RAM +UInt64 CCompressDialog::GetMemoryUsageComp_Threads_Dict(UInt32 numThreads, UInt64 dict64) +{ + UInt64 decompressMemory; + return GetMemoryUsage_Threads_Dict_DecompMem(numThreads, dict64, decompressMemory); +} +*/ + + +UInt64 CCompressDialog::GetMemoryUsage_Dict_DecompMem(UInt64 dict64, UInt64 &decompressMemory) +{ + return GetMemoryUsage_Threads_Dict_DecompMem(GetNumThreads2(), dict64, decompressMemory); +} + +UInt64 CCompressDialog::GetMemoryUsage_Threads_Dict_DecompMem(UInt32 numThreads, UInt64 dict64, UInt64 &decompressMemory) +{ + decompressMemory = (UInt64)(Int64)-1; + + const UInt32 level = GetLevel2(); + if (level == 0 && !Get_ArcInfoEx().Is_Zstd()) + { + decompressMemory = (1 << 20); + return decompressMemory; + } + UInt64 size = 0; + + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + if (fi.Filter_() && level >= 9) + size += (12 << 20) * 2 + (5 << 20); + // UInt32 numThreads = GetNumThreads2(); + + UInt32 numMainZipThreads = 1; + + if (IsZipFormat()) + { + UInt32 numSubThreads = 1; + if (GetMethodID() == kLZMA && numThreads > 1 && level >= 5) + numSubThreads = 2; + numMainZipThreads = numThreads / numSubThreads; + if (numMainZipThreads > 1) + size += (UInt64)numMainZipThreads * ((size_t)sizeof(size_t) << 23); + else + numMainZipThreads = 1; + } + + const int methodId = GetMethodID(); + + if (dict64 == (UInt64)(Int64)-1 + // && methodId != kZSTD + ) + return (UInt64)(Int64)-1; + + + switch (methodId) + { + case kLZMA: + case kLZMA2: + { + const UInt32 dict = (dict64 >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dict64); + UInt32 hs = dict - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + if (hs >= (1 << 24)) + hs >>= 1; + hs |= (1 << 16) - 1; + // if (numHashBytes >= 5) + if (level < 5) + hs |= (256 << 10) - 1; + hs++; + UInt64 size1 = (UInt64)hs * 4; + size1 += (UInt64)dict * 4; + if (level >= 5) + size1 += (UInt64)dict * 4; + size1 += (2 << 20); + + UInt32 numThreads1 = 1; + if (numThreads > 1 && level >= 5) + { + size1 += (2 << 20) + (4 << 20); + numThreads1 = 2; + } + + UInt32 numBlockThreads = numThreads / numThreads1; + + UInt64 chunkSize = 0; // it's solid chunk + + if (methodId != kLZMA && numBlockThreads != 1) + { + chunkSize = Get_Lzma2_ChunkSize(dict); + + if (IsXzFormat()) + { + UInt32 blockSizeLog = GetBlockSizeSpec(); + if (blockSizeLog != (UInt32)(Int32)-1) + { + if (blockSizeLog == kSolidLog_FullSolid) + { + numBlockThreads = 1; + chunkSize = 0; + } + else if (blockSizeLog != kSolidLog_NoSolid) + chunkSize = (UInt64)1 << blockSizeLog; + } + } + } + + if (chunkSize == 0) + { + const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16); + UInt64 blockSize = (UInt64)dict + (1 << 16) + + (numThreads1 > 1 ? (1 << 20) : 0); + blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2)); + if (blockSize >= kBlockSizeMax) + blockSize = kBlockSizeMax; + size += numBlockThreads * (size1 + blockSize); + } + else + { + size += numBlockThreads * (size1 + chunkSize); + const UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1; + if (chunkSize < ((UInt32)1 << 26)) numBlockThreads++; + if (chunkSize < ((UInt32)1 << 24)) numBlockThreads++; + if (chunkSize < ((UInt32)1 << 22)) numBlockThreads++; + size += numPackChunks * chunkSize; + } + + decompressMemory = dict + (2 << 20); + return size; + } + + /* + case kZSTD: + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = level; + props.nbWorkers = numThreads; + ZstdEncProps_SetDictProps_From_CompressDialog(&props, *this); + ZstdEncProps_NormalizeFull(&props); + size = ZstdEncProps_GetMemUsage(&props); + decompressMemory = (UInt64)1 << props.windowLog; + return size; + } + */ + + case kPPMd: + { + decompressMemory = dict64 + (2 << 20); + return size + decompressMemory; + } + + case kDeflate: + case kDeflate64: + { + UInt64 size1 = 3 << 20; + // if (level >= 7) + size1 += (1 << 20); + size += size1 * numMainZipThreads; + decompressMemory = (2 << 20); + return size; + } + + case kBZip2: + { + decompressMemory = (7 << 20); + UInt64 memForOneThread = (10 << 20); + return size + memForOneThread * numThreads; + } + + case kPPMdZip: + { + decompressMemory = dict64 + (2 << 20); + return size + (UInt64)decompressMemory * numThreads; + } + } + + return (UInt64)(Int64)-1; +} + + + +static void AddMemUsage(UString &s, UInt64 v) +{ + const char *post; + if (v <= ((UInt64)16 << 30)) + { + v = (v + (1 << 20) - 1) >> 20; + post = "MB"; + } + else if (v <= ((UInt64)64 << 40)) + { + v = (v + (1 << 30) - 1) >> 30; + post = "GB"; + } + else + { + const UInt64 v2 = v + ((UInt64)1 << 40) - 1; + if (v <= v2) + v = v2; + v >>= 40; + post = "TB"; + } + s.Add_UInt64(v); + s.Add_Space(); + s += post; +} + + +void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) +{ + if (value == (UInt64)(Int64)-1) + { + SetItemText(res, TEXT("?")); + return; + } + UString s; + AddMemUsage(s, value); + if (res == IDT_COMPRESS_MEMORY_VALUE) + { + const UString mus = Get_MemUse_Spec(); + NCompression::CMemUse mu; + if (!mus.IsEmpty()) + mu.Parse(mus); + if (mu.IsDefined) + { + s += " / "; + AddMemUsage(s, mu.GetBytes(_ramSize_Reduced)); + } + else if (_ramSize_Defined) + { + s += " / "; + AddMemUsage(s, _ramUsage_Auto); + } + + if (_ramSize_Defined) + { + s += " / "; + AddMemUsage(s, _ramSize); + } + } + SetItemText(res, s); +} + + +void CCompressDialog::SetMemoryUsage() +{ + UInt64 decompressMem; + const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem); + PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage); + PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem); + #ifdef PRINT_PARAMS + Print_Params(); + #endif +} + + + +#ifdef PRINT_PARAMS + +static const char kPropDelimeter = ' '; // ':' + +static void AddPropName(AString &s, const char *name) +{ + if (!s.IsEmpty()) + s += kPropDelimeter; + s += name; +} + +static void AddProp(AString &s, const char *name, unsigned v) +{ + AddPropName(s, name); + s.Add_UInt32(v); +} + +static void AddProp_switch(AString &s, const char *name, E_ZSTD_paramSwitch_e e) +{ + AddPropName(s, name); + s += e == k_ZSTD_ps_enable ? "" : "-"; +} + +static void PrintPropAsLog(AString &s, const char *name, size_t v) +{ + AddPropName(s, name); + for (unsigned i = 0; i < sizeof(size_t) * 8; i++) + { + if (((size_t)1 << i) == v) + { + s.Add_UInt32(i); + return; + } + } + char c = 'b'; + if ((v & 0x3FFFFFFF) == 0) { v >>= 30; c = 'G'; } + else if ((v & 0xFFFFF) == 0) { v >>= 20; c = 'M'; } + else if ((v & 0x3FF) == 0) { v >>= 10; c = 'K'; } + s.Add_UInt64(v); + s += c; +} + +static void ZstdEncProps_Print(CZstdEncProps *props, AString &s) +{ + if (props->level_zstd >= 0) + AddProp(s, "zx", props->level_zstd); + else + AddProp(s, "zf", -(props->level_zstd)); + AddProp(s, "a", props->strategy); + AddProp(s, "d", props->windowLog); + AddProp(s, "zclog", props->chainLog); + AddProp(s, "zhb", props->hashLog); + AddProp(s, "mml", props->minMatch); + AddProp(s, "mcb", props->searchLog); + AddProp(s, "fb", props->targetLength); + AddProp(s, "mt", props->nbWorkers); + PrintPropAsLog(s, "c", props->jobSize); + AddProp(s, "zov", props->overlapLog); + PrintPropAsLog(s, "ztps", props->targetPrefixSize); + AddProp_switch(s, "zmfr", props->useRowMatchFinder); + if (props->ldmParams.enableLdm == k_ZSTD_ps_enable) + { + AddProp_switch(s, "zle", props->ldmParams.enableLdm); + AddProp(s, "zlhb", props->ldmParams.hashLog); + AddProp(s, "zlbb", props->ldmParams.bucketSizeLog); + AddProp(s, "zlmml", props->ldmParams.minMatchLength); + AddProp(s, "zlhrb", props->ldmParams.hashRateLog); + } +} + +void CCompressDialog::Print_Params() +{ + { + CZstdEncProps props; + ZstdEncProps_Init(&props); + // props.level_zstd = level; + props.level_7z = GetLevel2(); + ZstdEncProps_SetDictProps_From_CompressDialog(&props, *this); + { + UInt32 order = GetOrderSpec(); + if (order != (UInt32)(Int32)-1) + props.targetLength = GetOrderSpec(); + } + props.nbWorkers = GetNumThreads2(); + // props.windowLog = 18; // for debug + ZstdEncProps_NormalizeFull(&props); + AString s; + ZstdEncProps_Print(&props, s); + SetItemTextA(IDT_COMPRESS_PARAMS_INFO, s); + } +} + +#endif // PRINT_PARAMS + + + +void CCompressDialog::SetParams() +{ + const CArcInfoEx &ai = Get_ArcInfoEx(); + m_Params.SetText(TEXT("")); + const int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + m_Params.SetText(fo.Options); + } +} + +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 unsigned index = FindRegistryFormat_Always(ai.Name); + NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index]; + fo.Options = Info.Options; + fo.Level = GetLevelSpec(); + { + const UInt64 dict64 = GetDictSpec(); + UInt32 dict32; + if (dict64 == (UInt64)(Int64)-1) + dict32 = (UInt32)(Int32)-1; + else + { + dict32 = (UInt32)dict64; + if (dict64 != dict32) + { + /* here we must write 32-bit value for registry that indicates big_value + (UInt32)(Int32)-1 : is used as marker for default size + (UInt32)(Int32)-2 : it can be used to indicate big value (4 GiB) + the value must be larger than threshold + */ + dict32 = (UInt32)(Int32)-2; + // dict32 = kLzmaMaxDictSize; // it must be larger than threshold + } + } + fo.Dictionary = dict32; + } + /* + { + const UInt64 dict64 = GetDictChainSpec(); + UInt32 dict32; + if (dict64 == (UInt64)(Int64)-1) + dict32 = (UInt32)(Int32)-1; + else + { + dict32 = (UInt32)dict64; + if (dict64 != dict32) + { + dict32 = (UInt32)(Int32)-2; + // dict32 = k_Zstd_MAX_DictSize; // it must be larger than threshold + } + } + fo.DictionaryChain = dict32; + } + */ + + fo.Order = GetOrderSpec(); + fo.Method = GetMethodSpec(); + fo.EncryptionMethod = GetEncryptionMethodSpec(); + fo.NumThreads = GetNumThreadsSpec(); + fo.BlockLogSize = GetBlockSizeSpec(); + 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.IsSet_TimePrec()) + { + 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, (LPARAM)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.Add_Colon(); + if (methodID >= 0 && (unsigned)methodID < Z7_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 Z7_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 Z7_LANG + LangSetWindowText(*this, IDB_COMPRESS_OPTIONS); // IDS_OPTIONS + LangSetDlgItems(*this, kLangIDs_Options, Z7_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(unsigned code, unsigned 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(unsigned 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_Options); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.h 2024-10-20 16:00:00.000000000 +0000 @@ -1,215 +1,483 @@ -// CompressDialog.h - -#ifndef __COMPRESS_DIALOG_H -#define __COMPRESS_DIALOG_H - -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Edit.h" - -#include "../Common/LoadCodecs.h" -#include "../Common/ZipRegistry.h" - -#include "../FileManager/DialogSize.h" - -#include "CompressDialogRes.h" - -namespace NCompressDialog -{ - namespace NUpdateMode - { - enum EEnum - { - kAdd, - kUpdate, - kFresh, - kSync - }; - } - - struct CInfo - { - NUpdateMode::EEnum UpdateMode; - NWildcard::ECensorPathMode PathMode; - - bool SolidIsSpecified; - bool MultiThreadIsAllowed; - UInt64 SolidBlockSize; - UInt32 NumThreads; - - CRecordVector VolumeSizes; - - UInt32 Level; - UString Method; - UInt32 Dictionary; - bool OrderMode; - UInt32 Order; - UString Options; - - UString EncryptionMethod; - - bool SFXMode; - bool OpenShareForWrite; - bool DeleteAfterCompressing; - - CBoolPair SymLinks; - CBoolPair HardLinks; - CBoolPair AltStreams; - CBoolPair NtSecurity; - - UString ArcPath; // in: Relative or abs ; out: Relative or abs - - // FString CurrentDirPrefix; - bool KeepName; - - bool GetFullPathName(UString &result) const; - - int FormatIndex; - - UString Password; - bool EncryptHeadersIsAllowed; - bool EncryptHeaders; - - CInfo(): - UpdateMode(NCompressDialog::NUpdateMode::kAdd), - PathMode(NWildcard::k_RelatPath), - SFXMode(false), - OpenShareForWrite(false), - DeleteAfterCompressing(false), - FormatIndex(-1) - { - Level = Dictionary = Order = UInt32(-1); - OrderMode = false; - Method.Empty(); - Options.Empty(); - EncryptionMethod.Empty(); - } - }; -} - -class CCompressDialog: public NWindows::NControl::CModalDialog -{ - NWindows::NControl::CComboBox m_ArchivePath; - NWindows::NControl::CComboBox m_Format; - NWindows::NControl::CComboBox m_Level; - NWindows::NControl::CComboBox m_Method; - NWindows::NControl::CComboBox m_Dictionary; - NWindows::NControl::CComboBox m_Order; - NWindows::NControl::CComboBox m_Solid; - NWindows::NControl::CComboBox m_NumThreads; - - NWindows::NControl::CComboBox m_UpdateMode; - NWindows::NControl::CComboBox m_PathMode; - - NWindows::NControl::CComboBox m_Volume; - NWindows::NControl::CDialogChildControl m_Params; - - NWindows::NControl::CEdit _password1Control; - NWindows::NControl::CEdit _password2Control; - NWindows::NControl::CComboBox _encryptionMethod; - - NCompression::CInfo m_RegistryInfo; - - int m_PrevFormat; - UString DirPrefix; - UString StartDirPrefix; - - void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2); - void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2); - - void SetArchiveName(const UString &name); - int FindRegistryFormat(const UString &name); - int FindRegistryFormatAlways(const UString &name); - - void CheckSFXNameChange(); - void SetArchiveName2(bool prevWasSFX); - - int GetStaticFormatIndex(); - - void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value); - - void SetLevel(); - - void SetMethod(int keepMethodId = -1); - int GetMethodID(); - UString GetMethodSpec(); - UString GetEncryptionMethodSpec(); - - bool IsZipFormat(); - - void SetEncryptionMethod(); - - void AddDictionarySize(UInt32 size); - - void SetDictionary(); - - UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0); - - UInt32 GetLevel() { return GetComboValue(m_Level); } - UInt32 GetLevelSpec() { return GetComboValue(m_Level, 1); } - UInt32 GetLevel2(); - UInt32 GetDictionary() { return GetComboValue(m_Dictionary); } - UInt32 GetDictionarySpec() { return GetComboValue(m_Dictionary, 1); } - UInt32 GetOrder() { return GetComboValue(m_Order); } - UInt32 GetOrderSpec() { return GetComboValue(m_Order, 1); } - UInt32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); } - UInt32 GetNumThreads2() { UInt32 num = GetNumThreadsSpec(); if (num == UInt32(-1)) num = 1; return num; } - UInt32 GetBlockSizeSpec() { return GetComboValue(m_Solid, 1); } - - int AddOrder(UInt32 size); - void SetOrder(); - bool GetOrderMode(); - - void SetSolidBlockSize(); - void SetNumThreads(); - - UInt64 GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory); - UInt64 GetMemoryUsage(UInt64 &decompressMemory); - void PrintMemUsage(UINT res, UInt64 value); - void SetMemoryUsage(); - void SetParams(); - void SaveOptionsInMem(); - - void UpdatePasswordControl(); - bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); } - - unsigned GetFormatIndex(); - bool SetArcPathFields(const UString &path, UString &name, bool always); - bool GetFinalPath_Smart(UString &resPath); - -public: - CObjectVector *ArcFormats; - CUIntVector ArcIndices; // can not be empty, must contain Info.FormatIndex, if Info.FormatIndex >= 0 - - NCompressDialog::CInfo Info; - UString OriginalFileName; // for bzip2, gzip2 - bool CurrentDirWasChanged; - - INT_PTR Create(HWND wndParent = 0) - { - BIG_DIALOG_SIZE(400, 304); - return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS), wndParent); - } - - CCompressDialog(): CurrentDirWasChanged(false) {}; - -protected: - - void CheckSFXControlsEnable(); - // void CheckVolumeEnable(); - void CheckControlsEnable(); - - void OnButtonSetArchive(); - bool IsSFX(); - void OnButtonSFX(); - - 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(); - -}; - -#endif +// CompressDialog.h + +#ifndef ZIP7_INC_COMPRESS_DIALOG_H +#define ZIP7_INC_COMPRESS_DIALOG_H + +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" + +#include "../Common/LoadCodecs.h" +#include "../Common/ZipRegistry.h" + +#include "../FileManager/DialogSize.h" + +#include "CompressDialogRes.h" + +namespace NCompressDialog +{ + namespace NUpdateMode + { + enum EEnum + { + kAdd, + kUpdate, + kFresh, + kSync + }; + } + + struct CInfo + { + NUpdateMode::EEnum UpdateMode; + NWildcard::ECensorPathMode PathMode; + + bool SolidIsSpecified; + // bool MultiThreadIsAllowed; + UInt64 SolidBlockSize; + UInt32 NumThreads; + + NCompression::CMemUse MemUsage; + + CRecordVector VolumeSizes; + + UInt32 Level; + UString Method; + UInt64 Dict64; + // UInt64 Dict64_Chain; + bool OrderMode; + UInt32 Order; + UString Options; + + UString EncryptionMethod; + + bool SFXMode; + bool OpenShareForWrite; + bool DeleteAfterCompressing; + + CBoolPair SymLinks; + 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 + + // FString CurrentDirPrefix; + bool KeepName; + + bool GetFullPathName(UString &result) const; + + int FormatIndex; + + UString Password; + bool EncryptHeadersIsAllowed; + bool EncryptHeaders; + + CInfo(): + UpdateMode(NCompressDialog::NUpdateMode::kAdd), + PathMode(NWildcard::k_RelatPath), + SFXMode(false), + OpenShareForWrite(false), + DeleteAfterCompressing(false), + FormatIndex(-1) + { + Level = Order = (UInt32)(Int32)-1; + NumThreads = (UInt32)(Int32)-1; + SolidIsSpecified = false; + Dict64 = (UInt64)(Int64)(-1); + // Dict64_Chain = (UInt64)(Int64)(-1); + OrderMode = false; + 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 +{ +public: + CBool1 SymLinks; + CBool1 HardLinks; + CBool1 AltStreams; + CBool1 NtSecurity; + CBool1 PreserveATime; +private: + bool _ramSize_Defined; + + NWindows::NControl::CComboBox m_ArchivePath; + NWindows::NControl::CComboBox m_Format; + NWindows::NControl::CComboBox m_Level; + NWindows::NControl::CComboBox m_Method; + NWindows::NControl::CComboBox m_Dictionary; + // NWindows::NControl::CComboBox m_Dictionary_Chain; + NWindows::NControl::CComboBox m_Order; + NWindows::NControl::CComboBox m_Solid; + NWindows::NControl::CComboBox m_NumThreads; + NWindows::NControl::CComboBox m_MemUse; + NWindows::NControl::CComboBox m_Volume; + + int _dictionaryCombo_left; + + UStringVector _memUse_Strings; + + NWindows::NControl::CDialogChildControl m_Params; + + NWindows::NControl::CComboBox m_UpdateMode; + NWindows::NControl::CComboBox m_PathMode; + + NWindows::NControl::CEdit _password1Control; + NWindows::NControl::CEdit _password2Control; + NWindows::NControl::CComboBox _encryptionMethod; + + int _auto_MethodId; + UInt32 _auto_Dict; // (UInt32)(Int32)-1 means unknown + UInt32 _auto_Dict_Chain; // (UInt32)(Int32)-1 means unknown + UInt32 _auto_Order; + UInt64 _auto_Solid; + UInt32 _auto_NumThreads; + + int _default_encryptionMethod_Index; + + int m_PrevFormat; + UString DirPrefix; + UString StartDirPrefix; + + size_t _ramSize; // full RAM size avail + size_t _ramSize_Reduced; // full for 64-bit and reduced for 32-bit + UInt64 _ramUsage_Auto; + +public: + NCompression::CInfo m_RegistryInfo; + + void SetArchiveName(const UString &name); + int FindRegistryFormat(const UString &name); + unsigned FindRegistryFormat_Always(const UString &name); + + const CArcInfoEx &Get_ArcInfoEx() + { + return (*ArcFormats)[GetFormatIndex()]; + } + + NCompression::CFormatOptions &Get_FormatOptions(); + + void CheckSFXNameChange(); + void SetArchiveName2(bool prevWasSFX); + + unsigned GetStaticFormatIndex(); + + void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value); + + void SetLevel2(); + void SetLevel() + { + SetLevel2(); + EnableMultiCombo(IDC_COMPRESS_LEVEL); + SetMethod(); + } + + void SetMethod2(int keepMethodId); + void SetMethod(int keepMethodId = -1) + { + SetMethod2(keepMethodId); + EnableMultiCombo(IDC_COMPRESS_METHOD); + } + + void MethodChanged() + { + SetDictionary2(); + EnableMultiCombo(IDC_COMPRESS_DICTIONARY); + // EnableMultiCombo(IDC_COMPRESS_DICTIONARY2); + SetOrder2(); + EnableMultiCombo(IDC_COMPRESS_ORDER); + } + + int GetMethodID_RAW(); + int GetMethodID(); + + UString GetMethodSpec(UString &estimatedName); + UString GetMethodSpec(); + bool IsMethodEqualTo(const UString &s); + UString GetEncryptionMethodSpec(); + + bool IsZipFormat(); + bool IsXzFormat(); + + void SetEncryptionMethod(); + + int AddDict2(size_t sizeReal, size_t sizeShow); + int AddDict(size_t size); + // int AddDict_Chain(size_t size); + + void SetDictionary2(); + + UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0); + UInt64 GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax = 0); + + UInt32 GetLevel() { return GetComboValue(m_Level); } + UInt32 GetLevelSpec() { return GetComboValue(m_Level, 1); } + UInt32 GetLevel2(); + + UInt64 GetDictSpec() { return GetComboValue_64(m_Dictionary, 1); } + // UInt64 GetDictChainSpec() { return GetComboValue_64(m_Dictionary_Chain, 1); } + + UInt64 GetDict2() + { + UInt64 num = GetDictSpec(); + if (num == (UInt64)(Int64)-1) + { + if (_auto_Dict == (UInt32)(Int32)-1) + return (UInt64)(Int64)-1; // unknown + num = _auto_Dict; + } + return num; + } + + // UInt32 GetOrder() { return GetComboValue(m_Order); } + UInt32 GetOrderSpec() { return GetComboValue(m_Order, 1); } + UInt32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); } + + UInt32 GetNumThreads2() + { + UInt32 num = GetNumThreadsSpec(); + if (num == (UInt32)(Int32)-1) + num = _auto_NumThreads; + return num; + } + + 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(); + + void SetOrder2(); + + bool GetOrderMode(); + + void SetSolidBlockSize2(); + void SetSolidBlockSize(/* bool useDictionary = false */) + { + SetSolidBlockSize2(); + EnableMultiCombo(IDC_COMPRESS_SOLID); + } + + void SetNumThreads2(); + void SetNumThreads() + { + SetNumThreads2(); + EnableMultiCombo(IDC_COMPRESS_THREADS); + } + + int AddMemComboItem(UInt64 val, bool isPercent = false, bool isDefault = false); + void SetMemUseCombo(); + UString Get_MemUse_Spec(); + UInt64 Get_MemUse_Bytes(); + + UInt64 GetMemoryUsage_Dict_DecompMem(UInt64 dict, UInt64 &decompressMemory); + UInt64 GetMemoryUsage_Threads_Dict_DecompMem(UInt32 numThreads, UInt64 dict, UInt64 &decompressMemory); + UInt64 GetMemoryUsage_DecompMem(UInt64 &decompressMemory); + UInt64 GetMemoryUsageComp_Threads_Dict(UInt32 numThreads, UInt64 dict64); + + void PrintMemUsage(UINT res, UInt64 value); + void SetMemoryUsage(); + void Print_Params(); + + void SetParams(); + + void SaveOptionsInMem(); + + void UpdatePasswordControl(); + bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); } + + unsigned GetFormatIndex(); + bool SetArcPathFields(const UString &path, UString &name, bool always); + bool SetArcPathFields(const UString &path); + bool GetFinalPath_Smart(UString &resPath) const; + void ArcPath_WasChanged(const UString &newPath); + + void CheckSFXControlsEnable(); + // void CheckVolumeEnable(); + void EnableMultiCombo(unsigned id); + void FormatChanged(bool isChanged); + + void OnButtonSetArchive(); + bool IsSFX(); + void OnButtonSFX(); + + virtual bool OnInit() Z7_override; + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + virtual void OnHelp() Z7_override; + + void MessageBoxError(LPCWSTR message) + { + 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 + AStringVector ExternalMethods; + + void SetMethods(const CObjectVector &userCodecs); + + NCompressDialog::CInfo Info; + UString OriginalFileName; // for bzip2, gzip2 + + INT_PTR Create(HWND wndParent = NULL) + { + BIG_DIALOG_SIZE(400, 320); + return CModalDialog::Create(SIZED_DIALOG(IDD_COMPRESS), wndParent); + } + + CCompressDialog() {} +}; + + + + +class COptionsDialog: public NWindows::NControl::CModalDialog +{ + struct CBoolBox + { + bool IsSupported; + bool DefaultVal; + CBoolPair BoolPair; + + unsigned Id; + unsigned Set_Id; + + void SetIDs(unsigned id, unsigned 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() Z7_override; + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + virtual void OnHelp() Z7_override; + +public: + + INT_PTR Create(HWND wndParent = NULL) + { + 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 -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog.rc 2024-03-11 07:00:00.000000000 +0000 @@ -0,0 +1,233 @@ +#include "CompressDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 400 +#define yc 320 + +#undef gSize +#undef gSpace +#undef g0xs +#undef g1x +#undef g1xs +#undef g2xs +#undef g3x +#undef g3xs +#undef g4x +#undef g4x2 +#undef g4xs +#undef g4xs2 + +#define gSize 192 +#define gSpace 24 + + +#define g1xs 88 +#define g0xs (gSize - g1xs) +#define g1x (m + g0xs) + +#define g3xs 52 +#define g2xs (gSize - g3xs) +#define g3x (m + g2xs) + +#define g4x (m + gSize + gSpace) +#define g4x2 (g4x + m) +#define g4xs (xc - gSize - gSpace) +#define g4xs2 (g4xs - m - m) + +#define yOpt 80 + +#define xArcFolderOffs 40 + +#undef GROUP_Y_SIZE +#undef GROUP_Y_SIZE_ENCRYPT +#ifdef UNDER_CE +#define GROUP_Y_SIZE 8 +#define GROUP_Y_SIZE_ENCRYPT 8 +#else +#define GROUP_Y_SIZE 64 +#define GROUP_Y_SIZE_ENCRYPT 128 +#endif + +// #define DICT_SIZE_SPACE 8 +// #define DICT_SIZE 54 +// #define DICT_x (g1x + g1xs - DICT_SIZE) +// #define DICT2_x (DICT_x - DICT_SIZE_SPACE - DICT_SIZE) + +#define yPsw (yOpt + GROUP_Y_SIZE + 8) + +IDD_COMPRESS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Add to Archive" +BEGIN + LTEXT "", IDT_COMPRESS_ARCHIVE_FOLDER, m + xArcFolderOffs, m, xc - xArcFolderOffs, 8 + LTEXT "&Archive:", IDT_COMPRESS_ARCHIVE, m, 12, xArcFolderOffs, 8 + COMBOBOX IDC_COMPRESS_ARCHIVE, m + xArcFolderOffs, 18, xc - bxsDots - 12 - xArcFolderOffs, 126, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE, xs - m - bxsDots, 16, bxsDots, bys, WS_GROUP + + LTEXT "Archive &format:", IDT_COMPRESS_FORMAT, m, 41, g0xs, 8 + COMBOBOX IDC_COMPRESS_FORMAT, g1x, 39, g1xs, 80, MY_COMBO | CBS_SORT + + LTEXT "Compression &level:", IDT_COMPRESS_LEVEL, m, 62, g0xs, 8 + COMBOBOX IDC_COMPRESS_LEVEL, g1x, 60, g1xs, 80, MY_COMBO + + LTEXT "Compression &method:", IDT_COMPRESS_METHOD, m, 83, g0xs, 8 + COMBOBOX IDC_COMPRESS_METHOD, g1x, 81, g1xs, 80, MY_COMBO + + LTEXT "&Dictionary size:", IDT_COMPRESS_DICTIONARY, m, 104, g0xs, 8 + COMBOBOX IDC_COMPRESS_DICTIONARY, g1x, 102, g1xs, 167, MY_COMBO + // LTEXT "&Dictionary size:", IDT_COMPRESS_DICTIONARY, m, 104, DICT_x - m, 16 // 8, SS_LEFTNOWORDWRAP + // LTEXT "", IDT_COMPRESS_PARAMS_INFO, m, 283, xs, MY_TEXT_NOPREFIX + // CTEXT "-", 0, DICT_x - DICT_SIZE_SPACE, 104, DICT_SIZE_SPACE, 8 + // COMBOBOX IDC_COMPRESS_DICTIONARY2, DICT2_x, 102, DICT_SIZE, 140, MY_COMBO + // COMBOBOX IDC_COMPRESS_DICTIONARY, DICT_x, 102, DICT_SIZE, 140, MY_COMBO + + LTEXT "&Word size:", IDT_COMPRESS_ORDER, m, 125, g0xs, 8 + COMBOBOX IDC_COMPRESS_ORDER, g1x, 123, g1xs, 140, MY_COMBO + + LTEXT "&Solid Block size:", IDT_COMPRESS_SOLID, m, 146, g0xs, 8 + COMBOBOX IDC_COMPRESS_SOLID, g1x, 144, g1xs, 140, MY_COMBO + + LTEXT "Number of CPU &threads:", IDT_COMPRESS_THREADS, m, 167, g0xs, 8 + COMBOBOX IDC_COMPRESS_THREADS, g1x, 165, g1xs - 35, 140, MY_COMBO + RTEXT "", IDT_COMPRESS_HARDWARE_THREADS, g1x + g1xs - 35 + 10, 167, 25, MY_TEXT_NOPREFIX + + + LTEXT "Memory usage for Compressing:", IDT_COMPRESS_MEMORY, m, 184, g2xs, 8 + COMBOBOX IDC_COMPRESS_MEM_USE, g3x, 188, g3xs, 140, MY_COMBO + LTEXT "", IDT_COMPRESS_MEMORY_VALUE, m, 194, g2xs, MY_TEXT_NOPREFIX + + LTEXT "Memory usage for Decompressing:", IDT_COMPRESS_MEMORY_DE, m, 208, g2xs, 8 + RTEXT "", IDT_COMPRESS_MEMORY_DE_VALUE, g3x, 208, g3xs, MY_TEXT_NOPREFIX + + + LTEXT "Split to &volumes, bytes:", IDT_SPLIT_TO_VOLUMES, m, 225, gSize, 8 + COMBOBOX IDC_COMPRESS_VOLUME, m, 237, gSize, 73, MY_COMBO_WITH_EDIT + + LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m, 256, gSize, 8 + EDITTEXT IDE_COMPRESS_PARAMETERS, m, 268, gSize, 14, ES_AUTOHSCROLL + + 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 + + LTEXT "Path mode:", IDT_COMPRESS_PATH_MODE, g4x, 61, 80, 8 + COMBOBOX IDC_COMPRESS_PATH_MODE, g4x + 84, 59, g4xs - 84, 80, MY_COMBO + + + GROUPBOX "Options", IDG_COMPRESS_OPTIONS, g4x, yOpt, g4xs, GROUP_Y_SIZE + + CONTROL "Create SF&X archive", IDX_COMPRESS_SFX, MY_CHECKBOX, + g4x2, yOpt + 14, g4xs2, 10 + CONTROL "Compress shared files", IDX_COMPRESS_SHARED, MY_CHECKBOX, + g4x2, yOpt + 30, g4xs2, 10 + CONTROL "Delete files after compression", IDX_COMPRESS_DEL, MY_CHECKBOX, + g4x2, yOpt + 46, g4xs2, 10 + + + GROUPBOX "Encryption", IDG_COMPRESS_ENCRYPTION, g4x, yPsw, g4xs, GROUP_Y_SIZE_ENCRYPT + + LTEXT "Enter &password:", IDT_PASSWORD_ENTER, g4x2, yPsw + 14, g4xs2, 8 + EDITTEXT IDE_COMPRESS_PASSWORD1, g4x2, yPsw + 26, g4xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Reenter password:", IDT_PASSWORD_REENTER, g4x2, yPsw + 46, g4xs2, 8 + EDITTEXT IDE_COMPRESS_PASSWORD2, g4x2, yPsw + 58, g4xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL + + CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, + g4x2, yPsw + 79, g4xs2, 10 + + LTEXT "&Encryption method:", IDT_COMPRESS_ENCRYPTION_METHOD, g4x2, yPsw + 95, 100, 8 + COMBOBOX IDC_COMPRESS_ENCRYPTION_METHOD, g4x2 + 100, yPsw + 93, g4xs2 - 100, 198, MY_COMBO + + CONTROL "Encrypt file &names", IDX_COMPRESS_ENCRYPT_FILE_NAMES, MY_CHECKBOX, + g4x2, yPsw + 111, g4xs2, 10 + + DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys + PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys +END + + +#ifdef UNDER_CE + +#undef m +#undef xc +#undef yc + +#define m 4 +#define xc 152 +#define yc 160 + + +IDD_COMPRESS_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Add to Archive" +MY_FONT +BEGIN + COMBOBOX IDC_COMPRESS_ARCHIVE, m, m, xc - bxsDots - m, 126, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_COMPRESS_SET_ARCHIVE, xs - m - bxsDots, m, bxsDots, 12, WS_GROUP + + COMBOBOX IDC_COMPRESS_FORMAT, m , 22, 32, 80, MY_COMBO | CBS_SORT + COMBOBOX IDC_COMPRESS_LEVEL, m + 36, 22, 68, 80, MY_COMBO + COMBOBOX IDC_COMPRESS_METHOD, m + 108, 22, 44, 80, MY_COMBO + + COMBOBOX IDC_COMPRESS_DICTIONARY, m, 40, 40, 80, MY_COMBO + COMBOBOX IDC_COMPRESS_ORDER, m + 44, 40, 32, 80, MY_COMBO + COMBOBOX IDC_COMPRESS_SOLID, m + 80, 40, 40, 80, MY_COMBO + COMBOBOX IDC_COMPRESS_THREADS, m + 124, 40, 28, 80, MY_COMBO + + LTEXT "Split to &volumes, bytes:", IDT_SPLIT_TO_VOLUMES, m, 60, 32, 8 + COMBOBOX IDC_COMPRESS_VOLUME, m + 32, 58, 44, 73, MY_COMBO_WITH_EDIT + LTEXT "Parameters:", IDT_COMPRESS_PARAMETERS, m + 80, 60, 48, 8 + EDITTEXT IDE_COMPRESS_PARAMETERS, m + 128, 58, 24, 13, ES_AUTOHSCROLL + + COMBOBOX IDC_COMPRESS_UPDATE_MODE, m, 76, 88, 80, MY_COMBO + CONTROL "SF&X", IDX_COMPRESS_SFX, MY_CHECKBOX, m + 92, 77, 60, 10 + + CONTROL "Compress shared files", IDX_COMPRESS_SHARED, MY_CHECKBOX, m, 94, xc, 10 + + LTEXT "Enter &password:", IDT_PASSWORD_ENTER, m, 112, 60, 8 + EDITTEXT IDE_COMPRESS_PASSWORD1, m + 60, 110, 44, 13, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m + 108, 112, 44, 10 + + COMBOBOX IDC_COMPRESS_ENCRYPTION_METHOD, m, 128, 48, 198, MY_COMBO + CONTROL "Encrypt file &names", IDX_COMPRESS_ENCRYPT_FILE_NAMES, MY_CHECKBOX, m + 52, 130, 100, 10 + + OK_CANCEL +END + +#endif + +STRINGTABLE +BEGIN + IDS_PASSWORD_NOT_MATCH "Passwords do not match" + IDS_PASSWORD_USE_ASCII "Use only English letters, numbers and special characters (!, #, $, ...) for password." + IDS_PASSWORD_TOO_LONG "Password is too long" + + IDS_METHOD_STORE "Store" + IDS_METHOD_FASTEST "Fastest" + IDS_METHOD_FAST "Fast" + IDS_METHOD_NORMAL "Normal" + IDS_METHOD_MAXIMUM "Maximum" + IDS_METHOD_ULTRA "Ultra" + + IDS_COMPRESS_UPDATE_MODE_ADD "Add and replace files" + IDS_COMPRESS_UPDATE_MODE_UPDATE "Update and add files" + IDS_COMPRESS_UPDATE_MODE_FRESH "Freshen existing files" + IDS_COMPRESS_UPDATE_MODE_SYNC "Synchronize files" + + IDS_OPEN_TYPE_ALL_FILES "All Files" + IDS_COMPRESS_SET_ARCHIVE_BROWSE "Browse" + + IDS_COMPRESS_NON_SOLID "Non-solid" + 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" + + IDS_MEM_OPERATION_BLOCKED "The operation was blocked by 7-Zip." +END + + +#include "CompressOptionsDialog.rc" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialogRes.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialogRes.h 2024-03-15 07:00:00.000000000 +0000 @@ -1,87 +1,125 @@ -#define IDD_COMPRESS 4000 -#define IDD_COMPRESS_2 14000 - -#define IDC_COMPRESS_ARCHIVE 100 -#define IDB_COMPRESS_SET_ARCHIVE 101 -#define IDC_COMPRESS_LEVEL 102 -#define IDC_COMPRESS_UPDATE_MODE 103 -#define IDC_COMPRESS_FORMAT 104 -#define IDC_COMPRESS_VOLUME 105 -#define IDC_COMPRESS_METHOD 106 -#define IDC_COMPRESS_DICTIONARY 107 -#define IDC_COMPRESS_ORDER 108 -#define IDC_COMPRESS_SOLID 109 -#define IDC_COMPRESS_THREADS 110 -#define IDE_COMPRESS_PARAMETERS 111 - -#define IDT_COMPRESS_HARDWARE_THREADS 112 -#define IDT_COMPRESS_MEMORY_VALUE 113 -#define IDT_COMPRESS_MEMORY_DE_VALUE 114 - -#define IDG_COMPRESS_NTFS 115 -#define IDC_COMPRESS_PATH_MODE 116 - -#define IDE_COMPRESS_PASSWORD1 120 -#define IDE_COMPRESS_PASSWORD2 121 -#define IDC_COMPRESS_ENCRYPTION_METHOD 122 - -#define IDT_COMPRESS_ARCHIVE_FOLDER 130 - -#define IDT_COMPRESS_PATH_MODE 3410 - -#define IDT_PASSWORD_ENTER 3801 -#define IDT_PASSWORD_REENTER 3802 -#define IDX_PASSWORD_SHOW 3803 -#define IDS_PASSWORD_NOT_MATCH 3804 -#define IDS_PASSWORD_USE_ASCII 3805 -#define IDS_PASSWORD_TOO_LONG 3806 - -#define IDT_COMPRESS_ARCHIVE 4001 -#define IDT_COMPRESS_UPDATE_MODE 4002 -#define IDT_COMPRESS_FORMAT 4003 -#define IDT_COMPRESS_LEVEL 4004 -#define IDT_COMPRESS_METHOD 4005 -#define IDT_COMPRESS_DICTIONARY 4006 -#define IDT_COMPRESS_ORDER 4007 -#define IDT_COMPRESS_SOLID 4008 -#define IDT_COMPRESS_THREADS 4009 -#define IDT_COMPRESS_PARAMETERS 4010 -#define IDG_COMPRESS_OPTIONS 4011 - -#define IDX_COMPRESS_SFX 4012 -#define IDX_COMPRESS_SHARED 4013 - -#define IDG_COMPRESS_ENCRYPTION 4014 -#define IDT_COMPRESS_ENCRYPTION_METHOD 4015 -#define IDX_COMPRESS_ENCRYPT_FILE_NAMES 4016 - -#define IDT_COMPRESS_MEMORY 4017 -#define IDT_COMPRESS_MEMORY_DE 4018 - -#define IDX_COMPRESS_DEL 4019 - -#define IDX_COMPRESS_NT_SYM_LINKS 4040 -#define IDX_COMPRESS_NT_HARD_LINKS 4041 -#define IDX_COMPRESS_NT_ALT_STREAMS 4042 -#define IDX_COMPRESS_NT_SECUR 4043 - -#define IDS_METHOD_STORE 4050 -#define IDS_METHOD_FASTEST 4051 -#define IDS_METHOD_FAST 4052 -#define IDS_METHOD_NORMAL 4053 -#define IDS_METHOD_MAXIMUM 4054 -#define IDS_METHOD_ULTRA 4055 - -#define IDS_COMPRESS_UPDATE_MODE_ADD 4060 -#define IDS_COMPRESS_UPDATE_MODE_UPDATE 4061 -#define IDS_COMPRESS_UPDATE_MODE_FRESH 4062 -#define IDS_COMPRESS_UPDATE_MODE_SYNC 4063 - -#define IDS_COMPRESS_SET_ARCHIVE_BROWSE 4070 -#define IDS_OPEN_TYPE_ALL_FILES 4071 -#define IDS_COMPRESS_NON_SOLID 4072 -#define IDS_COMPRESS_SOLID 4073 - -#define IDT_SPLIT_TO_VOLUMES 7302 -#define IDS_INCORRECT_VOLUME_SIZE 7307 -#define IDS_SPLIT_CONFIRM 7308 +#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 +#define IDC_COMPRESS_LEVEL 102 +#define IDC_COMPRESS_UPDATE_MODE 103 +#define IDC_COMPRESS_FORMAT 104 +#define IDC_COMPRESS_VOLUME 105 +#define IDC_COMPRESS_METHOD 106 +#define IDC_COMPRESS_DICTIONARY 107 +#define IDC_COMPRESS_ORDER 108 +#define IDC_COMPRESS_SOLID 109 +#define IDC_COMPRESS_THREADS 110 +#define IDE_COMPRESS_PARAMETERS 111 + +#define IDT_COMPRESS_HARDWARE_THREADS 112 +#define IDT_COMPRESS_MEMORY_VALUE 113 +#define IDT_COMPRESS_MEMORY_DE_VALUE 114 + +#define IDG_COMPRESS_NTFS 115 +#define IDC_COMPRESS_PATH_MODE 116 +#define IDC_COMPRESS_MEM_USE 117 +// #define IDC_COMPRESS_DICTIONARY2 118 + +#define IDE_COMPRESS_PASSWORD1 120 +#define IDE_COMPRESS_PASSWORD2 121 +#define IDC_COMPRESS_ENCRYPTION_METHOD 122 + +#define IDT_COMPRESS_ARCHIVE_FOLDER 130 + +// #define IDB_COMPRESS_OPTIONS 140 +#define IDB_COMPRESS_OPTIONS 2100 +#define IDT_COMPRESS_OPTIONS 141 +// #define IDT_COMPRESS_PARAMS_INFO 142 + +#define IDT_COMPRESS_PATH_MODE 3410 + +#define IDT_PASSWORD_ENTER 3801 +#define IDT_PASSWORD_REENTER 3802 +#define IDX_PASSWORD_SHOW 3803 +#define IDS_PASSWORD_NOT_MATCH 3804 +#define IDS_PASSWORD_USE_ASCII 3805 +#define IDS_PASSWORD_TOO_LONG 3806 + +#define IDT_COMPRESS_ARCHIVE 4001 +#define IDT_COMPRESS_UPDATE_MODE 4002 +#define IDT_COMPRESS_FORMAT 4003 +#define IDT_COMPRESS_LEVEL 4004 +#define IDT_COMPRESS_METHOD 4005 +#define IDT_COMPRESS_DICTIONARY 4006 +#define IDT_COMPRESS_ORDER 4007 +#define IDT_COMPRESS_SOLID 4008 +#define IDT_COMPRESS_THREADS 4009 +#define IDT_COMPRESS_PARAMETERS 4010 +#define IDG_COMPRESS_OPTIONS 4011 + +#define IDX_COMPRESS_SFX 4012 +#define IDX_COMPRESS_SHARED 4013 + +#define IDG_COMPRESS_ENCRYPTION 4014 +#define IDT_COMPRESS_ENCRYPTION_METHOD 4015 +#define IDX_COMPRESS_ENCRYPT_FILE_NAMES 4016 + +#define IDT_COMPRESS_MEMORY 4017 +#define IDT_COMPRESS_MEMORY_DE 4018 + +#define IDX_COMPRESS_DEL 4019 + +#define IDX_COMPRESS_NT_SYM_LINKS 4040 +#define IDX_COMPRESS_NT_HARD_LINKS 4041 +#define IDX_COMPRESS_NT_ALT_STREAMS 4042 +#define IDX_COMPRESS_NT_SECUR 4043 + +#define IDS_METHOD_STORE 4050 +#define IDS_METHOD_FASTEST 4051 +#define IDS_METHOD_FAST 4052 +#define IDS_METHOD_NORMAL 4053 +#define IDS_METHOD_MAXIMUM 4054 +#define IDS_METHOD_ULTRA 4055 + +#define IDS_COMPRESS_UPDATE_MODE_ADD 4060 +#define IDS_COMPRESS_UPDATE_MODE_UPDATE 4061 +#define IDS_COMPRESS_UPDATE_MODE_FRESH 4062 +#define IDS_COMPRESS_UPDATE_MODE_SYNC 4063 + +#define IDS_COMPRESS_SET_ARCHIVE_BROWSE 4070 +#define IDS_OPEN_TYPE_ALL_FILES 4071 +#define IDS_COMPRESS_NON_SOLID 4072 +#define IDS_COMPRESS_SOLID 4073 + +#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 + +#define IDS_MEM_OPERATION_BLOCKED 7810 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressDialog_rc.cpp 2015-01-14 21:01:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,328 +0,0 @@ -// CompressDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "resource2.h" -#include "Windows/Control/DialogImpl.h" - -#include "CompressDialogRes.h" - -class CCompressDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CCompressDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : CModalDialogImpl(dialog,parent, id, wxT("Add to Archive")) - { - wxStaticText *m_pStaticTextMemoryCompress; - wxStaticText *m_pStaticTextMemoryDecompress; - wxTextCtrl *m_pTextCtrlPassword; - wxTextCtrl *m_pTextCtrlRePassword; - wxTextCtrl *m_pTextCtrlParameters; - wxComboBox *m_pComboBoxArchiveName; - wxComboBox *m_pComboBoxArchiveFormat; - wxComboBox *m_pComboBoxCompressionLevel; - wxComboBox *m_pComboBoxCompressionMethod; - wxComboBox *m_pComboBoxDictionarySize; - wxComboBox *m_pComboBoxWordSize; - wxComboBox *m_pComboBoxUpdateMode; - wxComboBox *m_pComboBoxPathMode; - wxComboBox *m_pComboBoxEncryptionMethod; - wxComboBox *m_pComboBoxSplitToVolumes; - wxCheckBox *m_pCheckBoxShowPassword; - wxCheckBox *m_pCheckBoxEncryptFileNames; - wxButton *m_pButtonBrowse; - - - ///Sizer for adding the controls created by users - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - wxStaticText *pStaticTextArchive = new wxStaticText(this, IDT_COMPRESS_ARCHIVE, wxT("&Archive:")); - wxBoxSizer *pArchiveNameSizer = new wxBoxSizer(wxHORIZONTAL); - m_pComboBoxArchiveName = new wxComboBox(this, IDC_COMPRESS_ARCHIVE, wxEmptyString, wxDefaultPosition, wxSize(600,-1), wxArrayString(), wxCB_DROPDOWN|wxCB_SORT); - m_pButtonBrowse = new wxButton(this, IDB_COMPRESS_SET_ARCHIVE, wxT("..."), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - pArchiveNameSizer->Add(m_pComboBoxArchiveName, 1, wxALL|wxEXPAND, 5); - pArchiveNameSizer->Add(m_pButtonBrowse, 0, wxALL|wxEXPAND, 5); - wxBoxSizer *pControlSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pLeftSizer = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer *pCompressionOptionsSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pCompressionStaticSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *pCompressionComboSizer = new wxBoxSizer(wxVERTICAL); - - wxStaticText *pStaticTextArchiveFormat = new wxStaticText(this, IDT_COMPRESS_FORMAT, wxT("Archive &format:")); - /* - wxArrayString archiveFormatArray; - archiveFormatArray.Add(wxT("7z")); - archiveFormatArray.Add(wxT("Tar")); - archiveFormatArray.Add(wxT("Zip")); - m_pComboBoxArchiveFormat = new wxComboBox(this, IDC_COMPRESS_COMBO_FORMAT, archiveFormatArray.Item(0), wxDefaultPosition, wxDefaultSize, archiveFormatArray, wxCB_READONLY); - */ - - m_pComboBoxArchiveFormat = new wxComboBox(this, IDC_COMPRESS_FORMAT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - wxStaticText *pStaticTextCompressionLevel = new wxStaticText(this, IDT_COMPRESS_LEVEL, wxT("Compression &level:")); - wxArrayString compressionLevelArray; - /* - compressionLevelArray.Add(wxT("Store")); - compressionLevelArray.Add(wxT("Fastest")); - compressionLevelArray.Add(wxT("Fast")); - compressionLevelArray.Add(wxT("Normal")); - compressionLevelArray.Add(wxT("Maximum")); - compressionLevelArray.Add(wxT("Ultra")); - m_pComboBoxCompressionLevel = new wxComboBox(this, IDC_COMPRESS_COMBO_LEVEL, compressionLevelArray.Item(0), wxDefaultPosition, wxDefaultSize, compressionLevelArray, wxCB_READONLY); - */ - m_pComboBoxCompressionLevel = new wxComboBox(this, IDC_COMPRESS_LEVEL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - wxStaticText *pStaticTextCompressionMethod = new wxStaticText(this, IDT_COMPRESS_METHOD, wxT("Compression &method:")); -/* - wxArrayString compressionMethodArray; - compressionMethodArray.Add(wxT("LZMA")); - compressionMethodArray.Add(wxT("PPMd")); - compressionMethodArray.Add(wxT("BZip2")); - m_pComboBoxCompressionMethod = new wxComboBox(this, IDC_COMPRESS_COMBO_METHOD, compressionMethodArray.Item(0), wxDefaultPosition, wxDefaultSize, compressionMethodArray, wxCB_READONLY); -*/ - m_pComboBoxCompressionMethod = new wxComboBox(this, IDC_COMPRESS_METHOD, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - wxStaticText *pStaticTextDictionarySize = new wxStaticText(this, IDT_COMPRESS_DICTIONARY, wxT("&Dictionary size:")); -/* - wxArrayString dictionarySizeArray; - dictionarySizeArray.Add(wxT("64 KB")); - dictionarySizeArray.Add(wxT("1 MB")); - dictionarySizeArray.Add(wxT("1 MB")); - dictionarySizeArray.Add(wxT("2 MB")); - dictionarySizeArray.Add(wxT("3 MB")); - dictionarySizeArray.Add(wxT("4 MB")); - dictionarySizeArray.Add(wxT("6 MB")); - dictionarySizeArray.Add(wxT("8 MB")); - dictionarySizeArray.Add(wxT("12 MB")); - dictionarySizeArray.Add(wxT("16 MB")); - dictionarySizeArray.Add(wxT("24 MB")); - dictionarySizeArray.Add(wxT("32 MB")); - dictionarySizeArray.Add(wxT("48 MB")); - dictionarySizeArray.Add(wxT("64 MB")); - dictionarySizeArray.Add(wxT("96 MB")); - dictionarySizeArray.Add(wxT("128 MB")); - m_pComboBoxDictionarySize = new wxComboBox(this, IDC_COMPRESS_COMBO_DICTIONARY, dictionarySizeArray.Item(0), wxDefaultPosition, wxDefaultSize, dictionarySizeArray, wxCB_READONLY); -*/ - m_pComboBoxDictionarySize = new wxComboBox(this, IDC_COMPRESS_DICTIONARY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - wxStaticText *pStaticTextNumberOfThreads = new wxStaticText(this, IDT_COMPRESS_THREADS, wxT("&Number of CPU threads:")); -/* - wxArrayString numberOfThreadsArray; - numberOfThreadsArray.Add(wxT("1")); - numberOfThreadsArray.Add(wxT("2")); - wxComboBox *m_pComboBoxNumberOfThreads = new wxComboBox(this, IDC_COMPRESS_COMBO_THREADS, numberOfThreadsArray.Item(0), wxDefaultPosition, wxDefaultSize, numberOfThreadsArray, wxCB_READONLY); -*/ - wxComboBox *m_pComboBoxNumberOfThreads = new wxComboBox(this, IDC_COMPRESS_THREADS, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - - - - - - wxStaticText *pStaticTextWordSize = new wxStaticText(this, IDT_COMPRESS_ORDER, wxT("&Word size:")); -/* - wxArrayString wordSizeArray; - wordSizeArray.Add(wxT("8")); - wordSizeArray.Add(wxT("12")); - wordSizeArray.Add(wxT("16")); - wordSizeArray.Add(wxT("24")); - wordSizeArray.Add(wxT("32")); - wordSizeArray.Add(wxT("48")); - wordSizeArray.Add(wxT("64")); - wordSizeArray.Add(wxT("96")); - wordSizeArray.Add(wxT("128")); - wordSizeArray.Add(wxT("192")); - wordSizeArray.Add(wxT("256")); - wordSizeArray.Add(wxT("273")); - m_pComboBoxWordSize = new wxComboBox(this, IDC_COMPRESS_COMBO_ORDER, wordSizeArray.Item(0), wxDefaultPosition, wxDefaultSize, wordSizeArray, wxCB_READONLY); -*/ - m_pComboBoxWordSize = new wxComboBox(this, IDC_COMPRESS_ORDER, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - - wxStaticText *pStaticTextBlockSize = new wxStaticText(this, IDT_COMPRESS_SOLID, wxT("&Solid Block size:")); - - wxComboBox *m_pComboBoxBlockSize = new wxComboBox(this, IDC_COMPRESS_SOLID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - pCompressionStaticSizer->Add(pStaticTextArchiveFormat, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextCompressionLevel, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextCompressionMethod, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextDictionarySize, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextWordSize, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextBlockSize, 1, wxALL|wxEXPAND, 5); - pCompressionStaticSizer->Add(pStaticTextNumberOfThreads, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxArchiveFormat, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxCompressionLevel, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxCompressionMethod, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxDictionarySize, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxWordSize, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxBlockSize, 1, wxALL|wxEXPAND, 5); - pCompressionComboSizer->Add(m_pComboBoxNumberOfThreads, 1, wxALL|wxEXPAND, 5); - pCompressionOptionsSizer->Add(pCompressionStaticSizer, 1, wxALL|wxEXPAND, 0); - pCompressionOptionsSizer->Add(pCompressionComboSizer, 1, wxALL|wxEXPAND, 0); - - wxBoxSizer *pMemoryUsageSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *pMemoryUsageLabelSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *pMemoryUsageInfoSizer = new wxBoxSizer(wxVERTICAL); - wxStaticText *pStaticTextCompressMemoryUsage = new wxStaticText(this, IDT_COMPRESS_MEMORY, wxT("Memory usage for Compressing:")); - m_pStaticTextMemoryCompress = new wxStaticText(this, IDT_COMPRESS_MEMORY_VALUE, wxT("709 MB"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - wxStaticText *pStaticTextDecompressMemoryUsage = new wxStaticText(this, IDT_COMPRESS_MEMORY_DE, wxT("Memory usage for Decompressing")); - m_pStaticTextMemoryDecompress = new wxStaticText(this, IDT_COMPRESS_MEMORY_DE_VALUE, wxT("66 MB"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - pMemoryUsageLabelSizer->Add(pStaticTextCompressMemoryUsage, 1, wxALL|wxEXPAND, 5); - pMemoryUsageLabelSizer->Add(pStaticTextDecompressMemoryUsage, 1, wxALL|wxEXPAND, 5); - pMemoryUsageInfoSizer->Add(m_pStaticTextMemoryCompress, 1, wxALL|wxEXPAND, 5); - pMemoryUsageInfoSizer->Add(m_pStaticTextMemoryDecompress, 1, wxALL|wxEXPAND, 5); - pMemoryUsageSizer->Add(pMemoryUsageLabelSizer, 1, wxALL|wxEXPAND, 0); - pMemoryUsageSizer->Add(pMemoryUsageInfoSizer, 0, wxALL|wxEXPAND, 0); - - wxStaticText *pStaticSplit2Volumes = new wxStaticText(this, IDT_SPLIT_TO_VOLUMES, wxT("Split to &volumes, bytes:")); -/* - wxArrayString split2VolumesArray; - split2VolumesArray.Add(wxT("1457664 - 3.5\" floppy")); - split2VolumesArray.Add(wxT("650M - CD")); - split2VolumesArray.Add(wxT("700M - CD")); - split2VolumesArray.Add(wxT("4480M - DVD")); - m_pComboBoxSplitToVolumes = new wxComboBox(this, IDC_COMPRESS_COMBO_VOLUME, wxEmptyString, wxDefaultPosition, wxDefaultSize, split2VolumesArray, wxCB_DROPDOWN); -*/ - m_pComboBoxSplitToVolumes = new wxComboBox(this, IDC_COMPRESS_VOLUME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_DROPDOWN); - - pLeftSizer->Add(pCompressionOptionsSizer, 0, wxALL|wxEXPAND, 0); - pLeftSizer->Add(pMemoryUsageSizer, 1, wxALL|wxEXPAND, 0); - pLeftSizer->Add(pStaticSplit2Volumes, 0, wxALL|wxEXPAND, 5); - pLeftSizer->Add(m_pComboBoxSplitToVolumes, 0, wxALL|wxEXPAND, 5); - - wxBoxSizer *pRightSizer = new wxBoxSizer(wxVERTICAL); - wxStaticText *pStaticTextUpdateMode = new wxStaticText(this, IDT_COMPRESS_UPDATE_MODE, wxT("&Update mode:")); -/* - wxArrayString updateModeArray; - updateModeArray.Add(wxT("Add and replace files")); - updateModeArray.Add(wxT("Update and add files")); - updateModeArray.Add(wxT("Freshen existing files")); - updateModeArray.Add(wxT("Synchronize files")); - m_pComboBoxUpdateMode = new wxComboBox(this, IDC_COMPRESS_COMBO_UPDATE_MODE, updateModeArray.Item(0), wxDefaultPosition, wxDefaultSize, updateModeArray, wxCB_READONLY); -*/ - m_pComboBoxUpdateMode = new wxComboBox(this, IDC_COMPRESS_UPDATE_MODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - - wxStaticText *pStaticTextPathMode = new wxStaticText(this, IDT_COMPRESS_PATH_MODE, wxT("Path mode:")); - m_pComboBoxPathMode = new wxComboBox(this, IDC_COMPRESS_PATH_MODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - - - - wxStaticBoxSizer *pOptionsSizer = new wxStaticBoxSizer(new wxStaticBox(this,IDG_COMPRESS_OPTIONS,_T("Options")),wxVERTICAL); - wxCheckBox *m_pCheckBoxSFXArchive = new wxCheckBox(this, IDX_COMPRESS_SFX, wxT("Create SF&X archive")); - pOptionsSizer->Add(m_pCheckBoxSFXArchive, 1, wxALL|wxEXPAND, 5); - wxCheckBox *m_pCheckBoxCompressSharedFiles = new wxCheckBox(this, IDX_COMPRESS_SHARED, wxT("Compress shared files")); - m_pCheckBoxCompressSharedFiles->Show(false); // this option is useless undex Unix ... - pOptionsSizer->Add(m_pCheckBoxCompressSharedFiles, 1, wxALL|wxEXPAND, 5); - - wxStaticBoxSizer * pEncryptSizer = new wxStaticBoxSizer(new wxStaticBox(this,IDG_COMPRESS_ENCRYPTION,_T("Encryption")),wxVERTICAL); - wxStaticText *pStaticTextPassword = new wxStaticText(this, IDT_PASSWORD_ENTER, wxT("Enter password:")); - m_pTextCtrlPassword = new wxTextCtrl(this, IDE_COMPRESS_PASSWORD1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); - wxStaticText *pStaticTextRePassword = new wxStaticText(this, IDT_PASSWORD_REENTER, wxT("Re-enter password:")); - m_pTextCtrlRePassword = new wxTextCtrl(this, IDE_COMPRESS_PASSWORD2, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); - m_pCheckBoxShowPassword = new wxCheckBox(this, IDX_PASSWORD_SHOW, wxT("Show Password")); - wxBoxSizer *pEncryptionMethodSizer = new wxBoxSizer(wxHORIZONTAL); - wxStaticText *pStaticTextEncryptionMethod = new wxStaticText(this, IDT_COMPRESS_ENCRYPTION_METHOD, wxT("&Encryption method:")); -/* - wxArrayString encryptionMethodArray; - encryptionMethodArray.Add(wxT("AES-256")); - m_pComboBoxEncryptionMethod =new wxComboBox(this, IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, encryptionMethodArray.Item(0), wxDefaultPosition, wxDefaultSize, encryptionMethodArray, wxCB_READONLY); -*/ - m_pComboBoxEncryptionMethod =new wxComboBox(this, IDC_COMPRESS_ENCRYPTION_METHOD, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY); - - pEncryptionMethodSizer->Add(pStaticTextEncryptionMethod, 1, wxALL|wxEXPAND, 5); - pEncryptionMethodSizer->Add(m_pComboBoxEncryptionMethod, 1, wxALL|wxEXPAND, 5); - m_pCheckBoxEncryptFileNames = new wxCheckBox(this, IDX_COMPRESS_ENCRYPT_FILE_NAMES, wxT("Encrypt file &names")); - pEncryptSizer->Add(pStaticTextPassword, 0, wxALL|wxEXPAND, 5); - pEncryptSizer->Add(m_pTextCtrlPassword, 0, wxLEFT|wxRIGHT|wxEXPAND, 5); - pEncryptSizer->Add(pStaticTextRePassword, 0, wxALL|wxEXPAND, 5); - pEncryptSizer->Add(m_pTextCtrlRePassword, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5); - pEncryptSizer->Add(m_pCheckBoxShowPassword, 0, wxALL|wxEXPAND, 5); - pEncryptSizer->Add(pEncryptionMethodSizer, 0, wxLEFT|wxRIGHT|wxEXPAND, 0); - pEncryptSizer->Add(m_pCheckBoxEncryptFileNames, 0, wxALL|wxEXPAND, 5); - - pRightSizer->Add(pStaticTextUpdateMode, 0, wxALL|wxEXPAND, 5); - pRightSizer->Add(m_pComboBoxUpdateMode, 0, wxALL|wxEXPAND, 5); - - pRightSizer->Add(pStaticTextPathMode, 0, wxALL|wxEXPAND, 5); - pRightSizer->Add(m_pComboBoxPathMode, 0, wxALL|wxEXPAND, 5); - - pRightSizer->Add(pOptionsSizer, 1, wxALL|wxEXPAND, 5); - pRightSizer->Add(pEncryptSizer, 0, wxALL|wxEXPAND, 5); - - pControlSizer->Add(pLeftSizer, 1, wxALL|wxEXPAND, 5); - pControlSizer->Add(pRightSizer, 1, wxALL|wxEXPAND, 5); - wxStaticText *pStaticTextParameters = new wxStaticText(this, IDT_COMPRESS_PARAMETERS, wxT("&Parameters:")); - m_pTextCtrlParameters = new wxTextCtrl(this, IDE_COMPRESS_PARAMETERS, wxEmptyString); - topsizer->Add(pStaticTextArchive, 0, wxLEFT | wxRIGHT | wxTOP |wxEXPAND, 10); - topsizer->Add(pArchiveNameSizer, 1, wxLEFT | wxRIGHT |wxEXPAND, 5); - topsizer->Add(pControlSizer, 0, wxALL|wxEXPAND, 5); - topsizer->Add(pStaticTextParameters, 0, wxLEFT | wxRIGHT | wxBOTTOM |wxEXPAND, 10); - topsizer->Add(m_pTextCtrlParameters, 0, wxLEFT | wxRIGHT |wxEXPAND, 10); - topsizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxHELP), 0, wxALL|wxEXPAND, 10); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -static CStringTable g_stringTable[] = -{ - { IDS_PASSWORD_NOT_MATCH ,L"Passwords do not match" }, - { IDS_PASSWORD_USE_ASCII ,L"Use only English letters, numbers and special characters (!, #, $, ...) for password." }, - { IDS_PASSWORD_TOO_LONG ,L"Password is too long" }, - - { IDS_METHOD_STORE ,L"Store" }, - { IDS_METHOD_FASTEST ,L"Fastest" }, - { IDS_METHOD_FAST ,L"Fast" }, - { IDS_METHOD_NORMAL ,L"Normal" }, - { IDS_METHOD_MAXIMUM ,L"Maximum" }, - { IDS_METHOD_ULTRA ,L"Ultra" }, - - { IDS_COMPRESS_UPDATE_MODE_ADD ,L"Add and replace files" }, - { IDS_COMPRESS_UPDATE_MODE_UPDATE ,L"Update and add files" }, - { IDS_COMPRESS_UPDATE_MODE_FRESH ,L"Freshen existing files" }, - { IDS_COMPRESS_UPDATE_MODE_SYNC ,L"Synchronize files" }, - - { IDS_OPEN_TYPE_ALL_FILES ,L"All Files" }, - { IDS_COMPRESS_SET_ARCHIVE_BROWSE ,L"Browse" }, - - { IDS_COMPRESS_NON_SOLID ,L"Non-solid" }, - { IDS_COMPRESS_SOLID ,L"Solid" }, - - { IDS_SPLIT_CONFIRM ,L"Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?" }, - - - { 0 , 0 } -}; - -REGISTER_DIALOG(IDD_COMPRESS,CCompressDialog,g_stringTable) - -BEGIN_EVENT_TABLE(CCompressDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_COMBOBOX(wxID_ANY, CModalDialogImpl::OnAnyChoice) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressOptionsDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressOptionsDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/CompressOptionsDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/CompressOptionsDialog.rc 2024-03-16 07:00:00.000000000 +0000 @@ -0,0 +1,79 @@ +#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) + + +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 + + MY_CONTROL_CHECKBOX ("Store symbolic links", IDX_COMPRESS_NT_SYM_LINKS, + ntPosX, ntPosY + 12, ntSizeX) + MY_CONTROL_CHECKBOX ("Store hard links", IDX_COMPRESS_NT_HARD_LINKS, + ntPosX, ntPosY + 26, ntSizeX) + MY_CONTROL_CHECKBOX ("Store alternate data streams", IDX_COMPRESS_NT_ALT_STREAMS, + ntPosX, ntPosY + 40, ntSizeX) + MY_CONTROL_CHECKBOX ("Store file security", IDX_COMPRESS_NT_SECUR, + ntPosX, ntPosY + 54, ntSizeX) + + LTEXT "", IDT_COMPRESS_TIME_INFO, g5x, timePosY - 14, g5xs, 8 + + + GROUPBOX "Time", IDG_COMPRESS_TIME, g5x, timePosY, g5xs, 112 + +// MY_CONTROL_CHECKBOX ("Default", IDX_COMPRESS_TIME_DEFAULT, +// ntPosX, timePosY + 10, ntSizeX) + + MY_CONTROL_CHECKBOX_COLON (IDX_COMPRESS_PREC_SET, ntPosX, timePosY + 14) + LTEXT "Timestamp precision:", IDT_COMPRESS_TIME_PREC, + ntPosX + cboxColonSize, timePosY + 14, ntSizeX - precSizeX - cboxColonSize, 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 + + MY_CONTROL_CHECKBOX_COLON (IDX_COMPRESS_MTIME_SET, ntPosX, timePosY + 28) + MY_CONTROL_CHECKBOX ("Store modification time", IDX_COMPRESS_MTIME, + ntPosX + cboxColonSize, timePosY + 28, ntSizeX - cboxColonSize) + + MY_CONTROL_CHECKBOX_COLON (IDX_COMPRESS_CTIME_SET, ntPosX, timePosY + 42) + MY_CONTROL_CHECKBOX ("Store creation time", IDX_COMPRESS_CTIME, + ntPosX + cboxColonSize, timePosY + 42, ntSizeX - cboxColonSize) + + MY_CONTROL_CHECKBOX_COLON (IDX_COMPRESS_ATIME_SET, ntPosX, timePosY + 56) + MY_CONTROL_CHECKBOX ("Store last access time", IDX_COMPRESS_ATIME, + ntPosX + cboxColonSize, timePosY + 56, ntSizeX - cboxColonSize) + + MY_CONTROL_CHECKBOX_2LINES(colonString, + IDX_COMPRESS_ZTIME_SET, + ntPosX, timePosY + 72, cboxColonSize) + MY_CONTROL_CHECKBOX_2LINES( + "Set archive time to latest file time", + IDX_COMPRESS_ZTIME, + ntPosX + cboxColonSize, timePosY + 72, ntSizeX - cboxColonSize) + + MY_CONTROL_CHECKBOX_2LINES( + "Do not change source files last access time", + IDX_COMPRESS_PRESERVE_ATIME, + ntPosX, timePosY + 92, ntSizeX) + + + 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 -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/Extract.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/Extract.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/Extract.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/Extract.rc 2020-09-29 09:22:00.000000000 +0000 @@ -0,0 +1,59 @@ +#include "ExtractRes.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_MEM_ERROR "The system cannot allocate the required amount of memory" + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_UPDATE_NOT_SUPPORTED "Update operations are not supported for this archive." + IDS_CANT_OPEN_ARCHIVE "Cannot open file '{0}' as archive" + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Cannot open encrypted archive '{0}'. Wrong password?" + IDS_UNSUPPORTED_ARCHIVE_TYPE "Unsupported archive type" + + IDS_CANT_OPEN_AS_TYPE "Cannot open the file as {0} archive" + IDS_IS_OPEN_AS_TYPE "The file is open as {0} archive" + IDS_IS_OPEN_WITH_OFFSET "The archive is open with offset" + + IDS_PROGRESS_EXTRACTING "Extracting" + + IDS_PROGRESS_SKIPPING "Skipping" + + IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files." + + IDS_EXTRACT_PATHS_FULL "Full pathnames" + IDS_EXTRACT_PATHS_NO "No pathnames" + IDS_EXTRACT_PATHS_ABS "Absolute pathnames" + IDS_PATH_MODE_RELAT "Relative pathnames" + + IDS_EXTRACT_OVERWRITE_ASK "Ask before overwrite" + IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT "Overwrite without prompt" + IDS_EXTRACT_OVERWRITE_SKIP_EXISTING "Skip existing files" + IDS_EXTRACT_OVERWRITE_RENAME "Auto rename" + IDS_EXTRACT_OVERWRITE_RENAME_EXISTING "Auto rename existing files" + + IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD "Unsupported compression method for '{0}'." + IDS_EXTRACT_MESSAGE_DATA_ERROR "Data error in '{0}'. File is broken" + IDS_EXTRACT_MESSAGE_CRC_ERROR "CRC failed in '{0}'. File is broken." + IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED "Data error in encrypted file '{0}'. Wrong password?" + IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED "CRC failed in encrypted file '{0}'. Wrong password?" + + IDS_EXTRACT_MSG_WRONG_PSW_GUESS "Wrong password?" + // IDS_EXTRACT_MSG_ENCRYPTED "Encrypted file" + + IDS_EXTRACT_MSG_UNSUPPORTED_METHOD "Unsupported compression method" + IDS_EXTRACT_MSG_DATA_ERROR "Data error" + IDS_EXTRACT_MSG_CRC_ERROR "CRC failed" + IDS_EXTRACT_MSG_UNAVAILABLE_DATA "Unavailable data" + IDS_EXTRACT_MSG_UEXPECTED_END "Unexpected end of data" + IDS_EXTRACT_MSG_DATA_AFTER_END "There are some data after the end of the payload data" + IDS_EXTRACT_MSG_IS_NOT_ARC "Is not archive" + IDS_EXTRACT_MSG_HEADERS_ERROR "Headers Error" + IDS_EXTRACT_MSG_WRONG_PSW_CLAIM "Wrong password" + + IDS_OPEN_MSG_UNAVAILABLE_START "Unavailable start of archive" + IDS_OPEN_MSG_UNCONFIRMED_START "Unconfirmed start of archive" + // IDS_OPEN_MSG_ERROR_FLAGS + 5 "Unexpected end of archive" + // IDS_OPEN_MSG_ERROR_FLAGS + 6 "There are data after the end of archive" + IDS_OPEN_MSG_UNSUPPORTED_FEATURE "Unsupported feature" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.cpp 2015-10-03 17:44:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.cpp 2023-03-19 17:00:00.000000000 +0000 @@ -1,420 +1,421 @@ -// ExtractDialog.cpp - -#include "StdAfx.h" - -#include "../../../Common/StringConvert.h" -#include "../../../Common/Wildcard.h" - -#include "../../../Windows/FileName.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/ResourceString.h" - -#ifndef NO_REGISTRY -#include "../FileManager/HelpUtils.h" -#endif - - -#include "../FileManager/BrowseDialog.h" -#include "../FileManager/LangUtils.h" -#include "../FileManager/resourceGui.h" - -#include "ExtractDialog.h" -#include "ExtractDialogRes.h" -#include "ExtractRes.h" - -using namespace NWindows; -using namespace NFile; -using namespace NName; - -extern HINSTANCE g_hInstance; - -static const UInt32 kPathMode_IDs[] = -{ - IDS_EXTRACT_PATHS_FULL, - IDS_EXTRACT_PATHS_NO, - IDS_EXTRACT_PATHS_ABS -}; - -static const UInt32 kOverwriteMode_IDs[] = -{ - IDS_EXTRACT_OVERWRITE_ASK, - IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT, - IDS_EXTRACT_OVERWRITE_SKIP_EXISTING, - IDS_EXTRACT_OVERWRITE_RENAME, - IDS_EXTRACT_OVERWRITE_RENAME_EXISTING -}; - -#ifndef _SFX - -static const - // NExtract::NPathMode::EEnum - int - kPathModeButtonsVals[] = -{ - NExtract::NPathMode::kFullPaths, - NExtract::NPathMode::kNoPaths, - NExtract::NPathMode::kAbsPaths -}; - -static const - int - // NExtract::NOverwriteMode::EEnum - kOverwriteButtonsVals[] = -{ - NExtract::NOverwriteMode::kAsk, - NExtract::NOverwriteMode::kOverwrite, - NExtract::NOverwriteMode::kSkip, - NExtract::NOverwriteMode::kRename, - NExtract::NOverwriteMode::kRenameExisting -}; - -#endif - -#ifdef LANG - -static const UInt32 kLangIDs[] = -{ - IDT_EXTRACT_EXTRACT_TO, - IDT_EXTRACT_PATH_MODE, - IDT_EXTRACT_OVERWRITE_MODE, - // IDX_EXTRACT_ALT_STREAMS, - IDX_EXTRACT_NT_SECUR, - IDX_EXTRACT_ELIM_DUP, - IDG_PASSWORD, - IDX_PASSWORD_SHOW -}; -#endif - -// static const int kWildcardsButtonIndex = 2; - -#ifndef NO_REGISTRY -static const unsigned kHistorySize = 16; -#endif - -#ifndef _SFX - -// it's used in CompressDialog also -void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal) -{ - int curSel = 0; - for (unsigned i = 0; i < numItems; i++) - { - UString s = LangString(langIDs[i]); - s.RemoveChar(L'&'); - int index = (int)combo.AddString(s); - combo.SetItemData(index, i); - if (values[i] == curVal) - curSel = i; - } - combo.SetCurSel(curSel); -} - -// it's used in CompressDialog also -bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2) -{ - if (b1.Def) return b1.Val; - if (b2.Def) return b2.Val; - return b1.Val; -} - -void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2) -{ - CheckButton(id, GetBoolsVal(b1, b2)); -} - -void CExtractDialog::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; -} - -#endif - -bool CExtractDialog::OnInit() -{ - #ifdef LANG - { - UString s; - LangString_OnlyFromLangFile(IDD_EXTRACT, s); - if (s.IsEmpty()) - GetText(s); - if (!ArcPath.IsEmpty()) - { - s.AddAscii(" : "); - s += ArcPath; - } - SetText(s); - // LangSetWindowText(*this, IDD_EXTRACT); - LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); - } - #endif - - #ifndef _SFX - _passwordControl.Attach(GetItem(IDE_EXTRACT_PASSWORD)); - _passwordControl.SetText(Password); - _passwordControl.SetPasswordChar(TEXT('*')); - _pathName.Attach(GetItem(IDE_EXTRACT_NAME)); - #endif - - #ifdef NO_REGISTRY - - PathMode = NExtract::NPathMode::kFullPaths; - OverwriteMode = NExtract::NOverwriteMode::kAsk; - - #else - - _info.Load(); - - if (_info.PathMode == NExtract::NPathMode::kCurPaths) - _info.PathMode = NExtract::NPathMode::kFullPaths; - - if (!PathMode_Force && _info.PathMode_Force) - PathMode = _info.PathMode; - if (!OverwriteMode_Force && _info.OverwriteMode_Force) - OverwriteMode = _info.OverwriteMode; - - // CheckButton_TwoBools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams); - CheckButton_TwoBools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity); - CheckButton_TwoBools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup); - - CheckButton(IDX_PASSWORD_SHOW, _info.ShowPassword.Val); - UpdatePasswordControl(); - - #endif - - _path.Attach(GetItem(IDC_EXTRACT_PATH)); - - UString pathPrefix = DirPath; - - #ifndef _SFX - - if (_info.SplitDest.Val) - { - CheckButton(IDX_EXTRACT_NAME_ENABLE, true); - UString pathName; - SplitPathToParts_Smart(DirPath, pathPrefix, pathName); - if (pathPrefix.IsEmpty()) - pathPrefix = pathName; - else - _pathName.SetText(pathName); - } - else - ShowItem_Bool(IDE_EXTRACT_NAME, false); - - #endif - - _path.SetText(pathPrefix); - - #ifndef NO_REGISTRY - for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++) - _path.AddString(_info.Paths[i]); - #endif - - /* - if (_info.Paths.Size() > 0) - _path.SetCurSel(0); - else - _path.SetCurSel(-1); - */ - - #ifndef _SFX - - _pathMode.Attach(GetItem(IDC_EXTRACT_PATH_MODE)); - _overwriteMode.Attach(GetItem(IDC_EXTRACT_OVERWRITE_MODE)); - - AddComboItems(_pathMode, kPathMode_IDs, ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode); - AddComboItems(_overwriteMode, kOverwriteMode_IDs, ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode); - - #endif - -#ifdef _WIN32 - HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON)); - SetIcon(ICON_BIG, icon); -#endif - - // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); - // filesWindow.Enable(_enableFilesButton); - - NormalizePosition(); - - return CModalDialog::OnInit(); -} - -#ifndef _SFX -void CExtractDialog::UpdatePasswordControl() -{ - _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*')); - UString password; - _passwordControl.GetText(password); - _passwordControl.SetText(password); -} -#endif - -bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch (buttonID) - { - case IDB_EXTRACT_SET_PATH: - OnButtonSetPath(); - return true; - #ifndef _SFX - case IDX_EXTRACT_NAME_ENABLE: - ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE)); - return true; - case IDX_PASSWORD_SHOW: - { - UpdatePasswordControl(); - return true; - } - #endif - } - return CModalDialog::OnButtonClicked(buttonID, buttonHWND); -} - -void CExtractDialog::OnButtonSetPath() -{ - UString currentPath; - _path.GetText(currentPath); - UString title = LangString(IDS_EXTRACT_SET_FOLDER); - UString resultPath; - if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) - return; - #ifndef NO_REGISTRY - _path.SetCurSel(-1); - #endif - _path.SetText(resultPath); -} - -void AddUniqueString(UStringVector &list, const UString &s) -{ - FOR_VECTOR (i, list) - if (s.IsEqualTo_NoCase(list[i])) - return; - list.Add(s); -} - -void CExtractDialog::OnOK() -{ - #ifndef _SFX - int pathMode2 = kPathModeButtonsVals[_pathMode.GetCurSel()]; - if (PathMode != NExtract::NPathMode::kCurPaths || - pathMode2 != NExtract::NPathMode::kFullPaths) - PathMode = (NExtract::NPathMode::EEnum)pathMode2; - - OverwriteMode = (NExtract::NOverwriteMode::EEnum)kOverwriteButtonsVals[_overwriteMode.GetCurSel()]; - - // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode(); - - _passwordControl.GetText(Password); - - #endif - - #ifndef NO_REGISTRY - - // GetButton_Bools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams); - GetButton_Bools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity); - GetButton_Bools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup); - - bool showPassword = IsShowPasswordChecked(); - if (showPassword != _info.ShowPassword.Val) - { - _info.ShowPassword.Def = true; - _info.ShowPassword.Val = showPassword; - } - - if (_info.PathMode != pathMode2) - { - _info.PathMode_Force = true; - _info.PathMode = (NExtract::NPathMode::EEnum)pathMode2; - /* - // we allow kAbsPaths in registry. - if (_info.PathMode == NExtract::NPathMode::kAbsPaths) - _info.PathMode = NExtract::NPathMode::kFullPaths; - */ - } - - if (!OverwriteMode_Force && _info.OverwriteMode != OverwriteMode) - _info.OverwriteMode_Force = true; - _info.OverwriteMode = OverwriteMode; - - - #else - - ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP); - - #endif - - UString s; - - #ifdef NO_REGISTRY - - _path.GetText(s); - - #else - - int currentItem = _path.GetCurSel(); - if (currentItem == CB_ERR) - { - _path.GetText(s); - if (_path.GetCount() >= kHistorySize) - currentItem = _path.GetCount() - 1; - } - else - _path.GetLBText(currentItem, s); - - #endif - - s.Trim(); - NName::NormalizeDirPathPrefix(s); - - #ifndef _SFX - - bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE); - if (splitDest) - { - UString pathName; - _pathName.GetText(pathName); - pathName.Trim(); - s += pathName; - NName::NormalizeDirPathPrefix(s); - } - if (splitDest != _info.SplitDest.Val) - { - _info.SplitDest.Def = true; - _info.SplitDest.Val = splitDest; - } - - #endif - - DirPath = s; - - #ifndef NO_REGISTRY - _info.Paths.Clear(); - #ifndef _SFX - AddUniqueString(_info.Paths, s); - #endif - for (int i = 0; i < _path.GetCount(); i++) - if (i != currentItem) - { - UString sTemp; - _path.GetLBText(i, sTemp); - sTemp.Trim(); - AddUniqueString(_info.Paths, sTemp); - } - _info.Save(); - #endif - - CModalDialog::OnOK(); -} - -#ifndef NO_REGISTRY -static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm"; -void CExtractDialog::OnHelp() -{ - ShowHelpWindow(NULL, kHelpTopic); - CModalDialog::OnHelp(); -} -#endif +// ExtractDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringConvert.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/ResourceString.h" + +#ifndef Z7_NO_REGISTRY +#include "../FileManager/HelpUtils.h" +#endif + + +#include "../FileManager/BrowseDialog.h" +#include "../FileManager/LangUtils.h" +#include "../FileManager/resourceGui.h" + +#include "ExtractDialog.h" +#include "ExtractDialogRes.h" +#include "ExtractRes.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +extern HINSTANCE g_hInstance; + +#ifndef Z7_SFX + +static const UInt32 kPathMode_IDs[] = +{ + IDS_EXTRACT_PATHS_FULL, + IDS_EXTRACT_PATHS_NO, + IDS_EXTRACT_PATHS_ABS +}; + +static const UInt32 kOverwriteMode_IDs[] = +{ + IDS_EXTRACT_OVERWRITE_ASK, + IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT, + IDS_EXTRACT_OVERWRITE_SKIP_EXISTING, + IDS_EXTRACT_OVERWRITE_RENAME, + IDS_EXTRACT_OVERWRITE_RENAME_EXISTING +}; + +static const + // NExtract::NPathMode::EEnum + int + kPathModeButtonsVals[] = +{ + NExtract::NPathMode::kFullPaths, + NExtract::NPathMode::kNoPaths, + NExtract::NPathMode::kAbsPaths +}; + +static const + int + // NExtract::NOverwriteMode::EEnum + kOverwriteButtonsVals[] = +{ + NExtract::NOverwriteMode::kAsk, + NExtract::NOverwriteMode::kOverwrite, + NExtract::NOverwriteMode::kSkip, + NExtract::NOverwriteMode::kRename, + NExtract::NOverwriteMode::kRenameExisting +}; + +#endif + +#ifdef Z7_LANG + +static const UInt32 kLangIDs[] = +{ + IDT_EXTRACT_EXTRACT_TO, + IDT_EXTRACT_PATH_MODE, + IDT_EXTRACT_OVERWRITE_MODE, + // IDX_EXTRACT_ALT_STREAMS, + IDX_EXTRACT_NT_SECUR, + IDX_EXTRACT_ELIM_DUP, + IDG_PASSWORD, + IDX_PASSWORD_SHOW +}; +#endif + +// static const int kWildcardsButtonIndex = 2; + +#ifndef Z7_NO_REGISTRY +static const unsigned kHistorySize = 16; +#endif + +#ifndef Z7_SFX + +// it's used in CompressDialog also +void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal); +void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal) +{ + unsigned curSel = 0; + for (unsigned i = 0; i < numItems; i++) + { + UString s = LangString(langIDs[i]); + s.RemoveChar(L'&'); + const int index = (int)combo.AddString(s); + combo.SetItemData(index, (LPARAM)i); + if (values[i] == curVal) + curSel = i; + } + combo.SetCurSel(curSel); +} + +// it's used in CompressDialog also +bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2); +bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2) +{ + if (b1.Def) return b1.Val; + if (b2.Def) return b2.Val; + return b1.Val; +} + +void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2) +{ + CheckButton(id, GetBoolsVal(b1, b2)); +} + +void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2) +{ + const bool val = IsButtonCheckedBool(id); + const bool oldVal = GetBoolsVal(b1, b2); + if (val != oldVal) + b1.Def = b2.Def = true; + b1.Val = b2.Val = val; +} + +#endif + +bool CExtractDialog::OnInit() +{ + #ifdef Z7_LANG + { + UString s; + LangString_OnlyFromLangFile(IDD_EXTRACT, s); + if (s.IsEmpty()) + GetText(s); + if (!ArcPath.IsEmpty()) + { + s += " : "; + s += ArcPath; + } + SetText(s); + // LangSetWindowText(*this, IDD_EXTRACT); + LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); + } + #endif + + #ifndef Z7_SFX + _passwordControl.Attach(GetItem(IDE_EXTRACT_PASSWORD)); + _passwordControl.SetText(Password); + _passwordControl.SetPasswordChar(TEXT('*')); + _pathName.Attach(GetItem(IDE_EXTRACT_NAME)); + #endif + + #ifdef Z7_NO_REGISTRY + + PathMode = NExtract::NPathMode::kFullPaths; + OverwriteMode = NExtract::NOverwriteMode::kAsk; + + #else + + _info.Load(); + + if (_info.PathMode == NExtract::NPathMode::kCurPaths) + _info.PathMode = NExtract::NPathMode::kFullPaths; + + if (!PathMode_Force && _info.PathMode_Force) + PathMode = _info.PathMode; + if (!OverwriteMode_Force && _info.OverwriteMode_Force) + OverwriteMode = _info.OverwriteMode; + + // CheckButton_TwoBools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams); + CheckButton_TwoBools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity); + CheckButton_TwoBools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup); + + CheckButton(IDX_PASSWORD_SHOW, _info.ShowPassword.Val); + UpdatePasswordControl(); + + #endif + + _path.Attach(GetItem(IDC_EXTRACT_PATH)); + + UString pathPrefix = DirPath; + + #ifndef Z7_SFX + + if (_info.SplitDest.Val) + { + CheckButton(IDX_EXTRACT_NAME_ENABLE, true); + UString pathName; + SplitPathToParts_Smart(DirPath, pathPrefix, pathName); + if (pathPrefix.IsEmpty()) + pathPrefix = pathName; + else + _pathName.SetText(pathName); + } + else + ShowItem_Bool(IDE_EXTRACT_NAME, false); + + #endif + + _path.SetText(pathPrefix); + + #ifndef Z7_NO_REGISTRY + for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++) + _path.AddString(_info.Paths[i]); + #endif + + /* + if (_info.Paths.Size() > 0) + _path.SetCurSel(0); + else + _path.SetCurSel(-1); + */ + + #ifndef Z7_SFX + + _pathMode.Attach(GetItem(IDC_EXTRACT_PATH_MODE)); + _overwriteMode.Attach(GetItem(IDC_EXTRACT_OVERWRITE_MODE)); + + AddComboItems(_pathMode, kPathMode_IDs, Z7_ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode); + AddComboItems(_overwriteMode, kOverwriteMode_IDs, Z7_ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode); + + #endif + + HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON)); + SetIcon(ICON_BIG, icon); + + // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); + // filesWindow.Enable(_enableFilesButton); + + NormalizePosition(); + + return CModalDialog::OnInit(); +} + +#ifndef Z7_SFX +void CExtractDialog::UpdatePasswordControl() +{ + _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*')); + UString password; + _passwordControl.GetText(password); + _passwordControl.SetText(password); +} +#endif + +bool CExtractDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_EXTRACT_SET_PATH: + OnButtonSetPath(); + return true; + #ifndef Z7_SFX + case IDX_EXTRACT_NAME_ENABLE: + ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE)); + return true; + case IDX_PASSWORD_SHOW: + { + UpdatePasswordControl(); + return true; + } + #endif + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CExtractDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + UString title = LangString(IDS_EXTRACT_SET_FOLDER); + UString resultPath; + if (!MyBrowseForFolder(*this, title, currentPath, resultPath)) + return; + #ifndef Z7_NO_REGISTRY + _path.SetCurSel(-1); + #endif + _path.SetText(resultPath); +} + +void AddUniqueString(UStringVector &list, const UString &s); +void AddUniqueString(UStringVector &list, const UString &s) +{ + FOR_VECTOR (i, list) + if (s.IsEqualTo_NoCase(list[i])) + return; + list.Add(s); +} + +void CExtractDialog::OnOK() +{ + #ifndef Z7_SFX + int pathMode2 = kPathModeButtonsVals[_pathMode.GetCurSel()]; + if (PathMode != NExtract::NPathMode::kCurPaths || + pathMode2 != NExtract::NPathMode::kFullPaths) + PathMode = (NExtract::NPathMode::EEnum)pathMode2; + + OverwriteMode = (NExtract::NOverwriteMode::EEnum)kOverwriteButtonsVals[_overwriteMode.GetCurSel()]; + + // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode(); + + _passwordControl.GetText(Password); + + #endif + + #ifndef Z7_NO_REGISTRY + + // GetButton_Bools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams); + GetButton_Bools(IDX_EXTRACT_NT_SECUR, NtSecurity, _info.NtSecurity); + GetButton_Bools(IDX_EXTRACT_ELIM_DUP, ElimDup, _info.ElimDup); + + bool showPassword = IsShowPasswordChecked(); + if (showPassword != _info.ShowPassword.Val) + { + _info.ShowPassword.Def = true; + _info.ShowPassword.Val = showPassword; + } + + if (_info.PathMode != pathMode2) + { + _info.PathMode_Force = true; + _info.PathMode = (NExtract::NPathMode::EEnum)pathMode2; + /* + // we allow kAbsPaths in registry. + if (_info.PathMode == NExtract::NPathMode::kAbsPaths) + _info.PathMode = NExtract::NPathMode::kFullPaths; + */ + } + + if (!OverwriteMode_Force && _info.OverwriteMode != OverwriteMode) + _info.OverwriteMode_Force = true; + _info.OverwriteMode = OverwriteMode; + + + #else + + ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP); + + #endif + + UString s; + + #ifdef Z7_NO_REGISTRY + + _path.GetText(s); + + #else + + int currentItem = _path.GetCurSel(); + if (currentItem == CB_ERR) + { + _path.GetText(s); + if (_path.GetCount() >= (int)kHistorySize) + currentItem = _path.GetCount() - 1; + } + else + _path.GetLBText(currentItem, s); + + #endif + + s.Trim(); + NName::NormalizeDirPathPrefix(s); + + #ifndef Z7_SFX + + const bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE); + if (splitDest) + { + UString pathName; + _pathName.GetText(pathName); + pathName.Trim(); + s += pathName; + NName::NormalizeDirPathPrefix(s); + } + if (splitDest != _info.SplitDest.Val) + { + _info.SplitDest.Def = true; + _info.SplitDest.Val = splitDest; + } + + #endif + + DirPath = s; + + #ifndef Z7_NO_REGISTRY + _info.Paths.Clear(); + #ifndef Z7_SFX + AddUniqueString(_info.Paths, s); + #endif + for (int i = 0; i < _path.GetCount(); i++) + if (i != currentItem) + { + UString sTemp; + _path.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(_info.Paths, sTemp); + } + _info.Save(); + #endif + + CModalDialog::OnOK(); +} + +#ifndef Z7_NO_REGISTRY +#define kHelpTopic "fm/plugins/7-zip/extract.htm" +void CExtractDialog::OnHelp() +{ + ShowHelpWindow(kHelpTopic); + CModalDialog::OnHelp(); +} +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.h 2023-01-29 16:00:00.000000000 +0000 @@ -1,113 +1,113 @@ -// ExtractDialog.h - -#ifndef __EXTRACT_DIALOG_H -#define __EXTRACT_DIALOG_H - -#include "ExtractDialogRes.h" - -#include "../../../Windows/Control/ComboBox.h" -#include "../../../Windows/Control/Edit.h" - -#include "../Common/ExtractMode.h" - -#include "../FileManager/DialogSize.h" - -#ifndef NO_REGISTRY -#include "../Common/ZipRegistry.h" -#endif - -namespace NExtractionDialog -{ - /* - namespace NFilesMode - { - enum EEnum - { - kSelected, - kAll, - kSpecified - }; - } - */ -} - -class CExtractDialog: public NWindows::NControl::CModalDialog -{ - #ifdef NO_REGISTRY - NWindows::NControl::CDialogChildControl _path; - #else - NWindows::NControl::CComboBox _path; - #endif - - #ifndef _SFX - NWindows::NControl::CEdit _pathName; - NWindows::NControl::CEdit _passwordControl; - NWindows::NControl::CComboBox _pathMode; - NWindows::NControl::CComboBox _overwriteMode; - #endif - - #ifndef _SFX - // int GetFilesMode() const; - void UpdatePasswordControl(); - #endif - - void OnButtonSetPath(); - - void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2); - void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2); - virtual bool OnInit(); - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - virtual void OnOK(); - - #ifndef NO_REGISTRY - - virtual void OnHelp(); - - NExtract::CInfo _info; - - #endif - - bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); } -public: - // bool _enableSelectedFilesButton; - // bool _enableFilesButton; - // NExtractionDialog::NFilesMode::EEnum FilesMode; - - UString DirPath; - UString ArcPath; - - #ifndef _SFX - UString Password; - #endif - bool PathMode_Force; - bool OverwriteMode_Force; - NExtract::NPathMode::EEnum PathMode; - NExtract::NOverwriteMode::EEnum OverwriteMode; - - #ifndef _SFX - // CBoolPair AltStreams; - CBoolPair NtSecurity; - #endif - - CBoolPair ElimDup; - - INT_PTR Create(HWND aWndParent = 0) - { - #ifdef _SFX - BIG_DIALOG_SIZE(240, 64); - #else - BIG_DIALOG_SIZE(300, 160); - #endif - return CModalDialog::Create(SIZED_DIALOG(IDD_EXTRACT), aWndParent); - } - - CExtractDialog(): - PathMode_Force(false), - OverwriteMode_Force(false) - { - ElimDup.Val = true; - } - -}; - -#endif +// ExtractDialog.h + +#ifndef ZIP7_INC_EXTRACT_DIALOG_H +#define ZIP7_INC_EXTRACT_DIALOG_H + +#include "ExtractDialogRes.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Edit.h" + +#include "../Common/ExtractMode.h" + +#include "../FileManager/DialogSize.h" + +#ifndef Z7_NO_REGISTRY +#include "../Common/ZipRegistry.h" +#endif + +namespace NExtractionDialog +{ + /* + namespace NFilesMode + { + enum EEnum + { + kSelected, + kAll, + kSpecified + }; + } + */ +} + +class CExtractDialog: public NWindows::NControl::CModalDialog +{ + #ifdef Z7_NO_REGISTRY + NWindows::NControl::CDialogChildControl _path; + #else + NWindows::NControl::CComboBox _path; + #endif + + #ifndef Z7_SFX + NWindows::NControl::CEdit _pathName; + NWindows::NControl::CEdit _passwordControl; + NWindows::NControl::CComboBox _pathMode; + NWindows::NControl::CComboBox _overwriteMode; + #endif + + #ifndef Z7_SFX + // int GetFilesMode() const; + void UpdatePasswordControl(); + #endif + + void OnButtonSetPath(); + + void CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2); + void GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2); + virtual bool OnInit() Z7_override; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override; + virtual void OnOK() Z7_override; + + #ifndef Z7_NO_REGISTRY + + virtual void OnHelp() Z7_override; + + NExtract::CInfo _info; + + #endif + + bool IsShowPasswordChecked() const { return IsButtonCheckedBool(IDX_PASSWORD_SHOW); } +public: + // bool _enableSelectedFilesButton; + // bool _enableFilesButton; + // NExtractionDialog::NFilesMode::EEnum FilesMode; + + UString DirPath; + UString ArcPath; + + #ifndef Z7_SFX + UString Password; + #endif + bool PathMode_Force; + bool OverwriteMode_Force; + NExtract::NPathMode::EEnum PathMode; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + #ifndef Z7_SFX + // CBoolPair AltStreams; + CBoolPair NtSecurity; + #endif + + CBoolPair ElimDup; + + INT_PTR Create(HWND aWndParent = NULL) + { + #ifdef Z7_SFX + BIG_DIALOG_SIZE(240, 64); + #else + BIG_DIALOG_SIZE(300, 160); + #endif + return CModalDialog::Create(SIZED_DIALOG(IDD_EXTRACT), aWndParent); + } + + CExtractDialog(): + PathMode_Force(false), + OverwriteMode_Force(false) + { + ElimDup.Val = true; + } + +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog.rc 2014-05-12 07:52:05.000000000 +0000 @@ -0,0 +1,98 @@ +#include "ExtractDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 336 +#define yc 168 + +#undef g1xs +#undef g2x +#undef g2x2 +#undef g2xs +#undef g2xs2 + +#define g1xs 160 + +#define gSpace 20 +#define g2x (m + g1xs + gSpace) +#define g2x2 (g2x + m) +#define g2xs (xc - g1xs - gSpace) +#define g2xs2 (g2xs - m - m) + +#undef GROUP_Y_SIZE +#ifdef UNDER_CE +#define GROUP_Y_SIZE 8 +#else +#define GROUP_Y_SIZE 56 +#endif + +IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Extract" +BEGIN + LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 + COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 12, 100, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 2, bxsDots, bys, WS_GROUP + + CONTROL "", IDX_EXTRACT_NAME_ENABLE, MY_CHECKBOX, m, m + 34, 12, 10 + EDITTEXT IDE_EXTRACT_NAME, m + 12 + 2, m + 32, g1xs - 12 - 2, 14, ES_AUTOHSCROLL + + LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 52, g1xs, 8 + COMBOBOX IDC_EXTRACT_PATH_MODE, m, m + 64, g1xs, 140, MY_COMBO + + CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, + m, m + 84, g1xs, 10 + + LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 104, g1xs, 8 + COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m, m + 116, g1xs, 140, MY_COMBO + + + GROUPBOX "Password", IDG_PASSWORD, g2x, m + 36, g2xs, GROUP_Y_SIZE + EDITTEXT IDE_EXTRACT_PASSWORD, g2x2, m + 50, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, g2x2, m + 72, g2xs2, 10 + +// CONTROL "Restore alternate data streams", IDX_EXTRACT_ALT_STREAMS, MY_CHECKBOX, +// g2x, m + 104, g2xs, 10 + CONTROL "Restore file security", IDX_EXTRACT_NT_SECUR, MY_CHECKBOX, + g2x, m + 104, g2xs, 10 + + DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys + PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys +END + + +#ifdef UNDER_CE + +#undef m +#define m 4 + +#undef xc +#undef yc + +#define xc 152 +#define yc 128 + +#undef g1xs + +#define g1xs 64 + +IDD_EXTRACT_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Extract" +BEGIN + LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc - bxsDots - 8, 8 + COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 8, 100, MY_COMBO_WITH_EDIT + PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 3, bxsDots, bys, WS_GROUP + + LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 36, g1xs, 8 + COMBOBOX IDC_EXTRACT_PATH_MODE, m + g1xs, m + 36, xc - g1xs, 100, MY_COMBO + + LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 56, g1xs, 8 + COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m + g1xs, m + 56, xc - g1xs, 100, MY_COMBO + + LTEXT "Password", IDG_PASSWORD, m, m + 76, g1xs, 8 + EDITTEXT IDE_EXTRACT_PASSWORD, m + g1xs, m + 76, xc - g1xs, 14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, m + 92, xc, 10 + + OK_CANCEL +END + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialogRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialogRes.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialogRes.h 2015-09-19 09:42:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialogRes.h 2015-08-25 11:11:13.000000000 +0000 @@ -1,24 +1,24 @@ -#define IDD_EXTRACT 3400 -#define IDD_EXTRACT_2 13400 - -#define IDC_EXTRACT_PATH 100 -#define IDB_EXTRACT_SET_PATH 101 -#define IDC_EXTRACT_PATH_MODE 102 -#define IDC_EXTRACT_OVERWRITE_MODE 103 - -#define IDE_EXTRACT_PASSWORD 120 - -#define IDE_EXTRACT_NAME 130 -#define IDX_EXTRACT_NAME_ENABLE 131 - - -#define IDT_EXTRACT_EXTRACT_TO 3401 -#define IDT_EXTRACT_PATH_MODE 3410 -#define IDT_EXTRACT_OVERWRITE_MODE 3420 - -#define IDX_EXTRACT_ELIM_DUP 3430 -#define IDX_EXTRACT_NT_SECUR 3431 -// #define IDX_EXTRACT_ALT_STREAMS 3432 - -#define IDX_PASSWORD_SHOW 3803 -#define IDG_PASSWORD 3807 +#define IDD_EXTRACT 3400 +#define IDD_EXTRACT_2 13400 + +#define IDC_EXTRACT_PATH 100 +#define IDB_EXTRACT_SET_PATH 101 +#define IDC_EXTRACT_PATH_MODE 102 +#define IDC_EXTRACT_OVERWRITE_MODE 103 + +#define IDE_EXTRACT_PASSWORD 120 + +#define IDE_EXTRACT_NAME 130 +#define IDX_EXTRACT_NAME_ENABLE 131 + + +#define IDT_EXTRACT_EXTRACT_TO 3401 +#define IDT_EXTRACT_PATH_MODE 3410 +#define IDT_EXTRACT_OVERWRITE_MODE 3420 + +#define IDX_EXTRACT_ELIM_DUP 3430 +#define IDX_EXTRACT_NT_SECUR 3431 +// #define IDX_EXTRACT_ALT_STREAMS 3432 + +#define IDX_PASSWORD_SHOW 3803 +#define IDG_PASSWORD 3807 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog_rc.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog_rc.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractDialog_rc.cpp 2015-01-14 20:45:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractDialog_rc.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -// ExtractDialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" - -#include "ExtractRes.h" -#include "ExtractDialogRes.h" - -/* -IDD_EXTRACT DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT -CAPTION "Extract" -BEGIN - LTEXT "E&xtract to:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8 - COMBOBOX IDC_EXTRACT_PATH, m, m + 12, xc - bxsDots - 12, 100, MY_COMBO_WITH_EDIT - PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, m + 12 - 2, bxsDots, bys, WS_GROUP - - CONTROL "", IDX_EXTRACT_NAME_ENABLE, MY_CHECKBOX, m, m + 34, 12, 10 - EDITTEXT IDE_EXTRACT_NAME, m + 12 + 2, m + 32, g1xs - 12 - 2, 14, ES_AUTOHSCROLL - - LTEXT "Path mode:", IDT_EXTRACT_PATH_MODE, m, m + 52, g1xs, 8 - COMBOBOX IDC_EXTRACT_PATH_MODE, m, m + 64, g1xs, 140, MY_COMBO - - CONTROL "Eliminate duplication of root folder", IDX_EXTRACT_ELIM_DUP, MY_CHECKBOX, - m, m + 84, g1xs, 10 - - LTEXT "Overwrite mode:", IDT_EXTRACT_OVERWRITE_MODE, m, m + 104, g1xs, 8 - COMBOBOX IDC_EXTRACT_OVERWRITE_MODE, m, m + 116, g1xs, 140, MY_COMBO - - - GROUPBOX "Password", IDG_PASSWORD, g2x, m + 36, g2xs, GROUP_Y_SIZE - EDITTEXT IDE_EXTRACT_PASSWORD, g2x2, m + 50, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Show Password", IDX_PASSWORD_SHOW, MY_CHECKBOX, g2x2, m + 72, g2xs2, 10 - -// CONTROL "Restore alternate data streams", IDX_EXTRACT_ALT_STREAMS, MY_CHECKBOX, -// g2x, m + 104, g2xs, 10 - CONTROL "Restore file security", IDX_EXTRACT_NT_SECUR, MY_CHECKBOX, - g2x, m + 104, g2xs, 10 - - DEFPUSHBUTTON "OK", IDOK, bx3, by, bxs, bys, WS_GROUP - PUSHBUTTON "Cancel", IDCANCEL, bx2, by, bxs, bys - PUSHBUTTON "Help", IDHELP, bx1, by, bxs, bys -END -*/ - - -class CExtractDialogImpl : public NWindows::NControl::CModalDialogImpl -{ - public: - CExtractDialogImpl(NWindows::NControl::CModalDialog *dialog,wxWindow * parent , int id) : CModalDialogImpl(dialog,parent, id, wxT("Extract")) - { - wxStaticText *m_pStaticTextExtractTo; - wxTextCtrl *m_pTextCtrlPassword; - wxButton *m_pButtonBrowse; - wxComboBox *m_pComboBoxExtractTo; - wxCheckBox *m_pCheckBoxShowPassword; - - wxTextCtrl *m_pTextCtrlName; - wxCheckBox *m_pCheckBoxNameEnable; - - wxComboBox *m_pPathMode; - - wxCheckBox * m_pCheckBoxElimDup; - wxCheckBox * m_pCheckBoxNtSecur; - - wxComboBox *m_pOverWriteMode; - - ///Sizer for adding the controls created by users - wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL); - - wxArrayString pathArray; - m_pStaticTextExtractTo = new wxStaticText(this, IDT_EXTRACT_EXTRACT_TO, wxT("E&xtract To:")); - wxBoxSizer *pPathSizer = new wxBoxSizer(wxHORIZONTAL); - // m_pComboBoxExtractTo = new wxComboBox(this, IDC_EXTRACT_PATH, wxEmptyString, wxDefaultPosition, wxDefaultSize, pathArray, wxCB_DROPDOWN|wxCB_SORT); - m_pComboBoxExtractTo = new wxComboBox(this, IDC_EXTRACT_PATH, wxEmptyString, wxDefaultPosition, wxSize(600,-1), pathArray, wxCB_DROPDOWN|wxCB_SORT); - m_pButtonBrowse = new wxButton(this, IDB_EXTRACT_SET_PATH, wxT("..."), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - pPathSizer->Add(m_pComboBoxExtractTo, 1, wxLEFT|wxRIGHT|wxEXPAND, 5); - pPathSizer->Add(m_pButtonBrowse, 0, wxLEFT|wxRIGHT|wxEXPAND, 5); - - wxBoxSizer *pControlSizer = new wxBoxSizer(wxHORIZONTAL); - - wxStaticBoxSizer * grpPathMode = new wxStaticBoxSizer(new wxStaticBox(this,IDT_EXTRACT_PATH_MODE,_T("Path mode :")),wxVERTICAL); - - m_pPathMode = new wxComboBox(this, IDC_EXTRACT_PATH_MODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, pathArray, wxCB_DROPDOWN); - - grpPathMode->Add(m_pPathMode, 1, wxLEFT|wxRIGHT|wxEXPAND, 5); - - wxBoxSizer *pLeftSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *pRightSizer = new wxBoxSizer(wxVERTICAL); - - - m_pTextCtrlName = new wxTextCtrl(this, IDE_EXTRACT_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize); - m_pCheckBoxNameEnable = new wxCheckBox(this, IDX_EXTRACT_NAME_ENABLE, wxT("")); - - m_pCheckBoxElimDup = new wxCheckBox(this, IDX_EXTRACT_ELIM_DUP, wxT("Eliminate duplication of root folder")); - - m_pCheckBoxNtSecur = new wxCheckBox(this, IDX_EXTRACT_NT_SECUR, wxT("Restore file security")); - - wxStaticBoxSizer * grpOverWriteMode = new wxStaticBoxSizer(new wxStaticBox(this,IDT_EXTRACT_OVERWRITE_MODE,wxT("Overwrite mode :")),wxVERTICAL); - m_pOverWriteMode = new wxComboBox(this, IDC_EXTRACT_OVERWRITE_MODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, pathArray, wxCB_DROPDOWN); - grpOverWriteMode->Add(m_pOverWriteMode, 1, wxLEFT|wxRIGHT|wxEXPAND, 5); - - - - wxStaticBoxSizer *pPasswordSizer = new wxStaticBoxSizer(new wxStaticBox(this,IDG_PASSWORD,wxT("Password")),wxVERTICAL); - m_pTextCtrlPassword = new wxTextCtrl(this, IDE_EXTRACT_PASSWORD, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); - m_pCheckBoxShowPassword = new wxCheckBox(this, IDX_PASSWORD_SHOW, wxT("Show Password")); - pPasswordSizer->Add(m_pTextCtrlPassword, 0, wxALL|wxEXPAND, 5); - pPasswordSizer->Add(m_pCheckBoxShowPassword, 0, wxALL|wxEXPAND, 5); - - pLeftSizer->Add(m_pCheckBoxNameEnable, 0, wxALL|wxEXPAND, 5); - pLeftSizer->Add(m_pTextCtrlName, 1, wxALL|wxEXPAND, 5); - - pLeftSizer->Add(grpPathMode, 1, wxALL|wxEXPAND, 5); - pLeftSizer->Add(m_pCheckBoxElimDup, 1, wxALL|wxEXPAND, 5); - pLeftSizer->Add(grpOverWriteMode, 0, wxALL|wxEXPAND, 5); - - pRightSizer->Add(pPasswordSizer, 0, wxALL|wxEXPAND, 5); - pRightSizer->Add(m_pCheckBoxNtSecur, 1, wxALL|wxEXPAND, 5); - - pControlSizer->Add(pLeftSizer, 1, wxALL|wxEXPAND, 5); - pControlSizer->Add(pRightSizer, 1, wxLEFT | wxRIGHT | wxEXPAND, 5); - - topsizer->Add(m_pStaticTextExtractTo, 0, wxALL | wxEXPAND , 10); - topsizer->Add(pPathSizer, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND , 5); - topsizer->Add(pControlSizer, 1, wxALL | wxEXPAND , 5); - topsizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxHELP), 0, wxALL | wxEXPAND , 5); - - this->OnInit(); - - SetSizer(topsizer); // use the sizer for layout - topsizer->SetSizeHints(this); // set size hints to honour minimum size - } -private: - // Any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() -}; - -REGISTER_DIALOG(IDD_EXTRACT,CExtractDialog,0) - -BEGIN_EVENT_TABLE(CExtractDialogImpl, wxDialog) - EVT_BUTTON(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_CHECKBOX(wxID_ANY, CModalDialogImpl::OnAnyButton) - EVT_MENU(WORKER_EVENT, CModalDialogImpl::OnWorkerEvent) -END_EVENT_TABLE() - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractGUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractGUI.cpp 2015-10-03 17:44:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,279 +1,297 @@ -// ExtractGUI.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileFind.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/Thread.h" - -#include "../FileManager/ExtractCallback.h" -#include "../FileManager/FormatUtils.h" -#include "../FileManager/LangUtils.h" -#include "../FileManager/resourceGui.h" -#include "../FileManager/OverwriteDialogRes.h" - -#include "../Common/ArchiveExtractCallback.h" -#include "../Common/PropIDUtils.h" - -#include "../Explorer/MyMessages.h" - -#include "resource2.h" -#include "ExtractRes.h" - -#include "ExtractDialog.h" -#include "ExtractGUI.h" -#include "HashGUI.h" - -#include "../FileManager/PropertyNameRes.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; - -#ifndef _SFX - -static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true) -{ - AddLangString(s, resourceID); - if (addColon) - s += L':'; - s.Add_Space(); - char sz[32]; - ConvertUInt64ToString(value, sz); - s.AddAscii(sz); - s.Add_LF(); -} - -static void AddSizePair(UString &s, UINT resourceID, UInt64 value) -{ - wchar_t sz[32]; - AddLangString(s, resourceID); - s += L": "; - ConvertUInt64ToString(value, sz); - s += MyFormatNew(IDS_FILE_SIZE, sz); - // s += sz; - if (value >= (1 << 20)) - { - ConvertUInt64ToString(value >> 20, sz); - s += L" ("; - s += sz; - s += L" MB)"; - } - s.Add_LF(); -} - -#endif - -class CThreadExtracting: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - CCodecs *codecs; - CExtractCallbackImp *ExtractCallbackSpec; - const CObjectVector *FormatIndices; - const CIntVector *ExcludedFormatIndices; - - UStringVector *ArchivePaths; - UStringVector *ArchivePathsFull; - const NWildcard::CCensorNode *WildcardCensor; - const CExtractOptions *Options; - #ifndef _SFX - CHashBundle *HashBundle; - #endif - CMyComPtr ExtractCallback; - UString Title; -}; - -HRESULT CThreadExtracting::ProcessVirt() -{ - CDecompressStat Stat; - #ifndef _SFX - if (HashBundle) - HashBundle->Init(); - #endif - - HRESULT res = Extract(codecs, - *FormatIndices, *ExcludedFormatIndices, - *ArchivePaths, *ArchivePathsFull, - *WildcardCensor, *Options, ExtractCallbackSpec, ExtractCallback, - #ifndef _SFX - HashBundle, - #endif - FinalMessage.ErrorMessage.Message, Stat); - #ifndef _SFX - if (res == S_OK && Options->TestMode && ExtractCallbackSpec->IsOK()) - { - UString s; - - AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); - AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); - - if (!HashBundle) - { - if (Stat.NumFolders != 0) - AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders); - AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles); - AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize); - if (Stat.NumAltStreams != 0) - { - s.Add_LF(); - AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams); - AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize); - } - } - - if (HashBundle) - { - s.Add_LF(); - AddHashBundleRes(s, *HashBundle, UString()); - } - - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - - FinalMessage.OkMessage.Title = Title; - FinalMessage.OkMessage.Message = s; - } - #endif - return res; -} - -HRESULT ExtractGUI( - CCodecs *codecs, - const CObjectVector &formatIndices, - const CIntVector &excludedFormatIndices, - UStringVector &archivePaths, - UStringVector &archivePathsFull, - const NWildcard::CCensorNode &wildcardCensor, - CExtractOptions &options, - #ifndef _SFX - CHashBundle *hb, - #endif - bool showDialog, - bool &messageWasDisplayed, - CExtractCallbackImp *extractCallback, - HWND hwndParent) -{ - messageWasDisplayed = false; - - CThreadExtracting extracter; - extracter.codecs = codecs; - extracter.FormatIndices = &formatIndices; - extracter.ExcludedFormatIndices = &excludedFormatIndices; - - if (!options.TestMode) - { - FString outputDir = options.OutputDir; - #ifndef UNDER_CE - if (outputDir.IsEmpty()) - GetCurrentDir(outputDir); - #endif - if (showDialog) - { - CExtractDialog dialog; - FString outputDirFull; - if (!MyGetFullPathName(outputDir, outputDirFull)) - { - ShowErrorMessage(kIncorrectOutDir); - messageWasDisplayed = true; - return E_FAIL; - } - NName::NormalizeDirPathPrefix(outputDirFull); - - dialog.DirPath = fs2us(outputDirFull); -#ifndef _WIN32 - { - extern const TCHAR * nameWindowToUnix(const TCHAR * lpFileName); - UString tmpDirectoryPath = dialog.DirPath; - dialog.DirPath = nameWindowToUnix(tmpDirectoryPath); - } -#endif - - dialog.OverwriteMode = options.OverwriteMode; - dialog.OverwriteMode_Force = options.OverwriteMode_Force; - dialog.PathMode = options.PathMode; - dialog.PathMode_Force = options.PathMode_Force; - dialog.ElimDup = options.ElimDup; - - if (archivePathsFull.Size() == 1) - dialog.ArcPath = archivePathsFull[0]; - - #ifndef _SFX - // dialog.AltStreams = options.NtOptions.AltStreams; - dialog.NtSecurity = options.NtOptions.NtSecurity; - if (extractCallback->PasswordIsDefined) - dialog.Password = extractCallback->Password; - #endif - - if (dialog.Create(hwndParent) != IDOK) - return E_ABORT; - - outputDir = us2fs(dialog.DirPath); - - options.OverwriteMode = dialog.OverwriteMode; - options.PathMode = dialog.PathMode; - options.ElimDup = dialog.ElimDup; - - #ifndef _SFX - // options.NtOptions.AltStreams = dialog.AltStreams; - options.NtOptions.NtSecurity = dialog.NtSecurity; - extractCallback->Password = dialog.Password; - extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); - #endif - } - if (!MyGetFullPathName(outputDir, options.OutputDir)) - { - ShowErrorMessage(kIncorrectOutDir); - messageWasDisplayed = true; - return E_FAIL; - } - NName::NormalizeDirPathPrefix(options.OutputDir); - - /* - if (!CreateComplexDirectory(options.OutputDir)) - { - UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); - UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, - #ifdef LANG - 0x02000603, - #endif - options.OutputDir); - s2.Add_LF(); - s2 += s; - MyMessageBox(s2); - return E_FAIL; - } - */ - } - - UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING); - - extracter.Title = title; - extracter.ExtractCallbackSpec = extractCallback; - extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog; - extracter.ExtractCallback = extractCallback; - extracter.ExtractCallbackSpec->Init(); - - extracter.ProgressDialog.CompressingMode = false; - - extracter.ArchivePaths = &archivePaths; - extracter.ArchivePathsFull = &archivePathsFull; - extracter.WildcardCensor = &wildcardCensor; - extracter.Options = &options; - #ifndef _SFX - extracter.HashBundle = hb; - #endif - - extracter.ProgressDialog.IconID = IDI_ICON; - - RINOK(extracter.Create(title, hwndParent)); - messageWasDisplayed = extracter.ThreadFinishedOK & - extracter.ProgressDialog.MessagesDisplayed; - return extracter.Result; -} +// ExtractGUI.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Thread.h" + +#include "../FileManager/ExtractCallback.h" +#include "../FileManager/FormatUtils.h" +#include "../FileManager/LangUtils.h" +#include "../FileManager/resourceGui.h" +#include "../FileManager/OverwriteDialogRes.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/PropIDUtils.h" + +#include "../Explorer/MyMessages.h" + +#include "resource2.h" +#include "ExtractRes.h" + +#include "ExtractDialog.h" +#include "ExtractGUI.h" +#include "HashGUI.h" + +#include "../FileManager/PropertyNameRes.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const wchar_t * const kIncorrectOutDir = L"Incorrect output directory path"; + +#ifndef Z7_SFX + +static void AddValuePair(UString &s, UINT resourceID, UInt64 value, bool addColon = true) +{ + AddLangString(s, resourceID); + if (addColon) + s.Add_Colon(); + s.Add_Space(); + s.Add_UInt64(value); + s.Add_LF(); +} + +static void AddSizePair(UString &s, UINT resourceID, UInt64 value) +{ + AddLangString(s, resourceID); + s += ": "; + AddSizeValue(s, value); + s.Add_LF(); +} + +#endif + +class CThreadExtracting: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + /* + #ifdef Z7_EXTERNAL_CODECS + const CExternalCodecs *externalCodecs; + #endif + */ + + CCodecs *codecs; + CExtractCallbackImp *ExtractCallbackSpec; + const CObjectVector *FormatIndices; + const CIntVector *ExcludedFormatIndices; + + UStringVector *ArchivePaths; + UStringVector *ArchivePathsFull; + const NWildcard::CCensorNode *WildcardCensor; + const CExtractOptions *Options; + + #ifndef Z7_SFX + CHashBundle *HashBundle; + virtual void ProcessWasFinished_GuiVirt() Z7_override; + #endif + + CMyComPtr FolderArchiveExtractCallback; + UString Title; + + CPropNameValPairs Pairs; +}; + + +#ifndef Z7_SFX +void CThreadExtracting::ProcessWasFinished_GuiVirt() +{ + if (HashBundle && !Pairs.IsEmpty()) + ShowHashResults(Pairs, *this); +} +#endif + +HRESULT CThreadExtracting::ProcessVirt() +{ + CDecompressStat Stat; + + #ifndef Z7_SFX + /* + if (HashBundle) + HashBundle->Init(); + */ + #endif + + HRESULT res = Extract( + /* + #ifdef Z7_EXTERNAL_CODECS + externalCodecs, + #endif + */ + codecs, + *FormatIndices, *ExcludedFormatIndices, + *ArchivePaths, *ArchivePathsFull, + *WildcardCensor, *Options, + ExtractCallbackSpec, ExtractCallbackSpec, FolderArchiveExtractCallback, + #ifndef Z7_SFX + HashBundle, + #endif + FinalMessage.ErrorMessage.Message, Stat); + + #ifndef Z7_SFX + if (res == S_OK && ExtractCallbackSpec->IsOK()) + { + if (HashBundle) + { + AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives); + AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize); + AddHashBundleRes(Pairs, *HashBundle); + } + else if (Options->TestMode) + { + UString s; + + AddValuePair(s, IDS_ARCHIVES_COLON, Stat.NumArchives, false); + AddSizePair(s, IDS_PROP_PACKED_SIZE, Stat.PackSize); + + if (Stat.NumFolders != 0) + AddValuePair(s, IDS_PROP_FOLDERS, Stat.NumFolders); + AddValuePair(s, IDS_PROP_FILES, Stat.NumFiles); + AddSizePair(s, IDS_PROP_SIZE, Stat.UnpackSize); + if (Stat.NumAltStreams != 0) + { + s.Add_LF(); + AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, Stat.NumAltStreams); + AddSizePair(s, IDS_PROP_ALT_STREAMS_SIZE, Stat.AltStreams_UnpackSize); + } + s.Add_LF(); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + FinalMessage.OkMessage.Title = Title; + FinalMessage.OkMessage.Message = s; + } + } + #endif + + return res; +} + + + +HRESULT ExtractGUI( + // DECL_EXTERNAL_CODECS_LOC_VARS + CCodecs *codecs, + const CObjectVector &formatIndices, + const CIntVector &excludedFormatIndices, + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + #ifndef Z7_SFX + CHashBundle *hb, + #endif + bool showDialog, + bool &messageWasDisplayed, + CExtractCallbackImp *extractCallback, + HWND hwndParent) +{ + messageWasDisplayed = false; + + CThreadExtracting extracter; + /* + #ifdef Z7_EXTERNAL_CODECS + extracter.externalCodecs = _externalCodecs; + #endif + */ + extracter.codecs = codecs; + extracter.FormatIndices = &formatIndices; + extracter.ExcludedFormatIndices = &excludedFormatIndices; + + if (!options.TestMode) + { + FString outputDir = options.OutputDir; + #ifndef UNDER_CE + if (outputDir.IsEmpty()) + GetCurrentDir(outputDir); + #endif + if (showDialog) + { + CExtractDialog dialog; + FString outputDirFull; + if (!MyGetFullPathName(outputDir, outputDirFull)) + { + ShowErrorMessage(kIncorrectOutDir); + messageWasDisplayed = true; + return E_FAIL; + } + NName::NormalizeDirPathPrefix(outputDirFull); + + dialog.DirPath = fs2us(outputDirFull); + + dialog.OverwriteMode = options.OverwriteMode; + dialog.OverwriteMode_Force = options.OverwriteMode_Force; + dialog.PathMode = options.PathMode; + dialog.PathMode_Force = options.PathMode_Force; + dialog.ElimDup = options.ElimDup; + + if (archivePathsFull.Size() == 1) + dialog.ArcPath = archivePathsFull[0]; + + #ifndef Z7_SFX + // dialog.AltStreams = options.NtOptions.AltStreams; + dialog.NtSecurity = options.NtOptions.NtSecurity; + if (extractCallback->PasswordIsDefined) + dialog.Password = extractCallback->Password; + #endif + + if (dialog.Create(hwndParent) != IDOK) + return E_ABORT; + + outputDir = us2fs(dialog.DirPath); + + options.OverwriteMode = dialog.OverwriteMode; + options.PathMode = dialog.PathMode; + options.ElimDup = dialog.ElimDup; + + #ifndef Z7_SFX + // options.NtOptions.AltStreams = dialog.AltStreams; + options.NtOptions.NtSecurity = dialog.NtSecurity; + extractCallback->Password = dialog.Password; + extractCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); + #endif + } + if (!MyGetFullPathName(outputDir, options.OutputDir)) + { + ShowErrorMessage(kIncorrectOutDir); + messageWasDisplayed = true; + return E_FAIL; + } + NName::NormalizeDirPathPrefix(options.OutputDir); + + /* + if (!CreateComplexDirectory(options.OutputDir)) + { + UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); + UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, + #ifdef Z7_LANG + 0x02000603, + #endif + options.OutputDir); + s2.Add_LF(); + s2 += s; + MyMessageBox(s2); + return E_FAIL; + } + */ + } + + UString title = LangString(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING); + + extracter.Title = title; + extracter.ExtractCallbackSpec = extractCallback; + extracter.ExtractCallbackSpec->ProgressDialog = &extracter; + extracter.FolderArchiveExtractCallback = extractCallback; + extracter.ExtractCallbackSpec->Init(); + + extracter.CompressingMode = false; + + extracter.ArchivePaths = &archivePaths; + extracter.ArchivePathsFull = &archivePathsFull; + extracter.WildcardCensor = &wildcardCensor; + extracter.Options = &options; + #ifndef Z7_SFX + extracter.HashBundle = hb; + #endif + + extracter.IconID = IDI_ICON; + + RINOK(extracter.Create(title, hwndParent)) + messageWasDisplayed = extracter.ThreadFinishedOK && extracter.MessagesDisplayed; + return extracter.Result; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractGUI.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractGUI.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractGUI.h 2023-01-29 16:00:00.000000000 +0000 @@ -1,38 +1,39 @@ -// GUI/ExtractGUI.h - -#ifndef __EXTRACT_GUI_H -#define __EXTRACT_GUI_H - -#include "../Common/Extract.h" - -#include "../FileManager/ExtractCallback.h" - -/* - RESULT can be S_OK, even if there are errors!!! - if RESULT == S_OK, check extractCallback->IsOK() after ExtractGUI(). - - RESULT = E_ABORT - user break. - RESULT != E_ABORT: - { - messageWasDisplayed = true - message was displayed already. - messageWasDisplayed = false - there was some internal error, so you must show error message. - } -*/ - -HRESULT ExtractGUI( - CCodecs *codecs, - const CObjectVector &formatIndices, - const CIntVector &excludedFormatIndices, - UStringVector &archivePaths, - UStringVector &archivePathsFull, - const NWildcard::CCensorNode &wildcardCensor, - CExtractOptions &options, - #ifndef _SFX - CHashBundle *hb, - #endif - bool showDialog, - bool &messageWasDisplayed, - CExtractCallbackImp *extractCallback, - HWND hwndParent = NULL); - -#endif +// GUI/ExtractGUI.h + +#ifndef ZIP7_INC_EXTRACT_GUI_H +#define ZIP7_INC_EXTRACT_GUI_H + +#include "../Common/Extract.h" + +#include "../FileManager/ExtractCallback.h" + +/* + RESULT can be S_OK, even if there are errors!!! + if RESULT == S_OK, check extractCallback->IsOK() after ExtractGUI(). + + RESULT = E_ABORT - user break. + RESULT != E_ABORT: + { + messageWasDisplayed = true - message was displayed already. + messageWasDisplayed = false - there was some internal error, so you must show error message. + } +*/ + +HRESULT ExtractGUI( + // DECL_EXTERNAL_CODECS_LOC_VARS + CCodecs *codecs, + const CObjectVector &formatIndices, + const CIntVector &excludedFormatIndices, + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + #ifndef Z7_SFX + CHashBundle *hb, + #endif + bool showDialog, + bool &messageWasDisplayed, + CExtractCallbackImp *extractCallback, + HWND hwndParent = NULL); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractRes.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractRes.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/ExtractRes.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/ExtractRes.h 2015-03-23 10:37:35.000000000 +0000 @@ -1,51 +1,51 @@ -#define IDS_MEM_ERROR 3000 - -#define IDS_CANNOT_CREATE_FOLDER 3003 -#define IDS_UPDATE_NOT_SUPPORTED 3004 -#define IDS_CANT_OPEN_ARCHIVE 3005 -#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 3006 -#define IDS_UNSUPPORTED_ARCHIVE_TYPE 3007 - -#define IDS_CANT_OPEN_AS_TYPE 3017 -#define IDS_IS_OPEN_AS_TYPE 3018 -#define IDS_IS_OPEN_WITH_OFFSET 3019 - -#define IDS_PROGRESS_EXTRACTING 3300 - -#define IDS_PROGRESS_SKIPPING 3325 - -#define IDS_EXTRACT_SET_FOLDER 3402 - -#define IDS_EXTRACT_PATHS_FULL 3411 -#define IDS_EXTRACT_PATHS_NO 3412 -#define IDS_EXTRACT_PATHS_ABS 3413 -#define IDS_PATH_MODE_RELAT 3414 - -#define IDS_EXTRACT_OVERWRITE_ASK 3421 -#define IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT 3422 -#define IDS_EXTRACT_OVERWRITE_SKIP_EXISTING 3423 -#define IDS_EXTRACT_OVERWRITE_RENAME 3424 -#define IDS_EXTRACT_OVERWRITE_RENAME_EXISTING 3425 - -#define IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 3700 -#define IDS_EXTRACT_MESSAGE_DATA_ERROR 3701 -#define IDS_EXTRACT_MESSAGE_CRC_ERROR 3702 -#define IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 3703 -#define IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED 3704 - -#define IDS_EXTRACT_MSG_WRONG_PSW_GUESS 3710 -// #define IDS_EXTRACT_MSG_ENCRYPTED 3711 - -#define IDS_EXTRACT_MSG_UNSUPPORTED_METHOD 3721 -#define IDS_EXTRACT_MSG_DATA_ERROR 3722 -#define IDS_EXTRACT_MSG_CRC_ERROR 3723 -#define IDS_EXTRACT_MSG_UNAVAILABLE_DATA 3724 -#define IDS_EXTRACT_MSG_UEXPECTED_END 3725 -#define IDS_EXTRACT_MSG_DATA_AFTER_END 3726 -#define IDS_EXTRACT_MSG_IS_NOT_ARC 3727 -#define IDS_EXTRACT_MSG_HEADERS_ERROR 3728 -#define IDS_EXTRACT_MSG_WRONG_PSW_CLAIM 3729 - -#define IDS_OPEN_MSG_UNAVAILABLE_START 3763 -#define IDS_OPEN_MSG_UNCONFIRMED_START 3764 -#define IDS_OPEN_MSG_UNSUPPORTED_FEATURE 3768 +#define IDS_MEM_ERROR 3000 + +#define IDS_CANNOT_CREATE_FOLDER 3003 +#define IDS_UPDATE_NOT_SUPPORTED 3004 +#define IDS_CANT_OPEN_ARCHIVE 3005 +#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 3006 +#define IDS_UNSUPPORTED_ARCHIVE_TYPE 3007 + +#define IDS_CANT_OPEN_AS_TYPE 3017 +#define IDS_IS_OPEN_AS_TYPE 3018 +#define IDS_IS_OPEN_WITH_OFFSET 3019 + +#define IDS_PROGRESS_EXTRACTING 3300 + +#define IDS_PROGRESS_SKIPPING 3325 + +#define IDS_EXTRACT_SET_FOLDER 3402 + +#define IDS_EXTRACT_PATHS_FULL 3411 +#define IDS_EXTRACT_PATHS_NO 3412 +#define IDS_EXTRACT_PATHS_ABS 3413 +#define IDS_PATH_MODE_RELAT 3414 + +#define IDS_EXTRACT_OVERWRITE_ASK 3421 +#define IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT 3422 +#define IDS_EXTRACT_OVERWRITE_SKIP_EXISTING 3423 +#define IDS_EXTRACT_OVERWRITE_RENAME 3424 +#define IDS_EXTRACT_OVERWRITE_RENAME_EXISTING 3425 + +#define IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 3700 +#define IDS_EXTRACT_MESSAGE_DATA_ERROR 3701 +#define IDS_EXTRACT_MESSAGE_CRC_ERROR 3702 +#define IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 3703 +#define IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED 3704 + +#define IDS_EXTRACT_MSG_WRONG_PSW_GUESS 3710 +// #define IDS_EXTRACT_MSG_ENCRYPTED 3711 + +#define IDS_EXTRACT_MSG_UNSUPPORTED_METHOD 3721 +#define IDS_EXTRACT_MSG_DATA_ERROR 3722 +#define IDS_EXTRACT_MSG_CRC_ERROR 3723 +#define IDS_EXTRACT_MSG_UNAVAILABLE_DATA 3724 +#define IDS_EXTRACT_MSG_UEXPECTED_END 3725 +#define IDS_EXTRACT_MSG_DATA_AFTER_END 3726 +#define IDS_EXTRACT_MSG_IS_NOT_ARC 3727 +#define IDS_EXTRACT_MSG_HEADERS_ERROR 3728 +#define IDS_EXTRACT_MSG_WRONG_PSW_CLAIM 3729 + +#define IDS_OPEN_MSG_UNAVAILABLE_START 3763 +#define IDS_OPEN_MSG_UNCONFIRMED_START 3764 +#define IDS_OPEN_MSG_UNSUPPORTED_FEATURE 3768 Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/7zip/UI/GUI/FM.ico and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/FM.ico differ diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.cpp 2015-09-19 18:26:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.cpp 2024-03-14 11:00:00.000000000 +0000 @@ -1,460 +1,494 @@ -// GUI.cpp - -#include "StdAfx.h" - -#include "../../../../C/Alloc.h" - -#include "../../../Common/MyInitGuid.h" - -#include "../../../Common/CommandLineParser.h" -#include "../../../Common/IntToString.h" -#include "../../../Common/MyException.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/FileDir.h" -#include "../../../Windows/NtCheck.h" -#ifdef _WIN32 -#include "../../../Windows/MemoryLock.h" -#endif - -#include "../Common/ArchiveCommandLine.h" -#include "../Common/ExitCode.h" - -#include "../FileManager/StringUtils.h" -#include "../FileManager/MyWindowsNew.h" - -#include "BenchmarkDialog.h" -#include "ExtractGUI.h" -#include "HashGUI.h" -#include "UpdateGUI.h" - -#include "ExtractRes.h" - -using namespace NWindows; - -HINSTANCE g_hInstance; -#ifndef _UNICODE -#endif - -#if 0 // #ifndef UNDER_CE - -DWORD g_ComCtl32Version; - -static DWORD GetDllVersion(LPCTSTR dllName) -{ - DWORD dwVersion = 0; - HINSTANCE hinstDll = LoadLibrary(dllName); - if (hinstDll) - { - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion"); - if (pDllGetVersion) - { - DLLVERSIONINFO dvi; - ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hr = (*pDllGetVersion)(&dvi); - if (SUCCEEDED(hr)) - dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); - } - FreeLibrary(hinstDll); - } - return dwVersion; -} - -#endif - -bool g_LVN_ITEMACTIVATE_Support = true; - -static void ErrorMessage(LPCWSTR message) -{ - MessageBoxW(NULL, message, L"7-Zip", MB_ICONERROR | MB_OK); -} - -static void ErrorLangMessage(UINT resourceID) -{ - ErrorMessage(LangString(resourceID)); -} - -static const char *kNoFormats = "7-Zip cannot find the code that works with archives."; - -static int ShowMemErrorMessage() -{ - ErrorLangMessage(IDS_MEM_ERROR); - return NExitCode::kMemoryError; -} - -static int ShowSysErrorMessage(DWORD errorCode) -{ - if (errorCode == E_OUTOFMEMORY) - return ShowMemErrorMessage(); - ErrorMessage(HResultToMessage(errorCode)); - return NExitCode::kFatalError; -} - -static void ThrowException_if_Error(HRESULT res) -{ - if (res != S_OK) - throw CSystemException(res); -} - -static int Main2(int argc,TCHAR **argv) -{ - UStringVector commandStrings; -#ifdef _WIN32 - NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); -#else - extern void mySplitCommandLineW(int numArguments,TCHAR **arguments,UStringVector &parts); - mySplitCommandLineW(argc,argv,commandStrings); -#endif - #ifndef UNDER_CE - if (commandStrings.Size() > 0) - commandStrings.Delete(0); - #endif - if (commandStrings.Size() == 0) - { - MessageBoxW(0, L"Specify command", L"7-Zip", 0); - return 0; - } - - CArcCmdLineOptions options; - CArcCmdLineParser parser; - - parser.Parse1(commandStrings, options); - parser.Parse2(options); - - #if defined(_WIN32) && !defined(UNDER_CE) - NSecurity::EnablePrivilege_SymLink(); - #ifdef _7ZIP_LARGE_PAGES - if (options.LargePages) - NSecurity::EnablePrivilege_LockMemory(); - #endif - #endif - - CREATE_CODECS_OBJECT - - codecs->CaseSensitiveChange = options.CaseSensitiveChange; - codecs->CaseSensitive = options.CaseSensitive; - ThrowException_if_Error(codecs->Load()); - - bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); - - if (codecs->Formats.Size() == 0 && - (isExtractGroupCommand - - || options.Command.IsFromUpdateGroup())) - { - #ifdef EXTERNAL_CODECS - if (!codecs->MainDll_ErrorPath.IsEmpty()) - { - UString s = L"7-Zip cannot load module "; - s += fs2us(codecs->MainDll_ErrorPath); - throw s; - } - #endif - throw kNoFormats; - } - - CObjectVector formatIndices; - if (!ParseOpenTypes(*codecs, options.ArcType, formatIndices)) - { - ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); - return NExitCode::kFatalError; - } - - CIntVector excludedFormatIndices; - FOR_VECTOR (k, options.ExcludedArcTypes) - { - CIntVector tempIndices; - if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) - || tempIndices.Size() != 1) - { - ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); - return NExitCode::kFatalError; - } - excludedFormatIndices.AddToUniqueSorted(tempIndices[0]); - // excludedFormatIndices.Sort(); - } - - #ifdef EXTERNAL_CODECS - if (isExtractGroupCommand - || options.Command.CommandType == NCommandType::kHash - || options.Command.CommandType == NCommandType::kBenchmark) - ThrowException_if_Error(__externalCodecs.Load()); - #endif - - if (options.Command.CommandType == NCommandType::kBenchmark) - { - HRESULT res = Benchmark(EXTERNAL_CODECS_VARS_L options.Properties); - /* - if (res == S_FALSE) - { - stdStream << "\nDecoding Error\n"; - return NExitCode::kFatalError; - } - */ - ThrowException_if_Error(res); - } - else if (isExtractGroupCommand) - { - UStringVector ArchivePathsSorted; - UStringVector ArchivePathsFullSorted; - - CExtractCallbackImp *ecs = new CExtractCallbackImp; - CMyComPtr extractCallback = ecs; - - #ifndef _NO_CRYPTO - ecs->PasswordIsDefined = options.PasswordEnabled; - ecs->Password = options.Password; - #endif - - ecs->Init(); - - CExtractOptions eo; - (CExtractOptionsBase &)eo = options.ExtractOptions; - eo.StdInMode = options.StdInMode; - eo.StdOutMode = options.StdOutMode; - eo.YesToAll = options.YesToAll; - eo.TestMode = options.Command.IsTestCommand(); - - #ifndef _SFX - eo.Properties = options.Properties; - #endif - - bool messageWasDisplayed = false; - - #ifndef _SFX - CHashBundle hb; - CHashBundle *hb_ptr = NULL; - - if (!options.HashMethods.IsEmpty()) - { - hb_ptr = &hb; - ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); - } - #endif - - { - CDirItemsStat st; - HRESULT hresultMain = EnumerateDirItemsAndSort( - options.arcCensor, - NWildcard::k_RelatPath, - UString(), // addPathPrefix - ArchivePathsSorted, - ArchivePathsFullSorted, - st, - NULL // &scan: change it!!!! - ); - if (hresultMain != S_OK) - { - /* - if (hresultMain != E_ABORT && messageWasDisplayed) - return NExitCode::kFatalError; - */ - throw CSystemException(hresultMain); - } - } - - ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); - - HRESULT result = ExtractGUI(codecs, - formatIndices, excludedFormatIndices, - ArchivePathsSorted, - ArchivePathsFullSorted, - options.Censor.Pairs.Front().Head, - eo, - #ifndef _SFX - hb_ptr, - #endif - options.ShowDialog, messageWasDisplayed, ecs); - if (result != S_OK) - { - if (result != E_ABORT && messageWasDisplayed) - return NExitCode::kFatalError; - throw CSystemException(result); - } - if (!ecs->IsOK()) - return NExitCode::kFatalError; - } - else if (options.Command.IsFromUpdateGroup()) - { - #ifndef _NO_CRYPTO - bool passwordIsDefined = options.PasswordEnabled && !options.Password.IsEmpty(); - #endif - - CUpdateCallbackGUI callback; - // callback.EnablePercents = options.EnablePercents; - - #ifndef _NO_CRYPTO - callback.PasswordIsDefined = passwordIsDefined; - callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); - callback.Password = options.Password; - #endif - - // callback.StdOutMode = options.UpdateOptions.StdOutMode; - callback.Init(); - - if (!options.UpdateOptions.InitFormatIndex(codecs, formatIndices, options.ArchiveName) || - !options.UpdateOptions.SetArcPath(codecs, options.ArchiveName)) - { - ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED); - return NExitCode::kFatalError; - } - bool messageWasDisplayed = false; - HRESULT result = UpdateGUI( - codecs, formatIndices, - options.ArchiveName, - options.Censor, - options.UpdateOptions, - options.ShowDialog, - messageWasDisplayed, - &callback); - - if (result != S_OK) - { - if (result != E_ABORT && messageWasDisplayed) - return NExitCode::kFatalError; - throw CSystemException(result); - } - if (callback.FailedFiles.Size() > 0) - { - if (!messageWasDisplayed) - throw CSystemException(E_FAIL); - return NExitCode::kWarning; - } - } - else if (options.Command.CommandType == NCommandType::kHash) - { - bool messageWasDisplayed = false; - HRESULT result = HashCalcGUI(EXTERNAL_CODECS_VARS_L - options.Censor, options.HashOptions, messageWasDisplayed); - - if (result != S_OK) - { - if (result != E_ABORT && messageWasDisplayed) - return NExitCode::kFatalError; - throw CSystemException(result); - } - /* - if (callback.FailedFiles.Size() > 0) - { - if (!messageWasDisplayed) - throw CSystemException(E_FAIL); - return NExitCode::kWarning; - } - */ - } - else - { - throw "Unsupported command"; - } - return 0; -} - -#define NT_CHECK_FAIL_ACTION ErrorMessage(L"Unsupported Windows version"); return NExitCode::kFatalError; - -#ifdef _WIN32 -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, - #ifdef UNDER_CE - LPWSTR - #else - LPSTR - #endif - /* lpCmdLine */, int /* nCmdShow */) -{ - g_hInstance = hInstance; - #ifdef _WIN32 - NT_CHECK - SetLargePageSize(); - #endif - - InitCommonControls(); - - #ifndef UNDER_CE - g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); - g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); - #endif - - // OleInitialize is required for ProgressBar in TaskBar. - #ifndef UNDER_CE - OleInitialize(NULL); - #endif - - LoadLangOneTime(); - - // setlocale(LC_COLLATE, ".ACP"); - try - { - return Main2(); - } -#else -int Main1(int argc,TCHAR **argv) -{ - LoadLangOneTime(); - - // under MacOSX, a bundle does not keep the current directory - // between 7zFM and 7zG ... - // So, try to use the environment variable P7ZIP_CURRENT_DIR - const char *p7zip_current_dir = getenv("P7ZIP_CURRENT_DIR"); - - if (p7zip_current_dir) - { - UString currentDir = MultiByteToUnicodeString(p7zip_current_dir); - - NWindows::NFile::NDir::SetCurrentDir(currentDir); - } - - - // setlocale(LC_COLLATE, ".ACP"); - try - { - return Main2(argc,argv); - } -#endif - catch(const CNewException &) - { - return ShowMemErrorMessage(); - } - catch(const CArcCmdLineException &e) - { - ErrorMessage(e); - return NExitCode::kUserError; - } - catch(const CSystemException &systemError) - { - if (systemError.ErrorCode == E_ABORT) - return NExitCode::kUserBreak; - return ShowSysErrorMessage(systemError.ErrorCode); - } - catch(const UString &s) - { - ErrorMessage(s); - return NExitCode::kFatalError; - } - catch(const AString &s) - { - ErrorMessage(GetUnicodeString(s)); - return NExitCode::kFatalError; - } - catch(const wchar_t *s) - { - ErrorMessage(s); - return NExitCode::kFatalError; - } - catch(const char *s) - { - ErrorMessage(GetUnicodeString(s)); - return NExitCode::kFatalError; - } - catch(int v) - { - wchar_t s[32]; - ConvertUInt32ToString(v, s); - ErrorMessage(UString(L"Error: ") + s); - return NExitCode::kFatalError; - } - catch(...) - { - ErrorMessage(L"Unknown error"); - return NExitCode::kFatalError; - } -} +// GUI.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include "../../../../C/DllSecur.h" +#endif + +#include "../../../Common/MyWindows.h" +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../../../Common/MyInitGuid.h" + +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/MyException.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/NtCheck.h" + +#include "../Common/ArchiveCommandLine.h" +#include "../Common/ExitCode.h" + +#include "../FileManager/StringUtils.h" +#include "../FileManager/LangUtils.h" + +#include "BenchmarkDialog.h" +#include "ExtractGUI.h" +#include "HashGUI.h" +#include "UpdateGUI.h" + +#include "ExtractRes.h" + +using namespace NWindows; + +#ifdef Z7_EXTERNAL_CODECS +extern +const CExternalCodecs *g_ExternalCodecs_Ptr; +const CExternalCodecs *g_ExternalCodecs_Ptr; +#endif + +extern +HINSTANCE g_hInstance; +HINSTANCE g_hInstance; +extern +bool g_DisableUserQuestions; +bool g_DisableUserQuestions; + +#ifndef UNDER_CE + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // win2000 +#define Z7_USE_DYN_ComCtl32Version +#endif + +#ifdef Z7_USE_DYN_ComCtl32Version +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +extern +DWORD g_ComCtl32Version; +DWORD g_ComCtl32Version; + +static DWORD GetDllVersion(LPCTSTR dllName) +{ + DWORD dwVersion = 0; + const HMODULE hmodule = LoadLibrary(dllName); + if (hmodule) + { + const + DLLGETVERSIONPROC f_DllGetVersion = Z7_GET_PROC_ADDRESS( + DLLGETVERSIONPROC, hmodule, + "DllGetVersion"); + if (f_DllGetVersion) + { + DLLVERSIONINFO dvi; + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + const HRESULT hr = (*f_DllGetVersion)(&dvi); + if (SUCCEEDED(hr)) + dwVersion = (DWORD)MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + FreeLibrary(hmodule); + } + return dwVersion; +} + +#endif +#endif + +extern +bool g_LVN_ITEMACTIVATE_Support; +bool g_LVN_ITEMACTIVATE_Support = true; + +DECLARE_AND_SET_CLIENT_VERSION_VAR + +static void ErrorMessage(LPCWSTR message) +{ + if (!g_DisableUserQuestions) + MessageBoxW(NULL, message, L"7-Zip", MB_ICONERROR | MB_OK); +} + +static void ErrorMessage(const char *s) +{ + ErrorMessage(GetUnicodeString(s)); +} + +static void ErrorLangMessage(UINT resourceID) +{ + ErrorMessage(LangString(resourceID)); +} + +static const char * const kNoFormats = "7-Zip cannot find the code that works with archives."; + +static int ShowMemErrorMessage() +{ + ErrorLangMessage(IDS_MEM_ERROR); + return NExitCode::kMemoryError; +} + +static int ShowSysErrorMessage(HRESULT errorCode) +{ + if (errorCode == E_OUTOFMEMORY) + return ShowMemErrorMessage(); + ErrorMessage(HResultToMessage(errorCode)); + return NExitCode::kFatalError; +} + +static void ThrowException_if_Error(HRESULT res) +{ + if (res != S_OK) + throw CSystemException(res); +} + +static int Main2() +{ + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + + #ifndef UNDER_CE + if (commandStrings.Size() > 0) + commandStrings.Delete(0); + #endif + if (commandStrings.Size() == 0) + { + MessageBoxW(NULL, L"Specify command", L"7-Zip", 0); + return 0; + } + + CArcCmdLineOptions options; + CArcCmdLineParser parser; + + parser.Parse1(commandStrings, options); + g_DisableUserQuestions = options.YesToAll; + parser.Parse2(options); + + CREATE_CODECS_OBJECT + + codecs->CaseSensitive_Change = options.CaseSensitive_Change; + codecs->CaseSensitive = options.CaseSensitive; + ThrowException_if_Error(codecs->Load()); + Codecs_AddHashArcHandler(codecs); + + #ifdef Z7_EXTERNAL_CODECS + { + g_ExternalCodecs_Ptr = &_externalCodecs; + UString s; + codecs->GetCodecsErrorMessage(s); + if (!s.IsEmpty()) + { + if (!g_DisableUserQuestions) + MessageBoxW(NULL, s, L"7-Zip", MB_ICONERROR); + } + + } + #endif + + const bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + if (codecs->Formats.Size() == 0 && + (isExtractGroupCommand + + || options.Command.IsFromUpdateGroup())) + { + #ifdef Z7_EXTERNAL_CODECS + if (!codecs->MainDll_ErrorPath.IsEmpty()) + { + UString s ("7-Zip cannot load module: "); + s += fs2us(codecs->MainDll_ErrorPath); + throw s; + } + #endif + throw kNoFormats; + } + + CObjectVector formatIndices; + if (!ParseOpenTypes(*codecs, options.ArcType, formatIndices)) + { + ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); + return NExitCode::kFatalError; + } + + CIntVector excludedFormats; + FOR_VECTOR (k, options.ExcludedArcTypes) + { + CIntVector tempIndices; + if (!codecs->FindFormatForArchiveType(options.ExcludedArcTypes[k], tempIndices) + || tempIndices.Size() != 1) + { + ErrorLangMessage(IDS_UNSUPPORTED_ARCHIVE_TYPE); + return NExitCode::kFatalError; + } + excludedFormats.AddToUniqueSorted(tempIndices[0]); + // excludedFormats.Sort(); + } + + #ifdef Z7_EXTERNAL_CODECS + if (isExtractGroupCommand + || options.Command.IsFromUpdateGroup() + || options.Command.CommandType == NCommandType::kHash + || options.Command.CommandType == NCommandType::kBenchmark) + ThrowException_if_Error(_externalCodecs.Load()); + #endif + + if (options.Command.CommandType == NCommandType::kBenchmark) + { + HRESULT res = Benchmark( + EXTERNAL_CODECS_VARS_L + options.Properties, + options.NumIterations_Defined ? + options.NumIterations : + k_NumBenchIterations_Default); + /* + if (res == S_FALSE) + { + stdStream << "\nDecoding Error\n"; + return NExitCode::kFatalError; + } + */ + ThrowException_if_Error(res); + } + else if (isExtractGroupCommand) + { + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + + #ifndef Z7_NO_CRYPTO + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + #endif + + ecs->Init(); + + CExtractOptions eo; + (CExtractOptionsBase &)eo = options.ExtractOptions; + eo.StdInMode = options.StdInMode; + eo.StdOutMode = options.StdOutMode; + eo.YesToAll = options.YesToAll; + ecs->YesToAll = options.YesToAll; + eo.TestMode = options.Command.IsTestCommand(); + ecs->TestMode = eo.TestMode; + + #ifndef Z7_SFX + eo.Properties = options.Properties; + #endif + + bool messageWasDisplayed = false; + + #ifndef Z7_SFX + CHashBundle hb; + CHashBundle *hb_ptr = NULL; + + if (!options.HashMethods.IsEmpty()) + { + hb_ptr = &hb; + ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); + } + #endif + + { + CDirItemsStat st; + HRESULT hresultMain = EnumerateDirItemsAndSort( + options.arcCensor, + NWildcard::k_RelatPath, + UString(), // addPathPrefix + ArchivePathsSorted, + ArchivePathsFullSorted, + st, + NULL // &scan: change it!!!! + ); + if (hresultMain != S_OK) + { + /* + if (hresultMain != E_ABORT && messageWasDisplayed) + return NExitCode::kFatalError; + */ + throw CSystemException(hresultMain); + } + } + + ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1); + + HRESULT result = ExtractGUI( + // EXTERNAL_CODECS_VARS_L + codecs, + formatIndices, excludedFormats, + ArchivePathsSorted, + ArchivePathsFullSorted, + options.Censor.Pairs.Front().Head, + eo, + #ifndef Z7_SFX + hb_ptr, + #endif + options.ShowDialog, messageWasDisplayed, ecs); + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return NExitCode::kFatalError; + throw CSystemException(result); + } + if (!ecs->IsOK()) + return NExitCode::kFatalError; + } + else if (options.Command.IsFromUpdateGroup()) + { + #ifndef Z7_NO_CRYPTO + bool passwordIsDefined = options.PasswordEnabled && !options.Password.IsEmpty(); + #endif + + CUpdateCallbackGUI callback; + // callback.EnablePercents = options.EnablePercents; + + #ifndef Z7_NO_CRYPTO + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + #endif + + // callback.StdOutMode = options.UpdateOptions.StdOutMode; + callback.Init(); + + if (!options.UpdateOptions.InitFormatIndex(codecs, formatIndices, options.ArchiveName) || + !options.UpdateOptions.SetArcPath(codecs, options.ArchiveName)) + { + ErrorLangMessage(IDS_UPDATE_NOT_SUPPORTED); + return NExitCode::kFatalError; + } + bool messageWasDisplayed = false; + HRESULT result = UpdateGUI( + codecs, formatIndices, + options.ArchiveName, + options.Censor, + options.UpdateOptions, + options.ShowDialog, + messageWasDisplayed, + &callback); + + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return NExitCode::kFatalError; + throw CSystemException(result); + } + if (callback.FailedFiles.Size() > 0) + { + if (!messageWasDisplayed) + throw CSystemException(E_FAIL); + return NExitCode::kWarning; + } + } + else if (options.Command.CommandType == NCommandType::kHash) + { + bool messageWasDisplayed = false; + HRESULT result = HashCalcGUI(EXTERNAL_CODECS_VARS_L + options.Censor, options.HashOptions, messageWasDisplayed); + + if (result != S_OK) + { + if (result != E_ABORT && messageWasDisplayed) + return NExitCode::kFatalError; + throw CSystemException(result); + } + /* + if (callback.FailedFiles.Size() > 0) + { + if (!messageWasDisplayed) + throw CSystemException(E_FAIL); + return NExitCode::kWarning; + } + */ + } + else + { + throw "Unsupported command"; + } + return 0; +} + +#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE) +#define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return NExitCode::kFatalError; +#endif + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, + #ifdef UNDER_CE + LPWSTR + #else + LPSTR + #endif + /* lpCmdLine */, int /* nCmdShow */) +{ + g_hInstance = hInstance; + + #ifdef _WIN32 + NT_CHECK + #endif + + InitCommonControls(); + +#ifdef Z7_USE_DYN_ComCtl32Version + g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4)); +#endif + + // OleInitialize is required for ProgressBar in TaskBar. + #ifndef UNDER_CE + OleInitialize(NULL); + #endif + + #ifdef Z7_LANG + LoadLangOneTime(); + #endif + + // setlocale(LC_COLLATE, ".ACP"); + try + { + #ifdef _WIN32 + My_SetDefaultDllDirectories(); + #endif + + return Main2(); + } + catch(const CNewException &) + { + return ShowMemErrorMessage(); + } + catch(const CMessagePathException &e) + { + ErrorMessage(e); + return NExitCode::kUserError; + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_ABORT) + return NExitCode::kUserBreak; + return ShowSysErrorMessage(systemError.ErrorCode); + } + catch(const UString &s) + { + ErrorMessage(s); + return NExitCode::kFatalError; + } + catch(const AString &s) + { + ErrorMessage(s); + return NExitCode::kFatalError; + } + catch(const wchar_t *s) + { + ErrorMessage(s); + return NExitCode::kFatalError; + } + catch(const char *s) + { + ErrorMessage(s); + return NExitCode::kFatalError; + } + catch(int v) + { + AString e ("Error: "); + e.Add_UInt32((unsigned)v); + ErrorMessage(e); + return NExitCode::kFatalError; + } + catch(...) + { + ErrorMessage("Unknown error"); + return NExitCode::kFatalError; + } +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.dsp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.dsp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsp 2024-03-04 19:00:00.000000000 +0000 @@ -0,0 +1,1275 @@ +# Microsoft Developer Studio Project File - Name="GUI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=GUI - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak" CFG="GUI - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GUI - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GUI - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /D "Z7_LARGE_PAGES" /FAcs /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zg.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /D "Z7_LARGE_PAGES" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zg.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /D "Z7_LARGE_PAGES" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zg.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zg.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gr /MDd /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "Z7_LANG" /D "Z7_LONG_PATH" /D "Z7_EXTERNAL_CODECS" /D "Z7_DEVICE_FILE" /D "Z7_LARGE_PAGES" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zg.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Util\7zg.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GUI - Win32 Release" +# Name "GUI - Win32 Debug" +# Name "GUI - Win32 ReleaseU" +# Name "GUI - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zG.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\ExtractRes.h +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Bench.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Bench.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\HashCalc.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyMessages.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\BenchmarkDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\BenchmarkDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\BrowseDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\BrowseDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=.\CompressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\CompressDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\EditDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\EditDialog.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ListViewDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\MemDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\MemDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PasswordDialog.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgressDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgressDialog2.h +# End Source File +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=..\FileManager\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\FileManager\SysIconUtils.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=.\GUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\HashGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\HashGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI2.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI2.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\CreateCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilterCoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MethodProps.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MultiOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\PropId.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\UniqBlocks.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\CopyCoder.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c + +!IF "$(CFG)" == "GUI - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrcOpt.c + +!IF "$(CFG)" == "GUI - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zTypes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zVersion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Compiler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.c + +!IF "$(CFG)" == "GUI - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\DllSecur.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Precomp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c + +!IF "$(CFG)" == "GUI - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Common.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynLimBuf.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyWindows.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Static.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Clipboard.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\COM.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ErrorMsg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileLink.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryGlobal.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +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\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\System.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\SystemInfo.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\TimeUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\ItemNameUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp +# End Source File +# Begin Source File + +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 +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IStream.h +# End Source File +# End Group +# End Target +# End Project diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.dsw p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsw --- p7zip-rar-16.02/CPP/7zip/UI/GUI/GUI.dsw 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/GUI.dsw 2002-09-24 15:57:18.000000000 +0000 @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GUI"=.\GUI.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/HashGUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/HashGUI.cpp 2015-11-20 20:40:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.cpp 2024-07-04 18:00:00.000000000 +0000 @@ -1,278 +1,341 @@ -// HashGUI.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/ErrorMsg.h" - -#include "../FileManager/FormatUtils.h" -#include "../FileManager/LangUtils.h" -#include "../FileManager/OverwriteDialogRes.h" -#include "../FileManager/ProgressDialog2.h" -#include "../FileManager/ProgressDialog2Res.h" -#include "../FileManager/PropertyNameRes.h" -#include "../FileManager/resourceGui.h" - -#include "HashGUI.h" - -using namespace NWindows; - -class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI -{ - UInt64 NumFiles; - bool _curIsFolder; - UString FirstFileName; - - HRESULT ProcessVirt(); - -public: - const NWildcard::CCensor *censor; - const CHashOptions *options; - - DECL_EXTERNAL_CODECS_LOC_VARS2; - - CHashCallbackGUI() {} - ~CHashCallbackGUI() { } - - INTERFACE_IHashCallbackUI(;) - - void AddErrorMessage(DWORD systemError, const wchar_t *name) - { - ProgressDialog.Sync.AddError_Code_Name(systemError, name); - } -}; - -static void AddValuePair(UString &s, UINT resourceID, UInt64 value) -{ - AddLangString(s, resourceID); - s.AddAscii(": "); - char sz[32]; - ConvertUInt64ToString(value, sz); - s.AddAscii(sz); - s.Add_LF(); -} - -static void AddSizeValuePair(UString &s, UINT resourceID, UInt64 value) -{ - AddLangString(s, resourceID); - s.AddAscii(": "); - wchar_t sz[32]; - ConvertUInt64ToString(value, sz); - s += MyFormatNew(IDS_FILE_SIZE, sz); - ConvertUInt64ToString(value >> 20, sz); - s.AddAscii(" ("); - s += sz; - s.AddAscii(" MB)"); - s.Add_LF(); -} - -HRESULT CHashCallbackGUI::StartScanning() -{ - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_Status(LangString(IDS_SCANNING)); - return CheckBreak(); -} - -HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) -{ - return ProgressDialog.Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir); -} - -HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError) -{ - AddErrorMessage(systemError, fs2us(path)); - return CheckBreak(); -} - -HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st) -{ - return ScanProgress(st, FString(), false); -} - -HRESULT CHashCallbackGUI::CheckBreak() -{ - return ProgressDialog.Sync.CheckStop(); -} - -HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles) -{ - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_NumFilesTotal(numFiles); - return CheckBreak(); -} - -HRESULT CHashCallbackGUI::SetTotal(UInt64 size) -{ - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_NumBytesTotal(size); - return CheckBreak(); -} - -HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed) -{ - return ProgressDialog.Sync.Set_NumBytesCur(completed); -} - -HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */) -{ - return S_OK; -} - -HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder) -{ - if (NumFiles == 0) - FirstFileName = name; - _curIsFolder = isFolder; - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_FilePath(name, isFolder); - return CheckBreak(); -} - -HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError) -{ - // if (systemError == ERROR_SHARING_VIOLATION) - { - AddErrorMessage(systemError, fs2us(path)); - return S_FALSE; - } - // return systemError; -} - -HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */) -{ - CProgressSync &sync = ProgressDialog.Sync; - if (!_curIsFolder) - NumFiles++; - sync.Set_NumFilesCur(NumFiles); - return CheckBreak(); -} - -static void AddHashString(UString &s, const CHasherState &h, unsigned digestIndex, const wchar_t *title) -{ - s += title; - s.Add_Space(); - char temp[k_HashCalc_DigestSize_Max * 2 + 4]; - AddHashHexToString(temp, h.Digests[digestIndex], h.DigestSize); - s.AddAscii(temp); - s.Add_LF(); -} - -static void AddHashResString(UString &s, const CHasherState &h, unsigned digestIndex, UInt32 resID) -{ - UString s2 = LangString(resID); - UString name; - name.SetFromAscii(h.Name); - s2.Replace(L"CRC", name); - AddHashString(s, h, digestIndex, s2); -} - -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName) -{ - if (hb.NumErrors != 0) - { - AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors); - s.Add_LF(); - } - - if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty()) - { - AddLangString(s, IDS_PROP_NAME); - s.AddAscii(": "); - s += firstFileName; - s.Add_LF(); - } - else - { - AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); - AddValuePair(s, IDS_PROP_FILES, hb.NumFiles); - } - - AddSizeValuePair(s, IDS_PROP_SIZE, hb.FilesSize); - - if (hb.NumAltStreams != 0) - { - s.Add_LF(); - AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams); - AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize); - } - - if (hb.NumErrors == 0 && hb.Hashers.IsEmpty()) - { - s.Add_LF(); - AddLangString(s, IDS_MESSAGE_NO_ERRORS); - } - - FOR_VECTOR (i, hb.Hashers) - { - s.Add_LF(); - const CHasherState &h = hb.Hashers[i]; - if (hb.NumFiles == 1 && hb.NumDirs == 0) - { - s.AddAscii(h.Name); - AddHashString(s, h, k_HashCalc_Index_DataSum, L":"); - } - else - { - AddHashResString(s, h, k_HashCalc_Index_DataSum, IDS_CHECKSUM_CRC_DATA); - AddHashResString(s, h, k_HashCalc_Index_NamesSum, IDS_CHECKSUM_CRC_DATA_NAMES); - } - if (hb.NumAltStreams != 0) - { - AddHashResString(s, h, k_HashCalc_Index_StreamsSum, IDS_CHECKSUM_CRC_STREAMS_NAMES); - } - } -} - -HRESULT CHashCallbackGUI::AfterLastFile(const CHashBundle &hb) -{ - UString s; - AddHashBundleRes(s, hb, FirstFileName); - - CProgressSync &sync = ProgressDialog.Sync; - sync.Set_NumFilesCur(hb.NumFiles); - - CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0); - pair.Message = s; - LangString(IDS_CHECKSUM_INFORMATION, pair.Title); - - return S_OK; -} - -HRESULT CHashCallbackGUI::ProcessVirt() -{ - NumFiles = 0; - - AString errorInfo; - HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS - *censor, *options, errorInfo, this); - - return res; -} - -HRESULT HashCalcGUI( - DECL_EXTERNAL_CODECS_LOC_VARS - const NWildcard::CCensor &censor, - const CHashOptions &options, - bool &messageWasDisplayed) -{ - CHashCallbackGUI t; - #ifdef EXTERNAL_CODECS - t.__externalCodecs = __externalCodecs; - #endif - t.censor = &censor; - t.options = &options; - - t.ProgressDialog.ShowCompressionInfo = false; - - const UString title = LangString(IDS_CHECKSUM_CALCULATING); - - t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE); - t.ProgressDialog.MainAddTitle = title; - t.ProgressDialog.MainAddTitle.Add_Space(); - - RINOK(t.Create(title)); - messageWasDisplayed = t.ThreadFinishedOK && t.ProgressDialog.MessagesDisplayed; - return S_OK; -} +// HashGUI.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/ErrorMsg.h" + +#include "../FileManager/FormatUtils.h" +#include "../FileManager/LangUtils.h" +#include "../FileManager/ListViewDialog.h" +#include "../FileManager/OverwriteDialogRes.h" +#include "../FileManager/ProgressDialog2.h" +#include "../FileManager/ProgressDialog2Res.h" +#include "../FileManager/PropertyNameRes.h" +#include "../FileManager/resourceGui.h" + +#include "HashGUI.h" + +using namespace NWindows; + + + +class CHashCallbackGUI Z7_final: public CProgressThreadVirt, public IHashCallbackUI +{ + UInt64 NumFiles; + bool _curIsFolder; + UString FirstFileName; + // UString MainPath; + + CPropNameValPairs PropNameValPairs; + + HRESULT ProcessVirt() Z7_override; + virtual void ProcessWasFinished_GuiVirt() Z7_override; + +public: + const NWildcard::CCensor *censor; + const CHashOptions *options; + + DECL_EXTERNAL_CODECS_LOC_VARS_DECL + + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IHashCallbackUI) + + /* + void AddErrorMessage(DWORD systemError, const wchar_t *name) + { + Sync.AddError_Code_Name(systemError, name); + } + */ + void AddErrorMessage(HRESULT systemError, const wchar_t *name) + { + Sync.AddError_Code_Name(systemError, name); + } +}; + + +void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) +{ + CProperty &pair = pairs.AddNew(); + AddLangString(pair.Name, resourceID); + char sz[32]; + ConvertUInt64ToString(value, sz); + pair.Value = sz; +} + + +void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) +{ + CProperty &pair = pairs.AddNew(); + LangString(resourceID, pair.Name); + AddSizeValue(pair.Value, value); +} + + +HRESULT CHashCallbackGUI::StartScanning() +{ + CProgressSync &sync = Sync; + sync.Set_Status(LangString(IDS_SCANNING)); + return CheckBreak(); +} + +HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) +{ + return Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir); +} + +HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError) +{ + AddErrorMessage(HRESULT_FROM_WIN32(systemError), fs2us(path)); + return CheckBreak(); +} + +HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st) +{ + return ScanProgress(st, FString(), false); // isDir +} + +HRESULT CHashCallbackGUI::CheckBreak() +{ + return Sync.CheckStop(); +} + +HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles) +{ + CProgressSync &sync = Sync; + sync.Set_NumFilesTotal(numFiles); + return CheckBreak(); +} + +HRESULT CHashCallbackGUI::SetTotal(UInt64 size) +{ + CProgressSync &sync = Sync; + sync.Set_NumBytesTotal(size); + return CheckBreak(); +} + +HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed) +{ + return Sync.Set_NumBytesCur(completed); +} + +HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */) +{ + return S_OK; +} + +HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder) +{ + if (NumFiles == 0) + FirstFileName = name; + _curIsFolder = isFolder; + CProgressSync &sync = Sync; + sync.Set_FilePath(name, isFolder); + return CheckBreak(); +} + +HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError) +{ + // if (systemError == ERROR_SHARING_VIOLATION) + { + AddErrorMessage(HRESULT_FROM_WIN32(systemError), fs2us(path)); + return S_FALSE; + } + // return systemError; +} + +HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */) +{ + CProgressSync &sync = Sync; + if (!_curIsFolder) + NumFiles++; + sync.Set_NumFilesCur(NumFiles); + return CheckBreak(); +} + +static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16; + +static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex) +{ + char temp[k_DigestStringSize]; + h.WriteToString(digestIndex, temp); + s.Value = temp; +} + +static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsigned digestIndex, UInt32 resID) +{ + CProperty &pair = s.AddNew(); + UString &s2 = pair.Name; + LangString(resID, s2); + UString name (h.Name); + s2.Replace(L"CRC", name); + s2.Replace(L":", L""); + AddHashString(pair, h, digestIndex); +} + + +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb) +{ + if (hb.NumErrors != 0) + AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors); + + if (hb.NumFiles == 1 && hb.NumDirs == 0 && !hb.FirstFileName.IsEmpty()) + { + CProperty &pair = s.AddNew(); + LangString(IDS_PROP_NAME, pair.Name); + pair.Value = hb.FirstFileName; + } + else + { + if (!hb.MainName.IsEmpty()) + { + CProperty &pair = s.AddNew(); + LangString(IDS_PROP_NAME, pair.Name); + pair.Value = hb.MainName; + } + if (hb.NumDirs != 0) + AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); + AddValuePair(s, IDS_PROP_FILES, hb.NumFiles); + } + + AddSizeValuePair(s, IDS_PROP_SIZE, hb.FilesSize); + + if (hb.NumAltStreams != 0) + { + AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams); + AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize); + } + + FOR_VECTOR (i, hb.Hashers) + { + const CHasherState &h = hb.Hashers[i]; + if (hb.NumFiles == 1 && hb.NumDirs == 0) + { + CProperty &pair = s.AddNew(); + pair.Name += h.Name; + AddHashString(pair, h, k_HashCalc_Index_DataSum); + } + else + { + AddHashResString(s, h, k_HashCalc_Index_DataSum, IDS_CHECKSUM_CRC_DATA); + AddHashResString(s, h, k_HashCalc_Index_NamesSum, IDS_CHECKSUM_CRC_DATA_NAMES); + } + if (hb.NumAltStreams != 0) + { + AddHashResString(s, h, k_HashCalc_Index_StreamsSum, IDS_CHECKSUM_CRC_STREAMS_NAMES); + } + } +} + + +void AddHashBundleRes(UString &s, const CHashBundle &hb) +{ + CPropNameValPairs pairs; + AddHashBundleRes(pairs, hb); + + FOR_VECTOR (i, pairs) + { + const CProperty &pair = pairs[i]; + s += pair.Name; + s += ": "; + s += pair.Value; + s.Add_LF(); + } + + if (hb.NumErrors == 0 && hb.Hashers.IsEmpty()) + { + s.Add_LF(); + AddLangString(s, IDS_MESSAGE_NO_ERRORS); + s.Add_LF(); + } +} + + +HRESULT CHashCallbackGUI::AfterLastFile(CHashBundle &hb) +{ + hb.FirstFileName = FirstFileName; + // MainPath + AddHashBundleRes(PropNameValPairs, hb); + + CProgressSync &sync = Sync; + sync.Set_NumFilesCur(hb.NumFiles); + + // CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0); + // pair.Message = s; + // LangString(IDS_CHECKSUM_INFORMATION, pair.Title); + + return S_OK; +} + + +HRESULT CHashCallbackGUI::ProcessVirt() +{ + NumFiles = 0; + AString errorInfo; + HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS + *censor, *options, errorInfo, this); + return res; +} + + +HRESULT HashCalcGUI( + DECL_EXTERNAL_CODECS_LOC_VARS + const NWildcard::CCensor &censor, + const CHashOptions &options, + bool &messageWasDisplayed) +{ + CHashCallbackGUI t; + #ifdef Z7_EXTERNAL_CODECS + t._externalCodecs = _externalCodecs; + #endif + t.censor = &censor; + t.options = &options; + + t.ShowCompressionInfo = false; + + const UString title = LangString(IDS_CHECKSUM_CALCULATING); + + t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); + t.MainAddTitle = title; + t.MainAddTitle.Add_Space(); + + RINOK(t.Create(title)) + messageWasDisplayed = t.ThreadFinishedOK && t.MessagesDisplayed; + return S_OK; +} + + +void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd) +{ + CListViewDialog lv; + + FOR_VECTOR (i, propPairs) + { + const CProperty &pair = propPairs[i]; + lv.Strings.Add(pair.Name); + lv.Values.Add(pair.Value); + } + + lv.Title = LangString(IDS_CHECKSUM_INFORMATION); + lv.DeleteIsAllowed = true; + lv.SelectFirst = false; + lv.NumColumns = 2; + + lv.Create(hwnd); +} + + +void ShowHashResults(const CHashBundle &hb, HWND hwnd) +{ + CPropNameValPairs propPairs; + AddHashBundleRes(propPairs, hb); + ShowHashResults(propPairs, hwnd); +} + +void CHashCallbackGUI::ProcessWasFinished_GuiVirt() +{ + if (Result != E_ABORT) + ShowHashResults(PropNameValPairs, *this); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/HashGUI.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/HashGUI.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/HashGUI.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,16 +1,27 @@ -// HashGUI.h - -#ifndef __HASH_GUI_H -#define __HASH_GUI_H - -#include "../Common/HashCalc.h" - -HRESULT HashCalcGUI( - DECL_EXTERNAL_CODECS_LOC_VARS - const NWildcard::CCensor &censor, - const CHashOptions &options, - bool &messageWasDisplayed); - -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName); - -#endif +// HashGUI.h + +#ifndef ZIP7_INC_HASH_GUI_H +#define ZIP7_INC_HASH_GUI_H + +#include "../Common/HashCalc.h" +#include "../Common/Property.h" + +HRESULT HashCalcGUI( + DECL_EXTERNAL_CODECS_LOC_VARS + const NWildcard::CCensor &censor, + const CHashOptions &options, + bool &messageWasDisplayed); + +typedef CObjectVector CPropNameValPairs; + +void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); +void AddSizeValue(UString &s, UInt64 value); +void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); + +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb); +void AddHashBundleRes(UString &s, const CHashBundle &hb); + +void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd); +void ShowHashResults(const CHashBundle &hb, HWND hwnd); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/StdAfx.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.cpp 2006-10-11 06:53:34.000000000 +0000 @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/StdAfx.h 2023-03-06 18:00:00.000000000 +0000 @@ -0,0 +1,6 @@ +// StdAfx.h + +#if _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../FileManager/StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp 2015-06-21 18:28:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp 2024-10-20 15:00:00.000000000 +0000 @@ -1,280 +1,295 @@ -// UpdateCallbackGUI.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" - -#include "../../../Windows/PropVariant.h" - -#include "../FileManager/FormatUtils.h" -#include "../FileManager/LangUtils.h" - -#include "../FileManager/resourceGui.h" - -#include "resource2.h" - -#include "UpdateCallbackGUI.h" - -using namespace NWindows; - -// CUpdateCallbackGUI::~CUpdateCallbackGUI() {} - -void CUpdateCallbackGUI::Init() -{ - CUpdateCallbackGUI2::Init(); - FailedFiles.Clear(); -} - -void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result); - -HRESULT CUpdateCallbackGUI::OpenResult( - const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) -{ - UString s; - OpenResult_GUI(s, codecs, arcLink, name, result); - if (!s.IsEmpty()) - { - ProgressDialog->Sync.AddError_Message(s); - } - - return S_OK; -} - -HRESULT CUpdateCallbackGUI::StartScanning() -{ - CProgressSync &sync = ProgressDialog->Sync; - sync.Set_Status(LangString(IDS_SCANNING)); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::ScanError(const FString &path, DWORD systemError) -{ - FailedFiles.Add(path); - ProgressDialog->Sync.AddError_Code_Name(systemError, fs2us(path)); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::FinishScanning(const CDirItemsStat &st) -{ - CProgressSync &sync = ProgressDialog->Sync; - RINOK(ProgressDialog->Sync.ScanProgress(st.NumFiles + st.NumAltStreams, - st.GetTotalBytes(), FString(), true)); - sync.Set_Status(L""); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool /* updating */) -{ - CProgressSync &sync = ProgressDialog->Sync; - sync.Set_Status(LangString(IDS_PROGRESS_COMPRESSING)); - sync.Set_TitleFileName(name); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::FinishArchive(const CFinishArchiveStat & /* st */) -{ - CProgressSync &sync = ProgressDialog->Sync; - sync.Set_Status(L""); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::CheckBreak() -{ - return ProgressDialog->Sync.CheckStop(); -} - -HRESULT CUpdateCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) -{ - return ProgressDialog->Sync.ScanProgress(st.NumFiles + st.NumAltStreams, - st.GetTotalBytes(), path, isDir); -} - -/* -HRESULT CUpdateCallbackGUI::Finalize() -{ - return S_OK; -} -*/ - -HRESULT CUpdateCallbackGUI::SetNumItems(UInt64 numItems) -{ - ProgressDialog->Sync.Set_NumFilesTotal(numItems); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total) -{ - ProgressDialog->Sync.Set_NumBytesTotal(total); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completed) -{ - return ProgressDialog->Sync.Set_NumBytesCur(completed); -} - -HRESULT CUpdateCallbackGUI::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) -{ - ProgressDialog->Sync.Set_Ratio(inSize, outSize); - return CheckBreak(); -} - -HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool isDir, bool /* isAnti */, UInt32 mode) -{ - return SetOperation_Base(mode, name, isDir); -} - -HRESULT CUpdateCallbackGUI::OpenFileError(const FString &path, DWORD systemError) -{ - FailedFiles.Add(path); - // if (systemError == ERROR_SHARING_VIOLATION) - { - ProgressDialog->Sync.AddError_Code_Name(systemError, fs2us(path)); - return S_FALSE; - } - // return systemError; -} - -HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 /* operationResult */) -{ - NumFiles++; - ProgressDialog->Sync.Set_NumFilesCur(NumFiles); - return S_OK; -} - -void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); - -HRESULT CUpdateCallbackGUI::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) -{ - if (opRes != NArchive::NExtract::NOperationResult::kOK) - { - UString s; - SetExtractErrorMessage(opRes, isEncrypted, name, s); - ProgressDialog->Sync.AddError_Message(s); - } - return S_OK; -} - -HRESULT CUpdateCallbackGUI::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) -{ - return SetOperation_Base(op, name, isDir); -} - -HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) -{ - *password = NULL; - if (passwordIsDefined) - *passwordIsDefined = BoolToInt(PasswordIsDefined); - if (!PasswordIsDefined) - { - if (AskPassword) - { - RINOK(ShowAskPasswordDialog()) - } - } - if (passwordIsDefined) - *passwordIsDefined = BoolToInt(PasswordIsDefined); - return StringToBstr(Password, password); -} - -HRESULT CUpdateCallbackGUI::CryptoGetTextPassword(BSTR *password) -{ - return CryptoGetTextPassword2(NULL, password); -} - -/* -It doesn't work, since main stream waits Dialog -HRESULT CUpdateCallbackGUI::CloseProgress() -{ - ProgressDialog->MyClose(); - return S_OK; -} -*/ - - -HRESULT CUpdateCallbackGUI::Open_CheckBreak() -{ - return ProgressDialog->Sync.CheckStop(); -} - -HRESULT CUpdateCallbackGUI::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) -{ - // if (numFiles != NULL) ProgressDialog->Sync.SetNumFilesTotal(*numFiles); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) -{ - return ProgressDialog->Sync.CheckStop(); -} - -#ifndef _NO_CRYPTO - -HRESULT CUpdateCallbackGUI::Open_CryptoGetTextPassword(BSTR *password) -{ - PasswordWasAsked = true; - return CryptoGetTextPassword2(NULL, password); -} - -/* -HRESULT CUpdateCallbackGUI::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) -{ - passwordIsDefined = PasswordIsDefined; - password = Password; - return S_OK; -} - -bool CUpdateCallbackGUI::Open_WasPasswordAsked() -{ - return PasswordWasAsked; -} - -void CUpdateCallbackGUI::Open_Clear_PasswordWasAsked_Flag() -{ - PasswordWasAsked = false; -} -*/ - -HRESULT CUpdateCallbackGUI::ShowDeleteFile(const wchar_t *name, bool isDir) -{ - return SetOperation_Base(NUpdateNotifyOp::kDelete, name, isDir); -} - -HRESULT CUpdateCallbackGUI::FinishDeletingAfterArchiving() -{ - // ClosePercents2(); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::DeletingAfterArchiving(const FString &path, bool isDir) -{ - return ProgressDialog->Sync.Set_Status2(_lang_Removing, fs2us(path), isDir); -} - -HRESULT CUpdateCallbackGUI::StartOpenArchive(const wchar_t * /* name */) -{ - return S_OK; -} - -HRESULT CUpdateCallbackGUI::ReadingFileError(const FString &path, DWORD systemError) -{ - FailedFiles.Add(path); - ProgressDialog->Sync.AddError_Code_Name(systemError, fs2us(path)); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::WriteSfx(const wchar_t * /* name */, UInt64 /* size */) -{ - CProgressSync &sync = ProgressDialog->Sync; - sync.Set_Status(L"WriteSfx"); - return S_OK; -} - -HRESULT CUpdateCallbackGUI::Open_Finished() -{ - // ClosePercents(); - return S_OK; -} - -#endif +// UpdateCallbackGUI.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/PropVariant.h" + +#include "../FileManager/FormatUtils.h" +#include "../FileManager/LangUtils.h" + +#include "../FileManager/resourceGui.h" + +#include "resource2.h" + +#include "UpdateCallbackGUI.h" + +using namespace NWindows; + +// CUpdateCallbackGUI::~CUpdateCallbackGUI() {} + +void CUpdateCallbackGUI::Init() +{ + CUpdateCallbackGUI2::Init(); + FailedFiles.Clear(); +} + +void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result); + +HRESULT CUpdateCallbackGUI::OpenResult( + const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) +{ + UString s; + OpenResult_GUI(s, codecs, arcLink, name, result); + if (!s.IsEmpty()) + { + ProgressDialog->Sync.AddError_Message(s); + } + + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartScanning() +{ + CProgressSync &sync = ProgressDialog->Sync; + sync.Set_Status(LangString(IDS_SCANNING)); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::ScanError(const FString &path, DWORD systemError) +{ + FailedFiles.Add(path); + ProgressDialog->Sync.AddError_Code_Name(HRESULT_FROM_WIN32(systemError), fs2us(path)); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishScanning(const CDirItemsStat &st) +{ + CProgressSync &sync = ProgressDialog->Sync; + RINOK(ProgressDialog->Sync.ScanProgress(st.NumFiles + st.NumAltStreams, + st.GetTotalBytes(), FString(), true)) + sync.Set_Status(L""); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool /* updating */) +{ + CProgressSync &sync = ProgressDialog->Sync; + sync.Set_Status(LangString(IDS_PROGRESS_COMPRESSING)); + sync.Set_TitleFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishArchive(const CFinishArchiveStat & /* st */) +{ + CProgressSync &sync = ProgressDialog->Sync; + sync.Set_Status(L""); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CheckBreak() +{ + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CUpdateCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) +{ + return ProgressDialog->Sync.ScanProgress(st.NumFiles + st.NumAltStreams, + st.GetTotalBytes(), path, isDir); +} + +/* +HRESULT CUpdateCallbackGUI::Finalize() +{ + return S_OK; +} +*/ + +HRESULT CUpdateCallbackGUI::SetNumItems(const CArcToDoStat &stat) +{ + ProgressDialog->Sync.Set_NumFilesTotal(stat.Get_NumDataItems_Total()); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total) +{ + ProgressDialog->Sync.Set_NumBytesTotal(total); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completed) +{ + return ProgressDialog->Sync.Set_NumBytesCur(completed); +} + +HRESULT CUpdateCallbackGUI::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + ProgressDialog->Sync.Set_Ratio(inSize, outSize); + return CheckBreak(); +} + +HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool isDir, bool /* isAnti */, UInt32 mode) +{ + return SetOperation_Base(mode, name, isDir); +} + +HRESULT CUpdateCallbackGUI::OpenFileError(const FString &path, DWORD systemError) +{ + FailedFiles.Add(path); + // if (systemError == ERROR_SHARING_VIOLATION) + { + ProgressDialog->Sync.AddError_Code_Name(HRESULT_FROM_WIN32(systemError), fs2us(path)); + return S_FALSE; + } + // return systemError; +} + +HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 /* operationResult */) +{ + NumFiles++; + ProgressDialog->Sync.Set_NumFilesCur(NumFiles); + return S_OK; +} + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s); + +HRESULT CUpdateCallbackGUI::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + UString s; + SetExtractErrorMessage(opRes, isEncrypted, name, s); + ProgressDialog->Sync.AddError_Message(s); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir) +{ + return SetOperation_Base(op, name, isDir); +} + +HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + *password = NULL; + if (passwordIsDefined) + *passwordIsDefined = BoolToInt(PasswordIsDefined); + if (!PasswordIsDefined) + { + if (AskPassword) + { + RINOK(ShowAskPasswordDialog()) + } + } + if (passwordIsDefined) + *passwordIsDefined = BoolToInt(PasswordIsDefined); + return StringToBstr(Password, password); +} + +HRESULT CUpdateCallbackGUI::CryptoGetTextPassword(BSTR *password) +{ + return CryptoGetTextPassword2(NULL, password); +} + +/* +It doesn't work, since main stream waits Dialog +HRESULT CUpdateCallbackGUI::CloseProgress() +{ + ProgressDialog->MyClose(); + return S_OK; +} +*/ + + +HRESULT CUpdateCallbackGUI::Open_CheckBreak() +{ + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CUpdateCallbackGUI::Open_SetTotal(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) +{ + // if (numFiles != NULL) ProgressDialog->Sync.SetNumFilesTotal(*numFiles); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::Open_SetCompleted(const UInt64 * /* numFiles */, const UInt64 * /* numBytes */) +{ + return ProgressDialog->Sync.CheckStop(); +} + +#ifndef Z7_NO_CRYPTO + +HRESULT CUpdateCallbackGUI::Open_CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + return CryptoGetTextPassword2(NULL, password); +} + +/* +HRESULT CUpdateCallbackGUI::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) +{ + passwordIsDefined = PasswordIsDefined; + password = Password; + return S_OK; +} + +bool CUpdateCallbackGUI::Open_WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void CUpdateCallbackGUI::Open_Clear_PasswordWasAsked_Flag() +{ + PasswordWasAsked = false; +} +*/ + +HRESULT CUpdateCallbackGUI::ShowDeleteFile(const wchar_t *name, bool isDir) +{ + return SetOperation_Base(NUpdateNotifyOp::kDelete, name, isDir); +} + +HRESULT CUpdateCallbackGUI::FinishDeletingAfterArchiving() +{ + // ClosePercents2(); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::DeletingAfterArchiving(const FString &path, bool isDir) +{ + return ProgressDialog->Sync.Set_Status2(_lang_Removing, fs2us(path), isDir); +} + + +HRESULT CUpdateCallbackGUI::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode) +{ + return MoveArc_Start_Base(srcTempPath, destFinalPath, totalSize, updateMode); +} +HRESULT CUpdateCallbackGUI::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize) +{ + return MoveArc_Progress_Base(totalSize, currentSize); +} +HRESULT CUpdateCallbackGUI::MoveArc_Finish() +{ + return MoveArc_Finish_Base(); +} + + +HRESULT CUpdateCallbackGUI::StartOpenArchive(const wchar_t * /* name */) +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::ReadingFileError(const FString &path, DWORD systemError) +{ + FailedFiles.Add(path); + ProgressDialog->Sync.AddError_Code_Name(HRESULT_FROM_WIN32(systemError), fs2us(path)); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::WriteSfx(const wchar_t * /* name */, UInt64 /* size */) +{ + CProgressSync &sync = ProgressDialog->Sync; + sync.Set_Status(L"WriteSfx"); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::Open_Finished() +{ + // ClosePercents(); + return S_OK; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI.h 2023-04-01 09:00:00.000000000 +0000 @@ -1,34 +1,31 @@ -// UpdateCallbackGUI.h - -#ifndef __UPDATE_CALLBACK_GUI_H -#define __UPDATE_CALLBACK_GUI_H - -#include "../Common/Update.h" -#include "../Common/ArchiveOpenCallback.h" - -#include "UpdateCallbackGUI2.h" - -class CUpdateCallbackGUI: - public IOpenCallbackUI, - public IUpdateCallbackUI2, - public CUpdateCallbackGUI2 -{ -public: - // CUpdateCallbackGUI(); - // ~CUpdateCallbackGUI(); - - bool AskPassword; - - void Init(); - - CUpdateCallbackGUI(): - AskPassword(false) - {} - - INTERFACE_IUpdateCallbackUI2(;) - INTERFACE_IOpenCallbackUI(;) - - FStringVector FailedFiles; -}; - -#endif +// UpdateCallbackGUI.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_GUI_H +#define ZIP7_INC_UPDATE_CALLBACK_GUI_H + +#include "../Common/Update.h" +#include "../Common/ArchiveOpenCallback.h" + +#include "UpdateCallbackGUI2.h" + +class CUpdateCallbackGUI Z7_final: + public IOpenCallbackUI, + public IUpdateCallbackUI2, + public CUpdateCallbackGUI2 +{ + Z7_IFACE_IMP(IOpenCallbackUI) + Z7_IFACE_IMP(IUpdateCallbackUI) + Z7_IFACE_IMP(IDirItemsCallback) + Z7_IFACE_IMP(IUpdateCallbackUI2) + +public: + bool AskPassword; + FStringVector FailedFiles; + + CUpdateCallbackGUI(): + AskPassword(false) + {} + void Init(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp 2015-06-19 18:38:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp 2024-10-20 09:00:00.000000000 +0000 @@ -1,59 +1,130 @@ -// UpdateCallbackGUI2.cpp - -#include "StdAfx.h" - -#include "../FileManager/LangUtils.h" -#include "../FileManager/PasswordDialog.h" - -#include "resource2.h" -#include "resource3.h" -#include "ExtractRes.h" - -#include "UpdateCallbackGUI.h" - -using namespace NWindows; - -static const UINT k_UpdNotifyLangs[] = -{ - IDS_PROGRESS_ADD, - IDS_PROGRESS_UPDATE, - IDS_PROGRESS_ANALYZE, - IDS_PROGRESS_REPLICATE, - IDS_PROGRESS_REPACK, - IDS_PROGRESS_SKIPPING, - IDS_PROGRESS_DELETE, - IDS_PROGRESS_HEADER -}; - -void CUpdateCallbackGUI2::Init() -{ - NumFiles = 0; - - _lang_Removing = LangString(IDS_PROGRESS_REMOVE); - _lang_Ops.Clear(); - for (unsigned i = 0; i < ARRAY_SIZE(k_UpdNotifyLangs); i++) - _lang_Ops.Add(LangString(k_UpdNotifyLangs[i])); -} - -HRESULT CUpdateCallbackGUI2::SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir) -{ - const UString *s = NULL; - if (notifyOp < _lang_Ops.Size()) - s = &(_lang_Ops[(unsigned)notifyOp]); - else - s = &_emptyString; - - return ProgressDialog->Sync.Set_Status2(*s, name, isDir); -} - - -HRESULT CUpdateCallbackGUI2::ShowAskPasswordDialog() -{ - CPasswordDialog dialog; - ProgressDialog->WaitCreating(); - if (dialog.Create(*ProgressDialog) != IDOK) - return E_ABORT; - Password = dialog.Password; - PasswordIsDefined = true; - return S_OK; -} +// UpdateCallbackGUI2.cpp + +#include "StdAfx.h" + +#include "../FileManager/LangUtils.h" +#include "../FileManager/PasswordDialog.h" + +#include "resource2.h" +#include "resource3.h" +#include "ExtractRes.h" +#include "../FileManager/resourceGui.h" + +#include "UpdateCallbackGUI.h" + +using namespace NWindows; + +static const UINT k_UpdNotifyLangs[] = +{ + IDS_PROGRESS_ADD, + IDS_PROGRESS_UPDATE, + IDS_PROGRESS_ANALYZE, + IDS_PROGRESS_REPLICATE, + IDS_PROGRESS_REPACK, + IDS_PROGRESS_SKIPPING, + IDS_PROGRESS_DELETE, + IDS_PROGRESS_HEADER +}; + +void CUpdateCallbackGUI2::Init() +{ + NumFiles = 0; + + LangString(IDS_PROGRESS_REMOVE, _lang_Removing); + LangString(IDS_MOVING, _lang_Moving); + _lang_Ops.Clear(); + for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_UpdNotifyLangs); i++) + _lang_Ops.Add(LangString(k_UpdNotifyLangs[i])); +} + +HRESULT CUpdateCallbackGUI2::SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir) +{ + const UString *s = NULL; + if (notifyOp < _lang_Ops.Size()) + s = &(_lang_Ops[(unsigned)notifyOp]); + else + s = &_emptyString; + + return ProgressDialog->Sync.Set_Status2(*s, name, isDir); +} + + +HRESULT CUpdateCallbackGUI2::ShowAskPasswordDialog() +{ + CPasswordDialog dialog; + ProgressDialog->WaitCreating(); + if (dialog.Create(*ProgressDialog) != IDOK) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + return S_OK; +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_UpdateStatus() +{ + UString s; + s.Add_UInt64(_arcMoving_percents); + s.Add_Char('%'); + + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (totalDefined || _arcMoving_current != 0) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + + s += " : "; + s += _lang_Moving; + s += " : "; + // s.Add_Char('\"'); + s += _arcMoving_name1; + // s.Add_Char('\"'); + return ProgressDialog->Sync.Set_Status2(s, _arcMoving_name2, + false); // isDir +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode) +{ + _arcMoving_percents = 0; + _arcMoving_total = totalSize; + _arcMoving_current = 0; + _arcMoving_updateMode = updateMode; + _arcMoving_name1 = srcTempPath; + _arcMoving_name2 = destFinalPath; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize) +{ + _arcMoving_total = totalSize; + _arcMoving_current = currentSize; + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + if (percents == _arcMoving_percents) + return ProgressDialog->Sync.CheckStop(); + // Sleep(300); // for debug + _arcMoving_percents = percents; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Finish_Base() +{ + return ProgressDialog->Sync.Set_Status2(L"", L"", false); +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h 2015-06-19 18:38:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h 2024-10-20 09:00:00.000000000 +0000 @@ -1,35 +1,53 @@ -// UpdateCallbackGUI2.h - -#ifndef __UPDATE_CALLBACK_GUI2_H -#define __UPDATE_CALLBACK_GUI2_H - -#include "../FileManager/ProgressDialog2.h" - -class CUpdateCallbackGUI2 -{ - UStringVector _lang_Ops; - UString _emptyString; -public: - UString Password; - bool PasswordIsDefined; - bool PasswordWasAsked; - UInt64 NumFiles; - - UString _lang_Removing; - - CUpdateCallbackGUI2(): - PasswordIsDefined(false), - PasswordWasAsked(false), - NumFiles(0) - {} - - // ~CUpdateCallbackGUI2(); - void Init(); - - CProgressDialog *ProgressDialog; - - HRESULT SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir); - HRESULT ShowAskPasswordDialog(); -}; - -#endif +// UpdateCallbackGUI2.h + +#ifndef ZIP7_INC_UPDATE_CALLBACK_GUI2_H +#define ZIP7_INC_UPDATE_CALLBACK_GUI2_H + +#include "../FileManager/ProgressDialog2.h" + +class CUpdateCallbackGUI2 +{ +public: + CProgressDialog *ProgressDialog; +protected: + UString _arcMoving_name1; + UString _arcMoving_name2; + UInt64 _arcMoving_percents; + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + Int32 _arcMoving_updateMode; +public: + bool PasswordIsDefined; + bool PasswordWasAsked; + UInt64 NumFiles; + UString Password; +protected: + UStringVector _lang_Ops; + UString _lang_Removing; + UString _lang_Moving; + UString _emptyString; + + HRESULT MoveArc_UpdateStatus(); + HRESULT MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 /* totalSize */, Int32 updateMode); + HRESULT MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize); + HRESULT MoveArc_Finish_Base(); + +public: + + CUpdateCallbackGUI2(): + _arcMoving_percents(0), + _arcMoving_total(0), + _arcMoving_current(0), + _arcMoving_updateMode(0), + PasswordIsDefined(false), + PasswordWasAsked(false), + NumFiles(0) + {} + + void Init(); + + HRESULT SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir); + HRESULT ShowAskPasswordDialog(); +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateGUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateGUI.cpp 2016-06-11 08:08:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -1,491 +1,605 @@ -// UpdateGUI.cpp - -#include "StdAfx.h" - -#include "../../../Common/IntToString.h" -#include "../../../Common/StringConvert.h" -#include "../../../Common/StringToInt.h" - -#include "../../../Windows/DLL.h" -#include "../../../Windows/FileDir.h" -#include "../../../Windows/FileName.h" -#include "../../../Windows/Thread.h" - -#include "../Common/WorkDir.h" - -#include "../Explorer/MyMessages.h" - -#include "../FileManager/LangUtils.h" -#include "../FileManager/StringUtils.h" -#include "../FileManager/resourceGui.h" - -#include "CompressDialog.h" -#include "UpdateGUI.h" - -#include "resource2.h" - -using namespace NWindows; -using namespace NFile; -using namespace NDir; - -static CFSTR kDefaultSfxModule = FTEXT("7z.sfx"); -static const wchar_t *kSFXExtension = L"exe"; - -extern void AddMessageToString(UString &dest, const UString &src); - -UString HResultToMessage(HRESULT errorCode); - -class CThreadUpdating: public CProgressThreadVirt -{ - HRESULT ProcessVirt(); -public: - CCodecs *codecs; - const CObjectVector *formatIndices; - const UString *cmdArcPath; - CUpdateCallbackGUI *UpdateCallbackGUI; - NWildcard::CCensor *WildcardCensor; - CUpdateOptions *Options; - bool needSetPath; -}; - -HRESULT CThreadUpdating::ProcessVirt() -{ - CUpdateErrorInfo ei; - HRESULT res = UpdateArchive(codecs, *formatIndices, *cmdArcPath, - *WildcardCensor, *Options, - ei, UpdateCallbackGUI, UpdateCallbackGUI, needSetPath); - FinalMessage.ErrorMessage.Message.SetFromAscii(ei.Message); - ErrorPaths = ei.FileNames; - if (ei.SystemError != S_OK && ei.SystemError != E_FAIL && ei.SystemError != E_ABORT) - return ei.SystemError; - return res; -} - -static void AddProp(CObjectVector &properties, const UString &name, const UString &value) -{ - CProperty prop; - prop.Name = name; - prop.Value = value; - properties.Add(prop); -} - -static void AddProp(CObjectVector &properties, const UString &name, UInt32 value) -{ - wchar_t tmp[32]; - ConvertUInt64ToString(value, tmp); - AddProp(properties, name, tmp); -} - -static void AddProp(CObjectVector &properties, const UString &name, bool value) -{ - AddProp(properties, name, value ? UString(L"on"): UString(L"off")); -} - -static bool IsThereMethodOverride(bool is7z, const UString &propertiesString) -{ - UStringVector strings; - SplitString(propertiesString, strings); - FOR_VECTOR (i, strings) - { - const UString &s = strings[i]; - if (is7z) - { - const wchar_t *end; - UInt64 n = ConvertStringToUInt64(s, &end); - if (n == 0 && *end == L'=') - return true; - } - else - { - if (s.Len() > 0) - if (s[0] == L'm' && s[1] == L'=') - return true; - } - } - return false; -} - -static void ParseAndAddPropertires(CObjectVector &properties, - const UString &propertiesString) -{ - UStringVector strings; - SplitString(propertiesString, strings); - FOR_VECTOR (i, strings) - { - const UString &s = strings[i]; - CProperty property; - int index = s.Find(L'='); - if (index < 0) - property.Name = s; - else - { - property.Name.SetFrom(s, index); - property.Value = s.Ptr(index + 1); - } - properties.Add(property); - } -} - -static UString GetNumInBytesString(UInt64 v) -{ - wchar_t s[32]; - ConvertUInt64ToString(v, s); - size_t len = wcslen(s); - s[len++] = L'B'; - s[len] = L'\0'; - return s; -} - -static void SetOutProperties( - CObjectVector &properties, - bool is7z, - UInt32 level, - bool setMethod, - const UString &method, - UInt32 dictionary, - bool orderMode, - UInt32 order, - bool solidIsSpecified, UInt64 solidBlockSize, - bool multiThreadIsAllowed, UInt32 numThreads, - const UString &encryptionMethod, - bool encryptHeadersIsAllowed, bool encryptHeaders, - bool /* sfxMode */) -{ - if (level != (UInt32)(Int32)-1) - AddProp(properties, L"x", (UInt32)level); - if (setMethod) - { - if (!method.IsEmpty()) - AddProp(properties, is7z ? L"0": L"m", method); - if (dictionary != (UInt32)(Int32)-1) - { - UString name; - if (is7z) - name = L"0"; - if (orderMode) - name += L"mem"; - else - name += L"d"; - AddProp(properties, name, GetNumInBytesString(dictionary)); - } - if (order != (UInt32)(Int32)-1) - { - UString name; - if (is7z) - name = L"0"; - if (orderMode) - name += L"o"; - else - name += L"fb"; - AddProp(properties, name, (UInt32)order); - } - } - - if (!encryptionMethod.IsEmpty()) - AddProp(properties, L"em", encryptionMethod); - - if (encryptHeadersIsAllowed) - AddProp(properties, L"he", encryptHeaders); - if (solidIsSpecified) - AddProp(properties, L"s", GetNumInBytesString(solidBlockSize)); - if (multiThreadIsAllowed) - AddProp(properties, L"mt", numThreads); -} - -struct C_UpdateMode_ToAction_Pair -{ - NCompressDialog::NUpdateMode::EEnum UpdateMode; - const NUpdateArchive::CActionSet *ActionSet; -}; - -static const C_UpdateMode_ToAction_Pair g_UpdateMode_Pairs[] = -{ - { NCompressDialog::NUpdateMode::kAdd, &NUpdateArchive::k_ActionSet_Add }, - { NCompressDialog::NUpdateMode::kUpdate, &NUpdateArchive::k_ActionSet_Update }, - { NCompressDialog::NUpdateMode::kFresh, &NUpdateArchive::k_ActionSet_Fresh }, - { NCompressDialog::NUpdateMode::kSync, &NUpdateArchive::k_ActionSet_Sync } -}; - -static int FindActionSet(const NUpdateArchive::CActionSet &actionSet) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_UpdateMode_Pairs); i++) - if (actionSet.IsEqualTo(*g_UpdateMode_Pairs[i].ActionSet)) - return i; - return -1; -} - -static int FindUpdateMode(NCompressDialog::NUpdateMode::EEnum mode) -{ - for (unsigned i = 0; i < ARRAY_SIZE(g_UpdateMode_Pairs); i++) - if (mode == g_UpdateMode_Pairs[i].UpdateMode) - return i; - return -1; -} - - -static HRESULT ShowDialog( - CCodecs *codecs, - const CObjectVector &censor, - CUpdateOptions &options, - CUpdateCallbackGUI *callback, HWND hwndParent) -{ - if (options.Commands.Size() != 1) - throw "It must be one command"; - /* - FString currentDirPrefix; - #ifndef UNDER_CE - { - if (!MyGetCurrentDirectory(currentDirPrefix)) - return E_FAIL; - NName::NormalizeDirPathPrefix(currentDirPrefix); - } - #endif - */ - - bool oneFile = false; - NFind::CFileInfo fileInfo; - UString name; - - /* - if (censor.Pairs.Size() > 0) - { - const NWildcard::CPair &pair = censor.Pairs[0]; - if (pair.Head.IncludeItems.Size() > 0) - { - const NWildcard::CItem &item = pair.Head.IncludeItems[0]; - if (item.ForFile) - { - name = pair.Prefix; - FOR_VECTOR (i, item.PathParts) - { - if (i > 0) - name.Add_PathSepar(); - name += item.PathParts[i]; - } - if (fileInfo.Find(us2fs(name))) - { - if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) - oneFile = !fileInfo.IsDir(); - } - } - } - } - */ - if (censor.Size() > 0) - { - const NWildcard::CCensorPath &cp = censor[0]; - if (cp.Include) - { - { - if (fileInfo.Find(us2fs(cp.Path))) - { - if (censor.Size() == 1) - oneFile = !fileInfo.IsDir(); - } - } - } - } - - - #if defined(_WIN32) && !defined(UNDER_CE) - CCurrentDirRestorer curDirRestorer; - #endif - CCompressDialog dialog; - NCompressDialog::CInfo &di = dialog.Info; - dialog.ArcFormats = &codecs->Formats; - - if (options.MethodMode.Type_Defined) - di.FormatIndex = options.MethodMode.Type.FormatIndex; - - FOR_VECTOR (i, codecs->Formats) - { - const CArcInfoEx &ai = codecs->Formats[i]; - if (!ai.UpdateEnabled) - continue; - if (!oneFile && ai.Flags_KeepName()) - continue; - if ((int)i != di.FormatIndex) - if (ai.Name.IsEqualTo_Ascii_NoCase("swfc")) - if (!oneFile || name.Len() < 4 || !StringsAreEqualNoCase_Ascii(name.RightPtr(4), ".swf")) - continue; - dialog.ArcIndices.Add(i); - } - if (dialog.ArcIndices.IsEmpty()) - { - ShowErrorMessage(L"No Update Engines"); - return E_FAIL; - } - - // di.ArchiveName = options.ArchivePath.GetFinalPath(); - di.ArcPath = options.ArchivePath.GetPathWithoutExt(); - dialog.OriginalFileName = fs2us(fileInfo.Name); - - di.PathMode = options.PathMode; - - // di.CurrentDirPrefix = currentDirPrefix; - di.SFXMode = options.SfxMode; - di.OpenShareForWrite = options.OpenShareForWrite; - di.DeleteAfterCompressing = options.DeleteAfterCompressing; - - di.SymLinks = options.SymLinks; - di.HardLinks = options.HardLinks; - di.AltStreams = options.AltStreams; - di.NtSecurity = options.NtSecurity; - - if (callback->PasswordIsDefined) - di.Password = callback->Password; - - di.KeepName = !oneFile; - - NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; - - { - int index = FindActionSet(actionSet); - if (index < 0) - return E_NOTIMPL; - di.UpdateMode = g_UpdateMode_Pairs[(unsigned)index].UpdateMode; - } - - if (dialog.Create(hwndParent) != IDOK) - return E_ABORT; - - options.DeleteAfterCompressing = di.DeleteAfterCompressing; - - options.SymLinks = di.SymLinks; - options.HardLinks = di.HardLinks; - options.AltStreams = di.AltStreams; - options.NtSecurity = di.NtSecurity; - - #if defined(_WIN32) && !defined(UNDER_CE) - curDirRestorer.NeedRestore = dialog.CurrentDirWasChanged; - #endif - - options.VolumesSizes = di.VolumeSizes; - /* - if (di.VolumeSizeIsDefined) - { - MyMessageBox(L"Splitting to volumes is not supported"); - return E_FAIL; - } - */ - - - { - int index = FindUpdateMode(di.UpdateMode); - if (index < 0) - return E_FAIL; - actionSet = *g_UpdateMode_Pairs[index].ActionSet; - } - - options.PathMode = di.PathMode; - - const CArcInfoEx &archiverInfo = codecs->Formats[di.FormatIndex]; - callback->PasswordIsDefined = (!di.Password.IsEmpty()); - if (callback->PasswordIsDefined) - callback->Password = di.Password; - - options.MethodMode.Properties.Clear(); - - bool is7z = archiverInfo.Name.IsEqualTo_Ascii_NoCase("7z"); - bool methodOverride = IsThereMethodOverride(is7z, di.Options); - - SetOutProperties( - options.MethodMode.Properties, - is7z, - di.Level, - !methodOverride, - di.Method, - di.Dictionary, - di.OrderMode, di.Order, - di.SolidIsSpecified, di.SolidBlockSize, - di.MultiThreadIsAllowed, di.NumThreads, - di.EncryptionMethod, - di.EncryptHeadersIsAllowed, di.EncryptHeaders, - di.SFXMode); - - options.OpenShareForWrite = di.OpenShareForWrite; - ParseAndAddPropertires(options.MethodMode.Properties, di.Options); - - if (di.SFXMode) - options.SfxMode = true; - options.MethodMode.Type = COpenType(); - options.MethodMode.Type_Defined = true; - options.MethodMode.Type.FormatIndex = di.FormatIndex; - - options.ArchivePath.VolExtension = archiverInfo.GetMainExt(); - if (di.SFXMode) - options.ArchivePath.BaseExtension = kSFXExtension; - else - options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; - options.ArchivePath.ParseFromPath(di.ArcPath, k_ArcNameMode_Smart); - - NWorkDir::CInfo workDirInfo; - workDirInfo.Load(); - options.WorkingDir.Empty(); - if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) - { - FString fullPath; - MyGetFullPathName(us2fs(di.ArcPath), fullPath); - FString namePart; - options.WorkingDir = GetWorkDir(workDirInfo, fullPath, namePart); - CreateComplexDir(options.WorkingDir); - } - return S_OK; -} - -HRESULT UpdateGUI( - CCodecs *codecs, - const CObjectVector &formatIndices, - const UString &cmdArcPath, - NWildcard::CCensor &censor, - CUpdateOptions &options, - bool showDialog, - bool &messageWasDisplayed, - CUpdateCallbackGUI *callback, - HWND hwndParent) -{ - messageWasDisplayed = false; - bool needSetPath = true; - if (showDialog) - { - RINOK(ShowDialog(codecs, censor.CensorPaths, options, callback, hwndParent)); - needSetPath = false; - } - if (options.SfxMode && options.SfxModule.IsEmpty()) - { - FString folder = NWindows::NDLL::GetModuleDirPrefix(); - options.SfxModule = folder + kDefaultSfxModule; - } - - CThreadUpdating tu; - - tu.needSetPath = needSetPath; - - tu.codecs = codecs; - tu.formatIndices = &formatIndices; - tu.cmdArcPath = &cmdArcPath; - - tu.UpdateCallbackGUI = callback; - tu.UpdateCallbackGUI->ProgressDialog = &tu.ProgressDialog; - tu.UpdateCallbackGUI->Init(); - - UString title = LangString(IDS_PROGRESS_COMPRESSING); - - /* - if (hwndParent != 0) - { - tu.ProgressDialog.MainWindow = hwndParent; - // tu.ProgressDialog.MainTitle = fileName; - tu.ProgressDialog.MainAddTitle = title + L' '; - } - */ - - tu.WildcardCensor = &censor; - tu.Options = &options; - tu.ProgressDialog.IconID = IDI_ICON; - - RINOK(tu.Create(title, hwndParent)); - - messageWasDisplayed = tu.ThreadFinishedOK && tu.ProgressDialog.MessagesDisplayed; - return tu.Result; -} +// UpdateGUI.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../../Windows/DLL.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/Thread.h" + +#include "../Common/WorkDir.h" + +#include "../Explorer/MyMessages.h" + +#include "../FileManager/LangUtils.h" +#include "../FileManager/StringUtils.h" +#include "../FileManager/resourceGui.h" + +#include "CompressDialog.h" +#include "UpdateGUI.h" + +#include "resource2.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDir; + +static const char * const kDefaultSfxModule = "7z.sfx"; +static const char * const kSFXExtension = "exe"; + +extern void AddMessageToString(UString &dest, const UString &src); + +UString HResultToMessage(HRESULT errorCode); + +class CThreadUpdating: public CProgressThreadVirt +{ + HRESULT ProcessVirt() Z7_override; +public: + CCodecs *codecs; + const CObjectVector *formatIndices; + const UString *cmdArcPath; + CUpdateCallbackGUI *UpdateCallbackGUI; + NWildcard::CCensor *WildcardCensor; + CUpdateOptions *Options; + bool needSetPath; +}; + +HRESULT CThreadUpdating::ProcessVirt() +{ + CUpdateErrorInfo ei; + HRESULT res = UpdateArchive(codecs, *formatIndices, *cmdArcPath, + *WildcardCensor, *Options, + ei, UpdateCallbackGUI, UpdateCallbackGUI, needSetPath); + FinalMessage.ErrorMessage.Message = ei.Message.Ptr(); + ErrorPaths = ei.FileNames; + if (res != S_OK) + return res; + 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; + prop.Name = name; + prop.Value = value; + properties.Add(prop); +} + +static void AddProp_UInt32(CObjectVector &properties, const char *name, UInt32 value) +{ + UString s; + s.Add_UInt32(value); + AddProp_UString(properties, name, s); +} + +static void AddProp_bool(CObjectVector &properties, const char *name, bool value) +{ + AddProp_UString(properties, name, UString(value ? "on": "off")); +} + + +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) +{ + FOR_VECTOR (i, strings) + { + const UString &s = strings[i]; + if (is7z) + { + const wchar_t *end; + UInt64 n = ConvertStringToUInt64(s, &end); + if (n == 0 && *end == L'=') + return true; + } + else + { + if (s.Len() > 0) + if (s[0] == L'm' && s[1] == L'=') + return true; + } + } + return false; +} + +static void ParseAndAddPropertires(CObjectVector &properties, + const UStringVector &strings) +{ + FOR_VECTOR (i, strings) + { + const UString &s = strings[i]; + CProperty property; + const int index = s.Find(L'='); + if (index < 0) + property.Name = s; + else + { + property.Name.SetFrom(s, (unsigned)index); + property.Value = s.Ptr(index + 1); + } + properties.Add(property); + } +} + + +static void AddProp_Size(CObjectVector &properties, const char *name, const UInt64 size) +{ + UString s; + s.Add_UInt64(size); + s.Add_Char('b'); + AddProp_UString(properties, name, s); +} + + +static void SetOutProperties( + CObjectVector &properties, + const NCompressDialog::CInfo &di, + bool is7z, + bool setMethod) +{ + if (di.Level != (UInt32)(Int32)-1) + AddProp_UInt32(properties, "x", (UInt32)di.Level); + if (setMethod) + { + 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 += (di.OrderMode ? "mem" : "d"); + AddProp_Size(properties, name, di.Dict64); + } + /* + if (di.Dict64_Chain != (UInt64)(Int64)-1) + { + AString name; + if (is7z) + name = "0"; + name += "dc"; + AddProp_Size(properties, name, di.Dict64_Chain); + } + */ + if (di.Order != (UInt32)(Int32)-1) + { + AString name; + if (is7z) + name = "0"; + name += (di.OrderMode ? "o" : "fb"); + AddProp_UInt32(properties, name, (UInt32)di.Order); + } + } + + if (!di.EncryptionMethod.IsEmpty()) + AddProp_UString(properties, "em", di.EncryptionMethod); + + if (di.EncryptHeadersIsAllowed) + AddProp_bool(properties, "he", di.EncryptHeaders); + + if (di.SolidIsSpecified) + AddProp_Size(properties, "s", di.SolidBlockSize); + + if ( + // 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"; + if (memUse.IsPercent) + { + UString s; + // s += 'p'; // for debug: alternate percent method + s.Add_UInt64(memUse.Val); + s.Add_Char('%'); + AddProp_UString(properties, kMemUse, s); + } + 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; + const NUpdateArchive::CActionSet *ActionSet; +}; + +static const C_UpdateMode_ToAction_Pair g_UpdateMode_Pairs[] = +{ + { NCompressDialog::NUpdateMode::kAdd, &NUpdateArchive::k_ActionSet_Add }, + { NCompressDialog::NUpdateMode::kUpdate, &NUpdateArchive::k_ActionSet_Update }, + { NCompressDialog::NUpdateMode::kFresh, &NUpdateArchive::k_ActionSet_Fresh }, + { NCompressDialog::NUpdateMode::kSync, &NUpdateArchive::k_ActionSet_Sync } +}; + +static int FindActionSet(const NUpdateArchive::CActionSet &actionSet) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_UpdateMode_Pairs); i++) + if (actionSet.IsEqualTo(*g_UpdateMode_Pairs[i].ActionSet)) + return (int)i; + return -1; +} + +static int FindUpdateMode(NCompressDialog::NUpdateMode::EEnum mode) +{ + for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_UpdateMode_Pairs); i++) + if (mode == g_UpdateMode_Pairs[i].UpdateMode) + return (int)i; + return -1; +} + + +static HRESULT ShowDialog( + CCodecs *codecs, + const CObjectVector &censor, + CUpdateOptions &options, + CUpdateCallbackGUI *callback, HWND hwndParent) +{ + if (options.Commands.Size() != 1) + throw "It must be one command"; + /* + FString currentDirPrefix; + #ifndef UNDER_CE + { + if (!MyGetCurrentDirectory(currentDirPrefix)) + return E_FAIL; + NName::NormalizeDirPathPrefix(currentDirPrefix); + } + #endif + */ + + bool oneFile = false; + NFind::CFileInfo fileInfo; + UString name; + + /* + if (censor.Pairs.Size() > 0) + { + const NWildcard::CPair &pair = censor.Pairs[0]; + if (pair.Head.IncludeItems.Size() > 0) + { + const NWildcard::CItem &item = pair.Head.IncludeItems[0]; + if (item.ForFile) + { + name = pair.Prefix; + FOR_VECTOR (i, item.PathParts) + { + if (i > 0) + name.Add_PathSepar(); + name += item.PathParts[i]; + } + if (fileInfo.Find(us2fs(name))) + { + if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) + oneFile = !fileInfo.IsDir(); + } + } + } + } + */ + if (censor.Size() > 0) + { + const NWildcard::CCensorPath &cp = censor[0]; + if (cp.Include) + { + { + if (fileInfo.Find(us2fs(cp.Path))) + { + if (censor.Size() == 1) + oneFile = !fileInfo.IsDir(); + } + } + } + } + + + /* + // v23: we restore current dir in dialog code + #if defined(_WIN32) && !defined(UNDER_CE) + CCurrentDirRestorer curDirRestorer; + #endif + */ + + CCompressDialog dialog; + NCompressDialog::CInfo &di = dialog.Info; + dialog.ArcFormats = &codecs->Formats; + { + CObjectVector userCodecs; + codecs->Get_CodecsInfoUser_Vector(userCodecs); + dialog.SetMethods(userCodecs); + } + + if (options.MethodMode.Type_Defined) + di.FormatIndex = options.MethodMode.Type.FormatIndex; + + FOR_VECTOR (i, codecs->Formats) + { + const CArcInfoEx &ai = codecs->Formats[i]; + if (!ai.UpdateEnabled) + continue; + if (!oneFile && ai.Flags_KeepName()) + continue; + if ((int)i != di.FormatIndex) + { + if (ai.Flags_HashHandler()) + continue; + if (ai.Name.IsEqualTo_Ascii_NoCase("swfc")) + if (!oneFile || name.Len() < 4 || !StringsAreEqualNoCase_Ascii(name.RightPtr(4), ".swf")) + continue; + } + dialog.ArcIndices.Add(i); + } + if (dialog.ArcIndices.IsEmpty()) + { + ShowErrorMessage(L"No Update Engines"); + return E_FAIL; + } + + // di.ArchiveName = options.ArchivePath.GetFinalPath(); + di.ArcPath = options.ArchivePath.GetPathWithoutExt(); + dialog.OriginalFileName = fs2us(fileInfo.Name); + + di.PathMode = options.PathMode; + + // di.CurrentDirPrefix = currentDirPrefix; + di.SFXMode = options.SfxMode; + di.OpenShareForWrite = options.OpenShareForWrite; + di.DeleteAfterCompressing = options.DeleteAfterCompressing; + + di.SymLinks = options.SymLinks; + 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; + + di.KeepName = !oneFile; + + NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; + + { + int index = FindActionSet(actionSet); + if (index < 0) + return E_NOTIMPL; + di.UpdateMode = g_UpdateMode_Pairs[(unsigned)index].UpdateMode; + } + + ParseProperties(options.MethodMode.Properties, di); + + if (dialog.Create(hwndParent) != IDOK) + return E_ABORT; + + options.DeleteAfterCompressing = di.DeleteAfterCompressing; + + options.SymLinks = di.SymLinks; + 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; + #endif + */ + + options.VolumesSizes = di.VolumeSizes; + /* + if (di.VolumeSizeIsDefined) + { + MyMessageBox(L"Splitting to volumes is not supported"); + return E_FAIL; + } + */ + + + { + int index = FindUpdateMode(di.UpdateMode); + if (index < 0) + return E_FAIL; + actionSet = *g_UpdateMode_Pairs[index].ActionSet; + } + + options.PathMode = di.PathMode; + + const CArcInfoEx &archiverInfo = codecs->Formats[di.FormatIndex]; + callback->PasswordIsDefined = (!di.Password.IsEmpty()); + if (callback->PasswordIsDefined) + callback->Password = di.Password; + + // we clear command line options, and fill options form Dialog + options.MethodMode.Properties.Clear(); + + const bool is7z = archiverInfo.Is_7z(); + + UStringVector optionStrings; + SplitOptionsToStrings(di.Options, optionStrings); + const bool methodOverride = IsThereMethodOverride(is7z, optionStrings); + + SetOutProperties(options.MethodMode.Properties, di, + is7z, + !methodOverride); // setMethod + + options.OpenShareForWrite = di.OpenShareForWrite; + ParseAndAddPropertires(options.MethodMode.Properties, optionStrings); + + if (di.SFXMode) + options.SfxMode = true; + options.MethodMode.Type = COpenType(); + options.MethodMode.Type_Defined = true; + options.MethodMode.Type.FormatIndex = di.FormatIndex; + + options.ArchivePath.VolExtension = archiverInfo.GetMainExt(); + if (di.SFXMode) + options.ArchivePath.BaseExtension = kSFXExtension; + else + options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; + options.ArchivePath.ParseFromPath(di.ArcPath, k_ArcNameMode_Smart); + + NWorkDir::CInfo workDirInfo; + workDirInfo.Load(); + options.WorkingDir.Empty(); + if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) + { + FString fullPath; + MyGetFullPathName(us2fs(di.ArcPath), fullPath); + FString namePart; + options.WorkingDir = GetWorkDir(workDirInfo, fullPath, namePart); + CreateComplexDir(options.WorkingDir); + } + return S_OK; +} + +HRESULT UpdateGUI( + CCodecs *codecs, + const CObjectVector &formatIndices, + const UString &cmdArcPath, + NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + bool &messageWasDisplayed, + CUpdateCallbackGUI *callback, + HWND hwndParent) +{ + messageWasDisplayed = false; + bool needSetPath = true; + if (showDialog) + { + RINOK(ShowDialog(codecs, censor.CensorPaths, options, callback, hwndParent)) + needSetPath = false; + } + if (options.SfxMode && options.SfxModule.IsEmpty()) + { + options.SfxModule = NWindows::NDLL::GetModuleDirPrefix(); + options.SfxModule += kDefaultSfxModule; + } + + CThreadUpdating tu; + + tu.needSetPath = needSetPath; + + tu.codecs = codecs; + tu.formatIndices = &formatIndices; + tu.cmdArcPath = &cmdArcPath; + + tu.UpdateCallbackGUI = callback; + tu.UpdateCallbackGUI->ProgressDialog = &tu; + tu.UpdateCallbackGUI->Init(); + + UString title = LangString(IDS_PROGRESS_COMPRESSING); + if (!formatIndices.IsEmpty()) + { + const int fin = formatIndices[0].FormatIndex; + if (fin >= 0) + if (codecs->Formats[fin].Flags_HashHandler()) + title = LangString(IDS_CHECKSUM_CALCULATING); + } + + /* + if (hwndParent != 0) + { + tu.ProgressDialog.MainWindow = hwndParent; + // tu.ProgressDialog.MainTitle = fileName; + tu.ProgressDialog.MainAddTitle = title + L' '; + } + */ + + tu.WildcardCensor = &censor; + tu.Options = &options; + tu.IconID = IDI_ICON; + + RINOK(tu.Create(title, hwndParent)) + + messageWasDisplayed = tu.ThreadFinishedOK && tu.MessagesDisplayed; + return tu.Result; +} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateGUI.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/UpdateGUI.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/UpdateGUI.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,33 +1,33 @@ -// GUI/UpdateGUI.h - -#ifndef __UPDATE_GUI_H -#define __UPDATE_GUI_H - -#include "../Common/Update.h" - -#include "UpdateCallbackGUI.h" - -/* - callback->FailedFiles contains names of files for that there were problems. - RESULT can be S_OK, even if there are such warnings!!! - - RESULT = E_ABORT - user break. - RESULT != E_ABORT: - { - messageWasDisplayed = true - message was displayed already. - messageWasDisplayed = false - there was some internal error, so you must show error message. - } -*/ - -HRESULT UpdateGUI( - CCodecs *codecs, - const CObjectVector &formatIndices, - const UString &cmdArcPath2, - NWildcard::CCensor &censor, - CUpdateOptions &options, - bool showDialog, - bool &messageWasDisplayed, - CUpdateCallbackGUI *callback, - HWND hwndParent = NULL); - -#endif +// GUI/UpdateGUI.h + +#ifndef ZIP7_INC_UPDATE_GUI_H +#define ZIP7_INC_UPDATE_GUI_H + +#include "../Common/Update.h" + +#include "UpdateCallbackGUI.h" + +/* + callback->FailedFiles contains names of files for that there were problems. + RESULT can be S_OK, even if there are such warnings!!! + + RESULT = E_ABORT - user break. + RESULT != E_ABORT: + { + messageWasDisplayed = true - message was displayed already. + messageWasDisplayed = false - there was some internal error, so you must show error message. + } +*/ + +HRESULT UpdateGUI( + CCodecs *codecs, + const CObjectVector &formatIndices, + const UString &cmdArcPath2, + NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + bool &messageWasDisplayed, + CUpdateCallbackGUI *callback, + HWND hwndParent = NULL); + +#endif diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile --- p7zip-rar-16.02/CPP/7zip/UI/GUI/makefile 2015-10-03 20:19:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile 2025-07-01 15:00:00.000000000 +0000 @@ -1,140 +1,149 @@ - -TARGET_FLAGS=`wx-config --unicode=yes --cxxflags` - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LIBS=`wx-config --unicode=yes --libs` $(LOCAL_LIBS_DLL) - -# - -GUI_OBJS = \ - BenchmarkDialog.o \ - BenchmarkDialog_rc.o \ - CompressDialog.o \ - CompressDialog_rc.o \ - ExtractDialog.o \ - ExtractDialog_rc.o \ - GUI.o \ - HashGUI.o \ - ExtractGUI.o \ - UpdateCallbackGUI.o \ - UpdateGUI.o \ - wxGUI.o \ - -COMMON_OBJS = \ -CommandLineParser.o \ -CRC.o \ -IntToString.o \ -NewHandler.o \ -Lang.o \ -ListFileUtils.o \ -MyString.o \ -MyVector.o \ -StringConvert.o \ -StringToInt.o \ -UTFConvert.o \ -Wildcard.o \ - -# CommonDialog.o MemoryLock.o ResourceString.o ResourceString.o Shell.o -WIN_OBJS = \ -DLL.o \ -ErrorMsg.o \ -FileDir.o \ -FileFind.o \ -FileIO.o \ -FileName.o \ -PropVariant.o \ -PropVariantConv.o \ -Registry.o \ -Synchronization.o \ -System.o \ -TimeUtils.o \ -Window.o \ - -WIN_CTRL_OBJS = \ -Dialog.o \ -Controls.o \ - -7ZIP_COMMON_OBJS = \ -CreateCoder.o \ -FilePathAutoRename.o \ -FileStreams.o \ -FilterCoder.o \ -LimitedStreams.o \ -MethodProps.o \ -ProgressUtils.o \ -PropId.o \ -StreamObjects.o \ -StreamUtils.o \ -UniqBlocks.o \ - -UI_COMMON_OBJS = \ -ArchiveCommandLine.o \ -ArchiveExtractCallback.o \ -ArchiveOpenCallback.o \ -Bench.o \ -DefaultName.o \ -EnumDirItems.o \ -Extract.o \ -ExtractingFilePath.o \ -HashCalc.o \ -LoadCodecs.o \ -OpenArchive.o \ -PropIDUtils.o \ -SetProperties.o \ -SortUtils.o \ -TempFiles.o \ -Update.o \ -UpdateAction.o \ -UpdateCallback.o \ -UpdatePair.o \ -UpdateProduce.o \ -WorkDir.o \ -ZipRegistry.o \ - -AR_COMMON_OBJS = \ - OutStreamWithCRC.o - -FM_OBJS_OUT = \ -MessagesDialog.o \ -MessagesDialog_rc.o \ - -FM_OBJS = \ -FormatUtils.o \ -ProgramLocation.o \ -SplitUtils.o \ -StringUtils.o \ -ExtractCallback.o \ -LangUtils.o \ -OverwriteDialog.o \ -OverwriteDialog_rc.o \ -ProgressDialog2.o \ -ProgressDialog2_rc.o \ -PasswordDialog.o \ -PasswordDialog_rc.o \ - -C_OBJS = \ - Alloc.o \ - CpuArch.o \ - Threads.o \ - -OBJS_OUT=\ - $(GUI_OBJS) \ - $(COMMON_OBJS) \ - $(WIN_OBJS) \ - $(WIN_CTRL_OBJS) \ - $(7ZIP_COMMON_OBJS) \ - $(UI_COMMON_OBJS) \ - $(AR_COMMON_OBJS) \ - $(FM_OBJS)\ - MyMessages.o \ - CopyCoder.o \ - $(C_OBJS) \ - MyWindows.o \ - wine_date_and_time.o \ - wine_GetXXXDefaultLangID.o \ - 7zCrc.o $(OBJ_CRC32) - -include ../../../../makefile.glb - +PROG = 7zG.exe +CFLAGS = $(CFLAGS) \ + -DZ7_LANG \ + -DZ7_EXTERNAL_CODECS \ + +!IFDEF UNDER_CE +LIBS = $(LIBS) ceshell.lib Commctrl.lib +!ELSE +LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib gdi32.lib +CFLAGS = $(CFLAGS) -DZ7_DEVICE_FILE +# -DZ7_LONG_PATH -DZ7_LARGE_PAGES +!ENDIF + +GUI_OBJS = \ + $O\BenchmarkDialog.obj \ + $O\CompressDialog.obj \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + $O\GUI.obj \ + $O\HashGUI.obj \ + $O\UpdateCallbackGUI.obj \ + $O\UpdateCallbackGUI2.obj \ + $O\UpdateGUI.obj \ + +COMMON_OBJS = \ + $O\CommandLineParser.obj \ + $O\CRC.obj \ + $O\DynLimBuf.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\MyString.obj \ + $O\MyVector.obj \ + $O\NewHandler.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\Clipboard.obj \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\ErrorMsg.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileLink.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\MemoryGlobal.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConv.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\System.obj \ + $O\SystemInfo.obj \ + $O\TimeUtils.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + +7ZIP_COMMON_OBJS = \ + $O\CreateCoder.obj \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\FilterCoder.obj \ + $O\LimitedStreams.obj \ + $O\MethodProps.obj \ + $O\MultiOutStream.obj \ + $O\ProgressUtils.obj \ + $O\PropId.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + $O\UniqBlocks.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\Bench.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\HashCalc.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + $O\OutStreamWithCRC.obj \ + +FM_OBJS = \ + $O\EditDialog.obj \ + $O\ExtractCallback.obj \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\ListViewDialog.obj \ + $O\MemDialog.obj \ + $O\OpenCallback.obj \ + $O\ProgramLocation.obj \ + $O\PropertyName.obj \ + $O\RegistryUtils.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog2.obj \ + +FM_OBJS = $(FM_OBJS) \ + $O\BrowseDialog.obj \ + $O\ComboDialog.obj \ + $O\SysIconUtils.obj \ + +EXPLORER_OBJS = \ + $O\MyMessages.obj \ + +COMPRESS_OBJS = \ + $O\CopyCoder.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\CpuArch.obj \ + $O\DllSecur.obj \ + $O\Threads.obj \ + +!include "../../Crc.mak" +!include "../../Sort.mak" + +!include "../../7zip.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/GUI/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,417 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/7zG$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DLANG \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Common/WorkDir.cpp \ - ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp \ - ../../../../CPP/7zip/UI/Explorer/MyMessages.cpp \ - ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp \ - ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp \ - ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp \ - ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp \ - ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp \ - ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp \ - ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp \ - ../../../../CPP/7zip/UI/GUI/BenchmarkDialog.cpp \ - ../../../../CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp \ - ../../../../CPP/7zip/UI/GUI/CompressDialog.cpp \ - ../../../../CPP/7zip/UI/GUI/CompressDialog_rc.cpp \ - ../../../../CPP/7zip/UI/GUI/ExtractDialog.cpp \ - ../../../../CPP/7zip/UI/GUI/ExtractDialog_rc.cpp \ - ../../../../CPP/7zip/UI/GUI/ExtractGUI.cpp \ - ../../../../CPP/7zip/UI/GUI/GUI.cpp \ - ../../../../CPP/7zip/UI/GUI/HashGUI.cpp \ - ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp \ - ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp \ - ../../../../CPP/7zip/UI/GUI/UpdateGUI.cpp \ - ../../../../CPP/7zip/UI/GUI/wxGUI.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/Lang.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/Control/Controls.cpp \ - ../../../../CPP/Windows/Control/Dialog.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Registry.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/Windows/Window.cpp \ - ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -7zCrc.o : ../../../../C/7zCrc.c - $(CC) $(CFLAGS) ../../../../C/7zCrc.c -7zCrcOpt.o : ../../../../C/7zCrcOpt.c - $(CC) $(CFLAGS) ../../../../C/7zCrcOpt.c -Alloc.o : ../../../../C/Alloc.c - $(CC) $(CFLAGS) ../../../../C/Alloc.c -CpuArch.o : ../../../../C/CpuArch.c - $(CC) $(CFLAGS) ../../../../C/CpuArch.c -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -OutStreamWithCRC.o : ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp -CreateCoder.o : ../../../../CPP/7zip/Common/CreateCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/CreateCoder.cpp -FilePathAutoRename.o : ../../../../CPP/7zip/Common/FilePathAutoRename.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilePathAutoRename.cpp -FileStreams.o : ../../../../CPP/7zip/Common/FileStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FileStreams.cpp -FilterCoder.o : ../../../../CPP/7zip/Common/FilterCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/FilterCoder.cpp -LimitedStreams.o : ../../../../CPP/7zip/Common/LimitedStreams.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/LimitedStreams.cpp -MethodProps.o : ../../../../CPP/7zip/Common/MethodProps.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/MethodProps.cpp -ProgressUtils.o : ../../../../CPP/7zip/Common/ProgressUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/ProgressUtils.cpp -PropId.o : ../../../../CPP/7zip/Common/PropId.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/PropId.cpp -StreamObjects.o : ../../../../CPP/7zip/Common/StreamObjects.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamObjects.cpp -StreamUtils.o : ../../../../CPP/7zip/Common/StreamUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/StreamUtils.cpp -UniqBlocks.o : ../../../../CPP/7zip/Common/UniqBlocks.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Common/UniqBlocks.cpp -CopyCoder.o : ../../../../CPP/7zip/Compress/CopyCoder.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/Compress/CopyCoder.cpp -ArchiveCommandLine.o : ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp -ArchiveExtractCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp -ArchiveOpenCallback.o : ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp -Bench.o : ../../../../CPP/7zip/UI/Common/Bench.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Bench.cpp -DefaultName.o : ../../../../CPP/7zip/UI/Common/DefaultName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/DefaultName.cpp -EnumDirItems.o : ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp -Extract.o : ../../../../CPP/7zip/UI/Common/Extract.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Extract.cpp -ExtractingFilePath.o : ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp -HashCalc.o : ../../../../CPP/7zip/UI/Common/HashCalc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/HashCalc.cpp -LoadCodecs.o : ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp -OpenArchive.o : ../../../../CPP/7zip/UI/Common/OpenArchive.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp -PropIDUtils.o : ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp -SetProperties.o : ../../../../CPP/7zip/UI/Common/SetProperties.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SetProperties.cpp -SortUtils.o : ../../../../CPP/7zip/UI/Common/SortUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/SortUtils.cpp -TempFiles.o : ../../../../CPP/7zip/UI/Common/TempFiles.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/TempFiles.cpp -Update.o : ../../../../CPP/7zip/UI/Common/Update.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/Update.cpp -UpdateAction.o : ../../../../CPP/7zip/UI/Common/UpdateAction.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateAction.cpp -UpdateCallback.o : ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp -UpdatePair.o : ../../../../CPP/7zip/UI/Common/UpdatePair.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdatePair.cpp -UpdateProduce.o : ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp -WorkDir.o : ../../../../CPP/7zip/UI/Common/WorkDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/WorkDir.cpp -ZipRegistry.o : ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Common/ZipRegistry.cpp -MyMessages.o : ../../../../CPP/7zip/UI/Explorer/MyMessages.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/Explorer/MyMessages.cpp -ExtractCallback.o : ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ExtractCallback.cpp -FormatUtils.o : ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/FormatUtils.cpp -LangUtils.o : ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/LangUtils.cpp -OverwriteDialog.o : ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/OverwriteDialog.cpp -OverwriteDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp -PasswordDialog.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog.cpp -PasswordDialog_rc.o : ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp -ProgramLocation.o : ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgramLocation.cpp -PropertyName.o : ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/PropertyName.cpp -ProgressDialog2.o : ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgressDialog2.cpp -ProgressDialog2_rc.o : ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp -SplitUtils.o : ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/SplitUtils.cpp -StringUtils.o : ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/FileManager/StringUtils.cpp -BenchmarkDialog.o : ../../../../CPP/7zip/UI/GUI/BenchmarkDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/BenchmarkDialog.cpp -BenchmarkDialog_rc.o : ../../../../CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp -CompressDialog.o : ../../../../CPP/7zip/UI/GUI/CompressDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/CompressDialog.cpp -CompressDialog_rc.o : ../../../../CPP/7zip/UI/GUI/CompressDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/CompressDialog_rc.cpp -ExtractDialog.o : ../../../../CPP/7zip/UI/GUI/ExtractDialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/ExtractDialog.cpp -ExtractDialog_rc.o : ../../../../CPP/7zip/UI/GUI/ExtractDialog_rc.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/ExtractDialog_rc.cpp -ExtractGUI.o : ../../../../CPP/7zip/UI/GUI/ExtractGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/ExtractGUI.cpp -GUI.o : ../../../../CPP/7zip/UI/GUI/GUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/GUI.cpp -HashGUI.o : ../../../../CPP/7zip/UI/GUI/HashGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/HashGUI.cpp -UpdateCallbackGUI.o : ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp -UpdateCallbackGUI2.o : ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp -UpdateGUI.o : ../../../../CPP/7zip/UI/GUI/UpdateGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/UpdateGUI.cpp -wxGUI.o : ../../../../CPP/7zip/UI/GUI/wxGUI.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/GUI/wxGUI.cpp -CRC.o : ../../../../CPP/Common/CRC.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CRC.cpp -CommandLineParser.o : ../../../../CPP/Common/CommandLineParser.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/CommandLineParser.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -Lang.o : ../../../../CPP/Common/Lang.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Lang.cpp -ListFileUtils.o : ../../../../CPP/Common/ListFileUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/ListFileUtils.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -NewHandler.o : ../../../../CPP/Common/NewHandler.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/NewHandler.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -StringToInt.o : ../../../../CPP/Common/StringToInt.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringToInt.cpp -UTFConvert.o : ../../../../CPP/Common/UTFConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/UTFConvert.cpp -Wildcard.o : ../../../../CPP/Common/Wildcard.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/Wildcard.cpp -Controls.o : ../../../../CPP/Windows/Control/Controls.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Controls.cpp -Dialog.o : ../../../../CPP/Windows/Control/Dialog.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Control/Dialog.cpp -DLL.o : ../../../../CPP/Windows/DLL.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/DLL.cpp -ErrorMsg.o : ../../../../CPP/Windows/ErrorMsg.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/ErrorMsg.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -PropVariant.o : ../../../../CPP/Windows/PropVariant.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariant.cpp -PropVariantConv.o : ../../../../CPP/Windows/PropVariantConv.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/PropVariantConv.cpp -Registry.o : ../../../../CPP/Windows/Registry.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Registry.cpp -Synchronization.o : ../../../../CPP/Windows/Synchronization.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Synchronization.cpp -System.o : ../../../../CPP/Windows/System.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/System.cpp -TimeUtils.o : ../../../../CPP/Windows/TimeUtils.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/TimeUtils.cpp -Window.o : ../../../../CPP/Windows/Window.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/Window.cpp -wine_GetXXXDefaultLangID.o : ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_GetXXXDefaultLangID.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - 7zCrc.o \ - $(OBJ_CRC32) \ - Alloc.o \ - CpuArch.o \ - Threads.o \ - OutStreamWithCRC.o \ - CreateCoder.o \ - FilePathAutoRename.o \ - FileStreams.o \ - FilterCoder.o \ - LimitedStreams.o \ - MethodProps.o \ - ProgressUtils.o \ - PropId.o \ - StreamObjects.o \ - StreamUtils.o \ - UniqBlocks.o \ - CopyCoder.o \ - ArchiveCommandLine.o \ - ArchiveExtractCallback.o \ - ArchiveOpenCallback.o \ - Bench.o \ - DefaultName.o \ - EnumDirItems.o \ - Extract.o \ - ExtractingFilePath.o \ - HashCalc.o \ - LoadCodecs.o \ - OpenArchive.o \ - PropIDUtils.o \ - SetProperties.o \ - SortUtils.o \ - TempFiles.o \ - Update.o \ - UpdateAction.o \ - UpdateCallback.o \ - UpdatePair.o \ - UpdateProduce.o \ - WorkDir.o \ - ZipRegistry.o \ - MyMessages.o \ - ExtractCallback.o \ - FormatUtils.o \ - LangUtils.o \ - OverwriteDialog.o \ - OverwriteDialog_rc.o \ - PasswordDialog.o \ - PasswordDialog_rc.o \ - ProgramLocation.o \ - PropertyName.o \ - ProgressDialog2.o \ - ProgressDialog2_rc.o \ - SplitUtils.o \ - StringUtils.o \ - BenchmarkDialog.o \ - BenchmarkDialog_rc.o \ - CompressDialog.o \ - CompressDialog_rc.o \ - ExtractDialog.o \ - ExtractDialog_rc.o \ - ExtractGUI.o \ - GUI.o \ - HashGUI.o \ - UpdateCallbackGUI.o \ - UpdateCallbackGUI2.o \ - UpdateGUI.o \ - wxGUI.o \ - CRC.o \ - CommandLineParser.o \ - IntToString.o \ - Lang.o \ - ListFileUtils.o \ - MyString.o \ - MyVector.o \ - MyWindows.o \ - NewHandler.o \ - StringConvert.o \ - StringToInt.o \ - UTFConvert.o \ - Wildcard.o \ - Controls.o \ - Dialog.o \ - DLL.o \ - ErrorMsg.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - PropVariant.o \ - PropVariantConv.o \ - Registry.o \ - Synchronization.o \ - System.o \ - TimeUtils.o \ - Window.o \ - wine_GetXXXDefaultLangID.o \ - wine_date_and_time.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/resource.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/resource.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource.rc 2024-03-04 14:00:00.000000000 +0000 @@ -0,0 +1,26 @@ +#include "../../MyVersionInfo.rc" +// #include + +#include "resource2.rc" +#include "resource3.rc" + +#include "../FileManager/resourceGui.rc" + +MY_VERSION_INFO(MY_VFT_APP, "7-Zip GUI", "7zg", "7zg.exe") + +IDI_ICON ICON "FM.ico" + +#ifndef UNDER_CE +1 24 MOVEABLE PURE "7zG.exe.manifest" +#endif + +#include "../FileManager/PropertyName.rc" +#include "../FileManager/MemDialog.rc" +#include "../FileManager/OverwriteDialog.rc" +#include "../FileManager/PasswordDialog.rc" +#include "../FileManager/ProgressDialog2.rc" +#include "Extract.rc" +#include "../FileManager/BrowseDialog.rc" +#include "../FileManager/ComboDialog.rc" +#include "../FileManager/EditDialog.rc" +#include "../FileManager/ListViewDialog.rc" diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/resource2.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/resource2.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.h 2011-05-14 07:58:00.000000000 +0000 @@ -1,2 +1,2 @@ -#define IDS_PROGRESS_COMPRESSING 3301 -#define IDS_ARCHIVES_COLON 3907 +#define IDS_PROGRESS_COMPRESSING 3301 +#define IDS_ARCHIVES_COLON 3907 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/resource2.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/resource2.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource2.rc 2011-06-06 11:47:30.000000000 +0000 @@ -0,0 +1,10 @@ +#include "ExtractDialog.rc" +#include "CompressDialog.rc" +#include "BenchmarkDialog.rc" +#include "resource2.h" + +STRINGTABLE +BEGIN + IDS_PROGRESS_COMPRESSING "Compressing" + IDS_ARCHIVES_COLON "Archives:" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/resource3.h p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.h --- p7zip-rar-16.02/CPP/7zip/UI/GUI/resource3.h 2015-09-19 09:42:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.h 2015-08-25 11:10:27.000000000 +0000 @@ -1,10 +1,10 @@ -#define IDS_PROGRESS_REMOVE 3305 - -#define IDS_PROGRESS_ADD 3320 -#define IDS_PROGRESS_UPDATE 3321 -#define IDS_PROGRESS_ANALYZE 3322 -#define IDS_PROGRESS_REPLICATE 3323 -#define IDS_PROGRESS_REPACK 3324 - -#define IDS_PROGRESS_DELETE 3326 -#define IDS_PROGRESS_HEADER 3327 +#define IDS_PROGRESS_REMOVE 3305 + +#define IDS_PROGRESS_ADD 3320 +#define IDS_PROGRESS_UPDATE 3321 +#define IDS_PROGRESS_ANALYZE 3322 +#define IDS_PROGRESS_REPLICATE 3323 +#define IDS_PROGRESS_REPACK 3324 + +#define IDS_PROGRESS_DELETE 3326 +#define IDS_PROGRESS_HEADER 3327 diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/resource3.rc p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.rc --- p7zip-rar-16.02/CPP/7zip/UI/GUI/resource3.rc 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/resource3.rc 2015-03-23 10:25:10.000000000 +0000 @@ -0,0 +1,15 @@ +#include "resource3.h" + +STRINGTABLE +BEGIN + IDS_PROGRESS_REMOVE "Removing" + + IDS_PROGRESS_ADD "Adding" + IDS_PROGRESS_UPDATE "Updating" + IDS_PROGRESS_ANALYZE "Analyzing" + IDS_PROGRESS_REPLICATE "Replicating" + IDS_PROGRESS_REPACK "Repacking" + + IDS_PROGRESS_DELETE "Deleting" + IDS_PROGRESS_HEADER "Header creating" +END diff -Nru p7zip-rar-16.02/CPP/7zip/UI/GUI/wxGUI.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/wxGUI.cpp --- p7zip-rar-16.02/CPP/7zip/UI/GUI/wxGUI.cpp 2015-06-22 21:20:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/GUI/wxGUI.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,783 +0,0 @@ -// wxGUI.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#ifdef __WXMAC__ - -#define UInt32 max_UInt32 -#include -#undef UInt32 - -#endif - -#define static const -#include "../GUI/p7zip_32.xpm" -#undef static - -#undef ACTIVATE_DIALOG_TESTS - -#ifdef _WIN32 -#error 5 -#endif - -#include "Windows/Window.h" -#include "Windows/Control/DialogImpl.h" - -#include "Common/StringConvert.h" - -bool GetProgramFolderPath(UString &folder) -{ - const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR"); - if (p7zip_home_dir == 0) p7zip_home_dir="./"; - - folder = MultiByteToUnicodeString(p7zip_home_dir); - - return true; -} - - -// FIXME - -static pthread_t g_main_thread; - -bool is_main_thread(void) -{ - return ( g_main_thread == pthread_self() ); -} - -void verify_main_thread(void) -{ - if ( ! is_main_thread() ) - { - printf("verify_main_thread-wxGUI\n"); - abort(); - } -} - - - - - - - - - -int Main1(int argc,TCHAR **argv); - -#include "Windows/Registry.h" -using namespace NWindows; -using namespace NRegistry; - - -#include "Common/StringConvert.h" -#include "Windows/FileDir.h" -#include "Windows/Synchronization.h" - -#include "ExtractRes.h" -#include "../Explorer/MyMessages.h" - -#include "../FileManager/resourceGui.h" -#include "ExtractGUI.h" -#include "UpdateGUI.h" -#include "BenchmarkDialog.h" -#include "../FileManager/RegistryUtils.h" - -using namespace NWindows; -using namespace NFile; - -#include "../FileManager/ProgramLocation.h" - -static LPCWSTR kHelpFileName = L"help/"; - -void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile) -{ - UString path; - if (!::GetProgramFolderPath(path)) - return; - path += kHelpFileName; - path += topicFile; - printf("ShowHelpWindow(%p,%ls)=>%ls\n",hwnd,topicFile,(const wchar_t *)path); - // HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL); - wxString path2(path); - wxLaunchDefaultBrowser(path2); -} - -////////////////////////////// TRIES /////////////////////////////////// - -#ifdef ACTIVATE_DIALOG_TESTS -static void ErrorMessage(const wchar_t *message) -{ - MessageBox(0,message, wxT("7-Zip GUI"),wxICON_ERROR); -} - -#include "../FileManager/PasswordDialog.h" -#include "../FileManager/MessagesDialog.h" -#include "../FileManager/OverwriteDialog.h" -#include "Windows/Thread.h" - -void myErrorMsg(const wchar_t *message) -{ - MessageBox(0,message, wxT("Message"),wxICON_ERROR); -} - -void testCMessagesDialog() -{ - UStringVector Messages; - - Messages.Add(L"message 1"); - Messages.Add(L"message 2"); - Messages.Add(L"message 3"); - Messages.Add(L"message 4"); - Messages.Add(L"message 5"); - Messages.Add(L"message 6"); - Messages.Add(L"message 7"); - Messages.Add(L"message 8"); - Messages.Add(L"message 9"); - - CMessagesDialog messagesDialog; - messagesDialog.Messages = &Messages; - int ret = messagesDialog.Create( 0 ); // ParentWindow - - if (ret == IDOK) myErrorMsg(wxT("CMessagesDialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("CMessagesDialog => IDCANCEL")); - else myErrorMsg(wxT("CMessagesDialog => ?")); - -} - -void testCOverwriteDialog() -{ -SYSTEMTIME systemTime; -GetSystemTime( &systemTime ); - - -const wchar_t *existName = L"existName"; -FILETIME data_existTime; -FILETIME *existTime = &data_existTime ; -UInt64 data_existSize = 1234; -UInt64 *existSize = &data_existSize; -const wchar_t *newName = L"newName"; -FILETIME data_newTime; -FILETIME *newTime = &data_newTime; -UInt64 data_newSize = 45678; -UInt64 *newSize = &data_newSize; -Int32 data_answer=0; -Int32 *answer = &data_answer; - -SystemTimeToFileTime( &systemTime , &data_existTime); -SystemTimeToFileTime( &systemTime , &data_newTime); - - COverwriteDialog dialog; - - dialog.OldFileInfo.Time = *existTime; - dialog.OldFileInfo.TimeIsDefined = true; // FIXME : look again at the sample ! - - dialog.OldFileInfo.SizeIsDefined = (existSize != NULL); - if (dialog.OldFileInfo.SizeIsDefined) - dialog.OldFileInfo.Size = *existSize; - dialog.OldFileInfo.Name = existName; - - if (newTime == 0) - dialog.NewFileInfo.TimeIsDefined = false; - else - { - dialog.NewFileInfo.TimeIsDefined = true; - dialog.NewFileInfo.Time = *newTime; - } - - dialog.NewFileInfo.SizeIsDefined = (newSize != NULL); - if (dialog.NewFileInfo.SizeIsDefined) - dialog.NewFileInfo.Size = *newSize; - dialog.NewFileInfo.Name = newName; - - /* - NOverwriteDialog::NResult::EEnum writeAnswer = - NOverwriteDialog::Execute(oldFileInfo, newFileInfo); - */ - INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z - - switch(writeAnswer) - { - case IDCANCEL: myErrorMsg(wxT("COverwriteDialog => IDCANCEL")); break; - case IDNO: myErrorMsg(wxT("COverwriteDialog => IDNO")); break; - case IDC_BUTTON_OVERWRITE_NO_TO_ALL: myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_NO_TO_ALL")); break; - case IDC_BUTTON_OVERWRITE_YES_TO_ALL:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_YES_TO_ALL")); break; - case IDC_BUTTON_OVERWRITE_AUTO_RENAME:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_AUTO_RENAME")); break; - case IDYES: myErrorMsg(wxT("COverwriteDialog => IDYES")); break; - default: myErrorMsg(wxT("COverwriteDialog => default")); break; - } -} - -void testCPasswordDialog() -{ - CPasswordDialog dialog; - - int ret = dialog.Create(0); - if (ret == IDOK) { - UString Password = dialog.Password; - UString msg = wxT("CPasswordDialog => IDOK password=\""); - msg += Password; - msg += wxT("\""); - myErrorMsg(msg); - } - else if (ret == IDCANCEL) myErrorMsg(wxT("CPasswordDialog => IDCANCEL")); - else myErrorMsg(wxT("CPasswordDialog => ?")); - -} - -struct CThreadProgressDialog -{ - CProgressDialog * ProgressDialog; - static THREAD_FUNC_DECL MyThreadFunction(void *param) - { - ((CThreadProgressDialog *)param)->Result = ((CThreadProgressDialog *)param)->Process(); - return 0; - } - HRESULT Result; - HRESULT Process() - { - Sleep(1000); - int total = 1000; - - ProgressDialog->ProgressSynch.SetTitleFileName(L"SetTitleFileName"); - ProgressDialog->ProgressSynch.SetNumFilesTotal(100); - ProgressDialog->ProgressSynch.SetNumFilesCur(1); - ProgressDialog->ProgressSynch.SetProgress(total, 0); - // ProgressDialog.ProgressSynch.SetRatioInfo(inSize, outSize); - // ProgressDialog.ProgressSynch.SetCurrentFileName(name); - - ProgressDialog->ProgressSynch.SetPos(total/10); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File1"); - Sleep(1000); - ProgressDialog->ProgressSynch.SetPos(total/2); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File2"); - Sleep(1000); - ProgressDialog->ProgressSynch.SetPos(total); - ProgressDialog->ProgressSynch.SetCurrentFileName(L"File3"); - Sleep(1000); - ProgressDialog->MyClose(); - return 0; - } -}; - -void testCProgressDialog() -{ - CProgressDialog ProgressDialog; - - CThreadProgressDialog benchmarker; - benchmarker.ProgressDialog = &ProgressDialog; - NWindows::CThread thread; - thread.Create(CThreadProgressDialog::MyThreadFunction, &benchmarker); - - // void StartProgressDialog(const UString &title) - int ret = ProgressDialog.Create(L"testCProgressDialog", 0); - - if (ret == IDOK) myErrorMsg(wxT("CProgressDialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("CProgressDialog => IDCANCEL")); - else myErrorMsg(wxT("CProgressDialog => ?")); - -} - -void testDialog(int num) -{ - NWindows::NControl::CModalDialog dialog; - - printf("Generic Dialog(%d)\n",num); - int ret = dialog.Create(num, 0); - if (ret == IDOK) myErrorMsg(wxT("Generic Dialog => IDOK")); - else if (ret == IDCANCEL) myErrorMsg(wxT("Generic Dialog => IDCANCEL")); - else myErrorMsg(wxT("Generic Dialog => ?")); -} - -void testMessageBox() -{ - int ret = MessageBoxW(0, L"test yes/no/cancel", - L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL); - if (ret == IDYES) myErrorMsg(wxT("MessageBoxW => IDYES")); - else if (ret == IDNO) myErrorMsg(wxT("MessageBoxW => IDNO")); - else if (ret == IDCANCEL) myErrorMsg(wxT("MessageBoxW => IDCANCEL")); - else myErrorMsg(wxT("MessageBoxW => ?")); -} - -static void testRegistry() -{ - SaveRegLang(L"fr"); - - UString langFile; - ReadRegLang(langFile); - - printf("testRegistry : -%ls-\n",(const wchar_t *)langFile); -} - - -int Main2(int argc,TCHAR **argv); - -int Main3(int argc,wxChar **argv) -{ - testRegistry(); - - int num = -1; - - if (argc >=2 ) - { - num = argv[1][0] - L'0'; - } - printf("num=%d\n",num); - - - switch(num) - { - case 0: - { - TCHAR **argv2 = (TCHAR **)calloc(argc,sizeof(*argv)); - - argv2[0] = argv[0]; - for(int i = 2; i < argc; i++) argv2[i-1] = argv[i]; - - return Main2(argc-1,argv2); - } - // TODO Benchmark - // TODO CCompressDialog - // TODO CExtractDialog ? - case 1 : testCMessagesDialog(); break; - case 2 : testCOverwriteDialog(); break; - case 3 : testCPasswordDialog(); break; - case 4 : testCProgressDialog(); break; - case 5 : testMessageBox(); break; - case 9 : - if (argc >= 3) - { - AString str = GetAnsiString(argv[2]); - int num = atoi((const char*)str); - testDialog(num); - } - else - { - printf("usage : 7zG 9 \n"); - } - break; - default : - printf("usage : 7zG number\n"); - - }; - - return 0; -} - -#endif // ACTIVATE_DIALOG_TESTS - -static const TCHAR *kCUBasePath = TEXT("Software/7-ZIP"); -static const WCHAR *kLangValueName = L"Lang"; - -void SaveRegLang(const UString &langFile) -{ - CKey key; - key.Create(HKEY_CURRENT_USER, kCUBasePath); - key.SetValue(kLangValueName, langFile); -} - -void ReadRegLang(UString &langFile) -{ - langFile.Empty(); - CKey key; - if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) - key.QueryValue(kLangValueName, langFile); -} - - -////////////////////////////////// - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" // global_use_utf16_conversion - -void mySplitCommandLineW(int numArguments, TCHAR **arguments,UStringVector &parts) { - - parts.Clear(); - for(int ind=0;ind < numArguments; ind++) { - UString tmp = arguments[ind]; - // tmp.Trim(); " " is a valid filename ... - if (!tmp.IsEmpty()) { - parts.Add(tmp); -// DEBUG printf("ARG %d : '%ls'\n",ind,(const wchar_t *)tmp); - } - } -} - -// ---------------------------------------------------------------------------- -// private classes -// ---------------------------------------------------------------------------- - -// Define a new frame type -class MyFrame: public wxFrame -{ -public: - // ctor - MyFrame(wxFrame *frame, const wxString& title, int x, int y, int w, int h); - // virtual ~MyFrame(); - - // operations - void WriteText(const wxString& text) { m_txtctrl->WriteText(text); } - -protected: - // callbacks - void OnWorkerEvent(wxCommandEvent& event); -private: - // just some place to put our messages in - wxTextCtrl *m_txtctrl; - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent) - // EVT_IDLE(MyFrame::OnIdle) -END_EVENT_TABLE() - -// My frame constructor -MyFrame::MyFrame(wxFrame *frame, const wxString& title, - int x, int y, int w, int h) - : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)) -{ - this->SetIcon(wxICON(p7zip_32)); - -#if wxUSE_STATUSBAR - CreateStatusBar(2); -#endif // wxUSE_STATUSBAR - - m_txtctrl = new wxTextCtrl(this, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(0, 0), wxTE_MULTILINE | wxTE_READONLY); -} - -void myCreateHandle(int n); -wxWindow * g_window=0; - -void MyFrame::OnWorkerEvent(wxCommandEvent& event) -{ - int n = event.GetInt(); - myCreateHandle(n); -} - - -// Define a new application type, each program should derive a class from wxApp -class MyApp : public wxApp -{ -public: - // override base class virtuals - // ---------------------------- - - // this one is called on application startup and is a good place for the app - // initialization (doing it here and not in the ctor allows to have an error - // return: if OnInit() returns false, the application terminates) - virtual bool OnInit(); -}; - -// Create a new application object: this macro will allow wxWidgets to create -// the application object during program execution (it's better than using a -// static object for many reasons) and also implements the accessor function -// wxGetApp() which will return the reference of the right type (i.e. MyApp and -// not wxApp) -IMPLEMENT_APP(MyApp) - - - -time_t g_T0 = 0; - -/* FIXME : to erase ? -class MyThread : public wxThread -{ - int _argc; - TCHAR **_argv; -public: - MyThread(int argc,TCHAR **argv): wxThread(),_argc(argc), _argv(argv) {} - - // thread execution starts here - virtual void *Entry() - { -#ifdef ACTIVATE_DIALOG_TESTS - int ret = Main3(_argc,_argv); -#else - int ret = Main1(_argc,_argv); -#endif - exit(ret); - } -}; -*/ - -// 'Main program' equivalent: the program execution "starts" here -bool MyApp::OnInit() -{ - // don't parse the command-line options ! - // : if ( !wxApp::OnInit() ) return false; - -#ifdef __WXMAC__ -ProcessSerialNumber PSN; -GetCurrentProcess(&PSN); -TransformProcessType(&PSN,kProcessTransformToForegroundApplication); -#endif - - - g_main_thread = pthread_self(); - - { // define P7ZIP_HOME_DIR - extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base); - static char p7zip_home_dir[MAX_PATH]; - - UString fullPath; - NDir::MyGetFullPathName(wxApp::argv[0], fullPath); - AString afullPath = GetAnsiString(fullPath); - - AString dir,name; - - my_windows_split_path(afullPath,dir,name); - - const char *dir2 = nameWindowToUnix((const char *)dir); - snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",dir2); - p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0; - putenv(p7zip_home_dir); - // DEBUG printf("putenv(%s)\n",p7zip_home_dir); - } - global_use_utf16_conversion = 1; // UNICODE ! - - g_T0 = time(0); - // DEBUG printf("MAIN Thread : 0x%lx\n",wxThread::GetCurrentId()); - - // Create the main frame window - MyFrame *frame = new MyFrame((wxFrame *)NULL, _T("7-zip Main Window"), 50, 50, 450, 340); - // Don't Show the frame ! - // frame->Show(true); - - g_window = frame; - - SetTopWindow(frame); - -/* FIXME ? - MyThread *thread = new MyThread(wxApp::argc,wxApp::argv); - thread->Create(); // != wxTHREAD_NO_ERROR - thread->Run(); - - // success: wxApp::OnRun() will be called which will enter the main message - // loop and the application will run. If we returned false here, the - // application would exit immediately. - return true; -*/ - - int ret = Main1(wxApp::argc,wxApp::argv); - - exit(ret); - - return false; -} - -////////////////////////////////////////// - -#include "resource2.h" -#include "resource3.h" -#include "ExtractRes.h" -// #include "resourceGui.h" -#include "../FileManager/PropertyNameRes.h" - - -static CStringTable g_stringTable[] = -{ - /* GUI/resource2.rc */ - - - { IDS_PROGRESS_COMPRESSING ,L"Compressing" }, - { IDS_ARCHIVES_COLON ,L"Archives:" }, - - /* ../FileManager/resourceGui.rc */ - { IDS_MESSAGE_NO_ERRORS ,L"There are no errors" }, - - { IDS_PROGRESS_TESTING ,L"Testing" }, - - { IDS_CHECKSUM_CALCULATING ,L"Checksum calculating..." }, - { IDS_CHECKSUM_INFORMATION ,L"Checksum information" }, - { IDS_CHECKSUM_CRC_DATA ,L"CRC checksum for data:" }, - { IDS_CHECKSUM_CRC_DATA_NAMES ,L"CRC checksum for data and names:" }, - { IDS_CHECKSUM_CRC_STREAMS_NAMES ,L"CRC checksum for streams and names:" }, - - { IDS_INCORRECT_VOLUME_SIZE ,L"Incorrect volume size" }, - - { IDS_OPENNING ,L"Opening..." }, - { IDS_SCANNING ,L"Scanning..." }, - - /* ../FileManager/PropertyName.rc */ - { IDS_PROP_PATH ,L"Path" }, - { IDS_PROP_NAME ,L"Name" }, - { IDS_PROP_EXTENSION ,L"Extension" }, - { IDS_PROP_IS_FOLDER ,L"Folder" }, - { IDS_PROP_SIZE ,L"Size" }, - { IDS_PROP_PACKED_SIZE ,L"Packed Size" }, - { IDS_PROP_ATTRIBUTES ,L"Attributes" }, - { IDS_PROP_CTIME ,L"Created" }, - { IDS_PROP_ATIME ,L"Accessed" }, - { IDS_PROP_MTIME ,L"Modified" }, - { IDS_PROP_SOLID ,L"Solid" }, - { IDS_PROP_C0MMENTED ,L"Commented" }, - { IDS_PROP_ENCRYPTED ,L"Encrypted" }, - { IDS_PROP_SPLIT_BEFORE ,L"Split Before" }, - { IDS_PROP_SPLIT_AFTER ,L"Split After" }, - { IDS_PROP_DICTIONARY_SIZE ,L"Dictionary" }, - { IDS_PROP_CRC ,L"CRC" }, - { IDS_PROP_FILE_TYPE ,L"Type" }, - { IDS_PROP_ANTI ,L"Anti" }, - { IDS_PROP_METHOD ,L"Method" }, - { IDS_PROP_HOST_OS ,L"Host OS" }, - { IDS_PROP_FILE_SYSTEM ,L"File System" }, - { IDS_PROP_USER ,L"User" }, - { IDS_PROP_GROUP ,L"Group" }, - { IDS_PROP_BLOCK ,L"Block" }, - { IDS_PROP_COMMENT ,L"Comment" }, - { IDS_PROP_POSITION ,L"Position" }, - { IDS_PROP_PREFIX ,L"Path Prefix" }, - { IDS_PROP_FOLDERS ,L"Folders" }, - { IDS_PROP_FILES ,L"Files" }, - { IDS_PROP_VERSION ,L"Version" }, - { IDS_PROP_VOLUME ,L"Volume" }, - { IDS_PROP_IS_VOLUME ,L"Multivolume" }, - { IDS_PROP_OFFSET ,L"Offset" }, - { IDS_PROP_LINKS ,L"Links" }, - { IDS_PROP_NUM_BLOCKS ,L"Blocks" }, - { IDS_PROP_NUM_VOLUMES ,L"Volumes" }, - - { IDS_PROP_BIT64 ,L"64-bit" }, - { IDS_PROP_BIG_ENDIAN ,L"Big-endian" }, - { IDS_PROP_CPU ,L"CPU" }, - { IDS_PROP_PHY_SIZE ,L"Physical Size" }, - { IDS_PROP_HEADERS_SIZE ,L"Headers Size" }, - { IDS_PROP_CHECKSUM ,L"Checksum" }, - { IDS_PROP_CHARACTS ,L"Characteristics" }, - { IDS_PROP_VA ,L"Virtual Address" }, - { IDS_PROP_ID ,L"ID" }, - { IDS_PROP_SHORT_NAME ,L"Short Name" }, - { IDS_PROP_CREATOR_APP ,L"Creator Application" }, - { IDS_PROP_SECTOR_SIZE ,L"Sector Size" }, - { IDS_PROP_POSIX_ATTRIB ,L"Mode" }, - { IDS_PROP_SYM_LINK ,L"Symbolic Link" }, - { IDS_PROP_ERROR ,L"Error" }, - { IDS_PROP_TOTAL_SIZE ,L"Total Size" }, - { IDS_PROP_FREE_SPACE ,L"Free Space" }, - { IDS_PROP_CLUSTER_SIZE ,L"Cluster Size" }, - { IDS_PROP_VOLUME_NAME ,L"Label" }, - { IDS_PROP_LOCAL_NAME ,L"Local Name" }, - { IDS_PROP_PROVIDER ,L"Provider" }, - { IDS_PROP_NT_SECURITY ,L"NT Security" }, - { IDS_PROP_ALT_STREAM ,L"Alternate Stream" }, - { IDS_PROP_AUX ,L"Aux" }, - { IDS_PROP_DELETED ,L"Deleted" }, - { IDS_PROP_IS_TREE ,L"Is Tree" }, - { IDS_PROP_SHA1 ,L"SHA-1" }, - { IDS_PROP_SHA256 ,L"SHA-256" }, - { IDS_PROP_ERROR_TYPE ,L"Error Type" }, - { IDS_PROP_NUM_ERRORS ,L"Errors" }, - { IDS_PROP_ERROR_FLAGS ,L"Errors" }, - { IDS_PROP_WARNING_FLAGS ,L"Warnings" }, - { IDS_PROP_WARNING ,L"Warning" }, - { IDS_PROP_NUM_STREAMS ,L"Streams" }, - { IDS_PROP_NUM_ALT_STREAMS ,L"Alternate Streams" }, - { IDS_PROP_ALT_STREAMS_SIZE ,L"Alternate Streams Size" }, - { IDS_PROP_VIRTUAL_SIZE ,L"Virtual Size" }, - { IDS_PROP_UNPACK_SIZE ,L"Unpack Size" }, - { IDS_PROP_TOTAL_PHY_SIZE ,L"Total Physical Size" }, - { IDS_PROP_VOLUME_INDEX ,L"Volume Index" }, - { IDS_PROP_SUBTYPE ,L"SubType" }, - { IDS_PROP_SHORT_COMMENT ,L"Short Comment" }, - { IDS_PROP_CODE_PAGE ,L"Code Page" }, - { IDS_PROP_IS_NOT_ARC_TYPE ,L"Is not archive type" }, - { IDS_PROP_PHY_SIZE_CANT_BE_DETECTED ,L"Physical Size can't be detected" }, - { IDS_PROP_ZEROS_TAIL_IS_ALLOWED ,L"Zeros Tail Is Allowed" }, - { IDS_PROP_TAIL_SIZE ,L"Tail Size" }, - { IDS_PROP_EMB_STUB_SIZE ,L"Embedded Stub Size" }, - { IDS_PROP_NT_REPARSE ,L"Link" }, - { IDS_PROP_HARD_LINK ,L"Hard Link" }, - { IDS_PROP_INODE ,L"iNode" }, - { IDS_PROP_STREAM_ID ,L"Stream ID" }, - - - - /* Extract.rc */ - /**************/ - { IDS_MEM_ERROR ,L"The system cannot allocate the required amount of memory" }, - { IDS_CANNOT_CREATE_FOLDER ,L"Cannot create folder '{0}'" }, - { IDS_UPDATE_NOT_SUPPORTED ,L"Update operations are not supported for this archive." }, - { IDS_CANT_OPEN_ARCHIVE ,L"Can not open file '{0}' as archive" }, - { IDS_CANT_OPEN_ENCRYPTED_ARCHIVE ,L"Can not open encrypted archive '{0}'. Wrong password?" }, - { IDS_UNSUPPORTED_ARCHIVE_TYPE ,L"Unsupported archive type" }, - - { IDS_CANT_OPEN_AS_TYPE ,L"Can not open the file as {0} archive" }, - { IDS_IS_OPEN_AS_TYPE ,L"The file is open as {0} archive" }, - { IDS_IS_OPEN_WITH_OFFSET ,L"The archive is open with offset" }, - - { IDS_PROGRESS_EXTRACTING ,L"Extracting" }, - - { IDS_PROGRESS_SKIPPING ,L"Skipping" }, - - { IDS_EXTRACT_SET_FOLDER ,L"Specify a location for extracted files." }, - - { IDS_EXTRACT_PATHS_FULL ,L"Full pathnames" }, - { IDS_EXTRACT_PATHS_NO ,L"No pathnames" }, - { IDS_EXTRACT_PATHS_ABS ,L"Absolute pathnames" }, - { IDS_PATH_MODE_RELAT ,L"Relative pathnames" }, - - { IDS_EXTRACT_OVERWRITE_ASK ,L"Ask before overwrite" }, - { IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT ,L"Overwrite without prompt" }, - { IDS_EXTRACT_OVERWRITE_SKIP_EXISTING ,L"Skip existing files" }, - { IDS_EXTRACT_OVERWRITE_RENAME ,L"Auto rename" }, - { IDS_EXTRACT_OVERWRITE_RENAME_EXISTING ,L"Auto rename existing files" }, - - { IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD ,L"Unsupported compression method for '{0}'." }, - { IDS_EXTRACT_MESSAGE_DATA_ERROR ,L"Data error in '{0}'. File is broken" }, - { IDS_EXTRACT_MESSAGE_CRC_ERROR ,L"CRC failed in '{0}'. File is broken." }, - { IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED ,L"Data error in encrypted file '{0}'. Wrong password?" }, - { IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED ,L"CRC failed in encrypted file '{0}'. Wrong password?" }, - - { IDS_EXTRACT_MSG_WRONG_PSW_GUESS ,L"Wrong password?" }, - // { IDS_EXTRACT_MSG_ENCRYPTED ,L"Encrypted file" }, - - { IDS_EXTRACT_MSG_UNSUPPORTED_METHOD ,L"Unsupported compression method" }, - { IDS_EXTRACT_MSG_DATA_ERROR ,L"Data error" }, - { IDS_EXTRACT_MSG_CRC_ERROR ,L"CRC failed" }, - { IDS_EXTRACT_MSG_UNAVAILABLE_DATA ,L"Unavailable data" }, - { IDS_EXTRACT_MSG_UEXPECTED_END ,L"Unexpected end of data" }, - { IDS_EXTRACT_MSG_DATA_AFTER_END ,L"There are some data after the end of the payload data" }, - { IDS_EXTRACT_MSG_IS_NOT_ARC ,L"Is not archive" }, - { IDS_EXTRACT_MSG_HEADERS_ERROR ,L"Headers Error" }, - { IDS_EXTRACT_MSG_WRONG_PSW_CLAIM ,L"Wrong password" }, - - { IDS_OPEN_MSG_UNAVAILABLE_START ,L"Unavailable start of archive" }, - { IDS_OPEN_MSG_UNCONFIRMED_START ,L"Unconfirmed start of archive" }, - // { IDS_OPEN_MSG_ERROR_FLAGS + 5 ,L"Unexpected end of archive" }, - // { IDS_OPEN_MSG_ERROR_FLAGS + 6 ,L"There are data after the end of archive" }, - { IDS_OPEN_MSG_UNSUPPORTED_FEATURE ,L"Unsupported feature" }, - - - // resource3.rc - { IDS_PROGRESS_REMOVE ,L"Removing" }, - - { IDS_PROGRESS_ADD ,L"Adding" }, - { IDS_PROGRESS_UPDATE ,L"Updating" }, - { IDS_PROGRESS_ANALYZE ,L"Analyzing" }, - { IDS_PROGRESS_REPLICATE ,L"Replicating" }, - { IDS_PROGRESS_REPACK ,L"Repacking" }, - - { IDS_PROGRESS_DELETE ,L"Deleting" }, - { IDS_PROGRESS_HEADER ,L"Header creating" }, - - - { 0 , 0 } -}; - -REGISTER_STRINGTABLE(g_stringTable) - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile --- p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/makefile 2015-10-03 20:18:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - -TARGET_FLAGS=`wx-config --unicode=yes --cxxflags` - -include ../../../../makefile.crc32 -include ../../../../makefile.machine - -LIBS=`wx-config --unicode=yes --libs` $(LOCAL_LIBS_DLL) - -include ../../../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile.list --- p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/makefile.list 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ - - -# WARNING : automatically generated by utils/generate.py - -PROG=../../../../bin/P7ZIP$(BINSUFFIX) - -all: $(PCH_NAME) $(PROG) - -LOCAL_FLAGS=$(TARGET_FLAGS) \ - -DLANG \ - -DEXTERNAL_CODECS \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE \ - -D_REENTRANT \ - -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE \ - -D_UNICODE \ - -DUNIX_USE_WIN_FILE \ - -SRCS=\ - ../../../../CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - -SRCS_C=\ - ../../../../C/Threads.c \ - -StdAfx.h.gch : ../../../myWindows/StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -Threads.o : ../../../../C/Threads.c - $(CC) $(CFLAGS) ../../../../C/Threads.c -wxP7ZIP.o : ../../../../CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp -IntToString.o : ../../../../CPP/Common/IntToString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/IntToString.cpp -MyString.o : ../../../../CPP/Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyString.cpp -MyVector.o : ../../../../CPP/Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyVector.cpp -StringConvert.o : ../../../../CPP/Common/StringConvert.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/StringConvert.cpp -FileDir.o : ../../../../CPP/Windows/FileDir.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileDir.cpp -FileFind.o : ../../../../CPP/Windows/FileFind.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileFind.cpp -FileIO.o : ../../../../CPP/Windows/FileIO.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileIO.cpp -FileName.o : ../../../../CPP/Windows/FileName.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Windows/FileName.cpp -MyWindows.o : ../../../../CPP/Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/Common/MyWindows.cpp -wine_date_and_time.o : ../../../../CPP/myWindows/wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) ../../../../CPP/myWindows/wine_date_and_time.cpp - -OBJS=\ - Threads.o \ - wxP7ZIP.o \ - IntToString.o \ - MyString.o \ - MyVector.o \ - StringConvert.o \ - FileDir.o \ - FileFind.o \ - FileIO.o \ - FileName.o \ - MyWindows.o \ - wine_date_and_time.o \ - diff -Nru p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp --- p7zip-rar-16.02/CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp 2015-01-27 19:46:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -// wxFM.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "wx/dnd.h" - -#undef _WIN32 - -#ifdef __WXMAC__ - -#define UInt32 max_UInt32 -#include -#undef UInt32 - -#endif - -#include "Common/StringConvert.h" -#include "Windows/FileDir.h" - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" // global_use_utf16_conversion - -using namespace NWindows; -using namespace NFile; - -/////////////////////////////////////////// - -static LPCWSTR kArchiveNoNameSwitch = L" -an"; - -HRESULT MyCreateProcess(const UString ¶ms,LPCWSTR curDir, bool waitFinish) -{ - printf("MyCreateProcess: waitFinish=%d\n",(unsigned)waitFinish); - printf("\tparams : %ls\n",(const wchar_t*)params); - - printf("\tcurDir : %ls\n",(const wchar_t*)curDir); - - wxString cmd(params); - wxString memoCurDir = wxGetCwd(); - - if (curDir) { // FIXME - wxSetWorkingDirectory(wxString(curDir)); - } - - printf("MyCreateProcess: cmd='%ls'\n",(const wchar_t *)cmd); - long pid = 0; - if (waitFinish) pid = wxExecute(cmd, wxEXEC_SYNC); // FIXME process never ends and stays zombie ... - else pid = wxExecute(cmd, wxEXEC_ASYNC); - - if (curDir) { - wxSetWorkingDirectory(memoCurDir); - } - - // FIXME if (pid == 0) return E_FAIL; - - return S_OK; -} - - - -static HRESULT ExtractGroupCommand(const UStringVector &archivePaths, - const UString ¶ms) -{ - UString params2 = params; -// AddLagePagesSwitch(params2); - params2 += kArchiveNoNameSwitch; - - - char tempFile[256]; - static int count = 1000; - - sprintf(tempFile,"/tmp/7zExtract_%d_%d.tmp",(int)getpid(),count++); - - FILE * file = fopen(tempFile,"w"); - if (file) - { - for (int i = 0; i < archivePaths.Size(); i++) { - fprintf(file,"%ls\n",(const wchar_t *)archivePaths[i]); - printf(" TMP_%d : '%ls'\n",i,(const wchar_t *)archivePaths[i]); - } - - fclose(file); - } - params2 += L" -ai@"; - params2 += GetUnicodeString(tempFile); - printf("ExtractGroupCommand : -%ls-\n",(const wchar_t *)params2); - HRESULT res = MyCreateProcess(params2, 0, true); - printf("ExtractGroupCommand : END\n"); - - remove(tempFile); - - return res; -} - - -HRESULT TestArchives(const UStringVector &archivePaths) -{ - UString params; - params = L"/Users/me/P7ZIP/bin/7zG"; // Get7zGuiPath(); - params += L" t"; - return ExtractGroupCommand(archivePaths, params); -} - -// Define a new application type, each program should derive a class from wxApp -class MyApp : public wxApp -{ -public: - virtual bool OnInit(); -}; - -// Create a new application object: this macro will allow wxWidgets to create -// the application object during program execution (it's better than using a -// static object for many reasons) and also implements the accessor function -// wxGetApp() which will return the reference of the right type (i.e. MyApp and -// not wxApp) -IMPLEMENT_APP(MyApp) - - -class DnDFile : public wxFileDropTarget -{ -public: - DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; } - - virtual bool OnDropFiles(wxCoord x, wxCoord y, - const wxArrayString& filenames); - -private: - wxListBox *m_pOwner; -}; - - - - -bool DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) -{ - size_t nFiles = filenames.GetCount(); - wxString str; - str.Printf( _T("%d files dropped"), (int)nFiles); - m_pOwner->Append(str); - - UStringVector archivePaths; - - for ( size_t n = 0; n < nFiles; n++ ) - { - // m_pOwner->Append(filenames[n]); -/* - if (wxFile::Exists(filenames[n])) - m_pOwner->Append(wxT(" This file exists.") ); - else - m_pOwner->Append(wxT(" This file doesn't exist.") ); -*/ - // cmd = cmd + _T(" \"") + filenames[n] + _T("\""); - const wchar_t * wx = filenames[n].wc_str (); - archivePaths.Add(wx); - } - - /* - m_pOwner->Append(cmd); - - - long pid = 0; - - pid = wxExecute(cmd, wxEXEC_ASYNC); - */ - - TestArchives(archivePaths); - - return true; -} - -////////////////// - -class DnDFrame : public wxFrame -{ -public: - DnDFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h); - virtual ~DnDFrame(); - - void OnQuit(wxCommandEvent& event); - - DECLARE_EVENT_TABLE() - -// private: -public: - // GUI controls - wxListBox *m_ctrlFile; - -}; - -enum -{ - Menu_Quit = 1, - Menu_Drag, - Menu_DragMoveDef, - Menu_DragMoveAllow, - Menu_NewFrame, - Menu_About = 101, - Menu_OpenFile, - Menu_Help, - Menu_Clear, - Menu_Copy, - Menu_Paste, - Menu_CopyBitmap, - Menu_PasteBitmap, - Menu_PasteMFile, - Menu_CopyFiles, - Menu_Shape_New = 500, - Menu_Shape_Edit, - Menu_Shape_Clear, - Menu_ShapeClipboard_Copy, - Menu_ShapeClipboard_Paste, - Button_Colour = 1001 -}; - -DnDFrame::DnDFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h) -: wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h)) -{ - // frame icon and status bar - // FIXME SetIcon(wxICON(sample)); - - - - // construct menu - wxMenu *file_menu = new wxMenu; - file_menu->Append(Menu_Drag, _T("&Test drag...")); - file_menu->AppendCheckItem(Menu_DragMoveDef, _T("&Move by default")); - file_menu->AppendCheckItem(Menu_DragMoveAllow, _T("&Allow moving")); - file_menu->AppendSeparator(); - file_menu->Append(Menu_NewFrame, _T("&New frame\tCtrl-N")); - file_menu->AppendSeparator(); - file_menu->Append(Menu_OpenFile, _T("&Open file...")); - file_menu->AppendSeparator(); - file_menu->Append(Menu_Quit, _T("E&xit\tCtrl-Q")); - - wxMenuBar *menu_bar = new wxMenuBar; - menu_bar->Append(file_menu, _T("&File")); -//#if wxUSE_LOG -// menu_bar->Append(log_menu, _T("&Log")); -//#endif // wxUSE_LOG -// menu_bar->Append(clip_menu, _T("&Clipboard")); -// menu_bar->Append(help_menu, _T("&Help")); - - SetMenuBar(menu_bar); - - - // - // wxString strFile(_T("Drop files here!")); - - wxString str; - wxString str2 = wxString::FromUTF8(getenv("P7ZIP_HOME_DIR")); - str = wxString(_T("P7ZIP_HOME_DIR -")) + str2 + _T("-"); - - wxString strFile(str); - - m_ctrlFile = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, &strFile , - wxLB_HSCROLL | wxLB_ALWAYS_SB ); - - - // m_ctrlFile->Append(str); - - - m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile)); - - wxBoxSizer *sizer_top = new wxBoxSizer( wxHORIZONTAL ); - sizer_top->Add(m_ctrlFile, 1, wxEXPAND ); - - wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL ); -sizer->Add(sizer_top, 2, wxEXPAND ); - -SetSizer(sizer); -sizer->SetSizeHints( this ); - -} - -void DnDFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) -{ - Close(true); -} - -DnDFrame::~DnDFrame() -{ -/* -#if wxUSE_LOG - if ( m_pLog != NULL ) { - if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog ) - delete m_pLog; - } -#endif // wxUSE_LOG - */ -} - - -BEGIN_EVENT_TABLE(DnDFrame, wxFrame) -EVT_MENU(Menu_Quit, DnDFrame::OnQuit) -END_EVENT_TABLE() - -// 'Main program' equivalent: the program execution "starts" here -bool MyApp::OnInit() -{ - // don't parse the command-line options ! - // : if ( !wxApp::OnInit() ) return false; - -#ifdef __WXMAC__ -ProcessSerialNumber PSN; -GetCurrentProcess(&PSN); -TransformProcessType(&PSN,kProcessTransformToForegroundApplication); -#endif - - - { // define P7ZIP_HOME_DIR - extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base); - static char p7zip_home_dir[MAX_PATH]; - - UString fullPath; - NDir::MyGetFullPathName(wxApp::argv[0], fullPath); - AString afullPath = GetAnsiString(fullPath); - - AString dir,name; - - my_windows_split_path(afullPath,dir,name); - - const char *dir2 = nameWindowToUnix((const char *)dir); - snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",dir2); - p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0; - putenv(p7zip_home_dir); - // DEBUG printf("putenv(%s)\n",p7zip_home_dir); - } - global_use_utf16_conversion = 1; // UNICODE ! - - - wxInitAllImageHandlers(); - -// Main1(wxApp::argc,wxApp::argv); - - // create the main frame window - DnDFrame *frame = new DnDFrame((wxFrame *) NULL, - _T("P7ZIP Drag-and-Drop"), - 10, 100, 750, 540); - - - printf("P7ZIP_HOME_DIR : -%s-\n", getenv("P7ZIP_HOME_DIR")); - - - - // activate it - frame->Show(true); - - SetTopWindow(frame); - - - - - - // success: wxApp::OnRun() will be called which will enter the main message - // loop and the application will run. If we returned false here, the - // application would exit immediately. - return true; -} diff -Nru p7zip-rar-16.02/CPP/7zip/UI/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/makefile --- p7zip-rar-16.02/CPP/7zip/UI/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/UI/makefile 2010-10-01 14:35:42.000000000 +0000 @@ -0,0 +1,12 @@ +DIRS = \ + Client7z\~ \ + Console\~ \ + Explorer\~ \ + Far\~ \ + FileManager\~ \ + GUI\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_clang.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_clang.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang.mak 2021-04-28 16:54:36.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_clang.mak +include ../../warn_clang.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_clang_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_arm64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_clang_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_arm64.mak 2021-03-25 08:00:48.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_clang_arm64.mak +include ../../warn_clang.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_clang_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_clang_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x64.mak 2021-03-10 12:08:53.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_clang_x64.mak +include ../../warn_clang.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_clang_x86.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x86.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_clang_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_clang_x86.mak 2021-03-10 12:09:05.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_clang_x86.mak +include ../../warn_clang.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc.mak 2021-03-30 12:08:18.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_gcc.mak +include ../../warn_gcc.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_gcc_arm.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_gcc_arm.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm.mak 2021-03-10 12:11:04.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_gcc_arm.mak +include ../../warn_gcc.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_gcc_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_gcc_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_arm64.mak 2021-04-28 16:55:09.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_gcc_arm64.mak +include ../../warn_gcc.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_gcc_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_gcc_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x64.mak 2021-03-10 12:11:07.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_gcc_x64.mak +include ../../warn_gcc.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_gcc_x86.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x86.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_gcc_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_gcc_x86.mak 2021-03-10 12:11:10.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_gcc_x86.mak +include ../../warn_gcc.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_mac_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_arm64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_mac_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_arm64.mak 2021-04-27 09:48:28.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_mac_arm64.mak +include ../../warn_clang_mac.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/cmpl_mac_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_x64.mak --- p7zip-rar-16.02/CPP/7zip/cmpl_mac_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/cmpl_mac_x64.mak 2021-04-27 09:49:30.000000000 +0000 @@ -0,0 +1,3 @@ +include ../../var_mac_x64.mak +include ../../warn_clang_mac.mak +include makefile.gcc diff -Nru p7zip-rar-16.02/CPP/7zip/makefile p7zip-rar-16.02+really25.00+ds/CPP/7zip/makefile --- p7zip-rar-16.02/CPP/7zip/makefile 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/makefile 2009-11-27 19:54:02.000000000 +0000 @@ -0,0 +1,10 @@ +DIRS = \ + UI\~ \ + Bundles\~ \ + +all: $(DIRS) + +$(DIRS): + cd $(@D) + $(MAKE) -nologo + cd .. diff -Nru p7zip-rar-16.02/CPP/7zip/var_clang.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang.mak --- p7zip-rar-16.02/CPP/7zip/var_clang.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang.mak 2021-04-28 11:31:13.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM= +O=b/c +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/var_clang_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_arm64.mak --- p7zip-rar-16.02/CPP/7zip/var_clang_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_arm64.mak 2024-03-20 06:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +PLATFORM=arm64 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= + +MY_ARCH=-march=armv8-a +MY_ARCH=-march=armv8-a+crypto+crc +MY_ARCH=-march=armv8.3-a+crypto+crc +MY_ARCH= + +USE_ASM= +USE_ASM=1 + +ASM_FLAGS=-Wno-unused-macros +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/var_clang_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x64.mak --- p7zip-rar-16.02/CPP/7zip/var_clang_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x64.mak 2024-01-29 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/c_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/var_clang_x86.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x86.mak --- p7zip-rar-16.02/CPP/7zip/var_clang_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_clang_x86.mak 2024-01-29 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x86 +O=b/c_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/var_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc.mak --- p7zip-rar-16.02/CPP/7zip/var_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc.mak 2021-04-28 11:30:57.000000000 +0000 @@ -0,0 +1,12 @@ +PLATFORM= +O=b/g +IS_X64= +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH= +USE_ASM= +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff -Nru p7zip-rar-16.02/CPP/7zip/var_gcc_arm.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm.mak --- p7zip-rar-16.02/CPP/7zip/var_gcc_arm.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm.mak 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,34 @@ +PLATFORM=arm +O=b/g_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64= + +CROSS_COMPILE_ABI= +CROSS_COMPILE_ABI=arm-linux-musleabi +CROSS_COMPILE_ABI=arm-linux-musleabihf +CROSS_COMPILE_ABI=aarch64-linux-musl +CROSS_COMPILE_ABI=arm-linux-gnueabi +CROSS_COMPILE_ABI=arm-linux-gnueabihf + +COMPILER_VER_POSTFIX=-12 +COMPILER_VER_POSTFIX= + +CROSS_COMPILE_PREFIX= + +CROSS_COMPILE=$(CROSS_COMPILE_PREFIX)$(CROSS_COMPILE_ABI)- +CROSS_COMPILE= + +MY_ARCH= +MY_ARCH=-mtune=cortex-a53 -march=armv7-a +MY_ARCH=-mtune=cortex-a53 -march=armv4 +MY_ARCH=-mtune=cortex-a53 + +USE_ASM= + +LDFLAGS_STATIC_3=-static +LDFLAGS_STATIC_3= + +CC=$(CROSS_COMPILE)gcc$(COMPILER_VER_POSTFIX) +CXX=$(CROSS_COMPILE)g++$(COMPILER_VER_POSTFIX) +# -marm -march=armv5t -march=armv6 -march=armv7-a -march=armv8-a -march=armv8-a+crc+crypto diff -Nru p7zip-rar-16.02/CPP/7zip/var_gcc_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm64.mak --- p7zip-rar-16.02/CPP/7zip/var_gcc_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_arm64.mak 2021-04-28 11:24:49.000000000 +0000 @@ -0,0 +1,12 @@ +PLATFORM=arm64 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +MY_ARCH=-mtune=cortex-a53 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ + +# -march=armv8-a+crc+crypto diff -Nru p7zip-rar-16.02/CPP/7zip/var_gcc_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x64.mak --- p7zip-rar-16.02/CPP/7zip/var_gcc_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x64.mak 2024-01-27 08:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/g_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-mavx512f -mavx512vl +MY_ARCH= +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ diff -Nru p7zip-rar-16.02/CPP/7zip/var_gcc_x86.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x86.mak --- p7zip-rar-16.02/CPP/7zip/var_gcc_x86.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_gcc_x86.mak 2024-01-29 11:00:00.000000000 +0000 @@ -0,0 +1,10 @@ +PLATFORM=x86 +O=b/g_$(PLATFORM) +IS_X64= +IS_X86=1 +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-m32 +USE_ASM=1 +CC=$(CROSS_COMPILE)gcc +CXX=$(CROSS_COMPILE)g++ diff -Nru p7zip-rar-16.02/CPP/7zip/var_mac_arm64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_arm64.mak --- p7zip-rar-16.02/CPP/7zip/var_mac_arm64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_arm64.mak 2024-03-20 07:00:00.000000000 +0000 @@ -0,0 +1,13 @@ +PLATFORM=arm64 +O=b/m_$(PLATFORM) +IS_X64= +IS_X86= +IS_ARM64=1 +CROSS_COMPILE= +#use this code to reduce features +MY_ARCH=-arch arm64 -march=armv8-a +MY_ARCH=-arch arm64 +USE_ASM=1 +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/var_mac_x64.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_x64.mak --- p7zip-rar-16.02/CPP/7zip/var_mac_x64.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/var_mac_x64.mak 2021-04-28 11:26:18.000000000 +0000 @@ -0,0 +1,11 @@ +PLATFORM=x64 +O=b/m_$(PLATFORM) +IS_X64=1 +IS_X86= +IS_ARM64= +CROSS_COMPILE= +MY_ARCH=-arch x86_64 +USE_ASM= +CC=$(CROSS_COMPILE)clang +CXX=$(CROSS_COMPILE)clang++ +USE_CLANG=1 diff -Nru p7zip-rar-16.02/CPP/7zip/warn_clang.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang.mak --- p7zip-rar-16.02/CPP/7zip/warn_clang.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang.mak 2023-05-06 05:00:00.000000000 +0000 @@ -0,0 +1,3 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors +# CXX_STD_FLAGS = -std=c++11 +# CXX_STD_FLAGS = diff -Nru p7zip-rar-16.02/CPP/7zip/warn_clang_mac.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang_mac.mak --- p7zip-rar-16.02/CPP/7zip/warn_clang_mac.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_clang_mac.mak 2023-05-06 05:00:00.000000000 +0000 @@ -0,0 +1,9 @@ +CFLAGS_WARN = -Weverything -Wfatal-errors -Wno-poison-system-directories +CXX_STD_FLAGS = -std=c++98 +CXX_STD_FLAGS = -std=c++11 +CXX_STD_FLAGS = -std=c++14 +CXX_STD_FLAGS = -std=c++17 +CXX_STD_FLAGS = -std=c++20 +CXX_STD_FLAGS = -std=c++23 + +CXX_STD_FLAGS = -std=c++11 diff -Nru p7zip-rar-16.02/CPP/7zip/warn_gcc.mak p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_gcc.mak --- p7zip-rar-16.02/CPP/7zip/warn_gcc.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/7zip/warn_gcc.mak 2024-10-24 06:00:00.000000000 +0000 @@ -0,0 +1,55 @@ +CFLAGS_WARN_GCC_4_8 = \ + -Waddress \ + -Waggressive-loop-optimizations \ + -Wattributes \ + -Wcast-align \ + -Wcomment \ + -Wdiv-by-zero \ + -Wformat-contains-nul \ + -Winit-self \ + -Wint-to-pointer-cast \ + -Wunused \ + -Wunused-macros \ + +CFLAGS_WARN_GCC_5 = $(CFLAGS_WARN_GCC_4_8)\ + -Wbool-compare \ + +CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_5)\ + -Wduplicated-cond \ + +# -Wno-strict-aliasing + +CFLAGS_WARN_GCC_7 = $(CFLAGS_WARN_GCC_6)\ + -Wbool-operation \ + -Wconversion \ + -Wdangling-else \ + -Wduplicated-branches \ + -Wimplicit-fallthrough=5 \ + -Wint-in-bool-context \ + -Wmaybe-uninitialized \ + -Wmisleading-indentation \ + +CFLAGS_WARN_GCC_8 = $(CFLAGS_WARN_GCC_7)\ + -Wcast-align=strict \ + -Wmissing-attributes + +CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_8)\ + -Waddress-of-packed-member \ + +# In C: -Wsign-conversion enabled also by -Wconversion +# -Wno-sign-conversion \ + + +CFLAGS_WARN_GCC_PPMD_UNALIGNED = \ + -Wno-strict-aliasing \ + + +CFLAGS_WARN = $(CFLAGS_WARN_GCC_4_8) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_5) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_6) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_7) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_8) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) + +# CXX_STD_FLAGS = -std=c++11 +# CXX_STD_FLAGS = diff -Nru p7zip-rar-16.02/CPP/ANDROID/7z/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/7z/jni/Android.mk 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -# -# build 7z for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := 7z - -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows -LOCAL_SRC_FILES := \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Windows/DLL.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/Alloc.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Threads.c \ - -# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+) -LOCAL_CFLAGS += -fPIE -LOCAL_LDFLAGS += -fPIE -pie - -include $(BUILD_EXECUTABLE) - diff -Nru p7zip-rar-16.02/CPP/ANDROID/7z/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/7z/jni/Application.mk 2011-06-12 15:07:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/7z/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/makefile --- p7zip-rar-16.02/CPP/ANDROID/7z/makefile 2011-06-12 15:42:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7z/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ - -TARGET=7z - -include ../makefile.inc - -test: install - adb shell $(DEVICE_DIR)/$(TARGET) b - -test_all: install - adb push ../../../check/test/7za433_7zip_lzma.7z $(DEVICE_DIR) - adb shell $(DEVICE_DIR)/7za t $(DEVICE_DIR)/7za433_7zip_lzma.7z - diff -Nru p7zip-rar-16.02/CPP/ANDROID/7za/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/7za/jni/Android.mk 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,264 +0,0 @@ -# -# build 7za for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := 7za - -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../7zip/Archive \ - -I../../../7zip/Archive/7z \ - -I../../../7zip/Archive/BZip2 \ - -I../../../7zip/Archive/Common \ - -I../../../7zip/Archive/GZip \ - -I../../../7zip/Archive/Cab \ - -I../../../7zip/Archive/Lzma \ - -I../../../7zip/Archive/Tar \ - -I../../../7zip/Archive/Zip \ - -I../../../7zip/Archive/Split \ - -I../../../7zip/Archive/Z \ - -I../../../7zip/Compress \ - -I../../../7zip/Crypto \ - -I../../../7zip/UI/Console \ - -I../../../7zip/UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -LOCAL_SRC_FILES := \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+) -LOCAL_CFLAGS += -fPIE -LOCAL_LDFLAGS += -fPIE -pie - -include $(BUILD_EXECUTABLE) - diff -Nru p7zip-rar-16.02/CPP/ANDROID/7za/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/7za/jni/Application.mk 2011-06-12 15:07:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi -# p7zip armeabi and armeabi-v7a run at the same speed (p7zip does not use FPU) -# APP_ABI := armeabi armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/7za/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/makefile --- p7zip-rar-16.02/CPP/ANDROID/7za/makefile 2011-06-12 16:50:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7za/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ - -TARGET=7za - -include ../makefile.inc - -test: install - adb shell $(DEVICE_DIR)/7za b - -test_crc: install - adb shell $(DEVICE_DIR)/7za -mm=crc b - -test_complex: install - adb shell $(DEVICE_DIR)/7za "-mm=*" b - -test2: - adb push ./libs/armeabi-v7a/7za $(DEVICE_DIR)/7za-v7a - adb shell chmod 777 $(DEVICE_DIR)/7za-v7a - adb shell $(DEVICE_DIR)/7za-v7a b - -test_all: install - adb push ../../../check/test/7za433_7zip_lzma.7z $(DEVICE_DIR) - adb shell $(DEVICE_DIR)/7za t $(DEVICE_DIR)/7za433_7zip_lzma.7z - -bench: install test - -# FIXME -debug: - cd jni ; ndk-build NDK_DEBUG=1 - adb push ./libs/armeabi/7za /data/app/ - adb push ./libs/armeabi/gdbserver /data/app/ - adb shell chmod 777 /data/app/7za - adb shell chmod 777 /data/app/gdbserver - adb forward tcp:1234: tcp:1234 - adb shell /data/app/gdbserver :1234 /data/app/7za - diff -Nru p7zip-rar-16.02/CPP/ANDROID/7zr/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/7zr/jni/Android.mk 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -# -# build 7zr for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := 7zr - -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DBREAK_HANDLER -D_NO_CRYPTO \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../7zip/Archive \ - -I../../../7zip/Archive/7z \ - -I../../../7zip/Archive/BZip2 \ - -I../../../7zip/Archive/Common \ - -I../../../7zip/Archive/GZip \ - -I../../../7zip/Archive/Cab \ - -I../../../7zip/Archive/Lzma \ - -I../../../7zip/Archive/Tar \ - -I../../../7zip/Archive/Zip \ - -I../../../7zip/Archive/Split \ - -I../../../7zip/Archive/Z \ - -I../../../7zip/Compress \ - -I../../../7zip/Crypto \ - -I../../../7zip/UI/Console \ - -I../../../7zip/UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -LOCAL_SRC_FILES := \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilePathAutoRename.cpp \ - ../../../../CPP/7zip/Common/FileStreams.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveCommandLine.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveExtractCallback.cpp \ - ../../../../CPP/7zip/UI/Common/ArchiveOpenCallback.cpp \ - ../../../../CPP/7zip/UI/Common/Bench.cpp \ - ../../../../CPP/7zip/UI/Common/DefaultName.cpp \ - ../../../../CPP/7zip/UI/Common/EnumDirItems.cpp \ - ../../../../CPP/7zip/UI/Common/Extract.cpp \ - ../../../../CPP/7zip/UI/Common/ExtractingFilePath.cpp \ - ../../../../CPP/7zip/UI/Common/HashCalc.cpp \ - ../../../../CPP/7zip/UI/Common/LoadCodecs.cpp \ - ../../../../CPP/7zip/UI/Common/OpenArchive.cpp \ - ../../../../CPP/7zip/UI/Common/PropIDUtils.cpp \ - ../../../../CPP/7zip/UI/Common/SetProperties.cpp \ - ../../../../CPP/7zip/UI/Common/SortUtils.cpp \ - ../../../../CPP/7zip/UI/Common/TempFiles.cpp \ - ../../../../CPP/7zip/UI/Common/Update.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateAction.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateCallback.cpp \ - ../../../../CPP/7zip/UI/Common/UpdatePair.cpp \ - ../../../../CPP/7zip/UI/Common/UpdateProduce.cpp \ - ../../../../CPP/7zip/UI/Console/BenchCon.cpp \ - ../../../../CPP/7zip/UI/Console/ConsoleClose.cpp \ - ../../../../CPP/7zip/UI/Console/ExtractCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/HashCon.cpp \ - ../../../../CPP/7zip/UI/Console/List.cpp \ - ../../../../CPP/7zip/UI/Console/Main.cpp \ - ../../../../CPP/7zip/UI/Console/MainAr.cpp \ - ../../../../CPP/7zip/UI/Console/OpenCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/PercentPrinter.cpp \ - ../../../../CPP/7zip/UI/Console/UpdateCallbackConsole.cpp \ - ../../../../CPP/7zip/UI/Console/UserInputUtils.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CommandLineParser.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/ListFileUtils.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StdInStream.cpp \ - ../../../../CPP/Common/StdOutStream.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/ErrorMsg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantConv.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/myAddExeFlag.cpp \ - ../../../../CPP/myWindows/mySplitCommandLine.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Sha256.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+) -LOCAL_CFLAGS += -fPIE -LOCAL_LDFLAGS += -fPIE -pie - -include $(BUILD_EXECUTABLE) - diff -Nru p7zip-rar-16.02/CPP/ANDROID/7zr/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/7zr/jni/Application.mk 2011-06-12 15:07:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi -# p7zip armeabi and armeabi-v7a run at the same speed (p7zip does not use FPU) -# APP_ABI := armeabi armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/7zr/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/makefile --- p7zip-rar-16.02/CPP/ANDROID/7zr/makefile 2015-01-18 16:05:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/7zr/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ - -TARGET=7zr - -include ../makefile.inc - -test: install - adb shell $(DEVICE_DIR)/7zr b - -test_crc: install - adb shell $(DEVICE_DIR)/7zr -mm=crc b - -test_complex: install - adb shell $(DEVICE_DIR)/7zr "-mm=*" b - -test2: - adb push ./libs/armeabi-v7a/7zr $(DEVICE_DIR)/7zr-v7a - adb shell chmod 777 $(DEVICE_DIR)/7zr-v7a - adb shell $(DEVICE_DIR)/7zr-v7a b - -test_all: install - adb push ../../../check/test/7zr433_7zip_lzma.7z $(DEVICE_DIR) - adb shell $(DEVICE_DIR)/7zr t $(DEVICE_DIR)/7zr433_7zip_lzma.7z - -bench: install test - -# FIXME -debug: - cd jni ; ndk-build NDK_DEBUG=1 - adb push ./libs/armeabi/7zr /data/app/ - adb push ./libs/armeabi/gdbserver /data/app/ - adb shell chmod 777 /data/app/7zr - adb shell chmod 777 /data/app/gdbserver - adb forward tcp:1234: tcp:1234 - adb shell /data/app/gdbserver :1234 /data/app/7zr - diff -Nru p7zip-rar-16.02/CPP/ANDROID/Format7zFree/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/Format7zFree/jni/Android.mk 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,272 +0,0 @@ -# -# build 7z for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := 7z - -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ - -I../../../myWindows \ - -I../../../ \ - -I../../../include_windows - -LOCAL_SRC_FILES := \ - ../../../../CPP/7zip/Archive/7z/7zCompressionMode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zDecode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zEncode.cpp \ - ../../../../CPP/7zip/Archive/7z/7zExtract.cpp \ - ../../../../CPP/7zip/Archive/7z/7zFolderInStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandler.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zHeader.cpp \ - ../../../../CPP/7zip/Archive/7z/7zIn.cpp \ - ../../../../CPP/7zip/Archive/7z/7zOut.cpp \ - ../../../../CPP/7zip/Archive/7z/7zProperties.cpp \ - ../../../../CPP/7zip/Archive/7z/7zRegister.cpp \ - ../../../../CPP/7zip/Archive/7z/7zSpecStream.cpp \ - ../../../../CPP/7zip/Archive/7z/7zUpdate.cpp \ - ../../../../CPP/7zip/Archive/ApmHandler.cpp \ - ../../../../CPP/7zip/Archive/ArHandler.cpp \ - ../../../../CPP/7zip/Archive/ArchiveExports.cpp \ - ../../../../CPP/7zip/Archive/ArjHandler.cpp \ - ../../../../CPP/7zip/Archive/Bz2Handler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabBlockInStream.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHandler.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabHeader.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabIn.cpp \ - ../../../../CPP/7zip/Archive/Cab/CabRegister.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmHandler.cpp \ - ../../../../CPP/7zip/Archive/Chm/ChmIn.cpp \ - ../../../../CPP/7zip/Archive/ComHandler.cpp \ - ../../../../CPP/7zip/Archive/Common/CoderMixer2.cpp \ - ../../../../CPP/7zip/Archive/Common/DummyOutStream.cpp \ - ../../../../CPP/7zip/Archive/Common/FindSignature.cpp \ - ../../../../CPP/7zip/Archive/Common/HandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Common/InStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/ItemNameUtils.cpp \ - ../../../../CPP/7zip/Archive/Common/MultiStream.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithCRC.cpp \ - ../../../../CPP/7zip/Archive/Common/OutStreamWithSha1.cpp \ - ../../../../CPP/7zip/Archive/Common/ParseProperties.cpp \ - ../../../../CPP/7zip/Archive/CpioHandler.cpp \ - ../../../../CPP/7zip/Archive/CramfsHandler.cpp \ - ../../../../CPP/7zip/Archive/DeflateProps.cpp \ - ../../../../CPP/7zip/Archive/DllExports2.cpp \ - ../../../../CPP/7zip/Archive/DmgHandler.cpp \ - ../../../../CPP/7zip/Archive/ElfHandler.cpp \ - ../../../../CPP/7zip/Archive/ExtHandler.cpp \ - ../../../../CPP/7zip/Archive/FatHandler.cpp \ - ../../../../CPP/7zip/Archive/FlvHandler.cpp \ - ../../../../CPP/7zip/Archive/GzHandler.cpp \ - ../../../../CPP/7zip/Archive/GptHandler.cpp \ - ../../../../CPP/7zip/Archive/HandlerCont.cpp \ - ../../../../CPP/7zip/Archive/HfsHandler.cpp \ - ../../../../CPP/7zip/Archive/IhexHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHandler.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoHeader.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoIn.cpp \ - ../../../../CPP/7zip/Archive/Iso/IsoRegister.cpp \ - ../../../../CPP/7zip/Archive/LzhHandler.cpp \ - ../../../../CPP/7zip/Archive/LzmaHandler.cpp \ - ../../../../CPP/7zip/Archive/MachoHandler.cpp \ - ../../../../CPP/7zip/Archive/MbrHandler.cpp \ - ../../../../CPP/7zip/Archive/MslzHandler.cpp \ - ../../../../CPP/7zip/Archive/MubHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisDecode.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisHandler.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisIn.cpp \ - ../../../../CPP/7zip/Archive/Nsis/NsisRegister.cpp \ - ../../../../CPP/7zip/Archive/NtfsHandler.cpp \ - ../../../../CPP/7zip/Archive/PeHandler.cpp \ - ../../../../CPP/7zip/Archive/PpmdHandler.cpp \ - ../../../../CPP/7zip/Archive/QcowHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/RarHandler.cpp \ - ../../../../CPP/7zip/Archive/Rar/Rar5Handler.cpp \ - ../../../../CPP/7zip/Archive/RpmHandler.cpp \ - ../../../../CPP/7zip/Archive/SplitHandler.cpp \ - ../../../../CPP/7zip/Archive/SquashfsHandler.cpp \ - ../../../../CPP/7zip/Archive/SwfHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandler.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarHeader.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarIn.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarOut.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarRegister.cpp \ - ../../../../CPP/7zip/Archive/Tar/TarUpdate.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfHandler.cpp \ - ../../../../CPP/7zip/Archive/Udf/UdfIn.cpp \ - ../../../../CPP/7zip/Archive/UefiHandler.cpp \ - ../../../../CPP/7zip/Archive/VdiHandler.cpp \ - ../../../../CPP/7zip/Archive/VhdHandler.cpp \ - ../../../../CPP/7zip/Archive/VmdkHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandler.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimIn.cpp \ - ../../../../CPP/7zip/Archive/Wim/WimRegister.cpp \ - ../../../../CPP/7zip/Archive/XarHandler.cpp \ - ../../../../CPP/7zip/Archive/XzHandler.cpp \ - ../../../../CPP/7zip/Archive/ZHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipAddCommon.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandler.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipHandlerOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipIn.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipItem.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipOut.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipRegister.cpp \ - ../../../../CPP/7zip/Archive/Zip/ZipUpdate.cpp \ - ../../../../CPP/7zip/Common/CWrappers.cpp \ - ../../../../CPP/7zip/Common/CreateCoder.cpp \ - ../../../../CPP/7zip/Common/FilterCoder.cpp \ - ../../../../CPP/7zip/Common/InBuffer.cpp \ - ../../../../CPP/7zip/Common/InOutTempBuffer.cpp \ - ../../../../CPP/7zip/Common/LimitedStreams.cpp \ - ../../../../CPP/7zip/Common/MemBlocks.cpp \ - ../../../../CPP/7zip/Common/MethodId.cpp \ - ../../../../CPP/7zip/Common/MethodProps.cpp \ - ../../../../CPP/7zip/Common/OffsetStream.cpp \ - ../../../../CPP/7zip/Common/OutBuffer.cpp \ - ../../../../CPP/7zip/Common/OutMemStream.cpp \ - ../../../../CPP/7zip/Common/ProgressMt.cpp \ - ../../../../CPP/7zip/Common/ProgressUtils.cpp \ - ../../../../CPP/7zip/Common/PropId.cpp \ - ../../../../CPP/7zip/Common/StreamBinder.cpp \ - ../../../../CPP/7zip/Common/StreamObjects.cpp \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Common/UniqBlocks.cpp \ - ../../../../CPP/7zip/Common/VirtThread.cpp \ - ../../../../CPP/7zip/Compress/BZip2Crc.cpp \ - ../../../../CPP/7zip/Compress/BZip2Decoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Encoder.cpp \ - ../../../../CPP/7zip/Compress/BZip2Register.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Coder.cpp \ - ../../../../CPP/7zip/Compress/Bcj2Register.cpp \ - ../../../../CPP/7zip/Compress/BcjCoder.cpp \ - ../../../../CPP/7zip/Compress/BcjRegister.cpp \ - ../../../../CPP/7zip/Compress/BitlDecoder.cpp \ - ../../../../CPP/7zip/Compress/BranchMisc.cpp \ - ../../../../CPP/7zip/Compress/BranchRegister.cpp \ - ../../../../CPP/7zip/Compress/ByteSwap.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/CopyCoder.cpp \ - ../../../../CPP/7zip/Compress/CopyRegister.cpp \ - ../../../../CPP/7zip/Compress/Deflate64Register.cpp \ - ../../../../CPP/7zip/Compress/DeflateDecoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateEncoder.cpp \ - ../../../../CPP/7zip/Compress/DeflateRegister.cpp \ - ../../../../CPP/7zip/Compress/DeltaFilter.cpp \ - ../../../../CPP/7zip/Compress/ImplodeDecoder.cpp \ - ../../../../CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzOutWindow.cpp \ - ../../../../CPP/7zip/Compress/LzhDecoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Decoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Encoder.cpp \ - ../../../../CPP/7zip/Compress/Lzma2Register.cpp \ - ../../../../CPP/7zip/Compress/LzmaDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaEncoder.cpp \ - ../../../../CPP/7zip/Compress/LzmaRegister.cpp \ - ../../../../CPP/7zip/Compress/LzmsDecoder.cpp \ - ../../../../CPP/7zip/Compress/LzxDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdDecoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdEncoder.cpp \ - ../../../../CPP/7zip/Compress/PpmdRegister.cpp \ - ../../../../CPP/7zip/Compress/PpmdZip.cpp \ - ../../../../CPP/7zip/Compress/QuantumDecoder.cpp \ - ../../../../CPP/7zip/Compress/ShrinkDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZDecoder.cpp \ - ../../../../CPP/7zip/Compress/XpressDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibDecoder.cpp \ - ../../../../CPP/7zip/Compress/ZlibEncoder.cpp \ - ../../../../CPP/7zip/Crypto/7zAes.cpp \ - ../../../../CPP/7zip/Crypto/7zAesRegister.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/HmacSha256.cpp \ - ../../../../CPP/7zip/Crypto/MyAes.cpp \ - ../../../../CPP/7zip/Crypto/MyAesReg.cpp \ - ../../../../CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp \ - ../../../../CPP/7zip/Crypto/RandGen.cpp \ - ../../../../CPP/7zip/Crypto/Rar20Crypto.cpp \ - ../../../../CPP/7zip/Crypto/Rar5Aes.cpp \ - ../../../../CPP/7zip/Crypto/RarAes.cpp \ - ../../../../CPP/7zip/Crypto/WzAes.cpp \ - ../../../../CPP/7zip/Crypto/ZipCrypto.cpp \ - ../../../../CPP/7zip/Crypto/ZipStrong.cpp \ - ../../../../CPP/Common/CRC.cpp \ - ../../../../CPP/Common/CrcReg.cpp \ - ../../../../CPP/Common/DynLimBuf.cpp \ - ../../../../CPP/Common/IntToString.cpp \ - ../../../../CPP/Common/MyMap.cpp \ - ../../../../CPP/Common/MyString.cpp \ - ../../../../CPP/Common/MyVector.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Common/MyXml.cpp \ - ../../../../CPP/Common/NewHandler.cpp \ - ../../../../CPP/Common/Sha1Reg.cpp \ - ../../../../CPP/Common/Sha256Reg.cpp \ - ../../../../CPP/Common/StringConvert.cpp \ - ../../../../CPP/Common/StringToInt.cpp \ - ../../../../CPP/Common/UTFConvert.cpp \ - ../../../../CPP/Common/Wildcard.cpp \ - ../../../../CPP/Common/XzCrc64Reg.cpp \ - ../../../../CPP/Windows/FileDir.cpp \ - ../../../../CPP/Windows/FileFind.cpp \ - ../../../../CPP/Windows/FileIO.cpp \ - ../../../../CPP/Windows/FileName.cpp \ - ../../../../CPP/Windows/PropVariant.cpp \ - ../../../../CPP/Windows/PropVariantUtils.cpp \ - ../../../../CPP/Windows/Synchronization.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/Windows/TimeUtils.cpp \ - ../../../../CPP/myWindows/wine_date_and_time.cpp \ - ../../../../C/7zBuf2.c \ - ../../../../C/7zCrc.c \ - ../../../../C/7zCrcOpt.c \ - ../../../../C/7zStream.c \ - ../../../../C/Aes.c \ - ../../../../C/Alloc.c \ - ../../../../C/Bcj2.c \ - ../../../../C/Bcj2Enc.c \ - ../../../../C/Blake2s.c \ - ../../../../C/Bra.c \ - ../../../../C/Bra86.c \ - ../../../../C/BraIA64.c \ - ../../../../C/BwtSort.c \ - ../../../../C/CpuArch.c \ - ../../../../C/Delta.c \ - ../../../../C/HuffEnc.c \ - ../../../../C/LzFind.c \ - ../../../../C/LzFindMt.c \ - ../../../../C/Lzma2Dec.c \ - ../../../../C/Lzma2Enc.c \ - ../../../../C/LzmaDec.c \ - ../../../../C/LzmaEnc.c \ - ../../../../C/MtCoder.c \ - ../../../../C/Ppmd7.c \ - ../../../../C/Ppmd7Dec.c \ - ../../../../C/Ppmd7Enc.c \ - ../../../../C/Ppmd8.c \ - ../../../../C/Ppmd8Dec.c \ - ../../../../C/Ppmd8Enc.c \ - ../../../../C/Sha1.c \ - ../../../../C/Sha256.c \ - ../../../../C/Sort.c \ - ../../../../C/Threads.c \ - ../../../../C/Xz.c \ - ../../../../C/XzCrc64.c \ - ../../../../C/XzCrc64Opt.c \ - ../../../../C/XzDec.c \ - ../../../../C/XzEnc.c \ - ../../../../C/XzIn.c \ - -include $(BUILD_SHARED_LIBRARY) - diff -Nru p7zip-rar-16.02/CPP/ANDROID/Format7zFree/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/Format7zFree/jni/Application.mk 2011-06-12 15:07:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/Format7zFree/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/makefile --- p7zip-rar-16.02/CPP/ANDROID/Format7zFree/makefile 2011-06-12 15:24:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Format7zFree/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - -TARGET=lib7z.so - -all: build - -include ../makefile.inc - -install:: - adb shell mv $(DEVICE_DIR)/$(TARGET) $(DEVICE_DIR)/7z.so - diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/Lzham/jni/Android.mk 2016-03-10 07:27:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -# -# build Lzham for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := Lzham - -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows \ --I../../../../CPP/7zip/Compress/Lzham/include \ --I../../../../CPP/7zip/Compress/Lzham/lzhamcomp \ --I../../../../CPP/7zip/Compress/Lzham/lzhamdecomp - -LOCAL_SRC_FILES := \ - ../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../../CPP/7zip/Compress/Lzham/LzhamRegister.cpp \ - ../../../../CPP/Common/MyWindows.cpp \ - ../../../../CPP/Windows/System.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp \ - ../../../../CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp \ - ../../../../C/Alloc.c \ - -include $(BUILD_SHARED_LIBRARY) - diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/Lzham/jni/Application.mk 2016-03-10 07:50:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/makefile --- p7zip-rar-16.02/CPP/ANDROID/Lzham/makefile 2016-03-10 07:23:51.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ - -TARGET=lzham - -all: build - -include ../makefile.inc - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o differ diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o.d p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o.d --- p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o.d 2016-03-10 07:50:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o.d 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Common/StreamUtils.o: \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/StreamUtils.cpp \ - ../../../myWindows/StdAfx.h ../../../myWindows/config.h \ - ../../../Common/Common.h ../../../Common/../../C/Compiler.h \ - ../../../Common/MyWindows.h ../../../Common/MyGuidDef.h \ - ../../../Common/MyTypes.h ../../../Common/../../C/7zTypes.h \ - ../../../Common/NewHandler.h ../../../Common/MyWindows.h \ - ../../../Common/MyTypes.h ../../../Common/MyString.h \ - ../../../Common/MyVector.h ../../../include_windows/windows.h \ - ../../../include_windows/basetyps.h ../../../include_windows/tchar.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/StreamUtils.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../IStream.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../IDecl.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyUnknown.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyWindows.h - -../../../myWindows/StdAfx.h: - -../../../myWindows/config.h: - -../../../Common/Common.h: - -../../../Common/../../C/Compiler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyGuidDef.h: - -../../../Common/MyTypes.h: - -../../../Common/../../C/7zTypes.h: - -../../../Common/NewHandler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyTypes.h: - -../../../Common/MyString.h: - -../../../Common/MyVector.h: - -../../../include_windows/windows.h: - -../../../include_windows/basetyps.h: - -../../../include_windows/tchar.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/StreamUtils.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../IStream.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../IDecl.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyUnknown.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Common/../../Common/MyWindows.h: Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o differ diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o.d p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o.d --- p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o.d 2016-03-10 07:50:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o.d 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/CodecExports.o: \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/CodecExports.cpp \ - ../../../myWindows/StdAfx.h ../../../myWindows/config.h \ - ../../../Common/Common.h ../../../Common/../../C/Compiler.h \ - ../../../Common/MyWindows.h ../../../Common/MyGuidDef.h \ - ../../../Common/MyTypes.h ../../../Common/../../C/7zTypes.h \ - ../../../Common/NewHandler.h ../../../Common/MyWindows.h \ - ../../../Common/MyTypes.h ../../../Common/MyString.h \ - ../../../Common/MyVector.h ../../../include_windows/windows.h \ - ../../../include_windows/basetyps.h ../../../include_windows/tchar.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../../C/CpuArch.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../../C/7zTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/ComTry.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyCom.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/NewHandler.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Windows/Defs.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Windows/../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../ICoder.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IStream.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IDecl.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyUnknown.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/RegisterCodec.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/MethodId.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/../../Common/MyTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../ICoder.h - -../../../myWindows/StdAfx.h: - -../../../myWindows/config.h: - -../../../Common/Common.h: - -../../../Common/../../C/Compiler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyGuidDef.h: - -../../../Common/MyTypes.h: - -../../../Common/../../C/7zTypes.h: - -../../../Common/NewHandler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyTypes.h: - -../../../Common/MyString.h: - -../../../Common/MyVector.h: - -../../../include_windows/windows.h: - -../../../include_windows/basetyps.h: - -../../../include_windows/tchar.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../../C/CpuArch.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../../C/7zTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/ComTry.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyCom.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/NewHandler.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Windows/Defs.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Windows/../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../ICoder.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IStream.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IDecl.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyUnknown.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/RegisterCodec.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/MethodId.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/../../Common/MyTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../ICoder.h: Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o differ diff -Nru p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o.d p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o.d --- p7zip-rar-16.02/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o.d 2016-03-10 07:50:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o.d 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/obj/local/armeabi/objs/Lzham/__/__/__/__/CPP/7zip/Compress/DllExportsCompress.o: \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/DllExportsCompress.cpp \ - ../../../myWindows/StdAfx.h ../../../myWindows/config.h \ - ../../../Common/Common.h ../../../Common/../../C/Compiler.h \ - ../../../Common/MyWindows.h ../../../Common/MyGuidDef.h \ - ../../../Common/MyTypes.h ../../../Common/../../C/7zTypes.h \ - ../../../Common/NewHandler.h ../../../Common/MyWindows.h \ - ../../../Common/MyTypes.h ../../../Common/MyString.h \ - ../../../Common/MyVector.h ../../../include_windows/windows.h \ - ../../../include_windows/basetyps.h ../../../include_windows/tchar.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyInitGuid.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyGuidDef.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../ICoder.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IStream.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IDecl.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyUnknown.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/RegisterCodec.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/MethodId.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/../../Common/MyTypes.h \ - /media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../ICoder.h - -../../../myWindows/StdAfx.h: - -../../../myWindows/config.h: - -../../../Common/Common.h: - -../../../Common/../../C/Compiler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyGuidDef.h: - -../../../Common/MyTypes.h: - -../../../Common/../../C/7zTypes.h: - -../../../Common/NewHandler.h: - -../../../Common/MyWindows.h: - -../../../Common/MyTypes.h: - -../../../Common/MyString.h: - -../../../Common/MyVector.h: - -../../../include_windows/windows.h: - -../../../include_windows/basetyps.h: - -../../../include_windows/tchar.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyInitGuid.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyGuidDef.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../ICoder.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IStream.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../IDecl.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyUnknown.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../../Common/MyWindows.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/RegisterCodec.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/MethodId.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../Common/../../Common/MyTypes.h: - -/media/me/DISK_COMPLEMENT/me/P7ZIP/p7zip_15.14_030/CPP/ANDROID/Lzham/jni/../../../../CPP/7zip/Compress/../Common/../ICoder.h: diff -Nru p7zip-rar-16.02/CPP/ANDROID/MemLat/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/MemLat/jni/Android.mk 2011-06-12 18:27:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -# -# build MemLat for armeabi and armeabi-v7a CPU -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := MemLat -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DNUM_DIRECT_TESTS=6 -DNUM_PAR_TESTS=5 \ - -I../../../../Utils/CPUTest/MemLat - - -LOCAL_SRC_FILES := \ - ../../../../Utils/CPUTest/MemLat/MemLat.cpp \ - ../../../../Utils/CPUTest/MemLat/Walk.c - -include $(BUILD_EXECUTABLE) diff -Nru p7zip-rar-16.02/CPP/ANDROID/MemLat/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/MemLat/jni/Application.mk 2011-06-12 18:24:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/MemLat/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/makefile --- p7zip-rar-16.02/CPP/ANDROID/MemLat/makefile 2011-06-12 18:28:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/MemLat/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - -TARGET=MemLat - -all: build - -include ../makefile.inc - - -test: install - adb shell $(DEVICE_DIR)/$(TARGET) 4 p5 n - -# simple memlat test: -# MemLat 4 p5 n - diff -Nru p7zip-rar-16.02/CPP/ANDROID/PipeLen/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/PipeLen/jni/Android.mk 2011-06-12 18:22:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -# -# build PipeLen for armeabi and armeabi-v7a CPU -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := PipeLen -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DUNICODE \ - -D_UNICODE \ --I../../../../Utils/CPUTest/PipeLen - - -LOCAL_SRC_FILES := \ - ../../../../Utils/CPUTest/PipeLen/PipeLen.cpp - -include $(BUILD_EXECUTABLE) diff -Nru p7zip-rar-16.02/CPP/ANDROID/PipeLen/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/PipeLen/jni/Application.mk 2011-06-12 18:20:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/PipeLen/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/makefile --- p7zip-rar-16.02/CPP/ANDROID/PipeLen/makefile 2011-06-12 18:43:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/PipeLen/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ - -TARGET=PipeLen - -all: build - -include ../makefile.inc - - -test: install - adb shell $(DEVICE_DIR)/$(TARGET) r0 n - -# One pipelen test: -# pipelen r0 n -# All pipelen tests (too long) : -# pipelen n - diff -Nru p7zip-rar-16.02/CPP/ANDROID/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile --- p7zip-rar-16.02/CPP/ANDROID/makefile 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ - - -all: - $(MAKE) -C 7za all - $(MAKE) -C 7z all - $(MAKE) -C 7zr all - $(MAKE) -C Format7zFree all - $(MAKE) -C test_lib all - $(MAKE) -C MemLat all - $(MAKE) -C PipeLen all - -clean: - $(MAKE) -C 7za clean - $(MAKE) -C 7z clean - $(MAKE) -C 7zr clean - $(MAKE) -C Format7zFree clean - $(MAKE) -C test_lib clean - $(MAKE) -C MemLat clean - $(MAKE) -C PipeLen clean - -install: all - $(MAKE) -C 7za install - $(MAKE) -C 7z install - $(MAKE) -C 7zr install - $(MAKE) -C Format7zFree install - $(MAKE) -C test_lib install - $(MAKE) -C MemLat install - $(MAKE) -C PipeLen install - - diff -Nru p7zip-rar-16.02/CPP/ANDROID/makefile.inc p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile.inc --- p7zip-rar-16.02/CPP/ANDROID/makefile.inc 2014-12-29 21:52:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/makefile.inc 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ - -# For emulator -# DEVICE_DIR=/data/app - -# DEVICE_DIR=/sdcard/P7ZIP # cannot do "chmod 777" - -# For ACER ICONIA A500 -# For SAMSUNG S II -# DEVICE_DIR=/data/local/P7ZIP - -# For Samsung Galaxy Note 3 -DEVICE_DIR=/data/local/tmp/P7ZIP - -all: build - -build: - cd jni ; ndk-build NDK_DEBUG=0 V=1 - -install:: - adb shell mkdir $(DEVICE_DIR) - adb push ./libs/armeabi/$(TARGET) $(DEVICE_DIR) - adb shell chmod 777 $(DEVICE_DIR)/$(TARGET) - -# adb push ./libs/armeabi-v7a/$(TARGET) $(DEVICE_DIR)/$(TARGET)-v7a -# adb shell chmod 777 $(DEVICE_DIR)/$(TARGET)-v7a - - -mkdir: - adb shell mkdir $(DEVICE_DIR) - -clean: - rm -fr libs obj - diff -Nru p7zip-rar-16.02/CPP/ANDROID/readme.txt p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/readme.txt --- p7zip-rar-16.02/CPP/ANDROID/readme.txt 2011-06-12 18:54:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/readme.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ - -to compile : --------------- -- you need ANDROID NDK - - -make all : build all the programs -make install : install all the programs -make clean : clean all - -to test : - -cd 7za -make test - -look at the makefile to see other tests - - - - -III. Debuggable versus Release builds: --------------------------------------- - -In NDK r5, ndk-build has been modified to make it easier to switch between -release and debug builds. This is done by using the NDK_DEBUG variable. -For example: - - $NDK/ndk-build NDK_DEBUG=1 => forces the generation of debug binaries - $NDK/ndk-build NDK_DEBUG=0 => forces the generation of release binaries - -If you don't specify NDK_DEBUG, ndk-build will keep its default behaviour, -which is to inspect the AndroidManifest.xml, if any, and see if its - element has android:debuggable="true". - -IMPORTANT: If you use the build tools of SDK r8 (or higher), you - won't need to touch your AndroidManifest.xml file at all! - - That's because if you build a debug package (e.g. with - "ant debug" or the corresponding option of the ADT plugin), - the tool will automatically pick the native debug files - generated with NDK_DEBUG=1. - -Also, as a convenience, the release and debug object files generated by the -NDK are now stored in different directories (e.g. obj/local//objs and -obj/local//objs-debug). This avoids having to recompile all your sources -when you switch between these two modes (even when you only modified one or -two source files). - diff -Nru p7zip-rar-16.02/CPP/ANDROID/test_lib/jni/Android.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Android.mk --- p7zip-rar-16.02/CPP/ANDROID/test_lib/jni/Android.mk 2016-03-10 07:15:57.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -# -# build test_lib for armeabi and armeabi-v7a CPU -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := test_lib -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DUNICODE \ - -D_UNICODE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - - -LOCAL_SRC_FILES := \ - ../../../myWindows/wine_date_and_time.cpp \ - ../../../myWindows/wine_GetXXXDefaultLangID.cpp \ - ../../../myWindows/myAddExeFlag.cpp \ - ../../../myWindows/mySplitCommandLine.cpp \ - ../../../myWindows/test_lib.cpp \ - ../../../Common/MyString.cpp \ - ../../../Common/MyWindows.cpp \ - ../../../Common/MyVector.cpp \ - -# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+) -LOCAL_CFLAGS += -fPIE -LOCAL_LDFLAGS += -fPIE -pie - -include $(BUILD_EXECUTABLE) diff -Nru p7zip-rar-16.02/CPP/ANDROID/test_lib/jni/Application.mk p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Application.mk --- p7zip-rar-16.02/CPP/ANDROID/test_lib/jni/Application.mk 2011-06-12 15:07:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/jni/Application.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The ARMv7 is significanly faster due to the use of the hardware FPU -APP_ABI := armeabi # armeabi-v7a -#APP_PLATFORM := android-8 diff -Nru p7zip-rar-16.02/CPP/ANDROID/test_lib/makefile p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/makefile --- p7zip-rar-16.02/CPP/ANDROID/test_lib/makefile 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/ANDROID/test_lib/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ - -TARGET=test_lib - -all: build - -include ../makefile.inc - - -test: install - adb shell $(DEVICE_DIR)/$(TARGET) - diff -Nru p7zip-rar-16.02/CPP/Build.mak p7zip-rar-16.02+really25.00+ds/CPP/Build.mak --- p7zip-rar-16.02/CPP/Build.mak 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Build.mak 2025-07-02 05:00:00.000000000 +0000 @@ -0,0 +1,252 @@ +LIBS = $(LIBS) oleaut32.lib ole32.lib + +# CFLAGS = $(CFLAGS) -DZ7_NO_UNICODE +!IFNDEF MY_NO_UNICODE +# CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE +!ENDIF + +!IF "$(CC)" != "clang-cl" +# for link time code generation: +# CFLAGS = $(CFLAGS) -GL +!ENDIF + +!IFNDEF O +!IFDEF PLATFORM +O=$(PLATFORM) +!ELSE +O=o +!ENDIF +!ENDIF + +!IF "$(CC)" != "clang-cl" +# CFLAGS = $(CFLAGS) -FAsc -Fa$O/asm/ +!ENDIF + +# LFLAGS = $(LFLAGS) /guard:cf + + +!IF "$(PLATFORM)" == "x64" +MY_ML = ml64 -WX +#-Dx64 +!ELSEIF "$(PLATFORM)" == "arm64" +MY_ML = armasm64 +!ELSEIF "$(PLATFORM)" == "arm" +MY_ML = armasm -WX +!ELSE +MY_ML = ml -WX +# -DABI_CDECL +!ENDIF + +# MY_ML = "$(MY_ML) -Fl$O\asm\ + + +!IFDEF UNDER_CE +RFLAGS = $(RFLAGS) -dUNDER_CE +!IFDEF MY_CONSOLE +LFLAGS = $(LFLAGS) /ENTRY:mainACRTStartup +!ENDIF +!ELSE +!IFDEF OLD_COMPILER +LFLAGS = $(LFLAGS) -OPT:NOWIN98 +!ENDIF +!IF "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +CFLAGS = $(CFLAGS) -Gr +!ENDIF +LIBS = $(LIBS) user32.lib advapi32.lib shell32.lib +!ENDIF + +!IF "$(PLATFORM)" == "arm" +COMPL_ASM = $(MY_ML) $** $O/$(*B).obj +!ELSEIF "$(PLATFORM)" == "arm64" +COMPL_ASM = $(MY_ML) $** $O/$(*B).obj +!ELSE +COMPL_ASM = $(MY_ML) -c -Fo$O/ $** +!ENDIF + +!IFDEF OLD_COMPILER +CFLAGS_WARN_LEVEL = -W4 +!ELSE +CFLAGS_WARN_LEVEL = -Wall +!ENDIF + +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ $(CFLAGS_WARN_LEVEL) -WX -EHsc -Gy -GR- -GF + +!IF "$(CC)" == "clang-cl" + +CFLAGS = $(CFLAGS) \ + -Werror \ + -Wall \ + -Wextra \ + -Weverything \ + -Wfatal-errors \ + +!ENDIF + +# !IFDEF MY_DYNAMIC_LINK +!IF "$(MY_DYNAMIC_LINK)" != "" +CFLAGS = $(CFLAGS) -MD +!ELSE +!IFNDEF MY_SINGLE_THREAD +CFLAGS = $(CFLAGS) -MT +!ENDIF +!ENDIF + + +CFLAGS = $(CFLAGS_COMMON) $(CFLAGS) + + +!IFNDEF OLD_COMPILER + +CFLAGS = $(CFLAGS) -GS- -Zc:wchar_t +!IFDEF VCTOOLSVERSION +!IF "$(VCTOOLSVERSION)" >= "14.00" +!IF "$(CC)" != "clang-cl" +CFLAGS = $(CFLAGS) -Zc:throwingNew +!ENDIF +!ENDIF +!ELSE +# -Zc:forScope is default in VS2010. so we need it only for older versions +CFLAGS = $(CFLAGS) -Zc:forScope +!ENDIF + +!IFNDEF UNDER_CE +!IF "$(CC)" != "clang-cl" +MP_NPROC = 16 +!IFDEF NUMBER_OF_PROCESSORS +!IF $(NUMBER_OF_PROCESSORS) < $(MP_NPROC) +MP_NPROC = $(NUMBER_OF_PROCESSORS) +!ENDIF +!ENDIF +CFLAGS = $(CFLAGS) -MP$(MP_NPROC) +!ENDIF +!IFNDEF PLATFORM +# CFLAGS = $(CFLAGS) -arch:IA32 +!ENDIF +!ENDIF + +!ENDIF + + +!IFDEF MY_CONSOLE +CFLAGS = $(CFLAGS) -D_CONSOLE +!ENDIF + +!IFNDEF UNDER_CE +!IF "$(PLATFORM)" == "arm" +CFLAGS = $(CFLAGS) -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE +!ENDIF +!ENDIF + +!IF "$(PLATFORM)" == "x64" +CFLAGS_O1 = $(CFLAGS) -O1 +!ELSE +CFLAGS_O1 = $(CFLAGS) -O1 +!ENDIF +CFLAGS_O2 = $(CFLAGS) -O2 + +LFLAGS = $(LFLAGS) -nologo -OPT:REF -OPT:ICF -INCREMENTAL:NO + +!IFNDEF UNDER_CE +LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE +!ENDIF + +!IFDEF DEF_FILE +LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE) +!ELSE +!IF defined(MY_FIXED) && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" +LFLAGS = $(LFLAGS) /FIXED +!ELSE +LFLAGS = $(LFLAGS) /FIXED:NO +!ENDIF +# /BASE:0x400000 +!ENDIF + +!IF "$(PLATFORM)" == "arm64" +# we can get better compression ratio with ARM64 filter if we change alignment to 4096 +# LFLAGS = $(LFLAGS) /FILEALIGN:4096 +!ENDIF + + + +# !IF "$(PLATFORM)" == "x64" + +!IFDEF SUB_SYS_VER + +MY_SUB_SYS_VER=5.02 + +!IFDEF MY_CONSOLE +LFLAGS = $(LFLAGS) /SUBSYSTEM:console,$(MY_SUB_SYS_VER) +!ELSE +LFLAGS = $(LFLAGS) /SUBSYSTEM:windows,$(MY_SUB_SYS_VER) +!ENDIF + +!ENDIF + + +!IF "$(PLATFORM)" == "arm64" +CLANG_FLAGS_TARGET = --target=arm64-pc-windows-msvc +!ENDIF + +COMPL_CLANG_SPEC=clang-cl $(CLANG_FLAGS_TARGET) +COMPL_ASM_CLANG = $(COMPL_CLANG_SPEC) -nologo -c -Fo$O/ $(CFLAGS_WARN_LEVEL) -WX $** +# COMPL_C_CLANG = $(COMPL_CLANG_SPEC) $(CFLAGS_O2) + + +PROGPATH = $O\$(PROG) + +COMPL_O1 = $(CC) $(CFLAGS_O1) $** +COMPL_O2 = $(CC) $(CFLAGS_O2) $** +COMPL_PCH = $(CC) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $** +COMPL = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $** +COMPLB = $(CC) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $< +COMPLB_O2 = $(CC) $(CFLAGS_O2) $< +# COMPLB_O2 = $(CC) $(CFLAGS_O2) -Yu"StdAfx.h" -Fp$O/a.pch $< + +CFLAGS_C_ALL = $(CFLAGS_O2) $(CFLAGS_C_SPEC) + +CCOMPL_PCH = $(CC) $(CFLAGS_C_ALL) -Yc"Precomp.h" -Fp$O/a.pch $** +CCOMPL_USE = $(CC) $(CFLAGS_C_ALL) -Yu"Precomp.h" -Fp$O/a.pch $** +CCOMPLB_USE = $(CC) $(CFLAGS_C_ALL) -Yu"Precomp.h" -Fp$O/a.pch $< +CCOMPL = $(CC) $(CFLAGS_C_ALL) $** +CCOMPLB = $(CC) $(CFLAGS_C_ALL) $< + +!IF "$(CC)" == "clang-cl" +COMPL = $(COMPL) -FI StdAfx.h +COMPLB = $(COMPLB) -FI StdAfx.h +CCOMPL_USE = $(CCOMPL_USE) -FI Precomp.h +CCOMPLB_USE = $(CCOMPLB_USE) -FI Precomp.h +!ENDIF + +all: $(PROGPATH) + +clean: + -del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch $O\*.asm + +$O: + if not exist "$O" mkdir "$O" +$O/asm: + if not exist "$O/asm" mkdir "$O/asm" + +!IF "$(CC)" != "clang-cl" +# for link time code generation: +# LFLAGS = $(LFLAGS) -LTCG +!ENDIF + +$(PROGPATH): $O $O/asm $(OBJS) $(DEF_FILE) + link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) + +!IFNDEF NO_DEFAULT_RES +$O\resource.res: $(*B).rc + rc $(RFLAGS) -fo$@ $** +!ENDIF +$O\StdAfx.obj: $(*B).cpp + $(COMPL_PCH) + +predef: empty.c + $(CCOMPL) /EP /Zc:preprocessor /PD +predef2: A.cpp + $(COMPL) -EP -Zc:preprocessor -PD +predef3: A.cpp + $(COMPL) -E -dM +predef4: A.cpp + $(COMPL_O2) -E diff -Nru p7zip-rar-16.02/CPP/Common/AutoPtr.h p7zip-rar-16.02+really25.00+ds/CPP/Common/AutoPtr.h --- p7zip-rar-16.02/CPP/Common/AutoPtr.h 2008-08-14 09:11:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/AutoPtr.h 2024-01-31 14:00:00.000000000 +0000 @@ -1,35 +1,46 @@ -// Common/AutoPtr.h - -#ifndef __COMMON_AUTOPTR_H -#define __COMMON_AUTOPTR_H - -template class CMyAutoPtr -{ - T *_p; -public: - CMyAutoPtr(T *p = 0) : _p(p) {} - CMyAutoPtr(CMyAutoPtr& p): _p(p.release()) {} - CMyAutoPtr& operator=(CMyAutoPtr& p) - { - reset(p.release()); - return (*this); - } - ~CMyAutoPtr() { delete _p; } - T& operator*() const { return *_p; } - // T* operator->() const { return (&**this); } - T* get() const { return _p; } - T* release() - { - T *tmp = _p; - _p = 0; - return tmp; - } - void reset(T* p = 0) - { - if (p != _p) - delete _p; - _p = p; - } -}; - -#endif +// Common/AutoPtr.h + +#ifndef ZIP7_INC_COMMON_AUTOPTR_H +#define ZIP7_INC_COMMON_AUTOPTR_H + +template class CMyUniquePtr +// CMyAutoPtr +{ + T *_p; + + CMyUniquePtr(CMyUniquePtr& p); // : _p(p.release()) {} + CMyUniquePtr& operator=(T *p); + CMyUniquePtr& operator=(CMyUniquePtr& p); + /* + { + reset(p.release()); + return (*this); + } + */ + void reset(T* p = NULL) + { + if (p != _p) + delete _p; + _p = p; + } +public: + CMyUniquePtr(T *p = NULL) : _p(p) {} + ~CMyUniquePtr() { delete _p; } + T& operator*() const { return *_p; } + T* operator->() const { return _p; } + // operator bool() const { return _p != NULL; } + T* get() const { return _p; } + T* release() + { + T *tmp = _p; + _p = NULL; + return tmp; + } + void Create_if_Empty() + { + if (!_p) + _p = new T; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/CRC.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/CRC.cpp --- p7zip-rar-16.02/CPP/Common/CRC.cpp 2009-05-30 20:19:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/CRC.cpp 2021-01-23 07:42:14.000000000 +0000 @@ -1,7 +1,7 @@ -// Common/CRC.cpp - -#include "StdAfx.h" - -#include "../../C/7zCrc.h" - -struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; +// Common/CRC.cpp + +#include "StdAfx.h" + +#include "../../C/7zCrc.h" + +static struct CCRCTableInit { CCRCTableInit() { CrcGenerateTable(); } } g_CRCTableInit; diff -Nru p7zip-rar-16.02/CPP/Common/C_FileIO.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.cpp --- p7zip-rar-16.02/CPP/Common/C_FileIO.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.cpp 2020-12-13 17:15:26.000000000 +0000 @@ -1,92 +1,3 @@ -// Common/C_FileIO.cpp - -#include "C_FileIO.h" - -#include -#ifdef _WIN32 -#include -#else -#include -#endif - -namespace NC { -namespace NFile { -namespace NIO { - -bool CFileBase::OpenBinary(const char *name, int flags) -{ - #ifdef O_BINARY - flags |= O_BINARY; - #endif - Close(); - _handle = ::open(name, flags, 0666); - return _handle != -1; -} - -bool CFileBase::Close() -{ - if (_handle == -1) - return true; - if (close(_handle) != 0) - return false; - _handle = -1; - return true; -} - -bool CFileBase::GetLength(UInt64 &length) const -{ - off_t curPos = Seek(0, SEEK_CUR); - off_t lengthTemp = Seek(0, SEEK_END); - Seek(curPos, SEEK_SET); - length = (UInt64)lengthTemp; - return true; -} - -off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const -{ - return ::lseek(_handle, distanceToMove, moveMethod); -} - -///////////////////////// -// CInFile - -bool CInFile::Open(const char *name) -{ - return CFileBase::OpenBinary(name, O_RDONLY); -} - -bool CInFile::OpenShared(const char *name, bool) -{ - return Open(name); -} - -ssize_t CInFile::Read(void *data, size_t size) -{ - return read(_handle, data, size); -} - -///////////////////////// -// COutFile - -bool COutFile::Create(const char *name, bool createAlways) -{ - if (createAlways) - { - Close(); - _handle = ::creat(name, 0666); - return _handle != -1; - } - return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY); -} - -bool COutFile::Open(const char *name, DWORD creationDisposition) -{ - return Create(name, false); -} - -ssize_t COutFile::Write(const void *data, size_t size) -{ - return write(_handle, data, size); -} - -}}} +// Common/C_FileIO.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/Common/C_FileIO.h p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.h --- p7zip-rar-16.02/CPP/Common/C_FileIO.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/C_FileIO.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,53 +1,6 @@ -// Common/C_FileIO.h - -#ifndef __COMMON_C_FILEIO_H -#define __COMMON_C_FILEIO_H - -#include -#include - -#include "MyTypes.h" -#include "MyWindows.h" - -#ifdef _WIN32 -#ifdef _MSC_VER -typedef size_t ssize_t; -#endif -#endif - -namespace NC { -namespace NFile { -namespace NIO { - -class CFileBase -{ -protected: - int _handle; - bool OpenBinary(const char *name, int flags); -public: - CFileBase(): _handle(-1) {}; - ~CFileBase() { Close(); } - bool Close(); - bool GetLength(UInt64 &length) const; - off_t Seek(off_t distanceToMove, int moveMethod) const; -}; - -class CInFile: public CFileBase -{ -public: - bool Open(const char *name); - bool OpenShared(const char *name, bool shareForWrite); - ssize_t Read(void *data, size_t size); -}; - -class COutFile: public CFileBase -{ -public: - bool Create(const char *name, bool createAlways); - bool Open(const char *name, DWORD creationDisposition); - ssize_t Write(const void *data, size_t size); -}; - -}}} - -#endif +// Common/C_FileIO.h + +#ifndef ZIP7_INC_COMMON_C_FILEIO_H +#define ZIP7_INC_COMMON_C_FILEIO_H + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/CksumReg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/CksumReg.cpp --- p7zip-rar-16.02/CPP/Common/CksumReg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/CksumReg.cpp 2023-03-24 11:00:00.000000000 +0000 @@ -0,0 +1,55 @@ +// CksumReg.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" +#include "../7zip/Compress/BZip2Crc.h" + +Z7_CLASS_IMP_COM_1( + CCksumHasher + , IHasher +) + CBZip2Crc _crc; + UInt64 _size; +public: + // Byte _mtDummy[1 << 7]; + CCksumHasher() + { + _crc.Init(0); + _size = 0; + } +}; + +Z7_COM7F_IMF2(void, CCksumHasher::Init()) +{ + _crc.Init(0); + _size = 0; +} + +Z7_COM7F_IMF2(void, CCksumHasher::Update(const void *data, UInt32 size)) +{ + _size += size; + CBZip2Crc crc = _crc; + for (UInt32 i = 0; i < size; i++) + crc.UpdateByte(((const Byte *)data)[i]); + _crc = crc; +} + +Z7_COM7F_IMF2(void, CCksumHasher::Final(Byte *digest)) +{ + UInt64 size = _size; + CBZip2Crc crc = _crc; + while (size) + { + crc.UpdateByte((Byte)size); + size >>= 8; + } + const UInt32 val = crc.GetDigest(); + SetUi32(digest, val) +} + +REGISTER_HASHER(CCksumHasher, 0x203, "CKSUM", 4) diff -Nru p7zip-rar-16.02/CPP/Common/ComTry.h p7zip-rar-16.02+really25.00+ds/CPP/Common/ComTry.h --- p7zip-rar-16.02/CPP/Common/ComTry.h 2010-10-20 05:25:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/ComTry.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,18 +1,21 @@ -// ComTry.h - -#ifndef __COM_TRY_H -#define __COM_TRY_H - -#include "MyWindows.h" -// #include "Exception.h" -// #include "NewHandler.h" - -#define COM_TRY_BEGIN try { -#define COM_TRY_END } catch(const char * s) { throw s ; } \ - catch(...) { return E_OUTOFMEMORY; } - - // catch(const CNewException &) { return E_OUTOFMEMORY; } - // catch(const CSystemException &e) { return e.ErrorCode; } - // catch(...) { return E_FAIL; } - -#endif +// ComTry.h + +#ifndef ZIP7_INC_COM_TRY_H +#define ZIP7_INC_COM_TRY_H + +#include "MyWindows.h" +// #include "Exception.h" +// #include "NewHandler.h" + +#define COM_TRY_BEGIN try { +#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; } + +/* +#define COM_TRY_END } \ + catch(const CNewException &) { return E_OUTOFMEMORY; } \ + catch(...) { return HRESULT_FROM_WIN32(ERROR_NOACCESS); } \ +*/ + // catch(const CSystemException &e) { return e.ErrorCode; } + // catch(...) { return E_FAIL; } + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/CommandLineParser.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.cpp --- p7zip-rar-16.02/CPP/Common/CommandLineParser.cpp 2015-06-19 12:44:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.cpp 2024-05-05 09:00:00.000000000 +0000 @@ -1,204 +1,231 @@ -// CommandLineParser.cpp - -#include "StdAfx.h" - -#include "CommandLineParser.h" - -static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a) -{ - for (;;) - { - char c = *a; - if (c == 0) - return true; - if ((unsigned char)MyCharLower_Ascii(c) != MyCharLower_Ascii(*u)) - return false; - a++; - u++; - } -} - -namespace NCommandLineParser { - -#ifdef _WIN32 -bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) -{ - dest1.Empty(); - dest2.Empty(); - bool quoteMode = false; - unsigned i; - for (i = 0; i < src.Len(); i++) - { - wchar_t c = src[i]; - if ((c == L' ' || c == L'\t') && !quoteMode) - { - dest2 = src.Ptr(i + 1); - return i != 0; - } - if (c == L'\"') - quoteMode = !quoteMode; - else - dest1 += c; - } - return i != 0; -} - -void SplitCommandLine(const UString &s, UStringVector &parts) -{ - UString sTemp = s; - sTemp.Trim(); - parts.Clear(); - for (;;) - { - UString s1, s2; - if (SplitCommandLine(sTemp, s1, s2)) - parts.Add(s1); - if (s2.IsEmpty()) - break; - sTemp = s2; - } -} -#endif - -static const char *kStopSwitchParsing = "--"; - -static bool inline IsItSwitchChar(wchar_t c) -{ - return (c == '-'); -} - -CParser::CParser(unsigned numSwitches): - _numSwitches(numSwitches), - _switches(0) -{ - _switches = new CSwitchResult[numSwitches]; -} - -CParser::~CParser() -{ - delete []_switches; -} - - -// if (s) contains switch then function updates switch structures -// out: true, if (s) is a switch -bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms) -{ - if (s.IsEmpty() || !IsItSwitchChar(s[0])) - return false; - - unsigned pos = 1; - unsigned switchIndex = 0; - int maxLen = -1; - - for (unsigned i = 0; i < _numSwitches; i++) - { - const char *key = switchForms[i].Key; - unsigned switchLen = MyStringLen(key); - if ((int)switchLen <= maxLen || pos + switchLen > s.Len()) - continue; - if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key)) - { - switchIndex = i; - maxLen = switchLen; - } - } - - if (maxLen < 0) - { - ErrorMessage = "Unknown switch:"; - return false; - } - - pos += maxLen; - - CSwitchResult &sw = _switches[switchIndex]; - const CSwitchForm &form = switchForms[switchIndex]; - - if (!form.Multi && sw.ThereIs) - { - ErrorMessage = "Multiple instances for switch:"; - return false; - } - - sw.ThereIs = true; - - int rem = s.Len() - pos; - if (rem < form.MinLen) - { - ErrorMessage = "Too short switch:"; - return false; - } - - sw.WithMinus = false; - sw.PostCharIndex = -1; - - switch (form.Type) - { - case NSwitchType::kMinus: - if (rem == 1) - { - sw.WithMinus = (s[pos] == '-'); - if (sw.WithMinus) - return true; - ErrorMessage = "Incorrect switch postfix:"; - return false; - } - break; - - case NSwitchType::kChar: - if (rem == 1) - { - wchar_t c = s[pos]; - if (c <= 0x7F) - { - sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c); - if (sw.PostCharIndex >= 0) - return true; - } - ErrorMessage = "Incorrect switch postfix:"; - return false; - } - break; - - case NSwitchType::kString: - sw.PostStrings.Add((const wchar_t *)s + pos); - return true; - } - - if (pos != s.Len()) - { - ErrorMessage = "Too long switch:"; - return false; - } - return true; -} - -bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings) -{ - ErrorLine.Empty(); - bool stopSwitch = false; - FOR_VECTOR (i, commandStrings) - { - const UString &s = commandStrings[i]; - if (!stopSwitch) - { - if (s.IsEqualTo(kStopSwitchParsing)) - { - stopSwitch = true; - continue; - } - if (!s.IsEmpty() && IsItSwitchChar(s[0])) - { - if (ParseString(s, switchForms)) - continue; - ErrorLine = s; - return false; - } - } - NonSwitchStrings.Add(s); - } - return true; -} - -} +// CommandLineParser.cpp + +#include "StdAfx.h" + +#include "CommandLineParser.h" + +namespace NCommandLineParser { + +#ifdef _WIN32 + +bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2) +{ + dest1.Empty(); + dest2.Empty(); + bool quoteMode = false; + unsigned i; + for (i = 0; i < src.Len(); i++) + { + const wchar_t c = src[i]; + if ((c == L' ' || c == L'\t') && !quoteMode) + { + dest2 = src.Ptr(i + 1); + return i != 0; + } + if (c == L'\"') + quoteMode = !quoteMode; + else + dest1 += c; + } + return i != 0; +} + +void SplitCommandLine(const UString &s, UStringVector &parts) +{ +#if 0 +/* we don't use CommandLineToArgvW() because + it can remove tail backslash: + "1\" + converted to + 1" +*/ + parts.Clear(); + { + int nArgs; + LPWSTR *szArgList = CommandLineToArgvW(s, &nArgs); + if (szArgList) + { + for (int i = 0; i < nArgs; i++) + { + // printf("%2d: |%S|\n", i, szArglist[i]); + parts.Add(szArgList[i]); + } + LocalFree(szArgList); + return; + } + } +#endif +/* +#ifdef _UNICODE + throw 20240406; +#else +*/ + UString sTemp (s); + sTemp.Trim(); + parts.Clear(); + for (;;) + { + UString s1, s2; + if (SplitCommandLine(sTemp, s1, s2)) + parts.Add(s1); + if (s2.IsEmpty()) + break; + sTemp = s2; + } +// #endif +} +#endif + + +static const char * const kStopSwitchParsing = "--"; + +static bool inline IsItSwitchChar(wchar_t c) +{ + return (c == '-'); +} + +CParser::CParser(): + _switches(NULL), + StopSwitchIndex(-1) +{ +} + +CParser::~CParser() +{ + delete []_switches; +} + + +// if (s) contains switch then function updates switch structures +// out: true, if (s) is a switch +bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches) +{ + if (s.IsEmpty() || !IsItSwitchChar(s[0])) + return false; + + unsigned pos = 1; + unsigned switchIndex = 0; + int maxLen = -1; + + for (unsigned i = 0; i < numSwitches; i++) + { + const char * const key = switchForms[i].Key; + const unsigned switchLen = MyStringLen(key); + if ((int)switchLen <= maxLen || pos + switchLen > s.Len()) + continue; + if (IsString1PrefixedByString2_NoCase_Ascii((const wchar_t *)s + pos, key)) + { + switchIndex = i; + maxLen = (int)switchLen; + } + } + + if (maxLen < 0) + { + ErrorMessage = "Unknown switch:"; + return false; + } + + pos += (unsigned)maxLen; + + CSwitchResult &sw = _switches[switchIndex]; + const CSwitchForm &form = switchForms[switchIndex]; + + if (!form.Multi && sw.ThereIs) + { + ErrorMessage = "Multiple instances for switch:"; + return false; + } + + sw.ThereIs = true; + + const unsigned rem = s.Len() - pos; + if (rem < form.MinLen) + { + ErrorMessage = "Too short switch:"; + return false; + } + + sw.WithMinus = false; + sw.PostCharIndex = -1; + + switch (form.Type) + { + case NSwitchType::kMinus: + if (rem == 1) + { + sw.WithMinus = (s[pos] == '-'); + if (sw.WithMinus) + return true; + ErrorMessage = "Incorrect switch postfix:"; + return false; + } + break; + + case NSwitchType::kChar: + if (rem == 1) + { + const wchar_t c = s[pos]; + if (c <= 0x7F) + { + sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c); + if (sw.PostCharIndex >= 0) + return true; + } + ErrorMessage = "Incorrect switch postfix:"; + return false; + } + break; + + case NSwitchType::kString: + { + sw.PostStrings.Add(s.Ptr(pos)); + return true; + } + // case NSwitchType::kSimple: + default: break; + } + + if (pos != s.Len()) + { + ErrorMessage = "Too long switch:"; + return false; + } + return true; +} + + +bool CParser::ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings) +{ + StopSwitchIndex = -1; + ErrorMessage.Empty(); + ErrorLine.Empty(); + NonSwitchStrings.Clear(); + delete []_switches; + _switches = NULL; + _switches = new CSwitchResult[numSwitches]; + + FOR_VECTOR (i, commandStrings) + { + const UString &s = commandStrings[i]; + if (StopSwitchIndex < 0) + { + if (s.IsEqualTo(kStopSwitchParsing)) + { + StopSwitchIndex = (int)NonSwitchStrings.Size(); + continue; + } + if (!s.IsEmpty() && IsItSwitchChar(s[0])) + { + if (ParseString(s, switchForms, numSwitches)) + continue; + ErrorLine = s; + return false; + } + } + NonSwitchStrings.Add(s); + } + return true; +} + +} diff -Nru p7zip-rar-16.02/CPP/Common/CommandLineParser.h p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.h --- p7zip-rar-16.02/CPP/Common/CommandLineParser.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/CommandLineParser.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,63 +1,63 @@ -// Common/CommandLineParser.h - -#ifndef __COMMON_COMMAND_LINE_PARSER_H -#define __COMMON_COMMAND_LINE_PARSER_H - -#include "MyString.h" - -namespace NCommandLineParser { - -bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2); -void SplitCommandLine(const UString &s, UStringVector &parts); - -namespace NSwitchType -{ - enum EEnum - { - kSimple, - kMinus, - kString, - kChar - }; -} - -struct CSwitchForm -{ - const char *Key; - Byte Type; - bool Multi; - Byte MinLen; - // int MaxLen; - const char *PostCharSet; -}; - -struct CSwitchResult -{ - bool ThereIs; - bool WithMinus; - int PostCharIndex; - UStringVector PostStrings; - - CSwitchResult(): ThereIs(false) {}; -}; - -class CParser -{ - unsigned _numSwitches; - CSwitchResult *_switches; - - bool ParseString(const UString &s, const CSwitchForm *switchForms); -public: - UStringVector NonSwitchStrings; - AString ErrorMessage; - UString ErrorLine; - - CParser(unsigned numSwitches); - ~CParser(); - bool ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings); - const CSwitchResult& operator[](size_t index) const { return _switches[index]; } -}; - -} - -#endif +// Common/CommandLineParser.h + +#ifndef ZIP7_INC_COMMON_COMMAND_LINE_PARSER_H +#define ZIP7_INC_COMMON_COMMAND_LINE_PARSER_H + +#include "MyString.h" + +namespace NCommandLineParser { + +bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2); +void SplitCommandLine(const UString &s, UStringVector &parts); + +namespace NSwitchType +{ + enum EEnum + { + kSimple, + kMinus, + kString, + kChar + }; +} + +struct CSwitchForm +{ + const char *Key; + Byte Type; + bool Multi; + Byte MinLen; + // int MaxLen; + const char *PostCharSet; +}; + +struct CSwitchResult +{ + bool ThereIs; + bool WithMinus; + int PostCharIndex; + UStringVector PostStrings; + + CSwitchResult(): ThereIs(false) {} +}; + +class CParser +{ + CSwitchResult *_switches; + + bool ParseString(const UString &s, const CSwitchForm *switchForms, unsigned numSwitches); +public: + UStringVector NonSwitchStrings; + int StopSwitchIndex; // NonSwitchStrings[StopSwitchIndex+] are after "--" + AString ErrorMessage; + UString ErrorLine; + + CParser(); + ~CParser(); + bool ParseStrings(const CSwitchForm *switchForms, unsigned numSwitches, const UStringVector &commandStrings); + const CSwitchResult& operator[](unsigned index) const { return _switches[index]; } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Common.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Common.h --- p7zip-rar-16.02/CPP/Common/Common.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Common.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,13 +1,28 @@ -// Common.h - -#ifndef __COMMON_COMMON_H -#define __COMMON_COMMON_H - -#include "../../C/Compiler.h" - -#include "MyWindows.h" -#include "NewHandler.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1])) - -#endif +// Common.h + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#ifndef ZIP7_INC_COMMON_H +#define ZIP7_INC_COMMON_H + +#include "../../C/Precomp.h" +#include "Common0.h" +#include "MyWindows.h" + +/* +This file is included to all cpp files in 7-Zip. +Each folder contains StdAfx.h file that includes "Common.h". +So 7-Zip includes "Common.h" in both modes: + with precompiled StdAfx.h +and + without precompiled StdAfx.h + +include "Common.h" before other h files of 7-zip, + if you need predefined macros. +do not include "Common.h", if you need only interfaces, + and you don't need predefined macros. +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Common0.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Common0.h --- p7zip-rar-16.02/CPP/Common/Common0.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Common0.h 2024-02-26 10:00:00.000000000 +0000 @@ -0,0 +1,330 @@ +// Common0.h + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif + +#ifndef ZIP7_INC_COMMON0_H +#define ZIP7_INC_COMMON0_H + +#include "../../C/Compiler.h" + +/* +This file contains compiler related things for cpp files. +This file is included to all cpp files in 7-Zip via "Common.h". +Also this file is included in "IDecl.h" (that is included in interface files). +So external modules can use 7-Zip interfaces without +predefined macros defined in "Common.h". +*/ + +#ifdef _MSC_VER + #pragma warning(disable : 4710) // function not inlined + // 'CUncopyable::CUncopyable': + #pragma warning(disable : 4514) // unreferenced inline function has been removed + #if _MSC_VER < 1300 + #pragma warning(disable : 4702) // unreachable code + #pragma warning(disable : 4714) // function marked as __forceinline not inlined + #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information + #endif + #if _MSC_VER < 1400 + #pragma warning(disable : 4511) // copy constructor could not be generated // #pragma warning(disable : 4512) // assignment operator could not be generated + #pragma warning(disable : 4512) // assignment operator could not be generated + #endif + #if _MSC_VER > 1400 && _MSC_VER <= 1900 + // #pragma warning(disable : 4996) + // strcat: This function or variable may be unsafe + // GetVersion was declared deprecated + #endif + +#if _MSC_VER > 1200 +// -Wall warnings + +#if _MSC_VER <= 1600 +#pragma warning(disable : 4917) // 'OLE_HANDLE' : a GUID can only be associated with a class, interface or namespace +#endif + +// #pragma warning(disable : 4061) // enumerator '' in switch of enum '' is not explicitly handled by a case label +// #pragma warning(disable : 4266) // no override available for virtual member function from base ''; function is hidden +#pragma warning(disable : 4625) // copy constructor was implicitly defined as deleted +#pragma warning(disable : 4626) // assignment operator was implicitly defined as deleted +#if _MSC_VER >= 1600 && _MSC_VER < 1920 +#pragma warning(disable : 4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught +#endif +#if _MSC_VER >= 1600 +#pragma warning(disable : 4365) // 'initializing' : conversion from 'int' to 'unsigned int', signed / unsigned mismatch +#endif +#if _MSC_VER < 1800 +// we disable the warning, if we don't use 'final' in class +#pragma warning(disable : 4265) // class has virtual functions, but destructor is not virtual +#endif + +#if _MSC_VER >= 1900 +#pragma warning(disable : 5026) // move constructor was implicitly defined as deleted +#pragma warning(disable : 5027) // move assignment operator was implicitly defined as deleted +#endif +#if _MSC_VER >= 1912 +#pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception. +#endif +#if _MSC_VER >= 1925 +// #pragma warning(disable : 5204) // 'ISequentialInStream' : class has virtual functions, but its trivial destructor is not virtual; instances of objects derived from this class may not be destructed correctly +#endif +#if _MSC_VER >= 1934 +// #pragma warning(disable : 5264) // const variable is not used +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(_MSC_VER) // && !defined(__clang__) +#define Z7_DECLSPEC_NOTHROW __declspec(nothrow) +#elif defined(__clang__) || defined(__GNUC__) +#define Z7_DECLSPEC_NOTHROW __attribute__((nothrow)) +#else +#define Z7_DECLSPEC_NOTHROW +#endif + +/* +#if defined (_MSC_VER) && _MSC_VER >= 1900 \ + || defined(__clang__) && __clang_major__ >= 6 \ + || defined(__GNUC__) && __GNUC__ >= 6 + #define Z7_noexcept noexcept +#else + #define Z7_noexcept throw() +#endif +*/ + + +#if defined(__clang__) + +#if /* defined(_WIN32) && */ __clang_major__ >= 16 +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#if __clang_major__ >= 4 && __clang_major__ < 12 && !defined(_WIN32) +/* +if compiled with new GCC libstdc++, GCC libstdc++ can use: +13.2.0/include/c++/ + : #define _NEW + : #define _GLIBCXX_STDLIB_H 1 +*/ +#pragma GCC diagnostic ignored "-Wreserved-id-macro" +#endif + +// noexcept, final, = delete +#pragma GCC diagnostic ignored "-Wc++98-compat" +#if __clang_major__ >= 4 +// throw() dynamic exception specifications are deprecated +#pragma GCC diagnostic ignored "-Wdeprecated-dynamic-exception-spec" +#endif + +#if __clang_major__ <= 6 // check it +#pragma GCC diagnostic ignored "-Wsign-conversion" +#endif + +#pragma GCC diagnostic ignored "-Wold-style-cast" +#pragma GCC diagnostic ignored "-Wglobal-constructors" +#pragma GCC diagnostic ignored "-Wexit-time-destructors" + +#if defined(Z7_LLVM_CLANG_VERSION) && __clang_major__ >= 18 // 18.1.0RC +#pragma GCC diagnostic ignored "-Wswitch-default" +#endif +// #pragma GCC diagnostic ignored "-Wunused-private-field" +// #pragma GCC diagnostic ignored "-Wnonportable-system-include-path" +// #pragma GCC diagnostic ignored "-Wsuggest-override" +// #pragma GCC diagnostic ignored "-Wsign-conversion" +// #pragma GCC diagnostic ignored "-Winconsistent-missing-override" +// #pragma GCC diagnostic ignored "-Wsuggest-destructor-override" +// #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +// #pragma GCC diagnostic ignored "-Wdeprecated-copy-with-user-provided-dtor" +// #pragma GCC diagnostic ignored "-Wdeprecated-copy-dtor" +// #ifndef _WIN32 +// #pragma GCC diagnostic ignored "-Wweak-vtables" +// #endif +/* +#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40400) \ + || defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30000) +// enumeration values not explicitly handled in switch +#pragma GCC diagnostic ignored "-Wswitch-enum" +#endif +*/ +#endif // __clang__ + + +#ifdef __GNUC__ +// #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" +#endif + + +/* There is BUG in MSVC 6.0 compiler for operator new[]: + It doesn't check overflow, when it calculates size in bytes for allocated array. + So we can use Z7_ARRAY_NEW macro instead of new[] operator. */ + +#if defined(_MSC_VER) && (_MSC_VER == 1200) && !defined(_WIN64) + #define Z7_ARRAY_NEW(p, T, size) p = new T[((size) > 0xFFFFFFFFu / sizeof(T)) ? 0xFFFFFFFFu / sizeof(T) : (size)]; +#else + #define Z7_ARRAY_NEW(p, T, size) p = new T[size]; +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 8)) + #define Z7_ATTR_NORETURN __attribute__((noreturn)) +#elif (defined(__clang__) && (__clang_major__ >= 3)) + #if __has_feature(cxx_attributes) + #define Z7_ATTR_NORETURN [[noreturn]] + #else + #define Z7_ATTR_NORETURN __attribute__((noreturn)) + #endif +#elif (defined(_MSC_VER) && (_MSC_VER >= 1900)) + #define Z7_ATTR_NORETURN [[noreturn]] +#else + #define Z7_ATTR_NORETURN +#endif + + +// final in "GCC 4.7.0" +// In C++98 and C++03 code the alternative spelling __final can be used instead (this is a GCC extension.) + +#if defined (__cplusplus) && __cplusplus >= 201103L \ + || defined(_MSC_VER) && _MSC_VER >= 1800 \ + || defined(__clang__) && __clang_major__ >= 4 \ + /* || defined(__GNUC__) && __GNUC__ >= 9 */ + #define Z7_final final + #if defined(__clang__) && __cplusplus < 201103L + #pragma GCC diagnostic ignored "-Wc++11-extensions" + #endif +#elif defined (__cplusplus) && __cplusplus >= 199711L \ + && defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) + #define Z7_final __final +#else + #define Z7_final + #if defined(__clang__) && __clang_major__ >= 4 \ + || defined(__GNUC__) && __GNUC__ >= 4 + #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" + #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" + #endif +#endif + +#define Z7_class_final(c) class c Z7_final + + +#if defined (__cplusplus) && __cplusplus >= 201103L \ + || (defined(_MSC_VER) && _MSC_VER >= 1800) + #define Z7_CPP_IS_SUPPORTED_default + #define Z7_eq_delete = delete + // #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c) c(const c& k) = default; +#else + #define Z7_eq_delete + // #define Z7_DECL_DEFAULT_COPY_CONSTRUCTOR_IF_SUPPORTED(c) +#endif + + +#if defined(__cplusplus) && (__cplusplus >= 201103L) \ + || defined(_MSC_VER) && (_MSC_VER >= 1400) /* && (_MSC_VER != 1600) */ \ + || defined(__clang__) && __clang_major__ >= 4 + #if defined(_MSC_VER) && (_MSC_VER == 1600) /* && (_MSC_VER != 1600) */ + #pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override' + #define Z7_DESTRUCTOR_override + #else + #define Z7_DESTRUCTOR_override override + #endif + #define Z7_override override +#else + #define Z7_override + #define Z7_DESTRUCTOR_override +#endif + + + +#define Z7_CLASS_NO_COPY(cls) \ + private: \ + cls(const cls &) Z7_eq_delete; \ + cls &operator=(const cls &) Z7_eq_delete; + +class CUncopyable +{ +protected: + CUncopyable() {} // allow constructor + // ~CUncopyable() {} + Z7_CLASS_NO_COPY(CUncopyable) +}; + +#define MY_UNCOPYABLE :private CUncopyable +// #define MY_UNCOPYABLE + + +// typedef void (*Z7_void_Function)(void); + +#if defined(__clang__) || defined(__GNUC__) +#define Z7_CAST_FUNC(t, e) reinterpret_cast(reinterpret_cast(e)) +#else +#define Z7_CAST_FUNC(t, e) reinterpret_cast(reinterpret_cast(e)) +// #define Z7_CAST_FUNC(t, e) reinterpret_cast(e) +#endif + +#define Z7_GET_PROC_ADDRESS(func_type, hmodule, func_name) \ + Z7_CAST_FUNC(func_type, GetProcAddress(hmodule, func_name)) + +// || defined(__clang__) +// || defined(__GNUC__) + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define Z7_DECLSPEC_NOVTABLE __declspec(novtable) +#else +#define Z7_DECLSPEC_NOVTABLE +#endif + +#ifdef __clang__ +#define Z7_PURE_INTERFACES_BEGIN \ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"") +_Pragma("GCC diagnostic ignored \"-Wweak-vtables\"") +#define Z7_PURE_INTERFACES_END \ +_Pragma("GCC diagnostic pop") +#else +#define Z7_PURE_INTERFACES_BEGIN +#define Z7_PURE_INTERFACES_END +#endif + +// NewHandler.h and NewHandler.cpp redefine operator new() to throw exceptions, if compiled with old MSVC compilers +#include "NewHandler.h" + +/* +// #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) Z7_ARRAY_SIZE(a) +#endif +*/ + +#endif // ZIP7_INC_COMMON0_H + + + +// #define Z7_REDEFINE_NULL + +#if defined(Z7_REDEFINE_NULL) /* && (!defined(__clang__) || defined(_MSC_VER)) */ + +// NULL is defined in +#include +#undef NULL + +#ifdef __cplusplus + #if defined (__cplusplus) && __cplusplus >= 201103L \ + || (defined(_MSC_VER) && _MSC_VER >= 1800) + #define NULL nullptr + #else + #define NULL 0 + #endif +#else + #define NULL ((void *)0) +#endif + +#else // Z7_REDEFINE_NULL + +#if defined(__clang__) && __clang_major__ >= 5 +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#endif // Z7_REDEFINE_NULL + +// for precompiler: +// #include "MyWindows.h" diff -Nru p7zip-rar-16.02/CPP/Common/CrcReg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/CrcReg.cpp --- p7zip-rar-16.02/CPP/Common/CrcReg.cpp 2016-05-18 17:31:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/CrcReg.cpp 2023-12-08 11:00:00.000000000 +0000 @@ -1,98 +1,77 @@ -// CrcReg.cpp - -#include "StdAfx.h" - -#include "../../C/7zCrc.h" -#include "../../C/CpuArch.h" - -#include "../Common/MyCom.h" - -#include "../7zip/Common/RegisterCodec.h" - -EXTERN_C_BEGIN - -typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); - -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); - -extern CRC_FUNC g_CrcUpdate; -extern CRC_FUNC g_CrcUpdateT8; -extern CRC_FUNC g_CrcUpdateT4; - -EXTERN_C_END - -class CCrcHasher: - public IHasher, - public ICompressSetCoderProperties, - public CMyUnknownImp -{ - UInt32 _crc; - CRC_FUNC _updateFunc; - Byte mtDummy[1 << 7]; - - bool SetFunctions(UInt32 tSize); -public: - CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } - - MY_UNKNOWN_IMP2(IHasher, ICompressSetCoderProperties) - INTERFACE_IHasher(;) - STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); -}; - -bool CCrcHasher::SetFunctions(UInt32 tSize) -{ - _updateFunc = g_CrcUpdate; - - if (tSize == 1) - _updateFunc = CrcUpdateT1; - else if (tSize == 4) - { - if (g_CrcUpdateT4) - _updateFunc = g_CrcUpdateT4; - else - return false; - } - else if (tSize == 8) - { - if (g_CrcUpdateT8) - _updateFunc = g_CrcUpdateT8; - else - return false; - } - - return true; -} - -STDMETHODIMP CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps) -{ - for (UInt32 i = 0; i < numProps; i++) - { - const PROPVARIANT &prop = coderProps[i]; - if (propIDs[i] == NCoderPropID::kDefaultProp) - { - if (prop.vt != VT_UI4) - return E_INVALIDARG; - if (!SetFunctions(prop.ulVal)) - return E_NOTIMPL; - } - } - return S_OK; -} - -STDMETHODIMP_(void) CCrcHasher::Init() throw() -{ - _crc = CRC_INIT_VAL; -} - -STDMETHODIMP_(void) CCrcHasher::Update(const void *data, UInt32 size) throw() -{ - _crc = _updateFunc(_crc, data, size, g_CrcTable); -} - -STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) throw() -{ - UInt32 val = CRC_GET_DIGEST(_crc); - SetUi32(digest, val); -} - -REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4) +// CrcReg.cpp + +#include "StdAfx.h" + +#include "../../C/7zCrc.h" +#include "../../C/CpuArch.h" + +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +EXTERN_C_BEGIN + +EXTERN_C_END + +Z7_CLASS_IMP_COM_2( + CCrcHasher + , IHasher + , ICompressSetCoderProperties +) + UInt32 _crc; + Z7_CRC_UPDATE_FUNC _updateFunc; + + Z7_CLASS_NO_COPY(CCrcHasher) + + bool SetFunctions(UInt32 tSize); +public: + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + + CCrcHasher(): _crc(CRC_INIT_VAL) { SetFunctions(0); } +}; + +bool CCrcHasher::SetFunctions(UInt32 tSize) +{ + const Z7_CRC_UPDATE_FUNC f = z7_GetFunc_CrcUpdate(tSize); + if (!f) + { + _updateFunc = CrcUpdate; + return false; + } + _updateFunc = f; + return true; +} + +Z7_COM7F_IMF(CCrcHasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (!SetFunctions(prop.ulVal)) + return E_NOTIMPL; + } + } + return S_OK; +} + +Z7_COM7F_IMF2(void, CCrcHasher::Init()) +{ + _crc = CRC_INIT_VAL; +} + +Z7_COM7F_IMF2(void, CCrcHasher::Update(const void *data, UInt32 size)) +{ + _crc = _updateFunc(_crc, data, size); +} + +Z7_COM7F_IMF2(void, CCrcHasher::Final(Byte *digest)) +{ + const UInt32 val = CRC_GET_DIGEST(_crc); + SetUi32(digest, val) +} + +REGISTER_HASHER(CCrcHasher, 0x1, "CRC32", 4) diff -Nru p7zip-rar-16.02/CPP/Common/Defs.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Defs.h --- p7zip-rar-16.02/CPP/Common/Defs.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Defs.h 2023-03-24 09:00:00.000000000 +0000 @@ -1,15 +1,16 @@ -// Common/Defs.h - -#ifndef __COMMON_DEFS_H -#define __COMMON_DEFS_H - -template inline T MyMin(T a, T b) { return a < b ? a : b; } -template inline T MyMax(T a, T b) { return a > b ? a : b; } - -template inline int MyCompare(T a, T b) - { return a == b ? 0 : (a < b ? -1 : 1); } - -inline int BoolToInt(bool v) { return (v ? 1 : 0); } -inline bool IntToBool(int v) { return (v != 0); } - -#endif +// Common/Defs.h + +#ifndef ZIP7_INC_COMMON_DEFS_H +#define ZIP7_INC_COMMON_DEFS_H + +template inline T MyMin(T a, T b) { return a < b ? a : b; } +template inline T MyMax(T a, T b) { return a > b ? a : b; } + +template inline int MyCompare(T a, T b) + { return a == b ? 0 : (a < b ? -1 : 1); } + +inline int BoolToInt(bool v) { return (v ? 1 : 0); } +inline unsigned BoolToUInt(bool v) { return (v ? 1u : 0u); } +inline bool IntToBool(int v) { return (v != 0); } + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/DynLimBuf.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.cpp --- p7zip-rar-16.02/CPP/Common/DynLimBuf.cpp 2016-05-18 17:31:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.cpp 2022-12-15 20:00:00.000000000 +0000 @@ -1,93 +1,93 @@ -// Common/DynLimBuf.cpp - -#include "StdAfx.h" - -#include "DynLimBuf.h" -#include "MyString.h" - -CDynLimBuf::CDynLimBuf(size_t limit) throw() -{ - _chars = 0; - _pos = 0; - _size = 0; - _sizeLimit = limit; - _error = true; - unsigned size = 1 << 4; - if (size > limit) - size = (unsigned)limit; - _chars = (Byte *)MyAlloc(size); - if (_chars) - { - _size = size; - _error = false; - } -} - -CDynLimBuf & CDynLimBuf::operator+=(char c) throw() -{ - if (_error) - return *this; - if (_size == _pos) - { - size_t n = _sizeLimit - _size; - if (n == 0) - { - _error = true; - return *this; - } - if (n > _size) - n = _size; - - n += _pos; - - Byte *newBuf = (Byte *)MyAlloc(n); - if (!newBuf) - { - _error = true; - return *this; - } - memcpy(newBuf, _chars, _pos); - MyFree(_chars); - _chars = newBuf; - _size = n; - } - _chars[_pos++] = c; - return *this; -} - -CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw() -{ - if (_error) - return *this; - unsigned len = MyStringLen(s); - size_t rem = _sizeLimit - _pos; - if (rem < len) - { - len = (unsigned)rem; - _error = true; - } - if (_size - _pos < len) - { - size_t n = _pos + len; - if (n - _size < _size) - { - n = _sizeLimit; - if (n - _size > _size) - n = _size * 2; - } - - Byte *newBuf = (Byte *)MyAlloc(n); - if (!newBuf) - { - _error = true; - return *this; - } - memcpy(newBuf, _chars, _pos); - MyFree(_chars); - _chars = newBuf; - _size = n; - } - memcpy(_chars + _pos, s, len); - _pos += len; - return *this; -} +// Common/DynLimBuf.cpp + +#include "StdAfx.h" + +#include "DynLimBuf.h" +#include "MyString.h" + +CDynLimBuf::CDynLimBuf(size_t limit) throw() +{ + _chars = NULL; + _pos = 0; + _size = 0; + _sizeLimit = limit; + _error = true; + unsigned size = 1 << 4; + if (size > limit) + size = (unsigned)limit; + _chars = (Byte *)MyAlloc(size); + if (_chars) + { + _size = size; + _error = false; + } +} + +CDynLimBuf & CDynLimBuf::operator+=(char c) throw() +{ + if (_error) + return *this; + if (_size == _pos) + { + size_t n = _sizeLimit - _size; + if (n == 0) + { + _error = true; + return *this; + } + if (n > _size) + n = _size; + + n += _pos; + + Byte *newBuf = (Byte *)MyAlloc(n); + if (!newBuf) + { + _error = true; + return *this; + } + memcpy(newBuf, _chars, _pos); + MyFree(_chars); + _chars = newBuf; + _size = n; + } + _chars[_pos++] = (Byte)c; + return *this; +} + +CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw() +{ + if (_error) + return *this; + unsigned len = MyStringLen(s); + size_t rem = _sizeLimit - _pos; + if (rem < len) + { + len = (unsigned)rem; + _error = true; + } + if (_size - _pos < len) + { + size_t n = _pos + len; + if (n - _size < _size) + { + n = _sizeLimit; + if (n - _size > _size) + n = _size * 2; + } + + Byte *newBuf = (Byte *)MyAlloc(n); + if (!newBuf) + { + _error = true; + return *this; + } + memcpy(newBuf, _chars, _pos); + MyFree(_chars); + _chars = newBuf; + _size = n; + } + memcpy(_chars + _pos, s, len); + _pos += len; + return *this; +} diff -Nru p7zip-rar-16.02/CPP/Common/DynLimBuf.h p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.h --- p7zip-rar-16.02/CPP/Common/DynLimBuf.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/DynLimBuf.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,40 +1,41 @@ -// Common/DynLimBuf.h - -#ifndef __COMMON_DYN_LIM_BUF_H -#define __COMMON_DYN_LIM_BUF_H - -#include - -#include "../../C/Alloc.h" - -#include "MyString.h" - -class CDynLimBuf -{ - Byte *_chars; - size_t _pos; - size_t _size; - size_t _sizeLimit; - bool _error; - - CDynLimBuf(const CDynLimBuf &s); - - // ---------- forbidden functions ---------- - CDynLimBuf &operator+=(wchar_t c); - -public: - CDynLimBuf(size_t limit) throw(); - ~CDynLimBuf() { MyFree(_chars); } - - size_t Len() const { return _pos; } - void Empty() { _pos = 0; } - - operator const Byte *() const { return _chars; } - // const char *Ptr() const { return _chars; } - - CDynLimBuf &operator+=(char c) throw(); - CDynLimBuf &operator+=(const char *s) throw(); -}; - - -#endif +// Common/DynLimBuf.h + +#ifndef ZIP7_INC_COMMON_DYN_LIM_BUF_H +#define ZIP7_INC_COMMON_DYN_LIM_BUF_H + +#include + +#include "../../C/Alloc.h" + +#include "MyString.h" + +class CDynLimBuf +{ + Byte *_chars; + size_t _pos; + size_t _size; + size_t _sizeLimit; + bool _error; + + CDynLimBuf(const CDynLimBuf &s); + + // ---------- forbidden functions ---------- + CDynLimBuf &operator+=(wchar_t c); + +public: + CDynLimBuf(size_t limit) throw(); + ~CDynLimBuf() { MyFree(_chars); } + + size_t Len() const { return _pos; } + bool IsError() const { return _error; } + void Empty() { _pos = 0; _error = false; } + + operator const Byte *() const { return _chars; } + // const char *Ptr() const { return _chars; } + + CDynLimBuf &operator+=(char c) throw(); + CDynLimBuf &operator+=(const char *s) throw(); +}; + + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/DynamicBuffer.h p7zip-rar-16.02+really25.00+ds/CPP/Common/DynamicBuffer.h --- p7zip-rar-16.02/CPP/Common/DynamicBuffer.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/DynamicBuffer.h 2023-12-08 11:00:00.000000000 +0000 @@ -1,64 +1,76 @@ -// Common/DynamicBuffer.h - -#ifndef __COMMON_DYNAMIC_BUFFER_H -#define __COMMON_DYNAMIC_BUFFER_H - -template class CDynamicBuffer -{ - T *_items; - size_t _size; - size_t _pos; - - CDynamicBuffer(const CDynamicBuffer &buffer); - void operator=(const CDynamicBuffer &buffer); - - void Grow(size_t size) - { - size_t delta = _size >= 64 ? _size : 64; - if (delta < size) - delta = size; - size_t newCap = _size + delta; - if (newCap < delta) - { - newCap = _size + size; - if (newCap < size) - throw 20120116; - } - - T *newBuffer = new T[newCap]; - if (_pos != 0) - memcpy(newBuffer, _items, _pos * sizeof(T)); - delete []_items; - _items = newBuffer; - _size = newCap; - } - -public: - CDynamicBuffer(): _items(0), _size(0), _pos(0) {} - // operator T *() { return _items; } - operator const T *() const { return _items; } - ~CDynamicBuffer() { delete []_items; } - - T *GetCurPtrAndGrow(size_t addSize) - { - size_t rem = _size - _pos; - if (rem < addSize) - Grow(addSize - rem); - T *res = _items + _pos; - _pos += addSize; - return res; - } - - void AddData(const T *data, size_t size) - { - memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T)); - } - - const size_t GetPos() const { return _pos; } - - // void Empty() { _pos = 0; } -}; - -typedef CDynamicBuffer CByteDynamicBuffer; - -#endif +// Common/DynamicBuffer.h + +#ifndef ZIP7_INC_COMMON_DYNAMIC_BUFFER_H +#define ZIP7_INC_COMMON_DYNAMIC_BUFFER_H + +#include + +#include "MyTypes.h" + +template class CDynamicBuffer +{ + T *_items; + size_t _size; + size_t _pos; + + CDynamicBuffer(const CDynamicBuffer &buffer); + void operator=(const CDynamicBuffer &buffer); + + void Grow(size_t size) + { + size_t delta = _size >= 64 ? _size : 64; + if (delta < size) + delta = size; + size_t newCap = _size + delta; + if (newCap < delta) + { + newCap = _size + size; + if (newCap < size) + throw 20120116; + } + + T *newBuffer = new T[newCap]; + if (_pos != 0) + memcpy(newBuffer, _items, _pos * sizeof(T)); + delete []_items; + _items = newBuffer; + _size = newCap; + } + +public: + CDynamicBuffer(): _items(NULL), _size(0), _pos(0) {} + // operator T *() { return _items; } + operator const T *() const { return _items; } + ~CDynamicBuffer() { delete []_items; } + + void Free() + { + delete []_items; + _items = NULL; + _size = 0; + _pos = 0; + } + + T *GetCurPtrAndGrow(size_t addSize) + { + size_t rem = _size - _pos; + if (rem < addSize) + Grow(addSize - rem); + T *res = _items + _pos; + _pos += addSize; + return res; + } + + void AddData(const T *data, size_t size) + { + memcpy(GetCurPtrAndGrow(size), data, size * sizeof(T)); + } + + size_t GetPos() const { return _pos; } + + // void Empty() { _pos = 0; } +}; + +typedef CDynamicBuffer CByteDynamicBuffer; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/IntToString.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.cpp --- p7zip-rar-16.02/CPP/Common/IntToString.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.cpp 2023-12-11 07:00:00.000000000 +0000 @@ -1,146 +1,215 @@ -// Common/IntToString.cpp - -#include "StdAfx.h" - -#include "IntToString.h" - -#define CONVERT_INT_TO_STR(charType, tempSize) \ - unsigned char temp[tempSize]; unsigned i = 0; \ - while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ - *s++ = (charType)('0' + (unsigned)val); \ - while (i != 0) { i--; *s++ = temp[i]; } \ - *s = 0; - -void ConvertUInt32ToString(UInt32 val, char *s) throw() -{ - CONVERT_INT_TO_STR(char, 16); -} - -void ConvertUInt64ToString(UInt64 val, char *s) throw() -{ - if (val <= (UInt32)0xFFFFFFFF) - { - ConvertUInt32ToString((UInt32)val, s); - return; - } - CONVERT_INT_TO_STR(char, 24); -} - -void ConvertUInt64ToOct(UInt64 val, char *s) throw() -{ - UInt64 v = val; - unsigned i; - for (i = 1;; i++) - { - v >>= 3; - if (v == 0) - break; - } - s[i] = 0; - do - { - unsigned t = (unsigned)(val & 0x7); - val >>= 3; - s[--i] = (char)('0' + t); - } - while (i); -} - -void ConvertUInt32ToHex(UInt32 val, char *s) throw() -{ - UInt32 v = val; - unsigned i; - for (i = 1;; i++) - { - v >>= 4; - if (v == 0) - break; - } - s[i] = 0; - do - { - unsigned t = (unsigned)((val & 0xF)); - val >>= 4; - s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } - while (i); -} - -void ConvertUInt64ToHex(UInt64 val, char *s) throw() -{ - UInt64 v = val; - unsigned i; - for (i = 1;; i++) - { - v >>= 4; - if (v == 0) - break; - } - s[i] = 0; - do - { - unsigned t = (unsigned)((val & 0xF)); - val >>= 4; - s[--i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } - while (i); -} - -void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw() -{ - s[8] = 0; - for (int i = 7; i >= 0; i--) - { - unsigned t = val & 0xF; - val >>= 4; - s[i] = (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); - } -} - -/* -void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s) -{ - s[8] = 0; - for (int i = 7; i >= 0; i--) - { - unsigned t = val & 0xF; - val >>= 4; - s[i] = (wchar_t)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); - } -} -*/ - -void ConvertUInt32ToString(UInt32 val, wchar_t *s) throw() -{ - CONVERT_INT_TO_STR(wchar_t, 16); -} - -void ConvertUInt64ToString(UInt64 val, wchar_t *s) throw() -{ - if (val <= (UInt32)0xFFFFFFFF) - { - ConvertUInt32ToString((UInt32)val, s); - return; - } - CONVERT_INT_TO_STR(wchar_t, 24); -} - -void ConvertInt64ToString(Int64 val, char *s) throw() -{ - if (val < 0) - { - *s++ = '-'; - val = -val; - } - ConvertUInt64ToString(val, s); -} - -void ConvertInt64ToString(Int64 val, wchar_t *s) throw() -{ - if (val < 0) - { - *s++ = L'-'; - val = -val; - } - ConvertUInt64ToString(val, s); -} +// Common/IntToString.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#include "IntToString.h" + +#define CONVERT_INT_TO_STR(charType, tempSize) \ + if (val < 10) \ + *s++ = (charType)('0' + (unsigned)val); \ + else { \ + Byte temp[tempSize]; \ + size_t i = 0; \ + do { \ + temp[++i] = (Byte)('0' + (unsigned)(val % 10)); \ + val /= 10; } \ + while (val >= 10); \ + *s++ = (charType)('0' + (unsigned)val); \ + do { *s++ = (charType)temp[i]; } \ + while (--i); \ + } \ + *s = 0; \ + return s; + +char * ConvertUInt32ToString(UInt32 val, char *s) throw() +{ + CONVERT_INT_TO_STR(char, 16) +} + +char * ConvertUInt64ToString(UInt64 val, char *s) throw() +{ + if (val <= (UInt32)0xFFFFFFFF) + return ConvertUInt32ToString((UInt32)val, s); + CONVERT_INT_TO_STR(char, 24) +} + +wchar_t * ConvertUInt32ToString(UInt32 val, wchar_t *s) throw() +{ + CONVERT_INT_TO_STR(wchar_t, 16) +} + +wchar_t * ConvertUInt64ToString(UInt64 val, wchar_t *s) throw() +{ + if (val <= (UInt32)0xFFFFFFFF) + return ConvertUInt32ToString((UInt32)val, s); + CONVERT_INT_TO_STR(wchar_t, 24) +} + +void ConvertInt64ToString(Int64 val, char *s) throw() +{ + if (val < 0) + { + *s++ = '-'; + val = -val; + } + ConvertUInt64ToString((UInt64)val, s); +} + +void ConvertInt64ToString(Int64 val, wchar_t *s) throw() +{ + if (val < 0) + { + *s++ = L'-'; + val = -val; + } + ConvertUInt64ToString((UInt64)val, s); +} + + +void ConvertUInt64ToOct(UInt64 val, char *s) throw() +{ + { + UInt64 v = val; + do + s++; + while (v >>= 3); + } + *s = 0; + do + { + const unsigned t = (unsigned)val & 7; + *--s = (char)('0' + t); + } + while (val >>= 3); +} + +MY_ALIGN(16) const char k_Hex_Upper[16] = + { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; +MY_ALIGN(16) const char k_Hex_Lower[16] = + { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; + +void ConvertUInt32ToHex(UInt32 val, char *s) throw() +{ + { + UInt32 v = val; + do + s++; + while (v >>= 4); + } + *s = 0; + do + { + const unsigned t = (unsigned)val & 0xF; + *--s = GET_HEX_CHAR_UPPER(t); + } + while (val >>= 4); +} + +void ConvertUInt64ToHex(UInt64 val, char *s) throw() +{ + { + UInt64 v = val; + do + s++; + while (v >>= 4); + } + *s = 0; + do + { + const unsigned t = (unsigned)val & 0xF; + *--s = GET_HEX_CHAR_UPPER(t); + } + while (val >>= 4); +} + +void ConvertUInt32ToHex8Digits(UInt32 val, char *s) throw() +{ + s[8] = 0; + int i = 7; + do + { + { const unsigned t = (unsigned)val & 0xF; s[i--] = GET_HEX_CHAR_UPPER(t); } + { const unsigned t = (Byte)val >> 4; val >>= 8; s[i--] = GET_HEX_CHAR_UPPER(t); } + } + while (i >= 0); +} + +/* +void ConvertUInt32ToHex8Digits(UInt32 val, wchar_t *s) +{ + s[8] = 0; + for (int i = 7; i >= 0; i--) + { + const unsigned t = (unsigned)val & 0xF; + val >>= 4; + s[i] = GET_HEX_CHAR(t); + } +} +*/ + + +MY_ALIGN(16) static const Byte k_Guid_Pos[] = + { 6,4,2,0, 11,9, 16,14, 19,21, 24,26,28,30,32,34 }; + +char *RawLeGuidToString(const Byte *g, char *s) throw() +{ + s[ 8] = '-'; + s[13] = '-'; + s[18] = '-'; + s[23] = '-'; + s[36] = 0; + for (unsigned i = 0; i < 16; i++) + { + char *s2 = s + k_Guid_Pos[i]; + const unsigned v = g[i]; + s2[0] = GET_HEX_CHAR_UPPER(v >> 4); + s2[1] = GET_HEX_CHAR_UPPER(v & 0xF); + } + return s + 36; +} + +char *RawLeGuidToString_Braced(const Byte *g, char *s) throw() +{ + *s++ = '{'; + s = RawLeGuidToString(g, s); + *s++ = '}'; + *s = 0; + return s; +} + + +void ConvertDataToHex_Lower(char *dest, const Byte *src, size_t size) throw() +{ + if (size) + { + const Byte *lim = src + size; + do + { + const unsigned b = *src++; + dest[0] = GET_HEX_CHAR_LOWER(b >> 4); + dest[1] = GET_HEX_CHAR_LOWER(b & 0xF); + dest += 2; + } + while (src != lim); + } + *dest = 0; +} + +void ConvertDataToHex_Upper(char *dest, const Byte *src, size_t size) throw() +{ + if (size) + { + const Byte *lim = src + size; + do + { + const unsigned b = *src++; + dest[0] = GET_HEX_CHAR_UPPER(b >> 4); + dest[1] = GET_HEX_CHAR_UPPER(b & 0xF); + dest += 2; + } + while (src != lim); + } + *dest = 0; +} diff -Nru p7zip-rar-16.02/CPP/Common/IntToString.h p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.h --- p7zip-rar-16.02/CPP/Common/IntToString.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/IntToString.h 2023-10-01 06:00:00.000000000 +0000 @@ -1,24 +1,54 @@ -// Common/IntToString.h - -#ifndef __COMMON_INT_TO_STRING_H -#define __COMMON_INT_TO_STRING_H - -#include "MyTypes.h" - -void ConvertUInt32ToString(UInt32 value, char *s) throw(); -void ConvertUInt64ToString(UInt64 value, char *s) throw(); - -void ConvertUInt32ToString(UInt32 value, wchar_t *s) throw(); -void ConvertUInt64ToString(UInt64 value, wchar_t *s) throw(); - -void ConvertUInt64ToOct(UInt64 value, char *s) throw(); - -void ConvertUInt32ToHex(UInt32 value, char *s) throw(); -void ConvertUInt64ToHex(UInt64 value, char *s) throw(); -void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw(); -// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw(); - -void ConvertInt64ToString(Int64 value, char *s) throw(); -void ConvertInt64ToString(Int64 value, wchar_t *s) throw(); - -#endif +// Common/IntToString.h + +#ifndef ZIP7_INC_COMMON_INT_TO_STRING_H +#define ZIP7_INC_COMMON_INT_TO_STRING_H + +#include "MyTypes.h" + +// return: the pointer to the "terminating" null character after written characters + +char * ConvertUInt32ToString(UInt32 value, char *s) throw(); +char * ConvertUInt64ToString(UInt64 value, char *s) throw(); + +wchar_t * ConvertUInt32ToString(UInt32 value, wchar_t *s) throw(); +wchar_t * ConvertUInt64ToString(UInt64 value, wchar_t *s) throw(); +void ConvertInt64ToString(Int64 value, char *s) throw(); +void ConvertInt64ToString(Int64 value, wchar_t *s) throw(); + +void ConvertUInt64ToOct(UInt64 value, char *s) throw(); + +extern const char k_Hex_Upper[16]; +extern const char k_Hex_Lower[16]; + +#define GET_HEX_CHAR_UPPER(t) (k_Hex_Upper[t]) +#define GET_HEX_CHAR_LOWER(t) (k_Hex_Lower[t]) +/* +// #define GET_HEX_CHAR_UPPER(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) +static inline unsigned GetHex_Lower(unsigned v) +{ + const unsigned v0 = v + '0'; + v += 'a' - 10; + if (v < 'a') + v = v0; + return v; +} +static inline char GetHex_Upper(unsigned v) +{ + return (char)((v < 10) ? ('0' + v) : ('A' + (v - 10))); +} +*/ + + +void ConvertUInt32ToHex(UInt32 value, char *s) throw(); +void ConvertUInt64ToHex(UInt64 value, char *s) throw(); +void ConvertUInt32ToHex8Digits(UInt32 value, char *s) throw(); +// void ConvertUInt32ToHex8Digits(UInt32 value, wchar_t *s) throw(); + +// use RawLeGuid only for RAW bytes that contain stored GUID as Little-endian. +char *RawLeGuidToString(const Byte *guid, char *s) throw(); +char *RawLeGuidToString_Braced(const Byte *guid, char *s) throw(); + +void ConvertDataToHex_Lower(char *dest, const Byte *src, size_t size) throw(); +void ConvertDataToHex_Upper(char *dest, const Byte *src, size_t size) throw(); + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Lang.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.cpp --- p7zip-rar-16.02/CPP/Common/Lang.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.cpp 2023-05-16 10:00:00.000000000 +0000 @@ -1,163 +1,173 @@ -// Common/Lang.cpp - -#include "StdAfx.h" - -#include "Lang.h" -#include "StringToInt.h" -#include "UTFConvert.h" - -#include "../Windows/FileIO.h" - -void CLang::Clear() throw() -{ - delete []_text; - _text = 0; - _ids.Clear(); - _offsets.Clear(); -} - -static const wchar_t *kLangSignature = L";!@Lang2@!UTF-8!"; - -bool CLang::OpenFromString(const AString &s2) -{ - UString s; - if (!ConvertUTF8ToUnicode(s2, s)) - return false; - unsigned i = 0; - if (s.IsEmpty()) - return false; - if (s[0] == 0xFEFF) - i++; - - for (const wchar_t *p = kLangSignature;; i++) - { - wchar_t c = *p++; - if (c == 0) - break; - if (s[i] != c) - return false; - } - - _text = new wchar_t[s.Len() - i + 1]; - wchar_t *text = _text; - - Int32 id = -100; - UInt32 pos = 0; - - while (i < s.Len()) - { - unsigned start = pos; - do - { - wchar_t c = s[i++]; - if (c == '\n') - break; - if (c == '\\') - { - if (i == s.Len()) - return false; - c = s[i++]; - switch (c) - { - case '\n': return false; - case 'n': c = '\n'; break; - case 't': c = '\t'; break; - case '\\': c = '\\'; break; - default: text[pos++] = L'\\'; break; - } - } - text[pos++] = c; - } - while (i < s.Len()); - - { - unsigned j = start; - for (; j < pos; j++) - if (text[j] != ' ') - break; - if (j == pos) - { - id++; - continue; - } - } - if (text[start] == ';') - { - pos = start; - id++; - continue; - } - - text[pos++] = 0; - const wchar_t *end; - UInt32 id32 = ConvertStringToUInt32(text + start, &end); - if (*end == 0) - { - if (id32 > ((UInt32)1 << 30) || (Int32)id32 < id) - return false; - id = (Int32)id32; - pos = start; - continue; - } - - if (id < 0) - return false; - _ids.Add((UInt32)id++); - _offsets.Add(start); - } - - return true; -} - -bool CLang::Open(CFSTR fileName, const wchar_t *id) -{ - Clear(); - NWindows::NFile::NIO::CInFile file; - if (!file.Open(fileName)) - return false; - UInt64 length; - if (!file.GetLength(length)) - return false; - if (length > (1 << 20)) - return false; - - AString s; - unsigned len = (unsigned)length; - char *p = s.GetBuf(len); - UInt32 processed; - if (!file.Read(p, len, processed)) - return false; - file.Close(); - if (len != processed) - return false; - - char *p2 = p; - for (unsigned i = 0; i < len; i++) - { - char c = p[i]; - if (c == 0) - break; - if (c != 0x0D) - *p2++ = c; - } - *p2 = 0; - s.ReleaseBuf_SetLen((unsigned)(p2 - p)); - - if (OpenFromString(s)) - { - const wchar_t *name = Get(0); - if (name && wcscmp(name, id) == 0) - return true; - } - - Clear(); - return false; -} - -const wchar_t *CLang::Get(UInt32 id) const throw() -{ - int index = _ids.FindInSorted(id); - if (index < 0) - return NULL; - return _text + (size_t)_offsets[index]; -} +// Common/Lang.cpp + +#include "StdAfx.h" + +#include "Lang.h" +#include "StringToInt.h" +#include "UTFConvert.h" + +#include "../Windows/FileIO.h" + +void CLang::Clear() throw() +{ + _ids.Clear(); + _offsets.Clear(); + Comments.Clear(); + delete []_text; + _text = NULL; +} + +static const char * const kLangSignature = ";!@Lang2@!UTF-8!\n"; + +bool CLang::OpenFromString(const AString &s2) +{ + UString su; + if (!ConvertUTF8ToUnicode(s2, su)) + return false; + if (su.IsEmpty()) + return false; + const wchar_t *s = su; + const wchar_t *sLim = s + su.Len(); + if (*s == 0xFEFF) + s++; + for (const char *p = kLangSignature;; s++) + { + const Byte c = (Byte)(*p++); + if (c == 0) + break; + if (*s != c) + return false; + } + + wchar_t *text = new wchar_t[(size_t)(sLim - s) + 1]; + _text = text; + + UString comment; + Int32 id = -1024; + unsigned pos = 0; + + while (s != sLim) + { + const unsigned start = pos; + do + { + wchar_t c = *s++; + if (c == '\n') + break; + if (c == '\\') + { + if (s == sLim) + return false; + c = *s++; + switch (c) + { + case '\n': return false; + case 'n': c = '\n'; break; + case 't': c = '\t'; break; + case '\\': /* c = '\\'; */ break; + default: text[pos++] = L'\\'; break; + } + } + text[pos++] = c; + } + while (s != sLim); + + { + unsigned j = start; + for (; j < pos; j++) + if (text[j] != ' ' && text[j] != '\t') + break; + if (j == pos) + { + id++; + pos = start; + continue; + } + } + + // start != pos + text[pos++] = 0; + + if (text[start] == ';') + { + comment = text + start; + comment.TrimRight(); + if (comment.Len() != 1) + Comments.Add(comment); + id++; + pos = start; + continue; + } + + const wchar_t *end; + const UInt32 id32 = ConvertStringToUInt32(text + start, &end); + if (*end == 0) + { + if (id32 > ((UInt32)1 << 30) || (Int32)id32 < id) + return false; + id = (Int32)id32; + pos = start; + continue; + } + + if (id < 0) + return false; + _ids.Add((UInt32)id++); + _offsets.Add(start); + } + + return true; +} + +bool CLang::Open(CFSTR fileName, const char *id) +{ + Clear(); + NWindows::NFile::NIO::CInFile file; + if (!file.Open(fileName)) + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length > (1 << 20)) + return false; + + AString s; + const unsigned len = (unsigned)length; + char *p = s.GetBuf(len); + size_t processed; + if (!file.ReadFull(p, len, processed)) + return false; + file.Close(); + if (len != processed) + return false; + + char *p2 = p; + for (unsigned i = 0; i < len; i++) + { + const char c = p[i]; + if (c == 0) + break; + if (c != 0x0D) + *p2++ = c; + } + *p2 = 0; + s.ReleaseBuf_SetLen((unsigned)(p2 - p)); + + if (OpenFromString(s)) + { + const wchar_t *name = Get(0); + if (name && StringsAreEqual_Ascii(name, id)) + return true; + } + + Clear(); + return false; +} + +const wchar_t *CLang::Get(UInt32 id) const throw() +{ + const int index = _ids.FindInSorted(id); + if (index < 0) + return NULL; + return _text + (size_t)_offsets[(unsigned)index]; +} diff -Nru p7zip-rar-16.02/CPP/Common/Lang.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.h --- p7zip-rar-16.02/CPP/Common/Lang.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Lang.h 2023-05-16 10:00:00.000000000 +0000 @@ -1,23 +1,30 @@ -// Common/Lang.h - -#ifndef __COMMON_LANG_H -#define __COMMON_LANG_H - -#include "MyString.h" - -class CLang -{ - wchar_t *_text; - CRecordVector _ids; - CRecordVector _offsets; - - bool OpenFromString(const AString &s); -public: - CLang(): _text(0) {} - ~CLang() { Clear(); } - bool Open(CFSTR fileName, const wchar_t *id); - void Clear() throw(); - const wchar_t *Get(UInt32 id) const throw(); -}; - -#endif +// Common/Lang.h + +#ifndef ZIP7_INC_COMMON_LANG_H +#define ZIP7_INC_COMMON_LANG_H + +#include "MyString.h" + +class CLang +{ + wchar_t *_text; + + bool OpenFromString(const AString &s); +public: + CRecordVector _ids; + CRecordVector _offsets; + UStringVector Comments; + + CLang(): _text(NULL) {} + ~CLang() { Clear(); } + bool Open(CFSTR fileName, const char *id); + void Clear() throw(); + bool IsEmpty() const { return _ids.IsEmpty(); } + const wchar_t *Get(UInt32 id) const throw(); + const wchar_t *Get_by_index(unsigned index) const throw() + { + return _text + (size_t)_offsets[index]; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/ListFileUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.cpp --- p7zip-rar-16.02/CPP/Common/ListFileUtils.cpp 2015-07-14 20:13:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.cpp 2024-02-19 10:00:00.000000000 +0000 @@ -1,117 +1,150 @@ -// Common/ListFileUtils.cpp - -#include "StdAfx.h" - -#include "../../C/CpuArch.h" - -#include "../Windows/FileIO.h" - -#include "ListFileUtils.h" -#include "MyBuffer.h" -#include "StringConvert.h" -#include "UTFConvert.h" - -static const char kQuoteChar = '\"'; - -static void AddName(UStringVector &strings, UString &s) -{ - s.Trim(); - if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar) - { - s.DeleteBack(); - s.Delete(0); - } - if (!s.IsEmpty()) - strings.Add(s); -} - -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage) -{ - NWindows::NFile::NIO::CInFile file; - if (!file.Open(fileName,true)) /* follow the symbolic link */ - return false; - UInt64 fileSize; - if (!file.GetLength(fileSize)) - return false; - if (fileSize >= ((UInt32)1 << 31) - 32) - return false; - UString u; - if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE) - { - if ((fileSize & 1) != 0) - return false; - CByteArr buf((size_t)fileSize); - UInt32 processed; - if (!file.Read(buf, (UInt32)fileSize, processed)) - return false; - if (processed != fileSize) - return false; - file.Close(); - unsigned num = (unsigned)fileSize / 2; - wchar_t *p = u.GetBuf(num); - if (codePage == MY__CP_UTF16) - for (unsigned i = 0; i < num; i++) - { - wchar_t c = GetUi16(buf + i * 2); - if (c == 0) - return false; - p[i] = c; - } - else - for (unsigned i = 0; i < num; i++) - { - wchar_t c = (wchar_t)GetBe16(buf + i * 2); - if (c == 0) - return false; - p[i] = c; - } - p[num] = 0; - u.ReleaseBuf_SetLen(num); - } - else - { - AString s; - char *p = s.GetBuf((unsigned)fileSize); - UInt32 processed; - if (!file.Read(p, (UInt32)fileSize, processed)) - return false; - if (processed != fileSize) - return false; - file.Close(); - s.ReleaseBuf_CalcLen((unsigned)processed); - if (s.Len() != processed) - return false; - - // #ifdef CP_UTF8 - if (codePage == CP_UTF8) - { - if (!ConvertUTF8ToUnicode(s, u)) - return false; - } - else - // #endif - MultiByteToUnicodeString2(u, s, codePage); - } - - const wchar_t kGoodBOM = 0xFEFF; - const wchar_t kBadBOM = 0xFFFE; - - UString s; - unsigned i = 0; - for (; i < u.Len() && u[i] == kGoodBOM; i++); - for (; i < u.Len(); i++) - { - wchar_t c = u[i]; - if (c == kGoodBOM || c == kBadBOM) - return false; - if (c == L'\n' || c == 0xD) - { - AddName(strings, s); - s.Empty(); - } - else - s += c; - } - AddName(strings, s); - return true; -} +// Common/ListFileUtils.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#include "ListFileUtils.h" +#include "MyBuffer.h" +#include "StringConvert.h" +#include "UTFConvert.h" + +#include "../Windows/FileIO.h" + +#define CSysInFile NWindows::NFile::NIO::CInFile +#define MY_GET_LAST_ERROR ::GetLastError() + + +#define kQuoteChar '\"' + + +static void AddName(UStringVector &strings, UString &s) +{ + s.Trim(); + if (s.Len() >= 2 && s[0] == kQuoteChar && s.Back() == kQuoteChar) + { + s.DeleteBack(); + s.Delete(0); + } + if (!s.IsEmpty()) + strings.Add(s); +} + + +static bool My_File_Read(CSysInFile &file, void *data, size_t size, DWORD &lastError) +{ + size_t processed; + if (!file.ReadFull(data, size, processed)) + { + lastError = MY_GET_LAST_ERROR; + return false; + } + if (processed != size) + { + lastError = 1; // error: size of listfile was changed + return false; + } + return true; +} + + +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError) +{ + lastError = 0; + CSysInFile file; + if (!file.Open(fileName)) + { + lastError = MY_GET_LAST_ERROR; + return false; + } + UInt64 fileSize; + if (!file.GetLength(fileSize)) + { + lastError = MY_GET_LAST_ERROR; + return false; + } + if (fileSize >= ((UInt32)1 << 31) - 32) + return false; + UString u; + if (codePage == Z7_WIN_CP_UTF16 || codePage == Z7_WIN_CP_UTF16BE) + { + if ((fileSize & 1) != 0) + return false; + CByteArr buf((size_t)fileSize); + + if (!My_File_Read(file, buf, (size_t)fileSize, lastError)) + return false; + + file.Close(); + const size_t num = (size_t)fileSize / 2; + wchar_t *p = u.GetBuf((unsigned)num); + if (codePage == Z7_WIN_CP_UTF16) + for (size_t i = 0; i < num; i++) + { + const wchar_t c = GetUi16(buf.ConstData() + (size_t)i * 2); + if (c == 0) + return false; + p[i] = c; + } + else + for (size_t i = 0; i < num; i++) + { + const wchar_t c = (wchar_t)GetBe16(buf.ConstData() + (size_t)i * 2); + if (c == 0) + return false; + p[i] = c; + } + p[num] = 0; + u.ReleaseBuf_SetLen((unsigned)num); + } + else + { + AString s; + char *p = s.GetBuf((unsigned)fileSize); + + if (!My_File_Read(file, p, (size_t)fileSize, lastError)) + return false; + + file.Close(); + s.ReleaseBuf_CalcLen((unsigned)fileSize); + if (s.Len() != fileSize) + return false; + + // #ifdef CP_UTF8 + if (codePage == CP_UTF8) + { + // we must check UTF8 here, if convert function doesn't check + if (!CheckUTF8_AString(s)) + return false; + if (!ConvertUTF8ToUnicode(s, u)) + return false; + } + else + // #endif + MultiByteToUnicodeString2(u, s, codePage); + } + + const wchar_t kGoodBOM = 0xFEFF; + // const wchar_t kBadBOM = 0xFFFE; + + UString s; + unsigned i = 0; + for (; i < u.Len() && u[i] == kGoodBOM; i++); + for (; i < u.Len(); i++) + { + wchar_t c = u[i]; + /* + if (c == kGoodBOM || c == kBadBOM) + return false; + */ + if (c == '\n' || c == 0xD) + { + AddName(strings, s); + s.Empty(); + } + else + s += c; + } + AddName(strings, s); + return true; +} diff -Nru p7zip-rar-16.02/CPP/Common/ListFileUtils.h p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.h --- p7zip-rar-16.02/CPP/Common/ListFileUtils.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/ListFileUtils.h 2023-02-01 17:00:00.000000000 +0000 @@ -1,14 +1,18 @@ -// Common/ListFileUtils.h - -#ifndef __COMMON_LIST_FILE_UTILS_H -#define __COMMON_LIST_FILE_UTILS_H - -#include "MyString.h" -#include "MyTypes.h" - -#define MY__CP_UTF16 1200 -#define MY__CP_UTF16BE 1201 - -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); - -#endif +// Common/ListFileUtils.h + +#ifndef ZIP7_INC_COMMON_LIST_FILE_UTILS_H +#define ZIP7_INC_COMMON_LIST_FILE_UTILS_H + +#include "MyString.h" +#include "MyTypes.h" + +#define Z7_WIN_CP_UTF16 1200 +#define Z7_WIN_CP_UTF16BE 1201 + +// bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); + + // = CP_OEMCP +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, + DWORD &lastError); + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/LzFindPrepare.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/LzFindPrepare.cpp --- p7zip-rar-16.02/CPP/Common/LzFindPrepare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/LzFindPrepare.cpp 2021-07-15 10:37:36.000000000 +0000 @@ -0,0 +1,7 @@ +// Sha256Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/LzFind.h" + +static struct CLzFindPrepare { CLzFindPrepare() { LzFindPrepare(); } } g_CLzFindPrepare; diff -Nru p7zip-rar-16.02/CPP/Common/Md5Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Md5Reg.cpp --- p7zip-rar-16.02/CPP/Common/Md5Reg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Md5Reg.cpp 2024-11-26 07:00:00.000000000 +0000 @@ -0,0 +1,44 @@ +// Md5Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Md5.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CMd5Hasher + , IHasher +) + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CMd5 *Md5() { return (CMd5 *)(void *)(Byte *)_buf; } +public: + CMd5Hasher(): + _buf(sizeof(CMd5)) + { + Md5_Init(Md5()); + } +}; + +Z7_COM7F_IMF2(void, CMd5Hasher::Init()) +{ + Md5_Init(Md5()); +} + +Z7_COM7F_IMF2(void, CMd5Hasher::Update(const void *data, UInt32 size)) +{ + Md5_Update(Md5(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CMd5Hasher::Final(Byte *digest)) +{ + Md5_Final(Md5(), digest); +} + +REGISTER_HASHER(CMd5Hasher, 0x208, "MD5", MD5_DIGEST_SIZE) diff -Nru p7zip-rar-16.02/CPP/Common/MyBuffer.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer.h --- p7zip-rar-16.02/CPP/Common/MyBuffer.h 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer.h 2024-02-19 08:00:00.000000000 +0000 @@ -1,244 +1,297 @@ -// Common/MyBuffer.h - -#ifndef __COMMON_MY_BUFFER_H -#define __COMMON_MY_BUFFER_H - -#include "Defs.h" - -template class CBuffer -{ - T *_items; - size_t _size; - -public: - void Free() - { - if (_items) - { - delete []_items; - _items = 0; - } - _size = 0; - } - - CBuffer(): _items(0), _size(0) {}; - CBuffer(size_t size): _items(0), _size(0) { _items = new T[size]; _size = size; } - CBuffer(const CBuffer &buffer): _items(0), _size(0) - { - size_t size = buffer._size; - if (size != 0) - { - _items = new T[size]; - memcpy(_items, buffer._items, size * sizeof(T)); - _size = size; - } - } - - ~CBuffer() { delete []_items; } - - operator T *() { return _items; } - operator const T *() const { return _items; } - size_t Size() const { return _size; } - - void Alloc(size_t size) - { - if (size != _size) - { - Free(); - if (size != 0) - { - _items = new T[size]; - _size = size; - } - } - } - - void AllocAtLeast(size_t size) - { - if (size > _size) - { - Free(); - _items = new T[size]; - _size = size; - } - } - - void CopyFrom(const T *data, size_t size) - { - Alloc(size); - if (size != 0) - memcpy(_items, data, size * sizeof(T)); - } - - void ChangeSize_KeepData(size_t newSize, size_t keepSize) - { - if (newSize == _size) - return; - T *newBuffer = NULL; - if (newSize != 0) - { - newBuffer = new T[newSize]; - if (keepSize > _size) - keepSize = _size; - if (keepSize != 0) - memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T)); - } - delete []_items; - _items = newBuffer; - _size = newSize; - } - - CBuffer& operator=(const CBuffer &buffer) - { - if (&buffer != this) - CopyFrom(buffer, buffer._size); - return *this; - } -}; - -template -bool operator==(const CBuffer& b1, const CBuffer& b2) -{ - size_t size1 = b1.Size(); - if (size1 != b2.Size()) - return false; - if (size1 == 0) - return true; - return memcmp(b1, b2, size1 * sizeof(T)) == 0; -} - -template -bool operator!=(const CBuffer& b1, const CBuffer& b2) -{ - size_t size1 = b1.Size(); - if (size1 != b2.Size()) - return true; - if (size1 == 0) - return false; - return memcmp(b1, b2, size1 * sizeof(T)) != 0; -} - - -typedef CBuffer CCharBuffer; -// typedef CBuffer CWCharBuffer; -typedef CBuffer CByteBuffer; - - -template class CObjArray -{ -protected: - T *_items; -private: - // we disable constructors - CObjArray(const CObjArray &buffer); - void operator=(const CObjArray &buffer); -public: - void Free() - { - delete []_items; - _items = 0; - } - CObjArray(size_t size): _items(0) { if (size != 0) _items = new T[size]; } - CObjArray(): _items(0) {}; - ~CObjArray() { delete []_items; } - - operator T *() { return _items; } - operator const T *() const { return _items; } - - void Alloc(size_t newSize) - { - delete []_items; - _items = 0; - _items = new T[newSize]; - } -}; - -typedef CObjArray CByteArr; -typedef CObjArray CBoolArr; -typedef CObjArray CIntArr; -typedef CObjArray CUIntArr; - - -template class CObjArray2 -{ - T *_items; - unsigned _size; - - CObjArray2(const CObjArray2 &buffer); - void operator=(const CObjArray2 &buffer); -public: - - void Free() - { - delete []_items; - _items = 0; - _size = 0; - } - CObjArray2(): _items(0), _size(0) {}; - /* - CObjArray2(const CObjArray2 &buffer): _items(0), _size(0) - { - size_t newSize = buffer._size; - if (newSize != 0) - { - T *newBuffer = new T[newSize];; - _items = newBuffer; - _size = newSize; - const T *src = buffer; - for (size_t i = 0; i < newSize; i++) - newBuffer[i] = src[i]; - } - } - */ - /* - CObjArray2(size_t size): _items(0), _size(0) - { - if (size != 0) - { - _items = new T[size]; - _size = size; - } - } - */ - - ~CObjArray2() { delete []_items; } - - operator T *() { return _items; } - operator const T *() const { return _items; } - - unsigned Size() const { return (unsigned)_size; } - bool IsEmpty() const { return _size == 0; } - - // SetSize doesn't keep old items. It allocates new array if size is not equal - void SetSize(unsigned size) - { - if (size == _size) - return; - T *newBuffer = NULL; - if (size != 0) - newBuffer = new T[size]; - delete []_items; - _items = newBuffer; - _size = size; - } - - /* - CObjArray2& operator=(const CObjArray2 &buffer) - { - Free(); - size_t newSize = buffer._size; - if (newSize != 0) - { - T *newBuffer = new T[newSize];; - _items = newBuffer; - _size = newSize; - const T *src = buffer; - for (size_t i = 0; i < newSize; i++) - newBuffer[i] = src[i]; - } - return *this; - } - */ -}; - -#endif +// Common/MyBuffer.h + +#ifndef ZIP7_INC_COMMON_MY_BUFFER_H +#define ZIP7_INC_COMMON_MY_BUFFER_H + +#include + +#include "Defs.h" +#include "MyTypes.h" + +/* 7-Zip now uses CBuffer only as CByteBuffer. + So there is no need to use Z7_ARRAY_NEW macro in CBuffer code. */ + +template class CBuffer +{ + T *_items; + size_t _size; + +public: + void Free() + { + if (_items) + { + delete []_items; + _items = NULL; + } + _size = 0; + } + + CBuffer(): _items(NULL), _size(0) {} + CBuffer(size_t size): _items(NULL), _size(0) + { + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + CBuffer(const CBuffer &buffer): _items(NULL), _size(0) + { + const size_t size = buffer._size; + if (size != 0) + { + _items = new T[size]; + memcpy(_items, buffer._items, size * sizeof(T)); + _size = size; + } + } + + ~CBuffer() { delete []_items; } + + operator T *() { return _items; } + operator const T *() const { return _items; } + const T* ConstData() const { return _items; } + T* NonConstData() const { return _items; } + T* NonConstData() { return _items; } + // const T* Data() const { return _items; } + // T* Data() { return _items; } + + size_t Size() const { return _size; } + + void Alloc(size_t size) + { + if (size != _size) + { + Free(); + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + } + + void AllocAtLeast(size_t size) + { + if (size > _size) + { + Free(); + _items = new T[size]; + _size = size; + } + } + + void CopyFrom(const T *data, size_t size) + { + Alloc(size); + if (size != 0) + memcpy(_items, data, size * sizeof(T)); + } + + void ChangeSize_KeepData(size_t newSize, size_t keepSize) + { + if (newSize == _size) + return; + T *newBuffer = NULL; + if (newSize != 0) + { + newBuffer = new T[newSize]; + if (keepSize > _size) + keepSize = _size; + if (keepSize != 0) + memcpy(newBuffer, _items, MyMin(keepSize, newSize) * sizeof(T)); + } + delete []_items; + _items = newBuffer; + _size = newSize; + } + + void Wipe() + { + if (_size != 0) + memset(_items, 0, _size * sizeof(T)); + } + + CBuffer& operator=(const CBuffer &buffer) + { + if (&buffer != this) + CopyFrom(buffer, buffer._size); + return *this; + } +}; + +template +bool operator==(const CBuffer& b1, const CBuffer& b2) +{ + size_t size1 = b1.Size(); + if (size1 != b2.Size()) + return false; + if (size1 == 0) + return true; + return memcmp(b1, b2, size1 * sizeof(T)) == 0; +} + +template +bool operator!=(const CBuffer& b1, const CBuffer& b2) +{ + size_t size1 = b1.Size(); + if (size1 != b2.Size()) + return true; + if (size1 == 0) + return false; + return memcmp(b1, b2, size1 * sizeof(T)) != 0; +} + + +// typedef CBuffer CCharBuffer; +// typedef CBuffer CWCharBuffer; +typedef CBuffer CByteBuffer; + + +class CByteBuffer_Wipe: public CByteBuffer +{ + Z7_CLASS_NO_COPY(CByteBuffer_Wipe) +public: + // CByteBuffer_Wipe(): CBuffer() {} + CByteBuffer_Wipe(size_t size): CBuffer(size) {} + ~CByteBuffer_Wipe() { Wipe(); } +}; + + + +template class CObjArray +{ +protected: + T *_items; +private: + // we disable copy + CObjArray(const CObjArray &buffer); + void operator=(const CObjArray &buffer); +public: + void Free() + { + delete []_items; + _items = NULL; + } + CObjArray(size_t size): _items(NULL) + { + if (size != 0) + { + Z7_ARRAY_NEW(_items, T, size) + // _items = new T[size]; + } + } + CObjArray(): _items(NULL) {} + ~CObjArray() { delete []_items; } + + operator T *() { return _items; } + operator const T *() const { return _items; } + const T* ConstData() const { return _items; } + T* NonConstData() const { return _items; } + T* NonConstData() { return _items; } + // const T* Data() const { return _items; } + // T* Data() { return _items; } + + void Alloc(size_t newSize) + { + delete []_items; + _items = NULL; + Z7_ARRAY_NEW(_items, T, newSize) + // _items = new T[newSize]; + } +}; + +typedef CObjArray CByteArr; +typedef CObjArray CBoolArr; +typedef CObjArray CIntArr; +typedef CObjArray CUIntArr; + + +template class CObjArray2 +{ + T *_items; + unsigned _size; + + // we disable copy + CObjArray2(const CObjArray2 &buffer); + void operator=(const CObjArray2 &buffer); +public: + + void Free() + { + delete []_items; + _items = NULL; + _size = 0; + } + CObjArray2(): _items(NULL), _size(0) {} + /* + CObjArray2(const CObjArray2 &buffer): _items(NULL), _size(0) + { + size_t newSize = buffer._size; + if (newSize != 0) + { + T *newBuffer = new T[newSize];; + _items = newBuffer; + _size = newSize; + const T *src = buffer; + for (size_t i = 0; i < newSize; i++) + newBuffer[i] = src[i]; + } + } + */ + /* + CObjArray2(size_t size): _items(NULL), _size(0) + { + if (size != 0) + { + _items = new T[size]; + _size = size; + } + } + */ + + ~CObjArray2() { delete []_items; } + + operator T *() { return _items; } + operator const T *() const { return _items; } + + unsigned Size() const { return (unsigned)_size; } + bool IsEmpty() const { return _size == 0; } + + // SetSize doesn't keep old items. It allocates new array if size is not equal + void SetSize(unsigned size) + { + if (size == _size) + return; + T *newBuffer = NULL; + if (size != 0) + { + Z7_ARRAY_NEW(newBuffer, T, size) + // newBuffer = new T[size]; + } + delete []_items; + _items = newBuffer; + _size = size; + } + + /* + CObjArray2& operator=(const CObjArray2 &buffer) + { + Free(); + size_t newSize = buffer._size; + if (newSize != 0) + { + T *newBuffer = new T[newSize];; + _items = newBuffer; + _size = newSize; + const T *src = buffer; + for (size_t i = 0; i < newSize; i++) + newBuffer[i] = src[i]; + } + return *this; + } + */ +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyBuffer2.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer2.h --- p7zip-rar-16.02/CPP/Common/MyBuffer2.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyBuffer2.h 2023-12-10 20:00:00.000000000 +0000 @@ -0,0 +1,185 @@ +// Common/MyBuffer2.h + +#ifndef ZIP7_INC_COMMON_MY_BUFFER2_H +#define ZIP7_INC_COMMON_MY_BUFFER2_H + +#include "../../C/Alloc.h" + +#include "MyTypes.h" + +class CMidBuffer +{ + Byte *_data; + size_t _size; + + Z7_CLASS_NO_COPY(CMidBuffer) + +public: + CMidBuffer(): _data(NULL), _size(0) {} + ~CMidBuffer() { ::MidFree(_data); } + + void Free() { ::MidFree(_data); _data = NULL; _size = 0; } + + bool IsAllocated() const { return _data != NULL; } + operator Byte *() { return _data; } + operator const Byte *() const { return _data; } + size_t Size() const { return _size; } + + void Alloc(size_t size) + { + if (!_data || size != _size) + { + ::MidFree(_data); + _size = 0; + _data = NULL; + _data = (Byte *)::MidAlloc(size); + if (_data) + _size = size; + } + } + + void AllocAtLeast(size_t size) + { + if (!_data || size > _size) + { + ::MidFree(_data); + const size_t kMinSize = (size_t)1 << 16; + if (size < kMinSize) + size = kMinSize; + _size = 0; + _data = NULL; + _data = (Byte *)::MidAlloc(size); + if (_data) + _size = size; + } + } +}; + + +class CAlignedBuffer1 +{ + Byte *_data; + + Z7_CLASS_NO_COPY(CAlignedBuffer1) + +public: + ~CAlignedBuffer1() + { + z7_AlignedFree(_data); + } + + CAlignedBuffer1(size_t size) + { + _data = NULL; + _data = (Byte *)z7_AlignedAlloc(size); + if (!_data) + throw 1; + } + + operator Byte *() { return _data; } + operator const Byte *() const { return _data; } +}; + + +class CAlignedBuffer +{ + Byte *_data; + size_t _size; + + Z7_CLASS_NO_COPY(CAlignedBuffer) + +public: + CAlignedBuffer(): _data(NULL), _size(0) {} + ~CAlignedBuffer() + { + z7_AlignedFree(_data); + } + + /* + CAlignedBuffer(size_t size): _size(0) + { + _data = NULL; + _data = (Byte *)z7_AlignedAlloc(size); + if (!_data) + throw 1; + _size = size; + } + */ + + void Free() + { + z7_AlignedFree(_data); + _data = NULL; + _size = 0; + } + + bool IsAllocated() const { return _data != NULL; } + operator Byte *() { return _data; } + operator const Byte *() const { return _data; } + size_t Size() const { return _size; } + + void Alloc(size_t size) + { + if (!_data || size != _size) + { + z7_AlignedFree(_data); + _size = 0; + _data = NULL; + _data = (Byte *)z7_AlignedAlloc(size); + if (_data) + _size = size; + } + } + + void AllocAtLeast(size_t size) + { + if (!_data || size > _size) + { + z7_AlignedFree(_data); + _size = 0; + _data = NULL; + _data = (Byte *)z7_AlignedAlloc(size); + if (_data) + _size = size; + } + } + + // (size <= size_max) + void AllocAtLeast_max(size_t size, size_t size_max) + { + if (!_data || size > _size) + { + z7_AlignedFree(_data); + _size = 0; + _data = NULL; + if (size_max < size) size_max = size; // optional check + const size_t delta = size / 2; + size += delta; + if (size < delta || size > size_max) + size = size_max; + _data = (Byte *)z7_AlignedAlloc(size); + if (_data) + _size = size; + } + } +}; + +/* + CMidAlignedBuffer must return aligned pointer. + - in Windows it uses CMidBuffer(): MidAlloc() : VirtualAlloc() + VirtualAlloc(): Memory allocated is automatically initialized to zero. + MidAlloc(0) returns NULL + - in non-Windows systems it uses g_AlignedAlloc. + g_AlignedAlloc::Alloc(size = 0) can return non NULL. +*/ + +typedef +#ifdef _WIN32 + CMidBuffer +#else + CAlignedBuffer +#endif + CMidAlignedBuffer; + + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyCom.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyCom.h --- p7zip-rar-16.02/CPP/Common/MyCom.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyCom.h 2024-10-16 16:00:00.000000000 +0000 @@ -1,262 +1,693 @@ -// MyCom.h - -#ifndef __MY_COM_H -#define __MY_COM_H - -#include "MyWindows.h" -#include "NewHandler.h" - -#ifndef RINOK -#define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; } -#endif - -template -class CMyComPtr -{ - T* _p; -public: - CMyComPtr(): _p(NULL) {} - CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); } - CMyComPtr(const CMyComPtr& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); } - ~CMyComPtr() { if (_p) _p->Release(); } - void Release() { if (_p) { _p->Release(); _p = NULL; } } - operator T*() const { return (T*)_p; } - // T& operator*() const { return *_p; } - T** operator&() { return &_p; } - T* operator->() const { return _p; } - T* operator=(T* p) - { - if (p) - p->AddRef(); - if (_p) - _p->Release(); - _p = p; - return p; - } - T* operator=(const CMyComPtr& lp) { return (*this = lp._p); } - bool operator!() const { return (_p == NULL); } - // bool operator==(T* pT) const { return _p == pT; } - void Attach(T* p2) - { - Release(); - _p = p2; - } - T* Detach() - { - T* pt = _p; - _p = NULL; - return pt; - } - #ifdef _WIN32 - HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) - { - return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); - } - #endif - /* - HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) - { - CLSID clsid; - HRESULT hr = CLSIDFromProgID(szProgID, &clsid); - ATLASSERT(_p == NULL); - if (SUCCEEDED(hr)) - hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); - return hr; - } - */ - template - HRESULT QueryInterface(REFGUID iid, Q** pp) const throw() - { - return _p->QueryInterface(iid, (void**)pp); - } -}; - -////////////////////////////////////////////////////////// - -inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) -{ - *bstr = ::SysAllocString(src); - return (*bstr) ? S_OK : E_OUTOFMEMORY; -} - -class CMyComBSTR -{ - BSTR m_str; - -public: - CMyComBSTR(): m_str(NULL) {} - ~CMyComBSTR() { ::SysFreeString(m_str); } - BSTR* operator&() { return &m_str; } - operator LPCOLESTR() const { return m_str; } - // operator bool() const { return m_str != NULL; } - // bool operator!() const { return m_str == NULL; } -private: - // operator BSTR() const { return m_str; } - - CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } - // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } - // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } - CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } - - /* - CMyComBSTR(REFGUID src) - { - LPOLESTR szGuid; - StringFromCLSID(src, &szGuid); - m_str = ::SysAllocString(szGuid); - CoTaskMemFree(szGuid); - } - */ - - CMyComBSTR& operator=(const CMyComBSTR& src) - { - if (m_str != src.m_str) - { - if (m_str) - ::SysFreeString(m_str); - m_str = src.MyCopy(); - } - return *this; - } - - CMyComBSTR& operator=(LPCOLESTR src) - { - ::SysFreeString(m_str); - m_str = ::SysAllocString(src); - return *this; - } - - unsigned Len() const { return ::SysStringLen(m_str); } - - BSTR MyCopy() const - { - // We don't support Byte BSTRs here - return ::SysAllocStringLen(m_str, ::SysStringLen(m_str)); - /* - UINT byteLen = ::SysStringByteLen(m_str); - BSTR res = ::SysAllocStringByteLen(NULL, byteLen); - if (res && byteLen != 0 && m_str) - memcpy(res, m_str, byteLen); - return res; - */ - } - - /* - void Attach(BSTR src) { m_str = src; } - BSTR Detach() - { - BSTR s = m_str; - m_str = NULL; - return s; - } - */ - - void Empty() - { - ::SysFreeString(m_str); - m_str = NULL; - } -}; - -////////////////////////////////////////////////////////// - -class CMyUnknownImp -{ -public: - ULONG __m_RefCount; - CMyUnknownImp(): __m_RefCount(0) {} - - // virtual ~CMyUnknownImp() {}; -}; - -#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \ -(REFGUID iid, void **outObject) throw() { *outObject = NULL; - -#define MY_QUERYINTERFACE_ENTRY(i) else if (iid == IID_ ## i) \ - { *outObject = (void *)(i *)this; } - -#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \ - { *outObject = (void *)(IUnknown *)(i *)this; } - -#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ - MY_QUERYINTERFACE_ENTRY(i) - -#define MY_QUERYINTERFACE_END else return E_NOINTERFACE; ++__m_RefCount; /* AddRef(); */ return S_OK; } - -#define MY_ADDREF_RELEASE \ -STDMETHOD_(ULONG, AddRef)() throw() { return ++__m_RefCount; } \ -STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ - return __m_RefCount; delete this; return 0; } - -#define MY_UNKNOWN_IMP_SPEC(i) \ - MY_QUERYINTERFACE_BEGIN \ - i \ - MY_QUERYINTERFACE_END \ - MY_ADDREF_RELEASE - - -#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \ - MY_QUERYINTERFACE_END \ - MY_ADDREF_RELEASE - -#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \ - MY_QUERYINTERFACE_ENTRY(i) \ - ) - -#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - ) - -#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - MY_QUERYINTERFACE_ENTRY(i3) \ - ) - -#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - MY_QUERYINTERFACE_ENTRY(i3) \ - MY_QUERYINTERFACE_ENTRY(i4) \ - ) - -#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - MY_QUERYINTERFACE_ENTRY(i3) \ - MY_QUERYINTERFACE_ENTRY(i4) \ - MY_QUERYINTERFACE_ENTRY(i5) \ - ) - -#define MY_UNKNOWN_IMP6(i1, i2, i3, i4, i5, i6) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - MY_QUERYINTERFACE_ENTRY(i3) \ - MY_QUERYINTERFACE_ENTRY(i4) \ - MY_QUERYINTERFACE_ENTRY(i5) \ - MY_QUERYINTERFACE_ENTRY(i6) \ - ) - -#define MY_UNKNOWN_IMP7(i1, i2, i3, i4, i5, i6, i7) MY_UNKNOWN_IMP_SPEC( \ - MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \ - MY_QUERYINTERFACE_ENTRY(i1) \ - MY_QUERYINTERFACE_ENTRY(i2) \ - MY_QUERYINTERFACE_ENTRY(i3) \ - MY_QUERYINTERFACE_ENTRY(i4) \ - MY_QUERYINTERFACE_ENTRY(i5) \ - MY_QUERYINTERFACE_ENTRY(i6) \ - MY_QUERYINTERFACE_ENTRY(i7) \ - ) - -const HRESULT k_My_HRESULT_WritingWasCut = 0x20000010; - -#endif +// MyCom.h + +#ifndef ZIP7_INC_MY_COM_H +#define ZIP7_INC_MY_COM_H + +#include "MyWindows.h" +#include "MyTypes.h" + +template +class CMyComPtr +{ + T* _p; +public: + CMyComPtr(): _p(NULL) {} + CMyComPtr(T* p) throw() { if ((_p = p) != NULL) p->AddRef(); } + CMyComPtr(const CMyComPtr& lp) throw() { if ((_p = lp._p) != NULL) _p->AddRef(); } + ~CMyComPtr() { if (_p) _p->Release(); } + void Release() { if (_p) { _p->Release(); _p = NULL; } } + operator T*() const { return (T*)_p; } + T* Interface() const { return (T*)_p; } + // T& operator*() const { return *_p; } + T** operator&() { return &_p; } + T* operator->() const { return _p; } + T* operator=(T* p) + { + if (p) + p->AddRef(); + if (_p) + _p->Release(); + _p = p; + return p; + } + T* operator=(const CMyComPtr& lp) { return (*this = lp._p); } + bool operator!() const { return (_p == NULL); } + // bool operator==(T* pT) const { return _p == pT; } + void Attach(T* p2) + { + Release(); + _p = p2; + } + T* Detach() + { + T* pt = _p; + _p = NULL; + return pt; + } + #ifdef _WIN32 + HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p); + } + #endif + /* + HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) + { + CLSID clsid; + HRESULT hr = CLSIDFromProgID(szProgID, &clsid); + ATLASSERT(_p == NULL); + if (SUCCEEDED(hr)) + hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p); + return hr; + } + */ + template + HRESULT QueryInterface(REFGUID iid, Q** pp) const throw() + { + // if (*pp) throw 20220216; // for debug + return _p->QueryInterface(iid, (void**)pp); + } +}; + + +template +class CMyComPtr2 +{ + cls* _p; + + CMyComPtr2(const CMyComPtr2& lp); + CMyComPtr2(cls* p); + CMyComPtr2(iface* p); + iface* operator=(const CMyComPtr2& lp); + iface* operator=(cls* p); + iface* operator=(iface* p); +public: + CMyComPtr2(): _p(NULL) {} + ~CMyComPtr2() + { + if (_p) + { + iface *ip = _p; + ip->Release(); + } + } + // void Release() { if (_p) { (iface *)_p->Release(); _p = NULL; } } + cls* operator->() const { return _p; } + cls* ClsPtr() const { return _p; } + operator iface*() const + { + iface *ip = _p; + return ip; + } + iface* Interface() const + { + iface *ip = _p; + return ip; + } + // operator bool() const { return _p != NULL; } + bool IsDefined() const { return _p != NULL; } + void Create_if_Empty() + { + if (!_p) + { + _p = new cls; + iface *ip = _p; + ip->AddRef(); + } + } + iface* Detach() + { + iface *ip = _p; + _p = NULL; + return ip; + } + void SetFromCls(cls *src) + { + if (src) + { + iface *ip = src; + ip->AddRef(); + } + if (_p) + { + iface *ip = _p; + ip->Release(); + } + _p = src; + } +}; + + +template +class CMyComPtr2_Create +{ + cls* _p; + + CMyComPtr2_Create(const CMyComPtr2_Create& lp); + CMyComPtr2_Create(cls* p); + CMyComPtr2_Create(iface* p); + iface* operator=(const CMyComPtr2_Create& lp); + iface* operator=(cls* p); + iface* operator=(iface* p); +public: + CMyComPtr2_Create(): _p(new cls) + { + iface *ip = _p; + ip->AddRef(); + } + ~CMyComPtr2_Create() + { + iface *ip = _p; + ip->Release(); + } + cls* operator->() const { return _p; } + cls* ClsPtr() const { return _p; } + operator iface*() const + { + iface *ip = _p; + return ip; + } + iface* Interface() const + { + iface *ip = _p; + return ip; + } +}; + + +#define Z7_DECL_CMyComPtr_QI_FROM(i, v, unk) \ + CMyComPtr v; (unk)->QueryInterface(IID_ ## i, (void **)&v); + + +////////////////////////////////////////////////////////// + +inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr) +{ + *bstr = ::SysAllocString(src); + return (*bstr) ? S_OK : E_OUTOFMEMORY; +} + +class CMyComBSTR +{ + BSTR m_str; + Z7_CLASS_NO_COPY(CMyComBSTR) +public: + CMyComBSTR(): m_str(NULL) {} + ~CMyComBSTR() { ::SysFreeString(m_str); } + BSTR* operator&() { return &m_str; } + operator LPCOLESTR() const { return m_str; } + // operator bool() const { return m_str != NULL; } + // bool operator!() const { return m_str == NULL; } + + void Wipe_and_Free() + { + if (m_str) + { + memset(m_str, 0, ::SysStringLen(m_str) * sizeof(*m_str)); + Empty(); + } + } + +private: + // operator BSTR() const { return m_str; } + + CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); } + // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); } + // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); } + // CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); } + + /* + CMyComBSTR(REFGUID src) + { + LPOLESTR szGuid; + StringFromCLSID(src, &szGuid); + m_str = ::SysAllocString(szGuid); + CoTaskMemFree(szGuid); + } + */ + + /* + CMyComBSTR& operator=(const CMyComBSTR& src) + { + if (m_str != src.m_str) + { + if (m_str) + ::SysFreeString(m_str); + m_str = src.MyCopy(); + } + return *this; + } + */ + + CMyComBSTR& operator=(LPCOLESTR src) + { + ::SysFreeString(m_str); + m_str = ::SysAllocString(src); + return *this; + } + + unsigned Len() const { return ::SysStringLen(m_str); } + + BSTR MyCopy() const + { + // We don't support Byte BSTRs here + return ::SysAllocStringLen(m_str, ::SysStringLen(m_str)); + /* + UINT byteLen = ::SysStringByteLen(m_str); + BSTR res = ::SysAllocStringByteLen(NULL, byteLen); + if (res && byteLen != 0 && m_str) + memcpy(res, m_str, byteLen); + return res; + */ + } + + /* + void Attach(BSTR src) { m_str = src; } + BSTR Detach() + { + BSTR s = m_str; + m_str = NULL; + return s; + } + */ + + void Empty() + { + ::SysFreeString(m_str); + m_str = NULL; + } +}; + + +class CMyComBSTR_Wipe: public CMyComBSTR +{ + Z7_CLASS_NO_COPY(CMyComBSTR_Wipe) +public: + CMyComBSTR_Wipe(): CMyComBSTR() {} + ~CMyComBSTR_Wipe() { Wipe_and_Free(); } +}; + + + +/* + If CMyUnknownImp doesn't use virtual destructor, the code size is smaller. + But if some class_1 derived from CMyUnknownImp + uses Z7_COM_ADDREF_RELEASE and IUnknown::Release() + and some another class_2 is derived from class_1, + then class_1 must use virtual destructor: + virtual ~class_1(); + In that case, class_1::Release() calls correct destructor of class_2. + We can use virtual ~CMyUnknownImp() to disable warning + "class has virtual functions, but destructor is not virtual". + Also we can use virtual ~IUnknown() {} in MyWindows.h +*/ + +class CMyUnknownImp +{ + Z7_CLASS_NO_COPY(CMyUnknownImp) +protected: + ULONG _m_RefCount; + CMyUnknownImp(): _m_RefCount(0) {} + + #ifdef _WIN32 + #if defined(__GNUC__) || defined(__clang__) + // virtual ~CMyUnknownImp() {} // to disable GCC/CLANG varnings + #endif + #endif +}; + + + +#define Z7_COM_QI_BEGIN \ + private: STDMETHOD(QueryInterface) (REFGUID iid, void **outObject) throw() Z7_override Z7_final \ + { *outObject = NULL; + +#define Z7_COM_QI_ENTRY(i) \ + else if (iid == IID_ ## i) \ + { i *ti = this; *outObject = ti; } +// { *outObject = (void *)(i *)this; } + +#define Z7_COM_QI_ENTRY_UNKNOWN_0 \ + if (iid == IID_IUnknown) \ + { IUnknown *tu = this; *outObject = tu; } + +#define Z7_COM_QI_ENTRY_UNKNOWN(i) \ + if (iid == IID_IUnknown) \ + { i *ti = this; IUnknown *tu = ti; *outObject = tu; } +// { *outObject = (void *)(IUnknown *)(i *)this; } + +#define Z7_COM_QI_BEGIN2(i) \ + Z7_COM_QI_BEGIN \ + Z7_COM_QI_ENTRY_UNKNOWN(i) \ + Z7_COM_QI_ENTRY(i) + + +#define Z7_COM_ADDREF_RELEASE_MT \ + private: \ + STDMETHOD_(ULONG, AddRef)() Z7_override Z7_final \ + { return (ULONG)InterlockedIncrement((LONG *)&_m_RefCount); } \ + STDMETHOD_(ULONG, Release)() Z7_override Z7_final \ + { const LONG v = InterlockedDecrement((LONG *)&_m_RefCount); \ + if (v != 0) return (ULONG)v; \ + delete this; return 0; } + +#define Z7_COM_QI_END_MT \ + else return E_NOINTERFACE; \ + InterlockedIncrement((LONG *)&_m_RefCount); /* AddRef(); */ return S_OK; } + +// you can define Z7_COM_USE_ATOMIC, +// if you want to call Release() from different threads (for example, for .NET code) +// #define Z7_COM_USE_ATOMIC + +#if defined(Z7_COM_USE_ATOMIC) && !defined(Z7_ST) + +#ifndef _WIN32 +#if 0 +#include "../../C/Threads.h" +#else +EXTERN_C_BEGIN +LONG InterlockedIncrement(LONG volatile *addend); +LONG InterlockedDecrement(LONG volatile *addend); +EXTERN_C_END +#endif +#endif // _WIN32 + +#define Z7_COM_ADDREF_RELEASE Z7_COM_ADDREF_RELEASE_MT +#define Z7_COM_QI_END Z7_COM_QI_END_MT + +#else // !Z7_COM_USE_ATOMIC + +#define Z7_COM_ADDREF_RELEASE \ + private: \ + STDMETHOD_(ULONG, AddRef)() throw() Z7_override Z7_final \ + { return ++_m_RefCount; } \ + STDMETHOD_(ULONG, Release)() throw() Z7_override Z7_final \ + { if (--_m_RefCount != 0) return _m_RefCount; \ + delete this; return 0; } + +#define Z7_COM_QI_END \ + else return E_NOINTERFACE; \ + ++_m_RefCount; /* AddRef(); */ return S_OK; } + +#endif // !Z7_COM_USE_ATOMIC + + +#define Z7_COM_UNKNOWN_IMP_SPEC(i) \ + Z7_COM_QI_BEGIN \ + i \ + Z7_COM_QI_END \ + Z7_COM_ADDREF_RELEASE + + +#define Z7_COM_UNKNOWN_IMP_0 \ + Z7_COM_QI_BEGIN \ + Z7_COM_QI_ENTRY_UNKNOWN_0 \ + Z7_COM_QI_END \ + Z7_COM_ADDREF_RELEASE + +#define Z7_COM_UNKNOWN_IMP_1(i) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i) \ + Z7_COM_QI_ENTRY(i) \ + ) + +#define Z7_COM_UNKNOWN_IMP_2(i1, i2) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + ) + +#define Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + ) + +#define Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + ) + +#define Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + ) + +#define Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_ENTRY(i6) \ + ) + +#define Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_ENTRY(i6) \ + Z7_COM_QI_ENTRY(i7) \ + ) + +#define Z7_COM_UNKNOWN_IMP_8(i1, i2, i3, i4, i5, i6, i7, i8) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_ENTRY(i6) \ + Z7_COM_QI_ENTRY(i7) \ + Z7_COM_QI_ENTRY(i8) \ + ) + + +#define Z7_IFACES_IMP_UNK_1(i1) \ + Z7_COM_UNKNOWN_IMP_1(i1) \ + Z7_IFACE_COM7_IMP(i1) \ + +#define Z7_IFACES_IMP_UNK_2(i1, i2) \ + Z7_COM_UNKNOWN_IMP_2(i1, i2) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + +#define Z7_IFACES_IMP_UNK_3(i1, i2, i3) \ + Z7_COM_UNKNOWN_IMP_3(i1, i2, i3) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + +#define Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \ + Z7_COM_UNKNOWN_IMP_4(i1, i2, i3, i4) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + +#define Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \ + Z7_COM_UNKNOWN_IMP_5(i1, i2, i3, i4, i5) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + +#define Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \ + Z7_COM_UNKNOWN_IMP_6(i1, i2, i3, i4, i5, i6) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + Z7_IFACE_COM7_IMP(i6) \ + +#define Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + Z7_IFACE_COM7_IMP(i6) \ + Z7_IFACE_COM7_IMP(i7) \ + + +#define Z7_CLASS_IMP_COM_0(c) \ + Z7_class_final(c) : \ + public IUnknown, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + private: + +#define Z7_CLASS_IMP_COM_1(c, i1) \ + Z7_class_final(c) : \ + public i1, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_1(i1) \ + private: + +#define Z7_CLASS_IMP_COM_2(c, i1, i2) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_2(i1, i2) \ + private: + +#define Z7_CLASS_IMP_COM_3(c, i1, i2, i3) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_3(i1, i2, i3) \ + private: + +#define Z7_CLASS_IMP_COM_4(c, i1, i2, i3, i4) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_4(i1, i2, i3, i4) \ + private: + +#define Z7_CLASS_IMP_COM_5(c, i1, i2, i3, i4, i5) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_5(i1, i2, i3, i4, i5) \ + private: + +#define Z7_CLASS_IMP_COM_6(c, i1, i2, i3, i4, i5, i6) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public i6, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_6(i1, i2, i3, i4, i5, i6) \ + private: + + +#define Z7_CLASS_IMP_COM_7(c, i1, i2, i3, i4, i5, i6, i7) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public i6, \ + public i7, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \ + private: + + +/* +#define Z7_CLASS_IMP_NOQIB_0(c) \ + Z7_class_final(c) : \ + public IUnknown, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + private: +*/ + +#define Z7_CLASS_IMP_NOQIB_1(c, i1) \ + Z7_class_final(c) : \ + public i1, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_0 \ + Z7_IFACE_COM7_IMP(i1) \ + private: + +#define Z7_CLASS_IMP_NOQIB_2(c, i1, i2) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_1(i2) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + private: + +#define Z7_CLASS_IMP_NOQIB_3(c, i1, i2, i3) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_2(i2, i3) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + private: + +#define Z7_CLASS_IMP_NOQIB_4(c, i1, i2, i3, i4) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_3(i2, i3, i4) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + +/* +#define Z7_CLASS_IMP_NOQIB_5(c, i1, i2, i3, i4, i5) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public CMyUnknownImp { \ + Z7_COM_UNKNOWN_IMP_4(i2, i3, i4, i5) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ +*/ + + +#define Z7_CLASS_IMP_IInStream(c) \ + class c Z7_final : \ + public IInStream, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_2(ISequentialInStream, IInStream) \ + + +#define k_My_HRESULT_WritingWasCut 0x20000010 + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyException.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyException.h --- p7zip-rar-16.02/CPP/Common/MyException.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyException.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// Common/Exception.h - -#ifndef __COMMON_EXCEPTION_H -#define __COMMON_EXCEPTION_H - -#include "MyWindows.h" - -struct CSystemException -{ - HRESULT ErrorCode; - CSystemException(HRESULT errorCode): ErrorCode(errorCode) {} -}; - -#endif +// Common/Exception.h + +#ifndef ZIP7_INC_COMMON_EXCEPTION_H +#define ZIP7_INC_COMMON_EXCEPTION_H + +#include "MyWindows.h" + +struct CSystemException +{ + HRESULT ErrorCode; + CSystemException(HRESULT errorCode): ErrorCode(errorCode) {} +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyGuidDef.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyGuidDef.h --- p7zip-rar-16.02/CPP/Common/MyGuidDef.h 2014-12-21 14:26:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyGuidDef.h 2023-09-06 17:00:00.000000000 +0000 @@ -1,54 +1,63 @@ -// Common/MyGuidDef.h - -#ifndef GUID_DEFINED -#define GUID_DEFINED - -#include "MyTypes.h" - -typedef struct { - UInt32 Data1; - UInt16 Data2; - UInt16 Data3; - unsigned char Data4[8]; -} GUID; - -#ifdef __cplusplus -#define REFGUID const GUID & -#else -#define REFGUID const GUID * -#endif - -#define REFCLSID REFGUID -#define REFIID REFGUID - -#ifdef __cplusplus -inline int operator==(REFGUID g1, REFGUID g2) -{ - for (int i = 0; i < (int)sizeof(g1); i++) - if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i]) - return 0; - return 1; -} -inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } -#endif - -#ifdef __cplusplus - #define MY_EXTERN_C extern "C" -#else - #define MY_EXTERN_C extern -#endif - -#endif - - -#ifdef DEFINE_GUID -#undef DEFINE_GUID -#endif - -#ifdef INITGUID - #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else - #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - MY_EXTERN_C const GUID name -#endif +// Common/MyGuidDef.h + +// #pragma message "Common/MyGuidDef.h" + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +// #pragma message "GUID_DEFINED" + +#include "MyTypes.h" + +typedef struct { + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + Byte Data4[8]; +} GUID; + +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * +#endif + +// typedef GUID IID; +typedef GUID CLSID; + +#define REFCLSID REFGUID +#define REFIID REFGUID + +#ifdef __cplusplus +inline int operator==(REFGUID g1, REFGUID g2) +{ + for (unsigned i = 0; i < sizeof(g1); i++) + if (((const Byte *)&g1)[i] != ((const Byte *)&g2)[i]) + return 0; + return 1; +} +inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); } +#endif + +#endif // GUID_DEFINED + +#ifndef EXTERN_C +#ifdef __cplusplus + #define EXTERN_C extern "C" +#else + #define EXTERN_C extern +#endif +#endif + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name; \ + EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyInitGuid.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyInitGuid.h --- p7zip-rar-16.02/CPP/Common/MyInitGuid.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyInitGuid.h 2023-03-24 09:00:00.000000000 +0000 @@ -1,45 +1,57 @@ -// Common/MyInitGuid.h - -#ifndef __COMMON_MY_INITGUID_H -#define __COMMON_MY_INITGUID_H - -/* -This file must be included only to one C++ file in project before -declarations of COM interfaces with DEFINE_GUID macro. - -Each GUID must be initialized exactly once in project. -There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h): - - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name. - - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID. - -Also we need IID_IUnknown that is initialized in some file for linking: - MSVC: by default the linker uses some lib file that contains IID_IUnknown - MinGW: add -luuid switch for linker - WinCE: we define IID_IUnknown in this file - Other: we define IID_IUnknown in this file -*/ - -#ifdef _WIN32 - -#ifdef UNDER_CE -#include -#endif - -#include - -#ifdef UNDER_CE -DEFINE_GUID(IID_IUnknown, -0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); -#endif - -#else - -#define INITGUID -#include "MyGuidDef.h" -DEFINE_GUID(IID_IUnknown, -0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); - -#endif - - -#endif +// Common/MyInitGuid.h + +#ifndef ZIP7_INC_COMMON_MY_INITGUID_H +#define ZIP7_INC_COMMON_MY_INITGUID_H + +/* +This file must be included only to one C++ file in project before +declarations of COM interfaces with DEFINE_GUID macro. + +Each GUID must be initialized exactly once in project. +There are two different versions of the DEFINE_GUID macro in guiddef.h (MyGuidDef.h): + - if INITGUID is not defined: DEFINE_GUID declares an external reference to the symbol name. + - if INITGUID is defined: DEFINE_GUID initializes the symbol name to the value of the GUID. + +Also we need IID_IUnknown that is initialized in some file for linking: + MSVC: by default the linker uses some lib file that contains IID_IUnknown + MinGW: add -luuid switch for linker + WinCE: we define IID_IUnknown in this file + Other: we define IID_IUnknown in this file +*/ + +// #include "Common.h" +/* vc6 without sdk needs before , + but it doesn't work in new msvc. + So we include full "MyWindows.h" instead of */ +// #include +#include "MyWindows.h" + +#ifdef _WIN32 + +#ifdef __clang__ + // #pragma GCC diagnostic ignored "-Wmissing-variable-declarations" +#endif + +#ifdef UNDER_CE +#include +#endif + +// for vc6 without sdk we must define INITGUID here +#define INITGUID +#include + +#ifdef UNDER_CE +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +#endif + +#else // _WIN32 + +#define INITGUID +#include "MyGuidDef.h" +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + +#endif // _WIN32 + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyLinux.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyLinux.h --- p7zip-rar-16.02/CPP/Common/MyLinux.h 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyLinux.h 2023-03-15 16:00:00.000000000 +0000 @@ -1,42 +1,75 @@ -// MyLinux.h - -#ifndef __MY_LIN_LINUX_H -#define __MY_LIN_LINUX_H - -#define MY_LIN_S_IFMT 00170000 -#define MY_LIN_S_IFSOCK 0140000 -#define MY_LIN_S_IFLNK 0120000 -#define MY_LIN_S_IFREG 0100000 -#define MY_LIN_S_IFBLK 0060000 -#define MY_LIN_S_IFDIR 0040000 -#define MY_LIN_S_IFCHR 0020000 -#define MY_LIN_S_IFIFO 0010000 - -#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK) -#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG) -#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR) -#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR) -#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK) -#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO) -#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK) - -#define MY_LIN_S_ISUID 0004000 -#define MY_LIN_S_ISGID 0002000 -#define MY_LIN_S_ISVTX 0001000 - -#define MY_LIN_S_IRWXU 00700 -#define MY_LIN_S_IRUSR 00400 -#define MY_LIN_S_IWUSR 00200 -#define MY_LIN_S_IXUSR 00100 - -#define MY_LIN_S_IRWXG 00070 -#define MY_LIN_S_IRGRP 00040 -#define MY_LIN_S_IWGRP 00020 -#define MY_LIN_S_IXGRP 00010 - -#define MY_LIN_S_IRWXO 00007 -#define MY_LIN_S_IROTH 00004 -#define MY_LIN_S_IWOTH 00002 -#define MY_LIN_S_IXOTH 00001 - -#endif +// MyLinux.h + +#ifndef ZIP7_INC_COMMON_MY_LINUX_H +#define ZIP7_INC_COMMON_MY_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 +#define MY_LIN_S_IFREG 0100000 +#define MY_LIN_S_IFBLK 0060000 +#define MY_LIN_S_IFDIR 0040000 +#define MY_LIN_S_IFCHR 0020000 +#define MY_LIN_S_IFIFO 0010000 + +#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK) +#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG) +#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR) +#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR) +#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK) +#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO) +#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK) + +#define MY_LIN_S_ISUID 0004000 +#define MY_LIN_S_ISGID 0002000 +#define MY_LIN_S_ISVTX 0001000 + +#define MY_LIN_S_IRWXU 00700 +#define MY_LIN_S_IRUSR 00400 +#define MY_LIN_S_IWUSR 00200 +#define MY_LIN_S_IXUSR 00100 + +#define MY_LIN_S_IRWXG 00070 +#define MY_LIN_S_IRGRP 00040 +#define MY_LIN_S_IWGRP 00020 +#define MY_LIN_S_IXGRP 00010 + +#define MY_LIN_S_IRWXO 00007 +#define MY_LIN_S_IROTH 00004 +#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 -Nru p7zip-rar-16.02/CPP/Common/MyMap.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.cpp --- p7zip-rar-16.02/CPP/Common/MyMap.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.cpp 2023-09-06 20:00:00.000000000 +0000 @@ -1,140 +1,140 @@ -// MyMap.cpp - -#include "StdAfx.h" - -#include "MyMap.h" - -static const unsigned kNumBitsMax = sizeof(UInt32) * 8; - -static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) throw() -{ - if (startPos == sizeof(value) * 8) - return 0; - value >>= startPos; - if (numBits == sizeof(value) * 8) - return value; - return value & (((UInt32)1 << numBits) - 1); -} - -static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; } - -bool CMap32::Find(UInt32 key, UInt32 &valueRes) const throw() -{ - valueRes = (UInt32)(Int32)-1; - if (Nodes.Size() == 0) - return false; - if (Nodes.Size() == 1) - { - const CNode &n = Nodes[0]; - if (n.Len == kNumBitsMax) - { - valueRes = n.Values[0]; - return (key == n.Key); - } - } - - unsigned cur = 0; - unsigned bitPos = kNumBitsMax; - for (;;) - { - const CNode &n = Nodes[cur]; - bitPos -= n.Len; - if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) - return false; - unsigned bit = GetSubBit(key, --bitPos); - if (n.IsLeaf[bit]) - { - valueRes = n.Values[bit]; - return (key == n.Keys[bit]); - } - cur = (unsigned)n.Keys[bit]; - } -} - -bool CMap32::Set(UInt32 key, UInt32 value) -{ - if (Nodes.Size() == 0) - { - CNode n; - n.Key = n.Keys[0] = n.Keys[1] = key; - n.Values[0] = n.Values[1] = value; - n.IsLeaf[0] = n.IsLeaf[1] = 1; - n.Len = kNumBitsMax; - Nodes.Add(n); - return false; - } - if (Nodes.Size() == 1) - { - CNode &n = Nodes[0]; - if (n.Len == kNumBitsMax) - { - if (key == n.Key) - { - n.Values[0] = n.Values[1] = value; - return true; - } - unsigned i = kNumBitsMax - 1; - for (; GetSubBit(key, i) == GetSubBit(n.Key, i); i--); - n.Len = (UInt16)(kNumBitsMax - (1 + i)); - unsigned newBit = GetSubBit(key, i); - n.Values[newBit] = value; - n.Keys[newBit] = key; - return false; - } - } - - unsigned cur = 0; - unsigned bitPos = kNumBitsMax; - for (;;) - { - CNode &n = Nodes[cur]; - bitPos -= n.Len; - if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) - { - unsigned i = n.Len - 1; - for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--); - - CNode e2(n); - e2.Len = (UInt16)i; - - n.Len = (UInt16)(n.Len - (1 + i)); - unsigned newBit = GetSubBit(key, bitPos + i); - n.Values[newBit] = value; - n.IsLeaf[newBit] = 1; - n.IsLeaf[1 - newBit] = 0; - n.Keys[newBit] = key; - n.Keys[1 - newBit] = Nodes.Size(); - Nodes.Add(e2); - return false; - } - unsigned bit = GetSubBit(key, --bitPos); - - if (n.IsLeaf[bit]) - { - if (key == n.Keys[bit]) - { - n.Values[bit] = value; - return true; - } - unsigned i = bitPos - 1; - for (; GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--); - - CNode e2; - - unsigned newBit = GetSubBit(key, i); - e2.Values[newBit] = value; - e2.Values[1 - newBit] = n.Values[bit]; - e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1; - e2.Keys[newBit] = key; - e2.Keys[1 - newBit] = e2.Key = n.Keys[bit]; - e2.Len = (UInt16)(bitPos - (1 + i)); - - n.IsLeaf[bit] = 0; - n.Keys[bit] = Nodes.Size(); - - Nodes.Add(e2); - return false; - } - cur = (unsigned)n.Keys[bit]; - } -} +// MyMap.cpp + +#include "StdAfx.h" + +#include "MyMap.h" + +static const unsigned kNumBitsMax = sizeof(UInt32) * 8; + +static UInt32 GetSubBits(UInt32 value, unsigned startPos, unsigned numBits) throw() +{ + if (startPos == sizeof(value) * 8) + return 0; + value >>= startPos; + if (numBits == sizeof(value) * 8) + return value; + return value & (((UInt32)1 << numBits) - 1); +} + +static inline unsigned GetSubBit(UInt32 v, unsigned n) { return (unsigned)(v >> n) & 1; } + +bool CMap32::Find(UInt32 key, UInt32 &valueRes) const throw() +{ + valueRes = (UInt32)(Int32)-1; + if (Nodes.Size() == 0) + return false; + if (Nodes.Size() == 1) + { + const CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + valueRes = n.Values[0]; + return (key == n.Key); + } + } + + unsigned cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + const CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + return false; + unsigned bit = GetSubBit(key, --bitPos); + if (n.IsLeaf[bit]) + { + valueRes = n.Values[bit]; + return (key == n.Keys[bit]); + } + cur = (unsigned)n.Keys[bit]; + } +} + +bool CMap32::Set(UInt32 key, UInt32 value) +{ + if (Nodes.Size() == 0) + { + CNode n; + n.Key = n.Keys[0] = n.Keys[1] = key; + n.Values[0] = n.Values[1] = value; + n.IsLeaf[0] = n.IsLeaf[1] = 1; + n.Len = kNumBitsMax; + Nodes.Add(n); + return false; + } + if (Nodes.Size() == 1) + { + CNode &n = Nodes[0]; + if (n.Len == kNumBitsMax) + { + if (key == n.Key) + { + n.Values[0] = n.Values[1] = value; + return true; + } + unsigned i = kNumBitsMax - 1; + for (; GetSubBit(key, i) == GetSubBit(n.Key, i); i--); + n.Len = (UInt16)(kNumBitsMax - (1 + i)); + const unsigned newBit = GetSubBit(key, i); + n.Values[newBit] = value; + n.Keys[newBit] = key; + return false; + } + } + + unsigned cur = 0; + unsigned bitPos = kNumBitsMax; + for (;;) + { + CNode &n = Nodes[cur]; + bitPos -= n.Len; + if (GetSubBits(key, bitPos, n.Len) != GetSubBits(n.Key, bitPos, n.Len)) + { + unsigned i = (unsigned)n.Len - 1; + for (; GetSubBit(key, bitPos + i) == GetSubBit(n.Key, bitPos + i); i--); + + CNode e2(n); + e2.Len = (UInt16)i; + + n.Len = (UInt16)(n.Len - (1 + i)); + unsigned newBit = GetSubBit(key, bitPos + i); + n.Values[newBit] = value; + n.IsLeaf[newBit] = 1; + n.IsLeaf[1 - newBit] = 0; + n.Keys[newBit] = key; + n.Keys[1 - newBit] = (UInt32)Nodes.Size(); + Nodes.Add(e2); + return false; + } + const unsigned bit = GetSubBit(key, --bitPos); + + if (n.IsLeaf[bit]) + { + if (key == n.Keys[bit]) + { + n.Values[bit] = value; + return true; + } + unsigned i = bitPos - 1; + for (; GetSubBit(key, i) == GetSubBit(n.Keys[bit], i); i--); + + CNode e2; + + const unsigned newBit = GetSubBit(key, i); + e2.Values[newBit] = value; + e2.Values[1 - newBit] = n.Values[bit]; + e2.IsLeaf[newBit] = e2.IsLeaf[1 - newBit] = 1; + e2.Keys[newBit] = key; + e2.Keys[1 - newBit] = e2.Key = n.Keys[bit]; + e2.Len = (UInt16)(bitPos - (1 + i)); + + n.IsLeaf[bit] = 0; + n.Keys[bit] = (UInt32)Nodes.Size(); + + Nodes.Add(e2); + return false; + } + cur = (unsigned)n.Keys[bit]; + } +} diff -Nru p7zip-rar-16.02/CPP/Common/MyMap.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.h --- p7zip-rar-16.02/CPP/Common/MyMap.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyMap.h 2023-03-15 16:00:00.000000000 +0000 @@ -1,28 +1,28 @@ -// MyMap.h - -#ifndef __COMMON_MYMAP_H -#define __COMMON_MYMAP_H - -#include "MyTypes.h" -#include "MyVector.h" - -class CMap32 -{ - struct CNode - { - UInt32 Key; - UInt32 Keys[2]; - UInt32 Values[2]; - UInt16 Len; - Byte IsLeaf[2]; - }; - CRecordVector Nodes; - -public: - - void Clear() { Nodes.Clear(); } - bool Find(UInt32 key, UInt32 &valueRes) const throw(); - bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already -}; - -#endif +// MyMap.h + +#ifndef ZIP7_INC_COMMON_MY_MAP_H +#define ZIP7_INC_COMMON_MY_MAP_H + +#include "MyTypes.h" +#include "MyVector.h" + +class CMap32 +{ + struct CNode + { + UInt32 Key; + UInt32 Keys[2]; + UInt32 Values[2]; + UInt16 Len; + Byte IsLeaf[2]; + }; + CRecordVector Nodes; + +public: + + void Clear() { Nodes.Clear(); } + bool Find(UInt32 key, UInt32 &valueRes) const throw(); + bool Set(UInt32 key, UInt32 value); // returns true, if there is such key already +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyString.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.cpp --- p7zip-rar-16.02/CPP/Common/MyString.cpp 2016-02-17 19:01:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.cpp 2025-06-15 08:00:00.000000000 +0000 @@ -1,1732 +1,1842 @@ -// Common/MyString.cpp - -#include "StdAfx.h" - -#ifdef _WIN32 -#include -#else -#include -#endif - -#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING) -#include "StringConvert.h" -#endif - -#include "MyString.h" - -#define MY_STRING_NEW(_T_, _size_) new _T_[_size_] -// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_))) - -/* -inline const char* MyStringGetNextCharPointer(const char *p) throw() -{ - #if defined(_WIN32) && !defined(UNDER_CE) - return CharNextA(p); - #else - return p + 1; - #endif -} -*/ - -int FindCharPosInString(const char *s, char c) throw() -{ - for (const char *p = s;; p++) - { - if (*p == c) - return (int)(p - s); - if (*p == 0) - return -1; - // MyStringGetNextCharPointer(p); - } -} - -int FindCharPosInString(const wchar_t *s, wchar_t c) throw() -{ - for (const wchar_t *p = s;; p++) - { - if (*p == c) - return (int)(p - s); - if (*p == 0) - return -1; - } -} - -/* -void MyStringUpper_Ascii(wchar_t *s) -{ - for (;;) - { - wchar_t c = *s; - if (c == 0) - return; - *s++ = MyCharUpper_Ascii(c); - } -} -*/ - -void MyStringLower_Ascii(char *s) throw() -{ - for (;;) - { - char c = *s; - if (c == 0) - return; - *s++ = MyCharLower_Ascii(c); - } -} - -void MyStringLower_Ascii(wchar_t *s) throw() -{ - for (;;) - { - wchar_t c = *s; - if (c == 0) - return; - *s++ = MyCharLower_Ascii(c); - } -} - -#ifdef _WIN32 - -#ifdef _UNICODE - -// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } -// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } -// for WinCE - FString - char -// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; } - -#else - -// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); } -// char * MyStringUpper(char *s) { return CharUpperA(s); } -// char * MyStringLower(char *s) { return CharLowerA(s); } - -wchar_t MyCharUpper_WIN(wchar_t c) throw() -{ - wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)(unsigned)(UINT_PTR)res; - const int kBufSize = 4; - char s[kBufSize + 1]; - int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); - if (numChars == 0 || numChars > kBufSize) - return c; - s[numChars] = 0; - ::CharUpperA(s); - ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); - return c; -} - -/* -wchar_t MyCharLower_WIN(wchar_t c) -{ - wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return (wchar_t)(unsigned)(UINT_PTR)res; - const int kBufSize = 4; - char s[kBufSize + 1]; - int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); - if (numChars == 0 || numChars > kBufSize) - return c; - s[numChars] = 0; - ::CharLowerA(s); - ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); - return c; -} -*/ - -/* -wchar_t * MyStringUpper(wchar_t *s) -{ - if (s == 0) - return 0; - wchar_t *res = CharUpperW(s); - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return res; - AString a = UnicodeStringToMultiByte(s); - a.MakeUpper(); - MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); - return s; -} -*/ - -/* -wchar_t * MyStringLower(wchar_t *s) -{ - if (s == 0) - return 0; - wchar_t *res = CharLowerW(s); - if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) - return res; - AString a = UnicodeStringToMultiByte(s); - a.MakeLower(); - MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); - return s; -} -*/ - -#endif - -#endif - -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; - } -} - -bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() -{ - for (;;) - { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; - if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; - if (c1 == 0) return true; - } -} - -// ---------- ASCII ---------- - -bool AString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() -{ - const char *s1 = _chars; - for (;;) - { - char c2 = *s++; - if (c2 == 0) - return true; - char c1 = *s1++; - if (MyCharLower_Ascii(c1) != - MyCharLower_Ascii(c2)) - return false; - } -} - -bool UString::IsPrefixedBy_Ascii_NoCase(const char *s) const throw() -{ - const wchar_t *s1 = _chars; - for (;;) - { - char c2 = *s++; - if (c2 == 0) - return true; - wchar_t c1 = *s1++; - if (MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2)) - return false; - } -} - -bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() -{ - for (;;) - { - unsigned char c = *a; - if (c != *u) - return false; - if (c == 0) - return true; - a++; - u++; - } -} - -bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() -{ - for (;;) - { - char c1 = *s1++; - char c2 = *s2++; - if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) - return false; - if (c1 == 0) - return true; - } -} - -bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() -{ - for (;;) - { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; - if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) - return false; - if (c1 == 0) - return true; - } -} - -bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() -{ - for (;;) - { - wchar_t c1 = *s1++; - char c2 = *s2++; - if (c1 != (unsigned char)c2 && (c1 > 0x7F || MyCharLower_Ascii(c1) != (unsigned char)MyCharLower_Ascii(c2))) - return false; - if (c1 == 0) - return true; - } -} - -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; - } -} - -bool IsString1PrefixedByString2_NoCase(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 && MyCharUpper(c1) != MyCharUpper(c2)) - return false; - } -} - -// NTFS order: uses upper case -int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() -{ - for (;;) - { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; - if (c1 != c2) - { - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); - if (u1 < u2) return -1; - if (u1 > u2) return 1; - } - if (c1 == 0) return 0; - } -} - -/* -int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) -{ - for (; num != 0; num--) - { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; - if (c1 != c2) - { - wchar_t u1 = MyCharUpper(c1); - wchar_t u2 = MyCharUpper(c2); - if (u1 < u2) return -1; - if (u1 > u2) return 1; - } - if (c1 == 0) return 0; - } - return 0; -} -*/ - -// ---------- AString ---------- - -void AString::InsertSpace(unsigned &index, unsigned size) -{ - Grow(size); - MoveItems(index + size, index); -} - -#define k_Alloc_Len_Limit 0x40000000 - -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_DELETE(_chars); - _chars = newBuf; - _limit = 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); - newBuf[0] = 0; - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = newLimit; -} - -void AString::SetStartLen(unsigned len) -{ - _chars = 0; - _chars = MY_STRING_NEW(char, len + 1); - _len = len; - _limit = len; -} - -void AString::Grow_1() -{ - unsigned next = _len; - next += next / 2; - next += 16; - next &= ~(unsigned)15; - ReAlloc(next - 1); -} - -void AString::Grow(unsigned n) -{ - unsigned freeSize = _limit - _len; - if (n <= freeSize) - return; - - unsigned next = _len + n; - next += next / 2; - next += 16; - next &= ~(unsigned)15; - ReAlloc(next - 1); -} - -/* -AString::AString(unsigned num, const char *s) -{ - unsigned len = MyStringLen(s); - if (num > len) - num = len; - SetStartLen(num); - memcpy(_chars, s, num); - _chars[num] = 0; -} -*/ - -AString::AString(unsigned num, const AString &s) -{ - if (num > s._len) - num = s._len; - SetStartLen(num); - memcpy(_chars, s._chars, num); - _chars[num] = 0; -} - -AString::AString(const AString &s, char c) -{ - SetStartLen(s.Len() + 1); - char *chars = _chars; - unsigned len = s.Len(); - memcpy(chars, s, len); - chars[len] = c; - chars[len + 1] = 0; -} - -AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) -{ - SetStartLen(num1 + num2); - char *chars = _chars; - memcpy(chars, s1, num1); - memcpy(chars + num1, s2, num2 + 1); -} - -AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); } -AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); } -AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); } - -AString::AString() -{ - _chars = 0; - _chars = MY_STRING_NEW(char, 4); - _len = 0; - _limit = 4 - 1; - _chars[0] = 0; -} - -AString::AString(char c) -{ - SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; -} - -AString::AString(const char *s) -{ - SetStartLen(MyStringLen(s)); - MyStringCopy(_chars, s); -} - -AString::AString(const AString &s) -{ - SetStartLen(s._len); - MyStringCopy(_chars, s._chars); -} - -AString &AString::operator=(char c) -{ - if (1 > _limit) - { - char *newBuf = MY_STRING_NEW(char, 1 + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = 1; - } - _len = 1; - _chars[0] = c; - _chars[1] = 0; - return *this; -} - -AString &AString::operator=(const char *s) -{ - unsigned len = MyStringLen(s); - if (len > _limit) - { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - MyStringCopy(_chars, s); - return *this; -} - -AString &AString::operator=(const AString &s) -{ - if (&s == this) - return *this; - unsigned len = s._len; - if (len > _limit) - { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - MyStringCopy(_chars, s._chars); - return *this; -} - -void AString::SetFromWStr_if_Ascii(const wchar_t *s) -{ - unsigned len = 0; - { - for (;; len++) - { - wchar_t c = s[len]; - if (c == 0) - break; - if (c >= 0x80) - return; - } - } - if (len > _limit) - { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - char *dest = _chars; - unsigned i; - for (i = 0; i < len; i++) - dest[i] = (char)s[i]; - dest[i] = 0; -} - -/* -void AString::SetFromBstr_if_Ascii(BSTR s) -{ - unsigned len = ::SysStringLen(s); - { - for (unsigned i = 0; i < len; i++) - if (s[i] <= 0 || s[i] >= 0x80) - return; - } - if (len > _limit) - { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - char *dest = _chars; - unsigned i; - for (i = 0; i < len; i++) - dest[i] = (char)s[i]; - dest[i] = 0; -} -*/ - -void AString::Add_Space() { operator+=(' '); } -void AString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } -void AString::Add_LF() { operator+=('\n'); } - -AString &AString::operator+=(const char *s) -{ - unsigned len = MyStringLen(s); - Grow(len); - MyStringCopy(_chars + _len, s); - _len += len; - return *this; -} - -AString &AString::operator+=(const AString &s) -{ - Grow(s._len); - MyStringCopy(_chars + _len, s._chars); - _len += s._len; - return *this; -} - -void AString::SetFrom(const char *s, unsigned len) // no check -{ - if (len > _limit) - { - char *newBuf = MY_STRING_NEW(char, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - if (len != 0) - memcpy(_chars, s, len); - _chars[len] = 0; - _len = len; -} - -void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check -{ - unsigned i; - for (i = 0; i < len; i++) - if (s[i] == 0) - break; - SetFrom(s, i); -} - -int AString::Find(const char *s, unsigned startIndex) const throw() -{ - const char *fs = strstr(_chars + startIndex, s); - if (!fs) - return -1; - return (int)(fs - _chars); - - /* - if (s[0] == 0) - return startIndex; - unsigned len = MyStringLen(s); - const char *p = _chars + startIndex; - for (;; p++) - { - const char c = *p; - if (c != s[0]) - { - if (c == 0) - return -1; - continue; - } - unsigned i; - for (i = 1; i < len; i++) - if (p[i] != s[i]) - break; - if (i == len) - return (int)(p - _chars); - } - */ -} - -int AString::ReverseFind(char c) const throw() -{ - if (_len == 0) - return -1; - const char *p = _chars + _len - 1; - for (;;) - { - if (*p == c) - return (int)(p - _chars); - if (p == _chars) - return -1; - p--; // p = GetPrevCharPointer(_chars, p); - } -} - -int AString::ReverseFind_PathSepar() const throw() -{ - if (_len == 0) - return -1; - const char *p = _chars + _len - 1; - for (;;) - { - char c = *p; - if (IS_PATH_SEPAR(c)) - return (int)(p - _chars); - if (p == _chars) - return -1; - p--; - } -} - -void AString::TrimLeft() throw() -{ - const char *p = _chars; - for (;; p++) - { - char c = *p; - if (c != ' ' && c != '\n' && c != '\t') - break; - } - unsigned pos = (unsigned)(p - _chars); - if (pos != 0) - { - MoveItems(0, pos); - _len -= pos; - } -} - -void AString::TrimRight() throw() -{ - const char *p = _chars; - unsigned i; - for (i = _len; i != 0; i--) - { - char c = p[i - 1]; - if (c != ' ' && c != '\n' && c != '\t') - break; - } - if (i != _len) - { - _chars[i] = 0; - _len = i; - } -} - -void AString::InsertAtFront(char c) -{ - if (_limit == _len) - Grow_1(); - MoveItems(1, 0); - _chars[0] = c; - _len++; -} - -/* -void AString::Insert(unsigned index, char c) -{ - InsertSpace(index, 1); - _chars[index] = c; - _len++; -} -*/ - -void AString::Insert(unsigned index, const char *s) -{ - unsigned num = MyStringLen(s); - if (num != 0) - { - InsertSpace(index, num); - memcpy(_chars + index, s, num); - _len += num; - } -} - -void AString::Insert(unsigned index, const AString &s) -{ - unsigned num = s.Len(); - if (num != 0) - { - InsertSpace(index, num); - memcpy(_chars + index, s, num); - _len += num; - } -} - -void AString::RemoveChar(char ch) throw() -{ - char *src = _chars; - - for (;;) - { - char c = *src++; - if (c == 0) - return; - if (c == ch) - break; - } - - char *dest = src - 1; - - for (;;) - { - char c = *src++; - if (c == 0) - break; - if (c != ch) - *dest++ = c; - } - - *dest = 0; - _len = (unsigned)(dest - _chars); -} - -// !!!!!!!!!!!!!!! test it if newChar = '\0' -void AString::Replace(char oldChar, char newChar) throw() -{ - if (oldChar == newChar) - return; // 0; - // unsigned number = 0; - int pos = 0; - while ((unsigned)pos < _len) - { - pos = Find(oldChar, pos); - if (pos < 0) - break; - _chars[(unsigned)pos] = newChar; - pos++; - // number++; - } - return; // number; -} - -void AString::Replace(const AString &oldString, const AString &newString) -{ - if (oldString.IsEmpty()) - return; // 0; - if (oldString == newString) - return; // 0; - unsigned oldLen = oldString.Len(); - unsigned newLen = newString.Len(); - // unsigned number = 0; - int pos = 0; - while ((unsigned)pos < _len) - { - pos = Find(oldString, pos); - if (pos < 0) - break; - Delete(pos, oldLen); - Insert(pos, newString); - pos += newLen; - // number++; - } - // return number; -} - -void AString::Delete(unsigned index) throw() -{ - MoveItems(index, index + 1); - _len--; -} - -void AString::Delete(unsigned index, unsigned count) throw() -{ - if (index + count > _len) - count = _len - index; - if (count > 0) - { - MoveItems(index, index + count); - _len -= count; - } -} - -void AString::DeleteFrontal(unsigned num) throw() -{ - if (num != 0) - { - MoveItems(0, num); - _len -= num; - } -} - -/* -AString operator+(const AString &s1, const AString &s2) -{ - AString result(s1); - result += s2; - return result; -} - -AString operator+(const AString &s, const char *chars) -{ - AString result(s); - result += chars; - return result; -} - -AString operator+(const char *chars, const AString &s) -{ - AString result(chars); - result += s; - return result; -} - -AString operator+(const AString &s, char c) -{ - AString result(s); - result += c; - return result; -} -*/ - -/* -AString operator+(char c, const AString &s) -{ - AString result(c); - result += s; - return result; -} -*/ - - - - -// ---------- UString ---------- - -void UString::InsertSpace(unsigned index, unsigned size) -{ - Grow(size); - MoveItems(index + size, index); -} - -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); - wmemcpy(newBuf, _chars, _len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = newLimit; -} - -void UString::ReAlloc2(unsigned newLimit) -{ - 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); - newBuf[0] = 0; - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = newLimit; -} - -void UString::SetStartLen(unsigned len) -{ - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, len + 1); - _len = len; - _limit = len; -} - -void UString::Grow_1() -{ - unsigned next = _len; - next += next / 2; - next += 16; - next &= ~(unsigned)15; - ReAlloc(next - 1); -} - -void UString::Grow(unsigned n) -{ - unsigned freeSize = _limit - _len; - if (n <= freeSize) - return; - - unsigned next = _len + n; - next += next / 2; - next += 16; - next &= ~(unsigned)15; - ReAlloc(next - 1); -} - - -UString::UString(unsigned num, const wchar_t *s) -{ - unsigned len = MyStringLen(s); - if (num > len) - num = len; - SetStartLen(num); - wmemcpy(_chars, s, num); - _chars[num] = 0; -} - - -UString::UString(unsigned num, const UString &s) -{ - if (num > s._len) - num = s._len; - SetStartLen(num); - wmemcpy(_chars, s._chars, num); - _chars[num] = 0; -} - -UString::UString(const UString &s, wchar_t c) -{ - SetStartLen(s.Len() + 1); - wchar_t *chars = _chars; - unsigned len = s.Len(); - wmemcpy(chars, s, len); - chars[len] = c; - chars[len + 1] = 0; -} - -UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) -{ - SetStartLen(num1 + num2); - wchar_t *chars = _chars; - wmemcpy(chars, s1, num1); - wmemcpy(chars + num1, s2, num2 + 1); -} - -UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); } -UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); } -UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); } - -UString::UString() -{ - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, 4); - _len = 0; - _limit = 4 - 1; - _chars[0] = 0; -} - -UString::UString(wchar_t c) -{ - SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; -} - -UString::UString(const wchar_t *s) -{ - unsigned len = MyStringLen(s); - SetStartLen(len); - wmemcpy(_chars, s, len + 1); -} - -UString::UString(const UString &s) -{ - SetStartLen(s._len); - wmemcpy(_chars, s._chars, s._len + 1); -} - -UString &UString::operator=(wchar_t c) -{ - if (1 > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = 1; - } - _len = 1; - _chars[0] = c; - _chars[1] = 0; - return *this; -} - -UString &UString::operator=(const wchar_t *s) -{ - unsigned len = MyStringLen(s); - if (len > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - wmemcpy(_chars, s, len + 1); - return *this; -} - -UString &UString::operator=(const UString &s) -{ - if (&s == this) - return *this; - unsigned len = s._len; - if (len > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - wmemcpy(_chars, s._chars, len + 1); - return *this; -} - -void UString::SetFromBstr(BSTR s) -{ - unsigned len = ::SysStringLen(s); - if (len > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - _len = len; - // if (s) - wmemcpy(_chars, s, len + 1); -} - -void UString::Add_Space() { operator+=(L' '); } -void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } - -void UString::Add_LF() -{ - if (_limit == _len) - Grow_1(); - unsigned len = _len; - wchar_t *chars = _chars; - chars[len++] = L'\n'; - chars[len] = 0; - _len = len; -} - -UString &UString::operator+=(const wchar_t *s) -{ - unsigned len = MyStringLen(s); - Grow(len); - wmemcpy(_chars + _len, s, len + 1); - _len += len; - return *this; -} - -UString &UString::operator+=(const UString &s) -{ - Grow(s._len); - wmemcpy(_chars + _len, s._chars, s._len + 1); - _len += s._len; - return *this; -} - -void UString::SetFrom(const wchar_t *s, unsigned len) // no check -{ - if (len > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - if (len != 0) - wmemcpy(_chars, s, len); - _chars[len] = 0; - _len = len; -} - -void UString::SetFromAscii(const char *s) -{ - unsigned len = MyStringLen(s); - if (len > _limit) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - MY_STRING_DELETE(_chars); - _chars = newBuf; - _limit = len; - } - wchar_t *chars = _chars; - for (unsigned i = 0; i < len; i++) - chars[i] = (unsigned char)s[i]; - chars[len] = 0; - _len = len; -} - -void UString::AddAscii(const char *s) -{ - unsigned len = MyStringLen(s); - Grow(len); - wchar_t *chars = _chars + _len; - for (unsigned i = 0; i < len; i++) - chars[i] = (unsigned char)s[i]; - chars[len] = 0; - _len += len; -} - - - -int UString::Find(const wchar_t *s, unsigned startIndex) const throw() -{ - const wchar_t *fs = wcsstr(_chars + startIndex, s); - if (!fs) - return -1; - return (int)(fs - _chars); - - /* - if (s[0] == 0) - return startIndex; - unsigned len = MyStringLen(s); - const wchar_t *p = _chars + startIndex; - for (;; p++) - { - const wchar_t c = *p; - if (c != s[0]) - { - if (c == 0) - return -1; - continue; - } - unsigned i; - for (i = 1; i < len; i++) - if (p[i] != s[i]) - break; - if (i == len) - return (int)(p - _chars); - } - */ -} - -int UString::ReverseFind(wchar_t c) const throw() -{ - if (_len == 0) - return -1; - const wchar_t *p = _chars + _len - 1; - for (;;) - { - if (*p == c) - return (int)(p - _chars); - if (p == _chars) - return -1; - p--; - } -} - -int UString::ReverseFind_PathSepar() const throw() -{ - if (_len == 0) - return -1; - const wchar_t *p = _chars + _len - 1; - for (;;) - { - wchar_t c = *p; - if (IS_PATH_SEPAR(c)) - return (int)(p - _chars); - if (p == _chars) - return -1; - p--; - } -} - -void UString::TrimLeft() throw() -{ - const wchar_t *p = _chars; - for (;; p++) - { - wchar_t c = *p; - if (c != ' ' && c != '\n' && c != '\t') - break; - } - unsigned pos = (unsigned)(p - _chars); - if (pos != 0) - { - MoveItems(0, pos); - _len -= pos; - } -} - -void UString::TrimRight() throw() -{ - const wchar_t *p = _chars; - unsigned i; - for (i = _len; i != 0; i--) - { - wchar_t c = p[i - 1]; - if (c != ' ' && c != '\n' && c != '\t') - break; - } - if (i != _len) - { - _chars[i] = 0; - _len = i; - } -} - -void UString::InsertAtFront(wchar_t c) -{ - if (_limit == _len) - Grow_1(); - MoveItems(1, 0); - _chars[0] = c; - _len++; -} - -/* -void UString::Insert(unsigned index, wchar_t c) -{ - InsertSpace(index, 1); - _chars[index] = c; - _len++; -} -*/ - -void UString::Insert(unsigned index, const wchar_t *s) -{ - unsigned num = MyStringLen(s); - if (num != 0) - { - InsertSpace(index, num); - wmemcpy(_chars + index, s, num); - _len += num; - } -} - -void UString::Insert(unsigned index, const UString &s) -{ - unsigned num = s.Len(); - if (num != 0) - { - InsertSpace(index, num); - wmemcpy(_chars + index, s, num); - _len += num; - } -} - -void UString::RemoveChar(wchar_t ch) throw() -{ - wchar_t *src = _chars; - - for (;;) - { - wchar_t c = *src++; - if (c == 0) - return; - if (c == ch) - break; - } - - wchar_t *dest = src - 1; - - for (;;) - { - wchar_t c = *src++; - if (c == 0) - break; - if (c != ch) - *dest++ = c; - } - - *dest = 0; - _len = (unsigned)(dest - _chars); -} - -// !!!!!!!!!!!!!!! test it if newChar = '\0' -void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() -{ - if (oldChar == newChar) - return; // 0; - // unsigned number = 0; - int pos = 0; - while ((unsigned)pos < _len) - { - pos = Find(oldChar, pos); - if (pos < 0) - break; - _chars[(unsigned)pos] = newChar; - pos++; - // number++; - } - return; // number; -} - -void UString::Replace(const UString &oldString, const UString &newString) -{ - if (oldString.IsEmpty()) - return; // 0; - if (oldString == newString) - return; // 0; - unsigned oldLen = oldString.Len(); - unsigned newLen = newString.Len(); - // unsigned number = 0; - int pos = 0; - while ((unsigned)pos < _len) - { - pos = Find(oldString, pos); - if (pos < 0) - break; - Delete(pos, oldLen); - Insert(pos, newString); - pos += newLen; - // number++; - } - // return number; -} - -void UString::Delete(unsigned index) throw() -{ - MoveItems(index, index + 1); - _len--; -} - -void UString::Delete(unsigned index, unsigned count) throw() -{ - if (index + count > _len) - count = _len - index; - if (count > 0) - { - MoveItems(index, index + count); - _len -= count; - } -} - -void UString::DeleteFrontal(unsigned num) throw() -{ - if (num != 0) - { - MoveItems(0, num); - _len -= num; - } -} - - -// ---------- UString2 ---------- - -void UString2::ReAlloc2(unsigned newLimit) -{ - 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); -} - -void UString2::SetStartLen(unsigned len) -{ - _chars = 0; - _chars = MY_STRING_NEW(wchar_t, len + 1); - _len = len; -} - - -/* -UString2::UString2(wchar_t c) -{ - SetStartLen(1); - _chars[0] = c; - _chars[1] = 0; -} -*/ - -UString2::UString2(const wchar_t *s) -{ - unsigned len = MyStringLen(s); - SetStartLen(len); - wmemcpy(_chars, s, len + 1); -} - -UString2::UString2(const UString2 &s): _chars(NULL), _len(0) -{ - if (s._chars) - { - SetStartLen(s._len); - wmemcpy(_chars, s._chars, s._len + 1); - } -} - -/* -UString2 &UString2::operator=(wchar_t c) -{ - if (1 > _len) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, 1 + 1); - if (_chars) - MY_STRING_DELETE(_chars); - _chars = newBuf; - } - _len = 1; - _chars[0] = c; - _chars[1] = 0; - return *this; -} -*/ - -UString2 &UString2::operator=(const wchar_t *s) -{ - unsigned len = MyStringLen(s); - if (len > _len) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - if (_chars) - MY_STRING_DELETE(_chars); - _chars = newBuf; - } - _len = len; - MyStringCopy(_chars, s); - return *this; -} - -void UString2::SetFromAscii(const char *s) -{ - unsigned len = MyStringLen(s); - if (len > _len) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - if (_chars) - MY_STRING_DELETE(_chars); - _chars = newBuf; - } - wchar_t *chars = _chars; - for (unsigned i = 0; i < len; i++) - chars[i] = (unsigned char)s[i]; - chars[len] = 0; - _len = len; -} - -UString2 &UString2::operator=(const UString2 &s) -{ - if (&s == this) - return *this; - unsigned len = s._len; - if (len > _len) - { - wchar_t *newBuf = MY_STRING_NEW(wchar_t, len + 1); - if (_chars) - MY_STRING_DELETE(_chars); - _chars = newBuf; - } - _len = len; - MyStringCopy(_chars, s._chars); - return *this; -} - -bool operator==(const UString2 &s1, const UString2 &s2) -{ - return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0); -} - -bool operator==(const UString2 &s1, const wchar_t *s2) -{ - if (s1.IsEmpty()) - return (*s2 == 0); - return wcscmp(s1.GetRawPtr(), s2) == 0; -} - -bool operator==(const wchar_t *s1, const UString2 &s2) -{ - if (s2.IsEmpty()) - return (*s1 == 0); - return wcscmp(s1, s2.GetRawPtr()) == 0; -} - - - -// ---------------------------------------- - -/* -int MyStringCompareNoCase(const char *s1, const char *s2) -{ - return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); -} -*/ - -static inline UINT GetCurrentCodePage() -{ - #if defined(UNDER_CE) || !defined(_WIN32) - return CP_ACP; - #else - return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; - #endif -} - -#ifdef USE_UNICODE_FSTRING - -#ifndef _UNICODE - -AString fs2fas(CFSTR s) -{ - return UnicodeStringToMultiByte(s, GetCurrentCodePage()); -} - -FString fas2fs(const AString &s) -{ - return MultiByteToUnicodeString(s, GetCurrentCodePage()); -} - -#endif - -#else - -UString fs2us(const FString &s) -{ - return MultiByteToUnicodeString((AString)s, GetCurrentCodePage()); -} - -FString us2fs(const wchar_t *s) -{ - return UnicodeStringToMultiByte(s, GetCurrentCodePage()); -} - -#endif - - - -#ifndef ENV_HAVE_WCTYPE_H -// FIXME - -wchar_t *wmemcpy(wchar_t * d, const wchar_t * s, size_t n) -{ - wchar_t *a = d; - while (n--) *d++ = *s++; - return a; -} - -int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n) -{ - for (; n && *l==*r; n--, l++, r++); - return n ? (*l-*r) : 0; -} - -wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) -{ - for (; n && *s != c; n--, s++); - return n ? (wchar_t *)s : 0; -} - -int wcscmp(const wchar_t *l, const wchar_t *r) -{ - for (; *l==*r && *l && *r; l++, r++); - return *l - *r; -} - -size_t wcslen(const wchar_t *s) -{ - const wchar_t *a; - for (a=s; *s; s++); - return s-a; -} - -wchar_t *wcschr(const wchar_t *s, wchar_t c) -{ - if (!c) return (wchar_t *)s + wcslen(s); - for (; *s && *s != c; s++); - return *s ? (wchar_t *)s : 0; -} - -#undef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#undef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) - -static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n) -{ - const wchar_t *z; - size_t l, ip, jp, k, p, ms, p0, mem, mem0; - - /* Computing length of needle */ - for (l=0; n[l] && h[l]; l++); - if (n[l]) return 0; /* hit the end of h */ - - /* Compute maximal suffix */ - ip = -1; jp = 0; k = p = 1; - while (jp+k n[jp+k]) { - jp += k; - k = 1; - p = jp - ip; - } else { - ip = jp++; - k = p = 1; - } - } - ms = ip; - p0 = p; - - /* And with the opposite comparison */ - ip = -1; jp = 0; k = p = 1; - while (jp+k ms+1) ms = ip; - else p = p0; - - /* Periodic needle? */ - if (wmemcmp(n, n+p, ms+1)) { - mem0 = 0; - p = MAX(ms, l-ms-1) + 1; - } else mem0 = l-p; - mem = 0; - - /* Initialize incremental end-of-haystack pointer */ - z = h; - - /* Search loop */ - for (;;) { - /* Update incremental end-of-haystack pointer */ - if (z-h < l) { - /* Fast estimate for MIN(l,63) */ - size_t grow = l | 63; - const wchar_t *z2 = wmemchr(z, 0, grow); - if (z2) { - z = z2; - if (z-h < l) return 0; - } else z += grow; - } - - /* Compare right half */ - for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++); - if (n[k]) { - h += k-ms; - mem = 0; - continue; - } - /* Compare left half */ - for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); - if (k <= mem) return (wchar_t *)h; - h += p; - mem = mem0; - } -} - -wchar_t *wcsstr(const wchar_t * h, const wchar_t * n) -{ - /* Return immediately on empty needle or haystack */ - if (!n[0]) return (wchar_t *)h; - if (!h[0]) return 0; - - /* Use faster algorithms for short needles */ - h = wcschr(h, *n); - if (!h || !n[1]) return (wchar_t *)h; - if (!h[1]) return 0; - - return twoway_wcsstr(h, n); -} - -#if defined(__DJGPP__) -wchar_t *wcscpy(wchar_t * d, const wchar_t * s) -{ - wchar_t *a = d; - while ((*d++ = *s++)); - return a; -} - -wchar_t *wcscat(wchar_t *dest, const wchar_t * src) -{ - wcscpy(dest + wcslen(dest), src); - return dest; -} - -#endif - -#endif +// Common/MyString.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "IntToString.h" + +#if !defined(_UNICODE) || !defined(USE_UNICODE_FSTRING) +#include "StringConvert.h" +#endif + +#include "MyString.h" + +#define MY_STRING_NEW(_T_, _size_) new _T_[_size_] +// #define MY_STRING_NEW(_T_, _size_) ((_T_ *)my_new((size_t)(_size_) * sizeof(_T_))) + +/* +inline const char* MyStringGetNextCharPointer(const char *p) throw() +{ + #if defined(_WIN32) && !defined(UNDER_CE) + return CharNextA(p); + #else + return p + 1; + #endif +} +*/ + +#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() +{ + for (const char *p = s;; p++) + { + if (*p == c) + return (int)(p - s); + if (*p == 0) + return -1; + // MyStringGetNextCharPointer(p); + } +} + +int FindCharPosInString(const wchar_t *s, wchar_t c) throw() +{ + for (const wchar_t *p = s;; p++) + { + if (*p == c) + return (int)(p - s); + if (*p == 0) + return -1; + } +} + +/* +void MyStringUpper_Ascii(char *s) throw() +{ + for (;;) + { + const char c = *s; + if (c == 0) + return; + *s++ = MyCharUpper_Ascii(c); + } +} + +void MyStringUpper_Ascii(wchar_t *s) throw() +{ + for (;;) + { + const wchar_t c = *s; + if (c == 0) + return; + *s++ = MyCharUpper_Ascii(c); + } +} +*/ + +void MyStringLower_Ascii(char *s) throw() +{ + for (;;) + { + const char c = *s; + if (c == 0) + return; + *s++ = MyCharLower_Ascii(c); + } +} + +void MyStringLower_Ascii(wchar_t *s) throw() +{ + for (;;) + { + const wchar_t c = *s; + if (c == 0) + return; + *s++ = MyCharLower_Ascii(c); + } +} + +#ifdef _WIN32 + +#ifdef _UNICODE + +// wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); } +// wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); } +// for WinCE - FString - char +// const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p) { return p - 1; } + +#else + +// const char * MyStringGetPrevCharPointer(const char *base, const char *p) throw() { return CharPrevA(base, p); } +// char * MyStringUpper(char *s) { return CharUpperA(s); } +// char * MyStringLower(char *s) { return CharLowerA(s); } + +wchar_t MyCharUpper_WIN(wchar_t c) throw() +{ + wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned)(UINT_PTR)res; + const int kBufSize = 4; + char s[kBufSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); + if (numChars == 0 || numChars > kBufSize) + return c; + s[numChars] = 0; + ::CharUpperA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} + +/* +wchar_t MyCharLower_WIN(wchar_t c) +{ + wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return (wchar_t)(unsigned)(UINT_PTR)res; + const int kBufSize = 4; + char s[kBufSize + 1]; + int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufSize, 0, 0); + if (numChars == 0 || numChars > kBufSize) + return c; + s[numChars] = 0; + ::CharLowerA(s); + ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1); + return c; +} +*/ + +/* +wchar_t * MyStringUpper(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharUpperW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeUpper(); + MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + return s; +} +*/ + +/* +wchar_t * MyStringLower(wchar_t *s) +{ + if (s == 0) + return 0; + wchar_t *res = CharLowerW(s); + if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return res; + AString a = UnicodeStringToMultiByte(s); + a.MakeLower(); + MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a)); + return s; +} +*/ + +#endif + +#endif + +bool IsString1PrefixedByString2(const char *s1, const char *s2) throw() +{ + for (;;) + { + const char c2 = *s2++; if (c2 == 0) return true; + const char c1 = *s1++; if (c1 != c2) return false; + } +} + +bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; + if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) return false; + if (c1 == 0) return true; + } +} + +// ---------- ASCII ---------- + +bool StringsAreEqual_Ascii(const char *u, const char *a) throw() +{ + for (;;) + { + const char c = *a; + if (c != *u) + return false; + if (c == 0) + return true; + a++; + u++; + } +} + +bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw() +{ + for (;;) + { + const unsigned char c = (unsigned char)*a; + if (c != *u) + return false; + if (c == 0) + return true; + a++; + u++; + } +} + +bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw() +{ + for (;;) + { + const char c1 = *s1++; + const char c2 = *s2++; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + if (c1 == 0) + return true; + } +} + +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + if (c1 == 0) + return true; + } +} + +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + 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) + return true; + } +} + +bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + const wchar_t c2 = *s2++; if (c2 == 0) return true; + const wchar_t c1 = *s1++; if (c1 != c2) return false; + } +} + +bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + const unsigned char c2 = (unsigned char)(*s2++); if (c2 == 0) return true; + const wchar_t c1 = *s1++; if (c1 != c2) return false; + } +} + +bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw() +{ + for (;;) + { + const char c2 = *s2++; if (c2 == 0) return true; + const char c1 = *s1++; + if (c1 != c2 && MyCharLower_Ascii(c1) != MyCharLower_Ascii(c2)) + return false; + } +} + +bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *s1, const char *s2) throw() +{ + for (;;) + { + 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; + } +} + +bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + const wchar_t c2 = *s2++; if (c2 == 0) return true; + const wchar_t c1 = *s1++; + if (c1 != c2 && MyCharUpper(c1) != MyCharUpper(c2)) + return false; + } +} + +// NTFS order: uses upper case +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + const wchar_t c1 = *s1++; + const wchar_t c2 = *s2++; + if (c1 != c2) + { + const wchar_t u1 = MyCharUpper(c1); + const wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } +} + +/* +int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) +{ + for (; num != 0; num--) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + wchar_t u1 = MyCharUpper(c1); + wchar_t u2 = MyCharUpper(c2); + if (u1 < u2) return -1; + if (u1 > u2) return 1; + } + if (c1 == 0) return 0; + } + return 0; +} +*/ + +// ---------- AString ---------- + +void AString::InsertSpace(unsigned &index, unsigned size) +{ + Grow(size); + MoveItems(index + size, index); +} + +#define k_Alloc_Len_Limit (0x40000000 - 2) +// #define k_Alloc_Len_Limit (((unsigned)1 << (sizeof(unsigned) * 8 - 2)) - 2) + +void AString::ReAlloc(unsigned newLimit) +{ + // 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; +} + +#define THROW_STRING_ALLOC_EXCEPTION { throw 20130220; } + +#define CHECK_STRING_ALLOC_LEN(len) \ + { if ((len) > k_Alloc_Len_Limit) THROW_STRING_ALLOC_EXCEPTION } + +void AString::ReAlloc2(unsigned newLimit) +{ + CHECK_STRING_ALLOC_LEN(newLimit) + // 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; + _limit = newLimit; + _len = 0; +} + +void AString::SetStartLen(unsigned len) +{ + _chars = NULL; + _chars = MY_STRING_NEW_char((size_t)len + 1); + _len = len; + _limit = len; +} + +Z7_NO_INLINE +void AString::Grow_1() +{ + unsigned next = _len; + 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) + THROW_STRING_ALLOC_EXCEPTION + ReAlloc(next); + // Grow(1); +} + +void AString::Grow(unsigned n) +{ + 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_STRING_ALLOC_EXCEPTION + ReAlloc(next); +} + +AString::AString(unsigned num, const char *s) +{ + unsigned len = MyStringLen(s); + if (num > len) + num = len; + SetStartLen(num); + memcpy(_chars, s, num); + _chars[num] = 0; +} + +AString::AString(unsigned num, const AString &s) +{ + if (num > s._len) + num = s._len; + SetStartLen(num); + memcpy(_chars, s._chars, num); + _chars[num] = 0; +} + +AString::AString(const AString &s, char c) +{ + SetStartLen(s.Len() + 1); + char *chars = _chars; + unsigned len = s.Len(); + memcpy(chars, s, len); + chars[len] = c; + chars[(size_t)len + 1] = 0; +} + +AString::AString(const char *s1, unsigned num1, const char *s2, unsigned num2) +{ + SetStartLen(num1 + num2); + char *chars = _chars; + memcpy(chars, s1, num1); + memcpy(chars + num1, s2, num2 + 1); +} + +AString operator+(const AString &s1, const AString &s2) { return AString(s1, s1.Len(), s2, s2.Len()); } +AString operator+(const AString &s1, const char *s2) { return AString(s1, s1.Len(), s2, MyStringLen(s2)); } +AString operator+(const char *s1, const AString &s2) { return AString(s1, MyStringLen(s1), s2, s2.Len()); } + +static const unsigned kStartStringCapacity = 4; + +AString::AString() +{ + _chars = NULL; + _chars = MY_STRING_NEW_char(kStartStringCapacity); + _len = 0; + _limit = kStartStringCapacity - 1; + _chars[0] = 0; +} + +AString::AString(char c) +{ + SetStartLen(1); + char *chars = _chars; + chars[0] = c; + chars[1] = 0; +} + +AString::AString(const char *s) +{ + SetStartLen(MyStringLen(s)); + MyStringCopy(_chars, s); +} + +AString::AString(const AString &s) +{ + SetStartLen(s._len); + MyStringCopy(_chars, s._chars); +} + +AString &AString::operator=(char c) +{ + if (1 > _limit) + { + char *newBuf = MY_STRING_NEW_char(1 + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = 1; + } + _len = 1; + char *chars = _chars; + chars[0] = c; + chars[1] = 0; + return *this; +} + +AString &AString::operator=(const char *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s); + return *this; +} + +AString &AString::operator=(const AString &s) +{ + if (&s == this) + return *this; + unsigned len = s._len; + if (len > _limit) + { + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + MyStringCopy(_chars, s._chars); + return *this; +} + +void AString::SetFromWStr_if_Ascii(const wchar_t *s) +{ + unsigned len = 0; + { + for (;; len++) + { + wchar_t c = s[len]; + if (c == 0) + break; + if (c >= 0x80) + return; + } + } + if (len > _limit) + { + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + char *dest = _chars; + unsigned i; + for (i = 0; i < len; i++) + dest[i] = (char)s[i]; + dest[i] = 0; +} + +/* +void AString::SetFromBstr_if_Ascii(BSTR s) +{ + unsigned len = ::SysStringLen(s); + { + for (unsigned i = 0; i < len; i++) + if (s[i] <= 0 || s[i] >= 0x80) + return; + } + if (len > _limit) + { + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + char *dest = _chars; + unsigned i; + for (i = 0; i < len; i++) + dest[i] = (char)s[i]; + dest[i] = 0; +} +*/ + +void AString::Add_Char(char c) { operator+=(c); } +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+=('/'); } +void AString::Add_Dot() { operator+=('.'); } +void AString::Add_Minus() { operator+=('-'); } +void AString::Add_Colon() { operator+=(':'); } + +AString &AString::operator+=(const char *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + MyStringCopy(_chars + _len, s); + _len += len; + return *this; +} + +void AString::Add_OptSpaced(const char *s) +{ + Add_Space_if_NotEmpty(); + (*this) += s; +} + +AString &AString::operator+=(const AString &s) +{ + Grow(s._len); + MyStringCopy(_chars + _len, s._chars); + _len += s._len; + return *this; +} + +void AString::Add_UInt32(UInt32 v) +{ + Grow(10); + _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); +} + +void UString::Add_UInt64(UInt64 v) +{ + Grow(20); + _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) + { + CHECK_STRING_ALLOC_LEN(len) + char *newBuf = MY_STRING_NEW_char((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + if (len != 0) + memcpy(_chars, s, len); + _chars[len] = 0; + _len = len; +} + +void AString::SetFrom_Chars_SizeT(const char *s, size_t len) +{ + CHECK_STRING_ALLOC_LEN(len) + SetFrom(s, (unsigned)len); +} + +void AString::SetFrom_CalcLen(const char *s, unsigned len) // no check +{ + unsigned i; + for (i = 0; i < len; i++) + if (s[i] == 0) + break; + SetFrom(s, i); +} + +int AString::Find(const char *s, unsigned startIndex) const throw() +{ + const char *fs = strstr(_chars + startIndex, s); + if (!fs) + return -1; + return (int)(fs - _chars); + + /* + if (s[0] == 0) + return startIndex; + unsigned len = MyStringLen(s); + const char *p = _chars + startIndex; + for (;; p++) + { + const char c = *p; + if (c != s[0]) + { + if (c == 0) + return -1; + continue; + } + unsigned i; + for (i = 1; i < len; i++) + if (p[i] != s[i]) + break; + if (i == len) + return (int)(p - _chars); + } + */ +} + +int AString::ReverseFind(char c) const throw() +{ + if (_len == 0) + return -1; + const char *p = _chars + _len - 1; + for (;;) + { + if (*p == c) + return (int)(p - _chars); + if (p == _chars) + return -1; + p--; // p = GetPrevCharPointer(_chars, p); + } +} + +int AString::ReverseFind_PathSepar() const throw() +{ + if (_len == 0) + return -1; + const char *p = _chars + _len - 1; + for (;;) + { + const char c = *p; + if (IS_PATH_SEPAR(c)) + return (int)(p - _chars); + if (p == _chars) + return -1; + p--; + } +} + +void AString::TrimLeft() throw() +{ + const char *p = _chars; + for (;; p++) + { + char c = *p; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + unsigned pos = (unsigned)(p - _chars); + if (pos != 0) + { + MoveItems(0, pos); + _len -= pos; + } +} + +void AString::TrimRight() throw() +{ + const char *p = _chars; + unsigned i; + for (i = _len; i != 0; i--) + { + char c = p[(size_t)i - 1]; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + if (i != _len) + { + _chars[i] = 0; + _len = i; + } +} + +void AString::InsertAtFront(char c) +{ + if (_limit == _len) + Grow_1(); + MoveItems(1, 0); + _chars[0] = c; + _len++; +} + +/* +void AString::Insert(unsigned index, char c) +{ + InsertSpace(index, 1); + _chars[index] = c; + _len++; +} +*/ + +void AString::Insert(unsigned index, const char *s) +{ + unsigned num = MyStringLen(s); + if (num != 0) + { + InsertSpace(index, num); + memcpy(_chars + index, s, num); + _len += num; + } +} + +void AString::Insert(unsigned index, const AString &s) +{ + unsigned num = s.Len(); + if (num != 0) + { + InsertSpace(index, num); + memcpy(_chars + index, s, num); + _len += num; + } +} + +void AString::RemoveChar(char ch) throw() +{ + char *src = _chars; + + for (;;) + { + char c = *src++; + if (c == 0) + return; + if (c == ch) + break; + } + + char *dest = src - 1; + + for (;;) + { + char c = *src++; + if (c == 0) + break; + if (c != ch) + *dest++ = c; + } + + *dest = 0; + _len = (unsigned)(dest - _chars); +} + +// !!!!!!!!!!!!!!! test it if newChar = '\0' +void AString::Replace(char oldChar, char newChar) throw() +{ + if (oldChar == newChar) + return; // 0; + // unsigned number = 0; + int pos = 0; + char *chars = _chars; + while ((unsigned)pos < _len) + { + pos = Find(oldChar, (unsigned)pos); + if (pos < 0) + break; + chars[(unsigned)pos] = newChar; + pos++; + // number++; + } + return; // number; +} + +void AString::Replace(const AString &oldString, const AString &newString) +{ + if (oldString.IsEmpty()) + return; // 0; + if (oldString == newString) + return; // 0; + const unsigned oldLen = oldString.Len(); + const unsigned newLen = newString.Len(); + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldString, (unsigned)pos); + if (pos < 0) + break; + Delete((unsigned)pos, oldLen); + Insert((unsigned)pos, newString); + pos += newLen; + // number++; + } + // return number; +} + +void AString::Delete(unsigned index) throw() +{ + MoveItems(index, index + 1); + _len--; +} + +void AString::Delete(unsigned index, unsigned count) throw() +{ + if (index + count > _len) + count = _len - index; + if (count > 0) + { + MoveItems(index, index + count); + _len -= count; + } +} + +void AString::DeleteFrontal(unsigned num) throw() +{ + if (num != 0) + { + MoveItems(0, num); + _len -= num; + } +} + +/* +AString operator+(const AString &s1, const AString &s2) +{ + AString result(s1); + result += s2; + return result; +} + +AString operator+(const AString &s, const char *chars) +{ + AString result(s); + result += chars; + return result; +} + +AString operator+(const char *chars, const AString &s) +{ + AString result(chars); + result += s; + return result; +} + +AString operator+(const AString &s, char c) +{ + AString result(s); + result += c; + return result; +} +*/ + +/* +AString operator+(char c, const AString &s) +{ + AString result(c); + result += s; + return result; +} +*/ + + + + +// ---------- UString ---------- + +void UString::InsertSpace(unsigned index, unsigned size) +{ + Grow(size); + MoveItems(index + size, index); +} + +void UString::ReAlloc(unsigned newLimit) +{ + // 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; + _limit = newLimit; +} + +void UString::ReAlloc2(unsigned newLimit) +{ + CHECK_STRING_ALLOC_LEN(newLimit) + // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)newLimit + 1); + newBuf[0] = 0; + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = newLimit; + _len = 0; +} + +void UString::SetStartLen(unsigned len) +{ + _chars = NULL; + _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); + _len = len; + _limit = len; +} + +Z7_NO_INLINE +void UString::Grow_1() +{ + unsigned next = _len; + 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) + THROW_STRING_ALLOC_EXCEPTION + ReAlloc(next); +} + +void UString::Grow(unsigned n) +{ + 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_STRING_ALLOC_EXCEPTION + ReAlloc(next - 1); +} + + +UString::UString(unsigned num, const wchar_t *s) +{ + unsigned len = MyStringLen(s); + if (num > len) + num = len; + SetStartLen(num); + wmemcpy(_chars, s, num); + _chars[num] = 0; +} + + +UString::UString(unsigned num, const UString &s) +{ + if (num > s._len) + num = s._len; + SetStartLen(num); + wmemcpy(_chars, s._chars, num); + _chars[num] = 0; +} + +UString::UString(const UString &s, wchar_t c) +{ + SetStartLen(s.Len() + 1); + wchar_t *chars = _chars; + unsigned len = s.Len(); + wmemcpy(chars, s, len); + chars[len] = c; + chars[(size_t)len + 1] = 0; +} + +UString::UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2) +{ + SetStartLen(num1 + num2); + wchar_t *chars = _chars; + wmemcpy(chars, s1, num1); + wmemcpy(chars + num1, s2, num2 + 1); +} + +UString operator+(const UString &s1, const UString &s2) { return UString(s1, s1.Len(), s2, s2.Len()); } +UString operator+(const UString &s1, const wchar_t *s2) { return UString(s1, s1.Len(), s2, MyStringLen(s2)); } +UString operator+(const wchar_t *s1, const UString &s2) { return UString(s1, MyStringLen(s1), s2, s2.Len()); } + +UString::UString() +{ + _chars = NULL; + _chars = MY_STRING_NEW_wchar_t(kStartStringCapacity); + _len = 0; + _limit = kStartStringCapacity - 1; + _chars[0] = 0; +} + +UString::UString(wchar_t c) +{ + SetStartLen(1); + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; +} + +UString::UString(char c) +{ + SetStartLen(1); + wchar_t *chars = _chars; + chars[0] = (unsigned char)c; + chars[1] = 0; +} + +UString::UString(const wchar_t *s) +{ + const unsigned len = MyStringLen(s); + SetStartLen(len); + wmemcpy(_chars, s, len + 1); +} + +UString::UString(const char *s) +{ + const unsigned len = MyStringLen(s); + SetStartLen(len); + wchar_t *chars = _chars; + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s[i]; + chars[len] = 0; +} + +UString::UString(const AString &s) +{ + const unsigned len = s.Len(); + SetStartLen(len); + wchar_t *chars = _chars; + const char *s2 = s.Ptr(); + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s2[i]; + chars[len] = 0; +} + +UString::UString(const UString &s) +{ + SetStartLen(s._len); + wmemcpy(_chars, s._chars, s._len + 1); +} + +UString &UString::operator=(wchar_t c) +{ + if (1 > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = 1; + } + _len = 1; + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; + return *this; +} + +UString &UString::operator=(const wchar_t *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + wmemcpy(_chars, s, len + 1); + return *this; +} + +UString &UString::operator=(const UString &s) +{ + if (&s == this) + return *this; + unsigned len = s._len; + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + wmemcpy(_chars, s._chars, len + 1); + return *this; +} + +void UString::SetFrom(const wchar_t *s, unsigned len) // no check +{ + if (len > _limit) + { + CHECK_STRING_ALLOC_LEN(len) + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + if (len != 0) + wmemcpy(_chars, s, len); + _chars[len] = 0; + _len = len; +} + +void UString::SetFromBstr(LPCOLESTR s) +{ + unsigned len = ::SysStringLen((BSTR)(void *)(s)); + + /* + #if WCHAR_MAX > 0xffff + size_t num_wchars = 0; + for (size_t i = 0; i < len;) + { + wchar_t c = s[i++]; + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = s[i]; + if (c2 >= 0xdc00 && c2 < 0xe000) + { + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + i++; + } + } + num_wchars++; + } + len = num_wchars; + #endif + */ + + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + _len = len; + + /* + #if WCHAR_MAX > 0xffff + + wchar_t *chars = _chars; + for (size_t i = 0; i <= len; i++) + { + wchar_t c = *s++; + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = *s; + if (c2 >= 0xdc00 && c2 < 0xe000) + { + s++; + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + } + } + chars[i] = c; + } + + #else + */ + + // if (s) + wmemcpy(_chars, s, len + 1); + + // #endif +} + +UString &UString::operator=(const char *s) +{ + unsigned len = MyStringLen(s); + if (len > _limit) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + MY_STRING_DELETE(_chars) + _chars = newBuf; + _limit = len; + } + wchar_t *chars = _chars; + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s[i]; + chars[len] = 0; + _len = len; + return *this; +} + +void UString::Add_Char(char c) { operator+=((wchar_t)(unsigned char)c); } +// void UString::Add_WChar(wchar_t c) { operator+=(c); } +void UString::Add_Dot() { operator+=(L'.'); } +void UString::Add_Space() { operator+=(L' '); } +void UString::Add_Minus() { operator+=(L'-'); } +void UString::Add_Colon() { operator+=(L':'); } +void UString::Add_LF() { operator+=(L'\n'); } +void UString::Add_Space_if_NotEmpty() { if (!IsEmpty()) Add_Space(); } + +UString &UString::operator+=(const wchar_t *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + wmemcpy(_chars + _len, s, len + 1); + _len += len; + return *this; +} + +UString &UString::operator+=(const UString &s) +{ + Grow(s._len); + wmemcpy(_chars + _len, s._chars, s._len + 1); + _len += s._len; + return *this; +} + +UString &UString::operator+=(const char *s) +{ + unsigned len = MyStringLen(s); + Grow(len); + wchar_t *chars = _chars + _len; + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s[i]; + chars[len] = 0; + _len += len; + return *this; +} + + +void UString::Add_UInt32(UInt32 v) +{ + Grow(10); + _len = (unsigned)(ConvertUInt32ToString(v, _chars + _len) - _chars); +} + +void AString::Add_UInt64(UInt64 v) +{ + Grow(20); + _len = (unsigned)(ConvertUInt64ToString(v, _chars + _len) - _chars); +} + + +int UString::Find(const wchar_t *s, unsigned startIndex) const throw() +{ + const wchar_t *fs = wcsstr(_chars + startIndex, s); + if (!fs) + return -1; + return (int)(fs - _chars); + + /* + if (s[0] == 0) + return startIndex; + unsigned len = MyStringLen(s); + const wchar_t *p = _chars + startIndex; + for (;; p++) + { + const wchar_t c = *p; + if (c != s[0]) + { + if (c == 0) + return -1; + continue; + } + unsigned i; + for (i = 1; i < len; i++) + if (p[i] != s[i]) + break; + if (i == len) + return (int)(p - _chars); + } + */ +} + +int UString::ReverseFind(wchar_t c) const throw() +{ + if (_len == 0) + return -1; + const wchar_t *p = _chars + _len; + do + { + if (*(--p) == c) + return (int)(p - _chars); + } + while (p != _chars); + return -1; +} + +int UString::ReverseFind_PathSepar() const throw() +{ + const wchar_t *p = _chars + _len; + while (p != _chars) + { + const wchar_t c = *(--p); + if (IS_PATH_SEPAR(c)) + return (int)(p - _chars); + } + return -1; +} + +void UString::TrimLeft() throw() +{ + const wchar_t *p = _chars; + for (;; p++) + { + wchar_t c = *p; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + unsigned pos = (unsigned)(p - _chars); + if (pos != 0) + { + MoveItems(0, pos); + _len -= pos; + } +} + +void UString::TrimRight() throw() +{ + const wchar_t *p = _chars; + unsigned i; + for (i = _len; i != 0; i--) + { + wchar_t c = p[(size_t)i - 1]; + if (c != ' ' && c != '\n' && c != '\t') + break; + } + if (i != _len) + { + _chars[i] = 0; + _len = i; + } +} + +void UString::InsertAtFront(wchar_t c) +{ + if (_limit == _len) + Grow_1(); + MoveItems(1, 0); + _chars[0] = c; + _len++; +} + +/* +void UString::Insert_wchar_t(unsigned index, wchar_t c) +{ + InsertSpace(index, 1); + _chars[index] = c; + _len++; +} +*/ + +void UString::Insert(unsigned index, const wchar_t *s) +{ + unsigned num = MyStringLen(s); + if (num != 0) + { + InsertSpace(index, num); + wmemcpy(_chars + index, s, num); + _len += num; + } +} + +void UString::Insert(unsigned index, const UString &s) +{ + unsigned num = s.Len(); + if (num != 0) + { + InsertSpace(index, num); + wmemcpy(_chars + index, s, num); + _len += num; + } +} + +void UString::RemoveChar(wchar_t ch) throw() +{ + wchar_t *src = _chars; + + for (;;) + { + wchar_t c = *src++; + if (c == 0) + return; + if (c == ch) + break; + } + + wchar_t *dest = src - 1; + + for (;;) + { + wchar_t c = *src++; + if (c == 0) + break; + if (c != ch) + *dest++ = c; + } + + *dest = 0; + _len = (unsigned)(dest - _chars); +} + +// !!!!!!!!!!!!!!! test it if newChar = '\0' +void UString::Replace(wchar_t oldChar, wchar_t newChar) throw() +{ + if (oldChar == newChar) + return; // 0; + // unsigned number = 0; + int pos = 0; + wchar_t *chars = _chars; + while ((unsigned)pos < _len) + { + pos = Find(oldChar, (unsigned)pos); + if (pos < 0) + break; + chars[(unsigned)pos] = newChar; + pos++; + // number++; + } + return; // number; +} + +void UString::Replace(const UString &oldString, const UString &newString) +{ + if (oldString.IsEmpty()) + return; // 0; + if (oldString == newString) + return; // 0; + unsigned oldLen = oldString.Len(); + unsigned newLen = newString.Len(); + // unsigned number = 0; + int pos = 0; + while ((unsigned)pos < _len) + { + pos = Find(oldString, (unsigned)pos); + if (pos < 0) + break; + Delete((unsigned)pos, oldLen); + Insert((unsigned)pos, newString); + pos += newLen; + // number++; + } + // return number; +} + +void UString::Delete(unsigned index) throw() +{ + MoveItems(index, index + 1); + _len--; +} + +void UString::Delete(unsigned index, unsigned count) throw() +{ + if (index + count > _len) + count = _len - index; + if (count > 0) + { + MoveItems(index, index + count); + _len -= count; + } +} + +void UString::DeleteFrontal(unsigned num) throw() +{ + if (num != 0) + { + MoveItems(0, num); + _len -= num; + } +} + + +// ---------- UString2 ---------- + +void UString2::ReAlloc2(unsigned newLimit) +{ + // wrong (_len) is allowed after this function + CHECK_STRING_ALLOC_LEN(newLimit) + // MY_STRING_REALLOC(_chars, wchar_t, newLimit + 1, 0); + 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 = NULL; + _chars = MY_STRING_NEW_wchar_t((size_t)len + 1); + _len = len; +} + + +/* +UString2::UString2(wchar_t c) +{ + SetStartLen(1); + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; +} +*/ + +UString2::UString2(const wchar_t *s) +{ + const unsigned len = MyStringLen(s); + SetStartLen(len); + wmemcpy(_chars, s, len + 1); +} + +UString2::UString2(const UString2 &s): _chars(NULL), _len(0) +{ + if (s._chars) + { + SetStartLen(s._len); + wmemcpy(_chars, s._chars, s._len + 1); + } +} + +/* +UString2 &UString2::operator=(wchar_t c) +{ + if (1 > _len) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t(1 + 1); + if (_chars) + MY_STRING_DELETE(_chars) + _chars = newBuf; + } + _len = 1; + wchar_t *chars = _chars; + chars[0] = c; + chars[1] = 0; + return *this; +} +*/ + +UString2 &UString2::operator=(const wchar_t *s) +{ + unsigned len = MyStringLen(s); + if (len > _len) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + if (_chars) + MY_STRING_DELETE(_chars) + _chars = newBuf; + } + _len = len; + MyStringCopy(_chars, s); + return *this; +} + +void UString2::SetFromAscii(const char *s) +{ + unsigned len = MyStringLen(s); + if (len > _len) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + if (_chars) + MY_STRING_DELETE(_chars) + _chars = newBuf; + } + wchar_t *chars = _chars; + for (unsigned i = 0; i < len; i++) + chars[i] = (unsigned char)s[i]; + chars[len] = 0; + _len = len; +} + +UString2 &UString2::operator=(const UString2 &s) +{ + if (&s == this) + return *this; + unsigned len = s._len; + if (len > _len) + { + wchar_t *newBuf = MY_STRING_NEW_wchar_t((size_t)len + 1); + if (_chars) + MY_STRING_DELETE(_chars) + _chars = newBuf; + } + _len = len; + MyStringCopy(_chars, s._chars); + return *this; +} + +bool operator==(const UString2 &s1, const UString2 &s2) +{ + return s1.Len() == s2.Len() && (s1.IsEmpty() || wcscmp(s1.GetRawPtr(), s2.GetRawPtr()) == 0); +} + +bool operator==(const UString2 &s1, const wchar_t *s2) +{ + if (s1.IsEmpty()) + return (*s2 == 0); + return wcscmp(s1.GetRawPtr(), s2) == 0; +} + +bool operator==(const wchar_t *s1, const UString2 &s2) +{ + if (s2.IsEmpty()) + return (*s1 == 0); + return wcscmp(s1, s2.GetRawPtr()) == 0; +} + + + +// ---------------------------------------- + +/* +int MyStringCompareNoCase(const char *s1, const char *s2) +{ + return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2)); +} +*/ + +#if !defined(USE_UNICODE_FSTRING) || !defined(_UNICODE) + +static inline UINT GetCurrentCodePage() +{ + #if defined(UNDER_CE) || !defined(_WIN32) + return CP_ACP; + #else + return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + #endif +} + +#endif + +#ifdef USE_UNICODE_FSTRING + +#ifndef _UNICODE + +AString fs2fas(CFSTR s) +{ + return UnicodeStringToMultiByte(s, GetCurrentCodePage()); +} + +FString fas2fs(const char *s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} + +FString fas2fs(const AString &s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} + +#endif // _UNICODE + +#else // USE_UNICODE_FSTRING + +UString fs2us(const FChar *s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} + +UString fs2us(const FString &s) +{ + return MultiByteToUnicodeString(s, GetCurrentCodePage()); +} + +FString us2fs(const wchar_t *s) +{ + return UnicodeStringToMultiByte(s, GetCurrentCodePage()); +} + +#endif // USE_UNICODE_FSTRING + + +bool CStringFinder::FindWord_In_LowCaseAsciiList_NoCase(const char *p, const wchar_t *str) +{ + _temp.Empty(); + for (;;) + { + const wchar_t c = *str++; + if (c == 0) + break; + if (c <= 0x20 || c > 0x7f) + return false; + _temp.Add_Char((char)MyCharLower_Ascii((char)c)); + } + + while (*p != 0) + { + const char *s2 = _temp.Ptr(); + char c, c2; + do + { + c = *p++; + c2 = *s2++; + } + while (c == c2); + + if (c == ' ') + { + if (c2 == 0) + return true; + continue; + } + + while (*p++ != ' '); + } + + return false; +} + + +void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + unsigned len = srcString.Len(); + if (len == 0) + return; + UString s; + for (unsigned i = 0; i < len; i++) + { + const wchar_t c = srcString[i]; + if (c == ' ') + { + if (!s.IsEmpty()) + { + destStrings.Add(s); + s.Empty(); + } + } + else + s += c; + } + if (!s.IsEmpty()) + destStrings.Add(s); +} diff -Nru p7zip-rar-16.02/CPP/Common/MyString.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.h --- p7zip-rar-16.02/CPP/Common/MyString.h 2016-02-17 18:39:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyString.h 2025-07-01 10:00:00.000000000 +0000 @@ -1,792 +1,1079 @@ -// Common/String.h - -#ifndef __COMMON_STRING_H -#define __COMMON_STRING_H - -#include - -#ifdef ENV_HAVE_WCHAR__H -#include -#endif - -#ifdef ENV_HAVE_WCTYPE_H -#include -#else -#define towupper(c) (c) // FIXME -int wcscmp(const wchar_t *s1, const wchar_t *s2); -wchar_t * wmemcpy(wchar_t *dest, const wchar_t *src, size_t num); -wchar_t * wcsstr(const wchar_t *wcs1, const wchar_t *wcs2); -#endif - -#include "MyWindows.h" -#include "MyTypes.h" -#include "MyVector.h" - -#ifdef _WIN32 -#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/') -#else -#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR) -#endif - -inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); } -inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); } - -inline unsigned MyStringLen(const char *s) -{ - unsigned i; - for (i = 0; s[i] != 0; i++); - return i; -} - -inline void MyStringCopy(char *dest, const char *src) -{ - while ((*dest++ = *src++) != 0); -} - -inline char *MyStpCpy(char *dest, const char *src) -{ - for (;;) - { - char c = *src; - *dest = c; - if (c == 0) - return dest; - src++; - dest++; - } -} - -inline unsigned MyStringLen(const wchar_t *s) -{ - unsigned i; - for (i = 0; s[i] != 0; i++); - return i; -} - -inline void MyStringCopy(wchar_t *dest, const wchar_t *src) -{ - while ((*dest++ = *src++) != 0); -} - -/* -inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src) -{ - for (;;) - { - wchar_t c = *src; - *dest = c; - if (c == 0) - return dest; - src++; - dest++; - } -} -*/ - -int FindCharPosInString(const char *s, char c) throw(); -int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); - -#ifdef _WIN32 - #ifndef _UNICODE - #define STRING_UNICODE_THROW - #endif -#endif - -#ifndef STRING_UNICODE_THROW - #define STRING_UNICODE_THROW throw() -#endif - -/* -inline char MyCharUpper_Ascii(char c) -{ - if (c >= 'a' && c <= 'z') - return (char)(c - 0x20); - return c; -} -inline wchar_t MyCharUpper_Ascii(wchar_t c) -{ - if (c >= 'a' && c <= 'z') - return (wchar_t)(c - 0x20); - return c; -} -*/ - -inline char MyCharLower_Ascii(char c) -{ - if (c >= 'A' && c <= 'Z') - return (char)((unsigned char)c + 0x20); - return c; -} - -inline wchar_t MyCharLower_Ascii(wchar_t c) -{ - if (c >= 'A' && c <= 'Z') - return (wchar_t)(c + 0x20); - return c; -} - -wchar_t MyCharUpper_WIN(wchar_t c) throw(); - -inline wchar_t MyCharUpper(wchar_t c) throw() -{ - if (c < 'a') return c; - if (c <= 'z') return (wchar_t)(c - 0x20); - if (c <= 0x7F) return c; - #ifdef _WIN32 - #ifdef _UNICODE - return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); - #else - return (wchar_t)MyCharUpper_WIN(c); - #endif - #else - return (wchar_t)towupper(c); - #endif -} - -/* -wchar_t MyCharLower_WIN(wchar_t c) throw(); - -inline wchar_t MyCharLower(wchar_t c) throw() -{ - if (c < 'A') return c; - if (c <= 'Z') return (wchar_t)(c + 0x20); - if (c <= 0x7F) return c; - #ifdef _WIN32 - #ifdef _UNICODE - return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); - #else - return (wchar_t)MyCharLower_WIN(c); - #endif - #else - return (wchar_t)tolower(c); - #endif -} -*/ - -// char *MyStringUpper(char *s) throw(); -// char *MyStringLower(char *s) throw(); - -// void MyStringUpper_Ascii(wchar_t *s) throw(); -void MyStringLower_Ascii(char *s) throw(); -void MyStringLower_Ascii(wchar_t *s) throw(); -// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; -// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; - -bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); - -bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); -bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); -bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw(); - -int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); -// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); - -// ---------- ASCII ---------- -// char values in ASCII strings must be less then 128 -bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); -bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); -bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); -bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); - -#define MY_STRING_DELETE(_p_) delete []_p_; -// #define MY_STRING_DELETE(_p_) my_delete(_p_); - -class AString -{ - char *_chars; - unsigned _len; - unsigned _limit; - - void MoveItems(unsigned dest, unsigned src) - { - memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); - } - - void InsertSpace(unsigned &index, unsigned size); - - void ReAlloc(unsigned newLimit); - void ReAlloc2(unsigned newLimit); - void SetStartLen(unsigned len); - void Grow_1(); - void Grow(unsigned n); - - // AString(unsigned num, const char *s); - AString(unsigned num, const AString &s); - AString(const AString &s, char c); // it's for String + char - AString(const char *s1, unsigned num1, const char *s2, unsigned num2); - - friend AString operator+(const AString &s, char c) { return AString(s, c); } ; - // friend AString operator+(char c, const AString &s); // is not supported - - friend AString operator+(const AString &s1, const AString &s2); - friend AString operator+(const AString &s1, const char *s2); - friend AString operator+(const char *s1, const AString &s2); - - // ---------- forbidden functions ---------- - AString &operator+=(wchar_t c); - AString &operator=(wchar_t c); - AString(wchar_t c); - void Find(wchar_t c) const; - void Find(wchar_t c, unsigned startIndex) const; - void ReverseFind(wchar_t c) const; - void InsertAtFront(wchar_t c); - void RemoveChar(wchar_t ch); - void Replace(wchar_t oldChar, wchar_t newChar); - -public: - AString(); - AString(char c); - AString(const char *s); - AString(const AString &s); - ~AString() { MY_STRING_DELETE(_chars); } - - unsigned Len() const { return _len; } - bool IsEmpty() const { return _len == 0; } - void Empty() { _len = 0; _chars[0] = 0; } - - operator const char *() const { return _chars; } - const char *Ptr() const { return _chars; } - const char *Ptr(unsigned pos) const { return _chars + pos; } - const char *RightPtr(unsigned num) const { return _chars + _len - num; } - char Back() const { return _chars[_len - 1]; } - - void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } - - /* GetBuf(minLen): provides the buffer that can store - at least (minLen) characters and additional null terminator. - 9.35: GetBuf doesn't preserve old characters and terminator */ - char *GetBuf(unsigned minLen) - { - if (minLen > _limit) - ReAlloc2(minLen); - return _chars; - } - char *GetBuf_SetEnd(unsigned minLen) - { - if (minLen > _limit) - ReAlloc2(minLen); - char *chars = _chars; - chars[minLen] = 0; - _len = minLen; - return chars; - } - - void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } - void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } - void ReleaseBuf_CalcLen(unsigned maxLen) - { - char *chars = _chars; - chars[maxLen] = 0; - _len = MyStringLen(chars); - } - - AString &operator=(char c); - AString &operator=(const char *s); - AString &operator=(const AString &s); - void SetFromWStr_if_Ascii(const wchar_t *s); - // void SetFromBstr_if_Ascii(BSTR s); - - AString &operator+=(char c) - { - if (_limit == _len) - Grow_1(); - unsigned len = _len; - char *chars = _chars; - chars[len++] = c; - chars[len] = 0; - _len = len; - return *this; - } - - void Add_Space(); - void Add_Space_if_NotEmpty(); - void Add_LF(); - void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); } - - AString &operator+=(const char *s); - AString &operator+=(const AString &s); - void AddAscii(const char *s) { operator+=(s); } - - void SetFrom(const char *s, unsigned len); // no check - void SetFrom_CalcLen(const char *s, unsigned len); - // void SetFromAscii(const char *s) { operator+=(s); } - - 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); } - - - bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; } - bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } - // int Compare(const char *s) const { return MyStringCompare(_chars, s); } - // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } - // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } - // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } - bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } - bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); - - bool IsAscii() const - { - unsigned len = Len(); - const char *s = _chars; - for (unsigned i = 0; i < len; i++) - if ((unsigned char)s[i] >= 0x80) - return false; - return true; - } - int Find(char c) const { return FindCharPosInString(_chars, c); } - int Find(char c, unsigned startIndex) const - { - int pos = FindCharPosInString(_chars + startIndex, c); - return pos < 0 ? -1 : (int)startIndex + pos; - } - - int ReverseFind(char c) const throw(); - int ReverseFind_Dot() const throw() { return ReverseFind('.'); } - int ReverseFind_PathSepar() const throw(); - - int Find(const char *s) const { return Find(s, 0); } - int Find(const char *s, unsigned startIndex) const throw(); - - void TrimLeft() throw(); - void TrimRight() throw(); - void Trim() - { - TrimRight(); - TrimLeft(); - } - - void InsertAtFront(char c); - // void Insert(unsigned index, char c); - void Insert(unsigned index, const char *s); - void Insert(unsigned index, const AString &s); - - void RemoveChar(char ch) throw(); - - void Replace(char oldChar, char newChar) throw(); - void Replace(const AString &oldString, const AString &newString); - - void Delete(unsigned index) throw(); - void Delete(unsigned index, unsigned count) throw(); - void DeleteFrontal(unsigned num) throw(); - void DeleteBack() { _chars[--_len] = 0; } - void DeleteFrom(unsigned index) - { - if (index < _len) - { - _len = index; - _chars[index] = 0; - } - } -}; - -bool operator<(const AString &s1, const AString &s2); -bool operator>(const AString &s1, const AString &s2); - -/* -bool operator==(const AString &s1, const AString &s2); -bool operator==(const AString &s1, const char *s2); -bool operator==(const char *s1, const AString &s2); - -bool operator!=(const AString &s1, const AString &s2); -bool operator!=(const AString &s1, const char *s2); -bool operator!=(const char *s1, const AString &s2); -*/ - -inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } -inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } -inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } - -inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } -inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } -inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } - -// ---------- forbidden functions ---------- - -void operator==(char c1, const AString &s2); -void operator==(const AString &s1, char c2); - -void operator+(char c, const AString &s); // this function can be OK, but we don't use it - -void operator+(const AString &s, int c); -void operator+(const AString &s, unsigned c); -void operator+(int c, const AString &s); -void operator+(unsigned c, const AString &s); -void operator-(const AString &s, int c); -void operator-(const AString &s, unsigned c); - - -class UString -{ - wchar_t *_chars; - unsigned _len; - unsigned _limit; - - void MoveItems(unsigned dest, unsigned src) - { - memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); - } - - void InsertSpace(unsigned index, unsigned size); - - void ReAlloc(unsigned newLimit); - void ReAlloc2(unsigned newLimit); - void SetStartLen(unsigned len); - void Grow_1(); - void Grow(unsigned n); - - UString(unsigned num, const wchar_t *s); // for Mid - UString(unsigned num, const UString &s); // for Left - UString(const UString &s, wchar_t c); // it's for String + char - UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); - - friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } ; - // friend UString operator+(wchar_t c, const UString &s); // is not supported - - friend UString operator+(const UString &s1, const UString &s2); - friend UString operator+(const UString &s1, const wchar_t *s2); - friend UString operator+(const wchar_t *s1, const UString &s2); - - // ---------- forbidden functions ---------- - - UString &operator+=(char c); - UString &operator+=(unsigned char c); - UString &operator=(char c); - UString &operator=(unsigned char c); - UString(char c); - UString(unsigned char c); - void Find(char c) const; - void Find(unsigned char c) const; - void Find(char c, unsigned startIndex) const; - void Find(unsigned char c, unsigned startIndex) const; - void ReverseFind(char c) const; - void ReverseFind(unsigned char c) const; - void InsertAtFront(char c); - void InsertAtFront(unsigned char c); - void RemoveChar(char ch); - void RemoveChar(unsigned char ch); - void Replace(char oldChar, char newChar); - void Replace(unsigned char oldChar, unsigned char newChar); - -public: - UString(); - UString(wchar_t c); - UString(const wchar_t *s); - UString(const UString &s); - ~UString() { MY_STRING_DELETE(_chars); } - - unsigned Len() const { return _len; } - bool IsEmpty() const { return _len == 0; } - void Empty() { _len = 0; _chars[0] = 0; } - - operator const wchar_t *() const { return _chars; } - const wchar_t *Ptr() const { return _chars; } - const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } - const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } - wchar_t Back() const { return _chars[_len - 1]; } - - void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } - - wchar_t *GetBuf(unsigned minLen) - { - if (minLen > _limit) - ReAlloc2(minLen); - return _chars; - } - wchar_t *GetBuf_SetEnd(unsigned minLen) - { - if (minLen > _limit) - ReAlloc2(minLen); - wchar_t *chars = _chars; - chars[minLen] = 0; - _len = minLen; - return chars; - } - - void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } - void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } - void ReleaseBuf_CalcLen(unsigned maxLen) - { - wchar_t *chars = _chars; - chars[maxLen] = 0; - _len = MyStringLen(chars); - } - - UString &operator=(wchar_t c); - UString &operator=(const wchar_t *s); - UString &operator=(const UString &s); - void SetFromBstr(BSTR s); - - UString &operator+=(wchar_t c) - { - if (_limit == _len) - Grow_1(); - unsigned len = _len; - wchar_t *chars = _chars; - chars[len++] = c; - chars[len] = 0; - _len = len; - return *this; - } - - void Add_Space(); - void Add_Space_if_NotEmpty(); - void Add_LF(); - void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); } - - UString &operator+=(const wchar_t *s); - UString &operator+=(const UString &s); - - void SetFrom(const wchar_t *s, unsigned len); // no check - - void SetFromAscii(const char *s); - void AddAscii(const char *s); - - UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } - UString Left(unsigned count) const { return UString(count, *this); } - - // void MakeUpper() { MyStringUpper(_chars); } - // void MakeUpper() { MyStringUpper_Ascii(_chars); } - // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } - void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } - - bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } - bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } - bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } - int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } - // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } - // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } - // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } - bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); } - bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); } - bool IsPrefixedBy_Ascii_NoCase(const char *s) const throw(); - - bool IsAscii() const - { - unsigned len = Len(); - const wchar_t *s = _chars; - for (unsigned i = 0; i < len; i++) - if (s[i] >= 0x80) - return false; - return true; - } - int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } - int Find(wchar_t c, unsigned startIndex) const - { - int pos = FindCharPosInString(_chars + startIndex, c); - return pos < 0 ? -1 : (int)startIndex + pos; - } - - int ReverseFind(wchar_t c) const throw(); - int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); } - int ReverseFind_PathSepar() const throw(); - - int Find(const wchar_t *s) const { return Find(s, 0); } - int Find(const wchar_t *s, unsigned startIndex) const throw(); - - void TrimLeft() throw(); - void TrimRight() throw(); - void Trim() - { - TrimRight(); - TrimLeft(); - } - - void InsertAtFront(wchar_t c); - // void Insert(unsigned index, wchar_t c); - void Insert(unsigned index, const wchar_t *s); - void Insert(unsigned index, const UString &s); - - void RemoveChar(wchar_t ch) throw(); - - void Replace(wchar_t oldChar, wchar_t newChar) throw(); - void Replace(const UString &oldString, const UString &newString); - - void Delete(unsigned index) throw(); - void Delete(unsigned index, unsigned count) throw(); - void DeleteFrontal(unsigned num) throw(); - void DeleteBack() { _chars[--_len] = 0; } - void DeleteFrom(unsigned index) - { - if (index < _len) - { - _len = index; - _chars[index] = 0; - } - } -}; - -bool operator<(const UString &s1, const UString &s2); -bool operator>(const UString &s1, const UString &s2); - -inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } -inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } -inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } - -inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } -inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } -inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } - - -// ---------- forbidden functions ---------- - -void operator==(wchar_t c1, const UString &s2); -void operator==(const UString &s1, wchar_t c2); - -void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it - -void operator+(const UString &s, char c); -void operator+(const UString &s, unsigned char c); -void operator+(char c, const UString &s); -void operator+(unsigned char c, const UString &s); -void operator-(const UString &s1, wchar_t c); - -#ifdef _WIN32 -// can we forbid these functions, if wchar_t is 32-bit ? -void operator+(const UString &s, int c); -void operator+(const UString &s, unsigned c); -void operator+(int c, const UString &s); -void operator+(unsigned c, const UString &s); -void operator-(const UString &s1, int c); -void operator-(const UString &s1, unsigned c); -#endif - - - - - - - -class UString2 -{ - wchar_t *_chars; - unsigned _len; - - void ReAlloc2(unsigned newLimit); - void SetStartLen(unsigned len); - - // ---------- forbidden functions ---------- - - UString2 &operator=(char c); - UString2 &operator=(unsigned char c); - UString2 &operator=(wchar_t c); - UString2(char c); - UString2(unsigned char c); - -public: - UString2(): _chars(NULL), _len(0) {} - // UString2(wchar_t c); - UString2(const wchar_t *s); - UString2(const UString2 &s); - ~UString2() { if (_chars) MY_STRING_DELETE(_chars); } - - unsigned Len() const { return _len; } - bool IsEmpty() const { return _len == 0; } - // void Empty() { _len = 0; _chars[0] = 0; } - - // operator const wchar_t *() const { return _chars; } - const wchar_t *GetRawPtr() const { return _chars; } - - wchar_t *GetBuf(unsigned minLen) - { - if (!_chars || minLen > _len) - ReAlloc2(minLen); - return _chars; - } - void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } - - UString2 &operator=(const wchar_t *s); - UString2 &operator=(const UString2 &s); - void SetFromAscii(const char *s); -}; - -bool operator==(const UString2 &s1, const UString2 &s2); -bool operator==(const UString2 &s1, const wchar_t *s2); -bool operator==(const wchar_t *s1, const UString2 &s2); - -inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); } -inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); } -inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); } - - -// ---------- forbidden functions ---------- - -void operator==(wchar_t c1, const UString2 &s2); -void operator==(const UString2 &s1, wchar_t c2); -bool operator<(const UString2 &s1, const UString2 &s2); -bool operator>(const UString2 &s1, const UString2 &s2); - -void operator+(const UString2 &s1, const UString2 &s2); -void operator+(const UString2 &s1, const wchar_t *s2); -void operator+(const wchar_t *s1, const UString2 &s2); -void operator+(wchar_t c, const UString2 &s); -void operator+(const UString2 &s, wchar_t c); -void operator+(const UString2 &s, char c); -void operator+(const UString2 &s, unsigned char c); -void operator+(char c, const UString2 &s); -void operator+(unsigned char c, const UString2 &s); -void operator-(const UString2 &s1, wchar_t c); - - - - - - -typedef CObjectVector AStringVector; -typedef CObjectVector UStringVector; - -#ifdef _UNICODE - typedef UString CSysString; -#else - typedef AString CSysString; -#endif - -typedef CObjectVector CSysStringVector; - - -// ---------- FString ---------- - -#ifdef _UNICODE // FIXME #ifdef _WIN32 - #define USE_UNICODE_FSTRING -#endif - -#ifdef USE_UNICODE_FSTRING - - #define __FTEXT(quote) L##quote - - typedef wchar_t FChar; - typedef UString FString; - - #define fs2us(_x_) (_x_) - #define us2fs(_x_) (_x_) - FString fas2fs(const AString &s); - AString fs2fas(const FChar *s); - -#else - - #define __FTEXT(quote) quote - - typedef char FChar; - typedef AString FString; - - UString fs2us(const FString &s); - FString us2fs(const wchar_t *s); - #define fas2fs(_x_) (_x_) - #define fs2fas(_x_) (_x_) - -#endif - -#define FTEXT(quote) __FTEXT(quote) - -#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) -#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) -#define FCHAR_ANY_MASK FTEXT('*') -#define FSTRING_ANY_MASK FTEXT("*") -typedef const FChar *CFSTR; - -typedef CObjectVector FStringVector; - -#endif +// Common/MyString.h + +#ifndef ZIP7_INC_COMMON_MY_STRING_H +#define ZIP7_INC_COMMON_MY_STRING_H + +#include + +#ifndef _WIN32 +#include +#include +#endif + +#include "Common.h" +#include "MyWindows.h" +#include "MyTypes.h" +#include "MyVector.h" + + +/* if (DEBUG_FSTRING_INHERITS_ASTRING is defined), then + FString inherits from AString, so we can find bugs related to FString at compile time. + DON'T define DEBUG_FSTRING_INHERITS_ASTRING in release code */ + +// #define DEBUG_FSTRING_INHERITS_ASTRING + +#ifdef DEBUG_FSTRING_INHERITS_ASTRING +class FString; +#endif + + +#ifdef _MSC_VER + #ifdef _NATIVE_WCHAR_T_DEFINED + #define MY_NATIVE_WCHAR_T_DEFINED + #endif +#else + #define MY_NATIVE_WCHAR_T_DEFINED +#endif + +/* + native support for wchar_t: + _MSC_VER == 1600 : /Zc:wchar_t is not supported + _MSC_VER == 1310 (VS2003) + ? _MSC_VER == 1400 (VS2005) : wchar_t <- unsigned short + /Zc:wchar_t : wchar_t <- __wchar_t, _WCHAR_T_DEFINED and _NATIVE_WCHAR_T_DEFINED + _MSC_VER > 1400 (VS2008+) + /Zc:wchar_t[-] + /Zc:wchar_t is on by default +*/ + +#ifdef _WIN32 +#define IS_PATH_SEPAR(c) ((c) == '\\' || (c) == '/') +#else +#define IS_PATH_SEPAR(c) ((c) == CHAR_PATH_SEPARATOR) +#endif + +inline bool IsPathSepar(char c) { return IS_PATH_SEPAR(c); } +inline bool IsPathSepar(wchar_t c) { return IS_PATH_SEPAR(c); } + +inline unsigned MyStringLen(const char *s) +{ + unsigned i; + for (i = 0; s[i] != 0; i++); + return i; +} + +inline void MyStringCopy(char *dest, const char *src) +{ + while ((*dest++ = *src++) != 0); +} + +inline char *MyStpCpy(char *dest, const char *src) +{ + for (;;) + { + const char c = *src; + *dest = c; + if (c == 0) + return dest; + src++; + dest++; + } +} + +inline void MyStringCat(char *dest, const char *src) +{ + for (; *dest != 0; dest++); + while ((*dest++ = *src++) != 0); + // MyStringCopy(dest + MyStringLen(dest), src); +} + +inline unsigned MyStringLen(const wchar_t *s) +{ + unsigned i; + for (i = 0; s[i] != 0; i++); + return i; +} + +inline void MyStringCopy(wchar_t *dest, const wchar_t *src) +{ + while ((*dest++ = *src++) != 0); +} + +inline void MyStringCat(wchar_t *dest, const wchar_t *src) +{ + for (; *dest != 0; dest++); + while ((*dest++ = *src++) != 0); + // MyStringCopy(dest + MyStringLen(dest), src); +} + + +/* +inline wchar_t *MyWcpCpy(wchar_t *dest, const wchar_t *src) +{ + for (;;) + { + const wchar_t c = *src; + *dest = c; + if (c == 0) + return dest; + src++; + dest++; + } +} +*/ + +int FindCharPosInString(const char *s, char c) throw(); +int FindCharPosInString(const wchar_t *s, wchar_t c) throw(); + +#ifdef _WIN32 + #ifndef _UNICODE + #define STRING_UNICODE_THROW + #endif +#endif + +#ifndef STRING_UNICODE_THROW + #define STRING_UNICODE_THROW throw() +#endif + + +inline char MyCharUpper_Ascii(char c) +{ + if (c >= 'a' && c <= 'z') + return (char)((unsigned char)c - 0x20); + return c; +} + +/* +inline wchar_t MyCharUpper_Ascii(wchar_t c) +{ + if (c >= 'a' && c <= 'z') + return (wchar_t)(c - 0x20); + return c; +} +*/ + +inline char MyCharLower_Ascii(char c) +{ + if (c >= 'A' && c <= 'Z') + return (char)((unsigned char)c + 0x20); + return c; +} + +inline wchar_t MyCharLower_Ascii(wchar_t c) +{ + if (c >= 'A' && c <= 'Z') + return (wchar_t)(c + 0x20); + return c; +} + +wchar_t MyCharUpper_WIN(wchar_t c) throw(); + +inline wchar_t MyCharUpper(wchar_t c) throw() +{ + if (c < 'a') return c; + if (c <= 'z') return (wchar_t)(c - 0x20); + if (c <= 0x7F) return c; + #ifdef _WIN32 + #ifdef _UNICODE + return (wchar_t)(unsigned)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned)c); + #else + return (wchar_t)MyCharUpper_WIN(c); + #endif + #else + return (wchar_t)towupper((wint_t)c); + #endif +} + +/* +wchar_t MyCharLower_WIN(wchar_t c) throw(); + +inline wchar_t MyCharLower(wchar_t c) throw() +{ + if (c < 'A') return c; + if (c <= 'Z') return (wchar_t)(c + 0x20); + if (c <= 0x7F) return c; + #ifdef _WIN32 + #ifdef _UNICODE + return (wchar_t)(unsigned)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned)c); + #else + return (wchar_t)MyCharLower_WIN(c); + #endif + #else + return (wchar_t)tolower(c); + #endif +} +*/ + +// char *MyStringUpper(char *s) throw(); +// char *MyStringLower(char *s) throw(); + +// void MyStringUpper_Ascii(char *s) throw(); +// void MyStringUpper_Ascii(wchar_t *s) throw(); +void MyStringLower_Ascii(char *s) throw(); +void MyStringLower_Ascii(wchar_t *s) throw(); +// wchar_t *MyStringUpper(wchar_t *s) STRING_UNICODE_THROW; +// wchar_t *MyStringLower(wchar_t *s) STRING_UNICODE_THROW; + +bool StringsAreEqualNoCase(const wchar_t *s1, const wchar_t *s2) throw(); + +bool IsString1PrefixedByString2(const char *s1, const char *s2) throw(); +bool IsString1PrefixedByString2(const wchar_t *s1, const wchar_t *s2) throw(); +bool IsString1PrefixedByString2(const wchar_t *s1, const char *s2) throw(); +bool IsString1PrefixedByString2_NoCase_Ascii(const char *s1, const char *s2) throw(); +bool IsString1PrefixedByString2_NoCase_Ascii(const wchar_t *u, const char *a) throw(); +bool IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) throw(); + +#define MyStringCompare(s1, s2) wcscmp(s1, s2) +int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) throw(); +// int MyStringCompareNoCase_N(const wchar_t *s1, const wchar_t *s2, unsigned num) throw(); + +// ---------- ASCII ---------- +// char values in ASCII strings must be less then 128 +bool StringsAreEqual_Ascii(const char *u, const char *a) throw(); +bool StringsAreEqual_Ascii(const wchar_t *u, const char *a) throw(); +bool StringsAreEqualNoCase_Ascii(const char *s1, const char *s2) throw(); +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const char *s2) throw(); +bool StringsAreEqualNoCase_Ascii(const wchar_t *s1, const wchar_t *s2) throw(); + +#define MY_STRING_DELETE(_p_) { delete [](_p_); } +// #define MY_STRING_DELETE(_p_) my_delete(_p_); + + +#define FORBID_STRING_OPS_2(cls, t) \ + void Find(t) const; \ + void Find(t, unsigned startIndex) const; \ + void ReverseFind(t) const; \ + void InsertAtFront(t); \ + void RemoveChar(t); \ + void Replace(t, t); \ + +#define FORBID_STRING_OPS(cls, t) \ + explicit cls(t); \ + explicit cls(const t *); \ + cls &operator=(t); \ + cls &operator=(const t *); \ + cls &operator+=(t); \ + cls &operator+=(const t *); \ + FORBID_STRING_OPS_2(cls, t) \ + +/* + cls &operator+(t); \ + cls &operator+(const t *); \ +*/ + +#define FORBID_STRING_OPS_AString(t) FORBID_STRING_OPS(AString, t) +#define FORBID_STRING_OPS_UString(t) FORBID_STRING_OPS(UString, t) +#define FORBID_STRING_OPS_UString2(t) FORBID_STRING_OPS(UString2, t) + +class AString +{ + char *_chars; + unsigned _len; + unsigned _limit; + + void MoveItems(unsigned dest, unsigned src) + { + memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(char)); + } + + void InsertSpace(unsigned &index, unsigned size); + + void ReAlloc(unsigned newLimit); + void ReAlloc2(unsigned newLimit); + void SetStartLen(unsigned len); + + Z7_NO_INLINE + void Grow_1(); + void Grow(unsigned n); + + AString(unsigned num, const char *s); + AString(unsigned num, const AString &s); + AString(const AString &s, char c); // it's for String + char + AString(const char *s1, unsigned num1, const char *s2, unsigned num2); + + friend AString operator+(const AString &s, char c) { return AString(s, c); } + // friend AString operator+(char c, const AString &s); // is not supported + + friend AString operator+(const AString &s1, const AString &s2); + friend AString operator+(const AString &s1, const char *s2); + friend AString operator+(const char *s1, const AString &s2); + + // ---------- forbidden functions ---------- + + #ifdef MY_NATIVE_WCHAR_T_DEFINED + FORBID_STRING_OPS_AString(wchar_t) + #endif + + FORBID_STRING_OPS_AString(signed char) + FORBID_STRING_OPS_AString(unsigned char) + FORBID_STRING_OPS_AString(short) + FORBID_STRING_OPS_AString(unsigned short) + FORBID_STRING_OPS_AString(int) + FORBID_STRING_OPS_AString(unsigned) + FORBID_STRING_OPS_AString(long) + FORBID_STRING_OPS_AString(unsigned long) + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + AString(const FString &s); + AString &operator=(const FString &s); + AString &operator+=(const FString &s); + #endif + +public: + explicit AString(); + explicit AString(char c); + explicit AString(const char *s); + AString(const AString &s); + ~AString() { MY_STRING_DELETE(_chars) } + + unsigned Len() const { return _len; } + bool IsEmpty() const { return _len == 0; } + void Empty() { _len = 0; _chars[0] = 0; } + + operator const char *() const { return _chars; } + char *Ptr_non_const() const { return _chars; } + const char *Ptr() const { return _chars; } + const char *Ptr(unsigned pos) const { return _chars + pos; } + const char *Ptr(int pos) const { return _chars + (unsigned)pos; } + const char *RightPtr(unsigned num) const { return _chars + _len - num; } + char Back() const { return _chars[(size_t)_len - 1]; } + + void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } + + char *GetBuf() { return _chars; } + /* GetBuf(minLen): provides the buffer that can store + at least (minLen) characters and additional null terminator. + 9.35: GetBuf doesn't preserve old characters and terminator */ + char *GetBuf(unsigned minLen) + { + if (minLen > _limit) + ReAlloc2(minLen); + return _chars; + } + char *GetBuf_SetEnd(unsigned minLen) + { + if (minLen > _limit) + ReAlloc2(minLen); + char *chars = _chars; + chars[minLen] = 0; + _len = minLen; + return chars; + } + + void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } + void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } + void ReleaseBuf_CalcLen(unsigned maxLen) + { + char *chars = _chars; + chars[maxLen] = 0; + _len = MyStringLen(chars); + } + + AString &operator=(char c); + AString &operator=(const char *s); + AString &operator=(const AString &s); + void SetFromWStr_if_Ascii(const wchar_t *s); + // void SetFromBstr_if_Ascii(BSTR s); + +// private: + Z7_FORCE_INLINE + AString &operator+=(char c) + { + if (_limit == _len) + Grow_1(); + unsigned len = _len; + char *chars = _chars; + chars[len++] = c; + chars[len] = 0; + _len = len; + return *this; + } +public: + void Add_Space(); + void Add_Space_if_NotEmpty(); + void Add_OptSpaced(const char *s); + void Add_Char(char c); + void Add_LF(); + void Add_Slash(); + void Add_Dot(); + void Add_Minus(); + void Add_Colon(); + void Add_PathSepar() { operator+=(CHAR_PATH_SEPARATOR); } + + AString &operator+=(const char *s); + AString &operator+=(const AString &s); + + 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_Chars_SizeT(const char* s, size_t len); // no check + void SetFrom(const char* s, int len) // no check + { + SetFrom(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); } + + + bool IsEqualTo(const char *s) const { return strcmp(_chars, s) == 0; } + bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } + // int Compare(const char *s) const { return MyStringCompare(_chars, s); } + // int Compare(const AString &s) const { return MyStringCompare(_chars, s._chars); } + // int CompareNoCase(const char *s) const { return MyStringCompareNoCase(_chars, s); } + // int CompareNoCase(const AString &s) const { return MyStringCompareNoCase(_chars, s._chars); } + bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } + bool IsPrefixedBy_Ascii_NoCase(const char *s) const { return IsString1PrefixedByString2_NoCase_Ascii(_chars, s); } + + bool IsAscii() const + { + const unsigned len = Len(); + const char *s = _chars; + for (unsigned i = 0; i < len; i++) + if ((unsigned char)s[i] >= 0x80) + return false; + return true; + } + int Find(char c) const { return FindCharPosInString(_chars, c); } + int Find(char c, unsigned startIndex) const + { + const int pos = FindCharPosInString(_chars + startIndex, c); + return pos < 0 ? -1 : (int)startIndex + pos; + } + int Find(char c, int startIndex) const + { + return Find(c, (unsigned)startIndex); + } + + int ReverseFind(char c) const throw(); + int ReverseFind_Dot() const throw() { return ReverseFind('.'); } + int ReverseFind_PathSepar() const throw(); + + int Find(const char *s) const { return Find(s, 0); } + int Find(const char *s, unsigned startIndex) const throw(); + + void TrimLeft() throw(); + void TrimRight() throw(); + void Trim() + { + TrimRight(); + TrimLeft(); + } + + void InsertAtFront(char c); + // void Insert(unsigned index, char c); + void Insert(unsigned index, const char *s); + void Insert(unsigned index, const AString &s); + + void RemoveChar(char ch) throw(); + + void Replace(char oldChar, char newChar) throw(); + void Replace(const AString &oldString, const AString &newString); + + void Delete(unsigned index) throw(); + void Delete(unsigned index, unsigned count) throw(); + void DeleteFrontal(unsigned num) throw(); + void DeleteBack() { _chars[--_len] = 0; } + void DeleteFrom(unsigned index) + { + if (index < _len) + { + _len = index; + _chars[index] = 0; + } + } + void DeleteFrom(int index) + { + DeleteFrom((unsigned)index); + } + + + void Wipe_and_Empty() + { + if (_chars) + { + memset(_chars, 0, (_limit + 1) * sizeof(*_chars)); + _len = 0; + } + } +}; + + +class AString_Wipe: public AString +{ + Z7_CLASS_NO_COPY(AString_Wipe) +public: + AString_Wipe(): AString() {} + // AString_Wipe(const AString &s): AString(s) {} + // AString_Wipe &operator=(const AString &s) { AString::operator=(s); return *this; } + // AString_Wipe &operator=(const char *s) { AString::operator=(s); return *this; } + ~AString_Wipe() { Wipe_and_Empty(); } +}; + + +bool operator<(const AString &s1, const AString &s2); +bool operator>(const AString &s1, const AString &s2); + +/* +bool operator==(const AString &s1, const AString &s2); +bool operator==(const AString &s1, const char *s2); +bool operator==(const char *s1, const AString &s2); + +bool operator!=(const AString &s1, const AString &s2); +bool operator!=(const AString &s1, const char *s2); +bool operator!=(const char *s1, const AString &s2); +*/ + +inline bool operator==(const AString &s1, const AString &s2) { return s1.Len() == s2.Len() && strcmp(s1, s2) == 0; } +inline bool operator==(const AString &s1, const char *s2) { return strcmp(s1, s2) == 0; } +inline bool operator==(const char *s1, const AString &s2) { return strcmp(s1, s2) == 0; } + +inline bool operator!=(const AString &s1, const AString &s2) { return s1.Len() != s2.Len() || strcmp(s1, s2) != 0; } +inline bool operator!=(const AString &s1, const char *s2) { return strcmp(s1, s2) != 0; } +inline bool operator!=(const char *s1, const AString &s2) { return strcmp(s1, s2) != 0; } + +// ---------- forbidden functions ---------- + +void operator==(char c1, const AString &s2); +void operator==(const AString &s1, char c2); + +void operator+(char c, const AString &s); // this function can be OK, but we don't use it + +void operator+(const AString &s, int c); +void operator+(const AString &s, unsigned c); +void operator+(int c, const AString &s); +void operator+(unsigned c, const AString &s); +void operator-(const AString &s, int c); +void operator-(const AString &s, unsigned c); + + +class UString +{ + wchar_t *_chars; + unsigned _len; + unsigned _limit; + + void MoveItems(unsigned dest, unsigned src) + { + memmove(_chars + dest, _chars + src, (size_t)(_len - src + 1) * sizeof(wchar_t)); + } + + void InsertSpace(unsigned index, unsigned size); + + void ReAlloc(unsigned newLimit); + void ReAlloc2(unsigned newLimit); + void SetStartLen(unsigned len); + void Grow_1(); + void Grow(unsigned n); + + UString(unsigned num, const wchar_t *s); // for Mid + UString(unsigned num, const UString &s); // for Left + UString(const UString &s, wchar_t c); // it's for String + char + UString(const wchar_t *s1, unsigned num1, const wchar_t *s2, unsigned num2); + + friend UString operator+(const UString &s, wchar_t c) { return UString(s, c); } + // friend UString operator+(wchar_t c, const UString &s); // is not supported + + friend UString operator+(const UString &s1, const UString &s2); + friend UString operator+(const UString &s1, const wchar_t *s2); + friend UString operator+(const wchar_t *s1, const UString &s2); + + // ---------- forbidden functions ---------- + + FORBID_STRING_OPS_UString(signed char) + FORBID_STRING_OPS_UString(unsigned char) + FORBID_STRING_OPS_UString(short) + + #ifdef MY_NATIVE_WCHAR_T_DEFINED + FORBID_STRING_OPS_UString(unsigned short) + #endif + + FORBID_STRING_OPS_UString(int) + FORBID_STRING_OPS_UString(unsigned) + FORBID_STRING_OPS_UString(long) + FORBID_STRING_OPS_UString(unsigned long) + + FORBID_STRING_OPS_2(UString, char) + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + UString(const FString &s); + UString &operator=(const FString &s); + UString &operator+=(const FString &s); + #endif + +public: + UString(); + explicit UString(wchar_t c); + explicit UString(char c); + explicit UString(const char *s); + explicit UString(const AString &s); + UString(const wchar_t *s); + UString(const UString &s); + ~UString() { MY_STRING_DELETE(_chars) } + + unsigned Len() const { return _len; } + bool IsEmpty() const { return _len == 0; } + void Empty() { _len = 0; _chars[0] = 0; } + + operator const wchar_t *() const { return _chars; } + wchar_t *Ptr_non_const() const { return _chars; } + const wchar_t *Ptr() const { return _chars; } + const wchar_t *Ptr(int pos) const { return _chars + (unsigned)pos; } + const wchar_t *Ptr(unsigned pos) const { return _chars + pos; } + const wchar_t *RightPtr(unsigned num) const { return _chars + _len - num; } + wchar_t Back() const { return _chars[(size_t)_len - 1]; } + + void ReplaceOneCharAtPos(unsigned pos, wchar_t c) { _chars[pos] = c; } + + wchar_t *GetBuf() { return _chars; } + + /* + wchar_t *GetBuf_GetMaxAvail(unsigned &availBufLen) + { + availBufLen = _limit; + return _chars; + } + */ + + wchar_t *GetBuf(unsigned minLen) + { + if (minLen > _limit) + ReAlloc2(minLen); + return _chars; + } + wchar_t *GetBuf_SetEnd(unsigned minLen) + { + if (minLen > _limit) + ReAlloc2(minLen); + wchar_t *chars = _chars; + chars[minLen] = 0; + _len = minLen; + return chars; + } + + void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } + void ReleaseBuf_SetEnd(unsigned newLen) { _len = newLen; _chars[newLen] = 0; } + void ReleaseBuf_CalcLen(unsigned maxLen) + { + wchar_t *chars = _chars; + chars[maxLen] = 0; + _len = MyStringLen(chars); + } + + UString &operator=(wchar_t c); + UString &operator=(char c) { return (*this)=((wchar_t)(unsigned char)c); } + UString &operator=(const wchar_t *s); + UString &operator=(const UString &s); + void SetFrom(const wchar_t *s, unsigned len); // no check + void SetFromBstr(LPCOLESTR s); + UString &operator=(const char *s); + UString &operator=(const AString &s) { return operator=(s.Ptr()); } + +// private: + Z7_FORCE_INLINE + UString &operator+=(wchar_t c) + { + if (_limit == _len) + Grow_1(); + unsigned len = _len; + wchar_t *chars = _chars; + chars[len++] = c; + chars[len] = 0; + _len = len; + return *this; + } + +private: + UString &operator+=(char c); // { return (*this)+=((wchar_t)(unsigned char)c); } +public: + void Add_Char(char c); + // void Add_WChar(wchar_t c); + void Add_Space(); + void Add_Space_if_NotEmpty(); + void Add_LF(); + void Add_Dot(); + void Add_Minus(); + void Add_Colon(); + void Add_PathSepar() { operator+=(WCHAR_PATH_SEPARATOR); } + + UString &operator+=(const wchar_t *s); + UString &operator+=(const UString &s); + UString &operator+=(const char *s); + UString &operator+=(const AString &s) { return operator+=(s.Ptr()); } + + void Add_UInt32(UInt32 v); + void Add_UInt64(UInt64 v); + + UString Mid(unsigned startIndex, unsigned count) const { return UString(count, _chars + startIndex); } + UString Left(unsigned count) const { return UString(count, *this); } + UString Left(int count) const { return Left((unsigned)count); } + + // void MakeUpper() { MyStringUpper(_chars); } + // void MakeUpper() { MyStringUpper_Ascii(_chars); } + // void MakeUpper_Ascii() { MyStringUpper_Ascii(_chars); } + void MakeLower_Ascii() { MyStringLower_Ascii(_chars); } + + bool IsEqualTo(const char *s) const { return StringsAreEqual_Ascii(_chars, s); } + bool IsEqualTo_NoCase(const wchar_t *s) const { return StringsAreEqualNoCase(_chars, s); } + bool IsEqualTo_Ascii_NoCase(const char *s) const { return StringsAreEqualNoCase_Ascii(_chars, s); } + int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } + // int Compare(const UString &s) const { return MyStringCompare(_chars, s._chars); } + // int CompareNoCase(const wchar_t *s) const { return MyStringCompareNoCase(_chars, s); } + // int CompareNoCase(const UString &s) const { return MyStringCompareNoCase(_chars, s._chars); } + bool IsPrefixedBy(const wchar_t *s) const { return IsString1PrefixedByString2(_chars, s); } + bool IsPrefixedBy(const char *s) const { return IsString1PrefixedByString2(_chars, s); } + bool IsPrefixedBy_NoCase(const wchar_t *s) const { return IsString1PrefixedByString2_NoCase(_chars, s); } + bool IsPrefixedBy_Ascii_NoCase(const char *s) const { return IsString1PrefixedByString2_NoCase_Ascii(_chars, s); } + + bool IsAscii() const + { + const unsigned len = Len(); + const wchar_t *s = _chars; + for (unsigned i = 0; i < len; i++) + if ((unsigned)(int)s[i] >= 0x80) + return false; + return true; + } + int Find(wchar_t c) const { return FindCharPosInString(_chars, c); } + int Find(wchar_t c, unsigned startIndex) const + { + const int pos = FindCharPosInString(_chars + startIndex, c); + return pos < 0 ? -1 : (int)startIndex + pos; + } + + int ReverseFind(wchar_t c) const throw(); + int ReverseFind_Dot() const throw() { return ReverseFind(L'.'); } + int ReverseFind_PathSepar() const throw(); + + int Find(const wchar_t *s) const { return Find(s, 0); } + int Find(const wchar_t *s, unsigned startIndex) const throw(); + + void TrimLeft() throw(); + void TrimRight() throw(); + void Trim() + { + TrimRight(); + TrimLeft(); + } + + void InsertAtFront(wchar_t c); + // void Insert_wchar_t(unsigned index, wchar_t c); + void Insert(unsigned index, const wchar_t *s); + void Insert(unsigned index, const UString &s); + + void RemoveChar(wchar_t ch) throw(); + + void Replace(wchar_t oldChar, wchar_t newChar) throw(); + void Replace(const UString &oldString, const UString &newString); + + void Delete(int index) throw() { Delete((unsigned)index); } + void Delete(unsigned index) throw(); + void Delete(unsigned index, unsigned count) throw(); + void DeleteFrontal(unsigned num) throw(); + void DeleteBack() { _chars[--_len] = 0; } + void DeleteFrom(int index) { DeleteFrom((unsigned)index); } + void DeleteFrom(unsigned index) + { + if (index < _len) + { + _len = index; + _chars[index] = 0; + } + } + + void Wipe_and_Empty() + { + if (_chars) + { + memset(_chars, 0, (_limit + 1) * sizeof(*_chars)); + _len = 0; + } + } +}; + + +class UString_Wipe: public UString +{ + Z7_CLASS_NO_COPY(UString_Wipe) +public: + UString_Wipe(): UString() {} + // UString_Wipe(const UString &s): UString(s) {} + // UString_Wipe &operator=(const UString &s) { UString::operator=(s); return *this; } + // UString_Wipe &operator=(const wchar_t *s) { UString::operator=(s); return *this; } + ~UString_Wipe() { Wipe_and_Empty(); } +}; + + +bool operator<(const UString &s1, const UString &s2); +bool operator>(const UString &s1, const UString &s2); + +inline bool operator==(const UString &s1, const UString &s2) { return s1.Len() == s2.Len() && wcscmp(s1, s2) == 0; } +inline bool operator==(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) == 0; } +inline bool operator==(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) == 0; } + +inline bool operator!=(const UString &s1, const UString &s2) { return s1.Len() != s2.Len() || wcscmp(s1, s2) != 0; } +inline bool operator!=(const UString &s1, const wchar_t *s2) { return wcscmp(s1, s2) != 0; } +inline bool operator!=(const wchar_t *s1, const UString &s2) { return wcscmp(s1, s2) != 0; } + + +// ---------- forbidden functions ---------- + +void operator==(wchar_t c1, const UString &s2); +void operator==(const UString &s1, wchar_t c2); + +void operator+(wchar_t c, const UString &s); // this function can be OK, but we don't use it + +void operator+(const AString &s1, const UString &s2); +void operator+(const UString &s1, const AString &s2); + +void operator+(const UString &s1, const char *s2); +void operator+(const char *s1, const UString &s2); + +void operator+(const UString &s, char c); +void operator+(const UString &s, unsigned char c); +void operator+(char c, const UString &s); +void operator+(unsigned char c, const UString &s); +void operator-(const UString &s1, wchar_t c); + +#ifdef _WIN32 +// can we forbid these functions, if wchar_t is 32-bit ? +void operator+(const UString &s, int c); +void operator+(const UString &s, unsigned c); +void operator+(int c, const UString &s); +void operator+(unsigned c, const UString &s); +void operator-(const UString &s1, int c); +void operator-(const UString &s1, unsigned c); +#endif + + + + + + + +class UString2 +{ + wchar_t *_chars; + unsigned _len; + + void ReAlloc2(unsigned newLimit); + void SetStartLen(unsigned len); + + // ---------- forbidden functions ---------- + + FORBID_STRING_OPS_UString2(char) + FORBID_STRING_OPS_UString2(signed char) + FORBID_STRING_OPS_UString2(unsigned char) + FORBID_STRING_OPS_UString2(short) + + UString2 &operator=(wchar_t c); + + UString2(const AString &s); + UString2 &operator=(const AString &s); + UString2 &operator+=(const AString &s); + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + UString2(const FString &s); + UString2 &operator=(const FString &s); + UString2 &operator+=(const FString &s); + #endif + +public: + UString2(): _chars(NULL), _len(0) {} + UString2(const wchar_t *s); + UString2(const UString2 &s); + ~UString2() { if (_chars) { MY_STRING_DELETE(_chars) } } + + unsigned Len() const { return _len; } + bool IsEmpty() const { return _len == 0; } + // void Empty() { _len = 0; _chars[0] = 0; } + + // operator const wchar_t *() const { return _chars; } + const wchar_t *GetRawPtr() const { return _chars; } + + int Compare(const wchar_t *s) const { return wcscmp(_chars, s); } + + wchar_t *GetBuf(unsigned minLen) + { + if (!_chars || minLen > _len) + ReAlloc2(minLen); + return _chars; + } + void ReleaseBuf_SetLen(unsigned newLen) { _len = newLen; } + + UString2 &operator=(const wchar_t *s); + UString2 &operator=(const UString2 &s); + void SetFromAscii(const char *s); +}; + +bool operator==(const UString2 &s1, const UString2 &s2); +bool operator==(const UString2 &s1, const wchar_t *s2); +bool operator==(const wchar_t *s1, const UString2 &s2); + +inline bool operator!=(const UString2 &s1, const UString2 &s2) { return !(s1 == s2); } +inline bool operator!=(const UString2 &s1, const wchar_t *s2) { return !(s1 == s2); } +inline bool operator!=(const wchar_t *s1, const UString2 &s2) { return !(s1 == s2); } + + +// ---------- forbidden functions ---------- + +void operator==(wchar_t c1, const UString2 &s2); +void operator==(const UString2 &s1, wchar_t c2); +bool operator<(const UString2 &s1, const UString2 &s2); +bool operator>(const UString2 &s1, const UString2 &s2); + +void operator+(const UString2 &s1, const UString2 &s2); +void operator+(const UString2 &s1, const wchar_t *s2); +void operator+(const wchar_t *s1, const UString2 &s2); +void operator+(wchar_t c, const UString2 &s); +void operator+(const UString2 &s, wchar_t c); +void operator+(const UString2 &s, char c); +void operator+(const UString2 &s, unsigned char c); +void operator+(char c, const UString2 &s); +void operator+(unsigned char c, const UString2 &s); +void operator-(const UString2 &s1, wchar_t c); + + + + + + +typedef CObjectVector AStringVector; +typedef CObjectVector UStringVector; + +#ifdef _UNICODE + typedef UString CSysString; +#else + typedef AString CSysString; +#endif + +typedef CObjectVector CSysStringVector; + + +// ---------- FString ---------- + +#ifndef DEBUG_FSTRING_INHERITS_ASTRING +#ifdef _WIN32 + #define USE_UNICODE_FSTRING +#endif +#endif + +#ifdef USE_UNICODE_FSTRING + + #define MY_FTEXT(quote) L##quote + + typedef wchar_t FChar; + typedef UString FString; + + #define fs2us(_x_) (_x_) + #define us2fs(_x_) (_x_) + FString fas2fs(const char *s); + FString fas2fs(const AString &s); + AString fs2fas(const FChar *s); + +#else // USE_UNICODE_FSTRING + + #define MY_FTEXT(quote) quote + + typedef char FChar; + + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + + class FString: public AString + { + // FString &operator=(const char *s); + FString &operator=(const AString &s); + // FString &operator+=(const AString &s); + public: + FString(const AString &s): AString(s.Ptr()) {} + FString(const FString &s): AString(s.Ptr()) {} + FString(const char *s): AString(s) {} + FString() {} + FString &operator=(const FString &s) { AString::operator=((const AString &)s); return *this; } + FString &operator=(char c) { AString::operator=(c); return *this; } + FString &operator+=(char c) { AString::operator+=(c); return *this; } + FString &operator+=(const FString &s) { AString::operator+=((const AString &)s); return *this; } + FString Left(unsigned count) const { return FString(AString::Left(count)); } + }; + void operator+(const AString &s1, const FString &s2); + void operator+(const FString &s1, const AString &s2); + + inline FString operator+(const FString &s1, const FString &s2) + { + AString s =(const AString &)s1 + (const AString &)s2; + return FString(s.Ptr()); + // return FString((const AString &)s1 + (const AString &)s2); + } + inline FString operator+(const FString &s1, const FChar *s2) + { + return s1 + (FString)s2; + } + /* + inline FString operator+(const FChar *s1, const FString &s2) + { + return (FString)s1 + s2; + } + */ + + inline FString fas2fs(const char *s) { return FString(s); } + + #else // DEBUG_FSTRING_INHERITS_ASTRING + typedef AString FString; + #define fas2fs(_x_) (_x_) + #endif // DEBUG_FSTRING_INHERITS_ASTRING + + UString fs2us(const FChar *s); + UString fs2us(const FString &s); + FString us2fs(const wchar_t *s); + #define fs2fas(_x_) (_x_) + +#endif // USE_UNICODE_FSTRING + +#define FTEXT(quote) MY_FTEXT(quote) + +#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR) +#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR) + +// #define FCHAR_ANY_MASK FTEXT('*') +// #define FSTRING_ANY_MASK FTEXT("*") + +typedef const FChar *CFSTR; + +typedef CObjectVector FStringVector; + + +class CStringFinder +{ + AString _temp; +public: + // list - is list of low case Ascii strings separated by space " ". + // the function returns true, if it can find exact word (str) in (list). + bool FindWord_In_LowCaseAsciiList_NoCase(const char *list, const wchar_t *str); +}; + +void SplitString(const UString &srcString, UStringVector &destStrings); + +#endif + + + +#if defined(_WIN32) + // #include + // WCHAR_MAX is defined as ((wchar_t)-1) + #define Z7_WCHART_IS_16BIT 1 +#elif (defined(WCHAR_MAX) && (WCHAR_MAX <= 0xffff)) \ + || (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ == 2)) + #define Z7_WCHART_IS_16BIT 1 +#endif + +#if WCHAR_PATH_SEPARATOR == L'\\' +// WSL scheme +#define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT ((wchar_t)((unsigned)(0xF000) + (unsigned)'\\')) +// #define WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT '_' +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyTypes.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyTypes.h --- p7zip-rar-16.02/CPP/Common/MyTypes.h 2015-06-19 12:49:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyTypes.h 2024-01-26 10:00:00.000000000 +0000 @@ -1,38 +1,38 @@ -// Common/MyTypes.h - -#ifndef __COMMON_MY_TYPES_H -#define __COMMON_MY_TYPES_H - -#include "../../C/7zTypes.h" - -typedef int HRes; - -#ifdef __cplusplus -struct CBoolPair -{ - bool Val; - bool Def; - - CBoolPair(): Val(false), Def(false) {} - - void Init() - { - Val = false; - Def = false; - } - - void SetTrueTrue() - { - Val = true; - Def = true; - } -}; - -#define CLASS_NO_COPY(cls) \ - private: \ - cls(const cls &); \ - cls &operator=(const cls &); - -#endif - -#endif +// Common/MyTypes.h + +#ifndef ZIP7_INC_COMMON_MY_TYPES_H +#define ZIP7_INC_COMMON_MY_TYPES_H + +#include "Common0.h" +#include "../../C/7zTypes.h" + +// typedef int HRes; +// typedef HRESULT HRes; + +struct CBoolPair +{ + bool Val; + bool Def; + + CBoolPair(): Val(false), Def(false) {} + + void Init() + { + Val = false; + Def = false; + } + + void SetTrueTrue() + { + Val = true; + Def = true; + } + + void SetVal_as_Defined(bool val) + { + Val = val; + Def = true; + } +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyUnknown.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyUnknown.h --- p7zip-rar-16.02/CPP/Common/MyUnknown.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyUnknown.h 2023-03-18 16:00:00.000000000 +0000 @@ -1,17 +1,8 @@ -// MyUnknown.h - -#ifndef __MY_UNKNOWN_H -#define __MY_UNKNOWN_H - -#include "MyWindows.h" - -/* -#ifdef _WIN32 -#include -#include -#else -#include "MyWindows.h" -#endif -*/ - -#endif +// MyUnknown.h + +#ifndef ZIP7_INC_MY_UNKNOWN_H +#define ZIP7_INC_MY_UNKNOWN_H + +#include "MyWindows.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyVector.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.cpp --- p7zip-rar-16.02/CPP/Common/MyVector.cpp 2015-10-20 18:48:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.cpp 2011-11-27 17:08:55.000000000 +0000 @@ -1,3 +1,3 @@ -// Common/MyVector.cpp - -#include "StdAfx.h" +// Common/MyVector.cpp + +#include "StdAfx.h" diff -Nru p7zip-rar-16.02/CPP/Common/MyVector.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.h --- p7zip-rar-16.02/CPP/Common/MyVector.h 2015-10-20 18:48:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyVector.h 2024-01-22 11:00:00.000000000 +0000 @@ -1,626 +1,724 @@ -// Common/MyVector.h - -#ifndef __COMMON_MY_VECTOR_H -#define __COMMON_MY_VECTOR_H - -#include - -template -class CRecordVector -{ - T *_items; - unsigned _size; - unsigned _capacity; - - void MoveItems(unsigned destIndex, unsigned srcIndex) - { - memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); - } - - void ReserveOnePosition() - { - if (_size == _capacity) - { - unsigned newCapacity = _capacity + (_capacity >> 2) + 1; - T *p = new T[newCapacity]; - if (_size != 0) - memcpy(p, _items, (size_t)_size * sizeof(T)); - delete []_items; - _items = p; - _capacity = newCapacity; - } - } - -public: - - CRecordVector(): _items(0), _size(0), _capacity(0) {} - - CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0) - { - unsigned size = v.Size(); - if (size != 0) - { - _items = new T[size]; - _size = size; - _capacity = size; - memcpy(_items, v._items, (size_t)size * sizeof(T)); - } - } - - unsigned Size() const { return _size; } - bool IsEmpty() const { return _size == 0; } - - void ConstructReserve(unsigned size) - { - if (size != 0) - { - _items = new T[size]; - _capacity = size; - } - } - - void Reserve(unsigned newCapacity) - { - if (newCapacity > _capacity) - { - T *p = new T[newCapacity]; - if (_size != 0) - memcpy(p, _items, (size_t)_size * sizeof(T)); - delete []_items; - _items = p; - _capacity = newCapacity; - } - } - - void ClearAndReserve(unsigned newCapacity) - { - Clear(); - if (newCapacity > _capacity) - { - delete []_items; - _items = NULL; - _capacity = 0; - _items = new T[newCapacity]; - _capacity = newCapacity; - } - } - - void ClearAndSetSize(unsigned newSize) - { - ClearAndReserve(newSize); - _size = newSize; - } - - void ChangeSize_KeepData(unsigned newSize) - { - if (newSize > _capacity) - { - T *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) - return; - T *p = NULL; - if (_size != 0) - { - p = new T[_size]; - memcpy(p, _items, (size_t)_size * sizeof(T)); - } - delete []_items; - _items = p; - _capacity = _size; - } - - ~CRecordVector() { delete []_items; } - - void ClearAndFree() - { - delete []_items; - _items = NULL; - _size = 0; - _capacity = 0; - } - - void Clear() { _size = 0; } - - void DeleteBack() { _size--; } - - void DeleteFrom(unsigned index) - { - // if (index <= _size) - _size = index; - } - - void DeleteFrontal(unsigned num) - { - if (num != 0) - { - MoveItems(0, num); - _size -= num; - } - } - - void Delete(unsigned index) - { - MoveItems(index, index + 1); - _size -= 1; - } - - /* - void Delete(unsigned index, unsigned num) - { - if (num > 0) - { - MoveItems(index, index + num); - _size -= num; - } - } - */ - - CRecordVector& operator=(const CRecordVector &v) - { - if (&v == this) - return *this; - unsigned size = v.Size(); - if (size > _capacity) - { - delete []_items; - _capacity = 0; - _size = 0; - _items = NULL; - _items = new T[size]; - _capacity = size; - } - _size = size; - if (size != 0) - memcpy(_items, v._items, (size_t)size * sizeof(T)); - return *this; - } - - CRecordVector& operator+=(const CRecordVector &v) - { - unsigned size = v.Size(); - Reserve(_size + size); - if (size != 0) - memcpy(_items + _size, v._items, (size_t)size * sizeof(T)); - _size += size; - return *this; - } - - unsigned Add(const T item) - { - ReserveOnePosition(); - _items[_size] = item; - return _size++; - } - - void AddInReserved(const T item) - { - _items[_size++] = item; - } - - void Insert(unsigned index, const T item) - { - ReserveOnePosition(); - MoveItems(index + 1, index); - _items[index] = item; - _size++; - } - - void MoveToFront(unsigned index) - { - if (index != 0) - { - T temp = _items[index]; - memmove(_items + 1, _items, (size_t)index * sizeof(T)); - _items[0] = temp; - } - } - - const T& operator[](unsigned index) const { return _items[index]; } - T& operator[](unsigned index) { return _items[index]; } - const T& Front() const { return _items[0]; } - T& Front() { return _items[0]; } - const T& Back() const { return _items[_size - 1]; } - T& Back() { return _items[_size - 1]; } - - /* - void Swap(unsigned i, unsigned j) - { - T temp = _items[i]; - _items[i] = _items[j]; - _items[j] = temp; - } - */ - - int FindInSorted(const T item, unsigned left, unsigned right) const - { - while (left != right) - { - unsigned mid = (left + right) / 2; - const T midVal = (*this)[mid]; - if (item == midVal) - return mid; - if (item < midVal) - right = mid; - else - left = mid + 1; - } - return -1; - } - - int FindInSorted2(const T &item, unsigned left, unsigned right) const - { - while (left != right) - { - unsigned mid = (left + right) / 2; - const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); - if (comp == 0) - return mid; - if (comp < 0) - right = mid; - else - left = mid + 1; - } - return -1; - } - - int FindInSorted(const T item) const - { - return FindInSorted(item, 0, _size); - } - - int FindInSorted2(const T &item) const - { - return FindInSorted2(item, 0, _size); - } - - unsigned AddToUniqueSorted(const T item) - { - unsigned left = 0, right = _size; - while (left != right) - { - unsigned mid = (left + right) / 2; - const T midVal = (*this)[mid]; - if (item == midVal) - return mid; - if (item < midVal) - right = mid; - else - left = mid + 1; - } - Insert(right, item); - return right; - } - - unsigned AddToUniqueSorted2(const T &item) - { - unsigned left = 0, right = _size; - while (left != right) - { - unsigned mid = (left + right) / 2; - const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); - if (comp == 0) - return mid; - if (comp < 0) - right = mid; - else - left = mid + 1; - } - Insert(right, item); - return right; - } - - static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param) - { - T temp = p[k]; - for (;;) - { - unsigned s = (k << 1); - if (s > size) - break; - if (s < size && compare(p + s + 1, p + s, param) > 0) - s++; - if (compare(&temp, p + s, param) >= 0) - break; - p[k] = p[s]; - k = s; - } - p[k] = temp; - } - - void Sort(int (*compare)(const T*, const T*, void *), void *param) - { - unsigned size = _size; - if (size <= 1) - return; - T* p = (&Front()) - 1; - { - unsigned i = size >> 1; - do - SortRefDown(p, i, size, compare, param); - while (--i != 0); - } - do - { - T temp = p[size]; - p[size--] = p[1]; - p[1] = temp; - SortRefDown(p, 1, size, compare, param); - } - while (size > 1); - } - - static void SortRefDown2(T* p, unsigned k, unsigned size) - { - T temp = p[k]; - for (;;) - { - unsigned s = (k << 1); - if (s > size) - break; - if (s < size && p[s + 1].Compare(p[s]) > 0) - s++; - if (temp.Compare(p[s]) >= 0) - break; - p[k] = p[s]; - k = s; - } - p[k] = temp; - } - - void Sort2() - { - unsigned size = _size; - if (size <= 1) - return; - T* p = (&Front()) - 1; - { - unsigned i = size >> 1; - do - SortRefDown2(p, i, size); - while (--i != 0); - } - do - { - T temp = p[size]; - p[size--] = p[1]; - p[1] = temp; - SortRefDown2(p, 1, size); - } - while (size > 1); - } -}; - -typedef CRecordVector CIntVector; -typedef CRecordVector CUIntVector; -typedef CRecordVector CBoolVector; -typedef CRecordVector CByteVector; -typedef CRecordVector CPointerVector; - -template -class CObjectVector -{ - CPointerVector _v; -public: - unsigned Size() const { return _v.Size(); } - bool IsEmpty() const { return _v.IsEmpty(); } - void ReserveDown() { _v.ReserveDown(); } - // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); } - void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); } - - CObjectVector() {}; - CObjectVector(const CObjectVector &v) - { - unsigned size = v.Size(); - _v.ConstructReserve(size); - for (unsigned i = 0; i < size; i++) - _v.AddInReserved(new T(v[i])); - } - CObjectVector& operator=(const CObjectVector &v) - { - if (&v == this) - return *this; - Clear(); - unsigned size = v.Size(); - _v.Reserve(size); - for (unsigned i = 0; i < size; i++) - _v.AddInReserved(new T(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])); - return *this; - } - - const T& operator[](unsigned index) const { return *((T *)_v[index]); } - T& operator[](unsigned index) { return *((T *)_v[index]); } - const T& Front() const { return operator[](0); } - T& Front() { return operator[](0); } - const T& Back() const { return operator[](_v.Size() - 1); } - T& Back() { return operator[](_v.Size() - 1); } - - void MoveToFront(unsigned index) { _v.MoveToFront(index); } - - unsigned Add(const T& item) { return _v.Add(new T(item)); } - - void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); } - - T& AddNew() - { - T *p = new T; - _v.Add(p); - return *p; - } - - T& AddNewInReserved() - { - T *p = new T; - _v.AddInReserved(p); - return *p; - } - - void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); } - - T& InsertNew(unsigned index) - { - T *p = new T; - _v.Insert(index, p); - return *p; - } - - ~CObjectVector() - { - for (unsigned i = _v.Size(); i != 0;) - delete (T *)_v[--i]; - } - - void ClearAndFree() - { - Clear(); - _v.ClearAndFree(); - } - - void Clear() - { - for (unsigned i = _v.Size(); i != 0;) - delete (T *)_v[--i]; - _v.Clear(); - } - - void DeleteFrom(unsigned index) - { - unsigned size = _v.Size(); - for (unsigned i = index; i < size; i++) - delete (T *)_v[i]; - _v.DeleteFrom(index); - } - - void DeleteFrontal(unsigned num) - { - for (unsigned i = 0; i < num; i++) - delete (T *)_v[i]; - _v.DeleteFrontal(num); - } - - void DeleteBack() - { - delete (T *)_v[_v.Size() - 1]; - _v.DeleteBack(); - } - - void Delete(unsigned index) - { - delete (T *)_v[index]; - _v.Delete(index); - } - - /* - void Delete(unsigned index, unsigned num) - { - for (unsigned i = 0; i < num; i++) - delete (T *)_v[index + i]; - _v.Delete(index, num); - } - */ - - /* - int Find(const T& item) const - { - unsigned size = Size(); - for (unsigned i = 0; i < size; i++) - if (item == (*this)[i]) - return i; - return -1; - } - */ - - int FindInSorted(const T& item) const - { - unsigned left = 0, right = Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); - if (comp == 0) - return mid; - if (comp < 0) - right = mid; - else - left = mid + 1; - } - return -1; - } - - unsigned AddToUniqueSorted(const T& item) - { - unsigned left = 0, right = Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); - if (comp == 0) - return mid; - if (comp < 0) - right = mid; - else - left = mid + 1; - } - Insert(right, item); - return right; - } - - /* - unsigned AddToSorted(const T& item) - { - unsigned left = 0, right = Size(); - while (left != right) - { - unsigned mid = (left + right) / 2; - const T& midVal = (*this)[mid]; - int comp = item.Compare(midVal); - if (comp == 0) - { - right = mid + 1; - break; - } - if (comp < 0) - right = mid; - else - left = mid + 1; - } - Insert(right, item); - return right; - } - */ - - void Sort(int (*compare)(void *const *, void *const *, void *), void *param) - { _v.Sort(compare, param); } - - static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) - { return (*(*((const T **)a1))).Compare(*(*((const T **)a2))); } - - void Sort() { _v.Sort(CompareObjectItems, 0); } -}; - -#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++) - -#endif +// Common/MyVector.h + +#ifndef ZIP7_INC_COMMON_MY_VECTOR_H +#define ZIP7_INC_COMMON_MY_VECTOR_H + +#include + +#include "Common.h" + +const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1; + +template +class CRecordVector +{ + T *_items; + unsigned _size; + unsigned _capacity; + + void MoveItems(unsigned destIndex, unsigned srcIndex) + { + memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); + } + + void ReAllocForNewCapacity(const unsigned newCapacity) + { + T *p; + Z7_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(NULL), _size(0), _capacity(0) + { + const unsigned size = v.Size(); + if (size != 0) + { + // Z7_ARRAY_NEW(_items, T, size) + _items = new T[size]; + _size = size; + _capacity = size; + memcpy(_items, v._items, (size_t)size * sizeof(T)); + } + } + + unsigned Size() const { return _size; } + bool IsEmpty() const { return _size == 0; } + + void ConstructReserve(unsigned size) + { + if (size != 0) + { + Z7_ARRAY_NEW(_items, T, size) + // _items = new T[size]; + _capacity = size; + } + } + + void Reserve(unsigned newCapacity) + { + if (newCapacity > _capacity) + { + 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; + Z7_ARRAY_NEW(_items, T, newCapacity) + // _items = new T[newCapacity]; + _capacity = newCapacity; + } + } + + void ClearAndSetSize(unsigned newSize) + { + ClearAndReserve(newSize); + _size = newSize; + } + + void ReserveDown() + { + if (_size == _capacity) + return; + T *p = NULL; + if (_size != 0) + { + // Z7_ARRAY_NEW(p, T, _size) + p = new T[_size]; + memcpy(p, _items, (size_t)_size * sizeof(T)); + } + delete []_items; + _items = p; + _capacity = _size; + } + + ~CRecordVector() { delete []_items; } + + void ClearAndFree() + { + delete []_items; + _items = NULL; + _size = 0; + _capacity = 0; + } + + void Clear() { _size = 0; } + + void DeleteBack() { _size--; } + + void DeleteFrom(unsigned index) + { + // if (index <= _size) + _size = index; + } + + void DeleteFrontal(unsigned num) + { + if (num != 0) + { + MoveItems(0, num); + _size -= num; + } + } + + void Delete(unsigned index) + { + MoveItems(index, index + 1); + _size -= 1; + } + + /* + void Delete(unsigned index, unsigned num) + { + if (num > 0) + { + MoveItems(index, index + num); + _size -= num; + } + } + */ + + CRecordVector& operator=(const CRecordVector &v) + { + if (&v == this) + return *this; + const unsigned size = v.Size(); + if (size > _capacity) + { + delete []_items; + _capacity = 0; + _size = 0; + _items = NULL; + _items = new T[size]; + _capacity = size; + } + _size = size; + if (size != 0) + memcpy(_items, v._items, (size_t)size * sizeof(T)); + return *this; + } + + CRecordVector& operator+=(const CRecordVector &v) + { + 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 = newSize; + } + return *this; + } + + unsigned Add(const T item) + { + ReserveOnePosition(); + 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; + } + */ + + unsigned AddInReserved(const T item) + { + const unsigned size = _size; + _size = size + 1; + _items[size] = item; + return size; + } + + void Insert(unsigned index, const T item) + { + ReserveOnePosition(); + MoveItems(index + 1, index); + _items[index] = item; + _size++; + } + + void InsertInReserved(unsigned index, const T item) + { + MoveItems(index + 1, index); + _items[index] = item; + _size++; + } + + void MoveToFront(unsigned index) + { + if (index != 0) + { + const T temp = _items[index]; + memmove(_items + 1, _items, (size_t)index * sizeof(T)); + _items[0] = temp; + } + } + + const T& operator[](unsigned index) const { return _items[index]; } + T& operator[](unsigned index) { return _items[index]; } + const T& operator[](int index) const { return _items[(unsigned)index]; } + T& operator[](int index) { return _items[(unsigned)index]; } + + const T* ConstData() const { return _items; } + T* NonConstData() const { return _items; } + T* NonConstData() { return _items; } + + const T* Data() const { return _items; } + T* Data() { return _items; } + + const T& FrontItem() const { return _items[0]; } + T& FrontItem() { return _items[0]; } + /* + const T Front() const { return _items[0]; } + T Front() { return _items[0]; } + const T& Front() const { return _items[0]; } + T& Front() { return _items[0]; } + */ + const T& Back() const { return _items[(size_t)_size - 1]; } + T& Back() { return _items[(size_t)_size - 1]; } + + /* + void Swap(unsigned i, unsigned j) + { + const T temp = _items[i]; + _items[i] = _items[j]; + _items[j] = temp; + } + */ + + int FindInSorted(const T item, unsigned left, unsigned right) const + { + while (left != right) + { + // 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; + if (item < midVal) + right = mid; + else + left = mid + 1; + } + return -1; + } + + int FindInSorted2(const T &item, unsigned left, unsigned right) const + { + while (left != right) + { + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + const int comp = item.Compare(midVal); + if (comp == 0) + return (int)mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + return -1; + } + + int FindInSorted(const T item) const + { + return FindInSorted(item, 0, _size); + } + + int FindInSorted2(const T &item) const + { + return FindInSorted2(item, 0, _size); + } + + unsigned AddToUniqueSorted(const T item) + { + unsigned left = 0, right = _size; + while (left != right) + { + // 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; + if (item < midVal) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + unsigned AddToUniqueSorted2(const T &item) + { + unsigned left = 0, right = _size; + while (left != right) + { + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + const int comp = item.Compare(midVal); + if (comp == 0) + return mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param) + { + const T temp = p[k]; + for (;;) + { + unsigned s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + unsigned size = _size; + if (size <= 1) + return; + T* p = _items - 1; + { + unsigned i = size >> 1; + do + SortRefDown(p, i, size, compare, param); + while (--i); + } + do + { + const T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown(p, 1, size, compare, param); + } + while (size > 1); + } + + static void SortRefDown2(T* p, unsigned k, unsigned size) + { + const T temp = p[k]; + for (;;) + { + unsigned s = (k << 1); + if (s > size) + break; + if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0) + s++; + if (temp.Compare(p[s]) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; + } + + void Sort2() + { + unsigned size = _size; + if (size <= 1) + return; + T* p = _items - 1; + { + unsigned i = size >> 1; + do + SortRefDown2(p, i, size); + while (--i); + } + do + { + const T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + SortRefDown2(p, 1, size); + } + while (size > 1); + } +}; + +typedef CRecordVector CIntVector; +typedef CRecordVector CUIntVector; +typedef CRecordVector CBoolVector; +typedef CRecordVector CByteVector; +typedef CRecordVector CPointerVector; + +template +class CObjectVector +{ + CPointerVector _v; +public: + unsigned Size() const { return _v.Size(); } + bool IsEmpty() const { return _v.IsEmpty(); } + void ReserveDown() { _v.ReserveDown(); } + // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); } + void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); } + + CObjectVector() {} + CObjectVector(const CObjectVector &v) + { + const unsigned size = v.Size(); + _v.ConstructReserve(size); + for (unsigned i = 0; i < size; i++) + AddInReserved(v[i]); + } + CObjectVector& operator=(const CObjectVector &v) + { + if (&v == this) + return *this; + Clear(); + const unsigned size = v.Size(); + _v.Reserve(size); + for (unsigned i = 0; i < size; i++) + AddInReserved(v[i]); + return *this; + } + + CObjectVector& operator+=(const CObjectVector &v) + { + 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; + } + + const T& operator[](unsigned index) const { return *((T *)_v[index]); } + T& operator[](unsigned index) { return *((T *)_v[index]); } + const T& operator[](int index) const { return *((T *)_v[(unsigned)index]); } + T& operator[](int index) { return *((T *)_v[(unsigned)index]); } + const T& Front() const { return operator[](0); } + T& Front() { return operator[](0); } + const T& Back() const { return *(T *)_v.Back(); } + T& Back() { return *(T *)_v.Back(); } + + void MoveToFront(unsigned index) { _v.MoveToFront(index); } + + 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); + + + T& AddNew() + { + _v.ReserveOnePosition(); + T *p = new T; + _v.AddInReserved(p); + return *p; + } + + T& AddNewInReserved() + { + T *p = new T; + _v.AddInReserved(p); + return *p; + } + + 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.InsertInReserved(index, p); + return *p; + } + + ~CObjectVector() + { + for (unsigned i = _v.Size(); i != 0;) + delete (T *)_v[--i]; + } + + void ClearAndFree() + { + Clear(); + _v.ClearAndFree(); + } + + void Clear() + { + for (unsigned i = _v.Size(); i != 0;) + delete (T *)_v[--i]; + _v.Clear(); + } + + void DeleteFrom(unsigned index) + { + const unsigned size = _v.Size(); + for (unsigned i = index; i < size; i++) + delete (T *)_v[i]; + _v.DeleteFrom(index); + } + + void DeleteFrontal(unsigned num) + { + for (unsigned i = 0; i < num; i++) + delete (T *)_v[i]; + _v.DeleteFrontal(num); + } + + void DeleteBack() + { + delete (T *)_v.Back(); + _v.DeleteBack(); + } + + void Delete(unsigned index) + { + delete (T *)_v[index]; + _v.Delete(index); + } + // void Delete(int index) { Delete((unsigned)index); } + + /* + void Delete(unsigned index, unsigned num) + { + for (unsigned i = 0; i < num; i++) + delete (T *)_v[index + i]; + _v.Delete(index, num); + } + */ + + /* + int Find(const T& item) const + { + unsigned size = Size(); + for (unsigned i = 0; i < size; i++) + if (item == (*this)[i]) + return i; + return -1; + } + */ + + int FindInSorted(const T& item) const + { + unsigned left = 0, right = Size(); + while (left != right) + { + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + const int comp = item.Compare(midVal); + if (comp == 0) + return (int)mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + return -1; + } + + unsigned AddToUniqueSorted(const T& item) + { + unsigned left = 0, right = Size(); + while (left != right) + { + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + const int comp = item.Compare(midVal); + if (comp == 0) + return mid; + if (comp < 0) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + + /* + unsigned AddToSorted(const T& item) + { + unsigned left = 0, right = Size(); + while (left != right) + { + // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); + const unsigned mid = (left + right) / 2; + const T& midVal = (*this)[mid]; + const int comp = item.Compare(midVal); + if (comp == 0) + { + right = mid + 1; + break; + } + if (comp < 0) + right = mid; + else + left = mid + 1; + } + Insert(right, item); + return right; + } + */ + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { _v.Sort(compare, param); } + + static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) + { return (*(*((const T *const *)a1))).Compare(*(*((const T *const *)a2))); } + + void Sort() { _v.Sort(CompareObjectItems, NULL); } +}; + +#define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++) + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyWindows.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.cpp --- p7zip-rar-16.02/CPP/Common/MyWindows.cpp 2015-06-19 17:33:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.cpp 2024-02-15 07:00:00.000000000 +0000 @@ -1,128 +1,292 @@ -// MyWindows.cpp - -#include "StdAfx.h" - -#ifndef _WIN32 - -#include "MyWindows.h" -#include "MyTypes.h" -#include /* FIXED */ - -static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } -static inline void FreeForBSTR(void *pv) { ::free(pv);} - -/* FIXME -static UINT MyStringLen(const wchar_t *s) -{ - UINT i; - for (i = 0; s[i] != '\0'; i++); - return i; -} -*/ - -BSTR SysAllocStringByteLen(LPCSTR psz, UINT len) -{ - // FIXED int realLen = len + sizeof(UINT) + 3; - const int LEN_ADDON = sizeof(wchar_t) - 1; - int realLen = len + sizeof(UINT) + sizeof(wchar_t) + LEN_ADDON; - void *p = AllocateForBSTR(realLen); - if (p == 0) - return 0; - *(UINT *)p = len; - // "void *" instead of "BSTR" to avoid unaligned copy of "wchar_t" because of optimizer on Solaris - void * bstr = (void *)((UINT *)p + 1); - if (psz) memmove(bstr, psz, len); // psz does not always have "wchar_t" alignment. - void *pb = (void *)(((Byte *)bstr) + len); - memset(pb,0,sizeof(wchar_t) + LEN_ADDON); - return (BSTR)bstr; -} - -BSTR WINAPI SysAllocStringLen(const OLECHAR *sz, unsigned int numChars) // FIXME - code -{ - UINT len = (numChars + 1) * sizeof(OLECHAR); - void *p = AllocateForBSTR(len + sizeof(UINT)); - if (p == 0) - return 0; - memset(p,0,len + sizeof(UINT)); - *(UINT *)p = numChars * sizeof(OLECHAR); // FIXED - void * bstr = (void *)((UINT *)p + 1); - if (sz) memmove(bstr, sz, numChars * sizeof(OLECHAR)); // sz does not always have "wchar_t" alignment. - - return (BSTR)bstr; -} - - -BSTR SysAllocString(const OLECHAR *sz) -{ - if (sz == 0) - return 0; - UINT strLen = MyStringLen(sz); - UINT len = (strLen + 1) * sizeof(OLECHAR); - void *p = AllocateForBSTR(len + sizeof(UINT)); - if (p == 0) - return 0; - *(UINT *)p = strLen * sizeof(OLECHAR); // FIXED - void * bstr = (void *)((UINT *)p + 1); - memmove(bstr, sz, len); // sz does not always have "wchar_t" alignment. - return (BSTR)bstr; -} - -void SysFreeString(BSTR bstr) -{ - if (bstr != 0) - FreeForBSTR((UINT *)bstr - 1); -} - -UINT SysStringByteLen(BSTR bstr) -{ - if (bstr == 0) - return 0; - return *((UINT *)bstr - 1); - -} - -UINT SysStringLen(BSTR bstr) -{ - return SysStringByteLen(bstr) / sizeof(OLECHAR); -} - -HRESULT VariantClear(VARIANTARG *prop) -{ - if (prop->vt == VT_BSTR) - SysFreeString(prop->bstrVal); - prop->vt = VT_EMPTY; - return S_OK; -} - -HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src) -{ - HRESULT res = ::VariantClear(dest); - if (res != S_OK) - return res; - if (src->vt == VT_BSTR) - { - dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, - SysStringByteLen(src->bstrVal)); - if (dest->bstrVal == 0) - return E_OUTOFMEMORY; - dest->vt = VT_BSTR; - } - else - *dest = *src; - return S_OK; -} - -LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) -{ - if(ft1->dwHighDateTime < ft2->dwHighDateTime) - return -1; - if(ft1->dwHighDateTime > ft2->dwHighDateTime) - return 1; - if(ft1->dwLowDateTime < ft2->dwLowDateTime) - return -1; - if(ft1->dwLowDateTime > ft2->dwLowDateTime) - return 1; - return 0; -} - -#endif +// MyWindows.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include +#include +#ifdef __GNUC__ +#include +#endif + +#include "MyWindows.h" + +static inline void *AllocateForBSTR(size_t cb) { return ::malloc(cb); } +static inline void FreeForBSTR(void *pv) { ::free(pv);} + +/* Win32 uses DWORD (32-bit) type to store size of string before (OLECHAR *) string. + We must select CBstrSizeType for another systems (not Win32): + + if (CBstrSizeType is UINT32), + then we support only strings smaller than 4 GB. + Win32 version always has that limitation. + + if (CBstrSizeType is UINT), + (UINT can be 16/32/64-bit) + We can support strings larger than 4 GB (if UINT is 64-bit), + but sizeof(UINT) can be different in parts compiled by + different compilers/settings, + and we can't send such BSTR strings between such parts. +*/ + +typedef UINT32 CBstrSizeType; +// typedef UINT CBstrSizeType; + +#define k_BstrSize_Max 0xFFFFFFFF +// #define k_BstrSize_Max UINT_MAX +// #define k_BstrSize_Max ((UINT)(INT)-1) + +BSTR SysAllocStringByteLen(LPCSTR s, UINT len) +{ + /* Original SysAllocStringByteLen in Win32 maybe fills only unaligned null OLECHAR at the end. + We provide also aligned null OLECHAR at the end. */ + + if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType))) + return NULL; + + UINT size = (len + (UINT)sizeof(OLECHAR) + (UINT)sizeof(OLECHAR) - 1) & ~((UINT)sizeof(OLECHAR) - 1); + void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType)); + if (!p) + return NULL; + *(CBstrSizeType *)p = (CBstrSizeType)len; + BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); + if (s) + memcpy(bstr, s, len); + for (; len < size; len++) + ((Byte *)bstr)[len] = 0; + return bstr; +} + +BSTR SysAllocStringLen(const OLECHAR *s, UINT len) +{ + if (len >= (k_BstrSize_Max - (UINT)sizeof(OLECHAR) - (UINT)sizeof(CBstrSizeType)) / (UINT)sizeof(OLECHAR)) + return NULL; + + UINT size = len * (UINT)sizeof(OLECHAR); + void *p = AllocateForBSTR(size + (UINT)sizeof(CBstrSizeType) + (UINT)sizeof(OLECHAR)); + if (!p) + return NULL; + *(CBstrSizeType *)p = (CBstrSizeType)size; + BSTR bstr = (BSTR)((CBstrSizeType *)p + 1); + if (s) + memcpy(bstr, s, size); + bstr[len] = 0; + return bstr; +} + +BSTR SysAllocString(const OLECHAR *s) +{ + if (!s) + return NULL; + const OLECHAR *s2 = s; + while (*s2 != 0) + s2++; + return SysAllocStringLen(s, (UINT)(s2 - s)); +} + +void SysFreeString(BSTR bstr) +{ + if (bstr) + FreeForBSTR((CBstrSizeType *)(void *)bstr - 1); +} + +UINT SysStringByteLen(BSTR bstr) +{ + if (!bstr) + return 0; + return *((CBstrSizeType *)(void *)bstr - 1); +} + +UINT SysStringLen(BSTR bstr) +{ + if (!bstr) + return 0; + return *((CBstrSizeType *)(void *)bstr - 1) / (UINT)sizeof(OLECHAR); +} + + +HRESULT VariantClear(VARIANTARG *prop) +{ + if (prop->vt == VT_BSTR) + SysFreeString(prop->bstrVal); + prop->vt = VT_EMPTY; + return S_OK; +} + +HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src) +{ + HRESULT res = ::VariantClear(dest); + if (res != S_OK) + return res; + if (src->vt == VT_BSTR) + { + dest->bstrVal = SysAllocStringByteLen((LPCSTR)src->bstrVal, + SysStringByteLen(src->bstrVal)); + if (!dest->bstrVal) + return E_OUTOFMEMORY; + dest->vt = VT_BSTR; + } + else + *dest = *src; + return S_OK; +} + +LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2) +{ + if (ft1->dwHighDateTime < ft2->dwHighDateTime) return -1; + if (ft1->dwHighDateTime > ft2->dwHighDateTime) return 1; + if (ft1->dwLowDateTime < ft2->dwLowDateTime) return -1; + if (ft1->dwLowDateTime > ft2->dwLowDateTime) return 1; + return 0; +} + +DWORD GetLastError() +{ + return (DWORD)errno; +} + +void SetLastError(DWORD dw) +{ + errno = (int)dw; +} + + +static LONG TIME_GetBias() +{ + time_t utc = time(NULL); + struct tm *ptm = localtime(&utc); + int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ + ptm = gmtime(&utc); + ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ + LONG bias = (int)(mktime(ptm)-utc); + return bias; +} + +#define TICKS_PER_SEC 10000000 +/* +#define SECS_PER_DAY (24 * 60 * 60) +#define SECS_1601_TO_1970 ((369 * 365 + 89) * (UInt64)SECS_PER_DAY) +#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKS_PER_SEC) +*/ + +#define GET_TIME_64(pft) ((pft)->dwLowDateTime | ((UInt64)(pft)->dwHighDateTime << 32)) + +#define SET_FILETIME(ft, v64) \ + (ft)->dwLowDateTime = (DWORD)v64; \ + (ft)->dwHighDateTime = (DWORD)(v64 >> 32); + + +BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime) +{ + UInt64 v = GET_TIME_64(fileTime); + v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC); + SET_FILETIME(localFileTime, v) + return TRUE; +} + +BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime) +{ + UInt64 v = GET_TIME_64(localFileTime); + v = (UInt64)((Int64)v + (Int64)TIME_GetBias() * TICKS_PER_SEC); + SET_FILETIME(fileTime, v) + return TRUE; +} + +/* +VOID WINAPI GetSystemTimeAsFileTime(FILETIME *ft) +{ + UInt64 t = 0; + timeval tv; + if (gettimeofday(&tv, NULL) == 0) + { + t = tv.tv_sec * (UInt64)TICKS_PER_SEC + TICKS_1601_TO_1970; + t += tv.tv_usec * 10; + } + SET_FILETIME(ft, t) +} +*/ + +DWORD WINAPI GetTickCount(VOID) +{ + #ifndef _WIN32 + // gettimeofday() doesn't work in some MINGWs by unknown reason + timeval tv; + if (gettimeofday(&tv, NULL) == 0) + { + // tv_sec and tv_usec are (long) + return (DWORD)((UInt64)(Int64)tv.tv_sec * (UInt64)1000 + (UInt64)(Int64)tv.tv_usec / 1000); + } + #endif + return (DWORD)time(NULL) * 1000; +} + + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + +BOOL WINAPI FileTimeToSystemTime(const FILETIME *ft, SYSTEMTIME *st) +{ + UInt32 v; + UInt64 v64 = GET_TIME_64(ft); + v64 /= 10000; + st->wMilliseconds = (WORD)(v64 % 1000); v64 /= 1000; + st->wSecond = (WORD)(v64 % 60); v64 /= 60; + st->wMinute = (WORD)(v64 % 60); v64 /= 60; + v = (UInt32)v64; + st->wHour = (WORD)(v % 24); v /= 24; + + // 1601-01-01 was Monday + st->wDayOfWeek = (WORD)((v + 1) % 7); + + UInt32 leaps, year, day, mon; + leaps = (3 * ((4 * v + (365 - 31 - 28) * 4 + 3) / PERIOD_400) + 3) / 4; + v += 28188 + leaps; + // leaps - the number of exceptions from PERIOD_4 rules starting from 1600-03-01 + // (1959 / 64) - converts day from 03-01 to month + year = (20 * v - 2442) / (5 * PERIOD_4); + day = v - (year * PERIOD_4) / 4; + mon = (64 * day) / 1959; + st->wDay = (WORD)(day - (1959 * mon) / 64); + mon -= 1; + year += 1524; + if (mon > 12) + { + mon -= 12; + year++; + } + st->wMonth = (WORD)mon; + st->wYear = (WORD)year; + + /* + unsigned year, mon; + unsigned char ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + unsigned t; + + year = (WORD)(1601 + v / PERIOD_400 * 400); + v %= PERIOD_400; + + t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100; + t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4; + t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365; + + st->wYear = (WORD)year; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 0;; mon++) + { + unsigned d = ms[mon]; + if (v < d) + break; + v -= d; + } + st->wDay = (WORD)(v + 1); + st->wMonth = (WORD)(mon + 1); + */ + + return TRUE; +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyWindows.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.h --- p7zip-rar-16.02/CPP/Common/MyWindows.h 2014-12-22 14:43:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyWindows.h 2023-09-14 11:00:00.000000000 +0000 @@ -1,226 +1,325 @@ -// MyWindows.h - -#ifndef __MYWINDOWS_H -#define __MYWINDOWS_H - -#ifdef _WIN32 - -#include - -#else - -#include // for wchar_t -#include - -#include "MyGuidDef.h" - -typedef char CHAR; -typedef unsigned char UCHAR; - -#undef BYTE -typedef unsigned char BYTE; - -typedef short SHORT; -typedef unsigned short USHORT; - -#undef WORD -typedef unsigned short WORD; -typedef short VARIANT_BOOL; - -typedef int INT; -typedef Int32 INT32; -typedef unsigned int UINT; -typedef UInt32 UINT32; -typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit -typedef UINT32 ULONG; - -#undef DWORD -typedef UINT32 DWORD; - -typedef Int64 LONGLONG; -typedef UInt64 ULONGLONG; - -typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER; -typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER; - -typedef const CHAR *LPCSTR; - -typedef wchar_t WCHAR; - -#ifdef _UNICODE -typedef WCHAR TCHAR; -#define lstrcpy wcscpy -#define lstrcat wcscat -#define lstrlen wcslen -#else -typedef CHAR TCHAR; -#define lstrcpy strcpy -#define lstrcat strcat -#define lstrlen strlen -#endif -#define _wcsicmp(str1,str2) MyStringCompareNoCase(str1,str2) - -typedef const TCHAR *LPCTSTR; -typedef WCHAR OLECHAR; -typedef const WCHAR *LPCWSTR; -typedef OLECHAR *BSTR; -typedef const OLECHAR *LPCOLESTR; -typedef OLECHAR *LPOLESTR; - -typedef struct _FILETIME -{ - DWORD dwLowDateTime; - DWORD dwHighDateTime; -}FILETIME; - -#define HRESULT LONG -#define FAILED(Status) ((HRESULT)(Status)<0) -typedef ULONG PROPID; -typedef LONG SCODE; - -#define S_OK ((HRESULT)0x00000000L) -#define S_FALSE ((HRESULT)0x00000001L) -#define E_NOTIMPL ((HRESULT)0x80004001L) -#define E_NOINTERFACE ((HRESULT)0x80004002L) -#define E_ABORT ((HRESULT)0x80004004L) -#define E_FAIL ((HRESULT)0x80004005L) -#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) -#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) -#define E_INVALIDARG ((HRESULT)0x80070057L) - -#ifdef _MSC_VER -#define STDMETHODCALLTYPE __stdcall -#else -#define STDMETHODCALLTYPE -#endif - -#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f -#define STDMETHOD(f) STDMETHOD_(HRESULT, f) -#define STDMETHODIMP_(type) type STDMETHODCALLTYPE -#define STDMETHODIMP STDMETHODIMP_(HRESULT) - -#define PURE = 0 - -#define MIDL_INTERFACE(x) struct - -#ifdef __cplusplus - -DEFINE_GUID(IID_IUnknown, -0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); -struct IUnknown -{ - STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE; - STDMETHOD_(ULONG, AddRef)() PURE; - STDMETHOD_(ULONG, Release)() PURE; - #ifndef _WIN32 - virtual ~IUnknown() {} - #endif -}; - -typedef IUnknown *LPUNKNOWN; - -#endif - -#define VARIANT_TRUE ((VARIANT_BOOL)-1) -#define VARIANT_FALSE ((VARIANT_BOOL)0) - -enum VARENUM -{ - VT_EMPTY = 0, - VT_NULL = 1, - VT_I2 = 2, - VT_I4 = 3, - VT_R4 = 4, - VT_R8 = 5, - VT_CY = 6, - VT_DATE = 7, - VT_BSTR = 8, - VT_DISPATCH = 9, - VT_ERROR = 10, - VT_BOOL = 11, - VT_VARIANT = 12, - VT_UNKNOWN = 13, - VT_DECIMAL = 14, - VT_I1 = 16, - VT_UI1 = 17, - VT_UI2 = 18, - VT_UI4 = 19, - VT_I8 = 20, - VT_UI8 = 21, - VT_INT = 22, - VT_UINT = 23, - VT_VOID = 24, - VT_HRESULT = 25, - VT_FILETIME = 64 -}; - -typedef unsigned short VARTYPE; -typedef WORD PROPVAR_PAD1; -typedef WORD PROPVAR_PAD2; -typedef WORD PROPVAR_PAD3; - -#ifdef __cplusplus - -typedef struct tagPROPVARIANT -{ - VARTYPE vt; - PROPVAR_PAD1 wReserved1; - PROPVAR_PAD2 wReserved2; - PROPVAR_PAD3 wReserved3; - union - { - CHAR cVal; - UCHAR bVal; - SHORT iVal; - USHORT uiVal; - LONG lVal; - ULONG ulVal; - INT intVal; - UINT uintVal; - LARGE_INTEGER hVal; - ULARGE_INTEGER uhVal; - VARIANT_BOOL boolVal; - SCODE scode; - FILETIME filetime; - BSTR bstrVal; - }; -} PROPVARIANT; - -typedef PROPVARIANT tagVARIANT; -typedef tagVARIANT VARIANT; -typedef VARIANT VARIANTARG; - -#define MY_EXTERN_C extern "C" - -MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop); -MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src); - -#else - -#define MY_EXTERN_C extern - - -#endif - -MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); -MY_EXTERN_C BSTR SysAllocStringLen(const OLECHAR*,UINT); -MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz); -MY_EXTERN_C void SysFreeString(BSTR bstr); -MY_EXTERN_C UINT SysStringByteLen(BSTR bstr); -MY_EXTERN_C UINT SysStringLen(BSTR bstr); - -/* MY_EXTERN_C DWORD GetLastError(); */ -MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); - -#define CP_ACP 0 -#define CP_OEMCP 1 - -typedef enum tagSTREAM_SEEK -{ - STREAM_SEEK_SET = 0, - STREAM_SEEK_CUR = 1, - STREAM_SEEK_END = 2 -} STREAM_SEEK; - -#endif -#endif +// MyWindows.h + +#ifdef Z7_DEFINE_GUID +#undef Z7_DEFINE_GUID +#endif + +#ifdef INITGUID + #define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name; \ + EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else + #define Z7_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID name +#endif + + +#ifndef ZIP7_INC_MY_WINDOWS_H +#define ZIP7_INC_MY_WINDOWS_H + +#ifdef _WIN32 + +#include "../../C/7zWindows.h" + +#else // _WIN32 + +#include // for wchar_t +#include +// #include // for uintptr_t + +#include "../../C/7zTypes.h" +#include "MyGuidDef.h" + +// WINAPI is __stdcall in Windows-MSVC in windef.h +#define WINAPI + +typedef char CHAR; +typedef unsigned char UCHAR; + +#undef BYTE +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short USHORT; + +#undef WORD +typedef unsigned short WORD; +typedef short VARIANT_BOOL; + +#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff)) +#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) + +// MS uses long for BOOL, but long is 32-bit in MS. So we use int. +// typedef long BOOL; +typedef int BOOL; + +#ifndef FALSE + #define FALSE 0 + #define TRUE 1 +#endif + +// typedef size_t ULONG_PTR; +// typedef size_t DWORD_PTR; +// typedef uintptr_t UINT_PTR; +// typedef ptrdiff_t UINT_PTR; + +typedef Int64 LONGLONG; +typedef UInt64 ULONGLONG; + +typedef struct { LONGLONG QuadPart; } LARGE_INTEGER; +typedef struct { ULONGLONG QuadPart; } ULARGE_INTEGER; + +typedef const CHAR *LPCSTR; +typedef CHAR TCHAR; +typedef const TCHAR *LPCTSTR; +typedef wchar_t WCHAR; +typedef WCHAR OLECHAR; +typedef const WCHAR *LPCWSTR; +typedef OLECHAR *BSTR; +typedef const OLECHAR *LPCOLESTR; +typedef OLECHAR *LPOLESTR; + +typedef struct +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME; + +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) +#define FAILED(hr) ((HRESULT)(hr) < 0) +typedef ULONG PROPID; +typedef LONG SCODE; + + +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) +#define E_NOTIMPL ((HRESULT)0x80004001L) +#define E_NOINTERFACE ((HRESULT)0x80004002L) +#define E_ABORT ((HRESULT)0x80004004L) +#define E_FAIL ((HRESULT)0x80004005L) +#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) +#define CLASS_E_CLASSNOTAVAILABLE ((HRESULT)0x80040111L) + + +#ifdef _MSC_VER +#define STDMETHODCALLTYPE __stdcall +#define STDAPICALLTYPE __stdcall +#else +// do we need __export here? +#define STDMETHODCALLTYPE +#define STDAPICALLTYPE +#endif + +#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE + +#ifndef DECLSPEC_NOTHROW +#define DECLSPEC_NOTHROW Z7_DECLSPEC_NOTHROW +#endif + +#ifndef DECLSPEC_NOVTABLE +#define DECLSPEC_NOVTABLE Z7_DECLSPEC_NOVTABLE +#endif + +#ifndef COM_DECLSPEC_NOTHROW +#ifdef COM_STDMETHOD_CAN_THROW + #define COM_DECLSPEC_NOTHROW +#else + #define COM_DECLSPEC_NOTHROW DECLSPEC_NOTHROW +#endif +#endif + +#define DECLARE_INTERFACE(iface) struct DECLSPEC_NOVTABLE iface +#define DECLARE_INTERFACE_(iface, baseiface) struct DECLSPEC_NOVTABLE iface : public baseiface + +#define STDMETHOD_(t, f) virtual COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE f +#define STDMETHOD(f) STDMETHOD_(HRESULT, f) +#define STDMETHODIMP_(t) COM_DECLSPEC_NOTHROW t STDMETHODCALLTYPE +#define STDMETHODIMP STDMETHODIMP_(HRESULT) + + +#define PURE = 0 + +// #define MIDL_INTERFACE(x) struct + + +#ifdef __cplusplus + +/* + p7zip and 7-Zip before v23 used virtual destructor in IUnknown, + if _WIN32 is not defined. + It used virtual destructor, because some compilers don't like virtual + interfaces without virtual destructor. + IUnknown in Windows (_WIN32) doesn't use virtual destructor in IUnknown. + We still can define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here, + if we want to be compatible with old plugin interface of p7zip and 7-Zip before v23. + +v23: + In new 7-Zip v23 we try to be more compatible with original IUnknown from _WIN32. + So we do not define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN here, +*/ +// #define Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN + +#ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override" +#endif +#endif + +Z7_PURE_INTERFACES_BEGIN + +DEFINE_GUID(IID_IUnknown, +0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); +struct IUnknown +{ + STDMETHOD(QueryInterface) (REFIID iid, void **outObject) =0; + STDMETHOD_(ULONG, AddRef)() =0; + STDMETHOD_(ULONG, Release)() =0; + #ifdef Z7_USE_VIRTUAL_DESTRUCTOR_IN_IUNKNOWN + virtual ~IUnknown() {} + #endif +}; + +typedef IUnknown *LPUNKNOWN; + +Z7_PURE_INTERFACES_END + +#endif // __cplusplus + +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#define VARIANT_FALSE ((VARIANT_BOOL)0) + +enum VARENUM +{ + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_FILETIME = 64 +}; + +typedef unsigned short VARTYPE; +typedef WORD PROPVAR_PAD1; +typedef WORD PROPVAR_PAD2; +typedef WORD PROPVAR_PAD3; + +typedef struct tagPROPVARIANT +{ + VARTYPE vt; + PROPVAR_PAD1 wReserved1; + PROPVAR_PAD2 wReserved2; + PROPVAR_PAD3 wReserved3; + union + { + CHAR cVal; + UCHAR bVal; + SHORT iVal; + USHORT uiVal; + LONG lVal; + ULONG ulVal; + INT intVal; + UINT uintVal; + LARGE_INTEGER hVal; + ULARGE_INTEGER uhVal; + VARIANT_BOOL boolVal; + SCODE scode; + FILETIME filetime; + BSTR bstrVal; + }; +} PROPVARIANT; + +typedef PROPVARIANT tagVARIANT; +typedef tagVARIANT VARIANT; +typedef VARIANT VARIANTARG; + +EXTERN_C HRESULT VariantClear(VARIANTARG *prop); +EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, const VARIANTARG *src); + +typedef struct tagSTATPROPSTG +{ + LPOLESTR lpwstrName; + PROPID propid; + VARTYPE vt; +} STATPROPSTG; + +EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len); +EXTERN_C BSTR SysAllocStringLen(const OLECHAR *sz, UINT len); +EXTERN_C BSTR SysAllocString(const OLECHAR *sz); +EXTERN_C void SysFreeString(BSTR bstr); +EXTERN_C UINT SysStringByteLen(BSTR bstr); +EXTERN_C UINT SysStringLen(BSTR bstr); + +EXTERN_C DWORD GetLastError(); +EXTERN_C void SetLastError(DWORD dwCode); +EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2); + +EXTERN_C DWORD GetCurrentThreadId(); +EXTERN_C DWORD GetCurrentProcessId(); + +#define MAX_PATH 1024 + +#define CP_ACP 0 +#define CP_OEMCP 1 +#define CP_UTF8 65001 + +typedef enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + + + +typedef struct +{ + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} SYSTEMTIME; + +BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *localFileTime); +BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *localFileTime, FILETIME *fileTime); +BOOL WINAPI FileTimeToSystemTime(const FILETIME *fileTime, SYSTEMTIME *systemTime); +// VOID WINAPI GetSystemTimeAsFileTime(FILETIME *systemTimeAsFileTime); + +DWORD GetTickCount(); + + +/* +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 +*/ + +#endif // _WIN32 + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/MyXml.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.cpp --- p7zip-rar-16.02/CPP/Common/MyXml.cpp 2015-11-20 20:40:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.cpp 2025-06-16 09:00:00.000000000 +0000 @@ -1,260 +1,349 @@ -// MyXml.cpp - -#include "StdAfx.h" - -#include "MyXml.h" - -static bool IsValidChar(char c) -{ - return - c >= 'a' && c <= 'z' || - c >= 'A' && c <= 'Z' || - c >= '0' && c <= '9' || - c == '-'; -} - -static bool IsSpaceChar(char c) -{ - return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); -} - -#define SKIP_SPACES(s) while (IsSpaceChar(*s)) s++; - -int CXmlItem::FindProp(const AString &propName) const throw() -{ - FOR_VECTOR (i, Props) - if (Props[i].Name == propName) - return i; - return -1; -} - -AString CXmlItem::GetPropVal(const AString &propName) const -{ - int index = FindProp(propName); - if (index >= 0) - return Props[index].Value; - return AString(); -} - -bool CXmlItem::IsTagged(const AString &tag) const throw() -{ - return (IsTag && Name == tag); -} - -int CXmlItem::FindSubTag(const AString &tag) const throw() -{ - FOR_VECTOR (i, SubItems) - if (SubItems[i].IsTagged(tag)) - return i; - return -1; -} - -AString CXmlItem::GetSubString() const -{ - if (SubItems.Size() == 1) - { - const CXmlItem &item = SubItems[0]; - if (!item.IsTag) - return item.Name; - } - return AString(); -} - -const AString * CXmlItem::GetSubStringPtr() const throw() -{ - if (SubItems.Size() == 1) - { - const CXmlItem &item = SubItems[0]; - if (!item.IsTag) - return &item.Name; - } - return NULL; -} - -AString CXmlItem::GetSubStringForTag(const AString &tag) const -{ - int index = FindSubTag(tag); - if (index >= 0) - return SubItems[index].GetSubString(); - return AString(); -} - -const char * CXmlItem::ParseItem(const char *s, int numAllowedLevels) -{ - SKIP_SPACES(s); - - const char *beg = s; - for (;;) - { - char c; - c = *s; if (c == 0 || c == '<') break; s++; - c = *s; if (c == 0 || c == '<') break; s++; - } - if (*s == 0) - return NULL; - if (s != beg) - { - IsTag = false; - Name.SetFrom(beg, (unsigned)(s - beg)); - return s; - } - - IsTag = true; - - s++; - SKIP_SPACES(s); - - beg = s; - for (;; s++) - if (!IsValidChar(*s)) - break; - if (s == beg || *s == 0) - return NULL; - Name.SetFrom(beg, (unsigned)(s - beg)); - - for (;;) - { - beg = s; - SKIP_SPACES(s); - if (*s == '/') - { - s++; - // SKIP_SPACES(s); - if (*s != '>') - return NULL; - return s + 1; - } - if (*s == '>') - { - s++; - if (numAllowedLevels == 0) - return NULL; - SubItems.Clear(); - for (;;) - { - SKIP_SPACES(s); - if (s[0] == '<' && s[1] == '/') - break; - CXmlItem &item = SubItems.AddNew(); - s = item.ParseItem(s, numAllowedLevels - 1); - if (!s) - return NULL; - } - - s += 2; - unsigned len = Name.Len(); - for (unsigned i = 0; i < len; i++) - if (s[i] != Name[i]) - return NULL; - s += len; - if (s[0] != '>') - return NULL; - return s + 1; - } - if (beg == s) - return NULL; - - // ReadProperty - CXmlProp &prop = Props.AddNew(); - - beg = s; - for (;; s++) - { - char c = *s; - if (!IsValidChar(c)) - break; - } - if (s == beg) - return NULL; - prop.Name.SetFrom(beg, (unsigned)(s - beg)); - - SKIP_SPACES(s); - if (*s != '=') - return NULL; - s++; - SKIP_SPACES(s); - if (*s != '\"') - return NULL; - s++; - - beg = s; - for (;;) - { - char c = *s; - if (c == 0) - return NULL; - if (c == '\"') - break; - s++; - } - prop.Value.SetFrom(beg, (unsigned)(s - beg)); - s++; - } -} - -static const char * SkipHeader(const char *s, const char *startString, const char *endString) -{ - SKIP_SPACES(s); - if (IsString1PrefixedByString2(s, startString)) - { - s = strstr(s, endString); - if (!s) - return NULL; - s += strlen(endString); - } - return s; -} - -void CXmlItem::AppendTo(AString &s) const -{ - if (IsTag) - s += '<'; - s += Name; - if (IsTag) - { - FOR_VECTOR (i, Props) - { - const CXmlProp &prop = Props[i]; - s += ' '; - s += prop.Name; - s += '='; - s += '\"'; - s += prop.Value; - s += '\"'; - } - s += '>'; - } - FOR_VECTOR (i, SubItems) - { - const CXmlItem &item = SubItems[i]; - if (i != 0 && !SubItems[i - 1].IsTag) - s += ' '; - item.AppendTo(s); - } - if (IsTag) - { - s += '<'; - s += '/'; - s += Name; - s += '>'; - } -} - -bool CXml::Parse(const char *s) -{ - s = SkipHeader(s, ""); if (!s) return false; - s = SkipHeader(s, ""); if (!s) return false; - - s = Root.ParseItem(s, 1000); - if (!s || !Root.IsTag) - return false; - SKIP_SPACES(s); - return *s == 0; -} - -/* -void CXml::AppendTo(AString &s) const -{ - Root.AppendTo(s); -} -*/ +// MyXml.cpp + +#include "StdAfx.h" + +#include "MyXml.h" +#include "StringToInt.h" + +static bool IsValidChar(char c) +{ + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-'; +} + +static bool IsSpaceChar(char c) +{ + return (c == ' ' || c == '\t' || c == 0x0D || c == 0x0A); +} + +#define SKIP_SPACES(s) while (IsSpaceChar(*s)) s++; + +int CXmlItem::FindProp(const char *propName) const throw() +{ + FOR_VECTOR (i, Props) + if (Props[i].Name.IsEqualTo(propName)) + return (int)i; + return -1; +} + +AString CXmlItem::GetPropVal(const char *propName) const +{ + const int index = FindProp(propName); + if (index >= 0) + return Props[(unsigned)index].Value; + return AString(); +} + +bool CXmlItem::IsTagged(const char *tag) const throw() +{ + return (IsTag && Name.IsEqualTo(tag)); +} + +int CXmlItem::FindSubTag(const char *tag) const throw() +{ + FOR_VECTOR (i, SubItems) + if (SubItems[i].IsTagged(tag)) + return (int)i; + return -1; +} + +const CXmlItem *CXmlItem::FindSubTag_GetPtr(const char *tag) const throw() +{ + FOR_VECTOR (i, SubItems) + { + const CXmlItem *p = &SubItems[i]; + if (p->IsTagged(tag)) + return p; + } + return NULL; +} + +AString CXmlItem::GetSubString() const +{ + if (SubItems.Size() == 1) + { + const CXmlItem &item = SubItems[0]; + if (!item.IsTag) + return item.Name; + } + return AString(); +} + +const AString * CXmlItem::GetSubStringPtr() const throw() +{ + if (SubItems.Size() == 1) + { + const CXmlItem &item = SubItems[0]; + if (!item.IsTag) + return &item.Name; + } + return NULL; +} + +AString CXmlItem::GetSubStringForTag(const char *tag) const +{ + const CXmlItem *item = FindSubTag_GetPtr(tag); + if (item) + return item->GetSubString(); + return AString(); +} + +const char * CXmlItem::ParseItem(const char *s, int numAllowedLevels) +{ + SKIP_SPACES(s) + + const char *beg = s; + for (;;) + { + char c; + c = *s; if (c == 0 || c == '<') break; s++; + c = *s; if (c == 0 || c == '<') break; s++; + } + if (*s == 0) + return NULL; + { + const size_t num = (size_t)(s - beg); + if (num) + { + IsTag = false; + Name.SetFrom_Chars_SizeT(beg, num); + return s; + } + } + + IsTag = true; + + s++; + SKIP_SPACES(s) + + beg = s; + for (;; s++) + if (!IsValidChar(*s)) + break; + if (s == beg || *s == 0) + return NULL; + Name.SetFrom_Chars_SizeT(beg, (size_t)(s - beg)); + + for (;;) + { + beg = s; + SKIP_SPACES(s) + if (*s == '/') + { + s++; + // SKIP_SPACES(s) + if (*s != '>') + return NULL; + return s + 1; + } + if (*s == '>') + { + s++; + if (numAllowedLevels == 0) + return NULL; + SubItems.Clear(); + for (;;) + { + SKIP_SPACES(s) + if (s[0] == '<' && s[1] == '/') + break; + CXmlItem &item = SubItems.AddNew(); + s = item.ParseItem(s, numAllowedLevels - 1); + if (!s) + return NULL; + } + + s += 2; + const unsigned len = Name.Len(); + const char *name = Name.Ptr(); + for (unsigned i = 0; i < len; i++) + if (*s++ != *name++) + return NULL; + // s += len; + if (s[0] != '>') + return NULL; + return s + 1; + } + if (beg == s) + return NULL; + + // ReadProperty + CXmlProp &prop = Props.AddNew(); + + beg = s; + for (;; s++) + { + char c = *s; + if (!IsValidChar(c)) + break; + } + if (s == beg) + return NULL; + prop.Name.SetFrom_Chars_SizeT(beg, (size_t)(s - beg)); + + SKIP_SPACES(s) + if (*s != '=') + return NULL; + s++; + SKIP_SPACES(s) + if (*s != '\"') + return NULL; + s++; + + beg = s; + for (;;) + { + char c = *s; + if (c == 0) + return NULL; + if (c == '\"') + break; + s++; + } + prop.Value.SetFrom_Chars_SizeT(beg, (size_t)(s - beg)); + s++; + } +} + +static const char * SkipHeader(const char *s, const char *startString, const char *endString) +{ + SKIP_SPACES(s) + if (IsString1PrefixedByString2(s, startString)) + { + s = strstr(s, endString); + if (!s) + return NULL; + s += strlen(endString); + } + return s; +} + +void CXmlItem::AppendTo(AString &s) const +{ + if (IsTag) + s += '<'; + s += Name; + if (IsTag) + { + FOR_VECTOR (i, Props) + { + const CXmlProp &prop = Props[i]; + s.Add_Space(); + s += prop.Name; + s += '='; + s += '\"'; + s += prop.Value; + s += '\"'; + } + s += '>'; + } + FOR_VECTOR (i, SubItems) + { + const CXmlItem &item = SubItems[i]; + if (i != 0 && !SubItems[i - 1].IsTag) + s.Add_Space(); + item.AppendTo(s); + } + if (IsTag) + { + s += '<'; + s += '/'; + s += Name; + s += '>'; + } +} + +bool CXml::Parse(const char *s) +{ + s = SkipHeader(s, ""); if (!s) return false; + s = SkipHeader(s, ""); if (!s) return false; + + s = Root.ParseItem(s, 1000); + if (!s || !Root.IsTag) + return false; + SKIP_SPACES(s) + return *s == 0; +} + +/* +void CXml::AppendTo(AString &s) const +{ + Root.AppendTo(s); +} +*/ + + +void z7_xml_DecodeString(AString &temp) +{ + char * const beg = temp.GetBuf(); + char *dest = beg; + const char *p = beg; + for (;;) + { + char c = *p++; + if (c == 0) + break; + if (c == '&') + { + if (p[0] == '#') + { + const char *end; + const UInt32 number = ConvertStringToUInt32(p + 1, &end); + if (*end == ';' && number != 0 && number <= 127) + { + p = end + 1; + c = (char)number; + } + } + else if ( + p[0] == 'a' && + p[1] == 'm' && + p[2] == 'p' && + p[3] == ';') + { + p += 4; + } + else if ( + p[0] == 'l' && + p[1] == 't' && + p[2] == ';') + { + p += 3; + c = '<'; + } + else if ( + p[0] == 'g' && + p[1] == 't' && + p[2] == ';') + { + p += 3; + c = '>'; + } + else if ( + p[0] == 'a' && + p[1] == 'p' && + p[2] == 'o' && + p[3] == 's' && + p[4] == ';') + { + p += 5; + c = '\''; + } + else if ( + p[0] == 'q' && + p[1] == 'u' && + p[2] == 'o' && + p[3] == 't' && + p[4] == ';') + { + p += 5; + c = '\"'; + } + } + *dest++ = c; + } + temp.ReleaseBuf_SetEnd((unsigned)(dest - beg)); +} diff -Nru p7zip-rar-16.02/CPP/Common/MyXml.h p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.h --- p7zip-rar-16.02/CPP/Common/MyXml.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/MyXml.h 2024-01-21 20:00:00.000000000 +0000 @@ -1,43 +1,45 @@ -// MyXml.h - -#ifndef __MY_XML_H -#define __MY_XML_H - -#include "MyString.h" - -struct CXmlProp -{ - AString Name; - AString Value; -}; - -class CXmlItem -{ -public: - AString Name; - bool IsTag; - CObjectVector Props; - CObjectVector SubItems; - - const char * ParseItem(const char *s, int numAllowedLevels); - - bool IsTagged(const AString &tag) const throw(); - int FindProp(const AString &propName) const throw(); - AString GetPropVal(const AString &propName) const; - AString GetSubString() const; - const AString * GetSubStringPtr() const throw(); - int FindSubTag(const AString &tag) const throw(); - AString GetSubStringForTag(const AString &tag) const; - - void AppendTo(AString &s) const; -}; - -struct CXml -{ - CXmlItem Root; - - bool Parse(const char *s); - // void AppendTo(AString &s) const; -}; - -#endif +// MyXml.h + +#ifndef ZIP7_INC_MY_XML_H +#define ZIP7_INC_MY_XML_H + +#include "MyString.h" + +struct CXmlProp +{ + AString Name; + AString Value; +}; + +class CXmlItem +{ +public: + AString Name; + bool IsTag; + CObjectVector Props; + CObjectVector SubItems; + + const char * ParseItem(const char *s, int numAllowedLevels); + + bool IsTagged(const char *tag) const throw(); + int FindProp(const char *propName) const throw(); + AString GetPropVal(const char *propName) const; + AString GetSubString() const; + const AString * GetSubStringPtr() const throw(); + int FindSubTag(const char *tag) const throw(); + const CXmlItem *FindSubTag_GetPtr(const char *tag) const throw(); + AString GetSubStringForTag(const char *tag) const; + void AppendTo(AString &s) const; +}; + +struct CXml +{ + CXmlItem Root; + + bool Parse(const char *s); + // void AppendTo(AString &s) const; +}; + +void z7_xml_DecodeString(AString &s); + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/NewHandler.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.cpp --- p7zip-rar-16.02/CPP/Common/NewHandler.cpp 2015-09-05 18:14:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.cpp 2024-03-28 19:00:00.000000000 +0000 @@ -1,39 +1,340 @@ -// NewHandler.cpp - -#include "StdAfx.h" - -#include "../../C/Alloc.h" - - -#ifdef DONT_REDEFINE_NEW - -int g_NewHandler = 0; - -#else - -/* An overload function for the C++ new */ -void * operator new(size_t size) -{ - return MyAlloc(size); -} - -/* An overload function for the C++ new[] */ -void * operator new[](size_t size) -{ - return MyAlloc(size); -} - -/* An overload function for the C++ delete */ -void operator delete(void *pnt) -{ - MyFree(pnt); -} - -/* An overload function for the C++ delete[] */ -void operator delete[](void *pnt) -{ - MyFree(pnt); -} - -#endif - +// NewHandler.cpp + +#include "StdAfx.h" + +#include + +#include "NewHandler.h" + +// #define DEBUG_MEMORY_LEAK + +#ifndef DEBUG_MEMORY_LEAK + +#ifdef Z7_REDEFINE_OPERATOR_NEW + +/* +void * my_new(size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; + void *p = ::malloc(size); + if (!p) + throw CNewException(); + return p; +} + +void my_delete(void *p) throw() +{ + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); + ::free(p); +} + +void * my_Realloc(void *p, size_t newSize, size_t oldSize) +{ + void *newBuf = my_new(newSize); + if (oldSize != 0) + memcpy(newBuf, p, oldSize); + my_delete(p); + return newBuf; +} +*/ + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + /* by C++ specification: + if (size == 0), operator new(size) returns non_NULL pointer. + If (operator new(0) returns NULL), it's out of specification. + but some calling code can work correctly even in this case too. */ + // if (size == 0) return NULL; // for debug only. don't use it + + /* malloc(0) returns non_NULL in main compilers, as we need here. + But specification also allows malloc(0) to return NULL. + So we change (size=0) to (size=1) here to get real non_NULL pointer */ + if (size == 0) + size = 1; + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + // void *p = ::MyAlloc(size); // note: MyAlloc(0) returns NULL + void *p = ::malloc(size); + if (!p) + throw CNewException(); + return p; +} + + +#if defined(_MSC_VER) && _MSC_VER == 1600 +// vs2010 has no throw() by default ? +#pragma warning(push) +#pragma warning(disable : 4986) // 'operator delete': exception specification does not match previous declaration +#endif + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() +{ + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); + // MyFree(p); + ::free(p); +} + +/* we define operator delete(void *p, size_t n) because + vs2022 compiler uses delete(void *p, size_t n), and + we want to mix files from different compilers: + - old vc6 linker + - old vc6 complier + - new vs2022 complier +*/ +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t n) throw() +{ + UNUSED_VAR(n) + ::free(p); +} + +#if defined(_MSC_VER) && _MSC_VER == 1600 +#pragma warning(pop) +#endif + +/* +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size) +{ + // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size); + if (size == 0) + size = 1; + void *p = ::malloc(size); + if (!p) + throw CNewException(); + return p; +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw() +{ + // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p); + ::free(p); +} +*/ + +#endif + +#else + +#include + +// #pragma init_seg(lib) +/* +const int kDebugSize = 1000000; +static void *a[kDebugSize]; +static int g_index = 0; + +class CC +{ +public: + CC() + { + for (int i = 0; i < kDebugSize; i++) + a[i] = 0; + } + ~CC() + { + printf("\nDestructor: %d\n", numAllocs); + for (int i = 0; i < kDebugSize; i++) + if (a[i] != 0) + return; + } +} g_CC; +*/ + +#ifdef _WIN32 +static bool wasInit = false; +static CRITICAL_SECTION cs; +#endif + +static int numAllocs = 0; + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size) +{ + #ifdef _WIN32 + if (!wasInit) + { + InitializeCriticalSection(&cs); + wasInit = true; + } + EnterCriticalSection(&cs); + + numAllocs++; + int loc = numAllocs; + void *p = HeapAlloc(GetProcessHeap(), 0, size); + /* + if (g_index < kDebugSize) + { + a[g_index] = p; + g_index++; + } + */ + printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); + LeaveCriticalSection(&cs); + if (!p) + throw CNewException(); + return p; + #else + numAllocs++; + int loc = numAllocs; + if (size == 0) + size = 1; + void *p = malloc(size); + /* + if (g_index < kDebugSize) + { + a[g_index] = p; + g_index++; + } + */ + printf("Alloc %6d, size = %8u\n", loc, (unsigned)size); + if (!p) + throw CNewException(); + return p; + #endif +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw() +{ + if (!p) + return; + #ifdef _WIN32 + EnterCriticalSection(&cs); + /* + for (int i = 0; i < g_index; i++) + if (a[i] == p) + a[i] = 0; + */ + HeapFree(GetProcessHeap(), 0, p); + // if (numAllocs == 0) numAllocs = numAllocs; // ERROR + numAllocs--; + // if (numAllocs == 0) numAllocs = numAllocs; // OK: all objects were deleted + printf("Free %d\n", numAllocs); + LeaveCriticalSection(&cs); + #else + free(p); + numAllocs--; + printf("Free %d\n", numAllocs); + #endif +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t n) throw(); +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t n) throw() +{ + UNUSED_VAR(n) + printf("delete_WITH_SIZE=%u, ptr = %p\n", (unsigned)n, p); + operator delete(p); +} + +/* +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size) +{ + printf("operator_new[] : "); + return operator new(size); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size : size=%d : ", (unsigned)sz); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw() +{ + if (!p) + return; + printf("operator_delete[] : "); + operator delete(p); +} + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p, size_t sz) throw() +{ + if (!p) + return; + printf("operator_delete_size[] : size=%d : ", (unsigned)sz); + operator delete(p); +} +*/ + +#endif + +/* +int MemErrorVC(size_t) +{ + throw CNewException(); + // return 1; +} +CNewHandlerSetter::CNewHandlerSetter() +{ + // MemErrorOldVCFunction = _set_new_handler(MemErrorVC); +} +CNewHandlerSetter::~CNewHandlerSetter() +{ + // _set_new_handler(MemErrorOldVCFunction); +} +*/ diff -Nru p7zip-rar-16.02/CPP/Common/NewHandler.h p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.h --- p7zip-rar-16.02/CPP/Common/NewHandler.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/NewHandler.h 2024-01-22 11:00:00.000000000 +0000 @@ -1,69 +1,121 @@ -// Common/NewHandler.h - -#ifndef __COMMON_NEW_HANDLER_H -#define __COMMON_NEW_HANDLER_H - -/* -This file must be included before any code that uses operators "delete" or "new". -Also you must compile and link "NewHandler.cpp", if you use MSVC 6.0. -The operator "new" in MSVC 6.0 doesn't throw exception "bad_alloc". -So we define another version of operator "new" that throws "CNewException" on failure. - -If you use compiler that throws exception in "new" operator (GCC or new version of MSVC), -you can compile without "NewHandler.cpp". So standard exception "bad_alloc" will be used. - -It's still allowed to use redefined version of operator "new" from "NewHandler.cpp" -with any compiler. 7-Zip's code can work with "bad_alloc" and "CNewException" exceptions. -But if you use some additional code (outside of 7-Zip's code), you must check -that redefined version of operator "new" (that throws CNewException) is not -problem for your code. - -Also we declare delete(void *p) throw() that creates smaller code. -*/ - -#include - -class CNewException {}; - -#ifdef WIN32 -// We can compile my_new and my_delete with _fastcall -/* -void * my_new(size_t size); -void my_delete(void *p) throw(); -// void * my_Realloc(void *p, size_t newSize, size_t oldSize); -*/ -#endif - -#ifdef _WIN32 - -void * -#ifdef _MSC_VER -__cdecl -#endif -operator new(size_t size); - -void -#ifdef _MSC_VER -__cdecl -#endif -operator delete(void *p) throw(); - -#endif - -/* -#ifdef _WIN32 -void * -#ifdef _MSC_VER -__cdecl -#endif -operator new[](size_t size); - -void -#ifdef _MSC_VER -__cdecl -#endif -operator delete[](void *p) throw(); -#endif -*/ - -#endif +// Common/NewHandler.h + +#ifndef ZIP7_INC_COMMON_NEW_HANDLER_H +#define ZIP7_INC_COMMON_NEW_HANDLER_H + +/* +NewHandler.h and NewHandler.cpp allows to solve problem with compilers that +don't throw exception in operator new(). + +This file must be included before any code that uses operators new() or delete() +and you must compile and link "NewHandler.cpp", if you use some old MSVC compiler. + +DOCs: + Since ISO C++98, operator new throws std::bad_alloc when memory allocation fails. + MSVC 6.0 returned a null pointer on an allocation failure. + Beginning in VS2002, operator new conforms to the standard and throws on failure. + + By default, the compiler also generates defensive null checks to prevent + these older-style allocators from causing an immediate crash on failure. + The /Zc:throwingNew option tells the compiler to leave out these null checks, + on the assumption that all linked memory allocators conform to the standard. + +The operator new() in some MSVC versions doesn't throw exception std::bad_alloc. +MSVC 6.0 (_MSC_VER == 1200) doesn't throw exception. +The code produced by some another MSVC compilers also can be linked +to library that doesn't throw exception. +We suppose that code compiled with VS2015+ (_MSC_VER >= 1900) throws exception std::bad_alloc. +For older _MSC_VER versions we redefine operator new() and operator delete(). +Our version of operator new() throws CNewException() exception on failure. + +It's still allowed to use redefined version of operator new() from "NewHandler.cpp" +with any compiler. 7-Zip's code can work with std::bad_alloc and CNewException() exceptions. +But if you use some additional code (outside of 7-Zip's code), you must check +that redefined version of operator new() is not problem for your code. +*/ + +#include + +#ifdef _WIN32 +// We can compile my_new and my_delete with _fastcall +/* +void * my_new(size_t size); +void my_delete(void *p) throw(); +// void * my_Realloc(void *p, size_t newSize, size_t oldSize); +*/ +#endif + + +#if defined(_MSC_VER) && (_MSC_VER < 1600) + // If you want to use default operator new(), you can disable the following line + #define Z7_REDEFINE_OPERATOR_NEW +#endif + + +#ifdef Z7_REDEFINE_OPERATOR_NEW + +// std::bad_alloc can require additional DLL dependency. +// So we don't define CNewException as std::bad_alloc here. + +class CNewException {}; + +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new(size_t size); + +/* +#if 0 && defined(_MSC_VER) && _MSC_VER == 1600 + #define Z7_OPERATOR_DELETE_SPEC_THROW0 +#else + #define Z7_OPERATOR_DELETE_SPEC_THROW0 throw() +#endif +*/ +#if defined(_MSC_VER) && _MSC_VER == 1600 +#pragma warning(push) +#pragma warning(disable : 4986) // 'operator delete': exception specification does not match previous declaration +#endif + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p) throw(); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete(void *p, size_t n) throw(); + +#if defined(_MSC_VER) && _MSC_VER == 1600 +#pragma warning(pop) +#endif + + +#else + +#include + +#define CNewException std::bad_alloc + +#endif + +/* +#ifdef _WIN32 +void * +#ifdef _MSC_VER +__cdecl +#endif +operator new[](size_t size); + +void +#ifdef _MSC_VER +__cdecl +#endif +operator delete[](void *p) throw(); +#endif +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Random.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.cpp --- p7zip-rar-16.02/CPP/Common/Random.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.cpp 2023-09-07 14:00:00.000000000 +0000 @@ -0,0 +1,28 @@ +// Common/Random.cpp + +#include "StdAfx.h" + +#include + +#ifndef _WIN32 +#include +#else +#include "MyWindows.h" +#endif + +#include "Random.h" + +void CRandom::Init(unsigned seed) { srand(seed); } + +void CRandom::Init() +{ + Init((unsigned) + #ifdef _WIN32 + GetTickCount() + #else + time(NULL) + #endif + ); +} + +int CRandom::Generate() const { return rand(); } diff -Nru p7zip-rar-16.02/CPP/Common/Random.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.h --- p7zip-rar-16.02/CPP/Common/Random.h 2015-11-20 20:40:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Random.h 2023-09-07 14:00:00.000000000 +0000 @@ -1,14 +1,14 @@ -// Common/Random.h - -#ifndef __COMMON_RANDOM_H -#define __COMMON_RANDOM_H - -class CRandom -{ -public: - void Init(); - void Init(unsigned int seed); - int Generate() const; -}; - -#endif +// Common/Random.h + +#ifndef ZIP7_INC_COMMON_RANDOM_H +#define ZIP7_INC_COMMON_RANDOM_H + +class CRandom +{ +public: + void Init(); + void Init(unsigned seed); + int Generate() const; +}; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Sha1Prepare.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Prepare.cpp --- p7zip-rar-16.02/CPP/Common/Sha1Prepare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Prepare.cpp 2021-01-23 07:44:01.000000000 +0000 @@ -0,0 +1,7 @@ +// Sha1Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/Sha1.h" + +static struct CSha1Prepare { CSha1Prepare() { Sha1Prepare(); } } g_Sha1Prepare; diff -Nru p7zip-rar-16.02/CPP/Common/Sha1Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Reg.cpp --- p7zip-rar-16.02/CPP/Common/Sha1Reg.cpp 2016-05-18 17:31:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha1Reg.cpp 2023-03-16 20:00:00.000000000 +0000 @@ -1,40 +1,67 @@ -// Sha1Reg.cpp - -#include "StdAfx.h" - -#include "../../C/Sha1.h" - -#include "../Common/MyCom.h" - -#include "../7zip/Common/RegisterCodec.h" - -class CSha1Hasher: - public IHasher, - public CMyUnknownImp -{ - CSha1 _sha; - Byte mtDummy[1 << 7]; - -public: - CSha1Hasher() { Sha1_Init(&_sha); } - - MY_UNKNOWN_IMP1(IHasher) - INTERFACE_IHasher(;) -}; - -STDMETHODIMP_(void) CSha1Hasher::Init() throw() -{ - Sha1_Init(&_sha); -} - -STDMETHODIMP_(void) CSha1Hasher::Update(const void *data, UInt32 size) throw() -{ - Sha1_Update(&_sha, (const Byte *)data, size); -} - -STDMETHODIMP_(void) CSha1Hasher::Final(Byte *digest) throw() -{ - Sha1_Final(&_sha, digest); -} - -REGISTER_HASHER(CSha1Hasher, 0x201, "SHA1", SHA1_DIGEST_SIZE) +// Sha1Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha1.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_2( + CSha1Hasher + , IHasher + , ICompressSetCoderProperties +) + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_buf; } +public: + CSha1Hasher(): + _buf(sizeof(CSha1)) + { + Sha1_SetFunction(Sha(), 0); + Sha1_InitState(Sha()); + } +}; + +Z7_COM7F_IMF2(void, CSha1Hasher::Init()) +{ + Sha1_InitState(Sha()); +} + +Z7_COM7F_IMF2(void, CSha1Hasher::Update(const void *data, UInt32 size)) +{ + Sha1_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha1Hasher::Final(Byte *digest)) +{ + Sha1_Final(Sha(), digest); +} + + +Z7_COM7F_IMF(CSha1Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 2) + return E_NOTIMPL; + algo = (unsigned)prop.ulVal; + } + } + if (!Sha1_SetFunction(Sha(), algo)) + return E_NOTIMPL; + return S_OK; +} + +REGISTER_HASHER(CSha1Hasher, 0x201, "SHA1", SHA1_DIGEST_SIZE) diff -Nru p7zip-rar-16.02/CPP/Common/Sha256Prepare.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Prepare.cpp --- p7zip-rar-16.02/CPP/Common/Sha256Prepare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Prepare.cpp 2021-01-23 07:44:19.000000000 +0000 @@ -0,0 +1,7 @@ +// Sha256Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/Sha256.h" + +static struct CSha256Prepare { CSha256Prepare() { Sha256Prepare(); } } g_Sha256Prepare; diff -Nru p7zip-rar-16.02/CPP/Common/Sha256Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Reg.cpp --- p7zip-rar-16.02/CPP/Common/Sha256Reg.cpp 2016-05-18 17:31:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha256Reg.cpp 2023-03-16 20:00:00.000000000 +0000 @@ -1,40 +1,67 @@ -// Sha256Reg.cpp - -#include "StdAfx.h" - -#include "../../C/Sha256.h" - -#include "../Common/MyCom.h" - -#include "../7zip/Common/RegisterCodec.h" - -class CSha256Hasher: - public IHasher, - public CMyUnknownImp -{ - CSha256 _sha; - Byte mtDummy[1 << 7]; - -public: - CSha256Hasher() { Sha256_Init(&_sha); } - - MY_UNKNOWN_IMP1(IHasher) - INTERFACE_IHasher(;) -}; - -STDMETHODIMP_(void) CSha256Hasher::Init() throw() -{ - Sha256_Init(&_sha); -} - -STDMETHODIMP_(void) CSha256Hasher::Update(const void *data, UInt32 size) throw() -{ - Sha256_Update(&_sha, (const Byte *)data, size); -} - -STDMETHODIMP_(void) CSha256Hasher::Final(Byte *digest) throw() -{ - Sha256_Final(&_sha, digest); -} - -REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE) +// Sha256Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha256.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_2( + CSha256Hasher + , IHasher + , ICompressSetCoderProperties +) + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_buf; } +public: + CSha256Hasher(): + _buf(sizeof(CSha256)) + { + Sha256_SetFunction(Sha(), 0); + Sha256_InitState(Sha()); + } +}; + +Z7_COM7F_IMF2(void, CSha256Hasher::Init()) +{ + Sha256_InitState(Sha()); +} + +Z7_COM7F_IMF2(void, CSha256Hasher::Update(const void *data, UInt32 size)) +{ + Sha256_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha256Hasher::Final(Byte *digest)) +{ + Sha256_Final(Sha(), digest); +} + + +Z7_COM7F_IMF(CSha256Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 2) + return E_NOTIMPL; + algo = (unsigned)prop.ulVal; + } + } + if (!Sha256_SetFunction(Sha(), algo)) + return E_NOTIMPL; + return S_OK; +} + +REGISTER_HASHER(CSha256Hasher, 0xA, "SHA256", SHA256_DIGEST_SIZE) diff -Nru p7zip-rar-16.02/CPP/Common/Sha3Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha3Reg.cpp --- p7zip-rar-16.02/CPP/Common/Sha3Reg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha3Reg.cpp 2024-12-01 09:00:00.000000000 +0000 @@ -0,0 +1,76 @@ +// Sha3Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha3.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CSha3Hasher + , IHasher +) + unsigned _digestSize; + bool _isShake; + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha3 *Sha() { return (CSha3 *)(void *)(Byte *)_buf; } +public: + CSha3Hasher(unsigned digestSize, bool isShake, unsigned blockSize): + _digestSize(digestSize), + _isShake(isShake), + _buf(sizeof(CSha3)) + { + CSha3 *p = Sha(); + Sha3_SET_blockSize(p, blockSize) + Sha3_Init(Sha()); + } +}; + +Z7_COM7F_IMF2(void, CSha3Hasher::Init()) +{ + Sha3_Init(Sha()); +} + +Z7_COM7F_IMF2(void, CSha3Hasher::Update(const void *data, UInt32 size)) +{ + Sha3_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha3Hasher::Final(Byte *digest)) +{ + Sha3_Final(Sha(), digest, _digestSize, _isShake); +} + +Z7_COM7F_IMF2(UInt32, CSha3Hasher::GetDigestSize()) +{ + return (UInt32)_digestSize; +} + + +#define REGISTER_SHA3_HASHER_2(cls, id, name, digestSize, isShake, digestSize_for_blockSize) \ + namespace N ## cls { \ + static IHasher *CreateHasherSpec() \ + { return new CSha3Hasher(digestSize / 8, isShake, \ + SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize_for_blockSize / 8)); } \ + static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, digestSize / 8 }; \ + struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ + static REGISTER_HASHER_NAME(cls) g_RegisterHasher; } + +#define REGISTER_SHA3_HASHER( cls, id, name, size, isShake) \ + REGISTER_SHA3_HASHER_2(cls, id, name, size, isShake, size) + +// REGISTER_SHA3_HASHER (Sha3_224_Hasher, 0x230, "SHA3-224", 224, false) +REGISTER_SHA3_HASHER (Sha3_256_Hasher, 0x231, "SHA3-256", 256, false) +// REGISTER_SHA3_HASHER (Sha3_386_Hasher, 0x232, "SHA3-384", 384, false) +// REGISTER_SHA3_HASHER (Sha3_512_Hasher, 0x233, "SHA3-512", 512, false) +// REGISTER_SHA3_HASHER (Shake128_Hasher, 0x240, "SHAKE128", 128, true) +// REGISTER_SHA3_HASHER (Shake256_Hasher, 0x241, "SHAKE256", 256, true) +// REGISTER_SHA3_HASHER_2 (Shake128_512_Hasher, 0x248, "SHAKE128-256", 256, true, 128) // -1344 (max) +// REGISTER_SHA3_HASHER_2 (Shake256_512_Hasher, 0x249, "SHAKE256-512", 512, true, 256) // -1088 (max) +// Shake supports different digestSize values for same blockSize diff -Nru p7zip-rar-16.02/CPP/Common/Sha512Prepare.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Prepare.cpp --- p7zip-rar-16.02/CPP/Common/Sha512Prepare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Prepare.cpp 2024-11-12 09:00:00.000000000 +0000 @@ -0,0 +1,7 @@ +// Sha512Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/Sha512.h" + +static struct CSha512Prepare { CSha512Prepare() { Sha512Prepare(); } } g_Sha512Prepare; diff -Nru p7zip-rar-16.02/CPP/Common/Sha512Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Reg.cpp --- p7zip-rar-16.02/CPP/Common/Sha512Reg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Sha512Reg.cpp 2024-11-12 09:00:00.000000000 +0000 @@ -0,0 +1,83 @@ +// Sha512Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha512.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_2( + CSha512Hasher + , IHasher + , ICompressSetCoderProperties +) + unsigned _digestSize; + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha512 *Sha() { return (CSha512 *)(void *)(Byte *)_buf; } +public: + CSha512Hasher(unsigned digestSize): + _digestSize(digestSize), + _buf(sizeof(CSha512)) + { + Sha512_SetFunction(Sha(), 0); + Sha512_InitState(Sha(), _digestSize); + } +}; + +Z7_COM7F_IMF2(void, CSha512Hasher::Init()) +{ + Sha512_InitState(Sha(), _digestSize); +} + +Z7_COM7F_IMF2(void, CSha512Hasher::Update(const void *data, UInt32 size)) +{ + Sha512_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha512Hasher::Final(Byte *digest)) +{ + Sha512_Final(Sha(), digest, _digestSize); +} + +Z7_COM7F_IMF2(UInt32, CSha512Hasher::GetDigestSize()) +{ + return (UInt32)_digestSize; +} + +Z7_COM7F_IMF(CSha512Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 2) + return E_NOTIMPL; + algo = (unsigned)prop.ulVal; + } + } + if (!Sha512_SetFunction(Sha(), algo)) + return E_NOTIMPL; + return S_OK; +} + +#define REGISTER_SHA512_HASHER(cls, id, name, size) \ + namespace N ## cls { \ + static IHasher *CreateHasherSpec() { return new CSha512Hasher(size); } \ + static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ + struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ + static REGISTER_HASHER_NAME(cls) g_RegisterHasher; } + +// REGISTER_SHA512_HASHER (Sha512_224_Hasher, 0x220, "SHA512-224", SHA512_224_DIGEST_SIZE) +// REGISTER_SHA512_HASHER (Sha512_256_Hasher, 0x221, "SHA512-256", SHA512_256_DIGEST_SIZE) +REGISTER_SHA512_HASHER (Sha384Hasher, 0x222, "SHA384", SHA512_384_DIGEST_SIZE) +REGISTER_SHA512_HASHER (Sha512Hasher, 0x223, "SHA512", SHA512_DIGEST_SIZE) diff -Nru p7zip-rar-16.02/CPP/Common/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/Common/StdAfx.h --- p7zip-rar-16.02/CPP/Common/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#include "Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/StdInStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.cpp --- p7zip-rar-16.02/CPP/Common/StdInStream.cpp 2015-09-29 15:56:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.cpp 2023-12-11 13:00:00.000000000 +0000 @@ -1,119 +1,98 @@ -// Common/StdInStream.cpp - -#include "StdAfx.h" - -#include - -#include "StdInStream.h" -#include "StringConvert.h" -#include "UTFConvert.h" - -static const char kNewLineChar = '\n'; - -static const char *kEOFMessage = "Unexpected end of input stream"; -static const char *kReadErrorMessage ="Error reading input stream"; -static const char *kIllegalCharMessage = "Illegal character in input stream"; - -// static LPCTSTR kFileOpenMode = TEXT("r"); - -// extern int g_CodePage; - -#ifdef _UNICODE -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" -#endif - -CStdInStream g_StdIn(stdin); - -bool CStdInStream::Open(LPCTSTR fileName) throw() -{ - Close(); -// _stream = _tfopen(fileName, kFileOpenMode); -#ifdef _UNICODE - AString aStr = UnicodeStringToMultiByte(fileName, CP_ACP); // FIXME - const char * name = nameWindowToUnix(aStr); -#else - const char * name = nameWindowToUnix(fileName); -#endif - _stream = fopen(name, "r"); - _streamIsOpen = (_stream != 0); - return _streamIsOpen; -} - -bool CStdInStream::Close() throw() -{ - if (!_streamIsOpen) - return true; - _streamIsOpen = (fclose(_stream) != 0); - return !_streamIsOpen; -} - -AString CStdInStream::ScanStringUntilNewLine(bool allowEOF) -{ - AString s; - for (;;) - { - int intChar = GetChar(); - if (intChar == EOF) - { - if (allowEOF) - break; - throw kEOFMessage; - } - char c = (char)intChar; - if (c == 0) - throw kIllegalCharMessage; - if (c == kNewLineChar) - break; - s += c; - } - return s; -} - -#ifdef _WIN32 -UString CStdInStream::ScanUStringUntilNewLine() -{ - AString s = ScanStringUntilNewLine(true); - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - UString dest; - if (codePage == CP_UTF8) - ConvertUTF8ToUnicode(s, dest); - else - dest = MultiByteToUnicodeString(s, (UINT)codePage); - return dest; -} -#else - -#ifndef ENV_HAVE_GETPASS -UString CStdInStream::ScanUStringUntilNewLine() -{ - AString s = ScanStringUntilNewLine(true); - UString dest = MultiByteToUnicodeString(s, (UINT)-1); - return dest; -} -#endif - -#endif - -void CStdInStream::ReadToString(AString &resultString) -{ - resultString.Empty(); - int c; - while ((c = GetChar()) != EOF) - resultString += (char)c; -} - -bool CStdInStream::Eof() throw() -{ - return (feof(_stream) != 0); -} - -int CStdInStream::GetChar() -{ - int c = fgetc(_stream); // getc() doesn't work in BeOS? - if (c == EOF && !Eof()) - throw kReadErrorMessage; - return c; -} +// Common/StdInStream.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#endif + +#include "StdInStream.h" +#include "StringConvert.h" +#include "UTFConvert.h" + +// #define kEOFMessage "Unexpected end of input stream" +// #define kReadErrorMessage "Error reading input stream" +// #define kIllegalCharMessage "Illegal zero character in input stream" + + +CStdInStream g_StdIn(stdin); + +/* +#define kFileOpenMode TEXT("r") + +bool CStdInStream::Open(LPCTSTR fileName) throw() +{ + Close(); + _stream = + #ifdef _WIN32 + _tfopen + #else + fopen + #endif + (fileName, kFileOpenMode); + _streamIsOpen = (_stream != 0); + return _streamIsOpen; +} + +bool CStdInStream::Close() throw() +{ + if (!_streamIsOpen) + return true; + _streamIsOpen = (fclose(_stream) != 0); + return !_streamIsOpen; +} +*/ + +bool CStdInStream::ScanAStringUntilNewLine(AString &s) +{ + s.Empty(); + for (;;) + { + const int intChar = GetChar(); + if (intChar == EOF) + return true; + const char c = (char)intChar; + if (c == 0) + return false; + if (c == '\n') + return true; + s.Add_Char(c); + } +} + +bool CStdInStream::ScanUStringUntilNewLine(UString &dest) +{ + dest.Empty(); + AString s; + const bool res = ScanAStringUntilNewLine(s); + int codePage = CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if ((unsigned)codePage == CP_UTF8) + ConvertUTF8ToUnicode(s, dest); + else + MultiByteToUnicodeString2(dest, s, (UINT)(unsigned)codePage); + return res; +} + +/* +bool CStdInStream::ReadToString(AString &resultString) +{ + resultString.Empty(); + for (;;) + { + int intChar = GetChar(); + if (intChar == EOF) + return !Error(); + char c = (char)intChar; + if (c == 0) + return false; + resultString += c; + } +} +*/ + +int CStdInStream::GetChar() +{ + return fgetc(_stream); // getc() doesn't work in BeOS? +} diff -Nru p7zip-rar-16.02/CPP/Common/StdInStream.h p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.h --- p7zip-rar-16.02/CPP/Common/StdInStream.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StdInStream.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,33 +1,46 @@ -// Common/StdInStream.h - -#ifndef __COMMON_STD_IN_STREAM_H -#define __COMMON_STD_IN_STREAM_H - -#include - -#include "MyString.h" -#include "MyTypes.h" - -class CStdInStream -{ - FILE *_stream; - bool _streamIsOpen; -public: - CStdInStream(): _stream(0), _streamIsOpen(false) {}; - CStdInStream(FILE *stream): _stream(stream), _streamIsOpen(false) {}; - ~CStdInStream() { Close(); } - - bool Open(LPCTSTR fileName) throw(); - bool Close() throw(); - - AString ScanStringUntilNewLine(bool allowEOF = false); - void ReadToString(AString &resultString); - UString ScanUStringUntilNewLine(); - - bool Eof() throw(); - int GetChar(); -}; - -extern CStdInStream g_StdIn; - -#endif +// Common/StdInStream.h + +#ifndef ZIP7_INC_COMMON_STD_IN_STREAM_H +#define ZIP7_INC_COMMON_STD_IN_STREAM_H + +#include + +#include "MyString.h" +#include "MyTypes.h" + +class CStdInStream +{ + FILE *_stream; + // bool _streamIsOpen; +public: + int CodePage; + + CStdInStream(FILE *stream = NULL): + _stream(stream), + // _streamIsOpen(false), + CodePage(-1) + {} + + /* + ~CStdInStream() { Close(); } + + bool Open(LPCTSTR fileName) throw(); + bool Close() throw(); + */ + + // returns: + // false, if ZERO character in stream + // true, if EOF or '\n' + bool ScanAStringUntilNewLine(AString &s); + bool ScanUStringUntilNewLine(UString &s); + // bool ReadToString(AString &resultString); + + bool Eof() const throw() { return (feof(_stream) != 0); } + bool Error() const throw() { return (ferror(_stream) != 0); } + + int GetChar(); +}; + +extern CStdInStream g_StdIn; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/StdOutStream.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.cpp --- p7zip-rar-16.02/CPP/Common/StdOutStream.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.cpp 2024-02-09 09:00:00.000000000 +0000 @@ -1,106 +1,248 @@ -// Common/StdOutStream.cpp - -#include "StdAfx.h" - -#include - -#include "IntToString.h" -#include "StdOutStream.h" -#include "StringConvert.h" -#include "UTFConvert.h" - -static const char kNewLineChar = '\n'; - -static const char *kFileOpenMode = "wt"; - -extern int g_CodePage; - -CStdOutStream g_StdOut(stdout); -CStdOutStream g_StdErr(stderr); - -bool CStdOutStream::Open(const char *fileName) throw() -{ - Close(); - _stream = fopen(fileName, kFileOpenMode); - _streamIsOpen = (_stream != 0); - return _streamIsOpen; -} - -bool CStdOutStream::Close() throw() -{ - if (!_streamIsOpen) - return true; - if (fclose(_stream) != 0) - return false; - _stream = 0; - _streamIsOpen = false; - return true; -} - -bool CStdOutStream::Flush() throw() -{ - return (fflush(_stream) == 0); -} - -CStdOutStream & endl(CStdOutStream & outStream) throw() -{ - return outStream << kNewLineChar; -} - -CStdOutStream & CStdOutStream::operator<<(const wchar_t *s) -{ - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - AString dest; - if (codePage == CP_UTF8) - ConvertUnicodeToUTF8(s, dest); - else - UnicodeStringToMultiByte2(dest, s, (UINT)codePage); - return operator<<((const char *)dest); -} - -void StdOut_Convert_UString_to_AString(const UString &s, AString &temp) -{ - int codePage = g_CodePage; - if (codePage == -1) - codePage = CP_OEMCP; - if (codePage == CP_UTF8) - ConvertUnicodeToUTF8(s, temp); - else - UnicodeStringToMultiByte2(temp, s, (UINT)codePage); -} - -void CStdOutStream::PrintUString(const UString &s, AString &temp) -{ - StdOut_Convert_UString_to_AString(s, temp); - *this << (const char *)temp; -} - -CStdOutStream & CStdOutStream::operator<<(Int32 number) throw() -{ - char s[32]; - ConvertInt64ToString(number, s); - return operator<<(s); -} - -CStdOutStream & CStdOutStream::operator<<(Int64 number) throw() -{ - char s[32]; - ConvertInt64ToString(number, s); - return operator<<(s); -} - -CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw() -{ - char s[16]; - ConvertUInt32ToString(number, s); - return operator<<(s); -} - -CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw() -{ - char s[32]; - ConvertUInt64ToString(number, s); - return operator<<(s); -} +// Common/StdOutStream.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#endif + +#include "IntToString.h" +#include "StdOutStream.h" +#include "StringConvert.h" +#include "UTFConvert.h" + +CStdOutStream g_StdOut(stdout); +CStdOutStream g_StdErr(stderr); + +/* +// #define kFileOpenMode "wt" + +bool CStdOutStream::Open(const char *fileName) throw() +{ + Close(); + _stream = fopen(fileName, kFileOpenMode); + _streamIsOpen = (_stream != 0); + return _streamIsOpen; +} + +bool CStdOutStream::Close() throw() +{ + if (!_streamIsOpen) + return true; + if (fclose(_stream) != 0) + return false; + _stream = 0; + _streamIsOpen = false; + return true; +} +*/ + +bool CStdOutStream::Flush() throw() +{ + return (fflush(_stream) == 0); +} + +CStdOutStream & endl(CStdOutStream & outStream) throw() +{ + return outStream << '\n'; +} + +CStdOutStream & CStdOutStream::operator<<(const wchar_t *s) +{ + AString temp; + UString s2(s); + PrintUString(s2, temp); + return *this; +} + +void CStdOutStream::PrintUString(const UString &s, AString &temp) +{ + Convert_UString_to_AString(s, temp); + *this << (const char *)temp; +} + +void CStdOutStream::Convert_UString_to_AString(const UString &src, AString &dest) +{ + int codePage = CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if ((unsigned)codePage == CP_UTF8) + ConvertUnicodeToUTF8(src, dest); + else + UnicodeStringToMultiByte2(dest, src, (UINT)(unsigned)codePage); +} + + +static const wchar_t kReplaceChar = '_'; + +/* +void CStdOutStream::Normalize_UString_LF_Allowed(UString &s) +{ + if (!IsTerminalMode) + return; + + const unsigned len = s.Len(); + wchar_t *d = s.GetBuf(); + + for (unsigned i = 0; i < len; i++) + { + const wchar_t c = d[i]; + if (c == 0x1b || (c <= 13 && c >= 7 && c != '\n')) + d[i] = kReplaceChar; + } +} +*/ + +void CStdOutStream::Normalize_UString(UString &s) +{ + const unsigned len = s.Len(); + wchar_t *d = s.GetBuf(); + + if (IsTerminalMode) + for (unsigned i = 0; i < len; i++) + { + const wchar_t c = d[i]; + if ((c <= 13 && c >= 7) || c == 0x1b) + d[i] = kReplaceChar; + } + else + for (unsigned i = 0; i < len; i++) + { + const wchar_t c = d[i]; + if (c == '\n') + d[i] = kReplaceChar; + } +} + +void CStdOutStream::Normalize_UString_Path(UString &s) +{ + if (ListPathSeparatorSlash.Def) + { +#ifdef _WIN32 + if (ListPathSeparatorSlash.Val) + s.Replace(L'\\', L'/'); +#else + if (!ListPathSeparatorSlash.Val) + s.Replace(L'/', L'\\'); +#endif + } + Normalize_UString(s); +} + + +/* +void CStdOutStream::Normalize_UString(UString &src) +{ + const wchar_t *s = src.Ptr(); + const unsigned len = src.Len(); + unsigned i; + for (i = 0; i < len; i++) + { + const wchar_t c = s[i]; +#if 0 && !defined(_WIN32) + if (c == '\\') // IsTerminalMode && + break; +#endif + if ((unsigned)c < 0x20) + break; + } + if (i == len) + return; + + UString temp; + for (i = 0; i < len; i++) + { + wchar_t c = s[i]; +#if 0 && !defined(_WIN32) + if (c == '\\') + temp += (wchar_t)L'\\'; + else +#endif + if ((unsigned)c < 0x20) + { + if (c == '\n' + || (IsTerminalMode && (c == 0x1b || (c <= 13 && c >= 7)))) + { +#if 1 || defined(_WIN32) + c = (wchar_t)kReplaceChar; +#else + temp += (wchar_t)L'\\'; + if (c == '\n') c = L'n'; + else if (c == '\r') c = L'r'; + else if (c == '\a') c = L'a'; + else if (c == '\b') c = L'b'; + else if (c == '\t') c = L't'; + else if (c == '\v') c = L'v'; + else if (c == '\f') c = L'f'; + else + { + temp += (wchar_t)(L'0' + (unsigned)c / 64); + temp += (wchar_t)(L'0' + (unsigned)c / 8 % 8); + c = (wchar_t)(L'0' + (unsigned)c % 8); + } +#endif + } + } + temp += c; + } + src = temp; +} +*/ + +void CStdOutStream::NormalizePrint_UString_Path(const UString &s, UString &tempU, AString &tempA) +{ + tempU = s; + Normalize_UString_Path(tempU); + PrintUString(tempU, tempA); +} + +void CStdOutStream::NormalizePrint_UString_Path(const UString &s) +{ + UString tempU; + AString tempA; + NormalizePrint_UString_Path(s, tempU, tempA); +} + +void CStdOutStream::NormalizePrint_wstr_Path(const wchar_t *s) +{ + UString tempU = s; + Normalize_UString_Path(tempU); + AString tempA; + PrintUString(tempU, tempA); +} + +void CStdOutStream::NormalizePrint_UString(const UString &s) +{ + UString tempU = s; + Normalize_UString(tempU); + AString tempA; + PrintUString(tempU, tempA); +} + +CStdOutStream & CStdOutStream::operator<<(Int32 number) throw() +{ + char s[32]; + ConvertInt64ToString(number, s); + return operator<<(s); +} + +CStdOutStream & CStdOutStream::operator<<(Int64 number) throw() +{ + char s[32]; + ConvertInt64ToString(number, s); + return operator<<(s); +} + +CStdOutStream & CStdOutStream::operator<<(UInt32 number) throw() +{ + char s[16]; + ConvertUInt32ToString(number, s); + return operator<<(s); +} + +CStdOutStream & CStdOutStream::operator<<(UInt64 number) throw() +{ + char s[32]; + ConvertUInt64ToString(number, s); + return operator<<(s); +} diff -Nru p7zip-rar-16.02/CPP/Common/StdOutStream.h p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.h --- p7zip-rar-16.02/CPP/Common/StdOutStream.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StdOutStream.h 2024-02-09 09:00:00.000000000 +0000 @@ -1,62 +1,87 @@ -// Common/StdOutStream.h - -#ifndef __COMMON_STD_OUT_STREAM_H -#define __COMMON_STD_OUT_STREAM_H - -#include - -#include "MyString.h" -#include "MyTypes.h" - -class CStdOutStream -{ - FILE *_stream; - bool _streamIsOpen; -public: - CStdOutStream(): _stream(0), _streamIsOpen(false) {}; - CStdOutStream(FILE *stream): _stream(stream), _streamIsOpen(false) {}; - ~CStdOutStream() { Close(); } - - // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; } - // bool IsDefined() const { return _stream != NULL; } - - operator FILE *() { return _stream; } - bool Open(const char *fileName) throw(); - bool Close() throw(); - bool Flush() throw(); - - CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &)) - { - (*func)(*this); - return *this; - } - - CStdOutStream & operator<<(const char *s) throw() - { - fputs(s, _stream); - return *this; - } - - CStdOutStream & operator<<(char c) throw() - { - fputc((unsigned char)c, _stream); - return *this; - } - - CStdOutStream & operator<<(Int32 number) throw(); - CStdOutStream & operator<<(Int64 number) throw(); - CStdOutStream & operator<<(UInt32 number) throw(); - CStdOutStream & operator<<(UInt64 number) throw(); - - CStdOutStream & operator<<(const wchar_t *s); - void PrintUString(const UString &s, AString &temp); -}; - -CStdOutStream & endl(CStdOutStream & outStream) throw(); - -extern CStdOutStream g_StdOut; -extern CStdOutStream g_StdErr; - -void StdOut_Convert_UString_to_AString(const UString &s, AString &temp); - -#endif +// Common/StdOutStream.h + +#ifndef ZIP7_INC_COMMON_STD_OUT_STREAM_H +#define ZIP7_INC_COMMON_STD_OUT_STREAM_H + +#include + +#include "MyString.h" +#include "MyTypes.h" + +class CStdOutStream +{ + FILE *_stream; + // bool _streamIsOpen; +public: + bool IsTerminalMode; + CBoolPair ListPathSeparatorSlash; + int CodePage; + + CStdOutStream(FILE *stream = NULL): + _stream(stream), + // _streamIsOpen(false), + IsTerminalMode(false), + CodePage(-1) + { + ListPathSeparatorSlash.Val = +#ifdef _WIN32 + false; +#else + true; +#endif + } + + // ~CStdOutStream() { Close(); } + + // void AttachStdStream(FILE *stream) { _stream = stream; _streamIsOpen = false; } + // bool IsDefined() const { return _stream != NULL; } + + operator FILE *() { return _stream; } + /* + bool Open(const char *fileName) throw(); + bool Close() throw(); + */ + bool Flush() throw(); + + CStdOutStream & operator<<(CStdOutStream & (* func)(CStdOutStream &)) + { + (*func)(*this); + return *this; + } + + CStdOutStream & operator<<(const char *s) throw() + { + fputs(s, _stream); + return *this; + } + + CStdOutStream & operator<<(char c) throw() + { + fputc((unsigned char)c, _stream); + return *this; + } + + CStdOutStream & operator<<(Int32 number) throw(); + CStdOutStream & operator<<(Int64 number) throw(); + CStdOutStream & operator<<(UInt32 number) throw(); + CStdOutStream & operator<<(UInt64 number) throw(); + + CStdOutStream & operator<<(const wchar_t *s); + void PrintUString(const UString &s, AString &temp); + void Convert_UString_to_AString(const UString &src, AString &dest); + + void Normalize_UString(UString &s); + void Normalize_UString_Path(UString &s); + + void NormalizePrint_UString_Path(const UString &s, UString &tempU, AString &tempA); + void NormalizePrint_UString_Path(const UString &s); + void NormalizePrint_UString(const UString &s); + void NormalizePrint_wstr_Path(const wchar_t *s); +}; + +CStdOutStream & endl(CStdOutStream & outStream) throw(); + +extern CStdOutStream g_StdOut; +extern CStdOutStream g_StdErr; + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/StringConvert.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.cpp --- p7zip-rar-16.02/CPP/Common/StringConvert.cpp 2016-02-23 21:49:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.cpp 2024-02-19 10:00:00.000000000 +0000 @@ -1,220 +1,762 @@ -// Common/StringConvert.cpp - -#include "StdAfx.h" - -#include "StringConvert.h" -extern "C" -{ -int global_use_utf16_conversion = 0; -} - -#ifdef LOCALE_IS_UTF8 - -#ifdef __APPLE_CC__ -#define UInt32 macUIn32 -#include -#undef UInt32 - -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) -{ - if (!srcString.IsEmpty()) - { - UString resultString; - const char * path = &srcString[0]; - -// FIXME size_t n = strlen(path); - - CFStringRef cfpath = CFStringCreateWithCString(NULL,path,kCFStringEncodingUTF8); - - if (cfpath) - { - - CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath); - CFRelease(cfpath); - CFStringNormalize(cfpath2,kCFStringNormalizationFormC); - - size_t n = CFStringGetLength(cfpath2); - for(size_t i = 0 ; i< n ;i++) { - UniChar uc = CFStringGetCharacterAtIndex(cfpath2,i); - resultString += (wchar_t)uc; // FIXME - } - - CFRelease(cfpath2); - - return resultString; - } - } - - UString resultString; - for (int i = 0; i < srcString.Len(); i++) - resultString += wchar_t(srcString[i] & 255); - - return resultString; -} - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) -{ - if (!srcString.IsEmpty()) - { - const wchar_t * wcs = &srcString[0]; - char utf8[4096]; - UniChar unipath[4096]; - - size_t n = wcslen(wcs); - - for(size_t i = 0 ; i<= n ;i++) { - unipath[i] = wcs[i]; - } - - CFStringRef cfpath = CFStringCreateWithCharacters(NULL,unipath,n); - - CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath); - CFRelease(cfpath); - CFStringNormalize(cfpath2,kCFStringNormalizationFormD); - - CFStringGetCString(cfpath2,(char *)utf8,4096,kCFStringEncodingUTF8); - - CFRelease(cfpath2); - - return AString(utf8); - } - - AString resultString; - for (int i = 0; i < srcString.Len(); i++) - { - if (srcString[i] >= 256) resultString += '?'; - else resultString += char(srcString[i]); - } - return resultString; -} - -#else /* __APPLE_CC__ */ - - -#include "UTFConvert.h" - -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) -{ - if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) - { - UString resultString; - bool bret = ConvertUTF8ToUnicode(srcString,resultString); - if (bret) return resultString; - } - - UString resultString; - for (int i = 0; i < srcString.Len(); i++) - resultString += wchar_t(srcString[i] & 255); - - return resultString; -} - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) -{ - if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) - { - AString resultString; - ConvertUnicodeToUTF8(srcString,resultString); - return resultString; - } - - AString resultString; - for (int i = 0; i < srcString.Len(); i++) - { - if (srcString[i] >= 256) resultString += '?'; - else resultString += char(srcString[i]); - } - return resultString; -} - -#endif /* __APPLE_CC__ */ - -#else /* LOCALE_IS_UTF8 */ - -UString MultiByteToUnicodeString(const AString &srcString, UINT /* codePage */ ) -{ -#ifdef ENV_HAVE_MBSTOWCS - if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) - { - UString resultString; - int numChars = mbstowcs(resultString.GetBuf(srcString.Len()),srcString,srcString.Len()+1); - if (numChars >= 0) { - resultString.ReleaseBuf_SetEnd(numChars); - -#if WCHAR_MAX > 0xffff - for (int i = numChars; i >= 0; i--) { - if (resultString[i] > 0xffff) { - wchar_t c = resultString[i] - 0x10000; - resultString.Delete(i); - wchar_t texts[]= { ((c >> 10) & 0x3ff) + 0xd800, (c & 0x3ff) + 0xdc00 , 0 }; - resultString.Insert(i, texts); - numChars++; - } - } -#endif - - return resultString; - } - } -#endif - - UString resultString; - for (int i = 0; i < srcString.Len(); i++) - resultString += wchar_t(srcString[i] & 255); - - return resultString; -} - -AString UnicodeStringToMultiByte(const UString &src, UINT /* codePage */ ) -{ -#ifdef ENV_HAVE_WCSTOMBS -#if WCHAR_MAX > 0xffff - UString srcString(src); - for (int i = 0; i < srcString.Len(); i++) { - if ((0xd800 <= srcString[i] && srcString[i] <= 0xdbff) && ((i + 1) < srcString.Len()) && - (0xdc00 <= srcString[i + 1] && srcString[i + 1] < 0xE000)) { - wchar_t c = (((srcString[i] - 0xd800) << 10) | (srcString[i + 1] - 0xdc00)) + 0x10000; - srcString.Delete(i, 2); - srcString.Insert(i, c); - } - } -#else - const UString &srcString = src; -#endif - - if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) - { - AString resultString; - int numRequiredBytes = srcString.Len() * 6+1; - int numChars = wcstombs(resultString.GetBuf(numRequiredBytes),srcString,numRequiredBytes); - if (numChars >= 0) { - resultString.ReleaseBuf_SetEnd(numChars); - return resultString; - } - } -#else - const UString &srcString = src; -#endif - - AString resultString; - for (int i = 0; i < srcString.Len(); i++) - { - if (srcString[i] >= 256) resultString += '?'; - else resultString += char(srcString[i]); - } - return resultString; -} - -#endif /* LOCALE_IS_UTF8 */ - - -void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage) -{ - dest = MultiByteToUnicodeString(srcString,codePage); -} - -void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage) -{ - dest = UnicodeStringToMultiByte(srcString,codePage); -} - +// Common/StringConvert.cpp + +#include "StdAfx.h" + +#include "StringConvert.h" + +#ifndef _WIN32 +// #include +#include +#endif + +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) +#include "UTFConvert.h" +#endif + +#ifdef ENV_HAVE_LOCALE +#include +#endif + +static const char k_DefultChar = '_'; + +#ifdef _WIN32 + +/* +MultiByteToWideChar(CodePage, DWORD dwFlags, + LPCSTR lpMultiByteStr, int cbMultiByte, + LPWSTR lpWideCharStr, int cchWideChar) + + if (cbMultiByte == 0) + return: 0. ERR: ERROR_INVALID_PARAMETER + + if (cchWideChar == 0) + return: the required buffer size in characters. + + if (supplied buffer size was not large enough) + return: 0. ERR: ERROR_INSUFFICIENT_BUFFER + The number of filled characters in lpWideCharStr can be smaller than cchWideChar (if last character is complex) + + If there are illegal characters: + if MB_ERR_INVALID_CHARS is set in dwFlags: + - the function stops conversion on illegal character. + - Return: 0. ERR: ERROR_NO_UNICODE_TRANSLATION. + + if MB_ERR_INVALID_CHARS is NOT set in dwFlags: + before Vista: illegal character is dropped (skipped). WinXP-64: GetLastError() returns 0. + in Vista+: illegal character is not dropped (MSDN). Undocumented: illegal + character is converted to U+FFFD, which is REPLACEMENT CHARACTER. +*/ + + +void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) +{ + dest.Empty(); + if (src.IsEmpty()) + return; + { + /* + wchar_t *d = dest.GetBuf(src.Len()); + const char *s = (const char *)src; + unsigned i; + + for (i = 0;;) + { + Byte c = (Byte)s[i]; + if (c >= 0x80 || c == 0) + break; + d[i++] = (wchar_t)c; + } + + if (i != src.Len()) + { + unsigned len = MultiByteToWideChar(codePage, 0, s + i, + src.Len() - i, d + i, + src.Len() + 1 - i); + if (len == 0) + throw 282228; + i += len; + } + + d[i] = 0; + dest.ReleaseBuf_SetLen(i); + */ + unsigned len = (unsigned)MultiByteToWideChar(codePage, 0, src, (int)src.Len(), NULL, 0); + if (len == 0) + { + if (GetLastError() != 0) + throw 282228; + } + else + { + len = (unsigned)MultiByteToWideChar(codePage, 0, src, (int)src.Len(), dest.GetBuf(len), (int)len); + if (len == 0) + throw 282228; + dest.ReleaseBuf_SetEnd(len); + } + } +} + +/* + int WideCharToMultiByte( + UINT CodePage, DWORD dwFlags, + LPCWSTR lpWideCharStr, int cchWideChar, + LPSTR lpMultiByteStr, int cbMultiByte, + LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar); + +if (lpDefaultChar == NULL), + - it uses system default value. + +if (CodePage == CP_UTF7 || CodePage == CP_UTF8) + if (lpDefaultChar != NULL || lpUsedDefaultChar != NULL) + return: 0. ERR: ERROR_INVALID_PARAMETER. + +The function operates most efficiently, if (lpDefaultChar == NULL && lpUsedDefaultChar == NULL) + +*/ + +static void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + dest.Empty(); + defaultCharWasUsed = false; + if (src.IsEmpty()) + return; + { + /* + unsigned numRequiredBytes = src.Len() * 2; + char *d = dest.GetBuf(numRequiredBytes); + const wchar_t *s = (const wchar_t *)src; + unsigned i; + + for (i = 0;;) + { + wchar_t c = s[i]; + if (c >= 0x80 || c == 0) + break; + d[i++] = (char)c; + } + + if (i != src.Len()) + { + BOOL defUsed = FALSE; + defaultChar = defaultChar; + + bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7); + unsigned len = WideCharToMultiByte(codePage, 0, s + i, src.Len() - i, + d + i, numRequiredBytes + 1 - i, + (isUtf ? NULL : &defaultChar), + (isUtf ? NULL : &defUsed)); + defaultCharWasUsed = (defUsed != FALSE); + if (len == 0) + throw 282229; + i += len; + } + + d[i] = 0; + dest.ReleaseBuf_SetLen(i); + */ + + /* + if (codePage != CP_UTF7) + { + const wchar_t *s = (const wchar_t *)src; + unsigned i; + for (i = 0;; i++) + { + wchar_t c = s[i]; + if (c >= 0x80 || c == 0) + break; + } + + if (s[i] == 0) + { + char *d = dest.GetBuf(src.Len()); + for (i = 0;;) + { + wchar_t c = s[i]; + if (c == 0) + break; + d[i++] = (char)c; + } + d[i] = 0; + dest.ReleaseBuf_SetLen(i); + return; + } + } + */ + + unsigned len = (unsigned)WideCharToMultiByte(codePage, 0, src, (int)src.Len(), NULL, 0, NULL, NULL); + if (len == 0) + { + if (GetLastError() != 0) + throw 282228; + } + else + { + BOOL defUsed = FALSE; + bool isUtf = (codePage == CP_UTF8 || codePage == CP_UTF7); + // defaultChar = defaultChar; + len = (unsigned)WideCharToMultiByte(codePage, 0, src, (int)src.Len(), + dest.GetBuf(len), (int)len, + (isUtf ? NULL : &defaultChar), + (isUtf ? NULL : &defUsed) + ); + if (!isUtf) + defaultCharWasUsed = (defUsed != FALSE); + if (len == 0) + throw 282228; + dest.ReleaseBuf_SetEnd(len); + } + } +} + +/* +#ifndef UNDER_CE +AString SystemStringToOemString(const CSysString &src) +{ + AString dest; + const unsigned len = src.Len() * 2; + CharToOem(src, dest.GetBuf(len)); + dest.ReleaseBuf_CalcLen(len); + return dest; +} +#endif +*/ + +#else // _WIN32 + +// #include +/* + if (wchar_t is 32-bit (#if WCHAR_MAX > 0xffff), + and utf-8 string contains big unicode character > 0xffff), + then we still use 16-bit surrogate pair in UString. + It simplifies another code where utf-16 encoding is used. + So we use surrogate-conversion code only in is file. +*/ + +/* + mbstowcs() returns error if there is error in utf-8 stream, + mbstowcs() returns error if there is single surrogates point (d800-dfff) in utf-8 stream +*/ + +/* +static void MultiByteToUnicodeString2_Native(UString &dest, const AString &src) +{ + dest.Empty(); + if (src.IsEmpty()) + return; + + const size_t limit = ((size_t)src.Len() + 1) * 2; + wchar_t *d = dest.GetBuf((unsigned)limit); + const size_t len = mbstowcs(d, src, limit); + if (len != (size_t)-1) + { + dest.ReleaseBuf_SetEnd((unsigned)len); + return; + } + dest.ReleaseBuf_SetEnd(0); +} +*/ + +bool g_ForceToUTF8 = true; // false; + +void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) +{ + dest.Empty(); + if (src.IsEmpty()) + return; + + if (codePage == CP_UTF8 || g_ForceToUTF8) + { +#if 1 + ConvertUTF8ToUnicode(src, dest); + return; +#endif + } + + const size_t limit = ((size_t)src.Len() + 1) * 2; + wchar_t *d = dest.GetBuf((unsigned)limit); + const size_t len = mbstowcs(d, src, limit); + if (len != (size_t)-1) + { + dest.ReleaseBuf_SetEnd((unsigned)len); + +#if WCHAR_MAX > 0xffff + d = dest.GetBuf(); + for (size_t i = 0;; i++) + { + wchar_t c = d[i]; + // printf("\ni=%2d c = %4x\n", (unsigned)i, (unsigned)c); + if (c == 0) + break; + if (c >= 0x10000 && c < 0x110000) + { + UString tempString = d + i; + const wchar_t *t = tempString.Ptr(); + + for (;;) + { + wchar_t w = *t++; + // printf("\nchar=%x\n", w); + if (w == 0) + break; + if (i == limit) + break; // unexpected error + if (w >= 0x10000 && w < 0x110000) + { +#if 1 + if (i + 1 == limit) + break; // unexpected error + w -= 0x10000; + d[i++] = (unsigned)0xd800 + (((unsigned)w >> 10) & 0x3ff); + w = 0xdc00 + (w & 0x3ff); +#else + // w = '_'; // for debug +#endif + } + d[i++] = w; + } + dest.ReleaseBuf_SetEnd((unsigned)i); + break; + } + } + +#endif + + /* + printf("\nMultiByteToUnicodeString2 (%d) %s\n", (int)src.Len(), src.Ptr()); + printf("char: "); + for (unsigned i = 0; i < src.Len(); i++) + printf (" %02x", (int)(Byte)src[i]); + printf("\n"); + printf("\n-> (%d) %ls\n", (int)dest.Len(), dest.Ptr()); + printf("wchar_t: "); + for (unsigned i = 0; i < dest.Len(); i++) + { + printf (" %02x", (int)dest[i]); + } + printf("\n"); + */ + + return; + } + + /* if there is mbstowcs() error, we have two ways: + + 1) change 0x80+ characters to some character: '_' + in that case we lose data, but we have correct UString() + and that scheme can show errors to user in early stages, + when file converted back to mbs() cannot be found + + 2) transfer bad characters in some UTF-16 range. + it can be non-original Unicode character. + but later we still can restore original character. + */ + + + // printf("\nmbstowcs ERROR !!!!!! s=%s\n", src.Ptr()); + { + unsigned i; + const char *s = (const char *)src; + for (i = 0;;) + { + Byte c = (Byte)s[i]; + if (c == 0) + break; + // we can use ascii compatibilty character '_' + // if (c > 0x7F) c = '_'; // we replace "bad: character + d[i++] = (wchar_t)c; + } + d[i] = 0; + dest.ReleaseBuf_SetLen(i); + } +} + +static void UnicodeStringToMultiByte2_Native(AString &dest, const UString &src) +{ + dest.Empty(); + if (src.IsEmpty()) + return; + + const size_t limit = ((size_t)src.Len() + 1) * 6; + char *d = dest.GetBuf((unsigned)limit); + + const size_t len = wcstombs(d, src, limit); + + if (len != (size_t)-1) + { + dest.ReleaseBuf_SetEnd((unsigned)len); + return; + } + dest.ReleaseBuf_SetEnd(0); +} + + +static void UnicodeStringToMultiByte2(AString &dest, const UString &src2, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + // if (codePage == 1234567) // for debug purposes + if (codePage == CP_UTF8 || g_ForceToUTF8) + { +#if 1 + defaultCharWasUsed = false; + ConvertUnicodeToUTF8(src2, dest); + return; +#endif + } + + UString src = src2; +#if WCHAR_MAX > 0xffff + { + src.Empty(); + for (unsigned i = 0; i < src2.Len();) + { + wchar_t c = src2[i++]; + if (c >= 0xd800 && c < 0xdc00 && i != src2.Len()) + { + const wchar_t c2 = src2[i]; + if (c2 >= 0xdc00 && c2 < 0xe000) + { +#if 1 + // printf("\nSurragate [%d]: %4x %4x -> ", i, (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + // printf("%4x\n", (int)c); + i++; +#else + // c = '_'; // for debug +#endif + } + } + src += c; + } + } +#endif + + dest.Empty(); + defaultCharWasUsed = false; + if (src.IsEmpty()) + return; + + const size_t len = wcstombs(NULL, src, 0); + + if (len != (size_t)-1) + { + const unsigned limit = ((unsigned)len); + if (limit == len) + { + char *d = dest.GetBuf(limit); + + /* + { + printf("\nwcstombs; len = %d %ls \n", (int)src.Len(), src.Ptr()); + for (unsigned i = 0; i < src.Len(); i++) + printf (" %02x", (int)src[i]); + printf("\n"); + printf("\ndest Limit = %d \n", limit); + } + */ + + const size_t len2 = wcstombs(d, src, len + 1); + + if (len2 != (size_t)-1 && len2 <= limit) + { + /* + printf("\nOK : destLen = %d : %s\n", (int)len, dest.Ptr()); + for (unsigned i = 0; i < len2; i++) + printf(" %02x", (int)(Byte)dest[i]); + printf("\n"); + */ + dest.ReleaseBuf_SetEnd((unsigned)len2); + return; + } + } + } + + { + const wchar_t *s = (const wchar_t *)src; + char *d = dest.GetBuf(src.Len()); + + unsigned i; + for (i = 0;;) + { + wchar_t c = s[i]; + if (c == 0) + break; + if (c >= + 0x100 + // 0x80 + ) + { + c = defaultChar; + defaultCharWasUsed = true; + } + + d[i++] = (char)c; + } + d[i] = 0; + dest.ReleaseBuf_SetLen(i); + /* + printf("\nUnicodeStringToMultiByte2; len = %d \n", (int)src.Len()); + printf("ERROR: %s\n", dest.Ptr()); + */ + } +} + +#endif // _WIN32 + + +UString MultiByteToUnicodeString(const AString &src, UINT codePage) +{ + UString dest; + MultiByteToUnicodeString2(dest, src, codePage); + return dest; +} + +UString MultiByteToUnicodeString(const char *src, UINT codePage) +{ + return MultiByteToUnicodeString(AString(src), codePage); +} + + +void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage) +{ + bool defaultCharWasUsed; + UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed); +} + +AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed) +{ + AString dest; + UnicodeStringToMultiByte2(dest, src, codePage, defaultChar, defaultCharWasUsed); + return dest; +} + +AString UnicodeStringToMultiByte(const UString &src, UINT codePage) +{ + AString dest; + bool defaultCharWasUsed; + UnicodeStringToMultiByte2(dest, src, codePage, k_DefultChar, defaultCharWasUsed); + return dest; +} + + + + +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) + +#ifdef _WIN32 +#define U_to_A(a, b, c) UnicodeStringToMultiByte2 +// #define A_to_U(a, b, c) MultiByteToUnicodeString2 +#else +// void MultiByteToUnicodeString2_Native(UString &dest, const AString &src); +#define U_to_A(a, b, c) UnicodeStringToMultiByte2_Native(a, b) +// #define A_to_U(a, b, c) MultiByteToUnicodeString2_Native(a, b) +#endif + +bool IsNativeUTF8() +{ + UString u; + AString a, a2; + // for (unsigned c = 0x80; c < (UInt32)0x10000; c += (c >> 9) + 1) + for (unsigned c = 0x80; c < (UInt32)0xD000; c += (c >> 2) + 1) + { + u.Empty(); + u += (wchar_t)c; + /* + if (Unicode_Is_There_Utf16SurrogateError(u)) + continue; + #ifndef _WIN32 + if (Unicode_Is_There_BmpEscape(u)) + continue; + #endif + */ + ConvertUnicodeToUTF8(u, a); + U_to_A(a2, u, CP_OEMCP); + if (a != a2) + return false; + } + return true; +} + +#endif + + +#ifdef ENV_HAVE_LOCALE + +const char *GetLocale(void) +{ + #ifdef ENV_HAVE_LOCALE + // printf("\n\nsetlocale(LC_CTYPE, NULL) : return : "); + const char *s = setlocale(LC_CTYPE, NULL); + if (!s) + { + // printf("[NULL]\n"); + s = "C"; + } + else + { + // ubuntu returns "C" after program start + // printf("\"%s\"\n", s); + } + return s; + #elif defined(LOCALE_IS_UTF8) + return "utf8"; + #else + return "C"; + #endif +} + +#ifdef _WIN32 + static void Set_ForceToUTF8(bool) {} +#else + static void Set_ForceToUTF8(bool val) { g_ForceToUTF8 = val; } +#endif + +static bool Is_Default_Basic_Locale(const char *locale) +{ + const AString a (locale); + if (a.IsEqualTo_Ascii_NoCase("") + || a.IsEqualTo_Ascii_NoCase("C") + || a.IsEqualTo_Ascii_NoCase("POSIX")) + return true; + return false; +} + +static bool Is_Default_Basic_Locale() +{ + return Is_Default_Basic_Locale(GetLocale()); +} + + +void MY_SetLocale() +{ + #ifdef ENV_HAVE_LOCALE + /* + { + const char *s = GetLocale(); + printf("\nGetLocale() : returned : \"%s\"\n", s); + } + */ + + unsigned start = 0; + // unsigned lim = 0; + unsigned lim = 3; + + /* + #define MY_SET_LOCALE_FLAGS__FROM_ENV 1 + #define MY_SET_LOCALE_FLAGS__TRY_UTF8 2 + + unsigned flags = + MY_SET_LOCALE_FLAGS__FROM_ENV | + MY_SET_LOCALE_FLAGS__TRY_UTF8 + + if (flags != 0) + { + if (flags & MY_SET_LOCALE_FLAGS__FROM_ENV) + lim = (flags & MY_SET_LOCALE_FLAGS__TRY_UTF8) ? 3 : 1; + else + { + start = 1; + lim = 2; + } + } + */ + + for (unsigned i = start; i < lim; i++) + { + /* + man7: "If locale is an empty string, "", each part of the locale that + should be modified is set according to the environment variables. + for glibc: glibc, first from the user's environment variables: + 1) the environment variable LC_ALL, + 2) environment variable with the same name as the category (see the + 3) the environment variable LANG + The locale "C" or "POSIX" is a portable locale; it exists on all conforming systems. + + for WIN32 : MSDN : + Sets the locale to the default, which is the user-default + ANSI code page obtained from the operating system. + The locale name is set to the value returned by GetUserDefaultLocaleName. + The code page is set to the value returned by GetACP + */ + const char *newLocale = ""; + + #ifdef __APPLE__ + + /* look also CFLocale + there is no C.UTF-8 in macos + macos has UTF-8 locale only with some language like en_US.UTF-8 + what is best way to set UTF-8 locale in macos? */ + if (i == 1) + newLocale = "en_US.UTF-8"; + + /* file open with non-utf8 sequencies return + #define EILSEQ 92 // "Illegal byte sequence" + */ +#else + // newLocale = "C"; + if (i == 1) + { + newLocale = "C.UTF-8"; // main UTF-8 locale in ubuntu + // newLocale = ".utf8"; // supported in new Windows 10 build 17134 (April 2018 Update), the Universal C Runtime + // newLocale = "en_US.utf8"; // supported by ubuntu ? + // newLocale = "en_US.UTF-8"; + /* setlocale() in ubuntu allows locales with minor chracter changes in strings + "en_US.UTF-8" / "en_US.utf8" */ + } + +#endif + + // printf("\nsetlocale(LC_ALL, \"%s\") : returned: ", newLocale); + + // const char *s = + setlocale(LC_ALL, newLocale); + + /* + if (!s) + printf("NULL: can't set locale"); + else + printf("\"%s\"\n", s); + */ + + // request curent locale of program + const char *locale = GetLocale(); + if (locale) + { + AString a (locale); + a.MakeLower_Ascii(); + // if (a.Find("utf") >= 0) + { + if (IsNativeUTF8()) + { + Set_ForceToUTF8(true); + return; + } + } + if (!Is_Default_Basic_Locale(locale)) + { + // if there is some non-default and non-utf locale, we want to use it + break; // comment it for debug + } + } + } + + if (IsNativeUTF8()) + { + Set_ForceToUTF8(true); + return; + } + + if (Is_Default_Basic_Locale()) + { + Set_ForceToUTF8(true); + return; + } + + Set_ForceToUTF8(false); + + #elif defined(LOCALE_IS_UTF8) + // assume LC_CTYPE="utf8" + #else + // assume LC_CTYPE="C" + #endif +} +#endif diff -Nru p7zip-rar-16.02/CPP/Common/StringConvert.h p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.h --- p7zip-rar-16.02/CPP/Common/StringConvert.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StringConvert.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,77 +1,110 @@ -// Common/StringConvert.h - -#ifndef __COMMON_STRING_CONVERT_H -#define __COMMON_STRING_CONVERT_H - -#include "MyString.h" -#include "MyWindows.h" - -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); - -// optimized versions that work faster for ASCII strings -void MultiByteToUnicodeString2(UString &dest, const AString &srcString, UINT codePage = CP_ACP); -// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed); -void UnicodeStringToMultiByte2(AString &dest, const UString &srcString, UINT codePage); - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage, char defaultChar, bool &defaultCharWasUsed); -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); - -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString) - { return unicodeString; } -inline UString GetUnicodeString(const AString &ansiString) - { return MultiByteToUnicodeString(ansiString); } -inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage); } -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString, UINT) - { return unicodeString; } - -inline const char* GetAnsiString(const char* ansiString) - { return ansiString; } -inline const AString& GetAnsiString(const AString &ansiString) - { return ansiString; } -inline AString GetAnsiString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - -inline const char* GetOemString(const char* oemString) - { return oemString; } -inline const AString& GetOemString(const AString &oemString) - { return oemString; } -inline AString GetOemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } - - -#ifdef _UNICODE - inline const wchar_t* GetSystemString(const wchar_t* unicodeString) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString) - { return unicodeString;} - inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */) - { return unicodeString;} - inline UString GetSystemString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage);} - inline UString GetSystemString(const AString &multiByteString) - { return MultiByteToUnicodeString(multiByteString);} -#else - inline const char* GetSystemString(const char *ansiString) - { return ansiString; } - inline const AString& GetSystemString(const AString &multiByteString, UINT) - { return multiByteString; } - inline const char * GetSystemString(const char *multiByteString, UINT) - { return multiByteString; } - inline AString GetSystemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - inline AString GetSystemString(const UString &unicodeString, UINT codePage) - { return UnicodeStringToMultiByte(unicodeString, codePage); } -#endif - -#ifndef UNDER_CE -AString SystemStringToOemString(const CSysString &srcString); -#endif - -#endif +// Common/StringConvert.h + +#ifndef ZIP7_INC_COMMON_STRING_CONVERT_H +#define ZIP7_INC_COMMON_STRING_CONVERT_H + +#include "MyString.h" +#include "MyWindows.h" + +UString MultiByteToUnicodeString(const AString &src, UINT codePage = CP_ACP); +UString MultiByteToUnicodeString(const char *src, UINT codePage = CP_ACP); + +// optimized versions that work faster for ASCII strings +void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage = CP_ACP); +// void UnicodeStringToMultiByte2(AString &dest, const UString &s, UINT codePage, char defaultChar, bool &defaultCharWasUsed); +void UnicodeStringToMultiByte2(AString &dest, const UString &src, UINT codePage); + +AString UnicodeStringToMultiByte(const UString &src, UINT codePage, char defaultChar, bool &defaultCharWasUsed); +AString UnicodeStringToMultiByte(const UString &src, UINT codePage = CP_ACP); + +inline const wchar_t* GetUnicodeString(const wchar_t *u) { return u; } +inline const UString& GetUnicodeString(const UString &u) { return u; } + +inline UString GetUnicodeString(const AString &a) { return MultiByteToUnicodeString(a); } +inline UString GetUnicodeString(const char *a) { return MultiByteToUnicodeString(a); } + +inline UString GetUnicodeString(const AString &a, UINT codePage) + { return MultiByteToUnicodeString(a, codePage); } +inline UString GetUnicodeString(const char *a, UINT codePage) + { return MultiByteToUnicodeString(a, codePage); } + +inline const wchar_t* GetUnicodeString(const wchar_t *u, UINT) { return u; } +inline const UString& GetUnicodeString(const UString &u, UINT) { return u; } + +inline const char* GetAnsiString(const char *a) { return a; } +inline const AString& GetAnsiString(const AString &a) { return a; } + +inline AString GetAnsiString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); } +inline AString GetAnsiString(const UString &u) { return UnicodeStringToMultiByte(u); } + +/* +inline const char* GetOemString(const char* oem) + { return oem; } +inline const AString& GetOemString(const AString &oem) + { return oem; } +*/ +const char* GetOemString(const char* oem); +const AString& GetOemString(const AString &oem); +inline AString GetOemString(const UString &u) + { return UnicodeStringToMultiByte(u, CP_OEMCP); } + +#ifdef _UNICODE + inline const wchar_t* GetSystemString(const wchar_t *u) { return u;} + inline const UString& GetSystemString(const UString &u) { return u;} + inline const wchar_t* GetSystemString(const wchar_t *u, UINT /* codePage */) { return u;} + inline const UString& GetSystemString(const UString &u, UINT /* codePage */) { return u;} + + inline UString GetSystemString(const AString &a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); } + inline UString GetSystemString(const char *a, UINT codePage) { return MultiByteToUnicodeString(a, codePage); } + inline UString GetSystemString(const AString &a) { return MultiByteToUnicodeString(a); } + inline UString GetSystemString(const char *a) { return MultiByteToUnicodeString(a); } +#else + inline const char* GetSystemString(const char *a) { return a; } + inline const AString& GetSystemString(const AString &a) { return a; } + inline const char* GetSystemString(const char *a, UINT) { return a; } + inline const AString& GetSystemString(const AString &a, UINT) { return a; } + + inline AString GetSystemString(const wchar_t *u) { return UnicodeStringToMultiByte(UString(u)); } + inline AString GetSystemString(const UString &u) { return UnicodeStringToMultiByte(u); } + inline AString GetSystemString(const UString &u, UINT codePage) { return UnicodeStringToMultiByte(u, codePage); } + + + + /* + inline AString GetSystemString(const wchar_t *u) + { + UString s; + s = u; + return UnicodeStringToMultiByte(s); + } + */ + +#endif + +#ifndef UNDER_CE +AString SystemStringToOemString(const CSysString &src); +#endif + + +#ifdef _WIN32 +/* we don't need locale functions in Windows + but we can define ENV_HAVE_LOCALE here for debug purposes */ +// #define ENV_HAVE_LOCALE +#else +#define ENV_HAVE_LOCALE +#endif + +#ifdef ENV_HAVE_LOCALE +void MY_SetLocale(); +const char *GetLocale(void); +#endif + +#if !defined(_WIN32) || defined(ENV_HAVE_LOCALE) +bool IsNativeUTF8(); +#endif + +#ifndef _WIN32 +extern bool g_ForceToUTF8; +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/StringToInt.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.cpp --- p7zip-rar-16.02/CPP/Common/StringToInt.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.cpp 2024-03-02 08:00:00.000000000 +0000 @@ -1,144 +1,154 @@ -// Common/StringToInt.cpp - -#include "StdAfx.h" - -#include "StringToInt.h" - -static const UInt32 k_UInt32_max = 0xFFFFFFFF; -static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); -// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1; - -#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \ - uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ - if (end) *end = s; \ - uintType res = 0; \ - for (;; s++) { \ - charTypeUnsigned c = (charTypeUnsigned)*s; \ - if (c < '0' || c > '9') { if (end) *end = s; return res; } \ - if (res > (k_ ## uintType ## _max) / 10) return 0; \ - res *= 10; \ - unsigned v = (c - '0'); \ - if (res > (k_ ## uintType ## _max) - v) return 0; \ - res += v; }} - -CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte) -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 wchar_t *s, const wchar_t **end) throw() -{ - if (end) - *end = s; - const wchar_t *s2 = s; - if (*s == '-') - s2++; - if (*s2 == 0) - return 0; - const wchar_t *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; -} - -UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw() -{ - if (end) - *end = s; - UInt32 res = 0; - for (;; s++) - { - unsigned c = (unsigned char)*s; - if (c < '0' || c > '7') - { - if (end) - *end = s; - return res; - } - if ((res & (UInt32)7 << (32 - 3)) != 0) - return 0; - res <<= 3; - res |= (unsigned)(c - '0'); - } -} - -UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw() -{ - if (end) - *end = s; - UInt64 res = 0; - for (;; s++) - { - unsigned c = (unsigned char)*s; - if (c < '0' || c > '7') - { - if (end) - *end = s; - return res; - } - if ((res & (UInt64)7 << (64 - 3)) != 0) - return 0; - res <<= 3; - res |= (unsigned)(c - '0'); - } -} - -UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw() -{ - if (end) - *end = s; - UInt32 res = 0; - for (;; s++) - { - unsigned c = (Byte)*s; - unsigned v; - if (c >= '0' && c <= '9') v = (c - '0'); - else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); - else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); - else - { - if (end) - *end = s; - return res; - } - if ((res & (UInt32)0xF << (32 - 4)) != 0) - return 0; - res <<= 4; - res |= v; - } -} - -UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw() -{ - if (end) - *end = s; - UInt64 res = 0; - for (;; s++) - { - unsigned c = (Byte)*s; - unsigned v; - if (c >= '0' && c <= '9') v = (c - '0'); - else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); - else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); - else - { - if (end) - *end = s; - return res; - } - if ((res & (UInt64)0xF << (64 - 4)) != 0) - return 0; - res <<= 4; - res |= v; - } -} +// Common/StringToInt.cpp + +#include "StdAfx.h" + +#include +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#include // for WCHAR_MAX in vs2022 +#endif + +#include "StringToInt.h" + +static const UInt32 k_UInt32_max = 0xFFFFFFFF; +static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); +// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1; + +#define DIGIT_TO_VALUE(charTypeUnsigned, digit) ((unsigned)(charTypeUnsigned)digit - '0') +// #define DIGIT_TO_VALUE(charTypeUnsigned, digit) ((unsigned)digit - '0') +// #define DIGIT_TO_VALUE(charTypeUnsigned, digit) ((unsigned)(digit - '0')) + +#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \ +uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ + if (end) *end = s; \ + uintType res = 0; \ + for (;; s++) { \ + const unsigned v = DIGIT_TO_VALUE(charTypeUnsigned, *s); \ + if (v > 9) { if (end) *end = s; return res; } \ + if (res > (k_ ## uintType ## _max) / 10) return 0; \ + res *= 10; \ + if (res > (k_ ## uintType ## _max) - v) return 0; \ + res += v; }} + +// arm-linux-gnueabi GCC compilers give (WCHAR_MAX > UINT_MAX) by some unknown reason +// so we don't use this branch +#if 0 && WCHAR_MAX > UINT_MAX +/* + if (sizeof(wchar_t) > sizeof(unsigned) + we must use CONVERT_STRING_TO_UINT_FUNC_SLOW + But we just stop compiling instead. + We need some real cases to test this code. +*/ +#error Stop_Compiling_WCHAR_MAX_IS_LARGER_THAN_UINT_MAX +#define CONVERT_STRING_TO_UINT_FUNC_SLOW(uintType, charType, charTypeUnsigned) \ +uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ + if (end) *end = s; \ + uintType res = 0; \ + for (;; s++) { \ + const charTypeUnsigned c = (charTypeUnsigned)*s; \ + if (c < '0' || c > '9') { if (end) *end = s; return res; } \ + if (res > (k_ ## uintType ## _max) / 10) return 0; \ + res *= 10; \ + const unsigned v = (unsigned)(c - '0'); \ + if (res > (k_ ## uintType ## _max) - v) return 0; \ + res += v; }} +#endif + + +CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte) +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 wchar_t *s, const wchar_t **end) throw() +{ + if (end) + *end = s; + const wchar_t *s2 = s; + if (*s == '-') + s2++; + const wchar_t *end2; + UInt32 res = ConvertStringToUInt32(s2, &end2); + if (s2 == end2) + return 0; + if (s != s2) + { + if (res > (UInt32)1 << (32 - 1)) + return 0; + res = 0 - res; + } + else + { + if (res & (UInt32)1 << (32 - 1)) + return 0; + } + if (end) + *end = end2; + return (Int32)res; +} + + +#define CONVERT_OCT_STRING_TO_UINT_FUNC(uintType) \ +uintType ConvertOctStringTo ## uintType(const char *s, const char **end) throw() \ +{ \ + if (end) *end = s; \ + uintType res = 0; \ + for (;; s++) { \ + const unsigned c = (unsigned)(Byte)*s - '0'; \ + if (c > 7) { \ + if (end) \ + *end = s; \ + return res; \ + } \ + if (res & (uintType)7 << (sizeof(uintType) * 8 - 3)) \ + return 0; \ + res <<= 3; \ + res |= c; \ + } \ +} + +CONVERT_OCT_STRING_TO_UINT_FUNC(UInt32) +CONVERT_OCT_STRING_TO_UINT_FUNC(UInt64) + + +#define CONVERT_HEX_STRING_TO_UINT_FUNC(uintType) \ +uintType ConvertHexStringTo ## uintType(const char *s, const char **end) throw() \ +{ \ + if (end) *end = s; \ + uintType res = 0; \ + for (;; s++) { \ + unsigned c = (unsigned)(Byte)*s; \ + Z7_PARSE_HEX_DIGIT(c, { if (end) *end = s; return res; }) \ + if (res & (uintType)0xF << (sizeof(uintType) * 8 - 4)) \ + return 0; \ + res <<= 4; \ + res |= c; \ + } \ +} + +CONVERT_HEX_STRING_TO_UINT_FUNC(UInt32) +CONVERT_HEX_STRING_TO_UINT_FUNC(UInt64) + +const char *FindNonHexChar(const char *s) throw() +{ + for (;;) + { + unsigned c = (Byte)*s++; // pointer can go 1 byte after end + c -= '0'; + if (c <= 9) + continue; + c -= 'A' - '0'; + c &= ~0x20u; + if (c > 5) + return s - 1; + } +} + +Byte *ParseHexString(const char *s, Byte *dest) throw() +{ + for (;;) + { + unsigned v0 = (Byte)s[0]; Z7_PARSE_HEX_DIGIT(v0, return dest;) + unsigned v1 = (Byte)s[1]; s += 2; Z7_PARSE_HEX_DIGIT(v1, return dest;) + *dest++ = (Byte)(v1 | (v0 << 4)); + } +} diff -Nru p7zip-rar-16.02/CPP/Common/StringToInt.h p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.h --- p7zip-rar-16.02/CPP/Common/StringToInt.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/StringToInt.h 2023-12-11 08:00:00.000000000 +0000 @@ -1,21 +1,38 @@ -// Common/StringToInt.h - -#ifndef __COMMON_STRING_TO_INT_H -#define __COMMON_STRING_TO_INT_H - -#include "MyTypes.h" - -UInt32 ConvertStringToUInt32(const char *s, const char **end) throw(); -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 wchar_t *s, const wchar_t **end) throw(); - -UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw(); -UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw(); - -UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw(); -UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw(); - -#endif +// Common/StringToInt.h + +#ifndef ZIP7_INC_COMMON_STRING_TO_INT_H +#define ZIP7_INC_COMMON_STRING_TO_INT_H + +#include "MyTypes.h" + +UInt32 ConvertStringToUInt32(const char *s, const char **end) throw(); +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(); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw(); + +UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw(); +UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw(); + +#define Z7_PARSE_HEX_DIGIT(c, err_op) \ +{ c -= '0'; \ + if (c > 9) { \ + c -= 'A' - '0'; \ + c &= ~0x20u; \ + if (c > 5) { err_op } \ + c += 10; \ + } \ +} + +const char *FindNonHexChar(const char *s) throw(); + +// in: (dest != NULL) +// returns: pointer in dest array after last written byte +Byte *ParseHexString(const char *s, Byte *dest) throw(); + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/TextConfig.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.cpp --- p7zip-rar-16.02/CPP/Common/TextConfig.cpp 2016-05-20 08:20:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.cpp 2023-12-10 20:00:00.000000000 +0000 @@ -1,124 +1,123 @@ -// Common/TextConfig.cpp - -#include "StdAfx.h" - -#include "TextConfig.h" -#include "UTFConvert.h" - -static inline bool IsDelimitChar(char c) -{ - return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t'); -} - -static AString GetIDString(const char *s, unsigned &finishPos) -{ - AString result; - for (finishPos = 0; ; finishPos++) - { - char c = s[finishPos]; - if (IsDelimitChar(c) || c == '=') - break; - result += c; - } - return result; -} - -static bool WaitNextLine(const AString &s, unsigned &pos) -{ - for (; pos < s.Len(); pos++) - if (s[pos] == 0x0A) - return true; - return false; -} - -static bool SkipSpaces(const AString &s, unsigned &pos) -{ - for (; pos < s.Len(); pos++) - { - char c = s[pos]; - if (!IsDelimitChar(c)) - { - if (c != ';') - return true; - if (!WaitNextLine(s, pos)) - return false; - } - } - return false; -} - -bool GetTextConfig(const AString &s, CObjectVector &pairs) -{ - pairs.Clear(); - unsigned pos = 0; - - ///////////////////// - // read strings - - for (;;) - { - if (!SkipSpaces(s, pos)) - break; - CTextConfigPair pair; - unsigned finishPos; - AString temp = GetIDString(((const char *)s) + pos, finishPos); - if (!ConvertUTF8ToUnicode(temp, pair.ID)) - return false; - if (finishPos == 0) - return false; - pos += finishPos; - if (!SkipSpaces(s, pos)) - return false; - if (s[pos] != '=') - return false; - pos++; - if (!SkipSpaces(s, pos)) - return false; - if (s[pos] != '\"') - return false; - pos++; - AString message; - for (;;) - { - if (pos >= s.Len()) - return false; - char c = s[pos++]; - if (c == '\"') - break; - if (c == '\\') - { - c = s[pos++]; - switch (c) - { - case 'n': message += '\n'; break; - case 't': message += '\t'; break; - case '\\': message += '\\'; break; - case '\"': message += '\"'; break; - default: message += '\\'; message += c; break; - } - } - else - message += c; - } - if (!ConvertUTF8ToUnicode(message, pair.String)) - return false; - pairs.Add(pair); - } - return true; -} - -int FindTextConfigItem(const CObjectVector &pairs, const UString &id) throw() -{ - FOR_VECTOR (i, pairs) - if (pairs[i].ID == id) - return i; - return -1; -} - -UString GetTextConfigValue(const CObjectVector &pairs, const UString &id) -{ - int index = FindTextConfigItem(pairs, id); - if (index < 0) - return UString(); - return pairs[index].String; -} +// Common/TextConfig.cpp + +#include "StdAfx.h" + +#include "TextConfig.h" +#include "UTFConvert.h" + +static inline bool IsDelimitChar(char c) +{ + return (c == ' ' || c == 0x0A || c == 0x0D || c == '\0' || c == '\t'); +} + +static AString GetIDString(const char *s, unsigned &finishPos) +{ + AString result; + for (finishPos = 0; ; finishPos++) + { + const char c = s[finishPos]; + if (IsDelimitChar(c) || c == '=') + break; + result += c; + } + return result; +} + +static bool WaitNextLine(const AString &s, unsigned &pos) +{ + for (; pos < s.Len(); pos++) + if (s[pos] == 0x0A) + return true; + return false; +} + +static bool SkipSpaces(const AString &s, unsigned &pos) +{ + for (; pos < s.Len(); pos++) + { + const char c = s[pos]; + if (!IsDelimitChar(c)) + { + if (c != ';') + return true; + if (!WaitNextLine(s, pos)) + return false; + } + } + return false; +} + +bool GetTextConfig(const AString &s, CObjectVector &pairs) +{ + pairs.Clear(); + unsigned pos = 0; + + ///////////////////// + // read strings + + for (;;) + { + if (!SkipSpaces(s, pos)) + break; + CTextConfigPair pair; + unsigned finishPos; + const AString temp (GetIDString(((const char *)s) + pos, finishPos)); + if (!ConvertUTF8ToUnicode(temp, pair.ID)) + return false; + if (finishPos == 0) + return false; + pos += finishPos; + if (!SkipSpaces(s, pos)) + return false; + if (s[pos] != '=') + return false; + pos++; + if (!SkipSpaces(s, pos)) + return false; + if (s[pos] != '\"') + return false; + pos++; + AString message; + for (;;) + { + if (pos >= s.Len()) + return false; + char c = s[pos++]; + if (c == '\"') + break; + if (c == '\\') + { + c = s[pos++]; + switch (c) + { + case 'n': c = '\n'; break; + case 't': c = '\t'; break; + case '\\': break; + case '\"': break; + default: message += '\\'; break; + } + } + message += c; + } + if (!ConvertUTF8ToUnicode(message, pair.String)) + return false; + pairs.Add(pair); + } + return true; +} + +int FindTextConfigItem(const CObjectVector &pairs, const char *id) throw() +{ + FOR_VECTOR (i, pairs) + if (pairs[i].ID.IsEqualTo(id)) + return (int)i; + return -1; +} + +UString GetTextConfigValue(const CObjectVector &pairs, const char *id) +{ + const int index = FindTextConfigItem(pairs, id); + if (index < 0) + return UString(); + return pairs[index].String; +} diff -Nru p7zip-rar-16.02/CPP/Common/TextConfig.h p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.h --- p7zip-rar-16.02/CPP/Common/TextConfig.h 2015-11-20 20:40:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/TextConfig.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,19 +1,19 @@ -// Common/TextConfig.h - -#ifndef __COMMON_TEXT_CONFIG_H -#define __COMMON_TEXT_CONFIG_H - -#include "MyString.h" - -struct CTextConfigPair -{ - UString ID; - UString String; -}; - -bool GetTextConfig(const AString &text, CObjectVector &pairs); - -int FindTextConfigItem(const CObjectVector &pairs, const UString &id) throw(); -UString GetTextConfigValue(const CObjectVector &pairs, const UString &id); - -#endif +// Common/TextConfig.h + +#ifndef ZIP7_INC_COMMON_TEXT_CONFIG_H +#define ZIP7_INC_COMMON_TEXT_CONFIG_H + +#include "MyString.h" + +struct CTextConfigPair +{ + UString ID; + UString String; +}; + +bool GetTextConfig(const AString &text, CObjectVector &pairs); + +int FindTextConfigItem(const CObjectVector &pairs, const char *id) throw(); +UString GetTextConfigValue(const CObjectVector &pairs, const char *id); + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/UTFConvert.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.cpp --- p7zip-rar-16.02/CPP/Common/UTFConvert.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.cpp 2024-02-19 09:00:00.000000000 +0000 @@ -1,288 +1,863 @@ -// UTFConvert.cpp - -#include "StdAfx.h" - -#include "MyTypes.h" -#include "UTFConvert.h" - -#ifdef _WIN32 -#define _WCHART_IS_16BIT 1 -#endif - -/* - _UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte - - n : _UTF8_START(n) : Bits of code point - - 0 : 0x80 : : unused - 1 : 0xC0 : 11 : - 2 : 0xE0 : 16 : Basic Multilingual Plane - 3 : 0xF0 : 21 : Unicode space - 3 : 0xF8 : 26 : - 5 : 0xFC : 31 : UCS-4 - 6 : 0xFE : 36 : We can use it, if we want to encode any 32-bit value - 7 : 0xFF : -*/ - -#define _UTF8_START(n) (0x100 - (1 << (7 - (n)))) - -#define _UTF8_HEAD_PARSE2(n) if (c < _UTF8_START((n) + 1)) { numBytes = (n); c -= _UTF8_START(n); } - -#define _UTF8_HEAD_PARSE \ - _UTF8_HEAD_PARSE2(1) \ - else _UTF8_HEAD_PARSE2(2) \ - else _UTF8_HEAD_PARSE2(3) \ - else _UTF8_HEAD_PARSE2(4) \ - else _UTF8_HEAD_PARSE2(5) \ - - // else _UTF8_HEAD_PARSE2(6) - -bool CheckUTF8(const char *src, bool allowReduced) throw() -{ - for (;;) - { - Byte c = *src++; - if (c == 0) - return true; - - if (c < 0x80) - continue; - if (c < 0xC0) // (c < 0xC0 + 2) // if we support only optimal encoding chars - return false; - - unsigned numBytes; - _UTF8_HEAD_PARSE - else - return false; - - UInt32 val = c; - - do - { - Byte c2 = *src++; - if (c2 < 0x80 || c2 >= 0xC0) - return allowReduced && c2 == 0; - val <<= 6; - val |= (c2 - 0x80); - } - while (--numBytes); - - if (val >= 0x110000) - return false; - } -} - - -#define _ERROR_UTF8 \ - { if (dest) dest[destPos] = (wchar_t)0xFFFD; destPos++; ok = false; continue; } - -static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim) throw() -{ - size_t destPos = 0; - bool ok = true; - - for (;;) - { - Byte c; - if (src == srcLim) - { - *destLen = destPos; - return ok; - } - c = *src++; - - if (c < 0x80) - { - if (dest) - dest[destPos] = (wchar_t)c; - destPos++; - continue; - } - if (c < 0xC0) - _ERROR_UTF8 - - unsigned numBytes; - _UTF8_HEAD_PARSE - else - _ERROR_UTF8 - - UInt32 val = c; - - do - { - Byte c2; - if (src == srcLim) - break; - c2 = *src; - if (c2 < 0x80 || c2 >= 0xC0) - break; - src++; - val <<= 6; - val |= (c2 - 0x80); - } - while (--numBytes); - - if (numBytes != 0) - _ERROR_UTF8 - - if (val < 0x10000) - { - if (dest) - dest[destPos] = (wchar_t)val; - destPos++; - } - else - { - val -= 0x10000; - if (val >= 0x100000) - _ERROR_UTF8 - if (dest) - { - dest[destPos + 0] = (wchar_t)(0xD800 + (val >> 10)); - dest[destPos + 1] = (wchar_t)(0xDC00 + (val & 0x3FF)); - } - destPos += 2; - } - } -} - -#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) - -#define _UTF8_HEAD(n, val) ((char)(_UTF8_START(n) + (val >> (6 * (n))))) -#define _UTF8_CHAR(n, val) ((char)(0x80 + (((val) >> (6 * (n))) & 0x3F))) - -static size_t Utf16_To_Utf8_Calc(const wchar_t *src, const wchar_t *srcLim) -{ - size_t size = srcLim - src; - for (;;) - { - if (src == srcLim) - return size; - - UInt32 val = *src++; - - if (val < 0x80) - continue; - - if (val < _UTF8_RANGE(1)) - { - size++; - continue; - } - - if (val >= 0xD800 && val < 0xDC00 && src != srcLim) - { - UInt32 c2 = *src; - if (c2 >= 0xDC00 && c2 < 0xE000) - { - src++; - size += 2; - continue; - } - } - - #ifdef _WCHART_IS_16BIT - - size += 2; - - #else - - if (val < _UTF8_RANGE(2)) size += 2; - else if (val < _UTF8_RANGE(3)) size += 3; - else if (val < _UTF8_RANGE(4)) size += 4; - else if (val < _UTF8_RANGE(5)) size += 5; - else size += 6; - - #endif - } -} - -static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim) -{ - for (;;) - { - if (src == srcLim) - return dest; - - UInt32 val = *src++; - - if (val < 0x80) - { - *dest++ = (char)val; - continue; - } - - if (val < _UTF8_RANGE(1)) - { - dest[0] = _UTF8_HEAD(1, val); - dest[1] = _UTF8_CHAR(0, val); - dest += 2; - continue; - } - - if (val >= 0xD800 && val < 0xDC00 && src != srcLim) - { - UInt32 c2 = *src; - if (c2 >= 0xDC00 && c2 < 0xE000) - { - src++; - val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; - dest[0] = _UTF8_HEAD(3, val); - dest[1] = _UTF8_CHAR(2, val); - dest[2] = _UTF8_CHAR(1, val); - dest[3] = _UTF8_CHAR(0, val); - dest += 4; - continue; - } - } - - #ifndef _WCHART_IS_16BIT - if (val < _UTF8_RANGE(2)) - #endif - { - dest[0] = _UTF8_HEAD(2, val); - dest[1] = _UTF8_CHAR(1, val); - dest[2] = _UTF8_CHAR(0, val); - dest += 3; - continue; - } - - #ifndef _WCHART_IS_16BIT - - UInt32 b; - unsigned numBits; - if (val < _UTF8_RANGE(3)) { numBits = 6 * 3; b = _UTF8_HEAD(3, val); } - else if (val < _UTF8_RANGE(4)) { numBits = 6 * 4; b = _UTF8_HEAD(4, val); } - else if (val < _UTF8_RANGE(5)) { numBits = 6 * 5; b = _UTF8_HEAD(5, val); } - else { numBits = 6 * 6; b = _UTF8_START(6); } - - *dest++ = (Byte)b; - - do - { - numBits -= 6; - *dest++ = (char)(0x80 + ((val >> numBits) & 0x3F)); - } - while (numBits != 0); - - #endif - } -} - -bool ConvertUTF8ToUnicode(const AString &src, UString &dest) -{ - dest.Empty(); - size_t destLen = 0; - Utf8_To_Utf16(NULL, &destLen, src, src.Ptr(src.Len())); - bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src.Ptr(src.Len())); - dest.ReleaseBuf_SetEnd((unsigned)destLen); - return res; -} - -void ConvertUnicodeToUTF8(const UString &src, AString &dest) -{ - dest.Empty(); - size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len())); - Utf16_To_Utf8(dest.GetBuf((unsigned)destLen), src, src.Ptr(src.Len())); - dest.ReleaseBuf_SetEnd((unsigned)destLen); -} +// UTFConvert.cpp + +#include "StdAfx.h" + +// #include + +#include "MyTypes.h" +#include "UTFConvert.h" + + +#ifndef Z7_WCHART_IS_16BIT +#ifndef __APPLE__ + // we define it if the system supports files with non-utf8 symbols: + #define MY_UTF8_RAW_NON_UTF8_SUPPORTED +#endif +#endif + +/* + MY_UTF8_START(n) - is a base value for start byte (head), if there are (n) additional bytes after start byte + + n : MY_UTF8_START(n) : Bits of code point + + 0 : 0x80 : : unused + 1 : 0xC0 : 11 : + 2 : 0xE0 : 16 : Basic Multilingual Plane + 3 : 0xF0 : 21 : Unicode space + 4 : 0xF8 : 26 : + 5 : 0xFC : 31 : UCS-4 : wcstombs() in ubuntu is limited to that value + 6 : 0xFE : 36 : We can use it, if we want to encode any 32-bit value + 7 : 0xFF : +*/ + +#define MY_UTF8_START(n) (0x100 - (1 << (7 - (n)))) + +#define MY_UTF8_HEAD_PARSE2(n) \ + if (c < MY_UTF8_START((n) + 1)) \ + { numBytes = (n); val -= MY_UTF8_START(n); } + +#ifndef Z7_WCHART_IS_16BIT + +/* + if (wchar_t is 32-bit), we can support large points in long UTF-8 sequence, + when we convert wchar_t strings to UTF-8: + (_UTF8_NUM_TAIL_BYTES_MAX == 3) : (21-bits points) - Unicode + (_UTF8_NUM_TAIL_BYTES_MAX == 5) : (31-bits points) - UCS-4 + (_UTF8_NUM_TAIL_BYTES_MAX == 6) : (36-bit hack) +*/ + +#define MY_UTF8_NUM_TAIL_BYTES_MAX 5 +#endif + +/* +#define MY_UTF8_HEAD_PARSE \ + UInt32 val = c; \ + MY_UTF8_HEAD_PARSE2(1) \ + else MY_UTF8_HEAD_PARSE2(2) \ + else MY_UTF8_HEAD_PARSE2(3) \ + else MY_UTF8_HEAD_PARSE2(4) \ + else MY_UTF8_HEAD_PARSE2(5) \ + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + else MY_UTF8_HEAD_PARSE2(6) + #endif +*/ + +#define MY_UTF8_HEAD_PARSE_MAX_3_BYTES \ + UInt32 val = c; \ + MY_UTF8_HEAD_PARSE2(1) \ + else MY_UTF8_HEAD_PARSE2(2) \ + else { numBytes = 3; val -= MY_UTF8_START(3); } + + +#define MY_UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) + + +#define START_POINT_FOR_SURROGATE 0x10000 + + +/* we use 128 bytes block in 16-bit BMP-PLANE to encode non-UTF-8 Escapes + Also we can use additional HIGH-PLANE (we use 21-bit points above 0x1f0000) + to simplify internal intermediate conversion in Linux: + RAW-UTF-8 <-> internal wchar_t utf-16 strings <-> RAW-UTF-UTF-8 +*/ + + +#if defined(Z7_WCHART_IS_16BIT) + +#define UTF_ESCAPE_PLANE 0 + +#else + +/* +we can place 128 ESCAPE chars to + ef 80 - ee be 80 (3-bytes utf-8) : similar to WSL + ef ff - ee bf bf + +1f ef 80 - f7 be be 80 (4-bytes utf-8) : last 4-bytes utf-8 plane (out of Unicode) +1f ef ff - f7 be bf bf (4-bytes utf-8) : last 4-bytes utf-8 plane (out of Unicode) +*/ + +// #define UTF_ESCAPE_PLANE_HIGH (0x1f << 16) +// #define UTF_ESCAPE_PLANE UTF_ESCAPE_PLANE_HIGH +#define UTF_ESCAPE_PLANE 0 + +/* + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is set) + { + if (UTF_ESCAPE_PLANE is UTF_ESCAPE_PLANE_HIGH) + { + we can restore any 8-bit Escape from ESCAPE-PLANE-21 plane. + But ESCAPE-PLANE-21 point cannot be stored to utf-16 (7z archive) + So we still need a way to extract 8-bit Escapes and BMP-Escapes-8 + from same BMP-Escapes-16 stored in 7z. + And if we want to restore any 8-bit from 7z archive, + we still must use Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT for (utf-8 -> utf-16) + Also we need additional Conversions to tranform from utf-16 to utf-16-With-Escapes-21 + } + else (UTF_ESCAPE_PLANE == 0) + { + we must convert original 3-bytes utf-8 BMP-Escape point to sequence + of 3 BMP-Escape-16 points with Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + so we can extract original RAW-UTF-8 from UTFD-16 later. + } + } +*/ + +#endif + + + +#define UTF_ESCAPE_BASE 0xef00 + + +#ifdef UTF_ESCAPE_BASE +#define IS_ESCAPE_POINT(v, plane) (((v) & (UInt32)0xffffff80) == (plane) + UTF_ESCAPE_BASE + 0x80) +#endif + +#define IS_SURROGATE_POINT(v) (((v) & (UInt32)0xfffff800) == 0xd800) +#define IS_LOW_SURROGATE_POINT(v) (((v) & (UInt32)0xfffffc00) == 0xdc00) + + +#define UTF_ERROR_UTF8_CHECK \ + { NonUtf = true; continue; } + +void CUtf8Check::Check_Buf(const char *src, size_t size) throw() +{ + Clear(); + // Byte maxByte = 0; + + for (;;) + { + if (size == 0) + break; + + const Byte c = (Byte)(*src++); + size--; + + if (c == 0) + { + ZeroChar = true; + continue; + } + + /* + if (c > maxByte) + maxByte = c; + */ + + if (c < 0x80) + continue; + + if (c < 0xc0 + 2) + UTF_ERROR_UTF8_CHECK + + unsigned numBytes; + UInt32 val = c; + MY_UTF8_HEAD_PARSE2(1) + else MY_UTF8_HEAD_PARSE2(2) + else MY_UTF8_HEAD_PARSE2(3) + else MY_UTF8_HEAD_PARSE2(4) + else MY_UTF8_HEAD_PARSE2(5) + else + { + UTF_ERROR_UTF8_CHECK + } + + unsigned pos = 0; + do + { + if (pos == size) + break; + unsigned c2 = (Byte)src[pos]; + c2 -= 0x80; + if (c2 >= 0x40) + break; + val <<= 6; + val |= c2; + if (pos == 0) + if (val < (((unsigned)1 << 7) >> numBytes)) + break; + pos++; + } + while (--numBytes); + + if (numBytes != 0) + { + if (pos == size) + Truncated = true; + else + UTF_ERROR_UTF8_CHECK + } + + #ifdef UTF_ESCAPE_BASE + if (IS_ESCAPE_POINT(val, 0)) + Escape = true; + #endif + + if (MaxHighPoint < val) + MaxHighPoint = val; + + if (IS_SURROGATE_POINT(val)) + SingleSurrogate = true; + + src += pos; + size -= pos; + } + + // MaxByte = maxByte; +} + +bool Check_UTF8_Buf(const char *src, size_t size, bool allowReduced) throw() +{ + CUtf8Check check; + check.Check_Buf(src, size); + return check.IsOK(allowReduced); +} + +/* +bool CheckUTF8_chars(const char *src, bool allowReduced) throw() +{ + CUtf8Check check; + check.CheckBuf(src, strlen(src)); + return check.IsOK(allowReduced); +} +*/ + +bool CheckUTF8_AString(const AString &s) throw() +{ + CUtf8Check check; + check.Check_AString(s); + return check.IsOK(); +} + + +/* +bool CheckUTF8(const char *src, bool allowReduced) throw() +{ + // return Check_UTF8_Buf(src, strlen(src), allowReduced); + + for (;;) + { + const Byte c = (Byte)(*src++); + if (c == 0) + return true; + + if (c < 0x80) + continue; + if (c < 0xC0 + 2 || c >= 0xf5) + return false; + + unsigned numBytes; + MY_UTF8_HEAD_PARSE + else + return false; + + unsigned pos = 0; + + do + { + Byte c2 = (Byte)(*src++); + if (c2 < 0x80 || c2 >= 0xC0) + return allowReduced && c2 == 0; + val <<= 6; + val |= (c2 - 0x80); + pos++; + } + while (--numBytes); + + if (val < MY_UTF8_RANGE(pos - 1)) + return false; + + if (val >= 0x110000) + return false; + } +} +*/ + +// in case of UTF-8 error we have two ways: +// 21.01- : old : 0xfffd: REPLACEMENT CHARACTER : old version +// 21.02+ : new : 0xef00 + (c) : similar to WSL scheme for low symbols + +#define UTF_REPLACEMENT_CHAR 0xfffd + + + +#define UTF_ESCAPE(c) \ + ((flags & Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE) ? \ + UTF_ESCAPE_PLANE + UTF_ESCAPE_BASE + (c) : UTF_REPLACEMENT_CHAR) + +/* +#define UTF_HARD_ERROR_UTF8 + { if (dest) dest[destPos] = (wchar_t)UTF_ESCAPE(c); \ + destPos++; ok = false; continue; } +*/ + +// we ignore utf errors, and don't change (ok) variable! + +#define UTF_ERROR_UTF8 \ + { if (dest) dest[destPos] = (wchar_t)UTF_ESCAPE(c); \ + destPos++; continue; } + +// we store UTF-16 in wchar_t strings. So we use surrogates for big unicode points: + +// for debug puposes only we can store UTF-32 in wchar_t: +// #define START_POINT_FOR_SURROGATE ((UInt32)0 - 1) + + +/* + WIN32 MultiByteToWideChar(CP_UTF8) emits 0xfffd point, if utf-8 error was found. + Ant it can emit single 0xfffd from 2 src bytes. + It doesn't emit single 0xfffd from 3-4 src bytes. + We can + 1) emit Escape point for each incorrect byte. So we can data recover later + 2) emit 0xfffd for each incorrect byte. + That scheme is similar to Escape scheme, but we emit 0xfffd + instead of each Escape point. + 3) emit single 0xfffd from 1-2 incorrect bytes, as WIN32 MultiByteToWideChar scheme +*/ + +static bool Utf8_To_Utf16(wchar_t *dest, size_t *destLen, const char *src, const char *srcLim, unsigned flags) throw() +{ + size_t destPos = 0; + bool ok = true; + + for (;;) + { + if (src == srcLim) + { + *destLen = destPos; + return ok; + } + + const Byte c = (Byte)(*src++); + + if (c < 0x80) + { + if (dest) + dest[destPos] = (wchar_t)c; + destPos++; + continue; + } + + if (c < 0xc0 + 2 + || c >= 0xf5) // it's limit for 0x140000 unicode codes : win32 compatibility + { + UTF_ERROR_UTF8 + } + + unsigned numBytes; + + MY_UTF8_HEAD_PARSE_MAX_3_BYTES + + unsigned pos = 0; + do + { + if (src + pos == srcLim) + break; + unsigned c2 = (Byte)src[pos]; + c2 -= 0x80; + if (c2 >= 0x40) + break; + val <<= 6; + val |= c2; + pos++; + if (pos == 1) + { + if (val < (((unsigned)1 << 7) >> numBytes)) + break; + if (numBytes == 2) + { + if (flags & Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) + if ((val & (0xF800 >> 6)) == (0xd800 >> 6)) + break; + } + else if (numBytes == 3 && val >= (0x110000 >> 12)) + break; + } + } + while (--numBytes); + + if (numBytes != 0) + { + if ((flags & Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE) == 0) + { + // the following code to emit the 0xfffd chars as win32 Utf8 function. + // disable the folling line, if you need 0xfffd for each incorrect byte as in Escape mode + src += pos; + } + UTF_ERROR_UTF8 + } + + /* + if (val < MY_UTF8_RANGE(pos - 1)) + UTF_ERROR_UTF8 + */ + + #ifdef UTF_ESCAPE_BASE + + if ((flags & Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT) + && IS_ESCAPE_POINT(val, 0)) + { + // We will emit 3 utf16-Escape-16-21 points from one Escape-16 point (3 bytes) + UTF_ERROR_UTF8 + } + + #endif + + /* + We don't expect virtual Escape-21 points in UTF-8 stream. + And we don't check for Escape-21. + So utf8-Escape-21 will be converted to another 3 utf16-Escape-21 points. + Maybe we could convert virtual utf8-Escape-21 to one utf16-Escape-21 point in some cases? + */ + + if (val < START_POINT_FOR_SURROGATE) + { + /* + if ((flags & Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) + && IS_SURROGATE_POINT(val)) + { + // We will emit 3 utf16-Escape-16-21 points from one Surrogate-16 point (3 bytes) + UTF_ERROR_UTF8 + } + */ + if (dest) + dest[destPos] = (wchar_t)val; + destPos++; + } + else + { + /* + if (val >= 0x110000) + { + // We will emit utf16-Escape-16-21 point from each source byte + UTF_ERROR_UTF8 + } + */ + if (dest) + { + dest[destPos + 0] = (wchar_t)(0xd800 - (0x10000 >> 10) + (val >> 10)); + dest[destPos + 1] = (wchar_t)(0xdc00 + (val & 0x3ff)); + } + destPos += 2; + } + src += pos; + } +} + + + +#define MY_UTF8_HEAD(n, val) ((char)(MY_UTF8_START(n) + (val >> (6 * (n))))) +#define MY_UTF8_CHAR(n, val) ((char)(0x80 + (((val) >> (6 * (n))) & 0x3F))) + +static size_t Utf16_To_Utf8_Calc(const wchar_t *src, const wchar_t *srcLim, unsigned flags) +{ + size_t size = (size_t)(srcLim - src); + for (;;) + { + if (src == srcLim) + return size; + + UInt32 val = (UInt32)(*src++); + + if (val < 0x80) + continue; + + if (val < MY_UTF8_RANGE(1)) + { + size++; + continue; + } + + #ifdef UTF_ESCAPE_BASE + + #if UTF_ESCAPE_PLANE != 0 + if (flags & Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE) + if (IS_ESCAPE_POINT(val, UTF_ESCAPE_PLANE)) + continue; + #endif + + if (flags & Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE) + if (IS_ESCAPE_POINT(val, 0)) + continue; + + #endif + + if (IS_SURROGATE_POINT(val)) + { + // it's hack to UTF-8 encoding + + if (val < 0xdc00 && src != srcLim) + { + const UInt32 c2 = (UInt32)*src; + if (c2 >= 0xdc00 && c2 < 0xe000) + src++; + } + size += 2; + continue; + } + + #ifdef Z7_WCHART_IS_16BIT + + size += 2; + + #else + + if (val < MY_UTF8_RANGE(2)) size += 2; + else if (val < MY_UTF8_RANGE(3)) size += 3; + else if (val < MY_UTF8_RANGE(4)) size += 4; + else if (val < MY_UTF8_RANGE(5)) size += 5; + else + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + size += 6; + #else + size += 3; + #endif + + #endif + } +} + + +static char *Utf16_To_Utf8(char *dest, const wchar_t *src, const wchar_t *srcLim, unsigned flags) +{ + for (;;) + { + if (src == srcLim) + return dest; + + UInt32 val = (UInt32)*src++; + + if (val < 0x80) + { + *dest++ = (char)val; + continue; + } + + if (val < MY_UTF8_RANGE(1)) + { + dest[0] = MY_UTF8_HEAD(1, val); + dest[1] = MY_UTF8_CHAR(0, val); + dest += 2; + continue; + } + + #ifdef UTF_ESCAPE_BASE + + #if UTF_ESCAPE_PLANE != 0 + /* + if (wchar_t is 32-bit) + && (Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE is set) + && (point is virtual escape plane) + we extract 8-bit byte from virtual HIGH-ESCAPE PLANE. + */ + if (flags & Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE) + if (IS_ESCAPE_POINT(val, UTF_ESCAPE_PLANE)) + { + *dest++ = (char)(val); + continue; + } + #endif // UTF_ESCAPE_PLANE != 0 + + /* if (Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE is defined) + we extract 8-bit byte from BMP-ESCAPE PLANE. */ + + if (flags & Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE) + if (IS_ESCAPE_POINT(val, 0)) + { + *dest++ = (char)(val); + continue; + } + + #endif // UTF_ESCAPE_BASE + + if (IS_SURROGATE_POINT(val)) + { + // it's hack to UTF-8 encoding + if (val < 0xdc00 && src != srcLim) + { + const UInt32 c2 = (UInt32)*src; + if (IS_LOW_SURROGATE_POINT(c2)) + { + src++; + val = (((val - 0xd800) << 10) | (c2 - 0xdc00)) + 0x10000; + dest[0] = MY_UTF8_HEAD(3, val); + dest[1] = MY_UTF8_CHAR(2, val); + dest[2] = MY_UTF8_CHAR(1, val); + dest[3] = MY_UTF8_CHAR(0, val); + dest += 4; + continue; + } + } + if (flags & Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR) + val = UTF_REPLACEMENT_CHAR; // WIN32 function does it + } + + #ifndef Z7_WCHART_IS_16BIT + if (val < MY_UTF8_RANGE(2)) + #endif + { + dest[0] = MY_UTF8_HEAD(2, val); + dest[1] = MY_UTF8_CHAR(1, val); + dest[2] = MY_UTF8_CHAR(0, val); + dest += 3; + continue; + } + + #ifndef Z7_WCHART_IS_16BIT + + // we don't expect this case. so we can throw exception + // throw 20210407; + + char b; + unsigned numBits; + if (val < MY_UTF8_RANGE(3)) { numBits = 6 * 3; b = MY_UTF8_HEAD(3, val); } + else if (val < MY_UTF8_RANGE(4)) { numBits = 6 * 4; b = MY_UTF8_HEAD(4, val); } + else if (val < MY_UTF8_RANGE(5)) { numBits = 6 * 5; b = MY_UTF8_HEAD(5, val); } + #if MY_UTF8_NUM_TAIL_BYTES_MAX >= 6 + else { numBits = 6 * 6; b = (char)MY_UTF8_START(6); } + #else + else + { + val = UTF_REPLACEMENT_CHAR; + { numBits = 6 * 3; b = MY_UTF8_HEAD(3, val); } + } + #endif + + *dest++ = b; + + do + { + numBits -= 6; + *dest++ = (char)(0x80 + ((val >> numBits) & 0x3F)); + } + while (numBits != 0); + + #endif + } +} + +bool Convert_UTF8_Buf_To_Unicode(const char *src, size_t srcSize, UString &dest, unsigned flags) +{ + dest.Empty(); + size_t destLen = 0; + Utf8_To_Utf16(NULL, &destLen, src, src + srcSize, flags); + bool res = Utf8_To_Utf16(dest.GetBuf((unsigned)destLen), &destLen, src, src + srcSize, flags); + dest.ReleaseBuf_SetEnd((unsigned)destLen); + return res; +} + +bool ConvertUTF8ToUnicode_Flags(const AString &src, UString &dest, unsigned flags) +{ + return Convert_UTF8_Buf_To_Unicode(src, src.Len(), dest, flags); +} + + +static +unsigned g_UTF8_To_Unicode_Flags = + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + #ifndef Z7_WCHART_IS_16BIT + | Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + #ifdef MY_UTF8_RAW_NON_UTF8_SUPPORTED + | Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + #endif + #endif + ; + + +/* +bool ConvertUTF8ToUnicode_boolRes(const AString &src, UString &dest) +{ + return ConvertUTF8ToUnicode_Flags(src, dest, g_UTF8_To_Unicode_Flags); +} +*/ + +bool ConvertUTF8ToUnicode(const AString &src, UString &dest) +{ + return ConvertUTF8ToUnicode_Flags(src, dest, g_UTF8_To_Unicode_Flags); +} + +void Print_UString(const UString &a); + +void ConvertUnicodeToUTF8_Flags(const UString &src, AString &dest, unsigned flags) +{ + /* + if (src.Len()== 24) + throw "202104"; + */ + dest.Empty(); + const size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()), flags); + char *destStart = dest.GetBuf((unsigned)destLen); + const char *destEnd = Utf16_To_Utf8(destStart, src, src.Ptr(src.Len()), flags); + dest.ReleaseBuf_SetEnd((unsigned)destLen); + // printf("\nlen = %d\n", src.Len()); + if (destLen != (size_t)(destEnd - destStart)) + { + /* + // dest.ReleaseBuf_SetEnd((unsigned)(destEnd - destStart)); + printf("\nlen = %d\n", (unsigned)destLen); + printf("\n(destEnd - destStart) = %d\n", (unsigned)(destEnd - destStart)); + printf("\n"); + // Print_UString(src); + printf("\n"); + // printf("\nlen = %d\n", destLen); + */ + throw 20210406; + } +} + + + +unsigned g_Unicode_To_UTF8_Flags = + // Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE + 0 + #ifndef _WIN32 + #ifdef MY_UTF8_RAW_NON_UTF8_SUPPORTED + | Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE + #else + | Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR + #endif + #endif + ; + +void ConvertUnicodeToUTF8(const UString &src, AString &dest) +{ + ConvertUnicodeToUTF8_Flags(src, dest, g_Unicode_To_UTF8_Flags); +} + +void Convert_Unicode_To_UTF8_Buf(const UString &src, CByteBuffer &dest) +{ + const unsigned flags = g_Unicode_To_UTF8_Flags; + dest.Free(); + const size_t destLen = Utf16_To_Utf8_Calc(src, src.Ptr(src.Len()), flags); + dest.Alloc(destLen); + const char *destEnd = Utf16_To_Utf8((char *)(void *)(Byte *)dest, src, src.Ptr(src.Len()), flags); + if (destLen != (size_t)(destEnd - (char *)(void *)(Byte *)dest)) + throw 202104; +} + +/* + +#ifndef _WIN32 +void Convert_UTF16_To_UTF32(const UString &src, UString &dest) +{ + dest.Empty(); + for (size_t i = 0; i < src.Len();) + { + wchar_t c = src[i++]; + if (c >= 0xd800 && c < 0xdc00 && i < src.Len()) + { + const wchar_t c2 = src[i]; + if (c2 >= 0xdc00 && c2 < 0xe000) + { + // printf("\nSurragate [%d]: %4x %4x -> ", i, (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + // printf("%4x\n", (int)c); + i++; + } + } + dest += c; + } +} + +void Convert_UTF32_To_UTF16(const UString &src, UString &dest) +{ + dest.Empty(); + for (size_t i = 0; i < src.Len();) + { + wchar_t w = src[i++]; + if (w >= 0x10000 && w < 0x110000) + { + w -= 0x10000; + dest += (wchar_t)((unsigned)0xd800 + (((unsigned)w >> 10) & 0x3ff)); + w = 0xdc00 + (w & 0x3ff); + } + dest += w; + } +} + +bool UTF32_IsThere_BigPoint(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 c = (UInt32)src[i++]; + if (c >= 0x110000) + return true; + } + return false; +} + +bool Unicode_IsThere_BmpEscape(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 c = (UInt32)src[i++]; + if (IS_ESCAPE_POINT(c, 0)) + return true; + } + return false; +} + + +#endif + +bool Unicode_IsThere_Utf16SurrogateError(const UString &src) +{ + for (size_t i = 0; i < src.Len();) + { + const UInt32 val = (UInt32)src[i++]; + if (IS_SURROGATE_POINT(val)) + { + // it's hack to UTF-8 encoding + if (val >= 0xdc00 || i == src.Len()) + return true; + const UInt32 c2 = (UInt32)*src; + if (!IS_LOW_SURROGATE_POINT(c2)) + return true; + } + } + return false; +} +*/ + +#ifndef Z7_WCHART_IS_16BIT + +void Convert_UnicodeEsc16_To_UnicodeEscHigh +#if UTF_ESCAPE_PLANE == 0 + (UString &) {} +#else + (UString &s) +{ + const unsigned len = s.Len(); + for (unsigned i = 0; i < len; i++) + { + wchar_t c = s[i]; + if (IS_ESCAPE_POINT(c, 0)) + { + c += UTF_ESCAPE_PLANE; + s.ReplaceOneCharAtPos(i, c); + } + } +} +#endif +#endif diff -Nru p7zip-rar-16.02/CPP/Common/UTFConvert.h p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.h --- p7zip-rar-16.02/CPP/Common/UTFConvert.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/UTFConvert.h 2023-03-15 20:00:00.000000000 +0000 @@ -1,12 +1,384 @@ -// Common/UTFConvert.h - -#ifndef __COMMON_UTF_CONVERT_H -#define __COMMON_UTF_CONVERT_H - -#include "MyString.h" - -bool CheckUTF8(const char *src, bool allowReduced = false) throw(); -bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); -void ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); - -#endif +// Common/UTFConvert.h + +#ifndef ZIP7_INC_COMMON_UTF_CONVERT_H +#define ZIP7_INC_COMMON_UTF_CONVERT_H + +#include "MyBuffer.h" +#include "MyString.h" + +struct CUtf8Check +{ + // Byte MaxByte; // in original src stream + bool NonUtf; + bool ZeroChar; + bool SingleSurrogate; + bool Escape; + bool Truncated; + UInt32 MaxHighPoint; // only for points >= 0x80 + + CUtf8Check() { Clear(); } + + void Clear() + { + // MaxByte = 0; + NonUtf = false; + ZeroChar = false; + SingleSurrogate = false; + Escape = false; + Truncated = false; + MaxHighPoint = 0; + } + + void Update(const CUtf8Check &c) + { + if (c.NonUtf) NonUtf = true; + if (c.ZeroChar) ZeroChar = true; + if (c.SingleSurrogate) SingleSurrogate = true; + if (c.Escape) Escape = true; + if (c.Truncated) Truncated = true; + if (MaxHighPoint < c.MaxHighPoint) MaxHighPoint = c.MaxHighPoint; + } + + void PrintStatus(AString &s) const + { + s.Empty(); + + // s.Add_OptSpaced("MaxByte="); + // s.Add_UInt32(MaxByte); + + if (NonUtf) s.Add_OptSpaced("non-UTF8"); + if (ZeroChar) s.Add_OptSpaced("ZeroChar"); + if (SingleSurrogate) s.Add_OptSpaced("SingleSurrogate"); + if (Escape) s.Add_OptSpaced("Escape"); + if (Truncated) s.Add_OptSpaced("Truncated"); + + if (MaxHighPoint != 0) + { + s.Add_OptSpaced("MaxUnicode="); + s.Add_UInt32(MaxHighPoint); + } + } + + + bool IsOK(bool allowReduced = false) const + { + if (NonUtf || SingleSurrogate || ZeroChar) + return false; + if (MaxHighPoint >= 0x110000) + return false; + if (Truncated && !allowReduced) + return false; + return true; + } + + // it checks full buffer as specified in (size) and it doesn't stop on zero char + void Check_Buf(const char *src, size_t size) throw(); + + void Check_AString(const AString &s) throw() + { + Check_Buf(s.Ptr(), s.Len()); + } +}; + +/* +if (allowReduced == false) - all UTF-8 character sequences must be finished. +if (allowReduced == true) - it allows truncated last character-Utf8-sequence +*/ + +bool Check_UTF8_Buf(const char *src, size_t size, bool allowReduced) throw(); +bool CheckUTF8_AString(const AString &s) throw(); + +#define Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR (1 << 0) +#define Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE (1 << 1) +#define Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT (1 << 2) + +/* +Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + + if (flag is NOT set) + { + it processes SINGLE-SURROGATE-8 as valid Unicode point. + it converts SINGLE-SURROGATE-8 to SINGLE-SURROGATE-16 + Note: some sequencies of two SINGLE-SURROGATE-8 points + will generate correct SURROGATE-16-PAIR, and + that SURROGATE-16-PAIR later will be converted to correct + UTF8-SURROGATE-21 point. So we don't restore original + STR-8 sequence in that case. + } + + if (flag is set) + { + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is defined) + it generates ESCAPE for SINGLE-SURROGATE-8, + if (Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE is not defined) + it generates U+fffd for SINGLE-SURROGATE-8, + } + + +Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + + if (flag is NOT set) + it generates (U+fffd) code for non-UTF-8 (invalid) characters + + if (flag is set) + { + It generates (ESCAPE) codes for NON-UTF-8 (invalid) characters. + And later we can restore original UTF-8-RAW characters from (ESCAPE-16-21) codes. + } + +Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + + if (flag is NOT set) + { + it process ESCAPE-8 points as another Unicode points. + In Linux: ESCAPE-16 will mean two different ESCAPE-8 seqences, + so we need HIGH-ESCAPE-PLANE-21 to restore UTF-8-RAW -> UTF-16 -> UTF-8-RAW + } + + if (flag is set) + { + it generates ESCAPE-16-21 for ESCAPE-8 points + so we can restore UTF-8-RAW -> UTF-16 -> UTF-8-RAW without HIGH-ESCAPE-PLANE-21. + } + + +Main USE CASES with UTF-8 <-> UTF-16 conversions: + + WIN32: UTF-16-RAW -> UTF-8 (Archive) -> UTF-16-RAW + { + set Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + Do NOT set Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Do NOT set Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + + So we restore original SINGLE-SURROGATE-16 from single SINGLE-SURROGATE-8. + } + + Linux: UTF-8-RAW -> UTF-16 (Intermediate / Archive) -> UTF-8-RAW + { + we want restore original UTF-8-RAW sequence later from that ESCAPE-16. + Set the flags: + Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + Z7_UTF_FLAG_FROM_UTF8_BMP_ESCAPE_CONVERT + } + + MacOS: UTF-8-RAW -> UTF-16 (Intermediate / Archive) -> UTF-8-RAW + { + we want to restore correct UTF-8 without any BMP processing: + Set the flags: + Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR + Z7_UTF_FLAG_FROM_UTF8_USE_ESCAPE + } + +*/ + +// zero char is not allowed in (src) buf +bool Convert_UTF8_Buf_To_Unicode(const char *src, size_t srcSize, UString &dest, unsigned flags = 0); + +bool ConvertUTF8ToUnicode_Flags(const AString &src, UString &dest, unsigned flags = 0); +bool ConvertUTF8ToUnicode(const AString &src, UString &dest); + +#define Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR (1 << 8) +#define Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE (1 << 9) +// #define Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE (1 << 10) + +/* +Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR + + if (flag is NOT set) + { + we extract SINGLE-SURROGATE as normal UTF-8 + + In Windows : for UTF-16-RAW <-> UTF-8 (archive) <-> UTF-16-RAW in . + + In Linux : + use-case-1: UTF-8 -> UTF-16 -> UTF-8 doesn't generate UTF-16 SINGLE-SURROGATE, + if (Z7_UTF_FLAG_FROM_UTF8_SURROGATE_ERROR) is used. + use-case 2: UTF-16-7z (with SINGLE-SURROGATE from Windows) -> UTF-8 (Linux) + will generate SINGLE-SURROGATE-UTF-8 here. + } + + if (flag is set) + { + we generate UTF_REPLACEMENT_CHAR (0xfffd) for SINGLE_SURROGATE + it can be used for compatibility mode with WIN32 UTF function + or if we want UTF-8 stream without any errors + } + + +Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE + + if (flag is NOT set) it doesn't extract raw 8-bit symbol from Escape-Plane-16 + if (flag is set) it extracts raw 8-bit symbol from Escape-Plane-16 + + in Linux we need some way to extract NON-UTF8 RAW 8-bits from BMP (UTF-16 7z archive): + if (we use High-Escape-Plane), we can transfer BMP escapes to High-Escape-Plane. + if (we don't use High-Escape-Plane), we must use Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE. + + +Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE + // that flag affects the code only if (wchar_t is 32-bit) + // that mode with high-escape can be disabled now in UTFConvert.cpp + if (flag is NOT set) + it doesn't extract raw 8-bit symbol from High-Escape-Plane + if (flag is set) + it extracts raw 8-bit symbol from High-Escape-Plane + +Main use cases: + +WIN32 : UTF-16-RAW -> UTF-8 (archive) -> UTF-16-RAW + { + Do NOT set Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE. + Do NOT set Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR. + So we restore original UTF-16-RAW. + } + +Linix : UTF-8 with Escapes -> UTF-16 (7z archive) -> UTF-8 with Escapes + set Z7_UTF_FLAG_TO_UTF8_EXTRACT_BMP_ESCAPE to extract non-UTF from 7z archive + set Z7_UTF_FLAG_TO_UTF8_PARSE_HIGH_ESCAPE for intermediate UTF-16. + Note: high esacape mode can be ignored now in UTFConvert.cpp + +macOS: + the system doesn't support incorrect UTF-8 in file names. + set Z7_UTF_FLAG_TO_UTF8_SURROGATE_ERROR +*/ + +extern unsigned g_Unicode_To_UTF8_Flags; + +void ConvertUnicodeToUTF8_Flags(const UString &src, AString &dest, unsigned flags = 0); +void ConvertUnicodeToUTF8(const UString &src, AString &dest); + +void Convert_Unicode_To_UTF8_Buf(const UString &src, CByteBuffer &dest); + +/* +#ifndef _WIN32 +void Convert_UTF16_To_UTF32(const UString &src, UString &dest); +void Convert_UTF32_To_UTF16(const UString &src, UString &dest); +bool UTF32_IsThere_BigPoint(const UString &src); +bool Unicode_IsThere_BmpEscape(const UString &src); +#endif + +bool Unicode_IsThere_Utf16SurrogateError(const UString &src); +*/ + +#ifdef Z7_WCHART_IS_16BIT +#define Convert_UnicodeEsc16_To_UnicodeEscHigh(s) +#else +void Convert_UnicodeEsc16_To_UnicodeEscHigh(UString &s); +#endif + +/* +// #include "../../C/CpuArch.h" + +// ---------- Utf16 Little endian functions ---------- + +// We store 16-bit surrogates even in 32-bit WCHARs in Linux. +// So now we don't use the following code: + +#if WCHAR_MAX > 0xffff + +// void *p : pointer to src bytes stream +// size_t len : num Utf16 characters : it can include or not include NULL character + +inline size_t Utf16LE__Get_Num_WCHARs(const void *p, size_t len) +{ + #if WCHAR_MAX > 0xffff + size_t num_wchars = 0; + for (size_t i = 0; i < len; i++) + { + wchar_t c = GetUi16(p); + p = (const void *)((const Byte *)p + 2); + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = GetUi16(p); + if (c2 >= 0xdc00 && c2 < 0xe000) + { + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + p = (const void *)((const Byte *)p + 2); + i++; + } + } + num_wchars++; + } + return num_wchars; + #else + UNUSED_VAR(p) + return len; + #endif +} + +// #include + +inline wchar_t *Utf16LE__To_WCHARs_Sep(const void *p, size_t len, wchar_t *dest) +{ + for (size_t i = 0; i < len; i++) + { + wchar_t c = GetUi16(p); + p = (const void *)((const Byte *)p + 2); + + #if WCHAR_PATH_SEPARATOR != L'/' + if (c == L'/') + c = WCHAR_PATH_SEPARATOR; + #endif + + #if WCHAR_MAX > 0xffff + + if (c >= 0xd800 && c < 0xdc00 && i + 1 != len) + { + wchar_t c2 = GetUi16(p); + if (c2 >= 0xdc00 && c2 < 0xe000) + { + // printf("\nSurragate : %4x %4x -> ", (int)c, (int)c2); + c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); + p = (const void *)((const Byte *)p + 2); + i++; + // printf("%4x\n", (int)c); + } + } + + #endif + + *dest++ = c; + } + return dest; +} + + +inline size_t Get_Num_Utf16_chars_from_wchar_string(const wchar_t *p) +{ + size_t num = 0; + for (;;) + { + wchar_t c = *p++; + if (c == 0) + return num; + num += ((c >= 0x10000 && c < 0x110000) ? 2 : 1); + } + return num; +} + +inline Byte *wchars_to_Utf16LE(const wchar_t *p, Byte *dest) +{ + for (;;) + { + wchar_t c = *p++; + if (c == 0) + return dest; + if (c >= 0x10000 && c < 0x110000) + { + SetUi16(dest , (UInt16)(0xd800 + ((c >> 10) & 0x3FF))); + SetUi16(dest + 2, (UInt16)(0xdc00 + ( c & 0x3FF))); + dest += 4; + } + else + { + SetUi16(dest, c); + dest += 2; + } + } +} + +#endif +*/ + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Wildcard.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.cpp --- p7zip-rar-16.02/CPP/Common/Wildcard.cpp 2015-10-03 13:03:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.cpp 2025-06-16 10:00:00.000000000 +0000 @@ -1,682 +1,789 @@ -// Common/Wildcard.cpp - -#include "StdAfx.h" - -#include "Wildcard.h" - -bool g_CaseSensitive = - #ifdef _WIN32 - false; - #else - true; - #endif - - -bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2) -{ - if (g_CaseSensitive) - return IsString1PrefixedByString2(s1, s2); - return IsString1PrefixedByString2_NoCase(s1, s2); -} - -int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW -{ - if (g_CaseSensitive) - return wcscmp(s1, s2); - return MyStringCompareNoCase(s1, s2); -} - -#ifndef USE_UNICODE_FSTRING -int CompareFileNames(const char *s1, const char *s2) -{ - if (g_CaseSensitive) - return wcscmp(fs2us(s1), fs2us(s2)); - return MyStringCompareNoCase(fs2us(s1), fs2us(s2)); -} -#endif - -// ----------------------------------------- -// this function compares name with mask -// ? - any char -// * - any char or empty - -static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) -{ - for (;;) - { - wchar_t m = *mask; - wchar_t c = *name; - if (m == 0) - return (c == 0); - if (m == '*') - { - if (EnhancedMaskTest(mask + 1, name)) - return true; - if (c == 0) - return false; - } - else - { - if (m == '?') - { - if (c == 0) - return false; - } - else if (m != c) - if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c)) - return false; - mask++; - } - name++; - } -} - -// -------------------------------------------------- -// Splits path to strings - -void SplitPathToParts(const UString &path, UStringVector &pathParts) -{ - pathParts.Clear(); - unsigned len = path.Len(); - if (len == 0) - return; - UString name; - unsigned prev = 0; - for (unsigned i = 0; i < len; i++) - if (IsPathSepar(path[i])) - { - name.SetFrom(path.Ptr(prev), i - prev); - pathParts.Add(name); - prev = i + 1; - } - name.SetFrom(path.Ptr(prev), len - prev); - pathParts.Add(name); -} - -void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name) -{ - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - dirPrefix.SetFrom(path, (unsigned)(p - start)); - name = p; -} - -void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name) -{ - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - if (p != start) - { - if (IsPathSepar(*(p - 1))) - p--; - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - } - dirPrefix.SetFrom(path, (unsigned)(p - start)); - name = p; -} - -UString ExtractDirPrefixFromPath(const UString &path) -{ - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - return path.Left((unsigned)(p - start)); -} - -UString ExtractFileNameFromPath(const UString &path) -{ - const wchar_t *start = path; - const wchar_t *p = start + path.Len(); - for (; p != start; p--) - if (IsPathSepar(*(p - 1))) - break; - return p; -} - - -bool DoesWildcardMatchName(const UString &mask, const UString &name) -{ - return EnhancedMaskTest(mask, name); -} - -bool DoesNameContainWildcard(const UString &path) -{ - for (unsigned i = 0; i < path.Len(); i++) - { - wchar_t c = path[i]; - if (c == '*' || c == '?') - return true; - } - return false; -} - - -// ----------------------------------------------------------' -// NWildcard - -namespace NWildcard { - -/* - -M = MaskParts.Size(); -N = TestNameParts.Size(); - - File Dir -ForFile rec M<=N [N-M, N) - -!ForDir nonrec M=N [0, M) - - -ForDir rec M 1) - return true; - } - return false; -} - -bool CCensorNode::AreThereIncludeItems() const -{ - if (IncludeItems.Size() > 0) - return true; - FOR_VECTOR (i, SubNodes) - if (SubNodes[i].AreThereIncludeItems()) - return true; - return false; -} - -bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const -{ - const CObjectVector &items = include ? IncludeItems : ExcludeItems; - FOR_VECTOR (i, items) - if (items[i].CheckPath(pathParts, isFile)) - return true; - return false; -} - -bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const -{ - if (CheckPathCurrent(false, pathParts, isFile)) - { - include = false; - return true; - } - include = true; - bool finded = CheckPathCurrent(true, pathParts, isFile); - if (pathParts.Size() <= 1) - return finded; - int index = FindSubNode(pathParts.Front()); - if (index >= 0) - { - UStringVector pathParts2 = pathParts; - pathParts2.Delete(0); - if (SubNodes[index].CheckPathVect(pathParts2, isFile, include)) - return true; - } - return finded; -} - -/* -bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const -{ - UStringVector pathParts; - SplitPathToParts(path, pathParts); - if (CheckPathVect(pathParts, isFile, include)) - { - if (!include || !isAltStream) - return true; - } - if (isAltStream && !pathParts.IsEmpty()) - { - UString &back = pathParts.Back(); - int pos = back.Find(L':'); - if (pos > 0) - { - back.DeleteFrom(pos); - return CheckPathVect(pathParts, isFile, include); - } - } - return false; -} - -bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const -{ - bool include; - if (CheckPath2(isAltStream, path, isFile, include)) - return include; - return false; -} -*/ - -bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const -{ - if (CheckPathCurrent(include, pathParts, isFile)) - return true; - if (Parent == 0) - return false; - pathParts.Insert(0, Name); - return Parent->CheckPathToRoot(include, pathParts, isFile); -} - -/* -bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const -{ - UStringVector pathParts; - SplitPathToParts(path, pathParts); - return CheckPathToRoot(include, pathParts, isFile); -} -*/ - -void CCensorNode::AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching) -{ - if (path.IsEmpty()) - return; - bool forFile = true; - bool forFolder = true; - UString path2 = path; - if (IsPathSepar(path.Back())) - { - path2.DeleteBack(); - forFile = false; - } - AddItem(include, path2, recursive, forFile, forFolder, wildcardMatching); -} - -void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) -{ - ExcludeItems += fromNodes.ExcludeItems; - FOR_VECTOR (i, fromNodes.SubNodes) - { - const CCensorNode &node = fromNodes.SubNodes[i]; - int subNodeIndex = FindSubNode(node.Name); - if (subNodeIndex < 0) - subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this)); - SubNodes[subNodeIndex].ExtendExclude(node); - } -} - -int CCensor::FindPrefix(const UString &prefix) const -{ - FOR_VECTOR (i, Pairs) - if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) - return i; - return -1; -} - -#if 1 // #ifdef _WIN32 - -bool IsDriveColonName(const wchar_t *s) -{ - wchar_t c = s[0]; - return c != 0 && s[1] == ':' && s[2] == 0 && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); -} - -unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts) -{ - if (pathParts.IsEmpty()) - return 0; - - unsigned testIndex = 0; - if (pathParts[0].IsEmpty()) - { - if (pathParts.Size() < 4 - || !pathParts[1].IsEmpty() - || pathParts[2] != L"?") - return 0; - testIndex = 3; - } - if (NWildcard::IsDriveColonName(pathParts[testIndex])) - return testIndex + 1; - return 0; -} - -#endif - -static unsigned GetNumPrefixParts(const UStringVector pathParts) -{ - if (pathParts.IsEmpty()) - return 0; - - #ifdef _WIN32 - - if (IsDriveColonName(pathParts[0])) - return 1; - if (!pathParts[0].IsEmpty()) - return 0; - - if (pathParts.Size() == 1) - return 1; - if (!pathParts[1].IsEmpty()) - return 1; - if (pathParts.Size() == 2) - return 2; - if (pathParts[2] == L".") - return 3; - - unsigned networkParts = 2; - if (pathParts[2] == L"?") - { - if (pathParts.Size() == 3) - return 3; - if (IsDriveColonName(pathParts[3])) - return 4; - if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC")) - return 3; - networkParts = 4; - } - - networkParts += - // 2; // server/share - 1; // server - if (pathParts.Size() <= networkParts) - return pathParts.Size(); - return networkParts; - - #else - - return pathParts[0].IsEmpty() ? 1 : 0; - - #endif -} - -void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching) -{ - if (path.IsEmpty()) - throw "Empty file path"; - - UStringVector pathParts; - SplitPathToParts(path, pathParts); - - bool forFile = true; - if (pathParts.Back().IsEmpty()) - { - forFile = false; - pathParts.DeleteBack(); - } - - UString prefix; - - int ignoreWildcardIndex = -1; - - // #ifdef _WIN32 - // we ignore "?" wildcard in "\\?\" prefix. - if (pathParts.Size() >= 3 - && pathParts[0].IsEmpty() - && pathParts[1].IsEmpty() - && pathParts[2] == L"?") - ignoreWildcardIndex = 2; - // #endif - - if (pathMode != k_AbsPath) - { - ignoreWildcardIndex = -1; - - const unsigned numPrefixParts = GetNumPrefixParts(pathParts); - unsigned numSkipParts = numPrefixParts; - - if (pathMode != k_FullPath) - { - if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts) - numSkipParts = pathParts.Size() - 1; - } - { - int dotsIndex = -1; - for (unsigned i = numPrefixParts; i < pathParts.Size(); i++) - { - const UString &part = pathParts[i]; - if (part == L".." || part == L".") - dotsIndex = i; - } - - if (dotsIndex >= 0) - if (dotsIndex == (int)pathParts.Size() - 1) - numSkipParts = pathParts.Size(); - else - numSkipParts = pathParts.Size() - 1; - } - - for (unsigned i = 0; i < numSkipParts; i++) - { - { - const UString &front = pathParts.Front(); - // WIN32 doesn't support wildcards in file names - if (wildcardMatching) - if (i >= numPrefixParts && DoesNameContainWildcard(front)) - break; - prefix += front; - prefix.Add_PathSepar(); - } - pathParts.Delete(0); - } - } - - int index = FindPrefix(prefix); - if (index < 0) - index = Pairs.Add(CPair(prefix)); - - if (pathMode != k_AbsPath) - { - if (pathParts.IsEmpty() || pathParts.Size() == 1 && pathParts[0].IsEmpty()) - { - // we create universal item, if we skip all parts as prefix (like \ or L:\ ) - pathParts.Clear(); - pathParts.Add(L"*"); - forFile = true; - wildcardMatching = true; - recursive = false; - } - } - - CItem item; - item.PathParts = pathParts; - item.ForDir = true; - item.ForFile = forFile; - item.Recursive = recursive; - item.WildcardMatching = wildcardMatching; - Pairs[index].Head.AddItem(include, item, ignoreWildcardIndex); -} - -/* -bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const -{ - bool finded = false; - FOR_VECTOR (i, Pairs) - { - bool include; - if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include)) - { - if (!include) - return false; - finded = true; - } - } - return finded; -} -*/ - -void CCensor::ExtendExclude() -{ - unsigned i; - for (i = 0; i < Pairs.Size(); i++) - if (Pairs[i].Prefix.IsEmpty()) - break; - if (i == Pairs.Size()) - return; - unsigned index = i; - for (i = 0; i < Pairs.Size(); i++) - if (index != i) - Pairs[i].Head.ExtendExclude(Pairs[index].Head); -} - -void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode) -{ - FOR_VECTOR(i, CensorPaths) - { - const CCensorPath &cp = CensorPaths[i]; - AddItem(censorPathMode, cp.Include, cp.Path, cp.Recursive, cp.WildcardMatching); - } - CensorPaths.Clear(); -} - -void CCensor::AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching) -{ - CCensorPath &cp = CensorPaths.AddNew(); - cp.Path = path; - cp.Include = include; - cp.Recursive = recursive; - cp.WildcardMatching = wildcardMatching; -} - -} +// Common/Wildcard.cpp + +#include "StdAfx.h" + +#include "Wildcard.h" + +extern +bool g_CaseSensitive; +bool g_CaseSensitive = + #ifdef _WIN32 + false; + #elif defined (__APPLE__) + #ifdef TARGET_OS_IPHONE + true; + #else + false; + #endif + #else + true; + #endif + + +bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2) +{ + if (g_CaseSensitive) + return IsString1PrefixedByString2(s1, s2); + return IsString1PrefixedByString2_NoCase(s1, s2); +} + +// #include + +/* +static int MyStringCompare_PathLinux(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (c1 == '/') c1 = 0; + if (c2 == '/') c2 = 0; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} +*/ + +static int MyStringCompare_Path(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (IS_PATH_SEPAR(c1)) c1 = 0; + if (IS_PATH_SEPAR(c2)) c2 = 0; + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} + +static int MyStringCompareNoCase_Path(const wchar_t *s1, const wchar_t *s2) throw() +{ + for (;;) + { + wchar_t c1 = *s1++; + wchar_t c2 = *s2++; + if (c1 != c2) + { + if (c1 == 0) return -1; + if (c2 == 0) return 1; + if (IS_PATH_SEPAR(c1)) c1 = 0; + if (IS_PATH_SEPAR(c2)) c2 = 0; + c1 = MyCharUpper(c1); + c2 = MyCharUpper(c2); + if (c1 < c2) return -1; + if (c1 > c2) return 1; + continue; + } + if (c1 == 0) return 0; + } +} + +int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW +{ + /* + printf("\nCompareFileNames"); + printf("\n S1: %ls", s1); + printf("\n S2: %ls", s2); + printf("\n"); + */ + // 21.07 : we parse PATH_SEPARATOR so: 0 < PATH_SEPARATOR < 1 + if (g_CaseSensitive) + return MyStringCompare_Path(s1, s2); + return MyStringCompareNoCase_Path(s1, s2); +} + +#ifndef USE_UNICODE_FSTRING +int CompareFileNames(const char *s1, const char *s2) +{ + const UString u1 = fs2us(s1); + const UString u2 = fs2us(s2); + return CompareFileNames(u1, u2); +} +#endif + +// ----------------------------------------- +// this function compares name with mask +// ? - any char +// * - any char or empty + +static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name) +{ + for (;;) + { + const wchar_t m = *mask; + const wchar_t c = *name; + if (m == 0) + return (c == 0); + if (m == '*') + { + if (EnhancedMaskTest(mask + 1, name)) + return true; + if (c == 0) + return false; + } + else + { + if (m == '?') + { + if (c == 0) + return false; + } + else if (m != c) + if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c)) + return false; + mask++; + } + name++; + } +} + +// -------------------------------------------------- +// Splits path to strings + +void SplitPathToParts(const UString &path, UStringVector &pathParts) +{ + pathParts.Clear(); + unsigned len = path.Len(); + if (len == 0) + return; + UString name; + unsigned prev = 0; + for (unsigned i = 0; i < len; i++) + if (IsPathSepar(path[i])) + { + name.SetFrom(path.Ptr(prev), i - prev); + pathParts.Add(name); + prev = i + 1; + } + name.SetFrom(path.Ptr(prev), len - prev); + pathParts.Add(name); +} + +void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name) +{ + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + for (; p != start; p--) + if (IsPathSepar(*(p - 1))) + break; + dirPrefix.SetFrom(path, (unsigned)(p - start)); + name = p; +} + +void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name) +{ + const wchar_t *start = path; + const wchar_t *p = start + path.Len(); + if (p != start) + { + if (IsPathSepar(*(p - 1))) + p--; + for (; p != start; p--) + if (IsPathSepar(*(p - 1))) + break; + } + dirPrefix.SetFrom(path, (unsigned)(p - start)); + name = p; +} + +/* +UString ExtractDirPrefixFromPath(const UString &path) +{ + return path.Left(path.ReverseFind_PathSepar() + 1)); +} +*/ + +UString ExtractFileNameFromPath(const UString &path) +{ + return UString(path.Ptr((unsigned)(path.ReverseFind_PathSepar() + 1))); +} + + +bool DoesWildcardMatchName(const UString &mask, const UString &name) +{ + return EnhancedMaskTest(mask, name); +} + +bool DoesNameContainWildcard(const UString &path) +{ + for (unsigned i = 0; i < path.Len(); i++) + { + wchar_t c = path[i]; + if (c == '*' || c == '?') + return true; + } + return false; +} + + +// ----------------------------------------------------------' +// NWildcard + +namespace NWildcard { + +/* + +M = MaskParts.Size(); +N = TestNameParts.Size(); + + File Dir +ForFile rec M<=N [N-M, N) - +!ForDir nonrec M=N [0, M) - + +ForDir rec M &items = include ? IncludeItems : ExcludeItems; + items.Add(item); +} + +void CCensorNode::AddItem(bool include, CItem &item, int ignoreWildcardIndex) +{ + if (item.PathParts.Size() <= 1) + { + if (item.PathParts.Size() != 0 && item.WildcardMatching) + { + if (!DoesNameContainWildcard(item.PathParts.Front())) + item.WildcardMatching = false; + } + AddItemSimple(include, item); + return; + } + + const UString &front = item.PathParts.Front(); + + // WIN32 doesn't support wildcards in file names + if (item.WildcardMatching + && ignoreWildcardIndex != 0 + && DoesNameContainWildcard(front)) + { + AddItemSimple(include, item); + return; + } + CCensorNode &subNode = Find_SubNode_Or_Add_New(front); + item.PathParts.Delete(0); + subNode.AddItem(include, item, ignoreWildcardIndex - 1); +} + +/* +void CCensorNode::AddItem(bool include, const UString &path, const CCensorPathProps &props) +{ + CItem item; + SplitPathToParts(path, item.PathParts); + item.Recursive = props.Recursive; + item.ForFile = props.ForFile; + item.ForDir = props.ForDir; + item.WildcardMatching = props.WildcardMatching; + AddItem(include, item); +} +*/ + +bool CCensorNode::NeedCheckSubDirs() const +{ + FOR_VECTOR (i, IncludeItems) + { + const CItem &item = IncludeItems[i]; + if (item.Recursive || item.PathParts.Size() > 1) + return true; + } + return false; +} + +bool CCensorNode::AreThereIncludeItems() const +{ + if (IncludeItems.Size() > 0) + return true; + FOR_VECTOR (i, SubNodes) + if (SubNodes[i].AreThereIncludeItems()) + return true; + return false; +} + +bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const +{ + const CObjectVector &items = include ? IncludeItems : ExcludeItems; + FOR_VECTOR (i, items) + if (items[i].CheckPath(pathParts, isFile)) + return true; + return false; +} + +bool CCensorNode::CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const +{ + if (CheckPathCurrent(false, pathParts, isFile)) + { + include = false; + return true; + } + if (pathParts.Size() > 1) + { + int index = FindSubNode(pathParts.Front()); + if (index >= 0) + { + UStringVector pathParts2 = pathParts; + pathParts2.Delete(0); + if (SubNodes[(unsigned)index].CheckPathVect(pathParts2, isFile, include)) + return true; + } + } + bool finded = CheckPathCurrent(true, pathParts, isFile); + include = finded; // if (!finded), then (true) is allowed also + return finded; +} + +/* +bool CCensorNode::CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + if (CheckPathVect(pathParts, isFile, include)) + { + if (!include || !isAltStream) + return true; + } + if (isAltStream && !pathParts.IsEmpty()) + { + UString &back = pathParts.Back(); + int pos = back.Find(L':'); + if (pos > 0) + { + back.DeleteFrom(pos); + return CheckPathVect(pathParts, isFile, include); + } + } + return false; +} + +bool CCensorNode::CheckPath(bool isAltStream, const UString &path, bool isFile) const +{ + bool include; + if (CheckPath2(isAltStream, path, isFile, include)) + return include; + return false; +} +*/ + +bool CCensorNode::CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (!Parent) + return false; + pathParts.Insert(0, Name); + return Parent->CheckPathToRoot_Change(include, pathParts, isFile); +} + +bool CCensorNode::CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const +{ + if (CheckPathCurrent(include, pathParts, isFile)) + return true; + if (!Parent) + return false; + UStringVector pathParts2; + pathParts2.Add(Name); + pathParts2 += pathParts; + return Parent->CheckPathToRoot_Change(include, pathParts2, isFile); +} + +/* +bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const +{ + UStringVector pathParts; + SplitPathToParts(path, pathParts); + return CheckPathToRoot(include, pathParts, isFile); +} +*/ + +void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) +{ + ExcludeItems += fromNodes.ExcludeItems; + FOR_VECTOR (i, fromNodes.SubNodes) + { + const CCensorNode &node = fromNodes.SubNodes[i]; + Find_SubNode_Or_Add_New(node.Name).ExtendExclude(node); + } +} + +int CCensor::FindPairForPrefix(const UString &prefix) const +{ + FOR_VECTOR (i, Pairs) + if (CompareFileNames(Pairs[i].Prefix, prefix) == 0) + return (int)i; + return -1; +} + +#ifdef _WIN32 + +bool IsDriveColonName(const wchar_t *s) +{ + unsigned c = s[0]; + c |= 0x20; + c -= 'a'; + return c <= (unsigned)('z' - 'a') && s[1] == ':' && s[2] == 0; +} + +unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts) +{ + if (pathParts.IsEmpty()) + return 0; + + unsigned testIndex = 0; + if (pathParts[0].IsEmpty()) + { + if (pathParts.Size() < 4 + || !pathParts[1].IsEmpty() + || !pathParts[2].IsEqualTo("?")) + return 0; + testIndex = 3; + } + if (NWildcard::IsDriveColonName(pathParts[testIndex])) + return testIndex + 1; + return 0; +} + +#endif + +static unsigned GetNumPrefixParts(const UStringVector &pathParts) +{ + if (pathParts.IsEmpty()) + return 0; + + /* empty last part could be removed already from (pathParts), + if there was tail path separator (slash) in original full path string. */ + + #ifdef _WIN32 + + if (IsDriveColonName(pathParts[0])) + return 1; + if (!pathParts[0].IsEmpty()) + return 0; + + if (pathParts.Size() == 1) + return 1; + if (!pathParts[1].IsEmpty()) + return 1; + if (pathParts.Size() == 2) + return 2; + if (pathParts[2].IsEqualTo(".")) + return 3; + + unsigned networkParts = 2; + if (pathParts[2].IsEqualTo("?")) + { + if (pathParts.Size() == 3) + return 3; + if (IsDriveColonName(pathParts[3])) + return 4; + if (!pathParts[3].IsEqualTo_Ascii_NoCase("UNC")) + return 3; + networkParts = 4; + } + + networkParts += + // 2; // server/share + 1; // server + if (pathParts.Size() <= networkParts) + return pathParts.Size(); + return networkParts; + + #else + + return pathParts[0].IsEmpty() ? 1 : 0; + + #endif +} + +void CCensor::AddItem(ECensorPathMode pathMode, bool include, const UString &path, + const CCensorPathProps &props) +{ + if (path.IsEmpty()) + throw "Empty file path"; + + UStringVector pathParts; + SplitPathToParts(path, pathParts); + + CCensorPathProps props2 = props; + + bool forFile = true; + bool forDir = true; + const UString &back = pathParts.Back(); + if (back.IsEmpty()) + { + // we have tail path separator. So it's directory. + // we delete tail path separator here even for "\" and "c:\" + forFile = false; + pathParts.DeleteBack(); + } + else + { + if (props.MarkMode == kMark_StrictFile + || (props.MarkMode == kMark_StrictFile_IfWildcard + && DoesNameContainWildcard(back))) + forDir = false; + } + + + UString prefix; + + int ignoreWildcardIndex = -1; + + // #ifdef _WIN32 + // we ignore "?" wildcard in "\\?\" prefix. + if (pathParts.Size() >= 3 + && pathParts[0].IsEmpty() + && pathParts[1].IsEmpty() + && pathParts[2].IsEqualTo("?")) + ignoreWildcardIndex = 2; + // #endif + + if (pathMode != k_AbsPath) + { + // detection of the number of Skip Parts for prefix + ignoreWildcardIndex = -1; + + const unsigned numPrefixParts = GetNumPrefixParts(pathParts); + unsigned numSkipParts = numPrefixParts; + + if (pathMode != k_FullPath) + { + // if absolute path, then all parts before last part will be in prefix + if (numPrefixParts != 0 && pathParts.Size() > numPrefixParts) + numSkipParts = pathParts.Size() - 1; + } + { + int dotsIndex = -1; + for (unsigned i = numPrefixParts; i < pathParts.Size(); i++) + { + const UString &part = pathParts[i]; + if (part.IsEqualTo("..") || part.IsEqualTo(".")) + dotsIndex = (int)i; + } + + if (dotsIndex >= 0) + { + if (dotsIndex == (int)pathParts.Size() - 1) + numSkipParts = pathParts.Size(); + else + numSkipParts = pathParts.Size() - 1; + } + } + + // we split (pathParts) to (prefix) and (pathParts). + for (unsigned i = 0; i < numSkipParts; i++) + { + { + const UString &front = pathParts.Front(); + // WIN32 doesn't support wildcards in file names + if (props.WildcardMatching) + if (i >= numPrefixParts && DoesNameContainWildcard(front)) + break; + prefix += front; + prefix.Add_PathSepar(); + } + pathParts.Delete(0); + } + } + + int index = FindPairForPrefix(prefix); + if (index < 0) + { + index = (int)Pairs.Size(); + Pairs.AddNew().Prefix = prefix; + } + + if (pathMode != k_AbsPath) + { + if (pathParts.IsEmpty() || (pathParts.Size() == 1 && pathParts[0].IsEmpty())) + { + // we create universal item, if we skip all parts as prefix (like \ or L:\ ) + pathParts.Clear(); + pathParts.Add(UString("*")); + forFile = true; + forDir = true; + props2.WildcardMatching = true; + props2.Recursive = false; + } + } + + /* + // not possible now + if (!forDir && !forFile) + { + UString s ("file path was blocked for files and directories: "); + s += path; + throw s; + // return; // for debug : ignore item (don't create Item) + } + */ + + CItem item; + item.PathParts = pathParts; + item.ForDir = forDir; + item.ForFile = forFile; + item.Recursive = props2.Recursive; + item.WildcardMatching = props2.WildcardMatching; + Pairs[(unsigned)index].Head.AddItem(include, item, ignoreWildcardIndex); +} + +/* +bool CCensor::CheckPath(bool isAltStream, const UString &path, bool isFile) const +{ + bool finded = false; + FOR_VECTOR (i, Pairs) + { + bool include; + if (Pairs[i].Head.CheckPath2(isAltStream, path, isFile, include)) + { + if (!include) + return false; + finded = true; + } + } + return finded; +} +*/ + +void CCensor::ExtendExclude() +{ + unsigned i; + for (i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.IsEmpty()) + break; + if (i == Pairs.Size()) + return; + unsigned index = i; + for (i = 0; i < Pairs.Size(); i++) + if (index != i) + Pairs[i].Head.ExtendExclude(Pairs[index].Head); +} + +void CCensor::AddPathsToCensor(ECensorPathMode censorPathMode) +{ + FOR_VECTOR(i, CensorPaths) + { + const CCensorPath &cp = CensorPaths[i]; + AddItem(censorPathMode, cp.Include, cp.Path, cp.Props); + } + CensorPaths.Clear(); +} + +void CCensor::AddPreItem(bool include, const UString &path, const CCensorPathProps &props) +{ + CCensorPath &cp = CensorPaths.AddNew(); + cp.Path = path; + cp.Include = include; + cp.Props = props; +} + +} diff -Nru p7zip-rar-16.02/CPP/Common/Wildcard.h p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.h --- p7zip-rar-16.02/CPP/Common/Wildcard.h 2015-10-03 12:42:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Wildcard.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,149 +1,231 @@ -// Common/Wildcard.h - -#ifndef __COMMON_WILDCARD_H -#define __COMMON_WILDCARD_H - -#include "MyString.h" - -int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW; -#ifndef USE_UNICODE_FSTRING - int CompareFileNames(const char *s1, const char *s2); -#endif - -bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2); - -void SplitPathToParts(const UString &path, UStringVector &pathParts); -void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name); -void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path) - -UString ExtractDirPrefixFromPath(const UString &path); -UString ExtractFileNameFromPath(const UString &path); - -bool DoesNameContainWildcard(const UString &path); -bool DoesWildcardMatchName(const UString &mask, const UString &name); - -namespace NWildcard { - -// FIXME #ifdef _WIN32 -// returns true, if name is like "a:", "c:", ... -bool IsDriveColonName(const wchar_t *s); -unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts); -// #endif - -struct CItem -{ - UStringVector PathParts; - bool Recursive; - bool ForFile; - bool ForDir; - bool WildcardMatching; - - #ifdef _WIN32 - bool IsDriveItem() const - { - return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]); - } - #endif - - // CItem(): WildcardMatching(true) {} - - bool AreAllAllowed() const; - bool CheckPath(const UStringVector &pathParts, bool isFile) const; -}; - -class CCensorNode -{ - CCensorNode *Parent; - - bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const; - void AddItemSimple(bool include, CItem &item); -public: - bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const; - - CCensorNode(): Parent(0) { }; - CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { }; - - UString Name; // WIN32 doesn't support wildcards in file names - CObjectVector SubNodes; - CObjectVector IncludeItems; - CObjectVector ExcludeItems; - - bool AreAllAllowed() const; - - int FindSubNode(const UString &path) const; - - void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1); - void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir, bool wildcardMatching); - void AddItem2(bool include, const UString &path, bool recursive, bool wildcardMatching); - - bool NeedCheckSubDirs() const; - bool AreThereIncludeItems() const; - - // bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const; - // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; - - bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; - // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; - void ExtendExclude(const CCensorNode &fromNodes); -}; - -struct CPair -{ - UString Prefix; - CCensorNode Head; - - CPair(const UString &prefix): Prefix(prefix) { }; -}; - -enum ECensorPathMode -{ - k_RelatPath, // absolute prefix as Prefix, remain path in Tree - k_FullPath, // drive prefix as Prefix, remain path in Tree - k_AbsPath // full path in Tree -}; - -struct CCensorPath -{ - UString Path; - bool Include; - bool Recursive; - bool WildcardMatching; - - CCensorPath(): - Include(true), - Recursive(false), - WildcardMatching(true) - {} -}; - -class CCensor -{ - int FindPrefix(const UString &prefix) const; -public: - CObjectVector Pairs; - - CObjectVector CensorPaths; - - bool AllAreRelative() const - { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } - - void AddItem(ECensorPathMode pathMode, bool include, const UString &path, bool recursive, bool wildcardMatching); - // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; - void ExtendExclude(); - - void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode); - void AddPreItem(bool include, const UString &path, bool recursive, bool wildcardMatching); - void AddPreItem(const UString &path) - { - AddPreItem(true, path, false, false); - } - void AddPreItem_Wildcard() - { - AddPreItem(true, L"*", false, true); - } -}; - - -} - -#endif +// Common/Wildcard.h + +#ifndef ZIP7_INC_COMMON_WILDCARD_H +#define ZIP7_INC_COMMON_WILDCARD_H + +#include "MyString.h" + +int CompareFileNames(const wchar_t *s1, const wchar_t *s2) STRING_UNICODE_THROW; +#ifndef USE_UNICODE_FSTRING + int CompareFileNames(const char *s1, const char *s2); +#endif + +bool IsPath1PrefixedByPath2(const wchar_t *s1, const wchar_t *s2); + +void SplitPathToParts(const UString &path, UStringVector &pathParts); +void SplitPathToParts_2(const UString &path, UString &dirPrefix, UString &name); +void SplitPathToParts_Smart(const UString &path, UString &dirPrefix, UString &name); // ignores dir delimiter at the end of (path) + +UString ExtractDirPrefixFromPath(const UString &path); +UString ExtractFileNameFromPath(const UString &path); + +bool DoesNameContainWildcard(const UString &path); +bool DoesWildcardMatchName(const UString &mask, const UString &name); + +namespace NWildcard { + +#ifdef _WIN32 +// returns true, if name is like "a:", "c:", ... +bool IsDriveColonName(const wchar_t *s); +unsigned GetNumPrefixParts_if_DrivePath(UStringVector &pathParts); +#endif + +struct CItem +{ + UStringVector PathParts; + bool Recursive; + bool ForFile; + bool ForDir; + bool WildcardMatching; + + #ifdef _WIN32 + bool IsDriveItem() const + { + return PathParts.Size() == 1 && !ForFile && ForDir && IsDriveColonName(PathParts[0]); + } + #endif + + // CItem(): WildcardMatching(true) {} + + bool AreAllAllowed() const; + bool CheckPath(const UStringVector &pathParts, bool isFile) const; +}; + + + +const Byte kMark_FileOrDir = 0; +const Byte kMark_StrictFile = 1; +const Byte kMark_StrictFile_IfWildcard = 2; + +struct CCensorPathProps +{ + bool Recursive; + bool WildcardMatching; + Byte MarkMode; + + CCensorPathProps(): + Recursive(false), + WildcardMatching(true), + MarkMode(kMark_FileOrDir) + {} +}; + + +class CCensorNode MY_UNCOPYABLE +{ + CCensorNode *Parent; + + bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const; + void AddItemSimple(bool include, CItem &item); +public: + // bool ExcludeDirItems; + + CCensorNode(): + Parent(NULL) + // , ExcludeDirItems(false) + {} + + CCensorNode(const UString &name, CCensorNode *parent): + Parent(parent) + // , ExcludeDirItems(false) + , Name(name) + {} + + UString Name; // WIN32 doesn't support wildcards in file names + CObjectVector SubNodes; + CObjectVector IncludeItems; + CObjectVector ExcludeItems; + + CCensorNode &Find_SubNode_Or_Add_New(const UString &name) + { + int i = FindSubNode(name); + if (i >= 0) + return SubNodes[(unsigned)i]; + // return SubNodes.Add(CCensorNode(name, this)); + CCensorNode &node = SubNodes.AddNew(); + node.Parent = this; + node.Name = name; + return node; + } + + bool AreAllAllowed() const; + + int FindSubNode(const UString &path) const; + + void AddItem(bool include, CItem &item, int ignoreWildcardIndex = -1); + // void AddItem(bool include, const UString &path, const CCensorPathProps &props); + void Add_Wildcard() + { + CItem item; + item.PathParts.Add(L"*"); + item.Recursive = false; + item.ForFile = true; + item.ForDir = true; + item.WildcardMatching = true; + AddItem( + true // include + , item); + } + + // NeedCheckSubDirs() returns true, if there are IncludeItems rules that affect items in subdirs + bool NeedCheckSubDirs() const; + bool AreThereIncludeItems() const; + + /* + CheckPathVect() doesn't check path in Parent CCensorNode + so use CheckPathVect() for root CCensorNode + OUT: + returns (true) && (include = false) - file in exlude list + returns (true) && (include = true) - file in include list and is not in exlude list + returns (false) - file is not in (include/exlude) list + */ + bool CheckPathVect(const UStringVector &pathParts, bool isFile, bool &include) const; + + // bool CheckPath2(bool isAltStream, const UString &path, bool isFile, bool &include) const; + // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; + + // CheckPathToRoot_Change() changes pathParts !!! + bool CheckPathToRoot_Change(bool include, UStringVector &pathParts, bool isFile) const; + bool CheckPathToRoot(bool include, const UStringVector &pathParts, bool isFile) const; + + // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; + void ExtendExclude(const CCensorNode &fromNodes); +}; + + +struct CPair MY_UNCOPYABLE +{ + UString Prefix; + CCensorNode Head; + + // CPair(const UString &prefix): Prefix(prefix) { }; +}; + + +enum ECensorPathMode +{ + k_RelatPath, // absolute prefix as Prefix, remain path in Tree + k_FullPath, // drive prefix as Prefix, remain path in Tree + k_AbsPath // full path in Tree +}; + + +struct CCensorPath +{ + UString Path; + bool Include; + CCensorPathProps Props; + + CCensorPath(): + Include(true) + {} +}; + + +class CCensor MY_UNCOPYABLE +{ + int FindPairForPrefix(const UString &prefix) const; +public: + CObjectVector Pairs; + + bool ExcludeDirItems; + bool ExcludeFileItems; + + CCensor(): + ExcludeDirItems(false), + ExcludeFileItems(false) + {} + + CObjectVector CensorPaths; + + bool AllAreRelative() const + { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } + + void AddItem(ECensorPathMode pathMode, bool include, const UString &path, const CCensorPathProps &props); + // bool CheckPath(bool isAltStream, const UString &path, bool isFile) const; + void ExtendExclude(); + + void AddPathsToCensor(NWildcard::ECensorPathMode censorPathMode); + void AddPreItem(bool include, const UString &path, const CCensorPathProps &props); + + void AddPreItem_NoWildcard(const UString &path) + { + CCensorPathProps props; + props.WildcardMatching = false; + AddPreItem( + true, // include + path, props); + } + void AddPreItem_Wildcard() + { + CCensorPathProps props; + // props.WildcardMatching = true; + AddPreItem( + true, // include + UString("*"), props); + } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Common/Xxh64Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/Xxh64Reg.cpp --- p7zip-rar-16.02/CPP/Common/Xxh64Reg.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/Xxh64Reg.cpp 2024-01-22 11:00:00.000000000 +0000 @@ -0,0 +1,97 @@ +// Xxh64Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Xxh64.h" +#include "../../C/CpuArch.h" + +// #define Z7_USE_HHX64_ORIGINAL +#ifdef Z7_USE_HHX64_ORIGINAL +#ifdef __clang__ +#include "../../C/zstd7z/7z_zstd_cmpl.h" +#pragma GCC diagnostic ignored "-Wlanguage-extension-token" +#endif +#define XXH_STATIC_LINKING_ONLY +#include "../../C/zstd7z/common/xxhash.h" +#endif + +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CXxh64Hasher + , IHasher +) + CXxh64 _state; +public: + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + CXxh64Hasher() { Init(); } +}; + +Z7_COM7F_IMF2(void, CXxh64Hasher::Init()) +{ + Xxh64_Init(&_state); +} + +Z7_COM7F_IMF2(void, CXxh64Hasher::Update(const void *data, UInt32 size)) +{ +#if 1 + Xxh64_Update(&_state, data, size); +#else // for debug: + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 8; + if (size2 == 0) + size2 = 1; + Xxh64_Update(&_state, data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +#endif +} + +Z7_COM7F_IMF2(void, CXxh64Hasher::Final(Byte *digest)) +{ + const UInt64 val = Xxh64_Digest(&_state); + SetUi64(digest, val) +} + +REGISTER_HASHER(CXxh64Hasher, 0x211, "XXH64", 8) + + + +#ifdef Z7_USE_HHX64_ORIGINAL +namespace NOriginal +{ +Z7_CLASS_IMP_COM_1( + CXxh64Hasher + , IHasher +) + XXH64_state_t _state; +public: + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + CXxh64Hasher() { Init(); } +}; + +Z7_COM7F_IMF2(void, CXxh64Hasher::Init()) +{ + XXH64_reset(&_state, 0); +} + +Z7_COM7F_IMF2(void, CXxh64Hasher::Update(const void *data, UInt32 size)) +{ + XXH64_update(&_state, data, size); +} + +Z7_COM7F_IMF2(void, CXxh64Hasher::Final(Byte *digest)) +{ + const UInt64 val = XXH64_digest(&_state); + SetUi64(digest, val) +} + +REGISTER_HASHER(CXxh64Hasher, 0x212, "XXH64a", 8) +} +#endif diff -Nru p7zip-rar-16.02/CPP/Common/XzCrc64Init.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Init.cpp --- p7zip-rar-16.02/CPP/Common/XzCrc64Init.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Init.cpp 2017-01-30 17:59:51.000000000 +0000 @@ -0,0 +1,7 @@ +// XzCrc64Init.cpp + +#include "StdAfx.h" + +#include "../../C/XzCrc64.h" + +static struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit; diff -Nru p7zip-rar-16.02/CPP/Common/XzCrc64Reg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Reg.cpp --- p7zip-rar-16.02/CPP/Common/XzCrc64Reg.cpp 2016-05-18 17:31:03.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Common/XzCrc64Reg.cpp 2023-03-16 20:00:00.000000000 +0000 @@ -1,42 +1,39 @@ -// XzCrc64Reg.cpp - -#include "StdAfx.h" - -#include "../../C/CpuArch.h" -#include "../../C/XzCrc64.h" - -#include "../Common/MyCom.h" - -#include "../7zip/Common/RegisterCodec.h" - -class CXzCrc64Hasher: - public IHasher, - public CMyUnknownImp -{ - UInt64 _crc; - Byte mtDummy[1 << 7]; - -public: - CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {} - - MY_UNKNOWN_IMP1(IHasher) - INTERFACE_IHasher(;) -}; - -STDMETHODIMP_(void) CXzCrc64Hasher::Init() throw() -{ - _crc = CRC64_INIT_VAL; -} - -STDMETHODIMP_(void) CXzCrc64Hasher::Update(const void *data, UInt32 size) throw() -{ - _crc = Crc64Update(_crc, data, size); -} - -STDMETHODIMP_(void) CXzCrc64Hasher::Final(Byte *digest) throw() -{ - UInt64 val = CRC64_GET_DIGEST(_crc); - SetUi64(digest, val); -} - -REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8) +// XzCrc64Reg.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" +#include "../../C/XzCrc64.h" + +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CXzCrc64Hasher + , IHasher +) + UInt64 _crc; +public: + Byte _mtDummy[1 << 7]; // it's public to eliminate clang warning: unused private field + + CXzCrc64Hasher(): _crc(CRC64_INIT_VAL) {} +}; + +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Init()) +{ + _crc = CRC64_INIT_VAL; +} + +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Update(const void *data, UInt32 size)) +{ + _crc = Crc64Update(_crc, data, size); +} + +Z7_COM7F_IMF2(void, CXzCrc64Hasher::Final(Byte *digest)) +{ + const UInt64 val = CRC64_GET_DIGEST(_crc); + SetUi64(digest, val) +} + +REGISTER_HASHER(CXzCrc64Hasher, 0x4, "CRC64", 8) diff -Nru p7zip-rar-16.02/CPP/Windows/COM.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.cpp --- p7zip-rar-16.02/CPP/Windows/COM.cpp 2015-06-19 10:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.cpp 2014-12-30 16:11:07.000000000 +0000 @@ -1,41 +1,41 @@ -// Windows/COM.cpp - -#include "StdAfx.h" - -/* - -#include "COM.h" -#include "../Common/StringConvert.h" - -namespace NWindows { -namespace NCOM { - -// CoInitialize (NULL); must be called! - -UString GUIDToStringW(REFGUID guid) -{ - UString s; - const unsigned kSize = 48; - StringFromGUID2(guid, s.GetBuf(kSize), kSize); - s.ReleaseBuf_CalcLen(kSize); - return s; -} - -AString GUIDToStringA(REFGUID guid) -{ - return UnicodeStringToMultiByte(GUIDToStringW(guid)); -} - -HRESULT StringToGUIDW(const wchar_t *string, GUID &classID) -{ - return CLSIDFromString((wchar_t *)string, &classID); -} - -HRESULT StringToGUIDA(const char *string, GUID &classID) -{ - return StringToGUIDW(MultiByteToUnicodeString(string), classID); -} - -}} - -*/ +// Windows/COM.cpp + +#include "StdAfx.h" + +/* + +#include "COM.h" +#include "../Common/StringConvert.h" + +namespace NWindows { +namespace NCOM { + +// CoInitialize (NULL); must be called! + +UString GUIDToStringW(REFGUID guid) +{ + UString s; + const unsigned kSize = 48; + StringFromGUID2(guid, s.GetBuf(kSize), kSize); + s.ReleaseBuf_CalcLen(kSize); + return s; +} + +AString GUIDToStringA(REFGUID guid) +{ + return UnicodeStringToMultiByte(GUIDToStringW(guid)); +} + +HRESULT StringToGUIDW(const wchar_t *string, GUID &classID) +{ + return CLSIDFromString((wchar_t *)string, &classID); +} + +HRESULT StringToGUIDA(const char *string, GUID &classID) +{ + return StringToGUIDW(MultiByteToUnicodeString(string), classID); +} + +}} + +*/ diff -Nru p7zip-rar-16.02/CPP/Windows/COM.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.h --- p7zip-rar-16.02/CPP/Windows/COM.h 2015-06-19 10:52:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/COM.h 2023-03-17 16:00:00.000000000 +0000 @@ -1,70 +1,86 @@ -// Windows/COM.h - -#ifndef __WINDOWS_COM_H -#define __WINDOWS_COM_H - -#include "../Common/MyString.h" - -namespace NWindows { -namespace NCOM { - -#ifdef _WIN32 - -class CComInitializer -{ -public: - CComInitializer() - { - #ifdef UNDER_CE - CoInitializeEx(NULL, COINIT_MULTITHREADED); - #else - // it's single thread. Do we need multithread? - CoInitialize(NULL); - #endif - }; - ~CComInitializer() { CoUninitialize(); } -}; - -class CStgMedium -{ - STGMEDIUM _object; -public: - bool _mustBeReleased; - CStgMedium(): _mustBeReleased(false) {} - ~CStgMedium() { Free(); } - void Free() - { - if (_mustBeReleased) - ReleaseStgMedium(&_object); - _mustBeReleased = false; - } - const STGMEDIUM* operator->() const { return &_object;} - STGMEDIUM* operator->() { return &_object;} - STGMEDIUM* operator&() { return &_object; } -}; - -#endif - -/* -////////////////////////////////// -// GUID <--> String Conversions -UString GUIDToStringW(REFGUID guid); -AString GUIDToStringA(REFGUID guid); -#ifdef UNICODE - #define GUIDToString GUIDToStringW -#else - #define GUIDToString GUIDToStringA -#endif - -HRESULT StringToGUIDW(const wchar_t *string, GUID &classID); -HRESULT StringToGUIDA(const char *string, GUID &classID); -#ifdef UNICODE - #define StringToGUID StringToGUIDW -#else - #define StringToGUID StringToGUIDA -#endif -*/ - -}} - -#endif +// Windows/COM.h + +#ifndef ZIP7_INC_WINDOWS_COM_H +#define ZIP7_INC_WINDOWS_COM_H + +// #include "../Common/MyString.h" + +namespace NWindows { +namespace NCOM { + +#ifdef _WIN32 + +class CComInitializer +{ +public: + CComInitializer() + { + #ifdef UNDER_CE + CoInitializeEx(NULL, COINIT_MULTITHREADED); + #else + // it's single thread. Do we need multithread? + CoInitialize(NULL); + #endif + } + ~CComInitializer() { CoUninitialize(); } +}; + +/* +class CStgMedium2 +{ + STGMEDIUM _object; + bool _mustBeReleased; +public: + CStgMedium2(): _mustBeReleased(false) {} + ~CStgMedium2() { Free(); } + void Free() + { + if (_mustBeReleased) + ReleaseStgMedium(&_object); + _mustBeReleased = false; + } + const STGMEDIUM* operator->() const { return &_object;} + STGMEDIUM* operator->() { return &_object;} + STGMEDIUM* operator&() { return &_object; } +}; +*/ + +struct CStgMedium: public STGMEDIUM +{ + CStgMedium() + { + tymed = TYMED_NULL; // 0 + hGlobal = NULL; + pUnkForRelease = NULL; + } + ~CStgMedium() + { + ReleaseStgMedium(this); + } +}; + +#endif + +/* +////////////////////////////////// +// GUID <--> String Conversions +UString GUIDToStringW(REFGUID guid); +AString GUIDToStringA(REFGUID guid); +#ifdef UNICODE + #define GUIDToString GUIDToStringW +#else + #define GUIDToString GUIDToStringA +#endif + +HRESULT StringToGUIDW(const wchar_t *string, GUID &classID); +HRESULT StringToGUIDA(const char *string, GUID &classID); +#ifdef UNICODE + #define StringToGUID StringToGUIDW +#else + #define StringToGUID StringToGUIDA +#endif +*/ + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Clipboard.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.cpp --- p7zip-rar-16.02/CPP/Windows/Clipboard.cpp 2010-03-24 20:04:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.cpp 2017-02-08 11:28:25.000000000 +0000 @@ -1,160 +1,130 @@ -// Windows/Clipboard.cpp - -#include "StdAfx.h" - - -#include "Windows/Clipboard.h" -#include "Windows/Defs.h" -#ifdef _WIN32 -#include "Windows/Memory.h" -#include "Windows/Shell.h" -#include "Windows/Memory.h" -#else -#include -#include -#undef _WIN32 -#endif - -#include "Common/StringConvert.h" - -namespace NWindows { - -bool CClipboard::Open(HWND wndNewOwner) -{ -#ifdef _WIN32 - m_Open = BOOLToBool(::OpenClipboard(wndNewOwner)); -#else - m_Open = wxTheClipboard->Open(); -#endif - return m_Open; -} - -CClipboard::~CClipboard() -{ - Close(); -} - -bool CClipboard::Close() -{ - if (!m_Open) - return true; -#ifdef _WIN32 - m_Open = !BOOLToBool(CloseClipboard()); -#else - wxTheClipboard->Close(); - m_Open = false; -#endif - return !m_Open; -} - -#ifdef _WIN32 -bool ClipboardIsFormatAvailableHDROP() -{ - return BOOLToBool(IsClipboardFormatAvailable(CF_HDROP)); -} -#endif - -/* -bool ClipboardGetTextString(AString &s) -{ - s.Empty(); - if (!IsClipboardFormatAvailable(CF_TEXT)) - return false; - CClipboard clipboard; - - if (!clipboard.Open(NULL)) - return false; - - HGLOBAL h = ::GetClipboardData(CF_TEXT); - if (h != NULL) - { - NMemory::CGlobalLock globalLock(h); - const char *p = (const char *)globalLock.GetPointer(); - if (p != NULL) - { - s = p; - return true; - } - } - return false; -} -*/ - -/* -bool ClipboardGetFileNames(UStringVector &names) -{ - names.Clear(); - if (!IsClipboardFormatAvailable(CF_HDROP)) - return false; - CClipboard clipboard; - - if (!clipboard.Open(NULL)) - return false; - - HGLOBAL h = ::GetClipboardData(CF_HDROP); - if (h != NULL) - { - NMemory::CGlobalLock globalLock(h); - void *p = (void *)globalLock.GetPointer(); - if (p != NULL) - { - NShell::CDrop drop(false); - drop.Attach((HDROP)p); - drop.QueryFileNames(names); - return true; - } - } - return false; -} -*/ - -#ifdef _WIN32 -static bool ClipboardSetData(UINT uFormat, const void *data, size_t size) -{ - NMemory::CGlobal global; - if (!global.Alloc(GMEM_DDESHARE | GMEM_MOVEABLE, size)) - return false; - { - NMemory::CGlobalLock globalLock(global); - LPVOID p = globalLock.GetPointer(); - if (p == NULL) - return false; - memcpy(p, data, size); - } - if (::SetClipboardData(uFormat, global) == NULL) - return false; - global.Detach(); - return true; -} -#endif - -bool ClipboardSetText(HWND owner, const UString &s) -{ - CClipboard clipboard; - if (!clipboard.Open(owner)) - return false; -#ifdef _WIN32 - if (!::EmptyClipboard()) - return false; - - bool res; - res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Length() + 1) * sizeof(wchar_t)); - #ifndef _UNICODE - AString a; - a = UnicodeStringToMultiByte(s, CP_ACP); - res |= ClipboardSetData(CF_TEXT, (const char *)a, (a.Length() + 1) * sizeof(char)); - a = UnicodeStringToMultiByte(s, CP_OEMCP); - res |= ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Length() + 1) * sizeof(char)); - #endif - return res; -#else - wxTheClipboard->Clear(); - // This data objects are held by the clipboard, - // so do not delete them in the app. - wxString ws(s); - wxTheClipboard->SetData( new wxTextDataObject(ws) ); - return true; -#endif -} - -} +// Windows/Clipboard.cpp + +#include "StdAfx.h" + +#ifdef UNDER_CE +#include +#endif + +#include "../Common/StringConvert.h" + +#include "Clipboard.h" +#include "Defs.h" +#include "MemoryGlobal.h" +#include "Shell.h" + +namespace NWindows { + +bool CClipboard::Open(HWND wndNewOwner) throw() +{ + m_Open = BOOLToBool(::OpenClipboard(wndNewOwner)); + return m_Open; +} + +bool CClipboard::Close() throw() +{ + if (!m_Open) + return true; + m_Open = !BOOLToBool(CloseClipboard()); + return !m_Open; +} + +bool ClipboardIsFormatAvailableHDROP() +{ + return BOOLToBool(IsClipboardFormatAvailable(CF_HDROP)); +} + +/* +bool ClipboardGetTextString(AString &s) +{ + s.Empty(); + if (!IsClipboardFormatAvailable(CF_TEXT)) + return false; + CClipboard clipboard; + + if (!clipboard.Open(NULL)) + return false; + + HGLOBAL h = ::GetClipboardData(CF_TEXT); + if (h != NULL) + { + NMemory::CGlobalLock globalLock(h); + const char *p = (const char *)globalLock.GetPointer(); + if (p != NULL) + { + s = p; + return true; + } + } + return false; +} +*/ + +/* +bool ClipboardGetFileNames(UStringVector &names) +{ + names.Clear(); + if (!IsClipboardFormatAvailable(CF_HDROP)) + return false; + CClipboard clipboard; + + if (!clipboard.Open(NULL)) + return false; + + HGLOBAL h = ::GetClipboardData(CF_HDROP); + if (h != NULL) + { + NMemory::CGlobalLock globalLock(h); + void *p = (void *)globalLock.GetPointer(); + if (p != NULL) + { + NShell::CDrop drop(false); + drop.Attach((HDROP)p); + drop.QueryFileNames(names); + return true; + } + } + return false; +} +*/ + +static bool ClipboardSetData(UINT uFormat, const void *data, size_t size) throw() +{ + NMemory::CGlobal global; + if (!global.Alloc(GMEM_DDESHARE | GMEM_MOVEABLE, size)) + return false; + { + NMemory::CGlobalLock globalLock(global); + LPVOID p = globalLock.GetPointer(); + if (!p) + return false; + memcpy(p, data, size); + } + if (::SetClipboardData(uFormat, global) == NULL) + return false; + global.Detach(); + return true; +} + +bool ClipboardSetText(HWND owner, const UString &s) +{ + CClipboard clipboard; + if (!clipboard.Open(owner)) + return false; + if (!::EmptyClipboard()) + return false; + + bool res; + res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Len() + 1) * sizeof(wchar_t)); + #ifndef _UNICODE + AString a (UnicodeStringToMultiByte(s, CP_ACP)); + if (ClipboardSetData(CF_TEXT, (const char *)a, (a.Len() + 1) * sizeof(char))) + res = true; + a = UnicodeStringToMultiByte(s, CP_OEMCP); + if (ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Len() + 1) * sizeof(char))) + res = true; + #endif + return res; +} + +} diff -Nru p7zip-rar-16.02/CPP/Windows/Clipboard.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.h --- p7zip-rar-16.02/CPP/Windows/Clipboard.h 2008-08-16 00:01:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Clipboard.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,28 +1,28 @@ -// Windows/Clipboard.h - -#ifndef __CLIPBOARD_H -#define __CLIPBOARD_H - -#include "Common/MyString.h" - -namespace NWindows { - -class CClipboard -{ - bool m_Open; -public: - CClipboard(): m_Open(false) {}; - ~CClipboard(); - bool Open(HWND wndNewOwner); - bool Close(); -}; - -bool ClipboardIsFormatAvailableHDROP(); - -// bool ClipboardGetFileNames(UStringVector &names); -// bool ClipboardGetTextString(AString &s); -bool ClipboardSetText(HWND owner, const UString &s); - -} - -#endif +// Windows/Clipboard.h + +#ifndef ZIP7_INC_CLIPBOARD_H +#define ZIP7_INC_CLIPBOARD_H + +#include "../Common/MyString.h" + +namespace NWindows { + +class CClipboard +{ + bool m_Open; +public: + CClipboard(): m_Open(false) {} + ~CClipboard() { Close(); } + bool Open(HWND wndNewOwner) throw(); + bool Close() throw(); +}; + +bool ClipboardIsFormatAvailableHDROP(); + +// bool ClipboardGetFileNames(UStringVector &names); +// bool ClipboardGetTextString(AString &s); +bool ClipboardSetText(HWND owner, const UString &s); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/CommonDialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.cpp --- p7zip-rar-16.02/CPP/Windows/CommonDialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.cpp 2023-03-17 16:00:00.000000000 +0000 @@ -0,0 +1,269 @@ +// Windows/CommonDialog.cpp + +#include "StdAfx.h" + +#include "../Common/MyBuffer.h" + +#ifdef UNDER_CE +#include +#endif + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#include "CommonDialog.h" +#include "Defs.h" +// #include "FileDir.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +/* + GetSaveFileName() + GetOpenFileName() + OPENFILENAME + +(lpstrInitialDir) : the initial directory. +DOCs: the algorithm for selecting the initial directory varies on different platforms: +{ + Win2000/XP/Vista: + 1. If lpstrFile contains a path, that path is the initial directory. + 2. Otherwise, lpstrInitialDir specifies the initial directory. + + Win7: + If lpstrInitialDir has the same value as was passed the first time + the application used an Open or Save As dialog box, the path + most recently selected by the user is used as the initial directory. +} + +Win10: + in: + function supports (lpstrInitialDir) path with super prefix "\\\\?\\" + function supports (lpstrInitialDir) path with long path + function doesn't support absolute (lpstrFile) path with super prefix "\\\\?\\" + function doesn't support absolute (lpstrFile) path with long path + out: the path with super prefix "\\\\?\\" will be returned, if selected path is long + +WinXP-64 and Win10: if no filters, the system shows all files. + but DOCs say: If all three members are zero or NULL, + the system does not use any filters and does not + show any files in the file list control of the dialog box. + +in Win7+: GetOpenFileName() and GetSaveFileName() + do not support pstrCustomFilter feature anymore +*/ + +#ifdef UNDER_CE +#define MY_OFN_PROJECT 0x00400000 +#define MY_OFN_SHOW_ALL 0x01000000 +#endif + + +/* +structures + OPENFILENAMEW + OPENFILENAMEA +contain additional members: +#if (_WIN32_WINNT >= 0x0500) + void *pvReserved; + DWORD dwReserved; + DWORD FlagsEx; +#endif + +If we compile the source code with (_WIN32_WINNT >= 0x0500), some functions +will not work at NT 4.0, if we use sizeof(OPENFILENAME). +We try to use reduced structure OPENFILENAME_NT4. +*/ + +// #if defined(_WIN64) || (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500) +#if defined(__GNUC__) && (__GNUC__ <= 9) || defined(Z7_OLD_WIN_SDK) + #ifndef _UNICODE + #define my_compatib_OPENFILENAMEA OPENFILENAMEA + #endif + #define my_compatib_OPENFILENAMEW OPENFILENAMEW + + // MinGW doesn't support some required macros. So we define them here: + #ifndef CDSIZEOF_STRUCT + #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) + #endif + #ifndef _UNICODE + #ifndef OPENFILENAME_SIZE_VERSION_400A + #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName) + #endif + #endif + #ifndef OPENFILENAME_SIZE_VERSION_400W + #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName) + #endif + + #ifndef _UNICODE + #define my_compatib_OPENFILENAMEA_size OPENFILENAME_SIZE_VERSION_400A + #endif + #define my_compatib_OPENFILENAMEW_size OPENFILENAME_SIZE_VERSION_400W +#else + #ifndef _UNICODE + #define my_compatib_OPENFILENAMEA OPENFILENAME_NT4A + #define my_compatib_OPENFILENAMEA_size sizeof(my_compatib_OPENFILENAMEA) + #endif + #define my_compatib_OPENFILENAMEW OPENFILENAME_NT4W + #define my_compatib_OPENFILENAMEW_size sizeof(my_compatib_OPENFILENAMEW) +#endif +/* +#elif defined(UNDER_CE) || defined(_WIN64) || (_WIN32_WINNT < 0x0500) +// || !defined(WINVER) + #ifndef _UNICODE + #define my_compatib_OPENFILENAMEA OPENFILENAMEA + #define my_compatib_OPENFILENAMEA_size sizeof(OPENFILENAMEA) + #endif + #define my_compatib_OPENFILENAMEW OPENFILENAMEW + #define my_compatib_OPENFILENAMEW_size sizeof(OPENFILENAMEW) +#else + +#endif +*/ + +#ifndef _UNICODE +#define CONV_U_To_A(dest, src, temp) AString temp; if (src) { temp = GetSystemString(src); dest = temp; } +#endif + +bool CCommonDialogInfo::CommonDlg_BrowseForFile(LPCWSTR lpstrInitialDir, const UStringVector &filters) +{ + /* GetSaveFileName() and GetOpenFileName() could change current dir, + if OFN_NOCHANGEDIR is not used. + We can restore current dir manually, if it's required. + 22.02: we use OFN_NOCHANGEDIR. So we don't need to restore current dir manually. */ + // NFile::NDir::CCurrentDirRestorer curDirRestorer; + +#ifndef _UNICODE + if (!g_IsNT) + { + AString tempPath; + AStringVector f; + unsigned i; + for (i = 0; i < filters.Size(); i++) + f.Add(GetSystemString(filters[i])); + unsigned size = f.Size() + 1; + for (i = 0; i < f.Size(); i++) + size += f[i].Len(); + CObjArray filterBuf(size); + // memset(filterBuf, 0, size * sizeof(char)); + { + char *dest = filterBuf; + for (i = 0; i < f.Size(); i++) + { + const AString &s = f[i]; + MyStringCopy(dest, s); + dest += s.Len() + 1; + } + *dest = 0; + } + my_compatib_OPENFILENAMEA p; + memset(&p, 0, sizeof(p)); + p.lStructSize = my_compatib_OPENFILENAMEA_size; + p.hwndOwner = hwndOwner; + if (size > 1) + { + p.lpstrFilter = filterBuf; + p.nFilterIndex = (DWORD)(FilterIndex + 1); + } + + CONV_U_To_A(p.lpstrInitialDir, lpstrInitialDir, initialDir_a) + CONV_U_To_A(p.lpstrTitle, lpstrTitle, title_a) + + const AString filePath_a = GetSystemString(FilePath); + const unsigned bufSize = MAX_PATH * 8 + + filePath_a.Len() + + initialDir_a.Len(); + p.nMaxFile = bufSize; + p.lpstrFile = tempPath.GetBuf(bufSize); + MyStringCopy(p.lpstrFile, filePath_a); + p.Flags = + OFN_EXPLORER + | OFN_HIDEREADONLY + | OFN_NOCHANGEDIR; + const BOOL b = SaveMode ? + ::GetSaveFileNameA((LPOPENFILENAMEA)(void *)&p) : + ::GetOpenFileNameA((LPOPENFILENAMEA)(void *)&p); + if (!b) + return false; + { + tempPath.ReleaseBuf_CalcLen(bufSize); + FilePath = GetUnicodeString(tempPath); + FilterIndex = (int)p.nFilterIndex - 1; + return true; + } + } + else +#endif + { + UString tempPath; + unsigned size = filters.Size() + 1; + unsigned i; + for (i = 0; i < filters.Size(); i++) + size += filters[i].Len(); + CObjArray filterBuf(size); + // memset(filterBuf, 0, size * sizeof(wchar_t)); + { + wchar_t *dest = filterBuf; + for (i = 0; i < filters.Size(); i++) + { + const UString &s = filters[i]; + MyStringCopy(dest, s); + dest += s.Len() + 1; + } + *dest = 0; + // if ((unsigned)(dest + 1 - filterBuf) != size) return false; + } + my_compatib_OPENFILENAMEW p; + memset(&p, 0, sizeof(p)); + p.lStructSize = my_compatib_OPENFILENAMEW_size; + p.hwndOwner = hwndOwner; + if (size > 1) + { + p.lpstrFilter = filterBuf; + p.nFilterIndex = (DWORD)(FilterIndex + 1); + } + unsigned bufSize = MAX_PATH * 8 + FilePath.Len(); + if (lpstrInitialDir) + { + p.lpstrInitialDir = lpstrInitialDir; + bufSize += MyStringLen(lpstrInitialDir); + } + p.nMaxFile = bufSize; + p.lpstrFile = tempPath.GetBuf(bufSize); + MyStringCopy(p.lpstrFile, FilePath); + p.lpstrTitle = lpstrTitle; + p.Flags = + OFN_EXPLORER + | OFN_HIDEREADONLY + | OFN_NOCHANGEDIR + // | OFN_FORCESHOWHIDDEN // Win10 shows hidden items even without this flag + // | OFN_PATHMUSTEXIST + #ifdef UNDER_CE + | (OpenFolderMode ? (MY_OFN_PROJECT | MY_OFN_SHOW_ALL) : 0) + #endif + ; + const BOOL b = SaveMode ? + ::GetSaveFileNameW((LPOPENFILENAMEW)(void *)&p) : + ::GetOpenFileNameW((LPOPENFILENAMEW)(void *)&p); + /* DOCs: lpstrFile : + if the buffer is too small, then: + - the function returns FALSE + - the CommDlgExtendedError() returns FNERR_BUFFERTOOSMALL + - the first two bytes of the lpstrFile buffer contain the + required size, in bytes or characters. */ + if (!b) + return false; + { + tempPath.ReleaseBuf_CalcLen(bufSize); + FilePath = tempPath; + FilterIndex = (int)p.nFilterIndex - 1; + return true; + } + } +} + +} diff -Nru p7zip-rar-16.02/CPP/Windows/CommonDialog.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.h --- p7zip-rar-16.02/CPP/Windows/CommonDialog.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/CommonDialog.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,23 +1,43 @@ -// Windows/CommonDialog.h - -#ifndef __WINDOWS_COMMON_DIALOG_H -#define __WINDOWS_COMMON_DIALOG_H - -#include "../Common/MyString.h" - -namespace NWindows { - -bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, - LPCWSTR initialDir, // can be NULL, so dir prefix in filePath will be used - LPCWSTR filePath, // full path - LPCWSTR filterDescription, // like "All files (*.*)" - LPCWSTR filter, // like "*.exe" - UString &resPath - #ifdef UNDER_CE - , bool openFolder = false - #endif -); - -} - -#endif +// Windows/CommonDialog.h + +#ifndef ZIP7_INC_WINDOWS_COMMON_DIALOG_H +#define ZIP7_INC_WINDOWS_COMMON_DIALOG_H + +#include "../Common/MyString.h" + +namespace NWindows { + +struct CCommonDialogInfo +{ + /* (FilterIndex == -1) means no selected filter. + and (-1) also is reserved for unsupported custom filter. + if (FilterIndex >= 0), then FilterIndex is index of filter */ + int FilterIndex; // [in / out] + bool SaveMode; + #ifdef UNDER_CE + bool OpenFolderMode; + #endif + HWND hwndOwner; + // LPCWSTR lpstrInitialDir; + LPCWSTR lpstrTitle; + UString FilePath; // [in / out] + + CCommonDialogInfo() + { + FilterIndex = -1; + SaveMode = false; + #ifdef UNDER_CE + OpenFolderMode = false; + #endif + hwndOwner = NULL; + // lpstrInitialDir = NULL; + lpstrTitle = NULL; + } + + /* (filters) : 2 sequential vector strings (Description, Masks) represent each filter */ + bool CommonDlg_BrowseForFile(LPCWSTR lpstrInitialDir, const UStringVector &filters); +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Console.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.cpp --- p7zip-rar-16.02/CPP/Windows/Console.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.cpp 2014-12-30 16:13:06.000000000 +0000 @@ -0,0 +1,10 @@ +// Windows/Console.cpp + +#include "StdAfx.h" + +#include "Console.h" + +namespace NWindows{ +namespace NConsole{ + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Console.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.h --- p7zip-rar-16.02/CPP/Windows/Console.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Console.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,52 @@ +// Windows/Console.h + +#ifndef ZIP7_INC_WINDOWS_CONSOLE_H +#define ZIP7_INC_WINDOWS_CONSOLE_H + +#include "Defs.h" + +namespace NWindows { +namespace NConsole { + +class CBase +{ +protected: + HANDLE m_Object; +public: + void Attach(HANDLE handle) { m_Object = handle; } + bool GetMode(DWORD &mode) + { return BOOLToBool(::GetConsoleMode(m_Object, &mode)); } + bool SetMode(DWORD mode) + { return BOOLToBool(::SetConsoleMode(m_Object, mode)); } +}; + +class CIn: public CBase +{ +public: + bool PeekEvents(PINPUT_RECORD events, DWORD numEvents, DWORD &numEventsRead) + { return BOOLToBool(::PeekConsoleInput(m_Object, events, numEvents, &numEventsRead)); } + bool PeekEvent(INPUT_RECORD &event, DWORD &numEventsRead) + { return PeekEvents(&event, 1, numEventsRead); } + bool ReadEvents(PINPUT_RECORD events, DWORD numEvents, DWORD &numEventsRead) + { return BOOLToBool(::ReadConsoleInput(m_Object, events, numEvents, &numEventsRead)); } + bool ReadEvent(INPUT_RECORD &event, DWORD &numEventsRead) + { return ReadEvents(&event, 1, numEventsRead); } + bool GetNumberOfEvents(DWORD &numEvents) + { return BOOLToBool(::GetNumberOfConsoleInputEvents(m_Object, &numEvents)); } + + bool WriteEvents(const INPUT_RECORD *events, DWORD numEvents, DWORD &numEventsWritten) + { return BOOLToBool(::WriteConsoleInput(m_Object, events, numEvents, &numEventsWritten)); } + bool WriteEvent(const INPUT_RECORD &event, DWORD &numEventsWritten) + { return WriteEvents(&event, 1, numEventsWritten); } + + bool Read(LPVOID buffer, DWORD numChars, DWORD &numCharsRead) + { return BOOLToBool(::ReadConsole(m_Object, buffer, numChars, &numCharsRead, NULL)); } + + bool Flush() + { return BOOLToBool(::FlushConsoleInputBuffer(m_Object)); } + +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ComboBox.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.cpp --- p7zip-rar-16.02/CPP/Windows/Control/ComboBox.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.cpp 2023-01-19 20:00:00.000000000 +0000 @@ -0,0 +1,66 @@ +// Windows/Control/ComboBox.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../../Common/StringConvert.h" +#endif + +#include "ComboBox.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +LRESULT CComboBox::GetLBText(int index, CSysString &s) +{ + s.Empty(); + LRESULT len = GetLBTextLen(index); // length, excluding the terminating null character + if (len == CB_ERR) + return len; + LRESULT len2 = GetLBText(index, s.GetBuf((unsigned)len)); + if (len2 == CB_ERR) + return len; + if (len > len2) + len = len2; + s.ReleaseBuf_CalcLen((unsigned)len); + return len; +} + +#ifndef _UNICODE +LRESULT CComboBox::AddString(LPCWSTR s) +{ + if (g_IsNT) + return SendMsgW(CB_ADDSTRING, 0, (LPARAM)s); + return AddString(GetSystemString(s)); +} + +LRESULT CComboBox::GetLBText(int index, UString &s) +{ + s.Empty(); + if (g_IsNT) + { + LRESULT len = SendMsgW(CB_GETLBTEXTLEN, MY_int_TO_WPARAM(index), 0); + if (len == CB_ERR) + return len; + LRESULT len2 = SendMsgW(CB_GETLBTEXT, MY_int_TO_WPARAM(index), (LPARAM)s.GetBuf((unsigned)len)); + if (len2 == CB_ERR) + return len; + if (len > len2) + len = len2; + s.ReleaseBuf_CalcLen((unsigned)len); + return len; + } + AString sa; + const LRESULT len = GetLBText(index, sa); + if (len == CB_ERR) + return len; + s = GetUnicodeString(sa); + return (LRESULT)s.Len(); +} +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ComboBox.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.h --- p7zip-rar-16.02/CPP/Windows/Control/ComboBox.h 2014-12-28 17:04:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ComboBox.h 2023-03-17 15:00:00.000000000 +0000 @@ -1,84 +1,77 @@ -// Windows/Control/ComboBox.h - -#ifndef __WINDOWS_WX_CONTROL_COMBOBOX_H -#define __WINDOWS_WX_CONTROL_COMBOBOX_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - - -#include "Windows/Control/Window2.h" // NMHDR - -#ifndef _WIN32 -#define CB_ERR (-1) // wxNOT_FOUND -#endif - -typedef struct -{ - NMHDR hdr; -#define CBENF_ESCAPE 1 -#define CBENF_RETURN 2 - int iWhy; -} NMCBEENDEDITW; - -typedef NMCBEENDEDITW * PNMCBEENDEDITW; - - -class wxComboBox; - -namespace NWindows { - namespace NControl { - - class CComboBox // : public CWindow - { - wxComboBox* _choice; - public: - CComboBox() : _choice(0) {} - - void Attach(wxWindow * newWindow); - wxWindow * Detach(); - operator HWND() const; - - int AddString(const TCHAR * txt); - - void SetText(LPCTSTR s); - - void GetText(CSysString &s); - - int GetCount() const ; - void GetLBText(int index, CSysString &s); - - void SetCurSel(int index); - int GetCurSel(); - - void SetItemData(int index, int val); - - LRESULT GetItemData(int index); - - LRESULT GetItemData_of_CurSel() { return GetItemData(GetCurSel()); } - - void Enable(bool state); - - void ResetContent(); - }; - - class CComboBoxEx : public CComboBox // : public CWindow - { - public: - /* FIXME - LRESULT DeleteItem(int index) - { return SendMessage(CBEM_DELETEITEM, index, 0); } - LRESULT InsertItem(COMBOBOXEXITEM *item) - { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); } - DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) - { return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); } - HWND GetEditControl() - { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); } - */ - }; - - - } -} - -#endif // __WINDOWS_WX_CONTROL_COMBOBOX_H +// Windows/Control/ComboBox.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_COMBOBOX_H +#define ZIP7_INC_WINDOWS_CONTROL_COMBOBOX_H + +#include "../../Common/MyWindows.h" + +#include + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CComboBox: public CWindow +{ +public: + void ResetContent() { SendMsg(CB_RESETCONTENT, 0, 0); } + LRESULT AddString(LPCTSTR s) { return SendMsg(CB_ADDSTRING, 0, (LPARAM)s); } + #ifndef _UNICODE + LRESULT AddString(LPCWSTR s); + #endif + + /* If this parameter is -1, any current selection in the list is removed and the edit control is cleared.*/ + LRESULT SetCurSel(int index) { return SendMsg(CB_SETCURSEL, MY_int_TO_WPARAM(index), 0); } + LRESULT SetCurSel(unsigned index) { return SendMsg(CB_SETCURSEL, index, 0); } + + /* If no item is selected, it returns CB_ERR (-1) */ + int GetCurSel() { return (int)SendMsg(CB_GETCURSEL, 0, 0); } + + /* If an error occurs, it is CB_ERR (-1) */ + int GetCount() { return (int)SendMsg(CB_GETCOUNT, 0, 0); } + + LRESULT GetLBTextLen(int index) { return SendMsg(CB_GETLBTEXTLEN, MY_int_TO_WPARAM(index), 0); } + LRESULT GetLBText(int index, LPTSTR s) { return SendMsg(CB_GETLBTEXT, MY_int_TO_WPARAM(index), (LPARAM)s); } + LRESULT GetLBText(int index, CSysString &s); + #ifndef _UNICODE + LRESULT GetLBText(int index, UString &s); + #endif + + LRESULT SetItemData(int index, LPARAM lParam) { return SendMsg(CB_SETITEMDATA, MY_int_TO_WPARAM(index), lParam); } + LRESULT GetItemData(int index) { return SendMsg(CB_GETITEMDATA, MY_int_TO_WPARAM(index), 0); } + LRESULT GetItemData(unsigned index) { return SendMsg(CB_GETITEMDATA, index, 0); } + + LRESULT GetItemData_of_CurSel() { return GetItemData(GetCurSel()); } + + void ShowDropDown(bool show = true) { SendMsg(CB_SHOWDROPDOWN, show ? TRUE : FALSE, 0); } +}; + +#ifndef UNDER_CE + +class CComboBoxEx: public CComboBox +{ +public: + bool SetUnicodeFormat(bool fUnicode) { return LRESULTToBool(SendMsg(CBEM_SETUNICODEFORMAT, BOOLToBool(fUnicode), 0)); } + + /* Returns: + an INT value that represents the number of items remaining in the control. + If (index) is invalid, the message returns CB_ERR. */ + LRESULT DeleteItem(int index) { return SendMsg(CBEM_DELETEITEM, MY_int_TO_WPARAM(index), 0); } + + LRESULT InsertItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_INSERTITEM, 0, (LPARAM)item); } + #ifndef _UNICODE + LRESULT InsertItem(COMBOBOXEXITEMW *item) { return SendMsg(CBEM_INSERTITEMW, 0, (LPARAM)item); } + #endif + + LRESULT SetItem(COMBOBOXEXITEM *item) { return SendMsg(CBEM_SETITEM, 0, (LPARAM)item); } + DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) { return (DWORD)SendMsg(CBEM_SETEXTENDEDSTYLE, exMask, (LPARAM)exStyle); } + HWND GetEditControl() { return (HWND)SendMsg(CBEM_GETEDITCONTROL, 0, 0); } + HIMAGELIST SetImageList(HIMAGELIST imageList) { return (HIMAGELIST)SendMsg(CBEM_SETIMAGELIST, 0, (LPARAM)imageList); } +}; + +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/CommandBar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/CommandBar.h --- p7zip-rar-16.02/CPP/Windows/Control/CommandBar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/CommandBar.h 2023-03-17 12:00:00.000000000 +0000 @@ -0,0 +1,52 @@ +// Windows/Control/CommandBar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_COMMANDBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_COMMANDBAR_H + +#ifdef UNDER_CE + +#include "../../Common/MyWindows.h" + +#include + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CCommandBar: public NWindows::CWindow +{ +public: + bool Create(HINSTANCE hInst, HWND hwndParent, int idCmdBar) + { + _window = ::CommandBar_Create(hInst, hwndParent, idCmdBar); + return (_window != NULL); + } + + // Macros + // void Destroy() { CommandBar_Destroy(_window); } + // bool AddButtons(UINT numButtons, LPTBBUTTON buttons) { return BOOLToBool(SendMsg(TB_ADDBUTTONS, (WPARAM)numButtons, (LPARAM)buttons)); } + // bool InsertButton(unsigned iButton, LPTBBUTTON button) { return BOOLToBool(SendMsg(TB_INSERTBUTTON, (WPARAM)iButton, (LPARAM)button)); } + // BOOL AddToolTips(UINT numToolTips, LPTSTR toolTips) { return BOOLToBool(SendMsg(TB_SETTOOLTIPS, (WPARAM)numToolTips, (LPARAM)toolTips)); } + void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); } + + // bool AddAdornments(DWORD dwFlags) { return BOOLToBool(::CommandBar_AddAdornments(_window, dwFlags, 0)); } + // int AddBitmap(HINSTANCE hInst, int idBitmap, int iNumImages, int iImageWidth, int iImageHeight) { return ::CommandBar_AddBitmap(_window, hInst, idBitmap, iNumImages, iImageWidth, iImageHeight); } + bool DrawMenuBar(WORD iButton) { return BOOLToBool(::CommandBar_DrawMenuBar(_window, iButton)); } + HMENU GetMenu(WORD iButton) { return ::CommandBar_GetMenu(_window, iButton); } + int Height() { return CommandBar_Height(_window); } + HWND InsertComboBox(HINSTANCE hInst, int iWidth, UINT dwStyle, WORD idComboBox, WORD iButton) { return ::CommandBar_InsertComboBox(_window, hInst, iWidth, dwStyle, idComboBox, iButton); } + bool InsertMenubar(HINSTANCE hInst, WORD idMenu, WORD iButton) { return BOOLToBool(::CommandBar_InsertMenubar(_window, hInst, idMenu, iButton)); } + bool InsertMenubarEx(HINSTANCE hInst, LPTSTR pszMenu, WORD iButton) { return BOOLToBool(::CommandBar_InsertMenubarEx(_window, hInst, pszMenu, iButton)); } + bool Show(bool cmdShow) { return BOOLToBool(::CommandBar_Show(_window, BoolToBOOL(cmdShow))); } + + + // CE 4.0 + void AlignAdornments() { CommandBar_AlignAdornments(_window); } +}; + +}} + +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Controls.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Controls.cpp --- p7zip-rar-16.02/CPP/Windows/Control/Controls.cpp 2015-10-09 09:45:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Controls.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,533 +0,0 @@ -// Dialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" - #include "wx/imaglist.h" - #include "wx/listctrl.h" -#endif - -#undef _WIN32 - -#include "Windows/Control/Dialog.h" - -void verify_main_thread(void); - -class LockGUI -{ - bool _IsMain; - public: - LockGUI() { - verify_main_thread(); - _IsMain = wxThread::IsMain(); - if (!_IsMain) { - // DEBUG - printf("GuiEnter-Controls(0x%lx)\n",wxThread::GetCurrentId()); - abort(); // FIXME wxMutexGuiEnter(); - } - } - ~LockGUI() { - if (!_IsMain) { - wxMutexGuiLeave(); - // DEBUG printf("GuiLeave(0x%lx)\n",wxThread::GetCurrentId()); - } - } -}; -///////////////////////// - -static const wxString CLASS_NAME_wxStaticText = wxT("wxStaticText"); -static const wxString CLASS_NAME_wxTextCtrl = wxT("wxTextCtrl"); - -namespace NWindows { - namespace NControl { - - void CDialogChildControl::SetText(LPCWSTR s) - { - LockGUI lock; - const wxChar * class_name = _window->GetClassInfo()->GetClassName (); - - if ( CLASS_NAME_wxStaticText == class_name) { - ((wxStaticText *)_window)->SetLabel(s); - } else if ( CLASS_NAME_wxTextCtrl == class_name) { - ((wxTextCtrl *)_window)->SetLabel(s); - } else { - // ((wxControl *)_window)->SetValue(s); // FIXME - printf("INTERNAL ERROR - CDialogChildControl::SetText(class=%ls) not implemented\n",class_name); - exit(-1); - } - } - - bool CDialogChildControl::GetText(CSysString &s) - { - wxString str; - { - LockGUI lock; - const wxChar * class_name = _window->GetClassInfo()->GetClassName (); - if ( CLASS_NAME_wxStaticText == class_name) { - str = ((wxStaticText *)_window)->GetLabel(); - } else if ( CLASS_NAME_wxTextCtrl == class_name) { - str = ((wxTextCtrl *)_window)->GetLabel(); - } else { - // FIXME str = ((wxTextCtrl *)_window)->GetValue(); - printf("INTERNAL ERROR - CDialogChildControl::GetText(class=%ls) not implemented\n",class_name); - exit(-1); - } - } - s = str; - return true; - } - } -} - -///////////////////////// Windows/Control/ComboBox.cpp -#include "Windows/Control/ComboBox.h" - -namespace NWindows { - namespace NControl { - - void CComboBox::Attach(wxWindow * newWindow) { _choice = (wxComboBox*)newWindow; } - - wxWindow * CComboBox::Detach() - { - wxWindow * window = _choice; - _choice = NULL; - return window; - } - - CComboBox::operator HWND() const { return (HWND)_choice; } - - - int CComboBox::AddString(const TCHAR * txt) { - LockGUI lock; - wxString item(txt); - return _choice->Append(item); - } - - void CComboBox::SetText(LPCTSTR s) { - LockGUI lock; - wxString str(s); - _choice->SetValue(str); - } - - void CComboBox::GetText(CSysString &s) { - LockGUI lock; - wxString str = _choice->GetValue(); - s = str; - } - - int CComboBox::GetCount() const { - LockGUI lock; - return _choice->GetCount(); - } - - void CComboBox::GetLBText(int index, CSysString &s) { - LockGUI lock; - wxString str = _choice->GetString(index); - s = str; - } - - void CComboBox::SetCurSel(int index) { - LockGUI lock; - _choice->SetSelection(index); - } - - int CComboBox::GetCurSel() { - LockGUI lock; - return _choice->GetSelection(); - } - - void CComboBox::SetItemData(int index, int val) { - LockGUI lock; - _choice->SetClientData( index, (void *)(((char *)0) + val)); - } - - LRESULT CComboBox::GetItemData(int index) - { - LockGUI lock; - void * data = _choice->GetClientData(index); - LRESULT ret = (LRESULT)(((char *)data) - ((char *)0)); - return ret; - } - - void CComboBox::Enable(bool state) { - LockGUI lock; - _choice->Enable(state); - } - - void CComboBox::ResetContent() { - LockGUI lock; - _choice->Clear(); - } - } -} - -///////////////////////// Windows/Control/Edit.cpp -#include "Windows/Control/Edit.h" - -namespace NWindows { - namespace NControl { - - void CEdit::SetPasswordChar(WPARAM c) // Warning : does not work for wxMSW - { - LockGUI lock; - long style = _window->GetWindowStyle(); - if ( c == 0 ) style &= ~(wxTE_PASSWORD); - else style |= wxTE_PASSWORD; - _window->SetWindowStyle(style); - _window->Refresh(); - } - - - void CEdit::Show(int cmdShow) - { - LockGUI lock; - // FIXME _window->Show(cmdShow != SW_HIDE); - _window->Enable(cmdShow != SW_HIDE); - } - - void CEdit::SetText(LPCWSTR s) - { - LockGUI lock; - ((wxTextCtrl *)_window)->SetValue(s); - } - - bool CEdit::GetText(CSysString &s) - { - wxString str; - { - LockGUI lock; - str = ((wxTextCtrl *)_window)->GetValue(); - } - s = str; - return true; - } - - } -} - -///////////////////////// Windows/Control/ProgressBar.cpp -#include "Windows/Control/ProgressBar.h" - -namespace NWindows { - namespace NControl { - - CProgressBar::CProgressBar(wxWindow* newWindow): - _window((wxGauge *)newWindow) , _minValue(0), _range(0) { } - - void CProgressBar::Attach(wxWindow* newWindow) { - _window = (wxGauge *)newWindow; - _minValue = 0; - _range = 0; - } - - void CProgressBar::SetRange32(int minValue, int maxValue) { - int range = maxValue - minValue; - if (range >= 1) - { - LockGUI lock; - _minValue = minValue; - _range = range; - _window->SetRange(_range); - } - } - - void CProgressBar::SetPos(int pos) { - if (_range >= 1) - { - LockGUI lock; - int value = pos - _minValue; - if ((value >= 0) && (value <= _range)) _window->SetValue(value); - } - } - - } -} - -///////////////////////// Windows/Control/StatusBar.cpp -#include "Windows/Control/StatusBar.h" - -namespace NWindows { - namespace NControl { - - void CStatusBar::Attach(wxWindow * newWindow) { _statusBar = (wxStatusBar*)newWindow; } - - wxWindow * CStatusBar::Detach() - { - wxWindow * window = _statusBar; - _statusBar = NULL; - return window; - } - - void CStatusBar::SetText(int index, LPCTSTR text) - { - _statusBar->SetStatusText(text,index); - } - - } - -} - -///////////////////////// Windows/Control/ListView.cpp -#include "Windows/Control/ListView.h" - -namespace NWindows { -namespace NControl { - - void CListView::Attach(wxWindow * newWindow) { - _list = (wxListCtrl *)newWindow; - } - - CListView::operator HWND() const { return (HWND)_list; } - - int CListView::GetItemCount() const {return _list->GetItemCount(); } - - int CListView::InsertItem(int index, LPCTSTR text) { - return _list->InsertItem(index, text); - } - int CListView::InsertItem(const LVITEM* item) { - /* - int col = item->iSubItem; - wxString text; - if (item->mask & LVIF_TEXT) text = item->pszText; - - // printf("%p->InsertItem(id=%d,%ls)\n",_list,item->iItem, (const wchar_t *)text); - return _list->InsertItem(item->iItem, text); - */ - wxListItem info; - long mask = 0; - info.SetId(item->iItem); - if (item->mask & LVIF_TEXT) - { - info.SetText(item->pszText); - mask |= wxLIST_MASK_TEXT; - } - if (item->mask & LVIF_PARAM) - { - info.SetData(item->lParam); - mask |= wxLIST_MASK_DATA; - } - if (item->mask & LVIF_STATE) - { - info.SetState(item->state); - mask |= wxLIST_MASK_STATE; - } - // FIXME if (item->mask & LVIF_IMAGE) - - info.SetMask(mask); - - return _list->InsertItem(info); - } - - void CListView::SetItem(const LVITEM* item) { - int col = item->iSubItem; - wxString text; - if (item->mask & LVIF_TEXT) text = item->pszText; - // printf("%p->SetItem(id=%d,col=%d,%ls)\n",_list,item->iItem, col,(const wchar_t *)text); - _list->SetItem(item->iItem, col, text); - } - - int CListView::SetSubItem(int index, int subIndex, LPCTSTR text) - { - return _list->SetItem(index, subIndex, text); - } - - void SetUnicodeFormat(bool fUnicode) { return ; } - - void CListView::_InsertColumn(int columnIndex, LPCTSTR text, int format, int width) - { - _list->InsertColumn(columnIndex, text, format, width); - } - - void CListView::InsertColumn(int columnIndex, LPCTSTR text, int width) - { - this->_InsertColumn(columnIndex, text, wxLIST_FORMAT_LEFT, width); - } - - void CListView::InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) - { - wxString text; - int format = wxLIST_FORMAT_LEFT; - int width = -1; - if (columnInfo->mask & LVCF_FMT) - { - if (columnInfo->fmt == LVCFMT_LEFT) format = wxLIST_FORMAT_LEFT; - if (columnInfo->fmt == LVCFMT_RIGHT) format = wxLIST_FORMAT_RIGHT; - } - if (columnInfo->mask & LVCF_TEXT) text = columnInfo->pszText; - if (columnInfo->mask & LVCF_WIDTH) width = columnInfo->cx; - // FIXME LVCF_SUBITEM - // printf("%p->InsertColumn(%d,%ls)\n",_list,columnIndex,(const wchar_t *)heading); - // _list->InsertColumn(columnIndex, text, format, width); - this->_InsertColumn(columnIndex, text, format, width); - } - - void CListView::DeleteAllItems() { - _list->DeleteAllItems(); - printf("%p->DeleteAllItems()\n",_list); - } - - void CListView::SetRedraw(bool b) { - if (b) _list->Thaw(); - else _list->Freeze(); - printf(" %p->SetRedraw()\n",_list); - } - - void CListView::SetItemCount(int count) { - // ONLY IF VIRTUAL REPORT -- _list->SetItemCount(count); - printf(" %p->SetItemCount(%d)\n",_list,count); - } - - void CListView::InvalidateRect(void *, bool) { - printf("FIXME %p->InvalidateRect()\n",_list);/* FIXME */ - } - - int CListView::GetSelectedCount() const { - int nb = _list->GetSelectedItemCount(); - printf(" %p->GetSelectedCount()=>%d\n",_list,nb); - return nb; - } - - void /* bool */ CListView::EnsureVisible(int index, bool partialOK) { - - printf(" %p->EnsureVisible(%d)\n",_list,index); - - if (index == -1) index = 0; - _list->EnsureVisible(index); - - // return true; - } - - void CListView::SetItemState(int index, UINT state, UINT mask) { - // don't work _list->SetItemState(index, state, mask); !? - // try SetItem ... - /* - wxListItem info; - - info.m_mask = wxLIST_MASK_STATE; - info.m_itemId = index; - info.m_col = 0; - info.m_state = state; - info.m_mask = mask; - - _list->SetItem(info); - */ - - printf(" %p->SetItemState(%d,0x%x,0x%x)\n",_list,index,state,mask); - - if (index == -1) return; - - _list->SetItemState(index, state & (LVIS_SELECTED|LVIS_SELECTED), mask & (LVIS_SELECTED|LVIS_SELECTED)); - -/* - if (mask & LVIS_FOCUSED) { - printf(" %p->SetItemState(%d) => FOCUSED\n",_list,index); - _list->SetItemState(index, state & LVIS_FOCUSED, mask & LVIS_FOCUSED); - } - - if (mask & LVIS_SELECTED) { - printf(" %p->SetItemState(%d) => SELECTED\n",_list,index); - _list->SetItemState(index, state & LVIS_SELECTED, mask & LVIS_SELECTED); - } -*/ - } - - UINT CListView::GetItemState(int index, UINT mask) const - { - UINT state = _list->GetItemState(index, mask); - printf("FIXME %p->GetItemState(index=%d,mask=0x%x)=0x%x\n",_list,index,(unsigned)mask,(unsigned)state); /* FIXME */ - - return state; - } - - void /* bool */ CListView::Update() { - printf("FIXME %p->Update()\n",_list); /* FIXME */ - } - - bool CListView::DeleteColumn(int columnIndex) { - // printf("%p->DeleteColumn()\n",_list); - if (_list->GetColumnCount() < 1) return false; - return _list->DeleteColumn(columnIndex); // always return true !? - } - - bool CListView::GetItemParam(int itemIndex, LPARAM ¶m) const - { - param = _list->GetItemData(itemIndex); - - // printf(" %p->GetItemParam(%d) => %ld\n",_list,itemIndex,(long)param); - - return true; - } - - int CListView::GetNextItem(int startIndex, UINT flags) const - { - int item = _list->GetNextItem(startIndex, wxLIST_NEXT_ALL, flags); - printf(" %p->GetNextItem(%d) => %d\n",_list,startIndex,item); - return item; - - } - - int CListView::GetFocusedItem() const - { - int item = _list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); - printf(" %p->GetFocusedItem() => %d\n",_list,item); - return item; - } - - void CListView::RedrawAllItems() - { - printf("FIXME %p->RedrawAllItems()\n",_list); - } - - // FIXME added - int CListView::GetColumnCount() - { - return _list->GetColumnCount(); - } - - void CListView::SetFocus() { /* FIXME */ } - - void CListView::RedrawItem(int item) { /* FIXME */ } - - bool CListView::SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam) { - printf(" %p->SortItems()\n",_list); - return _list->SortItems(compareFunction, dataParam); - } - - bool CListView::GetColumn(int columnIndex, LVCOLUMN* columnInfo) - { - columnInfo->cx = _list->GetColumnWidth(columnIndex);// FIXME - - bool ret = false; - - if (columnInfo->cx >= 1) ret = true; - - // printf("CListView::GetColumn(%d) cx=%d\n",columnIndex,(int)columnInfo->cx); - - return ret; - } - - // HWND EditLabel(int itemIndex) - void CListView::EditLabel(int itemIndex) - { - /* FIXME */ - } - - - LRESULT CListView2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) - { - return 0; // FIXME return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); - } - - -}} - diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Dialog.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.cpp --- p7zip-rar-16.02/CPP/Windows/Control/Dialog.cpp 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.cpp 2024-03-06 10:00:00.000000000 +0000 @@ -1,584 +1,446 @@ -// Dialog.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include - - -#undef _WIN32 - -#include "Windows/Control/DialogImpl.h" -#include "Windows/Synchronization.h" - -// FIXME -class MyApp : public wxApp -{ -public: - virtual bool OnInit(); -}; - -DECLARE_APP(MyApp) - -// #include "../GUI/p7zip_32.xpm" -extern const char * p7zip_32_xpm[]; - -const TCHAR * nameWindowToUnix(const TCHAR * lpFileName) { - if ((lpFileName[0] == wxT('c')) && (lpFileName[1] == wxT(':'))) return lpFileName+2; - return lpFileName; -} - - -extern time_t g_T0; // FIXME - -#define DIALOG_ID_MESSAGEBOX 8100 -#define DIALOG_ID_DIR_DIALOG 8101 -#define DIALOG_ID_FILE_DIALOG 8102 -#define DIALOG_ID_POST_DIALOG 8190 -#define DIALOG_ID_END_DIALOG 8199 - -static struct -{ - bool busy; - - int id; - wxWindow *parentWindow; - - // CreateDialog - NWindows::NControl::CModalDialog * dialog; - - // EndModal - int value; - NWindows::NControl::CModalDialogImpl * window; - - // MessageBox - const TCHAR * msg; - const TCHAR * title; - int flag; - - // - LPCWSTR initialFolderOrFile; - - wxSemaphore * sem; - int ret; - - UString resultPath; - -#define MAX_CREATE 16 -} g_tabCreate[MAX_CREATE]; - -static int myCreateHandle2(int n); - -static int findFreeInd() -{ -static NWindows::NSynchronization::CCriticalSection g_CriticalSection; - - g_CriticalSection.Enter(); - int ind = 0; - while (ind < MAX_CREATE) - { - if (g_tabCreate[ind].busy == false) - { - g_tabCreate[ind].busy = true; - break; - } - ind++; - } - g_CriticalSection.Leave(); - - return ind; -} - -static int WaitInd(wxWindow * destWindow, int ind,int id,wxWindow * parent,UString &resultPath) -{ - int ret = 0; - - g_tabCreate[ind].id = id; - g_tabCreate[ind].parentWindow = parent; - g_tabCreate[ind].ret = 0; - g_tabCreate[ind].resultPath = wxEmptyString; - - if (wxThread::IsMain()) - { - ret = myCreateHandle2(ind); - resultPath = g_tabCreate[ind].resultPath; - } - else - { - if (destWindow == 0) { - extern wxWindow * g_window; - if (g_window == 0) - { - printf("INTERNAL ERROR : g_window and destWindow == NULL\n"); abort(); - } - destWindow = g_window; - } - g_tabCreate[ind].sem = new wxSemaphore(0); - - // create any type of command event here - wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT ); - event.SetInt( ind ); - - // send in a thread-safe way - // DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow); - wxPostEvent( destWindow, event ); - - g_tabCreate[ind].sem->Wait(); - - ret = g_tabCreate[ind].ret; - resultPath = g_tabCreate[ind].resultPath; - // DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): ret=%d\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow,ret); - delete g_tabCreate[ind].sem; - g_tabCreate[ind].sem = 0; - } - - g_tabCreate[ind].busy = false; - - return ret; -} - -static int WaitInd(wxWindow * destWindow,int ind,int id,wxWindow * parent) -{ - UString resultPath; - return WaitInd(destWindow,ind,id,parent,resultPath); -} - -void verify_main_thread(void); - -class LockGUI -{ - bool _IsMain; - public: - LockGUI() { - - verify_main_thread(); - - _IsMain = wxThread::IsMain(); - if (!_IsMain) { - // DEBUG - printf("GuiEnter-Dialog(0x%lx)\n",wxThread::GetCurrentId()); - abort(); // FIXME wxMutexGuiEnter(); - } - } - ~LockGUI() { - if (!_IsMain) { - wxMutexGuiLeave(); - // DEBUG printf("GuiLeave(0x%lx)\n",wxThread::GetCurrentId()); - } - } -}; - -static const unsigned int kNumDialogsMax = 32; -static unsigned int g_NumDialogs = 0; -static const CDialogInfo *g_Dialogs[kNumDialogsMax]; - -void RegisterDialog(const CDialogInfo *dialogInfo) -{ - // DEBUG printf("RegisterDialog : %d\n",dialogInfo->id); - if (g_NumDialogs < kNumDialogsMax) - g_Dialogs[g_NumDialogs++] = dialogInfo; -} - -namespace NWindows { - - UString MyLoadString(UINT resourceID) - { - for(unsigned i=0; i < g_NumDialogs; i++) { - if (g_Dialogs[i]->stringTable) { - int j = 0; - while(g_Dialogs[i]->stringTable[j].str) { - if (resourceID == g_Dialogs[i]->stringTable[j].id) { - return g_Dialogs[i]->stringTable[j].str; - } - - j++; - } - } - } - printf("MyLoadString(resourceID=%u) : NOT FOUND\n",(unsigned)resourceID); - return L"FIXME-MyLoadStringW-"; - } - - void MyLoadString(UINT resourceID, UString &dest) - { - dest = MyLoadString(resourceID); - } - - namespace NControl { - -/////////////////////////////////////////// CModalDialog ////////////////////////////////// - - bool CModalDialog::CheckButton(int buttonID, UINT checkState) - { - LockGUI lock; - wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID); - if (w) - { - w->SetValue(checkState == BST_CHECKED); - return true; - } - return false; - } - - UINT CModalDialog::IsButtonChecked(int buttonID) const - { - LockGUI lock; - wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID); - if (w) - { - bool bret = w->GetValue(); - if (bret) return BST_CHECKED; - } - return BST_UNCHECKED; - } - - void CModalDialog::EnableItem(int id, bool state) - { - LockGUI lock; - wxWindow* w = _window->FindWindow(id); - if (w) w->Enable(state); - } - - void CModalDialog::SetItemText(int id, const TCHAR *txt) - { - LockGUI lock; - wxWindow* w = _window->FindWindow(id); - if (w) - { - wxString label(txt); - w->SetLabel(label); - } - } - - wxWindow * CModalDialog::GetItem(long id) const - { - LockGUI lock; - wxWindow * w = _window->FindWindow(id); - if (w == 0) printf("@@WARNING :GetItem(%ld)=NULL\n",id); - return w; - } - - void CModalDialog::ShowItem(int itemID, int cmdShow) const - { - LockGUI lock; - // cmdShow = SW_HIDE or SW_SHOW (sometimes false or true !) - wxWindow* w = _window->FindWindow(itemID); - if (w) - { -// FIXME w->Show(cmdShow != SW_HIDE); - w->Enable(cmdShow != SW_HIDE); - } - } - - UINT_PTR CModalDialog::SetTimer(UINT_PTR idEvent , unsigned milliseconds) - { - LockGUI lock; - return _window->SetTimer(idEvent , milliseconds); - } - - void CModalDialog::KillTimer(UINT_PTR idEvent) - { - LockGUI lock; - _window->KillTimer(idEvent); - } - - void CModalDialog::SetText(const TCHAR *_title) { - LockGUI lock; - _window->SetTitle(_title); - } - - - bool CModalDialog::GetText(CSysString &s) { - wxString str; - { - LockGUI lock; - str = _window->GetTitle(); - } - s = str; - return true; - } - - INT_PTR CModalDialog::Create(int id , HWND parentWindow) - { - int ind = findFreeInd(); - - g_tabCreate[ind].dialog = this; - - return WaitInd(0, ind,id,parentWindow); - } - - void CModalDialog::End(int result) - { - int ind = findFreeInd(); - - g_tabCreate[ind].window = _window; - g_tabCreate[ind].value = result; - - WaitInd(this->_window,ind,DIALOG_ID_END_DIALOG,0); - } - - void CModalDialog::PostMsg(UINT message) - { - int ind = findFreeInd(); - - g_tabCreate[ind].dialog = this; - g_tabCreate[ind].value = message; - - WaitInd(this->_window,ind,DIALOG_ID_POST_DIALOG,0); - } - -/////////////////////////////////////////// CModalDialogImpl /////////////////////////////////////// - - CModalDialogImpl::CModalDialogImpl(CDialog *dialog, wxWindow* parent, wxWindowID id, - const wxString& title, const wxPoint& pos, - const wxSize& size, long style) : - wxDialog(parent, id, title , pos , size, style /* | wxDIALOG_NO_PARENT */ ) , - _timer(this, TIMER_ID_IMPL), _dialog(dialog) - { - // set the frame icon - this->SetIcon(wxICON(p7zip_32)); - } - - void CModalDialogImpl::OnAnyButton(wxCommandEvent& event) - { - int id = event.GetId(); - if (id == wxID_OK) - { - if (_dialog) _dialog->OnOK(); - // event.Skip(true); - } - else if (id == wxID_CANCEL) - { - if (_dialog) _dialog->OnCancel(); - // event.Skip(true); - } - else if (id == wxID_HELP) - { - if (_dialog) _dialog->OnHelp(); - } - else - { - if (_dialog) - { - /* bool bret = */ _dialog->OnButtonClicked(id, FindWindow(id) ); - } - } - } - - void CModalDialogImpl::OnAnyChoice(wxCommandEvent &event) - { - int itemID = event.GetId(); - if (_dialog) _dialog->OnCommand(CBN_SELCHANGE, itemID, 0); - } - - void CModalDialogImpl::OnAnyTimer(wxTimerEvent &event) - { - int timerID = event.GetId(); - if (_dialog) _dialog->OnTimer(timerID , 0); - } - } -} - -///////////////////////// myCreateHandle - - -static int myCreateHandle2(int n) -{ - unsigned int id = g_tabCreate[n].id; - wxWindow * parentWindow = g_tabCreate[n].parentWindow; - NWindows::NControl::CModalDialogImpl * window = 0; - - // DEBUG printf("T=0x%lx - %d : myCreateHandle(%d): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,n); - - if (id == DIALOG_ID_END_DIALOG) - { - /* FIXME : the dialog must be shown before ending it ? - while (!g_tabCreate[n].window->IsShownOnScreen()) Sleep(200); - Sleep(200); - */ - g_tabCreate[n].window->EndModal(g_tabCreate[n].value); - return 0; - } - - if (id == DIALOG_ID_POST_DIALOG) - { - g_tabCreate[n].dialog->OnMessage(g_tabCreate[n].value, 0, 0); - return 0; - } - - if (id == DIALOG_ID_MESSAGEBOX) - { - long style = g_tabCreate[n].flag; - long decorated_style = style; - if ( ( style & ( wxICON_EXCLAMATION | wxICON_HAND | wxICON_INFORMATION | - wxICON_QUESTION ) ) == 0 ) - { - decorated_style |= ( style & wxYES ) ? wxICON_QUESTION : wxICON_INFORMATION ; - } - wxMessageDialog dialog(parentWindow, g_tabCreate[n].msg, g_tabCreate[n].title, decorated_style); - // FIXME dialog.SetIcon(wxICON(p7zip_32)); - int ret = dialog.ShowModal(); - - return ret; - } - - if (id == DIALOG_ID_DIR_DIALOG) - { - wxString defaultDir = g_tabCreate[n].initialFolderOrFile; - wxDirDialog dirDialog(g_tabCreate[n].parentWindow, - g_tabCreate[n].title, defaultDir); - dirDialog.SetIcon(wxICON(p7zip_32)); - int ret = dirDialog.ShowModal(); - if (ret == wxID_OK) g_tabCreate[n].resultPath = dirDialog.GetPath(); - return ret; - } - - if (id == DIALOG_ID_FILE_DIALOG) - { - wxString defaultFilename = g_tabCreate[n].initialFolderOrFile; - - wxFileName filename(defaultFilename); - - wxString dir = filename.GetPath(); - wxString name = filename.GetFullName(); - - - // printf("DIALOG_ID_FILE_DIALOG = '%ls' => '%ls' '%ls'\n",&defaultFilename[0],&dir[0],&name[0]); - - - wxFileDialog fileDialog(g_tabCreate[n].parentWindow, g_tabCreate[n].title, - dir, name, wxT("All Files (*.*)|*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); - fileDialog.SetIcon(wxICON(p7zip_32)); - int ret = fileDialog.ShowModal(); - if (ret == wxID_OK) g_tabCreate[n].resultPath = fileDialog.GetPath(); - return ret; - } - - for(unsigned i=0; i < g_NumDialogs; i++) { - if (id == g_Dialogs[i]->id) { - // DEBUG printf("%d : Create(%d,%p): CreateDialog-1\n",time(0)-g_T0,id,parentWindow); - window = (g_Dialogs[i]->createDialog)(g_tabCreate[n].dialog,g_tabCreate[n].parentWindow); - // DEBUG printf("%d : Create(%d,%p): CreateDialog-2\n",time(0)-g_T0,id,parentWindow); - break; - } - } - - if (window) { - - // DEBUG printf("%d : Create(%d,%p): %p->ShowModal()\n",time(0)-g_T0,id,parentWindow,window); - - // window->Show(true); - // wxGetApp().ProcessPendingEvents(); - - INT_PTR ret = window->ShowModal(); - - // DEBUG printf("%d : Create(%d,%p): %p->ShowModal() - ret=%d\n",time(0)-g_T0,id,parentWindow,window,ret); - window->Detach(); - window->Destroy(); - - // DEBUG printf("%d : Create(%d,%p): END\n",time(0)-g_T0,id,parentWindow,window); - - return ret; - } - - // FIXME - printf("INTERNAL ERROR : cannot find dialog %d\n",id); - - return 0; -} - -void myCreateHandle(int n) -{ - int ret = myCreateHandle2(n); - g_tabCreate[n].ret = ret; - g_tabCreate[n].sem->Post(); -} - -int MessageBoxW(wxWindow * parent, const TCHAR * msg, const TCHAR * title,int flag) -{ - int ind = findFreeInd(); - - g_tabCreate[ind].msg = msg; - g_tabCreate[ind].title = title; - g_tabCreate[ind].flag = flag; - - return WaitInd(parent,ind,DIALOG_ID_MESSAGEBOX,parent); // FIXME -} - - - -// FIXME : should be in Windows/Shell.cpp - -namespace NWindows{ -namespace NShell{ - -bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath) -{ - int ind = findFreeInd(); - - g_tabCreate[ind].title = title; - g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(initialFolder); - - UString resTmp; - int ret = WaitInd(0,ind,DIALOG_ID_DIR_DIALOG,owner,resTmp); // FIXME - if(ret == wxID_OK) - { - resultPath = resTmp; - return true; - } - return false; -} - -}} - -/////////////////////////// CPP/Windows/CommonDialog.cpp -namespace NWindows -{ - - // OLD bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR /* FIXME initialDir */ , LPCWSTR fullFileName, LPCWSTR s, UString &resPath) - bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, - LPCWSTR /* FIXME initialDir */ , // can be NULL, so dir prefix in filePath will be used - LPCWSTR filePath, // full path - LPCWSTR /* FIXME filterDescription */ , // like "All files (*.*)" - LPCWSTR filter, // like "*.exe" - UString &resPath - #ifdef UNDER_CE - , bool openFolder = false - #endif - ) - { - int ind = findFreeInd(); - - g_tabCreate[ind].title = title; - g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(filePath); - - UString resTmp; - int ret = WaitInd(0,ind,DIALOG_ID_FILE_DIALOG,hwnd,resTmp); // FIXME - if(ret == wxID_OK) - { - resPath = resTmp; - return true; - } - return false; - } -} - -// From CPP/7zip/UI/FileManager/BrowseDialog.cpp -bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result) -{ - result = path; - return true; -} - +// Windows/Control/Dialog.cpp + +#include "StdAfx.h" + +// #include "../../Windows/DLL.h" + +#ifndef _UNICODE +#include "../../Common/StringConvert.h" +#endif + +#include "Dialog.h" + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +APIENTRY +DialogProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(dialogHWND); + if (message == WM_INITDIALOG) + tempDialog.SetUserDataLongPtr(lParam); + CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr()); + if (dialog == NULL) + return FALSE; + if (message == WM_INITDIALOG) + dialog->Attach(dialogHWND); + + /* MSDN: The dialog box procedure should return + TRUE - if it processed the message + FALSE - if it did not process the message + If the dialog box procedure returns FALSE, + the dialog manager performs the default dialog operation in response to the message. + */ + + try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); } + catch(...) { return TRUE; } +} + +bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: return OnInit(); + case WM_COMMAND: return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam); + case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam); + case WM_TIMER: return OnTimer(wParam, lParam); + case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_DESTROY: return OnDestroy(); + case WM_HELP: OnHelp(); return true; + /* + OnHelp( + #ifdef UNDER_CE + (void *) + #else + (LPHELPINFO) + #endif + lParam); + return true; + */ + default: return false; + } +} + +/* +bool CDialog::OnCommand2(WPARAM wParam, LPARAM lParam) +{ + return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam); +} +*/ + +bool CDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam) +{ + if (code == BN_CLICKED) + return OnButtonClicked(itemID, (HWND)lParam); + return false; +} + +bool CDialog::OnButtonClicked(unsigned buttonID, HWND /* buttonHWND */) +{ + switch (buttonID) + { + case IDOK: OnOK(); break; + case IDCANCEL: OnCancel(); break; + case IDCLOSE: OnClose(); break; + case IDCONTINUE: OnContinue(); break; + case IDHELP: OnHelp(); break; + default: return false; + } + return true; +} + +#ifndef UNDER_CE +/* in win2000/win98 : monitor functions are supported. + We need dynamic linking, if we want nt4/win95 support in program. + Even if we compile the code with low (WINVER) value, we still + want to use monitor functions. So we declare missing functions here */ +// #if (WINVER < 0x0500) +#ifndef MONITOR_DEFAULTTOPRIMARY +extern "C" { +DECLARE_HANDLE(HMONITOR); +#define MONITOR_DEFAULTTOPRIMARY 0x00000001 +typedef struct tagMONITORINFO +{ + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; +} MONITORINFO, *LPMONITORINFO; +WINUSERAPI HMONITOR WINAPI MonitorFromWindow(HWND hwnd, DWORD dwFlags); +WINUSERAPI BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpmi); +} +#endif +#endif + +static bool GetWorkAreaRect(RECT *rect, HWND hwnd) +{ + if (hwnd) + { + #ifndef UNDER_CE + /* MonitorFromWindow() is supported in Win2000+ + MonitorFromWindow() : retrieves a handle to the display monitor that has the + largest area of intersection with the bounding rectangle of a specified window. + dwFlags: Determines the function's return value if the window does not intersect any display monitor. + MONITOR_DEFAULTTONEAREST : Returns display that is nearest to the window. + MONITOR_DEFAULTTONULL : Returns NULL. + MONITOR_DEFAULTTOPRIMARY : Returns the primary display monitor. + */ + const HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); + if (hmon) + { + MONITORINFO mi; + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + if (GetMonitorInfoA(hmon, &mi)) + { + *rect = mi.rcWork; + return true; + } + } + #endif + } + + /* Retrieves the size of the work area on the primary display monitor. + The work area is the portion of the screen not obscured + by the system taskbar or by application desktop toolbars. + Any DPI virtualization mode of the caller has no effect on this output. */ + + return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0)); +} + + +bool IsDialogSizeOK(int xSize, int ySize, HWND hwnd) +{ + // it returns for system font. Real font uses another values + const LONG v = GetDialogBaseUnits(); + const int x = LOWORD(v); + const int y = HIWORD(v); + + RECT rect; + GetWorkAreaRect(&rect, hwnd); + const int wx = RECT_SIZE_X(rect); + const int wy = RECT_SIZE_Y(rect); + return + xSize / 4 * x <= wx && + ySize / 8 * y <= wy; +} + +bool CDialog::GetMargins(int margin, int &x, int &y) +{ + x = margin; + y = margin; + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = margin; + rect.bottom = margin; + if (!MapRect(&rect)) + return false; + x = rect.right - rect.left; + y = rect.bottom - rect.top; + return true; +} + +int CDialog::Units_To_Pixels_X(int units) +{ + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = units; + rect.bottom = units; + if (!MapRect(&rect)) + return units * 3 / 2; + return rect.right - rect.left; +} + +bool CDialog::GetItemSizes(unsigned id, int &x, int &y) +{ + RECT rect; + if (!::GetWindowRect(GetItem(id), &rect)) + return false; + x = RECT_SIZE_X(rect); + y = RECT_SIZE_Y(rect); + return true; +} + +void CDialog::GetClientRectOfItem(unsigned id, RECT &rect) +{ + ::GetWindowRect(GetItem(id), &rect); + ScreenToClient(&rect); +} + +bool CDialog::MoveItem(unsigned id, int x, int y, int width, int height, bool repaint) +{ + return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint))); +} + + +/* +typedef BOOL (WINAPI * Func_DwmGetWindowAttribute)( + HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); + +static bool GetWindowsRect_DWM(HWND hwnd, RECT *rect) +{ + // dll load and free is too slow : 300 calls in second. + NDLL::CLibrary dll; + if (!dll.Load(FTEXT("dwmapi.dll"))) + return false; + Func_DwmGetWindowAttribute f = (Func_DwmGetWindowAttribute)dll.GetProc("DwmGetWindowAttribute" ); + if (f) + { + #define MY__DWMWA_EXTENDED_FRAME_BOUNDS 9 + // 30000 per second + RECT r; + if (f(hwnd, MY__DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK) + { + *rect = r; + return true; + } + } + return false; +} +*/ + + +static bool IsRect_Small_Inside_Big(const RECT &sm, const RECT &big) +{ + return sm.left >= big.left + && sm.right <= big.right + && sm.top >= big.top + && sm.bottom <= big.bottom; +} + + +static bool AreRectsOverlapped(const RECT &r1, const RECT &r2) +{ + return r1.left < r2.right + && r1.right > r2.left + && r1.top < r2.bottom + && r1.bottom > r2.top; +} + + +static bool AreRectsEqual(const RECT &r1, const RECT &r2) +{ + return r1.left == r2.left + && r1.right == r2.right + && r1.top == r2.top + && r1.bottom == r2.bottom; +} + + +void CDialog::NormalizeSize(bool fullNormalize) +{ + RECT workRect; + if (!GetWorkAreaRect(&workRect, *this)) + return; + RECT rect; + if (!GetWindowRect(&rect)) + return; + int xs = RECT_SIZE_X(rect); + int ys = RECT_SIZE_Y(rect); + + // we don't want to change size using workRect, if window is outside of WorkArea + if (!AreRectsOverlapped(rect, workRect)) + return; + + /* here rect and workRect are overlapped, but it can be false + overlapping of small shadow when window in another display. */ + + const int xsW = RECT_SIZE_X(workRect); + const int ysW = RECT_SIZE_Y(workRect); + if (xs <= xsW && ys <= ysW) + return; // size of window is OK + if (fullNormalize) + { + Show(SW_SHOWMAXIMIZED); + return; + } + int x = workRect.left; + int y = workRect.top; + if (xs < xsW) x += (xsW - xs) / 2; else xs = xsW; + if (ys < ysW) y += (ysW - ys) / 2; else ys = ysW; + Move(x, y, xs, ys, true); +} + + +void CDialog::NormalizePosition() +{ + RECT workRect; + if (!GetWorkAreaRect(&workRect, *this)) + return; + + RECT rect2 = workRect; + bool useWorkArea = true; + const HWND parentHWND = GetParent(); + + if (parentHWND) + { + RECT workRectParent; + if (!GetWorkAreaRect(&workRectParent, parentHWND)) + return; + + // if windows are in different monitors, we use only workArea of current window + + if (AreRectsEqual(workRectParent, workRect)) + { + // RECT rect3; if (GetWindowsRect_DWM(parentHWND, &rect3)) {} + CWindow wnd(parentHWND); + if (wnd.GetWindowRect(&rect2)) + { + // it's same monitor. So we try to use parentHWND rect. + /* we don't want to change position, if parent window is not inside work area. + In Win10 : parent window rect is 8 pixels larger for each corner than window size for shadow. + In maximize mode : window is outside of workRect. + if parent window is inside workRect, we will use parent window instead of workRect */ + if (IsRect_Small_Inside_Big(rect2, workRect)) + useWorkArea = false; + } + } + } + + RECT rect; + if (!GetWindowRect(&rect)) + return; + + if (useWorkArea) + { + // we don't want to move window, if it's already inside. + if (IsRect_Small_Inside_Big(rect, workRect)) + return; + // we don't want to move window, if it's outside of workArea + if (!AreRectsOverlapped(rect, workRect)) + return; + rect2 = workRect; + } + + { + const int xs = RECT_SIZE_X(rect); + const int ys = RECT_SIZE_Y(rect); + const int xs2 = RECT_SIZE_X(rect2); + const int ys2 = RECT_SIZE_Y(rect2); + // we don't want to change position if parent is smaller. + if (xs <= xs2 && ys <= ys2) + { + const int x = rect2.left + (xs2 - xs) / 2; + const int y = rect2.top + (ys2 - ys) / 2; + + if (x != rect.left || y != rect.top) + Move(x, y, xs, ys, true); + // SetWindowPos(*this, HWND_TOP, x, y, 0, 0, SWP_NOSIZE); + return; + } + } +} + + + +bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow) +{ + const HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); + if (!aHWND) + return false; + Attach(aHWND); + return true; +} + +INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow) +{ + return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); +} + +#ifndef _UNICODE + +bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow) +{ + HWND aHWND; + if (g_IsNT) + aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); + else + { + AString name; + LPCSTR templateNameA; + if (IS_INTRESOURCE(templateName)) + templateNameA = (LPCSTR)templateName; + else + { + name = GetSystemString(templateName); + templateNameA = name; + } + aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this); + } + if (aHWND == 0) + return false; + Attach(aHWND); + return true; +} + +INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow) +{ + if (g_IsNT) + return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this); + AString name; + LPCSTR templateNameA; + if (IS_INTRESOURCE(templateName)) + templateNameA = (LPCSTR)templateName; + else + { + name = GetSystemString(templateName); + templateNameA = name; + } + return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this); +} +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Dialog.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.h --- p7zip-rar-16.02/CPP/Windows/Control/Dialog.h 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Dialog.h 2024-05-03 10:00:00.000000000 +0000 @@ -1,171 +1,213 @@ -// Windows/Control/Dialog.h - -#ifndef __WINDOWS_CONTROL_DIALOG_H -#define __WINDOWS_CONTROL_DIALOG_H - -#include "Windows/Window.h" - -#ifndef _WIN32 - -#define WM_SETTEXT (6000) // wxID_HIGHEST + 1 -#define WM_USER (6999) // wxID_HIGHEST + 1000 -#define WM_APP (26999) // wxID_HIGHEST + 22000 - -#endif - -#ifndef _WIN32 -#define CBN_SELCHANGE 1 -#endif - -#define BST_CHECKED 1 -#define BST_UNCHECKED 0 -// #define BST_INDETERMINATE 0x0002 - -// FIXME #define wsprintf(a,b,c,d,e) swprintf(a,9999,b,c,d,e) // FIXME - -namespace NWindows { - namespace NControl { - - class CModalDialogImpl; - - class CDialog - { - protected: - CModalDialogImpl * _window; - public: - operator HWND() const { return HWND(_window); } - - bool OnInit(CModalDialogImpl * window) { - _window = window; - return OnInit(); - } - virtual bool OnInit() { return false; } - virtual void OnOK() {} - virtual void OnCancel() {} - virtual void OnHelp() {} - virtual bool OnButtonClicked(int buttonID, wxWindow * buttonHWND) { return false; } - virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { return false; } - virtual bool OnCommand(int code, int itemID, LPARAM lParam) { return false; } - virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; } - - void NormalizeSize(bool fullNormalize = false) { /* FIXME */ } - void NormalizePosition() { /* FIXME */ } - }; - - class CModalDialog : public CDialog - { - public: - - - ////////////////// COMPATIBILITY - - bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID) - { -/* - for(int id = firstButtonID; id <= lastButtonID; id++) - { - CheckButton(id,id == checkButtonID); - } -*/ - this->CheckButton(checkButtonID,true); - - return true; - } - - - bool CheckButton(int buttonID, UINT checkState); - bool CheckButton(int buttonID, bool checkState) - { - return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); - } - - - UINT IsButtonChecked(int buttonID) const; - - bool IsButtonCheckedBool(long buttonID) const - { return (IsButtonChecked(buttonID) == BST_CHECKED); } - - void EnableItem(int id, bool state); - - void SetItemText(int id, const TCHAR *txt); - - wxWindow * GetItem(long id) const ; - - void ShowItem(int itemID, int cmdShow) const; - - void ShowItem_Bool(int itemID, bool show) const { ShowItem(itemID, show ? SW_SHOW: SW_HIDE); } - - - void HideItem(int itemID) const { ShowItem(itemID, SW_HIDE); } - - void End(int result); - - void SetText(const TCHAR *_title); // { _dialog->SetTitle(_title); } - - bool GetText(CSysString &s); - - INT_PTR Create(int id , HWND parentWindow); - - void PostMsg(UINT message); - - virtual void OnHelp() {} - - UINT_PTR SetTimer(UINT_PTR idEvent , unsigned milliseconds); - - void KillTimer(UINT_PTR idEvent); - - virtual void OnOK() { End(IDOK); } - virtual void OnCancel() { End(IDCANCEL); } - }; - -class CDialogChildControl : public NWindows::CWindow -{ -public: - CDialogChildControl() {} - - int m_ID; - void Init(const NWindows::NControl::CModalDialog &parentDialog, int id) - { - m_ID = id; - this->Attach(parentDialog.GetItem(id)); - } - virtual void SetText(LPCWSTR s); - virtual bool GetText(CSysString &s); -}; - -} -} - -struct CStringTable -{ - unsigned int id; - const wchar_t *str; -}; - -struct CDialogInfo -{ - int id; - NWindows::NControl::CModalDialogImpl * (*createDialog)(NWindows::NControl::CModalDialog * dialog, HWND parentWindow); - CStringTable * stringTable; -}; - -void RegisterDialog(const CDialogInfo *dialogInfo); - -#define REGISTER_DIALOG_NAME(x) CRegister ## x - -#define REGISTER_DIALOG(id,x,stringTable) \ - static NWindows::NControl::CModalDialogImpl * myCreate##x(NWindows::NControl::CModalDialog * dialog,HWND parentWindow) \ - { return new x##Impl(dialog,parentWindow,id); } \ - static struct CDialogInfo g_DialogInfo = { id , myCreate##x, stringTable }; \ - struct REGISTER_DIALOG_NAME(x) { \ - REGISTER_DIALOG_NAME(x)() { RegisterDialog(&g_DialogInfo); }}; \ - static REGISTER_DIALOG_NAME(x) g_RegisterDialog; - -#define REGISTER_STRINGTABLE(stringTable) \ - static struct CDialogInfo g_DialogInfo = { -1 , 0 , stringTable }; \ - struct REGISTER_DIALOG_NAME(x) { \ - REGISTER_DIALOG_NAME(x)() { RegisterDialog(&g_DialogInfo); }}; \ - static REGISTER_DIALOG_NAME(x) g_RegisterDialog; - -#endif - +// Windows/Control/Dialog.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_DIALOG_H +#define ZIP7_INC_WINDOWS_CONTROL_DIALOG_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +#ifndef IDCONTINUE +#define IDCONTINUE 11 +#endif + +class CDialog: public CWindow +{ + // Z7_CLASS_NO_COPY(CDialog) +public: + CDialog(HWND wnd = NULL): CWindow(wnd) {} + virtual ~CDialog() {} + + HWND GetItem(unsigned itemID) const + { return GetDlgItem(_window, (int)itemID); } + + bool EnableItem(unsigned itemID, bool enable) const + { return BOOLToBool(::EnableWindow(GetItem(itemID), BoolToBOOL(enable))); } + + bool ShowItem(unsigned itemID, int cmdShow) const + { return BOOLToBool(::ShowWindow(GetItem(itemID), cmdShow)); } + + bool ShowItem_Bool(unsigned itemID, bool show) const + { return ShowItem(itemID, show ? SW_SHOW: SW_HIDE); } + + bool HideItem(unsigned itemID) const { return ShowItem(itemID, SW_HIDE); } + + bool SetItemText(unsigned itemID, LPCTSTR s) + { return BOOLToBool(SetDlgItemText(_window, (int)itemID, s)); } + + bool SetItemTextA(unsigned itemID, LPCSTR s) + { return BOOLToBool(SetDlgItemTextA(_window, (int)itemID, s)); } + + bool SetItemText_Empty(unsigned itemID) + { return SetItemText(itemID, TEXT("")); } + + #ifndef _UNICODE + bool SetItemText(unsigned itemID, LPCWSTR s) + { + CWindow window(GetItem(itemID)); + return window.SetText(s); + } + #endif + + UINT GetItemText(unsigned itemID, LPTSTR string, unsigned maxCount) + { return GetDlgItemText(_window, (int)itemID, string, (int)maxCount); } + #ifndef _UNICODE + /* + bool GetItemText(unsigned itemID, LPWSTR string, int maxCount) + { + CWindow window(GetItem(unsigned)); + return window.GetText(string, maxCount); + } + */ + #endif + + bool GetItemText(unsigned itemID, UString &s) + { + CWindow window(GetItem(itemID)); + return window.GetText(s); + } + +/* + bool SetItemInt(unsigned itemID, UINT value, bool isSigned) + { return BOOLToBool(SetDlgItemInt(_window, (int)itemID, value, BoolToBOOL(isSigned))); } +*/ + bool SetItemUInt(unsigned itemID, UINT value) + { return BOOLToBool(SetDlgItemInt(_window, (int)itemID, value, FALSE)); } +/* + bool GetItemInt(unsigned itemID, bool isSigned, UINT &value) + { + BOOL result; + value = GetDlgItemInt(_window, (int)itemID, &result, BoolToBOOL(isSigned)); + return BOOLToBool(result); + } +*/ + bool GetItemUInt(unsigned itemID, UINT &value) + { + BOOL result; + value = GetDlgItemInt(_window, (int)itemID, &result, FALSE); + return BOOLToBool(result); + } + + HWND GetNextGroupItem(HWND control, bool previous) + { return GetNextDlgGroupItem(_window, control, BoolToBOOL(previous)); } + HWND GetNextTabItem(HWND control, bool previous) + { return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); } + + LRESULT SendMsg_NextDlgCtl(WPARAM wParam, LPARAM lParam) + { return SendMsg(WM_NEXTDLGCTL, wParam, lParam); } + LRESULT SendMsg_NextDlgCtl_HWND(HWND hwnd) { return SendMsg_NextDlgCtl((WPARAM)hwnd, TRUE); } + LRESULT SendMsg_NextDlgCtl_CtlId(unsigned id) { return SendMsg_NextDlgCtl_HWND(GetItem(id)); } + LRESULT SendMsg_NextDlgCtl_Next() { return SendMsg_NextDlgCtl(0, FALSE); } + LRESULT SendMsg_NextDlgCtl_Prev() { return SendMsg_NextDlgCtl(1, FALSE); } + + bool MapRect(LPRECT rect) + { return BOOLToBool(MapDialogRect(_window, rect)); } + + bool IsMessage(LPMSG message) + { return BOOLToBool(IsDialogMessage(_window, message)); } + + LRESULT SendItemMessage(unsigned itemID, UINT message, WPARAM wParam, LPARAM lParam) + { return SendDlgItemMessage(_window, (int)itemID, message, wParam, lParam); } + + bool CheckButton(unsigned buttonID, UINT checkState) + { return BOOLToBool(CheckDlgButton(_window, (int)buttonID, checkState)); } + bool CheckButton(unsigned buttonID, bool checkState) + { return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); } + + UINT IsButtonChecked_BST(unsigned buttonID) const + { return IsDlgButtonChecked(_window, (int)buttonID); } + bool IsButtonCheckedBool(unsigned buttonID) const + { return (IsButtonChecked_BST(buttonID) == BST_CHECKED); } + + bool CheckRadioButton(unsigned firstButtonID, unsigned lastButtonID, unsigned checkButtonID) + { return BOOLToBool(::CheckRadioButton(_window, + (int)firstButtonID, (int)lastButtonID, (int)checkButtonID)); } + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnInit() { return true; } + // virtual bool OnCommand2(WPARAM wParam, LPARAM lParam); + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam); + virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; } + virtual bool OnDestroy() { return false; } + + /* + #ifdef UNDER_CE + virtual void OnHelp(void *) { OnHelp(); } + #else + virtual void OnHelp(LPHELPINFO) { OnHelp(); } + #endif + */ + virtual void OnHelp() {} + + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND); + virtual void OnOK() {} + virtual void OnContinue() {} + virtual void OnCancel() {} + virtual void OnClose() {} + virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */) { return false; } + virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; } + + LONG_PTR SetMsgResult(LONG_PTR newLongPtr ) + { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); } + LONG_PTR GetMsgResult() const + { return GetLongPtr(DWLP_MSGRESULT); } + + bool GetMargins(int margin, int &x, int &y); + int Units_To_Pixels_X(int units); + bool GetItemSizes(unsigned id, int &x, int &y); + void GetClientRectOfItem(unsigned id, RECT &rect); + bool MoveItem(unsigned id, int x, int y, int width, int height, bool repaint = true); + bool MoveItem_RECT(unsigned id, const RECT &r, bool repaint = true) + { return MoveItem(id, r.left, r.top, RECT_SIZE_X(r), RECT_SIZE_Y(r), repaint); } + + void NormalizeSize(bool fullNormalize = false); + void NormalizePosition(); +}; + +class CModelessDialog: public CDialog +{ +public: + bool Create(LPCTSTR templateName, HWND parentWindow); + bool Create(UINT resID, HWND parentWindow) { return Create(MAKEINTRESOURCEW(resID), parentWindow); } + #ifndef _UNICODE + bool Create(LPCWSTR templateName, HWND parentWindow); + #endif + virtual void OnOK() Z7_override { Destroy(); } + virtual void OnContinue() Z7_override { Destroy(); } + virtual void OnCancel() Z7_override { Destroy(); } + virtual void OnClose() Z7_override { Destroy(); } +}; + +class CModalDialog: public CDialog +{ +public: + INT_PTR Create(LPCTSTR templateName, HWND parentWindow); + INT_PTR Create(UINT resID, HWND parentWindow) { return Create(MAKEINTRESOURCEW(resID), parentWindow); } + #ifndef _UNICODE + INT_PTR Create(LPCWSTR templateName, HWND parentWindow); + #endif + + bool End(INT_PTR result) { return BOOLToBool(::EndDialog(_window, result)); } + virtual void OnOK() Z7_override { End(IDOK); } + virtual void OnContinue() Z7_override { End(IDCONTINUE); } + virtual void OnCancel() Z7_override { End(IDCANCEL); } + virtual void OnClose() Z7_override { End(IDCLOSE); } +}; + +class CDialogChildControl: public NWindows::CWindow +{ + // unsigned m_ID; +public: + void Init(const NWindows::NControl::CDialog &parentDialog, unsigned id) + { + // m_ID = id; + Attach(parentDialog.GetItem(id)); + } +}; + +bool IsDialogSizeOK(int xSize, int ySize, HWND hwnd = NULL); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/DialogImpl.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/DialogImpl.h --- p7zip-rar-16.02/CPP/Windows/Control/DialogImpl.h 2010-04-03 17:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/DialogImpl.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -// Windows/Control/DialogImpl.h - -#ifndef __WINDOWS_CONTROL_DIALOGIMPL_H -#define __WINDOWS_CONTROL_DIALOGIMPL_H - -#include "Windows/Window.h" -#include "Windows/Control/Dialog.h" - -void myCreateHandle(int n); // FIXME - duplicate - -enum { - WORKER_EVENT=100 // this one gets sent from the worker thread -}; - -namespace NWindows { - namespace NControl { - -#define TIMER_ID_IMPL (1234) - - class CModalDialogImpl : public wxDialog - { - wxTimer _timer; - - CDialog *_dialog; - public: - CModalDialogImpl(CDialog *dialog, wxWindow* parent, wxWindowID id, const wxString& title, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxDEFAULT_DIALOG_STYLE ); - - CDialog * Detach() - { - CDialog * oldDialog = _dialog; - _dialog = NULL; - return oldDialog; - } - - void OnInit() - { - if (_dialog) _dialog->OnInit(this); - } - - void OnAnyButton(wxCommandEvent& event); - void OnAnyChoice(wxCommandEvent &event); - void OnAnyTimer(wxTimerEvent &event); - -/* FIXME virtual void SetLabel(const wxString &title) - { - // Why we must do this "alias" ? - this->SetTitle(title); - } -*/ - ////////////////// - UINT_PTR SetTimer(UINT_PTR /* FIXME idEvent */, unsigned milliseconds) - { - _timer.Start(milliseconds); - return TIMER_ID_IMPL; - } - void KillTimer(UINT_PTR idEvent) - { - if (idEvent == TIMER_ID_IMPL) _timer.Stop(); - } - void OnWorkerEvent(wxCommandEvent& event) - { - int n = event.GetInt(); - // printf("CModalDialogImpl::OnWorkerEvent(n=%d)\n",n); - myCreateHandle(n); - } - }; -} -} - -#endif - diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Edit.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Edit.h --- p7zip-rar-16.02/CPP/Windows/Control/Edit.h 2014-12-29 18:13:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Edit.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,25 +1,19 @@ -// Windows/Control/Edit.h - -#ifndef __WINDOWS_CONTROL_EDIT_H -#define __WINDOWS_CONTROL_EDIT_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -namespace NWindows { -namespace NControl { - -class CEdit: public CWindow -{ -public: - void SetPasswordChar(WPARAM c); - void Show(int cmdShow); - void Show_Bool(bool show) { Show(show ? SW_SHOW: SW_HIDE); } - virtual void SetText(LPCWSTR s); - virtual bool GetText(CSysString &s); -}; - -}} - -#endif - +// Windows/Control/Edit.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_EDIT_H +#define ZIP7_INC_WINDOWS_CONTROL_EDIT_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CEdit: public CWindow +{ +public: + void SetPasswordChar(WPARAM c) { SendMsg(EM_SETPASSWORDCHAR, c); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ImageList.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.cpp --- p7zip-rar-16.02/CPP/Windows/Control/ImageList.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.cpp 2014-12-30 18:08:36.000000000 +0000 @@ -0,0 +1,10 @@ +// Windows/Control/ImageList.cpp + +#include "StdAfx.h" + +#include "ImageList.h" + +namespace NWindows { +namespace NControl { + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ImageList.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.h --- p7zip-rar-16.02/CPP/Windows/Control/ImageList.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ImageList.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,87 @@ +// Windows/Control/ImageList.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_IMAGE_LIST_H +#define ZIP7_INC_WINDOWS_CONTROL_IMAGE_LIST_H + +#include + +#include "../Defs.h" + +namespace NWindows { +namespace NControl { + +class CImageList +{ + HIMAGELIST m_Object; +public: + operator HIMAGELIST() const {return m_Object; } + CImageList(): m_Object(NULL) {} + bool Attach(HIMAGELIST imageList) + { + if (imageList == NULL) + return false; + m_Object = imageList; + return true; + } + + HIMAGELIST Detach() + { + HIMAGELIST imageList = m_Object; + m_Object = NULL; + return imageList; + } + + bool Create(int width, int height, UINT flags, int initialNumber, int grow) + { + HIMAGELIST a = ImageList_Create(width, height, flags, + initialNumber, grow); + if (a == NULL) + return false; + return Attach(a); + } + + bool Destroy() // DeleteImageList() in MFC + { + if (m_Object == NULL) + return false; + return BOOLToBool(ImageList_Destroy(Detach())); + } + + ~CImageList() + { Destroy(); } + + int GetImageCount() const + { return ImageList_GetImageCount(m_Object); } + + bool GetImageInfo(int index, IMAGEINFO* imageInfo) const + { return BOOLToBool(ImageList_GetImageInfo(m_Object, index, imageInfo)); } + + int Add(HBITMAP hbmImage, HBITMAP hbmMask = NULL) + { return ImageList_Add(m_Object, hbmImage, hbmMask); } + int AddMasked(HBITMAP hbmImage, COLORREF mask) + { return ImageList_AddMasked(m_Object, hbmImage, mask); } + int AddIcon(HICON icon) + { return ImageList_AddIcon(m_Object, icon); } + int Replace(int index, HICON icon) + { return ImageList_ReplaceIcon(m_Object, index, icon); } + + // If index is -1, the function removes all images. + bool Remove(int index) + { return BOOLToBool(ImageList_Remove(m_Object, index)); } + bool RemoveAll() + { return BOOLToBool(ImageList_RemoveAll(m_Object)); } + + HICON ExtractIcon(int index) + { return ImageList_ExtractIcon(NULL, m_Object, index); } + HICON GetIcon(int index, UINT flags) + { return ImageList_GetIcon(m_Object, index, flags); } + + bool GetIconSize(int &width, int &height) const + { return BOOLToBool(ImageList_GetIconSize(m_Object, &width, &height)); } + bool SetIconSize(int width, int height) + { return BOOLToBool(ImageList_SetIconSize(m_Object, width, height)); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ListView.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.cpp --- p7zip-rar-16.02/CPP/Windows/Control/ListView.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.cpp 2023-03-17 12:00:00.000000000 +0000 @@ -0,0 +1,162 @@ +// Windows/Control/ListView.cpp + +#include "StdAfx.h" + +#include "ListView.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +bool CListView::CreateEx(DWORD exStyle, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) +{ + return CWindow::CreateEx(exStyle, WC_LISTVIEW, TEXT(""), style, x, y, width, + height, parentWindow, idOrHMenu, instance, createParam); +} + +/* note: LVITEM and LVCOLUMN structures contain optional fields + depending from preprocessor macros: + #if (_WIN32_IE >= 0x0300) + #if (_WIN32_WINNT >= 0x0501) + #if (_WIN32_WINNT >= 0x0600) +*/ + +bool CListView::GetItemParam(unsigned index, LPARAM ¶m) const +{ + LVITEM item; + item.iItem = (int)index; + item.iSubItem = 0; + item.mask = LVIF_PARAM; + const bool res = GetItem(&item); + param = item.lParam; + return res; +} + +int CListView::InsertColumn(unsigned columnIndex, LPCTSTR text, int width) +{ + LVCOLUMN ci; + ci.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + ci.pszText = (LPTSTR)(void *)text; + ci.iSubItem = (int)columnIndex; + ci.cx = width; + return InsertColumn(columnIndex, &ci); +} + +int CListView::InsertItem(unsigned index, LPCTSTR text) +{ + LVITEM item; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.iItem = (int)index; + item.lParam = (LPARAM)index; + item.pszText = (LPTSTR)(void *)text; + item.iSubItem = 0; + return InsertItem(&item); +} + +int CListView::SetSubItem(unsigned index, unsigned subIndex, LPCTSTR text) +{ + LVITEM item; + item.mask = LVIF_TEXT; + item.iItem = (int)index; + item.pszText = (LPTSTR)(void *)text; + item.iSubItem = (int)subIndex; + return SetItem(&item); +} + +#ifndef _UNICODE + +int CListView::InsertColumn(unsigned columnIndex, LPCWSTR text, int width) +{ + LVCOLUMNW ci; + ci.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + ci.pszText = (LPWSTR)(void *)text; + ci.iSubItem = (int)columnIndex; + ci.cx = width; + return InsertColumn(columnIndex, &ci); +} + +int CListView::InsertItem(unsigned index, LPCWSTR text) +{ + LVITEMW item; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.iItem = (int)index; + item.lParam = (LPARAM)index; + item.pszText = (LPWSTR)(void *)text; + item.iSubItem = 0; + return InsertItem(&item); +} + +int CListView::SetSubItem(unsigned index, unsigned subIndex, LPCWSTR text) +{ + LVITEMW item; + item.mask = LVIF_TEXT; + item.iItem = (int)index; + item.pszText = (LPWSTR)(void *)text; + item.iSubItem = (int)subIndex; + return SetItem(&item); +} + +#endif + +static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow window(hwnd); + CListView2 *w = (CListView2 *)(window.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CListView2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + +void CListView2::SetWindowProc() +{ + SetUserDataLongPtr((LONG_PTR)this); + #ifndef _UNICODE + if (g_IsNT) + _origWindowProc = (WNDPROC)SetLongPtrW(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc); + else + #endif + _origWindowProc = (WNDPROC)SetLongPtr(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc); +} + +/* +LRESULT CListView3::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT res = CListView2::OnMessage(message, wParam, lParam); + if (message == WM_GETDLGCODE) + { + // when user presses RETURN, windows sends default (first) button command to parent dialog. + // we disable this: + MSG *msg = (MSG *)lParam; + WPARAM key = wParam; + bool change = false; + if (msg) + { + if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN) + change = true; + } + else if (wParam == VK_RETURN) + change = true; + if (change) + res |= DLGC_WANTALLKEYS; + } + return res; +} +*/ + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ListView.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.h --- p7zip-rar-16.02/CPP/Windows/Control/ListView.h 2015-10-06 09:47:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ListView.h 2023-03-17 16:00:00.000000000 +0000 @@ -1,190 +1,156 @@ -// Windows/Control/ListView.h - -#ifndef __WINDOWS_CONTROL_LISTVIEW_H -#define __WINDOWS_CONTROL_LISTVIEW_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -/* -#include -*/ - -#ifndef _WIN32 - -#define LVCF_FMT 0x0001 -#define LVCF_WIDTH 0x0002 -#define LVCF_TEXT 0x0004 -#define LVCF_SUBITEM 0x0008 -#define LVCF_IMAGE 0x0010 -#define LVCF_ORDER 0x0020 - -#define LVCFMT_LEFT 0x0000 -#define LVCFMT_RIGHT 0x0001 -#define LVCFMT_CENTER 0x0002 -#define LVCFMT_JUSTIFYMASK 0x0003 - - -// state -#define LVIS_FOCUSED 0x0002 /* wxLIST_STATE_FOCUSED */ -#define LVIS_SELECTED 0x0004 /* wxLIST_STATE_SELECTED */ - -#define LVNI_SELECTED 0x0004 /* wxLIST_STATE_SELECTED */ - -typedef INT (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); - -typedef struct tagLVCOLUMNW -{ - UINT mask; - int fmt; - int cx; - LPWSTR pszText; - int cchTextMax; - int iSubItem; - // FIXME int iOrder; // not available -} LVCOLUMNW; - -#define LVCOLUMN LVCOLUMNW -#define LV_COLUMNW LVCOLUMNW /* FIXME */ - - - -typedef struct tagLVITEMW -{ - UINT mask; - int iItem; - int iSubItem; - UINT state; - UINT stateMask; - LPWSTR pszText; - int cchTextMax; - int iImage; - LPARAM lParam; -#if (_WIN32_IE >= 0x0300) - int iIndent; -#endif -#if (_WIN32_WINNT >= 0x501) - int iGroupId; - UINT cColumns; // tile view columns - PUINT puColumns; -#endif -} LVITEMW; - -#define LVITEM LVITEMW - -#define LVIF_TEXT 0x0001 -// FIXME - mask -#define LVIF_PARAM 2 -#define LVIF_IMAGE 4 -#define LVIF_STATE 8 - -#endif - -class wxListCtrl; - -namespace NWindows { -namespace NControl { - -class CListView // : public NWindows::CWindow -{ - wxListCtrl *_list; -public: - CListView() : _list(0) {} - void Attach(wxWindow * newWindow); - - operator HWND() const; - - void SetUnicodeFormat() { /* FIXME */ ; } - - - int GetItemCount() const; - - int InsertItem(int index, LPCTSTR text); - int InsertItem(const LVITEM* item); - - void SetItem(const LVITEM* item); - - int SetSubItem(int index, int subIndex, LPCTSTR text); - - void SetUnicodeFormat(bool fUnicode) { return ; } - - void InsertColumn(int columnIndex, LPCTSTR text, int width); - - void InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo); - - void DeleteAllItems(); - - void SetRedraw(bool); - - void SetItemCount(int ); - - void InvalidateRect(void *, bool); - - int GetSelectedCount() const; - - void /* bool */ EnsureVisible(int index, bool partialOK); - - void SetItemState(int index, UINT state, UINT mask); - - void SetItemState_FocusedSelected(int index) { SetItemState(index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } - - void SetItemState_Selected(int index, bool select) { SetItemState(index, select ? LVIS_SELECTED : 0, LVIS_SELECTED); } - void SetItemState_Selected(int index) { SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); } - - UINT GetItemState(int index, UINT mask) const; - - bool IsItemSelected(int index) const { return GetItemState(index, LVIS_SELECTED) == LVIS_SELECTED; } - - void /* bool */ Update(); - - bool DeleteColumn(int columnIndex); - - bool GetItemParam(int itemIndex, LPARAM ¶m) const; - - int GetNextItem(int startIndex, UINT flags) const; - - int GetFocusedItem() const; - - void RedrawAllItems(); - // FIXME added - int GetColumnCount(); - - void SetFocus(); - - void RedrawItem(int item); - - bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam); - - bool GetColumn(int columnIndex, LVCOLUMN* columnInfo); - - // HWND EditLabel(int itemIndex) - void EditLabel(int itemIndex); - - bool SetColumnWidthAuto(int iCol) { - return true; // FIXME SetColumnWidth(iCol, LVSCW_AUTOSIZE); - } - -private: - void _InsertColumn(int columnIndex, LPCTSTR text, int format, int width); - -}; - -class CListView2: public CListView -{ -// FIXME WNDPROC _origWindowProc; -public: - // void SetWindowProc(); - virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); -}; - -/* -class CListView3: public CListView2 -{ -public: - virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); -}; -*/ - -}} -#endif - +// Windows/Control/ListView.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_LISTVIEW_H +#define ZIP7_INC_WINDOWS_CONTROL_LISTVIEW_H + +#include "../../Common/MyWindows.h" + +#include + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CListView: public NWindows::CWindow +{ +public: + bool CreateEx(DWORD exStyle, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam); + + void SetUnicodeFormat() + { + #ifndef UNDER_CE + ListView_SetUnicodeFormat(_window, TRUE); + #endif + } + + bool DeleteAllItems() { return BOOLToBool(ListView_DeleteAllItems(_window)); } + bool DeleteColumn(unsigned columnIndex) { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); } + + int InsertColumn(unsigned columnIndex, const LVCOLUMN *columnInfo) { return ListView_InsertColumn(_window, columnIndex, columnInfo); } + int InsertColumn(unsigned columnIndex, LPCTSTR text, int width); + bool SetColumnOrderArray(unsigned count, const int *columns) + { return BOOLToBool(ListView_SetColumnOrderArray(_window, count, (int *)(void *)columns)); } + + /* + int GetNumColumns() + { + HWND header = ListView_GetHeader(_window); + if (!header) + return -1; + return Header_GetItemCount(header); + } + */ + + int InsertItem(const LVITEM* item) { return ListView_InsertItem(_window, item); } + int InsertItem(unsigned index, LPCTSTR text); + bool SetItem(const LVITEM* item) { return BOOLToBool(ListView_SetItem(_window, item)); } + int SetSubItem(unsigned index, unsigned subIndex, LPCTSTR text); + + #ifndef _UNICODE + + int InsertColumn(unsigned columnIndex, const LVCOLUMNW *columnInfo) { return (int)SendMsg(LVM_INSERTCOLUMNW, (WPARAM)columnIndex, (LPARAM)columnInfo); } + int InsertColumn(unsigned columnIndex, LPCWSTR text, int width); + int InsertItem(const LV_ITEMW* item) { return (int)SendMsg(LVM_INSERTITEMW, 0, (LPARAM)item); } + int InsertItem(unsigned index, LPCWSTR text); + bool SetItem(const LV_ITEMW* item) { return BOOLToBool((BOOL)SendMsg(LVM_SETITEMW, 0, (LPARAM)item)); } + int SetSubItem(unsigned index, unsigned subIndex, LPCWSTR text); + + #endif + + bool DeleteItem(unsigned itemIndex) { return BOOLToBool(ListView_DeleteItem(_window, itemIndex)); } + + UINT GetSelectedCount() const { return ListView_GetSelectedCount(_window); } + int GetItemCount() const { return ListView_GetItemCount(_window); } + + INT GetSelectionMark() const { return ListView_GetSelectionMark(_window); } + + void SetItemCount(unsigned numItems) { ListView_SetItemCount(_window, numItems); } + void SetItemCountEx(unsigned numItems, DWORD flags) { ListView_SetItemCountEx(_window, numItems, flags); } + + /* startIndex : The index of the item with which to begin the search, + or -1 to find the first item that matches the specified flags. + The specified item itself is excluded from the search. */ + int GetNextItem(int startIndex, UINT flags) const { return ListView_GetNextItem(_window, startIndex, flags); } + int GetNextSelectedItem(int startIndex) const { return GetNextItem(startIndex, LVNI_SELECTED); } + int GetFocusedItem() const { return GetNextItem(-1, LVNI_FOCUSED); } + + bool GetItem(LVITEM* item) const { return BOOLToBool(ListView_GetItem(_window, item)); } + bool GetItemParam(unsigned itemIndex, LPARAM ¶m) const; + /* + void GetItemText(unsigned itemIndex, unsigned subItemIndex, LPTSTR text, unsigned textSizeMax) const + { ListView_GetItemText(_window, itemIndex, subItemIndex, text, textSizeMax) } + */ + bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam) + { return BOOLToBool(ListView_SortItems(_window, compareFunction, dataParam)); } + + // If (index == -1), then the state change is applied to all items. + void SetItemState(int index, UINT state, UINT mask) { ListView_SetItemState(_window, index, state, mask) } + void SetItemState_Selected(int index, bool select) { SetItemState(index, select ? LVIS_SELECTED : 0, LVIS_SELECTED); } + void SetItemState_Selected(int index) { SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); } + void SelectAll() { SetItemState_Selected(-1); } + void SetItemState_FocusedSelected(int index) { SetItemState(index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } + UINT GetItemState(int index, UINT mask) const { return ListView_GetItemState(_window, index, mask); } + bool IsItemSelected(int index) const { return GetItemState(index, LVIS_SELECTED) == LVIS_SELECTED; } + + bool GetColumn(unsigned columnIndex, LVCOLUMN* columnInfo) const + { return BOOLToBool(ListView_GetColumn(_window, columnIndex, columnInfo)); } + + HIMAGELIST SetImageList(HIMAGELIST imageList, int imageListType) + { return ListView_SetImageList(_window, imageList, imageListType); } + + // version 4.70: NT5 | (NT4 + ie3) | w98 | (w95 + ie3) + DWORD GetExtendedListViewStyle() { return ListView_GetExtendedListViewStyle(_window); } + void SetExtendedListViewStyle(DWORD exStyle) { ListView_SetExtendedListViewStyle(_window, exStyle); } + void SetExtendedListViewStyle(DWORD exMask, DWORD exStyle) { ListView_SetExtendedListViewStyleEx(_window, exMask, exStyle); } + + void SetCheckState(UINT index, bool checkState) { ListView_SetCheckState(_window, index, BoolToBOOL(checkState)) } + bool GetCheckState(UINT index) { return BOOLToBool(ListView_GetCheckState(_window, index)); } + + bool EnsureVisible(int index, bool partialOK) { return BOOLToBool(ListView_EnsureVisible(_window, index, BoolToBOOL(partialOK))); } + + bool GetItemRect(int index, RECT *rect, int code) { return BOOLToBool(ListView_GetItemRect(_window, index, rect, code)); } + + HWND GetEditControl() { return ListView_GetEditControl(_window) ; } + HWND EditLabel(int itemIndex) { return ListView_EditLabel(_window, itemIndex) ; } + + bool RedrawItems(int firstIndex, int lastIndex) { return BOOLToBool(ListView_RedrawItems(_window, firstIndex, lastIndex)); } + bool RedrawAllItems() + { + if (GetItemCount() > 0) + return RedrawItems(0, GetItemCount() - 1); + return true; + } + bool RedrawItem(int index) { return RedrawItems(index, index); } + + int HitTest(LPLVHITTESTINFO info) { return ListView_HitTest(_window, info); } + COLORREF GetBkColor() { return ListView_GetBkColor(_window); } + bool SetColumnWidth(int iCol, int cx) { return BOOLToBool(ListView_SetColumnWidth(_window, iCol, cx)); } + bool SetColumnWidthAuto(int iCol) { return SetColumnWidth(iCol, LVSCW_AUTOSIZE); } +}; + +class CListView2: public CListView +{ + WNDPROC _origWindowProc; + // ~CListView2() ZIP7_eq_delete; +public: + virtual ~CListView2() {} + CListView2() {} + void SetWindowProc(); + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +/* +class CListView3: public CListView2 +{ +public: + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; +*/ + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ProgressBar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ProgressBar.h --- p7zip-rar-16.02/CPP/Windows/Control/ProgressBar.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ProgressBar.h 2023-01-19 20:00:00.000000000 +0000 @@ -1,34 +1,35 @@ -// Windows/Control/ProgressBar.h - -#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H -#define __WINDOWS_CONTROL_PROGRESSBAR_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -class wxGauge; - -namespace NWindows { -namespace NControl { - - -class CProgressBar : public CWindow -{ -protected: - wxGauge* _window; - int _minValue; - int _range; -public: - CProgressBar(wxWindow* newWindow = NULL); - - void Attach(wxWindow* newWindow); - - void SetRange32(int minValue, int maxValue); - - void SetPos(int pos); -}; - -}} - -#endif - +// Windows/Control/ProgressBar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_PROGRESSBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_PROGRESSBAR_H + +#include "../../Common/MyWindows.h" + +#include + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CProgressBar: public CWindow +{ +public: + LRESULT SetPos(int pos) { return SendMsg(PBM_SETPOS, (unsigned)pos, 0); } + // LRESULT DeltaPos(int increment) { return SendMsg(PBM_DELTAPOS, increment, 0); } + // UINT GetPos() { return (UINT)SendMsg(PBM_GETPOS, 0, 0); } + // LRESULT SetRange(unsigned short minValue, unsigned short maxValue) { return SendMsg(PBM_SETRANGE, 0, MAKELPARAM(minValue, maxValue)); } + DWORD SetRange32(int minValue, int maxValue) { return (DWORD)SendMsg(PBM_SETRANGE32, (unsigned)minValue, (LPARAM)(unsigned)maxValue); } + // int SetStep(int step) { return (int)SendMsg(PBM_SETSTEP, step, 0); } + // LRESULT StepIt() { return SendMsg(PBM_STEPIT, 0, 0); } + // INT GetRange(bool minValue, PPBRANGE range) { return (INT)SendMsg(PBM_GETRANGE, BoolToBOOL(minValue), (LPARAM)range); } + + #ifndef UNDER_CE + COLORREF SetBarColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBARCOLOR, 0, (LPARAM)color); } + COLORREF SetBackgroundColor(COLORREF color) { return (COLORREF)SendMsg(PBM_SETBKCOLOR, 0, (LPARAM)color); } + #endif +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/PropertyPage.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.cpp --- p7zip-rar-16.02/CPP/Windows/Control/PropertyPage.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.cpp 2023-09-26 17:00:00.000000000 +0000 @@ -0,0 +1,165 @@ +// Windows/Control/PropertyPage.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../../Common/StringConvert.h" +#endif + +#include "PropertyPage.h" + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NControl { + +static +#ifdef Z7_OLD_WIN_SDK + BOOL +#else + INT_PTR +#endif +APIENTRY MyProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(dialogHWND); + if (message == WM_INITDIALOG) + tempDialog.SetUserDataLongPtr(((PROPSHEETPAGE *)lParam)->lParam); + CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr()); + if (dialog == NULL) + return FALSE; + if (message == WM_INITDIALOG) + dialog->Attach(dialogHWND); + try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); } + catch(...) { return TRUE; } +} + +bool CPropertyPage::OnNotify(UINT /* controlID */, LPNMHDR lParam) +{ + switch (lParam->code) + { + case PSN_APPLY: SetMsgResult(OnApply2(LPPSHNOTIFY(lParam))); break; + case PSN_KILLACTIVE: SetMsgResult(BoolToBOOL(OnKillActive2(LPPSHNOTIFY(lParam)))); break; + case PSN_SETACTIVE: SetMsgResult(OnSetActive2(LPPSHNOTIFY(lParam))); break; + case PSN_RESET: OnReset2(LPPSHNOTIFY(lParam)); break; + case PSN_HELP: OnNotifyHelp2(LPPSHNOTIFY(lParam)); break; + default: return false; + } + return true; +} + +/* +PROPSHEETPAGE fields depend from +#if (_WIN32_WINNT >= 0x0600) +#elif (_WIN32_WINNT >= 0x0501) +#elif (_WIN32_IE >= 0x0400) +PROPSHEETHEADER fields depend from +#if (_WIN32_IE >= 0x0400) +*/ +#if defined(PROPSHEETPAGEA_V1_SIZE) && !defined(Z7_OLD_WIN_SDK) +#ifndef _UNICODE +#define my_compatib_PROPSHEETPAGEA PROPSHEETPAGEA_V1 +#endif +#define my_compatib_PROPSHEETPAGEW PROPSHEETPAGEW_V1 +#else +// for old mingw: +#ifndef _UNICODE +#define my_compatib_PROPSHEETPAGEA PROPSHEETPAGEA +#endif +#define my_compatib_PROPSHEETPAGEW PROPSHEETPAGEW +#endif + +INT_PTR MyPropertySheet(const CObjectVector &pagesInfo, HWND hwndParent, const UString &title) +{ + unsigned i; + #ifndef _UNICODE + AStringVector titles; + for (i = 0; i < pagesInfo.Size(); i++) + titles.Add(GetSystemString(pagesInfo[i].Title)); + CRecordVector pagesA; + #endif + CRecordVector pagesW; + + for (i = 0; i < pagesInfo.Size(); i++) + { + const CPageInfo &pageInfo = pagesInfo[i]; + #ifndef _UNICODE + { + my_compatib_PROPSHEETPAGEA page; + memset(&page, 0, sizeof(page)); + page.dwSize = sizeof(page); + page.dwFlags = PSP_HASHELP; + page.hInstance = g_hInstance; + page.pszTemplate = MAKEINTRESOURCEA(pageInfo.ID); + // page.pszIcon = NULL; + page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure; + + if (!titles[i].IsEmpty()) + { + page.pszTitle = titles[i]; + page.dwFlags |= PSP_USETITLE; + } + // else page.pszTitle = NULL; + page.lParam = (LPARAM)pageInfo.Page; + // page.pfnCallback = NULL; + pagesA.Add(page); + } + #endif + { + my_compatib_PROPSHEETPAGEW page; + memset(&page, 0, sizeof(page)); + page.dwSize = sizeof(page); + page.dwFlags = PSP_HASHELP; + page.hInstance = g_hInstance; + page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID); + // page.pszIcon = NULL; + page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure; + + if (!pageInfo.Title.IsEmpty()) + { + page.pszTitle = pageInfo.Title; + page.dwFlags |= PSP_USETITLE; + } + // else page.pszTitle = NULL; + page.lParam = (LPARAM)pageInfo.Page; + // page.pfnCallback = NULL; + pagesW.Add(page); + } + } + + #ifndef _UNICODE + if (!g_IsNT) + { + PROPSHEETHEADERA sheet; + sheet.dwSize = sizeof(sheet); + sheet.dwFlags = PSH_PROPSHEETPAGE; + sheet.hwndParent = hwndParent; + sheet.hInstance = g_hInstance; + AString titleA (GetSystemString(title)); + sheet.pszCaption = titleA; + sheet.nPages = pagesA.Size(); + sheet.nStartPage = 0; + sheet.ppsp = (LPCPROPSHEETPAGEA)(const void *)pagesA.ConstData(); + sheet.pfnCallback = NULL; + return ::PropertySheetA(&sheet); + } + else + #endif + { + PROPSHEETHEADERW sheet; + sheet.dwSize = sizeof(sheet); + sheet.dwFlags = PSH_PROPSHEETPAGE; + sheet.hwndParent = hwndParent; + sheet.hInstance = g_hInstance; + sheet.pszCaption = title; + sheet.nPages = pagesW.Size(); + sheet.nStartPage = 0; + sheet.ppsp = (LPCPROPSHEETPAGEW)(const void *)pagesW.ConstData(); + sheet.pfnCallback = NULL; + return ::PropertySheetW(&sheet); + } +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/PropertyPage.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.h --- p7zip-rar-16.02/CPP/Windows/Control/PropertyPage.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/PropertyPage.h 2023-03-17 15:00:00.000000000 +0000 @@ -0,0 +1,50 @@ +// Windows/Control/PropertyPage.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_PROPERTYPAGE_H +#define ZIP7_INC_WINDOWS_CONTROL_PROPERTYPAGE_H + +#include "../../Common/MyWindows.h" + +#include + +#include "Dialog.h" + +namespace NWindows { +namespace NControl { + +INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam); + +class CPropertyPage: public CDialog +{ +public: + CPropertyPage(HWND window = NULL): CDialog(window) {} + + void Changed() { PropSheet_Changed(GetParent(), (HWND)*this); } + void UnChanged() { PropSheet_UnChanged(GetParent(), (HWND)*this); } + + virtual bool OnNotify(UINT controlID, LPNMHDR lParam) Z7_override; + + virtual bool OnKillActive() { return false; } // false = OK + virtual bool OnKillActive2(const PSHNOTIFY *) { return OnKillActive(); } + virtual LONG OnSetActive() { return false; } // false = OK + virtual LONG OnSetActive2(const PSHNOTIFY *) { return OnSetActive(); } + virtual LONG OnApply() { return PSNRET_NOERROR; } + virtual LONG OnApply2(const PSHNOTIFY *) { return OnApply(); } + virtual void OnNotifyHelp() {} + virtual void OnNotifyHelp2(const PSHNOTIFY *) { OnNotifyHelp(); } + virtual void OnReset() {} + virtual void OnReset2(const PSHNOTIFY *) { OnReset(); } +}; + +struct CPageInfo +{ + CPropertyPage *Page; + UString Title; + UINT ID; +}; + +INT_PTR MyPropertySheet(const CObjectVector &pagesInfo, HWND hwndParent, const UString &title); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ReBar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ReBar.h --- p7zip-rar-16.02/CPP/Windows/Control/ReBar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ReBar.h 2023-01-19 15:00:00.000000000 +0000 @@ -0,0 +1,34 @@ +// Windows/Control/ReBar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_REBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_REBAR_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CReBar: public NWindows::CWindow +{ +public: + bool SetBarInfo(LPREBARINFO barInfo) + { return LRESULTToBool(SendMsg(RB_SETBARINFO, 0, (LPARAM)barInfo)); } + bool InsertBand(int index, LPREBARBANDINFO bandInfo) + { return LRESULTToBool(SendMsg(RB_INSERTBAND, MY_int_TO_WPARAM(index), (LPARAM)bandInfo)); } + bool SetBandInfo(unsigned index, LPREBARBANDINFO bandInfo) + { return LRESULTToBool(SendMsg(RB_SETBANDINFO, index, (LPARAM)bandInfo)); } + void MaximizeBand(unsigned index, bool ideal) + { SendMsg(RB_MAXIMIZEBAND, index, BoolToBOOL(ideal)); } + bool SizeToRect(LPRECT rect) + { return LRESULTToBool(SendMsg(RB_SIZETORECT, 0, (LPARAM)rect)); } + UINT GetHeight() + { return (UINT)SendMsg(RB_GETBARHEIGHT); } + UINT GetBandCount() + { return (UINT)SendMsg(RB_GETBANDCOUNT); } + bool DeleteBand(UINT index) + { return LRESULTToBool(SendMsg(RB_DELETEBAND, index)); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Static.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Static.h --- p7zip-rar-16.02/CPP/Windows/Control/Static.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Static.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,23 +1,28 @@ -// Windows/Control/Static.h - -#ifndef __WINDOWS_CONTROL_STATIC_H -#define __WINDOWS_CONTROL_STATIC_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -typedef void * HICON; - -namespace NWindows { -namespace NControl { - -class CStatic : public CWindow -{ -public: - - HICON SetIcon(HICON icon) { return 0; } // FIXME -}; - -}} - -#endif +// Windows/Control/Static.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_STATIC_H +#define ZIP7_INC_WINDOWS_CONTROL_STATIC_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CStatic: public CWindow +{ +public: + HANDLE SetImage(WPARAM imageType, HANDLE handle) { return (HANDLE)SendMsg(STM_SETIMAGE, imageType, (LPARAM)handle); } + HANDLE GetImage(WPARAM imageType) { return (HANDLE)SendMsg(STM_GETIMAGE, imageType, 0); } + + #ifdef UNDER_CE + HICON SetIcon(HICON icon) { return (HICON)SetImage(IMAGE_ICON, icon); } + HICON GetIcon() { return (HICON)GetImage(IMAGE_ICON); } + #else + HICON SetIcon(HICON icon) { return (HICON)SendMsg(STM_SETICON, (WPARAM)icon, 0); } + HICON GetIcon() { return (HICON)SendMsg(STM_GETICON, 0, 0); } + #endif +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/StatusBar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StatusBar.h --- p7zip-rar-16.02/CPP/Windows/Control/StatusBar.h 2008-08-13 11:45:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StatusBar.h 2023-01-19 15:00:00.000000000 +0000 @@ -1,56 +1,42 @@ -// Windows/Control/StatusBar.h - -#ifndef __WINDOWS_CONTROL_STATUSBAR_H -#define __WINDOWS_CONTROL_STATUSBAR_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -class wxStatusBar; - -namespace NWindows { -namespace NControl { - -class CStatusBar // : public NWindows::CWindow -{ - wxStatusBar * _statusBar; -public: - CStatusBar() : _statusBar(0) {} - - void Attach(wxWindow * newWindow); - wxWindow * Detach(); - - void SetText(int index, LPCTSTR text); - -/* FIXME - bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id) - { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != 0; } - bool SetParts(int numParts, const int *edgePostions) - { return LRESULTToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); } - bool SetText(LPCTSTR text) - { return CWindow::SetText(text); } - - bool SetText(int index, LPCTSTR text, UINT type) - { return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); } - bool SetText(int index, LPCTSTR text) - { return SetText(index, text, 0); } - void Simple(bool simple) - { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); } - - #ifndef _UNICODE - bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id) - { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != 0; } - bool SetText(LPCWSTR text) - { return CWindow::SetText(text); } - bool SetText(int index, LPCWSTR text, UINT type) - { return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); } - bool SetText(int index, LPCWSTR text) - { return SetText(index, text, 0); } - #endif -*/ -}; - -}} - -#endif - +// Windows/Control/StatusBar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_STATUSBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_STATUSBAR_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CStatusBar: public NWindows::CWindow +{ +public: + bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id) + { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != NULL; } + bool SetText(LPCTSTR text) + { return CWindow::SetText(text); } + bool SetText(unsigned index, LPCTSTR text, UINT type) + { return LRESULTToBool(SendMsg(SB_SETTEXT, index | type, (LPARAM)text)); } + bool SetText(unsigned index, LPCTSTR text) + { return SetText(index, text, 0); } + + #ifndef _UNICODE + bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id) + { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != NULL; } + bool SetText(LPCWSTR text) + { return CWindow::SetText(text); } + bool SetText(unsigned index, LPCWSTR text, UINT type) + { return LRESULTToBool(SendMsg(SB_SETTEXTW, index | type, (LPARAM)text)); } + bool SetText(unsigned index, LPCWSTR text) + { return SetText(index, text, 0); } + #endif + + bool SetParts(unsigned numParts, const int *edgePostions) + { return LRESULTToBool(SendMsg(SB_SETPARTS, numParts, (LPARAM)edgePostions)); } + void Simple(bool simple) + { SendMsg(SB_SIMPLE, (WPARAM)BoolToBOOL(simple), 0); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StdAfx.h --- p7zip-rar-16.02/CPP/Windows/Control/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/StdAfx.h 2023-01-14 11:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/ToolBar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ToolBar.h --- p7zip-rar-16.02/CPP/Windows/Control/ToolBar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/ToolBar.h 2023-03-17 12:00:00.000000000 +0000 @@ -0,0 +1,43 @@ +// Windows/Control/ToolBar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_TOOLBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_TOOLBAR_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CToolBar: public NWindows::CWindow +{ +public: + void AutoSize() { SendMsg(TB_AUTOSIZE, 0, 0); } + DWORD GetButtonSize() { return (DWORD)SendMsg(TB_GETBUTTONSIZE, 0, 0); } + + bool GetMaxSize(LPSIZE size) + #ifdef UNDER_CE + { + // maybe it must be fixed for more than 1 buttons + const DWORD val = GetButtonSize(); + size->cx = LOWORD(val); + size->cy = HIWORD(val); + return true; + } + #else + { + return LRESULTToBool(SendMsg(TB_GETMAXSIZE, 0, (LPARAM)size)); + } + #endif + + bool EnableButton(UINT buttonID, bool enable) { return LRESULTToBool(SendMsg(TB_ENABLEBUTTON, buttonID, MAKELONG(BoolToBOOL(enable), 0))); } + void ButtonStructSize() { SendMsg(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON)); } + HIMAGELIST SetImageList(UINT listIndex, HIMAGELIST imageList) { return HIMAGELIST(SendMsg(TB_SETIMAGELIST, listIndex, (LPARAM)imageList)); } + bool AddButton(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONS, numButtons, (LPARAM)buttons)); } + #ifndef _UNICODE + bool AddButtonW(UINT numButtons, LPTBBUTTON buttons) { return LRESULTToBool(SendMsg(TB_ADDBUTTONSW, numButtons, (LPARAM)buttons)); } + #endif +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Trackbar.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Trackbar.h --- p7zip-rar-16.02/CPP/Windows/Control/Trackbar.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Trackbar.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,27 @@ +// Windows/Control/Trackbar.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_TRACKBAR_H +#define ZIP7_INC_WINDOWS_CONTROL_TRACKBAR_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CTrackbar: public CWindow +{ +public: + void SetRange(int minimum, int maximum, bool redraw = true) + { SendMsg(TBM_SETRANGE, BoolToBOOL(redraw), MAKELONG(minimum, maximum)); } + void SetPos(int pos, bool redraw = true) + { SendMsg(TBM_SETPOS, BoolToBOOL(redraw), pos); } + void SetTicFreq(int freq) + { SendMsg(TBM_SETTICFREQ, freq); } + + int GetPos() + { return (int)SendMsg(TBM_GETPOS); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Window2.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.cpp --- p7zip-rar-16.02/CPP/Windows/Control/Window2.cpp 2008-08-15 12:32:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.cpp 2023-03-17 09:00:00.000000000 +0000 @@ -1,211 +1,202 @@ -// Windows/Control/Window2.cpp - -#include "StdAfx.h" - -#ifndef _UNICODE -#include "Common/StringConvert.h" -#endif -#include "Windows/Control/Window2.h" - -// extern HINSTANCE g_hInstance; -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -namespace NWindows { - -#ifndef _UNICODE -ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); -#endif - -namespace NControl { - -#ifdef _WIN32 -static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, - WPARAM wParam, LPARAM lParam) -{ - CWindow tempWindow(aHWND); - if (message == WM_NCCREATE) - tempWindow.SetUserDataLongPtr( - LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams)); - CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr()); - if (window != NULL && message == WM_NCCREATE) - window->Attach(aHWND); - if (window == 0) - { - #ifndef _UNICODE - if (g_IsNT) - return DefWindowProcW(aHWND, message, wParam, lParam); - else - #endif - return DefWindowProc(aHWND, message, wParam, lParam); - } - return window->OnMessage(message, wParam, lParam); -} - -bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className, - LPCTSTR windowName, DWORD style, - int x, int y, int width, int height, - HWND parentWindow, HMENU idOrHMenu, - HINSTANCE instance) -{ - WNDCLASS windowClass; - if(!::GetClassInfo(instance, className, &windowClass)) - { - // windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.style = 0; - - windowClass.lpfnWndProc = WindowProcedure; - windowClass.cbClsExtra = NULL; - windowClass.cbWndExtra = NULL; - windowClass.hInstance = instance; - windowClass.hIcon = NULL; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - windowClass.lpszMenuName = NULL; - windowClass.lpszClassName = className; - if (::RegisterClass(&windowClass) == 0) - return false; - } - return CWindow::CreateEx(exStyle, className, windowName, - style, x, y, width, height, parentWindow, - idOrHMenu, instance, this); -} - -#ifndef _UNICODE - -bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className, - LPCWSTR windowName, DWORD style, - int x, int y, int width, int height, - HWND parentWindow, HMENU idOrHMenu, - HINSTANCE instance) -{ - bool needRegister; - if(g_IsNT) - { - WNDCLASSW windowClass; - needRegister = ::GetClassInfoW(instance, className, &windowClass) == 0; - } - else - { - WNDCLASSA windowClassA; - AString classNameA; - LPCSTR classNameP; - if (IS_INTRESOURCE(className)) - classNameP = (LPCSTR)className; - else - { - classNameA = GetSystemString(className); - classNameP = classNameA; - } - needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0; - } - if (needRegister) - { - WNDCLASSW windowClass; - // windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.style = 0; - windowClass.lpfnWndProc = WindowProcedure; - windowClass.cbClsExtra = NULL; - windowClass.cbWndExtra = NULL; - windowClass.hInstance = instance; - windowClass.hIcon = NULL; - windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); - windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - windowClass.lpszMenuName = NULL; - windowClass.lpszClassName = className; - if (MyRegisterClass(&windowClass) == 0) - return false; - } - return CWindow::CreateEx(exStyle, className, windowName, - style, x, y, width, height, parentWindow, - idOrHMenu, instance, this); - -} -#endif - -LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - #ifndef _UNICODE - if (g_IsNT) - return DefWindowProcW(_window, message, wParam, lParam); - else - #endif - return DefWindowProc(_window, message, wParam, lParam); -} -#endif - -LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) -{ - LRESULT result; - switch (message) - { - case WM_CREATE: - if (!OnCreate((CREATESTRUCT *)lParam)) - return -1; - break; - case WM_COMMAND: - if (OnCommand(wParam, lParam, result)) - return result; - break; - case WM_NOTIFY: - if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result)) - return result; - break; - case WM_DESTROY: - OnDestroy(); - break; - case WM_CLOSE: - OnClose(); - return 0; -#ifdef _WIN32 - case WM_SIZE: - if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam))) - return 0; -#endif - } -#ifdef _WIN32 - return DefProc(message, wParam, lParam); -#else - return 0; -#endif -} - -bool CWindow2::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result) -{ - return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result); -} - -bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */, LRESULT & /* result */) -{ - return false; - // return DefProc(message, wParam, lParam); - /* - if (code == BN_CLICKED) - return OnButtonClicked(itemID, (HWND)lParam); - */ -} - -/* -bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND) -{ - switch(aButtonID) - { - case IDOK: - OnOK(); - break; - case IDCANCEL: - OnCancel(); - break; - case IDHELP: - OnHelp(); - break; - default: - return false; - } - return true; -} - -*/ - -}} +// Windows/Control/Window2.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../../Common/StringConvert.h" +#endif + +#include "Window2.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); +#endif + +namespace NControl { + +#ifdef UNDER_CE +#define MY_START_WM_CREATE WM_CREATE +#else +#define MY_START_WM_CREATE WM_NCCREATE +#endif + +static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempWindow(aHWND); + if (message == MY_START_WM_CREATE) + tempWindow.SetUserDataLongPtr((LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams)); + CWindow2 *window = (CWindow2 *)(tempWindow.GetUserDataLongPtr()); + if (window && message == MY_START_WM_CREATE) + window->Attach(aHWND); + if (!window) + { + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(aHWND, message, wParam, lParam); + else + #endif + return DefWindowProc(aHWND, message, wParam, lParam); + } + return window->OnMessage(message, wParam, lParam); +} + +bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className, LPCTSTR windowName, + DWORD style, int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance) +{ + WNDCLASS wc; + if (!::GetClassInfo(instance, className, &wc)) + { + // wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = 0; + wc.lpfnWndProc = WindowProcedure; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = instance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = className; + if (::RegisterClass(&wc) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, style, + x, y, width, height, parentWindow, idOrHMenu, instance, this); +} + +#ifndef _UNICODE + +bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className, LPCWSTR windowName, + DWORD style, int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance) +{ + bool needRegister; + if (g_IsNT) + { + WNDCLASSW wc; + needRegister = ::GetClassInfoW(instance, className, &wc) == 0; + } + else + { + WNDCLASSA windowClassA; + AString classNameA; + LPCSTR classNameP; + if (IS_INTRESOURCE(className)) + classNameP = (LPCSTR)className; + else + { + classNameA = GetSystemString(className); + classNameP = classNameA; + } + needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0; + } + if (needRegister) + { + WNDCLASSW wc; + // wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = 0; + wc.lpfnWndProc = WindowProcedure; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = instance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = className; + if (MyRegisterClass(&wc) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, style, + x, y, width, height, parentWindow, idOrHMenu, instance, this); +} + +#endif + +LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(_window, message, wParam, lParam); + else + #endif + return DefWindowProc(_window, message, wParam, lParam); +} + +LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; + switch (message) + { + case WM_CREATE: + if (!OnCreate((CREATESTRUCT *)lParam)) + return -1; + break; + case WM_COMMAND: + if (OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result)) + return result; + break; + case WM_NOTIFY: + if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result)) + return result; + break; + case WM_DESTROY: + OnDestroy(); + break; + case WM_CLOSE: + OnClose(); + return 0; + case WM_SIZE: + if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam))) + return 0; + } + return DefProc(message, wParam, lParam); +} + +/* +bool CWindow2::OnCommand2(WPARAM wParam, LPARAM lParam, LRESULT &result) +{ + return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result); +} +*/ + +bool CWindow2::OnCommand(unsigned /* code */, unsigned /* itemID */, LPARAM /* lParam */, LRESULT & /* result */) +{ + return false; + // return DefProc(message, wParam, lParam); + /* + if (code == BN_CLICKED) + return OnButtonClicked(itemID, (HWND)lParam); + */ +} + +/* +bool CDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDOK: + OnOK(); + break; + case IDCANCEL: + OnCancel(); + break; + case IDHELP: + OnHelp(); + break; + default: + return false; + } + return true; +} + +*/ + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Control/Window2.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.h --- p7zip-rar-16.02/CPP/Windows/Control/Window2.h 2015-01-02 20:15:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Control/Window2.h 2023-03-17 10:00:00.000000000 +0000 @@ -1,73 +1,53 @@ -// Windows/Control/Window2.h - -#ifndef __WINDOWS_CONTROL_WINDOW2_H -#define __WINDOWS_CONTROL_WINDOW2_H - -#include "Windows/Window.h" -#include "Windows/Defs.h" - -namespace NWindows { -namespace NControl { - -class CWindow2 // : public CWindow -{ - // LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam); - HWND _window; -public: - CWindow2(HWND newWindow = NULL): _window(newWindow){}; - CWindow2& operator=(HWND newWindow) - { - _window = newWindow; - return *this; - } - - virtual ~CWindow2() {} - - operator HWND() const { return 0; } // FIXME { return _window; } - - -#ifdef _WIN32 - bool CreateEx(DWORD exStyle, LPCTSTR className, - LPCTSTR windowName, DWORD style, - int x, int y, int width, int height, - HWND parentWindow, HMENU idOrHMenu, - HINSTANCE instance); - - #ifndef _UNICODE - bool CreateEx(DWORD exStyle, LPCWSTR className, - LPCWSTR windowName, DWORD style, - int x, int y, int width, int height, - HWND parentWindow, HMENU idOrHMenu, - HINSTANCE instance); - #endif -#endif - - virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); - virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; } - // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); - virtual bool OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result); - virtual bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result); - virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; } - virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */, LRESULT & /* result */) { return false; } - virtual void OnDestroy() { /* FIXME PostQuitMessage(0); */ } - virtual void OnClose() { /* FIXME Destroy(); */ } - /* - virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); }; - virtual LRESULT OnHelp() {}; - virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); - virtual void OnOK() {}; - virtual void OnCancel() {}; - */ - -#ifdef _WIN32 - LONG_PTR SetMsgResult(LONG_PTR newLongPtr ) - { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); } - LONG_PTR GetMsgResult() const - { return GetLongPtr(DWLP_MSGRESULT); } -#endif -}; - -}} - -#endif - +// Windows/Control/Window2.h + +#ifndef ZIP7_INC_WINDOWS_CONTROL_WINDOW2_H +#define ZIP7_INC_WINDOWS_CONTROL_WINDOW2_H + +#include "../Window.h" + +namespace NWindows { +namespace NControl { + +class CWindow2: public CWindow +{ + // Z7_CLASS_NO_COPY(CWindow2) + + LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam); +public: + CWindow2(HWND newWindow = NULL): CWindow(newWindow) {} + virtual ~CWindow2() {} + + bool CreateEx(DWORD exStyle, LPCTSTR className, LPCTSTR windowName, + DWORD style, int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance); + + #ifndef _UNICODE + bool CreateEx(DWORD exStyle, LPCWSTR className, LPCWSTR windowName, + DWORD style, int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, HINSTANCE instance); + #endif + + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; } + // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); + // bool OnCommand2(WPARAM wParam, LPARAM lParam, LRESULT &result); + virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam, LRESULT &result); + virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; } + virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */, LRESULT & /* result */) { return false; } + virtual void OnDestroy() { PostQuitMessage(0); } + virtual void OnClose() { Destroy(); } + /* + virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); } + virtual LRESULT OnHelp() {}; + virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND); + virtual void OnOK() {}; + virtual void OnCancel() {}; + */ + + LONG_PTR SetMsgResult(LONG_PTR newLongPtr) { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); } + LONG_PTR GetMsgResult() const { return GetLongPtr(DWLP_MSGRESULT); } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/DLL.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.cpp --- p7zip-rar-16.02/CPP/Windows/DLL.cpp 2015-10-10 12:26:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.cpp 2024-01-26 16:00:00.000000000 +0000 @@ -1,185 +1,178 @@ -// Windows/DLL.cpp - -#include "StdAfx.h" - -#ifdef __APPLE_CC__ -#include -#elif ENV_BEOS -#include -#include -#else -#define UINT64 DLL_UINT64 // HP-UX , dlfcn.h defines UINT64 but p7zip also defines UINT64 -#include // dlopen ... -#undef UINT64 -#endif - -#include "DLL.h" -#include "Defs.h" -#ifdef _UNICODE -#include "../Common/StringConvert.h" -#endif - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" - -// #define TRACEN(u) u; -#define TRACEN(u) /* */ - -namespace NWindows { -namespace NDLL { - -bool CLibrary::Free() -{ -TRACEN((printf("CLibrary::Free(this=%p,%p)\n",(void *)this,(void *)_module))) - if (_module == 0) - return true; - -#ifdef __APPLE_CC__ - int ret = NSUnLinkModule ((NSModule)_module, 0); -#elif ENV_BEOS - int ret = unload_add_on((image_id)_module); -#else - int ret = dlclose(_module); -#endif -TRACEN((printf("CLibrary::Free dlclose(%p)=%d\n",(void *)_module,ret))) - if (ret != 0) return false; - _module = 0; - return true; -} - -static FARPROC local_GetProcAddress(HMODULE module,LPCSTR lpProcName) -{ - void *ptr = 0; - TRACEN((printf("local_GetProcAddress(%p,%s)\n",(void *)module,lpProcName))) - if (module) { -#ifdef __APPLE_CC__ - char name[MAX_PATHNAME_LEN]; - snprintf(name,sizeof(name),"_%s",lpProcName); - name[sizeof(name)-1] = 0; - TRACEN((printf("NSLookupSymbolInModule(%p,%s)\n",(void *)module,name))) - NSSymbol sym; - sym = NSLookupSymbolInModule((NSModule)module, name); - if (sym) { - ptr = NSAddressOfSymbol(sym); - } else { - ptr = 0; - } -#elif ENV_BEOS - if (get_image_symbol((image_id)module, lpProcName, B_SYMBOL_TYPE_TEXT, &ptr) != B_OK) - ptr = 0; -#else - ptr = dlsym (module, lpProcName); -#endif - TRACEN((printf("CLibrary::GetProc : dlsym(%p,%s)=%p\n",(void *)module,lpProcName,ptr))) - } - return (FARPROC)ptr; -} - -FARPROC CLibrary::GetProc(LPCSTR lpProcName) const -{ - TRACEN((printf("CLibrary::GetProc(%p,%s)\n",(void *)_module,lpProcName))) - return local_GetProcAddress(_module,lpProcName); -} - -bool CLibrary::Load(LPCTSTR lpLibFileName) -{ - if(!Free()) - return false; - - void *handler = 0; - char name[MAX_PATHNAME_LEN+1]; -#ifdef _UNICODE - AString name2 = UnicodeStringToMultiByte(lpLibFileName); - strcpy(name,nameWindowToUnix((const char *)name2)); -#else - strcpy(name,nameWindowToUnix(lpLibFileName)); -#endif - - // replace ".dll" with ".so" - size_t len = strlen(name); - if ((len >=4) && (strcmp(name+len-4,".dll") == 0)) { - strcpy(name+len-4,".so"); - } - - TRACEN((printf("CLibrary::Load(this=%p,%ls) => %s\n",(void *)this,lpLibFileName,name))) - -#ifdef __APPLE_CC__ - NSObjectFileImage image; - NSObjectFileImageReturnCode nsret; - - nsret = NSCreateObjectFileImageFromFile (name, &image); - if (nsret == NSObjectFileImageSuccess) { - TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : OK\n",name))) - handler = (HMODULE)NSLinkModule(image,name,NSLINKMODULE_OPTION_RETURN_ON_ERROR - | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); - } else { - TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : ERROR\n",name))) - } -#elif ENV_BEOS - // normalize path (remove things like "./", "..", etc..), otherwise it won't work - BPath p(name, NULL, true); - status_t err = B_OK; - image_id image = load_add_on(p.Path()); -TRACEN((printf("load_add_on(%s)=%d\n",p.Path(),(int)image))) - if (image < 0) { - err = (image_id)handler; - handler = 0; - } else { - err = 0; - handler = (HMODULE)image; - } -#else - int options_dlopen = 0; -#ifdef RTLD_LOCAL - options_dlopen |= RTLD_LOCAL; -#endif -#ifdef RTLD_NOW - options_dlopen |= RTLD_NOW; -#endif -#ifdef RTLD_GROUP - #if ! (defined(hpux) || defined(__hpux)) - options_dlopen |= RTLD_GROUP; // mainly for solaris but not for HPUX - #endif -#endif - TRACEN((printf("CLibrary::Load - dlopen(%s,0x%d)\n",name,options_dlopen))) - handler = dlopen(name,options_dlopen); -#endif // __APPLE_CC__ - TRACEN((printf("CLibrary::Load(%s) => %p\n",name,handler))) - if (handler) { - - // Call DllMain() like in Windows : useless now - - // Propagate the value of global_use_utf16_conversion into the plugins - int *tmp = (int *)local_GetProcAddress(handler,"global_use_utf16_conversion"); - if (tmp) *tmp = global_use_utf16_conversion; -#ifdef ENV_HAVE_LSTAT - tmp = (int *)local_GetProcAddress(handler,"global_use_lstat"); - if (tmp) *tmp = global_use_lstat; -#endif - // test construtors calls - void (*fctTest)(void) = (void (*)(void))local_GetProcAddress(handler,"sync_TestConstructor"); - if (fctTest) fctTest(); - - } else { -#ifdef __APPLE_CC__ - NSLinkEditErrors c; - int num_err; - const char *file,*err; - NSLinkEditError(&c,&num_err,&file,&err); - printf("Can't load '%ls' (%s)\n", lpLibFileName,err); -#elif ENV_BEOS - printf("Can't load '%ls' (%s)\n", lpLibFileName,strerror(err)); -#else - printf("Can't load '%ls' (%s)\n", lpLibFileName,dlerror()); -#endif - } - - _module = handler; - TRACEN((printf("CLibrary::Load(this=%p,%ls) => _module=%p\n",(void *)this,lpLibFileName,_module))) - - return true; -} - - -}} - +// Windows/DLL.cpp + +#include "StdAfx.h" + +#include "DLL.h" + +#ifdef _WIN32 + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +extern HINSTANCE g_hInstance; + +namespace NWindows { +namespace NDLL { + +bool CLibrary::Free() throw() +{ + if (_module == NULL) + return true; + if (!::FreeLibrary(_module)) + return false; + _module = NULL; + return true; +} + +bool CLibrary::LoadEx(CFSTR path, DWORD flags) throw() +{ + if (!Free()) + return false; + #ifndef _UNICODE + if (!g_IsNT) + { + _module = ::LoadLibraryEx(fs2fas(path), NULL, flags); + } + else + #endif + { + _module = ::LoadLibraryExW(fs2us(path), NULL, flags); + } + return (_module != NULL); +} + +bool CLibrary::Load(CFSTR path) throw() +{ + if (!Free()) + return false; + #ifndef _UNICODE + if (!g_IsNT) + { + _module = ::LoadLibrary(fs2fas(path)); + } + else + #endif + { + _module = ::LoadLibraryW(fs2us(path)); + } + return (_module != NULL); +} + +bool MyGetModuleFileName(FString &path) +{ + const HMODULE hModule = g_hInstance; + path.Empty(); + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[MAX_PATH + 2]; + s[0] = 0; + const DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1); + if (size <= MAX_PATH && size != 0) + { + path = fas2fs(s); + return true; + } + } + else + #endif + { + WCHAR s[MAX_PATH + 2]; + s[0] = 0; + const DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1); + if (size <= MAX_PATH && size != 0) + { + path = us2fs(s); + return true; + } + } + return false; +} + +#ifndef Z7_SFX + +FString GetModuleDirPrefix() +{ + FString s; + if (MyGetModuleFileName(s)) + { + const int pos = s.ReverseFind_PathSepar(); + if (pos >= 0) + s.DeleteFrom((unsigned)(pos + 1)); + } + if (s.IsEmpty()) + s = "." STRING_PATH_SEPARATOR; + return s; +} + +#endif + +}} + +#else // _WIN32 + +#include +#include + +// FARPROC +void *GetProcAddress(HMODULE module, LPCSTR procName) +{ + void *ptr = NULL; + if (module) + ptr = dlsym(module, procName); + return ptr; +} + +namespace NWindows { +namespace NDLL { + +bool CLibrary::Free() throw() +{ + if (!_module) + return true; + const int ret = dlclose(_module); + if (ret != 0) + return false; + _module = NULL; + return true; +} + +bool CLibrary::Load(CFSTR path) throw() +{ + if (!Free()) + return false; + + int options = 0; + + #ifdef RTLD_LOCAL + options |= RTLD_LOCAL; + #endif + + #ifdef RTLD_NOW + options |= RTLD_NOW; + #endif + + #ifdef RTLD_GROUP + #if ! (defined(hpux) || defined(__hpux)) + options |= RTLD_GROUP; // mainly for solaris but not for HPUX + #endif + #endif + + _module = dlopen(path, options); + return (_module != NULL); +} + +/* +// FARPROC +void * CLibrary::GetProc(LPCSTR procName) const +{ + // return My_GetProcAddress(_module, procName); + return local_GetProcAddress(_module, procName); + // return NULL; +} +*/ + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/DLL.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.h --- p7zip-rar-16.02/CPP/Windows/DLL.h 2011-07-08 20:45:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/DLL.h 2023-03-24 11:00:00.000000000 +0000 @@ -1,50 +1,103 @@ -// Windows/DLL.h - -#ifndef __WINDOWS_DLL_H -#define __WINDOWS_DLL_H - -#include "../Common/MyString.h" - -typedef void * HMODULE; -// #define LOAD_LIBRARY_AS_DATAFILE 0 -typedef int (*FARPROC)(); - -namespace NWindows { -namespace NDLL { - -class CLibrary -{ - HMODULE _module; -public: - CLibrary(): _module(NULL) {}; - ~CLibrary() { Free(); } - - operator HMODULE() const { return _module; } - HMODULE* operator&() { return &_module; } - bool IsLoaded() const { return (_module != NULL); }; - - void Attach(HMODULE m) - { - Free(); - _module = m; - } - HMODULE Detach() - { - HMODULE m = _module; - _module = NULL; - return m; - } - - bool Free(); - // bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE); - bool Load(CFSTR path); - FARPROC GetProc(LPCSTR procName) const; // { return My_GetProcAddress(_module, procName); } -}; - -bool MyGetModuleFileName(FString &path); - -FString GetModuleDirPrefix(); - -}} - -#endif +// Windows/DLL.h + +#ifndef ZIP7_INC_WINDOWS_DLL_H +#define ZIP7_INC_WINDOWS_DLL_H + +#include "../Common/MyString.h" + +#ifndef _WIN32 +typedef void * HMODULE; +// typedef int (*FARPROC)(); +// typedef void *FARPROC; +void *GetProcAddress(HMODULE module, LPCSTR procName); +#endif + +namespace NWindows { +namespace NDLL { + +#ifdef _WIN32 + +/* +#ifdef UNDER_CE +#define My_GetProcAddress(module, procName) (void *)::GetProcAddressA(module, procName) +#else +#define My_GetProcAddress(module, procName) (void *)::GetProcAddress(module, procName) +#endif +*/ + +/* Win32: Don't call CLibrary::Free() and FreeLibrary() from another + FreeLibrary() code: detaching code in DLL entry-point or in + destructors of global objects in DLL module. */ + +class CLibrary +{ + HMODULE _module; + + // Z7_CLASS_NO_COPY(CLibrary); + // copy constructor is required here +public: + CLibrary(): _module(NULL) {} + ~CLibrary() { Free(); } + + CLibrary(const CLibrary &c): _module(NULL) + { + if (c._module) + { + // we need non const to reference from original item + // c._module = NULL; + throw 20230102; + } + } + + HMODULE Get_HMODULE() const { return _module; } + // operator HMODULE() const { return _module; } + // HMODULE* operator&() { return &_module; } + bool IsLoaded() const { return (_module != NULL); } + + void Attach(HMODULE m) + { + Free(); + _module = m; + } + HMODULE Detach() + { + const HMODULE m = _module; + _module = NULL; + return m; + } + + bool Free() throw(); + bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE) throw(); + bool Load(CFSTR path) throw(); + // FARPROC + // void *GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); } +}; + +#else + +class CLibrary +{ + HMODULE _module; + + // Z7_CLASS_NO_COPY(CLibrary); +public: + CLibrary(): _module(NULL) {} + ~CLibrary() { Free(); } + + HMODULE Get_HMODULE() const { return _module; } + + bool Free() throw(); + bool Load(CFSTR path) throw(); + // FARPROC + // void *GetProc(LPCSTR procName) const; // { return My_GetProcAddress(_module, procName); } +}; + +#endif + +bool MyGetModuleFileName(FString &path); + +FString GetModuleDirPrefix(); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Defs.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Defs.h --- p7zip-rar-16.02/CPP/Windows/Defs.h 2009-12-21 16:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Defs.h 2023-01-26 12:00:00.000000000 +0000 @@ -1,17 +1,17 @@ -// Windows/Defs.h - -#ifndef __WINDOWS_DEFS_H -#define __WINDOWS_DEFS_H - -#include "../Common/MyWindows.h" - -// #ifdef _WIN32 -inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); } -inline bool BOOLToBool(BOOL v) { return (v != FALSE); } -inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); } -// #endif - -inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); } -inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); } - -#endif +// Windows/Defs.h + +#ifndef ZIP7_INC_WINDOWS_DEFS_H +#define ZIP7_INC_WINDOWS_DEFS_H + +#include "../Common/MyWindows.h" + +#ifdef _WIN32 +inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); } +#endif + +inline bool BOOLToBool(BOOL v) { return (v != FALSE); } + +inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); } +inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); } + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/ErrorMsg.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.cpp --- p7zip-rar-16.02/CPP/Windows/ErrorMsg.cpp 2015-01-18 18:20:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.cpp 2023-01-29 16:00:00.000000000 +0000 @@ -1,90 +1,133 @@ -// Windows/ErrorMsg.h - -#include "StdAfx.h" - -#include "Windows/ErrorMsg.h" -#include "Common/StringConvert.h" - -namespace NWindows { -namespace NError { - -UString MyFormatMessage(DWORD errorCode) -{ - const char * txt = 0; - AString msg; - - switch(errorCode) { - case ERROR_NO_MORE_FILES : txt = "No more files"; break ; - case E_NOTIMPL : txt = "E_NOTIMPL"; break ; - case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; - case E_ABORT : txt = "E_ABORT"; break ; - case E_FAIL : txt = "E_FAIL"; break ; - case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; - case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; - case E_INVALIDARG : txt = "E_INVALIDARG"; break ; - case ERROR_DIRECTORY : txt = "Error Directory"; break ; - default: - txt = strerror(errorCode); - } - if (txt) { - msg = txt; - } else { - char msgBuf[256]; - snprintf(msgBuf,sizeof(msgBuf),"error #%x",(unsigned)errorCode); - msgBuf[sizeof(msgBuf)-1] = 0; - msg = msgBuf; - } - return MultiByteToUnicodeString(msg); -} - -#if 0 -bool MyFormatMessage(DWORD messageID, CSysString &message) -{ - const char * txt = 0; - AString msg; - - switch(messageID) { - case ERROR_NO_MORE_FILES : txt = "No more files"; break ; - case E_NOTIMPL : txt = "E_NOTIMPL"; break ; - case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; - case E_ABORT : txt = "E_ABORT"; break ; - case E_FAIL : txt = "E_FAIL"; break ; - case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; - case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; - case E_INVALIDARG : txt = "E_INVALIDARG"; break ; - default: - txt = strerror(messageID); - } - if (txt) { - msg = txt; - } else { - char msgBuf[256]; - snprintf(msgBuf,sizeof(msgBuf),"error #%x",(unsigned)messageID); - msgBuf[sizeof(msgBuf)-1] = 0; - msg = msgBuf; - } - - msg += " "; - -#ifdef _UNICODE - message = MultiByteToUnicodeString(msg); -#else - message = msg; -#endif - return true; -} - -#ifndef _UNICODE -bool MyFormatMessage(DWORD messageID, UString &message) -{ - CSysString messageSys; - bool result = MyFormatMessage(messageID, messageSys); - message = GetUnicodeString(messageSys); - return result; -} -#endif - -#endif - -}} - +// Windows/ErrorMsg.h + +#include "StdAfx.h" + +#if !defined(_UNICODE) || !defined(_WIN32) +#include "../Common/StringConvert.h" +#endif + +#include "ErrorMsg.h" + +#ifdef _WIN32 +#if !defined(_UNICODE) +extern bool g_IsNT; +#endif +#endif + +namespace NWindows { +namespace NError { + +static bool MyFormatMessage(DWORD errorCode, UString &message) +{ + #ifndef Z7_SFX + if ((HRESULT)errorCode == MY_HRES_ERROR_INTERNAL_ERROR) + { + message = "Internal Error: The failure in hardware (RAM or CPU), OS or program"; + return true; + } + #endif + + #ifdef _WIN32 + + LPVOID msgBuf; + #ifndef _UNICODE + if (!g_IsNT) + { + if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, 0, (LPTSTR) &msgBuf, 0, NULL) == 0) + return false; + message = GetUnicodeString((LPCTSTR)msgBuf); + } + else + #endif + { + if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) + return false; + message = (LPCWSTR)msgBuf; + } + ::LocalFree(msgBuf); + return true; + + #else // _WIN32 + + AString m; + + const char *s = NULL; + + switch ((Int32)errorCode) + { + // case ERROR_NO_MORE_FILES : s = "No more files"; break; + // case ERROR_DIRECTORY : s = "Error Directory"; break; + case E_NOTIMPL : s = "E_NOTIMPL : Not implemented"; break; + case E_NOINTERFACE : s = "E_NOINTERFACE : No such interface supported"; break; + case E_ABORT : s = "E_ABORT : Operation aborted"; break; + case E_FAIL : s = "E_FAIL : Unspecified error"; break; + + case STG_E_INVALIDFUNCTION : s = "STG_E_INVALIDFUNCTION"; break; + case CLASS_E_CLASSNOTAVAILABLE : s = "CLASS_E_CLASSNOTAVAILABLE"; break; + + case E_OUTOFMEMORY : s = "E_OUTOFMEMORY : Can't allocate required memory"; break; + case E_INVALIDARG : s = "E_INVALIDARG : One or more arguments are invalid"; break; + + // case MY_E_ERROR_NEGATIVE_SEEK : s = "MY_E_ERROR_NEGATIVE_SEEK"; break; + default: + break; + } + + /* strerror() for unknown errors still shows message "Unknown error -12345678") + So we must transfer error codes before strerror() */ + if (!s) + { + if ((errorCode & 0xFFFF0000) == (UInt32)((MY_FACILITY_WRes << 16) | 0x80000000)) + errorCode &= 0xFFFF; + else if ((errorCode & ((UInt32)1 << 31))) + return false; // we will show hex error later for that case + + s = strerror((int)errorCode); + + // if (!s) + { + m += "errno="; + m.Add_UInt32(errorCode); + if (s) + m += " : "; + } + } + + if (s) + m += s; + + MultiByteToUnicodeString2(message, m); + return true; + + #endif +} + + +UString MyFormatMessage(DWORD errorCode) +{ + UString m; + if (!MyFormatMessage(errorCode, m) || m.IsEmpty()) + { + char s[16]; + for (int i = 0; i < 8; i++) + { + unsigned t = errorCode & 0xF; + errorCode >>= 4; + s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[8] = 0; + m += "Error #"; + m += s; + } + else if (m.Len() >= 2 + && m[m.Len() - 1] == 0x0A + && m[m.Len() - 2] == 0x0D) + m.DeleteFrom(m.Len() - 2); + return m; +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/ErrorMsg.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.h --- p7zip-rar-16.02/CPP/Windows/ErrorMsg.h 2014-12-21 12:44:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ErrorMsg.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,15 +1,16 @@ -// Windows/ErrorMsg.h - -#ifndef __WINDOWS_ERROR_MSG_H -#define __WINDOWS_ERROR_MSG_H - -#include "../Common/MyString.h" - -namespace NWindows { -namespace NError { - -UString MyFormatMessage(DWORD errorCode); - -}} - -#endif +// Windows/ErrorMsg.h + +#ifndef ZIP7_INC_WINDOWS_ERROR_MSG_H +#define ZIP7_INC_WINDOWS_ERROR_MSG_H + +#include "../Common/MyString.h" + +namespace NWindows { +namespace NError { + +UString MyFormatMessage(DWORD errorCode); +inline UString MyFormatMessage(HRESULT errorCode) { return MyFormatMessage((DWORD)errorCode); } + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileDir.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.cpp --- p7zip-rar-16.02/CPP/Windows/FileDir.cpp 2015-11-09 15:51:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.cpp 2025-06-20 11:00:00.000000000 +0000 @@ -1,879 +1,1360 @@ -// Windows/FileDir.cpp - -#include "StdAfx.h" - -#ifndef _UNICODE -#include "../Common/StringConvert.h" -#endif - -#include "FileDir.h" -#include "FileFind.h" -#include "FileName.h" - -using namespace NWindows; -using namespace NFile; -using namespace NName; - -#include "../Common/StringConvert.h" -#include "../Common/IntToString.h" - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" -#include "Windows/Synchronization.h" - -#include // rmdir -#include - -#include // mkdir -#include -#include - -#include - -// #define TRACEN(u) u; -#define TRACEN(u) /* */ - -int g_filedir = 1; - -static NWindows::NSynchronization::CCriticalSection g_CountCriticalSection; - -class Umask -{ - public: - mode_t current_umask; - mode_t mask; - Umask() { - current_umask = umask (0); /* get and set the umask */ - umask(current_umask); /* restore the umask */ - mask = 0777 & (~current_umask); - } -}; - -static Umask gbl_umask; -extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ); - - -#ifdef _UNICODE -AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ? -{ - AString astr = UnicodeStringToMultiByte(name); - return AString(nameWindowToUnix((const char *)astr)); -} -#endif - -DWORD WINAPI GetFullPathNameW( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME - if (name == 0) return 0; - - DWORD name_len = lstrlen(name); - - if (name[0] == '/') { - DWORD ret = name_len+2; - if (ret >= len) { - TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 0)\n",name, (int)len))) - return 0; - } - lstrcpy(buffer,L"c:"); - lstrcat(buffer,name); - - *lastpart=buffer; - TCHAR *ptr=buffer; - while (*ptr) { - if (*ptr == '/') - *lastpart=ptr+1; - ptr++; - } - TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) - return ret; - } - if (isascii(name[0]) && (name[1] == ':')) { // FIXME isascii - DWORD ret = name_len; - if (ret >= len) { - TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 1)\n",name, (int)len))) - return 0; - } - lstrcpy(buffer,name); - - *lastpart=buffer; - TCHAR *ptr=buffer; - while (*ptr) { - if (*ptr == '/') - *lastpart=ptr+1; - ptr++; - } - TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) - return ret; - } - - // name is a relative pathname. - // - if (len < 2) { - TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 2)\n",name, (int)len))) - return 0; - } - - DWORD ret = 0; - char begin[MAX_PATHNAME_LEN]; - /* DWORD begin_len = GetCurrentDirectoryA(MAX_PATHNAME_LEN,begin); */ - DWORD begin_len = 0; - begin[0]='c'; - begin[1]=':'; - char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); - if (cret) { - begin_len = strlen(begin); - } - - if (begin_len >= 1) { - // strlen(begin) + strlen("/") + strlen(name) - ret = begin_len + 1 + name_len; - - if (ret >= len) { - TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 4)\n",name, (int)len))) - return 0; - } - UString wbegin = GetUnicodeString(begin); - lstrcpy(buffer,wbegin); - lstrcat(buffer,L"/"); - lstrcat(buffer,name); - - *lastpart=buffer + begin_len + 1; - TCHAR *ptr=buffer; - while (*ptr) { - if (*ptr == '/') - *lastpart=ptr+1; - ptr++; - } - TRACEN((printf("GetFullPathNameA(%ls,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) - } else { - ret = 0; - TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 5)\n",name, (int)len))) - } - return ret; -} - -static int copy_fd(int fin,int fout) -{ - char buffer[16384]; - ssize_t ret_in; - ssize_t ret_out; - - do { - ret_out = -1; - do { - ret_in = read(fin, buffer,sizeof(buffer)); - } while (ret_in < 0 && (errno == EINTR)); - if (ret_in >= 1) { - do { - ret_out = write (fout, buffer, ret_in); - } while (ret_out < 0 && (errno == EINTR)); - } else if (ret_in == 0) { - ret_out = 0; - } - } while (ret_out >= 1); - return ret_out; -} - -static BOOL CopyFile(const char *src,const char *dst) -{ - int ret = -1; - -#ifdef O_BINARY - int flags = O_BINARY; -#else - int flags = 0; -#endif - -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif - - // printf("##DBG CopyFile(%s,%s)\n",src,dst); - int fout = open(dst,O_CREAT | O_WRONLY | O_EXCL | flags, 0600); - if (fout != -1) - { - int fin = open(src,O_RDONLY | flags , 0600); - if (fin != -1) - { - ret = copy_fd(fin,fout); - if (ret == 0) ret = close(fin); - else close(fin); - } - if (ret == 0) ret = close(fout); - else close(fout); - } - if (ret == 0) return TRUE; - return FALSE; -} - - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -namespace NWindows { -namespace NFile { - -// SetCurrentDirectory doesn't support \\?\ prefix - -#ifdef WIN_LONG_PATH -bool GetLongPathBase(CFSTR fileName, UString &res); -bool GetLongPath(CFSTR fileName, UString &res); -#endif - -namespace NDir { - - -#ifdef _WIN32 - -#ifndef UNDER_CE - -bool MyGetWindowsDirectory(FString &path) -{ - UINT needLength; - #ifndef _UNICODE - if (!g_IsNT) - { - TCHAR s[MAX_PATH + 2]; - s[0] = 0; - needLength = ::GetWindowsDirectory(s, MAX_PATH + 1); - path = fas2fs(s); - } - else - #endif - { - WCHAR s[MAX_PATH + 2]; - s[0] = 0; - needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1); - path = us2fs(s); - } - return (needLength > 0 && needLength <= MAX_PATH); -} - - -bool MyGetSystemDirectory(FString &path) -{ - UINT needLength; - #ifndef _UNICODE - if (!g_IsNT) - { - TCHAR s[MAX_PATH + 2]; - s[0] = 0; - needLength = ::GetSystemDirectory(s, MAX_PATH + 1); - path = fas2fs(s); - } - else - #endif - { - WCHAR s[MAX_PATH + 2]; - s[0] = 0; - needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1); - path = us2fs(s); - } - return (needLength > 0 && needLength <= MAX_PATH); -} -#endif -#endif // _WIN32 - -bool SetDirTime(CFSTR fileName, const FILETIME * /* cTime */ , const FILETIME *aTime, const FILETIME *mTime) -{ - AString cfilename = UnicodeStringToMultiByte(fileName); - const char * unix_filename = nameWindowToUnix((const char *)cfilename); - - struct utimbuf buf; - - struct stat oldbuf; - int ret = stat(unix_filename,&oldbuf); - if (ret == 0) { - buf.actime = oldbuf.st_atime; - buf.modtime = oldbuf.st_mtime; - } else { - time_t current_time = time(0); - buf.actime = current_time; - buf.modtime = current_time; - } - - if (aTime) - { - LARGE_INTEGER ltime; - DWORD dw; - ltime.QuadPart = aTime->dwHighDateTime; - ltime.QuadPart = (ltime.QuadPart << 32) | aTime->dwLowDateTime; - RtlTimeToSecondsSince1970( <ime, &dw ); - buf.actime = dw; - } - - if (mTime) - { - LARGE_INTEGER ltime; - DWORD dw; - ltime.QuadPart = mTime->dwHighDateTime; - ltime.QuadPart = (ltime.QuadPart << 32) | mTime->dwLowDateTime; - RtlTimeToSecondsSince1970( <ime, &dw ); - buf.modtime = dw; - } - - /* ret = */ utime(unix_filename, &buf); - - return true; -} - -#ifdef WIN_LONG_PATH -bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2) -{ - if (!GetLongPathBase(s1, d1) || - !GetLongPathBase(s2, d2)) - return false; - if (d1.IsEmpty() && d2.IsEmpty()) - return false; - if (d1.IsEmpty()) d1 = fs2us(s1); - if (d2.IsEmpty()) d2 = fs2us(s2); - return true; -} -#endif - -static int convert_to_symlink(const char * name) { - TRACEN(printf("LINK(%s)\n",name)) - FILE *file = fopen(name,"rb"); - if (file) { - char buf[MAX_PATHNAME_LEN+1]; - char * ret = fgets(buf,sizeof(buf)-1,file); - fclose(file); - if (ret) { - int ir = unlink(name); - if (ir == 0) { - ir = symlink(buf,name); - TRACEN(printf("TO(%s)\n",buf)) - } - return ir; - } - } - return -1; -} - -bool SetFileAttrib(CFSTR fileName, DWORD fileAttributes,CObjectVector *delayedSymLinks) -{ - if (!fileName) { - SetLastError(ERROR_PATH_NOT_FOUND); - TRACEN((printf("SetFileAttrib(NULL,%d) : false-1\n",fileAttributes))) - return false; - } -#ifdef _UNICODE - AString name = nameWindowToUnix2(fileName); -#else - const char * name = nameWindowToUnix(fileName); -#endif - struct stat stat_info; -#ifdef ENV_HAVE_LSTAT - if (global_use_lstat) { - if(lstat(name,&stat_info)!=0) { - TRACEN((printf("SetFileAttrib(%s,%d) : false-2-1\n",(const char *)name,fileAttributes))) - return false; - } - } else -#endif - { - if(stat(name,&stat_info)!=0) { - TRACEN((printf("SetFileAttrib(%s,%d) : false-2-2\n",(const char *)name,fileAttributes))) - return false; - } - } - - if (fileAttributes & FILE_ATTRIBUTE_UNIX_EXTENSION) { - stat_info.st_mode = fileAttributes >> 16; -#ifdef ENV_HAVE_LSTAT - if (S_ISLNK(stat_info.st_mode)) { - if (delayedSymLinks) { - delayedSymLinks->Add(CDelayedSymLink(name)); - } else if ( convert_to_symlink(name) != 0) { - TRACEN((printf("SetFileAttrib(%s,%d) : false-3\n",(const char *)name,fileAttributes))) - return false; - } - } else -#endif - if (S_ISREG(stat_info.st_mode)) { - TRACEN((printf("##DBG chmod-2(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask))) - chmod(name,stat_info.st_mode & gbl_umask.mask); - } else if (S_ISDIR(stat_info.st_mode)) { - // user/7za must be able to create files in this directory - stat_info.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR); - TRACEN((printf("##DBG chmod-3(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask))) - chmod(name,stat_info.st_mode & gbl_umask.mask); - } -#ifdef ENV_HAVE_LSTAT - } else if (!S_ISLNK(stat_info.st_mode)) { - // do not use chmod on a link -#else - } else { -#endif - - /* Only Windows Attributes */ - if( S_ISDIR(stat_info.st_mode)) { - /* Remark : FILE_ATTRIBUTE_READONLY ignored for directory. */ - TRACEN((printf("##DBG chmod-4(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask))) - chmod(name,stat_info.st_mode & gbl_umask.mask); - } else { - if (fileAttributes & FILE_ATTRIBUTE_READONLY) stat_info.st_mode &= ~0222; /* octal!, clear write permission bits */ - TRACEN((printf("##DBG chmod-5(%s,%o)\n",(const char *)name,(unsigned)stat_info.st_mode & gbl_umask.mask))) - chmod(name,stat_info.st_mode & gbl_umask.mask); - } - } - TRACEN((printf("SetFileAttrib(%s,%d) : true\n",(const char *)name,fileAttributes))) - - return true; -} - -bool RemoveDir(CFSTR path) -{ - if (!path || !*path) { - SetLastError(ERROR_PATH_NOT_FOUND); - return FALSE; - } - AString name = nameWindowToUnix2(path); - TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name))) - - if (rmdir( (const char *)name ) != 0) { - return FALSE; - } - return TRUE; -} - -bool MyMoveFile(CFSTR existFileName, CFSTR newFileName) -{ -#ifdef _UNICODE - AString src = nameWindowToUnix2(existFileName); - AString dst = nameWindowToUnix2(newFileName); -#else - const char * src = nameWindowToUnix(existFileName); - const char * dst = nameWindowToUnix(newFileName); -#endif - - TRACEN((printf("MyMoveFile(%s,%s)\n",(const char *)src,(const char *)dst))) - - int ret = rename(src,dst); - if (ret != 0) - { - if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target) - { - BOOL bret = CopyFile(src,dst); - if (bret == FALSE) return false; - - struct stat info_file; - ret = stat(src,&info_file); - if (ret == 0) { - TRACEN((printf("##DBG chmod-1(%s,%o)\n",(const char *)dst,(unsigned)info_file.st_mode & gbl_umask.mask))) - ret = chmod(dst,info_file.st_mode & gbl_umask.mask); - } - if (ret == 0) { - ret = unlink(src); - } - if (ret == 0) return true; - } - return false; - } - return true; -} - -bool CreateDir(CFSTR path) -{ - if (!path || !*path) { - SetLastError(ERROR_PATH_NOT_FOUND); - return false; - } - -#ifdef _UNICODE - AString name = nameWindowToUnix2(path); -#else - const char * name = nameWindowToUnix(path); -#endif - bool bret = false; - if (mkdir( name, 0700 ) == 0) bret = true; - - TRACEN((printf("CreateDir(%s)=%d\n",(const char *)name,(int)bret))) - return bret; -} - -bool CreateComplexDir(CFSTR _aPathName) -{ - AString name = nameWindowToUnix2(_aPathName); - TRACEN((printf("CreateComplexDir(%s)\n",(const char *)name))) - - - FString pathName = _aPathName; - int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR); - if (pos > 0 && pos == pathName.Len() - 1) - { - if (pathName.Len() == 3 && pathName[1] == L':') - return true; // Disk folder; - pathName.Delete(pos); - } - FString pathName2 = pathName; - pos = pathName.Len(); - TRACEN((printf("CreateComplexDir(%s) pathName2=%ls\n",(const char *)name,(CFSTR)pathName2))) - for (;;) - { - if (CreateDir(pathName)) - break; - TRACEN((printf("CreateComplexDir(%s) GetLastError=%d (ERROR_ALREADY_EXISTS=%d)\n",(const char *)name,::GetLastError(), ERROR_ALREADY_EXISTS))) - if (::GetLastError() == ERROR_ALREADY_EXISTS) - { -#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory - NFind::CFileInfo fileInfo; - if (!fileInfo.Find(pathName)) // For network folders - return true; - if (!fileInfo.IsDir()) - return false; -#endif - break; - } - pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR); - if (pos < 0 || pos == 0) - return false; - if (pathName[pos - 1] == L':') - return false; - pathName = pathName.Left(pos); - } - pathName = pathName2; - while (pos < pathName.Len()) - { - pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1); - if (pos < 0) - pos = pathName.Len(); - if (!CreateDir(pathName.Left(pos))) - return false; - } - return true; -} - -bool DeleteFileAlways(CFSTR name) -{ - if (!name || !*name) { - SetLastError(ERROR_PATH_NOT_FOUND); - return false; - } -#ifdef _UNICODE - AString unixname = nameWindowToUnix2(name); -#else - const char * unixname = nameWindowToUnix(name); -#endif - bool bret = false; - if (remove(unixname) == 0) bret = true; - TRACEN((printf("DeleteFileAlways(%s)=%d\n",(const char *)unixname,(int)bret))) - return bret; -} - -bool RemoveDirWithSubItems(const FString &path) -{ - bool needRemoveSubItems = true; - { - NFind::CFileInfo fi; - if (!fi.Find(path)) - return false; - if (!fi.IsDir()) - { - ::SetLastError(ERROR_DIRECTORY); - return false; - } - if (fi.HasReparsePoint()) - needRemoveSubItems = false; - } - - if (needRemoveSubItems) - { - FString s = path; - s += FCHAR_PATH_SEPARATOR; - unsigned prefixSize = s.Len(); - s += FCHAR_ANY_MASK; - NFind::CEnumerator enumerator(s); - NFind::CFileInfo fi; - while (enumerator.Next(fi)) - { - s.DeleteFrom(prefixSize); - s += fi.Name; - if (fi.IsDir()) - { - if (!RemoveDirWithSubItems(s)) - return false; - } - else if (!DeleteFileAlways(s)) - return false; - } - } - - if (!SetFileAttrib(path, 0)) - return false; - return RemoveDir(path); -} - - -bool RemoveDirectoryWithSubItems(const FString &path); // FIXME -static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo) -{ - if (fileInfo.IsDir()) - return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); - return DeleteFileAlways(pathPrefix + fileInfo.Name); -} -bool RemoveDirectoryWithSubItems(const FString &path) -{ - NFind::CFileInfo fileInfo; - FString pathPrefix = path + FCHAR_PATH_SEPARATOR; - { - NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK); - while (enumerator.Next(fileInfo)) - if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) - return false; - } - if (!SetFileAttrib(path, 0)) - return false; - return RemoveDir(path); -} - -#ifdef UNDER_CE - -bool MyGetFullPathName(CFSTR fileName, FString &resFullPath) -{ - resFullPath = fileName; - return true; -} - -#else - -bool MyGetFullPathName(CFSTR path, FString &resFullPath) -{ - return GetFullPath(path, resFullPath); -} - -bool SetCurrentDir(CFSTR path) -{ - AString apath = UnicodeStringToMultiByte(path); - - return chdir((const char*)apath) == 0; -} - -bool GetCurrentDir(FString &path) -{ - char begin[MAX_PATHNAME_LEN]; - begin[0]='c'; - begin[1]=':'; - char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); - if (cret) - { -#ifdef _UNICODE - path = GetUnicodeString(begin); -#else - path = begin; -#endif - return true; - } - return false; -} - -#endif - -bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName) -{ - bool res = MyGetFullPathName(path, resDirPrefix); - if (!res) - resDirPrefix = path; - int pos = resDirPrefix.ReverseFind(FCHAR_PATH_SEPARATOR); - resFileName = resDirPrefix.Ptr(pos + 1); - resDirPrefix.DeleteFrom(pos + 1); - return res; -} - -bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix) -{ - FString resFileName; - return GetFullPathAndSplit(path, resDirPrefix, resFileName); -} - -bool MyGetTempPath(FString &path) -{ - path = L"c:/tmp/"; // final '/' is needed - return true; -} - -static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile) -{ -#ifdef _WIN32 - UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); -#else - static UInt32 memo_count = 0; - UInt32 count; - - g_CountCriticalSection.Enter(); - count = memo_count++; - g_CountCriticalSection.Leave(); - UINT number = (UINT)getpid(); - - UInt32 d = (GetTickCount() << 12) ^ (count << 14) ^ number; -#endif - for (unsigned i = 0; i < 100; i++) - { - path = prefix; - if (addRandom) - { - FChar s[16]; - UInt32 value = d; - unsigned k; - for (k = 0; k < 8; k++) - { - unsigned t = value & 0xF; - value >>= 4; - s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); - } - s[k] = '\0'; - if (outFile) - path += FChar('.'); - path += s; - UInt32 step = GetTickCount() + 2; - if (step == 0) - step = 1; - d += step; - } - addRandom = true; - if (outFile) - path += FTEXT(".tmp"); - if (NFind::DoesFileOrDirExist(path)) - { - SetLastError(ERROR_ALREADY_EXISTS); - continue; - } - if (outFile) - { - if (outFile->Create(path, false)) - return true; - } - else - { - if (CreateDir(path)) - return true; - } - DWORD error = GetLastError(); - if (error != ERROR_FILE_EXISTS && - error != ERROR_ALREADY_EXISTS) - break; - } - path.Empty(); - return false; -} - -bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile) -{ - if (!Remove()) - return false; - if (!CreateTempFile(prefix, false, _path, outFile)) - return false; - _mustBeDeleted = true; - return true; -} - -bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile) -{ - if (!Remove()) - return false; - FString tempPath; - if (!MyGetTempPath(tempPath)) - return false; - if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile)) - return false; - _mustBeDeleted = true; - return true; -} - -bool CTempFile::Remove() -{ - if (!_mustBeDeleted) - return true; - _mustBeDeleted = !DeleteFileAlways(_path); - return !_mustBeDeleted; -} - -bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore) -{ - if (deleteDestBefore) - if (NFind::DoesFileExist(name)) - if (!DeleteFileAlways(name)) - return false; - DisableDeleting(); - return MyMoveFile(_path, name); -} - -bool CTempDir::Create(CFSTR prefix) -{ - if (!Remove()) - return false; - FString tempPath; - if (!MyGetTempPath(tempPath)) - return false; - if (!CreateTempFile(tempPath + prefix, true, _path, NULL)) - return false; - _mustBeDeleted = true; - return true; -} - -bool CTempDir::Remove() -{ - if (!_mustBeDeleted) - return true; - _mustBeDeleted = !RemoveDirectoryWithSubItems(_path); - return !_mustBeDeleted; -} - -#ifdef ENV_UNIX - -CDelayedSymLink::CDelayedSymLink(const char * source) - : _source(source) -{ - struct stat st; - - if (lstat(_source, &st) == 0) { - _dev = st.st_dev; - _ino = st.st_ino; - } else { - _dev = 0; - } -} - -bool CDelayedSymLink::Create() -{ - struct stat st; - - if (_dev == 0) { - errno = EPERM; - return false; - } - if (lstat(_source, &st) != 0) - return false; - if (_dev != st.st_dev || _ino != st.st_ino) { - // Placeholder file has been overwritten or moved by another - // symbolic link creation - errno = EPERM; - return false; - } - - return convert_to_symlink(_source) == 0; -} - -#endif // ENV_UNIX - -}}} - -#ifndef _SFX - -namespace NWindows { -namespace NDLL { - -FString GetModuleDirPrefix() -{ - FString s; - - const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR"); - if (p7zip_home_dir) { - return MultiByteToUnicodeString(p7zip_home_dir,CP_ACP); - } - - return FTEXT(".") FSTRING_PATH_SEPARATOR; -} - -}} - -#endif +// Windows/FileDir.cpp + +#include "StdAfx.h" + + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../Common/C_FileIO.h" +#include "../Common/MyBuffer2.h" +#include "../Common/StringConvert.h" +#endif + +#include "FileDir.h" +#include "FileFind.h" +#include "FileName.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +#ifndef _WIN32 + +static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts) +{ + if (ft) + { +#if defined(_AIX) + ts.tv_sec = ft->tv_sec; + ts.tv_nsec = ft->tv_nsec; +#else + ts = *ft; +#endif + 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 { + +#ifdef _WIN32 + +#ifndef UNDER_CE + +bool GetWindowsDir(FString &path) +{ + const unsigned kBufSize = MAX_PATH + 16; + UINT len; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetWindowsDirectory(s, kBufSize); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetWindowsDirectoryW(s, kBufSize); + path = us2fs(s); + } + return (len != 0 && len < kBufSize); +} + + +/* +new DOCs for GetSystemDirectory: + returned path does not end with a backslash unless the + system directory is the root directory. +*/ + +bool GetSystemDir(FString &path) +{ + const unsigned kBufSize = MAX_PATH + 16; + UINT len; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetSystemDirectory(s, kBufSize); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetSystemDirectoryW(s, kBufSize); + path = us2fs(s); + } + return (len != 0 && len < kBufSize); +} +#endif // UNDER_CE + + +bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } + #endif + + HANDLE hDir = INVALID_HANDLE_VALUE; + IF_USE_MAIN_PATH + hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + #ifdef Z7_LONG_PATH + if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + hDir = ::CreateFileW(superPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + #endif + + bool res = false; + if (hDir != INVALID_HANDLE_VALUE) + { + res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime)); + ::CloseHandle(hDir); + } + return res; +} + + + +bool SetFileAttrib(CFSTR path, DWORD attrib) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::SetFileAttributes(fs2fas(path), attrib)) + return true; + } + else + #endif + { + IF_USE_MAIN_PATH + if (::SetFileAttributesW(fs2us(path), attrib)) + return true; + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + return BOOLToBool(::SetFileAttributesW(superPath, attrib)); + } + #endif + } + return false; +} + + +bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) +{ + #ifdef _WIN32 + if ((attrib & 0xF0000000) != 0) + attrib &= 0x3FFF; + #endif + return SetFileAttrib(path, attrib); +} + + +bool RemoveDir(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::RemoveDirectory(fs2fas(path))) + return true; + } + else + #endif + { + IF_USE_MAIN_PATH + if (::RemoveDirectoryW(fs2us(path))) + return true; + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + return BOOLToBool(::RemoveDirectoryW(superPath)); + } + #endif + } + return false; +} + + +// When moving a directory, oldFile and newFile must be on the same drive. + +bool MyMoveFile(CFSTR oldFile, CFSTR newFile) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::MoveFile(fs2fas(oldFile), fs2fas(newFile))) + return true; + } + else + #endif + { + IF_USE_MAIN_PATH_2(oldFile, newFile) + { + if (::MoveFileW(fs2us(oldFile), fs2us(newFile))) + return true; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH_2) + { + UString d1, d2; + if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2)) + return BOOLToBool(::MoveFileW(d1, d2)); + } + #endif + } + return false; +} + +#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500 +static DWORD WINAPI CopyProgressRoutine_to_ICopyFileProgress( + LARGE_INTEGER TotalFileSize, // file size + LARGE_INTEGER TotalBytesTransferred, // bytes transferred + LARGE_INTEGER /* StreamSize */, // bytes in stream + LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream + DWORD /* dwStreamNumber */, // current stream + DWORD /* dwCallbackReason */, // callback reason + HANDLE /* hSourceFile */, // handle to source file + HANDLE /* hDestinationFile */, // handle to destination file + LPVOID lpData // from CopyFileEx +) +{ + return ((ICopyFileProgress *)lpData)->CopyFileProgress( + (UInt64)TotalFileSize.QuadPart, + (UInt64)TotalBytesTransferred.QuadPart); +} +#endif + +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress) +{ +#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500 +#ifndef _UNICODE + if (g_IsNT) +#endif + if (progress) + { + IF_USE_MAIN_PATH_2(oldFile, newFile) + { + if (::MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile), + CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED)) + return true; + if (::GetLastError() == ERROR_REQUEST_ABORTED) + return false; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH_2) + { + UString d1, d2; + if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2)) + return BOOLToBool(::MoveFileWithProgressW(d1, d2, + CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED)); + } + #endif + return false; + } +#else + UNUSED_VAR(progress) +#endif + return MyMoveFile(oldFile, newFile); +} + +#ifndef UNDER_CE +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000 +#define Z7_USE_DYN_CreateHardLink +#endif + +#ifdef Z7_USE_DYN_CreateHardLink +EXTERN_C_BEGIN +typedef BOOL (WINAPI *Func_CreateHardLinkW)( + LPCWSTR lpFileName, + LPCWSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes + ); +EXTERN_C_END +#endif +#endif // UNDER_CE + +bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + /* + if (::CreateHardLink(fs2fas(newFileName), fs2fas(existFileName), NULL)) + return true; + */ + } + else + #endif + { +#ifdef Z7_USE_DYN_CreateHardLink + const + Func_CreateHardLinkW + my_CreateHardLinkW = Z7_GET_PROC_ADDRESS( + Func_CreateHardLinkW, ::GetModuleHandleW(L"kernel32.dll"), + "CreateHardLinkW"); + if (!my_CreateHardLinkW) + return false; + #define MY_CreateHardLinkW my_CreateHardLinkW +#else + #define MY_CreateHardLinkW CreateHardLinkW +#endif + IF_USE_MAIN_PATH_2(newFileName, existFileName) + { + if (MY_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL)) + return true; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH_2) + { + UString d1, d2; + if (GetSuperPaths(newFileName, existFileName, d1, d2, USE_MAIN_PATH_2)) + return BOOLToBool(MY_CreateHardLinkW(d1, d2, NULL)); + } + #endif + } + return false; +} + + +/* +WinXP-64 CreateDir(): + "" - ERROR_PATH_NOT_FOUND + \ - ERROR_ACCESS_DENIED + C:\ - ERROR_ACCESS_DENIED, if there is such drive, + + D:\folder - ERROR_PATH_NOT_FOUND, if there is no such drive, + C:\nonExistent\folder - ERROR_PATH_NOT_FOUND + + C:\existFolder - ERROR_ALREADY_EXISTS + C:\existFolder\ - ERROR_ALREADY_EXISTS + + C:\folder - OK + C:\folder\ - OK + + \\Server\nonExistent - ERROR_BAD_NETPATH + \\Server\Share_Readonly - ERROR_ACCESS_DENIED + \\Server\Share - ERROR_ALREADY_EXISTS + + \\Server\Share_NTFS_drive - ERROR_ACCESS_DENIED + \\Server\Share_FAT_drive - ERROR_ALREADY_EXISTS +*/ + +bool CreateDir(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::CreateDirectory(fs2fas(path), NULL)) + return true; + } + else + #endif + { + IF_USE_MAIN_PATH + if (::CreateDirectoryW(fs2us(path), NULL)) + return true; + #ifdef Z7_LONG_PATH + if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + return BOOLToBool(::CreateDirectoryW(superPath, NULL)); + } + #endif + } + return false; +} + +/* + CreateDir2 returns true, if directory can contain files after the call (two cases): + 1) the directory already exists + 2) the directory was created + path must be WITHOUT trailing path separator. + + We need CreateDir2, since fileInfo.Find() for reserved names like "com8" + returns FILE instead of DIRECTORY. And we need to use SuperPath */ + +static bool CreateDir2(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + if (::CreateDirectory(fs2fas(path), NULL)) + return true; + } + else + #endif + { + IF_USE_MAIN_PATH + if (::CreateDirectoryW(fs2us(path), NULL)) + return true; + #ifdef Z7_LONG_PATH + if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + { + if (::CreateDirectoryW(superPath, NULL)) + return true; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return false; + NFind::CFileInfo fi; + if (!fi.Find(us2fs(superPath))) + return false; + return fi.IsDir(); + } + } + #endif + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return false; + NFind::CFileInfo fi; + if (!fi.Find(path)) + return false; + return fi.IsDir(); +} + +#endif // _WIN32 + +static bool CreateDir2(CFSTR path); + +bool CreateComplexDir(CFSTR _path) +{ + #ifdef _WIN32 + + { + const DWORD attrib = NFind::GetFileAttrib(_path); + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + return true; + } + + #ifndef UNDER_CE + + if (IsDriveRootPath_SuperAllowed(_path)) + return false; + + const unsigned prefixSize = GetRootPrefixSize(_path); + + #endif // UNDER_CE + + #else // _WIN32 + + // Posix + NFind::CFileInfo fi; + if (fi.Find(_path)) + { + if (fi.IsDir()) + return true; + } + + #endif // _WIN32 + + FString path (_path); + + int pos = path.ReverseFind_PathSepar(); + if (pos >= 0 && (unsigned)pos == path.Len() - 1) + { + if (path.Len() == 1) + return true; + path.DeleteBack(); + } + + const FString path2 (path); + pos = (int)path.Len(); + + for (;;) + { + if (CreateDir2(path)) + break; + if (::GetLastError() == ERROR_ALREADY_EXISTS) + return false; + pos = path.ReverseFind_PathSepar(); + if (pos < 0 || pos == 0) + return false; + + #if defined(_WIN32) && !defined(UNDER_CE) + if (pos == 1 && IS_PATH_SEPAR(path[0])) + return false; + if (prefixSize >= (unsigned)pos + 1) + return false; + #endif + + path.DeleteFrom((unsigned)pos); + } + + while (pos < (int)path2.Len()) + { + int pos2 = NName::FindSepar(path2.Ptr((unsigned)pos + 1)); + if (pos2 < 0) + pos = (int)path2.Len(); + else + pos += 1 + pos2; + path.SetFrom(path2, (unsigned)pos); + if (!CreateDir(path)) + return false; + } + + return true; +} + + +#ifdef _WIN32 + +bool DeleteFileAlways(CFSTR path) +{ + /* If alt stream, we also need to clear READ-ONLY attribute of main file before delete. + SetFileAttrib("name:stream", ) changes attributes of main file. */ + { + DWORD attrib = NFind::GetFileAttrib(path); + if (attrib != INVALID_FILE_ATTRIBUTES + && (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0 + && (attrib & FILE_ATTRIBUTE_READONLY) != 0) + { + if (!SetFileAttrib(path, attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY)) + return false; + } + } + + #ifndef _UNICODE + if (!g_IsNT) + { + if (::DeleteFile(fs2fas(path))) + return true; + } + else + #endif + { + /* DeleteFile("name::$DATA") deletes all alt streams (same as delete DeleteFile("name")). + Maybe it's better to open "name::$DATA" and clear data for unnamed stream? */ + IF_USE_MAIN_PATH + if (::DeleteFileW(fs2us(path))) + return true; + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + return BOOLToBool(::DeleteFileW(superPath)); + } + #endif + } + return false; +} + + + +bool RemoveDirWithSubItems(const FString &path) +{ + bool needRemoveSubItems = true; + { + NFind::CFileInfo fi; + if (!fi.Find(path)) + return false; + if (!fi.IsDir()) + { + ::SetLastError(ERROR_DIRECTORY); + return false; + } + if (fi.HasReparsePoint()) + needRemoveSubItems = false; + } + + if (needRemoveSubItems) + { + FString s (path); + s.Add_PathSepar(); + const unsigned prefixSize = s.Len(); + NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(s); + NFind::CDirEntry fi; + bool isError = false; + DWORD lastError = 0; + while (enumerator.Next(fi)) + { + s.DeleteFrom(prefixSize); + s += fi.Name; + if (fi.IsDir()) + { + if (!RemoveDirWithSubItems(s)) + { + lastError = GetLastError(); + isError = true; + } + } + else if (!DeleteFileAlways(s)) + { + lastError = GetLastError(); + isError = false; + } + } + if (isError) + { + SetLastError(lastError); + return false; + } + } + + // we clear read-only attrib to remove read-only dir + if (!SetFileAttrib(path, 0)) + return false; + return RemoveDir(path); +} + +bool RemoveDirAlways_if_Empty(const FString &path) +{ + const DWORD attrib = NFind::GetFileAttrib(path); + if (attrib != INVALID_FILE_ATTRIBUTES + && (attrib & FILE_ATTRIBUTE_READONLY)) + { + bool need_ClearAttrib = true; + if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) == 0) + { + FString s (path); + s.Add_PathSepar(); + NFind::CEnumerator enumerator; + enumerator.SetDirPrefix(s); + NFind::CDirEntry fi; + if (enumerator.Next(fi)) + { + // we don't want to change attributes, if there are files + // in directory, because RemoveDir(path) will fail. + need_ClearAttrib = false; + // SetLastError(ERROR_DIR_NOT_EMPTY); + // return false; + } + } + if (need_ClearAttrib) + SetFileAttrib(path, 0); // we clear read-only attrib to remove read-only dir + } + return RemoveDir(path); +} + +#endif // _WIN32 + +#ifdef UNDER_CE + +bool MyGetFullPathName(CFSTR path, FString &resFullPath) +{ + resFullPath = path; + return true; +} + +#else + +bool MyGetFullPathName(CFSTR path, FString &resFullPath) +{ + return GetFullPath(path, resFullPath); +} + +#ifdef _WIN32 + +/* Win10: SetCurrentDirectory() doesn't support long paths and + doesn't support super prefix "\\?\", if long path behavior is not + enabled in registry (LongPathsEnabled) and in manifest (longPathAware). */ + +bool SetCurrentDir(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + return BOOLToBool(::SetCurrentDirectory(fs2fas(path))); + } + else + #endif + { + return BOOLToBool(::SetCurrentDirectoryW(fs2us(path))); + } +} + + +/* +we use system function GetCurrentDirectory() +new GetCurrentDirectory() DOCs: + - If the function fails, the return value is zero. + - If the function succeeds, the return value specifies + the number of characters that are written to the buffer, + not including the terminating null character. + - If the buffer is not large enough, the return value specifies + the required size of the buffer, in characters, + including the null-terminating character. + +GetCurrentDir() calls GetCurrentDirectory(). +GetCurrentDirectory() in win10 in tests: + the returned (path) does not end with a backslash, if + current directory is not root directory of drive. + But that behavior is not guarantied in specification docs. +*/ + +bool GetCurrentDir(FString &path) +{ + const unsigned kBufSize = MAX_PATH + 16; + path.Empty(); + + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[kBufSize + 1]; + s[0] = 0; + const DWORD len = ::GetCurrentDirectory(kBufSize, s); + if (len == 0 || len >= kBufSize) + return false; + s[kBufSize] = 0; // optional guard + path = fas2fs(s); + return true; + } + else + #endif + { + DWORD len; + { + WCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetCurrentDirectoryW(kBufSize, s); + if (len == 0) + return false; + if (len < kBufSize) + { + s[kBufSize] = 0; // optional guard + path = us2fs(s); + return true; + } + } + UString temp; + const DWORD len2 = ::GetCurrentDirectoryW(len, temp.GetBuf(len)); + if (len2 == 0) + return false; + temp.ReleaseBuf_CalcLen(len); + if (temp.Len() != len2 || len - 1 != len2) + { + /* it's unexpected case, if current dir of process + was changed between two function calls, + or some unexpected function implementation */ + // SetLastError((DWORD)E_FAIL); // we can set some error code + return false; + } + path = us2fs(temp); + return true; + } +} + +#endif // _WIN32 +#endif // UNDER_CE + + +bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName) +{ + bool res = MyGetFullPathName(path, resDirPrefix); + if (!res) + resDirPrefix = path; + int pos = resDirPrefix.ReverseFind_PathSepar(); + pos++; + resFileName = resDirPrefix.Ptr((unsigned)pos); + resDirPrefix.DeleteFrom((unsigned)pos); + return res; +} + +bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix) +{ + FString resFileName; + return GetFullPathAndSplit(path, resDirPrefix, resFileName); +} + + + +bool MyGetTempPath(FString &path) +{ + #ifdef _WIN32 + + /* + new DOCs for GetTempPathW(): + - The returned string ends with a backslash. + - The maximum possible return value is MAX_PATH+1 (261). + */ + + const unsigned kBufSize = MAX_PATH + 16; + DWORD len; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetTempPath(kBufSize, s); + path = fas2fs(s); + } + else + #endif + { + WCHAR s[kBufSize + 1]; + s[0] = 0; + len = ::GetTempPathW(kBufSize, s); + path = us2fs(s); + } + /* win10: GetTempPathW() doesn't set backslash at the end of path, + if (buffer_size == len_of(path_with_backslash)). + So we normalize path here: */ + NormalizeDirPathPrefix(path); + return (len != 0 && len < kBufSize); + + #else // !_WIN32 + + // FIXME: improve that code + path = STRING_PATH_SEPARATOR "tmp"; + const char *s; + if (NFind::DoesDirExist_FollowLink(path)) + s = STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR; + else + s = "." STRING_PATH_SEPARATOR; + path = s; + return true; + + #endif +} + + +bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFile *outFile) +{ + UInt32 d = + #ifdef _WIN32 + (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId(); + #else + (UInt32)(time(NULL) << 12) ^ ((UInt32)getppid() << 14) ^ (UInt32)(getpid()); + #endif + + for (unsigned i = 0; i < 100; i++) + { + postfix.Empty(); + if (addRandom) + { + char s[16]; + UInt32 val = d; + unsigned k; + for (k = 0; k < 8; k++) + { + const unsigned t = (unsigned)val & 0xF; + val >>= 4; + s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); + } + s[k] = '\0'; + if (outFile) + postfix.Add_Dot(); + postfix += s; + UInt32 step = GetTickCount() + 2; + if (step == 0) + step = 1; + d += step; + } + addRandom = true; + if (outFile) + postfix += ".tmp"; + FString path (prefix); + path += postfix; + if (NFind::DoesFileOrDirExist(path)) + { + SetLastError(ERROR_ALREADY_EXISTS); + continue; + } + if (outFile) + { + if (outFile->Create_NEW(path)) + return true; + } + else + { + if (CreateDir(path)) + return true; + } + const DWORD error = GetLastError(); + if (error != ERROR_FILE_EXISTS && + error != ERROR_ALREADY_EXISTS) + break; + } + postfix.Empty(); + return false; +} + +bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile) +{ + if (!Remove()) + return false; + _path.Empty(); + AString postfix; + if (!CreateTempFile2(prefix, false, postfix, outFile)) + return false; + _path = prefix; + _path += postfix; + _mustBeDeleted = true; + return true; +} + +bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile) +{ + if (!Remove()) + return false; + _path.Empty(); + FString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + AString postfix; + tempPath += namePrefix; + if (!CreateTempFile2(tempPath, true, postfix, outFile)) + return false; + _path = tempPath; + _path += postfix; + _mustBeDeleted = true; + return true; +} + +bool CTempFile::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !DeleteFileAlways(_path); + return !_mustBeDeleted; +} + +bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore, + ICopyFileProgress *progress) +{ + if (deleteDestBefore) + { + if (NFind::DoesFileExist_Raw(name)) + { + // attrib = NFind::GetFileAttrib(name); + if (!DeleteFileAlways(name)) + return false; + } + } + DisableDeleting(); + // if (!progress) return MyMoveFile(_path, name); + return MyMoveFile_with_Progress(_path, name, progress); + /* + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) + { + DWORD attrib2 = NFind::GetFileAttrib(name); + if (attrib2 != INVALID_FILE_ATTRIBUTES) + SetFileAttrib(name, attrib2 | FILE_ATTRIBUTE_READONLY); + } + */ +} + +#ifdef _WIN32 +bool CTempDir::Create(CFSTR prefix) +{ + if (!Remove()) + return false; + _path.Empty(); + FString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + tempPath += prefix; + AString postfix; + if (!CreateTempFile2(tempPath, true, postfix, NULL)) + return false; + _path = tempPath; + _path += postfix; + _mustBeDeleted = true; + return true; +} + +bool CTempDir::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !RemoveDirWithSubItems(_path); + return !_mustBeDeleted; +} +#endif + + + +#ifndef _WIN32 + +bool RemoveDir(CFSTR path) +{ + return (rmdir(path) == 0); +} + + +static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progress) +{ + { + NIO::COutFile outFile; + if (!outFile.Create_NEW(newFile)) + return FALSE; + NIO::CInFile inFile; + if (!inFile.Open(oldFile)) + return FALSE; + + const size_t k_BufSize = 1 << 16; + CAlignedBuffer1 buf(k_BufSize); + + UInt64 length = 0; + if (progress && !inFile.GetLength(length)) + length = 0; + UInt64 prev = 0; + UInt64 cur = 0; + for (;;) + { + const ssize_t num = inFile.read_part(buf, k_BufSize); + if (num == 0) + return TRUE; + if (num < 0) + break; + size_t processed; + const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed); + if (num2 != num || processed != (size_t)num) + break; + cur += (size_t)num2; + if (progress && cur - prev >= (1u << 20)) + { + prev = cur; + if (progress->CopyFileProgress(length, cur) != PROGRESS_CONTINUE) + { + errno = EINTR; // instead of WIN32::ERROR_REQUEST_ABORTED + break; + } + } + } + } + // There is file IO error or process was interrupted by user. + // We close output file and delete it. + // DeleteFileAlways doesn't change errno (if successed), but we restore errno. + const int errno_save = errno; + DeleteFileAlways(newFile); + errno = errno_save; + return FALSE; +} + + +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress) +{ + int res = rename(oldFile, newFile); + if (res == 0) + return true; + if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem) + return false; + + if (My_CopyFile(oldFile, newFile, progress) == FALSE) + return false; + + struct stat info_file; + res = stat(oldFile, &info_file); + if (res != 0) + return false; + + /* + ret = chmod(dst,info_file.st_mode & g_umask.mask); + */ + return (unlink(oldFile) == 0); +} + +bool MyMoveFile(CFSTR oldFile, CFSTR newFile) +{ + return MyMoveFile_with_Progress(oldFile, newFile, NULL); +} + + +bool CreateDir(CFSTR path) +{ + return (mkdir(path, 0777) == 0); // change it +} + +static bool CreateDir2(CFSTR path) +{ + return (mkdir(path, 0777) == 0); // change it +} + + +bool DeleteFileAlways(CFSTR path) +{ + return (remove(path) == 0); +} + +bool SetCurrentDir(CFSTR path) +{ + return (chdir(path) == 0); +} + + +bool GetCurrentDir(FString &path) +{ + path.Empty(); + + #define MY_PATH_MAX PATH_MAX + // #define MY_PATH_MAX 1024 + + char s[MY_PATH_MAX + 1]; + char *res = getcwd(s, MY_PATH_MAX); + if (res) + { + path = fas2fs(s); + return true; + } + { + // if (errno != ERANGE) return false; + #if defined(__GLIBC__) || defined(__APPLE__) + /* As an extension to the POSIX.1-2001 standard, glibc's getcwd() + allocates the buffer dynamically using malloc(3) if buf is NULL. */ + res = getcwd(NULL, 0); + if (res) + { + path = fas2fs(res); + ::free(res); + return true; + } + #endif + return false; + } +} + + + +// #undef UTIME_OMIT // to debug + +#ifndef UTIME_OMIT + /* we can define UTIME_OMIT for debian and another systems. + Is it OK to define UTIME_OMIT to -2 here, if UTIME_OMIT is not defined? */ + // #define UTIME_OMIT -2 +#endif + + + + + +bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) +{ + // need testing + /* + struct utimbuf buf; + struct stat st; + UNUSED_VAR(cTime) + + printf("\nstat = %s\n", path); + int ret = stat(path, &st); + + if (ret == 0) + { + buf.actime = st.st_atime; + buf.modtime = st.st_mtime; + } + else + { + time_t cur_time = time(0); + buf.actime = cur_time; + buf.modtime = cur_time; + } + + if (aTime) + { + UInt32 ut; + if (NTime::FileTimeToUnixTime(*aTime, ut)) + buf.actime = ut; + } + + if (mTime) + { + UInt32 ut; + if (NTime::FileTimeToUnixTime(*mTime, ut)) + buf.modtime = ut; + } + + return utime(path, &buf) == 0; + */ + + // if (!aTime && !mTime) return true; + + struct timespec times[2]; + UNUSED_VAR(cTime) + + bool needChange; + 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; +} + + + +struct C_umask +{ + mode_t mask; + + C_umask() + { + /* by security reasons we restrict attributes according + with process's file mode creation mask (umask) */ + const mode_t um = umask(0); // octal :0022 is expected + mask = 0777 & (~um); // octal: 0755 is expected + umask(um); // restore the umask + // printf("\n umask = 0%03o mask = 0%03o\n", um, mask); + + // mask = 0777; // debug we can disable the restriction: + } +}; + +static C_umask g_umask; + +// #define PRF(x) x; +#define PRF(x) + +#define TRACE_SetFileAttrib(msg) \ + PRF(printf("\nSetFileAttrib(%s, %x) : %s\n", (const char *)path, attrib, msg);) + +#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) +{ + TRACE_SetFileAttrib("") + + struct stat st; + + bool use_lstat = true; + if (use_lstat) + { + if (lstat(path, &st) != 0) + { + TRACE_SetFileAttrib("bad lstat()") + return false; + } + // TRACE_chmod("lstat", st.st_mode); + } + else + { + if (stat(path, &st) != 0) + { + TRACE_SetFileAttrib("bad stat()") + return false; + } + } + + if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) + { + TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION") + st.st_mode = attrib >> 16; + if (S_ISDIR(st.st_mode)) + { + // user/7z must be able to create files in this directory + st.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR); + } + else if (!S_ISREG(st.st_mode)) + return true; + } + else if (S_ISLNK(st.st_mode)) + { + /* for most systems: permissions for symlinks are fixed to rwxrwxrwx. + so we don't need chmod() for symlinks. */ + return true; + // SetLastError(ENOSYS); + // return false; + } + else + { + TRACE_SetFileAttrib("Only Windows Attributes") + // Only Windows Attributes + if (S_ISDIR(st.st_mode) + || (attrib & FILE_ATTRIBUTE_READONLY) == 0) + return true; + st.st_mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions + } + + int res; + /* + if (S_ISLNK(st.st_mode)) + { + printf("\nfchmodat()\n"); + TRACE_chmod(path, (st.st_mode) & g_umask.mask) + // AT_SYMLINK_NOFOLLOW is not implemted still in Linux. + res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask, + S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0); + } + else + */ + { + TRACE_chmod(path, (st.st_mode) & g_umask.mask) + res = chmod(path, (st.st_mode) & g_umask.mask); + } + // TRACE_SetFileAttrib("End") + return (res == 0); +} + + +bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) +{ + PRF(printf("\nhard link() %s -> %s\n", newFileName, existFileName);) + return (link(existFileName, newFileName) == 0); +} + +#endif // !_WIN32 + +// #endif + +}}} diff -Nru p7zip-rar-16.02/CPP/Windows/FileDir.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.h --- p7zip-rar-16.02/CPP/Windows/FileDir.h 2016-03-23 19:33:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileDir.h 2024-11-30 20:00:00.000000000 +0000 @@ -1,137 +1,161 @@ -// Windows/FileDir.h - -#ifndef __WINDOWS_FILE_DIR_H -#define __WINDOWS_FILE_DIR_H - -#include "../Common/MyString.h" -#include "../Common/MyVector.h" - -#include "FileIO.h" - -#ifdef ENV_UNIX -#include // ino_t -#endif - -namespace NWindows { -namespace NFile { -namespace NDir { - -class CDelayedSymLink; - -bool GetWindowsDir(FString &path); -bool GetSystemDir(FString &path); - -bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime); -bool SetFileAttrib(CFSTR path, DWORD attrib, CObjectVector *delayedSymLinks = 0); -bool MyMoveFile(CFSTR existFileName, CFSTR newFileName); - -#ifndef UNDER_CE -bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName); -#endif - -bool RemoveDir(CFSTR path); -bool CreateDir(CFSTR path); - -/* CreateComplexDir returns true, if directory can contain files after the call (two cases): - 1) the directory already exists (network shares and drive paths are supported) - 2) the directory was created - path can be WITH or WITHOUT trailing path separator. */ - -bool CreateComplexDir(CFSTR path); - -bool DeleteFileAlways(CFSTR name); -bool RemoveDirWithSubItems(const FString &path); - -bool MyGetFullPathName(CFSTR path, FString &resFullPath); -bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName); -bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix); - -#ifndef UNDER_CE - -bool SetCurrentDir(CFSTR path); -bool GetCurrentDir(FString &resultPath); - -#endif - -bool MyGetTempPath(FString &resultPath); - -class CTempFile -{ - bool _mustBeDeleted; - FString _path; - void DisableDeleting() { _mustBeDeleted = false; } -public: - CTempFile(): _mustBeDeleted(false) {} - ~CTempFile() { Remove(); } - const FString &GetPath() const { return _path; } - bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix - bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile); - bool Remove(); - bool MoveTo(CFSTR name, bool deleteDestBefore); -}; - -class CTempDir -{ - bool _mustBeDeleted; - FString _path; -public: - CTempDir(): _mustBeDeleted(false) {} - ~CTempDir() { Remove(); } - const FString &GetPath() const { return _path; } - void DisableDeleting() { _mustBeDeleted = false; } - bool Create(CFSTR namePrefix) ; - bool Remove(); -}; - -// Symbolic links must be created last so that they can't be used to -// create or overwrite files above the extraction directory. -class CDelayedSymLink -{ -#ifdef ENV_UNIX - // Where the symlink should be created. The target is specified in - // the placeholder file. - AString _source; - - // Device and inode of the placeholder file. Before creating the - // symlink, we must check that these haven't been changed by creation - // of another symlink. - dev_t _dev; - ino_t _ino; - -public: - explicit CDelayedSymLink(const char * source); - bool Create(); -#else // !ENV_UNIX -public: - CDelayedSymLink(const char * source) {} - bool Create() { return true; } -#endif // ENV_UNIX -}; - - -#if !defined(UNDER_CE) -class CCurrentDirRestorer -{ - FString _path; -public: - bool NeedRestore; - - CCurrentDirRestorer(): NeedRestore(true) - { - GetCurrentDir(_path); - } - ~CCurrentDirRestorer() - { - if (!NeedRestore) - return; - FString s; - if (GetCurrentDir(s)) - if (s != _path) - SetCurrentDir(_path); - } -}; -#endif - -}}} - -#endif +// Windows/FileDir.h + +#ifndef ZIP7_INC_WINDOWS_FILE_DIR_H +#define ZIP7_INC_WINDOWS_FILE_DIR_H + +#include "../Common/MyString.h" + +#include "FileIO.h" + +namespace NWindows { +namespace NFile { +namespace NDir { + +bool GetWindowsDir(FString &path); +bool GetSystemDir(FString &path); + +/* +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 + +bool SetFileAttrib(CFSTR path, DWORD attrib); + +/* + Some programs store posix attributes in high 16 bits of windows attributes field. + Also some programs use additional flag markers: 0x8000 or 0x4000. + 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 + +bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib); + + +#ifndef _WIN32 +#define PROGRESS_CONTINUE 0 +#define PROGRESS_CANCEL 1 +// #define PROGRESS_STOP 2 +// #define PROGRESS_QUIET 3 +#endif +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(ICopyFileProgress) +{ + // in: total, current: include all/processed alt streams. + // it returns PROGRESS_CONTINUE or PROGRESS_CANCEL. + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) = 0; +}; +Z7_PURE_INTERFACES_END + +bool MyMoveFile(CFSTR existFileName, CFSTR newFileName); +// (progress == NULL) is allowed +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress); + + +#ifndef UNDER_CE +bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName); +#endif + +bool RemoveDir(CFSTR path); +bool CreateDir(CFSTR path); + +/* CreateComplexDir returns true, if directory can contain files after the call (two cases): + 1) the directory already exists (network shares and drive paths are supported) + 2) the directory was created + path can be WITH or WITHOUT trailing path separator. */ + +bool CreateComplexDir(CFSTR path); + +bool DeleteFileAlways(CFSTR name); +bool RemoveDirWithSubItems(const FString &path); +#ifdef _WIN32 +bool RemoveDirAlways_if_Empty(const FString &path); +#else +#define RemoveDirAlways_if_Empty RemoveDir +#endif + +bool MyGetFullPathName(CFSTR path, FString &resFullPath); +bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName); +bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix); + +#ifndef UNDER_CE + +bool SetCurrentDir(CFSTR path); +bool GetCurrentDir(FString &resultPath); + +#endif + +bool MyGetTempPath(FString &resultPath); + +bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFile *outFile); + +class CTempFile MY_UNCOPYABLE +{ + bool _mustBeDeleted; + FString _path; + void DisableDeleting() { _mustBeDeleted = false; } +public: + CTempFile(): _mustBeDeleted(false) {} + ~CTempFile() { Remove(); } + const FString &GetPath() const { return _path; } + bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix + bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile); + bool Remove(); + // bool MoveTo(CFSTR name, bool deleteDestBefore); + bool MoveTo(CFSTR name, bool deleteDestBefore, + ICopyFileProgress *progress); +}; + + +#ifdef _WIN32 +class CTempDir MY_UNCOPYABLE +{ + bool _mustBeDeleted; + FString _path; +public: + CTempDir(): _mustBeDeleted(false) {} + ~CTempDir() { Remove(); } + const FString &GetPath() const { return _path; } + void DisableDeleting() { _mustBeDeleted = false; } + bool Create(CFSTR namePrefix) ; + bool Remove(); +}; +#endif + + +#if !defined(UNDER_CE) +class CCurrentDirRestorer MY_UNCOPYABLE +{ + FString _path; +public: + bool NeedRestore; + + CCurrentDirRestorer(): NeedRestore(true) + { + GetCurrentDir(_path); + } + ~CCurrentDirRestorer() + { + if (!NeedRestore) + return; + FString s; + if (GetCurrentDir(s)) + if (s != _path) + SetCurrentDir(_path); + } +}; +#endif + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileFind.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.cpp --- p7zip-rar-16.02/CPP/Windows/FileFind.cpp 2015-11-09 14:30:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.cpp 2025-06-20 11:00:00.000000000 +0000 @@ -1,595 +1,1449 @@ -// Windows/FileFind.cpp - -#include "StdAfx.h" - -#include "FileFind.h" -#include "FileIO.h" - -#include "../Common/StringConvert.h" - - -#ifndef _UNICODE -extern bool g_IsNT; -#endif - -#include -#include -#include - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" - -// #define TRACEN(u) u; -#define TRACEN(u) /* */ - -void my_windows_split_path(const AString &p_path, AString &dir , AString &base) { - int pos = p_path.ReverseFind('/'); - if (pos == -1) { - // no separator - dir = "."; - if (p_path.IsEmpty()) - base = "."; - else - base = p_path; - } else if ((pos+1) < p_path.Len()) { - // true separator - base = p_path.Ptr(pos+1); - while ((pos >= 1) && (p_path[pos-1] == '/')) - pos--; - if (pos == 0) - dir = "/"; - else - dir = p_path.Left(pos); - } else { - // separator at the end of the path - // pos = p_path.find_last_not_of("/"); - pos = -1; - int ind = 0; - while (p_path[ind]) { - if (p_path[ind] != '/') - pos = ind; - ind++; - } - if (pos == -1) { - base = "/"; - dir = "/"; - } else { - my_windows_split_path(p_path.Left(pos+1),dir,base); - } - } -} - -static void my_windows_split_path(const UString &p_path, UString &dir , UString &base) { - int pos = p_path.ReverseFind(L'/'); - if (pos == -1) { - // no separator - dir = L"."; - if (p_path.IsEmpty()) - base = L"."; - else - base = p_path; - } else if ((pos+1) < p_path.Len()) { - // true separator - base = p_path.Ptr(pos+1); - while ((pos >= 1) && (p_path[pos-1] == L'/')) - pos--; - if (pos == 0) - dir = L"/"; - else - dir = p_path.Left(pos); - } else { - // separator at the end of the path - // pos = p_path.find_last_not_of("/"); - pos = -1; - int ind = 0; - while (p_path[ind]) { - if (p_path[ind] != L'/') - pos = ind; - ind++; - } - if (pos == -1) { - base = L"/"; - dir = L"/"; - } else { - my_windows_split_path(p_path.Left(pos+1),dir,base); - } - } -} - -static int filter_pattern(const char *string , const char *pattern , int flags_nocase) { - if ((string == 0) || (*string==0)) { - if (pattern == 0) - return 1; - while (*pattern=='*') - ++pattern; - return (!*pattern); - } - - switch (*pattern) { - case '*': - if (!filter_pattern(string+1,pattern,flags_nocase)) - return filter_pattern(string,pattern+1,flags_nocase); - return 1; - case 0: - if (*string==0) - return 1; - break; - case '?': - return filter_pattern(string+1,pattern+1,flags_nocase); - default: - if ( ((flags_nocase) && (tolower(*pattern)==tolower(*string))) - || (*pattern == *string) - ) { - return filter_pattern(string+1,pattern+1,flags_nocase); - } - break; - } - return 0; -} - -namespace NWindows { -namespace NFile { - -#ifdef SUPPORT_DEVICE_FILE -bool IsDeviceName(CFSTR n); -#endif - -#if defined(WIN_LONG_PATH) -bool GetLongPath(CFSTR fileName, UString &res); -#endif - -namespace NFind { - -bool CFileInfo::IsDots() const throw() -{ - if (!IsDir() || Name.IsEmpty()) - return false; - if (Name[0] != FTEXT('.')) - return false; - return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == FTEXT('.')); -} - -#define WIN_FD_TO_MY_FI(fi, fd) \ - fi.Attrib = fd.dwFileAttributes; \ - fi.CTime = fd.ftCreationTime; \ - fi.ATime = fd.ftLastAccessTime; \ - fi.MTime = fd.ftLastWriteTime; \ - fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \ - fi.IsDevice = false; - - /* - #ifdef UNDER_CE - fi.ObjectID = fd.dwOID; - #else - fi.ReparseTag = fd.dwReserved0; - #endif - */ - -#ifndef _UNICODE - -static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } - -static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi) -{ - WIN_FD_TO_MY_FI(fi, fd); - fi.Name = fas2fs(fd.cFileName); -} -#endif - -//////////////////////////////// -// CFindFile - -bool CFindFile::Close() -{ - if(_dirp == 0) - return true; - int ret = closedir(_dirp); - if (ret == 0) - { - _dirp = 0; - return true; - } - return false; -} - - -static bool originalFilename(const UString & src, AString & res) -{ - // Try to recover the original filename - res = ""; - int i=0; - while (src[i]) - { - if (src[i] >= 256) { - return false; - } else { - res += char(src[i]); - } - i++; - } - return true; -} - -// Warning this function cannot update "fileInfo.Name" -static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename,bool ignoreLink) { - struct stat stat_info; - - int ret; -#ifdef ENV_HAVE_LSTAT - if ( (global_use_lstat) && (ignoreLink == false)) { - ret = lstat(filename,&stat_info); - } else -#endif - { - ret = stat(filename,&stat_info); - } - - // printf("fillin_CFileInfo(%s,%d)=%d mode=%o\n",filename,(int)ignoreLink,ret,(unsigned)stat_info.st_mode); - - - if (ret != 0) return ret; - - /* FIXME : FILE_ATTRIBUTE_HIDDEN ? */ - if (S_ISDIR(stat_info.st_mode)) { - fileInfo.Attrib = FILE_ATTRIBUTE_DIRECTORY; - } else { - fileInfo.Attrib = FILE_ATTRIBUTE_ARCHIVE; - } - - if (!(stat_info.st_mode & S_IWUSR)) - fileInfo.Attrib |= FILE_ATTRIBUTE_READONLY; - - fileInfo.Attrib |= FILE_ATTRIBUTE_UNIX_EXTENSION + ((stat_info.st_mode & 0xFFFF) << 16); - - RtlSecondsSince1970ToFileTime( stat_info.st_ctime, &fileInfo.CTime ); - RtlSecondsSince1970ToFileTime( stat_info.st_mtime, &fileInfo.MTime ); - RtlSecondsSince1970ToFileTime( stat_info.st_atime, &fileInfo.ATime ); - - fileInfo.IsDevice = false; - - if (S_ISDIR(stat_info.st_mode)) { - fileInfo.Size = 0; - } else { // file or symbolic link - fileInfo.Size = stat_info.st_size; // for a symbolic link, size = size of filename - } - return 0; -} - -static int fillin_CFileInfo(CFileInfo &fi,const char *dir,const char *name,bool ignoreLink) { - char filename[MAX_PATHNAME_LEN]; - size_t dir_len = strlen(dir); - size_t name_len = strlen(name); - size_t total = dir_len + 1 + name_len + 1; // 1 = strlen("/"); + le zero character - if (total >= MAX_PATHNAME_LEN) throw "fillin_CFileInfo - internal error - MAX_PATHNAME_LEN"; - memcpy(filename,dir,dir_len); - if (dir_len >= 1) - { - if (filename[dir_len-1] == CHAR_PATH_SEPARATOR) - { // delete the '/' - dir_len--; - } - } - filename[dir_len] = CHAR_PATH_SEPARATOR; - memcpy(filename+(dir_len+1),name,name_len+1); // copy also final '\0' - -#ifdef _UNICODE - fi.Name = GetUnicodeString(name, CP_ACP); -#else - fi.Name = name; -#endif - - int ret = fillin_CFileInfo(fi,filename,ignoreLink); - if (ret != 0) { - AString err_msg = "stat error for "; - err_msg += filename; - err_msg += " ("; - err_msg += strerror(errno); - err_msg += ")"; - throw err_msg; - } - return ret; -} - -bool CFindFile::FindFirst(CFSTR cfWildcard, CFileInfo &fi, bool ignoreLink) -{ - if (!Close()) - return false; - - AString Awildcard = UnicodeStringToMultiByte(cfWildcard, CP_ACP); - const char * wildcard = (const char *)Awildcard; - - - if ((!wildcard) || (wildcard[0]==0)) { - SetLastError(ERROR_PATH_NOT_FOUND); - return false; - } - - my_windows_split_path(nameWindowToUnix(wildcard),_directory,_pattern); - - TRACEN((printf("CFindFile::FindFirst : %s (dirname=%s,pattern=%s)\n",wildcard,(const char *)_directory,(const char *)_pattern))) - - _dirp = ::opendir((const char *)_directory); - TRACEN((printf("CFindFile::FindFirst : opendir=%p\n",_dirp))) - - if ((_dirp == 0) && (global_use_utf16_conversion)) { - // Try to recover the original filename - UString ustr = MultiByteToUnicodeString(_directory, 0); - AString resultString; - bool is_good = originalFilename(ustr, resultString); - if (is_good) { - _dirp = ::opendir((const char *)resultString); - _directory = resultString; - } - } - - if (_dirp == 0) return false; - - struct dirent *dp; - while ((dp = readdir(_dirp)) != NULL) { - if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) { - int retf = fillin_CFileInfo(fi,(const char *)_directory,dp->d_name,ignoreLink); - if (retf) - { - TRACEN((printf("CFindFile::FindFirst : closedir-1(dirp=%p)\n",_dirp))) - closedir(_dirp); - _dirp = 0; - SetLastError( ERROR_NO_MORE_FILES ); - return false; - } - TRACEN((printf("CFindFile::FindFirst -%s- true\n",dp->d_name))) - return true; - } - } - - TRACEN((printf("CFindFile::FindFirst : closedir-2(dirp=%p)\n",_dirp))) - closedir(_dirp); - _dirp = 0; - SetLastError( ERROR_NO_MORE_FILES ); - return false; - -} - -bool CFindFile::FindNext(CFileInfo &fi) -{ - if (_dirp == 0) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - - struct dirent *dp; - while ((dp = readdir(_dirp)) != NULL) { - if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) { - int retf = fillin_CFileInfo(fi,(const char *)_directory,dp->d_name,false); - if (retf) - { - TRACEN((printf("FindNextFileA -%s- ret_handle=FALSE (errno=%d)\n",dp->d_name,errno))) - return false; - - } - TRACEN((printf("FindNextFileA -%s- true\n",dp->d_name))) - return true; - } - } - TRACEN((printf("FindNextFileA ret_handle=FALSE (ERROR_NO_MORE_FILES)\n"))) - SetLastError( ERROR_NO_MORE_FILES ); - return false; -} - -#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0; - -void CFileInfoBase::ClearBase() throw() -{ - Size = 0; - MY_CLEAR_FILETIME(CTime); - MY_CLEAR_FILETIME(ATime); - MY_CLEAR_FILETIME(MTime); - Attrib = 0; - IsAltStream = false; - IsDevice = false; -} - -bool CFileInfo::Find(CFSTR wildcard, bool ignoreLink) -{ - #ifdef SUPPORT_DEVICE_FILE - if (IsDeviceName(wildcard)) - { - Clear(); - IsDevice = true; - NIO::CInFile inFile; - if (!inFile.Open(wildcard)) - return false; - Name = wildcard + 4; - if (inFile.LengthDefined) - Size = inFile.Length; - return true; - } - #endif - CFindFile finder; - if (finder.FindFirst(wildcard, *this,ignoreLink)) - return true; - #ifdef _WIN32 - { - DWORD lastError = GetLastError(); - if (lastError == ERROR_BAD_NETPATH || lastError == ERROR_FILE_NOT_FOUND) - { - int len = MyStringLen(wildcard); - if (len > 2 && wildcard[0] == '\\' && wildcard[1] == '\\') - { - int pos = FindCharPosInString(wildcard + 2, FTEXT('\\')); - if (pos >= 0) - { - pos += 2 + 1; - len -= pos; - CFSTR remString = wildcard + pos; - int pos2 = FindCharPosInString(remString, FTEXT('\\')); - FString s = wildcard; - if (pos2 < 0 || pos2 == len - 1) - { - FString s = wildcard; - if (pos2 < 0) - { - pos2 = len; - s += FTEXT('\\'); - } - s += FCHAR_ANY_MASK; - if (finder.FindFirst(s, *this)) - if (Name == FTEXT(".")) - { - Name.SetFrom(s.Ptr(pos), pos2); - return true; - } - ::SetLastError(lastError); - } - } - } - } - } - #endif - return false; -} - -bool DoesFileExist(CFSTR name) -{ - CFileInfo fi; - return fi.Find(name) && !fi.IsDir(); -} - -bool DoesDirExist(CFSTR name) -{ - CFileInfo fi; - return fi.Find(name) && fi.IsDir(); -} -bool DoesFileOrDirExist(CFSTR name) -{ - CFileInfo fi; - return fi.Find(name); -} - -bool CEnumerator::NextAny(CFileInfo &fi) -{ - if (_findFile.IsHandleAllocated()) - return _findFile.FindNext(fi); - else - return _findFile.FindFirst(_wildcard, fi); -} - -bool CEnumerator::Next(CFileInfo &fi) -{ - for (;;) - { - if (!NextAny(fi)) - return false; - if (!fi.IsDots()) - return true; - } -} - -bool CEnumerator::Next(CFileInfo &fi, bool &found) -{ - if (Next(fi)) - { - found = true; - return true; - } - found = false; - return (::GetLastError() == ERROR_NO_MORE_FILES); -} - -//////////////////////////////// -// CFindChangeNotification -// FindFirstChangeNotification can return 0. MSDN doesn't tell about it. - -#ifdef _WIN32 -bool CFindChangeNotification::Close() -{ - if (!IsHandleAllocated()) - return true; - if (!::FindCloseChangeNotification(_handle)) - return false; - _handle = INVALID_HANDLE_VALUE; - return true; -} - -HANDLE CFindChangeNotification::FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter) -{ - #ifndef _UNICODE - if (!g_IsNT) - _handle = ::FindFirstChangeNotification(fs2fas(pathName), BoolToBOOL(watchSubtree), notifyFilter); - else - #endif - { - _handle = ::FindFirstChangeNotificationW(fs2us(pathName), BoolToBOOL(watchSubtree), notifyFilter); - #ifdef WIN_LONG_PATH - if (!IsHandleAllocated()) - { - UString longPath; - if (GetLongPath(pathName, longPath)) - _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter); - } - #endif - } - return _handle; -} - -#ifndef UNDER_CE - -bool MyGetLogicalDriveStrings(CObjectVector &driveStrings) -{ - driveStrings.Clear(); - #ifndef _UNICODE - if (!g_IsNT) - { - driveStrings.Clear(); - UINT32 size = GetLogicalDriveStrings(0, NULL); - if (size == 0) - return false; - AString buf; - UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size)); - if (newSize == 0 || newSize > size) - return false; - AString s; - for (UINT32 i = 0; i < newSize; i++) - { - char c = buf[i]; - if (c == '\0') - { - driveStrings.Add(fas2fs(s)); - s.Empty(); - } - else - s += c; - } - return s.IsEmpty(); - } - else - #endif - { - UINT32 size = GetLogicalDriveStringsW(0, NULL); - if (size == 0) - return false; - UString buf; - UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size)); - if (newSize == 0 || newSize > size) - return false; - UString s; - for (UINT32 i = 0; i < newSize; i++) - { - WCHAR c = buf[i]; - if (c == L'\0') - { - driveStrings.Add(us2fs(s)); - s.Empty(); - } - else - s += c; - } - return s.IsEmpty(); - } -} - -#endif - -#endif // _WIN32 - -}}} +// Windows/FileFind.cpp + +#include "StdAfx.h" + +// #include + +#ifndef _WIN32 +#include /* Definition of AT_* constants */ +#include "TimeUtils.h" +// for major +// #include +#endif + +#include "FileFind.h" +#include "FileIO.h" +#include "FileName.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +#if defined(_WIN32) && !defined(UNDER_CE) + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0502 // Win2003 +#define Z7_USE_DYN_FindFirstStream +#endif + +#ifdef Z7_USE_DYN_FindFirstStream + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +EXTERN_C_BEGIN + +typedef enum +{ + My_FindStreamInfoStandard, + My_FindStreamInfoMaxInfoLevel +} MY_STREAM_INFO_LEVELS; + +typedef struct +{ + LARGE_INTEGER StreamSize; + WCHAR cStreamName[MAX_PATH + 36]; +} MY_WIN32_FIND_STREAM_DATA, *MY_PWIN32_FIND_STREAM_DATA; + +typedef HANDLE (WINAPI *Func_FindFirstStreamW)(LPCWSTR fileName, MY_STREAM_INFO_LEVELS infoLevel, + LPVOID findStreamData, DWORD flags); + +typedef BOOL (APIENTRY *Func_FindNextStreamW)(HANDLE findStream, LPVOID findStreamData); + +EXTERN_C_END + +#else + +#define MY_WIN32_FIND_STREAM_DATA WIN32_FIND_STREAM_DATA +#define My_FindStreamInfoStandard FindStreamInfoStandard + +#endif +#endif // defined(_WIN32) && !defined(UNDER_CE) + + +namespace NWindows { +namespace NFile { + + +#ifdef _WIN32 +#ifdef Z7_DEVICE_FILE +namespace NSystem +{ +bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); +} +#endif +#endif + +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; + FiTime_Clear(CTime); + FiTime_Clear(ATime); + FiTime_Clear(MTime); + + #ifdef _WIN32 + Attrib = 0; + // ReparseTag = 0; + IsAltStream = false; + IsDevice = false; + #else + dev = 0; + ino = 0; + mode = 0; + nlink = 0; + uid = 0; + gid = 0; + rdev = 0; + #endif +} + + +bool CFileInfoBase::SetAs_StdInFile() +{ + ClearBase(); + Size = (UInt64)(Int64)-1; + NTime::GetCurUtc_FiTime(MTime); + CTime = ATime = MTime; + +#ifdef _WIN32 + + /* in GUI mode : GetStdHandle(STD_INPUT_HANDLE) returns NULL, + and it doesn't set LastError. */ +#if 1 + SetLastError(0); + const HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (!h || h == INVALID_HANDLE_VALUE) + { + if (GetLastError() == 0) + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + BY_HANDLE_FILE_INFORMATION info; + if (GetFileInformationByHandle(h, &info) + && info.dwVolumeSerialNumber) + { + Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + // FileID_Low = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + // NumLinks = SupportHardLinks ? info.nNumberOfLinks : 1; + Attrib = info.dwFileAttributes; + CTime = info.ftCreationTime; + ATime = info.ftLastAccessTime; + MTime = info.ftLastWriteTime; + } +#if 0 + printf( + "\ndwFileAttributes = %8x" + "\nftCreationTime = %8x" + "\nftLastAccessTime = %8x" + "\nftLastWriteTime = %8x" + "\ndwVolumeSerialNumber = %8x" + "\nnFileSizeHigh = %8x" + "\nnFileSizeLow = %8x" + "\nnNumberOfLinks = %8x" + "\nnFileIndexHigh = %8x" + "\nnFileIndexLow = %8x \n", + (unsigned)info.dwFileAttributes, + (unsigned)info.ftCreationTime.dwHighDateTime, + (unsigned)info.ftLastAccessTime.dwHighDateTime, + (unsigned)info.ftLastWriteTime.dwHighDateTime, + (unsigned)info.dwVolumeSerialNumber, + (unsigned)info.nFileSizeHigh, + (unsigned)info.nFileSizeLow, + (unsigned)info.nNumberOfLinks, + (unsigned)info.nFileIndexHigh, + (unsigned)info.nFileIndexLow); +#endif +#endif + +#else // non-Wiondow + + mode = S_IFIFO | 0777; // 0755 : 0775 : 0664 : 0644 : +#if 1 + struct stat st; + if (fstat(0, &st) == 0) + { + SetFrom_stat(st); + if (!S_ISREG(st.st_mode) + // S_ISFIFO(st->st_mode) + || st.st_size == 0) + { + Size = (UInt64)(Int64)-1; + // mode = S_IFIFO | 0777; + } + } +#endif +#endif + + return true; +} + +bool CFileInfo::IsDots() const throw() +{ + if (!IsDir() || Name.IsEmpty()) + return false; + if (Name[0] != '.') + return false; + return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == '.'); +} + + +#ifdef _WIN32 + + +#define WIN_FD_TO_MY_FI(fi, fd) \ + fi.Attrib = fd.dwFileAttributes; \ + fi.CTime = fd.ftCreationTime; \ + fi.ATime = fd.ftLastAccessTime; \ + fi.MTime = fd.ftLastWriteTime; \ + fi.Size = (((UInt64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow; \ + /* fi.ReparseTag = fd.dwReserved0; */ \ + fi.IsAltStream = false; \ + fi.IsDevice = false; + + /* + #ifdef UNDER_CE + fi.ObjectID = fd.dwOID; + #else + fi.ReparseTag = fd.dwReserved0; + #endif + */ + +static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi) +{ + WIN_FD_TO_MY_FI(fi, fd) + fi.Name = us2fs(fd.cFileName); + #if defined(_WIN32) && !defined(UNDER_CE) + // fi.ShortName = us2fs(fd.cAlternateFileName); + #endif +} + +#ifndef _UNICODE +static void Convert_WIN32_FIND_DATA_to_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi) +{ + WIN_FD_TO_MY_FI(fi, fd) + fi.Name = fas2fs(fd.cFileName); + #if defined(_WIN32) && !defined(UNDER_CE) + // fi.ShortName = fas2fs(fd.cAlternateFileName); + #endif +} +#endif + +//////////////////////////////// +// CFindFile + +bool CFindFileBase::Close() throw() +{ + if (_handle == INVALID_HANDLE_VALUE) + return true; + if (!::FindClose(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +/* +WinXP-64 FindFirstFile(): + "" - ERROR_PATH_NOT_FOUND + folder\ - ERROR_FILE_NOT_FOUND + \ - ERROR_FILE_NOT_FOUND + c:\ - ERROR_FILE_NOT_FOUND + c: - ERROR_FILE_NOT_FOUND, if current dir is ROOT ( c:\ ) + c: - OK, if current dir is NOT ROOT ( c:\folder ) + folder - OK + + \\ - ERROR_INVALID_NAME + \\Server - ERROR_INVALID_NAME + \\Server\ - ERROR_INVALID_NAME + + \\Server\Share - ERROR_BAD_NETPATH + \\Server\Share - ERROR_BAD_NET_NAME (Win7). + !!! There is problem : Win7 makes some requests for "\\Server\Shar" (look in Procmon), + when we call it for "\\Server\Share" + + \\Server\Share\ - ERROR_FILE_NOT_FOUND + + \\?\UNC\Server\Share - ERROR_INVALID_NAME + \\?\UNC\Server\Share - ERROR_BAD_PATHNAME (Win7) + \\?\UNC\Server\Share\ - ERROR_FILE_NOT_FOUND + + \\Server\Share_RootDrive - ERROR_INVALID_NAME + \\Server\Share_RootDrive\ - ERROR_INVALID_NAME + + e:\* - ERROR_FILE_NOT_FOUND, if there are no items in that root folder + w:\* - ERROR_PATH_NOT_FOUND, if there is no such drive w: +*/ + +bool CFindFile::FindFirst(CFSTR path, CFileInfo &fi) +{ + if (!Close()) + return false; + #ifndef _UNICODE + if (!g_IsNT) + { + WIN32_FIND_DATAA fd; + _handle = ::FindFirstFileA(fs2fas(path), &fd); + if (_handle == INVALID_HANDLE_VALUE) + return false; + Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi); + } + else + #endif + { + WIN32_FIND_DATAW fd; + + IF_USE_MAIN_PATH + _handle = ::FindFirstFileW(fs2us(path), &fd); + #ifdef Z7_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + _handle = ::FindFirstFileW(superPath, &fd); + } + #endif + if (_handle == INVALID_HANDLE_VALUE) + return false; + Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi); + } + return true; +} + +bool CFindFile::FindNext(CFileInfo &fi) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + WIN32_FIND_DATAA fd; + if (!::FindNextFileA(_handle, &fd)) + return false; + Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi); + } + else + #endif + { + WIN32_FIND_DATAW fd; + if (!::FindNextFileW(_handle, &fd)) + return false; + Convert_WIN32_FIND_DATA_to_FileInfo(fd, fi); + } + return true; +} + +#if defined(_WIN32) && !defined(UNDER_CE) + +//////////////////////////////// +// AltStreams + +#ifdef Z7_USE_DYN_FindFirstStream +static Func_FindFirstStreamW g_FindFirstStreamW; +static Func_FindNextStreamW g_FindNextStreamW; +#define MY_FindFirstStreamW g_FindFirstStreamW +#define MY_FindNextStreamW g_FindNextStreamW +static struct CFindStreamLoader +{ + CFindStreamLoader() + { + const HMODULE hm = ::GetModuleHandleA("kernel32.dll"); + g_FindFirstStreamW = Z7_GET_PROC_ADDRESS( + Func_FindFirstStreamW, hm, + "FindFirstStreamW"); + g_FindNextStreamW = Z7_GET_PROC_ADDRESS( + Func_FindNextStreamW, hm, + "FindNextStreamW"); + } +} g_FindStreamLoader; +#else +#define MY_FindFirstStreamW FindFirstStreamW +#define MY_FindNextStreamW FindNextStreamW +#endif + + +bool CStreamInfo::IsMainStream() const throw() +{ + return StringsAreEqualNoCase_Ascii(Name, "::$DATA"); +} + +UString CStreamInfo::GetReducedName() const +{ + // remove ":$DATA" postfix, but keep postfix, if Name is "::$DATA" + UString s (Name); + if (s.Len() > 6 + 1 && StringsAreEqualNoCase_Ascii(s.RightPtr(6), ":$DATA")) + s.DeleteFrom(s.Len() - 6); + return s; +} + +/* +UString CStreamInfo::GetReducedName2() const +{ + UString s = GetReducedName(); + if (!s.IsEmpty() && s[0] == ':') + s.Delete(0); + return s; +} +*/ + +static void Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(const MY_WIN32_FIND_STREAM_DATA &sd, CStreamInfo &si) +{ + si.Size = (UInt64)sd.StreamSize.QuadPart; + si.Name = sd.cStreamName; +} + +/* + WinXP-64 FindFirstStream(): + "" - ERROR_PATH_NOT_FOUND + folder\ - OK + folder - OK + \ - OK + c:\ - OK + c: - OK, if current dir is ROOT ( c:\ ) + c: - OK, if current dir is NOT ROOT ( c:\folder ) + \\Server\Share - OK + \\Server\Share\ - OK + + \\ - ERROR_INVALID_NAME + \\Server - ERROR_INVALID_NAME + \\Server\ - ERROR_INVALID_NAME +*/ + +bool CFindStream::FindFirst(CFSTR path, CStreamInfo &si) +{ + if (!Close()) + return false; +#ifdef Z7_USE_DYN_FindFirstStream + if (!g_FindFirstStreamW) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } +#endif + { + MY_WIN32_FIND_STREAM_DATA sd; + SetLastError(0); + IF_USE_MAIN_PATH + _handle = MY_FindFirstStreamW(fs2us(path), My_FindStreamInfoStandard, &sd, 0); + if (_handle == INVALID_HANDLE_VALUE) + { + if (::GetLastError() == ERROR_HANDLE_EOF) + return false; + // long name can be tricky for path like ".\dirName". + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + _handle = MY_FindFirstStreamW(superPath, My_FindStreamInfoStandard, &sd, 0); + } + #endif + } + if (_handle == INVALID_HANDLE_VALUE) + return false; + Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si); + } + return true; +} + +bool CFindStream::FindNext(CStreamInfo &si) +{ +#ifdef Z7_USE_DYN_FindFirstStream + if (!g_FindNextStreamW) + { + ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return false; + } +#endif + { + MY_WIN32_FIND_STREAM_DATA sd; + if (!MY_FindNextStreamW(_handle, &sd)) + return false; + Convert_WIN32_FIND_STREAM_DATA_to_StreamInfo(sd, si); + } + return true; +} + +bool CStreamEnumerator::Next(CStreamInfo &si, bool &found) +{ + bool res; + if (_find.IsHandleAllocated()) + res = _find.FindNext(si); + else + res = _find.FindFirst(_filePath, si); + if (res) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_HANDLE_EOF); +} + +#endif + + +/* +WinXP-64 GetFileAttributes(): + If the function fails, it returns INVALID_FILE_ATTRIBUTES and use GetLastError() to get error code + + \ - OK + C:\ - OK, if there is such drive, + D:\ - ERROR_PATH_NOT_FOUND, if there is no such drive, + + C:\folder - OK + C:\folder\ - OK + C:\folderBad - ERROR_FILE_NOT_FOUND + + \\Server\BadShare - ERROR_BAD_NETPATH + \\Server\Share - WORKS OK, but MSDN says: + GetFileAttributes for a network share, the function fails, and GetLastError + returns ERROR_BAD_NETPATH. You must specify a path to a subfolder on that share. +*/ + +DWORD GetFileAttrib(CFSTR path) +{ + #ifndef _UNICODE + if (!g_IsNT) + return ::GetFileAttributes(fs2fas(path)); + else + #endif + { + IF_USE_MAIN_PATH + { + DWORD dw = ::GetFileAttributesW(fs2us(path)); + if (dw != INVALID_FILE_ATTRIBUTES) + return dw; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + return ::GetFileAttributesW(superPath); + } + #endif + return INVALID_FILE_ATTRIBUTES; + } +} + +/* if path is "c:" or "c::" then CFileInfo::Find() returns name of current folder for that disk + so instead of absolute path we have relative path in Name. That is not good in some calls */ + +/* In CFileInfo::Find() we want to support same names for alt streams as in CreateFile(). */ + +/* CFileInfo::Find() +We alow the following paths (as FindFirstFile): + C:\folder + c: - if current dir is NOT ROOT ( c:\folder ) + +also we support paths that are not supported by FindFirstFile: + \ + \\.\c: + c:\ - Name will be without tail slash ( c: ) + \\?\c:\ - Name will be without tail slash ( c: ) + \\Server\Share + \\?\UNC\Server\Share + + c:\folder:stream - Name = folder:stream + c:\:stream - Name = :stream + c::stream - Name = c::stream +*/ + +bool CFileInfo::Find(CFSTR path, bool followLink) +{ + #ifdef Z7_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(); + Name = path + 4; + IsDevice = true; + + if (NName::IsDrivePath2(path + 4) && path[6] == 0) + { + FChar drive[4] = { path[4], ':', '\\', 0 }; + UInt64 clusterSize, totalSize, freeSize; + if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize)) + { + Size = totalSize; + return true; + } + } + + NIO::CInFile inFile; + // ::OutputDebugStringW(path); + if (!inFile.Open(path)) + return false; + // ::OutputDebugStringW(L"---"); + if (inFile.SizeDefined) + Size = inFile.Size; + return true; + } + #endif + + #if defined(_WIN32) && !defined(UNDER_CE) + + const int colonPos = FindAltStreamColon(path); + if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0) + { + UString streamName = fs2us(path + (unsigned)colonPos); + FString filePath (path); + filePath.DeleteFrom((unsigned)colonPos); + /* we allow both cases: + name:stream + name:stream:$DATA + */ + const unsigned kPostfixSize = 6; + if (streamName.Len() <= kPostfixSize + || !StringsAreEqualNoCase_Ascii(streamName.RightPtr(kPostfixSize), ":$DATA")) + streamName += ":$DATA"; + + bool isOk = true; + + if (IsDrivePath2(filePath) && + (colonPos == 2 || (colonPos == 3 && filePath[2] == '\\'))) + { + // FindFirstFile doesn't work for "c:\" and for "c:" (if current dir is ROOT) + ClearBase(); + Name.Empty(); + if (colonPos == 2) + Name = filePath; + } + else + isOk = Find(filePath, followLink); // check it (followLink) + + if (isOk) + { + Attrib &= ~(DWORD)(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); + Size = 0; + CStreamEnumerator enumerator(filePath); + for (;;) + { + CStreamInfo si; + bool found; + if (!enumerator.Next(si, found)) + return false; + if (!found) + { + ::SetLastError(ERROR_FILE_NOT_FOUND); + return false; + } + if (si.Name.IsEqualTo_NoCase(streamName)) + { + // we delete postfix, if alt stream name is not "::$DATA" + if (si.Name.Len() > kPostfixSize + 1) + si.Name.DeleteFrom(si.Name.Len() - kPostfixSize); + Name += us2fs(si.Name); + Size = si.Size; + IsAltStream = true; + return true; + } + } + } + } + + #endif + + CFindFile finder; + + #if defined(_WIN32) && !defined(UNDER_CE) + { + /* + DWORD lastError = GetLastError(); + if (lastError == ERROR_FILE_NOT_FOUND + || lastError == ERROR_BAD_NETPATH // XP64: "\\Server\Share" + || lastError == ERROR_BAD_NET_NAME // Win7: "\\Server\Share" + || lastError == ERROR_INVALID_NAME // XP64: "\\?\UNC\Server\Share" + || lastError == ERROR_BAD_PATHNAME // Win7: "\\?\UNC\Server\Share" + ) + */ + + unsigned rootSize = 0; + if (IsSuperPath(path)) + rootSize = kSuperPathPrefixSize; + + if (NName::IsDrivePath(path + rootSize) && path[rootSize + 3] == 0) + { + DWORD attrib = GetFileAttrib(path); + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + ClearBase(); + Attrib = attrib; + Name = path + rootSize; + Name.DeleteFrom(2); + if (!Fill_From_ByHandleFileInfo(path)) + { + } + return true; + } + } + else if (IS_PATH_SEPAR(path[0])) + { + if (path[1] == 0) + { + DWORD attrib = GetFileAttrib(path); + if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + ClearBase(); + Name.Empty(); + Attrib = attrib; + return true; + } + } + else + { + const unsigned prefixSize = GetNetworkServerPrefixSize(path); + if (prefixSize > 0 && path[prefixSize] != 0) + { + if (NName::FindSepar(path + prefixSize) < 0) + { + if (Fill_From_ByHandleFileInfo(path)) + { + Name = path + prefixSize; + return true; + } + + FString s (path); + s.Add_PathSepar(); + s.Add_Char('*'); // CHAR_ANY_MASK + bool isOK = false; + if (finder.FindFirst(s, *this)) + { + if (Name.IsEqualTo(".")) + { + Name = path + prefixSize; + return true; + } + isOK = true; + /* if "\\server\share" maps to root folder "d:\", there is no "." item. + But it's possible that there are another items */ + } + { + const DWORD attrib = GetFileAttrib(path); + if (isOK || (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0)) + { + ClearBase(); + if (attrib != INVALID_FILE_ATTRIBUTES) + Attrib = attrib; + else + SetAsDir(); + Name = path + prefixSize; + return true; + } + } + // ::SetLastError(lastError); + } + } + } + } + } + #endif + + bool res = finder.FindFirst(path, *this); + if (!followLink + || !res + || !HasReparsePoint()) + return res; + + // return FollowReparse(path, IsDir()); + return Fill_From_ByHandleFileInfo(path); +/* + // Fill_From_ByHandleFileInfo returns false (with Access Denied error), + // if there is reparse link file (not directory reparse item). + if (Fill_From_ByHandleFileInfo(path)) + return true; + return HasReparsePoint(); +*/ +} + +bool CFileInfoBase::Fill_From_ByHandleFileInfo(CFSTR path) +{ + BY_HANDLE_FILE_INFORMATION info; + if (!NIO::CFileBase::GetFileInformation(path, &info)) + return false; + { + Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + CTime = info.ftCreationTime; + ATime = info.ftLastAccessTime; + MTime = info.ftLastWriteTime; + Attrib = info.dwFileAttributes; + return true; + } +} + +/* +bool CFileInfo::FollowReparse(CFSTR path, bool isDir) +{ + if (isDir) + { + FString prefix = path; + prefix.Add_PathSepar(); + + // "folder/." refers to folder itself. So we can't use that path + // we must use enumerator and search "." item + CEnumerator enumerator; + enumerator.SetDirPrefix(prefix); + for (;;) + { + CFileInfo fi; + if (!enumerator.NextAny(fi)) + break; + if (fi.Name.IsEqualTo_Ascii_NoCase(".")) + { + // we can copy preperies; + CTime = fi.CTime; + ATime = fi.ATime; + MTime = fi.MTime; + Attrib = fi.Attrib; + Size = fi.Size; + return true; + } + break; + } + // LastError(lastError); + return false; + } + + { + NIO::CInFile inFile; + if (inFile.Open(path)) + { + BY_HANDLE_FILE_INFORMATION info; + if (inFile.GetFileInformation(&info)) + { + ClearBase(); + Size = (((UInt64)info.nFileSizeHigh) << 32) + info.nFileSizeLow; + CTime = info.ftCreationTime; + ATime = info.ftLastAccessTime; + MTime = info.ftLastWriteTime; + Attrib = info.dwFileAttributes; + return true; + } + } + return false; + } +} +*/ + +bool DoesFileExist_Raw(CFSTR name) +{ + CFileInfo fi; + return fi.Find(name) && !fi.IsDir(); +} + +bool DoesFileExist_FollowLink(CFSTR name) +{ + CFileInfo fi; + return fi.Find_FollowLink(name) && !fi.IsDir(); +} + +bool DoesDirExist(CFSTR name, bool followLink) +{ + CFileInfo fi; + return fi.Find(name, followLink) && fi.IsDir(); +} + +bool DoesFileOrDirExist(CFSTR name) +{ + CFileInfo fi; + return fi.Find(name); +} + + +void CEnumerator::SetDirPrefix(const FString &dirPrefix) +{ + _wildcard = dirPrefix; + _wildcard.Add_Char('*'); +} + +bool CEnumerator::NextAny(CFileInfo &fi) +{ + if (_findFile.IsHandleAllocated()) + return _findFile.FindNext(fi); + else + return _findFile.FindFirst(_wildcard, fi); +} + +bool CEnumerator::Next(CFileInfo &fi) +{ + for (;;) + { + if (!NextAny(fi)) + return false; + if (!fi.IsDots()) + return true; + } +} + +bool CEnumerator::Next(CFileInfo &fi, bool &found) +{ + /* + for (;;) + { + if (!NextAny(fi)) + break; + if (!fi.IsDots()) + { + found = true; + return true; + } + } + */ + + if (Next(fi)) + { + found = true; + return true; + } + + found = false; + DWORD lastError = ::GetLastError(); + if (_findFile.IsHandleAllocated()) + return (lastError == ERROR_NO_MORE_FILES); + // we support the case for empty root folder: FindFirstFile("c:\\*") returns ERROR_FILE_NOT_FOUND + if (lastError == ERROR_FILE_NOT_FOUND) + return true; + if (lastError == ERROR_ACCESS_DENIED) + { + // here we show inaccessible root system folder as empty folder to eliminate redundant user warnings + const char *s = "System Volume Information" STRING_PATH_SEPARATOR "*"; + const int len = (int)strlen(s); + const int delta = (int)_wildcard.Len() - len; + if (delta == 0 || (delta > 0 && IS_PATH_SEPAR(_wildcard[(unsigned)delta - 1]))) + if (StringsAreEqual_Ascii(_wildcard.Ptr((unsigned)delta), s)) + return true; + } + return false; +} + + +//////////////////////////////// +// CFindChangeNotification +// FindFirstChangeNotification can return 0. MSDN doesn't tell about it. + +bool CFindChangeNotification::Close() throw() +{ + if (!IsHandleAllocated()) + return true; + if (!::FindCloseChangeNotification(_handle)) + return false; + _handle = INVALID_HANDLE_VALUE; + return true; +} + +HANDLE CFindChangeNotification::FindFirst(CFSTR path, bool watchSubtree, DWORD notifyFilter) +{ + #ifndef _UNICODE + if (!g_IsNT) + _handle = ::FindFirstChangeNotification(fs2fas(path), BoolToBOOL(watchSubtree), notifyFilter); + else + #endif + { + IF_USE_MAIN_PATH + _handle = ::FindFirstChangeNotificationW(fs2us(path), BoolToBOOL(watchSubtree), notifyFilter); + #ifdef Z7_LONG_PATH + if (!IsHandleAllocated()) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + _handle = ::FindFirstChangeNotificationW(superPath, BoolToBOOL(watchSubtree), notifyFilter); + } + #endif + } + return _handle; +} + +#ifndef UNDER_CE + +bool MyGetLogicalDriveStrings(CObjectVector &driveStrings) +{ + driveStrings.Clear(); + #ifndef _UNICODE + if (!g_IsNT) + { + driveStrings.Clear(); + UINT32 size = GetLogicalDriveStrings(0, NULL); + if (size == 0) + return false; + CObjArray buf(size); + UINT32 newSize = GetLogicalDriveStrings(size, buf); + if (newSize == 0 || newSize > size) + return false; + AString s; + UINT32 prev = 0; + for (UINT32 i = 0; i < newSize; i++) + { + if (buf[i] == 0) + { + s = buf + prev; + prev = i + 1; + driveStrings.Add(fas2fs(s)); + } + } + return prev == newSize; + } + else + #endif + { + UINT32 size = GetLogicalDriveStringsW(0, NULL); + if (size == 0) + return false; + CObjArray buf(size); + UINT32 newSize = GetLogicalDriveStringsW(size, buf); + if (newSize == 0 || newSize > size) + return false; + UString s; + UINT32 prev = 0; + for (UINT32 i = 0; i < newSize; i++) + { + if (buf[i] == 0) + { + s = buf + prev; + prev = i + 1; + driveStrings.Add(us2fs(s)); + } + } + return prev == newSize; + } +} + +#endif // UNDER_CE + + + +#else // _WIN32 + +// ---------- POSIX ---------- + +static int MY_lstat(CFSTR path, struct stat *st, bool followLink) +{ + memset(st, 0, sizeof(*st)); + int res; + // #ifdef ENV_HAVE_LSTAT + if (/* global_use_lstat && */ !followLink) + { + // printf("\nlstat\n"); + res = lstat(path, st); + } + else + // #endif + { + // printf("\nstat\n"); + res = stat(path, st); + } +#if 0 +#if defined(__clang__) && __clang_major__ >= 14 + #pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + + printf("\n st_dev = %lld", (long long)(st->st_dev)); + printf("\n st_ino = %lld", (long long)(st->st_ino)); + printf("\n st_mode = %llx", (long long)(st->st_mode)); + printf("\n st_nlink = %lld", (long long)(st->st_nlink)); + printf("\n st_uid = %lld", (long long)(st->st_uid)); + printf("\n st_gid = %lld", (long long)(st->st_gid)); + printf("\n st_size = %lld", (long long)(st->st_size)); + printf("\n st_blksize = %lld", (long long)(st->st_blksize)); + printf("\n st_blocks = %lld", (long long)(st->st_blocks)); + printf("\n st_ctim = %lld", (long long)(ST_CTIME((*st)).tv_sec)); + printf("\n st_mtim = %lld", (long long)(ST_MTIME((*st)).tv_sec)); + printf("\n st_atim = %lld", (long long)(ST_ATIME((*st)).tv_sec)); + printf(S_ISFIFO(st->st_mode) ? "\n FIFO" : "\n NO FIFO"); + printf("\n"); +#endif + + return res; +} + + +static const char *Get_Name_from_Path(CFSTR path) throw() +{ + size_t len = strlen(path); + if (len == 0) + return path; + const char *p = path + len - 1; + { + if (p == path) + return path; + p--; + } + for (;;) + { + char c = *p; + if (IS_PATH_SEPAR(c)) + return p + 1; + if (p == path) + return path; + p--; + } +} + + +UInt32 Get_WinAttribPosix_From_PosixMode(UInt32 mode) +{ + UInt32 attrib = S_ISDIR(mode) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + if ((mode & 0222) == 0) // S_IWUSR in p7zip + attrib |= FILE_ATTRIBUTE_READONLY; + return attrib | FILE_ATTRIBUTE_UNIX_EXTENSION | ((mode & 0xFFFF) << 16); +} + +/* +UInt32 Get_WinAttrib_From_stat(const struct stat &st) +{ + UInt32 attrib = S_ISDIR(st.st_mode) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + + if ((st.st_mode & 0222) == 0) // check it !!! + attrib |= FILE_ATTRIBUTE_READONLY; + + attrib |= FILE_ATTRIBUTE_UNIX_EXTENSION + ((st.st_mode & 0xFFFF) << 16); + return attrib; +} +*/ + +void CFileInfoBase::SetFrom_stat(const struct stat &st) +{ + // IsDevice = false; + + if (S_ISDIR(st.st_mode)) + { + Size = 0; + } + else + { + Size = (UInt64)st.st_size; // for a symbolic link, size = size of filename + } + + // Attrib = Get_WinAttribPosix_From_PosixMode(st.st_mode); + + // NTime::UnixTimeToFileTime(st.st_ctime, CTime); + // NTime::UnixTimeToFileTime(st.st_mtime, MTime); + // NTime::UnixTimeToFileTime(st.st_atime, ATime); + #ifdef __APPLE__ + // #ifdef _DARWIN_FEATURE_64_BIT_INODE + /* + here we can use birthtime instead of st_ctimespec. + but we use st_ctimespec for compatibility with previous versions and p7zip. + st_birthtimespec in OSX + st_birthtim : at FreeBSD, NetBSD + */ + // timespec_To_FILETIME(st.st_birthtimespec, CTime); + // #else + // timespec_To_FILETIME(st.st_ctimespec, CTime); + // #endif + // 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, &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; + 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; +} + + +bool CFileInfo::Find(CFSTR path, bool followLink) +{ + // printf("\nCEnumerator::Find() name = %s\n", path); + if (!Find_DontFill_Name(path, followLink)) + return false; + + // printf("\nOK\n"); + + Name = Get_Name_from_Path(path); + if (!Name.IsEmpty()) + { + char c = Name.Back(); + if (IS_PATH_SEPAR(c)) + Name.DeleteBack(); + } + return true; +} + + +bool DoesFileExist_Raw(CFSTR name) +{ + // FIXME for symbolic links. + struct stat st; + if (MY_lstat(name, &st, false) != 0) + return false; + return !S_ISDIR(st.st_mode); +} + +bool DoesFileExist_FollowLink(CFSTR name) +{ + // FIXME for symbolic links. + struct stat st; + if (MY_lstat(name, &st, true) != 0) + return false; + return !S_ISDIR(st.st_mode); +} + +bool DoesDirExist(CFSTR name, bool followLink) +{ + struct stat st; + if (MY_lstat(name, &st, followLink) != 0) + return false; + return S_ISDIR(st.st_mode); +} + +bool DoesFileOrDirExist(CFSTR name) +{ + struct stat st; + if (MY_lstat(name, &st, false) != 0) + return false; + return true; +} + + +CEnumerator::~CEnumerator() +{ + if (_dir) + closedir(_dir); +} + +void CEnumerator::SetDirPrefix(const FString &dirPrefix) +{ + _wildcard = dirPrefix; +} + +bool CDirEntry::IsDots() const throw() +{ + /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) + we can call fstatat() for that case, but we use only (Name) check here */ + +#if !defined(_AIX) && !defined(__sun) + if (Type != DT_DIR && Type != DT_UNKNOWN) + return false; +#endif + + return Name.Len() != 0 + && Name.Len() <= 2 + && Name[0] == '.' + && (Name.Len() == 1 || Name[1] == '.'); +} + + +bool CEnumerator::NextAny(CDirEntry &fi, bool &found) +{ + found = false; + + if (!_dir) + { + const char *w = "./"; + if (!_wildcard.IsEmpty()) + w = _wildcard.Ptr(); + _dir = ::opendir((const char *)w); + if (_dir == NULL) + return false; + } + + // To distinguish end of stream from an error, we must set errno to zero before readdir() + errno = 0; + + struct dirent *de = readdir(_dir); + if (!de) + { + if (errno == 0) + return true; // it's end of stream, and we report it with (found = false) + // it's real error + return false; + } + + fi.iNode = de->d_ino; + +#if !defined(_AIX) && !defined(__sun) + fi.Type = de->d_type; + /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN) + we can set (Type) from fstatat() in that case. + But (Type) is not too important. So we don't set it here with slow fstatat() */ + /* + // fi.Type = DT_UNKNOWN; // for debug + if (fi.Type == DT_UNKNOWN) + { + struct stat st; + if (fstatat(dirfd(_dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) == 0) + if (S_ISDIR(st.st_mode)) + fi.Type = DT_DIR; + } + */ +#endif + + /* + if (de->d_type == DT_DIR) + fi.Attrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_UNIX_EXTENSION | ((UInt32)(S_IFDIR) << 16); + else if (de->d_type < 16) + fi.Attrib = FILE_ATTRIBUTE_UNIX_EXTENSION | ((UInt32)(de->d_type) << (16 + 12)); + */ + fi.Name = de->d_name; + + /* + printf("\nCEnumerator::NextAny; len = %d %s \n", (int)fi.Name.Len(), fi.Name.Ptr()); + for (unsigned i = 0; i < fi.Name.Len(); i++) + printf (" %02x", (unsigned)(Byte)de->d_name[i]); + printf("\n"); + */ + + found = true; + return true; +} + + +bool CEnumerator::Next(CDirEntry &fi, bool &found) +{ + // printf("\nCEnumerator::Next()\n"); + // PrintName("Next", ""); + for (;;) + { + if (!NextAny(fi, found)) + return false; + if (!found) + return true; + if (!fi.IsDots()) + { + /* + if (!NeedFullStat) + return true; + // we silently skip error file here - it can be wrong link item + if (fi.Find_DontFill_Name(path)) + return true; + */ + return true; + } + } +} + +/* +bool CEnumerator::Next(CDirEntry &fileInfo, bool &found) +{ + bool found; + if (!Next(fi, found)) + return false; + return found; +} +*/ + +bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const +{ + // printf("\nCEnumerator::Fill_FileInfo()\n"); + struct stat st; + // probably it's OK to use fstatat() even if it changes file position dirfd(_dir) + int res = fstatat(dirfd(_dir), de.Name, &st, followLink ? 0 : AT_SYMLINK_NOFOLLOW); + // if fstatat() is not supported, we can use stat() / lstat() + + /* + const FString path = _wildcard + s; + int res = MY_lstat(path, &st, followLink); + */ + + if (res != 0) + return false; + // printf("\nname=%s\n", de.Name.Ptr()); + fileInfo.SetFrom_stat(st); + fileInfo.Name = de.Name; + return true; +} + +#endif // _WIN32 + +}}} diff -Nru p7zip-rar-16.02/CPP/Windows/FileFind.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.h --- p7zip-rar-16.02/CPP/Windows/FileFind.h 2015-06-20 07:33:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileFind.h 2024-02-11 08:00:00.000000000 +0000 @@ -1,130 +1,347 @@ -// Windows/FileFind.h - -#ifndef __WINDOWS_FILE_FIND_H -#define __WINDOWS_FILE_FIND_H - -#include "../Common/MyString.h" -#include "../Common/MyTypes.h" -#include "Defs.h" - -#include /* for DIR */ -#include - -namespace NWindows { -namespace NFile { -namespace NFind { - -namespace NAttributes -{ - inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; } - inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; } - inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; } - inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } - 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; } -} - -class CFileInfoBase -{ - bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); } -public: - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - DWORD Attrib; - bool IsAltStream; - bool IsDevice; - - /* - #ifdef UNDER_CE - DWORD ObjectID; - #else - UINT32 ReparseTag; - #endif - */ - - CFileInfoBase() { ClearBase(); } - void ClearBase() throw(); - - void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } - - bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); } - bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); } - bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); } - bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); } - bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); } - bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); } - bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); } - bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); } - bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); } - bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); } - bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); } - bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); } -}; - -struct CFileInfo: public CFileInfoBase -{ - FString Name; - #if defined(_WIN32) && !defined(UNDER_CE) - // FString ShortName; - #endif - - bool IsDots() const throw(); - bool Find(CFSTR wildcard, bool ignoreLink = false); -}; - -class CFindFile -{ - friend class CEnumerator; - DIR *_dirp; - AString _pattern; - AString _directory; -public: - bool IsHandleAllocated() const { return (_dirp != 0); } - CFindFile(): _dirp(0) {} - ~CFindFile() { Close(); } - bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo, bool ignoreLink = false); - bool FindNext(CFileInfo &fileInfo); - bool Close(); -}; - -bool DoesFileExist(CFSTR name); -bool DoesDirExist(CFSTR name); -bool DoesFileOrDirExist(CFSTR name); - -class CEnumerator -{ - CFindFile _findFile; - FString _wildcard; - - bool NextAny(CFileInfo &fileInfo); -public: - CEnumerator(const FString &wildcard): _wildcard(wildcard) {} - bool Next(CFileInfo &fileInfo); - bool Next(CFileInfo &fileInfo, bool &found); -}; - -#ifdef _WIN32 -class CFindChangeNotification -{ - HANDLE _handle; -public: - operator HANDLE () { return _handle; } - bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; } - CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {} - ~CFindChangeNotification() { Close(); } - bool Close() throw(); - HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter); - bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); } -}; -#endif - -#ifndef UNDER_CE -bool MyGetLogicalDriveStrings(CObjectVector &driveStrings); -#endif - -}}} - -#endif +// Windows/FileFind.h + +#ifndef ZIP7_INC_WINDOWS_FILE_FIND_H +#define ZIP7_INC_WINDOWS_FILE_FIND_H + +#ifndef _WIN32 +#include +#include +#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 { + +// bool DoesFileExist(CFSTR name, bool followLink); +bool DoesFileExist_Raw(CFSTR name); +bool DoesFileExist_FollowLink(CFSTR name); +bool DoesDirExist(CFSTR name, bool followLink); + +inline bool DoesDirExist(CFSTR name) + { return DoesDirExist(name, false); } +inline bool DoesDirExist_FollowLink(CFSTR name) + { return DoesDirExist(name, true); } + +// it's always _Raw +bool DoesFileOrDirExist(CFSTR name); + +DWORD GetFileAttrib(CFSTR path); + +#ifdef _WIN32 + +namespace NAttributes +{ + inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; } + inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; } + inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; } + inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } + 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; + CFiTime CTime; + CFiTime ATime; + CFiTime MTime; + #ifdef _WIN32 + DWORD Attrib; + bool IsAltStream; + bool IsDevice; + + /* + #ifdef UNDER_CE + DWORD ObjectID; + #else + UINT32 ReparseTag; + #endif + */ + #else + dev_t dev; /* ID of device containing file */ + ino_t ino; + 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 + + CFileInfoBase() { ClearBase(); } + void ClearBase() throw(); + bool SetAs_StdInFile(); + + #ifdef _WIN32 + + bool Fill_From_ByHandleFileInfo(CFSTR path); + void SetAsDir() { Attrib = FILE_ATTRIBUTE_DIRECTORY; } // |= (FILE_ATTRIBUTE_UNIX_EXTENSION + (S_IFDIR << 16)); + + bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); } + bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); } + bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); } + bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); } + bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); } + bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); } + bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); } + bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); } + bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); } + bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); } + bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); } + bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); } + + UInt32 GetWinAttrib() const { return Attrib; } + UInt32 GetPosixAttrib() const + { + return NAttributes::Get_PosixMode_From_WinAttrib(Attrib); + } + 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 | 0777; } + void SetFrom_stat(const struct stat &st); + + 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 + { + #ifdef _WIN32 + return HasReparsePoint(); + #else + return IsPosixLink(); + #endif + } +}; + +struct CFileInfo: public CFileInfoBase +{ + FString Name; + #if defined(_WIN32) && !defined(UNDER_CE) + // FString ShortName; + #endif + + bool IsDots() const throw(); + bool Find(CFSTR path, bool followLink = false); + bool Find_FollowLink(CFSTR path) { return Find(path, true); } + + #ifdef _WIN32 + // bool Fill_From_ByHandleFileInfo(CFSTR path); + // bool FollowReparse(CFSTR path, bool isDir); + #else + bool Find_DontFill_Name(CFSTR path, bool followLink = false); + #endif +}; + + +#ifdef _WIN32 + +class CFindFileBase MY_UNCOPYABLE +{ +protected: + HANDLE _handle; +public: + bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; } + CFindFileBase(): _handle(INVALID_HANDLE_VALUE) {} + ~CFindFileBase() { Close(); } + bool Close() throw(); +}; + +class CFindFile: public CFindFileBase +{ +public: + bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo); + bool FindNext(CFileInfo &fileInfo); +}; + +#if defined(_WIN32) && !defined(UNDER_CE) + +struct CStreamInfo +{ + UString Name; + UInt64 Size; + + UString GetReducedName() const; // returns ":Name" + // UString GetReducedName2() const; // returns "Name" + bool IsMainStream() const throw(); +}; + +class CFindStream: public CFindFileBase +{ +public: + bool FindFirst(CFSTR filePath, CStreamInfo &streamInfo); + bool FindNext(CStreamInfo &streamInfo); +}; + +class CStreamEnumerator MY_UNCOPYABLE +{ + CFindStream _find; + FString _filePath; + + bool NextAny(CFileInfo &fileInfo, bool &found); +public: + CStreamEnumerator(const FString &filePath): _filePath(filePath) {} + bool Next(CStreamInfo &streamInfo, bool &found); +}; + +#endif // defined(_WIN32) && !defined(UNDER_CE) + + +class CEnumerator MY_UNCOPYABLE +{ + CFindFile _findFile; + FString _wildcard; + + bool NextAny(CFileInfo &fileInfo); +public: + void SetDirPrefix(const FString &dirPrefix); + bool Next(CFileInfo &fileInfo); + bool Next(CFileInfo &fileInfo, bool &found); +}; + + +class CFindChangeNotification MY_UNCOPYABLE +{ + HANDLE _handle; +public: + operator HANDLE () { return _handle; } + bool IsHandleAllocated() const + { + /* at least on win2000/XP (undocumented): + if pathName is "" or NULL, + FindFirstChangeNotification() could return NULL. + So we check for INVALID_HANDLE_VALUE and NULL. + */ + return _handle != INVALID_HANDLE_VALUE && _handle != NULL; + } + CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {} + ~CFindChangeNotification() { Close(); } + bool Close() throw(); + HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter); + bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); } +}; + +#ifndef UNDER_CE +bool MyGetLogicalDriveStrings(CObjectVector &driveStrings); +#endif + +typedef CFileInfo CDirEntry; + + +#else // WIN32 + + +struct CDirEntry +{ + ino_t iNode; +#if !defined(_AIX) && !defined(__sun) + Byte Type; +#endif + FString Name; + + /* +#if !defined(_AIX) && !defined(__sun) + bool IsDir() const + { + // (Type == DT_UNKNOWN) on some systems + return Type == DT_DIR; + } +#endif + */ + + bool IsDots() const throw(); +}; + +class CEnumerator MY_UNCOPYABLE +{ + DIR *_dir; + FString _wildcard; + + bool NextAny(CDirEntry &fileInfo, bool &found); +public: + CEnumerator(): _dir(NULL) {} + ~CEnumerator(); + void SetDirPrefix(const FString &dirPrefix); + + bool Next(CDirEntry &fileInfo, bool &found); + bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const; + bool DirEntry_IsDir(const CDirEntry &de, bool followLink) const + { +#if !defined(_AIX) && !defined(__sun) + if (de.Type == DT_DIR) + return true; + if (de.Type != DT_UNKNOWN) + return false; +#endif + CFileInfo fileInfo; + if (Fill_FileInfo(de, fileInfo, followLink)) + { + return fileInfo.IsDir(); + } + return false; // change it + } +}; + +/* +inline UInt32 Get_WinAttrib_From_PosixMode(UInt32 mode) +{ + UInt32 attrib = S_ISDIR(mode) ? + FILE_ATTRIBUTE_DIRECTORY : + FILE_ATTRIBUTE_ARCHIVE; + if ((st.st_mode & 0222) == 0) // check it !!! + attrib |= FILE_ATTRIBUTE_READONLY; + return attrib; +} +*/ + +// UInt32 Get_WinAttrib_From_stat(const struct stat &st); + + +#endif // WIN32 + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileIO.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.cpp --- p7zip-rar-16.02/CPP/Windows/FileIO.cpp 2016-02-23 21:50:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.cpp 2024-02-12 10:00:00.000000000 +0000 @@ -1,458 +1,954 @@ -// Windows/FileIO.cpp - -#include "StdAfx.h" - -#include "FileIO.h" -#include "Defs.h" -#include "../Common/StringConvert.h" - -#include -#include -#include -#include -#include - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" - -#include -#include - -#ifdef ENV_HAVE_LSTAT -#define FD_LINK (-2) -#endif - -#define GENERIC_READ 0x80000000 -#define GENERIC_WRITE 0x40000000 - -#ifdef ENV_HAVE_LSTAT -extern "C" -{ -int global_use_lstat=1; // default behaviour : p7zip stores symlinks instead of dumping the files they point to -} -#endif - -extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ); - -namespace NWindows { -namespace NFile { -namespace NIO { - -CFileBase::~CFileBase() -{ - Close(); -} - -bool CFileBase::Create(CFSTR filename, DWORD dwDesiredAccess, - DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,bool ignoreSymbolicLink) -{ - Close(); - - int flags = 0; -#ifdef USE_UNICODE_FSTRING - AString astr = UnicodeStringToMultiByte(filename); - const char * name = nameWindowToUnix((const char *)astr); -#else - const char * name = nameWindowToUnix(filename); -#endif - -#ifdef O_BINARY - flags |= O_BINARY; -#endif - -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif - - /* now use the umask value */ - int mask = umask(0); - (void)umask(mask); - int mode = 0666 & ~(mask & 066); /* keep the R/W for the user */ - - if (dwDesiredAccess & GENERIC_WRITE) flags |= O_WRONLY; - if (dwDesiredAccess & GENERIC_READ) flags |= O_RDONLY; - - - switch (dwCreationDisposition) - { - case CREATE_NEW : flags |= O_CREAT | O_EXCL; break; - case CREATE_ALWAYS : flags |= O_CREAT; break; - case OPEN_EXISTING : break; - case OPEN_ALWAYS : flags |= O_CREAT; break; - // case TRUNCATE_EXISTING : flags |= O_TRUNC; break; - } - // printf("##DBG open(%s,0x%x,%o)##\n",name,flags,(unsigned)mode); - - _fd = -1; -#ifdef ENV_HAVE_LSTAT - if ((global_use_lstat) && (ignoreSymbolicLink == false)) - { - _size = readlink(name, _buffer, sizeof(_buffer)-1); - if (_size > 0) { - if (dwDesiredAccess & GENERIC_READ) { - _fd = FD_LINK; - _offset = 0; - _buffer[_size]=0; - } else if (dwDesiredAccess & GENERIC_WRITE) { - // does not overwrite the file pointed by symbolic link - if (!unlink(name)) return false; - } - } - } -#endif - - if (_fd == -1) { - _fd = open(name,flags, mode); - } - - if ((_fd == -1) && (global_use_utf16_conversion)) { - // bug #1204993 - Try to recover the original filename - UString ustr = MultiByteToUnicodeString(AString(name), 0); - AString resultString; - int is_good = 1; - for (int i = 0; i < ustr.Len(); i++) - { - if (ustr[i] >= 256) { - is_good = 0; - break; - } else { - resultString += char(ustr[i]); - } - } - if (is_good) { - _fd = open((const char *)resultString,flags, mode); - } - } - - if (_fd == -1) { - /* !ENV_HAVE_LSTAT : an invalid symbolic link => errno == ENOENT */ - return false; - } else { - _unix_filename = name; - } - - return true; -} - -/* FIXME -bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, - DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink) -{ - Close(); - return Create(UnicodeStringToMultiByte(fileName, CP_ACP), - desiredAccess, shareMode, creationDisposition, flagsAndAttributes,ignoreSymbolicLink); -} -*/ - -bool CFileBase::Close() -{ - struct utimbuf buf; - - buf.actime = _lastAccessTime; - buf.modtime = _lastWriteTime; - - _lastAccessTime = _lastWriteTime = (time_t)-1; - - if(_fd == -1) - return true; - -#ifdef ENV_HAVE_LSTAT - if(_fd == FD_LINK) { - _fd = -1; - return true; - } -#endif - - int ret = ::close(_fd); - if (ret == 0) { - _fd = -1; - - /* On some OS (mingwin, MacOSX ...), you must close the file before updating times */ - if ((buf.actime != (time_t)-1) || (buf.modtime != (time_t)-1)) { - struct stat oldbuf; - int ret = stat((const char*)(_unix_filename),&oldbuf); - if (ret == 0) { - if (buf.actime == (time_t)-1) buf.actime = oldbuf.st_atime; - if (buf.modtime == (time_t)-1) buf.modtime = oldbuf.st_mtime; - } else { - time_t current_time = time(0); - if (buf.actime == (time_t)-1) buf.actime = current_time; - if (buf.modtime == (time_t)-1) buf.modtime = current_time; - } - /* ret = */ utime((const char *)(_unix_filename), &buf); - } - return true; - } - return false; -} - -bool CFileBase::GetLength(UINT64 &length) const -{ - if (_fd == -1) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - -#ifdef ENV_HAVE_LSTAT - if (_fd == FD_LINK) { - length = _size; - return true; - } -#endif - - off_t pos_cur = ::lseek(_fd, 0, SEEK_CUR); - if (pos_cur == (off_t)-1) - return false; - - off_t pos_end = ::lseek(_fd, 0, SEEK_END); - if (pos_end == (off_t)-1) - return false; - - off_t pos_cur2 = ::lseek(_fd, pos_cur, SEEK_SET); - if (pos_cur2 == (off_t)-1) - return false; - - length = (UINT64)pos_end; - - return true; -} - -bool CFileBase::Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition) -{ - if (_fd == -1) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - -#ifdef ENV_HAVE_LSTAT - if (_fd == FD_LINK) { - INT64 offset; - switch (moveMethod) { - case STREAM_SEEK_SET : offset = distanceToMove; break; - case STREAM_SEEK_CUR : offset = _offset + distanceToMove; break; - case STREAM_SEEK_END : offset = _size + distanceToMove; break; - default : offset = -1; - } - if (offset < 0) { - SetLastError( EINVAL ); - return false; - } - if (offset > _size) offset = _size; - newPosition = _offset = offset; - return true; - } -#endif - - bool ret = true; - - off_t pos = (off_t)distanceToMove; - - off_t newpos = ::lseek(_fd,pos,moveMethod); - - if (newpos == ((off_t)-1)) { - ret = false; - } else { - newPosition = (UINT64)newpos; - } - - return ret; -} - -bool CFileBase::Seek(UINT64 position, UINT64 &newPosition) -{ - return Seek(position, FILE_BEGIN, newPosition); -} - -///////////////////////// -// CInFile - -bool CInFile::Open(CFSTR fileName, DWORD shareMode, - DWORD creationDisposition, DWORD flagsAndAttributes) -{ - return Create(fileName, GENERIC_READ, shareMode, - creationDisposition, flagsAndAttributes); -} - -bool CInFile::Open(CFSTR fileName,bool ignoreSymbolicLink) -{ - return Create(fileName, GENERIC_READ , FILE_SHARE_READ, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL,ignoreSymbolicLink); -} - -// ReadFile and WriteFile functions in Windows have BUG: -// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) -// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES -// (Insufficient system resources exist to complete the requested service). - -// static UINT32 kChunkSizeMax = (1 << 24); - -bool CInFile::ReadPart(void *data, UINT32 size, UINT32 &processedSize) -{ - // if (size > kChunkSizeMax) - // size = kChunkSizeMax; - return Read(data,size,processedSize); -} - -bool CInFile::Read(void *buffer, UINT32 bytesToRead, UINT32 &bytesRead) -{ - if (_fd == -1) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - - if (bytesToRead == 0) { - bytesRead =0; - return TRUE; - } - -#ifdef ENV_HAVE_LSTAT - if (_fd == FD_LINK) { - if (_offset >= _size) { - bytesRead = 0; - return TRUE; - } - int len = (_size - _offset); - if (len > bytesToRead) len = bytesToRead; - memcpy(buffer,_buffer+_offset,len); - bytesRead = len; - _offset += len; - return TRUE; - } -#endif - - ssize_t ret; - do { - ret = read(_fd,buffer,bytesToRead); - } while (ret < 0 && (errno == EINTR)); - - if (ret != -1) { - bytesRead = ret; - return TRUE; - } - bytesRead =0; - return FALSE; -} - -///////////////////////// -// COutFile - -bool COutFile::Open(CFSTR fileName, DWORD shareMode, - DWORD creationDisposition, DWORD flagsAndAttributes) -{ - return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, - creationDisposition, flagsAndAttributes); -} - -static inline DWORD GetCreationDisposition(bool createAlways) - { return createAlways? CREATE_ALWAYS: CREATE_NEW; } - -bool COutFile::Open(CFSTR fileName, DWORD creationDisposition) -{ - return Open(fileName, FILE_SHARE_READ, - creationDisposition, FILE_ATTRIBUTE_NORMAL); -} - -bool COutFile::Create(CFSTR fileName, bool createAlways) -{ - return Open(fileName, GetCreationDisposition(createAlways)); -} - -bool COutFile::CreateAlways(CFSTR fileName, DWORD /* flagsAndAttributes */ ) -{ - return Open(fileName, true); // FIXME -} - -bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw() -{ - LARGE_INTEGER ltime; - DWORD dw; - - if (_fd == -1) { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - - /* On some OS (cygwin, MacOSX ...), you must close the file before updating times */ - if (aTime) { - ltime.QuadPart = aTime->dwHighDateTime; - ltime.QuadPart = (ltime.QuadPart << 32) | aTime->dwLowDateTime; - RtlTimeToSecondsSince1970( <ime, &dw ); - _lastAccessTime = dw; - } - if (mTime) { - ltime.QuadPart = mTime->dwHighDateTime; - ltime.QuadPart = (ltime.QuadPart << 32) | mTime->dwLowDateTime; - RtlTimeToSecondsSince1970( <ime, &dw ); - _lastWriteTime = dw; - } - - return true; -} - -bool COutFile::SetMTime(const FILETIME *mTime) throw() -{ - return SetTime(NULL, NULL, mTime); -} - -bool COutFile::WritePart(const void *data, UINT32 size, UINT32 &processedSize) throw() -{ -// if (size > kChunkSizeMax) -// size = kChunkSizeMax; - - return Write(data,size,processedSize); -} - -bool COutFile::Write(const void *buffer, UINT32 bytesToWrite, UINT32 &bytesWritten) throw() -{ - if (_fd == -1) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - - ssize_t ret; - do { - ret = write(_fd,buffer, bytesToWrite); - } while (ret < 0 && (errno == EINTR)); - - if (ret != -1) { - bytesWritten = ret; - return TRUE; - } - bytesWritten =0; - return FALSE; -} - -bool COutFile::SetEndOfFile() throw() -{ - if (_fd == -1) - { - SetLastError( ERROR_INVALID_HANDLE ); - return false; - } - - bool bret = false; - - off_t pos_cur = lseek(_fd, 0, SEEK_CUR); - if (pos_cur != (off_t)-1) { - int iret = ftruncate(_fd, pos_cur); - if (iret == 0) bret = true; - } - - return bret; -} - -bool COutFile::SetLength(UINT64 length) throw() -{ - UINT64 newPosition; - if(!Seek(length, newPosition)) - return false; - if(newPosition != length) - return false; - return SetEndOfFile(); -} - -}}} +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#ifdef Z7_DEVICE_FILE +#include "../../C/Alloc.h" +#endif + +// #include + +/* +#ifndef _WIN32 +// for ioctl BLKGETSIZE64 +#include +#include +#endif +*/ + +#include "FileIO.h" +#include "FileName.h" + +HRESULT GetLastError_noZero_HRESULT() +{ + const DWORD res = ::GetLastError(); + if (res == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(res); +} + +#ifdef _WIN32 + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +namespace NWindows { +namespace NFile { + +#ifdef Z7_DEVICE_FILE + +namespace NSystem +{ +bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); +} +#endif + +namespace NIO { + +/* +WinXP-64 CreateFile(): + "" - ERROR_PATH_NOT_FOUND + :stream - OK + .:stream - ERROR_PATH_NOT_FOUND + .\:stream - OK + + folder\:stream - ERROR_INVALID_NAME + folder:stream - OK + + c:\:stream - OK + + c::stream - ERROR_INVALID_NAME, if current dir is NOT ROOT ( c:\dir1 ) + c::stream - OK, if current dir is ROOT ( c:\ ) +*/ + +bool CFileBase::Create(CFSTR path, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + if (!Close()) + return false; + + #ifdef Z7_DEVICE_FILE + IsDeviceFile = false; + #endif + + #ifndef _UNICODE + if (!g_IsNT) + { + _handle = ::CreateFile(fs2fas(path), desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL); + } + else + #endif + { + IF_USE_MAIN_PATH + _handle = ::CreateFileW(fs2us(path), desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL); + #ifdef Z7_LONG_PATH + if (_handle == INVALID_HANDLE_VALUE && USE_SUPER_PATH) + { + UString superPath; + if (GetSuperPath(path, superPath, USE_MAIN_PATH)) + _handle = ::CreateFileW(superPath, desiredAccess, shareMode, + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL); + } + #endif + } + + /* + #ifndef UNDER_CE + #ifndef Z7_SFX + if (_handle == INVALID_HANDLE_VALUE) + { + // it's debug hack to open symbolic links in Windows XP and WSL links in Windows 10 + DWORD lastError = GetLastError(); + if (lastError == ERROR_CANT_ACCESS_FILE) + { + CByteBuffer buf; + if (NIO::GetReparseData(path, buf, NULL)) + { + CReparseAttr attr; + if (attr.Parse(buf, buf.Size())) + { + FString dirPrefix, fileName; + if (NDir::GetFullPathAndSplit(path, dirPrefix, fileName)) + { + FString fullPath; + if (GetFullPath(dirPrefix, us2fs(attr.GetPath()), fullPath)) + { + // FIX IT: recursion levels must be restricted + return Create(fullPath, desiredAccess, + shareMode, creationDisposition, flagsAndAttributes); + } + } + } + } + SetLastError(lastError); + } + } + #endif + #endif + */ + + return (_handle != INVALID_HANDLE_VALUE); +} + +bool CFileBase::Close() throw() +{ + if (_handle == INVALID_HANDLE_VALUE) + return true; +#if 0 + if (!IsStdStream) +#endif + { + if (!::CloseHandle(_handle)) + return false; + } +#if 0 + IsStdStream = false; + IsStdPipeStream = false; +#endif + _handle = INVALID_HANDLE_VALUE; + return true; +} + +bool CFileBase::GetLength(UInt64 &length) const throw() +{ + #ifdef Z7_DEVICE_FILE + if (IsDeviceFile && SizeDefined) + { + length = Size; + return true; + } + #endif + + DWORD high = 0; + const DWORD low = ::GetFileSize(_handle, &high); + if (low == INVALID_FILE_SIZE) + if (::GetLastError() != NO_ERROR) + return false; + length = (((UInt64)high) << 32) + low; + return true; + + /* + LARGE_INTEGER fileSize; + // GetFileSizeEx() is unsupported in 98/ME/NT, and supported in Win2000+ + if (!GetFileSizeEx(_handle, &fileSize)) + return false; + length = (UInt64)fileSize.QuadPart; + return true; + */ +} + + +/* Specification for SetFilePointer(): + + If a new file pointer is a negative value, + { + the function fails, + the file pointer is not moved, + the code returned by GetLastError() is ERROR_NEGATIVE_SEEK. + } + + If the hFile handle is opened with the FILE_FLAG_NO_BUFFERING flag set + { + an application can move the file pointer only to sector-aligned positions. + A sector-aligned position is a position that is a whole number multiple of + the volume sector size. + An application can obtain a volume sector size by calling the GetDiskFreeSpace. + } + + It is not an error to set a file pointer to a position beyond the end of the file. + The size of the file does not increase until you call the SetEndOfFile, WriteFile, or WriteFileEx function. + + If the return value is INVALID_SET_FILE_POINTER and if lpDistanceToMoveHigh is non-NULL, + an application must call GetLastError to determine whether or not the function has succeeded or failed. +*/ + +bool CFileBase::GetPosition(UInt64 &position) const throw() +{ + LONG high = 0; + const DWORD low = ::SetFilePointer(_handle, 0, &high, FILE_CURRENT); + if (low == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) + { + // for error case we can set (position) to (-1) or (0) or leave (position) unchanged. + // position = (UInt64)(Int64)-1; // for debug + position = 0; + return false; + } + position = (((UInt64)(UInt32)high) << 32) + low; + return true; + // we don't want recursed GetPosition() + // return Seek(0, FILE_CURRENT, position); +} + +bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw() +{ + #ifdef Z7_DEVICE_FILE + if (IsDeviceFile && SizeDefined && moveMethod == FILE_END) + { + distanceToMove += Size; + moveMethod = FILE_BEGIN; + } + #endif + + LONG high = (LONG)(distanceToMove >> 32); + const DWORD low = ::SetFilePointer(_handle, (LONG)(distanceToMove & 0xFFFFFFFF), &high, moveMethod); + if (low == INVALID_SET_FILE_POINTER) + { + const DWORD lastError = ::GetLastError(); + if (lastError != NO_ERROR) + { + // 21.07: we set (newPosition) to real position even after error. + GetPosition(newPosition); + SetLastError(lastError); // restore LastError + return false; + } + } + newPosition = (((UInt64)(UInt32)high) << 32) + low; + return true; +} + +bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) const throw() +{ + return Seek((Int64)position, FILE_BEGIN, newPosition); +} + +bool CFileBase::SeekToBegin() const throw() +{ + UInt64 newPosition = 0; + return Seek(0, newPosition) && (newPosition == 0); +} + +bool CFileBase::SeekToEnd(UInt64 &newPosition) const throw() +{ + return Seek(0, FILE_END, newPosition); +} + +// ---------- CInFile --------- + +#ifdef Z7_DEVICE_FILE + +void CInFile::CorrectDeviceSize() +{ + // maybe we must decrease kClusterSize to 1 << 12, if we want correct size at tail + const UInt32 kClusterSize = 1 << 14; + UInt64 pos = Size & ~(UInt64)(kClusterSize - 1); + UInt64 realNewPosition; + if (!Seek(pos, realNewPosition)) + return; + Byte *buf = (Byte *)MidAlloc(kClusterSize); + + bool needbackward = true; + + for (;;) + { + UInt32 processed = 0; + // up test is slow for "PhysicalDrive". + // processed size for latest block for "PhysicalDrive0" is 0. + if (!Read1(buf, kClusterSize, processed)) + break; + if (processed == 0) + break; + needbackward = false; + Size = pos + processed; + if (processed != kClusterSize) + break; + pos += kClusterSize; + } + + if (needbackward && pos != 0) + { + pos -= kClusterSize; + for (;;) + { + // break; + if (!Seek(pos, realNewPosition)) + break; + if (!buf) + { + buf = (Byte *)MidAlloc(kClusterSize); + if (!buf) + break; + } + UInt32 processed = 0; + // that code doesn't work for "PhysicalDrive0" + if (!Read1(buf, kClusterSize, processed)) + break; + if (processed != 0) + { + Size = pos + processed; + break; + } + if (pos == 0) + break; + pos -= kClusterSize; + } + } + MidFree(buf); +} + + +void CInFile::CalcDeviceSize(CFSTR s) +{ + SizeDefined = false; + Size = 0; + if (_handle == INVALID_HANDLE_VALUE || !IsDeviceFile) + return; + #ifdef UNDER_CE + + SizeDefined = true; + Size = 128 << 20; + + #else + + PARTITION_INFORMATION partInfo; + bool needCorrectSize = true; + + /* + WinXP 64-bit: + + HDD \\.\PhysicalDrive0 (MBR): + GetPartitionInfo == GeometryEx : corrrect size? (includes tail) + Geometry : smaller than GeometryEx (no tail, maybe correct too?) + MyGetDiskFreeSpace : FAIL + Size correction is slow and block size (kClusterSize) must be small? + + HDD partition \\.\N: (NTFS): + MyGetDiskFreeSpace : Size of NTFS clusters. Same size can be calculated after correction + GetPartitionInfo : size of partition data: NTFS clusters + TAIL; TAIL contains extra empty sectors and copy of first sector of NTFS + Geometry / CdRomGeometry / GeometryEx : size of HDD (not that partition) + + CD-ROM drive (ISO): + MyGetDiskFreeSpace : correct size. Same size can be calculated after correction + Geometry == CdRomGeometry : smaller than corrrect size + GetPartitionInfo == GeometryEx : larger than corrrect size + + Floppy \\.\a: (FAT): + Geometry : correct size. + CdRomGeometry / GeometryEx / GetPartitionInfo / MyGetDiskFreeSpace - FAIL + correction works OK for FAT. + correction works OK for non-FAT, if kClusterSize = 512. + */ + + if (GetPartitionInfo(&partInfo)) + { + Size = (UInt64)partInfo.PartitionLength.QuadPart; + SizeDefined = true; + needCorrectSize = false; + if ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\' && (s)[5] == ':' && (s)[6] == 0) + { + FChar path[4] = { s[4], ':', '\\', 0 }; + UInt64 clusterSize, totalSize, freeSize; + if (NSystem::MyGetDiskFreeSpace(path, clusterSize, totalSize, freeSize)) + Size = totalSize; + else + needCorrectSize = true; + } + } + + if (!SizeDefined) + { + my_DISK_GEOMETRY_EX geomEx; + SizeDefined = GetGeometryEx(&geomEx); + if (SizeDefined) + Size = (UInt64)geomEx.DiskSize.QuadPart; + else + { + DISK_GEOMETRY geom; + SizeDefined = GetGeometry(&geom); + if (!SizeDefined) + SizeDefined = GetCdRomGeometry(&geom); + if (SizeDefined) + Size = (UInt64)geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector; + } + } + + if (needCorrectSize && SizeDefined && Size != 0) + { + CorrectDeviceSize(); + SeekToBegin(); + } + + // SeekToBegin(); + #endif +} + +// ((desiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)) == 0 && + +#define MY_DEVICE_EXTRA_CODE \ + IsDeviceFile = IsDevicePath(fileName); \ + CalcDeviceSize(fileName); +#else +#define MY_DEVICE_EXTRA_CODE +#endif + +bool CInFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) +{ + DWORD desiredAccess = GENERIC_READ; + + #ifdef _WIN32 + if (PreserveATime) + desiredAccess |= FILE_WRITE_ATTRIBUTES; + #endif + + bool res = Create(fileName, desiredAccess, shareMode, creationDisposition, flagsAndAttributes); + + #ifdef _WIN32 + if (res && PreserveATime) + { + FILETIME ft; + ft.dwHighDateTime = ft.dwLowDateTime = 0xFFFFFFFF; + ::SetFileTime(_handle, NULL, &ft, NULL); + } + #endif + + MY_DEVICE_EXTRA_CODE + return res; +} + +bool CInFile::OpenShared(CFSTR fileName, bool shareForWrite) +{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } + +bool CInFile::Open(CFSTR fileName) + { return OpenShared(fileName, false); } + +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +// Probably in some version of Windows there are problems with other sizes: +// for 32 MB (maybe also for 16 MB). +// And message can be "Network connection was lost" + +static const UInt32 kChunkSizeMax = 1 << 22; + +bool CInFile::Read1(void *data, UInt32 size, UInt32 &processedSize) throw() +{ + DWORD processedLoc = 0; + const bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw() +{ +#if 0 + const UInt32 chunkSizeMax = (0 || IsStdStream) ? (1 << 20) : kChunkSizeMax; + if (size > chunkSizeMax) + size = chunkSizeMax; +#else + if (size > kChunkSizeMax) + size = kChunkSizeMax; +#endif + return Read1(data, size, processedSize); +} + +bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) throw() +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + const bool res = ReadPart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((Byte *)data + processedLoc); + size -= processedLoc; + } + while (size); + return true; +} + +bool CInFile::ReadFull(void *data, size_t size, size_t &processedSize) throw() +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + const UInt32 sizeLoc = (size > kChunkSizeMax ? (UInt32)kChunkSizeMax : (UInt32)size); + const bool res = Read1(data, sizeLoc, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((Byte *)data + processedLoc); + size -= processedLoc; + } + while (size); + return true; +} + +// ---------- COutFile --------- + +bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } + +bool COutFile::Open_Disposition(CFSTR fileName, DWORD creationDisposition) + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } + +bool COutFile::Create_ALWAYS_with_Attribs(CFSTR fileName, DWORD flagsAndAttributes) + { return Open(fileName, FILE_SHARE_READ, CREATE_ALWAYS, flagsAndAttributes); } + +bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw() + { return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); } + +bool COutFile::SetMTime(const FILETIME *mTime) throw() { return SetTime(NULL, NULL, mTime); } + +bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw() +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UInt32)processedLoc; + return res; +} + +bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw() +{ + processedSize = 0; + do + { + UInt32 processedLoc = 0; + const bool res = WritePart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (const void *)((const Byte *)data + processedLoc); + size -= processedLoc; + } + while (size); + return true; +} + +bool COutFile::WriteFull(const void *data, size_t size) throw() +{ + do + { + UInt32 processedLoc = 0; + const UInt32 sizeCur = (size > kChunkSizeMax ? kChunkSizeMax : (UInt32)size); + if (!WritePart(data, sizeCur, processedLoc)) + return false; + if (processedLoc == 0) + return (size == 0); + data = (const void *)((const Byte *)data + processedLoc); + size -= processedLoc; + } + while (size); + return true; +} + +bool COutFile::SetEndOfFile() throw() { return BOOLToBool(::SetEndOfFile(_handle)); } + +bool COutFile::SetLength(UInt64 length) throw() +{ + UInt64 newPosition; + if (!Seek(length, newPosition)) + return false; + if (newPosition != length) + return false; + return SetEndOfFile(); +} + +bool COutFile::SetLength_KeepPosition(UInt64 length) throw() +{ + UInt64 currentPos = 0; + if (!GetPosition(currentPos)) + return false; + DWORD lastError = 0; + const bool result = SetLength(length); + if (!result) + lastError = GetLastError(); + UInt64 currentPos2; + const bool result2 = Seek(currentPos, currentPos2); + if (lastError != 0) + SetLastError(lastError); + return (result && result2); +} + +}}} + +#else // _WIN32 + + +// POSIX + +#include +#include + +namespace NWindows { +namespace NFile { + +namespace NDir { +bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime); +} + +namespace NIO { + +bool CFileBase::OpenBinary(const char *name, int flags, mode_t mode) +{ + #ifdef O_BINARY + flags |= O_BINARY; + #endif + + Close(); + _handle = ::open(name, flags, mode); + 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() +{ + if (_handle == -1) + return true; + if (close(_handle) != 0) + return false; + _handle = -1; + /* + IsDeviceFile = false; + SizeDefined = false; + */ + return true; +} + +bool CFileBase::GetLength(UInt64 &length) const +{ + length = 0; + // length = (UInt64)(Int64)-1; // for debug + const off_t curPos = seekToCur(); + if (curPos == -1) + return false; + 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); + // return res; +} + +off_t CFileBase::seekToBegin() const throw() +{ + return seek(0, SEEK_SET); +} + +off_t CFileBase::seekToCur() const throw() +{ + return seek(0, SEEK_CUR); +} + +/* +bool CFileBase::SeekToBegin() const throw() +{ + return (::seek(0, SEEK_SET) != -1); +} +*/ + + +///////////////////////// +// CInFile + +bool CInFile::Open(const char *name) +{ + return CFileBase::OpenBinary(name, O_RDONLY); +} + +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 +0x7ffff000 = (2GiB - 4 KiB) bytes, returning the number of bytes actually transferred. +*/ + +static const size_t kChunkSizeMax = ((size_t)1 << 22); + +ssize_t CInFile::read_part(void *data, size_t size) throw() +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + return ::read(_handle, data, size); +} + +bool CInFile::ReadFull(void *data, size_t size, size_t &processed) throw() +{ + processed = 0; + do + { + const ssize_t res = read_part(data, size); + if (res < 0) + return false; + if (res == 0) + break; + data = (void *)((Byte *)data + (size_t)res); + processed += (size_t)res; + size -= (size_t)res; + } + while (size); + return true; +} + + +///////////////////////// +// COutFile + +bool COutFile::OpenBinary_forWrite_oflag(const char *name, int oflag) +{ + Path = name; // change it : set it only if open is success. + return OpenBinary(name, oflag, mode_for_Create); +} + + +/* + windows exist non-exist posix + CREATE_NEW Fail Create O_CREAT | O_EXCL + CREATE_ALWAYS Trunc Create O_CREAT | O_TRUNC + OPEN_ALWAYS Open Create O_CREAT + OPEN_EXISTING Open Fail 0 + TRUNCATE_EXISTING Trunc Fail O_TRUNC ??? + + // O_CREAT = If the file exists, this flag has no effect except as noted under O_EXCL below. + // If O_CREAT and O_EXCL are set, open() shall fail if the file exists. + // O_TRUNC : If the file exists and the file is successfully opened, its length shall be truncated to 0. +*/ +bool COutFile::Open_EXISTING(const char *name) + { return OpenBinary_forWrite_oflag(name, O_WRONLY); } +bool COutFile::Create_ALWAYS(const char *name) + { return OpenBinary_forWrite_oflag(name, O_WRONLY | O_CREAT | O_TRUNC); } +bool COutFile::Create_NEW(const char *name) + { return OpenBinary_forWrite_oflag(name, O_WRONLY | O_CREAT | O_EXCL); } +bool COutFile::Create_ALWAYS_or_Open_ALWAYS(const char *name, bool createAlways) +{ + return OpenBinary_forWrite_oflag(name, + createAlways ? + O_WRONLY | O_CREAT | O_TRUNC : + O_WRONLY | O_CREAT); +} +/* +bool COutFile::Create_ALWAYS_or_NEW(const char *name, bool createAlways) +{ + return OpenBinary_forWrite_oflag(name, + createAlways ? + O_WRONLY | O_CREAT | O_TRUNC : + O_WRONLY | O_CREAT | O_EXCL); +} +bool COutFile::Open_Disposition(const char *name, DWORD creationDisposition) +{ + int flag; + switch (creationDisposition) + { + case CREATE_NEW: flag = O_WRONLY | O_CREAT | O_EXCL; break; + case CREATE_ALWAYS: flag = O_WRONLY | O_CREAT | O_TRUNC; break; + case OPEN_ALWAYS: flag = O_WRONLY | O_CREAT; break; + case OPEN_EXISTING: flag = O_WRONLY; break; + case TRUNCATE_EXISTING: flag = O_WRONLY | O_TRUNC; break; + default: + SetLastError(EINVAL); + return false; + } + return OpenBinary_forWrite_oflag(name, flag); +} +*/ + +ssize_t COutFile::write_part(const void *data, size_t size) throw() +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + return ::write(_handle, data, size); +} + +ssize_t COutFile::write_full(const void *data, size_t size, size_t &processed) throw() +{ + processed = 0; + do + { + const ssize_t res = write_part(data, size); + if (res < 0) + return res; + if (res == 0) + break; + data = (const void *)((const Byte *)data + (size_t)res); + processed += (size_t)res; + size -= (size_t)res; + } + while (size); + return (ssize_t)processed; +} + +bool COutFile::SetLength(UInt64 length) throw() +{ + const off_t len2 = (off_t)length; + if ((Int64)length != len2) + { + SetLastError(EFBIG); + return false; + } + // The value of the seek pointer shall not be modified by a call to ftruncate(). + const int iret = ftruncate(_handle, len2); + return (iret == 0); +} + +bool COutFile::Close() +{ + const bool res = CFileBase::Close(); + if (!res) + return res; + if (CTime_defined || ATime_defined || MTime_defined) + { + /* bool res2 = */ NWindows::NFile::NDir::SetDirTime(Path, + CTime_defined ? &CTime : NULL, + ATime_defined ? &ATime : NULL, + MTime_defined ? &MTime : NULL); + } + return res; +} + +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; + + if (cTime) { CTime = *cTime; CTime_defined = true; } else CTime_defined = false; + 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 CFiTime *mTime) throw() +{ + if (mTime) { MTime = *mTime; MTime_defined = true; } else MTime_defined = false; + return true; +} + +}}} + + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileIO.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.h --- p7zip-rar-16.02/CPP/Windows/FileIO.h 2015-10-03 10:08:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileIO.h 2025-06-20 11:15:00.000000000 +0000 @@ -1,108 +1,467 @@ -// Windows/FileIO.h - -#ifndef __WINDOWS_FILEIO_H -#define __WINDOWS_FILEIO_H - -#include - -#ifndef _WIN32 - -#define FILE_SHARE_READ 1 -#define FILE_SHARE_WRITE 2 - -#define FILE_BEGIN SEEK_SET -#define FILE_CURRENT SEEK_CUR -#define FILE_END SEEK_END -#define INVALID_SET_FILE_POINTER ((DWORD)-1) - -#endif - -#define _my_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) -#define _my_IO_REPARSE_TAG_SYMLINK (0xA000000CL) - -#define _my_SYMLINK_FLAG_RELATIVE 1 - -namespace NWindows { -namespace NFile { - -struct CReparseAttr -{ - UInt32 Tag; - UInt32 Flags; - UString SubsName; - UString PrintName; - - CReparseAttr(): Tag(0), Flags(0) {} - bool Parse(const Byte *p, size_t size); - - bool IsMountPoint() const { return Tag == _my_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction - bool IsSymLink() const { return Tag == _my_IO_REPARSE_TAG_SYMLINK; } - bool IsRelative() const { return Flags == _my_SYMLINK_FLAG_RELATIVE; } - // bool IsVolume() const; - - bool IsOkNamePair() const; - UString GetPath() const; -}; - -namespace NIO { - - -class CFileBase -{ -protected: - int _fd; - AString _unix_filename; - time_t _lastAccessTime; - time_t _lastWriteTime; -#ifdef ENV_HAVE_LSTAT - int _size; - char _buffer[MAX_PATHNAME_LEN+1]; - int _offset; -#endif - - bool Create(CFSTR fileName, DWORD desiredAccess, - DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink=false); - -public: - CFileBase(): _fd(-1) {}; - virtual ~CFileBase(); - - virtual bool Close(); - - bool GetLength(UINT64 &length) const; - - bool Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition); - bool Seek(UINT64 position, UINT64 &newPosition); -}; - -class CInFile: public CFileBase -{ -public: - bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); - bool OpenShared(CFSTR fileName, bool /* shareForWrite */ ,bool ignoreSymbolicLink=false) { - return Open(fileName,ignoreSymbolicLink); - } - bool Open(CFSTR fileName,bool ignoreSymbolicLink=false); - bool ReadPart(void *data, UINT32 size, UINT32 &processedSize); - bool Read(void *data, UINT32 size, UINT32 &processedSize); -}; - -class COutFile: public CFileBase -{ -public: - bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); - bool Open(CFSTR fileName, DWORD creationDisposition); - 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 WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw(); - bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw(); - bool SetEndOfFile() throw(); - bool SetLength(UInt64 length) throw(); -}; - -}}} - -#endif +// Windows/FileIO.h + +#ifndef ZIP7_INC_WINDOWS_FILE_IO_H +#define ZIP7_INC_WINDOWS_FILE_IO_H + +#include "../Common/MyWindows.h" + +#define Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#define Z7_WIN_IO_REPARSE_TAG_SYMLINK (0xA000000CL) +#define Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL) + +#define Z7_WIN_SYMLINK_FLAG_RELATIVE 1 + +#define Z7_WIN_LX_SYMLINK_VERSION_2 2 + +#ifdef _WIN32 + +#if defined(_WIN32) && !defined(UNDER_CE) +#include +#endif + +#else + +#include +#include + +#endif + +#include "../Common/MyString.h" +#include "../Common/MyBuffer.h" + +#include "../Windows/TimeUtils.h" + +#include "Defs.h" + +HRESULT GetLastError_noZero_HRESULT(); + +#define my_FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER +#define my_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) // REPARSE_DATA_BUFFER +#define my_FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER + +namespace NWindows { +namespace NFile { + +#if defined(_WIN32) && !defined(UNDER_CE) +/* + in: (CByteBuffer &dest) is empty + in: (path) uses Windows path separator (\). + out: (path) uses Linux path separator (/). + if (isAbsPath == true), then "c:\\" prefix is replaced to "/mnt/c/" prefix +*/ +void Convert_WinPath_to_WslLinuxPath(FString &path, bool convertDrivePath); +// (path) must use Linux path separator (/). +void FillLinkData_WslLink(CByteBuffer &dest, const wchar_t *path); + +/* + in: (CByteBuffer &dest) is empty + if (isSymLink == false) : MOUNT_POINT : (path) must be absolute. + if (isSymLink == true) : SYMLINK : Windows + (path) must use Windows path separator (\). + (path) must be without link "\\??\\" prefix. + link "\\??\\" prefix will be added inside FillLinkData(), if path is absolute. +*/ +void FillLinkData_WinLink(CByteBuffer &dest, const wchar_t *path, bool isSymLink); +// in: (CByteBuffer &dest) is empty +inline void FillLinkData(CByteBuffer &dest, const wchar_t *path, bool isSymLink, bool isWSL) +{ + if (isWSL) + FillLinkData_WslLink(dest, path); + else + FillLinkData_WinLink(dest, path, isSymLink); +} +#endif + +struct CReparseShortInfo +{ + unsigned Offset; + unsigned Size; + + bool Parse(const Byte *p, size_t size); +}; + +struct CReparseAttr +{ + UInt32 Tag; + UInt32 Flags; + UString SubsName; + UString PrintName; + AString WslName; + + bool HeaderError; + bool TagIsUnknown; + bool MinorError; + DWORD ErrorCode; + + CReparseAttr(): Tag(0), Flags(0) {} + + // returns (true) and (ErrorCode = 0), if (it's correct known link) + // returns (false) and (ErrorCode = ERROR_REPARSE_TAG_INVALID), if unknown tag + bool Parse(const Byte *p, size_t size); + + bool IsMountPoint() const { return Tag == Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT; } // it's Junction + bool IsSymLink_Win() const { return Tag == Z7_WIN_IO_REPARSE_TAG_SYMLINK; } + bool IsSymLink_WSL() const { return Tag == Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK; } + + // note: "/dir1/path" is marked as relative. + bool IsRelative_Win() const { return Flags == Z7_WIN_SYMLINK_FLAG_RELATIVE; } + + bool IsRelative_WSL() const + { + return WslName[0] != '/'; // WSL uses unix path separator + } + + bool IsOkNamePair() const; + UString GetPath() const; +}; + +#ifdef _WIN32 +#define CFiInfo BY_HANDLE_FILE_INFORMATION +#define ST_MTIME(st) (st).ftLastWriteTime +#else +#define CFiInfo stat +#endif + +#ifdef _WIN32 + +namespace NIO { + +bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo = NULL); +bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size); +bool DeleteReparseData(CFSTR path); + +class CFileBase MY_UNCOPYABLE +{ +protected: + HANDLE _handle; + + bool Create(CFSTR path, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + +public: + + bool DeviceIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inSize, + LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned, LPOVERLAPPED overlapped = NULL) const + { + return BOOLToBool(::DeviceIoControl(_handle, controlCode, inBuffer, inSize, + outBuffer, outSize, bytesReturned, overlapped)); + } + + bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize, LPDWORD bytesReturned) const + { + return DeviceIoControl(controlCode, NULL, 0, outBuffer, outSize, bytesReturned); + } + + bool DeviceIoControlOut(DWORD controlCode, LPVOID outBuffer, DWORD outSize) const + { + DWORD bytesReturned; + return DeviceIoControlOut(controlCode, outBuffer, outSize, &bytesReturned); + } + +public: + bool PreserveATime; +#if 0 + bool IsStdStream; + bool IsStdPipeStream; +#endif +#ifdef Z7_DEVICE_FILE + bool IsDeviceFile; + bool SizeDefined; + UInt64 Size; // it can be larger than real available size +#endif + + CFileBase(): + _handle(INVALID_HANDLE_VALUE), + PreserveATime(false) +#if 0 + , IsStdStream(false), + , IsStdPipeStream(false) +#endif + {} + ~CFileBase() { Close(); } + + HANDLE GetHandle() const { return _handle; } + + // void Detach() { _handle = INVALID_HANDLE_VALUE; } + + bool Close() throw(); + + bool GetPosition(UInt64 &position) const throw(); + bool GetLength(UInt64 &length) const throw(); + + bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const throw(); + bool Seek(UInt64 position, UInt64 &newPosition) const throw(); + bool SeekToBegin() const throw(); + bool SeekToEnd(UInt64 &newPosition) const throw(); + + bool GetFileInformation(BY_HANDLE_FILE_INFORMATION *info) const + { return BOOLToBool(GetFileInformationByHandle(_handle, info)); } + + static bool GetFileInformation(CFSTR path, BY_HANDLE_FILE_INFORMATION *info) + { + // probably it can work for complex paths: unsupported by another things + NIO::CFileBase file; + if (!file.Create(path, 0, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS)) + return false; + return file.GetFileInformation(info); + } +}; + +#ifndef UNDER_CE +#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM +#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS) +// #define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS) + +// IOCTL_DISK_GET_DRIVE_GEOMETRY_EX works since WinXP +#define my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS) + +struct my_DISK_GEOMETRY_EX +{ + DISK_GEOMETRY Geometry; + LARGE_INTEGER DiskSize; + BYTE Data[1]; +}; +#endif + +class CInFile: public CFileBase +{ + #ifdef Z7_DEVICE_FILE + + #ifndef UNDER_CE + + bool GetGeometry(DISK_GEOMETRY *res) const + { return DeviceIoControlOut(IOCTL_DISK_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } + + bool GetGeometryEx(my_DISK_GEOMETRY_EX *res) const + { return DeviceIoControlOut(my_IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, res, sizeof(*res)); } + + bool GetCdRomGeometry(DISK_GEOMETRY *res) const + { return DeviceIoControlOut(IOCTL_CDROM_GET_DRIVE_GEOMETRY, res, sizeof(*res)); } + + bool GetPartitionInfo(PARTITION_INFORMATION *res) + { return DeviceIoControlOut(IOCTL_DISK_GET_PARTITION_INFO, LPVOID(res), sizeof(*res)); } + + #endif + + void CorrectDeviceSize(); + void CalcDeviceSize(CFSTR name); + + #endif + +public: + bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool OpenShared(CFSTR fileName, bool shareForWrite); + bool Open(CFSTR fileName); + +#if 0 + bool AttachStdIn() + { + IsDeviceFile = false; + const HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (h == INVALID_HANDLE_VALUE || !h) + return false; + IsStdStream = true; + IsStdPipeStream = true; + _handle = h; + return true; + } +#endif + + #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 Open_for_FileRenameInformation(CFSTR fileName) + { + return Create(fileName, DELETE | SYNCHRONIZE | GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); + // 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: + // we use Create() with (desiredAccess = 0) instead of Open() with GENERIC_READ + return + Create(fileName, 0, + // Open(fileName, + FILE_SHARE_READ, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS); + } + + #endif + + bool Read1(void *data, UInt32 size, UInt32 &processedSize) throw(); + bool ReadPart(void *data, UInt32 size, UInt32 &processedSize) throw(); + bool Read(void *data, UInt32 size, UInt32 &processedSize) throw(); + bool ReadFull(void *data, size_t size, size_t &processedSize) throw(); +}; + +class COutFile: public CFileBase +{ + bool Open_Disposition(CFSTR fileName, DWORD creationDisposition); +public: + bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open_EXISTING(CFSTR fileName) + { return Open_Disposition(fileName, OPEN_EXISTING); } + bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways) + { return Open_Disposition(fileName, createAlways ? CREATE_ALWAYS : OPEN_ALWAYS); } + bool Create_ALWAYS_or_NEW(CFSTR fileName, bool createAlways) + { return Open_Disposition(fileName, createAlways ? CREATE_ALWAYS : CREATE_NEW); } + bool Create_ALWAYS(CFSTR fileName) + { return Open_Disposition(fileName, CREATE_ALWAYS); } + bool Create_NEW(CFSTR fileName) + { return Open_Disposition(fileName, CREATE_NEW); } + + bool Create_ALWAYS_with_Attribs(CFSTR fileName, DWORD flagsAndAttributes); + + 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(); + bool SetEndOfFile() throw(); + bool SetLength(UInt64 length) throw(); + bool SetLength_KeepPosition(UInt64 length) throw(); +}; + +} + + +#else // _WIN32 + +namespace NIO { + +bool GetReparseData(CFSTR path, CByteBuffer &reparseData); +// bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size); + +// parameters are in reverse order of symlink() function !!! +bool SetSymLink(CFSTR from, CFSTR to); +bool SetSymLink_UString(CFSTR from, const UString &to); + + +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, mode_t mode = 0666); +public: + bool PreserveATime; +#if 0 + bool IsStdStream; +#endif + + CFileBase(): _handle(-1), PreserveATime(false) +#if 0 + , IsStdStream(false) +#endif + {} + ~CFileBase() { Close(); } + // void Detach() { _handle = -1; } + bool Close(); + bool GetLength(UInt64 &length) const; + off_t seek(off_t distanceToMove, int moveMethod) const; + off_t seekToBegin() const throw(); + 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 +{ +public: + bool Open(const char *name); + bool OpenShared(const char *name, bool shareForWrite); +#if 0 + bool AttachStdIn() + { + _handle = GetStdHandle(STD_INPUT_HANDLE); + if (_handle == INVALID_HANDLE_VALUE || !_handle) + return false; + IsStdStream = true; + } +#endif + ssize_t read_part(void *data, size_t size) throw(); + // ssize_t read_full(void *data, size_t size, size_t &processed); + bool ReadFull(void *data, size_t size, size_t &processedSize) throw(); +}; + +class COutFile: public CFileBase +{ + bool CTime_defined; + bool ATime_defined; + bool MTime_defined; + CFiTime CTime; + CFiTime ATime; + CFiTime MTime; + + AString Path; + ssize_t write_part(const void *data, size_t size) throw(); + bool OpenBinary_forWrite_oflag(const char *name, int oflag); +public: + mode_t mode_for_Create; + + COutFile(): + CTime_defined(false), + ATime_defined(false), + MTime_defined(false), + mode_for_Create(0666) + {} + + bool Close(); + + bool Open_EXISTING(CFSTR fileName); + bool Create_ALWAYS_or_Open_ALWAYS(CFSTR fileName, bool createAlways); + bool Create_ALWAYS(CFSTR fileName); + bool Create_NEW(CFSTR fileName); + // bool Create_ALWAYS_or_NEW(CFSTR fileName, bool createAlways); + // bool Open_Disposition(const char *name, DWORD creationDisposition); + + ssize_t write_full(const void *data, size_t size, size_t &processed) throw(); + + bool WriteFull(const void *data, size_t size) throw() + { + size_t processed; + ssize_t res = write_full(data, size, processed); + if (res == -1) + return false; + return processed == size; + } + + bool SetLength(UInt64 length) throw(); + bool SetLength_KeepPosition(UInt64 length) throw() + { + return SetLength(length); + } + bool SetTime(const CFiTime *cTime, const CFiTime *aTime, const CFiTime *mTime) throw(); + bool SetMTime(const CFiTime *mTime) throw(); +}; + +} + +#endif // _WIN32 + +}} + + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileLink.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileLink.cpp --- p7zip-rar-16.02/CPP/Windows/FileLink.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileLink.cpp 2025-06-20 11:00:00.000000000 +0000 @@ -0,0 +1,697 @@ +// Windows/FileLink.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef Z7_DEVICE_FILE +#include "../../C/Alloc.h" +#endif + +#include "../Common/UTFConvert.h" +#include "../Common/StringConvert.h" + +#include "FileDir.h" +#include "FileFind.h" +#include "FileIO.h" +#include "FileName.h" + +#ifdef Z7_OLD_WIN_SDK +#ifndef ERROR_INVALID_REPARSE_DATA +#define ERROR_INVALID_REPARSE_DATA 4392L +#endif +#ifndef ERROR_REPARSE_TAG_INVALID +#define ERROR_REPARSE_TAG_INVALID 4393L +#endif +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { + +using namespace NName; + +/* +Win10 Junctions/SymLinks: + - (/) slash doesn't work as path separator + - Win10 preinstalled junctions don't use tail backslash, but tail backslashes also work. + - double backslash works only after drive prefix "c:\\dir1\dir2\", + and doesn't work in another places. + - absolute path without \??\ prefix doesn't work + - absolute path "c:" doesn't work +*/ + +/* + Reparse Points (Junctions and Symbolic Links): + struct + { + UInt32 Tag; + UInt16 Size; // not including starting 8 bytes + UInt16 Reserved; // = 0, DOCs: // Length, in bytes, of the unparsed portion of + // the file name pointed to by the FileName member of the associated file object. + // This member is only valid for create operations when the I/O fails with STATUS_REPARSE. + + UInt16 SubstituteOffset; // offset in bytes from start of namesChars + UInt16 SubstituteLen; // size in bytes, it doesn't include tailed NUL + UInt16 PrintOffset; // offset in bytes from start of namesChars + UInt16 PrintLen; // size in bytes, it doesn't include tailed NUL + + [UInt32] Flags; // for Symbolic Links only. + + UInt16 namesChars[] + } + + MOUNT_POINT (Junction point): + 1) there is NUL wchar after path + 2) Default Order in table: + Substitute Path + Print Path + 3) pathnames can not contain dot directory names + + SYMLINK: + 1) there is no NUL wchar after path + 2) Default Order in table: + Print Path + Substitute Path + +DOCS: + The print name SHOULD be an informative pathname, suitable for display + to a user, that also identifies the target of the mount point. + Neither of these pathnames can contain dot directory names. + +reparse tags, with the exception of IO_REPARSE_TAG_SYMLINK, +are processed on the server and are not processed by a client +after transmission over the wire. +Clients SHOULD treat associated reparse data as opaque data. +*/ + +/* +Win10 WSL2: +admin rights + sudo: it creates normal windows symbolic link. +in another cases : it creates IO_REPARSE_TAG_LX_SYMLINK repare point. +*/ + +/* +static const UInt32 kReparseFlags_Alias = (1 << 29); +static const UInt32 kReparseFlags_HighLatency = (1 << 30); +static const UInt32 kReparseFlags_Microsoft = ((UInt32)1 << 31); + +#define Z7_WIN_IO_REPARSE_TAG_HSM (0xC0000004L) +#define Z7_WIN_IO_REPARSE_TAG_HSM2 (0x80000006L) +#define Z7_WIN_IO_REPARSE_TAG_SIS (0x80000007L) +#define Z7_WIN_IO_REPARSE_TAG_WIM (0x80000008L) +#define Z7_WIN_IO_REPARSE_TAG_CSV (0x80000009L) +#define Z7_WIN_IO_REPARSE_TAG_DFS (0x8000000AL) +#define Z7_WIN_IO_REPARSE_TAG_DFSR (0x80000012L) +*/ + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) + +static const char * const k_LinkPrefix = "\\??\\"; +static const char * const k_LinkPrefix_UNC = "\\??\\UNC\\"; +static const unsigned k_LinkPrefix_Size = 4; + +static bool IsLinkPrefix(const wchar_t *s) +{ + return IsString1PrefixedByString2(s, k_LinkPrefix); +} + +/* +static const char * const k_VolumePrefix = "Volume{"; +static const bool IsVolumeName(const wchar_t *s) +{ + return IsString1PrefixedByString2(s, k_VolumePrefix); +} +*/ + +#if defined(_WIN32) && !defined(UNDER_CE) + +#define Set16(p, v) SetUi16(p, v) +#define Set32(p, v) SetUi32(p, v) + +static void WriteString(Byte *dest, const wchar_t *path) +{ + for (;;) + { + const wchar_t c = *path++; + if (c == 0) + return; + Set16(dest, (UInt16)c) + dest += 2; + } +} + +#ifdef _WIN32 +void Convert_WinPath_to_WslLinuxPath(FString &s, bool convertDrivePath) +{ + if (convertDrivePath && IsDrivePath(s)) + { + FChar c = s[0]; + c = MyCharLower_Ascii(c); + s.DeleteFrontal(2); + s.InsertAtFront(c); + s.Insert(0, FTEXT("/mnt/")); + } + s.Replace(FCHAR_PATH_SEPARATOR, FTEXT('/')); +} +#endif + + +static const unsigned k_Link_Size_Limit = 1u << 16; // 16-bit field is used for size. + +void FillLinkData_WslLink(CByteBuffer &dest, const wchar_t *path) +{ + // dest.Free(); // it's empty already + // WSL probably uses Replacement Character UTF-16 0xFFFD for unsupported characters? + AString utf; + ConvertUnicodeToUTF8(path, utf); + const unsigned size = 4 + utf.Len(); + if (size >= k_Link_Size_Limit) + return; + dest.Alloc(8 + size); + Byte *p = dest; + Set32(p, Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK) + // Set32(p + 4, (UInt32)size) + Set16(p + 4, (UInt16)size) + Set16(p + 6, 0) + Set32(p + 8, Z7_WIN_LX_SYMLINK_VERSION_2) + memcpy(p + 12, utf.Ptr(), utf.Len()); +} + + +void FillLinkData_WinLink(CByteBuffer &dest, const wchar_t *path, bool isSymLink) +{ + // dest.Free(); // it's empty already + bool isAbs = false; + if (IS_PATH_SEPAR(path[0])) + { + // root paths "\dir1\path" are marked as relative + if (IS_PATH_SEPAR(path[1])) + isAbs = true; + } + else + isAbs = IsAbsolutePath(path); + if (!isAbs && !isSymLink) + { + // Win10 allows us to create relative MOUNT_POINT. + // But relative MOUNT_POINT will not work when accessing it. + // So we prevent useless creation of a relative MOUNT_POINT. + return; + } + + bool needPrintName = true; + UString subs (path); + if (isAbs) + { + const bool isSuperPath = IsSuperPath(path); + if (!isSuperPath && NName::IsNetworkPath(us2fs(path))) + { + subs = k_LinkPrefix_UNC; + subs += (path + 2); + } + else + { + if (isSuperPath) + { + // we remove super prefix: + path += kSuperPathPrefixSize; + // we want to get correct abolute path in PrintName still. + if (!IsDrivePath(path)) + needPrintName = false; // we need "\\server\path" for print name. + } + subs = k_LinkPrefix; + subs += path; + } + } + const size_t len1 = subs.Len() * 2; + size_t len2 = (size_t)MyStringLen(path) * 2; + if (!needPrintName) + len2 = 0; + size_t totalNamesSize = len1 + len2; + /* some WIM imagex software uses old scheme for symbolic links. + so we can use old scheme for byte to byte compatibility */ + const bool newOrderScheme = isSymLink; + // newOrderScheme = false; + if (!newOrderScheme) + totalNamesSize += 2 * 2; // we use NULL terminators in old scheme. + + const size_t size = 8 + 8 + (isSymLink ? 4 : 0) + totalNamesSize; + if (size >= k_Link_Size_Limit) + return; + dest.Alloc(size); + memset(dest, 0, size); + const UInt32 tag = isSymLink ? + Z7_WIN_IO_REPARSE_TAG_SYMLINK : + Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT; + Byte *p = dest; + Set32(p, tag) + // Set32(p + 4, (UInt32)(size - 8)) + Set16(p + 4, (UInt16)(size - 8)) + Set16(p + 6, 0) + p += 8; + + unsigned subOffs = 0; + unsigned printOffs = 0; + if (newOrderScheme) + subOffs = (unsigned)len2; + else + printOffs = (unsigned)len1 + 2; + + Set16(p + 0, (UInt16)subOffs) + Set16(p + 2, (UInt16)len1) + Set16(p + 4, (UInt16)printOffs) + Set16(p + 6, (UInt16)len2) + p += 8; + if (isSymLink) + { + const UInt32 flags = isAbs ? 0 : Z7_WIN_SYMLINK_FLAG_RELATIVE; + Set32(p, flags) + p += 4; + } + WriteString(p + subOffs, subs); + if (needPrintName) + WriteString(p + printOffs, path); +} + +#endif // defined(_WIN32) && !defined(UNDER_CE) + + +static void GetString(const Byte *p, unsigned len, UString &res) +{ + wchar_t *s = res.GetBuf(len); + unsigned i; + for (i = 0; i < len; i++) + { + const wchar_t c = Get16(p + (size_t)i * 2); + if (c == 0) + break; + s[i] = c; + } + s[i] = 0; + res.ReleaseBuf_SetLen(i); +} + + +bool CReparseAttr::Parse(const Byte *p, size_t size) +{ + ErrorCode = (DWORD)ERROR_INVALID_REPARSE_DATA; + HeaderError = true; + TagIsUnknown = true; + MinorError = false; + + if (size < 8) + return false; + Tag = Get32(p); + if (Get16(p + 6) != 0) // padding + { + // DOCs: Reserved : the field SHOULD be set to 0 + // and MUST be ignored (by parser). + // Win10 ignores it. + MinorError = true; // optional + } + unsigned len = Get16(p + 4); + p += 8; + size -= 8; + if (len != size) + // if (len > size) + return false; + /* + if ((type & kReparseFlags_Alias) == 0 || + (type & kReparseFlags_Microsoft) == 0 || + (type & 0xFFFF) != 3) + */ + HeaderError = false; + + if ( Tag != Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT + && Tag != Z7_WIN_IO_REPARSE_TAG_SYMLINK + && Tag != Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK) + { + // for unsupported reparse points + ErrorCode = (DWORD)ERROR_REPARSE_TAG_INVALID; // ERROR_REPARSE_TAG_MISMATCH + // errorCode = ERROR_REPARSE_TAG_MISMATCH; // ERROR_REPARSE_TAG_INVALID + return false; + } + + TagIsUnknown = false; + + if (Tag == Z7_WIN_IO_REPARSE_TAG_LX_SYMLINK) + { + if (len < 4) + return false; + if (Get32(p) != Z7_WIN_LX_SYMLINK_VERSION_2) + return false; + len -= 4; + p += 4; + char *s = WslName.GetBuf(len); + unsigned i; + for (i = 0; i < len; i++) + { + const char c = (char)p[i]; + s[i] = c; + if (c == 0) + break; + } + s[i] = 0; + WslName.ReleaseBuf_SetLen(i); + MinorError = (i != len); + ErrorCode = 0; + return true; + } + + if (len < 8) + return false; + const unsigned subOffs = Get16(p); + const unsigned subLen = Get16(p + 2); + const unsigned printOffs = Get16(p + 4); + const unsigned printLen = Get16(p + 6); + len -= 8; + p += 8; + + Flags = 0; + if (Tag == Z7_WIN_IO_REPARSE_TAG_SYMLINK) + { + if (len < 4) + return false; + Flags = Get32(p); + len -= 4; + p += 4; + } + + if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen) + return false; + if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen) + return false; + GetString(p + subOffs, subLen >> 1, SubsName); + GetString(p + printOffs, printLen >> 1, PrintName); + + ErrorCode = 0; + return true; +} + + +bool CReparseShortInfo::Parse(const Byte *p, size_t size) +{ + const Byte * const start = p; + Offset = 0; + Size = 0; + if (size < 8) + return false; + const UInt32 Tag = Get32(p); + UInt32 len = Get16(p + 4); + /* + if (len + 8 > size) + return false; + */ + /* + if ((type & kReparseFlags_Alias) == 0 || + (type & kReparseFlags_Microsoft) == 0 || + (type & 0xFFFF) != 3) + */ + if (Tag != Z7_WIN_IO_REPARSE_TAG_MOUNT_POINT && + Tag != Z7_WIN_IO_REPARSE_TAG_SYMLINK) + // return true; + return false; + /* + if (Get16(p + 6) != 0) // padding + return false; + */ + p += 8; + size -= 8; + if (len != size) // do we need that check? + return false; + if (len < 8) + return false; + unsigned subOffs = Get16(p); + unsigned subLen = Get16(p + 2); + unsigned printOffs = Get16(p + 4); + unsigned printLen = Get16(p + 6); + len -= 8; + p += 8; + + // UInt32 Flags = 0; + if (Tag == Z7_WIN_IO_REPARSE_TAG_SYMLINK) + { + if (len < 4) + return false; + // Flags = Get32(p); + len -= 4; + p += 4; + } + + if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen) + return false; + if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen) + return false; + + Offset = (unsigned)(p - start) + subOffs; + Size = subLen; + return true; +} + +bool CReparseAttr::IsOkNamePair() const +{ + if (IsLinkPrefix(SubsName)) + { + if (PrintName == GetPath()) + return true; +/* + if (!IsDrivePath(SubsName.Ptr(k_LinkPrefix_Size))) + return PrintName.IsEmpty(); + if (wcscmp(SubsName.Ptr(k_LinkPrefix_Size), PrintName) == 0) + return true; +*/ + } + return wcscmp(SubsName, PrintName) == 0; +} + +/* +bool CReparseAttr::IsVolume() const +{ + if (!IsLinkPrefix(SubsName)) + return false; + return IsVolumeName(SubsName.Ptr(k_LinkPrefix_Size)); +} +*/ + +UString CReparseAttr::GetPath() const +{ + UString s (SubsName); + if (IsSymLink_WSL()) + { + // if (CheckUTF8(attr.WslName) + if (!ConvertUTF8ToUnicode(WslName, s)) + MultiByteToUnicodeString2(s, WslName); + } + else if (IsLinkPrefix(s)) + { + if (IsString1PrefixedByString2_NoCase_Ascii(s.Ptr(), k_LinkPrefix_UNC)) + { + s.DeleteFrontal(6); + s.ReplaceOneCharAtPos(0, '\\'); + } + else + { + s.ReplaceOneCharAtPos(1, '\\'); // we normalize prefix from "\??\" to "\\?\" + if (IsDrivePath(s.Ptr(k_LinkPrefix_Size))) + s.DeleteFrontal(k_LinkPrefix_Size); + } + } + return s; +} + +#ifdef Z7_DEVICE_FILE + +namespace NSystem +{ +bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); +} +#endif // Z7_DEVICE_FILE + +#if defined(_WIN32) && !defined(UNDER_CE) + +namespace NIO { + +bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo) +{ + reparseData.Free(); + CInFile file; + if (!file.OpenReparse(path)) + return false; + + if (fileInfo) + file.GetFileInformation(fileInfo); + + const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; + CByteArr buf(kBufSize); + DWORD returnedSize; + if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize)) + return false; + reparseData.CopyFrom(buf, returnedSize); + return true; +} + +static bool CreatePrefixDirOfFile(CFSTR path) +{ + FString path2 (path); + const int pos = path2.ReverseFind_PathSepar(); + if (pos < 0) + return true; + #ifdef _WIN32 + if (pos == 2 && path2[1] == L':') + return true; // we don't create Disk folder; + #endif + path2.DeleteFrom((unsigned)pos); + return NDir::CreateComplexDir(path2); +} + + +static bool OutIoReparseData(DWORD controlCode, CFSTR path, void *data, DWORD size) +{ + COutFile file; + if (!file.Open(path, + FILE_SHARE_WRITE, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)) + return false; + + DWORD returnedSize; + return file.DeviceIoControl(controlCode, data, size, NULL, 0, &returnedSize); +} + + +// MOUNT_POINT (Junction Point) and LX_SYMLINK (WSL) can be written without administrator rights. +// SYMLINK requires administrator rights. +// If there is Reparse data already, it still writes new Reparse data +bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size) +{ + NFile::NFind::CFileInfo fi; + if (fi.Find(path)) + { + if (fi.IsDir() != isDir) + { + ::SetLastError(ERROR_DIRECTORY); + return false; + } + } + else + { + if (isDir) + { + if (!NDir::CreateComplexDir(path)) + return false; + } + else + { + CreatePrefixDirOfFile(path); + COutFile file; + if (!file.Create_NEW(path)) + return false; + } + } + + return OutIoReparseData(my_FSCTL_SET_REPARSE_POINT, path, (void *)(const Byte *)(data), size); +} + + +bool DeleteReparseData(CFSTR path) +{ + CByteBuffer reparseData; + if (!GetReparseData(path, reparseData, NULL)) + return false; + /* MSDN: The tag specified in the ReparseTag member of this structure + must match the tag of the reparse point to be deleted, + and the ReparseDataLength member must be zero */ + #define my_REPARSE_DATA_BUFFER_HEADER_SIZE 8 + if (reparseData.Size() < my_REPARSE_DATA_BUFFER_HEADER_SIZE) + { + SetLastError(ERROR_INVALID_REPARSE_DATA); + return false; + } + // BYTE buf[my_REPARSE_DATA_BUFFER_HEADER_SIZE]; + // memset(buf, 0, sizeof(buf)); + // memcpy(buf, reparseData, 4); // tag + memset(reparseData + 4, 0, my_REPARSE_DATA_BUFFER_HEADER_SIZE - 4); + return OutIoReparseData(my_FSCTL_DELETE_REPARSE_POINT, path, reparseData, my_REPARSE_DATA_BUFFER_HEADER_SIZE); +} + +} + +#endif // defined(_WIN32) && !defined(UNDER_CE) + + +#ifndef _WIN32 + +namespace NIO { + +bool GetReparseData(CFSTR path, CByteBuffer &reparseData) +{ + reparseData.Free(); + + #define MAX_PATHNAME_LEN 1024 + char buf[MAX_PATHNAME_LEN + 2]; + const size_t request = sizeof(buf) - 1; + + // printf("\nreadlink() path = %s \n", path); + const ssize_t size = readlink(path, buf, request); + // there is no tail zero + + if (size < 0) + return false; + if ((size_t)size >= request) + { + SetLastError(EINVAL); // check it: ENAMETOOLONG + return false; + } + + // printf("\nreadlink() res = %s size = %d \n", buf, (int)size); + reparseData.CopyFrom((const Byte *)buf, (size_t)size); + return true; +} + + +/* +// If there is Reparse data already, it still writes new Reparse data +bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size) +{ + // AString s; + // s.SetFrom_CalcLen(data, size); + // return (symlink(s, path) == 0); + UNUSED_VAR(path) + UNUSED_VAR(isDir) + UNUSED_VAR(data) + UNUSED_VAR(size) + SetLastError(ENOSYS); + return false; +} +*/ + +bool SetSymLink(CFSTR from, CFSTR to) +{ + // printf("\nsymlink() %s -> %s\n", from, to); + int ir; + // ir = unlink(path); + // if (ir == 0) + ir = symlink(to, from); + return (ir == 0); +} + +bool SetSymLink_UString(CFSTR from, const UString &to) +{ + AString utf; + ConvertUnicodeToUTF8(to, utf); + return SetSymLink(from, utf); +} + +} + +#endif // !_WIN32 + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/FileMapping.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.cpp --- p7zip-rar-16.02/CPP/Windows/FileMapping.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.cpp 2014-12-31 13:08:39.000000000 +0000 @@ -0,0 +1,12 @@ +// Windows/FileMapping.cpp + +#include "StdAfx.h" + +#include "FileMapping.h" + +namespace NWindows { +namespace NFile { +namespace NMapping { + + +}}} diff -Nru p7zip-rar-16.02/CPP/Windows/FileMapping.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.h --- p7zip-rar-16.02/CPP/Windows/FileMapping.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileMapping.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,66 @@ +// Windows/FileMapping.h + +#ifndef ZIP7_INC_WINDOWS_FILE_MAPPING_H +#define ZIP7_INC_WINDOWS_FILE_MAPPING_H + +#include "../Common/MyTypes.h" + +#include "Handle.h" + +namespace NWindows { + +class CFileMapping: public CHandle +{ +public: + WRes Create(DWORD protect, UInt64 maxSize, LPCTSTR name) + { + _handle = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, protect, (DWORD)(maxSize >> 32), (DWORD)maxSize, name); + return ::GetLastError(); + } + + WRes Open(DWORD + #ifndef UNDER_CE + desiredAccess + #endif + , LPCTSTR name) + { + #ifdef UNDER_CE + WRes res = Create(PAGE_READONLY, 0, name); + if (res == ERROR_ALREADY_EXISTS) + return 0; + Close(); + if (res == 0) + res = ERROR_FILE_NOT_FOUND; + return res; + #else + _handle = ::OpenFileMapping(desiredAccess, FALSE, name); + if (_handle != NULL) + return 0; + return ::GetLastError(); + #endif + } + + LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap) + { + return ::MapViewOfFile(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap); + } + + #ifndef UNDER_CE + LPVOID Map(DWORD desiredAccess, UInt64 fileOffset, SIZE_T numberOfBytesToMap, LPVOID baseAddress) + { + return ::MapViewOfFileEx(_handle, desiredAccess, (DWORD)(fileOffset >> 32), (DWORD)fileOffset, numberOfBytesToMap, baseAddress); + } + #endif +}; + +class CFileUnmapper +{ + const void *_data; +public: + CFileUnmapper(const void *data) : _data(data) {} + ~CFileUnmapper() { ::UnmapViewOfFile(_data); } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileName.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.cpp --- p7zip-rar-16.02/CPP/Windows/FileName.cpp 2015-06-22 21:31:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.cpp 2025-06-14 13:39:00.000000000 +0000 @@ -1,729 +1,911 @@ -// Windows/FileName.cpp - -#include "StdAfx.h" - -#include "Windows/FileName.h" -#include "Common/Wildcard.h" - -#include "Common/StringConvert.h" - -namespace NWindows { -namespace NFile { -namespace NDir { -bool MyGetFullPathName(CFSTR path, FString &resFullPath); -}}} - -namespace NWindows { -namespace NFile { -namespace NName { - -#define IS_SEPAR(c) IS_PATH_SEPAR(c) - -int FindSepar(const wchar_t *s) throw() -{ - for (const wchar_t *p = s;; p++) - { - const wchar_t c = *p; - if (c == 0) - return -1; - if (IS_SEPAR(c)) - return (int)(p - s); - } -} - -#ifndef USE_UNICODE_FSTRING -int FindSepar(const FChar *s) throw() -{ - for (const FChar *p = s;; p++) - { - const FChar c = *p; - if (c == 0) - return -1; - if (IS_SEPAR(c)) - return (int)(p - s); - } -} -#endif - - -#ifndef USE_UNICODE_FSTRING -void NormalizeDirPathPrefix(FString &dirPath) -{ - if (dirPath.IsEmpty()) - return; - if (dirPath.Back() != FCHAR_PATH_SEPARATOR) - dirPath += FCHAR_PATH_SEPARATOR; -} -#endif - -void NormalizeDirPathPrefix(UString &dirPath) -{ - if (dirPath.IsEmpty()) - return; - if (dirPath.Back() != WCHAR_PATH_SEPARATOR) - dirPath += WCHAR_PATH_SEPARATOR; -} - - -#ifdef _WIN32 - -const wchar_t *kSuperPathPrefix = L"\\\\?\\"; -static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\"; - -#define IS_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\') -#define IS_SUPER_PREFIX(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '?' && (s)[3] == '\\') -#define IS_SUPER_OR_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && ((s)[2] == '?' || (s)[2] == '.') && (s)[3] == '\\') -#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z') - -#define IS_UNC_WITH_SLASH(s) ( \ - ((s)[0] == 'U' || (s)[0] == 'u') && \ - ((s)[1] == 'N' || (s)[1] == 'n') && \ - ((s)[2] == 'C' || (s)[2] == 'c') && \ - (s)[3] == '\\') - -bool IsDevicePath(CFSTR s) throw() -{ - #ifdef UNDER_CE - - s = s; - return false; - /* - // actually we don't know the way to open device file in WinCE. - unsigned len = MyStringLen(s); - if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0) - return false; - if (s[4] != ':') - return false; - // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ)); - */ - - #else - - if (!IS_DEVICE_PATH(s)) - return false; - unsigned len = MyStringLen(s); - if (len == 6 && s[5] == ':') - return true; - if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0) - return false; - for (unsigned i = 17; i < len; i++) - if (s[i] < '0' || s[i] > '9') - return false; - return true; - - #endif -} - -bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); } - -bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; } -bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); } -bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); } -// bool IsSuperUncPath(const wchar_t *s) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); } - -#ifndef USE_UNICODE_FSTRING -bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; } -bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); } -bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); } -#endif // USE_UNICODE_FSTRING - -bool IsAbsolutePath(const wchar_t *s) throw() -{ - return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s); -} - -static const unsigned kDrivePrefixSize = 3; /* c:\ */ - -#ifndef USE_UNICODE_FSTRING - -static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) throw() -{ - // Network path: we look "server\path\" as root prefix - int pos = FindCharPosInString(s, '\\'); - if (pos < 0) - return 0; - int pos2 = FindCharPosInString(s + pos + 1, '\\'); - if (pos2 < 0) - return 0; - return pos + pos2 + 2; -} - -static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) throw() -{ - if (IsDrivePath(s)) - return kDrivePrefixSize; - if (s[0] != '\\' || s[1] != '\\') - return 0; - unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2); - return (size == 0) ? 0 : 2 + size; -} - -static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw() -{ - if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)) - { - unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize); - return (size == 0) ? 0 : kSuperUncPathPrefixSize + size; - } - // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\" - int pos = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR); - if (pos < 0) - return 0; - return kSuperPathPrefixSize + pos + 1; -} - -unsigned GetRootPrefixSize(CFSTR s) throw() -{ - if (IS_DEVICE_PATH(s)) - return kDevicePathPrefixSize; - if (IsSuperPath(s)) - return GetRootPrefixSize_Of_SuperPath(s); - return GetRootPrefixSize_Of_SimplePath(s); -} - -#endif // USE_UNICODE_FSTRING - -static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw() -{ - // Network path: we look "server\path\" as root prefix - int pos = FindCharPosInString(s, L'\\'); - if (pos < 0) - return 0; - int pos2 = FindCharPosInString(s + pos + 1, L'\\'); - if (pos2 < 0) - return 0; - return pos + pos2 + 2; -} - -static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw() -{ - if (IsDrivePath(s)) - return kDrivePrefixSize; - if (s[0] != '\\' || s[1] != '\\') - return 0; - unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2); - return (size == 0) ? 0 : 2 + size; -} - -static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw() -{ - if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)) - { - unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize); - return (size == 0) ? 0 : kSuperUncPathPrefixSize + size; - } - // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\" - int pos = FindCharPosInString(s + kSuperPathPrefixSize, L'\\'); - if (pos < 0) - return 0; - return kSuperPathPrefixSize + pos + 1; -} - -unsigned GetRootPrefixSize(const wchar_t *s) throw() -{ - if (IS_DEVICE_PATH(s)) - return kDevicePathPrefixSize; - if (IsSuperPath(s)) - return GetRootPrefixSize_Of_SuperPath(s); - return GetRootPrefixSize_Of_SimplePath(s); -} - -#else // _WIN32 - -static const unsigned kDrivePrefixSize = 3; /* c:\ */ -#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z') -bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == WCHAR_PATH_SEPARATOR; } - -bool IsAbsolutePath(const wchar_t *s) throw() { return s[0] == WCHAR_PATH_SEPARATOR; } - -#ifndef USE_UNICODE_FSTRING -unsigned GetRootPrefixSize(CFSTR s) throw() { return s[0] == CHAR_PATH_SEPARATOR ? 1 : 0; } -#endif -unsigned GetRootPrefixSize(const wchar_t *s) throw() { - if (IsDrivePath(s)) - return kDrivePrefixSize; - - return s[0] == CHAR_PATH_SEPARATOR ? 1 : 0; -} - -#endif // _WIN32 - - -#ifndef UNDER_CE - -static bool GetCurDir(UString &path) -{ - path.Empty(); - char begin[MAX_PATHNAME_LEN]; - begin[0]='c'; - begin[1]=':'; - char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); - if (cret) - { -#ifdef _UNICODE - path = GetUnicodeString(begin); -#else - path = begin; -#endif - return true; - } - return false; -} - -static bool ResolveDotsFolders(UString &s) -{ - #ifdef _WIN32 - s.Replace(L'/', WCHAR_PATH_SEPARATOR); - #endif - for (int i = 0;;) - { - wchar_t c = s[i]; - if (c == 0) - return true; - if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR)) - { - wchar_t c1 = s[i + 1]; - if (c1 == '.') - { - wchar_t c2 = s[i + 2]; - if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0) - { - if (i == 0) - return false; - int k = i - 2; - for (; k >= 0; k--) - if (s[k] == WCHAR_PATH_SEPARATOR) - break; - unsigned num; - if (k >= 0) - { - num = i + 2 - k; - i = k; - } - else - { - num = (c2 == 0 ? (i + 2) : (i + 3)); - i = 0; - } - s.Delete(i, num); - continue; - } - } - else - { - if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0) - { - unsigned num = 2; - if (i != 0) - i--; - else if (c1 == 0) - num = 1; - s.Delete(i, num); - continue; - } - } - } - i++; - } -} - -#endif // UNDER_CE - -#define LONG_PATH_DOTS_FOLDERS_PARSING - - -/* -Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\ -To solve that problem we check such path: - - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper - - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain -*/ -#ifdef LONG_PATH_DOTS_FOLDERS_PARSING -#ifndef UNDER_CE -static bool AreThereDotsFolders(CFSTR s) -{ - for (unsigned i = 0;; i++) - { - FChar c = s[i]; - if (c == 0) - return false; - if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)) - { - FChar c1 = s[i + 1]; - if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR || - (c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR))) - return true; - } - } -} -#endif -#endif // LONG_PATH_DOTS_FOLDERS_PARSING - -#ifdef WIN_LONG_PATH - -/* -Most of Windows versions have problems, if some file or dir name -contains '.' or ' ' at the end of name (Bad Path). -To solve that problem, we always use Super Path ("\\?\" prefix and full path) -in such cases. Note that "." and ".." are not bad names. - -There are 3 cases: - 1) If the path is already Super Path, we use that path - 2) If the path is not Super Path : - 2.1) Bad Path; we use only Super Path. - 2.2) Good Path; we use Main Path. If it fails, we use Super Path. - - NeedToUseOriginalPath returns: - kSuperPathType_UseOnlyMain : Super already - kSuperPathType_UseOnlySuper : not Super, Bad Path - kSuperPathType_UseMainAndSuper : not Super, Good Path -*/ - -int GetUseSuperPathType(CFSTR s) throw() -{ - if (IsSuperOrDevicePath(s)) - { - #ifdef LONG_PATH_DOTS_FOLDERS_PARSING - if ((s)[2] != '.') - if (AreThereDotsFolders(s + kSuperPathPrefixSize)) - return kSuperPathType_UseOnlySuper; - #endif - return kSuperPathType_UseOnlyMain; - } - - for (unsigned i = 0;; i++) - { - FChar c = s[i]; - if (c == 0) - return kSuperPathType_UseMainAndSuper; - if (c == '.' || c == ' ') - { - FChar c2 = s[i + 1]; - if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR) - { - // if it's "." or "..", it's not bad name. - if (c == '.') - { - if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR) - continue; - if (s[i - 1] == '.') - { - if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR) - continue; - } - } - return kSuperPathType_UseOnlySuper; - } - } - } -} - - -/* - returns false in two cases: - - if GetCurDir was used, and GetCurDir returned error. - - if we can't resolve ".." name. - if path is ".", "..", res is empty. - if it's Super Path already, res is empty. - for \**** , and if GetCurDir is not drive (c:\), res is empty - for absolute paths, returns true, res is Super path. -*/ - - -static bool GetSuperPathBase(CFSTR s, UString &res) -{ - res.Empty(); - - FChar c = s[0]; - if (c == 0) - return true; - if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) - return true; - - if (IsSuperOrDevicePath(s)) - { - #ifdef LONG_PATH_DOTS_FOLDERS_PARSING - - if ((s)[2] == '.') - return true; - - // we will return true here, so we will try to use these problem paths. - - if (!AreThereDotsFolders(s + kSuperPathPrefixSize)) - return true; - - UString temp = fs2us(s); - unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp); - if (fixedSize == 0) - return true; - - UString rem = &temp[fixedSize]; - if (!ResolveDotsFolders(rem)) - return true; - - temp.DeleteFrom(fixedSize); - res += temp; - res += rem; - - #endif - - return true; - } - - if (c == CHAR_PATH_SEPARATOR) - { - if (s[1] == CHAR_PATH_SEPARATOR) - { - UString temp = fs2us(s + 2); - unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp); - if (fixedSize == 0) // maybe we must ignore that error to allow short network paths? - return false; - UString rem = &temp[fixedSize]; - if (!ResolveDotsFolders(rem)) - return false; - res += kSuperUncPrefix; - temp.DeleteFrom(fixedSize); - res += temp; - res += rem; - return true; - } - } - else - { - if (IsDrivePath(s)) - { - UString temp = fs2us(s); - UString rem = &temp[kDrivePrefixSize]; - if (!ResolveDotsFolders(rem)) - return true; - res += kSuperPathPrefix; - temp.DeleteFrom(kDrivePrefixSize); - res += temp; - res += rem; - return true; - } - } - - UString curDir; - if (!GetCurDir(curDir)) - return false; - if (curDir.Back() != WCHAR_PATH_SEPARATOR) - curDir += WCHAR_PATH_SEPARATOR; - - unsigned fixedSizeStart = 0; - unsigned fixedSize = 0; - const wchar_t *superMarker = NULL; - if (IsSuperPath(curDir)) - { - fixedSize = GetRootPrefixSize_Of_SuperPath(curDir); - if (fixedSize == 0) - return false; - } - else - { - if (IsDrivePath(curDir)) - { - superMarker = kSuperPathPrefix; - fixedSize = kDrivePrefixSize; - } - else - { - if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR) - return false; - fixedSizeStart = 2; - fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]); - if (fixedSize == 0) - return false; - superMarker = kSuperUncPrefix; - } - } - - UString temp; - if (c == CHAR_PATH_SEPARATOR) - { - temp = fs2us(s + 1); - } - else - { - temp += &curDir[fixedSizeStart + fixedSize]; - temp += fs2us(s); - } - if (!ResolveDotsFolders(temp)) - return false; - if (superMarker) - res += superMarker; - res += curDir.Mid(fixedSizeStart, fixedSize); - res += temp; - return true; -} - - -/* - In that case if GetSuperPathBase doesn't return new path, we don't need - to use same path that was used as main path - - GetSuperPathBase superPath.IsEmpty() onlyIfNew - false * * GetCurDir Error - true false * use Super path - true true true don't use any path, we already used mainPath - true true false use main path as Super Path, we don't try mainMath - That case is possible now if GetCurDir returns unknow - type of path (not drive and not network) - - We can change that code if we want to try mainPath, if GetSuperPathBase returns error, - and we didn't try mainPath still. - If we want to work that way, we don't need to use GetSuperPathBase return code. -*/ - -bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew) -{ - if (GetSuperPathBase(path, superPath)) - { - if (superPath.IsEmpty()) - { - // actually the only possible when onlyIfNew == true and superPath is empty - // is case when - - if (onlyIfNew) - return false; - superPath = fs2us(path); - } - return true; - } - return false; -} - -bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew) -{ - if (!GetSuperPathBase(s1, d1) || - !GetSuperPathBase(s2, d2)) - return false; - if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew) - return false; - if (d1.IsEmpty()) d1 = fs2us(s1); - if (d2.IsEmpty()) d2 = fs2us(s2); - return true; -} - - -/* -// returns true, if we need additional use with New Super path. -bool GetSuperPath(CFSTR path, UString &superPath) -{ - if (GetSuperPathBase(path, superPath)) - return !superPath.IsEmpty(); - return false; -} -*/ -#endif // WIN_LONG_PATH - -bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res) -{ - res = s; - - #ifdef UNDER_CE - - if (s[0] != CHAR_PATH_SEPARATOR) - { - if (!dirPrefix) - return false; - res = dirPrefix; - res += s; - } - - #else - - unsigned prefixSize = GetRootPrefixSize(s); - if (prefixSize != 0) - { - if (!AreThereDotsFolders(s + prefixSize)) - return true; - - UString rem = fs2us(s + prefixSize); - if (!ResolveDotsFolders(rem)) - return true; // maybe false; - res.DeleteFrom(prefixSize); - res += us2fs(rem); - return true; - } - - /* - FChar c = s[0]; - if (c == 0) - return true; - if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) - return true; - if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR) - return true; - if (IsDrivePath(s)) - return true; - */ - - UString curDir; - if (dirPrefix) - curDir = fs2us(dirPrefix); - else - { - if (!GetCurDir(curDir)) - return false; - } - if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR) - curDir += WCHAR_PATH_SEPARATOR; - - unsigned fixedSize = 0; - - #ifdef _WIN32 - - if (IsSuperPath(curDir)) - { - fixedSize = GetRootPrefixSize_Of_SuperPath(curDir); - if (fixedSize == 0) - return false; - } - else - { - if (IsDrivePath(curDir)) - fixedSize = kDrivePrefixSize; - else - { - if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR) - return false; - fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]); - if (fixedSize == 0) - return false; - fixedSize += 2; - } - } - #else - if (IsDrivePath(curDir)) - fixedSize = kDrivePrefixSize; - - #endif // _WIN32 - - UString temp; - if (s[0] == CHAR_PATH_SEPARATOR) - { - temp = fs2us(s + 1); - } - else - { - temp += curDir.Ptr(fixedSize); - temp += fs2us(s); - } - if (!ResolveDotsFolders(temp)) - return false; - curDir.DeleteFrom(fixedSize); - res = us2fs(curDir); - res += us2fs(temp); - - #endif // UNDER_CE - - return true; -} - -bool GetFullPath(CFSTR path, FString &fullPath) -{ - return GetFullPath(NULL, path, fullPath); -} - -}}} +// Windows/FileName.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#include "../Common/StringConvert.h" +#endif + +#include "FileDir.h" +#include "FileName.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { +namespace NName { + +#define IS_SEPAR(c) IS_PATH_SEPAR(c) + +int FindSepar(const wchar_t *s) throw() +{ + for (const wchar_t *p = s;; p++) + { + const wchar_t c = *p; + if (c == 0) + return -1; + if (IS_SEPAR(c)) + return (int)(p - s); + } +} + +#ifndef USE_UNICODE_FSTRING +int FindSepar(const FChar *s) throw() +{ + for (const FChar *p = s;; p++) + { + const FChar c = *p; + if (c == 0) + return -1; + if (IS_SEPAR(c)) + return (int)(p - s); + } +} +#endif + +#ifndef USE_UNICODE_FSTRING +void NormalizeDirPathPrefix(FString &dirPath) +{ + if (dirPath.IsEmpty()) + return; + if (!IsPathSepar(dirPath.Back())) + dirPath.Add_PathSepar(); +} +#endif + +void NormalizeDirPathPrefix(UString &dirPath) +{ + if (dirPath.IsEmpty()) + return; + if (!IsPathSepar(dirPath.Back())) + dirPath.Add_PathSepar(); +} + + +#define IS_LETTER_CHAR(c) ((((unsigned)(int)(c) | 0x20) - (unsigned)'a' <= (unsigned)('z' - 'a'))) +bool IsDrivePath (const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); } +// bool IsDriveName2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; } + +#ifdef _WIN32 + +bool IsDrivePath2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; } + +#ifndef USE_UNICODE_FSTRING +#ifdef Z7_LONG_PATH +static void NormalizeDirSeparators(UString &s) +{ + const unsigned len = s.Len(); + for (unsigned i = 0; i < len; i++) + if (s[i] == '/') + s.ReplaceOneCharAtPos(i, WCHAR_PATH_SEPARATOR); +} +#endif +#endif + +void NormalizeDirSeparators(FString &s) +{ + const unsigned len = s.Len(); + for (unsigned i = 0; i < len; i++) + if (s[i] == '/') + s.ReplaceOneCharAtPos(i, FCHAR_PATH_SEPARATOR); +} + +bool IsAltPathPrefix(CFSTR s) throw() +{ + unsigned len = MyStringLen(s); + if (len == 0) + return false; + if (s[len - 1] != ':') + return false; + + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsDevicePath(s)) + return false; + if (IsSuperPath(s)) + { + s += kSuperPathPrefixSize; + len -= kSuperPathPrefixSize; + } + if (len == 2 && IsDrivePath2(s)) + return false; + #endif + + return true; +} + +#endif // _WIN32 + + +const char * const kSuperPathPrefix = + STRING_PATH_SEPARATOR + STRING_PATH_SEPARATOR "?" + STRING_PATH_SEPARATOR; +#ifdef Z7_LONG_PATH +static const char * const kSuperUncPrefix = + STRING_PATH_SEPARATOR + STRING_PATH_SEPARATOR "?" + STRING_PATH_SEPARATOR "UNC" + STRING_PATH_SEPARATOR; +#endif + +#define IS_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '.' && IS_SEPAR((s)[3])) +#define IS_SUPER_PREFIX(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '?' && IS_SEPAR((s)[3])) + +#define IS_UNC_WITH_SLASH(s) ( \ + ((s)[0] == 'U' || (s)[0] == 'u') \ + && ((s)[1] == 'N' || (s)[1] == 'n') \ + && ((s)[2] == 'C' || (s)[2] == 'c') \ + && IS_SEPAR((s)[3])) + +static const unsigned kDrivePrefixSize = 3; /* c:\ */ + +bool IsSuperPath(const wchar_t *s) throw(); +bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); } +// bool IsSuperUncPath(const wchar_t *s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); } + +#if defined(_WIN32) && !defined(UNDER_CE) + +#define IS_SUPER_OR_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && ((s)[2] == '?' || (s)[2] == '.') && IS_SEPAR((s)[3])) +bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); } +bool IsDevicePath(CFSTR s) throw() +{ + #ifdef UNDER_CE + + s = s; + return false; + /* + // actually we don't know the way to open device file in WinCE. + unsigned len = MyStringLen(s); + if (len < 5 || len > 5 || !IsString1PrefixedByString2(s, "DSK")) + return false; + if (s[4] != ':') + return false; + // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ)); + */ + + #else + + if (!IS_DEVICE_PATH(s)) + return false; + const unsigned len = MyStringLen(s); + if (len == 6 && s[5] == ':') + return true; + if (len < 18 || len > 22 || !IsString1PrefixedByString2(s + kDevicePathPrefixSize, "PhysicalDrive")) + return false; + for (unsigned i = 17; i < len; i++) + if (s[i] < '0' || s[i] > '9') + return false; + return true; + + #endif +} + +bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); } +bool IsNetworkPath(CFSTR s) throw() +{ + if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1])) + return false; + if (IsSuperUncPath(s)) + return true; + const FChar c = s[2]; + return (c != '.' && c != '?'); +} + +unsigned GetNetworkServerPrefixSize(CFSTR s) throw() +{ + if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1])) + return 0; + unsigned prefixSize = 2; + if (IsSuperUncPath(s)) + prefixSize = kSuperUncPathPrefixSize; + else + { + const FChar c = s[2]; + if (c == '.' || c == '?') + return 0; + } + const int pos = FindSepar(s + prefixSize); + if (pos < 0) + return 0; + return prefixSize + (unsigned)(pos + 1); +} + +bool IsNetworkShareRootPath(CFSTR s) throw() +{ + const unsigned prefixSize = GetNetworkServerPrefixSize(s); + if (prefixSize == 0) + return false; + s += prefixSize; + const int pos = FindSepar(s); + if (pos < 0) + return true; + return s[(unsigned)pos + 1] == 0; +} + +bool IsAltStreamPrefixWithColon(const UString &s) throw() +{ + if (s.IsEmpty()) + return false; + if (s.Back() != ':') + return false; + unsigned pos = 0; + if (IsSuperPath(s)) + pos = kSuperPathPrefixSize; + if (s.Len() - pos == 2 && IsDrivePath2(s.Ptr(pos))) + return false; + return true; +} + +bool If_IsSuperPath_RemoveSuperPrefix(UString &s) +{ + if (!IsSuperPath(s)) + return false; + unsigned start = 0; + unsigned count = kSuperPathPrefixSize; + const wchar_t *s2 = s.Ptr(kSuperPathPrefixSize); + if (IS_UNC_WITH_SLASH(s2)) + { + start = 2; + count = kSuperUncPathPrefixSize - 2; + } + s.Delete(start, count); + return true; +} + + +#ifndef USE_UNICODE_FSTRING +bool IsDrivePath2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; } +// bool IsDriveName2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; } +bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); } +bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); } +bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); } +#endif // USE_UNICODE_FSTRING + +bool IsDrivePath_SuperAllowed(CFSTR s) throw() +{ + if (IsSuperPath(s)) + s += kSuperPathPrefixSize; + return IsDrivePath(s); +} + +bool IsDriveRootPath_SuperAllowed(CFSTR s) throw() +{ + if (IsSuperPath(s)) + s += kSuperPathPrefixSize; + return IsDrivePath(s) && s[kDrivePrefixSize] == 0; +} + +bool IsAbsolutePath(const wchar_t *s) throw() +{ + return IS_SEPAR(s[0]) || IsDrivePath2(s); +} + +int FindAltStreamColon(CFSTR path) throw() +{ + unsigned i = 0; + if (IsSuperPath(path)) + i = kSuperPathPrefixSize; + if (IsDrivePath2(path + i)) + i += 2; + int colonPos = -1; + for (;; i++) + { + const FChar c = path[i]; + if (c == 0) + return colonPos; + if (c == ':') + { + if (colonPos < 0) + colonPos = (int)i; + continue; + } + if (IS_SEPAR(c)) + colonPos = -1; + } +} + +#ifndef USE_UNICODE_FSTRING + +static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) +{ + // Network path: we look "server\path\" as root prefix + const int pos = FindSepar(s); + if (pos < 0) + return 0; + const int pos2 = FindSepar(s + (unsigned)pos + 1); + if (pos2 < 0) + return 0; + return (unsigned)pos + (unsigned)pos2 + 2; +} + +static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) +{ + if (IsDrivePath(s)) + return kDrivePrefixSize; + if (!IS_SEPAR(s[0])) + return 0; + if (s[1] == 0 || !IS_SEPAR(s[1])) + return 1; + const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2); + return (size == 0) ? 0 : 2 + size; +} + +static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) +{ + if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)) + { + const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize); + return (size == 0) ? 0 : kSuperUncPathPrefixSize + size; + } + // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\" + const int pos = FindSepar(s + kSuperPathPrefixSize); + if (pos < 0) + return 0; + return kSuperPathPrefixSize + (unsigned)pos + 1; +} + +unsigned GetRootPrefixSize(CFSTR s) throw() +{ + if (IS_DEVICE_PATH(s)) + return kDevicePathPrefixSize; + if (IsSuperPath(s)) + return GetRootPrefixSize_Of_SuperPath(s); + return GetRootPrefixSize_Of_SimplePath(s); +} + +#endif // USE_UNICODE_FSTRING +#endif // _WIN32 + + +static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw() +{ + // Network path: we look "server\path\" as root prefix + const int pos = FindSepar(s); + if (pos < 0) + return 0; + const int pos2 = FindSepar(s + (unsigned)pos + 1); + if (pos2 < 0) + return 0; + return (unsigned)(pos + pos2 + 2); +} + +static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw() +{ + if (IsDrivePath(s)) + return kDrivePrefixSize; + if (!IS_SEPAR(s[0])) + return 0; + if (s[1] == 0 || !IS_SEPAR(s[1])) + return 1; + const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2); + return (size == 0) ? 0 : 2 + size; +} + +static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw() +{ + if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)) + { + const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize); + return (size == 0) ? 0 : kSuperUncPathPrefixSize + size; + } + // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\" + const int pos = FindSepar(s + kSuperPathPrefixSize); + if (pos < 0) + return 0; + return kSuperPathPrefixSize + (unsigned)(pos + 1); +} + +#ifdef _WIN32 +unsigned GetRootPrefixSize(const wchar_t *s) throw() +#else +unsigned GetRootPrefixSize_WINDOWS(const wchar_t *s) throw() +#endif +{ + if (IS_DEVICE_PATH(s)) + return kDevicePathPrefixSize; + if (IsSuperPath(s)) + return GetRootPrefixSize_Of_SuperPath(s); + return GetRootPrefixSize_Of_SimplePath(s); +} + +#ifndef _WIN32 + +bool IsAbsolutePath(const wchar_t *s) throw() { return IS_SEPAR(s[0]); } + +#ifndef USE_UNICODE_FSTRING +unsigned GetRootPrefixSize(CFSTR s) throw(); +unsigned GetRootPrefixSize(CFSTR s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; } +#endif +unsigned GetRootPrefixSize(const wchar_t *s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; } + +#endif // _WIN32 + + +#ifndef UNDER_CE + + +#ifdef USE_UNICODE_FSTRING + +#define GetCurDir NDir::GetCurrentDir + +#else + +static bool GetCurDir(UString &path) +{ + path.Empty(); + FString s; + if (!NDir::GetCurrentDir(s)) + return false; + path = fs2us(s); + return true; +} + +#endif + + +static bool ResolveDotsFolders(UString &s) +{ + #ifdef _WIN32 + // s.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + + for (unsigned i = 0;;) + { + const wchar_t c = s[i]; + if (c == 0) + return true; + if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1]))) + { + const wchar_t c1 = s[i + 1]; + if (c1 == '.') + { + const wchar_t c2 = s[i + 2]; + if (IS_SEPAR(c2) || c2 == 0) + { + if (i == 0) + return false; + int k = (int)i - 2; + i += 2; + + for (;; k--) + { + if (k < 0) + return false; + if (!IS_SEPAR(s[(unsigned)k])) + break; + } + + do + k--; + while (k >= 0 && !IS_SEPAR(s[(unsigned)k])); + + unsigned num; + + if (k >= 0) + { + num = i - (unsigned)k; + i = (unsigned)k; + } + else + { + num = (c2 == 0 ? i : (i + 1)); + i = 0; + } + + s.Delete(i, num); + continue; + } + } + else if (IS_SEPAR(c1) || c1 == 0) + { + unsigned num = 2; + if (i != 0) + i--; + else if (c1 == 0) + num = 1; + s.Delete(i, num); + continue; + } + } + + i++; + } +} + +#endif // UNDER_CE + +#define LONG_PATH_DOTS_FOLDERS_PARSING + + +/* +Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\ +To solve that problem we check such path: + - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper + - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain +*/ +#ifdef LONG_PATH_DOTS_FOLDERS_PARSING +#ifndef UNDER_CE +static bool AreThereDotsFolders(CFSTR s) +{ + for (unsigned i = 0;; i++) + { + FChar c = s[i]; + if (c == 0) + return false; + if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1]))) + { + FChar c1 = s[i + 1]; + if (c1 == 0 || IS_SEPAR(c1) || + (c1 == '.' && (s[i + 2] == 0 || IS_SEPAR(s[i + 2])))) + return true; + } + } +} +#endif +#endif // LONG_PATH_DOTS_FOLDERS_PARSING + +#ifdef Z7_LONG_PATH + +/* +Most of Windows versions have problems, if some file or dir name +contains '.' or ' ' at the end of name (Bad Path). +To solve that problem, we always use Super Path ("\\?\" prefix and full path) +in such cases. Note that "." and ".." are not bad names. + +There are 3 cases: + 1) If the path is already Super Path, we use that path + 2) If the path is not Super Path : + 2.1) Bad Path; we use only Super Path. + 2.2) Good Path; we use Main Path. If it fails, we use Super Path. + + NeedToUseOriginalPath returns: + kSuperPathType_UseOnlyMain : Super already + kSuperPathType_UseOnlySuper : not Super, Bad Path + kSuperPathType_UseMainAndSuper : not Super, Good Path +*/ + +int GetUseSuperPathType(CFSTR s) throw() +{ + if (IsSuperOrDevicePath(s)) + { + #ifdef LONG_PATH_DOTS_FOLDERS_PARSING + if ((s)[2] != '.') + if (AreThereDotsFolders(s + kSuperPathPrefixSize)) + return kSuperPathType_UseOnlySuper; + #endif + return kSuperPathType_UseOnlyMain; + } + + for (unsigned i = 0;; i++) + { + FChar c = s[i]; + if (c == 0) + return kSuperPathType_UseMainAndSuper; + if (c == '.' || c == ' ') + { + FChar c2 = s[i + 1]; + if (c2 == 0 || IS_SEPAR(c2)) + { + // if it's "." or "..", it's not bad name. + if (c == '.') + { + if (i == 0 || IS_SEPAR(s[i - 1])) + continue; + if (s[i - 1] == '.') + { + if (i - 1 == 0 || IS_SEPAR(s[i - 2])) + continue; + } + } + return kSuperPathType_UseOnlySuper; + } + } + } +} + + + +/* + returns false in two cases: + - if GetCurDir was used, and GetCurDir returned error. + - if we can't resolve ".." name. + if path is ".", "..", res is empty. + if it's Super Path already, res is empty. + for \**** , and if GetCurDir is not drive (c:\), res is empty + for absolute paths, returns true, res is Super path. +*/ + +static bool GetSuperPathBase(CFSTR s, UString &res) +{ + res.Empty(); + + FChar c = s[0]; + if (c == 0) + return true; + if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) + return true; + + if (IsSuperOrDevicePath(s)) + { + #ifdef LONG_PATH_DOTS_FOLDERS_PARSING + + if ((s)[2] == '.') + return true; + + // we will return true here, so we will try to use these problem paths. + + if (!AreThereDotsFolders(s + kSuperPathPrefixSize)) + return true; + + UString temp = fs2us(s); + const unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp); + if (fixedSize == 0) + return true; + + UString rem = temp.Ptr(fixedSize); + if (!ResolveDotsFolders(rem)) + return true; + + temp.DeleteFrom(fixedSize); + res += temp; + res += rem; + + #endif + + return true; + } + + if (IS_SEPAR(c)) + { + if (IS_SEPAR(s[1])) + { + UString temp = fs2us(s + 2); + const unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp); + // we ignore that error to allow short network paths server\share? + /* + if (fixedSize == 0) + return false; + */ + UString rem = temp.Ptr(fixedSize); + if (!ResolveDotsFolders(rem)) + return false; + res += kSuperUncPrefix; + temp.DeleteFrom(fixedSize); + res += temp; + res += rem; + return true; + } + } + else + { + if (IsDrivePath2(s)) + { + UString temp = fs2us(s); + unsigned prefixSize = 2; + if (IsDrivePath(s)) + prefixSize = kDrivePrefixSize; + UString rem = temp.Ptr(prefixSize); + if (!ResolveDotsFolders(rem)) + return true; + res += kSuperPathPrefix; + temp.DeleteFrom(prefixSize); + res += temp; + res += rem; + return true; + } + } + + UString curDir; + if (!GetCurDir(curDir)) + return false; + NormalizeDirPathPrefix(curDir); + + unsigned fixedSizeStart = 0; + unsigned fixedSize = 0; + const char *superMarker = NULL; + if (IsSuperPath(curDir)) + { + fixedSize = GetRootPrefixSize_Of_SuperPath(curDir); + if (fixedSize == 0) + return false; + } + else + { + if (IsDrivePath(curDir)) + { + superMarker = kSuperPathPrefix; + fixedSize = kDrivePrefixSize; + } + else + { + if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1])) + return false; + fixedSizeStart = 2; + fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2)); + if (fixedSize == 0) + return false; + superMarker = kSuperUncPrefix; + } + } + + UString temp; + if (IS_SEPAR(c)) + { + temp = fs2us(s + 1); + } + else + { + temp += &curDir[fixedSizeStart + fixedSize]; + temp += fs2us(s); + } + if (!ResolveDotsFolders(temp)) + return false; + if (superMarker) + res += superMarker; + res += curDir.Mid(fixedSizeStart, fixedSize); + res += temp; + return true; +} + + +/* + In that case if GetSuperPathBase doesn't return new path, we don't need + to use same path that was used as main path + + GetSuperPathBase superPath.IsEmpty() onlyIfNew + false * * GetCurDir Error + true false * use Super path + true true true don't use any path, we already used mainPath + true true false use main path as Super Path, we don't try mainMath + That case is possible now if GetCurDir returns unknown + type of path (not drive and not network) + + We can change that code if we want to try mainPath, if GetSuperPathBase returns error, + and we didn't try mainPath still. + If we want to work that way, we don't need to use GetSuperPathBase return code. +*/ + +bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew) +{ + if (GetSuperPathBase(path, superPath)) + { + if (superPath.IsEmpty()) + { + // actually the only possible when onlyIfNew == true and superPath is empty + // is case when + + if (onlyIfNew) + return false; + superPath = fs2us(path); + } + + NormalizeDirSeparators(superPath); + return true; + } + return false; +} + +bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew) +{ + if (!GetSuperPathBase(s1, d1) || + !GetSuperPathBase(s2, d2)) + return false; + + NormalizeDirSeparators(d1); + NormalizeDirSeparators(d2); + + if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew) + return false; + if (d1.IsEmpty()) d1 = fs2us(s1); + if (d2.IsEmpty()) d2 = fs2us(s2); + return true; +} + + +/* +// returns true, if we need additional use with New Super path. +bool GetSuperPath(CFSTR path, UString &superPath) +{ + if (GetSuperPathBase(path, superPath)) + return !superPath.IsEmpty(); + return false; +} +*/ +#endif // Z7_LONG_PATH + +bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res) +{ + res = s; + + #ifdef UNDER_CE + + if (!IS_SEPAR(s[0])) + { + if (!dirPrefix) + return false; + res = dirPrefix; + res += s; + } + + #else + + const unsigned prefixSize = GetRootPrefixSize(s); + if (prefixSize != 0) +#ifdef _WIN32 + if (prefixSize != 1) +#endif + { + if (!AreThereDotsFolders(s + prefixSize)) + return true; + + UString rem = fs2us(s + prefixSize); + if (!ResolveDotsFolders(rem)) + return true; // maybe false; + res.DeleteFrom(prefixSize); + res += us2fs(rem); + return true; + } + + UString curDir; + if (dirPrefix && prefixSize == 0) + curDir = fs2us(dirPrefix); // we use (dirPrefix), only if (s) path is relative + else + { + if (!GetCurDir(curDir)) + return false; + } + NormalizeDirPathPrefix(curDir); + + unsigned fixedSize = GetRootPrefixSize(curDir); + + UString temp; +#ifdef _WIN32 + if (prefixSize != 0) + { + /* (s) is absolute path, but only (prefixSize == 1) is possible here. + So for full resolving we need root of current folder and + relative part of (s). */ + s += prefixSize; + // (s) is relative part now + if (fixedSize == 0) + { + // (curDir) is not absolute. + // That case is unexpected, but we support it too. + curDir.Empty(); + curDir.Add_PathSepar(); + fixedSize = 1; + // (curDir) now is just Separ character. + // So final (res) path later also will have Separ prefix. + } + } + else +#endif // _WIN32 + { + // (s) is relative path + temp = curDir.Ptr(fixedSize); + // (temp) is relative_part_of(curDir) + } + temp += fs2us(s); + if (!ResolveDotsFolders(temp)) + return false; + curDir.DeleteFrom(fixedSize); + // (curDir) now contains only absolute prefix part + res = us2fs(curDir); + res += us2fs(temp); + + #endif // UNDER_CE + + return true; +} + + +bool GetFullPath(CFSTR path, FString &fullPath) +{ + return GetFullPath(NULL, path, fullPath); +} + +}}} diff -Nru p7zip-rar-16.02/CPP/Windows/FileName.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.h --- p7zip-rar-16.02/CPP/Windows/FileName.h 2015-06-22 20:46:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileName.h 2025-06-20 11:00:00.000000000 +0000 @@ -1,35 +1,142 @@ -// Windows/FileName.h - -#ifndef __WINDOWS_FILENAME_H -#define __WINDOWS_FILENAME_H - -#include "../../C/7zTypes.h" - -#include "../Common/MyString.h" - -namespace NWindows { -namespace NFile { -namespace NName { - -int FindSepar(const wchar_t *s) throw(); -#ifndef USE_UNICODE_FSTRING -int FindSepar(const FChar *s) throw(); -#endif - -const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR; -const TCHAR kAnyStringWildcard = '*'; - -void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\' -#ifndef _UNICODE -void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\' -#endif - -bool IsAbsolutePath(const wchar_t *s) throw(); -unsigned GetRootPrefixSize(const wchar_t *s) throw(); - -bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath); -bool GetFullPath(CFSTR path, FString &fullPath); - -}}} - -#endif +// Windows/FileName.h + +#ifndef ZIP7_INC_WINDOWS_FILE_NAME_H +#define ZIP7_INC_WINDOWS_FILE_NAME_H + +#include "../Common/MyString.h" + +namespace NWindows { +namespace NFile { +namespace NName { + +int FindSepar(const wchar_t *s) throw(); +#ifndef USE_UNICODE_FSTRING +int FindSepar(const FChar *s) throw(); +#endif + +void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty +void NormalizeDirPathPrefix(UString &dirPath); + +#ifdef _WIN32 +void NormalizeDirSeparators(FString &s); +#endif + +bool IsDrivePath(const wchar_t *s) throw(); // first 3 chars are drive chars like "a:\\" + +bool IsAltPathPrefix(CFSTR s) throw(); /* name: */ + +extern const char * const kSuperPathPrefix; /* \\?\ */ +const unsigned kDevicePathPrefixSize = 4; +const unsigned kSuperPathPrefixSize = 4; +const unsigned kSuperUncPathPrefixSize = kSuperPathPrefixSize + 4; + +#if defined(_WIN32) && !defined(UNDER_CE) + +bool IsDevicePath(CFSTR s) throw(); /* \\.\ */ +bool IsSuperUncPath(CFSTR s) throw(); /* \\?\UNC\ */ +bool IsNetworkPath(CFSTR s) throw(); /* \\?\UNC\ or \\SERVER */ + +/* GetNetworkServerPrefixSize() returns size of server prefix: + \\?\UNC\SERVER\ + \\SERVER\ + in another cases it returns 0 +*/ + +unsigned GetNetworkServerPrefixSize(CFSTR s) throw(); + +bool IsNetworkShareRootPath(CFSTR s) throw(); /* \\?\UNC\SERVER\share or \\SERVER\share or with slash */ + +bool IsDrivePath_SuperAllowed(CFSTR s) throw(); // first chars are drive chars like "a:\" or "\\?\a:\" +bool IsDriveRootPath_SuperAllowed(CFSTR s) throw(); // exact drive root path "a:\" or "\\?\a:\" + +bool IsDrivePath2(const wchar_t *s) throw(); // first 2 chars are drive chars like "a:" +// bool IsDriveName2(const wchar_t *s) throw(); // is drive name like "a:" +bool IsSuperPath(const wchar_t *s) throw(); +bool IsSuperOrDevicePath(const wchar_t *s) throw(); + +bool IsAltStreamPrefixWithColon(const UString &s) throw(); +// returns true, if super prefix was removed +bool If_IsSuperPath_RemoveSuperPrefix(UString &s); + +#ifndef USE_UNICODE_FSTRING +bool IsDrivePath2(CFSTR s) throw(); // first 2 chars are drive chars like "a:" +// bool IsDriveName2(CFSTR s) throw(); // is drive name like "a:" +bool IsDrivePath(CFSTR s) throw(); +bool IsSuperPath(CFSTR s) throw(); +bool IsSuperOrDevicePath(CFSTR s) throw(); + +/* GetRootPrefixSize() returns size of ROOT PREFIX for cases: + \ + \\.\ + C:\ + \\?\C:\ + \\?\UNC\SERVER\Shared\ + \\SERVER\Shared\ + in another cases it returns 0 +*/ + +unsigned GetRootPrefixSize(CFSTR s) throw(); + +#endif + +int FindAltStreamColon(CFSTR path) throw(); + +#endif // _WIN32 + +bool IsAbsolutePath(const wchar_t *s) throw(); +unsigned GetRootPrefixSize(const wchar_t *s) throw(); + +#ifndef _WIN32 +/* GetRootPrefixSize_WINDOWS() is called in linux, but it parses path by windows rules. + It supports only paths system (linux) slash separators (STRING_PATH_SEPARATOR), + It doesn't parses paths with backslash (windows) separators. + "c:/dir/file" is supported. +*/ +unsigned GetRootPrefixSize_WINDOWS(const wchar_t *s) throw(); +#endif + +#ifdef Z7_LONG_PATH + +const int kSuperPathType_UseOnlyMain = 0; +const int kSuperPathType_UseOnlySuper = 1; +const int kSuperPathType_UseMainAndSuper = 2; + +int GetUseSuperPathType(CFSTR s) throw(); +bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew); +bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew); + +#define USE_MAIN_PATH (_useSuperPathType != kSuperPathType_UseOnlySuper) +#define USE_MAIN_PATH_2 (_useSuperPathType1 != kSuperPathType_UseOnlySuper && _useSuperPathType2 != kSuperPathType_UseOnlySuper) + +#define USE_SUPER_PATH (_useSuperPathType != kSuperPathType_UseOnlyMain) +#define USE_SUPER_PATH_2 (_useSuperPathType1 != kSuperPathType_UseOnlyMain || _useSuperPathType2 != kSuperPathType_UseOnlyMain) + +#define IF_USE_MAIN_PATH int _useSuperPathType = GetUseSuperPathType(path); if (USE_MAIN_PATH) +#define IF_USE_MAIN_PATH_2(x1, x2) \ + int _useSuperPathType1 = GetUseSuperPathType(x1); \ + int _useSuperPathType2 = GetUseSuperPathType(x2); \ + if (USE_MAIN_PATH_2) + +#else + +#define IF_USE_MAIN_PATH +#define IF_USE_MAIN_PATH_2(x1, x2) + +#endif // Z7_LONG_PATH + +/* + if (dirPrefix != NULL && (path) is relative) + { + (dirPrefix) will be used + result (fullPath) will contain prefix part of (dirPrefix). + } + Current_Dir path can be used in 2 cases: + 1) if (path) is relative && dirPrefix == NULL + 2) for _WIN32: if (path) is absolute starting wuth "\" +*/ +bool GetFullPath(CFSTR dirPrefix, CFSTR path, FString &fullPath); +bool GetFullPath(CFSTR path, FString &fullPath); + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileSystem.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.cpp --- p7zip-rar-16.02/CPP/Windows/FileSystem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.cpp 2024-07-16 17:00:00.000000000 +0000 @@ -0,0 +1,187 @@ +// Windows/FileSystem.cpp + +#include "StdAfx.h" + +#ifndef UNDER_CE + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#include "FileSystem.h" +#include "Defs.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NFile { +namespace NSystem { + +#ifdef _WIN32 + +bool MyGetVolumeInformation( + CFSTR rootPath, + UString &volumeName, + LPDWORD volumeSerialNumber, + LPDWORD maximumComponentLength, + LPDWORD fileSystemFlags, + UString &fileSystemName) +{ + BOOL res; + #ifndef _UNICODE + if (!g_IsNT) + { + TCHAR v[MAX_PATH + 2]; v[0] = 0; + TCHAR f[MAX_PATH + 2]; f[0] = 0; + res = GetVolumeInformation(fs2fas(rootPath), + v, MAX_PATH, + volumeSerialNumber, maximumComponentLength, fileSystemFlags, + f, MAX_PATH); + volumeName = MultiByteToUnicodeString(v); + fileSystemName = MultiByteToUnicodeString(f); + } + else + #endif + { + WCHAR v[MAX_PATH + 2]; v[0] = 0; + WCHAR f[MAX_PATH + 2]; f[0] = 0; + res = GetVolumeInformationW(fs2us(rootPath), + v, MAX_PATH, + volumeSerialNumber, maximumComponentLength, fileSystemFlags, + f, MAX_PATH); + volumeName = v; + fileSystemName = f; + } + return BOOLToBool(res); +} + +UINT MyGetDriveType(CFSTR pathName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + return GetDriveType(fs2fas(pathName)); + } + else + #endif + { + return GetDriveTypeW(fs2us(pathName)); + } +} + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0400 +// GetDiskFreeSpaceEx requires Windows95-OSR2, NT4 +#define Z7_USE_DYN_GetDiskFreeSpaceEx +#endif + +#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx +typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExA)( + LPCSTR lpDirectoryName, // directory name + PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller + PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk + PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk +); + +typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExW)( + LPCWSTR lpDirectoryName, // directory name + PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller + PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk + PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk +); +#endif + +bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize) +{ + DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters; + bool sizeIsDetected = false; + #ifndef _UNICODE + if (!g_IsNT) + { +#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx + const + Func_GetDiskFreeSpaceExA f = Z7_GET_PROC_ADDRESS( + Func_GetDiskFreeSpaceExA, GetModuleHandle(TEXT("kernel32.dll")), + "GetDiskFreeSpaceExA"); + if (f) +#endif + { + ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2; + sizeIsDetected = BOOLToBool( +#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx + f +#else + GetDiskFreeSpaceExA +#endif + (fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2)); + totalSize = totalSize2.QuadPart; + freeSize = freeSize2.QuadPart; + } + if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters)) + return false; + } + else + #endif + { +#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx + const + Func_GetDiskFreeSpaceExW f = Z7_GET_PROC_ADDRESS( + Func_GetDiskFreeSpaceExW, GetModuleHandle(TEXT("kernel32.dll")), + "GetDiskFreeSpaceExW"); + if (f) +#endif + { + ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2; + sizeIsDetected = BOOLToBool( +#ifdef Z7_USE_DYN_GetDiskFreeSpaceEx + f +#else + GetDiskFreeSpaceExW +#endif + (fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2)); + totalSize = totalSize2.QuadPart; + freeSize = freeSize2.QuadPart; + } + if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters)) + return false; + } + clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster; + if (!sizeIsDetected) + { + totalSize = clusterSize * (UInt64)numClusters; + freeSize = clusterSize * (UInt64)numFreeClusters; + } + return true; +} + +#endif + +/* +bool Is_File_LimitedBy_4GB(CFSTR _path, bool &isFsDetected) +{ + isFsDetected = false; + FString path (_path); + path.DeleteFrom(NName::GetRootPrefixSize(path)); + // GetVolumeInformation supports super paths. + // NName::If_IsSuperPath_RemoveSuperPrefix(path); + if (!path.IsEmpty()) + { + DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; + UString volName, fileSystemName; + if (MyGetVolumeInformation(path, volName, + &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, + fileSystemName)) + { + isFsDetected = true; + if (fileSystemName.IsPrefixedBy_Ascii_NoCase("fat")) + return true; + } + } + return false; +} +*/ + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/FileSystem.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.h --- p7zip-rar-16.02/CPP/Windows/FileSystem.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/FileSystem.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,31 @@ +// Windows/FileSystem.h + +#ifndef ZIP7_INC_WINDOWS_FILE_SYSTEM_H +#define ZIP7_INC_WINDOWS_FILE_SYSTEM_H + +#include "../Common/MyString.h" +#include "../Common/MyTypes.h" + +namespace NWindows { +namespace NFile { +namespace NSystem { + +#ifdef _WIN32 + +bool MyGetVolumeInformation( + CFSTR rootPath , + UString &volumeName, + LPDWORD volumeSerialNumber, + LPDWORD maximumComponentLength, + LPDWORD fileSystemFlags, + UString &fileSystemName); + +UINT MyGetDriveType(CFSTR pathName); + +bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize); + +#endif + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Handle.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Handle.h --- p7zip-rar-16.02/CPP/Windows/Handle.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Handle.h 2023-03-17 18:00:00.000000000 +0000 @@ -0,0 +1,39 @@ +// Windows/Handle.h + +#ifndef ZIP7_INC_WINDOWS_HANDLE_H +#define ZIP7_INC_WINDOWS_HANDLE_H + +#include "../Common/MyWindows.h" + +namespace NWindows { + +class CHandle MY_UNCOPYABLE +{ +protected: + HANDLE _handle; +public: + operator HANDLE() { return _handle; } + CHandle(): _handle(NULL) {} + ~CHandle() { Close(); } + bool IsCreated() const { return (_handle != NULL); } + bool Close() + { + if (_handle == NULL) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = NULL; + return true; + } + void Attach(HANDLE handle) { _handle = handle; } + HANDLE Detach() + { + const HANDLE handle = _handle; + _handle = NULL; + return handle; + } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/MemoryGlobal.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.cpp --- p7zip-rar-16.02/CPP/Windows/MemoryGlobal.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.cpp 2014-12-31 13:01:35.000000000 +0000 @@ -0,0 +1,36 @@ +// Windows/MemoryGlobal.cpp + +#include "StdAfx.h" + +#include "MemoryGlobal.h" + +namespace NWindows { +namespace NMemory { + +bool CGlobal::Alloc(UINT flags, SIZE_T size) throw() +{ + HGLOBAL newBlock = ::GlobalAlloc(flags, size); + if (newBlock == NULL) + return false; + _global = newBlock; + return true; +} + +bool CGlobal::Free() throw() +{ + if (_global == NULL) + return true; + _global = ::GlobalFree(_global); + return (_global == NULL); +} + +bool CGlobal::ReAlloc(SIZE_T size) throw() +{ + HGLOBAL newBlock = ::GlobalReAlloc(_global, size, GMEM_MOVEABLE); + if (newBlock == NULL) + return false; + _global = newBlock; + return true; +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/MemoryGlobal.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.h --- p7zip-rar-16.02/CPP/Windows/MemoryGlobal.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryGlobal.h 2023-03-17 18:00:00.000000000 +0000 @@ -0,0 +1,55 @@ +// Windows/MemoryGlobal.h + +#ifndef ZIP7_INC_WINDOWS_MEMORY_GLOBAL_H +#define ZIP7_INC_WINDOWS_MEMORY_GLOBAL_H + +#include "../Common/MyWindows.h" + +namespace NWindows { +namespace NMemory { + +class CGlobal +{ + HGLOBAL _global; +public: + CGlobal(): _global(NULL) {} + ~CGlobal() { Free(); } + operator HGLOBAL() const { return _global; } + void Attach(HGLOBAL hGlobal) + { + Free(); + _global = hGlobal; + } + HGLOBAL Detach() + { + const HGLOBAL h = _global; + _global = NULL; + return h; + } + bool Alloc(UINT flags, SIZE_T size) throw(); + bool Free() throw(); + LPVOID Lock() const { return GlobalLock(_global); } + void Unlock() const { GlobalUnlock(_global); } + bool ReAlloc(SIZE_T size) throw(); +}; + +class CGlobalLock +{ + HGLOBAL _global; + LPVOID _ptr; +public: + LPVOID GetPointer() const { return _ptr; } + CGlobalLock(HGLOBAL hGlobal): _global(hGlobal) + { + _ptr = GlobalLock(hGlobal); + } + ~CGlobalLock() + { + if (_ptr) + GlobalUnlock(_global); + } +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/MemoryLock.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.cpp --- p7zip-rar-16.02/CPP/Windows/MemoryLock.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.cpp 2024-05-02 11:00:00.000000000 +0000 @@ -0,0 +1,127 @@ +// Windows/MemoryLock.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#include "MemoryLock.h" + +namespace NWindows { +namespace NSecurity { + +#ifndef UNDER_CE + +#ifdef _UNICODE +#define MY_FUNC_SELECT(f) :: f +#else +#define MY_FUNC_SELECT(f) my_ ## f +extern "C" { +typedef BOOL (WINAPI * Func_OpenProcessToken)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle); +typedef BOOL (WINAPI * Func_LookupPrivilegeValue)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid); +typedef BOOL (WINAPI * Func_AdjustTokenPrivileges)(HANDLE TokenHandle, BOOL DisableAllPrivileges, + PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength); +} + +#define GET_PROC_ADDR(fff, name) \ + const Func_ ## fff my_ ## fff = Z7_GET_PROC_ADDRESS( \ + Func_ ## fff, hModule, name); +#endif + +bool EnablePrivilege(LPCTSTR privilegeName, bool enable) +{ + bool res = false; + + #ifndef _UNICODE + + const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); + if (!hModule) + return false; + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + + GET_PROC_ADDR( + OpenProcessToken, + "OpenProcessToken") + GET_PROC_ADDR( + LookupPrivilegeValue, + "LookupPrivilegeValueA") + GET_PROC_ADDR( + AdjustTokenPrivileges, + "AdjustTokenPrivileges") + + if (my_OpenProcessToken && + my_AdjustTokenPrivileges && + my_LookupPrivilegeValue) + + #endif + + { + HANDLE token; + if (MY_FUNC_SELECT(OpenProcessToken)(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + { + TOKEN_PRIVILEGES tp; + if (MY_FUNC_SELECT(LookupPrivilegeValue)(NULL, privilegeName, &(tp.Privileges[0].Luid))) + { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = (enable ? SE_PRIVILEGE_ENABLED : 0); + if (MY_FUNC_SELECT(AdjustTokenPrivileges)(token, FALSE, &tp, 0, NULL, NULL)) + res = (GetLastError() == ERROR_SUCCESS); + } + ::CloseHandle(token); + } + } + + #ifndef _UNICODE + + ::FreeLibrary(hModule); + + #endif + + return res; +} + + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); + +/* + We suppose that Window 10 works incorrectly with "Large Pages" at: + - Windows 10 1703 (15063) : incorrect allocating after VirtualFree() + - Windows 10 1709 (16299) : incorrect allocating after VirtualFree() + - Windows 10 1809 (17763) : the failures for blocks of 1 GiB and larger, + if CPU doesn't support 1 GB pages. + Windows 10 1903 (18362) probably works correctly. +*/ + +unsigned Get_LargePages_RiskLevel() +{ + OSVERSIONINFOEXW vi; + const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + if (!ntdll) + return 0; + const + Func_RtlGetVersion func = Z7_GET_PROC_ADDRESS( + Func_RtlGetVersion, ntdll, + "RtlGetVersion"); + if (!func) + return 0; + func(&vi); + if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) + return 0; + if (vi.dwMajorVersion + vi.dwMinorVersion != 10) + return 0; + if (vi.dwBuildNumber <= 16299) + return 1; + + #ifdef MY_CPU_X86_OR_AMD64 + if (vi.dwBuildNumber < 18362 && !CPU_IsSupported_PageGB()) + return 1; + #endif + + return 0; +} + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/MemoryLock.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.h --- p7zip-rar-16.02/CPP/Windows/MemoryLock.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/MemoryLock.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,40 @@ +// Windows/MemoryLock.h + +#ifndef ZIP7_INC_WINDOWS_MEMORY_LOCK_H +#define ZIP7_INC_WINDOWS_MEMORY_LOCK_H + +#include "../Common/MyWindows.h" + +namespace NWindows { +namespace NSecurity { + +#ifndef UNDER_CE + +bool EnablePrivilege(LPCTSTR privilegeName, bool enable = true); + +inline bool EnablePrivilege_LockMemory(bool enable = true) +{ + return EnablePrivilege(SE_LOCK_MEMORY_NAME, enable); +} + +inline void EnablePrivilege_SymLink() +{ + /* Probably we do not to set any Privilege for junction points. + But we need them for Symbolic links */ + NSecurity::EnablePrivilege(SE_RESTORE_NAME); + + /* Probably we need only SE_RESTORE_NAME, but there is also + SE_CREATE_SYMBOLIC_LINK_NAME. So we set it also. Do we need it? */ + + NSecurity::EnablePrivilege(TEXT("SeCreateSymbolicLinkPrivilege")); // SE_CREATE_SYMBOLIC_LINK_NAME + + // Do we need to set SE_BACKUP_NAME ? +} + +unsigned Get_LargePages_RiskLevel(); + +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Menu.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.cpp --- p7zip-rar-16.02/CPP/Windows/Menu.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.cpp 2023-03-06 16:00:00.000000000 +0000 @@ -0,0 +1,265 @@ +// Windows/Menu.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif +#include "Menu.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +/* +structures + MENUITEMINFOA + MENUITEMINFOW +contain additional member: + #if (WINVER >= 0x0500) + HBITMAP hbmpItem; + #endif +If we compile the source code with (WINVER >= 0x0500), some functions +will not work at NT4, if cbSize is set as sizeof(MENUITEMINFO). +So we use size of old version of structure in some conditions. +Win98 probably supports full structure including hbmpItem. + +We have 2 ways to get/set string in menu item: +win95/NT4: we must use MIIM_TYPE only. + MIIM_TYPE : Retrieves or sets the fType and dwTypeData members. +win98/win2000: there are new flags that can be used instead of MIIM_TYPE: + MIIM_FTYPE : Retrieves or sets the fType member. + MIIM_STRING : Retrieves or sets the dwTypeData member. + +Windows versions probably support MIIM_TYPE flag, if we set MENUITEMINFO::cbSize +as sizeof of old (small) MENUITEMINFO that doesn't include (hbmpItem) field. +But do all Windows versions support old MIIM_TYPE flag, if we use +MENUITEMINFO::cbSize as sizeof of new (big) MENUITEMINFO including (hbmpItem) field ? +win10 probably supports any combination of small/big (cbSize) and old/new MIIM_TYPE/MIIM_STRING. +*/ + +#if defined(UNDER_CE) || defined(_WIN64) || (WINVER < 0x0500) + #ifndef _UNICODE + #define my_compatib_MENUITEMINFOA_size sizeof(MENUITEMINFOA) + #endif + #define my_compatib_MENUITEMINFOW_size sizeof(MENUITEMINFOW) +#else + #define MY_STRUCT_SIZE_BEFORE(structname, member) ((UINT)(UINT_PTR)((LPBYTE)(&((structname*)0)->member) - (LPBYTE)(structname*)0)) + #ifndef _UNICODE + #define my_compatib_MENUITEMINFOA_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOA, hbmpItem) + #endif + #define my_compatib_MENUITEMINFOW_size MY_STRUCT_SIZE_BEFORE(MENUITEMINFOW, hbmpItem) +#if defined(__clang__) && __clang_major__ >= 13 +// error : performing pointer subtraction with a null pointer may have undefined behavior +#pragma GCC diagnostic ignored "-Wnull-pointer-subtraction" +#endif +#endif + + +#define COPY_MENUITEM_field(d, s, name) \ + d.name = s.name; + +#define COPY_MENUITEM_fields(d, s) \ + COPY_MENUITEM_field(d, s, fMask) \ + COPY_MENUITEM_field(d, s, fType) \ + COPY_MENUITEM_field(d, s, fState) \ + COPY_MENUITEM_field(d, s, wID) \ + COPY_MENUITEM_field(d, s, hSubMenu) \ + COPY_MENUITEM_field(d, s, hbmpChecked) \ + COPY_MENUITEM_field(d, s, hbmpUnchecked) \ + COPY_MENUITEM_field(d, s, dwItemData) \ + +static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOW &si) +{ + ZeroMemory(&si, sizeof(si)); + si.cbSize = my_compatib_MENUITEMINFOW_size; // sizeof(si); + COPY_MENUITEM_fields(si, item) +} + +#ifndef _UNICODE +static void ConvertItemToSysForm(const CMenuItem &item, MENUITEMINFOA &si) +{ + ZeroMemory(&si, sizeof(si)); + si.cbSize = my_compatib_MENUITEMINFOA_size; // sizeof(si); + COPY_MENUITEM_fields(si, item) +} +#endif + +static void ConvertItemToMyForm(const MENUITEMINFOW &si, CMenuItem &item) +{ + COPY_MENUITEM_fields(item, si) +} + +#ifndef _UNICODE +static void ConvertItemToMyForm(const MENUITEMINFOA &si, CMenuItem &item) +{ + COPY_MENUITEM_fields(item, si) +} +#endif + + +bool CMenu::GetItem(UINT itemIndex, bool byPosition, CMenuItem &item) const +{ + item.StringValue.Empty(); + const unsigned kMaxSize = 512; + #ifndef _UNICODE + if (!g_IsNT) + { + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + const bool isString = item.IsString(); + unsigned bufSize = kMaxSize; + AString a; + if (isString) + { + si.cch = bufSize; + si.dwTypeData = a.GetBuf(bufSize); + } + bool res = GetItemInfo(itemIndex, byPosition, &si); + if (isString) + a.ReleaseBuf_CalcLen(bufSize); + if (!res) + return false; + { + if (isString && si.cch >= bufSize - 1) + { + si.dwTypeData = NULL; + res = GetItemInfo(itemIndex, byPosition, &si); + if (!res) + return false; + si.cch++; + bufSize = si.cch; + si.dwTypeData = a.GetBuf(bufSize); + res = GetItemInfo(itemIndex, byPosition, &si); + a.ReleaseBuf_CalcLen(bufSize); + if (!res) + return false; + } + ConvertItemToMyForm(si, item); + if (isString) + item.StringValue = GetUnicodeString(a); + return true; + } + } + else + #endif + { + wchar_t s[kMaxSize + 1]; + s[0] = 0; + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + const bool isString = item.IsString(); + unsigned bufSize = kMaxSize; + if (isString) + { + si.cch = bufSize; + si.dwTypeData = s; + } + bool res = GetItemInfo(itemIndex, byPosition, &si); + if (!res) + return false; + if (isString) + { + s[Z7_ARRAY_SIZE(s) - 1] = 0; + item.StringValue = s; + if (si.cch >= bufSize - 1) + { + si.dwTypeData = NULL; + res = GetItemInfo(itemIndex, byPosition, &si); + if (!res) + return false; + si.cch++; + bufSize = si.cch; + si.dwTypeData = item.StringValue.GetBuf(bufSize); + res = GetItemInfo(itemIndex, byPosition, &si); + item.StringValue.ReleaseBuf_CalcLen(bufSize); + if (!res) + return false; + } + // if (item.StringValue.Len() != si.cch) throw 123; // for debug + } + ConvertItemToMyForm(si, item); + return true; + } +} + + +bool CMenu::SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + AString s; + if (item.IsString()) + { + s = GetSystemString(item.StringValue); + si.dwTypeData = s.Ptr_non_const(); + } + return SetItemInfo(itemIndex, byPosition, &si); + } + else + #endif + { + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + si.dwTypeData = item.StringValue.Ptr_non_const(); + return SetItemInfo(itemIndex, byPosition, &si); + } +} + + +bool CMenu::InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + MENUITEMINFOA si; + ConvertItemToSysForm(item, si); + AString s; + if (item.IsString()) + { + s = GetSystemString(item.StringValue); + si.dwTypeData = s.Ptr_non_const(); + } + return InsertItem(itemIndex, byPosition, &si); + } + else + #endif + { + MENUITEMINFOW si; + ConvertItemToSysForm(item, si); + if (item.IsString()) + si.dwTypeData = item.StringValue.Ptr_non_const(); + #ifdef UNDER_CE + UINT flags = (item.fType & MFT_SEPARATOR) ? MF_SEPARATOR : MF_STRING; + UINT_PTR id = item.wID; + if ((item.fMask & MIIM_SUBMENU) != 0) + { + flags |= MF_POPUP; + id = (UINT_PTR)item.hSubMenu; + } + if (!Insert(itemIndex, flags | (byPosition ? MF_BYPOSITION : MF_BYCOMMAND), id, item.StringValue)) + return false; + return SetItemInfo(itemIndex, byPosition, &si); + #else + return InsertItem(itemIndex, byPosition, &si); + #endif + } +} + +#ifndef _UNICODE +bool CMenu::AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem) +{ + if (g_IsNT) + return BOOLToBool(::AppendMenuW(_menu, flags, newItemID, newItem)); + else + return AppendItem(flags, newItemID, GetSystemString(newItem)); +} +#endif + +} diff -Nru p7zip-rar-16.02/CPP/Windows/Menu.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.h --- p7zip-rar-16.02/CPP/Windows/Menu.h 2010-11-07 21:28:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Menu.h 2023-01-22 07:00:00.000000000 +0000 @@ -1,4 +1,170 @@ - -/* TODO */ - - +// Windows/Menu.h + +#ifndef ZIP7_INC_WINDOWS_MENU_H +#define ZIP7_INC_WINDOWS_MENU_H + +#include "../Common/MyWindows.h" +#include "../Common/MyString.h" + +#include "Defs.h" + +namespace NWindows { + +#ifndef MIIM_STRING +#define MIIM_STRING 0x00000040 +#endif +/* +#ifndef MIIM_BITMAP +#define MIIM_BITMAP 0x00000080 +#endif +*/ +#ifndef MIIM_FTYPE +#define MIIM_FTYPE 0x00000100 +#endif + +struct CMenuItem +{ + UString StringValue; + UINT fMask; + UINT fType; + UINT fState; + UINT wID; + HMENU hSubMenu; + HBITMAP hbmpChecked; + HBITMAP hbmpUnchecked; + ULONG_PTR dwItemData; + // LPTSTR dwTypeData; + // UINT cch; + // HBITMAP hbmpItem; + bool IsString() const { return (fMask & (MIIM_TYPE | MIIM_STRING)) != 0; } + bool IsSeparator() const { return (fType == MFT_SEPARATOR); } + CMenuItem(): fMask(0), fType(0), fState(0), wID(0), + hSubMenu(NULL), hbmpChecked(NULL), hbmpUnchecked(NULL), dwItemData(0) {} +}; + +class CMenu +{ + HMENU _menu; +public: + CMenu(): _menu(NULL) {} + operator HMENU() const { return _menu; } + void Attach(HMENU menu) { _menu = menu; } + + HMENU Detach() + { + const HMENU menu = _menu; + _menu = NULL; + return menu; + } + + bool Create() + { + _menu = ::CreateMenu(); + return (_menu != NULL); + } + + bool CreatePopup() + { + _menu = ::CreatePopupMenu(); + return (_menu != NULL); + } + + bool Destroy() + { + if (!_menu) + return false; + return BOOLToBool(::DestroyMenu(Detach())); + } + + int GetItemCount() const + { + #ifdef UNDER_CE + for (unsigned i = 0;; i++) + { + CMenuItem item; + item.fMask = MIIM_STATE; + if (!GetItem(i, true, item)) + return (int)i; + } + #else + return GetMenuItemCount(_menu); + #endif + } + + HMENU GetSubMenu(int pos) const { return ::GetSubMenu(_menu, pos); } + #ifndef UNDER_CE + /* + bool GetItemString(UINT idItem, UINT flag, CSysString &result) + { + result.Empty(); + int len = ::GetMenuString(_menu, idItem, 0, 0, flag); + int len2 = ::GetMenuString(_menu, idItem, result.GetBuf(len + 2), len + 1, flag); + if (len > len2) + len = len2; + result.ReleaseBuf_CalcLen(len + 2); + return (len != 0); + } + */ + UINT GetItemID(int pos) const { return ::GetMenuItemID(_menu, pos); } + UINT GetItemState(UINT id, UINT flags) const { return ::GetMenuState(_menu, id, flags); } + #endif + + bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo) const + { return BOOLToBool(::GetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo) + { return BOOLToBool(::SetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + + bool AppendItem(UINT flags, UINT_PTR newItemID, LPCTSTR newItem) + { return BOOLToBool(::AppendMenu(_menu, flags, newItemID, newItem)); } + + bool Insert(UINT position, UINT flags, UINT_PTR idNewItem, LPCTSTR newItem) + { return BOOLToBool(::InsertMenu(_menu, position, flags, idNewItem, newItem)); } + + #ifndef UNDER_CE + bool InsertItem(UINT itemIndex, bool byPosition, LPCMENUITEMINFO itemInfo) + { return BOOLToBool(::InsertMenuItem(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + #endif + + bool RemoveItem(UINT item, UINT flags) { return BOOLToBool(::RemoveMenu(_menu, item, flags)); } + void RemoveAllItemsFrom(UINT index) { while (RemoveItem(index, MF_BYPOSITION)); } + void RemoveAllItems() { RemoveAllItemsFrom(0); } + + #ifndef _UNICODE + bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) const + { return BOOLToBool(::GetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool InsertItem(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) + { return BOOLToBool(::InsertMenuItemW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo) + { return BOOLToBool(::SetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); } + bool AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem); + #endif + + bool GetItem(UINT itemIndex, bool byPosition, CMenuItem &item) const; + bool SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item); + bool InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item); + + int Track(UINT flags, int x, int y, HWND hWnd) { return ::TrackPopupMenuEx(_menu, flags, x, y, hWnd, NULL); } + + bool CheckRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT flags) + { return BOOLToBool(::CheckMenuRadioItem(_menu, idFirst, idLast, idCheck, flags)); } + + DWORD CheckItem(UINT id, UINT uCheck) { return ::CheckMenuItem(_menu, id, uCheck); } + DWORD CheckItemByID(UINT id, bool check) { return CheckItem(id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); } + + BOOL EnableItem(UINT uIDEnableItem, UINT uEnable) { return EnableMenuItem(_menu, uIDEnableItem, uEnable); } +}; + +class CMenuDestroyer +{ + CMenu *_menu; +public: + CMenuDestroyer(CMenu &menu): _menu(&menu) {} + CMenuDestroyer(): _menu(NULL) {} + ~CMenuDestroyer() { if (_menu) _menu->Destroy(); } + void Attach(CMenu &menu) { _menu = &menu; } + void Disable() { _menu = NULL; } +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/NationalTime.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.cpp --- p7zip-rar-16.02/CPP/Windows/NationalTime.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.cpp 2023-01-17 11:00:00.000000000 +0000 @@ -0,0 +1,37 @@ +// Windows/NationalTime.cpp + +#include "StdAfx.h" + +#include "NationalTime.h" + +namespace NWindows { +namespace NNational { +namespace NTime { + +bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time, + LPCTSTR format, CSysString &resultString) +{ + resultString.Empty(); + int numChars = ::GetTimeFormat(locale, flags, time, format, NULL, 0); + if (numChars == 0) + return false; + numChars = ::GetTimeFormat(locale, flags, time, format, + resultString.GetBuf((unsigned)numChars), numChars + 1); + resultString.ReleaseBuf_CalcLen((unsigned)numChars); + return (numChars != 0); +} + +bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time, + LPCTSTR format, CSysString &resultString) +{ + resultString.Empty(); + int numChars = ::GetDateFormat(locale, flags, time, format, NULL, 0); + if (numChars == 0) + return false; + numChars = ::GetDateFormat(locale, flags, time, format, + resultString.GetBuf((unsigned)numChars), numChars + 1); + resultString.ReleaseBuf_CalcLen((unsigned)numChars); + return (numChars != 0); +} + +}}} diff -Nru p7zip-rar-16.02/CPP/Windows/NationalTime.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.h --- p7zip-rar-16.02/CPP/Windows/NationalTime.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/NationalTime.h 2023-01-10 17:00:00.000000000 +0000 @@ -0,0 +1,20 @@ +// Windows/NationalTime.h + +#ifndef ZIP7_INC_WINDOWS_NATIONAL_TIME_H +#define ZIP7_INC_WINDOWS_NATIONAL_TIME_H + +#include "../Common/MyString.h" + +namespace NWindows { +namespace NNational { +namespace NTime { + +bool MyGetTimeFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time, + LPCTSTR format, CSysString &resultString); + +bool MyGetDateFormat(LCID locale, DWORD flags, CONST SYSTEMTIME *time, + LPCTSTR format, CSysString &resultString); + +}}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Net.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.cpp --- p7zip-rar-16.02/CPP/Windows/Net.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.cpp 2023-03-18 07:00:00.000000000 +0000 @@ -0,0 +1,398 @@ +// Windows/Net.cpp + +#include "StdAfx.h" + +#include "../Common/MyBuffer.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#include "Net.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +extern "C" +{ +#if !defined(WNetGetResourceParent) +// #if defined(Z7_OLD_WIN_SDK) +// #if (WINVER >= 0x0400) +DWORD APIENTRY WNetGetResourceParentA(IN LPNETRESOURCEA lpNetResource, + OUT LPVOID lpBuffer, IN OUT LPDWORD lpcbBuffer); +DWORD APIENTRY WNetGetResourceParentW(IN LPNETRESOURCEW lpNetResource, + OUT LPVOID lpBuffer, IN OUT LPDWORD lpcbBuffer); +#ifdef UNICODE +#define WNetGetResourceParent WNetGetResourceParentW +#else +#define WNetGetResourceParent WNetGetResourceParentA +#endif + +DWORD APIENTRY WNetGetResourceInformationA(IN LPNETRESOURCEA lpNetResource, + OUT LPVOID lpBuffer, IN OUT LPDWORD lpcbBuffer, OUT LPSTR *lplpSystem); +DWORD APIENTRY WNetGetResourceInformationW(IN LPNETRESOURCEW lpNetResource, + OUT LPVOID lpBuffer, IN OUT LPDWORD lpcbBuffer, OUT LPWSTR *lplpSystem); +#ifdef UNICODE +#define WNetGetResourceInformation WNetGetResourceInformationW +#else +#define WNetGetResourceInformation WNetGetResourceInformationA +#endif +// #endif // (WINVER >= 0x0400) +#endif +} + +namespace NWindows { +namespace NNet { + +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource) +{ + Close(); + const DWORD result = ::WNetOpenEnum(scope, type, usage, netResource, &_handle); + _handleAllocated = (result == NO_ERROR); + return result; +} + +#ifndef _UNICODE +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource) +{ + Close(); + const DWORD result = ::WNetOpenEnumW(scope, type, usage, netResource, &_handle); + _handleAllocated = (result == NO_ERROR); + return result; +} +#endif + +static void SetComplexString(bool &defined, CSysString &destString, LPCTSTR srcString) +{ + defined = (srcString != NULL); + if (defined) + destString = srcString; + else + destString.Empty(); +} + +static void ConvertNETRESOURCEToCResource(const NETRESOURCE &netResource, CResource &resource) +{ + resource.Scope = netResource.dwScope; + resource.Type = netResource.dwType; + resource.DisplayType = netResource.dwDisplayType; + resource.Usage = netResource.dwUsage; + SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName); + SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName); + SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment); + SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider); +} + +static void SetComplexString2(LPTSTR *destString, bool defined, const CSysString &srcString) +{ + if (defined) + *destString = srcString.Ptr_non_const(); + else + *destString = NULL; +} + +static void ConvertCResourceToNETRESOURCE(const CResource &resource, NETRESOURCE &netResource) +{ + netResource.dwScope = resource.Scope; + netResource.dwType = resource.Type; + netResource.dwDisplayType = resource.DisplayType; + netResource.dwUsage = resource.Usage; + SetComplexString2(&netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName); + SetComplexString2(&netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName); + SetComplexString2(&netResource.lpComment, resource.CommentIsDefined, resource.Comment); + SetComplexString2(&netResource.lpProvider, resource.ProviderIsDefined, resource.Provider); +} + +#ifndef _UNICODE + +static void SetComplexString(bool &defined, UString &destString, LPCWSTR src) +{ + defined = (src != NULL); + if (defined) + destString = src; + else + destString.Empty(); +} + +static void ConvertNETRESOURCEToCResource(const NETRESOURCEW &netResource, CResourceW &resource) +{ + resource.Scope = netResource.dwScope; + resource.Type = netResource.dwType; + resource.DisplayType = netResource.dwDisplayType; + resource.Usage = netResource.dwUsage; + SetComplexString(resource.LocalNameIsDefined, resource.LocalName, netResource.lpLocalName); + SetComplexString(resource.RemoteNameIsDefined, resource.RemoteName, netResource.lpRemoteName); + SetComplexString(resource.CommentIsDefined, resource.Comment, netResource.lpComment); + SetComplexString(resource.ProviderIsDefined, resource.Provider, netResource.lpProvider); +} + +static void SetComplexString2(LPWSTR *destString, bool defined, const UString &srcString) +{ + if (defined) + *destString = srcString.Ptr_non_const(); + else + *destString = NULL; +} + +static void ConvertCResourceToNETRESOURCE(const CResourceW &resource, NETRESOURCEW &netResource) +{ + netResource.dwScope = resource.Scope; + netResource.dwType = resource.Type; + netResource.dwDisplayType = resource.DisplayType; + netResource.dwUsage = resource.Usage; + SetComplexString2(&netResource.lpLocalName, resource.LocalNameIsDefined, resource.LocalName); + SetComplexString2(&netResource.lpRemoteName, resource.RemoteNameIsDefined, resource.RemoteName); + SetComplexString2(&netResource.lpComment, resource.CommentIsDefined, resource.Comment); + SetComplexString2(&netResource.lpProvider, resource.ProviderIsDefined, resource.Provider); +} + +static void ConvertResourceWToResource(const CResourceW &resourceW, CResource &resource) +{ + *(CResourceBase *)&resource = *(CResourceBase *)&resourceW; + resource.LocalName = GetSystemString(resourceW.LocalName); + resource.RemoteName = GetSystemString(resourceW.RemoteName); + resource.Comment = GetSystemString(resourceW.Comment); + resource.Provider = GetSystemString(resourceW.Provider); +} + +static void ConvertResourceToResourceW(const CResource &resource, CResourceW &resourceW) +{ + *(CResourceBase *)&resourceW = *(CResourceBase *)&resource; + resourceW.LocalName = GetUnicodeString(resource.LocalName); + resourceW.RemoteName = GetUnicodeString(resource.RemoteName); + resourceW.Comment = GetUnicodeString(resource.Comment); + resourceW.Provider = GetUnicodeString(resource.Provider); +} +#endif + +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource) +{ + NETRESOURCE netResource; + LPNETRESOURCE pointer = NULL; + if (resource) + { + ConvertCResourceToNETRESOURCE(*resource, netResource); + pointer = &netResource; + } + return Open(scope, type, usage, pointer); +} + +#ifndef _UNICODE +DWORD CEnum::Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource) +{ + if (g_IsNT) + { + NETRESOURCEW netResource; + LPNETRESOURCEW pointer = NULL; + if (resource) + { + ConvertCResourceToNETRESOURCE(*resource, netResource); + pointer = &netResource; + } + return Open(scope, type, usage, pointer); + } + CResource resourceA; + CResource *pointer = NULL; + if (resource) + { + ConvertResourceWToResource(*resource, resourceA); + pointer = &resourceA; + } + return Open(scope, type, usage, pointer); +} +#endif + +DWORD CEnum::Close() +{ + if (!_handleAllocated) + return NO_ERROR; + const DWORD result = ::WNetCloseEnum(_handle); + _handleAllocated = (result != NO_ERROR); + return result; +} + +DWORD CEnum::Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + return ::WNetEnumResource(_handle, lpcCount, lpBuffer, lpBufferSize); +} + +#ifndef _UNICODE +DWORD CEnum::NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize) +{ + return ::WNetEnumResourceW(_handle, lpcCount, lpBuffer, lpBufferSize); +} +#endif + +DWORD CEnum::Next(CResource &resource) +{ + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + DWORD numEntries = 1; + const DWORD result = Next(&numEntries, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + if (numEntries != 1) + return (DWORD)E_FAIL; + ConvertNETRESOURCEToCResource(lpnrLocal[0], resource); + return result; +} + +#ifndef _UNICODE +DWORD CEnum::Next(CResourceW &resource) +{ + if (g_IsNT) + { + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + DWORD numEntries = 1; + const DWORD result = NextW(&numEntries, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + if (numEntries != 1) + return (DWORD)E_FAIL; + ConvertNETRESOURCEToCResource(lpnrLocal[0], resource); + return result; + } + CResource resourceA; + const DWORD result = Next(resourceA); + ConvertResourceToResourceW(resourceA, resource); + return result; +} +#endif + + +DWORD GetResourceParent(const CResource &resource, CResource &parentResource) +{ + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCE netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + const DWORD result = ::WNetGetResourceParent(&netResource, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource); + return result; +} + +#ifndef _UNICODE +DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource) +{ + if (g_IsNT) + { + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + const DWORD result = ::WNetGetResourceParentW(&netResource, lpnrLocal, &bufferSize); + if (result != NO_ERROR) + return result; + ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource); + return result; + } + CResource resourceA, parentResourceA; + ConvertResourceWToResource(resource, resourceA); + const DWORD result = GetResourceParent(resourceA, parentResourceA); + ConvertResourceToResourceW(parentResourceA, parentResource); + return result; +} +#endif + +DWORD GetResourceInformation(const CResource &resource, + CResource &destResource, CSysString &systemPathPart) +{ + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCE netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + LPTSTR lplpSystem; + const DWORD result = ::WNetGetResourceInformation(&netResource, + lpnrLocal, &bufferSize, &lplpSystem); + if (result != NO_ERROR) + return result; + if (lplpSystem != NULL) + systemPathPart = lplpSystem; + ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource); + return result; +} + +#ifndef _UNICODE +DWORD GetResourceInformation(const CResourceW &resource, + CResourceW &destResource, UString &systemPathPart) +{ + if (g_IsNT) + { + const DWORD kBufferSize = 16384; + CByteArr byteBuffer(kBufferSize); + LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (void *) (BYTE *)(byteBuffer); + ZeroMemory(lpnrLocal, kBufferSize); + DWORD bufferSize = kBufferSize; + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + LPWSTR lplpSystem; + const DWORD result = ::WNetGetResourceInformationW(&netResource, + lpnrLocal, &bufferSize, &lplpSystem); + if (result != NO_ERROR) + return result; + if (lplpSystem != 0) + systemPathPart = lplpSystem; + ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource); + return result; + } + CResource resourceA, destResourceA; + ConvertResourceWToResource(resource, resourceA); + AString systemPathPartA; + const DWORD result = GetResourceInformation(resourceA, destResourceA, systemPathPartA); + ConvertResourceToResourceW(destResourceA, destResource); + systemPathPart = GetUnicodeString(systemPathPartA); + return result; +} +#endif + +DWORD AddConnection2(const CResource &resource, + LPCTSTR password, LPCTSTR userName, DWORD flags) +{ + NETRESOURCE netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + return ::WNetAddConnection2(&netResource, + password, userName, flags); +} + +DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags); + +#ifndef _UNICODE +DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags) +{ + if (g_IsNT) + { + NETRESOURCEW netResource; + ConvertCResourceToNETRESOURCE(resource, netResource); + return ::WNetAddConnection2W(&netResource,password, userName, flags); + } + CResource resourceA; + ConvertResourceWToResource(resource, resourceA); + const CSysString passwordA (GetSystemString(password)); + const CSysString userNameA (GetSystemString(userName)); + return AddConnection2(resourceA, + password ? (LPCTSTR)passwordA: 0, + userName ? (LPCTSTR)userNameA: 0, + flags); +} +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Net.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.h --- p7zip-rar-16.02/CPP/Windows/Net.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Net.h 2023-03-18 07:00:00.000000000 +0000 @@ -0,0 +1,87 @@ +// Windows/Net.h + +#ifndef ZIP7_INC_WINDOWS_NET_H +#define ZIP7_INC_WINDOWS_NET_H + +#include "../Common/MyString.h" +#include "../Common/MyWindows.h" + +namespace NWindows { +namespace NNet { + +struct CResourceBase +{ + DWORD Scope; + DWORD Type; + DWORD DisplayType; + DWORD Usage; + bool LocalNameIsDefined; + bool RemoteNameIsDefined; + bool CommentIsDefined; + bool ProviderIsDefined; +}; + +struct CResource: public CResourceBase +{ + CSysString LocalName; + CSysString RemoteName; + CSysString Comment; + CSysString Provider; +}; + +#ifdef _UNICODE +typedef CResource CResourceW; +#else +struct CResourceW: public CResourceBase +{ + UString LocalName; + UString RemoteName; + UString Comment; + UString Provider; +}; +#endif + +class CEnum +{ + HANDLE _handle; + bool _handleAllocated; + DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCE netResource); + DWORD Next(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize); + #ifndef _UNICODE + DWORD Open(DWORD scope, DWORD type, DWORD usage, LPNETRESOURCEW netResource); + DWORD NextW(LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize); + #endif +protected: + bool IsHandleAllocated() const { return _handleAllocated; } +public: + CEnum(): _handleAllocated(false) {} + ~CEnum() { Close(); } + DWORD Close(); + DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResource *resource); + DWORD Next(CResource &resource); + #ifndef _UNICODE + DWORD Open(DWORD scope, DWORD type, DWORD usage, const CResourceW *resource); + DWORD Next(CResourceW &resource); + #endif +}; + +DWORD GetResourceParent(const CResource &resource, CResource &parentResource); +#ifndef _UNICODE +DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource); +#endif + +DWORD GetResourceInformation(const CResource &resource, + CResource &destResource, CSysString &systemPathPart); +#ifndef _UNICODE +DWORD GetResourceInformation(const CResourceW &resource, + CResourceW &destResource, UString &systemPathPart); +#endif + +DWORD AddConnection2(const CResource &resource, LPCTSTR password, LPCTSTR userName, DWORD flags); +#ifndef _UNICODE +DWORD AddConnection2(const CResourceW &resource, LPCWSTR password, LPCWSTR userName, DWORD flags); +#endif + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/NtCheck.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/NtCheck.h --- p7zip-rar-16.02/CPP/Windows/NtCheck.h 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/NtCheck.h 2023-03-08 18:00:00.000000000 +0000 @@ -1,46 +1,58 @@ -// Windows/NtCheck.h - -#ifndef __WINDOWS_NT_CHECK_H -#define __WINDOWS_NT_CHECK_H - -#ifdef _WIN32 - -#include "../Common/MyWindows.h" - -#if !defined(_WIN64) && !defined(UNDER_CE) -static inline bool IsItWindowsNT() -{ - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT); -} -#endif - -#ifndef _UNICODE - #if defined(_WIN64) || defined(UNDER_CE) - bool g_IsNT = true; - #define SET_IS_NT - #else - bool g_IsNT = false; - #define SET_IS_NT g_IsNT = IsItWindowsNT(); - #endif - #define NT_CHECK_ACTION - // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION } -#else - #if !defined(_WIN64) && !defined(UNDER_CE) - #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION } - #else - #define NT_CHECK_ACTION - #endif - #define SET_IS_NT -#endif - -#define NT_CHECK NT_CHECK_ACTION SET_IS_NT - -#else - -#define NT_CHECK - -#endif - -#endif +// Windows/NtCheck.h + +#ifndef ZIP7_INC_WINDOWS_NT_CHECK_H +#define ZIP7_INC_WINDOWS_NT_CHECK_H + +#ifdef _WIN32 + +#include "../Common/MyWindows.h" + +#if !defined(_WIN64) && !defined(UNDER_CE) + +#if defined(_MSC_VER) && _MSC_VER >= 1900 +#pragma warning(push) +// GetVersionExW was declared deprecated +#pragma warning(disable : 4996) +#endif +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#if defined(_MSC_VER) && _MSC_VER >= 1900 +#pragma warning(pop) +#endif + +#endif + +#ifndef _UNICODE + extern + bool g_IsNT; + #if defined(_WIN64) || defined(UNDER_CE) + bool g_IsNT = true; + #define SET_IS_NT + #else + bool g_IsNT = false; + #define SET_IS_NT g_IsNT = IsItWindowsNT(); + #endif + #define NT_CHECK_ACTION + // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION } +#else + #if !defined(_WIN64) && !defined(UNDER_CE) + #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION } + #else + #define NT_CHECK_ACTION + #endif + #define SET_IS_NT +#endif + +#define NT_CHECK NT_CHECK_ACTION SET_IS_NT + +#else + +#define NT_CHECK + +#endif + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/ProcessMessages.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.cpp --- p7zip-rar-16.02/CPP/Windows/ProcessMessages.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.cpp 2010-09-17 07:22:42.000000000 +0000 @@ -0,0 +1,22 @@ +// Windows/ProcessMessages.cpp + +#include "StdAfx.h" + +#include "ProcessMessages.h" + +namespace NWindows { + +void ProcessMessages(HWND window) +{ + MSG msg; + while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + if (window == (HWND) NULL || !IsDialogMessage(window, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +} + +} diff -Nru p7zip-rar-16.02/CPP/Windows/ProcessMessages.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.h --- p7zip-rar-16.02/CPP/Windows/ProcessMessages.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessMessages.h 2023-03-18 07:00:00.000000000 +0000 @@ -0,0 +1,12 @@ +// Windows/ProcessMessages.h + +#ifndef ZIP7_INC_WINDOWS_PROCESS_MESSAGES_H +#define ZIP7_INC_WINDOWS_PROCESS_MESSAGES_H + +namespace NWindows { + +void ProcessMessages(HWND window); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/ProcessUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.cpp --- p7zip-rar-16.02/CPP/Windows/ProcessUtils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.cpp 2023-12-11 11:00:00.000000000 +0000 @@ -0,0 +1,102 @@ +// ProcessUtils.cpp + +#include "StdAfx.h" + +#include "../Common/StringConvert.h" + +#include "ProcessUtils.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef UNDER_CE +static UString GetQuotedString(const UString &s) +{ + UString s2 ('\"'); + s2 += s; + s2.Add_Char('\"'); + return s2; +} +#endif + +WRes CProcess::Create(LPCWSTR imageName, const UString ¶ms, LPCWSTR curDir) +{ + /* + OutputDebugStringW(L"CProcess::Create"); + OutputDebugStringW(imageName); + if (params) + { + OutputDebugStringW(L"params:"); + OutputDebugStringW(params); + } + if (curDir) + { + OutputDebugStringW(L"cur dir:"); + OutputDebugStringW(curDir); + } + */ + + Close(); + const UString params2 = + #ifndef UNDER_CE + GetQuotedString(imageName) + L' ' + + #endif + params; + #ifdef UNDER_CE + curDir = NULL; + #else + imageName = NULL; + #endif + PROCESS_INFORMATION pi; + BOOL result; + #ifndef _UNICODE + if (!g_IsNT) + { + STARTUPINFOA si; + si.cb = sizeof(si); + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.lpTitle = NULL; + si.dwFlags = 0; + si.cbReserved2 = 0; + si.lpReserved2 = NULL; + + CSysString curDirA; + if (curDir != 0) + curDirA = GetSystemString(curDir); + const AString s = GetSystemString(params2); + result = ::CreateProcessA(NULL, s.Ptr_non_const(), + NULL, NULL, FALSE, 0, NULL, ((curDir != 0) ? (LPCSTR)curDirA: 0), &si, &pi); + } + else + #endif + { + STARTUPINFOW si; + si.cb = sizeof(si); + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.lpTitle = NULL; + si.dwFlags = 0; + si.cbReserved2 = 0; + si.lpReserved2 = NULL; + + result = CreateProcessW(imageName, params2.Ptr_non_const(), + NULL, NULL, FALSE, 0, NULL, curDir, &si, &pi); + } + if (result == 0) + return ::GetLastError(); + ::CloseHandle(pi.hThread); + _handle = pi.hProcess; + return 0; +} + +WRes MyCreateProcess(LPCWSTR imageName, const UString ¶ms) +{ + CProcess process; + return process.Create(imageName, params, NULL); +} + +} diff -Nru p7zip-rar-16.02/CPP/Windows/ProcessUtils.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.h --- p7zip-rar-16.02/CPP/Windows/ProcessUtils.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ProcessUtils.h 2023-03-18 07:00:00.000000000 +0000 @@ -0,0 +1,138 @@ +// Windows/ProcessUtils.h + +#ifndef ZIP7_INC_WINDOWS_PROCESS_UTILS_H +#define ZIP7_INC_WINDOWS_PROCESS_UTILS_H + +#include "../Common/MyWindows.h" + +#ifndef Z7_OLD_WIN_SDK + +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#else // Z7_OLD_WIN_SDK + +typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; +} MODULEINFO, *LPMODULEINFO; + +typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS; +typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + +#endif // Z7_OLD_WIN_SDK + +#include "../Common/MyString.h" + +#include "Defs.h" +#include "Handle.h" + +namespace NWindows { + +class CProcess: public CHandle +{ +public: + bool Open(DWORD desiredAccess, bool inheritHandle, DWORD processId) + { + _handle = ::OpenProcess(desiredAccess, inheritHandle, processId); + return (_handle != NULL); + } + + #ifndef UNDER_CE + + bool GetExitCodeProcess(LPDWORD lpExitCode) { return BOOLToBool(::GetExitCodeProcess(_handle, lpExitCode)); } + bool Terminate(UINT exitCode) { return BOOLToBool(::TerminateProcess(_handle, exitCode)); } + #if (WINVER >= 0x0500) + DWORD GetGuiResources (DWORD uiFlags) { return ::GetGuiResources(_handle, uiFlags); } + #endif + bool SetPriorityClass(DWORD dwPriorityClass) { return BOOLToBool(::SetPriorityClass(_handle, dwPriorityClass)); } + DWORD GetPriorityClass() { return ::GetPriorityClass(_handle); } + // bool GetIoCounters(PIO_COUNTERS lpIoCounters ) { return BOOLToBool(::GetProcessIoCounters(_handle, lpIoCounters )); } + + bool GetTimes(LPFILETIME creationTime, LPFILETIME exitTime, LPFILETIME kernelTime, LPFILETIME userTime) + { return BOOLToBool(::GetProcessTimes(_handle, creationTime, exitTime, kernelTime, userTime)); } + + DWORD WaitForInputIdle(DWORD milliseconds) { return ::WaitForInputIdle(_handle, milliseconds); } + + // Debug + + bool ReadMemory(LPCVOID baseAddress, LPVOID buffer, SIZE_T size, SIZE_T* numberOfBytesRead) + { return BOOLToBool(::ReadProcessMemory(_handle, baseAddress, buffer, size, numberOfBytesRead)); } + + bool WriteMemory(LPVOID baseAddress, LPCVOID buffer, SIZE_T size, SIZE_T* numberOfBytesWritten) + { return BOOLToBool(::WriteProcessMemory(_handle, baseAddress, + #ifdef Z7_OLD_WIN_SDK + (LPVOID) + #endif + buffer, + size, numberOfBytesWritten)); } + + bool FlushInstructionCache(LPCVOID baseAddress = NULL, SIZE_T size = 0) + { return BOOLToBool(::FlushInstructionCache(_handle, baseAddress, size)); } + + LPVOID VirtualAlloc(LPVOID address, SIZE_T size, DWORD allocationType, DWORD protect) + { return VirtualAllocEx(_handle, address, size, allocationType, protect); } + + bool VirtualFree(LPVOID address, SIZE_T size, DWORD freeType) + { return BOOLToBool(::VirtualFreeEx(_handle, address, size, freeType)); } + + // Process Status API (PSAPI) + + /* + bool EmptyWorkingSet() + { return BOOLToBool(::EmptyWorkingSet(_handle)); } + bool EnumModules(HMODULE *hModules, DWORD arraySizeInBytes, LPDWORD receivedBytes) + { return BOOLToBool(::EnumProcessModules(_handle, hModules, arraySizeInBytes, receivedBytes)); } + DWORD MyGetModuleBaseName(HMODULE hModule, LPTSTR baseName, DWORD size) + { return ::GetModuleBaseName(_handle, hModule, baseName, size); } + bool MyGetModuleBaseName(HMODULE hModule, CSysString &name) + { + const unsigned len = MAX_PATH + 100; + const DWORD resultLen = MyGetModuleBaseName(hModule, name.GetBuf(len), len); + name.ReleaseBuf_CalcLen(len); + return (resultLen != 0); + } + + DWORD MyGetModuleFileNameEx(HMODULE hModule, LPTSTR baseName, DWORD size) + { return ::GetModuleFileNameEx(_handle, hModule, baseName, size); } + bool MyGetModuleFileNameEx(HMODULE hModule, CSysString &name) + { + const unsigned len = MAX_PATH + 100; + const DWORD resultLen = MyGetModuleFileNameEx(hModule, name.GetBuf(len), len); + name.ReleaseBuf_CalcLen(len); + return (resultLen != 0); + } + + bool GetModuleInformation(HMODULE hModule, LPMODULEINFO moduleInfo) + { return BOOLToBool(::GetModuleInformation(_handle, hModule, moduleInfo, sizeof(MODULEINFO))); } + bool GetMemoryInfo(PPROCESS_MEMORY_COUNTERS memCounters) + { return BOOLToBool(::GetProcessMemoryInfo(_handle, memCounters, sizeof(PROCESS_MEMORY_COUNTERS))); } + */ + + #endif + + WRes Create(LPCWSTR imageName, const UString ¶ms, LPCWSTR curDir); + + DWORD Wait() { return ::WaitForSingleObject(_handle, INFINITE); } +}; + +WRes MyCreateProcess(LPCWSTR imageName, const UString ¶ms); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/PropVariant.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.cpp --- p7zip-rar-16.02/CPP/Windows/PropVariant.cpp 2015-10-17 14:52:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.cpp 2024-02-26 08:00:00.000000000 +0000 @@ -1,347 +1,393 @@ -// Windows/PropVariant.cpp - -#include "StdAfx.h" - -#include "../Common/Defs.h" - -#include "PropVariant.h" - -namespace NWindows { -namespace NCOM { - -BSTR AllocBstrFromAscii(const char *s) throw() -{ - if (!s) - return NULL; - UINT len = (UINT)strlen(s); - BSTR p = ::SysAllocStringLen(NULL, len); - if (p) - { - for (UINT i = 0; i <= len; i++) - p[i] = (Byte)s[i]; - } - return p; -} - -HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw() -{ - p->bstrVal = ::SysAllocStringLen(NULL, numChars); - if (!p->bstrVal) - { - p->vt = VT_ERROR; - p->scode = E_OUTOFMEMORY; - return E_OUTOFMEMORY; - } - p->vt = VT_BSTR; - return S_OK; -} - -HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw() -{ - p->bstrVal = AllocBstrFromAscii(s); - if (p->bstrVal) - { - p->vt = VT_BSTR; - return S_OK; - } - p->vt = VT_ERROR; - p->scode = E_OUTOFMEMORY; - return E_OUTOFMEMORY; -} - -CPropVariant::CPropVariant(const PROPVARIANT &varSrc) -{ - vt = VT_EMPTY; - InternalCopy(&varSrc); -} - -CPropVariant::CPropVariant(const CPropVariant &varSrc) -{ - vt = VT_EMPTY; - InternalCopy(&varSrc); -} - -CPropVariant::CPropVariant(BSTR bstrSrc) -{ - vt = VT_EMPTY; - *this = bstrSrc; -} - -CPropVariant::CPropVariant(LPCOLESTR lpszSrc) -{ - vt = VT_EMPTY; - *this = lpszSrc; -} - -CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc) -{ - InternalCopy(&varSrc); - return *this; -} - -CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc) -{ - InternalCopy(&varSrc); - return *this; -} - -CPropVariant& CPropVariant::operator=(BSTR bstrSrc) -{ - *this = (LPCOLESTR)bstrSrc; - return *this; -} - -static const char *kMemException = "out of memory"; - -CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) -{ - InternalClear(); - vt = VT_BSTR; - wReserved1 = 0; - bstrVal = ::SysAllocString(lpszSrc); - if (!bstrVal && lpszSrc) - { - throw kMemException; - // vt = VT_ERROR; - // scode = E_OUTOFMEMORY; - } - return *this; -} - -CPropVariant& CPropVariant::operator=(const UString &s) -{ - InternalClear(); - vt = VT_BSTR; - wReserved1 = 0; - bstrVal = ::SysAllocStringLen(s, s.Len()); - if (!bstrVal) - throw kMemException; - return *this; -} - -CPropVariant& CPropVariant::operator=(const UString2 &s) -{ - /* - if (s.IsEmpty()) - *this = L""; - else - */ - { - InternalClear(); - vt = VT_BSTR; - wReserved1 = 0; - bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len()); - if (!bstrVal) - throw kMemException; - /* SysAllocStringLen probably appends a null-terminating character for NULL string. - But it doesn't specified in MSDN. - But we suppose that it works - - if (!s.GetRawPtr()) - { - *bstrVal = 0; - } - */ - - /* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL) - pointers to this function causes an unexpected termination of the application. - Is it safe? Maybe we must chamnge the code for that case ? */ - } - return *this; -} - -CPropVariant& CPropVariant::operator=(const char *s) -{ - InternalClear(); - vt = VT_BSTR; - wReserved1 = 0; - bstrVal = AllocBstrFromAscii(s); - if (!bstrVal) - { - throw kMemException; - // vt = VT_ERROR; - // scode = E_OUTOFMEMORY; - } - return *this; -} - -CPropVariant& CPropVariant::operator=(bool bSrc) throw() -{ - if (vt != VT_BOOL) - { - InternalClear(); - vt = VT_BOOL; - } - boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; - return *this; -} - -BSTR CPropVariant::AllocBstr(unsigned numChars) -{ - if (vt != VT_EMPTY) - InternalClear(); - vt = VT_BSTR; - wReserved1 = 0; - bstrVal = ::SysAllocStringLen(NULL, numChars); - if (!bstrVal) - { - throw kMemException; - // vt = VT_ERROR; - // scode = E_OUTOFMEMORY; - } - return bstrVal; -} - -#define SET_PROP_FUNC(type, id, dest) \ - CPropVariant& CPropVariant::operator=(type value) throw() \ - { if (vt != id) { InternalClear(); vt = id; } \ - dest = value; return *this; } - -SET_PROP_FUNC(Byte, VT_UI1, bVal) -// SET_PROP_FUNC(Int16, VT_I2, iVal) -SET_PROP_FUNC(Int32, VT_I4, lVal) -SET_PROP_FUNC(UInt32, VT_UI4, ulVal) -SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart) -SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart) -SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) - -HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() -{ - switch (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: - prop->vt = VT_EMPTY; - prop->wReserved1 = 0; - prop->wReserved2 = 0; - prop->wReserved3 = 0; - prop->uhVal.QuadPart = 0; - return S_OK; - } - return ::VariantClear((VARIANTARG *)prop); - // return ::PropVariantClear(prop); - // PropVariantClear can clear VT_BLOB. -} - -HRESULT CPropVariant::Clear() throw() -{ - if (vt == VT_EMPTY) - return S_OK; - return PropVariant_Clear(this); -} - -HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() -{ - ::VariantClear((tagVARIANT *)this); - switch (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: - memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); - return S_OK; - } - return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast(pSrc)); -} - - -HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw() -{ - HRESULT hr = Clear(); - if (FAILED(hr)) - return hr; - memcpy(this, pSrc, sizeof(PROPVARIANT)); - pSrc->vt = VT_EMPTY; - return S_OK; -} - -HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw() -{ - if (pDest->vt != VT_EMPTY) - { - HRESULT hr = PropVariant_Clear(pDest); - if (FAILED(hr)) - return hr; - } - memcpy(pDest, this, sizeof(PROPVARIANT)); - vt = VT_EMPTY; - return S_OK; -} - -HRESULT CPropVariant::InternalClear() throw() -{ - if (vt == VT_EMPTY) - return S_OK; - HRESULT hr = Clear(); - if (FAILED(hr)) - { - vt = VT_ERROR; - scode = hr; - } - return hr; -} - -void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) -{ - HRESULT hr = Copy(pSrc); - if (FAILED(hr)) - { - if (hr == E_OUTOFMEMORY) - throw kMemException; - vt = VT_ERROR; - scode = hr; - } -} - -int CPropVariant::Compare(const CPropVariant &a) throw() -{ - if (vt != a.vt) - return MyCompare(vt, a.vt); - switch (vt) - { - case VT_EMPTY: return 0; - // case VT_I1: return MyCompare(cVal, a.cVal); - case VT_UI1: return MyCompare(bVal, a.bVal); - case VT_I2: return MyCompare(iVal, a.iVal); - case VT_UI2: return MyCompare(uiVal, a.uiVal); - case VT_I4: return MyCompare(lVal, a.lVal); - case VT_UI4: return MyCompare(ulVal, a.ulVal); - // case VT_UINT: return MyCompare(uintVal, a.uintVal); - 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_BSTR: return 0; // Not implemented - default: return 0; - } -} - -}} +// Windows/PropVariant.cpp + +#include "StdAfx.h" + +#include "../Common/Defs.h" + +#include "PropVariant.h" + +namespace NWindows { +namespace NCOM { + +BSTR AllocBstrFromAscii(const char *s) throw() +{ + if (!s) + return NULL; + UINT len = (UINT)strlen(s); + BSTR p = ::SysAllocStringLen(NULL, len); + if (p) + { + for (UINT i = 0; i <= len; i++) + p[i] = (Byte)s[i]; + } + return p; +} + +HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw() +{ + p->bstrVal = ::SysAllocStringLen(NULL, numChars); + if (!p->bstrVal) + { + p->vt = VT_ERROR; + p->scode = E_OUTOFMEMORY; + return E_OUTOFMEMORY; + } + p->vt = VT_BSTR; + return S_OK; +} + +HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw() +{ + p->bstrVal = AllocBstrFromAscii(s); + if (p->bstrVal) + { + p->vt = VT_BSTR; + return S_OK; + } + p->vt = VT_ERROR; + p->scode = E_OUTOFMEMORY; + return E_OUTOFMEMORY; +} + +CPropVariant::CPropVariant(const PROPVARIANT &varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(const CPropVariant &varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(BSTR bstrSrc) +{ + vt = VT_EMPTY; + *this = bstrSrc; +} + +CPropVariant::CPropVariant(LPCOLESTR lpszSrc) +{ + vt = VT_EMPTY; + *this = lpszSrc; +} + +CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc) +{ + InternalCopy(&varSrc); + return *this; +} + +CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc) +{ + InternalCopy(&varSrc); + return *this; +} + +CPropVariant& CPropVariant::operator=(BSTR bstrSrc) +{ + *this = (LPCOLESTR)bstrSrc; + return *this; +} + +static const char * const kMemException = "out of memory"; + +CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocString(lpszSrc); + if (!bstrVal && lpszSrc) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + return *this; +} + +CPropVariant& CPropVariant::operator=(const UString &s) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocStringLen(s, s.Len()); + if (!bstrVal) + throw kMemException; + return *this; +} + +CPropVariant& CPropVariant::operator=(const UString2 &s) +{ + /* + if (s.IsEmpty()) + *this = L""; + else + */ + { + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len()); + if (!bstrVal) + throw kMemException; + /* SysAllocStringLen probably appends a null-terminating character for NULL string. + But it doesn't specified in MSDN. + But we suppose that it works + + if (!s.GetRawPtr()) + { + *bstrVal = 0; + } + */ + + /* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL) + pointers to this function causes an unexpected termination of the application. + Is it safe? Maybe we must chamnge the code for that case ? */ + } + return *this; +} + +CPropVariant& CPropVariant::operator=(const char *s) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = AllocBstrFromAscii(s); + if (!bstrVal) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + return *this; +} + +CPropVariant& CPropVariant::operator=(bool bSrc) throw() +{ + if (vt != VT_BOOL) + { + InternalClear(); + vt = VT_BOOL; + } + boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; + return *this; +} + +BSTR CPropVariant::AllocBstr(unsigned numChars) +{ + if (vt != VT_EMPTY) + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocStringLen(NULL, numChars); + if (!bstrVal) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + return bstrVal; +} + +#define SET_PROP_id_dest(id, dest) \ + if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0; + +void CPropVariant::Set_Int32(Int32 value) throw() +{ + SET_PROP_id_dest(VT_I4, lVal) +} + +void CPropVariant::Set_Int64(Int64 value) throw() +{ + SET_PROP_id_dest(VT_I8, hVal.QuadPart) +} + +#define SET_PROP_FUNC(type, id, dest) \ + CPropVariant& CPropVariant::operator=(type value) throw() \ + { SET_PROP_id_dest(id, dest) return *this; } + +SET_PROP_FUNC(Byte, VT_UI1, bVal) +// SET_PROP_FUNC(Int16, VT_I2, iVal) +// SET_PROP_FUNC(Int32, VT_I4, lVal) +SET_PROP_FUNC(UInt32, VT_UI4, ulVal) +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() throw() +{ + switch ((unsigned)vt) + { + CASE_SIMPLE_VT_VALUES + // vt = VT_EMPTY; // it's optional + return; + default: break; + } + ::VariantClear((tagVARIANT *)this); +} + +HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() +{ + switch ((unsigned)prop->vt) + { + CASE_SIMPLE_VT_VALUES + prop->vt = VT_EMPTY; + break; + default: + { + const HRESULT res = ::VariantClear((VARIANTARG *)prop); + if (res != S_OK || prop->vt != VT_EMPTY) + return res; + break; + } + } + 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() +{ + Clear(); + switch ((unsigned)pSrc->vt) + { + CASE_SIMPLE_VT_VALUES + memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); + return S_OK; + default: break; + } + return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast(pSrc)); +} + + +HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw() +{ + 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; +} + +HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw() +{ + if (pDest->vt != VT_EMPTY) + { + 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; + } + const HRESULT hr = Clear(); + if (FAILED(hr)) + { + vt = VT_ERROR; + scode = hr; + } + return hr; +} + +void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) +{ + const HRESULT hr = Copy(pSrc); + if (FAILED(hr)) + { + if (hr == E_OUTOFMEMORY) + throw kMemException; + vt = VT_ERROR; + scode = hr; + } +} + + +int CPropVariant::Compare(const CPropVariant &a) throw() +{ + if (vt != a.vt) + return MyCompare(vt, a.vt); + switch ((unsigned)vt) + { + case VT_EMPTY: return 0; + // case VT_I1: return MyCompare(cVal, a.cVal); + case VT_UI1: return MyCompare(bVal, a.bVal); + case VT_I2: return MyCompare(iVal, a.iVal); + case VT_UI2: return MyCompare(uiVal, a.uiVal); + case VT_I4: return MyCompare(lVal, a.lVal); + case VT_UI4: return MyCompare(ulVal, a.ulVal); + // case VT_UINT: return MyCompare(uintVal, a.uintVal); + 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: + { + 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 -Nru p7zip-rar-16.02/CPP/Windows/PropVariant.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.h --- p7zip-rar-16.02/CPP/Windows/PropVariant.h 2015-10-03 08:49:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariant.h 2023-01-28 16:00:00.000000000 +0000 @@ -1,112 +1,173 @@ -// Windows/PropVariant.h - -#ifndef __WINDOWS_PROP_VARIANT_H -#define __WINDOWS_PROP_VARIANT_H - -#include "../Common/MyTypes.h" -#include "../Common/MyWindows.h" -#include "../Common/MyString.h" - -namespace NWindows { -namespace NCOM { - -BSTR AllocBstrFromAscii(const char *s) throw(); - -HRESULT PropVariant_Clear(PROPVARIANT *p) throw(); - -HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw(); -HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw(); - -inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw() -{ - p->vt = VT_UI4; - p->ulVal = v; -} - -inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw() -{ - p->vt = VT_UI8; - p->uhVal.QuadPart = v; -} - -inline void PropVarEm_Set_FileTime64(PROPVARIANT *p, UInt64 v) throw() -{ - p->vt = VT_FILETIME; - p->filetime.dwLowDateTime = (DWORD)v; - p->filetime.dwHighDateTime = (DWORD)(v >> 32); -} - -inline void PropVarEm_Set_Bool(PROPVARIANT *p, bool b) throw() -{ - p->vt = VT_BOOL; - p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE); -} - - -class CPropVariant : public tagPROPVARIANT -{ -public: - CPropVariant() - { - vt = VT_EMPTY; - wReserved1 = 0; - // wReserved2 = 0; - // wReserved3 = 0; - // uhVal.QuadPart = 0; - bstrVal = 0; - } - ~CPropVariant() throw() { Clear(); } - CPropVariant(const PROPVARIANT &varSrc); - CPropVariant(const CPropVariant &varSrc); - CPropVariant(BSTR bstrSrc); - CPropVariant(LPCOLESTR lpszSrc); - CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); } - CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; } - -private: - CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; } - CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; } - -public: - CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; } - CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; } - CPropVariant(Int64 value) { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; } - CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; } - - CPropVariant& operator=(const CPropVariant &varSrc); - CPropVariant& operator=(const PROPVARIANT &varSrc); - CPropVariant& operator=(BSTR bstrSrc); - CPropVariant& operator=(LPCOLESTR lpszSrc); - CPropVariant& operator=(const UString &s); - CPropVariant& operator=(const UString2 &s); - CPropVariant& operator=(const char *s); - - CPropVariant& operator=(bool bSrc) throw(); - CPropVariant& operator=(Byte value) throw(); - -private: - CPropVariant& operator=(Int16 value) throw(); - -public: - CPropVariant& operator=(Int32 value) throw(); - CPropVariant& operator=(UInt32 value) throw(); - CPropVariant& operator=(UInt64 value) throw(); - CPropVariant& operator=(Int64 value) throw(); - CPropVariant& operator=(const FILETIME &value) throw(); - - BSTR AllocBstr(unsigned numChars); - - HRESULT Clear() throw(); - HRESULT Copy(const PROPVARIANT *pSrc) throw(); - HRESULT Attach(PROPVARIANT *pSrc) throw(); - HRESULT Detach(PROPVARIANT *pDest) throw(); - - HRESULT InternalClear() throw(); - void InternalCopy(const PROPVARIANT *pSrc); - - int Compare(const CPropVariant &a) throw(); -}; - -}} - -#endif +// Windows/PropVariant.h + +#ifndef ZIP7_INC_WINDOWS_PROP_VARIANT_H +#define ZIP7_INC_WINDOWS_PROP_VARIANT_H + +#include "../Common/MyTypes.h" +#include "../Common/MyWindows.h" +#include "../Common/MyString.h" + +namespace NWindows { +namespace NCOM { + +BSTR AllocBstrFromAscii(const char *s) throw(); + +HRESULT PropVariant_Clear(PROPVARIANT *p) throw(); + +HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw(); +HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw(); + +inline void PropVarEm_Set_UInt32(PROPVARIANT *p, UInt32 v) throw() +{ + p->vt = VT_UI4; + p->ulVal = v; +} + +inline void PropVarEm_Set_UInt64(PROPVARIANT *p, UInt64 v) throw() +{ + p->vt = VT_UI8; + p->uhVal.QuadPart = v; +} + +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() +{ + p->vt = VT_BOOL; + p->boolVal = (b ? VARIANT_TRUE : VARIANT_FALSE); +} + + +class CPropVariant : public tagPROPVARIANT +{ + // ---------- forbidden functions ---------- + CPropVariant(const char *s); + // CPropVariant(const UString &s); + #ifdef DEBUG_FSTRING_INHERITS_ASTRING + CPropVariant(const FString &s); + CPropVariant& operator=(const FString &s); + #endif + +public: + CPropVariant() + { + vt = VT_EMPTY; + wReserved1 = 0; + // wReserved2 = 0; + // wReserved3 = 0; + // uhVal.QuadPart = 0; + bstrVal = NULL; + } + + + 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() throw(); + CPropVariant(const PROPVARIANT &varSrc); + CPropVariant(const CPropVariant &varSrc); + CPropVariant(BSTR bstrSrc); + CPropVariant(LPCOLESTR lpszSrc); + CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); } + CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; } + +private: + CPropVariant(UInt16 value); // { vt = VT_UI2; wReserved1 = 0; uiVal = value; } + CPropVariant(Int16 value); // { vt = VT_I2; wReserved1 = 0; iVal = value; } + CPropVariant(Int32 value); // { vt = VT_I4; wReserved1 = 0; lVal = value; } + CPropVariant(Int64 value); // { vt = VT_I8; wReserved1 = 0; hVal.QuadPart = value; } + +public: + CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; } + CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; } + CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; } + + CPropVariant& operator=(const CPropVariant &varSrc); + CPropVariant& operator=(const PROPVARIANT &varSrc); + CPropVariant& operator=(BSTR bstrSrc); + CPropVariant& operator=(LPCOLESTR lpszSrc); + CPropVariant& operator=(const UString &s); + CPropVariant& operator=(const UString2 &s); + CPropVariant& operator=(const char *s); + CPropVariant& operator=(const AString &s) + { return (*this)=(const char *)s; } + + CPropVariant& operator=(bool bSrc) throw(); + CPropVariant& operator=(Byte value) throw(); + +private: + CPropVariant& operator=(Int16 value) throw(); + CPropVariant& operator=(UInt16 value) throw(); + CPropVariant& operator=(Int32 value) throw(); + CPropVariant& operator=(Int64 value) throw(); + +public: + CPropVariant& operator=(UInt32 value) throw(); + CPropVariant& operator=(UInt64 value) throw(); + CPropVariant& operator=(const FILETIME &value) throw(); + + void Set_Int32(Int32 value) throw(); + void Set_Int64(Int64 value) throw(); + + BSTR AllocBstr(unsigned numChars); + + HRESULT Clear() throw(); + HRESULT Copy(const PROPVARIANT *pSrc) throw(); + HRESULT Attach(PROPVARIANT *pSrc) throw(); + HRESULT Detach(PROPVARIANT *pDest) throw(); + + HRESULT InternalClear() throw(); + void InternalCopy(const PROPVARIANT *pSrc); + int Compare(const CPropVariant &a) throw(); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/PropVariantConv.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.cpp --- p7zip-rar-16.02/CPP/Windows/PropVariantConv.cpp 2015-10-03 08:49:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.cpp 2024-03-13 09:00:00.000000000 +0000 @@ -1,109 +1,274 @@ -// PropVariantConvert.cpp - -#include "StdAfx.h" - -#include "../Common/IntToString.h" - -#include "Defs.h" -#include "PropVariantConv.h" - -#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 ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) throw() -{ - SYSTEMTIME st; - if (!BOOLToBool(FileTimeToSystemTime(&ft, &st))) - { - *s = 0; - return false; - } - unsigned val = st.wYear; - if (val >= 10000) - { - *s++ = (char)('0' + val / 10000); - val %= 10000; - } - { - s[3] = (char)('0' + val % 10); val /= 10; - s[2] = (char)('0' + val % 10); val /= 10; - s[1] = (char)('0' + val % 10); - s[0] = (char)('0' + val / 10); - s += 4; - } - UINT_TO_STR_2('-', st.wMonth); - UINT_TO_STR_2('-', st.wDay); - if (includeTime) - { - UINT_TO_STR_2(' ', st.wHour); - UINT_TO_STR_2(':', st.wMinute); - if (includeSeconds) - { - UINT_TO_STR_2(':', st.wSecond); - /* - *s++ = '.'; - unsigned val = st.wMilliseconds; - s[2] = (char)('0' + val % 10); val /= 10; - s[1] = (char)('0' + val % 10); - s[0] = (char)('0' + val / 10); - s += 3; - */ - } - } - *s = 0; - return true; -} - -void ConvertFileTimeToString(const FILETIME &ft, wchar_t *dest, bool includeTime, bool includeSeconds) throw() -{ - char s[32]; - ConvertFileTimeToString(ft, s, includeTime, includeSeconds); - for (unsigned i = 0;; i++) - { - unsigned char c = s[i]; - dest[i] = c; - if (c == 0) - return; - } -} - -void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw() -{ - *dest = 0; - switch (prop.vt) - { - case VT_EMPTY: return; - case VT_BSTR: dest[0] = '?'; dest[1] = 0; return; - case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return; - 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: ConvertFileTimeToString(prop.filetime, dest, true, true); 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; - case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return; - case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return; - default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2); - } -} - -void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw() -{ - *dest = 0; - switch (prop.vt) - { - case VT_EMPTY: return; - case VT_BSTR: dest[0] = '?'; dest[1] = 0; return; - case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return; - 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: ConvertFileTimeToString(prop.filetime, dest, true, true); 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; - case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return; - case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return; - default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2); - } -} +// PropVariantConv.cpp + +#include "StdAfx.h" + +#include "../Common/IntToString.h" + +#include "Defs.h" +#include "PropVariantConv.h" + +#define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; } + +static const unsigned k_TimeStringBufferSize = 64; + +bool g_Timestamp_Show_UTC; +#if 0 +bool g_Timestamp_Show_DisableZ; +bool g_Timestamp_Show_TDelimeter; +bool g_Timestamp_Show_ZoneOffset; +#endif + +Z7_NO_INLINE +bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level, unsigned flags) throw() +{ + *s = 0; + FILETIME ft; + +#if 0 + Int64 bias64 = 0; +#endif + + const bool show_utc = + (flags & kTimestampPrintFlags_Force_UTC) ? true : + (flags & kTimestampPrintFlags_Force_LOCAL) ? false : + g_Timestamp_Show_UTC; + + if (show_utc) + ft = utc; + else + { + if (!FileTimeToLocalFileTime(&utc, &ft)) + return false; +#if 0 + if (g_Timestamp_Show_ZoneOffset) + { + const UInt64 utc64 = (((UInt64)utc.dwHighDateTime) << 32) + utc.dwLowDateTime; + const UInt64 loc64 = (((UInt64) ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + bias64 = (Int64)utc64 - (Int64)loc64; + } +#endif + } + + 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; + if (val >= 10000) + { + *s++ = (char)('0' + val / 10000); + val %= 10000; + } + s[3] = (char)('0' + val % 10); val /= 10; + s[2] = (char)('0' + val % 10); val /= 10; + s[1] = (char)('0' + val % 10); + s[0] = (char)('0' + val / 10); + s += 4; + } + UINT_TO_STR_2('-', st.wMonth) + UINT_TO_STR_2('-', st.wDay) + + if (level > kTimestampPrintLevel_DAY) + { + const char setChar = +#if 0 + g_Timestamp_Show_TDelimeter ? 'T' : // ISO 8601 +#endif + ' '; + UINT_TO_STR_2(setChar, st.wHour) + UINT_TO_STR_2(':', st.wMinute) + + if (level >= kTimestampPrintLevel_SEC) + { + UINT_TO_STR_2(':', st.wSecond) + + if (level > kTimestampPrintLevel_SEC) + { + *s++ = '.'; + /* + { + unsigned val = st.wMilliseconds; + s[2] = (char)('0' + val % 10); val /= 10; + s[1] = (char)('0' + val % 10); + s[0] = (char)('0' + val / 10); + s += 3; + } + *s++ = ' '; + */ + + { + unsigned numDigits = 7; + UInt32 val = (UInt32)((((UInt64)ft.dwHighDateTime << 32) + ft.dwLowDateTime) % 10000000); + for (unsigned i = numDigits; i != 0;) + { + i--; + s[i] = (char)('0' + val % 10); val /= 10; + } + if (numDigits > (unsigned)level) + 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)); + } + } + } + } + + if (show_utc) + { + if ((flags & kTimestampPrintFlags_DisableZ) == 0 +#if 0 + && !g_Timestamp_Show_DisableZ +#endif + ) + *s++ = 'Z'; + } +#if 0 + else if (g_Timestamp_Show_ZoneOffset) + { +#if 1 + { + char c; + if (bias64 < 0) + { + bias64 = -bias64; + c = '+'; + } + else + c = '-'; + UInt32 bias = (UInt32)((UInt64)bias64 / (10000000 * 60)); +#else + TIME_ZONE_INFORMATION zi; + const DWORD dw = GetTimeZoneInformation(&zi); + if (dw <= TIME_ZONE_ID_DAYLIGHT) // == 2 + { + // UTC = LOCAL + Bias + Int32 bias = zi.Bias; + char c; + if (bias < 0) + { + bias = -bias; + c = '+'; + } + else + c = '-'; +#endif + const UInt32 hours = (UInt32)bias / 60; + const UInt32 mins = (UInt32)bias % 60; + UINT_TO_STR_2(c, hours) + UINT_TO_STR_2(':', mins) + } + } +#endif + *s = 0; + return true; +} + + +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[k_TimeStringBufferSize]; + const bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level); + for (unsigned i = 0;; i++) + { + const 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[k_TimeStringBufferSize]; + const bool res = ConvertUtcFileTimeToString(ft, s, level); + for (unsigned i = 0;; i++) + { + const Byte c = (Byte)s[i]; + dest[i] = c; + if (c == 0) + break; + } + return res; +} + + +void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw() +{ + *dest = 0; + switch (prop.vt) + { + case VT_EMPTY: return; + case VT_BSTR: dest[0] = '?'; dest[1] = 0; return; + case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return; + 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: + { + // 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; + case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return; + case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return; + default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2); + } +} + +void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw() +{ + *dest = 0; + switch (prop.vt) + { + case VT_EMPTY: return; + case VT_BSTR: dest[0] = '?'; dest[1] = 0; return; + case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return; + 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: + { + // 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; + case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return; + case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return; + default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2); + } +} diff -Nru p7zip-rar-16.02/CPP/Windows/PropVariantConv.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.h --- p7zip-rar-16.02/CPP/Windows/PropVariantConv.h 2015-01-05 18:38:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantConv.h 2024-03-13 09:00:00.000000000 +0000 @@ -1,30 +1,47 @@ -// Windows/PropVariantConv.h - -#ifndef __PROP_VARIANT_CONV_H -#define __PROP_VARIANT_CONV_H - -#include "../Common/MyTypes.h" - -// provide at least 32 bytes for buffer including zero-end -bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true) throw(); -void ConvertFileTimeToString(const FILETIME &ft, wchar_t *s, bool includeTime = true, bool includeSeconds = true) throw(); - -// provide at least 32 bytes for buffer including zero-end -// don't send VT_BSTR to these functions -void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw(); -void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw(); - -inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value) -{ - switch (prop.vt) - { - case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true; - case VT_UI4: value = prop.ulVal; return true; - case VT_UI2: value = prop.uiVal; return true; - case VT_UI1: value = prop.bVal; return true; - case VT_EMPTY: return false; - default: throw 151199; - } -} - -#endif +// Windows/PropVariantConv.h + +#ifndef ZIP7_INC_PROP_VARIANT_CONV_H +#define ZIP7_INC_PROP_VARIANT_CONV_H + +#include "../Common/MyTypes.h" + +// provide at least 32 bytes for buffer including zero-end + +extern bool g_Timestamp_Show_UTC; + +#define kTimestampPrintLevel_DAY -3 +// #define kTimestampPrintLevel_HOUR -2 +#define kTimestampPrintLevel_MIN -1 +#define kTimestampPrintLevel_SEC 0 +#define kTimestampPrintLevel_NTFS 7 +#define kTimestampPrintLevel_NS 9 + + +#define kTimestampPrintFlags_Force_UTC (1 << 0) +#define kTimestampPrintFlags_Force_LOCAL (1 << 1) +#define kTimestampPrintFlags_DisableZ (1 << 4) + +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, unsigned flags = 0) 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 +void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw(); +void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw(); + +inline bool ConvertPropVariantToUInt64(const PROPVARIANT &prop, UInt64 &value) +{ + switch (prop.vt) + { + case VT_UI8: value = (UInt64)prop.uhVal.QuadPart; return true; + case VT_UI4: value = prop.ulVal; return true; + case VT_UI2: value = prop.uiVal; return true; + case VT_UI1: value = prop.bVal; return true; + case VT_EMPTY: return false; + default: throw 151199; + } +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/PropVariantUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.cpp --- p7zip-rar-16.02/CPP/Windows/PropVariantUtils.cpp 2015-09-17 19:02:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.cpp 2021-01-22 19:45:27.000000000 +0000 @@ -1,149 +1,161 @@ -// PropVariantUtils.cpp - -#include "StdAfx.h" - -#include "../Common/IntToString.h" - -#include "PropVariantUtils.h" - -using namespace NWindows; - -static AString GetHex(UInt32 v) -{ - char sz[16]; - sz[0] = '0'; - sz[1] = 'x'; - ConvertUInt32ToHex(v, sz + 2); - return sz; -} - -AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value) -{ - AString s; - for (unsigned i = 0; i < num; i++) - { - const CUInt32PCharPair &p = pairs[i]; - if (p.Value == value) - s = p.Name; - } - if (s.IsEmpty()) - s = GetHex(value); - return s; -} - -void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop) -{ - prop = TypePairToString(pairs, num, value); -} - - -AString TypeToString(const char * const table[], unsigned num, UInt32 value) -{ - if (value < num) - return table[value]; - return GetHex(value); -} - -void TypeToProp(const char * const table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop) -{ - prop = TypeToString(table, num, value); -} - - -AString FlagsToString(const char * const *names, unsigned num, UInt32 flags) -{ - AString s; - for (unsigned i = 0; i < num; i++) - { - UInt32 flag = (UInt32)1 << i; - if ((flags & flag) != 0) - { - const char *name = names[i]; - if (name != 0 && name[0] != 0) - { - if (!s.IsEmpty()) - s += ' '; - s += name; - flags &= ~flag; - } - } - } - if (flags != 0) - { - if (!s.IsEmpty()) - s += ' '; - s += GetHex(flags); - } - return s; -} - -AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags) -{ - AString s; - for (unsigned i = 0; i < num; i++) - { - const CUInt32PCharPair &p = pairs[i]; - UInt32 flag = (UInt32)1 << (unsigned)p.Value; - if ((flags & flag) != 0) - { - if (p.Name[0] != 0) - { - if (!s.IsEmpty()) - s += ' '; - s += p.Name; - } - } - flags &= ~flag; - } - if (flags != 0) - { - if (!s.IsEmpty()) - s += ' '; - s += GetHex(flags); - } - return s; -} - -void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop) -{ - prop = FlagsToString(pairs, num, flags); -} - - -AString Flags64ToString(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags) -{ - AString s; - for (unsigned i = 0; i < num; i++) - { - const CUInt32PCharPair &p = pairs[i]; - UInt64 flag = (UInt64)1 << (unsigned)p.Value; - if ((flags & flag) != 0) - { - if (p.Name[0] != 0) - { - if (!s.IsEmpty()) - s += ' '; - s += p.Name; - } - } - flags &= ~flag; - } - if (flags != 0) - { - if (!s.IsEmpty()) - s += ' '; - { - char sz[32]; - sz[0] = '0'; - sz[1] = 'x'; - ConvertUInt64ToHex(flags, sz + 2); - s += sz; - } - } - return s; -} - -void Flags64ToProp(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags, NCOM::CPropVariant &prop) -{ - prop = Flags64ToString(pairs, num, flags); -} +// PropVariantUtils.cpp + +#include "StdAfx.h" + +#include "../Common/IntToString.h" + +#include "PropVariantUtils.h" + +using namespace NWindows; + +static void AddHex(AString &s, UInt32 v) +{ + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(v, sz + 2); + s += sz; +} + + +AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value) +{ + char sz[16]; + const char *p = NULL; + for (unsigned i = 0; i < num; i++) + { + const CUInt32PCharPair &pair = pairs[i]; + if (pair.Value == value) + p = pair.Name; + } + if (!p) + { + ConvertUInt32ToString(value, sz); + p = sz; + } + return (AString)p; +} + +void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop) +{ + prop = TypePairToString(pairs, num, value); +} + + +AString TypeToString(const char * const table[], unsigned num, UInt32 value) +{ + char sz[16]; + const char *p = NULL; + if (value < num) + p = table[value]; + if (!p) + { + ConvertUInt32ToString(value, sz); + p = sz; + } + return (AString)p; +} + +void TypeToProp(const char * const table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop) +{ + char sz[16]; + const char *p = NULL; + if (value < num) + p = table[value]; + if (!p) + { + ConvertUInt32ToString(value, sz); + p = sz; + } + prop = p; +} + + +AString FlagsToString(const char * const *names, unsigned num, UInt32 flags) +{ + AString s; + for (unsigned i = 0; i < num; i++) + { + UInt32 flag = (UInt32)1 << i; + if ((flags & flag) != 0) + { + const char *name = names[i]; + if (name && name[0] != 0) + { + s.Add_OptSpaced(name); + flags &= ~flag; + } + } + } + if (flags != 0) + { + s.Add_Space_if_NotEmpty(); + AddHex(s, flags); + } + return s; +} + +AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags) +{ + AString s; + for (unsigned i = 0; i < num; i++) + { + const CUInt32PCharPair &p = pairs[i]; + UInt32 flag = (UInt32)1 << (unsigned)p.Value; + if ((flags & flag) != 0) + { + if (p.Name[0] != 0) + s.Add_OptSpaced(p.Name); + } + flags &= ~flag; + } + if (flags != 0) + { + s.Add_Space_if_NotEmpty(); + AddHex(s, flags); + } + return s; +} + +void FlagsToProp(const char * const *names, unsigned num, UInt32 flags, NCOM::CPropVariant &prop) +{ + prop = FlagsToString(names, num, flags); +} + +void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop) +{ + prop = FlagsToString(pairs, num, flags); +} + + +static AString Flags64ToString(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags) +{ + AString s; + for (unsigned i = 0; i < num; i++) + { + const CUInt32PCharPair &p = pairs[i]; + UInt64 flag = (UInt64)1 << (unsigned)p.Value; + if ((flags & flag) != 0) + { + if (p.Name[0] != 0) + s.Add_OptSpaced(p.Name); + } + flags &= ~flag; + } + if (flags != 0) + { + { + char sz[32]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt64ToHex(flags, sz + 2); + s.Add_OptSpaced(sz); + } + } + return s; +} + +void Flags64ToProp(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags, NCOM::CPropVariant &prop) +{ + prop = Flags64ToString(pairs, num, flags); +} diff -Nru p7zip-rar-16.02/CPP/Windows/PropVariantUtils.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.h --- p7zip-rar-16.02/CPP/Windows/PropVariantUtils.h 2015-09-17 19:02:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/PropVariantUtils.h 2023-03-06 16:00:00.000000000 +0000 @@ -1,33 +1,34 @@ -// Windows/PropVariantUtils.h - -#ifndef __PROP_VARIANT_UTILS_H -#define __PROP_VARIANT_UTILS_H - -#include "../Common/MyString.h" - -#include "PropVariant.h" - -struct CUInt32PCharPair -{ - UInt32 Value; - const char *Name; -}; - -AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value); -void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); - -AString FlagsToString(const char * const *names, unsigned num, UInt32 flags); -AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags); -void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop); - -AString TypeToString(const char * const table[], unsigned num, UInt32 value); -void TypeToProp(const char * const table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); - -#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, ARRAY_SIZE(pairs), value, prop) -#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, ARRAY_SIZE(pairs), value, prop) -#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, ARRAY_SIZE(table), value, prop) - -void Flags64ToProp(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags, NWindows::NCOM::CPropVariant &prop); -#define FLAGS64_TO_PROP(pairs, value, prop) Flags64ToProp(pairs, ARRAY_SIZE(pairs), value, prop) - -#endif +// Windows/PropVariantUtils.h + +#ifndef ZIP7_INC_PROP_VARIANT_UTILS_H +#define ZIP7_INC_PROP_VARIANT_UTILS_H + +#include "../Common/MyString.h" + +#include "PropVariant.h" + +struct CUInt32PCharPair +{ + UInt32 Value; + const char *Name; +}; + +AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value); +void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); + +AString FlagsToString(const char * const *names, unsigned num, UInt32 flags); +AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags); +void FlagsToProp(const char * const *names, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop); +void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop); + +AString TypeToString(const char * const table[], unsigned num, UInt32 value); +void TypeToProp(const char * const table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); + +#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, Z7_ARRAY_SIZE(pairs), value, prop) +#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, Z7_ARRAY_SIZE(pairs), value, prop) +#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, Z7_ARRAY_SIZE(table), value, prop) + +void Flags64ToProp(const CUInt32PCharPair *pairs, unsigned num, UInt64 flags, NWindows::NCOM::CPropVariant &prop); +#define FLAGS64_TO_PROP(pairs, value, prop) Flags64ToProp(pairs, Z7_ARRAY_SIZE(pairs), value, prop) + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Registry.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.cpp --- p7zip-rar-16.02/CPP/Windows/Registry.cpp 2015-01-05 21:12:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.cpp 2024-11-13 11:00:00.000000000 +0000 @@ -1,313 +1,474 @@ -// Windows/Registry.cpp - -#include "StdAfx.h" - -#ifndef _UNICODE -#include "Common/StringConvert.h" -#endif -#include "Windows/Registry.h" - -#include - -class HKEY_Impl -{ - public: - wxString path; - HKEY_Impl(wxString a) : path(a) {} -}; - -namespace NWindows { -namespace NRegistry { - -#define ERROR_SET_VALUE (E_INVALIDARG) // FIXME -#define ERROR_GET_VALUE (E_INVALIDARG) // FIXME -#define PROGRAM_NAME L"p7zip" - -static wxConfig * g_config = 0; -static int g_config_ref = 0; - -static void configAddRef() { - if (g_config == 0) { - g_config = new wxConfig(PROGRAM_NAME); - g_config->Flush(true); - wxConfigBase::Set(g_config); - } - g_config_ref++; -} - -static void configSubRef() { - if (g_config_ref >= 1) - { - g_config_ref--; - if (g_config_ref == 0) { - delete g_config; - g_config = 0; - wxConfigBase::Set(NULL); - } else { - g_config->Flush(true); - } - } -} - -LONG CKey::Close() throw() -{ - if (_object) - { - configSubRef(); - delete _object; - } - _object = 0; - return ERROR_SUCCESS; -} - -LONG CKey::Create(HKEY parentKey, LPCTSTR keyName) throw() -{ - Close(); - - configAddRef(); - - wxString path; - - if (parentKey == HKEY_CURRENT_USER) { - path=L"/" + wxString(keyName); - } else { - path = parentKey->path + L"/" + wxString(keyName); - } - _object = new HKEY_Impl(path); - return ERROR_SUCCESS; -} -LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw() -{ - Close(); - - configAddRef(); - - wxString path; - - if (parentKey == HKEY_CURRENT_USER) { - path=L"/" + wxString(keyName); - } else { - path = parentKey->path + L"/" + wxString(keyName); - } - _object = new HKEY_Impl(path); - return ERROR_SUCCESS; -} - -LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->DeleteGroup(subKeyName); - if (ret) return ERROR_SUCCESS; - return ERROR_GET_VALUE; -} - -LONG CKey::DeleteValue(LPCTSTR name) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->DeleteEntry(name); - if (ret) return ERROR_SUCCESS; - return ERROR_GET_VALUE; -} - -LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw() -{ - g_config->SetPath(_object->path); - long val; - bool ret = g_config->Read(name,&val); - if (ret) { - value = (UInt32)val; - return ERROR_SUCCESS; - } - return ERROR_GET_VALUE; -} - -LONG CKey::QueryValue(LPCTSTR name, bool &value) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->Read(name,&value); - if (ret) return ERROR_SUCCESS; - return ERROR_GET_VALUE; -} - -LONG CKey::QueryValue(LPCTSTR name, CSysString &value) -{ - g_config->SetPath(_object->path); - wxString val; - bool ret = g_config->Read(name,&val); - if (ret) { - value = val; - return ERROR_SUCCESS; - } - return ERROR_GET_VALUE; -} - -LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw() -{ - UInt32 newVal; - LONG res = QueryValue(name, newVal); - if (res == ERROR_SUCCESS) - value = newVal; - return res; -} - -LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw() -{ - bool newVal; - LONG res = QueryValue(name, newVal); - if (res == ERROR_SUCCESS) - value = newVal; - return res; -} - -LONG CKey::SetValue(LPCTSTR valueName, UInt32 value) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->Write(valueName,(long)value); - if (ret == true) return ERROR_SUCCESS; - return ERROR_SET_VALUE; -} - -LONG CKey::SetValue(LPCTSTR valueName, bool value) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->Write(valueName,value); - if (ret == true) return ERROR_SUCCESS; - return ERROR_SET_VALUE; -} - -LONG CKey::SetValue(LPCTSTR valueName, LPCTSTR value) throw() -{ - g_config->SetPath(_object->path); - bool ret = g_config->Write(valueName,value); - if (ret == true) return ERROR_SUCCESS; - return ERROR_SET_VALUE; -} - -LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw() -{ - static char hexa[] = "0123456789ABCDEF"; - /* FIXME - MYASSERT(value != NULL); - MYASSERT(_object != NULL); - return RegSetValueEx(_object, name, NULL, REG_BINARY, (const BYTE *)value, size); - */ - BYTE *buf = (BYTE *)value; - wxString str; - for(UInt32 i=0;i>4) & 0x0f]; - str += hexa[ buf[i] & 0x0f]; - } - return SetValue(name,(LPCTSTR)str); -} - -LONG CKey::EnumKeys(CSysStringVector &keyNames) -{ - g_config->SetPath(_object->path); - keyNames.Clear(); - // enumeration variables - wxString str; - long dummy; - bool bCont = g_config->GetFirstEntry(str, dummy); - while ( bCont ) { - keyNames.Add((const TCHAR *)str); - bCont = g_config->GetNextEntry(str, dummy); - } - - // now all groups... - bCont = g_config->GetFirstGroup(str, dummy); - while ( bCont ) { - keyNames.Add((const TCHAR *)str); - bCont = g_config->GetNextGroup(str, dummy); - } - return ERROR_SUCCESS; -} - -LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) throw() -{ - g_config->SetPath(_object->path); - wxString str; - bool ret = g_config->Read(name,&str); - if (ret == false) return ERROR_GET_VALUE; - - size_t l = str.Len() / 2; - if (l > dataSize) l = dataSize; - else dataSize=l; - - BYTE *buf = (BYTE *)value; - for(UInt32 i=0;iSetPath(_object->path); - wxString str; - bool ret = g_config->Read(name,&str); - if (ret == false) return ERROR_GET_VALUE; - - dataSize = str.Len() / 2; - value.Alloc(dataSize); - return QueryValue(name, (BYTE *)value, dataSize); -} - - -LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) throw() -{ - UInt32 numChars = 0; - int i; - for (i = 0; i < strings.Size(); i++) - numChars += strings[i].Len() + 1; - CBuffer buffer(numChars); - int pos = 0; - for (i = 0; i < strings.Size(); i++) - { - const UString &s = strings[i]; - MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s); - pos += s.Len() + 1; - } - return SetValue(valueName, buffer, numChars * sizeof(wchar_t)); -} - -LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings) -{ - strings.Clear(); - CByteBuffer buffer; - UInt32 dataSize; - LONG res = QueryValue(valueName, buffer, dataSize); - if (res != ERROR_SUCCESS) - return res; - if (dataSize % sizeof(wchar_t) != 0) - return E_FAIL; - const wchar_t *data = (const wchar_t *)(const Byte *)buffer; - int numChars = dataSize / sizeof(wchar_t); - UString s; - for (int i = 0; i < numChars; i++) - { - wchar_t c = data[i]; - if (c == 0) - { - strings.Add(s); - s.Empty(); - } - else - s += c; - } - return res; -} - - -} -} - +// Windows/Registry.cpp + +#include "StdAfx.h" + +#include +// #include + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif +#include "Registry.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { +namespace NRegistry { + +#define MYASSERT(expr) // _ASSERTE(expr) +#define MY_ASSUME(expr) + +/* +static void Error() +{ + #ifdef _CONSOLE + printf("\nregistry error\n"); + #else + MessageBoxW(0, L"registry error", L"", 0); + // exit(1); + #endif +} + +#define MY_ASSUME(expr) { if (!(expr)) Error(); } +*/ + +LONG CKey::Create(HKEY parentKey, LPCTSTR keyName, + LPTSTR keyClass, DWORD options, REGSAM accessMask, + LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition) throw() +{ + MY_ASSUME(parentKey != NULL); + DWORD dispositionReal; + HKEY key = NULL; + LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass, + options, accessMask, securityAttributes, &key, &dispositionReal); + if (disposition != NULL) + *disposition = dispositionReal; + if (res == ERROR_SUCCESS) + { + res = Close(); + _object = key; + } + return res; +} + +LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw() +{ + MY_ASSUME(parentKey != NULL); + HKEY key = NULL; + LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key); + if (res == ERROR_SUCCESS) + { + res = Close(); + MYASSERT(res == ERROR_SUCCESS); + _object = key; + } + return res; +} + +LONG CKey::Close() throw() +{ + LONG res = ERROR_SUCCESS; + if (_object != NULL) + { + res = RegCloseKey(_object); + _object = NULL; + } + return res; +} + +// win95, win98: deletes subkey and all its subkeys +// winNT to be deleted must not have subkeys +LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw() +{ + MY_ASSUME(_object != NULL); + return RegDeleteKey(_object, subKeyName); +} + +LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw() +{ + { + CKey key; + LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE); + if (res != ERROR_SUCCESS) + return res; + FILETIME fileTime; + const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL + TCHAR buffer[kBufSize]; + // we use loop limit here for some unexpected code failure + for (unsigned loop_cnt = 0; loop_cnt < (1u << 26); loop_cnt++) + { + DWORD size = kBufSize; + // we always request starting item (index==0) in each iteration, + // because we remove starting item (index==0) in each loop iteration. + res = RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime); + if (res != ERROR_SUCCESS) + { + // possible return codes: + // ERROR_NO_MORE_ITEMS : are no more subkeys available + // ERROR_MORE_DATA : name buffer is too small + // we can try to remove (subKeyName), even if there is non ERROR_NO_MORE_ITEMS error. + // if (res != ERROR_NO_MORE_ITEMS) return res; + break; + } + res = key.RecurseDeleteKey(buffer); + if (res != ERROR_SUCCESS) + return res; + } + // key.Close(); + } + return DeleteSubKey(subKeyName); +} + + +///////////////////////// +// Value Functions + +static inline UInt32 BoolToUINT32(bool value) { return (value ? 1: 0); } +static inline bool UINT32ToBool(UInt32 value) { return (value != 0); } + + +LONG CKey::DeleteValue(LPCTSTR name) throw() +{ + MY_ASSUME(_object != NULL); + return ::RegDeleteValue(_object, name); +} + +#ifndef _UNICODE +LONG CKey::DeleteValue(LPCWSTR name) +{ + MY_ASSUME(_object != NULL); + if (g_IsNT) + return ::RegDeleteValueW(_object, name); + return DeleteValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name)); +} +#endif + +LONG CKey::SetValue(LPCTSTR name, UInt32 value) throw() +{ + MY_ASSUME(_object != NULL); + return RegSetValueEx(_object, name, 0, REG_DWORD, + (const BYTE *)&value, sizeof(UInt32)); +} + +LONG CKey::SetValue(LPCTSTR name, bool value) throw() +{ + return SetValue(name, BoolToUINT32(value)); +} + + +// value must be string that is NULL terminated +LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw() +{ + MYASSERT(value != NULL); + MY_ASSUME(_object != NULL); + // note: RegSetValueEx supports (value == NULL), if (cbData == 0) + return RegSetValueEx(_object, name, 0, REG_SZ, + (const BYTE *)value, (DWORD)(((DWORD)lstrlen(value) + 1) * sizeof(TCHAR))); +} + +/* +LONG CKey::SetValue(LPCTSTR name, const CSysString &value) +{ + MYASSERT(value != NULL); + MY_ASSUME(_object != NULL); + return RegSetValueEx(_object, name, 0, REG_SZ, + (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR)); +} +*/ + +#ifndef _UNICODE + +LONG CKey::SetValue(LPCWSTR name, LPCWSTR value) +{ + MYASSERT(value != NULL); + MY_ASSUME(_object != NULL); + if (g_IsNT) + return RegSetValueExW(_object, name, 0, REG_SZ, + (const BYTE *)value, (DWORD)(((DWORD)wcslen(value) + 1) * sizeof(wchar_t))); + return SetValue(name == NULL ? NULL : + (LPCSTR)GetSystemString(name), + (LPCSTR)GetSystemString(value)); +} + +#endif + + +LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw() +{ + MYASSERT(value != NULL); + MY_ASSUME(_object != NULL); + return RegSetValueEx(_object, name, 0, REG_BINARY, + (const BYTE *)value, size); +} + +LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) +{ + MYASSERT(value != NULL); + CKey key; + LONG res = key.Create(parentKey, keyName); + if (res == ERROR_SUCCESS) + res = key.SetValue(valueName, value); + return res; +} + +LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw() +{ + MYASSERT(value != NULL); + CKey key; + LONG res = key.Create(_object, keyName); + if (res == ERROR_SUCCESS) + res = key.SetValue(valueName, value); + return res; +} + + +LONG CKey::GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw() +{ + DWORD type = 0; + DWORD count = sizeof(value); + UInt32 value2; // = value; + const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count); + if (res == ERROR_SUCCESS) + { + // ERROR_UNSUPPORTED_TYPE + if (count != sizeof(value) || type != REG_DWORD) + return ERROR_UNSUPPORTED_TYPE; // ERROR_INVALID_DATA; + value = value2; + } + return res; +} + +LONG CKey::GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw() +{ + DWORD type = 0; + DWORD count = sizeof(value); + UInt64 value2; // = value; + const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count); + if (res == ERROR_SUCCESS) + { + if (count != sizeof(value) || type != REG_QWORD) + return ERROR_UNSUPPORTED_TYPE; + value = value2; + } + return res; +} + +LONG CKey::GetValue_bool_IfOk(LPCTSTR name, bool &value) throw() +{ + UInt32 uintValue; + const LONG res = GetValue_UInt32_IfOk(name, uintValue); + if (res == ERROR_SUCCESS) + value = UINT32ToBool(uintValue); + return res; +} + + + +LONG CKey::QueryValue(LPCTSTR name, CSysString &value) +{ + value.Empty(); + LONG res = ERROR_SUCCESS; + { + // if we don't want multiple calls here, + // we can use big value (264) here. + // 3 is default available length in new string. + DWORD size_prev = 3 * sizeof(TCHAR); + // at least 2 attempts are required. But we use more attempts for cases, + // where string can be changed by anothner process + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + { + LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(TCHAR)); + res = QueryValueEx(name, &type, size == 0 ? NULL : buf, &size); + // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size. + } + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_SZ && type != REG_EXPAND_SZ) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + value.ReleaseBuf_CalcLen(size / sizeof(TCHAR)); + if (res != ERROR_MORE_DATA) + return res; + } + } + return res; +} + + +#ifndef _UNICODE + +LONG CKey::QueryValue(LPCWSTR name, UString &value) +{ + value.Empty(); + LONG res = ERROR_SUCCESS; + if (g_IsNT) + { + DWORD size_prev = 3 * sizeof(wchar_t); + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + { + LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(wchar_t)); + res = RegQueryValueExW(_object, name, NULL, &type, + size == 0 ? NULL : buf, &size); + } + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_SZ && type != REG_EXPAND_SZ) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + value.ReleaseBuf_CalcLen(size / sizeof(wchar_t)); + if (res != ERROR_MORE_DATA) + return res; + } + } + else + { + AString vTemp; + res = QueryValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name), vTemp); + value = GetUnicodeString(vTemp); + } + return res; +} + +#endif + + +LONG CKey::QueryValue_Binary(LPCTSTR name, CByteBuffer &value) +{ + // value.Free(); + DWORD size_prev = 0; + LONG res = ERROR_SUCCESS; + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + value.Alloc(size_prev); + res = QueryValueEx(name, &type, value.NonConstData(), &size); + // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size. + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_BINARY) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + if (size < value.Size()) + value.ChangeSize_KeepData(size, size); + if (res != ERROR_MORE_DATA) + return res; + } + return res; +} + + +LONG CKey::EnumKeys(CSysStringVector &keyNames) +{ + keyNames.Clear(); + CSysString keyName; + for (DWORD index = 0; ; index++) + { + const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL + FILETIME lastWriteTime; + DWORD nameSize = kBufSize; + const LONG res = ::RegEnumKeyEx(_object, index, + keyName.GetBuf(kBufSize), &nameSize, + NULL, NULL, NULL, &lastWriteTime); + keyName.ReleaseBuf_CalcLen(kBufSize); + if (res == ERROR_NO_MORE_ITEMS) + return ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + return res; + keyNames.Add(keyName); + } +} + + +LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) +{ + size_t numChars = 0; + unsigned i; + + for (i = 0; i < strings.Size(); i++) + numChars += strings[i].Len() + 1; + + CObjArray buffer(numChars); + size_t pos = 0; + + for (i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + const size_t size = s.Len() + 1; + wmemcpy(buffer + pos, s, size); + pos += size; + } + // if (pos != numChars) return E_FAIL; + return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t)); +} + +LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings) +{ + strings.Clear(); + CByteBuffer buffer; + const LONG res = QueryValue_Binary(valueName, buffer); + if (res != ERROR_SUCCESS) + return res; + const size_t dataSize = buffer.Size(); + if (dataSize % sizeof(wchar_t)) + return ERROR_INVALID_DATA; + const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer; + const size_t numChars = dataSize / sizeof(wchar_t); + // we can check that all names are finished + // if (numChars != 0 && data[numChars - 1] != 0) return ERROR_INVALID_DATA; + size_t prev = 0; + UString s; + for (size_t i = 0; i < numChars; i++) + { + if (data[i] == 0) + { + s = data + prev; + strings.Add(s); + prev = i + 1; + } + } + return res; +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Registry.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.h --- p7zip-rar-16.02/CPP/Windows/Registry.h 2015-01-05 20:49:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Registry.h 2024-11-08 11:00:00.000000000 +0000 @@ -1,102 +1,96 @@ -// Windows/Registry.h - -#ifndef __WINDOWS_REGISTRY_H -#define __WINDOWS_REGISTRY_H - -#include "../Common/MyBuffer.h" -#include "../Common/MyString.h" -#include "../Common/MyTypes.h" - -#ifndef _WIN32 -class HKEY_Impl; - -typedef HKEY_Impl * HKEY; - -#define HKEY_CURRENT_USER ((HKEY) 0x80000001) - -typedef DWORD REGSAM; -#define ERROR_SUCCESS (0) -#define KEY_READ (0x1234) // FIXME -#define KEY_ALL_ACCESS (~0) // FIXME - -#endif - -namespace NWindows { -namespace NRegistry { - -LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value); - -class CKey -{ - HKEY _object; -public: - CKey(): _object(NULL) {} - ~CKey() { Close(); } - - operator HKEY() const { return _object; } -#if 0 - void Attach(HKEY key) { _object = key; } - HKEY Detach() - { - HKEY key = _object; - _object = NULL; - return key; - } - - LONG Create(HKEY parentKey, LPCTSTR keyName, - LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE, - REGSAM accessMask = KEY_ALL_ACCESS, - LPSECURITY_ATTRIBUTES securityAttributes = NULL, - LPDWORD disposition = NULL); -#endif // #if 0 - LONG Create(HKEY parentKey, LPCTSTR keyName) throw(); - LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS) throw(); - - LONG Close() throw(); - - LONG DeleteSubKey(LPCTSTR subKeyName) throw(); - LONG RecurseDeleteKey(LPCTSTR subKeyName) throw(); - - LONG DeleteValue(LPCTSTR name) throw(); - #ifndef _UNICODE - LONG DeleteValue(LPCWSTR name); - #endif - - LONG SetValue(LPCTSTR valueName, UInt32 value) throw(); - LONG SetValue(LPCTSTR valueName, bool value) throw(); - LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw(); - // LONG SetValue(LPCTSTR valueName, const CSysString &value); - #ifndef _UNICODE - LONG SetValue(LPCWSTR name, LPCWSTR value); - // LONG SetValue(LPCWSTR name, const UString &value); - #endif - - LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw(); - - LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) throw(); - LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings); - - LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw(); - - LONG QueryValue(LPCTSTR name, UInt32 &value) throw(); - LONG QueryValue(LPCTSTR name, bool &value) throw(); - LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize) throw(); - LONG QueryValue(LPCTSTR name, CSysString &value); - - LONG GetValue_IfOk(LPCTSTR name, UInt32 &value) throw(); - LONG GetValue_IfOk(LPCTSTR name, bool &value) throw(); - - #ifndef _UNICODE - LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize); - LONG QueryValue(LPCWSTR name, UString &value); - #endif - - LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) throw(); - LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize); - - LONG EnumKeys(CSysStringVector &keyNames); -}; - -}} - -#endif +// Windows/Registry.h + +#ifndef ZIP7_INC_WINDOWS_REGISTRY_H +#define ZIP7_INC_WINDOWS_REGISTRY_H + +#include "../Common/MyBuffer.h" +#include "../Common/MyString.h" + +namespace NWindows { +namespace NRegistry { + +LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value); + +class CKey +{ + HKEY _object; + + LONG QueryValueEx(LPCTSTR lpValueName, LPDWORD lpType, + LPBYTE lpData, LPDWORD lpcbData) + { + return RegQueryValueEx(_object, lpValueName, NULL, lpType, lpData, lpcbData); + } + +public: + CKey(): _object(NULL) {} + ~CKey() { Close(); } + + operator HKEY() const { return _object; } + void Attach(HKEY key) { _object = key; } + HKEY Detach() + { + const HKEY key = _object; + _object = NULL; + return key; + } + + LONG Create(HKEY parentKey, LPCTSTR keyName, + LPTSTR keyClass = REG_NONE, + DWORD options = REG_OPTION_NON_VOLATILE, + REGSAM accessMask = KEY_ALL_ACCESS, + LPSECURITY_ATTRIBUTES securityAttributes = NULL, + LPDWORD disposition = NULL) throw(); + LONG Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask = KEY_ALL_ACCESS) throw(); + + LONG Close() throw(); + + LONG DeleteSubKey(LPCTSTR subKeyName) throw(); + LONG RecurseDeleteKey(LPCTSTR subKeyName) throw(); + + LONG DeleteValue(LPCTSTR name) throw(); +#ifndef _UNICODE + LONG DeleteValue(LPCWSTR name); +#endif + + LONG SetValue(LPCTSTR valueName, UInt32 value) throw(); + LONG SetValue(LPCTSTR valueName, bool value) throw(); + LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw(); + // LONG SetValue(LPCTSTR valueName, const CSysString &value); +#ifndef _UNICODE + LONG SetValue(LPCWSTR name, LPCWSTR value); + // LONG SetValue(LPCWSTR name, const UString &value); +#endif + + LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw(); + + LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings); + LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings); + + LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw(); + + // GetValue_[type]_IfOk(): + // if (return_result == ERROR_SUCCESS), (value) variable was read from registry + // if (return_result != ERROR_SUCCESS), (value) variable was not changed + LONG GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw(); + LONG GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw(); + LONG GetValue_bool_IfOk(LPCTSTR name, bool &value) throw(); + + // QueryValue(): + // if (return_result == ERROR_SUCCESS), (value) string was read from registry + // if (return_result != ERROR_SUCCESS), (value) string was cleared + LONG QueryValue(LPCTSTR name, CSysString &value); +#ifndef _UNICODE + LONG QueryValue(LPCWSTR name, UString &value); +#endif + + // QueryValue_Binary(): + // if (return_result == ERROR_SUCCESS), (value) buffer was read from registry (BINARY data) + // if (return_result != ERROR_SUCCESS), (value) buffer was cleared + LONG QueryValue_Binary(LPCTSTR name, CByteBuffer &value); + + LONG EnumKeys(CSysStringVector &keyNames); +}; + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/ResourceString.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.cpp --- p7zip-rar-16.02/CPP/Windows/ResourceString.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.cpp 2021-01-25 19:06:46.000000000 +0000 @@ -0,0 +1,103 @@ +// Windows/ResourceString.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#include "ResourceString.h" + +extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE + +static CSysString MyLoadStringA(HINSTANCE hInstance, UINT resourceID) +{ + CSysString s; + int size = 128; + int len; + do + { + size <<= 1; + len = ::LoadString(hInstance, resourceID, s.GetBuf((unsigned)size - 1), size); + } + while (size - len <= 1); + s.ReleaseBuf_CalcLen((unsigned)len); + return s; +} + +#endif + +static const int kStartSize = 256; + +static void MyLoadString2(HINSTANCE hInstance, UINT resourceID, UString &s) +{ + int size = kStartSize; + int len; + do + { + size <<= 1; + len = ::LoadStringW(hInstance, resourceID, s.GetBuf((unsigned)size - 1), size); + } + while (size - len <= 1); + s.ReleaseBuf_CalcLen((unsigned)len); +} + +// NT4 doesn't support LoadStringW(,,, 0) to get pointer to resource string. So we don't use it. + +UString MyLoadString(UINT resourceID) +{ + #ifndef _UNICODE + if (!g_IsNT) + return GetUnicodeString(MyLoadStringA(g_hInstance, resourceID)); + else + #endif + { + { + wchar_t s[kStartSize]; + s[0] = 0; + int len = ::LoadStringW(g_hInstance, resourceID, s, kStartSize); + if (kStartSize - len > 1) + return s; + } + UString dest; + MyLoadString2(g_hInstance, resourceID, dest); + return dest; + } +} + +void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest) +{ + dest.Empty(); + #ifndef _UNICODE + if (!g_IsNT) + MultiByteToUnicodeString2(dest, MyLoadStringA(hInstance, resourceID)); + else + #endif + { + { + wchar_t s[kStartSize]; + s[0] = 0; + int len = ::LoadStringW(hInstance, resourceID, s, kStartSize); + if (kStartSize - len > 1) + { + dest = s; + return; + } + } + MyLoadString2(hInstance, resourceID, dest); + } +} + +void MyLoadString(UINT resourceID, UString &dest) +{ + MyLoadString(g_hInstance, resourceID, dest); +} + +} diff -Nru p7zip-rar-16.02/CPP/Windows/ResourceString.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.h --- p7zip-rar-16.02/CPP/Windows/ResourceString.h 2014-12-28 12:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/ResourceString.h 2023-03-18 08:00:00.000000000 +0000 @@ -1,16 +1,17 @@ -// Windows/ResourceString.h - -#ifndef __WINDOWS_RESOURCE_STRING_H -#define __WINDOWS_RESOURCE_STRING_H - -#include "../Common/MyString.h" - -namespace NWindows { - -UString MyLoadString(UINT resourceID); -void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest); -void MyLoadString(UINT resourceID, UString &dest); - -} - -#endif +// Windows/ResourceString.h + +#ifndef ZIP7_INC_WINDOWS_RESOURCE_STRING_H +#define ZIP7_INC_WINDOWS_RESOURCE_STRING_H + +#include "../Common/MyString.h" +#include "../Common/MyWindows.h" + +namespace NWindows { + +UString MyLoadString(UINT resourceID); +void MyLoadString(HINSTANCE hInstance, UINT resourceID, UString &dest); +void MyLoadString(UINT resourceID, UString &dest); + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/SecurityUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.cpp --- p7zip-rar-16.02/CPP/Windows/SecurityUtils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.cpp 2023-03-18 09:00:00.000000000 +0000 @@ -0,0 +1,186 @@ +// Windows/SecurityUtils.cpp + +#include "StdAfx.h" + +#include "SecurityUtils.h" + +namespace NWindows { +namespace NSecurity { + +/* +bool MyLookupAccountSid(LPCTSTR systemName, PSID sid, + CSysString &accountName, CSysString &domainName, PSID_NAME_USE sidNameUse) +{ + DWORD accountNameSize = 0, domainNameSize = 0; + + if (!::LookupAccountSid(systemName, sid, + accountName.GetBuf(0), &accountNameSize, + domainName.GetBuf(0), &domainNameSize, sidNameUse)) + { + if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return false; + } + DWORD accountNameSize2 = accountNameSize, domainNameSize2 = domainNameSize; + bool result = BOOLToBool(::LookupAccountSid(systemName, sid, + accountName.GetBuf(accountNameSize), &accountNameSize2, + domainName.GetBuf(domainNameSize), &domainNameSize2, sidNameUse)); + accountName.ReleaseBuf_CalcLen(accountNameSize); + domainName.ReleaseBuf_CalcLen(domainNameSize); + return result; +} +*/ + +static void SetLsaString(LPWSTR src, PLSA_UNICODE_STRING dest) +{ + const size_t len = (size_t)wcslen(src); + dest->Length = (USHORT)(len * sizeof(WCHAR)); + dest->MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR)); + dest->Buffer = src; +} + +/* +static void MyLookupSids(CPolicy &policy, PSID ps) +{ + LSA_REFERENCED_DOMAIN_LIST *referencedDomains = NULL; + LSA_TRANSLATED_NAME *names = NULL; + NTSTATUS nts = policy.LookupSids(1, &ps, &referencedDomains, &names); + int res = LsaNtStatusToWinError(nts); + LsaFreeMemory(referencedDomains); + LsaFreeMemory(names); +} +*/ + +extern "C" { + +#ifndef _UNICODE +typedef BOOL (WINAPI * Func_LookupAccountNameW)( + LPCWSTR lpSystemName, + LPCWSTR lpAccountName, + PSID Sid, + LPDWORD cbSid, + LPWSTR ReferencedDomainName, + LPDWORD cchReferencedDomainName, + PSID_NAME_USE peUse + ); +#endif + +} + +static PSID GetSid(LPWSTR accountName) +{ + #ifndef _UNICODE + const HMODULE hModule = GetModuleHandle(TEXT("advapi32.dll")); + if (!hModule) + return NULL; + const + Func_LookupAccountNameW lookupAccountNameW = Z7_GET_PROC_ADDRESS( + Func_LookupAccountNameW, hModule, + "LookupAccountNameW"); + if (!lookupAccountNameW) + return NULL; + #endif + + DWORD sidLen = 0, domainLen = 0; + SID_NAME_USE sidNameUse; + if (! + #ifdef _UNICODE + ::LookupAccountNameW + #else + lookupAccountNameW + #endif + (NULL, accountName, NULL, &sidLen, NULL, &domainLen, &sidNameUse)) + { + if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + const PSID pSid = ::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidLen); + LPWSTR domainName = (LPWSTR)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (domainLen + 1) * sizeof(WCHAR)); + const BOOL res = + #ifdef _UNICODE + ::LookupAccountNameW + #else + lookupAccountNameW + #endif + (NULL, accountName, pSid, &sidLen, domainName, &domainLen, &sidNameUse); + ::HeapFree(GetProcessHeap(), 0, domainName); + if (res) + return pSid; + } + } + return NULL; +} + +#define Z7_WIN_SE_LOCK_MEMORY_NAME L"SeLockMemoryPrivilege" + +bool AddLockMemoryPrivilege() +{ + CPolicy policy; + LSA_OBJECT_ATTRIBUTES attr; + attr.Length = sizeof(attr); + attr.RootDirectory = NULL; + attr.ObjectName = NULL; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (policy.Open(NULL, &attr, + // GENERIC_WRITE) + POLICY_ALL_ACCESS) + // STANDARD_RIGHTS_REQUIRED, + // GENERIC_READ | GENERIC_EXECUTE | POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES) + != 0) + return false; + LSA_UNICODE_STRING userRights; + wchar_t s[128] = Z7_WIN_SE_LOCK_MEMORY_NAME; + SetLsaString(s, &userRights); + WCHAR userName[256 + 2]; + DWORD size = 256; + if (!GetUserNameW(userName, &size)) + return false; + const PSID psid = GetSid(userName); + if (psid == NULL) + return false; + bool res = false; + + /* + PLSA_UNICODE_STRING userRightsArray; + ULONG countOfRights; + NTSTATUS status = policy.EnumerateAccountRights(psid, &userRightsArray, &countOfRights); + if (status != 0) + return false; + bool finded = false; + for (ULONG i = 0; i < countOfRights; i++) + { + LSA_UNICODE_STRING &ur = userRightsArray[i]; + if (ur.Length != s.Length() * sizeof(WCHAR)) + continue; + if (wcsncmp(ur.Buffer, s, s.Length()) != 0) + continue; + finded = true; + res = true; + break; + } + if (!finded) + */ + { + /* + LSA_ENUMERATION_INFORMATION *enums; + ULONG countReturned; + NTSTATUS status = policy.EnumerateAccountsWithUserRight(&userRights, &enums, &countReturned); + if (status == 0) + { + for (ULONG i = 0; i < countReturned; i++) + MyLookupSids(policy, enums[i].Sid); + if (enums) + ::LsaFreeMemory(enums); + res = true; + } + */ + const NTSTATUS status = policy.AddAccountRights(psid, &userRights); + if (status == 0) + res = true; + // ULONG res = LsaNtStatusToWinError(status); + } + HeapFree(GetProcessHeap(), 0, psid); + return res; +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/SecurityUtils.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.h --- p7zip-rar-16.02/CPP/Windows/SecurityUtils.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/SecurityUtils.h 2024-05-02 11:00:00.000000000 +0000 @@ -0,0 +1,150 @@ +// Windows/SecurityUtils.h + +#ifndef ZIP7_INC_WINDOWS_SECURITY_UTILS_H +#define ZIP7_INC_WINDOWS_SECURITY_UTILS_H + +#include + +#include "Defs.h" + +#ifndef _UNICODE + +extern "C" { +typedef NTSTATUS (NTAPI *Func_LsaOpenPolicy)(PLSA_UNICODE_STRING SystemName, + PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle); +typedef NTSTATUS (NTAPI *Func_LsaClose)(LSA_HANDLE ObjectHandle); +typedef NTSTATUS (NTAPI *Func_LsaAddAccountRights)(LSA_HANDLE PolicyHandle, + PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights ); +#define MY_STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L) +} + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +#define POLICY_FUNC_CALL(fff, str) \ + if (hModule == NULL) return MY_STATUS_NOT_IMPLEMENTED; \ + const Func_ ## fff v = Z7_GET_PROC_ADDRESS(Func_ ## fff, hModule, str); \ + if (!v) return MY_STATUS_NOT_IMPLEMENTED; \ + const NTSTATUS res = v + +#else + +#define POLICY_FUNC_CALL(fff, str) \ + const NTSTATUS res = ::fff + +#endif + + +namespace NWindows { +namespace NSecurity { + +class CAccessToken +{ + HANDLE _handle; +public: + CAccessToken(): _handle(NULL) {} + ~CAccessToken() { Close(); } + bool Close() + { + if (_handle == NULL) + return true; + bool res = BOOLToBool(::CloseHandle(_handle)); + if (res) + _handle = NULL; + return res; + } + + bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess) + { + Close(); + return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle)); + } + + /* + bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf) + { + Close(); + return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle)); + } + */ + + bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState, + DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength) + { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges), + newState, bufferLength, previousState, returnLength)); } + + bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState) + { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); } + + bool AdjustPrivileges(PTOKEN_PRIVILEGES newState) + { return AdjustPrivileges(false, newState); } + +}; + + + + +struct CPolicy +{ +protected: + LSA_HANDLE _handle; + #ifndef _UNICODE + HMODULE hModule; + #endif +public: + operator LSA_HANDLE() const { return _handle; } + CPolicy(): _handle(NULL) + { + #ifndef _UNICODE + hModule = GetModuleHandle(TEXT("advapi32.dll")); + #endif + } + ~CPolicy() { Close(); } + + NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes, + ACCESS_MASK desiredAccess) + { + Close(); + POLICY_FUNC_CALL (LsaOpenPolicy, "LsaOpenPolicy") + (systemName, objectAttributes, desiredAccess, &_handle); + return res; + } + + NTSTATUS Close() + { + if (_handle == NULL) + return 0; + POLICY_FUNC_CALL (LsaClose, "LsaClose") + (_handle); + _handle = NULL; + return res; + } + + NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights, + PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned) + { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); } + + NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights) + { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); } + + NTSTATUS LookupSids(ULONG count, PSID* sids, + PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names) + { return LsaLookupSids(_handle, count, sids, referencedDomains, names); } + + NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights) + { + POLICY_FUNC_CALL (LsaAddAccountRights, "LsaAddAccountRights") + (_handle, accountSid, userRights, countOfRights); + return res; + } + NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights) + { return AddAccountRights(accountSid, userRights, 1); } + + NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights) + { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); } +}; + +bool AddLockMemoryPrivilege(); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Shell.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.cpp --- p7zip-rar-16.02/CPP/Windows/Shell.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.cpp 2024-01-25 06:00:00.000000000 +0000 @@ -0,0 +1,839 @@ +// Windows/Shell.cpp + +#include "StdAfx.h" + +#include "../Common/MyCom.h" +#include "../Common/StringConvert.h" + +#include "COM.h" +#include "FileName.h" +#include "MemoryGlobal.h" +#include "Shell.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +// MSVC6 and old SDK don't support this function: +// #define LWSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE +// LWSTDAPI StrRetToStrW(STRRET *pstr, LPCITEMIDLIST pidl, LPWSTR *ppsz); + +// #define SHOW_DEBUG_SHELL + +#ifdef SHOW_DEBUG_SHELL + +#include "../Common/IntToString.h" + +static void Print_Number(UInt32 number, const char *s) +{ + AString s2; + s2.Add_UInt32(number); + s2.Add_Space(); + s2 += s; + OutputDebugStringA(s2); +} + +#define ODS(sz) { OutputDebugStringA(sz); } +#define ODS_U(s) { OutputDebugStringW(s); } +#define ODS_(op) { op; } + +#else + +#define ODS(sz) +#define ODS_U(s) +#define ODS_(op) + +#endif + + +namespace NWindows { +namespace NShell { + +#ifndef UNDER_CE + +// SHGetMalloc is unsupported in Windows Mobile? + +void CItemIDList::Free() +{ + if (!m_Object) + return; + /* DOCs: + SHGetMalloc was introduced in Windows 95 and Microsoft Windows NT 4.0, + but as of Windows 2000 it is no longer necessary. + In its place, programs can call the equivalent (and easier to use) CoTaskMemAlloc and CoTaskMemFree. + Description from oldnewthings: + shell functions could work without COM (if OLE32.DLL is not loaded), + but now if OLE32.DLL is loaded, then shell functions and com functions do same things. + 22.02: so we use OLE32.DLL function to free memory: + */ + /* + CMyComPtr shellMalloc; + if (::SHGetMalloc(&shellMalloc) != NOERROR) + throw 41099; + shellMalloc->Free(m_Object); + */ + CoTaskMemFree(m_Object); + m_Object = NULL; +} + +/* +CItemIDList::(LPCITEMIDLIST itemIDList): m_Object(NULL) + { *this = itemIDList; } +CItemIDList::(const CItemIDList& itemIDList): m_Object(NULL) + { *this = itemIDList; } + +CItemIDList& CItemIDList::operator=(LPCITEMIDLIST object) +{ + Free(); + if (object != 0) + { + UINT32 size = GetSize(object); + m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size); + if (m_Object != NULL) + MoveMemory(m_Object, object, size); + } + return *this; +} + +CItemIDList& CItemIDList::operator=(const CItemIDList &object) +{ + Free(); + if (object.m_Object != NULL) + { + UINT32 size = GetSize(object.m_Object); + m_Object = (LPITEMIDLIST)CoTaskMemAlloc(size); + if (m_Object != NULL) + MoveMemory(m_Object, object.m_Object, size); + } + return *this; +} +*/ + + +static HRESULT ReadUnicodeStrings(const wchar_t *p, size_t size, UStringVector &names) +{ + names.Clear(); + const wchar_t *lim = p + size; + UString s; + /* + if (size == 0 || p[size - 1] != 0) + return E_INVALIDARG; + if (size == 1) + return S_OK; + if (p[size - 2] != 0) + return E_INVALIDARG; + */ + for (;;) + { + const wchar_t *start = p; + for (;;) + { + if (p == lim) return E_INVALIDARG; // S_FALSE + if (*p++ == 0) + break; + } + const size_t num = (size_t)(p - start); + if (num == 1) + { + if (p != lim) return E_INVALIDARG; // S_FALSE + return S_OK; + } + s.SetFrom(start, (unsigned)(num - 1)); + ODS_U(s) + names.Add(s); + // names.ReserveOnePosition(); + // names.AddInReserved_Ptr_of_new(new UString((unsigned)num - 1, start)); + } +} + + +static HRESULT ReadAnsiStrings(const char *p, size_t size, UStringVector &names) +{ + names.Clear(); + AString name; + for (; size != 0; size--) + { + const char c = *p++; + if (c == 0) + { + if (name.IsEmpty()) + return S_OK; + names.Add(GetUnicodeString(name)); + name.Empty(); + } + else + name.Add_Char(c); + } + return E_INVALIDARG; +} + + +#define INIT_FORMATETC_HGLOBAL(type) { (type), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } + +static HRESULT DataObject_GetData_HGLOBAL(IDataObject *dataObject, CLIPFORMAT cf, NCOM::CStgMedium &medium) +{ + FORMATETC etc = INIT_FORMATETC_HGLOBAL(cf); + RINOK(dataObject->GetData(&etc, &medium)) + if (medium.tymed != TYMED_HGLOBAL) + return E_INVALIDARG; + return S_OK; +} + +static HRESULT DataObject_GetData_HDROP_Names(IDataObject *dataObject, UStringVector &names) +{ + names.Clear(); + NCOM::CStgMedium medium; + + /* Win10 : if (dataObject) is from IContextMenu::Initialize() and + if (len_of_path >= MAX_PATH (260) for some file in data object) + { + GetData() returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) + "The data area passed to a system call is too small", + Is there a way to fix this code for long paths? + } */ + + RINOK(DataObject_GetData_HGLOBAL(dataObject, CF_HDROP, medium)) + const size_t blockSize = GlobalSize(medium.hGlobal); + if (blockSize < sizeof(DROPFILES)) + return E_INVALIDARG; + NMemory::CGlobalLock dropLock(medium.hGlobal); + const DROPFILES *dropFiles = (const DROPFILES *)dropLock.GetPointer(); + if (!dropFiles) + return E_INVALIDARG; + if (blockSize < dropFiles->pFiles + || dropFiles->pFiles < sizeof(DROPFILES) + // || dropFiles->pFiles != sizeof(DROPFILES) + ) + return E_INVALIDARG; + const size_t size = blockSize - dropFiles->pFiles; + const void *namesData = (const Byte *)(const void *)dropFiles + dropFiles->pFiles; + HRESULT hres; + if (dropFiles->fWide) + { + if (size % sizeof(wchar_t) != 0) + return E_INVALIDARG; + hres = ReadUnicodeStrings((const wchar_t *)namesData, size / sizeof(wchar_t), names); + } + else + hres = ReadAnsiStrings((const char *)namesData, size, names); + + ODS_(Print_Number(names.Size(), "DataObject_GetData_HDROP_Names")) + return hres; +} + + + +// CF_IDLIST: +#define MYWIN_CFSTR_SHELLIDLIST TEXT("Shell IDList Array") + +typedef struct +{ + UINT cidl; + UINT aoffset[1]; +} MYWIN_CIDA; +/* + cidl : number of PIDLs that are being transferred, not including the parent folder. + aoffset : An array of offsets, relative to the beginning of this structure. + aoffset[0] - fully qualified PIDL of a parent folder. + If this PIDL is empty, the parent folder is the desktop. + aoffset[1] ... aoffset[cidl] : offset to one of the PIDLs to be transferred. + All of these PIDLs are relative to the PIDL of the parent folder. +*/ + +static HRESULT DataObject_GetData_IDLIST(IDataObject *dataObject, UStringVector &names) +{ + names.Clear(); + NCOM::CStgMedium medium; + RINOK(DataObject_GetData_HGLOBAL(dataObject, (CLIPFORMAT) + RegisterClipboardFormat(MYWIN_CFSTR_SHELLIDLIST), medium)) + const size_t blockSize = GlobalSize(medium.hGlobal); + if (blockSize < sizeof(MYWIN_CIDA) || blockSize >= (UInt32)((UInt32)0 - 1)) + return E_INVALIDARG; + NMemory::CGlobalLock dropLock(medium.hGlobal); + const MYWIN_CIDA *cida = (const MYWIN_CIDA *)dropLock.GetPointer(); + if (!cida) + return E_INVALIDARG; + if (cida->cidl == 0) + { + // is it posssible to have no selected items? + // it's unexpected case. + return E_INVALIDARG; + } + if (cida->cidl >= (blockSize - (UInt32)sizeof(MYWIN_CIDA)) / sizeof(UINT)) + return E_INVALIDARG; + const UInt32 start = cida->cidl * (UInt32)sizeof(UINT) + (UInt32)sizeof(MYWIN_CIDA); + + STRRET strret; + CMyComPtr parentFolder; + { + const UINT offset = cida->aoffset[0]; + if (offset < start || offset >= blockSize + // || offset != start + ) + return E_INVALIDARG; + + CMyComPtr desktopFolder; + RINOK(::SHGetDesktopFolder(&desktopFolder)) + if (!desktopFolder) + return E_FAIL; + + LPCITEMIDLIST const lpcItem = (LPCITEMIDLIST)(const void *)((const Byte *)cida + offset); + + #ifdef SHOW_DEBUG_SHELL + { + const HRESULT res = desktopFolder->GetDisplayNameOf( + lpcItem, SHGDN_FORPARSING, &strret); + if (res == S_OK && strret.uType == STRRET_WSTR) + { + ODS_U(strret.pOleStr) + /* if lpcItem is empty, the path will be + "C:\Users\user_name\Desktop" + if lpcItem is "My Computer" folder, the path will be + "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" */ + CoTaskMemFree(strret.pOleStr); + } + } + #endif + + RINOK(desktopFolder->BindToObject(lpcItem, + NULL, IID_IShellFolder, (void **)&parentFolder)) + if (!parentFolder) + return E_FAIL; + } + + names.ClearAndReserve(cida->cidl); + UString path; + + // for (int y = 0; y < 1; y++) // for debug + for (unsigned i = 1; i <= cida->cidl; i++) + { + const UINT offset = cida->aoffset[i]; + if (offset < start || offset >= blockSize) + return E_INVALIDARG; + const void *p = (const Byte *)(const void *)cida + offset; + /* ITEMIDLIST of file can contain more than one SHITEMID item. + In win10 only SHGDN_FORPARSING returns path that contains + all path parts related to parts of ITEMIDLIST. + So we can use only SHGDN_FORPARSING here. + Don't use (SHGDN_INFOLDER) + Don't use (SHGDN_INFOLDER | SHGDN_FORPARSING) + */ + RINOK(parentFolder->GetDisplayNameOf((LPCITEMIDLIST)p, SHGDN_FORPARSING, &strret)) + + /* + // MSVC6 and old SDK do not support StrRetToStrW(). + LPWSTR lpstr; + RINOK (StrRetToStrW(&strret, NULL, &lpstr)) + ODS_U(lpstr) + path = lpstr; + CoTaskMemFree(lpstr); + */ + if (strret.uType != STRRET_WSTR) + return E_INVALIDARG; + ODS_U(strret.pOleStr) + path = strret.pOleStr; + // the path could have super path prefix "\\\\?\\" + // we can remove super path prefix here, if we don't need that prefix + #ifdef Z7_LONG_PATH + // we remove super prefix, if we can work without that prefix + NFile::NName::If_IsSuperPath_RemoveSuperPrefix(path); + #endif + names.AddInReserved(path); + CoTaskMemFree(strret.pOleStr); + } + + ODS_(Print_Number(cida->cidl, "CFSTR_SHELLIDLIST END")) + return S_OK; +} + + +HRESULT DataObject_GetData_HDROP_or_IDLIST_Names(IDataObject *dataObject, UStringVector &paths) +{ + ODS("-- DataObject_GetData_HDROP_or_IDLIST_Names START") + HRESULT hres = NShell::DataObject_GetData_HDROP_Names(dataObject, paths); + // if (hres == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) + if (hres != S_OK) + { + ODS("-- DataObject_GetData_IDLIST START") + // for (int y = 0; y < 10000; y++) // for debug + hres = NShell::DataObject_GetData_IDLIST(dataObject, paths); + } + ODS("-- DataObject_GetData_HDROP_or_IDLIST_Names END") + return hres; +} + + + +// #if (NTDDI_VERSION >= NTDDI_VISTA) +typedef struct +{ + UINT cItems; // number of items in rgdwFileAttributes array + DWORD dwSumFileAttributes; // all of the attributes ORed together + DWORD dwProductFileAttributes; // all of the attributes ANDed together + DWORD rgdwFileAttributes[1]; // array +} MYWIN_FILE_ATTRIBUTES_ARRAY; + +#define MYWIN_CFSTR_FILE_ATTRIBUTES_ARRAY TEXT("File Attributes Array") + +HRESULT DataObject_GetData_FILE_ATTRS(IDataObject *dataObject, CFileAttribs &attribs) +{ + attribs.Clear(); + NCOM::CStgMedium medium; + RINOK(DataObject_GetData_HGLOBAL(dataObject, (CLIPFORMAT) + RegisterClipboardFormat(MYWIN_CFSTR_FILE_ATTRIBUTES_ARRAY), medium)) + const size_t blockSize = GlobalSize(medium.hGlobal); + if (blockSize < sizeof(MYWIN_FILE_ATTRIBUTES_ARRAY)) + return E_INVALIDARG; + NMemory::CGlobalLock dropLock(medium.hGlobal); + const MYWIN_FILE_ATTRIBUTES_ARRAY *faa = (const MYWIN_FILE_ATTRIBUTES_ARRAY *)dropLock.GetPointer(); + if (!faa) + return E_INVALIDARG; + const unsigned numFiles = faa->cItems; + if (numFiles == 0) + { + // is it posssible to have empty array here? + return E_INVALIDARG; + } + if ((blockSize - (sizeof(MYWIN_FILE_ATTRIBUTES_ARRAY) - sizeof(DWORD))) + / sizeof(DWORD) != numFiles) + return E_INVALIDARG; + // attribs.Sum = faa->dwSumFileAttributes; + // attribs.Product = faa->dwProductFileAttributes; + // attribs.Vals.SetFromArray(faa->rgdwFileAttributes, numFiles); + // attribs.IsDirVector.ClearAndSetSize(numFiles); + + if ((faa->dwSumFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + /* in win10: if selected items are volumes (c:\, d:\ ..) in My Compter, + all items have FILE_ATTRIBUTE_DIRECTORY attribute + ntfs volume also have FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM + udf volume: FILE_ATTRIBUTE_READONLY + dvd-rom device: (-1) : all bits are set + */ + const DWORD *attr = faa->rgdwFileAttributes; + // DWORD product = (UInt32)0 - 1, sum = 0; + for (unsigned i = 0; i < numFiles; i++) + { + if (attr[i] & FILE_ATTRIBUTE_DIRECTORY) + { + // attribs.ThereAreDirs = true; + attribs.FirstDirIndex = (int)i; + break; + } + // attribs.IsDirVector[i] = (attr[i] & FILE_ATTRIBUTE_DIRECTORY) != 0; + // product &= v; + // sum |= v; + } + // ODS_(Print_Number(product, "Product calc FILE_ATTRIBUTES_ARRAY ==== DataObject_GetData_HDROP_Names")) + // ODS_(Print_Number(sum, "Sum calc FILE_ATTRIBUTES_ARRAY ==== DataObject_GetData_HDROP_Names")) + } + // ODS_(Print_Number(attribs.Product, "Product FILE_ATTRIBUTES_ARRAY ==== DataObject_GetData_HDROP_Names")) + // ODS_(Print_Number(attribs.Sum, "Sum FILE_ATTRIBUTES_ARRAY ==== DataObject_GetData_HDROP_Names")) + ODS_(Print_Number(numFiles, "FILE_ATTRIBUTES_ARRAY ==== DataObject_GetData_HDROP_Names")) + return S_OK; +} + + +///////////////////////////// +// CDrop + +/* + win10: + DragQueryFile() implementation code is not effective because + there is no pointer inside DROP internal file list, so + DragQueryFile(fileIndex) runs all names in range [0, fileIndex]. + DragQueryFile(,, buf, bufSize) + if (buf == NULL) by spec + { + returns value is the required size + in characters, of the buffer, not including the terminating null character + tests show that if (bufSize == 0), then it also returns required size. + } + if (bufSize != NULL) + { + returns: the count of the characters copied, not including null character. + win10: null character is also copied at position buf[ret_count]; + } +*/ + +/* +void CDrop::Attach(HDROP object) +{ + Free(); + m_Object = object; + m_Assigned = true; +} + +void CDrop::Free() +{ + if (m_MustBeFinished && m_Assigned) + Finish(); + m_Assigned = false; +} + +UINT CDrop::QueryCountOfFiles() +{ + return QueryFile(0xFFFFFFFF, (LPTSTR)NULL, 0); +} + +void CDrop::QueryFileName(UINT fileIndex, UString &fileName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + AString fileNameA; + const UINT len = QueryFile(fileIndex, (LPTSTR)NULL, 0); + const UINT numCopied = QueryFile(fileIndex, fileNameA.GetBuf(len + 2), len + 2); + fileNameA.ReleaseBuf_CalcLen(len); + if (numCopied != len) + throw 20221223; + fileName = GetUnicodeString(fileNameA); + } + else + #endif + { + // kReserve must be >= 3 for additional buffer size + // safety and for optimal performance + const unsigned kReserve = 3; + { + unsigned len = 0; + wchar_t *buf = fileName.GetBuf_GetMaxAvail(len); + if (len >= kReserve) + { + const UINT numCopied = QueryFile(fileIndex, buf, len); + if (numCopied < len - 1) + { + // (numCopied < len - 1) case means that it have copied full string. + fileName.ReleaseBuf_CalcLen(numCopied); + return; + } + } + } + const UINT len = QueryFile(fileIndex, (LPWSTR)NULL, 0); + const UINT numCopied = QueryFile(fileIndex, + fileName.GetBuf(len + kReserve), len + kReserve); + fileName.ReleaseBuf_CalcLen(len); + if (numCopied != len) + throw 20221223; + } +} + + +void CDrop::QueryFileNames(UStringVector &fileNames) +{ + UINT numFiles = QueryCountOfFiles(); + + Print_Number(numFiles, "\n====== CDrop::QueryFileNames START ===== \n"); + + fileNames.ClearAndReserve(numFiles); + UString s; + for (UINT i = 0; i < numFiles; i++) + { + QueryFileName(i, s); + if (!s.IsEmpty()) + fileNames.AddInReserved(s); + } + Print_Number(numFiles, "\n====== CDrop::QueryFileNames END ===== \n"); +} +*/ + + +// #if (NTDDI_VERSION >= NTDDI_VISTA) +// SHGetPathFromIDListEx returns a win32 file system path for the item in the name space. +typedef int Z7_WIN_GPFIDL_FLAGS; + +extern "C" { +#ifndef _UNICODE +typedef BOOL (WINAPI * Func_SHGetPathFromIDListW)(LPCITEMIDLIST pidl, LPWSTR pszPath); // nt4 +#endif + +#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0600 // Vista +#define Z7_USE_DYN_SHGetPathFromIDListEx +#endif + +#ifdef Z7_USE_DYN_SHGetPathFromIDListEx +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION +typedef BOOL (WINAPI * Func_SHGetPathFromIDListEx)(LPCITEMIDLIST pidl, PWSTR pszPath, DWORD cchPath, Z7_WIN_GPFIDL_FLAGS uOpts); // vista +#endif +} + +#ifndef _UNICODE + +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, AString &path) +{ + path.Empty(); + const unsigned len = MAX_PATH + 16; + const bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuf(len))); + path.ReleaseBuf_CalcLen(len); + return result; +} + +#endif + +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path) +{ + path.Empty(); + unsigned len = MAX_PATH + 16; + +#ifdef _UNICODE + bool result = BOOLToBool(::SHGetPathFromIDList(itemIDList, path.GetBuf(len))); +#else + const + Func_SHGetPathFromIDListW + shGetPathFromIDListW = Z7_GET_PROC_ADDRESS( + Func_SHGetPathFromIDListW, ::GetModuleHandleW(L"shell32.dll"), + "SHGetPathFromIDListW"); + if (!shGetPathFromIDListW) + return false; + bool result = BOOLToBool(shGetPathFromIDListW(itemIDList, path.GetBuf(len))); +#endif + + if (!result) + { + ODS("==== GetPathFromIDList() SHGetPathFromIDList() returned false") + /* for long path we need SHGetPathFromIDListEx(). + win10: SHGetPathFromIDListEx() for long path returns path with + with super path prefix "\\\\?\\". */ +#ifdef Z7_USE_DYN_SHGetPathFromIDListEx + const + Func_SHGetPathFromIDListEx + func_SHGetPathFromIDListEx = Z7_GET_PROC_ADDRESS( + Func_SHGetPathFromIDListEx, ::GetModuleHandleW(L"shell32.dll"), + "SHGetPathFromIDListEx"); + if (func_SHGetPathFromIDListEx) +#endif + { + ODS("==== GetPathFromIDList() (SHGetPathFromIDListEx)") + do + { + len *= 4; + result = BOOLToBool( +#ifdef Z7_USE_DYN_SHGetPathFromIDListEx + func_SHGetPathFromIDListEx +#else + SHGetPathFromIDListEx +#endif + (itemIDList, path.GetBuf(len), len, 0)); + if (result) + break; + } + while (len <= (1 << 16)); + } + } + + path.ReleaseBuf_CalcLen(len); + return result; +} + +#endif + +#ifdef UNDER_CE + +bool BrowseForFolder(LPBROWSEINFO, CSysString) +{ + return false; +} + +bool BrowseForFolder(HWND, LPCTSTR, UINT, LPCTSTR, CSysString &) +{ + return false; +} + +bool BrowseForFolder(HWND /* owner */, LPCTSTR /* title */, + LPCTSTR /* initialFolder */, CSysString & /* resultPath */) +{ + /* + // SHBrowseForFolder doesn't work before CE 6.0 ? + if (GetProcAddress(LoadLibrary(L"ceshell.dll", L"SHBrowseForFolder") == 0) + MessageBoxW(0, L"no", L"", 0); + else + MessageBoxW(0, L"yes", L"", 0); + */ + /* + UString s = "all files"; + s += " (*.*)"; + return MyGetOpenFileName(owner, title, initialFolder, s, resultPath, true); + */ + return false; +} + +#else + +/* win10: SHBrowseForFolder() doesn't support long paths, + even if long path suppport is enabled in registry and in manifest. + and SHBrowseForFolder() doesn't support super path prefix "\\\\?\\". */ + +bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath) +{ + resultPath.Empty(); + NWindows::NCOM::CComInitializer comInitializer; + LPITEMIDLIST itemIDList = ::SHBrowseForFolder(browseInfo); + if (!itemIDList) + return false; + CItemIDList itemIDListHolder; + itemIDListHolder.Attach(itemIDList); + return GetPathFromIDList(itemIDList, resultPath); +} + + +static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data) +{ + #ifndef UNDER_CE + switch (uMsg) + { + case BFFM_INITIALIZED: + { + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, data); + break; + } + /* + case BFFM_SELCHANGED: + { + TCHAR dir[MAX_PATH]; + if (::SHGetPathFromIDList((LPITEMIDLIST) lp , dir)) + SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)dir); + else + SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)TEXT("")); + break; + } + */ + default: + break; + } + #endif + return 0; +} + + +static bool BrowseForFolder(HWND owner, LPCTSTR title, UINT ulFlags, + LPCTSTR initialFolder, CSysString &resultPath) +{ + CSysString displayName; + BROWSEINFO browseInfo; + browseInfo.hwndOwner = owner; + browseInfo.pidlRoot = NULL; + + // there are Unicode/Astring problems in some WinCE SDK ? + /* + #ifdef UNDER_CE + browseInfo.pszDisplayName = (LPSTR)displayName.GetBuf(MAX_PATH); + browseInfo.lpszTitle = (LPCSTR)title; + #else + */ + browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH); + browseInfo.lpszTitle = title; + // #endif + browseInfo.ulFlags = ulFlags; + browseInfo.lpfn = initialFolder ? BrowseCallbackProc : NULL; + browseInfo.lParam = (LPARAM)initialFolder; + return BrowseForFolder(&browseInfo, resultPath); +} + +#ifdef Z7_OLD_WIN_SDK +// ShlObj.h: +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 +#endif +#endif + +bool BrowseForFolder(HWND owner, LPCTSTR title, + LPCTSTR initialFolder, CSysString &resultPath) +{ + return BrowseForFolder(owner, title, + #ifndef UNDER_CE + BIF_NEWDIALOGSTYLE | + #endif + BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT, initialFolder, resultPath); + // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0) +} + +#ifndef _UNICODE + +extern "C" { +typedef LPITEMIDLIST (WINAPI * Func_SHBrowseForFolderW)(LPBROWSEINFOW lpbi); +} + +static bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath) +{ + NWindows::NCOM::CComInitializer comInitializer; + const + Func_SHBrowseForFolderW + f_SHBrowseForFolderW = Z7_GET_PROC_ADDRESS( + Func_SHBrowseForFolderW, ::GetModuleHandleW(L"shell32.dll"), + "SHBrowseForFolderW"); + if (!f_SHBrowseForFolderW) + return false; + LPITEMIDLIST itemIDList = f_SHBrowseForFolderW(browseInfo); + if (!itemIDList) + return false; + CItemIDList itemIDListHolder; + itemIDListHolder.Attach(itemIDList); + return GetPathFromIDList(itemIDList, resultPath); +} + +static +int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data) +{ + switch (uMsg) + { + case BFFM_INITIALIZED: + { + SendMessageW(hwnd, BFFM_SETSELECTIONW, TRUE, data); + break; + } + /* + case BFFM_SELCHANGED: + { + wchar_t dir[MAX_PATH * 2]; + + if (shGetPathFromIDListW((LPITEMIDLIST)lp , dir)) + SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)dir); + else + SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM)L""); + break; + } + */ + default: + break; + } + return 0; +} + + +static bool BrowseForFolder(HWND owner, LPCWSTR title, UINT ulFlags, + LPCWSTR initialFolder, UString &resultPath) +{ + UString displayName; + BROWSEINFOW browseInfo; + browseInfo.hwndOwner = owner; + browseInfo.pidlRoot = NULL; + browseInfo.pszDisplayName = displayName.GetBuf(MAX_PATH); + browseInfo.lpszTitle = title; + browseInfo.ulFlags = ulFlags; + browseInfo.lpfn = initialFolder ? BrowseCallbackProc2 : NULL; + browseInfo.lParam = (LPARAM)initialFolder; + return BrowseForFolder(&browseInfo, resultPath); +} + +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath) +{ + if (g_IsNT) + return BrowseForFolder(owner, title, + BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS + // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified. + , initialFolder, resultPath); + // BIF_STATUSTEXT; BIF_USENEWUI (Version 5.0) + CSysString s; + bool res = BrowseForFolder(owner, GetSystemString(title), + BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS + // | BIF_STATUSTEXT // This flag is not supported when BIF_NEWDIALOGSTYLE is specified. + , GetSystemString(initialFolder), s); + resultPath = GetUnicodeString(s); + return res; +} + +#endif + +#endif + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/Shell.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.h --- p7zip-rar-16.02/CPP/Windows/Shell.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Shell.h 2024-01-27 10:00:00.000000000 +0000 @@ -1,21 +1,129 @@ -// Windows/Shell.h - -#ifndef __WINDOWS_SHELL_H -#define __WINDOWS_SHELL_H - -#include -// #include - -#include "Common/MyString.h" -#include "Windows/Defs.h" - - -namespace NWindows{ -namespace NShell{ - -bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath); - -}} - - -#endif +// Windows/Shell.h + +#ifndef ZIP7_WINDOWS_SHELL_H +#define ZIP7_WINDOWS_SHELL_H + +#include "../Common/MyWindows.h" +#if defined(__MINGW32__) || defined(__MINGW64__) +#include +#else +#include +#endif + +#include "../Common/MyString.h" + +#include "Defs.h" + +namespace NWindows { +namespace NShell { + +///////////////////////// +// CItemIDList +#ifndef UNDER_CE + +class CItemIDList +{ + LPITEMIDLIST m_Object; + Z7_CLASS_NO_COPY(CItemIDList) +public: + CItemIDList(): m_Object(NULL) {} + // CItemIDList(LPCITEMIDLIST itemIDList); + // CItemIDList(const CItemIDList& itemIDList); + ~CItemIDList() { Free(); } + void Free(); + void Attach(LPITEMIDLIST object) + { + Free(); + m_Object = object; + } + LPITEMIDLIST Detach() + { + LPITEMIDLIST object = m_Object; + m_Object = NULL; + return object; + } + operator LPITEMIDLIST() { return m_Object;} + operator LPCITEMIDLIST() const { return m_Object;} + LPITEMIDLIST* operator&() { return &m_Object; } + LPITEMIDLIST operator->() { return m_Object; } + + // CItemIDList& operator=(LPCITEMIDLIST object); + // CItemIDList& operator=(const CItemIDList &object); +}; + +///////////////////////////// +// CDrop + +/* +class CDrop +{ + HDROP m_Object; + bool m_MustBeFinished; + bool m_Assigned; + void Free(); +public: + CDrop(bool mustBeFinished) : m_MustBeFinished(mustBeFinished), m_Assigned(false) {} + ~CDrop() { Free(); } + + void Attach(HDROP object); + operator HDROP() { return m_Object;} + bool QueryPoint(LPPOINT point) + { return BOOLToBool(::DragQueryPoint(m_Object, point)); } + void Finish() + { + ::DragFinish(m_Object); + } + UINT QueryFile(UINT fileIndex, LPTSTR fileName, UINT bufSize) + { return ::DragQueryFile(m_Object, fileIndex, fileName, bufSize); } + #ifndef _UNICODE + UINT QueryFile(UINT fileIndex, LPWSTR fileName, UINT bufSize) + { return ::DragQueryFileW(m_Object, fileIndex, fileName, bufSize); } + #endif + UINT QueryCountOfFiles(); + void QueryFileName(UINT fileIndex, UString &fileName); + void QueryFileNames(UStringVector &fileNames); +}; +*/ +#endif + +struct CFileAttribs +{ + int FirstDirIndex; + // DWORD Sum; + // DWORD Product; + // CRecordVector Vals; + // CRecordVector IsDirVector; + + CFileAttribs() + { + Clear(); + } + + void Clear() + { + FirstDirIndex = -1; + // Sum = 0; + // Product = 0; + // IsDirVector.Clear(); + } +}; + + +/* read pathnames from HDROP or SHELLIDLIST. + The parser can return E_INVALIDARG, if there is some unexpected data in dataObject */ +HRESULT DataObject_GetData_HDROP_or_IDLIST_Names(IDataObject *dataObject, UStringVector &names); + +HRESULT DataObject_GetData_FILE_ATTRS(IDataObject *dataObject, CFileAttribs &attribs); + +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, CSysString &path); +bool BrowseForFolder(LPBROWSEINFO lpbi, CSysString &resultPath); +bool BrowseForFolder(HWND owner, LPCTSTR title, LPCTSTR initialFolder, CSysString &resultPath); + +#ifndef _UNICODE +bool GetPathFromIDList(LPCITEMIDLIST itemIDList, UString &path); +bool BrowseForFolder(LPBROWSEINFO lpbi, UString &resultPath); +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath); +#endif +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/StdAfx.h --- p7zip-rar-16.02/CPP/Windows/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/StdAfx.h 2023-12-04 10:00:00.000000000 +0000 @@ -0,0 +1,11 @@ +// StdAfx.h + +#ifndef ZIP7_INC_STDAFX_H +#define ZIP7_INC_STDAFX_H + +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif +#include "../Common/Common.h" + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Synchronization.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.cpp --- p7zip-rar-16.02/CPP/Windows/Synchronization.cpp 2009-06-06 08:59:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.cpp 2023-03-18 10:00:00.000000000 +0000 @@ -1,157 +1,87 @@ -// Windows/Synchronization.cpp - -#include "StdAfx.h" - -#include "Synchronization.h" - -// #define TRACEN(u) u; -#define TRACEN(u) /* */ - -#define MAGIC 0x1234CAFE -class CSynchroTest -{ - int _magic; - public: - CSynchroTest() { - _magic = MAGIC; - } - void testConstructor() { - if (_magic != MAGIC) { - printf("ERROR : no constructors called during loading of plugins (please look at LINK_SHARED in makefile.machine)\n"); - exit(EXIT_FAILURE); - } - } -}; - -static CSynchroTest gbl_synchroTest; - -extern "C" void sync_TestConstructor(void) { - gbl_synchroTest.testConstructor(); -} - - -namespace NWindows { -namespace NSynchronization { - - -#ifndef ENV_BEOS -#ifdef DEBUG_SYNCHRO - void CSynchro::dump_error(int ligne,int ret,const char *text,void *param) - { - printf("\n##T%d#ERROR2 (l=%d) %s : param=%p ret = %d (%s)##\n",(int)pthread_self(),ligne,text,param,ret,strerror(ret)); - // abort(); - } - CSynchro::CSynchro() { - TRACEN((printf("\nT%d : E1-CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) - _isValid = false; - } - - void CSynchro::Create() { - TRACEN((printf("\nT%d : E1-CSynchro::Create(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) - pthread_mutexattr_t mutexattr; - memset(&mutexattr,0,sizeof(mutexattr)); - int ret = pthread_mutexattr_init(&mutexattr); - if (ret != 0) { - dump_error(__LINE__,ret,"pthread_mutexattr_init",&mutexattr); - } - ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) dump_error(__LINE__,ret,"pthread_mutexattr_settype",&mutexattr); - ret = ::pthread_mutex_init(&_object,&mutexattr); - if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_init",&_object); - ret = ::pthread_cond_init(&_cond,0); - if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_init",&_cond); - TRACEN((printf("\nT%d : E2-CSynchro::Create(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) - } - CSynchro::~CSynchro() { - TRACEN((printf("\nT%d : E1-~CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) - if (_isValid) { - int ret = ::pthread_mutex_destroy(&_object); - if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_destroy",&_object); - ret = ::pthread_cond_destroy(&_cond); - if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_destroy",&_cond); - TRACEN((printf("\nT%d : E2-~CSynchro(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) - } - _isValid = false; - } - void CSynchro::Enter() { - TRACEN((printf("\nT%d : E1-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) - int ret = ::pthread_mutex_lock(&_object); - if (ret != 0) { - dump_error(__LINE__,ret,"CSynchro::Enter-pthread_mutex_lock",&_object); - } - TRACEN((printf("\nT%d : E2-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) - } - void CSynchro::Leave() { - TRACEN((printf("\nT%d : E1-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) - int ret = ::pthread_mutex_unlock(&_object); - if (ret != 0) dump_error(__LINE__,ret,"Leave::pthread_mutex_unlock",&_object); - TRACEN((printf("\nT%d : E2-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) - } - void CSynchro::WaitCond() { - TRACEN((printf("\nT%d : E1-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) - int ret = ::pthread_cond_wait(&_cond, &_object); - if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_wait",&_cond); - TRACEN((printf("\nT%d : E2-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) - } - void CSynchro::LeaveAndSignal() { - TRACEN((printf("\nT%d : E1-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) - int ret = ::pthread_cond_broadcast(&_cond); - if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_broadcast",&_cond); - TRACEN((printf("\nT%d : E2-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_object))) - ret = ::pthread_mutex_unlock(&_object); - if (ret != 0) dump_error(__LINE__,ret,"LeaveAndSignal::pthread_mutex_unlock",&_object); - TRACEN((printf("\nT%d : E3-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) - } -#endif -#endif - -}} - -DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ) -{ - TRACEN((printf("\nT%d : E1-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) - if (wait_all != FALSE) { - printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) wait_all(%d) != FALSE\n\n",(unsigned)wait_all); - abort(); - } - - if (timeout != INFINITE) { - printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) timeout(%u) != INFINITE\n\n",(unsigned)timeout); - abort(); - } - - if (count < 1) { - printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) count(%u) < 1\n\n",(unsigned)count); - abort(); - } - - NWindows::NSynchronization::CSynchro *synchro = handles[0]->_sync; - - TRACEN((printf("\nT%d : E2-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) - synchro->Enter(); - TRACEN((printf("\nT%d : E3-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) - -#ifdef DEBUG_SYNCHRO - for(DWORD i=1;i_sync) { - printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) synchro(%p) != handles[%d]->_sync(%p)\n\n", - synchro,(unsigned)i,handles[i]->_sync); - abort(); - } - } -#endif - - while(1) { - for(DWORD i=0;iIsSignaledAndUpdate()) { - synchro->Leave(); - TRACEN((printf("\nT%d : E4-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) - return WAIT_OBJECT_0+i; - } - } - synchro->WaitCond(); - } - synchro->Leave(); - return ETIMEDOUT; // WAIT_TIMEOUT; -} - +// Windows/Synchronization.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 + +#include "Synchronization.h" + +namespace NWindows { +namespace NSynchronization { + +/* +#define INFINITE 0xFFFFFFFF +#define MAXIMUM_WAIT_OBJECTS 64 +#define STATUS_ABANDONED_WAIT_0 ((NTSTATUS)0x00000080L) +#define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) +#define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) +// WINAPI +DWORD WaitForMultipleObjects(DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout); +*/ + +/* clang: we need to place some virtual functions in cpp file to rid off the warning: + 'CBaseHandle_WFMO' has no out-of-line virtual method definitions; + its vtable will be emitted in every translation unit */ +CBaseHandle_WFMO::~CBaseHandle_WFMO() +{ +} + +bool CBaseEvent_WFMO::IsSignaledAndUpdate() +{ + if (this->_state == false) + return false; + if (this->_manual_reset == false) + this->_state = false; + return true; +} + +bool CSemaphore_WFMO::IsSignaledAndUpdate() +{ + if (this->_count == 0) + return false; + this->_count--; + return true; +} + +DWORD WINAPI WaitForMultiObj_Any_Infinite(DWORD count, const CHandle_WFMO *handles) +{ + if (count < 1) + { + // abort(); + SetLastError(EINVAL); + return WAIT_FAILED; + } + + CSynchro *synchro = handles[0]->_sync; + synchro->Enter(); + + // #ifdef DEBUG_SYNCHRO + for (DWORD i = 1; i < count; i++) + { + if (synchro != handles[i]->_sync) + { + // abort(); + synchro->Leave(); + SetLastError(EINVAL); + return WAIT_FAILED; + } + } + // #endif + + for (;;) + { + for (DWORD i = 0; i < count; i++) + { + if (handles[i]->IsSignaledAndUpdate()) + { + synchro->Leave(); + return WAIT_OBJECT_0 + i; + } + } + synchro->WaitCond(); + } +} + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Synchronization.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.h --- p7zip-rar-16.02/CPP/Windows/Synchronization.h 2010-03-01 20:49:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization.h 2024-03-03 09:00:00.000000000 +0000 @@ -1,187 +1,386 @@ -// Windows/Synchronization.h - -#ifndef __WINDOWS_SYNCHRONIZATION_H -#define __WINDOWS_SYNCHRONIZATION_H - -#include "Defs.h" - -extern "C" -{ -#include "../../C/Threads.h" -} - -#ifdef _WIN32 -#include "Handle.h" -#endif - -namespace NWindows { -namespace NSynchronization { - -class Uncopyable { -protected: - Uncopyable() {} // allow construction - ~Uncopyable() {} // and destruction of derived objects... -private: - Uncopyable(const Uncopyable&); // ...but prevent copying - Uncopyable& operator=(const Uncopyable&); -}; - - -class CBaseEvent // FIXME : private Uncopyable -{ -protected: - ::CEvent _object; -public: - bool IsCreated() { return Event_IsCreated(&_object) != 0; } -#ifdef _WIN32 - operator HANDLE() { return _object.handle; } -#endif - CBaseEvent() { Event_Construct(&_object); } - ~CBaseEvent() { Close(); } - WRes Close() { return Event_Close(&_object); } - #ifdef _WIN32 - WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, - LPSECURITY_ATTRIBUTES securityAttributes = NULL) - { - _object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset), - BoolToBOOL(initiallyOwn), name); - if (_object.handle != 0) - return 0; - return ::GetLastError(); - } - WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) - { - _object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name); - if (_object.handle != 0) - return 0; - return ::GetLastError(); - } - #endif - - WRes Set() { return Event_Set(&_object); } - // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); } - WRes Reset() { return Event_Reset(&_object); } - WRes Lock() { return Event_Wait(&_object); } -}; - -class CManualResetEvent: public CBaseEvent -{ -public: - WRes Create(bool initiallyOwn = false) - { - return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0); - } - WRes CreateIfNotCreated() - { - if (IsCreated()) - return 0; - return ManualResetEvent_CreateNotSignaled(&_object); - } - #ifdef _WIN32 - WRes CreateWithName(bool initiallyOwn, LPCTSTR name) - { - return CBaseEvent::Create(true, initiallyOwn, name); - } - #endif -}; - -class CAutoResetEvent: public CBaseEvent -{ -public: - WRes Create() - { - return AutoResetEvent_CreateNotSignaled(&_object); - } - WRes CreateIfNotCreated() - { - if (IsCreated()) - return 0; - return AutoResetEvent_CreateNotSignaled(&_object); - } -}; - -#ifdef _WIN32 -class CObject: public CHandle -{ -public: - WRes Lock(DWORD timeoutInterval = INFINITE) - { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); } -}; -class CMutex: public CObject -{ -public: - WRes Create(bool initiallyOwn, LPCTSTR name = NULL, - LPSECURITY_ATTRIBUTES securityAttributes = NULL) - { - _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name); - if (_handle != 0) - return 0; - return ::GetLastError(); - } - WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) - { - _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name); - if (_handle != 0) - return 0; - return ::GetLastError(); - } - WRes Release() - { - return ::ReleaseMutex(_handle) ? 0 : ::GetLastError(); - } -}; -class CMutexLock -{ - CMutex *_object; -public: - CMutexLock(CMutex &object): _object(&object) { _object->Lock(); } - ~CMutexLock() { _object->Release(); } -}; -#endif - -class CSemaphore : private Uncopyable -{ - ::CSemaphore _object; -public: - CSemaphore() { Semaphore_Construct(&_object); } - ~CSemaphore() { Close(); } - WRes Close() { return Semaphore_Close(&_object); } -#ifdef _WIN32 - operator HANDLE() { return _object.handle; } -#endif - WRes Create(UInt32 initiallyCount, UInt32 maxCount) - { - return Semaphore_Create(&_object, initiallyCount, maxCount); - } - WRes Release() { return Semaphore_Release1(&_object); } - WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); } - WRes Lock() { return Semaphore_Wait(&_object); } -}; - -class CCriticalSection : private Uncopyable -{ - ::CCriticalSection _object; -public: - CCriticalSection() { CriticalSection_Init(&_object); } - ~CCriticalSection() { CriticalSection_Delete(&_object); } - void Enter() { CriticalSection_Enter(&_object); } - void Leave() { CriticalSection_Leave(&_object); } -}; - -class CCriticalSectionLock : private Uncopyable -{ - CCriticalSection *_object; - void Unlock() { _object->Leave(); } -public: - CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); } - ~CCriticalSectionLock() { Unlock(); } -}; - -}} - -#ifndef _WIN32 -#include "Synchronization2.h" -#endif - -#endif - +// Windows/Synchronization.h + +#ifndef ZIP7_INC_WINDOWS_SYNCHRONIZATION_H +#define ZIP7_INC_WINDOWS_SYNCHRONIZATION_H + +#include "../../C/Threads.h" + +#include "../Common/MyTypes.h" + +#include "Defs.h" + +#ifdef _WIN32 +#include "Handle.h" +#endif + +namespace NWindows { +namespace NSynchronization { + +class CBaseEvent MY_UNCOPYABLE +{ +protected: + ::CEvent _object; +public: + bool IsCreated() { return Event_IsCreated(&_object) != 0; } + + CBaseEvent() { Event_Construct(&_object); } + ~CBaseEvent() { Close(); } + WRes Close() { return Event_Close(&_object); } + + #ifdef _WIN32 + operator HANDLE() { return _object; } + WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL) + { + _object = ::CreateEvent(sa, BoolToBOOL(manualReset), BoolToBOOL(initiallyOwn), name); + if (name == NULL && _object != NULL) + return 0; + return ::GetLastError(); + } + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _object = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_object != NULL) + return 0; + return ::GetLastError(); + } + #endif + + WRes Set() { return Event_Set(&_object); } + // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); } + WRes Reset() { return Event_Reset(&_object); } + WRes Lock() { return Event_Wait(&_object); } +}; + +class CManualResetEvent: public CBaseEvent +{ +public: + WRes Create(bool initiallyOwn = false) + { + return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0); + } + WRes CreateIfNotCreated_Reset() + { + if (IsCreated()) + return Reset(); + return ManualResetEvent_CreateNotSignaled(&_object); + } + #ifdef _WIN32 + WRes CreateWithName(bool initiallyOwn, LPCTSTR name) + { + return CBaseEvent::Create(true, initiallyOwn, name); + } + #endif +}; + +class CAutoResetEvent: public CBaseEvent +{ +public: + WRes Create() + { + return AutoResetEvent_CreateNotSignaled(&_object); + } + WRes CreateIfNotCreated_Reset() + { + if (IsCreated()) + return Reset(); + return AutoResetEvent_CreateNotSignaled(&_object); + } +}; + + +/* +#ifdef _WIN32 + +class CObject: public CHandle +{ +public: + WRes Lock(DWORD timeoutInterval = INFINITE) + { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); } +}; + +class CMutex: public CObject +{ +public: + WRes Create(bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL) + { + _handle = ::CreateMutex(sa, BoolToBOOL(initiallyOwn), name); + if (name == NULL && _handle != 0) + return 0; + return ::GetLastError(); + } + #ifndef UNDER_CE + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_handle != 0) + return 0; + return ::GetLastError(); + } + #endif + WRes Release() + { + return ::ReleaseMutex(_handle) ? 0 : ::GetLastError(); + } +}; + +class CMutexLock MY_UNCOPYABLE +{ + CMutex *_object; +public: + CMutexLock(CMutex &object): _object(&object) { _object->Lock(); } + ~CMutexLock() { _object->Release(); } +}; + +#endif // _WIN32 +*/ + + +class CSemaphore MY_UNCOPYABLE +{ + ::CSemaphore _object; +public: + CSemaphore() { Semaphore_Construct(&_object); } + ~CSemaphore() { Close(); } + WRes Close() { return Semaphore_Close(&_object); } + + #ifdef _WIN32 + operator HANDLE() { return _object; } + #endif + + // bool IsCreated() const { return Semaphore_IsCreated(&_object) != 0; } + + WRes Create(UInt32 initCount, UInt32 maxCount) + { + return Semaphore_Create(&_object, initCount, maxCount); + } + WRes OptCreateInit(UInt32 initCount, UInt32 maxCount) + { + return Semaphore_OptCreateInit(&_object, initCount, maxCount); + } + WRes Release() { return Semaphore_Release1(&_object); } + WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); } + WRes Lock() { return Semaphore_Wait(&_object); } +}; + +class CCriticalSection MY_UNCOPYABLE +{ + ::CCriticalSection _object; +public: + CCriticalSection() { CriticalSection_Init(&_object); } + ~CCriticalSection() { CriticalSection_Delete(&_object); } + void Enter() { CriticalSection_Enter(&_object); } + void Leave() { CriticalSection_Leave(&_object); } +}; + +class CCriticalSectionLock MY_UNCOPYABLE +{ + CCriticalSection *_object; + void Unlock() { _object->Leave(); } +public: + CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); } + ~CCriticalSectionLock() { Unlock(); } +}; + + +#ifdef _WIN32 + +typedef HANDLE CHandle_WFMO; +typedef CSemaphore CSemaphore_WFMO; +typedef CAutoResetEvent CAutoResetEvent_WFMO; +typedef CManualResetEvent CManualResetEvent_WFMO; + +inline DWORD WINAPI WaitForMultiObj_Any_Infinite(DWORD count, const CHandle_WFMO *handles) +{ + return ::WaitForMultipleObjects(count, handles, FALSE, INFINITE); +} + +#define SYNC_OBJ_DECL(obj) +#define SYNC_WFMO(x) +#define SYNC_PARAM(x) +#define SYNC_PARAM_DECL(x) + +#else // _WIN32 + +// POSIX sync objects for WaitForMultipleObjects + +#define SYNC_WFMO(x) x +#define SYNC_PARAM(x) x, +#define SYNC_PARAM_DECL(x) NWindows::NSynchronization::CSynchro *x +#define SYNC_OBJ_DECL(x) NWindows::NSynchronization::CSynchro x; + +class CSynchro MY_UNCOPYABLE +{ + pthread_mutex_t _mutex; + pthread_cond_t _cond; + bool _isValid; + +public: + CSynchro() { _isValid = false; } + ~CSynchro() + { + if (_isValid) + { + ::pthread_mutex_destroy(&_mutex); + ::pthread_cond_destroy(&_cond); + } + _isValid = false; + } + WRes Create() + { + RINOK(::pthread_mutex_init(&_mutex, NULL)) + const WRes ret = ::pthread_cond_init(&_cond, NULL); + _isValid = 1; + return ret; + } + WRes Enter() + { +#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \ + && defined(__FreeBSD__) + #pragma GCC diagnostic ignored "-Wthread-safety-negative" + #pragma GCC diagnostic ignored "-Wthread-safety-analysis" +#endif + return ::pthread_mutex_lock(&_mutex); + } + WRes Leave() + { + return ::pthread_mutex_unlock(&_mutex); + } + WRes WaitCond() + { + return ::pthread_cond_wait(&_cond, &_mutex); + } + WRes LeaveAndSignal() + { + const WRes res1 = ::pthread_cond_broadcast(&_cond); + const WRes res2 = ::pthread_mutex_unlock(&_mutex); + return (res2 ? res2 : res1); + } +}; + + +struct CBaseHandle_WFMO; +typedef NWindows::NSynchronization::CBaseHandle_WFMO *CHandle_WFMO; + +// these constants are from Windows +#define WAIT_OBJECT_0 0 +#define WAIT_FAILED ((DWORD)0xFFFFFFFF) + +DWORD WINAPI WaitForMultiObj_Any_Infinite(DWORD count, const CHandle_WFMO *handles); + + +struct CBaseHandle_WFMO MY_UNCOPYABLE +{ + CSynchro *_sync; + + CBaseHandle_WFMO(): _sync(NULL) {} + virtual ~CBaseHandle_WFMO(); + + operator CHandle_WFMO() { return this; } + virtual bool IsSignaledAndUpdate() = 0; +}; + + +class CBaseEvent_WFMO : public CBaseHandle_WFMO +{ + bool _manual_reset; + bool _state; + +public: + + // bool IsCreated() { return (this->_sync != NULL); } + // CBaseEvent_WFMO() { ; } + // ~CBaseEvent_WFMO() Z7_override { Close(); } + + WRes Close() { this->_sync = NULL; return 0; } + + WRes Create( + CSynchro *sync, + bool manualReset, bool initiallyOwn) + { + this->_sync = sync; + this->_manual_reset = manualReset; + this->_state = initiallyOwn; + return 0; + } + + WRes Set() + { + RINOK(this->_sync->Enter()) + this->_state = true; + return this->_sync->LeaveAndSignal(); + } + + WRes Reset() + { + RINOK(this->_sync->Enter()) + this->_state = false; + return this->_sync->Leave(); + } + + virtual bool IsSignaledAndUpdate() Z7_override; +}; + + +class CManualResetEvent_WFMO Z7_final: public CBaseEvent_WFMO +{ +public: + WRes Create(CSynchro *sync, bool initiallyOwn = false) { return CBaseEvent_WFMO::Create(sync, true, initiallyOwn); } +}; + + +class CAutoResetEvent_WFMO Z7_final: public CBaseEvent_WFMO +{ +public: + WRes Create(CSynchro *sync) { return CBaseEvent_WFMO::Create(sync, false, false); } + WRes CreateIfNotCreated_Reset(CSynchro *sync) + { + return Create(sync); + } +}; + + +class CSemaphore_WFMO Z7_final: public CBaseHandle_WFMO +{ + UInt32 _count; + UInt32 _maxCount; + +public: + CSemaphore_WFMO() : _count(0), _maxCount(0) {} + + WRes Close() { this->_sync = NULL; return 0; } + + WRes Create(CSynchro *sync, UInt32 initCount, UInt32 maxCount) + { + if (initCount > maxCount || maxCount < 1) + return EINVAL; + this->_sync = sync; + this->_count = initCount; + this->_maxCount = maxCount; + return 0; + } + + WRes Release(UInt32 releaseCount = 1) + { + if (releaseCount < 1) + return EINVAL; + + RINOK(this->_sync->Enter()) + UInt32 newCount = this->_count + releaseCount; + if (newCount > this->_maxCount) + { + RINOK(this->_sync->Leave()) + return ERROR_TOO_MANY_POSTS; // EINVAL + } + this->_count = newCount; + + return this->_sync->LeaveAndSignal(); + } + + virtual bool IsSignaledAndUpdate() Z7_override; +}; + +#endif // _WIN32 + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Synchronization2.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization2.h --- p7zip-rar-16.02/CPP/Windows/Synchronization2.h 2009-06-06 08:59:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Synchronization2.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +0,0 @@ -// Windows/Synchronization.h - -#ifdef ENV_BEOS -#include -#include -#include -#endif - -/* Remark : WFMO = WaitForMultipleObjects */ - -namespace NWindows { namespace NSynchronization { struct CBaseHandleWFMO; } } - -typedef NWindows::NSynchronization::CBaseHandleWFMO *HANDLE; - -DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ); - -namespace NWindows { -namespace NSynchronization { - -#ifdef ENV_BEOS -class CSynchro : BLocker, private Uncopyable -{ -#define MAX_THREAD 256 - thread_id _waiting[MAX_THREAD]; // std::list _waiting; - int index_waiting; -public: - CSynchro() { index_waiting = 0; } - void Create() { index_waiting = 0; } - ~CSynchro() {} - void Enter() { Lock(); } - void Leave() { Unlock(); } - void WaitCond() { - _waiting[index_waiting++] = find_thread(NULL); // _waiting.push_back(find_thread(NULL)); - thread_id sender; - Unlock(); - int msg = receive_data(&sender, NULL, 0); - Lock(); - } - void LeaveAndSignal() { - // Unlock(); - // Lock(); - // for (std::list::iterator index = _waiting.begin(); index != _waiting.end(); index++) - for(int index = 0 ; index < index_waiting ; index++) - { - send_data(_waiting[index], '7zCN', NULL, 0); - } - index_waiting = 0; // _waiting.clear(); - Unlock(); - } -}; -#else // #ifdef ENV_BEOS -#ifdef DEBUG_SYNCHRO -class CSynchro: private Uncopyable -{ - pthread_mutex_t _object; - pthread_cond_t _cond; - bool _isValid; - void dump_error(int ligne,int ret,const char *text,void *param); -public: - CSynchro(); - ~CSynchro(); - void Create(); - void Enter(); - void Leave(); - void WaitCond(); - void LeaveAndSignal(); -}; -#else // #ifdef DEBUG_SYNCHRO -class CSynchro : private Uncopyable -{ - pthread_mutex_t _object; - pthread_cond_t _cond; - bool _isValid; -public: - CSynchro() { _isValid = false; } - ~CSynchro() { - if (_isValid) { - ::pthread_mutex_destroy(&_object); - ::pthread_cond_destroy(&_cond); - } - _isValid = false; - } - void Create() { - ::pthread_mutex_init(&_object,0); - ::pthread_cond_init(&_cond,0); - } - void Enter() { - ::pthread_mutex_lock(&_object); - } - void Leave() { - ::pthread_mutex_unlock(&_object); - } - void WaitCond() { - ::pthread_cond_wait(&_cond, &_object); - } - void LeaveAndSignal() { - ::pthread_cond_broadcast(&_cond); - ::pthread_mutex_unlock(&_object); - } -}; -#endif // #ifdef DEBUG_SYNCHRO -#endif // #ifdef ENV_BEOS - -struct CBaseHandleWFMO // FIXME : private Uncopyable -{ - CSynchro *_sync; - - CBaseHandleWFMO() { } - - operator HANDLE() { return this; } - virtual bool IsSignaledAndUpdate() = 0; -}; - -class CBaseEventWFMO : public CBaseHandleWFMO -{ - bool _manual_reset; - bool _state; - -public: - - bool IsCreated() { return (this->_sync != 0); } - CBaseEventWFMO() { this->_sync = 0; } - ~CBaseEventWFMO() { Close(); } - - WRes Close() { this->_sync = 0; return S_OK; } - - WRes Create(CSynchro *sync,bool manualReset, bool initiallyOwn) - { - this->_sync = sync; - this->_manual_reset = manualReset; - this->_state = initiallyOwn; - return S_OK; - } - - WRes Set() { - this->_sync->Enter(); - this->_state = true; - this->_sync->LeaveAndSignal(); - return S_OK; - } - - WRes Reset() { - this->_sync->Enter(); - this->_state = false; - this->_sync->Leave(); - return S_OK; - } - virtual bool IsSignaledAndUpdate() { - if (this->_state == true) { - if (this->_manual_reset == false) this->_state = false; - return true; - } - return false; - } -}; - -class CManualResetEventWFMO: public CBaseEventWFMO -{ -public: - WRes Create(CSynchro *sync,bool initiallyOwn = false) { return CBaseEventWFMO::Create(sync,true, initiallyOwn); } -}; - -class CAutoResetEventWFMO: public CBaseEventWFMO -{ -public: - WRes Create(CSynchro *sync) { return CBaseEventWFMO::Create(sync,false, false); } - WRes CreateIfNotCreated(CSynchro *sync) - { - if (IsCreated()) - return 0; - return CBaseEventWFMO::Create(sync,false, false); - } -}; - -class CSemaphoreWFMO : public CBaseHandleWFMO -{ - LONG _count; - LONG _maxCount; - -public: - CSemaphoreWFMO() : _count(0), _maxCount(0) { this->_sync=0;} - WRes Create(CSynchro *sync,LONG initiallyCount, LONG maxCount) - { - if ((initiallyCount < 0) || (initiallyCount > maxCount) || (maxCount < 1)) return S_FALSE; - this->_sync = sync; - this->_count = initiallyCount; - this->_maxCount = maxCount; - return S_OK; - } - WRes Release(LONG releaseCount = 1) { - if (releaseCount < 1) return S_FALSE; - - this->_sync->Enter(); - LONG newCount = this->_count + releaseCount; - if (newCount > this->_maxCount) - { - this->_sync->Leave(); - return S_FALSE; - } - this->_count = newCount; - - this->_sync->LeaveAndSignal(); - - return S_OK; - } - WRes Close() { this->_sync=0; return S_OK; } - - virtual bool IsSignaledAndUpdate() { - if (this->_count > 0) { - this->_count--; - return true; - } - return false; - } -}; - -}} - diff -Nru p7zip-rar-16.02/CPP/Windows/System.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp --- p7zip-rar-16.02/CPP/Windows/System.cpp 2016-05-19 16:47:31.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp 2025-06-30 15:00:00.000000000 +0000 @@ -1,171 +1,421 @@ -#include -#include - -#if defined (__NetBSD__) || defined(__OpenBSD__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) -#include -#include -#elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) || defined(__NETWARE__) -#include -#elif defined(hpux) || defined(__hpux) -#include -#include -#endif - -#if defined(__NETWARE__) -#include -#endif - -#if defined(ENV_BEOS) -#include -#endif - - -#include "Common/MyTypes.h" - -namespace NWindows -{ - namespace NSystem - { - /************************ GetNumberOfProcessors ************************/ - - #if defined (__NetBSD__) || defined(__OpenBSD__) - UInt32 GetNumberOfProcessors() { - int mib[2], value; - int nbcpu = 1; - - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - size_t len = sizeof(size_t); - if (sysctl(mib, 2, &value, &len, NULL, 0) >= 0) - if (value > nbcpu) - nbcpu = value; - return nbcpu; - } - #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) - UInt32 GetNumberOfProcessors() { - int nbcpu = 1; - size_t value; - size_t len = sizeof(value); - if (sysctlbyname("hw.ncpu", &value, &len, NULL, 0) == 0) - nbcpu = value; - return nbcpu; - } - #elif defined (__APPLE__) - UInt32 GetNumberOfProcessors() { - int nbcpu = 1,value; - size_t valSize = sizeof(value); - if (sysctlbyname ("hw.ncpu", &value, &valSize, NULL, 0) == 0) - nbcpu = value; - return nbcpu; - } - - #elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) - UInt32 GetNumberOfProcessors() { - int nbcpu = sysconf (_SC_NPROCESSORS_CONF); - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #elif defined(hpux) || defined(__hpux) - UInt32 GetNumberOfProcessors() { - struct pst_dynamic psd; - if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1) - return (UInt32)psd.psd_proc_cnt; - return 1; - } - #elif defined(__NETWARE__) - UInt32 GetNumberOfProcessors() { - // int nbcpu = get_nprocs_conf(); - int nbcpu = get_nprocs(); - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #elif defined(ENV_BEOS) - UInt32 GetNumberOfProcessors() { - system_info info; - get_system_info(&info); - int nbcpu = info.cpu_count; - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #else - #warning Generic GetNumberOfProcessors - UInt32 GetNumberOfProcessors() { - return 1; - } - #endif - - /************************ GetRamSize ************************/ - bool GetRamSize(UInt64 &size) { - size = (UInt64)(sizeof(size_t)) << 29; - bool isDefined = true; - -#ifdef linux - FILE * f = fopen( "/proc/meminfo", "r" ); - if (f) - { - char buffer[256]; - unsigned long total; - - size = 0; - - while (fgets( buffer, sizeof(buffer), f )) - { - /* old style /proc/meminfo ... */ - if (sscanf( buffer, "Mem: %lu", &total)) - { - size += total; - } - - /* new style /proc/meminfo ... */ - if (sscanf(buffer, "MemTotal: %lu", &total)) - size = ((UInt64)total)*1024; - } - fclose( f ); - } -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__APPLE__) || defined(__OpenBSD__) -#ifdef HW_MEMSIZE - uint64_t val = 0; // support 2Gb+ RAM - int mib[2] = { CTL_HW, HW_MEMSIZE }; -#elif defined(HW_PHYSMEM64) - uint64_t val = 0; // support 2Gb+ RAM - int mib[2] = { CTL_HW, HW_PHYSMEM64 }; -#else // HW_MEMSIZE - unsigned int val = 0; // For old system - int mib[2] = { CTL_HW, HW_PHYSMEM }; -#endif // HW_MEMSIZE - size_t size_sys = sizeof(val); - - sysctl(mib, 2, &val, &size_sys, NULL, 0); - if (val) size = val; -#elif defined(__CYGWIN__) - unsigned long pagesize=sysconf(_SC_PAGESIZE); // returns 65536 => OK - // see http://readlist.com/lists/cygwin.com/cygwin/0/3313.html - unsigned long maxpages=sysconf(_SC_PHYS_PAGES); - size = ((UInt64)pagesize)*maxpages; -#elif defined ( sun ) || defined(__NETWARE__) - unsigned long pagesize=sysconf(_SC_PAGESIZE); - unsigned long maxpages=sysconf(_SC_PHYS_PAGES); - size = ((UInt64)pagesize)*maxpages; -#elif defined(hpux) || defined(__hpux) - struct pst_static pst; - union pstun pu; - - pu.pst_static = &pst; - if ( pstat( PSTAT_STATIC, pu, (size_t)sizeof(pst), (size_t)0, 0 ) != -1 ) { - size = ((UInt64)pst.physical_memory)*pst.page_size; - } -#elif defined(ENV_BEOS) - system_info info; - get_system_info(&info); - size = info.max_pages; - size *= 4096; -#else -#warning Generic GetRamSize - isDefined = false; -#endif - return isDefined; - } - - } -} - +// Windows/System.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#else +#include +#endif +#endif + +#include "../Common/Defs.h" +// #include "../Common/MyWindows.h" + +// #include "../../C/CpuArch.h" + +#include "System.h" + +namespace NWindows { +namespace NSystem { + +#ifdef _WIN32 + +/* +note: returned value in 32-bit version can be limited by value 32. + while 64-bit version returns full value. +GetMaximumProcessorCount(groupNumber) can return higher value than +GetActiveProcessorCount(groupNumber) in some cases, because CPUs can be added. +*/ +// typedef DWORD (WINAPI *Func_GetMaximumProcessorCount)(WORD GroupNumber); +typedef DWORD (WINAPI *Func_GetActiveProcessorCount)(WORD GroupNumber); +typedef WORD (WINAPI *Func_GetActiveProcessorGroupCount)(VOID); +/* +#if 0 && defined(ALL_PROCESSOR_GROUPS) +#define MY_ALL_PROCESSOR_GROUPS ALL_PROCESSOR_GROUPS +#else +#define MY_ALL_PROCESSOR_GROUPS 0xffff +#endif +*/ + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +bool CCpuGroups::Load() +{ + NumThreadsTotal = 0; + GroupSizes.Clear(); + const HMODULE hmodule = ::GetModuleHandleA("kernel32.dll"); + // Is_Win11_Groups = GetProcAddress(hmodule, "SetThreadSelectedCpuSetMasks") != NULL; + const + Func_GetActiveProcessorGroupCount + fn_GetActiveProcessorGroupCount = Z7_GET_PROC_ADDRESS( + Func_GetActiveProcessorGroupCount, hmodule, + "GetActiveProcessorGroupCount"); + const + Func_GetActiveProcessorCount + fn_GetActiveProcessorCount = Z7_GET_PROC_ADDRESS( + Func_GetActiveProcessorCount, hmodule, + "GetActiveProcessorCount"); + if (!fn_GetActiveProcessorGroupCount || + !fn_GetActiveProcessorCount) + return false; + + const unsigned numGroups = fn_GetActiveProcessorGroupCount(); + if (numGroups == 0) + return false; + UInt32 sum = 0; + for (unsigned i = 0; i < numGroups; i++) + { + const UInt32 num = fn_GetActiveProcessorCount((WORD)i); + /* + if (num == 0) + { + // it means error + // but is it possible that some group is empty by some reason? + // GroupSizes.Clear(); + // return false; + } + */ + sum += num; + GroupSizes.Add(num); + } + NumThreadsTotal = sum; + // NumThreadsTotal = fn_GetActiveProcessorCount(MY_ALL_PROCESSOR_GROUPS); + return true; +} + +UInt32 CountAffinity(DWORD_PTR mask) +{ + UInt32 num = 0; + for (unsigned i = 0; i < sizeof(mask) * 8; i++) + { + num += (UInt32)(mask & 1); + mask >>= 1; + } + return num; +} + +BOOL CProcessAffinity::Get() +{ + IsGroupMode = false; + Groups.Load(); + // SetThreadAffinityMask(GetCurrentThread(), 1); + // SetProcessAffinityMask(GetCurrentProcess(), 1); + BOOL res = GetProcessAffinityMask(GetCurrentProcess(), + &processAffinityMask, &systemAffinityMask); + /* DOCs: On a system with more than 64 processors, if the threads + of the calling process are in a single processor group, the + function sets the variables pointed to by lpProcessAffinityMask + and lpSystemAffinityMask to the process affinity mask and the + processor mask of active logical processors for that group. + If the calling process contains threads in multiple groups, + the function returns zero for both affinity masks + + note: tested in Win10: GetProcessAffinityMask() doesn't return 0 + in (processAffinityMask) and (systemAffinityMask) masks. + We need to test it in Win11: how to get mask==0 from GetProcessAffinityMask()? + */ + if (!res) + { + processAffinityMask = 0; + systemAffinityMask = 0; + } + if (Groups.GroupSizes.Size() > 1 && Groups.NumThreadsTotal) + if (// !res || + processAffinityMask == 0 || // to support case described in DOCs and for (!res) case + processAffinityMask == systemAffinityMask) // for default nonchanged affinity + { + // we set IsGroupMode only if processAffinity is default (not changed). + res = TRUE; + IsGroupMode = true; + } + return res; +} + + +UInt32 CProcessAffinity::Load_and_GetNumberOfThreads() +{ + if (Get()) + { + const UInt32 numProcessors = GetNumProcessThreads(); + if (numProcessors) + return numProcessors; + } + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + // the number of logical processors in the current group + return systemInfo.dwNumberOfProcessors; +} + +UInt32 GetNumberOfProcessors() +{ + // We need to know how many threads we can use. + // By default the process is assigned to one group. + CProcessAffinity pa; + return pa.Load_and_GetNumberOfThreads(); +} + +#else + + +BOOL CProcessAffinity::Get() +{ + numSysThreads = GetNumberOfProcessors(); + + /* + numSysThreads = 8; + for (unsigned i = 0; i < numSysThreads; i++) + CpuSet_Set(&cpu_set, i); + return TRUE; + */ + + #ifdef Z7_AFFINITY_SUPPORTED + + // numSysThreads = sysconf(_SC_NPROCESSORS_ONLN); // The number of processors currently online + if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) != 0) + return FALSE; + return TRUE; + + #else + + // cpu_set = ((CCpuSet)1 << (numSysThreads)) - 1; + return TRUE; + // errno = ENOSYS; + // return FALSE; + + #endif +} + +UInt32 GetNumberOfProcessors() +{ + #ifndef Z7_ST + long n = sysconf(_SC_NPROCESSORS_CONF); // The number of processors configured + if (n < 1) + n = 1; + return (UInt32)n; + #else + return 1; + #endif +} + +#endif + + +#ifdef _WIN32 + +#ifndef UNDER_CE + +#if !defined(_WIN64) && \ + (defined(__MINGW32_VERSION) || defined(Z7_OLD_WIN_SDK)) + +typedef struct { + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; +} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX; + +#else + +#define MY_MEMORYSTATUSEX MEMORYSTATUSEX +#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX + +#endif + +typedef BOOL (WINAPI *Func_GlobalMemoryStatusEx)(MY_LPMEMORYSTATUSEX lpBuffer); + +#endif // !UNDER_CE + + +bool GetRamSize(size_t &size) +{ + size = (size_t)sizeof(size_t) << 29; + + #ifndef UNDER_CE + MY_MEMORYSTATUSEX stat; + stat.dwLength = sizeof(stat); + #endif + + #ifdef _WIN64 + + if (!::GlobalMemoryStatusEx(&stat)) + return false; + size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys); + return true; + + #else + + #ifndef UNDER_CE + const + Func_GlobalMemoryStatusEx fn = Z7_GET_PROC_ADDRESS( + Func_GlobalMemoryStatusEx, ::GetModuleHandleA("kernel32.dll"), + "GlobalMemoryStatusEx"); + if (fn && fn(&stat)) + { + // (MY_MEMORYSTATUSEX::ullTotalVirtual) < 4 GiB in 32-bit mode + size_t size2 = (size_t)0 - 1; + if (size2 > stat.ullTotalPhys) + size2 = (size_t)stat.ullTotalPhys; + if (size2 > stat.ullTotalVirtual) + size2 = (size_t)stat.ullTotalVirtual; + size = size2; + return true; + } + #endif + + // On computers with more than 4 GB of memory: + // new docs : GlobalMemoryStatus can report (-1) value to indicate an overflow. + // some old docs : GlobalMemoryStatus can report (modulo 4 GiB) value. + // (for example, if 5 GB total memory, it could report 1 GB). + // We don't want to get (modulo 4 GiB) value. + // So we use GlobalMemoryStatusEx() instead. + { + MEMORYSTATUS stat2; + stat2.dwLength = sizeof(stat2); + ::GlobalMemoryStatus(&stat2); + size = MyMin(stat2.dwTotalVirtual, stat2.dwTotalPhys); + return true; + } + #endif +} + +#else + +// POSIX +// #include + +bool GetRamSize(size_t &size) +{ + UInt64 size64; + size = (size_t)sizeof(size_t) << 29; + size64 = size; + +#if defined(__APPLE__) || defined(__DragonFly__) || \ + defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + + uint64_t val = 0; + int mib[2]; + mib[0] = CTL_HW; + + #ifdef HW_MEMSIZE + mib[1] = HW_MEMSIZE; + // printf("\n sysctl HW_MEMSIZE"); + #elif defined(HW_PHYSMEM64) + mib[1] = HW_PHYSMEM64; + // printf("\n sysctl HW_PHYSMEM64"); + #else + mib[1] = HW_PHYSMEM; + // printf("\n sysctl HW_PHYSMEM"); + #endif + + size_t size_sys = sizeof(val); + int res = sysctl(mib, 2, &val, &size_sys, NULL, 0); + // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val, (int)size_sys, errno); + // we use strict check (size_sys == sizeof(val)) for returned value + // because big-endian encoding is possible: + if (res == 0 && size_sys == sizeof(val) && val) + size64 = val; + else + { + uint32_t val32 = 0; + size_sys = sizeof(val32); + res = sysctl(mib, 2, &val32, &size_sys, NULL, 0); + // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val32, (int)size_sys, errno); + if (res == 0 && size_sys == sizeof(val32) && val32) + size64 = val32; + } + + #elif defined(_AIX) + #if defined(_SC_AIX_REALMEM) // AIX + size64 = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024; + #endif + #elif 0 || defined(__sun) + #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) + // FreeBSD, Linux, OpenBSD, and Solaris. + { + const long phys_pages = sysconf(_SC_PHYS_PAGES); + const long page_size = sysconf(_SC_PAGESIZE); + // #pragma message("GetRamSize : sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE)") + // printf("\n_SC_PHYS_PAGES (hex) = %lx", (unsigned long)phys_pages); + // printf("\n_SC_PAGESIZE = %lu\n", (unsigned long)page_size); + if (phys_pages != -1 && page_size != -1) + size64 = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size; + } + #endif + #elif defined(__gnu_hurd__) + // fixme + #elif defined(__FreeBSD_kernel__) && defined(__GLIBC__) + // GNU/kFreeBSD Debian + // fixme + #else + + struct sysinfo info; + if (::sysinfo(&info) != 0) + return false; + size64 = (UInt64)info.mem_unit * info.totalram; + /* + printf("\n mem_unit = %lld", (UInt64)info.mem_unit); + printf("\n totalram = %lld", (UInt64)info.totalram); + printf("\n freeram = %lld", (UInt64)info.freeram); + */ + + #endif + + size = (size_t)1 << (sizeof(size_t) * 8 - 1); + if (size > size64) + size = (size_t)size64; + return true; +} + +#endif + + +unsigned long Get_File_OPEN_MAX() +{ + #ifdef _WIN32 + return (1 << 24) - (1 << 16); // ~16M handles + #else + // some linux versions have default open file limit for user process of 1024 files. + long n = sysconf(_SC_OPEN_MAX); + // n = -1; // for debug + // n = 9; // for debug + if (n < 1) + { + // n = OPEN_MAX; // ??? + // n = FOPEN_MAX; // = 16 : + #ifdef _POSIX_OPEN_MAX + n = _POSIX_OPEN_MAX; // = 20 : + #else + n = 30; // our limit + #endif + } + return (unsigned long)n; + #endif +} + +unsigned Get_File_OPEN_MAX_Reduced_for_3_tasks() +{ + unsigned long numFiles_OPEN_MAX = NSystem::Get_File_OPEN_MAX(); + const unsigned delta = 10; // the reserve for another internal needs of process + if (numFiles_OPEN_MAX > delta) + numFiles_OPEN_MAX -= delta; + else + numFiles_OPEN_MAX = 1; + numFiles_OPEN_MAX /= 3; // we suppose that we have up to 3 tasks in total for multiple file processing + numFiles_OPEN_MAX = MyMax(numFiles_OPEN_MAX, (unsigned long)3); + unsigned n = (unsigned)(int)-1; + if (n > numFiles_OPEN_MAX) + n = (unsigned)numFiles_OPEN_MAX; + return n; +} + +}} diff -Nru p7zip-rar-16.02/CPP/Windows/System.cpp.back p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp.back --- p7zip-rar-16.02/CPP/Windows/System.cpp.back 2016-05-19 16:41:47.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.cpp.back 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -#include -#include - -#if defined (__NetBSD__) || defined(__OpenBSD__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) -#include -#include -#elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) || defined(__NETWARE__) -#include -#elif defined(hpux) || defined(__hpux) -#include -#include -#endif - -#if defined(__NETWARE__) -#include -#endif - -#if defined(ENV_BEOS) -#include -#endif - - -#include "Common/MyTypes.h" - -namespace NWindows -{ - namespace NSystem - { - /************************ GetNumberOfProcessors ************************/ - - #if defined (__NetBSD__) || defined(__OpenBSD__) - UInt32 GetNumberOfProcessors() { - int mib[2], value; - int nbcpu = 1; - - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - size_t len = sizeof(size_t); - if (sysctl(mib, 2, &value, &len, NULL, 0) >= 0) - if (value > nbcpu) - nbcpu = value; - return nbcpu; - } - #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) - UInt32 GetNumberOfProcessors() { - int nbcpu = 1; - size_t value; - size_t len = sizeof(value); - if (sysctlbyname("hw.ncpu", &value, &len, NULL, 0) == 0) - nbcpu = value; - return nbcpu; - } - #elif defined (__APPLE__) - UInt32 GetNumberOfProcessors() { - int nbcpu = 1,value; - size_t valSize = sizeof(value); - if (sysctlbyname ("hw.ncpu", &value, &valSize, NULL, 0) == 0) - nbcpu = value; - return nbcpu; - } - - #elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) - UInt32 GetNumberOfProcessors() { - int nbcpu = sysconf (_SC_NPROCESSORS_CONF); - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #elif defined(hpux) || defined(__hpux) - UInt32 GetNumberOfProcessors() { - struct pst_dynamic psd; - if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1) - return (UInt32)psd.psd_proc_cnt; - return 1; - } - #elif defined(__NETWARE__) - UInt32 GetNumberOfProcessors() { - // int nbcpu = get_nprocs_conf(); - int nbcpu = get_nprocs(); - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #elif defined(ENV_BEOS) - UInt32 GetNumberOfProcessors() { - system_info info; - get_system_info(&info); - int nbcpu = info.cpu_count; - if (nbcpu < 1) nbcpu = 1; - return nbcpu; - } - #else - #warning Generic GetNumberOfProcessors - UInt32 GetNumberOfProcessors() { - return 1; - } - #endif - - /************************ GetRamSize ************************/ - bool GetRamSize(UInt64 &size) { - size = (UInt64)(sizeof(size_t)) << 29; - bool isDefined = true; - -#ifdef linux - FILE * f = fopen( "/proc/meminfo", "r" ); - if (f) - { - char buffer[256]; - unsigned long total; - - size = 0; - - while (fgets( buffer, sizeof(buffer), f )) - { - /* old style /proc/meminfo ... */ - if (sscanf( buffer, "Mem: %lu", &total)) - { - size += total; - } - - /* new style /proc/meminfo ... */ - if (sscanf(buffer, "MemTotal: %lu", &total)) - size = ((UInt64)total)*1024; - } - fclose( f ); - } -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__APPLE__) -#ifdef HW_MEMSIZE - uint64_t val = 0; // support 2Gb+ RAM - int mib[2] = { CTL_HW, HW_MEMSIZE }; -#else // HW_MEMSIZE - unsigned int val = 0; // For old system - int mib[2] = { CTL_HW, HW_PHYSMEM }; -#endif // HW_MEMSIZE - size_t size_sys = sizeof(val); - - sysctl(mib, 2, &val, &size_sys, NULL, 0); - if (val) size = val; -#elif defined(__CYGWIN__) - unsigned long pagesize=sysconf(_SC_PAGESIZE); // returns 65536 => OK - // see http://readlist.com/lists/cygwin.com/cygwin/0/3313.html - unsigned long maxpages=sysconf(_SC_PHYS_PAGES); - size = ((UInt64)pagesize)*maxpages; -#elif defined ( sun ) || defined(__NETWARE__) - unsigned long pagesize=sysconf(_SC_PAGESIZE); - unsigned long maxpages=sysconf(_SC_PHYS_PAGES); - size = ((UInt64)pagesize)*maxpages; -#elif defined(hpux) || defined(__hpux) - struct pst_static pst; - union pstun pu; - - pu.pst_static = &pst; - if ( pstat( PSTAT_STATIC, pu, (size_t)sizeof(pst), (size_t)0, 0 ) != -1 ) { - size = ((UInt64)pst.physical_memory)*pst.page_size; - } -#elif defined(ENV_BEOS) - system_info info; - get_system_info(&info); - size = info.max_pages; - size *= 4096; -#else -#warning Generic GetRamSize - isDefined = false; -#endif - return isDefined; - } - - } -} - diff -Nru p7zip-rar-16.02/CPP/Windows/System.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.h --- p7zip-rar-16.02/CPP/Windows/System.h 2015-11-20 20:40:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/System.h 2025-06-30 10:00:00.000000000 +0000 @@ -1,17 +1,189 @@ -// Windows/System.h - -#ifndef __WINDOWS_SYSTEM_H -#define __WINDOWS_SYSTEM_H - -#include "../Common/MyTypes.h" - -namespace NWindows { -namespace NSystem { - -UInt32 GetNumberOfProcessors(); - -bool GetRamSize(UInt64 &size); // returns false, if unknown ram size - -}} - -#endif +// Windows/System.h + +#ifndef ZIP7_INC_WINDOWS_SYSTEM_H +#define ZIP7_INC_WINDOWS_SYSTEM_H + +#ifndef _WIN32 +// #include +#include "../../C/Threads.h" +#endif + +#include "../Common/MyTypes.h" +#include "../Common/MyVector.h" +#include "../Common/MyWindows.h" + +namespace NWindows { +namespace NSystem { + +#ifdef _WIN32 + +struct CCpuGroups +{ + CRecordVector GroupSizes; + UInt32 NumThreadsTotal; // sum of threads in all groups + // bool Is_Win11_Groups; // useless + + void Get_GroupSize_Min_Max(UInt32 &minSize, UInt32 &maxSize) const + { + unsigned num = GroupSizes.Size(); + UInt32 minSize2 = 0, maxSize2 = 0; + if (num) + { + minSize2 = (UInt32)0 - 1; + do + { + const UInt32 v = GroupSizes[--num]; + if (minSize2 > v) minSize2 = v; + if (maxSize2 < v) maxSize2 = v; + } + while (num); + } + minSize = minSize2; + maxSize = maxSize2; + } + bool Load(); + CCpuGroups(): NumThreadsTotal(0) {} +}; + +UInt32 CountAffinity(DWORD_PTR mask); + +struct CProcessAffinity +{ + // UInt32 numProcessThreads; + // UInt32 numSysThreads; + DWORD_PTR processAffinityMask; + DWORD_PTR systemAffinityMask; + + CCpuGroups Groups; + bool IsGroupMode; + /* + IsGroupMode == true, if + Groups.GroupSizes.Size() > 1) && { dafalt affinity was not changed } + IsGroupMode == false, if single group or affinity was changed + */ + + UInt32 Load_and_GetNumberOfThreads(); + + void InitST() + { + // numProcessThreads = 1; + // numSysThreads = 1; + processAffinityMask = 1; + systemAffinityMask = 1; + IsGroupMode = false; + // Groups.NumThreadsTotal = 0; + // Groups.Is_Win11_Groups = false; + } + +/* + void CpuZero() + { + processAffinityMask = 0; + } + + void CpuSet(unsigned cpuIndex) + { + processAffinityMask |= ((DWORD_PTR)1 << cpuIndex); + } +*/ + + UInt32 GetNumProcessThreads() const + { + if (IsGroupMode) + return Groups.NumThreadsTotal; + // IsGroupMode == false + // so we don't want to use groups + // we return number of threads in default primary group: + return CountAffinity(processAffinityMask); + } + UInt32 GetNumSystemThreads() const + { + if (Groups.GroupSizes.Size() > 1 && Groups.NumThreadsTotal) + return Groups.NumThreadsTotal; + return CountAffinity(systemAffinityMask); + } + + BOOL Get(); + + BOOL SetProcAffinity() const + { + return SetProcessAffinityMask(GetCurrentProcess(), processAffinityMask); + } +}; + + +#else // WIN32 + +struct CProcessAffinity +{ + UInt32 numSysThreads; + + UInt32 GetNumSystemThreads() const { return (UInt32)numSysThreads; } + BOOL Get(); + + #ifdef Z7_AFFINITY_SUPPORTED + + CCpuSet cpu_set; + + void InitST() + { + numSysThreads = 1; + CpuSet_Zero(&cpu_set); + CpuSet_Set(&cpu_set, 0); + } + + UInt32 GetNumProcessThreads() const { return (UInt32)CPU_COUNT(&cpu_set); } + void CpuZero() { CpuSet_Zero(&cpu_set); } + void CpuSet(unsigned cpuIndex) { CpuSet_Set(&cpu_set, cpuIndex); } + int IsCpuSet(unsigned cpuIndex) const { return CpuSet_IsSet(&cpu_set, cpuIndex); } + // void CpuClr(int cpuIndex) { CPU_CLR(cpuIndex, &cpu_set); } + + BOOL SetProcAffinity() const + { + return sched_setaffinity(0, sizeof(cpu_set), &cpu_set) == 0; + } + + #else // Z7_AFFINITY_SUPPORTED + + void InitST() + { + numSysThreads = 1; + } + + UInt32 GetNumProcessThreads() const + { + return numSysThreads; + /* + UInt32 num = 0; + for (unsigned i = 0; i < sizeof(cpu_set) * 8; i++) + num += (UInt32)((cpu_set >> i) & 1); + return num; + */ + } + + void CpuZero() { } + void CpuSet(unsigned /* cpuIndex */) { /* UNUSED_VAR(cpuIndex) */ } + int IsCpuSet(unsigned cpuIndex) const { return (cpuIndex < numSysThreads) ? 1 : 0; } + + BOOL SetProcAffinity() const + { + errno = ENOSYS; + return FALSE; + } + + #endif // Z7_AFFINITY_SUPPORTED +}; + +#endif // _WIN32 + + +UInt32 GetNumberOfProcessors(); + +bool GetRamSize(size_t &size); // returns false, if unknown ram size + +unsigned long Get_File_OPEN_MAX(); +unsigned Get_File_OPEN_MAX_Reduced_for_3_tasks(); + +}} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/SystemInfo.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.cpp --- p7zip-rar-16.02/CPP/Windows/SystemInfo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.cpp 2024-11-09 08:00:00.000000000 +0000 @@ -0,0 +1,1251 @@ +// Windows/SystemInfo.cpp + +#include "StdAfx.h" + +#include "../../C/CpuArch.h" + +#include "../Common/IntToString.h" +#include "../Common/StringConvert.h" + +#ifdef _WIN32 + +#include "Registry.h" + +#else + +#include +#include +#ifdef __APPLE__ +#include + +#elif !defined(_AIX) + +#if defined(__GLIBC__) && (__GLIBC__ * 100 + __GLIBC_MINOR__ >= 216) + #define Z7_GETAUXV_AVAILABLE +#else +// #pragma message("=== is not NEW GLIBC === ") + #if defined __has_include + #if __has_include () +// #pragma message("=== sys/auxv.h is avail=== ") + #define Z7_GETAUXV_AVAILABLE + #endif + #endif +#endif + +#ifdef Z7_GETAUXV_AVAILABLE +// #if defined __has_include +// #if __has_include () +#include +#define USE_HWCAP +// #endif +// #endif + +// #undef AT_HWCAP // to debug +// #undef AT_HWCAP2 // to debug + +/* the following patch for some debian systems. + Is it OK to define AT_HWCAP and AT_HWCAP2 here with these constant numbers? */ +/* +#if defined(__FreeBSD_kernel__) && defined(__GLIBC__) + #ifndef AT_HWCAP + #define AT_HWCAP 16 + #endif + #ifndef AT_HWCAP2 + #define AT_HWCAP2 26 + #endif +#endif +*/ + +#ifdef USE_HWCAP + +#if defined(__FreeBSD__) + +// #if (__FreeBSD__ >= 13) // (FreeBSD 12.01 is required for elf_aux_info() ???) +static unsigned long MY_getauxval(int aux) +{ + unsigned long val; + if (elf_aux_info(aux, &val, sizeof(val))) + return 0; + return val; +} + +#else // ! __FreeBSD__ + +#ifdef MY_CPU_ARM_OR_ARM64 + #if defined __has_include + #if __has_include () +#include + #endif + #endif +#endif + +#if defined(AT_HWCAP) || defined(AT_HWCAP2) +#define MY_getauxval getauxval +#endif + +#endif // ! __FreeBSD__ +#endif // USE_HWCAP +#endif // Z7_GETAUXV_AVAILABLE + +#endif // !defined(_AIX) + +#ifdef __linux__ +#include "../Windows/FileIO.h" +#endif + +#endif // WIN32 + +#include "SystemInfo.h" +#include "System.h" + +using namespace NWindows; + +#ifdef __linux__ + +static bool ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf) +{ + NWindows::NFile::NIO::CInFile file; + if (!file.Open(fileName)) + return false; + /* + UInt64 size; + if (!file.GetLength(size)) + { + // GetLength() doesn't work "/proc/cpuinfo" + return false; + } + if (size >= ((UInt32)1 << 29)) + return false; + */ + size_t size = 0; + size_t addSize = (size_t)1 << 12; + for (;;) + { + // printf("\nsize = %d\n", (unsigned)size); + buf.ChangeSize_KeepData(size + addSize, size); + size_t processed; + if (!file.ReadFull(buf.NonConstData() + size, addSize, processed)) + return false; + if (processed == 0) + { + buf.ChangeSize_KeepData(size, size); + return true; + } + size += processed; + addSize *= 2; + } +} + +#endif + + +#if defined(_WIN32) || defined(AT_HWCAP) || defined(AT_HWCAP2) +static void PrintHex(AString &s, UInt64 v) +{ + char temp[32]; + ConvertUInt64ToHex(v, temp); + s += temp; +} +#endif + +#ifdef MY_CPU_X86_OR_AMD64 + +Z7_NO_INLINE +static void PrintCpuChars(AString &s, UInt32 v) +{ + for (unsigned j = 0; j < 4; j++) + { + const Byte b = (Byte)(v & 0xFF); + v >>= 8; + if (b == 0) + break; + if (b >= 0x20 && b <= 0x7f) + s.Add_Char((char)b); + else + { + s.Add_Char('['); + char temp[16]; + ConvertUInt32ToHex(b, temp); + s += temp; + s.Add_Char(']'); + } + } +} + + +static void x86cpuid_to_String(AString &s) +{ + s.Empty(); + + UInt32 a[4]; + // cpuid was called already. So we don't check for cpuid availability here + z7_x86_cpuid(a, 0x80000000); + + if (a[0] >= 0x80000004) // if (maxFunc2 >= hi+4) the full name is available + { + for (unsigned i = 0; i < 3; i++) + { + z7_x86_cpuid(a, (UInt32)(0x80000002 + i)); + for (unsigned j = 0; j < 4; j++) + PrintCpuChars(s, a[j]); + } + } + + s.Trim(); + + if (s.IsEmpty()) + { + z7_x86_cpuid(a, 0); + for (unsigned i = 1; i < 4; i++) + { + const unsigned j = (i ^ (i >> 1)); + PrintCpuChars(s, a[j]); + } + s.Trim(); + } +} + +/* +static void x86cpuid_all_to_String(AString &s) +{ + Cx86cpuid p; + if (!x86cpuid_CheckAndRead(&p)) + return; + s += "x86cpuid maxFunc = "; + s.Add_UInt32(p.maxFunc); + for (unsigned j = 0; j <= p.maxFunc; j++) + { + s.Add_LF(); + // s.Add_UInt32(j); // align + { + char temp[32]; + ConvertUInt32ToString(j, temp); + unsigned len = (unsigned)strlen(temp); + while (len < 8) + { + len++; + s.Add_Space(); + } + s += temp; + } + + s += ":"; + UInt32 d[4] = { 0 }; + MyCPUID(j, &d[0], &d[1], &d[2], &d[3]); + for (unsigned i = 0; i < 4; i++) + { + char temp[32]; + ConvertUInt32ToHex8Digits(d[i], temp); + s.Add_Space(); + s += temp; + } + } +} +*/ + +#endif + + + +#ifdef _WIN32 + +static const char * const k_PROCESSOR_ARCHITECTURE[] = +{ + "x86" // "INTEL" + , "MIPS" + , "ALPHA" + , "PPC" + , "SHX" + , "ARM" + , "IA64" + , "ALPHA64" + , "MSIL" + , "x64" // "AMD64" + , "IA32_ON_WIN64" + , "NEUTRAL" + , "ARM64" + , "ARM32_ON_WIN64" +}; + +#define Z7_WIN_PROCESSOR_ARCHITECTURE_INTEL 0 +#define Z7_WIN_PROCESSOR_ARCHITECTURE_AMD64 9 + + +#define Z7_WIN_PROCESSOR_INTEL_PENTIUM 586 +#define Z7_WIN_PROCESSOR_AMD_X8664 8664 + +/* +static const CUInt32PCharPair k_PROCESSOR[] = +{ + { 2200, "IA64" }, + { 8664, "x64" } +}; + +#define PROCESSOR_INTEL_386 386 +#define PROCESSOR_INTEL_486 486 +#define PROCESSOR_INTEL_PENTIUM 586 +#define PROCESSOR_INTEL_860 860 +#define PROCESSOR_INTEL_IA64 2200 +#define PROCESSOR_AMD_X8664 8664 +#define PROCESSOR_MIPS_R2000 2000 +#define PROCESSOR_MIPS_R3000 3000 +#define PROCESSOR_MIPS_R4000 4000 +#define PROCESSOR_ALPHA_21064 21064 +#define PROCESSOR_PPC_601 601 +#define PROCESSOR_PPC_603 603 +#define PROCESSOR_PPC_604 604 +#define PROCESSOR_PPC_620 620 +#define PROCESSOR_HITACHI_SH3 10003 +#define PROCESSOR_HITACHI_SH3E 10004 +#define PROCESSOR_HITACHI_SH4 10005 +#define PROCESSOR_MOTOROLA_821 821 +#define PROCESSOR_SHx_SH3 103 +#define PROCESSOR_SHx_SH4 104 +#define PROCESSOR_STRONGARM 2577 // 0xA11 +#define PROCESSOR_ARM720 1824 // 0x720 +#define PROCESSOR_ARM820 2080 // 0x820 +#define PROCESSOR_ARM920 2336 // 0x920 +#define PROCESSOR_ARM_7TDMI 70001 +#define PROCESSOR_OPTIL 18767 // 0x494f +*/ + + +/* +static const char * const k_PF[] = +{ + "FP_ERRATA" + , "FP_EMU" + , "CMPXCHG" + , "MMX" + , "PPC_MOVEMEM_64BIT" + , "ALPHA_BYTE" + , "SSE" + , "3DNOW" + , "RDTSC" + , "PAE" + , "SSE2" + , "SSE_DAZ" + , "NX" + , "SSE3" + , "CMPXCHG16B" + , "CMP8XCHG16" + , "CHANNELS" + , "XSAVE" + , "ARM_VFP_32" + , "ARM_NEON" + , "L2AT" + , "VIRT_FIRMWARE" + , "RDWRFSGSBASE" + , "FASTFAIL" + , "ARM_DIVIDE" + , "ARM_64BIT_LOADSTORE_ATOMIC" + , "ARM_EXTERNAL_CACHE" + , "ARM_FMAC" + , "RDRAND" + , "ARM_V8" + , "ARM_V8_CRYPTO" + , "ARM_V8_CRC32" + , "RDTSCP" + , "RDPID" + , "ARM_V81_ATOMIC" + , "MONITORX" +}; +*/ + +#endif + + +static void PrintPage(AString &s, UInt64 v) +{ + const char *t = "B"; + if ((v & 0x3ff) == 0) + { + v >>= 10; + t = "KB"; + } + s.Add_UInt64(v); + s += t; +} + +#ifdef _WIN32 + +static AString TypeToString2(const char * const table[], unsigned num, UInt32 value) +{ + char sz[16]; + const char *p = NULL; + if (value < num) + p = table[value]; + if (!p) + { + ConvertUInt32ToString(value, sz); + p = sz; + } + return (AString)p; +} + +// #if defined(Z7_LARGE_PAGES) || defined(_WIN32) +// #ifdef _WIN32 +void PrintSize_KMGT_Or_Hex(AString &s, UInt64 v) +{ + char c = 0; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'K'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'M'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'G'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'T'; + }}}} + else + { + // s += "0x"; + PrintHex(s, v); + return; + } + s.Add_UInt64(v); + if (c) + s.Add_Char(c); + s.Add_Char('B'); +} +// #endif +// #endif + +static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si) +{ + s += TypeToString2(k_PROCESSOR_ARCHITECTURE, Z7_ARRAY_SIZE(k_PROCESSOR_ARCHITECTURE), si.wProcessorArchitecture); + + if (!( (si.wProcessorArchitecture == Z7_WIN_PROCESSOR_ARCHITECTURE_INTEL && si.dwProcessorType == Z7_WIN_PROCESSOR_INTEL_PENTIUM) + || (si.wProcessorArchitecture == Z7_WIN_PROCESSOR_ARCHITECTURE_AMD64 && si.dwProcessorType == Z7_WIN_PROCESSOR_AMD_X8664))) + { + s.Add_Space(); + // s += TypePairToString(k_PROCESSOR, Z7_ARRAY_SIZE(k_PROCESSOR), si.dwProcessorType); + s.Add_UInt32(si.dwProcessorType); + } + s.Add_Space(); + PrintHex(s, si.wProcessorLevel); + s.Add_Dot(); + PrintHex(s, si.wProcessorRevision); + if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors)) + if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8) + { + s += " act:"; + PrintHex(s, si.dwActiveProcessorMask); + } + s += " threads:"; + s.Add_UInt32(si.dwNumberOfProcessors); + if (si.dwPageSize != 1 << 12) + { + s += " page:"; + PrintPage(s, si.dwPageSize); + } + if (si.dwAllocationGranularity != 1 << 16) + { + s += " gran:"; + PrintPage(s, si.dwAllocationGranularity); + } + s.Add_Space(); + + const DWORD_PTR minAdd = (DWORD_PTR)si.lpMinimumApplicationAddress; + UInt64 maxSize = (UInt64)(DWORD_PTR)si.lpMaximumApplicationAddress + 1; + const UInt32 kReserveSize = ((UInt32)1 << 16); + if (minAdd != kReserveSize) + { + PrintSize_KMGT_Or_Hex(s, minAdd); + s.Add_Minus(); + } + else + { + if ((maxSize & (kReserveSize - 1)) == 0) + maxSize += kReserveSize; + } + PrintSize_KMGT_Or_Hex(s, maxSize); +} + +#ifndef _WIN64 +EXTERN_C_BEGIN +typedef VOID (WINAPI *Func_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); +EXTERN_C_END +#endif + +#endif + +#ifdef __APPLE__ +#ifndef MY_CPU_X86_OR_AMD64 +static void Add_sysctlbyname_to_String(const char *name, AString &s) +{ + size_t bufSize = 256; + char buf[256]; + if (z7_sysctlbyname_Get(name, &buf, &bufSize) == 0) + s += buf; +} +#endif +#endif + +void GetSysInfo(AString &s1, AString &s2); +void GetSysInfo(AString &s1, AString &s2) +{ + s1.Empty(); + s2.Empty(); + + #ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + { + SysInfo_To_String(s1, si); + // s += " : "; + } + + #if !defined(_WIN64) && !defined(UNDER_CE) + const + Func_GetNativeSystemInfo fn = Z7_GET_PROC_ADDRESS( + Func_GetNativeSystemInfo, GetModuleHandleA("kernel32.dll"), + "GetNativeSystemInfo"); + if (fn) + { + SYSTEM_INFO si2; + fn(&si2); + // if (memcmp(&si, &si2, sizeof(si)) != 0) + { + // s += " - "; + SysInfo_To_String(s2, si2); + } + } + #endif + #endif +} + + +static void AddBracedString(AString &dest, AString &src) +{ + if (!src.IsEmpty()) + { + dest.Add_Space_if_NotEmpty(); + dest.Add_Char('('); + dest += src; + dest.Add_Char(')'); + } +} + +struct CCpuName +{ + AString CpuName; + AString Revision; + AString Microcode; + AString LargePages; + +#ifdef _WIN32 + UInt32 MHz; + +#ifdef MY_CPU_ARM64 +#define Z7_SYS_INFO_SHOW_ARM64_REGS +#endif +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + bool Arm64_ISAR0_EL1_Defined; + UInt64 Arm64_ISAR0_EL1; +#endif +#endif + +#ifdef _WIN32 + CCpuName(): + MHz(0) +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + , Arm64_ISAR0_EL1_Defined(false) + , Arm64_ISAR0_EL1(0) +#endif + {} +#endif + + void Fill(); + + void Get_Revision_Microcode_LargePages(AString &s) + { + s.Empty(); + AddBracedString(s, Revision); + AddBracedString(s, Microcode); +#ifdef _WIN32 + if (MHz != 0) + { + s.Add_Space_if_NotEmpty(); + s.Add_UInt32(MHz); + s += " MHz"; + } +#endif + if (!LargePages.IsEmpty()) + s.Add_OptSpaced(LargePages); + } + +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + void Get_Registers(AString &s) + { + if (Arm64_ISAR0_EL1_Defined) + { + // ID_AA64ISAR0_EL1 + s.Add_OptSpaced("cp4030:"); + PrintHex(s, Arm64_ISAR0_EL1); + { + const unsigned sha2 = ((unsigned)(Arm64_ISAR0_EL1 >> 12) & 0xf) - 1; + if (sha2 < 2) + { + s += ":SHA256"; + if (sha2) + s += ":SHA512"; + } + } + } + } +#endif +}; + +void CCpuName::Fill() +{ + // CpuName.Empty(); + // Revision.Empty(); + // Microcode.Empty(); + // LargePages.Empty(); + + AString &s = CpuName; + + #ifdef MY_CPU_X86_OR_AMD64 + { + #if !defined(MY_CPU_AMD64) + if (z7_x86_cpuid_GetMaxFunc()) + #endif + { + x86cpuid_to_String(s); + { + UInt32 a[4]; + z7_x86_cpuid(a, 1); + char temp[16]; + ConvertUInt32ToHex(a[0], temp); + Revision += temp; + } + } + } + #elif defined(__APPLE__) + { + Add_sysctlbyname_to_String("machdep.cpu.brand_string", s); + } + #elif defined(MY_CPU_E2K) && defined(Z7_MCST_LCC_VERSION) && (Z7_MCST_LCC_VERSION >= 12323) + { + s += "mcst "; + s += __builtin_cpu_name(); + s.Add_Space(); + s += __builtin_cpu_arch(); + } + #endif + + +#ifdef _WIN32 + { + NRegistry::CKey key; + if (key.Open(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), KEY_READ) == ERROR_SUCCESS) + { + // s.Empty(); // for debug + { + CSysString name; + if (s.IsEmpty()) + if (key.QueryValue(TEXT("ProcessorNameString"), name) == ERROR_SUCCESS) + { + s += GetAnsiString(name); + } + if (key.QueryValue(TEXT("Identifier"), name) == ERROR_SUCCESS) + { + if (!Revision.IsEmpty()) + Revision += " : "; + Revision += GetAnsiString(name); + } + } +#ifdef _WIN32 + key.GetValue_UInt32_IfOk(TEXT("~MHz"), MHz); +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS +/* +mapping arm64 registers to Windows registry: +CP 4000: MIDR_EL1 +CP 4020: ID_AA64PFR0_EL1 +CP 4021: ID_AA64PFR1_EL1 +CP 4028: ID_AA64DFR0_EL1 +CP 4029: ID_AA64DFR1_EL1 +CP 402C: ID_AA64AFR0_EL1 +CP 402D: ID_AA64AFR1_EL1 +CP 4030: ID_AA64ISAR0_EL1 +CP 4031: ID_AA64ISAR1_EL1 +CP 4038: ID_AA64MMFR0_EL1 +CP 4039: ID_AA64MMFR1_EL1 +CP 403A: ID_AA64MMFR2_EL1 +*/ + if (key.GetValue_UInt64_IfOk(TEXT("CP 4030"), Arm64_ISAR0_EL1) == ERROR_SUCCESS) + Arm64_ISAR0_EL1_Defined = true; +#endif +#endif + LONG res[2]; + CByteBuffer bufs[2]; + res[0] = key.QueryValue_Binary(TEXT("Previous Update Revision"), bufs[0]); + res[1] = key.QueryValue_Binary(TEXT("Update Revision"), bufs[1]); + if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS) + { + for (unsigned i = 0; i < 2; i++) + { + if (i == 1) + Microcode += "->"; + if (res[i] != ERROR_SUCCESS) + continue; + const CByteBuffer &buf = bufs[i]; + if (buf.Size() == 8) + { + const UInt32 high = GetUi32(buf); + if (high != 0) + { + PrintHex(Microcode, high); + Microcode.Add_Dot(); + } + PrintHex(Microcode, GetUi32(buf + 4)); + } + } + } + } + } +#endif + + if (s.IsEmpty()) + { + #ifdef MY_CPU_NAME + s += MY_CPU_NAME; + #endif + } + + #ifdef __APPLE__ + { + AString s2; + UInt32 v = 0; + if (z7_sysctlbyname_Get_UInt32("machdep.cpu.core_count", &v) == 0) + { + s2.Add_UInt32(v); + s2.Add_Char('C'); + } + if (z7_sysctlbyname_Get_UInt32("machdep.cpu.thread_count", &v) == 0) + { + s2.Add_UInt32(v); + s2.Add_Char('T'); + } + if (!s2.IsEmpty()) + { + s.Add_Space_if_NotEmpty(); + s += s2; + } + } + #endif + + #ifdef Z7_LARGE_PAGES + Add_LargePages_String(LargePages); + #endif +} + +void AddCpuFeatures(AString &s); +void AddCpuFeatures(AString &s) +{ + #ifdef _WIN32 + // const unsigned kNumFeatures_Extra = 32; // we check also for unknown features + // const unsigned kNumFeatures = Z7_ARRAY_SIZE(k_PF) + kNumFeatures_Extra; + const unsigned kNumFeatures = 64; + UInt64 flags = 0; + for (unsigned i = 0; i < kNumFeatures; i++) + { + if (IsProcessorFeaturePresent((DWORD)i)) + { + flags += (UInt64)1 << i; + // s.Add_Space_if_NotEmpty(); + // s += TypeToString2(k_PF, Z7_ARRAY_SIZE(k_PF), i); + } + } + s.Add_OptSpaced("f:"); + PrintHex(s, flags); + + #elif defined(__APPLE__) + { + UInt32 v = 0; + if (z7_sysctlbyname_Get_UInt32("hw.pagesize", &v) == 0) + { + s.Add_OptSpaced("PageSize:"); + PrintPage(s, v); + } + } + + #else + + const long v = sysconf(_SC_PAGESIZE); + if (v != -1) + { + s.Add_OptSpaced("PageSize:"); + PrintPage(s, (unsigned long)v); + } + + #if !defined(_AIX) + + #ifdef __linux__ + + CByteBuffer buf; + if (ReadFile_to_Buffer("/sys/kernel/mm/transparent_hugepage/enabled", buf)) + // if (ReadFile_to_Buffer("/proc/cpuinfo", buf)) + { + s.Add_OptSpaced("THP:"); + AString s2; + s2.SetFrom_CalcLen((const char *)(const void *)(const Byte *)buf, (unsigned)buf.Size()); + const int pos = s2.Find('['); + if (pos >= 0) + { + const int pos2 = s2.Find(']', (unsigned)pos + 1); + if (pos2 >= 0) + { + s2.DeleteFrom((unsigned)pos2); + s2.DeleteFrontal((unsigned)pos + 1); + } + } + s += s2; + } + // else throw CSystemException(MY_SRes_HRESULT_FROM_WRes(errno)); + + #endif + + + #ifdef AT_HWCAP + s.Add_OptSpaced("hwcap:"); + { + unsigned long h = MY_getauxval(AT_HWCAP); + PrintHex(s, h); + #ifdef MY_CPU_ARM64 +#ifndef HWCAP_SHA3 +#define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SHA512 +#define HWCAP_SHA512 (1 << 21) +// #pragma message("=== HWCAP_SHA512 define === ") +#endif + if (h & HWCAP_CRC32) s += ":CRC32"; + if (h & HWCAP_SHA1) s += ":SHA1"; + if (h & HWCAP_SHA2) s += ":SHA2"; + if (h & HWCAP_SHA3) s += ":SHA3"; + if (h & HWCAP_SHA512) s += ":SHA512"; + if (h & HWCAP_AES) s += ":AES"; + if (h & HWCAP_ASIMD) s += ":ASIMD"; + #elif defined(MY_CPU_ARM) + if (h & HWCAP_NEON) s += ":NEON"; + #endif + } + #endif // AT_HWCAP + + #ifdef AT_HWCAP2 + { + unsigned long h = MY_getauxval(AT_HWCAP2); + #ifndef MY_CPU_ARM + if (h != 0) + #endif + { + s += " hwcap2:"; + PrintHex(s, h); + #ifdef MY_CPU_ARM + if (h & HWCAP2_CRC32) s += ":CRC32"; + if (h & HWCAP2_SHA1) s += ":SHA1"; + if (h & HWCAP2_SHA2) s += ":SHA2"; + if (h & HWCAP2_AES) s += ":AES"; + #endif + } + } + #endif // AT_HWCAP2 + #endif // _AIX + #endif // _WIN32 +} + + +#ifdef _WIN32 +#ifndef UNDER_CE + +Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION + +EXTERN_C_BEGIN +typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *); +EXTERN_C_END + +static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi) +{ + const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + if (!ntdll) + return FALSE; + const + Func_RtlGetVersion func = Z7_GET_PROC_ADDRESS( + Func_RtlGetVersion, ntdll, + "RtlGetVersion"); + if (!func) + return FALSE; + func(vi); + return TRUE; +} + +#endif +#endif + + +void GetOsInfoText(AString &sRes) +{ + sRes.Empty(); + AString s; + + #ifdef _WIN32 + #ifndef UNDER_CE + // OSVERSIONINFO vi; + OSVERSIONINFOEXW vi; + vi.dwOSVersionInfoSize = sizeof(vi); + // if (::GetVersionEx(&vi)) + if (My_RtlGetVersion(&vi)) + { + s += "Windows"; + if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) + s.Add_UInt32(vi.dwPlatformId); + s.Add_Space(); s.Add_UInt32(vi.dwMajorVersion); + s.Add_Dot(); s.Add_UInt32(vi.dwMinorVersion); + s.Add_Space(); s.Add_UInt32(vi.dwBuildNumber); + + if (vi.wServicePackMajor != 0 || vi.wServicePackMinor != 0) + { + s += " SP:"; s.Add_UInt32(vi.wServicePackMajor); + s.Add_Dot(); s.Add_UInt32(vi.wServicePackMinor); + } + // s += " Suite:"; PrintHex(s, vi.wSuiteMask); + // s += " Type:"; s.Add_UInt32(vi.wProductType); + // s.Add_Space(); s += GetOemString(vi.szCSDVersion); + } + /* + { + s += " OEMCP:"; s.Add_UInt32(GetOEMCP()); + s += " ACP:"; s.Add_UInt32(GetACP()); + } + */ + #endif + #else // _WIN32 + + if (!s.IsEmpty()) + s.Add_LF(); + struct utsname un; + if (uname(&un) == 0) + { + s += un.sysname; + // s += " : "; s += un.nodename; // we don't want to show name of computer + s += " : "; s += un.release; + s += " : "; s += un.version; + s += " : "; s += un.machine; + + #ifdef __APPLE__ + // Add_sysctlbyname_to_String("kern.version", s); + // it's same as "utsname.version" + #endif + } + #endif // _WIN32 + + sRes += s; + #ifdef MY_CPU_X86_OR_AMD64 + { + AString s2; + GetVirtCpuid(s2); + if (!s2.IsEmpty()) + { + sRes += " : "; + sRes += s2; + } + } + #endif +} + + + +void GetSystemInfoText(AString &sRes) +{ + GetOsInfoText(sRes); + sRes.Add_LF(); + + { + AString s, s1, s2; + GetSysInfo(s1, s2); + if (!s1.IsEmpty() || !s2.IsEmpty()) + { + s = s1; + if (s1 != s2 && !s2.IsEmpty()) + { + s += " - "; + s += s2; + } + } + { + AddCpuFeatures(s); + if (!s.IsEmpty()) + { + sRes += s; + sRes.Add_LF(); + } + } + } + { + AString s, registers; + GetCpuName_MultiLine(s, registers); + if (!s.IsEmpty()) + { + sRes += s; + sRes.Add_LF(); + } + if (!registers.IsEmpty()) + { + sRes += registers; + sRes.Add_LF(); + } + } + /* + #ifdef MY_CPU_X86_OR_AMD64 + { + AString s; + x86cpuid_all_to_String(s); + if (!s.IsEmpty()) + { + printCallback->Print(s); + printCallback->NewLine(); + } + } + #endif + */ +} + + +void GetCpuName_MultiLine(AString &s, AString ®isters); +void GetCpuName_MultiLine(AString &s, AString ®isters) +{ + CCpuName cpuName; + cpuName.Fill(); + s = cpuName.CpuName; + AString s2; + cpuName.Get_Revision_Microcode_LargePages(s2); + if (!s2.IsEmpty()) + { + s.Add_LF(); + s += s2; + } + registers.Empty(); +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + cpuName.Get_Registers(registers); +#endif +} + + +#ifdef MY_CPU_X86_OR_AMD64 + +void GetVirtCpuid(AString &s) +{ + const UInt32 kHv = 0x40000000; + + Z7_IF_X86_CPUID_SUPPORTED + { + UInt32 a[4]; + z7_x86_cpuid(a, kHv); + + if (a[0] < kHv || a[0] >= kHv + (1 << 16)) + return; + { + { + for (unsigned j = 1; j < 4; j++) + PrintCpuChars(s, a[j]); + } + } + if (a[0] >= kHv + 1) + { + UInt32 d[4]; + z7_x86_cpuid(d, kHv + 1); + s += " : "; + PrintCpuChars(s, d[0]); + if (a[0] >= kHv + 2) + { + z7_x86_cpuid(d, kHv + 2); + s += " : "; + s.Add_UInt32(d[1] >> 16); + s.Add_Dot(); s.Add_UInt32(d[1] & 0xffff); + s.Add_Dot(); s.Add_UInt32(d[0]); + s.Add_Dot(); s.Add_UInt32(d[2]); + s.Add_Dot(); s.Add_UInt32(d[3] >> 24); + s.Add_Dot(); s.Add_UInt32(d[3] & 0xffffff); + } + /* + if (a[0] >= kHv + 5) + { + z7_x86_cpuid(d, kHv + 5); + s += " : "; + s.Add_UInt32(d[0]); + s += "p"; + s.Add_UInt32(d[1]); + s += "t"; + } + */ + } + } +} + +#endif + + +void GetCompiler(AString &s) +{ + #ifdef __clang__ + s += " CLANG "; + s.Add_UInt32(__clang_major__); + s.Add_Dot(); + s.Add_UInt32(__clang_minor__); + s.Add_Dot(); + s.Add_UInt32(__clang_patchlevel__); + #endif + + #ifdef __xlC__ + s += " XLC "; + s.Add_UInt32(__xlC__ >> 8); + s.Add_Dot(); + s.Add_UInt32(__xlC__ & 0xFF); + #ifdef __xlC_ver__ + s.Add_Dot(); + s.Add_UInt32(__xlC_ver__ >> 8); + s.Add_Dot(); + s.Add_UInt32(__xlC_ver__ & 0xFF); + #endif + #endif + + // #define __LCC__ 126 + // #define __LCC_MINOR__ 20 + // #define __MCST__ 1 + #ifdef __MCST__ + s += " MCST"; + #endif + #ifdef __LCC__ + s += " LCC "; + s.Add_UInt32(__LCC__ / 100); + s.Add_Dot(); + s.Add_UInt32(__LCC__ % 100 / 10); + s.Add_UInt32(__LCC__ % 10); + #ifdef __LCC_MINOR__ + s.Add_Dot(); + s.Add_UInt32(__LCC_MINOR__ / 10); + s.Add_UInt32(__LCC_MINOR__ % 10); + #endif + #endif + + // #define __EDG_VERSION__ 602 + #ifdef __EDG_VERSION__ + s += " EDG "; + s.Add_UInt32(__EDG_VERSION__ / 100); + s.Add_Dot(); + s.Add_UInt32(__EDG_VERSION__ % 100 / 10); + s.Add_UInt32(__EDG_VERSION__ % 10); + #endif + + #ifdef __VERSION__ + s.Add_Space(); + s += "ver:"; + s += __VERSION__; + #endif + + #ifdef __GNUC__ + s += " GCC "; + s.Add_UInt32(__GNUC__); + s.Add_Dot(); + s.Add_UInt32(__GNUC_MINOR__); + s.Add_Dot(); + s.Add_UInt32(__GNUC_PATCHLEVEL__); + #endif + + + #ifdef _MSC_VER + s += " MSC "; + s.Add_UInt32(_MSC_VER); + #ifdef _MSC_FULL_VER + s.Add_Dot(); + s.Add_UInt32(_MSC_FULL_VER); + #endif + + #endif + + #if defined(__AVX512F__) + #if defined(__AVX512VL__) + #define MY_CPU_COMPILE_ISA "AVX512VL" + #else + #define MY_CPU_COMPILE_ISA "AVX512F" + #endif + #elif defined(__AVX2__) + #define MY_CPU_COMPILE_ISA "AVX2" + #elif defined(__AVX__) + #define MY_CPU_COMPILE_ISA "AVX" + #elif defined(__SSE2__) + #define MY_CPU_COMPILE_ISA "SSE2" + #elif defined(_M_IX86_FP) && (_M_IX86_FP >= 2) + #define MY_CPU_COMPILE_ISA "SSE2" + #elif defined(__SSE__) + #define MY_CPU_COMPILE_ISA "SSE" + #elif defined(_M_IX86_FP) && (_M_IX86_FP >= 1) + #define MY_CPU_COMPILE_ISA "SSE" + #elif defined(__i686__) + #define MY_CPU_COMPILE_ISA "i686" + #elif defined(__i586__) + #define MY_CPU_COMPILE_ISA "i586" + #elif defined(__i486__) + #define MY_CPU_COMPILE_ISA "i486" + #elif defined(__i386__) + #define MY_CPU_COMPILE_ISA "i386" + #elif defined(_M_IX86_FP) + #define MY_CPU_COMPILE_ISA "IA32" + #endif + + AString s2; + + #ifdef MY_CPU_COMPILE_ISA + s2.Add_OptSpaced(MY_CPU_COMPILE_ISA); + #endif + +#ifndef MY_CPU_ARM64 + #ifdef __ARM_FP + s2.Add_OptSpaced("FP"); + #endif + #ifdef __ARM_NEON + s2.Add_OptSpaced("NEON"); + #endif + #ifdef __NEON__ + s2.Add_OptSpaced("__NEON__"); + #endif + #ifdef __ARM_FEATURE_SIMD32 + s2.Add_OptSpaced("SIMD32"); + #endif +#endif + + #ifdef __ARM_FEATURE_CRYPTO + s2.Add_OptSpaced("CRYPTO"); + #endif + + #ifdef __ARM_FEATURE_SHA2 + s2.Add_OptSpaced("SHA2"); + #endif + + #ifdef __ARM_FEATURE_AES + s2.Add_OptSpaced("AES"); + #endif + + #ifdef __ARM_FEATURE_CRC32 + s2.Add_OptSpaced("CRC32"); + #endif + + #ifdef __ARM_FEATURE_UNALIGNED + s2.Add_OptSpaced("UNALIGNED"); + #endif + + + #ifdef MY_CPU_BE + s2.Add_OptSpaced("BE"); + #endif + + #if defined(MY_CPU_LE_UNALIGN) \ + && !defined(MY_CPU_X86_OR_AMD64) \ + && !defined(MY_CPU_ARM64) + s2.Add_OptSpaced("LE-unaligned"); + #endif + + if (!s2.IsEmpty()) + { + s.Add_OptSpaced(": "); + s += s2; + } +} diff -Nru p7zip-rar-16.02/CPP/Windows/SystemInfo.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.h --- p7zip-rar-16.02/CPP/Windows/SystemInfo.h 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/SystemInfo.h 2024-11-08 17:00:00.000000000 +0000 @@ -0,0 +1,19 @@ +// Windows/SystemInfo.h + +#ifndef ZIP7_INC_WINDOWS_SYSTEM_INFO_H +#define ZIP7_INC_WINDOWS_SYSTEM_INFO_H + +#include "../Common/MyString.h" + + +void GetCpuName_MultiLine(AString &s, AString ®isters); + +void GetOsInfoText(AString &sRes); +void GetSystemInfoText(AString &s); +void PrintSize_KMGT_Or_Hex(AString &s, UInt64 v); +void Add_LargePages_String(AString &s); + +void GetCompiler(AString &s); +void GetVirtCpuid(AString &s); + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/Thread.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Thread.h --- p7zip-rar-16.02/CPP/Windows/Thread.h 2010-05-29 16:13:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Thread.h 2025-06-30 15:00:00.000000000 +0000 @@ -1,41 +1,46 @@ -// Windows/Thread.h - -#ifndef __WINDOWS_THREAD_H -#define __WINDOWS_THREAD_H - -#include "Defs.h" - -extern "C" -{ -#include "../../C/Threads.h" -} - -namespace NWindows { - -class CThread -{ - ::CThread thread; -public: - CThread() { Thread_Construct(&thread); } - ~CThread() { Close(); } - bool IsCreated() { return Thread_WasCreated(&thread) != 0; } - WRes Close() { return Thread_Close(&thread); } - WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) - { return Thread_Create(&thread, startAddress, parameter); } - WRes Wait() { return Thread_Wait(&thread); } - - #ifdef _WIN32 - operator HANDLE() { return thread; } - void Attach(HANDLE handle) { thread = handle; } - HANDLE Detach() { HANDLE h = thread; thread = NULL; return h; } - DWORD Resume() { return ::ResumeThread(thread); } - DWORD Suspend() { return ::SuspendThread(thread); } - bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread, exitCode)); } - int GetPriority() { return ::GetThreadPriority(thread); } - bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread, priority)); } - #endif -}; - -} - -#endif +// Windows/Thread.h + +#ifndef ZIP7_INC_WINDOWS_THREAD_H +#define ZIP7_INC_WINDOWS_THREAD_H + +#include "../../C/Threads.h" + +#include "Defs.h" + +namespace NWindows { + +class CThread MY_UNCOPYABLE +{ + ::CThread thread; +public: + CThread() { Thread_CONSTRUCT(&thread) } + ~CThread() { Close(); } + bool IsCreated() { return Thread_WasCreated(&thread) != 0; } + WRes Close() { return Thread_Close(&thread); } + // WRes Wait() { return Thread_Wait(&thread); } + WRes Wait_Close() { return Thread_Wait_Close(&thread); } + + WRes Create(THREAD_FUNC_TYPE startAddress, LPVOID param) + { return Thread_Create(&thread, startAddress, param); } + WRes Create_With_Affinity(THREAD_FUNC_TYPE startAddress, LPVOID param, CAffinityMask affinity) + { return Thread_Create_With_Affinity(&thread, startAddress, param, affinity); } + WRes Create_With_CpuSet(THREAD_FUNC_TYPE startAddress, LPVOID param, const CCpuSet *cpuSet) + { return Thread_Create_With_CpuSet(&thread, startAddress, param, cpuSet); } + +#ifdef _WIN32 + WRes Create_With_Group(THREAD_FUNC_TYPE startAddress, LPVOID param, unsigned group, CAffinityMask affinity = 0) + { return Thread_Create_With_Group(&thread, startAddress, param, group, affinity); } + operator HANDLE() { return thread; } + void Attach(HANDLE handle) { thread = handle; } + HANDLE Detach() { HANDLE h = thread; thread = NULL; return h; } + DWORD Resume() { return ::ResumeThread(thread); } + DWORD Suspend() { return ::SuspendThread(thread); } + bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread, exitCode)); } + int GetPriority() { return ::GetThreadPriority(thread); } + bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread, priority)); } +#endif +}; + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/Windows/TimeUtils.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.cpp --- p7zip-rar-16.02/CPP/Windows/TimeUtils.cpp 2015-01-05 18:38:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.cpp 2025-06-12 08:00:00.000000000 +0000 @@ -1,203 +1,467 @@ -// Windows/TimeUtils.cpp - -#include "StdAfx.h" - -#include "Defs.h" -#include "TimeUtils.h" - -namespace NWindows { -namespace NTime { - -static const UInt32 kNumTimeQuantumsInSecond = 10000000; -static const UInt32 kFileTimeStartYear = 1601; -static const UInt32 kDosTimeStartYear = 1980; -static const UInt32 kUnixTimeStartYear = 1970; -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() -{ - #if defined(_WIN32) && !defined(UNDER_CE) - return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &ft)); - #else - ft.dwLowDateTime = 0; - ft.dwHighDateTime = 0; - UInt64 res; - if (!GetSecondsSince1601(kDosTimeStartYear + (dosTime >> 25), (dosTime >> 21) & 0xF, (dosTime >> 16) & 0x1F, - (dosTime >> 11) & 0x1F, (dosTime >> 5) & 0x3F, (dosTime & 0x1F) * 2, res)) - return false; - res *= kNumTimeQuantumsInSecond; - ft.dwLowDateTime = (UInt32)res; - ft.dwHighDateTime = (UInt32)(res >> 32); - return true; - #endif -} - -static const UInt32 kHighDosTime = 0xFF9FBF7D; -static const UInt32 kLowDosTime = 0x210000; - -#define PERIOD_4 (4 * 365 + 1) -#define PERIOD_100 (PERIOD_4 * 25 - 1) -#define PERIOD_400 (PERIOD_100 * 4 + 1) - -bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime) throw() -{ - #if defined(_WIN32) && !defined(UNDER_CE) - - WORD datePart, timePart; - if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart)) - { - dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime; - return false; - } - dosTime = (((UInt32)datePart) << 16) + timePart; - - #else - - unsigned year, mon, day, hour, min, sec; - UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); - Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - unsigned temp; - UInt32 v; - v64 += (kNumTimeQuantumsInSecond * 2 - 1); - v64 /= kNumTimeQuantumsInSecond; - sec = (unsigned)(v64 % 60); - v64 /= 60; - min = (unsigned)(v64 % 60); - v64 /= 60; - hour = (unsigned)(v64 % 24); - v64 /= 24; - - v = (UInt32)v64; - - year = (unsigned)(kFileTimeStartYear + v / PERIOD_400 * 400); - v %= PERIOD_400; - - temp = (unsigned)(v / PERIOD_100); - if (temp == 4) - temp = 3; - year += temp * 100; - v -= temp * PERIOD_100; - - temp = v / PERIOD_4; - if (temp == 25) - temp = 24; - year += temp * 4; - v -= temp * PERIOD_4; - - temp = v / 365; - if (temp == 4) - temp = 3; - year += temp; - v -= temp * 365; - - if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) - ms[1] = 29; - for (mon = 1; mon <= 12; mon++) - { - unsigned s = ms[mon - 1]; - if (v < s) - break; - v -= s; - } - day = (unsigned)v + 1; - - dosTime = kLowDosTime; - if (year < kDosTimeStartYear) - return false; - year -= kDosTimeStartYear; - dosTime = kHighDosTime; - if (year >= 128) - return false; - dosTime = (year << 25) | (mon << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec >> 1); - #endif - return true; -} - -void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft) throw() -{ - UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond; - ft.dwLowDateTime = (DWORD)v; - ft.dwHighDateTime = (DWORD)(v >> 32); -} - -bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft) throw() -{ - if (unixTime > kNumSecondsInFileTime - kUnixTimeOffset) - { - ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1; - return false; - } - Int64 v = (Int64)kUnixTimeOffset + unixTime; - if (v < 0) - { - ft.dwLowDateTime = ft.dwHighDateTime = 0; - return false; - } - UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond; - ft.dwLowDateTime = (DWORD)v2; - ft.dwHighDateTime = (DWORD)(v2 >> 32); - return true; -} - -Int64 FileTimeToUnixTime64(const FILETIME &ft) throw() -{ - UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; - return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset; -} - -bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime) throw() -{ - UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; - winTime /= kNumTimeQuantumsInSecond; - if (winTime < kUnixTimeOffset) - { - unixTime = 0; - return false; - } - winTime -= kUnixTimeOffset; - if (winTime > 0xFFFFFFFF) - { - unixTime = 0xFFFFFFFF; - return false; - } - unixTime = (UInt32)winTime; - return true; -} - -bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, - unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw() -{ - resSeconds = 0; - if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 || - day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) - return false; - UInt32 numYears = year - kFileTimeStartYear; - UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400; - Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) - ms[1] = 29; - month--; - for (unsigned i = 0; i < month; i++) - numDays += ms[i]; - numDays += day - 1; - resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; - return true; -} - -void GetCurUtcFileTime(FILETIME &ft) throw() -{ - // Both variants provide same low resolution on WinXP: about 15 ms. - // But GetSystemTimeAsFileTime is much faster. - - #ifdef UNDER_CE - SYSTEMTIME st; - GetSystemTime(&st); - SystemTimeToFileTime(&st, &ft); - #else - GetSystemTimeAsFileTime(&ft); - #endif -} - -}} +// Windows/TimeUtils.cpp + +#include "StdAfx.h" + +#ifndef _WIN32 +#include +#include +#endif + +#include "Defs.h" +#include "TimeUtils.h" + +namespace NWindows { +namespace NTime { + +static const UInt32 kNumTimeQuantumsInSecond = 10000000; +static const unsigned kFileTimeStartYear = 1601; +#if !defined(_WIN32) || defined(UNDER_CE) +static const unsigned kDosTimeStartYear = 1980; +#endif +static const unsigned kUnixTimeStartYear = 1970; +static const UInt64 kUnixTimeOffset = + (UInt64)60 * 60 * 24 * (89 + 365 * (UInt32)(kUnixTimeStartYear - kFileTimeStartYear)); +static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond; + +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)); + #else + ft.dwLowDateTime = 0; + ft.dwHighDateTime = 0; + UInt64 res; + if (!GetSecondsSince1601( + kDosTimeStartYear + (unsigned)(dosTime >> 25), + (unsigned)((dosTime >> 21) & 0xF), + (unsigned)((dosTime >> 16) & 0x1F), + (unsigned)((dosTime >> 11) & 0x1F), + (unsigned)((dosTime >> 5) & 0x3F), + (unsigned)((dosTime & 0x1F)) * 2, + res)) + return false; + res *= kNumTimeQuantumsInSecond; + ft.dwLowDateTime = (UInt32)res; + ft.dwHighDateTime = (UInt32)(res >> 32); + return true; + #endif +} + +static const UInt32 kHighDosTime = 0xFF9FBF7D; +static const UInt32 kLowDosTime = 0x210000; + +bool FileTime_To_DosTime(const FILETIME &ft, UInt32 &dosTime) throw() +{ + #if defined(_WIN32) && !defined(UNDER_CE) + + WORD datePart, timePart; + if (!::FileTimeToDosDateTime(&ft, &datePart, &timePart)) + { + dosTime = (ft.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime; + return false; + } + dosTime = (((UInt32)datePart) << 16) + timePart; + + #else + +#define PERIOD_4 (4 * 365 + 1) +#define PERIOD_100 (PERIOD_4 * 25 - 1) +#define PERIOD_400 (PERIOD_100 * 4 + 1) + + unsigned year, mon, day, hour, min, sec; + UInt64 v64 = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + unsigned temp; + UInt32 v; + v64 += (kNumTimeQuantumsInSecond * 2 - 1); + v64 /= kNumTimeQuantumsInSecond; + sec = (unsigned)(v64 % 60); + v64 /= 60; + min = (unsigned)(v64 % 60); + v64 /= 60; + hour = (unsigned)(v64 % 24); + v64 /= 24; + + v = (UInt32)v64; + + year = kFileTimeStartYear + (unsigned)(v / PERIOD_400 * 400); + v %= PERIOD_400; + + temp = (unsigned)(v / PERIOD_100); + if (temp == 4) + temp = 3; + year += temp * 100; + v -= temp * PERIOD_100; + + temp = v / PERIOD_4; + if (temp == 25) + temp = 24; + year += temp * 4; + v -= temp * PERIOD_4; + + temp = v / 365; + if (temp == 4) + temp = 3; + year += temp; + v -= temp * 365; + + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + for (mon = 1; mon <= 12; mon++) + { + unsigned s = ms[mon - 1]; + if (v < s) + break; + v -= s; + } + day = (unsigned)v + 1; + + dosTime = kLowDosTime; + if (year < kDosTimeStartYear) + return false; + year -= kDosTimeStartYear; + dosTime = kHighDosTime; + if (year >= 128) + return false; + dosTime = + ((UInt32)year << 25) + | ((UInt32)mon << 21) + | ((UInt32)day << 16) + | ((UInt32)hour << 11) + | ((UInt32)min << 5) + | ((UInt32)sec >> 1); + #endif + return true; +} + + +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 UnixTime_To_FileTime(UInt32 unixTime, FILETIME &ft) throw() +{ + const UInt64 v = UnixTime_To_FileTime64(unixTime); + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} + +UInt64 UnixTime64_To_FileTime64(Int64 unixTime) throw() +{ + return (UInt64)((Int64)kUnixTimeOffset + unixTime) * kNumTimeQuantumsInSecond; +} + + +bool UnixTime64_To_FileTime64(Int64 unixTime, UInt64 &fileTime) throw() +{ + if (unixTime > (Int64)(kNumSecondsInFileTime - kUnixTimeOffset)) + { + fileTime = (UInt64)(Int64)-1; + return false; + } + if (unixTime < -(Int64)kUnixTimeOffset) + { + fileTime = 0; + return false; + } + fileTime = UnixTime64_To_FileTime64(unixTime); + return true; +} + + +bool UnixTime64_To_FileTime(Int64 unixTime, FILETIME &ft) throw() +{ + 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 FileTime_To_UnixTime(const FILETIME &ft, UInt32 &unixTime) throw() +{ + UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime; + winTime /= kNumTimeQuantumsInSecond; + if (winTime < kUnixTimeOffset) + { + unixTime = 0; + return false; + } + winTime -= kUnixTimeOffset; + if (winTime > (UInt32)0xFFFFFFFF) + { + unixTime = (UInt32)0xFFFFFFFF; + return false; + } + unixTime = (UInt32)winTime; + return true; +} + +bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, + unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw() +{ + resSeconds = 0; + if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 || + day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) + return false; + const unsigned numYears = year - kFileTimeStartYear; + UInt32 numDays = (UInt32)((UInt32)numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400); + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + month--; + for (unsigned i = 0; i < month; i++) + numDays += ms[i]; + numDays += (UInt32)(day - 1); + resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; + return true; +} + + +/* docs: TIME_UTC is not defined on many platforms: + glibc 2.15, macOS 10.13 + FreeBSD 11.0, NetBSD 7.1, OpenBSD 6.0, + Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, + Cygwin 2.9, mingw, MSVC 14, Android 9.0. + Android NDK defines TIME_UTC but doesn't have the timespec_get(). +*/ +#if defined(TIME_UTC) && !defined(__ANDROID__) +#define ZIP7_USE_timespec_get +// #pragma message("ZIP7_USE_timespec_get") +#elif defined(CLOCK_REALTIME) +#define ZIP7_USE_clock_gettime +// #pragma message("ZIP7_USE_clock_gettime") +#endif + +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 UNDER_CE + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + #else + GetSystemTimeAsFileTime(&ft); + #endif + + #else + + FiTime_Clear(ft); +#ifdef ZIP7_USE_timespec_get + timespec_get(&ft, TIME_UTC); +#elif defined ZIP7_USE_clock_gettime + +#if defined(_AIX) + { + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ft.tv_sec = ts.tv_sec; + ft.tv_nsec = ts.tv_nsec; + } +#else + clock_gettime(CLOCK_REALTIME, &ft); +#endif + +#else + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + { + ft.tv_sec = now.tv_sec; + // timeval::tv_usec can be 64-bit signed in some cases + // timespec::tv_nsec can be 32-bit signed in some cases + ft.tv_nsec = + (Int32) // to eliminate compiler conversion error + (now.tv_usec * 1000); + } +#endif + + #endif +} + +#ifndef _WIN32 +void GetCurUtcFileTime(FILETIME &ft) throw() +{ + UInt64 v = 0; +#if defined(ZIP7_USE_timespec_get) || \ + defined(ZIP7_USE_clock_gettime) + timespec ts; +#if defined(ZIP7_USE_timespec_get) + if (timespec_get(&ts, TIME_UTC)) +#else + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) +#endif + { + v = ((UInt64)ts.tv_sec + kUnixTimeOffset) * + kNumTimeQuantumsInSecond + (UInt64)ts.tv_nsec / 100; + } +#else + struct timeval now; + if (gettimeofday(&now, NULL) == 0) + { + v = ((UInt64)now.tv_sec + kUnixTimeOffset) * + kNumTimeQuantumsInSecond + (UInt64)now.tv_usec * 10; + } +#endif + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); +} +#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, CFiTime &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 = (Int32)(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 -Nru p7zip-rar-16.02/CPP/Windows/TimeUtils.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.h --- p7zip-rar-16.02/CPP/Windows/TimeUtils.h 2015-09-01 18:04:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/TimeUtils.h 2023-01-10 17:00:00.000000000 +0000 @@ -1,24 +1,146 @@ -// Windows/TimeUtils.h - -#ifndef __WINDOWS_TIME_UTILS_H -#define __WINDOWS_TIME_UTILS_H - -#include "../Common/MyTypes.h" -#include "../Common/MyWindows.h" - -namespace NWindows { -namespace NTime { - -bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) throw(); -bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) throw(); -void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) throw(); -bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime) throw(); -bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) throw(); -Int64 FileTimeToUnixTime64(const FILETIME &ft) throw(); -bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, - unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) throw(); -void GetCurUtcFileTime(FILETIME &ft) throw(); - -}} - -#endif +// Windows/TimeUtils.h + +#ifndef ZIP7_INC_WINDOWS_TIME_UTILS_H +#define ZIP7_INC_WINDOWS_TIME_UTILS_H + +#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 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 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 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(); + +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 -Nru p7zip-rar-16.02/CPP/Windows/Window.cpp p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.cpp --- p7zip-rar-16.02/CPP/Windows/Window.cpp 2014-12-28 15:03:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.cpp 2023-01-01 08:00:00.000000000 +0000 @@ -1,101 +1,179 @@ -// Windows/Window.cpp - -#include "StdAfx.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWidgets headers) -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#undef _WIN32 - -#ifndef _UNICODE -#include "Common/StringConvert.h" -#endif -#include "Windows/Window.h" - -void verify_main_thread(void); - -class LockGUI -{ - bool _IsMain; - public: - LockGUI() { - verify_main_thread(); - - _IsMain = wxThread::IsMain(); - if (!_IsMain) { - printf("LockGUI-Windows\n"); - abort(); // FIXME wxMutexGuiEnter(); - } - } - ~LockGUI() { if (!_IsMain) wxMutexGuiLeave(); } -}; - -namespace NWindows { - -HWND GetDlgItem(HWND dialogWindow, int ControlID) -{ - LockGUI lock; - if (dialogWindow) return dialogWindow->FindWindow(ControlID); - return 0; -} - -void MySetWindowText(HWND wnd, LPCWSTR s) -{ - if (wnd == 0) return; - - LockGUI lock; - - wxString str = s; - /* - int id = wnd->GetId(); - if ( (id != wxID_OK) && (id != wxID_CANCEL) && (id != wxID_HELP) && (id != wxID_YES) && (id != wxID_NO)) - */ - { - wnd->SetLabel(str); - } -} - - bool CWindow::GetText(CSysString &s) - { - wxString str; - { - LockGUI lock; - str = _window->GetLabel(); - } - s = str; - return true; - } - - bool CWindow::IsEnabled() - { - LockGUI lock; - return _window->IsEnabled(); - } -} - -////////////////////////////////// Windows Compatibility -#include - -void Sleep(unsigned millisec) -{ - wxMilliSleep(millisec); -} - -t_processID GetCurrentProcess(void) { - return getpid(); -} - -void SetPriorityClass(t_processID pid , int priority) { - setpriority(PRIO_PROCESS,pid,priority); -} - +// Windows/Window.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../Common/StringConvert.h" +#endif +#include "Window.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass) +{ + if (g_IsNT) + return RegisterClassW(wndClass); + WNDCLASSA wndClassA; + wndClassA.style = wndClass->style; + wndClassA.lpfnWndProc = wndClass->lpfnWndProc; + wndClassA.cbClsExtra = wndClass->cbClsExtra; + wndClassA.cbWndExtra = wndClass->cbWndExtra; + wndClassA.hInstance = wndClass->hInstance; + wndClassA.hIcon = wndClass->hIcon; + wndClassA.hCursor = wndClass->hCursor; + wndClassA.hbrBackground = wndClass->hbrBackground; + AString menuName; + AString className; + if (IS_INTRESOURCE(wndClass->lpszMenuName)) + wndClassA.lpszMenuName = (LPCSTR)wndClass->lpszMenuName; + else + { + menuName = GetSystemString(wndClass->lpszMenuName); + wndClassA.lpszMenuName = menuName; + } + if (IS_INTRESOURCE(wndClass->lpszClassName)) + wndClassA.lpszClassName = (LPCSTR)wndClass->lpszClassName; + else + { + className = GetSystemString(wndClass->lpszClassName); + wndClassA.lpszClassName = className; + } + return RegisterClassA(&wndClassA); +} + +bool CWindow::Create(LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) +{ + if (g_IsNT) + { + _window = ::CreateWindowW(className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + return Create(GetSystemString(className), GetSystemString(windowName), + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); +} + +bool CWindow::CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) +{ + if (g_IsNT) + { + _window = ::CreateWindowExW(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + AString classNameA; + LPCSTR classNameP; + if (IS_INTRESOURCE(className)) + classNameP = (LPCSTR)className; + else + { + classNameA = GetSystemString(className); + classNameP = classNameA; + } + AString windowNameA; + LPCSTR windowNameP; + if (IS_INTRESOURCE(windowName)) + windowNameP = (LPCSTR)windowName; + else + { + windowNameA = GetSystemString(windowName); + windowNameP = windowNameA; + } + return CreateEx(exStyle, classNameP, windowNameP, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); +} + +#endif + +#ifndef _UNICODE +bool MySetWindowText(HWND wnd, LPCWSTR s) +{ + if (g_IsNT) + return BOOLToBool(::SetWindowTextW(wnd, s)); + return BOOLToBool(::SetWindowTextA(wnd, UnicodeStringToMultiByte(s))); +} +#endif + +bool CWindow::GetText(CSysString &s) const +{ + s.Empty(); + unsigned len = (unsigned)GetTextLength(); + if (len == 0) + return (::GetLastError() == ERROR_SUCCESS); + TCHAR *p = s.GetBuf(len); + { + const unsigned len2 = (unsigned)GetText(p, (int)(len + 1)); + if (len > len2) + len = len2; + } + s.ReleaseBuf_CalcLen(len); + if (len == 0) + return (::GetLastError() == ERROR_SUCCESS); + return true; +} + +#ifndef _UNICODE +bool CWindow::GetText(UString &s) const +{ + if (g_IsNT) + { + s.Empty(); + unsigned len = (unsigned)GetWindowTextLengthW(_window); + if (len == 0) + return (::GetLastError() == ERROR_SUCCESS); + wchar_t *p = s.GetBuf(len); + { + const unsigned len2 = (unsigned)GetWindowTextW(_window, p, (int)(len + 1)); + if (len > len2) + len = len2; + } + s.ReleaseBuf_CalcLen(len); + if (len == 0) + return (::GetLastError() == ERROR_SUCCESS); + return true; + } + CSysString sysString; + const bool result = GetText(sysString); + MultiByteToUnicodeString2(s, sysString); + return result; +} +#endif + + +/* +bool CWindow::ModifyStyleBase(int styleOffset, + DWORD remove, DWORD add, UINT flags) +{ + DWORD style = GetWindowLong(styleOffset); + DWORD newStyle = (style & ~remove) | add; + if (style == newStyle) + return false; // it is not good + + SetWindowLong(styleOffset, newStyle); + if (flags != 0) + { + ::SetWindowPos(_window, NULL, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | flags); + } + return TRUE; +} +*/ + +} diff -Nru p7zip-rar-16.02/CPP/Windows/Window.h p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.h --- p7zip-rar-16.02/CPP/Windows/Window.h 2015-10-03 18:04:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/Windows/Window.h 2023-03-21 12:00:00.000000000 +0000 @@ -1,43 +1,363 @@ -// Windows/Window.h - -#ifndef __WINDOWS_WINDOW_H -#define __WINDOWS_WINDOW_H - -#include "Windows/Defs.h" -#include "Common/MyString.h" - -namespace NWindows { - -HWND GetDlgItem(HWND dialogWindow, int ControlID); -void MySetWindowText(HWND wnd, LPCWSTR s); - -class CWindow -{ -private: - // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags); -protected: - HWND _window; -public: - CWindow(HWND newWindow = NULL): _window(newWindow){}; - CWindow& operator=(HWND newWindow) - { - _window = newWindow; - return *this; - } - operator HWND() const { return _window; } - void Attach(HWND newWindow) { _window = newWindow; } - HWND Detach() - { - HWND window = _window; - _window = NULL; - return window; - } - virtual void SetText(LPCWSTR s) { MySetWindowText(_window, s); } - virtual bool GetText(CSysString &s); - bool IsEnabled(); -}; - -} - -#endif - +// Windows/Window.h + +#ifndef ZIP7_INC_WINDOWS_WINDOW_H +#define ZIP7_INC_WINDOWS_WINDOW_H + +#include "../Common/MyWindows.h" +#include "../Common/MyString.h" + +#include "Defs.h" + +#ifndef UNDER_CE +#ifdef WM_CHANGEUISTATE +#define Z7_WIN_WM_CHANGEUISTATE WM_CHANGEUISTATE +#define Z7_WIN_WM_UPDATEUISTATE WM_UPDATEUISTATE +#define Z7_WIN_WM_QUERYUISTATE WM_QUERYUISTATE +#else +// these are defined for (_WIN32_WINNT >= 0x0500): +#define Z7_WIN_WM_CHANGEUISTATE 0x0127 +#define Z7_WIN_WM_UPDATEUISTATE 0x0128 +#define Z7_WIN_WM_QUERYUISTATE 0x0129 +#endif + +#ifdef UIS_SET + +#define Z7_WIN_UIS_SET UIS_SET +#define Z7_WIN_UIS_CLEAR UIS_CLEAR +#define Z7_WIN_UIS_INITIALIZE UIS_INITIALIZE + +#define Z7_WIN_UISF_HIDEFOCUS UISF_HIDEFOCUS +#define Z7_WIN_UISF_HIDEACCEL UISF_HIDEACCEL + +#else +// these are defined for (_WIN32_WINNT >= 0x0500): +// LOWORD(wParam) values in WM_*UISTATE +#define Z7_WIN_UIS_SET 1 +#define Z7_WIN_UIS_CLEAR 2 +#define Z7_WIN_UIS_INITIALIZE 3 + +// HIWORD(wParam) values in WM_*UISTATE +#define Z7_WIN_UISF_HIDEFOCUS 0x1 +#define Z7_WIN_UISF_HIDEACCEL 0x2 +// defined for for (_WIN32_WINNT >= 0x0501): +// #define Z7_WIN_UISF_ACTIVE 0x4 + +#endif + +#endif // UNDER_CE + + +#ifdef Z7_OLD_WIN_SDK + +// #define VK_OEM_1 0xBA // ';:' for US +#define VK_OEM_PLUS 0xBB // '+' any country +// #define VK_OEM_COMMA 0xBC // ',' any country +#define VK_OEM_MINUS 0xBD // '-' any country +// #define VK_OEM_PERIOD 0xBE // '.' any country +// #define VK_OEM_2 0xBF // '/?' for US +// #define VK_OEM_3 0xC0 // '`~' for US + +// #ifndef GWLP_USERDATA +#define GWLP_WNDPROC (-4) +#define GWLP_USERDATA (-21) +// #endif +#define DWLP_MSGRESULT 0 +// #define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT) +// #define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC) + +#define BTNS_BUTTON TBSTYLE_BUTTON // 0x0000 + +/* +vc6 defines INT_PTR via long: + typedef long INT_PTR, *PINT_PTR; + typedef unsigned long UINT_PTR, *PUINT_PTR; +but newer sdk (sdk2003+) defines INT_PTR via int: + typedef _W64 int INT_PTR, *PINT_PTR; + typedef _W64 unsigned int UINT_PTR, *PUINT_PTR; +*/ + +#define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) + +#define GetWindowLongPtrA GetWindowLongA +#define GetWindowLongPtrW GetWindowLongW +#ifdef UNICODE +#define GetWindowLongPtr GetWindowLongPtrW +#else +#define GetWindowLongPtr GetWindowLongPtrA +#endif // !UNICODE + +#define SetWindowLongPtrA SetWindowLongA +#define SetWindowLongPtrW SetWindowLongW +#ifdef UNICODE +#define SetWindowLongPtr SetWindowLongPtrW +#else +#define SetWindowLongPtr SetWindowLongPtrA +#endif // !UNICODE + +#define ListView_SetCheckState(hwndLV, i, fCheck) \ + ListView_SetItemState(hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck)?2:1), LVIS_STATEIMAGEMASK) + +#endif // Z7_OLD_WIN_SDK + +inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); } + +#define MY_int_TO_WPARAM(i) ((WPARAM)(INT_PTR)(i)) + +namespace NWindows { + +inline ATOM MyRegisterClass(CONST WNDCLASS *wndClass) + { return ::RegisterClass(wndClass); } + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); +#endif + +#ifdef _UNICODE +inline bool MySetWindowText(HWND wnd, LPCWSTR s) { return BOOLToBool(::SetWindowText(wnd, s)); } +#else +bool MySetWindowText(HWND wnd, LPCWSTR s); +#endif + + +#ifdef UNDER_CE +#define GWLP_USERDATA GWL_USERDATA +#define GWLP_WNDPROC GWL_WNDPROC +#define BTNS_BUTTON TBSTYLE_BUTTON +#define WC_COMBOBOXW L"ComboBox" +#define DWLP_MSGRESULT DWL_MSGRESULT +#endif + +class CWindow +{ + Z7_CLASS_NO_COPY(CWindow) +private: + // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags); +protected: + HWND _window; +public: + CWindow(HWND newWindow = NULL): _window(newWindow) {} + CWindow& operator=(HWND newWindow) + { + _window = newWindow; + return *this; + } + operator HWND() const { return _window; } + void Attach(HWND newWindow) { _window = newWindow; } + HWND Detach() + { + HWND window = _window; + _window = NULL; + return window; + } + + bool Foreground() { return BOOLToBool(::SetForegroundWindow(_window)); } + + HWND GetParent() const { return ::GetParent(_window); } + bool GetWindowRect(LPRECT rect) const { return BOOLToBool(::GetWindowRect(_window,rect)); } + #ifndef UNDER_CE + bool IsZoomed() const { return BOOLToBool(::IsZoomed(_window)); } + #endif + bool ClientToScreen(LPPOINT point) const { return BOOLToBool(::ClientToScreen(_window, point)); } + bool ScreenToClient(LPPOINT point) const { return BOOLToBool(::ScreenToClient(_window, point)); } + + bool CreateEx(DWORD exStyle, LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) + { + _window = ::CreateWindowEx(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + + bool Create(LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam) + { + _window = ::CreateWindow(className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, createParam); + return (_window != NULL); + } + + #ifndef _UNICODE + bool Create(LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam); + bool CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance, LPVOID createParam); + #endif + + + bool Destroy() + { + if (_window == NULL) + return true; + bool result = BOOLToBool(::DestroyWindow(_window)); + if (result) + _window = NULL; + return result; + } + bool IsWindow() { return BOOLToBool(::IsWindow(_window)); } + bool Move(int x, int y, int width, int height, bool repaint = true) + { return BOOLToBool(::MoveWindow(_window, x, y, width, height, BoolToBOOL(repaint))); } + + bool ChangeSubWindowSizeX(HWND hwnd, int xSize) + { + RECT rect; + ::GetWindowRect(hwnd, &rect); + POINT p1; + p1.x = rect.left; + p1.y = rect.top; + ScreenToClient(&p1); + return BOOLToBool(::MoveWindow(hwnd, p1.x, p1.y, xSize, rect.bottom - rect.top, TRUE)); + } + + void ScreenToClient(RECT *rect) + { + POINT p1, p2; + p1.x = rect->left; + p1.y = rect->top; + p2.x = rect->right; + p2.y = rect->bottom; + ScreenToClient(&p1); + ScreenToClient(&p2); + + rect->left = p1.x; + rect->top = p1.y; + rect->right = p2.x; + rect->bottom = p2.y; + } + + bool GetClientRect(LPRECT rect) { return BOOLToBool(::GetClientRect(_window, rect)); } + bool Show(int cmdShow) { return BOOLToBool(::ShowWindow(_window, cmdShow)); } + bool Show_Bool(bool show) { return Show(show ? SW_SHOW: SW_HIDE); } + + #ifndef UNDER_CE + bool SetPlacement(CONST WINDOWPLACEMENT *placement) { return BOOLToBool(::SetWindowPlacement(_window, placement)); } + bool GetPlacement(WINDOWPLACEMENT *placement) { return BOOLToBool(::GetWindowPlacement(_window, placement)); } + #endif + bool Update() { return BOOLToBool(::UpdateWindow(_window)); } + bool InvalidateRect(LPCRECT rect, bool backgroundErase = true) + { return BOOLToBool(::InvalidateRect(_window, rect, BoolToBOOL(backgroundErase))); } + void SetRedraw(bool redraw = true) { SendMsg(WM_SETREDRAW, (WPARAM)BoolToBOOL(redraw), 0); } + + LONG_PTR SetStyle(LONG_PTR style) { return SetLongPtr(GWL_STYLE, style); } + // LONG_PTR SetStyle(DWORD style) { return SetLongPtr(GWL_STYLE, (LONG_PTR)style); } + LONG_PTR GetStyle() const { return GetLongPtr(GWL_STYLE); } + // bool MyIsMaximized() const { return ((GetStyle() & WS_MAXIMIZE) != 0); } + + LONG_PTR SetLong(int index, LONG newLongPtr) { return ::SetWindowLong(_window, index, newLongPtr); } + LONG_PTR GetLong(int index) const { return ::GetWindowLong(_window, index); } + LONG_PTR SetUserDataLong(LONG newLongPtr) { return SetLong(GWLP_USERDATA, newLongPtr); } + LONG_PTR GetUserDataLong() const { return GetLong(GWLP_USERDATA); } + + + #ifdef UNDER_CE + + LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr) { return SetLong(index, newLongPtr); } + LONG_PTR GetLongPtr(int index) const { return GetLong(index); } + + LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetUserDataLong(newLongPtr); } + LONG_PTR GetUserDataLongPtr() const { return GetUserDataLong(); } + + #else + + LONG_PTR SetLongPtr(int index, LONG_PTR newLongPtr) + { return ::SetWindowLongPtr(_window, index, + #ifndef _WIN64 + (LONG) + #endif + newLongPtr); } + #ifndef _UNICODE + LONG_PTR SetLongPtrW(int index, LONG_PTR newLongPtr) + { return ::SetWindowLongPtrW(_window, index, + #ifndef _WIN64 + (LONG) + #endif + newLongPtr); } + #endif + + LONG_PTR GetLongPtr(int index) const { return ::GetWindowLongPtr(_window, index); } + LONG_PTR SetUserDataLongPtr(LONG_PTR newLongPtr) { return SetLongPtr(GWLP_USERDATA, newLongPtr); } + LONG_PTR GetUserDataLongPtr() const { return GetLongPtr(GWLP_USERDATA); } + + #endif + + /* + bool ModifyStyle(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0) + { return ModifyStyleBase(GWL_STYLE, remove, add, flags); } + bool ModifyStyleEx(HWND hWnd, DWORD remove, DWORD add, UINT flags = 0) + { return ModifyStyleBase(GWL_EXSTYLE, remove, add, flags); } + */ + + HWND SetFocus() { return ::SetFocus(_window); } + + LRESULT SendMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return ::SendMessage(_window, message, wParam, lParam); } + #ifndef _UNICODE + LRESULT SendMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return ::SendMessageW(_window, message, wParam, lParam); } + #endif + + bool PostMsg(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return BOOLToBool(::PostMessage(_window, message, wParam, lParam)); } + #ifndef _UNICODE + bool PostMsgW(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) + { return BOOLToBool(::PostMessageW(_window, message, wParam, lParam)); } + #endif + + bool SetText(LPCTSTR s) { return BOOLToBool(::SetWindowText(_window, s)); } + #ifndef _UNICODE + bool SetText(LPCWSTR s) { return MySetWindowText(_window, s); } + #endif + + int GetTextLength() const + { return GetWindowTextLength(_window); } + int GetText(LPTSTR string, int maxCount) const + { return GetWindowText(_window, string, maxCount); } + bool GetText(CSysString &s) const; + #ifndef _UNICODE + /* + UINT GetText(LPWSTR string, int maxCount) const + { return GetWindowTextW(_window, string, maxCount); } + */ + bool GetText(UString &s) const; + #endif + + bool Enable(bool enable) + { return BOOLToBool(::EnableWindow(_window, BoolToBOOL(enable))); } + + bool IsEnabled() const + { return BOOLToBool(::IsWindowEnabled(_window)); } + + #ifndef UNDER_CE + HMENU GetSystemMenu(bool revert) + { return ::GetSystemMenu(_window, BoolToBOOL(revert)); } + #endif + + UINT_PTR SetTimer(UINT_PTR idEvent, UINT elapse, TIMERPROC timerFunc = NULL) + { return ::SetTimer(_window, idEvent, elapse, timerFunc); } + bool KillTimer(UINT_PTR idEvent) + {return BOOLToBool(::KillTimer(_window, idEvent)); } + + HICON SetIcon(WPARAM sizeType, HICON icon) { return (HICON)SendMsg(WM_SETICON, sizeType, (LPARAM)icon); } +}; + +#define RECT_SIZE_X(r) ((r).right - (r).left) +#define RECT_SIZE_Y(r) ((r).bottom - (r).top) + +inline bool IsKeyDown(int virtKey) { return (::GetKeyState(virtKey) & 0x8000) != 0; } + +} + +#endif diff -Nru p7zip-rar-16.02/CPP/include_windows/basetyps.h p7zip-rar-16.02+really25.00+ds/CPP/include_windows/basetyps.h --- p7zip-rar-16.02/CPP/include_windows/basetyps.h 2011-07-09 12:25:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/include_windows/basetyps.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -#ifndef _BASETYPS_H -#define _BASETYPS_H - -#ifdef ENV_HAVE_GCCVISIBILITYPATCH - #define DLLEXPORT __attribute__ ((visibility("default"))) -#else - #define DLLEXPORT -#endif - -#ifdef __cplusplus -#define STDAPI extern "C" DLLEXPORT HRESULT -#else -#define STDAPI extern DLLEXPORT HRESULT -#endif /* __cplusplus */ - -typedef GUID IID; -typedef GUID CLSID; -#endif - diff -Nru p7zip-rar-16.02/CPP/include_windows/tchar.h p7zip-rar-16.02+really25.00+ds/CPP/include_windows/tchar.h --- p7zip-rar-16.02/CPP/include_windows/tchar.h 2008-08-05 09:48:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/include_windows/tchar.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/* - * tchar.h - * - * Unicode mapping layer for the standard C library. By including this - * file and using the 't' names for string functions - * (eg. _tprintf) you can make code which can be easily adapted to both - * Unicode and non-unicode environments. In a unicode enabled compile define - * _UNICODE before including tchar.h, otherwise the standard non-unicode - * library functions will be used. - * - * Note that you still need to include string.h or stdlib.h etc. to define - * the appropriate functions. Also note that there are several defines - * included for non-ANSI functions which are commonly available (but using - * the convention of prepending an underscore to non-ANSI library function - * names). - * - * This file is part of the Mingw32 package. - * - * Contributors: - * Created by Colin Peters - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * $Revision: 1.11 $ - * $Author: earnie $ - * $Date: 2003/05/03 13:48:46 $ - * - */ - -#ifndef _TCHAR_H_ -#define _TCHAR_H_ - -/* All the headers include this file. */ -#ifndef __int64 -#define __int64 long long -#endif - -#ifndef __cdecl -#define __cdecl /* */ -#endif - -/* - * NOTE: This tests _UNICODE, which is different from the UNICODE define - * used to differentiate Win32 API calls. - */ -#ifdef _UNICODE - - -/* - * Use TCHAR instead of char or wchar_t. It will be appropriately translated - * if _UNICODE is correctly defined (or not). - */ -#ifndef _TCHAR_DEFINED -typedef wchar_t TCHAR; -#define _TCHAR_DEFINED -#endif - -/* - * Unicode functions - */ -/* -#define _tfopen _wfopen -FILE *_wfopen( const wchar_t *filename, const wchar_t *mode ); -*/ - -#else /* Not _UNICODE */ - -#define _tfopen fopen - -/* - * TCHAR, the type you should use instead of char. - */ -#ifndef _TCHAR_DEFINED -typedef char TCHAR; -#define _TCHAR_DEFINED -#endif - -#endif /* Not _UNICODE */ - -#endif /* Not _TCHAR_H_ */ - diff -Nru p7zip-rar-16.02/CPP/include_windows/windows.h p7zip-rar-16.02+really25.00+ds/CPP/include_windows/windows.h --- p7zip-rar-16.02/CPP/include_windows/windows.h 2015-10-03 18:15:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/include_windows/windows.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -/* - windows.h - main header file for the Win32 API - - Written by Anders Norlander - - This file is part of a free library for the Win32 API. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -*/ -#ifndef _WINDOWS_H -#define _WINDOWS_H - -#include - -/* BEGIN #include */ - -#include "Common/MyWindows.h" // FIXED - -#ifndef CONST -#define CONST const -#endif - -#undef MAX_PATH -#define MAX_PATH 4096 /* Linux : 4096 - Windows : 260 */ - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#define WINAPI - -#undef BOOL -typedef int BOOL; - - -#define CREATE_NEW 1 -#define CREATE_ALWAYS 2 -#define OPEN_EXISTING 3 -#define OPEN_ALWAYS 4 -/* #define TRUNCATE_EXISTING 5 */ - - - -/* BEGIN #include */ -/* BEGIN */ -#define NO_ERROR 0L -#define ERROR_ALREADY_EXISTS EEXIST -#define ERROR_FILE_EXISTS EEXIST -#define ERROR_INVALID_HANDLE EBADF -#define ERROR_PATH_NOT_FOUND ENOENT -#define ERROR_DISK_FULL ENOSPC -#define ERROR_NO_MORE_FILES 0x100018 // FIXME -#define ERROR_DIRECTORY 267 // FIXME - -// #define ERROR_NEGATIVE_SEEK 0x100131 // FIXME - - -/* see Common/WyWindows.h -#define S_OK ((HRESULT)0x00000000L) -#define S_FALSE ((HRESULT)0x00000001L) -#define E_INVALIDARG ((HRESULT)0x80070057L) -#define E_NOTIMPL ((HRESULT)0x80004001L) -#define E_NOINTERFACE ((HRESULT)0x80004002L) -#define E_ABORT ((HRESULT)0x80004004L) -#define E_FAIL ((HRESULT)0x80004005L) -#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) -#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L) -#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0) -#define FAILED(Status) ((HRESULT)(Status)<0) -*/ -#ifndef VOID -#define VOID void -#endif -typedef void *PVOID,*LPVOID; -typedef WCHAR *LPWSTR; -typedef CHAR *LPSTR; -typedef TCHAR *LPTSTR; - -#ifdef UNICODE -/* - * P7ZIP_TEXT is a private macro whose specific use is to force the expansion of a - * macro passed as an argument to the macro TEXT. DO NOT use this - * macro within your programs. It's name and function could change without - * notice. - */ -#define P7ZIP_TEXT(q) L##q -#else -#define P7ZIP_TEXT(q) q -#endif -/* - * UNICODE a constant string when UNICODE is defined, else returns the string - * unmodified. - * The corresponding macros _TEXT() and _T() for mapping _UNICODE strings - * passed to C runtime functions are defined in mingw/tchar.h - */ -#define TEXT(q) P7ZIP_TEXT(q) - -typedef BYTE BOOLEAN; - -/* BEGIN #include */ -#ifndef __int64 -#define __int64 long long -#endif -typedef unsigned __int64 UINT64; -typedef __int64 INT64; -/* END #include */ - -#define FILE_ATTRIBUTE_READONLY 1 -#define FILE_ATTRIBUTE_HIDDEN 2 -#define FILE_ATTRIBUTE_SYSTEM 4 -#define FILE_ATTRIBUTE_DIRECTORY 16 -#define FILE_ATTRIBUTE_ARCHIVE 32 -#define FILE_ATTRIBUTE_DEVICE 64 -#define FILE_ATTRIBUTE_NORMAL 128 -#define FILE_ATTRIBUTE_TEMPORARY 256 -#define FILE_ATTRIBUTE_SPARSE_FILE 512 -#define FILE_ATTRIBUTE_REPARSE_POINT 1024 -#define FILE_ATTRIBUTE_COMPRESSED 2048 -#define FILE_ATTRIBUTE_OFFLINE 0x1000 -#define FILE_ATTRIBUTE_ENCRYPTED 0x4000 -#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */ - -/* END */ - -#include -#include - -/* END #include */ - -/* END #include */ - -/* BEGIN #include */ - -#define WAIT_OBJECT_0 0 -#define INFINITE 0xFFFFFFFF - -typedef struct _SYSTEMTIME { - WORD wYear; - WORD wMonth; - WORD wDayOfWeek; - WORD wDay; - WORD wHour; - WORD wMinute; - WORD wSecond; - WORD wMilliseconds; -} SYSTEMTIME; - -#ifdef __cplusplus -extern "C" { -#endif - -BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,FILETIME *); -BOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *,WORD *, WORD *); -BOOL WINAPI FileTimeToLocalFileTime(CONST FILETIME *,FILETIME *); -BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *,SYSTEMTIME *); -BOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *,FILETIME *); -VOID WINAPI GetSystemTime(SYSTEMTIME *); -BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,FILETIME *); -VOID WINAPI GetSystemTimeAsFileTime(FILETIME * time); - -DWORD WINAPI GetTickCount(VOID); - -#ifdef __cplusplus -} -#endif -/* END #include */ - -/* BEGIN #include */ - -#define CP_ACP 0 -#define CP_OEMCP 1 -#define CP_UTF8 65001 - -/* #include */ -#include - -#ifdef __cplusplus -extern "C" const IID IID_ISequentialStream; -struct ISequentialStream : public IUnknown -{ - STDMETHOD(QueryInterface)(REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(void) PURE; - STDMETHOD_(ULONG,Release)(void) PURE; - STDMETHOD(Read)(void*,ULONG,ULONG*) PURE; - STDMETHOD(Write)(void const*,ULONG,ULONG*) PURE; -}; -#else -extern const IID IID_ISequentialStream; -#endif /* __cplusplus */ - - -/* END #include */ - -#endif - diff -Nru p7zip-rar-16.02/CPP/myWindows/StdAfx.h p7zip-rar-16.02+really25.00+ds/CPP/myWindows/StdAfx.h --- p7zip-rar-16.02/CPP/myWindows/StdAfx.h 2015-10-03 18:34:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,216 +0,0 @@ -// stdafx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - - -#include "config.h" - -#define MAXIMUM_WAIT_OBJECTS 64 - -#define NO_INLINE /* FIXME */ - -#ifdef ENV_HAVE_PTHREAD -#include -#endif - -#include "Common/Common.h" -#include "Common/MyWindows.h" -#include "Common/MyTypes.h" -#include "Common/MyString.h" // FIXME - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __NETWARE__ -#include -#endif - -#undef CS /* fix for Solaris 10 x86 */ - - -#ifdef __cplusplus -# define EXTERN_C extern "C" -#else -# define EXTERN_C extern -#endif - - -/***************************/ - -#ifndef ENV_HAVE_WCHAR__H - -EXTERN_C_BEGIN - -size_t wcslen(const wchar_t *); -wchar_t *wcscpy(wchar_t * , const wchar_t * ); -wchar_t *wcscat(wchar_t * , const wchar_t * ); - -EXTERN_C_END - -#endif - -/***************************/ - -#define CLASS_E_CLASSNOTAVAILABLE ((HRESULT)0x80040111L) - -/************************* LastError *************************/ -inline DWORD WINAPI GetLastError(void) { return errno; } -inline void WINAPI SetLastError( DWORD err ) { errno = err; } - -#define AreFileApisANSI() (1) - -void Sleep(unsigned millisleep); - -typedef pid_t t_processID; - -t_processID GetCurrentProcess(void); - -#define NORMAL_PRIORITY_CLASS (0) -#define IDLE_PRIORITY_CLASS (10) -void SetPriorityClass(t_processID , int priority); - -#ifdef __cplusplus -class wxWindow; -typedef wxWindow *HWND; - -#define MB_ICONERROR (0x00000200) // wxICON_ERROR -#define MB_YESNOCANCEL (0x00000002 | 0x00000008 | 0x00000010) // wxYES | wxNO | wxCANCEL -#define MB_ICONQUESTION (0x00000400) // wxICON_QUESTION -#define MB_TASKMODAL (0) // FIXME -#define MB_SYSTEMMODAL (0) // FIXME - -#define MB_OK (0x00000004) // wxOK -#define MB_ICONSTOP (0x00000200) // wxICON_STOP -#define MB_OKCANCEL (0x00000004 | 0x00000010) // wxOK | wxCANCEL - -#define MessageBox MessageBoxW -int MessageBoxW(wxWindow * parent, const TCHAR * mes, const TCHAR * title,int flag); - - -// FIXME -#define IDCLOSE (5001) // wxID_CLOSE -#define IDEXIT (5006) // wxID_EXIT -#define IDOK (5100) // wxID_OK -#define IDCANCEL (5101) // wxID_CANCEL -#define IDABORT (5115) // wxID_ABORT -#define IDYES (5103) // wxID_YES -#define IDNO (5104) // wxID_NO -#define IDHELP (5009) // wxID_HELP - -// Show -#define SW_HIDE 0 -#define SW_SHOW 5 - - - -typedef void *HINSTANCE; - -// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits) -//typedef int INT_PTR; -typedef long INT_PTR; -// typedef unsigned int UINT_PTR; -typedef unsigned long UINT_PTR; - -typedef long LONG_PTR; -typedef unsigned long DWORD_PTR; - -typedef UINT_PTR WPARAM; - -/* WARNING - LPARAM shall be 'long' because of CListView::SortItems and wxListCtrl::SortItems : -*/ -typedef LONG_PTR LPARAM; -typedef LONG_PTR LRESULT; - - -#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF)) -#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) - - -#define CALLBACK /* */ - -#define ERROR_NEGATIVE_SEEK 0x100131 // FIXME -#define FACILITY_WIN32 7 // FIXME -#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) > 0 ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : (HRESULT)(x) ) // FIXME - -static inline HRESULT HRESULT_FROM_WIN32(unsigned int x) -{ - return (HRESULT)x > 0 ? ((HRESULT) ((x & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : (HRESULT)x; -} - -/************ Windows2.h ***********/ - -typedef void * WNDPROC; -typedef void * CREATESTRUCT; -typedef struct -{ - HWND hwndFrom; - - UINT code; -#define NM_DBLCLK 1 -#define LVN_ITEMCHANGED 2 -#define LVN_COLUMNCLICK 3 -#define CBEN_BEGINEDIT 10 -#define CBEN_ENDEDITW 11 - - -} NMHDR; -typedef NMHDR * LPNMHDR; - -typedef struct tagNMLISTVIEW -{ - NMHDR hdr; - INT iItem; - INT iSubItem; - UINT uNewState; - UINT uOldState; - // UINT uChanged; - // POINT ptAction; - LPARAM lParam; -} NMLISTVIEW, *LPNMLISTVIEW; - -typedef void * LPNMITEMACTIVATE; - -#define NM_RCLICK 1234 /* FIXME */ - -// FIXME -#define WM_CREATE 1 -#define WM_COMMAND 2 -#define WM_NOTIFY 3 -#define WM_DESTROY 4 -#define WM_CLOSE 5 - -#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) -#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF)) - - -/************ LANG ***********/ -typedef WORD LANGID; - -LANGID GetUserDefaultLangID(void); -LANGID GetSystemDefaultLangID(void); - -#define PRIMARYLANGID(l) ((WORD)(l) & 0x3ff) -#define SUBLANGID(l) ((WORD)(l) >> 10) - -#if defined( __x86_64__ ) - -#define _WIN64 1 - -#endif - -#endif - -#endif - diff -Nru p7zip-rar-16.02/CPP/myWindows/config.h p7zip-rar-16.02+really25.00+ds/CPP/myWindows/config.h --- p7zip-rar-16.02/CPP/myWindows/config.h 2016-03-23 19:12:45.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ - -#if !defined(__DJGPP__) - -#ifndef __CYGWIN__ - #define FILESYSTEM_IS_CASE_SENSITIVE 1 -#endif - - #if !defined(ENV_BEOS) - - /* */ - /* ENV_HAVE_WCHAR__H and not ENV_HAVE_WCHAR_H to avoid warning with wxWidgets */ - #define ENV_HAVE_WCHAR__H - - /* */ - #define ENV_HAVE_WCTYPE_H - - /* mbrtowc */ -/* #ifndef __hpux */ -/* #define ENV_HAVE_MBRTOWC */ -/* #endif */ - - /* towupper */ - #define ENV_HAVE_TOWUPPER - - #endif /* !ENV_BEOS */ - - #ifdef ENV_HAIKU /* AFTER !defined(ENV_BEOS) because ENV_HAIKU and ENV_BEOS are defined */ - /* */ - /* ENV_HAVE_WCHAR__H and not ENV_HAVE_WCHAR_H to avoid warning with wxWidgets */ - #define ENV_HAVE_WCHAR__H - - /* */ - #define ENV_HAVE_WCTYPE_H - - /* towupper */ - #define ENV_HAVE_TOWUPPER - #endif - - - - #if !defined(ENV_BEOS) && !defined(ANDROID_NDK) - - #define ENV_HAVE_GETPASS - - #if !defined(sun) - #define ENV_HAVE_TIMEGM - #endif - - #endif - - /* lstat, readlink and S_ISLNK */ - #define ENV_HAVE_LSTAT - - /* */ - #define ENV_HAVE_LOCALE - - /* mbstowcs */ - #define ENV_HAVE_MBSTOWCS - - /* wcstombs */ - #define ENV_HAVE_WCSTOMBS - -#endif /* !__DJGPP__ */ - -#ifndef ENV_BEOS -#define ENV_HAVE_PTHREAD -#endif - -/* ANDROID don't have wcstombs or mbstowcs ? */ -#if defined(ENV_MACOSX) || defined(ANDROID_NDK) -#define LOCALE_IS_UTF8 -#endif - -#ifdef LOCALE_IS_UTF8 -#undef ENV_HAVE_LOCALE -#undef ENV_HAVE_MBSTOWCS -#undef ENV_HAVE_WCSTOMBS -/* #undef ENV_HAVE_MBRTOWC */ -#endif - -#define MAX_PATHNAME_LEN 1024 - diff -Nru p7zip-rar-16.02/CPP/myWindows/initguid.h p7zip-rar-16.02+really25.00+ds/CPP/myWindows/initguid.h --- p7zip-rar-16.02/CPP/myWindows/initguid.h 2008-08-07 16:42:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/initguid.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -// initguid.h - -#include "Common/MyInitGuid.h" - diff -Nru p7zip-rar-16.02/CPP/myWindows/makefile p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile --- p7zip-rar-16.02/CPP/myWindows/makefile 2016-03-10 20:24:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -PROG=test_lib - -LOCAL_FLAGS=-I. -I.. -I../include_windows -DUNICODE -D_UNICODE - -include ../../makefile.crc32 -include ../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -OBJS= \ - wine_date_and_time.o \ - mySplitCommandLine.o \ - myAddExeFlag.o \ - wine_GetXXXDefaultLangID.o \ - test_lib.o \ - MyVector.o \ - MyString.o \ - MyWindows.o \ - CpuArch.o - -include ../../makefile.glb - diff -Nru p7zip-rar-16.02/CPP/myWindows/makefile.list p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile.list --- p7zip-rar-16.02/CPP/myWindows/makefile.list 2016-02-27 21:28:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - -all: $(PCH_NAME) $(PROG) - -SRCS= \ - mySplitCommandLine.cpp \ - myAddExeFlag.cpp \ - test_lib.cpp \ - wine_date_and_time.cpp \ - wine_GetXXXDefaultLangID.cpp \ - ../Common/MyVector.cpp \ - ../Common/MyString.cpp \ - ../Common/MyWindows.cpp - -StdAfx.h.gch : StdAfx.h - rm -f StdAfx.h.gch - $(CXX) $(CXXFLAGS) StdAfx.h -o StdAfx.h.gch - -mySplitCommandLine.o : mySplitCommandLine.cpp - $(CXX) $(CXXFLAGS) mySplitCommandLine.cpp -myAddExeFlag.o : myAddExeFlag.cpp - $(CXX) $(CXXFLAGS) myAddExeFlag.cpp -test_lib.o : test_lib.cpp - $(CXX) $(CXXFLAGS) test_lib.cpp -wine_date_and_time.o : wine_date_and_time.cpp - $(CXX) $(CXXFLAGS) wine_date_and_time.cpp -wine_GetXXXDefaultLangID.o : wine_GetXXXDefaultLangID.cpp - $(CXX) $(CXXFLAGS) wine_GetXXXDefaultLangID.cpp -MyVector.o : ../Common/MyVector.cpp - $(CXX) $(CXXFLAGS) ../Common/MyVector.cpp -MyString.o : ../Common/MyString.cpp - $(CXX) $(CXXFLAGS) ../Common/MyString.cpp -MyWindows.o : ../Common/MyWindows.cpp - $(CXX) $(CXXFLAGS) ../Common/MyWindows.cpp -CpuArch.o : ../../C/CpuArch.c - $(CC) $(CFLAGS) ../../C/CpuArch.c - diff -Nru p7zip-rar-16.02/CPP/myWindows/myAddExeFlag.cpp p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myAddExeFlag.cpp --- p7zip-rar-16.02/CPP/myWindows/myAddExeFlag.cpp 2009-07-14 11:01:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myAddExeFlag.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -#include "StdAfx.h" - -#include -#include - -#include - -#define NEED_NAME_WINDOWS_TO_UNIX -#include "myPrivate.h" - -#include "Common/StringConvert.h" - -void myAddExeFlag(const UString &u_name) -{ - AString filename = UnicodeStringToMultiByte(u_name, CP_ACP); // FIXME - const char * name = nameWindowToUnix(filename); - // printf("myAddExeFlag(%s)\n",name); - chmod(name,0700); -} - diff -Nru p7zip-rar-16.02/CPP/myWindows/myPrivate.h p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myPrivate.h --- p7zip-rar-16.02/CPP/myWindows/myPrivate.h 2015-09-05 20:22:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/myPrivate.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -void WINAPI RtlSecondsSince1970ToFileTime( DWORD Seconds, FILETIME * ft ); - -extern "C" int global_use_utf16_conversion; -#ifdef ENV_HAVE_LSTAT -extern "C" int global_use_lstat; -#endif - -const char *my_getlocale(void); - -#ifdef NEED_NAME_WINDOWS_TO_UNIX -static inline const char * nameWindowToUnix(const char * lpFileName) { - if ((lpFileName[0] == 'c') && (lpFileName[1] == ':')) return lpFileName+2; - return lpFileName; -} - - - -#endif - -// From mySplitCommandLine.cpp -void mySplitCommandLine(int numArguments, char *arguments[],UStringVector &parts); -class CStdOutStream; -void showP7zipInfo(CStdOutStream *so); - diff -Nru p7zip-rar-16.02/CPP/myWindows/mySplitCommandLine.cpp p7zip-rar-16.02+really25.00+ds/CPP/myWindows/mySplitCommandLine.cpp --- p7zip-rar-16.02/CPP/myWindows/mySplitCommandLine.cpp 2015-10-10 12:37:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/mySplitCommandLine.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -#include "StdAfx.h" - -#include "../Common/StringConvert.h" - -#include "myPrivate.h" -#include "Windows/System.h" -#include "7zip/MyVersion.h" -#include "Common/StdOutStream.h" -#include "Common/IntToString.h" -#include "../C/CpuArch.h" - -#ifdef ENV_HAVE_LOCALE -#include -#endif - -#include // memset - -extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base); - - -#if defined(MY_CPU_X86_OR_AMD64) && defined(_7ZIP_ASM) -static void PrintCpuChars(AString &s, UInt32 v) -{ - for (int j = 0; j < 4; j++) - { - Byte b = (Byte)(v & 0xFF); - v >>= 8; - if (b == 0) - break; - s += (char)b; - } -} - -static void x86cpuid_to_String(const Cx86cpuid &c, AString &s) -{ - s.Empty(); - - UInt32 maxFunc2 = 0; - UInt32 t[3]; - - MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]); - - bool fullNameIsAvail = (maxFunc2 >= 0x80000004); - - if (!fullNameIsAvail) - { - for (int i = 0; i < 3; i++) - PrintCpuChars(s, c.vendor[i]); - } - else - { - for (int i = 0; i < 3; i++) - { - UInt32 c[4] = { 0 }; - MyCPUID(0x80000002 + i, &c[0], &c[1], &c[2], &c[3]); - for (int j = 0; j < 4; j++) - PrintCpuChars(s, c[j]); - } - } - - s.Add_Space_if_NotEmpty(); - { - char temp[32]; - ConvertUInt32ToHex(c.ver, temp); - s += '('; - s += temp; - s += ')'; - } -} -#endif - -static void GetCpuName(AString &s) -{ - s.Empty(); - - #ifdef MY_CPU_X86_OR_AMD64 - { - #ifdef _7ZIP_ASM - Cx86cpuid cpuid; - if (x86cpuid_CheckAndRead(&cpuid)) - { - x86cpuid_to_String(cpuid, s); - return; - } - #endif - #ifdef MY_CPU_AMD64 - s = "x64"; - #else - s = "x86"; - #endif - } - #else - - #ifdef MY_CPU_LE - s = "LE"; - #elif defined(MY_CPU_BE) - s = "BE"; - #else - #error ENDIANNESS - #endif - - #endif -} - -void mySplitCommandLine(int numArguments, char *arguments[],UStringVector &parts) { - - { // define P7ZIP_HOME_DIR - static char p7zip_home_dir[MAX_PATH]; - AString dir,name; - my_windows_split_path(arguments[0],dir,name); - snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",(const char *)dir); - p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0; - putenv(p7zip_home_dir); - } - -#ifdef ENV_HAVE_LOCALE - // set the program's current locale from the user's environment variables - setlocale(LC_ALL,""); - - // auto-detect which conversion p7zip should use - char *locale = setlocale(LC_CTYPE,0); - if (locale) { - size_t len = strlen(locale); - char *locale_upper = (char *)malloc(len+1); - if (locale_upper) { - strcpy(locale_upper,locale); - - for(size_t i=0;i 2) && (arg[0] == '-') && ( (arg[1]=='p') || (arg[1]=='P') ) ) - { - memset(arg+2,'*',len-2); - } - } - } - } -} - -const char *my_getlocale(void) { -#ifdef ENV_HAVE_LOCALE - const char* ret = setlocale(LC_CTYPE,0); - if (ret == 0) - ret ="C"; - return ret; -#elif defined(LOCALE_IS_UTF8) - return "utf8"; -#else - return "C"; -#endif -} - -void showP7zipInfo(CStdOutStream *so) -{ - if (!so) - return; - - AString cpu_name; - GetCpuName(cpu_name); - cpu_name.Trim(); - - int bits = int(sizeof(void *)) * 8; - - *so << "p7zip Version " << P7ZIP_VERSION << " (locale=" << my_getlocale() <<",Utf16="; - if (global_use_utf16_conversion) *so << "on"; - else *so << "off"; - *so << ",HugeFiles="; - if (sizeof(off_t) >= 8) *so << "on,"; - else *so << "off,"; - *so << bits << " bits,"; - int nbcpu = NWindows::NSystem::GetNumberOfProcessors(); - if (nbcpu > 1) *so << nbcpu << " CPUs "; - else *so << nbcpu << " CPU "; - *so << cpu_name; - -#ifdef _7ZIP_ASM -{ - const char * txt =",ASM"; - #ifdef MY_CPU_X86_OR_AMD64 - if (CPU_Is_Aes_Supported()) { txt =",ASM,AES-NI"; } - #endif - *so << txt; -} -#endif - *so << ")\n\n"; - -} diff -Nru p7zip-rar-16.02/CPP/myWindows/test_lib.cpp p7zip-rar-16.02+really25.00+ds/CPP/myWindows/test_lib.cpp --- p7zip-rar-16.02/CPP/myWindows/test_lib.cpp 2016-02-27 10:20:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/test_lib.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,836 +0,0 @@ -#undef BIG_ENDIAN -#undef LITTLE_ENDIAN - -#include "StdAfx.h" - -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE_CC__ -#define UInt32 macUIn32 -#include -#undef UInt32 -#endif - -#ifdef ENV_HAVE_WCHAR__H -#include -#endif -#ifdef ENV_HAVE_LOCALE -#include -#endif - -#include - -#define NEED_NAME_WINDOWS_TO_UNIX -// #include "myPrivate.h" - -#include "Common/StringConvert.h" -#include "Common/StdOutStream.h" - -#undef NDEBUG -#include - -#include "Common/StringConvert.cpp" -#include "Common/StdOutStream.cpp" -#include "Common/IntToString.cpp" -#include "Common/UTFConvert.cpp" - -#include "Windows/Synchronization.cpp" -#include "Windows/FileFind.cpp" -#include "Windows/TimeUtils.cpp" -#include "Windows/System.cpp" -#include "../C/Threads.c" -#include "../../C/Ppmd.h" - -int g_CodePage = -1; - -int global_use_lstat = 0; // FIXME - -/* FIXME */ - -LPSTR WINAPI CharNextA( LPCSTR ptr ) { - if (!*ptr) - return (LPSTR)ptr; - return (LPSTR)(ptr + 1); // p7zip search only for ASCII characters like '/' so no need to worry about current locale -} - - -int MyStringCompare(const char *s1, const char *s2) -{ - while (true) - { - unsigned char c1 = (unsigned char)*s1++; - unsigned char c2 = (unsigned char)*s2++; - if (c1 < c2) return -1; - if (c1 > c2) return 1; - if (c1 == 0) return 0; - } -} - -int MyStringCompare(const wchar_t *s1, const wchar_t *s2) -{ - while (true) - { - wchar_t c1 = *s1++; - wchar_t c2 = *s2++; - if (c1 < c2) return -1; - if (c1 > c2) return 1; - if (c1 == 0) return 0; - } -} - - - -/* FIXME */ - -using namespace NWindows; - -#if defined(ENV_HAVE_WCHAR__H) && defined(ENV_HAVE_MBSTOWCS) && defined(ENV_HAVE_WCSTOMBS) -void test_mbs(void) { - wchar_t wstr1[256] = { - L'e', - 0xE8, // latin small letter e with grave - 0xE9, // latin small letter e with acute - L'a', - 0xE0, // latin small letter a with grave - 0x20AC, // euro sign - L'b', - 0 }; - wchar_t wstr2[256]; - char astr[256]; - - global_use_utf16_conversion = 1; - - size_t len1 = wcslen(wstr1); - - printf("wstr1 - %d - '%ls'\n",(int)len1,wstr1); - - size_t len0 = wcstombs(astr,wstr1,sizeof(astr)); - printf("astr - %d - '%s'\n",(int)len0,astr); - - size_t len2 = mbstowcs(wstr2,astr,sizeof(wstr2)/sizeof(*wstr2)); - printf("wstr - %d - '%ls'\n",(int)len2,wstr2); - - if (wcscmp(wstr1,wstr2) != 0) { - printf("ERROR during conversions wcs -> mbs -> wcs\n"); - exit(EXIT_FAILURE); - } - - char *ptr = astr; - size_t len = 0; - while (*ptr) { - ptr = CharNextA(ptr); - len += 1; - } - if ((len != len1) && (len != 12)) { // 12 = when locale is UTF8 instead of ISO8859-15 - printf("ERROR CharNextA : len=%d, len1=%d\n",(int)len,(int)len1); - exit(EXIT_FAILURE); - } - - UString ustr(wstr1); - assert(ustr.Len() == (int)len1); - - AString ansistr(astr); - assert(ansistr.Len() == (int)len0); - - ansistr = UnicodeStringToMultiByte(ustr); - assert(ansistr.Len() == (int)len0); - - assert(strcmp(ansistr,astr) == 0); - assert(wcscmp(ustr,wstr1) == 0); - - UString ustr2 = MultiByteToUnicodeString(astr); - assert(ustr2.Len() == (int)len1); - assert(wcscmp(ustr2,wstr1) == 0); -} -void test_mbs_2(void) { - wchar_t wstr1[256] = { - 0x1F388, // Ballon - 0 }; - wchar_t wstr1_7zip[256] = { // 7-zip use UTF16 wide string - 0xd83c, - 0xdf88, - 0 }; - char astr1[]= { - char(0xf0), char(0x9f), char(0x8e), char(0x88), 0 - - }; - wchar_t wstr2[256]; - char astr[256]; - - printf("\nTest Ballon character\n"); - - global_use_utf16_conversion = 1; - - size_t len1 = wcslen(wstr1); - - printf("wstr1 - %d - '%ls'\n",(int)len1,wstr1); - - size_t len0 = wcstombs(astr,wstr1,sizeof(astr)); - printf("astr - %d - '%s'\n",(int)len0,astr); - - printf("strlen(astr)=%d\n",(int)strlen(astr)); - printf("strlen(astr1)=%d\n",(int)strlen(astr1)); - assert(strlen(astr) == strlen(astr1)); - - assert(strcmp(astr,astr1) == 0); - - size_t len2 = mbstowcs(wstr2,astr,sizeof(wstr2)/sizeof(*wstr2)); - printf("wstr - %d - '%ls'\n",(int)len2,wstr2); - - if (wcscmp(wstr1,wstr2) != 0) { - printf("ERROR during conversions wcs -> mbs -> wcs\n"); - exit(EXIT_FAILURE); - } - - AString ansistr(astr); - assert(ansistr.Len() == (int)len0); - - UString ustr2 = MultiByteToUnicodeString(ansistr); - assert(ustr2.Len() == wcslen(wstr1_7zip)); - assert(wcscmp(ustr2,wstr1_7zip) == 0); -} -#endif - -static void test_astring(int num) { - AString strResult; - - strResult = "first part : "; - char number[256]; - sprintf(number,"%d",num); - strResult += AString(number); - - strResult += " : last part"; - - printf("strResult -%s-\n",(const char *)strResult); - -} - - -extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base); - -static struct { - const char *path; - const char *dir; - const char *base; -} -tabSplit[]= - { - { "",".","." }, - { "/","/","/" }, - { ".",".","." }, - { "//","/","/" }, - { "///","/","/" }, - { "dir",".","dir" }, - { "/dir","/","dir" }, - { "/dir/","/","dir" }, - { "/dir/base","/dir","base" }, - { "/dir//base","/dir","base" }, - { "/dir///base","/dir","base" }, - { "//dir/base","//dir","base" }, - { "///dir/base","///dir","base" }, - { "/dir/base/","/dir","base" }, - { 0,0,0 } - }; - -static void test_split_astring() { - int ind = 0; - while (tabSplit[ind].path) { - AString path(tabSplit[ind].path); - AString dir; - AString base; - - my_windows_split_path(path,dir,base); - - if ((dir != tabSplit[ind].dir) || (base != tabSplit[ind].base)) { - printf("ERROR : '%s' '%s' '%s'\n",(const char *)path,(const char *)dir,(const char *)base); - } - ind++; - } - printf("test_split_astring : done\n"); -} - - // Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 -#define EPOCH_BIAS 116444736000000000LL -static LARGE_INTEGER UnixTimeToUL(time_t tps_unx) -{ - LARGE_INTEGER ul; - ul.QuadPart = tps_unx * 10000000LL + EPOCH_BIAS; - return ul; -} - -static LARGE_INTEGER FileTimeToUL(FILETIME fileTime) -{ - LARGE_INTEGER lFileTime; - lFileTime.QuadPart = fileTime.dwHighDateTime; - lFileTime.QuadPart = (lFileTime.QuadPart << 32) | fileTime.dwLowDateTime; - return lFileTime; -} - -static void display(const char *txt,SYSTEMTIME systime) -{ - FILETIME fileTime; - BOOL ret = SystemTimeToFileTime(&systime,&fileTime); - assert(ret == TRUE); - LARGE_INTEGER ulFileTime = FileTimeToUL(fileTime); - - const char * day=""; - switch (systime.wDayOfWeek) - { - case 0:day = "Sunday";break; - case 1:day = "Monday";break; - case 2:day = "Tuesday";break; - case 3:day = "Wednesday";break; - case 4:day = "Thursday";break; - case 5:day = "Friday";break; - case 6:day = "Saturday";break; - } - g_StdOut<< txt << day << " " - << (int)systime.wYear << "/" << (int)systime.wMonth << "/" << (int)systime.wDay << " " - << (int)systime.wHour << ":" << (int)systime.wMinute << ":" << (int)systime.wSecond << ":" - << (int)systime.wMilliseconds - << " (" << (UInt64)ulFileTime.QuadPart << ")\n"; -} - -static void test_time() -{ - time_t tps_unx = time(0); - - printf("Test Time (1):\n"); - printf("===========\n"); - SYSTEMTIME systimeGM; - GetSystemTime(&systimeGM); - - LARGE_INTEGER ul = UnixTimeToUL(tps_unx); - g_StdOut<<" unix time = " << (UInt64)tps_unx << " (" << (UInt64)ul.QuadPart << ")\n"; - - g_StdOut<<" gmtime : " << asctime(gmtime(&tps_unx))<<"\n"; - g_StdOut<<" localtime : " << asctime(localtime(&tps_unx))<<"\n"; - - display(" GetSystemTime : ", systimeGM); -} - -static void test_time2() -{ - UInt32 dosTime = 0x30d0094C; - FILETIME utcFileTime; - FILETIME localFileTime; - FILETIME localFileTime2; - UInt32 dosTime2 = 0; - - printf("Test Time (2):\n"); - printf("===========\n"); - NTime::DosTimeToFileTime(dosTime, localFileTime); - NTime::FileTimeToDosTime(localFileTime, dosTime2); - assert(dosTime == dosTime2); - - printf("Test Time (3):\n"); - printf("===========\n"); - /* DosTime To utcFileTime */ - - if (NTime::DosTimeToFileTime(dosTime, localFileTime)) /* DosDateTimeToFileTime */ - { - if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) - utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; - } - - printf(" - 0x%x => 0x%x 0x%x => 0x%x 0x%x\n",(unsigned)dosTime, - (unsigned)localFileTime.dwHighDateTime,(unsigned)localFileTime.dwLowDateTime, - (unsigned)utcFileTime.dwHighDateTime,(unsigned)utcFileTime.dwLowDateTime); - - - /* utcFileTime to DosTime */ - - FileTimeToLocalFileTime(&utcFileTime, &localFileTime2); - NTime::FileTimeToDosTime(localFileTime2, dosTime2); /* FileTimeToDosDateTime */ - - printf(" - 0x%x <= 0x%x 0x%x <= 0x%x 0x%x\n",(unsigned)dosTime2, - (unsigned)localFileTime2.dwHighDateTime,(unsigned)localFileTime2.dwLowDateTime, - (unsigned)utcFileTime.dwHighDateTime,(unsigned)utcFileTime.dwLowDateTime); - - assert(dosTime == dosTime2); - assert(localFileTime.dwHighDateTime == localFileTime2.dwHighDateTime); - assert(localFileTime.dwLowDateTime == localFileTime2.dwLowDateTime); -} - -static void test_semaphore() -{ - g_StdOut << "\nTEST SEMAPHORE :\n"; - - NWindows::NSynchronization::CSynchro sync; - NWindows::NSynchronization::CSemaphoreWFMO sema; - bool bres; - DWORD waitResult; - int i; - - sync.Create(); - sema.Create(&sync,2,10); - - g_StdOut << " - Release(1)\n"; - for(i = 0 ;i < 8;i++) - { - // g_StdOut << " - Release(1) : "<< i << "\n"; - bres = sema.Release(1); - assert(bres == S_OK); - } - // g_StdOut << " - Release(1) : done\n"; - bres = sema.Release(1); - assert(bres == S_FALSE); - - g_StdOut << " - WaitForMultipleObjects(INFINITE)\n"; - HANDLE events[1] = { sema }; - for(i=0;i<10;i++) - { - waitResult = ::WaitForMultipleObjects(1, events, FALSE, INFINITE); - assert(waitResult == WAIT_OBJECT_0); - } - - g_StdOut << " Done\n"; -} - - -/****************************************************************************************/ - - -static int threads_count = 0; - -static THREAD_FUNC_RET_TYPE thread_fct(void * /* param */ ) { - threads_count++; - return 0; -} - -#define MAX_THREADS 100000 - -int test_thread(void) { - ::CThread thread; - - Thread_Construct(&thread); - - threads_count = 0; - - printf("test_thread : %d threads\n",MAX_THREADS); - - for(int i=0;i -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#define UInt32 mac_UInt32 -#include -#undef UInt32 -#endif // __APPLE__ - - -// #define TRACE printf - -typedef DWORD LCID; -typedef void * ULONG_PTR; /* typedef unsigned long ULONG_PTR; */ - -#define SORT_DEFAULT 0x0 - -#define LANG_NEUTRAL 0x00 -#define LANG_ENGLISH 0x09 - -#define SUBLANG_DEFAULT 0x01 /* user default */ - -#define MAKELCID(l, s) ( (l & 0xFFFF) | ((s & 0xFFFF)<<16)) -#define MAKELANGID(p, s) ((((WORD)(s))<<10) | (WORD)(p)) - -#define LANGIDFROMLCID(lcid) ((WORD)(lcid)) - -static LCID lcid_LC_MESSAGES = 0; -static LCID lcid_LC_CTYPE = 0; - -struct locale_name -{ - WCHAR win_name[128]; /* Windows name ("en-US") */ - WCHAR lang[128]; /* language ("en") (note: buffer contains the other strings too) */ - WCHAR *country; /* country ("US") */ - WCHAR *charset; /* charset ("UTF-8") for Unix format only */ - WCHAR *script; /* script ("Latn") for Windows format only */ - WCHAR *modifier; /* modifier or sort order */ - LCID lcid; /* corresponding LCID */ - int matches; /* number of elements matching LCID (0..4) */ - UINT codepage; /* codepage corresponding to charset */ -}; -#define WINE_UNICODE_INLINE static - -/***********************************************************/ -typedef struct { - const WCHAR * LOCALE_SNAME; - const WCHAR * LOCALE_SISO639LANGNAME; - const WCHAR * LOCALE_SISO3166CTRYNAME; - unsigned int LOCALE_IDEFAULTUNIXCODEPAGE; - unsigned int LOCALE_ILANGUAGE; -} t_info; - -static t_info g_langInfo[] = { - { L"af-ZA" , L"af" , L"ZA" , 28591 , 0x0436 }, /* afk.nls */ - { L"ar-SA" , L"ar" , L"SA" , 28596 , 0x0401 }, /* ara.nls */ - { L"ar-LB" , L"ar" , L"LB" , 28596 , 0x3001 }, /* arb.nls */ - { L"ar-EG" , L"ar" , L"EG" , 28596 , 0x0c01 }, /* are.nls */ - { L"ar-DZ" , L"ar" , L"DZ" , 28596 , 0x1401 }, /* arg.nls */ - { L"ar-BH" , L"ar" , L"BH" , 28596 , 0x3c01 }, /* arh.nls */ - { L"ar-IQ" , L"ar" , L"IQ" , 28596 , 0x0801 }, /* ari.nls */ - { L"ar-JO" , L"ar" , L"JO" , 28596 , 0x2c01 }, /* arj.nls */ - { L"ar-KW" , L"ar" , L"KW" , 28596 , 0x3401 }, /* ark.nls */ - { L"ar-LY" , L"ar" , L"LY" , 28596 , 0x1001 }, /* arl.nls */ - { L"ar-MA" , L"ar" , L"MA" , 28596 , 0x1801 }, /* arm.nls */ - { L"ar-OM" , L"ar" , L"OM" , 28596 , 0x2001 }, /* aro.nls */ - { L"ar-QA" , L"ar" , L"QA" , 28596 , 0x4001 }, /* arq.nls */ - { L"ar-SY" , L"ar" , L"SY" , 28596 , 0x2801 }, /* ars.nls */ - { L"ar-TN" , L"ar" , L"TN" , 28596 , 0x1c01 }, /* art.nls */ - { L"ar-AE" , L"ar" , L"AE" , 28596 , 0x3801 }, /* aru.nls */ - { L"ar-YE" , L"ar" , L"YE" , 28596 , 0x2401 }, /* ary.nls */ - { L"az-AZ" , L"az" , L"AZ" , 28595 , 0x082c }, /* aze.nls */ - { L"az-Latn-AZ" , L"az" , L"AZ" , 28599 , 0x042c }, /* azl.nls */ - { L"be-BY" , L"be" , L"BY" , 1251 , 0x0423 }, /* bel.nls */ - { L"bg-BG" , L"bg" , L"BG" , 1251 , 0x0402 }, /* bgr.nls */ - { L"br-FR" , L"br" , L"FR" , 28605 , 0x0493 }, /* brf.nls */ - { L"ca-ES" , L"ca" , L"ES" , 28605 , 0x0403 }, /* cat.nls */ - { L"zh-CN" , L"zh" , L"CN" , 936 , 0x0804 }, /* chs.nls */ - { L"zh-TW" , L"zh" , L"TW" , 950 , 0x0404 }, /* cht.nls */ - { L"kw-GB" , L"kw" , L"GB" , 28605 , 0x04891 }, /* cor.nls */ - { L"cs-CZ" , L"cs" , L"CZ" , 28592 , 0x0405 }, /* csy.nls */ - { L"cy-GB" , L"cy" , L"GB" , 28604 , 0x0492 }, /* cym.nls */ - { L"da-DK" , L"da" , L"DK" , 28605 , 0x0406 }, /* dan.nls */ - { L"de-AT" , L"de" , L"AT" , 28605 , 0x0c07 }, /* dea.nls */ - { L"de-LI" , L"de" , L"LI" , 28605 , 0x1407 }, /* dec.nls */ - { L"de-LU" , L"de" , L"LU" , 28605 , 0x1007 }, /* del.nls */ - { L"de-CH" , L"de" , L"CH" , 28605 , 0x0807 }, /* des.nls */ - { L"de-DE" , L"de" , L"DE" , 28605 , 0x0407 }, /* deu.nls */ - { L"dv-MV" , L"dv" , L"MV" , 65001 , 0x0465 }, /* div.nls */ - { L"el-GR" , L"el" , L"GR" , 28597 , 0x0408 }, /* ell.nls */ - { L"en-AU" , L"en" , L"AU" , 28591 , 0x0c09 }, /* ena.nls */ - { L"en-CB" , L"en" , L"CB" , 28591 , 0x2409 }, /* enb.nls */ - { L"en-CA" , L"en" , L"CA" , 28591 , 0x1009 }, /* enc.nls */ - { L"en-GB" , L"en" , L"GB" , 28605 , 0x0809 }, /* eng.nls */ - { L"en-IE" , L"en" , L"IE" , 28605 , 0x1809 }, /* eni.nls */ - { L"en-JM" , L"en" , L"JM" , 28591 , 0x2009 }, /* enj.nls */ - { L"en-BZ" , L"en" , L"BZ" , 28591 , 0x2809 }, /* enl.nls */ - { L"en-PH" , L"en" , L"PH" , 28591 , 0x3409 }, /* enp.nls */ - { L"en-ZA" , L"en" , L"ZA" , 28591 , 0x1c09 }, /* ens.nls */ - { L"en-TT" , L"en" , L"TT" , 28591 , 0x2c09 }, /* ent.nls */ - { L"en-US" , L"en" , L"US" , 28591 , 0x0409 }, /* enu.nls */ - { L"en-ZW" , L"en" , L"ZW" , 28591 , 0x3009 }, /* enw.nls */ - { L"en-NZ" , L"en" , L"NZ" , 28591 , 0x1409 }, /* enz.nls */ - { L"eo" , L"eo" , L"" , 65001 , 0x048f }, /* eox.nls */ - { L"es-PA" , L"es" , L"PA" , 28591 , 0x180a }, /* esa.nls */ - { L"es-BO" , L"es" , L"BO" , 28591 , 0x400a }, /* esb.nls */ - { L"es-CR" , L"es" , L"CR" , 28591 , 0x140a }, /* esc.nls */ - { L"es-DO" , L"es" , L"DO" , 28591 , 0x1c0a }, /* esd.nls */ - { L"es-SV" , L"es" , L"SV" , 28591 , 0x440a }, /* ese.nls */ - { L"es-EC" , L"es" , L"EC" , 28591 , 0x300a }, /* esf.nls */ - { L"es-GT" , L"es" , L"GT" , 28591 , 0x100a }, /* esg.nls */ - { L"es-HN" , L"es" , L"HN" , 28591 , 0x480a }, /* esh.nls */ - { L"es-NI" , L"es" , L"NI" , 28591 , 0x4c0a }, /* esi.nls */ - { L"es-C" , L"es" , L"C" , 28591 , 0x340a }, /* esl.nls */ - { L"es-MX" , L"es" , L"MX" , 28591 , 0x080a }, /* esm.nls */ - { L"es-ES_modern" , L"es" , L"ES" , 28605 , 0x0c0a }, /* esn.nls */ - { L"es-CO" , L"es" , L"CO" , 28591 , 0x240a }, /* eso.nls */ - { L"es-ES" , L"es" , L"ES" , 28605 , 0x040a }, /* esp.nls */ - { L"es-PE" , L"es" , L"PE" , 28591 , 0x280a }, /* esr.nls */ - { L"es-AR" , L"es" , L"AR" , 28591 , 0x2c0a }, /* ess.nls */ - { L"es-PR" , L"es" , L"PR" , 28591 , 0x500a }, /* esu.nls */ - { L"es-VE" , L"es" , L"VE" , 28591 , 0x200a }, /* esv.nls */ - { L"es-UY" , L"es" , L"UY" , 28591 , 0x380a }, /* esy.nls */ - { L"es-PY" , L"es" , L"PY" , 28591 , 0x3c0a }, /* esz.nls */ - { L"et-EE" , L"et" , L"EE" , 28605 , 0x0425 }, /* eti.nls */ - { L"eu-ES" , L"eu" , L"ES" , 28605 , 0x042d }, /* euq.nls */ - { L"fa-IR" , L"fa" , L"IR" , 65001 , 0x0429 }, /* far.nls */ - { L"fi-FI" , L"fi" , L"FI" , 28605 , 0x040b }, /* fin.nls */ - { L"fo-FO" , L"fo" , L"FO" , 28605 , 0x0438 }, /* fos.nls */ - { L"fr-FR" , L"fr" , L"FR" , 28605 , 0x040c }, /* fra.nls */ - { L"fr-BE" , L"fr" , L"BE" , 28605 , 0x080c }, /* frb.nls */ - { L"fr-CA" , L"fr" , L"CA" , 28591 , 0x0c0c }, /* frc.nls */ - { L"fr-LU" , L"fr" , L"LU" , 28605 , 0x140c }, /* frl.nls */ - { L"fr-MC" , L"fr" , L"MC" , 28605 , 0x180c }, /* frm.nls */ - { L"fr-CH" , L"fr" , L"CH" , 28605 , 0x100c }, /* frs.nls */ - { L"ga-IE" , L"ga" , L"IE" , 28605 , 0x043c }, /* gae.nls */ - { L"gd-GB" , L"gd" , L"GB" , 28605 , 0x083c }, /* gdh.nls */ - { L"gv-GB" , L"gv" , L"GB" , 28605 , 0x0c3c }, /* gdv.nls */ - { L"gl-ES" , L"gl" , L"ES" , 28605 , 0x0456 }, /* glc.nls */ - { L"gu-IN" , L"gu" , L"IN" , 65001 , 0x0447 }, /* guj.nls */ - { L"he-I" , L"he" , L"I" , 28598 , 0x040d }, /* heb.nls */ - { L"hi-IN" , L"hi" , L"IN" , 65001 , 0x0439 }, /* hin.nls */ - { L"hr-HR" , L"hr" , L"HR" , 28592 , 0x041a }, /* hrv.nls */ - { L"hu-HU" , L"hu" , L"HU" , 28592 , 0x040e }, /* hun.nls */ - { L"hy-AM" , L"hy" , L"AM" , 65001 , 0x042b }, /* hye.nls */ - { L"id-ID" , L"id" , L"ID" , 28591 , 0x0421 }, /* ind.nls */ - { L"is-IS" , L"is" , L"IS" , 28605 , 0x040f }, /* isl.nls */ - { L"it-IT" , L"it" , L"IT" , 28605 , 0x0410 }, /* ita.nls */ - { L"it-CH" , L"it" , L"CH" , 28605 , 0x0810 }, /* its.nls */ - { L"ja-JP" , L"ja" , L"JP" , 20932 , 0x0411 }, /* jpn.nls */ - { L"kn-IN" , L"kn" , L"IN" , 65001 , 0x044b }, /* kan.nls */ - { L"ka-GE" , L"ka" , L"GE" , 65001 , 0x0437 }, /* kat.nls */ - { L"kk-KZ" , L"kk" , L"KZ" , 28595 , 0x043f }, /* kkz.nls */ - { L"kok-IN" , L"kok" , L"IN" , 65001 , 0x0457 }, /* knk.nls */ - { L"ko-KR" , L"ko" , L"KR" , 949 , 0x0412 }, /* kor.nls */ - { L"ky-KG" , L"ky" , L"KG" , 28595 , 0x0440 }, /* kyr.nls */ - { L"lt-LT" , L"lt" , L"LT" , 28603 , 0x0427 }, /* lth.nls */ - { L"lv-LV" , L"lv" , L"LV" , 28603 , 0x0426 }, /* lvi.nls */ - { L"mr-IN" , L"mr" , L"IN" , 65001 , 0x044e }, /* mar.nls */ - { L"mk-MK" , L"mk" , L"MK" , 28595 , 0x042f }, /* mki.nls */ - { L"mn-MN" , L"mn" , L"MN" , 28595 , 0x0450 }, /* mon.nls */ - { L"ms-BN" , L"ms" , L"BN" , 28591 , 0x083e }, /* msb.nls */ - { L"ms-MY" , L"ms" , L"MY" , 28591 , 0x043e }, /* msl.nls */ - { L"nl-BE" , L"nl" , L"BE" , 28605 , 0x0813 }, /* nlb.nls */ - { L"nl-N" , L"nl" , L"N" , 28605 , 0x0413 }, /* nld.nls */ - { L"nl-SR" , L"nl" , L"SR" , 28605 , 0x0c13 }, /* nls.nls */ - { L"nn-NO" , L"nn" , L"NO" , 28605 , 0x0814 }, /* non.nls */ - { L"nb-NO" , L"nb" , L"NO" , 28605 , 0x0414 }, /* nor.nls */ - { L"pa-IN" , L"pa" , L"IN" , 65001 , 0x0446 }, /* pan.nls */ - { L"pl-P" , L"pl" , L"P" , 28592 , 0x0415 }, /* plk.nls */ - { L"pt-BR" , L"pt" , L"BR" , 28591 , 0x0416 }, /* ptb.nls */ - { L"pt-PT" , L"pt" , L"PT" , 28605 , 0x0816 }, /* ptg.nls */ - { L"rm-CH" , L"rm" , L"CH" , 28605 , 0x0417 }, /* rmc.nls */ - { L"ro-RO" , L"ro" , L"RO" , 28592 , 0x0418 }, /* rom.nls */ - { L"ru-RU" , L"ru" , L"RU" , 20866 , 0x0419 }, /* rus.nls */ - { L"sa-IN" , L"sa" , L"IN" , 65001 , 0x044f }, /* san.nls */ - { L"sk-SK" , L"sk" , L"SK" , 28592 , 0x041b }, /* sky.nls */ - { L"sl-SI" , L"sl" , L"SI" , 28592 , 0x0424 }, /* slv.nls */ - { L"sq-A" , L"sq" , L"A" , 28592 , 0x041c }, /* sqi.nls */ - { L"sr-SP" , L"sr" , L"SP" , 28595 , 0x0c1a }, /* srb.nls */ - { L"sr-Latn-SP" , L"sr" , L"SP" , 28592 , 0x081a }, /* srl.nls */ - { L"sv-SE" , L"sv" , L"SE" , 28605 , 0x041d }, /* sve.nls */ - { L"sv-FI" , L"sv" , L"FI" , 28605 , 0x081d }, /* svf.nls */ - { L"sw-KE" , L"sw" , L"KE" , 28591 , 0x0441 }, /* swk.nls */ - { L"syr-SY" , L"syr" , L"SY" , 65001 , 0x045a }, /* syr.nls */ - { L"ta-IN" , L"ta" , L"IN" , 65001 , 0x0449 }, /* tam.nls */ - { L"te-IN" , L"te" , L"IN" , 65001 , 0x044a }, /* tel.nls */ - { L"th-TH" , L"th" , L"TH" , 874 , 0x041e }, /* tha.nls */ - { L"tr-TR" , L"tr" , L"TR" , 28599 , 0x041f }, /* trk.nls */ - { L"tt-TA" , L"tt" , L"TA" , 28595 , 0x0444 }, /* ttt.nls */ - { L"uk-UA" , L"uk" , L"UA" , 21866 , 0x0422 }, /* ukr.nls */ - { L"ur-PK" , L"ur" , L"PK" , 1256 , 0x0420 }, /* urd.nls */ - { L"uz-UZ" , L"uz" , L"UZ" , 28595 , 0x0843 }, /* uzb.nls */ - { L"uz-Latn-UZ" , L"uz" , L"UZ" , 28605 , 0x0443 }, /* uzl.nls */ - { L"vi-VN" , L"vi" , L"VN" , 1258 , 0x042a }, /* vit.nls */ - { L"wa-BE" , L"wa" , L"BE" , 28605 , 0x0490 }, /* wal.nls */ - { L"zh-HK" , L"zh" , L"HK" , 950 , 0x0c04 }, /* zhh.nls */ - { L"zh-SG" , L"zh" , L"SG" , 936 , 0x1004 }, /* zhi.nls */ - { L"zh-MO" , L"zh" , L"MO" , 950 , 0x1404 }, /* zhm.nls */ - { 0 , 0 , 0 , 0, 0 } -}; - -/***********************************************************/ -WINE_UNICODE_INLINE WCHAR *strchrW( const WCHAR *str, WCHAR ch ) -{ - do { if (*str == ch) return (WCHAR *)(ULONG_PTR)str; } while (*str++); - return NULL; -} - -WINE_UNICODE_INLINE WCHAR *strpbrkW( const WCHAR *str, const WCHAR *accept ) -{ - for ( ; *str; str++) if (strchrW( accept, *str )) return (WCHAR *)(ULONG_PTR)str; - return NULL; -} - - -/***********************************************************/ - -WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str ) -{ - const WCHAR *s = str; - while (*s) s++; - return s - str; -} - -WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src ) -{ - WCHAR *p = dst; - while ((*p++ = *src++)); - return dst; -} - -WINE_UNICODE_INLINE WCHAR *strcatW( WCHAR *dst, const WCHAR *src ) -{ - strcpyW( dst + strlenW(dst), src ); - return dst; -} - -WINE_UNICODE_INLINE int strcmpW( const WCHAR *str1, const WCHAR *str2 ) -{ - while (*str1 && (*str1 == *str2)) { str1++; str2++; } - return *str1 - *str2; -} - - -WINE_UNICODE_INLINE LPWSTR lstrcpynW( LPWSTR dst, LPCWSTR src, int n ) -{ - { - LPWSTR d = dst; - LPCWSTR s = src; - UINT count = n; - - while ((count > 1) && *s) - { - count--; - *d++ = *s++; - } - if (count) *d = 0; - } - return dst; -} - -/* Copy Ascii string to Unicode without using codepages */ -static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n ) -{ - while (n > 1 && *src) - { - *dst++ = (unsigned char)*src++; - n--; - } - if (n) *dst = 0; -} - -/*******************************************************/ - -/* Charset to codepage map, sorted by name. */ -static const struct charset_entry -{ - const char *charset_name; - UINT codepage; -} charset_names[] = -{ - { "BIG5", 950 }, - { "CP1250", 1250 }, - { "CP1251", 1251 }, - { "CP1252", 1252 }, - { "CP1253", 1253 }, - { "CP1254", 1254 }, - { "CP1255", 1255 }, - { "CP1256", 1256 }, - { "CP1257", 1257 }, - { "CP1258", 1258 }, - { "CP932", 932 }, - { "CP936", 936 }, - { "CP949", 949 }, - { "CP950", 950 }, - { "EUCJP", 20932 }, - { "GB2312", 936 }, - { "IBM037", 37 }, - { "IBM1026", 1026 }, - { "IBM424", 424 }, - { "IBM437", 437 }, - { "IBM500", 500 }, - { "IBM850", 850 }, - { "IBM852", 852 }, - { "IBM855", 855 }, - { "IBM857", 857 }, - { "IBM860", 860 }, - { "IBM861", 861 }, - { "IBM862", 862 }, - { "IBM863", 863 }, - { "IBM864", 864 }, - { "IBM865", 865 }, - { "IBM866", 866 }, - { "IBM869", 869 }, - { "IBM874", 874 }, - { "IBM875", 875 }, - { "ISO88591", 28591 }, - { "ISO885910", 28600 }, - { "ISO885913", 28603 }, - { "ISO885914", 28604 }, - { "ISO885915", 28605 }, - { "ISO885916", 28606 }, - { "ISO88592", 28592 }, - { "ISO88593", 28593 }, - { "ISO88594", 28594 }, - { "ISO88595", 28595 }, - { "ISO88596", 28596 }, - { "ISO88597", 28597 }, - { "ISO88598", 28598 }, - { "ISO88599", 28599 }, - { "KOI8R", 20866 }, - { "KOI8U", 21866 }, - { "UTF8", CP_UTF8 } -}; - -static int charset_cmp( const void *name, const void *entry ) -{ - const struct charset_entry *charset = (const struct charset_entry *)entry; - return strcasecmp( (const char *)name, charset->charset_name ); -} - -static UINT find_charset( const WCHAR *name ) -{ - const struct charset_entry *entry; - char charset_name[16]; - size_t i, j; - - /* remove punctuation characters from charset name */ - for (i = j = 0; name[i] && j < sizeof(charset_name)-1; i++) - if (isalnum((unsigned char)name[i])) charset_name[j++] = name[i]; - charset_name[j] = 0; - - entry = (const struct charset_entry *)bsearch( charset_name, charset_names, - sizeof(charset_names)/sizeof(charset_names[0]), - sizeof(charset_names[0]), charset_cmp ); - if (entry) return entry->codepage; - - return 0; -} -/*******************************************************/ - -static BOOL find_locale_id_callback(/* LPCWSTR name, ? */ const t_info * tab, struct locale_name *data) -{ - // WCHAR buffer[128]; - int matches = 0; - WORD LangID = tab->LOCALE_ILANGUAGE & 0xFFFF; /* FIXME */ - LCID lcid = MAKELCID( LangID, SORT_DEFAULT ); /* FIXME: handle sort order */ - - if (PRIMARYLANGID(LangID) == LANG_NEUTRAL) return TRUE; /* continue search */ - - /* first check exact name */ - if (data->win_name[0] && tab->LOCALE_SNAME[0]) - /* GetLocaleInfoW( lcid, LOCALE_SNAME | LOCALE_NOUSEROVERRIDE, - buffer, sizeof(buffer)/sizeof(WCHAR) )) */ - { - if (!strcmpW( data->win_name, tab->LOCALE_SNAME )) - { - matches = 4; /* everything matches */ - goto done; - } - } - - /*if (!GetLocaleInfoW( lcid, LOCALE_SISO639LANGNAME | LOCALE_NOUSEROVERRIDE, - buffer, sizeof(buffer)/sizeof(WCHAR) )) */ - if (tab->LOCALE_SISO639LANGNAME[0] == 0) - return TRUE; - - if (strcmpW( tab->LOCALE_SISO639LANGNAME , data->lang )) return TRUE; - matches++; /* language name matched */ - - if (data->country) - { - /* if (GetLocaleInfoW( lcid, LOCALE_SISO3166CTRYNAME|LOCALE_NOUSEROVERRIDE, - buffer, sizeof(buffer)/sizeof(WCHAR) )) */ - if (tab->LOCALE_SISO3166CTRYNAME[0]) - { - if (strcmpW(tab->LOCALE_SISO3166CTRYNAME , data->country )) goto done; - matches++; /* country name matched */ - } - } - else /* match default language */ - { - if (SUBLANGID(LangID) == SUBLANG_DEFAULT) matches++; - } - - if (data->codepage) - { - UINT unix_cp; - /* if (GetLocaleInfoW( lcid, LOCALE_IDEFAULTUNIXCODEPAGE | LOCALE_RETURN_NUMBER, - (LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) )) */ - unix_cp = tab->LOCALE_IDEFAULTUNIXCODEPAGE; - { - if (unix_cp == data->codepage) matches++; - } - } - - /* FIXME: check sort order */ - -done: - if (matches > data->matches) - { - data->lcid = lcid; - data->matches = matches; - } - return (data->matches < 4); /* no need to continue for perfect match */ -} - - -/*********************************************************************** - * parse_locale_name - * - * Parse a locale name into a struct locale_name, handling both Windows and Unix formats. - * Unix format is: lang[_country][.charset][@modifier] - * Windows format is: lang[-script][-country][_modifier] - */ -static void parse_locale_name( const WCHAR *str, struct locale_name *name ) -{ - static const WCHAR sepW[] = {'-','_','.','@',0}; - static const WCHAR winsepW[] = {'-','_',0}; - static const WCHAR posixW[] = {'P','O','S','I','X',0}; - static const WCHAR cW[] = {'C',0}; - static const WCHAR latinW[] = {'l','a','t','i','n',0}; - static const WCHAR latnW[] = {'-','L','a','t','n',0}; - WCHAR *p; - int ind; - - // TRACE("%s\n", debugstr_w(str)); - - name->country = name->charset = name->script = name->modifier = NULL; - name->lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT ); - name->matches = 0; - name->codepage = 0; - name->win_name[0] = 0; - lstrcpynW( name->lang, str, sizeof(name->lang)/sizeof(WCHAR) ); - - if (!(p = strpbrkW( name->lang, sepW ))) - { - if (!strcmpW( name->lang, posixW ) || !strcmpW( name->lang, cW )) - { - name->matches = 4; /* perfect match for default English lcid */ - return; - } - strcpyW( name->win_name, name->lang ); - } - else if (*p == '-') /* Windows format */ - { - strcpyW( name->win_name, name->lang ); - *p++ = 0; - name->country = p; - if (!(p = strpbrkW( p, winsepW ))) goto done; - if (*p == '-') - { - *p++ = 0; - name->script = name->country; - name->country = p; - if (!(p = strpbrkW( p, winsepW ))) goto done; - } - *p++ = 0; - name->modifier = p; - } - else /* Unix format */ - { - if (*p == '_') - { - *p++ = 0; - name->country = p; - p = strpbrkW( p, sepW + 2 ); - } - if (p && *p == '.') - { - *p++ = 0; - name->charset = p; - p = strchrW( p, '@' ); - } - if (p) - { - *p++ = 0; - name->modifier = p; - } - - if (name->charset) - name->codepage = find_charset( name->charset ); - - /* rebuild a Windows name if possible */ - - if (name->charset) goto done; /* can't specify charset in Windows format */ - if (name->modifier && strcmpW( name->modifier, latinW )) - goto done; /* only Latn script supported for now */ - strcpyW( name->win_name, name->lang ); - if (name->modifier) strcatW( name->win_name, latnW ); - if (name->country) - { - p = name->win_name + strlenW(name->win_name); - *p++ = '-'; - strcpyW( p, name->country ); - } - } -done: - ; - -/* DEBUG - printf("EnumResourceLanguagesW(...):\n"); - printf(" name->win_name=%ls\n", name->win_name); - printf(" name->lang=%ls\n", name->lang); - printf(" name->country=%ls\n", name->country); - printf(" name->codepage=%d\n", name->codepage); -*/ -// EnumResourceLanguagesW( kernel32_handle, (LPCWSTR)RT_STRING, (LPCWSTR)LOCALE_ILANGUAGE, -// find_locale_id_callback, (LPARAM)name ); - - ind = 0; - while (g_langInfo[ind].LOCALE_SNAME) - { - BOOL ret = find_locale_id_callback(&g_langInfo[ind],name); - if (ret == FALSE) - break; - - ind++; - } -} - - - - -/********************************/ - -static UINT setup_unix_locales(void) -{ - struct locale_name locale_name; - // WCHAR buffer[128]; - WCHAR ctype_buff[128]; - char *locale; - UINT unix_cp = 0; - - if ((locale = setlocale( LC_CTYPE, NULL ))) - { - strcpynAtoW( ctype_buff, locale, sizeof(ctype_buff)/sizeof(WCHAR) ); - parse_locale_name( ctype_buff, &locale_name ); - lcid_LC_CTYPE = locale_name.lcid; - unix_cp = locale_name.codepage; - } - if (!lcid_LC_CTYPE) /* this one needs a default value */ - lcid_LC_CTYPE = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT ); - -#if 0 - TRACE( "got lcid %04x (%d matches) for LC_CTYPE=%s\n", - locale_name.lcid, locale_name.matches, debugstr_a(locale) ); - -#define GET_UNIX_LOCALE(cat) do \ - if ((locale = setlocale( cat, NULL ))) \ - { \ - strcpynAtoW( buffer, locale, sizeof(buffer)/sizeof(WCHAR) ); \ - if (!strcmpW( buffer, ctype_buff )) lcid_##cat = lcid_LC_CTYPE; \ - else { \ - parse_locale_name( buffer, &locale_name ); \ - lcid_##cat = locale_name.lcid; \ - TRACE( "got lcid %04x (%d matches) for " #cat "=%s\n", \ - locale_name.lcid, locale_name.matches, debugstr_a(locale) ); \ - } \ - } while (0) - - GET_UNIX_LOCALE( LC_COLLATE ); - GET_UNIX_LOCALE( LC_MESSAGES ); - GET_UNIX_LOCALE( LC_MONETARY ); - GET_UNIX_LOCALE( LC_NUMERIC ); - GET_UNIX_LOCALE( LC_TIME ); -#ifdef LC_PAPER - GET_UNIX_LOCALE( LC_PAPER ); -#endif -#ifdef LC_MEASUREMENT - GET_UNIX_LOCALE( LC_MEASUREMENT ); -#endif -#ifdef LC_TELEPHONE - GET_UNIX_LOCALE( LC_TELEPHONE ); -#endif - -#undef GET_UNIX_LOCALE - -#endif // #if 0 - - return unix_cp; -} - -/********************************/ - -static void LOCALE_Init(void) -{ - /* - extern void __wine_init_codepages( const union cptable *ansi_cp, const union cptable *oem_cp, - const union cptable *unix_cp ); - */ - - // UINT ansi_cp = 1252, oem_cp = 437, mac_cp = 10000, unix_cp; - UINT unix_cp = 0; - -#ifdef __APPLE__ - /* MacOS doesn't set the locale environment variables so we have to do it ourselves */ - CFArrayRef preferred_locales, all_locales; - CFStringRef user_language_string_ref = NULL; - char user_locale[50]; - - CFLocaleRef user_locale_ref = CFLocaleCopyCurrent(); - CFStringRef user_locale_string_ref = CFLocaleGetIdentifier( user_locale_ref ); - - CFStringGetCString( user_locale_string_ref, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 ); - CFRelease( user_locale_ref ); - if (!strchr( user_locale, '.' )) strcat( user_locale, ".UTF-8" ); - unix_cp = CP_UTF8; /* default to utf-8 even if we don't get a valid locale */ - setenv( "LANG", user_locale, 0 ); - // TRACE( "setting locale to '%s'\n", user_locale ); - - /* We still want to set the retrieve the preferred language as chosen in - System Preferences.app, because it can differ from CFLocaleCopyCurrent(). - */ - all_locales = CFLocaleCopyAvailableLocaleIdentifiers(); - preferred_locales = CFBundleCopyLocalizationsForPreferences( all_locales, NULL ); - if (preferred_locales && CFArrayGetCount( preferred_locales )) - user_language_string_ref = (CFStringRef)CFArrayGetValueAtIndex( preferred_locales, 0 ); // FIXME - CFRelease( all_locales ); -#endif /* __APPLE__ */ - - // FIXME setlocale( LC_ALL, "" ); - - unix_cp = setup_unix_locales(); - if (!lcid_LC_MESSAGES) lcid_LC_MESSAGES = lcid_LC_CTYPE; - -#ifdef __APPLE__ - /* Override lcid_LC_MESSAGES with user_language if LC_MESSAGES is set to default */ - if (lcid_LC_MESSAGES == lcid_LC_CTYPE && user_language_string_ref) - { - struct locale_name locale_name; - WCHAR buffer[128]; - CFStringGetCString( user_language_string_ref, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 ); - strcpynAtoW( buffer, user_locale, sizeof(buffer)/sizeof(WCHAR) ); - parse_locale_name( buffer, &locale_name ); - lcid_LC_MESSAGES = locale_name.lcid; - // TRACE( "setting lcid_LC_MESSAGES to '%s'\n", user_locale ); - } - if (preferred_locales) - CFRelease( preferred_locales ); -#endif - -#if 0 // FIXME - NtSetDefaultUILanguage( LANGIDFROMLCID(lcid_LC_MESSAGES) ); - NtSetDefaultLocale( TRUE, lcid_LC_MESSAGES ); - NtSetDefaultLocale( FALSE, lcid_LC_CTYPE ); - - ansi_cp = get_lcid_codepage( LOCALE_USER_DEFAULT ); - GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_IDEFAULTMACCODEPAGE | LOCALE_RETURN_NUMBER, - (LPWSTR)&mac_cp, sizeof(mac_cp)/sizeof(WCHAR) ); - GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_IDEFAULTCODEPAGE | LOCALE_RETURN_NUMBER, - (LPWSTR)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR) ); - if (!unix_cp) - GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_IDEFAULTUNIXCODEPAGE | LOCALE_RETURN_NUMBER, - (LPWSTR)&unix_cp, sizeof(unix_cp)/sizeof(WCHAR) ); - - if (!(ansi_cptable = wine_cp_get_table( ansi_cp ))) - ansi_cptable = wine_cp_get_table( 1252 ); - if (!(oem_cptable = wine_cp_get_table( oem_cp ))) - oem_cptable = wine_cp_get_table( 437 ); - if (!(mac_cptable = wine_cp_get_table( mac_cp ))) - mac_cptable = wine_cp_get_table( 10000 ); - if (unix_cp != CP_UTF8) - { - if (!(unix_cptable = wine_cp_get_table( unix_cp ))) - unix_cptable = wine_cp_get_table( 28591 ); - } - - __wine_init_codepages( ansi_cptable, oem_cptable, unix_cptable ); - - TRACE( "ansi=%03d oem=%03d mac=%03d unix=%03d\n", - ansi_cptable->info.codepage, oem_cptable->info.codepage, - mac_cptable->info.codepage, unix_cp ); - - setlocale(LC_NUMERIC, "C"); /* FIXME: oleaut32 depends on this */ -#endif -} - -LANGID GetUserDefaultLangID(void) -{ - // return LANGIDFROMLCID(GetUserDefaultLCID()); - if (lcid_LC_MESSAGES == 0) LOCALE_Init(); - return LANGIDFROMLCID(lcid_LC_MESSAGES); -} - -LANGID GetSystemDefaultLangID(void) -{ - // return LANGIDFROMLCID(GetSystemDefaultLCID()); - if (lcid_LC_MESSAGES == 0) LOCALE_Init(); - return LANGIDFROMLCID(lcid_LC_MESSAGES); -} - -#ifdef TEST -int main() -{ - LANGID langID; - WORD primLang; - WORD subLang; - - setlocale( LC_ALL, "" ); - - langID = GetUserDefaultLangID(); - printf("langID=0x%x\n",langID); - - primLang = (WORD)(PRIMARYLANGID(langID)); - subLang = (WORD)(SUBLANGID(langID)); - - printf("primLang=%d subLang=%d\n",(unsigned)primLang,(unsigned)subLang); - - return 0; -} -#endif - diff -Nru p7zip-rar-16.02/CPP/myWindows/wine_date_and_time.cpp p7zip-rar-16.02+really25.00+ds/CPP/myWindows/wine_date_and_time.cpp --- p7zip-rar-16.02/CPP/myWindows/wine_date_and_time.cpp 2015-01-14 19:25:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/CPP/myWindows/wine_date_and_time.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,468 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "config.h" - -#include -#include -#include -#include -#include /* gettimeofday */ -#include -#include -#include - -#include - -// #define TRACEN(u) u; -#define TRACEN(u) /* */ - -typedef LONG NTSTATUS; -#define STATUS_SUCCESS 0x00000000 - -#define TICKSPERSEC 10000000 -#define TICKSPERMSEC 10000 -#define SECSPERDAY 86400 -#define SECSPERHOUR 3600 -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define EPOCHWEEKDAY 1 /* Jan 1, 1601 was Monday */ -#define DAYSPERWEEK 7 -#define EPOCHYEAR 1601 -#define DAYSPERNORMALYEAR 365 -#define DAYSPERLEAPYEAR 366 -#define MONSPERYEAR 12 -#define DAYSPERQUADRICENTENNIUM (365 * 400 + 97) -#define DAYSPERNORMALCENTURY (365 * 100 + 24) -#define DAYSPERNORMALQUADRENNIUM (365 * 4 + 1) - -/* 1601 to 1970 is 369 years plus 89 leap days */ -#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY) -#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) -/* 1601 to 1980 is 379 years plus 91 leap days */ -#define SECS_1601_TO_1980 ((379 * 365 + 91) * (ULONGLONG)SECSPERDAY) -#define TICKS_1601_TO_1980 (SECS_1601_TO_1980 * TICKSPERSEC) -typedef short CSHORT; - -static LONG TIME_GetBias() { - time_t utc = time(NULL); - struct tm *ptm = localtime(&utc); - int localdaylight = ptm->tm_isdst; /* daylight for local timezone */ - ptm = gmtime(&utc); - ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */ - LONG bias = (int)(mktime(ptm)-utc); - TRACEN((printf("TIME_GetBias %ld\n",(long)bias))) - return bias; -} - -static inline void RtlSystemTimeToLocalTime( const LARGE_INTEGER *SystemTime, - LARGE_INTEGER *LocalTime ) { - LONG bias = TIME_GetBias(); - LocalTime->QuadPart = SystemTime->QuadPart - bias * (LONGLONG)TICKSPERSEC; -} - -void WINAPI RtlSecondsSince1970ToFileTime( DWORD Seconds, FILETIME * ft ) { - ULONGLONG secs = Seconds * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - ft->dwLowDateTime = (DWORD)secs; - ft->dwHighDateTime = (DWORD)(secs >> 32); - TRACEN((printf("RtlSecondsSince1970ToFileTime %lx => %lx %lx\n",(long)Seconds,(long)ft->dwHighDateTime,(long)ft->dwLowDateTime))) -} - -/* -void WINAPI RtlSecondsSince1970ToTime( DWORD Seconds, LARGE_INTEGER *Time ) -{ - ULONGLONG secs = Seconds * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - // Time->u.LowPart = (DWORD)secs; Time->u.HighPart = (DWORD)(secs >> 32); - Time->QuadPart = secs; -} - */ - -BOOL WINAPI DosDateTimeToFileTime( WORD fatdate, WORD fattime, FILETIME * ft) -{ - struct tm newtm; -#ifndef ENV_HAVE_TIMEGM - struct tm *gtm; - time_t time1, time2; -#endif - - TRACEN((printf("DosDateTimeToFileTime\n"))) - - newtm.tm_sec = (fattime & 0x1f) * 2; - newtm.tm_min = (fattime >> 5) & 0x3f; - newtm.tm_hour = (fattime >> 11); - newtm.tm_mday = (fatdate & 0x1f); - newtm.tm_mon = ((fatdate >> 5) & 0x0f) - 1; - newtm.tm_year = (fatdate >> 9) + 80; - newtm.tm_isdst = -1; -#ifdef ENV_HAVE_TIMEGM - RtlSecondsSince1970ToFileTime( timegm(&newtm), ft ); -#else - newtm.tm_isdst = 0; - time1 = mktime(&newtm); - gtm = gmtime(&time1); - time2 = mktime(gtm); - RtlSecondsSince1970ToFileTime( 2*time1-time2, ft ); -#endif - TRACEN((printf("DosDateTimeToFileTime(%ld,%ld) => %lx %lx\n", - (long)fatdate,(long)fattime, - (long)ft->dwHighDateTime,(long)ft->dwLowDateTime))) - - return TRUE; -} - -/* -BOOL WINAPI DosDateTimeToFileTime( WORD fatdate, WORD fattime, FILETIME * ft) { - struct tm newtm; - - TRACEN((printf("DosDateTimeToFileTime\n"))) - - memset(&newtm,0,sizeof(newtm)); - newtm.tm_sec = (fattime & 0x1f) * 2; - newtm.tm_min = (fattime >> 5) & 0x3f; - newtm.tm_hour = (fattime >> 11); - newtm.tm_mday = (fatdate & 0x1f); - newtm.tm_mon = ((fatdate >> 5) & 0x0f) - 1; - newtm.tm_year = (fatdate >> 9) + 80; - newtm.tm_isdst = -1; - - time_t time1 = mktime(&newtm); - LONG bias = TIME_GetBias(); - RtlSecondsSince1970ToFileTime( time1 - bias, ft ); - - - TRACEN((printf("DosDateTimeToFileTime(%ld,%ld) t1=%ld => %lx %lx\n", - (long)fatdate,(long)fattime,(long)time1, - (long)ft->dwHighDateTime,(long)ft->dwLowDateTime))) - - return TRUE; -} -*/ - -BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ) { - ULONGLONG tmp = Time->QuadPart; - TRACEN((printf("RtlTimeToSecondsSince1970-1 %llx\n",tmp))) - tmp /= TICKSPERSEC; - tmp -= SECS_1601_TO_1970; - TRACEN((printf("RtlTimeToSecondsSince1970-2 %llx\n",tmp))) - if (tmp > 0xffffffff) return FALSE; - *Seconds = (DWORD)tmp; - return TRUE; -} - -BOOL WINAPI FileTimeToDosDateTime( const FILETIME *ft, WORD *fatdate, WORD *fattime ) { - LARGE_INTEGER li; - ULONG t; - time_t unixtime; - struct tm* tm; - WORD fat_d,fat_t; - - TRACEN((printf("FileTimeToDosDateTime\n"))) - li.QuadPart = ft->dwHighDateTime; - li.QuadPart = (li.QuadPart << 32) | ft->dwLowDateTime; - RtlTimeToSecondsSince1970( &li, &t ); - unixtime = t; /* unixtime = t; * FIXME unixtime = t - TIME_GetBias(); */ - - tm = gmtime( &unixtime ); - - fat_t = (tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2); - fat_d = ((tm->tm_year - 80) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday; - if (fattime) - *fattime = fat_t; - if (fatdate) - *fatdate = fat_d; - - TRACEN((printf("FileTimeToDosDateTime : %lx %lx => %d %d\n", - (long)ft->dwHighDateTime,(long)ft->dwLowDateTime,(unsigned)fat_d,(unsigned)fat_t))) - - return TRUE; -} - -BOOL WINAPI FileTimeToLocalFileTime( const FILETIME *utcft, FILETIME * localft ) { - LARGE_INTEGER local, utc; - - TRACEN((printf("FileTimeToLocalFileTime\n"))) - utc.QuadPart = utcft->dwHighDateTime; - utc.QuadPart = (utc.QuadPart << 32) | utcft->dwLowDateTime; - RtlSystemTimeToLocalTime( &utc, &local ); - localft->dwLowDateTime = (DWORD)local.QuadPart; - localft->dwHighDateTime = (DWORD)(local.QuadPart >> 32); - - return TRUE; -} - -typedef struct _TIME_FIELDS { - CSHORT Year; - CSHORT Month; - CSHORT Day; - CSHORT Hour; - CSHORT Minute; - CSHORT Second; - CSHORT Milliseconds; - CSHORT Weekday; -} TIME_FIELDS; - -static const int MonthLengths[2][MONSPERYEAR] = -{ - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -static inline int IsLeapYear(int Year) { - return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0; -} - -static inline VOID WINAPI RtlTimeToTimeFields( - const LARGE_INTEGER *liTime, - TIME_FIELDS * TimeFields) { - int SecondsInDay; - long int cleaps, years, yearday, months; - long int Days; - LONGLONG Time; - - /* Extract millisecond from time and convert time into seconds */ - TimeFields->Milliseconds = - (CSHORT) (( liTime->QuadPart % TICKSPERSEC) / TICKSPERMSEC); - Time = liTime->QuadPart / TICKSPERSEC; - - /* The native version of RtlTimeToTimeFields does not take leap seconds - * into account */ - - /* Split the time into days and seconds within the day */ - Days = Time / SECSPERDAY; - SecondsInDay = Time % SECSPERDAY; - - /* compute time of day */ - TimeFields->Hour = (CSHORT) (SecondsInDay / SECSPERHOUR); - SecondsInDay = SecondsInDay % SECSPERHOUR; - TimeFields->Minute = (CSHORT) (SecondsInDay / SECSPERMIN); - TimeFields->Second = (CSHORT) (SecondsInDay % SECSPERMIN); - - /* compute day of week */ - TimeFields->Weekday = (CSHORT) ((EPOCHWEEKDAY + Days) % DAYSPERWEEK); - - /* compute year, month and day of month. */ - cleaps=( 3 * ((4 * Days + 1227) / DAYSPERQUADRICENTENNIUM) + 3 ) / 4; - Days += 28188 + cleaps; - years = (20 * Days - 2442) / (5 * DAYSPERNORMALQUADRENNIUM); - yearday = Days - (years * DAYSPERNORMALQUADRENNIUM)/4; - months = (64 * yearday) / 1959; - /* the result is based on a year starting on March. - * To convert take 12 from Januari and Februari and - * increase the year by one. */ - if( months < 14 ) { - TimeFields->Month = months - 1; - TimeFields->Year = years + 1524; - } else { - TimeFields->Month = months - 13; - TimeFields->Year = years + 1525; - } - /* calculation of day of month is based on the wonderful - * sequence of INT( n * 30.6): it reproduces the - * 31-30-31-30-31-31 month lengths exactly for small n's */ - TimeFields->Day = yearday - (1959 * months) / 64 ; -} - - -BOOL WINAPI FileTimeToSystemTime( const FILETIME *ft, SYSTEMTIME * syst ) { - TIME_FIELDS tf; - LARGE_INTEGER t; - - TRACEN((printf("FileTimeToSystemTime\n"))) - t.QuadPart = ft->dwHighDateTime; - t.QuadPart = (t.QuadPart << 32) | ft->dwLowDateTime; - RtlTimeToTimeFields(&t, &tf); - - syst->wYear = tf.Year; - syst->wMonth = tf.Month; - syst->wDay = tf.Day; - syst->wHour = tf.Hour; - syst->wMinute = tf.Minute; - syst->wSecond = tf.Second; - syst->wMilliseconds = tf.Milliseconds; - syst->wDayOfWeek = tf.Weekday; - return TRUE; -} - - -static inline NTSTATUS WINAPI RtlLocalTimeToSystemTime( const LARGE_INTEGER *LocalTime, - LARGE_INTEGER *SystemTime) { - - TRACEN((printf("RtlLocalTimeToSystemTime\n"))) - LONG bias = TIME_GetBias(); - SystemTime->QuadPart = LocalTime->QuadPart + bias * (LONGLONG)TICKSPERSEC; - return STATUS_SUCCESS; -} - -BOOL WINAPI LocalFileTimeToFileTime( const FILETIME *localft, FILETIME * utcft ) { - LARGE_INTEGER local, utc; - - TRACEN((printf("LocalFileTimeToFileTime\n"))) - local.QuadPart = localft->dwHighDateTime; - local.QuadPart = (local.QuadPart << 32) | localft->dwLowDateTime; - RtlLocalTimeToSystemTime( &local, &utc ); - utcft->dwLowDateTime = (DWORD)utc.QuadPart; - utcft->dwHighDateTime = (DWORD)(utc.QuadPart >> 32); - - return TRUE; -} - -/********************************************************************* - * GetSystemTime (KERNEL32.@) - * - * Get the current system time. - * - * RETURNS - * Nothing. - */ -VOID WINAPI GetSystemTime(SYSTEMTIME * systime) /* [O] Destination for current time */ -{ - FILETIME ft; - LARGE_INTEGER t; - - TRACEN((printf("GetSystemTime\n"))) - - struct timeval now; - gettimeofday( &now, 0 ); - t.QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - t.QuadPart += now.tv_usec * 10; - - ft.dwLowDateTime = (DWORD)(t.QuadPart); - ft.dwHighDateTime = (DWORD)(t.QuadPart >> 32); - FileTimeToSystemTime(&ft, systime); -} - -/****************************************************************************** - * RtlTimeFieldsToTime [NTDLL.@] - * - * Convert a TIME_FIELDS structure into a time. - * - * PARAMS - * ftTimeFields [I] TIME_FIELDS structure to convert. - * Time [O] Destination for the converted time. - * - * RETURNS - * Success: TRUE. - * Failure: FALSE. - */ -static BOOLEAN WINAPI RtlTimeFieldsToTime( - TIME_FIELDS * tfTimeFields, - LARGE_INTEGER *Time) -{ - int month, year, cleaps, day; - - TRACEN((printf("RtlTimeFieldsToTime\n"))) - - /* FIXME: normalize the TIME_FIELDS structure here */ - /* No, native just returns 0 (error) if the fields are not */ - if( tfTimeFields->Milliseconds< 0 || tfTimeFields->Milliseconds > 999 || - tfTimeFields->Second < 0 || tfTimeFields->Second > 59 || - tfTimeFields->Minute < 0 || tfTimeFields->Minute > 59 || - tfTimeFields->Hour < 0 || tfTimeFields->Hour > 23 || - tfTimeFields->Month < 1 || tfTimeFields->Month > 12 || - tfTimeFields->Day < 1 || - tfTimeFields->Day > MonthLengths - [ tfTimeFields->Month ==2 || IsLeapYear(tfTimeFields->Year)] - [ tfTimeFields->Month - 1] || - tfTimeFields->Year < 1601 ) - return FALSE; - - /* now calculate a day count from the date - * First start counting years from March. This way the leap days - * are added at the end of the year, not somewhere in the middle. - * Formula's become so much less complicate that way. - * To convert: add 12 to the month numbers of Jan and Feb, and - * take 1 from the year */ - if(tfTimeFields->Month < 3) { - month = tfTimeFields->Month + 13; - year = tfTimeFields->Year - 1; - } else { - month = tfTimeFields->Month + 1; - year = tfTimeFields->Year; - } - cleaps = (3 * (year / 100) + 3) / 4; /* nr of "century leap years"*/ - day = (36525 * year) / 100 - cleaps + /* year * dayperyr, corrected */ - (1959 * month) / 64 + /* months * daypermonth */ - tfTimeFields->Day - /* day of the month */ - 584817 ; /* zero that on 1601-01-01 */ - /* done */ - - Time->QuadPart = (((((LONGLONG) day * HOURSPERDAY + - tfTimeFields->Hour) * MINSPERHOUR + - tfTimeFields->Minute) * SECSPERMIN + - tfTimeFields->Second ) * 1000 + - tfTimeFields->Milliseconds ) * TICKSPERMSEC; - - return TRUE; -} - -/********************************************************************* - * SystemTimeToFileTime (KERNEL32.@) - */ -BOOL WINAPI SystemTimeToFileTime( const SYSTEMTIME *syst, FILETIME * ft ) { - TIME_FIELDS tf; - LARGE_INTEGER t; - - TRACEN((printf("SystemTimeToFileTime\n"))) - - tf.Year = syst->wYear; - tf.Month = syst->wMonth; - tf.Day = syst->wDay; - tf.Hour = syst->wHour; - tf.Minute = syst->wMinute; - tf.Second = syst->wSecond; - tf.Milliseconds = syst->wMilliseconds; - - RtlTimeFieldsToTime(&tf, &t); - ft->dwLowDateTime = (DWORD)t.QuadPart; - ft->dwHighDateTime = (DWORD)(t.QuadPart>>32); - return TRUE; -} - -/*********************************************************************** - * GetSystemTimeAsFileTime (KERNEL32.@) - * - * Get the current time in utc format. - * - * RETURNS - * Nothing. - */ -VOID WINAPI GetSystemTimeAsFileTime( - FILETIME * time) /* [out] Destination for the current utc time */ -{ - LARGE_INTEGER t; -/* - NtQuerySystemTime( &t ); -*/ - struct timeval now; - - gettimeofday( &now, 0 ); - t.QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - t.QuadPart += now.tv_usec * 10; - - time->dwLowDateTime = (DWORD)(t.QuadPart); - time->dwHighDateTime = (DWORD)(t.QuadPart >> 32); -} - -DWORD WINAPI GetTickCount(VOID) { // Retrieves the number of milliseconds - timeval v; - if (gettimeofday(&v, 0) == 0) - { - return (DWORD)(v.tv_sec * (UInt64)1000 + v.tv_usec / 1000); - } - return (DWORD)time(0)*1000; -} - diff -Nru p7zip-rar-16.02/ChangeLog p7zip-rar-16.02+really25.00+ds/ChangeLog --- p7zip-rar-16.02/ChangeLog 2016-06-11 09:32:55.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/ChangeLog 1970-01-01 00:00:00.000000000 +0000 @@ -1,1162 +0,0 @@ - -Version 16.02 -============= - - - - From Windows version of 7-Zip 16.02: - - The BUG in 16.00 - 16.01 was fixed: 7-Zip mistakenly reported the warning - "There are some data after the end of the payload data" for split archives. - -Version 16.01 (never published) -============= - - - From Windows version of 7-Zip 16.01: - - The bugs in SWM (WIM), EXE (PE) and CHM code were fixed. - - there are some internal changes in source code for better compatibility with VS2015 C++ compiler. - -Version 16.00 (never published) -============= - - - better support for OpenBsd (CPP/Windows/System.cpp), thanks Josh (https://sourceforge.net/p/p7zip/discussion/383043/thread/ee32dcd8/?limit=25#c322) - - - From Windows version of 7-Zip 16.00: - - 7-Zip now can extract multivolume ZIP archives (z01, z02, ... , zip). - - Some fixed bugs: - - bzip2 decoder -mmt2 reported E_FAIL (for k_My_HRESULT_WritingWasCut case), if we extract partial file. - - 7z solid update (hang in break) - - sha1 worked incorrectly for call after call with ((size & 3) != 0) - - 7z update bcj bugs were fixed. - - split (aaa.001) fixed - - iso loop fix - - rar4 multivol -stdin kpidSize - - drag and drop 1<2.txt - - memory access violation fix - - - -Version 15.14.1 -=============== - - - patch #32 Compiling in OS X fails with p7zip_15.14 - - -Version 15.14 -============= - - - bug #147 Directory traversal through symlinks - ( https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1038 ) - - - patch #26 : Patch to correctly set permissions for docs that permits non-sudo deletion of docs - - - patch #27 : Update Mac OS X LLVM 64bits Makefile - - - patch #28 : p7zip version 15.09 fails to build on s390 - - - patch #29 : please fix incorrect fsf address - - - patch #31 : p7zip 15.09 fails to build on mips - - - bug : "7za a -p ..." was fixed - - - bug #172 : Impossible to create archive with some unicode symbols in filename - - - From Windows version of 7-Zip 15.13: - - The BUG in 15.13 in CAB code was fixed. - - - From Windows version of 7-Zip 15.12: - - Some bugs were fixed. - - New localization: Yoruba. - - - test_emul becomes test_lib (tests libraries) - - - cross building added : - makefile.linux_cross_mipsel - - - support for android 5+ (-fPIE -pie) - -Version 15.12 (never published) -============= - - From Windows version of 7-Zip 15.12 : - - "There are no errors" string after "Test" operation inside archive. - - The bugs in LZMA SDK were fixed (but these bugs are not related directly to 7-Zip's code). - - - - From Windows version of 7-Zip 15.11 : - - Some bugs were fixed. - - 7-Zip 15.10 showed incorrect error message about missing volume for multivolume RAR archives. - - - ..../LZHAM added - - - -Version 15.10 beta -================== - - - bug #147 Directory traversal through symlinks - Bug-Debian: https://bugs.debian.org/774660 - Delay creation of symlinks to prevent arbitrary file writes (CVE-2015-1038) - Fix given by Ben Hutchings - - - From Windows version of 7-zip 15.10 beta: - - The BUG in 9.21 - 15.09 was fixed: - 7-Zip could ignore some parameters, specified for archive creation operation - for gzip and bzip2 formats in "Add to Archive" window and in command line - version (-m switch). - - Some bugs were fixed. - - extracting from solid wim archives worked incorrectly in some cases, - - Also there are some minor changes. - - 7-Zip can show the name of missing volume for multivolume RAR and VMDK archives. - - Some internal changes with 7-Zip Benchmark. - -Version 15.09 beta -================== - - - From Windows version of 7-zip 15.09 beta: - - 7-Zip now can extract ext2 and multivolume VMDK images. - - Some bugs were fixed. - - -Version 15.08 beta -================== - - - From Windows version of 7-zip 15.08 beta: - - - 7-Zip now can extract ext3 and ext4 (Linux file system) images. - - Some bugs were fixed. - - -Version 15.07 beta -================== - - - "bin/Codecs/Rar29.so" renamed to "bin/Codecs/Rar.so" - - - support for cygwin 64 bits - - - support for cygwin 64 bits with asm - - - cygwin : fix in GetRamSize() - - - cross building added : - makefile.linux_cross_aarch64 - makefile.linux_cross_arm - makefile.linux_cross_ppc - makefile.linux_cross_ppc64 - makefile.linux_cross_ppc64le - makefile.linux_cross_s390x (7za and 7zr pass tests, 7z does not pass tests) - - - - From Windows version of 7-zip 15.07 beta: - - 7-Zip now can extract GPT images and single file QCOW2, VMDK, VDI images. - - 7-Zip now can extract solid WIM archives with LZMS compression. - - Some bugs were fixed. - - - - From Windows version of 7-zip 15.06 beta: - - - 7-Zip now can extract RAR5 archives. - - 7-Zip now doesn't sort files by type while adding to solid 7z archive. - new -mqs switch to sort files by type while adding to solid 7z archive. - - The BUG in 7-Zip File Manager was fixed: - The "Move" operation to open 7z archive didn't delete empty files. - - The BUG in 15.05 was fixed: - console version added some text to the end of stdout stream, is -so switch was used. - - The BUG in 9.30 - 15.05 was fixed: - 7-Zip could not open multivolume sfx RAR archive. - - Some bugs were fixed. - - - From Windows version of 7-zip 15.05 beta: - - 7-Zip now can create 7z, xz and zip archives with 1536 MB dictionary for LZMA/LZMA2. - - 7-Zip File Manager now can operate with alternate file streams at NTFS volumes via "File / Alternate Streams" menu command. - - 7-Zip now can extract .zipx (WinZip) archives that use xz compression. - - new optional "section size" parameter for BCJ2 filter for compression ratio improving. - Example: -mf=BCJ2:d9M, if largest executable section in files is smaller than 9 MB. - - Speed optimizations for BCJ2 filter and SHA-1 and SHA-256 calculation. - - Console version now uses stderr stream for error messages. - - Console version now shows names of processed files only in progress line by default. - - new -bb[0-3] switch to set output log level. -bb1 shows names of processed files in log. - - new -bs[o|e|p][0|1|2] switch to set stream for output messages; - o: output, e: error, p: progress line; 0: disable, 1: stdout, 2: stderr. - - new -bt switch to show execution time statistics. - - new -myx[0-9] switch to set level of file analysis. - - new -mmtf- switch to set single thread mode for filters. - - The BUG was fixed: - - 7-Zip didn't restore NTFS permissions for folders during extracting from WIM archives. - - The BUG was fixed: - The command line version: if the command "rn" (Rename) was called with more - than one pair of paths, 7-Zip used only first rename pair. - - The BUG was fixed: - 7-Zip crashed for ZIP/LZMA/AES/AES-NI. - - The BUG in 15.01-15.02 was fixed: - 7-Zip created incorrect ZIP archives, if ZipCrypto encryption was used. - 7-Zip 9.20 can extract such incorrect ZIP archives. - - Some bugs were fixed. - - - -Version 9.38.2 -============== - - patch #27 : Update Mac OS X LLVM 64bits Makefile - and all others makefile.macosx_* become makefile.macosx_gcc_* - - - bug #153 Relative paths extracted outside of extraction directory - - -Version 9.38.1 -============== - - bug #145 "p7zip crashes while moving memory in MoveItems - - -Version 9.38 -============== - - - patch #23 fixes "7z with unicode file name with surrogate pair is not handled well in Linux" - - - bug #139 "password from commanline is visible in processes list" - Now the characters of the password are replaced with *. - - - From Windows version of 7-zip - - bug#138 If you extract the password with # program crashes - 7z now supports long password in RAR 3 and 4. - - - -Version 9.22 -============== - - From Windows version of 7-zip 9.22 - - 7-Zip could ignore some options when you created ZIP archives. - For example, it could use ZipCrypto cipher instead of AES-256. - - - From Windows version of 7-zip 9.21 - - New -mf=FilterID switch to specify compression filter. Examples: - 7z a -mf=bcj2 a.7z a.tar - 7z a -mf=delta:4 a.7z a.wav - 7z a -mf=bcj a.tar.xz a.tar - - - New class FString for file names at file systems. - - Speed optimization in CRC code for big-endian CPUs. - - - From Windows version of 7-zip - - Speed optimizations in AES code for Intel's 32nm CPUs. - - Speed optimizations in CRC calculation code for Intel's Atom CPUs. - - - - 7za can run on ANDROID 2.3 ! - - - bug with multi archives which are links. - - - #3283518 : Asm/x{32,64}/7zCrcT8U.asm introduces executable stack - - -Version 9.20.1 -============== - - - #3211479 "p7zip 9.20 - "unsupported method" with RAR files - " fixed - "install.sh" installs again "bin/Codecs/Rar29.so" - -Version 9.20 -============ - - - From Windows version of 7-zip 9.20, What's new after 7-Zip 4.65 (2009-02-03): - - 7-Zip now supports LZMA2 compression method. - - 7-Zip now can update solid .7z archives. - - 7-Zip now supports XZ archives. - - 7-Zip now supports PPMd compression in ZIP archives. - - 7-Zip now can unpack NTFS, FAT, VHD, MBR, APM, SquashFS, CramFS, MSLZ archives. - - 7-Zip now can unpack GZip, BZip2, LZMA, XZ and TAR archives from stdin. - - 7-Zip now can unpack some TAR and ISO archives with incorrect headers. - - 7-Zip now supports files that are larger than 8 GB in TAR archives. - - NSIS and WIM support was improved. - - Partial parsing for EXE resources, SWF and FLV. - - The support for archives in installers was improved. - - 7-Zip now can stores NTFS file timestamps to ZIP archives. - - Speed optimizations in PPMd codec. - - Speed optimizations in CRC calculation code for Intel's Atom CPUs. - - New -scrc switch to calculate total CRC-32 during extracting / testing. - - 7-Zip File Manager now doesn't use temp files to open nested archives stored without compression. - - Disk fragmentation problem for ZIP archives created by 7-Zip was fixed. - - Some bugs were fixed. - - New localizations: Hindi, Gujarati, Sanskrit, Tatar, Uyghur, Kazakh. - - Not in p7zip : Speed optimizations in AES code for Intel's 32nm CPUs. - - - - -Version 9.18 -============ - - From Windows version of 7-zip 9.17 - - Disk fragmentation problem for ZIP archives created by 7-Zip was fixed. - Notes: 7-Zip now uses 4 MB RAM buffer as file cache, when you create ZIP archives. - It reduces the number of Move_File_Position and Write_to_File operations. - - - From Windows version of 7-zip 9.18 - - 7-Zip now can unpack SquashFS and CramFS filesystem images. - - 7-Zip now can unpack some TAR and ISO archives with incorrect headers. - - Some bugs were fixed. - - - Some bugs were fixed in 7zG and 7zFM on MacOSX - - -Version 9.16 -============ - - From Windows version of 7-zip 9.16 - - 7-Zip now supports files that are larger than 8 GB in TAR archives. - - NSIS support was improved : - - 7-Zip now supports BZip2 method in NSIS installers. - - 7-Zip now can extract identical files from NSIS installers. - - Some bugs were fixed. - - New localizations: Hindi, Gujarati, Sanskrit. - - - From Windows version of 7-zip 9.15 - - Some bugs were fixed. - - New localization: Tatar - - - From Windows version of 7-zip 9.14 - - WIM support was improved. 7-Zip now can create WIM archives without compression. - - - - #3069545 "kSignatureDummy?" fixed - - - - -Version 9.13 -============ - - From Windows version of 7-zip 9.12 - - Some bugs were fixed. - - - - #2863580 "Crash in Rar decoder on a corrupted file" fixed - - - #2860898 "Dereferencing a zero pointer in cab handler" fixed - - - #2860679 "Division by zero in cab decoder" fixed - - - -Version 9.12 -============ - - From Windows version of 7-zip 9.12 - - ZIP / PPMd compression ratio was improved in Maximum and Ultra modes. - - The BUG in 7-Zip 9.* beta was fixed: LZMA2 codec didn't work, - if more than 10 threads were used (or more than 20 threads in some modes). - - - makefile.openbsd is now compatible with OpenBSD ports tree. - (thanks to jggimi) - - - cmake projects added. - - - 7zFM and 7zG can be built on MacOSX but these ports are in very alpha stage. - make app to build p7zip.app (p7zip for MacOSX) - - -Version 9.11 (never published) -============ - - From Windows version of 7-zip 9.11 - - 7-Zip now supports PPMd compression in .ZIP archives. - - Speed optimizations in PPMd codec. - - The support for archives in installers was improved. - - Some bugs were fixed. - - -Version 9.10 (never published) -============ - - - From Windows version of 7-zip 9.05 to 9.10 - - 7-Zip now can unpack Apple Partition Map (APM) disk images. - - 7-Zip now can unpack MSLZ archives. - - Partial parsing for EXE resources, SWF and FLV. - - Some bugs were fixed. - - - p7zip can now use hugetlbfs on Linux (thank to Joachim Henke) - Like with the Windows large pages, this gives a nice speedup, - when running memory intensive operations. - - - p7zip now uses UTF8 (kCFStringNormalizationFormD) On MacOSX - fixes #2831266 "p7zip can't find NFC Unicode filename in OSX Terminal" - and #2976169 "German Umlauts Failure" - - -Version 9.05 (never published) -============ - - - p7zip now uses precompiled header with gcc 4 - - -Version 9.04 (Major bugfixes and Major enhancements) -============ - - - From Windows version of 7-zip 9.04 : - - 7-Zip now can update solid .7z archives. - - 7-Zip now supports LZMA2 compression method. - - 7-Zip now supports XZ archives. - - 7-Zip now can unpack NTFS, FAT, VHD and MBR archives. - - 7-Zip now can unpack GZip, BZip2, LZMA, XZ and TAR archives from stdin. - - New -scrc switch to calculate total CRC-32 during extracting / testing. - - Some bugs were fixed. - - - #2799966 " A newly created 7z archive (by p7zip 4.65) is broken and cannot be unpacked / listed / tested" - Fixed : now "7za a -mx=9 archive.7z directory" creates a good archive even - if there are a lot of executable files. - - - Fixed : the RAM size was reported incorrectly on MacOSX 64bits (with 2Gb+ RAM) - - - #2798023 "segfault handling very large multivolume .7z file" - p7zip now displays the following error "Error: Too many open files" - if you don't have enough rights to open all the splitted files - ( on Linux : ulimit -n) - - -Version 4.65 -============ - - From Windows version of 7-zip 4.62 to 4.65 - - The bug in 7-Zip 4.63 was fixed: 7-Zip could not decrypt .ZIP archives encrypted with WinZip-AES method. - - 7-Zip now can unpack ZIP archives encrypted with PKWARE-AES. - - Some bugs were fixed. - - - Fixed : the RAM size was reported incorrectly on MacOSX 64bits - - - Fixed : makefile.linux_amd64_asm_icc - - - DJGPP : - makefile.djgpp becomes makefile.djgpp_old - makefile.djgpp_watt added (thank to Rugxulo) - - - - you can now compile 7za with a cmake project (see README) - the cmake project can build a codeblock project ;) - Remark : the kdevelop3 or Eclipse/CDT4 project don't work :( - -Version 4.61 -============ - - From Windows version of 7-zip 4.61 : - - 7-Zip now supports LZMA compression for .ZIP archives. - - Some bugs were fixed. - - - #2199036 : Ask for password twice when creating encrypted archive - - - 7zG added (read GUI/readme.txt) - - -Version 4.60 (never published) -============ - - - From Windows version of 7-zip 4.60 : - - Some bugs were fixed - - - p7zip didn't use the BCJ /BCJ2 filters for executables (: - - makefile.linux_amd64_asm_icc added (tested with Intel Compiler 11 on Ubuntu 8.04 x64) - - -Version 4.59 (never published) -============ - - - From Windows version of 7-zip 4.59 : - - 7-Zip now can unpack UDF, XAR and DMG/HFS archives. - - It's allowed to use -t switch for "list" and "extract" commands. - - Some bugs were fixed. - - - Bug : wrong timestamp for files extracted from .zip or .rar archives - - -Version 4.58 -============ - - From Windows version of 7-zip 4.58 : - - Some speed optimizations. - - 7-Zip now can unpack .lzma archives. - - Unicode (UTF-8) support for filenames in .ZIP archives. Now there are 3 modes: - 1) Default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols. - 2) -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols. - 3) -mcl switch: 7-Zip uses local code page. - - Now it's possible to store file creation time in 7z and ZIP archives (-mtc switch). - - 7-Zip now can unpack multivolume RAR archives created with - "old style volume names" scheme and names *.001, *.002, ... - - Now it's possible to use -mSW- and -mSW+ switches instead of -mSW=off and -mSW=on - - Some bugs were fixed. - - - Bug #1898410 : Timestamp error in archive listing - now "7za l .." and "ls -l just_extracted_file" give the same date and time. - - - Bug #1860938 : unix file rights only 600 instead of 644 - - - Bug #1941574 : gzip files always marked as OS FAT, Now p7zip uses "Unix". - - - Bug #1947700 : file containing excluded files not read - When using the -xr flag to list files not to be included in the - archive the file is not read if it is a symbolic link. - - - Feature Requests #1868080 : add support to compile for NetWare (makefile.netware_asm_gcc_3.X) - - - Patch #1883893 : Incorrect path ref to docs in man pages (When using the last ($DEST_DIR) argument with install.sh) - - - now "install.sh" supports filenames with spaces. - - - some code cleanup (Synchronization) - - - some minor fix in the BZip2 codec. - - - fix with the define "__TEXT" for s390 - - -Version 4.57 -============ - - From Windows version of 7-zip 4.57 : - - The BUG in command line version was fixed: -up3 switch could work incorrectly. - - Minor improvement in ZIP compression. - - -Version 4.56 (never published) -============ - - From Windows version of 7-zip 4.56 : - - Some bugs were fixed - - - On HPUX : fixed "Can't load '../bin/7z.dll'" - (Unsatisfied data symbol '_ZTVN10__cxxabiv121__vmi_class_type_infoE' in load module '../bin/7z.so'.) - - - bug : p7zip used to build a zip file with an "FAT" header instead of "Unix" header - If LANG was set, "unzip" tried to translate the filenames from "FAT" to locale ... - - - On AIX : fixed "HugeFiles=off" (thank kuriath) - - - bug #1800180 : LZMAlone compilation error in COutFile - - - Patch #1796569 : Fix FreeBSD FTBFS - - - Patch #1796575 : fix man1/7za.1 man1/7zr.1 man1/7z.1 - - -Version 4.55 -============ - - From Windows version of 7-zip 4.55 : - - Some bugs were fixed - - - fixed #1783007 : when make p7-zip 4.51 under hp-ux 11.11 error - - - fixed #1789154 : 7z use default or -m0=LZMA runtime error under HP-UX IA11.23 - - - support added for HPUX on Itanium. - (makefile.hpux-acc and makefile.hpux-acc_64) - - -Version 4.54 (never published) -============ - - From Windows version of 7-zip 4.54 : - - Decompression speed was increased - -Version 4.53 -============ - - From Windows version of 7-zip 4.53 : - - The bug in 7-Zip 4.48 - 4.52 beta was fixed: - 7-Zip could create .ZIP archives with broken files. - - Some bugs were fixed. - -Version 4.52 (never published) -============ - - From Windows version of 7-zip 4.52 : - - 7z now can unpack Compound files (msi, doc, ...). - - Some bugs were fixed (CAB decompressing) - - - lzma (CPP/7zip/Compress/LZMA_Alone) is now multi-threaded. - - - fixed #632912 : Extracting large directories takes quadratic time - (this bug was not fully fixed ...) - - - fixed : "7za x -odirectory archive.7z" now works even if "directory" is a symbolic link. - - - makefile.linux_s390x added : support for Linux on IBM z/Series Mainframe with s390x CPU - (thank y_stephen) - - - fixed crashes on BeOs with the flag "@filename" - - - cleanup in the makefile : defining LITTLE_ENDIAN or BIG_ENDIAN is not needed anymore - - - ppmd.exe added (CPP/7zip/Compress/PPMD_Alone) - -Version 4.51 -============ - - From Windows version of 7-zip 4.51 : - - Bug was fixed: 7-Zip 4.50 beta could not open some .7z archives. - - - fix built of test_emul - -Version 4.50 (never published) -============ - - From Windows version of 7-zip 4.50 : - - New switch for command line version: - -ssc[-] enables/disables case-sensitive mode for file names. - - Speed optimizations for AES encryption. - - Some bugs were fixed. - - - contrib/gzip-like_CLI_wrapper_for_7z/p7zip now supports commands like : - p7zip -- -name - p7zip "file name" - p7zip file1 file2 file3 - p7zip -d file1.7z file2.7z file3.7z - - never published because this version does not pass my tests. - -Version 4.49 -============ - - From Windows version of 7-zip 4.49 : - - 7-Zip (7z) now can unpack WIM archives - - - fixed : On Sparc Solaris, core dump during "7z a -sfx exe.x dir" with p7zip compiled with makefile.solaris_sparc_CC_32 - - - some code cleanup - - - On HPUX, p7zip can get the number of CPU and the size of the memory. - - -Version 4.48 -============ - - From Windows version of 7-zip 4.48 : - - Encryption strength for .7z format was increased. - Now it uses random initialization vectors. - - Some bugs were fixed. - - - fixed #1729236 : Makefile infrastructure not safe for parallel compilation - (if your make command understands -C and -j4, copy makefile.parallel_jobs over makefile) - - - Now the executables are not built with the PIC (position-independent code) flag. - 7z.so are still built with the PIC flag. - 7za and 7zr are now faster than 7z with 7z.so. - 7za, 7zr and 7r are now smaller. - - - contrib/gzip-like_CLI_wrapper_for_7z/p7zip now supports spaces in filename - and use 7za instead of 7z. - - - contrib/qnx630sp3 added to support QNX built (thank termterm) - - -Version 4.47 -============ - - From Windows version of 7-zip 4.47 : - - Bugs of 7-Zip 4.46 beta were fixed: BZip2 could work incorrectly - -Version 4.46 (never published) -============ - - - From Windows version of 7-zip 4.46 : - - New fast compression mode for Deflate method in Zip and GZip. - - Some bugs were fixed. - - - LZMA Benchmark : - - cygwin : RAM size detection - - computation of the CPU % - - - fixed #1721827 : install.sh now copies 7z.so - - - Client7z now uses 7z.so instead of 7za.so - - - new target : cygwin with asm - - - LZMA SDK added in the source package (CPP/7zip/Compress/LZMA_Alone) - - - fixed #1716987 : 7zr removed from 4.45 binary distribution - - - fixed #1706002 : make and install.sh use the same variables in the same order. - - -Version 4.45 -============ - - - From Windows version of 7-zip 4.45 : - - Default dictionary size was increased: Normal: 16 MB, Max: 32 MB. - - Speed optimizations. - - Benchmark was improved (new "b" command in command line version). - - The number of DLL files was reduced. - - switch -mhcf=off is not supported now. - - If -t{Type} switch is not specified, 7-Zip now uses extension of archive to detect the type of archive. - - Some bugs were fixed (BZip2 in multithread) - - x86 or x86_64 : ASM version of crc32 available - - - better detection of executable file (scripts do not need BCJ/BCJ2 filter) - - - default permissions are now : - - for a file : -rw------- - - for a directory : drwx------ - - - on MacOSX, locale is always utf8 (because the MacOSX filesystem supports only utf8 filenames) - - - makefile.qnx_static and makefile.qnx_shared added (Thank to termterm) - - -Version 4.44 -============ - - - From Windows version of 7-zip 4.44 : - - 7za : Cab support - - Speed optimizations for LZMA, Deflate, BZip2 and unRAR. - - fix : now, updating a crypted header archive keeps the crypted header - - - fixes in the help displayed by 7za/7z/7zr. - - - code cleanup - - remove of mySetModuleFileNameA (and its memory leak), GetModuleFileName ... - - - fixed : p7zip for DJGPP can now update an archive (thank stranix) - - - fixed : in the plugins of 7z, the "Utf16" state was always off. - - - fixed : support for directory names that are not encoded with the current locale. - (ex : directory name is in "iso 8859-15" whereas the locale is "utf8") - - - patch #1581907 : fix for FreeBSD in contrib/gzip-like_CLI_wrapper_for_7z/p7zip - - - fixed : p7zip can now restore a symbolic link from a Zip archive (archive.zip made with "zip -y") - remark/todo : p7zip stores, in a zip archive, the linked file instead of the symbolic link - - - fixed #1630452 : small fix in the output of the script install.sh - - - fixed #632912 : Extracting large directories takes quadratic time - - - preliminary support of HP-UX : remove of RTLD_GROUP for dlopen in DLL.cpp - makefile.hpux-acc should be able to build 7za for HP-UX (thank furiol) - - - Client7z added. - -Version 4.43 -============ - - From Windows version of 7-zip 4.43 : - - 7-Zip now can use multi-threading mode for compressing to .ZIP archives. - - ZIP format supporting was improved. - - 7-Zip now supports WinZip-compatible AES-256 encryption for .ZIP archives. - - 7-Zip now uses order list (list of extensions) for files sorting for compressing - to .7z archives. It can slightly increase compression ratio in some cases. - - 7-Zip now restores modification time of folders during .7z archives extracting. - - Some bugs were fixed. - - - fixed : the user can now see the percentage indicator. - - - fix "Bugs item #1612285" : doesn't preserve directory timestamps - - - support added for Tru64 / OSF 5.1 (makefile.tru64) - - - small fix "Bugs item #1533765" in install.sh (7zr install) - - - fix "Bugs item #1507913" : "make all" now build 7za and 7zCon.sfx - following the README. - - - manpage updated "bugs item #1509098" : exit codes added - - - manpage updated :-mhe=on (Header encryption) added - - - install.sh now can install the file README, ChangeLog and the directory DOCS - - -Version 4.42 -============ - - From Windows version of 7-zip 4.42 : - - Some bugs were fixed - - - the binaries provided by p7zip_4.XY_x86_linux_bin.tar.bz2 - can now run on Fedora x86_64, - and should now run on any 64bits Linux. - - - patch #1473746 - gzip-like CLI wrapper (for 7z) - see the directory "contrib/gzip-like_CLI_wrapper_for_7z". - - - patch #471478 - Support for OPTFLAGS - This patch allows to use system specific opt flags. - example : make OPTFLAGS="-O2 -march=athlon-xp" - - - the djgpp and cygwin makefile now build "7za" with case insensitive filenames - (Windows filesystem is case insensitive). - - -Version 4.41 -============ - - From Windows version of 7-zip 4.41 : - - Some bugs were fixed - - -Version 4.40 -============ - - - From Windows version of 7-zip 4.40 : - - 7-Zip now can unpack some installers created by NSIS - - Some bugs were fixed - - - format LZH/LHA : fixed directory display during listing or extracting - (a directory does not end with the path separator) - - - patch #1470817 - Handle 7zr in install.sh - - - code cleanup - - -Version 4.39 -============ - - - From Windows version of 7-zip 4.39 : - - Bug in versions 4.33:4.38 was fixed: - 7-Zip could not correctly compress files larger than 2 GB - to 7z archive in fast/fastest modes (HC4 match finder). - - -Version 4.38 -============ - - - From Windows version of 7-zip 4.38 : - - Some bugs were fixed. - - - new manpage : 7zr.1 - - update manpages : 7z.1 and 7za.1 - - new switch : --help - - - patch #1465026 - Patch for install.sh for packagers - - - DosDateTimeToFileTime fixed (rar format) - - - contrib/VirtualFileSystemForMidnightCommander/u7z updated - (thank sgh_punk) - - -Version 4.37 -============ - - From Windows version of 7-zip 4.37 : - - Some bugs were fixed. - - - fix build for Solaris sparc with CC instead of g++. - - - fix build for Solaris 9 x86 - - fix build for Solaris 10 x86 - - fix build for OpenBSD - - p7zip can now be build with djgpp. - - new target : 7zr (light version of 7za) - - new machine : IBM AIX - -Version 4.36 -============ - - From Windows version of 7-zip 4.36 : - - 7-zip now can unpack ISO archives - - - GCC 4.X : add C++ visibility support to reduce the size of the *.so - (see makefile.linux_x86_ppc_alpha__gcc_4.X) - - - cygwin now supports '-o/tmp' - -Version 4.35 -============ - - From Windows version of 7-zip 4.35 : - - New switch : -slt ("l" (list) command with -slt shows technical information for archive). - - Some bugs were fixed. - - - From Windows version of 7-zip 4.34 : - - BZip2 compressing / decompressing now can work in multi-threading mode - - Multi-threading mode now is default for multi-processor systems - -Version 4.33 -============ - - From Windows version of 7-zip 4.33 : - - Compressing speed and Memory requirements were increased. - Default dictionary size was increased: Fastest: 64 KB, Fast: 1 MB, - Normal: 4 MB, Max: 16 MB, Ultra: 64 MB. - - 64-bit version now supports 1 GB dictionary - - 7z/LZMA now can use only these match finders: HC4, BT2, BT3, BT4 - - Compression ratio in Zip/GZip/Deflate in Ultra mode was increased - - Some bugs were fixed - - - fix "Bugs item #1407358" : Passwords entered are not visible on command line - if the target has the system function "getpass". - - - fix "BCJ2" : now p7zip uses the "BCJ2" filter when the file has execute permission - (7-zip uses the "BCJ2" filter when the filename ends with ".dll", ".exe", ".ocx", ".sfx" or ".sys") - - - patch #1390722 : no new line at end of file - - - patch #1390716 : allow compiling with gcc-4.1 - - - patch #1425862 : allow other make programs than GNU make - - - Testing framework added ("make test" and "make test_7z") - - - fix 'lstat' : p7zip can compile if 'lstat' is not available - -Version 4.30 -============ - - From Windows version of 7-zip 4.30 : - - Speed optimizations in LZMA maximum/ultra compressing. - - LZMA now supports word size up to 273 - - 7-Zip now reduces dictionary size for LZMA, if you compress files - smaller than specified dictionary size. - - Some bugs were fixed - - - fix minor build trouble with MacOS X - - fix "Bugs item #1349229" : 7-zip now displays "e: Extract files from archive (without using directory names)" - -Version 4.29 -============ - - - fix "Bugs item #1305781" : "7z a -sfx" sets the execute-flag - and does not add ".exe" extension. - - - fix "Bugs item #1306783" : "7za a /tmp/t.7z /etc/passwd" - - - fix "Bugs item #1304797" : @lists don't handle files starting with ./ - - - fix "Bugs item #1309287" : man 7za fails after install - -Version 4.27 -============ - - From Windows version of 7-zip 4.27 : - - new plugin for 7z : 7-Zip can unpack CHM/HXS (MS HTML HELP) archives - - cab plugin for 7z : 7-Zip can unpack multivolume CAB archives - - Some bugs were fixed - - better support for 64bits (PPMD coder/decoder) - -Version 4.26 -============ - - From Windows version of 7-zip 4.26 : - - new plugin for 7z : LZH format support (extracting only) - - - fix (courtesy from Robert Millan) to make p7zip compile on GNU/kFreeBSD. - - - fix "Bug item #1273057", now "7z -so -t7z a dummy.7z file >output.7z" does not - finish with a "Segmentation fault (core dumped)". - - - fix "Bug item #1221056", now, makefile for p7zip use the flag "-O" to - support compilers that build invalid programs with the flag "-O2". - -Version 4.25 -============ - - From Windows version of 7-zip 4.25 : - - Some bugs were fixed - - DOCS/MANUAL/exit_codes.htm added - - - new plugin for 7z : RAR format support (extracting only) - - - better dependencies in makefile - -Version 4.23 -============ - - From Windows version of 7-zip 4.23 : - - Some bugs were fixed - - - manpages for 7za and 7z updated by Mohammed Adnene Trojette. - - - little fix for the help message of 7za or 7z. - - - bug #1224304 : Files and directories with \ in name not handled properly. - - - fix for tar archives that have pax header. - -Version 4.20 -============ - - - From Windows version of 7-zip 4.19 and 4.20 : - - BZip2 code was rewritten. Now it supports 3 modes: Normal, Maximum and - Ultra. In Normal mode it compresses almost as original BZip2 compressor. - Compression ratio in Maximum and Ultra modes is 1-3% better for some files, - but Maximum Mode is about 3 times slower and Ultra Mode is about 8 times - slower than Normal mode. - - Console version now prints all messages to stdout by default, - and if -so switch is specified, 7-Zip prints messages to stderr. - - Some bugs were fixed - - - Updating "contrib/VirtualFileSystemForMidnightCommander/" with u7z-4.16beta.tar.bz2 - - - bug #1204993 (does not find broken filenames) - - - bug #1201244 (Missing files in p7zip_4.18_x86_linux_bin.tar.bz2) - - - makefile.linux_x86_ppc_alpha : flag "-fPIC" added - - - flag "-l" added. - without : p7zip stores symlinks (like p7zip 4.18) - with "-l" : p7zip stores the files/directories pointed by symlinks (like before p7zip 4.18) - CAUTION : the scanning stage can never end because of symlinks like ".." - (ex: ln -s .. ldir) - -Version 4.18 -============ - - - From Windows version of 7-zip 4.18 and 4.17 : - - minor fixes - - - p7zip can now store and restore : - - symbolic links, - - file permission bits - Remark : for directory, restored_perm = stored_perm | 0700 . - - - fix in install.sh - - - On MacOSX, p7zip now restore times of a file. - - - more detailed errors during scanning stage. - - -Version 4.16 -============ - - - From Windows version of 7-zip 4.16 : - - Speed optimization (5%) for 7z / LZMA - - 7za now supports .Z archives - - -r- switch in command line now is default for all commands - - Some bugs were fixed - - bug #1119193 (list mode output confusing/wrong) - - - From Windows version of 7-zip 4.15 : - - Z format supporting (extracting only) - - 7-Zip now can extract ZIP archives compressed with "Shrink" method - - 7-Zip now doesn't interrupt the compressing when it can not open file. - 7-Zip just skips that file and shows warning. - - Some bugs were fixed - - - man pages added (thank Mohammed Adnene Trojette) - - bug #1112167 fixed (Temporary directory must be on same partition as target) - p7zip failed moving the temporary file at the end of - compressing to target file if the directories don't reside - on the same partition (or network path). - - bug #1164659 fixed (Invalid file date for "big endian" machine) - - p7zip now uses ".so" instead of ".dll" - - p7zip now handles "ctrl-c" and "kill" to cleanup temporary files before exiting - - p7zip now runs on BeOS. - - better support of filenames with spaces. - - some code cleanup - - "myWindows/myFiles.cpp" is now in "Windows/FileIO.cpp" - - "myWindows/myFindFile.cpp" is now in "Windows/FileFind.cpp" - - "myWindows/myDirectoryAndPath.cpp" is now in "Windows/FileDir.cpp" - - "myWindows/myEvents.cpp" is now in "Windows/Synchronization.cpp" - - "myWindows/wine_strings.cpp" is now in "Windows/String.cpp" - - -Version 4.14.01 -=============== - - huge speed up for multi CPUs machines (Thanks to loderunner - http://sourceforge.net/users/loderunner/). - - some code cleanup - - Fix problems with link files or directories. - - "7z a dummy -tgzip -so Doc.txt > archive.gz" now works. - - in the messages, the path separator is now '/' instead of '\'. - -Version 4.14 -============ - - - From Windows version of 7-zip 4.14 : - - STL using was reduced - - 7za now supports Split(001) archives - - "7za | more" now works - - Bugs item #1093095 : Usage banner now says "7za" (instead of "7z") when the binary is "7za" - - - use of AString instead of std::string (no more need of #include ") - - makefile.linux_gcc_2.95_no_need_for_libstdc added to build 7za for the - p7zip*_bin.tar.bz2 package. - 7za provided by p7zip*_bin.tar.bz2 is build on Debian 3.0 with gcc 2.95.4 - and should now find the locale on all kinds of Linux (Debian, Fedora, Mandrake, ...). - -Version 4.13 -============ - - new port of 7za from the source of 7za 4.13Beta for Windows - - - From Windows version of 7-zip 4.13 : - - Switch "--" stops switches parsing - - Some bugs were fixed - - User's manual updated (DOCS/MANUAL/index.htm) - - - makefile.netbsd_x86 added [Bug #1069055]. - - - new method to install 7z and its plugins (the "link" method do no work) - - - installer added (install.sh). - - - makefile.macosx_with_fink becomes makefile.macosx - and makefile.macosx uses c++ instead of CC - (on some MacOSX, CC is a link to gcc instead of g++) - - - new flag "-utf16" to enable "utf16" conversion [Bug #1075229]. - - - new logic to automatically enable or disable "utf16" conversion : - no locale, locale=="C" or locale=="POSIX" implies utf16=off - else utf16=on - uses "-utf16" or "-no-utf16" to change this behaviour. - [Bug #1075229] - - - 7z (compiled with -O2) works now on Sparc Solaris. - -Version 4.12 -============ - - new port of 7za from the source of 7za 4.12Beta for Windows - - - From Windows version of 7-zip 4.11 and 4.12 : - - 7-Zip now supports Zip64 extension of ZIP format. So now it's - possible to compress files bigger than 4 GB to ZIP archives. - - Some bugs were fixed - - - fix "7za a archive.7z file" that added all the files and directories - with filename "file", "FILE", "File" ... - - - p7zip now displays the locale (ex : en_US.UTF-8) in the banner. - - - new flag "-no-utf16" to avoid lossly conversion in filenames. - CAUTION : use this flag when you do not plan to export your archive. - - - support creation of self extracting archive. - - - better support of symbolic link (now, an invalid symbolic link - do not stop archiving but displays a warning). - - - better support of files that the user cannot read. - (now this kind of file is not added to the archive, and p7zip displays a warning). - - - return of 7z and its plugins. - - - support of listing/testing/extracting files from a splitted archive (only with 7z). - - - support of MacOX X 10.X. - - - creation of Gzip/Tar archives didn't work on Linux Alpha. - - - see "contrib/VirtualFileSystemForMidnightCommander/readme" to use 7za with "mc". - -Version 4.10 -============ - - new port of 7za from the source of 7za 4.10Beta for Windows - => p7zip now work on big endian CPU. - - - 7z for Unix is not maintain anymore (because as the source of unrar plugin for 7z - is not available, 7z is unless on Unix). - -Version 0.91 -============ - - add support for FreeBSD 5.2.1 - In Windows/Time.h add "#include " - and prototype change for FileTimeToUnixTime() - - - bug 990684 Corrected : support of filesystem - that support case sensitive filenames. - Example, since version 0.91 : - "7z a glibc -r glibc-2.3.2" - does not terminate with error : - Duplicate filename: - glibc-2.3.2\sysdeps\m88k\m88100\add_n.S - glibc-2.3.2\sysdeps\m88k\m88100\add_n.s - -Version 0.90 -============ - - build of 7z.exe and its DLL. - 7z.exe support more archive formats than 7za.exe - thanks to DLL in Formats and Codecs directories - - "#pragma once" is now in comments - - mainly For OpenBSD : - - add #include in include_windows/winnt.h - - remove stuff for GUID_SECTION and GUID_SECT in include_windows/basetyps.h - and include_windows/initguid.h - - some changes in 7zip/Crypto/aesopt.h because of endian.h - -Version 0.81 -============ - - add a copy of the help of 7-zip (see html directory) - - "7z a -r tmp.7z directory" works as expected. - no more need for commands like : 7z a -r tmp.7z "directory/*" - - 7z restores the date of each files (but not directories) - - 7z supports UNICODE filenames (version 0.80 supports only ASCII/Latin1 filenames) - - support of gcc 2.95 - - support of gcc 3.4 - - 7z needs no more libgen.h (dirname() and basename()) - - less "Internal Error #7" during arguments parsing - - minor change in class CThread - -Version 0.80 -============ - - First public release - - support of gcc 3.2 and 3.3 - diff -Nru p7zip-rar-16.02/DOC/7zC.txt p7zip-rar-16.02+really25.00+ds/DOC/7zC.txt --- p7zip-rar-16.02/DOC/7zC.txt 2014-12-21 12:44:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/7zC.txt 2014-12-03 14:35:44.000000000 +0000 @@ -1,187 +1,187 @@ -7z ANSI-C Decoder 9.35 ----------------------- - -7z ANSI-C provides 7z/LZMA decoding. -7z ANSI-C version is simplified version ported from C++ code. - -LZMA is default and general compression method of 7z format -in 7-Zip compression program (www.7-zip.org). LZMA provides high -compression ratio and very fast decompression. - - -LICENSE -------- - -7z ANSI-C Decoder is part of the LZMA SDK. -LZMA SDK is written and placed in the public domain by Igor Pavlov. - -Files ---------------------- - -7zDecode.* - Low level 7z decoding -7zExtract.* - High level 7z decoding -7zHeader.* - .7z format constants -7zIn.* - .7z archive opening -7zItem.* - .7z structures -7zMain.c - Test application - - -How To Use ----------- - -You can create .7z archive with 7z.exe, 7za.exe or 7zr.exe: - - 7z.exe a archive.7z *.htm -r -mx -m0fb=255 - -If you have big number of files in archive, and you need fast extracting, -you can use partly-solid archives: - - 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K - -In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only -512KB for extracting one file from such archive. - - -Limitations of current version of 7z ANSI-C Decoder ---------------------------------------------------- - - - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive. - - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters. - - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names. - -These limitations will be fixed in future versions. - - -Using 7z ANSI-C Decoder Test application: ------------------------------------------ - -Usage: 7zDec - -: - e: Extract files from archive - l: List contents of archive - t: Test integrity of archive - -Example: - - 7zDec l archive.7z - -lists contents of archive.7z - - 7zDec e archive.7z - -extracts files from archive.7z to current folder. - - -How to use .7z Decoder ----------------------- - -Memory allocation -~~~~~~~~~~~~~~~~~ - -7z Decoder uses two memory pools: -1) Temporary pool -2) Main pool -Such scheme can allow you to avoid fragmentation of allocated blocks. - - -Steps for using 7z decoder --------------------------- - -Use code at 7zMain.c as example. - -1) Declare variables: - inStream /* implements ILookInStream interface */ - CSzArEx db; /* 7z archive database structure */ - ISzAlloc allocImp; /* memory functions for main pool */ - ISzAlloc allocTempImp; /* memory functions for temporary pool */ - -2) call CrcGenerateTable(); function to initialize CRC structures. - -3) call SzArEx_Init(&db); function to initialize db structures. - -4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive - -This function opens archive "inStream" and reads headers to "db". -All items in "db" will be allocated with "allocMain" functions. -SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions. - -5) List items or Extract items - - Listing code: - ~~~~~~~~~~~~~ - - Use SzArEx_GetFileNameUtf16 function. Look example code in C\Util\7z\7zMain.c file. - - - Extracting code: - ~~~~~~~~~~~~~~~~ - - SZ_RESULT SzAr_Extract( - CArchiveDatabaseEx *db, - ILookInStream *inStream, - UInt32 fileIndex, /* index of file */ - UInt32 *blockIndex, /* index of solid block */ - Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - - If you need to decompress more than one file, you can send these values from previous call: - blockIndex, - outBuffer, - outBufferSize, - You can consider "outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - After decompressing you must free "outBuffer": - allocImp.Free(outBuffer); - -6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db". - - - - -Memory requirements for .7z decoding ------------------------------------- - -Memory usage for Archive opening: - - Temporary pool: - - Memory for uncompressed .7z headers - - some other temporary blocks - - Main pool: - - Memory for database: - Estimated size of one file structures in solid archive: - - Size (4 or 8 Bytes) - - CRC32 (4 bytes) - - LastWriteTime (8 bytes) - - Some file information (4 bytes) - - File Name (variable length) + pointer + allocation structures - -Memory usage for archive Decompressing: - - Temporary pool: - - Memory for LZMA decompressing structures - - Main pool: - - Memory for decompressed solid block - - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these - temprorary buffers can be about 15% of solid block size. - - -7z Decoder doesn't allocate memory for compressed blocks. -Instead of this, you must allocate buffer with desired -size before calling 7z Decoder. Use 7zMain.c as example. - - -Defines -------- - -_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr. - - ---- - -http://www.7-zip.org -http://www.7-zip.org/sdk.html -http://www.7-zip.org/support.html +7z ANSI-C Decoder 9.35 +---------------------- + +7z ANSI-C provides 7z/LZMA decoding. +7z ANSI-C version is simplified version ported from C++ code. + +LZMA is default and general compression method of 7z format +in 7-Zip compression program (www.7-zip.org). LZMA provides high +compression ratio and very fast decompression. + + +LICENSE +------- + +7z ANSI-C Decoder is part of the LZMA SDK. +LZMA SDK is written and placed in the public domain by Igor Pavlov. + +Files +--------------------- + +7zDecode.* - Low level 7z decoding +7zExtract.* - High level 7z decoding +7zHeader.* - .7z format constants +7zIn.* - .7z archive opening +7zItem.* - .7z structures +7zMain.c - Test application + + +How To Use +---------- + +You can create .7z archive with 7z.exe, 7za.exe or 7zr.exe: + + 7z.exe a archive.7z *.htm -r -mx -m0fb=255 + +If you have big number of files in archive, and you need fast extracting, +you can use partly-solid archives: + + 7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K + +In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only +512KB for extracting one file from such archive. + + +Limitations of current version of 7z ANSI-C Decoder +--------------------------------------------------- + + - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive. + - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters. + - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names. + +These limitations will be fixed in future versions. + + +Using 7z ANSI-C Decoder Test application: +----------------------------------------- + +Usage: 7zDec + +: + e: Extract files from archive + l: List contents of archive + t: Test integrity of archive + +Example: + + 7zDec l archive.7z + +lists contents of archive.7z + + 7zDec e archive.7z + +extracts files from archive.7z to current folder. + + +How to use .7z Decoder +---------------------- + +Memory allocation +~~~~~~~~~~~~~~~~~ + +7z Decoder uses two memory pools: +1) Temporary pool +2) Main pool +Such scheme can allow you to avoid fragmentation of allocated blocks. + + +Steps for using 7z decoder +-------------------------- + +Use code at 7zMain.c as example. + +1) Declare variables: + inStream /* implements ILookInStream interface */ + CSzArEx db; /* 7z archive database structure */ + ISzAlloc allocImp; /* memory functions for main pool */ + ISzAlloc allocTempImp; /* memory functions for temporary pool */ + +2) call CrcGenerateTable(); function to initialize CRC structures. + +3) call SzArEx_Init(&db); function to initialize db structures. + +4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive + +This function opens archive "inStream" and reads headers to "db". +All items in "db" will be allocated with "allocMain" functions. +SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions. + +5) List items or Extract items + + Listing code: + ~~~~~~~~~~~~~ + + Use SzArEx_GetFileNameUtf16 function. Look example code in C\Util\7z\7zMain.c file. + + + Extracting code: + ~~~~~~~~~~~~~~~~ + + SZ_RESULT SzAr_Extract( + CArchiveDatabaseEx *db, + ILookInStream *inStream, + UInt32 fileIndex, /* index of file */ + UInt32 *blockIndex, /* index of solid block */ + Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + + If you need to decompress more than one file, you can send these values from previous call: + blockIndex, + outBuffer, + outBufferSize, + You can consider "outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + After decompressing you must free "outBuffer": + allocImp.Free(outBuffer); + +6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db". + + + + +Memory requirements for .7z decoding +------------------------------------ + +Memory usage for Archive opening: + - Temporary pool: + - Memory for uncompressed .7z headers + - some other temporary blocks + - Main pool: + - Memory for database: + Estimated size of one file structures in solid archive: + - Size (4 or 8 Bytes) + - CRC32 (4 bytes) + - LastWriteTime (8 bytes) + - Some file information (4 bytes) + - File Name (variable length) + pointer + allocation structures + +Memory usage for archive Decompressing: + - Temporary pool: + - Memory for LZMA decompressing structures + - Main pool: + - Memory for decompressed solid block + - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these + temprorary buffers can be about 15% of solid block size. + + +7z Decoder doesn't allocate memory for compressed blocks. +Instead of this, you must allocate buffer with desired +size before calling 7z Decoder. Use 7zMain.c as example. + + +Defines +------- + +_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr. + + +--- + +http://www.7-zip.org +http://www.7-zip.org/sdk.html +http://www.7-zip.org/support.html diff -Nru p7zip-rar-16.02/DOC/7zFormat.txt p7zip-rar-16.02+really25.00+ds/DOC/7zFormat.txt --- p7zip-rar-16.02/DOC/7zFormat.txt 2010-10-20 04:56:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/7zFormat.txt 2018-05-12 05:15:22.000000000 +0000 @@ -1,469 +1,469 @@ -7z Format description (4.59) ----------------------------- - -This file contains description of 7z archive format. -7z archive can contain files compressed with any method. -See "Methods.txt" for description for defined compressing methods. - - -Format structure Overview -------------------------- - -Some fields can be optional. - -Archive structure -~~~~~~~~~~~~~~~~~ -SignatureHeader -[PackedStreams] -[PackedStreamsForHeaders] -[ - Header - or - { - Packed Header - HeaderInfo - } -] - - - -Header structure -~~~~~~~~~~~~~~~~ -{ - ArchiveProperties - AdditionalStreams - { - PackInfo - { - PackPos - NumPackStreams - Sizes[NumPackStreams] - CRCs[NumPackStreams] - } - CodersInfo - { - NumFolders - Folders[NumFolders] - { - NumCoders - CodersInfo[NumCoders] - { - ID - NumInStreams; - NumOutStreams; - PropertiesSize - Properties[PropertiesSize] - } - NumBindPairs - BindPairsInfo[NumBindPairs] - { - InIndex; - OutIndex; - } - PackedIndices - } - UnPackSize[Folders][Folders.NumOutstreams] - CRCs[NumFolders] - } - SubStreamsInfo - { - NumUnPackStreamsInFolders[NumFolders]; - UnPackSizes[] - CRCs[] - } - } - MainStreamsInfo - { - (Same as in AdditionalStreams) - } - FilesInfo - { - NumFiles - Properties[] - { - ID - Size - Data - } - } -} - -HeaderInfo structure -~~~~~~~~~~~~~~~~~~~~ -{ - (Same as in AdditionalStreams) -} - - - -Notes about Notation and encoding ---------------------------------- - -7z uses little endian encoding. - -7z archive format has optional headers that are marked as -[] -Header -[] - -REAL_UINT64 means real UINT64. - -UINT64 means real UINT64 encoded with the following scheme: - - Size of encoding sequence depends from first byte: - First_Byte Extra_Bytes Value - (binary) - 0xxxxxxx : ( xxxxxxx ) - 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y - 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y - ... - 1111110x BYTE y[6] : ( x << (8 * 6)) + y - 11111110 BYTE y[7] : y - 11111111 BYTE y[8] : y - - - -Property IDs ------------- - -0x00 = kEnd - -0x01 = kHeader - -0x02 = kArchiveProperties - -0x03 = kAdditionalStreamsInfo -0x04 = kMainStreamsInfo -0x05 = kFilesInfo - -0x06 = kPackInfo -0x07 = kUnPackInfo -0x08 = kSubStreamsInfo - -0x09 = kSize -0x0A = kCRC - -0x0B = kFolder - -0x0C = kCodersUnPackSize -0x0D = kNumUnPackStream - -0x0E = kEmptyStream -0x0F = kEmptyFile -0x10 = kAnti - -0x11 = kName -0x12 = kCTime -0x13 = kATime -0x14 = kMTime -0x15 = kWinAttributes -0x16 = kComment - -0x17 = kEncodedHeader - -0x18 = kStartPos -0x19 = kDummy - - -7z format headers ------------------ - -SignatureHeader -~~~~~~~~~~~~~~~ - BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - - ArchiveVersion - { - BYTE Major; // now = 0 - BYTE Minor; // now = 2 - }; - - UINT32 StartHeaderCRC; - - StartHeader - { - REAL_UINT64 NextHeaderOffset - REAL_UINT64 NextHeaderSize - UINT32 NextHeaderCRC - } - - -........................... - - -ArchiveProperties -~~~~~~~~~~~~~~~~~ -BYTE NID::kArchiveProperties (0x02) -for (;;) -{ - BYTE PropertyType; - if (aType == 0) - break; - UINT64 PropertySize; - BYTE PropertyData[PropertySize]; -} - - -Digests (NumStreams) -~~~~~~~~~~~~~~~~~~~~~ - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumStreams) - BIT Defined - } - UINT32 CRCs[NumDefined] - - -PackInfo -~~~~~~~~~~~~ - BYTE NID::kPackInfo (0x06) - UINT64 PackPos - UINT64 NumPackStreams - - [] - BYTE NID::kSize (0x09) - UINT64 PackSizes[NumPackStreams] - [] - - [] - BYTE NID::kCRC (0x0A) - PackStreamDigests[NumPackStreams] - [] - - BYTE NID::kEnd - - -Folder -~~~~~~ - UINT64 NumCoders; - for (NumCoders) - { - BYTE - { - 0:3 CodecIdSize - 4: Is Complex Coder - 5: There Are Attributes - 6: Reserved - 7: There are more alternative methods. (Not used anymore, must be 0). - } - BYTE CodecId[CodecIdSize] - if (Is Complex Coder) - { - UINT64 NumInStreams; - UINT64 NumOutStreams; - } - if (There Are Attributes) - { - UINT64 PropertiesSize - BYTE Properties[PropertiesSize] - } - } - - NumBindPairs = NumOutStreamsTotal - 1; - - for (NumBindPairs) - { - UINT64 InIndex; - UINT64 OutIndex; - } - - NumPackedStreams = NumInStreamsTotal - NumBindPairs; - if (NumPackedStreams > 1) - for(NumPackedStreams) - { - UINT64 Index; - }; - - - - -Coders Info -~~~~~~~~~~~ - - BYTE NID::kUnPackInfo (0x07) - - - BYTE NID::kFolder (0x0B) - UINT64 NumFolders - BYTE External - switch(External) - { - case 0: - Folders[NumFolders] - case 1: - UINT64 DataStreamIndex - } - - - BYTE ID::kCodersUnPackSize (0x0C) - for(Folders) - for(Folder.NumOutStreams) - UINT64 UnPackSize; - - - [] - BYTE NID::kCRC (0x0A) - UnPackDigests[NumFolders] - [] - - - - BYTE NID::kEnd - - - -SubStreams Info -~~~~~~~~~~~~~~ - BYTE NID::kSubStreamsInfo; (0x08) - - [] - BYTE NID::kNumUnPackStream; (0x0D) - UINT64 NumUnPackStreamsInFolders[NumFolders]; - [] - - - [] - BYTE NID::kSize (0x09) - UINT64 UnPackSizes[] - [] - - - [] - BYTE NID::kCRC (0x0A) - Digests[Number of streams with unknown CRC] - [] - - - BYTE NID::kEnd - - -Streams Info -~~~~~~~~~~~~ - - [] - PackInfo - [] - - - [] - CodersInfo - [] - - - [] - SubStreamsInfo - [] - - BYTE NID::kEnd - - -FilesInfo -~~~~~~~~~ - BYTE NID::kFilesInfo; (0x05) - UINT64 NumFiles - - for (;;) - { - BYTE PropertyType; - if (aType == 0) - break; - - UINT64 Size; - - switch(PropertyType) - { - kEmptyStream: (0x0E) - for(NumFiles) - BIT IsEmptyStream - - kEmptyFile: (0x0F) - for(EmptyStreams) - BIT IsEmptyFile - - kAnti: (0x10) - for(EmptyStreams) - BIT IsAntiFile - - case kCTime: (0x12) - case kATime: (0x13) - case kMTime: (0x14) - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumFiles) - BIT TimeDefined - } - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Definded Items) - UINT64 Time - [] - - kNames: (0x11) - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Files) - { - wchar_t Names[NameSize]; - wchar_t 0; - } - [] - - kAttributes: (0x15) - BYTE AllAreDefined - if (AllAreDefined == 0) - { - for(NumFiles) - BIT AttributesAreDefined - } - BYTE External; - if(External != 0) - UINT64 DataIndex - [] - for(Definded Attributes) - UINT32 Attributes - [] - } - } - - -Header -~~~~~~ - BYTE NID::kHeader (0x01) - - [] - ArchiveProperties - [] - - [] - BYTE NID::kAdditionalStreamsInfo; (0x03) - StreamsInfo - [] - - [] - BYTE NID::kMainStreamsInfo; (0x04) - StreamsInfo - [] - - [] - FilesInfo - [] - - BYTE NID::kEnd - - -HeaderInfo -~~~~~~~~~~ - [] - BYTE NID::kEncodedHeader; (0x17) - StreamsInfo for Encoded Header - [] - - ---- -End of document +7z Format description (18.06) +---------------------------- + +This file contains description of 7z archive format. +7z archive can contain files compressed with any method. +See "Methods.txt" for description for defined compressing methods. + + +Format structure Overview +------------------------- + +Some fields can be optional. + +Archive structure +~~~~~~~~~~~~~~~~~ +SignatureHeader +[PackedStreams] +[PackedStreamsForHeaders] +[ + Header + or + { + Packed Header + HeaderInfo + } +] + + + +Header structure +~~~~~~~~~~~~~~~~ +{ + ArchiveProperties + AdditionalStreams + { + PackInfo + { + PackPos + NumPackStreams + Sizes[NumPackStreams] + CRCs[NumPackStreams] + } + CodersInfo + { + NumFolders + Folders[NumFolders] + { + NumCoders + CodersInfo[NumCoders] + { + ID + NumInStreams; + NumOutStreams; + PropertiesSize + Properties[PropertiesSize] + } + NumBindPairs + BindPairsInfo[NumBindPairs] + { + InIndex; + OutIndex; + } + PackedIndices + } + UnPackSize[Folders][Folders.NumOutstreams] + CRCs[NumFolders] + } + SubStreamsInfo + { + NumUnPackStreamsInFolders[NumFolders]; + UnPackSizes[] + CRCs[] + } + } + MainStreamsInfo + { + (Same as in AdditionalStreams) + } + FilesInfo + { + NumFiles + Properties[] + { + ID + Size + Data + } + } +} + +HeaderInfo structure +~~~~~~~~~~~~~~~~~~~~ +{ + (Same as in AdditionalStreams) +} + + + +Notes about Notation and encoding +--------------------------------- + +7z uses little endian encoding. + +7z archive format has optional headers that are marked as +[] +Header +[] + +REAL_UINT64 means real UINT64. + +UINT64 means real UINT64 encoded with the following scheme: + + Size of encoding sequence depends from first byte: + First_Byte Extra_Bytes Value + (binary) + 0xxxxxxx : ( xxxxxxx ) + 10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y + 110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y + ... + 1111110x BYTE y[6] : ( x << (8 * 6)) + y + 11111110 BYTE y[7] : y + 11111111 BYTE y[8] : y + + + +Property IDs +------------ + +0x00 = kEnd + +0x01 = kHeader + +0x02 = kArchiveProperties + +0x03 = kAdditionalStreamsInfo +0x04 = kMainStreamsInfo +0x05 = kFilesInfo + +0x06 = kPackInfo +0x07 = kUnPackInfo +0x08 = kSubStreamsInfo + +0x09 = kSize +0x0A = kCRC + +0x0B = kFolder + +0x0C = kCodersUnPackSize +0x0D = kNumUnPackStream + +0x0E = kEmptyStream +0x0F = kEmptyFile +0x10 = kAnti + +0x11 = kName +0x12 = kCTime +0x13 = kATime +0x14 = kMTime +0x15 = kWinAttributes +0x16 = kComment + +0x17 = kEncodedHeader + +0x18 = kStartPos +0x19 = kDummy + + +7z format headers +----------------- + +SignatureHeader +~~~~~~~~~~~~~~~ + BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + + ArchiveVersion + { + BYTE Major; // now = 0 + BYTE Minor; // now = 4 + }; + + UINT32 StartHeaderCRC; + + StartHeader + { + REAL_UINT64 NextHeaderOffset + REAL_UINT64 NextHeaderSize + UINT32 NextHeaderCRC + } + + +........................... + + +ArchiveProperties +~~~~~~~~~~~~~~~~~ +BYTE NID::kArchiveProperties (0x02) +for (;;) +{ + BYTE PropertyType; + if (aType == 0) + break; + UINT64 PropertySize; + BYTE PropertyData[PropertySize]; +} + + +Digests (NumStreams) +~~~~~~~~~~~~~~~~~~~~~ + BYTE AllAreDefined + if (AllAreDefined == 0) + { + for(NumStreams) + BIT Defined + } + UINT32 CRCs[NumDefined] + + +PackInfo +~~~~~~~~~~~~ + BYTE NID::kPackInfo (0x06) + UINT64 PackPos + UINT64 NumPackStreams + + [] + BYTE NID::kSize (0x09) + UINT64 PackSizes[NumPackStreams] + [] + + [] + BYTE NID::kCRC (0x0A) + PackStreamDigests[NumPackStreams] + [] + + BYTE NID::kEnd + + +Folder +~~~~~~ + UINT64 NumCoders; + for (NumCoders) + { + BYTE + { + 0:3 CodecIdSize + 4: Is Complex Coder + 5: There Are Attributes + 6: Reserved + 7: There are more alternative methods. (Not used anymore, must be 0). + } + BYTE CodecId[CodecIdSize] + if (Is Complex Coder) + { + UINT64 NumInStreams; + UINT64 NumOutStreams; + } + if (There Are Attributes) + { + UINT64 PropertiesSize + BYTE Properties[PropertiesSize] + } + } + + NumBindPairs = NumOutStreamsTotal - 1; + + for (NumBindPairs) + { + UINT64 InIndex; + UINT64 OutIndex; + } + + NumPackedStreams = NumInStreamsTotal - NumBindPairs; + if (NumPackedStreams > 1) + for(NumPackedStreams) + { + UINT64 Index; + }; + + + + +Coders Info +~~~~~~~~~~~ + + BYTE NID::kUnPackInfo (0x07) + + + BYTE NID::kFolder (0x0B) + UINT64 NumFolders + BYTE External + switch(External) + { + case 0: + Folders[NumFolders] + case 1: + UINT64 DataStreamIndex + } + + + BYTE ID::kCodersUnPackSize (0x0C) + for(Folders) + for(Folder.NumOutStreams) + UINT64 UnPackSize; + + + [] + BYTE NID::kCRC (0x0A) + UnPackDigests[NumFolders] + [] + + + + BYTE NID::kEnd + + + +SubStreams Info +~~~~~~~~~~~~~~ + BYTE NID::kSubStreamsInfo; (0x08) + + [] + BYTE NID::kNumUnPackStream; (0x0D) + UINT64 NumUnPackStreamsInFolders[NumFolders]; + [] + + + [] + BYTE NID::kSize (0x09) + UINT64 UnPackSizes[] + [] + + + [] + BYTE NID::kCRC (0x0A) + Digests[Number of streams with unknown CRC] + [] + + + BYTE NID::kEnd + + +Streams Info +~~~~~~~~~~~~ + + [] + PackInfo + [] + + + [] + CodersInfo + [] + + + [] + SubStreamsInfo + [] + + BYTE NID::kEnd + + +FilesInfo +~~~~~~~~~ + BYTE NID::kFilesInfo; (0x05) + UINT64 NumFiles + + for (;;) + { + BYTE PropertyType; + if (aType == 0) + break; + + UINT64 Size; + + switch(PropertyType) + { + kEmptyStream: (0x0E) + for(NumFiles) + BIT IsEmptyStream + + kEmptyFile: (0x0F) + for(EmptyStreams) + BIT IsEmptyFile + + kAnti: (0x10) + for(EmptyStreams) + BIT IsAntiFile + + case kCTime: (0x12) + case kATime: (0x13) + case kMTime: (0x14) + BYTE AllAreDefined + if (AllAreDefined == 0) + { + for(NumFiles) + BIT TimeDefined + } + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Definded Items) + REAL_UINT64 Time + [] + + kNames: (0x11) + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Files) + { + wchar_t Names[NameSize]; + wchar_t 0; + } + [] + + kAttributes: (0x15) + BYTE AllAreDefined + if (AllAreDefined == 0) + { + for(NumFiles) + BIT AttributesAreDefined + } + BYTE External; + if(External != 0) + UINT64 DataIndex + [] + for(Definded Attributes) + UINT32 Attributes + [] + } + } + + +Header +~~~~~~ + BYTE NID::kHeader (0x01) + + [] + ArchiveProperties + [] + + [] + BYTE NID::kAdditionalStreamsInfo; (0x03) + StreamsInfo + [] + + [] + BYTE NID::kMainStreamsInfo; (0x04) + StreamsInfo + [] + + [] + FilesInfo + [] + + BYTE NID::kEnd + + +HeaderInfo +~~~~~~~~~~ + [] + BYTE NID::kEncodedHeader; (0x17) + StreamsInfo for Encoded Header + [] + + +--- +End of document diff -Nru p7zip-rar-16.02/DOC/7zip.hhp p7zip-rar-16.02+really25.00+ds/DOC/7zip.hhp --- p7zip-rar-16.02/DOC/7zip.hhp 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/7zip.hhp 2024-03-26 15:33:07.000000000 +0000 @@ -0,0 +1,84 @@ +[OPTIONS] +Compatibility=1.1 or later +Compiled file=7-zip.chm +Contents file=7zip.hhc +Default topic=start.htm +Display compile progress=No +Full-text search=Yes +Index file=7zip.hhk +Language=0x409 English (United States) + + +[FILES] +start.htm +general\thanks.htm +general\faq.htm +general\formats.htm +general\index.htm +general\license.htm +general\performance.htm +general\7z.htm +cmdline\index.htm +cmdline\syntax.htm +cmdline\exit_codes.htm +cmdline\commands\add.htm +cmdline\commands\bench.htm +cmdline\commands\delete.htm +cmdline\commands\extract.htm +cmdline\commands\extract_full.htm +cmdline\commands\update.htm +cmdline\commands\hash.htm +cmdline\commands\index.htm +cmdline\commands\list.htm +cmdline\commands\rename.htm +cmdline\commands\test.htm +cmdline\switches\index.htm +cmdline\switches\yes.htm +cmdline\switches\include.htm +cmdline\switches\method.htm +cmdline\switches\ar_include.htm +cmdline\switches\ar_exclude.htm +cmdline\switches\ar_no.htm +cmdline\switches\bb.htm +cmdline\switches\bs.htm +cmdline\switches\charset.htm +cmdline\switches\email.htm +cmdline\switches\list_tech.htm +cmdline\switches\large_pages.htm +cmdline\switches\output_dir.htm +cmdline\switches\overwrite.htm +cmdline\switches\password.htm +cmdline\switches\recurse.htm +cmdline\switches\sa.htm +cmdline\switches\scc.htm +cmdline\switches\scrc.htm +cmdline\switches\sdel.htm +cmdline\switches\sfx.htm +cmdline\switches\shared.htm +cmdline\switches\sni.htm +cmdline\switches\sns.htm +cmdline\switches\spf.htm +cmdline\switches\spm.htm +cmdline\switches\ssc.htm +cmdline\switches\stdin.htm +cmdline\switches\stdout.htm +cmdline\switches\stl.htm +cmdline\switches\stop_switch.htm +cmdline\switches\stx.htm +cmdline\switches\type.htm +cmdline\switches\update.htm +cmdline\switches\working_dir.htm +cmdline\switches\exclude.htm +fm\options.htm +fm\benchmark.htm +fm\temp.htm +fm\index.htm +fm\menu.htm +fm\about.htm +fm\plugins\index.htm +fm\plugins\7-zip\extract.htm +fm\plugins\7-zip\index.htm +fm\plugins\7-zip\add.htm + +[INFOTYPES] + diff -Nru p7zip-rar-16.02/DOC/7zip.wxs p7zip-rar-16.02+really25.00+ds/DOC/7zip.wxs --- p7zip-rar-16.02/DOC/7zip.wxs 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/7zip.wxs 2025-07-05 13:00:00.000000000 +0000 @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + 1 + + + + + + + + + + + + + + + + Privileged + + + + + + + + + + + + + + + + + + + + + + + + + + + Privileged + + + + + + Privileged + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru p7zip-rar-16.02/DOC/License.txt p7zip-rar-16.02+really25.00+ds/DOC/License.txt --- p7zip-rar-16.02/DOC/License.txt 2016-06-11 08:33:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/License.txt 2025-07-05 13:56:54.000000000 +0000 @@ -1,53 +1,151 @@ - 7-Zip source code - ~~~~~~~~~~~~~~~~~ - License for use and distribution - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - 7-Zip Copyright (C) 1999-2016 Igor Pavlov. - - Licenses for files are: - - 1) CPP/7zip/Compress/Rar* files: GNU LGPL + unRAR restriction - 2) All other files: GNU LGPL - - The GNU LGPL + unRAR restriction means that you must follow both - GNU LGPL rules and unRAR restriction rules. - - - GNU LGPL information - -------------------- - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - USA - - - unRAR restriction - ----------------- - - The decompression engine for RAR archives was developed using source - code of unRAR program. - All copyrights to original unRAR code are owned by Alexander Roshal. - - The license for original unRAR code has the following restriction: - - The unRAR sources cannot be used to re-create the RAR compression algorithm, - which is proprietary. Distribution of modified unRAR sources in separate form - or as a part of other software is permitted, provided that it is clearly - stated in the documentation and source comments that the code may - not be used to develop a RAR (WinRAR) compatible archiver. - - - -- - Igor Pavlov + 7-Zip source code + ~~~~~~~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 7-Zip Copyright (C) 1999-2025 Igor Pavlov. + + The licenses for files are: + + - CPP/7zip/Compress/Rar* files: the "GNU LGPL" with "unRAR license restriction" + - CPP/7zip/Compress/LzfseDecoder.cpp: the "BSD 3-clause License" + - C/ZstdDec.c: the "BSD 3-clause License" + - C/Xxh64.c: the "BSD 2-clause License" + - Some files are "public domain" files, if "public domain" status is stated in source file. + - the "GNU LGPL" for all other files. If there is no license information in + some source file, that file is under the "GNU LGPL". + + The "GNU LGPL" with "unRAR license restriction" means that you must follow both + "GNU LGPL" rules and "unRAR license restriction" rules. + + + + +GNU LGPL information +-------------------- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, + you can get a copy of the GNU Lesser General Public License from + http://www.gnu.org/ + + + + +BSD 3-clause License in 7-Zip code +---------------------------------- + + The "BSD 3-clause License" is used for the following code in 7z.dll + 1) LZFSE data decompression. + CPP/7zip/Compress/LzfseDecoder.cpp. + That code was derived from the code in the "LZFSE compression library" developed by Apple Inc, + that also uses the "BSD 3-clause License". + 2) ZSTD data decompression. + C/ZstdDec.c + that code was developed using original zstd decoder code as reference code. + The original zstd decoder code was developed by Facebook Inc, + that also uses the "BSD 3-clause License". + + Copyright (c) 2015-2016, Apple Inc. All rights reserved. + Copyright (c) Facebook, Inc. All rights reserved. + Copyright (c) 2023-2025 Igor Pavlov. + +Text of the "BSD 3-clause License" +---------------------------------- + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + + + + +BSD 2-clause License in 7-Zip code +---------------------------------- + + The "BSD 2-clause License" is used for the XXH64 code in 7-Zip. + C/Xxh64.c + + XXH64 code in 7-Zip was derived from the original XXH64 code developed by Yann Collet. + + Copyright (c) 2012-2021 Yann Collet. + Copyright (c) 2023-2025 Igor Pavlov. + +Text of the "BSD 2-clause License" +---------------------------------- + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + + + + +unRAR license restriction +------------------------- + +The decompression engine for RAR archives was developed using source +code of unRAR program. +All copyrights to original unRAR code are owned by Alexander Roshal. + +The license for original unRAR code has the following restriction: + + The unRAR sources cannot be used to re-create the RAR compression algorithm, + which is proprietary. Distribution of modified unRAR sources in separate form + or as a part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + +-- diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/add.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/add.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/add.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/add.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ - - - - - a (Add) command - - - - - -

a (Add) command

- -

Adds files to archive.

- -

Examples

- -
-7z a archive1.zip subdir\
-
- -

adds all files and subfolders from folder subdir to archive - archive1.zip. - The filenames in archive will contain subdir\ prefix.

- -
-7z a archive2.zip .\subdir\*
-
- -

adds all files and subfolders from folder subdir to archive - archive2.zip. - The filenames in archive will not contain subdir\ prefix.

- - -
-cd /D c:\dir1\
-7z a c:\archive3.zip dir2\dir3\ 
-
- -The filenames in archive c:\archive3.zip -will contain dir2\dir3\ prefix, -but they will not contain c:\dir1\ prefix. - -
-7z a Files.7z *.txt -r
-
- -

adds all *.txt files from current folder and its subfolders to archive - Files.7z.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -i (Include)
- -m (Method)
- -p (Set Password)
- -r (Recurse)
- -sdel (Delete files after including to archive)
- -sfx (create SFX)
- -si (use StdIn)
- -sni (Store NT security information)
- -sns (Store NTFS alternate Streams)
- -so (use StdOut)
- -spf (Use fully qualified file paths)
- -ssw (Compress shared files)
- -stl (Set archive timestamp from the most recently modified file)
- -t (Type of archive)
- -u (Update)
- -v (Volumes)
- -w (Working Dir)
- -x (Exclude)
-

- -

See also

- -

- Commands: - d (Delete), - u (Update)
- Switches: - -u (Update) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/bench.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/bench.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/bench.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/bench.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ - - - - - b (Benchmark) command - - - - - -

b (Benchmark) command

- -

Measures speed of the CPU and checks RAM for errors.

- -

Syntax

- -
-b [number_of_iterations] [-mmt{N}] [-md{N}] [-mm={Method}]
-
- -

There are two tests:

-

    -
  1. Compressing with LZMA method -
  2. Decompressing with LZMA method -
- -

The benchmark shows a rating in MIPS (million instructions per second). -The rating value is calculated from the measured CPU speed and it -is normalized with results of Intel Core 2 CPU with multi-threading option -switched off. So if you have Intel Core 2 Duo, -rating values must be close to real CPU frequency.

- -

You can change the upper dictionary size to increase memory usage by -md{N} switch. -Also, you can change the number of threads by -mmt{N} switch.

- -

The Dict column shows dictionary size. For example, 21 means 2^21 = 2 MB.

- -

The Usage column shows the percentage of time the processor is working. -It's normalized for a one-thread load. For example, 180% CPU Usage for 2 threads -can mean that average CPU usage is about 90% for each thread.

- -

The R / U column shows the rating normalized for 100% of CPU usage. -That column shows the performance of one average CPU thread.

- -

Avr shows averages for different dictionary sizes.

-

Tot shows averages of the compression and decompression ratings.

- -

Compression speed and rating strongly depend on memory (RAM) latency. - -

Decompression speed and rating strongly depend on the integer performance of the CPU. -For example, the Intel Pentium 4 has big branch -misprediction penalty (which is an effect of its long pipeline) and pretty slow -multiply and shift operations. So, the Pentium 4 has pretty low decompressing ratings.

- -

You can run a CRC calculation benchmark by specifying -mm=crc. -That test shows the speed of CRC calculation in MB/s. The first column shows the size of the block. -The next column shows the speed of CRC calculation for one thread. The other columns are results -for multi-threaded CRC calculation.

- -

With -mm=* switch you can run a complex benchmark. It tests hash calculation methods, -compression and encryption codecs of 7-Zip. -Note that the tests of LZMA have big weight in "total" results. -And the results are normilized with AMD K8 cpu in complex benchmark.

- -

Examples

- -
-7z b
-
-runs benchmarking. - -
-7z b -mmt1 -md26
-
-runs benchmarking with one thread and 64 MB dictionary. - -
-7z b 30
-
-

runs benchmarking with default settings for 30 iterations.

- -
-7z b -mm=*
-
-

runs complex 7-Zip benchmark.

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/delete.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/delete.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/delete.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/delete.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ - - - - - d (Delete) command - - - - - -

d (Delete) command

- -

Deletes files from archive.

- -

Example

- -
-7z d archive.zip *.bak -r
-
- -

deletes *.bak files from archive - archive.zip.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -i (Include)
- -m (Method)
- -p (Set Password)
- -r (Recurse)
- -sns (Store NTFS alternate Streams)
- -u (Update)
- -w (Working Dir)
- -x (Exclude) -

- -

See also

- -

- Commands: - a (Add), - u (Update) -

- -

- Switches: - -spf (Use fully qualified file paths)
- -stl (Set archive timestamp from the most recently modified file)
- -u (Update) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/extract.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/extract.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ - - - - - e (Extract) command - - - - - -

e (Extract) command

- -

Extracts files from an archive to the current -directory or to the output directory. The output directory can be specified by --o (Set Output Directory) switch.

- -

This command copies all extracted files to one directory. -If you want extract files with full paths, you must use -x (Extract with full paths) command. - -

7-Zip will prompt the user before overwriting existing files unless -the user specifies the -y (Assume Yes on all queries) -switch. If the user gives a no answer, 7-Zip will prompt for the file to be -extracted to a new filename. Then a no answer skips that file; or, yes -prompts for new filename.

- -

7-Zip accepts the following responses:

- - - - - - - - - -
Answer Abbr. Action
Yes y  
No n  
Always a Assume YES for ALL subsequent queries of the same class
Skip s Assume NO for ALL subsequent queries of the same class
Quit q Quit the program
- -

Abbreviated responses are allowed.

- -

Examples

- -
-7z e archive.zip
-
- -

extracts all files from archive - archive.zip to the current directory.

- -
-7z e archive.zip -oc:\soft *.cpp -r
-
- -

extracts all *.cpp files from archive - archive.zip to c:\soft folder.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -ai (Include archives)
- -an (Disable parsing of archive_name)
- -ao (Overwrite mode)
- -ax (Exclude archives)
- -i (Include)
- -m (Method)
- -o (Set Output Directory)
- -p (Set Password)
- -r (Recurse)
- -si (use StdIn)
- -sni (Store NT security information)
- -sns (Store NTFS alternate Streams)
- -so (use StdOut)
- -spf (Use fully qualified file paths)
- -t (Type of archive)
- -x (Exclude)
- -y (Assume Yes on all queries) -

- -

See also

- -

- Commands: - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/extract_full.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract_full.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/extract_full.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/extract_full.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ - - - - - x (Extract with full paths) command - - - - - -

x (Extract with full paths) command

- -

Extracts files from an archive with their full -paths in the current directory, or in an output directory if specified.

- -

See the e (Extract) command description for more details.

- -

Examples

- -
-7z x archive.zip
-
- -

extracts all files from the archive - archive.zip to the current directory.

- -
-7z x archive.zip -oc:\soft *.cpp -r
-
- -

extracts all *.cpp files from the archive - archive.zip to c:\soft folder.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -ai (Include archives)
- -an (Disable parsing of archive_name)
- -ao (Overwrite mode)
- -ax (Exclude archives)
- -i (Include)
- -m (Method)
- -o (Set Output Directory)
- -p (Set Password)
- -r (Recurse)
- -si (use StdIn)
- -sni (Store NT security information)
- -sns (Store NTFS alternate Streams)
- -so (use StdOut)
- -spf (Use fully qualified file paths)
- -t (Type of archive)
- -x (Exclude)
- -y (Assume Yes on all queries) -

- -

See also

- -

- Commands: - e (Extract) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/hash.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/hash.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/hash.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/hash.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ - - - - - h (Hash) command - - - - - -

h (Hash) command

- -

Calculate hash values for files.

- -

Syntax

- -
-h [-scrc{Method}] [files]
-
- -

Supported methods: CRC32, CRC64, SHA1, SHA256, BLAKE2sp. Default method is CRC32.

- -

Examples

- -
-7z h a.txt
-
- -

calculates CRC32 for a.txt.

- -
-7z h -scrcsha256 a.iso
-
- -

calculates SHA256 for a.iso.

- -
-7z h *
-
- -

calculates CRC32 for all files in current folder and all subfolders.

- -

Notes

- -

7-Zip shows hash values for each file, the sum of hash values and -the sum that includes all hash values of data and all hash values for filenames.

- -

7-Zip represents hash values for CRC32 and CRC64 as integer numbers in hex.

-

7-Zip represents hash values For SHA1, SHA256 and BLAKE2sp as sequence of bytes in hex.

- -

Switches that can be used with this command

- -

- -i (Include)
- -m (Method)
- -r (Recurse)
- -scrc (Set hash method)
- -si (use StdIn)
- -sns (Store NTFS alternate Streams)
- -ssw (Compress shared files)
- -x (Exclude) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/index.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - - - - - Command Line Commands - - - - - -

Command Line Commands

- -

The command is the first non-switch argument on the command line.

-

Command names are not case sensitive.

-

See also Command Line Syntax for more details about using the command line.

- -

Commands quick reference

- - - - - - - - - - - - - - -
CommandDescription
a Add
b Benchmark
d Delete
e Extract
h Hash
i Show information about supported formats
l List
rn Rename
t Test
u Update
x eXtract with full paths
- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/list.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/list.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/list.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/list.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ - - - - - l (List contents of archive) command - - - - - -

l (List contents of archive) command

- - - - - -

Lists contents of archive.

- - - - -

Examples

- -
-7z l archive.zip
-
- -

lists all files from archive archive.zip.

- - - - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -ai (Include archives)
- -an (Disable parsing of archive_name)
- -ax (Exclude archives)
- -i (Include)
- -slt (Show technical information)
- -sns (Store NTFS alternate Streams)
- -p (Set Password)
- -r (Recurse)
- -t (Type of archive)
- -x (Exclude) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/rename.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/rename.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/rename.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/rename.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ - - - - - rn (Rename) command - - - - - -

rn (Rename) command

- -

Renames files in archive.

- -

Syntax

- -
-rn <archive_name> <src_file_1> <dest_file_1> [ <src_file_2> <dest_file_2> ... ]
-
- -

Example

- -
-7z rn a.7z old.txt new.txt 2.txt folder\2new.txt 
-
- -

renames old.txt to new.txt -and 2.txt to folder\2new.txt -.

- - -

Notes

- -

Switches that can be used with this command

- -

- -i (Include)
- -m (Method)
- -p (Set Password)
- -r (Recurse)
- -stl (Set archive timestamp from the most recently modified file)
- -u (Update)
- -w (Working Dir)
- -x (Exclude) -

- -

-

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/style.css --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/test.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/test.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/test.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/test.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ - - - - - t (Test integrity of archive) command - - - - - -

t (Test integrity of archive) command

- -

Tests archive files.

- -

Example

- -
-7z t archive.zip *.doc -r
-
- -

tests *.doc files in archive - archive.zip.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -ai (Include archives)
- -an (Disable parsing of archive_name)
- -ax (Exclude archives)
- -i (Include)
- -p (Set Password)
- -r (Recurse)
- -sns (Store NTFS alternate Streams)
- -x (Exclude) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/update.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/update.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/commands/update.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/commands/update.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ - - - - - u (Update) command - - - - - -

u (Update) command

- -

Update older files in the archive and add files that are not already in the archive.

- -

Note: the updating of solid .7z archives can be slow, since it -can require some recompression.

- -

Example

- -
-7z u archive.zip *.doc
-
- -

updates *.doc files to archive - archive.zip.

- - -

Notes

- -

7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process -all files, you must use a * wildcard.

- - -

Switches that can be used with this command

- -

- -i (Include)
- -m (Method)
- -p (Set Password)
- -r (Recurse)
- -sfx (create SFX)
- -si (use StdIn)
- -so (use StdOut)
- -sni (Store NT security information)
- -sns (Store NTFS alternate Streams)
- -ssw (Compress shared files)
- -spf (Use fully qualified file paths)
- -stl (Set archive timestamp from the most recently modified file)
- -t (Type of archive)
- -u (Update)
- -w (Working Dir)
- -x (Exclude) -

- -

See also

- -

- Commands: - a (Add), - d (Delete), -

- -

- Switches: - -u (Update) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/exit_codes.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/exit_codes.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/exit_codes.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/exit_codes.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - - - - - Exit Codes from 7-Zip - - - - - -

Exit Codes from 7-Zip

- -

7-Zip returns the following exit codes:

- - - - - - - - - -
CodeMeaning
0No error
1Warning (Non fatal error(s)). For example, one or more files were - locked by some other application, so they were not compressed.
2Fatal error
7Command line error
8Not enough memory for operation
255User stopped the process
- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/index.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - - - - - Command Line Version User's Guide - - - - - -

Command Line Version User's Guide

- - -

7z.exe is the command line version of 7-Zip. 7z.exe uses 7z.dll -from the 7-Zip package. 7z.dll is used by the 7-Zip File Manager also. - -

7za.exe (a = alone) is a standalone version of 7-Zip. -7za.exe supports only 7z, lzma, cab, zip, gzip, bzip2, Z and tar formats. -7za.exe doesn't use external modules. - -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/style.css --- p7zip-rar-16.02/DOC/MANUAL/cmdline/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_exclude.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_exclude.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_exclude.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_exclude.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - -ax (Exclude archive filenames) switch - - - - - -

-ax (Exclude archive filenames) switch

- -

Specifies archives to be excluded from the operation.

-

Multiple exclude archive switches are supported.

- -

Syntax

- -
--ax[<recurse_type>]<file_ref>
-
-<recurse_type> ::= r[- | 0]
-<file_ref> ::= @{listfile} | !{wildcard}
-
- -

See -xi (Include archive filenames) switch description -for information about option parameters.

- - -

Examples

- -
-7z t -an -ai!*.7z -ax!a*.7z
-
- -

tests all *.7z archives, - except a*.7z archives.

- -

Commands that can be used with this switch

- -

- e (Extract), - l (List), - t (Test), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -ai (Include archives) - -an (Disable parsing of archive_name) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_include.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_include.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_include.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_include.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ - - - - - -ai (Include archive filenames) switch - - - - - -

-ai (Include archive filenames) switch

- -

Specifies additional include archive filenames and wildcards.

-

Multiple include switches are supported.

- -

Syntax

- -
--ai[<recurse_type>]<file_ref>
-
-<recurse_type> ::= r[- | 0]
-<file_ref> ::= @{listfile} | !{wildcard}
-
- -

Parameters

- -
-
<recurse_type>
-

Specifies how wildcards and file names in this switch must - be used. If this option is not given, recursion will be not used. - For more details see specification of the - -r (Recurse) switch.

-
-<recurse_type> ::= r[- | 0]
-
- -
-
<file_ref>
-
-

Specifies filenames and wildcards or list file that specify processed files.

-
-<file_ref> ::= @{listfile} | !{wildcard}
-
- - - - -
Option Description
{listfile} Specifies name of list file. See - List file description.
{wildcard} Specifies wildcard or filename.
-
-
- -

Examples

- -
-7z t -an -air!*.7z
-
- -

tests *.7z archives in current directory and all it's -subdirectories.

- -

Commands that can be used with this switch

- -

- e (Extract), - l (List), - t (Test), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -ax (Exclude archives) - -an (Disable parsing of archive_name) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_no.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_no.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ar_no.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ar_no.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ - - - - - -an (Disable parsing of archive_name) switch - - - - - -

-an (Disable parsing of archive_name) switch

- -

Disables parsing of the archive_name field on the command line. -This switch must be used with the --ai (Include archives) switch. -If you use a file list for your archives, you specify it with the -ai switch, -so you need to disable parsing of archive_name field from command line. - -

Syntax

- -
--an
-
- -

Examples

- -
-7z t -an -ai!*.7z -ax!a*.7z
-
- -

tests all *.7z archives, - except a*.7z archives.

- -

Commands that can be used with this switch

- -

- e (Extract), - l (List), - t (Test), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -ai (Include archives) - -ax (Exclude archives) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/bb.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bb.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/bb.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bb.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ - - - - - -bb (Set output log level) switch - - - - - -

-bb (Set output log level) switch

- -

The switch sets output log level for Delete/Add/Update/Extract operations.

- -

Syntax

- -
--bb[0-3]
-
- - - - - - - -
Log level Description
-bb0 disable log (default).
-bb1 or -bb show names of processed files in log.
-bb2 show names of additional files that were processed internally in - solid archives: - skipped files for "Extract" operation, - repacked files for "Add" / "Update" operations.
-bb3 show information about additional operations - (Analyze, Replicate) for "Add" / "Update" operations.
- -

Examples

- -
-7z a a.7z *.txt -bb
-
- -

adds *.txt files to a.7z archive -and shows all files that were processed.

- -
-7z u a.7z *.txt -bb3
-
- -

updates *.txt files in a.7z archive -and shows information about additional operations.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - u (Update), - x (Extract with full paths) -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/bs.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bs.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/bs.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/bs.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ - - - - - -spf (Use fully qualified file paths) switch - - - - - -

-bs (Set output stream for output/error/progress line) switch

- -

Syntax

- -
--bs{o|e|p}{0|1|2}
-
- - - - - - -
{id} Stream Type
o standard output messages
e error messages
p progress information
- - - - - - -
{N} Stream Destination
0 disable stream
1 redirect to stdout stream
2 redirect to stderr stream
- -

Default values: o1, e2, p1.

- - -

Examples

- -
-7z t a.7z -bse1 > messages.txt
-
- -

tests a.7z archive and sends error -messages to stdout that is redirected to messages.txt

- - -
-7z a -si -so -bsp2 -txz -an < file.tar > file.tar.xz
-
- -

compresses file.tar (from stdin) to file.tar.xz -(stdout stream) and shows progress information in stderr stream that can be seen at console window.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - h (Hash), - l (List), - e (Extract), - u (Update), - x (Extract with full paths) -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/charset.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/charset.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/charset.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/charset.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ - - - - - -scs (Set charset for list files) switch - - - - - -

-scs (Set charset for list files) switch

- -

Sets charset for list files.

- -

Syntax

- -
--scs{UTF-8 | UTF-16LE | UTF-16BE | WIN | DOS | {id} }
-
- -

Default charset is UTF-8.

- - - - - - - - - -
Value Description
UTF-8 Unicode UTF-8 character set.
UTF-16LE Unicode UTF-16 little-endian character set.
UTF-16BE Unicode UTF-16 big-endian character set.
WIN Default character set of Windows.
DOS Default DOS (OEM) character set of Windows.
{id} The code page number (as specified in Microsoft Windows).
- -

Notes: The list file in Unicode charset can start with the BOM (byte order mark) character (U+FEFF). - In that case 7-Zip checks that encoding of BOM corresponds to encoding - specified with this switch (for UTF-16LE and UTF-16BE).

- -

Examples

- -
-7z a archive.7z @listfile.txt -scsWIN
-
- -

compresses files from listfile.txt list, that contains -list of files in default character set of Windows.

- -
-7z a archive.7z @listfile.txt -scs1251
-
- -

compresses files from listfile.txt list, that contains -list of files in 1251 (Cyrillic Windows) codepage.

- -

Commands that can be used with this switch

- -

- a (Add), - u (Update) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/exclude.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/exclude.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/exclude.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/exclude.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ - - - - - -x (Exclude filenames) switch - - - - - -

-x (Exclude filenames) switch

- -

Specifies which filenames or wildcarded names must be excluded from the operation.

-

Multiple exclude switches are supported.

- -

Syntax

- -
--x[<recurse_type>]<file_ref>
-
-<recurse_type> ::= r[- | 0]
-<file_ref> ::= @{listfile} | !{wildcard}
-
- -

See -i (Include) switch description for information about - option parameters.

- - -

Examples

- -
-7z a -tzip archive.zip *.txt -x!temp.*
-
- -

adds to the archive.zip all - *.txt files, - except temp.* files.

- - -
-7z a archive.7z Folder1\ -xr!*.png
-
- -

adds to the archive.7z all - files from Folder1 and its subfolders, - except *.png files.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - h (Hash), - e (Extract), - l (List), - t (Test), - rn (Rename), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -r (Recurse), - -i (Include) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/include.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/include.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/include.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/include.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ - - - - - -i (Include filenames) switch - - - - - -

-i (Include filenames) switch

- -

Specifies additional include filenames and wildcards.

-

Multiple include switches are supported.

- -

Syntax

- -
--i[<recurse_type>]<file_ref>
-
-<recurse_type> ::= r[- | 0]
-<file_ref> ::= @{listfile} | !{wildcard}
-
- -

Parameters

- -
-
<recurse_type>
-

Specifies how wildcards and file names in this switch must - be used. If this option is not given, then the global value, assigned - by the -r (Recurse) switch will be used. For - more details see specification of the - -r (Recurse) switch.

-
-<recurse_type> ::= r[- | 0]
-
- -
-
<file_ref>
-
-

Specifies filenames and wildcards, or a list file, for files to be processed.

-
-<file_ref> ::= @{listfile} | !{wildcard}
-
- - - - -
Option Description
{listfile} Specifies name of list file. See - List file description.
{wildcard} Specifies wildcard or filename.
-
-
- -

Examples

- -
-7z a -tzip src.zip *.txt -ir!DIR1\*.cpp
-
- -

adds to src.zip archive all - *.txt files from current directory - and all *.cpp - files from directory DIR1 - and from all it's subdirectories.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - h (Hash), - l (List), - rn (Rename), - t (Test), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -r (Recurse), - -x (Exclude) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/index.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/index.htm 2016-05-19 10:11:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ - - - - - Command Line Switches - - - - - -

Command Line Switches

- -

Syntax

- -
-<switch>::= <switch_symbol><switch_characters>[<option>]
-<switch_symbol> ::= '/' | '-' 
-
-
-

On the command line, a switch consists of a switch specifier, -either a dash (-) or a forward slash (/), followed by the name of -the switch. Switch names cannot be abbreviated.

- -

Some switches take an argument after the switch name. -No spaces or tabs are allowed within a switch specification. -Switch names are not case sensitive, but arguments can be case sensitive. -

- -

Switch can be used in any place in command line. - -

See also Command Line Syntax for more details - about using the command line.

- -

Switch quick reference

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SwitchDescription
-- Stop switches parsing
-ad Show dialog box in GUI version (7zg)
-ai Include archive filenames
-an Disable parsing of archive_name
-ao Overwrite mode
-ax Exclude archive filenames
-bb[0-3] Set output log level
-bd Disable progress indicator
-bs{o|e|p}{0|1|2} Set output stream for output/error/progress
-bt Show execution time statistics
-i Include filenames
-m Set Compression Method
-o Set Output directory
-p Set Password
-r Recurse subdirectories
-sa Set Archive name mode
-scc Set charset for for console input/output
-scrc Set hash function
-scs Set charset for list files
-sdel Delete files after including to archive
-sfx Create SFX archive
-si Read data from StdIn
-slp Set Large Pages mode
-slt Show technical information
-sni Store NT security information
-sns Store NTFS alternate Streams
-snc Extract file as alternate stream, if there is ':' character in name
-snr Replace ':' character to '_' character in paths of alternate streams
-snh Store hard links as links (WIM and TAR formats only)
-snl Store symbolic links as links (WIM and TAR formats only)
-so Write data to StdOut
-spd Disable wildcard matching for file names
-spe Eliminate duplication of root folder for extract archive command
-spf Use fully qualified file paths
-ssc Set Sensitive Case mode
-ssw Compress files open for writing
-stl Set archive timestamp from the most recently modified file
-stm{HexMask} Set CPU thread affinity mask (hexadecimal number).
-stx{Type} Exclude archive type
-t Type of archive
-u Update options
-v Create Volumes
-w Set Working directory
-x Exclude filenames
-y Assume Yes on all queries
- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/large_pages.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/large_pages.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/large_pages.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/large_pages.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ - - - - - -slp (Set Large Pages mode) switch - - - - - -

-slp (Set Large Pages mode) switch

- -

Sets Large Pages mode.

- -

Syntax

- -
--slp[-]
-
- - - - - - -
Switch Description
-slp Enables Large Pages mode.
-slp- Disables Large Pages mode. This option is default for all commands.
- -

Large Pages mode increases the speed of compression. -However, there is a pause at the start of compression while 7-Zip allocates the large pages in memory. -If 7-Zip can't allocate large pages, it allocates usual small pages. -Also, the Windows Task Manager doesn't show the real memory usage of the program, if 7-Zip uses large pages. -This feature works only on Windows 2003 / XP x64. -Also, it requires administrator's rights for your system. -The recommended size of RAM for this feature is 3 GB or more. -To install this feature, you must run the 7-Zip File Manager at least once, -close it, and then reboot the system.

- -

Notes: if you use -slp mode, your Windows system can hang for several - seconds when 7-zip allocates memory blocks. - -When Windows tries to allocate large pages from RAM for 7-Zip, Windows can hang other tasks for that time. -It can look like full system hang, but then it resumes, and if allocation is successful, 7-Zip works faster. -Don't use -slp mode, if you don't want other tasks be hanged for several seconds. -Also it's senseless to use -slp mode to compress small data sets (less than 100 MB). -But if you compress big data sets (300 MB or more) with LZMA method with large dictionary, -you can get 5%-10% speed improvement with -slp mode.

- - - -

Example

- -
-7z a archive.7z -slp a.iso
-
- -

compresses a.iso file with Large Pages mode switched on.

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/list_tech.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/list_tech.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/list_tech.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/list_tech.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - - - - - -slt (Show technical information) switch - - - - - -

-slt (Show technical information) switch

- -

Sets technical mode for l (List) command.

- -

Syntax

- -
--slt
-
- -

Example

- -
-7z l -slt archive.7z
-
- -

shows detailed technical information for the files in archive.7z.

- -

Commands that can be used with this switch

- -

- l (List) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/method.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/method.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/method.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/method.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,738 +0,0 @@ - - - - - -m (Set compression Method) switch - - - - - -

-m (Set compression Method) switch

- -

Specifies the compression method.

- -

Syntax

- -
--m<method_parameters>
-
-
- -

The format for this switch depends on the archive type.

- - - -

-m switch also can specify hash method for -h (Hash) command,

- -

Notes: "Default value" in switches descriptions means the value that -will be used if switch is not specified.

- -

It's allowed to use reduced forms for boolean switches: sw+ or sw instead -sw=on, and sw- instead of sw=off.

- -

Zip

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterDefaultDescription
x=[0 | 1 | 3 | 5 | 7 | 9 ]5Sets level of compression.
m={MethodID}DeflateSets a method: Copy, Deflate, Deflate64, BZip2, LZMA, PPMd.
fb={NumFastBytes}32Sets number of Fast Bytes for Deflate encoder.
pass={NumPasses}1Sets number of Passes for Deflate encoder.
d={Size}[b|k|m]900000Sets Dictionary size for BZip2
mem={Size}[b|k|m]24 Sets size of used memory for PPMd.
o={Size}8 Sets model order for PPMd.
mt=[off | on | {N}]onSets multithreading mode.
em={EncryptionMethodID}ZipCryptoSets a encryption method: ZipCrypto, AES128, AES192, AES256
tc=[off | on]on Stores NTFS timestamps for files: Modification time, Creation time, Last access time.
cl=[off | on]off 7-Zip always uses local code page for file names.
cu=[off | on]off 7-Zip uses UTF-8 for file names that contain non-ASCII symbols.
cp={CodePage}off Sets code page
- -

By default (if cl and cu switches are not specified), 7-Zip uses UTF-8 encoding -only for file names that contain symbols unsupported by local code page.

- -
-
x=[0 | 1 | 3 | 5 | 7 | 9 ]
-
-

Sets level of compression. x=0 means Copy mode (no compression).

-

Deflate / Deflate64 settings:

- - - - - - - -
Level NumFastBytes NumPasses Description
1 32 1 Fastest
3 Fast
5 Normal
7 64 3 Maximum
9 128 10 Ultra
- -

x=1 and x=3 with Deflate method set fast mode for compression.

- -

BZip2 settings:

- - - - - - - -
Level Dictionary NumPasses Description
1 100000 1 Fastest
3 500000 Fast
5 900000 Normal
7 2 Maximum
9 7 Ultra
-
- -
fb={NumFastBytes}
-
-

Sets the number of fast bytes for the Deflate/Deflate64 encoder. - It can be in the range from 3 to 258 (257 for Deflate64). - Usually, a big number gives a little bit better - compression ratio and a slower compression process. - A large fast bytes parameter can significantly increase the compression ratio - for files which contain long identical sequences of bytes.

-
-
pass={NumPasses}
-
-

Sets number of passes for Deflate encoder. It can be in the range from 1 to 15 for Deflate and - from 1 to 10 for BZip2. Usually, a big number gives a little bit better - compression ratio and a slower compression process. -

-
-
d={Size}[b|k|m]
-
-

Sets the Dictionary size for BZip2. You must specify the size in bytes, kilobytes, or megabytes. - The maximum value for the Dictionary size is 900000b. If you do not specify any symbol - from set [b|k|m], dictionary size will be calculated as DictionarySize = 2^Size bytes.

-
- -
mem={Size}[b|k|m]
-
-

Sets the size of memory used for PPMd. You must specify the size in bytes, kilobytes, or megabytes. - The maximum value is 256 MB = 2^28 bytes. The default value - is 24 (16MB). If you do not specify any symbol from the set [b|k|m], the - memory size will be calculated as (2^Size) bytes. PPMd uses the same - amount of memory for compression and decompression.

-
- -
o={Size}
-
-

Sets the model order for PPMd. The size must be in the range [2,16]. The default value is 8.

-
- -
mt=[off | on | {N}]
-
-

Sets multithread mode. If you have a multiprocessor or multicore system, - you can get a speed increase with - this switch. This option affects only compression (with any method) and - decompression of BZip2 streams. - Each thread in the multithread mode uses 32 MB of RAM for buffering. - If you specify {N}, 7-Zip tries to use N threads.

-
-
- -

GZip

-GZip uses the same parameters as Zip, but GZip compresses only with Deflate method. -So GZip supports only the following parameters: x, fb, pass. - -

BZip2

- - - - - - - - - - - - - - - - - - - - - -
ParameterDefaultDescription
x=[1 | 3 | 5 | 7 | 9 ]5Sets level of compression.
pass={NumPasses}1Sets number of Passes for Bzip2 encoder.
d={Size}[b|k|m]900000Sets Dictionary size for BZip2
mt=[off | on | {N}]onSets multithreading mode.
- -
-
x=[1 | 3 | 5 | 7 | 9 ]
-
-

Sets level of compression

- - - - - - - -
Level Dictionary NumPasses Description
1 100000 1 Fastest
3 500000 Fast
5 900000 Normal
7 2 Maximum
9 7 Ultra
-
- -
d={Size}[b|k|m]
-
-

Sets the Dictionary size for BZip2. You must specify the size in bytes, kilobytes, or megabytes. - The maximum value for the Dictionary size is 900000b. If you do not specify any symbol - from set [b|k|m], dictionary size will be calculated as DictionarySize = 2^Size bytes.

-
- -
pass={NumPasses}
-
-

Sets the number of passes. It can be in the range from 1 to 10. - The default value is 1 for normal mode, 2 for maximum mode and 7 for ultra mode. - A bigger number can give a little bit better compression ratio and a slower compression process. -

-
-
mt=[off | on | {N}]
-
-

Sets multithread mode. If you have a multiprocessor or multicore system, - you can get a speed increase with - this switch. If you specify {N}, for example mt=4, 7-Zip tries to use 4 threads.

-
-
- -

7z

- - - - - - - - - - - - - - - - - - - - -
Parameter Default Description
x=[0 | 1 | 3 | 5 | 7 | 9 ] 5 Sets level of compression.
yx=[0 | 1 | 3 | 5 | 7 | 9 ] 5 Sets level of file analysis.
s=[off | on | [e] [{N}f] [{N}b | {N}k | {N}m | {N}g] on Sets solid mode.
qs=[off | on] off Sort files by type in solid archives.
f=[off | on | FilterID] on Enables or disables filters. FilterID: Delta:{N}, BCJ, BCJ2, ARM, ARMT, IA64, PPC, SPARC.
hc=[off | on] on Enables or disables archive header compressing.
he=[off | on] off Enables or disables archive header encryption.
b{C1}[s{S1}]:{C2}[s{S2}] Sets binding between coders.
{N}={MethodID}[:param1][:param2][..] LZMA2 Sets a method: LZMA, LZMA2, PPMd, BZip2, Deflate, Delta, BCJ, BCJ2, Copy.
mt=[off | on | {N}] on Sets multithreading mode.
mtf=[off | on] on Set multithreading mode for filters.
tm=[off | on] on Stores last Modified timestamps for files.
tc=[off | on] off Stores Creation timestamps for files.
ta=[off | on] off Stores last Access timestamps for files.
- -
-
x=[0 | 1 | 3 | 5 | 7 | 9 ]
-
-

Sets level of compression

- - - - - - - - -
Level Method Dictionary FastBytes MatchFinder Filter Description
0 Copy No compression.
1 LZMA2 64 KB 32 HC4 BCJ Fastest compressing
3 LZMA2 1 MB 32 HC4 BCJ Fast compressing
5 LZMA2 16 MB 32 BT4 BCJ Normal compressing
7 LZMA2 32 MB 64 BT4 BCJ Maximum compressing
9 LZMA2 64 MB 64 BT4 BCJ2Ultra compressing
-

Note: "x" works as "x=9".

-
- -
yx=[0 | 1 | 3 | 5 | 7 | 9 ]
-
-

Sets level of file analysis

- - - - - - -
Level Description
0 No analysis.
1 or more WAV file analysis (for Delta filter).
7 or more EXE file analysis (for Executable filters).
9 or more analysis of all files (Delta and executable filters).
-

Default level is 5: "yx=5".

-

"yx" works as "yx=9".

- -

If the level of analysis is smaller than 9, 7-Zip analyses only files - that have some file name extensions: EXE, DLL, WAV. - 7-Zip reads small data block at the beginning of file and tries to parse - the header. It supports only some formats: WAV, PE, ELF, Mach-O. - Then it can select filter that can increase compression ratio for that file.

- -

By default 7-Zip uses x86 filters (BCJ or BCJ2) for PE files (EXE, DLL). - 7-Zip doesn't use analysis in default (yx=5) mode. - If (yx=7), then analysis is used for PE files, and it can increase compression - ratio for files for non-x86 platforms like ARM.

- -
- -
s=[off | on | [e] [{N}f] [{N}b | {N}k | {N}m | {N}g)]
-
-

Enables or disables solid mode. The default mode is s=on. - In solid mode, files are grouped together. Usually, compressing in - solid mode improves the compression ratio.

- - - - - -
e Use a separate solid block for each new file extension
{N}f Set the limit for number of files in one solid block
{N}b | {N}k | {N}m | {N}g Set a limit for the total size of a solid block in bytes
- -

These are the default limits for the solid block size:

- - - - - - - - - -
Compression Level Solid block size
Store 0 B
Fastest 16 MB
Fast 128 MB
Normal 2 GB
Maximum 4 GB
Ultra 4 GB
- - -

Limitation of the solid block size usually decreases compression ratio but gives the following advantages:

-
    -
  • Decreases losses in case of future archive damage. -
  • Decreases extraction time of a group of files (or just one - file), so long as the group doesn't contain the entire archive.
  • -
-

The updating of solid .7z archives can be slow, since it - can require some recompression.

- -

Example:

-
-        s=100f10m
-      
-

set solid mode with 100 files & 10 MB limits per one solid block.

- -
f=[off | on | FilterID]
-
-

Enables or disables compression filters. - The default mode is f=on, when 7-zip uses filter only for executable files: - dll, exe, ocx, sfx, sys. It uses BCJ2 filter in Ultra mode and BCJ filter in other modes. - If f=FilterID if specified, 7-zip uses specified filter for all files. - FilterID can be: Delta:{N}, BCJ, BCJ2, ARM, ARMT, IA64, PPC, SPARC. -

-
hc=[off | on]
-
-

Enables or disables archive header compressing. The default mode is hc=on. - If archive header compressing is enabled, the archive header will - be compressed with LZMA method. -

-
he=[off | on]
-
-

Enables or disables archive header encryption. The default mode is he=off. -

- -
b{C1}[s{S1}]:{C2}[s{S2}]
-
-

Binds output stream S1 in coder C1 with input stream S2 in coder C2. - If stream number is not specified, stream with number 0 will be used. -

-

Usally coder has one input stream and - one output stream. In 7z some coders can have multiple input and output streams.

- -

For example, BCJ2 encoder has one - input stream and four output streams.

-
- -
mt=[off | on | {N}]
-
-

Sets multithread mode. If you have a multiprocessor or multicore system, - you can get a increase with this switch. - 7-Zip supports multithread mode only for LZMA / LZMA2 compression and - BZip2 compression / decompression. If you specify {N}, for example mt=4, - 7-Zip tries to use 4 threads. LZMA compression uses only 2 threads. -

-
- -
{N}={MethodID}[:param1][:param2] ... [:paramN]
-
-

Sets compression method. You can use any number of methods. - The default method is LZMA2.

- -

{N} sets the index number of method in methods chain. - Numbers must begin from 0. Methods that have smaller numbers will be used - before others.

- - -

Parameters must be in one of the following forms:

-
    -
  • {ParamName}={ParamValue}. -
  • {ParamName}{ParamValue}, if {ParamValue} - is number and {ParamName} doesn't contain numbers. -
- -

Supported methods:

- - - - - - - - -
MethodID Description
LZMA LZ-based algorithm
LZMA2 LZMA-based algorithm
PPMd Dmitry Shkarin's PPMdH with small changes
BZip2 BWT algorithm
Deflate LZ+Huffman
Copy No compression
- -

Supported filters:

- - - - - - - - - - -
MethodID Description
Delta Delta filter
BCJ converter for x86 executables
BCJ2 converter for x86 executables (version 2)
ARM converter for ARM (little endian) executables
ARMT converter for ARM Thumb (little endian) executables
IA64 converter for IA-64 executables
PPC converter for PowerPC (big endian) executables
SPARC converter for SPARC executables
-

Filters increase the compression ratio for some types of files. Filters - must be used with one of the compression method (for example, BCJ + LZMA).

-
- -

LZMA

-

LZMA is an algorithm based on Lempel-Ziv algorithm. - It provides very fast decompression (about 10-20 times faster than compression). - Memory requirements for compression and decompression also are different (see - d={Size}[b|k|m|g] switch for details).

- - - - - - - - - - - - - - - - - - - - -
Parameter Default Description
a=[0|1]1 Sets compressing mode
d={Size}[b|k|m|g]24 Sets Dictionary size
mf={MF_ID}bt4 Sets Match Finder
fb={N}32 Sets number of Fast Bytes
mc={N}32Sets Number of Cycles for Match Finder
lc={N}3 Sets number of Literal Context bits - [0, 8]
lp={N}0 Sets number of Literal Pos bits - [0, 4]
pb={N}2 Set number of Pos Bits - [0, 4]
- - -
-
a=[0|1]
-
-

Sets compression mode: 0 = fast, 1 = normal. - Default value is 1.

-
-
d={Size}[b|k|m|g]
-
-

Sets Dictionary size for LZMA. You must specify the size in bytes, kilobytes, or megabytes. - The maximum value for dictionary size is 1536 MB, but 32-bit version of 7-Zip allows - to specify up to 128 MB dictionary. - Default values for LZMA - are 24 (16 MB) in normal mode, 25 (32 MB) in maximum mode (-mx=7) - and 26 (64 MB) in ultra mode (-mx=9). - If you do not specify any symbol from the set [b|k|m|g], the - dictionary size will be calculated as DictionarySize = 2^Size bytes. - For decompressing a file compressed by LZMA method with dictionary size N, you need - about N bytes of memory (RAM) available. -

-
-
mf={MF_ID}
-
-

Sets Match Finder for LZMA. Default method is bt4. - Algorithms from hc* group don't provide a good compression ratio, - but they often work pretty fast in combination with fast mode (a=0). - Memory requirements depend on dictionary size (parameter "d" in table below). -

- - - - - - - - -
MF_ID Dictionary Memory Usage Description
bt2 9.5 * d + 4 MB Binary Tree 2 bytes hashing
bt3 11.5 * d 3 bytes hashing
bt4 64 KB ... 48 MB 11.5 * d 4 bytes hashing
64 MB ... 1024 MB 10.5 * d
hc4 64 KB ... 48 MB 7.5 * d Hash Chain
64 MB ... 1024 MB 6.5 * d
-

Note: Your operation system also needs some amount of physical memory for internal purposes. - So keep at least 32MB of physical memory unused.

-
- -
fb={N}
-
-

Sets number of fast bytes for LZMA. It can be in the range from 5 to 273. - The default value is 32 for normal mode and 64 for maximum and ultra modes. - Usually, a big number gives a little bit better - compression ratio and slower compression process. -

-
-
mc={N}
-
-

Sets number of cycles (passes) for match finder. It can be in range from 0 to 1000000000. - Default value is (16 + number_of_fast_bytes / 2) for BT* match finders and - (8 + number_of_fast_bytes / 4) for HC4 match finder. - If you specify mc=0, LZMA will use default value. - Usually, a big number gives a little bit better compression ratio and slower - compression process. For example, mf=HC4 and mc=10000 can provide almost the same - compression ratio as mf=BT4.

-
-
lc={N}
-
-

Sets the number of literal context bits (high bits of previous literal). - It can be in range from 0 to 8. - Default value is 3. Sometimes lc=4 gives gain for big files.

-
-
lp={N}
-
-

Sets the number of literal pos bits (low bits of current position for literals). - It can be in the range from 0 to 4. - The default value is 0. The lp switch is intended for periodical data when the - period is equal to 2^value (where lp=value). For example, for 32-bit (4 bytes) - periodical data you can use lp=2. Often it's better to set lc=0, - if you change lp switch.

-
-
pb={N}
-
-

Sets the number of pos bits (low bits of current position). - It can be in the range from 0 to 4. - The default value is 2. The pb switch is intended for periodical data when the - period is equal 2^value (where lp=value).

-
- -
- -

LZMA2

-

LZMA2 is modified version of LZMA. it provides the following advantages over LZMA:

-
    -
  • Better compression ratio for data than can't be compressed. LZMA2 can store such - blocks of data in uncompressed form. Also it decompresses such data faster. -
  • Better multithreading support. If you compress big file, LZMA2 can split - that file to chunks and compress these chunks in multiple threads. -
- - - - - - -
Parameter Default Description
c={Size}[b|k|m|g]dictSize * 4 Sets Chunk size
- -

If you don't specify ChunkSize, LZMA2 sets it to max(DictionarySize, min(256M, max(1M, DictionarySize * 4))).

- -

LZMA2 also supports all LZMA parameters, but lp+lc cannot be larger than 4.

- -

LZMA2 uses: 1 thread for each chunk in x1 and x3 modes; and - 2 threads for each chunk in x5, x7 and x9 modes. - If LZMA2 is set to use only such number of threads required for one chunk, - it doesn't split stream to chunks. So you can get different compression - ratio for different number of threads. You can get the best compression - ratio, when you use 1 or 2 threads.

- -

PPMd

-

PPMd is a PPM-based algorithm. This algorithm is mostly based - on Dmitry Shkarin's PPMdH source code. PPMd provides very good compression ratio for - plain text files. There is no difference between compression speed and - decompression speed. Memory requirements for compression and decompression - also are the same.

- - - - - - -
Parameter Default Description
mem={Size}[b|k|m|g]24 Sets size of used memory for PPMd.
o={Size}6 Sets model order for PPMd.
-
-
mem={Size}[b|k|m|g]
-
-

Sets the size of memory used for PPMd. You must specify the size in bytes, kilobytes, or megabytes. - The maximum value is 2GB = 2^31 bytes. The default value - is 24 (16MB). If you do not specify any symbol from the set [b|k|m|g], the - memory size will be calculated as (2^Size) bytes. PPMd uses the same - amount of memory for compression and decompression.

-
- -
o={Size}
-
-

Sets the model order for PPMd. The size must be in the range [2,32]. The default value is 6.

-
-
- -

BCJ2

-

BCJ2 is a Branch converter for 32-bit x86 executables (version 2). - It converts some branch instructions for increasing further compression.

-

A BCJ2 encoder has one input stream and four output streams:

-
    -
  • s0: main stream. It requires further compression.
  • -
  • s1: stream for converted CALL values. It requires further compression.
  • -
  • s2: stream for converted JUMP values. It requires further compression.
  • -
  • s3: service stream. It is already compressed.
  • -
-

If LZMA is used, the size of the dictionary for streams - s1 and s2 can be much smaller (512 KB is enough for most cases) - than the dictionary size for stream s0.

- -

Parameters:

-

-
d={Size}[b|k|m|g]
-
-

Sets section size for BCJ2 filter. Default section size is 64 MB. - If you do not specify any symbol from the set [b|k|m|g], the - section size will be calculated as SectionSize = 2^Size bytes. - This parameter doesn't affect memory consumption. - Compression ratio is better, if the section size is equal - or slightly larger than size of largest execution section in file. - Example: f=BCJ2:d9M, if largest executable section in files is smaller than 9 MB. -

-
-
- - -

Delta

-

It's possible to set delta offset in bytes. For example, to compress 16-bit stereo - WAV files, you can set "0=Delta:4". Default delta offset is 1.

-
- -

XZ

- -

XZ supports only LZMA2 codec now. The switches are similar to switches for 7z format.

- - - - - - - - - - - -
Parameter Default Description
x=[0 | 1 | 3 | 5 | 7 | 9 ] 5 Sets level of compression
f=FilterID Sets compression filter. FilterID: Delta:{N}, BCJ, ARM, ARMT, IA64, PPC, SPARC
{N}={MethodID}[:param1][:param2][..] LZMA2 Sets compression method: LZMA2:[param1]:[param2]:[...]
mt=[off | on | {N}] on Sets multithreading mode
- -

WIM

- - - - - - - - - - - - - - -
ParameterDefaultDescription
im={ImageNumber}Sets image number.
is=[off | on]offShow image number in paths.
- -

If image number is specified, 7-Zip works only with that image inside WIM archive. -Other images will be not changed. By default 7-Zip doesn't show image number, if there is only one -image in WIM archive, or if image number is specified. But if the switch "is" specified, -7-Zip shows image number.

- -

Examples

- -
-7z a archive.zip *.jpg -mx0
-
- -

adds *.jpg files to - archive.zip archive without compression.

- -
-7z a archive.7z *.exe *.dll -m0=BCJ -m1=LZMA:d=21
-
- -

adds *.exe and *.dll -files to solid archive archive.7z using LZMA method with -2 MB dictionary and BCJ filter.

- -
-7z a archive.7z a.tar -mf=BCJ2 -mx
-
- -

adds a.tar - files to archive archive.7z using BCJ2 filter.

- -
-7z a archive.7z *.wav -mf=Delta:4
-
- -

adds *.wav - files to archive archive.7z using Delta:4 filter.

- -
-7z a a.7z *.exe *.dll -m0=BCJ2 -m1=LZMA:d25 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3
-
- -

adds *.exe and *.dll - files to archive a.7z using BCJ2 filter, - LZMA with 32 MB dictionary for main output stream (s0), - and LZMA with 512 KB dictionary for s1 and s2 output streams of BCJ2.

- -
-7z a archive.7z *.txt -m0=PPMd
-
- -

adds *.txt files to archive -archive.7z using PPMd method.

- - -
-7z a a.tar.xz a.tar -mf=bcj -mx
-
- -

adds a.tar - files to archive a.tar.xz using BCJ filter.

- - -

Commands that can be used with this switch

- -

- a (Add), - h (Hash), - d (Delete), - rn (Rename), - u (Update) -

- -

See also

- -

- Switches: - -t (set Type of archive), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/output_dir.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/output_dir.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/output_dir.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/output_dir.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ - - - - - -o (set Output directory) switch - - - - - -

-o (set Output directory) switch

- -

Specifies a destination directory where files are to be extracted.

-

This switch can be used only with extraction commands.

- -

Syntax

- -
--o{dir_path}
-
- -
-
{dir_path}
-
This is the destination directory path. It's not required to end with a backslash. - If you specify * in {dir_path}, 7-Zip substitutes that * character to archive name.
-
- - -

Example

- -
-7z x archive.zip -oc:\Doc
-
- -

extracts all files from the archive.zip archive -to the c:\Doc directory.

- -
-7z x *.zip -o*
-
- -

extracts all *.zip archives to subfolders -with names of these archives.

- -

Commands that can be used with this switch

- -

- e (Extract), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/overwrite.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/overwrite.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/overwrite.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/overwrite.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - -ao (Overwrite mode) switch - - - - - -

-ao (Overwrite mode) switch

- -

Specifies the overwrite mode during extraction, to overwrite files already present on disk.

- -

Syntax

- -
--ao[a | s | t | u ]
-
- - - - - - - - -
Switch Description
-aoa Overwrite All existing files without prompt.
-aos Skip extracting of existing files.
-aou aUto rename extracting file (for example, name.txt will - be renamed to name_1.txt).
-aot auto rename existing file (for example, name.txt will - be renamed to name_1.txt).
- -

Examples

- -
-7z x test.zip -aoa
-
- -

extracts all files from test.zip archive and overwrites -existing files without any prompt.

- -

Commands that can be used with this switch

- -

- e (Extract), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -y (assume Yes on all queries), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/password.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/password.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/password.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/password.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ - - - - - -p (set Password) switch - - - - - -

-p (set Password) switch

- -

Specifies password.

- -

Syntax

- -
--p{password}
-
- -
-
{password}
-
Specifies password.
-
- - -

Examples

- -
-7z a archive.7z -psecret -mhe *.txt
-
-

compresses *.txt files to archive.7z using password -"secret". Also it encrypts archive headers (-mhe switch), so filenames will be encrypted. -

- -
-7z x archive.zip -psecret
-
-

extracts all files from archive.zip using password -"secret".

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - rn (Rename), - t (Test), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/recurse.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/recurse.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/recurse.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/recurse.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ - - - - - -r (Recurse subdirectories) switch - - - - - -

-r (Recurse subdirectories) switch

- -

Specifies the method of treating wildcards and filenames on the command line.

- -

Syntax

- -
--r[- | 0]
-
- - - - - - - -
Switch Description
-r Enable recurse subdirectories.
-r- Disable recurse subdirectories. This option is default for all commands.
-r0 Enable recurse subdirectories only for wildcard names.
- -

Examples

- -
-7z l archive.zip *.doc -r-
-
- -

lists all *.doc files - that belong to the archived root directory - in the archive.zip archive. -

- -
-7z a -tzip archive.zip -r src\*.cpp src\*.h
-
- -

adds all *.cpp and *.h - files from directory src and all it's subdirectories - to the archive.zip archive.

- -
-7z a archive.7z folder1\
-
- -

adds all files from directory folder1 and all it's subdirectories - to the archive.7z archive.

- -
-7z a archive.7z -r folder2\
-
- -

searches all folder2 directories in all subdirectories, - and adds them (including all subdirectories) to the archive.7z archive.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - h (Hash), - l (List), - rn (Rename), - t (Test), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -i (Include), - -x (Exclude) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sa.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sa.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sa.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sa.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ - - - - - -sa (set Archive name mode) switch - - - - - -

-sa (set Archive name mode) switch

- -

Specifies Archive name mode.

- -

Syntax

- -
--sa[a | e | s]
-
- - - - - - -
Switch Description
-saa Always add archive type extension.
-sae Use exact name specified in command.
-sas Add extension only if specified name has no extension. - It's default option.
- -

Examples

- -
-  7z a arc 1.txt
-
-

creates arc.7z

- -
-  7z a arc.spec 1.txt 
-
-

creates arc.spec

- -
-  7z a arc 1.txt -sae
-
-

creates arc

- -
-  7z a file.pdf file.pdf -saa -tzip
-
-

creates file.pdf.zip

- -

Commands that can be used with this switch

- -

- a (Add), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/scc.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scc.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/scc.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scc.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ - - - - - -scc (Set charset for console input/output) switch - - - - - -

-scc (Set charset for console input/output) switch

- -

Sets charset for for console input/output.

- -

Syntax

- -
--scc{UTF-8 | WIN | DOS}
-
- -

Default charset is DOS.

- -
-
UTF-8
-
Unicode UTF-8 character set.
-
WIN
-
Default character set of Windows.
-
DOS
-
DOS (OEM) character set of Windows.
-
- -

Example

- -
-7z l archive.7z -sccUTF-8
-
- -

lists files from archive.7z in UTF-8 encoding.

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/scrc.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scrc.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/scrc.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/scrc.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ - - - - - -scrc (Set hash function) switch - - - - - -

-scrc (Set hash function) switch

- -

Sets hash function for "extract" and "hash" commands.

- -

Syntax

- -
-[-scrc{Method}]
-
- -

Supported methods: CRC32, CRC64, SHA1, SHA256, BLAKE2sp, *. Default method is CRC32.

- -

Examples

- -
-7z t -scrcSHA256 archive.gz
-
- -

tests archive archive.gz and calculated SHA-256 for decompressed data.

- -
-7z h -scrcsha1 *.iso
-
- -

calculates SHA-1 for *.iso files.

- - -
-7z h -scrc* file.iso
-
- -

calculates hash values for file.iso file.

- -

Commands that can be used with this switch

- -

- h (Hash), - e (Extract), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sdel.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sdel.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sdel.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sdel.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - - - - - -sdel (Delete files after including to archive) switch - - - - - -

-sdel (Delete files after compression) switch

- -

Syntax

- -
--sdel
-
- -

If -sdel switch is specified, 7-Zip deletes files -after including to archive. So it works like moving files to archive.

-7-Zip deletes files at the end of operation and only if archive was successfully created.

- -

Examples

- -
-7z a a.7z *.txt -sdel
-
- -

moves txt files from disk's directory to a.7z archive.

- -

Commands that can be used with this switch

- -

- a (Add) -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sfx.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sfx.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sfx.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sfx.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ - - - - - -sfx (Create SFX archive) switch - - - - - -

-sfx (Create SFX archive) switch

- -

Creates self extracting archive.

- -

Syntax

- -
--sfx[{SFX_Module}]
-
- -
-
{SFX_Module}
-
-

Specifies the SFX module that will be combined with the archive. - This module must be placed in the same directory as the 7z.exe. - If {SFX_Module} is not assigned, 7-Zip will use standard console - SFX module 7zCon.sfx.

- - - - - - -
SFX_Module Description
7z.sfx Windows version.
7zCon.sfx Console version.
7zS.sfx Windows version for installers.
7zSD.sfx Windows version for installers (uses MSVCRT.dll).
-
-
- -

SFX module can unpack 7z archive or 7z multivolume archive. For example, -if you have name.7z or name.7z.001 archive, just rename sfx muldule to name.exe and place -to same folder with archive.

- -

SFX modules for installers

- -

SFX modules for installers are included in an external package (7z_extra). You can download -these modules from www.7-zip.org. SFX modules for installers (7zS.sfx and 7zSD.sfx) -allow you to create your own installation program. -Such a module extracts the archive to the user's temp folder, and runs a specified program, -and removes the temp files after the program finishes. -A self-extracting archive for installers must be created as joining the following files: -SFX_Module, Installer_Config (optional), 7z_Archive. -You can use the following command to create an installer self-extracting archive:

-
-copy /b 7zS.sfx + config.txt + archive.7z archive.exe
-
- -

An optimally small installation package size can be achieved, -if the installation files are uncompressed before including them in the 7z archive.

- -

-y switch for installer module specifies quiet mode extraction.

- -

Installer Config file format

-

-This config file contains commands for the Installer. The file begins with the string -;!@Install@!UTF-8! and ends with ;!@InstallEnd@!. -The file must be written in UTF-8 encoding. -The file contains any or all these string pairs: -

ID_String="Value"

-

- - - - - - - - - -
ID_String Description
Title Title for messages
BeginPrompt Begin Prompt message
Progress Value can be "yes" or "no". Default value is "yes".
RunProgram Command for executing. Default value is "setup.exe". Substring %%T - will be replaced with path to temporary folder, where files were extracted
Directory Directory prefix for "RunProgram". Default value is ".\\"
ExecuteFile Name of file for executing
ExecuteParameters Parameters for "ExecuteFile"
-

-

You may omit any pair.

- -

There are two ways to run a installation program: RunProgram and ExecuteFile. -Use RunProgram, if you want to run a program from the .7z archive. -Use ExecuteFile, if you want to open a document from the .7z archive, or -if you want to execute a command from Windows.

- -

If you use RunProgram, and if you specify empty directory prefix: Directory="", -the system searches for the executable file in the following sequence:

-
    -
  1. The directory from which the application (installer) loaded. -
  2. The temporary folder, where files were extracted. -
  3. The Windows system directory. -
- -

Config file Examples

- -
-;!@Install@!UTF-8!
-Title="7-Zip 4.00"
-BeginPrompt="Do you want to install the 7-Zip 4.00?"
-RunProgram="setup.exe"
-;!@InstallEnd@!
-
- -
- - -
-;!@Install@!UTF-8!
-Title="7-Zip 4.00"
-BeginPrompt="Do you want to install the 7-Zip 4.00?"
-ExecuteFile="7zip.msi"
-;!@InstallEnd@!
-
- -
- -
-;!@Install@!UTF-8!
-Title="7-Zip 4.01 Update"
-BeginPrompt="Do you want to install the 7-Zip 4.01 Update?"
-ExecuteFile="msiexec.exe"
-ExecuteParameters="/i 7zip.msi REINSTALL=ALL REINSTALLMODE=vomus"
-;!@InstallEnd@!
-
- -

Examples

- -
-7z a -sfx a.exe *.txt
-
- -

adds *.txt files to self extracting - archive a.exe using the default console SFX module.

- -
-7z a -sfx7z.sfx a.exe *
-
- -

adds all files to self extracting archive a.exe -with module 7z.sfx using windows version of SFX mudule.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - u (Update), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/shared.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/shared.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/shared.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/shared.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ - - - - - -ssw (Compress files open for writing) switch - - - - - -

-ssw (Compress files open for writing) switch

- -

Compresses files open for writing by another applications. If this switch is not -set, 7-zip doesn't include such files to archive.

- -

Syntax

- -
--ssw
-
- -

Example

- -
-7z a archive.7z -ssw *.txt
-
- -

compresses all *.txt files in -current folder including files open for writing by another applications.

- -

Commands that can be used with this switch

- -

- a (Add), - h (Hash), - u (Update) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sni.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sni.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sni.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sni.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - -sni (Store NT security information) switch - - - - - -

-sni (Store NT security information) switch

- -

Syntax

- -
--sni
-
- -

Use this switch to store and restore NT (NTFS) security information for files and directories. -Note that only NTFS file system supports that feature.

- -

Current version of 7-Zip can store NT security information only to WIM archives.

- -

Examples

- -
-7z a a.wim -sni *.txt
-
- -

stores txt files with NT security information.

- - -
-7z x a.wim -sni
-
-

unpacks a.wim and restores NT security information.

- -

Commands that can be used with this switch

- -

- a (Add), - e (Extract), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -sns -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sns.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sns.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/sns.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/sns.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ - - - - - -sns (Store NTFS alternate Streams) switch - - - - - -

-sns (Store NTFS alternate Streams) switch

- -

Syntax

- -
--sns[-]
-
- - - - - -
Switch Description
-sns Enable "Store NTFS alternate streams" mode. It's default option, if you extract archive.
-sns- Disable "Store NTFS alternate streams" mode. It's default option, if you create archive or - call "list" command.
- - -

If -sns mode is enabled, 7-Zip processes NTFS Alternate Data Streams for files and folders.

- -

Current version of 7-Zip can store NTFS alternate streams only to WIM archives.

- -

Note: 7-Zip can't include alternate streams to archives on 32-bit Windows XP and older systems.

- -

Examples

- -
-7z a a.wim -sns *.txt
-
-

stores txt files including alternate data streams.

- -
-7z x a.wim
-
-

unpacks a.wim including alternate data streams.

- -
-7z x a.wim -sns-
-
-

unpacks a.wim without alternate data streams.

- -
-7z l a.wim -sns
-
-

lists files in a.wim including alternate data streams.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - h (Hash), - l (List), - t (Test), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -sni -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/spf.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/spf.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/spf.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/spf.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ - - - - - -spf (Use fully qualified file paths) switch - - - - - -

-spf (Use fully qualified file paths) switch

- - - - - -
Switch Description
-spf Use absolute paths including drive letter.
-spf2 Use full paths without drive letter.
- -

Enables the mode that allows to use fully qualified file paths in archives. -If -spf switch is not specified, 7-Zip reduces file paths to relative paths when -it adds files to archive, and 7-Zip converts paths to relative paths when -you extract archive. -If -spf switch is specified, 7-Zip doesn't try to process or convert paths.

- -

Fully qualified file paths begin with one of the following:

-
    -
  • A UNC name, which starts with two backslash characters, for example, "\\Server1\". -
  • A disk designator with a backslash, for example "C:\". -
  • A single backslash, for example, "\Folder". -
- -

If -spf switch is specified, but the path is not fully qualified, 7-Zip will use specified path, -it will not convert the path to fully qualified path.

- - -

Please be careful, if you use -spf switch with "extract" command. -Check that file names in archive are correct. Note that with -spf switch -7-Zip can try to rewrite any file with path specified in archive.

- -

Syntax

- -
--spf
-
- -

Examples

- -
-7z a a.7z -spf c:\Files\test.txt d:\test.txt
-
- -

stores both txt files with full paths.

- -
-7z x a.7z -spf
-
- -

extracts files from a.7z archive with exact -file paths specified in archive.

- - -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - u (Update), - x (Extract with full paths) -

- -

See also

- -

- Switches: -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ssc.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ssc.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/ssc.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/ssc.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ - - - - - -ssc (Set Sensitive Case mode) switch - - - - - -

-ssc (Set Sensitive Case mode) switch

- -

Sets sensitive case mode for file names.

- -

Syntax

- -
--scs[-]
-
- - - - - -
Switch Description
-ssc Set case-sensitive mode. It's default for Posix/Linux systems.
-ssc- Set case-insensitive mode. It's default for Windows systems.
- -

Example

- -
-7z a archive.7z A*.txt -ssc -r
-
- -

compresses all A*.txt files - from current directory and all it's subdirectories. That command doesn't compress - a*.txt files. - -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - l (List), - t (Test), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stdin.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdin.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stdin.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdin.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - -si (read data from stdin) switch - - - - - -

-si (read data from stdin) switch

- -

Causes 7-Zip to read data from stdin (standard input) instead of from disc files.

- -

Syntax

- -
--si{file_name}
-
- -
-
{file_name}
-
Specifies a name that will be stored in the archive for the compressed data. - If file_name is not specified, data will be stored without a name.
-
- -

Note: The current version of 7-Zip support reading of archives from stdin only for xz, lzma, tar, gzip and bzip2 archives.

- -

Examples

- -
-7z a archive.gz -tgzip -siDoc2.txt < Doc.txt
-
- -

compresses input stream from file Doc.txt to -archive.gz archive -using Doc2.txt file name.

- -
-7z x 7z905.tar.gz -so | 7z x -si -ttar
-
- -

decompresses tar.gz archive.

- -

Commands that can be used with this switch

- -

- a (Add), - e (Extract), - h (Hash), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stdout.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdout.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stdout.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stdout.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ - - - - - -so (write data to stdout) switch - - - - - -

-so (write data to stdout) switch

- -

Causes 7-Zip to write output data to stdout (standard output stream).

- -

Syntax

- -
--so
-
- -

If the -so switch is used with the command that creates archive, it works only -with some archive formats: xz, gzip, bzip2 and tar.

- - -

Examples

- -
-7z x archive.gz -so > Doc.txt
-
- -

decompresses archive.gz -archive to output stream and then redirects that stream to -Doc.txt file.

- - -
-7z a dummy -tgzip -so Doc.txt > archive.gz
-
- -

compresses the Doc.txt file to the 7-Zip standard -output stream and writes that stream to -archive.gz file.

- -

Commands that can be used with this switch

- -

- a (Add), - e (Extract), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stl.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stl.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stl.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stl.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - - - - - -stl (Set archive timestamp from the most recently modified file) switch - - - - - -

-stl (Set archive timestamp from the most recently modified file) switch

- -

Syntax

- -
--stl
-
- -

If -stl switch is specified, 7-Zip sets timestamp for archive file as -timestamp from the most recently modified file in that archive.

- -

Examples

- -
-7z u a.7z -stl *.txt
-
- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - rn (Rename), - u (Update) -

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stop_switch.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stop_switch.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stop_switch.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stop_switch.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ - - - - - -- (Stop switches parsing) switch - - - - - -

-- (Stop switches parsing) switch

- -

Disables switch parsing after "--" on the command line. -This is to allow 7-Zip to use file names that start with "-". - -

Syntax

- -
---
-
- -

Examples

- -
-7z t -- -ArchiveName.7z
-
- -

tests -ArchiveName.7z archive.

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stx.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stx.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/stx.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/stx.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ - - - - - -stx (Exclude archive type) switch - - - - - -

-stx (Exclude archive type) switch

- -

The switch disables the code related to specified archive type and - an archive can not be open with specified archive type.

-

Multiple -stx switches are supported.

- -

Syntax

- -
--stx{archive_type}
-
- -
-
{archive_type}
-
Specifies the type of archive. It can be: 7z, xz, split, zip, gzip, bzip2, tar, .... -
-
- -

Example

- -
-7z x -stxpe archive.exe
-
- -

extracts files from archive.exe archive and doesn't use PE format handler.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - l (List), - t (Test), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/style.css --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/type.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/type.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/type.htm 2016-05-19 13:53:29.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/type.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ - - - - - -t (set Type of archive) switch - - - - - -

-t (set Type of archive) switch

- -

Specifies the type of archive.

- -

Syntax

- -
--t{archive_type}[:s{Size}][:r][:e][:a]
-
- -
-
{archive_type}
-
Specifies the type of archive. It can be: *, #, 7z, xz, split, zip, gzip, bzip2, tar, .... -
- -
*:r
-
Default mode. 7-Zip opens archive and subfile, if it's supported by format. -
- -
*
-
Opens only one top level archive. -
- -
*:s{Size}[b | k | m | g]
-
Sets upper limit for start of archive position. - Default scan size is 8 MBytes "*:s8m". - Example: "*:s0" means that it will open only file that has no any stub before archive. -
- -
#
-
Opens file in Parser mode, and ignores full archives. -
- -
#:a
-
Same as *, but it opens files with unknown extensions that contain archives in Parser Mode. -
- -
#:e
-
Opens file in Parser mode and checks all byte positions as start of archive. -
-
- -

If -t{archive_type} switch is not specified, 7-Zip uses extension of archive filename to - detect the type of archive. If you create new archive, -t{archive_type} switch is not - specified and there is no extension of archive, 7-Zip will create .7z archive.

- -

If -t{archive_type} switch is not specified and archive name contains incorrect extension, -the program will show the warning.

- -

It's possible to use the combined type (for example, mbr.vhd) for "Extract" and "List" -commands for some archives.

- -

When you extract archive of some types that contains another -archive without compression (for example, MBR in VHD), 7-Zip can open both -levels in one step. If you want to open/extract just top -level archive, use -t* switch.

- -

Note: xz, gzip and bzip2 formats support only one file per archive. -If you want to compress more than one file to these formats, -create a tar archive at first, and then compress it with your selected format.

- -

Example

- -
-7z a -tzip archive.zip *.txt
-
- -

adds all *.txt files from current directory -to zip archive archive.zip.

- -
-7z t -t7z.split archive.7z.001
-
- -

tests all files in archive.7z.001. It also checks -that archive is multivolume .7z archive.

- -
-7z x -t# sfxarchive.exe
-
- -

extracts sfxarchive.exe in parser mode.

- - -
-7z x -tiso archive.iso
-
- -

extracts files from archive.iso open as ISO archive. - -

-7z x -tudf archive.iso
-
- -

extracts files from archive.iso open as UDF archive. - - -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - e (Extract), - l (List), - t (Test), - u (Update), - x (Extract with full paths) -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/update.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/update.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/update.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/update.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ - - - - - -u (Update options) switch - - - - - -

-u (Update options) switch

- -

Specifies how to update files in an archive and (or) how to create new archives.

- -

Syntax

- -
--u[-]<action_set>[!{new_archive_name}]
-
-  <action_set> ::= <state_action>...
-
-    <state_action> ::= <state><action>
-
-      <state> ::= p | q | r | x | y | z | w
-
-      <action> ::= 0 | 1 | 2 | 3
-
- - -

Parameters

- -
-
dash (-)
-

Disables any updates in the base archive.

- -

The term base archive means the archive assigned by "base_archive_name" - on the command line. See Command line syntax - for more details.

-
-
{new_archive_name}
-

Specifies the path name of the new archive to be created. - All options in this switch will refer to this new archive.

-

If not assigned, then all options in this switch will - refer to the base archive of the command.

-
-
<state>
-

Specifies the state of a particular file to be processed.

-
<state> ::= p | q | r | x | y | z | w
-

For each unique filename there are 6 variants of state:

- - - - - - - - - - - - - - - - - - - - - - - - -
<state> State conditionFile on Disk File in Archive
p File exists in archive, but is not matched with wildcard.  Exists, but is not matched
q File exists in archive, but doesn't exist on disk.Doesn't exist Exists
r File doesn't exist in archive, but exists on disk.Exists Doesn't exist
x File in archive is newer than the file on disk.Older Newer
y File in archive is older than the file on disk.Newer Older
z File in archive is same as the file on diskSame Same
w Can not be detected what file is newer - (times are the same, sizes are different)? ?
-
- -
<action>
-

Specifies the action for a given <state>.

-
<action> ::= 0 | 1 | 2 | 3
-

For each state you can specify one of the three variants of actions:

- - - - - - -
<action> Description
0 Ignore file (don't create item in new archive for this file)
1 Copy file (copy from old archive to new)
2 Compress (compress file from disk to new archive)
3 Create Anti-item (item that will delete file or directory during extracting). This feature is supported only in 7z format.
-
-
- - -

Remarks

- -

Any update command (such as a (Add), - d (Delete), - u (Update)) can be assigned in these terms.

-

The following table shows action sets for update commands.

- - - - - - - - - -
command \ <state>p q r x y z w
d (Delete) 1 0 0 0 0 0 0
a (Add) 1 1 2 2 2 2 2
u (Update) 1 1 2 1 2 1 2
Freshen 1 1 0 1 2 1 2
Synchronize 1 0 2 1 2 1 2
- - -

If you don't specify a -!{new_archive_name} option, then -all options will refer to the main archive (the archive assigned on the command line after the 7z command). -If you specify !{new_archive_name} -option, then 7-Zip also will create a new archive with the specified name and all options -will refer to that new archive.

- -

Multiple update switches are supported. -7-Zip can create any number of new archives during one operation.

- -

By default, the action set for each new archive is assigned -as the action set of the main command. There are 3 different -action sets for commands: a (Add), - d (Delete), - u (Update). -You can overload any <state_action> pair.

- -

Time zone notes

-

If you change time zone (when you move your computer to another time zone -or if there are clock changes for daylight saving in your zone), you can have some problems -with update commands that depend from file's modification time. It's strongly recommended to use only -file system that uses Coordinated Universal Time (UTC) and archive format that also uses UTC. -In that case you will have no problems with time zone changes. -Also it's recommended to use only UTC formats in other cases, for example, if you send files to -someone in another time zone.

- -

Also in some cases there are no problems, if both file system and archive format use local time, for example, FAT file system and ZIP format.

-
    -
  • UTC file systems: NTFS -
  • UTC archive formats: .zip with -mtc switch, 7z, tar, gzip2, iso, wim -
  • Local time file systems : FAT, FAT32 -
  • Local time archive formats : rar, zip, cab -
- -

Examples

- -
-7z u c:\1\exist.7z -u- -up0q3x2z0!c:\1\update.7z *
-
- -

creates a new archive update.7z and -writes to this archive all files from current directory which differ from -files in exist.7z archive. -exist.7z archive will not be changed.

- -
-7z u c:\1\exist.7z -up0q3x2z0!c:\1\update.7z * -ms=off
-
- -

creates a new archive update.7z and -writes to this archive all files from the current directory which differ from -files in exist.7z archive. - -

Note: the updating of solid .7z archives can be slow, since it -can require some recompression.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - rn (Rename), - u (Update), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/volume.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/volume.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/volume.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/volume.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ - - - - - -v (Create Volumes) switch - - - - - -

-v (Create Volumes) switch

- -

Specifies volume sizes.

- -

Syntax

- -
--v{Size}[b | k | m | g]
-
-
-
-
{Size}[b | k | m | g]
-
Specifies volume size in Bytes, Kilobytes (1 Kilobyte = 1024 bytes), - Megabytes (1 Megabyte = 1024 Kilobytes) or Gigabytes (1 Gigabyte = 1024 Megabytes). - if you specify only {Size}, 7-zip will treat it as bytes.
-
- -

It's possible to specify several -v switches.

- -

NOTE: Please don't use volumes (and don't copy volumes) before finishing archiving. -7-Zip can change any volume (including first volume) at the end of archiving operation.

- -

Examples

- -
-7z a a.7z *.txt -v10k -v15k -v2m
-
- -

creates multivolume a.7z archive. -First volume will be 10 KB, second will be 15 KB, and all others will be 2 MB.

- -

Commands that can be used with this switch

- -

- a (Add), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/working_dir.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/working_dir.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/working_dir.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/working_dir.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - -w (set Working directory) switch - - - - - -

-w (set Working directory) switch

- -

Sets the working directory for the temporary base archive. By -default, 7-Zip builds a new base archive file in the same directory as the -old base archive file. By specifying this switch, you can set the -working directory where the temporary base archive file will be built. -After the temporary base archive file is built, it is copied over the -original archive; then, the temporary file is deleted.

- -

Syntax

- -
--w[{dir_path}]
-
- -
-
{dir_path}
-
-

Specifies the destination directory path. It's not required that - a path end with a backslash.

-

If <dir_path> is not assigned, then 7-Zip will use the Windows temporary directory.

-
-
- - -

Example

- -
-7z a -tzip archive.zip *.cpp -wc:\temp
-
- -

adds *.cpp files to the -archive.zip archive, creating a temporary archive -in c:\temp folder.

- -

Commands that can be used with this switch

- -

- a (Add), - d (Delete), - rn (Rename), - u (Update), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/yes.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/yes.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/switches/yes.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/switches/yes.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ - - - - - -y (assume Yes on all queries) switch - - - - - -

-y (assume Yes on all queries) switch

- -

Disables most of the normal user queries during 7-Zip -execution. You can use this switch to suppress overwrite queries in the -e (Extract) and -x (Extract with full paths) commands.

- -

Syntax

- -
-y
- -

Examples

- -
-7z x src.zip -y
-
- -

extracts all files from - src.zip archive. All overwrite queries will be -suppressed and files on disk with same filenames as in archive will be -overwritten.

- -

Commands that can be used with this switch

- -

- e (Extract), - x (Extract with full paths) -

- -

See also

- -

- Switches: - -ao (Overwrite mode), -

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/cmdline/syntax.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/syntax.htm --- p7zip-rar-16.02/DOC/MANUAL/cmdline/syntax.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/cmdline/syntax.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ - - - - - Command Line Syntax - - - - - -

Command Line Syntax

- -
-7z <command> [<switch>...] <base_archive_name> [<arguments>...]
-
-
-<arguments> ::= <switch> | <wildcard> | <filename> | <list_file>
-<switch>::= <switch_symbol><switch_characters>[<option>]
-<switch_symbol> ::= '/' | '-' 
-<list_file> ::= @{filename}
-
- - -

Expressions in square brackets (between '[' and ']') are optional.

- -

Expressions in curly braces ('{' and '}') mean that instead of that -Expression (including braces), the user must substitute some string.

- -

Expression

- -
-expression1 | expression2 | ... | expressionN
-
- -

-means that any (but only one) from these expressions must be specified. - -

Commands and -switches can be entered in upper or lower case.

- -

Command is the first non-switch argument.

- -

The "base_archive_name" must be the first filename on the command line -after the command.

- -

The switches and other filenames can be in any order.

- -

Wildcards or filenames with spaces must be quoted:

- -
-    "Dir\Program files\*"
-    Dir\"Program files"\*
-
- -

Switch options can be combined to save command line length. However, some -switch options take optional string arguments and therefore, must be the -last option in a combined argument token string because 7-Zip accepts the -rest of the argument token as the optional argument.

- -

7-Zip uses wild name matching similar to Windows 95:

-
    -
  • '*' means a sequence of arbitrary characters.
  • -
  • '?' means any character.
  • -
- -

-7-Zip doesn't use the system wildcard parser. 7-Zip doesn't -follow the archaic rule by which *.* means any file. 7-Zip treats -*.* as matching the name of any file that has an extension. To process all files, you must -use a * wildcard.

- -

Examples:

- - - - - -
*.txtmeans all files with an extension of ".txt"
?a*means all files with a second character of "a"
*1*means all names that contains character "1"
*.*.*means all names that contain two at least "." characters
- - -

The default wildcard "*" will be used if there is no filename/wildcard in the -command line.

- -

Slash ('\') at the end of a path means a directory. Without a Slash ('\') at -the end of the path, the path can refer either to a file or a directory. - - -

List file

- -

You can supply one or more filenames or wildcards for special list files -(files containing lists of files). The filenames in such list file must be -separated by new line symbol(s).

- -

For list files, 7-Zip uses UTF-8 encoding by default. You can change encoding -using -scs switch.

- -

Multiple list files are supported.

- -

For example, if the file "listfile.txt" contains the following:

- -
-    My programs\*.cpp
-    Src\*.cpp
-
-

then the command

- -
-    7z a -tzip archive.zip @listfile.txt
-
- -

adds to the archive "archive.zip" all "*.cpp" files from directories "My -programs" and "Src".

- -

Short and Long File Names

- -

7-Zip supports short file names (like FILENA~1.TXT) in some cases. -However, it's strongly recommended to use only the real (long) file names.

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/about.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/about.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/about.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/about.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - - - - - About Dialog Box - - - - - -

About Dialog Box

- -

The About dialog box provides information about 7-Zip. This dialog box is available -from the Help menu.

- -
    -
  • Press www.7-zip.org button for opening 7-Zip Home Page.
  • -
- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/benchmark.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/benchmark.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/benchmark.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/benchmark.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ - - - - - Benchmark - - - - - -

Benchmark

- -

This form allows you to measure the performance of your computer.

- -

There are two tests:

-

    -
  1. Compression with LZMA method -
  2. Decompression with LZMA method -
- -

The benchmark shows a rating in MIPS (million instructions per second). -The rating value is calculated from the measured speed, and it -is normalized with results of Intel Core 2 CPU with multi-threading option switched off. -So if you have modern CPU from Intel or AMD, rating values in single-thread mode -must be close to real CPU frequency.

- -

You can change the dictionary size to increase memory usage. -Also you can change the number of threads.

- -

The CPU Usage column shows the percentage of time the processor is working. -It's normalized for a one-thread load. For example, 180% CPU Usage for 2 threads -can mean that average CPU usage is about 90% for each thread.

- -

The Rating / Usage column shows rating normalized for 100% of CPU usage. -That column shows performance of the one CPU thread. It must be close to real CPU frequency, -if you have modern CPU.

- -

The Total rating shows averages of the compressing and decompression ratings.

- - -

Compression speed and rating strongly depend from memory (RAM) latency. - -

Decompression speed and rating strongly depend on CPU integer operations. -For example, an Intel Pentium 4 has big branch -misprediction penalty (which is effect of long pipeline) and pretty slow -multiply and shift operations. So, the Pentium 4 has pretty low decompressing -ratings.

- - -

Also the program checks possible errors. -If the program shows some error message, in most cases it means that -your RAM is defective. If so, don't use 7-Zip for -compressing data, since such errors can lead to data losses.

- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/index.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ - - - - - 7-Zip File Manager - - - - - -

7-Zip File Manager

- -

The 7-Zip File Manager is a program for manipulating files and folders.

- -

The 7-Zip File Manager can work with two panels. You can switch between -panels by pressing the Tab button. Most of the operations can be -executed using keyboard shortcuts or by right-clicking on items -and selecting the appropriate command from menu.

- - -

In This Section

- -
-
Menu Items and Shortcut Keys
-
Describes the menu items and keyboard shortcut.
-
Options Dialog Box
-
Describes what settings you can change that affect the 7-Zip File Manager.
-
Benchmark
-
Describes a 7-Zip Benchmark for measuring CPU performance.
-
About Dialog Box
-
Provides information about 7-Zip.
-
Plugins
-
Describes plugins for the 7-Zip File Manager.
-
- -
-

You have access to the following items from root folder in 7-Zip File Manager:

-
    -
  • Computer: computer's disks -
  • Documents: My Documents folder of current user -
  • Network -
  • \\. : the folder for low-level access to disks. - You must have administrator's rights to use that folder. - You can -
      -
    • copy .iso images from CD/DVD to file. -
    • view NTFS/FAT partitions via 7-Zip parser. It provides read-only access to files. -
    -
-

- - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/menu.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/menu.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/menu.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/menu.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ - - - - - Menu Items and Shortcut Keys - - - - - -

Menu Items

- -

Note: 'Grey' refers to the numeric keypad.

- -

File

- - - - - - - - - - - - - - - - - - - - - - - -
Menu item Shortcut Description
System Submenu with menu commands from system shell. It can be enabled in Options.
Open Enter Open current item
Open Inside Ctrl+PgDn Open current item as folder inside 7-Zip
Open Outside Shift+Enter Open current item in new window
View F3 Open selected item with viewer
Edit F4 Open selected item with editor
Rename F2 Rename selected item
Copy To... F5 Copy selected items
Move To... F6 Move selected items
Delete Delete Delete selected items
Split file... Split file to parts
Combine files... Combine files to one file
Properties Alt+Enter Show Properties of file
Comment Ctrl+Z Set comment for file
Calculate checksum Calculates CRC checksum for files
Diff Show the differences between two files. It can be enabled, if the diff program is set in Options
Create Folder F7 Create new folder
Create File Shift+F4 Creates new file
Link... Create symbolic link or hard link
Alternate Streams Show alternate file streams at NTFS.
Exit Alt+F4 Closes the program.
- -

Edit

- - - - - - - - - -
Menu Item Shortcut Description
Select All Shift+[Grey +] Select all items
Deselect All Shift+[Grey -] Select all items
Invert Selection [Grey *] Select / Deselect all items
Select... [Grey +] Select specified items
Deselect... [Grey -] Deselect specified items
Select by Type Alt+[Grey +] Select all items with the same extension as current item
Deselect by Type Alt+[Grey -] Deselect all items with the same extension as current item
- -

View

- - - - - - - - - - - - - - - - - - - - - - -
Menu Item Shortcut Description
Large IconsCtrl+1 Displays items by using large icons
Small IconsCtrl+2 Displays items by using small icons
List Ctrl+3Displays items in a list
Details Ctrl+4Displays items in a list with detailed information about each item
Name Ctrl+F3 Sort items by Name
Type Ctrl+F4 Sort items by Type
Date Ctrl+F5 Sort items by Date
Size Ctrl+F6 Sort items by Size
Unsorted Ctrl+F7 Do not sort items
Flat View Switch Flat view mode for list of files
2 Panels F9 Switch On/Off second panel
Toolbars Menu items for toolbars handling
Open Root Folder \ Open root computer folder
Up One Level Backspace Open the folder one level up
Folders History... Alt+F12 Open folders history
Refresh Ctrl+R Refresh items list
Auto Refresh If "Auto Refresh" is enabled, 7-Zip reloads list of files, if there are changes in files on drive.
- -

Favorites

- - - -
Menu Item Shortcut Description
Add folder to Favorites as Adds folder to favorities
- -

Tools

- - - - -
Menu Item Shortcut Description
Options... Open Options dialog box
Benchmark Measure the performance of your computer with 7-Zip LZMA benchmark
- - -

Help

- - - - -
Menu Item Shortcut Description
Contents... F1 Opens 7-Zip Help
About 7-Zip... Opens About dialog box
- - -

Miscellaneous commands

- - - - - - - - - - - - - -
Shortcut Description
Tab Switch between panels
Insert Select / Deselect current item
Shift+F10 Display the shortcut menu for the selected items
RightCtrl+0
Alt+0
...
RightCtrl+9
Alt+9
Open folder bookmark
Shift+RightCtrl+0
Shift+Alt+0
...
Shift+RightCtrl+9
Shift+Alt+9
Creates folder bookmark
Alt+F1 Edit the Folder Address on left panel
Alt+F2 Edit the Folder Address on right panel
Alt+Up Open same folder in other panel
Alt+Left,
Alt+Right
Open current folder in other panel
Ctrl+[Grey +] Adjust optimal column width for items
Ctrl+C Copy the name of selected file to clipboard
- -

Keyboard Shortcuts

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Key Normal Ctrl Alt Shift
Tab Switch panel
F1 Help Left Path
F2 Rename Right Path
F3 View Sort by Name
F4 Edit Sort by Type Exit Create File
F5 Copy Sort by Date
F6 Move Sort by Size
F7 Create Folder Unsorted
F9 1/2 Panels
F10 Menu Shortcut Menu
F12 Folders History
0-9 R: Folder BookmarkFolder Bookmark
A Select All
C Copy to clipboard
N Create File
R Refresh
Z Comment
Backspace Up One Level
Enter Open Properties Open outside
Insert Select Item
Delete Delete Item
Page Down Open Inside
Page Up Up One Level
Up Open same folder
Left Open current folder
Right Open current folder
\ Open root
Grey / Open root
Grey * Select All
Grey + Select Adjust columns Select by Type Select All
Grey - Deselect Deselect by Type Deselect All
- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/options.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/options.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/options.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/options.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ - - - - - Options Dialog Box - - - - - -

Options Dialog Box

- - -

You can change many of the settings that affect the 7-Zip File Manager -in the Options dialog box. To access this dialog box select Options -from the Tools menu.

- -

The options dialog box contains the following pages:

- - -

System Page

-

Allows you to specify the behavior of 7-Zip in the filing system.

-
-
Associate 7-Zip with
-
Allows to associate 7-Zip with file name extensions. - There are two list of associations: for "Current User" and for "All Users". - To set associations for "All Users" you must run 7-Zip File Manager - with administrator rights. - Each association can have up to 4 states: -
    -
  • no association. -
  • AppName - the extension is associated with another program (not 7-Zip). -
  • [7-Zip] - the extension is associated with another copy (edition) of 7-Zip. -
  • 7-Zip - the extension is associated with this copy of 7-Zip. -
- -

You can switch between these states by clicking on cell. Or you can change states - for all extension by clicking on "+" button.

-
- -

7-Zip Page

-

Allows you to specify behavior of 7-Zip in Windows Shell.

-
-
Integrate 7-Zip to shell context menu
-
Select this check box to add 7-Zip commands to Shell Context Menu. - There are two check boxes in 64-bit system. So it's possible to enable - 7-Zip context menu for 32-bit and 64-bit applications.
-
Cascaded context menu
-
Select this check box to group 7-Zip context menu items to one 7-Zip submenu.
-
Icons in context menu
-
Select this check box to show 7-Zip icon in context menu items.
-
Eliminate duplication of root folder
-
That option allows to eliminate duplication of root folder for "Extract to" operations, - if all files in archive are placed in folder with name that is identical to name of output folder.
-
Context menu items
-
Lists the optional context menu items. If an item is checked, - 7-Zip will add this item to the context menu.
-
- - -

Folders Page

-

Allows you to set the folders which 7-Zip will use for internal purposes.

- -

Working folder

- -

The working folder section allows you to specify a folder which will be used -for temporary archive files:

- -
-
System temp folder
-
7-Zip will use the Windows temp folder.
-
Current
-
7-Zip will use the folder containing the target archive.
-
Specified
-
7-Zip will use the folder specified in the following edit control.
-
- -
-
Use for removable drives only
-
Specifies whether 7-Zip should use the specified folder settings - only for removable drives; for other drives, 7-Zip will create - temporary archives in the folder containing the target archive. - If you clear this check box, 7-Zip always will use the specified folder - settings mode always. -
-
- -

7-Zip uses temporary archive files for all update operations. -So, for speed reasons, it is recommended that you select the -System temp folder option and select -Use for removable drives only check box. -

- -

Editor Page

-

Allows you to specify settings for the editor.

-
-
View
-
Specifies the path to the viewer that will be used for "View" command (F3).
-
Editor
-
Specifies the path to the editor that will be used for "Edit" command (F4).
-
Diff
-
Specifies the path to a file comparison utility that shows the - differences between two files.
-
- -

Settings Page

-

Allows you to specify some settings.

-
-
Show .. item
-
Shows .. item in file list.
-
Show real file icons
-
Shows real file icons in file list. If this option is enabled, - listing updates can be slower.
-
Full row select
-
When an item is selected, the item and all its subitems are highlighted.
-
Show grid lines
-
Displays gridlines around items and subitems.
-
Single-click to open an item
-
If enabled, File Manager opens files and folders by single-clicking them. -
Alternative selection mode
-
If enabled, File Manager keeps selection mark when you move cursor.
- -
Show system menu
-
Shows a system context sub-menu in the File menu.
- -
Use large memory pages
-
If enabled, 7-Zip will try to use large pages. This feature allows an increase in speed of compression. - This may cause 7-Zip to pause when starting compression, because of allocation of the large pages. - Also, the Windows Task Manager doesn't show the real memory usage of the program, if 7-Zip uses large pages. - This feature works only on Windows 2003 / XP x64. - Also you must have administrator's rights for your system. - Recommended size of RAM: 1 GB or more. - To install this feature you must run 7-Zip File Manager at least once, - close it and reboot the system.
-
- -

Language Page

-

Allows you to change the default language.

-
-
Language
-
Lists the available languages.
-
- - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/add.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/add.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/add.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/add.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ - - - - - Add to Archive Dialog Box - - - - - -

Add to Archive Dialog Box

- -

Allows you to specify options for creating or updating an archive.

- -

How to call this dialog box

-
    -
  1. In Windows Explorer or in 7-Zip, right-click the file(s) or folder(s) you want to compress.
  2. -
  3. Point to 7-Zip, and then click the Add to archive... command item.
  4. -
- -

Parameters

-
-
Archive
-
Provides a space for you to specify a destination archive name. - You can click "..." button to display "Open" dialog box - that you can use to locate archive.
- -
Archive format
-
Specifies a format of created archive. Some formats (gzip and bzip2) - do not support compressing more the one file per archive.
- -
Compression level
-
-

Specifies compression level. There are 6 levels of compression:

- - - - - - - - -
Value Meaning
Store Files will be copied to archive without compression.
Fastest Fastest compression.
Fast Fast compression.
Normal Compression with balanced settings.
Maximum Can give a higher compression ratio than Normal level. - But it can be slower, and it can require more memory.
Ultra Can give a higher compression ratio than Maximum level. - But it can be slower, and it can require more memory.
-
- -
Compression method
-
-

Specifies compression method. Each archive format can have its own compression methods:

- - - - - - - - -
Method Description
LZMA It's base compression method for 7z format. - Even old versions of 7-Zip can decompress archives created with LZMA method. - It provides high compression ratio and very fast decompression.
LZMA2 Default compression method of 7z format. LZMA2 is LZMA-based compression method. - It provides better multithreading support than LZMA. But compression ratio - can be worse in some cases. For best compression ratio with LZMA2 use 1 - or 2 CPU threads. If you use LZMA2 with more than 2 threads, 7-zip splits data - to chunks and compresses these chunks independently (2 threads per each chunk).
PPMd Dmitry Shkarin's PPMdH algorithm with small changes. - Usually it provides high compression ratio and high speed - for text files.
BZip2 Standard compression method based on BWT algorithm. - Usually it provides high speed and pretty good - compression ratio for text files.
Deflate Standard compression method of ZIP and GZip formats. - Compression ratio is not too high. But it provides pretty fast - compressing and decompressing. Deflate method supports only - 32 KB dictionary.
Deflate64 Modified version of Deflate algorithm with - bigger dictionary (64KB).
- -
-

Estimated 7-Zip performance and memory requirements for 2 GHz dual core CPU:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodLevelDictionary SizeCompressing SpeedDecompressing SpeedMemory for CompressingMemory for Decompressing
LZMAfastest64 KB4.5 MB/s15 MB/s3 MB3 MB
fast1 MB3 MB/s10 MB3 MB
normal16 MB2 MB/s186 MB18 MB
maximum32 MB1.8 MB/s376 MB34 MB
ultra64 MB1.6 MB/s709 MB66 MB
PPMDfast4 MB1.4 MB/s6 MB
normal24MB1.2 MB/s26 MB
maximum64 MB1.0 MB/s66 MB
ultra192 MB0.9 MB/s194 MB
Deflatefast32 KB15 MB/s40 MB/s3 MB2 MB
normal3.5 MB/s
maximum1.5 MB/s4MB
ultra0.4 MB/s
BZip2normal900 KB3 MB/s16 MB/s20 MB7 MB
maximum1.2 MB/s
ultra0.4 MB/s
-
- -
Dictionary size
-
-

Specifies Dictionary size for compression method.

-

Usually, a higher Dictionary size gives a higher compression ratio. - But compressing can be slower and it can require more memory.

-

- Memory (RAM) usage for LZMA compressing is about 11 times more than dictionary size. - Memory usage for LZMA decompressing is close to value of dictionary size. - Memory usage for PPMd compressing and decompressing is almost equal - to dictionary size.

-
- -
Word size
-
-

Specifies the length of words, which will be used to find identical - sequences of bytes for compression.

-

Usually for LZMA and Deflate, big Word size gives a little bit better - compression ratio and slower compression process. - A big Word size parameter can significantly increase compression ratio - for files which contain long identical sequences of bytes. For PPMd, - the Word size strongly affects both compression ratio and - compression/decompression speed.

-
- - -
Solid Block size
-
-

Specifies the size of a solid block. You can also disable solid mode. - In solid mode all files will be compressed as continuous data blocks. - Usually compressing to a solid archive improves the compression ratio. - You can use this option only for 7z archives. The updating of solid .7z - archives can be slow, since it can require some recompression.

-.

-
- -
Number of CPU threads
-
-

Specifies the number of threads for compressing. - A big number of threads can speed up compression speed on Multi-Processor systems. - Sometimes it can increase speed even on single-core CPU.

-
- -
Split to volumes
-
-
-    {Size}[b | k | m | g]
-    
- -

Specifies volume sizes in Bytes, Kilobytes (1 Kilobyte = 1024 bytes), - Megabytes (1 Megabyte = 1024 Kilobytes) or Gigabytes (1 Gigabyte = 1024 Megabytes). - If you specify only {Size}, 7-zip will treat it as bytes. It's possible to specify - several values. Example:

- -
-    10k 15k 2m
-    
- -

The first volume will be 10 KB, the second will be 15 KB, and all others will be 2 MB.

- -
- -
Parameters
-
-

Allows you to specify parameters for compression. See the - -m (Method) switch description for - more details. Omit the -m prefix (as in -m switch) when using this dialog box.

-

Examples

-
-      f=delta:4
-

uses Delta:4 filter (if you want to compress WAV files).

- -
-      f=bcj2
-

uses BCJ2 filter (for x86 executables).

- -
- -
Update mode
-
-

Specifies update mode:

- - - - - - -
Value Meaning
Add and replace files Add all specified files to the archive.
Update and add files Update older files in the archive and add - files that are new to the archive.
Freshen existing files Update specified files in the - archive that are older than the selected disk files.
Synchronize files Replace specified files only if - added files are newer. Always add those files, which are not - present in the archive. Delete from archive those files, - which are not present on the disk.
-
- -
Options
-
-

Specifies compression options:

- - - - - -
Option Meaning
Create SFX archive Create self-extracting archive. You can use this option only - for 7z archives. Look to - -sfx (Create SFX archive) switch description for - more details about SFX modules.
Compress shared files Compress files open for writing by another applications.
Delete files after compression Delete files - after including to archive. So it works like moving files to archive. - 7-Zip deletes files at the end of operation and only if archive was successfully created.
-
- -
Encryption
-
-

Specifies password and encryption options.

-
-
Enter password
-
Specify password here
-
Reenter password
-
Reenter password here for verification
-
Show Password
-
Shows Password
-
Encryption method
-
Specifies the encryption method. For 7z format, it can be only AES-256. - For ZIP format you can select ZipCrypto or AES-256. - Use ZipCrypto, if you want to get archive compatible with most of the ZIP archivers. - AES-256 provides stronger encryption, but now AES-256 is supported only - by 7-Zip, WinZip and some other ZIP archivers. -
Encrypt file names
-
Enables or disables archive header encryption, including file name encryption.
-
-
- - -
-
    - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/extract.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/extract.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/extract.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/extract.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ - - - - - Extract Dialog Box - - - - - -

    Extract Dialog Box

    - -

    Allows you to specify options for extracting files from archive.

    - -

    How to run this dialog box

    - -

    There are two ways to run this dialog to extract all files from an archive:

    -
      -
    • In Windows Explorer or in 7-Zip, right-click the archive file, point to 7-Zip, and then click Extract files....
    • -
    • Select the archive file in 7-Zip and press Extract button.
    • -
    - - -

    Parameters

    -
    -
    Extract to
    -
    Provides a space for you to specify an output folder. - You can click "..." button to display "Browse for folder" - dialog box that you can use to locate output folder.
    - -
    Path mode
    -
    -

    Specify extract mode:

    - - - - - -
    Value Meaning
    Full pathnames Extract files with full pathnames.
    No pathnames Extract files without folder paths.
    Absolute pathnames Extract files with absolute pathnames. - 7-Zip doesn't use folder specified in "Extract to" field for files in archive - that have absolute pathnames. Absolute path can include drive name.
    -
    - -
    Eliminate duplication of root folder
    -
    That option allows to eliminate duplication of root folder, if all files - in archive are placed in folder with name that is identical to name of output folder.
    - -
    Overwrite mode
    -
    -

    Specify overwrite mode for files that already present on disk:

    - - - - - - - -
    Value Meaning
    Ask before overwrite Ask before overwriting existing files.
    Overwrite without prompt Overwrite existing files without prompt.
    Skip existing files Skip extracting of existing files.
    Auto rename Rename extracted files, if a file with the same name already exists. - For example, file document.txt will be renamed to document_1.txt.
    Auto rename existing files Rename existing files, if a file with the same name already exists. - For example, file document.txt will be renamed to document_1.txt.
    -
    - -
    Password
    -
    -

    Specifies a password for encrypted archives.

    -
    -
    Show Password
    -
    Show a password in Password field.
    - -
    Restore file security
    -
    Restore file security information, if archive contains that information. - That feature now is implemented only for WIM archives.
    - -
    -
      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/index.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ - - - - - 7-Zip Plugin - - - - - -

      7-Zip Plugin

      - -

      7-Zip is a plugin for manipulating archives. It makes all archive files -look like usual folders in File Manager.

      - -

      Most of the operations with compressed files can be initiated by -right-clicking on files in the File Manager (or in Windows Explorer) and -selecting the appropriate command from a menu.

      - -

      Using 7-Zip

      - -
      -
      Opening archive
      -
      -

      There are two ways to open an archive file:

      -
        -
      • If you have the file type associated with 7-Zip, then you can open the - file with 7-Zip by double-clicking the file or by right-clicking and selecting - the Open command.
      • -
      • You can right-click the archive file, point to 7-Zip, - and then click the Open command item.
      • -
      -
      -
      Extracting archive
      -
      -

      There are two ways to extract files from an archive:

      -
        -
      • To extract all files from an archive right-click the archive file, - point to 7-Zip, and then click the Extract files... - command item.
      • -
      • To extract specific files from an archive, open it by - Open archive with 7-Zip, - select the items to extract, and run the Copy To... command.
      • -
      -

      Extract Dialog will appear.

      -
      -
      Testing archive
      -
      -

      To test an archive, right-click the archive file, - point to 7-Zip, and then click the Test archive - command item.

      -
      -
      Creating and updating files in an archive
      -
      -

      For creating or updating an archive file, right-click the file(s) or folder(s) you want to compress, - point to 7-Zip, and then click the Add to archive... command item. - Add to Archive Dialog will appear.

      -
      -
      - - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/style.css --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/7-zip/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/7-zip/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/index.htm --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - - - - - Plugins - - - - - -

      Plugins

      - -

      The 7-Zip File Manager can use internal and external plugins.

      - -

      Currently 7-Zip uses the following plugins:

      -
      -
      7-Zip
      -
      Plugin for manipulating archives.
      -
      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/plugins/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/style.css --- p7zip-rar-16.02/DOC/MANUAL/fm/plugins/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/plugins/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/fm/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/style.css --- p7zip-rar-16.02/DOC/MANUAL/fm/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/fm/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/7z.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/7z.htm --- p7zip-rar-16.02/DOC/MANUAL/general/7z.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/7z.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ - - - - - 7z Format - - - - - -

      7z Format

      - -

      7z is a new archive format, providing a high compression ratio.

      - -

      The main features of the 7z format:

      -
        -
      • Open architecture -
      • High compression ratio -
      • Strong AES-256 encryption -
      • Ability to use any compression, conversion or encryption method -
      • Supports files with sizes up to 16000000000 GB -
      • Unicode file names -
      • Solid compression -
      • Archive headers compression -
      - -

      7z has an open architecture, so it can support any new compression methods.

      -The following methods currently are integrated into 7z:

      - - - - - - - - - - -
      Method Description
      LZMA Improved and optimized version of LZ77 algorithm
      LZMA2 LZMA-based compression method. It provides better multithreading support than LZMA
      PPMD Dmitry Shkarin's PPMdH with small changes
      BCJ Converter for 32-bit x86 executables
      BCJ2 Converter for 32-bit x86 executables
      BZip2 Standard BWT algorithm
      Deflate Standard LZ77-based algorithm
      - -

      LZMA is the default and general compression method of 7z format. -The main features of the LZMA method:

      -
        -
      • High compression ratio -
      • Variable dictionary size (up to 4 GB) -
      • Compression speed: about 1 MB/s on 2 GHz CPU -
      • Decompression speed: about 10-20 MB/s on 2 GHz CPU -
      • Small memory requirement for decompression (depends from dictionary size) -
      • Small code size for decompression: about 5 KB -
      • Supports multi-threading and P4's hyper-threading -
      - -

      The LZMA compression algorithm is very suitable for embedded applications. -If you want to use LZMA code, you can ask for consultation, custom code programming, -and required developer licenses at -

      www.7-zip.org/support.html

      -

      - -

      AES encryption

      - -

      7-Zip supports encryption with the AES-256 algorithm. -This algorithm uses a cipher key with length of 256 bits. To create the key, 7-Zip -uses a derivation function based on an SHA-256 hash algorithm. -A key derivation function produces a derived key from a text password defined by the user. -To increase the cost of an exhaustive search for passwords, 7-Zip uses a big number -of iterations to produce the cipher key from the text password.

      - -

      Tips for selecting password length

      - -

      Here is an estimate of the time required for an exhaustive -password search attack, when the password is a random -sequence of lowercase Latin letters.

      - -

      The most complex task for password search attack is SHA-256 calculation. -Special SHA-256 hardware or GPU can be used to accelerate password search attack. -Now modern GPU can provide about 10 times more performance for SHA-256 calculation -than modern CPU. And special SHA-256 hardware can provide about 20 times more -performance than GPU.

      - -

      We suppose that one user with a budget of about $2000 (for GPUs) can check -10000 passwords per second and an organization with a budget of about -10^9 USD (one thousand million US dollars) can check 3 * 10^12 passwords per second. -We also suppose that the processor in use doubles its performance every two years; -so, each additional Latin letter of a long password adds about -9 years to an exhaustive key search attack.

      - -

      The result is this estimate of the time to succeed in an attack:

      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Password LengthSingle User AttackOrganization Attack
      1 1 s 1 s
      2 1 s 1 s
      3 2 s 1 s
      4 1 min 1 s
      5 30 min 1 s
      6 12 hours 1 s
      7 14 days 1 s
      8 1 year 1 s
      9 10 years 2 s
      10 19 years 1 min
      11 28 years 30 min
      12 37 years 12 hours
      13 46 years 14 days
      14 55 years 1 year
      15 64 years 10 years
      16 73 years 19 years
      17 82 years 28 years
      18 91 years 37 years
      19 100 years 46 years
      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/faq.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/faq.htm --- p7zip-rar-16.02/DOC/MANUAL/general/faq.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/faq.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ - - - - - Frequently Asked Questions (FAQ) - - - - - -

      Frequently Asked Questions (FAQ)

      - -

      Can I use 7-Zip in a commercial organization?

      -

      Yes, 7-Zip is free software. You can use it on any computer. You don't need to -register or pay for 7-Zip.

      - -

      How can I set file associations to 7-Zip in Windows 7 and Windows Vista?

      -

      You must run 7-Zip File Manager in administrator mode. -Right-click the icon of 7-Zip File Manager, and then click Run as administrator. -Then you can change file associations and some other options.

      - -

      Why 7z archives created by new version of 7-Zip can be larger than archives created by old version of 7-Zip?

      - -

      New versions of 7-Zip (starting from version 15.06) use another file sorting -order by default for solid 7z archives.

      - -

      Old version of 7-Zip (before version 15.06) used file sorting "by type" ("by extension").

      -

      New version of 7-Zip supports two sorting orders:

      -
        -
      • sorting by name - default order.
      • -
      • sorting by type, if 'qs' is specified in Parameters field in "Add to archive" window, - (or -mqs switch for command line version).
      • -
      - -

      You can get big difference in compression ratio for different sorting methods, -if dictionary size is smaller than total size of files. -If there are similar files in different folders, the sorting "by type" can provide -better compression ratio in some cases.

      - -

      Note that sorting "by type" has some drawbacks. -For example, NTFS volumes use sorting order "by name", so if an archive uses -another sorting, then the speed of some operations for files with unusual order -can fall on HDD devices (HDDs have low speed for "seek" operations).

      - -

      You can increase compression ratio with the following methods:

      -
        -
      • Increase dictionary size. It can help when 'qs' is not used.
      • -
      • Specify 'qs' in Parameters field (or use -mqs switch for command line version).
      • -
      - -

      If you think that unusual file order is not problem for you, -and if better compression ratio with small dictionary is more important for you, -use 'qs' mode.

      - -

      Why can't 7-Zip open some ZIP archives?

      -

      In 99% of these cases it means that the archive contains incorrect headers. -Other ZIP programs can open some archives with incorrect headers, since these programs -just ignore errors.

      -

      If you have such archive, please don't call the 7-Zip developers about it. -Instead try to find the program that was used to create the archive and inform the developers -of that program that their software is not ZIP-compatible.

      - -

      There are also some ZIP archives that were encoded with methods unsupported by 7-Zip, -for example, WAVPack (WinZip).

      - -

      Why does drag-and-drop archive extraction from 7-Zip to Explorer use temp files?

      -

      7-Zip doesn't know folder path of drop target. -Only Windows Explorer knows exact drop target. -And Windows Explorer needs files (drag source) as decompressed files on disk. -So 7-Zip extracts files from archive to temp folder and then -7-Zip notifies Windows Explorer about paths of these temp files. -Then Windows Explorer copies these files to drop target folder.

      - -

      To avoid temp file usage, you can use Extract command of 7-Zip or -drag-and-drop from 7-Zip to 7-Zip.

      - -

      Why doesn't the command line version add files without extensions to an archive?

      -

      You're probably using a *.* wildcard. 7-Zip doesn't use the operating system's wildcard mask parser, -and consequently treats *.* as any file that has an extension. -To process all files you must use the * wildcard instead or omit the wildcard altogether.

      - -

      Why doesn't -r switch work as expected?

      -

      In most cases you don't need -r switch. -7-Zip can compress subfolders even without -r switch.

      -

      Example 1:

      -
        7z.exe a c:\a.7z "C:\Program Files"
      -

      compresses "C:\Program Files" completely, including all subfolders.

      -

      Example 2:

      -
        7z.exe a -r c:\a.7z "C:\Program Files"
      -

      searches and compresses "Program Files" in all subfolders of C:\ (for example, in "C:\WINDOWS").

      -If you need to compress only files with some extension, you can use -r switch: -
        7z a -r c:\a.zip c:\dir\*.txt 
      -

      compresses all *.txt files from folder c:\dir\ and all it's subfolders.

      - -

      Why can't 7-Zip use big dictionary in 32-bit Windows?

      -

      32-bit Windows allocates only 2 GB of virtual space per one application. -Also that block of 2 GB can be fragmented (for example, by some DLL file), -so 7-Zip can't allocate one big contiguous block of virtual space. -There are no such limitations in 64-bit Windows. -So you can use any dictionary in Windows x64, if you have required amount of physical RAM.

      - -

      How can I install 7-Zip in silent mode?

      - -

      For exe installer: Use the "/S" parameter to do a silent installation and the "/D=dir" parameter -to specify the "output directory". These options are case-sensitive.

      - -

      For msi installer: Use the /q INSTALLDIR="C:\Program Files\7-Zip" parameters.

      - - -

      How can I recover corrupted 7z archive?

      - -

      There are some possible cases when archive is corrupted: -

        -
      • You can open archive and you can see the list of files, but when you press - Extract or Test command, there are some errors: Data Error or CRC Error. -
      • When you open archive, you get message "Can not open file 'a.7z' as archive" -
      - -

      It's possible to recover some data. Read about recovering procedure: - -

      Recover corrupted 7z archive

      - - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/formats.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/formats.htm --- p7zip-rar-16.02/DOC/MANUAL/general/formats.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/formats.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ - - - - - Supported formats - - - - - -

      Supported formats

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      FormatCreationFilename Extensions
      7z X 7z
      BZIP2 X bz2 bzip2 tbz2 tbz
      GZIP X gz gzip tgz
      TAR X tar
      WIM X wim swm
      XZ X xz txz
      ZIP X zip zipx jar xpi odt ods docx xlsx epub
      APM apm
      AR ar a deb lib
      ARJ arj
      CAB cab
      CHM chm chw chi chq
      COMPOUND msi msp doc xls ppt
      CPIO cpio
      CramFS cramfs
      DMG dmg
      Ext ext ext2 ext3 ext4 img
      FAT fat img
      HFS hfs hfsx
      HXS hxs hxi hxr hxq hxw lit
      iHEX ihex
      ISO iso img
      LZH lzh lha
      LZMA lzma
      MBR mbr
      MsLZ mslz
      Mub mub
      NSIS nsis
      NTFS ntfs img
      MBR mbr
      RAR rar r00
      RPM rpm
      PPMD ppmd
      QCOW2 qcow qcow2 qcow2c
      SPLIT 001 002 ...
      SquashFS squashfs
      UDF udf iso img
      UEFIc scap
      UEFIs uefif
      VDI vdi
      VHD vhd
      VMDK vmdk
      WIM wim esd
      XAR xar pkg
      Z z taz
      - -

      ZIP

      - -

      7-Zip creates ZIP compatible archives. -7-Zip supports the following ZIP compression methods:

      -
        -
      • 0 - Store
      • -
      • 1 - Shrink (decompression only)
      • -
      • 6 - Implode (decompression only)
      • -
      • 8 - Deflate
      • -
      • 9 - Deflate64
      • -
      • 12 - BZip2
      • -
      • 14 - LZMA
      • -
      • 95 - xz (decompression only)
      • -
      • 98 - PPMd
      • -
      • 99 - WinZip AES
      • -
      - -

      Files compressed with other ZIP compression methods -can't be extracted by the current version of the 7-Zip. -But these supported methods are the most popular today, -and therefore 7-Zip can decompress most ZIP archives. -To extract files compressed with non-supported methods you must use some -other ZIP utility.

      - -

      7-Zip supports the Zip64 extension of ZIP format.

      - -

      LZH

      - -

      7-Zip supports LZH archives only for listing, browsing and decompressing. -7-Zip supports -lh0-, -lh4-, -lh5-, -lh6- and -lh7- methods.

      - - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/index.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/index.htm --- p7zip-rar-16.02/DOC/MANUAL/general/index.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/index.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ - - - - - General Information - - - - - -

      General Information

      - -

      The main features of 7-Zip

      - - - -

      See Also

      - - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/license.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/license.htm --- p7zip-rar-16.02/DOC/MANUAL/general/license.htm 2016-05-19 13:53:29.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/license.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ - - - - - License for use and distribution - - - - - -

      License

      - -

      7-Zip Copyright (C) 1999-2016 Igor Pavlov.

      - -

      Licenses for files are:

      - -
    • 7z.dll: GNU LGPL + unRAR restriction -
    • All other files: GNU LGPL - - -

      The GNU LGPL + unRAR restriction means that you must follow both - GNU LGPL rules and unRAR restriction rules.

      - -

      Note: You can use 7-Zip on any computer, including a computer in a commercial - organization. You don't need to register or pay for 7-Zip.

      - -

      Read file License.txt for full information about license.

      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/performance.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/performance.htm --- p7zip-rar-16.02/DOC/MANUAL/general/performance.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/performance.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ - - - - - Performance - - - - - -

      Performance

      - -

      ZIP Format

      -

      Compression ratio results are very dependent upon the data used for -the tests. We compared 7-Zip with some of the leading -commercial archivers: PKZIP 2.04g, WinZip 7.0.

      - -

      FILE SET: The Canterbury Corpus (11 files totaling 2,810,784 bytes, -popular file set used to compression rates).

      - - - - - - - - - - - - - - - - - - - - - - -
      ArchiverCompressed sizeRatio
      7-Zip (zip format)676284100%
      PKZIP 2.04g -ex726047107%
      WinZip 7.0 (Max)731499108%
      - - -

      7z Format

      - -

      7z is the new archive format, providing a high compression ratio.

      - -

      FILE SET: The GIMP 1.2.4 for Windows after full installation -(127 subfolders, 1304 files totaling 27,128,826 bytes). -The GIMP is the GNU Image Manipulation Program. It can be downloaded from -www.gimp.org.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ArchiverCompressed sizeRatio
      7-Zip (7z format)5445402100%
      WinRAR 3.106004155110%
      WinAce 2.36242424115%
      CABARC 1.06455327119%
      7-Zip (zip format)9461621174%
      PKZIP 2.509842800181%
      - -

      GZIP Format

      - -

      7-Zip provides the best compression ratio for GZIP format. The compression ratio -is equal to its compression ratio for ZIP format (above).

      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/style.css --- p7zip-rar-16.02/DOC/MANUAL/general/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/MANUAL/general/thanks.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/thanks.htm --- p7zip-rar-16.02/DOC/MANUAL/general/thanks.htm 2016-05-10 09:50:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/general/thanks.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ - - - - - Thanks - - - - - -

      Thanks

      - -

      I would like to thank:

      -
        -
      • myspace from sf.net - for porting to Unix/Linux (p7zip), testing, bug fixing and more. -
      • ARJ Software - for ARJ. -
      • Eric Biggers - for LZMS description (wimlib). -
      • Wei Dai - for SHA-256 code and Crypto++ Library. -
      • Jeff Gilchrist - for compressing tests. -
      • Szymon Grabowski - for some ideas. -
      • Microsoft Corporation - for CAB/WIM formats descriptions, and WiX (Windows Installer XML). -
      • Nullsoft, Inc. and NSIS team - for NSIS (Nullsoft Scriptable Install System). -
      • Robert Martinez - 7-Zip Logo. -
      • Alexander Ratushnyak - for compressing tests. -
      • Eugene Roshal - for RAR. -
      • Matthew Russotto - for CHM/CAB format description. -
      • Julian Seward - for BZip2. -
      • Eugene Shelwien - for some ideas and algorithms. -
      • Dmitry Shkarin - for PPMd algorithm. -
      • Yoshioka Tsuneo - for TAR32 program. -
      • Vadim Yoockin - for compressing tests. -
      • Bulat Ziganshin - for some ideas. -
      • John Michael Williams - for help file corrections. -
      • Apple Inc. - for HFS. -
      • vu1tur(DMG2IMG) - for .DMG hints. -
      • Yutaka Sawada - for hints to ZIP Strong Encryption format. -
      • NTFS-3G team - for hints to NTFS. -
      • Phillip Lougher - for SquashFS. -
      • Haruyasu Yoshizaki - for LHA/LZH. -
      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/start.htm p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/start.htm --- p7zip-rar-16.02/DOC/MANUAL/start.htm 2016-05-21 08:53:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/start.htm 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ - - - - - 7-Zip Start Page - - - - - -

      7-Zip

      - -

      Welcome to 7-Zip 16.02

      -

      7-Zip is a file archiver with a high compression ratio.

      - -

      The documentation for 7-Zip includes:

      - - - -

      See Also

      - - - -
      - -

      Copyright (c) 1999-2016 Igor Pavlov

      -

      Web site: www.7-zip.org

      -

      Support: www.7-zip.org/support.html

      - - - diff -Nru p7zip-rar-16.02/DOC/MANUAL/style.css p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/style.css --- p7zip-rar-16.02/DOC/MANUAL/style.css 2015-01-03 20:33:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/MANUAL/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -body - { - padding: 0px 0px 0px 26px; - background: #ffffff; - color: #000000; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 80%; - } - -div - { - width: 90%; - border: 2px solid #999999; - padding: 4px 8px; - background: #cccccc; - } - -h1, h2, h3, h4 - { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: -26px; - } - -h1 - { - font-size: 145%; - margin-top: .5em; - margin-bottom: 1em; - } - -h2 - { - font-size: 130%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h3 - { - font-size: 115%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -h4 - { - font-size: 100%; - margin-top: 1.5em; - margin-bottom: .6em; - } - -ul p, ol p, dl p - { - margin-left: 0em; - } - -p - { - margin-top: .6em; - margin-bottom: .6em; - } - -dl - { - /*margin-top: 0em; */ - } - -dt - { - margin-top: .76em; - margin-bottom: .5em; - font-weight: bold; - } - -dd - { - margin-top: .5em; - margin-bottom: .5em; - margin-left: 1.9em; - } - - -ul, ol - { - margin-top: .6em; - margin-bottom: 0em; - } - -ol - { - margin-left: 3.6em; - } - -ul - { - list-style-type: disc; - margin-left: 1.9em; - } - -li - { - margin-bottom: .6em; - } - -ul ol, ol ol - { - list-style-type: lower-alpha; - { - - /* -pre - { - margin-top: .6em; - margin-bottom: .6em; - } - */ - -pre,code - { - font: 100% Courier New, Courier, mono; - color: #000000; - cursor: text; - } - -pre.syntax - { - background: #dddddd; - padding: 2pt,4pt - } - -pre.syntax - { - color: #000000; - } - -pre.example - { - margin-left: 2.0em; - /*margin-top: 12.0em;*/ - /*margin-bottom: 1.0em;*/ - color: #C00000; - /*padding: 10pt,20pt*/ - } - -table - { - /* width: 90%; */ - background: #999999; - margin-top: .6em; - margin-bottom: .3em; - } - -th - { - padding: 4px 8px; - background: #cccccc; - text-align: left; - font-size: 80%; - vertical-align: bottom; - } - -th.cc - { - text-align: center; - vertical-align: middle; - } - -td - { - padding: 4px 8px; - background: #ffffff; - vertical-align: top; - font-size: 80%; - } - -td.cc - { - text-align: center; - vertical-align: middle; - } - - -blockquote - { - margin-left: 3.8em; - margin-right: 3.8em; - margin-top: .6em; - margin-bottom: .6em; - } - -a:link - { - color: #0066ff; - } - -a:visited - { - color: #996600; - } - -a:hover - { - color: #cc9900; - } - -a.parameter:link - { - color: #0066ff; - text-decoration:none; - } - -a.parameter:visited - { - text-decoration:none; - } - -div.footer - { - width: 100%; - border: none; - background: #ffffff; - margin-top: 18pt; - padding-bottom: 12pt; - color: #228B22; - text-align: center; - font-size: 70%; - } - -span.filename -{ - color: #F00000; -} diff -Nru p7zip-rar-16.02/DOC/Methods.txt p7zip-rar-16.02+really25.00+ds/DOC/Methods.txt --- p7zip-rar-16.02/DOC/Methods.txt 2015-09-01 18:04:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/Methods.txt 2024-03-22 11:56:07.000000000 +0000 @@ -1,158 +1,177 @@ -7-Zip method IDs for 7z and xz archives ---------------------------------------- - -Version: 15.06 -Date: 2015-06-23 - -Each compression or crypto method in 7z is associated with unique binary value (ID). -The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes). - -xz and 7z formats use same ID map. - -If you want to add some new ID, you have two ways: - 1) Write request for allocating IDs to 7-Zip developers. - 2) Generate 8-bytes ID: - - 3F ZZ ZZ ZZ ZZ ZZ MM MM - - 3F - Prefix for random IDs (1 byte) - ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes. - - MM MM - Method ID (2 bytes) - - You can notify 7-Zip developers about your Developer ID / Method ID. - - Note: Use new ID, if old codec can not decode data encoded with new version. - - -List of defined IDs -------------------- - -00 - Copy - -03 - Delta -04 - BCJ (x86) -05 - PPC (big-endian) -06 - IA64 -07 - ARM (little-endian) -08 - ARMT (little-endian) -09 - SPARC - -21 - LZMA2 - -02.. - Common - 03 [Swap] - - 2 Swap2 - - 4 Swap4 - -03.. - 7z - 01 - - 01 - LZMA - - 03 - [Branch Codecs] - 01 - [x86 Codecs] - 03 - BCJ - 1B - BCJ2 (4 packed streams) - 02 - - 05 - PPC (big-endian) - 03 - - 01 - Alpha - 04 - - 01 - IA64 - 05 - - 01 - ARM (little-endian) - 06 - - 05 - M68 (big-endian) - 07 - - 01 - ARMT (little-endian) - 08 - - 05 - SPARC - - 04 - - 01 - PPMD - - 7F - - 01 - experimental method. - - -04.. - Misc codecs - - 00 - Reserved - - 01 - [Zip] - 00 - Copy (not used. Use {00} instead) - 01 - Shrink - 06 - Implode - 08 - Deflate - 09 - Deflate64 - 0A - Imploding - 0C - BZip2 (not used. Use {040202} instead) - 0E - LZMA (LZMA-zip) - 5F - xz - 60 - Jpeg - 61 - WavPack - 62 - PPMd (PPMd-zip) - 63 - wzAES - - 02 - - 02 - BZip2 - - 03 - [Rar] - 01 - Rar1 - 02 - Rar2 - 03 - Rar3 - 05 - Rar5 - - 04 - [Arj] - 01 - Arj(1,2,3) - 02 - Arj4 - - 05 - [Z] - - 06 - [Lzh] - - 07 - Reserved for 7z - - 08 - [Cab] - - 09 - [NSIS] - 01 - DeflateNSIS - 02 - BZip2NSIS - - F7 - External codecs (that are not included to 7-Zip) - - 0x xx - reserved - 10 xx - reserved - - -06.. - Crypto - - F0 - Ciphers without hashing algo - - 01 - [AES] - 0x - AES-128 - 4x - AES-192 - 8x - AES-256 - Cx - AES - - x0 - ECB - x1 - CBC - x2 - CFB - x3 - OFB - x4 - CTR - - F1 - Combine Ciphers - - 01 - [Zip] - 01 - ZipCrypto (Main Zip crypto algo) - - 03 - [RAR] - 02 - - 03 - Rar29AES (AES-128 + modified SHA-1) - - 07 - [7z] - 01 - 7zAES (AES-256 + SHA-256) - - ---- -End of document +7-Zip method IDs for 7z and xz archives +--------------------------------------- + +Version: 24.02 +Date: 2024-03-22 + +Each compression or crypto method in 7z is associated with unique binary value (ID). +The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes). + +xz and 7z formats use same ID map. + +If you want to add some new ID, you have two ways: + 1) Write request for allocating IDs to 7-Zip developers. + 2) Generate 8-bytes ID: + + 3F ZZ ZZ ZZ ZZ ZZ MM MM + + 3F - Prefix for random IDs (1 byte) + ZZ ZZ ZZ ZZ ZZ - Developer ID (5 bytes). Use real random bytes. + + MM MM - Method ID (2 bytes) + + You can notify 7-Zip developers about your Developer ID / Method ID. + + Note: Use new ID, if old codec can not decode data encoded with new version. + + +List of defined IDs +------------------- + +00 - Copy + +03 - Delta +04 - BCJ (x86) +05 - PPC (big-endian) +06 - IA64 +07 - ARM (little-endian) +08 - ARMT (little-endian) +09 - SPARC +0A - ARM64 +0B - RISCV + +21 - LZMA2 + +02.. - Common + 03 [Swap] + - 2 Swap2 + - 4 Swap4 + +03.. - 7z + 01 - + 01 - LZMA + + 03 - [Branch Codecs] + 01 - [x86 Codecs] + 03 - BCJ + 1B - BCJ2 (4 packed streams) + 02 - + 05 - PPC (big-endian) + 03 - + 01 - Alpha + 04 - + 01 - IA64 + 05 - + 01 - ARM (little-endian) + 06 - + 05 - M68 (big-endian) + 07 - + 01 - ARMT (little-endian) + 08 - + 05 - SPARC + + 04 - + 01 - PPMD + + 7F - + 01 - experimental method. + + +04.. - Misc codecs + + 00 - Reserved + + 01 - [Zip] + 00 - Copy (not used. Use {00} instead) + 01 - Shrink + 06 - Implode + 08 - Deflate + 09 - Deflate64 + 0A - Imploding + 0C - BZip2 (not used. Use {040202} instead) + 0E - LZMA (LZMA-zip) + + 5D - ZSTD + 5F - xz + 60 - Jpeg + 61 - WavPack + 62 - PPMd (PPMd-zip) + 63 - wzAES + + 02 - + 02 - BZip2 + + 03 - [Rar] + 01 - Rar1 + 02 - Rar2 + 03 - Rar3 + 05 - Rar5 + + 04 - [Arj] + 01 - Arj(1,2,3) + 02 - Arj4 + + 05 - [Z] + + 06 - [Lzh] + + 07 - Reserved for 7z + + 08 - [Cab] + + 09 - [NSIS] + 01 - DeflateNSIS + 02 - BZip2NSIS + + F7 - External codecs (that are not included to 7-Zip) + + 0x xx - reserved + + 10 xx - reserved (LZHAM) + 01 - LZHAM + + 11 xx - reserved (Tino Reichardt) + 01 - ZSTD + 02 - BROTLI + 04 - LZ4 + 05 - LZ5 + 06 - LIZARD + + 12 xx - reserverd (Denis Anisimov) + + 01 - WavPack2 + FE - eSplitter + FF - RawSplitter + + +06.. - Crypto + + F0 - Ciphers without hashing algo + + 01 - [AES] + 0x - AES-128 + 4x - AES-192 + 8x - AES-256 + Cx - AES + + x0 - ECB + x1 - CBC + x2 - CFB + x3 - OFB + x4 - CTR + + F1 - Combine Ciphers + + 01 - [Zip] + 01 - ZipCrypto (Main Zip crypto algo) + + 03 - [RAR] + 02 - + 03 - Rar29AES (AES-128 + modified SHA-1) + + 07 - [7z] + 01 - 7zAES (AES-256 + SHA-256) + + +--- +End of document diff -Nru p7zip-rar-16.02/DOC/copying.txt p7zip-rar-16.02+really25.00+ds/DOC/copying.txt --- p7zip-rar-16.02/DOC/copying.txt 2016-03-02 05:57:39.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/copying.txt 2016-01-22 05:55:48.000000000 +0000 @@ -1,502 +1,502 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff -Nru p7zip-rar-16.02/DOC/lzma.txt p7zip-rar-16.02+really25.00+ds/DOC/lzma.txt --- p7zip-rar-16.02/DOC/lzma.txt 2014-12-21 12:44:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/lzma.txt 2024-06-18 10:00:00.000000000 +0000 @@ -1,328 +1,345 @@ -LZMA compression ----------------- -Version: 9.35 - -This file describes LZMA encoding and decoding functions written in C language. - -LZMA is an improved version of famous LZ77 compression algorithm. -It was improved in way of maximum increasing of compression ratio, -keeping high decompression speed and low memory requirements for -decompressing. - -Note: you can read also LZMA Specification (lzma-specification.txt from LZMA SDK) - -Also you can look source code for LZMA encoding and decoding: - C/Util/Lzma/LzmaUtil.c - - -LZMA compressed file format ---------------------------- -Offset Size Description - 0 1 Special LZMA properties (lc,lp, pb in encoded form) - 1 4 Dictionary size (little endian) - 5 8 Uncompressed size (little endian). -1 means unknown size - 13 Compressed data - - - -ANSI-C LZMA Decoder -~~~~~~~~~~~~~~~~~~~ - -Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58. -If you want to use old interfaces you can download previous version of LZMA SDK -from sourceforge.net site. - -To use ANSI-C LZMA Decoder you need the following files: -1) LzmaDec.h + LzmaDec.c + Types.h - -Look example code: - C/Util/Lzma/LzmaUtil.c - - -Memory requirements for LZMA decoding -------------------------------------- - -Stack usage of LZMA decoding function for local variables is not -larger than 200-400 bytes. - -LZMA Decoder uses dictionary buffer and internal state structure. -Internal state structure consumes - state_size = (4 + (1.5 << (lc + lp))) KB -by default (lc=3, lp=0), state_size = 16 KB. - - -How To decompress data ----------------------- - -LZMA Decoder (ANSI-C version) now supports 2 interfaces: -1) Single-call Decompressing -2) Multi-call State Decompressing (zlib-like interface) - -You must use external allocator: -Example: -void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } -void SzFree(void *p, void *address) { p = p; free(address); } -ISzAlloc alloc = { SzAlloc, SzFree }; - -You can use p = p; operator to disable compiler warnings. - - -Single-call Decompressing -------------------------- -When to use: RAM->RAM decompressing -Compile files: LzmaDec.h + LzmaDec.c + Types.h -Compile defines: no defines -Memory Requirements: - - Input buffer: compressed size - - Output buffer: uncompressed size - - LZMA Internal Structures: state_size (16 KB for default settings) - -Interface: - int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, - const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); - In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size - propData - LZMA properties (5 bytes) - propSize - size of propData buffer (5 bytes) - finishMode - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). - You can use LZMA_FINISH_END, when you know that - current output buffer covers last bytes of stream. - alloc - Memory allocator. - - Out: - destLen - processed output size - srcLen - processed input size - - Output: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). - - If LZMA decoder sees end_marker before reaching output limit, it returns OK result, - and output value of destLen will be less than output buffer size limit. - - You can use multiple checks to test data integrity after full decompression: - 1) Check Result and "status" variable. - 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. - 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. - You must use correct finish mode in that case. */ - - -Multi-call State Decompressing (zlib-like interface) ----------------------------------------------------- - -When to use: file->file decompressing -Compile files: LzmaDec.h + LzmaDec.c + Types.h - -Memory Requirements: - - Buffer for input stream: any size (for example, 16 KB) - - Buffer for output stream: any size (for example, 16 KB) - - LZMA Internal Structures: state_size (16 KB for default settings) - - LZMA dictionary (dictionary size is encoded in LZMA properties header) - -1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header: - unsigned char header[LZMA_PROPS_SIZE + 8]; - ReadFile(inFile, header, sizeof(header) - -2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties - - CLzmaDec state; - LzmaDec_Constr(&state); - res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); - if (res != SZ_OK) - return res; - -3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop - - LzmaDec_Init(&state); - for (;;) - { - ... - int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); - ... - } - - -4) Free all allocated structures - LzmaDec_Free(&state, &g_Alloc); - -Look example code: - C/Util/Lzma/LzmaUtil.c - - -How To compress data --------------------- - -Compile files: - Types.h - Threads.h - LzmaEnc.h - LzmaEnc.c - LzFind.h - LzFind.c - LzFindMt.h - LzFindMt.c - LzHash.h - -Memory Requirements: - - (dictSize * 11.5 + 6 MB) + state_size - -Lzma Encoder can use two memory allocators: -1) alloc - for small arrays. -2) allocBig - for big arrays. - -For example, you can use Large RAM Pages (2 MB) in allocBig allocator for -better compression speed. Note that Windows has bad implementation for -Large RAM Pages. -It's OK to use same allocator for alloc and allocBig. - - -Single-call Compression with callbacks --------------------------------------- - -Look example code: - C/Util/Lzma/LzmaUtil.c - -When to use: file->file compressing - -1) you must implement callback structures for interfaces: -ISeqInStream -ISeqOutStream -ICompressProgress -ISzAlloc - -static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } -static void SzFree(void *p, void *address) { p = p; MyFree(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - - CFileSeqInStream inStream; - CFileSeqOutStream outStream; - - inStream.funcTable.Read = MyRead; - inStream.file = inFile; - outStream.funcTable.Write = MyWrite; - outStream.file = outFile; - - -2) Create CLzmaEncHandle object; - - CLzmaEncHandle enc; - - enc = LzmaEnc_Create(&g_Alloc); - if (enc == 0) - return SZ_ERROR_MEM; - - -3) initialize CLzmaEncProps properties; - - LzmaEncProps_Init(&props); - - Then you can change some properties in that structure. - -4) Send LZMA properties to LZMA Encoder - - res = LzmaEnc_SetProps(enc, &props); - -5) Write encoded properties to header - - Byte header[LZMA_PROPS_SIZE + 8]; - size_t headerSize = LZMA_PROPS_SIZE; - UInt64 fileSize; - int i; - - res = LzmaEnc_WriteProperties(enc, header, &headerSize); - fileSize = MyGetFileLength(inFile); - for (i = 0; i < 8; i++) - header[headerSize++] = (Byte)(fileSize >> (8 * i)); - MyWriteFileAndCheck(outFile, header, headerSize) - -6) Call encoding function: - res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, - NULL, &g_Alloc, &g_Alloc); - -7) Destroy LZMA Encoder Object - LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); - - -If callback function return some error code, LzmaEnc_Encode also returns that code -or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. - - -Single-call RAM->RAM Compression --------------------------------- - -Single-call RAM->RAM Compression is similar to Compression with callbacks, -but you provide pointers to buffers instead of pointers to stream callbacks: - -SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); - -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) - - - -Defines -------- - -_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. - -_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for - some structures will be doubled in that case. - -_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit. - -_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type. - - -_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder. - - -C++ LZMA Encoder/Decoder -~~~~~~~~~~~~~~~~~~~~~~~~ -C++ LZMA code use COM-like interfaces. So if you want to use it, -you can study basics of COM/OLE. -C++ LZMA code is just wrapper over ANSI-C code. - - -C++ Notes -~~~~~~~~~~~~~~~~~~~~~~~~ -If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling), -you must check that you correctly work with "new" operator. -7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator. -So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator: -operator new(size_t size) -{ - void *p = ::malloc(size); - if (p == 0) - throw CNewException(); - return p; -} -If you use MSCV that throws exception for "new" operator, you can compile without -"NewHandler.cpp". So standard exception will be used. Actually some code of -7-Zip catches any exception in internal code and converts it to HRESULT code. -So you don't need to catch CNewException, if you call COM interfaces of 7-Zip. - ---- - -http://www.7-zip.org -http://www.7-zip.org/sdk.html -http://www.7-zip.org/support.html +LZMA compression +---------------- +Version: 24.07 + +This file describes LZMA encoding and decoding functions written in C language. + +LZMA is an improved version of famous LZ77 compression algorithm. +It was improved in way of maximum increasing of compression ratio, +keeping high decompression speed and low memory requirements for +decompressing. + +Note: you can read also LZMA Specification (lzma-specification.txt from LZMA SDK) + +Also you can look source code for LZMA encoding and decoding: + C/Util/Lzma/LzmaUtil.c + + +LZMA compressed file format +--------------------------- +Offset Size Description + 0 1 Special LZMA properties (lc,lp, pb in encoded form) + 1 4 Dictionary size (little endian) + 5 8 Uncompressed size (little endian). -1 means unknown size + 13 Compressed data + + + +ANSI-C LZMA Decoder +~~~~~~~~~~~~~~~~~~~ + +Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58. +If you want to use old interfaces you can download previous version of LZMA SDK +from sourceforge.net site. + +To use ANSI-C LZMA Decoder you need the following files: +1) LzmaDec.h + LzmaDec.c + 7zTypes.h + Precomp.h + Compiler.h + +Look example code: + C/Util/Lzma/LzmaUtil.c + + +Memory requirements for LZMA decoding +------------------------------------- + +Stack usage of LZMA decoding function for local variables is not +larger than 200-400 bytes. + +LZMA Decoder uses dictionary buffer and internal state structure. +Internal state structure consumes + state_size = (4 + (1.5 << (lc + lp))) KB +by default (lc=3, lp=0), state_size = 16 KB. + + +How To decompress data +---------------------- + +LZMA Decoder (ANSI-C version) now supports 2 interfaces: +1) Single-call Decompressing +2) Multi-call State Decompressing (zlib-like interface) + +You must use external allocator: +Example: +void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } +void SzFree(void *p, void *address) { p = p; free(address); } +ISzAlloc alloc = { SzAlloc, SzFree }; + +You can use p = p; operator to disable compiler warnings. + + +Single-call Decompressing +------------------------- +When to use: RAM->RAM decompressing +Compile files: LzmaDec.h + LzmaDec.c + 7zTypes.h +Compile defines: no defines +Memory Requirements: + - Input buffer: compressed size + - Output buffer: uncompressed size + - LZMA Internal Structures: state_size (16 KB for default settings) + +Interface: + int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + propData - LZMA properties (5 bytes) + propSize - size of propData buffer (5 bytes) + finishMode - It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + You can use LZMA_FINISH_END, when you know that + current output buffer covers last bytes of stream. + alloc - Memory allocator. + + Out: + destLen - processed output size + srcLen - processed input size + + Output: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + + If LZMA decoder sees end_marker before reaching output limit, it returns OK result, + and output value of destLen will be less than output buffer size limit. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + + +Multi-call State Decompressing (zlib-like interface) +---------------------------------------------------- + +When to use: file->file decompressing +Compile files: LzmaDec.h + LzmaDec.c + 7zTypes.h + +Memory Requirements: + - Buffer for input stream: any size (for example, 16 KB) + - Buffer for output stream: any size (for example, 16 KB) + - LZMA Internal Structures: state_size (16 KB for default settings) + - LZMA dictionary (dictionary size is encoded in LZMA properties header) + +1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header: + unsigned char header[LZMA_PROPS_SIZE + 8]; + ReadFile(inFile, header, sizeof(header) + +2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties + + CLzmaDec state; + LzmaDec_Constr(&state); + res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); + if (res != SZ_OK) + return res; + +3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop + + LzmaDec_Init(&state); + for (;;) + { + ... + int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); + ... + } + + +4) Free all allocated structures + LzmaDec_Free(&state, &g_Alloc); + +Look example code: + C/Util/Lzma/LzmaUtil.c + + +How To compress data +-------------------- + +Compile files: + 7zTypes.h + Threads.h + Threads.c + LzmaEnc.h + LzmaEnc.c + LzFind.h + LzFind.c + LzFindMt.h + LzFindMt.c + LzFindOpt.c + LzHash.h + +Memory Requirements: + - (dictSize * 11.5 + 6 MB) + state_size + +Lzma Encoder can use two memory allocators: +1) alloc - for small arrays. +2) allocBig - for big arrays. + +For example, you can use Large RAM Pages (2 MB) in allocBig allocator for +better compression speed. Note that Windows has bad implementation for +Large RAM Pages. +It's OK to use same allocator for alloc and allocBig. + + +Single-call Compression with callbacks +-------------------------------------- + +Look example code: + C/Util/Lzma/LzmaUtil.c + +When to use: file->file compressing + +1) you must implement callback structures for interfaces: +ISeqInStream +ISeqOutStream +ICompressProgress +ISzAlloc + +static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } +static void SzFree(void *p, void *address) { p = p; MyFree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + + CFileSeqInStream inStream; + CFileSeqOutStream outStream; + + inStream.funcTable.Read = MyRead; + inStream.file = inFile; + outStream.funcTable.Write = MyWrite; + outStream.file = outFile; + + +2) Create CLzmaEncHandle object; + + CLzmaEncHandle enc; + + enc = LzmaEnc_Create(&g_Alloc); + if (enc == 0) + return SZ_ERROR_MEM; + + +3) initialize CLzmaEncProps properties; + + LzmaEncProps_Init(&props); + + Then you can change some properties in that structure. + +4) Send LZMA properties to LZMA Encoder + + res = LzmaEnc_SetProps(enc, &props); + +5) Write encoded properties to header + + Byte header[LZMA_PROPS_SIZE + 8]; + size_t headerSize = LZMA_PROPS_SIZE; + UInt64 fileSize; + int i; + + res = LzmaEnc_WriteProperties(enc, header, &headerSize); + fileSize = MyGetFileLength(inFile); + for (i = 0; i < 8; i++) + header[headerSize++] = (Byte)(fileSize >> (8 * i)); + MyWriteFileAndCheck(outFile, header, headerSize) + +6) Call encoding function: + res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, + NULL, &g_Alloc, &g_Alloc); + +7) Destroy LZMA Encoder Object + LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); + + +If callback function return some error code, LzmaEnc_Encode also returns that code +or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. + + +Single-call RAM->RAM Compression +-------------------------------- + +Single-call RAM->RAM Compression is similar to Compression with callbacks, +but you provide pointers to buffers instead of pointers to stream callbacks: + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) + + + +Defines +------- + +Z7_LZMA_SIZE_OPT - Enable some code size optimizations in LZMA Decoder to get smaller executable code. + +Z7_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for + some structures will be doubled in that case. + +Z7_DECL_Int32_AS_long - Define it if int is 16-bit on your compiler and long is 32-bit. + +Z7_DECL_SizeT_AS_unsigned_int - Define it if you don't want to use size_t type. + + +Defines for 7z decoder written in C +----------------------------------- +These defines are for 7zDec.c only (the decoder in C). +C++ 7z decoder doesn't uses these macros. + +Z7_PPMD_SUPPORT - define it if you need PPMD method support. +Z7_NO_METHODS_FILTERS - do not use filters (except of BCJ2 filter). +Z7_USE_NATIVE_BRANCH_FILTER - use filter for native ISA: + use x86 filter, if compiled to x86 executable, + use arm64 filter, if compiled to arm64 executable. + + +C++ LZMA Encoder/Decoder +~~~~~~~~~~~~~~~~~~~~~~~~ +C++ LZMA code use COM-like interfaces. So if you want to use it, +you can study basics of COM/OLE. +C++ LZMA code is just wrapper over ANSI-C code. + + +C++ Notes +~~~~~~~~~~~~~~~~~~~~~~~~ +If you use some C++ code folders in 7-Zip (for example, C++ code for 7z archive handling), +you must check that you correctly work with "new" operator. +7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator. +So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator, +if compiled by old MSVC compilers (MSVC before version VS 2010): + +operator new(size_t size) +{ + void *p = ::malloc(size); + if (!p) + throw CNewException(); + return p; +} + +If the compiler is VS 2010 or newer, NewHandler.cpp doesn't redefine "new" operator. +Sp if you use new compiler (VS 2010 or newer), you still can include "NewHandler.cpp" +to compilation, and it will not redefine operator new. +Also you can compile without "NewHandler.cpp" with new compilers. +If 7-zip doesn't redefine operator "new", standard exception will be used instead of CNewException. +Some code of 7-Zip catches any exception in internal code and converts it to HRESULT code. +So you don't need to catch CNewException, if you call COM interfaces of 7-Zip. + +--- + +http://www.7-zip.org +http://www.7-zip.org/sdk.html +http://www.7-zip.org/support.html diff -Nru p7zip-rar-16.02/DOC/readme.txt p7zip-rar-16.02+really25.00+ds/DOC/readme.txt --- p7zip-rar-16.02/DOC/readme.txt 2016-06-11 08:08:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/readme.txt 2025-07-05 13:00:00.000000000 +0000 @@ -1,158 +1,299 @@ -7-Zip 16.02 Sources -------------------- - -7-Zip is a file archiver for Windows. - -7-Zip Copyright (C) 1999-2016 Igor Pavlov. - - -License Info ------------- - -7-Zip is free software distributed under the GNU LGPL -(except for unRar code). -read License.txt for more infomation about license. - -Notes about unRAR license: - -Please check main restriction from unRar license: - - 2. The unRAR sources may be used in any software to handle RAR - archives without limitations free of charge, but cannot be used - to re-create the RAR compression algorithm, which is proprietary. - Distribution of modified unRAR sources in separate form or as a - part of other software is permitted, provided that it is clearly - stated in the documentation and source comments that the code may - not be used to develop a RAR (WinRAR) compatible archiver. - -In brief it means: -1) You can compile and use compiled files under GNU LGPL rules, since - unRAR license almost has no restrictions for compiled files. - You can link these compiled files to LGPL programs. -2) You can fix bugs in source code and use compiled fixed version. -3) You can not use unRAR sources to re-create the RAR compression algorithm. - - -LZMA SDK --------- - -This package also contains some files from LZMA SDK -You can download LZMA SDK from: - http://www.7-zip.org/sdk.html -LZMA SDK is written and placed in the public domain by Igor Pavlov. - - -How to compile --------------- -To compile sources you need Visual C++ 6.0. -For compiling some files you also need -new Platform SDK from Microsoft' Site: -http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm -or -http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm -or -http://www.microsoft.com/msdownload/platformsdk/sdkupdate/ - -If you use MSVC6, specify SDK directories at top of directories lists: -Tools / Options / Directories - - Include files - - Library files - - -To compile 7-Zip for AMD64 and IA64 you need: - Windows Server 2003 SP1 Platform SDK from microsoft.com - -Also you need Microsoft Macro Assembler: - - ml.exe for x86 - - ml64.exe for AMD64 -You can use ml.exe from Windows SDK for Windows Vista or some other version. - - -Compiling under Unix/Linux --------------------------- -Check this site for Posix/Linux version: -http://sourceforge.net/projects/p7zip/ - - -Notes: ------- -7-Zip consists of COM modules (DLL files). -But 7-Zip doesn't use standard COM interfaces for creating objects. -Look at -7zip\UI\Client7z folder for example of using DLL files of 7-Zip. -Some DLL files can use other DLL files from 7-Zip. -If you don't like it, you must use standalone version of DLL. -To compile standalone version of DLL you must include all used parts -to project and define some defs. -For example, 7zip\Bundles\Format7z is a standalone version of 7z.dll -that works with 7z format. So you can use such DLL in your project -without additional DLL files. - - -Description of 7-Zip sources package -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -DOC Documentation ---- - 7zFormat.txt - 7z format description - copying.txt - GNU LGPL license - unRarLicense.txt - License for unRAR part of source code - src-history.txt - Sources history - Methods.txt - Compression method IDs - readme.txt - Readme file - lzma.txt - LZMA compression description - 7zip.nsi - installer script for NSIS - 7zip.wix - installer script for WIX - - -Asm - Source code in Assembler (optimized code for CRC calculation and Intel-AES encryption) - -C - Source code in C - -CPP - Source code in C++ - -Common common files for C++ projects - -Windows common files for Windows related code - -7zip - - Common Common modules for 7-zip - - Archive files related to archiving - - Bundle Modules that are bundles of other modules (files) - - Alone 7za.exe: Standalone version of 7-Zip console that supports only 7z/xz/cab/zip/gzip/bzip2/tar. - Alone7z 7zr.exe: Standalone version of 7-Zip console that supports only 7z (reduced version) - Fm Standalone version of 7-Zip File Manager - Format7z 7za.dll: .7z support - Format7zExtract 7zxa.dll: .7z support, extracting only - Format7zR 7zr.dll: .7z support, reduced version - Format7zExtractR 7zxr.dll: .7z support, reduced version, extracting only - Format7zF 7z.dll: all formats - LzmaCon lzma.exe: LZMA compression/decompression - SFXCon 7zCon.sfx: Console 7z SFX module - SFXWin 7z.sfx: Windows 7z SFX module - SFXSetup 7zS.sfx: Windows 7z SFX module for Installers - - Compress files for compression/decompression - - Crypto files for encryption / decompression - - UI - - Agent Intermediary modules for FAR plugin and Explorer plugin - Client7z Test application for 7za.dll - Common Common UI files - Console 7z.exe : Console version - Explorer 7-zip.dll: 7-Zip Shell extension - Far plugin for Far Manager - FileManager 7zFM.exe: 7-Zip File Manager - GUI 7zG.exe: 7-Zip GUI version - - - ---- -Igor Pavlov -http://www.7-zip.org +7-Zip 25.00 Sources +------------------- + +7-Zip is a file archiver for Windows. + +7-Zip Copyright (C) 1999-2025 Igor Pavlov. + + +License Info +------------ + +7-Zip is free software distributed under the GNU LGPL +(except for unRar code). Also some code +is licensed under the "BSD 3-clause License". +Read "License.txt" for more infomation about license. + +Notes about unRAR license: + +Please check main restriction from unRar license: + + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + +In brief it means: +1) You can compile and use compiled files under GNU LGPL rules, since + unRAR license almost has no restrictions for compiled files. + You can link these compiled files to LGPL programs. +2) You can fix bugs in source code and use compiled fixed version. +3) You can not use unRAR sources to re-create the RAR compression algorithm. + + +LZMA SDK +-------- + +This package also contains some files from LZMA SDK +You can download LZMA SDK from: + http://www.7-zip.org/sdk.html +LZMA SDK is written and placed in the public domain by Igor Pavlov. + + +How to compile in Windows +------------------------- + +To compile the sources to Windows binaries you need Visual Studio compiler and/or Windows SDK. +You can use latest Windows Studio 2017/2019/2022 to compile binaries for x86, x64, arm64 and arm platforms. +Also you can use old compilers for some platforms: + x86 : Visual C++ 6.0 with Platform SDK + x64 : Windows Server 2003 R2 Platform SDK + ia64 (itanium) : Windows Server 2003 R2 Platform SDK + arm for Windows CE : Standard SDK for Windows CE 5.0 + +If you use MSVC6, specify also Platform SDK directories at top of directories lists: +Tools / Options / Directories + - Include files + - Library files + +Also you need Microsoft Macro Assembler: + - ml.exe for x86 + - ml64.exe for x64 +You can use ml.exe from Windows SDK for Windows Vista or some later versions. + +There are two ways to compile 7-Zip binaries: +1) via makefile in command line. +2) via dsp file in Visual Studio. + +The dsp file compiling can be used for development and debug purposes. +All final 7-Zip binaries are compiled via makefiles, that provide best +optimization options. + + +How to compile with makefile in Windows +--------------------------------------- + +Some macronames can be defined for compiling with makefile: + +PLATFORM + with possible values: x64, x86, arm64, arm, ia64 + +OLD_COMPILER + for old VC compiler, like MSCV 6.0. + +MY_DYNAMIC_LINK + for dynamic linking to the run-time library (msvcrt.dll). + The default makefile option is static linking to the run-time library. + +To compile all 7-Zip files for x64 with Visual Studio 2022, +use the following command sequence: + + cd SRC\CPP\7zip + %comspec% /k "C:\Program Files\VS2022\VC\Auxiliary\Build\vcvars64.bat" + nmake + +You can use another "vcvars*.bat" files from "VS2022\VC\Auxiliary\Build" directory +to compile for other platforms: + vcvars64.bat + vcvarsamd64_arm64.bat + vcvarsamd64_x86.bat + +Also you can compile single binary from directory with related project. +For example, to compile 7za.exe, use the following command sequence: + cd SRC\CPP\7zip\Bundles\Alone\ + nmake + + +Compiling 7-Zip for Unix/Linux +------------------------------ + +There are several options to compile 7-Zip with different compilers: gcc and clang. +Also 7-Zip code contains two versions for some parts of code: in C and in Assembeler. +So if you compile the version with Assembeler code, you will get faster 7-Zip binary. + +7-Zip's assembler code uses the following syntax for different platforms: + +1) x86 and x86-64 (AMD64): MASM syntax. + Now there are 3 programs that supports MASM syntax in Linux. +' 'Asmc Macro Assembler, JWasm, and UASM. Note that JWasm now doesn't support some + cpu instructions used in 7-Zip. + So you must install Asmc Macro Assembler in Linux or UASM, if you want to compile + fastest version of 7-Zip x86 and x86-64: + https://github.com/nidud/asmc + https://github.com/Terraspace/UASM + + +2) arm64: GNU assembler for ARM64 with preprocessor. + That systax is supported by GCC and CLANG for ARM64. + +There are different binaries that can be compiled from 7-Zip source. +There are 2 main files in folder for compiling: + makefile - that can be used for compiling Windows version of 7-Zip with nmake command + makefile.gcc - that can be used for compiling Linux/macOS versions of 7-Zip or Windows version + with MINGW (GCC) with make command. + +At first you must change the current folder to folder that contains `makefile.gcc`: + + cd CPP/7zip/Bundles/Alone2 + +Then you can compile `makefile.gcc` with the command: + + make -j -f makefile.gcc + +Also there are additional "*.mak" files in folder "CPP/7zip/" that can be used to compile +7-Zip binaries with optimized code and optimzing options. + +To compile with GCC without assembler: + cd CPP/7zip/Bundles/Alone2 + make -j -f ../../cmpl_gcc.mak + +To compile with CLANG without assembler: + make -j -f ../../cmpl_clang.mak + +To compile 7-Zip for x86-64 with asmc assembler: + make -j -f ../../cmpl_gcc_x64.mak + +To compile 7-Zip for arm64 with assembler: + make -j -f ../../cmpl_gcc_arm64.mak + +To compile 7-Zip for arm64 for macOS: + make -j -f ../../cmpl_mac_arm64.mak + +Also you can change some compiler options in the "mak" files: + cmpl_gcc.mak + var_gcc.mak + warn_gcc.mak + +makefile.gcc supports some variables that can change compile options + +USE_JWASM=1 + use JWasm assembler instead of Asmc. + Note that JWasm doesn't support AES instructions. So AES code from C version AesOpt.c + will be used instead of assembler code from AesOpt.asm. + +If you want to use UASM for x86-64 compiling, you can change 7zip_gcc.mak, +or send IS_X64=1 USE_ASM=1 MY_ASM="$UASM" to make command calling: + UASM="$PWD/GccUnixR/uasm" + cd "7zip-src/CPP/7zip/Bundles/Alone2" + make -f makefile.gcc -j IS_X64=1 USE_ASM=1 MY_ASM="$UASM" + + +DISABLE_RAR=1 + removes whole RAR related code from compilation. + +DISABLE_RAR_COMPRESS=1 + removes "not fully free" code of RAR decompression codecs from compilation. + +RAR decompression codecs in 7-Zip code has some additional license restrictions, +that can be treated as not fully compatible with free-software licenses. +DISABLE_RAR_COMPRESS=1 allows to exclude such "not-fully-free" RAR code from compilation. +if DISABLE_RAR_COMPRESS=1 is specified, 7-zip will not be able to decompress files +from rar archives, but 7-zip still will be able to open rar archives to get list of +files or to extract files that are stored without compression. +if DISABLE_RAR=1 is specified, 7-zip will not be able to work with RAR archives. + + + +7-Zip and p7zip +=============== +Now there are two different ports of 7-Zip for Linux/macOS: + +1) p7zip - another port of 7-Zip for Linux, made by an independent developer. + The latest version of p7zip now is 16.02, and that p7zip 16.02 is outdated now. + http://sourceforge.net/projects/p7zip/ + +2) 7-Zip for Linux/macOS - this package - it's new code with all changes from latest 7-Zip for Windows. + +These two ports are not identical. +Note also that some Linux specific things can be implemented better in p7zip than in new 7-Zip for Linux. + + + + +Notes: +------ +7-Zip consists of COM modules (DLL files). +But 7-Zip doesn't use standard COM interfaces for creating objects. +Look at +7zip\UI\Client7z folder for example of using DLL files of 7-Zip. +Some DLL files can use other DLL files from 7-Zip. +If you don't like it, you must use standalone version of DLL. +To compile standalone version of DLL you must include all used parts +to project and define some defs. +For example, 7zip\Bundles\Format7z is a standalone version of 7z.dll +that works with 7z format. So you can use such DLL in your project +without additional DLL files. + + +Description of 7-Zip sources package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +DOC Documentation +--- + readme.txt - Readme file + src-history.txt - Sources history + 7zC.txt - 7z ANSI-C Decoder description + 7zFormat.txt - 7z format description + Methods.txt - Compression method IDs + lzma.txt - LZMA compression description + License.txt - license information + copying.txt - GNU LGPL license + unRarLicense.txt - License for unRAR part of source code + 7zip.wxs - installer script for WIX + 7zip.hhp - html help project file + +Asm - Source code in Assembler : optimized code for CRC, SHA, AES, LZMA decoding. + +C - Source code in C + +CPP - Source code in C++ + +Common common files for C++ projects + +Windows common files for Windows related code + +7zip + + Common Common modules for 7-zip + + Archive files related to archiving + + Bundle Modules that are bundles of other modules (files) + + Alone 7za.exe: Standalone version of 7-Zip console that supports only 7z/xz/cab/zip/gzip/bzip2/tar. + Alone2 7zz.exe: Standalone version of 7-Zip console that supports all formats. + Alone7z 7zr.exe: Standalone version of 7-Zip console that supports only 7z (reduced version) + Fm Standalone version of 7-Zip File Manager + Format7z 7za.dll: .7z support + Format7zExtract 7zxa.dll: .7z support, extracting only + Format7zR 7zr.dll: .7z support, reduced version + Format7zExtractR 7zxr.dll: .7z support, reduced version, extracting only + Format7zF 7z.dll: all formats + LzmaCon lzma.exe: LZMA compression/decompression + SFXCon 7zCon.sfx: Console 7z SFX module + SFXWin 7z.sfx: Windows 7z SFX module + SFXSetup 7zS.sfx: Windows 7z SFX module for Installers + + Compress files for compression / decompression + + Crypto files for encryption / decryption + + UI + + Agent Intermediary modules for FAR plugin and Explorer plugin + Client7z Test application for 7za.dll + Common Common UI files + Console 7z.exe : Console version + Explorer 7-zip.dll: 7-Zip Shell extension + Far plugin for Far Manager + FileManager 7zFM.exe: 7-Zip File Manager + GUI 7zG.exe: 7-Zip GUI version + + + +--- +Igor Pavlov +http://www.7-zip.org diff -Nru p7zip-rar-16.02/DOC/src-history.txt p7zip-rar-16.02+really25.00+ds/DOC/src-history.txt --- p7zip-rar-16.02/DOC/src-history.txt 2016-06-11 08:08:07.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/DOC/src-history.txt 2025-07-05 14:00:00.000000000 +0000 @@ -1,542 +1,816 @@ -HISTORY of the 7-Zip source code --------------------------------- - -16.02 2016-05-21 -------------------------- -- The BUG in 16.00 - 16.01 was fixed: - Split Handler (SplitHandler.cpp) returned incorrect - total size value (kpidSize) for split archives. - - -16.01 2016-05-19 -------------------------- -- Some bugs were fixed, -- Some internal changes to reduce the number of compiler warnings. - - -16.00 2016-05-10 -------------------------- -- 7-Zip now can extract multivolume ZIP archives (z01, z02, ... , zip). -- Some bugs were fixed, - - -15.12 2015-11-19 -------------------------- -- The BUG in C version of 7z decoder was fixed: - 7zDec.c : SzDecodeLzma2() - 7z decoder could mistakenly report about decoding error for some 7z archives - that use LZMA2 compression method. - The probability to get that mistaken decoding error report was about - one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). -- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: - 7zArcIn.c : SzReadHeader2() - 7z decoder worked incorrectly for 7z archives that contain - empty solid blocks, that can be placed to 7z archive, if some file is - unavailable for reading during archive creation. - - -15.09 beta 2015-10-16 -------------------------- -- The BUG in LZMA / LZMA2 encoding code was fixed. - The BUG in LzFind.c::MatchFinder_ReadBlock() function. - If input data size is larger than (4 GiB - dictionary_size), - the following code worked incorrectly: - - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions - for compressing from memory to memory. - That BUG is not related to LZMA encoder version that works via streams. - - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if - default value of chunk size (CLzma2EncProps::blockSize) is changed - to value larger than (4 GiB - dictionary_size). - - -9.38 beta 2015-01-03 -------------------------- -- The BUG in 9.31-9.37 was fixed: - IArchiveGetRawProps interface was disabled for 7z archives. -- The BUG in 9.26-9.36 was fixed: - Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows. - - -9.36 beta 2014-12-26 -------------------------- -- The BUG in command line version was fixed: - 7-Zip created temporary archive in current folder during update archive - operation, if -w{Path} switch was not specified. - The fixed 7-Zip creates temporary archive in folder that contains updated archive. -- The BUG in 9.33-9.35 was fixed: - 7-Zip silently ignored file reading errors during 7z or gz archive creation, - and the created archive contained only part of file that was read before error. - The fixed 7-Zip stops archive creation and it reports about error. - - -9.31 2012-10-31 -------------------------- -- InBuffer.h : CInBuffer uses ISequentialInStream *_stream; instead of CMyComPtr - OutBuffer.h: COutBuffer uses ISequentialOutStream *_stream; instead of CMyComPtr - - -9.26 2011-04-11 -------------------------- -- The BUG was fixed: multi-threaded ZIP stored file size that was at scan stage, - So if the file was changed after scan, the Unpack Size field was incorrect - - -9.21 2011-04-11 -------------------------- -- New class FString for file names at file systems. -- Speed optimization in CRC code for big-endian CPUs. - - -9.18 2010-11-02 -------------------------- -- New small SFX module for installers (C/Util/SfxSetup). - - -9.17 2010-10-04 -------------------------- -- IStream.h::IOutStream:: - STDMETHOD(SetSize)(Int64 newSize) PURE; - was changed to - STDMETHOD(SetSize)(UInt64 newSize) PURE; - - -9.09 2009-12-12 -------------------------- -- The bug was fixed: - Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c - incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8. - - -9.05 2009-07-05 -------------------------- -- FileMapping.h::CFileMapping now returns WRes - - -9.04 2009-05-30 -------------------------- -- ICoder.h: NCoderPropID::EEnum values were changed - - -9.02 2009-04-23 -------------------------- -- Bug was fixed: if swap2 filter was requests at compression, - 7-zip used swap4 filter instead (but id was swap2), so archives were incorrect. - -4.61 2008-11-23 -------------------------- -- Bug in ver. 4.58+ was fixed: - 7-Zip didn't use any -m* switch after -mtc, -mcl or -mcu for .zip archives. -- Bug in .CAB code was fixed. 7-Zip didn't show some empty files, - if .CAB archive contains more than one empty file. - - -4.59 2008-07-27 -------------------------- -- Bug was fixed: - LZMA Encoder in fast compression mode could access memory outside of - allocated range in some rare cases. - - -4.59 alpha 2008-05-30 -------------------------- -- BUGS was fixed: - 7zOut.cpp: 7-Zip incorrectly wrote size of property records in some cases. - 7zIn.cpp: 7-Zip incorrectly work with archive, containg archive properties. - -4.58 alpha 9 2008-04-29 -------------------------- -- BUG was fixed: 7-Zip showed incorrect timestamps in ISO files. - - -4.58 alpha 8 2008-04-15 -------------------------- -- BUG in 4.58 alpha 5/6/7 was fixed: - LZMA encoder worked incorrectly, if lp != 0. -- Unicode (UTF-8) support for filenames in .ZIP archives. Now there are 3 modes: - 1) Default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols. - 2) -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols. - 3) -mcl switch: 7-Zip uses local code page. -- Now it's possible to use -mSW- and -mSW+ switches instead of -mSW=off and -mSW=on - - -4.58 alpha 7 2008-04-08 -------------------------- -- BUG was fixed: BZip2Encoder and BZip2Decoder used CEvent objects without - creating, when BZip2 code was called with one thread (with -mmt1 switch or with - default switches on single thread CPU). -- .lzma support. -- RPM and NSIS support was improved. -- LZMA now stores only (2 << n) or (3 << n) dictionary size value to LZMA properties. - - -4.58 alpha 6 2008-03-27 -------------------------- -- NTFS time extra in ZIP. -- New item property - kpidTimeType - VT_UI4 (0 - NTFS, 1 - Unix, 2 - DOS). -- Static CRC table is not required now for Lzma Encoder (in Lz MatchFinder). - - -4.58 alpha 5 2008-03-19 -------------------------- -- Creation time (-mtc switch) for .7z archives -- LZMA encoder was converted to ANSI-C - - -4.58 alpha 3 2008-02-25 -------------------------- -- Speed optimizations for LZMA decoding. Now it uses C code instead of C++. -- 7-Zip now has 128 MB dictionary limit for 32-bit version: - It's for speed optimization: kNumLogBits = 9 + sizeof(size_t) / 2; -- TAR: 'D' link flag support. -- 7-Zip now can unpack multivolume RAR archives created with - "old style volume names" scheme (-vn switch) and names *.001, *.002, ... -- Fixed bugs: - - 7-Zip FM could not copy / move files to root network folders like \\COMPNAME\FOLDERNAME\ - In case of move it removed original files. - - SFX-WIN: if there are errors, it still could return 0. - - ZIP (.XPS file) isZip64 && thisDiskNumber16 == 0xFFFF. - - ZIP name updating: - If zip file contains extra field and you try to change properties of files, - 7-zip tries to delete all extra fileds (except for WzAES). - And that code could hang. - - 7-Zip GUI didn't suggest BZip2 dictionary size used in previous run. - - If creation time stamp was included in .RAR archive, 7-zip used creation time stamp - as modification time stamp. - -4.58 alpha 2 2007-12-31 -------------------------- -- Small changes in Deflate and LZMA compression. -- Some speed optimizations. - - -4.57 ----- -- Bug was fixed: - Anti item is created for wrong file: - http://sourceforge.net/forum/forum.php?thread_id=1880366&forum_id=45798 - - -4.52 beta 2007-07-32 -------------------------- -- 7-Zip could not decompress some cab files -- "." dir creating at FAT was fixed / long names - - -4.50 beta 2007-07-24 -------------------------- -- 7-Zip now replaces unsupported filenames (like "nul", "com1") during extracting. -- New switch for command line version: - -ssc[-] enables/disables case-sensitive mode. -- 7z.exe l shows archive comment for zip archives -- Some bugs were fixed: long paths names shorter than 4. -- Speed optimizations for AES encryption. - - - -4.56 beta 2007-09-13 -------------------------- -- some fixes in LZ encoder (LZMA and Deflate) code. - size_t was replaces to ptrdiff_t. - size_t version worked incorrectly with some compilers. - - -4.46 beta 2007-05-25 -------------------------- -- CPP Synchronization objects now return HRes (error code) instead of bool. - - -4.45 beta 2007-04-16 -------------------------- -- 7-Zip now uses C version of CRC, so you must call CrcGenerateTable at - stratup code, or you must add CPP/Common/CRC.cpp to your project. -- Method ID in .7z now is 63-bit integer (UInt64). -- Open error messages -- unRar 1.5 fixed -- unShrink fixed -- BUG of 4.43 beta and 4.44 beta was fixed. - 7-Zip compressing to .zip in multi-threading mode didn't work in some cases. - - -4.44 beta 2007-01-20 -------------------------- - -- Bug was fixed: LZMAEncoder.cpp::CEncoder::GetOptimumFast - it was: - data++ - fixed version: - data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; - It could lead to very small cpmpression ratio decreasing when block needs move. - - -4.30 beta 2005-11-18 -------------------------- -- Security.h::AddLockMemoryPrivilege - installs "Large pages" feature -- MemoryLock.h::EnableLockMemoryPrivilege - enables "Large pages" feature -- Alloc.h::SetLargePageSize - sets optimal LargePageSize size - - -4.27 2005-09-21 -------------------------- -- Some GUIDs/interfaces were changed. - IStream.h: - ISequentialInStream::Read now works as old ReadPart - ISequentialOutStream::Write now works as old WritePart - - -4.26 beta 2005-08-05 -------------------------- -- MyAlloc(0)/BigAlloc(0) now return 0 - - -4.25 beta 2005-07-31 -------------------------- -- More 64-bit compatibilty - - -4.24 beta 2005-07-06 -------------------------- -- Common\NewHandler.h: using throw() for code size optimization. - - -4.23 2005-06-29 -------------------------- -- Bug was fixed: memory leak in Cab decoder. - - -4.19 beta 2005-05-21 -------------------------- -- BZip2 code was rewritten. Now 7-Zip doesn't use original BZip2 code. - Old (original) version was moved to folder 7zip/Compress/BZip2Original/ - - -4.14 beta 2005-01-11 -------------------------- -- STL using was reduced -- 7za now supports Split(001) archves - - -4.10 beta 2004-10-21 -------------------------- -- Codecs now use new interface: ICompressSetDecoderProperties2 - - -4.07 beta 2004-10-03 -------------------------- -- some interfaces were changed slightly to support - -stdin -stdout mode. -- FilterCoder for simple filters -- Wildcard censor class was changed. -- Bug was fixed: when encrypted stream was multiple 16, - it used additional 16 empty bytes. - - -3.11 2003-10-06 -------------------------- - File functions support unicode strings even - on Windows 95/98/ME. - - -3.08.02 2003-09-20 -------------------------- - More compatible with GCC. - - -3.08.02 beta 2003-08-20 -------------------------- - Extracting bug in 7zExtract.cpp was fixed. - - -3.08 beta 2003-08-19 -------------------------- - Big source code reconstruction. - - -2.30 Beta 32 2003-05-15 -------------------------- - Small changes in Deflate decoder. - - -2.30 Beta 31 2003-04-29 -------------------------- - Common/NewHandler.cpp - HeapAlloc in (included to beta 30) was changed to malloc. - HeapAlloc worked slower in Win95/98/Me. - - -2.30 Beta 30 2003-04-21 -------------------------- - new file: Common/String.cpp - Common/NewHandler.* were changed - - -2.30 Beta 29 2003-04-07 -------------------------- - Small changes in LZMA code. - - -2.30 Beta 28 2003-02-16 -------------------------- - Processing anti-files was corrected. - - -2.30 Beta 27 2003-01-24 -------------------------- - Project/Archiver/Format/Common/ArchiveInterface.h: - new IArchiveOpenVolumeCallback interface. - - -2.30 Beta 26 2003-01-12 -------------------------- - SDK/Interface/PropID.h: - kpidComment now is kpidCommented - - -2.30 Beta 25 2003-01-02 -------------------------- - Main archive interfaces were changed. - - -2.30 Beta 24 2002-11-01 -------------------------- - SDK/Windows/Synchronization.h - SDK/Windows/Synchronization.cpp - - some changes. - - -2.30 Beta 23 2002-09-07 -------------------------- - Project/FileManager folder was added. - Notation of some source files was changed. - - -2.30 Beta 22 2002-08-28 -------------------------- - Project/FileManager folder was added. - Notation of some source files was changed. - - - -2.30 Beta 21 2002-07-08 -------------------------- - Project/Compress/LZ/MatchFinder/BinTree/BinTree.h - Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h - Project/Compress/LZ/MatchFinder/BinTree/HC.h - Project/Compress/LZ/MatchFinder/BinTree/HCMain.h - - RAM requirements for LZMA (7z) compression were reduced. - - -2.30 Beta 20 2002-07-01 -------------------------- -- SDK/Stream/WindowOut.h - now it uses only required memory (dictionary size). -- Project/Archiver/Resource - contains common resurces - - -2.30 Beta 19 2002-04-11 -------------------------- -- SDK/Archive/Rar/Handler.cpp - supporting RAR29 - -2.30 Beta 18 2002-03-25 -------------------------- -- SDK/Archive/Cab/MSZipDecoder.cpp - SDK/Archive/Cab/LZXDecoder.cpp: - bug with corrupted archives was fixed -- Project/Compress/LZ/MatchFinder/BinTree/BinTree.h -- Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h - some speed optimization (using prefetching) - - -2.30 Beta 17 2002-03-03 -------------------------- -- ARJ suppport. - - -2.30 Beta 16 2002-02-24 -------------------------- -- Project/Compress/LZ/LZMA/Decoder.cpp: - Bug was fixed: LZMA could not extract more than 4 GB. -- RPM and CPIO formats. -- Project/Compress/LZ/LZMA/Encoder.* - Project/Archiver/Format/7z/OutHandler.cpp - New fast compression mode for LZMA: -m0a=0. -- New match finders for LZMA: bt4b, hc3, hc4. - - -2.30 Beta 15 2002-02-17 -------------------------- -- Compression ratio in LZMA was slightly improved: - Project/Compress/LZ/LZMA/Encoder.* - Project/Archiver/Format/7z/OutHandler.cpp - - -2.30 Beta 14 2002-02-10 -------------------------- -- Supporting multithreading for LZMA: - Project/Compress/LZ/MatchFinder/MT -- Common/String.h: - CStringBase::Replace function was fixed. - - -2.30 Beta 13 2002-01-27 -------------------------- -- Compress/LZ/MatchFinder/BinTree3.h: - method -- Compress/LZ/MatchFinder/BinTreemain.h: - - one VirtualAlloc array was splitted to - the for 3 arrays. - - Hash-functions were changed. - - - -2.30 Beta 12 2002-01-16 -------------------------- -- Compress/LZ/MatchFinder/BinTreemain.h: - Compress/LZ/MatchFinder/Patricia.h: - Compress/PPM/PPMd/SubAlloc.h: - Beta 11 bugs were fixed: - - VirtualFree was used incorrectly - - checking WIN32 instead _WINDOWS. - Compress/LZ/MatchFinder/Patricia.h: - Beta 11 bug with deleting m_Hash2Descendants was fixed. - - -2.30 Beta 11 2002-01-15 -------------------------- -- Compress/LZ/MatchFinder/BinTreemain.h: - Compress/LZ/MatchFinder/Patricia.h: - Compress/PPM/PPMd/SubAlloc.h: - using VirtualAlloc for memory allocating -- Exlorer/ContextMenu.cpp: - Testing supporting. - CreateProcess instead WinExec -- Format/Common/IArchiveHandler.h: - Exlorer/ProxyHandler.cpp: - FAR/Plugin.cpp: - New properties names: Method, HostOS. -- Exlorer/OverwriteDialog.cpp: - FAR/OverwriteDialog.cpp: - Windows/PropVariantConversions.h - Using National time format was eliminated. - - - -2.30 Beta 10 2002-01-11 -------------------------- -- Exlorer/ContextMenu.cpp: bug with context menu on - Windows NT4 in Unicode version was fixed. -- Format/7z/UpdateArchiveEngine.cpp: bug was fixed - - Updating in Beta 8 and 9 didn't work. -- Exlorer/CCompressDialog.cpp: history growing bug was fixed. - - -2.30 Beta 9 2002-01-08 -------------------------- -- SDK/Common/Vector.h: sopporting sorted object vectors . -- Lang features. -- Two new match finders: pat3h and pat4h. -- SDK/Archive/Zip/InEngine.cpp: bug was fixed. -- SDK/Windows/FileDir.cpp: function CreateComplexDirectory - was changed. - +HISTORY of the 7-Zip source code +-------------------------------- + +25.00 2025-07-05 +------------------------- +- 7-Zip for Windows can now use more than 64 CPU threads for compression + to zip/7z/xz archives and for the 7-Zip benchmark. + If there are more than one processor group in Windows (on systems with more than + 64 cpu threads), 7-Zip distributes running CPU threads across different processor groups. +- bzip2 compression speed was increased by 15-40%. +- deflate (zip/gz) compression speed was increased by 1-3%. +- improved support for zip, cpio and fat archives. +- fixed some bugs and vulnerabilities. + + +24.09 2024-11-29 +------------------------- +- The default dictionary size values for LZMA/LZMA2 compression methods were increased: + dictionary size compression level + v24.08 v24.09 v24.09 + 32-bit 64-bit + 8 MB 16 MB 16 MB -mx4 + 16 MB 32 MB 32 MB -mx5 : Normal + 32 MB 64 MB 64 MB -mx6 + 32 MB 64 MB 128 MB -mx7 : Maximum + 64 MB 64 MB 256 MB -mx8 + 64 MB 64 MB 256 MB -mx9 : Ultra + The default dictionary size values for 32-bit versions of LZMA/LZMA2 don't exceed 64 MB. +- 7-Zip now can calculate the following hash checksums: SHA-512, SHA-384, SHA3-256 and MD5. +- APM and HFS support was improved. +- If an archive update operation uses a temporary archive folder and + the archive is moved to the destination folder, 7-Zip shows the progress of moving + the archive file, as this operation can take a long time if the archive is large. +- The bug was fixed: 7-Zip File Manager didn't propagate Zone.Identifier stream + for extacted files from nested archives (if there is open archive inside another open archive). +- Some bugs were fixed. + + +24.08 2024-08-11 +------------------------- +- The bug in 7-Zip 24.00-24.07 was fixed: + For creating a zip archive: 7-Zip could write extra zero bytes after the end of the archive, + if a file included to archive cannot be compressed to a size smaller than original. + The created zip archive is correct except for the useless zero bytes after the end of the archive. + When unpacking such a zip archive, 7-Zip displays a warning: + "WARNING: There are data after the end of archive". +- Some bugs were fixed. + + +24.07 2024-06-19 +------------------------- +- Changes in files: + Asm/x86/Sha256Opt.asm + Asm/x86/Sha1Opt.asm + Now it uses "READONLY" flag for constant array segment. + It fixes an issue where ".rodata" section in 7-Zip for x86/x64 Linux had a "WRITE" attribute. +- The bug was fixed: 7-Zip could crash for some incorrect ZSTD archives. + + +24.06 2024-05-26 +------------------------- +- The bug was fixed: 7-Zip could not unpack some ZSTD archives. + + +24.05 2024-05-14 +------------------------- +- New switch -myv={MMNN} to set decoder compatibility version for 7z archive creating. + {MMNN} is 4-digit number that represents the version of 7-Zip without a dot. + If -myv={MMNN} switch is specified, 7-Zip will only use compression methods that can + be decoded by the specified version {MMNN} of 7-Zip and newer versions. + If -myv={MMNN} switch is not specified, -myv=2300 is used, and 7-Zip will only + use compression methods that can be decoded by 7-Zip 23.00 and newer versions. +- New switch -myfa={FilterID} to allow 7-Zip to use the specified filter method for 7z archive creating. +- New switch -myfd={FilterID} to disallow 7-Zip to use the specified filter method for 7z archive creating. + + +24.03 2024-03-23 +------------------------- +- 7-Zip now can use new RISCV filter for compression to 7z and xz archives. + RISCV filter can increase compression ratio for data containing executable + files compiled for RISC-V architecture. +- The speed for LZMA and LZMA2 decompression in ARM64 version for Windows + was increased by 20%-60%. + It uses arm64 assembler code, and clang-cl is required for arm64 assembler code compiling. +- Some bugs were fixed. + + +24.01 2024-01-31 +------------------------- +- 7-Zip uses file C/Precomp.h that is included to all c and c++ files. + CPP/Common/Common.h also includes C/Precomp.h. + C/Precomp.h defines the following macros (if _WIN32 is defined): + Z7_LARGE_PAGES 1 + Z7_LONG_PATH 1 + Z7_WIN32_WINNT_MIN 0x0500 (or higher) + _WIN32_WINNT 0x0500 (or higher) + WINVER _WIN32_WINNT + UNICODE 1 + _UNICODE 1 + if _WIN32_WINNT is defined already, C/Precomp.h doesn't redefine it. + +- 7-Zip now can unpack ZSTD archives (.zst extension). +- 7-Zip now can unpack ZIP and SquashFS archives that use ZSTD compression method. +- 7-Zip now supports fast hash algorithm XXH64 that is used in ZSTD. +- Speed optimizations for archive unpacking: rar, zip, gz, wim, cab. +- Speed optimizations for hash caclulation: CRC-32, CRC-64, Blake2sp. +- The bug was fixed: 7-Zip for Linux could fail for multivolume creation in some cases. +- Some bugs were fixed. + + +23.01 2023-06-20 +------------------------- +- All external macros for compiling C/C++ code of 7-Zip now have Z7_ prefix. +- 7-Zip COM interfaces now use new macros that allow to declare and implement COM interface. +- The code has been modified to compile with the maximum diagnostic warning level: + -Wall in MSVC and -Weverything in CLANG. + And some warning types are disabled in 2 files: + - C/Compiler.h for C/C++ code warnings. + - CPP/Common/Common.h for C++ code warnings. +- Linux/macOS versions of 7-Zip: IUnknown interface in new code doesn't use + virtual destructor that was used in previous 7-Zip and p7zip: + // virtual ~IUnknown() {} + So 7-Zip's dynamically linked shared libraries (codecs) are not compatible + between new 7-Zip for Linux/macOS and old 7-Zip (and p7zip). +- Some optimizations in filters code: BCJ, BCJ2, Swap* and opthers. +- If 7-Zip uses BCJ2 filter for big datasets compressing, it can use additional temp + files in system's TEMP folder. 7-Zip uses temp file for additional compressed + data stream, if size of such compressed stream is larger than predefined limit: + 16 MiB in 32-bit version, 4 GiB in 64-bit version. +- Some bugs were fixed. + + +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 + for cases where the name of some directory is the same as the prefix part of the name + of another directory or file. +- TAR archives created by 7-Zip now are more consistent with archives created by GNU TAR program. + + +21.06 2021-11-24 +------------------------- +- Bug in LZMA encoder in file LzmaEnc.c was fixed: + LzmaEnc_MemEncode(), LzmaEncode() and LzmaCompress() could work incorrectly, + if size value for output buffer is smaller than size required for all compressed data. + LzmaEnc_Encode() could work incorrectly, + if callback ISeqOutStream::Write() doesn't write all compressed data. + NCompress::NLzma::CEncoder::Code() could work incorrectly, + if callback ISequentialOutStream::Write() returns error code. +- Bug in versions 21.00-21.05 was fixed: + 7-Zip didn't set attributes of directories during archive extracting. + + +21.04 beta 2021-11-02 +------------------------- +- 7-Zip now reduces the number of working CPU threads for compression, + if RAM size is not enough for compression with big LZMA2 dictionary. +- 7-Zip now can create and check "file.sha256" and "file.sha1" text files + that contain the list of file names and SHA-1 / SHA-256 checksums in format + compatible with sha1sum/sha256sum programs. + + +21.03 beta 2021-07-20 +------------------------- +- The maximum dictionary size for LZMA/LZMA2 compressing was increased to 4 GB (3840 MiB). +- Minor speed optimizations in LZMA/LZMA2 compressing. + + +21.02 alpha 2021-05-06 +------------------------- +- 7-Zip now writes additional field for filename in UTF-8 encoding to zip archives. + It allows to extract correct file name from zip archives on different systems. +- The command line version of 7-Zip for macOS was released. +- The speed for LZMA and LZMA2 decompression in arm64 versions for macOS and Linux + was increased by 20%-60%. +- Some changes and improvements in ZIP, TAR and NSIS code. + + +21.01 alpha 2021-03-09 +------------------------- +- The command line version of 7-Zip for Linux was released. +- The improvements for speed of ARM64 version using hardware CPU instructions + for AES, CRC-32, SHA-1 and SHA-256. +- The bug in versions 18.02 - 21.00 was fixed: + 7-Zip could not correctly extract some ZIP archives created with xz compression method. +- Some bugs were fixed. + + +20.02 alpha 2020-08-08 +------------------------- +- The default number of LZMA2 chunks per solid block in 7z archive was increased to 64. + It allows to increase the compression speed for big 7z archives, if there is a big number + of CPU cores and threads. +- The speed of PPMd compressing/decompressing was increased for 7z/ZIP/RAR archives. +- The new -ssp switch. If the switch -ssp is specified, 7-Zip doesn't allow the system + to modify "Last Access Time" property of source files for archiving and hashing operations. +- Some bugs were fixed. + + +20.00 alpha 2020-02-06 +------------------------- +- 7-Zip now supports new optional match finders for LZMA/LZMA2 compression: bt5 and hc5, + that can work faster than bt4 and hc4 match finders for the data with big redundancy. +- The compression ratio was improved for Fast and Fastest compression levels with the + following default settings: + - Fastest level (-mx1) : hc5 match finder with 256 KB dictionary. + - Fast level (-mx3) : hc5 match finder with 4 MB dictionary. +- Minor speed optimizations in multithreaded LZMA/LZMA2 compression for Normal/Maximum/Ultra + compression levels. +- bzip2 decoding code was updated to support bzip2 archives, created by lbzip2 program. + + +19.02 2019-09-05 +------------------------- +- Support for SHA-1/SHA-256 optimized code in + Sha1Opt.c, Sha256Opt.c, Sha256Opt.asm, Sha1Opt.asm. + + +19.00 2019-02-21 +------------------------- +- Encryption strength for 7z archives was increased: + the size of random initialization vector was increased from 64-bit to 128-bit, + and the pseudo-random number generator was improved. +- Some bugs were fixed. + + +18.06 2018-12-30 +------------------------- +- The speed for LZMA/LZMA2 compressing was increased by 3-10%, + and there are minor changes in compression ratio. +- Some bugs were fixed. +- The bug in 7-Zip 18.02-18.05 was fixed: + There was memory leak in multithreading xz decoder - XzDecMt_Decode(), + if xz stream contains only one block. +- 7-Zip 18.02-18.05 used only one CPU thread for bz2 archive creation. +- The changes for MSVS compiler makefiles: + - the makefiles now use "PLATFORM" macroname with values (x64, x86, arm64) + instead of "CPU" macroname with values (AMD64, ARM64). + - the makefiles by default now use static version of the run-time library. + + +18.05 2018-04-30 +------------------------- +- The speed for LZMA/LZMA2 compressing was increased + by 8% for fastest/fast compression levels and + by 3% for normal/maximum compression levels. +- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in + Windows 10 because of some BUG with "Large Pages" in Windows 10. + Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299). + + +18.03 beta 2018-03-04 +------------------------- +- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm + for x64 with about 30% higher speed than main version of LZMA decoder written in C. +- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%. +- 7-Zip now can use multi-threading for 7z/LZMA2 decoding, + if there are multiple independent data chunks in LZMA2 stream. +- 7-Zip now can use multi-threading for xz decoding, + if there are multiple blocks in xz stream. + + +17.00 beta 2017-04-29 +------------------------- +- NewHandler.h / NewHandler.cpp: + now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900). +- C/7zTypes.h : the names of variables in interface structures were changed (vt). +- Some bugs were fixed. 7-Zip could crash in some cases. +- Some internal changes in code. + + +16.02 2016-05-21 +------------------------- +- The BUG in 16.00 - 16.01 was fixed: + Split Handler (SplitHandler.cpp) returned incorrect + total size value (kpidSize) for split archives. + + +16.01 2016-05-19 +------------------------- +- Some bugs were fixed, +- Some internal changes to reduce the number of compiler warnings. + + +16.00 2016-05-10 +------------------------- +- 7-Zip now can extract multivolume ZIP archives (z01, z02, ... , zip). +- Some bugs were fixed, + + +15.12 2015-11-19 +------------------------- +- The BUG in C version of 7z decoder was fixed: + 7zDec.c : SzDecodeLzma2() + 7z decoder could mistakenly report about decoding error for some 7z archives + that use LZMA2 compression method. + The probability to get that mistaken decoding error report was about + one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). +- The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: + 7zArcIn.c : SzReadHeader2() + 7z decoder worked incorrectly for 7z archives that contain + empty solid blocks, that can be placed to 7z archive, if some file is + unavailable for reading during archive creation. + + +15.09 beta 2015-10-16 +------------------------- +- The BUG in LZMA / LZMA2 encoding code was fixed. + The BUG in LzFind.c::MatchFinder_ReadBlock() function. + If input data size is larger than (4 GiB - dictionary_size), + the following code worked incorrectly: + - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions + for compressing from memory to memory. + That BUG is not related to LZMA encoder version that works via streams. + - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if + default value of chunk size (CLzma2EncProps::blockSize) is changed + to value larger than (4 GiB - dictionary_size). + + +9.38 beta 2015-01-03 +------------------------- +- The BUG in 9.31-9.37 was fixed: + IArchiveGetRawProps interface was disabled for 7z archives. +- The BUG in 9.26-9.36 was fixed: + Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows. + + +9.36 beta 2014-12-26 +------------------------- +- The BUG in command line version was fixed: + 7-Zip created temporary archive in current folder during update archive + operation, if -w{Path} switch was not specified. + The fixed 7-Zip creates temporary archive in folder that contains updated archive. +- The BUG in 9.33-9.35 was fixed: + 7-Zip silently ignored file reading errors during 7z or gz archive creation, + and the created archive contained only part of file that was read before error. + The fixed 7-Zip stops archive creation and it reports about error. + + +9.31 2012-10-31 +------------------------- +- InBuffer.h : CInBuffer uses ISequentialInStream *_stream; instead of CMyComPtr + OutBuffer.h: COutBuffer uses ISequentialOutStream *_stream; instead of CMyComPtr + + +9.26 2011-04-11 +------------------------- +- The BUG was fixed: multi-threaded ZIP stored file size that was at scan stage, + So if the file was changed after scan, the Unpack Size field was incorrect + + +9.21 2011-04-11 +------------------------- +- New class FString for file names at file systems. +- Speed optimization in CRC code for big-endian CPUs. + + +9.18 2010-11-02 +------------------------- +- New small SFX module for installers (C/Util/SfxSetup). + + +9.17 2010-10-04 +------------------------- +- IStream.h::IOutStream:: + STDMETHOD(SetSize)(Int64 newSize) PURE; + was changed to + STDMETHOD(SetSize)(UInt64 newSize) PURE; + + +9.09 2009-12-12 +------------------------- +- The bug was fixed: + Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c + incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8. + + +9.05 2009-07-05 +------------------------- +- FileMapping.h::CFileMapping now returns WRes + + +9.04 2009-05-30 +------------------------- +- ICoder.h: NCoderPropID::EEnum values were changed + + +9.02 2009-04-23 +------------------------- +- Bug was fixed: if swap2 filter was requests at compression, + 7-zip used swap4 filter instead (but id was swap2), so archives were incorrect. + +4.61 2008-11-23 +------------------------- +- Bug in ver. 4.58+ was fixed: + 7-Zip didn't use any -m* switch after -mtc, -mcl or -mcu for .zip archives. +- Bug in .CAB code was fixed. 7-Zip didn't show some empty files, + if .CAB archive contains more than one empty file. + + +4.59 2008-07-27 +------------------------- +- Bug was fixed: + LZMA Encoder in fast compression mode could access memory outside of + allocated range in some rare cases. + + +4.59 alpha 2008-05-30 +------------------------- +- BUGS was fixed: + 7zOut.cpp: 7-Zip incorrectly wrote size of property records in some cases. + 7zIn.cpp: 7-Zip incorrectly work with archive, containg archive properties. + +4.58 alpha 9 2008-04-29 +------------------------- +- BUG was fixed: 7-Zip showed incorrect timestamps in ISO files. + + +4.58 alpha 8 2008-04-15 +------------------------- +- BUG in 4.58 alpha 5/6/7 was fixed: + LZMA encoder worked incorrectly, if lp != 0. +- Unicode (UTF-8) support for filenames in .ZIP archives. Now there are 3 modes: + 1) Default mode: 7-Zip uses UTF-8, if the local code page doesn't contain required symbols. + 2) -mcu switch: 7-Zip uses UTF-8, if there are non-ASCII symbols. + 3) -mcl switch: 7-Zip uses local code page. +- Now it's possible to use -mSW- and -mSW+ switches instead of -mSW=off and -mSW=on + + +4.58 alpha 7 2008-04-08 +------------------------- +- BUG was fixed: BZip2Encoder and BZip2Decoder used CEvent objects without + creating, when BZip2 code was called with one thread (with -mmt1 switch or with + default switches on single thread CPU). +- .lzma support. +- RPM and NSIS support was improved. +- LZMA now stores only (2 << n) or (3 << n) dictionary size value to LZMA properties. + + +4.58 alpha 6 2008-03-27 +------------------------- +- NTFS time extra in ZIP. +- New item property - kpidTimeType - VT_UI4 (0 - NTFS, 1 - Unix, 2 - DOS). +- Static CRC table is not required now for Lzma Encoder (in Lz MatchFinder). + + +4.58 alpha 5 2008-03-19 +------------------------- +- Creation time (-mtc switch) for .7z archives +- LZMA encoder was converted to ANSI-C + + +4.58 alpha 3 2008-02-25 +------------------------- +- Speed optimizations for LZMA decoding. Now it uses C code instead of C++. +- 7-Zip now has 128 MB dictionary limit for 32-bit version: + It's for speed optimization: kNumLogBits = 9 + sizeof(size_t) / 2; +- TAR: 'D' link flag support. +- 7-Zip now can unpack multivolume RAR archives created with + "old style volume names" scheme (-vn switch) and names *.001, *.002, ... +- Fixed bugs: + - 7-Zip FM could not copy / move files to root network folders like \\COMPNAME\FOLDERNAME\ + In case of move it removed original files. + - SFX-WIN: if there are errors, it still could return 0. + - ZIP (.XPS file) isZip64 && thisDiskNumber16 == 0xFFFF. + - ZIP name updating: + If zip file contains extra field and you try to change properties of files, + 7-zip tries to delete all extra fileds (except for WzAES). + And that code could hang. + - 7-Zip GUI didn't suggest BZip2 dictionary size used in previous run. + - If creation time stamp was included in .RAR archive, 7-zip used creation time stamp + as modification time stamp. + +4.58 alpha 2 2007-12-31 +------------------------- +- Small changes in Deflate and LZMA compression. +- Some speed optimizations. + + +4.57 +---- +- Bug was fixed: + Anti item is created for wrong file: + http://sourceforge.net/forum/forum.php?thread_id=1880366&forum_id=45798 + + +4.52 beta 2007-07-32 +------------------------- +- 7-Zip could not decompress some cab files +- "." dir creating at FAT was fixed / long names + + +4.50 beta 2007-07-24 +------------------------- +- 7-Zip now replaces unsupported filenames (like "nul", "com1") during extracting. +- New switch for command line version: + -ssc[-] enables/disables case-sensitive mode. +- 7z.exe l shows archive comment for zip archives +- Some bugs were fixed: long paths names shorter than 4. +- Speed optimizations for AES encryption. + + + +4.56 beta 2007-09-13 +------------------------- +- some fixes in LZ encoder (LZMA and Deflate) code. + size_t was replaces to ptrdiff_t. + size_t version worked incorrectly with some compilers. + + +4.46 beta 2007-05-25 +------------------------- +- CPP Synchronization objects now return HRes (error code) instead of bool. + + +4.45 beta 2007-04-16 +------------------------- +- 7-Zip now uses C version of CRC, so you must call CrcGenerateTable at + stratup code, or you must add CPP/Common/CRC.cpp to your project. +- Method ID in .7z now is 63-bit integer (UInt64). +- Open error messages +- unRar 1.5 fixed +- unShrink fixed +- BUG of 4.43 beta and 4.44 beta was fixed. + 7-Zip compressing to .zip in multi-threading mode didn't work in some cases. + + +4.44 beta 2007-01-20 +------------------------- + +- Bug was fixed: LZMAEncoder.cpp::CEncoder::GetOptimumFast + it was: + data++ + fixed version: + data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1; + It could lead to very small cpmpression ratio decreasing when block needs move. + + +4.30 beta 2005-11-18 +------------------------- +- Security.h::AddLockMemoryPrivilege - installs "Large pages" feature +- MemoryLock.h::EnableLockMemoryPrivilege - enables "Large pages" feature +- Alloc.h::SetLargePageSize - sets optimal LargePageSize size + + +4.27 2005-09-21 +------------------------- +- Some GUIDs/interfaces were changed. + IStream.h: + ISequentialInStream::Read now works as old ReadPart + ISequentialOutStream::Write now works as old WritePart + + +4.26 beta 2005-08-05 +------------------------- +- MyAlloc(0)/BigAlloc(0) now return 0 + + +4.25 beta 2005-07-31 +------------------------- +- More 64-bit compatibilty + + +4.24 beta 2005-07-06 +------------------------- +- Common\NewHandler.h: using throw() for code size optimization. + + +4.23 2005-06-29 +------------------------- +- Bug was fixed: memory leak in Cab decoder. + + +4.19 beta 2005-05-21 +------------------------- +- BZip2 code was rewritten. Now 7-Zip doesn't use original BZip2 code. + Old (original) version was moved to folder 7zip/Compress/BZip2Original/ + + +4.14 beta 2005-01-11 +------------------------- +- STL using was reduced +- 7za now supports Split(001) archves + + +4.10 beta 2004-10-21 +------------------------- +- Codecs now use new interface: ICompressSetDecoderProperties2 + + +4.07 beta 2004-10-03 +------------------------- +- some interfaces were changed slightly to support + -stdin -stdout mode. +- FilterCoder for simple filters +- Wildcard censor class was changed. +- Bug was fixed: when encrypted stream was multiple 16, + it used additional 16 empty bytes. + + +3.11 2003-10-06 +------------------------- + File functions support unicode strings even + on Windows 95/98/ME. + + +3.08.02 2003-09-20 +------------------------- + More compatible with GCC. + + +3.08.02 beta 2003-08-20 +------------------------- + Extracting bug in 7zExtract.cpp was fixed. + + +3.08 beta 2003-08-19 +------------------------- + Big source code reconstruction. + + +2.30 Beta 32 2003-05-15 +------------------------- + Small changes in Deflate decoder. + + +2.30 Beta 31 2003-04-29 +------------------------- + Common/NewHandler.cpp + HeapAlloc in (included to beta 30) was changed to malloc. + HeapAlloc worked slower in Win95/98/Me. + + +2.30 Beta 30 2003-04-21 +------------------------- + new file: Common/String.cpp + Common/NewHandler.* were changed + + +2.30 Beta 29 2003-04-07 +------------------------- + Small changes in LZMA code. + + +2.30 Beta 28 2003-02-16 +------------------------- + Processing anti-files was corrected. + + +2.30 Beta 27 2003-01-24 +------------------------- + Project/Archiver/Format/Common/ArchiveInterface.h: + new IArchiveOpenVolumeCallback interface. + + +2.30 Beta 26 2003-01-12 +------------------------- + SDK/Interface/PropID.h: + kpidComment now is kpidCommented + + +2.30 Beta 25 2003-01-02 +------------------------- + Main archive interfaces were changed. + + +2.30 Beta 24 2002-11-01 +------------------------- + SDK/Windows/Synchronization.h + SDK/Windows/Synchronization.cpp + - some changes. + + +2.30 Beta 23 2002-09-07 +------------------------- + Project/FileManager folder was added. + Notation of some source files was changed. + + +2.30 Beta 22 2002-08-28 +------------------------- + Project/FileManager folder was added. + Notation of some source files was changed. + + + +2.30 Beta 21 2002-07-08 +------------------------- + Project/Compress/LZ/MatchFinder/BinTree/BinTree.h + Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h + Project/Compress/LZ/MatchFinder/BinTree/HC.h + Project/Compress/LZ/MatchFinder/BinTree/HCMain.h + - RAM requirements for LZMA (7z) compression were reduced. + + +2.30 Beta 20 2002-07-01 +------------------------- +- SDK/Stream/WindowOut.h + now it uses only required memory (dictionary size). +- Project/Archiver/Resource + contains common resurces + + +2.30 Beta 19 2002-04-11 +------------------------- +- SDK/Archive/Rar/Handler.cpp + supporting RAR29 + +2.30 Beta 18 2002-03-25 +------------------------- +- SDK/Archive/Cab/MSZipDecoder.cpp + SDK/Archive/Cab/LZXDecoder.cpp: + bug with corrupted archives was fixed +- Project/Compress/LZ/MatchFinder/BinTree/BinTree.h +- Project/Compress/LZ/MatchFinder/BinTree/BinTreeMain.h + some speed optimization (using prefetching) + + +2.30 Beta 17 2002-03-03 +------------------------- +- ARJ suppport. + + +2.30 Beta 16 2002-02-24 +------------------------- +- Project/Compress/LZ/LZMA/Decoder.cpp: + Bug was fixed: LZMA could not extract more than 4 GB. +- RPM and CPIO formats. +- Project/Compress/LZ/LZMA/Encoder.* + Project/Archiver/Format/7z/OutHandler.cpp + New fast compression mode for LZMA: -m0a=0. +- New match finders for LZMA: bt4b, hc3, hc4. + + +2.30 Beta 15 2002-02-17 +------------------------- +- Compression ratio in LZMA was slightly improved: + Project/Compress/LZ/LZMA/Encoder.* + Project/Archiver/Format/7z/OutHandler.cpp + + +2.30 Beta 14 2002-02-10 +------------------------- +- Supporting multithreading for LZMA: + Project/Compress/LZ/MatchFinder/MT +- Common/String.h: + CStringBase::Replace function was fixed. + + +2.30 Beta 13 2002-01-27 +------------------------- +- Compress/LZ/MatchFinder/BinTree3.h: + method +- Compress/LZ/MatchFinder/BinTreemain.h: + - one VirtualAlloc array was splitted to + the for 3 arrays. + - Hash-functions were changed. + + + +2.30 Beta 12 2002-01-16 +------------------------- +- Compress/LZ/MatchFinder/BinTreemain.h: + Compress/LZ/MatchFinder/Patricia.h: + Compress/PPM/PPMd/SubAlloc.h: + Beta 11 bugs were fixed: + - VirtualFree was used incorrectly + - checking WIN32 instead _WINDOWS. + Compress/LZ/MatchFinder/Patricia.h: + Beta 11 bug with deleting m_Hash2Descendants was fixed. + + +2.30 Beta 11 2002-01-15 +------------------------- +- Compress/LZ/MatchFinder/BinTreemain.h: + Compress/LZ/MatchFinder/Patricia.h: + Compress/PPM/PPMd/SubAlloc.h: + using VirtualAlloc for memory allocating +- Exlorer/ContextMenu.cpp: + Testing supporting. + CreateProcess instead WinExec +- Format/Common/IArchiveHandler.h: + Exlorer/ProxyHandler.cpp: + FAR/Plugin.cpp: + New properties names: Method, HostOS. +- Exlorer/OverwriteDialog.cpp: + FAR/OverwriteDialog.cpp: + Windows/PropVariantConversions.h + Using National time format was eliminated. + + + +2.30 Beta 10 2002-01-11 +------------------------- +- Exlorer/ContextMenu.cpp: bug with context menu on + Windows NT4 in Unicode version was fixed. +- Format/7z/UpdateArchiveEngine.cpp: bug was fixed - + Updating in Beta 8 and 9 didn't work. +- Exlorer/CCompressDialog.cpp: history growing bug was fixed. + + +2.30 Beta 9 2002-01-08 +------------------------- +- SDK/Common/Vector.h: sopporting sorted object vectors . +- Lang features. +- Two new match finders: pat3h and pat4h. +- SDK/Archive/Zip/InEngine.cpp: bug was fixed. +- SDK/Windows/FileDir.cpp: function CreateComplexDirectory + was changed. + diff -Nru p7zip-rar-16.02/GUI/Contents/Info.plist p7zip-rar-16.02+really25.00+ds/GUI/Contents/Info.plist --- p7zip-rar-16.02/GUI/Contents/Info.plist 2010-04-04 19:00:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Contents/Info.plist 1970-01-01 00:00:00.000000000 +0000 @@ -1,387 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDisplayName - 7zFM - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - 7z - 7Z - - CFBundleTypeIconFile - p7zip - CFBundleTypeName - 7-Zip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - bz2 - BZ2 - bzip2 - BZIP2 - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-bz2.icns - CFBundleTypeName - BZip2 - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - tbz2 - TBZ2 - tbzip2 - TBZIP2 - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-tbz2.icns - CFBundleTypeName - TBZip2 - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - bz - BZ - bzip - BZIP - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-bz.icns - CFBundleTypeName - BZip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - tbz - TBZ - tbzip - TBZIP - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-tbz.icns - CFBundleTypeName - TBzip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - gz - GZ - gzip - GZIP - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-gz.icns - CFBundleTypeName - GZip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - tgz - TGZ - tgzip - TGZIP - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-tgz.icns - CFBundleTypeName - TGZip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - tar - TAR - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-tar.icns - CFBundleTypeName - Tar - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - cpio - CPIO - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-cpio.icns - CFBundleTypeName - CPIO - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - cpgz - CPGZ - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-cpgz.icns - CFBundleTypeName - CPGZ - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - lzma - LZMA - - CFBundleTypeIconFile - p7zip - CFBundleTypeName - Lzma - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - pax - PAX - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-pax.icns - CFBundleTypeName - Pax - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - 001 - - CFBundleTypeIconFile - p7zip - CFBundleTypeName - Volume - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - iso - ISO - - CFBundleTypeIconFile - /System/Library/CoreServices/DiskImageMounter.app/Contents/Resources/diskcopy-doc.icns - CFBundleTypeName - ISO - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - exe - EXE - - CFBundleTypeIconFile - /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ExecutableBinaryIcon.icns - CFBundleTypeName - Windows Exe - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - cab - CAB - - CFBundleTypeIconFile - /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ExecutableBinaryIcon.icns - CFBundleTypeName - CAB - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - zip - ZIP - - CFBundleTypeIconFile - /System/Library/CoreServices/Archive Utility.app/Contents/Resources/bah-zip.icns - CFBundleTypeName - Zip - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - rar - RAR - .r00 - - CFBundleTypeIconFile - p7zip - CFBundleTypeName - Rar - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - ace - ACE - .c00 - - CFBundleTypeIconFile - p7zip - CFBundleTypeName - Ace - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleTypeExtensions - - * - - CFBundleTypeName - Archive - CFBundleTypeRole - Viewer - LSTypeIsPackage - - NSPersistentStoreTypeKey - XML - - - CFBundleExecutable - 7zFM - CFBundleIconFile - p7zip - CFBundleIdentifier - p7zip.7zFM - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - 7zFM - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1.3.2 - CFBundleSignature - aONe - CFBundleVersion - 57 - NSHumanReadableCopyright - Copyright © 2009-2010 aONe - NSPrincipalClass - NSApplication - SUFeedURL - http://p7zip.sourceforge.net - - diff -Nru p7zip-rar-16.02/GUI/Contents/PkgInfo p7zip-rar-16.02+really25.00+ds/GUI/Contents/PkgInfo --- p7zip-rar-16.02/GUI/Contents/PkgInfo 2010-04-04 19:00:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Contents/PkgInfo 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -APPLaONe \ No newline at end of file Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/GUI/Contents/Resources/p7zip.icns and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/Contents/Resources/p7zip.icns differ diff -Nru p7zip-rar-16.02/GUI/Lang/af.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/af.txt --- p7zip-rar-16.02/GUI/Lang/af.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/af.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.09 : Petri Jooste -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Afrikaans -Afrikaans -401 -OK -Kanselleer - - - -&Ja -&Nee -A&fsluit -Hulp - -&Gaan voort -440 -Ja vir &almal -Nee vir a&lmal -Stop -Herbegin -&Agtergrond -&Voorgrond -&Wag -Wagtend -Is u seker dat u wil kanselleer? -500 -&Lêer -R&edigeer -&Vertoon -G&unstelinge -&Gereedskap -&Hulp -540 -&Open -Open &Binne -Open B&uite -&Wys -R&edigeer -Her&noem -&Kopieer na... -&Verskuif na... -Ve&rwyder -Ver&deel lêer... -Kom&bineer lêers... -E&ienskappe -Komme&ntaar - - -Maak gids -Maak lêer -A&fsluit -600 -Selekteer &alles -Deselekteer a&lles -Keer &seleksie om -Selekteer... -Deselekteer... -Selekteer op Soort -Deselekteer op Soort -700 -&Groot ikone -&Klein ikone -&Lys -&Detail -730 -Ongesorteer - -&2 Panele -&Nutsbalke -Maak wortelgids oop -Een vlak hoër -Gidse geskiedenis... -&Verfris -750 -Argiveernutsbalk -Standaardnutsbalk -Groot knoppies -Wys teks op knoppies -800 -Voeg gids by gunstelinge &as -Boekmerk -900 -&Opsies... -&Normtoetsing -960 -&Inhoud... -&Aangaande 7-Zip... -1003 -Pad -Naam -Uitgang -Gids -Grootte -Ingepakte grootte -Kenmerke -Gemaak -Laatste toegang -Gewysig -Kompak -Kommentaar -Versleuteld -Verdeel Voor -Verdeel Na -Woordeboek -CRC -Tipe -Anti -Metode -Gasheer BS -Lêersstelsel -Gebruiker -Groep -Blok -Kommentaar -Posisie - - - - - - - - - - - - - - - - - - - - - - - - - -Fout -Totale grootte -Vrye ruimte -Klustergrootte -Etiket -Plaaslike naam -Verskaffer -2100 -Opsies -Taal -Taal: -Redigeerder -R&edigeerder: - -2200 -Stelsel -Assosieer 7-Zip met: -2301 -Integreer 7-Zip in kontekskeuselys. -Trapsgewyse kontekskeuselys -Kontekskeuselysitems: -2320 - - -Open -Pak lêers uit... -Voeg by argief... -Toets argief -Pak hier uit -Pak uit in {0} -Voeg by {0} -Saampers en e-pos... -Pers saam in {0} en e-pos -2400 -Gidse -&Werkgids -&TEMP-gids van het stelsel -&Huidige gids -&Gespesifiseerde gids: -Gebruik slegs vir verwisselbare media. -Spesifiseer die stoorplek vir tydelyke argieflêers. -2500 -Instellings -Wys ".." &item -Wys &ware lêerikone -Wys &stelselkeuselys -Wys seleksie oor &hele ry(e) -Wys &roosterlyne - - - -2900 -Aangaande 7-Zip -7-Zip is gratis programmatuur. Indien u egter so baie van 7-Zip hou dat u die verdere ontwikkeling wil ondersteun, registreer dan asb. met 'n geldelike donasie aan die 7-Zip Projek. -3000 - -Daar is geen foute nie -{0} objekt(e) is geselekteer -Kan gids '{0}' nie maak nie -Bywerk-funksie word vir hierdie argief nie ondersteun nie. - - - - -Lêer '{0}' is gewysig.\nWil u dit bywerk in die argief? -Kan lêer\n'{0}' nie bywerk nie -Redigeerder nie aan die gang gesit word nie. - - - - -Te veel items -3300 -Besig om uit te pak -Besig met saampersing -Besig om te toets -Besig om oop te maak... - -3400 -&Uitpak -U&itpak in: -Gee 'n bestemming vir uitgepakte lêers. -3410 -Pad-metode -Volledige padname -Geen padname -3420 -Vervang lêers -Vervang slegs met bevestiging -Vervang sonder bevestiging -Slaan bestaande lêers oor -Hernoem outomaties -Hernoem bestaande lêers outomaties -3500 -Bevestig lêeroorskrywing -Doelgids bevat alreeds 'n lêer met hierdie naam. -Wil u die bestaande lêer vervang -deur hierdie lêer ? -{0} grepe -O&utomaties hernoem -3700 -Nie-ondersteunde saampersmetode vir '{0}'. -Datafout in '{0}'. Lêer is beskadig. -CRC het misluk in '{0}'. Lêer is beskadig. - - -3800 -Tik wagwoord in -Tik wagwoord in: - -&Wys wagwoord - - - -&Wagwoord -3900 -Tydsduur sovêr: -Oorblywende tyd: -Grootte: -Spoed: - - -Foute: - -4000 -Voeg by argief -&Argief: -&Bywerkwyse: -Argie&fformaat: -Saampersingv&lak: -&Saampersmetode: -&Woordeboekgrootte: -&Woordgrootte: - - -Pa&rameters: -Opsies -Maak SF&X argief - - - -Enkripteer lêer&name -Geheuegebruik vir saampersing: -Geheuegebruik vir uitpakking: -4050 -Stoor -Vinnigste -Vinnig -Normaal -Maksimum -Ultra -4060 -Lêers byvoeg en vervang -Lêers bywerk en byvoeg -Verfris bestaande lêers -Sinkroniseer lêers -4070 -Blaai -Alle lêers - - -6000 -Kopieer -Verskuif -Kopieer na: -Verskuif na: -Besig met kopiëring... -Besig met verskuiwing... -Besig met hernoeming... - -Bewerking word nie ondersteun nie. -Fout by hernoeming van lêer of gids - - -6100 -Bevestig lêerverwydering -Bevestig gidsverwydering -Bevestig verwydering van meerdere lêers -Is u seker dat u '{0}' wil verwyder? -Is u seker dat u gids '{0}' asook die inhoud daarvan wil verwyder? -Is u seker dat u hierdie {0} items wil verwyder? -Besig met verwydering... -Fout by verwydering van lêer of gids - -6300 -Maak gids -Maak lêer -Naam van die gids: -Lêernaam: -Nuwe gids -Nuwe lêer -Fout by maak van gids -Fout by maak van nuwe lêer -6400 - - -Selekteer -Deselekteer -Masker: -6600 - -Gidse-geskiedenis -Diagnostiese boodskappe -Boodskap -7100 -Rekenaar -Network - -Stelsel -7200 -Voeg by -Pak uit -Toets -Kopiëer -Skuif -Vee uit -Intigting -7300 -Verdeel lêer -&Verdeel na: -Verdeel in &volumes, aantal grepe: -Besig met verdeling... - - - - - -7400 -Kombineer lêers -&Kombineer na: -Besig met kombinering... - - - -7500 - - - - -7600 -Meet -Geheuegebruik: -Inpakking -Uitpakking -Gradering -Totale gradering -Huidige -Resultaat - - -Lopies: diff -Nru p7zip-rar-16.02/GUI/Lang/an.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/an.txt --- p7zip-rar-16.02/GUI/Lang/an.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/an.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Feliciano Martínez Tur -; 9.07 : Juan Pablo Martínez -; -; -; -; -; -; -; -; -; -0 -7-Zip -Aragonese -Aragonés -401 -Acceptar -Cancelar - - - -&Sí -&No -&Zarrar -Aduya - -&Continar -440 -Sí a &tot -No a t&ot -Aturar -Tornar a empecipiar -Se&gundo plano -P&rimer plano -&Pausa -Aturau -Yes seguro que quiers cancelar? -500 -&Fichero -&Editar -&Veyer -&Favoritos -&Ferramientas -Ad&uya -540 -&Ubrir -Ubrir &adintro -Ubrir &difuera -&Veyer -&Editar -Re&nombrar -&Copiar en... -&Mover ta... -&Borrar -Di&vidir o fichero... -C&ombinar os fichers... -&Propiedatz -Comen&tario -Calcular a suma de comprebación -Diff -Creyar carpeta -Creyar fichero -&Salir -600 -Seleccionar-lo &tot -Deseleccionar-lo tot -&Invertir selección -Seleccionar... -Deseleccionar... -Seleccionar por tipo -Deseleccionar por tipo -700 -Iconos g&rans -&Iconos chicotz -&Lista -&Detalles -730 -Desordenau -Anvista plana -&2 panels -&Barras de ferramientas -Ubrir a carpeta radiz -Carpeta mai -Historial de carpetas... -&Esviellar -750 -Barra de ferramientas d'archivo -Barras de ferramientas estandard -Botons grans -Amostrar texto en os botons -800 -&Adhibir carpeta a favoritos como -Adhibir a favoritos -900 -&Opcions... -&Prebas de referencia (benchmark) -960 -&Conteniu... -A&rredol de 7-Zip... -1003 -Rota -Nombre -Tipo de fichero -Carpeta -Grandaria -Grandaria comprimida -Atributos -Creyau -Zaguer acceso -Zaguera modificación -Compacto -Comentario -Zifrau -Expandiu antis -Expandiu dimpués -Diccionario -CRC -Tipo -Anti -Metodo -SO d'orichen -Sistema de fichers -Usuario -Grupo -Bloque -Comentario -Posición -Prefixo de rota -Carpeta -Fichers -Versión -Fragmento -Multiframento -Desplazamiento -Vinclos -Bloques -Fragmentos - -64-bit -Big-endian -CPU -Grandaria fisica -Grandaria d'as cabeceras -Suma de comprebación -Caracteristicas -Adreza virtual -ID -Nombre curto -Aplicación creyadera -Grandaria de sector -Modo -Vinclo -Error -Espacio total -Espacio libre -Grandaria de sector -Etiqueta -Nombre local -Proveyedor -2100 -Opcions -Luenga -Luenga: -Editor -&Editor: -&Diff: -2200 -Sistema -Asociar 7-Zip con: -2301 -Integrar 7-Zip en o menú contextual de Windows -Menú contextual en cascada -Elementos d'o menú contextual: -2320 - - -Ubrir archivo -Extrayer-ne os fichers... -Adhibir a l'archivo... -Comprebar l'archivo -Extrayer aquí -Extrayer en {0} -Adhibir a {0} -Comprimir y ninviar por correu... -Comprimir en {0} y ninviar por correu -2400 -Carpeta -Carpeta de &treballo -Carpeta temporal d'o &sistema -Carpeta &actual -&Especificar una carpeta: -No emplegar que ta dispositivos extrayibles -Especificar una carpeta ta archivos temporals. -2500 -Propiedatz -Amostrar l'elemento ".." -Amostrar iconos propios -Amostrar o menú d'o sistema -&Seleccionar ringlera(s) completa(s) -Amostrar as linias d'a &quadricla -Clicar una vegada ta ubrir elemento -Modo de selección &alternativo -Emplegar pachinas de memoria &grans -2900 -Arredol de 7-Zip -7-Zip ye un programa libre y gratuito. Si quiers, puetz colaborar en o desembolique de 7-Zip rechistrando-te ta contribuyir a amillorar o programa. -3000 -O sistema no ha puesto asignar a cantidat necesaria de memoria -No i hai errors -{0} elemento(s) seleccionau(s) -No se puet creyar a carpeta '{0}' -Ista mena d'archivo no permite actualización. -No se puet ubrir o fichero '{0}' como archivo comprimiu -No se puet ubrir l'archivo zifrau '{0}'. Comprebe si a clau ye incorrecta. -Tipo d'archivo no admeso -O fichero {0} ya existe -O fichero '{0}' s'ha modificau.\nQuiers esviellar-lo en l'archivo? -No se puet esviellar o fichero\n'{0}' -No se puet executar l'editor. -O fichero pareix un virus (o nombre d'o fichero contiene espacios largos). -No se puet execitar ista operación dende una carpeta que tienga una rota larga. -Has de seleccionar un fichero -Has de seleccionar un u más fichers -Masiaus elementos -3300 -Extrayendo -comprimindo -Prebando -Ubrindo... -Buscando... -3400 -Extrayer -E&xtrayer a: -Selecciona un destín ta os fichers extrayius. -3410 -Modo de rota -Rotas completas -Sin rotas -3420 -Modo de sobrescritura -Con confirmación -Sin confirmación -Conservar os fichers ya existents -Renombrar automaticament -Renombrar automaticament os fichers ya existents -3500 -Confirmar a substitución de fichers -A carpeta de destín ya contiene un fichero con o mesmo nombre. -Quiers substituyir o fichero existent -por iste atro? -{0} bytes -Renombrar a&utomaticament -3700 -Metodo de compresión no valido ta '{0}'. -Error de datos en '{0}'. O fichero ye corrompiu. -O CRC ha fallau en '{0}'. O fichero ye corrompiu. -Error de datos en o fichero zifrau '{0}'. Verifica a clau. -Error de CRC en o fichero zifrau '{0}'. Verifica a clau. -3800 -Escribe a clau -Escribe a clau: -Torne a escribir a clau: -&Amostrar a clau -As claus son diferents. Por favor, torne a escribir-la. -Emplega en a clau nomás as letras de l'alfabeto anglés, numeros y caracters especials (!, #, $, ...) -A clau ye masiau larga. -Contrasenya -3900 -Tiempo transcorriu: -Tiempo pendient: -Grandaria: -Velocidat: -Procesau: -Razón de compresión: -Errors: -Archivos: -4000 -Adhibir a l'archivo -&Archivo: -M&odo d'actualización: -&Formato d'archivo: -&Libel de compresión: -&Metodo de compresión: -Grandaria de &diccionario: -Granda&ria d'a parola: -Grandaria de bloque compacto: -Numero de filos d'a CPU: -&Parametros: -Opcions -Creyar archivo SF&X (autoextrayible) -Comprimir fichers compartius -Encriptación -Metodo d'e &zifrau: -Zifrar &nombres de fichero -Memoria emplegada ta comprimir: -Memoria emplegada ta descomprimir: -4050 -Sin compresión -A mas rapida -Rapida -Normal -Maxima -Ultra -4060 -Adhibir y substituyir fichers -Esviellar y adhibir-ie fichers -Esviellar fichers ya presents -Sincronizar fichers -4070 -Explorar -Totz os fichers -No compacto -Compacto -6000 -Copiar -Mover -Copiar en: -Mover ta: -Copiando... -Movendo... -Renombrando... -Selecciona a carpeta de destín -Operación no permitida. -Error en enombrar un fichero u carpeta -Confirmar a copia d'o fichero -Yes seguro de que quiers copiar os fichers en l'archivo -6100 -Confirmar borrau de fichero -Confirmar borrau de carpeta -Confirmar borrau multiple fichers -Yes seguro que quiers borrar '{0}'? -Yes seguro que quiers borrar a carpeta '{0}' y tot o suyo conteniu? -Yes seguro que quiers borrar istos {0} elementos? -Borrando... -Error borrando fichero u carpeta -O sistema no puet mover un fichero con rota larga ta la Papelera de Reciclache -6300 -Creyar carpeta -Creyar fichero -Nombre de'a carpeta: -Nombre de'o fichero: -Carpeta nueva -Fichero nuevo -Error en creyar carpeta -Error en creyar o fichero: -6400 -Comentario -&Comentario: -Seleccionar -Deseleccionar -Patrón: -6600 -Propiedatz -Historial de carpetas -Mensaches de diagnostico -Mensache -7100 -O mío ordinador -Entorno de ret -Documentos -Sistema -7200 -Adhibir -Extrayer -Prebar -Copiar -Mover -Borrar -Información -7300 -Dividir fichero -Di&vidir a: -Dividir en fra&gmentos (bytes): -Dividindo... -Confirmar a división -Yes seguro que quiers dividir o fichero en {0} fragmentos? -A grandaria d'os fragmentos ha d'estar menor que a d'o fichero orichinal -Grandaria de fragmento incorrecta -Grandaria de fragmento especificada: {0} bytes.\nYe seguro que quiere dividir o fichero en fragmentos d'ixa grandaria? -7400 -Combinar fichers -&Combinar en: -Combinando... -Selecciona només o primer fichero -No s'ha puesto detectar o fichero como parti d'un fichero por fragmentos -No s'ha puesto trobar que un fragmento d'o fichero por fragmentos -7500 -Calculando a suma de verificación... -Suma de verificación (CRC) -CRC d'os datos: -CRC d'os datos y os nombres: -7600 -Prebas de referencia (benchmark) -Emplego de memoria: -Compresión -Descompresión -Taxa -Taxa total -Actual -Resultant -Emplego de CPU -Taxa / Emplego -Pasadas: diff -Nru p7zip-rar-16.02/GUI/Lang/ar.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ar.txt --- p7zip-rar-16.02/GUI/Lang/ar.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ar.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Awadh A Al-Ghaamdi -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Arabic -عربي -401 -حسنا -إلغاء الأمر - - - -&نعم -&لا -&إغلاق -تعليمات - -&استمرار -440 -نعم للكل -لا للكل -إيقاف -إعادة تشغيل -&بالمؤخرة -&بالمقدمة -&إيقاف مؤقت -متوقف مؤقتا -هل أنت متأكد من الإلغاء؟ -500 -&ملف -&تحرير -&عرض -تف&ضيلات -&أدوات -&تعليمات -540 -&فتح -&فتح بالداخل -&فتح للخارج -&عرض -&تحرير -إعادة تسمية -..نسخ إلى -..نقل إلى -&حذف -&تقسيم الملف... -دم&ج الملفات... -خ&صائص -تعليق& -حساب مجموعة إختبارية -فرق -إنشاء مجلد -إنشاء ملف -خروج -600 -تحديد الكل -عدم تحديد الكل -عكس التحديد -تحديد -عدم تحديد -تحديد حسب النوع -عدم تحديد حسب النوع -700 -رموز كبيرة -رموز صغيرة -&قائمة -&تفصيل -730 -عشوائي -عرض مسطح -&لائحتين -&أشرطة الأدوات -فتح المجلد الرئيسي -للأعلى بمستوى واحد -...محفوظات المجلدات -&تحديث -750 -شريط أدوات الأرشفة -شريط أدوات قياسي -أزرار كبيرة -إظهار التسميات النصية -800 -&إضافة المجلد للمفضلة باسم -المفضلة -900 -...&خيارات -&تقييم الأداء -960 -..&المحتويات -7-Zip &حول... -1003 -المسار -الإسم -الإمتداد -المجلد -الحجم -الحجم المحزوم -الخواص -الإنشاء -الدخول -التعديل -ثابت -بتعليق -مشفر -التقسيم قبل -التقسيم بعد -المعجم -CRC -النوع -متعدد -الطريقة -نظام التشغيل -نظام الملفات -المستخدم -المجموعة -الكتلة -التعليق -المكان -بادئة المسار -المجلدات -الملفات -الإصدار -وحدة التخزين -وحدة تخزين متعددة -التعويض -روابط -كتل -وحدات تخزين - -64-bit -Big-endian -CPU -الحجم الطبيعي -حجم المقدمات -عينة إختبار -المواصفات -العنوان الظاهري -الهوية -إسم قصير -برنامج التأليف -حجم القطاع -الوضعية -رابط -خطأ -الحجم الكلي -المساحة الفارغة -حجم الجزء -المسمى -الإسم المحلي -الموفر -2100 -خيارات -اللغة -ترجمة الأستاذ عوض آل-عائض الغامدي -المحرر -&المحرر: -ال&فرق: -2200 -النظام -تكامل البرنامج مع : -2301 -الإندماج مع قائمة سياق القشرة -تتالي قائمة سياق القشرة -عناصر قائمة سياق القشرة: -2320 -<مجلد> -<إرشيف> -فتح -استخراج الملفات... -إضافة إلى الإرشيف... -فحص الإرشيف -إستخراج هنا -إستخراج إلى {0}ـ -إضافة إلى {0}ـ -ضغط ثم إرسال... -ضغط إلى {0} ثم إرسال -2400 -مجلدات -&مجلد العمليات -&مجلد النظام المؤقت -&حالي -&معين: -الإستخدام فقط للأقراص المتحركة -تحديد موضع للإرشيف المؤقت للملفات -2500 -إعدادات -".." إظهار مادة -إظهار أيقونات الملف الفعلية -إظهار قائمة النظام -&تحديد الصف بالكامل -إظهار خطوط الشبكة -نقرة واحدة لفتح أي مادة -&نظام تحديد بديل -إستعمال &صفحات ذاكرة كبيرة -2900 -معلومات -رغم أن البرنامج مجاني، فإن أعجبك وأردت دعم تطويرات مستقبلية، يرجى ترخيصه بدفع 20 دولاراً. من الممكن استخدام بطاقة الائتمان أو أي طرق دفع أخرى -3000 -لا يمكن للنظام تخصيص الكمية المطلوبة للذاكرة -لا يوجد أخطاء -تم تحديد {0} عنصر -'{0}' لا يمكن إنشاء المجلد -تحديث العمليات غير مدعوم لهذا الإرشيف -كأرشيف '{0}' لا يمكن فتح الملف -كلمة المرور خطأ ؟ . '{0}' تعذر فتح الأرشيف المشفر -نوع أرشيف غير معتمد -موجود مسبقا {0} الملف -أتريد تحديثه في الإرشيف ؟\nالملف '{0}' تم تعديله -لا يمكن تحديث الملف\n'{0}' -لا يمكن بدء المحرر -(الملف يشبه فيروس (إسم الملف يحتوي على مسافات طويلة -لا يمكن إستدعاء العملية من مجلد له مسار طويل -يجب تحديد ملف واحد -يجب تحديد ملف واحد أو أكثر -عناصر كثيرة جداً -3300 -استخراج -الضغط -فحص -...فـتـح... -...يتم التفحص -3400 -استخراج -استخراج إلى: -تحديد الموضع للملفات المستخرجة -3410 -حالة المسار -اسم المسار بالكامل -بدون اسم المسار -3420 -حالة إعادة الكتابة -السؤال قبل إعادة الكتابة -إعادة الكتابة بدون تنبيه -تجاوز الملفات المتوفرة -تسمية تلقائية -تسمية الملفات الموجودة تلقائياً -3500 -تأكيد استبدال الملف -المجلد الهدف يحوي مسبقاً الملف -أتريد استبدال الملف الموجود؟ -بهذا الملف؟ -{0} بايت -إعادة تسمية تلقائية -3700 -'{0}'طريقة ضغط غير معتمدة لـ -'{0}'خطأ بيانات في. الملف تالف -'{0}' خطأ بصمة في . الملف تالف -خطأ بيانات في الملف المشفر '{0}' . كلمة المرور غير صحيحة ؟ -فشل الفحص الدوري في الملف المشفر '{0}' . كلمة المرور غير صحيحة ؟ -3800 -أدخل كلمة المرور -أدخل كلمة المرور: -إعادة كلمة المرور : -&إظهار كلمة المرور -كلمتا المرور غير متطابقتان -أستخدم فقط حروف إنجليزية و أرقام و علامات خاصة (!,#,,$ ...) لكلمة المرور -كلمة المرور طويلة جدا -كلمة المرور -3900 -الزمن المنقضي: -الزمن المتبقي: -الحجم الكلي: -السرعة: -المعالج: -نسبة الضغط: -الأخطاء: -ملفات الإرشيف: -4000 -إضافة للإرشيف -&الإرشيف: -&حالة التحديث: -صيغة الإرشيف: -مستوى الضغط&: -طريقة الضغط: -&حجم المعجم: -&حجم الكلمة: -حجم الكتلة الخاصة : -CPU عدد مؤشرات الـ : -&أوامر إضافية: -خيارات -إنشاء إرشيف ذاتي الإستخراج -ضغط الملفات المشاركة -التشفير -طريقة التشفير : -تشفير أسماء ال&ملفات -إستهلاك الذاكرة للضغط : -إستهلاك الذاكرة لإلغاء الضغط : -4050 -تخزين -أسرع -سريع -عادي -مرتفع -أقصى -4060 -إضافة واستبدال الملفات -تحديث و إضافة الملفات -تجديد الملفات المتوفرة فقط -مزامنة الملفات -4070 -إستعراض -كافة الملفات -غير خالص -خالص -6000 -نسخ -نقل -نسخ إلى: -نقل إلى: -...نـسـخ... -...نـقـل... -إعادة تسمية... -تحديد مجلد الوجهة -العملية غير معتمدة -حدوث خطأ لدي إعادة تسمية الملف أو المجلد -تأكيد نسخ الملف -هل أنت متأكد من نسخ الملفات للإرشيف؟ -6100 -تأكيد الحذف للملف -تأكيد الحذف للمجلد -تأكيد الحذف للملفات -'؟ {0}'هل أنت متأكد من حذف -هل أنت متأكد من حذف المجلد '{0}' و كافة محتوياته ؟ -؟ {0} هل أنت متأكد من حذف العناصر التالية -حذف... -حدوث خطأ لدي حذف الملف أو المجلد -لا يمكن للنظام نقل ملف له مسار طويل إلى سلة المحذوفات -6300 -إنشاء مجلد -إنشاء ملف -اسم المجلد: -اسم الملف: -مجلد جديد -ملف جديد -حدوث خطأ لدي إنشاء المجلد -حدوث خطأ لدي إنشاء الملف -6400 -تعليق -&تعليق: -تحديد -عدم تحديد -إخفاء -6600 -خصائص -محفوظات المجلدات -رسائل الفاحص -رسالة -7100 -جهاز الكمبيوتر -الشبكة -المستندات -النظام -7200 -إضافة -إستخراج -فحص -نسخ -نقل -حذف -معلومات -7300 -تقسيم الملف -&التقسيم إلى: -التقسيم لكتل أو بايتات: -تقسيم... -تأكيد التقسيم -هل تريد فعلا تقسيم الملف إلى {0} كتلة ؟ -يجب أن يكون حجم الكتلة أصغر من حجم الملف الأصلي -كتلة الحجم غير صحيحة -حجم الكتلة المعين : {0} بايت\nهل تريد فعلا تقسيم الأرشيف إلى مثل هذه الكتل ؟ -7400 -دمج الملفات -&دمج إلى: -دمج... -حدد فقط الجزء الأول من ملف التقسيم -لا يمكن إكتشاف الملف كجزء من ملف التقسيم -لا يمكن العثور على أكثر من جزء واحد من ملف التقسيم -7500 -...يتم حساب مجموعة الإختبار -معلومات مجموعة الإختبار -للبيانات CRC مجموعة الإختبار: -للبيانات و للأسماء CRC مجموعة الإختبار: -7600 -تقييم الأداء -إستخدام الذاكرة: -ضغط -فك ضغط -المعدل -المعدل الكلي -الحالي -الناتج -CPU إستهلاك الـ -التقدير / الإستهلاك -العمليات: diff -Nru p7zip-rar-16.02/GUI/Lang/ast.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ast.txt --- p7zip-rar-16.02/GUI/Lang/ast.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ast.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.07 : Dinamiteru -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Asturian -Asturianu -401 -Val -Torgar - - - -&Si -&Non -&Zarrar -Axuda - -&Siguir -440 -Si a &Too -Non a T&oo -Parar -Reentamar -&De fondu -&En primer planu -&Posar -Posao -¿Tas fixu que quies paralo? -500 -F&icheru -&Remanar -&Ver -F&avoritos -&Ferramientes -A&xuda -540 -&Abrir -Abrir &Dientro -Abrir F&uera -&Ver -&Remanar -Reno&mar -&Copiar a... -&Mover a... -&Borrar -&Partir ficheru... -Com&binar ficheros... -P&ropiedaes -Come&ntariu - - -Crear carpeta -Crear ficheru -Co&lar -600 -Seleicionar &Too -Deseleicionar too -&Invertir seleición -Seleicionar... -Deseleicionar... -Seleicionar por Tipu -Deseleicionar por Tipu -700 -Miniatures &Grandes -&Miniatures Pequeñes -&Llista -&Detalles -730 -Ensín Ordenar - -&2 Paneles -&Barres de Ferramientes -Abrir Carpeta Raiz -Xubir Un Nivel -Hestorial de Carpetes... -Actualiza&r -750 -Barra Ferramientes d´Archivu -Barra Ferramientes Normal -Botones Grandes -Amosar Testu nos Botones -800 -&Añedir carpeta a Favoritos como -Marca -900 -&Opciones... -&Bancu de Pruebes -960 -&Conteníos... -&Al rodiu 7-Zip... -1003 -Ruta -Nome -Estensión -Carpeta -Tamañu -Tamañu comprimío -Atributos -Creao -Accedío -Cambiao -Sólidu -Comentao -Cifrao -Partir antes -Partir dempués -Diccionariu -CRC -Tipu -Anti -Métodu -S.O. d´Acoyida -Sistema de ficheros -Usuariu -Grupu -Bloque -Comentariu -Posición - - - - - - - - - - - - - - - - - - - - - - - - - -Error -Tamañu total -Espaciu llibre -Tamañu del clúster -Etiqueta -Nome llocal -Suministrador -2100 -Opciones -Llingua -Llingua: -Remanaor -&Remanaor: - -2200 -Sistema -Asociar 7-Zip con: -2301 -Integrar 7-Zip nel menú contestual -Menú contestual en ´cascada´ -Artículos del menú contestual: -2320 - - -Abrir archivu -Estrayer ficheros... -Añedir al archivu... -Probar archivu -Estrayer equí -Estrayer a {0} -Añedir a {0} -Comprimir y mandar per correu... -Comprimir en {0} y mandar per correu -2400 -Carpetes -&Carpeta de trabayu -Carpeta &temporal de sistema -&Actual -&Especificar: -Usar sólo pa dispositivos estrayibles -Especificar llocalización pa ficheros d´archivos temporales. -2500 -Igües -Amosar ".." artículu -Amosar les miniatures reales del ficheru -Amosar menú del sistema -Seleicionar tola &fila -Amosar les llinies de la &cuadrícula - - - -2900 -Al rodiu 7-Zip -7-Zip ye software llibre. De toos moos, tú pues sofitar el desendolcu de 7-Zip rexistrándote. -3000 - -Ensín errores -{0} oxetu(os) seleicionaos -Nun se puede crear la carpeta '{0}' -Esti archivu nun permite les operaciones d´actualización. - - - - -El ficheru '{0}' foi modificáu.\nDo ¿Quies actualizalu nel archivu? -Nun se pudo actualizar l´archivu\n'{0}' -Nun se pudo entamar el Remanaor. - - - - -Demasiaos artículos -3300 -Estrayendo -Comprimiendo -Probando -Abriendo... - -3400 -Estrayer -E&strayer a: -Especificar llocalización pa ficheros estrayíos. -3410 -Mou de ruta -Nomes de ruta completos -Ensín nomes de ruta -3420 -Mou de sobreescritura -Entrugar enantes de sobreescribir -Sobreescribir ensín confirmación -Dexar ficheros esistentes -Auto renomar -Auto renomar ficheros esistentes -3500 -Confirmar sustitución de ficheros -La carpeta destín yá tien el ficheru procesáu. -¿Quiés sustituyir el ficheru esistente -con esti otru? -{0} bytes -A&uto Renomar -3700 -Métodu de compresión nun permitíu pa '{0}'. -Error de datos en '{0}'. El ficheru ta rotu. -El CRC falló en '{0}'. El ficheru ta rotu. - - -3800 -Introduz clave -Introduz clave: - -Amo&sar clave - - - -Clave -3900 -Tiempu trescurríu: -Tiempu pa finar: -Tamañu: -Velocidá: - - -Errores: - -4000 -Añedir al archivu -&Archivu: -Mo&u d´actualización: -&Formatu del archivu: -Nive&l de compresión: -&Métodu de compresión: -Tamañu del &Diccionariu: -Tamañu de la pa&llabra: - - -&Parámetros: -Opciones -Crear archivu SF&X - - - -Cifrar &nomes de ficheru -Usu de memoria pa la compresión: -Usu de memoria pa la descompresión: -4050 -Nenguna -Más rápida -Rápida -Normal -Másima -Ultra -4060 -Añedir y sustituyir ficheros -Actualizar y añedir ficheros -Actualizar ficheros esistentes -Sincronizar ficheros -4070 -Agüeyar -Tolos ficheros - - -6000 -Copiar -Mover -Copiar a: -Mover a: -Copiando... -Moviendo... -Renomando... - -La operación nun tá permitía. -Error al renomar el ficheru o carpeta - - -6100 -Confirmar Borráu de Ficheru -Confirmar Borráu de Carpeta -Confirmar Borráu Múltiple de Ficheros -¿Tas fixu que quies borrar '{0}'? -¿Tas fixu que quies borrar la carpeta '{0}' y tolos sos conteníos? -¿Tas fixu que quies borrar estos {0} artículos? -Borrando... -Error al borrar el ficheru o carpeta - -6300 -Crear Carpeta -Crear ficheru -Nome de la carpeta: -Nome del ficheru: -Nueva carpeta -Nuevu ficheru -Error al crear la carpeta -Error al crear el ficheru -6400 -Comentariu -&Comentariu: -Seleicionar -Deseleicionar -Mazcarita: -6600 - -Hestorial de carpetes -Mensaxes de diagnósticu -Mensax -7100 -Ordenador -Rede de Trabayu - -Sistema -7200 -Añedir -Estrayer -Probar -Copiar -Mover -Borrar -Información -7300 -Partir Ficheru -&Partir a: -Partir en &cachos, bytes: -Partiendo... - - - - - -7400 -Combinar Ficheros -&Combinar a: -Combinando... - - - -7500 - - - - -7600 -Bancu de Pruebes -Usu de memoria: -Comprimiendo -Descomprimiendo -Valoración -Valoración total -Actual -Resultáu - - -Correutos: diff -Nru p7zip-rar-16.02/GUI/Lang/az.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/az.txt --- p7zip-rar-16.02/GUI/Lang/az.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/az.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : F@rhad -; 15.02 : 22/05/2015 : Г. Гасымов -; -; -; -; -; -; -; -; -; -0 -7-Zip -Azerbaijani -Azərbaycanca -401 -OLDU -İmtina - - - -&Bəli -&Xeyr -&Bağla -Kömək - -&Davam -440 -&Hamısına Bəli -Ha&mısına Xeyr -Dayan -Yenidən başla -&Arxa planda -Ö&ndə -F&asilə -Fasilədə -Həqiqətən əməliyyatı dayandırmaq istəyirsiniz? -500 -&Fayl -&Düzəliş -&Görünüş -S&eçilmişlər -&Vasitələr -&Arayış -540 -&Aç -&Daxildə Aç -B&ayırda aç -&Baxış -&Düzəliş -Ye&nidən Adlandır -&Nüsxələ... -&Köçür... -&Sil -Faylı &Böl... -Faylları B&irləşdir... -X&üsusiyyətlər -Şər&h... -Yoxlama Cəmi -Müqayisə -Qovluq Yarat -Fayl Yarat -Ç&ıxış -İstinad -&Əvəzedici Axınlar -600 -&Hamısını Seç -Seçimi Ləğv Et -&Seçimi Çevir -Seç... -Seçimi Ləğv Et... -Növünə Görə Seç -Növünə Görə Seçimi Ləğv Et -700 -&Böyük İşarələr -K&içik İşarələr -&Siyahı -&Cədvəl -730 -Çeşidsiz -Müstəvi Görünüş -&2 Lövhə -&Alətlər Lövhələri -Kök Qovluğu Aç -Bir Səviyyə Yuxarı -Qovluqlar Tarixçəsi... -&Yenilə -Bilavasitə Yeniləmə -750 -Arxivləyicinin Düymələr Lövhəsi -Sadə Düymələr Lövhəsi -Böyük Düymələr -Düymələr Üzərində Mətnlər -800 -&Qovluğu Seçilmişlərə Fərqli Əlavə Et -Əlfəcin -900 -Tənzimləmələr... -Səmərə Sınağı -960 -&Başlıq... -7-Zip &Haqqında... -1003 -İstiqamət -Ad -Genişləmə -Qovluq -Ölçü -Sıxılmış -Rəmzlər -Yaranıb -Açıq -Dəyişilib -Aramsız -Şərh -Şifrələnib -Əvvəlki parça -Sonrakı parça -Lüğət - -Növ -Əleyhinə -Sıxılma Üsulu -Quruluş -Fayl Quruluşu -İstifadəçi -Dəstə -Bölmə -Şərh -Mövqe -İstiqamət -Qovluq -Fayl -Buraxılış -Cild -Çox Cildli -Uzlaşma -İstinad -Bölmə -Cild - - - -Prosessor -Fiziki Ölçü -Başlıqlar Ölçüsü -Yoxlama Cəmi -Xassələr -Xəyali Ünvan - -Qısa Ad -Yaradıcı -Sahə Ölçüsü -Vəziyyət -Rəmzi İstinad -Xəta -Cəmi Həcm -Azad Həcm -Toplam Həcm -Nişan -Qısa Ad -Təchizatcı -NT Təhlükəsizlik -Əvəzedici Axın - -Silinmiş -Ağac - - -Xəta Növü -Xətalar -Xətalar -Xəbərdarlıqlar -Xəbərdarlıq -Axınlar -Əvəzedici Axınlar -Əvəzedici Axınlar Ölçüsü -Xəyali Ölçü -Ceşidli Ölçü -Ümumi Fiziki Ölçü -Cild Nömrəsi -Növaltı -Qısa Şərh -Şifrələnmiş Səhifə - - - -Qalıq Ölçüsü -Tətbiq Olunmuş Bölmə Ölçüsü -İstinad -Sərt İstinad -iNode - -Yalnız Oxumaq Üçün -2100 -Tənzimləmələr -Dil -Dil: -Düzəliş -&Düzəliş: -&Müqayisə: -2200 -Quruluş -7-Zip Fayllarla Əlaqələnsin -Bütün İstifadəçilər -2301 -7-Zip əhatə təklifinə tətbiq edilsin -Zəncirvari əhatə təklifi -Ünsürlü əhatə təklifi: -Əhatə təklifində nişanlar -2320 - -<Аrxiv> -Arxivi Aç -Çeşidlə -Arxivə Əlavə Et... -Sınaq -Burda Çeşidlə -{0} Çeşidlə -{0} Əlavə Et -Sıx Və E-Poçtla Göndər... -{0} Sıx Və E-Poçtla Göndər -2400 -Qovluqlar -&İş Qovluğu -&Müvəqqəti Quruluş Qovluğu -&Cari -&Təyin Et: -Yalnız dəyişkən daşıyıcılar üçün istifadə -Müvəqqəti arxivlər üçün yer göstər. -2500 -Tənzimləmələr -".." ünsürünü göstər -Həqiqi fayl işarələri göstər -Quruluş təklifini göstər -Ox bütün sətir üzrə -Ayrıcıları Göstər -Bir Toxunuşla Aç -Əvəzedici vəziyyət işarələnməsi -Böyük yaddaş səhifələri istifadəsi -2900 -7-Zip Haqqında -7-Zip Sərbəst Yayılan Proqramdır -3000 -Kifayət qədər boş yaddaş yoxdur -Səhvlər tapılmadı -{0} Ayrılmış hədəf -'{0}' Qovluğunu yaratmaq mümkün olmadı -Bu arxiv üçün dəyişiklik əməliyatı dəstəklənmir -'{0}' Faylını arxiv kimi açmaq alınmadı -Şifrələnmiş '{0}' arxivini açmaq alınmadı. Yanlış şifrə? -Dəstəklənməyən arxiv -{0} faylı artıq mövcuddur -'{0}' faylına dəyişiklik edildi.\nSiz onu arxivdə yeniləmək istəyirsiz? -\n'{0}' faylını yeniləmək alınmadı -Redaktəni işə salmaq alınmadı -Fayl zərərvericiyə oxşayır (faylın adı uzun boşluq ardıcıllığı təşkil edir). -Əməliyyat uzun yol təşkil edən qovluqdan icra oluna bilmir. -Siz bir fayl seçməlisiniz -Siz bir və ya bir neçə fayl seçməlisiniz -Həddən çox ünsür -Faylı, '{0}' arxivi kimi açmaq alınmadı -Fayl, {0} arxivi kimi açıldı -Arxiv əvəzlənərək açıldı -3300 -Çeşidlənmə -Sıxılma -Sınaq -Açılma... -Yoxlama... -Silinmə -3320 -Əlavə Etmək -Yenilənmə -Təhlil -Nüsxələnmə -Yenidən Çeşidlənmə -Keçmə İcazəsi -Silinmə -Başlıqlar Yaradılması -3400 -Ayır -Ç&eçidlə: -Ayrılan faylların yerini göstərin. -3410 -Fayllara istiqamət: -Tam istiqamətlər -İstiqamətsiz -Mütləq istiqamətlər -Nisbi istiqamətlər -3420 -Yenidən yazılma: -Təsdiqli -Təsdiqsiz -Ötürmək -Birbaşa yenidən adlandır -Mövcud olanları yenidən adlandır -3430 -Kök qovluqla bənzərliyi aradan qaldır -Faylın təhlükəsizlik bərpası -3500 -Faylın əvəzlənmə təsdiqi -Qovluq artıq emal olunan fayl təşkil edir. -Mövcud faylı əvəzlə -növbəti faylla? -{0} bayt -Birbaşa yenidən adlandır -3700 -'{0}' faylının dəstəklənməyən sıxılma üsulu. -'{0}' məlumatlarında xəta. Fayl korlanıb. -'{0}' CRC xətası. Fayl korlanıb. -'{0}' şifrəli fayl məlumatlarında xəta. Yanlış şifrə? -'{0}' şifrəli faylı üçün CRC xətası. Yanlış şifrə? -3710 -Yanlış şifrə? -3721 -Dəstəklənməyən sıxılma üsulu -Dəlillərdə xəta -CRC xətası -Mövcud olmayan dəlillər -Dəlillərin gözlənilməz sonu -Bölmənin sonunda faydalı dəlillər olduğuna dəlillər var -Arxiv deyil -Başlıqlarda Xəta -Yanlış şifrə -3763 -Arxivin əvvəli mövcud deyil -Təsdiqsiz arxiv əvvəli - - - -Dəstəklənməyən xüsusiyyət -3800 -Şifrə daxil etmə -&Şifrə daxil edin: -Şifrəni təkrarlayın: -&Şifrəni göstər -Şifrələr uyğun deyil -Şifrə üçün yalnız latın hərfləri, rəqəmlər və xüsusi rəmzlər istifadə edin (!, #, $, ...) -Şifrə şox uzundur -&Şifrə -3900 -Keçdi: -Qalıb: -Cəmi: -Sürət: -Ölçü: -Sıxılma dərəcəsi: -Xəta: -Arxiv: -4000 -Arxivə əlavə etmək -&Arxiv: -&Dəyişmə vəziyyəti: -Arxiv &qismi: -Sıxılma &dərəcəsi: -Sıxılma &üsulu: -&Lüğət ölçüsü: -&Söz ölçüsü: -Bölmə ölçüsü: -Axın sayı: -&Nizamlar: -&Seçimlər -SF&X arxiv yarat -Yazılış üçün açıq faylları sıx -Şifrələmə -Şifrələmə üsulu: -Fayl adlarını &şifrələ -Qablaşdırma üçün yaddaş həcmi: -Çeşidləmə üçün yaddaş həcmi: -Sıxılmadan sonra faylları sil -4040 -Rəmzli keçidləri saxla -Sərt keçidləri saxla -Əvəzedici axınları saxla -Giriş hüququnu saxla -4050 -Sıxılmasız -Sürətli -Cəld -Məqbul -Yüksək -Daha Yüksək (Ultra) -4060 -Əlavə et və əvəzlə -Yenilə və əlavə et -Yenilə -Eyniləşdir (Sinxron) -4070 -Vərəqlə -Bütün Fayllar -Fayl ölçüsünə görə -Aramsız -6000 -Nüsxələ -Köçür -Nüsxələ: -Köçür: -Nüsxələlənmə... -Köçürülmə... -Yenidən adlandırılma... -Qovluğu göstərin. -Əməliyyat bu qovluq üçün dəstəklənmir. -Fayl və ya Qovluğun Yenidən Adlandırılması Zamanı Xəta -Faylların Nüsxələlənmə Təsdiqi -Siz həqiqətən bu faylları arxivə nüsxələmək istəyirsiz -6100 -Fayl silinmə təsdiqi -Qovluq silinmə təsdiqi -Fayllar dəstəsinin silinmə təsdiqi -Siz həqiqətən "{0}" silmək istəyirsiz? -Siz həqiqətən "{0}" qovluğunu və onun bütün məzmununu silmək istəyirsiz? -Siz həqiqətən {0} hədəfi silmək istəyirsiz? -Silinmə... -Fayl və ya Qovluq Silinməsi Zamanı Xəta -Quruluş uzun yollu faylların səbətə silinməsi əməliyyatını dəstəkləmir -6300 -Qovluq Yarat -Fayl Yarat -Qovluq Adı: -Fayl Adı: -Yeni Qovluq -Yeni Fayl -Qovluq Yaradılması Zamanı Zəta -Fayl Yaradılması Zamanı Zəta -6400 -Şərh -&Şərh: -Seçin -Seçimi Ləğv Edin -Üzlük (Maska): -6600 -Xassələr -Qovluqlar Tarixçəsi -İsmarıclar -İsmarıc -7100 -Kompüter -Şəbəkə -Sənədlər -Quruluş -7200 -Əlavə Et -Ayır -Sınaq -Nüsxələ -Köçür -Sil -Məlumat -7300 -Fayl Bölmək -&Bölmək: -Cildlərə &bölmək, (bayt) ölçüdə: -Bölünmə... -Bölünmə Təsdiqi -Siz həqiqətən faylı {0} hissəyə bölmək istəyirsiz? -Cild ölçüsü ilkin fayl ölçüsündən kiçik olmalıdır -Cildlərin ölçü təyin etmə sahəsində xəta -Təyin edilmiş cild ölçüsü: {0} bayt.\nSiz həqiqətən arxivi belə cildlərə bölmək istəyirsiniz? -7400 -Faylları Birləşdir -&Birləşdirmək: -Birləşmə... -Bölünmüş faylın yalnız birinci hissəsini seçmək lazımdır -Bölünmüş faylın tanınması mümkün olmadı -Bölünmüş faylın birdən çox hissəsini tapmaq mümkün olmadı -7500 -Yoxlanma cəminin hesablanması... -Yoxlanma cəmi -Dəlillər üçün CRC yoxlanma cəmi: -Dəlillər və adlar üçün CRC yoxlanma cəmi: -7600 -Səmərə Sinağı -Yaddaş Həcmi: -Qablaşdırma -Çeşidlənmə -Dərəcə -Ümumi Dərəcə -Cari -Nəticə -Yüklənmə -Yüklənmə Dərəcəsi -Keçid: -7700 -İstinad -Əlaqələndir -Mənbə: -Məqsəd: -7710 -İstinad Qismi -Sərt İstinad -Rəmzi İstinad (Fayl) -Rəmzi İstinad (Qovluq) -Bağlantı Nöqtəsi (Qovşaq) diff -Nru p7zip-rar-16.02/GUI/Lang/ba.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ba.txt --- p7zip-rar-16.02/GUI/Lang/ba.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ba.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.20 : Haqmar : www.bashqort.com -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Bashkir -Башҡортса -401 -Тамам -Кире ал - - - -&Эйе -&Юҡ -&Яп -Ярҙам - -&Дауам -440 -Бөтәһенә лә Э&йе -Бө&тәһенә лә Юҡ -Туҡта -Яңынан башла -&Артҡы планда -А&лғы планда -&Туҡтатып тор -Паузала -Был эште ысынлап та өҙөргә теләйһегеҙме? -500 -&Файл -Һа&йлау -&Күренеш -Һ&айланмалар -&Сервис -&Белешмә -540 -&Асырға -&Эсендә асырға -&Тышта асырға -Ҡа&рау -&Мөхәррирләргә -&Исемен алыштырырға -&Күбәйтергә... -Кү&серергә... -&Юйырға -Файлды &бүл... -Файлдар бер&ләштереү... -Мәғ&лүмәт -Тас&уирлама -Тикшереү һаны -Diff -Яңы папка... -Яңы &файл... -С&ығырға -600 -&Бөтәһен дә һайларға -Һай&лауҙы кире алырға -Бил&дәләнгәндәрҙе кире әйләндерергә -Маска менән һайларға... -Һайлауҙы ябырға... -Төр буйынса һайларға -Төр буйынса һайлауҙы ябырға -700 -&Эре тамғалар -&Бәләкәй тамғалар -&Исемлек -&Ентекле -730 -Тәртип булмаһын -Барыһын да күрһәт -&2 Панель -&Ҡоралдар панеле -Төп папканы ас -Бер кимәл юғары -Папкалар тарихы... -&Яңырт -750 -&Архивлау төймәләре -Стандарт төймәләр -Эре төймәләр -Төймәләр аңлатмалы -800 -Ғәмәлдәге папканы һайланғандарға өҫтәргә: -Урын -900 -&Көйләү... -&Етештереүсәнлекте үлсәү -960 -&Эстәлек... -7-Zip &тураhында... -1003 -Юл -Исем -Киңәйеүе -Папка -Күләм -Архивдағы күләме -Атрибуттар -Яһалған -Асылған -Үҙгәртелгән -Өҙөлмәгән -Аңлатма -Серләнгән -Алдағы киҫәк -Киләһе киҫәк -Һүҙлек -CRC -Төр -Анти -Ысул -Система -Файл системаһы -Ҡулланыусы -Tөркөм -Блок -Тасуирлама -Урын -Юл префиксы -Папкалар -Файлдар -Версия -Том -Күп томлы -Шылыу -Һылтанмалар -Блоктар -Томдар - -64-bit -Big-endian -Процессор -Физик күләме -Башлыҡтар күләме -Тикшереү суммаһы -Характеристикалар -Виртуаль адрес -ID -Ҡыҫҡа исем -Яһаусы -Сектор күләме -Режим -Һылтанма -Хата -Бар күләм -Буш урын -Кластер күләме -Билдә -Урындағы Исем -Провайдер -2100 -Көйләүҙәр -Тел һайлау -Тел: -Мөхәррирләүсе -&Мөхәррирләүсе: -&Diff: -2200 -Система -7-Zip менән килештер: -2301 -Контекст менюла 7-Zip-ты күрһәтергә -Каскадлы контекст меню -Контекст меню элементтары: -2320 -<Папка> -<Архив> -Архивты асырға -Файлдар сығарыу... -Архивғ өҫтәргә... -Архивты һынарға -Бында сығарырға -{0} папкаһына сығарырға -{0} итеп архивла -Архивлап, e-mail менән ебәрергә... -{0} итеп архивларға һәм e-mail менән ебәрергә -2400 -Папкалар -&Эш папкаһы -&Ваҡытлыса система папкаһы -&Ағымдағы -&Билдәләргә: -Алмаш ташығыстар өсөн генә ҡулланырға -Ваҡытлыса архивтар өсөн урын күрһәтегеҙ. -2500 -Көйләүҙәр -".." элементы күренһен -Файлдарҙың ысын тамғалары күренһен -Система менюһы күренһен -Бөтә юл һайланһын -Һыҙыҡтар күренһен -Бер сиртеү менән асырға -Альтернатив һайлау ысулы -Ҙур хәтер биттәрен ҡуллан -2900 -7-Zip тураhында -7-Zip – ирекле таратылған программа. -3000 -Буш хәтер етмәй -Хата табылманы -{0} объект һайланған -{0} папкаһын яһап булмай -Был архивды үҙгәртеү ғәмәлен үтәп булмай. -'{0}' файлын архив һымаҡ асып булмай -Шифрланған '{0}' файлын асып булманы. Хаталы пароль? -Терәкләнмәгән архив төрө -{0} файлы бар -'{0}' файлы мөхәррирләнде.\nБыл файл архивда яңыртылһынмы? -Файлды яңыртып булманы\n'{0}' -Мөхәррирләүсене асып булманы. -Файл вирусҡа оҡшаған (файл исемендә бер-бер артлы килгән күп бушлыҡтар бар). -Ғәмәлде бындай оҙон юллы папканан үтәп булмай. -Бер файлды һайлау кәрәк -Бер йәки күберәк файлды һайлау кәрәк -Бик күп элемент -3300 -Сығарыу бара... -Ҡыҫыу бара... -Һынау -Асыла... -Тарау бара... -3400 -Сығар -Бында &сығар: -Сығарыласаҡ файлдар өсөн урын һайлағыҙ. -3410 -Юл исемдәре -&Тулы юл исемдәре -Юл исемдәре булмаһын -3420 -Өҫтөнә яҙыу -&Өҫтөнә яҙыу алдынан һора -&Өҫтөнә яҙыу алдынан һорама -Булған файлдарҙы үтеп кит -Яңы исем ҡуш -Булған файлдарға яңы исем ҡуш -3500 -Файл алмаштырыуҙы раҫлағыҙ -Сығарыласаҡ папкала эшкәртелгән файл бар. -Булған -файлын киләһе менән алыштырырғамы? -{0} байт -&Яңы исем ҡушылһын -3700 -'{0}' файлын ҡыҫыу ысулын табып булманы. -'{0}' файлында мәғлүмәт хатаһы бар. Файл боҙоҡ. -'{0}' файлында CRC хатаһы бар. Файл боҙоҡ. -Шифрланған '{0}' файлы мәғлүмәттәрендә хата. Хаталы пароль? -Шифрланған '{0}' файлында CRC хатаһы. Хаталы пароль? -3800 -Пароль керетеү -&Паролде керетегеҙ: -Па&ролде яңынан керетегеҙ: -П&ароль күренһен -Паролдәр тап килмәй -Пароль өсөн тик латин хәрефтәрен, һандарҙы һәм махсус символдарҙы (!, #, $, ...) ҡулланығыҙ -Пароль бик оҙон -Пароль -3900 -Үткән ваҡыт: -Ҡалған ваҡыт: -Барыһы: -Тиҙлек: -Күләм: -Ҡыҫыу нисбәте: -Хаталар: -Архив: -4000 -Архивлау -&Архив: -&Яңыртыу ысулы: -А&рхив төрө: -Ҡыҫыу &дәрәжәһе: -Ҡ&ыҫыу ысулы: -Һүҙ&лек күләме: -Һүҙ күлә&ме: -Блоктар күләме: -Ағымдар һаны: -&Параметрҙар: -&Көйләү -SFX ар&хивын яһау -Яҙыуға асыҡ файлдарҙы ҡыҫырға -Шифрлау -Шифрлау методы: -&Файл исемдәрен шифрла -Ҡыҫҡанда хәтер ҡулланыу: -Сығарғанда хәтер ҡулланыу: -4050 -Ҡыҫыуһыҙ -Бик тиҙ -Тиҙ -Ғәҙәти -Максимум -Ультра -4060 -Өҫтәргә һәм алмаштырырға -Яңыртырға һәм өҫтәргә -Яңыртырға -Синхронларға -4070 -Ҡарау -Бар файлдар -Файл күләме буйынса -Өҙөлмәгән -6000 -Копияһын ал -Күсер -Копия ҡуйыласаҡ урын: -Күсереләсәк урын: -Копияһын алыу... -Күсереү... -Яңынан исемләү бара... -Папканы күрһәтегеҙ. -Ғәмәлде үтәп булмай -Файлға йәки папкаға яңы исем биреү хатаһы -Файлдарҙы күбәйтеүҙе раҫлау -Был файлдар архивға ҡуйылһынмы? -6100 -Файл юйыуҙы раҫлау -Папка юйыуҙы раҫлау -Берҙән күп файл юйыуҙы раҫлау -'{0}' юйылһынмы? -'{0}' папкаһы һәм эсендәгеләр юйылһынмы? -{0} есеме юйылһынмы? -Юйыу бара... -Файл йәки папка юйыу хатаһы -Оҙон юллы файлдарҙы кәрзингә юйыуҙы система терәкләмәй -6300 -Папка яhа -Файл яhа -Папка исеме: -Файл исеме: -Яңы папка -Яңы файл -Папка яһау хатаһы -Файл яһау хатаһы -6400 -Тасуирлама -&Асыҡлама: -hайла -Һайлауҙы кире ал -Маска: -6600 -Үҙенсәлектәр -Папкалар тарихы -Белдереүҙәр -Белдереү -7100 -Компьютер -Селтәр -Документтар -Система -7200 -Өҫтәргә -Сығарырға -Һынарға -Копияһын алырға -Күсерергә -Юйырға -Мәғлүмәт -7300 -Файлды бүл -&Ошо папкаға бүл: -Киҫәк/&байт итеп бүл: -Бүлеү бара... -Бүлеүҙе раҫлау -Был файлды {0} киҫәккә бүлеүҙе раҫлайһығыҙмы? -Том күләме сығанак файлдан бәләкәй булырға тейеш -Хаталы том күләме -Том күләме : {0} байт.\nФайлды бындай томдарға бүлеүҙе раҫлайһығыҙмы? -7400 -Файлдарҙы берләштер -&Ошо папкала берләштер: -Берләштереү бара... -Бүленгән файлдың беренсе киҫәген генә һайлағыҙ -Бүленгән файлды танып булманы -Бүленгән файлдың берҙән күп киҫәген табып булманы -7500 -Тикшереү һанын иҫәпләү бара... -Тикшереү һаны -Мәғлүмәттәр өсөн CRC тикшереү һаны: -Мәғлүмәттәр һәм исемдәр өсөн CRC тикшереү һаны: -7600 -Етештереүсәнлекте тикшереү -Хәтер ҡулланыу: -Ҡыҫыу -Сығарыу -Рейтинг -Дөйөм рейтинг -Хәҙерге -Һөҙөмтә -Процессор ҡулланыу -Рейтинг / Проц. ҡулл. -Үтеүҙәр: diff -Nru p7zip-rar-16.02/GUI/Lang/be.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/be.txt --- p7zip-rar-16.02/GUI/Lang/be.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/be.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Kirill Gulyakevitch -; 9.07 : 2011-03-15 : Drive DRKA -; -; -; -; -; -; -; -; -; -0 -7-Zip -Belarusian -Беларуская -401 -OK -Адмена - - - -&Так -&Не -&Зачыніць -Дапамога - -&Працягнуць -440 -Так для &усіх -Не для ў&сіх -Стоп -Перазапуск -&Фонам -&На пярэдні план -&Паўза -На паўзе -Вы сапраўды жадаеце перапыніць аперацыю? -500 -&Файл -&Праўка -&Выгляд -&Абранае -С&ервіс -&Даведка -540 -&Адкрыць -Адкрыць &усярэдзіне -Адкрыць з&вонку -Прагляд -&Рэдагаваць -Пера&назваць -&Капіяваць у... -&Перамясціць у... -&Выдаліць -Ра&збіць файл... -А&б'яднаць файлы... -Сво&йства -Коме&нтар -Кантрольная сума -Diff -&Стварыць папку -Ств&арыць Файл -В&ыхад -600 -Вылучыць у&сё -Прыбраць вылучэнне -&Звярнуць в&ыдзяленне -Вылучыць... -Прыбраць вылучэнне... -Вылучыць па тыпе -Прыбраць вылучэнне па тыпе -700 -&Буйныя значкі -&Дробныя значкі -Спі&с -&Табліца -730 -Без сартавання -Плоскі рэжым -&2 Панэлі -&Панэлі прылад -Адкрыць каранёвую папку -Пераход на адзін узровень уверх -Гісторыя папак... -А&бнавіць -750 -Панэль кнопак архіватара -Стандартная панэль кнопак -Вялікія кнопкі -Надпісы на кнопках -800 -Дадаць папку ў &абранае як -Закладка -900 -Налады... -Тэставанне прадукцыйнасці -960 -&Змест... -Аб &праграме... -1003 -Шлях -Імя -Пашырэнне -Папка -Памер -Сціснуты -Атрыбуты -Створаны -Адчынены -Зменены -Бесперапынны -Каментар -Зашыфраваны -Пабіты Да -Пабіты Пасля -Слоўнік -CRC -Тып -Анты -Метад -Сістэма -Файлавая Сістэма -Карыстальнік -Група -Блок -Каментар -Пазіцыя -Шлях -Папак -Файлаў -Версія -Тым -Шматтомны -Зрушэнне -Спасылак -Блокаў -Тамоў - -64-bit -Big-endian -Працэсар -Фізічны Памер -Памер Загалоўкаў -Кантрольная Сума -Характарыстыкі -Віртуальны Адрас -ID -Кароткае Iмя -Создатель -Памер Сектара -Рэжiм -Ссылка -Памылка -Ёмістасць -Вольна -Памер кластара -Пазнака -Лакальнае імя -Правайдэр -2100 -Налады -Мова -Мова: -Рэдактар -&Рэдактар: -&Diff: -2200 -Сістэма -Асацыяваць 7-Zip з файламі: -2301 -Убудаваць 7-Zip у кантэкстнае меню абалонкі -Каскаднае кантэкстнае меню -Элементы кантэкстнага меню: -2320 -<Папка> -<Архіў> -Адкрыць архіў -Распакаваць -Дадаць да архіва... -Тэставаць -Распакаваць тут -Распакаваць у {0} -Дадаць да {0} -Сціснуць і адправіць па email... -Сціснуць у {0} і адправіць па email -2400 -Папкі -&Працоўная Папка -&Сістэмная часавая Папка -&Бягучая -&Задаць: -Выкарыстаць толькі для зменных носьбітаў -Пакажыце становішча для часавых архіваў. -2500 -Налады -Паказваць элемент ".." -Паказваць рэальныя абразкі файлаў -Паказваць сістэмнае меню -Курсор на ўвесь радок -Паказваць падзельнікі -Адчыняць элемент адным клiкам -Альтэрнатыўны рэжым пазнакі -Выкарыстаць вялікія старонкі памяці -2900 -Аб праграме 7-Zip -7-Zip з'яўляецца вольна распаўсюджваемай праграмай. Аднак калі вы жадаеце падтрымаць распрацоўку 7-Zip, вы можаце зарэгістраваць праграму.Праграма перакладена Drive DRKA.Мая электронная скрыня: drka2003@mail.ru.Пераклад зроблен у верасні 2007 года. -3000 -Нядосыць вольнай памяці -Памылак не знойдзена -Вылучана аб'ектаў: {0} -Не атрымалася стварыць папку '{0}' -Аперацыі змены не падтрымліваюцца для гэтага архіва. -Не атрымалася адкрыць файл '{0}' як архіў -Не атрымалася адкрыць зашыфраваны архіў '{0}'. Няслушны пароль? -Непадтрымоўваны тып архіва -Файл {0} ужо існуе -Файл '{0}' быў зменены.\nВы жадаеце абнавіць яго ў архіве? -Не атрымалася абнавіць файл\n'{0}' -Не атрымалася запусціць рэдактар -Файл падобны на вірус (імя файла ўтрымоўвае доўгую паслядоўнасць прабелаў). -Аперацыя не можа быць выкананая з папкі, якая мае доўгі шлях. -Вы павінны вылучыць адзін файл -Вы павінны вылучыць адзін або некалькі файлаў -Занадта шмат элементаў -3300 -Распакаванне -Кампрэсія -Тэставанне -Адкрыццё... -Сканаванне... -3400 -Выняць -&Распакаваць у: -Пакажыце становішча для вымаемых файлаў. -3410 -Шляхі -По&ўные шляхі -&Без шляхоў -3420 -Перазапіс -&З пацверджаннем -Бы&ез пацверджанні -Прап&ускаць -Пераназваць аўтам. -Переім. аўтам. істот. -3500 -Пацверджанне замены файла -Папка ўжо ўтрымоўвае апрацоўваемы файл. -Замяніць наяўны файл -наступным файлам? -{0} байтаў -Пераназваць аўтам. -3700 -Непадтрымоўваны метад сціску для файла '{0}'. -Памылка ў дадзеных у '{0}'. Файл сапсаваны. -Памылка CRC у '{0}'. Файл сапсаваны. -Памылка ў дадзеных зашыфраванага файла '{0}'. Няслушны пароль? -Памылка CRC для зашыфраванага файла '{0}'. Няслушны пароль? -3800 -Увод пароля -&Увядзіце пароль: -&Паўтарыце пароль: -&Паказаць пароль -Паралі не супадаюць -Для пароля выкарыстайце толькі знакі лацінскага алфавіту, лічбы і адмысловыя знакі (!, #, $, ...) -Пароль занадта доўгі -&Пароль -3900 -Мінула: -Засталося: -Усяго: -Хуткасць: -Памер: -Ступень сціску: -Памылак: -Архіваў: -4000 -Дадаць да архіва -&Архіў: -&Рэжым змены: -&Фармат архіва: -&Узровень сціску: -&Метад сціску: -Памер &слоўніка: -Памер з&лоўлі: -Памер блока: -Лік струменяў: -&Параметры: -&Опцыі -Стварыць SF&X-архіў -Сціскаць адчыненыя для запісу файлы -Шыфраванне -Метад шыфравання: -&Шыфраваць імёны файлаў -Аб'ём памяці для пакавання: -Аб'ём памяці для распакавання: -4050 -Без сціску -Хуткасны -Хуткі -Нармалёвы -Максімальны -Ультра -4060 -Дадаць і замяніць -Абнавіць і дадаць -Абнавіць -Сінхранізаваць -4070 -Прагартаць -Усе файлы -Па памеры файла -Бесперапынны -6000 -Капіяваць -Перамясціць -Капіяваць у: -Перамясціць у: -Капіяванне... -Перамяшчэнне... -Пераназванне... -Пакажыце папку. -Аперацыя не падтрымліваецца для гэтай папкі. -Памылка пры пераназванні файла або папкі -Пацверджанне капіявання файлаў -Вы сапраўды жадаеце скапіяваць гэтыя файлы ў архіў -6100 -Пацверджанне выдалення файла -Пацверджанне выдалення папкі -Пацверджанне выдалення групы файлаў -Вы сапраўды жадаеце выдаліць "{0}"? -Вы сапраўды жадаеце выдаліць папку "{0}" і ўсё яе змесціва? -Вы сапраўды жадаеце выдаліць гэтыя аб'екты ({0} шт.)? -Выдаленне... -Памылка пры выдаленні файла або папкі -Сістэма не падтрымлівае аперацыю выдалення файлаў з доўгімі шляхамі ў кошык -6300 -Стварыць папку -Стварыць файл -Імя папкі: -Імя файла: -Новая Папка -Новы файл -Памылка пры стварэнні папкі -Памылка пры стварэнні файла -6400 -Каментар -&Каментар: -Вылучыць -Прыбраць вылучэнне -Маска: -6600 -Уласцівасці -Гісторыя папак -Паведамленні -Паведамленне -7100 -Кампутар -Сетка -Дакументы -Сістэма -7200 -Дадаць -Выняць -Тэставаць -Капіяваць -Перамясціць -Выдаліць -Інфармацыя -7300 -Разбіць файл -&Разбіць у: -Разбіць на &тамы памерам (у байтах): -Разбіццё... -Пацверджанне разбіцця -Вы сапраўды жадаеце разбіць файл на {0} частак? -Памер тома павінен быць менш памеру зыходнага файла -Памылка ў поле для задання памеру тамоў -Усталяваны памер тома: {0} байтаў.\nВы сапраўды жадаеце разбіць архіў на такія тамы? -7400 -Аб'яднаць файлы -&Аб'яднаць у: -Аб'яднанне... -Неабходна вылучыць толькі першую частку пабітага файла -Не атрымалася распазнаць пабіты файл -Не атрымалася знайсці больш адной часткі пабітага файла -7500 -Вылічэнне кантрольнай сумы... -Кантрольная сума -Кантрольная сума CRC для дадзеных: -Кантрольная сума CRC для дадзеных і імёнаў: -7600 -Тэставанне прадукцыйнасці -Аб'ём памяці: -Пакаванне -Распакаванне -Рэйтынг -Агульны рэйтынг -Бягучы -Выніковы -Нагрузка -Рэйтынг / Нагр. -Праходаў: diff -Nru p7zip-rar-16.02/GUI/Lang/bg.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/bg.txt --- p7zip-rar-16.02/GUI/Lang/bg.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/bg.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : chavv -; : icobgr -; 4.65 : Vassia Atanassova -; -; -; -; -; -; -; -; -0 -7-Zip -Bulgarian -Български -401 -OK -Отказ - - - -&Да -&Не -&Затваряне -Помощ - -Пр&одължаване -440 -Да за &всички -Не за &всички -Стоп -От начало -&Фонов режим -&Нормален режим -&Пауза -В пауза -Наистина ли желаете да прекратите? -500 -&Файл -&Редактиране -&Показване -&Любими -&Инструменти -&Помощ -540 -&Отваряне -Отваряне &в -Отваряне &извън -&Показване -&Редактиране -Преи&менуване -&Копиране в... -Пре&местване в... -Из&триване -Р&азделяне на файл... -О&бединяване на файлове... -&Свойства -Ком&ентар -Изчисляване на контролна сума - -Създаване на директория -Създаване на файл -Из&ход -600 -&Маркиране на всички -&Размаркиране на всички -&Обръщане на избора -Маркиране... -Размаркиране... -Маркиране по тип -Размаркиране по тип -700 -&Големи икони -&Малки икони -&Списък -&Детайли -730 -Несортиран -Плосък изглед -&2 панела -&Ленти с инструменти -Отваряне на главната директория -Едно ниво нагоре -История на директориите... -&Опресняване -750 -Лента на архива -Стандартна лента -Големи бутони -Показване на текст под бутоните -800 -&Добавяне на директорията като любима: -Отметка -900 -&Настройки... -&Статистика -960 -&Съдържание... -&За 7-zip... -1003 -Път -Име -Разширение -Директория -Размер -Компресиран размер -Атрибути -Създаден -Отварян -Изменен -Солиден -Коментар -Зашифрован -Разделен до -Разделен след -Речник -CRC -Тип -Анти -Метод -Операционна система -Файлова система -Потребител -Група -Блок -Коментар -Позиция -Префикс на пътя -Директории -Файлове -Версия -Том -Multivolume -Offset -Links -Blocks -Томове - -64-битов -Big-endian -CPU -Физически размер -Размер на заглавната част -Контролна сума -Характеристики -Виртуален адрес - - - - - - -Грешка -Пълен размер -Свободно пространство -Размер на клъстер -Етикет -Локално име -Доставчик -2100 -Настройки -Език -Език: -Редактор -&Редактор: - -2200 -Система -Асоцииране на 7-Zip с: -2301 -Интегриране на 7-Zip в контекстното меню на шела -Каскадно контекстно меню -Елементи на контекстното меню: -2320 -<Директория> -<Архив> -Отваряне на архив -Разархивиране на файловете... -Добавяне към архив... -Проверка на архива -Разархивиране тук -Разархивиране в {0} -Добавяне в {0} -Архивиране и изпращане... -Архивиране в {0} и изпращане -2400 -Директории -&Работна директория -&Системната TEMP директория -&Текущата -&Друга: -Използване само за преносими носители -Указване на място за временните архиви. -2500 -Настройки -Показване на обекта ".." -Показване на истинските икони на файловете -Показване на системното меню -&Избор на цял ред -Показване на помощни &линии - -&Алтернативен режим на избор -Използване на &големи страници от паметта -2900 -Информация -7-Zip се разпространява като свободен софтуер. Все пак, можете да подпомогнете разработката на 7-zip, като се регистрирате. -3000 -Системата не може да задели необходимото количество памет. -Няма грешки в архива -{0} обект(и) избрани -Не може да бъде създадена директория '{0}' -Този архив не поддържа операции за изменение. -Файлът '{0}' не може да се отвори като архив -Криптираният архив '{0}' не може да се отвори. Грешка в паролата? -Архив от тип, който не се поддържа -Файлът {0} вече съществува -Файлът '{0}' е бил променен.\nИскате ли да обновите копието му в архива? -Не може да бъде обновен файл \n'{0}' -Не може да бъде стартиран редактора. -Файлът прилича на вирус (името му съдържа дълги поредици интервали). -Операцията не може да бъде извикана от директория с толкова дълъг път. -Трябва да се избере един файл -Трябва да се изберат един или повече файлове -Твърде много обекти -3300 -Разархивиране -Компресия -Проверка -Отваряне... -Претърсване... -3400 -Разархивиране -&Разархивиране в: -Избор на място за разархивираните файлове. -3410 -Режим за пътищата -Пълни пътища -Без пътища -3420 -Режим за презаписване -Потвърждение преди презаписване -Презаписване без потвърждение -Пропускане на съществуващите файлове -Автоматично преименуване -Автоматично преименуване на съществуващите файлове -3500 -Подтвърдете замяната на файла -Директорията вече съдържа файл с такова име. -Желаете ли да замените съществуващия файл -с този файл? -{0} байта -&Автоматично преименуване -3700 -Неподдържан метод за компресия във файл '{0}'. -Грешка в данните в '{0}'. Файлът е повреден. -Проверката на цикличния остатък даде грешка в '{0}'. Файлът е повреден. -Грешка в данните в криптирания файл '{0}'. Грешка в паролата? -Проверката на цикличния остатък даде грешка в криптирания файл '{0}'. Грешка в паролата? -3800 -Въведете парола -Въведете парола: -Въведете повторно парола: -&Показване на паролата -Двете пароли не съвпадат -За паролата си използвайте само латински букви, цифри и специални символи (!, #, $, ...) -Паролата е твърде дълга -&Парола -3900 -Изминало време: -Оставащо време: -Размер: -Скорост: -Обработени: -Коефициент на компресия: -Грешки: -Архиви: -4000 -Добавяне към архив -&Архив: -Режим за изменение: -Формат на архива: -&Ниво на компресия: -Метод за компресия: -Размер на &речника: -Размер на &думата: -Размер на непрекъснат блок: -Брой процесорни нишки: -&Параметри: -&Опции -Самора&зархивиращ се архив -Компресирани споделени файлове -Криптиране -Метод за криптиране: -Криптиране на файловите &имена -Използвана памет за архивиране: -Използвана памет за разархивиране: -4050 -Без компресия -Най-бърза -Бърза -Нормална -Максимална -Ултра -4060 -Добавяне и замяна на файлове -Обновяване и добавяне на файлове -Опресняване на съществуващите файлове -Синхронизиране на файловете -4070 -Разглеждане -Всички файлове -Non-solid -Непрекъсната (solid) компресия -6000 -Копиране -Преместване -Копиране в: -Преместване в: -Копиране... -Местене... -Преименуване... -Избор на целева директория. -Операцията не се поддържа за тази директория. -Грешка при преименуването на файл или директория -Потвърждение за копирането на файл -Сигурни ли сте, че искате да копирате файлове към архива? -6100 -Потвърждение за изтриването на файл -Потвърждение за изтриването на директория -Потвърждение за изтриването на множество файлове -Сигурни ли сте, че искате да изтриете '{0}'? -Сигурни ли сте, че искате да изтриете диркеторията '{0}' с цялото й съдържание? -Сигурни ли сте, че искате да изтриете тези {0} обекта? -Изтриване... -Грешка при изтриване на файл или директория -Системата не може да изтрие файл с толкова дълъг път -6300 -Създаване на директория -Създаване на файл -Име на директория: -Име на файл: -Нова директория -Нов файл -Грешка при създаване на директория -Грешка при създаване на файл -6400 -Коментар -&Коментар: -Маркиране -Размаркиране -Маска: -6600 -Свойства -История на директориите -Диагностични съобщения -Съобщение -7100 -Компютър -Мрежа -Документи -Система -7200 -Добавяне -Извличане -Тестване -Копиране -Преместване -Изтриване -Информация -7300 -Разделяне на файл -&Разделяне на: -Разделяне на &томове, байтове: -Разделяне... -Потвърждение на разделянето -Сигурни ли сте, че искате да разделите файла на {0} тома? -Размерът на том трябва да бъде по-малък от размера на оригиналния файл -Невалиден размер на том -Указан размер на том: {0} байта.\nСигурни ли сте, че искате да разделите архива на томове с такъв размер? -7400 -Обединяване на файлове -&Обединяване в: -Обединяване... -Избиране само на първата част от разделения файл -Файлът не се разпознава като част от разделен оригинален файл -Не се открива повече от една част от разделения файл -7500 -Изчисляване на контролната сума... -Информация за контролната сума -CRC контролна сума за данни: -CRC контролна сума за данни и имена: -7600 -Статистика -Използвана памет: -Архивиране -Разархивиране -Оценка -Обща оценка -Текущо -Резултат - - -Успешно преминали: diff -Nru p7zip-rar-16.02/GUI/Lang/bn.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/bn.txt --- p7zip-rar-16.02/GUI/Lang/bn.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/bn.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.46 : Team Oruddho (Fahad Mohammad Shaon, Mahmud Hassan) : http://www.oruddho.com -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Bangla -বাংলা -401 -ঠিক আছে -বাতিল - - - -&হ্যাঁ -&না -&বন্ধ করা -সাহায্য - -&চালিয়ে যাওয়া -440 -&সবগুলোর জন্য হ্যাঁ -স&বগুলোর জন্য না -বন্ধ -আবার শুরু -&পটভূমি -& সামনে -&বিরতি -বিরতিতে অবস্থানরত -আপনি বাতিল করতে ইচ্ছুক? -500 -&ফাইল -&পরিবর্তন -প্রদর্শন& -&প্রিয় -&দরকারি -&সহায়তা -540 -&উন্মুক্ত করা -7-zip-এ উন্মুক্ত করা -বাহিরে উন্মুক্ত করা -&প্রদর্শন -&পরিবর্তন -নাম পরিবর্তন -&অনুলিপি হবে... -প্রতিস্থাপন হবে... -&মুছে ফেলা -&ফাইল খন্ডায়ন... -ফাইল সংযোজন... -বৈশিষ্টাবলি -মন্তব্য -Checksum গননা করা - -ফোল্ডার সৃষ্টি -ফাইল সৃষ্টি -বাহির -600 -সব নির্বাচন -নির্বাচন রদ করা -উল্টো নির্বাচন -নির্বাচন... -নির্বাচন রদ করা... -ধরণ অনুযায়ী নির্বাচন -ধরণ অনুযায়ী নির্বাচন রদ করা -700 -বৃহৎ প্রতিক -ছোট্ট প্রতিক -&তালিকা -&বিবরণ -730 -অসজ্জিত -সমতল সজ্জা -&ব্যবস্থাপক দ্বিখন্ডন -&দরকারিখুটি -মূল ফোল্ডার উন্মুক্ত করা -এক পর্যায় উপরে ... -ফোল্ডারের অতীত বিবরণ... -&সতেজতা -750 -সংকোচোন ব্যবস্থাপক খুটি -সাধারণ খুটি -বৃহৎ বোতাম -বোতামের শিরোনাম প্রদর্শন -800 -&প্রিয় ফোল্ডার হিসাবে সংযোজন ... -পছন্দের তালিকা -900 -&পছন্দগুলো... -&বেঞ্চমার্ক -960 -&সাহায্য... -&7-Zip সর্ম্পকে... -1003 -অবস্থান -নাম -পরিচয় -ফোল্ডার -আকার -সংকুচিত আকার -বৈশিষ্ট -সৃষ্টি হয়েছে -ব্যবহার হয়েছে -পরিবর্ধন হয়েছে -দৃঢ় -Commented -আটকানো -খন্ডনের পূর্বে -খন্ডনের পরে -অভিধান -CRC -ধরন -বিরোধী -পদ্ধতি -চলতি অপারেটিং সিস্টেম -ফাইল ব্যবস্থা -ব্যবহারকারী -দল -বাধা -মন্তব্য -অবস্থান -পথের বিশেষায়ণ (Path Prefix) - - - - - - - - - - - - - - - - - - - - - - - - -ত্রুটি -সম্পূর্ণ আকার -অবশিষ্ট জায়গা -ক্লাস্টারের আকার -শিরোনাম -স্থানীয় নাম -বিতরণকারী -2100 -পছন্দগুলো -ভাষা -ভাষা: -সম্পাদক -বর্তমান সম্পাদক : - -2200 -বর্তমান অবস্থা -7-Zip-এর সাথে সম্পর্কিত : -2301 -সাহায্যকারী তালিকায় 7-Zip সংযোজন -সাহায্যকারী তালিকায় একের ভিতর সব গুটিয়ে ফেলা -সাহায্যকারী তালিকার বিষয়সমূহ: -2320 -<ফোল্ডার> -<সংকুচিত ফাইল> -সংকুচিত ফাইল চালু করা -ফাইল সম্প্রসারণ... -সংকুচিত ফাইলে সংযোজন... -সংকুচিত ফাইল নিরীক্ষণ -এখানেই সম্প্রসারণ -সম্প্রসারণ করা হবে {0} -সযোজন করা হবে {0} -সংকোচন এবং ই-মেইল... -সংকোচন - {0} এবং ই-মেইল -2400 -ফোল্ডার -&কার্যরত ফোল্ডার -&অস্থায়ী ফোল্ডার -&প্রচলিত -&নির্দিষ্ট: -অস্থায়ী অংশের জন্য ব্যবহার করা -অস্থায়ী ফোল্ডার নির্বাচন করুন। -2500 -পছন্দগুলো -".." ফাইল প্রদর্শন -ফাইলের আসল প্রতিক দেখানো -কম্পিউটার চালকের তালিকা দেখানো -পূর্ণ পর্যায় প্রদর্শন -ছকের লাইন প্রদর্শন - -পরিপূরক নিবাচনের পদ্ধতি -বেশি স্মৃতির ব্যবহার -2900 -7-Zip সম্পর্কে -7-Zip একটি মুক্ত প্রোগ্রাম কিন্তু এটি 7-Zip এর কতৃপক্ষের কাচে নিবন্ধনের মাধ্যমে আপনি উন্নত সেবা পেতে পারেন -3000 - -কোন ত্রুটি নেই -{0} ফাইল(সমূহ) নির্বাচিত -'{0}' ফোল্ডার সৃষ্টি করা সম্ভব হচ্ছেনা -এই সংকোচনের ক্ষেত্রে এই সেবা প্রদান করা সম্ভব হচ্ছে না। -'{0}' -কে সংকুচিত ফাইল হিসেবে চালু করা সম্ভব হচ্ছেনা -'{0}' বদ্ধ সংকুচিত ফাইল চালু করা সম্ভব হচ্ছেনা. ভুল পাসওয়ার্ড? - - -ফাইলটি '{0}' পরিমার্জিত.\nআপনি সংকুচিত ফাইলটি ও পরিমার্জন করতে চান? -পরিমার্জন করা সম্ভব হয়নি\n'{0}' -সম্পাদক চালু করা সম্ভব নয় - - - - -অনেক বেশী ফাইল -3300 -সম্প্রসারণ করা হচ্ছে -সংকোচায়ন প্রক্রিয়াধীন -নিরক্ষণ করছে ... -উন্মুক্ত করা হচ্ছে... -তথ্য সংগ্রহ চলছে... (Scanning...) -3400 -সম্প্রসারণ -&সম্প্রসারণ করা হবে: -ফাইল সম্প্রসারনের ঠিকানা -3410 -ঠিকানা নির্বাচন পদ্ধতি -পূর্ণ ঠিকানাসমূহ -ঠিকানাবিহীন -3420 -প্রতিস্থাপন পদ্ধতি -প্রতিস্থাপনের পূর্বাভাস -আভাসবিহীন প্রতিস্থাপন -একই পরিচয় প্রাপ্ত ফাইল এড়িয়ে চলা -স্বয়ংক্রিয় পুঃনামকরণ -একই পরিচয় প্রাপ্ত ফাইলের নাম পরিবর্ত্ন -3500 -ফাইল প্রতিস্থাপন নিশ্চিত করণ -নির্ধারিত ফোল্ডারে ফাইলটি আগেথেকেই আছে -আপনিকি বর্তমান ফাইলটি প্রতিস্থাপন করতে চান? -এইটির সাথে? -{0} bytesবাইট -স্বয়ংক্রিয় পুঃনামকরণ -3700 -অসমর্থিত সংকোচন পদ্ধতি -'{0}'. -'{0}' ফাইলে ত্রুটিপূর্ণ তথ্য. ফাইলটি খন্ডিত -'{0}' ফাইলে CRC ব্যর্থ. ফাইলটি খন্ডিত -'{0}' বদ্ধ ফাইলে তথ্যে ত্রুটি. ভুল পাসওয়ার্ড? -'{0}' বদ্ধ ফাইলে CRC ব্যর্থ. ভুল পাসওয়ার্ড? -3800 -পাসওয়ার্ডটি প্রবেশ করুনঃ -পাসওয়ার্ডটি প্রবেশ করুনঃ -আবার পাসওয়ার্ড প্রবেশ করুনঃ -&পাসওয়ার্ড প্রদর্শন -পাসওয়ার্ড দুটি একই নয় -শুধু ইংলিশ বর্ণ, সংখ্যা এবং বিশেষ বর্ণ (!, #, $, ...) পাসওয়ার্ড হিসেবে ব্যবহার করুন -পাসওয়ার্ডটি খুব বেশী বড় হয়েছে -পাসওর্য়াড -3900 -অতিবাহিত সময়ঃ -সময় বাকি আছেঃ -আকার: -গতি: - - -বিফলতা : - -4000 -সংকোচনে সংযোজন -&সংকোচন -&পরিমার্জন পদ্ধতি: -সংকোচনের & পরিচয়: -সংকোচনের &পর্যায়: -সংকোচন &পদ্ধতি: -&Dictionary size: -&Word size: -Solid block size: -CPU-এর thread-এর সংখ্যা: -&Parameters: -পছন্দনীয় -স্বয়ংক্রিয় সংকোচন প্রোগ্রাম তৈরি -বিনিময়যোগ্য ফাইল সংকোচন -বদ্ধ করা -বদ্ধ করার পদ্ধতি: -ফাইলের নাম &আটকে ফেলা -সংকোচনের জন্য স্মৃতির ব্যবহার: -সম্প্রসারনের জন্য স্মৃতির ব্যবহার: -4050 -অতি সংকোচায়ন -অতি দ্রুত -দ্রুত -সাধারন -সর্ব্বোচ্চ -পলকের গতি -4060 -সংকোচন ও ফাইল প্রতিস্থাপন -পরিমার্জন ও ফাইল প্রতিস্থাপন -উল্লেখিত ফাইলে সতেজতা প্রদান -ফাইল সাজিয়ে রাখা -4070 -বিচরণ -সকল ফাইল -Non-solid -Solid -6000 -অনুলিপি গ্রহন -অনুলিপি গ্রহন এবং মুছে ফেলা -অনুলিপি করা হবে: -প্রতিস্থাপিত হবে: -অনুলিপি করা হচ্ছে... -প্রতিস্থাপিত হচ্ছে... -নাম পরিবর্তন... -গন্তব্য ফোল্ডার নির্বাচন. -কার্যটি সম্ভব নয় -ফাইল বা ফোল্ডারের নাম পরিবর্তনে সম্ভব নয় -ফাইল অনুলিপি নিশ্চিতকরণ -আপনি কি ফাইলগুলোকে সংকুচিত ফাইলে অনুলিপি গ্রহণ করতে চান। -6100 -ফাইলটি মুছে ফেলতে কি আপনি নিশ্চিত -ফোল্ডারটি মুছে ফেলতে কি আপনি নিশ্চিত -ফাইলটি মুছে ফেলতে কি আপনি নিশ্চিত -মুছে ফেলতে আপনি কি নিশ্চিত - '{0}'? -'{0}' ফোল্ডার এবং এর সব ফাইল আপনি কি মুছে ফেলতে নিশ্চিত? -নির্বাচিত {0} টি ফাইল আপনি কি মুছে ফেলতে নিশ্চিত? -মুছে ফেলা হচ্ছে... -ফাইল বা ফোল্ডার মুছে ফেলাতে সমস্যা হচ্ছে - -6300 -ফোল্ডার সৃষ্টি -ফাইল সৃষ্টি -ফোল্ডারের নাম: -ফাইল নাম: -নতুন ফোল্ডার -নতুন ধারক -ফোল্ডার সৃষ্টিতে সমস্যা -ফাইল সৃষ্টিতে সমস্যা -6400 -মন্তব্য -&মন্তব্য: -নির্বাচন -নির্বাচন রদ করা -আড়াল করা: -6600 - -ফোল্ডারের অতিত বিবরন -সমস্যা নিরাময় আভাস -আভাস -7100 -কম্পিউটার -আন্তঃ সম্পর্ক - -কম্পিউটার চালক -7200 -সংজোযন -সম্প্রসারন -নিরীক্ষণ -অনুলিপি গ্রহন -প্রতিস্থাপন -মুছে ফেলা -তথ্য -7300 -ফাইল খন্ডায়ন -&ফাইল খন্ডায়িত হবে: -volumes(খন্ডে), bytes(বাইটস)-এ খন্ডায়নঃ -ফাইল খন্ডায়ন চলছে... -ফাইল খন্ডায়ন নিশ্চিতকরণ -আপনি কি সংকুচিত ফাইলটিকে {0} খন্ডে খন্ডায়ন করতে চান? -খন্ডের আকার অবশ্যই মূল ফাইলের চেয়ে ছোট হতে হবে -খন্ডের আকারে ভুল -উল্লেক্ষিত খন্ডের আকার : {0} bytes.\nআপনি কি সংকোচিত ফাইলটিকে এ ভাবেই খন্ডে খন্ডায়ন করতে চান? -7400 -ফাইল একীভূতি করণ -&একীভূতি করা হবে: -একীভূতি চলছে... -শুধু প্রথম ফাইলটি নির্বাচন করুন - - -7500 -Checksum গননা চলছে... -Checksum তথ্য -তথ্যের জন্য CRC checksum: -তথ্য এবং নামের জন্য CRC checksum: -7600 -বেঞ্চমার্ক -ব্যবহৃত স্মৃতি : -সংকোচায়ন ... -সম্প্রসারণ ... -রেটিং -মোট রেটিং -চলতি -ফলাফল -CPU ব্যবহার করছে -Rating / ব্যবহার করছে -সফলতা : diff -Nru p7zip-rar-16.02/GUI/Lang/br.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/br.txt --- p7zip-rar-16.02/GUI/Lang/br.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/br.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.12 : KAD-Korvigelloù An Drouizig (drouizig.org). -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Breton -Brezhoneg -401 -Mat eo -Nullañ - - - -&Ya -&Ket -&Serriñ -Skoazell - -&Kenderc'hel -440 -Ya be&pred -Ket &bepred -Paouez -Adloc'hañ -&Drekleur -&Rakleur -&Ehan -Ehanet -Ha fellout a ra deoc'h nullañ ? -500 -&Restr -&Aozañ -&Gwelout -Di&baboù -&Ostilhoù -&Skoazell -540 -&Digeriñ -Digeriñ a-zia&barzh -Digeriñ a-zia&vaez -&Gwelout -&Aozañ -Adenv&el -&Kopiañ diwar... -&Dilec'hiañ diwar... -D&ilemel -&Troc'hañ restr... -&Kendeuziñ restroù... -P&erzhioù -Evezhia&denn - - -Sevel un teul -Sevel ur restr -&Kuitaat -600 -Diuz pep &tra -Diziuz pe tra -Lakaat an &diuzad war an tu gin -Diuz... -Diziuz... -Diuz diouzh ar rizh -Diziuz diouzh ar rizh -700 -Arlunioù &bras -Arlunioù &bihan -&Roll -&Munudoù -730 -Dirummet - -&2 brenestr -&Barrennoù ostilhoù -Digeriñ an teul gwrizienn -Teul kerent -Roll istor an teul... -Fresk&aat -750 -Barrenn ziell -Barrenn skouerek -Meudellioù bras -Diskouez an destenn -800 -&Ouzhpennañ ar c'havlec'h d'ar sinedoù -Sined -900 -&Dibaboù... -&Amprouiñ -960 -&Roll ar pennadoù... -A-&zivout 7-Zip... -1003 -Treug -Anv -Astenn -Teul -Ment -Gwasket -Doareennoù -Savet d'ar -Stoket d'ar -Kemmet d'ar -Solut -Evezhiadenn -Ennodet -Rannañ a-raok -Rannañ war-lerc'h -Geriadur -CRC -Rizh -Enep -Hentenn -OS ostiz -Reizhiad restroù -Implijour -Strollad -Bloc'h -Evezhiadenn -Lec'hiadur - - - - - - - - - - - - - - - - - - - - - - - - - -Fazi -Ment en holl -Egor vak -Ment ar c'hleusteurioù -Skritellig -Anv lec'hel -Pourchaser -2100 -Dibaboù -Yezh -Yezh : -Embanner -&Embanner : - -2200 -Reizhiad -Kenstagañ 7-Zip ouzh : -2301 -Lakaat 7-Zip el lañser kemperzhel -Lañser kemperzhel a-steud -Elfennoù al lañser kemperzhel : -2320 - - -Digeriñ -Eztennañ ar restroù... -Ouzhpennañ d'an diell... -Gwiriañ an diell -Eztennañ amañ -Eztennañ diwar {0} -Ouzhpennañ da {0} -Gwaskañ ha kas dre postel... -Gwaskañ diwar {0} ha kas dre postel. -2400 -Teulioù -Teulioù &labour -Teul dibadelus ar &reizhiad -Teul &red -Teul &spisaet : -Implijout nemet evit ar mediaoù dilec'hus -Spisait un teul evit lakaat ar restroù diell dibadelus. -2500 -Perzhioù -Diskouez an elfenn ".." -Diskouez arlunioù gwirion ar restroù -Diskouez al lañser reizhiad -&Diuz ar bannoù a-bezh -Diskouez al &linennoù kael - - - -2900 -Keloù -Digoust eo ar meziant 7-Zip. Mar plij deoc'h 7-zip ha mar fell deoc'h skoazellañ ar raktres-mañ e c'hellit donezoniñ argant da 7-Zip. -3000 - -N'eus fazi ebet -{0} elfenn ziuzet -N'haller ket sevel ar restr '{0}' -N'haller ket ober gant an oberiadennoù nevesaat evti an diell-mañ. - - - - -Kemmet ez eo bet ar restr '{0}'.\nHa fellout a ra deoc'h he nevesaat en diell ? -N'haller ket nevesaat\n'{0}' -N'haller ket loc'hañ an embanner. - - - - -Re a elfennoù -3300 -Eztennañ -O waskañ -Gwiriañ -O tigeriñ... - -3400 -Eztennañ -E&ztennañ diwar : -Dibabit un teul evit eztennañ an restroù. -3410 -Treugoù -Treugoù klok -Treug ebet -3420 -Mod erlec'hiañ -Goulenn a-raok erlec'hiañ -Erlec'hiañ hep goulenn -Lakaat ar restroù a zo anezho a-gostez -Adenvel ent-emgefre ar restroù a zo anezho - -3500 -Kadarnaat a-raok erlec'hiañ ur restr -Emañ dija ur restr gant ar memes anv en teul bukenn. -Ha fellout a ra deoc'h lakaat e-lec'h -ar restr da heul ? -{0} eizhtet -Adenvel ent-&emgefre -3700 -Hentenn waskañ direizh evit '{0}'. -Stlenn faziet e-barzh '{0}'. Gwastet eo ar restr. -Fazi ar reoliñ CRC evit '{0}'. Gwastet eo ar restr. - - -3800 -Roit ar ger-tremen -Roit ar ger-tremen : - -&Diskouez ar ger-tremen - - - -Ger-tremen -3900 -Amzer dremenet : -Amzer o chom : -Ment : -Tizh : - - -Fazioù : - -4000 -Ouzhpennañ d'an diell -&Diell : -&Mod nevesaat : -&Mentrezh an diell : -L&ive gwaskañ : -Rizh &gwaskañ: -&Ment ar geriadur : -Me&nt ar gerioù : - - -&Perzhioù: -&Dibaboù -Sevel un diell SF&X - - - -Ennodiñ an &anvioù restroù -Memor evit ar waskerezh : -Memor evit an diwaskerezh : -4050 -Gwaskañ ebet -Primañ -Prim -Reizh -Uhelañ -Gour -4060 -Ouzhpennañ hag erlec'hiañ ar restroù -Nevesaat hag ouzhpennañ ar restroù -Freskaat ar restroù a zo anezho -Goubredañ ar restroù -4070 -Furchal -An holl restroù - - -6000 -Kopiañ -Dilec'hiañ -Kopiañ e-barzh : -Dilec'hiañ diwar : -O kopiañ... -O tilec'hiañ... -Oc'h adenvel... - -N'haller ket ober an oberiadenn-mañ. -Fazi oc'h adenvel ar restr pe an teul - - -6100 -Kadarnañ a-raok dilemel ar restr -Kadarnañ a-raok dilemel an teul -Kadarnañ a-raok dilemel an holl restroù -Ha fellout a ra deoc'h dilemel '{0}' ? -Ha fellout a ra deoc'h dilemel an teul '{0}' ha pep tra a zo e-barzh ? -Ha fellout a ra deoc'h dilemel ar {0} elfenn-mañ ? -O tilemel... -Fazo o tilemel ar restr pe an teul - -6300 -Sevel un teul -Sevel ur restr -Anv an teul : -Anv restr : -Teul nevez -Restr nevez -Fazi o sevel an teul -Fazi o sevel ar restr -6400 -Evezhiadenn -&Evezhiadenn : -Diuz -Diziuz -Kuzh : -6600 - -Roll istor an teulioù -Kemennoù yalc'h -Kemenn -7100 -Urzhiataer -Rouedad - -Reizhiad -7200 -Ouzhpennañ -Eztennañ -Amprouiñ -Kopiañ -Dilec'hiañ -Dilemel -Keloù -7300 -Troc'hañ restr -&Troc'hañ da : -Troc'hañ e &levrennoù, eizhtetoù : -O troc'hañ... - - - - - -7400 -Kendeuziñ restroù -&Kendeuziñ da : -O kendeuziñ... - - - -7500 - - - - -7600 -Amprouiñ -Implij ar vemor : -Gwaskerezh -Diwaskerezh -Feur -Feur en holl -Red -Da heul - - -Tremenioù : diff -Nru p7zip-rar-16.02/GUI/Lang/ca.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ca.txt --- p7zip-rar-16.02/GUI/Lang/ca.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ca.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Josep Casals, Marc Folch -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Catalan -Català -401 -D'acord -Cancel.la - - - -&Sí -&No -Tan&ca -Ajuda - -&Continua -440 -Sí a &tot -No a t&ot -Atura -Reinicia -Rerefons -Primer pla -&Pausa -Aturat -Esteu segur que voleu cancel.lar? -500 -&Fitxer -&Edita -&Visualitza -&Preferits -E&ines -Aj&uda -540 -&Obre -Obre d&ins -Obre fora -&Visualitza -&Edita -Renom&ena -&Copia a... -&Moure a... -Suprimeix -&Divideix el fitxer... -Com&bina el fitxer... -P&ropietats -Come&ntari -Calcula el checksum -Diff -Crea carpeta -Crea fitxer -Surt -600 -Seleccion&a-ho tot -Deselecciona-ho tot -&Inverteix selecció -Selecciona... -Deselecciona... -Selecciona per tipus -Deselecciona per tipus -700 -Icones g&rans -Icones petites -&Llista -&Detalls -730 -No ordenat -Vista plana -&2 Taules -&Barres d'eines -Obre carpeta arrel -Carpeta pare -Historial de carpetes... -&Actualitza -750 -Barra d'eines afegeix/extreu -Barra d'eines estàndard -Botons grans -Mostra botons amb text -800 -&Afegeix la carpeta als Preferits com -Personal -900 -Opcions... -&Test de referència -960 -&Contingut... -Quant a 7-Zip... -1003 -Adreça -Nom -Tipus de fitxer -Carpeta -Mida -Mida comprimit -Atributs -Creat -Darrer accés -Darrera modificació -Compacte -Comentari -Xifrat -Expandit abans -Expandit després -Diccionari -CRC -Tipus -Anti -Mètode -SO orígen -Sistema de fitxers -Usuari -Grup -Bloc -Comentari -Posició -Path Prefix -Carpetes -Fitxers -Versió -Volum -Multivolum -Desplaçament -Enllaços -Blocs -Volums - -64-bits -Big-endian -CPU -Mida física -Mida capçaleres -Suma de verificació -Característiques -Adreça virtual -ID -Nom curt -Aplicació creadora -Mida del sector -Mode -Enllaç -Error -Mida total -Espai lliure -Mida sector -Etiqueta -Nom local -Proveïdor -2100 -Opcions -Llengua -Llengua: -Editor -&Editor: -&Diff: -2200 -Sistema -Associa 7-Zip amb: -2301 -Integra 7-Zip dins el menú contextual de Windows -Menú contextual en cascada -Objectes del menú contextual: -2320 - - -Obre -Extreu fitxers... -Afegeix al fitxer... -Comprova el fitxer -Extreu a aquesta carpeta -Extreu a {0} -Afegeix a {0} -Comprimeix i envia per correu electrònic... -Comprimeix a {0} i envia per correu electrònic -2400 -Carpetes -Carpeta de &treball -Carpeta temporal del &sistema -Carpeta a&ctual -E&specifica una carpeta: -Utilitza únicament per a discs extraïbles -Especifica una carpeta pels fitxers temporals. -2500 -Selecció -Mostra l'element ".." -Mostra icones reals dels fitxers -Mostra el menú de sistema -&Selecció de columna completa -Mostra les línies de &graella -Obre amb un sol clic els elements -Mode de selecció &alternatiu -Usa pàgines de memòria &grans -2900 -Informació sobre 7-Zip -7-Zip és programari lliure. De totes maneres, podeu col.laborar en el seu desenvolupament registrant el programa. -3000 -El sistema no pot assignar la quantitat de memòria requerida -No hi ha errors -{0} objecte(s) seleccionat(s) -No es pot crear la carpeta '{0}' -Aquest tipus de fitxer no permet actualització. -No es pot obrir el fitxe '{0}' com a arxiu -No es pot obrir el fitxer xifrat '{0}'. La contrasenya és incorrecta? -Tipus d'arxiu no admès -El fitxer {0} ja existeix -El fitxer '{0}' ha estat modificat.\nVoleu actualitzar-lo a l'arxiu? -No pot actualitzar-se el fitxer\n'{0}' -No pot executar-se l'editor. -El fitxer sembla un virus (el nom del fitxer conté espais molt llargs al nom). -L'operació no es pot cridar des d'una carpeta amb una ruta llarga. -Heu de seleccionar un fitxer -Heu de seleccionar un o més fitxers -Massa objectes -3300 -Extraient -Comprimint -Provant -Obrint... -Scanning... -3400 -Extreu -E&xtreu a: -Seleccioneu una destinació pels fitxers extrets. -3410 -Mode d'adreça -Adreça completa -Sense adreça -3420 -Sobreescriure -Amb confirmació -Sense confirmació -Conserva els fitxers ja existents -Reanomena automàticament -Auto-reanomena fitxers existents -3500 -Confirmeu substitució de fitxers -La carpeta de destí conté un fitxer amb el mateix nom. -Voleu substituir el fitxer existent -per aquest altre? -{0} bytes -Renomena a&utomàticament -3700 -Mètode de compressió no vàlid per a '{0}'. -Error de dades en '{0}'. El fitxer és corrupte. -CRC ha fallat en '{0}'. El fitxer és corrupte. -Error de dades al fitxer xifrat '{0}'. Contrasenya errònia? -CRC ha fallat al fitxer xifrat '{0}'. Contrasenya errònia? -3800 -Introduïu la contrasenya -Introduïu la contrasenya: -Torneu a introduir la contrasenya: -Mo&stra la contrasenya -Les contrasenyes no coincideixen -Utilitza només lletres (sense accents), números i caràcters especials (!, #, $, ...) a la contrasenya -La contrasenya és massa llarga -Contrasenya -3900 -Temps transcorregut: -Temps restant: -Mida: -Taxa: -Processat: -Ràtio de compressió: -Errors: -Arxius: -4000 -Afegir al fitxer -&Fitxer: -Mode d'act&ualització: -&Format del fitxer: -Nivell de &compressió: -&Tipus de compressió: -Mida del &diccionari: -Mida de la paraula: -Mida de bloc sòlid: -Nombre de fils de la CPU: -&Paràmetres: -Opcions -Crea fitxer SF&X -Comprimeix fitxers compartits -Xifrat -Mètode de xifrat: -Xifra el nom dels fitxers -Ús de memòria per comprimir: -Ús de memòria per descomprimir: -4050 -Sense compressió -Ràpida - -Normal -Màxima -Ultra -4060 -Afegeix i substitueix fitxers -Actualitza i afegeix fitxers -Actualitza fitxers ja presents -Sincronitza fitxers -4070 -Visualitza -Tots els fitxers -No sòlid -Sòlid -6000 -Copia -Mou -Copia a: -Mou a: -Copiant... -Movent... -Renomenant... -Seleccioneu una carpeta de destí. -Operació no permesa. -Error renomenant fitxer o carpeta -Confirmeu la còpia del fitxer -Esteu segur que voleu copiar els fitxers a l'arxiu -6100 -Confirmeu la supressió del fitxer -Confirmeu la supressió de la carpeta -Confirmeu supressió múltiple de fitxers -Esteu segur que voleu suprimir '{0}'? -Esteu segur que voleu suprimir la carpeta '{0}' i tot el seu contingut? -Esteu segur que voleu esborrar aquests {0} elements? -Suprimint... -Error esborrant fitxer o carpeta -El sistema no pot moure un fitxer amb una ruta llarga a la paperea de reciclatge -6300 -Crea carpeta -Crea arxiu -Nom de carpeta: -Nom d'arxiu: -Carpeta nova -Fitxer nou -Error creant carpeta -Error creant el fitxer -6400 -Comentari -&Comentari: -Selecciona -No selecciona -Màscara: -6600 -Properties -Historial de carpetes -Missatges de diagnosi -Missatge -7100 -El meu ordinador -Entorn de xarxa -Documents -Sistema -7200 -Afegeix -Extreu -Prova -Copia -Mou -Suprimeix -Info -7300 -Divideix fitxer -&Divideix a: -Divideix en &volums, bytes: -Dividint... -Confirmació de la divisió -Esteu segur que voleu dividir el fitxer en {0} volums? -La mida del volum ha de ser més petita que la mida del fitxer original -Mida del volum incorrecte -Mida de volum especificada: {0} bytes.\nEsteu segur que voleu dividir el fitxer en aquests volums? -7400 -Combina fitxers -&Combina a: -Combinant... -Seleccioneu només el primer fitxer -No es pot detectar un fitxer com a una part del fitxer dividit -No es pot trobar més d'una part del fitxer dividit -7500 -Calculant el checksum... -Informació del checksum -CRC checksum per les dades: -CRC checksum per les dades i els noms: -7600 -Test de referència -Ús de la memòria: -Comprimint -Decomprimint -Taxa -Taxa total -Actual -Resultant -Ús de la CPU -Taxa / Ús -Passades: diff -Nru p7zip-rar-16.02/GUI/Lang/co.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/co.txt --- p7zip-rar-16.02/GUI/Lang/co.txt 2016-05-20 08:51:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/co.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.00 : Patriccollu di Santa Maria è Sichè -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Corsican -Corsu -401 -OK -Abbandunà - - - -&Iè -I&nnò -&Chjode -Aiutu - -&Cuntinuà -440 -Iè per &Tutti -Innò per T&utti -Piantà -Riavvià -&Arci pianu -P&rimu pianu -&Pausa -In pausa -Site sicuru di vulè abbandunà ? -500 -&Schedariu -&Mudificà -&Affissà -&Favuriti -A&ttrezzi -A&iutu -540 -&Apre -Apre Den&tru -Apre F&ora -A&ffissà -&Mudificà -&Rinumà -&Cupià Ver Di... -&Dispiazzà Ver Di... -S&quassà -&Sparte u schedariu... -&Unisce i schedarii... -&Pruprietà -Cumme&ntu... -Calculà a somma di cuntrollu -Paragunà e sfarenze -Creà un Cartulare -Creà un Schedariu -&Esce -Leia -Flussi A<ernativi -600 -Selezziunà &Tuttu -Ùn selezziunà &Nunda -&Arritrusà a Selezzione -&Selezziunà... -Ùn selezziunà &micca... -Selezziunà da u Tipu -Ùn Selezziunà da u Tipu -700 -Icone &Maiò -Icone &Chjuche -&Lista -&Detaglii -730 -Non &Ordinatu -&Vista Sparta -&2 Finestre -&Barre d'Attrezzi -Apre u Cartulare di &Radica -Livellu &Superiore -Crunulugia di i Cartulari... -&Attualizà -Attualisazione Autumatica -750 -Barra d'Attrezzi d'Archiviu -Barra d'Attrezzi Classica -Buttoni Maiò -Affissà u Testu di i Buttoni -800 -&Aghjunghje u cartulare à i Favuriti cum'è -Indetta -900 -&Ozzioni... -&Sperimentu di pussibilità -960 -&Cuntenutu (in inglese)... -&Apprupositu di 7-Zip... -1003 -Passeghju -Nome -Estensione -Cartulare -Dimensione -Dimensione Cumpressa -Attributi -Creatu u -Accessu u -Mudificatu u -Solidu -Cummentatu -Cifratu -Frazziunà Nanzu -Frazziunà Dopu -Dizziunariu - -Tipu -Anti -Metoda -OS ospite -Sistema di Schedariu -Utilizatore -Gruppu -Bloccu -Cummentu -Pusizione -Prefissu di Passeghju -Cartulari -Schedarii -Versione -Vulume -Multi-Vulume -Offset -Leie -Blocchi -Vulumi - -64-bit -Big-endian -CPU -Dimensione Fisica -Dimensione di l'Intestature -Somma di cuntrollu -Caratteristiche -Indirizzu Virtuale -ID -Nome Cortu -Appiecazione d'Urigine -Dimensione di Settore -Modu -Leia Simbolica -Sbagliu -Dimensione Tutale -Spaziu Liberu -Dimensione di Cluster -Nome di Vulume -Nome Lucale -Furnidore -Sicurità NT -Flussu Alternativu -Ausiliaru -Squassatu -In Arburu - - -Tipu di Sbagliu -Sbaglii -Sbaglii -Avertimenti -Avertimentu -Flussi -Flussi Alternativi -Dimensione di i Flussi Alternativi -Dimensione Virtuale -Dimensione Senza Compressione -Dimensione Fisica Tutale -Indice di Vulume -SottuTipu -Cummentu Cortu -Pagina di Codice - - - -Dimensione di a Coda -Dimensione di u Mozzicone Incurpuratu -Leia -Leia Solida -iNode - -Lettura sola -2100 -Ozzioni -Lingua -Lingua : -Editore -&Editore : -Paragunà e sfarenze : -2200 -Sistema -Assucià 7-Zip cù : -Tutti l'utilizatori -2301 -Integrà 7-Zip à l'interfaccia cuntestuale -Interfaccia cuntestuale in cascata -Elementi di l'interfaccia cuntestuale : -Icone in l'interfaccia cuntestuale -2320 - - -Apre l'archiviu -Estrae i schedarii... -Aghjunghje à l'archiviu... -Verificà l'archiviu -Estrae Quì -Estrae ver di {0} -Aghjunghje à {0} -Cumprime è mandà da email... -Cumprime ver di {0} è mandà da email. -2400 -Cartulari -Cartulare di &travagliu -Cartulare timpurariu di &sistema -&Currente -&Specificatu : -Impiegà solu per i dischi amuvibili -Specificate un cartulare per i schedarii timpurarii d'archiviu. -2500 -Preferenze -Affissà l'elementu ".." -Affissà e vere icone di i schedarii -Affissà l'interfaccia sistema -Selezziunà tutta a linea -Affissà linee &quadrittate -Cliccu unicu per apre un elementu -Modu di selezzione &alternativa -Impiegà pagine maiò di memoria -2900 -Apprupositu di 7-Zip -7-Zip hè un prugramma liberu.\n\nTraduttu in lingua corsa da Patriccollu di Santa Maria è Sichè. -3000 -U sistema ùn pò micca attribuisce a quantità richiesta di memoria -Ùn ci hè micca sbagliu -{0} ughjettu(i) selezziunatu(i) -U cartulare '{0}' ùn pò micca esse creatu -L'azzioni di mudificazione ùn sò micca pussibule per quessu archiviu. -U schedariu '{0}' ùn pò micca esse apertu cum'è un archiviu -L'archiviu cifratu '{0}' ùn pò micca esse apertu. Parolla d'intrata falsa ? -Stu tipu d'archiviu ùn hè micca accettatu -U schedariu {0} esiste dighjà -U schedariu '{0}' hè statu mudificatu.\nVulete cambiallu in l'archiviu ? -Ùn hè micca pussibule di cambià u schedariu\n'{0}' -Ùn hè micca pussibule d'avvià l'editore. -U schedariu hè podasse infettatu da un virus (u so nome cuntene spazii numerosi). -St'azzione ùn pò micca fassi dapoi un cartulare cù u nome di passeghju cusì longu. -Ci vole à selezziunà un schedariu -Ci vole à selezziunà al menu un schedariu -Troppu elementi -Ùn hè micca pussibule d'apre u schedariu cum'è un archiviu {0} -U schedariu hè apertu cum'è un archiviu {0} -L'archiviu hè apertu cù offset -3300 -Estrazzione -Cumpressione -Verificazione -Apertura... -Esplurazione... -Cacciatura -3320 -Aghjuntu -Mudificazione -Analisa -Riproduzzione -Rimballasgiu -Tralasciamentu -Squassatura -Creazione di l'intestatura in corsu -3400 -Estrae -E&strae ver di : -Sciglite un cartulare per l'estrazzione di i schedarii. -3410 -Modu di passeghju : -Nomi cumpletti di passeghju -Alcunu nome di passeghju -Nomi assuluti di passeghju -Nomi relativi di passeghju -3420 -Modu di rimpiazzamentu : -Cunfirmà nanzu di rimpiazzà -Rimpiazzà senza dumandà -Ignurà i schedarii esistenti -Rinumà autumaticamente -Rinumà autumaticamente i schedarii esistenti -3430 -Ùn cupià micca u cartulare di radica -Risturà a sicurità di i schedarii -3500 -Cunfirmà u Rimpiazzamentu di Schedariu -U cartulare di distinazione cuntene dighjà un schedariu cù stu nome. -Vulete rimpiazzà u schedariu esistentu -cù quessu ? -{0} ottetti -Rinumà &Autumaticamente -3700 -Metoda di cumpressione micca accettatu per '{0}'. -Sbagliu di dati in '{0}'. U schedariu hè alteratu. -Fiascu di l'ispezzione CRC per u schedariu '{0}'. U schedariu hè alteratu. -Sbagliu di dati in u schedariu cifratu '{0}'. Parolla d'intrata falsa ? -Fiascu di l'ispezzione CRC per u schedariu cifratu '{0}'. Parolla d'intrata falsa ? -3710 -Parolla d'intrata falsa ? -3721 -Metoda di compressione micca accettatu -Sbagliu di dati -Fiascu di CRC -Dati micca dispunibule -Fine inaspettata di dati -Ci hè d'altri dati dopu à a fine di i dati ghjuvevule -Ùn hè un archiviu -Sbagliu d'Intestature -Parolla d'intrata falsa -3763 -Principiu di l'archiviu micca dispunibule -Principiu di l'archiviu micca confirmatu - - - -Funzione micca accettata -3800 -Scrivite a parolla d'intrata -Scrivite a parolla d'intrata : -Scrivite torna a parolla d'intrata : -&Affissà a parolla d'intrata -E parolle d'intrata sò sfarente -Per a parolla d'intrata, pudete impiegà solu : lettere senza aletta, cifri è segni particulari (!, #, $, ...) -A parolla d'intrata hè troppu longa -Parolla d'intrata -3900 -Tempu passatu : -Tempu rimanentu : -Dimensione tutale : -Celerità : -Prucessu : -Reditu di cumpressione : -Sbaglii : -Archivii : -4000 -Aghjunghje à l'archiviu -&Archiviu : -Modu di m&udificazione : -&Forma d'archiviu : -&Livellu de cumpressione : -&Metoda di cumpressione : -&Dimensione di u dizziunariu : -Dimensione di &e parolle : -Dimensione di u bloccu solidu : -Numeru di flussi CPU : -&Parametri : -Ozzioni -Creà un archiviu SF&X -Cumprime schedarii sparti -Cifratura -Metoda di cifratura : -Cifrà i &nomi di schedariu -Memoria impiegata da a Cumpressione : -Memoria impiegata da a Scumpressione : -Squassà i schedarii dopu à a cumpressione -4040 -Cunservà e leie simboliche -Cunservà e leie solide -Cunservà i flussi di dati alternativi -Cunservà a sicurità di i schedarii -4050 -Alcuna -A più rapida -Rapida -Nurmale -Massima -Ultra -4060 -Aghjunghje è rimpiazzà i schedarii -Mudificà è aghjunghje i schedarii -Attualizà i schedarii esistenti -Sincrunizà i schedarii -4070 -Sfuglià -Tutti i Schedarii -Non-solidu -Solidu -6000 -Cupià -Dispiazzà -Cupià ver di : -Dispiazzà ver di : -Copia in corsu... -Dispiazzamentu in corsu... -Cambiamentu di nome in corsu... -Selezziunà u cartulare di distinazione. -St'azzione ùn hè micca accettata per stu cartulare. -Sbagliu durante u Cambiu di Nome di Schedariu o di Cartulare -Cunfirmazione di a Copia di Schedariu -Site sicuru di vulè cupià u(i) schedariu(i) ver di l'archiviu -6100 -Cunfirmà a Squassatura di u Schedariu -Cunfirmà a Squassatura di u Cartulare -Cunfirmà a Squassatura di Schedarii Multiplice -Site sicuru di vulè squassà '{0}' ? -Site sicuru di vulè squassà u cartulare '{0}' è tuttu u so cuntenutu ? -Site sicuru di vulè squassà sti {0} elementi ? -Squassatura in corsu... -Sbagliu durante a Squassatura di Schedariu o di Cartulare -U sistema ùn pò micca mette à a Rumenzula un schedariu cù u nome di passeghju cusì longu -6300 -Creà un Cartulare -Creà un Schedariu -Nome di cartulare : -Nome di schedariu : -Novu Cartulare -Novu Schedariu -Sbagliu durante a Creazione di Cartulare -Sbagliu durante a Creazione di Schedariu -6400 -Cummentu -&Cummentu : -Selezziunà -Ùn Selezziunà -Filtru : -6600 -Pruprietà -Crunulugia di i Cartulari -Messaghji di diagnosticu -Messaghju -7100 -Urdinatore -Reta -Ducumenti -Sistema -7200 -Aghjunghje -Estrae -Verificà -Cupià -Dispiazzà -Squassà -Infurmazione -7300 -Sparte u schedariu -&Sparte in : -Sparte in &vulumi, ottetti : -Spartimentu... -Cunfirmà u Spartimentu -Site sicuru di vulè sparte u schedariu in {0} vulumi ? -A dimensione di u vulume deve esse più chjucu chì u schedariu d'urighjine -Dimensione di vulume falsa -Dimensione di vulume specificata : {0} ottetti.\nSite sicuru di vulè taglià l'archiviu in tali vulumi ? -7400 -Unisce i Schedarii -&Unisce in : -Unione... -Selezziunà solu a prima parte di l'archiviu spartutu -Ùn si trova alcuna parte d'archiviu spartutu -Ùn si trova micca più d'una parte d'archiviu spartutu -7500 -Calculu di a somma di cuntrollu... -Infurmazione nant'à a somma di cuntrollu -Somma di cuntrollu CRC per i dati : -Somma di cuntrollu CRC per i dati è i nomi : -7600 -Sperimentu di pussibilità -Memoria impiegata : -Cumpressione -Scumpressione -Percentuale -Percentuale tutale -Attuale -Risultante -Impiegu CPU -Estimatu / Impiegatu -Passagi : -7700 -Leia -Ligà -Leia d'urigine : -Leia di distinazione : -7710 -Tipu di Leia -Leia Solida -Leia Simbolica di Schedariu -Leia Simbolica di Cartulare -Unione di Cartulare diff -Nru p7zip-rar-16.02/GUI/Lang/cs.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/cs.txt --- p7zip-rar-16.02/GUI/Lang/cs.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/cs.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.30 : Milan Hrubý -; 4.33 : Michal Molhanec -; 9.07 : Jiří Malák -; -; -; -; -; -; -; -; -0 -7-Zip -Czech -Čeština -401 -OK -Storno - - - -&Ano -&Ne -Zavří&t -Nápověda - -Po&kračovat -440 -Ano na &všechno -N&e na všechno -Zastavit -Spustit znovu -&Pozadí -P&opředí -Po&zastavit -Pozastaveno -Jste si jistí, že to chcete stornovat? -500 -&Soubor -Úpr&avy -&Zobrazení -&Oblíbené -&Nástroje -Nápo&věda -540 -&Otevřít -Otevřít u&vnitř -Otevřít &mimo -&Zobrazit -&Upravit -&Přejmenovat -Kopírovat &do... -Př&esunout do... -Vymaza&t -&Rozdělit soubor... -&Sloučit soubory... -Vlast&nosti -Poznámk&a -Vypočítat kontrolní součet -Porovnat soubory -Vytvořit složku -Vytvořit soubor -&Konec -600 -Vybrat &vše -Zrušit výběr vše -&Invertovat výběr -Vybrat... -Zrušit výběr... -Vybrat podle typu -Zrušit výběr podle typu -700 -&Velké ikony -&Malé ikony -&Seznam -&Podrobnosti -730 -&Bez třídění -"Ploché" zobrazení -&2 panely -Nástrojové lišty -Otevřít kořenovou složku -O úroveň výš -Historie složek... -&Obnovit -750 -Archivační lišta -Standardní lišta -Velká tlačítka -Zobrazovat text tlačítek -800 -&Přidat složku do oblíbených jako -Záložka -900 -&Možnosti... -&Zkouška výkonu -960 -&Obsah... -O progr&amu 7-Zip... -1003 -Cesta -Název -Přípona -Složka -Velikost -Komprimovaná velikost -Atributy -Vytvořen -Použit -Změněn -Pevný -S poznámkou -Zakódovaný -Rozdělen do -Rozdělen od -Slovník -CRC -Typ -Anti -Metoda -Hostitelský OS -Souborový systém -Uživatel -Skupina -Blok -Poznámka -Pozice -Cesta -Složky -Soubory -Verze -Díl -Vícedílný -Offset -Odkazy -Bloků -Dílů - -64-bit -Big-endian -Pocesor -Fyzická velikost -Velikost hlaviček -Kontrolní součet -Charakteristiky -Virtuální adresa -ID -Krátké jméno -Autor -Velikost sektoru -Režim -Odkaz -Chyba -Celková velikost -Volné místo -Velikost clusteru -Označení -Místní název -Poskytovatel -2100 -Možnosti -Jazyk -Jazyk: -Editor -&Editor: -Program pro &porovnání souborů: -2200 -Systém -Asociovat 7-Zip s: -2301 -&Integrovat 7-Zip do kontextového menu -S&tupňovité kontextové menu -&Položky kontextového menu: -2320 - - -Otevřít -Rozbalit soubory... -Přidat do archivu... -Zkontrolovat archiv -Rozbalit zde -Rozbalit do {0} -Přidat do {0} -Zkomprimovat a odeslat poštou... -Zkomprimovat do {0} a odeslat poštou -2400 -Složky -Pracovní složka -&Systémová složka pro dočasné soubory -&Aktuální -S&ložka: -&Používat pouze pro vyjímatelné disky -Vyberte umístění pro dočasné komprimované soubory. -2500 -Nastavení -Zobrazovat položku ".." -Zobrazovat skutečnou ikonu souboru -Zobrazovat systémové menu -&Vybírat celý řádek -Zobrazovat &mřížku -Otevřít položku jedním kliknutím -&Alternativní způsob výběru -&Používat velké stránky paměti -2900 -O programu 7-Zip -7-Zip je svobodný software. Nicméně můžete podpořit jeho vývoj registrací. -3000 -Systém nemůže přidělit požadovanou velikost paměti -Nedošlo k žádným chybám -vybráno {0} objekt(ů) -Nelze vytvořit složku '{0}' -Aktualizace není podporována pro tento archiv. -Soubor '{0}' nelze otevřít jako archiv -Zakódovaný archiv '{0}' nelze otevřít. Špatné heslo? -Nepodporovaný typ archivu -Soubor {0} již existuje -Soubor '{0}' byl změněn.\nChcete ho aktualizovat v archivu? -Nelze aktualizovat soubor\n'{0}' -Editor nelze spustit. -Soubor se jeví jako virus (ve jménu souboru jsou dlouhé mezery). -Operace nemůže být provedena ze složky s dlouhou cestou. -Musíte vybrat jeden soubor -Musíte vybrat jeden nebo více souborů -Příliš mnoho položek -3300 -Rozbalování -Komprimování -Konrola -Otevírání... -Prohledávání... -3400 -Rozbalit -&Rozbalit do: -Vyberte umístění pro rozbalené soubory. -3410 -Cesty -Plné cesty -Bez cesty -3420 -Způsob přepisování -Zeptat se před přepisem -Přepsat bez výzvy -Přeskočit existující soubory -Automatické přejmenování -Automatické přejmenování existujících souborů -3500 -Potvrzení nahrazení souboru -Cílová složka již obsahuje zpracovaný soubor. -Chcete nahradit existující soubor -tímto? -{0} bajtů -A&utomaticky přejmenovat -3700 -Nepodporovaná komprimační metoda pro '{0}'. -Chyba dat v '{0}'. Soubor je poškozený. -Chyba CRC v '{0}'. Soubor je poškozený. -Chyba dat v zakódovaném souboru '{0}'. Chybné heslo? -Chyba CRC v zakódovaném souboru '{0}'. Chybné heslo? -3800 -Vložit heslo -Vložit heslo: -Potvrzení hesla: -Zobrazit he&slo -Heslo nesouhlasí -Pro heslo použíjte pouze anglická písmena, číslice a speciální znaky (!, #, $, ...) -Heslo je příliš dlouhé -Heslo -3900 -Uplynulý čas: -Zbývající čas: -Celková velikost: -Rychlost: -Zpracováno: -Komprimační poměr: -Chyb: -Archívy: -4000 -Přidat do archivu -&Archiv: -Způsob aktualizace: -&Formát archivu: -Ú&roveň komprese: -&Komprimační metoda: -Ve&likost slovníku: -V&elikost slova: -Velikost bloku: -Počet vláken procesoru: -&Parametry: -Možnosti -Vytvořit SF&X archiv -Zkomprimovat otevřené soubory -Zakódování -Metoda zakódování: -Zakódovat &názvy souborů -Spotřeba paměti pro zabalení: -Spotřeba paměti pro rozbalení: -4050 -Skladovací -Nejrychlejší -Rychlá -Normální -Maximální -Ultra -4060 -Přidat a nahradit soubory -Aktualizovat a přidat soubory -Aktualizovat existující soubory -Synchronizovat soubory -4070 -Procházet -Všechny soubory -Podle velikosti souboru -Pevný -6000 -Kopírovat -Přesunout -Kopírovat do: -Přesunout do: -Kopírování... -Přesouvání... -Přejmenování... -Vyberte cílovou složku. -Operace není podporována. -Chyba při přejmenování souboru nebo složky -Potvrzení kopírování souborů -Jste si jistí, že chcete zkopírovat soubory do archivu -6100 -Potvrdit vymazání souboru -Potvrdit vymazání složky -Potvrdit mnohonásobné vymazání souboru -Jste si jistí, že chcete vymazat '{0}'? -Jste si jistí, že chcete vymazat složku '{0}' a všechno co obsahuje? -Jste si jistí, že chcete vymazat tyto {0} položky? -Mazání... -Chyba při mazání souboru nebo složky -Systém nepodporuje přesun soubor s dlouhou cestou do Odpadkového koše -6300 -Vytvořit složku -Vytvořit soubor -Název složky: -Název souboru: -Nová složka -Nový soubor -Chyba při vytváření složky -Chyba při vytváření souboru -6400 -Poznámka -&Poznámka: -Vybrat -Zrušit výběr -Maska: -6600 -Vlastnosti -Historie složek -Diagnostické zprávy -Zpráva -7100 -Počítač -Síť -Dokumenty -Systém -7200 -Přidat -Rozbalit -Zkontrolovat -Kopírovat -Přesunout -Vymazat -Informace -7300 -Rozdělit soubor -Rozdělit do: -Rozdělit na díly, bajtů: -Rozdělování... -Potvrdit rozdělování -Jste si jistí, že chcete rozdělit soubor na {0} dílů? -Velikost dílu musí být menší než velikost původního souboru -Nesprávná velikost dílu -Zadaná velikost dílu: {0} bytů.\nJste si jistí, že chcete rozdělit archiv do takových dílů? -7400 -Sloučit soubory -Sloučit do: -Slučování... -Musí se vybrat pouze první díl rozděleného soubor -Nepodařilo se rozpoznat rozdělený soubor -Nepodařilo se nalézt více než jeden díl rozděleného souboru -7500 -Vypočítávání kontrolního součtu... -Informace o kontrolním součtu -CRC kontrolní součet pro data: -CRC kontrolní součet pro data a jména: -7600 -Zkouška výkonu -Spotřeba paměti: -Komprimování -Rozbalování -Výkon -Celkový výkon -Aktuální -Výsledné -Využití procesoru -Výkon / Využití -Průchodů: diff -Nru p7zip-rar-16.02/GUI/Lang/cy.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/cy.txt --- p7zip-rar-16.02/GUI/Lang/cy.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/cy.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.37 : Owain Lewis -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Welsh -Cymraeg -401 -Iawn -Canslo - - - -&Iawn -&Na -&Cau -Cymorth - -P&arhau -440 -Iawn i'r &Cwbwl -Na i'r C&wbwl -Stopio -Ailgychwyn -&Cefndir -&Blaendir -&Pwyllo -Pwyllo -Ydych chi am canslo? -500 -&Ffeil -&Golygu -Gwe&ld -Ff&efrynnau -&Offer -&Cymorth -540 -&Agor -Agor tu &Mewn -Agor tu &Fas -Gwe&ld -&Golygu -A&ilenwi -&Copïo i... -&Symud i... -&Dileu -&Hollti ffeil... -Cy&funo ffeilau... -&Priodweddau -Syl&wad -Cyfrifo swm-gwirio - -Creu Ffolder -Creu Ffeil -Alla&n -600 -Dewis y C&yfan -Dad-ddewis y Cyfan -Gwrt&hdroi'r Dewis -Dewis... -Dad-ddewis... -Dewis trwy Math -Dad-ddewis trwy Math -700 -Eiconau &Mawr -Eiconau &Bach -&Rhestr -Ma&nylion -730 -Dad-dosbarthu -Golwg Flat -&2 Paneli -Bariau &Offer -Agor Ffolder Gwraidd -Lan Un Lefel -Hanes Ffolderi... -&Adnewyddu -750 -Bar Offer Archif -Bar Offer Arferol -Botwmau Fawr -Dangos Testun Botwmau -800 -&Ychwanegu ffolder i Ffefrynnau fel -Llyfrnod -900 -&Dewisiadau... -&Meincnod -960 -&Cynnwys... -&Manylion 7-Zip... -1003 -Llwybr -Enw -Estyniad -Ffolder -Maint -Maint wedi'i Cywasgu -Priodweddau -Crëwyd -Cyrchwyd -Addaswyd -Solet -Sylwad -Amgryptio -Hollti Cyn -Hollti ar Ôl -Geiriadur -CRC -Math -Anti -Dull -SW Cynnal -System Ffeiliau -Ddefnyddiwr -Grŵp -Bloc -Sylwad -Safle -Rhagddodiad y Llwybr - - - - - - - - - - - - - - - - - - - - - - - - -Gwall -Cyfanswm Maint -Lle Rhydd -Maint Clwstwr -Label -Enw Lleol -Darparwr -2100 -Dewisiadau -Iaith -Iaith: -Golygydd -&Golygydd: - -2200 -System -Cysylltu 7-Zip gyda: -2301 -Cyfuno 7-Zip mewn i dewislen cyd-destun y cribyn -Dewislen cyd-destun wedi'i rhaeadru -Eitemau dewislen cyd-destun: -2320 - - -Agor archif -Echdynnu ffeiliau... -Ychwanegu i'r archif... -Profi archif -Echdynnu Yma -Echdynnu i {0} -Ychwanegu i {0} -Cywasgu ac e-bostio... -Cywasgu i {0} ac e-bostio -2400 -Ffolderi -Ffolder &gweithio -Ffolder tymor byr y &system -&Cyfredol -&Penodol: -Defnyddiwch am gyriant symudadwy yn unig -Nodwch lleoliad am ffeiliau archif tymor byr. -2500 -Gosodiadau -Dangos eitem ".." -Dangos eicon ffeil go iawn -Dangos dewislen y system -Dethol &holl rhes -Dangos llinellau &grid - -Modd dethol &arallddewisiol -Defnyddiwch tudalenau cof &mawr -2900 -Manylion 7-Zip -Mae 7-Zip yn meddalwedd am ddim. Ond, gallwch cefnogi y\ndatblygiad o 7-Zip trwy cofrestru. -3000 - -Mae na ddim wallau -{0} gwrthrych(au) dethol -Ddim yn gallu creu y ffolder '{0}' -Mae gweithrediadau diweddaru ddim yn ateg am yr archif hyn. - - - - -Roedd ffeil '{0}' wedi'i addasu.\nWyt ti moen ei diweddaru yn yr\narchif? -Ddim yn gallu diweddaru ffeil\n'{0}' -Ddim yn gallu dechrau golygydd. - - - - -Gormod o eitemau -3300 -Echdynnu -Cywasgu -Ymbrofi -Agor... -Sganio... -3400 -Echdynnu -E&chdynnu i: -Nodwch lleoliad am echdynnu ffeiliau. -3410 -Modd llwybr -Enwau llwybr llawn -Dim enwau llwybr -3420 -Modd disodli -Gofyn cyn disodli -Disodli heb awgrymeb -Crychneidio ffeiliau presennol -Ailenwu yn awtomatig -Ailenwu ffeiliau presennol yn awtomatig -3500 -Cadarnhau Disodli Ffeil -Mae'r ffolder hon eisioes yn cynnwys y ffeil cyrchfan. -Hoffech chi ddisodli'r ffeil sy'n bodoli eisioes -Gyda hon? -{0} beit -Ailenwi A&wtomatig -3700 -Modd cywasgu ddim yn dilys am '{0}'. -Gwall data mewn '{0}'. Ffeil wedi'i torri. -CRC wedi'i methu mewn '{0}'. Ffeil wedi'i torri. - - -3800 -Mewnbynnwch cyfrinair -Mewnbynnwch cyfrinair: - -&Dangos cyfrinair - - - -Cyfrinair -3900 -Wedi treiglo: -Amser a'r ôl: -Maint: -Cyflymder: - - -Gwallau: - -4000 -Ychwanegu i'r archif -&Archif: -Modd &diweddaru: -&Fformat yr archif: -&Lefel cywasgu: -Dull &cywasgu: -Maint &geiriadur: -Maint geiria&u: - - -&Paramedrau: -Dewisiadau -Creu archif SF&X - - - -Amgryptio &enwau ffeiliau -Defnydd cof am Cywasgu: -Defnydd cof am Datgywasgu: -4050 -Storio -Cyflymach -Cyflum -Arferol -Uchafswm -Ultra -4060 -Ychwanegu ac amnewid ffeiliau -Diweddaru ac ychwanegu ffeiliau -Adnewyddu y ffeiliau presennol -Cyfamseru ffeiliau -4070 -Pori -Pob Ffeil - - -6000 -Copïo -Symud -Copïo i: -Symud i: -Copïo... -Symud... -Ailenwi... - -Mae'r gweithrediad ddim wedi'i ategu. -Gwall wrth Ailenwi Ffeil neu Ffolder -Cadarnhau Copi Ffeil -Ydych chi'n siŵr eich bod am copïo'r ffeiliau i'r archif -6100 -Cadarnhau Dileu Ffeil -Cadarnhau Dileu Ffolder -Cadarnhau Dileu Ffeiliau Amryfal -Ydych chi'n siŵr eich bod am dileu '{0}'? -Ydych chi'n siŵr eich bod am dileu y ffolder '{0}' ac ei holl\ncynnwys? -Ydych chi'n siŵr eich bod am dileu yr eitemau hyn {0}? -Dileu... -Gwall Dileu Ffeil neu Ffolder - -6300 -Creu Ffolder -Creu Ffeil -Enw Ffolder: -Enw Ffeil: -Ffolder Newydd -Ffeil Newydd -Gwall wrth Creu Ffolder -Gwall wrth Creu Ffeil -6400 -Sylwad -&Sylwad: -Dewis -Dad-ddewis -Mwgwd: -6600 - -Hanes Ffolderi -Neges diagnostig -Neges -7100 -Cyfrifiadur -Rhyngrwyd - -System -7200 -Ychwanegu -Echdynnu -Profi -Copïo -Symud -Dileu -Gwybodaeth -7300 -Hollti Ffeil -&Hollti i: -Hollti i &cyfeintiau, beitiau: -Hollti... - - - - - -7400 -Cyfuno Ffeiliau -&Cyfuno i: -Cyfuno... - - - -7500 -Cyfrifo swm-gwirio... -Gwybodaeth swm-gwirio -Swm-gwirio CRC am data: -Swm-gwirio CRC am data ac enwau: -7600 -Meincnod -Defnyddiad cof: -Cywasgu -Datgywasgu -Amcangyfrif -Amcangyfrif llwyr -Presennol -Canlyniad - - -Pasio: diff -Nru p7zip-rar-16.02/GUI/Lang/da.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/da.txt --- p7zip-rar-16.02/GUI/Lang/da.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/da.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Jakob Schmidt -; 9.07 : Kian Andersen, Jørgen Rasmussen -; 15.00 : 2016-04-08 : scootergrisen -; -; -; -; -; -; -; -; -0 -7-Zip -Danish -Dansk -401 -OK -Annuller - - - -&Ja -&Nej -&Luk -Hjælp - -&Fortsæt -440 -Ja til &alle -Nej til a&lle -Stop -Genstart -&Baggrund -&Forgrund -&Pause -Pauset -Er du sikker på du vil annullere? -500 -&Filer -R&ediger -&Vis -F&avoritter -Funk&tioner -&Hjælp -540 -&Åbn -Åbn &inden i -Åbn &uden for -&Vis -&Rediger -O&mdøb -&Kopier til... -&Flyt til... -S&let -&Opdel fil... -Kom&biner filer... -&Egenskaber -Komme&ntar... -Udregn checksum -Sammenlign -Opret mappe -Opret fil -&Afslut -Opret/rediger genvej -&Alternative streams -600 -Vælg &alle -Fravælg alle -&Omvendt markering -Vælg... -Fravælg... -Vælg efter type -Fravælg efter type -700 -Sto&re ikoner -S&må ikoner -&Liste -&Detaljer -730 -Usorteret -Flad visning -&2 paneler -&Værktøjslinjer -Åbn rodmappe -Et niveau op -Mappehistorik... -&Opdater -Opdater automatisk -750 -Arkivlinje -Standardlinje -Store knapper -Vis knappernes tekst -800 -&Føj mappe til Favoritter som -Bogmærke -900 -&Indstillinger... -&Benchmark -960 -&Indhold... -&Om 7-Zip... -1003 -Sti -Navn -Filtype -Mappe -Størrelse -Pakket størrelse -Attributter -Oprettet -Åbnet -Ændret -Solid -Kommentar -Krypteret -Opdeling før -Opdeling efter -Leksikon - -Type -Anti -Metode -Vært OS -Filsystem -Bruger -Gruppe -Blok -Kommentar -Position -Sti præfiks -Mapper -Filer -Version -Bind -Flerbindsarkiv -Offset -Links -Blokke -Bind - -64-bit -Big-endian -CPU -Fysisk størrelse -Headerstørrelse -Checksum -Karakteristika -Virtuel adresse -ID -Kort navn -Oprettende program -Sektorstørrelse -Tilstand -Link -Fejl -Samlet størrelse -Fri plads -Clusterstørrelse -Etiket -Lokalt navn -Udbyder -NT Security -Alternativ stream -Aux -Slettet -Er træ - - -Fejltype -Fejl -Fejl -Advarsler -Advarsel -Streams -Alternative streams -Alternative streamsstørrelse -Virtuel størrelse -Udpakket størrelse -Samlet fysiske størrelse -Bind-indeks -Undertype -Kort kommentar -Tegnsæt - - - -Halestørrelse -Indlejret stumpstørrelse -Genvej -Fast forbindelse (Hard Link) -iNode - -Skrivebeskyttet -2100 -Indstillinger -Sprog -Sprog: -Redigering -&Rediger: -&Sammenlign (Diff): -2200 -System -Knyt 7-Zip til: -Alle brugere -2301 -Vis i Windows genvejsmenu -Brug undermenu -Punkter i genvejsmenu: -Ikoner i genvejsmenu -2320 - - -Åbn arkiv -Udpak filer... -Føj til arkiv... -Undersøg arkiv -Udpak her -Udpak til {0} -Føj til {0} -Pak og e-mail... -Pak til {0} og e-mail -2400 -Mapper -&Arbejdsmappe -&Systemets temp-mappe -&Nuværende -&Brugerdefineret: -Brug kun til flytbare drev -Angiv placering til midlertidige filer. -2500 -Indstillinger -Vis ".." element -Vis rigtige filikoner -Vis systemmenu -&Markér hele rækken -Vis &gitter -Ét klik for at åbne element -&Alternativ markeringsmetode -Brug &store hukommelsessider -2900 -Om 7-Zip -7-Zip er fri software -3000 -Systemet kan ikke tildele den nødvendige mængde hukommelse -Der er ingen fejl -{0} markerede element(er) -Kan ikke oprette mappe '{0}' -Arkivet understøtter ikke opdatering. -Kan ikke åbne filen '{0}' som arkiv -Kan ikke åbne krypterede arkiv '{0}'. Forkert adgangskode? -Arkivtypen er ikke understøttet -Filen {0} findes allerede -Filen '{0}' er blevet ændret.\nVil du opdatere den i arkivet? -Kan ikke opdatere filen\n'{0}' -Kan ikke starte redigering. -Filen ligner en virus (filnavnet indeholder lange mellemrum i navn). -Handlingen kan ikke kaldes fra en mappe med lang sti. -Du skal vælge en fil -Du skal vælge en eller flere filer -For mange elementer -Kan ikke åbne filen som {0}-arkiv -Filen er åbnet som {0}-arkiv -Arkivet er åbnet med offset -3300 -Udpakker -Nedpakker -Undersøger -Åbner... -Skanner... -Fjerner -3320 -Tilføjer -Opdaterer -Analyserer -Replikerer -Ompakker -Overspringer -Sletter -Opretter header -3400 -Udpak -U&dpak til: -Vælg en placering til udpakkede filer. -3410 -Stitype -Fulde stinavne -Ingen stinavne -Absolutte stinavne -Relative stinavne -3420 -Erstatningstype: -Spørg før erstatning -Erstat uden at spørge -Spring eksisterende filer over -Omdøb automatisk -Omdøb automatisk eksisterende filer -3430 -Forhindre duplikering af rodmappe -Genskab filsikkerhed -3500 -Bekræft filerstatning -Destinationsmappen indeholder allerede behandlede filer. -Ønsker du at udskifte den eksisterende fil -med denne? -{0} bytes -A&utomatisk omdøbning -3700 -Ikke understøttet pakkemetode for '{0}'. -Datafejl i '{0}'. Filen er ødelagt. -CRC mislykkedes i '{0}'. Filen er ødelagt. -Datafejl i den krypterede fil '{0}'. Forkert adgangskode? -CRC mislykkedes i den krypterede fil '{0}'. Forkert adgangskode? -3710 -Forkert adgangskode? -3721 -Pakkemetoden er ikke understøttet -Datafejl -CRC mislykkedes -Utilgængelig data -Uventet slutning på data -Der er data efter slutningen af nyttedataene -Ikke et arkiv -Fejl i headers -Forkert adgangskode -3763 -Utilgængelig begyndelse på arkiv -Ubekræftet begyndelse på arkiv - - - -Funktionen understøttes ikke -3800 -Indtast adgangskode -Indtast adgangskode: -Indtast adgangskode igen: -&Vis adgangskode -Adgangskoderne er ikke ens -Brug kun engelske bogstaver, numre og specialtegn (!, #, $, ...) til adgangskoden -Adgangskoden er for lang -Adgangskode -3900 -Forløbet tid: -Resterende tid: -Samlet størrelse: -Hastighed: -Behandlet: -Komprimeringsforhold: -Fejl: -Arkiver: -4000 -Føj til arkiv -&Arkiv: -O&pdateringstype: -Arkiv&format: -Komprimerings&niveau: -Pakke&metode: -Størrelse på or&dbog: -Størrelse på &ord: -Størrelse på solid block: -Antal CPU tråde: -Pa&rametre: -Funktioner -Opret selvudpakkende SF&X-arkiv -Komprimer delte filer -Kryptering -Krypteringsmetode: -Kr&ypter filnavne -Hukommelsesforbrug ved nedpakning: -Hukommelsesforbrug ved udpakning: -Slet filer efter komprimering -4040 -Gem symbolsk links -Gem hard links -Gem alternative data streams -Gem filsikkerhed -4050 -Kun gem -Hurtigste -Hurtig -Normal -Bedste -Ultra -4060 -Tilføj og erstat filer -Opdater og tilføj filer -Opdater eksisterende filer -Synkroniser filer -4070 -Gennemse -Alle filer -Non-solid -Solid -6000 -Kopier -Flyt -Kopier til: -Flyt til: -Kopierer... -Flytter... -Omdøber... -Vælg destinationsmappen. -Handlingen er ikke understøttet for denne mappe. -Fejl under omdøbning af fil eller mappe -Bekræft filkopiering -Er du sikker på at du vil kopiere filer til arkiv -6100 -Bekræft sletning af fil -Bekræft sletning af mappe -Bekræft sletning af flere filer -Er du sikker på du vil slette '{0}'? -Er du sikker på du vil slette mappen '{0}' og alt dens indhold? -Er du sikker på du vil slette disse {0} elementer? -Sletter... -Fejl under sletning af fil eller mappe -Systemet kan ikke flytte en fil med lang sti til Papirkurven -6300 -Opret mappe -Opret fil -Mappenavn: -Filnavn: -Ny mappe -Ny fil -Fejl under oprettelse af mappe -Fejl under oprettelse af fil -6400 -Kommentar -&Kommentar: -Vælg -Fravælg -Maske: -6600 -Egenskaber -Mappehistorik -Diagnostiske meddelelser -Meddelelse -7100 -Computer -Netværk -Dokumenter -System -7200 -Tilføj -Udpak -Test -Kopier -Flyt -Slet -Info -7300 -Opdel fil -&Opdel til: -Opd&el i bind, bytes: -Opdeler... -Bekræft opdeling -Er du sikker på du vil opdele filen i {0} bind? -Størrelsen på bind skal være mindre end størrelsen på den oprindelige fil -Forkert størrelse på bind -Angivet størrelse på bind: {0} bytes.\nEr du sikker på du ønsker, at opdele arkivet i disse bind? -7400 -Kombiner filer -&Kombiner til: -Kombinerer... -Vælg kun første del af opdelt fil -Kan ikke genkende fil, som del af en opdelt fil -Kan ikke finde mere end én del af opdelt fil -7500 -Beregner checksum... -Checksum information -CRC checksum for data: -CRC checksum for data og navne: -7600 -Benchmark -Hukommelsesforbrug: -Nedpakning -Udpakning -Vurdering -Samlet vurdering -Aktuelt -Resultat -CPU forbrug -Vurdering/forbrug -Gennemløb: -7700 -Opret/rediger genvej -Opret/rediger genvej -Genvej fra: -Genvej til: -7710 -Linktype -Fast forbindelse (Hard Link) -Fil symbolsk link -Mappe symbolsk link -Mappe forbindelsespunkt (Directory Junction) diff -Nru p7zip-rar-16.02/GUI/Lang/de.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/de.txt --- p7zip-rar-16.02/GUI/Lang/de.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/de.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 2.30 : Soeren Finster -; 4.07 : JAK-Software.DE -; 9.07 : Joachim Henke -; -; -; -; -; -; -; -; -0 -7-Zip -German -Deutsch -401 -OK -Abbrechen - - - -&Ja -&Nein -&Schließen -Hilfe - -&Fortsetzen -440 -Ja für &alle -Nein für a&lle -Stopp -Neustart -&Hintergrund -&Vordergrund -&Pause -Pause -Möchten Sie wirklich abbrechen? -500 -&Datei -&Bearbeiten -&Ansicht -&Favoriten -&Extras -&Hilfe -540 -Ö&ffnen -I&ntern öffnen -E&xtern öffnen -&Ansehen -&Bearbeiten -&Umbenennen -&Kopieren nach... -&Verschieben nach... -&Löschen -Datei auf&splitten... -Dateien &zusammenfügen... -E&igenschaften -K&ommentieren -&Prüfsumme berechnen -Ver&gleichen -Ordner erstellen -Datei erstellen -Be&enden -Verknüpfung... -&Alternative Datenströme -600 -Alles &markieren -Alles abwählen -Markierung &umkehren -Auswählen... -Auswahl aufheben... -Nach Typ auswählen -Nach Typ abwählen -700 -&Große Symbole -&Kleine Symbole -&Liste -&Details -730 -Unsortiert -Alles in einer &Ebene -&Zweigeteiltes Fenster -&Symbolleisten -Wurzelverzeichnis -Übergeordneter Ordner -Ordnerverlauf... -&Aktualisieren -Auto-Aktualisierung -750 -Archivfunktionen -Standardfunktionen -Große Schaltflächen -Schaltflächenbeschriftung -800 -&Ordner hinzufügen als -Favorit -900 -&Optionen... -&Benchmark -960 -&Hilfethemen -Ü&ber 7-Zip... -1003 -Pfad -Name -Erweiterung -Ordner -Größe -Gepackte Größe -Attribute -Erstellt am -Letzter Zugriff -Geändert am -Kompakt (solid) -Kommentiert -Verschlüsselt -Vorher geteilt -Danach geteilt -Wörterbuch -CRC -Typ -Anti -Verfahren -Herkunft -Dateisystem -Besitzer -Gruppe -Block -Kommentar -Position -Pfad -Ordner -Dateien -Version -Teilarchiv -Mehrteiliges Archiv -Offset -Verknüpfungen -Blöcke -Teilarchive - -64 Bit -Big-Endian -CPU -Gesamtgröße -Header-Größe -Prüfsumme -Kenndaten -Virtuelle Adresse -ID -Kurzname -Erstellt durch -Sektorgröße -Zugriffsrechte -Link -Fehler -Gesamtgröße -Freier Speicherplatz -Cluster-Größe -Name -Lokaler Name -Provider -NT-Sicherheit -Alternativer Datenstrom -Aux -Gelöscht -Ist Baum - - -Fehlertyp -Fehler -Fehler -Warnungen -Warnung -Datenströme -Alternative Datenströme -Größe der alternativen Datenströme -Virtuelle Größe -Entpackte Größe -Gesamte physikalische Größe -Teilstück Index -Untertyp -Kurzkommentar -Code-Seite - - - -Endungsgröße -integrierte Stub-Größe -Verknüpfung -Harte Verknüpfung -iNode - -Schreibgeschützt -2100 -Optionen -Sprache -Sprache: -Editor -&Editor: -Programm zum &Vergleichen: -2200 -System -7-Zip verknüpfen mit: -alle Benutzer -2301 -7-Zip in Kontextmenü integrieren -Kontextmenü kaskadieren -Einträge im Kontextmenü: -Symbole im Kontextmenü -2320 - - -Öffnen -Dateien entpacken... -Zu einem Archiv hinzufügen... -Archiv überprüfen -Hier entpacken -Entpacken nach {0} -Hinzufügen zu {0} -Archivieren und versenden... -Archivieren in {0} und versenden -2400 -Ordner -&Arbeitsverzeichnis -&TEMP-Ordner des Systems -Aktueller &Ordner -&Benutzerdefiniert: -Nur bei &Wechselmedien benutzen -Wählen Sie einen Ordner für temporäre Archivdateien: -2500 -Einstellungen -&Verzeichniseintrag ".." anzeigen -Symbole aus &Dateien laden und anzeigen -System-Kontext&menü im Dateimenü anzeigen -Dateiauswahl markiert ganze &Zeile -&Gitternetzlinien anzeigen -Einfacher &Klick zum Öffnen -&Alternativer Dateiauswahl-Modus -Große &Speicherseiten verwenden -2900 -Info über 7-Zip -7-Zip ist freie Software. Sie können jedoch das Projekt durch eine Registrierung unterstützen. -3000 -Das System kann die benötigte Speichermenge nicht bereit stellen. -Es sind keine Fehler aufgetreten. -{0} Objekt(e) markiert -Kann den Ordner "{0}" nicht erstellen. -Aktualisierungen werden für dieses Archiv nicht unterstützt. -Die Datei "{0}" kann nicht als Archiv geöffnet werden. -Das verschlüsselte Archiv "{0}" kann nicht geöffnet werden. Falsches Passwort? -Typ des Archives wird nicht unterstützt -Die Datei {0} existiert bereits. -Die Datei "{0}" wurde geändert.\nSoll sie im Archiv aktualisiert werden? -Die Datei konnte nicht aktualisiert werden.\n"{0}" -Kann Editor nicht starten -Die Datei scheint ein Virus zu sein (Dateiname enthält lange Reihen von Leerzeichen). -Die Operation kann nicht aus einem Ordner mit langem Pfad aufgerufen werden. -Bitte genau eine Datei auswählen. -Bitte mindestens eine Datei auswählen. -Zu viele Objekte -Die Datei kann nicht als {0}-Archiv geöffnet werden. -Die Datei wurde als {0}-Archiv geöffnet. -Die Datei wurde mit einem Offset geöffnet. -3300 -Entpacken -Komprimiere -Überprüfen -Öffne... -Durchsuche... -Entferne -3320 -Hinzufügen -Aktualisieren -Analysieren -Replizieren -Neu Packen -Überspringen -Löschen -Header erstellen -3400 -Entpacken -&Entpacken nach: -Wählen Sie einen Ordner für die entpackten Dateien: -3410 -Verzeichnisstruktur wiederherstellen -Komplette Pfadangaben -Keine Pfadangaben -Absolute Pfadangaben -Relative Pfadangaben -3420 -Dateien überschreiben -Nur mit Bestätigung -Ohne Bestätigung -Vorhandene Dateien überspringen -Automatisch umbenennen -Vorhandene Dateien umbenennen -3430 -Verdoppelung des Wurzelordners vermeiden -Dateirechte wiederherstellen -3500 -Überschreiben bestätigen -Der Zielordner beinhaltet bereits eine Datei diesen Namens. -Wollen Sie diese Datei -durch diese ersetzen? -{0} Bytes -A&utomatisch umbenennen -3700 -Das Kompressionsverfahren in "{0}" wird nicht unterstützt. -Datenfehler in "{0}". Die Datei ist beschädigt. -CRC-Prüfsummenfehler. Die Datei "{0}" ist beschädigt. -Datenfehler in der verschlüsselten Datei "{0}". Falsches Passwort? -CRC-Prüfsummenfehler bei verschlüsselter Datei "{0}". Falsches Passwort? -3710 -Falsches Passwort? -3721 -Nicht unterstützte Kompressionsmethode -Datenfehler -CRC-Fehler -Daten stehen nicht zur Verfügung -Unerwartetes Datenende -Es gibt noch Daten hinter den Hauptdaten -Ist kein Archiv -Headers-Fehler -Falsches Passwort -3763 -Anfang des Archivs fehlt -Anfang des Archivs nicht bestätigt - - - -Nicht unterstützte Funktion -3800 -Kennworteingabe -Passwort eingeben: -Passwort bestätigen: -Passwort an&zeigen -Die Passwörter stimmen nicht überein. -Bitte nur Buchstaben des englischen Alphabets, Ziffern und Sonderzeichen (!, #, $, ...) im Passwort verwenden! -Das Passwort ist zu lang. -Passwort -3900 -Verstrichene Zeit: -Verbleibende Zeit: -Gesamtdatenmenge: -Geschwindigkeit: -Verarbeitet: -Kompressionsrate: -Fehler: -Archive: -4000 -Zu Archiv hinzufügen -&Archiv: -Art der Akt&ualisierung: -Archiv&format: -&Kompressionsstärke: -Kompressions&verfahren: -Wörter&buchgröße: -&Wortgröße: -Größe &solider Blöcke: -Anzahl &CPU-Threads: -&Parameter: -Optionen -Selbstentpackendes Archiv (SF&X) erstellen -Zum Schreiben &geöffnete Dateien einbeziehen -Verschlüsselung -Verfahren: -Datei&namen verschlüsseln -Speicherbedarf beim Komprimieren: -Speicherbedarf beim Entpacken: -Dateien nach Komprimierung löschen -4040 -Symbolische Verknüpfungen speichern -Harte Verknüpfungen speichern -Alternative Datenströme speichern -Dateirechte speichern -4050 -Speichern -Schnellste -Schnell -Normal -Maximum -Ultra -4060 -Hinzufügen und Ersetzen -Aktualisieren und Hinzufügen -Vorhandene Dateien aktualisieren -Synchronisieren -4070 -Durchsuchen -Alle Dateien -Nicht solide -Solide -6000 -Kopieren -Verschieben -Kopieren nach: -Verschieben nach: -Kopiere... -Verschiebe... -Umbenennen... -Zielordner auswählen -Die Operation wird für diesen Ordner nicht unterstützt. -Fehler beim Umbenennen von Datei oder Ordner -Kopieren bestätigen -Sollen die Dateien wirklich in dieses Archiv kopiert werden: -6100 -Löschen von Datei bestätigen -Löschen von Ordner bestätigen -Löschen von mehreren Dateien bestätigen -Soll "{0}" wirklich gelöscht werden? -Soll der Ordner "{0}" und sein gesamter Inhalt wirklich gelöscht werden? -Sollen diese {0} Objekte wirklich gelöscht werden? -Lösche... -Fehler beim Löschen von Datei oder Ordner -Das System kann Dateien mit langem Pfad nicht in den Papierkorb verschieben. -6300 -Ordner erstellen -Datei erstellen -Ordnername: -Dateiname: -Neuer Ordner -Neue Datei -Fehler beim Erstellen des Ordners -Fehler beim Erstellen der Datei -6400 -Kommentar -&Kommentar: -Auswählen -Auswahl aufheben -Filter: -6600 -Eigenschaften -Ordnerverlauf -Diagnosemeldungen -Meldung -7100 -Arbeitsplatz -Netzwerk -Dokumente -System -7200 -Hinzufügen -Entpacken -Überprüfen -Kopieren -Verschieben -Löschen -Eigenschaften -7300 -Datei aufsplitten -Teildateien &nach: -In &Teildateien aufsplitten (Bytes): -Aufsplitten... -Aufsplitten bestätigen -Sind Sie sicher, die Datei in {0} Teildateien aufsplitten zu wollen? -Die Größe der Teildateien muss kleiner sein als die der ursprünglichen Datei. -Ungültiger Wert für Dateigrößen -Angegebene Größe für Teildateien: {0} Bytes.\nSind Sie sicher, dass das Archiv dementsprechend aufgesplittet werden soll? -7400 -Dateien zusammenfügen -Zieldatei &nach: -Zusammenfügen... -Bitte nur den ersten Teil der Datei auswählen. -Datei nicht als Teil einer aufgesplitteten Datei erkannt -Kann nicht mehr als eine Teildatei finden. -7500 -Berechne Prüfsumme... -Prüfsummen-Information -CRC-Prüfsumme über die Daten: -Prüfsumme über Daten und Namen: -7600 -Benchmark -Speichernutzung: -Komprimierung -Dekomprimierung -Bewertung -Gesamtwertung -Aktuell -Ergebnis -CPU-Nutzung -Bewert./Nutzung -Durchläufe: -7700 -Verknüpfung -Verknüpfung -Verknüpfung von: -Verknüpfung zu: -7710 -Verknüpfungsart -Harte Verknüpfung -Datei Symbolische Verknüpfung -Ordner Symbolische Verknüpfung -Ordner Verbindung diff -Nru p7zip-rar-16.02/GUI/Lang/el.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/el.txt --- p7zip-rar-16.02/GUI/Lang/el.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/el.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Vasileios Karakoidas, Jacaranda Bill, Vasilis Kosmidis -; 9.07 : SkyHi [HDManiacs Team] -; 15.00 : 2015-05-07: Pete D -; -; -; -; -; -; -; -; -0 -7-Zip -Greek -Ελληνικά -401 -OK -Άκυρο - - - -&Ναι -Ό&χι -&Κλείσιμο -Βοήθεια - -&Συνέχεια -440 -Ναι σε &όλα -Όχι σε ό&λα -&Παύση -Επανεκκίνηση -Στο &παρασκήνιο -Στο &προσκήνιο -&Παύση -Παύθηκε -Είστε σίγουροι ότι θέλετε να ακυρώσετε; -500 -&Αρχείο -&Επεξεργασία -Π&ροβολή -Αγα&πημένα -Εργα&λεία -&Βοήθεια -540 -Άν&οιγμα -Άνοιγμα στο &ίδιο παράθυρο -Άνοιγμα σε &νέο παράθυρο -Π&ροβολή -Επε&ξεργασία -Με&τονομασία -Αντι&γραφή... -Μετα&κίνηση... -Διαγρα&φή -&Τεμαχισμός αρχείου... -&Συνένωση αρχείων... -&Ιδιότητες -Σχόλιο -Υπολογισμός αθροίσματος ελέγχου -Diff -Δημιουργία φακέλου -Δημιουργία αρχείου -Έ&ξοδος -Σύνδεσμος -&Alternate Streams -600 -Ε&πιλογή όλων -Αποεπιλογή όλων -Αντιστροφή επιλογής -Επιλογή... -Αποεπιλογή... -Επιλογή σύμφωνα με τον τύπο αρχείου -Αποεπιλογή σύμφωνα με τον τύπο αρχείου -700 -Μεγάλα εικονί&δια -&Μικρά εικονίδια -&Λίστα -Λε&πτομέρειες -730 -Χωρίς ταξινόμηση -Επίπεδη προβολή -2 πάνελ -&Γραμμές εργαλείων -Άνοιγμα κεντρικού φακέλου -Μετάβαση ένα επίπεδο πάνω -&Ιστορικό φακέλων... -Α&νανέωση -Αυτόματη ανανέωση -750 -Συμπίεσης -Βασική -Μεγάλα εικονίδια -Εμφάνιση κειμένου -800 -&Προσθήκη καταλόγου στα Αγαπημένα ως -Σελιδοδείκτης -900 -&Ρυθμίσεις... -&Ελεγχος επιδόσεων -960 -&Περιεχόμενα... -Π&ερί του 7-Zip... -1003 -Θέση -Όνομα -Τύπος -Φάκελος -Μέγεθος -Συμπιεσμένο μέγεθος -Ιδιότητες -Δημιουργήθηκε -Προσπελάστηκε -Τροποποιήθηκε -Συμπαγές -Σχόλιο -Κωδικοποιημένο -Τεμαχισμός πριν -Τεμαχισμός μετά -Λεξικό - -Τύπος -Αντί -Μέθοδος -Λειτουργικό -Σύστημα αρχείων -Χρήστης -Ομάδα -Μπλοκ -Σχόλιο -Θέση -Προκαθορισμένη διαδρομή -Φάκελοι -Αρχεία -Έκδοση -Τόμος -Πολυτόμος -Offset -Σύνδεσμοι -Μπλοκ -Τόμοι - -64-bit -Big-endian -CPU -Φυσικό μέγεθος -Μέγεθος headers -Άθροισμα ελέγχου -Χαρακτηριστικά -Εικονική διεύθυνση -ID -Σύντομο όνομα -Εφαρμογή δημιουργίας -Μέγεθος τομέα -Κατάσταση λειτουργίας -Σύνδεσμος -Σφάλμα -Συνολικό μέγεθος -Ελεύθερος χώρος -Μέγεθος συμπλέγματος -Ετικέτα -Τοπικό όνομα -Παροχέας -NT Security -Alternate Stream -Aux -Deleted -Is Tree - - -Τύπος λάθους -Λάθη -Λάθη -Προειδοποιήσεις -Προειδοποίηση -Streams -Alternate Streams -Alternate Streams Size -Εικονικό μέγεθος -Αποσυμπιεσμένο μέγεθος -Συνολικό φυσικό μέγεθος -Ευρετήριο τόμου -SubType -Σύντομο σχόλιο -Κωδικοσελίδα - - - -Tail Size -Embedded Stub Size -Σύνδεσμος -Σταθερός σύνδεσμος -iNode - -Ανάγνωση-Μόνο -2100 -Ρυθμίσεις -Γλώσσα -Γλώσσα: -Πρόγραμμα επεξεργασίας -&Πρόγραμμα επεξεργασίας: -&Diff: -2200 -Σύστημα -Συσχέτιση του 7-Zip με τα αρχεία: -Ολοι οι χρήστες -2301 -Ενσωμάτωση του 7-Zip στο λειτουργικό -Με ομαδοποίηση των επιλογών -Στοιχεία του αναδυόμενου μενού: -Εικονίδια στο αναδυόμενο μενού -2320 -<Φάκελος> -<Αρχείο Συμπίεσης> -Άνοιγμα -Αποσυμπίεση αρχείων... -Προσθήκη σε αρχείο συμπίεσης... -Έλεγχος αρχείου συμπίεσης -Αποσυμπίεση εδώ -Αποσυμπίεση στο φάκελο {0} -Προσθήκη στο {0} -Συμπίεση και αποστολή με e-mail... -Συμπίεση στο {0} και αποστολή με e-mail -2400 -Φάκελοι -&Φάκελος εργασίας -&Προσωρινός φάκελος συστήματος -&Τρέχων φάκελος -&Καθορισμένος: -Χρήση μόνο για αφαιρούμενες μονάδες δίσκου -Καθορίστε μια τοποθεσία για τα προσωρινά αρχεία συμπίεσης. -2500 -Επιλογές -Εμφάνιση αντικειμένου ".." -Εμφάνιση των κανονικών εικονιδίων των αρχείων -Εμφάνιση μενού συστήματος -&Επιλογή ολόκληρης διαδρομής -Εμφάνιση γραμμών πλέγματος -Άνοιγμα αντικειμένου με μονό κλικ -Εναλλακτική κατάσταση επιλογής -Χρήση μεγάλων &σελίδων μνήμης -2900 -Πληροφορίες για το 7-Zip -Το 7-Zip είναι ελεύθερο λογισμικό. Ωστόσο μπορείτε να υποστηρίξετε την περαιτέρω ανάπτυξη του με την εγγραφή σας. -3000 -Το σύστημα δεν μπορεί να διαθέσει την απαιτούμενη ποσότητα μνήμης. -Δεν υπάρχουν σφάλματα -{0} επιλεγμένα στοιχεία -Αδύνατη η δημιουργία του φακέλου '{0}' -Οι λειτουργίες ενημέρωσης δεν είναι διαθέσιμες για αυτόν τον τύπο συμπιεσμένου αρχείου. -Δεν μπορεί να ανοιχθεί το αρχείο '{0}' σαν αρχείο συμπίεσης -Δεν μπορεί να ανοιχθεί το κρυπτογραφημένο αρχείο '{0}'. Λάθος κωδικός; -Μη υποστηριζόμενο αρχείο συμπίεσης. -Το αρχείο {0} ήδη υπάρχει. -Το αρχείο '{0}' τροποποιήθηκε.\nΘέλετε να ενημερώσετε το αρχείο συμπίεσης; -Αδυνατή η ενημέρωση του αρχείου\n'{0}' -Δεν είναι δυνατή η εκκίνηση του προγράμματος επεξεργασίας. -Το αρχείο μοιάζει με ιό (το όνομα του περιέχει μεγάλα κενά). -Η λειτουργία δεν μπορεί να κληθεί από ένα φάκελο που έχει μεγάλη διαδρομή. -Πρέπει να επιλέξετε ένα αρχείο. -Πρέπει να επιλέξετε ένα ή περισσότερα αρχεία. -Πάρα πολλά στοιχεία -Αδυναμία ανοίγματος του αρχείου ως {0} συμπιεσμένο -Το αρχείο είναι ανοιχτό ως {0} συμπιεσμένο -Το συμπιεσμένο αρχείο είναι ανοιχτό με offset -3300 -Αποσυμπίεση -Συμπίεση -Έλεγχος -Άνοιγμα... -Σάρωση... -Διαγραφή... -3320 -Προσθήκη.. -Ενημέρωση.. -Ανάλυση.. -Αντιγραφή.. -Επανασυμπίεση.. -Παράλειψη.. -Διαγραφή.. -Δημιουργία κεφαλίδας.. -3400 -Αποσυμπίεση -&Αποσυμπίεση στο φάκελο: -Καθορίστε τον φάκελο αποσυμπίεσης. -3410 -Επιλογές διαδρομών φακέλων -Πλήρεις διαδρομές φακέλων -Χωρίς διαδρομές φακέλων -Απόλυτες διαδρομές φακέλων -Σχετικές διαδρομές φακέλων -3420 -Επιλογές αντικατάστασης αρχείων -Αντικατάσταση με ερώτηση -Αντικατάσταση χωρίς ερώτηση -Παράβλεψη των υπαρχόντων αρχείων -Αυτόματη μετονομασία -Αυτόματη μετονομασία των υπαρχόντων αρχείων -3430 -Απαλοιφή ριζικού καταλόγου -Επαναφορά ασφάλειας αρχείου -3500 -Επιβεβαίωση αντικατάστασης του αρχείου -Ο φάκελος προορισμού περιέχει ήδη ένα αρχείο με το ίδιο όνομα. -Θέλετε να αντικαταστήσετε το υπάρχον αρχείο -με αυτό; -{0} bytes -Αυτόματη &μετονομασία -3700 -Μη υποστηριζόμενη μέθοδος συμπίεσης για το '{0}'. -Λάθος δεδομένων στο {0}. Το αρχείο είναι φθαρμένο. -Ο έλεγχος CRC απέτυχε στο '{0}'. Το αρχείο είναι φθαρμένο. -Λάθος δεδομένων στο κρυπτογραφημένο αρχείο '{0}'. Λάθος κωδικός; -Ο έλεγχος CRC απέτυχε στο κρυπτογραφημένο αρχείο '{0}'. Λάθος κωδικός; -3710 -Λάθος κωδικός; -3721 -Μη υποστηριζόμενη μέθοδος συμπίεσης -Λάθος δεδομένων -Ο έλεγχος CRC απέτυχε -Μη διαθέσιμα δεδομένα -Απρόβλεπτο τελείωμα δεδομένων -Υπάρχουν μερικα δεδομένα στο τέλος των χρήσιμων δεδομένων -Δεν είναι συμπιεσμένο αρχείο -Λάθος επικεφαλίδων -Λάθος κωδικός -3763 -Μη διαθέσιμη αρχή του συμπιεσμένου αρχείου -Ανεπιβεβαίωτη αρχή του συμπιεσμένου αρχείου - - - -Μη υποστηριζόμενη λειτουργία -3800 -Εισαγωγή κωδικού πρόσβασης -Κωδικός πρόσβασης: -Επανεισάγετε τον κωδικό πρόσβασης: -&Εμφάνιση κωδικού -Οι κωδικοί δεν ταιριάζουν. -Χρησιμοποιήστε μόνο Αγγλικά γράμματα, αριθμούς και ειδικούς χαρακτήρες (!, #, ...) για κωδικό. -Ο κωδικός είναι πολύ μεγάλος. -Κωδικός πρόσβασης -3900 -Διανύθηκε: -Απομένει: -Μέγεθος: -Ταχύτητα: -Επεξεργάσθηκαν: -Αναλογία συμπίεσης -Σφάλματα: -Αρχεία συμπίεσης: -4000 -Προσθήκη σε συμπιεσμένο αρχείο -&Όνομα αρχείου συμπίεσης: -&Τρόπος ενημέρωσης: -Συμπίεση στη μορ&φή: -Επίπεδο συμπίεσης: -&Μέθοδος συμπίεσης: -Μέγεθος &λεξικού: -Μέγεθος &λέξης: -Μέγεθος συμπαγούς μπλοκ: -Αριθμός νημάτων CPU -&Παράμετροι: -Επιλογές συμπίεσης -Με αυτόματη αποσυμπίεση (SF&X) -Συμπίεση κοινών αρχείων -Κρυπτογράφηση -Μέθοδος κρυπτογράφησης -Κρυπτογράφηση των &ονομάτων -Χρήση μνήμης για συμπίεση: -Χρήση μνήμης για αποσυμπίεση: -Διαγραφή αρχείων μετά τη συμπίεση -4040 -Αποθήκευση συμβολικών συνδέσμων -Αποθήκευση σταθερών συνδέσμων -Αποθήκευση ενναλλακτικών ροών δεδομένων -Αποθήκευση ασφάλειας αρχείου -4050 -Αποθήκευση -Πολύ γρήγορη -Γρήγορη -Κανονική -Μέγιστη -Υπερσυμπίεση -4060 -Προσθήκη και αντικατάσταση αρχείων -Προσθήκη και ενημέρωση αρχείων -Ενημέρωση των υπαρχόντων αρχείων -Συγχρονισμός αρχείων -4070 -Αναζήτηση -Όλα τα αρχεία -Μη-συμπαγές -Συμπαγές -6000 -Αντιγραφή -Μετακίνηση -Αντιγραφή στο: -Μετακίνηση στο: -Αντιγραφή... -Μετακίνηση... -Μετονομασία... -Επιλέξτε φάκελο προορισμού. -Η λειτουργία δεν υποστηρίζεται. -Παρουσιάστηκε σφάλμα κατά τη μετονομασία. -Επιβεβαίωση αντιγραφής αρχείων -Είστε βέβαιος ότι θέλετε να αντιγράψετε τα αρχεία στο αρχείο συμπίεσης; -6100 -Επιβεβαίωση διαγραφής του αρχείου -Επιβεβαίωση διαγραφής του φακέλου -Επιβεβαίωση διαγραφής πολλών αρχείων -Είστε βέβαιοι ότι θέλετε να διαγράψετε το '{0}' ; -Είστε βέβαιοι ότι θέλετε να διαγράψετε το φάκελο '{0}' και όλα τα περιεχόμενα του; -Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτά τα {0} στοιχεία; -Διαγραφή... -Παρουσιάστηκε σφάλμα κατά τη διαγραφή. -Το σύστημα δεν μπορεί να μετακινήσει ένα αρχείο με μεγάλη διαδρομή στον Κάδο Ανακύκλωσης. -6300 -Δημιουργία φακέλου -Δημιουργία αρχείου -Όνομα φακέλου: -Όνομα αρχείου: -Νέος φάκελος -Νέο αρχείο -Σφάλμα κατά την δημιουργία φακέλου. -Σφάλμα κατά την δημιουργία αρχείου. -6400 -Σχόλιο -&Σχόλιο: -Επιλογή -Αποεπιλογή -Με όνομα: -6600 -Ιδιότητες -Ιστορικό φακέλων -Διαγνωστικά μηνύματα -Μήνυμα -7100 -Υπολογιστής -Δικτύο -Έγγραφα -Σύστημα -7200 -Προσθήκη -Αποσυμπίεση -Έλεγχος -Αντιγραφή -Μετακίνηση -Διαγραφή -Πληροφορίες -7300 -Τεμαχισμός αρχείου -&Τεμαχισμός σε: -Τεμαχισμός σε τόμους: -Τεμαχισμός... -Επιβεβαίωση τεμαχισμού -Είστε βέβαιος ότι θέλετε να τεμαχίσετε το αρχείο σε {0} τόμους; -Το μέγεθος του τόμου πρέπει να είναι μικρότερο από αυτό του αρχικού αρχείου. -Λάθος μέγεθος τόμου -Καθορισμένο μέγεθος τόμου: {0} bytes.\nΕίστε σίγουρος ότι θέλετε να χωρίσετε το αρχείο σε τέτοιους τόμους; -7400 -Συνένωση αρχείων -&Συνένωση σε: -Συνένωση... -Επιλέξτε μόνο το πρώτο αρχείο -Το αρχείο δεν μπορεί να ανιχνευθεί ως μέρος τεμαχισμένου αρχείου. -Δεν μπορούν να βρεθούν πάνω από ένα μέρη τεμαχισμένου αρχείου. -7500 -Υπολογισμός αθροίσματος ελέγχου... -Πληροφορίες αθροίσματος ελέγχου -Άθροισμα ελέγχου CRC για δεδομένα: -Άθροισμα ελέγχου CRC για δεδομένα και ονόματα: -7600 -Αξιολόγηση επιδόσεων -Χρήση μνήμης: -Συμπίεση -Αποσυμπίεση -Εκτίμηση -Συνολ. εκτίμηση -Τρέχων πέρασμα -Αποτέλεσμα -Χρήση CPU -Ταξ/μιση/Χρήση -Περάσματα: -7700 -Σύνδεσμος -Σύνδεσμος -Σύνδεσμος από: -Σύνδεσμος έως: -7710 -Τύπος συνδέσμου -Σταθερός σύνδεσμος -Συμβολικός σύνδεσμος αρχείου -Συμβολικός σύνδεσμος καταλόγου -Συνένωση καταλόγου diff -Nru p7zip-rar-16.02/GUI/Lang/en.ttt p7zip-rar-16.02+really25.00+ds/GUI/Lang/en.ttt --- p7zip-rar-16.02/GUI/Lang/en.ttt 2015-03-29 11:30:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/en.ttt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.00 : 2015-03-29 : Igor Pavlov -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -English -English -401 -OK -Cancel - - - -&Yes -&No -&Close -Help - -&Continue -440 -Yes to &All -No to A&ll -Stop -Restart -&Background -&Foreground -&Pause -Paused -Are you sure you want to cancel? -500 -&File -&Edit -&View -F&avorites -&Tools -&Help -540 -&Open -Open &Inside -Open O&utside -&View -&Edit -Rena&me -&Copy To... -&Move To... -&Delete -&Split file... -Com&bine files... -P&roperties -Comme&nt... -Calculate checksum -Diff -Create Folder -Create File -E&xit -Link -&Alternate Streams -600 -Select &All -Deselect All -&Invert Selection -Select... -Deselect... -Select by Type -Deselect by Type -700 -Lar&ge Icons -S&mall Icons -&List -&Details -730 -Unsorted -Flat View -&2 Panels -&Toolbars -Open Root Folder -Up One Level -Folders History... -&Refresh -Auto Refresh -750 -Archive Toolbar -Standard Toolbar -Large Buttons -Show Buttons Text -800 -&Add folder to Favorites as -Bookmark -900 -&Options... -&Benchmark -960 -&Contents... -&About 7-Zip... -1003 -Path -Name -Extension -Folder -Size -Packed Size -Attributes -Created -Accessed -Modified -Solid -Commented -Encrypted -Split Before -Split After -Dictionary - -Type -Anti -Method -Host OS -File System -User -Group -Block -Comment -Position -Path Prefix -Folders -Files -Version -Volume -Multivolume -Offset -Links -Blocks -Volumes - -64-bit -Big-endian -CPU -Physical Size -Headers Size -Checksum -Characteristics -Virtual Address -ID -Short Name -Creator Application -Sector Size -Mode -Symbolic Link -Error -Total Size -Free Space -Cluster Size -Label -Local Name -Provider -NT Security -Alternate Stream -Aux -Deleted -Is Tree - - -Error Type -Errors -Errors -Warnings -Warning -Streams -Alternate Streams -Alternate Streams Size -Virtual Size -Unpack Size -Total Physical Size -Volume Index -SubType -Short Comment -Code Page - - - -Tail Size -Embedded Stub Size -Link -Hard Link -iNode - -Read-only -2100 -Options -Language -Language: -Editor -&Editor: -&Diff: -2200 -System -Associate 7-Zip with: -All users -2301 -Integrate 7-Zip to shell context menu -Cascaded context menu -Context menu items: -Icons in context menu -2320 - - -Open archive -Extract files... -Add to archive... -Test archive -Extract Here -Extract to {0} -Add to {0} -Compress and email... -Compress to {0} and email -2400 -Folders -&Working folder -&System temp folder -&Current -&Specified: -Use for removable drives only -Specify a location for temporary archive files. -2500 -Settings -Show ".." item -Show real file icons -Show system menu -&Full row select -Show &grid lines -Single-click to open an item -&Alternative selection mode -Use &large memory pages -2900 -About 7-Zip -7-Zip is free software -3000 -The system cannot allocate the required amount of memory -There are no errors -{0} object(s) selected -Cannot create folder '{0}' -Update operations are not supported for this archive. -Can not open file '{0}' as archive -Can not open encrypted archive '{0}'. Wrong password? -Unsupported archive type -File {0} is already exist -File '{0}' was modified.\nDo you want to update it in the archive? -Can not update file\n'{0}' -Cannot start editor. -The file looks like a virus (the file name contains long spaces in name). -The operation cannot be called from a folder that has a long path. -You must select one file -You must select one or more files -Too many items -Can not open the file as {0} archive -The file is open as {0} archive -The archive is open with offset -3300 -Extracting -Compressing -Testing -Opening... -Scanning... -Removing -3320 -Adding -Updating -Analyzing -Replicating -Repacking -Skipping -Deleting -Header creating -3400 -Extract -E&xtract to: -Specify a location for extracted files. -3410 -Path mode: -Full pathnames -No pathnames -Absolute pathnames -Relative pathnames -3420 -Overwrite mode: -Ask before overwrite -Overwrite without prompt -Skip existing files -Auto rename -Auto rename existing files -3430 -Eliminate duplication of root folder -Restore file security -3500 -Confirm File Replace -Destination folder already contains processed file. -Would you like to replace the existing file -with this one? -{0} bytes -A&uto Rename -3700 -Unsupported compression method for '{0}'. -Data error in '{0}'. File is broken. -CRC failed in '{0}'. File is broken. -Data error in encrypted file '{0}'. Wrong password? -CRC failed in encrypted file '{0}'. Wrong password? -3710 -Wrong password? -3721 -Unsupported compression method -Data error -CRC failed -Unavailable data -Unexpected end of data -There are some data after the end of the payload data -Is not archive -Headers Error -Wrong password -3763 -Unavailable start of archive -Unconfirmed start of archive - - - -Unsupported feature -3800 -Enter password -Enter password: -Reenter password: -&Show password -Passwords do not match -Use only English letters, numbers and special characters (!, #, $, ...) for password -Password is too long -Password -3900 -Elapsed time: -Remaining time: -Total size: -Speed: -Processed: -Compression ratio: -Errors: -Archives: -4000 -Add to archive -&Archive: -&Update mode: -Archive &format: -Compression &level: -Compression &method: -&Dictionary size: -&Word size: -Solid block size: -Number of CPU threads: -&Parameters: -Options -Create SF&X archive -Compress shared files -Encryption -Encryption method: -Encrypt file &names -Memory usage for Compressing: -Memory usage for Decompressing: -Delete files after compression -4040 -Store symbolic links -Store hard links -Store alternate data streams -Store file security -4050 -Store -Fastest -Fast -Normal -Maximum -Ultra -4060 -Add and replace files -Update and add files -Freshen existing files -Synchronize files -4070 -Browse -All Files -Non-solid -Solid -6000 -Copy -Move -Copy to: -Move to: -Copying... -Moving... -Renaming... -Select destination folder. -The operation is not supported for this folder. -Error Renaming File or Folder -Confirm File Copy -Are you sure you want to copy files to archive -6100 -Confirm File Delete -Confirm Folder Delete -Confirm Multiple File Delete -Are you sure you want to delete '{0}'? -Are you sure you want to delete the folder '{0}' and all its contents? -Are you sure you want to delete these {0} items? -Deleting... -Error Deleting File or Folder -The system cannot move a file with long path to the Recycle Bin -6300 -Create Folder -Create File -Folder name: -File Name: -New Folder -New File -Error Creating Folder -Error Creating File -6400 -Comment -&Comment: -Select -Deselect -Mask: -6600 -Properties -Folders History -Diagnostic messages -Message -7100 -Computer -Network -Documents -System -7200 -Add -Extract -Test -Copy -Move -Delete -Info -7300 -Split File -&Split to: -Split to &volumes, bytes: -Splitting... -Confirm Splitting -Are you sure you want to split file into {0} volumes? -Volume size must be smaller than size of original file -Incorrect volume size -Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes? -7400 -Combine Files -&Combine to: -Combining... -Select only first part of split file -Can not detect file as part of split file -Can not find more than one part of split file -7500 -Checksum calculating... -Checksum information -CRC checksum for data: -CRC checksum for data and names: -7600 -Benchmark -Memory usage: -Compressing -Decompressing -Rating -Total Rating -Current -Resulting -CPU Usage -Rating / Usage -Passes: -7700 -Link -Link -Link from: -Link to: -7710 -Link Type -Hard Link -File Symbolic Link -Directory Symbolic Link -Directory Junction diff -Nru p7zip-rar-16.02/GUI/Lang/eo.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/eo.txt --- p7zip-rar-16.02/GUI/Lang/eo.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/eo.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.37 : Dmitri Gabinski -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Esperanto -Esperanto -401 -B&one -Nuligu - - - -&Jes -&Ne -&Fermu -Helpo - -&Daŭrigu -440 -Jes por ĉ&iuj -Ne por ĉi&uj -&Haltu -Restartigu -&Fono -&Malfono -&Paŭzo -Paŭzita -Ĉu vi vere volas nuligi? -500 -&Dosiero -&Redakto -&Vido -&Favoritaj -&Agordoj -&Helpo -540 -&Malfermu -Malfermu &ene -Malfermu ek&stere -&Vidigu -&Redaktu -Ŝ&anĝu nomon -&Kopiu en... -M&ovu en... -&Forigu -&Erigu dosierojn... -Komb&inu dosierojn... -A&tributoj -Ko&mentu -Kalkulu kontrolsumon - -Kreu &dosierujon -Kre&u dos&ieron -E&liru -600 -M&arku ĉiun -Ma&lmarku ĉiun -&Inversigu markon -Marku... -Malmarku... -Marku laŭ tipo -Malmarku laŭ tipo -700 -&Grandaj bildetoj -&Malgrandaj bildetoj -&Listo -&Detale -730 -&Neordigite -Ununivela vido -&2 paneloj -&Ilobretoj -Malfermu radikan dosierujon -Supren je unu nivelo -Dosierujhistorio... -Ĝ&isdatigu -750 -Arĥivo-ilobreto -Norma ilobreto -Grandaj bildetoj -Montru butontekston -800 -&Aldonu dosierujon al favorataj kiel -Legosigno -900 -&Agordoj... -&Etalono -960 -&Enhavo... -&Pri 7-Zip... -1003 -Dosierindiko -Nomo -Dosiernoma sufikso -Dosierujo -Grando -Enarĥiva grando -Atributoj -Kreita -Malfermita -Ŝanĝita -Solida -Komento -Ĉifra -Disigita antaŭ -Disigita post -Vortaro -CRC -Tipo -Kontraŭ -Metodo -Gastiga operaciumo -Dosiersistemo -Uzulo -Grupo -Bloko -Komento -Pozicio -Vojprefikso - - - - - - - - - - - - - - - - - - - - - - - - -Eraro -Kapacito -Libera -Faskogrando -Marko -Loka nomo -Provizanto -2100 -Agordoj -Lingvo -Lingvo: -Redaktilo -&Redaktilo: - -2200 -Sistemo -Asociu 7-Zip-on kun dosieroj: -2301 -Metu 7-Zip'on en kuntekstan menuon de ŝelo -Kaskada kunteksta menuo -Punktoj de kunteksta menuo: -2320 - - -Malfermu -Elarĥivigu dosierojn... -Enarĥivigu... -Testu arĥivon -Elarĥivigu ĉi-tien -Elarĥivigu en {0} -Aldonu al {0} -Enarĥivigu kaj enretpoŝtigu... -Enarĥivigu en {0} kaj enretpoŝtigu... -2400 -Dosierujoj -&Kuranta dosierujo -&Sistema labora dosierujo -&Ĉi tiu -&Specifu: -&Uzi nur por demeteblaj datumportiloj -Specifu ujon por laboraj dosieroj. -2500 -Agordoj -Montru ".."-elementon -Montru realajn dosierbildetojn -Montru sisteman menuon -Marku &tutan linion -Montru &kradliniojn - -&Alternativa markreĝimo -Uzu &grandajn memorpaĝojn -2900 -Informo -7-Zip estas senpaga programo. Tamen, vi povas subteni evoluadon de 7-Zip per enregistriĝo. -3000 - -Eraroj ne trovitaj -{0} objekto(j) markita(j) -Fiaskis krei dosierujon '{0}' -Ĝisdatigoperacioj ne estas subtenataj por ĉi-tiu arĥivo. - - - - -Dosiero '{0}' ŝanĝiĝis.\nĈu vi volas ĝistadigi ĝin enraĥive? -Fiaskis ĝisdatigi dosieron\n'{0}'' -Fiaskis startigi redaktilon. - - - - -Troaj elementoj -3300 -Elarĥivigo -Densigo -Testado -Malfermo... -Analizante... -3400 -&Elarĥivigu -E&larĥivigu en: -Specifu ujon por elarĥivendaj dosieroj. -3410 -Dosierindikoj -&Absolutaj dosierindikoj -&Sen dosierindikoj -3420 -Anstataŭiga skribreĝimo -&Kun konfirmo -&Sen konfirmo -&Preterlasu estantaj dosieroj -Aŭtonomŝanĝo -Aŭtonomŝanĝo de ekzistantaj dosieroj -3500 -Konfirmo de nomŝanĝo -Dosierujo jam enhavas prilaboratan dosieron. -Anstataŭigu estantan dosieron -per ĉi-tiu? -{0} bajtoj -&Aŭtonomŝanĝo. -3700 -Ne estas subtenata densigmetodo por dosiero '{0}'. -Datumeraro en '{0}'. Difektiĝinta dosiero. -CRC-eraro en '{0}'. Difektiĝinta dosiero. - - -3800 -Pasvorto -Enigu pasvorton: - -&Montru pasvorton - - - -&Pasvorto -3900 -Pasinta tempo: -Restanta tempo: -Grando: -Rapideco: - - -Eraroj: - -4000 -Enarĥivigu -&Arĥivo: -A&nstataŭigreĝimo: -A&rĥivformato: -Densigo&nivelo -&Densigmetodo: -&Vortarogrando: -Vo&rtogrando: - - -&Parametroj: -Agordoj -Kreu SF&X-arĥivon - - - -Ĉifru dosier&nomojn -Memoruzo por densigo: -Memoruzo por maldensigo: -4050 -Sen densigo -Plej rapide -Rapide -Normala densigo -Maksimuma densigo -Ultra -4060 -Aldonu kaj anstataŭigu dosierojn -Ĝisdatigu kaj aldonu dosierojn -Refreŝigu estantajn dosierojn -Sinkronigu dosierojn -4070 -Foliumu -Ĉiuj dosieroj - - -6000 -Kopiu -Movu -Kopiu en: -Movu en: -Kopio... -Movo... -Nomŝanĝo... - -Operacio ne estas subtenata. -Eraro dum nomŝanĝo de dosiero aŭ dosierujo -Konfirmu dosierkopion -Ĉu vere kopii dosierojn enarĥiven -6100 -Konfirmo de forigo de dosiero -Konfirmo de forigo de dosierujo -Konfirmo de forigo de dosieraro -Ĉu vi vere volas forigi '{0}'? -Ĉu vi vere volas forigi dosierujon "{0}" kaj tutan ĝian enhavon? -Ĉu vi vere volas forigi ĉi tiajn {0} objektojn? -Forigo... -Eraro dum forigo de dosiero aŭ dosierujo - -6300 -Kreu dosierujon -Kreu dosieron -Dosierujnomo: -Dosiernomo: -Nova dosierujo -Nova dosiero -Eraro dum dosierujkreo -Eraro dum dosierkreo -6400 -Komento -&Komento: -Marku -Malmarku -Masko: -6600 - -Dosierujhistorio -Diagnozaj mesaĝoj -Mesaĝo -7100 -Komputilo -Reto - -Sistemo -7200 -Enarĥivigu -Elarĥivigu -Testu -Kopiu -Movu -Forigu -Informo -7300 -Erigu dosieron -&Erigu en: -&Plurvolumigu, bajtoj: -Erigo... - - - - - -7400 -Kombinu dosierojn -&Kombinu en: -Kombino... - - - -7500 -Kalkulante kontrolsumon... -Informo pri kontrolsumo -CRC-kontrolsumo por datumoj: -CRC-kontrolsumo por datumoj kaj nomoj: -7600 -Etalono -Memoruzo: -Densigo -Maldensigo -Takso -Tuta takso -Kuranta -Rezulta - - -Pasoj: diff -Nru p7zip-rar-16.02/GUI/Lang/es.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/es.txt --- p7zip-rar-16.02/GUI/Lang/es.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/es.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Pablo Rodriguez -; : Jbc25 -; : 2007-09-05 : Guillermo Gabrielli -; 9.07 : 2010-06-10 : Purgossu -; 2010-10-23 : Sergi Medina (corrected) -; -; -; -; -; -; -0 -7-Zip -Spanish -Español -401 -Aceptar -Cancelar - - - -&Sí -&No -&Cerrar -Ayuda - -&Continuar -440 -Sí a &todo -No a t&odo -Parar -Volver a empezar -Se&gundo plano -P&rimer plano -&Pausa -Pausado -¿Estás seguro de que deseas cancelar? -500 -&Archivo -&Editar -&Ver -&Favoritos -&Herramientas -Ay&uda -540 -&Abrir -Abrir &dentro -Abrir &fuera -&Ver -&Editar -Re&nombrar -&Copiar a... -&Mover a... -&Borrar -Di&vidir archivo... -C&ombinar archivos... -&Propiedades -Comen&tario -Suma de verificación -Diff -Crear carpeta -Crear archivo -&Salir -600 -Seleccionar &todo -Deseleccionar todo -&Invertir selección -Seleccionar... -Deseleccionar... -Seleccionar por tipo -Deseleccionar por tipo -700 -Iconos g&randes -&Iconos pequeños -&Lista -&Detalles -730 -Desordenado -Vista plana (flat view) -&2 paneles -&Barras de herramientas -Abrir directorio raíz -Subir un directorio -Historia de carpetas... -&Actualizar -750 -Barra de herramientas Archivo -Barras de herramientas estándar -Botones grandes -Mostrar texto en los botones -800 -&Añadir carpeta a favoritos como -Agregar a favoritos -900 -&Opciones... -&Pruebas (benchmark) -960 -&Contenido... -&Acerca de 7-Zip... -1003 -Ruta -Nombre -Tipo de archivo -Directorio -Tamaño -Tamaño comprimido -Atributos -Creado -Acceso -Modificado -Compacto -Comentado -Encriptado -expandido antes -expandido después -Diccionario -CRC -Tipo -Anti -Método -SO de origen -Sistema de archivos -Usuario -Grupo -Bloque -Comentario -Posición -Ruta -Directorios -Ficheros -Versión -Volumen -Multivolumen -Desplazamiento -Vínculos -Bloques -Volúmenes - -64-bit -Big-endian -CPU -Tamaño físico -Tamaño de las cabeceras -Verificación de suma -Características -Dirección virtual -ID -Nombre corto -Aplicación de creación -Tamaño de sector -Modo -Enlace -Error -Espacio total -Espacio libre -Tamaño de clúster -Etiqueta -Nombre local -Proveedor -2100 -Opciones -Lengua -Lengua: -Editor -&Editor: -&Diff: -2200 -Sistema -Asociar 7-Zip con: -2301 -Integrar 7-Zip en el menú contextual de Windows -Menú contextual en cascada -Elementos en el menú contextual: -2320 - - -Abrir comprimido -Extraer ficheros... -Añadir al archivo... -Comprobar archivo -Extraer aquí -Extraer en {0} -Añadir a {0} -Comprimir y enviar por correo... -Comprimir a {0} y enviar por correo -2400 -Directorios -Directorio de &trabajo -Directorio temporal del &sistema -Directorio &actual -&Especificar directorio: -Usar solo para dispositivos extraíbles -Especificar un directorio para archivos temporales. -2500 -Propiedades -Mostrar el elemento ".." -Mostrar iconos propios -Mostrar menú del sistema -&Seleccionar fila(s) entera(s) -Mostrar &cuadrícula -Clicar una vez para abrir elemento -Modo de selección &alternativo -Usar páginas &grandes de memoria -2900 -Acerca de 7-Zip -7-Zip es un programa excelente; además, es libre y gratuito. Tú puedes apoyar el desarrollo de 7-Zip registrándote para contribuir a mejorar el programa. -3000 -El sistema no ha podido asignar la cantidad necesaria de memoria -No hay errores -{0} elemento(s) seleccionado(s) -No se puede crear el directorio '{0}' -Este tipo de archivo no permite actualización. -No se puede abrir '{0}' como un archivo comprimido -No se puede abrir el archivo encriptado '{0}'. Verifique la contraseña. -Tipo de archivo no soportado -El fichero {0} ya existe -El fichero '{0}' ha sido modificado.\n¿Quieres actualizarlo en el archivo? -No puede actualizarse el fichero\n'{0}' -No puede ejecutarse el editor. -El fichero parece un virus (el nombre del fichero contiene espacios largos). -No puede realizarse la operación desde una carpeta que tenga una ruta larga. -Debes seleccionar un fichero -Debes seleccionar uno o más ficheros -Demasiados elementos -3300 -extrayendo -comprimiendo -probando -abriendo... -Buscando... -3400 -Extraer -E&xtraer a: -Selecciona destino para los archivos extraídos. -3410 -Modo de directorio -Directorio completo -Sin directorio -3420 -Sobreescribir -Con confirmación -Sin confirmación -Conservar archivos existentes -Renombrar automáticamente -Autorrenombrar archivos existentes -3500 -Confirmar sustitución de archivos -El directorio ya contiene un archivo con el mismo nombre. -¿Deseas sustituir el archivo existente -por este otro? -{0} bytes -Renombrar a&utomáticamente -3700 -Método de compresión no válido para '{0}'. -Error de datos en '{0}'. El archivo está corrupto. -CRC ha fallado en '{0}'. El archivo está corrupto. -Error de datos en el archivo encriptado '{0}'. Verifica la contraseña. -Fallo de CRC en el archivo encriptado '{0}'. Verifica la contraseña. -3800 -Introduce la contraseña -E&scribe la contraseña: -Escribe nue&vamente la contraseña: -&Mostrar la contraseña -Las contraseñas son diferentes. Por favor, vuelve a escribirlas. -Usa en la contraseña solamente letras del alfabeto inglés, números y caracteres especiales (!, #, $, ...) -La contraseña es demasiado larga. -Contraseña -3900 -Tiempo transcurrido: -Tiempo pendiente: -Tamaño: -Velocidad: -Procesado: -Razón de compresión: -Errores: -Archivos: -4000 -Añadir al archivo -&Archivo: -M&odo de actualización: -&Formato de archivo: -Nive&l de compresión: -&Tipo de compresión: -Tamaño de &diccionario: -Tama&ño de la palabra: -Tamaño de bloque compacto: -Número de hilos de la CPU: -&Parámetros: -Opciones -Crear archivo SF&X (autoextraíble) -Comprimir archivos abiertos para escritura -Encriptación -Método de &encriptación: -Encriptar &nombres de fichero -Memoria usada para comprimir: -Memoria usada para descomprimir: -4050 -Sin compresión -La más rápida -Rápida -Normal -Máxima -Ultra -4060 -Añadir y sustituir archivos -Actualizar y añadir archivos -Solo actualizar archivos -Sincronizar archivos -4070 -Explorar -Todos los archivos -No compacto -Sin límite -6000 -Copiar -Mover -Copiar a: -Mover a: -copiado... -movido... -Renombrando... -Selecciona la carpeta de destino -Operación no permitida. -Error renombrando fichero o carpeta -Confirmar copia de ficheros -¿Estás seguro de que deseas copiar los ficheros al archivo -6100 -Confirmar borrado de archivo -Confirmar borrado de carpeta -Confirmar borrado de numerosos ficheros -¿Estás seguro de querer borrar '{0}'? -¿Estás seguro de querer borrar la carpeta '{0}' y todo su contenido? -¿Estás seguro de querer borrar estos {0} elementos? -Borrando... -Error borrando fichero o carpeta -El sistema no puede mover un fichero con ruta larga a la Papelera de Reciclaje -6300 -Crear carpeta -Crear archivo -Nombre de carpeta: -Nombre de archivo: -Carpeta nueva -Archivo nuevo -Error creando carpeta -Error creando archivo -6400 -Comentario -&Comentario: -Seleccionar -Deseleccionar -Máscara: -6600 -Propiedades -Historial de carpetas -Mensajes de diagnóstico -Mensaje -7100 -Mi PC -Entorno de red -Documentos -Sistema -7200 -Agregar -Extraer -Probar -Copiar -Mover -Borrar -Información -7300 -Dividir archivo -Di&vidir a: -Dividir en fra&gmentos (bytes): -Dividiendo... -Confirmar división -¿Estás seguro de que deseas dividir el archivo en {0} partes? -El tamaño de los fragmentos debe ser menor que el del archivo original -Tamaño de fragmento incorrecto -Tamaño de fragmento especificado: {0} bytes.\n¿Estás seguro de que deseas dividir el archivo en fragmentos de ese tamaño? -7400 -Combinar archivos -&Combinar a: -Combinando... -Selecciona solamente el primer archivo -No se ha podido detectar el fichero como parte de un fichero por volúmenes -No se ha podido encontrar más que un fragmento del fichero por volúmenes -7500 -Calculando suma de verificación... -Suma de verificación (CRC) -CRC de los datos: -CRC de los datos y nombres: -7600 -Pruebas (benchmark) -Uso de memoria: -Compresión -Descompresión -Tasa -Tasa total -Actual -Resultante -Uso de CPU -Resultante/uso -Pasos: diff -Nru p7zip-rar-16.02/GUI/Lang/et.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/et.txt --- p7zip-rar-16.02/GUI/Lang/et.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/et.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.09 : Kaupo Suviste -; 9.07 : Mihkel Tõnnov -; -; -; -; -; -; -; -; -; -0 -7-Zip -Estonian -eesti keel -401 -OK -Loobu - - - -&Jah -&Ei -&Sulge -Abi - -&Jätka -440 -Kõigile j&ah -Kõigile e&i -Seiska -Restardi -&Taustal -&Esiplaanile -&Paus -Pausiks peatatud -Kas soovite kindlasti loobuda? -500 -&Fail -&Redigeeri -&Vaade -&Lemmikud -&Tööriistad -&Abi -540 -&Ava -Ava s&ees -Ava väljasp&ool -Vaat&ur -&Redigeeri -&Nimeta ümber -&Kopeeri asukohta... -&Teisalda asukohta... -Ku&stuta -Tükel&da fail... -Ü&henda failid... -Atri&buudid -Ko&mmentaar... -Arvuta kontrollsumma -Võrdle -Loo kaust -Loo fail -&Välju -600 -V&ali kõik -Tühista kõik valikud -&Pööra valik -Vali... -Tühista valik... -Vali tüübi järgi -Tühista tüübi järgi valik -700 -&Suured ikoonid -Väik&esed ikoonid -&Loend -Üksikasja&d -730 -Sortimata -Lame vaade -&Kaks paani -&Tööriistaribad -Ava juurkaust -Taseme võrra üles -Kaustaajalugu... -&Värskenda -750 -Arhiiviriistariba -Standardnupuriba -Suured nupud -Kuva nupusildid -800 -&Lisa kaust lemmikute hulka järjehoidjana -Järjehoidja -900 -&Häälestus... -&Jõudlustest -960 -&Sisukord... -&Teave 7-Zipi kohta... -1003 -Tee -Nimi -Laiend -Kaust -Maht -Maht tihendatult -Atribuudid -Loodud -Avatud -Muudetud -Ühtne -Kommenteeritud -Krüptitud -Tükeldatud enne -Tükeldatud pärast -Sõnastik -CRC -Tüüp -Anti -Meetod -Opsüsteem -Failisüsteem -Kasutaja -Rühm -Plokk -Kommentaar -Koht -Tee prefiks -Kaustu -Faile -Versioon -Köide -Mitmeköiteline -Nihe -Linke -Plokke -Köiteid - -64-bitine -Big-Endian -Protsessor -Füüsiline maht -Päiste maht -Kontrollsumma -Karakteristikud -Virtuaalaadress -ID -Lühinimi -Loomisrakendus -Sektori maht -Režiim -Link -Tõrge -Kogumaht -Vaba ruum -Klastri suurus -Silt -Kohalik nimi -Teenusepakkuja -2100 -Häälestus -Keel -Keel: -Redaktor -&Redaktor: -&Võrdlusprogramm: -2200 -Süsteem -Seosta 7-Zip laienditega: -2301 -Integreeri 7-Zip kesta hüpikmenüüsse -Kaskaad-hüpikmenüü -Hüpikmenüü käsud: -2320 - - -Ava arhiiv -Eralda failid... -Lisa arhiivi... -Testi arhiivi -Eralda siia -Eralda kausta {0} -Lisa arhiivi {0} -Tihenda ja meili... -Tihenda arhiiviks {0} ja meili -2400 -Kaustad -&Töökaust -&Süsteemi ajutiste failide kaust -&Praegune kaust -&Kasutaja määratud: -Kasuta ainult irddraivide puhul -Määrake ajutiste arhiivifailide asukoht. -2500 -Sätted -Kuva element ".." -Kuva tegelikud failiikoonid -Kuva süsteemimenüü -&Vali terve rida -Kuva &ruudujooned -Ava üksus ühe klõpsuga -&Alternatiivne valikurežiim -Kasuta &suuri mälulehekülgi -2900 -Teave 7-Zipi kohta -7-Zip on vaba tarkvara. Kuid kui soovite toetada 7-Zipi arendamist, siis saate programmi registreerida.\n\n7-Zipi Eesti koduleht:\nhttp://www.hot.ee/somberg/7zip.html -3000 -Süsteem ei saa eraldada nõutavat mälumahtu. -Vigu ei leitud. -{0} üksus(t) valitud -Ei saa luua kausta {0} -Selle arhiivi värskendamistoiminguid ei toetata. -Ei saa avada faili {0} arhiivina. -Ei saa avada krüptitud arhiivi {0}. Kas vale parool? -Toetamata arhiivitüüp. -Fail {0} on juba olemas. -Faili {0} on muudetud.\nKas soovite selle arhiivis värskendada? -Ei saa värskendada faili\n{0} -Ei saa käivitada redaktorit. -See fail sarnaneb viirusega (faili nimi sisaldab pikka tühikute jada). -Toimingut ei saa käivitada kaustast, millel on pikk tee. -Te peate valima ühe faili. -Te peate valima ühe või mitu faili. -Liiga palju üksusi. -3300 -välja eraldatud -tihendatud -Testimine -Avamine... -Läbivaatamine... -3400 -Väljaeraldamine -&Eralda välja kausta: -Määrake väljaeraldatud failide asukoht. -3410 -Teed -&Täielikud teenimed -Teenime&deta -3420 -Ülekirjutus -Küsi e&nne ülekirjutamist -Ki&rjuta küsimata üle -&Jäta olemasolevad failid vahele -Nimeta a&utomaatselt ümber -Nimeta &olemasolevad f. autom. ümber -3500 -Failiasenduse kinnitamine -Sihtkaust juba sisaldab töödeldavat faili. -Kas soovite asendada olemasoleva faili -selle failiga? -{0} baiti -Nimeta a&utomaatselt ümber -3700 -Toetuseta tihendusmeetod failile {0}. -Andmeviga failis {0}. Fail on rikutud. -Tsükkelkoodkontroll (CRC) failis {0} nurjus. Fail on rikutud. -Andmeviga krüptitud failis {0}. Kas vale parool? -Tsükkelkoodkontroll (CRC) krüptitud failis {0} nurjus. Kas vale parool? -3800 -Parooli sisestamine -Sisestage parool: -Parooli kordus: -&Kuva parool -Paroolid ei kattu. -Kasutage paroolis ainult inglise keele tähti, numbreid ja erimärke (!, #, $, ...). -Parool on liiga pikk. -&Parool -3900 -Kulunud aeg: -Järelejäänud aeg: -Kogumaht: -Kiirus: -Töödeldud: -Tihendussuhe: -Vigu: -Arhiive: -4000 -Arhiivi lisamine -&Arhiiv: -Värskend&usrežiim: -Arhiivi&vorming: -&Tihendusaste: -Tihendus&meetod: -Sõnaraamatu ma&ht: -&Sõna maht: -Ühtse ploki maht: -Protsessorilõimede arv: -Pa&rameetrid: -Suvandid -Loo is&eavanev arhiiv -Tihenda kirjutuseks avatud failid -Krüptimine -Krüptimismeetod: -Krüpti faili&nimed -Mälu hõivatus tihendamisel: -Mälu hõivatus hõrendamisel: -4050 -Tihenduseta -Kiireim tihendus -Kiirtihendus -Normaaltihendus -Maksimaaltihendus -Ultratihendus -4060 -Lisa ja asenda failid -Värskenda ja lisa failid -Värskenda olemasolevad failid -Sünkrooni failid -4070 -Sirvi -Kõik failid -Mitteühtne -Ühtne -6000 -Kopeerimine -Teisaldamine -Kopeeri asukohta: -Teisalda asukohta: -Kopeerimine... -Teisaldamine... -Ümbernimetamine... -Valige sihtkaust. -See toiming pole selles kaustas toetatud. -Tõrge faili või kausta ümbernimetamisel -Failikopeerimise kinnitamine -Kas soovite kindlasti kopeerida arhiivi järgmised failid: -6100 -Failikustutuse kinnitamine -Kaustakustutuse kinnitamine -Mitme faili kustutamise kinnitamine -Kas soovite kindlasti kustutada faili {0}? -Kas soovite kindlasti kustutada kausta {0} ja kogu selle sisu? -Kas soovite kindlasti kustutada need {0} üksust? -Kustutamine... -Tõrge faili või kausta kustutamisel -Süsteem ei saa teisaldada prügikasti pika teega faili. -6300 -Kausta loomine -Faili loomine -Kausta nimi: -Faili nimi: -Uus kaust -Uus fail -Tõrge kausta loomisel -Tõrge faili loomisel -6400 -- kommentaar -&Kommentaar: -Valimine -Valiku tühistamine -Mask: -6600 -Atribuudid -Kaustaajalugu -Diagnostikateated -Teade -7100 -Arvuti -Võrk -Dokumendid -Süsteem -7200 -Lisa -Eralda välja -Testi -Kopeeri -Teisalda -Kustuta -Teave -7300 -Faili tükeldamine: -&Tükelda asukohta: -&Tükelda köideteks (baitides): -Tükeldamine... -Tükeldamise kinnitamine -Kas soovite kindlasti tükeldada faili {0} köiteks? -Köite maht peab olema algfaili mahust väiksem. -Sobimatu köitemaht. -Määratud köitemaht: {0} baiti.\nKas soovite kindlasti tükeldada arhiivi niisugusteks köideteks? -7400 -Failide ühendamine: -Ü&henda asukohta: -Ühendamine... -Valige ainult tükeldatud faili esimene osa. -Ei õnnestu tuvastada, et see fail oleks tükeldatud faili osa. -Ei leia rohkem kui ühte tükeldatud faili osa. -7500 -Kontrollsumma arvutamine... -Kontrollsumma -Andmete CRC-kontrollsumma: -Andmete ja nimede CRC-kontrollsumma: -7600 -Jõudlustest -Mälu hõivatus: -Tihendamine -Hõrendamine -Hinnang -Üldine jõudlushinnang -Praegune: -Lõpptulemus: -CPU hõivatus -Hinnang/hõivatus -Töötiire: diff -Nru p7zip-rar-16.02/GUI/Lang/eu.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/eu.txt --- p7zip-rar-16.02/GUI/Lang/eu.txt 2016-02-03 05:05:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/eu.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.12 : 2015-12-04 : Xabier Aramendi -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Basque -Euskara -401 -&Ongi -E&zeztatu - - - -&Bai -&Ez -It&xi -&Laguntza - -&Jarraitu -440 -Bai &Guztiari -Ez G&uztiari -Gelditu -Berrabiarazi -Ba&rrenean -&Gainean -&Pausatu -Pausatuta -Zihur zaude ezeztatzea nahi duzula? -500 -&Agiria -&Editatu -&Ikusi -&Gogokoenak -&Tresnak -&Laguntza -540 -&Ireki -Ireki &Barnean -Ireki &Kanpoan -Ik&usi -&Editatu -Berrize&ndatu -Kopiatu &Hona... -&Mugitu Hona... -E&zabatu -Banan&du agiria... -Nahas&tu agiriak... -Ezau&garriak -&Aipamena... -Ka&lkulatu egiaztapen-batura -Ezber -Sortu Agiritegia -S&ortu Agiria -I&rten -Lotura -&Aldikatu Jarioak -600 -Hautatu &Guztiak -Deshatutau G&uztiak -&Alderantzizkatu Hautapena -&Hautatu... -&Deshautatu... -Hautatu &Motaz -Deshautatu M&otaz -700 -Ikur &Handiak -Ikur Txi&kiak -&Zerrenda -&Xehetasunak -730 -Ant&olatugabe -Ik&uspegi Laua -&2 Panel -&Tresnabarrak -Ireki &Erro Agiritegia -Maila Bat &Gora -Agiritegi &Historia... -&Berritu -Be&rez Berritu -750 -Artxibo Tresnabarra -Tresnabarra Estandarra -Botoi Handiak -Erakutsi Botoien Idazkia -800 -&Gehitu agiritegia Gogokoenetara honela -Lastermarka -900 -A&ukerak... -&Benchmark -960 -&Edukiak... -&7-Zip Buruz... -1003 -Helburua -Izena -Luzapena -Agiritegia -Neurria -Pakete Neurria -Ezaugarriak -Sortua -Sartua -Aldatua -Solidoa -Aipatua -Enkriptatua -Banandu Aurretik -Banandu Ondoren -Hiztegia - -Mota -Anti -Metodoa -Hostalari SE -Agiri Sistema -Erabiltzailea -Taldea -Blokea -Aipamena -Kokapena -Helburu Aurrizkia -Agiritegiak -Agiriak -Bertsioa -Bolumena -Bolumen-anitz -Oreka -Loturak -Blokeak -Bolumenak - -64-bit -Big-endian -CPU -Neurri Fisikoa -Idazburu Neurria -Egiaztapen-batura -Ezaugarriak -Helbide Birtuala -ID-a -Izen Laburra -Aplikazio Sortzailea -Sektore Neurria -Modua -Lotura Sinbolikoa -Akatsa -Neurria Guztira -Toki Askea -Kluster Neurria -Etiketa -Tokiko Izena -Hornitzailea -NT Segurtasuna -Aldikatu Jarioa -Aux -Ezabatuta -Zuhaitza da - - -Akats Mota -Akatsak -Akatsak -Ohartarazpenak -Ohartarazpena -Jarioak -Aldikatu Jarioak -Aldikatu Jario Neurriak -Neurri Birtuala -Despaketatu Neurria -Neurri Fisikoa Guztira -Bolumen Aurkibidea -AzpiMota -Aipamen Labura -Kode Orrialdea - - - -Isats Neurria -Barneratutako Stub Neurria -Lotura -Lotura Gogorra -iNode - -Irakurtzeko-bakarrik -2100 -Aukerak -Hizkuntza -Hizkuntza: -Editatzailea -&Editatzailea: -E&zberdintasunak: -2200 -Sistema -Elkartu 7-Zip hauekin: -Erabiltzaile guztiak -2301 -&Bateratu 7-Zip shell hitzinguru menura -&Urjauzi hitzinguru menua -Hitzinguru menuko gaiak: -&Ikurrak hitzinguru menuan -2320 - - -Ireki artxiboa -Atera agiriak... -Gehitu &artxibora... -Aztertu artxiboa -Atera Hemen -Atera hona: {0} -Gehitu hona: {0} -Konprimitu eta &bidali post@z... -Konprimitu hona {0} eta bidali post@z -2400 -Agiritegiak -&Lan agiritegia -&Sistemaren aldibaterako agiritegia -&Oraingoa -A&dierazia: -&Erabili gidagailu kengarrientzat bakarrik -Adierazi aldibaterako artxibo agirientzako kokalekua -2500 -Ezarpenak -&Erakutsi ".." gai -E&rakutsi egizko agiriaren ikurrak -Erakutsi siste&maren menua -&Lerro osoko hautapena -Erakutsi &saretxo lerroak -&Klik-bakarra gai bat irekitzeko -A&ukerazko hautapen modua -Erabili &oroimen handiko orrialdeak -2900 -7-Zip buruz -7-Zip software askea da -3000 -Sistemak ezin du beharrezko oroimen kopurua esleitu -Ez dago akatsik -{0} objetu hautaturik -Ezin da '{0}' agiritegia sortu -Eguneratze eragiketak ez daude sostengaturik artxibo honentzat. -Ezinezkoa '{0}' agiria artxibo bezala irekitzea -Ezinezkoa '{0}' artxibo enkriptatua ireki. Sarhitz okerra? -Artxibo mota ez dago sostengatua -{0} agiria badago jadanik -'{0}' agiria aldatu egin da.\nArtxioboan eguneratzea nahi duzu? -Ezinezkoa agiria eguneratzea\n'{0}' -Ezin da editatzailea abiarazi. -Agiriak birus bat ematen du (agiri izenak tarte luzeak ditu izenean). -Eragiketa ezin da helburu luze bat duen agiritegi batetik deitu -Agiri bat hautatu behar duzu -Agiri bat edo gehiago hautatu behar dituzu -Gai gehiegi -Ezin da agiria {0} artxibo bezala ireki -Agiria {0} artxibo bezala dago irekita -Artxiboa orekaz irekita dago -3300 -Ateratzen -Konprimitzen -Aztertzen -Atzeratzen... -Mihatzen... -Kentzen -3320 -Gehitzen -Eguneratzen -Aztertzen -Erreplikatzen -Berpaketatzen -Jauzten -Ezabatzen -Idazburua sortzen -3400 -&Atera -Atera &hona: -A&dierazi ateratako agirientzako kokaleku bat. -3410 -Helburu mo&dua: -Helburu-izen osoak -Helburu-izenik ez -Helburu-izen absolutoak -Helburu-izen erlatiboak -3420 -Gainidazketa modua: -Galdetu gainidatzi aurretik -Gainidazi galdetu gabe -Jauzi dauden agiriak -Berez berrizendatu -Berez berrizendatu dauden agiriak -3430 -Ezabatu erro agiritegi bikoizketa -Leheneratu agiri segurtasuna -3500 -Baieztatu Agiri Ordeztea -Helmuga agiritegiak jadanik badu prozesatutako agiria. -Dagoen agiria ordeztea nahi duzu -beste honekin? -{0} byte -&Berez Berrizendatu -3700 -Konpresio metodo sostengatu gabea '{0}'-rako. -Datu akatsa '{0}'. Agiria hautsita dago. -CRC hutsegitea '{0}'. Agiria hautsita dago. -Datu akatsa '{0}' enkriptaturiko agirian. Sarhitz okerra? -CRC hutsegitea '{0}' enkriptaturiko agirian. Sarhitz okerra? -3710 -Sarhitz okerra? -3721 -Konpresio metodoa ez dago sostengatua -Datu akatsa -CRC hutsegitea -Datu eskuraezinak -Ustekabeko datu amaiera -Zenbait akats daude gertaketa amaieraren ondoren -Ez da artxiboa -Idazburu Akatsa -Sarhitz okerra -3763 -Artxibo hasiera eskuraezina -Artxibo hasiera baieztatugabe - - - -Ezaugarri sostengu gabea -3800 -Sartu sarhitza -Sartu sarhitza: -Bersartu sarhitza: -&Erakutsi sarhitza -Sarhitzak ez datoz bat -Erabili bakarrik Ingelerazko hizkiak, zenbakiak eta hizki bereziak (!, #, $, ...) sarhitzarentzat -Sarhitza luzeegia da -Sarhitza -3900 -Igarotako denbora: -Gelditzen den denbora: -Neurria guztira: -Abiadura: -Prozesatuta: -Konpresio maila: -Akatsak: -Artxiboak: -4000 -Gehitu artxibora -&Artxiboa: -Egu&neraketa modua: -Artxibo he&uskarria: -Konpre&sio maila: -Konpresio &metodoa: -&Hiztegi neurria: -Hi&tz neurria: -&Bloke solidoaren neurria: -&CPU hari zenbatekoa: -&Parametroak: -Aukerak -Sortu SF&X artxiboa -&Konprimitu elkarbanaturiko agiriak -Enkriptaketa -Enkriptaketa metodoa: -Enkriptatu agiri &izenak -Oroimen erabilera Konprimitzeko: -Oroimen erabilera Deskonprimitzeko: -Ezabatu agi&riak konprimitu ondoren -4040 -Biltegiratu lotura sinbolikoak -Biltegiratu lotura gogorrak -Biltegiratu aldikatu datu jarioak -Biltegiratu agiri segurtasuna -4050 -Biltegia -Azkarrena -Azkarra -Arrunta -Gehiena -Ultra -4060 -Gehitu eta ordeztu agiriak -Eguneratu eta gehitu agiriak -Berritu dauden agiriak -Aldiberetu agiriak -4070 -Bilatu -Agiri Denak -Ez-solidoa -Solidoa -6000 -Kopiatu -Mugitu -Kopiatu hona: -Mugitu hona: -Kopiatzen... -Mugitzen... -Berrizendatzen... -Hautatu helmuga agiritegia. -Eragiketa hau ez dago sostengatua agiritegi honentzat. -Akatsa Agiria edo Agiritegia Berrizendatzerakoan -Baieztatu Agiri Kopiatzea -Zihur zaude agiriak artxibora kopiatzea nahi dituzula -6100 -Baieztatu Agiri Ezabapena -Baieztatu Agiritegi Ezabapena -Baieztatu Agiri Anitz Ezabapena -Zihur zaude '{0}' ezabatzea nahi duzula? -Zihur zaude '{0}' agiritegia eta bere eduki guztiak ezabatzea nahi dituzula? -Zihur zaude {0} gai hauek ezabatzea nahi dituzula? -Ezabatzen... -Akatsa Agiria edo Agiritegia Ezabatzerakoan -Sistemak ezin du helburu luzeko agiria Birziklapen Ontzira mugitu -6300 -Sortu Agiritegia -Sortu Agiria -Agiritegi izena: -Agiri Izena: -Agiritegi Berria -Agiri Berria -Akatsa Agiritegia Sortzerakoan -Akatsa Agiria Sortzerakoan -6400 -Aipamena -&Aipamena: -Hautatu -Deshautatu -Mozorroa: -6600 -Ezaugarriak -Agiritegi Historia -Azterketa mezuak -Mezuak -7100 -Ordenagailua -Sarea -Agiriak -Sistema -7200 -Gehitu -Atera -Aztertu -Kopiatu -Mugitu -Ezabatu -Argibideak -7300 -Banandu Agiria -Banandu &hona: -Banandu &bolumenetan, byte: -Banantzen... -Baieztatu Banantzea -Zihur zaude agiria {0} bolumenetan banantzea nahi duzula? -Bolumen neurria jatorrizko agiriaren neurria baino txikiagoa izan behar da -Bolumen neurri okerra -Adierazitako bolumen neurria: {0} byte.\nZihur zaude artxiboa bolumenetan banantzea nahi duzula? -7400 -Nahastu Agiriak -&Nahastu hona: -Nahasten... -Hautatu bakarrik banantzeko agiriaren lehen atala -Ezin da agiria atzeman banandutako agiriaren atal bezala -Ezin da aurkitu banandutako agiriaren atal bat baino gehiago -7500 -Egiaztapen-batura kalkulatzen... -Egiaztapen-batura argibideak -CRC Egiaztapen-batura datuentzat: -CRC Egiaztapen-batura datu eta izenentzat: -7600 -Benchmark -Oroimen erabilpena: -Konprimitzen -Deskonprimitzen -Mailaketa -Mailaketa Guztira -Oraingoa -Emaitza -CPU Erabilpena -Mailaketa / Erabilpena -Pasaldiak: -7700 -Lotura -Lotura -Lotura hemendik: -Lotura hona: -7710 -Lotura Mota -Lotura Gogorra -Agiri Lotura Sinbolikoa -Zuzenbide Lotura Sinbolikoa -Zuzenbide Elkargunea diff -Nru p7zip-rar-16.02/GUI/Lang/ext.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ext.txt --- p7zip-rar-16.02/GUI/Lang/ext.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ext.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Miguel Angel -; 9.07 : Purgossu -; -; -; -; -; -; -; -; -; -0 -7-Zip -Extremaduran -Estremeñu -401 -Acetal -Cancelal - - - -&Sí -&Nu -&Fechal -Ayua - -A&continal -440 -Sí &a tó -Nu a &tó -Paral -Reinicial -Se&gundu pranu -&Primel pranu -&Paral -Parau -De siguru que quieri cancelal la operación? -500 -&Archivu -&Eital -&Vel -A&tihus -&Herramientas -A&yua -540 -&Abril -Abril &dentru -Abril &huera -&Vel -&Eital -Renom&bral -&Copial a... -&Movel pa... -&Eliminal -De&sapartal ficheru... -Com&binal ficherus... -P&ropieais -Come&ntariu -Calculal suma e verificación -Diff -Creal diretóriu -Creal ficheru -&Salil -600 -Selecional &tó -Deselecional tó -&Invertil seleción -Selecional... -Deselecional... -Selecional pol tipu -Deselecional pol tipu -700 -Iconus g&randis -Iconus caquerus -&Listau -&Detallis -730 -Nu soportau -Vista prana -&2 panelis -Barra e herramien&tas -Abril diretóriu raí -Subil un nivel -Estorial de diretórius... -&Atualizal -750 -Barra e herramientas 'archivu' -Barra e herramientas estándal -Botonis grandis -Muestral testu enus botonis -800 -&Añíl diretóriu a Atihus comu -Atihu -900 -&Ocionis... -&Prebas ('benchmark') -960 -&Contenius... -&Al tentu 7-Zip... -1003 -Ruta -Nombri -Estensión -Diretóriu -Tamañu -Tamañu comprimiu -Atributus -Creau'l -Úrtimu acesu -Escambiau'l -Sóliu -Comentau -Encrihtau -Desapartau enantis -Desapartau endispués -Izionáriu -CRC -Tipu -Anti -Métou -S.O. orihin -Sistema d'archivus -Usuariu -Grupu -Broqui -Comentariu -Posición -Prefihu la ruta -Diretórius -Ficherus -Velsión -Volumin -Murtivolumin -Desprazamientu -Enlacis -Broquis -Volúmenis - -64-bit -Big-endian -UCP -Tamañu físicu -Tamañu las cabiceras -Suma e cumprebación -Caraterísticas -Direción virtual -ID -Nombri cortu -Apricación criaora -Tamañu el setol -Mou -Enlaci -Yerru -Tamañu total -Espaciu dispunibri -Tamañu el 'cluster' -Etiqueta -Nombri local -Proveol -2100 -Ocionis -Palra -Palra: -Eitol -&Eitol: -&Diff: -2200 -Sistema -Asocial 7-Zip a hormatus: -2301 -Integral 7-Zip nel menú contestual -Menú contestual en cascá -Elementus del menú contestual: -2320 - - -Abril archivu -Estrayel ficherus... -Añíl al archivu... -Comprebal archivu -Estrayel aquina -Estrayel en {0} -Añiil a {0} -Comprimil i envial pol correu-e... -Comprimil en {0} i envial pol correu -2400 -Diretórius -Diretóriu e labu&tu -Diretóriu temporal del &sistema -Diretóriu &ahtual -&Especifical: -Usal sólu pa dispositivus estrayíbris -Especifical ruta pa ficherus d'archivus temporalis. -2500 -Configuración -Muestral l'elementu \.." -Muestral icunus propius del ficheru -Muestral menú el sistema -&Selecional fila(s) enteriza(s) -Muestral línias e la &cuairícula -'Click' únicu p'abril un elementu -Móu e seleción &alternativu -Usa&l páhinas de memoria grandis -2900 -About 7-Zip -7-Zip es una apricación libri i a gastus pagus. Peru puei apoyal el desarrollu e 7-Zip meyanti'l rehistru el pograma. -3000 -El sistema nu á síu escapás d'asinal la cantiá prehisa de memoria -Sin yerrus -{0} elementu(s) selecionaus -Nu s'á puiu crial el diretóriu '{0}' -Nu se puei atualizal esti tipu d'archivu. -Nu s'á puiu abril '{0}' comu archivu -Nu s'a puiu abril l'archivu encritau '{0}'. Conseña yerronia? -Tipu archivu nu suportau -File {0} is already exist -El ficheru '{0}' á síu moificau.\nAtualizalu nel archivu? -Nu s'á puíu atualizal l'archivu\n'{0}' -Nu s'á puíu ehecutal el eitol. -El ficheru pahi un virus (el nombri'l ficheru contieni espacius largus nel nombri). -Nu puei realizasi la operación dendi un diretóriu que tenga una ruta larga. -You must select one file -You must select one or more files -Ai elementus en demasía -3300 -Estrayendu -Comprimiendu -Comprebandu -Abriendu... -Escaneandu... -3400 -Estrayel -E&strayel a: -Especifical destinu palus ficherus estrayíus. -3410 -Mou e ruta -Ruta compreta -Sin ruta -3420 -Mou e sobrescrebil -Preguntal enantis -Sobrescrebil sin preguntal -Conserval ficherus esistentis -Renombral de horma automática -Autu-renombral ficherus esistentis -3500 -Confirmal remprazu de ficherus -El diretóriu ya contieni un ficheru el mesmu nombri. -Escambial el ficheru esistenti -pol esti otru? -{0} bytes -Escambial nombri a&utomáticamenti -3700 -Métou e compresión nu soportau pa '{0}'. -Yerru datus en '{0}'. El ficheru está changarrau. -Yerru e CRC '{0}'. El ficheru está changarrau. -Yerru e datus nel ficheru encritau '{0}'. Conseña yerrónia? -Yerru e CRC nel ficheru encritau '{0}'. Conseña yerrónia? -3800 -Introuzil conseña -Introuzil conseña: -Repitil conseña: -Mue&stral conseña -Las cunseñas nu coinciín -Usi sólu letras ingresas, númirus i caráteris especialis (!, #, $, ...) pala conseña -La conseña tieni largura'n demasía -Conseña -3900 -Tiempu trascurríu: -Tiempu restanti: -Tamañu total: -Velociá: -Procesau: -Tasa e compresión: -Yerrus: -Archivus: -4000 -Añiil a archivu -&Archivu: -&Mou d'atualización: -&Hormatu d'archivu: -Nive&l de compresión: -Mé&tou e compresión: -Tamañu el i&zionariu: -Tama&ñu e parabra: -Tamañu el bloqui sóliu: -Númiru hilus e la UCP: -&Parámetrus: -Ocionis -Creal archivu 'SF&X' -Comprimil ficherus compartíus -Encritación -Métou encritación: -Encrital &nombris de ficheru -Usu e memoria pa compresión: -Usu e memoria pa decompresión: -4050 -Almacenal -La más respahila -Respahila -Normal -Másima -Ultra -4060 -Añiil i remprazal ficherus -Atualizal i añiil ficherus -Atualizal sólu ficherus esistentis -Sincronizal ficherus -4070 -Esproral -Tolos ficherus -Nu sóliu -Sóliu -6000 -Copial -Movel -Copial a: -Movel pa: -Copiandu... -Moviendu... -Renombrandu... -Selecional diretóriu destinu. -Operación nu soportá. -S'alcuentrau'n yerru al renombral el ficheru u diretóriu -Confirmal copia el ficheru -De siguru que quieri copiar estus ficherus al archivu? -6100 -Confirmal eliminación del ficheru -Confirmal eliminación del direhtoriu -Confirmal eliminación de varius ficherus -De siguru que quieri eliminal '{0}'? -De siguru que quieri eliminal el diretóriu '{0}' i tol su conteniu? -De siguru que quieri eliminal estus {0} elementus? -Eliminandu... -S'alcuentrau'n yerru al eliminal el ficheru u diretóriu -El sistema nu puei movel un ficheru con ruta larga a la Papelera Recicrahi -6300 -Creal diretóriu -Creal ficheru -Nombri e diretóriu: -Nombri el ficheru: -Nuevu diretóriu -Nuevu ficheru -S'alcuentrau'n yerru al creal el diretóriu -S'alcuentrau'n yerru al creal el ficheru -6400 -Comentáriu -&Comentáriu: -Selecional -Deselecional -Máscara: -6600 -Propieais -Estorial de diretórius -Mensahis de dianósticu -Mensahi -7100 -Mi PC -Entorno de red -Documentos -Sistema -7200 -Añiil -Estrayel -Comprebal -Copial -Movel -Eliminal -Inhormazión -7300 -Desapartal ficheru -&Desapartal a: -Desapartal en &balandronis, 'bytes': -Desapartandu... -Confirmal desapartamientu -De siguru que quieri desapartal el ficheru'n {0} volúmenis? -El tamañu lus volúmenis debi sel mas caqueru que'l del ficheru orihinal -Tamañu el volumin nu váliu -Introuza'l tamañu el volumin: {0} 'bytes'.\nDe siguru que quieri desapartal l'archivu'n tantus volúmenis? -7400 -Uñil ficherus -&Uñil en: -Uñiendu... -Selecional sólu'l primel ficheru -Nu s'á puíu detetal el ficheru comu parti d'un ficheru desapartau -Nu s'á puíu alcuentral más d'un balandrón del ficheru desapartau -7500 -Calculandu la suma e verificación... -Inhormazión de suma e verificación -Suma e verificación de 'CRC' pala inhormazión: -Suma e verificación de 'CRC' pala inhormazión i lus nombris: -7600 -Prebas ('benchmark') -Usu e memoria: -Comprimiendu -Comprimiendu -Razón -Razón total -Atual -Resurtau -Usu e CPU -Razón / Usu -Pasis: diff -Nru p7zip-rar-16.02/GUI/Lang/fa.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/fa.txt --- p7zip-rar-16.02/GUI/Lang/fa.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/fa.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.12 : Edris Naderan -; 4.53 : Mehdi Farhadi -; 9.22 : Hessam Mohamadi -; -; -; -; -; -; -; -; -0 -7-Zip -Farsi -فارسی -401 -تایید -لغو - - - -بله&ه -&خیر -بستن -راهنما - -ادامه -440 -بله روی همه -نه روی همه -توقف -ریستارت -پس زمینه -پیش زمینه -وقفه -متوقف -آیا میخواهید عملکرد را لغو میکنید؟ -500 -فایل -ویرایش -مشاهده -موردعلاقه ها -ابزارها -راهنما -540 -بازکردن -بازکردن از داخل -بازکردن از خارج -مشاهده -ویرایش -تغییرنام -کپی به... -انتقال به... -حذف -تقسیم فایل... -ادغام فایل.. -مشخصات -توضيح.. -محاسبه مجموع مقابله ای -مقایسه گر -ایجاد پوشه -ایجاد فایل -خروج -600 -انتخاب همه -لغو انتخاب‌ همه -انتخاب معکوس -انتخاب... -لغو انتخاب... -انتخاب بر حسب نوع -لغو انتخاب بر حسب نوع -700 -آیکون‌ بزرگ -آیکون‌ کوچک -لیست -جزئیات -730 -نامرتب -مشاهده یکنواخت -2 پانل -نوارابزارها -بازکردن ریشه پوشه -یک مرحله به بالا -تاریخچه پوشه ها.. -تازه کردن -750 -نوارابزار آرشیو -نوارابزار استاندارد -دکمه بزرگ -نمایش متن دکمه ها -800 -افزودن پوشه به مورد علاقه بعنوان -بوکمارک -900 -گزینه ها.. -سنجش -960 -محتویات.. -درباره برنامه.. -1003 -مسیر -نام -پسوند -پوشه -حجم -حجم فشرده شده -صفات -ساخته شده -دستیابی شده -تغییر یافته -یکدست -توضیح دار -رمزگذاری شده -تقسیم قبل از -تقسیم بعد از -لغت نامه -سی آر سی -نوع -Anti -روش -سیستم میزبان -فایل سیستمی -کاربر -گروه -بلوک -توضيح‌ -موقعیت -مسیر پیشوند -پوشه ها -فایل ها -نسخه -بخش -چند بخشی -آفست -لینک -بلوک ها -بخش ها - -64 بیت -Big-endian -پردازنده -حجم فیزیکی -حجم سرساز ها -مجموع مقابله ای -خصوصیات -آدرس مجازی -شناسه -نام کوتاه -سازنده برنامه -حجم قطاع -حالت -لینک -خطا -مجموع حجم -فضای خالی -حجم کلاستر -برچسب -نام محلی -ارائه دهنده -2100 -گزینه ها -زبان -زبان: -ویرایشگر -ویرایشگر: -مقایسه گر: -2200 -سیستم -وابسته سازی برنامه با: -2301 -افزودن منوی برنامه به منوی ویندوز -منوها به صورت آبشاری در یک منو -آیتم های منوی برنامه: -2320 -<پوشه> -<آرشیو> -بازکردن آرشیو -استخراج فایل‌ها... -افزودن به آرشیو... -تست آرشیو -استخراج در اینجا -استخراج به {0} -افزودن به {0} -فشرده سازی و ارسال با ایمیل... -فشرده‌سازی در {0} و ارسال با ایمیل -2400 -پوشه ها -پوشه در حال کار -پوشه موقت سیستم -فعلی -مشخص کنید: -فقط برای درایوهای پرتابل استفاده شود -یک مکان برای فایل های موقتی آرشیو مشخص کنید -2500 -تنظیمات -نمایش آیتم ".." -نمایش آیکون واقعی فایل -نمایش منوی سیستم -انتخاب سطر به طور کامل -نمایش خطوط توری -تک کلیک برای بازکردن یک آیتم -حالت انتخاب جايگزين -استفاده از صفحات حافظه حجیم -2900 -درباره برنامه -برنامه‌ای که در پیش رو دارید یک برنامه رایگان است، اما شما می توانید با پرداخت مبلغی جزئی به توسعه این نرم‌افزار کمک کنید. -3000 -سیستم مقدار حافظه موردنیاز را نمیتواند اختصاص دهد -خطایی وجود ندارد -{0} آیتم انتخاب شده -ایجاد پوشه '{0}' ممکن نیست -عملکرد بروزرسانی برای این آرشیو بروزرسانی نمیشود -فایل '{0}' را بعنوان یک آرشیو نمیتوان باز کرد -آرشیو رمزگذاری شده '{0}' را نمیتوان باز کرد.رمزعبور اشتباه است؟ -نوع آرشیو پشتیبانی نشده -فایل {0} از قبل موجود است -فایل '{0}' تغییر کرده است.\n آیا میخواهید این فایل در آرشیو بروزرسانی شود؟ -این فایل قابل بروزرسانی نمی‌باشد\n'{0}' -ویرایشگر را نمیتوان اجرا کرد -فایل شبیه ویروس است (نام فایل حاوی فضای بلندی در نام هست). -عملکرد نمیتواند از پوشه ای که مسیر بلند دارد فراخوانی شود -شما باید یک فایل انتخاب کنید -شما باید یک یا تعداد بیشتری فایل انتخاب کنید -تعداد آیتم ها بسیار زیاد است -3300 -در حال استخراج -فشرده سازی -تست -درحال بازکردن.. -در حال اسکن.. -3400 -استخراج -استخراج به: -یک مکان برای فایل های استخراج شده تعیین کنید -3410 -نوع مسیر -نام مسیر کامل -بدون نام مسیر -3420 -حالت جایگزینی -پرسش قبل از جایگزینی -جایگزینی بدون اخطار -چشمپوشی فایل‌های موجود -تغییرنام خودکار -تغییرنام خودکار فایل های موجود -3500 -تایید جایگزینی فایل -پوشه مقصد از قبل حاوی فایل در حال پردازش هست -آیا میخواهید فایل موجود با -این یکی جایگزین شود؟ -{0} بایت -تغییرنام خودکار -3700 -روش فشرده سازی برای '{0}' پشتیبانی نشذه است -خطای داده در '{0}'. اين فايل شکسته هست -سی آر سی در '{0}' موفق نشد.فایل شکسته هست -خطای داده در فايل رمزگذارى شده '{0}'. رمزعبور اشتباه است؟ -سی آر سی در فایل رمزگذاری شده '{0}' موفق نشد.رمزعبور اشتباه است -3800 -رمزعبور -رمزعبور: -تكرار رمزعبور: -نمایش رمزعبور -رمزعبورها یکسان نیست -فقط از حروف انگليسى، اعداد و علامت‌هاى خاص (!، #، $، ...) در رمزعبور استفاده كنيد -رمزعبور خیلی بلند است -رمزعبور -3900 -زمان سپری شده: -زمان باقیمانده: -مجموع حجم: -سرعت: -پردازش شده: -نسبت فشرده سازی: -خطاها: -آرشیو‌: -4000 -افزودن به آرشیو -آرشیو: -حالت بروزرسانی: -فرمت آرشیو: -ميزان فشرده‌سازی: -روش فشرده سازی: -حجم لغت نامه: -اندازه لغت: -حجم بلوک یکدست: -تعداد هسته پردازنده -پارامترها: -گزینه ها -ایجاد ارشیو خوداستخراجگر -فشرده سازی فایل های مشترک درسایر برنامه ها -رمزگذاری -روش رمزگذاری: -رمزگذاری نام فایل ها -حافظه مصرفی برای فشرده سازی: -حافظه مصرفی برای استخراج: -4050 -ذخیره -سریعترین -سریع -عادی -حداکثر -مافوق -4060 -افزودن و جایگزینی فایل ها -بروزرسانی و افزودن فایل ها -تازه کردن فایل های موجود -همگامسازی فایل ها -4070 -جستجو -همه فایل ها -غیر-یکدست -یکدست -6000 -کپی -انتقال -کپی به: -انتقال به: -در حال کپی... -در حال انتقال... -تغییرنام... -پوشه مقصد را انتخاب كنيد -عملکرد برای این پوشه پشتیبانی نمیشود -خطای تغییر نام فایل یا پوشه -تایید کپی فایل -آیا میخواهید فایل ها را به ارشیو کپی کنید -6100 -تایید حذف فایل -تایید حذف پوشه -تایید حذف فایل ها -آیا میخواهید '{0}' را حذف کنید؟ -آیا میخواهید پوشه '{0}' و همه محتویات آن را حذف کنید؟ -آیا میخواهید این {0} آیتم را حذف کنید؟ -در حال حذف... -خطای حذف فایل یا پوشه -سیستم فایل با مسیر بلند را نمیتواند به سطل زباله انتقال دهد -6300 -ایجاد پوشه -ایجاد فایل -نام پوشه: -نام فایل: -پوشه جدید -فایل جدید -خطای ایجاد پوشه -خطای ایجاد فایل -6400 -توضيح -توضيح: -انتخاب -لغو انتخاب -ماسك: -6600 -مشخصات -تاریخچه پوشه‌ها -پیغام‌های تشخيصی -پیام -7100 -رایانه -شبکه -اسناد -سیستم -7200 -افزودن -استخراج -تست -کپی -انتقال -حذف -اطلاعات -7300 -تقسیم فایل -تقسیم در: -تقسیم به چندین بخش،برحسب بایت: -در حال تقسیم... -تاييد تقسیم فایل -آیا میخواهید اين فايل را به {0} بخش تقسيم كنيد؟ -حجم بخش ها باید کوچکتر از اندازه فایل اصلی باشد -حجم بخش نادرست است -حجم بخش های مشخص شده: {0} بايت.\nآیا میخواهید آرشيو را به بخش هایی به اين اندازه تقسيم كنيد؟ -7400 -ادغام فایل ها -ادغام در: -در حال ادغام... -فقط اولین بخش فایل را انتخاب کنید -فایل را نمی تواند بعنوان فایل تقسیمی تشخیص دهد -بیشتر از یک بخش از فایل تقسیمی را نمیتواند پیدا کند -7500 -محاسبه مجموع مقابله ای.. -اطلاعات مجموع مقابله ای -مجموع مقابله ای سی آر سی برای داده: -مجموع مقابله ای سی آر سی برای داده و نام: -7600 -سنجش -حافظه مصرفی: -فشرده سازی -استخراج -رتبه بندی -رتبه بندی کلی: -فعلی -دستاورد -مصرف پردازنده -رتبه بندی / مصرف -تعداد عبور: diff -Nru p7zip-rar-16.02/GUI/Lang/fi.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/fi.txt --- p7zip-rar-16.02/GUI/Lang/fi.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/fi.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.08 : Ari Ryynanen -; 4.30 : Jarko P. -; 4.42 : Juhani Valtasalmi -; 9.35b : T.Sakkara -; 15.05 : 2015-08-07 : Lauri Kenttä -; -; -; -; -; -; -0 -7-Zip -Finnish -Suomi -401 -OK -Peruuta - - - -&Kyllä -&Ei -&Sulje -Ohje - -&Jatka -440 -Kyllä k&aikkiin -E&i kaikkiin -Pysäytä -Aloita uudelleen -&Tausta-ajona -&Normaali prioriteetti -&Pysäytä -Pysäytetty -Keskeytetäänkö toiminto? -500 -&Tiedosto -&Muokkaa -&Näytä -&Suosikit -Työ&kalut -&Ohje -540 -&Avaa -Avaa s&isäisesti -Avaa ulkoisesti -&Näytä -&Muokkaa -Nimeä &uudelleen -&Kopioi... -&Siirrä... -&Poista -&Jaa osiin... -&Yhdistä jaetut... -&Ominaisuudet -Ku&vaus -Laske tarkiste -Erot -Luo kansio -Luo tiedosto -&Lopeta -Linkitä -Vaihtoehtoiset tietovirrat -600 -V&alitse kaikki -Poista &valinnat -&Käänteinen valinta -Valitse... -Poista valinta... -Valitse lajeittain -Poista valinta lajeittain -700 -Suu&ret kuvakkeet -&Pienet kuvakkeet -&Luettelo -&Tiedot -730 -Alkuperäinen järjestys -Kansioiden sisältö luetteloituna -&Kaksi panelia -&Työkalupalkki -Avaa pääkansio -Avaa yläkansio -Kansiohistoria... -P&äivitä -Automaattipäivitys -750 -Pakettipalkki -Vakiopalkki -Suuret painikkeet -Näytä painiketekstit -800 -&Lisää kansio Suosikkeihin -Kirjanmerkki -900 -&Asetukset... -&Nopeustesti -960 -&Sisältö... -&Tietoja ohjelmasta... -1003 -Polku -Nimi -Pääte -Kansio -Koko -Pakattu koko -Määritteet -Luotu -Käytetty -Muokattu -Kiinteä -Kuvailtu -Suojaus -Jaa ennen -Jaa jälkeen -Sanakirja -Tarkiste -Laji -Vastakohta -Menetelmä -Isäntäjärjestelmä -Tiedostojärjestelmä -Käyttäjä -Ryhmä -Lohkoja -Kuvaus -Kohta -Polun etuliite -Kansioita -Tiedostoja -Versio -Nimi -Jaettu osiin -Siirtymä -Linkit -Lohkot -Nimet - -64-bittinen -Big-endian -Suoritin -Fyysinen koko -Otsikon koko -Tarkiste -Ominaisuudet -Näennäisosoite -ID -Lyhyt nimi -Luontisovellus -Sektorikoko -Tila -Symbolinen linkki -Virhe -Aseman koko -Vapaata tilaa -Varausyksikön koko -Nimi -Paikallinen nimi -Palveluntarjoja -NT-suojaukset -Vaihtoehtoinen tietovirta -Muu -Poistettu -On kansiorakenne - - -Virhelaji -Virheet -Virheet -Varoitukset -Varoitus -Tietovirrat -Vaihtoehtoiset tietovirrat -Vaihtoehtoisten tietovirtojen koko -Näennäiskoko -Pakkaamaton koko -Fyysinen koko -Aseman indeksi -Alilaji -Kuvaus -Koodisivu - - - -Loppupään koko -Upotetun segmentin koko -Linkki -Kiinteä linkki -iNode - -Vain luku -2100 -Asetukset -Kieli -Kieli: -Muokkausohjelmat -&Tekstieditori: -&Erojen etsintä: -2200 -Järjestelmäliitännät -Liitä 7-Zip seuraaviin tiedostotyypeihin: -Kaikki käyttäjät -2301 -Liitä 7-Zip järjestelmän valikoihin. -Ryhmitetty järjestelmävalikko -Järjestelmävalikon sisältö: -Näytä järjestelmävalikon kuvakkeet -2320 - - -Avaa -Pura... -Lisää pakettiin... -Eheystarkastus -Pura tänne -Pura kansioon {0} -Lisää pakettiin {0} -Pakkaa tiedostot ja lähetä... -Lisää pakettiin {0} ja lähetä -2400 -Kansiot -&Työkansio -&Järjestelmän väliaikaiskansio -&Nykyinen kansio -&Valittu kansio: -Käytä vain siirrettäville tietovälineille -Määritä väliaikaistiedostojen sijainti. -2500 -Tiedostoikkuna -Näytä &yläkansion symboli -Näytä &aidot tiedostokuvakkeet -Näytä &järjestelmävalikko -&Valitse koko rivi -Näytä &ruudukko -Avaa &kertanapsautuksella -Vaihtoehtoinen valintojen &esitystapa -Käytä &suuria muistisivuja -2900 -Tietoja -7-Zip on ilmaisohjelmisto. -3000 -Ei riittävästi muistia toimintoa varten -Ei virheitä. -{0} tiedosto(a) valittu -Ei voida luoda kansioita '{0}.' -Tätä pakettia ei voi päivittää. -Tiedoston '{0}' pakkausta ei voi purkaa. -Ei voi avata suojattua pakettia '{0}'. Väärä salasana? -Pakkaustapaa ei tueta -Tiedosto {0} on jo olemassa -Tiedostoa '{0}' on muutettu.\nHaluatko päivittää paketin? -Ei voida päivittää tiedostoa \n'{0}'. -Editoria ei voida käynnistää. -Tiedosto vaikuttaa haittaohjelmalta, sillä sen nimi sisältää peräkkäisiä välilyöntejä. -Toimintoa ei voi suorittaa kansiosta, jonka nimi on pitkä. -Valitse yksi tiedosto -Valitse vähintään yksi tiedosto -Liian monta kohdetta. -Ei voida avata tiedostoa {0}-pakettina -Tiedosto on avattu {0}-pakettina -Paketti on auki eri alkukohdasta (offset) -3300 -Puretaan paketti -Lisätään pakettiin -Eheystarkistus -Avataan... -Etsitään... -Poistetaan -3320 -Lisätään -Päivitetään -Analysoidaan -Kopioidaan -Pakataan uudestaan -Ohitetaan -Poistetaan -Luodaan otsikkoa -3400 -Pura -&Pura kansioon -Määritä puretuille tiedostoille sijainti. -3410 -Polut: -Täydet polut -Ei polkuja (vain nimi) -Absoluuttiset polut -Suhteelliset polut -3420 -Samannimiset tiedostot: -Kysy tapauskohtaisesti -Korvaa -Ohita -Uudelleennimeä automaattisesti -Uudelleennimeä entiset automaattisesti -3430 -Estä pääkansion kahdennus -Palauta tiedostojen suojaukset -3500 -Vahvista tiedoston korvaus -Kansiossa on jo samanniminen tiedosto. -Korvataanko aiempi tiedosto -tällä tiedostolla? -{0} tavua -&Uudelleennimeä automaattisesti -3700 -Tiedoston '{0}' pakkaustapaa ei tueta. -Sisältövirhe tiedostossa '{0}'. Tiedosto on viottunut. -Tiedoston '{0}' eheystarkistus epäonnistui. Tiedosto on vioittunut. -Virhe avattaessa suojattua tiedostoa '{0}'. Väärä salasana? -Tarkistevirhe avattaessa suojattua tiedostoa '{0}'. Väärä salasana? -3710 -Väärä salasana? -3721 -Pakkaustapaa ei tueta -Sisältövirhe -Tarkistevirhe -Sisältö ei ole käytettävissä -Sisällön ennenaikainen loppuminen -Varsinaisen tietosisällön jälkeen on ylimääräistä sisältöä -Tiedosto ei ole pakattu -Otsikkovirhe -Väärä salasana -3763 -Pakkauksen alku ei käytettävissä -Pakkauksen alkua ei vahvistettu - - - -Toiminto ei tuettu -3800 -Syötä salasana -Syötä salasana: -Toista salasana: -Näytä &salasana -Salasanat eivät täsmää -Salasanassa voi käyttää numeroita ja erikoismerkkejä, mutta EI skandinaavisia kirjaimia. -Liian pitkä salasana -Salasana -3900 -Aikaa kulunut: -Aikaa jäljellä: -Koko: -Nopeus: -Käsitelty: -Pakkaussuhde: -Virheitä: -Paketteja: -4000 -Lisää pakettiin -&Paketti: -&Päivitystapa: -Pakkaus&: -Pakkauksen &taso: -Pakkaus&menetelmä: -&Sanakirjan koko: -&Sanan koko: -Lohkokoko -Prosessorisäikeet: -&Parametrit: -Lisäasetukset -Luo itsepurkautuva paketti -Pakkaa yhteiset tiedostot -Suojaus -Salausalgoritmi -Tiedosto&nimien suojaus -Pakkaamiseen käytettävä muisti: -Purkamiseen käytettävä muisti: -Poista pakkauksen jälkeen -4040 -Tallenna symboliset linkit -Tallenna kiinteät linkit -Tallenna vaihtoehtoiset tietovirrat -Tallenna tiedostojen suojaukset -4050 -Ei pakkausta -Nopein -Nopea -Normaali -Maksimi -Ultra -4060 -Lisää ja korvaa -Päivitä ja lisää -Päivitä -Synkronoi -4070 -Selaa -Kaikki tiedostot -Muuttuva -Kiinteä -6000 -Kopioi -Siirrä -Kopioi kansioon: -Siirrä kansioon: -Kopioidaan... -Siirretään... -Nimetään uudelleen... -Valitse kohdekansio. -Toiminto ei ole tuettu. -Virhe uudelleennimettäessä tiedostoa tai kansiota -Vahvista tiedoston kopioiminen -Kopioidaanko tiedostot pakettiin -6100 -Vahvista tiedoston poisto -Vahvista kansion poisto -Vahvista useiden kohteiden poisto -Poistetaanko tiedosto '{0}'? -Poistetaanko kansio '{0}' ja kaikki sen sisältö? -Poistetaanko nämä {0} kohdetta? -Poistetaan... -Virhe poistettaessa tiedostoa tai kansiota -Roskakoriin ei voida siirtää tiedostoa, jolla on pitkä nimi -6300 -Luo uusi kansio -Luo uusi tiedosto -Kansion nimi: -Tiedostonimi: -Uusi kansio -Uusi tiedosto -Virhe luotaessa kansiota -Virhe luotaessa tiedostoa -6400 -Kuvaus -&Kuvaus: -Valitse -Poista valinta -Maski: -6600 -Ominaisuudet -Kansiohistoria -Tietoja -Viesti -7100 -Tietokone -Verkko -Dokumentit -Järjestelmä -7200 -Lisää -Pura -Eheystarkistus -Kopioi -Siirrä -Poista -Ominaisuudet -7300 -Jaa tiedosto osiin -&Jaa kansioon: -&Osien koko jaettaessa: -Jaetaan osiin... -Vahvista jakaminen. -Jaetaanko tiedosto {0} osaan? -Jaetun osan koon pitää olla alkuperäistä pienempi. -Jaetun osan koko ei kelpaa -Jaettavien osien koko: {0} tavua.\nJaetaanko tiedosto sen kokoisiin osiin? -7400 -Yhdistä jaetut tiedostot -&Yhdistä kansioon: -Yhdistetään... -Valitse jaetusta tiedostosta vain ensimmäinen osa -Tiedosto ei ole jaetun tiedoston osa -Jaetun tiedoston osista löydettiin vain yksi -7500 -Lasketaan tarkiste... -Tarkisteet -Sisällön tarkiste: -Sisällön ja tiedostonimien tarkiste: -7600 -Nopeustesti -Muistin käyttö: -Pakkaaminen -Purkaminen -Luokitus -Kokonaisluokitus -Nykyinen -Tulos -Suoritinkäyttö -Luokitus / käyttö -Läpäisty: -7700 -Linkitys -Linkitä -Linkitys kohteesta: -Linkitys kohteeseen: -7710 -Linkkilaji -Kiinteä linkki -Symbolinen tiedostolinkki -Symbolinen kansiolinkki -Kansioliitos diff -Nru p7zip-rar-16.02/GUI/Lang/fr.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/fr.txt --- p7zip-rar-16.02/GUI/Lang/fr.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/fr.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.07 : Nicolas Sierro -; 9.07 : Philippe Berthault -; 15.14 : Sylvain St-Amand (SSTSylvain) -; -; -; -; -; -; -; -; -0 -7-Zip -French -Français -401 -OK -Annuler - - - -&Oui -&Non -&Fermer -Aide - -&Continuer -440 -Oui pour &Tous -Non pour T&ous -Arrêter -Redémarrer -&Arrière-plan -P&remier plan -&Pause -En pause -Êtes-vous sur de vouloir annuler ? -500 -&Fichier -&Édition -Affic&hage -Fa&voris -&Outils -&Aide -540 -&Ouvrir -Ouvrir à l'&intérieur -Ouvrir à l'e&xtérieur -&Voir -&Édition -Reno&mmer -&Copier vers... -&Déplacer vers... -S&upprimer -Diviser le &fichier... -Combiner les fic&hiers... -P&ropriétés -Comme&ntaire... -Somme de contrôle -Diff -Créer un dossier -Créer un fichier -&Quitter -Lien -Flux &Alternatif -600 -Sélectionner &Tout -Désélectionner Tout -&Inverser la Sélection -Sélectionner... -Désélectionner... -Sélectionner par Sorte -Désélectionner par Sorte -700 -&Grandes Icônes -&Petites Icônes -&Liste -&Détails -730 -Non trié -Vue à plat -&2 Fenêtres -&Barres d'outils -Ouvrir le dossier racine -Dossier parent -Historique des dossiers... -Actualis&er -Actualiser Automatiquement -750 -Barre d'Archive -Barre Standard -Grands Boutons -Montrer le texte des Boutons -800 -&Ajouter le répertoire aux Favoris -Signet -900 -&Options... -&Test de performance -960 -&Contenu... -À &propos de 7-Zip... -1003 -Chemin -Nom -Extension -Dossier -Taille -Compressé -Attributs -Créé le -Accédé le -Modifié le -Solide -Commentaire -Chiffrer -Diviser Avant -Diviser Après -Dictionnaire - -Sorte -Anti -Méthode -OS hôte -Système de Fichiers -Utilisateur -Groupe -Bloc -Commentaire -Position -Préfixe -Dossiers -Fichiers -Version -Volume -Multivolume -Offset -Liens -Blocs -Volumes - -64 bits -Big-endian -CPU -Taille physique -Taille des en-têtes -Somme de contrôle -Caractéristiques -Adresse virtuelle -ID -Nom court -Application créatrice -Taille de secteur -Mode -Lien Symbolique -Erreur -Taille Totale -Espace Libre -Taille des clusters -Nom de volume -Nom local -Fournisseur -Sécurité NT -Flux alternatif -Aux -Effacer -En Arbre - - -Type d'erreur -Erreurs -Erreurs -Avertissements -Avertissement -Flux -Flux Alterné -Grosseur du Flux Alterné -Grosseur Virtuel -Grosseur Décompressé -Grosseur Physique Totale -Indexe du Volume -Sous-Type -Commentaire Bref -Code Page - - - -Grosseur Tail -Grosseur Embedded Stub -Lien -Lien Solide -iNode - -Lecture-seulement -2100 -Options -Langue -Langue : -Éditeur -&Éditeur : -&Diff : -2200 -Système -Associer avec 7-Zip : -Tous les utilisateurs -2301 -Intégrer 7-Zip au menu contextuel -Menu contextuel en cascade -Éléments du menu contextuel : -Icônes dans le menu contextuel -2320 - - -Ouvrir archive -Extraire les fichiers... -Ajouter à l'archive... -Contrôler l'archive -Extraire Ici -Extraire vers {0} -Ajouter à {0} -Compresser et envoyer par courriel... -Compresser vers {0} et envoyer par courriel -2400 -Dossiers -Dossier de &travail -Dossier temporaire du &système -&Courant -S&pécifié : -N'utiliser que pour les médias amovibles -Spécifiez un dossier pour les fichiers d'archive temporaires. -2500 -Paramètres -Afficher l'élément ".." -Afficher les icônes réelles des fichiers -Afficher le menu système -&Sélectionner toute la ligne -Afficher la &grille -Simple clic pour ouvrir un item -Utiliser la sélection &alternative -Utiliser des &grosses pages mémoire -2900 -A propos de 7-Zip -7-Zip est un logiciel libre -3000 -Le système ne peut allouer la quantité de mémoire nécessaire -Il n'y a pas d'erreurs -{0} objet(s) sélectionné(s) -Le dossier '{0}' ne peut pas être créé -Les opérations de mise à jour ne sont pas disponibles pour cette archive. -Le fichier '{0}' ne peut être ouvert comme une archive -L'archive cryptée '{0}' ne peut être ouverte. Mauvais mot de passe ? -Ce type d'archive n'est pas supporté -Le fichier {0} existe déjà -Le fichier '{0}' a été modifié.\nVoulez-vous le mettre à jour dans l'archive ? -Impossible de mettre à jour\n'{0}' -Impossible de démarrer l'éditeur. -Le fichier est peut-être un virus (le nom contient des grands espacements pour masquer l'extension). -Cette opération ne peut être effectuée depuis un dossier ayant un trop long chemin d'accès. -Vous devez sélectionner un fichier -Vous devez sélectionner un ou plusieurs fichiers -Trop d'objets -Ne peut ouvrir les fichiers {0} comme une archive -Le fichier {0} est ouvert comme une archive -L'archive est ouverte avec un décalage -3300 -Extraction -Compression -Contrôle -Ouverture... -Exploration... -Enlever -3320 -Ajoute -Modifie -Analyse -Réplique -Remballage -Passe -Efface -Création d'un en-tête -3400 -Extraire -E&xtraire vers : -Choisissez un dossier pour l'extraction des fichiers. -3410 -Mode de chemin : -Nom de chemin complet -Pas de nom de chemin -Nom de chemin absolu -Nom de chemin relatif -3420 -Mode de remplacement : -Confirmer avant de remplacer -Remplacer sans demander -Ignorer les fichiers existants -Renommer automatiquement -Renommer les fichiers existants -3430 -Élimine la duplication du répertoire racine -Restauration du fichier de sécurité -3500 -Confirmer le remplacement de fichier -Le dossier de destination contient déjà un fichier avec ce nom. -Voulez-vous remplacer le fichier existant -par celui-ci ? -{0} octets -Renommer &automatiquement -3700 -Méthode de compression non valide pour '{0}'. -Donnée erronée dans le fichier '{0}'. Le fichier est corrompu. -Échec du contrôle CRC dans le fichier '{0}'. Le fichier est corrompu. -Donnée erronée dans le fichier crypté '{0}'. Mauvais mot de passe ? -Échec du contrôle CRC dans le fichier crypté '{0}'. Mauvais mot de passe ? -3710 -Pas le bon mot de passe ? -3721 -Méthode de compression non supportée -Erreur de donnée -Échec de CRC -Donnée non disponible -Fin de données inattendues -Il y a des données après la fin des données utiles -N'est pas une archive -Erreur en-têtes -Mauvais mot de passe -3763 -Démarrage non disponible d'une archive -Démarrage non confirmé d'une archive - - - -Option non supportée -3800 -Entrez le mot de passe -Entrez le mot de passe : -Entrez le mot de passe à nouveau : -&Afficher le mot de passe -Les mots de passe ne correspondent pas -Pour le mot de passe, n'utilisez que des lettres non accentuées, des chiffres et des caractères spéciaux (!, #, $, ...) -Le mot de passe est trop long -Mot de passe -3900 -Temps écoulé : -Temps restant : -Taille totale : -Vitesse : -Traité : -Taux de compression : -Erreurs : -Archive : -4000 -Ajouter à l'archive -&Archive : -&Mode de mise à jour : -&Format de l'archive : -N&iveau de compression : -Méthode de &compression : -&Taille du dictionnaire : -Tai&lle des mots : -Taille de bloc solide : -Nombre de threads CPU : -&Paramètres : -Options -Créer une archive SF&X -Compresser des fichiers partagés -Chiffrement -Méthode de chiffrement : -Chiffre les &noms de fichiers -Mémoire pour la compression : -Mémoire pour la décompression : -Effacer les fichiers après compression -4040 -Emmagasine liens symboliques -Emmagasine liens solides -Emmagasine flux de données alternatifs -Emmagasine fichier de sécurité -4050 -Aucune -Le plus rapide -Rapide -Normale -Maximum -Ultra -4060 -Ajouter et remplacer les fichiers -Mettre à jour et ajouter les fichiers -Rafraîchir les fichiers existants -Synchroniser les fichiers -4070 -Choisir -Tous les fichiers -Non-solide -Solide -6000 -Copier -Déplacer -Copier dans : -Déplacer vers : -Copie... -Déplacement... -Renommage... -Sélectionnez le dossier de destination. -L'opération n'est pas possible pour ce dossier. -Erreur durant le Renommage du Fichier ou du Dossier -Confirmation de la Copie de(s) Fichier(s) -Confirmer la copie de(s) fichier(s) à archiver -6100 -Confirmer la Suppression du Fichier -Confirmer la Suppression du Dossier -Confirmer la Suppression de Multiple Fichiers -Êtes-vous sûr de vouloir supprimer '{0}' ? -Êtes-vous sûr de vouloir supprimer le dossier '{0}' et tout ce qu'il contient ? -Êtes-vous sûr de vouloir supprimer ces {0} objets ? -Suppression... -Erreur durant la suppression du fichier ou du dossier -Le système ne peut mettre à la Corbeille un fichier avec un trop long chemin d'accès -6300 -Créer un Dossier -Créer un Fichier -Nom du dossier : -Nom du fichier : -Nouveau dossier -Nouveau fichier -Erreur durant la création du dossier -Erreur durant la création du fichier -6400 -Commentaire -&Commentaire : -Sélectionner -Désélectionner -Masquer : -6600 -Propriétés -Historique des dossiers -Messages de diagnostic -Message -7100 -Ordinateur -Réseau -Documents -Système -7200 -Ajouter -Extraire -Tester -Copier -Déplacer -Supprimer -Informations -7300 -Diviser le fichier -&Diviser en : -Diviser en &volumes, octets : -Découper... -Confirmez le découpage -Êtes-vous sûr de vouloir découper le fichier en {0} volumes ? -La taille de volume doit être inférieure à la taille du fichier d'origine -Taille de volume incorrecte -Taille de volume spécifiée : {0} octets.\nÊtes-vous sûr de vouloir découper l'archive dans de tels volumes ? -7400 -Combiner les fichiers -&Combiner en : -Combinaison... -Ne sélectionnez que le premier fichier -Ne trouve aucun fichier faisant partie d'une archive divisée -Ne trouve qu'un seul fichier faisant partie d'une archive divisée -7500 -Calcul de la somme de contrôle... -Informations sur la somme de contrôle -Somme de contrôle des données : -Somme de contrôle des données et des noms : -7600 -Test de performance -Utilisation de la mémoire : -Compression -Décompression -Taux -Taux total -Actuel -Résultant -Utilisation CPU -Estimé / Usage -Passe : -7700 -Lien -Lien -Lien depuis : -Lien ver : -7710 -Sorte de lien -Lien solide -Lien symbolique de fichier -Lien symbolique de répertoire -Jonction de répertoire diff -Nru p7zip-rar-16.02/GUI/Lang/fur.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/fur.txt --- p7zip-rar-16.02/GUI/Lang/fur.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/fur.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.60 : Andrea Decorte (Klenje) : http://softfurlan.altervista.org : secont l'ortografie uficiâl de Provincie di Udin -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Friulian -Furlan -401 -Va ben -Scancele - - - -&Sì -&No -&Siare -&Jutori - -&Continue -440 -Sì &a ducj -No a &ducj -Ferme -Torne a inviâ -&Sfont -P&rin plan -&Pause -In pause -Sêstu sigûr di volê scancelâ? -500 -&File -&Modifiche -&Viodude -&Preferîts -&Imprescj -&Jutori -540 -&Viarç -Viarç dentri 7-&Zip -V&iarç fûr di 7-Zip -&Mostre -M&odifiche -Gambie &non -&Copie in... -Mô&f in... -&Elimine -&Divît file... -Torne a &unî files... -P&ropietâts -Comen&t -Calcole so&me di control - -Cree cartele -Cree file -V&a fûr -600 -Selezione d&ut -&Deselezione dut -&Invertìs selezion -Selezione... -Deselezione... -Selezione par gjenar -Deselezione par gjenar -700 -Iconis &grandis -Iconis &piçulis -&Liste -&Detais -730 -Cence ordin -Viodude plane -&2 panei -Sbaris dai impresc&j -Viarç cartele principâl -Parsore di un nivel -Storic des cartelis... -&Atualize -750 -Sbare dai imprescj par l'archivi -Sbare dai imprescj standard -Botons larcs -Mostre test dai botons -800 -&Zonte cartele ai Preferîts sicu -Preferît -900 -&Opzions... -&Banc di prove -960 -&Argoments... -&Informazions su 7-Zip... -1003 -Percors -Non -Estension -Cartele -Dimension -Dimension comprimude -Atribûts -Creât -Ultin acès -Modificât -Solit -Comentât -Cifrât -Divît prin di -Divît daspò di -Dizionari -CRC -Gjenar -Anti -Metodi -SO di origjin -Sisteme dai files -Utent -Grup -Bloc -Coment -Posizion -Prefìs dal troi -Cartelis -Files -Version -Volum -Multivolum -Offset -Leams -Blocs -Volums - -64-bit -Big-endian -CPU -Dimension fisiche -Dimension intestazions -Some di control -Caracteristichis -Direzion virtuâl - - - - - - -Erôr -Dimension totâl -Puest libar -Dimension setôr -Etichete -Non locâl -Furnidôr -2100 -Opzions -Lenghe -Lenghe: -Editôr -&Editôr: - -2200 -Sisteme -Associe 7-Zip cun: -2301 -Integre 7-Zip intal menù contestuâl de shell -Menù contestuâl in discjadude -Elements dal menù contestuâl: -2320 - - -Viarç archivi -Tire fûr files... -Zonte a un archivi... -Prove archivi -Tire fûr ca -Tire fûr in {0} -Zonte a {0} -Comprim e mande par email... -Comprim in {0} e mande par email -2400 -Cartelis -Cartele di &vore -Cartele &provisorie dal sisteme -&Corinte -&Specificade: -Dopre dome pai drives che si puedin gjavâ -Specifiche une posizion pai files provisoris di un archivi. -2500 -Configurazion -Mostre l'element ".." -Mostre lis veris iconis dai files -Mostre il menù dal sisteme -&Selezione la rie intire -Mostre les liniis de &gridele sot - -Mût di selezion &alternatîf -Dopre pagjinis di memorie &largjis -2900 -Informazions su 7-Zip -7-Zip al è un program libar. Purpûr, tu puedis supuartâ il disvilup di 7-Zip cu la regjistrazion. I utents regjistrâts a podaran otignî supuart tecnic. -3000 -Il sisteme nol rive a cjoli la cuantitât di memorie che e covente -Nissun erôr cjatât -{0} ogjet(s) selezionât(s) -No si pues creâ la cartele '{0}' -Lis operazions di atualizazion no son supuartadis par chest archivi. -No si pues viarzi il file '{0}' come archivi -No si pues viarzi l'archivi cifrât '{0}'. Ise sbaliade la peraule clâf? -Gjenar di archivi no supuartât -Il file {0} al esist za -Il file '{0}' al è stât modificât.\nVuelistu atualizâlu intal archivi? -No si pues atualizâ il file\n'{0}' -No si pues inviâ l'editôr. -Il file al samee un virus (il non al à dentri un grum di spazis). -Cheste operazion no pues jessi clamade di une cartele cuntun troi lunc. -Tu scugnis sielzi un file -Tu scugnis sielzi un o plui files -Masse elements -3300 -Daûr a tirâ fûr... -Daûr a comprimi -Daûr a provâ -Daûr a viarzi... -Daûr a scandaiâ... -3400 -Tire fûr -Tir&e fûr in: -Specifiche une posizion pai files tirâts fûr. -3410 -Struture des cartelis -Percors intîrs -Nissun percors -3420 -Sore scriture -Domande prin di scrivi parsore -Scrîf parsore cence domandâ -Salte i files che esistin -Gambie nons in automatic -Gambie nons in automatic se a esistin -3500 -Conferme de sostituzion dal file -Inte cartele di destinazion al è za il file processât. -Vuelistu sostituî il file esistint -cun chest file? -{0} bytes -&Gambie non in automatic -3700 -Il metodi di compression nol è supuartât par '{0}'. -Erôr di dâts in '{0}'. Il file al è corot. -CRC falît in '{0}'. Il file al è corot. -Erôr di dâts tal file cifrât '{0}'. Peraule clâf sbaliade? -CRC falît tal file cifrât '{0}'. Peraule clâf sbaliade? -3800 -Scrîf peraule clâf -Scrîf la peraule clâf: -Torne a inserî la peraule clâf: -&Mostre la peraule clâf -Lis peraulis clâfs no son compagnis -Dopre dome lis letaris inglesis (no acentadis), i numars e i caratars speciâi (!, #, $, ...) inte peraule clâf -La peraule clâf e je masse lungje -Peraule clâf -3900 -Timp passât: -Timp restant: -Dimension: -Sveltece: -Elaborât: -Tas di compression: -Erôrs: -Archivis: -4000 -Zonte a un archivi -&Archivi: -Mût di at&ualizazion: -&Formât archivi: -Nive&l di compression: -&Metodi di compression: -&Dimension dizionari: -Dimension &peraule: -Dimension bloc solit: -Numar di threads de CPU: -&Parametris: -Opzions -Cree archivi SF&X -Comprim i files condividûts -Ciframent -Metodi di ciframent: -Cifre i &nons dai files -Utilizazion memorie comprimint: -Utilizazion memorie decomprimint: -4050 -Cence compression -Il pi svelt -Svelt -Normâl -Massim -Super -4060 -Zonte e sostituìs files -Atualize e zonte files -Atualize i files che esistin -Sincronize i files -4070 -Sgarfe -Ducj i files -No-solit -Solit -6000 -Copie -Môf -Copie in: -Môf in: -Daûr a copiâ... -Daûr a movi... -Daûr a gambiâ non... -Sielç la cartele di destinazion. -L'operazion no je supuartade. -Erôr gambiant non a un file o une cartele -Conferme de copie dai files -Sêstu sigûr di volê copiâ i files tal archivi -6100 -Conferme de eliminazion dal file -Conferme de eliminazion de cartele -Conferme de eliminazion di plui files -Sêstu sigûr di volê eliminâ '{0}'? -Sêstu sigûr di volê eliminâ la cartele '{0}' e dut ce ch'al è lì dentri? -Sêstu sigûr di volê eliminâ chescj {0} elements? -Daûr a eliminâ... -Erôr eliminant un file o une cartele -Il sisteme nol pues movi un file cuntun troi lunc te Scovacere -6300 -Cree cartele -Cree file -Non de cartele: -Non dal file: -Gnove cartele -Gnûf file -Erôr inte creazion de cartele -Erôr inte creazion dal file -6400 -Coment -&Coment: -Selezione -Deselezione -Filtri: -6600 -Propietâts -Storic des cartelis -Messaçs diagnostics -Messaç -7100 -Ordenadôr -Rêt -Documents -Sisteme -7200 -Zonte -Tire fûr -Prove -Copie -Môf -Elimine -Info -7300 -Divît file -&Divît in: -Divît in &volums, grandece in bytes: -Daûr a dividi... -Conferme de division -Sêstu sigûr di volê dividi il file in {0} tocs? -La dimension di un volum e à di jessi plui piçule di chê dal file origjinâl -Dimension dai volums sbaliade -Dimension dai volums volude: {0} bytes.\nSêstu sigûr di volê dividi l'archivi in tocs di cheste dimension? -7400 -Torne a unî files -&Torne a unî in: -Daûr a tornâ a unî... -Sielç dome il prin file -No si pues rilevâ il file come toc di un file dividût -No son stâts cjatâts plui tocs di file dividûts -7500 -Daûr a calcolâ la some di control... -Informazions su la some di control -Some di control CRC pai dâts: -Some di control CRC pai dâts e i nons: -7600 -Banc di prove -Utilizazion memorie: -Comprimint -Decomprimint -Valutazion -Valutazion totâl -Corint -Risultant -Utilizazion CPU -Judizi / Utilizazion -Passaçs: diff -Nru p7zip-rar-16.02/GUI/Lang/fy.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/fy.txt --- p7zip-rar-16.02/GUI/Lang/fy.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/fy.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.53 : Berend Ytsma -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Frisian -Frysk -401 -Okee -Ofbrekke - - - -&Jawis -&Nee -&Slute -Help - -&Ferfetsje -440 -Jawis foar &Alles -Nee foar A&lles -Stopje -Opnij begjinne -&Eftergrûn -&Foargrûn -&Skoftsje -Skoft -Binne jo wis dat jo ôfbrekke wolle? -500 -&Triem -&Bewurkje -&Byld -B&lêdwizers -&Ark -&Help -540 -&Iepenje -Iepenje &yn -Iepenje bû&ten -&Byld -&Bewurkje -Omne&ame -&Kopiearje nei... -&Ferpleats nei... -&Wiskje -Triemmen &spjalte... -Triemmen Kom&binearje... -E&igenskippen -Komme&ntaar -Kontrôlesom berekenje - -Map meitsje -Triem meitsje -U&tgong -600 -&Alles selektearje -Alles net selektearje -&Seleksje omdraaien -Selektearje... -Net selektearje... -Selektearje neffens type -Net selektearje neffens type -700 -Gru&tte Ikoanen -L&ytse Ikoanen -&List -&Details -730 -Net Sortearre -Platte werjefte -&2 Panielen -&Arkbalke -Haadmap iepenje -Ien nivo omheech -Maphistoarje... -&Ferfarskje -750 -Argyf arkbalke -Standert arkbalke -Grutte knoppen -Knoptekst sjen litte -800 -Map oan blêdwizers &taheakje as -Blêdwizer meitsje -900 -&Opsjes... -&Ykpunt -960 -&Ynhâld... -&7-Zip it hoe en het... -1003 -Paad -Namme -Taheaksel -Map -Grutte -Ynpakte grutte -Skaaimerk -Makke -Lêste tagong -Feroare -Kompakt -Kommentaar -Fersifere -Spjalt foar -Spjalt efter -Wurdboek -CRC -Type -Anty -Metoade -Host OS -Triemsysteem -Brûker -Keppel -Blok -Kommentaar -Posysje -Paad foarheaksel -Mappen -Triemmen -Ferzje -Folume -Multifolume -Offset -Links -Blokken -Folumes - - - - - - - - - - - - - - - -Flater -Totale grutte -Frije romte -Kluster grutte -Kaartsje -Lokale namme -Ferskaffer -2100 -Opsjes -Taal -Taal: -Bewurker -&Bewurker: - -2200 -Systeem -Ferbyn 7-Zip Mei: -2301 -Yntegraasje fan 7-Zip yn ferbânmenu -Ferbânmenu yn trepfoarm -Ferbânmenu-items: -2320 - - -Argyf iepenje -Triemmen útpakke... -Oan argyf taheakje... -Argyf teste -Hjir útpakke -Utpakke yn {0} -Oan {0} taheakje -komprimearje en ferstjoere... -Komprimearje nei {0} en poste -2400 -Mappen -&Wurkmap -&Tydlikesysteemmap -&Aktive -&Oantsjutte: -Allinnich brûke foar útnimbere skiven -ynfiere fan de lokaasje foar tydlike argyftriemmen. -2500 -Ynstellings -".." item sjen litte -Echte triem ikoanen sjen litte -Systeemmenu sjen litte -&Folsleine rige selektearje -&Roaster sjen litte - -&Alternative seleksje modus -Brûk &grut ûnthâld siden -2900 -7-Zip it hoe en het -7-Zip is fergees. Mar, jo kinne de ûntwikkeling stypje troch jo te registrearjen. -3000 - -Der binne gjin flaters -{0} objekt(en) selektearre -Kin map '{0}' net meitsje -Bywurk operaasje waard net stipe troch dit argyf. -Kin triem '{0} net as argyf iepenje -Kin fersifere argyf '{0}' net iepenje. Ferkeard wachtwurd? - - -Triem '{0}' is wizige.\nWolle jo it bywurkje yn it argyf? -Kin triem '{0}'\nnet bywurkje -Kin bewurker net starte. - - - - -Tefolle items -3300 -Utpakke -Oan it komprimearjen -Oan it Testen -Oan it iepenjen... -Oan it skennen... -3400 -Utpakke -U&tpakke nei: -De lokaasje om nei út te pakken oantsjutte. -3410 -Paad modus -Folsleine paadnammen -Gjin paadnammen -3420 -Oerskriuw modus -Freegje foardat jo oerskriuwe -Oerskriuwe sûnder pront -Besteande triemmen oerslaan -Automatysk omneame -Automatysk ek by besteande triemmen -3500 -It ferfangen fan de triem befêstigje -Bestimmingsmap befettet al in triem mei dizze namme. -Wolle jo de triem ferfange -Mei dizze? -{0} bytes -A&utomatysk omneame -3700 -Net stipe kompresjemetoade foar '{0}'. -Data flater yn '{0}'. Triem is beskeadige. -CRC mislearre yn '{0}'. Triem is beskeadige. -Data flater yn fersifere triem '{0}'. Ferkeard wachtwurd? -CRC mislearre yn fersifere triem '{0}'. Ferkeard wachtwurd? -3800 -Wachtwurd ynfiere -Wachtwurd ynfiere: -Wachwurd opnij ynfiere: -Wachtwurd &sjen litte -Wachtwurden komme net oerien -Brûk allinne ingelske letters, nûmers en spesjale karakters (!, #, $, ...) foar it wachtwurd -Wachtwurd is te lang -Wachtwurd -3900 -Ferstrutsen tiid: -Tiid noch te gean: -Totale grutte: -Fluggens: -Ferwurke: -Kompresje nivo: -Flaters: -Argiven: -4000 -Oan argyf taheakje -&Argyf: -&Bywurkmodus: -Argyf &formaat: -Kompresje&nivo: -Kompresje&metoade: -&Wurdboekgrutte: -&Wurdgrutte: -Kompakte blokgrutte: -Tal CPU trieden: -&Parameters: -Opsjes -Meitsje SF&X-argyf -Dielde triemmen komprimearje -Fersifering -Fersiferingmetoade: -Fersiferje triem&nammen -Unthâld gebrûk by komprimearjen: -Unthâld gebrûk by ûntkomprimearjen: -4050 -Bewarje -Fluchst -Fluch -Normaal -Maksimum -Ultra -4060 -Triemmen taheakje en ferfange -Triemmen taheakje en bywurkje -Besteande triemmen ferfarskje -Triemmen lyk rinne litte -4070 -Blêdzje -Alle triemmen -net-kompakt -Kompakt -6000 -Kopiearje -Ferpleatse -Kopiearje nei: -Ferpleats nei: -Oan it kopiearren... -Oan it ferpleatsen... -Omneame... -Bestimmingsmap selektearje. -Operaasje wurdt net stipe. -Flater by it omneamen fan triem of map -Triem kopiearje befêstigje -Binne jo wis dat jo de triemmen nei it argyf kopiearje wolle? -6100 -It wiskjen fan de triem befêstigje -It wiskjen fan de map befêstigje -It wiskjen fan meardere triemmen befêstigje -Binne jo wis dat jo '{0}' wiskje wolle? -Binne jo wis dat jo de map '{0}' en al syn ynhâld wiskje wolle? -Binne jo wis dat jo {0} items wiskje wolle? -Oan it wiskjen -Flater by it wiskjen fan triem of map - -6300 -Map meitsje -Triem meitsje -Mapnamme: -Triem namme: -Nije map -Nije triem -Flater by it meitsjen fan map -Flater by’t meitsjen fan triem -6400 -Kommentaar -&Kommentaar: -Selektearje -Net Selektearje -Masker: -6600 -Eigenskippen -Maphistoarje -Diagnostyk berjocht -Berjocht -7100 -Kompjûter -Netwurk - -Systeem -7200 -Taheakje -Utpakke -Test -Kopiearje -Ferpleatse -Wiskje -Ynformaasje -7300 -Triem spjalte -&Spjalt nei: -Spjalte nei &folumes, bytes: -Oan it Spjalten... -Spjalte befêstigje -Wolle jo de triem spjalte yn {0} dielen? -Folumegrutte moat lytser wêze dan de grutte fan it orizjineel -Net juste folumegrutte -Oantsjutte folumegrutte: {0} bytes.\nWolle jo it argyf yn sokke folumes spjalte? -7400 -Triemmen kombinearje -&Kombinearje nei: -Oan it kombinearjen... -Allinne earste triem selektearje - - -7500 -Kontrôlesom oan it berekenjen... -Kontrôlesom ynformaasje -CRC kontrôlesom foar data: -CRC kontrôlesom foar data en nammen: -7600 -Benchmark -Unthâld gebrûk: -Oan it komprimearren -Oan it ûntkomprimearren -Wurdearring -Totale Wurdearring -Hjoeddeiske -Resultaat -CPU brûkens -Beoardieling / Brûkens -Kear foarbei: diff -Nru p7zip-rar-16.02/GUI/Lang/ga.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ga.txt --- p7zip-rar-16.02/GUI/Lang/ga.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ga.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Seanán Ó Coistín -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Irish -Gaeilge -401 -Tá go maith -Cealaigh - - - -&Tá -&Níl -&Dún -Cabhair - -&Lean ar aghaidh -440 -Tá do gach ceann -Níl go gach ceann -Stad -Atosaigh -&Cúlra -&Tulra -&Cuir ar sos -Ar sos -An bhfuil tú cinnte gur mian leat é a chealú? -500 -&Comhad -&Leagan -Am&harc -Ceanáin -&Uirlisí -&Cabhair -540 -&Oscail -Oscail &istigh -Oscail &lasamuigh -&Amharc -&Eagar -Athainmnigh -&Macasamhlaigh go... -&Bog go... -S&crios -Scar an comhad... -Cumascaigh na comhaid... -Airíonna -Nóta tráchta -Ríomh an tsuim sheiceála -Diff -Cruthaigh fillteán -Cruthaigh comhad -&Scoir -600 -Roghnaigh &uile -Díroghnaigh uile -&Aisiompaigh an roghnúchán -Roghnaigh... -Díroghnaigh... -Roghnaigh de réir cineál -Díroghnaigh de réir cineál -700 -&Deilbhíní móra -&Deilbhíní beaga -&Liosta -&Sonraí -730 -Neamhaicmithe -Gach rud in aon chiseal -&2 fhuinneog -&Barraí na n-uirlisí -Oscail an fréamhfhillteán -Suas fillteán amháin -Oireas na bhfillteán... -Athnuaigh -750 -Barra cartlanna -Barra na n-uirlisí caighdeánacha -Cnaipí móra -Taispeáin an téacs ar na cnaipí -800 -&Cuir an fillteán leis na Ceanáin -Leabharmharc -900 -&Roghanna... -Tástáil fheidhmíochta -960 -&Inneachair... -Maidir le 7-Zip... -1003 -Conair -Ainm -Breiseán -Fillteán -Méid -Comhbhrúite -Tréithe -Cruthaithe an -Rochtain faighte ar an -Mionathraithe ar an -Fothúil -Trácht -Criptithe -Roinn roimh -Roinn i ndiaidh -Foclóir -CRC -Cineál -Frith -Modh -Óstach an CO -Córas na gcomhad -Úsáideoir -Aicme -Ceap -Nóta tráchta -Suíomh -Réimír na conaire -Fillteáin -Comhaid -Leagan -Imleabhar -Il-imleabhair -Fritháirigh -Naisc -Ceapa -Imleabhair - -64 bheart -Foirceann mór -LAP -Méid aiceanta -Méid na gceanntásc -Suim seiceála -Tréithe -Seoladh fíorúil -ID -Ainm gearr -Feidhmchlár a chruthaigh í -Méid na hearnála -Modh -Nasc -Botún -Méid iomlán -Slí atá saor -Méid na braisle -Lipéad -Ainm logánta -Soláthraí -2100 -Roghanna -Teanga -Teanga: -Eagarthóir -&Eagarthóir: -&Diff: -2200 -Córas -Comhthiomsaigh 7-Zip le: -2301 -Comhtháthaigh 7-Zip sa roghchlár comhthéacs -Roghchlár comhthéacs ag titim -Nithe an roghchláir chomhthéacs: -2320 - - -Oscail -Asbhain na comhaid... -Cuir leis an gcartlann... -Tástáil an chartlann -Asbhain anseo -Bain go {0} -Cuir le {0} -Comhbhrúigh agus seol i ríomphost iad... -Comhbhrúigh go {0} agus seol i ríomhphost iad -2400 -Fillteáin -Fillteán oibre -Fillteán sealadach an chórai&s -An comhad reatha -Fillteán &sonraithe: -Bain feidhm as do thiomántáin inaistrithe amháin -Sonraigh suíomh i gcomhair comhaid chartlainne sealadacha. -2500 -Socruithe -Taispeáin an ní ".." -Taispeáin fíordheilbhíní an chomhaid -Taispeáin roghchlár an chórais -Roghnaigh an tsraith ar fad -Taispeáin línte na greille -Brúigh uair amháin chun ní a oscailt -Bain feidhm as modh roghnaithe malartach -Bain feidhm as leathanaigh chuimhne mhóra -2900 -Maidir le 7-Zip -Is saorearra é 7-Zip. Is féidir tacaíocht a thabhairt dá fhorbairt amach anseo, áfach, trí chlárú. -3000 -Ní féidir leis an gcóras an méid cuimhne atá de dhíth a leathdháileadh dó -Níl aon bhotún ann -{0} ní/nithe roghnaithe -Ní féidir an fillteán '{0}' a chruthú -Ní féidir an chartlann seo a nuashonrú. -Ní féidir an comhad '{0}' a oscailt mar chartlann -Ní féidir an chartlann chriptithe '{0}' a oscailt. An bhfuil an focal faire mícheart? -Ní thugtar tacaíocht don chineál comhad seo -Tá an comhad {0} ann cheana -Mionathraíodh an comhad '{0}'.\nAr mhaith leat é a nuashonrú sa chartlann? -Ní féidir an comhad a leanas a nuashonrú\n'{0}' -Ní féidir an t-eagarthóir a thosú. -B'fhéidir gur aicíd é an comhad (tá bearnaí móra in ainm an chomhaid). -Ní féidir an oibríocht seo a chur i bhfeidhm ó fhillteán a bhfuil conair fhada aige. -Caithfear comhad amháin a roghnú -Caithfear comhad amháin nó níos mó a roghnú -An iomarca nithe -3300 -Asbhaint -Ag comhbhrú -Ag tástáil -Ag oscailt... -Ag taiscéal... -3400 -Bain -Bain go: -Roghnaigh fillteán do na comhaid asbhainte. -3410 -Conairí -Conairí iomlána -Níl conair ann -3420 -Modh forscríofa -Deimhnigh sular forscríobhtar -Forscríobh gan iarraidh -Déan neamhaird de na comhaid atá ann cheana -Athainmnigh go huathoibríoch -Athainmnigh na comhaid atá ann cheana -3500 -Deimhnigh ionadú comhaid -Tá comhad leis an ainm seo sa spriocfhillteán cheana féin. -Ar mhaith leat an comhad atá ann cheana a ionadú -leis an gceann seo? -{0} bearta -Athainmnigh go huathoibríoch -3700 -Níl an bealach comhbhrúite bailí i gcomhair '{0}'. -Botún sna sonraí sa chomhad '{0}'. Tá an comhad briste. -Theip ar CRC sa chomhad '{0}'. Tá an comhad briste. -Sonra mícheart sa chomhad criptithe '{0}'. Focal faire mícheart? -Theip ar CRC sa chomhad chriptithe '{0}'. Focal faire mícheart? -3800 -Cuir isteach an focal faire -Cuir an focal faire isteach: -Cuir an focal faire isteach arís: -&Taispeáin an focal faire -Ní hionann an dá fhocal faire -Bain feidhm as litreacha gan síntí fada, uimhreacha agus carachtair shainiúla (!, #, $, ...) -Tá an focal faire rófhada -Focal faire -3900 -Am caite: -Am fágtha: -Méid iomlán: -Luas: -Déanta: -Luas an chomhbhrúite: -Botúin: -Cartlanna: -4000 -Cuir leis an gcartlann -&Cartlann: -&Modh nuashonraithe: -&Formáid na cartlainne: -Méid comhbhrúite: -Modh comhbhrúite: -&Méid an fhoclóra: -Méid na bhfocal: -Méid an chip fhothúla: -Líon na snáitheanna LAP: -&Teorainneacha: -Roghanna -Cruthaigh cartlann SF&X -Comhbhrúigh na comhaid a roinneadh -Criptiú -Modh criptiúcháin: -Criptigh ainmneacha na gcomhad -Cuimhne don chomhbhrúigh: -Cuimhne don dhíchomhbhrúigh: -4050 -Taisc -Is gasta -Gasta -Gnáth -Uasmhéid -Fíorghasta -4060 -Cuir comhaid leis agus ionadaigh -Nuashonraigh na comhaid agus cuir leo -Athnuaigh comhaid atá ann cheana -Comhionannaigh na comhaid -4070 -Siortaigh -Gach comhad -Neamhfhothúil -Fothúil -6000 -Macasamhlaigh -Bog -Macasamhlaigh chuig: -Bog chuig: -Ag acasamhlú... -Ag bogadh... -Ag athainmniú... -Roghnaigh an spriocfhillteán. -Ní féidir sin a dhéanamh. -Tharla botún ag athainmniú an comhad nó an fillteán -Deimhnigh macasamhlú an chomhaid -An bhfuil tú cinnte gur mian leat na comhaid a mhacasamhlú go dtí an chartlann? -6100 -Deimhnigh scriosadh an chomhaid -Deimhnigh scriosadh an chomhaid -Deimhnigh scriosadh iliomad comhad -An bhfuil tú cinnte gur mian leat '{0}' a scriosadh? -An bhfuil tú cinnte gur mian leat an fillteán '{0}' agus gach rud ann a scriosadh? -An bhfuil tú cinnte gur mian leat na {0} nithe seo a scriosadh? -Ag scriosadh... -Tharla botún ag scriosadh an comhad nó an fillteán -Ní thig leis an gcóras comhad le conair fhada a bhogadh go dtí an bosca athchúrsála -6300 -Cruthaigh comhad -Cruthaigh comhad -Ainm an chomhaid: -Ainm an chomhaid: -Comhad nua -Comhad nua -Tharla botún fad is a bhí an comhad á chruthú -Tharla botún fad is a bhí an comhad á chruthú -6400 -Trácht -&Trácht: -Roghnaigh -Díroghnaigh -Folaigh: -6600 -Airíonna -Oireas na bhfillteán -Teachtaireachtaí diagnóiseach -Teachtaireacht -7100 -Ríomhaire -Líonra -Cáipéisí -Córas -7200 -Cuir leis -Asbhain -Tástáil -Macasamhlaigh -Bog -Scrios -Faisnéis -7300 -Roinn an comhad -&Roinn chuig: -Roinn in imleabhair, bearta: -Ag roinnt... -Deimhnigh an roinnt -An bhfuil tú cinnte go dteastaíonn uait an comhad a roinnt i {0} imleabhair? -Ní mór do mhéid an imleabhair a bheith níos lú ná méid an chomhaid bhunaidh -Tá méid an cholúin mícheart -Méid an cholúin sonraithe: {0} bearta.\nAn bhfuil tú cinnte gur mian leat an chartlann a roinnt in imleabhair? -7400 -Cumaisc comhaid -&Cumaisc go: -Ag cumasc... -Ná roghnaigh an chéad chomhad -Ní féidir an comhad a bhraith mar chuid de chomhad scoilte -Ní féidir níos mó ná aon chuid amháin den chomhad scoilte a aimsiú -7500 -Ag ríomh na suime seiceála... -Faisnéis maidir leis an suim sheiceála -Suim sheiceála do shonraí: -Suim sheiceála do shonraí agus d'ainmneacha -7600 -Tástáil fheidhmíochta -Gnáthaíocht na cuimhne: -Ag comhbhrú -Ag díchomhbhrú -Measúnú -Measúnú iomlán -Reatha -Toradh -Gnáthaíocht an LAP -Measúnú / Gnáthaíocht -Bealaí: diff -Nru p7zip-rar-16.02/GUI/Lang/gl.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/gl.txt --- p7zip-rar-16.02/GUI/Lang/gl.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/gl.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.12 : Xosé Calvo -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Galician -Galego -401 -Dacordo -Cancelar - - - -&Si -&Non -&Fechar -Axuda - -&Continuar -440 -Si a &Todo -Non a T&odo -Parar -Reiniciar -&Fondo -&Letras -&Pausa -Parado -Ten a certeza de que quer cancelar? -500 -&Ficheiro -&Modificar -&Ver -F&avoritos -&Ferramentas -&Axuda -540 -&Abrir -Abrir &Dentro -Abrir &Fora -&Ver -&Modificar -Reno&mear -&Copiar Para... -&Mover Para... -&Eliminar - - -&Propriedades -Come&ntario - - -Crear Cartafol -Crear Ficheiro -Sa&ir -600 -Seleccionar &Todo -De-seleccionar Todo -&Inverter a Selección -Seleccionar... -De-seleccionar... -Seleccionar por Tipo -De-select por Tipo -700 -Icones &Grandes -Icones &Pequenos -&Lista -&Detalles -730 -Sen Orde - -&Dous Paineis -&Barras de Ferramentas -Abrir o Cartafol Raíz -Subir un Nível -Histórico de Cartafois... -&Refrescar -750 -Barra de Ferramentas de arquivos -Barra de Ferramentas normal -Botóns grandes -Mostrar o Texto dos Botóns -800 -&Adicionar o cartafol aos Favoritos como -Marcador -900 -&Opcións... -&Análise -960 -&Contido... -&Acerca do 7-Zip... -1003 -Camiño -Nome -Extensión -Cartafol -Tamaño -Tamaño comprimido -Atributos -Creado -Último acceso -Modificado -Sólido -Comentado -Encriptado -Partir Antes -Partir Depois -Dicionario -CRC -Tipo -Anti -Método -OS do Servidor -Sistema de Ficheiros -Usario -Grupo -Bloco -Comentario - - - - - - - - - - - - - - - - - - - - - - - - - - -Erro -Tamaño total -Tamaño disponíbel -Tamaño co cluster -Etiqueta -Nome local -Fornecedor -2100 -Opciós -Idioma -Idioma: -Editor -&Editor: - -2200 -Sistema -Asociar 7-Zip con: -2301 -Integratar 7-Zip no menú de contexto -Menú de contexto en cascata -Elementos do Menú de contexto: -2320 - - -Abrir arquivo -Extrair ficheiros... -Adicionar ao arquivo... -Comprobar arquivo -Extrair Aquí -Extrair para {0} -Adicionar a {0} -Comprimir e enviar por correo... -Comprimir a {0} e enviar por correo -2400 -Cartafois -&cartafol de traballo -Cartafol &temporario do sistema -Cartafol a&ctual -&Especificar: -Usar só discos removíveis -Especificar unha localización para os ficheiros de arquivo temporarios. -2500 -Axustes -Mostrar o elemento ".." -Mostrar os icones reais dos ficheiros -Mostrar o menú do sistema - - - - - -2900 -Sobre o 7-Zip -7-Zip é un programa gratuito. Contodo, pode contribuir co seu desenvolvimento rexistrándose. Se se rexistrar, terá direito a receber apoio técnico. -3000 - -Non se produciron erross -{0} obxecto(s) seleccionados -Non é posíbel crear o cartafol '{0}' -Este tipo de arquivo non permite actualizacións. - - - - -Modificouse o Ficheiro '{0}'.\nQuéreo actualizar no arquivo? -Non é posíbel actualizar o ficheiro\n'{0}' -Non se pode iniciar o editor. - - - - -Demasiados elementos -3300 -Extraindo -Comprimir -Proba -Abrindo... - -3400 -Extrair -E&xtrair para: -Especificar unha localización de destino para os ficheiros extraídos. -3410 -Modo nome de cartafol -Camiños completos -Sen camiños -3420 -Modo sobreposición -Con confirmación -Sen confirmación -Manter os ficheiros existentes -Renomear automaticamente - -3500 -Confirmar a Substitución dos Ficheiros -O cartafol de destino xa contén un ficheiro co mesmo nome. -Desexa substituir o ficheiro co mesmo nome -por este? -{0} bytes -Renomear &automaticamente -3700 -Método de compresión non válido para '{0}'. -Erro de datos en '{0}'. O ficheiro está mal. -CRC fallou en '{0}'. O ficheiro está mal. - - -3800 -Introduza o contrasinal -Introduza o contrasinal: - -&Mostrar o contrasinal - - - -Contrasinal -3900 -Tempo pasado: -Tempo restante: -Tamaño: -Velocidade: - - -Erros: - -4000 -Adicionar ao arquivo -&Arquivo: -&Modo de actualización: -&Format do arquivo: -&Nível de compresión: -&Tipo de compresión: -Tamaño do &dicionario: -Tamaño das &palabras: - - -&Parámetros: -Opcións -Crear un arquivo SF&X - - - -Encriptar os &nomes dos ficheiros -Uso da memoria para a Compresión: -Uso da memoria para a Decompresión: -4050 -Sen compresión -Máis rápida -Rápida -Normal -Máxima -Ultra -4060 -Adicionar e substituir os ficheiros -Actualizar e adicionar os ficheiros -Só actualizar os ficheiros existentes -Sincronizar os ficheiros -4070 -Ver -Todos os ficheiros - - -6000 -Copiar -Mover -Copiar para: -Mover para: -A copiar... -a mover... -A renomear... - -Non é posíbel efectuar esta operación. -Erro ao Renomear Ficheiro ou Cartafol - - -6100 -Confirmar Eliminar Ficheiro -Confirmar Eliminar Cartafol -Confirmar Eliminar Múltiplos Ficheiros -Ten a certeza de que desexa eliminar '{0}'? -Ten a certeza de que desexa eliminar o cartafol '{0}' e todo o seu contido? -Ten a certeza de que desexa eliminar estes {0} elementos? -A eliminar... -Erro ao eliminar Ficheiro ou Cartafol - -6300 -Crear Cartafol -Crear Ficheiro -Nome do cartafol: -Nome do Ficheiro: -Novo Cartafol -Novo Ficheiro -Erro ao crear o Cartafol -Erro ao crear o Ficheiro -6400 -Comentario -&Comentario: -Seleccionar -De-seleccionar -Máscara: -6600 - -Histórico dos Cartafois -mensaxes de diagnóstico -Mensaxe -7100 -Computador -Rede - -Sistema -7200 -Adicionar -Extrair -Probar -Copiar -Mover -Eliminar -Información -7300 - - -Partir en &volumes, bytes: - - - - - - -7400 - - - - - - -7500 - - - - -7600 -Análise -Uso da memoria: -Compresión -Decompresión -Relación -Relación total -Actual -Resultante - - -Pases: diff -Nru p7zip-rar-16.02/GUI/Lang/gu.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/gu.txt --- p7zip-rar-16.02/GUI/Lang/gu.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/gu.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Vinayy Sharrma : વિનય શર્મા દ્વારા અનુવાદિત મેહનત કરેલી છે તો પોતાનું નામ લખવામાં કાંઇ બુરાઈ નથી. હિન્દ પર ગર્વ કરો, જય હિન્દ ! જય હિન્દી ! જય ગરવી ગુજરાત ! જય ગુજરાતી -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Gujarati, Indian, હિન્દુસ્તાન -ગુજરાતી -401 -સારું -રદ્દ - - - -&હાઁ -&ના -&બંદ કરો -મદદ - -&જારી રાખો -440 -&બધા માટે હાઁ -&બધા માટે ના -રૂકો -પુનઃ શુરુ કરો -&પૄષ્ઠ્ભૂમિ -&અગ્રભૂમિ(ડેસ્ક્ટોપ) -&વિશ્રામ -થોભેલું -તુમે રદ્દ કરવા ચાહો છો. શું તમને યકીન છે? -500 -&ફ઼ાઇલ -&સંપાદન -&દર્શન -&મનપસંદ -&ઔજાર -&મદદ -540 -&ખોલો -&અંદર ખોલો -&બાહર ખોલો -&દૃશ્ય -&સંપાદન -&પુન: નામકરણ -&માં નકલ બનાવો... -&માં લઇ જાઓ... -&મિટાવો -&ફ઼ાઇલનો વિભાજન કરો... -&ફ઼ાઇલનો સંયોજન કરો... -&સંપત્તિયાઁ યા ગુણ -&ટિપ્પણી -&જાઁચ યોગની ગણના કરો -&અન્તર -&ફ઼ોલ્ડર તૈયાર કરો -&ફ઼ાઇલ તૈયાર કરો -&નિર્ગમન -600 -&બધા ચયન કરો -&બધા અચયનિત કરો -&ચયન ઊંધું કરો -ચયન કરો... -અચયન કરો... -પ્રકાર દ્વારા ચયન -પ્રકાર દ્વારા અચયન -700 -મોટાં પ્રતીક -લઘુ પ્રતીક -&સૂચી -&વર્ણન -730 -અવિતરિત -ચૌડ઼ા દૃશ્ય -&૨ ફ઼લક -&ઔજાર પટ્ટીઓ -મૂલ ફ઼ોલ્ડર ખોલો -એક સ્તર ઊપર ચઢ઼ો -ફ઼ોલ્ડરો નો ઇતિહાસ... -&તાજા કરો -750 -સંગ્રહ ઔજાર પટ્ટી -માનક ઔજાર પટ્ટી -મોટા ખટકા(બટન) -ખટકા(બટન)ના શબ્દ દિખાવો -800 -&ફ઼ોલ્ડર મનપસંદમાં એવી રીતે જોડો... -પુસ્તચિન્હ -900 -&વિકલ્પ... -&બેઞ્ચમાર્ક(પ્રામાણિક તુલના) -960 -&સામગ્રી... -૭-જિપ ના વિશેમાં... -1003 -માર્ગ -નામ -વિસ્તાર -ફ઼ોલ્ડર -આકાર -કુલ આકાર -વિશેષતા યા ગુણધર્મ -સર્જિત -ચલાવેલી -પરિવર્ધિત -ઠોસ -ટિપ્પણી -ગુપ્તિકૃત -ના પૂર્વે વિભાજન(ટુકડે) કરો -ના બાદ વિભાજન(ટુકડે) કરો -શબ્દકોશ -સીઆરસી -પ્રકાર -વિરોધી -પદ્ધતિ -યજમાન આજ્ઞાવલી(ઓપરેટિંગ સિસ્ટમ) -ફ઼ાઇલ પ્રણાલી -પ્રયોગકર્તા -સમૂહ -રોક કે ટુકડાઓ -પ્રતિક્રિયા -સ્થાન -માર્ગ પ્રત્યય -ફોલ્ડરસ -ફાઇલ્સ -સંસ્કરણ -જત્થા -અનેક જત્થાઓ -ઓફસેટ -કડિયાઁ -ટુકડ઼ે -જત્થે - -૬૪-બિટ -મોટું-એન્ડિયન -સીપીયૂ -ભૌતિક આકાર -શીર્ષકોંના આકાર -જાઁચયોગ -ચરિત્રતાઓ -આભાસી પત્તો -આઈડી -સંક્ષિપ્ત નામ -સર્જક અનુપ્રયોગ -સેક્ટરનો આકાર -સ્થિતિ -કડ઼ી -ત્રુટિ -કુલ આકાર -સ્વતન્ત્ર રિક્તસ્થાન(ખાલી જગહ) -ક્લસ્ટર(સમૂહ) આકાર -ધ્યાનાકર્ષક(લેબલ) -સ્થાનિક નામ -પ્રદાયક -2100 -વિકલ્પ -ભાષા -ભાષા: -સંપાદક -&સંપાદક: -&અન્તર: -2200 -પ્રણાલી કે તંત્ર -સંબધિત કરો ૭-જિપ ના સાથે: -2301 -૭-જિપ ના શેલ (કવચ) પ્રસંગ મેનુ માં જોડો -સોપાનીકૃત(કેસ્કેડેડ) પ્રસંગ મેનુ -પ્રસંગ(કોન્ટેક્સ્ટ) મેનુ વસ્તુએઁ: -2320 -<ફોલ્ડર> -<સંગ્રહ(આર્ચિવ)> -સંગ્રહ ખોલો -ફ઼ાઇલ્સ બાહર કાઢો... -સંગ્રહમાં જોડો... -સંગ્રહની જાઁચ કરો -અહિયાં બાહર કાઢો -{0} માં બાહર કાઢો -{0} માં જોડો -દબાવો(સંકુચન) અને ઇમેલ કરો... -{0} માં દબાવો અને ઈમેલ કરો -2400 -ફોલ્ડર્સ -&કાર્યરત ફોલ્ડર -&પ્રણાલીનું અસ્થાયી(ટેમ્પરરી) ફોલ્ડર -&ચાલુ -&નિર્દિષ્ટ: -ફક્ત હટાવવા યોગ્ય(રિમૂવેબલ) ડ્રાઈવ માટે જ પ્રયોગ કરો -અસ્થાયી સંગ્રહ ફાઇલ માટે સ્થાન નિર્દિષ્ટ કરો(બતાવો). -2500 -વ્યવસ્થાઓ -દિખાવો ".."વસ્તુ -વાસ્તવિક ફ઼ાઇલ પ્રતીક બતાવો -તંત્ર નો મેનુ બતાવો -&આખી પન્ક્તિનું ચયન -&ગ્રિડ(જાલ) રેખા દિખાવો -વસ્તુ ખોલવા માટે એક જ(સિંગલ)-ક્લિક -&વૈકલ્પિક ચયન સ્થિતિ -&મોટા સ્મૃતિ પૃષ્ઠનો પ્રયોગ કરો -2900 -7-જિપ ના વિશે -7-જિપ એ નિઃશુલ્ક સૉફ઼્ટવેયર છે. તો પણ, આપ પંજીકૃત(રજિસ્ટર્ડ) થઈને ૭-જ઼િપ ના વિકાસમાં સહયોગ કરી શકો છો. -3000 -તંત્ર જરૂરી માત્રામાં મેમોરી(સ્મૃતિ) વિતરિત નથી કરી શકતું -આમાં કોઈ પણ ત્રુટિ નથી -{0} ચયનિત વસ્તુ(ઓ) -'{0}' ફ઼ોલ્ડર સર્જિત નથી કરી શકતું -આ સંગ્રહ માટે અદ્યતનીકૃત સંચાલન સમર્થિત નથી. -'{0}' ફાઇલને સંગ્રહનાં રૂપમાં નથી ખોલી શકતું -'{0}' ગુપ્તિકૃત સંગ્રહને નથી ખોલી શકતુ. ગલત કૂટશબ્દ? -અસમર્થિત સંગ્રહ પ્રકાર -ફાઇલ {0} પહેલાથી હયાત છે -'{0}' ફ઼ાઇલ પરિવર્ધિત થઈ છે.\nશું તમે સંગ્રહમાં આને અદ્યતનીકૃત કરવા માગો છો? -ફ઼ાઇલ ને અદ્યતનીકૃત નથી કરી શકતું\n'{0}' -સંપાદકને શરૂ નથી કરી શકતું. -આ ફાઇલ એક વિષાણુ(વાયરસ) જેવી લાગે છે (ફાઇલ નામ લાંબી ખાલી જગહ નામમાં રાખતો છે). -જે ફોલ્ડરનો લાંબો માર્ગ છે તેનાથી સઞ્ચાલન ક્રિયા બોલાવી નથી શકાતી. -તમારે એક ફાઇલનો ચયન તો કરવો જ પડશે -તમારે એક કે જ્યાદા ફાઇલોંનો ચયન તો કરવો જ પડશે -બહુ વધારે વસ્તુઓ -3300 -બાહર કાઢી રહ્યું છે -સંકુચન કરી રહ્યું છે -પરીક્ષણ -ખોલી રહ્યુ છે... -તલાશી(સ્કૈનિંગ) કરી રહ્યુ છે... -3400 -બાહર કાઢો -&બાહર કાઢો: -બાહર કાઢેલી ફ઼ાઇલોં માટે સ્થાન નિર્દિષ્ટ કરો. -3410 -માર્ગ સ્થિતિ -આખો માર્ગનામ -કોઈ માર્ગ નામ નથી -3420 -અધિલેખન રીત -અધિલેખન કરતાં પહલાં પૂછો -વગર પૂછે અધિલેખન(જુનું મટાવવું) કરો -પહેલાથી હયાત ફ઼ાઇલસને છોડો -સ્વચાલિત પુન: નામકરણ -પહેલાથી હયાત ફ઼ાઇલસનો સ્વચાલિત(ઓટોમેટિક) પુન: નામકરણ કરો -3500 -ફ઼ાઇલ પ્રતિસ્થાપન ને પાક્કુ કરો -ગન્તવ્ય ફોલ્ડરમાં પહેલાથી જ પ્રક્રિયા થએલી ફ઼ાઇલ છે. -શું આપ પહેલાથી હયાત ફ઼ાઇલ ને બદલવું પસંદ કરશો? -આની જોડે? -{0} બાઇટ્સ -સ્વચાલિત પુન: નામકરણ -3700 -'{0}' ના માટે અસહાયક દબાવાવાની પદ્ધતિ. -ડેટા ત્રુટિ’{0}' માં. ફ઼ાઇલ તૂટેલી છે. -'{0}' માં સીઆરસી અસફલ. ફ઼ાઇલ તૂટેલી છે. -'{0}' ગુપ્તિકૃત(એનક્રિપ્ટેડ) ફાઇલ માં ડેટા ત્રુટિ. ગલત કૂટશબ્દ? -'{0}' ગુપ્તિકૃત(એનક્રિપ્ટેડ) ફાઇલ માં સીઆરસી અસફલ. ગલત કૂટશબ્દ? -3800 -કૂટશબ્દ(પાસવર્ડ) ડાલે -કૂટશબ્દ(પાસવર્ડ) ડાલે: -કૂટશબ્દ પુનઃ નાખો: -&કૂટશબ્દ(પાસવર્ડ) દિખાવો -કૂટશબ્દ સહેજેલાંથી જુદૂં છે -કૂટશબ્દ માટે ફક્ત ઇંગ્લિશ વર્ણમાલા, અંકો અને વિશેષ અક્ષરોં (!, #, $, ...) નો જ ઉપયોગ કરો -કૂટશબ્દ ખૂબ જ મોટું છે -કૂટશબ્દ(પાસવર્ડ) -3900 -વ્યતીત સમય: -શેષ બચેલું સમય: -કુલ આકાર: -ગતિ: -પ્રક્રિયા કરેલું: -દબાવાનું(આકાર છોટા કરવાનું)અનુપાત: -ત્રુટિયાઁ: -સંગ્રહ: -4000 -સંગ્રહમાં જોડો -&સંગ્રહ: -&અદ્યતનીકરણ સ્થિતિ(મોડ): -સંગ્રહ &ઢાઁચા: -&સંકુચન સ્તર: -&સંકુચન વિધિ: -&શબ્દકોશ આકાર: -&શબ્દ આકાર: -ઠોસ ટુકડાનો આકાર: -સીપીયૂ સૂત્ર સંખ્યા: -&પરિમાપ: -વિકલ્પ -&એસએફ઼એક્સ(SFX) સંગ્રહ તૈયાર કરો -સાઝી ફાઇલો સંકુચિત કરો -ગુપ્તિકરણ -ગુપ્તિકરણ પદ્ધતિ: -ફ઼ાઇલ &નામ ગુપ્તિકરણ કરો -સંકુચન માટે સ્મૃતિ પ્રયોગ: -પ્રસારણ માટે સ્મૃતિ પ્રયોગ: -4050 -ભંડારણ -સર્વાધિક તેજ -તેજ -સાધારણ -અધિકતમ -અત્યન્ત -4060 -ફ઼ાઇલેં જોડો અને પ્રતિસ્થાપિત કરો -ફાઇલો અદ્યતનીકૃત કરો અને જોડો -અવસ્થિત ફાઇલોં તાજા કરો -ફાઇલોં સમક્રમણ(સિંક્રોનાઈજ઼) કરો -4070 -બ્રાઉજ યા ઘૂમો -બધા ફાઇલોં -અ-ઠોસ -ઠોસ -6000 -નકલ -લઇ જાઓ -માં નકલ: -માં લઇ જાઓ: -નકલ... -લઇ જાઇ રહ્યુ છે... -પુનઃ નામકરણ... -ગન્તવ્ય ફોલ્ડર ચયનિત કરો. -આ ફોલ્ડર માટે આ સઞ્ચાલન ક્રિયા સમર્થિત નથી. -ફ઼ાઇલ કે ફ઼ોલ્ડરના પુનઃ નામકરણ માં ત્રુટિ -ફ઼ાઇલની નકલ કરવુ પાક્કું કરો -તમે સંગ્રહમાં ફાઇલ ની પ્રતિલિપિ કરવા ચાહો છો શું તમને યકીન છે -6100 -ફ઼ાઇલ મિટાવો આ પાક્કું કરો -ફ઼ોલ્ડર મિટાવો પાક્કું કરો -અનેક ફ઼ાઇલ મિટાવો પાક્કું કરો -શું તમને યકીન છે કે તમે મેટવવા ચાહો છો '{0}'? -શું તમને યકીન છે કે તમે ફ઼ોલ્ડર મિટાવવા માંગો છો ’{0}' અને આની બધી સામગ્રી પણ? -શું તમને યકીન છે કે તમે મિટાવવા માંગો છો આ {0} વસ્તુઓં ને? -મેટવી રહ્યુ છે... -ફ઼ાઇલ કિંવા ફ઼ોલ્ડર મિટાવામાં ત્રુટિ -તંત્ર લાંબા માર્ગ વાલી ફાઇલને પુનઃચક્રણ પેટી(રિસાઈકલ બિન)માં નથી લઇ જાઇ શકતુ. -6300 -ફ઼ોલ્ડર તૈયાર કરો -ફ઼ાઇલ તૈયાર કરો -ફ઼ોલ્ડર નામ: -ફ઼ાઇલ નામ: -નવુ ફ઼ોલ્ડર -નવી ફ઼ાઇલ -ફ઼ોલ્ડર તૈયાર કરવામાં ત્રુટિ -ફ઼ાઇલ તૈયાર કરવામાં ત્રુટિ -6400 -ટિપ્પણી -&ટિપ્પણી: -ચયન -ચયન રદ્દ -મુખૌટો: -6600 -ગુણ યા સંપત્તિયાઁ -ફ઼ોલ્ડરોંનો ઇતિહાસ -નિદાનાત્મક સંદેશ -સંદેશ -7100 -સંગણક -સઞ્જાલ -દસ્તાવેજ -પ્રણાલી -7200 -જોડો -બાહર કાઢો -પરીક્ષણ -નકલ -લઈ જાઓ -મિટાવો -સૂચના -7300 -ફ઼ાઇલનું વિભાજન કરો -&માં વિભાજન: -જત્થાઓમાં વિભાજન, બાઇટ્સ: -વિભાજન કરી રહ્યુ છે... -વિભાજન કરવાનું પાક્કું કરો -શું તમને યકીન છે કે તમે ફાઇલ ને {0} જત્થાઓમાં વિભાજિત કરવા માગો છો? -મૂલ ફાઇલના આકારની તુલનામાં જત્થાનું આકાર નાનો જ હોવો જોઇએ -જત્થાનો આકાર ખોટું છે -નિર્દેશિત જત્થા આકાર: {0} બાઇટસ.\n આપ સંગ્રહને એવા જત્થાઓમાં વિભાજિત કરવા ચાહો છો, શું તમને યકીન છે? -7400 -ફાઇલો સંયોજિત કરો -&માં સંયોજન કરો: -સંયોજન થઇ રહ્યુ છે... -વિભાજિત ફાઇલનો ફક્ત પ્રથમ ભાગ જ ચયનિત કરો -ફાઇલ ને વિભાજિત ફાઇલના ભાગના રૂપમાં ઓળખી નથી શકતુ -વિભાજિત ફાઇલના એક થી વધારે ભાગ શોધી નથી શકતુ -7500 -જાઁચયોગ(ચેકસમ)ની ગણના કરી રહ્યુ છે... -જાઁચયોગ(ચેકસમ) માહિતી -સીઆરસી જાઁચયોગ(ચેકસમ) આઁકડ઼ોં માટે : -સીઆરસી જાઁચયોગ(ચેકસમ) આઁકડ઼ોં અને નામોં માટે : -7600 -(કસૌટી ચિન્હ)બેઞ્ચમાર્ક -સ્મૃતિ ઉપયોગ: -સંકુચન કરી રહ્યું છે -પ્રસારણ કરી રહ્યું છે -ક્રમાંકન -કુલ ક્રમાંકન -વર્તમાન -પરિણામ -સીપીયૂ ઉપયોગ -ક્રમાંકન / ઉપયોગ -પાસ: diff -Nru p7zip-rar-16.02/GUI/Lang/he.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/he.txt --- p7zip-rar-16.02/GUI/Lang/he.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/he.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : peterg -; : Gal Brill -; 9.13 : 2010-04-30 : Jonathan Lahav -; -; -; -; -; -; -; -; -0 -7-Zip -Hebrew -עברית -401 -אישור -ביטול - - - -&כן -&לא -&סגור -עזרה - -ה&משך -440 -כן ל&הכל -ל&א להכל -עצור -התחל מחדש -&רקע -&קדמה -ה&שהה -מושהה -?האם את/ה בטוח/ה שברצונך לבטל -500 -&קובץ -&עריכה -&תצוגה -&מועדפים -&כלים -ע&זרה -540 -&פתח -פתח ב&תוכנה -פתח ב&חלון -&הצג -&ערוך -&שנה שם -...העתק ל& -...העבר ל& -&מחק -...פצל קובץ& -...מזג קבצים& -מ&אפיינים -הערה -חשב סיכום ביקורת -הבדל -צור תיקייה -צור קובץ -י&ציאה -600 -בח&ר הכל -בטל בחירה -ה&פוך בחירה -...בחר -...בטל בחירה -בחר לפי סוג -בטל בחירה לפי סוג -700 -סמלים &גדולים -סמלים &קטנים -&רשימה -&פרטים -730 -לא מסודר -תצוגה בפריסה מלאה -&שני חלונות -&סרגלי כלים -פתח תיקיית שורש -חזור שלב אחד -...היסטוריית תיקיות -ר&ענן -750 -סרגל ארכיון -סרגל רגיל -כפתורים גדולים -הצג את פעולת הכפתור מתחתיו -800 -&הוסף תיקייה למועדפים כ -סימנייה -900 -&...אפשרויות -&מבחן ביצועים -960 -&...תוכן -&...7-Zip אודות -1003 -נתיב -שם -סיומת -תיקייה -גודל -גודל מכווץ -תכונות -נוצר -נצפה -השתנה -רצוף -נרשמה הערה -הוצפן -פצל לפני -פצל אחרי -מילון -CRC -סוג -אנטי -שיטה -מערכת הפעלה -מערכת קבצים -משתמש -קבוצה -קטע -הערה -מיקום -תחילית נתיב -תיקיות -קבצים -גירסה -חלק -ריבוי חלקים -קיזוז -קישורים -קטעים -חלקים - -64ביט -אחסון בסדר חשיבות יורד -משאבי מערכת/מעבד -גודל פיזי -גודל כותרת עליונה -בדיקת סיכום -מאפיינים -כתובת וירטואלית -מס' זיהוי -שם קצר -תוכנה יוצרת -גודל סקטור -מצב -קישור -שגיאה -גודל כללי -שטח פנוי -גודל קלסטר/יחידת אחסון -תווית -שם מקומי -ספק -2100 -אפשרויות -Language / שפה -Language / שפה: -עורך -&עורך: -&הבדל: -2200 -מערכת -7-Zip שייך ל : -2301 -שלב את התוכנה בתפריט-ההקשר הכללי -תפריט מדורג -פריטי תפריט: -2320 -<תיקייה> -<ארכיון> -פתח ארכיון -...חלץ קבצים -...הוסף לארכיון -בדוק ארכיון -חלץ לכאן -{0} -חלץ ל -{0} -הוסף ל -כווץ ושלח בדואר אלקטרוני -כווץ ל- {0} ושלח בדואר אלקטרוני -2400 -תיקיות -&תיקיית עבודה -של המ&ערכת "Temp" תיקיית ה -&נוכחית -&בחר תיקייה: -השתמש בהגדרות אלו עבור כוננים ניידים בלבד -.בחר מיקום לקבצי ארכיון זמניים -2500 -הגדרות -".." הצג את הפריט -הצג סמלי קבצים אמיתיים -הצג את תפריט המערכת -בחר את כל ה&שורה -הצג קווי &טבלה -לחיצה אחת לפתיחת פריט -שיטת &בחירה חלופית -השתמש בקטעי זיכרון &גדולים יותר -2900 -7-Zip אודות -זו היא תוכנה חופשית. עם זאת, ביכולתך לתמוך בפיתוח התוכנה על ידי הרשמה -3000 -המערכת אינה יכולה להקצוות את כמות הזיכרון הדרושה -אין שגיאות -(נבחרו {0} פריט(ים -'{0}' אין אפשרות ליצור את התיקייה -.פעולות עדכון לא נתמכות עבור ארכיון זה -'לא היה ניתן לפתוח את הקובץ '{0}' כארכיון -'?לא היה ניתן לפתוח את הארכיון המקודד '{0}'. סיסמא שגוייה -סוג ארכיון אינו נתמך -הקובץ {0} כבר קיים -?האם ברצונך לעדכן אותו בארכיון\n.הקובץ '{0}' שונה -'{0}'\nאין אפשרות לעדכן את הקובץ -.אין אפשרות להפעיל את העורך -(ייתכן והקובץ היינו וירוס (ישנם רווחים גדולים בשם הקובץ -.הפעולה אינה יכולה להתבצע מתיקייה בעלת נתיב ארוך -הינך חייב/ת לבחור קובץ אחד -הינך חייב לבחור קובץ אחד או יותר -יותר מדי פריטים -3300 -מחלץ -מכווץ -בודק -...פותח -...סורק -3400 -חלץ -&חלץ ל: -.ציין יעד לחילוץ הקבצים -3410 -שיטת הנתיבים -נתיבים מלאים -ללא נתיבים -3420 -מצב שכתוב קבצים -שאל לפני שכתוב -שכתב בלי לשאול -דלג על קבצים קיימים -שינוי שם אוטומטי -שינוי שם אוטומטי לקבצים קיימים -3500 -אשר החלפת קובץ -.תיקיית היעד מכילה כבר קובץ בשם זה -האם ברצונך להחליף את הקובץ הקיים -?בקובץ הזה -{בתים: {0 -שינוי שם &אוטומטי -3700 -.'{0}' שיטת הדחיסה אינה נתמכת עבור -.שגיאת מידע ב '{0}'. הקובץ אינו תקין -.בדיקת סכום הנתונים נכשלה ב '{0}'. הקובץ אינו תקין -'?שגיאת נתון בקובץ המקודד '{0}'. סיסמא שגוייה -'?שגיאה בבדיקת סכום הנתונים בקובץ המקודד '{0}'. סיסמא שגוייה -3800 -הכנס סיסמא -הכנס סיסמא: -הכנס שנית את הסיסמא: -&הצג סיסמא -הסיסמאות אינן תואמות -(!, #, $, ...) ליצירת הסיסמא השתמש רק באותיות אנגליות, מספרים או תווים מיוחדים -הסיסמא ארוכה מידי -סיסמא -3900 -הזמן שעבר: -הזמן שנותר: -גודל כולל: -מהירות: -התקדמות: -יחס כיווץ: -שגיאות: -ארכיונים: -4000 -הוסף לארכיון -&ארכיון: -מצב &עדכון: -&פורמט הארכיון: -רמת &דחיסה: -&שיטת דחיסה: -גודל מי&לון: -גודל &מילה: -גודל קטע רצוף: -כמות הליכי מעבד/מערכת: -&פרמטרים: -אפשרויות -צור ארכיון &חילוץ-עצמי -דחוס קבצים שבשיתוף -הצפנה -שיטת הצפנה: -&קדד שמות קבצים -זיכרון הדרוש לדחיסה: -זיכרון הדרוש לחילוץ: -4050 -אחסון -הכי מהירה -מהירה -רגילה -מקסימאלית -אולטרה -4060 -הוסף והחלף קבצים -עדכן והוסף קבצים -רענן קבצים קיימים -סנכרן קבצים -4070 -עיון -כל הקבצים -לא רצוף -רצוף -6000 -העתק -העבר -העתק ל: -העבר ל: -...מעתיק -...מעביר -...משנה שם -בחר תיקיית יעד. -הפעולה אינה נתמכת עבור תיקייה זו -אירעה שגיאה בשינוי שם של קובץ או תיקייה -אשר העתקת קובץ -?האם את/ה בטוח/ה שברצונך להעתיק קבצים לארכיון -6100 -אשר מחיקת קובץ -אשר מחיקת תיקייה -אשר מחיקת מספר קבצים -?'{0}' האם את/ה בטוח/ה שברצונך למחוק את -?האם את/ה בטוח/ה שברצונך למחוק את התיקייה '{0}' ואת כל תוכנה -?האם את/ה בטוח/ה שברצונך למחוק את {0} הפריטים האלה -...מוחק -אירעה שגיאה במהלך מחיקת קובץ או תיקייה -המערכת אינה יכולה להעביר קובץ עם נתיב ארוך לפח המחזור -6300 -צור תיקייה -צור קובץ -שם התיקייה: -שם הקובץ: -תיקייה חדשה -קובץ חדש -שגיאה ביצירת תיקייה -שגיאה ביצירת קובץ -6400 -הערה -&הערה: -בחר -בטל בחירה -מיסוך: -6600 -מאפיינים -היסטוריית תיקיות -הודעות איבחון -הודעה -7100 -מחשב -רשת -מסמכים -מערכת -7200 -הוסף -חלץ -בדוק -העתק -העבר -מחק -מידע -7300 -פצל קובץ -&פצל ל: -פצל לחלקים, בתים: -...מפצל -אשר פיצול -? האם את/ה בטוח/ה שברצונך לפצל את הקובץ ל{0} חלקים -גודל החלק חייב להיות קטן יותר מהקובץ המקורי -גודל חלק שגוי -?האם את/ה בטוח/ה שברצונך לפצל את הארכיון לחלקים אלה\nגודל החלק המוגדר: {0} בתים -7400 -מזג קבצים -&מזג ל: -...מבצע מיזוג -בחר רק את החלק הראשון של הקובץ המפוצל -לא היה ניתן למצוא קובץ שהוא חלק מהקובץ המפוצל -לא ניתן למצוא יותר מחלק אחד של הקובץ המפוצל -7500 -...מחשב סיכום ביקורת -תוצאות סיכום ביקורת -עבור הנתונים CRC בדיקת סיכום ביקורת : -עבור הנתונים ושמות CRC בדיקת סיכום ביקורת : -7600 -מבחן ביצועים -זיכרון בשימוש: -מכווץ -מחלץ -קצב -סיכום הקצב -נוכחי -סופי -משאבי מערכת/מעבד -קצב / שימוש -הצלחות: diff -Nru p7zip-rar-16.02/GUI/Lang/hi.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/hi.txt --- p7zip-rar-16.02/GUI/Lang/hi.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/hi.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Vinayy Sharrma : अनुवाद विनय शर्मा मेहनत की है तो अपना नाम लिखने मे कोई बुराई तो है नही. हिन्दी पर गर्व करो, जय हिन्द ! जय हिन्दी ! -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Hindi, Indian, हिन्दुस्तान -हिन्दी -401 -ठीक है -रद्द - - - -&हाँ -&नहीं -&बंद करो -मदद - -&जारी रखे -440 -&सभी के लिये हाँ -&सभी के लिये नहीं -रूको -पुनः शुरु करें -&पॄष्ठ्भूमि -&अग्रभूमि(डेस्क्टोप) -&विश्राम -विश्रामित -तुम रद्द करना चाहते हो. तुम्हें यकीन है क्या? -500 -&फ़ाइल -&संपादन -&दर्शन -&मनपसंद -&औजार -&मदद -540 -&खोले -&अंदर खोले -&बाहर खोले -&दृश्य -&संपादन -&पुन: नामकरण -&में नकल बनाये... -&में ले जायें... -&मिटायें -&फ़ाइल का विभाजन करें... -&फ़ाइल का संयोजन करें... -&संपत्तियाँ या गुण -&टिप्पणी -&जाँच योग की गणना करें -&अन्तर -&फ़ोल्डर तैयार करें -&फ़ाइल तैयार करें -&निर्गमन -600 -&सभी चयन करे -&सभी अचयनित करें -&चयन उलटा करें -चयन करें... -अचयन करे... -प्रकार द्वारा चयन -प्रकार द्वारा अचयन -700 -बड़ी प्रतीक -लघु प्रतीक -&सूची -&वर्णन -730 -अवितरित -चौड़ा दृश्य -&२ फ़लक -&औजार पट्टीयाँ -मूल फ़ोल्डर खोले -एक स्तर ऊपर चढ़े -फ़ोल्डरो का इतिहास... -&ताजा करें -750 -संग्रह उपकरणपट्टी -मानक औजार पट्टी -बड़े खटके(बटन) -खटके(बटन) के शब्द दिखायें -800 -&फ़ोल्डर मनपसंद में ऎसे जोड़े... -पुस्तचिन्ह -900 -&विकल्प... -&बेञ्चमार्क(प्रामाणिक तुलना) -960 -&सामग्री... -7-जिप के बारे में... -1003 -मार्ग -नाम -विस्तार -फ़ोल्डर -आकार -कुल आकार -विशेषता या गुणधर्म -सर्जित -चलायी गई -परिवर्धित -ठोस -टिप्पणी -गुप्तिकृत -के पूर्व विभाजन(टुकडे) करें -के बाद विभाजन(टुकडे) करें -शब्दकोश -सीआरसी -प्रकार -विरोधी -पद्धति -यजमान आज्ञावली(ओपरेटिंग सिस्टम) -फ़ाइल प्रणाली -प्रयोगकर्ता -समूह -रोक या टुकड़े -प्रतिक्रिया -स्थान -मार्ग प्रत्यय -फोल्डर्स -फाइल्स -संस्करण -जत्था -अनेक जत्थे -ओफसेट -कडियाँ -टुकड़े -जत्थे - -64-बिट -बड़ा-एन्डियन -सीपीयू -भौतिक आकार -शीर्षकों के आकार -जाँचयोग -चरित्रताऎं -आभासी पता -आईडी -संक्षिप्त नाम -सर्जक अनुप्रयोग -सेक्टर का आकार -स्थिति -कड़ी -त्रुटि -कुल आकार -स्वतन्त्र रिक्तस्थान(खाली जगह) -क्लस्टर(समूह) आकार -ध्यानाकर्षक(लेबल) -स्थानिय नाम -प्रदायक -2100 -विकल्प -भाषा -भाषा: -संपादक -&संपादक: -&अन्तर: -2200 -प्रणाली या तंत्र -संबधित करें 7-जिप के साथ: -2301 -7-जिप के शेल (कवच) प्रसंग मेनु में जोडें -सोपानीकृत(केस्केडेड) प्रसंग मेनु -प्रसंग(कोन्टेक्स्ट) मेनु वस्तुएँ: -2320 -<फोल्डर> -<संग्रह(आर्चिव)> -संग्रह खोले -फ़ाइल्स बाहर निकाले... -संग्रह में जोड़े... -संग्रह की जाँच करे -यहीं बाहर निकाले -{0} में बाहर निकाले -{0} में जोड़े -दबायें(संकुचन) ओर इमेल करें... -{0} में दबायें ओर ईमेल करें -2400 -फ़ोल्डर्स -&कार्यरत फ़ोल्डर -&प्रणाली का अस्थायी(टेम्पररी) फोल्डर -&चालू -&निर्दिष्ट: -सिर्फ हटाने योग्य(रिमूवेबल) ड्राईव के लिये ही प्रयोग करें -अस्थायी संग्रह फाइल के लिये स्थान निर्दिष्ट करें(बतायें). -2500 -व्यवस्थाएँ -दिखाओ ".."वस्तु -वास्तविक फ़ाइल प्रतिमायें दिखाओ -तंत्र का मेनु दिखाओ -&पूरी पन्क्ति का चयन -&ग्रिड(जाल) रेखा दिखाओ -वस्तु खोलने के लिये एक ही(सिंगल)-क्लिक -&वैकल्पिक चयन स्थिति -&बड़े स्मृति पृष्ठ का प्रयोग करे -2900 -7-जिप के बारे में -7-जिप यह निःशुल्क सॉफ़्टवेयर है. फिर भी, आप पंजीकृत(रजिस्टर्ड) होकर७-ज़िप के विकास में सहयोग कर सकते हैं. -3000 -तंत्र जरूरी मात्रा में मेमोरी(स्मृति) वितरित नही कर सकता है -इनमे कोई भी त्रुटि नहीं है -{0} चयनित वस्तु(एँ) -'{0}' फ़ोल्डर सर्जित नहीं कर सकता -इस संग्रह के लिये अद्यतनीकृत संचालन समर्थित नहीं हैं. -'{0}' फाइल को संग्रह के रूप में नही खोल सकता -'{0}' गुप्तिकृत संग्रह को नही खोल सकता. गलत कूटशब्द? -असमर्थित संग्रह प्रकार -फाइल {0} पहले से मौजूद है -'{0}' फ़ाइल परिवर्धित हुई है.\nक्या तुम संग्रह में इसे अद्यतनीकृत करना चाहते हो? -फ़ाइल को अद्यतनीकृत नही कर सकता\n'{0}' -संपादक को शुरू नही कर सकता. -यह फाइल एक विषाणु(वायरस) जैसी लगती है(फाइल नाम लंबी खाली जगह नाम में रखता है). -जिस फोल्डर का लंबा मार्ग है उससे सञ्चालन क्रिया नही बुलाई जा सकती. -तुम्हे एक फाइल का चयन तो करना ही होगा -तुम्हे एक या ज्यादा फाइलों को चुनना ही होगा -बहुत ज्यादा वस्तुएँ -3300 -बाहर निकाल रहा है -संकुचन कर रहा है -परीक्षण -खोल रहा है... -तलाशी(स्कैनिंग) कर रहा है... -3400 -बाहर निकाले -&बाहर निकाले: -बाहर निकाली हुई फ़ाइलों के लिये स्थान निर्दिष्ट करें. -3410 -मार्ग स्थिति -पूरा मार्गनाम -कोई मार्ग नाम नहीं है -3420 -अधिलेखन रीत -अधिलेखन करने से पहले पूछे -बिना पूछे अधिलेखन(पुराने को मिटाना) करें -पहले से मौजूद फ़ाइलस को छोड़े -स्वचालित पुन: नामकरण -पहले से मौजूद फ़ाइलस का स्वचालित(ओटोमेटिक) पुन: नामकरण करे -3500 -फ़ाइल प्रतिस्थापन को पक्का करें -गन्तव्य फोल्डर में पहले से ही प्रक्रिया हुई फ़ाइल है. -क्या आप पहले से मौजूद फ़ाइल को बदलना पसंद करेंगे? -इसके साथ? -{0} बाइट्स -स्वचालित पुन: नामकरण -3700 -'{0}' के लिए असहायक दबाने की पद्धति. -डेटा त्रुटि'{0}' में. फ़ाइल टूटी हुई है. -'{0}' में सीआरसी असफल. फ़ाइल टूटी हुई है. -'{0}' गुप्तिकृत(एनक्रिप्टेड) फाइल में डेटा त्रुटि. गलत कूटशब्द? -'{0}'गुप्तिकृत(एनक्रिप्टेड) फाइल में सीआरसी असफल. गलत कूटशब्द? -3800 -कूटशब्द(पासवर्ड) डाले -कूटशब्द(पासवर्ड) डाले: -कूटशब्द पुनः डाले: -&कूटशब्द(पासवर्ड) दिखाओ -कूटशब्द सहेजे हुए से अलग है -कूटशब्द के लिये सिर्फ़ इंग्लिश वर्णमाला, अंको और विशेष अक्षरों (!, #, $, ...) का ही उपयोग करें -कूटशब्द बहुत ज्यादा बड़ा है -कूटशब्द(पासवर्ड) -3900 -व्यतीत समय: -बाकी बचा समय: -कुल आकार: -गति: -प्रक्रिया किया हुआ: -दबाने(आकार छोटा करने) का अनुपात: -त्रुटियाँ: -संग्रह: -4000 -संग्रह में जोड़े -&संग्रह: -&अद्यतनीकरण स्थिति(मोड): -संग्रह &ढाँचा: -&संकुचन स्तर: -&संकुचन विधि: -&शब्दकोश आकार: -&शब्द आकार: -ठोस टुकडे का आकार: -सीपीयू सूत्र संख्या: -&परिमाप: -विकल्प -&एसएफ़एक्स(SFX) संग्रह तैयार करें -साझी फाइलें संकुचित करें -गुप्तिकरण -गुप्तिकरण पद्धति: -फ़ाइल &नाम गुप्तिकरण करें -संकुचन के लिये स्मृति प्रयोग: -प्रसारण के लिये स्मृति प्रयोग: -4050 -भण्डारण -सर्वाधिक तेज -तेज -साधारण -अधिकतम -अत्यन्त -4060 -फ़ाइलें जोड़े और प्रतिस्थापित करे -फ़ाइले अद्यतनीकृत करें और जोड़े -अवस्थित फ़ाइलें ताजा करें -फाइलें समक्रमण(सिंक्रोनाईज़) करें -4070 -ब्राउज या घूमे -सभी फ़ाइलें -अ-ठोस -ठोस -6000 -नकल -ले जायें -में नकल: -में ले जायें: -नकल... -ले जा रहा है... -पुन: नामकरण... -गन्तव्य फोल्डर चयनित करें. -इस फोल्डर के लिये यह सञ्चालन क्रिया समर्थित नहीं है. -फ़ाइल या फ़ोल्डर के पुन: नामकरण में त्रुटि -फ़ाइल की नकल करना पक्का करो -तुम संग्रह में फाइल की प्रतिलिपि करना चाहते हो क्या तुम्हे यकीन है -6100 -फ़ाइल मिटाये यह पक्का करो -फ़ोल्डर मिटायें पक्का करो -अनेक फ़ाइल मिटायें पक्का करो -क्या तुम्हे यकीन है कि तुम मिटाना चाहते हो '{0}'? -क्या तुम्हे यकीन है कि तुम फ़ोल्डर मिटाना चाहते हो '{0}' और इसकी सब सामग्री भी? -क्या तुम्हे यकीन है कि तुम मिटाना चाहते हो इन {0} वस्तुओं को? -मिटा रहा है... -फ़ाइल किंवा फ़ोल्डर मिटाने में त्रुटि -तंत्र लंबे मार्ग वाली फाइल को पुनःचक्रण पेटी(रिसाईकल बिन) में नही ले जा सकता है. -6300 -फ़ॊल्डर तैयार करें -फ़ाइल तैयार करें -फ़ोल्डर नाम: -फ़ाइल नाम: -नया फ़ॊल्डर -नया फ़ाइल -फ़ोल्डर तैयार करने में त्रुटि -फ़ाइल तैयार करने में त्रुटि -6400 -टिप्पणी -&टिप्पणी: -चयन -चयन रद्द -मुखौटा: -6600 -गुण या संपत्तियाँ -फ़ोल्डरों का इतिहास -निदानात्मक संदेश -संदेश -7100 -संगणक -सञ्जाल -दस्तावेज -प्रणाली -7200 -जोड़े -बाहर निकाले -परीक्षण -नकल -ले जायें -मिटायें -सूचना -7300 -फ़ाइल का विभाजन करें -&में विभाजन: -जत्थों में विभाजन, बाइट्स: -विभाजन कर रहा है... -विभाजन करना पक्का करे -क्या तुम्हे यकीन है कि तुम फाइल को {0} जत्थों में विभाजित करना चाहते हो? -मूल फाइल के आकार की तुलना में जत्थे का आकार छोटा ही होना चाहिए -जत्थे का आकार गलत है -निर्देशित जत्था आकार: {0} बाइटस.\n आप संग्रह को ऎसे जत्थों में विभाजित करना चाहते है, क्या आपको यकीन है? -7400 -फ़ाइले संयोजित करें -&मेंसंयोजन करे: -संयोजन हो रहा है... -विभाजित फाइल का सिर्फ़ प्रथम भाग ही चयनित करे -फाइल को विभाजित फाइल के भाग के रूप में पहचान नही सकता -विभाजित फाइल का एक से ज्यादा भाग नही ढूँढ सकता -7500 -जाँचयोग(चेकसम) की गणना कर रहा है... -जाँचयोग(चेकसम) माहिती -सीआरसी जाँचयोग(चेकसम) आँकड़ों के लिये : -सीआरसी जाँचयोग(चेकसम) आँकड़ों और नामों के लिये : -7600 -(कसौटी चिन्ह)बेञ्चमार्क -स्मृति उपयोग: -संकुचन कर रहा है -प्रसारण हो रहा है -क्रमांकन -कुल क्रमांकन -वर्तमान -परिणाम -सीपीयू उपयोग -क्रमांकन / उपयोग -पास: diff -Nru p7zip-rar-16.02/GUI/Lang/hr.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/hr.txt --- p7zip-rar-16.02/GUI/Lang/hr.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/hr.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.12 : Alan Šimek -; 4.53 : Hasan Osmanagić -; 9.07 : -; 15.05 : 2015-06-15 : Stjepan Treger -; -; -; -; -; -; -; -0 -7-Zip -Croatian -Hrvatski -401 -U redu -Odustani - - - -&Da -&Ne -&Zatvori -Pomoć - -Nastavi -440 -Da za &Sve -Ne za Sv&e -&Stani -Ponovi -U pozadini -U prvom planu -&Pauza -Pauzirano -Poništiti? -500 -&Datoteke -&Uređivanje -&Izgled -Omiljene mape -&Alati -&Pomoć -540 -&Otvori -Ot&vori mapu -Otvori u &sustavu -Iz&gled -&Uređivanje -Prei&menuj -&Kopiraj u... -Premje&sti u... -O&briši -Podije&li datoteku... -Spo&ji datoteke... -Svojs&tva -Komentar -Izračun kontrolnog zbroja -Uspoređivanje -Stvo&ri mapu -Stvori &datoteku -&Izlaz -Poveznica -&Alternativni tokovi -600 -Odaberi &sve -Poništi odabir -&Obrni odabir -Odaberi... -Poništi odabir... -Odabir po tipu -Poništi odabir tipa -700 -&Velike ikone -&Male ikone -&Popis -&Detalji -730 -Neso&rtirano -Sadržaj mapa -&2 okna -Alatne &trake -&Korijen -&Nadmapa -Proš&le mape... -O&svježi -Automatski osvježi -750 -Alatna traka arhiva -Standardna alatna traka -Velike tipke -Prikaži tekst -800 -Dod&aj u popis omiljenih kao -Zabilješka -900 -&Mogućnosti... -M&jerenje -960 -&7-Zip pomoć... -&O programu... -1003 -Putanja -Prema nazivu -Tip -Mapa -Prema veličini -Sažeta veličina -Atributi -Kreirano -Pristupano -Prema mijenjanju -Zbijeno -Komentar -Enkripcija -Podjeli prije -Podjeli poslije -Rječnik - -Prema tipu -Anti -Način -Glavni OS -Sustav datoteka -Korisnik -Grupa -Zbijeno -Komentar -Pozicija -U datoteci -Mape -Datoteke -Inačica -Dio -Višedijelni -Razmak -Veza -Blokovi -Dijelova - -64-bitno -Big-endian -CPU -Fizička veličina -Veličina zaglavlja -Kontrolni zbroj -Karakteristike -Virtualna adresa -Jedinstvena oznaka -Kratko ime -Aplikacija stvaranja -Veličina sektora -Način -Poveznica -Greška -Ukupni kapacitet -Slobodni prostor -Veličina klastera -Naziv -Lokalni naziv -Pružatelj -NT sigurnost -Alternativni tok -Dodatno -Obrisano -Je stablo - - -Tip greške -Greške -Greške -Upozorenja -Upozorenje -Tokovi -Alternativni tokovi -Veličina alternativnih tokova -Virtualna veličina -Veličina raspakiranog -Ukupna fizička veličina -Indeks dijela -Podtip -Kratki komentar -Kodna stranica - - - -Veličina repa -Veličina ugrađenog odsječka -Poveznica -Čvrsta poveznica -iNode - -Samo za čitanje -2100 -Mogućnosti -Jezik -Jezik: -Uređivač -&Program za uređivanje: -Program za uspoređivanje: -2200 -Sustav -Poveži 7-Zip sa: -Svi korisnici -2301 -Integriraj 7-Zip u padajući kontekstni izbornik -Padajući kontekstni izbornik -Stavke kontekstnog izbornika: -Ikone kontekstnog izbornika -2320 - - -Otvori arhiv -Raspakiraj datoteke... -Dodaj u arhiv... -Testiraj arhiv -Raspakiraj ovdje -Raspakiraj u {0} -Dodaj u {0} -Sažimanje i slanje e-poštom -Sažimanje u {0} i slanje e-poštom -2400 -Mape -&Radna mapa -&Privremena sistemska mapa -&Trenutna -&Navedena: -Koristi samo za izmjenjive diskove -Lokaciju za smještaj privremenih datoteka. -2500 -Postavke -Nadmapa ".." -Prikaži prave ikone datoteka -Prikaži sistemski izbornik -&Označi cijeli redak -Prikaži &linije mreže -Jedan klik za otvaranje stavke -Drugi n&ačin označavanja -Koristi raspo&loživu memoriju -2900 -O 7-Zip-u -7-Zip je besplatan softver. -3000 -Sustav ne može pripremiti potrebnu količinu memorije -Nema grešaka -{0} objekt(a) izabrano -Ne mogu kreirati mapu '{0}' -Obnova nije podržana za ovaj arhiv. -Nemoguće otvoriti datoteku '{0}' kao arhiv -Nemoguće otvoriti kriptiranu arhivu '{0}'. Kriva lozinka? -Tip arhive nije podržan -Datoteka {0} već postoji -Datoteka '{0}' je izmijenjena.\nObnoviti arhiv? -Nije moguće obnoviti datoteku\n'{0}' -Nije moguće započeti uređivanje. -Datoteka izgleda kao virus (naziv datoteke sadrži dugačke razmake). -Operaciju nemoguće pozvati iz mape koja ima dugačku putanju. -Morate obilježiti jednu datoteku -Morate obilježiti jednu ili više datoteka -Previše stavki -Nemoguće otvoriti datoteku kao {0} arhivu -Datoteka je otvorena kao {0} arhiva -Arhiva je otvorena sa pomakom -3300 -Raspakiranje -Sažimanje u arhiv -Testiranje -Otvaranje u tijeku... -Skeniram... -Uklanjanje -3320 -Dodavanje -Ažuriranje -Analiziranje -Replikiranje -Repakiranje -Preskakanje -Brisanje -Stvaranje zaglavlja -3400 -Raspakiraj -&Raspakiraj u: -Lokacija za raspakiranje datoteka. -3410 -Putanja mapa: -Potpune putanje -Bez putanja -Apsolutne putanje -Relativne putanje -3420 -Natpiši postojeće -Pitaj prije natpisivanja postojećeg -Natpiši postojeće bez upozorenja -Preskoči postojeće datoteke -Automatska promjena naziva -Automatska promjena naziva postojećih datoteka -3430 -Eliminiraj dupliranje korijenske mape -Vrati sigurnost datoteka -3500 -Potvrdite zamjenu datoteka -Ciljana mapa već sadrži datoteku koja se trenutno obrađuje. -Zamijeniti postojeću -datoteku s ovom? -{0} bajte -A&utomatska promjena naziva -3700 -Nije podržan način sažimanja za '{0}'. -Podatkovna greška u '{0}'. Datoteka je neispravna. -CRC greška u '{0}'. Datoteka je neispravna. -Greška u kriptiranoj datoteci '{0}'. Kriva lozinka? -CRC greška u kriptiranoj datoteci '{0}'. Kriva lozinka? -3710 -Kriva lozinka? -3721 -Nepodržana metoda kompresije -Greška podataka -CRC neuspješan -Nedostupni podaci -Neočekivan kraj podataka -Postoji još podataka nakon glavnih podataka -Nije arhiva -Greška zaglavlja -Kriva lozinka -3763 -Neočekivan početak arhive -Nepotvrđen početak arhive - - - -Nepodržano svojstvo -3800 -Unesite lozinku -Unesite lozinku: -Ponovite lozinku: -&Prikaži lozinku -Lozinka nije jednaka -Koristite samo engleska slova, brojeve i specijalne znake (!, #, $, ...) za lozinku -Lozinka je preduga -&Lozinka -3900 -Utrošeno vrijeme: -Preostalo vrijeme: -Veličina: -Brzina: -Obrađeno: -Omjer kompresije: -Greške: -Arhive: -4000 -Dodaj u arhiv -&Arhiv: -&Način obnove: -&Format arhiva: -Stupanj sažimanja -&Metoda sažimanja: -Veličina &rječnika: -&Veličina riječi: -Veličina bloka u zbijenom: -Broj niti u CPU: -&Parametri: -&Mogućnosti -Kreiraj E&XE arhiv -Sažmi dijeljene datoteke -Kriptiranje -Metoda kriptiranja: -Enkripcija naziva datoteka -Korištenje memorije za sažimanje: -Korištenje memorije za raspakiranje: -Obriši datoteke nakon kompresije -4040 -Spremi simbolične poveznice -Spremi čvrste poveznice -Spremi alternativne tokove podataka -Spremi sigurnost datoteka -4050 -Bez sažimanja -Vrlo brzo -Brzo -Uobičajeno -Najjače -Ultra -4060 -Dodaj i zamjeni datoteke -Obnovi i dodaj datoteke -Osvježi postojeće datoteke -Sinkroniziraj datoteke -4070 -Traži -Sve datoteke -Bez-zbijanja -Zbijeno -6000 -Kopiraj -Premjesti -Kopiraj u: -Premjesti u: -Kopiranje u tijeku... -Premještanje u tijeku... -Preimenovanje u tijeku... -Odabir odredišne mape. -Operacija nije podržana. -Greška pri preimenovanju datoteke ili mape -Potvrdite kopiranje datoteka -Kopiranje datoteka u arhiv? -6100 -Potvrdite brisanje datoteke -Potvrdite brisanje mape -Potvrdite višestruko brisanje datoteka -Obrisati '{0}'? -Obrisati mapu '{0}' i sav njezin sadržaj? -Obrisati ove {0} podatke? -Brisanje u tijeku... -Greška pri brisanju datoteke ili mape -Sustav ne može premjestiti datoteku sa dugačkom putanjom u Kantu za recikliranje -6300 -Kreiraj mapu -Kreiraj datoteku -Naziv mape: -Naziv datoteke: -Nova mapa -Nova datoteka -Greška pri kreiranju mape -Greška pri kreiranju datoteka -6400 -Komentar -&Komentar: -Odaberi -Poništi odabir -Maska: -6600 -Svojstva -Kronologija mapa -Dijagnostičke poruke -Poruka -7100 -Računalo -Mreža -Dokumenti -Sustav -7200 -Dodaj -Raspakiraj -Testiraj -Kopiraj -Premjesti -Obriši -Svojstva -7300 -Podijeli datoteku -&Podijeli u: -Razdvajanje na dijelove, bajta: -Dioba... -Potvrdite diobu -Podijeliti datoteku u {0} dijelova? -Veličina diobenog dijela mora biti manja od izvorne datoteke -Netočna veličina bloka -Veličina bloka: {0} bajtova.\nJeste li sigurni da želite podijeliti u takve dijelove? -7400 -Spoji datoteke -&Spoji u: -Spajanje... -Označite samo prvu datoteku -Nije pronađena datoteka koja je dio razdijeljenih datoteka -Pronađena samo jedna datoteka od razdijeljenih datoteka -7500 -Izračunavanje kontrolnog zbroja... -Info kontrolni zbroj -CRC kontrolni zbroj za podatke: -CRC kontrolni zbroj za podatke i nazive: -7600 -Mjerenje -Korištenje memorije: -Sažimanje -Raspakiranje -Ocjena -Ukupna ocjena -Trenutno -Rezultat -CPU zauzeće -Ocjena / Zauzeće -Prolazi: -7700 -Poveznica -Poveznica -Veza od: -Veza do: -7710 -Tip poveznice -Čvrsta poveznica -Simbolična poveznica datoteka -Simbolična poveznica mapa -Mapa čvorišta diff -Nru p7zip-rar-16.02/GUI/Lang/hu.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/hu.txt --- p7zip-rar-16.02/GUI/Lang/hu.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/hu.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Jozsef Tamas Herczeg -; 9.16 : Nyilas MISY -; -; -; -; -; -; -; -; -; -0 -7-Zip -Hungarian -Magyar -401 -OK -Mégsem - - - -&Igen -&Nem -&Bezárás -Súgó - -&Folytatás -440 -I&gen, mindre -N&em, mindre -Leállítás -Újraindítás -&Háttérben -&Előtérben -&Szünet -Szünet -Biztos, hogy megszakítja a folyamatot? -500 -&Fájl -S&zerkesztés -&Nézet -Ked&vencek -&Eszközök -&Súgó -540 -M&egnyitás -Megnyitás &belül -Megnyitás kí&vül -&Nézet -S&zerkesztés -Átn&evezés -Más&olás mappába... -Át&helyezés mappába... -&Törlés -Fájl&darabolás... -Fájl&egyesítés... -T&ulajdonságok -&Megjegyzés -Checksum számolása -Különbség -Mappa létrehozása -Fájl létrehozása -&Kilépés -600 -Min&d kijelölése -Kijelölés megszüntetése -Kijelölés &megfordítása -Kijelölés... -Megszüntetés... -Kijelölés típus alapján -Megszüntetés típus alapján -700 -&Nagy ikonok -&Kis ikonok -&Lista -&Részletek -730 -Rendezetlen -Lapos ikonok -&2 panel -&Eszköztárak -Gyökérmappa megnyitása -Egy szinttel feljebb -Mappa előzmények... -&Frissítés -750 -Archiválás eszköztár -Szokásos eszköztár -Nagy gombok -Szövegcímkék megjelenítése -800 -Mappa &hozzáadása a Kedvencekhez mint -Könyvjelző -900 -&Beállítások... -&Teljesítménymérés -960 -&Tartalomjegyzék... -7-Zip &névjegye... -1003 -Útvonal -Név -Kiterjesztés -Mappa -Méret -Tömörített méret -Attribútumok -Létrehozva -Hozzáférés -Módosítva -Tömör -Megjegyzés -Titkosított -Feldarabolás előtt -Feldarabolás után -Szótár -CRC -Típus -Anti -Módszer -Gazda OS -Fájlrendszer -Felhasználó -Csoport -Blokk -Megjegyzés -Pozíció -Útvonal előtag -Mappák -Fájlok -Verzió -Kötet -Többkötet -Eltolás -Linkek -Blokkok -Kötetek - -64-bit -Big-endian -CPU -Fizikai méret -Fejlécek mérete -Checksum -Karakterisztika -Virtuális cím -ID -Név rendezése -Alkalmazás készítője -Szakasz mérete -Mód -Link -Hiba -Teljes méret -Szabad terület -Kluszterméret -Címke -Helyi név -Szolgáltató -2100 -Beállítások -Nyelv -Nyelv: -Szerkesztő -&Szerkesztő: -&Különbség: -2200 -Rendszer -7-Zip társítása: -2301 -7-Zip hozzáadása a parancsértelmező helyi menüjéhez -Lépcsőzetes helyi menü -Helyi menü elemek: -2320 - - -Archívum megnyitása -Fájlok kibontása... -Hozzáad az archívumhoz... -Archívum tesztelése -Kibontás ide -Kibontás ide: {0} -Hozzáadás: {0} -Tömörítés és küldés... -Tömörítés {0} archívumba és küldés -2400 -Mappák -&Munkamappa -A &rendszer ideiglenes mappája -&Jelenlegi -&Meghatározott: -Csak cserélhető meghajtókhoz -Válassza ki az ideiglenes archív fájlok mappáját. -2500 -Beállítások -A ".." elem látható -Az eredeti fájlikonok láthatók -Látható a rendszermenü -&Teljes soros kijelölés -&Rácsvonalak kijelzése -Elem megnyitása egyszeres kattintással -&Alternativ kiválasztási mód -&Nagy memória haszálata -2900 -A 7-Zip névjegye -A 7-Zip ingyenes szoftver. Ha elnyerte a tetszését, s mégis szeretné támogatni a további fejlesztését, regisztrálja 20 USD áron, fizethet hitelkártyával vagy más módon. -3000 -A rendszer nem tudja lefoglalni a szükséges memóriát -Az archívum hibamentes -{0} objektum kijelölve -A(z) '{0}' mappát nem lehet létrehozni -Az aktualizálás ennél az archívumtípusnál nem támogatott. -A(z) '{0}' fájl nem nyitható meg archívként -A(z) '{0}' titkosított archívum nem megnyitható. Hibás a jelszó? -Nem támogatott archívum típus -A(z) {0} fájl már létezik -'{0}'\nA fájl tartalma megváltozott.\nKívánja aktualizálni az archívumban? -A fájl nem aktualizálható:\n'{0}' -A szerkesztő nem indítható. -A fájl vírusnak néz ki (a fájlnév hosszú szóközt tartalmaz a nevében). -A művelet nem hívható meg abból a mappából amelynek hosszú az elérési útvonala. -Egy fájlt ki kell jelölnie! -Egy vagy több fájlt ki kell jelölnie -Túl sok elem -3300 -Kibontás -Tömörítés -Tesztelés -Megnyitás... -Vizsgálat... -3400 -Kibontás -&Kibontás ide: -Határozza meg a kibontott fájlok tárolómappáját. -3410 -Útvonal -Teljes útvonal -Nincs útvonal -3420 -Felülírás -Rákérdezés felülírás előtt -Felülírás rákérdezés nélkül -A létező fájlok kihagyása -Automatikus átnevezés -A létező fájlok automatikus átnevezése -3500 -Fájlcsere megerősítése -A célmappa már tartalmazza a feldolgozott fájlt. -Kívánja lecserélni a létező fájlt -ezzel a fájllal? -{0} bájt -A&utomatikus átnevezés -3700 -A(z) '{0}' tömörítési módja nem támogatott. -Adathiba a következőben: '{0}'. A fájl sérült. -CRC-hiba a következőben: '{0}'. A fájl sérült. -Adathiba a titkosított fájlban: '{0}'. Hibás a jelszó? -CRC-hiba a titkosított fájlban: '{0}'. Hibás a jelszó? -3800 -Jelszó beírása -Írja be a jelszót: -Jelszó újbóli beírása: -A &jelszó megjelenítése -Jelszavak nem egyeznek -Csak ékezetmentes karaktereket, számokat és speciális karaktereket (!, #, $, ...) használjon a jelszavaknak -A jelszó túl hosszú -Jelszó -3900 -Eltelt idő: -Hátralévő idő: -Méret: -Sebesség: -Feldolgozott: -Tömörítési arány: -Hibák: -Archívumok: -4000 -Behelyezés archívumba -&Archívum: -Akt&ualizálás módja: -Arcíhvum &formátuma: -Tömörítés &foka: -Tömörítés &módja: -&Címtár mérete: -&Szó mérete: -Tömör blokk méret: -CPU számok: -&Tulajdonságok: -Beállítások -SF&X archívum létrehozása -Megosztott fájlok tömörítése -Titkosítás -Titkosítási eljárás: -Fájlnevek &titkosítása -A tömörítés memóriahasználata: -A kitömörítés memóriahasználata: -4050 -Raktár -Leggyorsabb -Gyors -Normál -Legnagyobb -Ultra -4060 -Fájlok behelyezése és cseréje -Fájlok aktualizálása és behelyezése -Létező fájlok frissítése -Fájlok szinkronizálása -4070 -Tallózás -Minden fájl -Nem tömör -Tömör -6000 -Másolás -Áthelyezés -Másolás ide: -Áthelyezés ide: -Másolás... -Áthelyezés... -Átnevezés... -Válassza ki a cél mappát. -A művelet nem támogatott. -Hiba történt a fájl vagy a mappa átnevezésekor -Fájl másolásának megerősítése -Biztos, hogy fájl(oka)t akar másolni az archívumba? -6100 -Fájltörlés megerősítése -Mappatörlés megerősítése -Több fájltörlés megerősítése -Biztos, hogy törölni akarja a következőt: '{0}'? -Biztos, hogy törölni akarja a(z) '{0}' mappát és annak teljes tartalmát? -Biztos, hogy törölni akarja ezt a(z) {0} elemet? -Törlés... -Hiba történt a fájl vagy a mappa törlésekor -A rendszer nembírja mozgatni a fájlt a hosszú útvonallal a Lomtárba -6300 -Mappa létrehozása -Fájl létrehozása -Mappa neve: -Fájlnév: -Új mappa -Új fájl -Hiba történt a mappa létrehozásakor -Hiba történt a fájl létrehozásakor -6400 -Megjegyzés -&Megjegyzés: -Kijelölés -Megszüntetés -Maszk: -6600 -Tulajdonságok -Mappa előzmények -Diagnosztikai üzenetek -Üzenet -7100 -Sajátgép -Hálózati helyek -Dokumentumok -Rendszer -7200 -Hozzáadás -Kibontás -Teszt -Másolás -Áthelyezés -Törlés -Tulajdonságok -7300 -Fájldarabolás -&Darabolás ide: -Darabolás &kötetekre, bájt: -Darabolás... -Darabolás megerősítése -Biztos szét akarja darabolni a fájlt {0} kötetre? -Kötet méretének kissebbnek kell lennie, mint az eredeti fájl mérete -Hibás kötet méret -A megadott kötet mérete: {0} byte.\nBiztos fel akarja darabolni az archívumot ilyen kötetre? -7400 -Fájlegyesítés -&Egyesítés ide: -Egyesítés... -Csak az első rész kiválasztása a darabolt fájlból -Nem ismeri fel a fájlt, mint darabolt fájl része -Nem talál egynél több részt a darabolt fájlból -7500 -Leírás számolása... -Leírás információ -CRC leírás az adathoz: -CRC leírás az adathoz és névhez: -7600 -Teljesítménymérés -Memóriahasználat: -Tömörítés -Kitömörítés -Értékelés -Összértékelés -Jelenlegi -Eredmény -CPU használata -Becslés / Használat -Menetek: diff -Nru p7zip-rar-16.02/GUI/Lang/hy.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/hy.txt --- p7zip-rar-16.02/GUI/Lang/hy.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/hy.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,501 +0,0 @@ -;!@Lang2@!UTF-8! -; : Gevorg Papikyan -; 15.00 : Hrant Ohanyan : http://haysoft.org -; -; -; -; -; -; -; -; -; -0 -7-Zip -Armenian -Հայերեն -401 -ԼԱՎ -Չեղարկել - - - -&Այո -&Ոչ -&Փակել -Օգնություն - -&Շարունակել -440 -Այո բոլորի &համար -Ոչ բոլորի &համար -Կանգնեցնել -Վերսկսել -&Խորապատկերում -&Առջևում -&Դադար -Դադարի մեջ է -Ընդհատե՞լ -500 -&Ֆայլ -&Խմբագրել -&Տեսք -&Ընտրյալներ -Գ&ործիքներ -&Օգնություն -540 -&Բացել -Բացել &ներսում -Բացել դրս&ում -Ընտրել -&Խմբագրել -Վեր&անվանել -&Պատճենել... -&Տեղափոխել... -&Ջնջել -Տրոհել& ֆայլը... -Հ&ամակցել ֆայլը... -Հատկու&թյուններ -Մեկնաբա&նություններ -Հանրագումար -Համեմատել -&Ստեղծել թղթապանակ -Ստեղ&ծել ֆայլ -Փակ&ել -Հղում -&Այլընտրանքային հոսքեր -600 -Նշել &բոլորը -Ապանշել -&Ետարկել ն&շումը -Նշել... -Ապանշել... -Նշել ըստ տեսակի -Ապանշել ըստ տեսակի -700 -&Մեծ պատկերակներով -&Փոքր պատկերակներով -Ցուց&ակ -&Աղյուսակ -730 -Առանց դասավորելու -Հարթ եղանակ -&2 վահանակ -&Գործիքների վահանակ -Բացել արմատային թղթապանակը -Մեկ մակարդակ վերև -Թղթապանակների պատմությունը... -Թ&արմացնել -Ինքնաթարմացում -750 -Ծրագրի կոճակների վահանակ -Կոճակների ստանդարտ վահանակ -Մեծ կոճակներով -Կոճակների անունը -800 -Ավելացնել թղթապանակը &ընտրյալներին որպես -Էջանիշ -900 -Կարգավորումներ... -Արտադրողականության թեստ -960 -&Բովանդակություն... -Ծրագրի &մասին... -1003 -Ուղի -Անուն -Ընդլայնում -Թղթապանակ -Չափ -Սեղմած -Հատկություններ -Ստեղծվել է -Մուտք -Փոփոխվել է -Անընդհատ -Մեկնաբանություններ -Կոդավորված է -Տրոհված է մինչ -Տրոհված է հետո -Բառարան - -Տեսակ -Հակա -Մեթոդ -Համակարգ -Ֆայլային համակարգ -Օգտվող -Խումբ -Կողպում -Մեկնաբանություններ -Դիրք -Ուղի -Թղթապանակներ -Ֆայլեր -Տարբերակ -Հատոր -Բազմահատոր -Շեղում -Հղումներ -Հատվածներ -Հատորներ - - - -CPU -Ֆիզիկական չափը -Գլխագրերի չափը -Արդյունքը -Բնութագրություններ -Վիրտուալ հասցե - -Կարճ անուն -Ստեղծող -Հատվածի չափ -Եղանակ -Նշանային հղում -Սխալ -Ծավալ -Ազատ է -Կլաստերի չափ -Տառ -Տեղային անուն -Մատակարար -Անվտանգություն -Այլընտրանքային հոսք - -Հեռակա -Ծառ - - -Սխալի տեսակ -Սխալներ -Սխալներ -Զգուշացում -Զգուշացումներ -Հոսքեր -Այլընտրանքային հոսքեր -Այլընտրանքային հոսքերի չափ -Վիրտուալ չափը -Բացված չափը -Ընդհանուր ֆիզիկական չափը -Հատորի համարը -Ենթատեսակ -Կարճ մեկնաբանություն -Կոդային էջ - - - -Մնացորդի չափը -Ներկառուցված հատվածի չափը -Հղում -Կոշտ հղում -iNode - -Միայն կարդալու - - - - - - -2100 -Կարգավորումներ -Լեզուն -Լեզուն. -Խմբագիր -&Խմբագիր -&Համեմատելու ծրագիր. -2200 -Համակարգը -Ասոցիացնել 7-Zip-ը հետևյալ ֆայլերի հետ՝ -Բոլոր օգտվողները -2301 -Ներդնել 7-Zip-ը համատեքստային ցանկում -Կասկադային ցանկ -Համատեքստային ցանկի բաղադրիչները -Պատկերակներ համատեքստային ցանկում -2320 -«Թղթապանակ» -«Արխիվ» -Բացել արխիվը -Դուրս բերել -Ավելացնել արխիվի... -Թեստավորել -Դուրս բերել այստեղ -Դուրս բերել{0}-ում -Ավելացնել {0}-ին -Սեղմել և ուղարկել էլ. փոստով... -Սեղմել {0}-ում և ուղարկել էլ. փոստով -2400 -Թղթապանակներ -&Աշխատանքային թղթապանակ -&Համակարգային ժամանակավոր թղթապանակ -&Ընթացիկ -&Նշանակել. -Օգտագործել միայն շարժական կրիչների համար -Նշեք ժամանակավոր արխիվների համար տեղ -2500 -Կարգավորումներ -Ցուցադրել բաղադրիչը ".." -Ցուցադրել ֆայլերի իրական պատկերները -Ցուցադրել համակարգային ցանկը -Կուրսորը ամբողջ տողով -Ցուցադրել բաժանարարներ -Բացել մեկ սեղմամբ -Նշելու այլընտրանքային եղանակ -Օգտագործել հիշողության մեծ ծավալներ -2900 -7-Zip-ի մասին -7-Zip-ը ազատ տարածվող ծրագիր է: -3000 -Չկա ազատ տեղ -Սխալներ չկան -Ընտրված են {0} ֆայլեր -Հնարավոր չէ ստեղծել '{0}' թղթապանակը: -Փոփոխման գործողությունը այս արխիվը չի աջակցում: -Հնարավոր չէ բացել '{0}' ֆայլը որպես արխիվ -Հնարավոր չէ բացել '{0}' կողփած արխիվը: Մուտքագրեք գաղտնաբառը: -Արխիվի տեսակը չի աջակցվում -{0} ֆայլը արդեն գոյություն ունի -'{0}' ֆայլը փոփոխվել է:\n Թարմացնե՞լ այն արխիվում: -Հնարավոր չէ թարմացնել ֆայլը \n'{0}' -Հնարավոր չէ բացել խմբագիրը: -Ֆայլը նման է վիրուսի: -Գործողությունը չի կարող կատարվել այն թղթապանակից, որը ունի երկար ճանապարհ: -Ընտրեք գոնե մեկ ֆայլ -Ընտրեք գոնե մեկ կամ մի քանի ֆայլեր -Բաղադրիչները շատ են -Հնարավոր չեղավ բացել ֆայլը որպես {0} արխիվ -Ֆայլը բացվել է որպես {0} արխիվ -Ֆայլը բացվել է շեղումով -3300 -Դուրս է բերվում -Սեղմվում է -Թեստավորվում է -Բացվում է... -Տեսածրում... -Ջնջում -3320 -Ավելացվում է -Թարմացվում է -Վերլուծում -Պատճենվում է -Վերափաթեթավորում -Բաց է թողնվում -Ջնջում -Գլխագրերի ստեղծում -3400 -Դուրս բերել -&Դուրս բերել՝ -Նշեք հանվող ֆայլերի տեղադրությունը: -3410 -Ֆայլերի ուղին. -Ամբողջական& ուղիներ -&Առանց ուղիների -Բացարձակ ուղիներ -Հարաբերական ուղիներ -3420 -Վերագրանցում -Հաստատումով -Առանց հաստատման -Բաց թողնել -Վերանվանել -Վերանվանել գոյություն ունեցողները -3430 -Վերացնել արմատային թղթ. կրկնօրինակումը -Վերացնել մուտքի թույլտվությունը -3500 -Հաստատեք ֆայլի փոխարինումը -Թղթապանակում արդեն կա մշակված ֆայլ: -Փոխարինե՞լ առկա ֆայլը -տվյալ ֆայլով: -{0} բայթ -Վերանվանել ինք. -3700 -'{0}' ֆայլը սեղմելու եղանակը չի աջակցվում -Տվյալների սխալ'{0}'-ում: Ֆայլը վնասված է: -CRC սխալ'{0}'-ում: Ֆայլը վնասված է: -Սխալ՝ '{0}' ֆայլի կոդավորման տվյալներում: Գաղտնաբառը սխա՞լ է: -CRC սխալ '{0}' կոդավորված ֆայլի համար: Գաղտնաբառը սխա՞լ է: -3710 -Գաղտնաբառը սխա՞լ է -3721 -Սեղմելու չաջակցվող եղանակ -Սխալ տվյալներում -CRC սխալ -Անհասանելի տվյալներ -Տվյալների անսպասելի ավարտ -Կան տվյալներ՝ օգտակար տվյալների հատվածի վերջում -Արխիվ չէ -Սխալ գլխագրերում -Գաղտնաբառը սխալ է -3763 -Արխիվի անընդունելի սկիզբ -Արխիվի չհաստատված սկիզբ - - - -Չաջակցվող յուրահատկություն -3800 -Մուտքագրել գաղտնաբառ -&Մուտքագրել գաղտնաբառ. -Կրկնել գաղտնաբառը. -&Ցուցադրել գաղտնաբառը -Գաղտնաբառը չի համապատասխանում -Գաղտնաբառի համար օգտագործեք միայն լատիներեն տառեր, թվեր և հատուկ նշաններ (!, #, $, ...) -Գաղտնաբառը չափազանց երկար է -&Գաղտնաբառը. -3900 -Անցել է. -Մնացել է. -Չափ. -Արագություն. -Ընթացք. -Սեղմելու աստիճան -Սխալներ. -Արխիվներ. -4000 -Ավելացնել արխիվի -&Արխիվ. -&Փոփոխման կարգը. -&Արխիվի տեսակը. -&Սեղմելու աստիճանը. -&Սեղմելու մեթոդը. -Բառարանի &չափը. -Բառի չ&ափը. -Հատվածի չափը. -CPU հոսքերի քանակը. -&Ցուցիչներ. -&Ընտրանքներ -Ստեղծել SF&X արխիվ -Սեղմել համաօգտագործվող ֆայլերը -Կոդավորում -Կոդավորման եղանակ. -&Կոդավորել ֆայլերի անունները -Հիշող. ծավալը սեղմելու համար. -Հիշող. ծավալը դուրս բերելու համար. -Սեղմելուց հետո ջնջել ֆայլերը -4040 -Պահպանել նշանային հղումները -Պահպանել կոշտ հղումները -Պահպանել այլընտրանքային հոսքերը -Պահպանել մուտքի իրավունքը -4050 -Առանց սեղմելու -Արագընթաց -Արագ -Նորմալ -Առավելագույն -Ուլտրա -4060 -Ավելացնել և փոխարինել -Թարմացնել և ավելացնել -Թարմացնել -Համաժամեցնել -4070 -Թերթել -Բոլոր ֆայլերը -Ֆայլի չափով -Անդադար -6000 -Պատճենել -Տեղափոխել -Պատճենել՝ -Տեղափոխել՝ -Պատճենվում է... -Տեղափոխվում է... -Վերանվանվում է... -Ընտրել թղթապանակ -Գործողությունը չի աջակցվում -Սխալ` ֆայլը կամ թղթապանակը անվանափոխելիս: -Հաստատեք ֆայլերի պատճենումը -Պատճենե՞լ այս ֆայլերը արխիվի մեջ: -6100 -Հաստատել ֆայլի ջնջումը -Հաստատել թղթապանակի ջնջումը -Հաստատել ֆայլերի ջնջումը -Իրո՞ք ցանկանում եք ջնջել "{0}"-ը: -Իրո՞ք ցանկանում եք ջնջել "{0}" թղթապանակը և նրա պարունակությունը: -Իրո՞ք ցանկանում եք ջնջել ({0} հատ) ֆայլերը: -Ջնջում է... -Սխալ` ֆայլը կամ թղթապանակը ջնջելիս: -Հնարավոր չէ Աղբարկղ տեղափոխել երկար անուններով ֆայլեր: -6300 -Ստեղծել թղթապանակ -Ստեղծել ֆայլ -Թղթապանակի անունը. -Ֆայլի անունը. -Նոր թղթապանակ -Նոր ֆայլ -Սխալ` թղթապանակ ստեղծելիս -Սխալ` ֆայլ ստեղծելիս -6400 -Մեկնաբանություններ -&Մեկնաբանություններ -Նշել -Ապանշել -Դիմակ. -6600 -Հատկություններ -Թղթապանակների պատմությունը -Հաղորդագրություն -Հաղորդագրություն -7100 -Համակարգիչ -Ցանց -Փաստաթղթեր -Համակարգ -7200 -Ավելացնել -Դուրս բերել -Թեստավորել -Պատճենել -Տեղափոխել -Ջնջել -Տեղեկություն -7300 -Տրոհել ֆայլը -&Տրոհել՝ -Տրոհել &մասերի (բայթերով)` -Տրոհում... -Հաստատեք տրոհումը -Իրո˚ք տրոհել ֆայլը {0} հատորների -Հատորի չափը պետք է փոքր լինի ընթացիկ ֆայլի չափից -Գործողության սխալ -Հատորի նշված չափը. {0} բայթ:\nՏրոհե˚լ արխիվը հատորների: -7400 -Համակցել ֆայլը -&Համակցել. -Համակցում... -Ընտրել տրոհված ֆայլի միայն առաջին մասը -Հնարավոր չեղավ ճանաչել տրոհված ֆայլը -Հնարավոր չեղավ գտնել տրոհված ֆայլի մասերը -7500 -Checksum-ի որոշում... -Checksum -CRC checksum ֆայլերի համար. -CRC checksum ֆայլերի և անունների համար. -7600 -Արտադրողականության թեստ -Հիշողության ծավալը. -Սեղմել -Դուրս բերել -Վարկանիշ -Ընդհանուր վարկանիշը -Ընթացիկը -Ավարտուն արդյունքը -CPU-ի օգտ-ը -Վարկ./Օգտ. -Անցումներ. -7700 -Հղում -Կապել -Աղբյուր. -Նպատակ. -7710 -Հղման տեսակ -Կոշտ հղում -Նշանային հղում (ֆայլ) -Նշանային հղում (թղթապանակ) -Միացման կետ (Junction) diff -Nru p7zip-rar-16.02/GUI/Lang/id.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/id.txt --- p7zip-rar-16.02/GUI/Lang/id.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/id.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.14 : 02/01/2016 : Frans Liando -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Indonesian -Bahasa Indonesia -401 -Oke -Batal - - - -&Ya -&Tidak -&Tutup -Bantuan - -&Lanjut -440 -Ya untuk &semua -Tidak untuk s&emua -Henti -Mulai Ulang -Latar Bela&kang -Latar &Depan -&Jeda -Terjeda -Anda yakin ingin batal? -500 -&Berkas -&Edit -Tam&pilan -&Kesukaan -Pera&latan -Ban&tuan -540 -&Buka -Buka Sisi &Dalam -Buka Sisi L&uar -&Tampilkan -&Edit -&Nama Ulang -&Salin Ke... -P&indahkan Ke... -&Hapus -Be&lah Berkas... -Gabun&g Berkas... -P&roperti -K&omentari -Hitung ceksum -Beda -Buat Direktori -Buat Berkas -&Keluar -Tautan -Alternati&f Aliran -600 -Pi&lih Semua -Batal Pilih Semua -Pilih Sebal&iknya -Pilih... -Batal Pilih... -Pilih Berdasarkan Tipe -Batal Pilih Berdasarkan Tipe -700 -Ikon &Besar -Ikon &Kecil -&Daftar -&Rincian -730 -Tidak Berurutan -Tampilan Datar -&2 Panel -Bilah Ala&t -Buka Akar Direktori -Naik Satu Tingkat -Riwayat Direktori... -&Segarkan -Segarkan Otomatis -750 -Bilah Alat Arsip -Bilah Ala&t Standar -Tombol Besar -Perlihatkan Teks Tombol -800 -Tambah direktori ke Favorit sebagai -Markah -900 -&Pilihan... -&Tolok Ukur -960 -Petun&juk... -Mengen&ai 7-Zip... -1003 -Lintasan -Nama -Ekstensi -Direktori -Ukuran -Ukuran dipak -Atribut -Dibuat -Diakses -Dimodifikasi -Padat -Dikomentari -Dienkripsi -Belah Sebelum -Belah Setelah -Kamus - -Tipe -Anti -Metode -SO Host -Sistem Berkas -Pengguna -Grup -Blok -Komentar -Posisi -Awalan Lintasan -Direktori -Berkas -Versi -Volume -Multivolume -Gelinciran -Tautan -Blok -Volume - -64-bit -Big-endian -CPU -Ukuran Fisik -Ukuran Tajuk -Ceksum -Karakteristik -Alamat Maya -ID -Nama Singkat -Aplikasi Pembuat -Ukuran Sektor -Ragam -Tautan Simbolik -Kesalahan -Ukuran Total -Ruang Kosong -Ukuran Gugus -Label -Nama Lokal -Penyelenggara -Keamanan NT -Alternatif ALiran -Aux -Dihapus -Apakah Pohon - - -Tipe Kesalahan -Kesalahan -Kesalahan -Peringatan -Peringatan -Aliran -Alternatif Aliran -Ukuran Alternatif Aliran -Ukuran Maya -Ukuran Terbongkar -Jumlah Ukuran Fisik -Indeks Volume -SubTipe -Komentar Singkat -Laman Kode - - - -Ukuran Ujung -Ukuran Rintisan Tertanam -Tautan -Tautan Keras -iNode - -Hanya-baca -2100 -Pilihan -Bahasa -Bahasa: -Editor -&Editor: -Be&da: -2200 -Sistem -Asosiasikan 7-Zip dengan: -Semua pengguna -2301 -Integrasikan 7-Zip ke cangkang menu konteks -Menu konteks dikaskade -Butir-butir menu konteks: -Ikon-ikon di menu konteks -2320 - - -Buka arsip -Ekstrak berkas... -Tambah ke arsip... -Uji arsip -Ekstrak di sini -Ekstrak ke {0} -Tambah ke {0} -Mampat dan surat kawat... -Mampat ke {0} dan surat kawat -2400 -Direktori -&Direktori kerja -Direktori temporer &sistem -S&ekarang -&Ditentukan: -Hanya untuk kandar yang dapat dilepas -Tetapkan lokasi untuk berkas arsip sementara. -2500 -Pengaturan -Perlihatkan butir ".." -Perlihatkan ikon asli berkas -Perlihatkan menu sistem -&Memilih baris penuh -Perlihatkan &garis kisi-kisi -Klik-tunggal untuk membuka -Ragam pemilihan &alternatif -Gunakan halaman memori &besar -2900 -Mengenai 7-Zip -7-Zip merupakan perangkat lunak gratis.\n\nTerjemahan oleh Frans Liando. -3000 -Sistem tidak bisa mengalokasikan jumlah memori yang diperlukan -Tidak ada kesalahan -{0} objek terpilih -Tidak bisa membuat Direktori '{0}' -Operasi pembaruan tidaklah didukung untuk arsip ini. -Tidak bisa membuka berkas arsip '{0}' -Tidak bisa membuka arsip terenkripsi '{0}'. Salah kata sandi? -Tipe arsip tidak didukung -Berkas {0} telah ada -Berkas '{0}' telah termodifikasi.\nApakah Anda ingin perbarui berkas dalam arsip? -Tidak bisa perbarui berkas\n'{0}' -Tidak bisa memulai editor. -Berkas ini tampaknya seperti virus (pada nama berkas berisi spasi yang panjang). -Pengoperasian tidak bisa dipanggil dari direktori yang berlintasan panjang. -Anda harus pilih satu berkas -Anda harus pilih satu berkas atau lebih -Terlalu banyak butir -Tidak bisa buka berkas sebagai arsip {0} -Berkas dibuka sebagai arsip {0} -Berkas dibuka dengan gelinciran -3300 -Mengekstrak -Pemampatan -Pengujian -Membuka... -Memindai... -Memindah -3320 -Menambah -Memperbarui -Menganalisa -Mereplikasi -Pak ulang -Melewatkan -Menghapus -Membuat tajuk -3400 -Ekstrak -E&kstrak ke: -Tetapkan lokasi untuk berkas yang diekstrak. -3410 -Ragam lintasan: -Nama lengkap lintasan -Tidak ada nama lintasan -Nama lintasan absolut -Nama lintasan relatif -3420 -Ragam tulis timpa: -Konfirmasikan sebelum tulis timpa -Tulis timpa tanpa konfirmasi -Lewati berkas yang ada -Penamaan ulang automatis -Penamaan ulang automatis terhadap berkas yang ada -3430 -Hilangkan duplikasi direktori akar -Pulihkan keamanan berkas -3500 -Konfirmasi Penggantian Berkas -Direktori tujuan telah berisi berkas yang terproses. -Maukah Anda mengganti berkas yang ada -dengan yang satu ini? -{0} bita -Nama &Ulang Automatis -3700 -Metode mampat untuk '{0}' tidak didukung. -Kesalahan data di '{0}'. Berkas ini rusak. -CRC gagal di '{0}'. Berkas ini rusak. -Kesalahan data di berkas terenkripsi '{0}'. Salah kata sandi? -CRC gagal di berkas terenkripsi '{0}'. Salah kata sandi? -3710 -Salah kata sandi? -3721 -Metode mampat tidak didukung -Kesalahan data -CRC gagal -Data tidak tersedia -Akhir data tidak terduga -Terdapat suatu data setelah akhir muatan data -Bukan arsip -Kesalahan Tajuk -Salah kata sandi -3763 -Awal arsip belum tersedia -Awal arsip belum dikonfirmasi - - - -Fitur tidak didukung -3800 -Masukkan kata sandi -Masukkan kata sandi: -Konfirmasi kata sandi: -&Perlihatkan kata sandi -Kata sandi tidak cocok -Gunakanlah hanya huruf bahasa Indonesia, nomor dan karakter khusus (!, #, $, ...) untuk kata sandi -Kata sandi terlalu panjang -Kata sandi -3900 -Waktu terpakai: -Sisa waktu: -Jumlah ukuran: -Kecepatan: -Terproses: -Rasio mampat: -Kesalahan: -Arsip: -4000 -Tambah ke arsip -&Arsip: -Ragam perbar&u: -&Format arsip: -&Level mampat: -&Metode mampat: -Ukuran &kamus: -Ukuran ka&ta: -Ukuran blok padat: -Jumlah CPU: -&Parameter: -Pilihan -Buat arsip SF&X -Kompres berkas bersama -Enkripsi -Metode enkripsi: -Enkripsi &nama berkas -Pemakaian memori untuk Pemampatan: -Pemakaian memori untuk Pengawamampatan: -Hapus berkas setelah dimampatkan -4040 -Simpan tautan simbolik -Simpan tautan keras -Simpan alternatif aliran data -Simpan keamanan berkas -4050 -Simpan -Tercepat -Cepat -Normal -Maksimum -Ultra -4060 -Tambah dan ganti berkas -Perbarui dan tambah berkas -Segarkan ulang berkas yang ada -Sinkronisasikan berkas -4070 -Ramban -Semua Berkas -Non-padat -Padat -6000 -Salin -Pindah -Salin ke: -Pindah ke: -Menyalin... -Memindah... -Penamaan Ulang... -Pilih direktori tujuan. -Pengoperasian tidak didukung untuk direktori demikian. -Kesalahan Penamaan Ulang Berkas atau Direktori -Konfirmasi Salin Berkas -Anda yakin ingin menyalin berkas ke arsip? -6100 -Konfirmasi Hapus Berkas -Konfirmasi Hapus Direktori -Konfirmasi Hapus Berkas-berkas -Anda yakin ingin hapus '{0}'? -Anda yakin ingin hapus direktori '{0}' dan semua isinya? -Anda yakin ingin hapus {0} butir? -Menghapus... -Kesalahan Penghapusan Berkas atau Direktori -Sistem tidak bisa memindah suatu berkas yang berlintasan panjang ke Recycle Bin -6300 -Buat Direktori -Buat Berkas -Nama Direktori: -Nama berkas: -Direktori Baru -Berkas Baru -Kesalahan Membuat Direktori -Kesalahan Pembuatan Berkas -6400 -Komentar -&Komentari: -Pilih -Tidak Memilih -Masker: -6600 -Properti -Riwayat Direktori -Pesan Diagnosa -Pesan -7100 -Komputer -Jaringan -Dokumen -Sistem -7200 -Tambah -Ekstrak -Uji -Salin -Pindah -Hapus -Info -7300 -Belah Berkas -&Belah ke: -Belah ke &volume, bita: -Membelah... -Konfirmasi Membelah -Anda yakin ingin membelah berkas menjadi {0} volume? -Ukuran volume seharusnya lebih kecil dari pada ukuran asli berkas -Ukuran volume salah -Tentukan ukuran volume: {0} bita.\nAnda Yakin ingin membelah arsip menjadi volume demikian? -7400 -Gabung Berkas -&Gabung ke: -Menggabung... -Pilih bagian pertama saja dari berkas belahan -Tidak bisa mendeteksi berkas sebagai bagian berkas belahan -Tidak bisa menemukan lebih dari satu bagian berkas belahan -7500 -Hitung ceksum... -Informasi ceksum -Ceksum CRC untuk data: -Ceksum CRC untuk data dan nama: -7600 -Tolok Ukur -Pemakaian memori: -Pemampatan -Pengawamampatan -Penilaian -Jumlah Penilaian -Sekarang -Hasil -Pemakaian CPU -Penilaian/Pemakaian -Lulus: -7700 -Tautan -Tautan -Tautan dari: -Tautan ke: -7710 -Tipe Tautan -Tautan Keras -Berkas Tautan Simbolik -Direktori Tautan Simbolik -Cabang Direktori diff -Nru p7zip-rar-16.02/GUI/Lang/io.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/io.txt --- p7zip-rar-16.02/GUI/Lang/io.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/io.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.08 : iZoom -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Ido -Ido -401 -B&one -Abandonar - - - -&Yes -&No -&Klozez -Helpo - -&Durez -440 -Yes por &omni -No por o&mni -Haltez -Ristartez -&Fono -&Avanajo -&Pauzo -Pauzita -Kad vu ya volas abortar? -500 -&Dosiero -&Redakto -&Aspekto -&Favoraji -&Utensili -&Helpo -540 -&Apertigar -Apertigar int&erne -Apertigar e&xter -&Vidigar -&Redaktar -Ch&anjar nomo -Ko&piar aden... -Transp&ozar aden... -E&facar -F&endar dosiero... -Komb&inar dosieri... -In&heraji -Ko&mentar - - -Krear &dosieruyo -Krear dos&iero -E&kirar -600 -Merk&ar omno -Des&merkar omno -&Inversigar merko -Merkar... -Desmerkar... -Merkar segun tipo -Desmerkar segun tipo -700 -&Granda ikoneti -&Mikra ikoneti -&Listo -&Tabelo -730 -&Nearanjite - -&2 paneli -Utens&ila paneli -Apertigar radika dosieruyo -Ad-supre ye un nivelo -Dosieruya historio... -R&inovigar -750 -Utensila panelo di arkivo -Norma utensila panelo -Granda ikoneti -Videbla butontexto -800 -&Adjuntar dosieruyo ad la favorata quale -Lektomerkajo -900 -&Ajusti... -&Experienco dil rapideso -960 -&Konteno... -&Pri 7-Zip... -1003 -Dosiervoyo -Nomo -Dosiernoma sufixo -Dosieruyo -Grandeso -Enarkiva grandeso -Atributi -Kreita -Acesita -Chanjita -Solida -Komentita -Chifrita -Fendita ante -Fendita pos -Vortaro -CRC -Tipo -Kontre -Metodo -Operacala sistemo -Dosiersistemo -Uzero -Grupo -Bloko -Komenturo -Poziciono - - - - - - - - - - - - - - - - - - - - - - - - - -Eroro -Tota kapacivo -Vakanta -Faskogrando -Etiketo -Lokala nomo -Provizanto -2100 -Ajusti -Linguo -Linguo: -Redaktilo -&Redaktilo: - -2200 -Sistemo -Asociar 7-Zip-o kun dosieru: -2301 -Pozar 7-Zip'o en kuntexta menuo di shelo -Kaskada kuntexta menuo -Elementi di kuntexta menuo: -2320 - - -Apertar -Extraktar dosieri... -Adjuntar ad arkivo... -Verifikar arkivo -Extraktez hike -Extraktez aden {0} -Adjuntar ad {0} -Enarkivigar ed sendar elk-posto... -Enarkivigar aden {0} e sendar elk-posto... -2400 -Dosieruyi -&Laborala dosieruyo -&Sistemala provizora dosieruyo -&Nuna -&Definez: -&Uzar nur por deprenebla datumportili -Definar loko por provizora arkiva dosieri. -2500 -Ajusti -Montrar ".."-elemento -Montrar reala dosier-ikoneti -Montrar sistemala menuo -Merkar &tota lineo -Montrar &streki separanta - - - -2900 -Pri progamo... -7-Zip esas gratuita programo. Tamen, vu povas mantenar developado di 7-Zip per enregistrigesar. -3000 - -Erori ne es trovita -{0} objekt(o|i) merkita -Krear dosieruyo '{0}' neposiblesis -Rinovigo ne suportesas por ica arkivo. - - - - -Dosiero '{0}' chanjesis.\nKa vu volas rinovigar lu enarkive? -Rinovigo dil dosiero\n'{0}' faliis -Startigo dil redaktilo. - - - - -Tro multa objekti -3300 -Extrakto -Kompreso -Probado -Aperto... - -3400 -&Extraktar -E&xtraktar aden: -Definez loko por dosieri extraktenda. -3410 -Dosiervoyi -&Absoluta dosiervoyi -&Sen dosiervoyi -3420 -Remplasala skribmodo -&Kun konfirmo -&Sen konfirmo -&Omisar existanta dosieri -Automata nomchanjo -Automata nomchanjo de existanta dosieri -3500 -Konfirmo di nomchanjo -Dosieruyo ja kontenas operacata dosiero. -Kad remplasor esanta dosiero -per la ica? -{0} bayti* -&Automata nomchanjo. -3700 -Kompresmetodo ne esas suportata por dosiero '{0}'. -Datumeroro en '{0}'. Dosiero es fushita. -CRC-eroro en '{0}'. Dosiero es fushita. - - -3800 -Pasovorto -Sugestez pasovorto: - -&Montrar pasovorto - - - -&Pasovorto -3900 -Pasinta tempo: -Restanta tempo: -Grandeso: -Rapideso: - - -Erori: - -4000 -Adjuntar aden arkivo -&Arkivo: -R&emplasomodo: -A&rkiva formato: -Kompreso&grado -&Kompresometodo: -&Vortarograndeso: -Vo&rtograndeso: - - -&Parametri: -Ajustaji -Krear SF&X-arkivo - - - -Chifrar dosier&nomi -Memoruzo por kompresar: -Memoruzo por extraktar: -4050 -Sen kompresar -Maxim rapide -Rapide -Normala kompreso -Maxim granda kompreso -Extreme -4060 -Adjuntar e remplasar dosieri -Rinovigar e adjuntar dosieri -Rifreshigar existanta dosieri -Sinkronizar dosieri -4070 -Inspektar -Omna dosieri - - -6000 -Kopiar -Transpozar -Kopiez aden: -Transpozez aden: -Kopio... -Transpozo... -Nomchanjo... - -Operaco ne suportesas. -Eroro dum nomchanjo di dosiero o dosieruyo - - -6100 -Konfirmo dil efaco di dosiero -Konfirmo dil efaco di dosieruyo -Konfirmo dil efaco di dosieraro -Ka vu ya volas efacar '{0}'? -Ka vu ya volas efacar dosieruyo "{0}" e omna lua kontenaji? -Ka vu ya volas efacar ita {0} objekti? -Efaco... -Eroro dum efacar di dosiero o dosieruyo - -6300 -Krear dosieruyo -Krear dosiero -Dosieruynomo: -Dosiernomo: -Nova dosieruyo -Nova dosiero -Eroro dum dosieruykreo -Eroro dum dosierkreo -6400 -Komento -&Komento: -Merkar -Desmerkar -Masko: -6600 - -Dosieruyhistorio -Diagnozala mesaji -Mesajo -7100 -Komputilo -Reto - -Sistemo -7200 -Adjuntar -Extraktar -Verifikar -Kopiar -Transpozar -Efacar -Informo -7300 -Fendar dosiero -&Fendez aden: -&Fendar por volumini, bayti: -Fendo... - - - - - -7400 -Kombinar dosieri -&Kombinar aden: -Kombino... - - - -7500 - - - - -7600 -Experienco dil rapideso -Memoruzo: -Kompresado -Extraktado -Aprecuro -Tota aprecuro -Kuranta -Rezulta - - -Pasi: diff -Nru p7zip-rar-16.02/GUI/Lang/is.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/is.txt --- p7zip-rar-16.02/GUI/Lang/is.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/is.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.14 : 2016-04-23 : Stefán Örvar Sigmundsson -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Icelandic -Íslenska -401 -Í lagi -Viðhætta - - - -&Já -&Nei -&Loka -Hjálp - -&Halda áfram -440 -&Já við öllu -&Nei við öllu -Stöðva -Endurræsa -&Bakgrunnur -&Forgrunnur -&Gera hlé -Í hléi -Ert þú viss um að þú viljir viðhætta? -500 -&Skrá -&Breyta -S&koða -&Uppáhald -&Verkfæri -&Hjálp -540 -&Opna -Opna að &innanverðu -Opna að &utanverðu -S&koða -&Breyta -&Endurnefna -&Afrita í… -&Færa í… -E&yða -K&ljúfa skrá -S&ameina skrár -E&iginleikar -&Gera athugasemd -Reikna samtölu -Mismunur -Skapa &möppu -Skapa &skrá -&Hætta -&Tengill -&Víxlstraumar -600 -&Velja allt -&Afvelja allt -&Umsnúa vali -&Velja -&Afvelja -&Velja eftir tegund -&Afvelja eftir tegund -700 -&Stórar táknmyndir -S&máar táknmyndir -&Listi -Sm&áatriði -730 -Óflokkað -&Flatsýn -&2 spjöld -&Verkfærastikur -&Opna rótarmöppu -&Upp um eitt stig -M&öppusaga -&Endurglæða -S&jálfendurglæðun -750 -Safnverkfærastika -Stöðluð verkfærastika -Stórir takkar -Sýna takkatexta -800 -&Viðbæta möppu í uppáhald sem -Bókamerki -900 -&Valmöguleikar -&Afkastaprófa -960 -&Efnisyfirlit -&Um 7-Zip -1003 -Slóð -Nafn -Framlenging -Mappa -Stærð -Þjöppuð stærð -Eiginleikar -Skapað -Aðkomið -Dagsetning -Þétt -Athugasemd -Dulkóðað -Kljúfa fyrir -Kljúfa eftir -Orðasafn - -Tegund -And -Aðferð -Stýrikerfi hýsils -Skráakerfi -Notandi -Hópur -Bálkur -Athugasemd -Staðsetning -Slóðarforskeyti -Möppur -Skrár -Útgáfa -Bindi -Fjölbinda -Afsetning -Tenglar -Bálkar -Bindi - -64-bita -Háenda -Gjörvi -Efnisleg stærð -Höfðastærð -Samtala -Einkenni -Sýndarvistfang -Auðkenni -Stutt nafn -Skaparahugbúnaður -Geirastærð -Hamur -Mjúktengill -Villa -Heildarstærð -Laust pláss -Klasastærð -Merki -Staðarnafn -Veitandi -NT-öryggi -Víxlstraumur -Aðstoðar- -Eytt -Er tré - - -Villutegund -Villur -Villur -Viðvaranir -Viðvörun -Straumar -Víxlstraumar -Víxlstraumastærð -Sýndarstærð -Afþjöppuð stærð -Efnisleg heildarstærð -Bindaskrá -Undirtegund -Stutt athugasemd -Kóðasíða - - - -Halastærð -Innfallin stubbastærð -Tengill -Harðtengill -Skráhnútur - -Einungis lesanlegt -2100 -Valmöguleikar -Tungumál -Tungumál: -Ritill -&Ritill: -&Mismunur: -2200 -Kerfi -Tengja 7-Zip við: -Allir notendur -2301 -&Innleiða 7-Zip í samhengisvalmynd skeljar -&Þrepaskipt samhengisvalmynd -Samhengisvalmyndaratriði: -&Táknmyndir í samhengisvalmynd -2320 - - -Opna safn -Afþjappa skrár -Viðbæta í safn -Prófa safn -Afþjappa hér -Afþjappa í „{0}“ -Viðbæta í „{0}“ -Þjappa og senda í rafpósti -Þjappa í „{0}“ og senda í rafpósti -2400 -Möppur -Vinnslumappa -&Tímabundin mappa kerfis -&Núverandi -Til&greind: -N&ota einungis fyrir fjarlægjanleg drif -Tilgreina staðsetningu fyrir tímabundnar safnskrár. -2500 -Stillingar -Sýna „..“ &atriði -Sýna &raunverulegar skráartáknmyndir -Sýna &kerfisvalmynd -&Fullraðaval -Sýna &töflulínur -&Einsmella til að opna atriði -Annars konar &valhamur -Nota stórar &minnissíður -2900 -Um 7-Zip -7-Zip er frjáls hugbúnaður -3000 -Kerfið getur ekki ráðstafað nauðsynlega magninu af minninu -Það eru engar villur -„{0}“ hlutir valdir -Getur ekki skapað möppuna „{0}“ -Uppfærsluaðgerðir eru ekki studdar fyrir þetta safn. -Getur ekki opnað skrána „{0}“ sem safn -Getur ekki opnað dulkóðaða safnið „{0}“. Rangt aðgangsorð? -Óstudd safntegund -Skráin „{0}“ er nú þegar til -Skránni „{0}“ var breytt.\nVilt þú uppfæra hana í safninu? -Getur ekki uppfært skrána\n„{0}“ -Getur ekki ræst ritilinn. -Skráin lítur út eins og veira (skráarnafnið inniheldur löng bil). -Aðgerðina er ekki hægt að kalla í frá möppu sem hefur langa slóð. -Þú verður að velja eina skrá -Þú verður að velja eina eða fleiri skrár -Of mörg atriði -Getur ekki opnað skrána sem „{0}“-safn -Skráin er opin sem „{0}“-safn -Safnið er opið með afsetningu -3300 -Afþjappar -Þjappar -Prófar -Opnar -Skimar -Fjarlægir -3320 -Viðbætir -Uppfærir -Greinir -Endurtekur -Endurpakkar -Sleppir -Eyðir -Skapar höfuð -3400 -Afþjappa -Afþjappa í: -Tilgreindu staðsetningu fyrir afþjöppuðu skrárnar. -3410 -Slóðarhamur: -Full slóðarnöfn -Engin slóðarnöfn -Algild slóðarnöfn -Afstæð slóðarnöfn -3420 -Yfirritunarhamur: -Spyrja áður en yfirritað er -Yfirrita án kvaðningar -Sleppa gildandi skrám -Sjálfendurnefnun -Sjálfendurnefnun gildandi skráa -3430 -Útrýma afritinu af rótarmöppunni -Endurheimta skráaröryggi -3500 -Staðfesta skráaryfirritun -Áfangastaðsmappan inniheldur nú þegar meðhöndluðu skrána. -Vilt þú yfirrita gildandi skrána -með þessari? -{0} bæti -Sjálfendurnefnun -3700 -Óstudd þjöppunaraðferð fyrir „{0}“. -Gagnavilla í „{0}“. Skráin er brotin -CRC mistókst í „{0}“. Skráin er brotin. -Gagnavilla í dulkóðuðu „{0}“. Rangt aðgangsorð? -CRC mistókst í dulkóðuðu skránni „{0}“. Rangt aðgangsorð? -3710 -Rangt aðgangsorð? -3721 -Óstudd þjöppunaraðferð -Gagnavilla -CRC mistókst -Ótiltæk gögn -Óvæntur endir gagna -Það eru gögn eftir endanum á aðalgögnunum -Er ekki safn -Höfðavillur -Rangt aðgangsorð -3763 -Ótiltækt upphaf safns -Óstaðfest upphaf safns - - - -Óstuddur eiginleiki -3800 -Ritaðu aðgangsorðið -Ritaðu aðgangsorðið: -Endurritaðu aðgangsorðið: -Sýna aðgangsorðið -Aðgangsorðin samsvarast ekki -Notaðu einungis enska stafi, tölur og sérstök rittákn (!, #, $, o.s.frv.) í aðgangsorðunum -Aðgangsorðið er of langt -Aðgangsorð -3900 -Liðinn tími: -Tími eftir: -Heildarstærð: -Hraði: -Meðhöndlað: -Þjöppunarhlutfall: -Villur: -Söfn: -4000 -Viðbæta safni -Safn: -Uppfærsluhamur: -Safnsnið: -Þjöppunarsnið: -Þjöppunaraðferð: -Orðasafnsstærð: -Orðastærð: -Þéttbálkstærð: -Fjöldi gjörvaþráða: -Færibreytur: -Valmöguleikar -Skapa SFX-safn -Þjappa sameiginlegum skrám -Dulkóðun -Dulkóðunaraðferð: -Dulkóða skráarnöfn -Minnisnotkun fyrir þjöppun: -Minnisnotkun fyrir afþjöppun: -Eyða skrám eftir þjöppun -4040 -Geyma mjúktengla -Geyma harðtengla -Geyma víxlgagnastrauma -Geyma skráaröryggi -4050 -Geyma -Hraðast -Hratt -Venjulegt -Hámarks -Öfga- -4060 -Viðbæta og yfirrita skrár -Uppfæra og viðbæta skrám -Hressa við gildandi skrám -Samstilla skrár -4070 -Vafra -Allar skrár -Óþétt -Þétt -6000 -Afrita -Færa -Afrita í: -Færa í: -Afritar -Færir -Endurnefnir -Veldu móttökumöppu. -Aðferðin er ekki stutt fyrir þessa möppu. -Villa við endurnefnun skráar eða möppu -Staðfesta skráarafritun -Ert þú viss um að þú viljir afrita skrárnar í safnið -6100 -Staðfesta skráareyðingu -Staðfesta möppueyðingu -Staðfesta fjölskráaeyðingu -Ert þú viss um að þú viljir eyða „{0}“? -Ert þú viss um að þú viljir eyða möppunni „{0}“ og öllu innihaldinu hennar? -Ert þú viss um að þú viljir eyða þessum {0} atriðum? -Eyðir -Villa við eyðingu skráar eða möppu -Kerfið getur ekki fært skrá með langri slóð í Recycle Bin -6300 -Skapa möppu -Skapa skrá -Möppunafn: -Skráarnafn: -Ný mappa -Ný skrá -Villa við sköpun möppunnar -Villa við sköpun skráarinnar -6400 -Athugasemd -Athugasemd: -Velja -Afvelja -Mát: -6600 -Eiginleikar -Möppusaga -Greiningarskilaboð -Skilaboð -7100 -Tölva -Net -Skjöl -Kerfi -7200 -Viðbæta -Afþjappa -Prófa -Afrita -Færa -Eyða -Upplýsingar -7300 -Kljúfa skrá -Kljúfa í: -Kljúfa í bindi, bæti: -Klýfur -Staðfesta klofning -Ert þú viss um að þú viljir kjúfa skrána í {0} bindi? -Bindisstærð verður að vera minni en stærðin á upprunalegu skránni -Röng bindisstærð -Tilgreindu bindisstærð: {0} bæti.\nErt þú viss um að þú viljir kljúfa safnið í slík bindi? -7400 -Sameina skrár -Sameina í: -Sameinar -Veldu einungis fyrsta hlutann af klofningsskránni -Get ekki greint skrána sem hluta af klofningsskránni -Get ekki fundið meira en einn hluta af klofningsskránni -7500 -Reiknar samtölu -Samtöluupplýsingar -CRC-samtala fyrir gögn: -CRC-samtala fyrir gögn og nöfn: -7600 -Afkastapróf -Minnisnotkun: -Þjöppun -Afþjöppun -Niðurstaða -Heildarniðurstaða -Núverandi -Útkoma -Gjörvanotkun -Niðurstaða / Notkun -Yfirferðir: -7700 -Tengill -Tengill -Tengill frá: -Tengill til: -7710 -Tengiltegund -Harðtengill -Skráarmjúktengill -Skráasafnsmjúktengill -Skráasafnstenging \ No newline at end of file diff -Nru p7zip-rar-16.02/GUI/Lang/it.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/it.txt --- p7zip-rar-16.02/GUI/Lang/it.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/it.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.07 : Leandro Spagnol -; : Vincenzo Reale (some corrections) -; 15.05 : 2015-06-17 : TJL73 : http://tjl73.altervista.org/ -; -; -; -; -; -; -; -; -0 -7-Zip -Italian -Italiano -401 -OK -Annulla - - - -&Sì -&No -&Chiudi -Aiuto - -&Riprendi -440 -Sì per &tutti -No per t&utti -Ferma -Riavvia -&In background -&In primo piano -&Pausa -In pausa -Sei sicuro di voler annullare? -500 -&File -&Modifica -&Visualizza -&Preferiti -&Strumenti -&Aiuto -540 -&Apri -Apri in &7-Zip File Manager -Apri in E&xplorer -&Visualizza -Apri con l'&editor predefinito -Rino&mina -&Copia in... -&Sposta in... -&Elimina -&Dividi il file... -&Unisci i file... -&Proprietà -Comme&nto... -Calcola chec&ksum -Comparazione differenze (Diff) -Crea cartella -Crea file -E&sci -Collegamento -&Alternate Data Streams -600 -&Seleziona tutto -&Deseleziona tutto -In&verti selezione -Seleziona... -Deseleziona... -Seleziona per tipo -Deseleziona per tipo -700 -Icone &grandi -Icone &piccole -&Elenco -&Dettagli -730 -Nessun ordine -Vista non strutturata -Interfaccia a &2 pannelli -Barre degli &strumenti -Apri cartella principale -Livello superiore -Cronologia... -&Aggiorna -Aggiornamento automatico -750 -Barra archivio -Barra standard -Icone grandi -Mostra etichette di testo -800 -&Aggiungi la cartella ai Preferiti come -Collegamento -900 -&Opzioni... -&Benchmark -960 -&Guida... -&Informazioni su 7-Zip... -1003 -Percorso -Nome -Estensione -Cartella -Dimensione -Dimensione compressa -Attributi -Creato -Ultimo accesso -Ultima modifica -Solido -Commentato -Cifrato -Dividi prima -Dividi dopo -Dizionario - -Tipo -Estensione -Metodo -OS destinatario -File system -Utente -Gruppo -Blocco -Commento -Posizione -Percorso completo -Cartelle -File -Versione -Unità -Unità multiple -Offset -Collegamenti -Blocchi -Unità - -64-bit -Big-endian -CPU -Dimensione fisica -Dimensione intestazioni -Checksum -Caratteristiche -Indirizzo virtuale -ID -Nome breve -Applicativo origine -Dimensione settore -Modalità -Collegamento simbolico -Errore -Capacità -Disponibili -Dimensione dei cluster -Etichetta -Nome locale -Rete -Sicurezza NT -Flusso alternato -Ausiliario -Eliminato -Ad albero - - -Tipo di errori -Errori -Errori -Avvertimenti -Avvertimento -Flussi -Flussi alternati -Dimensione dei flussi alternati -Dimensione virtuale -Dimensione decompressione -Dimensione fisica totale -Indice del volume -Sottotipo -Commento breve -Pagina dei codici - - - -Dimensione della coda -Dimensione della matrice integrato -Collegamento -Collegamento statico -iNode - -Sola lettura -2100 -Opzioni -Lingua -Lingua: -Editor -&Editor predefinito: -Comparatore &differenze (Diff): -2200 -Sistema -Associa 7-Zip a: -Tutti gli utenti -2301 -Integra 7-Zip nel menu contestuale della shell -Menu contestuale a cascata -Elementi del menu contestuale: -Icone nel menu contestuale -2320 - - -Apri -Estrai i file... -Aggiungi all'archivio... -Verifica l'archivio -Estrai qui -Estrai in {0} -Aggiungi a {0} -Comprimi ed invia per email... -Comprimi in {0} ed invia per email -2400 -Cartelle -Cartella di lavoro -Cartella &TEMP di sistema -&Corrente -&Specificata: -&Utilizza solo per dischi rimovibili -Specifica una cartella per i file temporanei. -2500 -Impostazioni -Mostra l'elemento ".." -Mostra le icone dei file -Mostra le icone di sistema -Selezione a &riga intera -Mostra &griglia -Click singolo per aprire una voce -Modalità di selezione &alternativa -Utilizza pagine &larghe di memoria -2900 -Informazioni -7-Zip è un software libero.\n\nLocalizzazione italiana a cura di:\nTJL73 -3000 -Non è possibile allocare la quantità di memoria richiesta -Nessun errore. -Oggetti selezionati: {0} -Impossibile creare la cartella '{0}' -Non è possibile effettuare aggiornamenti su questo archivio. -Impossibile aprire il file '{0}' come archivio. -Impossibile aprire l'archivio cifrato '{0}'. Password errata? -Archivio non supportato -Il file {0} è già presente -Il file '{0}' è stato modificato.\nVuoi aggiornare l'archivio? -Impossibile aggiornare il file\n'{0}' -Impossibile avviare l'editor. -Il file sembra essere un virus (contiene molti spazi nel nome). -L'operazione non può essere richiamata da una cartella con percorso lungo. -Devi selezionare un file -Devi selezionare almeno un file -Troppi elementi -Impossibile aprire il file come archivio {0} -Il file è aperto come archivio {0} -L'archivio è aperto con offset -3300 -Estrazione in corso -Compressione in corso -Verifica archivio -Apertura in corso... -Scansione... -Rimozione -3320 -Aggiunta -Aggiornamento -Analisi -Replica -Ripacchettizzazione -Salto -Eliminazione -Creazione intestazione -3400 -Estrai -E&strai in: -Specifica una cartella in cui estrarre i file. -3410 -Struttura delle cartelle: -Percorsi completi -Nessun percorso -Percorsi assoluti -Percorsi relativi -3420 -Sovrascrittura: -Chiedi prima di sovrascrivere -Sovrascrivi senza chiedere -Non sovrascrivere i file esistenti -Rinomina automaticamente -Rinomina autom. i file esistenti -3430 -Elimina la duplicazione della radice -Ripristina sicurezza dei file -3500 -Conferma la sovrascrittura del file -File già esistente nella cartella di destinazione. -Vuoi sostituire il file esistente -con questo? -{0} byte -&Rinomina automaticamente -3700 -Metodo di compressione non supportato per '{0}'. -Errore nei dati in '{0}'. Il file è danneggiato. -CRC non corretto in '{0}'. Il file è danneggiato. -Errore nel file cifrato '{0}'. Password errata? -CRC errato nel file cifrato '{0}'. Password errata? -3710 -Password errata? -3721 -Metodo di compressione non supportata -Errore dei dati -CRC errato -Dati non disponibili -Fine dei dati inattesa -Sono presenti dati oltre la fine del blocco utile -Non è un archivio -Errore intestazioni -Password errata -3763 -Inizio dell'archivio non disponibile -Inizio dell'archivio non confermato - - - -Funzionalità non supportata -3800 -Inserisci password -&Inserisci password: -&Reinserisci password: -Mostra pass&word -Password differenti -Per la password, utilizzare solo lettere ASCII, numeri e caratteri speciali (!, #, $, ...) -La password è troppo lunga -Password -3900 -Tempo trascorso: -Tempo rimanente: -Dimensione totale: -Velocità: -Elaborato: -Rapporto compressione: -Errori: -Archivi: -4000 -Aggiungi all'archivio -Nome &archivio: -Modalità a&ggiornamento: -&Formato dell'archivio: -&Livello di compressione: -&Metodo di compressione: -Dimensione &Dizionario: -Dimensioni &Parola: -Dimensione del &blocco solido: -N&umero di flussi (thread) CPU: -Parametri &opzionali: -Opzioni -Crea archivio auto-&estraente -Comprimi file condivisi -Cifratura -Metodo &cifratura: -Cifra anche il &nome dei file -Quantità memoria per compressione: -Quantità memoria per decompressione: -Elimina i file dopo la compressione -4040 -Memorizza collegamenti simbolici -Memorizza collegamenti statici -Memorizza flussi dati alternati -Memorizza sicurezza dei file -4050 -Nessuna -Velocissima -Veloce -Normale -Massima -Ultra -4060 -Aggiungi e sostituisci i file -Aggiorna e aggiungi i file -Aggiorna i file esistenti -Sincronizza i file -4070 -Sfoglia -Tutti i file -Non-solido -Solido -6000 -Copia -Sposta -Copia in: -Sposta in: -Copia in corso... -Spostamento in corso... -Rinomina in corso... -Selezionare la cartella di destinazione. -Operazione non supportata per questa cartella. -Errore nella rinomina del file o cartella -Conferma copia -Sei sicuro di voler copiare questi file nell'archivio -6100 -Conferma l'eliminazione del file -Conferma l'eliminazione della cartella -Conferma l'eliminazione di più elementi -Sei certo di voler eliminare '{0}'? -Sei certo di voler eliminare la cartella '{0}' e tutto il suo contenuto? -Sei certo di voler eliminare questi {0} elementi? -Eliminazione in corso... -Errore nell'eliminazione del file o della cartella -Impossibile spostare un file con percorso lungo nel Cestino -6300 -Crea cartella -Crea file -Nome cartella: -Nome file: -Nuova cartella -Nuovo file -Errore nella creazione della cartella -Errore nella creazione del file -6400 -Commento -&Commento: -Seleziona -Deseleziona -Filtro: -6600 -Proprietà -Cronologia -Messaggi di diagnostica -Messaggio -7100 -Computer -Rete -Documenti -Sistema -7200 -Aggiungi -Estrai -Verifica -Copia -Sposta -Elimina -Proprietà -7300 -Dividi file -&Dividi in: -Di&vidi in più file (dimensione in byte): -Dividi in... -Conferma divisione -Sicuro di voler dividere l'archivio in {0} porzioni? -La dimensione di ciascuna porzione deve essere più piccola della dimensione totale dell'archivio originale -Dimensione non corretta -Dimensione specificata: {0} byte.\nSicuro di voler dividere l'archivio in questo modo? -7400 -Unisci i file -&Unisci in: -Unisci... -Seleziona solo la prima parte del file diviso -Impossibile riconoscere il file come archivio diviso -Impossibile trovare più di una parte dell'archivio diviso -7500 -Calcolo del checksum... -Informazioni sul checksum -CRC checksum sui dati: -CRC checksum su dati e nomi: -7600 -Benchmark -Utilizzo memoria: -Compressione in corso -Decompressione in corso -Valutazione -Valutazione totale -Attuale -Risultante -Utilizzo CPU -Stima / Utilizzo -Passaggi: -7700 -Collegamento -Collega -Origine collegamento: -Destinazione collegamento: -7710 -Tipo di collegamento -Collegamento statico -Collegamento simbolico al file -Collegamento simbolico alla cartella -Giunzione cartella diff -Nru p7zip-rar-16.02/GUI/Lang/ja.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ja.txt --- p7zip-rar-16.02/GUI/Lang/ja.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ja.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Komuro, Mick, 2chBBS-software -; : Crus Mitsuaki -; 9.07 : Stepanushkin Dmitry -; 9.23 : 2011-06-22 : Stepanushkin Dmitry, nabeshin -; 9.33 : 2014-06-17 : Stepanushkin Dmitry -; 15.00 : 2015-04-30 : Stepanushkin Dmitry -; -; -; -; -; -0 -7-Zip -Japanese -日本語 -401 -OK -キャンセル - - - -はい(&Y) -いいえ(&N) -閉じる(&C) -ヘルプ - -続行(&C) -440 -すべてに はい(&A) -すべてに いいえ(&L) -停止 -再開 -バックグラウンド(&B) -フォアグラウンド(&F) -一時停止(&P) -一時停止 -本当に圧縮を取りやめますか? -500 -ファイル(&F) -編集(&E) -表示(&V) -お気に入り(&A) -ツール(&T) -ヘルプ(&H) -540 -開く(&O) -7-Zipで閲覧(&I) -関連付けで開く(&U) -表示(&V) -編集(&E) -名前の変更(&M) -コピー(&C)... -移動(&M)... -削除(&D) -ファイル分割(&S)... -ファイル結合(&B)... -プロパティ(&R) -コメント(&N) -チェックサムの計算 -比較 -フォルダ作成 -ファイル作成 -閉じる(&X) -リンク作成 -代替データストリーム(&A) -600 -全て選択(&A) -全て選択解除 -反転選択(&I) -選択... -選択解除... -同一形式選択 -同一形式選択解除 -700 -大きいアイコン(&G) -小さいアイコン(&M) -一覧(&L) -詳細(&D) -730 -並べ替え解除 -フラットビュー -&2分割画面 -ツールバー(&T) -ルートフォルダを開く -1つ上の階層へ -フォルダ履歴... -最新の情報に更新(&R) -自動更新 -750 -書庫ツールバー -標準ツールバー -大きなボタン -ボタンのテキスト表示 -800 -フォルダをお気に入りに追加(&A) -ブックマーク -900 -オプション(&O)... -ベンチマーク(&B) -960 -ヘルプの表示(&C)... -7-Zipについて(&A)... -1003 -パス -名前 -拡張子 -フォルダ -サイズ -圧縮後サイズ -属性 -作成日時 -アクセス日時 -更新日時 -ソリッド -コメント済み -暗号化 -分割前 -分割後 -辞書 - -種類 -逆 -圧縮方法 -ホストOS -ファイルシステム -ユーザー -グループ -ブロック -コメント -ポジション -パスプレフィックス -フォルダ数 -ファイル数 -バージョン -ボリューム -多重ボリューム書庫 -オフセット -リンク数 -使用ブロック数 -ボリューム数 - -64ビット -ビッグエンディアン -CPU -物理サイズ -ヘッダーサイズ -チェックサム -特性 -仮想アドレス -ID -省略名 -作成アプリケーション -セクターサイズ -モード -リンク -エラー -合計サイズ -空き領域 -クラスタサイズ -ラベル -ローカル名 -プロバイダ -NTセキュリティ -代替データストリーム -補助 -削除済み -はツリー - - -エラー種類 -エラー -エラー -警告 -警告 -ストリーム -代替データストリーム -代替データストリームサイズ -仮想サイズ -解凍後サイズ -物理サイズ合計 -ボリュームインデックス -亜類型 -コメント -コードページ - - - -テイルのサイズ -組み込みスタブのサイズ -リンク -ハードリンク -iノード - -読み取り専用 -2100 -オプション -言語 -言語設定: -外部ツール -編集(&E): -比較(diff)(&D): -2200 -システム -7-Zipに関連付けるファイル: -全てのユーザー -2301 -シェルコンテキスト(右クリック)メニューに7-Zipを登録 -7-Zipをサブメニュー化する -メニュー項目: -コンテキストメニューにアイコンを表示 -2320 -<フォルダ> -<書庫> -開く -展開... -圧縮... -書庫をテスト -ここに展開 -{0}に展開 -{0}に圧縮 -圧縮して電子メール送信... -{0}に圧縮して電子メール送信 -2400 -フォルダ -作業フォルダ(&W) -システム一時フォルダ(&S) -カレントフォルダ(&C) -フォルダ指定(&P): -リムーバブルドライブのみ使用する -一時ファイルのための場所を指定してください -2500 -設定 -'..'を表示する -各ファイルの実際のアイコンを表示する -システム(エクスプローラ)のメニューも表示する -行単位(列アイテムを一括)で選択する(&F) -グリッド線を表示する(&G) -シングルクリックで開く -カーソル移動で選択が自動解除されないモード(&A) -大きなメモリページを使用する(&L) -2900 -7-Zipについて -7-Zipはフリーソフトウェアです -3000 -要求された量のメモリを割り当てることができません -正常です -{0}個のオブジェクトを選択 -'{0}'フォルダが作成できません -この書庫は更新機能がサポートされていません -ファイル'{0}'は書庫として開くことができません -暗号化された書庫'{0}'を開くことができません。パスワードが間違っていませんか? -未対応の書庫形式です -{0}ファイルは既に存在しています -'{0}'ファイルが変更されました。\n書庫を更新しますか? -ファイルを更新できません。\n'{0}' -エディタを起動できません。 -このファイルは、ウイルスのように見えます(ファイル名に大量のスペースを含んでいる)。 -パスが長いフォルダではこの操作を実行できません。 -1つのファイルを選択してください -1つ以上のファイルを選択してください -アイテムが多過ぎます -ファイルを{0}書庫として開くことができません -ファイルが{0}書庫として開かれています -書庫がオフセットを使用して開かれています -3300 -展開中 -圧縮中 -テスト中 -開いています... -スキャン中... -削除中 -3320 -追加中 -更新中 -解析中 -複製中 -再圧縮中 -スキップ中 -削除中 -ヘッダーの作成中 -3400 -展開 -展開先(&X): -展開先指定 -3410 -パス名出力方法: -フルパス -パスなし -絶対パス -相対パス -3420 -上書き方法 -上書きするときは確認する -常に上書き -ファイルが存在するときはスキップ -自動的にリネーム -ファイルが存在するときは自動リネーム -3430 -ルートフォルダーの重複を回避 -ファイルのセキュリティ属性を復元 -3500 -ファイル上書き確認 -出力先のフォルダには既に以下の同じファイルが存在します -現在のファイル -に次の新しいファイルを上書きしますか? -{0}バイト -自動的にリネーム(&U) -3700 -'{0}'はサポートされていない圧縮方式です -'{0}'でデータエラーが発生しました。ファイルは壊れています -'{0}'のCRCが違います。ファイルは壊れています -暗号化されたファイル'{0}'でデータエラーが発生しました。パスワードが間違っていませんか? -暗号化されたファイル'{0}'のCRCが違います。パスワードが間違っていませんか? -3710 -パスワードが間違っていませんか? -3721 -非対応圧縮方法 -データエラー -CRCが違います -データ取得失敗 -データ不足 -データのペイロード後にデータが存在します -書庫ではありません -ヘッダーエラー -パスワードが間違っています -3763 -書庫先頭の取得失敗 -無効な書庫先頭 - - - -非対応機能 -3800 -パスワード入力 -パスワード入力: -パスワード再入力: -パスワードを表示する(&S) -パスワードが一致しません -パスワードには半角英数記号(!, #, $, ...)のみを使用してください。 -パスワードがあまりに長過ぎます -パスワード -3900 -経過時間: -残り時間: -サイズ合計: -速度: -処理済み: -圧縮率: -エラー: -書庫数: -4000 -ファイル圧縮 -圧縮先(&A): -更新方法(&U): -書庫形式(&F): -圧縮レベル(&L): -圧縮方式(&M): -辞書サイズ(&D): -ワードサイズ(&W): -ソリッドブロックサイズ: -CPUスレッド数: -パラメータ(&P): -オプション -自己展開書庫作成(&X) -共有(編集中の)ファイルも圧縮 -暗号化 -暗号化方式: -ファイル名を暗号化(&N) -圧縮に必要なメモリ: -展開に必要なメモリ: -圧縮後に元のファイルを削除 -4040 -シンボリックリンクを保存 -ハードリンクを保存 -代替データストリームを保存 -ファイルのセキュリティ属性を保存 -4050 -無圧縮 -最速 -高速 -標準 -最高 -超圧縮 -4060 -すべてのファイル上書き -ファイル追加と更新 -変更したファイルのみ更新 -ファイルを同期させる -4070 -閲覧 -すべてのファイル -ソリッドなし -無制限 -6000 -コピー -移動 -フォルダへコピー: -フォルダへ移動: -コピーしています... -移動しています... -リネームしています... -対象のフォルダを選択してください。 -このフォルダでは、その操作はサポートされていません。 -ファイルまたはフォルダのリネームエラー -ファイルコピーの確認 -本当にファイルを書庫に追加しますか? -6100 -ファイル削除の確認 -フォルダ削除の確認 -複数ファイル削除の確認 -'{0}'を本当に削除しますか? -'{0}'フォルダとその中身のすべてを削除しますか? -これらの{0}個の項目を本当に削除しますか? -削除中... -ファイルまたはフォルダの削除エラー -ファイルのパスが長すぎるため、ファイルをごみ箱に移動できません -6300 -フォルダ作成 -ファイル作成 -フォルダ名: -ファイル名: -新しいフォルダ -新しいファイル -フォルダ作成エラー -ファイル作成エラー -6400 -コメント -コメント(&C): -選択 -選択解除 -マスク: -6600 -プロパティ -フォルダ履歴 -診断結果 -メッセージ -7100 -コンピュータ -ネットワーク -ドキュメント -システム -7200 -追加 -展開 -テスト -コピー -移動 -削除 -情報 -7300 -ファイル分割 -分割先(&S): -書庫をサイズで分割(&V): -分割中... -分割の確認 -{0}個にファイルを分割してもよろしいですか? -分割後のサイズは元のファイルサイズより小さいサイズを指定してください -不正なボリュームサイズ -選択されたボリュームサイズ:{0}バイト\nこのサイズに書庫を分割しますか? -7400 -ファイル結合 -結合先(&C): -結合中... -分割ファイルの先頭のファイルだけ選択してください -分割ファイルが見つかりません -分割ファイルの一部しか見つかりません -7500 -チェックサム計算中... -チェックサム情報 -データのCRCチェックサム: -データと名前のCRCチェックサム: -7600 -ベンチマーク -必要メモリ: -圧縮中 -展開中 -評価 -総合評価 -現在 -結果 -CPU使用率 -評価 / 使用率 -テスト回数: -7700 -リンク -リンク作成 -リンク元: -リンク先: -7710 -リンク種類 -ハードリンク -ファイルのシンボリックリンク -ディレクトリのシンボリックリンク -ディレクトリのジャンクション diff -Nru p7zip-rar-16.02/GUI/Lang/ka.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ka.txt --- p7zip-rar-16.02/GUI/Lang/ka.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ka.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.23 : 2011-09-25 : Translated by Giorgi Maghlakelidze, original translation by Dimitri Gogelia, -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Georgian -ქართული -401 -OK -გაუქმება - - - -&დიახ -&არა -&დახურვა -დახმარება - -&გაგრძელება -440 -დიახ &ყველასათვის -არა ყვე&ლასათვის -შეწყვეტა -ხელახლა -&ფონურად -&წინა პლანზე -&შეჩერება -&შეჩერებული -ნამდვილად გსურთ მოქმედების შეწყვეტა? -500 -&ფაილი -&დამუშავება -&ხედი -რ&ჩეულები -&ხელსაწყოები -&დახმარება -540 -&გახსნა -გახსნა &შიგნით -გახსნა გა&რეთ -და&თვალიერება -და&მუშავება -გადა&რქმევა -&ასლის მოთავსება... -&გადატანა... -&წაშლა -&ფაილის დაყოფა... -&ფაილების გაერთიანება... -თ&ვისებები -კომენ&ტარი -საკონტროლო ჯამის დათვლა -Diff -საქაღალდის შექმნა -ფაილის შექმნა -გ&ამოსვლა -600 -&ყველაფრის მონიშვნა -მონიშვნის გაუქმება -მონიშვნის შებრუნება -მოინიშნოს... -მოიხსნას მონიშვნა... -მონიშვნა ტიპის მიხედვით -მონიშვნის მოხსნა ტიპის მიხედვით -700 -&დიდი ხატულები -&პატარა ხატულები -&სია -&დაწვრილებით -730 -დაულაგებელი -ბრტყელი ხედი -&2 პანელი -&ხელსაწყოთა ზოლი -ძირეული საქაღალდის გახსნა -საქაღალდიდან გასვლა -საქაღალდეების ისტორია... -&განახლება -750 -დაარქივების ზოლი -ძირითადი ზოლი -დიდი ღილაკები -წარწერები ღილაკებზე -800 -&საქაღალდის რჩეულებში დამატება როგორც -სანიშნე -900 -&გამართვა... -&წარმადობის შემოწმება -960 -სარჩევი... -7-Zip-ის შესახებ... -1003 -მდებარეობა -სახელი -გაფართოება -საქაღალდე -ზომა -შეკუმშულის ზომა -ატრიბუტები -შექმნილია -გახსნილია -შეცვლილია -უწყვეტი -კომენტარი -დაშიფრულია -დაყოფა სანამ -დაყოფა შემდეგ -ლექსიკონი -CRC -ტიპი -ანტი -მეთოდი -სისტემა -ფაილური სისტემა -მომხმარებელი -ჯგუფი -ბლოკი -კომენტარი -მდებარეობა -მდებარეობის თავსართი -საქაღალდეები -ფაილები -ვერსია -ტომი -მრავალტომიანი -წანაცვლება -ბმულები -ბლოკები -ტომები - -64 ბიტი -Big-endian -CPU -ფიზიკური ზომა -სათაურების ზომა -საკონტროლო ჯამი -თვისებები -ვირტუალური მისამართი -ID -მოკლე სახელი -შემქმნელი პროგრამა -სექტორის ზომა -რეჟიმი -ბმული -შეცდომა -სრული მოცულობა -თავისუფალი სივრცე -კლასტერის ზომა -წარწერა -ადგილობრივი სახელი -მომწოდებელი -2100 -გამართვა -ენები -ენა: -რედაქტორი -რედაქტორი: -&Diff: -2200 -სისტემა -ასოცირება 7-Zip-თან: -2301 -7-Zip-ის გარსის კონტექსტურ მენიუში ჩადგმა -კასკადური კონტექსტური მენიუ -კონტექსტური მენიუს შემადგენლობა: -2320 -<საქაღალდე> -<არქივი> -არქივის გახსნა -ფაილების ამოღება... -არქივში ჩამატება... -არქივის შემოწმება -ამოღება აქ -ამოღება {0}-ში -{0}-ში ჩამატება -შეკუმშვა და ელფოსტით გაგზავნა... -{0}-ში შეკუმშვა და ელფოსტით გაგზავნა -2400 -საქაღალდეები -&მუშაობის საქაღალდე -&სისტემური დროებითი საქაღალდე -&მიმდინარე -&მითითებული: -გამოიყენება ცვლადი მეხსიერების მოწყობილობებისთვის -მიუთითეთ მდებარეობა დროებითი არქივებისათვის. -2500 -გამართვა -".." ელემენტის ჩვენება -ფაილთა ნამდვილი ხატულების ჩვენება -სისტემური მენიუს ჩვენება -კურსორი &მთელ სტრიქონზე -ჩვენება &ცხრილის სახით -ელემენტთა გახსნა ერთი წკაპით -მონიშნვის &ალტერნატიული რეჟიმი -&დიდი მეხსიერების ბლოკების გამოყენება -2900 -7-Zip-ის შესახებ -7-Zip არის თავისუფლად გავრცელებადი პროგრამული უზრუნველყოფა. -3000 -შეუძლებელია საჭირო ზომის მეხსიერების გამოყოფა -შეცდომები არ მოიძებნა -მონიშნულია {0} ობიექტი -ვერ მოხერხდა '{0}' საქაღალდეს შექმნა -ამ ტიპის არქივისათვის ცვლილების ოპერაცია ხელმიუწვდომელია. -'{0}' ფაილის არქივად გახსნა ვერ მოხერხდა -'{0}' დაშიფრული არქივის გახსნა ვერ მოხერხდა. არასწორი პაროლი? -არქივთა ამ სახეობის გახსნა შეუძლებელია -ფაილი '{0}' უკვე არსებობს -ფაილი '{0}' შეიცვალა.\nგნებავთ მისი არქივში განახლება? -შეუძლებელია \n'{0}'-ის განახლება -შეუძლებელია რედაქტორის გაშვება. -ფაილი შესაძლოა აღმოჩნდეს ვირუსი (სახელი შეიცავს ძალიან ბევრ თავმოყრილ ჰარს). -შეუძლებელია გრძელ-სახელიანი საქაღალდიდან ქმედების შესრულება -უნდა აირჩიოთ ერთი ფაილი -უნდა აირჩიოთ ერთი ან მეტი ფაილი -მეტისმეტად ბევრი ელემენტი -3300 -მიმდინარეობს ამოღება -მიმდინარეობს შეკუმშვა -მიმდინარეობს შემოწმება -მიმდინარეობს გახსნა... -მიმდინარეობს ამოკითხვა... -3400 -ამოღება -ა&მოღება: -მიუთითეთ ადგილი ამოსაღები ფაილებისათვის. -3410 -მდებარეობა -სრული მდებარეობა -მდებარეობის გარეშე -3420 -ზედგადაწერა -ზედგადაწერის დასტური -ზედგადაწერა დასრურის გარეშე -არსებული ფაილების გამოტოვება -ავტო-გადარქმევა -არსებული ფაილების ავტო-გადარქმევა -3500 -ფაილის ზედგადაწერის დასტური -საქაღალდე უკვე შეიცავს დამუშავებულ ფაილს. -გსურთ ჩაანაცვლოთ არსებული ფაილი -ახალი ფაილით? -{0} ბაიტი -ა&ვტო-გადარქმევა -3700 -შეკუმშვის შეუთავსებადი მეთოდი '{0}'-თვის. -მონაცემების შეცდომა '{0}'-ში. ფაილი დაზიანებულია. -CRC-ის შეცდომა '{0}'-ში. ფაილი დაზიანებულია. -მონაცემების შეცდომა დაშიფრულ ფაილში '{0}'. არასწორი პაროლი? -CRC ჩაიშალა დაშიფრულ ფაილში '{0}'. არასწორი პაროლი? -3800 -პაროლის შეყვანა -შეიყვანეთ პაროლი: -პაროლი ხელახლა: -პაროლის &ჩვენება -პაროლები არ დაემთხვა -პაროლად შეიყვანეთ მხოლოდ ლათინური ასოები, ციფრები და განსაკუთერებული სიმბოლოები (!, #, $, ...) -პაროლი მეტისმეტად გრძელია -პაროლი -3900 -გასული დრო: -დარჩენილი დრო: -ჯამური ზომა: -სიჩქარე: -დამუშავებული: -შეკუმშვის დონე: -შეცდომა: -არქივები: -4000 -არქივში ჩამატება -&არქივი: -&განახლების რეჟიმი: -არქივის &ფორმატი: -შეკუმშვის &დონე: -შეკუმშვის &მეთოდი: -&ლექსიკონის ზომა: -&სიტყვის ზომა: -უწყვეტი ბლოკის ზომა: -CPU ნაკადების ოდენობა: -&პარამეტრები: -დამატებითი -შეიქმნას SF&X არქივი -გაზიარებული ფაილების შეკუმშვა -დაშიფრვა -დაშიფრვის მეთოდი: -ფაილთა &სახელების დაშიფრვა -მეხსიერება შეკუმშვისათვის: -მეხსიერება ამოღებისათვის: -4050 -შეკუმშვის გარეშე -უსწრაფესი -სწრაფი -ჩვეულებრივი -მაღალი -უმაღლესი -4060 -ფაილთა დამატება და შეცვლა -ფაილთა განახლება და დამატება -ფაილთა განახლება -ფაილთა სინქრონიზება -4070 -დათვალიერება -ყველა ფაილი -წყვეტილი -უწყვეტი -6000 -ასლის აღება -გადატანა -ასლის მოთავსება: -გადატანა: -ასლის აღება... -გადატანა... -გადარქმევა... -აირჩიეთ დანიშნულების საქაღალდე. -ქმედება შუთავსებელია მიმდინარე საქაღალდესთან. -ფაილის ან საქაღალდის გადარქმევის შეცდომა -ფაილის ასლის შექმნის დასტური -ნადმვილად გსურთ ფაილების არქივში ჩამატება -6100 -ფაილის წაშლის თანხმობა -საქაღალდის წაშლის თანხმობა -რამდენიმე ფაილის წაშლის თანხმობა -დარწმუნებული ხართ, რომ გინდათ წაშალოთ '{0}'? -დარწმუნებული ხართ, რომ გინდათ წაშალოთ '{0}' საქაღალდე და მთელი მისი შიგთავსი? -დარწმუნებული ხართ, რომ გინდათ წაშალოთ {0} ელემენტები? -იშლება... -ფაილის ან საქაღალდის წაშლის შეცდომა -სისტემას არ შეუძლია გადაიტანოს სანაგვე ყუთში ფაილი მეტისმეტად გრძელი მისამართით. -6300 -საქაღალდის შექმნა -ფაილის შექმნა -საქაღალდის სახელი: -ფაილის სახელი: -ახალი საქაღალდე -ახალი ფაილი -შეცდომა საქაღალდის შექმნისას -შეცდომა ფაილის შექმნისას -6400 -კომენტარი -&კომენტარი: -მონიშვნა -მონიშვნის გაუქმება -ნიღაბი: -6600 -თვისებები -საქაღალდეთა ისტორია -დიაგნოსტიკური შეტყობინება -შეტყობინება -7100 -კომპიუტერი -ქსელი -დოკუმენტები -სისტემა -7200 -დამატება -ამოღება -შემოწმება -ასლი -გადატანა -წაშლა -ცნობები -7300 -ფაილის დაყოფა -&დაიყოფა: -დაიყოს &ტომებად, ზომით (ბაიტებში): -დაყოფა... -დაყოფის დასტური -ნამდვილად გსურთ ფაილის დაყოფა {0} ნაწილად? -ნაწილის ზომა უნდა იყოს საწყისი ფაილის ზომაზე ნაკლები -ნაწილის ზომა მიუღებელია -მითითებული ნაწილის ზომა: {0} ბაიტი.\nნამდვილად გსურთ ასეთი ზომის ნაწილებას დაყოთ ფაილი? -7400 -ფაილების შეერთება -&შეერთება: -შეერთება... -მონიშნეთ დაყოფილი ფაილის მხოლოდ პირველი ნაწილი -როგორც ჩანს, ფაილი არ წარმოადგენს დაყოფილი ფაილის ნაწილს -ვერ მოიზებნა დაყოფილი ფაილის ერთზე მეტი ნაწილი -7500 -საკონტროლო ჯამის დათვლა... -საკონტრლო ჯამის შესახებ -CRC ჯამი მონაცემთათვის: -CRC ჯამი სახელთა და მონაცემთათვის: -7600 -წარმადობის შემოწმება -გამოყენებული მეხსიერება: -შეკუმშვა -გაშლა -შეფასება -საერთო შეფასება -მიმდინარე -შემაჯამებელი -CPU დატვირთვა -შეფას./დატვირთვა -გატარება: diff -Nru p7zip-rar-16.02/GUI/Lang/kaa.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/kaa.txt --- p7zip-rar-16.02/GUI/Lang/kaa.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/kaa.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Atabek Murtazaev -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Karakalpak - Latin -Qaraqalpaqsha - Latın -401 -OK -Biykar etiw - - - -&Awa -&Yaq -&Jabıw -Ja'rdem - -&Dawam etiw -440 -&Barlıg'ına awa -Ba&rlıg'ına yaq -Toqtatıw -Qaytadan baslaw -&Artqı fong'a -Aldıng'ı &fong'a -&Pauza -Pauza qılıng'an -Anıq biykar etiwdi qa'leysizbe? -500 -&Fayl -&Du'zetiw -&Ko'rinis -&Saylandılar -A's&baplar -&Ja'rdem -540 -&Ashıw -&İshinde ashıw -&Sırtında ashıw -&Ko'riw -&Du'zetiw -Atın o'&zgertiw -Bul jerge &nusqasın alıw... -Bul jerge ko'shiriw... -O'shiriw -&Fayldı bo'liw... -Fayllardı &biriktiriw... -Sazlawla&r -Kom&mentariy... -Qadag'alaw summası -Diff -Papka jaratıw -Fayl jaratıw -Sh&ıg'ıw -600 -Barlıg'ın &saylaw -Saylawdı alıp taslaw -Saylawdı &teris awdarıw -Saylaw... -Saylawdı alıp taslaw... -Tu'ri boyınsha saylaw -Tu'ri boyınsha saylawdı alıp taslaw -700 -U'&lken ikonalar -Kishi &ikonalar -&Dizim -&Keste -730 -Ta'rtipsiz -Tegis ko'rinis -&2 panel -&A'sbaplar paneli -Derek papkasın ashıw -Bir da'reje joqarıg'a ko'teriliw -Papkalar tariyxı... -&Jan'alaw -750 -Arxivator knopkalar paneli -Standart knopkalar paneli -U'lken knopkalar -Knopkalar tekstin ko'rsetiw -800 -&Papkanı saylandılarg'a qosıw -Belgi -900 -&Sazlawlar... -&O'nimlilikti tekseriw -960 -&Mazmunı... -&7-Zip haqqında... -1003 -Jol -Atı -Ken'eytpe -Papka -Ko'lemi -Qısılg'andag'ı ko'lemi -Attributları -Jaratılg'an -Ashılg'an -O'zgertilgen -U'ziliksiz -Kommentariy berilgen -Shifrlengen -deyin bo'lingen -keyin bo'lingen -So'zlik -CRC -Tu'ri -Anti -Usıl -Basqarıwshı OS -Fayl sisteması -Paydalanıwshı -Topar -Blok -Kommentariy -Ornı -Jol prefiksi -Papkalar -Fayllar -Versiya -Tom -Ko'p tomlı -Jıljıw -Siltewler -Bloklar -Tomlar - -64-bit -Big-endian -Protsessor -Fizikalıq ko'lemi -Baslama ko'lemi -Qadag'alaw summası -Xarakteristika -Virtual adresi -ID -Qısqa atı -Jaratıwshı bag'darlama -Sektor ko'lemi -Rejim -Siltew -Qa'te -Ulıwma ko'lem -Bos orın -Klaster ko'lemi -Belgi -Jergilikli atı -Provayder -2100 -Sazlawlar -Til -Til: -Redaktor -&Redaktor: -&Diff: -2200 -Sistema -To'mendegi fayllardı 7-Zip penen baylanıstırıw: -2301 -7-Zip ti qabıq kontekst menyuine qosıw -Kaskadlı kontekst menyu -Kontekst menyu elementleri: -2320 - - -Arxivti ashıw -Fayllardı shıg'arıp alıw... -Arxivke qosıw... -Arxivti sınaw -Usı jerge shıg'arıw -Mına jerge shıg'arıw: {0} -Mınag'an qosıw: {0} -Qısıw ha'm email arqalı jiberiw... -Mınag'an qısıw: {0} ha'm email arqalı jiberiw -2400 -Papkalar -&İslewshi papka -&Sistemanın' waqtınshalıq papkası -Ha'zirgi &papka -&Ko'rsetilgen: -Tek alınbalı tasıg'ıshlar ushın paydalanıw -Waqtınshalıq arxiv fayllardın' ornın ko'rsetin'. -2500 -Sazlawlar -".." elementti ko'rsetiw -Fayldın' haqıyqıy ikonaların ko'rsetiw -Sistema menyuin ko'rsetiw -&Tolıq joldı saylaw -Tor &sızıqların ko'rsetiw -Elementti bir basıwdan ashıw -Saylawdın' &alternativ usılı -U'lken &yad betlerin paydalanıw -2900 -7-Zip haqqında -7-Zip bul biypul bag'darlama -3000 -Sistema kerekli bolg'an yad mug'darın ajırata almadı -Qa'te tabılmadı -{0} obekt saylang'an -'{0}' papkasın jaratıw iske aspadı -Bul arxiv ushın jan'alaw operatsiyaları qollanılmaydı. -'{0}' faylın arxiv sıpatında ashıw iske aspadı -Shifrlang'an '{0}' arxivin ashıw iske aspadı. Parol qa'te emespe? -Qollanbaytug'ın arxiv tu'ri -{0} faylı a'lle qashan bar (jaratılg'an) -'{0}' faylı o'zgertilgen.\nOnı arxiv ishinde jan'alawdı qa'leysizbe? -Mına fayldı jan'alaw iske aspadı\n'{0}' -Redaktordı ashıw iske aspadı. -Fayl virusqa uqsaydı (fayl atında uzın bos orınlar qollanılg'an). -Operatsiya uzun jollı papkadan ju'klene almaydı. -Siz bir fayl saylawın'ız kerek -Siz bir yamasa onnan ko'p fayllardı saylawın'ız kerek -Elementler sanı dım ko'p -3300 -Shıg'arılmaqta -Qısılmaqta -Sınaw -Ashılmaqta... -Skanerlenbekte... -3400 -Shıg'arıw -&Bul jerge shıg'arıw: -Shıg'arılatug'ın fayllar ushın orın ko'rsetin'. -3410 -Jol usılı -Tolıq jol atları -Jolsız -3420 -U'stinen jazıw usılı -U'stine jazıwdan aldın soraw -Soramastan u'stine jazıw -Aldınnan bar fayllardı o'tkizip jiberiw -Avtomat ta'rizde qayta at beriw -Aldınnan bar fayllarg'a avtomat ta'rizde qayta at beriw -3500 -Fayldın' u'stinen jazıwdı tastıyqlaw -Tayınlang'an papka a'lle qashan islengen fayldı o'z ishine alg'an. -Siz bar fayldı -mına fayl menen almastırıwdı qa'leysizbe? -{0} bayt -A&vtomat ta'rizde qayta at beriw -3700 -'{0}' faylı ushın tanıs bolmag'an qısıw usılı. -'{0}' faylında mag'lıwmat qa'tesi tabıldı. Fayl buzılg'an. -'{0}' faylında CRC qa'tesi tabıldı. Fayl buzılg'an. -'{0}' shifrlang'an faylında mag'lıwmat qa'tesi tabıldı. Parol qa'te emespe? -'{0}' shifrlang'an faylında CRC qa'tesi tabıldı. Parol qa'te emespe? -3800 -Paroldi kiritiw -Paroldi kiritin': -Paroldi qayta kiritin': -Paroldi &ko'rsetiw -Paroller sa'ykes kelmedi -Parol ushın tek latın a'lipbesi ha'riplerin, sanlar ha'm arnawlı simvollardı (!, #, $, ...) paydalanın' -Parol dım uzın -Parol -3900 -O'tken waqıt: -Qalg'an waqıt: -Tolıq ko'lem: -Tezlik: -İslengen ko'lem: -Qısıw da'rejesi: -Qa'teler: -Arxivler: -4000 -Arxivke qosıw -&Arxiv: -&Jan'alaw usılı: -Arxiv &formatı: -Qısıw &da'rejesi: -Qısıw &usılı: -&So'zlik ko'lemi: -So'z &ko'lemi: -Blok ko'lemi: -CPU ag'ımlar sanı: -&Parametrler: -Sazlawlar -SF&X arxivin jaratıw -Jazıw ushın ashılg'an fayllardı qısıw -Shifrlaw -Shifrlaw usılı: -Fayl a&tların shifrlaw -Qısıwg'a arnalg'an yad: -Ajıratıwg'a arnalg'an yad: -4050 -Qısıwsız -En' tez -Tez -Qa'dimgi -En' joqarı -Ultra -4060 -Fayllardı qosıw ha'm almastırıw -Fayllardı jan'alaw ha'm qosıw -Bar fayllardı jan'alaw -Fayllardı sinxronlastırıw -4070 -Belgilew -Barlıq fayllar -Fayl ko'lemi boyınsha -U'ziliksiz -6000 -Nusqasın alıw -Ko'shiriw -Mına papkag'a nusqasın alıw: -Mına papkag'a ko'shiriw: -Nusqa alınbaqta... -Ko'shirilmekte... -Qayta at berilmekte... -Papkanı saylan'. -Ko'rsetilgen operatsiya bul papka ushın qollanılmaydı. -Fayl yaki papkag'a qayta at beriwde qa'te ju'z berdi -Fayldın' nusqasın alıwdı tastıyqlan' -Siz bul fayllardı anıq arxivke ko'shiriwdi qa'leysizbe -6100 -Fayl o'shiriliwin tastıyqlaw -Papka o'shiriliwin tastıyqlaw -Fayllar toparının' o'shiriliwin tastıyqlaw -'{0}' degendi anıq o'shiriwdi qa'leysizbe? -'{0}' papkası ha'm onın' ishindegilerdi anıq o'shiriwdi qa'leysizbe? -Bul obektlerdi ({0} dana) anıq o'shiriwdi qa'leysizbe? -O'shirilmekte... -Fayl yaki papkanı o'shiriwde qa'te ju'z berdi -Sistema uzın jollı fayllardı sebetke ko'shire almaydı -6300 -Papka jaratıw -Fayl jaratıw -Papka atı: -Fayl atı: -Jan'a papka -Jan'a fayl -Papkanı jaratıwda qa'te ju'z berdi -Fayldı jaratıwda qa'te ju'z berdi -6400 -Kommentariy -&Kommentariy: -Saylaw -Saylawdı alıp taslaw -Maska: -6600 -Sazlawlar -Papkalar tariyxı -Diagnostik xabarlar -Xabar -7100 -Kompyuter -Tarmaq -Hu'jjetler -Sistema -7200 -Qosıw -Shıg'arıw -Sınaw -Nusqa alıw -Ko'shiriw -O'shiriw -Mag'lıwmat -7300 -Fayldı bo'liw -&Mınag'an bo'liw: -Tomlarg'a &bo'liw (baytlarda): -Bo'linbekte... -Bo'liwdi tastıyqlan' -Siz fayldı {0} bo'lekke anıq bo'liwdi qa'leysizbe? -Bo'lek ko'lemi original fayl ko'leminen kishi bolıwı kerek -Tom ko'lemi natuwrı berilgen -Tomnın' ko'rsetilgen ko'lemi: {0} bayt.\nArxivti bunday tomlarg'a anıq bo'liwdi qa'leysizbe? -7400 -Fayllardı biriktiriw -&Mınag'an biriktiriw: -Biriktirilmekte... -Bo'lingen fayldın' tek birinshi bo'legin saylaw kerek -Fayl bo'lingen fayldın' bo'legi retinde tanılmadı -Bo'lingen fayldın' birden ko'p bo'legi tabılmadı -7500 -Qadag'alaw summasın esaplaw... -Qadag'alaw summası mag'lıwmatı -Mag'lıwmatlar ushın CRC qadag'alaw summası: -Mag'lıwmatlar ha'm atamalar ushın CRC qadag'alaw summası: -7600 -O'nimlilikti tekseriw -Yad ko'lemi: -Qısıw -Ajıratıw -Reyting -Ulıwma reyting -Ha'zirgi -Ja'mi -Awırlıq -Reyting / Awır. -O'tkenler: diff -Nru p7zip-rar-16.02/GUI/Lang/kk.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/kk.txt --- p7zip-rar-16.02/GUI/Lang/kk.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/kk.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Arslan Beisenov, Arman Beisenov -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Kazakh -Қазақша -401 -Жарайды -Болдырмау - - - -&Иә -&Жоқ -&Жабу -Анықтама - -&Жалғастыру -440 -Бәріне &ия -Бәріне &жоқ -Тоқтату -Қайта іске қосу -&Фонды -&Алдыңғы жоспарға -&Үізілс -Үзілісте -Операцияны тоқтату керек пе? -500 -&Файл -&Өңдеу -&Көрініс -&Таңдаулы -С&ервис -&Анықтама -540 -&Ашу -Ішінен &ашу -Сыртынан ашу -Қарау -&Өңдеу -Қайта атау -&Көшіру... -&Жылжыту... -&Жою -Файлды бөлшектеу... -Файлды біріктіру... -Сипаттар -Комме&нтарий... -Бақылау сомасы -Diff -&Қалта жасау -Файл жасау -Шығу -600 -Бәрін ерекшелеу -Ерекшелеуді аластау -&Ерекшелеуді көрсету -Ерекшелеу... -Ерекшедеужі аластау... -Түрі б-ша ерекшелеу -Түрі б-ша ерекшелеуді аластау -700 -&Үлкен таңбаша -&Кішк. таңбаша -Тізім -&Кесте -730 -Сұрыптаусыз -Жалпақ режим -&2 тақта -&Құралдар тақтасы -Негізгі қалтады ашу -Бір деңгей жоғары өту -Қалта тарихы... -Жаңарту -750 -Мұрағаттауыш батырма тақтасы -Батырманың кәдімгі тақтасы -Үлкен батырмалар -Батырмада жазулар -800 -Қалтаны таңдаулыға басқаша үстеу -Таңдаулы -900 -Баптау... -Өнімді тестілеу -960 -&Басты... -Бағдарламада... -1003 -Жол -Аты -Кеңейтімі -Қалта -Көлем -Сығылған -Атрибут -Жасалған -Ашылған -Өзгерген -Үзіліссіз -Комментарий -Шифрланған -дейін бөлінген -кейін бөлінген -Сөздік -CRC -Түрі -Анти -Тәсіл -Жүйе -Файлдық жүйе -Пайдаланушы -Топ -Блок -Комментарий -Орны -Жолы -Қалта -Файл -Нұсқа -Том -Көп томды -Жылжу -Сілтеме -Блок -Том - -64-bit -Big-endian -Процессор -Физикалық көлемі -Тақырып көлемі -Бақылау сомасы -Характеристика -Виртуальды мекен-жай -ID -Қысқа аты -Жасаушы -Сектор көлемі -Режим -Сілтеме -Қателік -Сыйымы -Бос -Кластер көлемі -Белгі -Жергілікті аты -Провайдер -2100 -Баптау -Тіл -Тіл: -Өңдегіш -&Өңдегіш: -&Diff: -2200 -Жүйе -7-Zip файлмен ассорциялау: -2301 -Мұқабаның мәтінміндің мәзіріне 7-Zip қою -Каскадты мәтінмәндік мәзір -Мәтінміндік мәзірдің элементтері: -2320 -<Қалта> -<Мұрағат> -Мұрағат ашу -Бумадан шешу -Мұрағатқа үстеу... -Тестілеу -Мұнда шешу -{0} дегенде шешу -{0} дегенге үстеу -Сығып э-поштамен жіберу... -{0} дегенде сығып, э-поштамен жіберу -2400 -Қалта -&Жұмыс қалтасы -&Жүйелік уақытша қалта -&Ағымдық -&Сұрау: -Тек алмалы тасығыштарға ғана пайдалану -Уақытша мұрағаттардың орнын нұсқаңыз. -2500 -Баптау -".." элементті көрсету -Файлдың шынайы таңбашасын көрсету -Жүйелік мәзірді көрсету -Барлық жолаққа меңзер -Бөлгіштерді көрсету -Бір шерткеннен ашу -Белгілеудің альтернативті режимі -Жадтың үлкен беттерін пайдалану -2900 -7-Zip туралы -7-Zip - тегін таратылатын бағдарлама. -3000 -Бос жад жоқ -Қателік табылған жоқ -Ерекшеленген нысан: {0} -'{0}' қалтасын жасау мүмкін емес -Көтермейтін мұрағат үшін операция өзгертіледі. -'{0}' файлды мұрағат ретінде ашу мүмкін емес -Шифрланған '{0}' мұрағатты ашу мүмкін емес. Кілтсөз дұрыс емес пе? -Көтермейтін мұрағат түрі -{0} деген файл бар -'{0}' файлы өзгерді.\nОны мұрағатта жаңарту керек пе? -\n'{0}' файлды жаңарту мүмкін емес -Өңдегішті ашу мүмкін емес -Файл вирусқа ұқсайды (файл аты ұзақ жолды мәселені құрайды). -Операция қалтаға жолдың ұзақтығынан орындалмайды -Сізге бір файл таңдау керек -Сізге бір не бірнеше файл таңдау керек -Өте көп элемент -3300 -Шешу -Компрессия -Тестілеу -Ашылу... -Сканерлеу... -3400 -Шығару -&Мұнда шешу: -Шығарылатын файл орнын нұсқаңыз. -3410 -Жолдар -&Толық жол -&Жолсыз -3420 -Қайта жазу -&Растаумен -&Растаусыз -Өткізіп &жіберу -Автоматты қайта атау. -Бар файлды автом. қайта атау -3500 -Файлды ауыстыру растау -Қалтада іс жүргізілетін файл бар. -Файлды ауыстыру -келесі файлмен ба? -{0} байт -Автоматты қайта атау -3700 -'{0}' файлы үшін сығу әдісін көтермейді. -'{0}' мәліметінде қателік. Файл зақымдалған. -'{0}' CRC қателік. Файл зақымдалған. -Шифрланған '{0}' файлында мәліміт қате. Кілтсөз дұрыс емес пе? -Шифрланған '{0}' файлында CRС қате. Кілтсөз дұрыс емес пе? -3800 -Кілтсөзді енгізу -&Кілтсөзді енгізіңіз: -&Кілтсөзді қайталаңыз: -&Кілтсөзді көрсету -Кілтсөздер сәйкес емес -Кілтсөзге тек ағылшын әліпбиін пайдаланыңыз, сандар және арнайы нышандар (!, #, $, ...) -Кілтсөз өте ұзақ -&Кілтсөз -3900 -Өтті: -Қалды: -Барлығы: -Жылд.: -Көлем: -Сығу дәрежесі: -Қате: -Мұрағат: -4000 -Мұрағатқа үстеу -&Мұрағат: -&Өзгерту режимі: -&Мұрағат пішімі: -&Сығу деңгейі: -&Сығу тәсілі: -Сөздік &көлемі: -Сөз &көлемі: -Блог көлемі: -Ағым саны: -&Параметр: -&Баптау -SF&X-мұрағат жасау -Ашылған файд жазу үшін сығу -Шифрлау -Шифрлау тәсілі: -&Файлдың атын шифрлау -Бууға арналған көлем: -Шешуге арналған көлем: -4050 -Сығусыз -Жылдам -Шапшаң -Кәдімгі -Ең жоғарғы -Ультра -4060 -Үстеу, ауыстыру -Жаңарту, үстеу -Жаңату -Теңестіру -4070 -Сапыру -Барлық файл -Файл көлемі б-ша -Үзіліссіз -6000 -Көшіру -Жылжыту -Мұнда көшіру: -Мұнда жылжыту: -Көшіру... -Жылжыту... -Атын өзгерту... -Қалтаны нұсқаңыз -Бұл қалтаға операция көтермейді. -Файл не қалтаның атын өзгерту мүмкін емес -Файлды көшіруді растау -Мына файлдарды мұрағатқа көшіру керек пе -6100 -Файлды жоюды растау -Қалтаны жоюды растау -Бірнеше файлды жоюды растау -"{0}" дегенді жою керек пе? -"{0}" қалтасын және оның ішіндегілерін жою керек пе? -({0} дана) нысандарды жою керек пе? -Жойылу... -Файл не қалтаны жою қате -Ұзақ жолды файлдарды себетке жоюды жүйе көтермейді -6300 -Қалта жасау -Файл жасау -Қалта аты: -Файл аты: -Жаңа қалта -Жаңа файл -Қалтаны жасау қате -Файлды жасау кезінде қателік болды -6400 -Комментарий -&Комментарий: -Ерекшелеу -Аластау -Маска: -6600 -Сипаттар -Қалта тарихы -Хабарлама -Хабарлама -7100 -Компьютер -Желі -Құжаттар -Жүйе -7200 -Үстеу -Шығару -Тестілеу -Көшіру -Жылжыту -Жою -Ақпарат -7300 -Файлды бөлшектеу -&Бөлшектеу: -Томға бөлшектеу (байтқа): -Бөлшектеу... -Бөлшектеуді растау -Файлд {0} бөлікке бөлшектеу керек пе? -Том көлемі файлдың кіріс көлемінен аз болу керек -Томның көлемін енгізу қате -Томның орнатылған көлемі: {0} байт.\nМұрағатты томға бөлшектеу керек пе? -7400 -Файлдарды біріктіру -&Мұнда біріктіру: -Біріктіру... -Бөлшектенген файлдың бірінші бөлігін таңдау керек -Бөлшектенген файлды тану мүмкін емес -Бөлшектенген файлдың бөліктерін табу мүмкін емес -7500 -Бақылау сомасын есептеу... -Бақылау сомасы -Мәлімет үшін CRC бақылау сомасы: -Мәлімет және атау үшін CRC бақылау сомасы: -7600 -Өнімділікке тестілеу -Жад көлемі: -Буу -Шешу -Рейтинг -Жалпы рейтинг -Ағымдық -Нәтижесі -Ауырлық -Рейтинг / Жеңіс. -Өтулер: diff -Nru p7zip-rar-16.02/GUI/Lang/ko.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ko.txt --- p7zip-rar-16.02/GUI/Lang/ko.txt 2016-02-03 05:05:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ko.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : ZannyLim (임재형) -; : bzImage -; 4.52 : Hyeong il Kim (kurt Sawyer) -; 9.07 : Dong-yoon Han (한동윤) -; 15.12 : Winterscenery (Ji-yong BAE) -; -; -; -; -; -; -0 -7-Zip -Korean -한국어 -401 -확인 -취소 - - - -예(&Y) -아니오(&N) -닫기(&C) -도움말 - -계속(&C) -440 -모두 예(&A) -모두 아니오(&L) -중지 -다시 시작 -낮은 순위로(&B) -우선 순위로(&F) -일시정지(&P) -일시정지 됨 -정말로 취소하시겠습니까? -500 -파일(&F) -편집(&E) -보기(&V) -즐겨찾기(&A) -도구(&T) -도움말(&H) -540 -열기(&O) -내부 열기(&I) -외부 열기(&U) -파일 뷰어(&V) -편집(&E) -새 이름(&M) -복사(&C)... -이동(&M)... -삭제(&D) -파일 나누기(&S) -파일 합치기(&B) -속성(&R) -설명(&N) -체크섬 계산 -파일 비교 -폴더 만들기 -파일 만들기 -끝내기(&X) -링크... -대체 데이터 스트림(&A) -600 -모두 선택(&A) -모두 선택 취소 -선택 항목 반전(&I) -선택... -선택 취소... -파일 형식으로 선택 -파일 형식으로 선택 취소 -700 -큰 아이콘(&G) -작은 아이콘(&M) -목록(&L) -자세히(&S) -730 -정렬 안함 -펼쳐 보기 -2 패널(&2) -도구 모음(&T) -최상위 폴더 열기 -한단계 위로 -폴더 히스토리... -새로 고침(&R) -자동 새로 고침 -750 -압축 도구 모음 -표준 도구 모음 -큰 버튼 -버튼 텍스트 보기 -800 -즐겨찾기에 추가(&A) -북마크 -900 -옵션(&P)... -벤치마크(&B)... -960 -도움말 항목(&C)... -7-Zip 정보(&A)... -1003 -경로 -이름 -확장자 -폴더 -크기 -압축된 크기 -속성 -만든 날짜 -액세스한 날짜 -수정한 날짜 -솔리드 -설명 -암호화 -나누기 이전 -나누기 후 -사전 -CRC -형식 -안티 -압축 방식 -생성한 OS -파일 시스템 -사용자 -그룹 -블럭 -설명 -위치 -경로 접두 -폴더 -파일 -버전 -볼륨 -다중볼륨 -오프셋 -링크 -블록 -볼륨 - -64-bit -Big-endian -CPU -물리적 크기 -해더 크기 -체크섬 -특성 -가상 주소 -ID -짧은 이름 -생성자 응용프로그램 -섹터 크기 -모드 -연결 -오류 -전체 크기 -여유 공간 -클러스터 크기 -라벨 -로컬 이름 -제공자 -NT 보안 -대체 데이터 스트림 -Aux -Deleted -Is Tree - - -오류 유형 -오류 -오류 -경고 -경고 -스트림 -대체 데이터 스트림 -대체 데이터 스트림 크기 -가상 크기 -압축 해제 후 크기 -용량 실제 크기 -볼륨 인덱스 -SubType -Short Comment -코드 페이지 - - - -Tail Size -Embedded Stub Size -Link -Hard Link -iNode - -읽기 전용 -2100 -옵션 -언어 -언어: -편집기 -파일 편집기(&E): -파일 비교(&D): -2200 -시스템 -7-Zip 으로 연결: -모든 사용자 -2301 -7-Zip 탐색기 메뉴 사용 -탐색기 메뉴 계단식 보기 -탐색기 메뉴 항목: -탐색기 메뉴 아이콘 보기 -2320 -<폴더> -<압축파일> -압축파일 열기 -압축 풀기... -압축파일에 추가... -압축파일 테스트 -여기에 압축 풀기 -{0}에 풀기 -{0}에 추가 -압축해서 이메일 보내기 -{0}로 압축해서 이메일 보내기 -2400 -폴더 -작업 폴더(&W) -시스템 임시 폴더(&S) -현재 폴더(&C) -지정 폴더(&S): -이동식 드라이브에서만 사용 -압축에 관계된 파일이 임시적으로 사용할 위치 지정. -2500 -설정 -".." 항목 보기 -실제 파일 아이콘 보기 -시스템 메뉴 보기 -행 전체 선택(&F) -눈금선 보기(&G) -한 번 클릭으로 항목 열기 -대체 선택 모드 -큰 메모리 페이지 사용 -2900 -7-Zip 정보 -7-Zip 은 무료 소프트웨어입니다. -3000 -시스템이 필요한 양의 메모리를 할당할 수 없음 -오류 없음 -{0} 항목이 선택됨 -'{0}' 폴더를 생성할 수 없음 -업데이트 작업이 이 압축파일에서는 지원되지 않습니다. -파일 '{0}'을(를) 압축파일로 열 수 없음 -암호화된 압축파일 '{0}'을(를) 열 수 없습니다. 암호가 틀리나요? -지원되지 않는 압축파일 유형 -{0} 파일은 이미 존재함 -파일 '{0}'이 수정되었습니다.\n압축파일에 업데이트 하시겠습니까? -'{0}' 파일을 업데이트 할 수 없습니다. -편집기를 시작할 수 없습니다. -해당 파일이 바이러스 같습니다 (파일 이름에 길다란 공백이 들어있음). -긴 경로로된 폴더에서 해당 작업을 호출할 수 없습니다. -반드시 한 개의 파일을 선택해야함 -반드시 한 개 이상의 파일을 선택해야 함 -항목이 너무 많음 -Can not open the file as {0} archive -The file is open as {0} archive -The archive is open with offset -3300 -압축 푸는 중 -압축하는 중 -검사 중 -여는 중... -검색 중... -삭제 중 -3320 -추가 중 -업데이트 중 -분석 중 -복제 중 -다시 압축 중 -스킵 중 -삭제 중 -헤더 작성 중 -3400 -압축 풀기 -압축 풀기(&X): -압축 풀린 파일의 위치를 지정합니다. -3410 -경로 모드 -전체 경로명 -경로명 없음 -절대 경로명 -상대 경로명 -3420 -덮어쓰기 모드 -덮어쓰기 전에 물어봄 -물어보지 않고 덮어쓰기 -존재하는 파일 건너뛰기 -자동으로 이름 바꾸기 -존재하는 파일 이름 바꾸기 -3430 -최상위 폴더의 중복을 방지 -파일 보안 속성을 복원 -3500 -파일 교체시 확인 -대상 폴더에 이미 파일이 존재합니다. -존재하는 파일을 -이것으로 교체하시겠습니까? -{0} 바이트 -자동으로 이름 바꾸기(&U) -3700 -'{0}'은 지원하지 않는 압축 방식입니다. -'{0}'에 데이터 오류가 있습니다. 파일이 손상되었습니다. -'{0}'의 CRC 검사를 실패했습니다. 파일이 손상되었습니다. -암호화 파일 '{0}'에 데이터 오류가 있습니다. 암호가 틀리나요? -암호화 파일 '{0}'의 CRC 검사를 실패했습니다. 암호가 틀리나요? -3710 -잘못 입력된 암호? -3721 -지원하지 않는 압축 방법 -데이터 오류 -CRC가 다릅니다 -데이터 검색 실패 -데이터 부족 -There are some data after the end of the payload data -압축 파일이 아닙니다. -헤더 오류 -암호가 잘못되었습니다. -3763 -Unavailable start of archive -Unconfirmed start of archive - - - -지원하지 않는 기능 -3800 -암호 입력 -암호 입력: -암호 다시 입력: -암호 보기(&S) -암호가 일치하지 않음 -암호로는 영문자, 숫자 그리고 특수 문자 (!, #, $, ...)만 사용 -패스워드가 너무 김 -암호 -3900 -경과 시간: -남은 시간: -전체 크기: -속도: -처리됨: -압축 효율: -오류: -압축파일: -4000 -압축파일에 추가 -압축파일(&A): -업데이트 모드(&U): -압축파일 형식(&F): -압축 레벨(&L): -압축 방식(&M): -사전 크기(&D): -단어(word) 크기(&W): -솔리드 블록 크기: -CPU 스레드 수: -매개변수(&P): -옵션 -자동(SFX) 압축파일 생성(&X) -공유하고있는 파일 압축 -암호화 -암호화 방식: -파일 이름 암호화(&N) -압축시 사용 메모리: -압축 풀기시 사용 메모리: -압축 후 원본 파일을 삭제 -4040 -심볼릭 링크를 저장 -하드 링크를 저장 -대체 데이터 스트림을 저장 -파일 보안 속성을 저장 -4050 -저장 -가장 빠름 -빠름 -보통 -최고 -가장 느림 -4060 -파일을 추가하고 교체 -파일을 업데이트하고 추가 -존재하는 파일만 새롭게 하기 -압축파일 내용을 동기화 -4070 -찾아보기 -모든 파일 -솔리드 사용 않함 -솔리드 -6000 -복사 -이동 -폴더로 복사: -폴더로 이동: -복사 중... -이동 중... -이름 바꾸는 중... -대상 폴더를 선택하세요. -지원되지 않는 작업입니다. -파일 또는 폴더 이름 바꾸기 실패 -파일 복사 확인 -파일을 압축파일로 복사 하시겠습니까? -6100 -파일 삭제 확인 -폴더 삭제 확인 -여러 파일 지우기 확인 -'{0}'을(를) 삭제하시겠습니까? -폴더 '{0}'와 그 모든 내용을 삭제하시겠습니까? -이 {0} 항목들을 삭제하시겠습니까? -삭제 중... -파일 또는 폴더 삭제 실패 -시스템이 긴 경로의 파일을 휴지통으로 이동할 수 없음 -6300 -폴더 만들기 -파일 만들기 -폴더 이름: -파일 이름: -새 폴더 -새 파일 -폴더 만들기 오류 -파일 만들기 오류 -6400 -설명 -설명(&C): -선택 -선택 취소 -마스크: -6600 -속성 -폴더 히스토리 -진단 메시지 -메시지 -7100 -컴퓨터 -네트워크 -문서 -시스템 -7200 -추가 -압축 풀기 -테스트 -복사 -이동 -삭제 -정보 -7300 -파일 분할하기 -분할하기(&S): -볼륨 나누기, 바이트(&V): -분할하는 중... -분할 확인 -정말 {0} 볼륨들로 분할 하시겠습니까? -볼륨 크기가 원본 파일보다 작아야만 합니다. -볼륨 크기가 부적절합니다. -지정된 볼륨 크기: {0} 바이트.\n이 볼륨 크기로 분할 하시겠습니까? -7400 -파일 합치기 -합치기(&B): -파일 합치는 중... -첫번째 파일만 선택하시오 -분할한 파일의 한 부분으로 인식할 수 없음 -분할 파일의 한 부분 이상을 찾을 수 없음 -7500 -체크섬 계산중... -체크섬 정보 -데이터용 CRC 체크섬: -데이터와 이름용 CRC 체크섬: -7600 -벤치마크 -메모리 사용량: -압축 중 -압축 푸는 중 -평가 -전체 평가 -현재 -결과 -CPU 사용량 -평가 / 사용량 -통과: -7700 -링크 -링크 만들기 -원본: -링크: -7710 -링크 유형 -하드 링크 -파일의 심볼릭 링크 -디렉토리의 심볼릭 링크 -디렉토리 접합 diff -Nru p7zip-rar-16.02/GUI/Lang/ku-ckb.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku-ckb.txt --- p7zip-rar-16.02/GUI/Lang/ku-ckb.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku-ckb.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Ara Bakhtiar -; 4.66 : Ara Qadir : http://www.chawg.org -; -; -; -; -; -; -; -; -; -0 -7-Zip -Kurdish - Sorani -کوردی -401 -باشە -پاشگەزبوونەوە - - - -&بەڵێ -&نەخێر -&داخستن -یارمەتی - -&بەردەوامبوون -440 -بەڵێ بۆ &هەموو -نەخێر بۆ هە&موو -وەستاندن -دەستپێکردنەوە -&پاشەبنەما -پ&ێشەبنەما -&ڕاگرتن -ڕاگیردرا -دڵنیایت لە پاشگەزبوونەوە؟ -500 -&فایل -&دەستکاری -&بینین -د&ڵخوازەکان -&ئامڕازەکان -&یارمەتی -540 -&کردنەوە -کردنەوە لە&ناو خۆدا -کردنەوە لە &دەرەوە -&بینین -&دەستکاری -&ناوگۆڕین -&لەبەرگرتنەوە بۆ... -&گواستنەوە بۆ... -&سڕینەوە -&لەتکردنی پەڕگە... -&پێکەوە لکاندنی پەڕگەکان... -&تایبەتمەندییەکان -ل&ێدوان -ژماردنی checksum - -دروستکردنی بوخچە -دروستکردنی پەڕگە -دەر&چوون -600 -هەمووی دیاری بکە -هەموو دیاریکراوەکان لاببە -%پێچەوانەکردنەوەی دیاریکراو -دیاری بکە... -دیاری مەکە... -بە پێی جۆر دیاری بکە -لابردنی دیاریکراوەکان بەپێ جۆر -700 -ئایکۆنی &گەورە -ئایکۆنی &بچوک -&لیست -&وردەکاری -730 -ڕیزنەکراو -بینین بەشێوەی فلات -&2 پانێڵ -&جێ ئامڕاز -کردنەوەی بوخچەی ڕەگ -یەک ئاست بۆ سەرەوە -مێژووی بوخچەکان... -&بووژاندنەوە -750 -جێ ئامڕازی ئەرشیڤ -جی ئامڕازی بنچینە -دوگمەی گەورە -پیشاندانی دەقی دوگمەکان -800 -&زیادکردنی بوخچە بۆ دڵخوازەکان وەک -دڵخوازی -900 -&هەڵبژاردنەکان -&نیشانەی پێوان -960 -&ناوەڕۆکەکان... -&دەربارەی 7-Zip... -1003 -ڕێڕەو -ناو -پاشگر -بوخچە -قەبارە -قەبارەی پێچراو -تایبەتمەندی -دروستکراوە -بینراوە -دەستکاریکراوە -ڕەق -لێدوانی لەسەر دراوە -پارێزراو -لەتکردن پێش -لەتکردن پاش -فەرهەنگ -CRC -جۆر -دژ -ڕێباز -سیستەمی خانەخوێ -سیستەمی پەڕگە -بەکارهێنەر -گوروپ -بلۆک -لێدوان -جێگە -ـی ڕێڕەو Prefix -بوخچەکان -پەڕگەکان -وەشان -قەبارەکان -فرە قەبارە -Offset -بەستەرەکان -بلۆکەکان -قەبارەکان - -٦٤-بت -Big-endian -CPU -قەبارەی فیزیکی -قەبارەی سەر -کۆپشکنین -تایبەتمەندی -ناونیشانی ڕاستی - - - - - - -هەڵە -سەرجەمی قەبارە -بۆشایی بەتاڵ -قەبارەی کۆمەڵەکە -نیشان -ناوی ناوخۆیی -دابینکەر -2100 -ەەڵبژاردنەکان -زمان -زمان: -دەستکاریکەر -&دەستکاریکەر: - -2200 -سیستەم -7-Zip پەیوەست بکە بە: -2301 -7-Zip بکە نێو لیستەی مێنیوەوە -مێنیو بکە بە یەک هاوپۆل -کەرەستەکانی نێو مێنیو: -2320 -<بوخچە> -<ئەرشیڤ> -کردنەوەی ئەشیڤ -دەرکێشانی پەڕگەکان -زیادکردن بۆ ئەرشیڤ -تاقیکردنەوەی ئەرشیڤ -لێرە دەریبکێشە -دەرکێشان بۆ {0} -زیادکردنی بۆ {0} -پەستاندن و پەیامی ئەلیکترۆنی... -بیپەستێنە بۆ {0} و بە پەیامی ئەلیکترۆنی بینێرە -2400 -بوخچەکان -بوخچەی &کارکردن -بوخچەی کاتی &سیستەم -&ئێستایی -&دیاریکراو: -تەنها بۆ ئەو وەگەڕخەرانە بەکاری بهێنە کە توانای لابردنیان هەیە (removable disk) -شوێنێک دیاری بکە بۆ پەڕگە کاتییەکانی ئەرشیڤ. -2500 -ڕێکخستەکان -شتەکانی ".." پیشانبدە -ئایکۆنی ڕاستەقینەی پەڕگەکان پیشانبدە -مێنیوی سیستەم پیشانبدە -دیاریکردنی هەموو &ڕیزەکە -پیشاندانی هێڵە &grid ـەکان - -جۆری دیاریکردنی &جێگرەوە/ ئەڵتەرناتیڤ -پەڕەی بیرگەی &گەورە بەکارببە -2900 -7-Zip دەربارەی -7-Zip پڕۆگرامێکی خۆڕایە. لەگەڵ ئەوەشدا، ئەتوانی پاڵپشت بیت لە پەرەپێدانی 7-Zip. -3000 -سیستەم ناتوانێت بڕی پێویست لە بیرگە دابین بکات -هیچ هەڵەیەک نییە -{0} شت دیاریکراوە -ناتوانرێ بوخچەی '{0}' دروستبکرێت. -کارپێکردنی نوێکاری پاڵپشت نەکراوە بۆ ئەم ئەرشیڤە. -ناتوانرێت پەڕگەی '{0}' بکرێتەوە وەک ئەرشیڤ. -ناتوانرێت ئەرشیڤی پارێزراوی '{0}' بکرێتەوە. ئایا تێپەڕەوشە هەڵەیە؟ -جۆری ئەرشیڤ پاڵپشتی نەکراوە -پەڕگەی {0} پێشتر ەەیە -پەڕگەی '{0}' دەستکاریکراوە. ئەتەوێت لە ئەرشیڤەکەدا نوێی بکەیتەوە؟ -ناتوانرێ پەڕگەی \n'{0}' نوێبکرێتەوە -ناتوانرێ دەستکاریکەر دەستپێبکرێت. -پەڕگەکە لە ڤایرۆس دەچێت (ناوی پەڕگەکە بۆشایی زۆری تیادایە). -ناتوانرێت ئەو کردارە بانگبکرێت لە بوخچەیەکەوە کە ڕێڕەوێکی درێژی ەەیە. -پێویستە پەڕگەیەک دیاریبکەیت -پێویستە پەڕگەیەک یان زیاتر دیاریبکەیت -شتی(item) زۆر هەن -3300 -دەری دەکێشێ -دەی پەستێنێ... -تاقیدەکاتەوە -دەیکاتەوە... -دەی پشکنێت... -3400 -دەرکێشان -&دەرکێشان بۆ: -شوێنێک دیاری بکە بۆ پەڕگە دەرکێشراوەکان -3410 -جۆری ڕێڕەو -ناوی ڕێڕەوی تەواوەتی -ناوی ڕێڕەو نییە -3420 -جۆری بەسەردا نووسینەوە -بپرسە پێش بەسەردا نووسینەوە -بەسەردا بنووسەوە بەبێ ڕەزامەندی -پەڕگە هەبووەکان بپەڕێنە -خۆکار ناوگۆڕین -خۆکار ناوگۆڕینی پەڕگە هەبووەکان -3500 -دڵنیابە لە جێگرتنەوەی پەڕگە -بوخچەی مەبەست پەڕگەیەکی تیادایە بە هەمان ناو. -ئەتەوێت پەڕگە هەبووەکان جێبگیردرێتەوە؟ -لەگەڵ ئەم دانەیە؟ -{0} بایت -ناوگۆڕینی &خۆکار -3700 -ڕێبازێکی پاڵپشتی نەکراوی پەستاندن بۆ '{0}'. -زانیاری '{0}' هەڵەیە. پەڕگە تێکشکاوە. -CRC سەرکەوتوو نەبوو. پەڕگە تێکشکاوە. -زانیاری هەڵەیە لە پەڕگەی پارێزراودا '{0}'. ئایا تێپەڕەوشە هەڵەیە؟ -CRC هەڵەیە لە پەڕگەی پارێزراودا '{0}'. ئایا تێپەڕەوشە هەڵەیە؟ -3800 -نووسینی تێپەڕەوشە: -تێپەڕەوشە بنووسە: -تێپەڕەوشە بنووسەوە: -&پیشاندانی تێپەڕەوشە -تێپەڕەوشەکان وەک یەک نین -تەنها پیتە ئینگلیزییەکان، ژمارە و نووسە تیبەتییەکان ($، %، #) بۆ تێپەڕەوشە بەکاربهێنە -تێپەڕەوشە زۆر درێژە -تێپەڕەوشە -3900 -ک. دەستپێکردوو: -کاتی ماوە: -سەرجەمی قەبارە: -خێرایی: -جێبەجێکراوە: -ڕێژەی پەستاندن: -هەڵەکان: -ئەرشیڤەکان: -4000 -زیادکردن بۆ ئەرشیڤ -&ئەرشیڤ: -&جۆری نوێکاری: -&فۆڕماتی ئەرشیڤ: -&ئاستی پەستاندن: -&ڕێبازی پەستاندن: -قەبارەی &فەرەەنگ: -قەبارەی &وشە: -قەبارەی بلۆکی ڕەق: -ژمارەی دەزووەکانی CPU: -&هاوکۆڵکەکان: -هەڵبژاردنەکان -دروستکردنی ئەرشیڤی SF&X -پەستاندنی پەڕگە ئاڵوگۆڕکراوەکان -پاراستن -ڕێبازی پاراستن -&ناوی پەڕگەکان بپارێزە (encrypt) -ڕێژەی بەکارهێنانی بیرگە بۆ پەستاندان: -ڕێژەی بەکارهێنانی بیرگە بۆ کردنەوەی پەستێنراو: -4050 -پاشەکەوت -خێراترین -خێرا -ئاسایی -زۆرترین -سەروو -4060 -زیادکردن و جێگرتنەوەی پەڕگەکان -نوێکردنەوە و زیادکردنی پەڕگە -بووژاندنەوەی پەڕگە هەبووەکان -ـکردنی پەڕگەکان Synchronize -4070 -هەڵدەوە/ Browse -هەموو پەڕگەکان -نا-ڕەق -ڕەق -6000 -لەبەرگرتنەوە -گواستنەوە -لەبەرگتنەوە بۆ: -گواستنەوە بۆ: -لەبەری دەگرێتەوە... -دەیگوازێتەوە بۆ... -ناوی دەگۆڕێ... -بوخچەی مەبەست دیاری بکە. -ئەو کارە پاڵپشتی نەکراوە -هەڵە هەیە لە ناو گۆڕینی پەڕگە یان بوخچەکان. -دڵنیابە لە لەبەرگرتنەوەی پەڕگە -دڵنیایت لە لەبەرگرتنەوەی پەڕگەکان بۆ ئەرشیڤ؟ -6100 -دڵنیابە لە سڕینەوەی پەڕگە -دڵنیابە لە سڕینەوەی بوخچە -دڵنیابە لە سڕینەوەی هەموو پەڕگەکان -دڵنیایت لە سڕینەوەی '{0}'؟ -دڵنیایت لە سڕینەوەی بوخچەی '{0}' و هەموو ناوەڕۆکەکانی؟ -دڵنیایت لە سڕینەوەی ئەم {0} شتە؟ -دەی سڕێتەوە... -هەڵە هەیە لە سڕینەوەی پەڕگەکان یا بوخچەکان -سیستەم ناتوانێت پەڕگەیەک بگوێزێتەوە بۆ تەنەکەی خۆڵ بە ڕێڕەوی درێژەوە -6300 -دروستکردنی بوخچە -دروستکردنی پەڕگە -ناوی بوخچە: -ناوی پەڕگە: -بەخچەی نوێ -پەڕگەی نوێ -هەڵە هەیە لە دروستکردنی بوخچە -هەڵە هەیە لە دروستکردنی پەڕگەدا -6400 -لێدوان -&لێدوان: -دیاری بکە -دیاری مەکە -دەمامک: -6600 -تایبەتمەندییەکان -مێژووی بوخچەکان -پەیامی لێکۆڵینەوە/ پشکنین -پەیام -7100 -کۆمپیوتەر -ڕایەڵە -بەڵگەنامەکان -سیستەم -7200 -زیادکردن -دەرکێشان -تاقیکردنەوە -لەبەرگرتنەوە -گواستنەوە -سڕینەوە -زانیاری -7300 -لەتکردنی پەڕگە -&لەتی بکە بۆ: -لەتی بکە بۆ &قەبارە و بایت:‌ -لەتی دەکات... -دڵنیابە لە لەتکردن -دڵنیایت لە لەتکردنی پەڕگەی {0} بۆ دوو قەبارە؟ -پێویستە قەبارەی هەر یەک لە لەتەکان بچوکتربێت لە قەبارەی پەڕگە لەتکراوەکە -قەبارەی لەتکراوەکە هەڵەیە -قەبارەی دیاریکراوی لەتکراوەکە: {0} بایت.\nدڵنیایت لە لەتکردنی ئەرشیڤەکە بۆ ئەو قەبارانە؟ -7400 -پێکەوەلکاندنی پەڕگەکان -%پێکەوەی بلکێنە بۆ: -پێکەوەی دەلکێنێت... -تەنها پەڕگەی یەکەم دیاری بکە -ناتوانێت پەڕگە بدۆزێتەوە وەک بەشێک لە پەڕگە لەتکراوەکە -ناتوانێت لە بەشێک زیاتر بدۆزێتەوە لە پەڕگە لەتکراوەکە -7500 -ژماردنی کۆپشکنین... -زانیاری کۆپشکنین -کۆپشکنینی CRC بۆ دراوە: -کۆپشکنینی CRC بۆ دراوە و ناوەکان: -7600 -نیشانەی پێوان -ڕێژەی بەکارهێنراوی بیرگە: -پەستاندن -کردنەوەی پەستێنراو -هەڵسەنگاندن -سەرجەمی هەڵسەنگاندن -ئێستایی -ئەنجام -CPU ڕێژەی بەکارهێنراوی -ڕێژەی بەکارەێنراو / هەڵسەنگاندن -دەرچوونەکان: diff -Nru p7zip-rar-16.02/GUI/Lang/ku.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku.txt --- p7zip-rar-16.02/GUI/Lang/ku.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ku.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.37 : Rizoyê Xerzî -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Kurdish -Kurdî -401 -Temam -Betal - - - -&Erê -&Na -Bi&gire -Alîkarî - -Bi&domîne -440 -&Ji Bo Hemûyî Erê -Ji &Bo Hemûyî Na -Raweste -Dîsa Destpêke -L%i Pişt -Li &Pêş -&Rawestîne -Rawestiya - -Ma bila betal bibe? -500 -&Dosya -&Bipergalîne -&Nîşan Bide -Bi&jare -&Amûr -A&lîkarî -540 -&Veke -&Di Panelê De Veke -Di &Paceyê De Veke -&Nîşan Bide -&Sererast bike -&Navekî Nû Bidê -&Ji Ber Bigire -B&ar Bike -Jê B&ibe -Parçe Bi&ke... -Bike &Yek... -&Taybetî -Da&xuyanî -checksum heseb bike - -Pe&ldankeke Nû -Do&siyeke Nû -De&rkeve -600 -&Hemûyî hilbijêre -He&mû hilijartinê rake -Be&revajî wê hilbijêre -&Hilbijêre... -Hilbijarti&nê Rake... -Vî cureyî hilbijêre -Hilbijartina cure rake -700 -&Dawêrên Mezin -D&awêrên Biçûk -&Lîste -&Hûragahî -730 -Bê Dor -xuyakirina sade -&2 Panelan veke -Da&rikê amûran -Peldanka Kok Veke -Astekê Berjor -Dîroka Peldankê... -&Nû Bike -750 -Darikê arşîvê -Darikê standart -Bişkojkên mezin -Bila nivîsa bişkojkan bixuye -800 -Pe&ldanka derbasdar veke -Cih -900 -&Vebijêrk... -&Pîvana Çalakbûnê -960 -&Naverok... -D&er barê 7-Zip de... -1003 -Rê -Nav -Cure -Peldank -Mezinahî -Mezinahiya di arşîvê de -Taybetiyên xweser -Çêbûyî -Gihaştî -Guhertî -Hişk -Daxuyankirî -Şîfrekirî -Parçeyê borî -Parçeyê piştre -Ferheng -CRC -Cure -Dij -Awayê şidandinê -Platform -Pergala Dosiyê -Bikarhêner -Kom -Stûn -Daxuyanî -Cih -Path Prefix - - - - - - - - - - - - - - - - - - - - - - - - -Çewtî -Hemû Mezinahî -Cihê Vala -Mezinahiya telpikî -Etîket -Navê Herêmî -Derfetkar -2100 -Vebijêrk -Ziman -Ziman: -Per&galker -Pergalkerê De&qê: - -2200 -Pergal -Bi 7-Zip re têkildar bike: -2301 -Bila di pêşekên naverokê de 7-Zip bixuye -Pêşeka naverokê ya sûlavî -Hêmanên peşeka naverokê: -2320 - - -Arşîvê veke -Dosiyan derxe... -Bike Arşîv... -Arşîvê bihêçîne -Valake vir -Peldanka {0} derxe -Wekî {0} bike arşîv -Bişidîne û bişîne... -Wekî {0} bişidîne û bişîne -2400 -Peldank -Peldanka &Xebatê -&Peldanka TEMP a Pergalê -P&eldanka Derbasdar -Pe&ldanka Navborî: -Bi tenê ji bo ajokarên derketî bi kar bîne -Ji bo dosiyên demdemî yên arşîvê cih belî bike. -2500 -Mîheng -Bila hêmana ".." xuya bike -Bila dawêrên dosiyên rastî xuya bikin -Bila pêşeka pergalê xuya bike -Bila &hemû rêzikê bibore -Bila &xêzên tabloyê xuya bike - -&Kipa hilbijartina alternatîf -bîra berfireh bikar bîne -2900 -Der barê 7-Zip de -7-Zip nivîsbariyeke azad e. Lê, tu dikarî wekî tomarkirin desteka pêşxistina 7-zip bibî. -3000 - -Çewtî nîn e. -{0} heb hêman hilbijartî ne -Peldanka '{0}' nayê çêkirin -Tu nikarî vê arşîvê rojane bikî. - - - - -Dosiya '{0}' hatiye guhartin.\nMa bila di arşîvê bête rojanekirin? -Dosiya '{0}' nehate rojanekirin -Pergalkerê deqê nehate destpêkirin. - - - - -Hêman zêde ne -3300 -Tên derxistin -tên şidandin -tê hêçandin -vedibe... -Tê raguhestin -3400 -Derxe -&Cihê Dê Derkevê: -Ji bo dosya derkevinê cihekî belî bike. -3410 -Navê Rê -Navê tevahî yên rê -Bila navên rê tune bin -3420 -Dosiyên heyî -Ji bo li ser binivîse bipirse -Bê pirs li ser binivîse -Derxistin -Navekî nû li yên di arşîvê de bike -Navekî nû li yên heyî bike -3500 -Rewla Lisernivîsandinê -Di dosiya armanckirî de bi vî navî dosiyek heye. Bila li ser bête nivîsîn? -Dosiya heyî: -Dosiya tê derxistin: -{0} bayt -Na&vekî nû lê bike -3700 -Ji bo '{0}' awayê şidandinê nehate nasîn. -'{0}' xerabe ye. (Çewtiya daneyê) -'{0}' xerabe ye. (Çewtiya CRC) - - -3800 -Têketina Şîfreyê -Şîfreyê binivîse: - -Bi&la şîfre bixuye - - - -Şîfre -3900 -Dema borî: -Dema mayî: -Mezinahî: -Lez: - - -Çewt: - -4000 -Bike Arşîv -&Arşîv: -A&wayê rojanekirinê: -Awa&yê arşîvê: -A&sta şidandinê: -Awayê şi&dandinê: -Me&zinahiya ferhengê: -M&ezinahiya bêjeyê: - - -&Parametre: -Vebijêrk -Bila ew bixwe derxe (SFX) - - - -Navên dosiyê bike şîfre -Bikaranîna bîrê (Şidandin): -Bikaranîna bîrê (Vekirin): -4050 -Bêyî şidandin -Leztirîn -Bi Lez -Asayî -Herî Pir -Ultra -4060 -Dosiyan têxê, yên heyî derxe -Dosiyan têxê, yên kevin rojane bike -Bi tenê yên kevin rojane bike -Dosiyan bike wekî hev -4070 -Bibîne -Hemû dosya - - -6000 -Ji Ber Bigire -Bar Bike -Cihê Dê Were Jibergirtin: -Cihê Dê Were Barkirin: -tê jibergirtin... -tê barkirin... -navekî nû tê lêkirin... - -Kirin ne pêkan e. -Çewtiya Navlêkirinê -Erêkirina Jibergirtinê -Ma bila dosî ji bo arşîvê bên jibergirtin -6100 -Erêkirina jêbirina dosiyê -Erêkirina jêbirina peldankê -Erêkirina jêbirina gelek dosiyan -Ma bila dosiya '{0}' bête jêbirin? -Ma bila peldanka '{0}' û yên tê de bên jêbirin? -Ma bila hêmana {0} bête jêbirin? -tê jêbirin... -Çewtiya Jêbirinê - -6300 -Peldankeke nû -Dosiyeke Nû -Navê peldankê: -Navê Dosiyê: -Peldankeke Nû -Dosiyeke Nû -Çewtiya Çêkirina peldankê -Çewtiya çêkirina Dosiyê -6400 -Daxuyanî -&Daxuyanî: -Hilbijêre -Hilbijartinê rake -Derbirîna hilbijartinê: -6600 - -Rabirdûya Peldankê -Peyamên haydariyê -Peyam -7100 -Komputer -Tor - -Pergal -7200 -Bike Arşîv -Derxe -Bihêçîne -Ji Ber Bigire -Bar Bike -Jê Bibe -Agahî -7300 -Bike Parçe -Di &vê peldankê de parçe bike: -Wekî Bayt/&cilt bike parçe: -tê parçekirin... - - - - - -7400 -Bike Yek -Di vê &peldankê de bike yek: -tê yekirin... - - - -7500 -Hesabê sererastkirî... -Agahiyên hesabê sererast -CRC hesabê sererast bo data: -CRC hesabê sererast bo data û nav: -7600 -Çalakiya komputerê -Bikaranîna birê: -Şidandin -Vekirin -Puan -bi guloverî puanan -Carî -Encam - - -Serkeftî: diff -Nru p7zip-rar-16.02/GUI/Lang/ky.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ky.txt --- p7zip-rar-16.02/GUI/Lang/ky.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ky.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.20 : Kalil uulu Bolot -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Kyrgyz -Кыргызча -401 -OK -Айнуу - - - -&Ооба -&Жок -&Жабуу -Жардам - -&Улантуу -440 -Ооба &баарына -Жок б&аарына эмес -Токто -Кайта иштетүү -&Фоном -&Алдыңкы планга -&Тыныгуу -Тыныгууда -Сиз чын эле операцияны токтоткуңуз келип жатабы? -500 -&Файл -&Оңдоо -&Кейп -&Тандалган -С&ервис -&Жардам -540 -&Ачуу -Ичи&нен ачуу -Сырты&нан ачуу -Көрүү -&Редактирлөө -Атын& өзгөртүү -&Буга көчүрүү... -&Буга ордун которуу... -&Өчүрүү -Фа&лды бөлүштүрүү... -Ф&айлдарды кошуу... -Кас&иети -Комме&нтарий -Контролдук жыйынтык -Diff -&Баштык жаратуу -Фай&л жаратуу -Ч&ыгуу -600 -Баарын б&өлүү -Бөлүнгөндү алуу -&Бөлүүнү к&аратуу -Бөлүү... -Бөлүнгөндү алуу... -Түзү менен бөлүү -Түзү менен бөлүнгөндү алуу -700 -&Чоң белгилер -&Кичине белгилер -Тиз&ме -&Таблица -730 -Иргөөсүз -Түз түзүлүш -&2 Панель -&Аспап панелдери -Түпкү баштыкты ачуу -Бир деңгээлге өйдө өтүү -Баштыктардын тарыхы... -Ж&аңыртуу -750 -Архиватордун баскычтарынын панели -Стандарттык баскыч панели -Чоң баскычтар -Баскычтагы жазуулар -800 -Кантип тандалганга& баштыкты кошуу -Чөп кат -900 -Оңдоп-түздөмөлөр... -Өндүрүмдүүлүктү тестирлөө -960 -&Мазмуну... -Программа &жөнүндө... -1003 -Жол -Ат -Кенейтүү -Баштык -Көлөм -Кысылган -Атрибуттар -Жаралган -Ачылган -Өзгөртүлгөн -Үзгүлтүксүз -Комментарий -Шифрланган -Чейин бөлүнгөн -Кийин Бөлүнгөн -Сөздүк -CRC -Түр -Анти -Амал -Система -Файлдык система -Колдонуучу -Топ -Блок -Комментарий -Ээлеген ахывал -Жол -Баштыктар -Файлдар -Версиясы -Том -Көптомдуу -Жылдыруу -Сүрүштүрүү -Блоктор -Томдор - -64-bit -Big-endian -Процессор -Физикалык көлөм -Баш аттардын көлөмү -Текшерүү жыйынтык -Мүнөздөмөлөр -Виртуалдык дарек -ID -Кыска ат -Жараткан -Сектордун көлөмү -Түзүлүш -Сүрүштүрүү -Ката -Сыйдыргычтык -Бош -Размер кластера -Белги -Локалдык ат -Провайдер -2100 -Оңдоп-түздөмөлөр -Тил -Тил: -Редактор -&Редактор: -&Diff: -2200 -Система -7-Zip менен файлдарды бириктирүү: -2301 -7-Zipти менюнун контексттик кыртышына жайгаштыруу -Каскадттык контексттик меню -Контексттик менюнун элементтери: -2320 -<Баштык> -<Архив> -Архивди ачуу -Таңгагын чечүү -Архивке кошуу... -Тестирлөө -Мында таңгагын чечүү -Буга таңгагын чечүү {0} -Буга кошуу {0} -Кысып жана аны email менен жиберүү... -Буга кысып {0} жана email менен жиберүү -2400 -Баштыктар -&Иштөө баштык -&Убактылуу системалык баштык -&Учурдагы -&Тапшыруу: -Котормолуу алып жүрүүчүлөргө гана колдонуу -Убактылуу архивтерге турган ордун көрсөтүңүз. -2500 -Оңдоп-түздөмөлөр -".." элементин көрсөтүү -Файлдардын реалдуу иконкаларын көрсөтүү -Системалык менюну көрсөтүү -Курсор жалпы сапка -Бөлгүчтөрдү көрсөтүү -Бир басуу менен ачуу -Белгинин алтернативалык режими -Эстин чоң барактарын колдонуу -2900 -7-Zip программа жөнүндө -7-Zip эркин таратылуучу программа.Бирок сиз 7-Zipтин иштетүүсүн колдогуңуз келсе,сиз программаны каттатып койсоңуз болот. -3000 -Эркин эске тутуу жетишсиз -Ката табылган жок -{0} Нерселер бөлүнгөн -'{0}' баштыкты жаратуу ишке ашкан жок -Бул архив үчүн өзгөртүү операциялары колдолбойт. -'{0}' архивтей кылып ачуу ишке ашкан жок -Шифрленген архивди ачуу ишке ашкан жок '{0}'. Купуя-белги туура эмес? -Архивдин колдоо кылынбаган түрлөрү -{0} деген файл бар -'{0}' файлы өзгөртүлгөн.\nСиз аны архивде жаңырткыңыз келип жатабы? -\n'{0}' файлын жаңыртуу ишке ашкан жок -Редакторду иштетүү, ишке ашкан жок -Файл вируска окшош (файлдын аты ырааттуу бош жерди камтыйт). -Баштыктын ичинен операция аткарылбайт, жолдун узактыгынан. -Сиз бир фалды бөлүшүңүз керек -Сиз бир нече файлды бөлүшүңүз керек -Өтө көп элементтерди камтыйт -3300 -Таңгагын чечүү -Компрессиялоо -Тестирлөө -Ачуу... -Сканирлөө... -3400 -Чыгаруу -& Буга таңгагын чечүү: -Чыгарып жаткан файлдар үчүн ордун көрсөтүңүз. -3410 -Жолдор -То&лук жолдор -&Жолсуз -3420 -Кайта жазуу -&Далилдөө менен -Д&алилдөөсүз -Өткө&рүү -Автоматтык түрдө атын өзгөртүү. -Бар файлдардын аттарын автоматтык түрдө өзгөртүү. -3500 -Файлды алмаштырууну далилдөө -Баштык иштеп чыгарылган файлды камтыйт. -Бар файлдарды алмаштыруу -кийинки файл менен? -{0} байт -Автоматтык түрдө атын өзгөртүү. -3700 -'{0}' файлдагы колдобоочу кысуу амалы. -'{0}' берилүүсүндөгү ката.файл бузук. -'{0}' CRCте ката.файл бузук. -'{0}' шифрленген файлда ката. Туура эмес купуя-белги? -'{0}' шифрленген файл үчүн CRCте ката. Туура эмес купуя-белги? -3800 -Купуя-белгини киргизүү -&Купуя-белгини киргизиңиз: -&Купуя-белгини кайталаңыз: -&Купуя-белгини көрсөтүү -Купуя-белгилер бири-бирине туура келбейт -Купуя-белги үчүн латын алфавитиндеги символдорду гана колдонуңуз,сандарды жана атайын (!, #, $, ...) символдорун -Купуя-белги өтө узун -&Купуя-белги -3900 -Өттү: -Калды: -Баары: -Ылдамдык: -Көлөм: -Кысуунун даражасы: -Каталар: -Архивтер: -4000 -Архивке кошуу -&Архив: -&Өзгөртүүнүн режими: -&Архивдин форматы: -&Кысуунун деңгээли: -&Кысуунун амалы: -Сөздүктүн &көлөмү: -Сөздүн к&өлөмү: -Блоктун көлөмү: -Агымдардын саны: -&Параметрлер: -&Оңдоп-түздөмөлөр -SF&X-архивди жаратуу -Файлдарды жаздыруу үчүн ачууну кысуу -Шифрлөө -Шифрлөөнүн амалы: -&Файлдардын атын шифрлөө -Салып бекитүү үчүн эстин көлөмү: -Таңгагын чечүү үчүн эстин көломү: -4050 -Кысуусуз -Ылдамдуу -Бат -Кадимкидей -Ээң жогорку -Ультра -4060 -Кошуп жана алмаштыруу -Жаңыртып жана кошуу -Жаңыртуу -Калптандыруу -4070 -Барактоо -Баардык файлдар -Файлдын көлөмүндөй -Үзгүлтүксүз -6000 -Көчүрүү -Которуштуруу -Буга көчүрүү: -Буга которуштуруу: -Көчүрүү... -Ордун которуу... -Атын өзгөртүү... -Баштыкты көрсөтүңүз. -Операция бул баштык үчүн колдолбойт. -Баштыктын же файлдын атын өзгөртүүдө ката -Файлдарды көчүрүүнү аныктоо -Сиз бул файлдарды архивке көчүрүүнү чын эле каалап жатасызбы -6100 -Файлдын өчүрүүсүн аныктоо -Баштыктын өчүрүүсүн аныктоо -Файлдын тобун өчүрүүсүн аныктоо -Сиз "{0}" өчүрүүнү чын эле каалап жатасызбы? -Сиз "{0}" баштыктын ичиндегилери менен өчүрүүнү чын эле каалап жатасызбы? -({0} даана.) нерселерди өчүрүүнү чын эле каалап жатасызбы? -Өчүрүү... -Баштыкты же файлды өчүрүүдө ката -Система узун жолдуу файлдарды өчүрүүбаштыкка өчүрүү операциясын колдобойт -6300 -Баштык жаратуу -Файл жаратуу -Баштыктын аты: -Файлдын аты: -Жаңы баштык -Жаңы файл -Баштык жаратуудан ката -Файл жаратуудан ката -6400 -Комментарий -&Комментарий: -Бөлүү -Бөлүнгөндү алып салуу -Маска: -6600 -Касиет -Баштыктардын тарыхы -Билдирүү -Билдирүү -7100 -Компьютер -Желе -Иш кагаздар -Система -7200 -Кошуу -Чыгаруу -Тестирлөө -Көчүрүү -Ордун которуу -Өчүрүү -Маалымат -7300 -Файлды бөлүштүрүү -&Буга бөлүштүрүү: -(байт ) көлөмү менен томдорго бөлүштүрүү: -Бөлүштүрүү... -Бөлүштүрүүнү аныктоо -Сиз файлды {0} бөлүккө бөлгүңүз келип жатабы? -Томдун көлөмү баштапкы файлдын көлөмүнөн кичине болушу керек -Томдордун көлөмүн берүүдө ката -Отургузулган томдун көлөмү: {0} байт.\nСиз чын эле архивди ушундай томдорго бөлгүңүз келип жатабы? -7400 -Файлдарды бириктирүү -&Буга бириктирүү: -Биригүү... -Бөлүштүрүлгөн файлдын биринчи бөлүгүн гана бөлүү керек -Бөлүштүрүлгөн файлды таану ишке ашкан жок -Бөлүштүрүлгөн файлдын бир бөлүгүн дагы табуу ишке ашкан жок -7500 -Текшерүүнүн жыйынтыгын эсептөө... -Текшерүүнүн жыйынтыгы -Маалымат үчүн CRC текшерүү жыйынтыгы: -Маалымат жана аттар үчүн CRC текшерүү жыйынтыгы: -7600 -Өндүрүмдүүлүктү тестирлөө -Эстин көлөмү: -Салып бекитүү -Таңгагын чечүү -Рейтинг -Жалпы рейтинг -Учурдагы -Жыйынтыгы -Жүк -Рейтинг / Жүк. -Өтүүлөр: diff -Nru p7zip-rar-16.02/GUI/Lang/lij.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/lij.txt --- p7zip-rar-16.02/GUI/Lang/lij.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/lij.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : GENOVES.com.ar -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Ligurian -Zeneize -401 -D'acòrdio -Anulla - - - -&Sci -&No -Sæ&ra -Agiutto - -&Continoa -440 -Sci pe &Tutti -No pe T&utti -Ferma -Inandia torna -Into &sfondo -&In primmo cian -&Paoza -In paoza -Ti ê seguo de voei anulâ? -500 -&Archivio -&Modifica -&Vixoalizza -&Preferii -&Strumenti -A&giutto -540 -&Arvi -Arvi into Manezatô d'archivi 7-Zip -Arvi inte Explorer -&Vixoalizza -&Modifica -Ri&nomina -&Còpia inte... -&Spòsta inte... -Scancel&la -&Dividi l'archivio... -&Unisci i archivi... -P&ropietæ -Comen&ta... -Calcola somma de contròllo -Dif -Crea cartella -Crea archivio -Sc&iòrti -600 -Seleçionn-a &tutto -Deseleçionn-a tutto -In&verti seleçion -Seleçionn-a... -Deseleçionn-a... -Seleçionn-a pe tipo -Deseleçionn-a pe tipo -700 -Figue &grende -Figue picinn-e -&Listin -&Dæti -730 -Nisciun ordine -Vista ciatta -&2 barcoîn -Bare di &Strumenti -Arvi cartella prinçipâ -Livello supeiô -Cronologia... -&Agiorna -750 -Bara di strumenti Archivio -Bara di strumenti Normali -Figue grende -Mostra etichette de tèsto -800 -&Azonzi a cartella a-i Preferii comme -Colegamento -900 -&Òpsioin... -&Ponto de riferimento -960 -&Goidda... -&Informaçioin in sce de 7-Zip... -1003 -Percorso -Nomme -Estension -Cartella -Mezua -Mezua Conpressa -Atributi -Creou -Urtimo acesso -Urtima modifica -Sòlido -Comentou -Criptou -Dividi primma -Dividi dòppo -Diçionaio -CRC -Tipo -Anti -Metodo -OS destinaçion -Archivio do scistemma -Utente -Gruppo -Blòcco -Comento -Poxiçion -Prefisso da destinaçion -Cartelle -Archivi -Verscion -Volumme -Multivolumme -Offset -Colegamenti -Blòcchi -Volummi - -64-bit -Big-endian -CPU -Mezua fixica -Mezua de titoli -Somma de contròllo -Carateristiche -Indirisso Virtoale -ID -Nomme curto -Aplicaçion de creaçion -Mezua da seçion -Mòddo -Colegamento -Erô -Capaçitæ totale -Spaçio disponibile -Mezua de particole (cluster) -Etichetta -Nomme locale -Proveditô -2100 -Òpsioin -Lengoa -Lengoa: -Editô -&Editô: -&Dif: -2200 -Scistemma -Asòccia 7-Zip a: -2301 -Integra 7-Zip into menù contestoale -Menù contestoale a cascaa -Elementi do menù contestoale: -2320 - - -Arvi -Estranni i archivi... -Azonzi a l'archivio... -Contròlla l'archivio -Estranni chi. -Estranni inte {0} -Azonzi a {0} -Conprimmi e invia pe email... -Conprimmi in {0} e invia pe email -2400 -Cartelle -Cartella de tra&vaggio -Cartella &Temp de Scistemma -&Corente -&Specificâ: -Deuvia solo pe dischi estraibili -Specifica unna cartella pe-i archivi tenporanni. -2500 -Inpostaçioin -Mostra l'elemento ".." -Mostra e icöne di archivi -Mostra e icöne do scistemma -Seleçionn-a a &riga intrega -Mostra &grixella -Sciacâ unna vòtta sola pe arvî un elemento -&Mòddo de seleçion alternativo -Deuvia grende &pagine de memöia -2900 -Dæti -7-Zip o l'é un programa libero e de badda. -3000 -O scistemma o no peu separâ a quantitæ de memöia necesaia -Nisciun erô -{0} ògetti seleçionæ -Inposcibile creâ a cartella '{0}' -No l'é poscibile efetoâ agiornamenti in sce quest'archivio. -Inposcibile arvî l'archivio '{0}' comme conpilaçion -Inposcibile arvî a conpilaçion criptâ '{0}'. Scoretta a paròlla d'ordine? -Tipo de conpilaçion no consentia -L'archivio {0} za o l'existe -L'archivio '{0}' o l'é stæto modificou.\nTi veu agiornâ l'archivio? -Inposcibile agiornâ l'archivio\n'{0}' -Inposcibile inandiâ l'editô. -L'archivio o pâ d'ese un virus (o seu nomme o gh'à di spaççi longhi). -L'òperaçion a no peu conpletase da unna cartella da percorso longo. -Ti devi seleçionâ un archivio -Ti devi seleçionâ ùn ò ciù archivi -Tròppi elementi -3300 -Estraçion in corso... -Conprescion in corso... -Contròllo in corso... -Avertua in corso... -Controlemmo... -3400 -Estranni -&Estranni inte: -Specifica unna cartella dove estrae i archivi. -3410 -Strutua de cartelle -Percorsci conpleti -Nisciun percorso -3420 -Sorvescritua -Domanda primma de sorvescrive -Sorvescrivi sensa domandâ -No sorvescrive i archivi existenti -Rinomina outomaticamente -Rinomina outomaticamente i archivi existenti -3500 -Conferma a sostitoçion de l'archivio -A cartella destinaçion a contegne za l'archivio fæto. -Ti voriesci sostitoî l'archivio -con questo? -{0} byte -Rinomina &outomaticamente -3700 -Metodo de conprescion no consentio pe '{0}'. -Erô di dæti inte '{0}'. L'archivio o l'é danezou. -CRC no coretto inte '{0}'. L'archivio o l'é danezou. -Erô di dæti inte l'archivio criptou '{0}'. Scoretta a paròlla d'ordine? -CRC falio inte l'archivio criptou '{0}'. Scoretta a paròlla d'ordine? -3800 -Introduxi paròlla d'ordine -Introduxi paròlla d'ordine: -Ripeti a paròlla d'ordine: -&Mostra paròlla d'ordine -E paròlle d'ordine no coincidan -Deuvia solo segni de l'ingleize, numeri e carateri speciali (!, #, $, ...) pe-a paròlla d'ordine -Paròlla d'ordine tròppo longa -Paròlla d'ordine -3900 -Tenpo trascorso: -Tenpo rimanente: -Mezua: -Velocitæ: -Procesou: -Tascia de conprescion: -Eroî: -Conpilaçion: -4000 -Azonzi a l'archivio -&Archivio: -Modalitæ d'a&giornamento: -&Formato de l'archivio: -&Livello de conprescion: -&Metodo de conprescion: -Mezua &Diçionaio: -Mezue da Pa&ròlla: -Mezua do blòcco sòlido: -Numero de thread CPU: -&Parametri: -Òpsioin -Crea archivio outo-estraente -Conprimmi archivi condivixi -Critografia -Mòddo de criptâ: -Cripta o &nomme di archivi -Utilizzo da memöia pe conprescion: -Utilizzo da memöia pe deconprescion: -4050 -Nisciunn-a -Velociscima -Veloce -Normale -Mascima -Ultra -4060 -Azonzi e sostitoisci i archivi -Agiorna e azonzi i archivi -Agiorna i archivi existenti -Sincronizza i archivi -4070 -Sfeuggia -Tutti i archivi -No-sòlido -Sòlido -6000 -Còpia -Spòsta -Còpia inte: -Spòsta verso: -Còpia in corso... -Spostamento in corso... -Rinominaçion in corso... -Çerni cartella de destinaçion. -L'òperaçion a no l'é consentia. -Erô into rinominâ l'archivio ò a cartella -Conferma a còpia d'archivi -Ti ê seguo de voei copiâ di archivi a unna conpilaçion? -6100 -Conferma l'eliminaçion de l'archivio -Conferma l'eliminaçion da cartella -Conferma l'eliminaçion de ciù elementi -Ti ê seguo de voei eliminâ '{0}'? -Ti ê seguo de voei eliminâ a cartella '{0}' e tutto o seu contegnuo? -Ti ê seguo de voei eliminâ questi {0} elementi? -Eliminaçion in corso... -Erô inte l'eliminaçion de l'archivio ò da cartella -O scistemma o no peu caciâ via un archivio da percorso longo -6300 -Crea Cartella -Crea archivio -Nomme da cartella: -Nomme d'archivio: -Neuva cartella -Neuvo archivio -Erô inta creaçion da cartella -Erô inta creaçion de l'archivio -6400 -Comento -&Comento: -Seleçionn-a -Deseleçionn-a -Filtro: -6600 -Propietæ -Cronologia -Mesaggi diagnòstichi -Mesaggio -7100 -Calcolatô -Ræ -Documenti -Scistemma -7200 -Azonzi -Estranni -Contròlla -Còpia -Spòsta -Cancella -Propietæ -7300 -Dividi Archivio -&Dividi inte: -Di&vidi in ciù archivi, mezua in byte: -Dividimmo... -Conferma a divixon -Ti ê seguo de voei separâ l'archivio inte {0} volummi? -A mezua de volumme a deve ese ciù picinn-a de quella de l'òriginale -Scoretta a mezua do volumme -Mezua de volumme specificâ: {0} byte.\nTi ê seguo de voei separâ l'archivio inte quelli volummi? -7400 -Unisci i archivi -&Unisci inte: -Unimmo... -Seleçionn-a solo a primma parte de l'archivio divizo -No se gh'atreuva un archivio comme parte d'un archivio divizo -No se gh'atreuva ciù d'unna parte d'un archivio divizo -7500 -Calcolemmo a somma de contròllo... -Dæti da somma de contròllo -Somma de contròllo CRC pe dæti: -Somma de contròllo CRC pe dæti e nommi: -7600 -Ponto de riferimento -Utilizzo da memöia: -Conprescion in corso -Deconprescion in corso -Valutaçion -Valutaçion totale -Atoale -Derivou -Utilizzo de CPU -Rating / Utilizzo -Pasaggi: diff -Nru p7zip-rar-16.02/GUI/Lang/lt.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/lt.txt --- p7zip-rar-16.02/GUI/Lang/lt.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/lt.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 2.30 : Marius Navickas : http://www.teisininkas.lt/ivairus/7-zip: -; 4.57 : Domas Jokubauskis -; 15.05 : Vaidas777 (terminų šaltinis: www.raštija.lt) -; -; -; -; -; -; -; -; -0 -7-Zip -Lithuanian -Lietuvių -401 -Gerai -Atšaukti - - - -&Taip -&Ne -&Uždaryti -Elektroninis žinynas - -&Tęsti -440 -T&aip Visiems -Ne v&isiems -Sustabdyti -Iš naujo -&Fone -&Pirminis procesas -&Laikinai sustabdyti -Laikinai sustabdyta -Ar jūs esate tikri, kad norite atšaukti? -500 -&Failas -K&eisti -&Rodyti -Mėgi&amiausi -Įran&kiai -&Elektroninis žinynas -540 -&Atverti -Atverti v&iduje -Atverti iš&orėje -&Rodyti -K&eisti -Pervadi&nti -&Kopijuoti į... -&Perkelti į... -Šalin&ti -&Skaidyti failą... -Jungti &failus... -Savy&bės -Kome&ntuoti -Skaičiuoti kontrolinę sumą -Sulyginti -Sukurti aplanką -Sukurti failą -Išei&ti -Nuoroda -&Alternatyvūs srautai -600 -Pažymėti &viską -Nužymėti viską -Atv&irkštinis žymėjimas -Parinkti... -Atžymėti... -Pasirinkti pagal tipą -Atžymėti pagal tipą -700 -Did&elės piktogramos -&Mažos piktogramos -&Sąrašas -&Išsamiai -730 -Nerūšiuotos -Nepaisyti aplankų -&2 skydeliai -&Mygtukų juostos -Atverti šakninį aplanką -Lygiu aukščiau -Aplankų istorija... -&Atnaujinti -Automatiškai atnaujinti -750 -Archyvo mygtukų juosta -Standartinė mygtukų juosta -Dideli mygtukai -Rodyti užrašus ant mygtukų -800 -&Pridėti aplanką prie mėgiamiausiųjų kaip -Mėgiamiausias -900 -&Nuostatos... -&Spartos bandymas -960 -&Turinys... -&Apie 7-Zip... -1003 -Kelias -Pavadinimas -Plėtinys -Aplankas -Dydis -Dydis archyve -Atributai -Sukurta -Naudota -Pakeista -Vientisas -Komentaras -Šifruotas -Perskyra prieš -Perskyra paskui -Žodynas - -Tipas -Anti -Būdas -Kompiuterio OS -Bylų sistema -Naudotojas -Grupė -Blokas -Komentaras -Pozicija -Kelio priešdėlis -Aplankai -Failai -Versija -Tomas -Daugiatomis -Poslinkis -Nuorodos -Blokai -Tomai - -64-bit -Mažėjantys baitai -Procesorius -Fizinis dysis -Antraštės dydis -Kontrolinė suma -Charakteristikos -Virtualus adresas -ID -Trumpas pavadinimas -Kūrėjo programa -Sektoriaus dydis -Moda -Simbolinė nuoroda -Klaida -Visas dydis -Laisva vieta -Blokinio dydis -Žymė -Vietinis pavadinimas -Teikėjas -NT saugumas -Alternatyvus srautas -Pagalbinis -Ištrintas -Medis - - -Klaidos tipas -Klaidos -Klaidos -Perspėjimai -Perspėjimas -Srautai -Alternatyvūs srautai -Alternatyvių srautų dydis -Virtualus dydis -Išpakuoto dydis -Visas fizinis dydis -Tomo numeris -Subtipas -Trumpas komentaras -Kodų lentelė - - - -Pabaigos dydis -Įterpto bloko dydis -Nuoroda -Patvarioji nuoroda -iNode - -Tik skaityti -2100 -Nustatymai -Kalba -Kalba: -Redaktorius -R&edaktorius: -&Sulyginimas: -2200 -Sistema -Susieti 7-Zip su: -Visi vartotojai -2301 -Integruoti 7-Zip į kontekstinį meniu -Pakopinis kontekstinis meniu -Kontekstinio meniu įrašai: -Piktogramos kontekstiniame meniu -2320 - - -Atverti archyvą -Išskleisti failus... -Įtraukti į archyvą... -Patikrinti archyvą -Išskleisti čia -Išskleisti į {0} -Įtraukti į {0} -Suglaudinti ir išsiųsti el. paštu... -Suglaudinti į {0} ir išsiųsti el. paštu -2400 -Aplankai -&Darbinis aplankas -&Sisteminis laikinas aplankas -D&abartinis -Nurodyta&s: -Naudoti tik išimamiems diskams -Nurodyti vietą laikiniems archyviniams failams. -2500 -Nustatos -Rodyti „..“ failų sąraše -Rodyti tikras failų piktogramas -Rodyti sisteminį meniu -&Žymėti visą eilutę -Rodyti tinklelio linija&s -Atverti vienu spustelėjimu -&Kitoks žymėjimo būdas -Naudoti didžiu&lius atmintinės puslapius -2900 -Apie 7-Zip -7-Zip yra nemokama programa. -3000 -Sistema begali skirti reikalingo atminties kiekio -Klaidų nerasta -Pasirinkta {0} objektų: -Negalima sukurti aplanko „{0}“ -Šio archyvo negalima atnaujinti. -Negalima atverti „{0}“ failo kaip archyvo -Negalima atverti šifruoto archyvo „{0}“. Neteisingas slaptažodis? -Nepalaikomas archyvo tipas -Failas pavadinimu {0} yra -Failas „{0}“ buvo pakeistas.\nAr norite jį atnaujinti archyve? -Negalima atnaujinti failo\n„{0}“ -Negalima paleisti redaktoriaus. -Šis failas panašus į virusą (failo pavadinime yra pasikartojančių tarpų) -Šis veiksmas negali būti vykdomas iš aplanko, kuris turi ilgą kelią -Jūs privalote pažymėti vieną failą -Jūs privalote pažymėti bent vieną failą -Per daug elementų -Negalima atverti failo kaip {0} archyvo -Failas yra atvertas kaip {0} archyvas -Archyvas yra atvertas su ofsetu -3300 -Išskleidžiama -Glaudinama -Tikrinama -Atidaroma... -Skenuojama... -Šalinama -3320 -Glaudinama -Atnaujinama -Analizuojama -Dubliuojama -Glaudinama iš naujo -Praleidžiama -Šalinama -Kuriama antraštė -3400 -Išskleisti -Iš&skleisti į: -Nurodyti vietą išskleidžiamiesiems failams. -3410 -Kelio moda: -Pilni keliai -Jokių kelių -Absoliutūs keliai -Santykiniai keliai -3420 -Perrašymo režimas -Paklausti prieš perrašant -Perrašyti neįspėjant -Praleisti esančius failus -Automatiškai pervadinti -Automatiškai pervadinti esančius failus -3430 -Pašalinti šakninio aplanko pasikartojimą -Atstatyti failų saugumo nuostatas -3500 -Failų pakeitimo patvirtinimas -Paskirtame aplanke jau yra apdorojamas failas. -Ar norėtumėte pakeisti esančią failą -šiuo failu? -{0} baitų -A&utomatinis pervadinimas -3700 -Nepalaikomas suglaudinimo metodas failui „{0}“. -Duomenų klaida „{0}“. Failas pažeistas. -CRC klaida „{0}“. Failas pažeistas. -Duomenų klaida šifruotame faile „{0}“. Neteisingas slaptažodis? -CRC neatitikimas šifruotame faile „{0}“. Neteisingas slaptažodis? -3710 -Neteisingas slaptažodis? -3721 -Nepalaikomas suglaudinimo metodas -Duomenų klaida -CRC neatitikimas -Nepasiekiami duomenys -Netikėta duomenų pabaiga -Yra papildomi duomenys po naudingų duomenų -Tai nėra archyvas -Klaida antraštėse -Klaidingas slaptažodis -3763 -Nepasiekiama archyvo pradžia -Nepatvirtinta archyvo pradžia - - - -Nepalaikoma ypatybė -3800 -Slaptažodžio įvedimas -Įveskite slaptažodį: -Pakartokite slaptažodį: -&Rodyti slaptažodį -Slaptažodžiai nesutampa -Slaptažodžiui naudokite tik lotyniškas raides, numerius bei specialiuosius simbolius (!, #, $, ...) -Slaptažodis yra per ilgas -Slaptažodis -3900 -Praėjęs laikas: -Likęs laikas: -Dydis: -Sparta: -Apdorota: -Suglaudinimo laipsnis: -Klaidos: -Archyvai: -4000 -Įtraukti į archyvą -&Archyvas: -Atna&ujinimo režimas: -Archyvo &formatas: -Suglaudinimo &lygis: -Glaudini&mo būdas: -Žo&dyno dydis: -Ž&odžio dydis: -Vientiso bloko dydis: -CPU gijų skaičius: -&Parametrai: -Nuostatos -Sukurti iš&sipakuojantį archyvą -Glaudinti atvertus įrašymui failus -Šifravimas -Šifravimo metodas: -Už&šifruoti failų pavadinimus -Atmintinės naudojimas suglaudinimui: -Atmintinės naudojimas išskleidimui: -Ištrinti failus suglaudinus -4040 -Įsiminti simbolines nuorodas -Įsiminti patvariasias nuorodas -Įsiminti alternatyvius duomenų srautus -Įsiminti failų saugumo nuostatas -4050 -Mažiausias -Greitesnis -Greitas -Normalus -Didžiausias -Smarkiausias -4060 -Įtraukti ir pakeisti failus -Atnaujinti ir įtraukti failus -Atnaujinti esančius failus -Sinchronizuoti failus -4070 -Naršyti -Visus failus -Ne vientisas -Vientisas archyvas -6000 -Kopijuoti -Perkelti -Kopijuoti į: -Perkelti į: -Kopijuojama... -Perkeliama... -Pervadinama... -Pasirinkite paskirties aplanką. -Šiam aplankui veiksmas nepalaikomas. -Klaida pervadinant failą ar aplanką -Failų kopijavimo patvirtinimas -Ar jūs esate įsitikinę, jog norite kopijuoti failus į archyvą? -6100 -Patvirtinkite failo šalinimą -Patvirtinkite aplanko šalinimą -Patvirtinkite kelių failų šalinimą -Ar esate įsitikinę, jog norite pašalinti „{0}“? -Ar esate įsitikinę, jog norite pašalinti „{0}“ aplanką ir visą jo turinį? -Ar esate įsitikinę, jog norite pašalinti šiuos {0} elementus? -Šalinama... -Klaida trinant failą ar aplanką -Sistema negali perkelti failo į šiukšlinę, kadangi per ilgas kelias -6300 -Sukurti aplanką -Sukurti failą -Aplanko pavadinimas: -Failo pavadinimas: -Naujas aplankas -Naujas failas -Klaida kuriant aplanką -Klaida kuriant failą -6400 -Komentaras -&Komentaras: -Pažymėti -Panaikinti žymėjimą -Šablonas: -6600 -Nuostatos -Aplankų istorija -Diagnostiniai pranešimai -Pranešimas -7100 -Kompiuteris -Tinklas -Dokumentai -Sistema -7200 -Glaudinti -Išskleisti -Bandyti -Kopijuoti -Perkelti -Šalinti -Informacija -7300 -Skaidyti failą -&Skaidyti į: -Skaidyti į dalis bai&tais: -Skaidoma... -Skaidymo patvirtinimas -Ar jūs esate įsitikinę, jog norite failą skaidyti į {0} dalis? -Dalies dydis privalo būti mažesnis už dalijamo failo dydį -Neteisingas dalies dydis -Nurodytas dalies dydis: {0} baitai.\nAr jūs esate įsitikinę, jog norite archyvą skaidyti į tokias dalis? -7400 -Sujungti failus -&Sujungti į: -Sujungiami failai... -Pažymėkite tik pirmą suskaidyto archyvo failą -Nepavyko atpažinti suskaldyto failo -Nepavyko surasti daugiau nei vienos suskaldymo failo dalies -7500 -Skaičiuojama kontrolinė suma... -Kontrolinės sumos informacija -Duomenų CRC kontrolinė suma: -Duomenų ir failų pavadinimų CRC kontrolinė suma: -7600 -Spartos bandymas -Atmintinės naudojimas: -Suglaudinama -Išskleidžiama -Įvertis -Galutinis įvertis -Dabartinis -Galutinis -CPU naudojimas -Įvertis/naudojimas -Kartai: -7700 -Nuoroda -Sujungti -Šaltinis: -Tikslas: -7710 -Nuorodos tipas -Patvarioji nuoroda -Failo simbolinė nuoroda -Aplanko simbolinė nuoroda -Sujungimo taškas (Junction) diff -Nru p7zip-rar-16.02/GUI/Lang/lv.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/lv.txt --- p7zip-rar-16.02/GUI/Lang/lv.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/lv.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.10 : Armands Radzuška -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Latvian -Latviešu -401 -&Labi -&Atcelt - - - -&Jā -&Nē -Aiz&vērt -&Rokasgrāmata - -&Turpināt -440 -Jā &visiem -Nē v&isiem -Stop -Pārstartēt -&Fonā -&Priekšplānā -Pa&uze -Pauzēts -Vai piekrītat pārtraukt šo darbību? -500 -&Fails -&Labošana -&Izskats -Ie&cienītās -&Rīki -&Palīdzība -540 -&Atvērt -Atvērt &iekšpusē -Atvērt ārp&usē -Ap&skate -&Labot -Pā&rdēvēt -&Kopēt uz... -Pār&vietot uz... -&Dzēst -&Sadalīt failu... -Ap&vienot failus... -Īpašī&bas -&Piezīmes - - -Izveidot &mapi -Izveidot &failu -&Beigt -600 -Iezīmēt &visu -Atcelt vis&u -I&nvertēt iezīmējumu -Ie&zīmēt... -&Atcelt... -I&ezīmēt pēc tipa -A&tcelt pēc tipa -700 -&Lielas ikonas -&Mazas ikonas -&Saraksts -Sī&kāk -730 -&Nešķirot - -&2 paneļi -&Rīku joslas -&Atvērt saknes mapi -Līmeni &uz augšu -Mapju &vēsture... -&Pārlasīt -750 -Arhīva rīku josla -Standarta rīku josla -Lielas pogas -Parādīt pogu tekstu -800 -&Pievienot mapi iecienītajām kā -Iecienītās -900 -&Uzstādījumi... -&Darbspējas pārbaude -960 -&Rokasgrāmatas saturs... -&Par 7-Zip... -1003 -Ceļš -Nosaukums -Paplašinājums -Mape -Lielums -Saspiests -Atribūti -Izveidots -Atvērts -Pārveidots -Blīvs -Piezīmes -Šifrēts -Dalīts pirms -Dalīts pēc -Vārdnīca -CRC -Veids -Anti -Paņēmiens -Sistēma -Failu sistēma -Lietotājs -Grupa -Bloks -Piezīmes -Pozīcija - - - - - - - - - - - - - - - - - - - - - - - - - -Kļūda -Tilpums -Brīvā vieta -Klāstera lielums -Nosaukums -Lokālais nosaukums -Provaiders -2100 -Uzstādījumi -Valoda -Valoda: -Labošana -&Labošanas programma: - -2200 -Sistēma -Piesaistīt 7-Zip pie: -2301 -&Integrēt 7-Zip Windows vides kontekstizvēlē -&Kaskādveida kontekstizvēle -Kontekstizvēles elementi: -2320 - - -Atvērt arhīvu -Izvilkt failus... -Ielikt arhīvā... -Pārbaudīt arhīvu -Izvilkt šeit -Izvilkt {0} mapē -Ielikt {0} -Saspiest, sūtīt pa e-pastu... -Saspiest {0}, sūtīt pa e-pastu -2400 -Mapes -&Darba mape -&Sistēmas pagaidfailu mape -&Tekošā -&Noteikt: -&Izmantot tikai maināmajiem nesējiem -Norādiet vietu arhīvu pagaidfailiem. -2500 -Uzstādījumi -Parādīt ".." &vienību -Parādīt īstās &failu ikonas -Parādīt &sistēmas izvēli -&Pilnas rindas iezīmēšana -Parādīt at&dalošās līnijas - - - -2900 -Par 7-Zip -7-Zip ir bezmaksas programma, tomēr, reģistrējoties jūs varat 7-Zip izstrādāšanu atbalstīt. -3000 - -Kļūdu nav. -Iezīmēts(i) {0} objekts(i) -Mapi '{0}' neizdevās izveidot. -Šis arhīvs neatbalsta pārveidošanu. - - - - -Fails '{0}' ir pārveidots.\nVai vēlaties to atjaunināt arī arhīvā? -Failu nav iespējams uzlabot\n'{0}' -Nav iespējams palaist labošanas programmu. - - - - -Par daudz vienību. -3300 -Izvilkšana -saspiešana -Pārbaude -Atvēršana... - -3400 -Izvilkšana -&Izvilkt uz: -Norādiet vietu izvelkamiem failiem. -3410 -Ceļi -Pilni &ceļu nosaukumi -&Bez ceļu nosaukumiem -3420 -Pārrakstīšana -&Jautāt pirms pārrakstīšanas -Pārra&kstīt bez jautāšanas -I&zlaist esošos failus -A&utopārdēvēšana -Automātiski pārdēvēt esošos failu -3500 -Apstipriniet faila aizvietošanu -Mērķa mape jau satur apstrādājamo failu. -Vai vēlaties aizvietot esošo failu -ar šo? -{0} baiti -Autopārdēvēšana -3700 -Neatbalstīts saspiešanas paņēmiens '{0}' failam. -Datu kļūda '{0}'. Fails ir bojāts. -CRC kļūda '{0}'. Fails ir bojāts. - - -3800 -Paroles ievadīšana -Ievadiet paroli: - -Par&ole redzama - - - -&Parole -3900 -Pagājušais laiks: -Atlikušais laiks: -Lielums: -Ātrums: - - -Kļūdas: - -4000 -Pievienošana arhīvam -Ar&hīvs: -Pār&veidošanas režīms: -Arhīva &formāts: -&Saspiešanas līmenis: -&Saspiešanas paņēmiens: -&Vārdnīcas lielums: -Vār&da lielums: - - -Parame&tri: -&Uzstādījumi -Izveidot SF&X arhīvu - - - -Šifrēt failu &nosaukumus -Atmiņa arhivēšanai: -Atmiņa atarhivēšanai: -4050 -Uzkrāšana nesaspiežot -Ātrākais -Ātrais -Parastais -Maksimālā saspiešana -Ultra -4060 -Pievienot un aizvietot failus -Atjaunināt un pievienot failus -Atjaunināt esošos failus -Sinhronizēt failus -4070 -Pārlūkošana -Visi faili - - -6000 -Kopēt -Pārvietot -Kopēt uz: -Pārvietot uz: -Kopēšana... -Pārvietošana... -Pārdēvēšana... - -Darbība nav atbalstīta. -Faila vai mapes pārdēvēšanas kļūda - - -6100 -Faila dzēšanas apstiprinājums -Mapes dzēšanas apstiprinājums -Vairāku failu dzēšanas apstiprinājums -Vai piekrītat '{0}' dzēšanai? -Vai piekrītat mapes '{0}' un visa tās satura dzēšanai? -Vai piekrītat šo {0} vienību dzēšanai? -Dzēšana... -Faila vai mapes dzēšanas kļūda - -6300 -Mapes izveidošana -Faila izveidošana -Mapes nosaukums: -Faila nosaukums: -Jauna mape -Jauns fails -Mapes izveidošanas kļūda -Faila izveidošanas kļūda -6400 -Piezīmes -&Piezīmes: -Iezīmēšana -Iezīmējuma atcelšana -Šablons: -6600 - -Mapju vēsture -Diagnostikas paziņojumi -Paziņojums -7100 -Dators -Tīkls - -Sistēma -7200 -Ievietot -Izvilkt -Pārbaude -Kopēt -Pārvietot -Dzēst -Info -7300 -Sadalīt failu -&Dalīt uz: -&Dalīt sējumos, baitos: -Dalīšana... - - - - - -7400 -Apvienot failus -&Apvienot uz: -Apvienošana... - - - -7500 - - - - -7600 -Darpspējības pārbaude -Atmiņas pielietojums: -Arhivēšana -Atarhivēšana -Vērtējums -Kopējais vērtējums -Patreizējais -Rezultējošais - - -Izdošanās: diff -Nru p7zip-rar-16.02/GUI/Lang/mk.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/mk.txt --- p7zip-rar-16.02/GUI/Lang/mk.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/mk.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.09 : Gabriel Stojanoski -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Macedonian -Македонски -401 -Ок -Откажи - - - -&Да -&Не -&Затвори -Помош - -П&родолжи -440 -Да &Сите -Не Н&иедна -Стоп -Рестартирај -По&задина -&Напред -&Пауза -Паузирано -Дали сигурно сакате да откажете? -500 -&Датотека -&Уреди -&Изглед -&Омилени -&Алатки -&Помош -540 -&Отвори -Отвори &Внатре -Отвори &Надвор -&Поглед -&Уреди -&Преименувај -&Копирај Во... -&Премести Во... -&Избриши -&Подели датотека... -Ком&бинирај датотеки... -&Карактеристики -К&оментар - - -Креирај Директориум -Креирај Датотека -&Излези -600 -Селектирај &Се -Деселектирај Се -&Обратна Селекција -Селектирај... -Деселектирај... -Селектирај по Тип -Деселектирај по Тип -700 -&Големи Икони -&Мали Икони -&Листа -&Детали -730 -Неподредени - -&2 Панели -&Алатници -Отвори го основниот директориум -Едно Ниво Нагоре -Историја на Директориумите... -&Обнови -750 -Алатница на Архивата -Стандардна Алатница -Големи Копчиња -Текст На Копчињата -800 -&Додади го директориумот во Омилени -Забелешки -900 -&Опции... -&Тест -960 -&Содржина... -&За 7-Zip... -1003 -Патека -Име -Екстензија -Директориум -Големина -Пакувана Големина -Атрибути -Креирано -Пристапено -Променето -Целосна -Објаснета -Енкриптирана -Подели Пред -Подели После -Речник -CRC -Тип -Анти -Метод -Оперативен Систем -Датотечен Систем -Корисник -Група -Блок -Коментар -Позиција - - - - - - - - - - - - - - - - - - - - - - - - - -Грешка -Вкупна Големина -Слободен Простор -Голем на Кластерите -Етикета -Име -Провајдер -2100 -Опции -Јазик -Јазик: -Едитор -&Едитор: - -2200 -Систем -Придружи го 7-Zip со: -2301 -Интегрирај го 7-Zip во додатно мени -Каскадно додатно мени -Во додатното мени: -2320 -<Директориум> -<Архива> -Отвори архива -Отпакувај датотеки... -Додади во Архива... -Тестирај архива -Отпакувај овде -Отпакувај во {0} -Додади во {0} -Компресирај и прати на e-mail... -Компресирај во {0} и испрати -2400 -Директориуми -&Работен директориум -&Системски привремен директориум -&Моментален -&Одреди: -Само за преносни уреди -Одреди локација за привремените архивски датотеки. -2500 -Подесувања -Прикажи ".." предмет -Прикажи вистински икони -Прикажи системско мени -&Селектирај &цел ред -Прикажи &мрежа - - - -2900 -За 7-Zip -7-Zip е бесплатен архивер. Меѓутоа, вие можете да дадете поддршка на понатамошното развивање на 7-Zip со вашето регистрирање. -3000 - -Нема грешки -{0} објект(и) избрано -Не е можно креирање на директориумот '{0}' -Оваа операција не е поддржана за овој тип на архива. - - - - -Датотеката '{0}' е модифицирана.\nДали сакате да ја обновите во архивата? -Не е можно обновување на датотеката\n'{0}' -Грешка при стартување на Едиторот. - - - - -Премногу објекти -3300 -Отпакување -Компресирање -Тестирање -Отворање... - -3400 -Отпакувај -Отпакувај &во: -Одреди локација за отпакуваните датотеки. -3410 -Патеки -Целосна патека -Без патека -3420 -Презапишување -Прашај пред да презапишеш -Презапиши без прашување -Изостави постоечки датотеки -Автоматски преименувај -Автоматски преименувај постоечки датотеки -3500 -Потврди Замена на Датотеки -Конечниот директориум веќе ја содржи датотеката. -Дали сакате да ја замените постоечката датотека -со оваа? -{0} бајти -&Автоматски преименувај -3700 -Неподдржан метод за компресија за '{0}'. -Грешка во податоците во '{0}'. Датотеката е оштетена. -CRC грешка во '{0}'. Датотеката е оштетена. - - -3800 -Внеси лозинка -Внеси лозинка: - -&Прикажи ја лозинката - - - -Лозинка -3900 -Поминато време: -Преостанато време: -Големина: -Брзина: - - -Грешки: - -4000 -Додади во архива -&Архива: -&Додавање: -&Формат на Архива: -&Ниво на компресија: -&Метод на компресија: -Големина на &речникот: -Големина на &зборот: - - -&Параметри: -Опции -Креирај SFX ар&хива - - - -&Енкриптирај ги имињата -Искорист мемор за компрес: -Искорист мемор за декомпрес: -4050 -Спакувај -Најбрзо -Брзо -Нормално -Максимално -Ултра -4060 -Додади и замени датотеки -Обнови и додади датотеки -Обнови ги постоечките датотеки -Синхронизирај ги датотеките -4070 -Барај -Сите Датотеки - - -6000 -Копирај -Премести -Копирај Во: -Премести Во: -Копирање... -Преместување... -Преименување... - -Постапката не е поддржана. -Грешка при преименувањето на Датотеката или Директориумот - - -6100 -Потврдете го Бришењето на Датотеката -Потврдете го Бришењето на Директориумот -Потврдете го бришењето на повеќе датотеки -Дали сте сигурни за бришењето на '{0}'? -Дали сте сигурни за бришењето на директориумот '{0}' и неговата содржина? -Дали сте сигурни за бришењето на овие {0} датотеки? -Бришење... -Грешка при бришењето на Датотеката или Директориумот - -6300 -Креирај Директориум -Креирај датотека -Име на Директориумот: -Име на Датотеката: -Нов Директориум -Нова датотека -Грешка при креирањето на Директориумот -Грешка при креирањето на датотеката -6400 -Коментар -&Коментар: -Селектирај -Деселектитај -Маскирај: -6600 - -Историја на Директориумите -Дијагноза -Порака -7100 -Компјутер -Мрежа - -Систем -7200 -Додади -Отпакувај -Тестирај -Копирај -Премести -Избриши -Инфо -7300 -Подели датотека -&Подели на: -&Подели на делови, бајти: -Делење... - - - - - -7400 -Состави Датотеки -&Состави на: -Составување... - - - -7500 - - - - -7600 -Тест -Искорист Меморија: -Компресирање -Декомпресирање -Проценка -Вкупна Проценка -Моментално -Резултат - - -Поминато: diff -Nru p7zip-rar-16.02/GUI/Lang/mn.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/mn.txt --- p7zip-rar-16.02/GUI/Lang/mn.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/mn.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.12 : Bayar -; : Bayarsaikhan -; -; -; -; -; -; -; -; -; -0 -7-Zip -Mongolian -Монгол хэл -401 -За -Болих - - - -&Тийм -&Үгүй -&Хаах -Тусламж - -&Үргэлжлүүл -440 -Бүг&д тийм -Бүгд ү&гүй -Зогс -Дахин ачаалла -&Ар талд -&Өмнө тал -&Түр зогс -Түр зогслоо -Та үнэхээр болих гэж байна уу? -500 -&Файл -&Засах -&Үзүүлэх -Д&уртай зүйл -&Хэрэгслүүд -&Тусламж -540 -&Нээх -Дотор &нээх -Гадна &нээх -&Харах -&Засварлах -Нэр с&олих -...рүү &Хуулах... -...руу &Зөөх... -&Устгах -&Файл хуваах... -Файлуудыг нэгтгэх... -&Мэдээлэл үзэх -Тай&лбар - - -Хавтас үүсгэх -Файл үүсгэх -Га&рах -600 -Бүгдийг со&нгох -Сонгохоо болих -&Сонголтоо эргүүл -Сонгох... -Сонгохгүй... -Төрлөөр нь сонгох -Төрлөөр нь сонгохгүй -700 -Том& дүрсүүд -Жи&жиг дүрсүүд -&Жагсаалт -&Дэлгэрэнгүй -730 -Ангилаагүй - -&2 самбарууд -&Багажны самбар -Гол хавтсыг нээх -Нэг төвшин дээш -Хавтасны түүх... -&Сэргээ -750 -Aрхив багажны самбар -Стандарт багажны самбар -Том товчлуурууд -Товчлуурын текстийг үзүүл -800 -&Хавтсыг дуртайдаа нэмэх үү -Хавчуурга -900 -&Сонголтууд... -&Бэнчмарк -960 -&Агуулгууд... -&7-Зип-ийн тухай... -1003 -Зам -Нэр -Өргөтгөл -Хавтас -Хэмжээ -Багцалсан хэмжээ -Чанар -Үүсгэсэн -Хандсан -Өөрчилсөн -Баталгаатай -Тайлбар хийгдсэн -Нууцлагдсан -Өмнө хуваасан -Дараа хуваасан -Толь бичиг -CRC -Төрөл -Эсрэг -Арга -Хост ҮС -Файл систем -Хэрэглэгч -Бүлэг -Түгжих -Тайлбар -Байрлал - - - - - - - - - - - - - - - - - - - - - - - - - -Алдаа -Нийт хэмжээ -Хоосон зай -Кластерын зай -Нэр -Локаль Нэр -Хангагч -2100 -Сонголтууд -Хэл -Хэл: -Засварлагч -&Засварлагч: - -2200 -Систем -7-Зипийг дараахтай нэгтгэх: -2301 -7-Зип-ийг шелл контекст цэстэй нийлүүлэх -Контекст цэсийг цувуулан харуул -Контекст цэсийн төрлүүд: -2320 -<Хавтас> - -Архив нээх -Файлуудыг задал... -Архивт нэм... -Архивийн шалгалт -Энд задал -{0} руу задал -{0} рүү нэм -Шахах ба Шуудандах... -{0} рүү шахах ба Шууданд -2400 -Хавтсууд -&Ажлын хавтас -&Систем\завсрын хавтас -&Одоогийн -&Тодорхойлсон: -Зөвхөн зөөврийн төхөөрөмж хэрэглэх -Завсрын архив файл үүсгэх байрлалыг тодорхойл. -2500 -Тохируулгууд -Зүйл ".." үзүүлэх -Жинхэнэ файл дүрсийг харуулах -Системийн цэс харуул -&Бүтэн мөр сонгох -&Мөрийн дундах зураас харуулах - -&Сайжруулсан Сонгох горим -&Том санах ойн хуудас хэрэглэх -2900 -7-Zip-ийн тухай -7-Zip бол үнэгүй програм. Гэлээ ч та 7-Зип-д бүртгүүлэн хөгжүүлэгчдийг дэмжиж болно. Бүртгүүлсэн хэрэглэгчид техникийн дэмжлэг авах болно. -3000 - -Алдаа алга байна -{0} зүйл(үүд) сонгогдсон байна -Хавтас үүсгэж чадахгүй '{0}' -Дэмжигдээгүй архивийг задлах шинэчлэлт хийх. - - - - -Файл '{0}' өөрчлөгдлөө.\nТа архивт шинэчлэлт хиймээр байна уу? -Файлыг шинэчилж чадсангүй\n'{0} -Засварлагчийг нээж чадсангүй. - - - - -Дэндүү их юм байна -3300 -Задалж байна... -Шахаж байна -Шалгаж байна -Нээж байна... - -3400 -Задал -З&адлах газар: -Задалсан файлуудын байрлалыг тодорхойл. -3410 -Замын горим -Бүтэн замын нэр -Параметр алга -3420 -Давхарлаж бичих горим -Давхарлаж бичхээсээ өмнө асуух -Асуултгүй давхарлаж бичих -Байгаа файлыг алгасах -Автоматаар нэр солих -Байвал нэрийг нь солих -3500 -Файл дахин байрлуулахыг батлах -Хавтас файлыг агуулсан байна. -Байгаа файлуудыг дахин байрлуулах уу -Энүүнтэй юу? -{0} битүүд -A&втомат нэр солих -3700 -Дараах файлд шахалтын арга дэмжигдээгүй байна '{0}'. -'{0}'өгөгдлийн алдаа. Файл эвдэрсэн байна. -'{0}'CRC бүтсэнгүй. Файл эвдэрсэн байна. - - -3800 -Нууц үгээ оруулах -Нууц үгээ оруулах: - -&Нууц үг харуулах - - - -Нууц үг -3900 -Өнгөрсөн хугацаа: -Үлдсэн хугацаа: -Хэмжээ: -Хурд: - - -Алдаанууд: - -4000 -Архивт нэм -&Aрхив: -&Шинэчлэх горим: -Архив &өргөтгөл: -Шахалтын &төвшин: -Шахах &арга: -&Толь бичгийн хэмжээ: -&Үгийн хэмжээ: - - -&Параметерүүд: -Сонголтууд -SF&X архив үүсгэх - - - -&Файлын нэрүүдийг нууцал -Шахаж байгаа санах ойн хэрэглээ: -Задалж байгаа санах ойн хэрэглээ: -4050 -Хадгалах -Дээд хурданаар -Хурдан -Энгийн -Дээд хэмжээгээр -Ултра -4060 -Нэмэх ба дахин байрлуулах -Шинэчлэх ба дахин байрлуулах -Байгаа файлуудыг дахин унших -Файлуудыг тааруулах -4070 -Нэгжих -Бүх файлууд - - -6000 -Хуулах -Зөөх -хуулахдаа: -Зөөхдөө: -Хуулж байна... -Зөөж байна... -Нэр солиж байна... - -Үйлдэл дэмжигдээгүй байна. -Файл болон хавтсын нэрийг солиход алдаатай -Файл хуулахыг магадлах -Та үнэхээр файлуудыг архив руу хуулахыг хүсэж байна уу -6100 -Файл устгахыг батал -Хавтас устгахыг батал -Олон файл устгахыг батал -Та'{0}'-ийг устгах гэж байна уу? -'{0}' хавтас болон бүх агуулгыг устгах гэж байна уу? -{0} зүйлүүдийг устгах гэж байна уу? -Устгаж байна... -Файл болон хавтсыг устгахад алдаатай - -6300 -Хавтас үүсгэх -Файл үүсгэх -Хавтас нэр: -Файл нэр: -Шинэ хавтас -Шинэ файл -Хавтас үүсгэхэд алдаа гарав -Файл үүсгэхэд алдаа гарав -6400 -Тайлбар -&Тайлбар: -Сонгох -Сонгохгүй -Maск: -6600 - -Хавтсын түүх -Шинжилгээний зурвас -Зурвас -7100 -Компьютер -Сүлжээ - -Систем -7200 -Нэм -Задал -Шалгах -Хуулах -Зөөх -Устгах -Шинж... -7300 -Хуваах файл: -&Файл хуваах газар: -Эзлэхүүн рүү хуваах, битүүд: -Хувааж байна... - - - - - -7400 -Нэгтгэх файлууд: -&Нэгтгэх газар: -Нэгтгэж байна... - - - -7500 - - - - -7600 -Бэнчмарк -Санах ойн хэрэглээ: -Шахаж байна -Задалж байна -Үнэлж байна -Нийт үнэлгээ -Одоогийн -Хариуг гаргаж байна - - -Өнгөрсөн: diff -Nru p7zip-rar-16.02/GUI/Lang/mng.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng.txt --- p7zip-rar-16.02/GUI/Lang/mng.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 7-Zip 9.20 -; Saqirilatu Mongolqileb -; QQ:136087084 Email:saqirilatu@126.com -; Mongol soft QQ bulug Ⅰ: 39338772 Ⅱ:38803882 -; Toli Mongolian IME -; http://hi.baidu.com/saqirilatuu/item/9438213716f316ebe7bb7a8d -;last updated: 2014-1-1 -; -; -; -; -0 -7-Zip -Mongolian (Unicode) -ᠮᠤᠩᠭᠤᠯ ᠬᠡᠯᠡ -401 -ᠲᠡᠭᠡ -ᠤᠰᠠᠳᠬᠠᠬᠤ - - - -ᠲᠡᠭᠡ (&Y) -ᠪᠣᠯᠢ (&N) -ᠬᠠᠭᠠᠬᠤ (&C) -ᠬᠠᠪᠰᠤᠷᠤᠮᠵᠢ - -ᠵᠠᠯᠭᠠᠭᠠᠳ (&C) -440 -ᠪᠦᠭᠦᠳᠡ ᠲᠡᠭᠡ (&A) -ᠪᠦᠭᠦᠳᠡ ᠪᠣᠯᠢ (&L) -ᠵᠣᠭᠰᠣᠭᠠᠬᠤ -ᠳᠠᠬᠢᠨ ᠡᠬᠢᠯᠡᠬᠦ -ᠠᠷᠤ ᠲᠠᠯ᠎ᠠ (&B) -ᠡᠮᠦᠨ᠎ᠡ ᠲᠠᠯ᠎ᠠ (&F) -ᠵᠣᠭᠰᠣᠭᠠᠬᠤ (&P) -ᠨᠢᠭᠡᠨᠲᠡ ᠵᠣᠭᠰᠣᠪᠠ -ᠲᠠ ᠦᠨᠡᠬᠡᠷ ᠤᠰᠠᠳᠬᠠᠬᠤ ᠦᠦ ︖ -500 -ᠹᠠᠶᠢᠯ (&F) -ᠨᠠᠶᠢᠷᠠᠭᠤᠯᠬᠤ (&E) -ᠦᠵᠡᠬᠦ (&V) -ᠬᠠᠳᠠᠭᠠᠯᠠᠬᠤ (&A) -ᠪᠠᠭᠠᠵᠢ (&T) -ᠬᠠᠪᠰᠤᠷᠤᠮᠵᠢ (&H) -540 -ᠨᠡᠭᠡᠭᠡᠬᠦ (&O) -ᠣᠳᠣᠬᠢ ᠴᠣᠩᠬᠣ  ᠶᠢ ᠨᠡᠭᠡᠭᠡᠬᠦ (&I) -ᠰᠢᠨ᠎ᠡ ᠴᠣᠩᠬᠣ ᠪᠠᠶᠢᠭᠤᠯᠤᠭᠠᠳ ᠨᠡᠭᠡᠭᠡᠬᠦ (&U) -ᠵᠢᠷᠤᠭ ᠦᠵᠡᠬᠦ (&V) -ᠨᠠᠶᠢᠷᠠᠭᠤᠯᠬᠤ (&E) -ᠲᠠᠬᠢᠨ ᠨᠡᠷᠡᠯᠡᠬᠦ (&M) -ᠬᠣᠣᠰᠯᠠᠬᠤ (&C) -ᠰᠢᠯᠵᠢᠭᠦᠯᠬᠦ (&M) -ᠤᠰᠠᠳᠬᠠᠬᠤ (&D) -ᠹᠠᠶᠢᠯ ᠬᠤᠪᠢᠶᠠᠬᠤ (&S)... -ᠹᠠᠶᠢᠯ  ᠢ ᠨᠡᠶᠢᠯᠡᠭᠦᠯᠬᠦ (&B)... -ᠰᠢᠨᠵᠢ ᠴᠢᠨᠠᠷ (&R) -ᠲᠠᠶᠢᠯᠪᠤᠷᠢ (&N) -ᠹᠠᠶᠢᠯ ᠰᠢᠯᠭᠠᠬᠤ -ᠹᠠᠶᠢᠯ ᠠᠳᠠᠯᠢᠳᠬᠠᠬᠤ -ᠰᠢᠨ᠎ᠡ ᠬᠠᠪᠲᠠᠰᠤ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠹᠠᠶᠢᠯ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠭᠠᠷᠬᠤ (&X) -600 -ᠪᠦᠬᠦᠨ  ᠢ ᠰᠣᠩᠭᠣᠬᠤ (&A) -ᠪᠦᠬᠦᠨ  ᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠡᠰᠡᠷᠭᠦ ᠰᠣᠩᠭᠣᠬᠤ (&I) -ᠰᠣᠩᠭᠣᠬᠤ ... -ᠤᠰᠠᠳᠬᠠᠬᠤ ᠪᠠᠨ ᠰᠣᠩᠭᠣᠬᠤ ... -ᠠᠳᠠᠯᠢ ᠬᠡᠯᠪᠡᠷᠢ  ᠶᠢᠨ ᠹᠠᠶᠢᠯ  ᠢ ᠰᠣᠩᠭᠣᠬᠤ -ᠠᠳᠠᠯᠢ ᠬᠡᠯᠪᠡᠷᠢ  ᠶᠢᠨ ᠹᠠᠶᠢᠯ  ᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ -700 -ᠶᠡᠬᠡ ᠵᠢᠷᠤᠭ (&G) -ᠪᠠᠭ᠎ᠠ ᠵᠢᠷᠤᠭ (&M) -ᠵᠢᠭᠰᠠᠭᠠᠬᠤ (&L) -ᠨᠠᠷᠢᠨ ᠠᠭᠤᠯᠭ᠎ᠠ (&D) -730 -ᠮᠥᠷᠯᠡᠬᠦ ᠦᠭᠡᠢ -ᠲᠡᠭᠰᠢ ᠬᠡᠪ -ᠬᠣᠣᠰ ᠨᠢᠭᠤᠷ (&2) -ᠪᠠᠭᠠᠵᠢ  ᠶᠢᠨ ᠰᠠᠮᠪᠠᠷ᠎ᠠ (&T) -ᠦᠨᠳᠦᠰᠦ ᠬᠠᠪᠲᠠᠰᠤ ᠨᠡᠭᠡᠭᠡᠬᠦ -ᠳᠡᠭᠡᠭᠰᠢ -ᠬᠠᠪᠲᠠᠰᠤᠨ ‍ᠣ ᠲᠡᠦᠬᠡ ... -ᠰᠢᠨᠡᠳᠬᠡᠬᠦ (&R) -750 -ᠳᠠᠩᠰᠠᠨ ‍ᠣ ᠪᠠᠭᠠᠵᠢ  ᠶᠢᠨ ᠰᠠᠮᠪᠠᠷ᠎ᠠ -ᠪᠠᠷᠢᠮᠵᠢᠶ᠎ᠠ ᠪᠠᠭᠠᠵᠢ  ᠶᠢᠨ ᠰᠠᠮᠪᠠᠷ᠎ᠠ -ᠶᠡᠬᠡ ᠳᠠᠷᠤᠪᠴᠢ -ᠳᠠᠷᠤᠪᠴᠢ  ᠶᠢᠨ ᠦᠰᠦᠭ ᠢᠯᠡᠷᠡᠬᠦ -800 -ᠬᠠᠳᠠᠭᠠᠯᠠᠮᠵᠢ ᠲᠠᠭᠠᠨ ᠨᠡᠮᠡᠬᠦ (&A) -ᠱᠣᠰᠢᠭ᠎ᠠ -900 -ᠰᠣᠩᠭᠣᠯᠲᠠ (&O) -ᠥᠭᠭᠦᠭᠳᠡᠯ ᠰᠢᠯᠭᠠᠯᠲᠠ (&B) -960 -ᠬᠠᠪᠰᠤᠷᠤᠮᠵᠢ ᠦᠵᠡᠬᠦ (&C) -7-Zip ‍ᠣ ᠲᠤᠬᠠᠢ (&A) -1003 -ᠵᠠᠮ -ᠨᠡᠷᠡᠶᠢᠳᠦᠯ -ᠥᠷᠭᠡᠳᠭᠡᠭᠰᠡᠨ ᠨᠡᠷ᠎ᠡ -ᠬᠠᠪᠲᠠᠰᠤ -ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠠᠪᠴᠢᠶᠠᠭᠰᠠᠨ ‍ᠣ ᠳᠠᠷᠠᠭᠠᠬᠢ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠰᠢᠨᠵᠢ ᠴᠢᠨᠠᠷ -ᠪᠠᠶᠢᠭᠤᠯᠤᠭᠰᠠᠨ ᠴᠠᠭ -ᠦᠵᠡᠭᠰᠡᠨ ᠴᠠᠭ -ᠵᠠᠰᠠᠭᠰᠠᠨ ᠴᠠᠭ -ᠬᠠᠳᠠᠭᠤᠷ -ᠲᠠᠶᠢᠯᠪᠤᠷᠢ -ᠪᠠᠲᠤᠵᠢᠭᠤᠯᠬᠤ -ᠡᠮᠦᠨ᠎ᠡ ᠨᠢ ᠬᠤᠪᠢᠶᠠᠬᠤ -ᠰᠡᠭᠦᠯᠡᠷ ᠨᠢ ᠬᠤᠪᠢᠶᠠᠬᠤ -ᠲᠣᠯᠢ ᠪᠢᠴᠢᠭ  ᠦᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -CRC -ᠲᠥᠷᠥᠯ -ᠠᠷᠢᠯᠭᠠᠬᠤ ᠵᠦᠢᠯ -ᠲᠣᠭᠠᠴᠠᠬᠤ ᠠᠷᠭ᠎ᠠ -ᠭᠣᠣᠯ ᠠᠵᠢᠯᠯᠠᠬᠤ ᠰᠢᠰᠲ᠋ᠧᠮ -ᠹᠠᠶᠢᠯ  ᠤᠨ ᠰᠢᠰᠲ᠋ᠧᠮ -ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ -ᠪᠦᠯᠦᠭ -ᠥᠰᠦᠭ  ᠦᠨ ᠬᠡᠰᠡᠭ -ᠲᠠᠶᠢᠯᠪᠤᠷᠢ -ᠣᠷᠣᠨ ᠲᠣᠭᠲᠠᠭᠠᠬᠤ -ᠵᠠᠮ  ᠤᠨ ᠡᠮᠦᠨ᠎ᠡ ᠬᠡᠰᠡᠭ -ᠬᠠᠪᠲᠠᠰᠤ -ᠹᠠᠶᠢᠯ -ᠬᠡᠪ -ᠡᠪᠬᠡᠮᠡᠯ -ᠣᠯᠠᠨ ᠡᠪᠬᠡᠮᠡᠯ ᠠᠪᠴᠢᠭᠤᠯᠬᠤ -ᠬᠠᠵᠠᠭᠠᠢ ᠰᠢᠯᠵᠢᠭᠦᠯᠬᠦ -ᠵᠠᠯᠭᠠᠬᠤ -ᠥᠰᠦᠭ  ᠦᠨ ᠬᠡᠰᠡᠭ -ᠡᠪᠬᠡᠮᠡᠯ ᠬᠤᠪᠢᠶᠠᠬᠤ - -64 ᠣᠷᠣᠨ -ᠶᠡᠬᠡ ᠦᠰᠦᠭ  ᠦᠨ ᠬᠡᠰᠡᠭ  ᠦᠨ ᠳᠠᠷᠠᠭᠠᠯᠠᠯ -CPU -ᠹᠢᠽᠢᠺ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠹᠠᠶᠢᠯ  ᠤᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠨᠡᠶᠢᠯᠡᠪᠦᠷᠢ  ᠶᠢ ᠰᠢᠯᠭᠠᠬᠤ -ᠣᠨᠴᠠᠯᠢᠭ -ᠬᠡᠶᠢᠰᠪᠦᠷᠢ ᠬᠠᠶ᠋ᠢᠭ -ID -ᠵᠢᠭᠠᠬᠠᠨ ᠹᠠᠶᠢᠯ  ᠤᠨ ᠨᠡᠷ᠎ᠡ -ᠫᠷᠦᠭᠷᠡᠮ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠳᠡᠪᠢᠭᠦᠷ  ᠦᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠬᠡᠪ ᠵᠠᠭᠪᠤᠷ -ᠵᠠᠯᠭᠠᠬᠤ -ᠪᠤᠷᠤᠭᠤ -ᠶᠡᠷᠤᠩᠬᠡᠢ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠬᠡᠷᠡᠭᠯᠡᠭᠰᠡᠨ ᠣᠷᠣᠨ ᠵᠠᠢ -ᠪᠠᠭᠴᠠ  ᠶᠢᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠡᠪᠬᠡᠮᠡᠯ  ᠦᠨ ᠲᠡᠮᠳᠡᠭ -ᠲᠤᠰ ᠭᠠᠵᠠᠷ  ᠤᠨ ᠨᠡᠷᠡᠶᠢᠳᠦᠯ -ᠬᠠᠩᠭᠠᠭᠴᠢ -2100 -ᠰᠣᠩᠭᠣᠯᠲᠠ -ᠬᠡᠯᠡ -ᠬᠡᠯᠡ ᠰᠣᠩᠭᠣᠬᠤ᠄ -ᠨᠠᠶᠢᠷᠠᠭᠤᠯᠤᠭᠴᠢ -ᠲᠣᠭᠲᠠᠭᠰᠠᠨ ᠨᠠᠶᠢᠷᠠᠭᠤᠯᠤᠭᠴᠢ (&E): -ᠲᠣᠭᠲᠠᠭᠰᠠᠨ ᠹᠠᠶᠢᠯ  ᠢ ᠠᠳᠠᠯᠢᠳᠬᠠᠬᠤ (&D): -2200 -ᠰᠢᠰᠲ᠋ᠧᠮ -7-Zip ᠪᠠᠷ ᠹᠠᠶᠢᠯ  ᠤᠨ ᠲᠥᠷᠥᠯ  ᠢ ᠬᠣᠯᠪᠣᠭᠳᠠᠭᠤᠯᠬᠤ ᠄ -2301 -7-Zip ᠶ᠋ᠢ ᠪᠠᠷᠠᠭᠤᠨ ᠳᠠᠷᠤᠪᠴᠢ ᠳ᠋ᠥ ᠨᠡᠮᠡᠬᠦ -ᠪᠠᠷᠠᠭᠤᠨ ᠳᠠᠷᠤᠪᠴᠢ ᠳ᠋ᠥ ᠳᠠᠪᠬᠤᠴᠠᠭᠤᠯᠬᠤ -ᠪᠠᠷᠠᠭᠤᠨ ᠳᠠᠷᠤᠪᠴᠢ ᠳ᠋ᠥ ᠢᠯᠡᠷᠡᠬᠦ ᠺᠣᠳ᠋  ᠢ ᠰᠣᠩᠭᠣᠬᠤ -2320 -<ᠬᠠᠪᠲᠠᠰᠤ > -< ᠡᠪᠬᠡᠮᠡᠯ > -ᠠᠪᠴᠢᠮᠠᠯ  ᠢ ᠨᠡᠭᠡᠭᠡᠬᠦ -ᠮᠠᠲ᠋ᠧᠷᠢᠶᠠᠯ  ᠢ ᠭᠠᠷᠭᠠᠨ ᠠᠪᠬᠤ ... -ᠠᠪᠴᠢᠮᠠᠯ ᠳ᠋ᠥ ᠨᠡᠮᠡᠬᠦ ... -ᠠᠪᠴᠢᠮᠠᠯ  ᠢ ᠰᠢᠯᠭᠠᠬᠤ -ᠳᠣᠣᠷᠠᠬᠢ ᠭᠠᠷᠴᠠᠭ ᠳ᠋ᠥ ᠭᠠᠷᠭᠠᠨ ᠠᠪᠬᠤ -{0}ᠤᠷᠤᠭᠤ ᠵᠠᠳᠠᠯᠬᠤ -{0} ᠳ᠋ᠥ ᠨᠡᠮᠡᠬᠦ -ᠠᠪᠴᠢᠶᠠᠭᠠᠳ ᠢᠮᠸᠯ ᠶᠠᠪᠤᠭᠤᠯᠬᠤ ... -ᠠᠪᠴᠢᠶᠠᠭᠠᠳ {0}ᠶ᠋ᠢ ᠢᠯᠡᠭᠡᠬᠦ -2400 -ᠬᠠᠪᠲᠠᠰᠤ -ᠠᠵᠢᠯ  ᠤᠨ ᠬᠠᠪᠲᠠᠰᠤ (&W) -ᠰᠢᠰᠲ᠋ᠧᠮ \ ᠵᠠᠰᠠᠪᠤᠷᠢ  ᠶᠢᠨ ᠬᠠᠪᠲᠠᠰᠤ (&S) -ᠣᠳᠣ  ᠶᠢᠨ ᠬᠠᠪᠲᠠᠰᠤ (&C) -ᠲᠣᠭᠲᠠᠮᠠᠯ ᠪᠠᠶᠢᠷᠢ (&S) -ᠵᠥᠪᠬᠡᠨ ᠵᠥᠭᠡᠭᠡᠪᠦᠷᠢ  ᠶᠢᠨ ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠳ᠋ᠥ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ -ᠲᠦᠷ ᠴᠠᠭ  ᠤᠨ ᠠᠪᠴᠢᠮᠠᠯ ᠹᠠᠶᠢᠯ ᠡᠭᠦᠰᠬᠡᠬᠦ ᠪᠠᠶᠢᠷᠢᠯᠠᠯ  ᠢ ᠲᠣᠳᠣᠷᠬᠠᠶᠢᠯᠠᠯ -2500 -ᠢᠯᠡᠷᠡᠬᠦ -ᠢᠯᠡᠷᠡᠬᠦ “..” ᠵᠦᠢᠯ ( ᠳᠡᠭᠡᠭᠰᠢ ᠬᠣᠣᠰ ᠲᠣᠪᠴᠢᠳᠠᠭᠠᠳ ) -ᠦᠨᠡᠨ ᠵᠢᠷᠤᠭ ᠨᠢ ᠢᠯᠡᠷᠡᠬᠦ -ᠰᠢᠰᠲ᠋ᠧᠮ  ᠦᠨ ᠲᠣᠪᠶᠣᠭ ᠨᠢ ᠢᠯᠡᠷᠡᠬᠦ -ᠪᠦᠬᠦ ᠮᠥᠷ  ᠢ ᠰᠣᠩᠭᠣᠬᠤ (&F) -ᠰᠦᠯᠵᠢᠶᠡᠨ ᠤᠲᠠᠰᠤ ᠢᠯᠡᠷᠡᠬᠦ (&G) -ᠲᠣᠪᠴᠢᠳᠠᠭᠠᠳ ᠨᠡᠭᠡᠭᠡᠬᠦ -7-Zip ᠤᠯᠠᠮᠵᠢᠯᠠᠯᠲᠤ ᠬᠡᠪ  ᠢ ᠰᠣᠩᠭᠣᠬᠤ (&A) -ᠶᠡᠬᠡ ᠷᠠᠮ  ᠤᠨ ᠨᠢᠭᠤᠷ  ᠢ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ (&L) -2900 -7-Zip  ᠶᠢᠨ ᠲᠤᠬᠠᠢ -7-Zip ᠪᠣᠯ ᠲᠥᠯᠥᠪᠦᠷᠢ ᠦᠭᠡᠢ ᠰᠣᠹᠲ ᠂ ᠲᠠ ᠬᠠᠨᠳᠢᠪ  ᠤᠨ ᠬᠡᠯᠪᠡᠷᠢ ᠪᠠᠷ 7 -zip ᠶ᠋ᠢ ᠳᠡᠮᠵᠢᠵᠦ ᠪᠣᠯᠣᠨ᠎ᠠ ᠂ ᠮᠣᠩᠭᠣᠯ ᠰᠣᠹᠲ  ᠤᠨ ᠪᠦᠯᠦᠭ ᠨᠢᠭᠡ 39338772 ᠬᠣᠶᠠᠷ 38803882 ᠵᠢᠨ ᠰᠠᠴᠤᠷᠠᠯᠲᠤ ᠮᠣᠩᠭᠣᠯᠴᠢᠯᠠᠪᠠ ᠂ QQ 136087084 Email: saqirilatu@126.com -3000 -ᠰᠢᠰᠲ᠋ᠧᠮ ᠷᠠᠮ  ᠢ ᠨᠢ ᠬᠤᠪᠢᠶᠠᠵᠤ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠪᠤᠷᠤᠭᠤ ᠦᠭᠡᠢ -{0}  ᠢ ᠰᠣᠩᠭᠣᠬᠤ -{0}” ᠬᠠᠪᠲᠠᠰᠤ ᠪᠠᠶᠢᠭᠤᠯᠵᠤ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠲᠣᠰ ᠠᠪᠴᠢᠮᠠᠯ  ᠤᠨ ᠰᠢᠨᠡᠳᠬᠡᠬᠦ  ᠶᠢ ᠳᠡᠮᠵᠢᠬᠦ ᠦᠭᠡᠢ -ᠠᠪᠴᠢᠮᠠᠯ ᠨᠡᠭᠡᠭᠡᠵᠦ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ {0}” -ᠪᠠᠲᠤ ᠠᠪᠴᠢᠮᠠᠯ ᠨᠡᠭᠡᠭᠡᠵᠦ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ “{0}” ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠪᠤᠷᠤᠭᠤ -ᠳᠡᠮᠵᠢᠬᠦ ᠦᠭᠡᠢ ᠠᠪᠴᠢᠮᠠᠯ  ᠤᠨ ᠬᠡᠯᠪᠡᠷᠢ -{0} ᠹᠠᠶᠢᠯ ᠨᠢᠭᠡᠨᠲᠡ ᠪᠠᠶᠢᠨ᠎ᠠ -ᠹᠠᠶᠢᠯ“{0}”ᠥᠭᠡᠷᠡᠴᠢᠯᠡᠭᠳᠡᠪᠡ \nᠲᠠ ᠠᠪᠴᠢᠮᠠᠯ  ᠳᠠᠬᠢ ᠹᠠᠶᠢᠯ  ᠢᠶᠠᠨ ᠰᠢᠨᠡᠳᠬᠡᠬᠦ ᠦᠦ ? -ᠹᠠᠶᠢᠯ  ᠢ ᠰᠢᠨᠡᠳᠬᠡᠵᠦ ᠳᠡᠶᠢᠯᠦᠭᠰᠡᠨ ᠦᠭᠡᠢ \n“{0}”ᠲᠤᠰ ᠠᠪᠴᠢᠮᠠᠯ ᠪᠤᠷᠤᠭᠤ ᠭᠠᠷᠴᠠᠢ -ᠭᠠᠳᠠᠨᠠᠬᠢ ᠨᠠᠶᠢᠷᠠᠭᠤᠯᠭ᠎ᠠ  ᠶᠢ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠵᠤ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠲᠤᠰ ᠹᠠᠶᠢᠯ ᠬᠣᠣᠷ ᠲᠠᠢ ( ᠹᠠᠶᠢᠯ  ᠤᠨ ᠨᠡᠷ᠎ᠡ ᠳ᠋ᠥ ᠣᠯᠠᠨ ᠬᠣᠭᠣᠰᠤᠨ ᠵᠠᠢ ᠪᠠᠶᠢᠨ᠎ᠠ )。 -ᠬᠡᠲᠦᠷᠬᠡᠢ ᠤᠷᠲᠤ ᠂ ᠠᠵᠢᠯᠯᠠᠭᠤᠯᠵᠤ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠲᠠ ᠵᠢᠭᠠᠪᠠᠯ ᠨᠢᠭᠡ ᠹᠠᠶᠢᠯ ᠰᠣᠩᠭᠣᠨ᠎ᠠ -ᠲᠠ ᠬᠠᠮᠤᠭ ᠪᠠᠭ᠎ᠠ  ᠳᠠᠭᠠᠨ ᠨᠢᠭᠡ ᠹᠠᠶᠢᠯ ᠰᠣᠩᠭᠣᠨ᠎ᠠ -ᠮᠠᠲ᠋ᠧᠷᠢᠶᠠᠯ ᠬᠡᠲᠦᠷᠬᠡᠢ ᠣᠯᠠᠨ -3300 -ᠶᠠᠭ ᠭᠠᠷᠭᠠᠨ ᠠᠪᠴᠤ ᠪᠠᠶᠢᠨ᠎ᠠ .... -ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠰᠢᠯᠭᠠᠬᠤ -ᠶᠡᠬ ᠨᠡᠭᠡᠭᠡᠵᠦ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠬᠠᠶᠢᠵᠤ ᠪᠠᠶᠢᠨ᠎ᠠ ... -3400 -ᠭᠠᠷᠭᠠᠨ ᠠᠪᠬᠤ -(&X)  ᠠᠴᠠ ᠭᠠᠷᠭᠠᠨ ᠠᠪᠬᠤ : -ᠮᠠᠲ᠋ᠧᠷᠢᠶᠠᠯ  ᠢ ᠭᠠᠷᠭᠠᠨ ᠠᠪᠤᠭᠰᠠᠨ ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢᠨ ᠪᠠᠶᠢᠷᠢ -3410 -ᠵᠠᠮ  ᠤᠨ ᠬᠡᠯᠪᠡᠷᠢ -ᠪᠦᠷᠢᠨ ᠵᠠᠮ -ᠵᠠᠮ ᠦᠭᠡᠢ -3420 -ᠰᠣᠯᠢᠬᠤ ᠬᠡᠯᠪᠡᠷᠢ -ᠰᠣᠯᠢᠬᠤ  ᠠᠴᠠ ᠡᠮᠦᠨ᠎ᠡ ᠠᠰᠠᠭᠤᠨ᠎ᠠ -ᠰᠠᠨᠠᠭᠤᠯᠬᠤ ᠦᠭᠡᠢ ᠰᠢᠭᠤᠳ ᠰᠣᠯᠢᠬᠤ -ᠪᠠᠶᠢᠬᠤ ᠹᠠᠶᠢᠯ  ᠢ ᠥᠰᠦᠷᠬᠡᠶᠢᠯᠨᠨ ᠭᠠᠷᠬᠤ -ᠠᠦ᠋ᠲ᠋ᠣ᠋ ᠵᠢᠨᠷ ᠨᠡᠷᠡᠯᠡᠬᠦ -ᠣᠳᠣᠬᠢ ᠹᠠᠶᠢᠯ  ᠢᠶᠠᠨ ᠨᠡᠷᠡᠯᠡᠬᠦ -3500 -ᠹᠠᠶᠢᠯ  ᠢ ᠰᠣᠯᠢᠨ᠎ᠠ -ᠲᠣᠰ ᠬᠠᠪᠲᠠᠰᠤ ᠳ᠋ᠥ ᠠᠳᠠᠯᠢ ᠨᠡᠷᠡᠶᠢᠳᠦᠯ ᠲᠠᠢ ᠹᠠᠶᠢᠯ ᠪᠠᠶᠢᠨ᠎ᠠ -ᠣᠳᠣ ᠪᠠᠶᠢᠬᠤ ᠹᠠᠶᠢᠯ  ᠢᠶᠠᠨ -ᠰᠣᠯᠢᠬᠤ -{0}ᠦᠰᠦᠭ  ᠦᠨ ᠰᠢᠷᠬᠡᠭ -ᠠᠦ᠋ᠲ᠋ᠣ᠋ ᠰᠢᠨ᠎ᠡ ᠨᠡᠷᠡᠯᠡᠬᠦ (&U) -3700 -ᠳᠡᠮᠵᠢᠬᠦ ᠦᠭᠡᠢ ᠠᠪᠴᠢᠮᠠᠯ ᠲᠤᠭᠠᠴᠢᠯᠳᠠ “{0}”。 -ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ “{0}” ᠪᠤᠷᠤᠭᠤ ᠭᠠᠷᠴᠠᠢ ᠂ ᠹᠠᠶᠢᠯ ᠡᠪᠳᠡᠷᠡᠭᠰᠡᠨ ᠡ -CRC ᠰᠢᠯᠭᠠᠭᠠᠳ“{0}”ᠢᠯᠠᠭᠳᠠᠵᠠᠢ ᠂ ᠹᠠᠶᠢᠯ ᠡᠪᠳᠡᠷᠡᠭᠰᠡᠨ ᠡ -ᠪᠠᠲᠤ ᠹᠠᠶᠢᠯ “{0}”  ᠤᠨ ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ ᠨᠢ ᠪᠤᠷᠤᠭᠤ ᠂ ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠪᠤᠷᠤᠭᠤ -ᠪᠠᠲᠤ ᠹᠠᠶᠢᠯ “{0}” CRC  ᠵᠢᠨ ᠰᠢᠯᠭᠠᠭᠰᠠᠨ ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ ᠨᠢ ᠪᠤᠷᠤᠭᠤ ᠂ ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠪᠤᠷᠤᠭᠤ -3800 -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠣᠷᠣᠭᠤᠯᠬᠤ -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠣᠷᠣᠭᠤᠯᠬᠤ ᠄ -ᠳᠠᠬᠢᠨ ᠣᠷᠣᠭᠤᠯᠬᠤ -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠢᠯᠡᠷᠡᠬᠦ (&S) -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠪᠤᠷᠤᠭᠤ -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠵᠥᠪᠬᠡᠨ ᠠᠩᠭ᠍ᠯᠢ ᠬᠡᠯᠡ ᠪᠣᠯᠣᠨ ᠲᠣᠭ᠎ᠠ ᠬᠢᠭᠡᠳ ᠣᠨᠴᠠᠭᠠᠢ ᠲᠡᠮᠳᠡᠭ (!、#、$...) -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ ᠨᠢ ᠬᠡᠲᠦᠷᠬᠡᠢ ᠤᠷᠲᠤ -ᠨᠢᠭᠤᠴᠠ ᠨᠣᠮᠧᠷ -3900 -ᠬᠡᠷᠡᠭᠰᠡᠭᠰᠡᠨ ᠴᠠᠭ ᠄ -ᠦᠯᠡᠳᠡᠭᠰᠡᠨ ᠴᠠᠭ ᠄ -ᠶᠡᠷᠤᠩᠬᠡᠢ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -ᠬᠤᠷᠳᠤᠴᠠ ᠄ -ᠨᠢᠭᠡᠨᠲᠡ ᠰᠢᠢᠳᠪᠦᠷᠢᠯᠡᠭᠰᠡᠨ ᠨᠢ ᠄ -ᠠᠪᠴᠢᠶᠠᠭᠰᠠᠨ ᠬᠡᠮᠵᠢᠶ᠎ᠡ ᠄ -ᠪᠤᠷᠤᠭᠤ ᠭᠠᠷᠴᠠᠢ ᠄ -ᠠᠪᠴᠢᠮᠠᠯ ᠄ -4000 -ᠠᠪᠴᠢᠮᠠᠯ ᠳ᠋ᠥ ᠨᠡᠮᠡᠬᠦ -ᠠᠪᠴᠢᠮᠠᠯ (&A): -ᠰᠢᠨᠡᠳᠬᠡᠬᠦ ᠬᠡᠯᠪᠡᠷᠢ (&U): -ᠠᠪᠴᠢᠮᠠᠯ  ᠤᠨ ᠬᠡᠯᠪᠡᠷᠢ (&F): -ᠠᠪᠴᠢᠶᠠᠬᠤ ᠳᠡᠰ (&L): -ᠠᠪᠴᠢᠶᠠᠬᠤ ᠠᠷᠭ᠎ᠠ (&M): -ᠲᠣᠯᠢ  ᠶᠢᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ (&D): -ᠳᠠᠩ ᠦᠭᠡᠰ  ᠦᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ (&W): -ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ  ᠶᠢᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ -CPU ᠬᠡᠷᠡᠭᠯᠡᠭᠰᠡᠨ ᠬᠡᠮᠵᠢᠶ᠎ᠡ -ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ (&P): -ᠰᠣᠩᠭᠣᠯᠲᠠ -ᠥᠪᠡᠷᠲᠡᠭᠡᠨ ᠠᠴᠢᠶᠠᠯᠠᠭᠴᠢ ᠫᠷᠦᠭᠷᠡᠮ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ (&X) -ᠠᠪᠴᠢᠮᠠᠯ ᠹᠠᠶᠢᠯ  ᠢᠶᠠᠨ ᠬᠤᠪᠢᠶᠠᠯᠴᠠᠬᠤ -ᠪᠠᠲᠤᠵᠢᠭᠤᠯᠬᠤ -ᠪᠠᠲᠤᠵᠢᠭᠤᠯᠬᠤ ᠲᠣᠭᠠᠴᠠᠬᠤ ᠠᠷᠭ᠎ᠠ -ᠪᠠᠲᠤ ᠹᠠᠶᠢᠯ  ᠤᠨ ᠨᠡᠷᠡᠶᠢᠳᠦᠯ (&N) -ᠠᠪᠴᠢᠶᠠᠯᠠᠬᠤ ᠳ᠋ᠥ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ ᠷᠠᠮ -ᠵᠠᠳᠠᠯᠬᠤ ᠳ᠋ᠥ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ ᠷᠠᠮ -4050 -ᠵᠥᠪᠬᠡᠨ ᠬᠠᠳᠠᠭᠠᠯᠠᠬᠤ -ᠣᠨᠴᠠ ᠬᠤᠷᠳᠤᠨ ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠬᠤᠷᠳᠤᠨ ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠪᠠᠷᠢᠮᠵᠢᠶ᠎ᠠ ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠬᠠᠮᠤᠭ ᠶᠡᠬᠡ ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠴᠢᠨᠠᠷᠯᠠᠩᠭᠤᠢ ᠠᠪᠴᠢᠶᠠᠬᠤ -4060 -ᠹᠠᠶᠢᠯ ᠨᠡᠮᠡᠭᠡᠳ ᠰᠣᠯᠢᠬᠤ -ᠹᠠᠶᠢᠯ  ᠢ ᠰᠢᠨᠡᠳᠬᠡᠭᠡᠳ ᠨᠡᠮᠡᠬᠦ -ᠪᠠᠶᠢᠬᠤ ᠹᠠᠶᠢᠯ  ᠢ ᠰᠢᠨᠡᠳᠬᠡᠬᠦ -ᠠᠪᠴᠢᠮᠠᠯ  ᠤᠨ ᠠᠭᠤᠯᠭ᠎ᠠ  ᠶᠢ ᠵᠡᠷᠭᠡᠴᠡᠭᠦᠯᠬᠦ -4070 -ᠦᠵᠡᠬᠦ ... -ᠪᠦᠬᠦ ᠹᠠᠶᠢᠯ -ᠲᠡᠭᠡ -ᠪᠤᠯᠢ -6000 -ᠬᠣᠣᠰᠯᠠᠬᠤ -ᠰᠢᠯᠵᠢᠭᠦᠯᠬᠦ -ᠬᠣᠣᠰᠯᠠᠭᠤᠯᠤᠨ ᠄ -ᠰᠢᠯᠵᠢᠭᠦᠯᠦᠨ -ᠬᠣᠣᠰᠯᠠᠵᠤ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠰᠢᠯᠵᠢᠭᠦᠯᠵᠦ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠶᠠᠭ ᠰᠢᠨ᠎ᠡ ᠨᠡᠷᠡᠶᠢᠳᠴᠦ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠬᠠᠪᠲᠠᠰᠤ ᠰᠣᠩᠭᠣᠬᠤ -ᠣᠳᠣᠬᠢ ᠠᠵᠢᠯᠯᠠᠭ᠎ᠠ  ᠶᠢ ᠳᠡᠮᠵᠢᠬᠦ ᠦᠭᠡᠢ -ᠹᠠᠶᠢᠯ ᠪᠠ ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢ ᠲᠠᠬᠢᠨ ᠨᠡᠷᠡᠶᠢᠳᠴᠦ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠹᠠᠶᠢᠯ  ᠢ ᠬᠣᠣᠰᠯᠠᠬᠤ ᠦᠦ ︖ -ᠹᠠᠶᠢᠯ  ᠢ ᠠᠪᠴᠢᠮᠠᠯ ᠳ᠋ᠥ ᠬᠣᠣᠰᠯᠠᠬᠤ ᠦᠦ ︖ -6100 -ᠹᠠᠶᠢᠯ ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠣᠯᠠᠨ ᠹᠠᠶᠢᠯ  ᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠦᠨᠡᠬᠡᠷ“{0}” ᠶᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ ᠦᠦ ? -ᠦᠨᠡᠬᠡᠷ“{0}”ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢᠨ ᠪᠦᠬᠦ ᠠᠭᠤᠯᠭ᠎ᠠ  ᠶᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ ᠦᠦ ? -ᠦᠨᠡᠬᠡᠷ {0} ᠵᠢ ᠤᠰᠠᠳᠬᠠᠬᠤ ᠦᠦ ? -ᠤᠰᠠᠳᠬᠠᠵᠤ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠹᠠᠶᠢᠯ ᠪᠠ ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢ ᠤᠰᠠᠳᠬᠠᠵᠤ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -ᠰᠢᠰᠲ᠋ᠧᠮ ᠬᠡᠲᠦᠷᠬᠡᠢ ᠤᠷᠲᠤ ᠵᠠᠮ ᠲᠠᠢ ᠹᠠᠶᠢᠯ  ᠢ ᠬᠣᠭ ᠬᠤᠷᠢᠶᠠᠭᠴᠢ ᠳ᠋ᠥ ᠰᠢᠯᠵᠢᠭᠦᠯᠵᠦ ᠳᠡᠶᠢᠯᠬᠦ ᠦᠭᠡᠢ -6300 -ᠰᠢᠨ᠎ᠡ ᠬᠠᠪᠲᠠᠰᠤ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠰᠢᠨ᠎ᠡ ᠹᠠᠶᠢᠯ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢᠨ ᠨᠡᠷᠡᠶᠢᠳᠦᠯ ᠄ -ᠹᠠᠶᠢᠯ  ᠤᠨ ᠨᠡᠷ᠎ᠡ -ᠰᠢᠨ᠎ᠡ ᠬᠠᠪᠲᠠᠰᠤ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ -ᠰᠢᠨ᠎ᠡ ᠹᠠᠶᠢᠯ ᠪᠠᠶᠢᠭᠤᠯᠬᠤ .txt -ᠬᠠᠪᠲᠠᠰᠤ ᠪᠠᠶᠢᠭᠤᠯᠵᠤ ᠳᠡᠶᠢᠯᠦᠭᠰᠡᠨ ᠦᠭᠡᠢ -ᠰᠢᠨ᠎ᠡ ᠹᠠᠶᠢᠯ ᠪᠠᠶᠢᠭᠤᠯᠵᠤ ᠳᠡᠶᠢᠯᠦᠭᠰᠡᠨ ᠦᠭᠡᠢ -6400 -ᠲᠠᠶᠢᠯᠪᠤᠷᠢ -ᠲᠠᠶᠢᠯᠪᠤᠷᠢ (&C): -ᠰᠣᠩᠭᠣᠬᠤ -ᠰᠣᠩᠭᠣᠭᠰᠠᠨ  ᠢᠶᠠᠨ ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠨᠣᠮᠧᠷ ᠄ -6600 -ᠰᠢᠨᠵᠢ ᠴᠢᠨᠠᠷ -ᠬᠠᠪᠲᠠᠰᠤ  ᠶᠢᠨ ᠲᠡᠦᠬᠡ -ᠣᠨᠣᠰᠢᠯᠠᠭᠰᠠᠨ ᠰᠤᠷᠠᠭ -ᠰᠤᠷᠠᠭ -7100 -ᠮᠢᠨᠤ ᠺᠣᠮᠫᠢᠦ᠋ᠲ᠋ᠧᠷ -ᠰᠦᠯᠵᠢᠶᠡᠨ ‍ᠣ ᠬᠠᠨᠢ -ᠮᠢᠨᠤ ᠮᠠᠲ᠋ᠧᠷᠢᠶᠠᠯ -ᠰᠢᠰᠲ᠋ᠧᠮ -7200 -ᠨᠡᠮᠡᠬᠦ -ᠭᠠᠷᠭᠠᠨ ᠠᠪᠬᠤ -ᠰᠢᠯᠭᠠᠬᠤ -ᠬᠣᠣᠰᠯᠠᠬᠤ -ᠰᠢᠯᠵᠢᠭᠦᠯᠬᠦ -ᠤᠰᠠᠳᠬᠠᠬᠤ -ᠰᠤᠷᠠᠭ -7300 -ᠹᠠᠶᠢᠯ ᠰᠢᠯᠭᠠᠬᠤ -ᠹᠠᠶᠢᠯ  ᠢ (&S) ᠵᠦᠭ ᠰᠠᠯᠭᠠᠬᠤ᠄ -ᠡᠪᠬᠡᠮᠡᠯ ᠬᠤᠪᠢᠶᠠᠬᠤ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ (&V): -ᠰᠠᠯᠭᠠᠵᠤ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠰᠠᠯᠭᠠᠬᠤ ᠦᠦ -ᠲᠠ ᠹᠠᠶᠢᠯ  ᠢᠶᠠᠨ {0} ᠬᠡᠰᠡᠭ ᠬᠤᠪᠢᠶᠠᠬᠤ ᠦᠦ ︖ -ᠡᠪᠬᠡᠮᠡᠯ ᠬᠤᠪᠢᠶᠠᠭᠰᠠᠨ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ ᠨᠢ ᠤᠭ ᠹᠠᠶᠢᠯ  ᠠᠴᠠ ᠪᠠᠭ᠎ᠠ ᠪᠠᠶᠢᠬᠤ ᠬᠡᠷᠡᠭᠲᠡᠢ -ᠡᠪᠬᠡᠮᠡᠯ ᠬᠤᠪᠢᠶᠠᠬᠤ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ ᠨᠢ ᠪᠤᠷᠤᠭᠤ -ᠡᠪᠬᠡᠮᠡᠯ ᠬᠤᠪᠢᠶᠠᠬᠤ ᠶᠡᠬᠡ ᠪᠠᠭ᠎ᠠ  ᠶᠢ ᠲᠣᠭᠲᠠᠭᠠᠬᠤ {0} ᠦᠰᠦᠭ  ᠦᠨ ᠰᠢᠷᠬᠡᠭ \nᠲᠠ ᠳᠣᠣᠷᠠᠬᠢ ᠹᠠᠶᠢᠯ  ᠢ ᠬᠤᠪᠢᠶᠠᠬᠤ ᠦᠦ ? -7400 -ᠹᠠᠶᠢᠯ ᠨᠡᠶᠢᠯᠡᠭᠦᠯᠬᠦ -ᠹᠠᠶᠢᠯ  ᠢ (&S) ᠳ᠋ᠥ ᠨᠡᠶᠢᠯᠡᠭᠦᠯᠬᠦ -ᠨᠡᠶᠢᠯᠡᠭᠦᠯᠵᠦ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠬᠤᠪᠢᠷᠢ ᠡᠪᠬᠡᠮᠡᠯ  ᠦᠨ ᠲᠦᠷᠦᠭᠦᠦ ᠹᠠᠶᠢᠯ  ᠢ ᠰᠣᠩᠭᠣᠭᠠᠷᠠᠢ -ᠬᠤᠪᠢᠷᠢ ᠡᠪᠬᠡᠮᠡᠯ  ᠢ ᠲᠠᠨᠢᠬᠤ ᠦᠭᠡᠢ -ᠪᠤᠰᠤᠳ ᠬᠤᠪᠢᠷᠢ ᠡᠪᠬᠡᠮᠡᠯ ᠬᠠᠶᠢᠵᠤ ᠣᠯᠣᠭᠰᠠᠨ ᠦᠭᠡᠢ -7500 -ᠰᠢᠯᠭᠠᠵᠤ ᠪᠠᠶᠢᠨ᠎ᠠ ... -ᠰᠢᠯᠭᠠᠭᠰᠠᠨ ᠰᠤᠷᠠᠭ -CRC ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ ᠰᠢᠯᠭᠠᠬᠤ -CRC ᠲᠣᠭ᠎ᠠ ᠪᠠᠷᠢᠮᠲᠠ ᠪᠠ ᠹᠠᠶᠢᠯ  ᠤᠨ ᠨᠡᠷ᠎ᠡ  ᠶᠢ ᠰᠢᠯᠭᠠᠬᠤ : -7600 -ᠥᠭᠭᠦᠭᠳᠡᠯ ᠰᠢᠯᠭᠠᠯᠲᠠ -ᠷᠠᠮ ᠬᠡᠷᠡᠭᠯᠡᠯᠲᠡ ᠄ -ᠠᠪᠴᠢᠶᠠᠬᠤ -ᠵᠠᠳᠠᠯᠬᠤ -ᠣᠨᠣᠭ᠎ᠠ ᠥᠭᠬᠦ -ᠶᠡᠷᠤᠩᠬᠡᠢ ᠣᠨᠣᠭ᠎ᠠ -ᠣᠳᠣᠬᠢ -ᠦᠷ᠎ᠡ ᠳ᠋ᠦᠩ -CPUᠬᠡᠷᠡᠭᠯᠡᠭᠰᠡᠨ ᠬᠡᠮᠵᠢᠶ᠎ᠡ -ᠬᠡᠷᠡᠭᠯᠡᠭᠴᠢ  ᠶᠢᠨ ᠣᠨᠣᠭ᠎ᠠ -ᠪᠠᠲᠤᠯᠠᠭᠳᠠᠭᠰᠠᠨ ᠡ ᠄ diff -Nru p7zip-rar-16.02/GUI/Lang/mng2.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng2.txt --- p7zip-rar-16.02/GUI/Lang/mng2.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/mng2.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 7-Zip 9.20 -; Saqirilatu Mongolqileb -; QQ:136087084 Email:saqirilatu@126.com -; Mongol soft QQ bulug Ⅰ: 39338772 Ⅱ:38803882 -; Toli Mongolian IME -; http://hi.baidu.com/saqirilatuu/item/9438213716f316ebe7bb7a8d -;last updated: 2013-12-11 -; Update and Spelling corrected Bayarsaikhan -; -; -; -0 -7-Zip -Mongolian (MenkCode) -  -401 - - - - - - (&Y) - (&N) - (&C) - - - (&C) -440 -  (&A) -  (&L) - -  -  (&B) -  (&F) - (&P) -  -    ? -500 - (&F) - (&E) - (&V) - (&A) - (&T) - (&H) -540 - (&O) -    (&I) -    (&U) -  (&V) - (&E) -  (&M) - (&C) - (&M) - (&D) -  (&S)... -   (&B)... -  (&R) - (&N) -  -  -   -  - (&X) -600 -   (&A) -   -  (&I) - ... -   ... -      -      -700 -  (&G) -  (&M) - (&L) -  (&D) -730 -  -  -  (&2) -   (&T) -   - -   ... - (&R) -750 -     -    -  -    -800 -   (&A) - -900 - (&O) -  (&B) -960 -  (&C) -7-Zip   (&A) -1003 - - -  - -  -     -  -  -  -  - - - -   -   -     -CRC - -  -  -   -   - - -   - -  -    - - - - -   -  - -   -  - -64  -      -CPU -   -    -   - -  -ID -    -  -    -  - - -   -   -    -   -    - -2100 - - -  : - -  (&E): -    (&D): -2200 - -7-Zip       : -2301 -7-Zip      -    -       -2320 -< > -<  > -   -    ... -   ... -   -     -{0}  -{0}   -   ... - {0}   -2400 - -   (&W) - \  (&S) -   (&C) -  (&S) -      -         -2500 - - “..” (   ) -    -     -    (&F) -   (&G) -  -7-Zip     (&A) -      (&L) -2900 -7-Zip   -7-Zip           7-Zip        Ⅰ39338772 Ⅱ 38803882      QQ 136087084 Email: saqirilatu@126.com -3000 -       -  -{0}   -{0}”     -       -   “{0}” -     “{0}”    ? -     -{0}    - “{0}” \n       ? -     \n“{0}”,    -      -    (         )。 -     -     -       -   -3300 -    .... - - -   ... -  ... -3400 -  -(&X)   : -       -3410 -   -  -  -3420 -  -    -    -     -   -    -3500 -   -        -    - -{0}    -    (&U) -3700 -    “{0}”。 -  “{0}”  ,   -CRC  “{0}”,   -  “{0}”     ,    ? -  “{0}”CRC       ,    ? -3800 -    -    : -  : -   (&S) -    -           (!、#、$...) -    -  -3900 -  : -  : -   : - : -   : -  : - : -: -4000 -   - (&A): -  (&U): -   (&F): -  (&L): -  (&M): -    (&D): -     (&W): -     : -CPU  : -  (&P): - -    (&X) -    - -   : -    (&N) -    : -   : -4050 -  -   -  -  -   -  -4060 -   -    -    -     -4070 - ... -  - - -6000 - - -: -: -  ... -  ... -    ... -  -     -        -    -     -6100 -  -   -    -“{0}”  ? -“{0}”       ? - {0}  ? -  ... -       . -             -6300 -   -   -   : -  : -   -   .txt -    -     -6400 - - (&C): - -   -: -6600 -  -   -  - -7100 -  -   -  - -7200 - -  - - - - - -7300 -  -  (&S)   : -    (&V): -  ... -  -   {0}    ? -           -      -      :{0}    。\n      ? -7400 -  -  (&S)  : -  ... -       -     -      -7500 -  ... -  -CRC   : -CRC       : -7600 -  -  : - - -  -  - -  -CPU   -   -  : diff -Nru p7zip-rar-16.02/GUI/Lang/mr.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/mr.txt --- p7zip-rar-16.02/GUI/Lang/mr.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/mr.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.42 : अनुवाद सुबोध गायकवाड (Subodh Gaikwad) -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Marathi -मराठी -401 -ठीक -रद्द - - - -&हो -&नाही -&बंद -मदत - -&सुरु -440 -&सर्व ला हो -&सर्व ला नाही -थांबा -पुन्हा सुरु करा -&मागे लपवा -&समोर आणा -&विश्राम -विश्राम -तुम्हाला रद्द करण्याबाबत खात्री आहे का? -500 -&फ़ाइल -&संपादन -&दर्शन -आ&वडते -&अवजार -&मदत -540 -&उघडा -&अंदर उघडा -&बाहेर उघडा -&दृश्य -&संपादक -नाव बदल -&प्रतिलिपी... -&हलवा... -&मिटवा -&फ़ाइल तुकडे करा... -फ़ाइल जोडा... -लक्षणं -प्रतिक्रिया - - -फ़ोल्डर तयार करा -फ़ाइल तयार करा -गमन -600 -सर्व निवडा -सर्वांना अनिवडित करा -&निवड उलटी करा -निवडा... -अनिवडा... -प्रकारेद्वारा निवडा -प्रकारेद्वारे अनिवडा -700 -मोठे Icons -लहान Icons -&सुची -&माहिती -730 -अव्यवस्थित -Flat दृश्य -&२ फ़लक -&अवजार कप्पाs -Root फ़ोल्डर उघडा -एक वरती चढा -फ़ोल्डर इतिहास... -&टवटवीत करा -750 -दफ़तर अवजार कप्पा -प्रमाण अवजार कप्पा -मोठे कळ -कळ शब्द दाखवा -800 -&फ़ोल्डर आवडते मध्ये टाका... -पृष्ठ -900 -&पर्याय... -&Benchmark -960 -&माहिती... -7-Zip बद्दल... -1003 -मार्ग -नाव -शेपुट -फ़ोल्डर -आकार -दबलेला आकार -गुणधर्म -तयार -वापर -बदल -ठोस -भाष्य -बंधिस्त -या पुर्व तुकडे करा -या नंतर तुकडे करा -शब्दावली -CRC -प्रकार -विरुद्ध -पद्धत -यजमान आज्ञावली -फ़ाइल प्रणाली -उपयोगकर्ता -गट -गठ्ठा -प्रतिक्रिया -स्थिती -मार्गाची सुरुवात - - - - - - - - - - - - - - - - - - - - - - - - -चुक -एकूण आकार -खाली जागा -क्लस्टर आकार -शिर्षक -लोकल नाव -देणारा -2100 -पर्याय -भाषा -भाषा: -संपादक -&संपादक: - -2200 -प्रणाली -7-Zip संबधित करा: -2301 -7-Zip ला shell context मेनुशी जोडा -Cascaded context menu -Context मेनु वस्तू: -2320 - - -दफ़तर उघडा -फ़ाइल्स बाहेर काढा... -दफ़तरात टाका... -दफ़तर तपासा -येथे बाहेर काढा -बाहेर {0} -{0} येथे टाका -दाबा आणि इमेल करा... -{0} येथे दाबा आणि इमेल करा -2400 -फ़ोल्डर -&चलित फ़ोल्डर -&प्रणालीचे तात्पुरते फ़ोल्डर -&सध्या -&नमुद: -फक्त काढता येणाय्रा ड्रॉईव्हकरता वापरा -तात्पुरत्या दफ़तर करिता मार्ग दर्शवा. -2500 -स्थिती -वस्तू ".." दाखवा -फ़ाइलचे खरे icon दाखवा -प्रणालीचे मेनु दाखवा -&सर्व ओळ निवडा -&grid रेघा दाखवा - -&अतिरिक्त निवड पद्धती -मोठे स्मरणशक्ती पृष्ठ वापरा -2900 -7-Zip बद्दल माहिती -7-Zip हे मोफ़त सॉफ़्टवेअर आहे. तरिही, तुम्ही नोंद करुन याच्या प्रगतीला सहाय्य करू शकता. -3000 - -येथे एकही चूक नाही -निवडलेल्या वस्तू{0} -'{0}' फ़ोल्डर तयार होऊ शकले नाही -या दफ़तरासाठी नुतनीकरण शक्य नाही. - - - - -'{0}' ही फ़ाइल बदलली आहे.\nतुम्हाला हे दफ़तरात नुतन करायचे आहे का? -फ़ाइल नुतन करता येत नाही\n'{0}' -संपादक सुरु होत नाही. - - - - -खूपच जास्त वस्तू -3300 -बाहेर -दाब -तपासणी -उघडत आहे... -बारकाईने पाहत आहे... -3400 -बाहेर -&बाहेर: -फ़ाइल बाहेर काढण्यासाठी मार्ग नमूद करा. -3410 -मार्ग रित -पूर्ण पत्ता -पत्ता नाही -3420 -Overwrite रीत -overwrite करण्यापुर्वी विचारा -Overwrite न विचारता करा -अस्तित्वात असलेल्या फ़ाइल सोडा -स्वयंचलित नाव बदलवा -अस्तित्वात असलेल्या फ़ाइलचे आपोआप नाव बदलवा -3500 -फ़ाइल बदलवीणे खात्री -त्या फ़ोल्डरमध्ये अगोदरच कार्यान्वीत फ़ाइल आहे. -अस्तित्वात असलेली फ़ाइल बदलवायची आहे का? -यानी? -{0} बाइट्स -स्वयंचलित नाव बदलवा -3700 -असहाय्यक दाब पद्धत'{0}'. -डेटा चूक'{0}'. फ़ाइल तुटलेली आहे. -CRC अयशस्वी '{0}'. फ़ाइल तुटलेली आहे. - - -3800 -परवलिचा शब्द टाका -परवलिचा शब्द टाका: - -परवलिचा शब्द दाखवा - - - -परवलिचा शब्द -3900 -झालेला वेळ: -निघुन गेलेला वॆळ: -आकार: -वेग: - - -चूक: - -4000 -दफ़तरात टाका -&दफ़तर: -&नुतनीकरन रित: -दफ़तर &प्रकार: -दाब &level: -दाब &पद्धत: -&शब्द्कोश आकार: -&शब्द आकार: - - -&Parameters: -पर्याय -SF&X दफ़तर तयार करा - - - -फ़ाइल &नाव बंधिस्त करा -दाबण्यासाठी स्मरणशक्तीचा वापर: -प्रसरण पावण्यासाठी स्मरणशक्तीचा वापर: -4050 -साठा -अतिशय वेगवान -वेगवान -साधारण -जास्तीत जास्त -एकदमच -4060 -फ़ाइल टाका आणि ठेवा -फ़ाइल टाका आणि नुतन करा -अस्तित्वातील फ़ाइल ताजे करा -Synchronize फ़ाइल -4070 -ब्राउझ -सर्व फ़ाइल - - -6000 -प्रतिलिपी -हलवा -प्रतिलिपी: -हलवा: -प्रतिलिपी... -हलवल्या जात आहे... -नविन नाव दिल्या जात आहे... - -क्रिया करता येणार नाही. -फ़ाइल किंवा फ़ोल्डरला नविन नाव देता येत नाही आहे -फ़ाइलची प्रतिलिपी करण्यास तुमची खात्री आहे का -दफ़्तरात फ़ाइलची प्रतिलिपी करण्यास तुमची खात्री आहे का -6100 -फ़ाइल मिटवायची खात्री -फ़ोल्डर मिटवायची खात्री -अनेक फ़ाइल मिटवायची खात्री -तुम्हाला '{0}' मिटवायची खात्री आहे का? -तुम्हाला '{0}' फ़ोल्डर आणि त्यातील सर्व वस्तु मिटवायची खात्री आहे का? -तुम्हाला {0} वस्तु मिटवायची खात्री आहे का? -मिटत आहे... -फ़ाइल किंवा फ़ोल्डर मिटवता येत नाही आहे - -6300 -फ़ॊल्डर तयार करा -फ़ाइल तयार करा -फ़ोल्डर नाव: -फ़ाइलचे नाव: -नविन फ़ॊल्डर -नविन फ़ाइल -फ़ोल्डर तयार करता येत नाही आहे -फ़ाइल तयार करता येत नाही आहे -6400 -प्रतिक्रिया -&प्रतिक्रिया: -निवडा -निवड रद्द -मुखवटा: -6600 - -फ़ोल्डरचा इतिहास -उपचार संदेश -संदेश -7100 -संगणक -नेटवर्क - -प्रणाली -7200 -टाका -बाहेर -तपासा -प्रतिलिपी -हलवा -मिटवा -माहिती -7300 -फ़ाइलचे तुकडे करा -&येथे तुकडे: -तुकडे, बाइट्स: -तुकडे होत आहे... - - - - - -7400 -फ़ाइल जोडा -&येथे फ़ाइल जोडा: -फ़ाइल जुडत आहे... - - - -7500 -Checksum मोजत आहे... -Checksum माहिती -डेटाकरिता CRC checksum : -नाव आणि डेटाकरिता CRC checksum : -7600 -Benchmark -स्मरणशक्ती वापर: -दाबत आहे -प्रसरण होत आहे -क्रमांकन -एकुण क्रमांकन -सध्या -परिणाम - - -Passes: diff -Nru p7zip-rar-16.02/GUI/Lang/ms.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ms.txt --- p7zip-rar-16.02/GUI/Lang/ms.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ms.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.30 : Khairul Ridhwan Bin Omar -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Malay -Bahasa Melayu -401 -OK -Batal - - - -&Ya -&Tidak -&Tutup -Bantuan - -&Teruskan -440 -Ya untuk Semua -Tidak untuk Semua -Henti -Mula Semula -&Latar belakang -&Latar depan -&Berehat -Berehat -Anda yakin untuk membatalkannya? -500 -&Fail -&Edit -&Paparan -K&egemaran -&Alat -&Bantuan -540 -&Buka -Buka di D&alam -Buka di L&uar -&Paparan -&Edit -Nam&akan semula -&Salin ke... -&Pindahkan ke... -Hapus -&Bahagi/belah Fail... -Gab&ung Fail... -P&roperti -Kom&en - - -Buat Folder -Buat Fail -K&eluar -600 -Pilih &Semua -Jangan Pilih Semua -&Sonsangkan Pilihan -Pilih... -Tidak Memilih... -Pilih Berdasarkan Jenis -Tidak Memilih Berdasarkan Jenis -700 -Ikon B&esar -Ikon K&ecil -&Senarai -&Butiran -730 -Tidak Tersusun - -&2 Panel -&Toolbar -Buka Root Folder -Ke atas Satu Aras -Folder Sejarah... -&Segarkan Semula -750 -Toolbar Arkib -Toolbar Standard -Bebutang Besar -Perlihatkan Teks Bebutang -800 -&Tambah folder pada Kegemaran sebagai -Penanda Buku -900 -&Opsyen... -&Tanda Aras -960 -&Kandungan... -&Perihal 7-Zip... -1003 -Bahagian -Nama -Sambungan -Folder -Saiz -Saiz Paket -Atribut -Dibuat -Diakses -Diubah Suai -Solid -Komen -Terenkripsi -Terpisah Sebelum -Terpisah Selepas -Kamus -CRC -Jenis -Anti -Kaedah -Sistem Operasi -Sistem Fail -Pengguna -Kumpulan -Blok -Komen -Posisi - - - - - - - - - - - - - - - - - - - - - - - - - -Ralat -Saiz Keseluruhan -Ruang Kosong -Saiz Kluster -Label -Nama Tempatan -Penyedia -2100 -Opsyen -Bahasa -Bahasa: -Editor -&Editor: - -2200 -Sistem -Kongsikan 7-Zip dengan: -2301 -Integrasikan 7-Zip ke shell konteks menu -Cascaded konteks menu -Item pada konteks menu: -2320 - - -Buka arkib -Ekstrak fail... -Tambahkan ke arkib... -Uji arkib -Ekstrak di sini -Ekstrak ke {0} -Tambahkan ke {0} -Padatkan dan kirimkan melalui email... -Padatkan ke {0} dan kirimkan melalui email -2400 -Folder -&Folder kerja -&Folder sementara sistem -&Sekarang -&Ditentukan: -Hanya untuk pemacu mudah alih -Tentukan lokasi untuk arkib fail sementara. -2500 -Seting -Perlihatkan ".." item -Perlihatkan ikon asli dari fail -Perlihatkan menu sistem -&Pilih barisan penuh -Perlihatkan garisan grid - -&Mod Pilihan Alternatif -Gunakan muka surat memori yang &besar -2900 -Perihal 7-Zip -7-Zip adalah perisian percuma. Sokong pembangunan 7-Zip dengan melakukan pendaftaran. -3000 - -Tidak ada ralat -{0} buah objek telah terpilih -Tidak dapat membuat folder '{0}' -Tidak menyokong pengemaskinian untuk arkib ini. - - - - -Fail '{0}' telah terubah suai.\nApakah anda ingin mengemaskininya pada arkib? -Tidak dapat mengemaskini fail\n'{0}' -Tidak dapat membuka editor. - - - - -Terlalu banyak item -3300 -Sedang mengekstrak -Memampatkan -Pengujian -Membuka... - -3400 -Ekstrak -Ekstrak ke: -Tentukan lokasi untuk pengekstrakan fail. -3410 -Mod laluan -Laluan nama penuh -Tidak pakai nama laluan -3420 -Mod tulis semula -Tanya sebelum menulis semula -Tulis semula tanpa perlu diberitahu -Abaikan fail yang ada -Namakan semula automatik -Namakan automatik fail yang ada -3500 -Pastikan penggantian fail -Folder tujuan telah berisi fail yang telah terproses. -Mahukah anda menggantikan fail yang ada -dengan yang ini? -{0} baits -N&amakan semula Automatik -3700 -Kaedah pemampatan untuk '{0}' tidak disokong. -Data ralat di '{0}'. Fail ini rosak. -CRC gagal di '{0}'. Fail ini rosak. - - -3800 -Masukkan kata laluan -Masukkan kata laluan: - -&Perlihatkan kata laluan - - - -Kata laluan -3900 -Telah berlalu: -Selesai dalam: -Saiz: -Kecepatan: - - -Ralat: - -4000 -Tambahkan ke arkib -&Arkib: -&Mod kemaskini: -Format arkib: -Aras &mampatan: -Kaedah mampatan: -&Saiz kamus: -&Saiz perkataan: - - -&Parameter: -Opsyen -Buat arkib SF&X - - - -Enkripsi nama &fail -Penggunaan memori untuk Memampatkan: -Penggunaan memori untuk Menyah-mampatkan: -4050 -Untuk Penyimpanan -Lebih cepat -Cepat -Normal -Maksimum -Ultra -4060 -Tambah dan gantikan fail -Kemaskini dan tambahkan fail -Perbaharui fail yang ada -Menyesuaikan fail -4070 -Selusur... -Semua Fail - - -6000 -Salin -Pindah -Salin ke: -Pindah ke: -Sedang menyalin... -Sedang memindah... -Namakan semula... - -Operasi tidak disokong. -Ralat, ketika namakan semula Fail atau Folder -Pasti salinkan fail -Anda yakin untuk menyalinkan fail kepada arkib -6100 -Pasti penghapusan fail -Pasti penghapusan folder -Pasti penghapusan fail-fail -Anda yakin untuk menghapus '{0}'? -Anda yakin untuk menghapus folder '{0}' dan semua isi kandungannya? -Anda yakin untuk menghapus item {0}? -Penghapusan... -Ralat ketika menghapuskan Fail atau Folder - -6300 -Buat Folder -Buat Fail -Nama Folder: -Nama Fail: -Folder Baru -Fail Baru -Ralat, tidak dapat Membuat Folder -Ralat, tidak dapat Membuat Fail -6400 -Komen -&Komen: -Pilih -Tidak Memilih -Topeng: -6600 - -Folder Sejarah -Mesej diagnostik -Mesej -7100 -Komputer -Rangkaian - -Sistem -7200 -Tambah -Ekstrak -Uji -Salin -Pindah -Hapus -Maklumat -7300 -Pisahkan Fail -&Pisahkan ke: -Bahagi/belah ke &nilai, baits: -Pembelahan ... - - - - - -7400 -Gabungan Fail -&Gabung ke: -Penggabungan ... - - - -7500 - - - - -7600 -Tanda Aras -Penggunaan memori: -Pemampatan -Penyah-mampatan -Rating -Total Rating -Sekarang -Keputusan - - -Lulus: diff -Nru p7zip-rar-16.02/GUI/Lang/nb.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/nb.txt --- p7zip-rar-16.02/GUI/Lang/nb.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/nb.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.45 : Jostein Christoffer Andersen -; : Kjetil Hjartnes -; : Robert Grønning -; -; -; -; -; -; -; -; -0 -7-Zip -Norwegian Bokmal -Norsk Bokmål -401 -OK -Avbryt - - - -&Ja -&Nei -&Lukk -Hjelp - -&Fortsett -440 -Ja til &alt -Nei til a< -Stopp -Start på nytt -&Bakgrunn -&Forgrunn -&Stopp -Stoppet -Vil du avbryte? -500 -&Fil -&Rediger -&Vis -&Bokmerker -Verk&tøy -&Hjelp -540 -&Åpne -Åpne &internt -Åpne &eksternt -&Vis -&Rediger -Gi nytt &navn -&Kopier til … -&Flytt til … -S&lett -&Del opp arkiv … -&Sett sammen arkiv … -E&genskaper -&Kommentar … -Beregn sjekksum - -Ny &mappe … -Ny f&il … -&Avslutt -600 -Merk &alle -Merk i&ngen -Merk &omvendt -Merk … -Merk &ikke … -Merk &valgt type -Merk i&kke valgt type -700 -&Store ikoner -S&må ikoner -&Liste -&Detaljer -730 -Usortert -&Flat visning -&To felt -&Verktøylinjer -Rotmappe -Gå opp et nivå -Mappelogg … -&Oppdater -750 -Arkivverktøylinje -Standardverktøylinje -Store knapper -Knappetekst -800 -&Bokmerk denne mappen som -Bokmerke -900 -&Innstillinger … -&Yteprøve … -960 -&Innhold -&Om 7-Zip -1003 -Plassering -Navn -Filetternavn -Mappe -Størrelse -Komprimert størrelse -Attributter -Opprettet -Åpnet -Endret -Kompakt -Kommentert -Kryptert -Oppdeling før -Oppdeling etter -Ordbok -CRC -Type -Anti -Metode -Vert-OS -Filsystem -Bruker -Gruppe -Blokk -Kommentar -Posisjon -Stiprefiks - - - - - - - - - - - - - - - - - - - - - - - - -Feil -Total plass -Ledig plass -Sektorgruppestørrelse -Etikett -Lokalt navn -Forsyner -2100 -Innstillinger -Språk -Språk: -Redigering -&Redigeringsprogram: - -2200 -System -Assosier 7-Zip med: -2301 -Integrer 7-Zip i programmenyen -Forgrenet programmeny -Valg i programmenyen: -2320 - - -Åpne arkiv -Pakk ut … -Legg til arkiv … -Test arkiv -Pakk ut internt -Pakk ut til {0} -Legg til {0} -Komprimer og send med e-post … -Komprimer til {0} og send med e-post -2400 -Mapper -&Arbeidsmappe -Systemets &midlertidige mappe -&Nåværende -&Egendefinert: -Kun for flyttbare stasjoner -Angi plassering for midlertidige filer. -2500 -Innstillinger -Vis element for å gå opp et &nivå -Vis egentlige fil&ikoner -Vis system&meny -Merk &hele rader -Vis &rutenett - -&Alternativ merking -Bruk &store minnesider -2900 -Om 7-Zip -7-Zip er gratis programvare, men du kan støtte utviklingen av 7-Zip ved å registrere deg. -3000 - -Fant ingen feil. -{0} element(er) merket -Klarte ikke opprette mappen «{0}» -Oppdateringsfunksjoner støttes ikke for dette arkivet. -Kan ikke åpne filen «{0}» som arkiv -Kan ikke åpne det krypterte arkivet «{0}». Sjekk at du har riktig passord. - - -Filen «{0}» har blitt endret.\nVil du oppdatere den i arkivet? -Klarte ikke oppdatere filen\n«{0}» -Klarte ikke starte redigeringsprogram. - - - - -For mange elementer -3300 -Pakker ut -Komprimerer -Testing -Åpner … -Skanner … -3400 -Pakk ut -&Pakk ut til: -Angi plassering for filer som skal pakkes ut. -3410 -Filstier -Fullstendige filstier -Ingen filstier -3420 -Overskrivelse -Bekreft før overskrivelse -Overskriv uten bekreftelse -Hopp over filer som finnes allerede -Navngi nye filer automatisk -Navngi filer som finnes automatisk -3500 -Bekreft filoverskrivelse -Den behandlede filen finnes i målmappen allerede. -Vil du overskrive filen -med denne? -{0} byte -Navngi a&utomatisk -3700 -Komprimeringsmetoden støttes ikke for «{0}». -Datafeil i «{0}». Filen er ødelagt. -CRC-feil i «{0}». Filen er ødelagt. -Datafeil i den krypterte filen «{0}». Sjekk at du har riktig passord. -CRC feilet i den krypterte filen «{0}». Sjekk at du har riktig passord. -3800 -Angi passord -Angi passord: -Bekreft passord: -&Vis passord -Passordene er ikke like -Du kan bare bruke engelske bokstaver, tall eller spesialtegn (!, #, $, …) i passordet -Passordet er for langt -Passord -3900 -Tidsforbruk: -Gjenværende tid: -Størrelse: -Hastighet: - - -Feilet: - -4000 -Legg til arkiv -Filn&avn: -&Oppdateringsmetode: -&Format: -Komprimerings&nivå: -Komprimerings&metode: -Ord&bokstørrelse: -&Ordstørrelse: -Solid blokk størrelse: -Antall CPU tråder: -&Parametre: -&Innstillinger -Selvutpakkende arkiv («SF&X») - -Kryptering -Krypteringsmetode: -Kr&ypter filnavn -Minnebruk ved komprimering: -Minnebruk ved dekomprimering: -4050 -Ukomprimert -Raskest -Rask -Normal -Maksimum -Ultra -4060 -Legg til og overskriv filer -Oppdater og legg til filer -Oppdater filer -Synkroniser filer -4070 -Bla gjennom -Alle filer -Ikkje-solid -Solid -6000 -Kopier -Flytt -Kopier til: -Flytt til: -Kopierer … -Flytter … -Navngir … -Velg målmappe. -Operasjonen støttes ikke. -Det oppstod en feil da filen eller mappen skulle navngis -Bekreft at fil skal kopieres -Vil du kopiere filene til arkivet -6100 -Bekreft at fil skal slettes -Bekreft at mappe skal slettes -Bekreft at flere filer skal slettes -Vil du slette «{0}»? -Vil du slette mappen «{0}» med alt innhold? -Vil du slette disse {0} elementene? -Sletter … -Det oppstod en feil da filen eller mappen skulle slettes - -6300 -Ny mappe -Ny fil -Mappenavn: -Filnavn: -Ny mappe -Ny fil -Det oppstod en feil da mappen skulle opprettes -Det oppstod en feil da filen skulle opprettes -6400 -kommentar -&Kommentar: -Merk -Merk ikke -Filter: -6600 - -Mappelogg -Diagnosemeldinger -Melding -7100 -Datamaskin -Nettverk - -System -7200 -Legg til -Pakk ut -Prøv -Kopier -Flytt -Slett -Egenskaper -7300 -Del opp arkiv -&Del opp som: -&Del opp til flere delarkiv i størrelsen: -Deler opp … -Bekreft deling -Er du sikker på at du vil dele arkivet i {0} delarkiv? -Delarkivene må være mindre enn originalarkivet -Ugyldig delarkivstørrelse -Valgt delarkivstørrelse: {0} byte.\nEr du sikker på at du vil dele arkivet med denne størrelsen? -7400 -Sett sammen arkiv -&Sett sammen som: -Setter sammen … -Velg bare det første delarkivet - - -7500 -Beregner sjekksum … -Sjekksuminformasjon -CRC-sjekksum for data: -CRC-sjekksum for data og filnavn: -7600 -Yteprøve -Minnebruk: -Komprimering -Dekomprimering -Ytelse -Samlet ytelse -Nåværende -Resultat -CPU bruk -Ytelse / Bruk -Bestått: diff -Nru p7zip-rar-16.02/GUI/Lang/ne.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ne.txt --- p7zip-rar-16.02/GUI/Lang/ne.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ne.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.37 : Shiva Pokharel, Mahesh Subedi -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Nepali -नेपाली -401 -ठीक छ -रद्द गर्नुहोस् - - - -&हो -&होइन -&बन्द गर्नुहोस् -मद्दत - -&जारी राख्नुहोस् -440 -&सबैलाई हो -&कसैलाई होइन -रोक्नुहोस् -पुन: सुरु गर्नुहोस् -&पृष्ठभुमि -&अग्रभुमि -&पज गर्नुहोस् -पज गरिएको -तपाईँ रद्द गर्न यकिन हुनुहुन्छ ? -500 -&फाइल -&सम्पादन गर्नुहोस् -&हेर्नुहोस् -&रुचाइएको -&उपकरण -&मद्दत -540 -&खोल्नुहोस् -भित्रपट्टि खोल्नुहोस् -बाहरिपट्टि खोल्नुहोस् -&हेर्नुहोस् -&सम्पादन गर्नुहोस् -पुन: नामकरण गर्नुहोस् -&यसमा प्रतिलिपि बनाउनुहोस्... -&यसमा सार्नुहोस्... -&मेट्नुहोस् -&फाइल विभाजन गर्नुहोस्... -फाइलहरू संयोजन गर्नुहोस्... -&गुण -टिप्पणी -checksum गणना गर्नुहोस् - -फोल्डर सिर्जना गर्नुहोस् -फाइल सिर्जना गर्नुहोस् -निस्कनुहोस् -600 -सबै चयन गर्नुहोस् -सबै मेट्नुहोस् -&चयन उल्टाउनुहोस् -चयन गर्नुहोस्... -चयन हटाउनुहोस्... -प्रकार अनुसार चयन गर्नुहोस् -प्रकार अनुसार चयन हटाउनुहोस् -700 -ठूलो प्रतिमा -सानो प्रतिमा -&सूची -&वर्णन -730 -क्रमबद्ध नगरिएको -फ्ल्याट दृश्य -&२ प्यानल -&उपकरणपट्टी -प्रमूल फोल्डर खोल्नुहोस् -एक स्तर माथि -फोल्डरको इतिहार... -&ताजा गर्नुहोस् -750 -सङ्ग्रह उपकरणपट्टी -मानक उपकरणपट्टी -ठूलो बटन -बटनको पाठ देखाउनुहोस् -800 -&यस रूपमा रूचाइएकोमा फोल्डर थप्नुहोस् -पुस्तकचिनो -900 -&विकल्प... -&बेञ्चमार्क -960 -&सामग्री... -&7-जिपका बारेमा... -1003 -मार्ग -नाम -विस्तार -फोल्डर -साइज -प्याक गरिएको साइज -विशेषता -सिर्जित -पहुँच -परिमार्जित -ठोस -टिप्पणी -गुप्तिकृत -यस पहिले विभाजन गर्नुहोस् -यस पछि विभाजन गर्नुहोस् -शब्दकोश -CRC -प्रकार -बिरोधि -विधि -होस्ट OS -फाइल प्रणाली -प्रयोगकर्ता -समूह -रोक -टिप्पणी -स्थान -मार्ग प्रत्यय - - - - - - - - - - - - - - - - - - - - - - - - -त्रुटि -जम्मा साइज -स्वतन्त्र रिक्तस्थान -समूह साइज -लेबुल -स्थानिय नाम -प्रदायक -2100 -विकल्प -भाषा -भाषा: -सम्पादक -&सम्पादक: - -2200 -प्रणाली -यससँग 7-जिप सम्बन्धित: -2301 -शेल प्रसङ्ग मेनुमा 7-जिप लाई सम्मिलन गर्नुहोस् -सोपानी प्रसङ्ग मेनु -प्रसङ्ग मेनु वस्तु: -2320 - - -सङ्ग्रह खोल्नुहोस् -फाइलहरू निकाल्नुहोस्... -सङ्ग्रहमा थप्नुहोस्... -सङ्ग्रह जाँच्नुहोस् -यहाँ निकाल्नुहोस् -{0} मा निकाल्नुहोस् -{0} मा थप्नुहोस् -सङ्कुचन गरेर इमेल गर्नुहोस्... -{0} मा सङ्कुचन गर्नुहोस् र इमेल गर्नुहोस् -2400 -फोल्डर -&कार्य फोल्डर -&प्रणाली टेम्प(अस्थायी) फोल्डर -&चालू -&निर्दिष्ट: -हटाउन योग्य ड्राइभहरूका लागि मात्र प्रयोग गर्नुहोस् -अस्थायी सङ्ग्रह फाइलका लागि स्थान तोक्नुहोस् । -2500 -सेटिङ -".." वस्तु देखाउनुहोस् -वास्तविक फाइल प्रतिमा देखाउनुहोस् -प्रणाली मेनु देखाउनुहोस् -&पूरा पङ्क्ति चयन -ग्रिड रेखा देखाउनुहोस् - -&वैकल्पिक चयन मोड -ठूलो स्मृति पृष्ठ प्रयोग गर्नुहोस् -2900 -7-जिपका बारेमा -7-जिप निशुल्क सफ्टवेयर हो। यद्यपी,तपाईँले दर्ता गरेर 7-जिपलाई सहयोग गर्न सक्नुहुन्छ । -3000 - -त्यहाँ त्रुटि छैन -{0} वस्तु(हरू) चयन गरियो -'{0}'फोल्डर सिर्जना गर्न सकिदैन -यो सङ्ग्रहका लागि अद्यावधिक सञ्चालन समर्थन गर्दैन - - - - -'{0}'फाइल परिमार्जन गरिएको छ ।\nतपाईँले यसलाई सङ्ग्रहमा अद्यावधिक गर्न चाहनुहुन्छ ? -फाइल अद्यावधिक गर्न सकिदैन\n'{0}' -सम्पादक सुरु गर्न सकिदैन - - - - -धेरै वस्तु -3300 -निकाल्दैछ -सङ्कुचन -परीक्षण -खोल्दैछ... -स्क्यानिङ... -3400 -निकाल्नुहोस् -यसलाई निकाल्नुहोस्: -निकालिएको फाइलका लागि स्थान निर्दिष्ट गर्नुहोस् -3410 -मार्ग मोड -पूरा मार्गनाम -मार्गनामहरू छैन -3420 -अधिलेखन मोड -अधिलेखन गर्नु अगाडि सोध्नुहोस् -प्रोम्टबिना अधिलेखन गर्नुहोस् -अवस्थित फाइलहरू फड्काउनुहोस् -स्वचालित पुन: नामकरण -स्वचालित पुन: नामकरण अवस्थित फाइलहरू -3500 -फाइल प्रतिस्थापन यकिन गर्नुहोस् -गन्तव्य फोल्डरले पहिले नै प्रक्रिया गरिएको फाइल समावेश गर्दछ -अवस्थित फाइलमा प्रतिस्थापन गर्न चाहनुहुन्छ -योसँग? -{0} बाइट -स्वचालित पुन: नामकरण -3700 -'{0}'का लागि असमर्थित सङ्कुचन विधि -'{0}'लगत त्रुटि । फाइल बिग्रेको छ -'{0}' मा CRC असफल । फाइल बिग्रेको छ - - -3800 -पासवर्ड प्रविष्ट गर्नुहोस् -पासवर्ड प्रविष्ट गर्नुहोस्: - -&पासवर्ड देखाउनुहोस् - - - -पासवर्ड -3900 -व्यतीत समय: -पुन: नामकरण समय: -साइज: -गति: - - -त्रुटि: - -4000 -सङ्ग्रहमा थप्नुहोस् -&सङ्ग्रह: -&अद्यावधिक मोड: -सङ्ग्रह ढाँचा: -सङ्कुचन स्तर: -सङ्कुचन विधि: -&शब्दकोश साइज: -&शब्द साइज: - - -&परिमिति: -विकल्प -SF&X सङ्ग्रह सिर्जना गर्नुहोस् - - - -फाइलनाम गुप्तिकरण गर्नुहोस् -सङ्कुचनका लागि स्मृति प्रयोग: -असङ्कुचनका लागि स्मृति प्रयोग: -4050 -भण्डार गर्नुहोस् -सब भन्दा छिटो -छिटो -साधारण -अधिकतम -अत्यन्त -4060 -फाइल थपेर प्रतिस्थापन गर्नुहोस् -फाइलहरू अद्यावधिक गरेर थप्नुहोस् -अवस्थित फाइल ताजा गर्नुहोस् -फाइल समक्रमण गर्नुहोस् -4070 -ब्राउज गर्नुहोस् -सबै फाइल - - -6000 -प्रतिलिपि गर्नुहोस् -सार्नुहोस् -यसमा प्रतिलिपि गर्नुहोस्: -यसमा सार्नुहोस्: -प्रतिलिपि गर्दैछ... -सार्दैछ... -पुन: नामकरण... - -सञ्चालन समर्थन गर्दैन -फाइल वा फोल्डर पुन: नामकरण गर्दा त्रुटि -फाइल प्रतिलिपि गर्न यकिन गर्नुहोस् -तपाईँ फाइलहरू सङ्ग्रहमा प्रतिलिपि गर्न निश्चित हुनुहुन्छ -6100 -फाइल मेट्न यकिन गर्नुहोस् -फोल्ड मेट्न यकिन गर्नुहोस् -बहुविध फाइल मेट्न यकिन गर्नुहोस् -तपाईँ '{0}'मेट्न निश्चित हुनुहुन्छ ? -तपाईँ '{0}' फोल्डर यसको सबै सामग्री मेट्न निश्चित हुनुहुन्छ ? -तपाईँ {0} वस्तुहरू मेट्न निश्चित हुनुहुन्छ ? -मेट्दैछ... -फाइल वा फोल्डर मेट्दा त्रुटि - -6300 -फोल्डर सिर्जना गर्नुहोस् -फाइल सिर्जना गर्नुहोस् -फोल्डर नाम: -फाइल नाम: -नयाँ फोल्डर -नयाँ फाइल -फोल्डर सिर्जना गर्दा त्रुटि -फाइल सिर्जना गर्दा त्रुटि -6400 -टिप्पणी -&टिप्पणी: -चयन गर्नुहोस् -चयन हटाउनुहोस् -मास्क: -6600 - -फोल्डर इतिहार -निदानात्मक सन्देश -सन्देश -7100 -कम्प्युटर -सञ्जाल - -प्रणाली -7200 -थप्नुहोस् -निकाल्नुहोस् -परीक्षण गर्नुहोस् -प्रतिलिपि गर्नुहोस् -सार्नुहोस् -मेट्नुहोस् -सूचना -7300 -फाइल विभाजन गर्नुहोस् -&यसमा विभाजन गर्नुहोस्: -भोल्युम, बाइटमा विभाजन गर्नुहोस्: -विभाजन गर्दैछ... - - - - - -7400 -फाइल संयोजन गर्नुहोस् -&यसमा संयोजन गर्नुहोस्: -संयोजन गर्दैछ... - - - -7500 -Checksum गणना गर्दैछ... -Checksum सूचना -लगतका लागि CRC checksum: -लगत र नामहरूका लागि CRC checksum: -7600 -बेञ्चमार्क -स्मृति उपयोग: -सङ्कुचन -असङ्कुचन -दर -जम्मा दर -हालको -नतिजा - - -पास: diff -Nru p7zip-rar-16.02/GUI/Lang/nl.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/nl.txt --- p7zip-rar-16.02/GUI/Lang/nl.txt 2016-02-03 05:05:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/nl.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Bert van Velsen -; 4.26 : Jeroen van der Weijde. -; : Harm Hilvers -; 9.07 : Jeroen Tulp -; 15.00 : Jeroen Tulp -; -; -; -; -; -; -0 -7-Zip -Dutch -Nederlands -401 -OK -Annuleren - - - -&Ja -&Nee -A&fsluiten -Help - -&Hervatten -440 -Ja op &alles -Nee op a&lles -Stop -Herstarten -&Achtergrond -&Voorgrond -&Pauzeren -Gepauzeerd -Weet u zeker dat u wilt annuleren? -500 -&Bestand -Be&werken -Bee&ld -&Favorieten -E&xtra -&Help -540 -&Openen -Open B&innen -Open B&uiten -Bee&ld -&Bewerken -&Hernoemen -&Kopiëren naar... -&Verplaatsen naar... -Verwij&deren -Bestand &opsplitsen... -Bestanden &samenvoegen... -&Eigenschappen -O&pmerking -&Checksum berekenen -Ver&gelijken -Nieuwe &map -&Nieuw bestand -&Sluiten -Koppe&ling -&Alternate Streams -600 -&Alles selecteren -A&lles de-selecteren -Selectie &omkeren -&Selecteer... -&De-selecteer... -Selecteer op &type -De-selecteer op t&ype -700 -&Grote pictogrammen -&Kleine pictogrammen -&Lijst -&Details -730 -&Ongesorteerd -&Platte weergave -&2 Panelen -&Werkbalken -&Root map openen -Één &niveau omhoog -&Mappen Geschiedenis... -&Verversen -&Automatisch verversen -750 -&Archief werkbalk -&Standaard werkbalk -Grote kn&oppen -Knop&tekst weergeven -800 -&Map toevoegen aan Favorieten -Favoriet maken -900 -&Opties... -&Benchmark -960 -&Inhoud... -&Over 7-Zip... -1003 -Pad -Naam -Extensie -Map -Grootte -Ingepakte grootte -Kenmerken -Aangemaakt -Laatst geopend -Gewijzigd -Compact -Commentaar -Gecodeerd -Gesplitst voor -Gesplitst na -Woordenboek - -Type -Anti -Methode -Gastheer OS -Bestandssysteem -Gebruiker -Groep -Blok -Commentaar -Positie -Pad Prefix -Mappen -Bestanden -Versie -Volume -Multivolume -Offset -Koppelingen -Blokken -Volumes - -64-bit -Big-endian -CPU -Fysieke grootte -Kop grootte -Checksum -Karakteristieken -Virtueel Adres -ID -Korte Naam -Aanmaak Applicatie -Sector Grootte -Modus -Symbolische Kpoppeling -Fout -Capaciteit -Beschikbaar -Clustergrootte -Label -Lokale naam -Provider -NT Beveiliging -Alternate Stream -Aux -Verwijderd -Is Structuur - - -Error Type -Errors -Errors -Waarschuwingen -Waarschuwing -Streams -Alternate Streams -Alternate Streams Grootte -Virtuele Grootte -Uitgepakte Grootte -Totale Fysieke Grootte -Volume Index -SubType -Kort Commentaar -Tekstcodering - - - -Tail Grootte -Embedded Stub Grootte -Koppeling -Harde Koppeling -iNode - -Alleen-lezen -2100 -Opties -Taal -Taal: -Editor -&Editor: -&Vergelijken: -2200 -Systeem -Associeer 7-Zip met: -All users -2301 -7-Zip in het contextmenu integreren. -Trapsgewijs contextmenu -Contextmenu items: -Pictogrammen in contexmenu -2320 - - -Open archief -Bestanden uitpakken... -Toevoegen aan archief... -Testen archief -Uitpakken (hier) -Uitpakken naar {0} -Toevoegen aan {0} -Comprimeer en verstuur... -Comprimeer naar {0} en verstuur -2400 -Mappen -&Werkmap -&Tijdelijke systeemmap -&Huidige -&Gespecificeerd: -Alleen voor verwisselbare schijven gebruiken. -Specificeer een locatie voor tijdelijke archiefbestanden. -2500 -Instellingen -Toon ".." &item -Toon &echte bestandspictogrammen -Toon &systeem contextmenu -&Selecteer gehele rij -Toon &rasterlijnen -Enkele klik om een item te openen -&Alternatieve selectiemodus -&Gebruik grote geheugenpagina's -2900 -Over 7-Zip -7-Zip is gratis software. Echter, u kunt de ontwikkeling van 7-Zip ondersteunen door u te registreren. -3000 -Het systeem kan de benodigde hoeveelheid geheugen niet alloceren -Er zijn geen fouten. -{0} item(s) geselecteerd -Kan map '{0}' niet aanmaken. -Bijwerkfuncties niet ondersteund voor dit archief. -Kan bestand '{0}' niet openen als archief. -Kan het gecodeerde archief '{0}' niet openen. Verkeerd wachtwoord? -Niet ondersteund archief type -Bestand {0} bestaat reeds -Bestand '{0}' is gewijzigd.\nWilt u het bijwerken in het archief? -Kan bestand\n'{0}' niet bijwerken. -Kan de editor niet starten. -Het bestand lijkt op een virus (het bevat veel opeenvolgende spaties in de naam). -De actie kan niet worden uitgevoerd vanuit een folder met een dermate lang pad. -U moet 1 bestand selecteren -U moet 1 of meerdere bestanden selecteren -Te veel items -Kan het bestand niet openen als {0} archief -Het bestand is geopend als {0} archief -Het archiefis geopend met een offset -3300 -Uitpakken -Comprimeren -Testen -Openen... -Scannen... -Verwijderen -3320 -Toevoegen -Bijwerken -Analyseren -Repliceren -Opnieuw inpakken -Overslaan -Verwijderen -Kop aanmaken -3400 -&Uitpakken -U&itpakken naar: -Specificeer een locatie voor de uitgepakte bestanden. -3410 -Padmethode -Volledige padnamen -Geen padnamen -Absolute padnamen -Relatieve padnamen -3420 -Overschrijfmethode -Vraag voor overschrijven -Overschrijven zonder bevestiging -Bestaande bestanden overslaan -Automatisch hernoemen -Automatisch hernoemen van bestaande bestanden -3430 -Verwijder duplicaat van de hoofdmap -Herstellen bestandsbeveiliging -3500 -Bevestig vervangen bestand -Doelmap bevat reeds het verwerkte bestand. -Wilt u het bestaande bestand vervangen -door dit bestand? -{0} bytes -A&utomatisch hernoemen -3700 -Niet ondersteunde compressiemethode voor '{0}'. -Gegevensfout in '{0}'. Bestand is beschadigd. -CRC mislukt in '{0}'. Bestand is beschadigd. -Gegevensfout in het gecodeerde bestand '{0}'. Verkeerd wachtwoord? -CRC mislukt in het gecodeerde bestand '{0}'. Verkeerd wachtwoord? -3710 -Verkeerd wachtwoord? -3721 -Niet ondersteunde compresssiemethode -Gegevens fout -CRC mislukt -Data niet beschikbaar -Data eindigd onverwachts -Er is nog wat data na het einde van de payload data -Is geen archief -Kop Error -Verkeerd wachtwoord -3763 -Start van archief is niet beschikbaar -Start van archief is niet bevestigd - - - -Niet ondersteunde functie -3800 -Wachtwoord ingeven -Wachtwoord &ingeven: -Wachtwoord bevestigen: -Wachtwoord &tonen -Wachtwoorden komen niet overeen. -Gebruik alleen alfanumerieke en speciale karakters (!, #, $, ...) voor het wachtwoord -Wachtwoord is te lang. -&Wachtwoord -3900 -Verstreken tijd: -Overgebleven tijd: -Grootte: -Snelheid: -Verwerkt: -Compressie verhouding: -Fouten: -Archieven: -4000 -Toevoegen aan archief -&Archief: -&Bijwerkmethode: -Archief &formaat: -Compressie&niveau: -Compressie&methode: -&Woordenboekgrootte: -W&oordgrootte: -Compacte b&lokgrootte: -Aantal CP&U-threads: -&Parameters: -Opties -SF&X archief maken -Comprimeer &gedeelde bestanden -Codering -Cod&eermethode: -Codee&r bestandsnamen -Geheugengebruik bij het inpakken: -Geheugengebruik bij het uitpakken: -Verwijder bestanden na inpakken -4040 -Symboische koppelingen opslaan -Harde koppelingen opslaan -Alternate data streams opslaan -Bestandsbeveiliging opslaan -4050 -Opslaan -Snelst -Snel -Normaal -Maximum -Ultra -4060 -Bestanden toevoegen en vervangen -Bestanden bijwerken en toevoegen -Bestaande bestanden opfrissen -Bestanden synchroniseren -4070 -Bladeren -Alle bestanden -Niet compact -Compact -6000 -Kopiëren -Verplaatsen -Kopiëren naar: -Verplaatsen naar: -Bezig met kopiëren... -Bezig met verplaatsen... -Bezig met hernoemen... -Selecteer een doelmap. -Functie wordt niet ondersteund. -Fout bij het hernoemen van een bestand of map -Bevestig kopiëren van bestand -Weet u zeker dat u deze bestanden naar het archief wilt kopiëren -6100 -Verwijdering bestand bevestigen -Verwijdering map bevestigen -Verwijdering van meerdere bestanden bevestigen -Weet u zeker dat u '{0}' wilt verwijderen? -Weet u zeker dat u de map '{0}' en alle onderliggende items wilt verwijderen? -Weet u zeker dat u deze {0} items wilt verwijderen? -Bezig met verwijderen... -Fout bij het verwijderen van een bestand of map -Het systeem kan een bestand met een lang pad niet verplaatsen naar de Prullenbak -6300 -Map maken -Bestand maken -Naam van de map: -Bestandsnaam: -Nieuwe map -Nieuw bestand -Fout bij het maken van de map -Fout bij het maken van het bestand. -6400 -Opmerking -&Opmerking: -Selecteren -De-selecteren -Masker: -6600 -Eigenschappen -Mappen Geschiedenis -Diagnostische berichten -Bericht -7100 -Computer -Netwerk -Documenten -Systeem -7200 -Toevoegen -Uitpakken -Testen -Kopiëren -Verplaatsen -Verwijderen -Info -7300 -Opsplitsen bestand -&Opsplitsen naar: -Opsplitsen in &volumes (grootte in bytes): -Bezig met opsplitsen... -Bevestigen opsplitsen -Weet u zeker dat u het bestand wilt opsplitsen in {0} volumes? -De volumegrootte moet kleiner zijn dan de grootte van het oorspronkelijke bestand. -Verkeerde volumegrootte -Gespecificeerde volumegrootte: {0} bytes.\nWeet u zeker dat u het archief zo wilt splitsen? -7400 -Bestanden samenvoegen -&Samenvoegen naar: -Bezig met samenvoegen... -Selecteer alleen het eerste bestand. -Kan het bestand niet herkennen als onderdeel van een gesplitst bestand -Kan niet meer dan 1 deel van een gesplitst bestand -7500 -Bezig met checksum berekenen... -Checksum informatie -CRC checksum voor gegevens: -CRC checksum voor gegevens en namen: -7600 -Benchmark -Geheugengebruik: -Inpakken -Uitpakken -Waarde -Totale waarde -Huidig -Resultaat -CPU-gebruik -Waarde / gebruik -Doorgangen: -7700 -Koppeling -Koppeling -Koppeling van: -Koppeling naar: -7710 -Koppeling Type -Harde Koppeling -Bestand Symbolische Koppeling -Map Symbolische Koppeling -Mapsplitsing diff -Nru p7zip-rar-16.02/GUI/Lang/nn.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/nn.txt --- p7zip-rar-16.02/GUI/Lang/nn.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/nn.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.45 : Robert Grønning -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Norwegian Nynorsk -Norsk Nynorsk -401 -OK -Avbryt - - - -&Ja -&Nei -&Lukke -Hjelp - -&Hald fram -440 -Ja til &alt -N&ei til alt -Stopp -Start på nytt -&Bakgrunn -&Forgrunn -&Pause -Sett på pause -Er du sikker på du vil avbryte? -500 -&Fil -&Redigere -&Vis -F&avorittar -Verk&tøy -&Hjelp -540 -&Opna -Opna &Inni -Opna &Utanfor -&Vis -&Redigere -Endra &namn -&Kopiere til... -&Flytt til... -&Slett -&Del opp fil... -Set saman filer... -&Eigenskapar -Ko&mmentar -Rekna ut kontrollnummer - -Opprett mappe -Opprett fil -&Avslutta -600 -&Merk alle -Fjern alle markeringar -&Omvendt markering -Marker... -Fjern markering... -Merk etter type -Fjern markering etter type -700 -S&tore ikon -S&må ikon -&Lista -&Detaljar -730 -Assortert -Flat vising -&2 felt -&Verktøylinjer -Opna kjeldemappa -Opp eit nivå -Mappelogg... -&Oppdatere -750 -Arkiv verktøylinje -Standard verktøylinjer -Store knappar -Vis knappetekst -800 -&Legg mappe til i favorittar som -Bokmerke -900 -&Val... -&Yting test -960 -&Innhold... -&Om 7-Zip... -1003 -Bane -Namn -Fil etternamn -Mappe -Størrelse -Komprimert Størrelse -Eigenskapar -Oppretta -Opna -Endra -Solid -Kommentert -Kryptert -Delt før -Delt etter -Ordbok -CRC -Type -Anti -Metode -Vert OS -Filsystem -Brukar -Gruppe -Blokkering -Kommentar -Posisjon -Bane prefiks - - - - - - - - - - - - - - - - - - - - - - - - -Feil -Total størrelse -Ledig plass -Klyngje størrelse -Etikett -Lokalt namn -Leverandør -2100 -Val -Språk -Språk: -Redigeringsprogram -&Redigeringsprogram: - -2200 -System -Forbind 7-Zip med: -2301 -Legg inn 7-Zip i programmenyen -Forgreina programmeny -Programmeny val: -2320 - - -Opna arkiv -Pakk ut filer... -Legg til i arkiv... -Test arkiv -Pakk ut her -Pakk ut til {0} -Legg til i {0} -Komprimere og send som epost... -Komprimere til {0} og send som epost -2400 -Mapper -&Arbeidsmappe -&Midlertidig mappe -&Noverande -&Eigendefinert: -Berre for flyttbare stasjonar -Oppgje plassering for midlertidige arkiv filer. -2500 -Innstillingar -Vis ".." element -Vis dei ordentlege fil ikona -Vis system meny -&Merk heile rader -Vis &rutenett - -&Alternativ markerings modus -Bruk &store minnesider -2900 -Om 7-Zip -7-Zip er fri programvare. Du kan støtta utviklinga av 7-Zip ved å registrere deg. -3000 - -Ingen feil -{0} objekt(ar) valt -Kan ikkje oppretta mappe '{0}' -Dette arkivet manglar støtte for å kunne oppdaterast. -Kan ikkje opna fila '{0}' som eit arkiv -Kan ikkje opna det krypterte arkivet '{0}'. Feil passord? - - -Fila '{0}' blei endra.\nVil du oppdatere den i arkivet? -Kan ikkje oppdatere fil\n'{0}' -Kan ikkje starta redigeringsprogram. - - - - -For mange gonger -3300 -Pakkar ut -Komprimerer -Testing -Opnar... -Undersøkjer... -3400 -Pakk ut -Pakk ut &til: -Vel ei mappe for ut-pakka filer. -3410 -Bane modus -Fulstendig banenamn -Ingen banenamn -3420 -Overskriving modus -Bekrefta før overskriving -Skriv over utan bekrefting -Hopp over eksisterande filer -Endra filnamn automatisk -Endra filnamn automatisk for eksisterande filer -3500 -Bekrefta overskriving av fil -Målmappa inneheld allereie ei behandla fil. -Vil du overskriva den eksisterande fila -med denne? -{0} byte -&Skift filnamn automatisk -3700 -Kompresjonsmetoden er ikkje støtta for '{0}'. -Data feil i '{0}'. Fila er øydelagt. -CRC feila på '{0}'. Fila er øydelagt. -Data feil i den krypterte fila '{0}'. Feil passord? -CRC feila i den krypterte fila '{0}'. Feil passord? -3800 -Skriv inn passord -Skriv inn passord: -Skriv inn passordet på nytt: -&Vis passord -Passorda er ikkje like -Bruk berre Engelske bokstavar, tal og spesielle teikn (!, #, $, ...) i passordet -Passordet er for langt -Passord -3900 -Tid brukt: -Tid gjenstår: -Størrelse: -Fart: - - -Feil: - -4000 -Legg til i arkiv -&Arkiv: -&Oppdaterings modus: -Arkiv &format: -Kompresjons &nivå: -Kompresjons &metode: -O&rdbok størrelse: -Or&d størrelse: -Solid blokk størrelse: -Anntal CPU tråder: -&Parameter: -Val -Opprett SF&X arkiv - -Krypter -Krypter metode: -&Krypter filnamn -Minnebruk ved kompresjon: -Minnebruk ved ut-pakking: -4050 -Lagre -Raskast -Rask -Normal -Maksimum -Ekstrem -4060 -Legg til og skriv over filer -Oppdatere og legg til filer -Frisk opp eksisterande filer -Synkroniser filer -4070 -Bla igjennom -Alle filer -Ikkje-solid -Solid -6000 -Kopiere -Flytt -Kopiere til: -Flytt til: -Kopierer... -Flyttar... -Endrar namn... -Vel målmappe. -Støttar ikkje handlinga. -Feil ved endring av namn på fil eller mappe -Godkjenne filkopiering -Er du sikker på at du vil kopiere filer til arkiv -6100 -Godkjenne sletting av fil -Godkjenne sletting av mappe -Godkjenne sletting av fleire filer -Er du sikker på at du vil sletta '{0}'? -Er du sikker på at du vil sletta mappa '{0}' og alt innhold i den? -Er du sikker på at du vil sletta desse {0} elementa? -Slettar... -Feil ved sletting av fil eller mappe - -6300 -Opprett mappe -Opprett fil -Mappe namn: -Filnamn: -Ny mappe -Ny fil -Feil ved oppretting av mappe -Feil ved oppretting av fil -6400 -Kommentar -&Kommentar: -Marker -Fjern markering -Maske: -6600 - -Mappe logg -Diagnose meldingar -Melding -7100 -Datamaskin -Nettverk - -System -7200 -Legg til -Pakk ut -Test -Kopiere -Flytt -Slett -Informasjon -7300 -Del opp fil -&Del opp til: -Splitt opp i deler, byte: -Delar opp... -Godkjenne oppdeling -Er du sikker på at du vil dele opp fila i {0} delar? -Størrelsen på delane må vera mindre enn størrelsen på originalfila -Feil del-størrelse -Oppgitt del-størrelse: {0} byte.\nEr du sikker på du vil dele arkivet opp i slike deler? -7400 -Slå saman filer -&Slå saman til: -Slår saman... -Berre vel den første fila - - -7500 -Reknar ut kontrollnummer... -Informasjon om kontrollnummer -CRC kontrollnummer for data: -CRC kontrollnummer for data og namn: -7600 -Yting test -Minnebruk: -Kompresjon -Ut-pakking -Yting -Total yting -Noverande -Resultat -CPU bruk -Yting / Bruk -Gonger: diff -Nru p7zip-rar-16.02/GUI/Lang/pa-in.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/pa-in.txt --- p7zip-rar-16.02/GUI/Lang/pa-in.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/pa-in.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.53 : Gurmeet Singh Kochar -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Punjabi, Indian -ਪੰਜਾਬੀ -401 -ਠੀਕ ਹੈ -ਰੱਦ ਕਰੋ - - - -ਹਾਂ (&Y) -ਨਹੀਂ (&N) -ਬੰਦ ਕਰੋ (&C) -ਮੱਦਦ - -ਜਾਰੀ ਕਰੋ (&C) -440 -ਸਾਰਿਆਂ ਲਈ ਹਾਂ (&A) -ਸਾਰਿਆਂ ਲਈ ਨਹੀਂ (&l) -ਰੁਕੋ -ਮੁੜ ਚਾਲੂ ਕਰੋ -ਬੈਕਗਰਾਉਂਡ (&B) -ਫੋਰਗਰਾਉਂਡ (&F) -ਪੋਜ਼ (&P) -ਪੋਜ਼ ਹੋਇਆ -ਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਹੀ ਰੱਦ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? -500 -ਫਾਇਲ (&F) -ਸੋਧ (&E) -ਵੇਖੋ (&V) -ਪਸੰਦੀਦਾ (&a) -ਸੰਧ (&T) -ਮੱਦਦ (&H) -540 -ਖੋਲੋ (&O) -ਅੰਦਰ ਖੋਲੋ (&I) -ਬਾਹਰ ਖੋਲੋ (&u) -ਵਿਖਾਓ (&V) -ਸੋਧ ਕਰੋ (&E) -ਨਾਂ ਬਦਲੋ (&m) -ਨਵੇਂ ਟਿਕਾਣੇ ਤੇ ਨਕਲ ਉਤਾਰੋ (&C)... -ਨਵੇਂ ਟਿਕਾਣੇ ਤੇ ਭੇਜੋ (&M)... -ਹਟਾਓ (&D) -ਫਾਇਲ ਹਿੱਸਿਆਂ ਵਿੱਚ ਵੰਡੋ (&S)... -ਫਾਇਲ ਦੇ ਹਿੱਸੇ ਜੋੜੋ (&b)... -ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ (&r) -ਟਿੱਪਣੀ (&n) -ਚੈਕਸੱਮ ਗਣਨਾ ਕਰੋ - -ਫੋਲਡਰ ਬਣਾਓ -ਫਾਇਲ ਬਣਾਓ -ਬਾਹਰ ਨਿਕਲੋ (&x) -600 -ਸਭ ਚੁਣੋ (&A) -ਸਭ ਚੋਣ ਰੱਦ ਕਰੋ -ਉਲਟ ਚੋਣ ਕਰੋ (&I) -ਚੁਣੋ... -ਚੋਣ ਰੱਦ ਕਰੋ... -ਕਿਸਮ ਨਾਲ ਚੁਣੋ ਕਰੋ -ਕਿਸਮ ਨਾਲ ਚੋਣ ਰੱਦ ਕਰੋ -700 -ਵੱਡੇ ਆਈਕਾਨ (&g) -ਛੋਟੇ ਆਈਕਾਨ (&m) -ਸੂਚੀ (&L) -ਵੇਰਵੇ ਸਹਿਤ (&D) -730 -ਨਾ ਕ੍ਰਮ-ਬੱਧ -ਫਲੈਟ ਦ੍ਰਿਸ਼ -&2 ਪੈਨਲ -ਟੂਲਬਾਰ (&T) -ਰੂਟ ਫੋਲਡਰ ਖੋਲੋ -ਇੱਕ ਪੱਧਰ ਉੱਤੇ -ਫੋਲਡਰ ਅਤੀਤ... -ਤਾਜ਼ਾ ਕਰੋ(&R) -750 -ਆਕਾਈਵ ਟੂਲਬਾਰ -ਸਧਾਰਨ ਟੂਲਬਾਰ -ਵੱਡੇ ਬਟਨ -ਬਟਨ ਟੈਕਸਟ ਵਿਖਾਓ -800 -ਫੋਲਡਰ ਪਸੰਦੀਦਾ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ (&A) -ਬੁੱਕਮਾਰਕ -900 -ਚੋਣਾਂ (&O)... -ਬੈਂਚਮਾਰਕ (&B) -960 -ਵਿਸ਼ਾ ਸੂਚੀ (&C)... -7-ਜ਼ਿੱਪ ਬਾਰੇ (&A)... -1003 -ਮਾਰਗ -ਨਾਂ -ਐਕਸਟੈਂਸ਼ਨ -ਫੋਲਡਰ -ਸਾਈਜ਼ -ਪੈਕਡ ਸਾਈਜ਼ -ਲੱਛਨ -ਬਣਤਰ ਸਮਾਂ -ਪਹੁੰਚ ਸਮਾਂ -ਸੋਧ ਸਮਾਂ -ਠੋਸ -ਟਿੱਪਣੀ -ਐਨਕ੍ਰਿਪਟਡ -Split Before -Split After -ਡਿਕਸ਼ਨਰੀ -ਸੀ-ਆਰ-ਸੀ (CRC) -ਕਿਸਮ -ਐਂਟੀ (Anti) -ਢੰਗ -ਮੇਜ਼ਬਾਨ ਔ-ਐੱਸ -ਫਾਇਲ ਸਿਸਟਮ -ਯੂਜ਼ਰ -ਸਮੂਹ -ਬਲੋਕ -ਟਿੱਪਣੀ -ਸਥਿੱਤੀ -ਮਾਰਗ ਅਗੇਤਰ -ਫੋਲਡਰ -ਫਾਇਲਾਂ -ਵਰਜਨ -ਵੋਲੁੱਮ -ਮਲਟੀਵੋਲੁੱਮ -ਔਫ਼ਸੈਟ -ਲਿੰਕ -ਬਲੋਕ -ਵੋਲੁੱਮ - - - - - - - - - - - - - - - -ਸਮੱਸਿਆ -ਕੁੱਲ ਸਾਈਜ਼ -ਖ਼ਾਲੀ ਥਾਂ -ਕਲੱਸਟਰ ਸਾਈਜ਼ -ਲੇਬਲ -ਸਥਾਨਕ ਨਾਂ -ਉਪਲੱਬਧ ਕਰਤਾ -2100 -ਚੋਣਾਂ -ਭਾਸ਼ਾ -ਭਾਸ਼ਾ: -ਐਡੀਟਰ -ਟੈਕਸਟ ਐਡੀਟਰ (&E): - -2200 -ਸਿਸਟਮ -7-ਜ਼ਿੱਪ ਨਾਲ ਹੇਠਾਂ ਦਿੱਤੇ ਫਾਇਲ ਐਕਸਟੈਂਸ਼ਨ ਜੋੜੋ: -2301 -ਸ਼ੈੱਲ ਕੰਨਟੈਕਸਟ ਮੇਨੂੰ ਨਾਲ 7-ਜ਼ਿੱਪ ਨੂੰ ਏਕੀਕਿਰਤ ਕਰੋ -ਕੈਸਕੇਡਡ ਕੰਨਟੈਕਸਟ ਮੇਨੂੰ -ਕੰਨਟੈਕਸਟ ਮੇਨੂੰ ਆਈਟਮਾਂ: -2320 -<ਫੋਲਡਰ> -<ਆਕਾਈਵ> -ਆਕਾਈਵ ਖੋਲੋ -ਫਾਇਲਾਂ ਕੱਡੋ... -ਆਕਾਈਵ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ... -ਆਕਾਈਵ ਪਰਖੋ -ਫਾਇਲਾਂ ਇੱਥੇ ਕੱਡੋ -{0} ਵਿੱਚ ਕੱਡੋ -{0} ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ -ਨਪੀੜੋ ਅਤੇ ਈਮੇਲ ਕਰੋ... -{0} ਵਿੱਚ ਨਪੀੜੋ ਅਤੇ ਈਮੇਲ ਕਰੋ -2400 -ਫੋਲਡਰ -ਵਰਕਿੰਗ ਫੋਲਡਰ (&W) -ਸਿਸਟਮ ਆਰਜ਼ੀ (temp) ਫੋਲਡਰ (&S) -ਇਸ ਸਮੇਂ ਚੁਣਿਆ (&C) -ਹੇਠਾਂ ਦਿੱਤਾ ਗਿਆ (&S): -ਸਿਰਫ਼ ਹਟਾਈ ਜਾ ਸੱਕਨ ਵਾਲੀਆਂ ਡਰਾਈਵ ਲਈ ਵਰਤੋਂ ਕਰੋ -ਆਰਜ਼ੀ ਆਕਾਈਵ ਫਾਇਲਾਂ ਲਈ ਟਿਕਾਣਾ ਦੱਸੋ। -2500 -ਸੈਟਿੰਗ -".." ਆਈਟਮ ਵਿਖਾਓ -ਅਸਲੀ ਫਾਇਲ ਆਈਕਾਨ ਵਿਖਾਓ -ਸਿਸਟਮ ਮੇਨੂੰ ਵਿਖਾਓ -ਪੂਰੀ ਕਤਾਰ ਚੁਣੋ (&F) -ਗ੍ਰਿਡ ਲਾਈਨਾਂ ਵਿਖਾਓ (&g) - -ਵਿਕਲਪਕ ਚੁਣਾਓ ਢੰਗ (&A) -ਵੱਡੇ ਮੈਮੋਰੀ ਪੇਜ ਵਰਤੋ (&l) -2900 -7-ਜ਼ਿੱਪ ਬਾਰੇ -7-ਜ਼ਿੱਪ ਇੱਕ ਮੁਫ਼ਤ ਸਾਫ਼ਟਵੇਅਰ ਹੈ। ਪਰ ਫੇਰ ਵੀ, ਤੁਸੀਂ ਰਜਿਸਟਰ ਕਰਕੇ 7-ਜ਼ਿੱਪ ਦੇ ਵਿਕਾਸ ਵਿੱਚ ਸਮਰਥਨ ਪਾ ਸੱਕਦੇ ਹੋ।\n\nਪੰਜਾਬੀ ਵਿੱਚ ਅਨੁਵਾਦ ਕੀਤਾ (Translation Done By):\nGurmeet Singh Kochar (ਗੁਰਮੀਤ ਸਿੰਘ ਕੋਚਰ)\n -3000 - -ਕੋਈ ਸਮੱਸਿਆਵਾਂ ਨਹੀਂ ਹਨ -ਚੁਣੇ ਪਦਾਰਥ: {0} -'{0}' ਫੋਲਡਰ ਨਹੀਂ ਬਣਾਇਆ ਜਾ ਸੱਕਿਆ -ਅੱਪਡੇਟ ਔਪਰੇਸ਼ਨ ਇਸ ਆਕਾਈਵ ਲਈ ਸਹਿਯੋਗੀ ਨਹੀਂ ਹਨ। -'{0}' ਫਾਇਲ ਨੂੰ ਆਕਾਈਵ ਤਰ੍ਹਾਂ ਨਹੀਂ ਖੋਲਿਆ ਜਾ ਸੱਕਿਆ -'{0}' ਐਨਕ੍ਰਿਪਟਡ ਆਕਾਈਵ ਨਹੀਂ ਖੋਲਿਆ ਜਾ ਸੱਕਿਆ। ਗਲ਼ਤ ਪਾਸਵਰਡ? - - -'{0}' ਫਾਇਲ ਸੋਧ ਦਿੱਤੀ ਗਈ ਹੈ।\nਕੀ ਤੁਸੀਂ ਉਸਨੂੰ ਆਕਾਈਵ ਵਿੱਚ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? -ਫਾਇਲ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸੱਕੀ\n'{0}' -ਐਡੀਟਰ ਚਾਲੂ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸੱਕਿਆ। - - - - -ਬਹੁੱਤ ਸਾਰੀਆਂ ਆਈਟਮਾਂ -3300 -ਕੱਡੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ -ਨਪੀੜਨ ਕਾਰਜ ਚੱਲ ਰਿਹਾ ਹੈ -ਪਰਖ ਚੱਲ ਰਹੀ ਹੈ -ਖੋਲੀ ਜਾ ਰਹੀ ਹੈ... -ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... -3400 -ਕੱਡੋ -ਇੱਥੇ ਕੱਡੋ (&x): -ਕੱਡੀਆਂ ਜਾਉਣ ਵਾਲੀਆਂ ਫਾਇਲਾਂ ਲਈ ਟਿਕਾਣਾ ਦੱਸੋ। -3410 -ਮਾਰਗ ਢੰਗ -ਪੂਰੇ ਮਾਰਗ ਨਾਂ -ਕੋਈ ਮਾਰਗ ਨਾਂ ਨਹੀਂ -3420 -ਉਪਰੀਲੇਖਨ ਢੰਗ -ਉਪਰੀਲੇਖਨ ਤੋਂ ਪਹਿਲਾਂ ਤਸਦੀਕ -ਬਿਨ੍ਹਾਂ ਤਸਦੀਕ ਉਪਰੀਲੇਖਨ -ਮੌਜੂਦਾ ਫਾਇਲਾਂ ਨਾਂ ਕੱਡੋ -ਆਪੇ ਨਾਂ ਬਦਲ ਦਿਓ -ਮੌਜੂਦਾ ਫਾਇਲਾਂ ਦਾ ਆਪੇ ਨਾਂ ਬਦਲ ਦਿਓ -3500 -ਫਾਇਲ ਬਦਲਨ ਦੀ ਤਸਦੀਕ -ਕਾਰਵਾਈ ਕੀਤੀ ਜਾਉਂਦੀ ਫਾਇਲ ਨਿਯਤ ਫੋਲਡਰ ਵਿੱਚ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। -ਕੀ ਤੁਸੀਂ ਮੌਜੂਦਾ ਫਾਇਲ ਨੂੰ -ਇਸ ਫਾਇਲ ਨਾਲ ਬਦਲਨਾ ਚਾਹੋਗੇ? -{0} ਬਾਈਟ -ਆਪੇ ਨਾਂ ਬਦਲੀ ਕਰੋ (&u) -3700 -'{0}' ਲਈ ਨਪੀੜਨ ਢੰਗ ਸਹਿਯੋਗੀ ਨਹੀਂ। -'{0}' ਵਿੱਚ ਡਾਟਾ ਸਮੱਸਿਆ। ਫਾਇਲ ਟੁੱਟੀ ਹੋਈ ਹੈ। -'{0}' ਵਿੱਚ ਸੀ-ਆਰ-ਸੀ ਅਸਫ਼ਲ ਰਿਹਾ। ਫਾਇਲ ਟੁੱਟੀ ਹੋਈ ਹੈ। -'{0}' ਐਨਕ੍ਰਿਪਟਡ ਫਾਇਲ ਵਿੱਚ ਡਾਟਾ ਸਮੱਸਿਆ। ਗਲ਼ਤ ਪਾਸਵਰਡ? -'{0}' ਐਨਕ੍ਰਿਪਟਡ ਫਾਇਲ ਵਿੱਚ ਸੀ-ਆਰ-ਸੀ ਅਸਫ਼ਲ ਰਿਹਾ। ਗਲ਼ਤ ਪਾਸਵਰਡ? -3800 -ਪਾਸਵਰਡ ਭਰੋ -ਪਾਸਵਰਡ ਭਰੋ: -ਪਾਸਵਰਡ ਮੁੜ ਭਰੋ: -ਪਾਸਵਰਡ ਵਿਖਾਓ (&S) -ਪਾਸਵਰਡ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ -ਪਾਸਵਰਡ ਲਈ ਸਿਰਫ਼ ਅੰਗ੍ਰੇਜ਼ੀ ਅੱਖਰ, ਅੰਕ, ਅਤੇ ਖ਼ਾਸ ਅੱਖਰਾਂ (!, #, $, ...) ਦੀ ਹੀ ਵਰਤੋਂ ਕਰੋ -ਪਾਸਵਰਡ ਬਹੁੱਤ ਲੰਬਾ ਹੈ -ਪਾਸਵਰਡ -3900 -ਬੀਤਿਆ ਸਮਾਂ: -ਰਹਿੰਦਾ ਸਮਾਂ: -ਕੁੱਲ ਸਾਈਜ਼: -ਗਤੀ: -ਨਿਬੇੜੀਆਂ ਬਾਈਟ: -ਨਪੀੜਨ ਅਨੁਪਾਤ: -ਸਮੱਸਿਆਵਾਂ: -ਆਕਾਈਵਾਂ: -4000 -ਆਕਾਈਵ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ -ਆਕਾਈਵ (&A): -ਅੱਪਡੇਟ ਢੰਗ (&U): -ਆਕਾਈਵ ਫੌਰਮੈਟ (&f): -ਨਪੀੜਨ ਪੱਧਰ (&l): -ਨਪੀੜਨ ਢੰਗ (&m): -ਡਿਕਸ਼ਨਰੀ ਸਾਈਜ਼ (&D): -ਵਰਡ ਸਾਈਜ਼(&W): -ਠੋਸ ਬਲੋਕ ਸਾਈਜ਼: -ਸੀ-ਪੀ-ਯੂ ਥਰੈੱਡ ਗਿਣਤੀ: -ਪੈਰਾਮੀਟਰ (&P): -ਚੋਣਾਂ -SF&X ਆਕਾਈਵ ਬਣਾਓ -ਵਰਤੀਆਂ ਜਾਉਂਦੀਆਂ ਫਾਇਲਾਂ ਨੂੰ ਵੀ ਨਪੀੜੋ -ਐਨਕ੍ਰਿਪਸ਼ਨ -ਐਨਕ੍ਰਿਪਸ਼ਨ ਢੰਗ: -ਫਾਇਲਾਂ ਦੇ ਨਾਂ ਐਨਕ੍ਰਿਪਟ ਕਰੋ (&n) -ਨਪੀੜਨ ਲਈ ਮੈਮੋਰੀ ਦੀ ਵਰਤੋਂ: -ਆਕਾਈਵ ਖੋਲਨ ਲਈ ਮੈਮੋਰੀ ਦੀ ਵਰਤੋਂ: -4050 -ਸਿਰਫ਼ ਇਕੱਤਰਤਾ -ਬਹੁੱਤ ਤੇਜ਼ -ਤੇਜ਼ -ਆਮ -ਵੱਧੋਂ ਵੱਧ -ਸਭ ਤੋਂ ਵੱਧ -4060 -ਫਾਇਲਾਂ ਸ਼ਾਮਲ ਕਰੋ ਅਤੇ ਬਦਲੋ -ਫਾਇਲਾਂ ਸ਼ਾਮਲ ਅਤੇ ਅੱਪਡੇਟ ਕਰੋ -ਮੌਜੂਦਾ ਫਾਇਲਾਂ ਤਾਜ਼ਾ ਕਰੋ -ਫਾਇਲਾਂ ਸਮਕਾਲਵਰਤੀ ਕਰੋ -4070 -ਬਰਾਊਜ਼ -ਸਾਰੀਆਂ ਫਾਇਲਾਂ -ਨਾ-ਠੋਸ -ਠੋਸ -6000 -ਨਵੇਂ ਟਿਕਾਣੇ ਤੇ ਨਕਲ ਉਤਾਰੋ -ਨਵੇਂ ਟਿਕਾਣੇ ਤੇ ਭੇਜੋ -ਹੇਠਾਂ ਦਿੱਤੇ ਟਿਕਾਣੇ ਤੇ ਨਕਲ ਉਤਾਰੋ: -ਹੇਠਾਂ ਦਿੱਤੇ ਟਿਕਾਣੇ ਤੇ ਭੇਜੋ: -ਨਕਲ ਉਤਾਰੀ ਜਾ ਰਹੀ ਹੈ... -ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ... -ਨਾਂ ਬਦਲਿਆ ਜਾ ਰਿਹਾ ਹੈ... -ਨਿਯਤ ਫੋਲਡਰ ਚੁਣੋ -ਕਾਰਵਾਈ ਸਹਿਯੋਗੀ ਨਹੀਂ ਹੈ। -ਫਾਇਲ ਜਾਂ ਫੋਲਡਰ ਦਾ ਨਾਂ ਬਦਲਣ ਵਿੱਚ ਸਮੱਸਿਆ -ਫਾਇਲ ਦੀ ਨਕਲ ਉਤਾਰਣ ਦੀ ਤਸਦੀਕ -ਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਫਾਇਲਾਂ ਦੀ ਆਕਾਈਵ ਵਿੱਚ ਨਕਲ ਉਤਾਰਨਾ ਚਾਹੁੰਦੇ ਹੋ -6100 -ਫਾਇਲ ਹਟਾਉਣ ਦੀ ਤਸਦੀਕ -ਫੋਲਡਰ ਹਟਾਉਣ ਦੀ ਤਸਦੀਕ -ਬਹੁ-ਫਾਈਲਾਂ ਹਟਾਉਣ ਦੀ ਤਸਦੀਕ -'{0}' ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? -ਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਫੋਲਡਰ '{0}' ਅਤੇ ਉਸਦੇ ਵਿੱਚਲੀਆਂ ਆਈਟਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? -ਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਇਨ੍ਹਾਂ {0} ਆਈਟਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? -ਹਟਾਉਣ ਦੀ ਕਾਰਵਾਈ ਚੱਲ ਰਹੀ ਹੈ... -ਫਾਇਲ ਜਾਂ ਫੋਲਡਰ ਹਟਾਉਣ ਵਿੱਚ ਸਮੱਸਿਆ - -6300 -ਫੋਲਡਰ ਬਣਾਓ -ਫਾਇਲ ਬਣਾਓ -ਫੋਲਡਰ ਨਾਂ: -ਫਾਇਲ ਨਾਂ: -ਨਵਾਂ ਫੋਲਡਰ -ਨਵੀਂ ਫਾਇਲ -ਫੋਲਡਰ ਬਨਾਉਣ ਵਿੱਚ ਸਮੱਸਿਆ -ਫਾਇਲ ਬਨਾਉਣ ਵਿੱਚ ਸਮੱਸਿਆ -6400 -ਟਿੱਪਣੀ -ਟਿੱਪਣੀ (&C): -ਚੁਣੋ -ਚੋਣ ਰੱਦ ਕਰੋ -ਮਾਸਕ: -6600 -ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ -ਫੋਲਡਰ ਅਤੀਤ -ਡਾਈਗਨੋਸਟਿੱਕ ਸੰਦੇਸ਼ -ਸੰਦੇਸ਼ -7100 -ਕੰਪਿਊਟਰ -ਨੈੱਟਵਰਕ - -ਸਿਸਟਮ -7200 -ਸ਼ਾਮਲ ਕਰੋ -ਕੱਡੋ -ਪਰਖ ਕਰੋ -ਨਕਲ ਉਤਾਰੋ -ਨਵੇਂ ਟਿਕਾਣੇ ਤੇ ਭੇਜੋ -ਹਟਾਓ -ਜਾਣਕਾਰੀ -7300 -ਫਾਇਲ ਹਿੱਸਿਆਂ ਵਿੱਚ ਵੰਡੋ -ਹੇਠਾਂ ਦਿੱਤੇ ਟਿਕਾਣੇ ਉੱਤੇ ਹਿੱਸੇ ਕਰੋ (&S): -ਵੋਲੁੱਮਾਂ ਵਿੱਚ ਵੰਡੋ, ਬਾਈਟ (&v): -ਫਾਇਲ ਹਿੱਸਿਆਂ ਵਿੱਚ ਵੰਡੀ ਜਾ ਰਹੀ ਹੈ... -ਹਿੱਸੇ ਕਰਨ ਦੀ ਤਸਦੀਕ -ਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਫਾਇਲ ਦੇ {0} ਵੋਲੁੱਮਾਂ ਵਿੱਚ ਹਿੱਸੇ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? -ਵੋਲੁੱਮ ਸਾਈਜ਼ ਅਸਲੀ ਫਾਇਲ ਦੇ ਸਾਈਜ਼ ਤੋਂ ਛੋਟਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ -ਵੋਲੁੱਮ ਸਾਈਜ਼ ਗਲ਼ਤ ਹੈ -ਦਿੱਤਾ ਗਿਆ ਵੋਲੁੱਮ ਸਾਈਜ਼: {0} ਬਾਈਟ।\nਕੀ ਤੁਸੀਂ ਨਿਸ਼ਚਿੱਤ ਆਕਾਈਵ ਨੂੰ ਦਿੱਤੇ ਗਏ ਵੋਲੁੱਮਾਂ ਵਿੱਚ ਵੰਡਣਾ ਚਾਹੁੰਦੇ ਹੋ? -7400 -ਫਾਇਲ ਦੇ ਹਿੱਸੇ ਜੋੜੋ -ਹੇਠਾਂ ਦਿੱਤੇ ਟਿਕਾਣੇ ਉੱਤੇ ਹਿੱਸੇ ਜੋੜੋ(&C): -ਹਿੱਸੇ ਜੋੜੇ ਜਾ ਰਹੇ ਹਨ... -ਸਿਰਫ਼ ਪਹਿਲੀ ਫਾਇਲ ਚੁਣੋ - - -7500 -ਚੈਕਸੱਮ ਗਣਨਾ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ... -ਚੈਕਸੱਮ ਜਾਣਕਾਰੀ -ਡਾਟਾ ਲਈ ਸੀ-ਆਰ-ਸੀ ਚੈਕਸੱਮ: -ਡਾਟਾ ਅਤੇ ਨਾਮਾਂ ਲਈ ਸੀ-ਆਰ-ਸੀ ਚੈਕਸੱਮ: -7600 -ਬੈਂਚਮਾਰਕ -ਮੈਮੋਰੀ ਵਰਤੋਂ: -ਨਪੀੜਨ ਕਾਰਜ -ਖੋਲਣ ਕਾਰਜ -ਦਰਜ਼ਾ -ਕੁੱਲ ਦਰਜ਼ਾ -ਇਸ ਸਮੇਂ -ਰੀਸੱਲਟਿੰਗ -ਸੀ-ਪੀ-ਯੂ ਵਰਤੋਂ -ਦਰਜ਼ਾ / ਵਰਤੋਂ -ਪਾਸ: diff -Nru p7zip-rar-16.02/GUI/Lang/pl.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/pl.txt --- p7zip-rar-16.02/GUI/Lang/pl.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/pl.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,477 +0,0 @@ -;!@Lang2@!UTF-8! -; : cienislaw -; : pixel -; 9.07 : F1xat -; 9.33 : Łukasz Maria P. Pastuszczak -; -; -; -; -; -; -; -0 -7-Zip -Polish -Polski -401 -OK -Anuluj - - - -&Tak -&Nie -&Zamknij -Pomoc - -&Kontynuuj -440 -Ta&k na wszystkie -Ni&e na wszystkie -Zatrzymaj -Ponów -&Tło -&Pierwszy plan -&Wstrzymaj -Wstrzymano -Czy na pewno chcesz anulować? -500 -&Plik -&Edycja -&Widok -&Ulubione -&Narzędzia -Pomo&c -540 -&Otwórz -Otwórz &wewnątrz -Otwórz na &zewnątrz -Pod&gląd -&Edytuj -Zmień &nazwę -Kopiuj &do... -&Przenieś do... -&Usuń -Podzie&l plik... -Złą&cz pliki... -Wł&aściwości -Ko&mentarz -Oblicz sumę kontrolną -Diff -Utwórz &folder -U&twórz plik -Za&kończ -Dow&iązanie -600 -Z&aznacz wszystko -&Odznacz wszystko -Odwróć &zaznaczenie -Zaznacz... -Odznacz... -Zaznacz według typu -Odznacz według typu -700 -&Duże ikony -&Małe ikony -&Lista -&Szczegóły -730 -Nieposortowane -Widok płaski -&2 panele -&Paski narzędzi -Otwórz folder główny -Do góry o jeden poziom -Historia folderów... -&Odśwież -Automatyczne odświeżanie -750 -Pasek archiwum -Pasek standardowy -Duże przyciski -Pokaż etykiety tekstowe -800 -&Dodaj folder do ulubionych jako -Zakładka -900 -&Opcje... -&Test wydajności -960 -&Zawartość -7-Zip - i&nformacje -1003 -Ścieżka -Nazwa -Rozszerzenie -Folder -Rozmiar -Rozmiar po spakowaniu -Atrybuty -Utworzony -Ostatnio otwarty -Zmodyfikowany -Ciągły -Z komentarzem -Zaszyfrowany -Podzielony przed -Podzielony po -Słownik - -Typ -Anty -Metoda -Pochodzenie -System plików -Użytkownik -Grupa -Blok -Komentarz -Pozycja -Prefiks ścieżki -Foldery -Pliki -Wersja -Wolumin -Wielowoluminowy -Przesunięcie -Dowiązania -Bloki -Woluminy - -64-bitowy -Big-endian -Procesor -Rozmiar fizyczny -Rozmiar nagłówków -Suma kontrolna -Charakterystyki -Adres wirtualny -Numer seryjny woluminu -Krótka nazwa -Generator -Rozmiar sektora -Tryb -Dowiązanie symboliczne -Błąd -Całkowity rozmiar -Wolne miejsce -Rozmiar klastra -Etykieta -Nazwa lokalna -Dostawca -Zabezpieczenia NT -Alternatywny strumień - -Usunięty -Drzewo - - -Rodzaj błędu -Błędy -Błędy -Ostrzeżenia -Ostrzeżenie -Strumienie -Alternatywne strumienie -Rozmiar alternatywnych strumieni -Rozmiar wirtualny -Rozmiar po rozpakowaniu -Całkowity rozmiar fizyczny -Numer woluminu -Podtyp -Krótki komentarz -Strona kodowa - - - - - -Dowiązanie -Dowiązanie twarde -I-węzeł -2100 -Opcje -Język -Język: -Edytor -&Edytor: -&Diff: -2200 -System -Skojarz program 7-Zip z: -2301 -Zintegruj program 7-Zip z menu kontekstowym powłoki -Kaskadowe menu kontekstowe -Elementy menu kontekstowego: -Ikony w menu kontekstowym -2320 - - -Otwórz archiwum -Wypakuj pliki... -Dodaj do archiwum... -Testuj archiwum -Wypakuj tutaj -Wypakuj do {0} -Dodaj do {0} -Skompresuj i wyślij e-mailem... -Skompresuj do {0} i wyślij e-mailem -2400 -Foldery -Folder roboczy -&Systemowy folder tymczasowy -&Bieżący -&Wskazany: -Użyj tylko dla dysków wymiennych -Wskaż lokalizację dla tymczasowych plików archiwów. -2500 -Ustawienia -Pokaż element „..” -Pokaż prawdziwe ikony plików -Pokaż menu systemowe -Zaznaczaj &cały rząd -&Pokaż linie siatki -Pojedyncze kliknięcie otwiera element -&Alternatywny tryb zaznaczania -&Użyj dużych stron pamięci -2900 -7-Zip - informacje -7-Zip jest programem darmowym. -3000 -System nie może przydzielić wymaganej ilości pamięci -Nie wykryto błędów -Zaznaczono {0} obiekt(ów) -Nie można utworzyć folderu „{0}” -Operacje aktualizacji nie są obsługiwane dla tego archiwum. -Nie można otworzyć pliku „{0}” jako archiwum -Nie można otworzyć zaszyfrowanego archiwum „{0}”. Nieprawidłowe hasło? -Nieobsługiwany typ archiwum -Plik {0} już istnieje -Plik „{0}” został zmodyfikowany.\nCzy chcesz zaktualizować go w archiwum? -Nie można zaktualizować pliku\n„{0}” -Nie można uruchomić edytora. -Plik wygląda na wirusa (nazwa pliku zawiera długi ciąg spacji). -Operacja nie może być wywołana z folderu, który ma długą ścieżkę. -Musisz zaznaczyć jeden plik -Musisz zaznaczyć jeden lub więcej plików -Zbyt dużo elementów -3300 -Wypakowywanie -Kompresowanie -Testowanie -Otwieranie... -Skanowanie... -3400 -Wypakuj -&Wypakuj do: -Wskaż lokalizację dla wypakowanych plików. -3410 -Tryb ścieżek: -Pełne ścieżki -Bez ścieżek -Bezwzględne ścieżki -Względne ścieżki -3420 -Tryb nadpisywania: -Monituj przed nadpisaniem -Nadpisuj bez monitowania -Pomiń istniejące pliki -Automatycznie zmień nazwy -Automatycznie zmień nazwy istniejących plików -3430 -Wyeliminuj podwojenie folderu głównego -Przywróć zabezpieczenia plików -3500 -Potwierdź zamianę pliku -Folder docelowy zawiera już przetwarzany plik. -Czy chcesz zamienić istniejący plik -na następujący? -{0} bajtów -Automatycznie &zmień nazwy -3700 -Nieobsługiwana metoda kompresji pliku „{0}”. -Błąd danych w „{0}”. Plik jest uszkodzony. -CRC nie powiodła się dla „{0}”. Plik jest uszkodzony. -Błąd danych w zaszyfrowanym pliku „{0}”. Nieprawidłowe hasło? -CRC nie powiodła się dla zaszyfrowanego pliku „{0}”. Nieprawidłowe hasło? -3710 -Nieprawidłowe hasło? -3721 -Nieobsługiwana metoda kompresji -Błąd danych -CRC nie powiodła się -Niedostępne dane -Nieoczekiwany koniec danych -Pewne dane znajdują się za końcem bloku użytecznych danych -Nie rozpoznano archiwum -Błąd nagłówków -3763 -Niedostępny początek archiwum -Niepotwierdzony początek archiwum - - - -Nieobsługiwana funkcja -3800 -Wprowadź hasło -Wprowadź hasło: -Wprowadź ponownie hasło: -Pokaż &hasło -Hasła nie zgadzają się -W haśle używaj tylko liter alfabetu angielskiego, cyfr i znaków specjalnych (!, #, $, ...) -Hasło jest zbyt długie -Hasło -3900 -Upłynęło czasu: -Pozostało czasu: -Całkowity rozmiar: -Szybkość: -Przetworzono: -Współczynnik kompresji: -Błędy: -Archiwów: -4000 -Dodaj do archiwum -&Archiwum: -&Tryb aktualizacji: -&Format archiwum: -Stopień &kompresji: -&Metoda kompresji: -&Rozmiar słownika: -Rozmiar &słowa: -Rozmiar bloku ciągłego: -Liczba wątków: -&Parametry: -Opcje -&Utwórz archiwum SFX -Kompresuj pliki współdzielone -Szyfrowanie -Metoda szyfrowania: -&Zaszyfruj nazwy plików -Użycie pamięci dla kompresji: -Użycie pamięci dla dekompresji: -Usuń pliki po skompresowaniu -4040 -Zachowaj dowiązania symboliczne -Zachowaj dowiązania twarde -Zachowaj alternatywne strumienie danych -Zachowaj zabezpieczenia plików -4050 -Bez kompresji -Najszybsza -Szybka -Normalna -Maksymalna -Ultra -4060 -Dodaj i zamień pliki -Aktualizuj i dodaj pliki -Odśwież istniejące pliki -Synchronizuj pliki -4070 -Przeglądaj -Wszystkie pliki -Nieciągły -Ciągły -6000 -Kopiuj -Przenieś -Kopiuj do: -Przenieś do: -Kopiowanie... -Przenoszenie... -Zmienianie nazwy... -Wybierz folder docelowy. -Operacja nie jest obsługiwana dla tego folderu. -Błąd podczas zmiany nazwy pliku lub folderu -Potwierdź kopiowanie plików -Czy na pewno chcesz skopiować pliki do archiwum -6100 -Potwierdź usunięcie pliku -Potwierdź usunięcie folderu -Potwierdź usunięcie wielu plików -Czy na pewno chcesz usunąć plik „{0}”? -Czy na pewno chcesz usunąć folder „{0}” i całą zawartość? -Elementów: {0} - czy na pewno chcesz je usunąć? -Usuwanie... -Błąd podczas usuwania pliku lub folderu -System nie może przenieść pliku o długiej ścieżce do Kosza -6300 -Utwórz folder -Utwórz plik -Nazwa folderu: -Nazwa pliku: -Nowy folder -Nowy plik -Błąd podczas tworzenia folderu -Błąd podczas tworzenia pliku -6400 -- komentarz -&Komentarz: -Zaznacz -Odznacz -Maska: -6600 -Właściwości -Historia folderów -Komunikaty diagnostyczne -Komunikat -7100 -Komputer -Sieć -Dokumenty -System -7200 -Dodaj -Wypakuj -Testuj -Kopiuj -Przenieś -Usuń -Informacje -7300 -Podziel plik -&Podziel do: -Rozmiar &woluminów (bajty): -Dzielenie... -Potwierdź podział -Czy na pewno chcesz podzielić plik na {0} woluminów? -Rozmiar woluminu musi być mniejszy od rozmiaru oryginalnego pliku -Nieprawidłowy rozmiar woluminu -Określony rozmiar woluminu: {0} bajtów.\nCzy na pewno chcesz podzielić archiwum na takie woluminy? -7400 -Złącz pliki -&Złącz do: -Łączenie... -Zaznacz tylko pierwszą część podzielonego pliku -To nie jest poprawna część podzielonego pliku -Nie można odnaleźć co najmniej jednej części podzielonego pliku -7500 -Obliczanie sumy kontrolnej... -Informacja o sumie kontrolnej -Suma kontrolna CRC dla danych: -Suma kontrolna CRC dla danych i nazw: -7600 -Test wydajności -Użycie pamięci: -Kompresja -Dekompresja -Ocena -Całkowita ocena -Aktualnie -Wynik -Użycie CPU -Ocena / Użycie -Przebiegi: -7700 -Dowiązanie -Dowiąż -Element źródłowy: -Element docelowy: -7710 -Rodzaj dowiązania -Dowiązanie twarde -Dowiązanie symboliczne pliku -Dowiązanie symboliczne katalogu -Połączenie katalogów diff -Nru p7zip-rar-16.02/GUI/Lang/ps.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ps.txt --- p7zip-rar-16.02/GUI/Lang/ps.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ps.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.53 : 2007-12-26 : Pathanisation Project : pathanisation.pakhtosoft.com -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Pashto -پښتو -401 -هوکې -بندول - - - -هو& -نه& -بندول& -مرسته - -پرمختلل& -440 -ټولو ته هو& -ټ&ولو ته نه -تمول -بياپېلول -شاليد& -پاسليد& -ځنډول& -څنډېدلی -په ډاډمنه توګه غواړئ چې بند يې کړئ؟ -500 -دوتنه& -سمون& -ليد& -خ&واپوري -توکي& -مرسته& -540 -پرانيستل& -دننه& پرانيستل -بهر پ&رانيستل -ليد& -سمون& -بي&انومول -...ته لمېسل& -...ته خوځول& -ړنګول& -...دوتنه چول& -...دوتنې يوځ&ايول -ځانتياوې -څرګند&ون -چېکسم شمېرل - -پوښۍ جوړول -دوتنه جوړول -و&تون -600 -ټول ټاکل& -ټول ناټاکل -ټاکنه نسکورول& -...ټاکل -...ناټاکل -پر ډول ټاکل -پر ډول ناټاکل -700 -لو&ی انځورنونه -و&اړه انځورنونه -لړ& -خبرتياوې& -730 -ناڼلي -پوړ ليد -۲‏ چوکاټه& -توکپټې& -ولۍ پوښۍ پرانيستل -يو کچه برول -...پوښيو مخينه -تاندول& -750 -ارشيو توکپټه -کره توکپټه -لویې تڼۍ -د تڼيو ليکنې ښودل -800 -پوښۍ خواپورو ته زياتول لکه& -نښه -900 -...غوراوي& -بنچمارک& -960 -...منځپانګه& -...۷‏-زېپ په اړه& -1003 -يونلور -نوم -شاتاړی -پوښۍ -کچ -بنډل شوی کچ -څانتياوې -جوړشوی -رسی -بدلون -کلک -څرګندون -کوډييز -چول مخکښې -چول وروسته -ويېپانګه -CRC -ډول -مخالف -لېله -کوربه چغ -دوتنه غونډال -کارن -ډله -غونډ -څرګندون -ځای -يونلور مختاړی -پوښۍ -دوتنې -نسخه -ډکون -ګڼډکون -افسېټ -پېوندونه -غوڼدونه -ډکونونه - - - - - - - - - - - - - - - -تېروتنه -بشپړ کچ -پاتې تشه -ځومبک کچ -نښکه -ځایي نوم -برابروونى -2100 -غوراوي -ژبه -:ژبه -سمونګر -:سمونګر& - -2200 -غونډال -:له ۷‏-زېپ سره ملول -2301 -۷‏-زېپ سيپۍ تړاو غورنۍ کښې زياتول -ځړبهيزه تړاو غورنۍ -:تړاو غورنۍ توکي -2320 -<پوښۍ> -<ارشيو> -ارشيو پرانيستل -...دوتنې ويستل -...ارشيو ته زياتول -ارشيو ازمويل -دلته ويستل -ته ويستل {0}‏ -ته زياتول {0} -...زېرل او برېښل -ته زياتول او برېښل {0} -2400 -پوښۍ -&کارنه پوښۍ -&لنډمهاله غونډال پوښۍ -&اوسنۍ -&څانګړې -يوازې له لېرېدونکو چليځونو لپاره کارول -.د لنډمهاله ارشيو دوتنو لپاره ځای وټاکئ -2500 -امستنې -توکي ښودل ".." -د دوتنو ريښتيني انځورنونه ښودل -غونډال غورنۍ ښودل -ټول کيل ټاکل& -کرښې ښودل - -انډوليز ټاکنې اکر& -لوی ياد مخونه کارول& -2900 -۷‏-زېپ په اړه -.دا يو وړيا ساوتری دی. خو، په نومکښلو سره د ساوتري د پرمختګ ملاتړ کولی شئ -3000 - -هېڅ تېروتنه نشته -ټاکل شوي څيزونه {0} -پوښۍ جوړولی نه شي '{0}' -.اوسمهاله چلښتونه دې ارشيو لپاره منلي نه دي -'{0}' دوتنه لکه د ارشيو نه شي پرانيستلی -کوډييز ارشيو پرانيستلی نه شي '{0}'. ناسمه تېرنويې؟ - - -.'{0}' دوتنه کښې بدلون راغلی\nپه ارشيو کښې يې اوسمهالول غواړئ؟ -'{0}'\nدوتنه اوسمهالولی نه شي -سمونګر پېلولی نه شي - - - - -ډېر زيات توکي -3300 -وباسي -زېرل کيږي -ازموينه -...پرانيستل کيږي -...ځیريږي -3400 -ويستل -:ته و&يستل -.د ويستلو دوتنو لپاره يو ځای وټاکئ -3410 -يونلور اکر -بشپړ يونلورنومونه -هېڅ يونلورنومونه -3420 -سرليکلو اکر -سرليکلو نه مخکښې پوښتل -بې له پارليکې سرليکل -شته دوتنې پرېښودل -خپله بيانومول -شته دوتنې خپله بيانومول -3500 -دوتنه ځاېناستی باورييل -.موخه پوښۍ دمخه بهيرلې دوتنې لري -غواړئ چې شته دوتنه ځاېناستې کړئ -له دې سره؟ -باېټه {0} -خپله ب&يانومول -3700 -.لپاره نامنلې زېرنې لېله '{0}' -.کښې اومتوک ستونزه '{0}' دوتنه ماته ده -.کښې سرس پاتې راغی '{0}' دوتنه ماته ده -کوډييزې دوتنې '{0}' کښې اومتوک ستونزه. ناسمه تېرنويې؟ -په کوډييزې دوتنې '{0}' کښې سرس پاتې راغی. ناسمه تېرنويې؟ -3800 -تېرنويې وليکئ -:تېرنويې وليکئ -:تېرنويې بيا وليکئ -تېرنويې ښودل& -تېرنويې سمون نه خوري -تېرنويې لپاره يوازې انګريزي توري، شمېرې او ځانګړي لوښې (!, #, $, ...) وکاروئ -تېرنويې ډېره اوږده ده -تېرنويې -3900 -:تېر مهال -:پاتې مهال -:بشپړ کچ -:چټکتیا -:بهيرلی -:زېرلو نسبت -:تېروتنه -:ارشيونه -4000 -ارشيو ته زياتول -:ارشيو& -:اوسمهاليز اکر& -:ارشيو بڼه& -:زېرنې &کچه -:زېرنې &لېله -:ويېپانګې کچه& -:ويې کچ& -:کلک غونډ کچ -:د مبي مزيو شمېر -:ارزښتمني& -غوراوي -ارشيو جوړول SF&X -ونډولې دوتنې زېرل -کوډییزونه -:کوډییزونې لېله -دوتنه &نومونه کوډييزول -:زېرلو لپاره ياد کارونه -:نازېرلو لپاره ياد کارونه -4050 -زېرمل -ډېر چټک -چټک -ليوی -زيات -ډېر زيات چټک -4060 -دوتنې زياتول او ځاېناستول -دوتنې اوسمهالول او زياتول -شته دوتنې تاندول -دوتنې هممهالول -4070 -لټول -ټولې دوتنې -نا-کلک -کلک -6000 -لمېسل -خوځول -:ته لمېسل -:ته خوځول -...لميسل کيږي -...خوځيږي -بيانوميږي -.موخه پوښۍ وټاکئ -.چلښت منلی نه دی -دوتنې يا پوښۍ بيانومولو ستونزه -دوتنې لمېسل باورييل -په ډاډمنه توګه دوتنې ارشيو ته لمېسل غواړئ؟ -6100 -دوتنې ړنګونه باورييل -پوښۍ ړنګونه باورييل -ګڼو دوتنو ړنګونه باورييل -په ډاډمنه توګه '{0}' ړنګول غواړئ؟ -په ډاډمنه توګه '{0}' پوښۍ او د دې ټوله منځپانګه ړنګول غواړئ؟ -په ډاډمنه توګه دا {0} توکي ړنګول غواړئ؟ -...ړنګيږي -دوتنې يا پوښۍ ړنګولو ستونزه - -6300 -پوښۍ جوړول -دوتنه جوړول -:پوښۍ نوم -:دوتنه نوم -نوې پوښۍ -نوې دوتنه -پوښۍ جوړولو ستونزه -دوتنې جوړولو ستونزه -6400 -څرګندون -:څرګندون& -ټاکل -ناټاکل -:وربوزۍ -6600 -ځانتياوې -پوښيو مخينه -رنځ نومېرنې استوزه -استوزه -7100 -سولګر -جال - -غونډال -7200 -زياتول -ويستل -ازمويل -لمېسل -خوځول -ړنګول -خبرتياوې -7300 -دوتنه چول -:ته چول& -:ډکونونو، باېټونو ته چول& -...چول کيږي -چونه باورييل -په ډاډمنه توګه دوتنه په {0} ډکونونو وېشل غواړئ؟ -ډکون کچ بايد د دوتنې ار کچ نه وړوکی وي -ناسم ډکون کچ -.باېټه {0} :ټاکلی ډکون کچ\nپه ډاډمنه توګه غواړئ چې ارشيو په داسې ډکونونو وويشئ؟ -7400 -دوتنې يوځايول -:ته يوځايول& -...يوځايږي -يوازې لمړۍ دوتنه ټاکل - - -7500 -...چېکسم شمېريږي -چېکسم خبرتياوې -:چېکسم CRC اومتوک لپاره -:چېکسم CRC اومتوک او نومونو لپاره -7600 -بنچمارک -:ياد کارونه -زېريږي -نازېريږي -کچونه -بشپړه کچونه -اوسنی -پايليز -مبي کارونه -کچونه / کارونه -:تيريږي diff -Nru p7zip-rar-16.02/GUI/Lang/pt-br.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt-br.txt --- p7zip-rar-16.02/GUI/Lang/pt-br.txt 2015-10-03 12:54:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt-br.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Francisco Jr -; 4.37 : Fabricio Biazzotto -; 15.07 : Atualizado por Felipe -; -; -; -; -; -; -; -; -0 -7-Zip -Portuguese Brazilian -Português Brasileiro -401 -OK -Cancelar - - - -&Sim -&Não -&Fechar -Ajuda - -&Continuar -440 -Sim pra &Todos -Não pra T&odos -Parar -Reiniciar -&Em 2º plano -&Em 1º plano -&Pausar -Pausado -Você tem certeza que você quer cancelar? -500 -&Arquivo -&Editar -&Visualizar -F&avoritos -&Ferramentas -&Ajuda -540 -&Abrir -Abrir &por Dentro -Abrir p&or Fora -&Visualizar -&Editar -Re&nomear -&Copiar Para... -&Mover Para... -&Apagar -&Dividir arquivo... -Com&binar arquivos... -P&ropriedades -Comen&tário -Calcular checksum -Diff -Criar Pasta -Criar Arquivo -S&air -Link -&Correntes Alternantes -600 -Selecionar &Tudo -Desmarcar Tudo -&Inverter Seleção -Selecionar... -Desmarcar... -Selecionar por Tipo -Desfazer seleção por Tipo -700 -Íco&nes Grandes -Íc&ones Pequenos -&Lista -&Detalhes -730 -Desorganizado -Visualização Plana -&2 Painéis -&Barra de Ferramentas -Abrir a Pasta Raiz -Um Nível Acima -Histórico das Pastas... -&Atualizar -Auto-Atualizar -750 -Barra de Ferramentas do Arquivo Compactado -Barra de Ferramentas Padrão -Botões Grandes -Mostrar o Texto dos Botões -800 -&Adicionar a pasta aos Favoritos como -Favorito -900 -&Opções... -&Benchmark -960 -&Conteúdo... -&Sobre o 7-Zip... -1003 -Caminho -Nome -Extensão -Pasta -Tamanho -Tamanho Compactado -Atributos -Criado -Acessado -Modificado -Sólido -Comentado -Criptografado -Dividir Antes -Dividir Depois -Dicionário - -Tipo -Anti -Método -Sistema Operacional Hospedeiro -Sistema de Arquivos -Usuário -Grupo -Bloco -Comentário -Posição -Prefixo do Caminho -Pastas -Arquivos -Versão -Volume -Multivolume -Offset -Links -Blocos -Volumes - -64 bits -Big-endian -CPU -Tamanho Físico -Tamanho dos Cabeçalhos -Checksum -Características -Endereço Virtual -ID -Nome Curto -Aplicativo Criador -Tamanho do Setor -Modo -Link Simbólico -Erro -Tamanho Total -Espaço Livre -Tamanho do Cluster -Rótulo -Nome Local -Provedor -Segurança da NT -Corrente Alternante -Aux -Apagado -É Árvore - - -Tipo de Erro -Erros -Erros -Avisos -Aviso -Correntes -Correntes Alternantes -Tamanho das Correntes Alternantes -Tamanho Virtual -Tempo Descompactado -Total do Tamanho Físico -Índice do Volume -Sub-Tipo -Comentário Curto -Página do Código - - - -Tamanho da Cauda -Tamanho do Toco Embutido -Link -Link Rígido -iNode - -Somente-Leitura -2100 -Opções -Idioma -Idioma: -Editor -&Editor: -&Diff: -2200 -Sistema -Associar o 7-Zip com: -Todos os usuários -2301 -Integrar o 7-Zip ao menu de contexto do shell -Menu de contexto em cascata -Itens do menu de contexto: -Ícones no menu de contexto -2320 - - -Abrir arquivo compactado -Extrair arquivos... -Adicionar ao arquivo compactado... -Testar arquivo compactado -Extrair Aqui -Extrair para {0} -Adicionar para {0} -Comprimir e enviar por email... -Comprimir para {0} e enviar por email -2400 -Pastas -&Pasta de trabalho -&Pasta temporária do sistema -&Atual -&Especificada: -Usar só pra drives removíveis -Especifique um local pros arquivos compactados temporários. -2500 -Configurações -Mostrar o item ".." -Mostrar os ícones reais dos arquivos -Mostrar o menu do sistema -&Selecionar a linha inteira -Mostrar as &linhas de grade -Clique único pra abrir um item -&Modo de seleção alternativo -Usar &grandes páginas de memória -2900 -Sobre o 7-Zip -7-Zip é um software grátis -3000 -O sistema não pôde alocar a quantia requerida de memória -Não há erros -{0} objeto(s) selecionado(s) -Não pôde criar a pasta '{0}' -Operações de atualização não são suportadas por este arquivo compactado. -Não pôde abrir o arquivo '{0}' como arquivo compactado -Não pôde abrir o arquivo compactado encriptado '{0}'. Senha errada? -Tipo de arquivo compactado não suportado -O arquivo {0} já existe -O arquivo '{0}' foi modificado.\nVocê quer atualizá-lo no arquivo compactado? -Não pôde atualizar o arquivo\n'{0}' -Não pôde iniciar o editor. -O arquivo parece um vírus (o nome do arquivo contém espaços longos no nome). -A operação não pode ser chamada de uma pasta que tem um caminho longo. -Você deve selecionar um arquivo -Você deve selecionar um ou mais arquivos -Itens demais -Não pôde abrir o arquivo como {0} arquivo compactado -O arquivo está aberto como {0} arquivo compactado -O arquivo compactado está aberto com o offset -3300 -Extraindo -Comprimindo -Testando -Abrindo... -Escaneando... -Removendo -3320 -Adicionando -Atualizando -Analisando -Replicando -Re-compactando -Ignorando -Apagando -Criando cabeçalho -3400 -Extrair -E&xtrair para: -Especifique um local pros arquivos extraídos. -3410 -Modo do caminho: -Nomes dos caminhos completos -Sem nomes de caminhos -Nomes dos caminhos absolutos -Nomes dos caminhos relativos -3420 -Modo de sobrescrição: -Perguntar antes de sobrescrever -Sobrescrever sem alertar -Ignorar os arquivos existentes -Auto-renomear -Auto-renomear os arquivos existentes -3430 -Eliminar duplicação da pasta raiz -Restaurar a segurança do arquivo -3500 -Confirmar a Substituição dos Arquivos -A pasta destino já contém o arquivo processado. -Você gostaria de substituir o arquivo existente -por este? -{0} bytes -A&uto-Renomear -3700 -Método de compressão não suportado por '{0}'. -Erro nos dados de '{0}'. O arquivo está danificado. -O CRC falhou em '{0}'. O arquivo está danificado. -Erros nos dados do arquivo encriptado '{0}'. Senha errada? -O CRC falhou no arquivo encriptado '{0}'. Senha errada? -3710 -Senha errada? -3721 -Método de compressão não suportado -Erro dos dados -O CRC falhou -Dados indisponíveis -Fim inesperado dos dados -Há alguns dados após o fim da carga dos dados -Não é arquivo compactado -Erro dos Cabeçalhos -Senha errada -3763 -Início indisponível do arquivo compactado -Início não confirmado do arquivo compactado - - - -Função não suportada -3800 -Inserir senha -Inserir senha: -Re-inserir a senha: -&Mostrar senha -As senhas não combinam -Usar apenas letras em Inglês, números e caracteres especiais (!, #, $, ...) para a senha -A senha é muito longa -Senha -3900 -Tempo decorrido: -Tempo restante: -Tamanho total: -Velocidade: -Processados: -Taxa de compressão: -Erros: -Arquivos: -4000 -Adicionar ao arquivo compactado -&Arquivo compactado: -&Modo de atualização: -Formato do &arquivo compactado: -Nível da &compressão: -Método de &compressão: -&Tamanho do dicionário: -&Tamanho da palavra: -Tamanho do bloco sólido: -Número de threads da CPU: -&Parâmetros: -Opções -Criar ar&quivo compactado SFX -Comprimir arquivos compartilhados -Encriptação -Método de encriptação: -Criptografar os &nomes dos arquivos -Uso de memória pra Compressão: -Uso de memória para Descompressão: -Apagar arquivos após a compressão -4040 -Armazenar links simbólicos -Armazenar links rígidos -Armazenar correntes de dados alternantes -Armazenar segurança do arquivo -4050 -Armazenar -Mais rápida -Rápida -Normal -Máximo -Ultra -4060 -Adicionar e substituir arquivos -Atualizar e adicionar arquivos -Atualizar arquivos existentes -Sincronizar arquivos -4070 -Navegar -Todos os Arquivos -Não-sólido -Sólido -6000 -Copiar -Mover -Copiar para: -Mover para: -Copiando... -Movendo... -Renomeando... -Selecionar a pasta destino. -A operação não é suportada por esta pasta. -Erro ao Renomear o Arquivo ou Pasta -Confirmar a Cópia do Arquivo -Você tem certeza que você quer copiar os arquivos pra dentro do arquivo compactado? -6100 -Confirmar a Exclusão do Arquivo -Confirmar a Exclusão da Pasta -Confirmar a Exclusão de Múltiplos Arquivos -Você tem certeza que você quer apagar '{0}'? -Você tem certeza que você quer apagar a pasta '{0}' e todo o conteúdo dela? -Você tem certeza que você quer apagar estes {0} itens? -Apagando... -Erro ao Apagar o Arquivo ou Pasta -O sistema não pode mover um arquivo com caminho longo para o Recycle Bin -6300 -Criar Pasta -Criar Arquivo -Nome da pasta: -Nome do Arquivo: -Nova Pasta -Novo Arquivo -Erro ao Criar a Pasta -Erro ao Criar o Arquivo -6400 -Comentário -&Comentário: -Selecionar -Desmarcar -Máscara: -6600 -Propriedades -Histórico das Pastas -Mensagens de diagnóstico -Mensagem -7100 -Computador -Rede -Documentos -Sistema -7200 -Adicionar -Extrair -Testar -Copiar -Mover -Apagar -Info -7300 -Dividir Arquivo -&Dividir para: -Dividir em &volumes, bytes: -Dividindo... -Confirmar a Divisão -Você tem certeza que você quer dividir o arquivo em {0} volumes? -O tamanho do volume deve ser menor do que o tamanho do arquivo original -Tamanho do volume incorreto -Tamanho do volume especificado: {0} bytes.\nVocê tem certeza que você quer dividir o arquivo compactado em tais volumes? -7400 -Combinar Arquivos -&Combinar em: -Combinando... -Selecionar só a primeira parte do arquivo dividido -Não pôde detectar o arquivo como parte do arquivo dividido -Não pôde achar mais do que uma parte do arquivo dividido -7500 -Calculando checksum... -Informação do checksum -Checksum do CRC pros dados: -Checksum do CRC pros dados e nomes: -7600 -Benchmark -Uso da memória: -Comprimindo -Descomprimindo -Avaliação -Total da Avaliação -Atual -Resultando -Uso da CPU -Avaliação / Uso -Passos: -7700 -Link -Link -Link de: -Link para: -7710 -Tipo de Link -Link Rígido -Link Simbólico do Arquivo -Link Simbólico do Diretório -Junção do Diretório diff -Nru p7zip-rar-16.02/GUI/Lang/pt.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt.txt --- p7zip-rar-16.02/GUI/Lang/pt.txt 2016-05-19 09:45:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/pt.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Carlos Macao -; : João Alves -; : João Frade (100 NOME TR) -; 4.46 : Rui Costa -; 9.17 : Sérgio Marques -; 15.00 : Rui Aguiar -; -; -; -; -; -0 -7-Zip -Portuguese Portugal -Português -401 -OK -Cancelar - - - -&Sim -&Não -&Fechar -Ajuda - -&Continuar -440 -Sim p/ &Todos -Não p/ T&odos -Parar -Reiniciar -&Segundo plano -P&rimeiro plano -&Pausar -Em pausa -Quer mesmo cancelar? -500 -&Ficheiro -&Editar -&Ver -F&avoritos -Ferramen&tas -&Ajuda -540 -&Abrir -Abrir &dentro -Abrir &fora -&Ver -&Editar -Mudar& o nome -&Copiar para... -&Mover para... -&Eliminar -&Separar ficheiro... -Com&binar ficheiros... -P&ropriedades -Come&ntário -Calcular o checksum -Diff -Criar pasta -Criar ficheiro -&Sair -Link -&Alternar Fluxo -600 -Seleccionar &Tudo -Desmarcar tudo -&Inverter selecção -Seleccionar... -Desmarcar... -Seleccionar por tipo -Desmarcar por tipo -700 -Ícones &grandes -Ícones &pequenos -&Lista -&Detalhes -730 -Sem ordem -Vista plana -&2 painéis -&Barras de ferramentas -Abrir pasta root -Subir um nível -Histórico de pastas... -&Actualizar -Auto Actualizar -750 -Barra de ferramentas do arquivo -Barra de ferramentas pré-definida -Botões grandes -Mostrar a legenda dos botões -800 -&Adicionar a pasta aos favoritos como -Marcador -900 -&Opções... -&Desempenho -960 -&Conteúdo... -&Acerca do 7-Zip... -1003 -Caminho -Nome -Extensão -pasta -Tamanho -Tamanho comprimido -Atributos -Criado -Acedido -Modificado -sólido -Comentado -Encriptado -Separar antes -Separar depois -Dicionário - -Tipo -Anti -Método -SO anfitrião -Sistema de ficheiros -Utilizador -Grupo -Bloco -Comentário -Posição -Prefixo do destino -pastas -ficheiros -Versão -Volume -Multivolume -Não definido -Ligações -Blocos -Volumes - -64-bit -Big-endian -CPU -Tamanho físico -Tamanho dos cabeçalhos -Soma de verificação -Características -Endereço virtual -ID -Abreviatura -Criador da aplicação -Tamanho do sector -Modo -Ligação -Erro -Tamanho total -Espaço livre -Tamanho do sector -Etiqueta -Nome local -Fornecedor -Segurança NT -Alternar Fluxo -Aux -Excluído -É Árvore - - -Tipo de Erro -Erros -Erros -Avisos -Aviso -Fluxo -Alternar Fluxo -Alternate Tamanho de Fluxos -Tamanho Virtual -Tamanho Descompactado -Tamanho Físico Total -Índice de Volume -SubTipo -Breve Comentário -Página de Código - - - -Tamanho Tail -Tamanho Stub Incorporado -Link -Link do Disco Rígido -iNode - -Só de leitura -2100 -Opções -Idioma -Idioma: -Editor -&Editor: -&Diff: -2200 -Sistema -Associar o 7-Zip com: -Todos os utilizadores -2301 -Integrar o 7-Zip no menu de contexto -Menu de contexto em cascata -Itens do menu de contexto: -Icons no menu de contexto -2320 - - -Abrir arquivo -Extrair ficheiros... -Adicionar ao arquivo... -Testar arquivo -Extrair para aqui -Extrair para {0} -Adicionar a {0} -Comprimir e enviar por e-mail... -Comprimir para {0} e enviar por e-mail -2400 -pastas -&Pasta de trabalho -Pasta &temporária -&Actual -&Especificada: -Utilizar só para discos amovíveis -Especifique a pasta para os ficheiros temporários. -2500 -Definições -Mostrar item ".." -Mostrar os ícones reais dos ficheiros -Mostrar o menu do sistema -Selecção de linha &completa -Mostrar as linhas da &grelha -Clique uma vez para abrir um item -Modo de seleçção &alternativo -Utilizar páginas de &memória grandes -2900 -Acerca do 7-Zip -O 7-Zip é um programa gratuito.\n\nO 7-Zip foi traduzido por: Rui Aguiar\n\trui_a_aguiar@hotmail.com -3000 -O sistema não consegue alocar a memória necessária -Não existem erros -{0} objecto(s) seleccionado(s) -Não é possível criar a pasta '{0}' -Este tipo de arquivo não permite actualizações. -Não é possível abrir o ficheiro '{0}' como arquivo -Não é possível abrir o arquivo encriptado '{0}'. Palavra-passe errada? -O arquivo não é suportado -Já existe o ficheiro {0} -O ficheiro '{0}' foi modificado.\nQuer actualizá-lo no arquivo? -Não foi possível actualizar o ficheiro\n'{0}' -Não foi possível iniciar o editor. -O ficheiro parece ser um vírus (o nome do ficheiro contém muitos espaços em branco). -A operação não pode ser invocada a partir de uma pasta com uma longa localização. -Tem que seleccionar um ficheiro -Tem que seleccionar um ou mais ficheiros -Demasiados itens -Não é possível abrir o ficheiro como arquivo {0} -Ficheiro aberto como arquivo {0} -Arquivo aberto com offset -3300 -A extrair... -A comprimir -A testar... -A abrir... -A pesquisar... -Removendo -3320 -A adicionar... -A actualizar... -A analisar... -Replicando -A recomprimir... -A ignorar... -A eliminar -Criando cabeçalho -3400 -Extrair -E&xtrair para: -Especifique o destino para os ficheiros extraídos. -3410 -Modo de nome de pasta -Nome de pastas completo -Sem nome de pastas -Caminhos absolutos -Caminhos relativos -3420 -Modo de sobrescrever -Perguntar antes de substituir -Sem confirmação -Ignorar ficheiros existentes -Mudar o nome automaticamente. -Mudar o nome automomaticamente os ficheiros existentes -3430 -Eliminar a duplicação da pasta de raiz -Restaurar segurança de ficheiros -3500 -Confirmar substituição de ficheiro -A pasta já possui um ficheiro com o mesmo nome. -Deseja substituir o ficheiro existente -por este? -{0} bytes -Mudar o nome a&utomaticamente -3700 -O método de compressão é inválido para '{0}'. -Erro de dados em '{0}'. O arquivo está danificado. -CRC falhou em '{0}'. O arquivo está danificado. -Erro de dados no ficheiro encriptado '{0}'. Palavra-passe errada? -CRC falhou no ficheiro encriptado '{0}'. Palavra-passe errada? -3710 -Palavra-passe errada? -3721 -Método de compressão não suportado -Erro nos dados -O CRC falhou -Dados indisponíveis -Fim inesperado nos dados -Existem alguns dados após o final dos dados de carga útil -Não é um arquivo -Erro nos Cabeçalhos -Palavra-passe errada -3763 -Início de arquivo indisponível -Início de arquivo não confirmado - - - -Funcionalidade não suportada -3800 -Insira a palavra-passe -Introduza a palavra-passe: -Reintroduza a palavra-passe: -&Mostrar palavra-passe -As palavras-passe não coincidem -Para a palavra-passe, utilize apenas letras inglesas, números e os caracteres especiais (!, #, $, ...) -A palavra-passe é muito comprida -Palavra-passe -3900 -Tempo decorrido: -Tempo restante: -Tamanho: -Velocidade: -Processado: -Rácio de compressão: -Erros: -Arquivos: -4000 -Adicionar ao arquivo -&Arquivo: -&Modo de actualização: -&Formato do arquivo: -Níve&l de compressão: -Método de &compressão: -Tamanho do &dicionário: -&Tamanho da &palavra: -Tamanho dos blocos sólidos: -Nº de processos do CPU: -&Parâmetros: -Opções -Criar arquivo SF&X -Comprimir ficheiros partilhados -Encriptação -Método de encriptação: -Encriptar &nomes de ficheiros -Utilização de memória para compressão: -Utilização de memória para descompressão: -Excluir ficheiros após compressão -4040 -Armazenar links simbólicos -Armazenar links do disco rígido -Armazenar fluxo de dados alternados -Armazenar segurança de ficheiros -4050 -Guardar -Muito rápido -Rápido -Normal -Máxima -Ultra -4060 -Adicionar e substituir ficheiros -Actualizar e adicionar ficheiros -Actualizar ficheiros -Sincronizar ficheiros -4070 -Procurar -Todos os ficheiros -Não sólido -sólido -6000 -Copiar -Mover -Copiar para: -Mover para: -A copiar... -A mover... -A mudar o nome... -Seleccione a pasta de destino. -Operação não suportada. -Erro ao mudar o nome do ficheiro ou pasta -Confirmar a cópia dos ficheiros -Quer mesmo copiar os ficheiros para o arquivo? -6100 -Confirmar a eliminação do ficheiro -Confirmar a eliminação da pasta -Confirmar a eliminação de múltiplos ficheiros -Quer mesmo eliminar o '{0}'? -Quer mesmo eliminar a pasta '{0}' e todo o seu conteúdo? -Quer mesmo eliminar os itens {0}? -A eliminar... -Erro ao eliminar o ficheiro ou pasta -O sistema não consegue mover para a reciclagem um ficheiro com uma localização longa -6300 -Criar pasta -Criar ficheiro -Nome da pasta: -Nome do ficheiro: -Nova Pasta -Novo ficheiro -Erro ao criar a pasta -Erro ao criar ficheiro -6400 -Comentário -&Comentário: -Seleccionar -Desseleccionar -Máscara: -6600 -Propriedades -Histórico de pastas -Mensagens de diagnóstico -Mensagem -7100 -Computador -Rede -Documentos -Sistema -7200 -Adicionar -Extrair -Testar -Copiar -Mover -Eliminar -Info -7300 -Separar ficheiro -&Separar para: -Separar por &volumes, bytes: -A separar... -Confirmar separação -Quer mesmo separar o ficheiro em {0} volumes? -O tamanho do volume tem de ser inferior ao tamanho do ficheiro original -Tamanho do volume incorrecto -Tamanho do volume especificado: {0} bytes.\nQuer mesmo separar o arquivo nestes volumes? -7400 -Combinar ficheiros -&Combinar para: -A combinar... -Seleccione apenas o primeiro ficheiro -Não foi possivel apagar o ficheiro como parte do ficheiro dividido -Não foi possível encontrar mais do que uma parte do ficheiro dividido -7500 -A calcular o checksum... -Informações do checksum -CRC checksum para dados: -CRC checksum para dados e nome: -7600 -Desempenho -Utilização de Memória: -A comprimir -A descomprimir -Desempenho -Desempenho Total -Actual -Resultante -Utilização CPU -Desemp. / Utiliza. -Passagens: -7700 -Link -Link -Link de: -Link para: -7710 -Link Tipo -Link do Disco Rígido -Link do Ficheiro Simbólico -Link do Directório Simbólico -Directório de Junção \ No newline at end of file diff -Nru p7zip-rar-16.02/GUI/Lang/ro.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ro.txt --- p7zip-rar-16.02/GUI/Lang/ro.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ro.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.59 : Lucian Nan : http://www.prizeeinternational.com -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Romanian -Română -401 -Bine -Anulare - - - -&Da -&Nu -&Închide -Ajutor - -&Continuă -440 -Da, pe &toate -N&ici unul -Opreşte -Restartează -În &fundal -La &suprafaţă -&Pauză -În pauză -Eşti sigur că vrei să anulezi? -500 -&Fişier -&Editează -&Vizualizează -F&avorite -&Unelte -&Ajutor -540 -&Deschide -Deschide î&n -Deschide în &afară -&Vizualizeză -&Editează -&Redenumeşte -&Copiază la... -&Mută la... -Şter&ge -Împarte &fişierul... -&Uneşte fişierele... -&Proprietăţi -Comen&tariu -Calculează suma de verificare - -Crează director -Crează fişier -&Ieşire -600 -&Selectează tot -&Deselectează tot -&Inversează selecţia -Selectează... -Deselectează... -Selectează după tip -Deselectează după tip -700 -Iconiţe m&ari -Iconiţe m&ici -&Listă -&Detalii -730 -Nesortat -Vedere plană -&2 panouri -Bare de &unelte -Deschide directorul rădăcină -Un nivel mai sus -Istoria directoarelor... -&Împrospătează -750 -Bara de arhivare -Bara de unelte standard -Butoane mari -Arată textul butoanelor -800 -&Adaugă directorul în Favorite ca -Semn de carte -900 -&Opţiuni... -&Banc de încercare -960 -&Conţinut... -&Despre 7-Zip... -1003 -Calea -Nume -Extensie -Director -Mărime -Mărimea pachetului -Atribute -Creată -Accesată -Modificată -Solidă -Comentat -Criptat -Împarte înainte -Împarte după -Dicţionar -CRC -Tip -Anti -Metoda -SO gazdă -Fişier de sistem -Utilizator -Grup -Blochează -Comentariu -Poziţia -Prefixul destinaţiei -Directoare -Fişiere -Versiunea -Volum -Multivolume -Ofset -Legături -Blocuri -Volume - -64-bit -Big-endian -CPU -Mărime fizică -Mărimea antetelor -Checksum -Caracteristici -Adresa virtuală - - - - - - -Eroare -Mărimea totală -Spaţiu liber -Mărimea grupului -Etichetă -Nume local -Distribuitor -2100 -Opţiuni -Limba -Limba: -Editor -&Editor: - -2200 -Sistem -Asociază 7-Zip cu: -2301 -Integrează 7-Zip în contextul meniului shell -Contextul meniului în cascadă -Obiectele meniului: -2320 - - -Deschide arhiva -Dezarhivează fişierele... -Adaugă într-o arhivă... -Testează arhiva -Dezarhivează aici -Dezarhivează în {0} -Adaugă în {0} -Arhivează şi trimite email... -Arhivează în {0} şi trimite email -2400 -Directoare -&Directorul de lucru -Directorul &tempotar al sistemului -&Actual -&Specificat: -Utilizează numai pentru discurile detaşabile -Specifică o destinaţie pentru arhivele temporare. -2500 -Setări -Arată ".." obiect -Arată iconiţele reale ale fişierului -Arată meniul sistemului -Selectează &tot rândul -Arată liniile de ghidare - -Mod de selectare &alternativă -Utilizează pagini &mari de memorie -2900 -Despre 7-Zip -7-Zip este un program gratuit. Oricum, poţi contribui la dezvoltarea 7-Zip înregistrându-te. -3000 -Sistemul nu poate aloca memoria necesară -Nu sunt erori -{0} obiect(e) selectat(e) -Nu pot crea directorul '{0}' -Operaţiile de actualizare nu sunt suportate pentru această arhivă. -Nu pot deschide fişierul '{0}' ca arhivă -Nu pot deschide arhiva criptată '{0}'. Parola greşită? -Tip de arhivă nesuportat -Fișierul {0} există deja -Fişierul '{0}' a fost modificat.\nDoreşti să îl actualizez în arhivă? -Nu pot actualiza fişierul\n'{0}' -Nu pot porni editorul. -The file looks like a virus (the file name contains long spaces in name). -Operația nu poate fi apelată dintr-un director cu cale lungă. -Trebuie să alegi un fișier -Trebuie să alegi unul sau mai multe fișiere -Prea multe obiecte -3300 -Dezarhivez -Arhivare -Testez -Deschid... -Citesc... -3400 -Dezarhivează -Dezarhivează în: -Specifică o destinaţie pentru fişierele dezarhivate. -3410 -Modul destinaţie -Numele întreg al destinaţiei -Fără locaţie -3420 -Modul de înlocuire -Întreabă înainte de a înlocui -Înlocuieşte fară a întreba -Sări peste fişierele existente -Auto redenumire -Auto redenumeşte fişierele existente -3500 -Aprobă înlocuirea fişierului -Fişierul există deja în directorul destinaţie. -Doriţi să înlocuiţi fişierul existent -cu acesta? -{0} octeţi -A&uto redenumire -3700 -Metodă de arhivare nesuportată pentru '{0}'. -Eroare de date la '{0}'. Fişierul este corupt. -Verificarea CRC a eşuat pentru '{0}'. Fişierul este corupt. -Erori de date la fişierul criptat '{0}'. Parolă greşită? -Verificarea CRC a eşuat pentru fişierul criptat '{0}'. Parolă greşită? -3800 -Introdu parola -Introdu parola: -Reintrodu parola: -&Arată parola -Parolele nu sunt identice -Utilizaţi numai litere, cifre şi caracterele speciale (!, #, $, ...) pentru parolă -Parola este prea lungă -Parola -3900 -Timp trecut: -Timp rămas: -Mărimea: -Viteza: -Procesat: -Rata de comprimare: -Erori: -Arhive: -4000 -Adaugă într-o arhivă -&Arhivează: -Modul de a&ctualizare: -&Formatul arhivei: -&Nivel de arhivare: -&Metoda de arhivare: -Mărimea &dicţionarului: -Mărimea &cuvântului: -Mărimea blocului solid: -Numărul de procesoare utilizate: -&Parametri: -Opţiuni -Crează arhivă SF&X -Arhivează fişierele partajate -Criptare -Metoda de criptare: -Criptează &numele fişierului -Memorie utilizată pentru arhivare: -Memorie utilizată pentru dezarhivare: -4050 -Stochează -Imediată -Rapidă -Normală -Maximă -Ultra -4060 -Adaugă şi înlocuieşte fişierele -Actualizează şi adaugă fişierele -Actualizează fişierele existente -Sincronizează fişierele -4070 -Caută -Toate fişierele -NEsolid -Solid -6000 -Copiază -Mută -Copiază la: -Mută la: -Copiez... -Mut... -Redenumesc... -Alege directorul destinaţie. -Operaţia nu este suportată. -Eroare la redenumirea fişierului sau directorului -Aprobă copierea fişierului -Eşti sigur că vrei să copiezi fişierele în arhivă -6100 -Aprobă ştergerea fişierului -Aprobă ştergerea directorului -Aprobă ştergerea mai multor fişiere -Eşti sigur că vrei să ştergi '{0}'? -Eşti sigur că vrei să ştergi directorul '{0}' şi tot conţinutul lui? -Eşti sigur că vrei să ştergi aceste {0} obiecte? -Şterg... -Eroare la ştergerea fişierului sau directorului -Sistemul nu poate muta un fişier cu cale lungă la Coşul de gunoi -6300 -Crează director -Crează fişier -Numele directorului: -Numele fişierului: -Director nou -Fişier nou -Eroare la crearea directorului -Eroare la crearea fişierului -6400 -Comentariu -&Comentariu: -Selectează -Deselectează -Masca: -6600 -Proprietăţi -Istoria directoarelor -Mesaje de diagnosticare -Mesaj -7100 -Computer -Reţea -Documente -Sistem -7200 -Arhivează -Dezarhivează -Testează -Copiază -Mută -Şterge -Info -7300 -Împarte fişierul -Î&mparte în: -Împarte în &volume, octeţi: -Împart... -Confirmă împărţirea -Eşti sigur că vrei să imparţi arhiva în {0} volume (părţi)? -Dimensiunea volumului trebuie să fie mai mică decât dimensiunea fişierului original -Dimensiunea volumului este incorectă -Dimensiunea volumului specificat: {0} octeţi.\nEşti sigur că vrei să împarţi arhiva în mai multe volume (părţi)? -7400 -Uneşte fişierele -&Uneşte în: -Unesc... -Alege doar prima parte din fişierul împărțit -Nu pot detecta fișierul ca parte a fișierului împărțit -Nu găsesc mai mult de o parte din fișierul împărțit -7500 -Calculez suma de control... -Informaţii despre suma de control -Suma de control CRC pentru conţinut: -Suma de control CRC pentru conţinut şi nume: -7600 -Banc de încercare -Memorie utilizată: -Arhivez -Dezarhivez -Rata -Rata totală -Actual -Rezultate -Utilizarea procesorului -Rata / Utilizare -Trecute: diff -Nru p7zip-rar-16.02/GUI/Lang/ru.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ru.txt --- p7zip-rar-16.02/GUI/Lang/ru.txt 2015-11-06 16:39:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ru.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.10 : 2015-10-31 : Igor Pavlov -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Russian -Русский -401 -OK -Отмена - - - -&Да -&Нет -&Закрыть -Помощь - -&Продолжить -440 -Да для &всех -Нет для в&сех -Стоп -Перезапуск -&Фоном -&На передний план -&Пауза -На паузе -Вы действительно хотите прервать операцию? -500 -&Файл -&Правка -&Вид -&Избранное -С&ервис -&Справка -540 -&Открыть -Открыть &внутри -Открыть снару&жи -Просмотр -&Редактировать -Переи&меновать -&Копировать в... -&Переместить в... -&Удалить -Ра&збить файл... -О&бъединить файлы... -Сво&йства -Комме&нтарий... -Контрольная сумма -Сравнить -&Создать Папку -Созд&ать Файл -В&ыход -Ссылка -&Альтернативные Потоки -600 -Выделить в&се -Убрать выделение -&Обратить в&ыделение -Выделить... -Убрать выделение... -Выделить по типу -Убрать выделение по типу -700 -&Крупные значки -&Мелкие значки -Спис&ок -&Таблица -730 -Без сортировки -Плоский режим -&2 Панели -&Панели инструментов -Открыть корневую папку -Переход на один уровень вверх -История папок... -О&бновить -Автообновление -750 -Панель кнопок архиватора -Стандартная панель кнопок -Большие кнопки -Надписи на кнопках -800 -Добавить папку в &избранное как -Закладка -900 -Настройки... -Тестирование производительности -960 -&Оглавление... -О &программе... -1003 -Путь -Имя -Расширение -Папка -Размер -Сжатый -Атрибуты -Создан -Открыт -Изменен -Непрерывный -Комментарий -Зашифрован -Разбит До -Разбит После -Словарь - -Тип -Анти -Метод -Система -Файловая Система -Пользователь -Группа -Блок -Комментарий -Позиция -Путь -Папок -Файлов -Версия -Том -Многотомный -Смещение -Ссылок -Блоков -Томов - - - -Процессор -Физический Размер -Размер Заголовков -Контрольная Сумма -Характеристики -Виртуальный Адрес - -Короткое Имя -Создатель -Размер Сектора -Режим -Символьная Ссылка -Ошибка -Емкость -Свободно -Размер кластера -Метка -Локальное имя -Провайдер -NT Безопасность -Альтернативный Поток - -Удаленный -Дерево - - -Тип Ошибки -Ошибки -Ошибки -Предупреждения -Предупреждение -Потоки -Альтернативные Потоки -Размер Альтернативных потоков -Виртуальный Размер -Распакованный Размер -Общий Физический Размер -Номер Тома -Подтип -Короткий Комментарий -Кодовая Страница - - - -Размер Остатка -Размер Встроенного Блока -Ссылка -Жесткая Ссылка -iNode - -Только для чтения -2100 -Настройки -Язык -Язык: -Редактор -&Редактор: -&Программа сравнения: -2200 -Система -Ассоциировать 7-Zip с файлами: -Все пользователи -2301 -Встроить 7-Zip в контекстное меню оболочки -Каскадное контекстное меню -Элементы контекстного меню: -Иконки в контекстном меню -2320 -<Папка> -<Архив> -Открыть архив -Распаковать -Добавить к архиву... -Тестировать -Распаковать здесь -Распаковать в {0} -Добавить к {0} -Сжать и отправить по email... -Сжать в {0} и отправить по email -2400 -Папки -&Рабочая папка -&Системная временная папка -&Текущая -&Задать: -Использовать только для сменных носителей -Укажите положение для временных архивов. -2500 -Настройки -Показывать элемент ".." -Показывать реальные иконки файлов -Показывать системное меню -Курсор на всю строку -Показывать разделители -Открывать одним щелчком -Альтернативный режим пометки -Использовать большие страницы памяти -2900 -О программе 7-Zip -7-Zip является свободно распространяемой программой. -3000 -Недостаточно свободной памяти -Ошибок не найдено -Выделено объектов: {0} -Не удалось создать папку '{0}' -Операции изменения не поддерживаются для этого архива. -Не удалось открыть файл '{0}' как архив -Не удалось открыть зашифрованный архив '{0}'. Неверный пароль? -Неподдерживаемый тип архива -Файл {0} уже существует -Файл '{0}' был изменен.\nВы хотите обновить его в архиве? -Не удалось обновить файл\n'{0}' -Не удалось запустить редактор -Файл похож на вирус (имя файла содержит длинную последовательность пробелов). -Операция не может быть исполнена из папки, которая имеет длинный путь. -Вы должны выделить один файл -Вы должны выделить один или несколько файлов -Слишком много элементов -Не удалось открыть файл как {0} архив -Файл открыт как {0} архив -Архив открыт со смещением -3300 -Распаковка -Упаковка -Тестирование -Открытие... -Сканирование... -Удаление -3320 -Добавление -Обновление -Анализ -Копирование -Перепаковка -Пропуск -Удаление -Создание заголовков -3400 -Извлечь -&Распаковать в: -Укажите положение для извлекаемых файлов. -3410 -Пути к файлам: -Полные пути -Без путей -Абсолютные пути -Относительные пути -3420 -Перезапись: -С подтверждением -Без подтверждения -Пропускать -Переименовать автоматически -Переименовать существующие -3430 -Устранить дублирование корневой папки -Устанавливать права доступа -3500 -Подтверждение замены файла -Папка уже содержит обрабатываемый файл. -Заменить существующий файл -следующим файлом? -{0} байтов -Переименовать автом. -3700 -Неподдерживаемый метод сжатия для файла '{0}'. -Ошибка в данных в '{0}'. Файл испорчен. -Ошибка CRC в '{0}'. Файл испорчен. -Ошибка в данных зашифрованного файла '{0}'. Неверный пароль? -Ошибка CRC для зашифрованного файла '{0}'. Неверный пароль? -3710 -Неверный пароль? -3721 -Неподдерживаемый метод сжатия -Ошибка в данных -Ошибка CRC -Недоступные данные -Неожиданный конец данных -Есть данные после конца блока полезных данных -Не является архивом -Ошибка в заголовках -Неверный пароль -3763 -Недоступно начало архива -Неподтвержденное начало архива - - - -Неподдерживаемая функциональность -3800 -Ввод пароля -&Введите пароль: -Повторите пароль: -&Показать пароль -Пароли не совпадают -Для пароля используйте только символы латинского алфавита, цифры и специальные символы (!, #, $, ...) -Пароль слишком длинный -&Пароль -3900 -Прошло: -Осталось: -Всего: -Скорость: -Размер: -Степень сжатия: -Ошибок: -Архивов: -4000 -Добавить к архиву -&Архив: -&Режим изменения: -&Формат архива: -&Уровень сжатия: -&Метод сжатия: -Размер &словаря: -Размер с&лова: -Размер блока: -Число потоков: -&Параметры: -&Опции -Создать SF&X-архив -Сжимать открытые для записи файлы -Шифрование -Метод шифрования: -&Шифровать имена файлов -Объем памяти для упаковки: -Объем памяти для распаковки: -Удалять файлы после сжатия -4040 -Сохранять символьные ссылки -Сохранять жесткие ссылки -Сохранять альтернативные потоки -Сохранять права доступа -4050 -Без сжатия -Скоростной -Быстрый -Нормальный -Максимальный -Ультра -4060 -Добавить и заменить -Обновить и добавить -Обновить -Синхронизировать -4070 -Пролистать -Все файлы -По размеру файла -Непрерывный -6000 -Копировать -Переместить -Копировать в: -Переместить в: -Копирование... -Перемещение... -Переименование... -Укажите папку. -Операция не поддерживается для этой папки. -Ошибка при переименовании файла или папки -Подтверждение копирования файлов -Вы действительно хотите скопировать эти файлы в архив -6100 -Подтверждение удаления файла -Подтверждение удаления папки -Подтверждение удаления группы файлов -Вы действительно хотите удалить "{0}"? -Вы действительно хотите удалить папку "{0}" и все ее содержимое? -Вы действительно хотите удалить эти объекты ({0} шт.)? -Удаление... -Ошибка при удалении файла или папки -Система не поддерживает операцию удаления файлов с длинными путями в корзину -6300 -Создать папку -Создать файл -Имя папки: -Имя файла: -Новая папка -Новый файл -Ошибка при создании папки -Ошибка при создании файла -6400 -Комментарий -&Комментарий: -Выделить -Убрать выделение -Маска: -6600 -Свойства -История папок -Сообщения -Сообщение -7100 -Компьютер -Сеть -Документы -Система -7200 -Добавить -Извлечь -Тестировать -Копировать -Переместить -Удалить -Информация -7300 -Разбить файл -&Разбить в: -Разбить на &тома размером (в байтах): -Разбиение... -Подтверждение разбиения -Вы действительно хотите разбить файл на {0} частей? -Размер тома должен быть меньше размера исходного файла -Ошибка в поле для задания размера томов -Установленный размер тома: {0} байтов.\nВы действительно хотите разбить архив на такие тома? -7400 -Объединить файлы -&Объединить в: -Объединение... -Необходимо выделить только первую часть разбитого файла -Не удалось распознать разбитый файл -Не удалось найти более одной части разбитого файла -7500 -Вычисление контрольной суммы... -Контрольная сумма -Контрольная сумма CRC для данных: -Контрольная сумма CRC для данных и имен: -7600 -Тестирование производительности -Объем памяти: -Упаковка -Распаковка -Рейтинг -Общий рейтинг -Текущий -Итоговый -Нагрузка -Рейтинг / Нагр. -Проходов: -7700 -Ссылка -Связать -Источник: -Цель: -7710 -Тип ссылки -Жесткая ссылка -Символьная ссылка (Файл) -Символьная ссылка (Папка) -Точка соединения (Junction) diff -Nru p7zip-rar-16.02/GUI/Lang/sa.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sa.txt --- p7zip-rar-16.02/GUI/Lang/sa.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sa.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Vinayy Sharrma, अनुवादं विनय शर्मा संस्कृतम् गर्व कुरु, जय हिन्दं ! जय संस्कृतम्! एतत् साधारण अनुवादं अस्ति -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Sanskrit, Indian, हिन्दुस्तानं -संस्कृत -401 -ठीक अस्ति -रद्द - - - -&हाँ -&ना -&बंद कुरु -मददं - -&जारी रखे -440 -&सर्वस्य हाँ -&सर्वस्य ना -रूको -पुनः शुरु कुरु -&पॄष्ठ्भूमि -&अग्रभूमि(डेस्क्टोप) -&विश्राम -विश्रामितं -त्वम रद्द करना चाहते हो. तुम्हें यकीन अस्ति क्या? -500 -&फ़ाइलम् -&संपादनम् -&दर्शनम् -&मनपसंदम् -&औजारम् -&मददम् -540 -&अनावृतं -&अंदर अनावृतं -&बहिः अनावृतं -&दृश्यम् -&संपादनम् -&पुन: नामकरणम् -&में नकल बनाये... -&में ले जायें... -&मिटायें -&फ़ाइलस्य विभाजनं कुरु... -&फ़ाइलस्य संयोजनं कुरु... -&संपत्तियाँ वा गुणं -&टिप्पणी -&जाँच योगस्य गणनां कुरु -&अन्तर -&फोल्डरं निर्माणम् कुरु -&फ़ाइलं निर्माणम् कुरु -&निर्गमन -600 -&सर्व चयनं कुरु -&सर्व अचयनितं कुरु -&चयन उलटा कुरु -चयनं कुरु... -अचयनं कुरु... -प्रकार द्वारा चयनम् -प्रकार द्वारा अचयनम् -700 -विशाल प्रतीकं -लघु प्रतीकं -&सूची -&वर्णनं -730 -अवितरितम् -चौड़ा दृश्य -&२ फ़लक -&औजार पट्टीयाँ -मूल फोल्डरं अनावृतं -एक स्तर उर्ध्व चढ़े -फ़ोल्डरो का इतिहास... -&ताजा कुरु -750 -संग्रहम् उपकरणपट्टी -मानक औजार पट्टी -विशाल खटके(बटन) -खटके(बटन) के शब्द दिखायें -800 -&फोल्डरं मनपसंद में ऎसे जोड़े... -पुस्तचिन्हम् -900 -&विकल्पम्... -&बेञ्चमार्कम्(प्रामाणिक तुलना) -960 -&सामग्री... -7-जिप विषय... -1003 -मार्ग -नाम -विस्तारं -फोल्डरं -आकारं -कुल आकारं -विशेषता वा गुणधर्म -सर्जितं -चालितम् -परिवर्धितं -ठोस -टिप्पणी -गुप्तिकृतम् -के पूर्व विभाजनं(टुकडे) कुरु -के पश्चात विभाजनं(टुकडे) कुरु -शब्दकोशं -सीआरसी -प्रकारं -विरोधी -पद्धति -ओपरेटिंग सिस्टम -फ़ाइलं प्रणाली -प्रयोगकर्ता -समूहम् -रोक वा टुकड़े -प्रतिक्रिया -स्थानं -मार्ग प्रत्ययं -फोल्डर्स -फाइल्स -संस्करणम् -जत्था -अनेक जत्थे -ओफसेट -कडियाँ -टुकड़े -जत्थे - -64-बिट -विशाल-एन्डियन -सीपीयू -भौतिक आकारं -शीर्षकाः आकारं -जाँचयोग -चरित्रताऎं -आभासी पता -आईडी -संक्षिप्तः नामं -सर्जक अनुप्रयोगं -सेक्टरस्य आकारं -स्थिति -कड़ी -त्रुटि -कुल आकारं -स्वतन्त्र रिक्तस्थानं(खाली जगह) -क्लस्टर(समूह) आकारं -ध्यानाकर्षकं(लेबलम्) -स्थानिय नामम् -प्रदायकम् -2100 -विकल्पम् -भाषा -भाषा: -संपादकम् -&संपादक: -&अन्तर: -2200 -प्रणाली वा तंत्रम् -संबधित कुरु 7-जिप के साथ: -2301 -7-जिपस्य शेल(कवच) प्रसंग मेनु में जोडें -सोपानीकृत(केस्केडेड) प्रसंग मेनु -प्रसंग(कोन्टेक्स्ट) मेनु वस्तुएँ: -2320 -<फोल्डरं> -<संग्रहम्(आर्चिव)> -संग्रहम् अनावृतं -फ़ाइल्स बहिः निकाले... -संग्रहम् में जोड़े... -संग्रहमस्य जाँच कुरु -यहीं बहिः निकाले -{0} में बहिः निकाले -{0} में जोड़े -संकुचनं एवम् ईमेलम् कुरु... -{0} में दबायें एवम् ईमेलं कुरु -2400 -फ़ोल्डर्स -&कार्यरत फोल्डरं -&प्रणालयास्य अस्थायी(टेम्पररी) फोल्डरं -&चालू -&निर्दिष्ट: -मात्र हटाने योग्य(रिमूवेबल) ड्राईवाय ही प्रयोगं कुरु -अस्थायी संग्रहम् फाइलाय स्थानं निर्दिष्टं कुरु(बतायें). -2500 -व्यवस्थाएँ -दिखाओ ".."वस्तु -वास्तविक फ़ाइल प्रतिमायें दिखाओ -तंत्रस्य मेनु दिखाओ -&पूर्ण पन्क्तिस्य चयनं -&ग्रिड(जाल) रेखा दिखाओ -वस्तु अनावृताय एकं ही(सिंगल)-क्लिकम् -&वैकल्पिक चयनं स्थिति -&विशाल् स्मृति पृष्ठस्य प्रयोगं कुरु -2900 -7-जिप विषय -7-जिपं एतत निःशुल्क सॉफ़्टवेयर अस्ति. तथापि, भवान् पंजीकृतं(रजिस्टर्ड) होकर७-ज़िपस्य विकास में सहयोग कर सकते अस्ति. -3000 -तंत्रम् आवश्यक मात्रा में मेमोरी(स्मृति) वितरितं ना कर सकता अस्ति -इनमे कोई भी त्रुटि ना अस्ति -{0} चयनित वस्तु(एँ) -'{0}' फोल्डरं सर्जित ना कर सकता -एतत् संग्रहमस्य अद्यतनीकृत संचालन समर्थित ना अस्ति. -'{0}' फाइल को संग्रहम् के रूप में ना खोल सकता -'{0}' गुप्तिकृतम् संग्रहम् को ना खोल सकता. मिथ्या कूटशब्दम्? -असमर्थित संग्रहम् प्रकारं -फाइलं {0} पहले से मौजूद अस्ति -'{0}' फ़ाइल परिवर्धितं हुई अस्ति.\nक्या तुम संग्रहम् में इसे अद्यतनीकृतं करना चाहते हो? -फ़ाइल को अद्यतनीकृतं ना कर सकता\n'{0}' -संपादक को शुरू ना कर सकता. -यह फाइलं एक विषाणु(वायरस) जैसी लगती अस्ति(फाइलं नाम लंबी खाली जगह नाम में रखता अस्ति). -जिस फोल्डरं का लंबा मार्ग अस्ति उससे सञ्चालनं क्रिया ना बुलाई जा सकती. -तुम्हे एक फाइलं का चयन तो करना ही होगा -तुम्हे एक वा अधिक फाइलों को चुनना ही होगा -अत्यधिक वस्तुएँ -3300 -बहिः निकाल रहा अस्ति -संकुचनं कर रहा अस्ति -परीक्षणम् -अनावृतं कर रहा अस्ति... -तलाशी(स्कैनिंग) कर रहा अस्ति... -3400 -बहिः निकाले -&बहिः निकाले: -बहिः निकाली हुई फ़ाइलों के लिये स्थानं निर्दिष्टं कुरु. -3410 -मार्ग स्थिति -पूर्ण मार्गनामं -कोई मार्ग नामं ना अस्ति -3420 -अधिलेखन रीत -अधिलेखन करने से पहले पृच्छाः -बिना पृच्छाः अधिलेखनं(पुराने को मिटाना) कुरु -पहले से मौजूद फ़ाइलस को छोड़े -स्वचालित पुन: नामकरणं -पहले से मौजूद फ़ाइलस का स्वचालितं(ओटोमेटिक) पुन: नामकरणं कुरु -3500 -फ़ाइलं प्रतिस्थापनं को पक्का कुरु -गन्तव्य फोल्डरं में पहले से ही प्रक्रिया हुई फ़ाइलं अस्ति. -क्या भवान् पहले से मौजूद फ़ाइल को बदलना पसंद करेंगे? -इसके साथ? -{0} बाइट्स -स्वचालित पुन: नामकरणम् -3700 -'{0}' के लिए असहायक दबाने की पद्धति. -डेटा त्रुटि'{0}' में. फ़ाइलं टूटी हुई अस्ति. -'{0}' में सीआरसी असफल. फ़ाइलं टूटी हुई अस्ति. -'{0}' गुप्तिकृतम्(एनक्रिप्टेड) फाइलं में डेटा त्रुटि. मिथ्या कूटशब्दम्? -'{0}'गुप्तिकृतम्(एनक्रिप्टेड) फाइलं में सीआरसी असफल. मिथ्या कूटशब्दम्? -3800 -कूटशब्दम्(पासवर्ड) डाले -कूटशब्दम्(पासवर्ड) डाले: -कूटशब्दम् पुनः डाले: -&कूटशब्दम्(पासवर्ड) दिखाओ -कूटशब्दम् सहेजे हुए से अलग अस्ति -कूटशब्दम् के लिये मात्र इंग्लिश वर्णमाला, अंकाः और विशेष अक्षरों (!, #, $, ...) का ही उपयोग कुरु -कूटशब्दम् अत्यधिक विशाल अस्ति -कूटशब्दम्(पासवर्ड) -3900 -व्यतीत समय: -शेष बचा समय: -कुल आकारं: -गति: -प्रक्रिया किया हुआ: -दबाने(आकारं छोटा करने) का अनुपातं: -त्रुटियाँ: -संग्रहम्: -4000 -संग्रहम् में जोड़े -&संग्रहम्: -&अद्यतनीकरणं स्थिति(मोड): -संग्रहम् &ढाँचा: -&संकुचनम् स्तर: -&संकुचनम् विधि: -&शब्दकोशम् आकारं: -&शब्द आकारं: -ठोस टुकडे का आकारं: -सीपीयू सूत्र संख्या: -&परिमाप: -विकल्प -&एसएफ़एक्स(SFX) संग्रहम् निर्माणम् कुरु -साझी फाइलें संकुचितं कुरु -गुप्तिकरणम् -गुप्तिकरणम् पद्धति: -फ़ाइल &नाम गुप्तिकरणम् कुरु -संकुचनस्य स्मृति प्रयोग: -प्रसारणस्य स्मृति प्रयोग: -4050 -भण्डारणम् -सर्वाधिक तेज -तेज -साधारणम् -अधिकतम -अत्यन्त -4060 -फ़ाइलें जोड़े एवम् प्रतिस्थापित कुरु -फ़ाइले अद्यतनीकृतं कुरु एवम् जोड़े -अवस्थितं फ़ाइलें ताजा कुरु -फाइलें समक्रमण(सिंक्रोनाईज़) कुरु -4070 -ब्राउजम् वा घूमे -सर्वाः फ़ाइलें -अ-ठोसं -ठोसं -6000 -नकल -ले जायें -में नकल: -में ले जायें: -नकल... -ले जा रहा अस्ति... -पुन: नामकरणं... -गन्तव्य फोल्डरं चयनित कुरु. -एतत् फोल्डरं के लिये यह सञ्चालनं क्रिया समर्थितं ना अस्ति. -फ़ाइल वा फोल्डरं के पुन: नामकरणं में त्रुटि -फ़ाइल की नकल करना पक्का कुरु -तुम संग्रहम् में फाइलं की प्रतिलिपि करना चाहते हो क्या तुम्हे यकीन अस्ति -6100 -फ़ाइल मिटाये यह पक्का कुरु -फोल्डरं मिटायें पक्का कुरु -अनेक फ़ाइल मिटायें पक्का कुरु -क्या तुम्हे यकीन अस्ति कि तुम मिटाना चाहते हो '{0}'? -क्या तुम्हे यकीन अस्ति कि तुम फोल्डरं मिटाना चाहते हो '{0}' और इसकी सर्वाः सामग्री भी? -क्या तुम्हे यकीन अस्ति कि तुम मिटाना चाहते हो इन {0} वस्तुओं को? -मिटा रहा अस्ति... -फ़ाइलं किंवा फोल्डरं मिटाने में त्रुटि -तंत्र लंबे मार्ग वाली फाइलं को पुनःचक्रण पेटी(रिसाईकल बिन) में ना ले जा सकता अस्ति. -6300 -फ़ॊल्डर निर्माणम् कुरु -फ़ाइल निर्माणम् कुरु -फोल्डरं नाम: -फ़ाइल नाम: -नवीन फ़ॊल्डर -नवीन फ़ाइलं -फोल्डरं निर्माणम् करने में त्रुटि -फ़ाइल निर्माणम् करने में त्रुटि -6400 -टिप्पणी -&टिप्पणी: -चयनम् -चयन रद्द -मुखौटा: -6600 -गुणम् वा संपत्तियाँ -फ़ोल्डरों का इतिहास -निदानात्मकं संदेश -संदेशं -7100 -संगणकम् -सञ्जालम् -दस्तावेजम् -प्रणाली -7200 -जोड़े -बहिः निकाले -परीक्षणम् -नकल -ले जायें -मिटायें -सूचना -7300 -फ़ाइलस्य विभाजनं कुरु -&में विभाजनं: -जत्थों में विभाजनं, बाइट्स: -विभाजनं कर रहा अस्ति... -विभाजनं करना पक्का कुरु -क्या तुम्हे यकीन अस्ति कि तुम फाइलं को {0} जत्थों में विभाजित करना चाहते हो? -मूल फाइलं के आकारं की तुलना में जत्थे का आकारं छोटा ही होना चाहिए -जत्थे का आकारं मिथ्या अस्ति -निर्देशित जत्था आकारं: {0} बाइटस.\n भवान् संग्रहम् को ऎसे जत्थों में विभाजितं करना चाहते अस्ति, क्या आपको यकीन अस्ति? -7400 -फ़ाइले संयोजितं कुरु -&में संयोजनं कुरु: -संयोजनं हो रहा अस्ति... -विभाजितं फाइल का मात्र प्रथम भागं ही चयनितं कुरु -फाइलं को विभाजित फाइलं के भाग के रूप में पहचान ना सकता -विभाजित फाइलं का एक से ज्यादा भाग ना ढूँढ सकता -7500 -जाँचयोगस्य(चेकसम) गणनां कर रहा अस्ति... -जाँचयोग(चेकसम) माहिती -सीआरसी जाँचयोग(चेकसम) आँकड़ों के लिये : -सीआरसी जाँचयोग(चेकसम) आँकड़ों और नामों के लिये : -7600 -(कसौटी चिन्हं)बेञ्चमार्कम् -स्मृति उपयोग: -संकुचनं कर रहा अस्ति -प्रसारणं हो रहा अस्ति -क्रमांकन -कुल क्रमांकन -वर्तमानम् -परिणामम् -सीपीयू उपयोग -क्रमांकन / उपयोग -पास: diff -Nru p7zip-rar-16.02/GUI/Lang/si.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/si.txt --- p7zip-rar-16.02/GUI/Lang/si.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/si.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.59 : සුපුන් බුධාජීව (Supun Budhajeewa) -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Sinhala -සිංහල -401 -හරි -එපා - - - -ඔවු (&Y) -නැහැ (&N) -වසන්න (&C) -උදව් - -නැවත අරඹන්න (&C) -440 -සියල්ලටම ඔවු (&A) -සියල්ලටම නැහැ(&L) -නවතන්න -ප්‍රත්‍යාරම්භ කරන්න -පසුබිමින් (&B) -පෙරබිමින් (&F) -මදකට නවතන්න (&P) -මදකට නවතා ඇත -ඉවත්වීමට අවශ්‍ය බව විශ්වාස ද ? -500 -ගොනුව (&F) -සැකසුම් (&E) -දසුන (&V) -කැමතිම (&A) -මෙවලම් (&T) -උදව් (&H) -540 -විවෘත කරන්න (&O) -මෙහිම විවෘත කරන්න (&I) -පිටතින් විවෘත කරන්න (&U) -දසුන (&V) -සංස්කරණය කරන්න (&E) -නැවත නම් කරන්න (&M) -වෙනත් තැනකට පිටපත් කරන්න (&C)... -වෙනත් තැනකට ගෙනය‍න්න (&M)... -මකන්න (&D) -ගොනුව බෙදන්න (&S)... -ගොනු එකතු කරන්න (&B)... -වත්කම් (&R) -ටීකා (&N) -checksum ගණනය කරන්න - -බහාලුමක් තනන්න -ගොනුවක් තනන්න -ඉවත් වන්න (&X) -600 -සියල්ල තෝරන්න (&A) -තෝරන ලද සියල්ල ඉන් ඉවත් කරන්න -අනෙක් පැත්තට තෝරන්න (&I) -තෝරන්න... -තේරීම ඉවත් කරන්න... -වර්ගයෙන් තෝරන්න -වර්ගයෙන් තේරීම ඉවත් කරන්න -700 -විශාල මූර්ති (&G) -කුඩා මූර්ති (&M) -ලයිස්තුව (&L) -සවිස්තර (&D) -730 -අසුරන නොලද -පැතලි දසුන -පැනල &2 -මෙවලම් තීරු (&T) -ප්‍රධාන බහාලුම විවෘත කරන්න -ඉහළට එක් ස්ථරයක් -බහාලුම් අතීතය... -ප්‍රතිපූරණය කරන්න(&R) -750 -හැකිළුම් මෙවලම් තීරුව -සම්මත මෙවලම් තීරුව -විශාල බොත්තම් -බොත්තම් පෙළ දක්වන්න -800 -බහාලුම කැමතිම අංග වලට එකතු කරන අයුර (&A) -පොත් සලකුණ - අංක -900 -විකල්ප (&O)... -&Benchmark -960 -අන්තර්ගතය (&C)... -7-Zip පිළිබඳව (&A)... -1003 -මංපෙත -නම -දිගුව -බහාලුම -විශාලත්වය -හැකිළුමෙන් පසු විශාලත්වය -ලක්ෂණ -නිර්මාණය කළ දිනය -ප්‍රවේශ වූ දිනය -අළුත් කළ දිනය -සවි -ටීකා කොට ඇත -සුරක්ෂිතය -Split Before -Split After -Dictionary -CRC -වර්ගය -Anti -ක්‍රමය -ධාරක මෙහෙයුම් පද්ධතිය -ගොනු පද්ධතිය -පරිශිලක -සමූහය -Block -ටීකාව -පිහිටීම -Path Prefix -බහාලුම් -ගොනු -සංස්කරණය -Volume -Multivolume -Offset -සබැඳීන් -Blocks -Volumes - -බිට්-64 -Big-endian -මධ්‍යම සැකසුම් පද්ධතිය (CPU) -භෞතික විශාලත්වය -ශීර්ෂ විශාලත්වය -Checksum -මුහුණුවර -Virtual Address - - - - - - -දෝෂයක් -සම්පූර්ණ විශාලත්වය -නිදහස් ඉඩ -Cluster විශාලත්වය -නම් පත -Local Name -සපයන්නා -2100 -විකල්ප -භාෂාව -භාෂාව: -සංස්කාරකය -සංස්කාරකය (&E): - -2200 -පද්ධතිය -7-Zip සමග හවුල් කරන්න: -2301 -Shell context මෙනුව වෙත 7-Zip අන්තර්ගත කරන්න -Context menu අංග එක් අංගයක් යටතේ සඳහන් කරන්න‍‍‍ -Context මෙනු අංග: -2320 -<බහාලුම> -<හැකිළුම> -හැකිළුම විවෘත කරන්න -ගොනු ලිහන්න... -හැකිළුමකට ඇතුල් කරන්න... -හැකිළුම පරීක්ෂා කරන්න -මෙතැනට ලිහන්න -{0} වෙත ලිහන්න -{0} වෙත එක් කරන්න -හකුළා විදුලි තැපැල් කරන්න... -{0} වෙත හකුළා විදුලි තැපැල් කරන්න -2400 -බහාලුම් -සක්‍රීය බහාලුම් (&W) -පද්ධති තාවකාලික දෑ (Temp) බහාලුම (&S) -වත්මන් (&C) -තෝරන්න (&S): -ඉවත් කළ හැකි ධාවක සඳහා පමණක් භාවිතා කරන්න -තාවකාලික හැකිළුම් ගොනු සඳහා ස්ථානයක් දෙන්න. -2500 -සෙටිංග්ස් -".." අංගය පෙන්වන්න -ගොනු වල සත්‍ය මූර්තිය පෙන්වන්න -පද්ධති මෙනුව පෙන්වන්න -සම්පූර්ණ තීරු තේරීම (&F) -වගු රේභා පෙන්වන්න (&G) - -වෛකල්පිත තේරීම් ස්වභාවය (&A) -විශාල මතක පිටු භාවිතා කරන්න (&L) -2900 -7-Zip පිළිබඳව -7-Zip නිදහස් මෘදුකාංගයක් වුවත්, ලියාපදිංචි වීම මගින් 7-Zip හි වැඩි දියුණුව සඳහා ඔබට දායක විය හැකිය.\n\nමෙම සිංහල භාෂා පරිවර්තනය G.S.N. සුපුන් බුධාජීව (budhajeewa@gmail.com) විසින් සිදු කරන ලදී. -3000 -අවශ්‍ය මතක ප්‍රමාණය පද්ධතියට වෙන් කර ගත නොහැක -දෝෂ නොමැත -වස්තු {0}ක් තෝරා ඇත -'{0}' බහාලුම තැනිය නොහැක -මෙම හැකිළුම සඳහා යාවත්කාල කිරීම් සහයෝගය නොදක්වයි. -'{0}' ගොනුව හැකිළුමක් ලෙස විවෘත කළ නොහැක -සුරක්ෂිත '{0}' හැකිළුම විවෘත කළ නොහැක. මුරපදය වැරදි ද ? -සහයෝගී නොවන හැකිළුම් ක්‍රමයක් -{0} ගොනුව දැනටමත් ඇත -'{0}' ගොනුව නව්‍ය කෙරිනි.\nහැකිළුමෙහි එය යාවත්කාල කිරීමට ඔබට අවශ්‍ය ද ? -ගොනුව යාවත්කාල කල නොහැක\n'{0}' -සංස්කාරකය විවෘත කළ නොහැක. -ගොනුව වෛරසයක් වැනිය (ගොනු නාමයේ දිගු හිස් තැන් ඇත). -දිගු මංපෙතක් ඇති බහාලුමකින් ක්‍රියාකාරීත්වය කැඳවිය නොහැක. -එක් ගොනුවක් පමණක් තේරිය යුතුය. -ගොනු එකක් හෝ වැඩි ගණනක් තේරිය යුතුය. -අංග ඉතා අධිකය -3300 -ලිහමින් පවතී‍ -හකුළමින් පවතී -පරීක්ෂා කිරීම -විවෘත කරමින් පවතී... -සුපිරික්සමින් පවතී... -3400 -ලිහන්න -ලිහීමට තැනක් (&X) : -ලිහන ලද ගොනු සඳහා ස්ථානයක් තෝරන්න. -3410 -මංපෙත් ස්වභාවය -සම්පූර්ණ මංපෙත් නම් -මංපෙත් නම් අවශ්‍ය නැත -3420 -උඩින් ලිවීමේ ස්වභාවය -උඩින් ලියන්නට පෙර විමසන්න -විමසීමෙන් තොරව උඩින් ලියන්න -දැනටමත් ඇති ගොනු මගහරින්න -ගොනු ස්වයංක්‍රියව ප්‍රතිනම් කරන්න -දැනටමත් ඇති ගොනු‍ ප්‍රතිනම් කරන්න -3500 -ගොනු ප්‍රතිස්ථාපනය තහවුරු කර ගැනීම -ගමනාන්ත බහාලුමේ දැනටමත් නිර්මිත ගොනුවක් ඇත. -දැනටම පවතින පහත ගොනුව, -මෙය සමග ප්‍රතිස්ථාපනය කරන්න ද ? -{0} බයිට (Bytes) -ස්වයංක්‍රියව ප්‍රතිනම් කරන්න (&U) -3700 -'{0}' සඳහා සහයෝගය නොදක්වන හැකිළුම් ක්‍රමයක්. -'{0}' හි දත්ත දෝෂයකි. ගොනුව බිඳී ඇත. -'{0}' හි CRC අසමත් විනි. ගොනුව බිඳී ඇත. -සුරක්ෂිත '{0}' ගොනුවේ දත්ත දෝෂයකි. වැරදි මුරපදයක් ද ? -සුරක්ෂිත '{0}' ගොනුවේ CRC අසමත් විනි. වැරදි මුරපදයක් ද ? -3800 -මුරපදය ඇතුල් කරන්න -මුරපදය ඇතුල් කරන්න: -මුරපදය නැවත ඇතුල් කරන්න: -මුරපදය පෙන්වන්න (&S) -මුරපද නොගැලපේ -මුරපද සඳහා ඉංග්‍රිසි අකුරු, ඉලක්කම් සහ විශේෂිත සංකේත පමණක් භාවිතා කරන්න (!, #, $, ...) -මුරපදය දිග වැඩිය -මුරපදය -3900 -ගතවූ කාලය: -ඉතිරි කාලය: -සම්පූර්ණ විශාලත්වය: -වේගය: -ක්‍රියාවලියට භාජනය වූ ප්‍රමාණය: -හැකිළුම් අනුපාතය: -දෝෂ: -හැකිළුම්: -4000 -හැකිළුමකට එක් කරන්න -හැකිළුම (&A): -යාවත්කාල කිරීමේ ස්වභාවය (&U): -හැකිළුම් රටාව (&F): -හැකිළුම් මට්ටම (&L): -හැකිළුම් ක්‍රමය (&M): -&Dictionary size: -&Word size: -Solid block size: -Number of CPU threads: -පරාමිති (&P): -විකල්ප -SF&X හැකිළුමක් තනන්න -හවුල්කාර ගොනු ද හකුළන්න -සුරැකුම් -සුරැකුම් ක්‍රමය: -ගොනු නාම සුරකින්න (&S) -හැකිලීම සඳහා මතක භාවිතය: -ලිහීම ක්‍රියාව සඳහා මතක භාවිතය: -4050 -තැන්පත් කරන්න -ඉතා වේගවත් -වේගවත් -සාමාන්‍ය -උපරිම -අධි හැකිළුම්‍ -4060 -ගොනු එක් කර ප්‍රතිස්ථාපනය කරන්න -ගොනු යාවත්කාල කර එක් කරන්න -දැනටමත් ඇති ගොනු නැවුම් කරන්න -ගොනු සමකාලී කරන්න -4070 -සොයන්න -සියළු ගොනු -සවි-නොමැති -සවි -6000 -පිටපත් කරන්න -ගෙනයන්න -වෙනත් තැනකට පිටපත් කරන්න: -වෙනත් තැනකට ගෙනයන්න: -පිටපත් කරමින් පවතී... -ගෙනයමින් පවතී... -ප්‍රතිනම් කරමින් පවතී... -ගමනාන්ත බහාලුම තෝරන්න. -ක්‍රියාව කල නොහැක. -ගොනුව හෝ බහාලුම මැකීමේදී දෝෂයක් මතු විය -ගොනු පිටපත් කිරීම තහවුරු කිරීම -ගො‍නුව හැකිළුම වෙත පිටපත් කළ යුතු බව ඔබට විශ්වාස ද -6100 -ගොනු මැකීම තහවුරු කිරීම -බහාලුම් මැකීම තහවුරු කිරීම -බහු ගොනු මැකීම තහවුරු කිරීම -ඔබට '{0}' මැකීමට අවශ්‍ය බව විශ්වාස ද ? -ඔබට '{0}' බහාලුම හා එහි අන්තර්ගතය මැකීමට අවශ්‍ය බව විශ්වාස ද ? -ඔබට {0} යන වස්තු මැකීමට අවශ්‍ය බව විශ්වාස ද ? -මකමින් පවතී... -ගොනුව හෝ බහාලුම මැකීමේ දී දෝෂයක් මතු විය -දිගු මංපෙතක් ඇති ගොනුවක් කුණු බඳුනට යැවීම පද්ධතියට කල නොහැක. -6300 -බහාලුමක් තනන්න -ගොනුවක් තනන්න -බහාලුම් නාමය: -ගොනු නාමය: -නව බහාලුමක් -නව ගොනුවක් -බහාලුම තැනීමේදී දෝෂයක් මතුවිය -ගොනුව තැනීමේදී දෝෂයක් මතුවිය -6400 -ටීකාව -ටීකාව (&C): -තෝරන්න -තේරීම ඉවත් කරන්න -ගොනුවේ හෝ බහාලුමේ නම හෝ කොටසක්: -6600 -වත්කම් -බහාලුම් අතීතය -විනිශ්චීය පණිවුඩ -පණිවිඩය -7100 -පරිගණකය -ජාලය -ලියකියවිලි -පද්ධතිය -7200 -හකුළන්න -ලිහන්න -පරීක්ෂා කරන්න -පිටපත් කරන්න -ගෙන යන්න -මකන්න -තොරතුරු -7300 -ගොනුව බෙදන්න -ගොනුව බෙදා කොටස් මෙහි තැන්පත් කරන්න (&S): -කොටස් වලට බෙදන්න, බයිට (bytes): -ගොනුව බෙදමින් පවතී... -ගොනුව බෙදීම තහවුරු කරන්න -ගොනුව කොටස් {0} කට බෙදීමට අවශ්‍ය බව ඔබට විශ්වාස ද ? -බෙදූ කොටසක විශාලත්වය, මුල් ගොනුවේ විශාලත්වයට වඩා අඩු විය යුතුය -වැරදි කොටස් විශාලත්වයකි -සඳහන් කරන ලද කොටස් විශාලත්වය බයිට {0} කි.\nහැකිළුම මෙවන් කොටස් වලට බෙදියයුතු බව විශ්වාස ද ? -7400 -බෙදූ ගොනු එක් කරන්න -බෙදූ ගොනු එක් කර මෙහි තැනපත් කරන්න (&C): -බෙදූ ගොන එක් කරමින් පවතී... -පළමු ගොනුව පමණක් තෝරන්න -ගොනුව, බෙදන ලද ගොනුවක කොටසක් ලෙස හඳුනාගත නොහැක. -බෙදන ලද ගොනුවේ කොටස් වලින් එකකට වඩා සොයාගත නොහැක. -7500 -Checksum calculating... -Checksum information -CRC checksum for data: -CRC checksum for data and names: -7600 -Benchmark -මතක භාවිතය: -හැකිළුම් -ලිහුම් -ඇගයුම -සම්පූර්ණ ඇගයුම -වත්මන් -ප්‍රතිඵලිත -CPU භාවිතාව -ඇගයුම / භාවිතාව‍ -Passes: diff -Nru p7zip-rar-16.02/GUI/Lang/sk.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sk.txt --- p7zip-rar-16.02/GUI/Lang/sk.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sk.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,477 +0,0 @@ -;!@Lang2@!UTF-8! -; : Tomas Tomasek -; 9.07 : Pavel Devečka -; 9.38 beta : 2015-01-11 : Roman Horváth -; -; -; -; -; -; -; -; -0 -7-Zip -Slovak -Slovenčina -401 -OK -Zrušiť - - - -&Áno -&Nie -&Zavrieť -Pomocník - -Po&kračovať -440 -Áno na &všetko -Nie na vš&etko -Zastaviť -Reštartovať -&Pozadie -P&opredie -Po&zastaviť -Pozastavené -Ste si istý, že chcete akciu zrušiť? -500 -&Súbor -&Upraviť -&Zobraziť -&Obľúbené -&Nástroje -&Pomocník -540 -&Otvoriť -O&tvoriť vnútri -Ot&voriť externe -&Zobraziť -&Upraviť -&Premenovať -&Kopírovať do... -P&resunúť do... -O&dstrániť -Ro&zdeliť súbor... -Zlúč&iť súbory... -V&lastnosti -Ko&mentár -Vypočítať kontrolný súčet -Rozdiel (Diff) -Vytvoriť priečinok -Vytvoriť súbor -Uko&nčiť -Odkaz... -600 -Označiť všetko -Odznačiť všetko -Invertovať označenie -Označiť... -Odznačiť... -Označiť podľa typu -Odznačiť podľa typu -700 -&Veľké ikony -&Malé ikony -&Zoznam -&Podrobnosti -730 -Netriediť -Plochý vzhľad -&2 Panely -P&anely nástrojov -Otvoriť koreňový priečinok -O úroveň vyššie -História priečinkov... -&Obnoviť -Automatické obnovenie -750 -Archív -Štandard -Veľké ikony -Textový popis pod ikonami -800 -Pridať priečinok medzi obľúbené ako -Záložka -900 -N&astavenia... -&Skúšobný test -960 -&Obsah pomocníka... -O p&rograme 7-Zip -1003 -Cesta -Meno -Prípona -Priečinok -Veľkosť -Veľkosť po kompresii -Atribúty -Vytvorený -Sprístupnený -Zmenený -Jednoliaty -Komentovaný -Zašifrovaný -Rozdelený predtým -Rozdelený potom -Slovník -CRC -Typ -Anti -Metóda -Hostiteľský OS -Súborový systém -Používateľ -Skupina -Blok -Komentár -Pozícia -Predpona cesty -Priečinky -Súbory -Verzia -Zväzok -Multizväzok -Ofset -Odkazy -Bloky -Zväzky - -64-bitov -Big-endian -CPU -Fyzická veľkosť -Veľkosť hlavičiek -Kontrolný súčet -Charakteristiky -Virtuálna adresa -ID -Skrátený názov -Aplikácia -Veľkosť sektora -Režim -Symbolický odkaz -Chyba -Celková veľkosť -Voľné miesto -Veľkosť klastra -Menovka -Lokálny názov -Prevádzkovateľ -Bezpečnosť NT -Alternatívny prúd -Aux -Vymazané -Je strom - - -Typ chyby -Chyby -Chyby -Varovania -Varovanie -Prúdy -Alternatívne prúdy -Veľkosť alternatívneho prúdu -Virtuálna veľkosť -Veľkosť po rozbalení -Celková fyzická veľkosť -Index zväzku -Podtyp -Krátky komentár -Kódová stránka - - - -Veľkosť zakončenia -Veľkosť vloženého ústrižku -Odkaz -Pevný odkaz -iNode -2100 -Nastavenia -Jazyk -Jazyk: -Editor -Editor: -Vyhľadávač rozdielov (Diff): -2200 -Systém -Asociovať 7-Zip s vybranými typmi súborov: -2301 -Integrovať 7-Zip do kontextovej ponuky -Kaskádová kontextová ponuka -Položky kontextovej ponuky: -Ikony v kontextovej ponuke -2320 - - -Otvoriť archív -Rozbaliť súbory... -Pridať do archívu... -Otestovať archív -Rozbaliť tu -Rozbaliť do {0} -Pridať do {0} -Skomprimovať a poslať emailom... -Skomprimovať do {0} a poslať emailom -2400 -Priečinky -&Pracovný priečinok -&Systémový priečinok pre dočasné súbory -&Aktuálny priečinok -&Manuálne vybraný priečinok: -Po&užiť len pre vymeniteľné jednotky -Vyberte priečinok pre dočasné súbory. -2500 -Nastavenia -Ukázať položku ".." -Ukázať skutočné ikony súborov -Ukázať systémovú ponuku -Označiť celý riadok -Zobraziť čiary mriežky -Otvoriť položku jednoduchým kliknutím -Alternatívny režim výberu -Použitie veľkých stránok pamäti -2900 -O programe 7-Zip -7-Zip je voľne šíriteľný softvér -3000 -Systém nemôže alokovať požadované množstvo pamäte -V archíve sa nenašli žiadne chyby -{0} vybraných objektov -Nie je možné vytvoriť priečinok '{0}'. -Operácie aktualizácie nie sú pre tento archív podporované. -Súbor '{0}' nie je možné otvoriť ako archív -Nie je možné otvoriť šifrovaný archív '{0}'. Nesprávne heslo? -Nepodporovaný typ archívu -Súbor {0} už existuje. -Súbor '{0}' bol zmenený.\nChcete ho aktualizovať v archíve? -Nie je možné aktualizovať súbor\n'{0}' -Nie je možné spustiť editor. -Súbor vyzerá ako vírus. (Meno súboru obsahuje veľa medzier.) -Operácia nemôže byť vykonaná v priečinku, ktorý má dlhú cestu. -Musíte vybrať jeden súbor -Musíte vybrať jeden alebo viac súborov -Priveľa položiek -3300 -Rozbaľovanie -Komprimovanie -Výsledok testovania -Otváranie... -Prehľadávanie... -3400 -Rozbaliť -Rozbaliť do: -Špecifikujte priečinok pre rozbalené súbory. -3410 -Nastavenie názvov ciest: -Plné názvy ciest -Žiadne názvy ciest -Absolútne názvy ciest -Relatívne názvy ciest -3420 -Nastavenie prepísania: -Spýtať sa pred prepísaním -Prepísať bez výzvy -Preskočiť existujúce súbory -Automaticky premenovať -Automaticky premenovať existujúce súbory -3430 -Eliminovať duplikáty koreňového priečinka -Obnoviť práva súboru -3500 -Potvrdenie nahradenia súboru -Cieľový priečinok už obsahuje rozbaľovaný súbor. -Chcete nahradiť existujúci súbor -týmto súborom? -{0} bajtov -&Automaticky premenovať -3700 -Nepodporovaná kompresná metóda pre '{0}'. -Chybné údaje v '{0}'. Súbor je poškodený. -CRC zlyhalo v '{0}'. Súbor je poškodený. -Chybné údaje v šifrovanom súbore '{0}'. Nesprávne heslo? -CRC zlyhalo v šifrovanom súbore '{0}'. Nesprávne heslo? -3710 -Nesprávne heslo? -3721 -Nepodporovaná kompresná metóda -Chybné údaje -CRC zlyhalo -Údaje sú nedostupné -Neočakávaný koniec údajov -Za zužitkovateľnými údajmi sa nachádzajú ďalšie údaje -Nie je to archív -Chybné hlavičky -3763 -Začiatok archívu je nedostupný -Začiatok archívu nie je potvrdený - - - -Nepodporovaná funkcia -3800 -Zadajte heslo -Zadajte heslo: -Zopakujte heslo: -Ukázať heslo -Heslá nie sú zhodné -Používajte len písmená bez diakritiky, čísla a špeciálne znaky (!, #, $, ...) -Heslo je príliš dlhé -Heslo -3900 -Uplynutý čas: -Zostávajúci čas: -Veľkosť: -Rýchlosť: -Spracované: -Úroveň kompresie: -Chyby: -Archívy: -4000 -Pridať do archívu -&Archív: -&Nastavenie aktualizácie súborov v existujúcich archívoch: -&Formát archívu: -Ú&roveň kompresie: -&Kompresná metóda: -&Veľkosť slovníka: -V&eľkosť slova: -Veľk&osť jednoliateho bloku: -Poče&t CPU vlákien: -&Parametre: -Možnosti -Vytvoriť samorozbaľovací archív -Komprimovať zdieľané súbory -Šifrovanie -Metóda šifrovania: -Zašifrovať mená súborov -Pamäť potrebná na kompresiu: -Pamäť potrebná na dekompresiu: -Vymazať súbory po kompresii -4040 -Uložiť symbolické odkazy -Uložiť pevné odkazy -Uložiť alternatívne údajové prúdy -Uložiť práva súborov -4050 -Bez kompresie -Najrýchlejšia -Rýchla -Normálna -Maximálna -Ultra -4060 -Pridať a nahradiť súbory -Aktualizovať a pridať súbory -Aktualizovať existujúce súbory -Synchronizovať súbory -4070 -Prehľadávať -Všetky súbory -Nejednoliaty -Jednoliaty -6000 -Kopírovať -Presunúť -Kopírovať do: -Presunúť do: -Kopírovanie... -Presúvanie... -Premenovanie... -Vyberte cieľový priečinok. -Operácia nie je podporovaná pre tento priečinok. -Chyba pri premenovaní súboru alebo priečinka -Potvrdiť kopírovanie súboru/súborov -Ste si istý, že chcete kopírovať súbor/súbory do archívu -6100 -Potvrdenie odstránenia súboru -Potvrdenie odstránenia priečinka -Potvrdenie odstránenia viacerých položiek -Ste si istý, že chcete odstrániť súbor '{0}'? -Ste si istý, že chcete odstrániť priečinok '{0}' a celý jeho obsah? -Ste si istý, že chcete odstrániť týchto {0} položiek? -Odstraňovanie... -Chyba pri odstraňovaní súboru alebo priečinka -Systém nemôže presunúť do koša súbor s dlhou cestou -6300 -Vytvoriť priečinok -Vytvoriť súbor -Meno priečinka: -Meno súboru: -Nový priečinok -Nový súbor -Chyba pri vytváraní priečinka -Chyba pri vytváraní súboru -6400 -Komentár -&Komentár: -Označiť -Odznačiť -Maska: -6600 -Vlastnosti -História priečinkov -Diagnostické správy -Správa -7100 -Počítač -Sieť -Dokumenty -Systém -7200 -Pridať -Rozbaliť -Otestovať -Kopírovať -Presunúť -Odstrániť -Informácie -7300 -Rozdeliť súbor -&Rozdeliť na: -Roz&deliť na zväzky bajtov: -Rozdeľovanie... -Potvrdiť rozdeľovanie. -Ste si istý, že chcete rozdeliť súbor na {0} zväzkov? -Veľkosť zväzku musí byť menšia než veľkosť pôvodného súboru. -Nesprávna veľkosť zväzku -Určená veľkosť zväzku: {0} bajtov.\nSte si istý, že chcete rozdeliť archív na také zväzky? -7400 -Zlúčiť súbory -&Zlúčiť do: -Zlučovanie... -Vyberte len prvý súbor. -Nie je možné rozlíšiť súbor ako súčasť rozdeleného súboru -Nie je možné nájsť viac než jednu časť rozdeleného súboru -7500 -Výpočet kontrolného súčtu... -Informácie o kontrolnom súčte -CRC súčet pre údaje: -CRC súčet pre údaje a názvy: -7600 -Skúšobný test -Použitá pamäť: -Komprimovanie -Rozbaľovanie -Hodnotenie -Celkové hodnotenie -Aktuálne -Výsledné -Využitie CPU -Hodn. / Využitie -Testov bez chýb: -7700 -Odkaz -Odkaz -Odkaz z: -Odkaz do: -7710 -Typ odkazu -Pevný odkaz -Súbor symbolického odkazu -Priečinok symbolického odkazu -Prekríženie priečinkov diff -Nru p7zip-rar-16.02/GUI/Lang/sl.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sl.txt --- p7zip-rar-16.02/GUI/Lang/sl.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sl.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : tomazek -; 4.55 : miles -; -; -; -; -; -; -; -; -; -0 -7-Zip -Slovenian -Slovenski -401 -V redu -Prekliči - - - -&Da -&Ne -&Zapri -Pomoč - -&Nadaljuj -440 -Da za &vse -Ne za v&se -Zaustavi -Ponovno zaženi -&Ozadje -O&spredje -&Začasno zaustavi -Zaustavljen -Ste prepričani, da želite preklicati? -500 -&Datoteka -&Urejanje -&Pogled -Pr&iljubljene -O&rodja -Po&moč -540 -&Odpri -Odpri &znotraj -Odpri zu&naj -P&rikaz -&Urejanje -Prei&menuj -&Kopiraj ... -&Premakni ... -Iz&briši -&Razdeli datoteko ... -&Združi datoteke ... -L&astnosti -Opomb&e -Izračunaj preskusno vsoto - -Ustvari mapo -Ustvari datoteko -&Izhod -600 -Izberi &vse -Razveljavi izbiro vseh -&Preobrni izbor -Izberi ... -Razveljavi izbiro ... -Izberi glede na vrsto -Razveljavi izbiro glede na vrsto -700 -&Velike ikone -&Majhne ikone -&Seznam -&Podrobnosti -730 -Nerazvrščeno -Splošen pogled -&Dve podokni -&Orodne vrstice -Odpri korensko mapo -Nadrejena raven -Zgodovina mape ... -&Osveži -750 -Orodna vrstica arhiva -Navadna orodna vrstica -Veliki gumbi -Pokaži besedilo gumbov -800 -&Dodaj mapo med Priljubljene kot -Zaznamek -900 -&Možnosti ... -Me&ritev -960 -&Vsebina pomoči ... -&O programu 7-Zip ... -1003 -Pot -Ime -Pripona -Mapa -Velikost -Stisnjena velikost -Atributi -Izdelano -Uporabljeno -Spremenjeno -Trdno -Komentirano -Šifrirano -Razdeli pred -Razdeli po -Slovar -CRC -Vrsta -Anti -Metoda -Gostiteljski OS -Datotečni sistem -Uporabnik -Skupina -Blok -Opomba -Položaj -Predpona poti -Mape -Datoteke -Različica -Nosilec -Več nosilcev -Zamik -Povezave -Bloki -Nosilcev - - - - - - - - - - - - - - - -Napaka -Skupna velikost -Prostega prostora -Velikost gruče -Oznaka -Krajevno ime -Ponudnik -2100 -Možnosti -Jezik -Jezik: -Urejevalnik -&Urejevalnik: - -2200 -Sistem -Poveži 7-Zip z: -2301 -Integracija 7-Zip v kontekstni meni lupine -Kaskadni kontekstni meni -Izbire kontekstnega menija: -2320 - - -Odpri arhiv -Razširi datoteke ... -Stisni v arhiv ... -Preizkusi arhiv -Razširi semkaj -Razširi v {0} -Dodaj v {0} -Stisni in pošlji ... -Stisni v {0} in pošlji po e-pošti -2400 -Mape -&Delovna mapa -&Sistemska začasna mapa -&Trenutna mapa -&Navedeno: -Uporabi le za izmenljive pogone -Navedite mesto za začasne arhivske datoteke. -2500 -Nastavitve -Pokaži postavko ".." -Pokaži prave ikone datotek -Pokaži sistemski meni -&Izbor celotne vrstice -Pokaži &mrežne črte - -&Alternativni način izbiranja -Uporabi &velike spominske strani -2900 -O programu 7-Zip -7-Zip je brezplačen. Njegov razvoj podprete s tem, da se registrirate. -3000 - -Brez napak -Izbran(ih) {0} objekt(ov) -Mape '{0}' ni mogoče ustvariti -Za ta arhiv operacije osveževanja niso podprte. -Datoteke '{0}' ni mogoče odpreti kot arhiv -Šifriranega arhiva '{0}' ni mogoče odpreti. Je morda geslo napačno? - - -Datoteka '{0}' je bila spremenjena.\nJo želite osvežiti v arhivu? -Datoteke ni mogoče osvežiti\n'{0}' -Urejevalnika ni mogoče pognati. - - - - -Preveč izbir -3300 -Razširjanje -Stiskanje -Preizkušanje -Odpiranje ... -Pregledovanje ... -3400 -Razširi -R&azširi v: -Določite mesto razširjanja datotek. -3410 -Poti -Polne poti -Brez poti -3420 -Prepisovalni način -Zahtevaj potrditev -Prepiši brez potrditve -Preskoči obstoječe datoteke -Samodejno preimenuj -Samodejno preimenuj obstoječe datoteke -3500 -Potrditev zamenjave datoteke -Ciljna mapa že vsebuje obdelovano datoteko. -Želite zamenjati obstoječo datoteko -s to datoteko? -{0} bajtov -Samodejno &preimenuj -3700 -Nepodprta metoda stiskanja za '{0}'. -Podatkovna napaka v '{0}'. Datoteka je poškodovana. -Napaka CRC v '{0}'. Datoteka je poškodovana. -Podatkovna napaka v šifrirani datoteki '{0}'. Je geslo pravilno? -Napaka CRC v šifrirani datoteki '{0}'. Je geslo pravilno? -3800 -Vnos gesla -Vnesite geslo: -Ponovno vnesite geslo: -&Pokaži geslo -Gesli se ne ujemata -Za geslo uporabite le črke, številke in posebne znake angleške abecede (!, #, $, ...) -Geslo je predolgo -Geslo -3900 -Pretečeni čas: -Preostali čas: -Velikost: -Hitrost: -Obdelano: -Razmerje stiskanja: -Napake: -Arhivi: -4000 -Dodaj v arhiv -&Arhiv: -&Način osveževanja: -&Vrsta arhiva: -Raven &stiskanja: -&Metoda stiskanja: -&Velikost slovarja: -Velikost &besede: -Velikost trdnega bloka: -Število niti CPE: -&Parametri: -Možnosti -Izdelaj arhiv SF&X -Stisni skupne datoteke -Šifriranje -Metoda šifriranja: -Šifriraj &imena datotek -Poraba pomnilnika za stiskanje: -Poraba pomnilnika za razširjanje: -4050 -Brez stiskanja -Najhitrejše -Hitro -Običajno -Največje stiskanje -Ultra -4060 -Dodaj in zamenjaj datoteke -Osveži in dodaj datoteke -Osveži obstoječe datoteke -Sinhroniziraj datoteke -4070 -Prebrskaj -Vse datoteke -Ne-trdno -Trdno -6000 -Kopiraj -Premakni -Kopiraj v: -Premakni v: -Kopiranje ... -Premikanje ... -Preimenovanje ... -Izberite ciljno mapo. -Operacija ni podprta. -Napaka pri preimenovanju datoteke ali mape -Potrditev kopiranja datoteke -Ste prepričani, da želite kopirati datoteke v arhiv? -6100 -Potrditev brisanja datoteke -Potrditev brisanja mape -Potrditev brisanja več datotek -Ste prepričani, da želite zbrisati '{0}'? -Ste prepričani, da želite zbrisati mapo '{0}' in celotno njeno vsebino? -Ste prepričani, da želite zbrisati teh {0} postavk? -Brisanje ... -Napaka pri brisanju datoteke ali mape - -6300 -Izdelava mape -Ustvarjanje datoteke -Ime mape: -Ime datoteke: -Nova mapa -Nova datoteka -Napaka pri ustvarjanju mape -Napaka pri ustvarjanju datoteke -6400 -Opomba -&Opomba: -Izberi -Razveljavi izbiro -Maska: -6600 -Properties -Zgodovina map -Diagnostična sporočila -Sporočilo -7100 -Računalnik -Omrežje - -Sistem -7200 -Dodaj -Razširi -Preizkusi -Kopiraj -Premakni -Izbriši -Informacije -7300 -Razdeli datoteko -&Razdeli na: -Razdeli na &nosilce velikosti (v bajtih): -Razdeljevanje ... -Potrditev razdelitve -Ste prepričani, da želite razdeliti datoteko na {0} nosilcev? -Velikost nosilca mora biti manjša kot velikost izvorne datoteke -Neveljavna velikost nosilca -Navedena velikost nosilca: {0} bajtov.\nSte prepričani, da želite razdeliti arhiv na takšne nosilce? -7400 -Združi datoteke -&Združi v: -Združevanje ... -Izberite samo prvo datoteko - - -7500 -Izračun preskusne vsote ... -Podatki o preskusni vsoti -Preskusna vsota za podatke: -Preskusna vsota za podatke in imena: -7600 -Meritev -Poraba pomnilnika: -Stiskanje -Razširjanje -Ocena -Skupna ocena -Trenutno -Končno -Uporaba CPE -Ocena / uporaba -Prehodi: diff -Nru p7zip-rar-16.02/GUI/Lang/sq.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sq.txt --- p7zip-rar-16.02/GUI/Lang/sq.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sq.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.37 : Mikel Hasko -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Albanian -Shqip -401 -Në rregull -Anulim - - - -&Po -&Jo -&Mbyll -Ndihmë - -&Vazhdim -440 -Po për të gjith&a -Jo për të gjit&ha -Ndalo -Rinis -Në &sfond -Në pla&n të parë -&Pushim -Në pushim -Jeni të sigurt se dëshironi ta anuloni? -500 -&Skedari -&Redaktimi -&Pamja -&Të parapëlqyerit -&Veglat -&Ndihma -540 -&Hap -Hap përbre&nda -Hap përjas&hta -&Pamja -&Redakto -Ri&emërto -&Kopjo tek... -&Zhvendos tek... -&Fshi -N&daj skedarin... -Kom&bino skedarët... -&Vetitë -Ko&menti -Llogarit shumën e verifikimit - -Krijo një dosje -Krijo një skedar -&Dil -600 -S&elekto të gjithë -Çse&lekto të gjithë -Anasill selekti&min -Selekto... -Çselekto... -Selekto sipas tipit -Çselekto sipas tipit -700 -Ikona të &mëdha -Ikona të &vogla -&Listë -&Detaje -730 -&Të parenditur -Pamje e rrafshtë -&2 panele -&Shiritat e veglave -Hap dosjen rrënjë -Një nivel më lartë -Historiku i dosjes... -&Rifresko -750 -Shiriti i veglave i arkivit -Shiriti standard i veglave -Butona të mëdhenj -Shfaq tekstin e butonave -800 -&Shto dosjen tek të parapëlqyerit si -Shënuesi -900 -&Opsionet... -&Etapa -960 -&Përmbajtjet... -&Për 7-Zip... -1003 -Shtegu -Emri -Prapashtesa -Dosja -Madhësia -Madhësia e mbërthimit -Atributet -Krijuar më -Hyrë së fundi më -Modifikuar më -I qëndrueshëm -I komentuar -I shifruar -Ndaj para -Ndaj pas -Fjalori -CRC -Tipi -Anti -Metoda -Pronari i sistemit -Sistemi i skedarit -Përdoruesi -Grupi -Blloku -Komenti -Pozicioni -Prefiksi i shtegut - - - - - - - - - - - - - - - - - - - - - - - - -Gabim -Madhësia totale -Hapësira e lirë -Madhësia e cluster-it -Etiketa -Emri lokal -Kujdestari -2100 -Opsionet -Gjuha -Gjuha: -Redaktuesi -&Redaktuesi: - -2200 -Sistemi -Lidh 7-Zip me: -2301 -Integro 7-Zip në kontekst meny -Kaskado kontekst menynë -Elementë të kontekst menysë: -2320 - - -Hap arkivin -Zbërthe skedarët... -Shto në arkiv... -Testo arkivin -Zbërthe këtu -Zbërthe në {0} -Shto tek {0} -Kompreso dhe dërgo me e-mail... -Kompreso në {0} dhe dërgo me e-mail -2400 -Dosje -&Dosja e punës -Dosja e përkohshme e &sistemit -Dosja &aktuale -I sp&ecifikuar: -Përdor vetëm për njësi të largueshme -Specifikoni një vendndodhje për skedarët e përkohshëm të arkivit. -2500 -Rregullimet -Shfaq &artikullin ".." -Shfaq &ikonat e vërteta të skedarëve -Shfaq &menynë e sistemit -Selekto të tërë &rreshtin -Shfaq &vijat e rrjetit - -Mënyrë alternative &selektimi -Përdor &faqe të mëdha të memories -2900 -Për 7-Zip -7-Zip është softuer falas. Megjithatë, ju mund të përkrahni në zhvillimin e 7-Zip duke e regjistruar atë. -3000 - -S'ka gabime -Selektuar {0} objekt(e) -S'mund të krijojë dosjen '{0}' -Operacionet e azhurnimit për këtë arkiv s'përkrahen. - - - - -Skedari '{0}' u modifikua.\nDoni ta azhurnoni atë edhe në arkiv? -S'mund të azhurnojë skedarin\n'{0}' -S'mund të hap redaktuesin. - - - - -Tepër shumë artikuj -3300 -Duke zbërthyer -Duke kompresuar -Duke testuar -Duke hapur... -Duke skanuar... -3400 -Zbërthe -Z&bërthe në: -Specifikoni një vendndodhje për skedarët e zbërthyer. -3410 -Mënyra e Shtegut -Emra të plotë Shtigjesh -Pa emra shtigjesh -3420 -Mënyra e mbishkrimit -Pyet para se të mbishkruaj -Mbishkruaj pa nxitje -Mbikalo skedarët ekzistues -Riemërto automatikisht -Riemërto auto. skedarët ekzistues -3500 -Konfirmo zëvendësimin e skedarëve -Dosja e destinacionit e përmban një herë skedarin e përpunuar. -Dëshironi ta zëvendësoni skedarin ekzistues -me këtë? -{0} bajt -R&iemërtim automatik -3700 -Metodë e papërkrahshme kompresimi për '{0}'. -Gabim të dhënash në '{0}'. Skedari është i prishur. -CRC dështoi '{0}'. Skedari është i prishur. - - -3800 -Fusni fjalëkalimin -Fusni fjalëkalimin: - -&Trego fjalëkalimin - - - -Fjalëkalimi -3900 -Koha e kaluar: -Koha e mbetur: -Madhësia: -Shpejtësia: - - -Gabime: - -4000 -Shto në arkiv -&Arkivi: -&Mënyra e azhurnimit: -&Formati i arkivit: -&Niveli i kompresimit: -Metoda e kompr&esimit: -Ma&dhësia e fjalorit: -Mad&hësia e fjalës: - - -&Parametrat: -Opsionet -Krijo një arkiv SF&X - - - -Shifro em&rat e skedarëve -Shfrytëzimi i memo. për kompresimin: -Shfrytëzimi i memo. për dekompresimin: -4050 -Ruaj -Më i shpejtë -I shpejtë -Normal -Maksimal -Ultra -4060 -Shto dhe zëvendëso skedarët -Azhurno dhe shto skedarët -Azhurno skedarët ekzistues -Sinkronizo skedarët -4070 -Shfleto -Të gjithë skedarët - - -6000 -Kopjo -Zhvendos -Kopjo tek: -Zhvendos tek: -Duke kopjuar... -Duke zhvendosur... -Duke riemërtuar... - -Operacioni s'përkrahet. -Gabim gjatë riemërtimit të skedarit apo dosjes -Konfirmim për kopjimin e skedarëve -Jeni të sigurt që doni të kopjoni skedarë në arkiv -6100 -Konfirmo fshirjen e skedarit -Konfirmo fshirjen e dosjes -Konfirmo fshirjen e shumëfishtë të skedarëve -Jeni të sigurt që doni të fshini '{0}'? -Jeni të sigurt që doni të fshini dosjen '{0}' dhe tërë përmbajtjen e saj? -Jeni të sigurt që doni t'i fshini këto {0} artikuj? -Duke fshirë... -Gabim gjatë fshirjes së skedarit apo dosjes - -6300 -Krijo një dosje -Krijo një skedar -Emri i dosjes: -Emri i skedarit: -Dosje e re -Skedar i ri -Gabim gjatë krijimit të dosjes -Gabim gjatë krijimit të skedarit -6400 -Komenti -&Komenti: -Selekto -Çselekto -Maska: -6600 - -Historiku i dosjes -Mesazhe diagnostikues -Mesazhi -7100 -Kompjuteri -Rrejti - -Sistemi -7200 -Shto -Zbërthe -Testo -Kopjo -Zhvendos -Fshi -Info -7300 -Ndaj skedarin -&Ndaj në: -Ndaj në &volume (madhësia jepet në bajt): -Duke ndarë... - - - - - -7400 -Kombino skedarët -&Kombino në: -Duke kombinuar... - - - -7500 -Duke llogaritur shumën e verifikimit... -Informacionet e shumës së verifikimit -Shuma e verifikimit CRC për të dhënat: -Shuma e verifikimit CRC për të dhënat dhe emrat: -7600 -Etapa -Shfrytëzimi i memories: -Kompresimi -Dekompresimi -Vlerësimi -Vlerësimi total -Aktualisht -Rezultati - - -Kalime: diff -Nru p7zip-rar-16.02/GUI/Lang/sr-spc.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spc.txt --- p7zip-rar-16.02/GUI/Lang/sr-spc.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spc.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Lazar -; 9.07 : Ozzii -; -; -; -; -; -; -; -; -; -0 -7-Zip -Serbian - Cyrillic -Српски - ћирилица -401 -У реду -Откажи - - - -Да -Не -Затвори -Помоћ - -Настави -440 -Да за све -Не за све -Стани -Поново -Позадина -На врху -Пауза -Пауза -Да ли сте сигурни да желите да прекинете? -500 -Датотека -Уређивање -Преглед -Омиљено -Алати -Помоћ -540 -Погледај -Отвори са 7-Zip-ом -Отвори са придруженом програмом -Прегледај -Промени -Преименуј -Копирај у... -Премести у... -Обриши -Подели фајл... -Спој делове... -Својства -Коментар -Израчунајте проверну величину -разлика -Нова фасцикла -Нова датотека -Излаз -600 -Изабери све -Поништи избор свега -Обрнути избор -Изабери... -Поништи избор... -Изабери по типу -Поништи избор по типу -700 -Иконе -Напоредно слагање -Списак -Детаљи -730 -Без сортирања -Раван преглед -2 Прозора -Траке са алаткама -Отвори почетну фасциклу -Горе за један ниво -Хронологија... -Освежавање -750 -Рад са архивама -Рад са датотекама -Велика дугмад -Прикажи текст испод дугмади -800 -Додај -Изабери -900 -Опције... -Benchmark -960 -Помоћ... -О програму... -1003 -Путања -Назив -Тип -Фасцикла -Величина -Величина у запакованом стању -Атрибути -Креирана -Приступано -Промењено -Солидно -Коментар -Шифровано -Подели пре -Подели после -Речник -ЦРЦ -Тип -Анти -Метод -Оперативни систем -Систем датотека -Корисник -Група -Блок -Коментар -Положај -Префикс путање -Фасцикле -Датотеке -Верзија -Волумен -ВишеВолумена -Офсет -Линкови -Блокови -Волумени - -64-бит -Big-endian -Процесор -Физичка величина -Величина заглавља -Провера резултата -Карактеристике -Виртуелна адреса -ИД -Кратко име -Креатор апликације -Величина сектора -Начин -Линк -Грешка -Укупни капацитет -Слободни простор -Величинa cluster-а -Назив -Локално име -Провајдер -2100 -Опције -Језик -Језик: -Промене у датотекама -Програм: -Разлика: -2200 -Систем -7-Zip отвара следеће типове датотека: -2301 -Убаци 7-Zip у системски мени -Каскадни системски мени -Ставке системског менија: -2320 - - -Отвори архиву -Издвој датотеке... -Додај у архиву... -Тестирај архиву -Издвој овде -Издвој у {0} -Додај у {0} -Додај и направи e-mail... -Додај у {0} и направи e-mail -2400 -Фасцикле -Радна фасцикла -Користи Windows-ову привремену фасциклу -Тренутна -Наведена: -Користи само за измењиве медије -Наведите локацију за смештање привремених датотека. -2500 -Подешавања -Прикажи ".." -Прикажи праве сличице датотека -Прикажи системски мени -Обележи цео ред -Прикажи линије мреже -Један клик за отварање ставке -Алтернативни начин за бирање -Користи велике меморијске блокове -2900 -О програму -7-Zip је бесплатан програм. -3000 -Систем не може да издвоји потребну количину меморије -Није било никаквих грешака -{0} објекат(а) изабрано -Не могу да креирам Фасциклу '{0}' -Операција освежавања није дозвољена за ову архиву. -Не могу да отворим датотеку '(0)' као архива -Не могу да отворим шифровану архиву '(0)'. Погрешна лозинка? -Неподржан тип архиве -Датотека {0} већ постоји -Датотека '{0}' је измјењена.\nДа ли желите ажурирати архиву? -Није могуће ажурирати датотеку\n'{0}' -Није могуће започети уређивање. -Датотека изгледа као вирус (име датотеке садржи пуно размака у имену). -Операција не може бити позвана из фасцикле која има дугу путању. -Морате да изаберете неку датотеку -Морате да изаберете једну или више датотека -Исувише ставки -3300 -Издвајање -Додајем -Тестирање -Отварање у току... -Скенирање... -3400 -Издвој -Издвој у: -Наведи локацију где ће се издвајати датотеке из архива. -3410 -Путање -Пуна путања -Без путање -3420 -Замена -Питај пре него што замениш -Замени без запиткивања -Прескочи постојеће датотеке -Аутоматска промена назива -Аутоматска промена назива постојећих датотека -3500 -Потврди замену датотеке -Циљна фасцикла већ садржи датотеку која се тренутно обрађује. -Да ли желите да замените постојећу датотеку -са овом? -{0} бајтова -Аутоматска промена назива -3700 -Неподржани метод компресије за '{0}'. -Грешка у '{0}'. Датотека је неисправана. -CRC грешка у '{0}'. Датотека је неисправана. -Грешке у кодирану датотеку '(0)' Погрешна лозинка. -ЦРЦ грешка у шифроване датотеке '(0)' Погрешна лозинка. -3800 -Унесите лозинку -Унесите лозинку: -Поново унесите лозинку: -Прикажи лозинку -Лозинке се не поклапају -Користи само енглеска слова, бројева и специјалних знакова (!, #, $, ...) За лозинке -Лозинка је предугачка -Шифра -3900 -Протекло време: -Преостало време: -Величина: -Брзина: -Обрађено: -Компресиони однос: -Грешке: -Архиве: -4000 -Додај у архиву -Архива: -Надоградња архива: -Формат архиве: -Ниво компресије: -Тип компресије: -Dictionary size: -Word size: -Величина чврстог блока: -Број низа процесора: -Параметри: -Опције -Креирај SFX архиву -Компресија дељене датотека -Шифровање -Метода шифровања: -Шифруј називе датотека -Потребна меморија - компресија: -Потребна меморија - декомпресија: -4050 -Без компресије -Брже -Брзо -Нормално -Максимално -Најбрже -4060 -Додај и замени датотеке -Освежи и додај датотеке -Озвежи постојеће датотеке -Синхронизуј датотеке -4070 -Прегледај -Све датотеке -Не-чврсте -Чврсто -6000 -Копирај -Исеци -Копирај у: -Премести у: -Копирање у току... -Премештање у току... -Преименовање у току... -Изаберите одредишну фасциклу. -Операција није подржана. -Грешка при преименовању датотеке или фасцикле -Потврди копирање датотеке -Да ли сте сигурни да желите да копирате датотеке у архиву -6100 -Потврдите брисање датотеке -Потврдите брисање фасцикле -Потврдите вишеструко брисање датотека -Јесте ли сигурни да желите да обришете '{0}'? -Јесте ли сигурни да желите да обришете фасциклу '{0}' и сав њен садржај? -Јесте ли сигурни да желите да обришете ове {0} податке? -Брисање у току... -Грешка при брисању датотеке или фасцикле -Систем не може да премести датотеку са дугом путу у корпу за отпатке -6300 -Креирај фасциклу -Креирај датотеку -Име фасцикле: -Име датотеке: -Нова фасцикла -Нова датотека -Грешка при креирању фасцикли -Грешка при креирању датотека -6400 -Коментар -Коментар: -Одабери -Поништи избор -Маска: -6600 -Особине -Хронологија -Дијагностичке поруке -Поруке -7100 -Рачунар -Мрежа -Документи -Систем -7200 -Додај -Издвој -Тестирај -Копирај -Премести -Избриши -Својства -7300 -Подели датотеку -Подели на: -Подели на делове, бајти: -Подела... -Потврда поделе -Да ли сте сигурни да желите да поделите датотеку на (0) дела? -Величине дела мора бити мањи од величине оригиналне датотеке -Неисправна величина волумена -Одређена величина волумена: {0} бајтова.\nДа ли сте сигурни да желите да поделите архиву у тих волумена? -7400 -Састави датотеке -Састави у: -Спајање... -Изаберите само први део поделе датотеке -Не могу да откријем датотеку као део поделе -Не може се наћи више од једног дела поделе -7500 -Израчунавање проверне величине... -Информација о проверне величине -ЦРЦ порвера за податак: -ЦРЦ провера за податак и имена: -7600 -Benchmark -Коришћење меморије: -Компресија -Декомпресија -Оцена -Потпуна оцена -Тренутно -Резултат -Употреба процесора -Рејтинг/Употреба -Пролази: diff -Nru p7zip-rar-16.02/GUI/Lang/sr-spl.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spl.txt --- p7zip-rar-16.02/GUI/Lang/sr-spl.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sr-spl.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Lazar -; 9.07 : Ozzii -; -; -; -; -; -; -; -; -; -0 -7-Zip -Serbian - Latin -Srpski - latinica -401 -U redu -Otkaži - - - -Da -Ne -Zatvori -Pomoć - -Nastavi -440 -Da za sve -Ne za sve -Stani -Ponovo -Pozadina -Na vrhu -Pauza -Pauza -Da li ste sigurni da želite da prekinete? -500 -Datoteka -Uređivanje -Pregled -Omiljeno -Alati -Pomoć -540 -Pogledaj -Otvori sa 7-Zip-om -Otvori sa pridruženom programom -Pregledaj -Promeni -Preimenuj -Kopiraj u... -Premesti u... -Obriši -Podeli fajl... -Spoj delove... -Svojstva -Komentar -Izračunajte provernu veličinu -razlika -Nova fascikla -Nova datoteka -Izlaz -600 -Izaberi sve -Poništi izbor svega -Obrnuti izbor -Izaberi... -Poništi izbor... -Izaberi po tipu -Poništi izbor po tipu -700 -Ikone -Naporedno slaganje -Spisak -Detalji -730 -Bez sortiranja -Ravan pregled -2 Prozora -Trake sa alatkama -Otvori početnu fasciklu -Gore za jedan nivo -Hronologija... -Osvežavanje -750 -Rad sa arhivama -Rad sa datotekama -Velika dugmad -Prikaži tekst ispod dugmadi -800 -Dodaj -Izaberi -900 -Opcije... -Benchmark -960 -Pomoć... -O programu... -1003 -Putanja -Naziv -Tip -Fascikla -Veličina -Veličina u zapakovanom stanju -Atributi -Kreirana -Pristupano -Promenjeno -Solidno -Komentar -Šifrovano -Podeli pre -Podeli posle -Rečnik -CRC -Tip -Anti -Metod -Operativni sistem -Sistem datoteka -Korisnik -Grupa -Blok -Komentar -Položaj -Prefiks putanje -Fascikle -Datoteke -Verzija -Volumen -VišeVolumena -Ofset -Linkovi -Blokovi -Volumeni - -64-bit -Big-endian -Procesor -Fizička veličina -Veličina zaglavlja -Provera rezultata -Karakteristike -Virtuelna adresa -ID -Kratko ime -Kreator aplikacije -Veličina sektora -Način -Link -Greška -Ukupni kapacitet -Slobodni prostor -Veličina cluster-a -Naziv -Lokalno ime -Provajder -2100 -Opcije -Jezik -Jezik: -Promene u datotekama -Program: -Razlika: -2200 -Sistem -7-Zip otvara sledeće tipove datoteka: -2301 -Ubaci 7-Zip u sistemski meni -Kaskadni sistemski meni -Stavke sistemskog menija: -2320 - - -Otvori arhivu -Izdvoj datoteke... -Dodaj u arhivu... -Testiraj arhivu -Izdvoj ovde -Izdvoj u {0} -Dodaj u {0} -Dodaj i napravi e-mail... -Dodaj u {0} i napravi e-mail -2400 -Fascikle -Radna fascikla -Koristi Windows-ovu privremenu fasciklu -Trenutna -Navedena: -Koristi samo za izmenjive medije -Navedite lokaciju za smeštanje privremenih datoteka. -2500 -Podešavanja -Prikaži ".." -Prikaži prave sličice datoteka -Prikaži sistemski meni -Obeleži ceo red -Prikaži linije mreže -Jedan klik za otvaranje stavke -Alternativni način za biranje -Koristi velike memorijske blokove -2900 -O programu -7-Zip je besplatan program. -3000 -Sistem ne može da izdvoji potrebnu količinu memorije -Nije bilo nikakvih grešaka -{0} objekat(a) izabrano -Ne mogu da kreiram Fasciklu '{0}' -Operacija osvežavanja nije dozvoljena za ovu arhivu. -Ne mogu da otvorim datoteku '(0)' kao arhiva -Ne mogu da otvorim šifrovanu arhivu '(0)'. Pogrešna lozinka? -Nepodržan tip arhive -Datoteka {0} već postoji -Datoteka '{0}' je izmjenjena.\nDa li želite ažurirati arhivu? -Nije moguće ažurirati datoteku\n'{0}' -Nije moguće započeti uređivanje. -Datoteka izgleda kao virus (ime datoteke sadrži puno razmaka u imenu). -Operacija ne može biti pozvana iz fascikle koja ima dugu putanju. -Morate da izaberete neku datoteku -Morate da izaberete jednu ili više datoteka -Isuviše stavki -3300 -Izdvajanje -Dodajem -Testiranje -Otvaranje u toku... -Skeniranje... -3400 -Izdvoj -Izdvoj u: -Navedi lokaciju gde će se izdvajati datoteke iz arhiva. -3410 -Putanje -Puna putanja -Bez putanje -3420 -Zamena -Pitaj pre nego što zameniš -Zameni bez zapitkivanja -Preskoči postojeće datoteke -Automatska promena naziva -Automatska promena naziva postojećih datoteka -3500 -Potvrdi zamenu datoteke -Ciljna fascikla već sadrži datoteku koja se trenutno obrađuje. -Da li želite da zamenite postojeću datoteku -sa ovom? -{0} bajtova -Automatska promena naziva -3700 -Nepodržani metod kompresije za '{0}'. -Greška u '{0}'. Datoteka je neispravana. -CRC greška u '{0}'. Datoteka je neispravana. -Greške u kodiranu datoteku '(0)' Pogrešna lozinka. -CRC greška u šifrovane datoteke '(0)' Pogrešna lozinka. -3800 -Unesite lozinku -Unesite lozinku: -Ponovo unesite lozinku: -Prikaži lozinku -Lozinke se ne poklapaju -Koristi samo engleska slova, brojeva i specijalnih znakova (!, #, $, ...) Za lozinke -Lozinka je predugačka -Šifra -3900 -Proteklo vreme: -Preostalo vreme: -Veličina: -Brzina: -Obrađeno: -Kompresioni odnos: -Greške: -Arhive: -4000 -Dodaj u arhivu -Arhiva: -Nadogradnja arhiva: -Format arhive: -Nivo kompresije: -Tip kompresije: -Dictionary size: -Word size: -Veličina čvrstog bloka: -Broj niza procesora: -Parametri: -Opcije -Kreiraj SFX arhivu -Kompresija deljene datoteka -Šifrovanje -Metoda šifrovanja: -Šifruj nazive datoteka -Potrebna memorija - kompresija: -Potrebna memorija - dekompresija: -4050 -Bez kompresije -Brže -Brzo -Normalno -Maksimalno -Najbrže -4060 -Dodaj i zameni datoteke -Osveži i dodaj datoteke -Ozveži postojeće datoteke -Sinhronizuj datoteke -4070 -Pregledaj -Sve datoteke -Ne-čvrste -Čvrsto -6000 -Kopiraj -Iseci -Kopiraj u: -Premesti u: -Kopiranje u toku... -Premeštanje u toku... -Preimenovanje u toku... -Izaberite odredišnu fasciklu. -Operacija nije podržana. -Greška pri preimenovanju datoteke ili fascikle -Potvrdi kopiranje datoteke -Da li ste sigurni da želite da kopirate datoteke u arhivu -6100 -Potvrdite brisanje datoteke -Potvrdite brisanje fascikle -Potvrdite višestruko brisanje datoteka -Jeste li sigurni da želite da obrišete '{0}'? -Jeste li sigurni da želite da obrišete fasciklu '{0}' i sav njen sadržaj? -Jeste li sigurni da želite da obrišete ove {0} podatke? -Brisanje u toku... -Greška pri brisanju datoteke ili fascikle -Sistem ne može da premesti datoteku sa dugom putu u korpu za otpatke -6300 -Kreiraj fasciklu -Kreiraj datoteku -Ime fascikle: -Ime datoteke: -Nova fascikla -Nova datoteka -Greška pri kreiranju fascikli -Greška pri kreiranju datoteka -6400 -Komentar -Komentar: -Odaberi -Poništi izbor -Maska: -6600 -Osobine -Hronologija -Dijagnostičke poruke -Poruke -7100 -Računar -Mreža -Dokumenti -Sistem -7200 -Dodaj -Izdvoj -Testiraj -Kopiraj -Premesti -Izbriši -Svojstva -7300 -Podeli datoteku -Podeli na: -Podeli na delove, bajti: -Podela... -Potvrda podele -Da li ste sigurni da želite da podelite datoteku na (0) dela? -Veličine dela mora biti manji od veličine originalne datoteke -Neispravna veličina volumena -Određena veličina volumena: {0} bajtova.\nDa li ste sigurni da želite da podelite arhivu u tih volumena? -7400 -Sastavi datoteke -Sastavi u: -Spajanje... -Izaberite samo prvi deo podele datoteke -Ne mogu da otkrijem datoteku kao deo podele -Ne može se naći više od jednog dela podele -7500 -Izračunavanje proverne veličine... -Informacija o proverne veličine -CRC porvera za podatak: -CRC provera za podatak i imena: -7600 -Benchmark -Korišćenje memorije: -Kompresija -Dekompresija -Ocena -Potpuna ocena -Trenutno -Rezultat -Upotreba procesora -Rejting/Upotreba -Prolazi: diff -Nru p7zip-rar-16.02/GUI/Lang/sv.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/sv.txt --- p7zip-rar-16.02/GUI/Lang/sv.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/sv.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; : Andreas M Nilsson, Christoffer Enqvist -; 4.59 : Bernhard Eriksson -; -; -; -; -; -; -; -; -; -0 -7-Zip -Swedish -Svenska -401 -OK -Avbryt - - - -&Ja -&Nej -&Stäng -Hjälp - -F&ortsätt -440 -Ja till &Alla -Nej till A&lla -Stopp -Starta om -&Bakgrunden -&Förgrunden -&Pausa -Pausad -Är du säker på att du vill avbryta? -500 -&Arkiv -&Redigera -&Visa -&Favoriter -Verkt&yg -&Hjälp -540 -&Öppna -Öppna &internt -Öppna &externt -&Visa -&Redigera -&Byt namn -&Kopiera till... -&Flytta till... -&Ta bort -&Dela upp fil... -&Sätt ihop filer... -E&genskaper -Komme&ntera -Beräkna checksumma - -Skapa mapp -Skapa fil -&Avsluta -600 -Markera &alla -Avmarkera alla -&Invertera markering -Markera... -Avmarkera... -Markera efter typ -Avmarkera efter typ -700 -St&ora ikoner -Sm&å ikoner -&Lista -&Detaljerad lista -730 -Osorterade -Platt vy -&2 Paneler -&Verktygsfält -Öppna rotmappen -Upp en nivå -Mapphistorik... -&Uppdatera -750 -Verktygsfältet Arkiv -Verktygsfältet Standard -Stora Knappar -Visa Knapptext -800 -&Lägg mappen till Favoriter som -Bokmärke -900 -&Alternativ... -&Benchmark -960 -&Innehåll... -&Om 7-Zip... -1003 -Sökväg -Namn -Filändelse -Mapp -Storlek -Storlek komprimerad -Attribut -Skapad -Använd -Ändrad -Sammanhängande (Solid) -Kommenterad -Krypterad -Delad före -Delad efter -Ordlista -CRC -Typ -Anti -Metod -Värd OS -Filsystem -Användare -Grupp -Block -Kommentar -Position -Sökvägs prefix -Kataloger -Filer -Version -Volym -Multivolym -Offset -Länkar -Block -Volymer - -64-bitars -Big-endian -CPU -Fysisk storlek -Storlek på header -Checksumma -Karakteristisk -Virtuell adress - - - - - - -Fel -Total Storlek -Ledigt utrymme -Kluster storlek -Etikett -Datornamn -Nätverkstyp -2100 -Alternativ -Språk -Språk: -Redigerare -&Redigerare: - -2200 -System -Associera med 7-Zip: -2301 -Lägg till 7-Zip som alternativ i Utforskarens högerklicksmenyn -Placera 7-Zip som en undermeny -Objekt i högerklicksmenyn: -2320 - - -Öppna -Packa upp filer... -Lägg till arkiv... -Kontrollera arkivet -Packa upp här -Packa upp till {0} -Lägg till {0} -Komprimera och skicka som e-post... -Komprimera till {0} och skicka som e-post -2400 -Mappar -&Arbetsmapp -&Systemets temp-mapp -A&ktuell -Spe&cificerad: -Använd enbart för &flyttbara enheter -Ange plats där temporära arkivfiler ska sparas. -2500 -Inställningar -Visa ".." objektet -Visa riktiga ikoner, för filer innehållande ikoner (el. länkade) -Visa system-menyn -Markera &hel rad -Visa &rutnät - -&Alternativt markeringsläge -Använd &stora minnessidor -2900 -Om 7-Zip -7-Zip är fri programvara. Du kan emellertid stödja den fortsatta utvecklingen av 7-Zip genom att donera. Den aktuella översättningen på svenska är gjord av Wermlandsdata, baserad på arbete utfört av Andreas M Nilsson och Christoffer Enqvist. -3000 -Systemet kan inte allokera den begärda minnesmängden -Inga fel påträffades -{0} objekt markerade -Kan inte skapa mapp '{0}' -Uppdatering stöds inte för det här arkivet. -Kan inte öppna filen '{0}' som ett arkiv -Kan inte öppna det krypterade arkivet '{0}'. Fel lösenord? -Arkiv typen stöds ej -Filen {0} existerar redan -Filen '{0}' har blivit ändrad.\nVill du uppdatera den i arkivet? -Kan inte uppdatera filen\n'{0}' -Kan inte starta redigeraren. -Filen verkar vara ett virus (filnamnet innehåller 'långa' mellanslag). -Operation kan inte utföras från en katalog med en så lång sökväg. -Du måste välja en fil -Du måste välja en eller flera filer -För många objekt -3300 -Packar upp -Komprimerar -Kontrollerar -Öppnar... -Skannar... -3400 -Packa upp -&Packa upp till: -Ange sökväg för uppackade filer. -3410 -&Sökvägstyp -Kompletta sökvägar -Inga sökvägar -3420 -&Överskrivning -Fråga före överskrivning -Skriv över befintliga filer -Hoppa över befintliga filer -Automatisk omdöpning -Automatisk omdöpning av befintliga filer -3500 -Bekräfta överskrivning av fil -Målmappen innehåller redan den behandlade filen. -Vill du skriva över den befintliga filen -med den här? -{0} bytes -A&utomatisk omdöpning -3700 -Komprimeringsmetoden stöds inte för '{0}'. -Datafel i '{0}'. Filen är korrupt. -CRC-fel i '{0}'. Filen är korrupt. -Datafel i den krypterade filen '{0}'. Fel lösenord? -CRC-fel i den krypterade filen '{0}'. Fel lösenord? -3800 -Ange lösenord -Ange lösenord: -Upprepa lösenord: -&Visa lösenord -Lösenorden stämmer inte överens. -Använd endast engelska tecken, siffror och special tecken (!, #, $, ...) till lösenord -Lösenordet är för långt. -&Lösenord -3900 -Förfluten tid: -Återstående tid: -Storlek: -Hastighet: -Bearbetat: -Komprimeringsgrad: -Fel: -Arkiv: -4000 -Lägg till arkiv -&Arkiv: -&Uppdateringsmetod: -Arkiv&format: -Komprimeringsniv&å: -&Komprimeringsmetod: -Storlek på &ordlista: -Storlek på o&rd: -Solit block storlek: -Antal trådar: -&Parametrar: -Alternativ -Skapa sj&älvuppackande arkiv -Komprimera delade filer -Kryptering -Krypteringsmetod: -Kryptera fil&namn -Minne behövt vid komprimering: -Minne behövt vid dekomprimering: -4050 -Okomprimerat -Snabbaste -Snabb -Normal -Maximal -Ultra -4060 -Lägg till och ersätt filer -Lägg till och uppdatera befintliga filer -Uppdatera enbart befintliga filer -Synkronisera filer -4070 -Bläddra -Alla filer -Icke-solit -Solit -6000 -Kopiera -Flytta -Kopiera till: -Flytta till: -Kopierar... -Flyttar... -Döper om... -Välj målmapp. -Funktionen stöds inte. -Ett fel uppstod under omdöpning av fil eller mapp -Bekräfta kopiering av fil -Är du säker på att du vill kopiera filerna till arkivet -6100 -Bekräfta borttagning av fil -Bekräfta borttagning av mapp -Bekräfta borttagning av flera filer -Är du säker på att du vill ta bort '{0}'? -Är du säker på att du vill ta bort mappen '{0}' och allt dess innehåll? -Är du säker på att du vill ta bort de här {0} objekten? -Tar bort... -Ett fel uppstod under borttagning av fil eller mapp -Systemet kan inte flytta en fil med s lng skvg till papperskorgen -6300 -Skapa mapp -Skapa fil -Mappnamn: -Filnamn: -Ny mapp -Ny fil -Fel vid skapande av mapp -Fel vid skapande av fil -6400 -Kommentar -&Kommentar: -Markera -Avmarkera -Filter: -6600 -Egenskaper -Mapphistorik -Diagnostiska meddelanden -Meddelande -7100 -Dator -Nätverk -Dokument -System -7200 -Lägg till -Packa upp -Testa -Kopiera -Flytta -Radera -Info -7300 -Dela Upp Fil -&Dela upp till: -Dela upp i &delar (volymer), bytes: -Delar upp... -Bekräfta uppdelning -Är det säkert du vill dela upp filen i {0} volymer? -Volymstorleken måste vara mindre än storleken på originalfilen. -Felaktig volymstorlek. -Specificerad volymstorlek: {0} byte.\nÄr du säker du vill dela arkivet i sådana delar? -7400 -Sätt Ihop Filer -&Sätt ihop till: -Sätter ihop... -Markera bara första filen -Kan inte upptäcka att filen är en del av en uppdelad fil -Kan inte hitta mer än en del av en uppdelad fil -7500 -Beräknar checksumma... -Checksumma information -CRC checksumma för data: -CRC checksumma för data och namn: -7600 -Benchmark -Minnesanvändning: -Komprimering -Dekomprimering -Prestanda -Total prestanda -Aktuellt -Resultat -CPU Användning -Rate / Användning -Omgångar: diff -Nru p7zip-rar-16.02/GUI/Lang/ta.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ta.txt --- p7zip-rar-16.02/GUI/Lang/ta.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ta.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 3.13 : Ve Elanjelian : ThamiZha! team : www.thamizha.com -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Tamil -தமிழ் -401 -சரி -இரத்து - - - -ஆம் -வேண்டாம் -மூடு -உதவி - -தொடரவும் -440 -அனைத்திற்கும் ஆம் -அனைத்திற்கும் இல்லை -நிறுத்து -மீள்துவங்கு -பின்புலம் -முன்புலம் -தற்காலிகமாக நிறுத்து -தற்காலிக நிறுத்தல் -உறுதியாகவே இரத்து செய்ய விரும்புகிறீர்களா? -500 -கோப்பு -பதிப்பு -பார்வை -விருப்பங்கள் -கருவிகள் -உதவி -540 -திற -உள்ளே திற -வெளியே திற -பார்வை -பதிப்பு -மாற்றுப்பெயரிடு -இங்கு நகலெடு... -இங்கு நகர்த்து... -அழி - - -தன்மைகள் -கருத்துரை - - -கோப்பை உருவாக்கு -கோப்பு உருவாக்கு -வெளியேறு -600 -அனைத்தும் தேர்ந்தெடு -அனைத்தும் நீக்கு -தெரிவை புரட்டு -தேர்ந்தெடு... -நீக்கு... -வகைப்படி தெரிவுசெய் -வகைப்படி நீக்கு -700 -பெரிய உருபிகள் -சிறிய உருபிகள் -பட்டியல் -தகவல்கள் -730 -வரிசைப்படுத்தப்படாதது - -2 பலகங்கள் -கருவிப்பட்டைகள் -வேர் அடைவைத் திற -ஒரு படி மேல் -அடைவுகளின் வரலாறு... -புதுக்கல் -750 -காப்பக கருவிப்பட்டை -பொதுவான கருவிப்பட்டை -பெரிய பொத்தான்கள் -பொத்தான்களின் உரையைக் காட்டு -800 -அடைவை விரும்பியவற்றுள் இப்படி இணை -புத்தகக்குறி -900 -விருப்பத்தேர்வு... -மதிப்பீட்டு அளவை -960 -பொருளடக்கம்... -7-ஜிப்பைப் பற்றி... -1003 -பாதை -பெயர் -நீட்டிப்பு -அடைவு -அளவு -கட்டப்பட்ட அளவு -பண்புக்கூறு -உருவாக்கப்பட்டது -அனுகப்பட்டது -மாற்றப்பட்டது -திண்மம் -கருத்துரைக்கப்பட்ட -மறைக்குறியீட்டப்பட்டது -முன் பிரி -பின் பிரி -அகராதி -CRC -வகை -தடுப்பு -வழி -புரவலரின் OS -கோப்பு மண்டலம் -பயனர் -குழு -கட்டம் -குறிப்பு - - - - - - - - - - - - - - - - - - - - - - - - - - -தவறு -மொத்த அளவு -காளி இடம் -கொத்தணியின் அளவு -வில்லை -இடத்துரி பெயர் -வழங்குபவர் -2100 -தேர்வுகள் -மொழி -மொழி: -பதிப்பாளன் -பதிப்பாளன்: - -2200 -மண்டலம் -7-ஜிப்பை இதனுடன் தொடர்புப்படுத்து: -2301 -7-ஜிப்பை வெற்று சூழல்பட்டியலுடன் ஒருங்கிணை -விழுதொடரும் சூழல் பட்டியல் -சூழல் பட்டியல் உருப்படிகள்: -2320 -<அடைவு> -<காப்பகம்> -காப்பகத்தைத் திற -கோப்புகளை வெளிக்கொணர்... -காப்பகத்தில் இணை... -காப்பகத்தைச் சோதனைசெய் -இங்கு வெளிக்கொணர் -{0}-ல் வெளிக்கொணர் -{0}-ல் இணை -இறுக்கி மின்னஞ்சலனுப்பு... -{0}-க்கு இறுக்கி அஞ்சலனுப்பு -2400 -அடைவுகள் -பணியிலுள்ள அடைவு -மண்டல தற்காலிக அடைவு -நடப்பு -குறிப்பிட்ட: -கழற்று இயக்கிகளை மட்டும் பயன்படுத்து -கோப்புகளைத் தற்காலிக காப்பகப்படுத்தும் இடத்தைக் குறிப்பிடுக. -2500 -அமைவுகள் -".." உருப்படியைக் காட்டு -கோப்பு உருபிகளைக் காட்டு -மண்டல பட்டியலைக் காட்டு - - - - - -2900 -7-ஜிப்பைப் பற்றி -தமிழாக்கம் (c) 2004 தமிழா! குழு - www.thamizha.com/\n\n7-ஜிப் ஒரு பரிநிரல் ஆகும். ஆனால், நீங்கள் 7-ஜிப்பின் மேம்பாட்டை ஆதரிக்க விரும்பினால், பதிவுபெற்றுங்கள். பதிவுபெற்ற பயனராக, நீங்கள் தொழில்நுட்ப உதவியும் பெறலாம். -3000 - -தவறுகளேதுமில்லை -{0} பொருள் தெரிவானது -'{0}' அடைவை உருவாக்க இயலவில்லை -இக்காப்பகத்தில் புதுப்பிக்கும் செயல்களுக்கு ஆதரவில்லை. - - - - -'{0}' கோப்பு மாற்றப்பட்டது.\nஇதனை காப்பகத்தில் புதுப்பிக்க வேண்டுமா? -பின்வரும் கோப்பை புதுப்பிக்க இயலவில்லை\n'{0}' -பதிப்பாளனைத் துவக்க இயலவில்லை. - - - - -மிகவும் அதிகமான உருப்படிகள் -3300 -வெளிக்கொணரப்படுகின்றது -இறுக்கப்படுகின்றது -சோதனை... -திறக்கப்படுகின்றது... - -3400 -வெளிக்கொணர் -இங்கு வெளிக்கொணர்: -வெளிக்கொணர்ந்த கோப்புகளுக்கான இடத்தைக் குறிப்பிடு. -3410 -பாதை முறைமை -முழு பாதைப்பெயர்கள் -பாதைப்பெயர்களில்லை -3420 -மேலெழுதல் முறைமை -மேலெழுதுவதற்கு முன் கேள் -கேட்காமல் மேலெழுது -தற்பொழுதுள்ள கோப்புகளைத் தவிர் -தானாக மாற்றுப்பெயரிடு - -3500 -கோப்பு மாற்றத்தை உறுதிசெய் -சேரிட அடைவு ஏற்கனவே செயல்படுத்தப்பட்ட கோப்பைக் கொண்டுள்ளது. -தற்பொழுதுள்ள கோப்பை -இதக்கொண்டு மாற்ற விரும்புகிறீர்களா? -{0} பைட்கள் -தானாக மாற்றுப்பெயரிடு -3700 -'{0}'-ல் ஆதரவில்லாத இறுக்கல் முறை. -'{0}'-ல் தரவுத் தவறு. கோப்பு முறிந்துள்ளது. -'{0}'-ல் CRC தோல்வியுற்றது. கோப்பு முறிந்துள்ளது. - - -3800 -கடவுச்சொல்லை உள்ளிடுக -கடவுச்சொல்லை உள்ளிடுக: - -கடவுச்சொல்லை காட்டு - - - -கடவுச்சொல் -3900 -மீதமுள்ள நேரம்: -மீதமுள்ள நேரம்: -அளவு: -வேகம்: - - -தவறுகள்: - -4000 -காப்பகத்திலிணை -காப்பகம்: -புதுபிக்கும் முறைமை: -காப்பக வடிவம்: -இறுக்க வகை: -இறுக்கும் வழி: -அகராதி அளவு: -வார்த்தை அளவு: - - -அளபுருகள்: -விருப்பத்தேர்வுகள் -SFX காப்பகம் உறுவாக்கு - - - -பெயரை மறைக்குறியீடாக்கு -இறுக்க நினைவக பயன்பாடு: -பெருக்க நினைவக பயன்பாடு: -4050 -தேக்கு -அதிவிரைவான -விரைவான -சாதாரண -அதிகமான -சிறப்பான -4060 -சேர்த்து கோப்புகளை மாற்று -புதிப்பித்து கோப்புகளை சேர் -உள்ள கோப்புகளைப் புதுப்பி -கோப்புகளை ஒத்தியக்கு -4070 -உலாவு -அனைத்து கோப்புகளும் - - -6000 -நகல் -நகர்த்து -இங்கு நகலெடு: -இங்கு நகர்த்து: -நகலெடுக்கப்படுகிறது... -நகர்த்தப்படுகிறது... -பெயர்மாற்றப்படுகிறது... - -அத்தகைய செயலுக்கு ஆதரவில்லை. -கோப்பையோ அடைவையோ பெயர்மாற்றும்போது தவறு - - -6100 -கோப்பு அழிப்பை உறுதிசெய் -அடைவு அழிப்பை உறுதிசெய் -பல கோப்பு அழிப்பை உறுதிசெய் -'{0}'-ஐ உறுதியாக அழிக்க விரும்புகிறீர்களா? -'{0}' அடைவையும் அதிலுள்ளவற்றயும் உறுதியாகவே அழிக்க விரும்புகிறீர்களா? -இந்த {0} உருப்படிகளை உறுதியாக அழிக்க விரும்புகிறீர்களா? -அழிக்கப்படுகிறது... -கோப்பையோ அடைவையோ அழிக்கும்போது தவறு - -6300 -அடைவு உருவாக்கு -கோப்பு உருவாக்கு -அடைவின் பெயர்: -கோப்பின் பெயர்: -புதிய அடைவு -புதிய கோப்பு -அடைவு உருவாக்கும்போது தவறு -கோப்பு உருவாக்கையில் தவறேற்பட்டது -6400 -கருத்துரை -கருத்துரை: -தெரிவுசெய் -நீக்கு -முகமுடி: -6600 - -அடைவுகளின் வரலாறு -அறிவழிச் செய்திகள் -செய்தி -7100 -கணினி -பிணையம் - -மண்டலம் -7200 -இணை -வெளிக்கொணர் -பரிசோதி -நகல் -நகர்த்து -அழி -தகவல் -7300 - - -கனவளவுகளுக்கு, பைட்களுக்குப் பிரி: - - - - - - -7400 - - - - - - -7500 - - - - -7600 -மதிப்பீட்டு அளவை -நினைவக பயன்: -இறுக்கப்படுகையில் -பெருக்கப்படுகையில் -புள்ளிகள் -மொத்த புள்ளிகள் -நடப்பு -முடிவில் - - -சரியானவை: diff -Nru p7zip-rar-16.02/GUI/Lang/th.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/th.txt --- p7zip-rar-16.02/GUI/Lang/th.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/th.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.09 : Chayanon Ruamcharoen -; 4.10 : Zafire06 -; 9.13 : Kom10 -; -; -; -; -; -; -; -; -0 -7-Zip -Thai -ไทย -401 -ตกลง -ยกเลิก - - - -&ใช่ -&ไม่ -&ออก -ช่วยเหลือ - -&ดำเนินการต่อ -440 -ใช่ทั้งหมด -ไม่ทั้งหมด -หยุด -ฟื้นฟู -&ทำงานเป็นพื้นหลัง -&ทำงานเป็นพื้นหน้า -&หยุดชั่วคราว -หยุดชั่วคราว -คุณแน่ใจหรือว่าจะยกเลิก -500 -&แฟ้ม -&แก้ไข -&มุมมอง -&รายการโปรด -&เครื่องมือ -&ช่วยเหลือ -540 -&เปิด -เปิดในหน้าต่างเดิม -เปิดในหน้าต่างใหม่ -&มุมมอง -&แก้ไข -&เปลี่ยนชื่อ -&คัดลอกไปที่... -&วางที่... -&ลบ -&แยกไฟล์... -รวมไฟล์... -&คุณสมบัติ -&หมายเหตุ -คำนวณ checksum -Diff -สร้างโฟลเดอร์ -สร้างไฟล์ -ออก -600 -เลือกทั้งหมด -ยกเลิกการเลือกทั้งหมด -&สลับการเลือกให้เป็นตรงกันข้าม -เลือก... -ยกเลิกการเลือก... -เลือกด้วยแบบชนิด -ยกเลิกการเลือกด้วยแบบชนิด -700 -&ไอคอนขนาดใหญ่ -&ไอคอนขนาดเล็ก -&แสดงเป็นรายการ -&แสดงแบบละเอียด -730 -ไม่เลือก -แสดงไฟล์และโฟลด์เดอร์ทั้งหมด -&แสดง 2 แผง -&แถบเครื่องมือ -เปิดรากโฟลเดอร์ -เลื่อนขึ้นหนึ่งระดับ -ประวัติโฟลเดอร์... -&ฟื้นฟู -750 -แถบเครื่องมือเอกสาร -แถบเครื่องมือธรรมดา -ปุ่มขนาดใหญ่ -แสดงข้อความบนปุ่ม -800 -&เพิ่มโฟลเดอร์เข้ารายการโปรด -คั่นหน้าที่ -900 -&ตัวเลือก... -&เกณฑ์เปรียบเทียบสมรรถนะ -960 -&เนื้อหาและดัชนี... -&เกี่ยวกับ 7-Zip... -1003 -ที่ตั้ง -ชื่อ -ชนิด -โฟลเดอร์ -ขนาด -ขนาดเมื่อถูกจัดเก็บ -ลักษณะประจำ -สร้างเมื่อ -เข้าถึงเมื่อ -ดัดแปรเมื่อ -ต่อเนื่อง -หมายเหตุ -การเข้ารหัสลับ -ก่อนแบ่ง -หลังแบ่ง -ดิคชันนารี -ซีอาร์ซี -แบบชนิด -ต่อต้าน -วิธีการ -OS ที่ใช้ -ไฟล์ระบบ -ผู้ใช้ -กลุ่ม -บล็อก -หมายเหตุ -ตำแหน่ง -คำนำหน้าที่ตั้ง -โฟลเดอร์ -ไฟล์ -เวอร์ชั่น -วอลลุ่ม -มัลติวอลลุ่ม -ออฟเซ็ท -ลิ้งค์ -บล็อค -Volumes - -64-บิท -Big-endian -CPU -ขนาดทางกายภาพ -ขนาดเฮดเดอร์ -Checksum -คุณลักษณะ -Virtual Address -ID -ชื่อย่อ -ผู้สร้างโปรแกรม -ขนาด Sector -โหมด -ลิงค์ -เกิดข้อผิดพลาด -ขนาดทั้งหมด -ช่องว่างที่เหลืออยู่ -ขนาดกลุ่ม -ป้าย -ชื่อเฉพาะ -ผู้ให้บริการ -2100 -ตัวเลือก -ภาษา -ภาษา: -บรรณาธิกรณ์ -&บรรณาธิกรณ์: -&Diff: -2200 -ระบบ -ทำให้ 7-Zip ทำงานร่วมกับ: -2301 -รวบรวมคำสั่ง 7-Zip ไปที่แถบเมนูลัด -แยกเป็นแถบคำสั่ง 7-Zip -วัตถุที่ปรากฏบนเมนูลัด: -2320 -<โฟลเดอร์> -<เอกสาร> -เปิดเอกสาร -แยกไฟล์... -เพิ่มเข้าเอกสาร... -ทดสอบเอกสาร -แยกไฟล์ที่นี่ -แยกไฟล์ไปที่ {0} -เพิ่มเข้า {0} -บีบอัดแล้วส่งอีเมลล์... -บีบอัดเป็น {0} แล้วส่งอีเมลล์ -2400 -โฟลเดอร์ -&โฟลเดอร์ที่ทำงานอยู่ -&โฟลเดอร์ต่างๆของระบบ -&โฟลเดอร์ปัจจุบัน -&ระบุ: -ใช้สำหรับไดรฟ์แบบถอดได้เท่านั้น -ระบุที่ตั้งสำหรับไฟล์เอกสารชั่วคราว -2500 -กำหนด -แสดงวัตถุ ".." -แสดงไอคอนไฟล์ที่แท้จริง -แสดงเมนูระบบ -&เลือกเต็มแถว -แสดง &เส้นกริด -คลิกครั้งเดียวเพื่อเปิดไฟล์ -&โหมดการเลือกอื่น -ใช้ &เพจความจำขนาดใหญ่ -2900 -เกี่ยวกับ 7-Zip -7-Zip เป็นฟรีแวร์ อย่างไรก็ตาม คุณสามารถสนับสนุนการพัฒนาของ 7-Zip ได้โดยการลงทะเบียน เมื่อคุณเป็นผู้ใช้ที่ลงทะเบียนแล้ว คุณจะได้รับการสนับสนุนทางเทคนิคจากเรา -3000 -ระบบไม่สามารถใช้หน่วยความจำตามที่ระบุได้ -ไม่มีข้อผิดพลาด -{0} วัตถุที่เลือกไว้ -ไม่สามารถสร้างโฟลเดอร์ '{0}' -ปรับปรุงการทำงานไม่สนับสนุนสำหรับเอกสาร -ไม่สามารถเปิดไฟล์ '{0}' เป็นเอกสารได้ -ไม่สามารถเปิดไฟล์ที่เข้ารหัสได้ '{0}' พาสเวิร์ดผิดหรือไม่? -ชนิดของไฟล์บีบอัดไม่รองรับ -ไฟล์ {0} มีอยู่แล้ว -ไฟล์ '{0}' ได้ถูกดัดแปรแล้ว\nคุณต้องการจะปรับปรุงเอกสารหรือไม่ -ไม่สามารถปรับปรุงไฟล์\n'{0}' -ไม่สามารถเปิดตัวแก้ไขได้ -ไฟล์อาจเป็นไวรัส (ชื่อไฟล์มีช่องว่างยาว) -ไม่สามารถดำเเนินการได้จากโฟลเดอร์ที่มีที่ตั้งยาว -ท่านต้องเลือกไฟล์ -ท่านต้องเลือกไฟล์หนึ่งไฟล์หรือมากว่า -มีวัตถุมากเกินไป -3300 -กำลังแยกไฟล์ -กำลังบีบอัด -กำลังทดสอบ -กำลังเปิด... -กำลังสแกน... -3400 -แยกไฟล์ -แยกไฟล์ไปที่: -ระบุที่ตั้งสำหรับไฟล์ที่แยกออกมา -3410 -ที่ตั้ง -ชื่อที่ตั้งแบบเต็ม -ไม่มีชื่อที่ตั้ง -3420 -การบันทึกทับ -ถามก่อนมีการบันทึกทับ -บันทึกทับโดยไม่มีข้อความพร้อมรับ -ข้ามไฟล์ที่มีอยู่ -เปลี่ยนชื่ออัตโนมัติ -เปลี่ยนชื่อไฟล์ที่มีอยู่อัตโนมัติ -3500 -ยืนยันการแทนที่ไฟล์ -โฟลเดอร์ปลายทางมีไฟล์ที่ได้ประมวลผลแล้ว -คุณต้องการแทนที่ไฟล์ที่มีอยู่หรือไม่ -ด้วย -{0} ไบต์ -เปลี่ยนชื่ออัตโนมัติ -3700 -ไม่รองรับวิธีการบีบอัดนี้สำหรับ '{0}' -ข้อมูลใน '{0}' ผิดพลาด ไฟล์ชำรุด -ซีอาร์ซีใน '{0}' ไม่สามารถใช้การได้ ไฟล์ชำรุด -ข้อมูลในไฟล์บีบอัด '{0}' ผิดพลาด รหัสผ่านไม่ถูกต้อง? - -3800 -ใส่รหัสผ่าน -ใส่รหัสผ่าน: -ใส่รหัสผ่านอีกครั้ง: -&แสดงรหัสผ่าน -รหัสผผ่านไม่ตรง -ตั้งรหัสผ่านด้วยอักษรภาษาอังกฤษ หรืออักขระ (!, #, $, ...) -รห้สผ่านยาวเกินไป -รหัสผ่าน -3900 -ใช้เวลาไปแล้ว: -ต้องใช้เวลาอีก: -ขนาด: -ความเร็ว: -ดำเนินการแล้ว: -อัตราส่วนการบีบอัด: -ความผิดพลาด: -เอกสาร: -4000 -เพิ่มเข้าเอกสาร -&เอกสาร: -&การปรับปรุง: -รูปแบบการบีบอัดที่ต้องการใช้: -อัตราการบีบอัด: -&วิธีการบีบอัด: -&ขนาดดิคชันนารี: -&ขนาดอักษร: -ขนาด Solid block: -จำนวน CPU threads: -&พารามิเตอร์: -ตัวเลือก -สร้างเอกสาร SFX -บีบอัดแชร์ไฟล์ -การเข้ารหัส -วิธีการเข้ารหัส: -สร้างรหัสผ่าน -หน่วยความจำที่ใช้ในการบีบอัด: -หน่วยความจำที่ใช้ในการแตกออก: -4050 -เก็บเฉยๆ -เร็วที่สุด -เร็ว -ปกติ -ดี -ดีที่สุด -4060 -เพิ่มและแทนที่ไฟล์ -ปรับปรุงและเพิ่ม -ทำให้ไฟล์ที่มีอยู่ใช้การได้ดีขึ้น -ทำให้ไฟล์ประสานกัน -4070 -ค้นดู -ไฟล์ทั้งหมด -Non-solid -Solid -6000 -คัดลอก -ย้าย -คัดลอกไปที่: -ย้ายที่: -กำลังคัดลอก... -กำลังวาง... -กำลังเปลี่ยนชื่อ... -เลือกโฟลเดอร์ที่ตั้ง -การปฏิบัติการไม่สนับสนุน -เกิดข้อผิดพลาดในการเปลี่ยนชื่อไฟล์หรือโฟลเดอร์ -ยืนยันการคัดลอกไฟล์ -ท่านมั่นใจที่จะคัดลอกไฟล์ไปยังเอกสารหรือไม่ -6100 -ยืนยันการลบไฟล์ -ยืนยันการลบโฟลเดอร์ -ยืนยันการลบไฟล์แบบควบซ้อน -คุณแน่ใจหรือว่าคุณต้องการจะลบไฟล์ '{0}'? -คุณแน่ใจหรือว่าคุณต้องการจะลบโฟลเดอร์ '{0}' และข้อมูลของมันทั้งหมด -คุณแน่ใจหรือว่าจะลบวัตถุ {0} เหล่านี้ -กำลังลบ... -เกิดข้อผิดพลาดในการลบไฟล์หรือโฟลเดอร์ -ระบบไม่สามารถย้ายไฟล์ที่ชื่อที่ตั้งยาวไปยังถังขยะได้ -6300 -สร้างโฟลเดอร์ -สร้างไฟล์ -ชื่อโฟลเดอร์: -ชื่อไฟล์: -โฟลเดอร์ใหม่ -ไฟล์ใหม่ -เกิดข้อผิดพลาดในการสร้างโฟลเดอร์ -เหิดข้อผิดพลาดในการสร้างไฟล์ -6400 -หมายเหตุ -&หมายเหตุ: -เลือก -ยกเลิกการเลือก -ตัวพราง: -6600 -คุณสมบัติ -ประวัติโฟลเดอร์ -ข้อความวินิจฉัย -ข้อความ -7100 -คอมพิวเตอร์ -เครือข่าย -เอกสาร -ระบบ -7200 -เพิ่มเข้า -แยกไฟล์ -ทดสอบ -คัดลอก -ย้าย -ลบ -เกี่ยวกับ -7300 -แยกไฟล์ -&แยกไปยัง: -ขนาดไฟล์ที่ต้องการแบ่ง, ไบต์: -กำลังแยก... -ยืนยันการแยก -ท่านมั่นใจว่าต้องการแยกไฟล์เป็น {0} volumes? -ขนาด Volume ต้องเล็กกว่าขนาดไฟล์ต้นฉบับ -ขนาด volume ไม่ถูกต้อง -ระบุขนาด volume: {0} ไบท์.\nท่านมั่นใจว่าต้องการแบ่งไฟล์เป็น volumes ดังกล่าว? -7400 -รวมไฟล์ -&รวมไปยัง: -กำลังรวม... -เลือกเฉพาะส่วนแรกของไฟล์แยก -ไม่สามารถตรวจพบไฟล์ว่าเป็นส่วนหนึ่งของไฟล์แยก -ไม่สามารถหาไฟล์แยกได้มากหนึ่ง -7500 -กำลังคำนวณ Checksum... -ข้อมูล Checksum -CRC checksum ของข้อมูล: -CRC checksum ของข้อมูลและชื่อ: -7600 -เกณฑ์เปรียบเทียบสมรรถนะ -หน่วยความจำที่ใช้: -การบีบอัด -การยกเลิกบีบอัด -เกณฑ์ความสามารถ -เกณฑ์ความสามารถทั้งหมด -ปัจจุบัน -ผลการประเมิน -การใช้งาน CPU -ประสิทธิภาพ /การใช้งาน -ข้อความ: diff -Nru p7zip-rar-16.02/GUI/Lang/tr.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/tr.txt --- p7zip-rar-16.02/GUI/Lang/tr.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/tr.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : 2009-09-22 : X-FoRcE -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Turkish -Türkçe -401 -Tamam -İptal - - - -&Evet -&Hayır -&Kapat -Yardım - -De&vam et -440 -Tümüne E&vet -Tümüne Ha&yır -Dur -Tekrar başlat -&Arka planda -Ö&nde -&Duraklat -Duraklatıldı - -İptal edilsin mi? -500 -&Dosya -Dü&zenle -Gö&rüntüle -Sı&k Kullanılanlar -&Araçlar -&Yardım -540 -&Aç -Pa&nelde Aç -Pence&rede Aç -&Görüntüle -Dü&zenle -Yeni a&d ver -K&opyala -&Taşı -&Sil -&Parçala... -&Birleştir... -Öz&ellikler -Açıkla&ma -Toplam checksum hesapla -Fark -Yeni k&lasör -Yeni dos&ya -Çı&k -600 -&Tümünü seç -Tüm seçimi ka&ldır -&Aksini seç -Seç... -Seçimi kaldır... -Bu uzantıyı seç -Uzantılı seçimi kaldır -700 -&Büyük Simgeler -&Küçük Simgeler -&Liste -&Detaylar -730 -Sırasız -Düz Görünüm -&2 Panel aç -&Araç çubukları -Kök Klasörü Aç -Bir Seviye Yukarı -Klasör Geçmişi... -&Yenile -750 -Arşiv çubuğu -Standart çubuk -Büyük düğmeler -Düğme metinleri görünsün -800 -Geçerli &klasörü ekle -Yer -900 -&Seçenekler... -&Performans ölçümü -960 -İç&indekiler... -7-Zip &Hakkında... -1003 -Yol -Ad -Uzantı -Klasör -Boyut -Arşivde boyutu -Öznitelikler -Oluşturma -Erişim -Değiştirme -Katı -Açıklanmış -Şifrelenmiş -Önceki parça -Sonraki parça -Sözlük -CRC -Tür -Anti -Sıkıştırma şekli -İşletim sistemi -Dosya Sistemi -Kullanıcı -Grup -Blok -Açıklama -Konum -Yol Öneki -Klasörler -Dosyalar -Sürüm -Cilt -Çoklu Cilt -Konum -Bağlantılar -Bloklar -Ciltler - -64-bit -Big-endian -İşlemci -Fiziksel Boyut -Başlık Boyutu -Checksum -Karakteristik -Sanal Adres -ID -Kısa İsim -Oluşturan Yazılım -Kesim Boyutu -Biçim -Bağlantı -Hata -Toplam Boyut -Boş Alan -Küme Boyutu -Etiket -Yerel Ad -Sağlayıcı -2100 -Seçenekler -Dil -Dil: -Düzenleyici -Metin &düzenleyici: -&Fark: -2200 -Sistem -7-Zip ile ilişkilendir: -2301 -İçerik menülerinde 7-Zip görünsün -Kademeli içerik menüsü -İçerik menü öğeleri: -2320 - - -Arşivi aç -Dosyaları çıkart... -Arşivle... -Arşivi sına -Burada çıkart -{0} klasörüne çıkart -{0} olarak arşivle -Sıkıştırıp postala... -{0} olarak sıkıştır ve postala -2400 -Klasörler -Ça&lışma klasörü -&Sistem TEMP klasörü -&Geçerli klasör -&Belirtilen klasör: -Sadece çıkarılabilen sürücüler için kullan -Geçici arşiv dosyaları için bir yer belirleyin. -2500 -Ayarlar -".." öğesi görünsün -Gerçek dosya simgeleri görünsün -Sistem menüsü görünsün -&Tüm satır seçilsin -Tabl&o çizgileri görünsün -Öğeyi açmak için tek tıkla -&Alternatif seçim kipi -Geniş &bellek sayfaları kullan -2900 -7-Zip hakkında -7-Zip özgür bir yazılımdır. Ancak, kayıt olarak 7-zip geliştirme faaliyetine destek olabilirsiniz. -3000 -Sistem gerekli belleği ayarlayamadı -Hata yok. -{0} adet öğe seçili -'{0}' klasörü oluşturulamıyor -Bu arşiv üzerinde güncelleme yapamazsınız. -'{0}' arşiv dosyası olarak açılamıyor. -'{0}' dosyası açılamıyor. Şifreniz yanlış olabilir mi? -Desteklenmeyen arşiv tipi -Dosya {0} zaten mevcut -'{0}' dosyası değişmiş.\nArşivde güncellensin mi? -'{0}' dosyası güncellenemedi -Metin düzenleyici başlatılamadı. -Bu dosya virüs gibi görünüyor.(Dosya ismi uzun boşluk içeriyor). -The operation cannot be called from a folder that has a long path. -Bir dosya seçmelisiniz -Bir veya daha fazla dosya seçmelisiniz -Çok fazla öğe -3300 -çıkartılıyor -sıkıştırılıyor -Sınanıyor -açılıyor... -Taranıyor... -3400 -Çıkart -&Çıkartılacak yer: -Çıkartılacak dosyalar için bir yer belirleyin. -3410 -Yol adları -Tam yol adları -Yol adları olmasın -3420 -Olan dosyalar -Üzerine yazmak için sor -Sormadan üzerine yaz -Çıkartma -Arşivdekilere yeni ad ver -Olanlara yeni ad ver -3500 -Üzerine Yazma Durumu -Hedef klasörde bu adla bir dosya var. Üzerine yazılsın mı? -Mevcut dosya: -Çıkartılan dosya: -{0} bayt -&Yeni ad ver -3700 -'{0}' için sıkıştırma şekli tanınamadı. -'{0}' bozuk. (Veri hatası) -'{0}' bozuk. (CRC hatası) -Şifrelenmiş '{0}' dosyası hatalı. Şifreniz yanlış olabilir mi? -'{0}' dosyasında CRC hatası. Şifreniz yanlış olabilir mi? -3800 -Parola Girişi -Parolayı girin: -Şifre tekrarı: -Par&ola görünsün -Şifreler birbiriyle uyuşmuyor. -Şifre için İngilizce harfler, sayılar ve özel karekterden (!, #, $, ...) kullanabilirsiniz. -Şifre çok uzun -Parola -3900 -Geçen süre: -Kalan süre: -Boyut: -Hız: -İşlenen: -Sıkıştırma oranı: -Hatalı: -Arşivler: -4000 -Arşivle -&Arşiv: -&Güncelleme şekli: -Arşiv &biçimi: -Sıkıştırma dü&zeyi: -Sı&kıştırma şekli: -&Sözlük boyutu: -Ke&lime boyutu: -Aralıksız blok boyutu: -İşlemci iş parçası sayısı: -&Parametreler: -Seçenekler -Ke&ndi çıkartsın (SFX) -Paylaşılan dosyaları sıkıştır -Şifreleme -Şifreleme metodu: -Dosya adlarını şi&frele -Bellek kullanımı (Sıkıştırma): -Bellek kullanımı (Çözme): -4050 -Sıkıştırmasız -En hızlı -Hızlı -Normal -Maksimum -Ultra -4060 -Dosyaları ekle, olanları çıkart -Dosyaları ekle, eskileri güncelle -Sadece eskileri güncelle -Dosyaları eşitle -4070 -Gözat -Tüm dosyalar -Aralıklı -Aralıksız -6000 -Kopyala -Taşı -Kopyalanacak yer: -Taşınacak yer: -Kopyalanıyor... -Taşınıyor... -Dosya Adı Değiştiriliyor... -Hedef klasörü seçiniz. -Bu klasör için istenen işlem desteklenmiyor. -Dosya veya Klasör Adlandırma Hatası -Kopyalama Onayı -Dosyalar arşive kopyalansın mı -6100 -Dosya Silme Onayı -Klasör Silme Onayı -Birden Fazla Dosya Silme Onayı -'{0}' silinsin mi? -'{0}' klasörü ve içindekiler silinsin mi? -{0} silinsin mi? -Siliniyor... -Dosya veya Klasör Silme Hatası -Dosya yolu uzun olduğundan Geri Dönüşüm Kutusuna taşınamıyor -6300 -Yeni klasör -Yeni dosya -Klasör adı: -Dosya Adı: -Yeni Klasör -Yeni Dosya -Klasör Oluşturma Hatası -Dosya Oluşturma Hatası -6400 -Açıklama -&Açıklama: -Seç -Seçimi kaldır -Seçim ifadesi: -6600 -Özellikler -Klasör Geçmişi -Tanılayıcı iletiler -İleti -7100 -Bilgisayar -Ağ -Belgeler -Sistem -7200 -Arşivle -Çıkart -Sına -Kopyala -Taşı -Sil -Bilgi -7300 -Parçala -Şu &klasörde parçala: -Bayt/&cilt olarak parçala: -Parçalanıyor... -Silmeyi onaylayın -Dosyayı {0} parçaya ayırmak istediğinizden emin misiniz? -Parça büyüklüğü, orjinal dosya boyutundan küçük olmalıdır -Yanlış cilt boyutu -Belirtilen cilt boyutu: {0} bayt.\nBu boyutta ciltlere ayırmak istediğinize emin misiniz? -7400 -Birleştir -Şu &klasörde birleştir: -Birleştiriliyor... -Sadece ilk parçayı seçiniz -Parçalanan dosya tespit edilemedi -Parçalanmış dosyanın bir parçadan fazlası bulunamadı -7500 -Checksum değeri hesaplanıyor... -Checksum bilgisi -Verinin CRC değeri: -Verinin CRC değeri ve isimler: -7600 -Bilgisayar performansı -Bellek kullanımı: -Sıkıştırılıyor -Çözülüyor -Puan -Toplam Puan -Mevcut -Sonuç -İşlemci kullanımı -Puan / Kullanım -Başarılı: diff -Nru p7zip-rar-16.02/GUI/Lang/tt.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/tt.txt --- p7zip-rar-16.02/GUI/Lang/tt.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/tt.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.16 : Amychok : (Ne laŭdiĝu ke vi scias multajn lingvojn hontu ke vi ne scias patran lingvon) -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Tatar -Татарча -401 -Ярый -Юкка чыгару - - - -&Әйе -Юк& -&Ябырга -Ярдәм - -&Бару -440 -&Барысынга әйе -Барысынга юк -Стоп -Яңадан -&Җирлектә -&Алга -&Тыныш -Тынышта -Сезгә чынлап киләме операцияне өзәргә? -500 -&Файл -&Төзәтү -&Кыяфәт -&Сайланма -&Кораллар -&Белешмә -540 -&Ачырга -&Ачырга эчендә -&Ачырга тышында -&Карау -&Редакцияләү -Исе&м үзгәрү -&Кабатларга монда... -&Күчәрергә монда... -&Бетерергә -&Ватырга файлны... -Берләштерергә &файлларны... -&Үзлекләр -&Аңлатма -Тикшерү җыелма -Diff -&Ясарга папканы... -&Ясарга файлны... -&Чыгу -600 -&Сайларга бөтенесене -Сайлануны алырга -&Сайлануны әйләндерергә -Сайларга -Сайлануны алырга -Сайларга төр буенча -Алырга сайлануны төр буенча -700 -&Зур галәмәтләр -&Вак галәмәтләр -&Исемлек -&Җәдвәл -730 -Сортлаусыз -Яссы тарыз -&2 тәрәзә -&Кораллар тактасы -Ачырга тамыр папканы -Бер дәрәҗәгә өскәрәк -Элеккеге папкалар... -&Яңартырга -750 -Архивчының кнопкалар тактасы -Кнопкаларның стандарт тактасы -Зур кнопкалар -Язмалар кнопкаларда -800 -&Өстәрге папканы сайланмага, көбәк: -Китап битбилге -900 -&Көйләр... -&Җитештерүчәнлекне cыналу -960 -&Эчтәлек... -7-Zip &турында... -1003 -Юл -Исем -Киңәеш -Папка -Зурлык -Кысык -Үзенчәлекләр -Ясалган -Ачылган -Үзгәртелгән -Бөтен -Аңлатма -Шифрланган -Ватылган моңа кадәр -Аннан соң ватылган -Сүзлек -CRC -Төр -Каршы -Ысул -Система -Файл система -Кулланучы -төркем -Блок -Тәфсир -Торыш -Юл -Папка -Файл -Сүрүм -Том -Күп томлы -Күченү -Сылтамалар -Блок -Том - -64-бит -Big-endian -Барыштыручы -Физик Зурлыгы -Сәрләүхәрнең зурлыгы -тикшерү җыелма -Сыйфатламалар -Санал Адресы -ID -Кыска Исеме -Ясаучы -Бүлемтекнең Зурлыгы -Тарыз -Сылтама -Ялгыш -Сыемлык -Буш -Күмәк зурлыгы -Тамга -Урындагы исеме -Җибәрүче -2100 -Көйләр -Тел -Тел: -Мөхәрир -&Мөхәрир: -&Diff: -2200 -Система -7-Zip бәйләргә: -2301 -Тыгарга 7-Zip'ны ярының контекст менюга -Каскадлы контекст меню -Баглам меню гонсырлар: -2320 -<Папка> -<Архив> -Архив ачу -Чишү -Архивка өстәрге -Сынарга -Чишенергә монда -Чишенергә: {0}' папкага -Өстәрге: {0}ка -Кысып җибәрергә e-mail аша... -Кысып {0}ка, җибәрергә e-mail аша -2400 -Папкалар -&Эш папка -&Системаның вакытлы папкасы -&Агымдагы -&Күрсәтергә: -Файдаланырга алмаш таратучылар өчен генә -Сайлагыз урыны вакытлы архивларга -2500 -Көйләр -Күрсәтергә гонсырны".." -Күрсәтергә чынбарлык файлларның сынчыкларны -Күрсәтергә систем меню -Күрсәткечне бөтен юлга -Күрсәтергә бүлгечләрне -Ачырга чиртү белән -Альтернатив билге тарызы -Файдаланырга иснең зур битләр белән -2900 -7-Zip программа турында -Программа 7-Zip тараттылыра бушлай -3000 -Буш исе җитми -Ялгышлар юк -{0} объект сайлаган -Архив ясап булмады: {0} -Бу архив өчен үзгәртү операцияләр эшләмилер. -Файл ачып булмады '{0}' архив кебек -Шифрлы архив ацып булмады '{0}'. Пароль туры килмәде? -Программа бу архив төрә белән эшләми -Файл {0} бар инде -Файл '{0}' үзгәргән иде.\nСезгә килә яңартырга аны архивта? -Файл яңартып булмады\n'{0}' -Мөхәрирне җибәреп булмады. -Файл вируска охшаган (файл исемендә озын аралар эзлеклелеге бар). -Операция башкарылганга булдыралмы папкадан озын юл бөлән. -Сез бер файл сайларга тиеш -Сез бер я берничә файл сайларга тиеш -Гонсырлар артык күп -3300 -Чишү -Кысу бара -Сынау -Ачу... -Тарау... -3400 -Чыгарырга -Чишенергә монда: -Күрсәтегәз чыгара торган файлларга урынны. -3410 -Юллар -&Тулы юллар -Юлларсыз -3420 -Алмаш -Раслау белән -Раслаусыз -Үткәрергә -Исем үзгәрү автом. -Исем. үзгәр. автом. -3500 -Файл алмаштыруга раслау -Эшкертү торган файл папкада бар инде. -Алмаштырырга бар файлны -бу файл белән? -{0} байт -Исем үзгәрү автом. -3700 -Бу кысу ысулы файл өчен кулланылмы '{0}'. -Ялгыш мәгълүмәтләрдә '{0}'. Файл бозылган. -Ялгыш CRC'да '{0}'. Файл бозылган. -Ялгыш шифрлы файл мәгълүмәтләрдә '{0}'. Пароль дөресме? -Ялгыш шифрлы файл CRC'да '{0}'. Пароль дөресме? -3800 -Пароль язу -&Языгыз пароль: -&Кабатлагыз парольны: -&Күрсәтергә пароль -Парольлар тиңсез -Парольга языгыз латин әлифбасын галәмәтләрне гына, саннар һәм махсус галәмәтләрне (!, #, $, ...) -Пароль бик озын -Пароль -3900 -Узган: -Калган: -Барлыгы: -Тизлек: -Зурлыгы: -Кысу катылыгы: -Ялгыш: -Архив: -4000 -Архивка өстәрге -&Архив: -&Үзгәртү тарызы: -Архив форматы: -&Кысу дәрәҗәсе: -&Кысу ысулы: -&Лөгать зурлыгы: -&Cүз зурлыгы: -Блок зурлыгы: -Агымнарның исәбе: -&Параметрлар: -Опцияләр -Ясарга SF&X-архив -Кысарга яздыруга ачкан файлларны -Шифрлау -Шифрлау ысулы: -&Шифрларга файллар исемнәрне -Иснең күләме урау өчен: -Иснең күләме Чишү өчен: -4050 -Кысмаска -Бик тиз -Тиз -Гадәти -Иң зур -Ультра -4060 -Өстәрге һәм алмаштырырга -Яңартырга һәм өстәрге -Яңартырга -Синхронлаштыру -4070 -Актарырга -Бөтен файллар -Файл зурлыгына сайларга -Өзлексез -6000 -Кабатларга -Күчәрергә -Кабатларга монда: -Күчәрергә монда: -Кабатлану... -Күчү... -Исем үзгәрү... -Күрсәтегәз папканы. -Бу папка өчен операция кулланылмы. -Ялгыш файлның\папканың исем үзгәрү чакта -Файлларны кабатларга раслау -Сезгә чын киләме кабатларга бу файлларны архивка -6100 -Файл бетерүгә раслау -Папка бетерүгә раслау -Файллар төркемне бетерүгә раслау -Сезгә чын киләме бетерергә "{0}"? -Сезгә чын киләме бетерергә папканы "{0}" һәм өчендәге файлларны? -Сезгә чын киләме бетерергә бу объектларны ({0} данә)? -Бетерү... -Ялгыш файлны/папканы бетерүдә -Файллар бетерүне озын юллар белән кәрзингә система кулланылмы -6300 -Ясарга папканы -Ясарга файл -Папка исеме: -Файл исеме: -Яңа папка -Яңа файл -Ялгыш папка ясаганда -Ялгыш файл ясаганда -6400 -Аңлатма -&Аңлатма: -Сайларга -Алырга сайлануны -Үрнәк: -6600 -Үзлекләр -Элеккеге папкалар -Игъланнар -Игълан -7100 -Санак -Челтәр -Кәгазләр -Система -7200 -Өстәрге -Чыгарырга -Сынарга -Кабатларга -Күчәрергә -Бетерергә -Хәбәр -7300 -Өзергә файлны -&Өзергә монда: -&Ватырга томларга, шундый зурлыгы бөлән, байт: -Өзелү... -Өзелүгә раслау -Сезгә чын киләме өзергә файл {0} бүләккә? -Том зурлыгы чыгыш файлдан азрак булырга тиеш -Ялгыш томлар зурлыкны күрсәтү кырда -Тәгаенле том зурлыгы: {0} байт.\nСезгә чын киләме архив өзергә шундый томларга? -7400 -Берләштерергә файлларны -&Берләштерергә монда: -Берләштерү... -Кирәк сайларга өзелгән файлның беренче бүләкне гына -Өзелгән файлны белеп булмады -Өзелгән файлның табылган бер бүләк гәне -7500 -Хисаплау тикшерү җыелманы... -Тикшерү җыелма -CRC'ның тикшерү җыелмасы мәгълүматлар өчән: -CRC'ның тикшерү җыелмасы мәгълүматлар һәм исемнәр өчән: -7600 -Җитештерүчәнлекне cыналу -Иснең күләме: -Урау -Чишү -Шөһрәтлелек -Гомуми шөһрәтлелек -Агымдагы -Нәтиҗәле -Куллану -Шөһрәтлелек / Куллану. -Узу: diff -Nru p7zip-rar-16.02/GUI/Lang/ug.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/ug.txt --- p7zip-rar-16.02/GUI/Lang/ug.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/ug.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.59 : Sahran -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Uyghur -ئۇيغۇرچە -401 -جەزملە -ۋاز كەچ - - - -(&Y)ھەئە -ياق(&N) -ياپ(&C) -ياردەم - -داۋاملاشتۇر(&C) -440 -ھەممىسى ھەئە(&A) -ھەممىسى ياق(&L) -توختا -قايتا باشلا -ئارقا سۇپا(&B) -ئالدى سۇپا(&F) -ۋاقىتلىق توختا(&P) -ۋاقىتلىق توختىتىلدى -راستىنلا ۋاز كېچەمسىز؟ -500 -ھۆججەت(&F) -تەھرىر(&E) -كۆرۈنۈش(&V) -يىغقۇچ(&A) -قورال(&T) -ياردەم(&H) -540 -ئاچ(&O) -نۆۋەتتىكى كۆزنەكتە ئاچ(&I) -يېڭى كۆزنەكتە ئاچ(&U) -كۆرۈنۈش(&V) -تەھرىر(&E) -ئات ئۆزگەرت(&M) -كۆچۈرۈش ئورنى(&C)… -يۆتكەش ئورنى(&M)… -ئۆچۈر(&D) -ھۆججەت پارچىلا(&S)… -ھۆججەت بىرلەشتۈر(&B)… -خاسلىق(&R) -ئىزاھات(&N) -ھۆججەت دەلىللە - -يېڭى قىسقۇچ -يېڭى ھۆججەت -چېكىن(&X) -600 -ھەممىنى تاللا(&A) -ھەممىنى تاللىما -ئەكسىچە تاللا(&I) -تاللا… -ئەكسىچە تاللا… -ئوخشاش تۈردىكى ھۆججەتنى تاللا -ئوخشاش تۈردىكى ھۆججەتنى ئەكسىچە تاللا -700 -چوڭ سىنبەلگە(&G) -كىچىك سىنبەلگە(&M) -تىزىملىك(&L) -تەپسىلىي(&D) -730 -تەرتىپلەنمىگەن -تەكشىلىك كۆرۈنۈش -&2 يۈز -قورال ستونى(&T) -غول قىسقۇچنى ئاچ -يۇقىرىغا -قىسقۇچ تارىخى… -يېڭىلا(&R) -750 -پرىس قورال ستونى -ئۆلچەملىك قورال ستونى -چوڭ كۇنۇپكا -كۇنۇپكا خېتىنى كۆرسەت -800 -يىغقۇچقا قوش(&A) -خەتكۈچ -900 -تاللانما(&O)… -ئۆلچەملىك سىناش(&B) -960 -مۇندەرىجە(&C)… -7-Zip (&A)ھەققىدە -1003 -يول -ئاتى -كېڭەيتىلگەن ئاتى -قىسقۇچ -چوڭلۇقى -بوغچا چوڭلۇقى -خاسلىق -قۇرغان ۋاقىت -زىيارەت ۋاقتى -ئۆزگەرتكەن ۋاقىت -پۇختا -ئىزاھات -شىفىرلانغان -ئاۋال پارچىلا -كېيىن پارچىلا -لۇغەت -CRC -تىپى -قارشى -ئۇسۇل -ئاساسىي مەشغۇلات سىستېمىسى -ھۆججەت سىستېمىسى -ئىشلەتكۈچى -گۇرۇپپا -بۆلەك -ئىزاھات -ئورۇن -يول ئالدى قوشۇلغۇچى -قىسقۇچ -ھۆججەت -نەشرى -ئەن -كۆپ ئەن -ئورۇن ھالقىش -ئۇلانما -بۆلەك -ئەنلەش - -64-bit -Big-endian -CPU -فىزىكىلىق چوڭلۇقى -ھۆججەت باشى چوڭلۇقى -يىغىندا تەكشۈر -ئالاھىدىلىك -مەۋھۇم ئادرېس - - - - - - -خاتالىق -ئومۇمى سىغىمى -ئىشلىتىلىشچان بوشلۇق -توپلاشتۇرغۇچ چوڭلۇقى -ئەن -يەرلىك ئاتى -تەمىنلىگۈچى -2100 -تاللانما -تىل -تىل: -تەھرىرلىگۈچ -تەھرىرلىگۈچ(&E): - -2200 -سىستېما -7-Zip بىلەن باغلانغان ھۆججەت تىپى: -2301 -7-Zip نى ئوڭ كۇنۇپكا تىزىملىكىگە قوش -ئوڭ تىزىملىكنى دەستىلە -ئوڭ تىزىملىكتە كۆرۈنىدىغان تۈرنى تاللاش -2320 -<قىسقۇچ> -<پرىس> -پرىس ئاچ -ھۆججەت يەش… -پرىسقا قوش -پرىس سىنا -مۇشۇ يەرگە يەش -{0} غا يەش‪‬ -{0}‬ غا قوش ‪ -پرىس ۋە ئېلخەت… -‬ غا پرىسلاپ ئېلخەتتە يوللا -2400 -قىسقۇچ -خىزمەت مۇندەرىجىسى(&W) -(&S)سىستېما ۋاقىتلىق قىسقۇچ -(&C)نۆۋەتتىكى -(&S)بەلگىلەنگەن قىسقۇچ: -يان دىسكىغىلا ئىشلىتىلىدۇ -پرىس ھۆججىتىنى يېشىدىغان ۋاقىتلىق ئورۇندىن بىرنى بەلگىلەڭ. -2500 -تەڭشەك -كۆرسەت“..”تۈر -ھەقىقىي ھۆججەت سىنبەلگىسى كۆرسەت -سىستېما تىزىملىكىنى كۆرسەت -پۈتۈن قۇر تاللا(&F) -سېتكا كۆرسەت(&G) - -شەيئى تاللاش مودىلى(&A) -چوڭ ئەسلەك بېتى ئىشلەت(&L) -2900 -‎7-Zip‏ ھەققىدە -‏7-Zip ‏ھەقسىز دېتال. ئەمما تىزىملىتىش ئارقىلىق ئۇنى ئېچىشنى قوللىسىڭىز بولىدۇ. -3000 -سىستېما لازىملىق ئەسلەكنى تەقسىملىيەلمەيدۇ -خاتالىق يوق -{0} تۈر تاللاندى -“{0}” قىسقۇچ قۇرالمايدۇ -بۇ پرىس يېڭىلاش مەشغۇلاتىنى قوللىمايدۇ -'{0}' ھۆججەتنى پرىس سۈپىتىدە ئاچالمايدۇ -'{0}' شىفىرلانغان پرىسنى ئاچالمايدۇ. ئىم خاتا -قوللىمايدىغان پرىس تېپى -{0} ھۆججەت مەۋجۇد -“{0}”ئۆزگەرتىلدى\nپرىس ھۆججىتىدە يېڭىلامسىز؟ -“{0}”ھۆججەتنى يېڭىلىيالمىدى\n -تەھرىرلىگۈچنى قوزغىتالمىدى -بۇ ھۆججەت ۋىرۇستەك تۇرىدۇ (ھۆججەت ئاتىدا كۆپ بوشلۇق بار) -يولى ئۇزۇن قىسقۇچقا بۇ مەشغۇلاتنى ئېلىپ بارالمايدۇ. -چوقۇم ھۆججەتتىن بىرنى تاللاڭ -چوقۇم بىر ياكى بىر قانچە ھۆججەت تاللاڭ -تۈر بەك كۆپ -3300 -يېشىۋاتىدۇ -پرىسلاۋاتىدۇ -سىناۋاتىدۇ -ئېچىۋاتىدۇ… -ئىزدەۋاتىدۇ… -3400 -يەش -يېشىش ئورنى(&X): -ھۆججەت يېشىدىغان جايدىن بىرنى كۆرسىتىڭ -3410 -يول مودېلى -تولۇق يول ئاتى -يول ئاتى يوق -3420 -قاپلاش مودېلى -قاپلاشتىن بۇرۇن سورا -ئەسكەرتمەي قاپلا -مەۋجۇد ھۆججەتتىن ئاتلا -ئۆزلۈكىدىن ئاتىنى ئۆزگەرت -مەۋجۇد ھۆججەت ئاتىنى ئۆزگەرت -3500 -ھۆججەت ئالماشتۇرۇشنى جەزملە -بۇ قىسقۇچ ئوخشاش ئاتلىق ھۆججەتتىن بىرنى ئۆز ئىچىگە ئالغان -بۇنىڭغا مەۋجۇد ھۆججەتنى -ئالماشتۇرامسىز؟ -{0} بايت -ئۆزلۈكىدىن ئات ئۆزگەرت(&U) -3700 -{0} قوللىمايدىغان پرىسلاش مودېلى -“{0}” سانلىق مەلۇمات خاتا. ھۆججەت بۇزۇلغان -“{0}” ئورۇندىكى CRC تەكشۈرۈش مەغلۇپ بولدى، ھۆججەت بۇزۇلغان -»{0}« شىفىرلانغان ھۆججەت سانلىق مەلۇماتىدا خاتالىق بار، ئىم خاتا. -“{0}” شىفىرلانغان ھۆججەت CRC سانلىق مەلۇمات دەلىللەشتە خاتالىق بار، ئىم خاتا. -3800 -ئىم كىرگۈزۈڭ -ئىم كىرگۈزۈڭ: -ئىمنى قايتا كىرگۈزۈڭ -ئىم كۆرسەت(&S) -ئىم ماس كەلمىدى -(!、#、$...)ئىمغا ئىنگلىزچە ھەرپ، سان ۋە ئالاھىدە ھەرپ-بەلگىلەرلا ئىشلىتىلىدۇ -ئىم بەك ئۇزۇن -ئىم -3900 -كەتكەن ۋاقىت: -قالغان ۋاقىت: -ئومۇمىي چوڭلۇقى: -سۈرئىتى: -بىر تەرەپ قىلىندى: -پرىس نىسبىتى: -خاتالىق: -پرىس: -4000 -پرىسقا قوش -پرىس(&A): -يېڭىلاش مودېلى(&U): -پرىسلاش شەكلى(&F): -پرىسلاش دەرىجىسى(&L): -پرىسلاش مودېلى(&M): -لۇغەت چوڭلۇقى(&D): -سۆز چوڭلۇقى(&W): -مۇقىم سانلىق مەلۇمات چوڭلۇقى: -CPU ئېقىم سانى : -پارامېتىر(&P): -تاللانما -ئۆزى يېشىلىدىغان پرىس ياسا(&X) -ھەمبەھىر ھۆججەت پرىسلا -شىفىرلاش -شىفىرلاش ئۇسۇلى: -شىفىرلىق ھۆججەت ئاتى(&N) -پرىسلاشقا كېرەكلىك ئەسلەك: -يېشىشكە كېرەكلىك ئەسلەك: -4050 -ساقلا -ئەڭ تېز -تېز -نورمال -ئەڭ چوڭ -ئەڭ زور چەكتە -4060 -ھۆججەت قوش ۋە ئالماشتۇر -ھۆججەت يېڭىلا ۋە قوش -مەۋجۇد ھۆججەتنى يېڭىلا -ھۆججەت قەدەمداشلا -4070 -كۆز يۈگۈرت -ھەممە ھۆججەت -مۇقىمسىز -مۇقىم -6000 -كۆچۈر -يۆتكە -كۆچۈرۈش ئورنى: -يۆتكەش ئورنى: -كۆچۈرۈۋاتىدۇ… -يۆتكەۋاتىدۇ… -ئاتىنى ئۆزگەرتىۋاتىدۇ… -نىشان قىسقۇچ تاللاڭ -نۆۋەتتىكى مەشغۇلاتنى قوللىمايدۇ -ھۆججەت ياكى قىسقۇچ ئاتىنى ئۆزگەرتىش خاتالىقى -ھۆججەت كۆچۈرۈشنى جەزملە -ھۆججەتنى پرىسقا راستىنلا كۆچۈرەمسىز؟ -6100 -ھۆججەت ئۆچۈرۈشنى جەزملە -قىسقۇچ ئۆچۈرۈشنى جەزملە -كۆپ ھۆججەت ئۆچۈرۈشنى جەزملە -“{0}” راستىنلا ئۆچۈرەمسىز؟ -“{0}” قىسقۇچ ۋە مەزمۇننى راستىنلا ئۆچۈرەمسىز؟ -{0} تۈرنى راستىنلا ئۆچۈرەمسىز؟ -ئۆچۈرۈۋاتىدۇ… -قىسقۇچ ياكى ھۆججەت ئۆچۈرۈش خاتالىقى -سىستېما يولى ئۇزۇن بولغان ھۆججەتنى ئەخلەتخاناغا يۆتكىيەلمەيدۇ -6300 -قىسقۇچ قۇر -ھۆججەت قۇر -قىسقۇچ ئاتى -ھۆججەت ئاتى -يېڭى قىسقۇچ -يېڭى ھۆججەت -قىسقۇچ قۇرۇش خاتالىقى -ھۆججەت قۇرۇش خاتالىقى -6400 -ئىزاھات -ئىزاھات(&C) -تاللاش -ئەكسىچە تاللا -ماسكا: -6600 -خاسلىق -قىسقۇچ تارىخى -دىئاگنوز ئۇچۇرى -ئۇچۇر -7100 -كومپيۇتېر -تور قوشنا -پۈتۈكلەر -سىستېما -7200 -قوش -يەش -سىنا -كۆچۈر -يۆتكە -ئۆچۈر -ئۇچۇر -7300 -ھۆججەت پارچىلا -پارچىلاش سانى(&S): -پارچە چوڭلۇقى، بايت(&V): -پارچىلاۋاتىدۇ… -پارچىلاشنى جەزملە -ھۆججەتنى {0} پارچىغا بۆلەمسىز؟ -پارچە چوڭلۇقى چوقۇم ئەسلى ھۆججەتتىن كىچىك بولۇشى لازىم -پارچە چوڭلۇقى خاتا -بايت{0} بەلگىلەنگەن پارچە چوڭلۇقى\nنۆۋەتتىكى ھۆججەتنى پارچىلامسىز؟ -7400 -ھۆججەت بىرلەشتۈر -بىرلەشتۈرۈش(&C): -بىرلەشتۈرۈۋاتىدۇ… -بىرىنچى ھۆججەتنىلا تاللا -بۆلەكلەنگەن ھۆججەت پارچىسى ئىكەنلىكىنى بايقىيالمىدى -باشقا ھۆججەت پارچىسىنى بايقىيالمىدى -7500 -تەكشۈرۈۋاتىدۇ… -تەكشۈرۈش ئۇچۇرى -CRC سانلىق مەلۇمات تەكشۈرۈش: -CRC سانلىق مەلۇمات ۋە ھۆججەت ئاتى تەكشۈرۈش: -7600 -ئاساسىي تەكشۈرۈش -ئىشلىتىلگەن ئەسلەك: -پرىسلاۋاتىدۇ -يېشىۋاتىدۇ -سۈرئىتى -ئوتتۇرىچە سۈرئىتى -نۆۋەتتە -نەتىجە -CPU ئىشلىتىلىشى -ئىشلىتىش سۈرئىتى -يوللاش: diff -Nru p7zip-rar-16.02/GUI/Lang/uk.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/uk.txt --- p7zip-rar-16.02/GUI/Lang/uk.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/uk.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Andrij Ilechko -; : Mokiy Mazaylo -; : Sergiy Gontaruk -; : Misha Padalka -; 15.02 : 2015-05-19 : Yurii Petrashko -; -; -; -; -; -; -0 -7-Zip -Ukrainian -Українська -401 -OK -Скасувати - - - -&Так -&Ні -&Закрити -Довідка - -&Продовжити -440 -Так для &всіх -Ні для вс&іх -Зупинити -Перезапустити -&На задньому плані -&На передньому плані -&Пауза -Призупинено -Ви впевнені, що бажаєте скасувати операцію? -500 -&Файл -&Редагування -&Вигляд -&Уподобання -&Інструменти -&Допомога -540 -&Відкрити -Відкрити в&середині -Відкрити &зовні -&Переглянути -&Редагувати -Пере&йменувати -&Копіювати до... -Пере&містити до... -Ви&далити -Роз&бити файл... -Об'&єднати файли... -В&ластивості -Комент&ар -Обчислити контрольну суму -Порівнювач -Створити папку -Створити файл -Ви&хід -Посилання -Ал&ьтернативні потоки -600 -Ви&брати все -Зняти вибір -&Інвертувати вибір -Вибрати... -Зняти вибір... -Вибрати за типом -Зняти вибір за типом -700 -Вели&кі піктограми -&Дрібні піктограми -&Список -&Таблиця -730 -Без сортування -Плоский вигляд -&2 панелі -&Панелі інструментів -Відкрити кореневу папку -Вище на один рівень -Історія папок... -&Оновити -Автооновлення -750 -Панель архіву -Стандартна панель -Великі кнопки -Текст на кнопках -800 -&Додати папку до вподобань як -Закладка -900 -&Налаштування... -&Тестування продуктивності -960 -&Зміст... -&Про 7-Zip... -1003 -Шлях -Ім'я -Розширення -Папка -Розмір -Розмір в архіві -Атрибути -Створено -Відкрито -Змінено -Неперервний -З коментарем -Зашифровано -Розбито до -Розбито після -Словник - -Тип -Анти -Метод -Походження -Файлова система -Користувач -Група -Блок -Коментар -Позиція -Префікс шляху -Папок -Файлів -Версія -Том -Багатотомний -Зсув -Посилань -Блоків -Частин - - - -Процесор -Фізичний розмір -Розмір заголовків -Контрольна сума -Властивості -Віртуальна адреса - -Коротке ім'я -Створено програмою -Розмір сектора -Режим -Посилання -Помилка -Загальний обсяг -Вільний простір -Розмір кластеру -Мітка -Локальне ім'я -Провайдер -Безбека NT -Альтернативний потік - -Видалено -Дерево - - -Тип помилки -Помилки -Помилки -Попередження -Попередження -Потоки -Альтернативні потоки -Розмір альтернативних потоків -Віртуальний розмір -Розпакований розмір -Загальний фізичний розмір -Індекс тому -Підтип -Короткий коментар -Кодова сторінка - - - -Розмір залишку -Розмір вбудованої заглушки -Посилання -Жорстке посилання -iNode - -Лише для читання -2100 -Опції -Мова -Мова: -Редагування -&Редактор: -&Порівнювач: -2200 -Система -Асоціювати 7-Zip з: -Усі користувачі -2301 -Інтегрувати 7-Zip до контекстного меню оболонки -Каскадне контекстне меню -Пункти контекстного меню: -Піктограми в контекстному меню -2320 -<Папка> -<Архів> -Відкрити архів -Видобути файли... -Додати до архіву... -Тестувати архів -Видобути до поточної папки -Видобути до {0} -Додати до {0} -Стиснути та надіслати... -Стиснути до {0} та надіслати -2400 -Папки -&Робоча папка -&Системна тимчасова папка -&Поточна -&Задати: -Використовувати тільки для змінних носіїв -Вкажіть розташування тимчасових архівних файлів. -2500 -Налаштування -Відображати елемент ".." -Відображати справжні піктограми файлів -Відображати системне меню -Вибір &цілого рядка -Відображати лінії &сітки -Відкривати об'єкти одним кліком -&Альтернативний режим виділення -Використовувати &великі сторінки пам'яті -2900 -Про 7-Zip -7-Zip є вільним програмним забезпеченням -3000 -Система не може виділити необхідний обсяг пам'яті -Без помилок -Обрано об'єктів: {0} -Не вдається створити папку '{0}' -Операція оновлення не підтримується для даного архіву. -Не вдається відкрити файл '{0}' як архів -Не вдається відкрити зашифрований архів '{0}'. Хибний пароль? -Непідтримуватий тип архіву -Файл {0} вже існує -Файл '{0}' було змінено.\nБажаєте оновити його в архіві? -Неможливо оновити файл\n'{0}' -Не вдається запустити редактор. -Файл виглядає як вірус (ім'я файлу містить довгу послідовність пробілів). -Операцію не можна викликати з папки, яка має довгий шлях. -Ви повинні вибрати один файл -Ви повинні вибрати один або декілька файлів -Забагато елементів -Не вдалося відкрити файл як {0} архів -Файл відкрито як {0} архів -Архів відкрито зі зсувом -3300 -Видобування -Стиснення -Тестування -Відкриття... -Сканування... -Видалення -3320 -Додавання -Оновлення -Аналіз -Реплікація -Перепакування -Пропуск -Видалення -Створення заголовків -3400 -Видобути -В&идобути до: -Вкажіть розташування для видобутих файлів. -3410 -Обробка шляхів -Повні шляхи -Без шляхів -Абсолютні шляхи -Відносні шляхи -3420 -Режим перезапису -Запитувати перед перезаписом -Перезаписувати без запиту -Пропускати існуючі файли -Автоматично перейменовувати -Автоматично перейменовувати існуючі файли -3430 -Усувати дублювання кореневої папки -Відновляти дані безпеки файлу -3500 -Підтвердіть заміну файлу -Папка призначення вже містить оброблюваний файл. -Бажаєте замінити існуючий файл -на такий? -{0} байт -&Автоматично перейменовувати -3700 -Непідтривуваний метод стиснення для '{0}'. -Помилка даних у '{0}'. Файл пошкоджено. -Помилка CRC у '{0}'. Файл пошкоджено. -Помилка даних у зашифрованому файлі '{0}'. Хибний пароль? -Помилка CRC у зашифрованому файлі '{0}'. Хибний пароль? -3710 -Хибний пароль? -3721 -Непідтримуваний метод стиснення -Помилка даних -Помилка CRC -Недоступні дані -Неочікуваний кінець даних -Існують деякі дані після закінчення корисних даних -Не є архівом -Помилка заголовків -Неправильний пароль -3763 -Недоступний початок архіву -Непідтверджений початок архіву - - - -Непідтримувана функція -3800 -Уведіть пароль -Уведіть пароль: -Повторіть пароль: -&Відображати пароль -Паролі не співпадають -Для паролю використовуйте лише англійські літери, цифри та спеціальні символи (!, #, $, ...) -Пароль занадто довгий -Пароль -3900 -Минуло часу: -Залишилося: -Загалом: -Швидкість: -Оброблено: -Ступінь стиснення: -Помилок: -Архівів: -4000 -Додати до архіву -&Архів: -&Режим оновлення: -&Формат архіву: -С&тупінь стиснення: -&Метод стискання: -&Розмір словника: -Р&озмір слова: -Розмір блоку: -Кількість потоків: -&Параметри: -Налаштування -&Створити SFX архів -Стискати спільні файли -Шифрування -Метод шифрування: -Шифрувати &імена файлів -Необхідно пам'яті для стискання: -Необхідно пам'яті для видобування: -Видалити файли після стиснення -4040 -Зберігати символічні посилання -Зберігати жорсткі посилання -Зберігати альтернативні потоки даних -Зберігати дані безпеки файлу -4050 -Без стиснення -Найшвидше -Швидке -Нормальне -Максимальне -Ультра -4060 -Додати та замінити файли -Оновити та замінити файли -Оновити існуючі файли -Синхронізувати файли -4070 -Переглянути -Усі файли -За розміром файлу -Неперервний -6000 -Копіювати -Перемістити -Копіювати до: -Перемістити до: -Копіювання... -Переміщення... -Перейменування... -Виберіть папку призначення. -Операція не підтримується для цієї папки. -Помилка перейменування файлу або папки -Підтвердіть копіювання файлу -Ви впевнені, що хочете скопіювати файли до архіву -6100 -Підтвердіть видалення файлу -Підтвердіть видалення папки -Підтвердіть видалення декількох файлів -Ви впевнені, що хочете видалити '{0}'? -Ви впевнені, що хочете видалити папку '{0}' і весь її вміст? -Ви впевнені, що хочете видалити ці елементи ({0} шт.)? -Видалення... -Помилка при видаленні файлу або папки -Системі не вдалося перемістити файл із довгим шляхом до Кошика -6300 -Створити папку -Створити файл -Ім'я папки: -Ім'я файлу: -Нова папка -Новий файл -Помилка при створенні папки -Помилка при створенні файлу -6400 -Коментар -&Коментар: -Вибрати -Зняти вибір -Маска: -6600 -Властивості -Історія папок -Діагностичні повідомлення -Повідомлення -7100 -Комп'ютер -Мережа -Документи -Система -7200 -Додати -Видобути -Тестувати -Копіювати -Перемістити -Видалити -Інформація -7300 -Розбити файл -&Розбити до: -Розбити на &томи розміром, байт: -Розбиття... -Підтвердіть розбиття -Ви впевнені, що бажаєте розбити архів на {0} томів? -Розмір тому має бути меншим за розмір вихідного файлу -Неправильний розмір тому -Задано розмір тому: {0} байт.\nВи впевнені, що бажаєте розбити архів на такі томи? -7400 -Об'єднати файли -&Об'єднати до: -Об'єднання... -Виберіть тільки першу частину розбитого файлу -Не вдалося визначити файл, як частину розбитого файлу -Не вдалося знайти більше однієї частини розбитого файлу -7500 -Обчислення контрольної суми... -Інформація про контрольну суму -Контрольна сума CRC для даних: -Контрольна сума CRC для даних та імен: -7600 -Тестування продуктивності -Використано пам'яті: -Стискання -Видобування -Рейтинг -Загальний рейтинг -Поточні значення -Підсумкові значення -Завант. ЦП -Рейтинг/Завант. -Проходів: -7700 -Посилання -Пов'язати -Джерело: -Мета: -7710 -Тип посилання -Жорстке посилання -Символічне посилання (файл) -Символічне посилання (каталог) -Точка з'єднання (каталог) diff -Nru p7zip-rar-16.02/GUI/Lang/uz.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/uz.txt --- p7zip-rar-16.02/GUI/Lang/uz.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/uz.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 9.07 : Sherzod Mamatkulov -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Uzbek -O'zbek -401 -OK -Bekor - - - -&Ha -&Yo'q -&Yopish -Yordam - -&Davom et -440 -H&ammasiga ha -Hammasiga y&o'q -To'xta -Qayta boshla -&Orqa fon -Ol&di fon -&Pauza -Pauza qilingan -Haqiqatdan ham bekor qilishni istaysizmi? -500 -&Fayl -&Tahrir -&Ko'rinish -&Xatcho'plar -&Asboblar -&Yordam -540 -&Ochish -&Ichkarida ochish -&Tashqarida ochish -&Ko'rish -Ta&hrirlash -&Qayta nomlash -&Nusxalash... -Ko'chi&rish... -O'chirish -&Faylni bo'laklash... -Fayllarni &birlashtirish... -&Xossalari -&Sharh... -Nazorat summasini hisoblash -Farq -Papka yaratish -Fayl yaratish -&Chiqish -600 -H&ammasini tanla -Hammasini tashla -&Tanlanishni teskarila -Tanlash... -Tashlash... -Turi bo'yicha tanla -Turi bo'yicha tashla -700 -&Yirik ikonlar -&Mitti ikonlar -&Ro'yxat -&Tafsilotlar -730 -Saralanmagan -Tekis ko'rinish -&2 ta panel -&Uskunalar majmuasi -Ildiz papkasini och -Bir bosqich yuqoriga -Papkalar tarixi... -&Qayta och -750 -Arxiv toolbari -Standart toolbar -Yirik tugmalar -Tugmalar matnini ko'rsat -800 -&Papkani ushbu xatcho'pga qo'sh -Xatcho'p -900 -Tanl&ovlar... -&Baholash -960 -Yordam &tarkibi... -&7-Zip haqida... -1003 -Yo'lak -Nomi -Kengaytma -Papka -Hajmi -Siqilgan hajmi -Atributlari -Yaratilgan -Ochilgan -O'zgartirilgan -Yaxlit -Sharhlangan -Tilsimlangan -Bundan oldin bo'laklangan -Bundan keyin bo'laklangan -Lug'at -CRC -Turi -Anti -Uslub -Mezbon OS -Fayl tizimi -Foydalanuvchi -Guruh -Block -Sharh -Joylashuv -Yo'lak prefiksi -Papkalar soni -Fayllar soni -Versiya -Tom -Ko'p-tomli -Offset -Ulanmalar -Bloklar soni -Tomlar soni - -64-bit -Big-endian -Protsessor -Fizik hajmi -Header hajmi -Nazorat summasi -Tavsifi -Virtual adresi -ID -Qisqa nomi -Yaratgan dastur -Sektor hajmi -Uslubi -Ulanma -Xato -Umumiy hajmi -Bo'sh joy -Klaster hajmi -Yorliq -Lokal nomi -Provayder -2100 -Tanlovlar -Til -Til: -Muharrir -&Muharrir: -&Farq: -2200 -Tizim -Ushbu arxivlarni 7-Zip bilan biriktir: -2301 -7-Zipni qobiq kontekst menyusiga qo'sh -Kontekst menyusi pog'onali bo'lsin -Kontekst menyu bandlari: -2320 - - -Arxivni och -Fayllarni ajrat... -Arxivga qo'sh... -Arxivni sina -Shu joyga ajrat -{0}ga ajrat -{0}ga qo'sh -Siq va emailda jo'nat... -{0}ga siq va emailda jo'nat -2400 -Papkalar -&Ish papkasi -Tizim &vaqtinchalik (temp) papkasi -&Joriy papka -&Tayinlangan: -Faqat olinadigan drayvlar uchun ishlat -Vaqtinchalik arxiv fayllari uchun manzilni tayinlang. -2500 -Sharoit -".." qismini ko'rsat -Fayllarning haqiqiy ikonlarini ko'rsat -Tizim menyusini ko'rsat -&To'liq yo'lakni tanlash -&Panjara chiziqlarini ko'rsat -&Faylni ochish uchun bitta klik yetarli -&Muqobil tanlash uslubini qo'lla -&Yirik xotira pageini ishlat -2900 -7-Zip haqida -7-Zip - bepul dasturiy ta'minot. -3000 -Tizim kerakli miqdordagi xotirani band qila olmadi -Hechqanday xatolik aniqlanmadi -{0} ta qism tanlangan -'{0}' papkasini yarata olmadim -Bu arxivga nisbatan yangilash amallari bajarilmaydi. -'{0}' faylini arxiv sifatida ocha olmadim -Tilsimlangan '{0}' arxivni ocha olmadim. Noto'g'ri parol kiritildimi? -Noma'lum arxiv turi -{0} fayli oldindan mavjud -'{0}' fayli o'zgartirildi.\nUni arxiv ichida yangilashni xohlaysizmi? -Ushbu faylni yangilay olmadim\n'{0}' -Muharrirni ocha olmadim. -Bu fayl virusga o'xshaydi (fayl nomida uzun bo'shliq bor). -Bu amalni uzun yo'lakli papkada chaqirib bo'lmaydi. -Bitta faylni tanlashingiz lozim -Bitta yoki undan ortiq faylni tanlashingiz lozim -Qismlar o'ta ko'p -3300 -Ajratilmoqda -Siquv ketmoqda -sinaldi -Ochilmoqda... -Tekshirilmoqda... -3400 -Ajratish -&Buyerga ajrat: -Ajratilgan fayllar uchun manzil tayinlang. -3410 -Yo'lak uslubi -To'liq yo'lak nomlari -Yo'lak nomi yo'q -3420 -Ustidan yozish uslubi -Yozib yuborishdan oldin so'ra -So'ramasdan yozib yubor -Oldindan mavjud fayllarni tashlab ket -Avtomatik tarzda qayta nomla -Mavjud fayllarni avto qayta nomla -3500 -Fayl ustidan yozishni tasdiqlash -Manziliy papkada ishlangan fayl oldindan mavjud. -Mavjud faylni -bunisi bilan almashtirasizmi? -{0} bayt -A&vtomatik tarzda qayta nomla -3700 -'{0}'dagi siquv metodi notanish. -'{0}'da data xatosi yuz berdi. Fayl zararlangan. -'{0}'da CRC amalga oshmadi. Fayl zararlangan. -Tilsimlangan '{0}' faylida data xatosi yuz berdi. Parol noto'g'ri shekilli -Tilsimlangan '{0}' faylida CRC amalga oshmadi. Parol noto'g'ri shekilli -3800 -Parolni kiritish -Parolni kiriting: -Parolni qayta kiriting: -&Parolni ko'rsat -Parollar bir xil emas -Parol uchun faqat lotincha harflar, raqam va maxsus belgilar (!, #, $, ...) ishlating -Parol haddan tashqari uzun -Parol -3900 -O'tgan vaqt: -Qolgan vaqt: -Jami hajmi: -Tezlik: -Ishlandi: -Siquv nisbati: -Xatolar: -Arxivlar: -4000 -Arxivga qo'shish -&Arxiv: -&Yangilash uslubi: -Arxiv &formati: -Siq&uv bosqichi: -&Siquv metodi: -&Lug'at hajmi: -So'z haj&mi: -Yaxlit blok hajmi: -CPU oqimlari soni: -&Parametrlar: -Tanlovlar -SF&X arxiv yarat -Baham ko'rilgan fayllarni ham siq -Tilsimlash -Tilsimlash metodi: -Fayl &nomlarini tilsimla -Siquvda ishlatiladigan xotira: -Ajratuvda ishlatiladigan xotira: -4050 -Saqlash -Eng tez -Tez -O'rtacha -Eng zo'r -Ultra -4060 -Fayllarni qo'sh va almashtir -Fayllarni yangila va qo'sh -Mavjud fayllarni yangila -Fayllarni sinxronla -4070 -Belgila -Barcha fayllar -No-yaxlit -Yaxlit -6000 -Nusxalash -Ko'chirish -Ushbu katalogga nusxala: -Ushbu katalogga ko'chir: -Nusxalanmoqda... -Ko'chirilmoqda... -Qayta nomlanmoqda... -Manziliy papkani tanlang. -Ushbu papkaga nisbatan bu amalni qo'llab bo'lmaydi -Fayl yoki papkani qayta nomlashda xato yuz berdi -Faylni nusxalashni tasdiqlang -Haqiqatdan ham fayllarni arxivga nusxalashni xohlaysizmi -6100 -Faylni o'chirishni tasdiqlang -Papkani o'chirishni tasdiqlang -Ko'plab fayllarni o'chirishni tasdiqlang -Haqiqatdan ham '{0}'ni o'chirib tashlamoqchimisiz? -Haqiqatdan ham '{0}' papkasini butun tarkibi bilan o'chirib tashlamoqchimisiz? -Haqiqatdan ham ushbu {0} ta qismni o'chirib tashlamoqchimisiz? -O'chirilmoqda... -Fayl yoki papkani o'chirishda xato yuz berdi -Tizim uzun yo'lakli faylni Recycle Bin (Korzina)ga ko'chira olmaydi -6300 -Papka yaratish -Fayl yaratish -Papka nomi: -Fayl nomi: -Yangi papka -Yangi fayl -Papka yaratishda xato yuz berdi -Fayl yaratishda xatolik yuz berdi -6400 -sharhi -&Sharh: -Tanlash -Tashlash -Maska: -6600 -Xossalari -Papkalar tarixi -Diagnostik xabarlar -Xabar -7100 -Kompyuter -Tarmoq -Hujjatlar -Tizim -7200 -Qo'sh -Ajrat -Sina -Nusxala -Ko'chir -O'chir -Ma'lumot -7300 -Faylni bo'laklash -&Ushbu katalogga bo'lakla: -&Tomlarga bo'lakla, bayt: -Bo'laklanmoqda... -Bo'laklash tasdig'i -Haqiqatdan ham faylni {0} ta tomga bo'lmoqchimisiz? -Tom hajmi original fayl hajmidan kichikroq bo'lishi lozim -Tom hajmi noto'g'ri -Berilgan tom hajmi: {0} bayt.\nHaqiqatdan ham arxivni shunaqa bo'laklarga bo'lmoqchimisiz? -7400 -Fayllarni birlashtirish -&Ushbu katalogga birlashtir: -Birlashtirilmoqda... -Bo'lak faylning faqat birinchi qismini tanla -Bu fayl bo'lak faylning qismi emas -Bo'lak faylning bittadan ortiq qismi topilmadi -7500 -Nazorat summasi hisoblanmoqda... -Nazorat summasi ma'lumoti -Data uchun CRC checksum: -Data va nomlar uchun CRC checksum: -7600 -Baholash -Xotira ishlatilishi: -Siqish -Ajratish -Reyting -Umumiy reyting -Joriy -Natijaviy -CPU bandligi -Reyting / Ishlatish -O'tganlar: diff -Nru p7zip-rar-16.02/GUI/Lang/va.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/va.txt --- p7zip-rar-16.02/GUI/Lang/va.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/va.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 4:26 : Tomas Miralles -; 4.44 : Fernando Verdú -; -; -; -; -; -; -; -; -; -0 -7-Zip -Valencian -Valencià -401 -Acceptar -Cancel·lar - - - -&Si -&No -Tan&car -Ajuda - -&Continuar -440 -Si a &tot -No a t&ot -Parar -Reiniciar -Segon pla -Primer pla -&Pausa -Parat -Està segur que vol cancel·lar? -500 -&Arxiu -&Editar -&Visualitzar -Favorits -Ferramentes -Ajuda -540 -&Obrir -Obrir d&ins -Obrir fora -&Visualitzar -&Editar -Renom&enar -&Copiar a... -&Moure a... -&Suprimir -&Separar fitxer... -Com&binar fitxers... -P&ropietats -Come&ntari -Calcular checksum - -Crear directori -Crear fitxer -Eixir -600 -Seleccion&ar-ho tot -Deseleccionar-ho tot -&Invertir selecció -Seleccionar... -No seleccionar... -Seleccionar per tipus -No seleccionar per tipus -700 -Icones g&rans -Icones menudes -&Llista -&Detalls -730 -No ordenat -Vista plana -&2 Taules -&Barres de ferramentes -Obrir directori arrel -Directori pare -Historial de carpetes... -Actualitza&r -750 -Arxiu -Estàndard -Botons grans -Mostrar text dels botons -800 -&Afegir el directori als Favorits com a -Personal -900 -&Opcions... -&Banc de proves -960 -&Contingut... -Sobre 7-Zip... -1003 -Adreça -Nom -Tipus d'arxiu -Directori -Tamany -Tamany comprimit -Atributs -Creat -ültim accés -Última modificació -Compacte -Comentari -Xifrat -Expandit abans -Expandit després -Diccionari -CRC -Tipus -Anti -Mètode -SO d'origen -Sistema de fitxers -Usuari -Grup -Bloc -Comentari -Posició -Prefix de ruta - - - - - - - - - - - - - - - - - - - - - - - - -Error -Tamany total -Espai lliure -Tamany sector -Etiqueta -Nom local -Proveïdor -2100 -Opcions -Idioma -Idioma: -Editor -&Editor: - -2200 -Sistema -Associar 7-Zip amb: -2301 -Integrar 7-Zip dins el menu contextual de Windows -Menu contextual en cascada -Objectes del menu contextual: -2320 - - -Obrir arxiu -Extraure fitxers... -Afegir a l'arxiu... -Comprovar arxiu -Extraure ací -Extraure a {0} -Afegir a {0} -Comprimir i enviar per correu electrònic... -Comprimir a {0} i enviar per correu electrònic -2400 -Directoris -Directori de &treball -Directori temporal del &sistema -Directori a&ctual -E&specificar directori: -Utilitzar només per a discs extraibles -Especificar un directori per als arxius temporals. -2500 -Ajusts -Mostrar l'objecte ".." -Mostrar icones reals dels fitxers -Mostrar el menú del sistema -Seleccionar &tota la la fila -Mostrar &línies de la taula - -Mode de selecció &alternatiu -Utilitzar pàgines de memòria &grans -2900 -Sobre 7-Zip -7-Zip és un programa lliure (GNU LGPL). Pot col·laborar en el desenvolupament del 7-zip registrant-lo, com a usuari registrat podrà rebre suport tècnic. -3000 - -No hi ha errors -{0} objecte(s) seleccionat(s) -No es pot crear el directori '{0}' -Les operacions d'actualització d'este arxiu no estan suportades. -No es pot obrir el fitxer '{0}' com arxiu -No es pot obrir l'arxiu xifrat '{0}'. contrasenya incorrecta? - - -El fitxer '{0}' ha sigut modificat.\nVol actualitzar-lo a l'arxiu? -No es pot actualitzar el fitxer\n'{0}' -No es pot executar l'editor. - - - - -Massa objectes -3300 -Extraent -Comprimint -Provant -Obrint... -Escanejant... -3400 -Extraure -E&xtraure a: -Seleccione destinació per als fitxers extrets. -3410 -Mode d'adreça -Adreça sencera -Sense adreça -3420 -Sobreescriu -Pregunta abans de sobreescriure -Sobreescriu sense confirmació -Conserva arxius ja existents -Reanomena automàticament -Reanomena automàticament arxius ja existents -3500 -Confirmar substitució de fitxers -El directori de destinació conté un fitxer amb el mateix nom. -Vol substituir el fitxer existent -per este altre? -{0} bytes -Renomenar a&utomàticament -3700 -Mètode de compressió no vàlid per a '{0}'. -Error de dades en '{0}'. L'arxiu està corrupte. -CRC ha fallat en '{0}'. L'arxiu està corrupte. -Errors de dades en l'arxiu xifrat '{0}'. Contrasenya incorrecta? -CRC incorrecte en l'arxiu xifrat '{0}'. Contrasenya incorrecta? -3800 -Introduir contrasenya -Introduir contrasenya: -Reintroduir contrasenya: -Mo&strar contrasenya -Les contrasenyes no coincideixen -Useu només lletres de l'alfabet anglès, números i caràcters especials (!, #, $, ...) per a la contrasenya -Contrasenya massa llarga -Contrasenya -3900 -Temps transcorregut: -Temps restant: -Mida: -Velocitat: - - -Errors: - -4000 -Afegir a l'arxiu -&Arxiu: -Mode d'act&ualització: -&Format de l'arxiu: -&Nivell de compressió: -Tipus de co&mpressió: -Tamany &diccionari: -Tamany ¶ula: - - -&Paràmetres: -Opcions -Crear arxiu SF&X - -Xifrat -Métode de xifrat: -Encriptar el nom dels fitxers -Us de memòria Comprimint: -Us de memòria Descomprimint: -4050 -Sense compressió -La més ràpida -Ràpida -Normal -Màxima -Ultra -4060 -Afegir i substituir fitxers -Actualitzar i afegir fitxers -Actualitzar fitxers existents -Sincronitzar fitxers -4070 -Visualitzar -Tots els fitxers - - -6000 -Copiar -Moure -Copiar a: -Moure a: -Copiant... -Movent... -Renomenant... -Seleccioneu carpeta de destinació. -Operació no permesa. -Error renomenant fitxer o carpeta -Confirmar copia de fitxer -Està segur que vol copiar els fitxers a l'arxiu -6100 -Confirmar supressió del fitxer -Confirmar supressió del directori -Confirmar supressió m�ltiple de fitxers -Està segur de voler suprimir '{0}'? -Està segur de voler suprimir la carpeta '{0}' i tot el seu contingut? -Està segur de voler esborrar estos {0} elements? -Suprimint... -Error esborrant fitxer o carpeta - -6300 -Crear carpeta -Crear fitxer -Nom de carpeta: -Nom de fitxer: -Carpeta nova -Fitxer nou -Error creant carpeta -Error creant el fitxer -6400 -Comentari -&Comentari: -Seleccionar -No seleccionar -Màscara: -6600 - -Historial de directoris -Missatges de diagnosi -Missatge -7100 -El meu ordinador -Entorn de xarxa - -Sistema -7200 -Afegir -Extraure -Provar -Copiar -Moure -Esborrar -Info -7300 -Separar fitxer -&Separar a: -Separar en &volums, bytes: -Separant... -Confirma divissió -Esteu segurs que voleu dividir el fitxer en {0} volums? -La mida del volum ha de ser menor que la mida original del fitxer -Mida incorrecta de volum -Mida del volum especificada: {0} bytes.\nEsteu segurs que voleu dividir l'arxiu en volums? -7400 -Combinar fitxers -&Combinar a: -Combinant... -Seleccioneu només el primer fitxer - - -7500 -Calculant checksum... -Informació checksum -CRC checksum per a les dades: -CRC checksum per a dades i noms: -7600 -Banc de proves -Us de memoria: -Comprimint -Descomprimint -Taxa -Taxa total -Actual -Resultant - - -Passades: diff -Nru p7zip-rar-16.02/GUI/Lang/vi.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/vi.txt --- p7zip-rar-16.02/GUI/Lang/vi.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/vi.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,404 +0,0 @@ -;!@Lang2@!UTF-8! -; 2.30 : : Tran Hong Ha -; 4.42 : : Le Vu Hoang -; 4.48 : : Nguyen Hong Quan -; 9.07 : 2011-04-12 : Vietnamize Team -; -; -; -; -; -; -; -0 -7-Zip -Vietnamese -Tiếng Việt -401 -Đồng ý -Hủy bỏ - - - -Có -Không -Đóng -Giúp đỡ - -Tiếp tục -440 -Có tất cả -Không tất cả -Dừng -Làm lại -Chạy nền -Chế độ ưu tiên -Dừng -Đã dừng -Bạn chắc chắn muốn hủy bỏ? -500 -Tập tin -Biên tập -Xem -Ưa thích -Công cụ -Giúp đỡ -540 -Mở -Mở tại đây -Mở trong cửa sổ khác -Xem -Biên tập -Đổi tên -Sao chép đến... -Di chuyển đến... -Xoá -Chia cắt tệp nén... -Nối tệp nén... -Thuộc tính -Chú thích -Tính checksum (md5) -So sánh -Tạo thư mục -Tạo tệp nén -Thoát -600 -Chọn tất cả -Bỏ chọn tất cả -Đảo lựa chọn -Chọn... -Bỏ chọn... -Chọn theo loại -Bỏ chọn theo loại -700 -Biểu tượng lớn -Biểu tượng nhỏ -Danh sách -Chi tiết -730 -Không sắp xếp -Mọi tập tin và thư mục con -2 bảng -Thanh công cụ -Mở thư mục gốc -Lên một cấp -Lịch sử thư mục... -Nạp lại -750 -Thanh công cụ nén -Thanh công cụ chuẩn -Sử dụng nút lớn -Hiển thị chữ trên nút -800 -Thêm thư mục vào 'Ưa thích' như là -Đánh dấu -900 -Tùy chọn... -Đo tốc độ -960 -Nội dung... -Về 7-Zip... -1003 -Đường dẫn -Tên -Phần mở rộng -Thư mục -Kích cỡ thực -Kích cỡ nén -Thuộc tính -Thời điểm tạo -Thời điểm truy xuất -Thời điểm sửa đổi -Kiểu nén Solid -Ghi chú -Được mã hoá -Chia nhỏ trước -Chia nhỏ sau -Từ điển -CRC -Loại -Anti -Phương thức nén -Hệ điều hành -Tệp hệ thống -Người dùng -Tập đoàn -Số thứ tự -Chú thích -Vị trí -Đường dẫn đầu -Thư mục -Tập tin -Phiên bản -Kích cỡ -Đa kích cỡ -Offset -Liên kết -Tập tin -Kích cỡ - -64-bit -Big-endian -CPU -Kích cỡ lý thuyết -Kích cỡ hiện tại -Checksum -Đặc điểm -Địa chỉ ảo -ID -Tên ngắn -Trình tạo ứng dụng -Kích cỡ vùng -Chế độ -Liên kết -Lỗi -Tổng dung lượng -Dung lượng trống -Dung lượng cluster -Nhãn -Tên mạng cục bộ -Nhà cung cấp -2100 -Các tùy chọn -Ngôn ngữ hiển thị -Ngôn ngữ: -Biên tập -Trình biên tập: -Trình so sánh: -2200 -Hệ thống -Kết hợp 7-Zip với: -2301 -Tích hợp 7-Zip vào menu ngữ cảnh -Xếp tầng menu ngữ cảnh -Menu ngữ cảnh: -2320 - - -Mở tệp nén -Giải nén tệp... -Thêm vào tệp nén... -Kiểm tra tệp nén -Giải nén tại đây -Giải nén vào {0} -Thêm vào {0} -Nén và gởi qua email... -Nén thành {0} và gởi qua email -2400 -Thư mục -Thư mục hiện hành -Hệ thống thư mục tạm -Hiện tại -Đặc biệt: -Chỉ sử dụng cho ổ đĩa di động -Xác định vị trí cho các tệp lưu trữ tạm thời. -2500 -Thiết lập -Hiển thị mục ".." -Hiển thị biểu tượng thực của tệp -Hiển thị menu hệ thống -Chọn cả dòng -Hiển thị lưới -Nhắp chuột để mở -Chế độ chọn luân phiên -Sử dụng bộ nhớ lớn -2900 -Về 7-Zip -7-Zip là một phần mềm miễn phí. -3000 -Không thể cấp thêm dung lượng RAM yêu cầu -Không xuất hiện lỗi -{0} đối tượng đã chọn -Không thể tạo thư mục '{0}' -Tệp nén này không được hỗ trợ cập nhật. -Không thể mở '{0}' như là tệp nén -Không thể mở tập tin nén '{0}' bị mã hóa . Mật khẩu sai? -Không hỗ trợ tệp nén này -Tệp {0} đang tồn tại -Tệp '{0}' đã bị thay đổi.\nBạn có muốn cập nhật nó vào tập tin nén? -Không thể cập nhật tệp\n'{0}' -Không thể khởi động trình biên tập. -Tập tin này có thể là virus (tên tập tin có chứa khoảng cách dài). -Không thể thực hiện với một thư mục có đường dẫn quá dài. -Bạn phải chọn một tập tin -Bạn phải chọn một hoặc 2 tập tin -Quá nhiều tập tin -3300 -Đang giải nén... -Đang nén... -Đang kiểm tra... -Đang mở... -Đang quét... -3400 -Giải nén -Giải nén vào: -Chọn nơi để giải nén tệp. -3410 -Chọn đường dẫn -Đường dẫn đầy đủ -Không có đường dẫn -3420 -Chế độ ghi đè -Hỏi trước khi ghi đè -Ghi đè không cần hỏi -Bỏ qua tệp đã có -Tự động đổi tên -Tự động đổi tên tệp đã có -3500 -Xác nhận thay thế -Thư mục đích đã có tập tin đó. -Bạn có muốn thay thế tập tin đã có -bằng tập tin mới? -{0} bytes -Tự động đổi tên -3700 -Phương thức nén không hỗ trợ cho '{0}'. -Lỗi dữ liệu trong '{0}'. Tệp đã bị hỏng. -Lỗi chẵn/lẻ (CRC) trong '{0}'. Tệp đã bị hỏng. -Lỗi dữ liệu trong tệp nén bị mã hóa '{0}'. Mật khẩu sai? -Kiểm tra CRC thất bại trong tệp nén bị mã hóa '{0}'. Mật khẩu sai? -3800 -Vui lòng nhập mật khẩu -Nhập mật khẩu: -Nhập lại mật khẩu: -Xem mật khẩu -Mật khẩu không khớp nhau -Chỉ đặt mật khẩu bằng tiếng Anh, số và những kí tự đặc biệt (!, #, $, ...) cho mật khẩu -Mật khẩu quá dài -Mật khẩu -3900 -Thời gian đã qua: -Thời gian còn lại: -Tổng kích cỡ: -Tốc độ: -Đã nén: -Tỷ lệ nén: -Lỗi: -Tệp nén: -4000 -Thêm vào tệp nén -Tệp nén: -Chế độ cập nhật: -Dạng tệp nén: -Mức độ nén: -Phương thức nén: -Kích cỡ thư mục: -Kích cỡ văn bản: -Kích cỡ nén Solid: -Số luồng xử lý CPU: -Tham số: -Tùy chọn -Tạo trình tự giải nén tệp -Nén tập tin chia sẻ -Mã hóa -Phương thức mã hóa: -Mã hoá tên tệp -Bộ nhớ dùng cho việc nén: -Bộ nhớ dùng cho việc giải nén: -4050 -Lưu trữ -Nhanh nhất -Nhanh -Bình thường -Tối đa -Siêu nhanh -4060 -Thêm và thay thế -Thêm và cập nhật -Cập nhật tập tin đã có -Đồng bộ -4070 -Duyệt -Mọi tập tin -Không nén dạng Solid -Solid -6000 -Sao chép -Di chuyển -Sao chép đến: -Di chuyển đến: -Đang thêm... -Đang di chuyển... -Đang đổi tên... -Chọn thư mục đến. -Thao tác không được hỗ trợ cho tập tin này. -Lỗi khi đổi tên tệp hoặc thư mục -Xác nhận thêm -Bạn muốn thêm vào tệp nén? -6100 -Xác nhận xoá -Xác nhận xoá thư mục -Xác nhận xoá nhiều tệp -Bạn có chắc chắn muốn xoá '{0}'? -Bạn có chắc chắn muốn xoá thư mục '{0}' và mọi tập tin bên trong? -Bạn có chắc chắn muốn xoá {0} ? -Đang xóa... -Lỗi khi đang xóa tệp hoặc thư mục -Hệ thống không thể xóa tệp với đường dẫn dài vào Thùng rác -6300 -Tạo thư mục -Tạo tệp nén -Tên thư mục: -Tên tệp mới: -Thư mục mới -Tệp mới -Lỗi khi tạo thư mục -Lỗi khi tạo tệp -6400 -Chú thích -Chú thích: -Chọn -Bỏ chọn -Ẩn danh: -6600 -Thuộc tính -Lịch sử thư mục -Thông tin chẩn đoán -Thông tin -7100 -Máy tính -Mạng -Tài liệu -Hệ thống -7200 -Thêm -Giải nén -Kiểm tra -Sao chép -Di chuyển -Xoá -Thông tin -7300 -Chia nhỏ tệp -Chia nhỏ và lưu tại: -Chia thành nhiều phần, bytes: -Đang chia nhỏ... -Xác nhận việc chia nhỏ -Bạn có chắc muốn chia nhỏ tệp nén thành {0} phần? -Kích cỡ mỗi phần phải nhỏ hơn tệp gốc -Kích cỡ phần chia chưa đúng -Kích cỡ phần chia đã đặt: {0} bytes.\nBạn chắc chắn muốn chia tệp nén theo kích cỡ chia đã đặt? -7400 -Nối tệp -Nối thành: -Đang nối... -Chỉ chọn phần đầu của tệp bị chia nhỏ -Không thể xem tập tin như phần nối của tệp bị chia cắt -Không tìm thấy thêm phần nối nào của tệp chia cắt -7500 -Đang tính checksum... -Thông tin checksum -CRC checksum cho dữ liệu: -CRC checksum cho dữ liệu và tên: -7600 -Đo tốc độ -Bộ nhớ sử dụng: -Đang nén -Đang giải nén -Đánh giá -Tổng đánh giá -Hiện thời -Kết quả -Mức dùng CPU -Tốc độ / Mức dùng -Đã qua: diff -Nru p7zip-rar-16.02/GUI/Lang/yo.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/yo.txt --- p7zip-rar-16.02/GUI/Lang/yo.txt 2016-02-03 05:05:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/yo.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 15.00 : 2015-03-29 : Ibrahim Oyekan -; -; -; -; -; -; -; -; -; -; -0 -7-Zip -Yoruba -Yoruba -401 -O DAA -Pa re - - - -&Bẹẹni -&Bẹẹkọ -&Pádé -Ìrànlọwọ - -&Tẹ́-síwájú -440 -Bẹẹni fun &gbogbo ẹ -Bẹẹkọ fun &gbogbo ẹ -Dúró -Ṣàtúnbẹ̀rẹ̀ -&Ẹ̣̀hìn-ìgbéhìn -&Ojú-ìgbéhìn -&Dádúró -Ìdúró -Ṣe ẹ dájú pe ẹnyin fẹ́ paarẹ -500 -&Faíli -&Tunkọ -&Ìwò -&Aàyò -&Irinṣẹ́ -&Ìrànlọwọ -540 -&Ṣi -Ṣi &si ínú -Ṣi &si íta -&Ìwò -&Tunkọ -&Tun orukọ kọ -&Ṣẹ̀dà si... -&Gbé si... -&Paarẹ -&Pín faíli... -Ṣà àwọn faíli kópọ̀... -&Àbùdá -&Ọrọ ìwòye... -Ṣe iṣiro checksum -íyàtọ̀ -Dá àpò faíli silẹ́ -Dá faíli silẹ́ -&Pádé -Ìtọ́kasí -&Yiyan agbara détà -600 -Àṣàyàn &gbogbo faíli -Paa Àṣàyàn gbogbo faíli -&Yi Àṣàyàn Padà -Àṣàyàn... -Paa Àṣàyàn... -Àṣàyàn bi irú faíli -Paa Àṣàyàn bi irú faíli -700 -&Àmi ńlá -&Àmi Kékeré -&Akọjọ́ -&Awọn alaye -730 -Lai tọ lẹsẹsẹ -Iwò Ṣepẹtẹ -&Irinṣẹ́ méjì -&Pẹpẹ irinṣẹ́ -Ṣi pìlẹ̀ -Lọ sókè lẹẹkan -Ìtàn àpò faíli... -&Sọdọ̀tun -Isọdọ̀tun aládàáṣẹ́ -750 -Kó pẹpẹ irinṣẹ́ jọ́pọ -Ojúlówó pẹpẹ irinṣẹ́ -Onini ńlá -Fihàn Ìpilẹ̀sọ́ ọ̀rọ̀ Onini -800 -Fi àpò faíli si àpò faíli ayanfẹ -Àmì ìwé -900 -&Ìyàn... -&Ala -960na -&Àkóónú... -&Nípa 7-Zip... -1003 -Ọnà -Orukọ -Ìkọpọmó -Àpò faíli -Ìwọn -Ìwọn àkójọpọ̀ -Àwòmọ́ -Idásílẹ́ -Ìráyè sí -Atúnṣe -Alagbara -Ọrọ ìwòye -Ìwépọ̀ -Kọkọ pín -Pín lẹ́hìn -Ìwe itúmọ̀-èdè - -Irú -Egboogi -Ito lẹsẹsẹ -OS agbalejo -Ìlànà ètò fáìlì -Onilò -Ìwọ́pọ̀ -Dínà -Ọrọ ìwòye -Ipò -Ìpele ọ̀nà -Àpò faíli -Faíli -Ẹya -Ọ̀pọ̀ òǹlò -Ọ̀pọ̀ òǹlò ọpọlọpọ -Aiṣedeede -Awọn Ìtọ́kasí -Àkọsílẹ -Awọn ọ̀pọ̀ òǹlò - -Bíìtì-8 -Endian itóbi -CPU -Ìwọn gangan -Ìwọn àkọsórí -Checksum -Ti ìwà -Àdírẹ́ẹ̀sì àfojúunúṣe -ID -Orúkọ kuru -Ohun èlò eleda -Ìwọn apákàan -Móòdù -Ìtọ́kasí to ni aami -Ìṣiṣe -Ìwọn lapapọ -Aaye to ṣẹku -Ìwọn ìṣùpọ̀ -Aṣàmì -Agbègbè orúkọ -Olùpèsè -Ààbò NT -Yiyan agbara détà -Olurànlọwọ -Ààtàn -O jẹ igi - - -Irú -Awọn ìṣiṣe -Awọn ìṣiṣe -Awọn ìkìlọ̀ -Ìkìlọ̀ -Agbara détà -Yiyan agbara détà -Ìwọn Yiyan Agbara -Ìwọn àfojúunúṣe -Ìwọn ìtú erú -Ìwọn gangan lapapọ -Atọ́kà ọ̀pọ̀ òǹlò -ẹ̀ka-ìwọn -ọrọ ìwòye kuru -Ojú-ìwé kóòdù - - - -Ìwọn ìrú -Ìwọn àfibọ̀ ìyọkúrò -Ìtọ́kasí -Ìtọ́kasí lile -iNode - -Kàn kàá -2100 -Ìyàn -Èdè -Èdè: -Aṣàtúnṣe -&Aṣàtúnṣe: -&íyàtọ̀: -2200 -Ìlànà ètò -Da fáìlì pọ-mọ 7-Zip: -Gbogbo onilò -2301 -Sọ 7-Zip pọ̀ mọ mẹ́nù ọ̀gàngán ipò ṣẹ́ẹ̀lì -Mẹ́nù ọ̀gàngán ipò pérété -Ijẹri ninu mẹ́nù ọ̀gàngán ipò: -Àmì ninu mẹ́nù ọ̀gàngán ipò -2320 -<Àpò faíli> -<Àpò faíli àkójọ́pọ> -Ṣi àpò faíli àkójọ́pọ -Tú faíli silẹ... -Fi si àpò faíli àkójọ́pọ... -Dán àpò faíli àkójọ́pọ wò -Tú faíli si inú ibí -Tú faíli si inú {0} -Fi si {0} -Kó faíli jọ́pọ, ko rán í-meèlì... -Kó faíli jọ́pọ si {0} ko rán í-meèlì -2400 -Àpò faíli -&Àpò faíli iṣiṣẹ́ -&Ìlànà ètò àpò faíli ibùgbé -&Lọ́wọ́lọ́wọ́ -&Pàtó kan: -Lò fun àwo àká-ọ̀rọ̀ yiyọ nìkan -Yan ilé fun àpò faíli àkójọ́pọ ibùgbé -2500 -Ìtò -Fihàn ".." ijẹri -Fihàn àmì faíli gidi -Fihàn mẹ́nù ìlànà ètò -&Àṣàyàn gbogbo ìlà ìbú -Fihàn &àwọn ìlà gírìdì -Ìṣíra tẹ̀ lẹ́ẹ̀kan láti ṣí ijẹri -&Yiyan móòdù àṣàyàn -Lò &ojú-ìwé ti o nlò ibi ìpamọ́ ńlá -2900 -Nípa 7-Zip -Ẹ̀yà àìrídìmú ṣ'ofo ni 7-Zip -3000 -Ìlànà ètò ò le pín ibi ìpamọ́ ti o tó -Kò si iṣiṣe kankan -Iye àṣàyàn: {0} -Kò lé dá àpò faíli '{0}' -Kò lé ṣàfikùn àpò faíli àkójọ́pọ yí. -Kò lé ṣí àpò faíli '{0}' sí àpò faíli àkójọ́pọ -Kò lé ṣí àpò faíli àkójọ́pọ (ìpàrokò). ọrọ̀ aṣínà láìpé -Faíli yí o baamu -Faíli {0} ti wà níbẹ -Faíli '{0}' títúnṣe.\n ṣe ẹ fẹ̀ túnṣe si inú àpò faíli àkójọ́pọ? -Kò le ṣàfikún fun faíli yí \n'{0}' -Kò le ṣí Olótùú. -Faíli yí jọ àkóràn(Ààyè to wa ni àárín orukọ faíli ti poju). -Kò le pè ìmú iṣiṣẹ́ yí láti àpò faíli to ni ọ̀nà gígùn. -Ẹ gbọdọ ṣàyàn faíli kan. -Ẹ gbọdọ ṣàyàn faíli kan tàbí faíli pupọ -Ijẹri ti ẹ ṣà ti pọju -Kò le ṣí faíli yí bí {0} àpò faíli àkójọ́pọ -Faíli yí ti ṣí bí {0} àpò faíli àkójọ́pọ -Àpò faíli àkójọ́pọ yí ti ṣí pẹlu aiṣedeede -3300 -Ìtúsilẹ -Ìkójọ́pọ -Ìdánwò -Ìṣíṣí... -Ìṣẹ̀dà àwòrán ... -Ìyọkúrò -3320 -Ìfi-sí -Ìṣàfikùn -Ìtúpalẹ̀ -Ìfijọ -Ìṣatopọ -Mbẹ́ -Ìpaarẹ -Ìdá àkọsórí -3400 -Túsilẹ -&Tú faíli si inú: -Yan ibi ti awọn faíli ma tú si. -3410 -Móòdù ọ̀nà: -Gbogbo orukọ ọ̀nà -Kò si orukọ ọ̀nà -Orukọ ọ̀nà ọlọ́gangan -Orukọ ọ̀nà ìbátan -3420 -Móòdù ìkọsórí: -Béèrè kí ó tó kọ sórí faíli -Kọ sórí faíli lai béèrè -Mà wo faíli tó ti wà níbẹ -Tun orukọ kọ laládàáṣiṣẹ́ -Tun kọ orukọ faíli tó ti wà níbẹ laládàáṣiṣẹ́ -3430 -Mú ìfijọ àpò faíli ìpìlẹ̀ kúrò -Da ààbò faíli padà -3500 -Tẹnumọ́ àfirọ́pò faíli -Àpò fáìlì èbúté ti ní fáìlì ìgbésẹ́. -Ṣe ẹ fẹ̀ ṣàfirọ́pò fun fáìlì tó ti wà níbẹ -pẹlu fáìlì yí? -Báìtì {0} -&Tun orukọ kọ laládàáṣiṣẹ́ -3700 -Kọ si àtìlẹ́yìn fun ètò àkójọ́pọ yí '{0}'. -Ìṣiṣe détà ṣẹlẹ ní inú '{0}'. Fáìlì ti bajẹ. -Ìkùnà CRC ṣẹlẹ ní inú '{0}'. Fáìlì ti bajẹ. -Ìṣiṣe détà ṣẹlẹ ní inú fáìlì pàroko '{0}'. Tun wo ọ̀rọ̀ aṣínà -Ìkùnà CRC ṣẹlẹ ní inú fáìlì pàroko '{0}'. Tun wo ọ̀rọ̀ aṣínà -3710 -Tun wo ọ̀rọ̀ aṣínà -3721 -Ko si àtìlẹ́yìn fun ètò àkójọ́pọ yí -Ìṣiṣe détà ṣẹlẹ -Détà ò ṣeélò -Ìkùnà CRC -Détà ti parí lójijì -Détà ṣi wa lẹ̀hìn détà ọ̀gangan -Kò ṣe faíli akójọ́pọ -Ìṣiṣe àkọlé -Tun wo ọ̀rọ̀ aṣínà -3763 -Ìbẹ̀rẹ̀ faíli akójọ́pọ ò ṣeélò -Ìbẹ̀rẹ̀ faíli akójọ́pọ ò ṣe tẹnumọ́ - - - -Ko si àtìlẹ́yìn fun àfidámọ̀ yí -3800 -Tẹ̀ ọ̀rọ̀ aṣínà -Tẹ̀ ọ̀rọ̀ aṣínà: -ṣítẹ̀ ọ̀rọ̀ aṣínà: -&Fihàn ọ̀rọ̀ aṣínà -Awọn ọ̀rọ̀ aṣínà ò dọgba -Lò ábídí, iye tàbí aami Gẹ̀ẹ́sì nìkan (!, #, $, ...) fun ọ̀rọ̀ aṣínà -Ọ̀rọ̀ aṣínà ti gùn ju -Ọ̀rọ̀ aṣínà -3900 -Àsìkò ti okan: -Àsìkò ti o ku: -Ìwọn lapapọ: -Ìyára: -Ìṣètò: -Ìpín Ìkójọ́pọ: -Awọn ìṣiṣe: -Awọn faíli àkójọ́pọ: -4000 -Fi si àpò faíli àkójọ́pọ -&Faíli àkójọ́pọ: -&Móòdù ìṣàfikún: -&Ìgúnrégé faíli àkójọ́pọ: -&Ìpele àkójọ́pọ: -&Ọ̀nà àkójọ́pọ: -&Ìwọn àtúmọ̀-èdè: -&Ìwọn ó̩ró̩gbólóhùn: -Ìwọn sèdíwọ: -Iye èròjà atẹ̀lélànà CPU: -&Awọn afòdiwọ̀n: -Ìyàn -Dá àpò faíli àkójọ́pọ fun SF&X -Ko faíli alájọpín jọ́pọ -Ìpàrokò -Móòdù ìpàrokò: -&Ṣe ìpàrokò fun orúkọ faíli -ìlò ibi ìpamọ́ fun àkójọ́pọ: -ìlò ibi ìpamọ́ fun ìtúsilẹ: -Paarẹ faíli lẹ̀hìn àkójọ́pọ -4040 -Fi ìtọ́kasí to ni aami pamọ́ -Fi ìtọ́kasí lile pamọ́ -Fi agbara détà pamọ́ -Fi àfirọ́pò faíli pamọ́ -4050 -Ṣàfipamọ́ -Kíá ju -Kíákíá -Déédéé -Ki o pọju -Ki o púpọ̀ -4060 -Fi faíli si ki o tun fi rọ́pò -Ṣàfikùn faili ki o tun fi si -Sọ awọn faili lọ́wọ́ di ọ̀tun -Mú awọn faíli dọ́gba -4070 -Wáròyìn -Gbogbo faíli -Lai le -Lile -6000 -Ṣẹ̀dà -Gbé -Ṣẹ̀dà si: -Gbé si: -Ìṣẹ̀dà -Ìgbé... -Ìtunkọ... -Ṣàyàn èbúté àpò faíli. -Ìmú ṣiṣẹ́ o ni àtìlẹ́yìn fun àpò faíli. -Ìṣiṣe ṣẹlẹ ní ìtunkọ àpò faíli -Tẹnumọ́ ìṣẹ̀dà faíli -Ṣe ẹ́ dájú pe ẹ fẹ́ ṣẹ̀dà awọn faíli yí si àpò faíli àkójọ́pọ? -6100 -Tẹnumọ́ ìpaarẹ faíli -Tẹnumọ́ ìpaarẹ àpò faíli -Tẹnumọ́ ìpaarẹ àpò faíli ọ̀pọ̀ -Ṣe ẹ́ dájú pe ẹ fẹ́ paarẹ '{0}'? -Ṣe ẹ́ dájú pe ẹ fẹ́ paarẹ '{0}' a àti gbogbo àkóónú ẹ? -Ṣe ẹ́ dájú pe ẹ fẹ́ paarẹ iye ijẹri yí {0} ? -Ìpaarẹ... -Ìṣiṣe ṣẹlẹ ni ìpaarẹ faíli tàbí àpò faíli -Ìlànà ètò o le gbé faíli to ni orúkọ gígùn si inú Ààtàn -6300 -Dá àpò faíli -Dá faíli -Orúkọ àpò faíli: -Orúkọ faíli: -Àpò faíli -Faíli tuntun -Ìṣiṣe ṣẹlẹ ni ìdá àpò faíli -Ìṣiṣe ṣẹlẹ ni ìdá faíli -6400 -Ọrọ ìwòye -&Ọrọ ìwòye: -Ṣàyàn -Paa Àṣàyàn -Asẹ́ iye: -6600 -Àbùdá -Akọọ́lẹ̀ àpò faíli -Atọpinpin-Àìṣedédé iṣé -Iṣé -7100 -Kọ̀mpútà -Alásopọ̀ -Àkọsílẹ̀ -Ìlànà ètò -7200 -Fi-sí -Túsilẹ -Dán-wò -Ṣẹ̀dà -Gbé -Paarẹ -Ìròyìn -7300 -Pín faíli -&Pín si: -Pín si &ọ̀pọ̀ òǹlò, báìtì: -Ìpín... -Tẹnumọ́ Ìpín -Ṣe ẹ́ dájú pe ẹ fẹ́ pín faíli si ọ̀pọ̀ òǹlò {0}? -Ọ̀̀pọ̀ òǹlò láti kéré ju ìwọn faíli ojulowo lọ -ìwọn ọ̀pọ̀ òǹlò láìpé -Yan ìwọn ọ̀pọ̀ òǹlò: {0} báìtì.\nṢe ẹ́ dájú pe ẹ fẹ́ pín àpò faíli àkójọ́pọ si ọ̀pọ̀ òǹlò awọn yí? -7400 -Kó faíli pọ̀ -&Kó faíli pọ̀ si: -Ìkópọ̀... -Ṣàyàn akọkọ faíli ìpín nìkan -Ko lè rí faíli ni inu faíli ìpín -Ko lè rí ju apá faíli kan lọ -7500 -Ìkà checksum... -Ìròyìn Checksum -CRC checksum fun détà: -CRC checksum fun détà àti orúkọ: -7600 -Ala -Ìlò ibi ìpamọ́: -Akójọ́pọ -Ìtúsilẹ -Ìgbéléwọ̀n -Awọn ìgbéléwọ̀n lapapọ -Lọ́wọ́lọ́wọ́ -èsì -Ìlò CPU -Ìgbéléwọ̀n / Ìlò -Ìwé ìjáde: -7700 -Ìtọ́kasí -Ìtọ́kasí -Ìtọ́kasí láti: -Ìtọ́kasí: -7710 -Irú Ìtọ́kasí -Ìtọ́kasí lile -Faíli Ìtọ́kasí to ni aami -Iwé ilana Ìtọ́kasí to ni aami -Idapọ iwé ilana diff -Nru p7zip-rar-16.02/GUI/Lang/zh-cn.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-cn.txt --- p7zip-rar-16.02/GUI/Lang/zh-cn.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-cn.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; : Modern Tiger, kaZek, Hutu Li -; : Sparanoid (aka. Tunghsiao Liu) -; 15.05 : 2015-06-15 : Tunghsiao Liu : http://sparanoid.com/lab/7z/ -; -; -; -; -; -; -; -; -0 -7-Zip -Chinese Simplified -简体中文 -401 -确定 -取消 - - - -是(&Y) -否(&N) -关闭(&C) -帮助 - -继续(&C) -440 -全是(&A) -全否(&L) -停止 -重新开始 -后台(&B) -前台(&F) -暂停(&P) -已暂停 -您真的要取消吗? -500 -文件(&F) -编辑(&E) -查看(&V) -书签(&A) -工具(&T) -帮助(&H) -540 -打开(&O) -当前窗口打开(&I) -新建窗口打开(&U) -查看(&V) -编辑(&E) -重命名(&M) -复制到(&C)... -移动到(&M)... -删除(&D) -分割文件(&S)... -合并文件(&B)... -属性(&R) -注释(&N) -文件校验 -文件比较 -新建文件夹 -新建文件 -退出(&X) -链接 -交替数据流(&A) -600 -全选(&A) -全部取消 -反选(&I) -选择... -取消选择... -选择相同类型的文件 -取消选择相同类型的文件 -700 -大图标(&G) -小图标(&M) -列表(&L) -详细信息(&D) -730 -不排序 -平铺模式 -双版面(&2) -工具栏(&T) -打开根文件夹 -向上 -文件夹历史... -刷新(&R) -自动刷新 -750 -档案工具栏 -标准工具栏 -大按钮 -显示按钮文字 -800 -添加到书签(&A) -书签 -900 -选项(&O) -基准测试(&B) -960 -查看帮助(&C) -关于 7-Zip (&A) -1003 -路径 -名称 -扩展名 -文件夹 -大小 -压缩后大小 -属性 -创建时间 -访问时间 -修改时间 -固实 -注释 -加密 -之前分割 -之后分割 -字典大小 - -类型 -剔除项 -算法 -主操作系统 -文件系统 -用户 -组 -字块 -注释 -定位 -路径前缀 -文件夹 -文件 -版本 -卷 -多卷压缩 -偏移 -链接 -字块 -分卷 - -64 位 -大端序 -CPU -物理大小 -文件头大小 -校验和 -特征 -虚拟地址 -ID -短文件名 -创建程序 -扇区大小 -模式 -链接 -错误 -总大小 -可用空间 -簇大小 -卷标 -本地名称 -供应者 -NT 安全 -交替数据流 -Aux -已删除 -树状结构 - - -错误类型 -错误 -错误 -警告 -警告 -数据流 -交替数据流 -交替数据流大小 -虚拟大小 -释放大小 -完整物理大小 -卷索引 -SubType -短评论 -代码页 - - - -尾部大小 -嵌入尾部大小 -链接类型 -硬链接 -iNode - -只读 -2100 -选项 -语言 -选择语言: -编辑器 -指定编辑器(&E): -指定文件比较程序(&D): -2200 -系统 -使用 7-Zip 关联的文件类型: -所有用户 -2301 -添加 7-Zip 到右键菜单 -层叠右键菜单 -选择在右键菜单中显示的项目: -右键菜单显示图标 -2320 -<文件夹> -<档案> -打开压缩包 -提取文件... -添加到压缩包... -测试压缩包 -提取到当前目录 -提取到 {0} -添加到 {0} -压缩并邮寄... -压缩 {0} 并邮寄 -2400 -文件夹 -工作文件夹(&W) -系统临时文件夹(&S) -当前文件夹(&C) -指定位置(&S) -仅用于可移动设备 -指定一个存放临时压缩包的位置。 -2500 -显示 -显示「..」项 (双击向上) -显示真实图标 -显示系统菜单 -整行选择(&F) -显示网格线(&G) -单击打开项目 -7-Zip 传统选择模式(&A) -使用大内存页(&L) -2900 -关于 7-Zip -7-Zip 是一款自由软件。您可以通过捐赠的方式来支持 7-Zip 的开发。 -3000 -系统无法分配所需内存 -未发现错误 -选定 {0} 个项目 -无法创建文件夹「{0}」 -不支持此压缩包的更新操作。 -无法作为压缩包打开文件「{0}」 -无法打开加密压缩包「{0}」。密码错误? -不支持的压缩包格式 -文件 {0} 已存在 -文件「{0}」已修改。\n你想在压缩文件中更新它? -无法更新文件\n「{0}」。 -无法运行外部编辑。 -此文件似乎是病毒文件(文件名中包含多个空格)。 -无法为过长的路径完成该操作。 -您必须选择一个文件 -您至少要选择一个文件 -项目太多 -无法作为 {0} 压缩包打开该文件 -文件以 {0} 格式打开 -压缩包包含偏移 -3300 -正在提取 -正在压缩 -正在测试 -正在打开... -正在搜索... -正在移除 -3320 -正在添加 -正在更新 -正在分析 -正在复制 -正在打包 -正在跳过 -正在删除 -正在创建文件头 -3400 -提取 -提取到(&X): -指定一个提取文件的位置。 -3410 -路径模式 -完整路径 -无路径 -绝对路径 -相对路径 -3420 -覆盖模式 -在覆盖前询问 -不提示自动覆盖 -跳过已经存在的文件 -自动重命名 -重命名现有文件 -3430 -排除根目录重复文件 -恢复文件安全设置 -3500 -确认文件替换 -此文件夹已包含一个相同名称的文件。 -是否将现有文件 -替换为 -{0} 字节 -自动重新命名(&U) -3700 -不支持的压缩算法「{0}」。 -数据「{0}」发生错误,文件已损坏。 -CRC 校验「{0}」失败,文件已损坏。 -加密文件「{0}」数据有误,密码错误? -加密文件「{0}」CRC 数据校验有误,密码错误? -3710 -密码错误? -3721 -不支持的压缩算法 -数据错误 -CRC 校验失败 -数据不可用 -文件末端错误 -有效数据外包含额外数据 -非压缩包 -头部错误 -密码错误 -3763 -档案起始位置不可用 -无法确认档案起始位置 - - - -不支持此功能 -3800 -输入密码 -输入密码: -重新输入: -显示密码(&S) -密码不匹配 -密码只允许英文字符,数字,以及特殊字符 (!、#、$...) -密码过长 -密码 -3900 -已用时间: -剩余时间: -总大小: -速度: -已处理: -压缩率: -发生错误: -压缩包: -4000 -添加到压缩包 -压缩包(&A): -更新方式(&U): -压缩格式(&F): -压缩等级(&L): -压缩方法(&M): -字典大小(&D): -单词大小(&W): -固实数据大小: -CPU 线程数: -参数(&P): -选项 -创建自释放程序(&X) -压缩共享文件 -加密 -加密算法: -加密文件名(&N) -压缩所需内存: -解压缩所需内存: -操作完成后删除源文件 -4040 -保存符号链接 -保存硬链接 -保存交替数据流 -保存文件安全设置 -4050 -仅存储 -极速压缩 -快速压缩 -标准压缩 -最大压缩 -极限压缩 -4060 -添加并替换文件 -更新并添加文件 -只刷新已存在的文件 -同步压缩包内容 -4070 -浏览 -所有文件 -非固实 -固实 -6000 -复制 -移动 -复制到: -移动到: -正在复制... -正在移动... -正在重新命名... -选择目标文件夹。 -不支持当前操作 -无法重命名文件或文件夹。 -确认文件复制 -您确定复制文件到压缩包 -6100 -确认文件删除 -确认文件夹删除 -确认删除多个文件 -确实要删除 「{0}」吗? -确实要删除文件夹「{0}」以及全部内容吗? -确实要删除这 {0} 项? -正在删除... -无法删除文件或文件夹. -系统无法将过长路径的文件移动到回收站 -6300 -新建文件夹 -新建文件 -文件夹名称: -文件名: -新建文件夹 -新建文件.txt -无法创建文件夹 -无法新建文件 -6400 -注释 -注释(&C): -选择 -取消选定 -掩码: -6600 -属性 -文件夹历史 -诊断信息 -信息 -7100 -我的电脑 -网络 -我的文档 -系统 -7200 -添加 -提取 -测试 -复制 -移动 -删除 -信息 -7300 -分割文件 -分割文件到(&S): -分卷大小,字节(&V): -正在分割... -确认分割 -您确认要将文件分割为 {0} 个分卷? -分卷大小必须小于原文件大小 -分卷大小错误 -指定分卷大小:{0} 字节。\n您确定要分割当前文件吗? -7400 -合并文件 -合并文件到(&S): -正在合并... -请选择分卷的首个文件 -无法识别文件为压缩分卷 -无法找到其他压缩分卷 -7500 -正在校验... -校验信息 -CRC 数据校验: -CRC 数据及文件名校验: -7600 -基准测试 -内存使用: -压缩 -解压缩 -评分 -总体评分 -当前 -结果 -CPU 使用率 -使用率评分 -已通过: -7700 -链接 -链接 -链接自: -链接到: -7710 -链接类型 -硬链接 -文件符号链接(Symbolic Link) -目录符号链接(Symbolic Link) -目录接合点(Directory Junction) diff -Nru p7zip-rar-16.02/GUI/Lang/zh-tw.txt p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-tw.txt --- p7zip-rar-16.02/GUI/Lang/zh-tw.txt 2015-09-05 17:54:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/Lang/zh-tw.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -;!@Lang2@!UTF-8! -; 4.59 : Leon Tseng, sec2, 琥珀 -; 9.07 - 15.00 : Jack Pang : http://www.developershome.com/7-zip/ -; -; -; -; -; -; -; -; -; -0 -7-Zip -Chinese Traditional -繁體中文 -401 -確定 -取消 - - - -是(&Y) -否(&N) -關閉(&C) -說明 - -繼續(&C) -440 -全部皆是(&A) -全部皆否(&L) -停止 -重新開始 -背景作業(&B) -前景作業(&F) -暫停(&P) -暫停 -您確定要取消嗎? -500 -檔案(&F) -編輯(&E) -檢視(&V) -我的最愛(&A) -工具(&T) -說明(&H) -540 -開啟(&O) -在內部開啟(&I) -在外部開啟(&U) -檢視(&V) -編輯(&E) -重新命名(&M) -複製到(&C)... -移動到(&M)... -刪除(&D) -分割檔案(&S)... -合併檔案(&B)... -內容(&R) -註解(&N) -計算驗證值 -比較檔案 -建立資料夾 -建立檔案 -結束(&X) -連結 -附加資料流(&A) -600 -全選(&A) -全不選 -反向選擇(&I) -選取... -取消選取... -依類型選取 -依類型不選取 -700 -大圖示(&G) -小圖示(&M) -清單(&L) -詳細資料(&D) -730 -不排序 -攤開檢視 -雙窗格(&2) -工具列(&T) -開啟根目錄 -上移一層 -資料夾歷程記錄... -重新整理(&R) -自動重新整理 -750 -壓縮檔工具列 -標準工具列 -大型按鈕 -顯示按鈕文字 -800 -將資料夾加入我的最愛為(&A) -書籤 -900 -選項(&O)... -效能測試(&B) -960 -內容(&C)... -關於 7-Zip(&A)... -1003 -路徑 -名稱 -副檔名 -資料夾 -大小 -封裝後大小 -屬性 -建立日期 -存取日期 -修改日期 -緊密 -註解 -加密 -分割前 -分割後 -字典大小 - -類型 -防護 -方式 -主機作業系統 -檔案系統 -使用者 -群組 -區塊 -註解 -位置 -路徑前綴 -資料夾 -檔案 -版本 -卷 -多卷 -偏移 -連結 -區塊 -分卷 - -64 位 -大端序 -CPU -物理大小 -標頭大小 -驗證值 -特徵 -虛擬地址 -ID -簡稱 -創建程式 -扇區大小 -模式 -符號連結 -錯誤 -全部大小 -可用空間 -叢集大小 -標籤 -本機名稱 -提供者 -NT 安全性 -附加資料流 -Aux -刪除日期 -是否樹狀結構 - - -錯誤類型 -錯誤 -錯誤 -警告 -警告 -資料流 -附加資料流 -附加資料流大小 -虛擬大小 -解封後大小 -總物理大小 -卷索引 -子類型 -簡短註解 -代碼頁 - - - -文件尾大小 -嵌入式殘端大小 -連結 -硬連結 -iNode - -唯讀 -2100 -選項 -語言 -介面語言: -編輯器 -編輯器(&E): -檔案比較程式(&D): -2200 -系統 -使 7-Zip 與之產生關聯: -所有使用者 -2301 -將 7-Zip 整合到快顯功能表中 -串聯式快顯功能表 -快顯功能表項目: -快顯功能表顯示圖示 -2320 -<資料夾> -<壓縮檔> -開啟壓縮檔 -解壓縮檔案... -加入壓縮檔... -測試壓縮檔 -解壓縮至此 -解壓縮至 {0} -加入 {0} -壓縮並郵寄... -壓縮成 {0} 並郵寄 -2400 -資料夾 -工作資料夾(&W) -系統暫存資料夾(&S) -目前的資料夾(&C) -指定的資料夾(&S): -僅用於卸除式磁碟機 -請指定存放暫存壓縮檔的位置。 -2500 -設定 -顯示 ".." 項目 -顯示實際檔案圖示 -顯示系統選單 -整列選取(&F) -顯示格線(&G) -單擊開啟項目 -使用替代選擇模式(&A) -使用大記憶體分頁(&L) -2900 -關於 7-Zip -7-Zip 為自由軟體 -3000 -系統未能提供所需記憶體空間 -沒有任何錯誤 -已選取 {0} 個物件 -無法建立資料夾 '{0}' -此壓縮檔未支援更新操作。 -無法開啟壓縮檔 '{0}' -無法開啟加密的壓縮檔 '{0}'。錯誤的密碼? -不支援的壓縮檔類型 -檔案 {0} 已存在 -檔案 '{0}' 已被修改過。\n您是否要在此壓縮檔內更新檔案? -無法更新檔案\n'{0}' -無法啟動編輯器。 -檔案似是病毒(檔案名稱含有很多空格)。 -不能完成操作,因資料夾路徑過長。 -您必須選擇一個檔案 -您必須選擇最少一個檔案 -項目過多 -無法開啟為 {0} 壓縮檔 -開啟為 {0} 壓縮檔 -壓縮檔以偏移值開啟 -3300 -正在解壓縮 -正在壓縮 -測試 -正在開啟... -正在掃瞄... -正在移除 -3320 -正在加入 -正在更新 -正在分析 -正在複製 -正在重新封裝 -正在略過 -正在刪除 -正在建立標頭 -3400 -解壓縮 -解壓縮至(&X): -請指定存放暫存壓縮檔的位置。 -3410 -路徑模式: -完整的路徑名稱 -不要路徑名稱 -絕對路徑 -相對路徑 -3420 -覆寫模式 -覆寫前先詢問我 -覆寫時不詢問 -略過現有的檔案 -自動重新命名 -自動重新命名現有的檔案 -3430 -刪除重複的根目錄 -恢復檔案安全設定 -3500 -確認取代檔案 -目的資料夾已包含要處理的檔案。 -您要取代現有的檔案 -而改用這個檔案嗎? -{0} 位元組 -自動重新命名(&U) -3700 -'{0}' 未支援此壓縮方式。 -'{0}' 中的資料含有錯誤。檔案已損壞。 -'{0}' 的 CRC 驗證失敗。檔案已損壞。 -加密檔 '{0}' 中的資料含有錯誤。錯誤的密碼? -加密檔 '{0}' 的 CRC 驗證失敗。錯誤的密碼? -3710 -錯誤的密碼? -3721 -不支援此壓縮方式 -資料含有錯誤 -CRC 驗證失敗 -資料不能使用 -資料異常終結 -有效負載盡頭外還有其他資料 -不是壓縮檔 -標頭錯誤 -密碼錯誤 -3763 -壓縮檔的開端不能使用 -未能確認壓縮檔的開端 - - - -不支援的功能 -3800 -輸入密碼 -輸入密碼: -重新輸入密碼: -顯示密碼(&S) -密碼不一致 -僅能使用英文字母、數字和特殊字元 (!, #, $, ...) 當作密碼 -密碼太長 -密碼 -3900 -經過時間: -剩餘時間: -大小: -速度: -已處理: -壓縮率: -錯誤數: -壓縮檔: -4000 -加入壓縮檔 -壓縮檔(&A): -更新模式(&U): -壓縮檔格式(&F): -壓縮層級(&L): -壓縮方式(&M): -字典大小(&D): -字組大小(&W): -結實區塊大小: -CPU 線程數: -參數(&P): -選項 -建立自解壓縮檔(&X) -壓縮共用檔案 -加密 -加密方法: -加密檔名(&N) -壓縮時記憶體使用: -解壓縮時記憶體使用: -壓縮後刪除檔案 -4040 -儲存符號連結 -儲存硬連結 -儲存附加資料流 -儲存檔案安全設定 -4050 -封存 -最快速壓縮 -快速壓縮 -一般壓縮 -最大壓縮 -極致壓縮 -4060 -加入並取代檔案 -更新並加入檔案 -更新現有的檔案 -同步處理檔案 -4070 -瀏覽 -所有檔案 -非結實 -結實 -6000 -複製 -移動 -複製到: -移動到: -正在複製... -正在移動... -正在重新命名... -選擇目標資料夾。 -未支援的操作。 -重新命名檔案或資料夾時發生錯誤 -確認複製檔案 -您確定要複製檔案至壓縮檔? -6100 -確認刪除檔案 -確認刪除資料夾 -確認刪除多個檔案 -您確定要刪除 '{0}' 嗎? -您確定要刪除資料夾 '{0}' 以及它所有的內容嗎? -您確定要刪除這 {0} 個項目嗎? -正在刪除... -刪除檔案或資料夾時發生錯誤 -系統不能移動路徑過長的檔案到資源回收筒 -6300 -建立資料夾 -建立檔案 -資料夾名稱: -檔案名稱: -新增資料夾 -新增檔案 -建立資料夾時發生錯誤 -建立檔案時發生錯誤 -6400 -註解 -註解(&C): -選取 -取消選取 -遮罩: -6600 -內容 -資料夾歷程記錄 -診斷訊息 -訊息 -7100 -電腦 -網路 -文件 -系統 -7200 -加入 -解壓縮 -測試 -複製 -移動 -刪除 -資訊 -7300 -分割檔案 -分割到(&S): -分割壓縮檔,位元組(&V): -正在分割... -確認分割 -您確定要分割檔案為 {0} 個? -分割大小必須小於原始檔案大小 -不正確的分割大小 -指定的分割大小: {0} 位元組。\n您確定要分割為這些壓縮檔嗎? -7400 -合併檔案 -合併到(&C): -正在合併... -僅選取第一個檔案 -未能確認此檔案為完整檔案分割出來的一部分 -找不到完整檔案的其他部分 -7500 -正在計算驗證值... -驗證值資訊 -資料的 CRC 驗證值: -資料及名稱的 CRC 驗證值: -7600 -效能測試 -記憶體使用: -壓縮 -解壓縮 -評等 -整體評等 -目前 -結果 -CPU 使用 -評等 / 使用 -通過數: -7700 -連結 -連結 -連結自: -連結到: -7710 -連結類型 -硬連結 -檔案符號連結 -目錄符號連結 -目錄連接點 diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_compress.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_compress.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -[Desktop Entry] -ServiceTypes=inode/directory -Actions=CompressDialog;Compress7z;CompressZip;extractHere;ExtractSubdir;ExtractTo;test;Benchmark -X-KDE-Priority=TopLevel -X-KDE-Submenu=7-Zip -X-KDE-Icon=p7zip - -[Desktop Action CompressDialog] -Name=Add to Archive ... -Icon=p7zip -Exec=p7zipForFilemanager ad -t7z %U - -[Desktop Action Compress7z] -Name=Add to 7z Archive -Icon=p7zip -Exec=p7zipForFilemanager a -t7z %U - -[Desktop Action CompressZip] -Name=Add to Zip Archive -Icon=p7zip -Exec=p7zipForFilemanager a -tzip %U - -[Desktop Action extractHere] -Name=Extract Here -Exec=p7zipForFilemanager x %U -Icon=p7zip - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory -Icon=p7zip -Exec=p7zipForFilemanager xs %U - -[Desktop Action ExtractTo] -Name=Extract to ... -Icon=p7zip -Exec=p7zipForFilemanager xd %U - -[Desktop Action test] -Name=Test Archive -Exec=p7zipForFilemanager t %U -Icon=p7zip - -[Desktop Action Benchmark] -Name=Benchmark -Icon=p7zip -Exec=p7zipForFilemanager b - diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_compress2.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress2.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_compress2.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_compress2.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -[Desktop Entry] -ServiceTypes=all/allfiles -Actions=CompressDialog;Compress7z;CompressZip;extractHere;ExtractSubdir;ExtractTo;test;Benchmark -X-KDE-Priority=TopLevel -X-KDE-Submenu=7-Zip -X-KDE-Icon=p7zip - -[Desktop Action CompressDialog] -Name=Add to Archive ... -Icon=p7zip -Exec=p7zipForFilemanager ad -t7z %U - -[Desktop Action Compress7z] -Name=Add to 7z Archive -Icon=p7zip -Exec=p7zipForFilemanager a -t7z %U - -[Desktop Action CompressZip] -Name=Add to Zip Archive -Icon=p7zip -Exec=p7zipForFilemanager a -tzip %U - -[Desktop Action extractHere] -Name=Extract Here -Exec=p7zipForFilemanager x %U -Icon=p7zip - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory -Icon=p7zip -Exec=p7zipForFilemanager xs %U - -[Desktop Action ExtractTo] -Name=Extract to ... -Icon=p7zip -Exec=p7zipForFilemanager xd %U - -[Desktop Action test] -Name=Test Archive -Exec=p7zipForFilemanager t %U -Icon=p7zip - -[Desktop Action Benchmark] -Name=Benchmark -Icon=p7zip -Exec=p7zipForFilemanager b - diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_extract.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_extract.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -X-SuSE-translate=true -Encoding=UTF-8 -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=extractHere - -[Desktop Action extractHere] -Name=Extract Here with 7-zip -Exec=p7zipForFilemanager x %U -Icon=p7zip diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_extract_subdir.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_subdir.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_extract_subdir.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_subdir.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -X-SuSE-translate=true -Encoding=UTF-8 -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=ExtractSubdir - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory with 7-Zip -Icon=p7zip -Exec=p7zipForFilemanager xs %U diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_extract_to.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_to.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_extract_to.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_extract_to.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -X-SuSE-translate=true -Encoding=UTF-8 -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=ExtractTo - -[Desktop Action ExtractTo] -Name=Extract to ... with 7-Zip -Icon=p7zip -Exec=p7zipForFilemanager xd %U diff -Nru p7zip-rar-16.02/GUI/kde3/p7zip_test.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_test.desktop --- p7zip-rar-16.02/GUI/kde3/p7zip_test.desktop 2011-02-24 20:13:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/p7zip_test.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -X-SuSE-translate=true -Encoding=UTF-8 -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=test - -[Desktop Action test] -Name=Test with 7-zip -Exec=p7zipForFilemanager t %U -Icon=p7zip diff -Nru p7zip-rar-16.02/GUI/kde3/readme.txt p7zip-rar-16.02+really25.00+ds/GUI/kde3/readme.txt --- p7zip-rar-16.02/GUI/kde3/readme.txt 2008-11-30 17:00:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde3/readme.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ - - 7zG - === - - - -1) building ------------ - - make test_7zG : build bin/7zG and make some tests - - -2) installing 7zG (tested on Ubuntu 8.04) ------------------ - - copy the method used for 7z ! - - - find where 7z is installed - type 7z - - - copy the 7z shell - cp /usr/bin/7z /usr/bin/7zG - - - edit /usr/bin/7zG to replace 7z with 7zG - - - chmod 555 /usr/bin/7zG - - - copy bin/7zG according to what is written in /usr/bin/7zG - cp bin/7zG /usr/lib/p7zip/7zG - chmod 555 /usr/lib/p7zip/7zG - - - To have access to the Lang files, copy Lang - cp -r GUI/Lang /usr/lib/p7zip/Lang - find /usr/lib/p7zip/Lang -type d -exec chmod 555 {} \; - find /usr/lib/p7zip/Lang -type f -exec chmod 444 {} \; - - - - To have access to the help, copy help - cp -r GUI/help /usr/lib/p7zip/help - find /usr/lib/p7zip/help -type d -exec chmod 555 {} \; - find /usr/lib/p7zip/help -type f -exec chmod 444 {} \; - - - copy p7zipForFilemanager - cp GUI/p7zipForFilemanager /usr/bin/p7zipForFilemanager - chmod 555 /usr/bin/p7zipForFilemanager - - - copy the 7-zip icon - cp GUI/p7zip_16_ok.png /usr/share/icons/hicolor/16x16/apps/p7zip.png - chmod 444 /usr/share/icons/hicolor/16x16/apps/p7zip.png - -3) installing the context menu for KDE (dolphin) (tested on Ubuntu 8.04) --------------------------------------------------- - only for the user : - mkdir -p ~/.kde/share/apps/d3lphin/servicemenus/ - cp GUI/kde/*.desktop ~/.kde/share/apps/d3lphin/servicemenus/ - - - for all: - cp GUI/kde/*.desktop /usr/share/apps/d3lphin/servicemenus/ - - -4) installing the context menu for KDE (konqueror) (tested on Ubuntu 8.04) ----------------------------------------------------- - only for the user : - mkdir -p ~/.kde/share/apps/konqueror/servicemenus/ - cp GUI/kde/*.desktop ~/.kde/share/apps/konqueror/servicemenus/ - - for all: - cp GUI/kde/*.desktop /usr/share/apps/konqueror/servicemenus/ - - -5) installing the context menu for gnome (nautilus) ------------------------------------------------------ - don't know how to add a context menu in nautilus :( - diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_compress.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_compress.desktop 2011-02-24 20:41:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -[Desktop Entry] -Type=Service -ServiceTypes=inode/directory -MimeType=all/all; -Actions=CompressDialog;Compress7z;CompressZip;extractHere;ExtractSubdir;ExtractTo;test;Benchmark; -X-KDE-Priority=TopLevel -X-KDE-Submenu=7-Zip -X-KDE-Icon=p7zip -X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory - -[Desktop Action CompressDialog] -Name=Add to Archive ... -Icon=p7zip -Exec=p7zipForFilemanager ad -t7z %U - -[Desktop Action Compress7z] -Name=Add to 7z Archive -Icon=p7zip -Exec=p7zipForFilemanager a -t7z %U - -[Desktop Action CompressZip] -Name=Add to Zip Archive -Icon=p7zip -Exec=p7zipForFilemanager a -tzip %U - -[Desktop Action extractHere] -Name=Extract Here -Exec=p7zipForFilemanager x %U -Icon=p7zip - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory -Icon=p7zip -Exec=p7zipForFilemanager xs %U - -[Desktop Action ExtractTo] -Name=Extract to ... -Icon=p7zip -Exec=p7zipForFilemanager xd %U - -[Desktop Action test] -Name=Test Archive -Exec=p7zipForFilemanager t %U -Icon=p7zip - -[Desktop Action Benchmark] -Name=Benchmark -Icon=p7zip -Exec=p7zipForFilemanager b - diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_compress2.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress2.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_compress2.desktop 2011-02-23 20:36:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_compress2.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -[Desktop Entry] -Type=Service -ServiceTypes=all/allfiles -MimeType=all/all; -Actions=CompressDialog;Compress7z;CompressZip;extractHere;ExtractSubdir;ExtractTo;test;Benchmark; -X-KDE-Priority=TopLevel -X-KDE-Submenu=7-Zip -X-KDE-Icon=p7zip -X-KDE-ServiceTypes=KonqPopupMenu/Plugin - -[Desktop Action CompressDialog] -Name=Add to Archive ... -Icon=p7zip -Exec=p7zipForFilemanager ad -t7z %U - -[Desktop Action Compress7z] -Name=Add to 7z Archive -Icon=p7zip -Exec=p7zipForFilemanager a -t7z %U - -[Desktop Action CompressZip] -Name=Add to Zip Archive -Icon=p7zip -Exec=p7zipForFilemanager a -tzip %U - -[Desktop Action extractHere] -Name=Extract Here -Exec=p7zipForFilemanager x %U -Icon=p7zip - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory -Icon=p7zip -Exec=p7zipForFilemanager xs %U - -[Desktop Action ExtractTo] -Name=Extract to ... -Icon=p7zip -Exec=p7zipForFilemanager xd %U - -[Desktop Action test] -Name=Test Archive -Exec=p7zipForFilemanager t %U -Icon=p7zip - -[Desktop Action Benchmark] -Name=Benchmark -Icon=p7zip -Exec=p7zipForFilemanager b - diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_extract.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_extract.desktop 2011-02-24 20:52:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=extractHere; -Type=Service -X-KDE-ServiceTypes=KonqPopupMenu/Plugin - -[Desktop Action extractHere] -Name=Extract Here with 7-zip -Exec=p7zipForFilemanager x %U -Icon=p7zip diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_extract_subdir.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_subdir.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_extract_subdir.desktop 2011-02-24 20:52:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_subdir.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=ExtractSubdir; -Type=Service -X-KDE-ServiceTypes=KonqPopupMenu/Plugin - -[Desktop Action ExtractSubdir] -Name=Extract to subdirectory with 7-Zip -Icon=p7zip -Exec=p7zipForFilemanager xs %U diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_extract_to.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_to.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_extract_to.desktop 2011-02-24 20:52:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_extract_to.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=ExtractTo; -Type=Service -X-KDE-ServiceTypes=KonqPopupMenu/Plugin - -[Desktop Action ExtractTo] -Name=Extract to ... with 7-Zip -Icon=p7zip -Exec=p7zipForFilemanager xd %U diff -Nru p7zip-rar-16.02/GUI/kde4/p7zip_test.desktop p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_test.desktop --- p7zip-rar-16.02/GUI/kde4/p7zip_test.desktop 2011-02-24 20:52:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/p7zip_test.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Desktop Entry] -ServiceTypes=application/x-gzip,application/x-lha,application/x-tar,application/x-tgz,application/x-tbz,application/x-tbz2,application/x-zip,application/x-bzip,application/x-tzo,application/x-lzop,application/x-rar,application/x-rar-compressed,application/x-zoo,application/x-tarz,application/x-archive,application/x-bzip2,application/x-jar,application/x-deb,application/x-ace,application/x-7z,application/x-arc,application/x-arj,application/x-compress,application/x-cpio,application/x-pak -Actions=test; -Type=Service -X-KDE-ServiceTypes=KonqPopupMenu/Plugin - -[Desktop Action test] -Name=Test with 7-zip -Exec=p7zipForFilemanager t %U -Icon=p7zip diff -Nru p7zip-rar-16.02/GUI/kde4/readme.txt p7zip-rar-16.02+really25.00+ds/GUI/kde4/readme.txt --- p7zip-rar-16.02/GUI/kde4/readme.txt 2011-03-13 10:26:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/kde4/readme.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ - - 7zG - === - - - -1) building ------------ - - make test_7zG : build bin/7zG and make some tests - - -2) installing 7zG (tested on Ubuntu 10.10) ------------------ - - copy the method used for 7z ! - - - find where 7z is installed - type 7z - - - copy the 7z shell - cp /usr/bin/7z /usr/bin/7zG - - - edit /usr/bin/7zG to replace 7z with 7zG - - - chmod 555 /usr/bin/7zG - - - copy bin/7zG according to what is written in /usr/bin/7zG - cp bin/7zG /usr/lib/p7zip/7zG - chmod 555 /usr/lib/p7zip/7zG - - - To have access to the Lang files, copy Lang - cp -r GUI/Lang /usr/lib/p7zip/Lang - find /usr/lib/p7zip/Lang -type d -exec chmod 555 {} \; - find /usr/lib/p7zip/Lang -type f -exec chmod 444 {} \; - - - - To have access to the help, copy help - cp -r GUI/help /usr/lib/p7zip/help - find /usr/lib/p7zip/help -type d -exec chmod 555 {} \; - find /usr/lib/p7zip/help -type f -exec chmod 444 {} \; - - - copy p7zipForFilemanager - cp GUI/p7zipForFilemanager /usr/bin/p7zipForFilemanager - chmod 555 /usr/bin/p7zipForFilemanager - - - copy the 7-zip icon - cp GUI/p7zip_16_ok.png /usr/share/icons/hicolor/16x16/apps/p7zip.png - chmod 444 /usr/share/icons/hicolor/16x16/apps/p7zip.png - -3) installing the context menu for KDE (dolphin or konqueror) (tested on Ubuntu 10.10) --------------------------------------------------- - for all: - cp GUI/kde4/*.desktop /usr/share/kde4/services/ServiceMenus/ - - -5) installing the context menu for gnome (nautilus) ------------------------------------------------------ - don't know how to add a context menu in nautilus :( - diff -Nru p7zip-rar-16.02/GUI/p7zipForFilemanager p7zip-rar-16.02+really25.00+ds/GUI/p7zipForFilemanager --- p7zip-rar-16.02/GUI/p7zipForFilemanager 2008-08-06 21:19:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/p7zipForFilemanager 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -#! /bin/sh - -# program t archive1.7z ... archiveN.7z -# program x directory_out archive1.7z ... archiveN.7z -# program xd directory_out archive1.7z ... archiveN.7z -# program a -t7z current_directory file1 ... fileN -# program ad -tzip current_directory file1 ... fileN - -P7ZIP="7zG" - -list=/tmp/p7zip.list.$$ -rm -f ${list} - -trace=/tmp/7zG1.txt -rm -f ${trace} - -for file in "$@" -do - echo "arg=${file}" >> ${trace} -done - -cmd="$1" -shift - -flag_ad="" -flag_type="" - -case "${cmd}" in -b|t) - ;; -x|xs) - ;; -xd) - flag_ad="-ad" - ;; -a) - flag_type="$1" - shift - ;; -ad) - flag_type="$1" - shift - flag_ad="-ad" - ;; -*) - echo "Unknown command \"${cmd}\"" - exit 1 - ;; -esac - -#ext=".7z" -#if [ "${flag_type}" = "-tzip" ] -#then -# ext=".zip" -#fi - -argn="$#" -file1="$1" -dir1=`dirname "${file1}"` -file2="$2" -echo "argn=${argn}" >> ${trace} -echo "flag_type=${flag_type}" >> ${trace} -echo "file1=${file1}" >> ${trace} -echo "dir1=${dir1}" >> ${trace} -echo "file2=${file2}" >> ${trace} - -if [ "a${dir1}" != "a" ] -then - cd "${dir1}" -fi - -for file in "$@" -do - file=`basename "${file}"` - echo ${file} >> ${list} - echo "list=${file}" >> ${trace} -done - -case "${cmd}" in -b) - ${P7ZIP} b - ;; -t) - ${P7ZIP} t -an -ai@${list} - ;; -x|xd) - ${P7ZIP} x ${flag_ad} -an -ai@${list} - ;; -xs) - dir_out=`dirname "${file1}"` - ${P7ZIP} x ${flag_ad} -o"*" -an -ai@${list} - ;; -a|ad) - if [ ${argn} -eq "1" ] - then - file=`basename "${file1}"`${ext} - echo "archive_out=${file}" >> ${trace} - ${P7ZIP} a ${flag_ad} ${flag_type} -i@${list} ${flag} -- "${file}" - else - file=`basename "${dir1}"`${ext} - echo "archive_out=${file}" >> ${trace} - ${P7ZIP} a ${flag_ad} ${flag_type} -i@${list} ${flag} -- "${file}" - fi - ;; -esac - -rm -f ${list} - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/GUI/p7zip_16.icns and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16.icns differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/GUI/p7zip_16.png and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16.png differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/GUI/p7zip_16_ok.png and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_16_ok.png differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/GUI/p7zip_32.png and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/GUI/p7zip_32.png differ diff -Nru p7zip-rar-16.02/GUI/p7zip_32.xpm p7zip-rar-16.02+really25.00+ds/GUI/p7zip_32.xpm --- p7zip-rar-16.02/GUI/p7zip_32.xpm 2008-08-06 20:41:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/GUI/p7zip_32.xpm 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* XPM */ -static char * p7zip_32_xpm[] = { -"32 32 3 1", -" c None", -". c #000000", -"+ c #FFFFFF", -" ", -" ", -" ", -" ", -"................................", -"................................", -"..++++++++++++++++++++++++++++..", -"..++++++++++++++++++++++++++++..", -"..++++++++++++++++++++++++++++..", -"..+++.............++++++++++++..", -"..+++.............++++++++++++..", -"..+++.............++++++++++++..", -"..+++..+++++++++..++++++++++++..", -"..+++..+++++++++..++++++++++++..", -"..+++........+++..++.......+++..", -"..+++.......+++...++.......+++..", -"..+++......+++....++++++...+++..", -"..+++.....+++.....+++++...++++..", -"..+++.....+++.....++++...+++++..", -"..+++.....+++.....+++...++++++..", -"..+++.....+++.....++...+++++++..", -"..+++.....+++.....++...+++++++..", -"..+++.............++.......+++..", -"..+++.............++.......+++..", -"..++++++++++++++++++++++++++++..", -"..++++++++++++++++++++++++++++..", -"..++++++++++++++++++++++++++++..", -"................................", -"................................", -" ", -" ", -" "}; diff -Nru p7zip-rar-16.02/README p7zip-rar-16.02+really25.00+ds/README --- p7zip-rar-16.02/README 2016-06-11 09:28:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ - p7zip 16.02 - =========== - -Homepage : http://p7zip.sourceforge.net/ - -p7zip is a port of the Windows programs 7z.exe and 7za.exe provided by 7-zip. - -7-zip is a file archiver with the highest compression ratio. -Homepage : www.7-zip.org - - 7z uses plugins (7z.so and Codecs/Rar.so) to handle archives. - 7za is a stand-alone executable (7za handles less archive formats than 7z). - 7zr is a light stand-alone executable that supports only 7z/LZMA/BCJ/BCJ2. - - Some GUI : - 7zG : beta stage - 7zFM : alpha stage - -CAUTION : ---------- - -- FIRST : DO NOT USE the 7-zip format for backup purpose on Linux/Unix because : - - 7-zip does not store the owner/group of the file - - On Linux/Unix, in order to backup directories you must use tar ! - to backup a directory : tar cf - directory | 7za a -si directory.tar.7z - to restore your backup : 7za x -so directory.tar.7z | tar xf - - -- if you want to send files and directories (not the owner of file) - to others Unix/MacOS/Windows users, you can use the 7-zip format. - - example : 7za a directory.7z directory - - do not use "-r" because this flag does not do what you think - do not use "directory/*" because of ".*" files - (example : "directory/*" does not match "directory/.profile") - -BUILD : -------- - - If you have downloaded the "bin" package, - use directly the program bin/7za. (tested on Debian 3, Ubuntu 14.10) - As the program is statically linked, its should run on many x86 or amd64 linux. - - If you have downloaded the "source" package, - - According to your OS, copy makefile.linux, - makefile.freebsd, makefile.cygwin, ... - over makefile.machine - - Example : building 7za, 7z (with its plugins), 7zr and Client7z and passing the internal tests - cp makefile.linux_x86_asm_gcc_4 makefile.linux - make all_test - - - If you want to make a parallel build on a 4 cpu machine : make -j 4 TARGET - - If you have trouble, try : make -f makefile.oldmake TARGET - - make depend : to rebuild the makefile.depend - make clean : to clean all directories - make : to build bin/7za - make sfx : to build bin/7zCon.sfx (7za can now create SFX archive) - make 7z : to build bin/7z and its plugins : - - "bin/7z.so" (GNU LGPL + AES code license) - - "bin/Codecs/Rar.so" (GNU LGPL + unRAR restriction) - make 7zr : to build bin/7zr - make all : to build bin/7za and bin/7zCon.sfx - make all2 : to build bin/7za, bin/7z (with its plugins) and bin/7zCon.sfx - make all3 : to build bin/7za, bin/7z (with its plugins), bin/7zr and bin/7zCon.sfx - make test : to test bin/7za (extracting, archiving, password ...) - make test_7z : to test bin/7z (extracting, archiving, password ...) - make test_7zr : to test bin/7zr (extracting, archiving, ...) - - make 7zG : to build bin/7zG and its plugins : - - "bin/7z.so" (GNU LGPL + AES code license) - - "bin/Codecs/Rar.so" (GNU LGPL + unRAR restriction) - make test_7zG : to test bin/7zG (extracting, archiving, ...) - - - this procedure has been tested on : - - x86 CPU : - Linux - Debian 3.0 Stable - Linux - Ubuntu 14.10 - Linux - Ubuntu 15.10 - MacOS 10.6.6 - - - AMD64 CPU : - Linux - Ubuntu 14.10 - Linux - Ubuntu 15.10 - MacOS 10.6.6 - - - powerpc CPU : - MacOS X 10.4 (ppc) - - - arm : - Android (Galaxy Note 3) - - Some older versions of p7zip were tested : - - x86 CPU : - DOS - (built with DJGPP, see http://blairdude.googlepages.com/p7zip ) - Linux - Redhat 9.0 Standart - Linux - Fedora 2 (Redhat) (gcc 3.3.3 and gcc-3.4.1 with - stack-smashing protector from www.trl.ibm.com/projects/security/ssp/) - Linux - Mandrake 10.0 Official - Linux - Ubuntu 8.04 - FreeBSD 5.2.1 (gcc 3.3.3) - MacOS 10.4.8 - NetBSD - CYGWIN_NT-5.1 1.5.9(0.112/4/2) 2004-03-18 23:05 i686 Cygwin - Solaris 9 (x86) with gcc 3.3.2 - Solaris 10 (x86) - - - alpha CPU : - Linux - Debian 3.0 (alpha) with gcc 2.95.4 - - - AMD64 CPU : - Linux - SuSE 8 ES (AMD64 Opteron) with gcc 3.2.2 - Linux - Fedora 4 (AMD64 Turion) with gcc 4.0.1 - Linux - Ubuntu 8.10 - - - Itanium CPU : - HP-UX B.11.31 U ia64 with aCC (HP C/aC++ B3910B A.06.14 [Feb 22 2007]) - - - s390x CPU : - Linux - SUSE Enterprise Linux 10 - with gcc 4.1.2 - ( only the 32bits built works, the 64bits built does not pass the tests ) - - - sparc CPU : - Solaris 9 (sparc) with gcc 3.3.2 - - - sparc CPU : - Solaris 8 (sparc) with gcc 2.95.2 - - - - powerpc CPU : - MacOS X 10.1/darwin 5.5 with gcc 932.1 (gcc 2.95.2) - MacOS X 10.3 with XCode 1.5 - - - openpower CPU : - Linux openpower-linux1 2.6.5-7.97-pseries64 (ppc64) with gcc 3.3.3 - - - IBM : - AIX 5.3 with gcc 4.1.0 - - - Tru64 : - OSF 5.1 with gcc 3.4.2 - - - PA-RISC : - HP-UX 11.11 with aCC (HP ANSI C++ B3910B A.03.73) - HP-UX 11.11 with gcc 3.4.2 (7za and 7zr : OK, 7z : failed because of a buggy gcc for HP-UX, - plugins don't work because C++ constructors are not called !) - - -BUILD with cmake ----------------- - You can only build 7za. - - cd CPP/7zip/CMAKE - - ./generate.sh (or ./generate_xcode.sh for MacOSX) - - In CPP/7zip, you now have directories like : - - P7ZIP.codeblocks/ - - P7ZIP.EclipseCDT4/ - - P7ZIP.Unix/ - (or P7ZIP.Xcode/ for MacOSX) - - - For the target "Unix Makefiles" : - - cd CPP/7zip/P7ZIP.Unix - - make - - Remark : these targets use only C/C++ code. To build targets with ASM code you must read the previous paragraph. - - For others target, use the IDE (CodeBlocks, KDevelop3, Eclipse CDT4) - -INSTALL : ---------- - - method 1 - -------- - - edit install.sh to change DEST_HOME - - ./install.sh : to install - Remark : you must be "root" to install 7za in the directory "/usr/local" - - method 2 - -------- - - 7za is a stand-alone program, you can put this program where you want. - example : cp bin/7za /usr/local/bin/7za - - - 7z needs its plugins. You must copy the file 7z, 7z.so - and the directory Codecs in the same destination directory. - - - if you want to be able to create SFX archive, copy bin/7zCon.sfx - to the directory where 7za or 7z can be found. - - -USAGE: ------- - Remark : you can replace 7za with 7z. - - 7za t archive.7z : tests files in the archive archive.7z - 7za l archive.7z : lists all files from archive archive.7z - 7za x archive.7z : extracts all files from archive archive.7z - to the current directory - - 7za a archive.7z file1 fileN : add files to the archive archive.7z - - 7za a archive.7z dir1 : add all files and subdirectories from directory "dir1" to archive archive.7z - - CAUTION : do not use the flag "-r" unless you know what you are doing ... - - 7za a -sfx archive.x dir1 : add all files from directory "dir1" to SFX archive archive.x - - You can also add or extract files to/from .zip or .tar archives. - You can also compress/uncompress .gz or .bz2 files. - - 7za a -tzip archive.zip file file2 file3 - 7za a -ttar archive.tar file - 7za a -tgzip file.gz file - 7za a -tbzip2 archive.bz2 file - - You can use password for archives: - 7za a -pmy_password archive.7z dir1 - - For .7z archive only, you can enable archive header encryption with "-mhe" - 7za a -mhe=on -pmy_password archive.7z dir1 - - For more, see the documentation of 7za.exe in DOC/MANUAL directory - 7za a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1 - adds all files from directory "dir1" to archive archive.7z - using "ultra settings". - -t7z : 7z archive - -m0=lzma : lzma method - -mx=9 : level of compression = 9 (Ultra) - -mfb=64 : number of fast bytes for LZMA = 64 - -md=32m : dictionary size = 32 megabytes - -ms=on : solid archive = on - - To use the new codec "lzma2" - 7za a -m0=lzma2 archive.7z directory - - -BENCHMARKS : ------------- - 7za b : bench LZMA codec - 7z b -mm=crc : make internal crc check. - 7za b "-mm=*" : test all methods - - - -hugetlbfs (large pages) : -------------------------- - - Using huges pages in Linux requires some preparations. - First, make sure your running kernel has support for hugetlbfs compiled in: - - ~$ grep hugetlbfs /proc/filesystems - nodev hugetlbfs - - You can view your current huge page configuration like this: - - ~$ grep Huge /proc/meminfo - HugePages_Total: 0 - HugePages_Free: 0 - HugePages_Rsvd: 0 - HugePages_Surp: 0 - Hugepagesize: 2048 kB - - In this case the size of a huge page is 2 MiB. - So, if you have 2 GiB of RAM and want to reserve 512 MiB for huge pages, - you would need 256 pages. - - Do the following as root: - - ~# echo 296 >/proc/sys/vm/nr_hugepages - ~# grep Huge /proc/meminfo - HugePages_Total: 296 - HugePages_Free: 296 - HugePages_Rsvd: 0 - HugePages_Surp: 0 - Hugepagesize: 2048 kB - - Finally, make access from user space possible: - - ~# mkdir /hugepages - ~# mount -t hugetlbfs -o rw,nosuid,nodev,noexec,noatime none /hugepages - ~# chmod 1777 /hugepages - - Option 1 : Now huge pages are configured. - In your shell, set the environment variable HUGETLB_PATH to the mount point: - ~$ export HUGETLB_PATH=/hugepages - or - - Option 2 : Let p7zip find out the first directory with the type "hugetlbfs" - - - To enable huge page use in p7zip, pass the '-slp' switch to it. - Ex: 7za -slp a t.7z dir - - - - If you want this to be a permanent setup : - - mkdir /hugepages - - - add an entry to your /etc/fstab so that when you reboot your computer, - your hugetlbfs will mount automatically : - hugetlbfs /hugepages hugetlbfs rw,nosuid,nodev,noexec,noatime 0 0 - - - add this in your /etc/rc.local : - chmod 1777 /hugepages - echo 296 > /proc/sys/vm/nr_hugepages - - optional : export HUGETLB_PATH=/hugepages - - To enable huge page use in p7zip, pass the '-slp' switch to it : 7za -slp b - - - Remark : with current CPU : "7za -slp b" is not faster than "7za b". - If you want to see some speedup, compress at least 300MB - Ex : 7za -slp -mx=9 -a big_file.tar.7z big_file.tar - - -LICENSE : ---------- - please read DOC/License.txt. - -LIMITATIONS from 7-zip : ------------------------- - - - does not support uid/gid for the .tar format (so, use tar on Unix) - -LIMITATIONS for Unix version only : ------------------------------------ - - - can handle properly UNICODE filenames only if the environment is UTF-8. - Example : export LANG=en_US.UTF-8 ; unset LC_CTYPE - Remark : see the possible values for LANG in the directory - - /usr/lib/locale : Fedora 2 / Solaris 8 - - /usr/share/locale : OpenBSD / Debian / FreeBSD / MacOS X / Mandrake 10.1 / NetBSD - - On Linux, to display the available locales : locale -a - - p7zip relies on LC_CTYPE and then on LANG to convert name to/from UNICODE. - the command "locale" should display these environment variables. - you can also do "echo $LC_CTYPE" and "echo $LANG". - - If you do not plan to export your archive, you can use the flag "-no-utf16". - Usage : - 7za a -no-utf16 archive.7z dirOrFile1 ... dirOrFileN - 7za t -no-utf16 archive.7z - 7za l -no-utf16 archive.7z - 7za x -no-utf16 archive.7z - - - ignores Windows file access permissions (files are created with default permissions) - - see also TODO file. - -DEVELOPPER CORNER: ------------------- - - - static analysis with cppcheck - make cppcheck - - - static analysis with clang - scan-build make all4 2>&1 | tee -i scan-build.out - - - dynamic analysis : valgrind - cp makefile.linux_valgrind makefile.machine - make test - - - dynamic analysis : gcc sanitize - cp makefile.linux_amd64_sanitizer makefile.machine - make test - - - WaitForMultipleObject has no equivalence on Unix. - - Events don't exist. - - sizeof(wchar_t) = 4 with GCC (2 with MS VC++) - - "FIXME" in source code indicates that you should add codes to better handle all cases. - - - "FIXED" in source code indicates that the original code has been changed to work in Unix environment. - - see also TODO file. diff -Nru p7zip-rar-16.02/TODO p7zip-rar-16.02+really25.00+ds/TODO --- p7zip-rar-16.02/TODO 2015-11-21 09:35:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ - -7za/7z -====== -- auto-generate config.h (use a configure script ...) - -- suppress all exit(EXIT_FAILURE), FIXME, ... - -- no chmod for TAR (should restore the rights set) - -- no chown(uid,gid) for TAR - -- Use a more portable "String.h" - -- UTF16 : try to test with Complex Unicode filenames - -- KNOWN BUGS - - - date (format arj/rar/chm) ? - -- zip format : better support of symbolic links - -7zG / 7zFM -========================== - -- better help displaying - -- better support for space in filenames - - -7zG : - - sfx: wants 7z.sfx instead of 7zCon.sfx ? - - the dialogs are not on top of other windows => not visible ... - - -7zFM : - - the path "/" does not work (on OSX ?) - - strange behaviour : selected/unselected items diff -Nru p7zip-rar-16.02/Utils/CPUTest/Benchmark.h p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/Benchmark.h --- p7zip-rar-16.02/Utils/CPUTest/Benchmark.h 2011-06-12 17:52:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/Benchmark.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -// Benchmark.h: Benchmark functions for CPU tests - -#ifndef __BENCHMARK_H -#define __BENCHMARK_H - -#if (defined _WIN32) || (defined _WIN32_WCE) -#define ITS_WINDOWS -#endif - -#ifdef ITS_WINDOWS -#include -#endif - -#include -#include -#include - -#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) -#define MY_CPU_AMD64 -#endif - -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 -#endif - -#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) -#define MY_CPU_X86_OR_AMD64 -#endif - -#if defined(__sparc_v9__) || (defined(__sparc__) && defined(__arch64__)) -#define MY_CPU_SPARCV9 -#endif - -typedef unsigned UInt32; -#ifdef __GNUC__ -typedef long long int Int64; -typedef unsigned long long int UInt64; -#else -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#endif - -UInt64 GetTimeCount2() -{ - #ifdef ITS_WINDOWS - LARGE_INTEGER value; if (::QueryPerformanceCounter(&value)) return value.QuadPart; - return GetTickCount(); - #else - return clock(); - #endif -} - -UInt64 GetFreq2() -{ - #ifdef ITS_WINDOWS - LARGE_INTEGER value; if (::QueryPerformanceFrequency(&value)) return value.QuadPart; - return 1000; - #else - return CLOCKS_PER_SEC; - #endif -} - -#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_SPARCV9) -#define CYCLES_MODE -#define TIMER_IS_FAST -#endif - -inline UInt64 GetTimeCount() -{ - #if defined(_WIN32) && defined(MY_CPU_X86_OR_AMD64) - #ifdef _WIN64 - return __rdtsc(); - #else - UInt32 valueLow, valueHigh; - __asm RDTSC; - __asm mov valueLow, EAX; - __asm mov valueHigh, EDX; - return ((UInt64)(valueHigh) << 32) | valueLow; - #endif - #elif defined(__GNUC__) && defined (MY_CPU_X86_OR_AMD64) - UInt64 value; - __asm__ __volatile__("rdtsc" : "=A" (value)); - return value; - #elif defined(__GNUC__) && defined (_ARCH_PPC) - UInt32 valueLow, valueHigh, valueHigh2; - do - { - __asm__ __volatile__("mftbu %0" : "=r" (valueHigh)); - __asm__ __volatile__("mftb %0" : "=r" (valueLow)); - __asm__ __volatile__("mftbu %0" : "=r" (valueHigh2)); - } - while (valueHigh2 != valueHigh) - return ((UInt64)(valueHigh) << 32) | valueLow; - #elif defined(__GNUC__) && defined(MY_CPU_SPARCV9) - UInt64 value; - #ifdef __arch64__ - __asm__ __volatile__("rd %%tick,%0" : "=r" (value)); - #else - __asm__ __volatile__("rd %%tick,%%g1\n\t" - "stx %%g1,%0" - : "=m" (value) :: "g1"); - #endif - #else - return GetTimeCount2(); - #endif -} - -#if defined(ITS_WINDOWS) && !defined(UNDER_CE) -#define MY_SET_AFFINITY_NUMBER(n) SetThreadAffinityMask(GetCurrentThread(), 1 << (n)) -#else -#define MY_SET_AFFINITY_NUMBER(n) -#endif - -#define MY_SET_AFFINITY MY_SET_AFFINITY_NUMBER(0) - -class CRandomGenerator -{ - UInt32 A1; - UInt32 A2; -public: - CRandomGenerator() { Init(); } - void Init() { A1 = 362436069; A2 = 521288629;} - UInt32 GetRnd() - { - return - ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) + - ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) ); - } - UInt64 GetRnd64() - { - UInt64 res = ((UInt64)GetRnd()) << 32; - return res | GetRnd(); - } - UInt32 GetRnd32(UInt32 size) - { - return (UInt32)(GetRnd64() % size); - } -}; - -struct CPrinter -{ - char *buf; - size_t pos; - size_t size; - - CPrinter(int size) - { - buf = new char[size]; - this->size = size; - Init(); - } - void Init() - { - pos = 0; - *buf = 0; - } - void Print(const char *s); - void NewLine(); -}; - -void CPrinter::Print(const char *s) -{ - size_t len = strlen(s); - size_t rem = size - pos; - if (len >= rem) - len = rem - 1; - memcpy(buf + pos, s, len); - pos += len; - buf[pos] = 0; -} - -void CPrinter::NewLine() -{ - Print("\n"); -} - -#endif diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/MemLat.cpp p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/MemLat.cpp --- p7zip-rar-16.02/Utils/CPUTest/MemLat/MemLat.cpp 2011-06-12 18:15:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/MemLat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,953 +0,0 @@ -/* MemLat.cpp -- Memory Latency -2011-05-12 : Igor Pavlov : Public domain */ - -// #define _WIN32_WINNT 0x0500 - -#include - -#ifdef _MSC_VER -// "was declared deprecated" disabling -#pragma warning(disable : 4996 ) -// #define LARGE_PAGES -#endif - -#include "../Benchmark.h" -#include "../MyVersion.h" - -#include "Walk.h" - -#ifdef ITS_WINDOWS -#ifdef LARGE_PAGES -#include "..\..\..\Windows\Security.h" -#include "..\..\..\Windows\MemoryLock.h" -#endif -#endif - -// #define _TEST_64 - -#ifdef _TEST_64 -typedef UInt64 TestType; -const int kNumMoveBits = 3; -#else -typedef UInt32 TestType; -const int kNumMoveBits = 2; -#endif - -const int kNumTestsMax = 22; - -const int kBasePowerMax = 33; -const size_t kBufferSize3 = ((size_t)1 << (kBasePowerMax - kNumMoveBits)); - -#ifndef NUM_DIRECT_TESTS - #define NUM_DIRECT_TESTS 10 -#endif - -#ifndef NUM_PAR_TESTS - #define NUM_PAR_TESTS 12 -#endif - -static unsigned GetHex(const char *s) -{ - UInt32 value; - if (1 != sscanf(s, "%x", &value)) - throw "incorrect value"; - return value; -} - -#ifndef MY_CPU_AMD64 -#define SUPPORT_DIRECT -#endif - -#ifdef UNDER_CE -#define USE_GUI -#endif - -#ifdef USE_GUI -HWND g_Hwnd; -BOOL g_bAbort; - -#define MY_PROGRESS(id, nnn) \ - { MSG msg; wchar_t s2[64]; _itow(nnn, s2, 10); \ - SetWindowTextW(GetDlgItem(g_Hwnd, id), s2); \ - while (!g_bAbort && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) \ - if (!IsDialogMessage(g_Hwnd, &msg)) \ - { TranslateMessage(&msg); DispatchMessage(&msg); } \ - if (g_bAbort) return 1; } -#else -#define MY_PROGRESS(id, nnn) -#endif - -int main2(CPrinter &f, int numArgs, const char *args[]) -{ - f.Print("MemLat " MY_VERSION_COPYRIGHT_DATE "\n"); - if (numArgs < 2 || numArgs > 100) - { - f.Print( - "use: MemLat.exe Size[K|M] [n] [l] [b] [c] [p[N]]\n" - " Size[K|M] - upper memory limit\n" - " n - show results in ns\n" - " l - use large pages\n" - #ifdef SUPPORT_DIRECT - " a - unAligned read\n" - #endif - " b - check Bandwidth using sum operator\n" - " c - check Latency and Bandwidth using sequential Chain\n" - #ifdef SUPPORT_DIRECT - " d - Direct pointers\n" - #endif - " p - check different page sizes\n" - " p[N] - check page performance for pageSize = 2^N\n" - " r - check different page sizes with NOP-40 mode\n" - " x[N] - align test array on 2^N range\n" - " z[N] - the number of random interations = 2^N\n" - " w - write mode\n" - ); - return 1; - } - const char *arg = args[1]; - int len = (int)strlen(arg); - if (len < 1) - return 2; - size_t bufferSizeMax = atoi(arg); - if (arg[len-1] == 'K' || arg[len-1] == 'k') - bufferSizeMax <<= 10; - else - bufferSizeMax <<= 20; - bufferSizeMax >>= kNumMoveBits; - - #ifdef _WIN32 - #ifdef LARGE_PAGES - NWindows::NSecurity::AddLockMemoryPrivilege(); - NWindows::NSecurity::EnableLockMemoryPrivilege(); - #endif - #endif - - bool nsMode = false; - bool largePages = false; - bool noCache = false; - - bool bwMode = false; - bool seqMode = false; - #ifdef SUPPORT_DIRECT - bool alignMode = false; - bool directMode = false; - #endif - - bool writeMode = false; - bool pageMode = false; - int pageBits = 2; - - int zBits = - #ifdef UNDER_CE - 16; - #else - 21; - #endif - - int seqStep = 0; - - int xBits = - #ifdef ITS_WINDOWS - #ifdef UNDER_CE - 20; - #else - 24; - #endif - #else - 12; - #endif - - int affinity = 0; - - bool nopMode = false; - - for (int ii = 2; ii < numArgs; ii++) - { - const char *str = args[ii]; - switch(str[0]) - { - case 'p': - { - str++; - int len = (int)strlen(str); - if (len < 1) - pageMode = true; - else - { - pageBits = atoi(str); - if (pageBits > 30 || pageBits < 2) - return 1; - } - break; - } - case 'r': - { - pageMode = true; - nopMode = true; - break; - } - - case 'b': bwMode = true; break; - case 'c': - { - seqMode = true; - str++; - int len = (int)strlen(str); - if (len >= 1) - { - if (str[len - 1] == 'h') - seqStep = GetHex(str); - else - { - return 1; - // seqStep = atoi(str); - } - if (seqStep < 4 || seqStep > (1 << 30)) - return 1; - seqStep >>= kNumMoveBits; - } - break; - } - #ifdef SUPPORT_DIRECT - case 'a': alignMode = true; break; - case 'd': directMode = true; break; - #endif - - case 'n': nsMode = true; break; - case 'l': largePages = true; break; - case 'u': noCache = true; break; - case 'w': writeMode = true; break; - case 't': - { - str++; - int len = (int)strlen(str); - if (len < 1) - return 1; - else - { - affinity = atoi(str); - if (affinity > 31 || affinity < 0) - return 1; - } - break; - } - case 'x': - { - str++; - int len = (int)strlen(str); - if (len < 1) - return 1; - else - { - xBits = atoi(str); - if (xBits > 30 || xBits < 3) - return 1; - } - break; - } - case 'z': - { - str++; - int len = (int)strlen(str); - if (len < 1) - return 1; - else - { - zBits = atoi(str); - if (zBits > 30 || zBits < 3) - return 1; - } - break; - } - default: return 1; - } - } - MY_SET_AFFINITY_NUMBER(affinity); - - bool latMode = !(seqMode || bwMode); - - size_t kAlignSize = (size_t)1 << xBits; - size_t allocSize = ((size_t)bufferSizeMax * sizeof(TestType) + kAlignSize + kAlignSize - 1) & ~((size_t)kAlignSize - 1); - TestType *randAddressesBase = (TestType *) - #ifdef _WIN32 - ::VirtualAlloc(0, allocSize, - MEM_COMMIT - #ifndef UNDER_CE - | (largePages ? MEM_LARGE_PAGES : 0) - #endif - , PAGE_READWRITE | (noCache ? PAGE_NOCACHE : 0)); - #else - malloc(allocSize); - #endif - - if (randAddressesBase == 0) - { - f.Print( "Not enough memory\n"); - return 1; - } - - TestType *randAddresses = randAddressesBase; - - while((((size_t)randAddresses) & (kAlignSize - 1)) != 0) - randAddresses++; - - CRandomGenerator rg; - - const int kNumSubItemsBits = 2; - const int kNumSubItems = 1 << kNumSubItemsBits; - const int kNumMaxItems = (kBasePowerMax + 1) * kNumSubItems; - const unsigned kNumTestCycles = 4; - int kStartPower = 12; - - int numTests = kNumTestsMax; - - if (bwMode) - numTests = 9; - else if (seqMode) - numTests = (seqStep == 0) ? 13 : 1; - #ifdef SUPPORT_DIRECT - else if (alignMode) - numTests = 13; - #endif - else - { - if (pageMode) - numTests = 21; - else - { - if (writeMode) - { - numTests = 6; - #ifdef SUPPORT_DIRECT - numTests = directMode ? 3 : 2; - #endif - } - else - { - numTests = - #ifdef SUPPORT_DIRECT - directMode ? NUM_DIRECT_TESTS : - #endif - NUM_PAR_TESTS; - } - } - } - - if (numTests > kNumTestsMax) - numTests = kNumTestsMax; - - - unsigned sizes[kNumMaxItems]; - double ticksResults[kNumTestsMax][kNumMaxItems]; - TestType sum = 0; - - { - for (int k = 0; k < - #ifdef UNDER_CE - 20000000 - #else - 600000000 - #endif - ; k++) - sum += (k >> 3); - } - - UInt64 startCount = GetTimeCount(); - UInt64 startCount2 = GetTimeCount2(); - - { - for (int k = 0; k < - #ifdef UNDER_CE - 10000000 - #else - 100000000 - #endif - ; k++) - sum += (k >> 3); - } - - - - int sizeIndexMax = 0; - for (int testIndex = 0; testIndex < numTests; testIndex++) - { - MY_PROGRESS(102, testIndex); - - int numThreads = 1; - if (!seqMode && !bwMode - #ifdef SUPPORT_DIRECT - && !alignMode - #endif - ) - { - if (!pageMode) - numThreads = testIndex + 1; - } - int sizeIndex = 0; - // printf("\ntestIndex=%d\n", testIndex); - for (int k = kStartPower; k < 64; k++) - { - MY_PROGRESS(103, (1 << k) >> 10); - // printf("k=%d\n", k); - int t; - for (t = 0; t < kNumSubItems; t++, sizeIndex++) - { - unsigned a[kNumTestsMax]; - ticksResults[testIndex][sizeIndex] = 0; - // printf("t=%d\n", t); - unsigned bufferSize = ((unsigned)1 << (k - kNumMoveBits)) + - (t << (k - kNumMoveBits - kNumSubItemsBits)); - if (bufferSize > kBufferSize3 || bufferSize > bufferSizeMax) - break; - sizes[sizeIndex] = bufferSize; - - UInt32 numCycles; - - unsigned i; - const UInt32 kEmpty = 0xFFFFFFFF; - for (i = 0; i < bufferSize; i++) - randAddresses[i] = kEmpty; - - // printf("numCycles=%d\n", numCycles); - - #ifdef SUPPORT_DIRECT - if (alignMode) - { - UInt32 step = 1 << testIndex; - if (step > bufferSize) - continue; - numCycles = bufferSize / step; - UInt32 stepInBytes = step << kNumMoveBits; - char *pAlignStart = (char *)(randAddresses) + (stepInBytes - (1 << kNumMoveBits)) / 2; - a[0] = (UInt32)pAlignStart; - char *p = pAlignStart; - for (i = 0; i + step <= bufferSize; i += step, p += stepInBytes) - *(UInt32 *)p = (UInt32)(p + stepInBytes); - *(UInt32 *)(p - stepInBytes) = (UInt32)pAlignStart; - } - else - #endif - - if (bwMode || seqMode) - { - UInt32 step = (testIndex == 0) ? 1 : (1 << (testIndex - 1)); - if (seqStep != 0) - step = seqStep; - if (step > bufferSize) - continue; - numCycles = bufferSize / step; - if (bwMode) - { - if (numCycles < 4) - continue; - } - if (seqMode) - { - if (testIndex == 0 && seqStep == 0) - { - for (i = 0; i < bufferSize; i++) - randAddresses[i] = 1; - randAddresses[i - 1] = 0 - (i - 1); - } - else - { - for (i = 0; i < bufferSize; i += step) - randAddresses[i] = i + step; - randAddresses[i - step] = 0; - } - } - } - else - { - int curPageBits = pageBits; - if (pageMode) - curPageBits = pageBits + testIndex; - int kPageIntsBits = curPageBits - 2; - numCycles = bufferSize >> kPageIntsBits; - numCycles /= numThreads; - - // printf(" kNumCycles = %5d", numCycles); - if (numCycles > (1 << 10)) - { - const UInt32 kDiv = 8; - numCycles = numCycles / kDiv * (kDiv - 1); - const UInt32 kNumCyclesMax = (1 << zBits); - if (numCycles > kNumCyclesMax) - numCycles = kNumCyclesMax; - } - if (numCycles < 1) - continue; - - for (int s = 0; s < numThreads; s++) - { - UInt32 prev = 0xFFFFFFFF; - for (i = 0; i < numCycles; i++) - { - for (;;) - { - UInt32 pageIndex = rg.GetRnd32(bufferSize >> kPageIntsBits); - unsigned randValueBase = pageIndex << kPageIntsBits; - unsigned randValue = randValueBase + rg.GetRnd32(1 << kPageIntsBits); - - // unsigned randValue = (aaa + 1) % bufferSize; - // printf("randValue=%d\n", randValue); - - if (randAddresses[randValueBase] == kEmpty) - { - UInt32 val = randValue; - #ifdef SUPPORT_DIRECT - if (directMode) - val = (UInt32)(randAddresses + randValue); - #endif - - if (i == 0) - a[s] = val; - else - randAddresses[prev] = val; - randAddresses[randValueBase] = 0; - prev = randValue; - // printf(" i = %d r=%d\n", i, randValue); - break; - } - } - } - randAddresses[prev] = a[s]; - } - } - - double minValue = 1 << 30; - - UInt32 mult2 = (k <= 16) ? 2047000 : 127000; - mult2 = (UInt32)((UInt64)mult2 / GetFreq2()) + 1; - unsigned numSpecCycles = (unsigned)(((UInt64)1 << 12) * mult2 / numCycles) + 1; - - // printf("numSpecCycles = %5d\n", numSpecCycles); - for (i = 0; i < kNumTestCycles; i++) - { - UInt32 res = 0; - UInt64 startTime = GetTimeCount(); - if (latMode) - { - UInt32 numCycles2 = numCycles * numSpecCycles; - // printf(" numCycles2 = %5d \n", numCycles2); - - #ifdef SUPPORT_DIRECT - if (alignMode || - (pageMode || testIndex == 0) && directMode) - if (writeMode) - res = Walk1wd(numCycles2, (void **)a[0]); - else - res = Walk1d(numCycles2, (void **)a[0]); - else - #endif - if (pageMode || testIndex == 0) - if (nopMode) - res = Walk1Nop(randAddresses, numCycles2, a[0]); - else if (writeMode) - res = Walk1w(randAddresses, numCycles2, a[0]); - else - res = Walk1(randAddresses, numCycles2, a[0]); - else - #ifdef SUPPORT_DIRECT - if (directMode) - if (writeMode) - switch (testIndex) - { - case 1: res = Walk2wd(numCycles2, (void **)a[0], (void **)a[1]); break; - case 2: res = Walk3wd(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2]); break; - default: f.Print( "\nInternal error\n"); return 1; - } - else - switch (testIndex) - { - case 1: res = Walk2d(numCycles2, (void **)a[0], (void **)a[1]); break; - case 2: res = Walk3d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2]); break; - case 3: res = Walk4d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3]); break; - case 4: res = Walk5d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4]); break; - case 5: res = Walk6d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4], (void **)a[5]); break; - #if NUM_DIRECT_TESTS > 6 - case 6: res = Walk7d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4], (void **)a[5], (void **)a[6]); break; - #if NUM_DIRECT_TESTS > 7 - case 7: res = Walk8d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4], (void **)a[5], (void **)a[6], (void **)a[7]); break; - #if NUM_DIRECT_TESTS > 8 - case 8: res = Walk9d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4], (void **)a[5], (void **)a[6], (void **)a[7], (void **)a[8]); break; - #if NUM_DIRECT_TESTS > 9 - case 9: res = Walk10d(numCycles2, (void **)a[0], (void **)a[1], (void **)a[2], (void **)a[3], (void **)a[4], (void **)a[5], (void **)a[6], (void **)a[7], (void **)a[8], (void **)a[9]); break; - #endif - #endif - #endif - #endif - default: f.Print("\nInternal error\n"); return 1; - } - else - #endif - - if (writeMode) - { - switch (testIndex) - { - case 1: res = Walk2w(randAddresses, numCycles2, a[0], a[1]); break; - #ifdef _WIN64 - case 2: res = Walk3w(randAddresses, numCycles2, a[0], a[1], a[2]); break; - case 3: res = Walk4w(randAddresses, numCycles2, a[0], a[1], a[2], a[3]); break; - case 4: res = Walk5w(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4]); break; - case 5: res = Walk6w(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5]); break; - #endif - default: f.Print("\nInternal error\n"); return 1; - } - } - else - switch (testIndex) - { - case 1: res = Walk2(randAddresses, numCycles2, a[0], a[1]); break; - case 2: res = Walk3(randAddresses, numCycles2, a[0], a[1], a[2]); break; - case 3: res = Walk4(randAddresses, numCycles2, a[0], a[1], a[2], a[3]); break; - case 4: res = Walk5(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4]); break; - #if NUM_PAR_TESTS > 5 - case 5: res = Walk6(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5]); break; - #if NUM_PAR_TESTS > 6 - case 6: res = Walk7(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6]); break; - #if NUM_PAR_TESTS > 7 - case 7: res = Walk8(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break; - #if NUM_PAR_TESTS > 8 - case 8: res = Walk9(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); break; - #if NUM_PAR_TESTS > 9 - case 9: res = Walk10(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); break; - #if NUM_PAR_TESTS > 10 - case 10: res = Walk11(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]); break; - #if NUM_PAR_TESTS > 11 - case 11: res = Walk12(randAddresses, numCycles2, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]); break; - #endif - #endif - #endif - #endif - #endif - #endif - #endif - default: f.Print("\nInternal error\n"); return 1; - } - } - else - { - if (seqMode) - { - if (testIndex == 0 && seqStep == 0) - res = Walk1Add(randAddresses, numCycles * numSpecCycles, 0); - else - res = Walk1(randAddresses, numCycles * numSpecCycles, 0); - } - else - for (unsigned spec = 0; spec < numSpecCycles; spec++) - if (testIndex == 0) - if (writeMode) - WalkWrite(randAddresses, numCycles); - else - res += WalkSum(randAddresses, numCycles); - else - if (writeMode) - WalkWrite2(randAddresses, numCycles << (testIndex - 1), 1 << (testIndex - 1)); - else - res += WalkSum2(randAddresses, numCycles << (testIndex - 1), 1 << (testIndex - 1)); - } - double ticks = double(Int64(GetTimeCount() - startTime)) / numCycles / numSpecCycles / numThreads; - // printf("\nTimer=%d\n", GetTimeCount() - startTime); - sum += res; - if (ticks < minValue) - minValue = ticks; - if (minValue == 0) - minValue = 0.000000000000000001; - } - ticksResults[testIndex][sizeIndex] = minValue; - } - if (t != kNumSubItems) - break; - } - sizeIndexMax = sizeIndex; - } - UInt64 countTotal = GetTimeCount() - startCount; - UInt64 countTotal2 = GetTimeCount2() - startCount2; - - if (countTotal2 == 0) - countTotal2 = 1; - double freq = double((Int64)countTotal) * (Int64)GetFreq2() / (Int64)countTotal2; - if (freq == 0) - freq = 1; - - char temp[128]; - { - f.Print(" Size"); - #ifdef SUPPORT_DIRECT - if (alignMode) - { - for (int testIndex = 0; testIndex < numTests; testIndex++) - { - sprintf(temp, " %6d", testIndex == 0 ? 0 : (2 << testIndex)); - f.Print(temp); - } - } - else - #endif - if (seqMode || bwMode) - { - f.Print((seqMode && seqStep == 0) ? " Add" : " Linear"); - for (int testIndex = 1; testIndex < numTests; testIndex++) - { - sprintf(temp, " %6d", (2 << testIndex)); - f.Print(temp); - } - } - else - for (int testIndex = 0; testIndex < numTests; testIndex++) - { - sprintf(temp, " %6d", pageMode ? (pageBits + testIndex) : (testIndex + 1)); - f.Print(temp); - } - f.Print("\n\n"); - } - - for (int i = 0; i < sizeIndexMax; i++) - { - int size = (sizes[i] >> (10 - kNumMoveBits)); - if (size < (4 << 10)) - sprintf(temp, "%6d-K", size); - else - sprintf(temp, "%6d-M", size >> 10); - f.Print(temp); - - for (int testIndex = 0; testIndex < numTests; testIndex++) - { - double value = ticksResults[testIndex][i]; - if (nsMode) - value = double(value) * 1000000000 / freq; - sprintf(temp, " %6.2f", value); - f.Print(temp); - } - f.NewLine(); - } - - f.NewLine(); - if (sizeIndexMax > 0) - { - for (int iii = 0; iii < 3; iii++) - { - const int kMovs = 5 + iii; - f.Print("BW-"); - if (latMode) - { - sprintf(temp, "%3d B", 1 << kMovs); - f.Print(temp); - } - else - f.Print(" "); - - - for (int testIndex = 0; testIndex < numTests; testIndex++) - { - double memoryBandwidth = (freq / ticksResults[testIndex][sizeIndexMax - 1]) * (1 << kNumMoveBits); - if (latMode) - memoryBandwidth *= (1 << (kMovs - 2)); - else if (testIndex > 0) - memoryBandwidth *= (1 << (testIndex - 1)); - sprintf(temp, " %6d", (UInt32)(memoryBandwidth / 1000000)); - f.Print(temp); - } - f.NewLine(); - if (!latMode) - break; - } - f.NewLine(); - } - - if (sizeIndexMax > 0) - { - if (latMode) - { - int latencyIndex = 0; - double cacheLatency = ticksResults[latencyIndex][0] / freq; - sprintf(temp, "Cache latency = %10.2f ns = %10.2f cycles\n", - cacheLatency * (1e9), ticksResults[latencyIndex][0]); - f.Print(temp); - double memoryLatency = ticksResults[latencyIndex][sizeIndexMax - 1] / freq; - sprintf(temp, "Memory latency = %10.2f ns = %10.2f cycles\n", - memoryLatency * (1e9), ticksResults[latencyIndex][sizeIndexMax - 1]); - f.Print(temp); - } - { - if (nsMode) - f.Print("ns "); - if (largePages) - f.Print("LargePages "); - - if (bwMode) - f.Print("BW-Sum"); - else if (seqMode) - f.Print("Seq Step"); - else if (pageMode) - f.Print("PageMode"); - else - { - sprintf(temp, "PageSize=%d \n", 1 << pageBits); - f.Print(temp); - } - f.NewLine(); - } - } - - f.NewLine(); - sprintf(temp, "Timer frequency = %10.0f Hz\n", (double)(Int64)GetFreq2()); - f.Print(temp); - sprintf(temp, "CPU frequency = %10.2f MHz\n", freq / 1000000); - f.Print(temp); - - #ifdef _WIN32 - VirtualFree(randAddressesBase, 0, MEM_RELEASE); - #else - free(randAddressesBase); - #endif - return (int)(sum >> 3); -} - -static const size_t kTempSize = 20000; - -#ifdef USE_GUI - -static int g_TestNumber = 0; - -static int OneTest(CPrinter &f, const char *s, const wchar_t *fileName2) -{ - f.Init(); - - { - wchar_t s2[64]; - for (int t = 0; t < 100; t++) - { - s2[t] = s[t]; - if (s[t] == 0) - break; - } - SetWindowTextW(GetDlgItem(g_Hwnd, 110), s2); - MY_PROGRESS(101, g_TestNumber++); - } - - char args[10][32]; - int param = 1; - int pos = 0; - for (;;) - { - char c = *s++; - if (pos >= 32 || param >= 10) - return 1; - if (c == ' ') - { - args[param][pos++] = 0; - pos = 0; - param++; - } - else - { - args[param][pos++] = c; - if (c == 0) - break; - } - } - - const char *argsPtr[10]; - param++; - argsPtr[0] = "memLat.exe"; - for (int i = 1; i < param; i++) - argsPtr[i] = args[i]; - main2(f, param, argsPtr); - - wchar_t fileName[300]; - GetModuleFileNameW(0, fileName, 300); - wchar_t *p = wcsrchr(fileName, L'\\'); - if (p == 0) - return 0; - p++; - wcscpy(p, fileName2); - FILE *inputHandle = _wfopen(fileName, L"w+"); - if (inputHandle == 0) - { - MessageBoxW(0, L"Can't open text file", L"Error", 0); - return 1; - } - fprintf(inputHandle, "%s", f.buf); - fclose(inputHandle); - - return 0; -} - -static INT_PTR CALLBACK MyDlgProc(HWND /* hwnd */, UINT message, WPARAM wParam, LPARAM /* lParam */) -{ - switch(message) - { - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDCANCEL: - SetWindowTextW(GetDlgItem(g_Hwnd, 101), L"Stopping..."); - g_bAbort = TRUE; - break; - } - break; - default: - return FALSE; - } - return TRUE; -} - -int WINAPI WinMain(HINSTANCE, - HINSTANCE, - #ifdef UNDER_CE - LPWSTR - #else - LPSTR - #endif - , - int) -{ - g_bAbort = FALSE; - g_Hwnd = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(100), NULL, MyDlgProc); - if (g_Hwnd == 0) - { - MessageBoxW(0, L"Error", L"Error", 0); - return 1; - } - - CPrinter f(kTempSize); - - OneTest(f, "2m n c", L"c.txt"); - OneTest(f, "2m n b", L"b.txt"); - OneTest(f, "2m n b w", L"bw.txt"); - - OneTest(f, "16m n p d", L"pd.txt"); - OneTest(f, "16m n p2 d", L"p2d.txt"); - OneTest(f, "16m n p5 d", L"p5d.txt"); - OneTest(f, "16m n p6 d", L"p6d.txt"); - OneTest(f, "16m n p7 d", L"p7d.txt"); - OneTest(f, "16m n p12 d", L"p12d.txt"); - OneTest(f, "16m n p2", L"p2.txt"); - - // OneTest("16m n p d u", L"pdu.txt"); - // OneTest("16m n p2 d u", L"p2du.txt"); - // OneTest("16m n p4 d u", L"p4du.txt"); - // OneTest("16m n p5 d u", L"p5du.txt"); - // OneTest("1m n c u", L"cu.txt"); - // OneTest("1m n b u", L"bu.txt"); - // OneTest("1m n b w u", L"bwu.txt"); - - return 0; -} -#else -int -#ifdef _MSC_VER -_cdecl -#endif -main(int numargs, const char *args[]) -{ - CPrinter f(kTempSize); - int code = main2(f, numargs, args); - fputs(f.buf, stdout); - return code; -} -#endif diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk.c p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.c --- p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk.c 2011-06-12 17:54:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,267 +0,0 @@ -/* Walk.c -- memory walks -2010-10-14 : Igor Pavlov : Public domain */ - -#include "Walk.h" - -unsigned MY_FAST_CALL WalkSum(const unsigned *p, unsigned num) -{ - unsigned b = 0; - unsigned i; - for (i = 0; i < num; i += 16) - { - b = b + p[i] + - p[i + 1] + - p[i + 2] + - p[i + 3] + - p[i + 4] + - p[i + 5] + - p[i + 6] + - p[i + 7] + - p[i + 8] + - p[i + 9] + - p[i + 10] + - p[i + 11] + - p[i + 12] + - p[i + 13] + - p[i + 14] + - p[i + 15]; - } - return b; -} - -unsigned MY_FAST_CALL WalkSum2(const unsigned *p, unsigned num, unsigned step) -{ - unsigned b = 0; - unsigned i; - for (i = 0; i < num;) - { - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - b += p[i]; i += step; - } - return b; -} - -void MY_FAST_CALL WalkWrite(unsigned *p, unsigned num) -{ - unsigned i; - for (i = 0; i < num; i += 8) - { - p[i] = 0; - p[i + 1] = 0; - p[i + 2] = 0; - p[i + 3] = 0; - p[i + 4] = 0; - p[i + 5] = 0; - p[i + 6] = 0; - p[i + 7] = 0; - } -} - -void MY_FAST_CALL WalkWrite2(unsigned *p, unsigned num, unsigned step) -{ - unsigned i; - for (i = 0; i < num;) - { - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - p[i] = 0; i += step; - } -} - -unsigned MY_FAST_CALL Walk1Add(const unsigned *p, unsigned num, unsigned a0) -{ - unsigned i; - num >>= 4; - for (i = 0; i < num; i++) - { - a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; - a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; - a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; - a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; a0 += p[a0]; - } - return a0; -} - -unsigned MY_FAST_CALL Walk1Nop(const unsigned *p, unsigned num, unsigned a0) -{ - unsigned k = (a0 < 0xFFFFFFFF) ? 0 : 1; - unsigned i; - for (i = 0; i < num; i++) - { - a0 += k; - a0 = p[a0]; - } - return a0; -} - -#define R1 (unsigned)(size_t)a0 -#define R2 R1 + (unsigned)(size_t)a1 -#define R3 R2 + (unsigned)(size_t)a2 -#define R4 R3 + (unsigned)(size_t)a3 -#define R5 R4 + (unsigned)(size_t)a4 -#define R6 R5 + (unsigned)(size_t)a5 -#define R7 R6 + (unsigned)(size_t)a6 -#define R8 R7 + (unsigned)(size_t)a7 -#define R9 R8 + (unsigned)(size_t)a8 -#define R10 R9 + (unsigned)(size_t)a9 -#define R11 R10 + (unsigned)(size_t)a10 -#define R12 R11 + (unsigned)(size_t)a11 - -#define A1 a0 = p[a0]; -#define A2 A1 a1 = p[a1]; -#define A3 A2 a2 = p[a2]; -#define A4 A3 a3 = p[a3]; -#define A5 A4 a4 = p[a4]; -#define A6 A5 a5 = p[a5]; -#define A7 A6 a6 = p[a6]; -#define A8 A7 a7 = p[a7]; -#define A9 A8 a8 = p[a8]; -#define A10 A9 a9 = p[a9]; -#define A11 A10 a10 = p[a10]; -#define A12 A11 a11 = p[a11]; - -WWW_DECL(1) -{ - unsigned i; - num >>= 4; - for (i = 0; i < num; i++) - a0 = p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[a0]]]]]]]]]]]]]]]]; - return a0; -} - -#define WWW(n) WWW_DECL(n) \ -{ unsigned i; num >>= 2; \ - for (i = 0; i < num; i++) { \ - A ## n; A ## n; A ## n; A ## n; \ - } return R ## n ; } - -WWW(2) -WWW(3) -WWW(4) -WWW(5) -WWW(6) -WWW(7) -WWW(8) -WWW(9) -WWW(10) -WWW(11) -WWW(12) - -#define D1 a0 = *a0; -#define D2 D1 a1 = *a1; -#define D3 D2 a2 = *a2; -#define D4 D3 a3 = *a3; -#define D5 D4 a4 = *a4; -#define D6 D5 a5 = *a5; -#define D7 D6 a6 = *a6; -#define D8 D7 a7 = *a7; -#define D9 D8 a8 = *a8; -#define D10 D9 a9 = *a9; - -unsigned MY_FAST_CALL Walk1d(unsigned num, P1) -{ - unsigned i; - num >>= 4; - for (i = 0; i < num; i++) - a0 = *(void **)*(void **)*(void **)*(void **) - *(void **)*(void **)*(void **)*(void **) - *(void **)*(void **)*(void **)*(void **) - *(void **)*(void **)*(void **)*a0; - return R1; -} - -#define DDD(n) DDD_DECL(n) \ -{ unsigned i; num >>= 3; \ - for (i = 0; i < num; i++) { \ - D ## n; D ## n; D ## n; D ## n; \ - D ## n; D ## n; D ## n; D ## n; \ - } return R ## n ; } - -DDD(2) -DDD(3) -DDD(4) -DDD(5) -DDD(6) -DDD(7) -DDD(8) -DDD(9) -DDD(10) - -#define PPP(x, y) y = p[x]; p[x] = y; - -#define B1 PPP(a0, z0) -#define B2 B1 PPP(a1, z1) -#define B3 B2 PPP(a2, z2) -#define B4 B3 PPP(a3, z3) -#define B5 B4 PPP(a4, z4) -#define B6 B5 PPP(a5, z5) - -#define C1 PPP(z0, a0) -#define C2 C1 PPP(z1, a1) -#define C3 C2 PPP(z2, a2) -#define C4 C3 PPP(z3, a3) -#define C5 C4 PPP(z4, a4) -#define C6 C5 PPP(z5, a5) - -#define Z1 z0 -#define Z2 Z1, z1 -#define Z3 Z2, z2 -#define Z4 Z3, z3 -#define Z5 Z4, z4 -#define Z6 Z5, z5 - -#define RW(n) RW_DECL(n) \ -{ unsigned i; num >>= 3; for (i = 0; i < num; i++) { \ - unsigned Z ## n; \ - B ## n; C ## n; \ - B ## n; C ## n; \ - B ## n; C ## n; \ - B ## n; C ## n; \ - } return R ## n ; } - -RW(1) -RW(2) -RW(3) -RW(4) -RW(5) -RW(6) - - -#define MMM(x, y) y = *x; *x = y; - -#define E1 MMM(a0, z0) -#define E2 E1 MMM(a1, z1) -#define E3 E2 MMM(a2, z2) - -#define F1 MMM(z0, a0) -#define F2 F1 MMM(z1, a1) -#define F3 F2 MMM(z2, a2) - -#define Y1 **z0 -#define Y2 Y1, **z1 -#define Y3 Y2, **z2 - -#define WD(n) WD_DECL(n) \ -{ unsigned i; num >>= 3; \ - for (i = 0; i < num; i++) { \ - void Y ## n; \ - E ## n; F ## n; \ - E ## n; F ## n; \ - E ## n; F ## n; \ - E ## n; F ## n; \ - } return R ## n ; } - -WD(1) -WD(2) -WD(3) diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk.h p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.h --- p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk.h 2011-06-12 17:54:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -/* Walk.h -- memory walks -2010-12-17 : Igor Pavlov : Public domain */ - -#ifndef __WALK_H -#define __WALK_H - -#include - -#ifdef _MSC_VER -#if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) -#else -#define MY_NO_INLINE -#endif -#define MY_FAST_CALL MY_NO_INLINE __fastcall -#else -#define MY_FAST_CALL -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned MY_FAST_CALL WalkSum(const unsigned *p, unsigned num); -unsigned MY_FAST_CALL WalkSum2(const unsigned *p, unsigned num, unsigned step); -void MY_FAST_CALL WalkWrite(unsigned *p, unsigned num); -void MY_FAST_CALL WalkWrite2(unsigned *p, unsigned num, unsigned step); -unsigned MY_FAST_CALL Walk1Add(const unsigned *p, unsigned num, unsigned a0); -unsigned MY_FAST_CALL Walk1Nop(const unsigned *p, unsigned num, unsigned a0); - -#define U1 unsigned a0 -#define U2 U1, unsigned a1 -#define U3 U2, unsigned a2 -#define U4 U3, unsigned a3 -#define U5 U4, unsigned a4 -#define U6 U5, unsigned a5 -#define U7 U6, unsigned a6 -#define U8 U7, unsigned a7 -#define U9 U8, unsigned a8 -#define U10 U9, unsigned a9 -#define U11 U10, unsigned a10 -#define U12 U11, unsigned a11 - -#define WWW_DECL(n) \ - unsigned MY_FAST_CALL Walk ## n(const unsigned *p, unsigned num, U ## n) - -WWW_DECL(1); -WWW_DECL(2); -WWW_DECL(3); -WWW_DECL(4); -WWW_DECL(5); -WWW_DECL(6); -WWW_DECL(7); -WWW_DECL(8); -WWW_DECL(9); -WWW_DECL(10); -WWW_DECL(11); -WWW_DECL(12); - -#define RW_DECL(n) \ - unsigned MY_FAST_CALL Walk ## n ## w(unsigned *p, unsigned num, U ## n) - -RW_DECL(1); -RW_DECL(2); -RW_DECL(3); -RW_DECL(4); -RW_DECL(5); -RW_DECL(6); - -#define P1 void **a0 -#define P2 P1, void **a1 -#define P3 P2, void **a2 -#define P4 P3, void **a3 -#define P5 P4, void **a4 -#define P6 P5, void **a5 -#define P7 P6, void **a6 -#define P8 P7, void **a7 -#define P9 P8, void **a8 -#define P10 P9, void **a9 - -#define DDD_DECL(n) \ - unsigned MY_FAST_CALL Walk ## n ## d(unsigned num, P ## n) - -DDD_DECL(1); -DDD_DECL(2); -DDD_DECL(3); -DDD_DECL(4); -DDD_DECL(5); -DDD_DECL(6); -DDD_DECL(7); -DDD_DECL(8); -DDD_DECL(9); -DDD_DECL(10); - -#define WD_DECL(n) \ - unsigned MY_FAST_CALL Walk ## n ## wd(unsigned num, P ## n) - -WD_DECL(1); -WD_DECL(2); -WD_DECL(3); - -#ifdef __cplusplus -} -#endif - - -#endif diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk32.asm p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk32.asm --- p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk32.asm 2011-06-12 17:54:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk32.asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,662 +0,0 @@ -.386 -.model flat - -OPTION PROLOGUE:NONE -OPTION EPILOGUE:NONE - -.data -_TEXT$00 SEGMENT PARA PUBLIC 'CODE' - - -PUSHREG macro - push EBP - push EBX - push ESI - push EDI -endm - -POPREG macro - pop EDI - pop ESI - pop EBX - pop EBP -endm - -offs equ 4 * 4 -a0$ = (offs + 4) -a1$ = (a0$ + 4) -a2$ = (a1$ + 4) -a3$ = (a2$ + 4) -a4$ = (a3$ + 4) -a5$ = (a4$ + 4) - -align 16 -@WalkSum@8 PROC - - PUSHREG - xor EAX, EAX - xor EBX, EBX - xor ESI, ESI - xor EDI, EDI - shr EDX, 4 - align 16 -@@: - ttt = 0 - rept 4 - add EAX, DWORD PTR [ECX + ttt + 0] - add EBX, DWORD PTR [ECX + ttt + 4] - add ESI, DWORD PTR [ECX + ttt + 8] - add EDI, DWORD PTR [ECX + ttt + 12] - ttt = ttt + 16 - endm - - add ECX, 64 - dec EDX - jne @B - - add EAX, EBX - add EAX, ESI - add EAX, EDI - POPREG - ret 0 -@WalkSum@8 ENDP - - -align 16 -@WalkWrite@8 PROC - - PUSHREG - xor EAX, EAX - shr EDX, 4 - align 16 -@@: - ttt = 0 - rept 16 - mov DWORD PTR [ECX + ttt], EAX - ttt = ttt + 4 - endm - - add ECX, 64 - dec EDX - jne @B - - POPREG - ret 0 -@WalkWrite@8 ENDP - -align 16 -@WalkSum2@12 PROC - - PUSHREG - mov ESI, DWORD PTR a0$[ESP] - shl ESI, 2 - mov EDI, ESI - shl EDI, 1 - xor EAX, EAX - xor EBX, EBX - shl EDX, 2 - add EDX, ECX - align 16 -@@: - add EAX, DWORD PTR [ECX] - add EBX, DWORD PTR [ECX + ESI] - add ECX, EDI - - cmp ECX, EDX - jb @B - - add EAX, EBX - POPREG - ret 4 -@WalkSum2@12 ENDP - -align 16 -@WalkWrite2@12 PROC - - PUSHREG - mov ESI, DWORD PTR a0$[ESP] - shl ESI, 2 - mov EDI, ESI - mov EBX, ESI - add EBX, ESI - add EBX, ESI - shl EDI, 2 - xor EAX, EAX - shl EDX, 2 - add EDX, ECX - align 16 -@@: - rept 2 - mov DWORD PTR [ECX], EAX - mov DWORD PTR [ECX + ESI], EAX - mov DWORD PTR [ECX + ESI * 2], EAX - mov DWORD PTR [ECX + EBX], EAX - add ECX, EDI - endm - - cmp ECX, EDX - jb @B - - POPREG - ret 4 -@WalkWrite2@12 ENDP - -align 16 -@Walk1Add@12 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - shr EDX, 3 - align 16 -@@: - rept 8 - add EAX, DWORD PTR [ECX + EAX*4] - endm - - dec EDX - jne @B - - POPREG - ret 4 -@Walk1Add@12 ENDP - - - -align 16 -@Walk1Nop@12 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - xor EBX, EBX - align 16 -@@: - rept 40 - add EAX, EBX - endm - - mov EAX, DWORD PTR [ECX + EAX*4] - - dec EDX - jne @B - - POPREG - ret 4 -@Walk1Nop@12 ENDP - - -align 16 -@Walk1@12 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - shr EDX, 3 - align 16 -@@: - rept 8 - mov EAX, DWORD PTR [ECX + EAX*4] - endm - - dec EDX - jne @B - - POPREG - ret 4 -@Walk1@12 ENDP - -PPP macro x, y - mov x, DWORD PTR [ECX + y * 4] -endm - -QQQ macro x, y - mov DWORD PTR [ECX + y * 4], x -endm - -align 16 -@Walk1w@12 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - shr EDX, 3 - align 16 -@@: - rept 4 - PPP ESI, EAX - QQQ ESI, EAX - PPP EAX, ESI - QQQ EAX, ESI - endm - - dec EDX - jne @B - - POPREG - ret 4 -@Walk1w@12 ENDP - -align 16 -@Walk2@16 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - mov EBX, DWORD PTR a1$[ESP] - shr EDX, 2 - align 16 -@@: - rept 4 - mov EAX, DWORD PTR [ECX + EAX*4] - mov EBX, DWORD PTR [ECX + EBX*4] - endm - - dec EDX - jne @B - - add EAX, EBX - - POPREG - ret 8 -@Walk2@16 ENDP - - -align 16 -@Walk2w@16 PROC - - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - mov EBX, DWORD PTR a1$[ESP] - shr EDX, 2 - align 16 -@@: - rept 2 - - PPP ESI, EAX - PPP EDI, EBX - - QQQ ESI, EAX - QQQ EDI, EBX - - PPP EAX, ESI - PPP EBX, EDI - - QQQ EAX, ESI - QQQ EBX, EDI - endm - - dec EDX - jne @B - - add EAX, EBX - - POPREG - ret 8 -@Walk2w@16 ENDP - -align 16 -@Walk3@20 PROC - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - mov EBX, DWORD PTR a1$[ESP] - mov ESI, DWORD PTR a2$[ESP] - shr EDX, 1 - align 16 -@@: - rept 2 - mov EAX, DWORD PTR [ECX + EAX*4] - mov EBX, DWORD PTR [ECX + EBX*4] - mov ESI, DWORD PTR [ECX + ESI*4] - endm - - dec EDX - jne @B - - add EAX, EBX - add EAX, ESI - - POPREG - ret 12 -@Walk3@20 ENDP - - -align 16 -@Walk4@24 PROC - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - mov EBX, DWORD PTR a1$[ESP] - mov ESI, DWORD PTR a2$[ESP] - mov EDI, DWORD PTR a3$[ESP] - shr EDX, 1 - align 16 -@@: - rept 2 - mov EAX, DWORD PTR [ECX + EAX*4] - mov EBX, DWORD PTR [ECX + EBX*4] - mov ESI, DWORD PTR [ECX + ESI*4] - mov EDI, DWORD PTR [ECX + EDI*4] - endm - - dec EDX - jne @B - - add EAX, EBX - add EAX, ESI - add EAX, EDI - - POPREG - ret 16 -@Walk4@24 ENDP - - -align 16 -@Walk5@28 PROC - PUSHREG - mov EAX, DWORD PTR a0$[ESP] - mov EBX, DWORD PTR a1$[ESP] - mov ESI, DWORD PTR a2$[ESP] - mov EDI, DWORD PTR a3$[ESP] - mov EBP, DWORD PTR a4$[ESP] - shr EDX, 1 - align 16 -@@: - rept 2 - mov EAX, DWORD PTR [ECX + EAX*4] - mov EBX, DWORD PTR [ECX + EBX*4] - mov ESI, DWORD PTR [ECX + ESI*4] - mov EDI, DWORD PTR [ECX + EDI*4] - mov EBP, DWORD PTR [ECX + EBP*4] - endm - - dec EDX - jne @B - - add EAX, EBX - add EAX, ESI - add EAX, EDI - add EAX, EBP - - POPREG - ret 20 -@Walk5@28 ENDP - - -align 16 -@Walk1d@8 PROC - - PUSHREG - xor EAX, EAX - shr ECX, 3 - align 16 -@@: - rept 8 - mov EDX, DWORD PTR [EDX] - endm - - dec ECX - jne @B - - mov EAX, EDX - - POPREG - ret 0 -@Walk1d@8 ENDP - - -MMM macro x, y - mov x, DWORD PTR [y] -endm - -NNN macro x, y - mov DWORD PTR [y], x -endm - - -align 16 -@Walk1wd@8 PROC - - PUSHREG - xor EAX, EAX - shr ECX, 3 - align 16 -@@: - rept 4 - - MMM ESI, EDX - - NNN ESI, EDX - - MMM EDX, ESI - - NNN EDX, ESI - - endm - - dec ECX - jne @B - - mov EAX, EDX - - POPREG - ret 0 -@Walk1wd@8 ENDP - - -align 16 -@Walk2d@12 PROC - - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - shr ECX, 2 - align 16 -@@: - rept 4 - mov EDX, DWORD PTR [EDX] - mov EBX, DWORD PTR [EBX] - endm - - dec ECX - jne @B - - mov EAX, EDX - add EAX, EBX - - POPREG - ret 4 -@Walk2d@12 ENDP - - -align 16 -@Walk2wd@12 PROC - - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - shr ECX, 2 - align 16 -@@: - rept 2 - - MMM ESI, EDX - MMM EDI, EBX - - NNN ESI, EDX - NNN EDI, EBX - - MMM EDX, ESI - MMM EBX, EDI - - NNN EDX, ESI - NNN EBX, EDI - - endm - - dec ECX - jne @B - - mov EAX, EDX - add EAX, EBX - - POPREG - ret 4 -@Walk2wd@12 ENDP - -align 16 -@Walk3d@16 PROC - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - mov ESI, DWORD PTR a1$[ESP] - shr ECX, 1 - align 16 -@@: - rept 2 - mov EDX, DWORD PTR [EDX] - mov EBX, DWORD PTR [EBX] - mov ESI, DWORD PTR [ESI] - endm - - dec ECX - jne @B - - mov EAX, EDX - add EAX, EBX - add EAX, ESI - - POPREG - ret 8 -@Walk3d@16 ENDP - - -align 16 -@Walk3wd@16 PROC - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - mov EAX, DWORD PTR a1$[ESP] - shr ECX, 1 - align 16 -@@: - rept 1 - - MMM ESI, EDX - MMM EDI, EBX - MMM EBP, EAX - - NNN ESI, EDX - NNN EDI, EBX - NNN EBP, EAX - - MMM EDX, ESI - MMM EBX, EDI - MMM EAX, EBP - - NNN EDX, ESI - NNN EBX, EDI - NNN EAX, EBP - - endm - - dec ECX - jne @B - - add EAX, EDX - add EAX, EBX - - POPREG - ret 8 -@Walk3wd@16 ENDP - -align 16 -@Walk4d@20 PROC - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - mov ESI, DWORD PTR a1$[ESP] - mov EDI, DWORD PTR a2$[ESP] - shr ECX, 1 - align 16 -@@: - rept 2 - mov EDX, DWORD PTR [EDX] - mov EBX, DWORD PTR [EBX] - mov ESI, DWORD PTR [ESI] - mov EDI, DWORD PTR [EDI] - endm - - dec ECX - jne @B - - mov EAX, EDX - add EAX, EBX - add EAX, ESI - add EAX, EDI - - POPREG - ret 12 -@Walk4d@20 ENDP - - -align 16 -@Walk5d@24 PROC - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - mov ESI, DWORD PTR a1$[ESP] - mov EDI, DWORD PTR a2$[ESP] - mov EBP, DWORD PTR a3$[ESP] - shr ECX, 1 - align 16 -@@: - rept 2 - mov EDX, DWORD PTR [EDX] - mov EBX, DWORD PTR [EBX] - mov ESI, DWORD PTR [ESI] - mov EDI, DWORD PTR [EDI] - mov EBP, DWORD PTR [EBP] - endm - - dec ECX - jne @B - - mov EAX, EDX - add EAX, EBX - add EAX, ESI - add EAX, EDI - add EAX, EBP - - POPREG - ret 16 -@Walk5d@24 ENDP - - -align 16 -@Walk6d@28 PROC - PUSHREG - mov EBX, DWORD PTR a0$[ESP] - mov ESI, DWORD PTR a1$[ESP] - mov EDI, DWORD PTR a2$[ESP] - mov EBP, DWORD PTR a3$[ESP] - mov EAX, DWORD PTR a4$[ESP] - shr ECX, 1 - align 16 -@@: - rept 2 - mov EDX, DWORD PTR [EDX] - mov EBX, DWORD PTR [EBX] - mov ESI, DWORD PTR [ESI] - mov EDI, DWORD PTR [EDI] - mov EBP, DWORD PTR [EBP] - mov EAX, DWORD PTR [EAX] - endm - - dec ECX - jne @B - - add EAX, EDX - add EAX, EBX - add EAX, ESI - add EAX, EDI - add EAX, EBP - - POPREG - ret 20 -@Walk6d@28 ENDP - - - -_TEXT$00 ENDS - - -end diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk64.asm p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk64.asm --- p7zip-rar-16.02/Utils/CPUTest/MemLat/Walk64.asm 2011-06-12 17:54:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/Walk64.asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,831 +0,0 @@ -_TEXT SEGMENT - - -PUSHREG macro - push RBX - push RSI - push RDI - push R10 - push R11 - push R12 - push R13 - push R14 - push R15 -endm - -POPREG macro - pop R15 - pop R14 - pop R13 - pop R12 - pop R11 - pop R10 - pop RDI - pop RSI - pop RBX -endm - -offs equ 8 * 9 -p$ = (offs + 8) -num$= (p$ + 8) -a0$ = (num$ + 8) -a1$ = (a0$ + 8) -a2$ = (a1$ + 8) -a3$ = (a2$ + 8) -a4$ = (a3$ + 8) -a5$ = (a4$ + 8) -a6$ = (a5$ + 8) -a7$ = (a6$ + 8) -a8$ = (a7$ + 8) -a9$ = (a8$ + 8) -a10$ = (a9$ + 8) -a11$ = (a10$ + 8) - -align 16 -WalkSum PROC - - PUSHREG - xor RAX, RAX - xor RBX, RBX - xor RSI, RSI - xor RDI, RDI - shr RDX, 5 - align 16 -@@: - ttt = 0 - rept 4 - add RAX, QWORD PTR [RCX + ttt + 0] - add RBX, QWORD PTR [RCX + ttt + 8] - add RSI, QWORD PTR [RCX + ttt + 16] - add RDI, QWORD PTR [RCX + ttt + 24] - ttt = ttt + 32 - endm - - add RCX, 128 - dec RDX - jne @B - - add RAX, RBX - add RAX, RSI - add RAX, RDI - POPREG - ret 0 -WalkSum ENDP - - -align 16 -WalkWrite PROC - - PUSHREG - xor RAX, RAX - shr RDX, 5 - align 16 -@@: - ttt = 0 - rept 16 - mov QWORD PTR [RCX + ttt], RAX - ttt = ttt + 8 - endm - - add RCX, 128 - dec RDX - jne @B - - POPREG - ret 0 -WalkWrite ENDP - -align 16 -WalkSum2 PROC - - PUSHREG - shl R8, 2 - mov R9, R8 - add R9, R8 - mov R10, R9 - add R10, R8 - mov R11, R10 - add R11, R8 - - xor RAX, RAX - xor RBX, RBX - xor RSI, RSI - xor RDI, RDI - - shl RDX, 2 - add RDX, RCX - align 16 -@@: - add EAX, DWORD PTR [RCX] - add EBX, DWORD PTR [RCX + R8] - add ESI, DWORD PTR [RCX + R9] - add EDI, DWORD PTR [RCX + R10] - add RCX, R11 - - cmp RCX, RDX - jb @B - - add RAX, RBX - add RAX, RSI - add RAX, RDI - - POPREG - ret -WalkSum2 ENDP - - -align 16 -WalkWrite2 PROC - - PUSHREG - shl R8, 2 - mov R9, R8 - add R9, R8 - mov R10, R9 - add R10, R8 - mov R11, R10 - add R11, R8 - - xor RAX, RAX - - shl RDX, 2 - add RDX, RCX - align 16 -@@: - rept 2 - - mov DWORD PTR [RCX], EAX - mov DWORD PTR [RCX + R8], EAX - mov DWORD PTR [RCX + R9], EAX - mov DWORD PTR [RCX + R10], EAX - add RCX, R11 - - endm - - cmp RCX, RDX - jb @B - - POPREG - ret -WalkWrite2 ENDP - -align 16 -Walk1Add PROC - - PUSHREG - mov RAX, R8 - shr RDX, 3 - align 16 -@@: - rept 8 - add EAX, DWORD PTR [RCX + RAX*4] - endm - - dec RDX - jne @B - - POPREG - ret 0 -Walk1Add ENDP - - -align 16 -Walk1Nop PROC - - PUSHREG - mov RAX, R8 - xor EBX, EBX - align 16 -@@: - rept 40 - add EAX, EBX - endm - - mov EAX, DWORD PTR [RCX + RAX*4] - - dec RDX - jne @B - - POPREG - ret 0 -Walk1Nop ENDP - -align 16 -Walk1 PROC - - PUSHREG - mov RAX, R8 - shr RDX, 3 - align 16 -@@: - rept 8 - mov EAX, DWORD PTR [RCX + RAX*4] - endm - - dec RDX - jne @B - - POPREG - ret 0 -Walk1 ENDP - -PPP macro x, y - mov x, DWORD PTR [RCX + y * 4] -endm - -QQQ macro x, y - mov DWORD PTR [RCX + y * 4], x -endm - - -align 16 -Walk1w PROC - - PUSHREG - mov RAX, R8 - shr RDX, 3 - align 16 -@@: - rept 4 - - PPP R15d, RAX - - QQQ R15d, RAX - - PPP EAX, R15 - - QQQ EAX, R15 - - endm - - dec RDX - jne @B - - POPREG - ret 0 -Walk1w ENDP - -align 16 -Walk2 PROC - - PUSHREG - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - - dec RDX - jne @B - - mov RAX, R8 - add RAX, R9 - - POPREG - ret 0 -Walk2 ENDP - -align 16 -Walk2w PROC - - PUSHREG - shr RDX, 1 - align 16 -@@: - PPP R15d, R8 - PPP R14d, R9 - - QQQ R15d, R8 - QQQ R14d, R9 - - PPP R8d, R15 - PPP R9d, R14 - - QQQ R8d, R15 - QQQ R9d, R14 - - dec RDX - jne @B - - mov RAX, R8 - add RAX, R9 - - POPREG - ret 0 -Walk2w ENDP - - -align 16 -Walk3 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - - POPREG - ret -Walk3 ENDP - - -align 16 -Walk3w PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - shr RDX, 1 - align 16 -@@: - PPP R15d, R8 - PPP R14d, R9 - PPP R13d, RAX - - QQQ R15d, R8 - QQQ R14d, R9 - QQQ R13d, RAX - - PPP R8d, R15 - PPP R9d, R14 - PPP EAX, R13 - - QQQ R8d, R15 - QQQ R9d, R14 - QQQ EAX, R13 - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - - POPREG - ret -Walk3w ENDP - - -align 16 -Walk4 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - - POPREG - ret -Walk4 ENDP - - -align 16 -Walk4w PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - shr RDX, 1 - align 16 -@@: - - PPP R15d, R8 - PPP R14d, R9 - PPP R13d, RAX - PPP R12d, RSI - - QQQ R15d, R8 - QQQ R14d, R9 - QQQ R13d, RAX - QQQ R12d, RSI - - PPP R8d, R15 - PPP R9d, R14 - PPP EAX, R13 - PPP ESI, R12 - - QQQ R8d, R15 - QQQ R9d, R14 - QQQ EAX, R13 - QQQ ESI, R12 - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - - POPREG - ret -Walk4w ENDP - - -align 16 -Walk5 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - - POPREG - ret -Walk5 ENDP - -align 16 -Walk5w PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - shr RDX, 1 - align 16 -@@: - PPP R15d, R8 - PPP R14d, R9 - PPP R13d, RAX - PPP R12d, RSI - PPP R11d, RDI - - QQQ R15d, R8 - QQQ R14d, R9 - QQQ R13d, RAX - QQQ R12d, RSI - QQQ R11d, RDI - - PPP R8d, R15 - PPP R9d, R14 - PPP EAX, R13 - PPP ESI, R12 - PPP EDI, R11 - - QQQ R8d, R15 - QQQ R9d, R14 - QQQ EAX, R13 - QQQ ESI, R12 - QQQ EDI, R11 - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - - POPREG - ret -Walk5w ENDP - -align 16 -Walk6 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - - POPREG - ret -Walk6 ENDP - -align 16 -Walk6w PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - shr RDX, 1 - align 16 -@@: - PPP R15d, R8 - PPP R14d, R9 - PPP R13d, RAX - PPP R12d, RSI - PPP R11d, RDI - PPP R10d, RBX - - QQQ R15d, R8 - QQQ R14d, R9 - QQQ R13d, RAX - QQQ R12d, RSI - QQQ R11d, RDI - QQQ R10d, RBX - - PPP R8d, R15 - PPP R9d, R14 - PPP EAX, R13 - PPP ESI, R12 - PPP EDI, R11 - PPP EBX, R10 - - QQQ R8d, R15 - QQQ R9d, R14 - QQQ EAX, R13 - QQQ ESI, R12 - QQQ EDI, R11 - QQQ EBX, R10 - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - - POPREG - ret -Walk6w ENDP - -align 16 -Walk7 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - - POPREG - ret -Walk7 ENDP - - -align 16 -Walk8 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - mov r11d, DWORD PTR a7$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - mov r11d, DWORD PTR [RCX + R11*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - add RAX, R11 - - POPREG - ret -Walk8 ENDP - - -align 16 -Walk9 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - mov r11d, DWORD PTR a7$[rsp] - mov r12d, DWORD PTR a8$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - mov r11d, DWORD PTR [RCX + R11*4] - mov r12d, DWORD PTR [RCX + R12*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - add RAX, R11 - add RAX, R12 - - POPREG - ret -Walk9 ENDP - - -align 16 -Walk10 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - mov r11d, DWORD PTR a7$[rsp] - mov r12d, DWORD PTR a8$[rsp] - mov r13d, DWORD PTR a9$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - mov r11d, DWORD PTR [RCX + R11*4] - mov r12d, DWORD PTR [RCX + R12*4] - mov r13d, DWORD PTR [RCX + R13*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - add RAX, R11 - add RAX, R12 - add RAX, R13 - - POPREG - ret -Walk10 ENDP - -align 16 -Walk11 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - mov r11d, DWORD PTR a7$[rsp] - mov r12d, DWORD PTR a8$[rsp] - mov r13d, DWORD PTR a9$[rsp] - mov r14d, DWORD PTR a10$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - mov r11d, DWORD PTR [RCX + R11*4] - mov r12d, DWORD PTR [RCX + R12*4] - mov r13d, DWORD PTR [RCX + R13*4] - mov r14d, DWORD PTR [RCX + R14*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - add RAX, R11 - add RAX, R12 - add RAX, R13 - add RAX, R14 - - POPREG - ret -Walk11 ENDP - -align 16 -Walk12 PROC - PUSHREG - mov EAX, DWORD PTR a2$[rsp] - mov ESI, DWORD PTR a3$[rsp] - mov EDI, DWORD PTR a4$[rsp] - mov EBX, DWORD PTR a5$[rsp] - mov r10d, DWORD PTR a6$[rsp] - mov r11d, DWORD PTR a7$[rsp] - mov r12d, DWORD PTR a8$[rsp] - mov r13d, DWORD PTR a9$[rsp] - mov r14d, DWORD PTR a10$[rsp] - mov r15d, DWORD PTR a11$[rsp] - align 16 -@@: - mov R8d, DWORD PTR [RCX + R8*4] - mov R9d, DWORD PTR [RCX + R9*4] - mov EAX, DWORD PTR [RCX + RAX*4] - mov ESI, DWORD PTR [RCX + RSI*4] - mov EDI, DWORD PTR [RCX + RDI*4] - mov EBX, DWORD PTR [RCX + RBX*4] - mov r10d, DWORD PTR [RCX + R10*4] - mov r11d, DWORD PTR [RCX + R11*4] - mov r12d, DWORD PTR [RCX + R12*4] - mov r13d, DWORD PTR [RCX + R13*4] - mov r14d, DWORD PTR [RCX + R14*4] - mov r15d, DWORD PTR [RCX + R15*4] - - dec RDX - jne @B - - add RAX, R8 - add RAX, R9 - add RAX, RSI - add RAX, RDI - add RAX, RBX - add RAX, R10 - add RAX, R11 - add RAX, R12 - add RAX, R13 - add RAX, R14 - add RAX, R15 - - POPREG - ret -Walk12 ENDP - -_TEXT ENDS - - -end diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/makefile p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile --- p7zip-rar-16.02/Utils/CPUTest/MemLat/makefile 2016-03-10 20:22:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -PROG=MemLat - - -# ./MemLat 4 p5 n - -# -DLARGE_PAGES -LOCAL_FLAGS=-I. -DNUM_DIRECT_TESTS=6 -DNUM_PAR_TESTS=5 - -include ../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -OBJS=MemLat.o Walk.o - -include ../../../makefile.glb - diff -Nru p7zip-rar-16.02/Utils/CPUTest/MemLat/makefile.list p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile.list --- p7zip-rar-16.02/Utils/CPUTest/MemLat/makefile.list 2015-10-03 20:51:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MemLat/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ - -all: $(PCH_NAME) $(PROG) - -SRCS=MemLat.cpp - -MemLat.o : MemLat.cpp - $(CXX) $(CXXFLAGS) MemLat.cpp - -Walk.o : Walk.c - $(CC) $(CFLAGS) Walk.c - diff -Nru p7zip-rar-16.02/Utils/CPUTest/MyVersion.h p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MyVersion.h --- p7zip-rar-16.02/Utils/CPUTest/MyVersion.h 2011-06-12 17:52:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/MyVersion.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#define MY_VERSION "11.00" -#define MY_DATE "2011-05-12" -#define MY_COPYRIGHT ": Igor Pavlov : Public domain" -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/Utils/CPUTest/PipeLen/MemLat and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/MemLat differ diff -Nru p7zip-rar-16.02/Utils/CPUTest/PipeLen/PipeLen.cpp p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/PipeLen.cpp --- p7zip-rar-16.02/Utils/CPUTest/PipeLen/PipeLen.cpp 2011-06-12 18:16:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/PipeLen.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,428 +0,0 @@ -// PipeLen.cpp: measures CPU pipeline length - -#include - -#ifdef _MSC_VER -#pragma warning(disable : 4996 ) -#endif - -#include "../Benchmark.h" -#include "../MyVersion.h" - -#define __fastcall /* */ - -// #define _USE_ASM - -unsigned GetCyclesPerPrec() -{ - #ifdef TIMER_IS_FAST - return 1 << 12; - #else - return 1 << 20; // increase it, if you need more precision - #endif -} - -typedef unsigned char MyType; - -static const size_t kTempSize = 1 << 17; - -static void PrintHelp(CPrinter &f) -{ - f.Print("use: pipelen.exe Size\n Size - limit in KB\n"); -} - -#define C_NAME(x) C_##x -#define A_NAME(x) PL_##x - -#define HHH(x) unsigned __fastcall C_NAME(x)(unsigned char *values, unsigned bufferSize) -#define DDD(x) unsigned __fastcall A_NAME(x)(unsigned char *values, unsigned bufferSize) - -extern "C" -{ -#ifdef _USE_ASM -DDD( 0); DDD( 1); DDD( 2); DDD( 3); DDD( 4); DDD( 5); DDD( 6); DDD( 7); DDD( 8); DDD( 9); -DDD(10); DDD(11); DDD(12); DDD(13); DDD(14); DDD(15); DDD(16); DDD(17); DDD(18); DDD(19); -DDD(20); DDD(21); DDD(22); DDD(23); DDD(24); DDD(25); DDD(26); DDD(27); DDD(28); DDD(29); -DDD(30); DDD(31); DDD(32); DDD(33); DDD(34); DDD(35); DDD(36); DDD(37); DDD(38); DDD(39); -DDD(40); DDD(41); DDD(42); DDD(43); DDD(44); DDD(45); DDD(46); DDD(47); DDD(48); DDD(49); -// DDD(50); DDD(51); DDD(52); DDD(53); -#define NUM_ASM_TESTS 50 -#else -#define NUM_ASM_TESTS 0 -#endif - -#define NUM_C_MUL_TESTS 6 -#define NUM_C_READ1_TESTS 3 -#define NUM_C_READ2_TESTS 5 - -#define NUM_C_TESTS (NUM_C_MUL_TESTS + NUM_C_READ1_TESTS + NUM_C_READ2_TESTS) -#define LATEST_TEST_INDEX (NUM_C_TESTS + NUM_ASM_TESTS - 1) - -#define CCC(x) case x: { do sum += C_NAME(x)(values, bufferSize); while (--numPrecCycles); break; } -#define AAA(x) case NUM_C_TESTS + x: { do sum += A_NAME(x)(values, bufferSize); while (--numPrecCycles); break; } - -#define PRE_SIZE (256 + 4) -#define ZZZ(d, s) d = s ^ values[(size_t)s - 256]; -#define RRR ZZZ(c, c); -#define TTT c ^= values[(size_t)c - PRE_SIZE]; -#define VVV(b, G) if ((c & (1 << b)) != 0) { G } TTT; TTT; - -#define WWW(b, G) { UInt32 t; ZZZ(t, c); if ((c & (1 << b)) != 0) \ -{ ZZZ(c, t); G; ZZZ(t, c); } ZZZ(c, t); TTT; } - -#define MMM c = (c * m) ^ d -#define NNN c = (c * m2) ^ d -#define BBB(b, G) if ((c & (1 << b)) != 0) { RRR; G } NNN; NNN; - - -UInt32 g_Mult = 1; -UInt32 g_Mult2 = 1; -UInt32 g_Add = 0; - -#define JJJ(n, G) \ -HHH(n) { \ - UInt32 d = g_Add; UInt32 m = g_Mult; UInt32 m2 = g_Mult2; UInt32 c = 0; \ - for (unsigned i = 0; i < bufferSize; i++) { \ - c = values[(c >> 8) + i]; \ - BBB(0, G); BBB(1, G); BBB(2, G); BBB(3, G); BBB(4, G); BBB(5, G); BBB(6, G); BBB(7, G); \ - } return c; } - -#define GGG(n, G, Y) \ -HHH(n) { \ - UInt32 c = 0; \ - for (unsigned i = 0; i < bufferSize; i++) { \ - c = values[(c >> 8) + i]; \ - Y(0, G); Y(1, G); Y(2, G); Y(3, G); Y(4, G); Y(5, G); Y(6, G); Y(7, G); \ - } return c; } - -#define KKK(n, G) GGG(n, G, VVV) -#define UUU(n, G) GGG(n, G, WWW) - -JJJ(0, MMM;) -JJJ(1, MMM; MMM;) -JJJ(2, MMM; MMM; MMM;) -JJJ(3, MMM; MMM; MMM; MMM;) -JJJ(4, MMM; MMM; MMM; MMM; MMM;) -JJJ(5, MMM; MMM; MMM; MMM; MMM; MMM;) - -UUU(6, RRR;) -UUU(7, RRR; RRR;) -UUU(8, RRR; RRR; RRR;) - -KKK(9, RRR;) -KKK(10, RRR; RRR;) -KKK(11, RRR; RRR; RRR;) -KKK(12, RRR; RRR; RRR; RRR;) -KKK(13, RRR; RRR; RRR; RRR; RRR;) - -} - -static void PrintRes(CPrinter &f, const char *s, double v, bool nsMode, const char *post) -{ - char temp[128]; - sprintf(temp, "Pipeline length %s = %6.2f %s", s, v, nsMode ? "ns" : "stages"); - f.Print(temp); - if (post) - f.Print(post); - f.NewLine(); -} - -static void PrintSize(CPrinter &f, UInt32 n) -{ - char s[32]; - if (n >= 1 << 20) - sprintf(s, " %4d-M", n >> 20); - else if (n >= 1 << 10) - sprintf(s, " %4d-K", n >> 10); - else - sprintf(s, " %4d", n); - f.Print(s); -} - -const char *kNames[][2] = -{ - { "if (c & mask) { c^=v[c-256]; REP-N(c=c*1^0) } REP-2(c=c*1^0)", " - TEST" }, - { "MOVZX XOR ; if (c & mask) { REP-N(c^=v[c-256]) } REP-2(c^=v[c-260])", " + MOVZX + XOR - TEST" }, - { "if (c & mask) { REP-N(c^=v[c-256]) } REP-2(c^=v[c-260])", " - TEST" }, - { "REP-12 (ADD EBX, EAX) ; TEST EBX, (1 << NN) ; JNZ", " - TEST" }, - { "REP-14 (ADD EBX, EAX) ; ADD EBX, EBX ; JC", NULL }, - { "REP-5 (MOVZX, XOR) ; SHR 1 ; JC (Unaligned)", NULL }, - { "REP-10 (MOVZX, XOR) ; SHR 1 ; JC", NULL }, - { "REP-4 (IMUL EBX, EBX, 1) ; ADD EBX, EBX; JC", NULL }, -}; - -const unsigned kNumTests[] = -{ - NUM_C_MUL_TESTS, - NUM_C_READ1_TESTS, - NUM_C_READ2_TESTS, - 13, - 15, - 6, - 11, - 5 -}; - -const unsigned kNumPosBranches[] = -{ - 8, - 8, - 8, - 32, - 32, - 8, - 8, - 32 -}; - -int main2(CPrinter &f, int numArgs, const char *args[]) -{ - f.Print("PipeLen " MY_VERSION_COPYRIGHT_DATE "\n\n"); - if (numArgs < 1 || numArgs > 4) - { - PrintHelp(f); - return 1; - } - - unsigned bufferSizeMax = (64 << 10); - bool nsMode = true; - #ifdef CYCLES_MODE - nsMode = false; - #endif - - const unsigned kBasePowerMax = 28; - unsigned testIndexBegin = 0; - unsigned testIndexEnd = LATEST_TEST_INDEX; - - for (int yy = 1; yy < numArgs; yy++) - { - const char *arg = args[yy]; - if (arg[0] == 'n') - nsMode = true; - else if (arg[0] == 'r') - { - arg++; - unsigned len = (unsigned)strlen(arg); - if (len > 0) - { - testIndexBegin = atoi(arg); - if (testIndexBegin > LATEST_TEST_INDEX) - return 1; - testIndexEnd = testIndexBegin; - } - } - else - { - bufferSizeMax = atoi(arg); - if (bufferSizeMax < 1 || bufferSizeMax > ((1 << (kBasePowerMax - 10)))) - { - PrintHelp(f); - return 2; - } - bufferSizeMax <<= 10; - } - } - - MY_SET_AFFINITY; - - MyType *values = (MyType *)malloc((bufferSizeMax + 4 + PRE_SIZE) * sizeof(MyType)); - if (values == 0) - { - f.Print("Not enough memory\n"); - return 1; - } - { - for (int i = 0; i < PRE_SIZE; i++) - *values++ = 0; - } - - unsigned sum2 = 0; - - { - for (unsigned k = 0; k < (1 << 28); k++) - sum2 += (k >> 3); - } - - for (unsigned testIndex = testIndexBegin; testIndex <= testIndexEnd; testIndex++) - { - UInt64 startCount = GetTimeCount(); - UInt64 startCount2 = GetTimeCount2(); - - for (unsigned k = 0; k < (1 << 25); k++) - sum2 += (k >> 3); - - CRandomGenerator rg; - - const unsigned kNumSubItemsBits = 0; - const unsigned kNumSubItems = 1 << kNumSubItemsBits; - const unsigned kNumMaxItems = (kBasePowerMax + 1) * kNumSubItems; - unsigned sizes[kNumMaxItems]; - - const unsigned kNumSimMax = 4; - double ticksResults[kNumSimMax][kNumMaxItems]; - - const unsigned kStartPower = 2; - unsigned sum = 0; - - unsigned indexMax = 0; - - unsigned numPosBranches = 32; - for (int numSimSpec = 0; numSimSpec < kNumSimMax; numSimSpec++) - { - int index = 0; - for (int k = kStartPower; k < 64; k++) - { - int t; - for (t = 0; t < kNumSubItems; t++, index++) - { - unsigned bufferSize = (1 << k); - bufferSize += t * (1 << (k - kNumSubItemsBits)); - UInt32 numBranches = bufferSize * 8; - numBranches /= numPosBranches; - numBranches *= numPosBranches; - bufferSize = numBranches / 8; - - if (bufferSize > bufferSizeMax) - break; - sizes[index] = numBranches; - - unsigned i; - - for (i = 0; i < bufferSize; i++) - values[i] = (MyType)((numSimSpec < 2) ? ((numSimSpec & 1) ? 0xFF : 0) : - ((numSimSpec == 2) ? 0xAA : ((rg.GetRnd() >> 6) & 0xFF))); - - const unsigned kNumTestCycles = 5; - const unsigned numPrecCycles2 = (1 + GetCyclesPerPrec() / bufferSize); - UInt64 ticks[kNumTestCycles]; - for (i = 0; i < kNumTestCycles; i++) - { - UInt64 startTime = GetTimeCount(); - unsigned numPrecCycles = numPrecCycles2; - switch(testIndex) - { - CCC( 0) CCC( 1) CCC( 2) CCC( 3) CCC( 4) CCC( 5) CCC( 6) CCC( 7) CCC( 8) CCC( 9) - CCC(10) CCC(11) CCC(12) CCC(13) // CCC(14) CCC(15) CCC(16) CCC(17) CCC(18) - #ifdef _USE_ASM - AAA( 0) AAA( 1) AAA( 2) AAA( 3) AAA( 4) AAA( 5) AAA( 6) AAA( 7) AAA( 8) AAA( 9) - AAA(10) AAA(11) AAA(12) AAA(13) AAA(14) AAA(15) AAA(16) AAA(17) AAA(18) AAA(19) - AAA(20) AAA(21) AAA(22) AAA(23) AAA(24) AAA(25) AAA(26) AAA(27) AAA(28) AAA(29) - AAA(30) AAA(31) AAA(32) AAA(33) AAA(34) AAA(35) AAA(36) AAA(37) AAA(38) AAA(39) - AAA(40) AAA(41) AAA(42) AAA(43) AAA(44) AAA(45) AAA(46) AAA(47) AAA(48) AAA(49) - // AAA(50) AAA(51) AAA(52) AAA(53) - #endif - default: return 1; - } - ticks[i] = GetTimeCount() - startTime; - } - - double minValue = 1 << 30; - for (i = 0; i < kNumTestCycles; i++) - { - double d = (double)(Int64)ticks[i] / (bufferSize * 8) / numPrecCycles2; - if (d < minValue) - minValue = d; - } - if (minValue == 0) - minValue = 1e-30; - ticksResults[numSimSpec][index] = minValue; - } - if (t != kNumSubItems) - break; - } - indexMax = index; - } - UInt64 countTotal = GetTimeCount() - startCount; - UInt64 countTotal2 = GetTimeCount2() - startCount2; - if (countTotal2 == 0) - countTotal2 = 1; - - double freq = double((Int64)countTotal) * (Int64)GetFreq2() / (Int64)countTotal2; - if (freq == 0) - freq = 1; - - f.Print("#Branch #B/P 0 1 0-1 Random Len1 Len2\n\n"); - - double res[2]; - - unsigned num1 = 0; - unsigned startSum = 0; - unsigned group; - for (group = 0; group < sizeof(kNumTests) / sizeof(kNumTests[0]); group++) - { - unsigned sum2 = startSum + kNumTests[group]; - if (testIndex < sum2) - { - num1 = testIndex - startSum; - if (group <= 1) - num1++; - break; - } - startSum = sum2; - } - - numPosBranches = kNumPosBranches[group]; - for (unsigned i = 0; i < indexMax; i++) - { - UInt32 numBranches = sizes[i]; - PrintSize(f, numBranches); - PrintSize(f, numBranches / numPosBranches); - for (unsigned numSim = 0; numSim <= kNumSimMax + 1; numSim++) - { - double value = (numSim == kNumSimMax) ? - ticksResults[kNumSimMax - 1][i] * 2 - ticksResults[0][i] - ticksResults[1][i]: - (numSim == kNumSimMax + 1) ? - ticksResults[kNumSimMax - 1][i] * 2 - ticksResults[2][i] * 2 : - ticksResults[numSim][i]; - if (nsMode) - value = double(value) * 1000000000 / freq; - if (numSim >= kNumSimMax) - res[numSim - kNumSimMax] = value; - char temp[32]; - sprintf(temp, " %7.2f", value); - f.Print(temp); - } - f.NewLine(); - } - f.NewLine(); - - char temp[128]; - - sprintf(temp, "Test #%2d (%2d): %s \n", group, num1, kNames[group][0]); - f.Print(temp); - sprintf(temp, "Timer frequency = %10.0f Hz\n", (double)(Int64)GetFreq2()); - f.Print(temp); - sprintf(temp, "CPU frequency = %10.2f MHz\n", freq / 1000000); - f.Print(temp); - - const char *kPost = kNames[group][1]; - if (indexMax > 0) - { - char s[32]; - for (unsigned i = 0; i < 2; i++) - { - sprintf(s, "v.%d", i + 1); - PrintRes(f, s, res[i], nsMode, kPost); - } - } - PrintRes(f, " ", (res[0] + res[1]) / 2, nsMode, kPost); - - f.NewLine(); - f.NewLine(); - sum2 += sum; - - } - return (unsigned)sum2; -} - -int -#ifdef _MSC_VER -_cdecl -#endif -main(int numArgs, const char *args[]) -{ - CPrinter f(kTempSize); - int res = main2(f, numArgs, args); - fputs(f.buf, stdout); - return res; -} diff -Nru p7zip-rar-16.02/Utils/CPUTest/PipeLen/makefile p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile --- p7zip-rar-16.02/Utils/CPUTest/PipeLen/makefile 2016-03-10 20:23:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -PROG=PipeLen - -# -D_USE_ASM -LOCAL_FLAGS=-I. - -include ../../../makefile.machine - -TARGET_FLAGS=$(CC_EXE) -LOCAL_LINK=$(LINK_EXE) -LIBS=$(LOCAL_LIBS) - -# pl.o -OBJS=PipeLen.o - - -include ../../../makefile.glb - diff -Nru p7zip-rar-16.02/Utils/CPUTest/PipeLen/makefile.list p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile.list --- p7zip-rar-16.02/Utils/CPUTest/PipeLen/makefile.list 2015-10-03 20:52:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/makefile.list 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - -all: $(PCH_NAME) $(PROG) - -SRCS=PipeLen.cpp - -PipeLen.o : PipeLen.cpp - $(CXX) $(CXXFLAGS) PipeLen.cpp - diff -Nru p7zip-rar-16.02/Utils/CPUTest/PipeLen/pl32.asm p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/pl32.asm --- p7zip-rar-16.02/Utils/CPUTest/PipeLen/pl32.asm 2011-06-12 18:16:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/CPUTest/PipeLen/pl32.asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -.386 -.model flat - -OPTION PROLOGUE:NONE -OPTION EPILOGUE:NONE - -.data -_TEXT$00 SEGMENT PARA PUBLIC 'CODE' - - -MY_START macro - push EBX - push EBP - xor EAX, EAX - xor EBX, EBX - mov EBP, ECX - xor ECX, ECX - shr EDX, 2 -endm - -FIN macro - dec EDX - jnz lab1 - pop EBP - pop EBX - ret 0 -endm - -REP_MOVZX macro num - rept num - movzx EAX, BYTE PTR [ECX + EBX] - xor EBX, EAX - endm -endm - -REP_IMUL macro num - rept num - IMUL EBX, 1 - endm -endm - -REP_ADD macro num - rept num - add EBX, EAX - endm -endm - -READ_VAL_8 macro - movzx EBX, BYTE PTR [EBP + EBX] - add EBP, 1 -endm - -READ_VAL_32 macro - mov EBX, DWORD PTR [EBP + EBX] - add EBP, 4 -endm - -READ_VAL_32_2 macro - sub EBP, EBX - add EBP, EBX - mov EBX, DWORD PTR [EBP] - add EBP, 4 -endm - -TEST_MOVZX macro numOps1, numOps2 -MY_START - shl EDX, 2 - mov ECX, EBP - sub ECX, 256 - READ_VAL_8 - align 16 -lab1: - ttt = 0 - rept 8 - REP_MOVZX numOps1 - shr EBX, 1 - jc @F - REP_MOVZX numOps2 - ttt = ttt + 1 -@@: - endm - - READ_VAL_8 - FIN -endm - -TEST_IMUL macro numOps1, numOps2 -MY_START - READ_VAL_32 - align 16 -lab1: - ttt = 0 - rept 32 - REP_IMUL numOps1 - add EBX, EBX - jc @F - REP_IMUL numOps2 - ttt = ttt + 1 -@@: - endm - - READ_VAL_32 - FIN -endm - -TEST_ADD_ADD macro numOps1, numOps2 -MY_START - READ_VAL_32_2 - align 16 -lab1: - ttt = 0 - rept 32 - REP_ADD numOps1 - add EBX, EBX - jc @F - REP_ADD numOps2 - ttt = ttt + 1 -@@: - endm - - READ_VAL_32_2 - FIN -endm - -TEST_ADD_TEST macro numOps1, numOps2 -MY_START - READ_VAL_32_2 - align 16 -lab1: - ttt = 0 - rept 32 - REP_ADD numOps1 - test EBX, 1 shl ttt - jnz @F - REP_ADD numOps2 - ttt = ttt + 1 -@@: - endm - - READ_VAL_32_2 - FIN -endm - - -BBB macro kkk - align 16 - @CatStr(@PL_, %kkk, @8) PROC -endm - -EEE macro kkk - @CatStr(@PL_, %kkk, @8) ENDP - kkk = kkk + 1 -endm - - -MY_REPT macro kkk: req, num: req, my_func: req - kkkStart = kkk -rept num - BBB kkk - my_func (kkk - kkkStart), (num - 1 - (kkk - kkkStart)) - EEE kkk -endm -endm - - -kkk = 0 - - - MY_REPT kkk, 13, TEST_ADD_TEST - MY_REPT kkk, 15, TEST_ADD_ADD - MY_REPT kkk, 6, TEST_MOVZX - MY_REPT kkk, 11, TEST_MOVZX - MY_REPT kkk, 5, TEST_IMUL - - -_TEXT$00 ENDS - - -end diff -Nru p7zip-rar-16.02/Utils/bin_to_sources.py p7zip-rar-16.02+really25.00+ds/Utils/bin_to_sources.py --- p7zip-rar-16.02/Utils/bin_to_sources.py 2015-09-12 15:05:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/bin_to_sources.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -#!/usr/bin/env python - -import fnmatch -import os -import sys - -dir0='CPP/7zip/Bundles/Alone' -file0='Utils/file_7za.py' - -dir0='CPP/7zip/Bundles/SFXCon' -file0='Utils/file_7zCon_sfx.py' - -dir0='CPP/7zip/UI/Console' -file0='Utils/file_7z.py' - -dir0='CPP/7zip/Compress/Rar' -file0='Utils/file_Codecs_Rar_so.py' - -dir0='CPP/7zip/Bundles/Format7zFree' -file0='Utils/file_7z_so.py' - -dir0='CPP/7zip/UI/GUI' -file0='Utils/file_7zG.py' - -dir0='CPP/7zip/Bundles/Alone7z' -file0='Utils/file_7zr.py' - -dir0='CPP/7zip/UI/FileManager' -file0='Utils/file_7zFM.py' - -dir0='CPP/7zip/Bundles/LzmaCon' -file0='Utils/file_LzmaCon.py' - -dir0='CPP/7zip/UI/Client7z' -file0='Utils/file_Client7z.py' - -dir0='CPP/7zip/UI/P7ZIP' -file0='Utils/file_P7ZIP.py' - -dir0='CPP/7zip/TEST/TestUI' -file0='Utils/file_TestUI.py' - - -listO=[] - -for file in os.listdir(dir0): - if fnmatch.fnmatch(file, '*.o'): - # print(file) - file=os.path.splitext(file)[0] - listO.append(file) - - -listO.sort() - -listc=[] -listcpp=[] - -for file in listO: - # print("Searching " + file + " ...") - f_c= None - f_cpp = None - file_c = file + '.c' - file_cpp = file + '.cpp' - for root, dirs, files in os.walk("."): - for f in files: - if f == file_c: - f_c=os.path.join(root, f) - if f == file_cpp: - f_cpp=os.path.join(root, f) - if f_c is None: - if f_cpp is None: - print("Cannot find {}".format(file)) - sys.exit(-1) - else: - listcpp.append(f_cpp[2:]) - else: - if f_cpp is None: - listc.append(f_c[2:]) - else: - print("error {} => {} and {}".format(file,f_c,f_cpp)) - sys.exit(-1) - -f=open(file0,'w') -f.write('\n') - -listc.sort() -listcpp.sort() - -f.write('files_c=[\n') -for file in listc: - f.write(" '{}',\n".format(file)) -f.write(']\n') -f.write('\n') -f.write('files_cpp=[\n') -for file in listcpp: - f.write(" '{}',\n".format(file)) -f.write(']\n') -f.write('\n') -f.close() - - diff -Nru p7zip-rar-16.02/Utils/file_7z.py p7zip-rar-16.02+really25.00+ds/Utils/file_7z.py --- p7zip-rar-16.02/Utils/file_7z.py 2014-12-30 16:44:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7z.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Alloc.c', - 'C/CpuArch.c', - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/UI/Common/ArchiveCommandLine.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/Bench.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/EnumDirItems.cpp', - 'CPP/7zip/UI/Common/Extract.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/HashCalc.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Common/SetProperties.cpp', - 'CPP/7zip/UI/Common/SortUtils.cpp', - 'CPP/7zip/UI/Common/TempFiles.cpp', - 'CPP/7zip/UI/Common/Update.cpp', - 'CPP/7zip/UI/Common/UpdateAction.cpp', - 'CPP/7zip/UI/Common/UpdateCallback.cpp', - 'CPP/7zip/UI/Common/UpdatePair.cpp', - 'CPP/7zip/UI/Common/UpdateProduce.cpp', - 'CPP/7zip/UI/Console/BenchCon.cpp', - 'CPP/7zip/UI/Console/ConsoleClose.cpp', - 'CPP/7zip/UI/Console/ExtractCallbackConsole.cpp', - 'CPP/7zip/UI/Console/HashCon.cpp', - 'CPP/7zip/UI/Console/List.cpp', - 'CPP/7zip/UI/Console/Main.cpp', - 'CPP/7zip/UI/Console/MainAr.cpp', - 'CPP/7zip/UI/Console/OpenCallbackConsole.cpp', - 'CPP/7zip/UI/Console/PercentPrinter.cpp', - 'CPP/7zip/UI/Console/UpdateCallbackConsole.cpp', - 'CPP/7zip/UI/Console/UserInputUtils.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/ListFileUtils.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/StdInStream.cpp', - 'CPP/Common/StdOutStream.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Windows/DLL.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/myWindows/myAddExeFlag.cpp', - 'CPP/myWindows/mySplitCommandLine.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7zCon_sfx.py p7zip-rar-16.02+really25.00+ds/Utils/file_7zCon_sfx.py --- p7zip-rar-16.02/Utils/file_7zCon_sfx.py 2015-11-06 16:10:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7zCon_sfx.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Aes.c', - 'C/Alloc.c', - 'C/Bcj2.c', - 'C/Bra.c', - 'C/Bra86.c', - 'C/BraIA64.c', - 'C/CpuArch.c', - 'C/Delta.c', - 'C/Lzma2Dec.c', - 'C/LzmaDec.c', - 'C/Ppmd7.c', - 'C/Ppmd7Dec.c', - 'C/Sha256.c', - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/7z/7zDecode.cpp', - 'CPP/7zip/Archive/7z/7zExtract.cpp', - 'CPP/7zip/Archive/7z/7zHandler.cpp', - 'CPP/7zip/Archive/7z/7zHeader.cpp', - 'CPP/7zip/Archive/7z/7zIn.cpp', - 'CPP/7zip/Archive/7z/7zRegister.cpp', - 'CPP/7zip/Archive/Common/CoderMixer2.cpp', - 'CPP/7zip/Archive/Common/ItemNameUtils.cpp', - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Bundles/SFXCon/SfxCon.cpp', - 'CPP/7zip/Common/CWrappers.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/InBuffer.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/StreamBinder.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/VirtThread.cpp', - 'CPP/7zip/Compress/Bcj2Coder.cpp', - 'CPP/7zip/Compress/Bcj2Register.cpp', - 'CPP/7zip/Compress/BcjCoder.cpp', - 'CPP/7zip/Compress/BcjRegister.cpp', - 'CPP/7zip/Compress/BranchMisc.cpp', - 'CPP/7zip/Compress/BranchRegister.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/Compress/CopyRegister.cpp', - 'CPP/7zip/Compress/DeltaFilter.cpp', - 'CPP/7zip/Compress/Lzma2Decoder.cpp', - 'CPP/7zip/Compress/Lzma2Register.cpp', - 'CPP/7zip/Compress/LzmaDecoder.cpp', - 'CPP/7zip/Compress/LzmaRegister.cpp', - 'CPP/7zip/Compress/PpmdDecoder.cpp', - 'CPP/7zip/Compress/PpmdRegister.cpp', - 'CPP/7zip/Crypto/7zAes.cpp', - 'CPP/7zip/Crypto/7zAesRegister.cpp', - 'CPP/7zip/Crypto/MyAes.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/Extract.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Console/ConsoleClose.cpp', - 'CPP/7zip/UI/Console/ExtractCallbackConsole.cpp', - 'CPP/7zip/UI/Console/List.cpp', - 'CPP/7zip/UI/Console/MainAr.cpp', - 'CPP/7zip/UI/Console/OpenCallbackConsole.cpp', - 'CPP/7zip/UI/Console/PercentPrinter.cpp', - 'CPP/7zip/UI/Console/UserInputUtils.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/StdInStream.cpp', - 'CPP/Common/StdOutStream.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/myWindows/mySplitCommandLine.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7zFM.py p7zip-rar-16.02+really25.00+ds/Utils/file_7zFM.py --- p7zip-rar-16.02/Utils/file_7zFM.py 2015-06-22 19:40:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7zFM.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Alloc.c', - 'C/CpuArch.c', - 'C/Sha256.c', - 'C/Sort.c', - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/UI/Agent/Agent.cpp', - 'CPP/7zip/UI/Agent/AgentOut.cpp', - 'CPP/7zip/UI/Agent/AgentProxy.cpp', - 'CPP/7zip/UI/Agent/ArchiveFolder.cpp', - 'CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp', - 'CPP/7zip/UI/Agent/ArchiveFolderOut.cpp', - 'CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveName.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/CompressCall.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/EnumDirItems.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/HashCalc.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Common/SetProperties.cpp', - 'CPP/7zip/UI/Common/SortUtils.cpp', - 'CPP/7zip/UI/Common/UpdateAction.cpp', - 'CPP/7zip/UI/Common/UpdateCallback.cpp', - 'CPP/7zip/UI/Common/UpdatePair.cpp', - 'CPP/7zip/UI/Common/UpdateProduce.cpp', - 'CPP/7zip/UI/Common/WorkDir.cpp', - 'CPP/7zip/UI/Common/ZipRegistry.cpp', - 'CPP/7zip/UI/FileManager/App.cpp', - 'CPP/7zip/UI/FileManager/ClassDefs.cpp', - 'CPP/7zip/UI/FileManager/ComboDialog.cpp', - 'CPP/7zip/UI/FileManager/ComboDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/CopyDialog.cpp', - 'CPP/7zip/UI/FileManager/CopyDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/ExtractCallback.cpp', - 'CPP/7zip/UI/FileManager/FM.cpp', - 'CPP/7zip/UI/FileManager/FM_rc.cpp', - 'CPP/7zip/UI/FileManager/FSDrives.cpp', - 'CPP/7zip/UI/FileManager/FSFolder.cpp', - 'CPP/7zip/UI/FileManager/FSFolderCopy.cpp', - 'CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp', - 'CPP/7zip/UI/FileManager/FormatUtils.cpp', - 'CPP/7zip/UI/FileManager/LangUtils.cpp', - 'CPP/7zip/UI/FileManager/ListViewDialog.cpp', - 'CPP/7zip/UI/FileManager/ListViewDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/MessagesDialog.cpp', - 'CPP/7zip/UI/FileManager/MessagesDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/MyLoadMenu.cpp', - 'CPP/7zip/UI/FileManager/OpenCallback.cpp', - 'CPP/7zip/UI/FileManager/OverwriteDialog.cpp', - 'CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/Panel.cpp', - 'CPP/7zip/UI/FileManager/PanelCopy.cpp', - 'CPP/7zip/UI/FileManager/PanelCrc.cpp', - 'CPP/7zip/UI/FileManager/PanelFolderChange.cpp', - 'CPP/7zip/UI/FileManager/PanelItemOpen.cpp', - 'CPP/7zip/UI/FileManager/PanelItems.cpp', - 'CPP/7zip/UI/FileManager/PanelListNotify.cpp', - 'CPP/7zip/UI/FileManager/PanelMenu.cpp', - 'CPP/7zip/UI/FileManager/PanelOperations.cpp', - 'CPP/7zip/UI/FileManager/PanelSelect.cpp', - 'CPP/7zip/UI/FileManager/PanelSort.cpp', - 'CPP/7zip/UI/FileManager/PanelSplitFile.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/ProgramLocation.cpp', - 'CPP/7zip/UI/FileManager/ProgressDialog2.cpp', - 'CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp', - 'CPP/7zip/UI/FileManager/PropertyName.cpp', - 'CPP/7zip/UI/FileManager/RegistryUtils.cpp', - 'CPP/7zip/UI/FileManager/RootFolder.cpp', - 'CPP/7zip/UI/FileManager/SplitDialog.cpp', - 'CPP/7zip/UI/FileManager/SplitDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/SplitUtils.cpp', - 'CPP/7zip/UI/FileManager/StringUtils.cpp', - 'CPP/7zip/UI/FileManager/SysIconUtils.cpp', - 'CPP/7zip/UI/FileManager/TextPairs.cpp', - 'CPP/7zip/UI/FileManager/UpdateCallback100.cpp', - 'CPP/7zip/UI/FileManager/ViewSettings.cpp', - 'CPP/7zip/UI/FileManager/wxFM.cpp', - 'CPP/7zip/UI/GUI/HashGUI.cpp', - 'CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CrcReg.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/Lang.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/TextConfig.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Windows/Clipboard.cpp', - 'CPP/Windows/Control/Controls.cpp', - 'CPP/Windows/Control/Dialog.cpp', - 'CPP/Windows/Control/Window2.cpp', - 'CPP/Windows/DLL.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/Registry.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/Windows/Window.cpp', - 'CPP/myWindows/wine_GetXXXDefaultLangID.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7zG.py p7zip-rar-16.02+really25.00+ds/Utils/file_7zG.py --- p7zip-rar-16.02/Utils/file_7zG.py 2015-06-21 18:25:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7zG.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Alloc.c', - 'C/CpuArch.c', - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/UI/Common/ArchiveCommandLine.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/Bench.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/EnumDirItems.cpp', - 'CPP/7zip/UI/Common/Extract.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/HashCalc.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Common/SetProperties.cpp', - 'CPP/7zip/UI/Common/SortUtils.cpp', - 'CPP/7zip/UI/Common/TempFiles.cpp', - 'CPP/7zip/UI/Common/Update.cpp', - 'CPP/7zip/UI/Common/UpdateAction.cpp', - 'CPP/7zip/UI/Common/UpdateCallback.cpp', - 'CPP/7zip/UI/Common/UpdatePair.cpp', - 'CPP/7zip/UI/Common/UpdateProduce.cpp', - 'CPP/7zip/UI/Common/WorkDir.cpp', - 'CPP/7zip/UI/Common/ZipRegistry.cpp', - 'CPP/7zip/UI/Explorer/MyMessages.cpp', - 'CPP/7zip/UI/FileManager/ExtractCallback.cpp', - 'CPP/7zip/UI/FileManager/FormatUtils.cpp', - 'CPP/7zip/UI/FileManager/LangUtils.cpp', - 'CPP/7zip/UI/FileManager/OverwriteDialog.cpp', - 'CPP/7zip/UI/FileManager/OverwriteDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp', - 'CPP/7zip/UI/FileManager/ProgramLocation.cpp', - 'CPP/7zip/UI/FileManager/PropertyName.cpp', - 'CPP/7zip/UI/FileManager/ProgressDialog2.cpp', - 'CPP/7zip/UI/FileManager/ProgressDialog2_rc.cpp', - 'CPP/7zip/UI/FileManager/SplitUtils.cpp', - 'CPP/7zip/UI/FileManager/StringUtils.cpp', - 'CPP/7zip/UI/GUI/BenchmarkDialog.cpp', - 'CPP/7zip/UI/GUI/BenchmarkDialog_rc.cpp', - 'CPP/7zip/UI/GUI/CompressDialog.cpp', - 'CPP/7zip/UI/GUI/CompressDialog_rc.cpp', - 'CPP/7zip/UI/GUI/ExtractDialog.cpp', - 'CPP/7zip/UI/GUI/ExtractDialog_rc.cpp', - 'CPP/7zip/UI/GUI/ExtractGUI.cpp', - 'CPP/7zip/UI/GUI/GUI.cpp', - 'CPP/7zip/UI/GUI/HashGUI.cpp', - 'CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp', - 'CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp', - 'CPP/7zip/UI/GUI/UpdateGUI.cpp', - 'CPP/7zip/UI/GUI/wxGUI.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/Lang.cpp', - 'CPP/Common/ListFileUtils.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Windows/Control/Controls.cpp', - 'CPP/Windows/Control/Dialog.cpp', - 'CPP/Windows/DLL.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/Registry.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/Windows/Window.cpp', - 'CPP/myWindows/wine_GetXXXDefaultLangID.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7z_so.py p7zip-rar-16.02+really25.00+ds/Utils/file_7z_so.py --- p7zip-rar-16.02/Utils/file_7z_so.py 2015-11-06 16:10:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7z_so.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,252 +0,0 @@ - -files_c=[ - 'C/7zBuf2.c', - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/7zStream.c', - 'C/Aes.c', - 'C/Alloc.c', - 'C/Bcj2.c', - 'C/Bcj2Enc.c', - 'C/Blake2s.c', - 'C/Bra.c', - 'C/Bra86.c', - 'C/BraIA64.c', - 'C/BwtSort.c', - 'C/CpuArch.c', - 'C/Delta.c', - 'C/HuffEnc.c', - 'C/LzFind.c', - 'C/LzFindMt.c', - 'C/Lzma2Dec.c', - 'C/Lzma2Enc.c', - 'C/LzmaDec.c', - 'C/LzmaEnc.c', - 'C/MtCoder.c', - 'C/Ppmd7.c', - 'C/Ppmd7Dec.c', - 'C/Ppmd7Enc.c', - 'C/Ppmd8.c', - 'C/Ppmd8Dec.c', - 'C/Ppmd8Enc.c', - 'C/Sha1.c', - 'C/Sha256.c', - 'C/Sort.c', - 'C/Threads.c', - 'C/Xz.c', - 'C/XzCrc64.c', - 'C/XzCrc64Opt.c', - 'C/XzDec.c', - 'C/XzEnc.c', - 'C/XzIn.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/7z/7zCompressionMode.cpp', - 'CPP/7zip/Archive/7z/7zDecode.cpp', - 'CPP/7zip/Archive/7z/7zEncode.cpp', - 'CPP/7zip/Archive/7z/7zExtract.cpp', - 'CPP/7zip/Archive/7z/7zFolderInStream.cpp', - 'CPP/7zip/Archive/7z/7zHandler.cpp', - 'CPP/7zip/Archive/7z/7zHandlerOut.cpp', - 'CPP/7zip/Archive/7z/7zHeader.cpp', - 'CPP/7zip/Archive/7z/7zIn.cpp', - 'CPP/7zip/Archive/7z/7zOut.cpp', - 'CPP/7zip/Archive/7z/7zProperties.cpp', - 'CPP/7zip/Archive/7z/7zRegister.cpp', - 'CPP/7zip/Archive/7z/7zSpecStream.cpp', - 'CPP/7zip/Archive/7z/7zUpdate.cpp', - 'CPP/7zip/Archive/ApmHandler.cpp', - 'CPP/7zip/Archive/ArHandler.cpp', - 'CPP/7zip/Archive/ArchiveExports.cpp', - 'CPP/7zip/Archive/ArjHandler.cpp', - 'CPP/7zip/Archive/Bz2Handler.cpp', - 'CPP/7zip/Archive/Cab/CabBlockInStream.cpp', - 'CPP/7zip/Archive/Cab/CabHandler.cpp', - 'CPP/7zip/Archive/Cab/CabHeader.cpp', - 'CPP/7zip/Archive/Cab/CabIn.cpp', - 'CPP/7zip/Archive/Cab/CabRegister.cpp', - 'CPP/7zip/Archive/Chm/ChmHandler.cpp', - 'CPP/7zip/Archive/Chm/ChmIn.cpp', - 'CPP/7zip/Archive/ComHandler.cpp', - 'CPP/7zip/Archive/Common/CoderMixer2.cpp', - 'CPP/7zip/Archive/Common/DummyOutStream.cpp', - 'CPP/7zip/Archive/Common/FindSignature.cpp', - 'CPP/7zip/Archive/Common/HandlerOut.cpp', - 'CPP/7zip/Archive/Common/InStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/ItemNameUtils.cpp', - 'CPP/7zip/Archive/Common/MultiStream.cpp', - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/OutStreamWithSha1.cpp', - 'CPP/7zip/Archive/Common/ParseProperties.cpp', - 'CPP/7zip/Archive/CpioHandler.cpp', - 'CPP/7zip/Archive/CramfsHandler.cpp', - 'CPP/7zip/Archive/DeflateProps.cpp', - 'CPP/7zip/Archive/DllExports2.cpp', - 'CPP/7zip/Archive/DmgHandler.cpp', - 'CPP/7zip/Archive/ElfHandler.cpp', - 'CPP/7zip/Archive/ExtHandler.cpp', - 'CPP/7zip/Archive/FatHandler.cpp', - 'CPP/7zip/Archive/FlvHandler.cpp', - 'CPP/7zip/Archive/GzHandler.cpp', - 'CPP/7zip/Archive/GptHandler.cpp', - 'CPP/7zip/Archive/HandlerCont.cpp', - 'CPP/7zip/Archive/HfsHandler.cpp', - 'CPP/7zip/Archive/IhexHandler.cpp', - 'CPP/7zip/Archive/Iso/IsoHandler.cpp', - 'CPP/7zip/Archive/Iso/IsoHeader.cpp', - 'CPP/7zip/Archive/Iso/IsoIn.cpp', - 'CPP/7zip/Archive/Iso/IsoRegister.cpp', - 'CPP/7zip/Archive/LzhHandler.cpp', - 'CPP/7zip/Archive/LzmaHandler.cpp', - 'CPP/7zip/Archive/MachoHandler.cpp', - 'CPP/7zip/Archive/MbrHandler.cpp', - 'CPP/7zip/Archive/MslzHandler.cpp', - 'CPP/7zip/Archive/MubHandler.cpp', - 'CPP/7zip/Archive/Nsis/NsisDecode.cpp', - 'CPP/7zip/Archive/Nsis/NsisHandler.cpp', - 'CPP/7zip/Archive/Nsis/NsisIn.cpp', - 'CPP/7zip/Archive/Nsis/NsisRegister.cpp', - 'CPP/7zip/Archive/NtfsHandler.cpp', - 'CPP/7zip/Archive/PeHandler.cpp', - 'CPP/7zip/Archive/PpmdHandler.cpp', - 'CPP/7zip/Archive/QcowHandler.cpp', - 'CPP/7zip/Archive/Rar/RarHandler.cpp', - 'CPP/7zip/Archive/Rar/Rar5Handler.cpp', - 'CPP/7zip/Archive/RpmHandler.cpp', - 'CPP/7zip/Archive/SplitHandler.cpp', - 'CPP/7zip/Archive/SquashfsHandler.cpp', - 'CPP/7zip/Archive/SwfHandler.cpp', - 'CPP/7zip/Archive/Tar/TarHandler.cpp', - 'CPP/7zip/Archive/Tar/TarHandlerOut.cpp', - 'CPP/7zip/Archive/Tar/TarHeader.cpp', - 'CPP/7zip/Archive/Tar/TarIn.cpp', - 'CPP/7zip/Archive/Tar/TarOut.cpp', - 'CPP/7zip/Archive/Tar/TarRegister.cpp', - 'CPP/7zip/Archive/Tar/TarUpdate.cpp', - 'CPP/7zip/Archive/Udf/UdfHandler.cpp', - 'CPP/7zip/Archive/Udf/UdfIn.cpp', - 'CPP/7zip/Archive/UefiHandler.cpp', - 'CPP/7zip/Archive/VdiHandler.cpp', - 'CPP/7zip/Archive/VhdHandler.cpp', - 'CPP/7zip/Archive/VmdkHandler.cpp', - 'CPP/7zip/Archive/Wim/WimHandler.cpp', - 'CPP/7zip/Archive/Wim/WimHandlerOut.cpp', - 'CPP/7zip/Archive/Wim/WimIn.cpp', - 'CPP/7zip/Archive/Wim/WimRegister.cpp', - 'CPP/7zip/Archive/XarHandler.cpp', - 'CPP/7zip/Archive/XzHandler.cpp', - 'CPP/7zip/Archive/ZHandler.cpp', - 'CPP/7zip/Archive/Zip/ZipAddCommon.cpp', - 'CPP/7zip/Archive/Zip/ZipHandler.cpp', - 'CPP/7zip/Archive/Zip/ZipHandlerOut.cpp', - 'CPP/7zip/Archive/Zip/ZipIn.cpp', - 'CPP/7zip/Archive/Zip/ZipItem.cpp', - 'CPP/7zip/Archive/Zip/ZipOut.cpp', - 'CPP/7zip/Archive/Zip/ZipRegister.cpp', - 'CPP/7zip/Archive/Zip/ZipUpdate.cpp', - 'CPP/7zip/Common/CWrappers.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/InBuffer.cpp', - 'CPP/7zip/Common/InOutTempBuffer.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MemBlocks.cpp', - 'CPP/7zip/Common/MethodId.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/OffsetStream.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/OutMemStream.cpp', - 'CPP/7zip/Common/ProgressMt.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamBinder.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Common/VirtThread.cpp', - 'CPP/7zip/Compress/BZip2Crc.cpp', - 'CPP/7zip/Compress/BZip2Decoder.cpp', - 'CPP/7zip/Compress/BZip2Encoder.cpp', - 'CPP/7zip/Compress/BZip2Register.cpp', - 'CPP/7zip/Compress/Bcj2Coder.cpp', - 'CPP/7zip/Compress/Bcj2Register.cpp', - 'CPP/7zip/Compress/BcjCoder.cpp', - 'CPP/7zip/Compress/BcjRegister.cpp', - 'CPP/7zip/Compress/BitlDecoder.cpp', - 'CPP/7zip/Compress/BranchMisc.cpp', - 'CPP/7zip/Compress/BranchRegister.cpp', - 'CPP/7zip/Compress/ByteSwap.cpp', - 'CPP/7zip/Compress/CodecExports.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/Compress/CopyRegister.cpp', - 'CPP/7zip/Compress/Deflate64Register.cpp', - 'CPP/7zip/Compress/DeflateDecoder.cpp', - 'CPP/7zip/Compress/DeflateEncoder.cpp', - 'CPP/7zip/Compress/DeflateRegister.cpp', - 'CPP/7zip/Compress/DeltaFilter.cpp', - 'CPP/7zip/Compress/ImplodeDecoder.cpp', - 'CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp', - 'CPP/7zip/Compress/LzOutWindow.cpp', - 'CPP/7zip/Compress/LzhDecoder.cpp', - 'CPP/7zip/Compress/Lzma2Decoder.cpp', - 'CPP/7zip/Compress/Lzma2Encoder.cpp', - 'CPP/7zip/Compress/Lzma2Register.cpp', - 'CPP/7zip/Compress/LzmaDecoder.cpp', - 'CPP/7zip/Compress/LzmaEncoder.cpp', - 'CPP/7zip/Compress/LzmaRegister.cpp', - 'CPP/7zip/Compress/LzmsDecoder.cpp', - 'CPP/7zip/Compress/LzxDecoder.cpp', - 'CPP/7zip/Compress/PpmdDecoder.cpp', - 'CPP/7zip/Compress/PpmdEncoder.cpp', - 'CPP/7zip/Compress/PpmdRegister.cpp', - 'CPP/7zip/Compress/PpmdZip.cpp', - 'CPP/7zip/Compress/QuantumDecoder.cpp', - 'CPP/7zip/Compress/ShrinkDecoder.cpp', - 'CPP/7zip/Compress/ZDecoder.cpp', - 'CPP/7zip/Compress/XpressDecoder.cpp', - 'CPP/7zip/Compress/ZlibDecoder.cpp', - 'CPP/7zip/Compress/ZlibEncoder.cpp', - 'CPP/7zip/Crypto/7zAes.cpp', - 'CPP/7zip/Crypto/7zAesRegister.cpp', - 'CPP/7zip/Crypto/HmacSha1.cpp', - 'CPP/7zip/Crypto/HmacSha256.cpp', - 'CPP/7zip/Crypto/MyAes.cpp', - 'CPP/7zip/Crypto/MyAesReg.cpp', - 'CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp', - 'CPP/7zip/Crypto/RandGen.cpp', - 'CPP/7zip/Crypto/Rar20Crypto.cpp', - 'CPP/7zip/Crypto/Rar5Aes.cpp', - 'CPP/7zip/Crypto/RarAes.cpp', - 'CPP/7zip/Crypto/WzAes.cpp', - 'CPP/7zip/Crypto/ZipCrypto.cpp', - 'CPP/7zip/Crypto/ZipStrong.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CrcReg.cpp', - 'CPP/Common/DynLimBuf.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/MyMap.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/MyXml.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/Sha1Reg.cpp', - 'CPP/Common/Sha256Reg.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Common/XzCrc64Reg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantUtils.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7za.py p7zip-rar-16.02+really25.00+ds/Utils/file_7za.py --- p7zip-rar-16.02/Utils/file_7za.py 2015-11-06 16:10:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7za.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/7zStream.c', - 'C/Aes.c', - 'C/Alloc.c', - 'C/Bcj2.c', - 'C/Bcj2Enc.c', - 'C/Bra.c', - 'C/Bra86.c', - 'C/BraIA64.c', - 'C/BwtSort.c', - 'C/CpuArch.c', - 'C/Delta.c', - 'C/HuffEnc.c', - 'C/LzFind.c', - 'C/LzFindMt.c', - 'C/Lzma2Dec.c', - 'C/Lzma2Enc.c', - 'C/LzmaDec.c', - 'C/LzmaEnc.c', - 'C/MtCoder.c', - 'C/Ppmd7.c', - 'C/Ppmd7Dec.c', - 'C/Ppmd7Enc.c', - 'C/Ppmd8.c', - 'C/Ppmd8Dec.c', - 'C/Ppmd8Enc.c', - 'C/Sha1.c', - 'C/Sha256.c', - 'C/Sort.c', - 'C/Threads.c', - 'C/Xz.c', - 'C/XzCrc64.c', - 'C/XzCrc64Opt.c', - 'C/XzDec.c', - 'C/XzEnc.c', - 'C/XzIn.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/7z/7zCompressionMode.cpp', - 'CPP/7zip/Archive/7z/7zDecode.cpp', - 'CPP/7zip/Archive/7z/7zEncode.cpp', - 'CPP/7zip/Archive/7z/7zExtract.cpp', - 'CPP/7zip/Archive/7z/7zFolderInStream.cpp', - 'CPP/7zip/Archive/7z/7zHandler.cpp', - 'CPP/7zip/Archive/7z/7zHandlerOut.cpp', - 'CPP/7zip/Archive/7z/7zHeader.cpp', - 'CPP/7zip/Archive/7z/7zIn.cpp', - 'CPP/7zip/Archive/7z/7zOut.cpp', - 'CPP/7zip/Archive/7z/7zProperties.cpp', - 'CPP/7zip/Archive/7z/7zRegister.cpp', - 'CPP/7zip/Archive/7z/7zSpecStream.cpp', - 'CPP/7zip/Archive/7z/7zUpdate.cpp', - 'CPP/7zip/Archive/Bz2Handler.cpp', - 'CPP/7zip/Archive/Cab/CabBlockInStream.cpp', - 'CPP/7zip/Archive/Cab/CabHandler.cpp', - 'CPP/7zip/Archive/Cab/CabHeader.cpp', - 'CPP/7zip/Archive/Cab/CabIn.cpp', - 'CPP/7zip/Archive/Cab/CabRegister.cpp', - 'CPP/7zip/Archive/Common/CoderMixer2.cpp', - 'CPP/7zip/Archive/Common/DummyOutStream.cpp', - 'CPP/7zip/Archive/Common/FindSignature.cpp', - 'CPP/7zip/Archive/Common/HandlerOut.cpp', - 'CPP/7zip/Archive/Common/InStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/ItemNameUtils.cpp', - 'CPP/7zip/Archive/Common/MultiStream.cpp', - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/ParseProperties.cpp', - 'CPP/7zip/Archive/DeflateProps.cpp', - 'CPP/7zip/Archive/GzHandler.cpp', - 'CPP/7zip/Archive/LzmaHandler.cpp', - 'CPP/7zip/Archive/PpmdHandler.cpp', - 'CPP/7zip/Archive/SplitHandler.cpp', - 'CPP/7zip/Archive/Tar/TarHandler.cpp', - 'CPP/7zip/Archive/Tar/TarHandlerOut.cpp', - 'CPP/7zip/Archive/Tar/TarHeader.cpp', - 'CPP/7zip/Archive/Tar/TarIn.cpp', - 'CPP/7zip/Archive/Tar/TarOut.cpp', - 'CPP/7zip/Archive/Tar/TarRegister.cpp', - 'CPP/7zip/Archive/Tar/TarUpdate.cpp', - 'CPP/7zip/Archive/XzHandler.cpp', - 'CPP/7zip/Archive/ZHandler.cpp', - 'CPP/7zip/Archive/Zip/ZipAddCommon.cpp', - 'CPP/7zip/Archive/Zip/ZipHandler.cpp', - 'CPP/7zip/Archive/Zip/ZipHandlerOut.cpp', - 'CPP/7zip/Archive/Zip/ZipIn.cpp', - 'CPP/7zip/Archive/Zip/ZipItem.cpp', - 'CPP/7zip/Archive/Zip/ZipOut.cpp', - 'CPP/7zip/Archive/Zip/ZipRegister.cpp', - 'CPP/7zip/Archive/Zip/ZipUpdate.cpp', - 'CPP/7zip/Common/CWrappers.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/InBuffer.cpp', - 'CPP/7zip/Common/InOutTempBuffer.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MemBlocks.cpp', - 'CPP/7zip/Common/MethodId.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/OffsetStream.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/OutMemStream.cpp', - 'CPP/7zip/Common/ProgressMt.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamBinder.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Common/VirtThread.cpp', - 'CPP/7zip/Compress/BZip2Crc.cpp', - 'CPP/7zip/Compress/BZip2Decoder.cpp', - 'CPP/7zip/Compress/BZip2Encoder.cpp', - 'CPP/7zip/Compress/BZip2Register.cpp', - 'CPP/7zip/Compress/Bcj2Coder.cpp', - 'CPP/7zip/Compress/Bcj2Register.cpp', - 'CPP/7zip/Compress/BcjCoder.cpp', - 'CPP/7zip/Compress/BcjRegister.cpp', - 'CPP/7zip/Compress/BitlDecoder.cpp', - 'CPP/7zip/Compress/BranchMisc.cpp', - 'CPP/7zip/Compress/BranchRegister.cpp', - 'CPP/7zip/Compress/ByteSwap.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/Compress/CopyRegister.cpp', - 'CPP/7zip/Compress/Deflate64Register.cpp', - 'CPP/7zip/Compress/DeflateDecoder.cpp', - 'CPP/7zip/Compress/DeflateEncoder.cpp', - 'CPP/7zip/Compress/DeflateRegister.cpp', - 'CPP/7zip/Compress/DeltaFilter.cpp', - 'CPP/7zip/Compress/ImplodeDecoder.cpp', - 'CPP/7zip/Compress/ImplodeHuffmanDecoder.cpp', - 'CPP/7zip/Compress/LzOutWindow.cpp', - 'CPP/7zip/Compress/Lzma2Decoder.cpp', - 'CPP/7zip/Compress/Lzma2Encoder.cpp', - 'CPP/7zip/Compress/Lzma2Register.cpp', - 'CPP/7zip/Compress/LzmaDecoder.cpp', - 'CPP/7zip/Compress/LzmaEncoder.cpp', - 'CPP/7zip/Compress/LzmaRegister.cpp', - 'CPP/7zip/Compress/LzxDecoder.cpp', - 'CPP/7zip/Compress/PpmdDecoder.cpp', - 'CPP/7zip/Compress/PpmdEncoder.cpp', - 'CPP/7zip/Compress/PpmdRegister.cpp', - 'CPP/7zip/Compress/PpmdZip.cpp', - 'CPP/7zip/Compress/QuantumDecoder.cpp', - 'CPP/7zip/Compress/ShrinkDecoder.cpp', - 'CPP/7zip/Compress/ZDecoder.cpp', - 'CPP/7zip/Crypto/7zAes.cpp', - 'CPP/7zip/Crypto/7zAesRegister.cpp', - 'CPP/7zip/Crypto/HmacSha1.cpp', - 'CPP/7zip/Crypto/MyAes.cpp', - 'CPP/7zip/Crypto/MyAesReg.cpp', - 'CPP/7zip/Crypto/Pbkdf2HmacSha1.cpp', - 'CPP/7zip/Crypto/RandGen.cpp', - 'CPP/7zip/Crypto/WzAes.cpp', - 'CPP/7zip/Crypto/ZipCrypto.cpp', - 'CPP/7zip/Crypto/ZipStrong.cpp', - 'CPP/7zip/UI/Common/ArchiveCommandLine.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/Bench.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/EnumDirItems.cpp', - 'CPP/7zip/UI/Common/Extract.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/HashCalc.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Common/SetProperties.cpp', - 'CPP/7zip/UI/Common/SortUtils.cpp', - 'CPP/7zip/UI/Common/TempFiles.cpp', - 'CPP/7zip/UI/Common/Update.cpp', - 'CPP/7zip/UI/Common/UpdateAction.cpp', - 'CPP/7zip/UI/Common/UpdateCallback.cpp', - 'CPP/7zip/UI/Common/UpdatePair.cpp', - 'CPP/7zip/UI/Common/UpdateProduce.cpp', - 'CPP/7zip/UI/Console/BenchCon.cpp', - 'CPP/7zip/UI/Console/ConsoleClose.cpp', - 'CPP/7zip/UI/Console/ExtractCallbackConsole.cpp', - 'CPP/7zip/UI/Console/HashCon.cpp', - 'CPP/7zip/UI/Console/List.cpp', - 'CPP/7zip/UI/Console/Main.cpp', - 'CPP/7zip/UI/Console/MainAr.cpp', - 'CPP/7zip/UI/Console/OpenCallbackConsole.cpp', - 'CPP/7zip/UI/Console/PercentPrinter.cpp', - 'CPP/7zip/UI/Console/UpdateCallbackConsole.cpp', - 'CPP/7zip/UI/Console/UserInputUtils.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/CrcReg.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/ListFileUtils.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/Sha1Reg.cpp', - 'CPP/Common/Sha256Reg.cpp', - 'CPP/Common/StdInStream.cpp', - 'CPP/Common/StdOutStream.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Common/XzCrc64Reg.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/myWindows/myAddExeFlag.cpp', - 'CPP/myWindows/mySplitCommandLine.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_7zr.py p7zip-rar-16.02+really25.00+ds/Utils/file_7zr.py --- p7zip-rar-16.02/Utils/file_7zr.py 2015-11-06 16:10:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_7zr.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/7zStream.c', - 'C/Alloc.c', - 'C/Bcj2.c', - 'C/Bcj2Enc.c', - 'C/Bra.c', - 'C/Bra86.c', - 'C/BraIA64.c', - 'C/CpuArch.c', - 'C/Delta.c', - 'C/LzFind.c', - 'C/LzFindMt.c', - 'C/Lzma2Dec.c', - 'C/Lzma2Enc.c', - 'C/LzmaDec.c', - 'C/LzmaEnc.c', - 'C/MtCoder.c', - 'C/Sha256.c', - 'C/Threads.c', - 'C/Xz.c', - 'C/XzCrc64.c', - 'C/XzCrc64Opt.c', - 'C/XzDec.c', - 'C/XzEnc.c', - 'C/XzIn.c', -] - -files_cpp=[ - 'CPP/7zip/Archive/7z/7zCompressionMode.cpp', - 'CPP/7zip/Archive/7z/7zDecode.cpp', - 'CPP/7zip/Archive/7z/7zEncode.cpp', - 'CPP/7zip/Archive/7z/7zExtract.cpp', - 'CPP/7zip/Archive/7z/7zFolderInStream.cpp', - 'CPP/7zip/Archive/7z/7zHandler.cpp', - 'CPP/7zip/Archive/7z/7zHandlerOut.cpp', - 'CPP/7zip/Archive/7z/7zHeader.cpp', - 'CPP/7zip/Archive/7z/7zIn.cpp', - 'CPP/7zip/Archive/7z/7zOut.cpp', - 'CPP/7zip/Archive/7z/7zProperties.cpp', - 'CPP/7zip/Archive/7z/7zRegister.cpp', - 'CPP/7zip/Archive/7z/7zSpecStream.cpp', - 'CPP/7zip/Archive/7z/7zUpdate.cpp', - 'CPP/7zip/Archive/Common/CoderMixer2.cpp', - 'CPP/7zip/Archive/Common/DummyOutStream.cpp', - 'CPP/7zip/Archive/Common/HandlerOut.cpp', - 'CPP/7zip/Archive/Common/InStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/ItemNameUtils.cpp', - 'CPP/7zip/Archive/Common/MultiStream.cpp', - 'CPP/7zip/Archive/Common/OutStreamWithCRC.cpp', - 'CPP/7zip/Archive/Common/ParseProperties.cpp', - 'CPP/7zip/Archive/LzmaHandler.cpp', - 'CPP/7zip/Archive/SplitHandler.cpp', - 'CPP/7zip/Archive/XzHandler.cpp', - 'CPP/7zip/Common/CWrappers.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FilePathAutoRename.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/InBuffer.cpp', - 'CPP/7zip/Common/InOutTempBuffer.cpp', - 'CPP/7zip/Common/LimitedStreams.cpp', - 'CPP/7zip/Common/MethodId.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/OffsetStream.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/ProgressUtils.cpp', - 'CPP/7zip/Common/PropId.cpp', - 'CPP/7zip/Common/StreamBinder.cpp', - 'CPP/7zip/Common/StreamObjects.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Common/UniqBlocks.cpp', - 'CPP/7zip/Common/VirtThread.cpp', - 'CPP/7zip/Compress/Bcj2Coder.cpp', - 'CPP/7zip/Compress/Bcj2Register.cpp', - 'CPP/7zip/Compress/BcjCoder.cpp', - 'CPP/7zip/Compress/BcjRegister.cpp', - 'CPP/7zip/Compress/BranchMisc.cpp', - 'CPP/7zip/Compress/BranchRegister.cpp', - 'CPP/7zip/Compress/ByteSwap.cpp', - 'CPP/7zip/Compress/CopyCoder.cpp', - 'CPP/7zip/Compress/CopyRegister.cpp', - 'CPP/7zip/Compress/DeltaFilter.cpp', - 'CPP/7zip/Compress/Lzma2Decoder.cpp', - 'CPP/7zip/Compress/Lzma2Encoder.cpp', - 'CPP/7zip/Compress/Lzma2Register.cpp', - 'CPP/7zip/Compress/LzmaDecoder.cpp', - 'CPP/7zip/Compress/LzmaEncoder.cpp', - 'CPP/7zip/Compress/LzmaRegister.cpp', - 'CPP/7zip/UI/Common/ArchiveCommandLine.cpp', - 'CPP/7zip/UI/Common/ArchiveExtractCallback.cpp', - 'CPP/7zip/UI/Common/ArchiveOpenCallback.cpp', - 'CPP/7zip/UI/Common/Bench.cpp', - 'CPP/7zip/UI/Common/DefaultName.cpp', - 'CPP/7zip/UI/Common/EnumDirItems.cpp', - 'CPP/7zip/UI/Common/Extract.cpp', - 'CPP/7zip/UI/Common/ExtractingFilePath.cpp', - 'CPP/7zip/UI/Common/HashCalc.cpp', - 'CPP/7zip/UI/Common/LoadCodecs.cpp', - 'CPP/7zip/UI/Common/OpenArchive.cpp', - 'CPP/7zip/UI/Common/PropIDUtils.cpp', - 'CPP/7zip/UI/Common/SetProperties.cpp', - 'CPP/7zip/UI/Common/SortUtils.cpp', - 'CPP/7zip/UI/Common/TempFiles.cpp', - 'CPP/7zip/UI/Common/Update.cpp', - 'CPP/7zip/UI/Common/UpdateAction.cpp', - 'CPP/7zip/UI/Common/UpdateCallback.cpp', - 'CPP/7zip/UI/Common/UpdatePair.cpp', - 'CPP/7zip/UI/Common/UpdateProduce.cpp', - 'CPP/7zip/UI/Console/BenchCon.cpp', - 'CPP/7zip/UI/Console/ConsoleClose.cpp', - 'CPP/7zip/UI/Console/ExtractCallbackConsole.cpp', - 'CPP/7zip/UI/Console/HashCon.cpp', - 'CPP/7zip/UI/Console/List.cpp', - 'CPP/7zip/UI/Console/Main.cpp', - 'CPP/7zip/UI/Console/MainAr.cpp', - 'CPP/7zip/UI/Console/OpenCallbackConsole.cpp', - 'CPP/7zip/UI/Console/PercentPrinter.cpp', - 'CPP/7zip/UI/Console/UpdateCallbackConsole.cpp', - 'CPP/7zip/UI/Console/UserInputUtils.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/CrcReg.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/ListFileUtils.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/Sha256Reg.cpp', - 'CPP/Common/StdInStream.cpp', - 'CPP/Common/StdOutStream.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Common/XzCrc64Reg.cpp', - 'CPP/Windows/ErrorMsg.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/Windows/Synchronization.cpp', - 'CPP/Windows/System.cpp', - 'CPP/Windows/TimeUtils.cpp', - 'CPP/myWindows/myAddExeFlag.cpp', - 'CPP/myWindows/mySplitCommandLine.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_Client7z.py p7zip-rar-16.02+really25.00+ds/Utils/file_Client7z.py --- p7zip-rar-16.02/Utils/file_Client7z.py 2015-01-27 19:40:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_Client7z.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -files_c=[ - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/UI/Client7z/Client7z.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/UTFConvert.cpp', - 'CPP/Common/Wildcard.cpp', - 'CPP/Windows/DLL.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/PropVariantConv.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_Codecs_Lzham_so.py p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Lzham_so.py --- p7zip-rar-16.02/Utils/file_Codecs_Lzham_so.py 2016-02-03 05:35:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Lzham_so.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - -files_c=[ - 'C/Alloc.c', -] - -files_cpp=[ - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Compress/CodecExports.cpp', - 'CPP/7zip/Compress/DllExportsCompress.cpp', - 'CPP/7zip/Compress/Lzham/LzhamRegister.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Windows/System.cpp', - - # lzhamcomp - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzbase.cpp', - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp.cpp', - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_internal.cpp', - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_lzcomp_state.cpp', - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_match_accel.cpp', - 'CPP/7zip/Compress/Lzham/lzhamcomp/lzham_pthreads_threading.cpp', - - # lzhamdecomp - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_assert.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_checksum.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_huffman_codes.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecomp.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_lzdecompbase.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_mem.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_platform.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_prefix_coding.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_symbol_codec.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_timer.cpp', - 'CPP/7zip/Compress/Lzham/lzhamdecomp/lzham_vector.cpp', - - # lzhamlib - 'CPP/7zip/Compress/Lzham/lzhamlib/lzham_lib.cpp', -] - - diff -Nru p7zip-rar-16.02/Utils/file_Codecs_Rar_so.py p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Rar_so.py --- p7zip-rar-16.02/Utils/file_Codecs_Rar_so.py 2015-09-01 18:14:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_Codecs_Rar_so.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Alloc.c', - 'C/CpuArch.c', - 'C/Ppmd7.c', - 'C/Ppmd7Dec.c', -] - -files_cpp=[ - 'CPP/7zip/Common/InBuffer.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Compress/CodecExports.cpp', - 'CPP/7zip/Compress/DllExportsCompress.cpp', - 'CPP/7zip/Compress/LzOutWindow.cpp', - 'CPP/7zip/Compress/Rar1Decoder.cpp', - 'CPP/7zip/Compress/Rar2Decoder.cpp', - 'CPP/7zip/Compress/Rar3Decoder.cpp', - 'CPP/7zip/Compress/Rar3Vm.cpp', - 'CPP/7zip/Compress/Rar5Decoder.cpp', - 'CPP/7zip/Compress/RarCodecsRegister.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_LzmaCon.py p7zip-rar-16.02+really25.00+ds/Utils/file_LzmaCon.py --- p7zip-rar-16.02/Utils/file_LzmaCon.py 2015-06-19 18:09:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_LzmaCon.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ - -files_c=[ - 'C/7zCrc.c', - 'C/7zCrcOpt.c', - 'C/Alloc.c', - 'C/Bra86.c', - 'C/CpuArch.c', - 'C/LzFind.c', - 'C/LzFindMt.c', - 'C/LzmaDec.c', - 'C/LzmaEnc.c', - 'C/Lzma86Dec.c', - 'C/Lzma86Enc.c', - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp', - 'CPP/7zip/Common/CWrappers.cpp', - 'CPP/7zip/Common/CreateCoder.cpp', - 'CPP/7zip/Common/FileStreams.cpp', - 'CPP/7zip/Common/FilterCoder.cpp', - 'CPP/7zip/Common/MethodProps.cpp', - 'CPP/7zip/Common/OutBuffer.cpp', - 'CPP/7zip/Common/StreamUtils.cpp', - 'CPP/7zip/Compress/LzmaDecoder.cpp', - 'CPP/7zip/Compress/LzmaEncoder.cpp', - 'CPP/7zip/Compress/LzmaRegister.cpp', - 'CPP/7zip/UI/Common/Bench.cpp', - 'CPP/7zip/UI/Console/BenchCon.cpp', - 'CPP/7zip/UI/Console/ConsoleClose.cpp', - 'CPP/Common/CRC.cpp', - 'CPP/Common/CommandLineParser.cpp', - 'CPP/Common/CrcReg.cpp', - 'CPP/Common/C_FileIO.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Common/NewHandler.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Common/StringToInt.cpp', - 'CPP/Windows/PropVariant.cpp', - 'CPP/Windows/System.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - -# 'CPP/Windows/FileIO.cpp', - diff -Nru p7zip-rar-16.02/Utils/file_P7ZIP.py p7zip-rar-16.02+really25.00+ds/Utils/file_P7ZIP.py --- p7zip-rar-16.02/Utils/file_P7ZIP.py 2015-10-03 20:54:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_P7ZIP.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ - -files_c=[ - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/UI/P7ZIP/wxP7ZIP.cpp', - 'CPP/Common/IntToString.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyVector.cpp', - 'CPP/Common/StringConvert.cpp', - 'CPP/Windows/FileDir.cpp', - 'CPP/Windows/FileFind.cpp', - 'CPP/Windows/FileIO.cpp', - 'CPP/Windows/FileName.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/myWindows/wine_date_and_time.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/file_TestUI.py p7zip-rar-16.02+really25.00+ds/Utils/file_TestUI.py --- p7zip-rar-16.02/Utils/file_TestUI.py 2015-10-03 20:56:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/file_TestUI.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ - -files_c=[ - 'C/Threads.c', -] - -files_cpp=[ - 'CPP/7zip/TEST/TestUI/TestUI.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog.cpp', - 'CPP/7zip/UI/FileManager/PasswordDialog_rc.cpp', - 'CPP/Common/MyString.cpp', - 'CPP/Common/MyWindows.cpp', - 'CPP/Windows/Control/Controls.cpp', - 'CPP/Windows/Control/Dialog.cpp', - 'CPP/Windows/Window.cpp', -] - diff -Nru p7zip-rar-16.02/Utils/generate.py p7zip-rar-16.02+really25.00+ds/Utils/generate.py --- p7zip-rar-16.02/Utils/generate.py 2016-03-10 07:27:01.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/Utils/generate.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,801 +0,0 @@ -#!/usr/bin/env python - -import os -import sys - -class Structure: - def __init__(self, **kwds): - self.__dict__.update(kwds) - -TYPE_EXE=0 -TYPE_DLL=1 - -def generate_pro(filename,project): - - if os.path.isfile(filename): - os.remove(filename) - - f=open(filename,'w') - f.write(''' -# WARNING : automatically generated by utils/generate.py - -QT -= core gui -TARGET = ''' + project.name + ''' -''') - if project.type == TYPE_EXE: - f.write(''' -CONFIG += console -CONFIG -= app_bundle -TEMPLATE = app -''') - if project.type == TYPE_DLL: - f.write(''' -CONFIG += dll -TEMPLATE = lib -''') - - f.write(''' -DESTDIR = ../../../../bin - -unix: LIBS += -ldl - -DEFINES+=USE_LIB7Z_DLL - -''') - f.write('INCLUDEPATH = \\\n') - for file in project.includedirs: - f.write(" {} \\\n".format(file)) - f.write('\n') - for d in project.defines: - f.write("DEFINES += " + d + '\n') - f.write('\n') - f.write('SOURCES += \\\n') - for file in project.files_c: - f.write(" ../../../../{} \\\n".format(file)) - for file in project.files_cpp: - f.write(" ../../../../{} \\\n".format(file)) - - f.write(''' -macx: LIBS += -framework CoreFoundation -''') - f.write('\n') - f.close() - -premake4_headers=''' --- WARNING : automatically generated by utils/generate.py -solution "p7zip" - configurations { "Debug", "Release" } - --- includes for all projects - includedirs { -''' - -def generate_premake4(filename,project): - - if os.path.isfile(filename): - os.remove(filename) - - f=open(filename,'w') - f.write(premake4_headers) - for file in project.includedirs: - f.write(' "{}",\n'.format(file)) - f.write(' }\n\n') - defines="" - for d in project.defines: - defines+= ', "' + d + '"' - f.write(' configuration "Debug"\n') - f.write(' defines { "DEBUG"' + defines + ' }\n') - f.write(' flags { "Symbols" }\n') - f.write('\n') - f.write(' configuration "Release"\n') - f.write(' defines { "NDEBUG"' + defines + ' }\n') - f.write(' flags { "Optimize" } \n') - f.write('\n') - f.write(' project "all_c_code"\n') - f.write(' kind "StaticLib"\n') - f.write(' language "C"\n') - f.write(' files {\n') - for file in project.files_c: - f.write(' "../../../../{}",\n'.format(file)) - f.write(''' } - ---------------------------------- - project "''' + project.name + '''" - kind "ConsoleApp" - language "C++" - files { -''') - for file in project.files_cpp: - f.write(' "../../../../{}",\n'.format(file)) - f.write(''' - } - - configuration "linux" - links { "all_c_code", "pthread" } -''') - - f.close() - -def generate_cmake(filename,project): - - if os.path.isfile(filename): - os.remove(filename) - - f=open(filename,'w') - f.write(''' - -# WARNING : automatically generated by utils/generate.py -cmake_minimum_required(VERSION 2.8) - -''') - f.write('include_directories(\n') - for file in project.includedirs: - f.write(' "{}"\n'.format(file)) - f.write(')\n\n') - defines="" - for d in project.defines: - defines+= ' -D' + d - f.write('add_definitions(' + defines + ')\n') - f.write(''' -IF(APPLE) - add_definitions(-DENV_MACOSX) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation ) -ENDIF(APPLE) - -''') - if project.type == TYPE_EXE: - f.write('add_executable(' + project.name2 + '\n\n') - if project.type == TYPE_DLL: - f.write('add_library(' + project.name2 + ' MODULE\n\n') - for file in project.files_c: - f.write(' "../../../../{}"\n'.format(file)) - for file in project.files_cpp: - f.write(' "../../../../{}"\n'.format(file)) - f.write(')\n') - f.write(project.cmake_end) - f.close() - -def to_obj(file): - file2=os.path.basename(file) - return os.path.splitext(file2)[0] + '.o' - -def generate_makefile_list(filename,project,bin_dir='../../../../bin'): - - if os.path.isfile(filename): - os.remove(filename) - - f=open(filename,'w') - f.write(''' - -# WARNING : automatically generated by utils/generate.py - -''') - if project.type == TYPE_EXE: - f.write('PROG={}/{}$(BINSUFFIX)\n\n'.format(bin_dir,project.name)) - if project.type == TYPE_DLL: - f.write('PROG={}/{}.so\n\n'.format(bin_dir,project.name)) - - f.write('all: $(PCH_NAME) $(PROG)\n\n') - - f.write('LOCAL_FLAGS=$(TARGET_FLAGS) \\\n') - for d in project.defines: - f.write(' -D{} \\\n'.format(d)) - f.write('\n') - f.write('SRCS=\\\n') - for file in project.files_cpp: - f.write(' ../../../../{} \\\n'.format(file)) - f.write('\n') - f.write('SRCS_C=\\\n') - for file in project.files_c: - f.write(' ../../../../{} \\\n'.format(file)) - f.write(''' -StdAfx.h.gch : ../../../myWindows/StdAfx.h -\trm -f StdAfx.h.gch -\t$(CXX) $(CXXFLAGS) ../../../myWindows/StdAfx.h -o StdAfx.h.gch -''') - - for file in project.files_c: - file='../../../../' + file - f.write('{} : {}\n'.format(to_obj(file),file)) - f.write('\t$(CC) $(CFLAGS) {}\n'.format(file)) - for file in project.files_cpp: - file='../../../../' + file - f.write('{} : {}\n'.format(to_obj(file),file)) - f.write('\t$(CXX) $(CXXFLAGS) {}\n'.format(file)) - - f.write('\nOBJS=\\\n') - for file in project.files_c: - file=to_obj(file) - if file == '7zCrcOpt.o': - f.write(' $(OBJ_CRC32) \\\n') - else: - f.write(' {} \\\n'.format(file)) - for file in project.files_cpp: - f.write(' {} \\\n'.format(to_obj(file))) - if project.need_AES: - f.write(' $(OBJ_AES) \\\n') - - f.write('\n') - - - f.close() - -def generate_android_mk(filename,project): - - if os.path.isfile(filename): - os.remove(filename) - - f=open(filename,'w') - f.write('''# -# build {} for armeabi and armeabi-v7a CPU -# -# WARNING : file generated by generate.py -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := {} -'''.format(project.name,project.name)) - f.write(project.android_header) - f.write('LOCAL_SRC_FILES := \\\n') - for file in project.files_cpp: - f.write(' ../../../../{} \\\n'.format(file)) - for file in project.files_c: - f.write(' ../../../../{} \\\n'.format(file)) - - f.write('\n') - if project.type == TYPE_EXE: - f.write('# Needed since ANDROID 5, these programs run on android-16 (Android 4.1+)\n') - f.write('LOCAL_CFLAGS += -fPIE\n') - f.write('LOCAL_LDFLAGS += -fPIE -pie\n') - f.write('\n') - f.write('include $(BUILD_EXECUTABLE)\n\n') - if project.type == TYPE_DLL: - # nothing to do here - f.write('include $(BUILD_SHARED_LIBRARY)\n\n') - f.close() - -includedirs_7za=[ - "../../../myWindows", - "../../../", - "../../../include_windows" -] - - -includedirs_lzham=[ # FIXME - "../../../../CPP/7zip/Compress/Lzham/include", - "../../../../CPP/7zip/Compress/Lzham/lzhamcomp", - "../../../../CPP/7zip/Compress/Lzham/lzhamdecomp", - "../../../myWindows", - "../../../", - "../../../../", - "../../../include_windows" -] - -import file_7za -import file_7zCon_sfx -import file_7z -import file_7zr -import file_7zG -import file_7zFM -import file_7z_so -import file_Codecs_Rar_so -import file_Codecs_Lzham_so -import file_LzmaCon -import file_Client7z -import file_P7ZIP -import file_TestUI - - -project_7za=Structure(name="7za",name2="7za", - type=TYPE_EXE, - need_AES=True, - includedirs=includedirs_7za, - defines=[ "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7za.files_c, - files_cpp=file_7za.files_cpp, - cmake_end=''' - -IF(APPLE) - TARGET_LINK_LIBRARIES(7za ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7za ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../7zip/Archive \ - -I../../../7zip/Archive/7z \ - -I../../../7zip/Archive/BZip2 \ - -I../../../7zip/Archive/Common \ - -I../../../7zip/Archive/GZip \ - -I../../../7zip/Archive/Cab \ - -I../../../7zip/Archive/Lzma \ - -I../../../7zip/Archive/Tar \ - -I../../../7zip/Archive/Zip \ - -I../../../7zip/Archive/Split \ - -I../../../7zip/Archive/Z \ - -I../../../7zip/Compress \ - -I../../../7zip/Crypto \ - -I../../../7zip/UI/Console \ - -I../../../7zip/UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -''') - -project_7zr=Structure(name="7zr",name2="7zr", - type=TYPE_EXE, - need_AES=True, - includedirs=includedirs_7za, - defines=[ "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "_NO_CRYPTO", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7zr.files_c, - files_cpp=file_7zr.files_cpp, - cmake_end=''' - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zr ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zr ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DBREAK_HANDLER -D_NO_CRYPTO \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../7zip/Archive \ - -I../../../7zip/Archive/7z \ - -I../../../7zip/Archive/BZip2 \ - -I../../../7zip/Archive/Common \ - -I../../../7zip/Archive/GZip \ - -I../../../7zip/Archive/Cab \ - -I../../../7zip/Archive/Lzma \ - -I../../../7zip/Archive/Tar \ - -I../../../7zip/Archive/Zip \ - -I../../../7zip/Archive/Split \ - -I../../../7zip/Archive/Z \ - -I../../../7zip/Compress \ - -I../../../7zip/Crypto \ - -I../../../7zip/UI/Console \ - -I../../../7zip/UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -''') - -project_7zCon_sfx=Structure(name="7zCon.sfx",name2="7zCon.sfx", - type=TYPE_EXE, - need_AES=True, - includedirs=includedirs_7za, - defines=[ "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE", "EXTRACT_ONLY", "NO_READ_FROM_CODER", "_SFX" ], - files_c=file_7zCon_sfx.files_c, - files_cpp=file_7zCon_sfx.files_cpp, - cmake_end=''' - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zCon.sfx ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zCon.sfx ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''') - -project_7z=Structure(name="7z",name2="7z_", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7z.files_c, - files_cpp=file_7z.files_cpp, - cmake_end=''' - -find_library(DL_LIB dl) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7z_ ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7z_ ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows -''') - -project_Codecs_Rar=Structure(name="Rar",name2="Rar", - type=TYPE_DLL, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_Codecs_Rar_so.files_c, - files_cpp=file_Codecs_Rar_so.files_cpp, - cmake_end=''' - -find_library(DL_LIB dl) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(Rar ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(Rar ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows -''') - - - -project_Codecs_Lzham=Structure(name="Lzham",name2="Lzham", - type=TYPE_DLL, - need_AES=False, - includedirs=includedirs_lzham, - defines=[ "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_Codecs_Lzham_so.files_c, - files_cpp=file_Codecs_Lzham_so.files_cpp, - cmake_end=''' - -find_library(DL_LIB dl) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(Lzham ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(Lzham ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows \ --I../../../../CPP/7zip/Compress/Lzham/include \ --I../../../../CPP/7zip/Compress/Lzham/lzhamcomp \ --I../../../../CPP/7zip/Compress/Lzham/lzhamdecomp - -''') - - -project_7zG=Structure(name="7zG",name2="7zG", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "LANG", "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7zG.files_c, - files_cpp=file_7zG.files_cpp, - cmake_end=''' - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zG ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zG ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''') - -project_7zFM=Structure(name="7zFM_do_not_use",name2="7zFM_do_not_use", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "LANG", "NEW_FOLDER_INTERFACE", "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7zFM.files_c, - files_cpp=file_7zFM.files_cpp, - cmake_end=''' - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(7zFM_do_not_use ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7zFM_do_not_use ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''') - -project_Format7zFree=Structure(name="7z",name2="7z", - type=TYPE_DLL, - need_AES=True, - includedirs=includedirs_7za, - defines=[ "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_7z_so.files_c, - files_cpp=file_7z_so.files_cpp, - cmake_end=''' - -SET_TARGET_PROPERTIES(7z PROPERTIES PREFIX "") - -IF(APPLE) - TARGET_LINK_LIBRARIES(7z ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(7z ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ - -I../../../myWindows \ - -I../../../ \ - -I../../../include_windows - -''') - -project_LzmaCon=Structure(name="LzmaCon",name2="LzmaCon", - type=TYPE_EXE, - need_AES=True, - includedirs=includedirs_7za, - defines=[ "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX" ], - files_c=file_LzmaCon.files_c, - files_cpp=file_LzmaCon.files_cpp, - cmake_end=''' - -IF(APPLE) - TARGET_LINK_LIBRARIES(LzmaCon ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(LzmaCon ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -I../../../7zip/Archive \ - -I../../../7zip/Archive/7z \ - -I../../../7zip/Archive/BZip2 \ - -I../../../7zip/Archive/Common \ - -I../../../7zip/Archive/GZip \ - -I../../../7zip/Archive/Cab \ - -I../../../7zip/Archive/Lzma \ - -I../../../7zip/Archive/Tar \ - -I../../../7zip/Archive/Zip \ - -I../../../7zip/Archive/Split \ - -I../../../7zip/Archive/Z \ - -I../../../7zip/Compress \ - -I../../../7zip/Crypto \ - -I../../../7zip/UI/Console \ - -I../../../7zip/UI/Common \ - -I../../../Windows \ - -I../../../Common \ - -I../../../7zip/Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows - -''') - -project_Client7z=Structure(name="Client7z",name2="Client7z", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_Client7z.files_c, - files_cpp=file_Client7z.files_cpp, - cmake_end=''' - -find_library(DL_LIB dl) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(Client7z ${COREFOUNDATION_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(Client7z ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''', -android_header=r''' -LOCAL_CFLAGS := -DANDROID_NDK -fexceptions \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -DEXTERNAL_CODECS \ - -DBREAK_HANDLER \ - -DUNICODE -D_UNICODE -DUNIX_USE_WIN_FILE \ - -I../../../Windows \ - -I../../../Common \ - -I../../../../C \ --I../../../myWindows \ --I../../../ \ --I../../../include_windows -''') - -project_P7ZIP=Structure(name="P7ZIP",name2="P7ZIP", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "LANG", "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_P7ZIP.files_c, - files_cpp=file_P7ZIP.files_cpp, - cmake_end=''' - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(P7ZIP ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(P7ZIP ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''') - -project_TestUI=Structure(name="TestUI",name2="TestUI", - type=TYPE_EXE, - need_AES=False, - includedirs=includedirs_7za, - defines=[ "LANG", "EXTERNAL_CODECS", "_FILE_OFFSET_BITS=64", "_LARGEFILE_SOURCE", "_REENTRANT", "ENV_UNIX", "BREAK_HANDLER", "UNICODE", "_UNICODE", "UNIX_USE_WIN_FILE" ], - files_c=file_TestUI.files_c, - files_cpp=file_TestUI.files_cpp, - cmake_end=''' - -IF(APPLE) - add_definitions(-DENV_MACOSX -D__WXMAC__) -ENDIF(APPLE) - -find_package(wxWidgets COMPONENTS core base adv REQUIRED) - -find_library(DL_LIB dl) - -include( ${wxWidgets_USE_FILE} ) - -link_directories(${DL_LIB_PATH}) - -IF(APPLE) - TARGET_LINK_LIBRARIES(TestUI ${COREFOUNDATION_LIBRARY} ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -ELSE(APPLE) - IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(TestUI ${wxWidgets_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} dl) - ENDIF(HAVE_PTHREADS) -ENDIF(APPLE) - -''') -generate_makefile_list('../CPP/7zip/Bundles/Alone/makefile.list',project_7za) -generate_makefile_list('../CPP/7zip/Bundles/Alone7z/makefile.list',project_7zr) -generate_makefile_list('../CPP/7zip/UI/Console/makefile.list',project_7z) -generate_makefile_list('../CPP/7zip/Bundles/Format7zFree/makefile.list',project_Format7zFree) -generate_makefile_list('../CPP/7zip/Compress/Rar/makefile.list',project_Codecs_Rar,'../../../../bin/Codecs') -generate_makefile_list('../CPP/7zip/Compress/Lzham/makefile.list',project_Codecs_Lzham,'../../../../bin/Codecs') -generate_makefile_list('../CPP/7zip/Bundles/SFXCon/makefile.list',project_7zCon_sfx) -generate_makefile_list('../CPP/7zip/UI/GUI/makefile.list',project_7zG) -generate_makefile_list('../CPP/7zip/UI/FileManager/makefile.list',project_7zFM) -generate_makefile_list('../CPP/7zip/Bundles/LzmaCon/makefile.list',project_LzmaCon) -generate_makefile_list('../CPP/7zip/UI/Client7z/makefile.list',project_Client7z) -generate_makefile_list('../CPP/7zip/UI/P7ZIP/makefile.list',project_P7ZIP) -generate_makefile_list('../CPP/7zip/TEST/TestUI/makefile.list',project_TestUI) - -generate_pro('../CPP/7zip/QMAKE/7za/7za.pro',project_7za) -generate_pro('../CPP/7zip/QMAKE/7zr/7zr.pro',project_7zr) -generate_pro('../CPP/7zip/QMAKE/7z_/7z_.pro',project_7z) -generate_pro('../CPP/7zip/QMAKE/Format7zFree/Format7zFree.pro',project_Format7zFree) -generate_pro('../CPP/7zip/QMAKE/Rar/Rar.pro',project_Codecs_Rar) -generate_pro('../CPP/7zip/QMAKE/Lzham/Lzham.pro',project_Codecs_Lzham) - -generate_premake4('../CPP/7zip/PREMAKE/premake4.lua',project_7za) - -generate_cmake('../CPP/7zip/CMAKE/7za/CMakeLists.txt',project_7za) -generate_cmake('../CPP/7zip/CMAKE/7z_/CMakeLists.txt',project_7z) -generate_cmake('../CPP/7zip/CMAKE/7zG/CMakeLists.txt',project_7zG) -generate_cmake('../CPP/7zip/CMAKE/7zFM/CMakeLists.txt',project_7zFM) -generate_cmake('../CPP/7zip/CMAKE/7zr/CMakeLists.txt',project_7zr) -generate_cmake('../CPP/7zip/CMAKE/Format7zFree/CMakeLists.txt',project_Format7zFree) - - -generate_android_mk('../CPP/ANDROID/7za/jni/Android.mk',project_7za) -generate_android_mk('../CPP/ANDROID/7zr/jni/Android.mk',project_7zr) -generate_android_mk('../CPP/ANDROID/7z/jni/Android.mk',project_7z) -generate_android_mk('../CPP/ANDROID/Format7zFree/jni/Android.mk',project_Format7zFree) -generate_android_mk('../CPP/ANDROID/Lzham/jni/Android.mk',project_Codecs_Lzham) - - -#FIXME:7zr-CPP/7zip/Bundles/Alone7z - - diff -Nru p7zip-rar-16.02/check/check.sh p7zip-rar-16.02+really25.00+ds/check/check.sh --- p7zip-rar-16.02/check/check.sh 2015-10-20 18:47:50.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/check/check.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -#! /bin/sh - -sure() -{ - eval $* - if [ "$?" != "0" ] - then - echo "ERROR during : $*" - echo "ERROR during : $*" > last_error - exit 1 - fi -} - -#set -x - -P7ZIP="$@" -P7ZIP="${TOOLS} ${P7ZIP}" - -REP=TMP_$$ -echo "REP=${REP}" -echo "P7ZIP=${P7ZIP}" -echo "TOOLS=${TOOLS}" - -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} -mkdir -p ${REP} - -cd ${REP} - -# sure rm -fr 7za433_ref 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar -# sure rm -fr 7za433_7zip_bzip2.7z 7za433_7zip_lzma.7z 7za433_7zip_lzma_crypto.7z 7za433_7zip_ppmd.7z 7za433_tar.tar - -echo "" -echo "# TESTING ..." -echo "#############" - -sure ${P7ZIP} t ../test/7za433_tar.tar -sure ${P7ZIP} t ../test/7za433_7zip_lzma.7z -sure ${P7ZIP} t -pqwerty ../test/7za433_7zip_lzma_crypto.7z -sure ${P7ZIP} t ../test/7za433_7zip_ppmd.7z -sure ${P7ZIP} t ../test/7za433_7zip_bzip2.7z - -echo "" -echo "# EXTRACTING ..." -echo "################" - -sure tar xf ../test/7za433_tar.tar -sure mv 7za433_tar 7za433_ref - -sure ${P7ZIP} x ../test/7za433_tar.tar -sure diff -r 7za433_ref 7za433_tar - -sure ${P7ZIP} x ../test/7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -sure ${P7ZIP} x ../test/7za433_7zip_lzma_bcj2.7z -sure diff -r 7za433_ref 7za433_7zip_lzma_bcj2 - -sure ${P7ZIP} x -pqwerty ../test/7za433_7zip_lzma_crypto.7z -sure diff -r 7za433_ref 7za433_7zip_lzma_crypto - -sure ${P7ZIP} x ../test/7za433_7zip_ppmd.7z -sure diff -r 7za433_ref 7za433_7zip_ppmd - -sure ${P7ZIP} x ../test/7za433_7zip_ppmd_bcj2.7z -sure diff -r 7za433_ref 7za433_7zip_ppmd_bcj2 - -sure ${P7ZIP} x ../test/7za433_7zip_bzip2.7z -sure diff -r 7za433_ref 7za433_7zip_bzip2 - -sure ${P7ZIP} x ../test/7za433_7zip_lzma2.7z -sure diff -r 7za433_ref 7za433_7zip_lzma2 - -sure ${P7ZIP} x ../test/7za433_7zip_lzma2_bcj2.7z -sure diff -r 7za433_ref 7za433_7zip_lzma2_bcj2 - -sure ${P7ZIP} x -pqwerty ../test/7za433_7zip_lzma2_crypto.7z -sure diff -r 7za433_ref 7za433_7zip_lzma2_crypto - -echo "" -echo "# Archiving ..." -echo "###############" - -sure ${P7ZIP} a -ttar 7za433_tar.tar 7za433_tar -sure tar tvf 7za433_tar.tar - -sure ${P7ZIP} a 7za433_7zip_lzma.7z 7za433_7zip_lzma - -sure ${P7ZIP} a -sfx7zCon.sfx 7za433_7zip_lzma.x 7za433_7zip_lzma - -sure ${P7ZIP} a -pqwerty -mhc=on -mhe=on 7za433_7zip_lzma_crypto.7z 7za433_7zip_lzma_crypto - -sure ${P7ZIP} a -mx=9 -m0=ppmd:mem=64m:o=32 7za433_7zip_ppmd.7z 7za433_7zip_ppmd - -sure ${P7ZIP} a -m0=bzip2 7za433_7zip_bzip2.7z 7za433_7zip_bzip2 - -echo "" -echo "# EXTRACTING (PASS 2) ..." -echo "#########################" - -sure rm -fr 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar - -sure ${P7ZIP} x 7za433_tar.tar -sure diff -r 7za433_ref 7za433_tar - -sure ${P7ZIP} x 7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -sure rm -fr 7za433_7zip_lzma -# FIXME - only for 7zG -sure chmod +x ./7za433_7zip_lzma.x -sure ${TOOLS} ./7za433_7zip_lzma.x -sure diff -r 7za433_ref 7za433_7zip_lzma - -sure ${P7ZIP} x -pqwerty 7za433_7zip_lzma_crypto.7z -sure diff -r 7za433_ref 7za433_7zip_lzma_crypto - -sure ${P7ZIP} x 7za433_7zip_ppmd.7z -sure diff -r 7za433_ref 7za433_7zip_ppmd - -sure ${P7ZIP} x 7za433_7zip_bzip2.7z -sure diff -r 7za433_ref 7za433_7zip_bzip2 - -echo "" -echo "# EXTRACTING (LZMA) ..." -echo "#######################" - -rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma86 -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma_eos -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -echo "" -echo "# TESTING (XZ) ..." -echo "#######################" -sure ${P7ZIP} x ../test/7za.exe.xz -sure diff 7za.exe 7za433_ref/bin/7za.exe - -chmod +x 7za.exe -sure ${P7ZIP} -txz a 7za.exe.xz 7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x 7za.exe.xz -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -##################################### - -cd .. - -# ./clean_all.sh -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} - -echo "" -echo "========" -echo "ALL DONE" -echo "========" -echo "" diff -Nru p7zip-rar-16.02/check/check_7zr.sh p7zip-rar-16.02+really25.00+ds/check/check_7zr.sh --- p7zip-rar-16.02/check/check_7zr.sh 2015-09-12 10:12:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/check/check_7zr.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -#! /bin/sh - -sure() -{ - eval $* - if [ "$?" != "0" ] - then - echo "ERROR during : $*" - echo "ERROR during : $*" > last_error - exit 1 - fi -} - -P7ZIP="$@" -P7ZIP="${TOOLS} ${P7ZIP}" - - -REP=TMP_$$ -echo "REP=${REP}" -echo "P7ZIP=${P7ZIP}" -echo "TOOLS=${TOOLS}" - -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} -mkdir -p ${REP} - -cd ${REP} - -# sure rm -fr 7za433_ref 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar -# sure rm -fr 7za433_7zip_bzip2.7z 7za433_7zip_lzma.7z 7za433_7zip_lzma_crypto.7z 7za433_7zip_ppmd.7z 7za433_tar.tar - -echo "" -echo "# TESTING ..." -echo "#############" - -sure ${P7ZIP} t ../test/7za433_7zip_lzma.7z - - -echo "" -echo "# EXTRACTING ..." -echo "################" - -sure tar xf ../test/7za433_tar.tar -sure mv 7za433_tar 7za433_ref - -sure ${P7ZIP} x ../test/7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -sure ${P7ZIP} x ../test/7za433_7zip_lzma_bcj2.7z -sure diff -r 7za433_ref 7za433_7zip_lzma_bcj2 - -echo "" -echo "# Archiving ..." -echo "###############" - -sure ${P7ZIP} a 7za433_7zip_lzma.7z 7za433_7zip_lzma - -echo "" -echo "# EXTRACTING (PASS 2) ..." -echo "#########################" - -sure rm -fr 7za433_7zip_lzma - -sure ${P7ZIP} x 7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -echo "" -echo "# EXTRACTING (LZMA) ..." -echo "#######################" - -rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma86 -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x ../test/7za.exe.lzma_eos -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -echo "" -echo "# TESTING (XZ) ..." -echo "#######################" -sure ${P7ZIP} x ../test/7za.exe.xz -sure diff 7za.exe 7za433_ref/bin/7za.exe - -chmod +x 7za.exe -sure ${P7ZIP} -txz a 7za.exe.xz 7za.exe -sure rm -f 7za.exe - -sure ${P7ZIP} x 7za.exe.xz -sure diff 7za.exe 7za433_ref/bin/7za.exe -sure rm -f 7za.exe - -##################################### - -cd .. - -# ./clean_all.sh -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} - - -echo "" -echo "========" -echo "ALL DONE" -echo "========" -echo "" diff -Nru p7zip-rar-16.02/check/check_Client7z.sh p7zip-rar-16.02+really25.00+ds/check/check_Client7z.sh --- p7zip-rar-16.02/check/check_Client7z.sh 2015-09-12 10:30:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/check/check_Client7z.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -#! /bin/sh - -sure() -{ - eval $* - if [ "$?" != "0" ] - then - echo "ERROR during : $*" - echo "ERROR during : $*" > last_error - exit 1 - fi -} - -# set -x - -LD_LIBRARY_PATH=`cd ../bin ; pwd`:${LD_LIBRARY_PATH} -export LD_LIBRARY_PATH -echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" - -P7ZIP="$@" -P7ZIP="${TOOLS} ${P7ZIP}" - -REP=TMP_$$ -echo "REP=${REP}" -echo "P7ZIP=${P7ZIP}" -echo "TOOLS=${TOOLS}" - -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} -mkdir -p ${REP} - -cd ${REP} - -# sure rm -fr 7za433_ref 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar -# sure rm -fr 7za433_7zip_bzip2.7z 7za433_7zip_lzma.7z 7za433_7zip_lzma_crypto.7z 7za433_7zip_ppmd.7z 7za433_tar.tar - -# for Beos or MacOSX -ln -s ../../bin/7z.so . - -echo "" -echo "# TESTING ..." -echo "#############" - -sure ${P7ZIP} l ../test/7za433_7zip_lzma.7z -# sure ${P7ZIP} t -pqwerty ../test/7za433_7zip_lzma_crypto.7z -sure ${P7ZIP} l ../test/7za433_7zip_ppmd.7z -sure ${P7ZIP} l ../test/7za433_7zip_bzip2.7z - - - -echo "" -echo "# EXTRACTING ..." -echo "################" - -sure tar xf ../test/7za433_tar.tar -sure mv 7za433_tar 7za433_ref - -sure ${P7ZIP} x ../test/7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -# sure ${P7ZIP} x -pqwerty ../test/7za433_7zip_lzma_crypto.7z -# sure diff -r 7za433_ref 7za433_7zip_lzma_crypto - -sure ${P7ZIP} x ../test/7za433_7zip_ppmd.7z -sure diff -r 7za433_ref 7za433_7zip_ppmd - -sure ${P7ZIP} x ../test/7za433_7zip_bzip2.7z -sure diff -r 7za433_ref 7za433_7zip_bzip2 - -echo "" -echo "# Archiving ..." -echo "###############" - -sure ${P7ZIP} a 7za433_7zip_lzma.7z 7za433_7zip_lzma/bin/7za.exe 7za433_7zip_lzma/readme.txt 7za433_7zip_lzma/doc/copying.txt - -echo "" -echo "# EXTRACTING (PASS 2) ..." -echo "#########################" - -sure rm -fr 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar - -sure ${P7ZIP} x 7za433_7zip_lzma.7z -sure diff -r 7za433_ref 7za433_7zip_lzma - -cd .. - -# ./clean_all.sh -chmod -R 777 ${REP} 2> /dev/null -rm -fr ${REP} - -echo "" -echo "========" -echo "ALL DONE" -echo "========" -echo "" diff -Nru p7zip-rar-16.02/check/check_install.sh p7zip-rar-16.02+really25.00+ds/check/check_install.sh --- p7zip-rar-16.02/check/check_install.sh 2008-03-02 13:51:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/check/check_install.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -#! /bin/sh - -cd .. - -DEST_HOME=${HOME}/INSTALL_FOR_P7ZIP/local -DEST_HOME_SPACE="${HOME}/INSTALL_FOR_P7ZIP/lo cal" - -##########################################################################################" - -echo "## PASS 1 - no files " - -chmod -R 777 ${HOME}/INSTALL_FOR_P7ZIP -rm -fr ${HOME}/INSTALL_FOR_P7ZIP - -./install.sh "${DEST_HOME}/usr/bin" "${DEST_HOME}/usr/lib/p7zip" "${DEST_HOME}/usr/man" "${DEST_HOME}/usr/share/doc/p7zip" - - -echo "## PASS 2 - overwrite files " -./install.sh "${DEST_HOME}/usr/bin" "${DEST_HOME}/usr/lib/p7zip" "${DEST_HOME}/usr/man" "${DEST_HOME}/usr/share/doc/p7zip" - -mv "${DEST_HOME}" "${DEST_HOME}_REF" - -echo "## PASS 3 - with DEST_DIR" - -./install.sh "/usr/bin" "/usr/lib/p7zip" "/usr/man" "/usr/share/doc/p7zip" "${DEST_HOME}/" - -diff -r "${DEST_HOME}/usr/bin" "${DEST_HOME}_REF/usr/bin" > /dev/null - if [ "$?" = "0" ] - then - echo "#####" - echo "ERROR (bin)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME}/usr/man" "${DEST_HOME}_REF/usr/man" > /dev/null - if [ "$?" = "0" ] - then - echo "#####" - echo "ERROR (man)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME}/usr/lib" "${DEST_HOME}_REF/usr/lib" > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR (lib)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME}/usr/share" "${DEST_HOME}_REF/usr/share" > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR (share)" - echo "#####" - exit 1 - fi - -##########################################################################################" - -echo "## PASS 4 - no files " - -chmod -R 777 ${HOME}/INSTALL_FOR_P7ZIP -rm -fr ${HOME}/INSTALL_FOR_P7ZIP - -./install.sh "${DEST_HOME_SPACE}/usr/bin" "${DEST_HOME_SPACE}/usr/lib/p7zip" "${DEST_HOME_SPACE}/usr/man" "${DEST_HOME_SPACE}/usr/share/doc/p7zip" - - -echo "## PASS 5 - overwrite files " -./install.sh "${DEST_HOME_SPACE}/usr/bin" "${DEST_HOME_SPACE}/usr/lib/p7zip" "${DEST_HOME_SPACE}/usr/man" "${DEST_HOME_SPACE}/usr/share/doc/p7zip" - -# test each programs -echo "## PASS 6 - programs testing" - -"${DEST_HOME_SPACE}/usr/bin/7za" t check/test/7za433_7zip_lzma.7z > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR 7za" - echo "#####" - exit 1 - fi - -"${DEST_HOME_SPACE}/usr/bin/7z" t check/test/7za433_7zip_lzma.7z > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR 7z" - echo "#####" - exit 1 - fi - -"${DEST_HOME_SPACE}/usr/bin/7zr" t check/test/7za433_7zip_lzma.7z > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR 7zr" - echo "#####" - exit 1 - fi - - -mv "${DEST_HOME_SPACE}" "${DEST_HOME_SPACE}_REF" - -echo "## PASS 7 - with DEST_DIR" - -./install.sh "/usr/bin" "/usr/lib/p7zip" "/usr/man" "/usr/share/doc/p7zip" "${DEST_HOME_SPACE}/" - -diff -r "${DEST_HOME_SPACE}/usr/bin" "${DEST_HOME_SPACE}_REF/usr/bin" > /dev/null - if [ "$?" = "0" ] - then - echo "#####" - echo "ERROR (bin)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME_SPACE}/usr/man" "${DEST_HOME_SPACE}_REF/usr/man" > /dev/null - if [ "$?" = "0" ] - then - echo "#####" - echo "ERROR (man)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME_SPACE}/usr/lib" "${DEST_HOME_SPACE}_REF/usr/lib" > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR (lib)" - echo "#####" - exit 1 - fi - -diff -r "${DEST_HOME_SPACE}/usr/share" "${DEST_HOME_SPACE}_REF/usr/share" > /dev/null - if [ "$?" != "0" ] - then - echo "#####" - echo "ERROR (share)" - echo "#####" - exit 1 - fi - - -##########################################################################################" - -chmod -R 777 ${HOME}/INSTALL_FOR_P7ZIP -rm -fr ${HOME}/INSTALL_FOR_P7ZIP - - echo "########" - echo "All Done" - echo "########" - diff -Nru p7zip-rar-16.02/check/clean_all.sh p7zip-rar-16.02+really25.00+ds/check/clean_all.sh --- p7zip-rar-16.02/check/clean_all.sh 2008-05-18 11:53:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/check/clean_all.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -#! /bin/sh - -rm -fr 7za433_ref 7za433_7zip_bzip2 7za433_7zip_lzma 7za433_7zip_lzma_crypto 7za433_7zip_ppmd 7za433_tar -rm -fr 7za433_7zip_bzip2.7z 7za433_7zip_lzma.7z 7za433_7zip_lzma_crypto.7z 7za433_7zip_ppmd.7z 7za433_tar.tar -rm -fr last_error TMP_* - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za.exe.lzma and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za.exe.lzma86 and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma86 differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za.exe.lzma_eos and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.lzma_eos differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za.exe.xz and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za.exe.xz differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_bzip2.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_bzip2.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma2.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma2_bcj2.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2_bcj2.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma2_crypto.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma2_crypto.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma_bcj2.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma_bcj2.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_lzma_crypto.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_lzma_crypto.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_ppmd.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_ppmd.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_7zip_ppmd_bcj2.7z and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_7zip_ppmd_bcj2.7z differ Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/check/test/7za433_tar.tar and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/check/test/7za433_tar.tar differ diff -Nru p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/ChangeLog p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/ChangeLog --- p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/ChangeLog 2007-04-21 09:06:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/ChangeLog 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -=-=-=-= 4.29 -* Code optimization for using less temporary files as possible (may not work with p7zip - versions oldest than 4.29) - -=-=-=-= 4.16beta -* Changed internal date representation, because old date format may not work with - some mc versions. (thanks to Valery Koval for patch) -* Aligned with p7zip 4.16 beta (for properly handle old type archives with "./" prefix in - archive root, and deletion error from solid archives handle) - -=-=-=-= 4.14.2beta -* extract files with same name from different archive subdirs was not a bug, but feature, - so I made code cleanup. (thanks to myspace and Igor Pavlov) - -=-=-=-= 4.14.1beta -Aligned with p7zip 4.14.01 beta (may work with v 4.x) Not work with oldest versions! -* workaround p7zip bug for extract files with same name from different archive subdirs - -=-=-=-= 4.12.2beta -* incorrect show small text files in internal (mc) viewer = fixed - -=-=-=-= 4.12.1beta -Aligned with p7zip 4.12 beta (may work with v 4.10) Not work with oldest versions! -* many workarounds to aligning with 4.12 - -=-=-=-= 0.3.2beta -Aligned with p7zip 0.91 cause version 4.10beta is buggy -* incorrect handle files inside subdirs of archive without prefix "./" = fixed - -=-=-=-= 0.3.1beta -Aligned with p7zip 0.91 cause version 4.10beta is buggy -* incorrect handle filenames inside archive with length little than 12 symbols = fixed -* p7zip trying extract all files with same name in top dir and other dirs of archive = workaround -* some workarounds to align with version 0.91 - -=-=-=-= 0.3beta -Aligned with p7zip 0.90 cause version 4.10beta is buggy -* incorrect handle filenames with spaces = fixed - -=-=-=-= 0.2beta -first version, full of bugs... \ No newline at end of file diff -Nru p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/readme p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme --- p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/readme 2007-04-21 09:06:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -The official site of u7z is : http://sgh-punk.narod.ru/files/u7z/ - -INSTALL -======= -- edit /usr/share/mc/extfs/extfs.ini to add "u7z" after urar. - -- edit /usr/share/mc/mc.ext to add : -=-=-=-=-=-= Cut -=-=-=-=-=- -regex/\.(7z|7Z)$ - View=%view{ascii} 7za l %f - Open=%cd %p#u7z -=-=-=-=-=-= Cut -=-=-=-=-=- - -This must be added before Manual pages Lines to prevent handle 7z archive -like man page - -- copy u7z to /usr/share/mc/extfs - -- launch mc to try ;) - diff -Nru p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/readme.u7z p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme.u7z --- p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/readme.u7z 2007-04-21 09:06:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/readme.u7z 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -For use u7z you must add following line to extfs.ini - -=-=-=-=-=-= Cut -=-=-=-=-=- -u7z -=-=-=-=-=-= Cut -=-=-=-=-=- - -And add somthing like this to extension file - -REMARK: 7z may be replaced with 7za - -=-=-=-=-=-= Cut -=-=-=-=-=- -regex/\.(7z|7Z)$ - View=%view{ascii} 7z l %f - Open=%cd %p#u7z -=-=-=-=-=-= Cut -=-=-=-=-=- - -This must be added before Manual pages Lines to prevent handle 7z archive -like man page - - -If you have installed 7z with plugins, you can view and unpack .cab and other -(if there is plugin) archive types with u7z, just add - -=-=-=-=-=-= Cut -=-=-=-=-=- -regex/\.(cab|CAB)$ - View=%view{ascii} 7z l %f - Open=%cd %p#u7z -=-=-=-=-=-= Cut -=-=-=-=-=- - -to extension file, and somthing like this for other supported archives. diff -Nru p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/u7z p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/u7z --- p7zip-rar-16.02/contrib/VirtualFileSystemForMidnightCommander/u7z 2007-04-21 09:06:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/VirtualFileSystemForMidnightCommander/u7z 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -#! /bin/sh -# -# u7z - 7zip file archive Virtual File System for Midnight Commander ( ftp://ftp.ibiblio.org/pub/Linux/utils/file/managers/mc/ ) -# -# Copyright (C) 2004 Sergiy Niskorodov (sgh at mail dot zp dot ua) - -# Written by Sergiy Niskorodov aka SGh -# -# version 4.29 (12 Nov 2005) -# -# 7z for linux can be found on http://sourceforge.net/projects/p7zip/ - - -# Thanks to urar VFS authors andrey joukov 2:5020/337.13@fidonet.org, -# christian.gennerat@alcatel.fr, Andrew V. Samoilov -# I use this script like example - - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - -SEVENZ=`which 7z` || SEVENZ=`which 7za` - - -mc7zfs_list () -{ - $SEVENZ l "$1" 2> /dev/null | gawk -v uid=${UID-0} ' -BEGIN { flag=0; arr_of_month="JanFebMarAprMayJunJulAugSepOctNovDec" } - /^-------/ { flag++; if (flag > 1) exit 0; next } -{ -if (flag == 0) next - -year=substr($1, 1, 4) -month=substr($1, 6, 2) -day=substr($1, 9, 2) - -month_name=substr(arr_of_month, (month-1)*3+1, 3) - -time=substr($2, 1, 5) - -if (index($3, "D") != 0) - attr="drwxr-xr-x" -else -if (index($3, ".") != 0) - attr="-rw-r--r--" - -size=$4 - -$0=substr($0, 54) -if (NF > 1) - name=$0 -else - name=$1 - -gsub(/\\/, "/", name) - -printf "%s 1 %-8d %-8d %8d %3s %2d %4d %s %s\n", attr, uid, 0, size, month_name, day, year, time, name -}' -} - -mc7zfs_copyin () -{ -# preserve pwd. - pwd=`pwd` -# Create a directory and copy in it the tmp file with the random name - dir="$3".dir - mkdir "$dir" - cd "$dir" - di="${2%/*}" -# if file is to be written upper in the archive tree, make fake dir - if test "$di" != "${2##*/}" ; then - mkdir -p "$di" - fi - cp -fp "$3" "$dir/$2" - $SEVENZ a "$1" "$2" >/dev/null 2> /dev/null - cd $pwd - rm -rf "$3.dir" -} - -mc7zfs_copyout () -{ - $SEVENZ l "$1" | grep -q "[.][/].*$2" &> /dev/null && EXFNAME=*./"$2" || EXFNAME="$2" - $SEVENZ e -r- -so "$1" "$EXFNAME" > "$3" 2> /dev/null -} - -mc7zfs_mkdir () -{ -# preserve pwd. - pwd=`pwd` -# Create a directory and create in it a tmp directory with the good name - dir=tmpdir.${RANDOM} - mkdir $dir - cd $dir - mkdir -p "$2" - $SEVENZ a -r "$1" "$2" >/dev/null 2>/dev/null - cd $pwd - rm -rf $dir -} - -mc7zfs_rm () -{ - $SEVENZ l "$1" | grep -q "[.][/].*$2" &> /dev/null && EXFNAME=*./"$2" || EXFNAME="$2" - $SEVENZ d "$1" "$EXFNAME" 2>&1 | grep -q E_NOTIMPL &> /dev/null && { echo -e "Function not implemented...\n7z cannot delete files from solid archive." >&2 ; exit 1 ; } -} - -umask 077 - -cmd="$1" -shift - -case "$cmd" in - list) mc7zfs_list "$@" ;; - rm) mc7zfs_rm "$@" ;; - rmdir) mc7zfs_rm "$@" ;; - mkdir) mc7zfs_mkdir "$@" ;; - copyin) mc7zfs_copyin "$@" ;; - copyout) mc7zfs_copyout "$@" ;; - *) exit 1 ;; -esac -exit 0 diff -Nru p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/README p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/README --- p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/README 2007-04-21 09:06:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -gzip-like CLI wrapper (for 7z) -============================== - -The official site of the script p7zip provided in this directory -is http://packages.debian.org/unstable/utils/p7zip. - - -The script p7zip provides a CLI similar to that of -gzip/bzip2/etc Un*x utilities for 7z. - -When necessary, it emulates streaming by using -temporary files in /tmp. This is all transparent to -the application using it, which can use the same -semantincs than with gzip or bzip2. - -For example, you can do: - -tar --use-compress-program=p7zip -cf file.tar.7z dir/ - -to generate a 7zipped tarball. - diff -Nru p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/check/check.sh p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/check/check.sh --- p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/check/check.sh 2007-07-25 19:11:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/check/check.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -# ! /bin/sh - -# remove the strange filenames ... -rm -f -- "--" "bar" "-c" "-d" "-foo" "foo bar" "foo (bar) - ABCD" "-h" "-help" -if [ "$?" != "0" ] ; then - echo "error during rm" - exit 1 -fi - -# pipe -out=`echo "foobar" | ../p7zip | ../p7zip -d` - -if [ "${out}" != "foobar" ] ; then - echo "error in ../p7zip | ../p7zip -d" - exit 1 -fi - -# path with "./" -echo "foobar content" > foobar -../p7zip ./foobar -if [ "$?" != "0" ] ; then - echo "error p7zip ./foobar" - exit 1 -fi - -if [ ! -f ./foobar.7z ] ; then - echo "error ./foobar.7z not found" - exit 1 -fi - -../p7zip -d ./foobar.7z -if [ "$?" != "0" ] ; then - echo "error p7zip -d ./foobar.7z" - exit 1 -fi - -if [ ! -f ./foobar ] ; then - echo "error ./foobar not found" - exit 1 -fi - -content=`cat foobar` -if [ "${content}" != "foobar content" ] ; then - echo "error content of foobar" - exit 1 -fi - -rm -f foobar - -# the strange filenames are in the tar ... -tar xf files.tar -if [ "$?" != "0" ] ; then - echo "error in tar xf files.tar" - exit 1 -fi - -../p7zip -- "--" "bar" "-c" "-d" "-foo" "foo bar" "foo (bar) - ABCD" "-h" "-help" -if [ "$?" != "0" ] ; then - echo "error in p7zip" - exit 1 -fi - -for f in "--" "bar" "-c" "-d" "-foo" "foo bar" "foo (bar) - ABCD" "-h" "-help" -do - 7za -- t "${f}.7z" > /dev/null - if [ "$?" != 0 ] ; then - echo error in "${f}.7z" - exit 1 - fi -done - -../p7zip -d -- *.7z -if [ "$?" != "0" ] ; then - echo "error in p7zip -d" - exit 1 -fi - -for f in "--" "bar" "-c" "-d" "-foo" "foo bar" "foo (bar) - ABCD" "-h" "-help" -do - if [ ! -f "${f}" ] ; then - echo error "${f}" not found - exit 1 - fi -done - -# remove the strange filenames ... -rm -f -- "--" "bar" "-c" "-d" "-foo" "foo bar" "foo (bar) - ABCD" "-h" "-help" -if [ "$?" != "0" ] ; then - echo "error during rm" - exit 1 -fi - -# test errors - -../p7zip no_file -if [ "$?" = "0" ] ; then - echo "error p7zip no_file" - exit 1 -fi - -../p7zip -d no_file -if [ "$?" = "0" ] ; then - echo "error p7zip -d no_file" - exit 1 -fi - -../p7zip -d no_file.7z -if [ "$?" = "0" ] ; then - echo "error p7zip -d no_file.7z" - exit 1 -fi - -echo -echo "########" -echo "All Done" -echo "########" - Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/check/files.tar and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/check/files.tar differ diff -Nru p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 --- p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 2007-07-14 21:38:10.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -.TH p7zip 1 "October 31 2004" "Mohammed Adnene Trojette" -.SH NAME -p7zip \- Wrapper on 7za, a 7-zip file archiver with high compression ratio -.SH SYNOPSIS -.B p7zip -.BR [-d] -.BR [-h|--help] -.BR [--] -.BR [file ... ] - \-h print this help - \-d decompress file - \-- treats all subsequent arguments as file names, even if they start with a dash -.SH DESCRIPTION -7-Zip is a file archiver with the highest compression ratio. The program supports 7z (that implements LZMA compression algorithm), ZIP, CAB, ARJ, GZIP, BZIP2, TAR, CPIO, RPM and DEB formats. Compression ratio in the new 7z format is 30-50% better than ratio in ZIP format. -.TP -p7zip is a gzip-like CLI wrapper script for 7zip -.PP -.SH FUNCTION LETTERS -.TP -.B \-d -Decompress file -.TP -.B \-h, \--help -Print usage -.TP -.B \-- -Treats all subsequent arguments as file names, even if they start with a dash -.SH "SEE ALSO" -7z(1), 7za(1), 7zr(1), bzip2(1), gzip(1), zip(1) -.PP -.SH AUTHOR -.TP -Written for Debian by Mohammed Adnene Trojette. diff -Nru p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/p7zip p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/p7zip --- p7zip-rar-16.02/contrib/gzip-like_CLI_wrapper_for_7z/p7zip 2007-07-25 19:10:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/gzip-like_CLI_wrapper_for_7z/p7zip 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -#!/bin/sh -# gzip-like CLI wrapper for p7zip -# version 2.0 -# -# History -# 2.0 : -# - support for -filename, "file name" -# - p7zip file1 file2 ... - -set -e - -usage () - { - echo "Usage: $0 [-d] [-h|--help] [--] [ name ... ]" - echo "" - echo " -h print this help" - echo " -d decompress file" - echo " -- treats all subsequent arguments as file names, even if they start with a dash" - echo "" - exit 1 - } - -doit() -{ - compress=$1 - file="$2" - - if [ "${file}" != "" ] ; then - if ${compress} ; then - if [ -f "${file}" ] ; then - rm -f -- "${file}.7z" - 7za a -- "${file}.7z" "${file}" - if [ "$?" != "0" ] ; then - rm -f -- "${file}.7z" - exit 1 - fi - rm -- "${file}" - else - exit 1 - fi - else - case "${file}" in - *.7z) - if [ -f "${file}" ] ; then - 7za x -- "${file}" - if [ "$?" != "0" ] ; then - exit 1 - fi - rm -- "${file}" - else - exit 1 - fi - ;; - *) - echo "$0: ${file}: unknown suffix" - exit 1 - ;; - esac - fi - return 0 - fi - - P7ZIPTMP=${TMP:-/tmp} - tmp=`mktemp ${P7ZIPTMP}/p7zip.XXXXXXXX` - trap "rm -f -- ${tmp}" 0 - - if ${compress} ; then - if tty > /dev/null ; then - echo "$0: compressed data not written to a terminal." - echo "For help, type: $0 -h" - exit 1 - fi - rm -f -- ${tmp} - 7za a -si -- ${tmp} >/dev/null - if [ "$?" != "0" ] ; then - exit 1 - fi - cat ${tmp} - else - cat > ${tmp} - 7za x -so -- ${tmp} 2>/dev/null | cat - if [ "$?" != "0" ] ; then - exit 1 - fi - fi - - rm -f -- ${tmp} - return 0 -} - - -## MAIN - -compress=true -flag=true -file="" - -# make sure they're present, before we screw up -for i in mktemp 7za rm cat tty ; do - if ! which $i > /dev/null ; then - echo "$0: $i: command not found" - exit 1 - fi -done - -# files and flags -while [ "$#" != "0" ] ; do - case "$1" in - -d) - compress=false # decompressing - ;; - -c) - echo "$0: ignoring $1 option (not yet implemented)" - ;; - -h|--help) - usage - ;; - --) - flag=false - shift - break - ;; - *) - doit ${compress} "$1" - file="$1" - ;; - esac - shift -done - -# only files now -while [ "$#" != "0" ] ; do - doit ${compress} "$1" - file="$1" - shift -done - -if [ "${file}" = "" ] ; then - # compressing/decompressing using standart I/O - doit ${compress} -fi - -exit 0 - diff -Nru p7zip-rar-16.02/contrib/qnx630sp3/qnx630sp3-shared p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-shared --- p7zip-rar-16.02/contrib/qnx630sp3/qnx630sp3-shared 2015-09-12 15:03:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-shared 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -BIN="p7zip-4.47-x86-qnx6.shared" -cd ../../ && mkdir -p ../${BIN}/Codecs && \ -make clean && \ -mv makefile.machine makefile.machine.bak && \ -cp makefile.qnx_shared.bin makefile.machine && \ -make 7z && make 7za && make 7zr && make sfx && \ -mv ./bin/7z ../${BIN} && mv ./bin/7za ../${BIN} && mv ./bin/7zr ../${BIN} && mv ./bin/7zCon.sfx ../${BIN} && \ -make clean && \ -cp makefile.qnx_shared.so makefile.machine && \ -make 7z && \ -mv ./bin/7z.so ../${BIN} && mv ./bin/Codecs/Rar.so ../${BIN}/Codecs && \ -make clean && \ -mv makefile.machine.bak makefile.machine -echo "All done - look for binaries in ../${BIN}" diff -Nru p7zip-rar-16.02/contrib/qnx630sp3/qnx630sp3-static p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-static --- p7zip-rar-16.02/contrib/qnx630sp3/qnx630sp3-static 2007-06-24 19:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/contrib/qnx630sp3/qnx630sp3-static 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -BIN="p7zip-4.47-x86-qnx6.static" -cd ../../ && mkdir ../${BIN} && \ -make clean && \ -mv makefile.machine makefile.machine.bak && \ -cp makefile.qnx_static makefile.machine && \ -make 7za && make 7zr && make sfx && \ -mv ./bin/7za ../${BIN} && mv ./bin/7zr ../${BIN} && mv ./bin/7zCon.sfx ../${BIN} ; \ -make clean && \ -mv makefile.machine.bak makefile.machine -echo "All done - look for binaries in ../${BIN}" diff -Nru p7zip-rar-16.02/debian/changelog p7zip-rar-16.02+really25.00+ds/debian/changelog --- p7zip-rar-16.02/debian/changelog 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/changelog 2026-04-01 06:53:55.000000000 +0000 @@ -1,3 +1,26 @@ +p7zip-rar (16.02+really25.00+ds-0+deb12u1) bookworm; urgency=high + + * Non-maintainer upload by the LTS Security Team. + * Move codebase to 7-Zip (not p7zip) upstream 25.00, fixes: + - CVE-2025-53816: Zeroes written outside heap buffer in RAR5 handler + may lead to memory corruption and denial of service. + (Closes: #1109494) + * Edit package description about the codebase change. + * Drop yasm dependencies, ASM not enabled anymore in p7zip. + * Import patches from 25.00+ds-1+deb13u1. + * Selectively import packaging from trixie, to avoid disruption in + stable release: + - Bump p7zip-full dependency. + - Sync debian/copyright. + - Import debian/rules and 7zip-rar.install. + - Import debian/test/. + - Drop debian/format/ options. + * Stub debian/watch (reuse 7zip-rar tarball instead). + * Enable Salsa CI. + * Configure git-buildpackage for oldstable. + + -- Sylvain Beucler Wed, 01 Apr 2026 08:53:55 +0200 + p7zip-rar (16.02-3) unstable; urgency=medium * Hopefully fix uninitialized memory access (CVE-2018-10115) diff -Nru p7zip-rar-16.02/debian/control p7zip-rar-16.02+really25.00+ds/debian/control --- p7zip-rar-16.02/debian/control 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/control 2026-03-04 08:36:44.000000000 +0000 @@ -2,7 +2,7 @@ Section: non-free/utils Priority: optional Maintainer: Robert Luberda -Build-Depends: debhelper (>= 11), yasm [amd64], yasm [i386] +Build-Depends: debhelper (>= 11) XS-Autobuild: yes Rules-Requires-Root: no Standards-Version: 4.1.4 @@ -12,8 +12,7 @@ Package: p7zip-rar Architecture: any -Depends: p7zip-full (>= ${source:Upstream-Version}~), - p7zip-full (<< ${source:Upstream-Version}.~), +Depends: p7zip-full (>= 16.02+really25.00~), ${misc:Depends}, ${shlibs:Depends} Description: non-free rar module for p7zip @@ -22,3 +21,6 @@ . p7zip-rar provides a module for p7zip-full to make 7z able to extract RAR files. + . + To fix security vulnerabilities, this version is really a more recent + 7-Zip repackaged and patched to be reasonably compatible with p7zip. diff -Nru p7zip-rar-16.02/debian/copyright p7zip-rar-16.02+really25.00+ds/debian/copyright --- p7zip-rar-16.02/debian/copyright 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/copyright 2026-03-04 08:56:06.000000000 +0000 @@ -1,28 +1,174 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Igor Pavlov -Source: https://sourceforge.net/projects/p7zip/ -Comment: This software is non-free, due to the terms of the UnRAR license, - that does not meet Debian Free Software Guidelines. In particular, this - source code cannot be used to re-create the RAR compression algorithm, - and the license requires you to remove the software if you do not accept - its terms. +Upstream-Name: 7-Zip +Source: https://www.7-zip.org/ +Disclaimer: RAR code is under the non-free "unRAR license restriction" +Comment: Upstream tarball was repacked because it uses non-standatd compression options. + Repack with known compression options helps pristine-tar(1). Files: * -Copyright: 1999-2015, Igor Pavlov +Copyright: 1999-2024 Igor Pavlov License: LGPL-2.1+ -Files: CPP/7zip/Compress/Rar* - DOC/unRarLicense.txt -Copyright: 1999-2015, Igor Pavlov -License: LGPL-2.1+ and unRAR +Files: Asm/arm64/7zAsm.S + Asm/arm64/LzmaDecOpt.S + Asm/x86/7zAsm.asm + Asm/x86/7zCrcOpt.asm + Asm/x86/AesOpt.asm + Asm/x86/LzFindOpt.asm + Asm/x86/LzmaDecOpt.asm + Asm/x86/Sha1Opt.asm + Asm/x86/Sha256Opt.asm + Asm/x86/XzCrc64Opt.asm + C/7z.h + C/7zAlloc.c + C/7zAlloc.h + C/7zArcIn.c + C/7zBuf.c + C/7zBuf.h + C/7zBuf2.c + C/7zCrc.c + C/7zCrc.h + C/7zCrcOpt.c + C/7zDec.c + C/7zFile.c + C/7zFile.h + C/7zStream.c + C/7zTypes.h + C/7zVersion.h + C/Aes.c + C/Aes.h + C/AesOpt.c + C/Alloc.c + C/Alloc.h + C/Bcj2.c + C/Bcj2.h + C/Bcj2Enc.c + C/Blake2.h + C/Blake2s.c + C/Bra.c + C/Bra.h + C/Bra86.c + C/BraIA64.c + C/BwtSort.c + C/BwtSort.h + C/Compiler.h + C/CpuArch.c + C/CpuArch.h + C/Delta.c + C/Delta.h + C/DllSecur.c + C/DllSecur.h + C/HuffEnc.c + C/HuffEnc.h + C/LzFind.c + C/LzFind.h + C/LzFindMt.c + C/LzFindMt.h + C/LzFindOpt.c + C/LzHash.h + C/Lzma2Dec.c + C/Lzma2Dec.h + C/Lzma2DecMt.c + C/Lzma2DecMt.h + C/Lzma2Enc.c + C/Lzma2Enc.h + C/Lzma86.h + C/Lzma86Dec.c + C/Lzma86Enc.c + C/LzmaDec.c + C/LzmaDec.h + C/LzmaEnc.c + C/LzmaEnc.h + C/LzmaLib.c + C/LzmaLib.h + C/MtCoder.c + C/MtCoder.h + C/MtDec.c + C/MtDec.h + C/Ppmd.h + C/Ppmd7.c + C/Ppmd7.h + C/Ppmd7aDec.c + C/Ppmd7Dec.c + C/Ppmd7Enc.c + C/Ppmd8.c + C/Ppmd8.h + C/Ppmd8Dec.c + C/Ppmd8Enc.c + C/Precomp.h + C/RotateDefs.h + C/Sha1.c + C/Sha1.h + C/Sha1Opt.c + C/Sha256.c + C/Sha256.h + C/Sha256Opt.c + C/Sort.c + C/Sort.h + C/Threads.c + C/Threads.h + C/Util/7z/7zMain.c + C/Util/7z/Precomp.c + C/Util/7z/Precomp.h + C/Util/7zipInstall/7zipInstall.c + C/Util/7zipInstall/Precomp.c + C/Util/7zipInstall/Precomp.h + C/Util/7zipUninstall/7zipUninstall.c + C/Util/7zipUninstall/Precomp.c + C/Util/7zipUninstall/Precomp.h + C/Util/Lzma/LzmaUtil.c + C/Util/LzmaLib/LzmaLibExports.c + C/Util/SfxSetup/Precomp.c + C/Util/SfxSetup/Precomp.h + C/Util/SfxSetup/SfxSetup.c + C/Xz.c + C/Xz.h + C/XzCrc64.c + C/XzCrc64.h + C/XzCrc64Opt.c + C/XzDec.c + C/XzEnc.c + C/XzEnc.h + C/XzIn.c + CPP/7zip/Archive/PpmdHandler.cpp + CPP/7zip/Compress/PpmdDecoder.cpp + CPP/7zip/Compress/PpmdDecoder.h +Copyright: No copyright claimed +License: public-domain + Igor Pavlov : Public domain + ---------- + This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. + ---------- + This code is based on public domain code from Wei Dai's Crypto++ library. + ---------- + PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain + ---------- + Carryless rangecoder (1999): Dmitry Subbotin : Public domain + ---------- + Samuel Neves : Public domain -Files: contrib/* -Copyright: 2004, Sergiy Niskorodov (sgh at mail dot zp dot ua) -License: GPL-2+ +Files: CPP/7zip/Compress/LzfseDecoder.cpp +Copyright: 2015-2017, Apple Inc. + 2018 Igor Pavlov +License: BSD-3-clause +Comment: Some parts come from the "LZFSE compression library" + +Files: C/ZstdDec.c +Copyright: 2024 Igor Pavlov +License: BSD-3-clause +Comment: the code was developed by Igor Pavlov, using Zstandard format + specification and original zstd decoder code as reference code. + +Files: CPP/7zip/Compress/Rar* +Copyright: Alexander L. Roshal +License: unRAR Files: debian/* Copyright: 2016, Robert Luberda 2004-2012, Mohammed Adnè Trojette + 2021 Collabora, Ltd. + 2023-2024 YOKOTA Hiroshi + 2026 Sylvain Beucler License: GPL-2+ License: GPL-2+ @@ -35,52 +181,84 @@ Public License can be found in '/usr/share/common-licenses/GPL-2'. License: LGPL-2.1+ - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; version 2.1 of the License, or (at - your option) any later version. + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation version 2.1 of the License, or (at your + option) any later version. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. . - On Debian systems, the complete text of version 2.1 of the GNU Lesser - General Public License can be found in `/usr/share/common-licenses/LGPL-2.1'. + On Debian systems you can find the full text of the GNU Lesser General + Public License version 2.1 license at /usr/share/common-licenses/LGPL-2.1. + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + . + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and\/or other materials provided with the + distribution. + . + Neither the name of the nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: unRAR - ****** ***** ****** unRAR - free utility for RAR archives - ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ****** ******* ****** License for use and distribution of - ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ** ** ** ** ** ** FREE portable version - ~~~~~~~~~~~~~~~~~~~~~ - . - The source code of unRAR utility is freeware. This means: - . - 1. All copyrights to RAR and the utility unRAR are exclusively - owned by the author - Alexander Roshal. - . - 2. The unRAR sources may be used in any software to handle RAR - archives without limitations free of charge, but cannot be used - to re-create the RAR compression algorithm, which is proprietary. - Distribution of modified unRAR sources in separate form or as a - part of other software is permitted, provided that it is clearly - stated in the documentation and source comments that the code may - not be used to develop a RAR (WinRAR) compatible archiver. - . - 3. The unRAR utility may be freely distributed. No person or company - may charge a fee for the distribution of unRAR without written - permission from the copyright holder. - . - 4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS". - NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT - YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, - DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING - OR MISUSING THIS SOFTWARE. - . - 5. Installing and using the unRAR utility signifies acceptance of - these terms and conditions of the license. - . - 6. If you don't agree with terms of the license you must remove - unRAR files from your storage devices and cease to use the - utility. + ****** ***** ****** unRAR - free utility for RAR archives + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ****** ******* ****** License for use and distribution of + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ** ** ** ** ** ** FREE portable version + ~~~~~~~~~~~~~~~~~~~~~ + . + The source code of unRAR utility is freeware. This means: + . + 1. All copyrights to RAR and the utility unRAR are exclusively + owned by the author - Alexander Roshal. + . + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + . + 3. The unRAR utility may be freely distributed. No person or company + may charge a fee for the distribution of unRAR without written + permission from the copyright holder. + . + 4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS". + NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT + YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, + DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING + OR MISUSING THIS SOFTWARE. + . + 5. Installing and using the unRAR utility signifies acceptance of + these terms and conditions of the license. + . + 6. If you don't agree with terms of the license you must remove + unRAR files from your storage devices and cease to use the + utility. + . + Thank you for your interest in RAR and unRAR. . - Thank you for your interest in RAR and unRAR. . - Alexander L. Roshal + Alexander L. Roshal diff -Nru p7zip-rar-16.02/debian/gbp.conf p7zip-rar-16.02+really25.00+ds/debian/gbp.conf --- p7zip-rar-16.02/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/gbp.conf 2026-03-04 08:56:55.000000000 +0000 @@ -0,0 +1,6 @@ +[DEFAULT] +debian-branch = debian/bookworm + +[import-orig] +pristine-tar = True +postunpack = find Asm C CPP DOC -type f -execdir chmod -x {} ";" diff -Nru p7zip-rar-16.02/debian/p7zip-rar.install p7zip-rar-16.02+really25.00+ds/debian/p7zip-rar.install --- p7zip-rar-16.02/debian/p7zip-rar.install 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/p7zip-rar.install 2026-03-04 07:48:36.000000000 +0000 @@ -0,0 +1 @@ +CPP/7zip/Bundles/FormatRAR/b/g/Rar.so usr/lib/p7zip/Codecs \ No newline at end of file diff -Nru p7zip-rar-16.02/debian/patches/0001-Accept-Debian-build-flags.patch p7zip-rar-16.02+really25.00+ds/debian/patches/0001-Accept-Debian-build-flags.patch --- p7zip-rar-16.02/debian/patches/0001-Accept-Debian-build-flags.patch 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/0001-Accept-Debian-build-flags.patch 2026-03-04 07:03:20.000000000 +0000 @@ -0,0 +1,57 @@ +From: YOKOTA Hiroshi +Date: Sun, 9 May 2021 22:39:21 +0900 +Subject: Accept Debian build flags + +Forwarded: not-needed +--- + CPP/7zip/7zip_gcc.mak | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/CPP/7zip/7zip_gcc.mak b/CPP/7zip/7zip_gcc.mak +index 8fbef14..2756ba4 100644 +--- a/CPP/7zip/7zip_gcc.mak ++++ b/CPP/7zip/7zip_gcc.mak +@@ -45,7 +45,7 @@ CFLAGS_DEBUG = -g + else + CFLAGS_DEBUG = -DNDEBUG + ifneq ($(CC), $(CROSS_COMPILE)clang) +-LFLAGS_STRIP = -s ++LFLAGS_STRIP = + endif + endif + +@@ -104,14 +104,14 @@ SHARED_EXT=.dll + LDFLAGS = -shared -DEF $(DEF_FILE) $(LDFLAGS_STATIC) + else + SHARED_EXT=.so +-LDFLAGS = -shared -fPIC $(LDFLAGS_STATIC) ++LDFLAGS = -shared -fPIC $(DEB_LDFLAGS) $(LDFLAGS_STATIC) + CC_SHARED=-fPIC + endif + + + else + +-LDFLAGS = $(LDFLAGS_STATIC) ++LDFLAGS = $(DEB_LDFLAGS) $(LDFLAGS_STATIC) + # -z force-bti + # -s is not required for clang, do we need it for GCC ??? + +@@ -169,7 +169,7 @@ endif + + + +-CFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CC_SHARED) -o $@ ++CFLAGS = $(DEB_CFLAGS) $(DEB_CPPFLAGS) $(MY_ARCH_2) $(LOCAL_FLAGS) $(CFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CC_SHARED) -o $@ + + + ifdef IS_MINGW +@@ -210,7 +210,7 @@ CXX_WARN_FLAGS = + #-Wno-invalid-offsetof + #-Wno-reorder + +-CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CXXFLAGS_EXTRA) $(CC_SHARED) $(CXX_WARN_FLAGS) $(CXX_STD_FLAGS) $(CXX_INCLUDE_FLAGS) -o $@ ++CXXFLAGS = $(DEB_CXXFLAGS) $(DEB_CPPFLAGS) $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(FLAGS_FLTO) $(CXXFLAGS_EXTRA) $(CC_SHARED) $(CXX_WARN_FLAGS) $(CXX_STD_FLAGS) $(CXX_INCLUDE_FLAGS) -o $@ + + STATIC_TARGET= + ifdef COMPL_STATIC diff -Nru p7zip-rar-16.02/debian/patches/0002-Add-RAR-plugin-builder.patch p7zip-rar-16.02+really25.00+ds/debian/patches/0002-Add-RAR-plugin-builder.patch --- p7zip-rar-16.02/debian/patches/0002-Add-RAR-plugin-builder.patch 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/0002-Add-RAR-plugin-builder.patch 2026-03-04 07:03:20.000000000 +0000 @@ -0,0 +1,205 @@ +From: YOKOTA Hiroshi +Date: Tue, 30 May 2023 20:11:52 +0900 +Subject: Add RAR plugin builder + +Forwarded: not-needed + +RAR support is separated to another plugin and main package keeps DFSG +--- + CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak | 126 ++++++++++++++++++++++++++++++++ + CPP/7zip/Bundles/FormatRAR/makefile.gcc | 53 ++++++++++++++ + 2 files changed, 179 insertions(+) + create mode 100644 CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak + create mode 100644 CPP/7zip/Bundles/FormatRAR/makefile.gcc + +diff --git a/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak b/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak +new file mode 100644 +index 0000000..2fbcf52 +--- /dev/null ++++ b/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak +@@ -0,0 +1,126 @@ ++include ../../LzmaDec_gcc.mak ++ ++LOCAL_FLAGS_ST = ++MT_OBJS = ++ ++ifdef SystemDrive ++IS_MINGW = 1 ++else ++ifdef SYSTEMDRIVE ++# ifdef OS ++IS_MINGW = 1 ++endif ++endif ++ ++ifdef ST_MODE ++ ++LOCAL_FLAGS_ST = -DZ7_ST ++ ++ifdef IS_MINGW ++MT_OBJS = ++ ++endif ++ ++else ++ ++MT_OBJS = ++ ++endif ++ ++ ++ ++COMMON_OBJS = ++ ++WIN_OBJS = ++ ++7ZIP_COMMON_OBJS = \ ++ $O/InBuffer.o \ ++ $O/OutBuffer.o \ ++ $O/StreamUtils.o ++ ++AR_OBJS = ++ ++AR_COMMON_OBJS = ++ ++ ++7Z_OBJS = ++ ++CAB_OBJS = ++ ++CHM_OBJS = ++ ++ISO_OBJS = ++ ++NSIS_OBJS = ++ ++ifndef DISABLE_RAR ++RAR_OBJS = ++ ++endif ++ ++ ++TAR_OBJS = ++ ++UDF_OBJS = ++ ++WIM_OBJS = ++ ++ZIP_OBJS = ++ ++COMPRESS_OBJS = \ ++ $O/LzOutWindow.o ++ ++ifdef DISABLE_RAR ++DISABLE_RAR_COMPRESS=1 ++endif ++ ++ifndef DISABLE_RAR_COMPRESS ++COMPRESS_OBJS += \ ++ $O/Rar1Decoder.o \ ++ $O/Rar2Decoder.o \ ++ $O/Rar3Decoder.o \ ++ $O/Rar3Vm.o \ ++ $O/Rar5Decoder.o \ ++ $O/RarCodecsRegister.o ++ ++endif ++ ++CRYPTO_OBJS = ++ ++ifndef DISABLE_RAR ++CRYPTO_OBJS += ++ ++endif ++ ++ ++C_OBJS = \ ++ $O/Alloc.o \ ++ $O/CpuArch.o \ ++ $O/Ppmd7.o \ ++ $O/Ppmd7Dec.o \ ++ $O/Ppmd7aDec.o \ ++ $O/7zCrc.o \ ++ $O/7zCrcOpt.o ++ ++ARC_OBJS = \ ++ $(LZMA_DEC_OPT_OBJS) \ ++ $(C_OBJS) \ ++ $(MT_OBJS) \ ++ $(COMMON_OBJS) \ ++ $(WIN_OBJS) \ ++ $(AR_OBJS) \ ++ $(AR_COMMON_OBJS) \ ++ $(7Z_OBJS) \ ++ $(CAB_OBJS) \ ++ $(CHM_OBJS) \ ++ $(COM_OBJS) \ ++ $(ISO_OBJS) \ ++ $(NSIS_OBJS) \ ++ $(RAR_OBJS) \ ++ $(TAR_OBJS) \ ++ $(UDF_OBJS) \ ++ $(WIM_OBJS) \ ++ $(ZIP_OBJS) \ ++ $(COMPRESS_OBJS) \ ++ $(CRYPTO_OBJS) \ ++ $(7ZIP_COMMON_OBJS) +diff --git a/CPP/7zip/Bundles/FormatRAR/makefile.gcc b/CPP/7zip/Bundles/FormatRAR/makefile.gcc +new file mode 100644 +index 0000000..d070b84 +--- /dev/null ++++ b/CPP/7zip/Bundles/FormatRAR/makefile.gcc +@@ -0,0 +1,53 @@ ++PROG = Rar ++DEF_FILE = ../../Archive/Archive2.def ++ ++# IS_X64 = 1 ++# USE_ASM = 1 ++# ST_MODE = 1 ++ ++include Arc_gcc.mak ++ ++ifdef SystemDrive ++IS_MINGW = 1 ++else ++ifdef SYSTEMDRIVE ++# ifdef OS ++IS_MINGW = 1 ++endif ++endif ++ ++ ++ifdef IS_MINGW ++ ++LOCAL_FLAGS_WIN = \ ++ -DZ7_LARGE_PAGES \ ++ $(LOCAL_FLAGS_ST) ++ ++SYS_OBJS = ++ ++else ++ ++SYS_OBJS = \ ++ $O/MyWindows.o ++ ++endif ++ ++LOCAL_FLAGS = \ ++ -DZ7_EXTERNAL_CODECS \ ++ $(LOCAL_FLAGS_WIN) \ ++ $(LOCAL_FLAGS_ST) ++ ++ ++COMPRESS_OBJS_2 = \ ++ $O/CodecExports.o \ ++ $O/DllExportsCompress.o ++ ++AR_OBJS_2 = ++ ++OBJS = \ ++ $(ARC_OBJS) \ ++ $(AR_OBJS_2) \ ++ $(COMPRESS_OBJS_2) \ ++ $(SYS_OBJS) ++ ++include ../../7zip_gcc.mak diff -Nru p7zip-rar-16.02/debian/patches/0003-Add-missing-CRC-table-constructor-Closes-1118733.patch p7zip-rar-16.02+really25.00+ds/debian/patches/0003-Add-missing-CRC-table-constructor-Closes-1118733.patch --- p7zip-rar-16.02/debian/patches/0003-Add-missing-CRC-table-constructor-Closes-1118733.patch 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/0003-Add-missing-CRC-table-constructor-Closes-1118733.patch 2026-03-04 07:03:20.000000000 +0000 @@ -0,0 +1,25 @@ +From: YOKOTA Hiroshi +Date: Sun, 2 Nov 2025 10:29:49 +0900 +Subject: Add missing CRC table constructor (Closes: #1118733) + +This function requires to select Rar3 standard VM filters. +If it missing, RAR plugin fails to extract Rar3 codec data with +compression filters. +--- + CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak b/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak +index 2fbcf52..54ceece 100644 +--- a/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak ++++ b/CPP/7zip/Bundles/FormatRAR/Arc_gcc.mak +@@ -29,7 +29,8 @@ endif + + + +-COMMON_OBJS = ++COMMON_OBJS = \ ++ $O/CRC.o + + WIN_OBJS = + diff -Nru p7zip-rar-16.02/debian/patches/01-clean-makefile.patch p7zip-rar-16.02+really25.00+ds/debian/patches/01-clean-makefile.patch --- p7zip-rar-16.02/debian/patches/01-clean-makefile.patch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/01-clean-makefile.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -From: Robert Luberda -Date: Fri, 22 Jan 2016 00:47:56 +0100 -Subject: Clean makefile - ---- - makefile | 87 +++-------------------------------- - makefile.common | 139 -------------------------------------------------------- - 2 files changed, 6 insertions(+), 220 deletions(-) - -diff --git a/makefile b/makefile -index 745c8ed..c176a60 100644 ---- a/makefile -+++ b/makefile -@@ -1,85 +1,10 @@ -+.PHONY: all rar clean - - include makefile.common - --test_lib: common -- $(MAKE) -C CPP/myWindows all -- --other: common -- $(MAKE) -C Utils/CPUTest/MemLat all -- $(MAKE) -C Utils/CPUTest/PipeLen all -- $(MAKE) -C CPP/7zip/UI/P7ZIP all -- $(MAKE) -C CPP/7zip/TEST/TestUI all -- --other2: -- $(MAKE) -C CPP/7zip/Bundles/AloneGCOV all -- --7za: common -- $(MAKE) -C CPP/7zip/Bundles/Alone all -- --7zr: common -- $(MAKE) -C CPP/7zip/Bundles/Alone7z all -- --Client7z: common -- $(MKDIR) bin/Codecs -- $(MAKE) -C CPP/7zip/Bundles/Format7zFree all -- $(MAKE) -C CPP/7zip/UI/Client7z all -- --depend: -- $(MAKE) -C CPP/7zip/Bundles/Alone depend -- $(MAKE) -C CPP/7zip/Bundles/Alone7z depend -- $(MAKE) -C CPP/7zip/Bundles/SFXCon depend -- $(MAKE) -C CPP/7zip/UI/Client7z depend -- $(MAKE) -C CPP/7zip/UI/Console depend -- $(MAKE) -C CPP/7zip/Bundles/Format7zFree depend -- $(MAKE) -C CPP/7zip/Compress/Rar depend -- $(MAKE) -C CPP/7zip/UI/GUI depend -- $(MAKE) -C CPP/7zip/UI/FileManager depend -- --sfx: common -- $(MKDIR) bin -- $(MAKE) -C CPP/7zip/Bundles/SFXCon all -- --common7z:common -- $(MKDIR) bin/Codecs -- $(MAKE) -C CPP/7zip/Bundles/Format7zFree all -- $(MAKE) -C CPP/7zip/Compress/Rar all -- --lzham:common -- $(MKDIR) bin/Codecs -- $(MAKE) -C CPP/7zip/Compress/Lzham all -- --7z: common7z -- $(MAKE) -C CPP/7zip/UI/Console all -- --7zG: common7z LangAndHelp -- $(MAKE) -C CPP/7zip/UI/GUI all -- --7zFM: common7z LangAndHelp -- $(MAKE) -C CPP/7zip/UI/FileManager all -- --clean_C: -- $(MAKE) -C CPP/myWindows clean -- $(MAKE) -C CPP/7zip/Bundles/Alone clean -- $(MAKE) -C CPP/7zip/Bundles/Alone7z clean -- $(MAKE) -C CPP/7zip/Bundles/SFXCon clean -- $(MAKE) -C CPP/7zip/UI/Client7z clean -- $(MAKE) -C CPP/7zip/UI/Console clean -- $(MAKE) -C CPP/7zip/UI/FileManager clean -- $(MAKE) -C CPP/7zip/UI/GUI clean -- $(MAKE) -C CPP/7zip/Bundles/Format7zFree clean -- $(MAKE) -C CPP/7zip/Compress/Rar clean -- $(MAKE) -C CPP/7zip/Compress/Lzham clean -- $(MAKE) -C CPP/7zip/Bundles/LzmaCon clean2 -- $(MAKE) -C CPP/7zip/Bundles/AloneGCOV clean -- $(MAKE) -C CPP/7zip/TEST/TestUI clean -- $(MAKE) -C CPP/ANDROID clean -- $(MAKE) -C Utils/CPUTest/MemLat clean -- $(MAKE) -C Utils/CPUTest/PipeLen clean -- $(MAKE) -C CPP/7zip/UI/P7ZIP clean -- --LzmaCon: -- $(MAKE) -C CPP/7zip/Bundles/LzmaCon -- --test_LzmaCon: -- $(MAKE) -C CPP/7zip/Bundles/LzmaCon test -+all rar: -+ $(MKDIR) bin bin/Codecs -+ $(MAKE) -C CPP/7zip/Compress/Rar all - -+clean: -+ $(MAKE) -C CPP/7zip/Compress/Rar clean -diff --git a/makefile.common b/makefile.common -index d8f6e16..1912ba7 100644 ---- a/makefile.common -+++ b/makefile.common -@@ -6,145 +6,6 @@ DEST_SHARE=$(DEST_HOME)/lib/p7zip - DEST_SHARE_DOC=$(DEST_HOME)/share/doc/p7zip - DEST_MAN=$(DEST_HOME)/man - --.PHONY: default all all2 7za 7zG 7zFM sfx 7z 7zr Client7z common common7z LangAndHelp tar_bin depend test test_7z test_7zr test_7zG test_Client7z LzmaCon test_LzmaCon all_test app cppcheck lzham test_lib other -- --.PHONY: clean clean_full clean_C -- - include makefile.machine - --default:7za -- --all:7za sfx -- --all2: all 7z -- --all3: all2 7zr -- --all4: all3 Client7z LzmaCon lzham test_lib -- --all4bis: all3 Client7z LzmaCon test_lib # lzham not supported on x32 CPU. -- --all5: all4 7zG 7zFM -- --all6: all5 other -- --all_all : all6 -- --all_test : test test_7z test_7zr test_LzmaCon test_Client7z -- --all_test2 : all_test test_7zG -- --common: -- $(MKDIR) bin -- --app: common 7zFM 7zG 7z sfx -- rm -fr p7zip.app -- $(MKDIR) p7zip.app -- cp -rp GUI/Contents p7zip.app/ -- $(MKDIR) p7zip.app/Contents -- $(MKDIR) p7zip.app/Contents/MacOS -- cp bin/7zFM_do_not_use p7zip.app/Contents/MacOS/ -- cp bin/7zG p7zip.app/Contents/MacOS/ -- cp bin/7z.so p7zip.app/Contents/MacOS/ -- cp bin/7zCon.sfx p7zip.app/Contents/MacOS/ -- cp -rp bin/Codecs p7zip.app/Contents/MacOS/ -- cp -rp GUI/Lang p7zip.app/Contents/MacOS/ -- cp -rp DOC/MANUAL p7zip.app/Contents/MacOS/help -- --LangAndHelp: -- cd bin ; rm -f Lang ; ln -s ../GUI/Lang . -- cd bin ; rm -f help ; ln -s ../DOC/MANUAL help -- --clean: clean_C -- rm -fr bin -- rm -fr p7zip.app -- rm -f Lang -- rm -fr CPP/7zip/P7ZIP.* -- rm -fr CPP/7zip/CMAKE/P7ZIP.* -- rm -fr CPP/7zip/PREMAKE/P7ZIP.* -- rm -f CPP/7zip/QMAKE/*/*.o -- rm -f CPP/7zip/QMAKE/*/Makefile -- rm -f CPP/7zip/QMAKE/*/*.pro.user -- rm -f CPP/7zip/QMAKE/*/*.x -- -find . -name "build*" -exec rm -fr {} \; -- -find . -name "*-build-*" -exec rm -fr {} \; -- -find . -name "*.user" -exec rm -f {} \; -- -find . -name "._*" -exec rm -f {} \; -- rm -fr CPP/7zip/ANDROID/libs -- rm -fr CPP/7zip/ANDROID/obj -- rm -f make.log 1 2 cppcheck.out scan-build.out -- rm -f check/7z.so -- rm -fr p7zip.app/Contents/MacOS -- cd check ; ./clean_all.sh -- -- --clean_full:clean -- find . -name "makefile.depend" -exec rm -f {} \; -exec touch {} \; # empty makefile.depend -- find . -name "*~" -exec rm -f {} \; -- find . -name "*.orig" -exec rm -fr {} \; # kdiff3 merge -- find . -name ".*.swp" -exec rm -f {} \; -- find . -name "*.i" -exec rm -f {} \; -- find . -name "*.s" -exec rm -f {} \; -- find . -name ".DS_Store" -exec rm -f {} \; # MacOSX -- find . -name "._*" -exec rm -f {} \; # MacOSX -- find . -name "*.pyc" -exec rm -f {} \; -- find . -name "*.[ch]" -exec chmod -x {} \; -- find . -name "*.cpp" -exec chmod -x {} \; -- find . -name "*.asm" -exec chmod -x {} \; -- find . -name "makefile*" -exec chmod -x {} \; -- chmod -x ChangeLog README TODO man1/* DOC/*.txt -- chmod +x contrib/VirtualFileSystemForMidnightCommander/u7z -- chmod +x contrib/gzip-like_CLI_wrapper_for_7z/p7zip -- chmod +x install.sh check/*.sh -- --test: 7za sfx -- cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7za" -- --test_7z: 7z sfx -- cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7z" -- --test_7zr: 7zr sfx -- cd check ; TOOLS="${TOOLS}" ./check_7zr.sh "`pwd`/../bin/7zr" -- --test_7zG: 7zG sfx -- cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7zG" -- --test_Client7z: Client7z -- cd check ; TOOLS="${TOOLS}" ./check_Client7z.sh "`pwd`/../bin/Client7z" -- --install: -- ./install.sh $(DEST_BIN) $(DEST_SHARE) $(DEST_MAN) $(DEST_SHARE_DOC) $(DEST_DIR) -- --# cppcheck -f : test all flags --cppcheck: -- cppcheck --enable=all -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DNDEBUG -D_REENTRANT -DENV_UNIX -D_7ZIP_LARGE_PAGES -DBREAK_HANDLER -DUNICODE -D_UNICODE . 2>&1 | tee -i cppcheck.out -- --REP=$(shell pwd) --ARCHIVE=$(shell basename $(REP)) -- --.PHONY: tar_all tar_all2 src_7z tar_bin tar_bin2 -- --tar_all : clean_full -- rm -f ../$(ARCHIVE)_src_all.tar.bz2 -- cp makefile.linux_any_cpu makefile.machine -- cd .. ; (tar cf - $(ARCHIVE) | bzip2 -9 > $(ARCHIVE)_src_all.tar.bz2) -- --tar_all2 : clean_full -- rm -f ../$(ARCHIVE)_src_all.tar.bz2 -- cp makefile.linux_any_cpu makefile.machine -- cd .. ; (tar cf - $(ARCHIVE) | 7za a -mx=9 -tbzip2 -si $(ARCHIVE)_src_all.tar.bz2 ) -- --src_7z : clean_full -- rm -f ../$(ARCHIVE)_src.7z -- cd .. ; 7za a -mx=9 -m0=ppmd:mem=128m:o=32 $(ARCHIVE)_src.7z $(ARCHIVE) -- --tar_bin: -- rm -f ../$(ARCHIVE)_x86_linux_bin.tar.bz2 -- chmod +x install.sh contrib/VirtualFileSystemForMidnightCommander/u7z contrib/gzip-like_CLI_wrapper_for_7z/p7zip -- cd .. ; (tar cf - $(ARCHIVE)/bin $(ARCHIVE)/contrib $(ARCHIVE)/man1 $(ARCHIVE)/install.sh $(ARCHIVE)/ChangeLog $(ARCHIVE)/DOC $(ARCHIVE)/README $(ARCHIVE)/TODO | bzip2 -9 > $(ARCHIVE)_x86_linux_bin.tar.bz2) -- --tar_bin2: -- rm -f ../$(ARCHIVE)_x86_linux_bin.tar.bz2 -- chmod +x install.sh contrib/VirtualFileSystemForMidnightCommander/u7z contrib/gzip-like_CLI_wrapper_for_7z/p7zip -- cd .. ; (tar cf - $(ARCHIVE)/bin $(ARCHIVE)/contrib $(ARCHIVE)/man1 $(ARCHIVE)/install.sh $(ARCHIVE)/ChangeLog $(ARCHIVE)/DOC $(ARCHIVE)/README $(ARCHIVE)/TODO | 7za a -mx=9 -tbzip2 -si $(ARCHIVE)_x86_linux_bin.tar.bz2) - diff -Nru p7zip-rar-16.02/debian/patches/03-include-linux-makefile.patch p7zip-rar-16.02+really25.00+ds/debian/patches/03-include-linux-makefile.patch --- p7zip-rar-16.02/debian/patches/03-include-linux-makefile.patch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/03-include-linux-makefile.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -From: Robert Luberda -Date: Fri, 22 Jan 2016 11:16:14 +0100 -Subject: Include linux makefile - -Include appropriate makefile from makefile.machine - - makefile.linux_x86_asm_gcc_4.X on i386; - - makefile.linux_amd64_asm on amd64; - - makefile.linux_any_cpu_gcc_4.X otherwise. - -Update makefile.linux_amd64_asm to have the same visibility -flags as the *gcc_4.X makefiles. - -Update makefile.linux_x86_asm_gcc_4.X to use yasm instead -of nasm. ---- - makefile.linux_amd64_asm | 3 +++ - makefile.linux_x86_asm_gcc_4.X | 2 +- - makefile.machine | 20 ++++++++++++++++++++ - 3 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/makefile.linux_amd64_asm b/makefile.linux_amd64_asm -index 075c6a8..223559d 100644 ---- a/makefile.linux_amd64_asm -+++ b/makefile.linux_amd64_asm -@@ -11,6 +11,9 @@ ALLFLAGS=-m64 ${OPTFLAGS} -pipe \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -+ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden -+ -+ - CXX=g++ - CC=gcc - CC_SHARED=-fPIC -diff --git a/makefile.linux_x86_asm_gcc_4.X b/makefile.linux_x86_asm_gcc_4.X -index 1ac339b..3b86ccc 100644 ---- a/makefile.linux_x86_asm_gcc_4.X -+++ b/makefile.linux_x86_asm_gcc_4.X -@@ -18,7 +18,7 @@ CXX=g++ - CC=gcc - CC_SHARED=-fPIC - LINK_SHARED=-fPIC -shared --ASM=nasm -f elf -+ASM=yasm -f elf - - PRE_COMPILED_HEADER=StdAfx.h.gch - -diff --git a/makefile.machine b/makefile.machine -index 9e34c34..715e900 100644 ---- a/makefile.machine -+++ b/makefile.machine -@@ -1,6 +1,25 @@ - # - # makefile for Linux (x86, PPC, alpha ...) - # -+ifeq (1,1) # In debian always include the approrpiate makefile -+ -+ ifndef DEBIAN_P7ZIP_MAKEFILE -+ -+ ifeq (i386,$(DEB_HOST_ARCH)) -+ export DEBIAN_P7ZIP_MAKEFILE := makefile.linux_x86_asm_gcc_4.X -+ else -+ ifeq (amd64.64,$(DEB_HOST_ARCH).$(DEB_HOST_ARCH_BITS)) -+ export DEBIAN_P7ZIP_MAKEFILE := makefile.linux_amd64_asm -+ else -+ export DEBIAN_P7ZIP_MAKEFILE := makefile.linux_any_cpu_gcc_4.X # default -+ endif -+ endif -+ -+ endif -+ -+ include $(dir $(lastword $(MAKEFILE_LIST)))/$(DEBIAN_P7ZIP_MAKEFILE) -+ -+else - - OPTFLAGS=-O -s - -@@ -21,3 +40,4 @@ LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - OBJ_CRC32=$(OBJ_CRC32_C) - OBJ_AES= - -+endif diff -Nru p7zip-rar-16.02/debian/patches/05-hardening-flags.patch p7zip-rar-16.02+really25.00+ds/debian/patches/05-hardening-flags.patch --- p7zip-rar-16.02/debian/patches/05-hardening-flags.patch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/05-hardening-flags.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From: Robert Luberda -Date: Fri, 22 Jan 2016 00:53:09 +0100 -Subject: Hardening flags - -Add support for $(CPPFLAGS) and do not override $(CXXFLAGS) -and $(CFLAGS) - -Bug-Debian: https://bugs.debian.org/#682167 ---- - makefile.glb | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/makefile.glb b/makefile.glb -index fb001d5..e10ae03 100644 ---- a/makefile.glb -+++ b/makefile.glb -@@ -1,14 +1,14 @@ - - RM=rm -f - --CFLAGS=-c -I. \ -+CFLAGS+=$(CPPFLAGS) -c -I. \ - -I../../../../C \ - -I../../../../CPP/myWindows \ - -I../../../../CPP/include_windows \ - -I../../../../CPP \ - $(ALLFLAGS) $(ALLFLAGS_C) - --CXXFLAGS=-c -I. \ -+CXXFLAGS+=$(CPPFLAGS) -c -I. \ - -I../../../../C \ - -I../../../../CPP/myWindows \ - -I../../../../CPP/include_windows \ diff -Nru p7zip-rar-16.02/debian/patches/06-CVE-2018-5996.patch p7zip-rar-16.02+really25.00+ds/debian/patches/06-CVE-2018-5996.patch --- p7zip-rar-16.02/debian/patches/06-CVE-2018-5996.patch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/06-CVE-2018-5996.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -From: Robert Luberda -Date: Sun, 28 Jan 2018 23:47:40 +0100 -Subject: CVE-2018-5996 - -Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by -applying a few changes from 7Zip 18.00-beta. - -Bug-Debian: https://bugs.debian.org/#888314 ---- - CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++---- - CPP/7zip/Compress/Rar1Decoder.h | 1 + - CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++- - CPP/7zip/Compress/Rar2Decoder.h | 1 + - CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++--- - CPP/7zip/Compress/Rar3Decoder.h | 2 ++ - 6 files changed, 42 insertions(+), 8 deletions(-) - -diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp -index 1aaedcc..68030c7 100644 ---- a/CPP/7zip/Compress/Rar1Decoder.cpp -+++ b/CPP/7zip/Compress/Rar1Decoder.cpp -@@ -29,7 +29,7 @@ public: - }; - */ - --CDecoder::CDecoder(): m_IsSolid(false) { } -+CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } - - void CDecoder::InitStructures() - { -@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - InitData(); - if (!m_IsSolid) - { -+ _errorMode = false; - InitStructures(); - InitHuff(); - } -+ -+ if (_errorMode) -+ return S_FALSE; -+ - if (m_UnpackSize > 0) - { - GetFlagsBuf(); -@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) - { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } -- catch(const CInBufferException &e) { return e.ErrorCode; } -- catch(const CLzOutWindowException &e) { return e.ErrorCode; } -- catch(...) { return S_FALSE; } -+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(...) { _errorMode = true; return S_FALSE; } - } - - STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h -index 630f089..01b606b 100644 ---- a/CPP/7zip/Compress/Rar1Decoder.h -+++ b/CPP/7zip/Compress/Rar1Decoder.h -@@ -39,6 +39,7 @@ public: - - Int64 m_UnpackSize; - bool m_IsSolid; -+ bool _errorMode; - - UInt32 ReadBits(int numBits); - HRESULT CopyBlock(UInt32 distance, UInt32 len); -diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp -index b3f2b4b..0580c8d 100644 ---- a/CPP/7zip/Compress/Rar2Decoder.cpp -+++ b/CPP/7zip/Compress/Rar2Decoder.cpp -@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; - static const UInt32 kWindowReservSize = (1 << 22) + 256; - - CDecoder::CDecoder(): -- m_IsSolid(false) -+ m_IsSolid(false), -+ m_TablesOK(false) - { - } - -@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB - - bool CDecoder::ReadTables(void) - { -+ m_TablesOK = false; -+ - Byte levelLevels[kLevelTableSize]; - Byte newLevels[kMaxTableSize]; - m_AudioMode = (ReadBits(1) == 1); -@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void) - } - - memcpy(m_LastLevels, newLevels, kMaxTableSize); -+ m_TablesOK = true; -+ - return true; - } - -@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - return S_FALSE; - } - -+ if (!m_TablesOK) -+ return S_FALSE; -+ - UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - while (pos < unPackSize) - { -diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h -index 3a0535c..0e9005f 100644 ---- a/CPP/7zip/Compress/Rar2Decoder.h -+++ b/CPP/7zip/Compress/Rar2Decoder.h -@@ -139,6 +139,7 @@ class CDecoder : - - UInt64 m_PackSize; - bool m_IsSolid; -+ bool m_TablesOK; - - void InitStructures(); - UInt32 ReadBits(unsigned numBits); -diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp -index 3bf2513..6cb8a6a 100644 ---- a/CPP/7zip/Compress/Rar3Decoder.cpp -+++ b/CPP/7zip/Compress/Rar3Decoder.cpp -@@ -92,7 +92,8 @@ CDecoder::CDecoder(): - _writtenFileSize(0), - _vmData(0), - _vmCode(0), -- m_IsSolid(false) -+ m_IsSolid(false), -+ _errorMode(false) - { - Ppmd7_Construct(&_ppmd); - } -@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - return InitPPM(); - } - -+ TablesRead = false; -+ TablesOK = false; -+ - _lzMode = true; - PrevAlignBits = 0; - PrevAlignCount = 0; -@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - } - } - } -+ if (InputEofError()) -+ return S_FALSE; -+ - TablesRead = true; - - // original code has check here: -@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); - - memcpy(m_LastLevels, newLevels, kTablesSizesSum); -+ -+ TablesOK = true; -+ - return S_OK; - } - -@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - PpmEscChar = 2; - PpmError = true; - InitFilters(); -+ _errorMode = false; - } -+ -+ if (_errorMode) -+ return S_FALSE; -+ - if (!m_IsSolid || !TablesRead) - { - bool keepDecompressing; -@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - bool keepDecompressing; - if (_lzMode) - { -+ if (!TablesOK) -+ return S_FALSE; - RINOK(DecodeLZ(keepDecompressing)) - } - else -@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; - return CodeReal(progress); - } -- catch(const CInBufferException &e) { return e.ErrorCode; } -- catch(...) { return S_FALSE; } -+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(...) { _errorMode = true; return S_FALSE; } - // CNewException is possible here. But probably CNewException is caused - // by error in data stream. - } -diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h -index c130cec..2f72d7d 100644 ---- a/CPP/7zip/Compress/Rar3Decoder.h -+++ b/CPP/7zip/Compress/Rar3Decoder.h -@@ -192,6 +192,7 @@ class CDecoder: - UInt32 _lastFilter; - - bool m_IsSolid; -+ bool _errorMode; - - bool _lzMode; - bool _unsupportedFilter; -@@ -200,6 +201,7 @@ class CDecoder: - UInt32 PrevAlignCount; - - bool TablesRead; -+ bool TablesOK; - - CPpmd7 _ppmd; - int PpmEscChar; diff -Nru p7zip-rar-16.02/debian/patches/CVE-2018-10115.patch p7zip-rar-16.02+really25.00+ds/debian/patches/CVE-2018-10115.patch --- p7zip-rar-16.02/debian/patches/CVE-2018-10115.patch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/CVE-2018-10115.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,311 +0,0 @@ -From: Robert Luberda -Date: Tue, 29 May 2018 23:59:09 +0200 -Subject: Fix CVE-2018-10115 - -Apply "patch" taken from https://landave.io/files/patch_7zip_CVE-2018-10115.txt - - -Bugs-Debian: https://bugs.debian.org/897674 ---- - CPP/7zip/Compress/Rar1Decoder.cpp | 16 +++++++++++----- - CPP/7zip/Compress/Rar1Decoder.h | 3 ++- - CPP/7zip/Compress/Rar2Decoder.cpp | 17 +++++++++++++---- - CPP/7zip/Compress/Rar2Decoder.h | 3 ++- - CPP/7zip/Compress/Rar3Decoder.cpp | 19 +++++++++++++++---- - CPP/7zip/Compress/Rar3Decoder.h | 3 ++- - CPP/7zip/Compress/Rar5Decoder.cpp | 8 ++++++++ - CPP/7zip/Compress/Rar5Decoder.h | 1 + - 8 files changed, 54 insertions(+), 16 deletions(-) - -diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp -index 68030c7..8c890c8 100644 ---- a/CPP/7zip/Compress/Rar1Decoder.cpp -+++ b/CPP/7zip/Compress/Rar1Decoder.cpp -@@ -29,7 +29,7 @@ public: - }; - */ - --CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } -+CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false), _errorMode(false) { } - - void CDecoder::InitStructures() - { -@@ -345,7 +345,7 @@ void CDecoder::GetFlagsBuf() - - void CDecoder::InitData() - { -- if (!m_IsSolid) -+ if (!_isSolid) - { - AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; - AvrPlc = 0x3500; -@@ -391,6 +391,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - if (inSize == NULL || outSize == NULL) - return E_INVALIDARG; - -+ if (_isSolid && !_solidAllowed) -+ return S_FALSE; -+ -+ _solidAllowed = false; -+ - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) -@@ -398,13 +403,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - - m_UnpackSize = (Int64)*outSize; - m_OutWindowStream.SetStream(outStream); -- m_OutWindowStream.Init(m_IsSolid); -+ m_OutWindowStream.Init(_isSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - // CCoderReleaser coderReleaser(this); - InitData(); -- if (!m_IsSolid) -+ if (!_isSolid) - { - _errorMode = false; - InitStructures(); -@@ -475,6 +480,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - } - if (m_UnpackSize < 0) - return S_FALSE; -+ _solidAllowed = true; - return m_OutWindowStream.Flush(); - } - -@@ -491,7 +497,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { - if (size < 1) - return E_INVALIDARG; -- m_IsSolid = ((data[0] & 1) != 0); -+ _isSolid = ((data[0] & 1) != 0); - return S_OK; - } - -diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h -index 01b606b..8abb3a3 100644 ---- a/CPP/7zip/Compress/Rar1Decoder.h -+++ b/CPP/7zip/Compress/Rar1Decoder.h -@@ -38,7 +38,8 @@ public: - UInt32 LastLength; - - Int64 m_UnpackSize; -- bool m_IsSolid; -+ bool _isSolid; -+ bool _solidAllowed; - bool _errorMode; - - UInt32 ReadBits(int numBits); -diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp -index 0580c8d..be8d842 100644 ---- a/CPP/7zip/Compress/Rar2Decoder.cpp -+++ b/CPP/7zip/Compress/Rar2Decoder.cpp -@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; - static const UInt32 kWindowReservSize = (1 << 22) + 256; - - CDecoder::CDecoder(): -- m_IsSolid(false), -+ _isSolid(false), -+ _solidAllowed(false), - m_TablesOK(false) - { - } -@@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - if (inSize == NULL || outSize == NULL) - return E_INVALIDARG; - -+ if (_isSolid && !_solidAllowed) -+ return S_FALSE; -+ _solidAllowed = false; -+ - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) -@@ -330,12 +335,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - UInt64 pos = 0, unPackSize = *outSize; - - m_OutWindowStream.SetStream(outStream); -- m_OutWindowStream.Init(m_IsSolid); -+ m_OutWindowStream.Init(_isSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - // CCoderReleaser coderReleaser(this); -- if (!m_IsSolid) -+ if (!_isSolid) - { - InitStructures(); - if (unPackSize == 0) -@@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; - if (!ReadTables()) - return S_FALSE; -+ _solidAllowed = true; - return S_OK; - } - if (!ReadTables()) -@@ -386,6 +392,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - - if (!ReadLastTables()) - return S_FALSE; -+ -+ _solidAllowed = true; -+ - return m_OutWindowStream.Flush(); - } - -@@ -402,7 +411,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { - if (size < 1) - return E_INVALIDARG; -- m_IsSolid = ((data[0] & 1) != 0); -+ _isSolid = ((data[0] & 1) != 0); - return S_OK; - } - -diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h -index 0e9005f..370bce2 100644 ---- a/CPP/7zip/Compress/Rar2Decoder.h -+++ b/CPP/7zip/Compress/Rar2Decoder.h -@@ -138,7 +138,8 @@ class CDecoder : - Byte m_LastLevels[kMaxTableSize]; - - UInt64 m_PackSize; -- bool m_IsSolid; -+ bool _isSolid; -+ bool _solidAllowed; - bool m_TablesOK; - - void InitStructures(); -diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp -index 6cb8a6a..7b85833 100644 ---- a/CPP/7zip/Compress/Rar3Decoder.cpp -+++ b/CPP/7zip/Compress/Rar3Decoder.cpp -@@ -92,7 +92,8 @@ CDecoder::CDecoder(): - _writtenFileSize(0), - _vmData(0), - _vmCode(0), -- m_IsSolid(false), -+ _isSolid(false), -+ _solidAllowed(false), - _errorMode(false) - { - Ppmd7_Construct(&_ppmd); -@@ -821,7 +822,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - { - _writtenFileSize = 0; - _unsupportedFilter = false; -- if (!m_IsSolid) -+ if (!_isSolid) - { - _lzSize = 0; - _winPos = 0; -@@ -840,12 +841,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - if (_errorMode) - return S_FALSE; - -- if (!m_IsSolid || !TablesRead) -+ if (!_isSolid || !TablesRead) - { - bool keepDecompressing; - RINOK(ReadTables(keepDecompressing)); - if (!keepDecompressing) -+ { -+ _solidAllowed = true; - return S_OK; -+ } - } - - for (;;) -@@ -870,6 +874,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - if (!keepDecompressing) - break; - } -+ -+ _solidAllowed = true; -+ - RINOK(WriteBuf()); - UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize)); -@@ -890,6 +897,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - if (!inSize) - return E_INVALIDARG; - -+ if (_isSolid && !_solidAllowed) -+ return S_FALSE; -+ _solidAllowed = false; -+ - if (!_vmData) - { - _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); -@@ -928,7 +939,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) - { - if (size < 1) - return E_INVALIDARG; -- m_IsSolid = ((data[0] & 1) != 0); -+ _isSolid = ((data[0] & 1) != 0); - return S_OK; - } - -diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h -index 2f72d7d..32c8943 100644 ---- a/CPP/7zip/Compress/Rar3Decoder.h -+++ b/CPP/7zip/Compress/Rar3Decoder.h -@@ -191,7 +191,8 @@ class CDecoder: - CRecordVector _tempFilters; - UInt32 _lastFilter; - -- bool m_IsSolid; -+ bool _isSolid; -+ bool _solidAllowed; - bool _errorMode; - - bool _lzMode; -diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp -index dc8830f..a826d5a 100644 ---- a/CPP/7zip/Compress/Rar5Decoder.cpp -+++ b/CPP/7zip/Compress/Rar5Decoder.cpp -@@ -72,6 +72,7 @@ CDecoder::CDecoder(): - _writtenFileSize(0), - _dictSizeLog(0), - _isSolid(false), -+ _solidAllowed(false), - _wasInit(false), - _inputBuf(NULL) - { -@@ -801,7 +802,10 @@ HRESULT CDecoder::CodeReal() - */ - - if (res == S_OK) -+ { -+ _solidAllowed = true; - res = res2; -+ } - - if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize) - return S_FALSE; -@@ -821,6 +825,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - { - try - { -+ if (_isSolid && !_solidAllowed) -+ return S_FALSE; -+ _solidAllowed = false; -+ - if (_dictSizeLog >= sizeof(size_t) * 8) - return E_NOTIMPL; - -diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h -index b0a4dd1..3db5018 100644 ---- a/CPP/7zip/Compress/Rar5Decoder.h -+++ b/CPP/7zip/Compress/Rar5Decoder.h -@@ -271,6 +271,7 @@ class CDecoder: - Byte _dictSizeLog; - bool _tableWasFilled; - bool _isSolid; -+ bool _solidAllowed; - bool _wasInit; - - UInt32 _reps[kNumReps]; diff -Nru p7zip-rar-16.02/debian/patches/series p7zip-rar-16.02+really25.00+ds/debian/patches/series --- p7zip-rar-16.02/debian/patches/series 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/patches/series 2026-03-04 07:03:20.000000000 +0000 @@ -1,5 +1,3 @@ -01-clean-makefile.patch -03-include-linux-makefile.patch -05-hardening-flags.patch -06-CVE-2018-5996.patch -CVE-2018-10115.patch +0001-Accept-Debian-build-flags.patch +0002-Add-RAR-plugin-builder.patch +0003-Add-missing-CRC-table-constructor-Closes-1118733.patch diff -Nru p7zip-rar-16.02/debian/rules p7zip-rar-16.02+really25.00+ds/debian/rules --- p7zip-rar-16.02/debian/rules 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/rules 2026-03-04 07:24:34.000000000 +0000 @@ -1,31 +1,19 @@ #!/usr/bin/make -f -DH_AUTO_OPTIONS := -v -Smakefile --parallel - -export DEB_BUILD_MAINT_OPTIONS=hardening=+all - include /usr/share/dpkg/architecture.mk -ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) - CC := $(DEB_HOST_GNU_TYPE)-gcc - CXX := $(DEB_HOST_GNU_TYPE)-g++ -else - CC := gcc - CXX := g++ -endif +export DEB_BUILD_MAINT_OPTIONS=hardening=+all reproducible=+all %: - dh ${@} - -override_dh_auto_clean: - # Make sure patches are applied otherwise `make clean' fails - # on trying to clean the removed Rar directory (see #769520). - dpkg-source --before-build $(CURDIR) - dh_auto_clean $(DH_AUTO_OPTIONS) -- OPTFLAGS= - rm -rf bin/ + dh $@ override_dh_auto_build: - dh_auto_build $(DH_AUTO_OPTIONS) -- OPTFLAGS= rar + $(MAKE) -C CPP/7zip/Bundles/FormatRAR -f ../../cmpl_gcc.mak \ + CROSS_COMPILE="$(DEB_HOST_GNU_TYPE)-" \ + DEB_CFLAGS="$(CFLAGS) -pipe" \ + DEB_CXXFLAGS="$(CXXFLAGS) -pipe" \ + DEB_CPPFLAGS="$(CPPFLAGS)" \ + DEB_LDFLAGS="$(LDFLAGS) -pipe" -override_dh_auto_install: - dh_install bin/Codecs usr/lib/p7zip +override_dh_auto_clean: + $(MAKE) -C CPP/7zip/Bundles/FormatRAR -f ../../cmpl_gcc.mak clean diff -Nru p7zip-rar-16.02/debian/salsa-ci.yml p7zip-rar-16.02+really25.00+ds/debian/salsa-ci.yml --- p7zip-rar-16.02/debian/salsa-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/salsa-ci.yml 2026-03-04 08:52:01.000000000 +0000 @@ -0,0 +1,3 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml diff -Nru p7zip-rar-16.02/debian/source/include-binaries p7zip-rar-16.02+really25.00+ds/debian/source/include-binaries --- p7zip-rar-16.02/debian/source/include-binaries 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/source/include-binaries 2026-03-04 07:03:20.000000000 +0000 @@ -0,0 +1 @@ +debian/tests/data/data.rar diff -Nru p7zip-rar-16.02/debian/source/options p7zip-rar-16.02+really25.00+ds/debian/source/options --- p7zip-rar-16.02/debian/source/options 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/source/options 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -diff-ignore -tar-ignore diff -Nru p7zip-rar-16.02/debian/tests/control p7zip-rar-16.02+really25.00+ds/debian/tests/control --- p7zip-rar-16.02/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/tests/control 2026-03-04 07:03:20.000000000 +0000 @@ -0,0 +1,14 @@ +# -*- mode: conf -*- + +# Check RAR plugin is really loaded +Features: test-name=rar-plugin-load +Test-Command: 7z i +Restrictions: superficial + +# Check RAR container format support +Features: test-name=rar-list +Test-Command: 7z l debian/tests/data/data.rar + +# Check RAR complession decoder works +Features: test-name=rar-test +Test-Command: 7z t debian/tests/data/data.rar Binary files /srv/release.debian.org/tmp/eDSSfqGOE0/p7zip-rar-16.02/debian/tests/data/data.rar and /srv/release.debian.org/tmp/w3cp4HQ95j/p7zip-rar-16.02+really25.00+ds/debian/tests/data/data.rar differ diff -Nru p7zip-rar-16.02/debian/watch p7zip-rar-16.02+really25.00+ds/debian/watch --- p7zip-rar-16.02/debian/watch 2018-05-30 07:04:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/debian/watch 2026-03-04 20:43:57.000000000 +0000 @@ -1,3 +1,2 @@ +# To ease auditing, please reuse the orig tarball from the 7zip-rar package. version=4 - -https://qa.debian.org/watch/sf.php/p7zip/p7zip_(.*)_src_all.tar.bz2 debian uupdate diff -Nru p7zip-rar-16.02/install.sh p7zip-rar-16.02+really25.00+ds/install.sh --- p7zip-rar-16.02/install.sh 2015-10-05 08:39:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/install.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ -#! /bin/sh - -installShared() -{ - prg=$1 - if [ -x bin/${prg} ] - then - echo "- installing ${DEST_DIR}${DEST_BIN}/${prg}" - cp bin/${prg} "${DEST_DIR}${DEST_SHARE}/${prg}" - chmod 755 "${DEST_DIR}${DEST_SHARE}/${prg}" - strip "${DEST_DIR}${DEST_SHARE}/${prg}" - echo "#! /bin/sh" > "${DEST_DIR}${DEST_BIN}/${prg}" - echo "\"${DEST_SHARE}/${prg}\" \"\$@\"" >> "${DEST_DIR}${DEST_BIN}/${prg}" - chmod 755 "${DEST_DIR}${DEST_BIN}/${prg}" - fi -} - -# global install -DEST_HOME=/usr/local -# for testing -# DEST_HOME=${HOME}/INSTALL/usr/local -DEST_BIN=${DEST_HOME}/bin -DEST_SHARE=${DEST_HOME}/lib/p7zip -DEST_MAN=${DEST_HOME}/man -DEST_SHARE_DOC=${DEST_HOME}/share/doc/p7zip -DEST_DIR= -[ "$1" ] && DEST_BIN="$1" -[ "$2" ] && DEST_SHARE="$2" -[ "$3" ] && DEST_MAN="$3" -[ "$4" ] && DEST_SHARE_DOC="$4" -[ "$5" ] && DEST_DIR="$5" - -umask 0022 - -use_share="n" - -if [ -x bin/7zCon.sfx ] -then - use_share="o" -fi - -if [ -x bin/7z ] -then - use_share="o" -fi - -if [ -x bin/7zG ] -then - use_share="o" -fi - -if [ -x bin/7zFM ] -then - use_share="o" -fi - -# cleaning previous install -rm -f "${DEST_DIR}${DEST_BIN}/7z" -rm -f "${DEST_DIR}${DEST_BIN}/7za" -rm -f "${DEST_DIR}${DEST_BIN}/7zr" -rm -f "${DEST_DIR}${DEST_BIN}/7zG" -rm -f "${DEST_DIR}${DEST_BIN}/p7zipForFilemanager" -rm -f "${DEST_DIR}${DEST_BIN}/7zFM" -rm -f "${DEST_DIR}${DEST_SHARE}/7z" -rm -f "${DEST_DIR}${DEST_SHARE}/7za" -rm -f "${DEST_DIR}${DEST_SHARE}/7zCon.sfx" -rm -f "${DEST_DIR}${DEST_SHARE}/7zr" -rm -f "${DEST_DIR}${DEST_SHARE}/7zG" -rm -f "${DEST_DIR}${DEST_SHARE}/7zFM" -rm -f "${DEST_DIR}${DEST_SHARE}/7z.so" -chmod -R 777 "${DEST_DIR}${DEST_SHARE}/Codecs" 2> /dev/null -chmod -R 777 "${DEST_DIR}${DEST_SHARE}/Formats" 2> /dev/null -rm -fr "${DEST_DIR}${DEST_SHARE}/Codecs" -rm -fr "${DEST_DIR}${DEST_SHARE}/Formats" -rm -fr "${DEST_DIR}${DEST_SHARE}/Lang" -rm -f "${DEST_DIR}${DEST_MAN}/man1/7z.1" -rm -f "${DEST_DIR}${DEST_MAN}/man1/7za.1" -rm -f "${DEST_DIR}${DEST_MAN}/man1/7zr.1" -chmod -R 777 "${DEST_DIR}${DEST_SHARE_DOC}" 2> /dev/null -rm -fr "${DEST_DIR}${DEST_SHARE_DOC}" - -if [ "${use_share}" = "o" ] -then - mkdir -p "${DEST_DIR}${DEST_BIN}" - mkdir -p "${DEST_DIR}${DEST_SHARE}" - installShared 7za - installShared 7zr - installShared 7z - installShared 7zG - installShared 7zFM - - if [ -x bin/7zCon.sfx ] - then - echo "- installing ${DEST_DIR}${DEST_SHARE}/7zCon.sfx" - cp bin/7zCon.sfx "${DEST_DIR}${DEST_SHARE}/7zCon.sfx" - chmod 755 "${DEST_DIR}${DEST_SHARE}/7zCon.sfx" - strip "${DEST_DIR}${DEST_SHARE}/7zCon.sfx" - fi - - if [ -x bin/7z.so ] - then - echo "- installing ${DEST_DIR}${DEST_SHARE}/7z.so" - cp bin/7z.so "${DEST_DIR}${DEST_SHARE}/7z.so" - chmod 755 "${DEST_DIR}${DEST_SHARE}/7z.so" - fi - - if [ -d bin/Codecs ] - then - echo "- installing ${DEST_DIR}${DEST_SHARE}/Codecs" - cp -r bin/Codecs "${DEST_DIR}${DEST_SHARE}/" - chmod 755 "${DEST_DIR}${DEST_SHARE}"/*/* - fi - -else - if [ -x bin/7za ] - then - echo "- installing ${DEST_DIR}${DEST_BIN}/7za" - mkdir -p "${DEST_DIR}${DEST_BIN}" - cp bin/7za "${DEST_DIR}${DEST_BIN}/7za" - chmod 755 "${DEST_DIR}${DEST_BIN}/7za" - strip "${DEST_DIR}${DEST_BIN}/7za" - fi - - if [ -x bin/7zr ] - then - echo "- installing ${DEST_DIR}${DEST_BIN}/7zr" - mkdir -p "${DEST_DIR}${DEST_BIN}" - cp bin/7zr "${DEST_DIR}${DEST_BIN}/7zr" - chmod 755 "${DEST_DIR}${DEST_BIN}/7zr" - strip "${DEST_DIR}${DEST_BIN}/7zr" - fi -fi - -mkdir -p "${DEST_DIR}${DEST_MAN}/man1" -if [ -d DOC ] -then - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7z.1" - sed -e s?"{DEST_SHARE_DOC}"?"${DEST_SHARE_DOC}/DOC"?g man1/7z.1 > "${DEST_DIR}${DEST_MAN}/man1/7z.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7z.1" - - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7za.1" - sed -e s?"{DEST_SHARE_DOC}"?"${DEST_SHARE_DOC}/DOC"?g man1/7za.1 > "${DEST_DIR}${DEST_MAN}/man1/7za.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7za.1" - - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7zr.1" - sed -e s?"{DEST_SHARE_DOC}"?"${DEST_SHARE_DOC}/DOC"?g man1/7zr.1 > "${DEST_DIR}${DEST_MAN}/man1/7zr.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7zr.1" -else - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7z.1" - grep -v "{DEST_SHARE_DOC}" man1/7z.1 > "${DEST_DIR}${DEST_MAN}/man1/7z.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7z.1" - - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7za.1" - grep -v "{DEST_SHARE_DOC}" man1/7za.1 > "${DEST_DIR}${DEST_MAN}/man1/7za.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7za.1" - - echo "- installing ${DEST_DIR}${DEST_MAN}/man1/7zr.1" - grep -v "{DEST_SHARE_DOC}" man1/7zr.1 > "${DEST_DIR}${DEST_MAN}/man1/7zr.1" - chmod 644 "${DEST_DIR}${DEST_MAN}/man1/7zr.1" -fi - -if [ -f README ] -then - echo "- installing ${DEST_DIR}${DEST_SHARE_DOC}/README" - mkdir -p "${DEST_DIR}${DEST_SHARE_DOC}" - cp README "${DEST_DIR}${DEST_SHARE_DOC}/README" - chmod 644 "${DEST_DIR}${DEST_SHARE_DOC}/README" -fi - -if [ -f ChangeLog ] -then - echo "- installing ${DEST_DIR}${DEST_SHARE_DOC}/ChangeLog" - mkdir -p "${DEST_DIR}${DEST_SHARE_DOC}" - cp ChangeLog "${DEST_DIR}${DEST_SHARE_DOC}/ChangeLog" - chmod 644 "${DEST_DIR}${DEST_SHARE_DOC}/ChangeLog" -fi - -if [ -d DOC ] -then - echo "- installing HTML help in ${DEST_DIR}${DEST_SHARE_DOC}/DOC" - mkdir -p "${DEST_DIR}${DEST_SHARE_DOC}" - cp -r DOC "${DEST_DIR}${DEST_SHARE_DOC}/DOC" - find "${DEST_DIR}${DEST_SHARE_DOC}/DOC" -type d -exec chmod 755 {} \; - find "${DEST_DIR}${DEST_SHARE_DOC}/DOC" -type f -exec chmod 644 {} \; -fi - -use_lang="n" - -if [ -x bin/7zG ] -then - use_lang="o" - cp GUI/p7zipForFilemanager "${DEST_DIR}${DEST_BIN}/" - chmod 755 "${DEST_DIR}${DEST_BIN}/" -fi - -if [ -x bin/7zFM ] -then - use_lang="o" -fi - -if [ "${use_lang}" = "o" ] -then - echo "- installing Lang in ${DEST_DIR}${DEST_SHARE}" - cp -r GUI/Lang "${DEST_DIR}${DEST_SHARE}/" - find "${DEST_DIR}${DEST_SHARE}/Lang" -type d -exec chmod 755 {} \; - find "${DEST_DIR}${DEST_SHARE}/Lang" -type f -exec chmod 644 {} \; -fi - diff -Nru p7zip-rar-16.02/install_local_context_menu.sh p7zip-rar-16.02+really25.00+ds/install_local_context_menu.sh --- p7zip-rar-16.02/install_local_context_menu.sh 2011-02-23 20:12:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/install_local_context_menu.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#! /bin/sh - -tryInstall() -{ - prg=$1 - - if [ -d ${HOME}/.kde/share/apps/${prg} ] - then - echo "Installing menus for ${prg} ..." - mkdir -p ${HOME}/.kde/share/apps/${prg}/servicemenus - cp GUI/kde/*.desktop ${HOME}/.kde/share/apps/${prg}/servicemenus/ - fi -} - -tryInstall d3lphin -tryInstall dolphin -tryInstall konqueror - diff -Nru p7zip-rar-16.02/last_error p7zip-rar-16.02+really25.00+ds/last_error --- p7zip-rar-16.02/last_error 2016-05-20 09:39:53.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/last_error 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -ERROR during : make all_test diff -Nru p7zip-rar-16.02/makefile p7zip-rar-16.02+really25.00+ds/makefile --- p7zip-rar-16.02/makefile 2016-02-29 06:28:31.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ - -include makefile.common - -test_lib: common - $(MAKE) -C CPP/myWindows all - -other: common - $(MAKE) -C Utils/CPUTest/MemLat all - $(MAKE) -C Utils/CPUTest/PipeLen all - $(MAKE) -C CPP/7zip/UI/P7ZIP all - $(MAKE) -C CPP/7zip/TEST/TestUI all - -other2: - $(MAKE) -C CPP/7zip/Bundles/AloneGCOV all - -7za: common - $(MAKE) -C CPP/7zip/Bundles/Alone all - -7zr: common - $(MAKE) -C CPP/7zip/Bundles/Alone7z all - -Client7z: common - $(MKDIR) bin/Codecs - $(MAKE) -C CPP/7zip/Bundles/Format7zFree all - $(MAKE) -C CPP/7zip/UI/Client7z all - -depend: - $(MAKE) -C CPP/7zip/Bundles/Alone depend - $(MAKE) -C CPP/7zip/Bundles/Alone7z depend - $(MAKE) -C CPP/7zip/Bundles/SFXCon depend - $(MAKE) -C CPP/7zip/UI/Client7z depend - $(MAKE) -C CPP/7zip/UI/Console depend - $(MAKE) -C CPP/7zip/Bundles/Format7zFree depend - $(MAKE) -C CPP/7zip/Compress/Rar depend - $(MAKE) -C CPP/7zip/UI/GUI depend - $(MAKE) -C CPP/7zip/UI/FileManager depend - -sfx: common - $(MKDIR) bin - $(MAKE) -C CPP/7zip/Bundles/SFXCon all - -common7z:common - $(MKDIR) bin/Codecs - $(MAKE) -C CPP/7zip/Bundles/Format7zFree all - $(MAKE) -C CPP/7zip/Compress/Rar all - -lzham:common - $(MKDIR) bin/Codecs - $(MAKE) -C CPP/7zip/Compress/Lzham all - -7z: common7z - $(MAKE) -C CPP/7zip/UI/Console all - -7zG: common7z LangAndHelp - $(MAKE) -C CPP/7zip/UI/GUI all - -7zFM: common7z LangAndHelp - $(MAKE) -C CPP/7zip/UI/FileManager all - -clean_C: - $(MAKE) -C CPP/myWindows clean - $(MAKE) -C CPP/7zip/Bundles/Alone clean - $(MAKE) -C CPP/7zip/Bundles/Alone7z clean - $(MAKE) -C CPP/7zip/Bundles/SFXCon clean - $(MAKE) -C CPP/7zip/UI/Client7z clean - $(MAKE) -C CPP/7zip/UI/Console clean - $(MAKE) -C CPP/7zip/UI/FileManager clean - $(MAKE) -C CPP/7zip/UI/GUI clean - $(MAKE) -C CPP/7zip/Bundles/Format7zFree clean - $(MAKE) -C CPP/7zip/Compress/Rar clean - $(MAKE) -C CPP/7zip/Compress/Lzham clean - $(MAKE) -C CPP/7zip/Bundles/LzmaCon clean2 - $(MAKE) -C CPP/7zip/Bundles/AloneGCOV clean - $(MAKE) -C CPP/7zip/TEST/TestUI clean - $(MAKE) -C CPP/ANDROID clean - $(MAKE) -C Utils/CPUTest/MemLat clean - $(MAKE) -C Utils/CPUTest/PipeLen clean - $(MAKE) -C CPP/7zip/UI/P7ZIP clean - -LzmaCon: - $(MAKE) -C CPP/7zip/Bundles/LzmaCon - -test_LzmaCon: - $(MAKE) -C CPP/7zip/Bundles/LzmaCon test - diff -Nru p7zip-rar-16.02/makefile.afl p7zip-rar-16.02+really25.00+ds/makefile.afl --- p7zip-rar-16.02/makefile.afl 2015-10-05 13:52:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.afl 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=/home/me/TOOLS/afl-1.94b/afl-g++ -CC=/home/me/TOOLS/afl-1.94b/afl-gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.aix_gcc p7zip-rar-16.02+really25.00+ds/makefile.aix_gcc --- p7zip-rar-16.02/makefile.aix_gcc 2015-09-13 18:13:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.aix_gcc 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for AIX -# tested with AIX 5.3 and g++ 4.1.0 -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.android_arm p7zip-rar-16.02+really25.00+ds/makefile.android_arm --- p7zip-rar-16.02/makefile.android_arm 2016-03-10 20:33:59.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.android_arm 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -# -# makefile for ANDROID (generic ARM) -# -# export NDK= -# tested with android-ndk-r8c-linux-x86 -# - -ANDROID_NDK_HOME=$(NDK) -ANDROID_NDK_BIN=$(ANDROID_NDK_HOME)/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin - -# -fpic -Os -# -fstack-protector -ANDROID_FLAGS=\ - -MMD -MP -MF \ - -fpic -ffunction-sections -funwind-tables -fstack-protector \ - -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ \ - -march=armv5te -mtune=xscale -msoft-float -mthumb -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 \ - -I$(ANDROID_NDK_HOME)/sources/cxx-stl/system/include \ - -I$(ANDROID_NDK_HOME)/platforms/android-3/arch-arm/usr/include \ - -DANDROID -DANDROID_NDK -DNDEBUG \ - -ANDROID_LINK= \ - -Wl,--gc-sections -Wl,-z,nocopyreloc \ - --sysroot=$(NDK)/platforms/android-3/arch-arm \ - -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now \ - -L$(NDK)/platforms/android-3/arch-arm/usr/lib -lstdc++ \ - $(NDK)/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/libsupc++.a \ - -lc -lm - -OPTFLAGS=-O3 -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(ANDROID_FLAGS) \ - $(LOCAL_FLAGS) - -CXX=$(ANDROID_NDK_BIN)/arm-linux-androideabi-g++ -fexceptions -frtti -CC=$(ANDROID_NDK_BIN)/arm-linux-androideabi-gcc -CC_EXE= -fPIE -LINK_EXE=-fPIE -pie # -fPIE -pie : only for executable -CC_SHARED= -fpic -LINK_SHARED=-fpic -shared - -LOCAL_LIBS=$(ANDROID_LINK) -LOCAL_LIBS_DLL=$(LOCAL_LIBS) # -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.beos p7zip-rar-16.02+really25.00+ds/makefile.beos --- p7zip-rar-16.02/makefile.beos 2015-09-13 18:15:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.beos 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -DENV_BEOS \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-nostart - -LOCAL_LIBS=-lbe -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.common p7zip-rar-16.02+really25.00+ds/makefile.common --- p7zip-rar-16.02/makefile.common 2016-05-19 10:20:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.common 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -MKDIR = mkdir -p - -DEST_HOME=/usr/local -DEST_BIN=$(DEST_HOME)/bin -DEST_SHARE=$(DEST_HOME)/lib/p7zip -DEST_SHARE_DOC=$(DEST_HOME)/share/doc/p7zip -DEST_MAN=$(DEST_HOME)/man - -.PHONY: default all all2 7za 7zG 7zFM sfx 7z 7zr Client7z common common7z LangAndHelp tar_bin depend test test_7z test_7zr test_7zG test_Client7z LzmaCon test_LzmaCon all_test app cppcheck lzham test_lib other - -.PHONY: clean clean_full clean_C - -include makefile.machine - -default:7za - -all:7za sfx - -all2: all 7z - -all3: all2 7zr - -all4: all3 Client7z LzmaCon lzham test_lib - -all4bis: all3 Client7z LzmaCon test_lib # lzham not supported on x32 CPU. - -all5: all4 7zG 7zFM - -all6: all5 other - -all_all : all6 - -all_test : test test_7z test_7zr test_LzmaCon test_Client7z - -all_test2 : all_test test_7zG - -common: - $(MKDIR) bin - -app: common 7zFM 7zG 7z sfx - rm -fr p7zip.app - $(MKDIR) p7zip.app - cp -rp GUI/Contents p7zip.app/ - $(MKDIR) p7zip.app/Contents - $(MKDIR) p7zip.app/Contents/MacOS - cp bin/7zFM_do_not_use p7zip.app/Contents/MacOS/ - cp bin/7zG p7zip.app/Contents/MacOS/ - cp bin/7z.so p7zip.app/Contents/MacOS/ - cp bin/7zCon.sfx p7zip.app/Contents/MacOS/ - cp -rp bin/Codecs p7zip.app/Contents/MacOS/ - cp -rp GUI/Lang p7zip.app/Contents/MacOS/ - cp -rp DOC/MANUAL p7zip.app/Contents/MacOS/help - -LangAndHelp: - cd bin ; rm -f Lang ; ln -s ../GUI/Lang . - cd bin ; rm -f help ; ln -s ../DOC/MANUAL help - -clean: clean_C - rm -fr bin - rm -fr p7zip.app - rm -f Lang - rm -fr CPP/7zip/P7ZIP.* - rm -fr CPP/7zip/CMAKE/P7ZIP.* - rm -fr CPP/7zip/PREMAKE/P7ZIP.* - rm -f CPP/7zip/QMAKE/*/*.o - rm -f CPP/7zip/QMAKE/*/Makefile - rm -f CPP/7zip/QMAKE/*/*.pro.user - rm -f CPP/7zip/QMAKE/*/*.x - -find . -name "build*" -exec rm -fr {} \; - -find . -name "*-build-*" -exec rm -fr {} \; - -find . -name "*.user" -exec rm -f {} \; - -find . -name "._*" -exec rm -f {} \; - rm -fr CPP/7zip/ANDROID/libs - rm -fr CPP/7zip/ANDROID/obj - rm -f make.log 1 2 cppcheck.out scan-build.out - rm -f check/7z.so - rm -fr p7zip.app/Contents/MacOS - cd check ; ./clean_all.sh - - -clean_full:clean - find . -name "makefile.depend" -exec rm -f {} \; -exec touch {} \; # empty makefile.depend - find . -name "*~" -exec rm -f {} \; - find . -name "*.orig" -exec rm -fr {} \; # kdiff3 merge - find . -name ".*.swp" -exec rm -f {} \; - find . -name "*.i" -exec rm -f {} \; - find . -name "*.s" -exec rm -f {} \; - find . -name ".DS_Store" -exec rm -f {} \; # MacOSX - find . -name "._*" -exec rm -f {} \; # MacOSX - find . -name "*.pyc" -exec rm -f {} \; - find . -name "*.[ch]" -exec chmod -x {} \; - find . -name "*.cpp" -exec chmod -x {} \; - find . -name "*.asm" -exec chmod -x {} \; - find . -name "makefile*" -exec chmod -x {} \; - chmod -x ChangeLog README TODO man1/* DOC/*.txt - chmod +x contrib/VirtualFileSystemForMidnightCommander/u7z - chmod +x contrib/gzip-like_CLI_wrapper_for_7z/p7zip - chmod +x install.sh check/*.sh - -test: 7za sfx - cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7za" - -test_7z: 7z sfx - cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7z" - -test_7zr: 7zr sfx - cd check ; TOOLS="${TOOLS}" ./check_7zr.sh "`pwd`/../bin/7zr" - -test_7zG: 7zG sfx - cd check ; TOOLS="${TOOLS}" ./check.sh "`pwd`/../bin/7zG" - -test_Client7z: Client7z - cd check ; TOOLS="${TOOLS}" ./check_Client7z.sh "`pwd`/../bin/Client7z" - -install: - ./install.sh $(DEST_BIN) $(DEST_SHARE) $(DEST_MAN) $(DEST_SHARE_DOC) $(DEST_DIR) - -# cppcheck -f : test all flags -cppcheck: - cppcheck --enable=all -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DNDEBUG -D_REENTRANT -DENV_UNIX -D_7ZIP_LARGE_PAGES -DBREAK_HANDLER -DUNICODE -D_UNICODE . 2>&1 | tee -i cppcheck.out - -REP=$(shell pwd) -ARCHIVE=$(shell basename $(REP)) - -.PHONY: tar_all tar_all2 src_7z tar_bin tar_bin2 - -tar_all : clean_full - rm -f ../$(ARCHIVE)_src_all.tar.bz2 - cp makefile.linux_any_cpu makefile.machine - cd .. ; (tar cf - $(ARCHIVE) | bzip2 -9 > $(ARCHIVE)_src_all.tar.bz2) - -tar_all2 : clean_full - rm -f ../$(ARCHIVE)_src_all.tar.bz2 - cp makefile.linux_any_cpu makefile.machine - cd .. ; (tar cf - $(ARCHIVE) | 7za a -mx=9 -tbzip2 -si $(ARCHIVE)_src_all.tar.bz2 ) - -src_7z : clean_full - rm -f ../$(ARCHIVE)_src.7z - cd .. ; 7za a -mx=9 -m0=ppmd:mem=128m:o=32 $(ARCHIVE)_src.7z $(ARCHIVE) - -tar_bin: - rm -f ../$(ARCHIVE)_x86_linux_bin.tar.bz2 - chmod +x install.sh contrib/VirtualFileSystemForMidnightCommander/u7z contrib/gzip-like_CLI_wrapper_for_7z/p7zip - cd .. ; (tar cf - $(ARCHIVE)/bin $(ARCHIVE)/contrib $(ARCHIVE)/man1 $(ARCHIVE)/install.sh $(ARCHIVE)/ChangeLog $(ARCHIVE)/DOC $(ARCHIVE)/README $(ARCHIVE)/TODO | bzip2 -9 > $(ARCHIVE)_x86_linux_bin.tar.bz2) - -tar_bin2: - rm -f ../$(ARCHIVE)_x86_linux_bin.tar.bz2 - chmod +x install.sh contrib/VirtualFileSystemForMidnightCommander/u7z contrib/gzip-like_CLI_wrapper_for_7z/p7zip - cd .. ; (tar cf - $(ARCHIVE)/bin $(ARCHIVE)/contrib $(ARCHIVE)/man1 $(ARCHIVE)/install.sh $(ARCHIVE)/ChangeLog $(ARCHIVE)/DOC $(ARCHIVE)/README $(ARCHIVE)/TODO | 7za a -mx=9 -tbzip2 -si $(ARCHIVE)_x86_linux_bin.tar.bz2) - diff -Nru p7zip-rar-16.02/makefile.crc32 p7zip-rar-16.02+really25.00+ds/makefile.crc32 --- p7zip-rar-16.02/makefile.crc32 2014-12-29 17:27:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.crc32 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - -# CRC32, C version -OBJ_CRC32_C=7zCrcOpt.o # 7zCrc.o - -# CRC32, ASM version -OBJ_CRC32_x86=7zCrcOpt_asm.o # 7zCrc.o -OBJ_CRC32_x86_64=7zCrcOpt_asm.o # 7zCrc.o - diff -Nru p7zip-rar-16.02/makefile.cygwin p7zip-rar-16.02+really25.00+ds/makefile.cygwin --- p7zip-rar-16.02/makefile.cygwin 2015-09-13 18:15:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED= -LINK_SHARED=-shared - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.cygwin64 p7zip-rar-16.02+really25.00+ds/makefile.cygwin64 --- p7zip-rar-16.02/makefile.cygwin64 2015-09-20 07:26:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin64 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -OPTFLAGS=-O -s -m64 - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED= -LINK_SHARED=-shared - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.cygwin64_asm p7zip-rar-16.02+really25.00+ds/makefile.cygwin64_asm --- p7zip-rar-16.02/makefile.cygwin64_asm 2015-09-26 10:09:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin64_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - -OPTFLAGS=-O -s -m64 - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared -ASM=nasm -f win64 -DCYGWIN64 -Dx64 - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -CPU=x64 -OBJ_CRC32=$(OBJ_CRC32_x86_64) -OBJ_AES=AesOpt.o diff -Nru p7zip-rar-16.02/makefile.cygwin_asm p7zip-rar-16.02+really25.00+ds/makefile.cygwin_asm --- p7zip-rar-16.02/makefile.cygwin_asm 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared -ASM=nasm -f gnuwin32 - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.cygwin_clang p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang --- p7zip-rar-16.02/makefile.cygwin_clang 2016-02-17 05:42:18.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -OPTFLAGS=-O - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=clang++ -CC=clang -CC_SHARED= -LINK_SHARED=-shared - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.cygwin_clang_asm p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang_asm --- p7zip-rar-16.02/makefile.cygwin_clang_asm 2016-02-17 05:40:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.cygwin_clang_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ - -OPTFLAGS=-O - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT \ - -DENV_UNIX \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=clang++ -CC=clang -LINK_SHARED=-shared -ASM=nasm -f gnuwin32 - -# Cygwin does not need -ldl -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.djgpp p7zip-rar-16.02+really25.00+ds/makefile.djgpp --- p7zip-rar-16.02/makefile.djgpp 2015-09-13 18:15:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.djgpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# -# makefile for DJGPP -# (available targets for DJGPP : all test clean) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=gpp -CC=gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-lpthread -lsocket -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.djgpp_watt p7zip-rar-16.02+really25.00+ds/makefile.djgpp_watt --- p7zip-rar-16.02/makefile.djgpp_watt 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.djgpp_watt 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -# makefile.djgpp (using DJDEV 2.04, GCC/G++ 4.3.2, BinUtils 2.19, Make 3.81) -# Tested with p7zip 4.61 at http://sourceforge.net/projects/p7zip -# -# Add this via REGEDIT.EXE to Vista SP1 registry (dword, e.g. "128000000"): -# HKLM\System\CurrentControlSet\Control\Wow\DpmiLimit -# -# Needs two libs (N.B. Note that /beta/PTH207B.ZIP is 686+ only !!): -# 1). ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/pth207[bs].zip (297k,728k) -# http://gd.tuwien.ac.at/pc/dos/djgpp/current/v2gnu/ (faster URL) -# 2). http://www.bgnett.no/~giva/watt32s-2.2-dev.10.zip (2.3 MB) -# -# How to build: "cp makefile.djgpp makefile.machine ; make" -# Available targets (.EXEs) for DJGPP: 7za 7zr sfx -# -# P.S. "upx --best --lzma --all-filters bin/*" -# http://rugxulo.googlepages.com/upx303c.txt (how to compile UPX-UCL) - -ifeq ($(WATT_ROOT),) -$(error Please set WATT_ROOT env. var. first!) -endif - -#OPTFLAGS=-O -s -OPTIMIZE=-Os -mtune=i686 -fomit-frame-pointer -s -OPTFLAGS=$(OPTIMIZE) -I$(WATT_ROOT)/inc -L$(WATT_ROOT)/lib - -ALLFLAGS=$(OPTFLAGS) \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=gpp -CC=gcc -#LINK_SHARED=-shared -LINK_SHARED= - -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -#LOCAL_LIBS=-lpthread -lsocket -LOCAL_LIBS=-lpthread -lwatt - -#OBJ_CRC32=$(OBJ_CRC32_C) - -ASM=yasm -f coff -#ASM=nasm -f coff -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.freebsd5 p7zip-rar-16.02+really25.00+ds/makefile.freebsd5 --- p7zip-rar-16.02/makefile.freebsd5 2015-09-13 18:16:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.freebsd5 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -# -# makefile for FreeBSD 5 (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-lc_r -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.freebsd6+ p7zip-rar-16.02+really25.00+ds/makefile.freebsd6+ --- p7zip-rar-16.02/makefile.freebsd6+ 2016-03-02 04:06:57.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.freebsd6+ 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -# -# makefile for FreeBSD 6, 7, 8, 9, 10, ... (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.glb p7zip-rar-16.02+really25.00+ds/makefile.glb --- p7zip-rar-16.02/makefile.glb 2016-03-10 20:20:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.glb 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ - -RM=rm -f - -CFLAGS=-c -I. \ --I../../../../C \ --I../../../../CPP/myWindows \ --I../../../../CPP/include_windows \ --I../../../../CPP \ -$(ALLFLAGS) $(ALLFLAGS_C) - -CXXFLAGS=-c -I. \ --I../../../../C \ --I../../../../CPP/myWindows \ --I../../../../CPP/include_windows \ --I../../../../CPP \ -$(ALLFLAGS) $(ALLFLAGS_CPP) - - -PCH_NAME=$(PRE_COMPILED_HEADER) - - -include makefile.list -include makefile.depend - -$(PROG): $(OBJS) - $(CXX) $(ALLFLAGS) $(ALLFLAGS_CPP) $(LOCAL_LINK) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIBS) - -debug: - @echo "LOCAL_FLAGS=$(LOCAL_FLAGS)" - @echo "ALLFLAGS=$(ALLFLAGS)" - -depend: - rm -f makefile.depend - $(CXX) -MM $(CXXFLAGS) $(SRCS) > makefile.depend - -# $(CC) $(DFLAGS) $(SRCS_C) >> makefile.depend - -clean: - -@$(RM) $(PROG) core *.exe *.o *~ .*.swp *.orig *.gch $(PROGS) - -@$(RM) -fr SunWS_cache/ - -@$(RM) -r .inslog2 pchdir/ tca.map ir.out - -@$(RM) make.log tags 1 2 - -# CRC32, ASM version -7zCrcOpt_asm.o : ../../../../Asm/x86/7zCrcOpt_asm.asm - $(ASM) -I ../../../../Asm/x86/ ../../../../Asm/x86/7zCrcOpt_asm.asm -o 7zCrcOpt_asm.o -AesOpt.o : ../../../../Asm/x86/AesOpt.asm - $(ASM) -I ../../../../Asm/x86/ ../../../../Asm/x86/AesOpt.asm -o AesOpt.o diff -Nru p7zip-rar-16.02/makefile.gprof p7zip-rar-16.02+really25.00+ds/makefile.gprof --- p7zip-rar-16.02/makefile.gprof 2015-01-11 16:29:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.gprof 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ - -OPTFLAGS=-O -g -pg -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl -# static linkage -# LOCAL_LIBS=-static -lpthread - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.haiku p7zip-rar-16.02+really25.00+ds/makefile.haiku --- p7zip-rar-16.02/makefile.haiku 2015-09-29 21:34:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.haiku 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -DENV_BEOS -DENV_HAIKU \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-nostart - -LOCAL_LIBS=-lbe -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.hpux-acc p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc --- p7zip-rar-16.02/makefile.hpux-acc 2015-01-11 16:29:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -OPTFLAGS=-O - -ALLFLAGS=${OPTFLAGS} -mt -DD64 +Z +Ww2101 \ --D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ --DNDEBUG -D_REENTRANT -DENV_UNIX \ -$(LOCAL_FLAGS) - -CXX=aCC -AA -CC=aCC -Ae - -LINK_SHARED=-b -LOCAL_LIBS= -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.hpux-acc_64 p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc_64 --- p7zip-rar-16.02/makefile.hpux-acc_64 2015-01-11 16:29:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.hpux-acc_64 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ - -# build 64 bits program (Tested on HPUX with Itanium CPU) - -OPTFLAGS=-O - -ALLFLAGS=${OPTFLAGS} -mt +DD64 +Z +Ww2101 \ --D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ --DNDEBUG -D_REENTRANT -DENV_UNIX \ -$(LOCAL_FLAGS) - -CXX=aCC -AA -CC=aCC -Ae - -LINK_SHARED=-b -LOCAL_LIBS= -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.hpux-gcc p7zip-rar-16.02+really25.00+ds/makefile.hpux-gcc --- p7zip-rar-16.02/makefile.hpux-gcc 2015-09-13 18:16:52.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.hpux-gcc 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# -# makefile for HP-UX 11 -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_amd64 p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64 --- p7zip-rar-16.02/makefile.linux_amd64 2015-09-13 18:17:02.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ - -OPTFLAGS=-O -s - -# use "-m32" to have a 32bits executable -ALLFLAGS=-m64 ${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_amd64_asm p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm --- p7zip-rar-16.02/makefile.linux_amd64_asm 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ - - -# OPTFLAGS=-Ofast -flto -march=native -funroll-loops -s -OPTFLAGS=-O -s - -# use "-m32" to have a 32bits executable -ALLFLAGS=-m64 ${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=yasm -f elf -m amd64 -Dx64 - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x64 -OBJ_CRC32=$(OBJ_CRC32_x86_64) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_amd64_asm_icc p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm_icc --- p7zip-rar-16.02/makefile.linux_amd64_asm_icc 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_asm_icc 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -# -# makefile for Linux (x86_64) -# - -# OPTFLAGS=-fast -msse3 -s -OPTFLAGS=-m64 -O2 -march=core2 # -ipo # -no-gcc - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=icpc -i-static -CC=icc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=yasm -f elf -m amd64 -Dx64 - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x64 -OBJ_CRC32=$(OBJ_CRC32_x86_64) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_amd64_sanitizer p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_sanitizer --- p7zip-rar-16.02/makefile.linux_amd64_sanitizer 2015-10-04 09:38:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_amd64_sanitizer 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-g2 -fsanitize=address -fno-omit-frame-pointer -# OPTFLAGS=-g2 -fsanitize=thread -fno-omit-frame-pointer -#OPTFLAGS=-g2 -fsanitize=undefined -ftrapv -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fno-omit-frame-pointer - -ALLFLAGS=${OPTFLAGS} -pipe \ - -DDONT_REDEFINE_NEW \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_any_cpu p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu --- p7zip-rar-16.02/makefile.linux_any_cpu 2015-09-13 18:17:40.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_any_cpu_gcc_4.X p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu_gcc_4.X --- p7zip-rar-16.02/makefile.linux_any_cpu_gcc_4.X 2015-09-13 18:17:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_any_cpu_gcc_4.X 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_clang_amd64_asm p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm --- p7zip-rar-16.02/makefile.linux_clang_amd64_asm 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -OPTFLAGS=-O3 - -ALLFLAGS=-m64 ${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=clang++ -CC=clang -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=yasm -f elf -m amd64 -Dx64 - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-s -lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x64 -OBJ_CRC32=$(OBJ_CRC32_x86_64) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_clang_amd64_asm_sanitize p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm_sanitize --- p7zip-rar-16.02/makefile.linux_clang_amd64_asm_sanitize 2015-10-17 20:52:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_clang_amd64_asm_sanitize 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - -OPTFLAGS=-g2 -fsanitize=undefined -ftrapv -fsanitize=address -fno-omit-frame-pointer -fno-sanitize=alignment - - -ALLFLAGS=-m64 ${OPTFLAGS} -pipe \ - -DDONT_REDEFINE_NEW \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=clang++ -CC=clang -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=yasm -f elf -m amd64 -Dx64 - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-s -lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x64 -OBJ_CRC32=$(OBJ_CRC32_x86_64) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_cross_aarch64 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_aarch64 --- p7zip-rar-16.02/makefile.linux_cross_aarch64 2015-09-13 18:18:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_aarch64 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS ARM) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=aarch64-linux-gnu-g++ -CC=aarch64-linux-gnu-gcc -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-aarch64 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 --library-path /usr/aarch64-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_arm p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_arm --- p7zip-rar-16.02/makefile.linux_cross_arm 2015-09-13 18:18:14.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_arm 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS ARM) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=arm-linux-gnueabi-g++ -CC=arm-linux-gnueabi-gcc -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-arm /usr/arm-linux-gnueabi/lib/ld-linux.so.3 --library-path /usr/arm-linux-gnueabi/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_djgpp p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_djgpp --- p7zip-rar-16.02/makefile.linux_cross_djgpp 2016-02-17 20:16:53.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_djgpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# makefile for DJGPP -# (available targets for DJGPP : all test clean) -# -# -# export DJGPP_HOME=/home/me/djgpp -# - - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -I${DJGPP_HOME}/include \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=${DJGPP_HOME}/bin/i586-pc-msdosdjgpp-g++ -CC=${DJGPP_HOME}/bin/i586-pc-msdosdjgpp-gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-L${DJGPP_HOME}/lib -lpthread -lsocket -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_m68k p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_m68k --- p7zip-rar-16.02/makefile.linux_cross_m68k 2016-03-02 21:39:21.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_m68k 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# -# makefile for Linux (CROSS M68K) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -# qemu support only ColdFire CPU ? -CXX=m68k-linux-gnu-g++ -mcpu=5206 -msoft-float -CC=m68k-linux-gnu-gcc -mcpu=5206 -msoft-float -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-m68k /usr/m68k-linux-gnu/lib/ld.so.1 --library-path /usr/m68k-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_mipsel p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_mipsel --- p7zip-rar-16.02/makefile.linux_cross_mipsel 2016-03-02 05:48:00.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_mipsel 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# makefile for Linux (CROSS MIPSEL) -# -# - - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=mipsel-linux-gnu-g++ -CC=mipsel-linux-gnu-gcc -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-mipsel /usr/mipsel-linux-gnu/lib/ld.so.1 --library-path /usr/mipsel-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_ppc p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc --- p7zip-rar-16.02/makefile.linux_cross_ppc 2015-09-13 18:18:22.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS ARM) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=powerpc-linux-gnu-g++ -CC=powerpc-linux-gnu-gcc -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-ppc /usr/powerpc-linux-gnu/lib/ld.so.1 --library-path /usr/powerpc-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_ppc64 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64 --- p7zip-rar-16.02/makefile.linux_cross_ppc64 2015-09-13 18:18:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS ARM) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=powerpc-linux-gnu-g++ -m64 -CC=powerpc-linux-gnu-gcc -m64 -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-ppc64 /usr/powerpc-linux-gnu/lib64/ld64.so.1 --library-path /usr/powerpc-linux-gnu/lib64 - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_ppc64le p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64le --- p7zip-rar-16.02/makefile.linux_cross_ppc64le 2015-09-13 18:18:36.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_ppc64le 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS ARM) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=powerpc64le-linux-gnu-g++ -m64 -CC=powerpc64le-linux-gnu-gcc -m64 -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-ppc64le /usr/powerpc64le-linux-gnu/lib/ld64.so.2 --library-path /usr/powerpc64le-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_s390x p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_s390x --- p7zip-rar-16.02/makefile.linux_cross_s390x 2016-03-02 07:09:58.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_s390x 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS s390x) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=s390x-linux-gnu-g++ -m64 -CC=s390x-linux-gnu-gcc -m64 -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-s390x /usr/s390x-linux-gnu/lib/ld64.so.1 --library-path /usr/s390x-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_cross_sparc64 p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_sparc64 --- p7zip-rar-16.02/makefile.linux_cross_sparc64 2016-03-02 07:04:27.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_cross_sparc64 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (CROSS SPARC64) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=sparc64-linux-gnu-g++ -CC=sparc64-linux-gnu-gcc -CC_SHARED=-fPIC -DPIC -LINK_SHARED=-fPIC -DPIC -shared - -TOOLS=qemu-sparc64 /usr/sparc64-linux-gnu/lib/ld-linux.so.2 --library-path /usr/sparc64-linux-gnu/lib - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_gcc6_sanitize p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc6_sanitize --- p7zip-rar-16.02/makefile.linux_gcc6_sanitize 2016-05-19 10:51:30.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc6_sanitize 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O3 -fsanitize=undefined -fsanitize=bounds-strict -Wshift-overflow=2 -fdelete-null-pointer-checks -Wnull-dereference -fsanitize=bounds-strict -fno-sanitize=alignment - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++-6 -CC=gcc-6 -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_gcc_2.95_no_need_for_libstdc p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc_2.95_no_need_for_libstdc --- p7zip-rar-16.02/makefile.linux_gcc_2.95_no_need_for_libstdc 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_gcc_2.95_no_need_for_libstdc 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - -OPTFLAGS=-O2 -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=gcc -CC=gcc -LINK_SHARED=-shared -ASM=nasm -f elf - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_other p7zip-rar-16.02+really25.00+ds/makefile.linux_other --- p7zip-rar-16.02/makefile.linux_other 2015-09-13 18:18:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_other 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# makefile for Linux (other) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=/home/me/BUILDROOT/buildroot-2010.11/output/staging/usr/bin/i386-unknown-linux-uclibc-g++ -CC=/home/me/BUILDROOT/buildroot-2010.11/output/staging/usr/bin/i386-unknown-linux-uclibc-gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -#LOCAL_LIBS=-L,/home/me/BUILDROOT/buildroot-2010.11/output/staging/usr/lib -Wl,-rpath,/home/me/BUILDROOT/buildroot-2010.11/output/staging/usr/lib -lpthread -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_s390x p7zip-rar-16.02+really25.00+ds/makefile.linux_s390x --- p7zip-rar-16.02/makefile.linux_s390x 2015-09-13 18:18:56.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_s390x 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# makefile for Linux (IBM z/Series Mainframe with s390x CPU) -# -# tested under SUSE Enterprise Linux 10 - -OPTFLAGS=-O -m31 -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_scan-build p7zip-rar-16.02+really25.00+ds/makefile.linux_scan-build --- p7zip-rar-16.02/makefile.linux_scan-build 2015-09-20 17:22:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_scan-build 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -#OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -#CXX=g++ -#CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_valgrind p7zip-rar-16.02+really25.00+ds/makefile.linux_valgrind --- p7zip-rar-16.02/makefile.linux_valgrind 2015-09-19 09:12:42.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_valgrind 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-g1 - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -TOOLS=valgrind --tool=memcheck --leak-check=full --show-reachable=yes --log-file="/tmp/traces_valgrind/valgrind_%p" - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_x32 p7zip-rar-16.02+really25.00+ds/makefile.linux_x32 --- p7zip-rar-16.02/makefile.linux_x32 2015-09-13 18:19:06.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x32 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ - -OPTFLAGS=-O -s - -# use "-m32" to have a 32bits executable -ALLFLAGS=-mx32 ${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.linux_x86_asm_gcc_4.X p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X --- p7zip-rar-16.02/makefile.linux_x86_asm_gcc_4.X 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -# OPTFLAGS=-mfpmath=sse -Ofast -flto -march=native -funroll-loops -s -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe -m32 \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=nasm -f elf - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_x86_asm_gcc_4.X_fltk p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X_fltk --- p7zip-rar-16.02/makefile.linux_x86_asm_gcc_4.X_fltk 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_4.X_fltk 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -m32 -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX -DUSE_FLTK \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden `fltk-config --cxxflags` - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=nasm -f elf - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lpthread `fltk-config --ldflags` -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_x86_asm_gcc_mudflap_4.X p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_mudflap_4.X --- p7zip-rar-16.02/makefile.linux_x86_asm_gcc_mudflap_4.X 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_gcc_mudflap_4.X 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-g2 - -ALLFLAGS=${OPTFLAGS} -m32 -pipe -pthread -fmudflapth \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=nasm -f elf - -PRE_COMPILED_HEADER=StdAfx.h.gch - -LOCAL_LIBS=-lmudflapth -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_x86_asm_icc p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_icc --- p7zip-rar-16.02/makefile.linux_x86_asm_icc 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_asm_icc 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -# OPTFLAGS=-fast -msse3 -s -OPTFLAGS=-O2 -msse2 -s -Wcheck -fstack-security-check - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=icpc -i-static -CC=icc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=nasm -f elf - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.linux_x86_icc p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_icc --- p7zip-rar-16.02/makefile.linux_x86_icc 2015-01-11 16:33:54.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.linux_x86_icc 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -# OPTFLAGS=-fast -msse3 -s -OPTFLAGS=-O2 -msse2 -s -Wcheck -fstack-security-check - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=icpc -i-static -CC=icc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared -ASM=nasm -f elf - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.machine p7zip-rar-16.02+really25.00+ds/makefile.machine --- p7zip-rar-16.02/makefile.machine 2016-07-14 09:29:31.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.machine 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Linux (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} -pipe \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_LARGE_PAGES \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.macosx_gcc_32bits p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits --- p7zip-rar-16.02/makefile.macosx_gcc_32bits 2015-01-11 16:34:08.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -OPTFLAGS=-O - -# don't use -DNDEBUG in order to use MacOSX wxWidgets - -ALLFLAGS=-m32 ${OPTFLAGS} \ - -DENV_MACOSX \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=c++ -CC=cc -LINK_SHARED=-bundle - -LOCAL_LIBS=-framework CoreFoundation -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.macosx_gcc_32bits_asm p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_asm --- p7zip-rar-16.02/makefile.macosx_gcc_32bits_asm 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_asm 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -OPTFLAGS=-O - -# don't use -DNDEBUG in order to use MacOSX wxWidgets - -ALLFLAGS=${OPTFLAGS} \ - -mmacosx-version-min=10.4 -arch i386 \ - -DENV_MACOSX \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -D_REENTRANT -DENV_UNIX \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=c++ -CC=cc -LINK_SHARED=-bundle -ASM=nasm -f macho - -LOCAL_LIBS=-framework CoreFoundation -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - diff -Nru p7zip-rar-16.02/makefile.macosx_gcc_32bits_ppc p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_ppc --- p7zip-rar-16.02/makefile.macosx_gcc_32bits_ppc 2015-01-11 16:34:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_32bits_ppc 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - -OPTFLAGS=-O - -# don't use -DNDEBUG in order to use MacOSX wxWidgets - -ALLFLAGS= ${OPTFLAGS} \ - -mmacosx-version-min=10.4 -arch ppc \ - -DENV_MACOSX \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=c++ -CC=cc -LINK_SHARED=-bundle - -LOCAL_LIBS=-framework CoreFoundation -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.macosx_gcc_64bits p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_64bits --- p7zip-rar-16.02/makefile.macosx_gcc_64bits 2015-01-11 16:34:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.macosx_gcc_64bits 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -OPTFLAGS=-O - -# don't use -DNDEBUG in order to use MacOSX wxWidgets - -ALLFLAGS=-m64 ${OPTFLAGS} \ - -DENV_MACOSX \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=c++ -CC=cc -LINK_SHARED=-bundle - -LOCAL_LIBS=-framework CoreFoundation -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.macosx_llvm_64bits p7zip-rar-16.02+really25.00+ds/makefile.macosx_llvm_64bits --- p7zip-rar-16.02/makefile.macosx_llvm_64bits 2015-06-13 14:40:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.macosx_llvm_64bits 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - -OPTFLAGS=-O - -# don't use -DNDEBUG in order to use MacOSX wxWidgets - -ALLFLAGS=-m64 ${OPTFLAGS} \ - -DENV_MACOSX \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -# For old Mac OS X : -# CXX=/Developer/usr/bin/llvm-g++ -# CC=/Developer/usr/bin/llvm-gcc - -# For new Mac OS X : -XX=/usr/bin/llvm-g++ -CC=/usr/bin/llvm-gcc - -LINK_SHARED=-bundle - -LOCAL_LIBS=-framework CoreFoundation -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.netbsd p7zip-rar-16.02+really25.00+ds/makefile.netbsd --- p7zip-rar-16.02/makefile.netbsd 2015-09-13 18:19:46.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.netbsd 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# -# NetBSD >= 1.5.2 (which has no libc_r -- use libpthread) -# makefile for NetBSD (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -LINK_SHARED=-shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.netware_asm_gcc_3.X p7zip-rar-16.02+really25.00+ds/makefile.netware_asm_gcc_3.X --- p7zip-rar-16.02/makefile.netware_asm_gcc_3.X 2015-09-19 09:49:28.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.netware_asm_gcc_3.X 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# -# makefile for NetWare cross-gcc (x86) -# - -CROSSPREFIX=i586-netware- -BINSUFFIX=.nlm - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX -D__NETWARE__ -D_POSIX_SOURCE \ - -fpcc-struct-return \ - -D_7ZIP_ASM \ - $(LOCAL_FLAGS) - -CXX=$(CROSSPREFIX)g++ -CC=$(CROSSPREFIX)gcc -# LINK_SHARED=-shared -ASM=nasm -f elf -AWK=gawk - -LOCAL_LIBS= -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -CPU=x86 -OBJ_CRC32=$(OBJ_CRC32_x86) -OBJ_AES=AesOpt.o - -VERSION_INPUT=../../../7zip/MyVersion.h -P7ZIP_VERSION_AWK='/^\#define MY_VERSION /{gsub("\"","",$$3);print $$3}' -P7ZIP_VERSION=$(shell $(AWK) $(P7ZIP_VERSION_AWK) $(VERSION_INPUT)) -P7ZIP_COPYRIGHT_AWK='/^\#define MY_COPYRIGHT/{gsub($$1" "$$2" ","",$$0);print $$0}' -P7ZIP_COPYRIGHT=$(shell $(AWK) $(P7ZIP_COPYRIGHT_AWK) $(VERSION_INPUT)) - -LDFLAGS=-Wl,--nlm-description="7-Zip $(P7ZIP_VERSION) File Archiver (gcc build)" -LDFLAGS+=-Wl,--nlm-copyright=$(P7ZIP_COPYRIGHT) -LDFLAGS+=-Wl,--nlm-version=$(P7ZIP_VERSION) -LDFLAGS+=-Wl,--nlm-kernelspace -# LDFLAGS+=-Wl,--nlm-posixflag -LDFLAGS+=-Wl,--nlm-flag-off=2 - - diff -Nru p7zip-rar-16.02/makefile.oldmake p7zip-rar-16.02+really25.00+ds/makefile.oldmake --- p7zip-rar-16.02/makefile.oldmake 2016-02-29 06:33:04.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.oldmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ - -include makefile.common - -test_lib: common - cd CPP/myWindows ; $(MAKE) all - -other: common - cd Utils/CPUTest/MemLat ; $(MAKE) all - cd Utils/CPUTest/PipeLen ; $(MAKE) all - cd CPP/7zip/UI/P7ZIP ; $(MAKE) all - cd CPP/7zip/TEST/TestUI ; $(MAKE) all - -other2: - cd CPP/7zip/Bundles/AloneGCOV ; $(MAKE) all - -7za: common - cd CPP/7zip/Bundles/Alone ; $(MAKE) all - -7zr: common - cd CPP/7zip/Bundles/Alone7z ; $(MAKE) all - -Client7z: common - $(MKDIR) bin/Codecs - cd CPP/7zip/Bundles/Format7zFree ; $(MAKE) all - cd CPP/7zip/UI/Client7z ; $(MAKE) all - -depend: - cd CPP/7zip/Bundles/Alone ; $(MAKE) depend - cd CPP/7zip/Bundles/Alone7z ; $(MAKE) depend - cd CPP/7zip/Bundles/SFXCon ; $(MAKE) depend - cd CPP/7zip/UI/Client7z ; $(MAKE) depend - cd CPP/7zip/UI/Console ; $(MAKE) depend - cd CPP/7zip/Bundles/Format7zFree ; $(MAKE) depend - cd CPP/7zip/Compress/Rar ; $(MAKE) depend - cd CPP/7zip/UI/GUI ; $(MAKE) depend - cd CPP/7zip/UI/FileManager ; $(MAKE) depend - -sfx: common - $(MKDIR) bin - cd CPP/7zip/Bundles/SFXCon ; $(MAKE) all - -common7z:common - $(MKDIR) bin/Codecs - cd CPP/7zip/Bundles/Format7zFree ; $(MAKE) all - cd CPP/7zip/Compress/Rar ; $(MAKE) all - -lzham:common - $(MKDIR) bin/Codecs - cd CPP/7zip/Compress/Lzham all - -7z: common7z - cd CPP/7zip/UI/Console ; $(MAKE) all - -7zG: common7z LangAndHelp - cd CPP/7zip/UI/GUI ; $(MAKE) all - -7zFM: common7z LangAndHelp - cd CPP/7zip/UI/FileManager ; $(MAKE) all - -clean_C: - cd CPP/myWindows ; $(MAKE) clean - cd CPP/7zip/Bundles/Alone ; $(MAKE) clean - cd CPP/7zip/Bundles/Alone7z ; $(MAKE) clean - cd CPP/7zip/Bundles/SFXCon ; $(MAKE) clean - cd CPP/7zip/UI/Client7z ; $(MAKE) clean - cd CPP/7zip/UI/Console ; $(MAKE) clean - cd CPP/7zip/UI/FileManager ; $(MAKE) clean - cd CPP/7zip/UI/GUI ; $(MAKE) clean - cd CPP/7zip/Bundles/Format7zFree ; $(MAKE) clean - cd CPP/7zip/Compress/Rar ; $(MAKE) clean - cd CPP/7zip/Compress/Lzham ; $(MAKE) clean - cd CPP/7zip/Bundles/LzmaCon ; $(MAKE) clean2 - cd CPP/7zip/Bundles/AloneGCOV ; $(MAKE) clean - cd CPP/7zip/TEST/TestUI ; $(MAKE) clean - cd CPP/ANDROID ; $(MAKE) clean - cd Utils/CPUTest/MemLat ; $(MAKE) clean - cd Utils/CPUTest/PipeLen ; $(MAKE) clean - cd CPP/7zip/UI/P7ZIP ; $(MAKE) clean - -LzmaCon: - cd CPP/7zip/Bundles/LzmaCon ; $(MAKE) - -test_LzmaCon: - cd CPP/7zip/Bundles/LzmaCon ; $(MAKE) test - diff -Nru p7zip-rar-16.02/makefile.openbsd p7zip-rar-16.02+really25.00+ds/makefile.openbsd --- p7zip-rar-16.02/makefile.openbsd 2016-06-11 17:11:55.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.openbsd 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# makefile for OpenBSD (x86, PPC, alpha ...) -# - -MYCFLAGS?=-O -MYCXXFLAGS?=-O - -ALLFLAGS=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX -fPIC \ - $(LOCAL_FLAGS) - -ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden - -CXX=$(MYCXX) $(MYCXXFLAGS) -CC=$(MYCC) $(MYCFLAGS) -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.openbsd_no_port p7zip-rar-16.02+really25.00+ds/makefile.openbsd_no_port --- p7zip-rar-16.02/makefile.openbsd_no_port 2016-06-11 17:11:37.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.openbsd_no_port 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -# -# makefile for OpenBSD (x86, PPC, alpha ...) -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -ALLFLAGS_CPP=-DENV_HAVE_GCCVISIBILITYPATCH -fvisibility=hidden -fvisibility-inlines-hidden - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.qnx_shared.bin p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.bin --- p7zip-rar-16.02/makefile.qnx_shared.bin 2015-09-13 18:20:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.bin 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -################################################### -# makefile.machine for "7z , 7za , 7zr , 7zCon.sfx " : -# tested with p7zip-4.47_beta on qnx-6.3.0 sp3 x86 target - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=QCC -V3.3.5,gcc_ntox86 -CC=qcc -V3.3.5,gcc_ntox86 -LINK_SHARED=-shared - -#LOCAL_LIBS=-lpthread -#LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.qnx_shared.so p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.so --- p7zip-rar-16.02/makefile.qnx_shared.so 2015-09-13 18:20:16.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.qnx_shared.so 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -################################################### -# makefile.machine for "7z.so , Codecs/Rar.so" : -# tested with p7zip-4.47_beta on qnx-6.3.0 sp3 x86 target - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=QCC -V3.3.5,gcc_ntox86 -CC=qcc -V3.3.5,gcc_ntox86 -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -#LOCAL_LIBS=-lpthread -#LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.qnx_static p7zip-rar-16.02+really25.00+ds/makefile.qnx_static --- p7zip-rar-16.02/makefile.qnx_static 2015-09-13 18:20:20.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.qnx_static 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -################################################## -# makefile.machine for "static 7za 7zr 7zCon.sfx" : -# tested with p7zip-4.47_beta on qnx-6.3.0 sp3 x86 target - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) -Bstatic - -CXX=QCC -V3.3.5,gcc_ntox86 -CC=qcc -V3.3.5,gcc_ntox86 -LINK_SHARED=-Bstatic - -#LOCAL_LIBS=-lpthread -#LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl -LOCAL_LIBS_DLL=$(LOCAL_LIBS) - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.solaris_sparc_CC_32 p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_32 --- p7zip-rar-16.02/makefile.solaris_sparc_CC_32 2015-09-13 18:20:26.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_32 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - -OPTFLAGS=-fast -s - -ALLFLAGS=${OPTFLAGS} -mt \ - -DHAVE_LONG_LONG \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DENV_UNIX \ - -DNDEBUG -D_REENTRANT \ - $(LOCAL_FLAGS) - -CXX=CC -CC=cc -CC_SHARED=-KPIC -LINK_SHARED=-KPIC -G - -# -lCrun : standard C++ library (for new/delete) -LOCAL_LIBS=-lpthread -lCrun -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.solaris_sparc_CC_64 p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_64 --- p7zip-rar-16.02/makefile.solaris_sparc_CC_64 2015-09-13 18:20:32.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_CC_64 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ - -#-fast -xarch=v9 => 64 bits -# use "isainfo -v" to set the flag "-xarch" - -OPTFLAGS=-fast -xarch=v9 -s - -ALLFLAGS=${OPTFLAGS} -mt \ - -DHAVE_LONG_LONG \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DENV_UNIX \ - -DNDEBUG -D_REENTRANT \ - $(LOCAL_FLAGS) - -CXX=CC -CC=cc -CC_SHARED=-KPIC -LINK_SHARED=-KPIC -G - -# -lCrun : standard C++ library (for new/delete) -LOCAL_LIBS=-lpthread -lCrun -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.solaris_sparc_gcc p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_gcc --- p7zip-rar-16.02/makefile.solaris_sparc_gcc 2015-09-13 18:20:38.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.solaris_sparc_gcc 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DENV_UNIX \ - -DNDEBUG -D_REENTRANT \ - $(LOCAL_FLAGS) - -#CXX=/opt/sfw/bin/g++ -#CC=/opt/sfw/bin/gcc -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -lrt -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.solaris_x86 p7zip-rar-16.02+really25.00+ds/makefile.solaris_x86 --- p7zip-rar-16.02/makefile.solaris_x86 2015-09-13 18:20:44.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.solaris_x86 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DENV_UNIX \ - -DNDEBUG -D_REENTRANT \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -lrt -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/makefile.tru64 p7zip-rar-16.02+really25.00+ds/makefile.tru64 --- p7zip-rar-16.02/makefile.tru64 2015-09-13 18:20:48.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/makefile.tru64 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# -# makefile for Tru64 -# tested with OSF 5.1 and g++ 3.4.2 -# - -OPTFLAGS=-O -s - -ALLFLAGS=${OPTFLAGS} \ - -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -DNDEBUG -D_REENTRANT -DENV_UNIX \ - $(LOCAL_FLAGS) - -CXX=g++ -CC=gcc -CC_SHARED=-fPIC -LINK_SHARED=-fPIC -shared - -LOCAL_LIBS=-lpthread -LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl - -OBJ_CRC32=$(OBJ_CRC32_C) -OBJ_AES= - diff -Nru p7zip-rar-16.02/man1/7z.1 p7zip-rar-16.02+really25.00+ds/man1/7z.1 --- p7zip-rar-16.02/man1/7z.1 2007-09-21 18:53:12.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/man1/7z.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -.TH 7z 1 "September 1 2006" "Mohammed Adnene Trojette" -.SH NAME -7z \- A file archiver with highest compression ratio -.SH SYNOPSIS -.B 7z -.BR [adeltux] -.BR [\-] -.BR [SWITCH] -.BR -.BR ... -.PP -.SH DESCRIPTION -7-Zip is a file archiver with the highest compression ratio. The program supports 7z (that implements LZMA compression algorithm), ZIP, CAB, ARJ, GZIP, BZIP2, TAR, CPIO, RPM and DEB formats. Compression ratio in the new 7z format is 30-50% better than ratio in ZIP format. -.TP -7z uses plugins to handle archives. -.PP -.SH FUNCTION LETTERS -.TP -.B a -Add -.TP -.B d -Delete -.TP -.B e -Extract -.TP -.B l -List -.TP -.B t -Test -.TP -.B u -Update -.TP -.B x -eXtract with full paths -.PP -.SH SWITCHES -.TP -.B \-ai[r[\-|0]]{@listfile|!wildcard} -Include archives -.TP -.B \-ax[r[\-|0]]{@listfile|!wildcard} -eXclude archives -.TP -.B \-bd -Disable percentage indicator -.TP -.B \-i[r[\-|0]]{@listfile|!wildcard} -Include filenames -.TP -.B \-l -don't store symlinks; store the files/directories they point to (CAUTION : the scanning stage can never end because of recursive symlinks like 'ln \-s .. ldir') -.TP -.B \-m{Parameters} -Set Compression Method (see {DEST_SHARE_DOC}/MANUAL/switches/method.htm for a list of methods) -.TP -.B \-mhe=on|off -7z format only : enables or disables archive header encryption (Default : off) -.TP -.B \-o{Directory} -Set Output directory -.TP -.B \-p{Password} -Set Password -.TP -.B \-r[\-|0] -Recurse subdirectories (CAUTION: this flag does not do what you think, avoid using it) -.TP -.B \-sfx[{name}] -Create SFX archive -.TP -.B \-si -Read data from StdIn (eg: tar cf \- directory | 7z a \-si directory.tar.7z) -.TP -.B \-so -Write data to StdOut (eg: % echo foo | 7z a dummy \-tgzip \-si \-so > /dev/null) -.TP -.B \-slt -Sets technical mode for l (list) command -.TP -.B \-t{Type} -Type of archive (7z, zip, gzip, bzip2 or tar. 7z format is default) -.TP -.B \-v{Size}[b|k|m|g] -Create volumes -.TP -.B \-u[\-][p#][q#][r#][x#][y#][z#][!newArchiveName] -Update options -.TP -.B \-w[path] -Set Working directory -.TP -.B \-x[r[\-|0]]]{@listfile|!wildcard} -Exclude filenames -.TP -.B \-y -Assume Yes on all queries -.PP -.SH DIAGNOSTICS -7-Zip returns the following exit codes: -.RS -.IP 0 -Normal (no errors or warnings detected) -.IP 1 -Warning (Non fatal error(s)). For example, some files cannot be read during compressing. So they were not compressed -.IP 2 -Fatal error -.IP 7 -Bad command line parameters -.IP 8 -Not enough memory for operation -.IP 255 -User stopped the process with control-C (or similar) -.SH Backup and limitations -DO NOT USE the 7-zip format for backup purpose on Linux/Unix because : - \- 7-zip does not store the owner/group of the file. - -.LP -On Linux/Unix, in order to backup directories you must use tar : - \- to backup a directory : tar cf \- directory | 7za a \-si directory.tar.7z - \- to restore your backup : 7za x \-so directory.tar.7z | tar xf \- - -If you want to send files and directories (not the owner of file) -to others Unix/MacOS/Windows users, you can use the 7-zip format. - - example : 7za a directory.7z directory - -.LP -Do not use "\-r" because this flag does not do what you think. -.LP -Do not use directory/* because of ".*" files (example : "directory/*" does not match "directory/.profile") -.SH EXAMPLE 1 -.TP -.B 7z a \-t7z \-m0=lzma \-mx=9 \-mfb=64 \-md=32m \-ms=on archive.7z dir1 -adds all files from directory "dir1" to archive archive.7z using "ultra settings" -.TP -.B \-t7z -7z archive -.TP -.B \-m0=lzma -lzma method -.TP -.B \-mx=9 -level of compression = 9 (Ultra) -.TP -.B \-mfb=64 -number of fast bytes for LZMA = 64 -.TP -.B \-md=32m -dictionary size = 32 megabytes -.TP -.B \-ms=on -solid archive = on -.SH EXAMPLE 2 -.TP -.B -7z a \-sfx archive.exe dir1 -add all files from directory "dir1" to SFX archive archive.exe (Remark : SFX archive MUST end with ".exe") -.SH EXAMPLE 3 -.TP -.B -7z a \-mhe=on \-pmy_password archive.7z a_directory -add all files from directory "a_directory" to the archive "archive.7z" (with data and header archive encryption on) -.SH "SEE ALSO" -7za(1), 7zr(1), bzip2(1), gzip(1), zip(1) -.PP -.SH "HTML Documentation" -{DEST_SHARE_DOC}/MANUAL/index.htm -.SH AUTHOR -.TP -Written for Debian by Mohammed Adnene Trojette. diff -Nru p7zip-rar-16.02/man1/7za.1 p7zip-rar-16.02+really25.00+ds/man1/7za.1 --- p7zip-rar-16.02/man1/7za.1 2007-09-21 18:53:24.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/man1/7za.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -.TH 7za 1 "September 1 2006" "Mohammed Adnene Trojette" -.SH NAME -7za \- A file archiver with highest compression ratio -.SH SYNOPSIS -.B 7za -.BR [adeltux] -.BR [-] -.BR [SWITCH] -.BR -.BR ... -.PP -.SH DESCRIPTION -7-Zip is a file archiver with the highest compression ratio. The program supports 7z (that implements LZMA compression algorithm), ZIP, CAB, ARJ, GZIP, BZIP2, TAR, CPIO, RPM and DEB formats. Compression ratio in the new 7z format is 30-50% better than ratio in ZIP format. -.TP -7za is a stand-alone executable. 7za handles less archive formats than 7z, but does not need any others. -.PP -.SH FUNCTION LETTERS -.TP -.B a -Add -.TP -.B d -Delete -.TP -.B e -Extract -.TP -.B l -List -.TP -.B t -Test -.TP -.B u -Update -.TP -.B x -eXtract with full paths -.PP -.SH SWITCHES -.TP -.B \-ai[r[-|0]]{@listfile|!wildcard} -Include archives -.TP -.B \-ax[r[-|0]]{@listfile|!wildcard} -eXclude archives -.TP -.B \-bd -Disable percentage indicator -.TP -.B \-i[r[-|0]]{@listfile|!wildcard} -Include filenames -.TP -.B \-l -don't store symlinks; store the files/directories they point to (CAUTION : the scanning stage can never end because of recursive symlinks like 'ln \-s .. ldir') -.TP -.B \-m{Parameters} -Set Compression Method (see {DEST_SHARE_DOC}/MANUAL/switches/method.htm for a list of methods) -.TP -.B \-mhe=on|off -7z format only : enables or disables archive header encryption (Default : off) -.TP -.B \-o{Directory} -Set Output directory -.TP -.B \-p{Password} -Set Password -.TP -.B \-r[-|0] -Recurse subdirectories (CAUTION: this flag does not do what you think, avoid using it) -.TP -.B \-sfx[{name}] -Create SFX archive -.TP -.B \-si -Read data from StdIn (eg: tar cf \- directory | 7za a \-si directory.tar.7z) -.TP -.B \-so -Write data to StdOut (eg: % echo foo | 7z a dummy \-tgzip \-si \-so > /dev/null) -.TP -.B \-slt -Sets technical mode for l (list) command -.TP -.B \-t{Type} -Type of archive (7z, zip, gzip, bzip2 or tar. 7z format is default) -.TP -.B \-v{Size}[b|k|m|g] -Create volumes -.TP -.B \-u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] -Update options -.TP -.B \-w[path] -Set Working directory -.TP -.B \-x[r[-|0]]]{@listfile|!wildcard} -Exclude filenames -.TP -.B \-y -Assume Yes on all queries -.PP -.SH DIAGNOSTICS -7-Zip returns the following exit codes: -.RS -.IP 0 -Normal (no errors or warnings detected) -.IP 1 -Warning (Non fatal error(s)). For example, some files cannot be read during compressing. So they were not compressed -.IP 2 -Fatal error -.IP 7 -Bad command line parameters -.IP 8 -Not enough memory for operation -.IP 255 -User stopped the process with control-C (or similar) -.SH Backup and limitations -DO NOT USE the 7-zip format for backup purpose on Linux/Unix because : - \- 7-zip does not store the owner/group of the file. - -.LP -On Linux/Unix, in order to backup directories you must use tar : - \- to backup a directory : tar cf \- directory | 7za a \-si directory.tar.7z - \- to restore your backup : 7za x \-so directory.tar.7z | tar xf \- - -If you want to send files and directories (not the owner of file) -to others Unix/MacOS/Windows users, you can use the 7-zip format. - - example : 7za a directory.7z directory - -.LP -Do not use "\-r" because this flag does not do what you think. -.LP -Do not use directory/* because of ".*" files (example : "directory/*" does not match "directory/.profile") -.SH EXAMPLE 1 -.TP -.B 7za a \-t7z \-m0=lzma \-mx=9 \-mfb=64 \-md=32m \-ms=on archive.7z dir1 -adds all files from directory "dir1" to archive archive.7z using "ultra settings" -.TP -.B \-t7z -7z archive -.TP -.B \-m0=lzma -lzma method -.TP -.B \-mx=9 -level of compression = 9 (Ultra) -.TP -.B \-mfb=64 -number of fast bytes for LZMA = 64 -.TP -.B \-md=32m -dictionary size = 32 megabytes -.TP -.B \-ms=on -solid archive = on -.SH EXAMPLE 2 -.TP -.B -7za a \-sfx archive.exe dir1 -add all files from directory "dir1" to SFX archive archive.exe (Remark : SFX archive MUST end with ".exe") -.SH EXAMPLE 3 -.TP -.B -7za a \-mhe=on \-pmy_password archive.7z a_directory -add all files from directory "a_directory" to the archive "archive.7z" (with data and header archive encryption on) -.SH "SEE ALSO" -7z(1), 7zr(1), bzip2(1), gzip(1), zip(1) -.PP -.SH "HTML Documentation" -{DEST_SHARE_DOC}/MANUAL/index.htm -.SH AUTHOR -.TP -Written for Debian by Mohammed Adnene Trojette. diff -Nru p7zip-rar-16.02/man1/7zr.1 p7zip-rar-16.02+really25.00+ds/man1/7zr.1 --- p7zip-rar-16.02/man1/7zr.1 2007-09-21 18:53:34.000000000 +0000 +++ p7zip-rar-16.02+really25.00+ds/man1/7zr.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -.TH 7zr 1 "September 1 2006" "Mohammed Adnene Trojette" -.SH NAME -7zr \- A file archiver with highest compression ratio -.SH SYNOPSIS -.B 7zr -.BR [adeltux] -.BR [-] -.BR [SWITCH] -.BR -.BR ... -.PP -.SH DESCRIPTION -7-Zip is a file archiver with the highest compression ratio. The program supports 7z (that implements LZMA compression algorithm), ZIP, CAB, ARJ, GZIP, BZIP2, TAR, CPIO, RPM and DEB formats. Compression ratio in the new 7z format is 30-50% better than ratio in ZIP format. -.TP -7zr is a stand-alone executable. 7zr handles less archive formats than 7z, but does not need any others. 7zr is a "light-version" of 7za that only handles 7z archives. -.PP -.SH FUNCTION LETTERS -.TP -.B a -Add -.TP -.B d -Delete -.TP -.B e -Extract -.TP -.B l -List -.TP -.B t -Test -.TP -.B u -Update -.TP -.B x -eXtract with full paths -.PP -.SH SWITCHES -.TP -.B \-ai[r[-|0]]{@listfile|!wildcard} -Include archives -.TP -.B \-ax[r[-|0]]{@listfile|!wildcard} -eXclude archives -.TP -.B \-bd -Disable percentage indicator -.TP -.B \-i[r[-|0]]{@listfile|!wildcard} -Include filenames -.TP -.B \-l -don't store symlinks; store the files/directories they point to (CAUTION : the scanning stage can never end because of recursive symlinks like 'ln \-s .. ldir') -.TP -.B \-m{Parameters} -Set Compression Method (see {DEST_SHARE_DOC}/MANUAL/switches/method.htm for a list of methods) -.TP -.B \-mhe=on|off -7z format only : enables or disables archive header encryption (Default : off) -.TP -.B \-o{Directory} -Set Output directory -.TP -.B \-p{Password} -Set Password -.TP -.B \-r[-|0] -Recurse subdirectories (CAUTION: this flag does not do what you think, avoid using it) -.TP -.B \-sfx[{name}] -Create SFX archive -.TP -.B \-si -Read data from StdIn (eg: tar cf \- directory | 7zr a \-si directory.tar.7z) -.TP -.B \-so -Write data to StdOut (eg: 7zr x \-so directory.tar.7z | tar xf \-) -.TP -.B \-slt -Sets technical mode for l (list) command -.TP -.B \-v{Size}[b|k|m|g] -Create volumes -.TP -.B \-u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] -Update options -.TP -.B \-w[path] -Set Working directory -.TP -.B \-x[r[-|0]]]{@listfile|!wildcard} -Exclude filenames -.TP -.B \-y -Assume Yes on all queries -.PP -.SH DIAGNOSTICS -7-Zip returns the following exit codes: -.RS -.IP 0 -Normal (no errors or warnings detected) -.IP 1 -Warning (Non fatal error(s)). For example, some files cannot be read during compressing. So they were not compressed -.IP 2 -Fatal error -.IP 7 -Bad command line parameters -.IP 8 -Not enough memory for operation -.IP 255 -User stopped the process with control-C (or similar) -.SH Backup and limitations -DO NOT USE the 7-zip format for backup purpose on Linux/Unix because : - \- 7-zip does not store the owner/group of the file. - -.LP -On Linux/Unix, in order to backup directories you must use tar : - \- to backup a directory : tar cf - directory | 7zr a -si directory.tar.7z - \- to restore your backup : 7zr x -so directory.tar.7z | tar xf - - -If you want to send files and directories (not the owner of file) -to others Unix/MacOS/Windows users, you can use the 7-zip format. - - example : 7zr a directory.7z directory - -.LP -Do not use "\-r" because this flag does not do what you think. -.LP -Do not use directory/* because of ".*" files (example : "directory/*" does not match "directory/.profile") -.SH EXAMPLE 1 -.TP -.B 7zr a \-t7z \-m0=lzma \-mx=9 \-mfb=64 \-md=32m \-ms=on archive.7z dir1 -adds all files from directory "dir1" to archive archive.7z using "ultra settings" -.TP -.B \-t7z -7z archive -.TP -.B \-m0=lzma -lzma method -.TP -.B \-mx=9 -level of compression = 9 (Ultra) -.TP -.B \-mfb=64 -number of fast bytes for LZMA = 64 -.TP -.B \-md=32m -dictionary size = 32 megabytes -.TP -.B \-ms=on -solid archive = on -.SH EXAMPLE 2 -.TP -.B -7zr a \-sfx archive.exe dir1 -add all files from directory "dir1" to SFX archive archive.exe (Remark : SFX archive MUST end with ".exe") -.SH EXAMPLE 3 -.TP -.B -7zr a \-mhe=on \-pmy_password archive.7z a_directory -add all files from directory "a_directory" to the archive "archive.7z" (with data and header archive encryption on) -.SH "SEE ALSO" -7z(1), 7za(1), bzip2(1), gzip(1), zip(1) -.PP -.SH "HTML Documentation" -{DEST_SHARE_DOC}/MANUAL/index.htm -.SH AUTHOR -.TP -Written for Debian by Mohammed Adnene Trojette.